diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml new file mode 100644 index 0000000000000000000000000000000000000000..9fe0739fc84eedfbe7b7f2df94f73456fc6ba3c4 --- /dev/null +++ b/.github/workflows/develop.yml @@ -0,0 +1,18 @@ +name: Develop +'on': + push: + branches: + - develop +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Publish to Docker Hub + uses: docker/build-push-action@92e71463491f2d026a477188b8ad3a0fdd9d672c + with: + repository: iotaledger/goshimmer + username: '${{ secrets.IOTALEDGER_HUB_DOCKER_LOGIN }}' + password: '${{ secrets.IOTALEDGER_HUB_DOCKER_PASSWORD }}' + tags: develop diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 0000000000000000000000000000000000000000..4a5167673b90ecfaae1a2f313254d38490e4f3df --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,249 @@ +name: Integration tests + +on: pull_request + +jobs: + + autopeering: + name: autopeering + env: + TEST_NAME: autopeering + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build GoShimmer image + run: docker build -t iotaledger/goshimmer . + + - name: Pull additional Docker images + run: | + docker pull angelocapossele/drand:latest + docker pull gaiaadm/pumba:0.7.2 + docker pull gaiadocker/iproute2:latest + + - name: Run integration tests + run: docker-compose -f tools/integration-tests/tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + + - name: Create logs from tester + if: always() + run: | + docker logs tester &> tools/integration-tests/logs/tester.log + + - name: Save logs as artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: ${{ env.TEST_NAME }} + path: tools/integration-tests/logs + + + common: + name: common + env: + TEST_NAME: common + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build GoShimmer image + run: docker build -t iotaledger/goshimmer . + + - name: Pull additional Docker images + run: | + docker pull angelocapossele/drand:latest + docker pull gaiaadm/pumba:0.7.2 + docker pull gaiadocker/iproute2:latest + + - name: Run integration tests + run: docker-compose -f tools/integration-tests/tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + + - name: Create logs from tester + if: always() + run: | + docker logs tester &> tools/integration-tests/logs/tester.log + + - name: Save logs as artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: ${{ env.TEST_NAME }} + path: tools/integration-tests/logs + + consensus: + name: consensus + env: + TEST_NAME: consensus + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build GoShimmer image + run: docker build -t iotaledger/goshimmer . + + - name: Pull additional Docker images + run: | + docker pull angelocapossele/drand:latest + docker pull gaiaadm/pumba:0.7.2 + docker pull gaiadocker/iproute2:latest + + - name: Run integration tests + run: docker-compose -f tools/integration-tests/tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + + - name: Create logs from tester + if: always() + run: | + docker logs tester &> tools/integration-tests/logs/tester.log + + - name: Save logs as artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: ${{ env.TEST_NAME }} + path: tools/integration-tests/logs + + + drng: + name: drng + env: + TEST_NAME: drng + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build GoShimmer image + run: docker build -t iotaledger/goshimmer . + + - name: Pull additional Docker images + run: | + docker pull angelocapossele/drand:latest + docker pull gaiaadm/pumba:0.7.2 + docker pull gaiadocker/iproute2:latest + + - name: Run integration tests + run: docker-compose -f tools/integration-tests/tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + + - name: Create logs from tester + if: always() + run: | + docker logs tester &> tools/integration-tests/logs/tester.log + + - name: Save logs as artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: ${{ env.TEST_NAME }} + path: tools/integration-tests/logs + + + + message: + name: message + env: + TEST_NAME: message + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build GoShimmer image + run: docker build -t iotaledger/goshimmer . + + - name: Pull additional Docker images + run: | + docker pull angelocapossele/drand:latest + docker pull gaiaadm/pumba:0.7.2 + docker pull gaiadocker/iproute2:latest + + - name: Run integration tests + run: docker-compose -f tools/integration-tests/tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + + - name: Create logs from tester + if: always() + run: | + docker logs tester &> tools/integration-tests/logs/tester.log + + - name: Save logs as artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: ${{ env.TEST_NAME }} + path: tools/integration-tests/logs + + + + value: + name: value + env: + TEST_NAME: value + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build GoShimmer image + run: docker build -t iotaledger/goshimmer . + + - name: Pull additional Docker images + run: | + docker pull angelocapossele/drand:latest + docker pull gaiaadm/pumba:latest + docker pull gaiadocker/iproute2:latest + + - name: Run integration tests + run: docker-compose -f tools/integration-tests/tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + + - name: Create logs from tester + if: always() + run: | + docker logs tester &> tools/integration-tests/logs/tester.log + + - name: Save logs as artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: ${{ env.TEST_NAME }} + path: tools/integration-tests/logs + + faucet: + name: faucet + env: + TEST_NAME: faucet + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build GoShimmer image + run: docker build -t iotaledger/goshimmer . + + - name: Pull additional Docker images + run: | + docker pull angelocapossele/drand:latest + docker pull gaiaadm/pumba:latest + docker pull gaiadocker/iproute2:latest + + - name: Run integration tests + run: docker-compose -f tools/integration-tests/tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + + - name: Create logs from tester + if: always() + run: | + docker logs tester &> tools/integration-tests/logs/tester.log + + - name: Save logs as artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: ${{ env.TEST_NAME }} + path: tools/integration-tests/logs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cee5c81c8b65950195de4fd01b9f69ec751f036c..f69e06007f3a448fe30980005d96a93954c55e92 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,21 +1,38 @@ name: Release - -on: +'on': release: - types: [published] - + types: + - published jobs: - Release: - name: Release - runs-on: [ubuntu-latest] + goreleaser: + name: GoReleaser + runs-on: + - ubuntu-latest container: - image: iotmod/goreleaser-cgo-cross-compiler:1.13.5 - volumes: [/repo] - + image: 'iotmod/goreleaser-cgo-cross-compiler:1.14.4' + volumes: + - /repo steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - name: Release GoShimmer - run: goreleaser --rm-dist - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout + uses: actions/checkout@v2 + - name: Copy config.default.json to config.json + run: cp config.default.json config.json + - name: Release GoShimmer + run: goreleaser --rm-dist + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + docker: + name: Docker + runs-on: + - ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Publish to Docker Hub + uses: docker/build-push-action@92e71463491f2d026a477188b8ad3a0fdd9d672c + with: + repository: iotaledger/goshimmer + username: '${{ secrets.IOTALEDGER_HUB_DOCKER_LOGIN }}' + password: '${{ secrets.IOTALEDGER_HUB_DOCKER_PASSWORD }}' + tags: latest + tag_with_ref: true diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml new file mode 100644 index 0000000000000000000000000000000000000000..71550615dba7af022c0acd7a06729012d381b6b4 --- /dev/null +++ b/.github/workflows/reviewdog.yml @@ -0,0 +1,20 @@ +name: reviewdog + +on: pull_request + +jobs: + + golangci-lint: + name: GolangCI-Lint + runs-on: ubuntu-latest + steps: + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Run golangci-lint + uses: docker://reviewdog/action-golangci-lint:v1.2 + with: + github_token: ${{ secrets.github_token }} + golangci_lint_flags: "--timeout=10m" + reporter: "github-pr-review" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e7bc37ca3f75b146f08a87d482b4af246c5996df..d401d80a407bf966de26d57e59c98ae40bddb7b8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,19 +1,18 @@ name: Test GoShimmer -on: - push: - pull_request: - types: [opened, reopened] + +on: [push, pull_request] + jobs: build: - name: Test GoShimmer + name: Unit tests runs-on: ubuntu-latest steps: - - name: Set up Go 1.13 + - name: Set up Go 1.14.4 uses: actions/setup-go@v1 with: - go-version: 1.13 + go-version: 1.14.4 - name: Check out code into the Go module directory uses: actions/checkout@v2 diff --git a/.gitignore b/.gitignore index b376e693d4a49e941472f91450d7dc7937651069..ed554be4bbe94dca5030e830ec94f18fa5ef4953 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,7 @@ objectsdb/ # OSX related files .DS_Store shimmer -goshimmer \ No newline at end of file +goshimmer + +config.json +.env \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 38c720d5cddb746e8a184ebafb0d2f9e4c28f22b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +0,0 @@ -[submodule "IOTAtangle"] - path = IOTAtangle - url = https://github.com/glumb/IOTAtangle.git -[submodule "socket.io-client"] - path = socket.io-client - url = https://github.com/socketio/socket.io-client.git diff --git a/.golangci.yml b/.golangci.yml index 6de39205141d50effd3541fe2918da2a22238ad8..9b5002f493addd784e1d39cbd19f440863c68136 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,13 +1,15 @@ run: tests: true +issues: + exclude-use-default: false + max-issues-per-linter: 0 + linters-settings: gofmt: simplify: true golint: - min-confidence: 0.9 - gocyclo: - min-complexity: 15 + min-confidence: 0.8 govet: check-shadowing: true misspell: @@ -19,7 +21,7 @@ linters: - gofmt - goimports - govet + - golint disable: - errcheck - gochecknoglobals - - golint diff --git a/.goreleaser.yml b/.goreleaser.yml index 3d250a1508ccaca262b637b538442d7acf0195db..50e6ac8059d29423f2765a50a12e22658c92f9c9 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -13,13 +13,9 @@ builds: - id: goshimmer-darwin-amd64 binary: goshimmer env: - - CGO_ENABLED=1 - - CC=o64-clang - - CXX=o64-clang++ + - CGO_ENABLED=0 ldflags: - -s -w -X github.com/iotaledger/goshimmer/plugins/cli.AppVersion={{.Version}} - flags: - - -tags=pow_avx main: main.go goos: - darwin diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ea66788ed2c7fe8a2ea1952ec31796f44815314..78697c4c20a859bd03bacd130665d5e65617c168 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,85 @@ +# v0.2.0 - 2020-06-30 +* Adds the value transfer dApp: + * New binary transaction layout + * UTXO model + * Support for transactions with Ed25519 and BLS signatures + * Parallel reality based ledger state + * Support for colored tokens + * Conflict resolution via FPC + * Applied FCoB rules +* Adds the network delay dApp which is used to gather the avg. network delay occurring in the network +* Adds the faucet dApp giving the ability to request funds for testing via the dashboard or web API +* Adds the DRNG dApp which is used to propagate random numbers produced by a dRand committee (this dApp is inactive) +* Adds the base communication layer +* Adds improved analysis server: + * Splits it into 3 separate plugins `analysis-client`/`analysis-dashboard`/`analysis-server` + * Applies heartbeat pattern for robustness on both client and server side + * Uses TLV denoted messages for communication + * Complete new dashboard with live visualisations of the network graph and ongoing conflicts + * Use short node IDs throughout the analysis dashboard + * Prometheus exporter to expose global network metrics + * Storage for conflicts inside a MongoDB for further processing + * Complete rewritten autopeering data retention +* Adds additional HTTP API routes: + * "healtz" route to query the health of the node (for LBs) + * Query transaction attachment locations + * Query transactions by IDs + * Send transactions + * Get UTXOs on addresses + * Query info about the node + * Issue a faucet funding request + * Query dRNG committee + * Query dRNG random number + * Issue data payloads +* Adds dashboard improvements: + * Tips chart + * Communication layer visualizer + * Address and UTXOs view + * Message payload view + * DRNG live feed + * Faucet page to request funds + * Support different payload views (data, value, faucet, unknown) +* Adds integration test framework and corresponding tests: + * Autopeering/Network Split + * Message propagation + * FPC 50/50 network split voting + * Faucet funding + * Value transfers + * Synchronization +* Adds refactored communication layer code +* Adds BLAKE2-based PoW for rate control +* Adds rewritten FPC package +* Adds possibility to change config options with environment variables +* Adds sample Grafana dashboard for local node instances +* Adds snapshot-file import +* Adds "dirty-flag" to the `Database` plugin to check for corrupted databases +* Adds BadgerDB gargbage collection on startup/shutdown and removes periodic GC +* Adds review-dog linter and automatic integration tests execution to continuous integration pipeline +* Adds `Prometheus` exporter plugin with exposure for [following metrics](https://github.com/iotaledger/goshimmer/issues/465) +* Adds `Sync` plugin keeping track of the node's synchronization state +* Adds `Issuer` plugin which takes care of issuing messages (and blocking any issuance when the node is desynced) +* Adds `Profiling` plugin which exposes the `pprof` endpoints and is now configurable +* Adds `Bootstrap` plugin which continuously issues messages to keep the comm. layer graph growing +* Adds proper metrics collection in the `Metrics` plugin +* Adds support for the new HTTP API routes to the Go client library +* Adds `tools/docker-network` to run an isolated GoShimmer network with a chosen amount of nodes. Predefined local and global grafana dashboards are spinned up as well for the network +* Upgrades `hive.go` with various improvements and fixes +* Fixes bind address prints to not be normalized +* Fixes usage of WebSocket message rate limiter +* Fixes disabled/enabled plugins list in info response +* Fixes the `Graceful Shutdown` plugin not showing the actual background workers during shutdown. The node operator is now +able to see pending background workers in the order in which they are supposed to be terminated +* Refactors display of IDs to use Base58 throughout the entire codebase +* Increases network and database versions +* Removes usage of non std `errors` package +* Removes `Graph` plugin +* Renames `SPA` plugin to `Dashboard` +* Makes running GoShimmer with a config file mandatory if not explicitly bypassed + # v0.1.3 - 2020-03-16 * Update SPA plugin's JS dependencies -* Upgrad `github.com/gobuffalo/packr` to v2.8.0 +* Upgrade `github.com/gobuffalo/packr` to v2.8.0 * Resolves a security issue in the packr dependency, which would allow an unauthenticated attacker to read any file from the application's filesystem diff --git a/Dockerfile b/Dockerfile index 2f920cee5f951cf0e13a0ff2e3778c664dfea38b..42320aaeff591055f1fdcfee66a6c99b31f14c05 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ ############################ # Build ############################ -# golang:1.14.0-buster -FROM golang@sha256:fc7e7c9c4b0f6d2d5e8611ee73b9d1d3132750108878517bbf988aa772359ae4 AS build +# golang:1.14.4-buster +FROM golang@sha256:fbaba67d3bd0a6fd154eaa27d1a0a9e5e80ecdb0792736017fde7326d9bf8d69 AS build # Ensure ca-certficates are up to date RUN update-ca-certificates @@ -34,14 +34,14 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ # user:group is nonroot:nonroot, uid:gid = 65532:65532 FROM gcr.io/distroless/static@sha256:23aa732bba4c8618c0d97c26a72a32997363d591807b0d4c31b0bbc8a774bddf -VOLUME /mainnetdb - EXPOSE 14666/tcp EXPOSE 14626/udp +# Copy configuration +COPY snapshot.bin /snapshot.bin +COPY config.default.json /config.json + # Copy the Pre-built binary file from the previous stage COPY --from=build /go/bin/goshimmer /run/goshimmer -# Copy the default config -COPY config.json /config.json -ENTRYPOINT ["/run/goshimmer", "--config-dir=/", "--database.directory=/mainnetdb"] +ENTRYPOINT ["/run/goshimmer", "--config-dir=/", "--valueLayer.snapshot.file=/snapshot.bin", "--database.directory=/tmp/mainnetdb"] diff --git a/IOTAtangle b/IOTAtangle deleted file mode 160000 index 07bba77a296a2d06277cdae56aa963abeeb5f66e..0000000000000000000000000000000000000000 --- a/IOTAtangle +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 07bba77a296a2d06277cdae56aa963abeeb5f66e diff --git a/README.md b/README.md index 29f236f7d1893c6938baf27d8a946aae8a54721d..ad69bd3d9a749169fe44a38bfeede66cfcbe093f 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ <h1 align="center"> <br> - <a href="https://docs.iota.org/docs/node-software/0.1/goshimmer/introduction/overview.md"><img src="images/GoShimmer.png"></a> + <a href="https://github.com/iotaledger/goshimmer/wiki"><img src="images/GoShimmer.png"></a> </h1> <h2 align="center">Prototype node software for an IOTA network without the Coordinator</h2> <p align="center"> - <a href="https://docs.iota.org/docs/node-software/0.1/goshimmer/introduction/overview" style="text-decoration:none;"> + <a href="https://github.com/iotaledger/goshimmer/wiki" style="text-decoration:none;"> <img src="https://img.shields.io/badge/Documentation%20portal-blue.svg?style=for-the-badge" alt="Developer documentation portal"> </p> <p align="center"> @@ -23,9 +23,8 @@ <a href="#design">Design</a> â—ˆ <a href="#implemented-coordicide-modules">Implemented Coordicide modules</a> â—ˆ <a href="#work-in-progress-modules">Work-in-progress modules</a> â—ˆ - <a href="#installation">Installation</a> â—ˆ <a href="#getting-started">Getting started</a> â—ˆ - <a href="#client-library-and-http-api-reference">Client library and HTTP API reference</a> â—ˆ + <a href="#client-library-and-http-api-reference">Client-Library and HTTP API reference</a> â—ˆ <a href="#supporting-the-project">Supporting the project</a> â—ˆ <a href="#joining-the-discussion">Joining the discussion</a> </p> @@ -34,47 +33,47 @@ ## About -This repository is where the IOTA Foundation's Research Department runs simulations of the Coordicide modules to study and evaluate their performance. +This repository is where the IOTA Foundation's Research Department tests the Coordicide modules to study and evaluate their performance. The aim of this open repository is to give the community the opportunity to follow developments, take part in testing, and learn more about [Coordicide](https://coordicide.iota.org/). -**Note:** You can find details about future development plans in our [roadmap](https://roadmap.iota.org). +**Note:** You can find details about future development plans on our [roadmap](https://roadmap.iota.org). ## Design +The code in GoShimmer is modular, where each module represents either one of the [Coordicide components](https://coordicide.iota.org/) or a basic node function such as the gossip, ledger state, API just to mention a few. -The code in GoShimmer is modular, where each module represents either one of the [Coordicide components](https://coordicide.iota.org/) or a basic node function such as the gossip layer, ledger state, and API. + - +GoShimmer modularity is based on a combination of event-driven and layer-based approaches. -This approach allows us to develop each module in parallel and to test GoShimmer with one or more different versions. - -Each module is defined in the `packages` directory and can be enabled, using the `plugins` directory. +Each module is defined in the `packages` directory, with the exceptions for the dApps (e.g., value transfer, network delay and the faucet) that are under the `dapps` folder. Each module can be enabled using the `plugins` directory. **Note:** See the `main.go` file to see which plugins are currently supported. ## Implemented Coordicide modules -The `master` branch is the stable version of the GoShimmer software, which includes a minimal set of modules to allow you to send and gossip zero-value transactions. +The `master` branch is the stable version of the GoShimmer software, which includes a minimal set of modules to allow you to send and gossip the following types of object: + +- Generic data object, and more in general, any non-value transfer can be supported with its own dApp/App. +- Value objects to issue transactions. +- Faucet funding request objects. The `master` branch includes the following Coordicide modules: - [Node identities](https://coordicide.iota.org/module1) -- [Autopeering](https://coordicide.iota.org/module2) +- [Autopeering](https://coordicide.iota.org/module2). We also have a standalone autopeering simulator in this [repository](https://github.com/iotaledger/autopeering-sim). -The autopeering module is divided into two submodules: +- [Fast Probabilistic Consensus](https://coordicide.iota.org//module4.1.2). We also have a standalone FPC simulator in this [repository](https://github.com/iotaledger/fpc-sim). -- **Peer discovery:** Responsible for operations such as discovering new peers and verifying their online status +- [Tip Selection Algorithm](https://coordicide.iota.org//module5) -- **Neighbor selection:** Responsible for finding and managing neighbors +- [Parallel-reality-based Ledger State](https://iota.cafe/t/parallel-reality-based-ledger-state-using-utxo/261) (using the UTXO model). - - -We also have a standalone autopeering simulator in this [repository](https://github.com/iotaledger/autopeering-sim). ## Work-in-progress modules -Work-in-progress modules are typically kept on a different branch such as `mana`, and are not compatible with the `master` branch. Therefore, nodes that run these branches cannot join the current network because the code either is still too experimental or it includes breaking changes. +Work-in-progress modules are typically kept on a different branch such as `mana`, and are not compatible with the `master` branch. Therefore, nodes that run these branches cannot join the current network because the code either is still too experimental or it includes breaking changes. The same goes for the `develop` branch. The following Coordicide modules are a work in progress: @@ -82,153 +81,30 @@ The following Coordicide modules are a work in progress: - [Cellular Consensus](https://coordicide.iota.org/module5.1.1): The `ca` branch contains a first implementation of the Cellular Consensus module in the `packages` directory. -- [Fast Probabilistic Consensus](https://coordicide.iota.org/module5.1.2): The `fpc` branch contains a first implementation of the Fast Probabilistic Consensus module in the `packages` directory. We also have a standalone FPC simulator in this [repository](https://github.com/iotaledger/fpc-sim). - - [Spam Protection](https://coordicide.iota.org/module3): You can find the initial simulation source code of the rate control in this [repository](https://github.com/andypandypi/IOTARateControl) and the source code of the Adaptive Proof of Work simulator [here](https://github.com/iotaledger/adaptive-pow-sim). -As well as these modules, we are working on the following node functions: - -- Ledger State: The `ledger_state` branch implements a version of the [parallel-reality-based ledger state](https://iota.cafe/t/parallel-reality-based-ledger-state-using-utxo/261) (using the UTXO model). - -  - -## Client library and HTTP API reference - -You can use the Go client library to interact with GoShimmer (located under `github.com/iotaledger/goshimmer/client`). - -Alternatively, you can see the [API docs](https://docs.iota.org/docs/node-software/0.1/goshimmer/references/api-reference) for the available HTTP API endpoints. Or, to generate code samples, you can use the [OAS/Swagger specification file](https://github.com/iotaledger/goshimmer/blob/master/plugins/webapi/api.yaml). - -## Installation - -You have two options to install and run GoShimmer: - -- Use the precompiled executable file -- Compile the code from source - -### Executing the precompiled executable file - -The [release page](https://github.com/iotaledger/goshimmer/releases) includes downloadable files for Linux, macOS, and Windows. - -To run the node, all you need to do is download and execute one of these files, depending on your operating system. - -```bash -# Linux and macOS -./goshimmer -# Windows -goshimmer.exe -``` - -### Compiling the code from source - -If you want to build your own executable file, you need to follow these steps. - -#### Prerequisites - -To complete this guide, you need to have at least [version 1.13 of Go installed](https://golang.org/doc/install) on your device. - -To check if you have Go installed, run the following command: - -```bash -go version -``` - -If Go is installed, you should see the version that's installed. - ---- - -1. Clone the repository +## Client-Library and HTTP API reference - ```bash - git clone https://github.com/iotaledger/goshimmer.git - ``` +You can use the Go client-library to interact with GoShimmer (located under `github.com/iotaledger/goshimmer/client`). -2. Change into the `goshimmer` directory - -3. Use one of the following commands to build your executable file, depending on your operating system - - ```bash - # Linux and macOS - go build -o goshimmer - # Windows - go build -o goshimmer.exe - ``` - - **Note:** If you're using Windows PowerShell, enclose `goshimmer.exe` in single quotation marks. For example: go build -o 'goshimmer.exe'. +You can find more info about this on our [client-lib](https://github.com/iotaledger/goshimmer/wiki/Client-Lib:-Interaction-with-layers) wiki page. ## Getting started -When you first run GoShimmer, the node starts running and tries to connects to neighbors, using the autopeering module. - -To run other modules such as the `spammer` or the Glumb visualizer `graph`, you can configure GoShimmer to enable them through plugins. - -**Note:** For a list of all the available configuration parameters, you can run the following command: - -```bash -# Linux and macOS -./goshimmer -help -# Windows -goshimmer.exe -help -``` - -You can configure GoShimmer in the following ways: - -* Use a configuration file called `config.json` -* Use command-line options - -The repository includes a `config.json` file, which the executable file will find and use when you execute it. - -To use the command line, execute the file with one of the following commands, depending on your operating system - -```bash -# Linux and macOS -./goshimmer --node.enablePlugins "spammer" -# Windows -goshimmer.exe --node.enablePlugins "spammer" -``` - -Here, we use the command-line flags to enable the spammer plugin. This plugin allows you to send spam transactions to your node. - -### Configuring the dashboard - -GoShimmer has a dashboard that displays the current TPS, memory usage, neighbors and a Tangle explorer. - -You can change the dashboard configuration (e.g, bind address, port) under the `dashboard` section of the `config.json` file. For example, by changing the bind address to `0.0.0.0:8081`, you can enable remote access to the dashboard. - -To access the dashboard, you can use your browser (the default address is `http://127.0.0.1:8081`). - -  - -### Installing the Glumb visualizer - -The Glumb visualizer allows you to view the transactions in the network, using a web browser. - -1. Enable the `graph` plugin either in your `config.json` file or in the command line (`--node.enablePlugins=["graph"]`) - -2. If you're running GoShimmer with the precompiled executable file, do the following in the `goshimmer` directory: - - ```bash - git clone https://github.com/glumb/IOTAtangle.git - // only this version seems to be stable - cd IOTAtangle && git reset --hard 07bba77a296a2d06277cdae56aa963abeeb5f66e - cd ../ - git clone https://github.com/socketio/socket.io-client.git - ``` - -3. If you built the code from source, do the following in the `goshimmer` directory: - - ```bash - git submodule init - git submodule update - ``` - -To open the visualizer, run GoShimmer, and go to `127.0.0.1:8083` in a web browser. +You can find tutorials on how to [setup a GoShimmer node](https://github.com/iotaledger/goshimmer/wiki/Setting-up-a-GoShimmer-node), [writing a dApp](https://github.com/iotaledger/goshimmer/wiki/How-to-create-a-simple-dApp), [obtaining tokens from the faucet](https://github.com/iotaledger/goshimmer/wiki/How-to-obtain-tokens-from-the-faucet) and more on our [wiki](https://github.com/iotaledger/goshimmer/wiki). ## Supporting the project If you want to contribute to the code, consider posting a [bug report](https://github.com/iotaledger/goshimmer/issues/new-issue), feature request or a [pull request](https://github.com/iotaledger/goshimmer/pulls/). -See the [contributing guidelines](.github/CONTRIBUTING.md) for more information. +When creating a pull request, we recommend that you do the following: + +1. Clone the repository +2. Create a new branch for your fix or feature. For example, `git checkout -b fix/my-fix` or ` git checkout -b feat/my-feature`. +3. Run the `go fmt` command to make sure your code is well formatted +4. Document any exported packages +5. Target your pull request to be merged with `dev` ## Joining the discussion -If you want to get involved in the community, need help getting started, have any issues related to the repository or just want to discuss blockchain, distributed ledgers, and IoT with other people, feel free to join our [Discord](https://discord.iota.org/). +If you want to get involved in the community, need help getting started, have any issues related to the repository or just want to discuss blockchain, distributed ledgers, and IoT with other people, feel free to join our [Discord](https://discord.iota.org/). \ No newline at end of file diff --git a/client/autopeering.go b/client/autopeering.go new file mode 100644 index 0000000000000000000000000000000000000000..3d8e514bf1863e22d25140c1ffe055ffa3444dd4 --- /dev/null +++ b/client/autopeering.go @@ -0,0 +1,27 @@ +package client + +import ( + "fmt" + "net/http" + + webapi_autopeering "github.com/iotaledger/goshimmer/plugins/webapi/autopeering" +) + +const ( + routeGetNeighbors = "autopeering/neighbors" +) + +// GetNeighbors gets the chosen/accepted neighbors. +// If knownPeers is set, also all known peers to the node are returned additionally. +func (api *GoShimmerAPI) GetNeighbors(knownPeers bool) (*webapi_autopeering.Response, error) { + res := &webapi_autopeering.Response{} + if err := api.do(http.MethodGet, func() string { + if !knownPeers { + return routeGetNeighbors + } + return fmt.Sprintf("%s?known=1", routeGetNeighbors) + }(), nil, res); err != nil { + return nil, err + } + return res, nil +} diff --git a/client/data.go b/client/data.go new file mode 100644 index 0000000000000000000000000000000000000000..e252346b4b7219e9d974383a362973e04b621dcf --- /dev/null +++ b/client/data.go @@ -0,0 +1,23 @@ +package client + +import ( + "net/http" + + webapi_data "github.com/iotaledger/goshimmer/plugins/webapi/data" +) + +const ( + routeData = "data" +) + +// Data sends the given data (payload) by creating a message in the backend. +func (api *GoShimmerAPI) Data(data []byte) (string, error) { + + res := &webapi_data.Response{} + if err := api.do(http.MethodPost, routeData, + &webapi_data.Request{Data: data}, res); err != nil { + return "", err + } + + return res.ID, nil +} diff --git a/client/drng.go b/client/drng.go new file mode 100644 index 0000000000000000000000000000000000000000..68755b5b2ee5582881fd69514f0c33d73ed475e1 --- /dev/null +++ b/client/drng.go @@ -0,0 +1,49 @@ +package client + +import ( + "net/http" + + webapi_collectiveBeacon "github.com/iotaledger/goshimmer/plugins/webapi/drng/collectivebeacon" + webapi_committee "github.com/iotaledger/goshimmer/plugins/webapi/drng/info/committee" + webapi_randomness "github.com/iotaledger/goshimmer/plugins/webapi/drng/info/randomness" +) + +const ( + routeCollectiveBeacon = "drng/collectiveBeacon" + routeRandomness = "drng/info/randomness" + routeCommittee = "drng/info/committee" +) + +// BroadcastCollectiveBeacon sends the given collective beacon (payload) by creating a message in the backend. +func (api *GoShimmerAPI) BroadcastCollectiveBeacon(payload []byte) (string, error) { + + res := &webapi_collectiveBeacon.Response{} + if err := api.do(http.MethodPost, routeCollectiveBeacon, + &webapi_collectiveBeacon.Request{Payload: payload}, res); err != nil { + return "", err + } + + return res.ID, nil +} + +// GetRandomness gets the current randomness. +func (api *GoShimmerAPI) GetRandomness() (*webapi_randomness.Response, error) { + res := &webapi_randomness.Response{} + if err := api.do(http.MethodGet, func() string { + return routeRandomness + }(), nil, res); err != nil { + return nil, err + } + return res, nil +} + +// GetCommittee gets the current committee. +func (api *GoShimmerAPI) GetCommittee() (*webapi_committee.Response, error) { + res := &webapi_committee.Response{} + if err := api.do(http.MethodGet, func() string { + return routeCommittee + }(), nil, res); err != nil { + return nil, err + } + return res, nil +} diff --git a/client/faucet.go b/client/faucet.go new file mode 100644 index 0000000000000000000000000000000000000000..6e538ad28f63129528d49043fd311f967c9dda65 --- /dev/null +++ b/client/faucet.go @@ -0,0 +1,22 @@ +package client + +import ( + "net/http" + + webapi_faucet "github.com/iotaledger/goshimmer/plugins/webapi/faucet" +) + +const ( + routeFaucet = "faucet" +) + +// SendFaucetRequest requests funds from faucet nodes by sending a faucet request payload message. +func (api *GoShimmerAPI) SendFaucetRequest(base58EncodedAddr string) (*webapi_faucet.Response, error) { + res := &webapi_faucet.Response{} + if err := api.do(http.MethodPost, routeFaucet, + &webapi_faucet.Request{Address: base58EncodedAddr}, res); err != nil { + return nil, err + } + + return res, nil +} diff --git a/client/info.go b/client/info.go new file mode 100644 index 0000000000000000000000000000000000000000..08c43ae6f30d4c27a235bd548f2b17c3dda061ca --- /dev/null +++ b/client/info.go @@ -0,0 +1,20 @@ +package client + +import ( + "net/http" + + webapi_info "github.com/iotaledger/goshimmer/plugins/webapi/info" +) + +const ( + routeInfo = "info" +) + +// Info gets the info of the node. +func (api *GoShimmerAPI) Info() (*webapi_info.Response, error) { + res := &webapi_info.Response{} + if err := api.do(http.MethodGet, routeInfo, nil, res); err != nil { + return nil, err + } + return res, nil +} diff --git a/client/lib.go b/client/lib.go index 9f2da12438e084b097a11712fce31d194df26f9b..6f2992eb111c3287cd01c76a86ad906c0bcfe568 100644 --- a/client/lib.go +++ b/client/lib.go @@ -1,5 +1,5 @@ -// Implements a very simple wrapper for GoShimmer's web API . -package goshimmer +// Package client implements a very simple wrapper for GoShimmer's web API. +package client import ( "bytes" @@ -9,53 +9,39 @@ import ( "io" "io/ioutil" "net/http" - - webapi_broadcastData "github.com/iotaledger/goshimmer/plugins/webapi/broadcastData" - webapi_findTransactionHashes "github.com/iotaledger/goshimmer/plugins/webapi/findTransactionHashes" - webapi_getNeighbors "github.com/iotaledger/goshimmer/plugins/webapi/getNeighbors" - webapi_getTransactionObjectsByHash "github.com/iotaledger/goshimmer/plugins/webapi/getTransactionObjectsByHash" - webapi_getTransactionTrytesByHash "github.com/iotaledger/goshimmer/plugins/webapi/getTransactionTrytesByHash" - webapi_gtta "github.com/iotaledger/goshimmer/plugins/webapi/gtta" - webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi/spammer" - webapi_auth "github.com/iotaledger/goshimmer/plugins/webauth" - "github.com/iotaledger/iota.go/consts" - "github.com/iotaledger/iota.go/guards" - "github.com/iotaledger/iota.go/trinary" ) var ( - ErrBadRequest = errors.New("bad request") + // ErrBadRequest defines the "bad request" error. + ErrBadRequest = errors.New("bad request") + // ErrInternalServerError defines the "internal server error" error. ErrInternalServerError = errors.New("internal server error") - ErrNotFound = errors.New("not found") - ErrUnauthorized = errors.New("unauthorized") - ErrUnknownError = errors.New("unknown error") - ErrNotImplemented = errors.New("operation not implemented/supported/available") + // ErrNotFound defines the "not found" error. + ErrNotFound = errors.New("not found") + // ErrUnauthorized defines the "unauthorized" error. + ErrUnauthorized = errors.New("unauthorized") + // ErrUnknownError defines the "unknown error" error. + ErrUnknownError = errors.New("unknown error") + // ErrNotImplemented defines the "operation not implemented/supported/available" error. + ErrNotImplemented = errors.New("operation not implemented/supported/available") ) const ( - routeBroadcastData = "broadcastData" - routeGetTransactionTrytesByHash = "getTransactionTrytesByHash" - routeGetTransactionObjectsByHash = "getTransactionObjectsByHash" - routeFindTransactionsHashes = "findTransactionHashes" - routeGetNeighbors = "getNeighbors" - routeGetTransactionsToApprove = "getTransactionsToApprove" - routeSpammer = "spammer" - routeLogin = "login" - contentTypeJSON = "application/json" ) -func NewGoShimmerAPI(node string, httpClient ...http.Client) *GoShimmerAPI { +// NewGoShimmerAPI returns a new *GoShimmerAPI with the given baseURL and httpClient. +func NewGoShimmerAPI(baseURL string, httpClient ...http.Client) *GoShimmerAPI { if len(httpClient) > 0 { - return &GoShimmerAPI{node: node, httpClient: httpClient[0]} + return &GoShimmerAPI{baseURL: baseURL, httpClient: httpClient[0]} } - return &GoShimmerAPI{node: node} + return &GoShimmerAPI{baseURL: baseURL} } // GoShimmerAPI is an API wrapper over the web API of GoShimmer. type GoShimmerAPI struct { httpClient http.Client - node string + baseURL string jwt string } @@ -83,7 +69,7 @@ func interpretBody(res *http.Response, decodeTo interface{}) error { case http.StatusInternalServerError: return fmt.Errorf("%w: %s", ErrInternalServerError, errRes.Error) case http.StatusNotFound: - return fmt.Errorf("%w: %s", ErrNotFound, errRes.Error) + return fmt.Errorf("%w: %s", ErrNotFound, res.Request.URL.String()) case http.StatusBadRequest: return fmt.Errorf("%w: %s", ErrBadRequest, errRes.Error) case http.StatusUnauthorized: @@ -107,7 +93,7 @@ func (api *GoShimmerAPI) do(method string, route string, reqObj interface{}, res } // construct request - req, err := http.NewRequest(method, fmt.Sprintf("%s/%s", api.node, route), func() io.Reader { + req, err := http.NewRequest(method, fmt.Sprintf("%s/%s", api.baseURL, route), func() io.Reader { if data == nil { return nil } @@ -143,117 +129,7 @@ func (api *GoShimmerAPI) do(method string, route string, reqObj interface{}, res return nil } -// Login authorizes this API instance against the web API. -// You must call this function before any before any other call, if the web-auth plugin is enabled. -func (api *GoShimmerAPI) Login(username string, password string) error { - res := &webapi_auth.Response{} - if err := api.do(http.MethodPost, routeLogin, - &webapi_auth.Request{Username: username, Password: password}, res); err != nil { - return err - } - api.jwt = res.Token - return nil -} - -// BroadcastData sends the given data by creating a zero value transaction in the backend targeting the given address. -func (api *GoShimmerAPI) BroadcastData(targetAddress trinary.Trytes, data string) (trinary.Hash, error) { - if !guards.IsHash(targetAddress) { - return "", fmt.Errorf("%w: invalid address: %s", consts.ErrInvalidHash, targetAddress) - } - - res := &webapi_broadcastData.Response{} - if err := api.do(http.MethodPost, routeBroadcastData, - &webapi_broadcastData.Request{Address: targetAddress, Data: data}, res); err != nil { - return "", err - } - - return res.Hash, nil -} - -// GetTransactionTrytesByHash gets the corresponding transaction trytes given the transaction hashes. -func (api *GoShimmerAPI) GetTransactionTrytesByHash(txHashes trinary.Hashes) ([]trinary.Trytes, error) { - for _, hash := range txHashes { - if !guards.IsTrytes(hash) { - return nil, fmt.Errorf("%w: invalid hash: %s", consts.ErrInvalidHash, hash) - } - } - - res := &webapi_getTransactionTrytesByHash.Response{} - if err := api.do(http.MethodPost, routeGetTransactionTrytesByHash, - &webapi_getTransactionTrytesByHash.Request{Hashes: txHashes}, res); err != nil { - return nil, err - } - - return res.Trytes, nil -} - -// GetTransactionObjectsByHash gets the transaction objects given the transaction hashes. -func (api *GoShimmerAPI) GetTransactionObjectsByHash(txHashes trinary.Hashes) ([]webapi_getTransactionObjectsByHash.Transaction, error) { - for _, hash := range txHashes { - if !guards.IsTrytes(hash) { - return nil, fmt.Errorf("%w: invalid hash: %s", consts.ErrInvalidHash, hash) - } - } - - res := &webapi_getTransactionObjectsByHash.Response{} - if err := api.do(http.MethodPost, routeGetTransactionObjectsByHash, - &webapi_getTransactionObjectsByHash.Request{Hashes: txHashes}, res); err != nil { - return nil, err - } - - return res.Transactions, nil -} - -// FindTransactionHashes finds the given transaction hashes given the query. -func (api *GoShimmerAPI) FindTransactionHashes(query *webapi_findTransactionHashes.Request) ([]trinary.Hashes, error) { - for _, hash := range query.Addresses { - if !guards.IsTrytes(hash) { - return nil, fmt.Errorf("%w: invalid hash: %s", consts.ErrInvalidHash, hash) - } - } - - res := &webapi_findTransactionHashes.Response{} - if err := api.do(http.MethodPost, routeFindTransactionsHashes, query, res); err != nil { - return nil, err - } - - return res.Transactions, nil -} - -// GetNeighbors gets the chosen/accepted neighbors. -// If knownPeers is set, also all known peers to the node are returned additionally. -func (api *GoShimmerAPI) GetNeighbors(knownPeers bool) (*webapi_getNeighbors.Response, error) { - res := &webapi_getNeighbors.Response{} - if err := api.do(http.MethodGet, func() string { - if !knownPeers { - return routeGetNeighbors - } - return fmt.Sprintf("%s?known=1", routeGetNeighbors) - }(), nil, res); err != nil { - return nil, err - } - return res, nil -} - -// GetTips executes the tip-selection on the node to retrieve tips to approve. -func (api *GoShimmerAPI) GetTransactionsToApprove() (*webapi_gtta.Response, error) { - res := &webapi_gtta.Response{} - if err := api.do(http.MethodGet, routeGetTransactionsToApprove, nil, res); err != nil { - return nil, err - } - return res, nil -} - -// ToggleSpammer toggles the node internal spammer. -func (api *GoShimmerAPI) ToggleSpammer(enable bool) (*webapi_spammer.Response, error) { - res := &webapi_spammer.Response{} - if err := api.do(http.MethodGet, func() string { - if enable { - return fmt.Sprintf("%s?cmd=start", routeSpammer) - } - return fmt.Sprintf("%s?cmd=stop", routeSpammer) - }(), nil, res); err != nil { - return nil, err - } - return res, nil +// BaseURL returns the baseURL of the API. +func (api *GoShimmerAPI) BaseURL() string { + return api.baseURL } diff --git a/client/login.go b/client/login.go new file mode 100644 index 0000000000000000000000000000000000000000..610abf77c55f9692e1d5531edf64f7df7fec09f8 --- /dev/null +++ b/client/login.go @@ -0,0 +1,23 @@ +package client + +import ( + "net/http" + + webapi_auth "github.com/iotaledger/goshimmer/plugins/webauth" +) + +const ( + routeLogin = "login" +) + +// Login authorizes this API instance against the web API. +// You must call this function before any other call, if the web-auth plugin is enabled. +func (api *GoShimmerAPI) Login(username string, password string) error { + res := &webapi_auth.Response{} + if err := api.do(http.MethodPost, routeLogin, + &webapi_auth.Request{Username: username, Password: password}, res); err != nil { + return err + } + api.jwt = res.Token + return nil +} diff --git a/client/message.go b/client/message.go new file mode 100644 index 0000000000000000000000000000000000000000..a920c336d9acba56b8bf967eff2c2af993f85923 --- /dev/null +++ b/client/message.go @@ -0,0 +1,40 @@ +package client + +import ( + "net/http" + + webapi_message "github.com/iotaledger/goshimmer/plugins/webapi/message" +) + +const ( + routeFindByID = "message/findById" + routeSendPayload = "message/sendPayload" +) + +// FindMessageByID finds messages by the given base58 encoded IDs. The messages are returned in the same order as +// the given IDs. Non available messages are empty at their corresponding index. +func (api *GoShimmerAPI) FindMessageByID(base58EncodedIDs []string) (*webapi_message.Response, error) { + res := &webapi_message.Response{} + + if err := api.do( + http.MethodPost, + routeFindByID, + &webapi_message.Request{IDs: base58EncodedIDs}, + res, + ); err != nil { + return nil, err + } + + return res, nil +} + +// SendPayload send a message with the given payload. +func (api *GoShimmerAPI) SendPayload(payload []byte) (string, error) { + res := &webapi_message.MsgResponse{} + if err := api.do(http.MethodPost, routeSendPayload, + &webapi_message.MsgRequest{Payload: payload}, res); err != nil { + return "", err + } + + return res.ID, nil +} diff --git a/client/spammer.go b/client/spammer.go new file mode 100644 index 0000000000000000000000000000000000000000..0e747a69380b15061664e17843f8bfa57086fc4b --- /dev/null +++ b/client/spammer.go @@ -0,0 +1,26 @@ +package client + +import ( + "fmt" + "net/http" + + webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi/spammer" +) + +const ( + routeSpammer = "spammer" +) + +// ToggleSpammer toggles the node internal spammer. +func (api *GoShimmerAPI) ToggleSpammer(enable bool) (*webapi_spammer.Response, error) { + res := &webapi_spammer.Response{} + if err := api.do(http.MethodGet, func() string { + if enable { + return fmt.Sprintf("%s?cmd=start", routeSpammer) + } + return fmt.Sprintf("%s?cmd=stop", routeSpammer) + }(), nil, res); err != nil { + return nil, err + } + return res, nil +} diff --git a/client/value.go b/client/value.go new file mode 100644 index 0000000000000000000000000000000000000000..342aea66cc536113b49ead9e465ef6fac1408045 --- /dev/null +++ b/client/value.go @@ -0,0 +1,64 @@ +package client + +import ( + "fmt" + "net/http" + + webapi_attachments "github.com/iotaledger/goshimmer/plugins/webapi/value/attachments" + webapi_gettxn "github.com/iotaledger/goshimmer/plugins/webapi/value/gettransactionbyid" + webapi_sendtxn "github.com/iotaledger/goshimmer/plugins/webapi/value/sendtransaction" + webapi_unspentoutputs "github.com/iotaledger/goshimmer/plugins/webapi/value/unspentoutputs" +) + +const ( + routeAttachments = "value/attachments" + routeGetTxnByID = "value/transactionByID" + routeSendTxn = "value/sendTransaction" + routeUnspentOutputs = "value/unspentOutputs" +) + +// GetAttachments gets the attachments of a transaction ID +func (api *GoShimmerAPI) GetAttachments(base58EncodedTxnID string) (*webapi_attachments.Response, error) { + res := &webapi_attachments.Response{} + if err := api.do(http.MethodGet, func() string { + return fmt.Sprintf("%s?txnID=%s", routeAttachments, base58EncodedTxnID) + }(), nil, res); err != nil { + return nil, err + } + + return res, nil +} + +// GetTransactionByID gets the transaction of a transaction ID +func (api *GoShimmerAPI) GetTransactionByID(base58EncodedTxnID string) (*webapi_gettxn.Response, error) { + res := &webapi_gettxn.Response{} + if err := api.do(http.MethodGet, func() string { + return fmt.Sprintf("%s?txnID=%s", routeGetTxnByID, base58EncodedTxnID) + }(), nil, res); err != nil { + return nil, err + } + + return res, nil +} + +// GetUnspentOutputs return unspent output IDs of addresses +func (api *GoShimmerAPI) GetUnspentOutputs(addresses []string) (*webapi_unspentoutputs.Response, error) { + res := &webapi_unspentoutputs.Response{} + if err := api.do(http.MethodPost, routeUnspentOutputs, + &webapi_unspentoutputs.Request{Addresses: addresses}, res); err != nil { + return nil, err + } + + return res, nil +} + +// SendTransaction sends the transaction(bytes) to Tangle and returns transaction ID +func (api *GoShimmerAPI) SendTransaction(txnBytes []byte) (string, error) { + res := &webapi_sendtxn.Response{} + if err := api.do(http.MethodPost, routeSendTxn, + &webapi_sendtxn.Request{TransactionBytes: txnBytes}, res); err != nil { + return "", err + } + + return res.TransactionID, nil +} diff --git a/config.default.json b/config.default.json new file mode 100644 index 0000000000000000000000000000000000000000..5f172cac790624ecfbedbd7aeb46c5d84ddcde82 --- /dev/null +++ b/config.default.json @@ -0,0 +1,93 @@ +{ + "analysis": { + "client": { + "serverAddress": "ressims.iota.cafe:21888" + }, + "server": { + "bindAddress": "0.0.0.0:16178" + }, + "dashboard": { + "bindAddress": "0.0.0.0:8000", + "dev": false + } + }, + "autopeering": { + "entryNodes": [ + "2PV5487xMw5rasGBXXWeqSi4hLz7r19YBt8Y1TGAsQbj@ressims.iota.cafe:15626" + ], + "port": 14626 + }, + "dashboard": { + "bindAddress": "127.0.0.1:8081", + "dev": false, + "basic_auth": { + "enabled": false, + "username": "goshimmer", + "password": "goshimmer" + } + }, + "database": { + "directory": "mainnetdb", + "inMemory": false + }, + "drng": { + "instanceId": 1, + "threshold": 3, + "distributedPubKey": "", + "committeeMembers": [] + }, + "fpc": { + "bindAddress": "0.0.0.0:10895" + }, + "gossip": { + "port": 14666 + }, + "logger": { + "level": "info", + "disableCaller": false, + "disableStacktrace": false, + "encoding": "console", + "outputPaths": [ + "stdout", + "goshimmer.log" + ], + "disableEvents": true, + "remotelog": { + "serverAddress": "ressims.iota.cafe:5213" + } + }, + "metrics": { + "local": true, + "global": false + }, + "network": { + "bindAddress": "0.0.0.0", + "externalAddress": "auto" + }, + "node": { + "disablePlugins": [], + "enablePlugins": [] + }, + "pow": { + "difficulty": 22, + "numThreads": 1, + "timeout": "1m" + }, + "profiling": { + "bindAddress": "127.0.0.1:6061" + }, + "prometheus": { + "bindAddress": "127.0.0.1:9311" + }, + "webapi": { + "auth": { + "password": "goshimmer", + "privateKey": "", + "username": "goshimmer" + }, + "bindAddress": "127.0.0.1:8080" + }, + "networkdelay": { + "originPublicKey": "9DB3j9cWYSuEEtkvanrzqkzCQMdH1FGv3TawJdVbDxkd" + } +} diff --git a/dapps/faucet/dapp.go b/dapps/faucet/dapp.go new file mode 100644 index 0000000000000000000000000000000000000000..fff78faa8d426dd150777ced9f246bc736df744a --- /dev/null +++ b/dapps/faucet/dapp.go @@ -0,0 +1,133 @@ +package faucet + +import ( + "runtime" + "sync" + "time" + + faucet "github.com/iotaledger/goshimmer/dapps/faucet/packages" + faucetpayload "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/iotaledger/hive.go/workerpool" + "github.com/mr-tron/base58" + flag "github.com/spf13/pflag" +) + +const ( + // PluginName is the name of the faucet dApp. + PluginName = "Faucet" + + // CfgFaucetSeed defines the base58 encoded seed the faucet uses. + CfgFaucetSeed = "faucet.seed" + // CfgFaucetTokensPerRequest defines the amount of tokens the faucet should send for each request. + CfgFaucetTokensPerRequest = "faucet.tokensPerRequest" + // CfgFaucetMaxTransactionBookedAwaitTimeSeconds defines the time to await for the transaction fulfilling a funding request + // to become booked in the value layer. + CfgFaucetMaxTransactionBookedAwaitTimeSeconds = "faucet.maxTransactionBookedAwaitTimeSeconds" +) + +func init() { + flag.String(CfgFaucetSeed, "", "the base58 encoded seed of the faucet, must be defined if this dApp is enabled") + flag.Int(CfgFaucetTokensPerRequest, 1337, "the amount of tokens the faucet should send for each request") + flag.Int(CfgFaucetMaxTransactionBookedAwaitTimeSeconds, 5, "the max amount of time for a funding transaction to become booked in the value layer.") +} + +var ( + // App is the "plugin" instance of the faucet application. + plugin *node.Plugin + pluginOnce sync.Once + _faucet *faucet.Faucet + faucetOnce sync.Once + log *logger.Logger + fundingWorkerPool *workerpool.WorkerPool + fundingWorkerCount = runtime.GOMAXPROCS(0) + fundingWorkerQueueSize = 500 +) + +// App returns the plugin instance of the faucet dApp. +func App() *node.Plugin { + pluginOnce.Do(func() { + plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) + }) + return plugin +} + +// Faucet gets the faucet instance the faucet dApp has initialized. +func Faucet() *faucet.Faucet { + faucetOnce.Do(func() { + base58Seed := config.Node().GetString(CfgFaucetSeed) + if len(base58Seed) == 0 { + log.Fatal("a seed must be defined when enabling the faucet dApp") + } + seedBytes, err := base58.Decode(base58Seed) + if err != nil { + log.Fatalf("configured seed for the faucet is invalid: %s", err) + } + tokensPerRequest := config.Node().GetInt64(CfgFaucetTokensPerRequest) + if tokensPerRequest <= 0 { + log.Fatalf("the amount of tokens to fulfill per request must be above zero") + } + maxTxBookedAwaitTime := config.Node().GetInt64(CfgFaucetMaxTransactionBookedAwaitTimeSeconds) + if maxTxBookedAwaitTime <= 0 { + log.Fatalf("the max transaction booked await time must be more than 0") + } + _faucet = faucet.New(seedBytes, tokensPerRequest, time.Duration(maxTxBookedAwaitTime)*time.Second) + }) + return _faucet +} + +func configure(*node.Plugin) { + log = logger.NewLogger(PluginName) + Faucet() + + fundingWorkerPool = workerpool.New(func(task workerpool.Task) { + msg := task.Param(0).(*message.Message) + addr := msg.Payload().(*faucetpayload.Payload).Address() + msg, txID, err := Faucet().SendFunds(msg) + if err != nil { + log.Errorf("couldn't fulfill funding request to %s: %s", addr, err) + return + } + log.Infof("sent funds to address %s via tx %s and msg %s", addr, txID, msg.Id().String()) + }, workerpool.WorkerCount(fundingWorkerCount), workerpool.QueueSize(fundingWorkerQueueSize)) + + configureEvents() +} + +func run(*node.Plugin) { + if err := daemon.BackgroundWorker("[Faucet]", func(shutdownSignal <-chan struct{}) { + fundingWorkerPool.Start() + defer fundingWorkerPool.Stop() + <-shutdownSignal + }, shutdown.PriorityFaucet); err != nil { + log.Panicf("Failed to start daemon: %s", err) + } +} + +func configureEvents() { + messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + defer cachedMessage.Release() + defer cachedMessageMetadata.Release() + + msg := cachedMessage.Unwrap() + if msg == nil || !faucetpayload.IsFaucetReq(msg) { + return + } + + addr := msg.Payload().(*faucetpayload.Payload).Address() + _, added := fundingWorkerPool.TrySubmit(msg) + if !added { + log.Info("dropped funding request for address %s as queue is full", addr) + return + } + log.Infof("enqueued funding request for address %s", addr) + })) +} diff --git a/dapps/faucet/packages/errors.go b/dapps/faucet/packages/errors.go new file mode 100644 index 0000000000000000000000000000000000000000..c4a009b1709b542fc8f970a481049a8926cb0799 --- /dev/null +++ b/dapps/faucet/packages/errors.go @@ -0,0 +1,8 @@ +package faucet + +import "errors" + +var ( + // ErrInvalidAddr represents an error that is triggered when an invalid address is detected. + ErrInvalidAddr = errors.New("invalid address") +) diff --git a/dapps/faucet/packages/faucet.go b/dapps/faucet/packages/faucet.go new file mode 100644 index 0000000000000000000000000000000000000000..dd40e51fffa73802939bc5881ffed6fd8089dc6b --- /dev/null +++ b/dapps/faucet/packages/faucet.go @@ -0,0 +1,178 @@ +package faucet + +import ( + "errors" + "fmt" + "sync" + "time" + + faucetpayload "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/iotaledger/hive.go/events" +) + +var ( + // ErrFundingTxNotBookedInTime is returned when a funding transaction didn't get booked + // by this node in the maximum defined await time for it to get booked. + ErrFundingTxNotBookedInTime = errors.New("funding transaction didn't get booked in time") +) + +// New creates a new faucet using the given seed and tokensPerRequest config. +func New(seed []byte, tokensPerRequest int64, maxTxBookedAwaitTime time.Duration) *Faucet { + return &Faucet{ + tokensPerRequest: tokensPerRequest, + wallet: wallet.New(seed), + maxTxBookedAwaitTime: maxTxBookedAwaitTime, + } +} + +// The Faucet implements a component which will send tokens to actors requesting tokens. +type Faucet struct { + sync.Mutex + // the amount of tokens to send to every request + tokensPerRequest int64 + // the wallet instance of the faucet holding the tokens + wallet *wallet.Wallet + // the time to await for the transaction fulfilling a funding request + // to become booked in the value layer + maxTxBookedAwaitTime time.Duration +} + +// SendFunds sends IOTA tokens to the address from faucet request. +func (f *Faucet) SendFunds(msg *message.Message) (m *message.Message, txID string, err error) { + // ensure that only one request is being processed any given time + f.Lock() + defer f.Unlock() + + addr := msg.Payload().(*faucetpayload.Payload).Address() + + // get the output ids for the inputs and remainder balance + outputIds, addrsIndices, remainder := f.collectUTXOsForFunding() + + tx := transaction.New( + // inputs + transaction.NewInputs(outputIds...), + + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + addr: { + balance.New(balance.ColorIOTA, f.tokensPerRequest), + }, + }), + ) + + // add remainder address if needed + if remainder > 0 { + remainAddr := f.nextUnusedAddress() + tx.Outputs().Add(remainAddr, []*balance.Balance{balance.New(balance.ColorIOTA, remainder)}) + } + + for index := range addrsIndices { + tx.Sign(signaturescheme.ED25519(*f.wallet.Seed().KeyPair(index))) + } + + // prepare value payload with value factory + payload := valuetransfers.ValueObjectFactory().IssueTransaction(tx) + + // attach to message layer + msg, err = issuer.IssuePayload(payload) + if err != nil { + return nil, "", err + } + + // block for a certain amount of time until we know that the transaction + // actually got booked by this node itself + // TODO: replace with an actual more reactive way + bookedInTime := f.awaitTransactionBooked(tx.ID(), f.maxTxBookedAwaitTime) + if !bookedInTime { + return nil, "", fmt.Errorf("%w: tx %s", ErrFundingTxNotBookedInTime, tx.ID().String()) + } + + return msg, tx.ID().String(), nil +} + +// awaitTransactionBooked awaits maxAwait for the given transaction to get booked. +func (f *Faucet) awaitTransactionBooked(txID transaction.ID, maxAwait time.Duration) bool { + booked := make(chan struct{}, 1) + // exit is used to let the caller exit if for whatever + // reason the same transaction gets booked multiple times + exit := make(chan struct{}) + defer close(exit) + closure := events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *tangle.CachedTransactionMetadata, decisionPending bool) { + defer cachedTransaction.Release() + defer cachedTransactionMetadata.Release() + if cachedTransaction.Unwrap().ID() != txID { + return + } + select { + case booked <- struct{}{}: + case <-exit: + } + }) + valuetransfers.Tangle().Events.TransactionBooked.Attach(closure) + defer valuetransfers.Tangle().Events.TransactionBooked.Detach(closure) + select { + case <-time.After(maxAwait): + return false + case <-booked: + return true + } +} + +// collectUTXOsForFunding iterates over the faucet's UTXOs until the token threshold is reached. +// this function also returns the remainder balance for the given outputs. +func (f *Faucet) collectUTXOsForFunding() (outputIds []transaction.OutputID, addrsIndices map[uint64]struct{}, remainder int64) { + var total = f.tokensPerRequest + var i uint64 + addrsIndices = map[uint64]struct{}{} + + // get a list of address for inputs + for i = 0; total > 0; i++ { + addr := f.wallet.Seed().Address(i) + valuetransfers.Tangle().OutputsOnAddress(addr).Consume(func(output *tangle.Output) { + if output.ConsumerCount() > 0 || total == 0 { + return + } + + var val int64 + for _, coloredBalance := range output.Balances() { + val += coloredBalance.Value + } + addrsIndices[i] = struct{}{} + + // get unspent output ids and check if it's conflict + if val <= total { + total -= val + } else { + remainder = val - total + total = 0 + } + outputIds = append(outputIds, output.ID()) + }) + } + + return +} + +// nextUnusedAddress generates an unused address from the faucet seed. +func (f *Faucet) nextUnusedAddress() address.Address { + var index uint64 + for index = 0; ; index++ { + addr := f.wallet.Seed().Address(index) + cachedOutputs := valuetransfers.Tangle().OutputsOnAddress(addr) + if len(cachedOutputs) == 0 { + // unused address + cachedOutputs.Release() + return addr + } + cachedOutputs.Release() + } +} diff --git a/dapps/faucet/packages/faucet_test.go b/dapps/faucet/packages/faucet_test.go new file mode 100644 index 0000000000000000000000000000000000000000..9f56fc2e130fef818d3a9dba590641ffb127048c --- /dev/null +++ b/dapps/faucet/packages/faucet_test.go @@ -0,0 +1,46 @@ +package faucet + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" + + faucet "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + data "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +func TestIsFaucetReq(t *testing.T) { + keyPair := ed25519.GenerateKeyPair() + local := identity.NewLocalIdentity(keyPair.PublicKey, keyPair.PrivateKey) + + faucetMsg := message.New( + message.EmptyId, + message.EmptyId, + time.Now(), + local.PublicKey(), + 0, + faucet.New(address.Random()), + 0, + ed25519.EmptySignature, + ) + + dataMsg := message.New( + message.EmptyId, + message.EmptyId, + time.Now(), + local.PublicKey(), + 0, + data.NewData([]byte("data")), + 0, + ed25519.EmptySignature, + ) + + assert.Equal(t, true, faucet.IsFaucetReq(faucetMsg)) + assert.Equal(t, false, faucet.IsFaucetReq(dataMsg)) +} diff --git a/dapps/faucet/packages/payload/payload.go b/dapps/faucet/packages/payload/payload.go new file mode 100644 index 0000000000000000000000000000000000000000..264aa31134635cf2ba81670eadae8289efe16618 --- /dev/null +++ b/dapps/faucet/packages/payload/payload.go @@ -0,0 +1,128 @@ +package faucetpayload + +import ( + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/stringify" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +const ( + // ObjectName defines the name of the facuet object. + ObjectName = "faucet" +) + +// Payload represents a request which contains an address for the faucet to send funds to. +type Payload struct { + payloadType payload.Type + address address.Address +} + +// Type represents the identifier for the faucet Payload type. +var Type = payload.Type(2) + +// New is the constructor of a Payload and creates a new Payload object from the given details. +func New(addr address.Address) *Payload { + return &Payload{ + payloadType: Type, + address: addr, + } +} + +func init() { + payload.RegisterType(Type, ObjectName, GenericPayloadUnmarshalerFactory(Type)) +} + +// FromBytes parses the marshaled version of a Payload into an object. +// It either returns a new Payload or fills an optionally provided Payload with the parsed information. +func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, err error, consumedBytes int) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Payload{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to FromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read data + result.payloadType, err = marshalUtil.ReadUint32() + if err != nil { + return + } + payloadBytes, err := marshalUtil.ReadUint32() + if err != nil { + return + } + addr, err := marshalUtil.ReadBytes(int(payloadBytes)) + if err != nil { + return + } + result.address, _, _ = address.FromBytes(addr) + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Type returns the type of the faucet Payload. +func (faucetPayload *Payload) Type() payload.Type { + return faucetPayload.payloadType +} + +// Address returns the address of the faucet Payload. +func (faucetPayload *Payload) Address() address.Address { + return faucetPayload.address +} + +// Bytes marshals the data payload into a sequence of bytes. +func (faucetPayload *Payload) Bytes() []byte { + // initialize helper + marshalUtil := marshalutil.New() + + // marshal the payload specific information + marshalUtil.WriteUint32(faucetPayload.Type()) + marshalUtil.WriteUint32(uint32(len(faucetPayload.address))) + marshalUtil.WriteBytes(faucetPayload.address.Bytes()) + + // return result + return marshalUtil.Bytes() +} + +// Unmarshal unmarshals a given slice of bytes and fills the object. +func (faucetPayload *Payload) Unmarshal(data []byte) (err error) { + _, err, _ = FromBytes(data, faucetPayload) + + return +} + +// String returns a human readable version of faucet payload (for debug purposes). +func (faucetPayload *Payload) String() string { + return stringify.Struct("FaucetPayload", + stringify.StructField("address", faucetPayload.Address().String()), + ) +} + +// GenericPayloadUnmarshalerFactory sets the generic unmarshaler. +func GenericPayloadUnmarshalerFactory(payloadType payload.Type) payload.Unmarshaler { + return func(data []byte) (payload payload.Payload, err error) { + payload = &Payload{ + payloadType: payloadType, + } + err = payload.Unmarshal(data) + + return + } +} + +// IsFaucetReq checks if the message is faucet payload. +func IsFaucetReq(msg *message.Message) bool { + return msg.Payload().Type() == Type +} diff --git a/dapps/faucet/packages/payload/payload_test.go b/dapps/faucet/packages/payload/payload_test.go new file mode 100644 index 0000000000000000000000000000000000000000..40684e9879ba132e27508ace9dd9ce9c031d0376 --- /dev/null +++ b/dapps/faucet/packages/payload/payload_test.go @@ -0,0 +1,57 @@ +package faucetpayload + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +func ExamplePayload() { + keyPair := ed25519.GenerateKeyPair() + local := identity.NewLocalIdentity(keyPair.PublicKey, keyPair.PrivateKey) + + // 1. create faucet payload + faucetPayload := New( + // request address + address.Random(), + ) + + // 2. build actual message + tx := message.New( + message.EmptyId, + message.EmptyId, + time.Now(), + local.PublicKey(), + 0, + faucetPayload, + 0, + ed25519.EmptySignature, + ) + fmt.Println(tx.String()) +} + +func TestPayload(t *testing.T) { + originalPayload := New(address.Random()) + + clonedPayload1, err, _ := FromBytes(originalPayload.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, originalPayload.Address(), clonedPayload1.Address()) + + clonedPayload2, err, _ := FromBytes(clonedPayload1.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, originalPayload.Address(), clonedPayload2.Address()) +} diff --git a/dapps/networkdelay/dapp.go b/dapps/networkdelay/dapp.go new file mode 100644 index 0000000000000000000000000000000000000000..426f5da498b7242eeff3fc01257f3ce13f450ab6 --- /dev/null +++ b/dapps/networkdelay/dapp.go @@ -0,0 +1,140 @@ +package networkdelay + +import ( + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + messageTangle "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/goshimmer/plugins/remotelog" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/mr-tron/base58" +) + +const ( + // PluginName contains the human readable name of the plugin. + PluginName = "NetworkDelay" + + // CfgNetworkDelayOriginPublicKey defines the config flag of the issuer node public key. + CfgNetworkDelayOriginPublicKey = "networkdelay.originPublicKey" + + remoteLogType = "networkdelay" +) + +var ( + // App is the "plugin" instance of the network delay application. + app *node.Plugin + once sync.Once + + // log holds a reference to the logger used by this app. + log *logger.Logger + + remoteLogger *remotelog.RemoteLoggerConn + + myID string + myPublicKey ed25519.PublicKey + originPublicKey ed25519.PublicKey +) + +// App gets the plugin instance. +func App() *node.Plugin { + once.Do(func() { + app = node.NewPlugin(PluginName, node.Disabled, configure) + }) + return app +} + +func configure(_ *node.Plugin) { + // configure logger + log = logger.NewLogger(PluginName) + + remoteLogger = remotelog.RemoteLogger() + + if local.GetInstance() != nil { + myID = local.GetInstance().ID().String() + myPublicKey = local.GetInstance().PublicKey() + } + + // get origin public key from config + bytes, err := base58.Decode(config.Node().GetString(CfgNetworkDelayOriginPublicKey)) + if err != nil { + log.Fatalf("could not parse %s config entry as base58. %v", CfgNetworkDelayOriginPublicKey, err) + } + originPublicKey, _, err = ed25519.PublicKeyFromBytes(bytes) + if err != nil { + log.Fatalf("could not parse %s config entry as public key. %v", CfgNetworkDelayOriginPublicKey, err) + } + + configureWebAPI() + + // subscribe to message-layer + messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(onReceiveMessageFromMessageLayer)) +} + +func onReceiveMessageFromMessageLayer(cachedMessage *message.CachedMessage, cachedMessageMetadata *messageTangle.CachedMessageMetadata) { + defer cachedMessage.Release() + defer cachedMessageMetadata.Release() + + solidMessage := cachedMessage.Unwrap() + if solidMessage == nil { + log.Debug("failed to unpack solid message from message layer") + + return + } + + messagePayload := solidMessage.Payload() + if messagePayload.Type() != Type { + return + } + + // check for node identity + issuerPubKey := solidMessage.IssuerPublicKey() + if issuerPubKey != originPublicKey || issuerPubKey == myPublicKey { + return + } + + networkDelayObject, ok := messagePayload.(*Object) + if !ok { + log.Info("could not cast payload to network delay object") + + return + } + + now := time.Now().UnixNano() + + // abort if message was sent more than 1min ago + // this should only happen due to a node resyncing + if time.Duration(now-networkDelayObject.sentTime) > time.Minute { + log.Debugf("Received network delay message with >1min delay\n%s", networkDelayObject) + return + } + + sendToRemoteLog(networkDelayObject, now) +} + +func sendToRemoteLog(networkDelayObject *Object, receiveTime int64) { + m := networkDelay{ + NodeID: myID, + ID: networkDelayObject.id.String(), + SentTime: networkDelayObject.sentTime, + ReceiveTime: receiveTime, + Delta: receiveTime - networkDelayObject.sentTime, + Type: remoteLogType, + } + _ = remoteLogger.Send(m) +} + +type networkDelay struct { + NodeID string `json:"nodeId"` + ID string `json:"id"` + SentTime int64 `json:"sentTime"` + ReceiveTime int64 `json:"receiveTime"` + Delta int64 `json:"delta"` + Type string `json:"type"` +} diff --git a/dapps/networkdelay/object.go b/dapps/networkdelay/object.go new file mode 100644 index 0000000000000000000000000000000000000000..40e45947dddddc662c292e6ec006e59920731f86 --- /dev/null +++ b/dapps/networkdelay/object.go @@ -0,0 +1,161 @@ +package networkdelay + +import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/stringify" + "github.com/mr-tron/base58" +) + +const ( + // ObjectName defines the name of the networkdelay object. + ObjectName = "networkdelay" +) + +// ID represents a 32 byte ID of a network delay object. +type ID [32]byte + +// String returns a human-friendly representation of the ID. +func (id ID) String() string { + return base58.Encode(id[:]) +} + +// Object represents the network delay object type. +type Object struct { + id ID + sentTime int64 + + bytes []byte + bytesMutex sync.RWMutex +} + +// NewObject creates a new network delay object. +func NewObject(id ID, sentTime int64) *Object { + return &Object{ + id: id, + sentTime: sentTime, + } +} + +// FromBytes parses the marshaled version of an Object into a Go object. +// It either returns a new Object or fills an optionally provided Object with the parsed information. +func FromBytes(bytes []byte, optionalTargetObject ...*Object) (result *Object, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = Parse(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Parse unmarshals an Object using the given marshalUtil (for easier marshaling/unmarshaling). +func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTarget ...*Object) (result *Object, err error) { + // determine the target that will hold the unmarshaled information + switch len(optionalTarget) { + case 0: + result = &Object{} + case 1: + result = optionalTarget[0] + default: + panic("too many arguments in call to FromBytes") + } + + // read information that are required to identify the object from the outside + if _, err = marshalUtil.ReadUint32(); err != nil { + return + } + if _, err = marshalUtil.ReadUint32(); err != nil { + return + } + + // parse id + id, err := marshalUtil.ReadBytes(32) + if err != nil { + return + } + copy(result.id[:], id) + + // parse sent time + if result.sentTime, err = marshalUtil.ReadInt64(); err != nil { + return + } + + // store bytes, so we don't have to marshal manually + consumedBytes := marshalUtil.ReadOffset() + copy(result.bytes, marshalUtil.Bytes()[:consumedBytes]) + + return +} + +// Bytes returns a marshaled version of this Object. +func (o *Object) Bytes() (bytes []byte) { + // acquire lock for reading bytes + o.bytesMutex.RLock() + + // return if bytes have been determined already + if bytes = o.bytes; bytes != nil { + o.bytesMutex.RUnlock() + return + } + + // switch to write lock + o.bytesMutex.RUnlock() + o.bytesMutex.Lock() + defer o.bytesMutex.Unlock() + + // return if bytes have been determined in the mean time + if bytes = o.bytes; bytes != nil { + return + } + + objectLength := len(o.id) + marshalutil.INT64_SIZE + // initialize helper + marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + objectLength) + + // marshal the payload specific information + marshalUtil.WriteUint32(Type) + marshalUtil.WriteUint32(uint32(objectLength)) + marshalUtil.WriteBytes(o.id[:]) + marshalUtil.WriteInt64(o.sentTime) + + bytes = marshalUtil.Bytes() + + return +} + +// String returns a human-friendly representation of the Object. +func (o *Object) String() string { + return stringify.Struct("NetworkDelayObject", + stringify.StructField("id", o.id), + stringify.StructField("sentTime", uint64(o.sentTime)), + ) +} + +// region Payload implementation /////////////////////////////////////////////////////////////////////////////////////// + +// Type represents the identifier which addresses the network delay Object type. +const Type = payload.Type(189) + +// Type returns the type of the Object. +func (o *Object) Type() payload.Type { + return Type +} + +// Unmarshal unmarshals the payload from the given bytes. +func (o *Object) Unmarshal(data []byte) (err error) { + _, _, err = FromBytes(data, o) + + return +} + +func init() { + payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) { + payload = &Object{} + err = payload.Unmarshal(data) + + return + }) +} + +// // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dapps/networkdelay/webapi.go b/dapps/networkdelay/webapi.go new file mode 100644 index 0000000000000000000000000000000000000000..53f72ea6f2da3336e2bc5f3153ab95fff80fbab0 --- /dev/null +++ b/dapps/networkdelay/webapi.go @@ -0,0 +1,38 @@ +package networkdelay + +import ( + "math/rand" + "net/http" + "time" + + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/labstack/echo" +) + +func configureWebAPI() { + webapi.Server().POST("networkdelay", broadcastNetworkDelayObject) +} + +// broadcastNetworkDelayObject creates a message with a network delay object and +// broadcasts it to the node's neighbors. It returns the message ID if successful. +func broadcastNetworkDelayObject(c echo.Context) error { + // generate random id + rand.Seed(time.Now().UnixNano()) + var id [32]byte + if _, err := rand.Read(id[:]); err != nil { + return c.JSON(http.StatusInternalServerError, Response{Error: err.Error()}) + } + + msg, err := issuer.IssuePayload(NewObject(id, time.Now().UnixNano())) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + return c.JSON(http.StatusOK, Response{ID: msg.Id().String()}) +} + +// Response contains the ID of the message sent. +type Response struct { + ID string `json:"id,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/dapps/valuetransfers/dapp.go b/dapps/valuetransfers/dapp.go new file mode 100644 index 0000000000000000000000000000000000000000..e16014d0ac8a4aebb036418385108c67ea88275d --- /dev/null +++ b/dapps/valuetransfers/dapp.go @@ -0,0 +1,223 @@ +package valuetransfers + +import ( + "os" + "sync" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/consensus" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tipmanager" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + messageTangle "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/database" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + flag "github.com/spf13/pflag" +) + +const ( + // PluginName contains the human readable name of the plugin. + PluginName = "ValueTransfers" + + // DefaultAverageNetworkDelay contains the default average time it takes for a network to propagate through gossip. + DefaultAverageNetworkDelay = 5 * time.Second + + // CfgValueLayerSnapshotFile is the path to the snapshot file. + CfgValueLayerSnapshotFile = "valueLayer.snapshot.file" + + // CfgValueLayerFCOBAverageNetworkDelay is the avg. network delay to use for FCoB rules + CfgValueLayerFCOBAverageNetworkDelay = "valueLayer.fcob.averageNetworkDelay" +) + +func init() { + flag.String(CfgValueLayerSnapshotFile, "./snapshot.bin", "the path to the snapshot file") + flag.Int(CfgValueLayerFCOBAverageNetworkDelay, 5, "the avg. network delay to use for FCoB rules") +} + +var ( + // app is the "plugin" instance of the value-transfers application. + app *node.Plugin + appOnce sync.Once + + // _tangle represents the value tangle that is used to express votes on value transactions. + _tangle *tangle.Tangle + tangleOnce sync.Once + + // fcob contains the fcob consensus logic. + fcob *consensus.FCOB + + // ledgerState represents the ledger state, that keeps track of the liked branches and offers an API to access funds. + ledgerState *tangle.LedgerState + + // log holds a reference to the logger used by this app. + log *logger.Logger + + tipManager *tipmanager.TipManager + tipManagerOnce sync.Once + + valueObjectFactory *tangle.ValueObjectFactory + valueObjectFactoryOnce sync.Once +) + +// App gets the plugin instance. +func App() *node.Plugin { + appOnce.Do(func() { + app = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return app +} + +// Tangle gets the tangle instance. +// tangle represents the value tangle that is used to express votes on value transactions. +func Tangle() *tangle.Tangle { + tangleOnce.Do(func() { + _tangle = tangle.New(database.Store()) + }) + return _tangle +} + +// FCOB gets the fcob instance. +// fcob contains the fcob consensus logic. +func FCOB() *consensus.FCOB { + return fcob +} + +// LedgerState gets the ledgerState instance. +// ledgerState represents the ledger state, that keeps track of the liked branches and offers an API to access funds. +func LedgerState() *tangle.LedgerState { + return ledgerState +} + +func configure(_ *node.Plugin) { + // configure logger + log = logger.NewLogger(PluginName) + + // configure Tangle + _tangle = Tangle() + + // configure LedgerState + ledgerState = tangle.NewLedgerState(Tangle()) + + // read snapshot file + snapshotFilePath := config.Node().GetString(CfgValueLayerSnapshotFile) + if len(snapshotFilePath) != 0 { + snapshot := tangle.Snapshot{} + f, err := os.Open(snapshotFilePath) + if err != nil { + log.Panic("can not open snapshot file:", err) + } + if _, err := snapshot.ReadFrom(f); err != nil { + log.Panic("could not read snapshot file:", err) + } + _tangle.LoadSnapshot(snapshot) + log.Infof("read snapshot from %s", snapshotFilePath) + } + + _tangle.Events.Error.Attach(events.NewClosure(func(err error) { + log.Error(err) + })) + + // initialize tip manager and value object factory + tipManager = TipManager() + valueObjectFactory = ValueObjectFactory() + + _tangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedMetadata *tangle.CachedPayloadMetadata) { + cachedMetadata.Release() + cachedPayload.Consume(tipManager.AddTip) + })) + _tangle.Events.PayloadDisliked.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedMetadata *tangle.CachedPayloadMetadata) { + cachedMetadata.Release() + cachedPayload.Consume(tipManager.RemoveTip) + })) + + // configure FCOB consensus rules + cfgAvgNetworkDelay := config.Node().GetInt(CfgValueLayerFCOBAverageNetworkDelay) + log.Infof("avg. network delay configured to %d seconds", cfgAvgNetworkDelay) + fcob = consensus.NewFCOB(_tangle, time.Duration(cfgAvgNetworkDelay)*time.Second) + fcob.Events.Vote.Attach(events.NewClosure(func(id string, initOpn vote.Opinion) { + if err := voter.Vote(id, initOpn); err != nil { + log.Warnf("FPC vote: %s", err) + } + })) + fcob.Events.Error.Attach(events.NewClosure(func(err error) { + log.Errorf("FCOB error: %s", err) + })) + + // configure FPC + link to consensus + configureFPC() + voter.Events().Finalized.Attach(events.NewClosure(fcob.ProcessVoteResult)) + voter.Events().Finalized.Attach(events.NewClosure(func(ev *vote.OpinionEvent) { + log.Infof("FPC finalized for transaction with id '%s' - final opinion: '%s'", ev.ID, ev.Opinion) + })) + voter.Events().Failed.Attach(events.NewClosure(func(ev *vote.OpinionEvent) { + log.Warnf("FPC failed for transaction with id '%s' - last opinion: '%s'", ev.ID, ev.Opinion) + })) + + // register SignatureFilter in Parser + messagelayer.MessageParser().AddMessageFilter(tangle.NewSignatureFilter()) + + // subscribe to message-layer + messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(onReceiveMessageFromMessageLayer)) +} + +func run(*node.Plugin) { + if err := daemon.BackgroundWorker("ValueTangle", func(shutdownSignal <-chan struct{}) { + <-shutdownSignal + _tangle.Shutdown() + }, shutdown.PriorityTangle); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } + + runFPC() +} + +func onReceiveMessageFromMessageLayer(cachedMessage *message.CachedMessage, cachedMessageMetadata *messageTangle.CachedMessageMetadata) { + defer cachedMessage.Release() + defer cachedMessageMetadata.Release() + + solidMessage := cachedMessage.Unwrap() + if solidMessage == nil { + log.Debug("failed to unpack solid message from message layer") + + return + } + + messagePayload := solidMessage.Payload() + if messagePayload.Type() != valuepayload.Type { + return + } + + valuePayload, ok := messagePayload.(*valuepayload.Payload) + if !ok { + log.Debug("could not cast payload to value payload") + + return + } + + _tangle.AttachPayload(valuePayload) +} + +// TipManager returns the TipManager singleton. +func TipManager() *tipmanager.TipManager { + tipManagerOnce.Do(func() { + tipManager = tipmanager.New() + }) + return tipManager +} + +// ValueObjectFactory returns the ValueObjectFactory singleton. +func ValueObjectFactory() *tangle.ValueObjectFactory { + valueObjectFactoryOnce.Do(func() { + valueObjectFactory = tangle.NewValueObjectFactory(TipManager()) + }) + return valueObjectFactory +} diff --git a/dapps/valuetransfers/fpc.go b/dapps/valuetransfers/fpc.go new file mode 100644 index 0000000000000000000000000000000000000000..cd5a17185c6b7c040c1dc5b0c0bfd66015fee650 --- /dev/null +++ b/dapps/valuetransfers/fpc.go @@ -0,0 +1,224 @@ +package valuetransfers + +import ( + "context" + "fmt" + "net" + "strconv" + "sync" + + "github.com/golang/protobuf/proto" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/packages/prng" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/packages/vote/fpc" + votenet "github.com/iotaledger/goshimmer/packages/vote/net" + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/autopeering/peer" + "github.com/iotaledger/hive.go/autopeering/peer/service" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + flag "github.com/spf13/pflag" + "google.golang.org/grpc" +) + +const ( + // FpcPluginName contains the human readable name of the plugin. + FpcPluginName = "FPC" + + // CfgFPCQuerySampleSize defines how many nodes will be queried each round. + CfgFPCQuerySampleSize = "fpc.querySampleSize" + + // CfgFPCRoundInterval defines how long a round lasts (in seconds) + CfgFPCRoundInterval = "fpc.roundInterval" + + // CfgFPCBindAddress defines on which address the FPC service should listen. + CfgFPCBindAddress = "fpc.bindAddress" +) + +func init() { + flag.Int(CfgFPCQuerySampleSize, 21, "Size of the voting quorum (k)") + flag.Int(CfgFPCRoundInterval, 5, "FPC round interval [s]") + flag.String(CfgFPCBindAddress, "0.0.0.0:10895", "the bind address on which the FPC vote server binds to") +} + +var ( + voter *fpc.FPC + voterOnce sync.Once + voterServer *votenet.VoterServer + roundIntervalSeconds int64 = 5 +) + +// Voter returns the DRNGRoundBasedVoter instance used by the FPC plugin. +func Voter() vote.DRNGRoundBasedVoter { + voterOnce.Do(func() { + // create a function which gets OpinionGivers + opinionGiverFunc := func() (givers []vote.OpinionGiver, err error) { + opinionGivers := make([]vote.OpinionGiver, 0) + for _, p := range autopeering.Discovery().GetVerifiedPeers() { + fpcService := p.Services().Get(service.FPCKey) + if fpcService == nil { + continue + } + // TODO: maybe cache the PeerOpinionGiver instead of creating a new one every time + opinionGivers = append(opinionGivers, &PeerOpinionGiver{p: p}) + } + return opinionGivers, nil + } + voter = fpc.New(opinionGiverFunc) + }) + return voter +} + +func configureFPC() { + log = logger.NewLogger(FpcPluginName) + lPeer := local.GetInstance() + + bindAddr := config.Node().GetString(CfgFPCBindAddress) + _, portStr, err := net.SplitHostPort(bindAddr) + if err != nil { + log.Fatalf("FPC bind address '%s' is invalid: %s", bindAddr, err) + } + port, err := strconv.Atoi(portStr) + if err != nil { + log.Fatalf("FPC bind address '%s' is invalid: %s", bindAddr, err) + } + + if err := lPeer.UpdateService(service.FPCKey, "tcp", port); err != nil { + log.Fatalf("could not update services: %v", err) + } + + Voter().Events().RoundExecuted.Attach(events.NewClosure(func(roundStats *vote.RoundStats) { + peersQueried := len(roundStats.QueriedOpinions) + voteContextsCount := len(roundStats.ActiveVoteContexts) + log.Debugf("executed round with rand %0.4f for %d vote contexts on %d peers, took %v", roundStats.RandUsed, voteContextsCount, peersQueried, roundStats.Duration) + })) +} + +func runFPC() { + const ServerWorkerName = "FPCVoterServer" + if err := daemon.BackgroundWorker(ServerWorkerName, func(shutdownSignal <-chan struct{}) { + stopped := make(chan struct{}) + bindAddr := config.Node().GetString(CfgFPCBindAddress) + voterServer = votenet.New(Voter(), func(id string) vote.Opinion { + branchID, err := branchmanager.BranchIDFromBase58(id) + if err != nil { + log.Errorf("received invalid vote request for branch '%s'", id) + + return vote.Unknown + } + + cachedBranch := _tangle.BranchManager().Branch(branchID) + defer cachedBranch.Release() + + branch := cachedBranch.Unwrap() + if branch == nil { + return vote.Unknown + } + + if !branch.Preferred() { + return vote.Dislike + } + + return vote.Like + }, bindAddr, + metrics.Events().FPCInboundBytes, + metrics.Events().FPCOutboundBytes, + metrics.Events().QueryReceived, + ) + + go func() { + log.Infof("%s started, bind-address=%s", ServerWorkerName, bindAddr) + if err := voterServer.Run(); err != nil { + log.Errorf("Error serving: %s", err) + } + close(stopped) + }() + + // stop if we are shutting down or the server could not be started + select { + case <-shutdownSignal: + case <-stopped: + } + + log.Infof("Stopping %s ...", ServerWorkerName) + voterServer.Shutdown() + log.Infof("Stopping %s ... done", ServerWorkerName) + }, shutdown.PriorityFPC); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } + + if err := daemon.BackgroundWorker("FPCRoundsInitiator", func(shutdownSignal <-chan struct{}) { + log.Infof("Started FPC round initiator") + defer log.Infof("Stopped FPC round initiator") + unixTsPRNG := prng.NewUnixTimestampPRNG(roundIntervalSeconds) + unixTsPRNG.Start() + defer unixTsPRNG.Stop() + exit: + for { + select { + case r := <-unixTsPRNG.C(): + if err := voter.Round(r); err != nil { + log.Warnf("unable to execute FPC round: %s", err) + } + case <-shutdownSignal: + break exit + } + } + }, shutdown.PriorityFPC); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} + +// PeerOpinionGiver implements the OpinionGiver interface based on a peer. +type PeerOpinionGiver struct { + p *peer.Peer +} + +// Query queries another node for its opinion. +func (pog *PeerOpinionGiver) Query(ctx context.Context, ids []string) (vote.Opinions, error) { + fpcServicePort := pog.p.Services().Get(service.FPCKey).Port() + fpcAddr := net.JoinHostPort(pog.p.IP().String(), strconv.Itoa(fpcServicePort)) + + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + + // connect to the FPC service + conn, err := grpc.Dial(fpcAddr, opts...) + if err != nil { + return nil, fmt.Errorf("unable to connect to FPC service: %w", err) + } + defer conn.Close() + + client := votenet.NewVoterQueryClient(conn) + query := &votenet.QueryRequest{Id: ids} + reply, err := client.Opinion(ctx, query) + if err != nil { + metrics.Events().QueryReplyError.Trigger(&metrics.QueryReplyErrorEvent{ + ID: pog.p.ID().String(), + OpinionCount: len(ids), + }) + return nil, fmt.Errorf("unable to query opinions: %w", err) + } + + metrics.Events().FPCInboundBytes.Trigger(uint64(proto.Size(reply))) + metrics.Events().FPCOutboundBytes.Trigger(uint64(proto.Size(query))) + + // convert int32s in reply to opinions + opinions := make(vote.Opinions, len(reply.Opinion)) + for i, intOpn := range reply.Opinion { + opinions[i] = vote.ConvertInt32Opinion(intOpn) + } + + return opinions, nil +} + +// ID returns a string representation of the identifier of the underlying Peer. +func (pog *PeerOpinionGiver) ID() string { + return pog.p.ID().String() +} diff --git a/dapps/valuetransfers/packages/address/address.go b/dapps/valuetransfers/packages/address/address.go new file mode 100644 index 0000000000000000000000000000000000000000..16068a88d3e00c40cfe4eacfba4c98c851c28a36 --- /dev/null +++ b/dapps/valuetransfers/packages/address/address.go @@ -0,0 +1,137 @@ +package address + +import ( + "crypto/rand" + "fmt" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/mr-tron/base58" + "golang.org/x/crypto/blake2b" + + "github.com/iotaledger/hive.go/marshalutil" +) + +// Version represents the version of the address. Different versions are associated to different signature schemes. +type Version = byte + +// Digest represents a hashed version of the consumed public key of the address. Hashing the public key allows us to +// maintain quantum-robustness for addresses, that have never been spent from, and it allows us to have fixed size +// addresses. +type Digest = []byte + +// Address represents an address in the IOTA ledger. +type Address [Length]byte + +const ( + // VersionED25519 represents the address version that uses ED25519 signatures. + VersionED25519 = byte(1) + + // VersionBLS represents the address version that uses BLS signatures. + VersionBLS = byte(2) +) + +// Random creates a random address, which can for example be used in unit tests. +// first byte (version) is also random +func Random() (address Address) { + // generate a random sequence of bytes + if _, err := rand.Read(address[:]); err != nil { + panic(err) + } + return +} + +// RandomOfType creates a random address with the given Version. +func RandomOfType(versionByte Version) Address { + ret := Random() + ret[0] = versionByte + return ret +} + +// FromBase58 creates an address from a base58 encoded string. +func FromBase58(base58String string) (address Address, err error) { + // decode string + bytes, err := base58.Decode(base58String) + if err != nil { + return + } + + // sanitize input + if len(bytes) != Length { + err = fmt.Errorf("base58 encoded string does not match the length of an address") + + return + } + + // copy bytes to result + copy(address[:], bytes) + + return +} + +// FromED25519PubKey creates an address from an ed25519 public key. +func FromED25519PubKey(key ed25519.PublicKey) (address Address) { + digest := blake2b.Sum256(key[:]) + + address[0] = VersionED25519 + copy(address[1:], digest[:]) + + return +} + +// FromBLSPubKey creates an address from marshaled BLS public key +// unmarshaled BLS public key conforms to interface kyber.Point +func FromBLSPubKey(pubKey []byte) (address Address) { + digest := blake2b.Sum256(pubKey) + + address[0] = VersionBLS + copy(address[1:], digest[:]) + + return +} + +// FromBytes unmarshals an address from a sequence of bytes. +func FromBytes(bytes []byte) (result Address, consumedBytes int, err error) { + // parse the bytes + marshalUtil := marshalutil.New(bytes) + addressBytes, err := marshalUtil.ReadBytes(Length) + if err != nil { + return + } + copy(result[:], addressBytes) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Parse is a wrapper for simplified unmarshaling of a byte stream using the marshalUtil package. +func Parse(marshalUtil *marshalutil.MarshalUtil) (Address, error) { + address, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) }) + if err != nil { + return Address{}, err + } + + return address.(Address), nil +} + +// Version returns the version of the address, which corresponds to the signature scheme that is used. +func (address *Address) Version() Version { + return address[0] +} + +// Digest returns the digest part of an address (i.e. the hashed version of the ed25519 public key)- +func (address *Address) Digest() Digest { + return address[1:] +} + +// Bytes returns a marshaled version of this address. +func (address Address) Bytes() []byte { + return address[:] +} + +// String returns a human readable (base58 encoded) version of the address. +func (address Address) String() string { + return base58.Encode(address.Bytes()) +} + +// Length contains the length of an address (digest length = 32 + version byte length = 1). +const Length = 33 diff --git a/dapps/valuetransfers/packages/address/signaturescheme/bls.go b/dapps/valuetransfers/packages/address/signaturescheme/bls.go new file mode 100644 index 0000000000000000000000000000000000000000..7b10349b0419c144fd89151a071864f7f6bb8e0e --- /dev/null +++ b/dapps/valuetransfers/packages/address/signaturescheme/bls.go @@ -0,0 +1,231 @@ +package signaturescheme + +import ( + "fmt" + "math/rand" + + "github.com/mr-tron/base58" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/pairing/bn256" + "go.dedis.ch/kyber/v3/sign" + "go.dedis.ch/kyber/v3/sign/bdn" + "go.dedis.ch/kyber/v3/util/random" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" +) + +// bls.go implements BLS signature scheme which is robust against rogue public key attacks, +// called "Boneh-Drijvers-Neven" or BDN +// It uses go.dedis/kyber library. More info https://github.com/dedis/kyber/blob/master/sign/bdn/bdn.go +// Often BLS signatures are used as threshold signatures. +// This package doesn't implement any threshold signature related primitives. +// it only contains what is needed for the node to check validity of the BLS signatures against addresses, +// signature aggregation function and minimum signing required for testing +var suite = bn256.NewSuite() + +const ( + // BLSSignatureSize represents the length in bytes of a BLS signature. + BLSSignatureSize = 64 + + // BLSPublicKeySize represents the length in bytes of a BLS public key. + BLSPublicKeySize = 128 + + // BLSPrivateKeySize represents the length in bytes of a BLS private key. + BLSPrivateKeySize = 32 + + // BLSFullSignatureSize represents the length in bytes of a full BLS signature. + BLSFullSignatureSize = 1 + BLSPublicKeySize + BLSSignatureSize +) + +// ---------------- implements SignatureScheme interface +// blsSignatureScheme defines an interface for the key pairs of BLS signatures. +type blsSignatureScheme struct { + priKey kyber.Scalar + pubKey kyber.Point +} + +// deterministic sequence +var rnd = random.New(rand.New(rand.NewSource(42))) + +// RandBLS creates a RANDOM instance of a signature scheme, that is used to sign the corresponding address. +// only for testing: each time same sequence! +func RandBLS() SignatureScheme { + ret := &blsSignatureScheme{} + ret.priKey, ret.pubKey = bdn.NewKeyPair(suite, rnd) + return ret +} + +// BLS creates an instance of BLS signature scheme +// from given private and public keys in marshaled binary form +func BLS(priKey, pubKey []byte) (SignatureScheme, error) { + if len(priKey) != BLSPrivateKeySize || len(pubKey) != BLSPublicKeySize { + return nil, fmt.Errorf("wrong key size") + } + ret := &blsSignatureScheme{ + priKey: suite.G2().Scalar(), + pubKey: suite.G2().Point(), + } + if err := ret.pubKey.UnmarshalBinary(pubKey); err != nil { + return nil, err + } + if err := ret.priKey.UnmarshalBinary(priKey); err != nil { + return nil, err + } + return ret, nil +} + +func (sigscheme *blsSignatureScheme) Version() byte { + return address.VersionBLS +} + +func (sigscheme *blsSignatureScheme) Address() address.Address { + b, err := sigscheme.pubKey.MarshalBinary() + if err != nil { + panic(err) + } + return address.FromBLSPubKey(b) +} + +func (sigscheme *blsSignatureScheme) Sign(data []byte) Signature { + sig, err := bdn.Sign(suite, sigscheme.priKey, data) + if err != nil { + panic(err) + } + pubKeyBin, err := sigscheme.pubKey.MarshalBinary() + if err != nil { + panic(err) + } + return NewBLSSignature(pubKeyBin, sig) +} + +func (sigscheme *blsSignatureScheme) String() string { + pri, err := sigscheme.priKey.MarshalBinary() + if err != nil { + return fmt.Sprintf("BLS sigsheme: %v", err) + } + pub, err := sigscheme.pubKey.MarshalBinary() + if err != nil { + return fmt.Sprintf("BLS sigsheme: %v", err) + } + return base58.Encode(pri) + ", " + base58.Encode(pub) +} + +// interface contract (allow the compiler to check if the implementation has all of the required methods). +var _ SignatureScheme = &blsSignatureScheme{} + +// ---------------- implements Signature interface + +// BLSSignature represents a signature created with the BLS signature scheme. +type BLSSignature [BLSFullSignatureSize]byte + +// BLSSignatureFromBytes unmarshals a BLS signature from a sequence of bytes. +func BLSSignatureFromBytes(data []byte) (result *BLSSignature, consumedBytes int, err error) { + consumedBytes = 0 + err = nil + if len(data) < BLSFullSignatureSize { + err = fmt.Errorf("marshaled BLS signature size must be %d", BLSFullSignatureSize) + return + } + if data[0] != address.VersionBLS { + err = fmt.Errorf("wrong version byte, expected %d", address.VersionBLS) + return + } + result = &BLSSignature{} + copy(result[:BLSFullSignatureSize], data) + consumedBytes = BLSFullSignatureSize + return +} + +// NewBLSSignature creates BLS signature from raw public key and signature data +func NewBLSSignature(pubKey, signature []byte) *BLSSignature { + var ret BLSSignature + ret[0] = address.VersionBLS + copy(ret.pubKey(), pubKey) + copy(ret.signature(), signature) + return &ret +} + +func (sig *BLSSignature) pubKey() []byte { + return sig[1 : BLSPublicKeySize+1] +} + +func (sig *BLSSignature) signature() []byte { + return sig[1+BLSPublicKeySize:] +} + +// IsValid returns true if the signature correctly signs the given data. +func (sig *BLSSignature) IsValid(signedData []byte) bool { + if sig[0] != address.VersionBLS { + return false + } + // unmarshal public key + pubKey := suite.G2().Point() + if err := pubKey.UnmarshalBinary(sig.pubKey()); err != nil { + return false + } + return bdn.Verify(suite, pubKey, signedData, sig.signature()) == nil +} + +// Bytes marshals the signature into a sequence of bytes. +func (sig *BLSSignature) Bytes() []byte { + return sig[:] +} + +// Address returns the address that this signature signs. +func (sig *BLSSignature) Address() address.Address { + return address.FromBLSPubKey(sig.pubKey()) +} + +func (sig *BLSSignature) String() string { + return base58.Encode(sig[:]) +} + +// AggregateBLSSignatures combined multiple Signatures into a single one. +func AggregateBLSSignatures(sigs ...Signature) (Signature, error) { + if len(sigs) == 0 { + return nil, fmt.Errorf("must be at least one signature to aggregate") + } + if len(sigs) == 1 { + return sigs[0], nil + } + + pubKeys := make([]kyber.Point, len(sigs)) + signatures := make([][]byte, len(sigs)) + + var err error + for i, sig := range sigs { + sigBls, ok := sig.(*BLSSignature) + if !ok { + return nil, fmt.Errorf("not a BLS signature") + } + pubKeys[i] = suite.G2().Point() + if err = pubKeys[i].UnmarshalBinary(sigBls.pubKey()); err != nil { + return nil, err + } + signatures[i] = sigBls.signature() + } + mask, _ := sign.NewMask(suite, pubKeys, nil) + for i := range pubKeys { + _ = mask.SetBit(i, true) + } + aggregatedSignature, err := bdn.AggregateSignatures(suite, signatures, mask) + if err != nil { + return nil, err + } + sigBin, err := aggregatedSignature.MarshalBinary() + if err != nil { + return nil, err + } + aggregatedPubKey, err := bdn.AggregatePublicKeys(suite, mask) + if err != nil { + return nil, err + } + pubKeyBin, err := aggregatedPubKey.MarshalBinary() + if err != nil { + return nil, err + } + return NewBLSSignature(pubKeyBin, sigBin), nil +} + +// interface contract (allow the compiler to check if the implementation has all of the required methods). +var _ Signature = &BLSSignature{} diff --git a/dapps/valuetransfers/packages/address/signaturescheme/bls_test.go b/dapps/valuetransfers/packages/address/signaturescheme/bls_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a07c9e18336eb72e8e429d835f5c9c7b6367769f --- /dev/null +++ b/dapps/valuetransfers/packages/address/signaturescheme/bls_test.go @@ -0,0 +1,62 @@ +package signaturescheme + +import ( + "testing" + + "github.com/magiconair/properties/assert" + "github.com/mr-tron/base58" +) + +var dataToSign = []byte("Hello Boneh-Lynn-Shacham (BLS) --> Boneh-Drijvers-Neven (BDN)") + +func TestBLS_rndSigScheme(t *testing.T) { + sigScheme := RandBLS() + t.Logf("generating random BLS signature scheme: %s\n", sigScheme.(*blsSignatureScheme).String()) + signature := sigScheme.Sign(dataToSign) + + assert.Equal(t, sigScheme.Address(), signature.Address()) + res := signature.IsValid(dataToSign) + assert.Equal(t, res, true) +} + +const ( + priKeyTest = "Cjsu52qf28G4oLiUDcimEY7SPbWJQA9zoKCNi4ywMxg" + pubKeyTest = "28LgNCDp52gTotmd21hcEXKar5tTyxuJKqQdGHCJnZ5Z1M7Rdh4Qo2BYC3s3NicLD99tZ3yX9mZvRmsnQLMRcHnzqgq2CQp7CYWCKfTUT9yzJKUTQ4JmN2DhSkSNc5kau4KE8PRGByQxpiYQq4DRF4Qb3Dn4cHmhTrDi9xQiYTxoAYW" +) + +func TestBLS_sigScheme(t *testing.T) { + priKeyBin, err := base58.Decode(priKeyTest) + assert.Equal(t, err, nil) + + pubKeyBin, err := base58.Decode(pubKeyTest) + assert.Equal(t, err, nil) + + sigScheme, err := BLS(priKeyBin, pubKeyBin) + assert.Equal(t, err, nil) + + signature := sigScheme.Sign(dataToSign) + assert.Equal(t, sigScheme.Address(), signature.Address()) + assert.Equal(t, signature.IsValid(dataToSign), true) +} + +// number of signatures to aggregate +const numSigs = 100 + +func TestBLS_aggregation(t *testing.T) { + sigs := make([]Signature, numSigs) + sigSchemes := make([]SignatureScheme, numSigs) + + for i := range sigs { + sigSchemes[i] = RandBLS() + sigs[i] = sigSchemes[i].Sign(dataToSign) + } + // aggregate 2 signatures + a01, err := AggregateBLSSignatures(sigs[0], sigs[1]) + assert.Equal(t, err, nil) + assert.Equal(t, a01.IsValid(dataToSign), true) + + // aggregate N signatures + aN, err := AggregateBLSSignatures(sigs...) + assert.Equal(t, err, nil) + assert.Equal(t, aN.IsValid(dataToSign), true) +} diff --git a/dapps/valuetransfers/packages/address/signaturescheme/ed25519.go b/dapps/valuetransfers/packages/address/signaturescheme/ed25519.go new file mode 100644 index 0000000000000000000000000000000000000000..846d92de594628c9cea3c00d2057abb456cc6495 --- /dev/null +++ b/dapps/valuetransfers/packages/address/signaturescheme/ed25519.go @@ -0,0 +1,127 @@ +package signaturescheme + +import ( + "fmt" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/marshalutil" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" +) + +// region PUBLIC API /////////////////////////////////////////////////////////////////////////////////////////////////// + +// ED25519 creates an instance of a signature scheme, that is used to sign the corresponding address. +func ED25519(keyPair ed25519.KeyPair) SignatureScheme { + return &ed25519SignatureScheme{ + keyPair: keyPair, + } +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// region signature scheme implementation ////////////////////////////////////////////////////////////////////////////// + +// ed25519SignatureScheme defines an interface for ED25519 elliptic curve signatures. +type ed25519SignatureScheme struct { + keyPair ed25519.KeyPair +} + +// Version returns the version byte that is associated to this signature scheme. +func (signatureScheme *ed25519SignatureScheme) Version() byte { + return address.VersionED25519 +} + +// Address returns the address that this signature scheme instance is securing. +func (signatureScheme *ed25519SignatureScheme) Address() address.Address { + return address.FromED25519PubKey(signatureScheme.keyPair.PublicKey) +} + +// Sign creates a valid signature for the given data according to the signature scheme implementation. +func (signatureScheme *ed25519SignatureScheme) Sign(data []byte) Signature { + return &ED25519Signature{ + publicKey: signatureScheme.keyPair.PublicKey, + signature: signatureScheme.keyPair.PrivateKey.Sign(data), + } +} + +// interface contract (allow the compiler to check if the implementation has all of the required methods). +var _ SignatureScheme = &ed25519SignatureScheme{} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// region signature implementation ///////////////////////////////////////////////////////////////////////////////////// + +// ED25519Signature represents a signature for an addresses that uses elliptic curve cryptography. +type ED25519Signature struct { + publicKey ed25519.PublicKey + signature ed25519.Signature +} + +// Ed25519SignatureFromBytes unmarshals an ed25519 signatures from a sequence of bytes. +// It either creates a new signature or fills the optionally provided object with the parsed information. +func Ed25519SignatureFromBytes(bytes []byte, optionalTargetObject ...*ED25519Signature) (result *ED25519Signature, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &ED25519Signature{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to ed25519SignatureFromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read version + versionByte, err := marshalUtil.ReadByte() + if err != nil { + return + } else if versionByte != address.VersionED25519 { + err = fmt.Errorf("invalid version byte when parsing ed25519 signature") + + return + } + + // read public key + publicKey, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return ed25519.PublicKeyFromBytes(data) }) + if err != nil { + return + } + result.publicKey = publicKey.(ed25519.PublicKey) + + // read signature + signature, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return ed25519.SignatureFromBytes(data) }) + if err != nil { + return + } + result.signature = signature.(ed25519.Signature) + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// IsValid returns true if the signature is valid for the given data. +func (signature *ED25519Signature) IsValid(signedData []byte) bool { + return signature.publicKey.VerifySignature(signedData, signature.signature) +} + +// Bytes returns a marshaled version of the signature. +func (signature *ED25519Signature) Bytes() []byte { + marshalUtil := marshalutil.New(1 + ed25519.PublicKeySize + ed25519.SignatureSize) + marshalUtil.WriteByte(address.VersionED25519) + marshalUtil.WriteBytes(signature.publicKey[:]) + marshalUtil.WriteBytes(signature.signature[:]) + + return marshalUtil.Bytes() +} + +// Address returns the address, that this signature signs. +func (signature *ED25519Signature) Address() address.Address { + return address.FromED25519PubKey(signature.publicKey) +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dapps/valuetransfers/packages/address/signaturescheme/signature.go b/dapps/valuetransfers/packages/address/signaturescheme/signature.go new file mode 100644 index 0000000000000000000000000000000000000000..eb7d6e47dff9cc57f78b307189d5f690814726e1 --- /dev/null +++ b/dapps/valuetransfers/packages/address/signaturescheme/signature.go @@ -0,0 +1,15 @@ +package signaturescheme + +import "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + +// Signature defines an interface for an address signature generated by the corresponding signature scheme. +type Signature interface { + // IsValid returns true if the signature is valid for the given data. + IsValid(signedData []byte) bool + + // Bytes returns a marshaled version of the signature. + Bytes() []byte + + // Address returns the address that this signature signs. + Address() address.Address +} diff --git a/dapps/valuetransfers/packages/address/signaturescheme/signaturescheme.go b/dapps/valuetransfers/packages/address/signaturescheme/signaturescheme.go new file mode 100644 index 0000000000000000000000000000000000000000..046a44f766aa9b5e8a72e6d3e883642192f83866 --- /dev/null +++ b/dapps/valuetransfers/packages/address/signaturescheme/signaturescheme.go @@ -0,0 +1,17 @@ +package signaturescheme + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" +) + +// SignatureScheme defines an interface for different signature generation methods (i.e. ED25519, WOTS, and so on ...). +type SignatureScheme interface { + // Version returns the version byte that is associated to this signature scheme. + Version() byte + + // Address returns the address that this signature scheme instance is securing. + Address() address.Address + + // Sign creates a valid signature for the given data according to the signature scheme implementation. + Sign(data []byte) Signature +} diff --git a/dapps/valuetransfers/packages/balance/balance.go b/dapps/valuetransfers/packages/balance/balance.go new file mode 100644 index 0000000000000000000000000000000000000000..6559145b2b172898e42831a9b31e9bda99520804 --- /dev/null +++ b/dapps/valuetransfers/packages/balance/balance.go @@ -0,0 +1,77 @@ +package balance + +import ( + "strconv" + + "github.com/iotaledger/hive.go/marshalutil" +) + +// Balance represents a balance in the IOTA ledger. It consists out of a numeric value and a color. +type Balance struct { + // The numeric value of the balance. + Value int64 `json:"value"` + // The color of the balance. + Color Color `json:"color"` +} + +// New creates a new Balance with the given details. +func New(color Color, balance int64) (result *Balance) { + result = &Balance{ + Color: color, + Value: balance, + } + + return +} + +// FromBytes unmarshals a Balance from a sequence of bytes. +func FromBytes(bytes []byte) (result *Balance, consumedBytes int, err error) { + result = &Balance{} + + marshalUtil := marshalutil.New(bytes) + + result.Value, err = marshalUtil.ReadInt64() + if err != nil { + return + } + + coinColor, colorErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return ColorFromBytes(data) + }) + if colorErr != nil { + return nil, marshalUtil.ReadOffset(), colorErr + } + + result.Color = coinColor.(Color) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Parse is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. +func Parse(marshalUtil *marshalutil.MarshalUtil) (*Balance, error) { + address, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) }) + if err != nil { + return nil, err + } + + return address.(*Balance), nil +} + +// Bytes marshals the Balance into a sequence of bytes. +func (balance *Balance) Bytes() []byte { + marshalUtil := marshalutil.New(Length) + + marshalUtil.WriteInt64(balance.Value) + marshalUtil.WriteBytes(balance.Color.Bytes()) + + return marshalUtil.Bytes() +} + +// String creates a human readable string of the Balance. +func (balance *Balance) String() string { + return strconv.FormatInt(balance.Value, 10) + " " + balance.Color.String() +} + +// Length encodes the length of a marshaled Balance (the length of the color + 8 bytes for the balance). +const Length = 8 + ColorLength diff --git a/dapps/valuetransfers/packages/balance/balance_test.go b/dapps/valuetransfers/packages/balance/balance_test.go new file mode 100644 index 0000000000000000000000000000000000000000..35401c66a5eb5bed4ace5281f4ff1de1e289feb7 --- /dev/null +++ b/dapps/valuetransfers/packages/balance/balance_test.go @@ -0,0 +1,24 @@ +package balance + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMarshalUnmarshal(t *testing.T) { + balance := New(ColorIOTA, 1337) + assert.Equal(t, int64(1337), balance.Value) + assert.Equal(t, ColorIOTA, balance.Color) + + marshaledBalance := balance.Bytes() + assert.Equal(t, Length, len(marshaledBalance)) + + restoredBalance, consumedBytes, err := FromBytes(marshaledBalance) + if err != nil { + panic(err) + } + assert.Equal(t, Length, consumedBytes) + assert.Equal(t, balance.Value, restoredBalance.Value) + assert.Equal(t, balance.Color, restoredBalance.Color) +} diff --git a/dapps/valuetransfers/packages/balance/color.go b/dapps/valuetransfers/packages/balance/color.go new file mode 100644 index 0000000000000000000000000000000000000000..4fba5d26bb8f402fabb54a25ba08a3cae33070ad --- /dev/null +++ b/dapps/valuetransfers/packages/balance/color.go @@ -0,0 +1,47 @@ +package balance + +import ( + "github.com/iotaledger/hive.go/marshalutil" + "github.com/mr-tron/base58" +) + +// Color represents a marker that is associated to a token balance and that gives it a certain "meaning". The zero value +// represents "vanilla" IOTA tokens but it is also possible to define tokens that represent i.e. real world assets. +type Color [ColorLength]byte + +// ColorFromBytes unmarshals a Color from a sequence of bytes. +func ColorFromBytes(bytes []byte) (result Color, consumedBytes int, err error) { + colorBytes, err := marshalutil.New(bytes).ReadBytes(ColorLength) + if err != nil { + return + } + copy(result[:], colorBytes) + + consumedBytes = ColorLength + + return +} + +// Bytes marshals the Color into a sequence of bytes. +func (color Color) Bytes() []byte { + return color[:] +} + +// String creates a human readable string of the Color. +func (color Color) String() string { + if color == ColorIOTA { + return "IOTA" + } + + return base58.Encode(color[:]) +} + +// ColorLength represents the length of a Color (amount of bytes). +const ColorLength = 32 + +// ColorIOTA is the zero value of the Color and represents vanilla IOTA tokens. +var ColorIOTA Color = [32]byte{} + +// ColorNew represents a placeholder Color that will be replaced with the transaction ID that created the funds. It is +// used to indicate that tokens should be "colored" in their Output (minting new colored coins). +var ColorNew = [32]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} diff --git a/dapps/valuetransfers/packages/branchmanager/branch.go b/dapps/valuetransfers/packages/branchmanager/branch.go new file mode 100644 index 0000000000000000000000000000000000000000..7ccf9b0cc161bb01d44dabd323af3d212a8530de --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/branch.go @@ -0,0 +1,500 @@ +package branchmanager + +import ( + "fmt" + "sync" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" + "github.com/iotaledger/hive.go/types" +) + +// Branch represents a part of the tangle, that shares the same perception of the ledger state. Every conflicting +// transaction forms a Branch, that contains all transactions that are spending Outputs of the conflicting transactions. +// Branches can also be created by merging two other Branches, which creates an aggregated Branch. +type Branch struct { + objectstorage.StorableObjectFlags + + id BranchID + parentBranches []BranchID + conflicts map[ConflictID]types.Empty + preferred bool + liked bool + finalized bool + confirmed bool + rejected bool + + parentBranchesMutex sync.RWMutex + conflictsMutex sync.RWMutex + preferredMutex sync.RWMutex + likedMutex sync.RWMutex + finalizedMutex sync.RWMutex + confirmedMutex sync.RWMutex + rejectedMutex sync.RWMutex +} + +// NewBranch is the constructor of a Branch and creates a new Branch object from the given details. +func NewBranch(id BranchID, parentBranches []BranchID) *Branch { + return &Branch{ + id: id, + parentBranches: parentBranches, + conflicts: make(map[ConflictID]types.Empty), + } +} + +// BranchFromStorageKey is a factory method that creates a new Branch instance from a storage key of the objectstorage. +// It is used by the objectstorage, to create new instances of this entity. +func BranchFromStorageKey(key []byte, optionalTargetObject ...*Branch) (result *Branch, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Branch{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to BranchFromStorageKey") + } + + // parse information + marshalUtil := marshalutil.New(key) + result.id, err = ParseBranchID(marshalUtil) + if err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// BranchFromBytes unmarshals a Branch from a sequence of bytes. +func BranchFromBytes(bytes []byte, optionalTargetObject ...*Branch) (result *Branch, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseBranch(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseBranch unmarshals a Branch using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseBranch(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Branch) (result *Branch, err error) { + parsedObject, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return BranchFromStorageKey(data, optionalTargetObject...) + }) + if err != nil { + return + } + + result = parsedObject.(*Branch) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ID returns the identifier of the Branch (usually the transaction.ID that created the branch - unless its an +// aggregated Branch). +func (branch *Branch) ID() BranchID { + return branch.id +} + +// ParentBranches returns the identifiers of the parents of this Branch. +func (branch *Branch) ParentBranches() (parentBranches []BranchID) { + branch.parentBranchesMutex.RLock() + defer branch.parentBranchesMutex.RUnlock() + + parentBranches = make([]BranchID, len(branch.parentBranches)) + copy(parentBranches, branch.parentBranches) + + return +} + +// updateParentBranch updates the parent of a non-aggregated Branch. Aggregated branches can not simply be "moved +// around" by changing their parent and need to be re-aggregated (because their ID depends on their parents). +func (branch *Branch) updateParentBranch(newParentBranchID BranchID) (modified bool, err error) { + branch.parentBranchesMutex.RLock() + if len(branch.parentBranches) != 1 { + err = fmt.Errorf("tried to update parent of aggregated Branch '%s'", branch.ID()) + + branch.parentBranchesMutex.RUnlock() + + return + } + + if branch.parentBranches[0] == newParentBranchID { + branch.parentBranchesMutex.RUnlock() + + return + } + + branch.parentBranchesMutex.RUnlock() + branch.parentBranchesMutex.Lock() + defer branch.parentBranchesMutex.Unlock() + + if branch.parentBranches[0] == newParentBranchID { + return + } + + branch.parentBranches[0] = newParentBranchID + branch.SetModified() + modified = true + + return +} + +// IsAggregated returns true if the branch is not a conflict-branch, but was created by merging multiple other branches. +func (branch *Branch) IsAggregated() bool { + return len(branch.parentBranches) > 1 +} + +// Conflicts retrieves the Conflicts that a Branch is part of. +func (branch *Branch) Conflicts() (conflicts map[ConflictID]types.Empty) { + branch.conflictsMutex.RLock() + defer branch.conflictsMutex.RUnlock() + + conflicts = make(map[ConflictID]types.Empty, len(branch.conflicts)) + for conflict := range branch.conflicts { + conflicts[conflict] = types.Void + } + + return +} + +// addConflict registers the membership of this Branch in a given conflict. +func (branch *Branch) addConflict(conflict ConflictID) (added bool) { + branch.conflictsMutex.RLock() + if _, exists := branch.conflicts[conflict]; exists { + branch.conflictsMutex.RUnlock() + + return + } + + branch.conflictsMutex.RUnlock() + branch.conflictsMutex.Lock() + defer branch.conflictsMutex.Unlock() + + if _, exists := branch.conflicts[conflict]; exists { + return + } + + branch.conflicts[conflict] = types.Void + branch.SetModified() + added = true + + return +} + +// Preferred returns true, if the branch is the favored one among the branches in the same conflict sets. +func (branch *Branch) Preferred() bool { + branch.preferredMutex.RLock() + defer branch.preferredMutex.RUnlock() + + return branch.preferred +} + +// setPreferred is the setter for the preferred flag. It returns true if the value of the flag has been updated. +// A branch is preferred if it represents the "liked" part of the tangle in it corresponding Branch. +func (branch *Branch) setPreferred(preferred bool) (modified bool) { + branch.preferredMutex.RLock() + if branch.preferred == preferred { + branch.preferredMutex.RUnlock() + + return + } + + branch.preferredMutex.RUnlock() + branch.preferredMutex.Lock() + defer branch.preferredMutex.Unlock() + + if branch.preferred == preferred { + return + } + + branch.preferred = preferred + branch.SetModified() + modified = true + return +} + +// Liked returns if the branch is liked (it is preferred and all of its parents are liked). +func (branch *Branch) Liked() bool { + branch.likedMutex.RLock() + defer branch.likedMutex.RUnlock() + + return branch.liked +} + +// setLiked modifies the liked flag of this branch. It returns true, if the current value has been modified. +func (branch *Branch) setLiked(liked bool) (modified bool) { + branch.likedMutex.RLock() + if branch.liked == liked { + branch.likedMutex.RUnlock() + + return + } + + branch.likedMutex.RUnlock() + branch.likedMutex.Lock() + defer branch.likedMutex.Unlock() + + if branch.liked == liked { + return + } + + branch.liked = liked + branch.SetModified() + modified = true + return +} + +// Finalized returns true if the branch has been marked as finalized. +func (branch *Branch) Finalized() bool { + branch.finalizedMutex.RLock() + defer branch.finalizedMutex.RUnlock() + + return branch.finalized +} + +// setFinalized is the setter for the finalized flag. It returns true if the value of the flag has been updated. +// A branch is finalized if a decisions regarding its preference has been made. +// Note: Just because a branch has been finalized, does not mean that all transactions it contains have also been +// finalized but only that the underlying conflict that created the Branch has been finalized. +func (branch *Branch) setFinalized(finalized bool) (modified bool) { + branch.finalizedMutex.RLock() + if branch.finalized == finalized { + branch.finalizedMutex.RUnlock() + + return + } + + branch.finalizedMutex.RUnlock() + branch.finalizedMutex.Lock() + defer branch.finalizedMutex.Unlock() + + if branch.finalized == finalized { + return + } + + branch.finalized = finalized + branch.SetModified() + modified = true + + return +} + +// Confirmed returns true if the branch has been accepted to be part of the ledger state. +func (branch *Branch) Confirmed() bool { + branch.confirmedMutex.RLock() + defer branch.confirmedMutex.RUnlock() + + return branch.confirmed +} + +// setConfirmed is the setter for the confirmed flag. It returns true if the value of the flag has been updated. +// A branch is confirmed if it is considered to have been accepted to be part of the ledger state. +// Note: Just because a branch has been confirmed, does not mean that all transactions it contains have also been +// confirmed but only that the underlying conflict that created the Branch has been decided. +func (branch *Branch) setConfirmed(confirmed bool) (modified bool) { + branch.confirmedMutex.RLock() + if branch.confirmed == confirmed { + branch.confirmedMutex.RUnlock() + + return + } + + branch.confirmedMutex.RUnlock() + branch.confirmedMutex.Lock() + defer branch.confirmedMutex.Unlock() + + if branch.confirmed == confirmed { + return + } + + branch.confirmed = confirmed + branch.SetModified() + modified = true + + return +} + +// Rejected returns true if the branch has been rejected to be part of the ledger state. +func (branch *Branch) Rejected() bool { + branch.rejectedMutex.RLock() + defer branch.rejectedMutex.RUnlock() + + return branch.rejected +} + +// setRejected is the setter for the rejected flag. It returns true if the value of the flag has been updated. +// A branch is rejected if it is considered to have been rejected to be part of the ledger state. +func (branch *Branch) setRejected(rejected bool) (modified bool) { + branch.rejectedMutex.RLock() + if branch.rejected == rejected { + branch.rejectedMutex.RUnlock() + + return + } + + branch.rejectedMutex.RUnlock() + branch.rejectedMutex.Lock() + defer branch.rejectedMutex.Unlock() + + if branch.rejected == rejected { + return + } + + branch.rejected = rejected + branch.SetModified() + modified = true + + return +} + +// Bytes returns a marshaled version of this Branch. +func (branch *Branch) Bytes() []byte { + return marshalutil.New(). + WriteBytes(branch.ObjectStorageKey()). + WriteBytes(branch.ObjectStorageValue()). + Bytes() +} + +// String returns a human readable version of this Branch (for debug purposes). +func (branch *Branch) String() string { + return stringify.Struct("Branch", + stringify.StructField("id", branch.ID()), + ) +} + +// Update is disabled but needs to be implemented to be compatible with the objectstorage. +func (branch *Branch) Update(other objectstorage.StorableObject) { + panic("updates are disabled - please use the setters") +} + +// ObjectStorageKey returns the bytes that are used as a key when storing the Branch in an objectstorage. +func (branch *Branch) ObjectStorageKey() []byte { + return branch.id.Bytes() +} + +// ObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a marshaled +// Branch. +func (branch *Branch) ObjectStorageValue() []byte { + branch.preferredMutex.RLock() + branch.likedMutex.RLock() + defer branch.preferredMutex.RUnlock() + defer branch.likedMutex.RUnlock() + + parentBranches := branch.ParentBranches() + parentBranchCount := len(parentBranches) + + marshalUtil := marshalutil.New(5*marshalutil.BOOL_SIZE + marshalutil.UINT32_SIZE + parentBranchCount*BranchIDLength) + marshalUtil.WriteBool(branch.Preferred()) + marshalUtil.WriteBool(branch.Liked()) + marshalUtil.WriteBool(branch.Finalized()) + marshalUtil.WriteBool(branch.Confirmed()) + marshalUtil.WriteBool(branch.Rejected()) + marshalUtil.WriteUint32(uint32(parentBranchCount)) + for _, branchID := range parentBranches { + marshalUtil.WriteBytes(branchID.Bytes()) + } + + return marshalUtil.Bytes() +} + +// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. +func (branch *Branch) UnmarshalObjectStorageValue(valueBytes []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(valueBytes) + branch.preferred, err = marshalUtil.ReadBool() + if err != nil { + return + } + branch.liked, err = marshalUtil.ReadBool() + if err != nil { + return + } + branch.finalized, err = marshalUtil.ReadBool() + if err != nil { + return + } + branch.confirmed, err = marshalUtil.ReadBool() + if err != nil { + return + } + branch.rejected, err = marshalUtil.ReadBool() + if err != nil { + return + } + parentBranchCount, err := marshalUtil.ReadUint32() + if err != nil { + return + } + branch.parentBranches = make([]BranchID, parentBranchCount) + for i := uint32(0); i < parentBranchCount; i++ { + branch.parentBranches[i], err = ParseBranchID(marshalUtil) + if err != nil { + return + } + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// CachedBranch is a wrapper for the generic CachedObject returned by the objectstorage, that overrides the accessor +// methods, with a type-casted one. +type CachedBranch struct { + objectstorage.CachedObject +} + +// Retain marks this CachedObject to still be in use by the program. +func (cachedBranch *CachedBranch) Retain() *CachedBranch { + return &CachedBranch{cachedBranch.CachedObject.Retain()} +} + +// Unwrap is the type-casted equivalent of Get. It returns nil if the object does not exist. +func (cachedBranch *CachedBranch) Unwrap() *Branch { + untypedObject := cachedBranch.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*Branch) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject +} + +// Consume unwraps the CachedObject and passes a type-casted version to the consumer (if the object is not empty - it +// exists). It automatically releases the object when the consumer finishes. +func (cachedBranch *CachedBranch) Consume(consumer func(branch *Branch), forceRelease ...bool) (consumed bool) { + return cachedBranch.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Branch)) + }, forceRelease...) +} + +// CachedBranches represents a collection of CachedBranches. +type CachedBranches map[BranchID]*CachedBranch + +// Consume iterates over the CachedObjects, unwraps them and passes a type-casted version to the consumer (if the object +// is not empty - it exists). It automatically releases the object when the consumer finishes. It returns true, if at +// least one object was consumed. +func (cachedBranches CachedBranches) Consume(consumer func(branch *Branch)) (consumed bool) { + for _, cachedBranch := range cachedBranches { + consumed = cachedBranch.Consume(func(output *Branch) { + consumer(output) + }) || consumed + } + + return +} + +// Release is a utility function that allows us to release all CachedObjects in the collection. +func (cachedBranches CachedBranches) Release(force ...bool) { + for _, cachedBranch := range cachedBranches { + cachedBranch.Release(force...) + } +} diff --git a/dapps/valuetransfers/packages/branchmanager/branchid.go b/dapps/valuetransfers/packages/branchmanager/branchid.go new file mode 100644 index 0000000000000000000000000000000000000000..70e8aa532e4155c1b8f80108c58b0ad6906717e3 --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/branchid.go @@ -0,0 +1,107 @@ +package branchmanager + +import ( + "fmt" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/types" + "github.com/mr-tron/base58" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" +) + +// BranchID represents an identifier of a Branch. +type BranchID [BranchIDLength]byte + +var ( + // UndefinedBranchID is the zero value of a BranchID and represents a branch that has not been set. + UndefinedBranchID = BranchID{} + + // MasterBranchID is the identifier of the MasterBranch (root of the Branch DAG). + MasterBranchID = BranchID{1} +) + +// NewBranchID creates a new BranchID from a transaction ID. +func NewBranchID(transactionID transaction.ID) (branchID BranchID) { + copy(branchID[:], transactionID.Bytes()) + + return +} + +// BranchIDFromBytes unmarshals a BranchID from a sequence of bytes. +func BranchIDFromBytes(bytes []byte) (result BranchID, consumedBytes int, err error) { + // parse the bytes + marshalUtil := marshalutil.New(bytes) + branchIDBytes, idErr := marshalUtil.ReadBytes(BranchIDLength) + if idErr != nil { + err = idErr + + return + } + copy(result[:], branchIDBytes) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// BranchIDFromBase58 creates a new BranchID from a base58 encoded string. +func BranchIDFromBase58(base58String string) (branchID BranchID, err error) { + // decode string + bytes, err := base58.Decode(base58String) + if err != nil { + return + } + + // sanitize input + if len(bytes) != BranchIDLength { + err = fmt.Errorf("base58 encoded string does not match the length of a BranchID") + + return + } + + // copy bytes to result + copy(branchID[:], bytes) + + return +} + +// ParseBranchID unmarshals a BranchID using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseBranchID(marshalUtil *marshalutil.MarshalUtil) (result BranchID, err error) { + var branchIDBytes []byte + if branchIDBytes, err = marshalUtil.ReadBytes(BranchIDLength); err != nil { + return + } + + copy(result[:], branchIDBytes) + + return +} + +// Bytes marshals the BranchID into a sequence of bytes. +func (branchId BranchID) Bytes() []byte { + return branchId[:] +} + +// String creates a base58 encoded version of the BranchID. +func (branchId BranchID) String() string { + return base58.Encode(branchId[:]) +} + +// BranchIDLength encodes the length of a branch identifier - since branches get created by transactions, it has the +// same length as a transaction ID. +const BranchIDLength = transaction.IDLength + +// BranchIds represents a collection of BranchIds. +type BranchIds map[BranchID]types.Empty + +// ToList create a slice of BranchIDs from the collection. +func (branchIDs BranchIds) ToList() (result []BranchID) { + result = make([]BranchID, len(branchIDs)) + i := 0 + for branchID := range branchIDs { + result[i] = branchID + i++ + } + + return +} diff --git a/dapps/valuetransfers/packages/branchmanager/branchmanager.go b/dapps/valuetransfers/packages/branchmanager/branchmanager.go new file mode 100644 index 0000000000000000000000000000000000000000..cb9b4a3f94471e50bdb0f1e6af34842157d33366 --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/branchmanager.go @@ -0,0 +1,1136 @@ +package branchmanager + +import ( + "container/list" + "fmt" + "sort" + + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/kvstore" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/types" + "golang.org/x/crypto/blake2b" + + "github.com/iotaledger/goshimmer/packages/binary/storageprefix" +) + +// BranchManager is an entity that manages the branches of a UTXODAG. It offers methods to add, delete and modify +// Branches. It automatically keeps track of the "monotonicity" of liked and disliked by propagating these flags +// according to the structure of the Branch-DAG. +type BranchManager struct { + // stores the branches + branchStorage *objectstorage.ObjectStorage + + // stores the references which branch is the child of which parent (we store this in a separate "reference entity" + // instead of the branch itself, because there can potentially be a very large amount of child branches and we do + // not want the branch instance to get bigger and bigger (it would slow down its marshaling/unmarshaling). + childBranchStorage *objectstorage.ObjectStorage + + // stores the conflicts that create constraints regarding which branches can be aggregated. + conflictStorage *objectstorage.ObjectStorage + + // stores the references which branch is part of which conflict (we store this in a separate "reference entity" + // instead of the conflict itself, because there can be a very large amount of member branches and we do not want + // the conflict instance to get bigger and bigger (it would slow down its marshaling/unmarshaling). + conflictMemberStorage *objectstorage.ObjectStorage + + // contains the Events of the BranchManager + Events *Events +} + +// New is the constructor of the BranchManager. +func New(store kvstore.KVStore) (branchManager *BranchManager) { + osFactory := objectstorage.NewFactory(store, storageprefix.ValueTransfers) + + branchManager = &BranchManager{ + branchStorage: osFactory.New(osBranch, osBranchFactory, osBranchOptions...), + childBranchStorage: osFactory.New(osChildBranch, osChildBranchFactory, osChildBranchOptions...), + conflictStorage: osFactory.New(osConflict, osConflictFactory, osConflictOptions...), + conflictMemberStorage: osFactory.New(osConflictMember, osConflictMemberFactory, osConflictMemberOptions...), + Events: &Events{ + BranchPreferred: events.NewEvent(branchCaller), + BranchUnpreferred: events.NewEvent(branchCaller), + BranchLiked: events.NewEvent(branchCaller), + BranchDisliked: events.NewEvent(branchCaller), + BranchFinalized: events.NewEvent(branchCaller), + BranchConfirmed: events.NewEvent(branchCaller), + BranchRejected: events.NewEvent(branchCaller), + }, + } + branchManager.init() + + return +} + +// Branch loads a Branch from the objectstorage. +func (branchManager *BranchManager) Branch(branchID BranchID) *CachedBranch { + return &CachedBranch{CachedObject: branchManager.branchStorage.Load(branchID.Bytes())} +} + +// ChildBranches loads the references to the ChildBranches of the given Branch. +func (branchManager *BranchManager) ChildBranches(branchID BranchID) CachedChildBranches { + childBranches := make(CachedChildBranches, 0) + branchManager.childBranchStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + childBranches = append(childBranches, &CachedChildBranch{CachedObject: cachedObject}) + + return true + }, branchID.Bytes()) + + return childBranches +} + +// Conflict loads a Conflict from the objectstorage. +func (branchManager *BranchManager) Conflict(conflictID ConflictID) *CachedConflict { + return &CachedConflict{CachedObject: branchManager.conflictStorage.Load(conflictID.Bytes())} +} + +// ConflictMembers loads the referenced members of a Conflict from the objectstorage. +func (branchManager *BranchManager) ConflictMembers(conflictID ConflictID) CachedConflictMembers { + conflictMembers := make(CachedConflictMembers, 0) + branchManager.conflictMemberStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + conflictMembers = append(conflictMembers, &CachedConflictMember{CachedObject: cachedObject}) + + return true + }, conflictID.Bytes()) + + return conflictMembers +} + +// Fork adds a new Branch to the branch-DAG and automatically creates the Conflicts and references if they don't exist. +// It can also be used to update an existing Branch and add it to additional conflicts. +func (branchManager *BranchManager) Fork(branchID BranchID, parentBranches []BranchID, conflicts []ConflictID) (cachedBranch *CachedBranch, newBranchCreated bool) { + // create or load the branch + cachedBranch = &CachedBranch{ + CachedObject: branchManager.branchStorage.ComputeIfAbsent(branchID.Bytes(), + func(key []byte) objectstorage.StorableObject { + newBranch := NewBranch(branchID, parentBranches) + newBranch.Persist() + newBranch.SetModified() + + newBranchCreated = true + + return newBranch + }, + ), + } + + // create the referenced entities and references + cachedBranch.Retain().Consume(func(branch *Branch) { + // store references from the parent branches to this new child branch (only once when the branch is created + // since updating the parents happens through ElevateConflictBranch and is only valid for conflict Branches) + if newBranchCreated { + for _, parentBranchID := range parentBranches { + if cachedChildBranch, stored := branchManager.childBranchStorage.StoreIfAbsent(NewChildBranch(parentBranchID, branchID)); stored { + cachedChildBranch.Release() + } + } + } + + // store conflict + conflict references + for _, conflictID := range conflicts { + if branch.addConflict(conflictID) { + (&CachedConflict{CachedObject: branchManager.conflictStorage.ComputeIfAbsent(conflictID.Bytes(), func(key []byte) objectstorage.StorableObject { + newConflict := NewConflict(conflictID) + newConflict.Persist() + newConflict.SetModified() + + return newConflict + })}).Consume(func(conflict *Conflict) { + if cachedConflictMember, stored := branchManager.conflictMemberStorage.StoreIfAbsent(NewConflictMember(conflictID, branchID)); stored { + conflict.IncreaseMemberCount() + + cachedConflictMember.Release() + } + }) + } + } + }) + + return +} + +// ElevateConflictBranch moves a branch to a new parent. This is necessary if a new conflict appears in the past cone +// of an already existing conflict. +func (branchManager *BranchManager) ElevateConflictBranch(branchToElevate BranchID, newParent BranchID) (isConflictBranch bool, modified bool, err error) { + // load the branch + currentCachedBranch := branchManager.Branch(branchToElevate) + defer currentCachedBranch.Release() + + // abort if we could not load the branch + currentBranch := currentCachedBranch.Unwrap() + if currentBranch == nil { + err = fmt.Errorf("failed to load branch '%s'", branchToElevate) + + return + } + + // abort if this branch is aggregated (only conflict branches can be elevated) + if currentBranch.IsAggregated() { + return + } + isConflictBranch = true + + // remove old child branch references + branchManager.childBranchStorage.Delete(marshalutil.New(BranchIDLength * 2). + WriteBytes(currentBranch.ParentBranches()[0].Bytes()). + WriteBytes(branchToElevate.Bytes()). + Bytes(), + ) + + // add new child branch references + if cachedChildBranch, stored := branchManager.childBranchStorage.StoreIfAbsent(NewChildBranch(newParent, branchToElevate)); stored { + cachedChildBranch.Release() + } + + // update parent of branch + if modified, err = currentBranch.updateParentBranch(newParent); err != nil { + return + } + + return +} + +// BranchesConflicting returns true if the given Branches are part of the same Conflicts and can therefore not be +// merged. +func (branchManager *BranchManager) BranchesConflicting(branchIds ...BranchID) (branchesConflicting bool, err error) { + // iterate through branches and collect conflicting branches + traversedBranches := make(map[BranchID]types.Empty) + blacklistedBranches := make(map[BranchID]types.Empty) + for _, branchID := range branchIds { + // add the current branch to the stack of branches to check + ancestorStack := list.New() + ancestorStack.PushBack(branchID) + + // iterate over all ancestors and collect the conflicting branches + for ancestorStack.Len() >= 1 { + // retrieve branch from stack + firstElement := ancestorStack.Front() + currentBranchID := firstElement.Value.(BranchID) + ancestorStack.Remove(firstElement) + + // abort if we have seen this branch already + if _, traversedAlready := traversedBranches[currentBranchID]; traversedAlready { + continue + } + + // abort if this branch was blacklisted by another branch already + if _, branchesConflicting = blacklistedBranches[currentBranchID]; branchesConflicting { + return + } + + // unpack the branch and abort if we failed to load it + currentCachedBranch := branchManager.Branch(currentBranchID) + currentBranch := currentCachedBranch.Unwrap() + if currentBranch == nil { + err = fmt.Errorf("failed to load branch '%s'", currentBranchID) + + currentCachedBranch.Release() + + return + } + + // add the parents of the current branch to the list of branches to check + for _, parentBranchID := range currentBranch.ParentBranches() { + ancestorStack.PushBack(parentBranchID) + } + + // abort the following checks if the branch is aggregated (aggregated branches have no own conflicts) + if currentBranch.IsAggregated() { + currentCachedBranch.Release() + + continue + } + + // iterate through the conflicts and take note of its member branches + for conflictID := range currentBranch.Conflicts() { + for _, cachedConflictMember := range branchManager.ConflictMembers(conflictID) { + // unwrap the current ConflictMember + conflictMember := cachedConflictMember.Unwrap() + if conflictMember == nil { + cachedConflictMember.Release() + + continue + } + + if conflictMember.BranchID() == currentBranchID { + cachedConflictMember.Release() + + continue + } + + // abort if this branch was found as a conflict of another branch already + if _, branchesConflicting = traversedBranches[conflictMember.BranchID()]; branchesConflicting { + cachedConflictMember.Release() + currentCachedBranch.Release() + + return + } + + // store the current conflict in the list of seen conflicting branches + blacklistedBranches[conflictMember.BranchID()] = types.Void + + cachedConflictMember.Release() + } + } + + currentCachedBranch.Release() + + traversedBranches[currentBranchID] = types.Void + } + } + + return +} + +// AggregateBranches takes a list of BranchIDs and tries to "aggregate" the given IDs into a new Branch. It is used to +// correctly "inherit" the referenced parent Branches into a new one. +func (branchManager *BranchManager) AggregateBranches(branches ...BranchID) (cachedAggregatedBranch *CachedBranch, err error) { + // return the MasterBranch if we have no branches in the parameters + if len(branches) == 0 { + cachedAggregatedBranch = branchManager.Branch(MasterBranchID) + + return + } + + // return the first branch if there is only one + if len(branches) == 1 { + cachedAggregatedBranch = branchManager.Branch(branches[0]) + + return + } + + // check if the branches are conflicting + branchesConflicting, err := branchManager.BranchesConflicting(branches...) + if err != nil { + return + } + if branchesConflicting { + err = fmt.Errorf("the given branches are conflicting and can not be aggregated") + + return + } + + // filter out duplicates and shared ancestor Branches (abort if we faced an error) + deepestCommonAncestors, err := branchManager.findDeepestCommonDescendants(branches...) + if err != nil { + return + } + + // if there is only one branch that we found, then we are done + if len(deepestCommonAncestors) == 1 { + for _, firstBranchInList := range deepestCommonAncestors { + cachedAggregatedBranch = firstBranchInList + } + + return + } + + // if there is more than one parent: aggregate + aggregatedBranchID, aggregatedBranchParents, err := branchManager.determineAggregatedBranchDetails(deepestCommonAncestors) + if err != nil { + return + } + + // create or update the aggregated branch (the conflicts is an empty list because aggregated branches are not + // directly conflicting with other branches but are only used to propagate votes to all of their parents) + cachedAggregatedBranch, _ = branchManager.Fork(aggregatedBranchID, aggregatedBranchParents, []ConflictID{}) + + return +} + +// SetBranchPreferred is the method that allows us to modify the preferred flag of a branch. +func (branchManager *BranchManager) SetBranchPreferred(branchID BranchID, preferred bool) (modified bool, err error) { + return branchManager.setBranchPreferred(branchManager.Branch(branchID), preferred) +} + +// SetBranchLiked is the method that allows us to modify the liked flag of a branch (it propagates to the parents). +func (branchManager *BranchManager) SetBranchLiked(branchID BranchID, liked bool) (modified bool, err error) { + return branchManager.setBranchLiked(branchManager.Branch(branchID), liked) +} + +// SetBranchFinalized modifies the finalized flag of a branch. It automatically triggers +func (branchManager *BranchManager) SetBranchFinalized(branchID BranchID) (modified bool, err error) { + return branchManager.setBranchFinalized(branchManager.Branch(branchID)) +} + +// GenerateAggregatedBranchID generates an aggregated BranchID from the handed in BranchIDs. +func (branchManager *BranchManager) GenerateAggregatedBranchID(branchIDs ...BranchID) BranchID { + sort.Slice(branchIDs, func(i, j int) bool { + for k := 0; k < len(branchIDs[k]); k++ { + if branchIDs[i][k] < branchIDs[j][k] { + return true + } else if branchIDs[i][k] > branchIDs[j][k] { + return false + } + } + + return false + }) + + marshalUtil := marshalutil.New(BranchIDLength * len(branchIDs)) + for _, branchID := range branchIDs { + marshalUtil.WriteBytes(branchID.Bytes()) + } + + return blake2b.Sum256(marshalUtil.Bytes()) +} + +func (branchManager *BranchManager) setBranchFinalized(cachedBranch *CachedBranch) (modified bool, err error) { + defer cachedBranch.Release() + branch := cachedBranch.Unwrap() + if branch == nil { + err = fmt.Errorf("failed to unwrap branch") + + return + } + + if modified = branch.setFinalized(true); !modified { + return + } + + branchManager.Events.BranchFinalized.Trigger(cachedBranch) + + // propagate finalized to aggregated child branches + if err = branchManager.propagateFinalizedToAggregatedChildBranches(cachedBranch.Retain()); err != nil { + return + } + + if !branch.Preferred() { + branchManager.propagateRejectedToChildBranches(cachedBranch.Retain()) + + return + } + + // update all other branches that are in the same conflict sets to be not preferred and also finalized + for conflictID := range branch.Conflicts() { + branchManager.ConflictMembers(conflictID).Consume(func(conflictMember *ConflictMember) { + // skip the branch which just got preferred + if conflictMember.BranchID() == branch.ID() { + return + } + + _, err = branchManager.setBranchPreferred(branchManager.Branch(conflictMember.BranchID()), false) + if err != nil { + return + } + _, err = branchManager.setBranchFinalized(branchManager.Branch(conflictMember.BranchID())) + if err != nil { + return + } + }) + } + + // schedule confirmed checks of children + err = branchManager.propagateConfirmedToChildBranches(cachedBranch.Retain()) + + return +} + +// propagateFinalizedToAggregatedChildBranches propagates the finalized flag to the aggregated child branches of the +// given branch. An aggregated branch is finalized if all of its parents are finalized. +func (branchManager *BranchManager) propagateFinalizedToAggregatedChildBranches(cachedBranch *CachedBranch) (err error) { + // initialize stack with the child branches of the given branch + propagationStack := list.New() + cachedBranch.Consume(func(branch *Branch) { + branchManager.ChildBranches(branch.ID()).Consume(func(childBranch *ChildBranch) { + propagationStack.PushBack(branchManager.Branch(childBranch.ChildID())) + }) + }) + + // iterate through stack to propagate the changes to child branches + for propagationStack.Len() >= 1 { + stackElement := propagationStack.Front() + stackElement.Value.(*CachedBranch).Consume(func(branch *Branch) { + // abort if the branch is not aggregated + if !branch.IsAggregated() { + return + } + + // abort if not all parents are confirmed + for _, parentBranchID := range branch.ParentBranches() { + cachedParentBranch := branchManager.Branch(parentBranchID) + if parentBranch := cachedParentBranch.Unwrap(); parentBranch == nil || !parentBranch.Finalized() { + cachedParentBranch.Release() + + return + } + cachedParentBranch.Release() + } + + // abort if the branch was finalized already + if !branch.setFinalized(true) { + return + } + + // trigger events + branchManager.Events.BranchFinalized.Trigger(cachedBranch) + + // schedule confirmed checks of children + branchManager.ChildBranches(branch.ID()).Consume(func(childBranch *ChildBranch) { + propagationStack.PushBack(branchManager.Branch(childBranch.childID)) + }) + }) + propagationStack.Remove(stackElement) + } + + return +} + +func (branchManager *BranchManager) propagateRejectedToChildBranches(cachedBranch *CachedBranch) { + branchStack := list.New() + branchStack.PushBack(cachedBranch) + + for branchStack.Len() >= 1 { + currentStackElement := branchStack.Front() + currentCachedBranch := currentStackElement.Value.(*CachedBranch) + branchStack.Remove(currentStackElement) + + currentBranch := currentCachedBranch.Unwrap() + if currentBranch == nil || !currentBranch.setRejected(true) { + currentCachedBranch.Release() + + continue + } + + branchManager.Events.BranchRejected.Trigger(cachedBranch) + + branchManager.ChildBranches(currentBranch.ID()).Consume(func(childBranch *ChildBranch) { + branchStack.PushBack(branchManager.Branch(childBranch.ChildID())) + }) + + currentCachedBranch.Release() + } +} + +func (branchManager *BranchManager) propagateConfirmedToChildBranches(cachedBranch *CachedBranch) (err error) { + // initialize stack with our entry point for the propagation + propagationStack := list.New() + propagationStack.PushBack(cachedBranch) + + // iterate through stack to propagate the changes to child branches + for propagationStack.Len() >= 1 { + stackElement := propagationStack.Front() + stackElement.Value.(*CachedBranch).Consume(func(branch *Branch) { + // abort if the branch does not fulfill the conditions to be confirmed + if !branch.Preferred() || !branch.Finalized() { + return + } + + // abort if not all parents are confirmed + for _, parentBranchID := range branch.ParentBranches() { + cachedParentBranch := branchManager.Branch(parentBranchID) + if parentBranch := cachedParentBranch.Unwrap(); parentBranch == nil || !parentBranch.Confirmed() { + cachedParentBranch.Release() + + return + } + cachedParentBranch.Release() + } + + // abort if the branch was confirmed already + if !branch.setConfirmed(true) { + return + } + + // trigger events + branchManager.Events.BranchConfirmed.Trigger(cachedBranch) + + // schedule confirmed checks of children + branchManager.ChildBranches(branch.ID()).Consume(func(childBranch *ChildBranch) { + propagationStack.PushBack(branchManager.Branch(childBranch.childID)) + }) + }) + propagationStack.Remove(stackElement) + } + + return +} + +// Prune resets the database and deletes all objects (for testing or "node resets"). +func (branchManager *BranchManager) Prune() (err error) { + for _, storage := range []*objectstorage.ObjectStorage{ + branchManager.branchStorage, + branchManager.childBranchStorage, + branchManager.conflictStorage, + branchManager.conflictMemberStorage, + } { + if err = storage.Prune(); err != nil { + return + } + } + + branchManager.init() + + return +} + +func (branchManager *BranchManager) init() { + cachedBranch, branchAdded := branchManager.Fork(MasterBranchID, []BranchID{}, []ConflictID{}) + if !branchAdded { + cachedBranch.Release() + + return + } + + cachedBranch.Consume(func(branch *Branch) { + branch.setPreferred(true) + branch.setLiked(true) + branch.setFinalized(true) + branch.setConfirmed(true) + }) +} + +func (branchManager *BranchManager) setBranchPreferred(cachedBranch *CachedBranch, preferred bool) (modified bool, err error) { + defer cachedBranch.Release() + branch := cachedBranch.Unwrap() + if branch == nil { + err = fmt.Errorf("failed to unwrap branch") + + return + } + + if !preferred { + if modified = branch.setPreferred(false); modified { + branchManager.Events.BranchUnpreferred.Trigger(cachedBranch) + branchManager.propagatePreferredChangesToAggregatedChildBranches(branch.ID()) + branchManager.propagateDislikeToFutureCone(cachedBranch.Retain()) + } + + return + } + + for conflictID := range branch.Conflicts() { + // update all other branches to be not preferred + branchManager.ConflictMembers(conflictID).Consume(func(conflictMember *ConflictMember) { + // skip the branch which just got preferred + if conflictMember.BranchID() == branch.ID() { + return + } + + _, _ = branchManager.setBranchPreferred(branchManager.Branch(conflictMember.BranchID()), false) + }) + } + + // finally set the branch as preferred + if modified = branch.setPreferred(true); !modified { + return + } + + branchManager.Events.BranchPreferred.Trigger(cachedBranch) + branchManager.propagatePreferredChangesToAggregatedChildBranches(branch.ID()) + err = branchManager.propagateLike(cachedBranch.Retain()) + + return +} + +// propagatePreferredChangesToAggregatedChildBranches recursively updates the preferred flag of all descendants of the +// given Branch. +func (branchManager *BranchManager) propagatePreferredChangesToAggregatedChildBranches(parentBranchID BranchID) { + // initialize stack with children of the passed in parent Branch + branchStack := list.New() + branchManager.ChildBranches(parentBranchID).Consume(func(childBranchReference *ChildBranch) { + branchStack.PushBack(childBranchReference.ChildID()) + }) + + // iterate through child branches and propagate changes + for branchStack.Len() >= 1 { + // retrieve first element from the stack + currentEntry := branchStack.Front() + currentChildBranchID := currentEntry.Value.(BranchID) + branchStack.Remove(currentEntry) + + // load branch from storage + cachedAggregatedChildBranch := branchManager.Branch(currentChildBranchID) + + // only process branches that could be loaded and that are aggregated branches + if aggregatedChildBranch := cachedAggregatedChildBranch.Unwrap(); aggregatedChildBranch != nil && aggregatedChildBranch.IsAggregated() { + // determine if all parents are liked + allParentsPreferred := true + for _, parentID := range aggregatedChildBranch.ParentBranches() { + if allParentsPreferred { + allParentsPreferred = allParentsPreferred && branchManager.Branch(parentID).Consume(func(parentBranch *Branch) { + allParentsPreferred = allParentsPreferred && parentBranch.Preferred() + }) + } + } + + // trigger events and check children if the branch was updated + if aggregatedChildBranch.setPreferred(allParentsPreferred) { + if allParentsPreferred { + branchManager.Events.BranchPreferred.Trigger(cachedAggregatedChildBranch) + } else { + branchManager.Events.BranchUnpreferred.Trigger(cachedAggregatedChildBranch) + } + + // schedule checks for children if preferred flag was updated + branchManager.ChildBranches(currentChildBranchID).Consume(func(childBranchReference *ChildBranch) { + branchStack.PushBack(childBranchReference.ChildID()) + }) + } + } + + // release the branch when we are done + cachedAggregatedChildBranch.Release() + } +} + +func (branchManager *BranchManager) setBranchLiked(cachedBranch *CachedBranch, liked bool) (modified bool, err error) { + defer cachedBranch.Release() + branch := cachedBranch.Unwrap() + if branch == nil { + err = fmt.Errorf("failed to unwrap branch") + + return + } + + if !liked { + if !branch.setPreferred(false) { + return + } + + branchManager.Events.BranchUnpreferred.Trigger(cachedBranch) + + if modified = branch.setLiked(false); !modified { + return + } + + branchManager.Events.BranchDisliked.Trigger(cachedBranch) + + branchManager.propagateDislikeToFutureCone(cachedBranch.Retain()) + + return + } + + for _, parentBranchID := range branch.ParentBranches() { + if _, err = branchManager.setBranchLiked(branchManager.Branch(parentBranchID), true); err != nil { + return + } + } + + for conflictID := range branch.Conflicts() { + branchManager.ConflictMembers(conflictID).Consume(func(conflictMember *ConflictMember) { + if conflictMember.BranchID() == branch.ID() { + return + } + + _, err = branchManager.setBranchPreferred(branchManager.Branch(conflictMember.BranchID()), false) + if err != nil { + return + } + }) + } + + if !branch.setPreferred(true) { + return + } + + branchManager.Events.BranchPreferred.Trigger(cachedBranch) + + if modified = branch.setLiked(true); !modified { + return + } + + branchManager.Events.BranchLiked.Trigger(cachedBranch) + + err = branchManager.propagateLike(cachedBranch.Retain()) + + return +} + +// IsBranchLiked returns true if the Branch is currently marked as liked. +func (branchManager *BranchManager) IsBranchLiked(id BranchID) (liked bool) { + if id == UndefinedBranchID { + return + } + + if id == MasterBranchID { + return true + } + + branchManager.Branch(id).Consume(func(branch *Branch) { + liked = branch.Liked() + }) + + return +} + +// IsBranchConfirmed returns true if the Branch is marked as confirmed. +func (branchManager *BranchManager) IsBranchConfirmed(id BranchID) (confirmed bool) { + if id == UndefinedBranchID { + return + } + + if id == MasterBranchID { + return true + } + + branchManager.Branch(id).Consume(func(branch *Branch) { + confirmed = branch.Confirmed() + }) + + return +} + +func (branchManager *BranchManager) propagateLike(cachedBranch *CachedBranch) (err error) { + // unpack CachedBranch and abort of the branch doesn't exist or isn't preferred + defer cachedBranch.Release() + branch := cachedBranch.Unwrap() + if branch == nil || !branch.Preferred() { + return + } + + // check if parents are liked + for _, parentBranchID := range branch.ParentBranches() { + // abort, if the parent branch can not be loaded + cachedParentBranch := branchManager.Branch(parentBranchID) + parentBranch := cachedParentBranch.Unwrap() + if parentBranch == nil { + cachedParentBranch.Release() + + return fmt.Errorf("failed to load parent branch '%s' of branch '%s'", parentBranchID, branch.ID()) + } + + // abort if the parent branch is not liked + if !parentBranch.Liked() { + cachedParentBranch.Release() + + return + } + + cachedParentBranch.Release() + } + + // abort if the branch was liked already + if !branch.setLiked(true) { + return + } + + // trigger events + branchManager.Events.BranchLiked.Trigger(cachedBranch) + + // propagate liked checks to the children + for _, cachedChildBranch := range branchManager.ChildBranches(branch.ID()) { + childBranch := cachedChildBranch.Unwrap() + if childBranch == nil { + cachedChildBranch.Release() + + continue + } + + if err = branchManager.propagateLike(branchManager.Branch(childBranch.ChildID())); err != nil { + cachedChildBranch.Release() + + return + } + + cachedChildBranch.Release() + } + + return +} + +func (branchManager *BranchManager) propagateDislikeToFutureCone(cachedBranch *CachedBranch) { + branchStack := list.New() + branchStack.PushBack(cachedBranch) + + for branchStack.Len() >= 1 { + currentStackElement := branchStack.Front() + currentCachedBranch := currentStackElement.Value.(*CachedBranch) + branchStack.Remove(currentStackElement) + + currentBranch := currentCachedBranch.Unwrap() + if currentBranch == nil || !currentBranch.setLiked(false) { + currentCachedBranch.Release() + + continue + } + + branchManager.Events.BranchDisliked.Trigger(cachedBranch) + + branchManager.ChildBranches(currentBranch.ID()).Consume(func(childBranch *ChildBranch) { + branchStack.PushBack(branchManager.Branch(childBranch.ChildID())) + }) + + currentCachedBranch.Release() + } +} + +func (branchManager *BranchManager) determineAggregatedBranchDetails(deepestCommonAncestors CachedBranches) (aggregatedBranchID BranchID, aggregatedBranchParents []BranchID, err error) { + aggregatedBranchParents = make([]BranchID, len(deepestCommonAncestors)) + + i := 0 + aggregatedBranchConflictParents := make(CachedBranches) + for branchID, cachedBranch := range deepestCommonAncestors { + // release all following entries if we have encountered an error + if err != nil { + cachedBranch.Release() + + continue + } + + // store BranchID as parent + aggregatedBranchParents[i] = branchID + i++ + + // abort if we could not unwrap the Branch (should never happen) + branch := cachedBranch.Unwrap() + if branch == nil { + cachedBranch.Release() + + err = fmt.Errorf("failed to unwrap brach '%s'", branchID) + + continue + } + + if !branch.IsAggregated() { + aggregatedBranchConflictParents[branchID] = cachedBranch + + continue + } + + err = branchManager.collectClosestConflictAncestors(branch, aggregatedBranchConflictParents) + + cachedBranch.Release() + } + + if err != nil { + aggregatedBranchConflictParents.Release() + aggregatedBranchConflictParents = nil + + return + } + + aggregatedBranchID = branchManager.generateAggregatedBranchID(aggregatedBranchConflictParents) + + return +} + +func (branchManager *BranchManager) generateAggregatedBranchID(aggregatedBranches CachedBranches) BranchID { + counter := 0 + branchIDs := make([]BranchID, len(aggregatedBranches)) + for branchID, cachedBranch := range aggregatedBranches { + branchIDs[counter] = branchID + + counter++ + + cachedBranch.Release() + } + + return branchManager.GenerateAggregatedBranchID(branchIDs...) +} + +func (branchManager *BranchManager) collectClosestConflictAncestors(branch *Branch, closestConflictAncestors CachedBranches) (err error) { + // initialize stack + stack := list.New() + for _, parentRealityID := range branch.ParentBranches() { + stack.PushBack(parentRealityID) + } + + // work through stack + processedBranches := make(map[BranchID]types.Empty) + for stack.Len() != 0 { + // iterate through the parents (in a func so we can used defer) + err = func() error { + // pop parent branch id from stack + firstStackElement := stack.Front() + defer stack.Remove(firstStackElement) + parentBranchID := stack.Front().Value.(BranchID) + + // abort if the parent has been processed already + if _, branchProcessed := processedBranches[parentBranchID]; branchProcessed { + return nil + } + processedBranches[parentBranchID] = types.Void + + // load parent branch from database + cachedParentBranch := branchManager.Branch(parentBranchID) + + // abort if the parent branch could not be found (should never happen) + parentBranch := cachedParentBranch.Unwrap() + if parentBranch == nil { + cachedParentBranch.Release() + + return fmt.Errorf("failed to load branch '%s'", parentBranchID) + } + + // if the parent Branch is not aggregated, then we have found the closest conflict ancestor + if !parentBranch.IsAggregated() { + closestConflictAncestors[parentBranchID] = cachedParentBranch + + return nil + } + + // queue parents for additional check (recursion) + for _, parentRealityID := range parentBranch.ParentBranches() { + stack.PushBack(parentRealityID) + } + + // release the branch (we don't need it anymore) + cachedParentBranch.Release() + + return nil + }() + + if err != nil { + return + } + } + + return +} + +// findDeepestCommonDescendants takes a number of BranchIds and determines the most specialized Branches (furthest +// away from the MasterBranch) in that list, that contains all of the named BranchIds. +// +// Example: If we hand in "A, B" and B has A as its parent, then the result will contain the Branch B, because B is a +// child of A. +func (branchManager *BranchManager) findDeepestCommonDescendants(branches ...BranchID) (result CachedBranches, err error) { + result = make(CachedBranches) + + processedBranches := make(map[BranchID]types.Empty) + for _, branchID := range branches { + err = func() error { + // continue, if we have processed this branch already + if _, exists := processedBranches[branchID]; exists { + return nil + } + processedBranches[branchID] = types.Void + + // load branch from objectstorage + cachedBranch := branchManager.Branch(branchID) + + // abort if we could not load the CachedBranch + branch := cachedBranch.Unwrap() + if branch == nil { + cachedBranch.Release() + + return fmt.Errorf("could not load branch '%s'", branchID) + } + + // check branches position relative to already aggregated branches + for aggregatedBranchID, cachedAggregatedBranch := range result { + // abort if we can not load the branch + aggregatedBranch := cachedAggregatedBranch.Unwrap() + if aggregatedBranch == nil { + return fmt.Errorf("could not load branch '%s'", aggregatedBranchID) + } + + // if the current branch is an ancestor of an already aggregated branch, then we have found the more + // "specialized" branch already and keep it + if isAncestor, ancestorErr := branchManager.branchIsAncestorOfBranch(branch, aggregatedBranch); isAncestor || ancestorErr != nil { + return ancestorErr + } + + // check if the aggregated Branch is an ancestor of the current Branch and abort if we face an error + isAncestor, ancestorErr := branchManager.branchIsAncestorOfBranch(aggregatedBranch, branch) + if ancestorErr != nil { + return ancestorErr + } + + // if the aggregated branch is an ancestor of the current branch, then we have found a more specialized + // Branch and replace the old one with this one. + if isAncestor { + // replace aggregated branch if we have found a more specialized on + delete(result, aggregatedBranchID) + cachedAggregatedBranch.Release() + + result[branchID] = cachedBranch + } + } + + // store the branch as a new aggregate candidate if it was not found to be in any relation with the already + // aggregated ones. + result[branchID] = cachedBranch + + return nil + }() + + // abort if an error occurred while processing the current branch + if err != nil { + result.Release() + result = nil + + return + } + } + + return +} + +func (branchManager *BranchManager) branchIsAncestorOfBranch(ancestor *Branch, descendant *Branch) (isAncestor bool, err error) { + if ancestor.ID() == descendant.ID() { + return true, nil + } + + ancestorBranches, err := branchManager.getAncestorBranches(descendant) + if err != nil { + return + } + + ancestorBranches.Consume(func(ancestorOfDescendant *Branch) { + if ancestorOfDescendant.ID() == ancestor.ID() { + isAncestor = true + } + }) + + return +} + +func (branchManager *BranchManager) getAncestorBranches(branch *Branch) (ancestorBranches CachedBranches, err error) { + // initialize result + ancestorBranches = make(CachedBranches) + + // initialize stack + stack := list.New() + for _, parentRealityID := range branch.ParentBranches() { + stack.PushBack(parentRealityID) + } + + // work through stack + for stack.Len() != 0 { + // iterate through the parents (in a func so we can used defer) + err = func() error { + // pop parent branch id from stack + firstStackElement := stack.Front() + defer stack.Remove(firstStackElement) + parentBranchID := stack.Front().Value.(BranchID) + + // abort if the parent has been processed already + if _, branchProcessed := ancestorBranches[parentBranchID]; branchProcessed { + return nil + } + + // load parent branch from database + cachedParentBranch := branchManager.Branch(parentBranchID) + + // abort if the parent branch could not be founds (should never happen) + parentBranch := cachedParentBranch.Unwrap() + if parentBranch == nil { + cachedParentBranch.Release() + + return fmt.Errorf("failed to unwrap branch '%s'", parentBranchID) + } + + // store parent branch in result + ancestorBranches[parentBranchID] = cachedParentBranch + + // queue parents for additional check (recursion) + for _, parentRealityID := range parentBranch.ParentBranches() { + stack.PushBack(parentRealityID) + } + + return nil + }() + + // abort if an error occurs while trying to process the parents + if err != nil { + ancestorBranches.Release() + ancestorBranches = nil + + return + } + } + + return +} diff --git a/dapps/valuetransfers/packages/branchmanager/branchmanager_test.go b/dapps/valuetransfers/packages/branchmanager/branchmanager_test.go new file mode 100644 index 0000000000000000000000000000000000000000..268499b7b446b9536a2784f0b7ba902b05b7eebe --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/branchmanager_test.go @@ -0,0 +1,1178 @@ +package branchmanager + +import ( + "reflect" + "testing" + + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +type sampleTree struct { + cachedBranches [17]*CachedBranch + branches [17]*Branch + numID map[BranchID]int +} + +func (st *sampleTree) Release() { + for i := range st.cachedBranches { + if st.cachedBranches[i] == nil { + continue + } + st.cachedBranches[i].Release() + } +} + +// eventMock is a wrapper around mock.Mock used to test the triggered events. +type eventMock struct { + mock.Mock + + attached []struct { + *events.Event + *events.Closure + } +} + +func newEventMock(t *testing.T, mgr *BranchManager) *eventMock { + e := &eventMock{} + e.Test(t) + + // attach all events + e.attach(mgr.Events.BranchConfirmed, e.BranchConfirmed) + e.attach(mgr.Events.BranchDisliked, e.BranchDisliked) + e.attach(mgr.Events.BranchFinalized, e.BranchFinalized) + e.attach(mgr.Events.BranchLiked, e.BranchLiked) + e.attach(mgr.Events.BranchPreferred, e.BranchPreferred) + e.attach(mgr.Events.BranchRejected, e.BranchRejected) + e.attach(mgr.Events.BranchUnpreferred, e.BranchUnpreferred) + + // assure that all available events are mocked + numEvents := reflect.ValueOf(mgr.Events).Elem().NumField() + assert.Equalf(t, len(e.attached), numEvents, "not all events in BranchManager.Events have been attached") + + return e +} + +// DetachAll detaches all attached event mocks. +func (e *eventMock) DetachAll() { + for _, a := range e.attached { + a.Event.Detach(a.Closure) + } +} + +// Expect starts a description of an expectation of the specified event being triggered. +func (e *eventMock) Expect(eventName string, arguments ...interface{}) { + e.On(eventName, arguments...) +} + +func (e *eventMock) attach(event *events.Event, f interface{}) { + closure := events.NewClosure(f) + event.Attach(closure) + e.attached = append(e.attached, struct { + *events.Event + *events.Closure + }{event, closure}) +} + +func (e *eventMock) BranchConfirmed(cachedBranch *CachedBranch) { + defer cachedBranch.Release() + e.Called(cachedBranch.Unwrap()) +} + +func (e *eventMock) BranchDisliked(cachedBranch *CachedBranch) { + defer cachedBranch.Release() + e.Called(cachedBranch.Unwrap()) +} + +func (e *eventMock) BranchFinalized(cachedBranch *CachedBranch) { + defer cachedBranch.Release() + e.Called(cachedBranch.Unwrap()) +} + +func (e *eventMock) BranchLiked(cachedBranch *CachedBranch) { + defer cachedBranch.Release() + e.Called(cachedBranch.Unwrap()) +} + +func (e *eventMock) BranchPreferred(cachedBranch *CachedBranch) { + defer cachedBranch.Release() + e.Called(cachedBranch.Unwrap()) +} + +func (e *eventMock) BranchRejected(cachedBranch *CachedBranch) { + defer cachedBranch.Release() + e.Called(cachedBranch.Unwrap()) +} + +func (e *eventMock) BranchUnpreferred(cachedBranch *CachedBranch) { + defer cachedBranch.Release() + e.Called(cachedBranch.Unwrap()) +} + +// ./img/sample_tree.png +func createSampleTree(branchManager *BranchManager) *sampleTree { + st := &sampleTree{ + numID: map[BranchID]int{}, + } + cachedMasterBranch := branchManager.Branch(MasterBranchID) + st.cachedBranches[1] = cachedMasterBranch + st.branches[1] = cachedMasterBranch.Unwrap() + st.numID[st.branches[1].ID()] = 1 + + cachedBranch2, _ := branchManager.Fork(BranchID{2}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + branch2 := cachedBranch2.Unwrap() + st.branches[2] = branch2 + st.cachedBranches[2] = cachedBranch2 + st.numID[st.branches[2].ID()] = 2 + + cachedBranch3, _ := branchManager.Fork(BranchID{3}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + branch3 := cachedBranch3.Unwrap() + st.branches[3] = branch3 + st.cachedBranches[3] = cachedBranch3 + st.numID[st.branches[3].ID()] = 3 + + cachedBranch4, _ := branchManager.Fork(BranchID{4}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + branch4 := cachedBranch4.Unwrap() + st.branches[4] = branch4 + st.cachedBranches[4] = cachedBranch4 + st.numID[st.branches[4].ID()] = 4 + + cachedBranch5, _ := branchManager.Fork(BranchID{5}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + branch5 := cachedBranch5.Unwrap() + st.branches[5] = branch5 + st.cachedBranches[5] = cachedBranch5 + st.numID[st.branches[5].ID()] = 5 + + cachedBranch6, _ := branchManager.Fork(BranchID{6}, []BranchID{MasterBranchID}, []ConflictID{{2}}) + branch6 := cachedBranch6.Unwrap() + st.branches[6] = branch6 + st.cachedBranches[6] = cachedBranch6 + st.numID[st.branches[6].ID()] = 6 + + cachedBranch7, _ := branchManager.Fork(BranchID{7}, []BranchID{MasterBranchID}, []ConflictID{{2}}) + branch7 := cachedBranch7.Unwrap() + st.branches[7] = branch7 + st.cachedBranches[7] = cachedBranch7 + st.numID[st.branches[7].ID()] = 7 + + cachedBranch8, _ := branchManager.Fork(BranchID{8}, []BranchID{MasterBranchID}, []ConflictID{{3}}) + branch8 := cachedBranch8.Unwrap() + st.branches[8] = branch8 + st.cachedBranches[8] = cachedBranch8 + st.numID[st.branches[8].ID()] = 8 + + cachedBranch9, _ := branchManager.Fork(BranchID{9}, []BranchID{MasterBranchID}, []ConflictID{{3}}) + branch9 := cachedBranch9.Unwrap() + st.branches[9] = branch9 + st.cachedBranches[9] = cachedBranch9 + st.numID[st.branches[9].ID()] = 9 + + cachedAggrBranch10, err := branchManager.AggregateBranches(branch3.ID(), branch6.ID()) + if err != nil { + panic(err) + } + aggrBranch10 := cachedAggrBranch10.Unwrap() + st.branches[10] = aggrBranch10 + st.cachedBranches[10] = cachedAggrBranch10 + st.numID[st.branches[10].ID()] = 10 + + cachedAggrBranch11, err := branchManager.AggregateBranches(branch6.ID(), branch8.ID()) + if err != nil { + panic(err) + } + aggrBranch11 := cachedAggrBranch11.Unwrap() + st.branches[11] = aggrBranch11 + st.cachedBranches[11] = cachedAggrBranch11 + st.numID[st.branches[11].ID()] = 11 + + cachedBranch12, _ := branchManager.Fork(BranchID{12}, []BranchID{aggrBranch10.ID()}, []ConflictID{{4}}) + branch12 := cachedBranch12.Unwrap() + st.branches[12] = branch12 + st.cachedBranches[12] = cachedBranch12 + st.numID[st.branches[12].ID()] = 12 + + cachedBranch13, _ := branchManager.Fork(BranchID{13}, []BranchID{aggrBranch10.ID()}, []ConflictID{{4}}) + branch13 := cachedBranch13.Unwrap() + st.branches[13] = branch13 + st.cachedBranches[13] = cachedBranch13 + st.numID[st.branches[13].ID()] = 13 + + cachedBranch14, _ := branchManager.Fork(BranchID{14}, []BranchID{aggrBranch11.ID()}, []ConflictID{{5}}) + branch14 := cachedBranch14.Unwrap() + st.branches[14] = branch14 + st.cachedBranches[14] = cachedBranch14 + st.numID[st.branches[14].ID()] = 14 + + cachedBranch15, _ := branchManager.Fork(BranchID{15}, []BranchID{aggrBranch11.ID()}, []ConflictID{{5}}) + branch15 := cachedBranch15.Unwrap() + st.branches[15] = branch15 + st.cachedBranches[15] = cachedBranch15 + st.numID[st.branches[15].ID()] = 15 + + cachedAggrBranch16, err := branchManager.AggregateBranches(branch13.ID(), branch14.ID()) + if err != nil { + panic(err) + } + aggrBranch16 := cachedAggrBranch16.Unwrap() + st.branches[16] = aggrBranch16 + st.cachedBranches[16] = cachedAggrBranch16 + st.numID[st.branches[16].ID()] = 16 + return st +} + +func TestGetAncestorBranches(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + + st := createSampleTree(branchManager) + defer st.Release() + + { + masterBranch := branchManager.Branch(MasterBranchID) + assert.NotNil(t, masterBranch) + ancestorBranches, err := branchManager.getAncestorBranches(masterBranch.Unwrap()) + assert.NoError(t, err) + + expectedAncestors := map[BranchID]struct{}{} + actualAncestors := map[BranchID]struct{}{} + ancestorBranches.Consume(func(branch *Branch) { + actualAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedAncestors, actualAncestors) + } + + { + ancestorBranches, err := branchManager.getAncestorBranches(st.branches[4]) + assert.NoError(t, err) + + expectedAncestors := map[BranchID]struct{}{ + st.branches[2].ID(): {}, MasterBranchID: {}, + } + actualAncestors := map[BranchID]struct{}{} + ancestorBranches.Consume(func(branch *Branch) { + actualAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedAncestors, actualAncestors) + } + + { + ancestorBranches, err := branchManager.getAncestorBranches(st.branches[16]) + assert.NoError(t, err) + + expectedAncestors := map[BranchID]struct{}{ + st.branches[13].ID(): {}, st.branches[14].ID(): {}, + st.branches[10].ID(): {}, st.branches[11].ID(): {}, + st.branches[3].ID(): {}, st.branches[6].ID(): {}, st.branches[8].ID(): {}, + MasterBranchID: {}, + } + actualAncestors := map[BranchID]struct{}{} + ancestorBranches.Consume(func(branch *Branch) { + actualAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedAncestors, actualAncestors) + } + + { + ancestorBranches, err := branchManager.getAncestorBranches(st.branches[12]) + assert.NoError(t, err) + + expectedAncestors := map[BranchID]struct{}{ + st.branches[10].ID(): {}, st.branches[3].ID(): {}, + st.branches[6].ID(): {}, MasterBranchID: {}, + } + actualAncestors := map[BranchID]struct{}{} + ancestorBranches.Consume(func(branch *Branch) { + actualAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedAncestors, actualAncestors) + } + + { + ancestorBranches, err := branchManager.getAncestorBranches(st.branches[11]) + assert.NoError(t, err) + + expectedAncestors := map[BranchID]struct{}{ + st.branches[8].ID(): {}, st.branches[6].ID(): {}, MasterBranchID: {}, + } + actualAncestors := map[BranchID]struct{}{} + ancestorBranches.Consume(func(branch *Branch) { + actualAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedAncestors, actualAncestors) + } +} + +func TestIsAncestorOfBranch(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + + st := createSampleTree(branchManager) + defer st.Release() + + type testcase struct { + ancestor *Branch + descendent *Branch + is bool + } + + cases := []testcase{ + {st.branches[2], st.branches[4], true}, + {st.branches[4], st.branches[2], false}, + {st.branches[3], st.branches[4], false}, + {st.branches[3], st.branches[12], true}, + {st.branches[3], st.branches[10], true}, + {st.branches[3], st.branches[16], true}, + {st.branches[1], st.branches[16], true}, + {st.branches[11], st.branches[16], true}, + {st.branches[9], st.branches[16], false}, + {st.branches[6], st.branches[15], true}, + } + + for _, testCase := range cases { + isAncestor, err := branchManager.branchIsAncestorOfBranch(testCase.ancestor, testCase.descendent) + assert.NoError(t, err) + if testCase.is { + assert.True(t, isAncestor, "branch %d is an ancestor of branch %d", st.numID[testCase.ancestor.ID()], st.numID[testCase.descendent.ID()]) + continue + } + assert.False(t, isAncestor, "branch %d is not an ancestor of branch %d", st.numID[testCase.ancestor.ID()], st.numID[testCase.descendent.ID()]) + } +} + +func TestFindDeepestCommonDescendants(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + + st := createSampleTree(branchManager) + defer st.Release() + + { + deepestCommonDescendants, err := branchManager.findDeepestCommonDescendants(MasterBranchID, st.branches[2].ID()) + assert.NoError(t, err) + + expectedDeepestCommonDescendants := map[BranchID]struct{}{ + st.branches[2].ID(): {}, + } + actualDeepestCommonDescendants := map[BranchID]struct{}{} + deepestCommonDescendants.Consume(func(branch *Branch) { + actualDeepestCommonDescendants[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedDeepestCommonDescendants, actualDeepestCommonDescendants) + } + + { + deepestCommonDescendants, err := branchManager.findDeepestCommonDescendants(st.branches[2].ID(), st.branches[3].ID()) + assert.NoError(t, err) + + expectedDeepestCommonDescendants := map[BranchID]struct{}{ + st.branches[2].ID(): {}, st.branches[3].ID(): {}, + } + actualDeepestCommonDescendants := map[BranchID]struct{}{} + deepestCommonDescendants.Consume(func(branch *Branch) { + actualDeepestCommonDescendants[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedDeepestCommonDescendants, actualDeepestCommonDescendants) + } + + { + deepestCommonDescendants, err := branchManager.findDeepestCommonDescendants(st.branches[2].ID(), st.branches[4].ID(), st.branches[5].ID()) + assert.NoError(t, err) + + expectedDeepestCommonDescendants := map[BranchID]struct{}{ + st.branches[4].ID(): {}, st.branches[5].ID(): {}, + } + actualDeepestCommonDescendants := map[BranchID]struct{}{} + deepestCommonDescendants.Consume(func(branch *Branch) { + actualDeepestCommonDescendants[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedDeepestCommonDescendants, actualDeepestCommonDescendants) + } + + // breaks: should only be aggr. branch 11 which consists out of branch 6 and 8 + { + deepestCommonDescendants, err := branchManager.findDeepestCommonDescendants( + st.branches[6].ID(), st.branches[8].ID(), st.branches[11].ID()) + assert.NoError(t, err) + + expectedDeepestCommonDescendants := map[BranchID]struct{}{ + st.branches[11].ID(): {}, + } + actualDeepestCommonDescendants := map[BranchID]struct{}{} + deepestCommonDescendants.Consume(func(branch *Branch) { + actualDeepestCommonDescendants[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedDeepestCommonDescendants, actualDeepestCommonDescendants) + } + + // breaks: thinks that branch 13 is one of the deepest common descendants + { + deepestCommonDescendants, err := branchManager.findDeepestCommonDescendants( + st.branches[6].ID(), st.branches[8].ID(), st.branches[10].ID(), st.branches[11].ID(), + st.branches[12].ID(), st.branches[15].ID(), st.branches[14].ID(), st.branches[13].ID(), + st.branches[16].ID()) + assert.NoError(t, err) + + expectedDeepestCommonDescendants := map[BranchID]struct{}{ + st.branches[12].ID(): {}, st.branches[15].ID(): {}, st.branches[16].ID(): {}, + } + actualDeepestCommonDescendants := map[BranchID]struct{}{} + deepestCommonDescendants.Consume(func(branch *Branch) { + actualDeepestCommonDescendants[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedDeepestCommonDescendants, actualDeepestCommonDescendants) + } +} + +func TestCollectClosestConflictAncestors(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + + st := createSampleTree(branchManager) + defer st.Release() + + { + aggregatedBranchConflictParents := make(CachedBranches) + err := branchManager.collectClosestConflictAncestors(st.branches[10], aggregatedBranchConflictParents) + assert.NoError(t, err) + + expectedClosestConflictAncestors := map[BranchID]struct{}{ + st.branches[3].ID(): {}, st.branches[6].ID(): {}, + } + actualClosestConflictAncestors := map[BranchID]struct{}{} + aggregatedBranchConflictParents.Consume(func(branch *Branch) { + actualClosestConflictAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedClosestConflictAncestors, actualClosestConflictAncestors) + } + + { + aggregatedBranchConflictParents := make(CachedBranches) + err := branchManager.collectClosestConflictAncestors(st.branches[13], aggregatedBranchConflictParents) + assert.NoError(t, err) + + expectedClosestConflictAncestors := map[BranchID]struct{}{ + st.branches[3].ID(): {}, st.branches[6].ID(): {}, + } + actualClosestConflictAncestors := map[BranchID]struct{}{} + aggregatedBranchConflictParents.Consume(func(branch *Branch) { + actualClosestConflictAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedClosestConflictAncestors, actualClosestConflictAncestors) + } + + { + aggregatedBranchConflictParents := make(CachedBranches) + err := branchManager.collectClosestConflictAncestors(st.branches[14], aggregatedBranchConflictParents) + assert.NoError(t, err) + + expectedClosestConflictAncestors := map[BranchID]struct{}{ + st.branches[8].ID(): {}, st.branches[6].ID(): {}, + } + actualClosestConflictAncestors := map[BranchID]struct{}{} + aggregatedBranchConflictParents.Consume(func(branch *Branch) { + actualClosestConflictAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedClosestConflictAncestors, actualClosestConflictAncestors) + } + + { + aggregatedBranchConflictParents := make(CachedBranches) + err := branchManager.collectClosestConflictAncestors(st.branches[16], aggregatedBranchConflictParents) + assert.NoError(t, err) + + expectedClosestConflictAncestors := map[BranchID]struct{}{ + st.branches[13].ID(): {}, st.branches[14].ID(): {}, + } + actualClosestConflictAncestors := map[BranchID]struct{}{} + aggregatedBranchConflictParents.Consume(func(branch *Branch) { + actualClosestConflictAncestors[branch.ID()] = struct{}{} + }) + assert.Equal(t, expectedClosestConflictAncestors, actualClosestConflictAncestors) + } + + { + // lets check whether an aggregated branch out of branch 2 and aggr. branch 11 + // resolves to the same ID as when the actual parents (6 and 8) of aggr. branch 11 + // are used in conjunction with branch 2. + parentsBranches := CachedBranches{ + st.branches[2].ID(): st.cachedBranches[2].Retain(), + st.branches[6].ID(): st.cachedBranches[6].Retain(), + st.branches[8].ID(): st.cachedBranches[8].Retain(), + } + expectedAggrBranchID := branchManager.generateAggregatedBranchID(parentsBranches) + + cachedAggrBranch17, err := branchManager.AggregateBranches(st.branches[2].ID(), st.branches[11].ID()) + assert.NoError(t, err) + assert.Equal(t, expectedAggrBranchID, cachedAggrBranch17.Unwrap().ID()) + cachedAggrBranch17.Release() + } +} + +func TestBranchManager_ConflictMembers(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + + cachedBranch2, _ := branchManager.Fork(BranchID{2}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch2.Release() + branch2 := cachedBranch2.Unwrap() + + cachedBranch3, _ := branchManager.Fork(BranchID{3}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch3.Release() + branch3 := cachedBranch3.Unwrap() + + // assert conflict members + expectedConflictMembers := map[BranchID]struct{}{ + branch2.ID(): {}, branch3.ID(): {}, + } + actualConflictMembers := map[BranchID]struct{}{} + branchManager.ConflictMembers(ConflictID{0}).Consume(func(conflictMember *ConflictMember) { + actualConflictMembers[conflictMember.BranchID()] = struct{}{} + }) + assert.Equal(t, expectedConflictMembers, actualConflictMembers) + + // add branch 4 + cachedBranch4, _ := branchManager.Fork(BranchID{4}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch4.Release() + branch4 := cachedBranch4.Unwrap() + + // branch 4 should now also be part of the conflict set + expectedConflictMembers = map[BranchID]struct{}{ + branch2.ID(): {}, branch3.ID(): {}, branch4.ID(): {}, + } + actualConflictMembers = map[BranchID]struct{}{} + branchManager.ConflictMembers(ConflictID{0}).Consume(func(conflictMember *ConflictMember) { + actualConflictMembers[conflictMember.BranchID()] = struct{}{} + }) + assert.Equal(t, expectedConflictMembers, actualConflictMembers) +} + +// ./img/testelevation.png +func TestBranchManager_ElevateConflictBranch(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + + cachedBranch2, _ := branchManager.Fork(BranchID{2}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch2.Release() + branch2 := cachedBranch2.Unwrap() + + cachedBranch3, _ := branchManager.Fork(BranchID{3}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch3.Release() + branch3 := cachedBranch3.Unwrap() + + cachedBranch4, _ := branchManager.Fork(BranchID{4}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch4.Release() + branch4 := cachedBranch4.Unwrap() + + cachedBranch5, _ := branchManager.Fork(BranchID{5}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch5.Release() + branch5 := cachedBranch5.Unwrap() + + cachedBranch6, _ := branchManager.Fork(BranchID{6}, []BranchID{branch4.ID()}, []ConflictID{{2}}) + defer cachedBranch6.Release() + branch6 := cachedBranch6.Unwrap() + + cachedBranch7, _ := branchManager.Fork(BranchID{7}, []BranchID{branch4.ID()}, []ConflictID{{2}}) + defer cachedBranch7.Release() + branch7 := cachedBranch7.Unwrap() + + // lets assume the conflict between 2 and 3 is resolved and therefore we elevate + // branches 4 and 5 to the master branch + isConflictBranch, modified, err := branchManager.ElevateConflictBranch(branch4.ID(), MasterBranchID) + assert.NoError(t, err, "branch 4 should have been elevated to the master branch") + assert.True(t, isConflictBranch, "branch 4 should have been a conflict branch") + assert.True(t, modified, "branch 4 should have been modified") + assert.Equal(t, MasterBranchID, branch4.ParentBranches()[0], "branch 4's parent should now be the master branch") + + isConflictBranch, modified, err = branchManager.ElevateConflictBranch(branch5.ID(), MasterBranchID) + assert.NoError(t, err, "branch 5 should have been elevated to the master branch") + assert.True(t, isConflictBranch, "branch 5 should have been a conflict branch") + assert.True(t, modified, "branch 5 should have been modified") + assert.Equal(t, MasterBranchID, branch5.ParentBranches()[0], "branch 5's parent should now be the master branch") + + // check whether the child branches are what we expect them to be of the master branch + expectedMasterChildBranches := map[BranchID]struct{}{ + branch2.ID(): {}, branch3.ID(): {}, + branch4.ID(): {}, branch5.ID(): {}, + } + actualMasterChildBranches := map[BranchID]struct{}{} + branchManager.ChildBranches(MasterBranchID).Consume(func(childBranch *ChildBranch) { + actualMasterChildBranches[childBranch.ChildID()] = struct{}{} + }) + assert.Equal(t, expectedMasterChildBranches, actualMasterChildBranches) + + // check that 4 and 5 no longer are children of branch 2 + expectedBranch2ChildBranches := map[BranchID]struct{}{} + actualBranch2ChildBranches := map[BranchID]struct{}{} + branchManager.ChildBranches(branch2.ID()).Consume(func(childBranch *ChildBranch) { + actualBranch2ChildBranches[childBranch.ChildID()] = struct{}{} + }) + assert.Equal(t, expectedBranch2ChildBranches, actualBranch2ChildBranches) + + // lets assume the conflict between 4 and 5 is resolved and therefore we elevate + // branches 6 and 7 to the master branch + isConflictBranch, modified, err = branchManager.ElevateConflictBranch(branch6.ID(), MasterBranchID) + assert.NoError(t, err, "branch 6 should have been elevated to the master branch") + assert.True(t, isConflictBranch, "branch 6 should have been a conflict branch") + assert.True(t, modified, "branch 6 should have been modified") + assert.Equal(t, MasterBranchID, branch6.ParentBranches()[0], "branch 6's parent should now be the master branch") + + isConflictBranch, modified, err = branchManager.ElevateConflictBranch(branch7.ID(), MasterBranchID) + assert.NoError(t, err, "branch 7 should have been elevated to the master branch") + assert.True(t, isConflictBranch, "branch 7 should have been a conflict branch") + assert.True(t, modified, "branch 7 should have been modified") + assert.Equal(t, MasterBranchID, branch7.ParentBranches()[0], "branch 7's parent should now be the master branch") + + // check whether the child branches are what we expect them to be of the master branch + expectedMasterChildBranches = map[BranchID]struct{}{ + branch2.ID(): {}, branch3.ID(): {}, + branch4.ID(): {}, branch5.ID(): {}, + branch6.ID(): {}, branch7.ID(): {}, + } + actualMasterChildBranches = map[BranchID]struct{}{} + branchManager.ChildBranches(MasterBranchID).Consume(func(childBranch *ChildBranch) { + actualMasterChildBranches[childBranch.ChildID()] = struct{}{} + }) + assert.Equal(t, expectedMasterChildBranches, actualMasterChildBranches) + + // check that 6 and 7 no longer are children of branch 4 + expectedBranch4ChildBranches := map[BranchID]struct{}{} + actualBranch4ChildBranches := map[BranchID]struct{}{} + branchManager.ChildBranches(branch4.ID()).Consume(func(childBranch *ChildBranch) { + actualBranch4ChildBranches[childBranch.ChildID()] = struct{}{} + }) + assert.Equal(t, expectedBranch4ChildBranches, actualBranch4ChildBranches) + + // TODO: branches are never deleted? +} + +// ./img/testconflictdetection.png +func TestBranchManager_BranchesConflicting(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + + cachedBranch2, _ := branchManager.Fork(BranchID{2}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch2.Release() + branch2 := cachedBranch2.Unwrap() + + cachedBranch3, _ := branchManager.Fork(BranchID{3}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch3.Release() + branch3 := cachedBranch3.Unwrap() + + { + conflicting, err := branchManager.BranchesConflicting(MasterBranchID, branch2.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 2 should not be conflicting with master branch") + + conflicting, err = branchManager.BranchesConflicting(MasterBranchID, branch2.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 3 should not be conflicting with master branch") + + conflicting, err = branchManager.BranchesConflicting(branch2.ID(), branch3.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "branch 2 & 3 should be conflicting with each other") + } + + // spawn of branch 4 and 5 from branch 2 + cachedBranch4, _ := branchManager.Fork(BranchID{4}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch4.Release() + branch4 := cachedBranch4.Unwrap() + + cachedBranch5, _ := branchManager.Fork(BranchID{5}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch5.Release() + branch5 := cachedBranch5.Unwrap() + + { + conflicting, err := branchManager.BranchesConflicting(MasterBranchID, branch4.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 4 should not be conflicting with master branch") + + conflicting, err = branchManager.BranchesConflicting(branch3.ID(), branch4.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "branch 3 & 4 should be conflicting with each other") + + conflicting, err = branchManager.BranchesConflicting(MasterBranchID, branch5.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 5 should not be conflicting with master branch") + + conflicting, err = branchManager.BranchesConflicting(branch3.ID(), branch5.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "branch 3 & 5 should be conflicting with each other") + + // since both consume the same output + conflicting, err = branchManager.BranchesConflicting(branch4.ID(), branch5.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "branch 4 & 5 should be conflicting with each other") + } + + // branch 6, 7 are on the same level as 2 and 3 but are not part of that conflict set + cachedBranch6, _ := branchManager.Fork(BranchID{6}, []BranchID{MasterBranchID}, []ConflictID{{2}}) + defer cachedBranch6.Release() + branch6 := cachedBranch6.Unwrap() + + cachedBranch7, _ := branchManager.Fork(BranchID{7}, []BranchID{MasterBranchID}, []ConflictID{{2}}) + defer cachedBranch7.Release() + branch7 := cachedBranch7.Unwrap() + + { + conflicting, err := branchManager.BranchesConflicting(branch2.ID(), branch6.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 6 should not be conflicting with branch 2") + + conflicting, err = branchManager.BranchesConflicting(branch3.ID(), branch6.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 6 should not be conflicting with branch 3") + + conflicting, err = branchManager.BranchesConflicting(branch2.ID(), branch7.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 7 should not be conflicting with branch 2") + + conflicting, err = branchManager.BranchesConflicting(branch3.ID(), branch7.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 7 should not be conflicting with branch 3") + + conflicting, err = branchManager.BranchesConflicting(branch6.ID(), branch7.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "branch 6 & 7 should be conflicting with each other") + + conflicting, err = branchManager.BranchesConflicting(branch4.ID(), branch6.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 6 should not be conflicting with branch 4") + + conflicting, err = branchManager.BranchesConflicting(branch5.ID(), branch6.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 6 should not be conflicting with branch 5") + + conflicting, err = branchManager.BranchesConflicting(branch4.ID(), branch7.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 7 should not be conflicting with branch 4") + + conflicting, err = branchManager.BranchesConflicting(branch5.ID(), branch7.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 7 should not be conflicting with branch 5") + } + + // aggregated branch out of branch 4 (child of branch 2) and branch 6 + cachedAggrBranch8, aggrBranchErr := branchManager.AggregateBranches(branch4.ID(), branch6.ID()) + assert.NoError(t, aggrBranchErr) + defer cachedAggrBranch8.Release() + aggrBranch8 := cachedAggrBranch8.Unwrap() + + { + conflicting, err := branchManager.BranchesConflicting(aggrBranch8.ID(), MasterBranchID) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 8 should not be conflicting with master branch") + + conflicting, err = branchManager.BranchesConflicting(aggrBranch8.ID(), branch2.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 8 should not be conflicting with branch 2") + + // conflicting since branch 2 and branch 3 are + conflicting, err = branchManager.BranchesConflicting(aggrBranch8.ID(), branch3.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 8 & branch 3 should be conflicting with each other") + + // conflicting since branch 4 and branch 5 are + conflicting, err = branchManager.BranchesConflicting(aggrBranch8.ID(), branch5.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 8 & branch 5 should be conflicting with each other") + + // conflicting since branch 6 and branch 7 are + conflicting, err = branchManager.BranchesConflicting(aggrBranch8.ID(), branch7.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 8 & branch 7 should be conflicting with each other") + } + + // aggregated branch out of aggr. branch 8 and branch 7: + // should fail since branch 6 & 7 are conflicting + _, aggrBranchErr = branchManager.AggregateBranches(aggrBranch8.ID(), branch7.ID()) + assert.Error(t, aggrBranchErr, "can't aggregate branches aggr. branch 8 & conflict branch 7") + + // aggregated branch out of branch 5 (child of branch 2) and branch 7 + cachedAggrBranch9, aggrBranchErr := branchManager.AggregateBranches(branch5.ID(), branch7.ID()) + assert.NoError(t, aggrBranchErr) + defer cachedAggrBranch9.Release() + aggrBranch9 := cachedAggrBranch9.Unwrap() + + assert.NotEqual(t, aggrBranch8.ID().String(), aggrBranch9.ID().String(), "aggr. branches 8 & 9 should have different IDs") + + { + conflicting, err := branchManager.BranchesConflicting(aggrBranch9.ID(), MasterBranchID) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 9 should not be conflicting with master branch") + + // aggr. branch 8 and 9 should be conflicting, since 4 & 5 and 6 & 7 are + conflicting, err = branchManager.BranchesConflicting(aggrBranch8.ID(), aggrBranch9.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 8 & branch 9 should be conflicting with each other") + + // conflicting since branch 3 & 2 are + conflicting, err = branchManager.BranchesConflicting(branch3.ID(), aggrBranch9.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 9 & branch 3 should be conflicting with each other") + } + + // aggregated branch out of branch 3 and branch 6 + cachedAggrBranch10, aggrBranchErr := branchManager.AggregateBranches(branch3.ID(), branch6.ID()) + assert.NoError(t, aggrBranchErr) + defer cachedAggrBranch10.Release() + aggrBranch10 := cachedAggrBranch10.Unwrap() + + { + conflicting, err := branchManager.BranchesConflicting(aggrBranch10.ID(), MasterBranchID) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 10 should not be conflicting with master branch") + + // aggr. branch 8 and 10 should be conflicting, since 2 & 3 are + conflicting, err = branchManager.BranchesConflicting(aggrBranch8.ID(), aggrBranch10.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 8 & branch 10 should be conflicting with each other") + + // aggr. branch 9 and 10 should be conflicting, since 2 & 3 and 6 & 7 are + conflicting, err = branchManager.BranchesConflicting(aggrBranch9.ID(), aggrBranch10.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 9 & branch 10 should be conflicting with each other") + } + + // branch 11, 12 are on the same level as 2 & 3 and 6 & 7 but are not part of either conflict set + cachedBranch11, _ := branchManager.Fork(BranchID{11}, []BranchID{MasterBranchID}, []ConflictID{{3}}) + defer cachedBranch11.Release() + branch11 := cachedBranch11.Unwrap() + + cachedBranch12, _ := branchManager.Fork(BranchID{12}, []BranchID{MasterBranchID}, []ConflictID{{3}}) + defer cachedBranch12.Release() + branch12 := cachedBranch12.Unwrap() + + { + conflicting, err := branchManager.BranchesConflicting(MasterBranchID, branch11.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 11 should not be conflicting with master branch") + + conflicting, err = branchManager.BranchesConflicting(MasterBranchID, branch12.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "branch 12 should not be conflicting with master branch") + + conflicting, err = branchManager.BranchesConflicting(branch11.ID(), branch12.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "branch 11 & 12 should be conflicting with each other") + } + + // aggr. branch 13 out of branch 6 and 11 + cachedAggrBranch13, aggrBranchErr := branchManager.AggregateBranches(branch6.ID(), branch11.ID()) + assert.NoError(t, aggrBranchErr) + defer cachedAggrBranch13.Release() + aggrBranch13 := cachedAggrBranch13.Unwrap() + + { + conflicting, err := branchManager.BranchesConflicting(aggrBranch13.ID(), aggrBranch9.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 9 & 13 should be conflicting with each other") + + conflicting, err = branchManager.BranchesConflicting(aggrBranch13.ID(), aggrBranch8.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 8 & 13 should not be conflicting with each other") + + conflicting, err = branchManager.BranchesConflicting(aggrBranch13.ID(), aggrBranch10.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 10 & 13 should not be conflicting with each other") + } + + // aggr. branch 14 out of aggr. branch 10 and 13 + cachedAggrBranch14, aggrBranchErr := branchManager.AggregateBranches(aggrBranch10.ID(), aggrBranch13.ID()) + assert.NoError(t, aggrBranchErr) + defer cachedAggrBranch14.Release() + aggrBranch14 := cachedAggrBranch14.Unwrap() + + { + // aggr. branch 9 has parent branch 7 which conflicts with ancestor branch 6 of aggr. branch 14 + conflicting, err := branchManager.BranchesConflicting(aggrBranch14.ID(), aggrBranch9.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 14 & 9 should be conflicting with each other") + + // aggr. branch has ancestor branch 2 which conflicts with ancestor branch 3 of aggr. branch 14 + conflicting, err = branchManager.BranchesConflicting(aggrBranch14.ID(), aggrBranch8.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 14 & 8 should be conflicting with each other") + } + + // aggr. branch 15 out of branch 2, 7 and 12 + cachedAggrBranch15, aggrBranchErr := branchManager.AggregateBranches(branch2.ID(), branch7.ID(), branch12.ID()) + assert.NoError(t, aggrBranchErr) + defer cachedAggrBranch15.Release() + aggrBranch15 := cachedAggrBranch15.Unwrap() + + { + // aggr. branch 13 has parent branches 11 & 6 which conflicts which conflicts with ancestor branches 12 & 7 of aggr. branch 15 + conflicting, err := branchManager.BranchesConflicting(aggrBranch15.ID(), aggrBranch13.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 15 & 13 should be conflicting with each other") + + // aggr. branch 10 has parent branches 3 & 6 which conflicts with ancestor branches 2 & 7 of aggr. branch 15 + conflicting, err = branchManager.BranchesConflicting(aggrBranch15.ID(), aggrBranch10.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 15 & 10 should be conflicting with each other") + + // aggr. branch 8 has parent branch 6 which conflicts with ancestor branch 7 of aggr. branch 15 + conflicting, err = branchManager.BranchesConflicting(aggrBranch15.ID(), aggrBranch8.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 15 & 8 should be conflicting with each other") + } + + // aggr. branch 16 out of aggr. branches 15 and 9 + cachedAggrBranch16, aggrBranchErr := branchManager.AggregateBranches(aggrBranch15.ID(), aggrBranch9.ID()) + assert.NoError(t, aggrBranchErr) + defer cachedAggrBranch16.Release() + aggrBranch16 := cachedAggrBranch16.Unwrap() + + { + // sanity check + conflicting, err := branchManager.BranchesConflicting(aggrBranch16.ID(), aggrBranch9.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 16 & 9 should not be conflicting with each other") + + // sanity check + conflicting, err = branchManager.BranchesConflicting(aggrBranch16.ID(), branch7.ID()) + assert.NoError(t, err) + assert.False(t, conflicting, "aggr. branch 16 & 9 should not be conflicting with each other") + + conflicting, err = branchManager.BranchesConflicting(aggrBranch16.ID(), aggrBranch13.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 16 & 13 should be conflicting with each other") + + conflicting, err = branchManager.BranchesConflicting(aggrBranch16.ID(), aggrBranch14.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 16 & 14 should be conflicting with each other") + + conflicting, err = branchManager.BranchesConflicting(aggrBranch16.ID(), aggrBranch8.ID()) + assert.NoError(t, err) + assert.True(t, conflicting, "aggr. branch 16 & 8 should be conflicting with each other") + } + +} + +func TestBranchManager_SetBranchPreferred(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + event := newEventMock(t, branchManager) + defer event.DetachAll() + + cachedBranch2, _ := branchManager.Fork(BranchID{2}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch2.Release() + branch2 := cachedBranch2.Unwrap() + + cachedBranch3, _ := branchManager.Fork(BranchID{3}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch3.Release() + branch3 := cachedBranch3.Unwrap() + + assert.False(t, branch2.Preferred(), "branch 2 should not be preferred") + assert.False(t, branch2.Liked(), "branch 2 should not be liked") + assert.False(t, branch3.Preferred(), "branch 3 should not be preferred") + assert.False(t, branch3.Liked(), "branch 3 should not be liked") + + cachedBranch4, _ := branchManager.Fork(BranchID{4}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch4.Release() + branch4 := cachedBranch4.Unwrap() + + cachedBranch5, _ := branchManager.Fork(BranchID{5}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch5.Release() + branch5 := cachedBranch5.Unwrap() + + // lets assume branch 4 is preferred since its underlying transaction was longer + // solid than the avg. network delay before the conflicting transaction which created + // the conflict set was received + + event.Expect("BranchPreferred", branch4) + + modified, err := branchManager.SetBranchPreferred(branch4.ID(), true) + assert.NoError(t, err) + assert.True(t, modified) + + assert.True(t, branch4.Preferred(), "branch 4 should be preferred") + // is not liked because its parents aren't liked, respectively branch 2 + assert.False(t, branch4.Liked(), "branch 4 should not be liked") + assert.False(t, branch5.Preferred(), "branch 5 should not be preferred") + assert.False(t, branch5.Liked(), "branch 5 should not be liked") + + // now branch 2 becomes preferred via FPC, this causes branch 2 to be liked (since + // the master branch is liked) and its liked state propagates to branch 4 (but not branch 5) + + event.Expect("BranchPreferred", branch2) + event.Expect("BranchLiked", branch2) + event.Expect("BranchLiked", branch4) + + modified, err = branchManager.SetBranchPreferred(branch2.ID(), true) + assert.NoError(t, err) + assert.True(t, modified) + + assert.True(t, branch2.Liked(), "branch 2 should be liked") + assert.True(t, branch2.Preferred(), "branch 2 should be preferred") + assert.True(t, branch4.Liked(), "branch 4 should be liked") + assert.True(t, branch4.Preferred(), "branch 4 should still be preferred") + assert.False(t, branch5.Liked(), "branch 5 should not be liked") + assert.False(t, branch5.Preferred(), "branch 5 should not be preferred") + + // now the network decides that branch 5 is preferred (via FPC), thus branch 4 should lose its + // preferred and liked state and branch 5 should instead become preferred and liked + + event.Expect("BranchPreferred", branch5) + event.Expect("BranchLiked", branch5) + event.Expect("BranchUnpreferred", branch4) + event.Expect("BranchDisliked", branch4) + + modified, err = branchManager.SetBranchPreferred(branch5.ID(), true) + assert.NoError(t, err) + assert.True(t, modified) + + // sanity check for branch 2 state + assert.True(t, branch2.Liked(), "branch 2 should be liked") + assert.True(t, branch2.Preferred(), "branch 2 should be preferred") + + // check that branch 4 is disliked and not preferred + assert.False(t, branch4.Liked(), "branch 4 should be disliked") + assert.False(t, branch4.Preferred(), "branch 4 should not be preferred") + assert.True(t, branch5.Liked(), "branch 5 should be liked") + assert.True(t, branch5.Preferred(), "branch 5 should be preferred") + + // check that all event have been triggered + event.AssertExpectations(t) +} + +func TestBranchManager_SetBranchPreferred2(t *testing.T) { + branchManager := New(mapdb.NewMapDB()) + event := newEventMock(t, branchManager) + defer event.DetachAll() + + cachedBranch2, _ := branchManager.Fork(BranchID{2}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch2.Release() + branch2 := cachedBranch2.Unwrap() + + cachedBranch3, _ := branchManager.Fork(BranchID{3}, []BranchID{MasterBranchID}, []ConflictID{{0}}) + defer cachedBranch3.Release() + branch3 := cachedBranch3.Unwrap() + + cachedBranch4, _ := branchManager.Fork(BranchID{4}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch4.Release() + branch4 := cachedBranch4.Unwrap() + + cachedBranch5, _ := branchManager.Fork(BranchID{5}, []BranchID{branch2.ID()}, []ConflictID{{1}}) + defer cachedBranch5.Release() + branch5 := cachedBranch5.Unwrap() + + cachedBranch6, _ := branchManager.Fork(BranchID{6}, []BranchID{MasterBranchID}, []ConflictID{{2}}) + defer cachedBranch6.Release() + branch6 := cachedBranch6.Unwrap() + + cachedBranch7, _ := branchManager.Fork(BranchID{7}, []BranchID{MasterBranchID}, []ConflictID{{2}}) + defer cachedBranch7.Release() + branch7 := cachedBranch7.Unwrap() + + event.Expect("BranchPreferred", branch2) + event.Expect("BranchLiked", branch2) + event.Expect("BranchPreferred", branch6) + event.Expect("BranchLiked", branch6) + + // assume branch 2 preferred since solid longer than avg. network delay + modified, err := branchManager.SetBranchPreferred(branch2.ID(), true) + assert.NoError(t, err) + assert.True(t, modified) + + // assume branch 6 preferred since solid longer than avg. network delay + modified, err = branchManager.SetBranchPreferred(branch6.ID(), true) + assert.NoError(t, err) + assert.True(t, modified) + + { + assert.True(t, branch2.Liked(), "branch 2 should be liked") + assert.True(t, branch2.Preferred(), "branch 2 should be preferred") + assert.False(t, branch3.Liked(), "branch 3 should not be liked") + assert.False(t, branch3.Preferred(), "branch 3 should not be preferred") + assert.False(t, branch4.Liked(), "branch 4 should not be liked") + assert.False(t, branch4.Preferred(), "branch 4 should not be preferred") + assert.False(t, branch5.Liked(), "branch 5 should not be liked") + assert.False(t, branch5.Preferred(), "branch 5 should not be preferred") + + assert.True(t, branch6.Liked(), "branch 6 should be liked") + assert.True(t, branch6.Preferred(), "branch 6 should be preferred") + assert.False(t, branch7.Liked(), "branch 7 should not be liked") + assert.False(t, branch7.Preferred(), "branch 7 should not be preferred") + } + + // throw some aggregated branches into the mix + cachedAggrBranch8, err := branchManager.AggregateBranches(branch4.ID(), branch6.ID()) + assert.NoError(t, err) + defer cachedAggrBranch8.Release() + aggrBranch8 := cachedAggrBranch8.Unwrap() + + // should not be preferred because only 6 is is preferred but not 4 + assert.False(t, aggrBranch8.Liked(), "aggr. branch 8 should not be liked") + assert.False(t, aggrBranch8.Preferred(), "aggr. branch 8 should not be preferred") + + cachedAggrBranch9, err := branchManager.AggregateBranches(branch5.ID(), branch7.ID()) + assert.NoError(t, err) + defer cachedAggrBranch9.Release() + aggrBranch9 := cachedAggrBranch9.Unwrap() + + // branch 5 and 7 are neither liked or preferred + assert.False(t, aggrBranch9.Liked(), "aggr. branch 9 should not be liked") + assert.False(t, aggrBranch9.Preferred(), "aggr. branch 9 should not be preferred") + + // should not be preferred because only 6 is is preferred but not 3 + cachedAggrBranch10, err := branchManager.AggregateBranches(branch3.ID(), branch6.ID()) + assert.NoError(t, err) + defer cachedAggrBranch10.Release() + aggrBranch10 := cachedAggrBranch10.Unwrap() + + assert.False(t, aggrBranch10.Liked(), "aggr. branch 10 should not be liked") + assert.False(t, aggrBranch10.Preferred(), "aggr. branch 10 should not be preferred") + + // spawn off conflict branch 11 and 12 + cachedBranch11, _ := branchManager.Fork(BranchID{11}, []BranchID{aggrBranch8.ID()}, []ConflictID{{3}}) + defer cachedBranch11.Release() + branch11 := cachedBranch11.Unwrap() + + assert.False(t, branch11.Liked(), "aggr. branch 11 should not be liked") + assert.False(t, branch11.Preferred(), "aggr. branch 11 should not be preferred") + + cachedBranch12, _ := branchManager.Fork(BranchID{12}, []BranchID{aggrBranch8.ID()}, []ConflictID{{3}}) + defer cachedBranch12.Release() + branch12 := cachedBranch12.Unwrap() + + assert.False(t, branch12.Liked(), "aggr. branch 12 should not be liked") + assert.False(t, branch12.Preferred(), "aggr. branch 12 should not be preferred") + + cachedAggrBranch13, err := branchManager.AggregateBranches(branch4.ID(), branch12.ID()) + assert.NoError(t, err) + defer cachedAggrBranch13.Release() + aggrBranch13 := cachedAggrBranch13.Unwrap() + + assert.False(t, aggrBranch13.Liked(), "aggr. branch 13 should not be liked") + assert.False(t, aggrBranch13.Preferred(), "aggr. branch 13 should not be preferred") + + // now lets assume FPC finalized on branch 2, 6 and 4 to be preferred. + // branches 2 and 6 are already preferred but 4 is newly preferred. Branch 4 therefore + // should also become liked, since branch 2 of which it spawns off is liked too. + + // simulate branch 3 being not preferred from FPC vote + // this does not trigger any events as branch 3 was never preferred + modified, err = branchManager.SetBranchPreferred(branch3.ID(), false) + assert.NoError(t, err) + assert.False(t, modified) + // simulate branch 7 being not preferred from FPC vote + // this does not trigger any events as branch 7 was never preferred + modified, err = branchManager.SetBranchPreferred(branch7.ID(), false) + assert.NoError(t, err) + assert.False(t, modified) + + event.Expect("BranchPreferred", branch4) + event.Expect("BranchLiked", branch4) + event.Expect("BranchPreferred", aggrBranch8) + event.Expect("BranchLiked", aggrBranch8) + + // simulate branch 4 being preferred by FPC vote + modified, err = branchManager.SetBranchPreferred(branch4.ID(), true) + assert.NoError(t, err) + assert.True(t, modified) + assert.True(t, branch4.Liked(), "branch 4 should be liked") + assert.True(t, branch4.Preferred(), "branch 4 should be preferred") + + // this should cause aggr. branch 8 to also be preferred and liked, since branch 6 and 4 + // of which it spawns off are. + assert.True(t, aggrBranch8.Liked(), "aggr. branch 8 should be liked") + assert.True(t, aggrBranch8.Preferred(), "aggr. branch 8 should be preferred") + + // check that all event have been triggered + event.AssertExpectations(t) +} diff --git a/dapps/valuetransfers/packages/branchmanager/child_branch.go b/dapps/valuetransfers/packages/branchmanager/child_branch.go new file mode 100644 index 0000000000000000000000000000000000000000..10c1bfbf00cd146e93b31a3c7235d905e964d608 --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/child_branch.go @@ -0,0 +1,174 @@ +package branchmanager + +import ( + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" +) + +// ChildBranch represents the relationship between a Branch and its children. Since a Branch can have a potentially +// unbounded amount of child Branches, we store this as a separate k/v pair instead of a marshaled list of children +// inside the Branch. +type ChildBranch struct { + objectstorage.StorableObjectFlags + + parentID BranchID + childID BranchID +} + +// NewChildBranch is the constructor of the ChildBranch reference. +func NewChildBranch(parentID BranchID, childID BranchID) *ChildBranch { + return &ChildBranch{ + parentID: parentID, + childID: childID, + } +} + +// ChildBranchFromBytes unmarshals a ChildBranch from a sequence of bytes. +func ChildBranchFromBytes(bytes []byte, optionalTargetObject ...*ChildBranch) (result *ChildBranch, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseChildBranch(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ChildBranchFromStorageKey is a factory method that creates a new ChildBranch instance from a storage key of the +// objectstorage. It is used by the objectstorage, to create new instances of this entity. +func ChildBranchFromStorageKey(key []byte, optionalTargetObject ...*ChildBranch) (result *ChildBranch, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &ChildBranch{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to ChildBranchFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.parentID, err = ParseBranchID(marshalUtil); err != nil { + return + } + if result.childID, err = ParseBranchID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseChildBranch unmarshals a ChildBranch using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseChildBranch(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*ChildBranch) (result *ChildBranch, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return ChildBranchFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*ChildBranch) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ParentID returns the ID of the Branch that plays the role of the parent in this relationship. +func (childBranch *ChildBranch) ParentID() BranchID { + return childBranch.parentID +} + +// ChildID returns the ID of the Branch that plays the role of the child in this relationship. +func (childBranch *ChildBranch) ChildID() BranchID { + return childBranch.childID +} + +// ObjectStorageKey returns the bytes that are used a key when storing the Branch in an objectstorage. +func (childBranch ChildBranch) ObjectStorageKey() []byte { + return marshalutil.New(ConflictIDLength + BranchIDLength). + WriteBytes(childBranch.parentID.Bytes()). + WriteBytes(childBranch.childID.Bytes()). + Bytes() +} + +// ObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a marshaled +// ChildBranch. +func (childBranch ChildBranch) ObjectStorageValue() []byte { + return nil +} + +// UnmarshalObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a +// marshaled Branch. +func (childBranch ChildBranch) UnmarshalObjectStorageValue([]byte) (consumedBytes int, err error) { + return +} + +// Update is disabled but needs to be implemented to be compatible with the objectstorage. +func (childBranch ChildBranch) Update(objectstorage.StorableObject) { + panic("updates are disabled - use the setters") +} + +var _ objectstorage.StorableObject = &ChildBranch{} + +// CachedChildBranch is a wrapper for the generic CachedObject returned by the objectstorage that overrides the +// accessor methods, with a type-casted one. +type CachedChildBranch struct { + objectstorage.CachedObject +} + +// Retain marks this CachedObject to still be in use by the program. +func (cachedChildBranch *CachedChildBranch) Retain() *CachedChildBranch { + return &CachedChildBranch{cachedChildBranch.CachedObject.Retain()} +} + +// Unwrap is the type-casted equivalent of Get. It returns nil if the object does not exist. +func (cachedChildBranch *CachedChildBranch) Unwrap() *ChildBranch { + untypedObject := cachedChildBranch.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*ChildBranch) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject +} + +// Consume unwraps the CachedObject and passes a type-casted version to the consumer (if the object is not empty - it +// exists). It automatically releases the object when the consumer finishes. +func (cachedChildBranch *CachedChildBranch) Consume(consumer func(childBranch *ChildBranch), forceRelease ...bool) (consumed bool) { + return cachedChildBranch.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*ChildBranch)) + }, forceRelease...) +} + +// CachedChildBranches represents a collection of CachedChildBranches. +type CachedChildBranches []*CachedChildBranch + +// Consume iterates over the CachedObjects, unwraps them and passes a type-casted version to the consumer (if the object +// is not empty - it exists). It automatically releases the object when the consumer finishes. It returns true, if at +// least one object was consumed. +func (cachedChildBranches CachedChildBranches) Consume(consumer func(childBranch *ChildBranch)) (consumed bool) { + for _, cachedChildBranch := range cachedChildBranches { + consumed = cachedChildBranch.Consume(func(output *ChildBranch) { + consumer(output) + }) || consumed + } + + return +} + +// Release is a utility function that allows us to release all CachedObjects in the collection. +func (cachedChildBranches CachedChildBranches) Release(force ...bool) { + for _, cachedChildBranch := range cachedChildBranches { + cachedChildBranch.Release(force...) + } +} diff --git a/dapps/valuetransfers/packages/branchmanager/conflict.go b/dapps/valuetransfers/packages/branchmanager/conflict.go new file mode 100644 index 0000000000000000000000000000000000000000..f717aea91778b64868a59141ff562d45765226d0 --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/conflict.go @@ -0,0 +1,207 @@ +package branchmanager + +import ( + "sync" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" +) + +// Conflict represents a +type Conflict struct { + objectstorage.StorableObjectFlags + + id ConflictID + memberCount uint32 + + memberCountMutex sync.RWMutex +} + +// NewConflict is the constructor for new Conflicts. +func NewConflict(id ConflictID) *Conflict { + return &Conflict{ + id: id, + } +} + +// ConflictFromBytes unmarshals a Conflict from a sequence of bytes. +func ConflictFromBytes(bytes []byte, optionalTargetObject ...*Conflict) (result *Conflict, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseConflict(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ConflictFromStorageKey is a factory method that creates a new Conflict instance from a storage key of the +// objectstorage. It is used by the objectstorage, to create new instances of this entity. +func ConflictFromStorageKey(key []byte, optionalTargetObject ...*Conflict) (result *Conflict, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Conflict{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to ConflictFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.id, err = ParseConflictID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseConflict unmarshals a Conflict using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseConflict(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Conflict) (result *Conflict, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return ConflictFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*Conflict) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ID returns the identifier of this Conflict. +func (conflict *Conflict) ID() ConflictID { + return conflict.id +} + +// MemberCount returns the amount of Branches that are part of this Conflict. +func (conflict *Conflict) MemberCount() int { + conflict.memberCountMutex.RLock() + defer conflict.memberCountMutex.RLock() + + return int(conflict.memberCount) +} + +// IncreaseMemberCount offers a thread safe way to increase the MemberCount property. +func (conflict *Conflict) IncreaseMemberCount(optionalDelta ...int) int { + delta := uint32(1) + if len(optionalDelta) >= 1 { + delta = uint32(optionalDelta[0]) + } + + conflict.memberCountMutex.Lock() + defer conflict.memberCountMutex.Unlock() + + conflict.memberCount = conflict.memberCount + delta + conflict.SetModified() + + return int(conflict.memberCount) +} + +// DecreaseMemberCount offers a thread safe way to decrease the MemberCount property. +func (conflict *Conflict) DecreaseMemberCount(optionalDelta ...int) (newMemberCount int) { + delta := uint32(1) + if len(optionalDelta) >= 1 { + delta = uint32(optionalDelta[0]) + } + + conflict.memberCountMutex.Lock() + defer conflict.memberCountMutex.Unlock() + + conflict.memberCount = conflict.memberCount - delta + conflict.SetModified() + newMemberCount = int(conflict.memberCount) + + return +} + +// Bytes returns a marshaled version of this Conflict. +func (conflict *Conflict) Bytes() []byte { + return marshalutil.New(). + WriteBytes(conflict.ObjectStorageKey()). + WriteBytes(conflict.ObjectStorageValue()). + Bytes() +} + +// String returns a human readable version of this Conflict (for debug purposes). +func (conflict *Conflict) String() string { + return stringify.Struct("Conflict", + stringify.StructField("id", conflict.id), + stringify.StructField("memberCount", conflict.MemberCount()), + ) +} + +// ObjectStorageKey returns the bytes that are used a key when storing the Branch in an objectstorage. +func (conflict *Conflict) ObjectStorageKey() []byte { + return conflict.id.Bytes() +} + +// ObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a marshaled +// Branch. +func (conflict *Conflict) ObjectStorageValue() []byte { + return marshalutil.New(marshalutil.UINT32_SIZE). + WriteUint32(uint32(conflict.MemberCount())). + Bytes() +} + +// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. +func (conflict *Conflict) UnmarshalObjectStorageValue(valueBytes []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(valueBytes) + conflict.memberCount, err = marshalUtil.ReadUint32() + if err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Update is disabled but needs to be implemented to be compatible with the objectstorage. +func (conflict *Conflict) Update(other objectstorage.StorableObject) { + panic("updates are disabled - use the setters") +} + +var _ objectstorage.StorableObject = &Conflict{} + +// CachedConflict is a wrapper for the generic CachedObject returned by the objectstorage, that overrides the accessor +// methods, with a type-casted one. +type CachedConflict struct { + objectstorage.CachedObject +} + +// Retain marks this CachedObject to still be in use by the program. +func (cachedConflict *CachedConflict) Retain() *CachedConflict { + return &CachedConflict{cachedConflict.CachedObject.Retain()} +} + +// Unwrap is the type-casted equivalent of Get. It returns nil if the object does not exist. +func (cachedConflict *CachedConflict) Unwrap() *Conflict { + untypedObject := cachedConflict.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*Conflict) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject +} + +// Consume unwraps the CachedObject and passes a type-casted version to the consumer (if the object is not empty - it +// exists). It automatically releases the object when the consumer finishes. +func (cachedConflict *CachedConflict) Consume(consumer func(conflict *Conflict), forceRelease ...bool) (consumed bool) { + return cachedConflict.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Conflict)) + }, forceRelease...) +} diff --git a/dapps/valuetransfers/packages/branchmanager/conflict_id.go b/dapps/valuetransfers/packages/branchmanager/conflict_id.go new file mode 100644 index 0000000000000000000000000000000000000000..5b5db0da3d45a5e5fb99543f6543d86acc1251c1 --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/conflict_id.go @@ -0,0 +1,21 @@ +package branchmanager + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" +) + +// ConflictID represents an identifier of a Conflict. Since conflicts, are created by multiple transactions spending the +// same Output, the ConflictID is simply an alias for the conflicting OutputID. +type ConflictID = transaction.OutputID + +var ( + // ParseConflictID is a wrapper for simplified unmarshaling of Ids from a byte stream using the marshalUtil package. + ParseConflictID = transaction.ParseOutputID + + // ConflictIDFromBytes unmarshals a ConflictID from a sequence of bytes. + ConflictIDFromBytes = transaction.OutputIDFromBytes +) + +// ConflictIDLength encodes the length of a Conflict identifier - since Conflicts get created by transactions spending +// the same Output, it has the same length as an OutputID. +const ConflictIDLength = transaction.OutputIDLength diff --git a/dapps/valuetransfers/packages/branchmanager/conflict_member.go b/dapps/valuetransfers/packages/branchmanager/conflict_member.go new file mode 100644 index 0000000000000000000000000000000000000000..4d7fb663a03e17d478860a88f7e66a5d0b31e827 --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/conflict_member.go @@ -0,0 +1,174 @@ +package branchmanager + +import ( + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" +) + +// ConflictMember represents the relationship between a Conflict and its Branches. Since a Conflict can have a +// potentially unbounded amount of conflicting Consumers, we store this as a separate k/v pair instead of a marshaled +// ist of members inside the Branch. +type ConflictMember struct { + objectstorage.StorableObjectFlags + + conflictID ConflictID + branchID BranchID +} + +// NewConflictMember is the constructor of the ConflictMember reference. +func NewConflictMember(conflictID ConflictID, branchID BranchID) *ConflictMember { + return &ConflictMember{ + conflictID: conflictID, + branchID: branchID, + } +} + +// ConflictMemberFromBytes unmarshals a ConflictMember from a sequence of bytes. +func ConflictMemberFromBytes(bytes []byte, optionalTargetObject ...*ConflictMember) (result *ConflictMember, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseConflictMember(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ConflictMemberFromStorageKey is a factory method that creates a new ConflictMember instance from a storage key of the +// objectstorage. It is used by the objectstorage, to create new instances of this entity. +func ConflictMemberFromStorageKey(key []byte, optionalTargetObject ...*ConflictMember) (result *ConflictMember, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &ConflictMember{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to ConflictMemberFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.conflictID, err = ParseConflictID(marshalUtil); err != nil { + return + } + if result.branchID, err = ParseBranchID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseConflictMember unmarshals a ConflictMember using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseConflictMember(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*ConflictMember) (result *ConflictMember, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return ConflictMemberFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*ConflictMember) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ConflictID returns the identifier of the Conflict that this conflictMember belongs to. +func (conflictMember *ConflictMember) ConflictID() ConflictID { + return conflictMember.conflictID +} + +// BranchID returns the identifier of the Branch that this conflictMember references. +func (conflictMember *ConflictMember) BranchID() BranchID { + return conflictMember.branchID +} + +// ObjectStorageKey returns the bytes that are used a key when storing the Branch in an objectstorage. +func (conflictMember ConflictMember) ObjectStorageKey() []byte { + return marshalutil.New(ConflictIDLength + BranchIDLength). + WriteBytes(conflictMember.conflictID.Bytes()). + WriteBytes(conflictMember.branchID.Bytes()). + Bytes() +} + +// ObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a marshaled +// ConflictMember. +func (conflictMember ConflictMember) ObjectStorageValue() []byte { + return nil +} + +// UnmarshalObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a +// marshaled Branch. +func (conflictMember ConflictMember) UnmarshalObjectStorageValue([]byte) (consumedBytes int, err error) { + return +} + +// Update is disabled but needs to be implemented to be compatible with the objectstorage. +func (conflictMember ConflictMember) Update(other objectstorage.StorableObject) { + panic("updates are disabled - use the setters") +} + +var _ objectstorage.StorableObject = &ConflictMember{} + +// CachedConflictMember is a wrapper for the generic CachedObject returned by the objectstorage that overrides the +// accessor methods, with a type-casted one. +type CachedConflictMember struct { + objectstorage.CachedObject +} + +// Retain marks this CachedObject to still be in use by the program. +func (cachedConflictMember *CachedConflictMember) Retain() *CachedConflictMember { + return &CachedConflictMember{cachedConflictMember.CachedObject.Retain()} +} + +// Unwrap is the type-casted equivalent of Get. It returns nil if the object does not exist. +func (cachedConflictMember *CachedConflictMember) Unwrap() *ConflictMember { + untypedObject := cachedConflictMember.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*ConflictMember) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject +} + +// Consume unwraps the CachedObject and passes a type-casted version to the consumer (if the object is not empty - it +// exists). It automatically releases the object when the consumer finishes. +func (cachedConflictMember *CachedConflictMember) Consume(consumer func(conflictMember *ConflictMember), forceRelease ...bool) (consumed bool) { + return cachedConflictMember.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*ConflictMember)) + }, forceRelease...) +} + +// CachedConflictMembers represents a collection of CachedConflictMembers. +type CachedConflictMembers []*CachedConflictMember + +// Consume iterates over the CachedObjects, unwraps them and passes a type-casted version to the consumer (if the object +// is not empty - it exists). It automatically releases the object when the consumer finishes. It returns true, if at +// least one object was consumed. +func (cachedConflictMembers CachedConflictMembers) Consume(consumer func(conflictMember *ConflictMember)) (consumed bool) { + for _, cachedConflictMember := range cachedConflictMembers { + consumed = cachedConflictMember.Consume(func(output *ConflictMember) { + consumer(output) + }) || consumed + } + + return +} + +// Release is a utility function that allows us to release all CachedObjects in the collection. +func (cachedConflictMembers CachedConflictMembers) Release(force ...bool) { + for _, cachedConflictMember := range cachedConflictMembers { + cachedConflictMember.Release(force...) + } +} diff --git a/dapps/valuetransfers/packages/branchmanager/events.go b/dapps/valuetransfers/packages/branchmanager/events.go new file mode 100644 index 0000000000000000000000000000000000000000..f9615e209aaeb205624ed1eeb1f533c4019e601a --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/events.go @@ -0,0 +1,34 @@ +package branchmanager + +import ( + "github.com/iotaledger/hive.go/events" +) + +// Events is a container for the different kind of events of the BranchManager. +type Events struct { + // BranchPreferred gets triggered whenever a Branch becomes preferred that was not preferred before. + BranchPreferred *events.Event + + // BranchUnpreferred gets triggered whenever a Branch becomes unpreferred that was preferred before. + BranchUnpreferred *events.Event + + // BranchLiked gets triggered whenever a Branch becomes liked that was not liked before. + BranchLiked *events.Event + + // BranchLiked gets triggered whenever a Branch becomes preferred that was not preferred before. + BranchDisliked *events.Event + + // BranchFinalized gets triggered when a decision on a Branch is finalized and there will be no further state + // changes regarding its preferred state. + BranchFinalized *events.Event + + // BranchConfirmed gets triggered whenever a Branch becomes confirmed that was not confirmed before. + BranchConfirmed *events.Event + + // BranchRejected gets triggered whenever a Branch becomes rejected that was not rejected before. + BranchRejected *events.Event +} + +func branchCaller(handler interface{}, params ...interface{}) { + handler.(func(branch *CachedBranch))(params[0].(*CachedBranch).Retain()) +} diff --git a/dapps/valuetransfers/packages/branchmanager/imgs/sample_tree.png b/dapps/valuetransfers/packages/branchmanager/imgs/sample_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..88218b1b8b7aa7b675e57c33c9e3f318a2022ffc Binary files /dev/null and b/dapps/valuetransfers/packages/branchmanager/imgs/sample_tree.png differ diff --git a/dapps/valuetransfers/packages/branchmanager/imgs/testconflictdetection.PNG b/dapps/valuetransfers/packages/branchmanager/imgs/testconflictdetection.PNG new file mode 100644 index 0000000000000000000000000000000000000000..9da013e5b4caa42306c2c856386f7ee4a06bc167 Binary files /dev/null and b/dapps/valuetransfers/packages/branchmanager/imgs/testconflictdetection.PNG differ diff --git a/dapps/valuetransfers/packages/branchmanager/imgs/testelevation.PNG b/dapps/valuetransfers/packages/branchmanager/imgs/testelevation.PNG new file mode 100644 index 0000000000000000000000000000000000000000..b54ecfc5098dfcee316ff693b5cfa8bebc834d56 Binary files /dev/null and b/dapps/valuetransfers/packages/branchmanager/imgs/testelevation.PNG differ diff --git a/dapps/valuetransfers/packages/branchmanager/imgs/testlikepropagation.PNG b/dapps/valuetransfers/packages/branchmanager/imgs/testlikepropagation.PNG new file mode 100644 index 0000000000000000000000000000000000000000..c8aef98a87366018d16778561828080256c7b58d Binary files /dev/null and b/dapps/valuetransfers/packages/branchmanager/imgs/testlikepropagation.PNG differ diff --git a/dapps/valuetransfers/packages/branchmanager/objectstorage.go b/dapps/valuetransfers/packages/branchmanager/objectstorage.go new file mode 100644 index 0000000000000000000000000000000000000000..c9cbfe4abe13858e9f33906a27d86cbe63afc10e --- /dev/null +++ b/dapps/valuetransfers/packages/branchmanager/objectstorage.go @@ -0,0 +1,65 @@ +package branchmanager + +import ( + "time" + + "github.com/iotaledger/hive.go/objectstorage" +) + +const ( + // the following values are a list of prefixes defined as an enum + _ byte = iota + + // prefixes used for the objectstorage + osBranch + osChildBranch + osConflict + osConflictMember + + cacheTime = 30 * time.Second +) + +var ( + osLeakDetectionOption = objectstorage.LeakDetectionEnabled(false, objectstorage.LeakDetectionOptions{ + MaxConsumersPerObject: 10, + MaxConsumerHoldTime: 10 * time.Second, + }) + + osBranchOptions = []objectstorage.Option{ + objectstorage.CacheTime(cacheTime), + osLeakDetectionOption, + } + + osChildBranchOptions = []objectstorage.Option{ + objectstorage.CacheTime(cacheTime), + objectstorage.PartitionKey(BranchIDLength, BranchIDLength), + osLeakDetectionOption, + } + + osConflictOptions = []objectstorage.Option{ + objectstorage.CacheTime(cacheTime), + osLeakDetectionOption, + } + + osConflictMemberOptions = []objectstorage.Option{ + objectstorage.CacheTime(cacheTime), + objectstorage.PartitionKey(ConflictIDLength, BranchIDLength), + osLeakDetectionOption, + } +) + +func osBranchFactory(key []byte) (objectstorage.StorableObject, int, error) { + return BranchFromStorageKey(key) +} + +func osChildBranchFactory(key []byte) (objectstorage.StorableObject, int, error) { + return ChildBranchFromStorageKey(key) +} + +func osConflictFactory(key []byte) (objectstorage.StorableObject, int, error) { + return ConflictFromStorageKey(key) +} + +func osConflictMemberFactory(key []byte) (objectstorage.StorableObject, int, error) { + return ConflictMemberFromStorageKey(key) +} diff --git a/dapps/valuetransfers/packages/consensus/fcob.go b/dapps/valuetransfers/packages/consensus/fcob.go new file mode 100644 index 0000000000000000000000000000000000000000..b8a2925bdb4130375e22c408b3a674095e1c5ac8 --- /dev/null +++ b/dapps/valuetransfers/packages/consensus/fcob.go @@ -0,0 +1,171 @@ +package consensus + +import ( + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/hive.go/events" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/packages/vote" +) + +// FCOB defines the "Fast Consensus of Barcelona" rules that are used to form the initial opinions of nodes. It uses a +// local modifier based approach to reach approximate consensus within the network by waiting 1 network delay before +// setting a transaction to preferred (if it didnt see a conflict) and another network delay to set it to finalized (if +// it still didn't see a conflict). +type FCOB struct { + Events *FCOBEvents + + tangle *tangle.Tangle + averageNetworkDelay time.Duration +} + +// NewFCOB is the constructor for an FCOB consensus instance. It automatically attaches to the passed in Tangle and +// calls the corresponding Events if it needs to trigger a vote. +func NewFCOB(tangle *tangle.Tangle, averageNetworkDelay time.Duration) (fcob *FCOB) { + fcob = &FCOB{ + tangle: tangle, + averageNetworkDelay: averageNetworkDelay, + Events: &FCOBEvents{ + Error: events.NewEvent(events.ErrorCaller), + Vote: events.NewEvent(voteEvent), + }, + } + + // setup behavior of package instances + tangle.Events.TransactionBooked.Attach(events.NewClosure(fcob.onTransactionBooked)) + tangle.Events.Fork.Attach(events.NewClosure(fcob.onFork)) + + return +} + +// ProcessVoteResult allows an external voter to hand in the results of the voting process. +func (fcob *FCOB) ProcessVoteResult(ev *vote.OpinionEvent) { + transactionID, err := transaction.IDFromBase58(ev.ID) + if err != nil { + fcob.Events.Error.Trigger(err) + + return + } + + if _, err := fcob.tangle.SetTransactionPreferred(transactionID, ev.Opinion == vote.Like); err != nil { + fcob.Events.Error.Trigger(err) + } + + if _, err := fcob.tangle.SetTransactionFinalized(transactionID); err != nil { + fcob.Events.Error.Trigger(err) + } +} + +// onTransactionBooked analyzes the transaction that was booked by the Tangle and initiates the FCOB rules if it is not +// conflicting. If it is conflicting and a decision is still pending we trigger a voting process. +func (fcob *FCOB) onTransactionBooked(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *tangle.CachedTransactionMetadata, decisionPending bool) { + defer cachedTransaction.Release() + + cachedTransactionMetadata.Consume(func(transactionMetadata *tangle.TransactionMetadata) { + if transactionMetadata.Conflicting() { + // abort if the previous consumers where finalized already + if !decisionPending { + return + } + + fcob.Events.Vote.Trigger(transactionMetadata.BranchID().String(), vote.Dislike) + + return + } + + fcob.scheduleSetPreferred(cachedTransactionMetadata.Retain()) + }) +} + +// scheduleSetPreferred schedules the setPreferred logic after 1 network delay. +func (fcob *FCOB) scheduleSetPreferred(cachedTransactionMetadata *tangle.CachedTransactionMetadata) { + if fcob.averageNetworkDelay == 0 { + fcob.setPreferred(cachedTransactionMetadata) + } else { + time.AfterFunc(fcob.averageNetworkDelay, func() { + fcob.setPreferred(cachedTransactionMetadata) + }) + } +} + +// setPreferred sets the Transaction to preferred if it is not conflicting. +func (fcob *FCOB) setPreferred(cachedTransactionMetadata *tangle.CachedTransactionMetadata) { + cachedTransactionMetadata.Consume(func(transactionMetadata *tangle.TransactionMetadata) { + if transactionMetadata.Conflicting() { + return + } + + modified, err := fcob.tangle.SetTransactionPreferred(transactionMetadata.ID(), true) + if err != nil { + fcob.Events.Error.Trigger(err) + + return + } + + if modified { + fcob.scheduleSetFinalized(cachedTransactionMetadata.Retain()) + } + }) +} + +// scheduleSetFinalized schedules the setFinalized logic after 2 network delays. +// Note: it is 2 network delays because this function gets triggered at the end of the first delay that sets a +// Transaction to preferred (see setPreferred). +func (fcob *FCOB) scheduleSetFinalized(cachedTransactionMetadata *tangle.CachedTransactionMetadata) { + if fcob.averageNetworkDelay == 0 { + fcob.setFinalized(cachedTransactionMetadata) + } else { + time.AfterFunc(fcob.averageNetworkDelay, func() { + fcob.setFinalized(cachedTransactionMetadata) + }) + } +} + +// setFinalized sets the Transaction to finalized if it is not conflicting. +func (fcob *FCOB) setFinalized(cachedTransactionMetadata *tangle.CachedTransactionMetadata) { + cachedTransactionMetadata.Consume(func(transactionMetadata *tangle.TransactionMetadata) { + if transactionMetadata.Conflicting() { + return + } + + if _, err := fcob.tangle.SetTransactionFinalized(transactionMetadata.ID()); err != nil { + fcob.Events.Error.Trigger(err) + } + }) +} + +// onFork triggers a voting process whenever a Transaction gets forked into a new Branch. The initial opinion is derived +// from the preferred flag that was set using the FCOB rule. +func (fcob *FCOB) onFork(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *tangle.CachedTransactionMetadata, cachedTargetBranch *branchmanager.CachedBranch, conflictingInputs []transaction.OutputID) { + defer cachedTransaction.Release() + defer cachedTransactionMetadata.Release() + defer cachedTargetBranch.Release() + + transactionMetadata := cachedTransactionMetadata.Unwrap() + if transactionMetadata == nil { + return + } + + switch transactionMetadata.Preferred() { + case true: + fcob.Events.Vote.Trigger(transactionMetadata.ID().String(), vote.Like) + case false: + fcob.Events.Vote.Trigger(transactionMetadata.ID().String(), vote.Dislike) + } +} + +// FCOBEvents acts as a dictionary for events of an FCOB instance. +type FCOBEvents struct { + // Error gets called when FCOB faces an error. + Error *events.Event + + // Vote gets called when FCOB needs to vote on a transaction. + Vote *events.Event +} + +func voteEvent(handler interface{}, params ...interface{}) { + handler.(func(id string, initOpn vote.Opinion))(params[0].(string), params[1].(vote.Opinion)) +} diff --git a/dapps/valuetransfers/packages/payload/id.go b/dapps/valuetransfers/packages/payload/id.go new file mode 100644 index 0000000000000000000000000000000000000000..7b901ff92440e97dad81b5790e4c37edc98720fb --- /dev/null +++ b/dapps/valuetransfers/packages/payload/id.go @@ -0,0 +1,103 @@ +package payload + +import ( + "crypto/rand" + "fmt" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/mr-tron/base58" +) + +// ID represents the hash of a payload that is used to identify the given payload. +type ID [IDLength]byte + +// NewID creates a payload id from a base58 encoded string. +func NewID(base58EncodedString string) (result ID, err error) { + bytes, err := base58.Decode(base58EncodedString) + if err != nil { + return + } + + if len(bytes) != IDLength { + err = fmt.Errorf("length of base58 formatted payload id is wrong") + + return + } + + copy(result[:], bytes) + + return +} + +// ParseID is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. +func ParseID(marshalUtil *marshalutil.MarshalUtil) (ID, error) { + id, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return IDFromBytes(data) }) + if err != nil { + return ID{}, err + } + + return id.(ID), nil +} + +// IDFromBytes unmarshals a payload id from a sequence of bytes. +// It either creates a new payload id or fills the optionally provided object with the parsed information. +func IDFromBytes(bytes []byte, optionalTargetObject ...*ID) (result ID, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + var targetObject *ID + switch len(optionalTargetObject) { + case 0: + targetObject = &result + case 1: + targetObject = optionalTargetObject[0] + default: + panic("too many arguments in call to IDFromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read id from bytes + idBytes, err := marshalUtil.ReadBytes(IDLength) + if err != nil { + return + } + copy(targetObject[:], idBytes) + + // copy result if we have provided a target object + result = *targetObject + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// RandomID creates a random payload id which can for example be used in unit tests. +func RandomID() (id ID) { + // generate a random sequence of bytes + idBytes := make([]byte, IDLength) + if _, err := rand.Read(idBytes); err != nil { + panic(err) + } + + // copy the generated bytes into the result + copy(id[:], idBytes) + + return +} + +// String returns a base58 encoded version of the payload id. +func (id ID) String() string { + return base58.Encode(id[:]) +} + +// Bytes returns a marshaled version of this ID. +func (id ID) Bytes() []byte { + return id[:] +} + +// GenesisID contains the zero value of this ID which represents the genesis. +var GenesisID ID + +// IDLength defined the amount of bytes in a payload id (32 bytes hash value). +const IDLength = 32 diff --git a/dapps/valuetransfers/packages/payload/id_test.go b/dapps/valuetransfers/packages/payload/id_test.go new file mode 100644 index 0000000000000000000000000000000000000000..3a3558c293462833d5868ba66f6e1aa25f6d63fa --- /dev/null +++ b/dapps/valuetransfers/packages/payload/id_test.go @@ -0,0 +1,26 @@ +package payload + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test(t *testing.T) { + // create variable for id + sourceID, err := NewID("4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM") + if err != nil { + panic(err) + } + + // read serialized id into both variables + var restoredIDPointer ID + restoredIDValue, _, err := IDFromBytes(sourceID.Bytes(), &restoredIDPointer) + if err != nil { + panic(err) + } + + // check if both variables give the same result + assert.Equal(t, sourceID, restoredIDValue) + assert.Equal(t, sourceID, restoredIDPointer) +} diff --git a/dapps/valuetransfers/packages/payload/payload.go b/dapps/valuetransfers/packages/payload/payload.go new file mode 100644 index 0000000000000000000000000000000000000000..7ad1ffe3ef63f6b258c0f9b8641ba49bb26f6b6b --- /dev/null +++ b/dapps/valuetransfers/packages/payload/payload.go @@ -0,0 +1,324 @@ +package payload + +import ( + "sync" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" + "golang.org/x/crypto/blake2b" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +const ( + // ObjectName defines the name of the value object. + ObjectName = "value" +) + +// Payload represents the entity that forms the Tangle by referencing other Payloads using their trunk and branch. +// A Payload contains a transaction and defines, where in the Tangle a transaction is attached. +type Payload struct { + objectstorage.StorableObjectFlags + + id *ID + idMutex sync.RWMutex + + // TODO: rename to parents + trunkPayloadID ID + branchPayloadID ID + transaction *transaction.Transaction + bytes []byte + bytesMutex sync.RWMutex +} + +// New is the constructor of a Payload and creates a new Payload object from the given details. +func New(trunkPayloadID, branchPayloadID ID, valueTransfer *transaction.Transaction) *Payload { + return &Payload{ + trunkPayloadID: trunkPayloadID, + branchPayloadID: branchPayloadID, + transaction: valueTransfer, + } +} + +// FromBytes parses the marshaled version of a Payload into an object. +// It either returns a new Payload or fills an optionally provided Payload with the parsed information. +func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = Parse(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// FromStorageKey is a factory method that creates a new Payload instance from a storage key of the objectstorage. +// It is used by the objectstorage, to create new instances of this entity. +func FromStorageKey(key []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Payload{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to MissingPayloadFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + payloadID, idErr := ParseID(marshalUtil) + if idErr != nil { + err = idErr + + return + } + result.id = &payloadID + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Parse unmarshals a Payload using the given marshalUtil (for easier marshaling/unmarshaling). +func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Payload) (result *Payload, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Payload{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to Parse") + } + + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ID returns the identifier if the Payload. +func (payload *Payload) ID() ID { + // acquire lock for reading id + payload.idMutex.RLock() + + // return if id has been calculated already + if payload.id != nil { + defer payload.idMutex.RUnlock() + + return *payload.id + } + + // switch to write lock + payload.idMutex.RUnlock() + payload.idMutex.Lock() + defer payload.idMutex.Unlock() + + // return if id has been calculated in the mean time + if payload.id != nil { + return *payload.id + } + + // otherwise calculate the id + marshalUtil := marshalutil.New(IDLength + IDLength + transaction.IDLength) + marshalUtil.WriteBytes(payload.trunkPayloadID.Bytes()) + marshalUtil.WriteBytes(payload.branchPayloadID.Bytes()) + marshalUtil.WriteBytes(payload.Transaction().ID().Bytes()) + + var id ID = blake2b.Sum256(marshalUtil.Bytes()) + payload.id = &id + + return id +} + +// TrunkID returns the first Payload that is referenced by this Payload. +func (payload *Payload) TrunkID() ID { + return payload.trunkPayloadID +} + +// BranchID returns the second Payload that is referenced by this Payload. +func (payload *Payload) BranchID() ID { + return payload.branchPayloadID +} + +// Transaction returns the Transaction that is being attached in this Payload. +func (payload *Payload) Transaction() *transaction.Transaction { + return payload.transaction +} + +// Bytes returns a marshaled version of this Payload. +func (payload *Payload) Bytes() []byte { + return payload.ObjectStorageValue() +} + +func (payload *Payload) String() string { + return stringify.Struct("Payload", + stringify.StructField("id", payload.ID()), + stringify.StructField("trunk", payload.TrunkID()), + stringify.StructField("branch", payload.BranchID()), + stringify.StructField("transfer", payload.Transaction()), + ) +} + +// region Payload implementation /////////////////////////////////////////////////////////////////////////////////////// + +// Type represents the identifier which addresses the value Payload type. +const Type = payload.Type(1) + +// Type returns the type of the Payload. +func (payload *Payload) Type() payload.Type { + return Type +} + +// ObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a marshaled +// Branch. +func (payload *Payload) ObjectStorageValue() (bytes []byte) { + // acquire lock for reading bytes + payload.bytesMutex.RLock() + + // return if bytes have been determined already + if bytes = payload.bytes; bytes != nil { + defer payload.bytesMutex.RUnlock() + + return + } + + // switch to write lock + payload.bytesMutex.RUnlock() + payload.bytesMutex.Lock() + defer payload.bytesMutex.Unlock() + + // return if bytes have been determined in the mean time + if bytes = payload.bytes; bytes != nil { + return + } + + // retrieve bytes of transfer + transferBytes := payload.Transaction().ObjectStorageValue() + + // marshal fields + payloadLength := IDLength + IDLength + len(transferBytes) + marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + payloadLength) + marshalUtil.WriteUint32(Type) + marshalUtil.WriteUint32(uint32(payloadLength)) + marshalUtil.WriteBytes(payload.trunkPayloadID.Bytes()) + marshalUtil.WriteBytes(payload.branchPayloadID.Bytes()) + marshalUtil.WriteBytes(transferBytes) + bytes = marshalUtil.Bytes() + + // store result + payload.bytes = bytes + + return +} + +// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. +func (payload *Payload) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + + // read information that are required to identify the payload from the outside + _, err = marshalUtil.ReadUint32() + if err != nil { + return + } + _, err = marshalUtil.ReadUint32() + if err != nil { + return + } + + // parse trunk payload id + if payload.trunkPayloadID, err = ParseID(marshalUtil); err != nil { + return + } + if payload.branchPayloadID, err = ParseID(marshalUtil); err != nil { + return + } + if payload.transaction, err = transaction.Parse(marshalUtil); err != nil { + return + } + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + // store bytes, so we don't have to marshal manually + payload.bytes = make([]byte, consumedBytes) + copy(payload.bytes, data[:consumedBytes]) + + return +} + +// Unmarshal unmarshals a given slice of bytes and fills the object with the. +func (payload *Payload) Unmarshal(data []byte) (err error) { + _, _, err = FromBytes(data, payload) + + return +} + +func init() { + payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) { + payload, _, err = FromBytes(data) + + return + }) +} + +// define contract (ensure that the struct fulfills the corresponding interface) +var _ payload.Payload = &Payload{} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// region StorableObject implementation //////////////////////////////////////////////////////////////////////////////// + +// ObjectStorageKey returns the bytes that are used a key when storing the Branch in an objectstorage. +func (payload *Payload) ObjectStorageKey() []byte { + return payload.ID().Bytes() +} + +// Update is disabled but needs to be implemented to be compatible with the objectstorage. +func (payload *Payload) Update(other objectstorage.StorableObject) { + panic("a Payload should never be updated") +} + +// define contract (ensure that the struct fulfills the corresponding interface) +var _ objectstorage.StorableObject = &Payload{} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// CachedPayload is a wrapper for the object storage, that takes care of type casting the managed objects. +// Since go does not have generics (yet), the object storage works based on the generic "interface{}" type, which means +// that we have to regularly type cast the returned objects, to match the expected type. To reduce the burden of +// manually managing these type, we create a wrapper that does this for us. This way, we can consistently handle the +// specialized types of CachedObjects, without having to manually type cast over and over again. +type CachedPayload struct { + objectstorage.CachedObject +} + +// Retain wraps the underlying method to return a new "wrapped object". +func (cachedPayload *CachedPayload) Retain() *CachedPayload { + return &CachedPayload{cachedPayload.CachedObject.Retain()} +} + +// Consume wraps the underlying method to return the correctly typed objects in the callback. +func (cachedPayload *CachedPayload) Consume(consumer func(payload *Payload)) bool { + return cachedPayload.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Payload)) + }) +} + +// Unwrap provides a way to "Get" a type casted version of the underlying object. +func (cachedPayload *CachedPayload) Unwrap() *Payload { + untypedTransaction := cachedPayload.Get() + if untypedTransaction == nil { + return nil + } + + typeCastedTransaction := untypedTransaction.(*Payload) + if typeCastedTransaction == nil || typeCastedTransaction.IsDeleted() { + return nil + } + + return typeCastedTransaction +} diff --git a/dapps/valuetransfers/packages/payload/payload_test.go b/dapps/valuetransfers/packages/payload/payload_test.go new file mode 100644 index 0000000000000000000000000000000000000000..743e7310a0c3612e7f212df0834bdc5979230297 --- /dev/null +++ b/dapps/valuetransfers/packages/payload/payload_test.go @@ -0,0 +1,126 @@ +package payload + +import ( + "fmt" + "testing" + "time" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +func ExamplePayload() { + // 1. create value transfer (user provides this) + valueTransfer := transaction.New( + // inputs + transaction.NewInputs( + transaction.NewOutputID(address.Random(), transaction.RandomID()), + transaction.NewOutputID(address.Random(), transaction.RandomID()), + ), + + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1337), + }, + }), + ) + + // 2. create value payload (the ontology creates this and wraps the user provided transfer accordingly) + valuePayload := New( + // trunk in "value transfer ontology" (filled by ontology tipSelector) + GenesisID, + + // branch in "value transfer ontology" (filled by ontology tipSelector) + GenesisID, + + // value transfer + valueTransfer, + ) + + // 3. build actual transaction (the base layer creates this and wraps the ontology provided payload) + tx := message.New( + // trunk in "network tangle" ontology (filled by tipSelector) + message.EmptyId, + + // branch in "network tangle" ontology (filled by tipSelector) + message.EmptyId, + + // the time when the transaction was created + time.Now(), + + // public key of the issuer + ed25519.PublicKey{}, + + // the ever increasing sequence number of this transaction + 0, + + // payload + valuePayload, + + // nonce to check PoW + 0, + + // signature + ed25519.Signature{}, + ) + + fmt.Println(tx) +} + +func TestPayload(t *testing.T) { + addressKeyPair1 := ed25519.GenerateKeyPair() + addressKeyPair2 := ed25519.GenerateKeyPair() + + originalPayload := New( + GenesisID, + GenesisID, + transaction.New( + transaction.NewInputs( + transaction.NewOutputID(address.FromED25519PubKey(addressKeyPair1.PublicKey), transaction.RandomID()), + transaction.NewOutputID(address.FromED25519PubKey(addressKeyPair2.PublicKey), transaction.RandomID()), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1337), + }, + }), + ).Sign( + signaturescheme.ED25519(addressKeyPair1), + ), + ) + + assert.Equal(t, false, originalPayload.Transaction().SignaturesValid()) + + originalPayload.Transaction().Sign( + signaturescheme.ED25519(addressKeyPair2), + ) + + assert.Equal(t, true, originalPayload.Transaction().SignaturesValid()) + + clonedPayload1, _, err := FromBytes(originalPayload.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, originalPayload.BranchID(), clonedPayload1.BranchID()) + assert.Equal(t, originalPayload.TrunkID(), clonedPayload1.TrunkID()) + assert.Equal(t, originalPayload.Transaction().Bytes(), clonedPayload1.Transaction().Bytes()) + assert.Equal(t, originalPayload.ID(), clonedPayload1.ID()) + assert.Equal(t, true, clonedPayload1.Transaction().SignaturesValid()) + + clonedPayload2, _, err := FromBytes(clonedPayload1.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, originalPayload.ID(), clonedPayload2.ID()) + assert.Equal(t, true, clonedPayload2.Transaction().SignaturesValid()) +} diff --git a/dapps/valuetransfers/packages/tangle/attachment.go b/dapps/valuetransfers/packages/tangle/attachment.go new file mode 100644 index 0000000000000000000000000000000000000000..e7b41335b57948f0f9eb57bd1585d4831e1a1f69 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/attachment.go @@ -0,0 +1,196 @@ +package tangle + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" +) + +// Attachment stores the information which transaction was attached by which payload. We need this to be able to perform +// reverse lookups from transactions to their corresponding payloads, that attach them. +type Attachment struct { + objectstorage.StorableObjectFlags + + transactionID transaction.ID + payloadID payload.ID + + storageKey []byte +} + +// NewAttachment creates an attachment object with the given information. +func NewAttachment(transactionID transaction.ID, payloadID payload.ID) *Attachment { + return &Attachment{ + transactionID: transactionID, + payloadID: payloadID, + + storageKey: marshalutil.New(AttachmentLength). + WriteBytes(transactionID.Bytes()). + WriteBytes(payloadID.Bytes()). + Bytes(), + } +} + +// AttachmentFromBytes unmarshals an Attachment from a sequence of bytes - it either creates a new object or fills the +// optionally provided one with the parsed information. +func AttachmentFromBytes(bytes []byte, optionalTargetObject ...*Attachment) (result *Attachment, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseAttachment(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseAttachment is a wrapper for simplified unmarshaling of Attachments from a byte stream using the marshalUtil package. +func ParseAttachment(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Attachment) (result *Attachment, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return AttachmentFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*Attachment) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// AttachmentFromStorageKey gets called when we restore an Attachment from the storage - it parses the key bytes and +// returns the new object. +func AttachmentFromStorageKey(key []byte, optionalTargetObject ...*Attachment) (result *Attachment, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Attachment{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to AttachmentFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.transactionID, err = transaction.ParseID(marshalUtil); err != nil { + return + } + if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + result.storageKey = marshalutil.New(key[:consumedBytes]).Bytes(true) + + return +} + +// TransactionID returns the transaction id of this Attachment. +func (attachment *Attachment) TransactionID() transaction.ID { + return attachment.transactionID +} + +// PayloadID returns the payload id of this Attachment. +func (attachment *Attachment) PayloadID() payload.ID { + return attachment.payloadID +} + +// Bytes marshals the Attachment into a sequence of bytes. +func (attachment *Attachment) Bytes() []byte { + return attachment.ObjectStorageKey() +} + +// String returns a human readable version of the Attachment. +func (attachment *Attachment) String() string { + return stringify.Struct("Attachment", + stringify.StructField("transactionId", attachment.TransactionID()), + stringify.StructField("payloadId", attachment.PayloadID()), + ) +} + +// ObjectStorageKey returns the key that is used to store the object in the database. +func (attachment *Attachment) ObjectStorageKey() []byte { + return attachment.storageKey +} + +// ObjectStorageValue marshals the "content part" of an Attachment to a sequence of bytes. Since all of the information +// for this object are stored in its key, this method does nothing and is only required to conform with the interface. +func (attachment *Attachment) ObjectStorageValue() (data []byte) { + return +} + +// UnmarshalObjectStorageValue unmarshals the "content part" of an Attachment from a sequence of bytes. Since all of the information +// for this object are stored in its key, this method does nothing and is only required to conform with the interface. +func (attachment *Attachment) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + return +} + +// Update is disabled - updates are supposed to happen through the setters (if existing). +func (attachment *Attachment) Update(other objectstorage.StorableObject) { + panic("update forbidden") +} + +// Interface contract: make compiler warn if the interface is not implemented correctly. +var _ objectstorage.StorableObject = &Attachment{} + +// AttachmentLength holds the length of a marshaled Attachment in bytes. +const AttachmentLength = transaction.IDLength + payload.IDLength + +// region CachedAttachment ///////////////////////////////////////////////////////////////////////////////////////////// + +// CachedAttachment is a wrapper for the generic CachedObject returned by the objectstorage, that overrides the accessor +// methods, with a type-casted one. +type CachedAttachment struct { + objectstorage.CachedObject +} + +// Retain marks this CachedObject to still be in use by the program. +func (cachedAttachment *CachedAttachment) Retain() *CachedAttachment { + return &CachedAttachment{cachedAttachment.CachedObject.Retain()} +} + +// Unwrap is the type-casted equivalent of Get. It returns nil if the object does not exist. +func (cachedAttachment *CachedAttachment) Unwrap() *Attachment { + untypedObject := cachedAttachment.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*Attachment) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject +} + +// Consume unwraps the CachedObject and passes a type-casted version to the consumer (if the object is not empty - it +// exists). It automatically releases the object when the consumer finishes. +func (cachedAttachment *CachedAttachment) Consume(consumer func(attachment *Attachment)) (consumed bool) { + return cachedAttachment.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Attachment)) + }) +} + +// CachedAttachments represents a collection of CachedAttachments. +type CachedAttachments []*CachedAttachment + +// Consume iterates over the CachedObjects, unwraps them and passes a type-casted version to the consumer (if the object +// is not empty - it exists). It automatically releases the object when the consumer finishes. It returns true, if at +// least one object was consumed. +func (cachedAttachments CachedAttachments) Consume(consumer func(attachment *Attachment)) (consumed bool) { + for _, cachedAttachment := range cachedAttachments { + consumed = cachedAttachment.Consume(func(output *Attachment) { + consumer(output) + }) || consumed + } + + return +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dapps/valuetransfers/packages/tangle/attachment_test.go b/dapps/valuetransfers/packages/tangle/attachment_test.go new file mode 100644 index 0000000000000000000000000000000000000000..186214ed29b835cc6d2467bde5d469324748e3ad --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/attachment_test.go @@ -0,0 +1,28 @@ +package tangle + +import ( + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/stretchr/testify/assert" +) + +func TestAttachment(t *testing.T) { + transactionID := transaction.RandomID() + payloadID := payload.RandomID() + + attachment := NewAttachment(transactionID, payloadID) + + assert.Equal(t, transactionID, attachment.TransactionID()) + assert.Equal(t, payloadID, attachment.PayloadID()) + + clonedAttachment, consumedBytes, err := AttachmentFromBytes(attachment.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, AttachmentLength, consumedBytes) + assert.Equal(t, transactionID, clonedAttachment.TransactionID()) + assert.Equal(t, payloadID, clonedAttachment.PayloadID()) +} diff --git a/dapps/valuetransfers/packages/tangle/constants.go b/dapps/valuetransfers/packages/tangle/constants.go new file mode 100644 index 0000000000000000000000000000000000000000..f862156f666f8cfd48d39ff4ac5776bc44bc9faa --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/constants.go @@ -0,0 +1,14 @@ +package tangle + +import ( + "time" +) + +const ( + // MaxMissingTimeBeforeCleanup defines how long a transaction can be "missing", before we start pruning its future + // cone. + MaxMissingTimeBeforeCleanup = 30 * time.Second + + // MissingCheckInterval defines how often we check if missing transactions have been received. + MissingCheckInterval = 5 * time.Second +) diff --git a/dapps/valuetransfers/packages/tangle/consumer.go b/dapps/valuetransfers/packages/tangle/consumer.go new file mode 100644 index 0000000000000000000000000000000000000000..1fdcacb63ae9f3bc7cef6438973bb7e3adf83f79 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/consumer.go @@ -0,0 +1,194 @@ +package tangle + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" +) + +// ConsumerPartitionKeys defines the "layout" of the key. This enables prefix iterations in the objectstorage. +var ConsumerPartitionKeys = objectstorage.PartitionKey([]int{address.Length, transaction.IDLength, transaction.IDLength}...) + +// Consumer stores the information which transaction output was consumed by which transaction. We need this to be able +// to perform reverse lookups from transaction outputs to their corresponding consuming transactions. +type Consumer struct { + objectstorage.StorableObjectFlags + + consumedInput transaction.OutputID + transactionID transaction.ID + + storageKey []byte +} + +// NewConsumer creates a Consumer object with the given information. +func NewConsumer(consumedInput transaction.OutputID, transactionID transaction.ID) *Consumer { + return &Consumer{ + consumedInput: consumedInput, + transactionID: transactionID, + + storageKey: marshalutil.New(ConsumerLength). + WriteBytes(consumedInput.Bytes()). + WriteBytes(transactionID.Bytes()). + Bytes(), + } +} + +// ConsumerFromBytes unmarshals a Consumer from a sequence of bytes - it either creates a new object or fills the +// optionally provided one with the parsed information. +func ConsumerFromBytes(bytes []byte, optionalTargetObject ...*Consumer) (result *Consumer, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseConsumer(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseConsumer unmarshals a Consumer using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseConsumer(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Consumer) (result *Consumer, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return ConsumerFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*Consumer) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ConsumerFromStorageKey is a factory method that creates a new Consumer instance from a storage key of the +// objectstorage. It is used by the objectstorage, to create new instances of this entity. +func ConsumerFromStorageKey(key []byte, optionalTargetObject ...*Consumer) (result *Consumer, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Consumer{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to ConsumerFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.consumedInput, err = transaction.ParseOutputID(marshalUtil); err != nil { + return + } + if result.transactionID, err = transaction.ParseID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + result.storageKey = marshalutil.New(key[:consumedBytes]).Bytes(true) + + return +} + +// ConsumedInput returns the OutputID of the Consumer. +func (consumer *Consumer) ConsumedInput() transaction.OutputID { + return consumer.consumedInput +} + +// TransactionID returns the transaction ID of this Consumer. +func (consumer *Consumer) TransactionID() transaction.ID { + return consumer.transactionID +} + +// Bytes marshals the Consumer into a sequence of bytes. +func (consumer *Consumer) Bytes() []byte { + return consumer.ObjectStorageKey() +} + +// String returns a human readable version of the Consumer. +func (consumer *Consumer) String() string { + return stringify.Struct("Consumer", + stringify.StructField("consumedInput", consumer.ConsumedInput()), + stringify.StructField("transactionId", consumer.TransactionID()), + ) +} + +// ObjectStorageKey returns the key that is used to store the object in the database. +func (consumer *Consumer) ObjectStorageKey() []byte { + return consumer.storageKey +} + +// ObjectStorageValue marshals the "content part" of an Consumer to a sequence of bytes. Since all of the information for +// this object are stored in its key, this method does nothing and is only required to conform with the interface. +func (consumer *Consumer) ObjectStorageValue() (data []byte) { + return +} + +// UnmarshalObjectStorageValue unmarshals the "content part" of a Consumer from a sequence of bytes. Since all of the information +// for this object are stored in its key, this method does nothing and is only required to conform with the interface. +func (consumer *Consumer) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + return +} + +// Update is disabled - updates are supposed to happen through the setters (if existing). +func (consumer *Consumer) Update(other objectstorage.StorableObject) { + panic("update forbidden") +} + +// Interface contract: make compiler warn if the interface is not implemented correctly. +var _ objectstorage.StorableObject = &Consumer{} + +// ConsumerLength holds the length of a marshaled Consumer in bytes. +const ConsumerLength = transaction.OutputIDLength + transaction.IDLength + +// region CachedConsumer ///////////////////////////////////////////////////////////////////////////////////////////////// + +// CachedConsumer is a wrapper for the generic CachedObject returned by the objectstorage, that overrides the accessor +// methods, with a type-casted one. +type CachedConsumer struct { + objectstorage.CachedObject +} + +// Unwrap is the type-casted equivalent of Get. It returns nil if the object does not exist. +func (cachedConsumer *CachedConsumer) Unwrap() *Consumer { + untypedObject := cachedConsumer.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*Consumer) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject +} + +// Consume unwraps the CachedObject and passes a type-casted version to the consumer (if the object is not empty - it +// exists). It automatically releases the object when the consumer finishes. +func (cachedConsumer *CachedConsumer) Consume(consumer func(consumer *Consumer)) (consumed bool) { + return cachedConsumer.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Consumer)) + }) +} + +// CachedConsumers represents a collection of CachedConsumers. +type CachedConsumers []*CachedConsumer + +// Consume iterates over the CachedObjects, unwraps them and passes a type-casted version to the consumer (if the object +// is not empty - it exists). It automatically releases the object when the consumer finishes. It returns true, if at +// least one object was consumed. +func (cachedConsumers CachedConsumers) Consume(consumer func(consumer *Consumer)) (consumed bool) { + for _, cachedConsumer := range cachedConsumers { + consumed = cachedConsumer.Consume(func(output *Consumer) { + consumer(output) + }) || consumed + } + + return +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dapps/valuetransfers/packages/tangle/debugger.go b/dapps/valuetransfers/packages/tangle/debugger.go new file mode 100644 index 0000000000000000000000000000000000000000..976c5270f839abafc15fdb8bb36518ea4ee813de --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/debugger.go @@ -0,0 +1,115 @@ +package tangle + +import ( + "fmt" + "strings" +) + +// Debugger represents a utility that allows us to print debug messages and function calls. +type Debugger struct { + aliases map[interface{}]string + enabled bool + indent int +} + +// NewDebugger is the constructor of a debugger instance. +func NewDebugger() *Debugger { + return (&Debugger{}).ResetAliases() +} + +// Enable sets the debugger to print the debug information. +func (debugger *Debugger) Enable() { + debugger.enabled = true + + fmt.Println("[DEBUGGER::ENABLED]") +} + +// Disable sets the debugger to not print any debug information. +func (debugger *Debugger) Disable() { + fmt.Println("[DEBUGGER::DISABLED]") + debugger.enabled = false +} + +// ResetAliases removes any previously registered aliases. This can be useful if the same debugger instance is for +// example used in different tests or test cases. +func (debugger *Debugger) ResetAliases() *Debugger { + debugger.aliases = make(map[interface{}]string) + + return debugger +} + +// RegisterAlias registers a string representation for the given element. This can be used to create a string +// representation for things like ids in the form of byte slices. +func (debugger *Debugger) RegisterAlias(element interface{}, alias string) { + debugger.aliases[element] = alias +} + +// FunctionCall prints debug information about a function call. It automatically indents all following debug outputs +// until Return() is called. The best way to use this is by starting a function call with a construct like: +// +// defer debugger.FunctionCall("myFunction", param1, param2).Return() +func (debugger *Debugger) FunctionCall(identifier string, params ...interface{}) *Debugger { + if !debugger.enabled { + return debugger + } + + debugger.Print(identifier + "(" + debugger.paramsAsCommaSeparatedList(params...) + ") {") + debugger.indent++ + + return debugger +} + +// Return prints debug information about a FunctionCall() the was finished. It reduces the indentation for consecutive +// debug outputs. +func (debugger *Debugger) Return() *Debugger { + if !debugger.enabled { + return debugger + } + + debugger.indent-- + debugger.Print("}") + + return debugger +} + +// Print prints an arbitrary debug message that can for example be used to print an information when a certain part of +// the code is executed. +func (debugger *Debugger) Print(identifier string, params ...interface{}) { + if !debugger.enabled { + return + } + + if len(params) >= 1 { + debugger.print(identifier + " = " + debugger.paramsAsCommaSeparatedList(params...)) + } else { + debugger.print(identifier) + } +} + +// print is an internal utility function that actually prints the given string to stdout. +func (debugger *Debugger) print(stringToPrint string) { + fmt.Println("[DEBUGGER] " + strings.Repeat(" ", debugger.indent) + stringToPrint) +} + +// paramsAsCommaSeparatedList creates a comma separated list of the given parameters. +func (debugger *Debugger) paramsAsCommaSeparatedList(params ...interface{}) string { + paramsAsStrings := make([]string, len(params)) + for i, param := range params { + paramsAsStrings[i] = debugger.paramAsString(param) + } + + return strings.Join(paramsAsStrings, ", ") +} + +// paramAsString returns a string representation of an arbitrary parameter. +func (debugger *Debugger) paramAsString(param interface{}) string { + defer func() { recover() }() + if alias, aliasExists := debugger.aliases[param]; aliasExists { + return alias + } + + return fmt.Sprint(param) +} + +// debugger contains the default global debugger instance. +var debugger = NewDebugger() diff --git a/dapps/valuetransfers/packages/tangle/errors.go b/dapps/valuetransfers/packages/tangle/errors.go new file mode 100644 index 0000000000000000000000000000000000000000..3ada3b8ae0f57de974ed9bcc4a11012a6db3b5c4 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/errors.go @@ -0,0 +1,14 @@ +package tangle + +import "errors" + +var ( + // ErrFatal represents an error that is not "expected". + ErrFatal = errors.New("fatal error") + + // ErrTransactionInvalid represents an error type that is triggered when an invalid transaction is detected. + ErrTransactionInvalid = errors.New("transaction invalid") + + // ErrPayloadInvalid represents an error type that is triggered when an invalid payload is detected. + ErrPayloadInvalid = errors.New("payload invalid") +) diff --git a/dapps/valuetransfers/packages/tangle/events.go b/dapps/valuetransfers/packages/tangle/events.go new file mode 100644 index 0000000000000000000000000000000000000000..17207555c01f1fd714c7fdef352e46fbab7cd994 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/events.go @@ -0,0 +1,156 @@ +package tangle + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/events" +) + +// Events is a container for the different kind of events of the Tangle. +type Events struct { + // Get's called whenever a transaction + PayloadAttached *events.Event + PayloadSolid *events.Event + PayloadLiked *events.Event + PayloadConfirmed *events.Event + PayloadRejected *events.Event + PayloadDisliked *events.Event + MissingPayloadReceived *events.Event + PayloadMissing *events.Event + PayloadInvalid *events.Event + + // TransactionReceived gets triggered whenever a transaction was received for the first time (not solid yet). + TransactionReceived *events.Event + + // TransactionInvalid gets triggered whenever we receive an invalid transaction. + TransactionInvalid *events.Event + + // TransactionSolid gets triggered whenever a transaction becomes solid for the first time. + TransactionSolid *events.Event + + // TransactionBooked gets triggered whenever a transactions becomes solid and gets booked into a particular branch. + TransactionBooked *events.Event + + TransactionPreferred *events.Event + + TransactionUnpreferred *events.Event + + TransactionLiked *events.Event + + TransactionDisliked *events.Event + + TransactionConfirmed *events.Event + + TransactionRejected *events.Event + + TransactionFinalized *events.Event + + // Fork gets triggered when a previously un-conflicting transaction get's some of its inputs double spend, so that a + // new Branch is created. + Fork *events.Event + + Error *events.Event +} + +// EventSource is a type that contains information from where a specific change was triggered (the branch manager or +// the tangle). +type EventSource int + +const ( + // EventSourceTangle indicates that a change was issued by the Tangle. + EventSourceTangle EventSource = iota + + // EventSourceBranchManager indicates that a change was issued by the BranchManager. + EventSourceBranchManager +) + +func (eventSource EventSource) String() string { + return [...]string{"EventSourceTangle", "EventSourceBranchManager"}[eventSource] +} + +func newEvents() *Events { + return &Events{ + PayloadAttached: events.NewEvent(cachedPayloadEvent), + PayloadSolid: events.NewEvent(cachedPayloadEvent), + PayloadLiked: events.NewEvent(cachedPayloadEvent), + PayloadConfirmed: events.NewEvent(cachedPayloadEvent), + PayloadRejected: events.NewEvent(cachedPayloadEvent), + PayloadDisliked: events.NewEvent(cachedPayloadEvent), + MissingPayloadReceived: events.NewEvent(cachedPayloadEvent), + PayloadMissing: events.NewEvent(payloadIDEvent), + PayloadInvalid: events.NewEvent(cachedPayloadErrorEvent), + TransactionReceived: events.NewEvent(cachedTransactionAttachmentEvent), + TransactionInvalid: events.NewEvent(cachedTransactionErrorEvent), + TransactionSolid: events.NewEvent(cachedTransactionEvent), + TransactionBooked: events.NewEvent(transactionBookedEvent), + TransactionPreferred: events.NewEvent(cachedTransactionEvent), + TransactionUnpreferred: events.NewEvent(cachedTransactionEvent), + TransactionLiked: events.NewEvent(cachedTransactionEvent), + TransactionDisliked: events.NewEvent(cachedTransactionEvent), + TransactionFinalized: events.NewEvent(cachedTransactionEvent), + TransactionConfirmed: events.NewEvent(cachedTransactionEvent), + TransactionRejected: events.NewEvent(cachedTransactionEvent), + Fork: events.NewEvent(forkEvent), + Error: events.NewEvent(events.ErrorCaller), + } +} + +func payloadIDEvent(handler interface{}, params ...interface{}) { + handler.(func(payload.ID))(params[0].(payload.ID)) +} + +func cachedPayloadEvent(handler interface{}, params ...interface{}) { + handler.(func(*payload.CachedPayload, *CachedPayloadMetadata))( + params[0].(*payload.CachedPayload).Retain(), + params[1].(*CachedPayloadMetadata).Retain(), + ) +} + +func cachedPayloadErrorEvent(handler interface{}, params ...interface{}) { + handler.(func(*payload.CachedPayload, *CachedPayloadMetadata, error))( + params[0].(*payload.CachedPayload).Retain(), + params[1].(*CachedPayloadMetadata).Retain(), + params[2].(error), + ) +} + +func transactionBookedEvent(handler interface{}, params ...interface{}) { + handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, bool))( + params[0].(*transaction.CachedTransaction).Retain(), + params[1].(*CachedTransactionMetadata).Retain(), + params[2].(bool), + ) +} + +func forkEvent(handler interface{}, params ...interface{}) { + handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, *branchmanager.CachedBranch, []transaction.OutputID))( + params[0].(*transaction.CachedTransaction).Retain(), + params[1].(*CachedTransactionMetadata).Retain(), + params[2].(*branchmanager.CachedBranch).Retain(), + params[3].([]transaction.OutputID), + ) +} + +func cachedTransactionEvent(handler interface{}, params ...interface{}) { + handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata))( + params[0].(*transaction.CachedTransaction).Retain(), + params[1].(*CachedTransactionMetadata).Retain(), + ) +} + +func cachedTransactionErrorEvent(handler interface{}, params ...interface{}) { + handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, error))( + params[0].(*transaction.CachedTransaction).Retain(), + params[1].(*CachedTransactionMetadata).Retain(), + params[2].(error), + ) +} + +func cachedTransactionAttachmentEvent(handler interface{}, params ...interface{}) { + handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, *CachedAttachment))( + params[0].(*transaction.CachedTransaction).Retain(), + params[1].(*CachedTransactionMetadata).Retain(), + params[2].(*CachedAttachment).Retain(), + ) +} diff --git a/dapps/valuetransfers/packages/tangle/factory.go b/dapps/valuetransfers/packages/tangle/factory.go new file mode 100644 index 0000000000000000000000000000000000000000..6720e5d2f9c4361a3a4947706db17e848f16ffd1 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/factory.go @@ -0,0 +1,45 @@ +package tangle + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tipmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/events" +) + +// ValueObjectFactory acts as a factory to create new value objects. +type ValueObjectFactory struct { + tipManager *tipmanager.TipManager + Events *ValueObjectFactoryEvents +} + +// NewValueObjectFactory creates a new ValueObjectFactory. +func NewValueObjectFactory(tipManager *tipmanager.TipManager) *ValueObjectFactory { + return &ValueObjectFactory{ + tipManager: tipManager, + Events: &ValueObjectFactoryEvents{ + ValueObjectConstructed: events.NewEvent(valueObjectConstructedEvent), + }, + } +} + +// IssueTransaction creates a new value object including tip selection and returns it. +// It also triggers the ValueObjectConstructed event once it's done. +func (v *ValueObjectFactory) IssueTransaction(tx *transaction.Transaction) *payload.Payload { + parent1, parent2 := v.tipManager.Tips() + + valueObject := payload.New(parent1, parent2, tx) + v.Events.ValueObjectConstructed.Trigger(valueObject) + + return valueObject +} + +// ValueObjectFactoryEvents represent events happening on a ValueObjectFactory. +type ValueObjectFactoryEvents struct { + // Fired when a value object is built including tips. + ValueObjectConstructed *events.Event +} + +func valueObjectConstructedEvent(handler interface{}, params ...interface{}) { + handler.(func(*transaction.Transaction))(params[0].(*transaction.Transaction)) +} diff --git a/dapps/valuetransfers/packages/tangle/imgs/concurrency.png b/dapps/valuetransfers/packages/tangle/imgs/concurrency.png new file mode 100644 index 0000000000000000000000000000000000000000..5238ce8b1d2b3b3b7f9c4e5ab095eac0651bcd0b Binary files /dev/null and b/dapps/valuetransfers/packages/tangle/imgs/concurrency.png differ diff --git a/dapps/valuetransfers/packages/tangle/imgs/reverse-transaction-solidification.png b/dapps/valuetransfers/packages/tangle/imgs/reverse-transaction-solidification.png new file mode 100644 index 0000000000000000000000000000000000000000..0d63b99fe60c208e457b1a3d3d249fd27ca32a95 Binary files /dev/null and b/dapps/valuetransfers/packages/tangle/imgs/reverse-transaction-solidification.png differ diff --git a/dapps/valuetransfers/packages/tangle/imgs/reverse-valueobject-solidification.png b/dapps/valuetransfers/packages/tangle/imgs/reverse-valueobject-solidification.png new file mode 100644 index 0000000000000000000000000000000000000000..3c1d3ecf6da6f78bdcdd06fb3bb104e785af3331 Binary files /dev/null and b/dapps/valuetransfers/packages/tangle/imgs/reverse-valueobject-solidification.png differ diff --git a/dapps/valuetransfers/packages/tangle/imgs/scenario1.png b/dapps/valuetransfers/packages/tangle/imgs/scenario1.png new file mode 100644 index 0000000000000000000000000000000000000000..73b9b7cd0be6ce152a07d59bc5433179eb942b3f Binary files /dev/null and b/dapps/valuetransfers/packages/tangle/imgs/scenario1.png differ diff --git a/dapps/valuetransfers/packages/tangle/imgs/scenario2.png b/dapps/valuetransfers/packages/tangle/imgs/scenario2.png new file mode 100644 index 0000000000000000000000000000000000000000..653997ff5e2e5d8ce3fc7ef8df378bac6ce85bd8 Binary files /dev/null and b/dapps/valuetransfers/packages/tangle/imgs/scenario2.png differ diff --git a/dapps/valuetransfers/packages/tangle/ledgerstate.go b/dapps/valuetransfers/packages/tangle/ledgerstate.go new file mode 100644 index 0000000000000000000000000000000000000000..9b676acfedfebbf7a417bfc8d63c0bf24bdc8991 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/ledgerstate.go @@ -0,0 +1,34 @@ +package tangle + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" +) + +// LedgerState represents a struct, that allows us to read the balances from the UTXODAG by filtering the existing +// unspent Outputs depending on the liked branches. +type LedgerState struct { + tangle *Tangle +} + +// NewLedgerState is the constructor of the LedgerState. It creates a new instance with the given UTXODAG. +func NewLedgerState(tangle *Tangle) *LedgerState { + return &LedgerState{ + tangle: tangle, + } +} + +// Balances returns a map containing the balances of the different colors that are unspent on a certain address. +func (ledgerState *LedgerState) Balances(address address.Address) (coloredBalances map[balance.Color]int64) { + coloredBalances = make(map[balance.Color]int64) + + ledgerState.tangle.OutputsOnAddress(address).Consume(func(output *Output) { + if output.ConsumerCount() == 0 { + for _, coloredBalance := range output.Balances() { + coloredBalances[coloredBalance.Color] += coloredBalance.Value + } + } + }) + + return +} diff --git a/dapps/valuetransfers/packages/tangle/missingoutput.go b/dapps/valuetransfers/packages/tangle/missingoutput.go new file mode 100644 index 0000000000000000000000000000000000000000..796c666ea8869cfd0c40fd4b4df970c29503c0aa --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/missingoutput.go @@ -0,0 +1,133 @@ +package tangle + +import ( + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" +) + +// MissingOutputKeyPartitions defines the "layout" of the key. This enables prefix iterations in the objectstorage. +var MissingOutputKeyPartitions = objectstorage.PartitionKey([]int{address.Length, transaction.IDLength}...) + +// MissingOutput represents an Output that was referenced by a Transaction, but that is missing in our object storage. +type MissingOutput struct { + objectstorage.StorableObjectFlags + + outputID transaction.OutputID + missingSince time.Time +} + +// NewMissingOutput creates a new MissingOutput object, that . +func NewMissingOutput(outputID transaction.OutputID) *MissingOutput { + return &MissingOutput{ + outputID: outputID, + missingSince: time.Now(), + } +} + +// MissingOutputFromBytes unmarshals a MissingOutput from a sequence of bytes - it either creates a new object or fills +// the optionally provided one with the parsed information. +func MissingOutputFromBytes(bytes []byte, optionalTargetObject ...*MissingOutput) (result *MissingOutput, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseMissingOutput(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseMissingOutput unmarshals a MissingOutput using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseMissingOutput(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*MissingOutput) (result *MissingOutput, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return MissingOutputFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*MissingOutput) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// MissingOutputFromStorageKey gets called when we restore a MissingOutput from the storage. The content will be +// unmarshaled by an external caller using the binary.ObjectStorageValue interface. +func MissingOutputFromStorageKey(key []byte, optionalTargetObject ...*MissingOutput) (result *MissingOutput, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &MissingOutput{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to MissingOutputFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.outputID, err = transaction.ParseOutputID(marshalUtil); err != nil { + return + } + + return +} + +// ID returns the id of the Output that is missing. +func (missingOutput *MissingOutput) ID() transaction.OutputID { + return missingOutput.outputID +} + +// MissingSince returns the Time since the transaction was first reported as being missing. +func (missingOutput *MissingOutput) MissingSince() time.Time { + return missingOutput.missingSince +} + +// Bytes marshals the MissingOutput into a sequence of bytes. +func (missingOutput *MissingOutput) Bytes() []byte { + return marshalutil.New(transaction.OutputIDLength + marshalutil.TIME_SIZE). + WriteBytes(missingOutput.ObjectStorageKey()). + WriteBytes(missingOutput.ObjectStorageValue()). + Bytes() +} + +// ObjectStorageKey returns the key that is used to store the object in the object storage. +func (missingOutput *MissingOutput) ObjectStorageKey() []byte { + return missingOutput.outputID.Bytes() +} + +// ObjectStorageValue returns a bytes representation of the Transaction by implementing the encoding.BinaryMarshaler +// interface. +func (missingOutput *MissingOutput) ObjectStorageValue() []byte { + return marshalutil.New(marshalutil.TIME_SIZE). + WriteTime(missingOutput.MissingSince()). + Bytes() +} + +// UnmarshalObjectStorageValue restores the values of a MissingOutput from a sequence of bytes using the encoding.BinaryUnmarshaler +// interface. +func (missingOutput *MissingOutput) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + if missingOutput.missingSince, err = marshalUtil.ReadTime(); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters. +func (missingOutput *MissingOutput) Update(other objectstorage.StorableObject) { + panic("implement me") +} + +// Interface contract: make compiler warn if the interface is not implemented correctly. +var _ objectstorage.StorableObject = &MissingOutput{} diff --git a/dapps/valuetransfers/packages/tangle/missingpayload.go b/dapps/valuetransfers/packages/tangle/missingpayload.go new file mode 100644 index 0000000000000000000000000000000000000000..5ef6ca9e4a35e99a46fc933c61051c29dacee88d --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/missingpayload.go @@ -0,0 +1,131 @@ +package tangle + +import ( + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" +) + +// MissingPayload represents a payload that was referenced through branch or trunk but that is missing in our object +// storage. +type MissingPayload struct { + objectstorage.StorableObjectFlags + + payloadID payload.ID + missingSince time.Time +} + +// NewMissingPayload creates an entry for a missing value transfer payload. +func NewMissingPayload(payloadID payload.ID) *MissingPayload { + return &MissingPayload{ + payloadID: payloadID, + missingSince: time.Now(), + } +} + +// MissingPayloadFromBytes unmarshals an entry for a missing value transfer payload from a sequence of bytes. +// It either creates a new entry or fills the optionally provided one with the parsed information. +func MissingPayloadFromBytes(bytes []byte, optionalTargetObject ...*MissingPayload) (result *MissingPayload, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseMissingPayload(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseMissingPayload unmarshals a MissingPayload using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseMissingPayload(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*MissingPayload) (result *MissingPayload, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return MissingPayloadFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*MissingPayload) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// MissingPayloadFromStorageKey gets called when we restore an entry for a missing value transfer payload from the storage. The bytes and +// the content will be unmarshaled by an external caller using the binary.ObjectStorageValue interface. +func MissingPayloadFromStorageKey(key []byte, optionalTargetObject ...*MissingPayload) (result *MissingPayload, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &MissingPayload{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to MissingPayloadFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ID returns the payload id, that is missing. +func (missingPayload *MissingPayload) ID() payload.ID { + return missingPayload.payloadID +} + +// MissingSince returns the time.Time since the transaction was first reported as being missing. +func (missingPayload *MissingPayload) MissingSince() time.Time { + return missingPayload.missingSince +} + +// Bytes marshals the missing payload into a sequence of bytes. +func (missingPayload *MissingPayload) Bytes() []byte { + return marshalutil.New(payload.IDLength + marshalutil.TIME_SIZE). + WriteBytes(missingPayload.ObjectStorageKey()). + WriteBytes(missingPayload.ObjectStorageValue()). + Bytes() +} + +// Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters. +// It is required to match StorableObject interface. +func (missingPayload *MissingPayload) Update(other objectstorage.StorableObject) { + panic("implement me") +} + +// ObjectStorageKey returns the key that is used to store the object in the database. +// It is required to match StorableObject interface. +func (missingPayload *MissingPayload) ObjectStorageKey() []byte { + return missingPayload.payloadID.Bytes() +} + +// ObjectStorageValue is required to match the encoding.BinaryMarshaler interface. +func (missingPayload *MissingPayload) ObjectStorageValue() (data []byte) { + return marshalutil.New(marshalutil.TIME_SIZE). + WriteTime(missingPayload.MissingSince()). + Bytes() +} + +// UnmarshalObjectStorageValue is required to match the encoding.BinaryUnmarshaler interface. +func (missingPayload *MissingPayload) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + if missingPayload.missingSince, err = marshalUtil.ReadTime(); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Interface contract: make compiler warn if the interface is not implemented correctly. +var _ objectstorage.StorableObject = &MissingPayload{} diff --git a/dapps/valuetransfers/packages/tangle/objectstorage.go b/dapps/valuetransfers/packages/tangle/objectstorage.go new file mode 100644 index 0000000000000000000000000000000000000000..e7ed013043d5f781219f0dc7030275975d249bc3 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/objectstorage.go @@ -0,0 +1,70 @@ +package tangle + +import ( + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/objectstorage" +) + +const ( + // the following values are a list of prefixes defined as an enum + _ byte = iota + + // prefixes used for the objectstorage + osPayload + osPayloadMetadata + osMissingPayload + osApprover + osTransaction + osTransactionMetadata + osAttachment + osOutput + osConsumer + + cacheTime = 20 * time.Second +) + +var ( + osLeakDetectionOption = objectstorage.LeakDetectionEnabled(false, objectstorage.LeakDetectionOptions{ + MaxConsumersPerObject: 20, + MaxConsumerHoldTime: 10 * time.Second, + }) +) + +func osPayloadFactory(key []byte) (objectstorage.StorableObject, int, error) { + return payload.FromStorageKey(key) +} + +func osPayloadMetadataFactory(key []byte) (objectstorage.StorableObject, int, error) { + return PayloadMetadataFromStorageKey(key) +} + +func osMissingPayloadFactory(key []byte) (objectstorage.StorableObject, int, error) { + return MissingPayloadFromStorageKey(key) +} + +func osPayloadApproverFactory(key []byte) (objectstorage.StorableObject, int, error) { + return PayloadApproverFromStorageKey(key) +} + +func osTransactionFactory(key []byte) (objectstorage.StorableObject, int, error) { + return transaction.FromStorageKey(key) +} + +func osTransactionMetadataFactory(key []byte) (objectstorage.StorableObject, int, error) { + return TransactionMetadataFromStorageKey(key) +} + +func osAttachmentFactory(key []byte) (objectstorage.StorableObject, int, error) { + return AttachmentFromStorageKey(key) +} + +func osOutputFactory(key []byte) (objectstorage.StorableObject, int, error) { + return OutputFromStorageKey(key) +} + +func osConsumerFactory(key []byte) (objectstorage.StorableObject, int, error) { + return ConsumerFromStorageKey(key) +} diff --git a/dapps/valuetransfers/packages/tangle/output.go b/dapps/valuetransfers/packages/tangle/output.go new file mode 100644 index 0000000000000000000000000000000000000000..4421454ee8b13ef90b3c5302f16121c7e45ec146 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/output.go @@ -0,0 +1,577 @@ +package tangle + +import ( + "sync" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" +) + +// OutputKeyPartitions defines the "layout" of the key. This enables prefix iterations in the objectstorage. +var OutputKeyPartitions = objectstorage.PartitionKey([]int{address.Length, transaction.IDLength}...) + +// Output represents the output of a Transaction and contains the balances and the identifiers for this output. +type Output struct { + address address.Address + transactionID transaction.ID + branchID branchmanager.BranchID + solid bool + solidificationTime time.Time + firstConsumer transaction.ID + consumerCount int + preferred bool + finalized bool + liked bool + confirmed bool + rejected bool + balances []*balance.Balance + + branchIDMutex sync.RWMutex + solidMutex sync.RWMutex + solidificationTimeMutex sync.RWMutex + consumerMutex sync.RWMutex + preferredMutex sync.RWMutex + finalizedMutex sync.RWMutex + likedMutex sync.RWMutex + confirmedMutex sync.RWMutex + rejectedMutex sync.RWMutex + + objectstorage.StorableObjectFlags + storageKey []byte +} + +// NewOutput creates an Output that contains the balances and identifiers of a Transaction. +func NewOutput(address address.Address, transactionID transaction.ID, branchID branchmanager.BranchID, balances []*balance.Balance) *Output { + return &Output{ + address: address, + transactionID: transactionID, + branchID: branchID, + solid: false, + solidificationTime: time.Time{}, + balances: balances, + + storageKey: marshalutil.New().WriteBytes(address.Bytes()).WriteBytes(transactionID.Bytes()).Bytes(), + } +} + +// OutputFromBytes unmarshals an Output object from a sequence of bytes. +// It either creates a new object or fills the optionally provided object with the parsed information. +func OutputFromBytes(bytes []byte, optionalTargetObject ...*Output) (result *Output, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseOutput(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseOutput unmarshals an Output using the given marshalUtil (for easier marshaling/unmarshaling). +func ParseOutput(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Output) (result *Output, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return OutputFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*Output) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// OutputFromStorageKey get's called when we restore a Output from the storage. +// In contrast to other database models, it unmarshals some information from the key so we simply store the key before +// it gets handed over to UnmarshalObjectStorageValue (by the ObjectStorage). +func OutputFromStorageKey(keyBytes []byte, optionalTargetObject ...*Output) (result *Output, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Output{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to OutputFromStorageKey") + } + + // parse information + marshalUtil := marshalutil.New(keyBytes) + result.address, err = address.Parse(marshalUtil) + if err != nil { + return + } + result.transactionID, err = transaction.ParseID(marshalUtil) + if err != nil { + return + } + result.storageKey = marshalutil.New(keyBytes[:transaction.OutputIDLength]).Bytes(true) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ID returns the identifier of this Output. +func (output *Output) ID() transaction.OutputID { + return transaction.NewOutputID(output.Address(), output.TransactionID()) +} + +// Address returns the address that this output belongs to. +func (output *Output) Address() address.Address { + return output.address +} + +// TransactionID returns the id of the Transaction, that created this output. +func (output *Output) TransactionID() transaction.ID { + return output.transactionID +} + +// BranchID returns the id of the ledger state branch, that this output was booked in. +func (output *Output) BranchID() branchmanager.BranchID { + output.branchIDMutex.RLock() + defer output.branchIDMutex.RUnlock() + + return output.branchID +} + +// setBranchID is the setter for the property that indicates in which ledger state branch the output is booked. +func (output *Output) setBranchID(branchID branchmanager.BranchID) (modified bool) { + output.branchIDMutex.RLock() + if output.branchID == branchID { + output.branchIDMutex.RUnlock() + + return + } + + output.branchIDMutex.RUnlock() + output.branchIDMutex.Lock() + defer output.branchIDMutex.Unlock() + + if output.branchID == branchID { + return + } + + output.branchID = branchID + output.SetModified() + modified = true + + return +} + +// Solid returns true if the output has been marked as solid. +func (output *Output) Solid() bool { + output.solidMutex.RLock() + defer output.solidMutex.RUnlock() + + return output.solid +} + +// setSolid is the setter of the solid flag. It returns true if the solid flag was modified. +func (output *Output) setSolid(solid bool) (modified bool) { + output.solidMutex.RLock() + if output.solid != solid { + output.solidMutex.RUnlock() + + output.solidMutex.Lock() + if output.solid != solid { + output.solid = solid + if solid { + output.solidificationTimeMutex.Lock() + output.solidificationTime = time.Now() + output.solidificationTimeMutex.Unlock() + } + + output.SetModified() + + modified = true + } + output.solidMutex.Unlock() + + } else { + output.solidMutex.RUnlock() + } + + return +} + +// SolidificationTime returns the time when this Output was marked to be solid. +func (output *Output) SolidificationTime() time.Time { + output.solidificationTimeMutex.RLock() + defer output.solidificationTimeMutex.RUnlock() + + return output.solidificationTime +} + +// RegisterConsumer keeps track of the first transaction, that consumed an Output and consequently keeps track of the +// amount of other transactions spending the same Output. +func (output *Output) RegisterConsumer(consumer transaction.ID) (consumerCount int, firstConsumerID transaction.ID) { + output.consumerMutex.Lock() + defer output.consumerMutex.Unlock() + + if consumerCount = output.consumerCount; consumerCount == 0 { + output.firstConsumer = consumer + } + output.consumerCount++ + output.SetModified() + + firstConsumerID = output.firstConsumer + + return +} + +// ConsumerCount returns the number of transactions that have spent this Output. +func (output *Output) ConsumerCount() int { + output.consumerMutex.RLock() + defer output.consumerMutex.RUnlock() + + return output.consumerCount +} + +// Preferred returns true if the output belongs to a preferred transaction. +func (output *Output) Preferred() (result bool) { + output.preferredMutex.RLock() + defer output.preferredMutex.RUnlock() + + return output.preferred +} + +// setPreferred updates the preferred flag of the output. It is defined as a private setter because updating the +// preferred flag causes changes in other outputs and branches as well. This means that we need additional logic +// in the tangle. To update the preferred flag of a output, we need to use Tangle.SetTransactionPreferred(bool). +func (output *Output) setPreferred(preferred bool) (modified bool) { + output.preferredMutex.RLock() + if output.preferred == preferred { + output.preferredMutex.RUnlock() + + return + } + + output.preferredMutex.RUnlock() + output.preferredMutex.Lock() + defer output.preferredMutex.Unlock() + + if output.preferred == preferred { + return + } + + output.preferred = preferred + output.SetModified() + modified = true + + return +} + +// setFinalized allows us to set the finalized flag on the outputs. Finalized outputs will not be forked when +// a conflict arrives later. +func (output *Output) setFinalized(finalized bool) (modified bool) { + output.finalizedMutex.RLock() + if output.finalized == finalized { + output.finalizedMutex.RUnlock() + + return + } + + output.finalizedMutex.RUnlock() + output.finalizedMutex.Lock() + defer output.finalizedMutex.Unlock() + + if output.finalized == finalized { + return + } + + output.finalized = finalized + output.SetModified() + modified = true + + return +} + +// Finalized returns true, if the decision if this output is preferred or not has been finalized by consensus already. +func (output *Output) Finalized() bool { + output.finalizedMutex.RLock() + defer output.finalizedMutex.RUnlock() + + return output.finalized +} + +// Liked returns true if the Output was marked as liked. +func (output *Output) Liked() bool { + output.likedMutex.RLock() + defer output.likedMutex.RUnlock() + + return output.liked +} + +// setLiked modifies the liked flag of the given Output. It returns true if the value has been updated. +func (output *Output) setLiked(liked bool) (modified bool) { + output.likedMutex.RLock() + if output.liked == liked { + output.likedMutex.RUnlock() + + return + } + + output.likedMutex.RUnlock() + output.likedMutex.Lock() + defer output.likedMutex.Unlock() + + if output.liked == liked { + return + } + + output.liked = liked + output.SetModified() + modified = true + + return +} + +// Confirmed returns true if the Output was marked as confirmed. +func (output *Output) Confirmed() bool { + output.confirmedMutex.RLock() + defer output.confirmedMutex.RUnlock() + + return output.confirmed +} + +// setConfirmed modifies the confirmed flag of the given Output. It returns true if the value has been updated. +func (output *Output) setConfirmed(confirmed bool) (modified bool) { + output.confirmedMutex.RLock() + if output.confirmed == confirmed { + output.confirmedMutex.RUnlock() + + return + } + + output.confirmedMutex.RUnlock() + output.confirmedMutex.Lock() + defer output.confirmedMutex.Unlock() + + if output.confirmed == confirmed { + return + } + + output.confirmed = confirmed + output.SetModified() + modified = true + + return +} + +// Rejected returns true if the Output was marked as confirmed. +func (output *Output) Rejected() bool { + output.rejectedMutex.RLock() + defer output.rejectedMutex.RUnlock() + + return output.rejected +} + +// setRejected modifies the rejected flag of the given Output. It returns true if the value has been updated. +func (output *Output) setRejected(rejected bool) (modified bool) { + output.rejectedMutex.RLock() + if output.rejected == rejected { + output.rejectedMutex.RUnlock() + + return + } + + output.rejectedMutex.RUnlock() + output.rejectedMutex.Lock() + defer output.rejectedMutex.Unlock() + + if output.rejected == rejected { + return + } + + output.rejected = rejected + output.SetModified() + modified = true + + return +} + +// Balances returns the colored balances (color + balance) that this output contains. +func (output *Output) Balances() []*balance.Balance { + return output.balances +} + +// Bytes marshals the object into a sequence of bytes. +func (output *Output) Bytes() []byte { + return marshalutil.New(). + WriteBytes(output.ObjectStorageKey()). + WriteBytes(output.ObjectStorageValue()). + Bytes() +} + +// ObjectStorageKey returns the key that is used to store the object in the database. +// It is required to match StorableObject interface. +func (output *Output) ObjectStorageKey() []byte { + return marshalutil.New(transaction.OutputIDLength). + WriteBytes(output.address.Bytes()). + WriteBytes(output.transactionID.Bytes()). + Bytes() +} + +// ObjectStorageValue marshals the balances into a sequence of bytes - the address and transaction id are stored inside the key +// and are ignored here. +func (output *Output) ObjectStorageValue() []byte { + // determine amount of balances in the output + balances := output.Balances() + balanceCount := len(balances) + + // initialize helper + marshalUtil := marshalutil.New(branchmanager.BranchIDLength + 6*marshalutil.BOOL_SIZE + marshalutil.TIME_SIZE + transaction.IDLength + marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + balanceCount*balance.Length) + marshalUtil.WriteBytes(output.branchID.Bytes()) + marshalUtil.WriteBool(output.Solid()) + marshalUtil.WriteTime(output.SolidificationTime()) + marshalUtil.WriteBytes(output.firstConsumer.Bytes()) + marshalUtil.WriteUint32(uint32(output.ConsumerCount())) + marshalUtil.WriteBool(output.Preferred()) + marshalUtil.WriteBool(output.Finalized()) + marshalUtil.WriteBool(output.Liked()) + marshalUtil.WriteBool(output.Confirmed()) + marshalUtil.WriteBool(output.Rejected()) + marshalUtil.WriteUint32(uint32(balanceCount)) + for _, balanceToMarshal := range balances { + marshalUtil.WriteBytes(balanceToMarshal.Bytes()) + } + + return marshalUtil.Bytes() +} + +// UnmarshalObjectStorageValue restores a Output from a serialized version in the ObjectStorage with parts of the object +// being stored in its key rather than the content of the database to reduce storage requirements. +func (output *Output) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + if output.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { + return + } + if output.solid, err = marshalUtil.ReadBool(); err != nil { + return + } + if output.solidificationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if output.firstConsumer, err = transaction.ParseID(marshalUtil); err != nil { + return + } + consumerCount, err := marshalUtil.ReadUint32() + if err != nil { + return + } + if output.preferred, err = marshalUtil.ReadBool(); err != nil { + return + } + if output.finalized, err = marshalUtil.ReadBool(); err != nil { + return + } + if output.liked, err = marshalUtil.ReadBool(); err != nil { + return + } + if output.confirmed, err = marshalUtil.ReadBool(); err != nil { + return + } + if output.rejected, err = marshalUtil.ReadBool(); err != nil { + return + } + output.consumerCount = int(consumerCount) + balanceCount, err := marshalUtil.ReadUint32() + if err != nil { + return + } + output.balances = make([]*balance.Balance, balanceCount) + for i := uint32(0); i < balanceCount; i++ { + output.balances[i], err = balance.Parse(marshalUtil) + if err != nil { + return + } + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Update is disabled and panics if it ever gets called - it is required to match StorableObject interface. +func (output *Output) Update(other objectstorage.StorableObject) { + panic("this object should never be updated") +} + +func (output *Output) String() string { + return stringify.Struct("Output", + stringify.StructField("address", output.Address()), + stringify.StructField("transactionId", output.TransactionID()), + stringify.StructField("branchId", output.BranchID()), + stringify.StructField("solid", output.Solid()), + stringify.StructField("solidificationTime", output.SolidificationTime()), + stringify.StructField("balances", output.Balances()), + ) +} + +// define contract (ensure that the struct fulfills the given interface) +var _ objectstorage.StorableObject = &Output{} + +// region CachedOutput ///////////////////////////////////////////////////////////////////////////////////////////////// + +// CachedOutput is a wrapper for the generic CachedObject returned by the objectstorage, that overrides the accessor +// methods, with a type-casted one. +type CachedOutput struct { + objectstorage.CachedObject +} + +// Unwrap is the type-casted equivalent of Get. It returns nil if the object does not exist. +func (cachedOutput *CachedOutput) Unwrap() *Output { + untypedObject := cachedOutput.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*Output) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject +} + +// Consume unwraps the CachedObject and passes a type-casted version to the consumer (if the object is not empty - it +// exists). It automatically releases the object when the consumer finishes. +func (cachedOutput *CachedOutput) Consume(consumer func(output *Output)) (consumed bool) { + return cachedOutput.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Output)) + }) +} + +// CachedOutputs represents a collection of CachedOutputs. +type CachedOutputs map[transaction.OutputID]*CachedOutput + +// Consume iterates over the CachedObjects, unwraps them and passes a type-casted version to the consumer (if the object +// is not empty - it exists). It automatically releases the object when the consumer finishes. It returns true, if at +// least one object was consumed. +func (cachedOutputs CachedOutputs) Consume(consumer func(output *Output)) (consumed bool) { + for _, cachedOutput := range cachedOutputs { + consumed = cachedOutput.Consume(func(output *Output) { + consumer(output) + }) || consumed + } + + return +} + +// Release is a utility function, that allows us to release all CachedObjects in the collection. +func (cachedOutputs CachedOutputs) Release(force ...bool) { + for _, cachedOutput := range cachedOutputs { + cachedOutput.Release(force...) + } +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dapps/valuetransfers/packages/tangle/output_test.go b/dapps/valuetransfers/packages/tangle/output_test.go new file mode 100644 index 0000000000000000000000000000000000000000..47918395b92a13adbf8164933e7cb3c2ebc546e4 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/output_test.go @@ -0,0 +1,45 @@ +package tangle + +import ( + "testing" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/stretchr/testify/assert" +) + +func TestNewOutput(t *testing.T) { + randomAddress := address.Random() + randomTransactionID := transaction.RandomID() + + output := NewOutput(randomAddress, randomTransactionID, branchmanager.MasterBranchID, []*balance.Balance{ + balance.New(balance.ColorIOTA, 1337), + }) + + assert.Equal(t, randomAddress, output.Address()) + assert.Equal(t, randomTransactionID, output.TransactionID()) + assert.Equal(t, false, output.Solid()) + assert.Equal(t, time.Time{}, output.SolidificationTime()) + assert.Equal(t, []*balance.Balance{ + balance.New(balance.ColorIOTA, 1337), + }, output.Balances()) + + assert.Equal(t, true, output.setSolid(true)) + assert.Equal(t, false, output.setSolid(true)) + assert.Equal(t, true, output.Solid()) + assert.NotEqual(t, time.Time{}, output.SolidificationTime()) + + clonedOutput, _, err := OutputFromBytes(output.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, output.Address(), clonedOutput.Address()) + assert.Equal(t, output.TransactionID(), clonedOutput.TransactionID()) + assert.Equal(t, output.Solid(), clonedOutput.Solid()) + assert.Equal(t, output.SolidificationTime().Round(time.Second), clonedOutput.SolidificationTime().Round(time.Second)) + assert.Equal(t, output.Balances(), clonedOutput.Balances()) +} diff --git a/dapps/valuetransfers/packages/tangle/payloadapprover.go b/dapps/valuetransfers/packages/tangle/payloadapprover.go new file mode 100644 index 0000000000000000000000000000000000000000..572249db087a5d3ea065c823b7803e387261a852 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/payloadapprover.go @@ -0,0 +1,168 @@ +package tangle + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" +) + +// PayloadApprover is a database entity, that allows us to keep track of the "tangle structure" by encoding which +// payload approves which other payload. It allows us to traverse the tangle in the opposite direction of the referenced +// trunk and branch payloads. +type PayloadApprover struct { + objectstorage.StorableObjectFlags + + storageKey []byte + referencedPayloadID payload.ID + approvingPayloadID payload.ID +} + +// NewPayloadApprover creates an approver object that encodes a single relation between an approved and an approving payload. +func NewPayloadApprover(referencedPayload payload.ID, approvingPayload payload.ID) *PayloadApprover { + marshalUtil := marshalutil.New(payload.IDLength + payload.IDLength) + marshalUtil.WriteBytes(referencedPayload.Bytes()) + marshalUtil.WriteBytes(approvingPayload.Bytes()) + + return &PayloadApprover{ + referencedPayloadID: referencedPayload, + approvingPayloadID: approvingPayload, + storageKey: marshalUtil.Bytes(), + } +} + +// PayloadApproverFromBytes unmarshals a PayloadApprover from a sequence of bytes. +func PayloadApproverFromBytes(bytes []byte, optionalTargetObject ...*PayloadApprover) (result *PayloadApprover, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParsePayloadApprover(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParsePayloadApprover unmarshals a PayloadApprover using the given marshalUtil (for easier marshaling/unmarshaling). +func ParsePayloadApprover(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*PayloadApprover) (result *PayloadApprover, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return PayloadApproverFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*PayloadApprover) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// PayloadApproverFromStorageKey get's called when we restore transaction metadata from the storage. +// In contrast to other database models, it unmarshals the information from the key and does not use the UnmarshalObjectStorageValue +// method. +func PayloadApproverFromStorageKey(key []byte, optionalTargetObject ...*PayloadApprover) (result *PayloadApprover, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &PayloadApprover{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to PayloadApproverFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.referencedPayloadID, err = payload.ParseID(marshalUtil); err != nil { + return + } + if result.approvingPayloadID, err = payload.ParseID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + result.storageKey = marshalutil.New(key[:consumedBytes]).Bytes(true) + + return +} + +// ApprovingPayloadID returns the identifier of the approving payload. +func (payloadApprover *PayloadApprover) ApprovingPayloadID() payload.ID { + return payloadApprover.approvingPayloadID +} + +// ObjectStorageKey returns the key that is used to store the object in the database. +// It is required to match StorableObject interface. +func (payloadApprover *PayloadApprover) ObjectStorageKey() []byte { + return payloadApprover.storageKey +} + +// ObjectStorageValue is implemented to conform with the StorableObject interface, but it does not really do anything, +// since all of the information about an approver are stored in the "key". +func (payloadApprover *PayloadApprover) ObjectStorageValue() (data []byte) { + return +} + +// UnmarshalObjectStorageValue is implemented to conform with the StorableObject interface, but it does not really do +// anything, since all of the information about an approver are stored in the "key". +func (payloadApprover *PayloadApprover) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + return +} + +// Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters. +// It is required to match StorableObject interface. +func (payloadApprover *PayloadApprover) Update(other objectstorage.StorableObject) { + panic("implement me") +} + +// CachedPayloadApprover is a wrapper for the object storage, that takes care of type casting the managed objects. +// Since go does not have generics (yet), the object storage works based on the generic "interface{}" type, which means +// that we have to regularly type cast the returned objects, to match the expected type. To reduce the burden of +// manually managing these type, we create a wrapper that does this for us. This way, we can consistently handle the +// specialized types of CachedApprovers, without having to manually type cast over and over again. +type CachedPayloadApprover struct { + objectstorage.CachedObject +} + +// Retain wraps the underlying method to return a new "wrapped object". +func (cachedPayloadApprover *CachedPayloadApprover) Retain() *CachedPayloadApprover { + return &CachedPayloadApprover{cachedPayloadApprover.CachedObject.Retain()} +} + +// Consume wraps the underlying method to return the correctly typed objects in the callback. +func (cachedPayloadApprover *CachedPayloadApprover) Consume(consumer func(payload *PayloadApprover)) bool { + return cachedPayloadApprover.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*PayloadApprover)) + }) +} + +// Unwrap provides a way to "Get" a type casted version of the underlying object. +func (cachedPayloadApprover *CachedPayloadApprover) Unwrap() *PayloadApprover { + untypedTransaction := cachedPayloadApprover.Get() + if untypedTransaction == nil { + return nil + } + + typeCastedTransaction := untypedTransaction.(*PayloadApprover) + if typeCastedTransaction == nil || typeCastedTransaction.IsDeleted() { + return nil + } + + return typeCastedTransaction +} + +// CachedApprovers represents a collection of CachedPayloadApprover. +type CachedApprovers []*CachedPayloadApprover + +// Consume iterates over the CachedObjects, unwraps them and passes a type-casted version to the consumer (if the object +// is not empty - it exists). It automatically releases the object when the consumer finishes. It returns true, if at +// least one object was consumed. +func (cachedApprovers CachedApprovers) Consume(consumer func(approver *PayloadApprover)) (consumed bool) { + for _, cachedApprover := range cachedApprovers { + consumed = cachedApprover.Consume(consumer) || consumed + } + + return +} diff --git a/dapps/valuetransfers/packages/tangle/payloadmetadata.go b/dapps/valuetransfers/packages/tangle/payloadmetadata.go new file mode 100644 index 0000000000000000000000000000000000000000..be575207930db9ff5107719e43e1c623400dace3 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/payloadmetadata.go @@ -0,0 +1,377 @@ +package tangle + +import ( + "sync" + "time" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" +) + +// PayloadMetadata is a container for the metadata of a value transfer payload. +// It is used to store the information in the database. +type PayloadMetadata struct { + objectstorage.StorableObjectFlags + + payloadID payload.ID + solid bool + solidificationTime time.Time + liked bool + confirmed bool + rejected bool + branchID branchmanager.BranchID + + solidMutex sync.RWMutex + solidificationTimeMutex sync.RWMutex + likedMutex sync.RWMutex + confirmedMutex sync.RWMutex + rejectedMutex sync.RWMutex + branchIDMutex sync.RWMutex +} + +// NewPayloadMetadata creates an empty container for the metadata of a value transfer payload. +func NewPayloadMetadata(payloadID payload.ID) *PayloadMetadata { + return &PayloadMetadata{ + payloadID: payloadID, + } +} + +// PayloadMetadataFromBytes unmarshals a container with the metadata of a value transfer payload from a sequence of bytes. +// It either creates a new container or fills the optionally provided container with the parsed information. +func PayloadMetadataFromBytes(bytes []byte, optionalTargetObject ...*PayloadMetadata) (result *PayloadMetadata, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParsePayloadMetadata(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParsePayloadMetadata is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. +func ParsePayloadMetadata(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*PayloadMetadata) (result *PayloadMetadata, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return PayloadMetadataFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*PayloadMetadata) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// PayloadMetadataFromStorageKey gets called when we restore transaction metadata from the storage. The bytes and the content will be +// unmarshaled by an external caller using the binary.ObjectStorageValue interface. +func PayloadMetadataFromStorageKey(id []byte, optionalTargetObject ...*PayloadMetadata) (result *PayloadMetadata, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &PayloadMetadata{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to PayloadMetadataFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(id) + if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// PayloadID return the id of the payload that this metadata is associated to. +func (payloadMetadata *PayloadMetadata) PayloadID() payload.ID { + return payloadMetadata.payloadID +} + +// IsSolid returns true if the payload has been marked as solid. +func (payloadMetadata *PayloadMetadata) IsSolid() (result bool) { + payloadMetadata.solidMutex.RLock() + result = payloadMetadata.solid + payloadMetadata.solidMutex.RUnlock() + + return +} + +// setSolid marks a payload as either solid or not solid. +// It returns true if the solid flag was changes and automatically updates the solidificationTime as well. +func (payloadMetadata *PayloadMetadata) setSolid(solid bool) (modified bool) { + payloadMetadata.solidMutex.RLock() + if payloadMetadata.solid != solid { + payloadMetadata.solidMutex.RUnlock() + + payloadMetadata.solidMutex.Lock() + if payloadMetadata.solid != solid { + payloadMetadata.solid = solid + if solid { + payloadMetadata.solidificationTimeMutex.Lock() + payloadMetadata.solidificationTime = time.Now() + payloadMetadata.solidificationTimeMutex.Unlock() + } + + payloadMetadata.SetModified() + + modified = true + } + payloadMetadata.solidMutex.Unlock() + + } else { + payloadMetadata.solidMutex.RUnlock() + } + + return +} + +// SolidificationTime returns the time when the payload was marked to be solid. +func (payloadMetadata *PayloadMetadata) SolidificationTime() time.Time { + payloadMetadata.solidificationTimeMutex.RLock() + defer payloadMetadata.solidificationTimeMutex.RUnlock() + + return payloadMetadata.solidificationTime +} + +// Liked returns true if the Payload was marked as liked. +func (payloadMetadata *PayloadMetadata) Liked() bool { + payloadMetadata.likedMutex.RLock() + defer payloadMetadata.likedMutex.RUnlock() + + return payloadMetadata.liked +} + +// setLiked modifies the liked flag of the given Payload. It returns true if the value has been updated. +func (payloadMetadata *PayloadMetadata) setLiked(liked bool) (modified bool) { + payloadMetadata.likedMutex.RLock() + if payloadMetadata.liked == liked { + payloadMetadata.likedMutex.RUnlock() + + return + } + + payloadMetadata.likedMutex.RUnlock() + payloadMetadata.likedMutex.Lock() + defer payloadMetadata.likedMutex.Unlock() + + if payloadMetadata.liked == liked { + return + } + + payloadMetadata.liked = liked + payloadMetadata.SetModified() + modified = true + + return +} + +// Confirmed returns true if the Payload was marked as confirmed. +func (payloadMetadata *PayloadMetadata) Confirmed() bool { + payloadMetadata.confirmedMutex.RLock() + defer payloadMetadata.confirmedMutex.RUnlock() + + return payloadMetadata.confirmed +} + +// setConfirmed modifies the confirmed flag of the given Payload. It returns true if the value has been updated. +func (payloadMetadata *PayloadMetadata) setConfirmed(confirmed bool) (modified bool) { + payloadMetadata.confirmedMutex.RLock() + if payloadMetadata.confirmed == confirmed { + payloadMetadata.confirmedMutex.RUnlock() + + return + } + + payloadMetadata.confirmedMutex.RUnlock() + payloadMetadata.confirmedMutex.Lock() + defer payloadMetadata.confirmedMutex.Unlock() + + if payloadMetadata.confirmed == confirmed { + return + } + + payloadMetadata.confirmed = confirmed + payloadMetadata.SetModified() + modified = true + + return +} + +// Rejected returns true if the Payload was marked as confirmed. +func (payloadMetadata *PayloadMetadata) Rejected() bool { + payloadMetadata.rejectedMutex.RLock() + defer payloadMetadata.rejectedMutex.RUnlock() + + return payloadMetadata.rejected +} + +// setRejected modifies the rejected flag of the given Payload. It returns true if the value has been updated. +func (payloadMetadata *PayloadMetadata) setRejected(rejected bool) (modified bool) { + payloadMetadata.rejectedMutex.RLock() + if payloadMetadata.rejected == rejected { + payloadMetadata.rejectedMutex.RUnlock() + + return + } + + payloadMetadata.rejectedMutex.RUnlock() + payloadMetadata.rejectedMutex.Lock() + defer payloadMetadata.rejectedMutex.Unlock() + + if payloadMetadata.rejected == rejected { + return + } + + payloadMetadata.rejected = rejected + payloadMetadata.SetModified() + modified = true + + return +} + +// BranchID returns the identifier of the Branch that this Payload was booked into. +func (payloadMetadata *PayloadMetadata) BranchID() branchmanager.BranchID { + payloadMetadata.branchIDMutex.RLock() + defer payloadMetadata.branchIDMutex.RUnlock() + + return payloadMetadata.branchID +} + +// setBranchID is the setter for the BranchID that the corresponding Payload is booked into. +func (payloadMetadata *PayloadMetadata) setBranchID(branchID branchmanager.BranchID) (modified bool) { + payloadMetadata.branchIDMutex.RLock() + if branchID == payloadMetadata.branchID { + payloadMetadata.branchIDMutex.RUnlock() + + return + } + + payloadMetadata.branchIDMutex.RUnlock() + payloadMetadata.branchIDMutex.Lock() + defer payloadMetadata.branchIDMutex.Unlock() + + if branchID == payloadMetadata.branchID { + return + } + + payloadMetadata.branchID = branchID + payloadMetadata.SetModified() + modified = true + + return +} + +// Bytes marshals the metadata into a sequence of bytes. +func (payloadMetadata *PayloadMetadata) Bytes() []byte { + return marshalutil.New(payload.IDLength + marshalutil.TIME_SIZE + 2*marshalutil.BOOL_SIZE + branchmanager.BranchIDLength). + WriteBytes(payloadMetadata.ObjectStorageKey()). + WriteBytes(payloadMetadata.ObjectStorageValue()). + Bytes() +} + +// String creates a human readable version of the metadata (for debug purposes). +func (payloadMetadata *PayloadMetadata) String() string { + return stringify.Struct("PayloadMetadata", + stringify.StructField("payloadId", payloadMetadata.PayloadID()), + stringify.StructField("solid", payloadMetadata.IsSolid()), + stringify.StructField("solidificationTime", payloadMetadata.SolidificationTime()), + ) +} + +// ObjectStorageKey returns the key that is used to store the object in the database. +// It is required to match StorableObject interface. +func (payloadMetadata *PayloadMetadata) ObjectStorageKey() []byte { + return payloadMetadata.payloadID.Bytes() +} + +// Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters. +// It is required to match StorableObject interface. +func (payloadMetadata *PayloadMetadata) Update(other objectstorage.StorableObject) { + panic("update forbidden") +} + +// ObjectStorageValue is required to match the encoding.BinaryMarshaler interface. +func (payloadMetadata *PayloadMetadata) ObjectStorageValue() []byte { + return marshalutil.New(marshalutil.TIME_SIZE + 4*marshalutil.BOOL_SIZE). + WriteTime(payloadMetadata.SolidificationTime()). + WriteBool(payloadMetadata.IsSolid()). + WriteBool(payloadMetadata.Liked()). + WriteBool(payloadMetadata.Confirmed()). + WriteBool(payloadMetadata.Rejected()). + WriteBytes(payloadMetadata.BranchID().Bytes()). + Bytes() +} + +// UnmarshalObjectStorageValue is required to match the encoding.BinaryUnmarshaler interface. +func (payloadMetadata *PayloadMetadata) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + if payloadMetadata.solidificationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if payloadMetadata.solid, err = marshalUtil.ReadBool(); err != nil { + return + } + if payloadMetadata.liked, err = marshalUtil.ReadBool(); err != nil { + return + } + if payloadMetadata.confirmed, err = marshalUtil.ReadBool(); err != nil { + return + } + if payloadMetadata.rejected, err = marshalUtil.ReadBool(); err != nil { + return + } + if payloadMetadata.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// CachedPayloadMetadata is a wrapper for the object storage, that takes care of type casting the managed objects. +// Since go does not have generics (yet), the object storage works based on the generic "interface{}" type, which means +// that we have to regularly type cast the returned objects, to match the expected type. To reduce the burden of +// manually managing these type, we create a wrapper that does this for us. This way, we can consistently handle the +// specialized types of CachedObjects, without having to manually type cast over and over again. +type CachedPayloadMetadata struct { + objectstorage.CachedObject +} + +// Retain wraps the underlying method to return a new "wrapped object". +func (cachedPayloadMetadata *CachedPayloadMetadata) Retain() *CachedPayloadMetadata { + return &CachedPayloadMetadata{cachedPayloadMetadata.CachedObject.Retain()} +} + +// Consume wraps the underlying method to return the correctly typed objects in the callback. +func (cachedPayloadMetadata *CachedPayloadMetadata) Consume(consumer func(payloadMetadata *PayloadMetadata)) bool { + return cachedPayloadMetadata.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*PayloadMetadata)) + }) +} + +// Unwrap provides a way to "Get" a type casted version of the underlying object. +func (cachedPayloadMetadata *CachedPayloadMetadata) Unwrap() *PayloadMetadata { + untypedTransaction := cachedPayloadMetadata.Get() + if untypedTransaction == nil { + return nil + } + + typeCastedTransaction := untypedTransaction.(*PayloadMetadata) + if typeCastedTransaction == nil || typeCastedTransaction.IsDeleted() { + return nil + } + + return typeCastedTransaction +} diff --git a/dapps/valuetransfers/packages/tangle/payloadmetadata_test.go b/dapps/valuetransfers/packages/tangle/payloadmetadata_test.go new file mode 100644 index 0000000000000000000000000000000000000000..ff194d0bfa6296426045c49e745e10330b458d8d --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/payloadmetadata_test.go @@ -0,0 +1,45 @@ +package tangle + +import ( + "testing" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/stretchr/testify/assert" +) + +func TestMarshalUnmarshal(t *testing.T) { + originalMetadata := NewPayloadMetadata(payload.GenesisID) + + clonedMetadata, _, err := PayloadMetadataFromBytes(originalMetadata.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, originalMetadata.PayloadID(), clonedMetadata.PayloadID()) + assert.Equal(t, originalMetadata.IsSolid(), clonedMetadata.IsSolid()) + assert.Equal(t, originalMetadata.SolidificationTime().Round(time.Second), clonedMetadata.SolidificationTime().Round(time.Second)) + + originalMetadata.setSolid(true) + + clonedMetadata, _, err = PayloadMetadataFromBytes(originalMetadata.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, originalMetadata.PayloadID(), clonedMetadata.PayloadID()) + assert.Equal(t, originalMetadata.IsSolid(), clonedMetadata.IsSolid()) + assert.Equal(t, originalMetadata.SolidificationTime().Round(time.Second), clonedMetadata.SolidificationTime().Round(time.Second)) +} + +func TestPayloadMetadata_SetSolid(t *testing.T) { + originalMetadata := NewPayloadMetadata(payload.GenesisID) + + assert.Equal(t, false, originalMetadata.IsSolid()) + assert.Equal(t, time.Time{}, originalMetadata.SolidificationTime()) + + originalMetadata.setSolid(true) + + assert.Equal(t, true, originalMetadata.IsSolid()) + assert.Equal(t, time.Now().Round(time.Second), originalMetadata.SolidificationTime().Round(time.Second)) +} diff --git a/dapps/valuetransfers/packages/tangle/signature_filter.go b/dapps/valuetransfers/packages/tangle/signature_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..3720dab3a1923799579df560a72378d9e609541a --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/signature_filter.go @@ -0,0 +1,98 @@ +package tangle + +import ( + "errors" + "sync" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser" + "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/autopeering/peer" +) + +// SignatureFilter represents a filter for the MessageParser that filters out transactions with an invalid signature. +type SignatureFilter struct { + onAcceptCallback func(message *message.Message, peer *peer.Peer) + onRejectCallback func(message *message.Message, err error, peer *peer.Peer) + onAcceptCallbackMutex sync.RWMutex + onRejectCallbackMutex sync.RWMutex + workerPool async.WorkerPool +} + +// NewSignatureFilter is the constructor of the MessageFilter. +func NewSignatureFilter() *SignatureFilter { + return &SignatureFilter{} +} + +// Filter get's called whenever a new message is received. It rejects the message, if the message is not a valid value +// message. +func (filter *SignatureFilter) Filter(message *message.Message, peer *peer.Peer) { + filter.workerPool.Submit(func() { + // accept message if the message is not a value message (it will be checked by other filters) + valuePayload := message.Payload() + if valuePayload.Type() != payload.Type { + filter.getAcceptCallback()(message, peer) + + return + } + + // reject if the payload can not be casted to a ValuePayload (invalid payload) + typeCastedValuePayload, ok := valuePayload.(*payload.Payload) + if !ok { + filter.getRejectCallback()(message, errors.New("invalid value message"), peer) + + return + } + + // reject message if it contains a transaction with invalid signatures + if !typeCastedValuePayload.Transaction().SignaturesValid() { + filter.getRejectCallback()(message, errors.New("invalid transaction signatures"), peer) + + return + } + + // if all previous checks passed: accept message + filter.getAcceptCallback()(message, peer) + }) +} + +// OnAccept registers the given callback as the acceptance function of the filter. +func (filter *SignatureFilter) OnAccept(callback func(message *message.Message, peer *peer.Peer)) { + filter.onAcceptCallbackMutex.Lock() + defer filter.onAcceptCallbackMutex.Unlock() + + filter.onAcceptCallback = callback +} + +// OnReject registers the given callback as the rejection function of the filter. +func (filter *SignatureFilter) OnReject(callback func(message *message.Message, err error, peer *peer.Peer)) { + filter.onRejectCallbackMutex.Lock() + defer filter.onRejectCallbackMutex.Unlock() + + filter.onRejectCallback = callback +} + +// Shutdown shuts down the filter. +func (filter *SignatureFilter) Shutdown() { + filter.workerPool.ShutdownGracefully() +} + +// getAcceptCallback returns the callback that is executed when a message passes the filter. +func (filter *SignatureFilter) getAcceptCallback() func(message *message.Message, peer *peer.Peer) { + filter.onAcceptCallbackMutex.RLock() + defer filter.onAcceptCallbackMutex.RUnlock() + + return filter.onAcceptCallback +} + +// getRejectCallback returns the callback that is executed when a message is blocked by the filter. +func (filter *SignatureFilter) getRejectCallback() func(message *message.Message, err error, peer *peer.Peer) { + filter.onRejectCallbackMutex.RLock() + defer filter.onRejectCallbackMutex.RUnlock() + + return filter.onRejectCallback +} + +// interface contract (allow the compiler to check if the implementation has all of the required methods). +var _ messageparser.MessageFilter = &SignatureFilter{} diff --git a/dapps/valuetransfers/packages/tangle/signature_filter_test.go b/dapps/valuetransfers/packages/tangle/signature_filter_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4002da4add5d6724fa1dec9c0447ec110024eb46 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/signature_filter_test.go @@ -0,0 +1,175 @@ +package tangle + +import ( + "sync" + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + valuePayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser" + messagePayload "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tipselector" + "github.com/iotaledger/hive.go/autopeering/peer" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/identity" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/stretchr/testify/require" +) + +func TestSignatureFilter(t *testing.T) { + // create parser + messageParser := newSyncMessageParser(NewSignatureFilter()) + + // create helper instances + seed := wallet.NewSeed() + messageFactory := messagefactory.New(mapdb.NewMapDB(), []byte("sequenceKey"), identity.GenerateLocalIdentity(), tipselector.New()) + + // 1. test value message without signatures + { + // create unsigned transaction + tx := transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(0), transaction.GenesisID), + ), + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(1): { + balance.New(balance.ColorIOTA, 1337), + }, + }), + ) + + // parse message bytes + accepted, _, _, err := messageParser.Parse(messageFactory.IssuePayload(valuePayload.New(valuePayload.GenesisID, valuePayload.GenesisID, tx)).Bytes(), &peer.Peer{}) + + // check results (should be rejected) + require.Equal(t, false, accepted) + require.NotNil(t, err) + require.Equal(t, "invalid transaction signatures", err.Error()) + } + + // 2. test value message with signatures + { + // create signed transaction + tx := transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(0), transaction.GenesisID), + ), + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(1): { + balance.New(balance.ColorIOTA, 1337), + }, + }), + ) + tx.Sign(signaturescheme.ED25519(*seed.KeyPair(0))) + + // parse message bytes + accepted, _, _, err := messageParser.Parse(messageFactory.IssuePayload(valuePayload.New(valuePayload.GenesisID, valuePayload.GenesisID, tx)).Bytes(), &peer.Peer{}) + + // check results (should be accepted) + require.Equal(t, true, accepted) + require.Nil(t, err) + } + + // 3. test message with an invalid value payload + { + // create a data payload + marshalUtil := marshalutil.New(messagePayload.NewData([]byte("test")).Bytes()) + + // set the type to be a value payload + marshalUtil.WriteSeek(0) + marshalUtil.WriteUint32(valuePayload.Type) + + // parse modified bytes back into a payload object + dataPayload, err, _ := messagePayload.DataFromBytes(marshalUtil.Bytes()) + require.NoError(t, err) + + // parse message bytes + accepted, _, _, err := messageParser.Parse(messageFactory.IssuePayload(dataPayload).Bytes(), &peer.Peer{}) + + // check results (should be rejected) + require.Equal(t, false, accepted) + require.NotNil(t, err) + require.Equal(t, "invalid value message", err.Error()) + } +} + +// newSyncMessageParser creates a wrapped MessageParser that works synchronously by using a WaitGroup to wait for the +// parse result. +func newSyncMessageParser(messageFilters ...messageparser.MessageFilter) (tester *syncMessageParser) { + // initialize MessageParser + messageParser := messageparser.New() + for _, messageFilter := range messageFilters { + messageParser.AddMessageFilter(messageFilter) + } + + // create wrapped result + tester = &syncMessageParser{ + messageParser: messageParser, + } + + // setup async behavior (store result + mark WaitGroup done) + messageParser.Events.BytesRejected.Attach(events.NewClosure(func(bytes []byte, err error, peer *peer.Peer) { + tester.result = &messageParserResult{ + accepted: false, + message: nil, + peer: peer, + err: err, + } + + tester.wg.Done() + })) + messageParser.Events.MessageRejected.Attach(events.NewClosure(func(message *message.Message, err error, peer *peer.Peer) { + tester.result = &messageParserResult{ + accepted: false, + message: message, + peer: peer, + err: err, + } + + tester.wg.Done() + })) + messageParser.Events.MessageParsed.Attach(events.NewClosure(func(message *message.Message, peer *peer.Peer) { + tester.result = &messageParserResult{ + accepted: true, + message: message, + peer: peer, + err: nil, + } + + tester.wg.Done() + })) + + return +} + +// syncMessageParser is a wrapper for the MessageParser that allows to parse Messages synchronously. +type syncMessageParser struct { + messageParser *messageparser.MessageParser + result *messageParserResult + wg sync.WaitGroup +} + +// Parse parses the message bytes into a message. It either gets accepted or rejected. +func (tester *syncMessageParser) Parse(messageBytes []byte, peer *peer.Peer) (bool, *message.Message, *peer.Peer, error) { + tester.wg.Add(1) + tester.messageParser.Parse(messageBytes, peer) + tester.wg.Wait() + + return tester.result.accepted, tester.result.message, tester.result.peer, tester.result.err +} + +// messageParserResult is a struct that stores the results of a parsing operation, so we can return them after the +// WaitGroup is done waiting. +type messageParserResult struct { + accepted bool + message *message.Message + peer *peer.Peer + err error +} diff --git a/dapps/valuetransfers/packages/tangle/snapshot.go b/dapps/valuetransfers/packages/tangle/snapshot.go new file mode 100644 index 0000000000000000000000000000000000000000..b13df4d81409167068c882c8c893767c030cfcaa --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/snapshot.go @@ -0,0 +1,125 @@ +package tangle + +import ( + "encoding/binary" + "fmt" + "io" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" +) + +// Snapshot defines a snapshot of the ledger state. +type Snapshot map[transaction.ID]map[address.Address][]*balance.Balance + +// WriteTo writes the snapshot data to the given writer in the following format: +// transaction_count(int64) +// -> transaction_count * transaction_id(32byte) +// ->address_count(int64) +// ->address_count * address(33byte) +// ->balance_count(int64) +// ->balance_count * value(int64)+color(32byte) +func (s Snapshot) WriteTo(writer io.Writer) (int64, error) { + var bytesWritten int64 + transactionCount := len(s) + if err := binary.Write(writer, binary.LittleEndian, int64(transactionCount)); err != nil { + return 0, fmt.Errorf("unable to write transactions count: %w", err) + } + bytesWritten += 8 + for txID, addresses := range s { + if err := binary.Write(writer, binary.LittleEndian, txID); err != nil { + return bytesWritten, fmt.Errorf("unable to write transaction ID: %w", err) + } + bytesWritten += transaction.IDLength + if err := binary.Write(writer, binary.LittleEndian, int64(len(addresses))); err != nil { + return bytesWritten, fmt.Errorf("unable to write address count: %w", err) + } + bytesWritten += 8 + for addr, balances := range addresses { + if err := binary.Write(writer, binary.LittleEndian, addr); err != nil { + return bytesWritten, fmt.Errorf("unable to write address: %w", err) + } + bytesWritten += address.Length + if err := binary.Write(writer, binary.LittleEndian, int64(len(balances))); err != nil { + return bytesWritten, fmt.Errorf("unable to write balance count: %w", err) + } + bytesWritten += 8 + for _, bal := range balances { + if err := binary.Write(writer, binary.LittleEndian, bal.Value); err != nil { + return bytesWritten, fmt.Errorf("unable to write balance value: %w", err) + } + bytesWritten += 8 + if err := binary.Write(writer, binary.LittleEndian, bal.Color); err != nil { + return bytesWritten, fmt.Errorf("unable to write balance color: %w", err) + } + bytesWritten += balance.ColorLength + } + } + } + + return bytesWritten, nil +} + +// ReadFrom reads the snapshot bytes from the given reader. +// This function overrides existing content of the snapshot. +func (s Snapshot) ReadFrom(reader io.Reader) (int64, error) { + var bytesRead int64 + var transactionCount int64 + if err := binary.Read(reader, binary.LittleEndian, &transactionCount); err != nil { + return 0, fmt.Errorf("unable to read transaction count: %w", err) + } + bytesRead += 8 + + var i int64 + for ; i < transactionCount; i++ { + txIDBytes := make([]byte, transaction.IDLength) + if err := binary.Read(reader, binary.LittleEndian, txIDBytes); err != nil { + return bytesRead, fmt.Errorf("unable to read transaction ID: %w", err) + } + bytesRead += transaction.IDLength + var addrCount int64 + if err := binary.Read(reader, binary.LittleEndian, &addrCount); err != nil { + return bytesRead, fmt.Errorf("unable to read address count: %w", err) + } + bytesRead += 8 + txAddrMap := make(map[address.Address][]*balance.Balance, addrCount) + var j int64 + for ; j < addrCount; j++ { + addrBytes := make([]byte, address.Length) + if err := binary.Read(reader, binary.LittleEndian, addrBytes); err != nil { + return bytesRead, fmt.Errorf("unable to read address: %w", err) + } + bytesRead += address.Length + var balanceCount int64 + if err := binary.Read(reader, binary.LittleEndian, &balanceCount); err != nil { + return bytesRead, fmt.Errorf("unable to read balance count: %w", err) + } + bytesRead += 8 + + balances := make([]*balance.Balance, balanceCount) + var k int64 + for ; k < balanceCount; k++ { + var value int64 + if err := binary.Read(reader, binary.LittleEndian, &value); err != nil { + return bytesRead, fmt.Errorf("unable to read balance value: %w", err) + } + bytesRead += 8 + color := balance.Color{} + if err := binary.Read(reader, binary.LittleEndian, &color); err != nil { + return bytesRead, fmt.Errorf("unable to read balance color: %w", err) + } + bytesRead += balance.ColorLength + balances[k] = &balance.Balance{Value: value, Color: color} + } + addr := address.Address{} + copy(addr[:], addrBytes) + txAddrMap[addr] = balances + } + txID := transaction.ID{} + copy(txID[:], txIDBytes) + s[txID] = txAddrMap + } + + return bytesRead, nil +} diff --git a/dapps/valuetransfers/packages/tangle/snapshot_test.go b/dapps/valuetransfers/packages/tangle/snapshot_test.go new file mode 100644 index 0000000000000000000000000000000000000000..7ef8b153864d90fdfebd5034ec22ab676f87f6bb --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/snapshot_test.go @@ -0,0 +1,88 @@ +package tangle + +import ( + "bytes" + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/stretchr/testify/assert" +) + +func TestLoadSnapshot(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + snapshot := map[transaction.ID]map[address.Address][]*balance.Balance{ + transaction.GenesisID: { + address.Random(): []*balance.Balance{ + balance.New(balance.ColorIOTA, 337), + }, + + address.Random(): []*balance.Balance{ + balance.New(balance.ColorIOTA, 1000), + balance.New(balance.ColorIOTA, 1000), + }, + }, + } + tangle.LoadSnapshot(snapshot) + + // check whether outputs can be retrieved from tangle + for addr, balances := range snapshot[transaction.GenesisID] { + cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(addr, transaction.GenesisID)) + cachedOutput.Consume(func(output *Output) { + assert.Equal(t, addr, output.Address()) + assert.ElementsMatch(t, balances, output.Balances()) + assert.True(t, output.Solid()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID()) + }) + } +} + +func TestSnapshotMarshalUnmarshal(t *testing.T) { + const genesisBalance = 1000000000 + seed := wallet.NewSeed() + genesisAddr := seed.Address(GENESIS) + + snapshot := Snapshot{ + transaction.GenesisID: { + genesisAddr: { + balance.New(balance.ColorIOTA, genesisBalance), + }, + }, + } + + // includes txs count + const int64ByteSize = 8 + expectedLength := int64ByteSize + for _, addresses := range snapshot { + // tx id + expectedLength += transaction.IDLength + // addr count + expectedLength += int64ByteSize + for _, balances := range addresses { + // addr + expectedLength += address.Length + // balance count + expectedLength += int64ByteSize + // balances + expectedLength += len(balances) * (int64ByteSize + balance.ColorLength) + } + } + + var buf bytes.Buffer + written, err := snapshot.WriteTo(&buf) + assert.NoError(t, err, "writing the snapshot to the buffer should succeed") + assert.EqualValues(t, expectedLength, written, "written byte count should match the expected count") + + snapshotFromBytes := Snapshot{} + read, err := snapshotFromBytes.ReadFrom(&buf) + assert.NoError(t, err, "expected no error from reading valid snapshot bytes") + assert.EqualValues(t, expectedLength, read, "read byte count should match the expected count") + + // check that the source and unmarshaled snapshot are equivalent + assert.Equal(t, snapshot, snapshotFromBytes) +} diff --git a/dapps/valuetransfers/packages/tangle/tangle.go b/dapps/valuetransfers/packages/tangle/tangle.go new file mode 100644 index 0000000000000000000000000000000000000000..877d9fd07fbe2ab0ce64090a473ed3342fd9799e --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/tangle.go @@ -0,0 +1,2008 @@ +package tangle + +import ( + "container/list" + "errors" + "fmt" + "math" + + "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/kvstore" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/types" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/packages/binary/storageprefix" +) + +var ( + // ErrTransactionDoesNotSpendAllFunds is returned if a transaction does not spend all of its inputs. + ErrTransactionDoesNotSpendAllFunds = errors.New("transaction does not spend all funds from inputs") + // ErrInvalidTransactionSignature is returned if the signature of a transaction is invalid. + ErrInvalidTransactionSignature = errors.New("invalid transaction signatures") +) + +// Tangle represents the value tangle that consists out of value payloads. +// It is an independent ontology, that lives inside the tangle. +type Tangle struct { + branchManager *branchmanager.BranchManager + + payloadStorage *objectstorage.ObjectStorage + payloadMetadataStorage *objectstorage.ObjectStorage + approverStorage *objectstorage.ObjectStorage + missingPayloadStorage *objectstorage.ObjectStorage + transactionStorage *objectstorage.ObjectStorage + transactionMetadataStorage *objectstorage.ObjectStorage + attachmentStorage *objectstorage.ObjectStorage + outputStorage *objectstorage.ObjectStorage + consumerStorage *objectstorage.ObjectStorage + + Events *Events + + workerPool async.WorkerPool +} + +// New is the constructor of a Tangle and creates a new Tangle object from the given details. +func New(store kvstore.KVStore) (tangle *Tangle) { + osFactory := objectstorage.NewFactory(store, storageprefix.ValueTransfers) + + tangle = &Tangle{ + branchManager: branchmanager.New(store), + + payloadStorage: osFactory.New(osPayload, osPayloadFactory, objectstorage.CacheTime(cacheTime)), + payloadMetadataStorage: osFactory.New(osPayloadMetadata, osPayloadMetadataFactory, objectstorage.CacheTime(cacheTime)), + missingPayloadStorage: osFactory.New(osMissingPayload, osMissingPayloadFactory, objectstorage.CacheTime(cacheTime)), + approverStorage: osFactory.New(osApprover, osPayloadApproverFactory, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(payload.IDLength, payload.IDLength), objectstorage.KeysOnly(true)), + transactionStorage: osFactory.New(osTransaction, osTransactionFactory, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + transactionMetadataStorage: osFactory.New(osTransactionMetadata, osTransactionMetadataFactory, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + attachmentStorage: osFactory.New(osAttachment, osAttachmentFactory, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(transaction.IDLength, payload.IDLength), osLeakDetectionOption), + outputStorage: osFactory.New(osOutput, osOutputFactory, OutputKeyPartitions, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + consumerStorage: osFactory.New(osConsumer, osConsumerFactory, ConsumerPartitionKeys, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + + Events: newEvents(), + } + tangle.setupDAGSynchronization() + + // TODO: CHANGE BACK TO MULTI THREADING ONCE WE FIXED LOGICAL RACE CONDITIONS + tangle.workerPool.Tune(1) + + return +} + +// region MAIN PUBLIC API ////////////////////////////////////////////////////////////////////////////////////////////// + +// AttachPayload adds a new payload to the value tangle. +func (tangle *Tangle) AttachPayload(payload *payload.Payload) { + tangle.workerPool.Submit(func() { tangle.AttachPayloadSync(payload) }) +} + +// AttachPayloadSync is the worker function that stores the payload and calls the corresponding storage events. +func (tangle *Tangle) AttachPayloadSync(payloadToStore *payload.Payload) { + // store the payload models or abort if we have seen the payload already + cachedPayload, cachedPayloadMetadata, payloadStored := tangle.storePayload(payloadToStore) + if !payloadStored { + return + } + defer cachedPayload.Release() + defer cachedPayloadMetadata.Release() + + // store transaction models or abort if we have seen this attachment already (nil == was not stored) + cachedTransaction, cachedTransactionMetadata, cachedAttachment, transactionIsNew := tangle.storeTransactionModels(payloadToStore) + defer cachedTransaction.Release() + defer cachedTransactionMetadata.Release() + if cachedAttachment == nil { + return + } + defer cachedAttachment.Release() + + // store the references between the different entities (we do this after the actual entities were stored, so that + // all the metadata models exist in the database as soon as the entities are reachable by walks). + tangle.storePayloadReferences(payloadToStore) + + // trigger events + if tangle.missingPayloadStorage.DeleteIfPresent(payloadToStore.ID().Bytes()) { + tangle.Events.MissingPayloadReceived.Trigger(cachedPayload, cachedPayloadMetadata) + } + tangle.Events.PayloadAttached.Trigger(cachedPayload, cachedPayloadMetadata) + if transactionIsNew { + tangle.Events.TransactionReceived.Trigger(cachedTransaction, cachedTransactionMetadata, cachedAttachment) + } + + // check solidity + tangle.solidifyPayload(cachedPayload.Retain(), cachedPayloadMetadata.Retain(), cachedTransaction.Retain(), cachedTransactionMetadata.Retain()) +} + +// SetTransactionPreferred modifies the preferred flag of a transaction. It updates the transactions metadata, +// propagates the changes to the branch DAG and triggers an update of the liked flags in the value tangle. +func (tangle *Tangle) SetTransactionPreferred(transactionID transaction.ID, preferred bool) (modified bool, err error) { + return tangle.setTransactionPreferred(transactionID, preferred, EventSourceTangle) +} + +// SetTransactionFinalized modifies the finalized flag of a transaction. It updates the transactions metadata and +// propagates the changes to the BranchManager if the flag was updated. +func (tangle *Tangle) SetTransactionFinalized(transactionID transaction.ID) (modified bool, err error) { + return tangle.setTransactionFinalized(transactionID, EventSourceTangle) +} + +// ValuePayloadsLiked is checking if the Payloads referenced by the passed in IDs are all liked. +func (tangle *Tangle) ValuePayloadsLiked(payloadIDs ...payload.ID) (liked bool) { + for _, payloadID := range payloadIDs { + if payloadID == payload.GenesisID { + continue + } + + payloadMetadataFound := tangle.PayloadMetadata(payloadID).Consume(func(payloadMetadata *PayloadMetadata) { + liked = payloadMetadata.Liked() + }) + + if !payloadMetadataFound || !liked { + return false + } + } + + return true +} + +// ValuePayloadsConfirmed is checking if the Payloads referenced by the passed in IDs are all confirmed. +func (tangle *Tangle) ValuePayloadsConfirmed(payloadIDs ...payload.ID) (confirmed bool) { + for _, payloadID := range payloadIDs { + if payloadID == payload.GenesisID { + continue + } + + payloadMetadataFound := tangle.PayloadMetadata(payloadID).Consume(func(payloadMetadata *PayloadMetadata) { + confirmed = payloadMetadata.Confirmed() + }) + + if !payloadMetadataFound || !confirmed { + return false + } + } + + return true +} + +// BranchManager is the getter for the manager that takes care of creating and updating branches. +func (tangle *Tangle) BranchManager() *branchmanager.BranchManager { + return tangle.branchManager +} + +// LoadSnapshot creates a set of outputs in the value tangle, that are forming the genesis for future transactions. +func (tangle *Tangle) LoadSnapshot(snapshot map[transaction.ID]map[address.Address][]*balance.Balance) { + for transactionID, addressBalances := range snapshot { + for outputAddress, balances := range addressBalances { + input := NewOutput(outputAddress, transactionID, branchmanager.MasterBranchID, balances) + input.setSolid(true) + input.setBranchID(branchmanager.MasterBranchID) + input.setLiked(true) + input.setConfirmed(true) + input.setFinalized(true) + + // store output and abort if the snapshot has already been loaded earlier (output exists in the database) + cachedOutput, stored := tangle.outputStorage.StoreIfAbsent(input) + if !stored { + return + } + + cachedOutput.Release() + } + } +} + +// Fork creates a new branch from an existing transaction. +func (tangle *Tangle) Fork(transactionID transaction.ID, conflictingInputs []transaction.OutputID) (forked bool, finalized bool, err error) { + cachedTransaction := tangle.Transaction(transactionID) + cachedTransactionMetadata := tangle.TransactionMetadata(transactionID) + defer cachedTransaction.Release() + defer cachedTransactionMetadata.Release() + + tx := cachedTransaction.Unwrap() + if tx == nil { + err = fmt.Errorf("failed to load transaction '%s': %w", transactionID, ErrFatal) + + return + } + txMetadata := cachedTransactionMetadata.Unwrap() + if txMetadata == nil { + err = fmt.Errorf("failed to load metadata of transaction '%s': %w", transactionID, ErrFatal) + + return + } + + // abort if this transaction was finalized already + if txMetadata.Finalized() { + finalized = true + + return + } + + // update / create new branch + newBranchID := branchmanager.NewBranchID(tx.ID()) + cachedTargetBranch, newBranchCreated := tangle.branchManager.Fork(newBranchID, []branchmanager.BranchID{txMetadata.BranchID()}, conflictingInputs) + defer cachedTargetBranch.Release() + + // set branch to be preferred if the underlying transaction was marked as preferred + if txMetadata.Preferred() { + if _, err = tangle.branchManager.SetBranchPreferred(newBranchID, true); err != nil { + return + } + } + + // abort if the branch existed already + if !newBranchCreated { + return + } + + // move transactions to new branch + if err = tangle.moveTransactionToBranch(cachedTransaction.Retain(), cachedTransactionMetadata.Retain(), cachedTargetBranch.Retain()); err != nil { + return + } + + // trigger events + set result + tangle.Events.Fork.Trigger(cachedTransaction, cachedTransactionMetadata, cachedTargetBranch, conflictingInputs) + forked = true + + return +} + +// Prune resets the database and deletes all objects (for testing or "node resets"). +func (tangle *Tangle) Prune() (err error) { + if err = tangle.branchManager.Prune(); err != nil { + return + } + + for _, storage := range []*objectstorage.ObjectStorage{ + tangle.payloadStorage, + tangle.payloadMetadataStorage, + tangle.missingPayloadStorage, + tangle.approverStorage, + tangle.transactionStorage, + tangle.transactionMetadataStorage, + tangle.attachmentStorage, + tangle.outputStorage, + tangle.consumerStorage, + } { + if err = storage.Prune(); err != nil { + return + } + } + + return +} + +// Shutdown stops the worker pools and shuts down the object storage instances. +func (tangle *Tangle) Shutdown() *Tangle { + tangle.workerPool.ShutdownGracefully() + + for _, storage := range []*objectstorage.ObjectStorage{ + tangle.payloadStorage, + tangle.payloadMetadataStorage, + tangle.missingPayloadStorage, + tangle.approverStorage, + tangle.transactionStorage, + tangle.transactionMetadataStorage, + tangle.attachmentStorage, + tangle.outputStorage, + tangle.consumerStorage, + } { + storage.Shutdown() + } + + return tangle +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// region GETTERS/ITERATORS FOR THE STORED MODELS ////////////////////////////////////////////////////////////////////// + +// Transaction loads the given transaction from the objectstorage. +func (tangle *Tangle) Transaction(transactionID transaction.ID) *transaction.CachedTransaction { + return &transaction.CachedTransaction{CachedObject: tangle.transactionStorage.Load(transactionID.Bytes())} +} + +// TransactionMetadata retrieves the metadata of a value payload from the object storage. +func (tangle *Tangle) TransactionMetadata(transactionID transaction.ID) *CachedTransactionMetadata { + return &CachedTransactionMetadata{CachedObject: tangle.transactionMetadataStorage.Load(transactionID.Bytes())} +} + +// TransactionOutput loads the given output from the objectstorage. +func (tangle *Tangle) TransactionOutput(outputID transaction.OutputID) *CachedOutput { + return &CachedOutput{CachedObject: tangle.outputStorage.Load(outputID.Bytes())} +} + +// OutputsOnAddress retrieves all the Outputs that are associated with an address. +func (tangle *Tangle) OutputsOnAddress(address address.Address) (result CachedOutputs) { + result = make(CachedOutputs) + tangle.outputStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + outputID, _, err := transaction.OutputIDFromBytes(key) + if err != nil { + panic(err) + } + + result[outputID] = &CachedOutput{CachedObject: cachedObject} + + return true + }, address.Bytes()) + + return +} + +// Consumers retrieves the approvers of a payload from the object storage. +func (tangle *Tangle) Consumers(outputID transaction.OutputID) CachedConsumers { + consumers := make(CachedConsumers, 0) + tangle.consumerStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + consumers = append(consumers, &CachedConsumer{CachedObject: cachedObject}) + + return true + }, outputID.Bytes()) + + return consumers +} + +// Attachments retrieves the attachment of a payload from the object storage. +func (tangle *Tangle) Attachments(transactionID transaction.ID) CachedAttachments { + attachments := make(CachedAttachments, 0) + tangle.attachmentStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + attachments = append(attachments, &CachedAttachment{CachedObject: cachedObject}) + + return true + }, transactionID.Bytes()) + + return attachments +} + +// Payload retrieves a payload from the object storage. +func (tangle *Tangle) Payload(payloadID payload.ID) *payload.CachedPayload { + return &payload.CachedPayload{CachedObject: tangle.payloadStorage.Load(payloadID.Bytes())} +} + +// PayloadMetadata retrieves the metadata of a value payload from the object storage. +func (tangle *Tangle) PayloadMetadata(payloadID payload.ID) *CachedPayloadMetadata { + return &CachedPayloadMetadata{CachedObject: tangle.payloadMetadataStorage.Load(payloadID.Bytes())} +} + +// Approvers retrieves the approvers of a payload from the object storage. +func (tangle *Tangle) Approvers(payloadID payload.ID) CachedApprovers { + approvers := make(CachedApprovers, 0) + tangle.approverStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + approvers = append(approvers, &CachedPayloadApprover{CachedObject: cachedObject}) + + return true + }, payloadID.Bytes()) + + return approvers +} + +// ForeachApprovers iterates through the approvers of a payload and calls the passed in consumer function. +func (tangle *Tangle) ForeachApprovers(payloadID payload.ID, consume func(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata, transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata)) { + tangle.Approvers(payloadID).Consume(func(approver *PayloadApprover) { + approvingCachedPayload := tangle.Payload(approver.ApprovingPayloadID()) + + approvingCachedPayload.Consume(func(payload *payload.Payload) { + consume(approvingCachedPayload.Retain(), tangle.PayloadMetadata(approver.ApprovingPayloadID()), tangle.Transaction(payload.Transaction().ID()), tangle.TransactionMetadata(payload.Transaction().ID())) + }) + }) +} + +// ForEachConsumers iterates through the transactions that are consuming outputs of the given transactions +func (tangle *Tangle) ForEachConsumers(currentTransaction *transaction.Transaction, consume func(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata, transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata)) { + seenTransactions := make(map[transaction.ID]types.Empty) + currentTransaction.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + tangle.Consumers(transaction.NewOutputID(address, currentTransaction.ID())).Consume(func(consumer *Consumer) { + if _, transactionSeen := seenTransactions[consumer.TransactionID()]; !transactionSeen { + seenTransactions[consumer.TransactionID()] = types.Void + + cachedTransaction := tangle.Transaction(consumer.TransactionID()) + defer cachedTransaction.Release() + + cachedTransactionMetadata := tangle.TransactionMetadata(consumer.TransactionID()) + defer cachedTransactionMetadata.Release() + + tangle.Attachments(consumer.TransactionID()).Consume(func(attachment *Attachment) { + consume(tangle.Payload(attachment.PayloadID()), tangle.PayloadMetadata(attachment.PayloadID()), cachedTransaction.Retain(), cachedTransactionMetadata.Retain()) + }) + } + }) + + return true + }) +} + +// ForEachConsumersAndApprovers calls the passed in consumer for all payloads that either approve the given payload or +// that attach a transaction that spends outputs from the transaction inside the given payload. +func (tangle *Tangle) ForEachConsumersAndApprovers(currentPayload *payload.Payload, consume func(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata, transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata)) { + tangle.ForEachConsumers(currentPayload.Transaction(), consume) + tangle.ForeachApprovers(currentPayload.ID(), consume) +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// region DAG SYNCHRONIZATION ////////////////////////////////////////////////////////////////////////////////////////// + +// setupDAGSynchronization sets up the behavior how the branch dag and the value tangle and UTXO dag are connected. +func (tangle *Tangle) setupDAGSynchronization() { + tangle.branchManager.Events.BranchPreferred.Attach(events.NewClosure(tangle.onBranchPreferred)) + tangle.branchManager.Events.BranchUnpreferred.Attach(events.NewClosure(tangle.onBranchUnpreferred)) + tangle.branchManager.Events.BranchLiked.Attach(events.NewClosure(tangle.onBranchLiked)) + tangle.branchManager.Events.BranchDisliked.Attach(events.NewClosure(tangle.onBranchDisliked)) + tangle.branchManager.Events.BranchFinalized.Attach(events.NewClosure(tangle.onBranchFinalized)) + tangle.branchManager.Events.BranchConfirmed.Attach(events.NewClosure(tangle.onBranchConfirmed)) + tangle.branchManager.Events.BranchRejected.Attach(events.NewClosure(tangle.onBranchRejected)) +} + +// onBranchPreferred gets triggered when a branch in the branch DAG is marked as preferred. +func (tangle *Tangle) onBranchPreferred(cachedBranch *branchmanager.CachedBranch) { + tangle.propagateBranchPreferredChangesToTangle(cachedBranch, true) +} + +// onBranchUnpreferred gets triggered when a branch in the branch DAG is marked as NOT preferred. +func (tangle *Tangle) onBranchUnpreferred(cachedBranch *branchmanager.CachedBranch) { + tangle.propagateBranchPreferredChangesToTangle(cachedBranch, false) +} + +// onBranchLiked gets triggered when a branch in the branch DAG is marked as liked. +func (tangle *Tangle) onBranchLiked(cachedBranch *branchmanager.CachedBranch) { + tangle.propagateBranchedLikedChangesToTangle(cachedBranch, true) +} + +// onBranchDisliked gets triggered when a branch in the branch DAG is marked as disliked. +func (tangle *Tangle) onBranchDisliked(cachedBranch *branchmanager.CachedBranch) { + tangle.propagateBranchedLikedChangesToTangle(cachedBranch, false) +} + +// onBranchFinalized gets triggered when a branch in the branch DAG is marked as finalized. +func (tangle *Tangle) onBranchFinalized(cachedBranch *branchmanager.CachedBranch) { + tangle.propagateBranchFinalizedChangesToTangle(cachedBranch) +} + +// onBranchConfirmed gets triggered when a branch in the branch DAG is marked as confirmed. +func (tangle *Tangle) onBranchConfirmed(cachedBranch *branchmanager.CachedBranch) { + tangle.propagateBranchConfirmedRejectedChangesToTangle(cachedBranch, true) +} + +// onBranchRejected gets triggered when a branch in the branch DAG is marked as rejected. +func (tangle *Tangle) onBranchRejected(cachedBranch *branchmanager.CachedBranch) { + tangle.propagateBranchConfirmedRejectedChangesToTangle(cachedBranch, false) +} + +// propagateBranchPreferredChangesToTangle triggers the propagation of preferred status changes of a branch to the value +// tangle and its UTXO DAG. +func (tangle *Tangle) propagateBranchPreferredChangesToTangle(cachedBranch *branchmanager.CachedBranch, preferred bool) { + cachedBranch.Consume(func(branch *branchmanager.Branch) { + if !branch.IsAggregated() { + transactionID, _, err := transaction.IDFromBytes(branch.ID().Bytes()) + if err != nil { + panic(err) // this should never ever happen + } + + _, err = tangle.setTransactionPreferred(transactionID, preferred, EventSourceBranchManager) + if err != nil { + tangle.Events.Error.Trigger(err) + + return + } + } + }) +} + +// propagateBranchFinalizedChangesToTangle triggers the propagation of finalized status changes of a branch to the value +// tangle and its UTXO DAG. +func (tangle *Tangle) propagateBranchFinalizedChangesToTangle(cachedBranch *branchmanager.CachedBranch) { + cachedBranch.Consume(func(branch *branchmanager.Branch) { + if !branch.IsAggregated() { + transactionID, _, err := transaction.IDFromBytes(branch.ID().Bytes()) + if err != nil { + panic(err) // this should never ever happen + } + + _, err = tangle.setTransactionFinalized(transactionID, EventSourceBranchManager) + if err != nil { + tangle.Events.Error.Trigger(err) + + return + } + } + }) +} + +// propagateBranchedLikedChangesToTangle triggers the propagation of liked status changes of a branch to the value +// tangle and its UTXO DAG. +func (tangle *Tangle) propagateBranchedLikedChangesToTangle(cachedBranch *branchmanager.CachedBranch, liked bool) { + cachedBranch.Consume(func(branch *branchmanager.Branch) { + if !branch.IsAggregated() { + transactionID, _, err := transaction.IDFromBytes(branch.ID().Bytes()) + if err != nil { + panic(err) // this should never ever happen + } + + // propagate changes to future cone of transaction (value tangle) + tangle.propagateValuePayloadLikeUpdates(transactionID, liked) + } + }) +} + +// propagateBranchConfirmedRejectedChangesToTangle triggers the propagation of confirmed and rejected status changes of +// a branch to the value tangle and its UTXO DAG. +func (tangle *Tangle) propagateBranchConfirmedRejectedChangesToTangle(cachedBranch *branchmanager.CachedBranch, confirmed bool) { + cachedBranch.Consume(func(branch *branchmanager.Branch) { + if !branch.IsAggregated() { + transactionID, _, err := transaction.IDFromBytes(branch.ID().Bytes()) + if err != nil { + panic(err) // this should never ever happen + } + + // propagate changes to future cone of transaction (value tangle) + tangle.propagateValuePayloadConfirmedRejectedUpdates(transactionID, confirmed) + } + }) +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// region PRIVATE UTILITY METHODS ////////////////////////////////////////////////////////////////////////////////////// + +func (tangle *Tangle) setTransactionFinalized(transactionID transaction.ID, eventSource EventSource) (modified bool, err error) { + defer debugger.FunctionCall("setTransactionFinalized", transactionID, eventSource).Return() + + // retrieve metadata and consume + cachedTransactionMetadata := tangle.TransactionMetadata(transactionID) + cachedTransactionMetadata.Consume(func(metadata *TransactionMetadata) { + // update the finalized flag of the transaction + modified = metadata.setFinalized(true) + + // only propagate the changes if the flag was modified + if modified { + // set outputs to be finalized as well + tangle.Transaction(transactionID).Consume(func(tx *transaction.Transaction) { + tx.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + tangle.TransactionOutput(transaction.NewOutputID(address, transactionID)).Consume(func(output *Output) { + output.setFinalized(true) + }) + + return true + }) + }) + + // retrieve transaction from the database (for the events) + cachedTransaction := tangle.Transaction(transactionID) + defer cachedTransaction.Release() + if !cachedTransaction.Exists() { + return + } + + // trigger the corresponding event + tangle.Events.TransactionFinalized.Trigger(cachedTransaction, cachedTransactionMetadata) + + // propagate the rejected flag + if !metadata.Preferred() && !metadata.Rejected() { + tangle.propagateRejectedToTransactions(metadata.ID()) + } + + // propagate changes to value tangle and branch DAG if we were called from the tangle + // Note: if the update was triggered by a change in the branch DAG then we do not propagate the confirmed + // and rejected changes yet as those require the branch to be liked before (we instead do it in the + // BranchLiked event) + if eventSource == EventSourceTangle { + // propagate changes to the branches (UTXO DAG) + if metadata.Conflicting() { + _, err = tangle.branchManager.SetBranchFinalized(metadata.BranchID()) + if err != nil { + tangle.Events.Error.Trigger(err) + + return + } + } + + // propagate changes to future cone of transaction (value tangle) + tangle.propagateValuePayloadConfirmedRejectedUpdates(transactionID, metadata.Preferred()) + } + } + }) + + return +} + +// propagateRejectedToTransactions propagates the rejected flag to a transaction, its outputs and to its consumers. +func (tangle *Tangle) propagateRejectedToTransactions(transactionID transaction.ID) { + defer debugger.FunctionCall("propagateRejectedToTransactions", transactionID).Return() + + // initialize stack with first transaction + rejectedPropagationStack := list.New() + rejectedPropagationStack.PushBack(transactionID) + + // keep track of the added transactions so we don't add them multiple times + addedTransaction := make(map[transaction.ID]types.Empty) + + // work through stack + for rejectedPropagationStack.Len() >= 1 { + // pop the first element from the stack + firstElement := rejectedPropagationStack.Front() + rejectedPropagationStack.Remove(firstElement) + currentTransactionID := firstElement.Value.(transaction.ID) + + debugger.Print("rejectedPropagationStack.Front()", currentTransactionID) + + cachedTransactionMetadata := tangle.TransactionMetadata(currentTransactionID) + cachedTransactionMetadata.Consume(func(metadata *TransactionMetadata) { + cachedTransaction := tangle.Transaction(currentTransactionID) + cachedTransaction.Consume(func(tx *transaction.Transaction) { + if !metadata.setRejected(true) { + return + } + + if metadata.setPreferred(false) { + // set outputs to be not preferred as well + tangle.Transaction(currentTransactionID).Consume(func(tx *transaction.Transaction) { + tx.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + tangle.TransactionOutput(transaction.NewOutputID(address, currentTransactionID)).Consume(func(output *Output) { + output.setPreferred(false) + }) + + return true + }) + }) + + tangle.Events.TransactionUnpreferred.Trigger(cachedTransaction, cachedTransactionMetadata) + } + + // if the transaction is not finalized, yet then we set it to finalized + if !metadata.Finalized() { + if _, err := tangle.setTransactionFinalized(metadata.ID(), EventSourceTangle); err != nil { + tangle.Events.Error.Trigger(err) + + return + } + } + + // process all outputs + tx.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + outputID := transaction.NewOutputID(address, currentTransactionID) + + // mark the output to be rejected + tangle.TransactionOutput(outputID).Consume(func(output *Output) { + output.setRejected(true) + }) + + // queue consumers to also be rejected + tangle.Consumers(outputID).Consume(func(consumer *Consumer) { + if _, transactionAdded := addedTransaction[consumer.TransactionID()]; transactionAdded { + return + } + addedTransaction[consumer.TransactionID()] = types.Void + + rejectedPropagationStack.PushBack(consumer.TransactionID()) + }) + + return true + }) + + // trigger event + tangle.Events.TransactionRejected.Trigger(cachedTransaction, cachedTransactionMetadata) + }) + }) + } +} + +// TODO: WRITE COMMENT +func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdates(transactionID transaction.ID, confirmed bool) { + defer debugger.FunctionCall("propagateValuePayloadConfirmedRejectedUpdates", transactionID, confirmed).Return() + + // initiate stack with the attachments of the passed in transaction + propagationStack := list.New() + tangle.Attachments(transactionID).Consume(func(attachment *Attachment) { + propagationStack.PushBack(&valuePayloadPropagationStackEntry{ + CachedPayload: tangle.Payload(attachment.PayloadID()), + CachedPayloadMetadata: tangle.PayloadMetadata(attachment.PayloadID()), + CachedTransaction: tangle.Transaction(transactionID), + CachedTransactionMetadata: tangle.TransactionMetadata(transactionID), + }) + }) + + // iterate through stack (future cone of transactions) + for propagationStack.Len() >= 1 { + currentAttachmentEntry := propagationStack.Front() + tangle.propagateValuePayloadConfirmedRejectedUpdateStackEntry(propagationStack, currentAttachmentEntry.Value.(*valuePayloadPropagationStackEntry), confirmed) + propagationStack.Remove(currentAttachmentEntry) + } +} + +func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdateStackEntry(propagationStack *list.List, propagationStackEntry *valuePayloadPropagationStackEntry, confirmed bool) { + // release the entry when we are done + defer propagationStackEntry.Release() + + // unpack loaded objects and abort if the entities could not be loaded from the database + currentPayload, currentPayloadMetadata, currentTransaction, currentTransactionMetadata := propagationStackEntry.Unwrap() + if currentPayload == nil || currentPayloadMetadata == nil || currentTransaction == nil || currentTransactionMetadata == nil { + return + } + + defer debugger.FunctionCall("propagateValuePayloadConfirmedRejectedUpdateStackEntry", currentPayload.ID(), currentTransaction.ID()).Return() + + // perform different logic depending on the type of the change (liked vs dislike) + switch confirmed { + case true: + // abort if the transaction is not preferred, the branch of the payload is not liked, the referenced value payloads are not liked or the payload was marked as liked before + if !currentTransactionMetadata.Preferred() || !currentTransactionMetadata.Finalized() || !tangle.BranchManager().IsBranchConfirmed(currentPayloadMetadata.BranchID()) || !tangle.ValuePayloadsConfirmed(currentPayload.TrunkID(), currentPayload.BranchID()) || !currentPayloadMetadata.setConfirmed(true) { + return + } + + // trigger payload event + tangle.Events.PayloadConfirmed.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata) + + // propagate confirmed status to transaction and its outputs + if currentTransactionMetadata.setConfirmed(true) { + currentTransaction.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + tangle.TransactionOutput(transaction.NewOutputID(address, currentTransaction.ID())).Consume(func(output *Output) { + output.setConfirmed(true) + }) + + return true + }) + + tangle.Events.TransactionConfirmed.Trigger(propagationStackEntry.CachedTransaction, propagationStackEntry.CachedTransactionMetadata) + } + case false: + // abort if transaction is not finalized and neither of parents is rejected + if !currentTransactionMetadata.Finalized() && !(tangle.payloadRejected(currentPayload.BranchID()) || tangle.payloadRejected(currentPayload.TrunkID())) { + return + } + + // abort if the payload has been marked as disliked before + if !currentPayloadMetadata.setRejected(true) { + return + } + + tangle.Events.PayloadRejected.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata) + } + + // schedule checks of approvers and consumers + tangle.ForEachConsumersAndApprovers(currentPayload, tangle.createValuePayloadFutureConeIterator(propagationStack, make(map[payload.ID]types.Empty))) +} + +// setTransactionPreferred is an internal utility method that updates the preferred flag and triggers changes to the +// branch DAG and triggers an updates of the liked flags in the value tangle +func (tangle *Tangle) setTransactionPreferred(transactionID transaction.ID, preferred bool, eventSource EventSource) (modified bool, err error) { + // retrieve metadata and consume + cachedTransactionMetadata := tangle.TransactionMetadata(transactionID) + cachedTransactionMetadata.Consume(func(metadata *TransactionMetadata) { + // update the preferred flag of the transaction + modified = metadata.setPreferred(preferred) + + // only do something if the flag was modified + if modified { + // update outputs as well + tangle.Transaction(transactionID).Consume(func(tx *transaction.Transaction) { + tx.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + tangle.TransactionOutput(transaction.NewOutputID(address, transactionID)).Consume(func(output *Output) { + output.setPreferred(preferred) + }) + + return true + }) + }) + + // retrieve transaction from the database (for the events) + cachedTransaction := tangle.Transaction(transactionID) + defer cachedTransaction.Release() + if !cachedTransaction.Exists() { + return + } + + // trigger the correct event + if preferred { + tangle.Events.TransactionPreferred.Trigger(cachedTransaction, cachedTransactionMetadata) + } else { + tangle.Events.TransactionUnpreferred.Trigger(cachedTransaction, cachedTransactionMetadata) + } + + // propagate changes to value tangle and branch DAG if we were called from the tangle + // Note: if the update was triggered by a change in the branch DAG then we do not propagate the value + // payload changes yet as those require the branch to be liked before (we instead do it in the + // BranchLiked event) + if eventSource == EventSourceTangle { + // propagate changes to the branches (UTXO DAG) + if metadata.Conflicting() { + _, err = tangle.branchManager.SetBranchPreferred(metadata.BranchID(), preferred) + if err != nil { + tangle.Events.Error.Trigger(err) + + return + } + } + + // propagate changes to future cone of transaction (value tangle) + tangle.propagateValuePayloadLikeUpdates(transactionID, preferred) + } + } + }) + + return +} + +// propagateValuePayloadLikeUpdates updates the liked status of all value payloads attaching a certain transaction. If +// the transaction that was updated was the entry point to a branch then all value payloads inside this branch get +// updated as well (updates happen from past to presents). +func (tangle *Tangle) propagateValuePayloadLikeUpdates(transactionID transaction.ID, liked bool) { + // initiate stack with the attachments of the passed in transaction + propagationStack := list.New() + tangle.Attachments(transactionID).Consume(func(attachment *Attachment) { + propagationStack.PushBack(&valuePayloadPropagationStackEntry{ + CachedPayload: tangle.Payload(attachment.PayloadID()), + CachedPayloadMetadata: tangle.PayloadMetadata(attachment.PayloadID()), + CachedTransaction: tangle.Transaction(transactionID), + CachedTransactionMetadata: tangle.TransactionMetadata(transactionID), + }) + }) + + // iterate through stack (future cone of transactions) + for propagationStack.Len() >= 1 { + currentAttachmentEntry := propagationStack.Front() + tangle.processValuePayloadLikedUpdateStackEntry(propagationStack, liked, currentAttachmentEntry.Value.(*valuePayloadPropagationStackEntry)) + propagationStack.Remove(currentAttachmentEntry) + } +} + +// processValuePayloadLikedUpdateStackEntry is an internal utility method that processes a single entry of the +// propagation stack for the update of the liked flag when iterating through the future cone of a transactions +// attachments. It checks if a ValuePayloads has become liked (or disliked), updates the flag an schedules its future +// cone for additional checks. +func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack *list.List, liked bool, propagationStackEntry *valuePayloadPropagationStackEntry) { + // release the entry when we are done + defer propagationStackEntry.Release() + + // unpack loaded objects and abort if the entities could not be loaded from the database + currentPayload, currentPayloadMetadata, currentTransaction, currentTransactionMetadata := propagationStackEntry.Unwrap() + if currentPayload == nil || currentPayloadMetadata == nil || currentTransaction == nil || currentTransactionMetadata == nil { + return + } + + // perform different logic depending on the type of the change (liked vs dislike) + switch liked { + case true: + // abort if the transaction is not preferred, the branch of the payload is not liked, the referenced value payloads are not liked or the payload was marked as liked before + if !currentTransactionMetadata.Preferred() || !tangle.BranchManager().IsBranchLiked(currentPayloadMetadata.BranchID()) || !tangle.ValuePayloadsLiked(currentPayload.TrunkID(), currentPayload.BranchID()) || !currentPayloadMetadata.setLiked(liked) { + return + } + + // trigger payload event + tangle.Events.PayloadLiked.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata) + + // propagate liked to transaction and its outputs + if currentTransactionMetadata.setLiked(true) { + currentTransaction.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + tangle.TransactionOutput(transaction.NewOutputID(address, currentTransaction.ID())).Consume(func(output *Output) { + output.setLiked(true) + }) + + return true + }) + + // trigger event + tangle.Events.TransactionLiked.Trigger(propagationStackEntry.CachedTransaction, propagationStackEntry.CachedTransactionMetadata) + } + case false: + // abort if the payload has been marked as disliked before + if !currentPayloadMetadata.setLiked(liked) { + return + } + + tangle.Events.PayloadDisliked.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata) + + // look if we still have any liked attachments of this transaction + likedAttachmentFound := false + tangle.Attachments(currentTransaction.ID()).Consume(func(attachment *Attachment) { + tangle.PayloadMetadata(attachment.PayloadID()).Consume(func(payloadMetadata *PayloadMetadata) { + likedAttachmentFound = likedAttachmentFound || payloadMetadata.Liked() + }) + }) + + // if there are no other liked attachments of this transaction then also set it to disliked + if !likedAttachmentFound { + // propagate disliked to transaction and its outputs + if currentTransactionMetadata.setLiked(false) { + currentTransaction.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + tangle.TransactionOutput(transaction.NewOutputID(address, currentTransaction.ID())).Consume(func(output *Output) { + output.setLiked(false) + }) + + return true + }) + + // trigger event + tangle.Events.TransactionDisliked.Trigger(propagationStackEntry.CachedTransaction, propagationStackEntry.CachedTransactionMetadata) + } + } + } + + // schedule checks of approvers and consumers + tangle.ForEachConsumersAndApprovers(currentPayload, tangle.createValuePayloadFutureConeIterator(propagationStack, make(map[payload.ID]types.Empty))) +} + +// createValuePayloadFutureConeIterator returns a function that can be handed into the ForEachConsumersAndApprovers +// method, that iterates through the next level of the future cone of the given transaction and adds the found elements +// to the given stack. +func (tangle *Tangle) createValuePayloadFutureConeIterator(propagationStack *list.List, processedPayloads map[payload.ID]types.Empty) func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *CachedPayloadMetadata, cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata) { + return func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *CachedPayloadMetadata, cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata) { + // automatically release cached objects when we terminate + defer cachedPayload.Release() + defer cachedPayloadMetadata.Release() + defer cachedTransaction.Release() + defer cachedTransactionMetadata.Release() + + // abort if the payload could not be unwrapped + unwrappedPayload := cachedPayload.Unwrap() + if unwrappedPayload == nil { + return + } + + // abort if we have scheduled the check of this payload already + if _, payloadProcessedAlready := processedPayloads[unwrappedPayload.ID()]; payloadProcessedAlready { + return + } + processedPayloads[unwrappedPayload.ID()] = types.Void + + // schedule next checks + propagationStack.PushBack(&valuePayloadPropagationStackEntry{ + CachedPayload: cachedPayload.Retain(), + CachedPayloadMetadata: cachedPayloadMetadata.Retain(), + CachedTransaction: cachedTransaction.Retain(), + CachedTransactionMetadata: cachedTransactionMetadata.Retain(), + }) + } +} + +func (tangle *Tangle) payloadRejected(payloadID payload.ID) (rejected bool) { + tangle.PayloadMetadata(payloadID).Consume(func(payloadMetadata *PayloadMetadata) { + rejected = payloadMetadata.Rejected() + }) + return +} + +func (tangle *Tangle) storePayload(payloadToStore *payload.Payload) (cachedPayload *payload.CachedPayload, cachedMetadata *CachedPayloadMetadata, payloadStored bool) { + storedPayload, newPayload := tangle.payloadStorage.StoreIfAbsent(payloadToStore) + if !newPayload { + return + } + + cachedPayload = &payload.CachedPayload{CachedObject: storedPayload} + cachedMetadata = &CachedPayloadMetadata{CachedObject: tangle.payloadMetadataStorage.Store(NewPayloadMetadata(payloadToStore.ID()))} + payloadStored = true + + return +} + +func (tangle *Tangle) storeTransactionModels(solidPayload *payload.Payload) (cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata, cachedAttachment *CachedAttachment, transactionIsNew bool) { + cachedTransaction = &transaction.CachedTransaction{CachedObject: tangle.transactionStorage.ComputeIfAbsent(solidPayload.Transaction().ID().Bytes(), func(key []byte) objectstorage.StorableObject { + transactionIsNew = true + + result := solidPayload.Transaction() + result.Persist() + result.SetModified() + + return result + })} + + if transactionIsNew { + cachedTransactionMetadata = &CachedTransactionMetadata{CachedObject: tangle.transactionMetadataStorage.Store(NewTransactionMetadata(solidPayload.Transaction().ID()))} + + // store references to the consumed outputs + solidPayload.Transaction().Inputs().ForEach(func(outputId transaction.OutputID) bool { + tangle.consumerStorage.Store(NewConsumer(outputId, solidPayload.Transaction().ID())).Release() + + return true + }) + } else { + cachedTransactionMetadata = &CachedTransactionMetadata{CachedObject: tangle.transactionMetadataStorage.Load(solidPayload.Transaction().ID().Bytes())} + } + + // store a reference from the transaction to the payload that attached it or abort, if we have processed this attachment already + attachment, stored := tangle.attachmentStorage.StoreIfAbsent(NewAttachment(solidPayload.Transaction().ID(), solidPayload.ID())) + if !stored { + return + } + cachedAttachment = &CachedAttachment{CachedObject: attachment} + + return +} + +func (tangle *Tangle) storePayloadReferences(payload *payload.Payload) { + // store trunk approver + trunkID := payload.TrunkID() + tangle.approverStorage.Store(NewPayloadApprover(trunkID, payload.ID())).Release() + + // store branch approver + if branchID := payload.BranchID(); branchID != trunkID { + tangle.approverStorage.Store(NewPayloadApprover(branchID, payload.ID())).Release() + } +} + +// solidifyPayload is the worker function that solidifies the payloads (recursively from past to present). +func (tangle *Tangle) solidifyPayload(cachedPayload *payload.CachedPayload, cachedMetadata *CachedPayloadMetadata, cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata) { + // initialize the stack + solidificationStack := list.New() + solidificationStack.PushBack(&valuePayloadPropagationStackEntry{ + CachedPayload: cachedPayload, + CachedPayloadMetadata: cachedMetadata, + CachedTransaction: cachedTransaction, + CachedTransactionMetadata: cachedTransactionMetadata, + }) + + // process payloads that are supposed to be checked for solidity recursively + for solidificationStack.Len() > 0 { + currentSolidificationEntry := solidificationStack.Front() + tangle.processSolidificationStackEntry(solidificationStack, currentSolidificationEntry.Value.(*valuePayloadPropagationStackEntry)) + solidificationStack.Remove(currentSolidificationEntry) + } +} + +// deleteTransactionFutureCone removes a transaction and its whole future cone from the database (including all of the +// reference models). +func (tangle *Tangle) deleteTransactionFutureCone(transactionID transaction.ID, cause error) { + // initialize stack with current transaction + deleteStack := list.New() + deleteStack.PushBack(transactionID) + + // iterate through stack + for deleteStack.Len() >= 1 { + // pop first element from stack + currentTransactionIDEntry := deleteStack.Front() + deleteStack.Remove(currentTransactionIDEntry) + currentTransactionID := currentTransactionIDEntry.Value.(transaction.ID) + + // delete the transaction + consumers, attachments := tangle.deleteTransaction(currentTransactionID, cause) + + // queue consumers to also be deleted + for _, consumer := range consumers { + deleteStack.PushBack(consumer) + } + + // remove payload future cone + for _, attachingPayloadID := range attachments { + tangle.deletePayloadFutureCone(attachingPayloadID, cause) + } + } +} + +// deleteTransaction deletes a single transaction and all of its related models from the database. +// Note: We do not immediately remove the attachments as this is related to the Payloads and is therefore left to the +// caller to clean this up. +func (tangle *Tangle) deleteTransaction(transactionID transaction.ID, cause error) (consumers []transaction.ID, attachments []payload.ID) { + // create result + consumers = make([]transaction.ID, 0) + attachments = make([]payload.ID, 0) + + cachedTransaction := tangle.Transaction(transactionID) + cachedTransactionMetadata := tangle.TransactionMetadata(transactionID) + + // process transaction and its models + cachedTransaction.Consume(func(tx *transaction.Transaction) { + // if the removal was triggered by an invalid Transaction + if errors.Is(cause, ErrTransactionInvalid) { + tangle.Events.TransactionInvalid.Trigger(cachedTransaction, cachedTransactionMetadata, cause) + } + + // mark transaction as deleted + tx.Delete() + + // cleanup inputs + tx.Inputs().ForEach(func(outputId transaction.OutputID) bool { + // delete consumer pointers of the inputs of the current transaction + tangle.consumerStorage.Delete(marshalutil.New(transaction.OutputIDLength + transaction.IDLength).WriteBytes(outputId.Bytes()).WriteBytes(transactionID.Bytes()).Bytes()) + + return true + }) + + // introduce map to keep track of seen consumers (so we don't process them twice) + seenConsumers := make(map[transaction.ID]types.Empty) + seenConsumers[transactionID] = types.Void + + // cleanup outputs + tx.Outputs().ForEach(func(addr address.Address, balances []*balance.Balance) bool { + // delete outputs + tangle.outputStorage.Delete(marshalutil.New(address.Length + transaction.IDLength).WriteBytes(addr.Bytes()).WriteBytes(transactionID.Bytes()).Bytes()) + + // process consumers + tangle.Consumers(transaction.NewOutputID(addr, transactionID)).Consume(func(consumer *Consumer) { + // check if the transaction has been queued already + if _, consumerSeenAlready := seenConsumers[consumer.TransactionID()]; consumerSeenAlready { + return + } + seenConsumers[consumer.TransactionID()] = types.Void + + // queue consumers for deletion + consumers = append(consumers, consumer.TransactionID()) + }) + + return true + }) + }) + + // delete transaction metadata + cachedTransactionMetadata.Consume(func(metadata *TransactionMetadata) { + metadata.Delete() + }) + + // process attachments + tangle.Attachments(transactionID).Consume(func(attachment *Attachment) { + attachments = append(attachments, attachment.PayloadID()) + }) + + return +} + +// deletePayloadFutureCone removes a payload and its whole future cone from the database (including all of the reference +// models). +func (tangle *Tangle) deletePayloadFutureCone(payloadID payload.ID, cause error) { + // initialize stack with current transaction + deleteStack := list.New() + deleteStack.PushBack(payloadID) + + // iterate through stack + for deleteStack.Len() >= 1 { + // pop first element from stack + currentTransactionIDEntry := deleteStack.Front() + deleteStack.Remove(currentTransactionIDEntry) + currentPayloadID := currentTransactionIDEntry.Value.(payload.ID) + + cachedPayload := tangle.Payload(currentPayloadID) + cachedPayloadMetadata := tangle.PayloadMetadata(currentPayloadID) + + // process payload + cachedPayload.Consume(func(currentPayload *payload.Payload) { + // trigger payload invalid if it was called with an "invalid cause" + if errors.Is(cause, ErrPayloadInvalid) || errors.Is(cause, ErrTransactionInvalid) { + tangle.Events.PayloadInvalid.Trigger(cachedPayload, cachedPayloadMetadata, cause) + } + + // delete payload + currentPayload.Delete() + + // delete approvers + tangle.approverStorage.Delete(marshalutil.New(2 * payload.IDLength).WriteBytes(currentPayload.BranchID().Bytes()).WriteBytes(currentPayloadID.Bytes()).Bytes()) + if currentPayload.TrunkID() != currentPayload.BranchID() { + tangle.approverStorage.Delete(marshalutil.New(2 * payload.IDLength).WriteBytes(currentPayload.TrunkID().Bytes()).WriteBytes(currentPayloadID.Bytes()).Bytes()) + } + + // delete attachment + tangle.attachmentStorage.Delete(marshalutil.New(transaction.IDLength + payload.IDLength).WriteBytes(currentPayload.Transaction().ID().Bytes()).WriteBytes(currentPayloadID.Bytes()).Bytes()) + + // if this was the last attachment of the transaction then we also delete the transaction + if !tangle.Attachments(currentPayload.Transaction().ID()).Consume(func(attachment *Attachment) {}) { + tangle.deleteTransaction(currentPayload.Transaction().ID(), nil) + } + }) + + // delete payload metadata + cachedPayloadMetadata.Consume(func(payloadMetadata *PayloadMetadata) { + payloadMetadata.Delete() + }) + + // queue approvers + tangle.Approvers(currentPayloadID).Consume(func(approver *PayloadApprover) { + deleteStack.PushBack(approver.ApprovingPayloadID()) + }) + } +} + +// processSolidificationStackEntry processes a single entry of the solidification stack and schedules its approvers and +// consumers if necessary. +func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list.List, solidificationStackEntry *valuePayloadPropagationStackEntry) { + // release stack entry when we are done + defer solidificationStackEntry.Release() + + // unwrap and abort if any of the retrieved models are nil + currentPayload, currentPayloadMetadata, currentTransaction, currentTransactionMetadata := solidificationStackEntry.Unwrap() + if currentPayload == nil || currentPayloadMetadata == nil || currentTransaction == nil || currentTransactionMetadata == nil { + return + } + + // abort if the transaction is not solid or invalid + transactionSolid, consumedBranches, transactionSolidityErr := tangle.checkTransactionSolidity(currentTransaction, currentTransactionMetadata) + if transactionSolidityErr != nil { + tangle.deleteTransactionFutureCone(currentTransaction.ID(), transactionSolidityErr) + + return + } + if !transactionSolid { + return + } + + // abort if the payload is not solid or invalid + payloadSolid, payloadSolidityErr := tangle.payloadBecameNewlySolid(currentPayload, currentPayloadMetadata, consumedBranches) + if payloadSolidityErr != nil { + tangle.deletePayloadFutureCone(currentPayload.ID(), payloadSolidityErr) + + return + } + if !payloadSolid { + return + } + + // book the solid entities + transactionBooked, payloadBooked, decisionPending, bookingErr := tangle.book(solidificationStackEntry.Retain()) + if bookingErr != nil { + tangle.Events.Error.Trigger(bookingErr) + + return + } + + // keep track of the added payloads so we do not add them multiple times + processedPayloads := make(map[payload.ID]types.Empty) + + // trigger events and schedule check of approvers / consumers + if transactionBooked { + tangle.Events.TransactionBooked.Trigger(solidificationStackEntry.CachedTransaction, solidificationStackEntry.CachedTransactionMetadata, decisionPending) + + tangle.ForEachConsumers(currentTransaction, tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads)) + } + if payloadBooked { + tangle.ForeachApprovers(currentPayload.ID(), tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads)) + } +} + +func (tangle *Tangle) book(entitiesToBook *valuePayloadPropagationStackEntry) (transactionBooked bool, payloadBooked bool, decisionPending bool, err error) { + defer entitiesToBook.Release() + + if transactionBooked, decisionPending, err = tangle.bookTransaction(entitiesToBook.CachedTransaction.Retain(), entitiesToBook.CachedTransactionMetadata.Retain()); err != nil { + return + } + + if payloadBooked, err = tangle.bookPayload(entitiesToBook.CachedPayload.Retain(), entitiesToBook.CachedPayloadMetadata.Retain(), entitiesToBook.CachedTransactionMetadata.Retain()); err != nil { + return + } + + return +} + +func (tangle *Tangle) bookTransaction(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata) (transactionBooked bool, decisionPending bool, err error) { + defer cachedTransaction.Release() + defer cachedTransactionMetadata.Release() + + transactionToBook := cachedTransaction.Unwrap() + if transactionToBook == nil { + // TODO: explicit error var + err = errors.New("failed to unwrap transaction") + + return + } + + transactionMetadata := cachedTransactionMetadata.Unwrap() + if transactionMetadata == nil { + // TODO: explicit error var + err = errors.New("failed to unwrap transaction metadata") + + return + } + + // abort if transaction was marked as solid before + if !transactionMetadata.setSolid(true) { + return + } + + // trigger event if transaction became solid + tangle.Events.TransactionSolid.Trigger(cachedTransaction, cachedTransactionMetadata) + + consumedBranches := make(branchmanager.BranchIds) + conflictingInputs := make([]transaction.OutputID, 0) + conflictingInputsOfFirstConsumers := make(map[transaction.ID][]transaction.OutputID) + + finalizedConflictingSpenderFound := false + if !transactionToBook.Inputs().ForEach(func(outputID transaction.OutputID) bool { + cachedOutput := tangle.TransactionOutput(outputID) + defer cachedOutput.Release() + + // abort if the output could not be found + output := cachedOutput.Unwrap() + if output == nil { + err = fmt.Errorf("could not load output '%s': %w", outputID, ErrFatal) + + return false + } + + consumedBranches[output.BranchID()] = types.Void + + // register the current consumer and check if the input has been consumed before + consumerCount, firstConsumerID := output.RegisterConsumer(transactionToBook.ID()) + switch consumerCount { + // continue if we are the first consumer and there is no double spend + case 0: + return true + + // if the input has been consumed before but not been forked, yet + case 1: + // keep track of the conflicting inputs so we can fork them + if _, conflictingInputsExist := conflictingInputsOfFirstConsumers[firstConsumerID]; !conflictingInputsExist { + conflictingInputsOfFirstConsumers[firstConsumerID] = make([]transaction.OutputID, 0) + } + conflictingInputsOfFirstConsumers[firstConsumerID] = append(conflictingInputsOfFirstConsumers[firstConsumerID], outputID) + } + + // check if any of the consumers were finalized already + if !finalizedConflictingSpenderFound { + tangle.Consumers(outputID).Consume(func(consumer *Consumer) { + if !finalizedConflictingSpenderFound { + tangle.TransactionMetadata(consumer.TransactionID()).Consume(func(metadata *TransactionMetadata) { + finalizedConflictingSpenderFound = metadata.Preferred() && metadata.Finalized() + }) + } + }) + } + + // mark input as conflicting + conflictingInputs = append(conflictingInputs, outputID) + + return true + }) { + return + } + + cachedTargetBranch, err := tangle.branchManager.AggregateBranches(consumedBranches.ToList()...) + if err != nil { + return + } + defer cachedTargetBranch.Release() + + targetBranch := cachedTargetBranch.Unwrap() + if targetBranch == nil { + err = errors.New("failed to unwrap target branch") + + return + } + targetBranch.Persist() + + if len(conflictingInputs) >= 1 { + cachedTargetBranch, _ = tangle.branchManager.Fork(branchmanager.NewBranchID(transactionToBook.ID()), []branchmanager.BranchID{targetBranch.ID()}, conflictingInputs) + defer cachedTargetBranch.Release() + + targetBranch = cachedTargetBranch.Unwrap() + if targetBranch == nil { + err = errors.New("failed to inherit branches") + + return + } + } + + // book transaction into target branch + transactionMetadata.setBranchID(targetBranch.ID()) + + // create color for newly minted coins + mintedColor, _, err := balance.ColorFromBytes(transactionToBook.ID().Bytes()) + if err != nil { + panic(err) // this should never happen (a transaction id is always a valid color) + } + + // book outputs into the target branch + transactionToBook.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + // create correctly colored balances (replacing color of newly minted coins with color of transaction id) + coloredBalances := make([]*balance.Balance, len(balances)) + for i, currentBalance := range balances { + if currentBalance.Color == balance.ColorNew { + coloredBalances[i] = balance.New(mintedColor, currentBalance.Value) + } else { + coloredBalances[i] = currentBalance + } + } + + // store output + newOutput := NewOutput(address, transactionToBook.ID(), targetBranch.ID(), coloredBalances) + newOutput.setSolid(true) + tangle.outputStorage.Store(newOutput).Release() + + return true + }) + + // fork the conflicting transactions into their own branch if a decision is still pending + decisionPending = !finalizedConflictingSpenderFound + if decisionPending { + for consumerID, conflictingInputs := range conflictingInputsOfFirstConsumers { + _, decisionFinalized, forkedErr := tangle.Fork(consumerID, conflictingInputs) + if forkedErr != nil { + err = forkedErr + + return + } + + decisionPending = decisionPending || !decisionFinalized + } + } + transactionBooked = true + + return +} + +func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *CachedPayloadMetadata, cachedTransactionMetadata *CachedTransactionMetadata) (payloadBooked bool, err error) { + defer cachedPayload.Release() + defer cachedPayloadMetadata.Release() + defer cachedTransactionMetadata.Release() + + valueObject := cachedPayload.Unwrap() + valueObjectMetadata := cachedPayloadMetadata.Unwrap() + transactionMetadata := cachedTransactionMetadata.Unwrap() + + if valueObject == nil || valueObjectMetadata == nil || transactionMetadata == nil { + return + } + + branchBranchID := tangle.payloadBranchID(valueObject.BranchID()) + trunkBranchID := tangle.payloadBranchID(valueObject.TrunkID()) + transactionBranchID := transactionMetadata.BranchID() + + if branchBranchID == branchmanager.UndefinedBranchID || trunkBranchID == branchmanager.UndefinedBranchID || transactionBranchID == branchmanager.UndefinedBranchID { + return + } + + // abort if the payload has been marked as solid before + if !valueObjectMetadata.setSolid(true) { + return + } + + // trigger event if payload became solid + tangle.Events.PayloadSolid.Trigger(cachedPayload, cachedPayloadMetadata) + + cachedAggregatedBranch, err := tangle.BranchManager().AggregateBranches([]branchmanager.BranchID{branchBranchID, trunkBranchID, transactionBranchID}...) + if err != nil { + return + } + defer cachedAggregatedBranch.Release() + + aggregatedBranch := cachedAggregatedBranch.Unwrap() + if aggregatedBranch == nil { + return + } + + payloadBooked = valueObjectMetadata.setBranchID(aggregatedBranch.ID()) + + return +} + +// payloadBranchID returns the BranchID that the referenced Payload was booked into. +func (tangle *Tangle) payloadBranchID(payloadID payload.ID) branchmanager.BranchID { + if payloadID == payload.GenesisID { + return branchmanager.MasterBranchID + } + + cachedPayloadMetadata := tangle.PayloadMetadata(payloadID) + defer cachedPayloadMetadata.Release() + + payloadMetadata := cachedPayloadMetadata.Unwrap() + if payloadMetadata == nil { + + // if payload is missing and was not reported as missing, yet + if cachedMissingPayload, missingPayloadStored := tangle.missingPayloadStorage.StoreIfAbsent(NewMissingPayload(payloadID)); missingPayloadStored { + cachedMissingPayload.Consume(func(object objectstorage.StorableObject) { + tangle.Events.PayloadMissing.Trigger(object.(*MissingPayload).ID()) + }) + } + + return branchmanager.UndefinedBranchID + } + + // the BranchID is only set if the payload was also marked as solid + return payloadMetadata.BranchID() +} + +// payloadBecameNewlySolid returns true if the given payload is solid but was not marked as solid. yet. +func (tangle *Tangle) payloadBecameNewlySolid(p *payload.Payload, payloadMetadata *PayloadMetadata, transactionBranches []branchmanager.BranchID) (solid bool, err error) { + // abort if the payload was deleted + if p == nil || p.IsDeleted() || payloadMetadata == nil || payloadMetadata.IsDeleted() { + return + } + + // abort if the payload was marked as solid already + if payloadMetadata.IsSolid() { + return + } + + combinedBranches := transactionBranches + + trunkBranchID := tangle.payloadBranchID(p.TrunkID()) + if trunkBranchID == branchmanager.UndefinedBranchID { + return false, nil + } + combinedBranches = append(combinedBranches, trunkBranchID) + + branchBranchID := tangle.payloadBranchID(p.BranchID()) + if branchBranchID == branchmanager.UndefinedBranchID { + return false, nil + } + combinedBranches = append(combinedBranches, branchBranchID) + + branchesConflicting, err := tangle.branchManager.BranchesConflicting(combinedBranches...) + if err != nil { + return + } + if branchesConflicting { + err = fmt.Errorf("the payload '%s' combines conflicting versions of the ledger state: %w", p.ID(), ErrPayloadInvalid) + + return false, err + } + + solid = true + + return +} + +func (tangle *Tangle) checkTransactionSolidity(tx *transaction.Transaction, metadata *TransactionMetadata) (solid bool, consumedBranches []branchmanager.BranchID, err error) { + // abort if any of the models are nil or has been deleted + if tx == nil || tx.IsDeleted() || metadata == nil || metadata.IsDeleted() { + return + } + + // abort if we have previously determined the solidity status of the transaction already + if metadata.Solid() { + if solid = metadata.BranchID() != branchmanager.UndefinedBranchID; solid { + consumedBranches = []branchmanager.BranchID{metadata.BranchID()} + } + + return + } + + // determine the consumed inputs and balances of the transaction + inputsSolid, cachedInputs, consumedBalances, consumedBranchesMap, err := tangle.retrieveConsumedInputDetails(tx) + if err != nil || !inputsSolid { + return + } + defer cachedInputs.Release() + + // abort if the outputs are not matching the inputs + if !tangle.checkTransactionOutputs(consumedBalances, tx.Outputs()) { + err = fmt.Errorf("the outputs do not match the inputs in transaction with id '%s': %w", tx.ID(), ErrTransactionInvalid) + + return + } + + // abort if the branches are conflicting or we faced an error when checking the validity + consumedBranches = consumedBranchesMap.ToList() + branchesConflicting, err := tangle.branchManager.BranchesConflicting(consumedBranches...) + if err != nil { + return + } + if branchesConflicting { + err = fmt.Errorf("the transaction '%s' spends conflicting inputs: %w", tx.ID(), ErrTransactionInvalid) + + return + } + + // set the result to be solid and valid + solid = true + + return +} + +func (tangle *Tangle) getCachedOutputsFromTransactionInputs(tx *transaction.Transaction) (result CachedOutputs) { + result = make(CachedOutputs) + tx.Inputs().ForEach(func(inputId transaction.OutputID) bool { + result[inputId] = tangle.TransactionOutput(inputId) + + return true + }) + + return +} + +// ValidateTransactionToAttach checks that the given transaction spends all funds from its inputs and +// that its the signature is valid. +func (tangle *Tangle) ValidateTransactionToAttach(tx *transaction.Transaction) (err error) { + _, cachedInputs, consumedBalances, _, err := tangle.retrieveConsumedInputDetails(tx) + defer cachedInputs.Release() + if err != nil { + return + } + if !tangle.checkTransactionOutputs(consumedBalances, tx.Outputs()) { + err = ErrTransactionDoesNotSpendAllFunds + return + } + + if !tx.SignaturesValid() { + err = ErrInvalidTransactionSignature + return + } + return +} + +// retrieveConsumedInputDetails retrieves the details of the consumed inputs of a transaction. +func (tangle *Tangle) retrieveConsumedInputDetails(tx *transaction.Transaction) (inputsSolid bool, cachedInputs CachedOutputs, consumedBalances map[balance.Color]int64, consumedBranches branchmanager.BranchIds, err error) { + cachedInputs = tangle.getCachedOutputsFromTransactionInputs(tx) + consumedBalances = make(map[balance.Color]int64) + consumedBranches = make(branchmanager.BranchIds) + for _, cachedInput := range cachedInputs { + input := cachedInput.Unwrap() + if input == nil || !input.Solid() { + cachedInputs.Release() + + return + } + + consumedBranches[input.BranchID()] = types.Void + + // calculate the input balances + for _, inputBalance := range input.Balances() { + var newBalance int64 + if currentBalance, balanceExists := consumedBalances[inputBalance.Color]; balanceExists { + // check overflows in the numbers + if inputBalance.Value > math.MaxInt64-currentBalance { + // TODO: make it an explicit error var + err = fmt.Errorf("buffer overflow in balances of inputs: %w", ErrTransactionInvalid) + + cachedInputs.Release() + + return + } + + newBalance = currentBalance + inputBalance.Value + } else { + newBalance = inputBalance.Value + } + consumedBalances[inputBalance.Color] = newBalance + } + } + inputsSolid = true + + return +} + +// checkTransactionOutputs is a utility function that returns true, if the outputs are consuming all of the given inputs +// (the sum of all the balance changes is 0). It also accounts for the ability to "recolor" coins during the creating of +// outputs. If this function returns false, then the outputs that are defined in the transaction are invalid and the +// transaction should be removed from the ledger state. +func (tangle *Tangle) checkTransactionOutputs(inputBalances map[balance.Color]int64, outputs *transaction.Outputs) bool { + // create a variable to keep track of outputs that create a new color + var newlyColoredCoins int64 + var uncoloredCoins int64 + + // iterate through outputs and check them one by one + aborted := !outputs.ForEach(func(address address.Address, balances []*balance.Balance) bool { + for _, outputBalance := range balances { + // abort if the output creates a negative or empty output + if outputBalance.Value <= 0 { + return false + } + + // sidestep logic if we have a newly colored output (we check the supply later) + if outputBalance.Color == balance.ColorNew { + // catch overflows + if newlyColoredCoins > math.MaxInt64-outputBalance.Value { + return false + } + + newlyColoredCoins += outputBalance.Value + + continue + } + + // sidestep logic if we have ColorIOTA + if outputBalance.Color == balance.ColorIOTA { + // catch overflows + if uncoloredCoins > math.MaxInt64-outputBalance.Value { + return false + } + + uncoloredCoins += outputBalance.Value + + continue + } + + // check if the used color does not exist in our supply + availableBalance, spentColorExists := inputBalances[outputBalance.Color] + if !spentColorExists { + return false + } + + // abort if we spend more coins of the given color than we have + if availableBalance < outputBalance.Value { + return false + } + + // subtract the spent coins from the supply of this color + inputBalances[outputBalance.Color] -= outputBalance.Value + + // cleanup empty map entries (we have exhausted our funds) + if inputBalances[outputBalance.Color] == 0 { + delete(inputBalances, outputBalance.Color) + } + } + + return true + }) + + // abort if the previous checks failed + if aborted { + return false + } + + // determine the unspent inputs + var unspentCoins int64 + for _, unspentBalance := range inputBalances { + // catch overflows + if unspentCoins > math.MaxInt64-unspentBalance { + return false + } + + unspentCoins += unspentBalance + } + + // the outputs are valid if they spend all consumed funds + return unspentCoins == newlyColoredCoins+uncoloredCoins +} + +// TODO: write comment what it does +func (tangle *Tangle) moveTransactionToBranch(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata, cachedTargetBranch *branchmanager.CachedBranch) (err error) { + // push transaction that shall be moved to the stack + transactionStack := list.New() + branchStack := list.New() + branchStack.PushBack([3]interface{}{cachedTransactionMetadata.Unwrap().BranchID(), cachedTargetBranch, transactionStack}) + transactionStack.PushBack([2]interface{}{cachedTransaction, cachedTransactionMetadata}) + + // iterate through all transactions (grouped by their branch) + for branchStack.Len() >= 1 { + if err = func() error { + // retrieve branch details from stack + currentSolidificationEntry := branchStack.Front() + currentSourceBranch := currentSolidificationEntry.Value.([3]interface{})[0].(branchmanager.BranchID) + currentCachedTargetBranch := currentSolidificationEntry.Value.([3]interface{})[1].(*branchmanager.CachedBranch) + transactionStack := currentSolidificationEntry.Value.([3]interface{})[2].(*list.List) + branchStack.Remove(currentSolidificationEntry) + defer currentCachedTargetBranch.Release() + + // unpack target branch + targetBranch := currentCachedTargetBranch.Unwrap() + if targetBranch == nil { + return errors.New("failed to unpack branch") + } + + // iterate through transactions + for transactionStack.Len() >= 1 { + if err = func() error { + // retrieve transaction details from stack + currentSolidificationEntry := transactionStack.Front() + currentCachedTransaction := currentSolidificationEntry.Value.([2]interface{})[0].(*transaction.CachedTransaction) + currentCachedTransactionMetadata := currentSolidificationEntry.Value.([2]interface{})[1].(*CachedTransactionMetadata) + transactionStack.Remove(currentSolidificationEntry) + defer currentCachedTransaction.Release() + defer currentCachedTransactionMetadata.Release() + + // unwrap transaction + currentTransaction := currentCachedTransaction.Unwrap() + if currentTransaction == nil { + return errors.New("failed to unwrap transaction") + } + + // unwrap transaction metadata + currentTransactionMetadata := currentCachedTransactionMetadata.Unwrap() + if currentTransactionMetadata == nil { + return errors.New("failed to unwrap transaction metadata") + } + + // if we arrived at a nested branch + if currentTransactionMetadata.BranchID() != currentSourceBranch { + // abort if we the branch is a conflict branch or an error occurred while trying to elevate + isConflictBranch, _, elevateErr := tangle.branchManager.ElevateConflictBranch(currentTransactionMetadata.BranchID(), targetBranch.ID()) + if elevateErr != nil || isConflictBranch { + return elevateErr + } + + // determine the new branch of the transaction + newCachedTargetBranch, branchErr := tangle.calculateBranchOfTransaction(currentTransaction) + if branchErr != nil { + return branchErr + } + defer newCachedTargetBranch.Release() + + // unwrap the branch + newTargetBranch := newCachedTargetBranch.Unwrap() + if newTargetBranch == nil { + return errors.New("failed to unwrap branch") + } + newTargetBranch.Persist() + + // add the new branch (with the current transaction as a starting point to the branch stack) + newTransactionStack := list.New() + newTransactionStack.PushBack([2]interface{}{currentCachedTransaction.Retain(), currentCachedTransactionMetadata.Retain()}) + branchStack.PushBack([3]interface{}{currentTransactionMetadata.BranchID(), newCachedTargetBranch.Retain(), newTransactionStack}) + + return nil + } + + // abort if we did not modify the branch of the transaction + if !currentTransactionMetadata.setBranchID(targetBranch.ID()) { + return nil + } + + // update the payloads + tangle.updateBranchOfValuePayloadsAttachingTransaction(currentTransactionMetadata.ID()) + + // iterate through the outputs of the moved transaction + currentTransaction.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + // create reference to the output + outputID := transaction.NewOutputID(address, currentTransaction.ID()) + + // load output from database + cachedOutput := tangle.TransactionOutput(outputID) + defer cachedOutput.Release() + + // unwrap output + output := cachedOutput.Unwrap() + if output == nil { + err = fmt.Errorf("failed to load output '%s': %w", outputID, ErrFatal) + + return false + } + + // abort if the output was moved already + if !output.setBranchID(targetBranch.ID()) { + return true + } + + // schedule consumers for further checks + consumingTransactions := make(map[transaction.ID]types.Empty) + tangle.Consumers(transaction.NewOutputID(address, currentTransaction.ID())).Consume(func(consumer *Consumer) { + consumingTransactions[consumer.TransactionID()] = types.Void + }) + for transactionID := range consumingTransactions { + transactionStack.PushBack([2]interface{}{tangle.Transaction(transactionID), tangle.TransactionMetadata(transactionID)}) + } + + return true + }) + + return nil + }(); err != nil { + return err + } + } + + return nil + }(); err != nil { + return + } + } + + return +} + +// updateBranchOfValuePayloadsAttachingTransaction updates the BranchID of all payloads that attach a certain +// transaction (and its approvers). +func (tangle *Tangle) updateBranchOfValuePayloadsAttachingTransaction(transactionID transaction.ID) { + // initialize stack with the attachments of the given transaction + payloadStack := list.New() + tangle.Attachments(transactionID).Consume(func(attachment *Attachment) { + payloadStack.PushBack(tangle.Payload(attachment.PayloadID())) + }) + + // iterate through the stack to update all payloads we found + for payloadStack.Len() >= 1 { + // pop the first element from the stack + currentPayloadElement := payloadStack.Front() + payloadStack.Remove(currentPayloadElement) + + // process the found element + currentPayloadElement.Value.(*payload.CachedPayload).Consume(func(currentPayload *payload.Payload) { + // determine branches of referenced payloads + branchIDofBranch := tangle.branchIDofPayload(currentPayload.BranchID()) + branchIDofTrunk := tangle.branchIDofPayload(currentPayload.TrunkID()) + + // determine branch of contained transaction + var branchIDofTransaction branchmanager.BranchID + if !tangle.TransactionMetadata(currentPayload.Transaction().ID()).Consume(func(metadata *TransactionMetadata) { + branchIDofTransaction = metadata.BranchID() + }) { + return + } + + // abort if any of the branches is undefined + if branchIDofBranch == branchmanager.UndefinedBranchID || branchIDofTrunk == branchmanager.UndefinedBranchID || branchIDofTransaction == branchmanager.UndefinedBranchID { + return + } + + // aggregate the branches or abort if we face an error + cachedAggregatedBranch, err := tangle.branchManager.AggregateBranches(branchIDofBranch, branchIDofTrunk, branchIDofTransaction) + if err != nil { + tangle.Events.Error.Trigger(err) + + return + } + + // try to update the metadata of the payload and queue its approvers + cachedAggregatedBranch.Consume(func(branch *branchmanager.Branch) { + tangle.PayloadMetadata(currentPayload.ID()).Consume(func(payloadMetadata *PayloadMetadata) { + if !payloadMetadata.setBranchID(branch.ID()) { + return + } + + // queue approvers for recursive updates + tangle.ForeachApprovers(currentPayload.ID(), func(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata, transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + payloadMetadata.Release() + transaction.Release() + transactionMetadata.Release() + + payloadStack.PushBack(payload) + }) + }) + + }) + }) + } +} + +// branchIDofPayload returns the BranchID that a payload is booked into. +func (tangle *Tangle) branchIDofPayload(payloadID payload.ID) (branchID branchmanager.BranchID) { + if payloadID == payload.GenesisID { + return branchmanager.MasterBranchID + } + + tangle.PayloadMetadata(payloadID).Consume(func(payloadMetadata *PayloadMetadata) { + branchID = payloadMetadata.BranchID() + }) + + return +} + +func (tangle *Tangle) calculateBranchOfTransaction(currentTransaction *transaction.Transaction) (branch *branchmanager.CachedBranch, err error) { + consumedBranches := make(branchmanager.BranchIds) + if !currentTransaction.Inputs().ForEach(func(outputId transaction.OutputID) bool { + cachedTransactionOutput := tangle.TransactionOutput(outputId) + defer cachedTransactionOutput.Release() + + transactionOutput := cachedTransactionOutput.Unwrap() + if transactionOutput == nil { + err = fmt.Errorf("failed to load output '%s': %w", outputId, ErrFatal) + + return false + } + + consumedBranches[transactionOutput.BranchID()] = types.Void + + return true + }) { + return + } + + branch, err = tangle.branchManager.AggregateBranches(consumedBranches.ToList()...) + + return +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// valuePayloadPropagationStackEntry is a container for the elements in the propagation stack of ValuePayloads +type valuePayloadPropagationStackEntry struct { + CachedPayload *payload.CachedPayload + CachedPayloadMetadata *CachedPayloadMetadata + CachedTransaction *transaction.CachedTransaction + CachedTransactionMetadata *CachedTransactionMetadata +} + +// Retain creates a new container with its contained elements being retained for further use. +func (stackEntry *valuePayloadPropagationStackEntry) Retain() *valuePayloadPropagationStackEntry { + return &valuePayloadPropagationStackEntry{ + CachedPayload: stackEntry.CachedPayload.Retain(), + CachedPayloadMetadata: stackEntry.CachedPayloadMetadata.Retain(), + CachedTransaction: stackEntry.CachedTransaction.Retain(), + CachedTransactionMetadata: stackEntry.CachedTransactionMetadata.Retain(), + } +} + +// Release releases the elements in this container for being written by the objectstorage. +func (stackEntry *valuePayloadPropagationStackEntry) Release() { + stackEntry.CachedPayload.Release() + stackEntry.CachedPayloadMetadata.Release() + stackEntry.CachedTransaction.Release() + stackEntry.CachedTransactionMetadata.Release() +} + +// Unwrap retrieves the underlying StorableObjects from the cached elements in this container. +func (stackEntry *valuePayloadPropagationStackEntry) Unwrap() (payload *payload.Payload, payloadMetadata *PayloadMetadata, transaction *transaction.Transaction, transactionMetadata *TransactionMetadata) { + payload = stackEntry.CachedPayload.Unwrap() + payloadMetadata = stackEntry.CachedPayloadMetadata.Unwrap() + transaction = stackEntry.CachedTransaction.Unwrap() + transactionMetadata = stackEntry.CachedTransactionMetadata.Unwrap() + + return +} diff --git a/dapps/valuetransfers/packages/tangle/tangle_concurrency_test.go b/dapps/valuetransfers/packages/tangle/tangle_concurrency_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bf97f7bb86f032fe835e6231612efdc3cd1aea7f --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/tangle_concurrency_test.go @@ -0,0 +1,345 @@ +package tangle + +import ( + "sync" + "testing" + + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tipmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" +) + +func TestConcurrency(t *testing.T) { + // img/concurrency.png + // Builds a simple UTXO-DAG where each transaction spends exactly 1 output from genesis. + // Tips are concurrently selected (via TipManager) resulting in a moderately wide tangle depending on `threads`. + tangle := New(mapdb.NewMapDB()) + defer tangle.Shutdown() + + tipManager := tipmanager.New() + + count := 1000 + threads := 10 + countTotal := threads * count + + // initialize tangle with genesis block + outputs := make(map[address.Address][]*balance.Balance) + for i := 0; i < countTotal; i++ { + outputs[address.Random()] = []*balance.Balance{ + balance.New(balance.ColorIOTA, 1), + } + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + transactions := make([]*transaction.Transaction, countTotal) + valueObjects := make([]*payload.Payload, countTotal) + + // start threads, each working on its chunk of transaction and valueObjects + var wg sync.WaitGroup + for thread := 0; thread < threads; thread++ { + wg.Add(1) + go func(threadNo int) { + defer wg.Done() + + start := threadNo * count + end := start + count + + for i := start; i < end; i++ { + // issue transaction moving funds from genesis + tx := transaction.New( + transaction.NewInputs(inputIDs[i]), + transaction.NewOutputs( + map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + }), + ) + // use random value objects as tips (possibly created in other threads) + parent1, parent2 := tipManager.Tips() + valueObject := payload.New(parent1, parent2, tx) + + tangle.AttachPayloadSync(valueObject) + + tipManager.AddTip(valueObject) + transactions[i] = tx + valueObjects[i] = valueObject + } + }(thread) + } + + wg.Wait() + + // verify correctness + for i := 0; i < countTotal; i++ { + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions[i].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.Truef(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equalf(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if payload metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects[i].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.Truef(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equalf(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if outputs are found in database + transactions[i].Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(address, transactions[i].ID())) + assert.True(t, cachedOutput.Consume(func(output *Output) { + assert.Equalf(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances()) + assert.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.Truef(t, output.Solid(), "the output is not solid") + })) + return true + }) + + // check that all inputs are consumed exactly once + cachedInput := tangle.TransactionOutput(inputIDs[i]) + assert.True(t, cachedInput.Consume(func(output *Output) { + assert.Equalf(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances()) + assert.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.Truef(t, output.Solid(), "the output is not solid") + })) + } +} + +func TestReverseValueObjectSolidification(t *testing.T) { + // img/reverse-valueobject-solidification.png + // Builds a simple UTXO-DAG where each transaction spends exactly 1 output from genesis. + // All value objects reference the previous value object, effectively creating a chain. + // The test attaches the prepared value objects concurrently in reverse order. + tangle := New(mapdb.NewMapDB()) + defer tangle.Shutdown() + + tipManager := tipmanager.New() + + count := 1000 + threads := 5 + countTotal := threads * count + + // initialize tangle with genesis block + outputs := make(map[address.Address][]*balance.Balance) + for i := 0; i < countTotal; i++ { + outputs[address.Random()] = []*balance.Balance{ + balance.New(balance.ColorIOTA, 1), + } + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + transactions := make([]*transaction.Transaction, countTotal) + valueObjects := make([]*payload.Payload, countTotal) + + // prepare value objects + for i := 0; i < countTotal; i++ { + tx := transaction.New( + // issue transaction moving funds from genesis + transaction.NewInputs(inputIDs[i]), + transaction.NewOutputs( + map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + }), + ) + parent1, parent2 := tipManager.Tips() + valueObject := payload.New(parent1, parent2, tx) + + tipManager.AddTip(valueObject) + transactions[i] = tx + valueObjects[i] = valueObject + } + + // attach value objects in reverse order + var wg sync.WaitGroup + for thread := 0; thread < threads; thread++ { + wg.Add(1) + go func(threadNo int) { + defer wg.Done() + + for i := countTotal - 1 - threadNo; i >= 0; i -= threads { + valueObject := valueObjects[i] + tangle.AttachPayloadSync(valueObject) + } + }(thread) + } + wg.Wait() + + // verify correctness + for i := 0; i < countTotal; i++ { + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions[i].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.Truef(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equalf(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if payload metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects[i].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.Truef(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equalf(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if outputs are found in database + transactions[i].Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(address, transactions[i].ID())) + assert.True(t, cachedOutput.Consume(func(output *Output) { + assert.Equalf(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances()) + assert.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.Truef(t, output.Solid(), "the output is not solid") + })) + return true + }) + + // check that all inputs are consumed exactly once + cachedInput := tangle.TransactionOutput(inputIDs[i]) + assert.True(t, cachedInput.Consume(func(output *Output) { + assert.Equalf(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances()) + assert.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.Truef(t, output.Solid(), "the output is not solid") + })) + } +} + +func TestReverseTransactionSolidification(t *testing.T) { + testIterations := 500 + + // repeat the test a few times + for k := 0; k < testIterations; k++ { + // img/reverse-transaction-solidification.png + // Builds a UTXO-DAG with `txChains` spending outputs from the corresponding chain. + // All value objects reference the previous value object, effectively creating a chain. + // The test attaches the prepared value objects concurrently in reverse order. + + tangle := New(mapdb.NewMapDB()) + + tipManager := tipmanager.New() + + txChains := 2 + count := 10 + threads := 5 + countTotal := txChains * threads * count + + // initialize tangle with genesis block + outputs := make(map[address.Address][]*balance.Balance) + for i := 0; i < txChains; i++ { + outputs[address.Random()] = []*balance.Balance{ + balance.New(balance.ColorIOTA, 1), + } + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + transactions := make([]*transaction.Transaction, countTotal) + valueObjects := make([]*payload.Payload, countTotal) + + // create chains of transactions + for i := 0; i < count*threads; i++ { + for j := 0; j < txChains; j++ { + var tx *transaction.Transaction + + // transferring from genesis + if i == 0 { + tx = transaction.New( + transaction.NewInputs(inputIDs[j]), + transaction.NewOutputs( + map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + }), + ) + } else { + // create chains in UTXO dag + tx = transaction.New( + getTxOutputsAsInputs(transactions[i*txChains-txChains+j]), + transaction.NewOutputs( + map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + }), + ) + } + + transactions[i*txChains+j] = tx + } + } + + // prepare value objects (simple chain) + for i := 0; i < countTotal; i++ { + parent1, parent2 := tipManager.Tips() + valueObject := payload.New(parent1, parent2, transactions[i]) + + tipManager.AddTip(valueObject) + valueObjects[i] = valueObject + } + + // attach value objects in reverse order + var wg sync.WaitGroup + for thread := 0; thread < threads; thread++ { + wg.Add(1) + go func(threadNo int) { + defer wg.Done() + + for i := countTotal - 1 - threadNo; i >= 0; i -= threads { + valueObject := valueObjects[i] + tangle.AttachPayloadSync(valueObject) + } + }(thread) + } + wg.Wait() + + // verify correctness + for i := 0; i < countTotal; i++ { + // check if transaction metadata is found in database + require.Truef(t, tangle.TransactionMetadata(transactions[i].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + require.Truef(t, transactionMetadata.Solid(), "the transaction %s is not solid", transactions[i].ID().String()) + require.Equalf(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + }), "transaction metadata %s not found in database", transactions[i].ID()) + + // check if value object metadata is found in database + require.Truef(t, tangle.PayloadMetadata(valueObjects[i].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + require.Truef(t, payloadMetadata.IsSolid(), "the payload %s is not solid", valueObjects[i].ID()) + require.Equalf(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + }), "value object metadata %s not found in database", valueObjects[i].ID()) + + // check if outputs are found in database + transactions[i].Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(address, transactions[i].ID())) + require.Truef(t, cachedOutput.Consume(func(output *Output) { + // only the last outputs in chain should not be spent + if i+txChains >= countTotal { + require.Equalf(t, 0, output.ConsumerCount(), "the output should not be spent") + } else { + require.Equalf(t, 1, output.ConsumerCount(), "the output should be spent") + } + require.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances()) + require.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + require.Truef(t, output.Solid(), "the output is not solid") + }), "output not found in database for tx %s", transactions[i]) + return true + }) + } + } +} + +func getTxOutputsAsInputs(tx *transaction.Transaction) *transaction.Inputs { + outputIDs := make([]transaction.OutputID, 0) + tx.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + outputIDs = append(outputIDs, transaction.NewOutputID(address, tx.ID())) + return true + }) + + return transaction.NewInputs(outputIDs...) +} diff --git a/dapps/valuetransfers/packages/tangle/tangle_event_test.go b/dapps/valuetransfers/packages/tangle/tangle_event_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bdd3f1dfc42386262c342e644c8d298852563958 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/tangle_event_test.go @@ -0,0 +1,211 @@ +package tangle + +import ( + "reflect" + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/events" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +// eventTangle is a wrapper around Tangle used to test the triggered events. +type eventTangle struct { + mock.Mock + *Tangle + + attached []struct { + *events.Event + *events.Closure + } +} + +func newEventTangle(t *testing.T, tangle *Tangle) *eventTangle { + e := &eventTangle{Tangle: tangle} + e.Test(t) + + // attach all events + e.attach(tangle.Events.PayloadAttached, e.PayloadAttached) + e.attach(tangle.Events.PayloadSolid, e.PayloadSolid) + e.attach(tangle.Events.PayloadLiked, e.PayloadLiked) + e.attach(tangle.Events.PayloadConfirmed, e.PayloadConfirmed) + e.attach(tangle.Events.PayloadRejected, e.PayloadRejected) + e.attach(tangle.Events.PayloadDisliked, e.PayloadDisliked) + e.attach(tangle.Events.MissingPayloadReceived, e.MissingPayloadReceived) + e.attach(tangle.Events.PayloadMissing, e.PayloadMissing) + e.attach(tangle.Events.PayloadInvalid, e.PayloadInvalid) + e.attach(tangle.Events.TransactionReceived, e.TransactionReceived) + e.attach(tangle.Events.TransactionInvalid, e.TransactionInvalid) + e.attach(tangle.Events.TransactionSolid, e.TransactionSolid) + e.attach(tangle.Events.TransactionBooked, e.TransactionBooked) + e.attach(tangle.Events.TransactionPreferred, e.TransactionPreferred) + e.attach(tangle.Events.TransactionUnpreferred, e.TransactionUnpreferred) + e.attach(tangle.Events.TransactionLiked, e.TransactionLiked) + e.attach(tangle.Events.TransactionDisliked, e.TransactionDisliked) + e.attach(tangle.Events.TransactionFinalized, e.TransactionFinalized) + e.attach(tangle.Events.TransactionConfirmed, e.TransactionConfirmed) + e.attach(tangle.Events.TransactionRejected, e.TransactionRejected) + e.attach(tangle.Events.Fork, e.Fork) + e.attach(tangle.Events.Error, e.Error) + + // assure that all available events are mocked + numEvents := reflect.ValueOf(tangle.Events).Elem().NumField() + assert.Equalf(t, len(e.attached), numEvents, "not all events in Tangle.Events have been attached") + + return e +} + +// DetachAll detaches all attached event mocks. +func (e *eventTangle) DetachAll() { + for _, a := range e.attached { + a.Event.Detach(a.Closure) + } +} + +func (e *eventTangle) attach(event *events.Event, f interface{}) { + closure := events.NewClosure(f) + event.Attach(closure) + e.attached = append(e.attached, struct { + *events.Event + *events.Closure + }{event, closure}) +} + +// Expect starts a description of an expectation of the specified event being triggered. +func (e *eventTangle) Expect(eventName string, arguments ...interface{}) { + e.On(eventName, arguments...).Once() +} + +func (e *eventTangle) PayloadAttached(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap()) +} + +func (e *eventTangle) PayloadSolid(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap()) +} + +func (e *eventTangle) PayloadLiked(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap()) +} + +func (e *eventTangle) PayloadConfirmed(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap()) +} + +func (e *eventTangle) PayloadRejected(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap()) +} + +func (e *eventTangle) PayloadDisliked(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap()) +} + +func (e *eventTangle) MissingPayloadReceived(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap()) +} + +func (e *eventTangle) PayloadMissing(id payload.ID) { + e.Called(id) +} + +func (e *eventTangle) PayloadInvalid(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata, err error) { + defer payload.Release() + defer payloadMetadata.Release() + e.Called(payload.Unwrap(), payloadMetadata.Unwrap(), err) +} + +func (e *eventTangle) TransactionReceived(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, attachment *CachedAttachment) { + defer transaction.Release() + defer transactionMetadata.Release() + defer attachment.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), attachment.Unwrap()) +} + +func (e *eventTangle) TransactionInvalid(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, err error) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), err) +} + +func (e *eventTangle) TransactionSolid(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) TransactionBooked(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, decisionPending bool) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), decisionPending) +} + +func (e *eventTangle) TransactionPreferred(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) TransactionUnpreferred(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) TransactionLiked(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) TransactionDisliked(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) TransactionFinalized(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) TransactionConfirmed(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) TransactionRejected(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) { + defer transaction.Release() + defer transactionMetadata.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap()) +} + +func (e *eventTangle) Fork(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, branch *branchmanager.CachedBranch, outputIDs []transaction.OutputID) { + defer transaction.Release() + defer transactionMetadata.Release() + defer branch.Release() + e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), branch.Unwrap(), outputIDs) +} + +// TODO: Error is never tested +func (e *eventTangle) Error(err error) { + e.Called(err) +} diff --git a/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go new file mode 100644 index 0000000000000000000000000000000000000000..5d185f9637fef1a7bef59f8e8b69138936f2ac37 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go @@ -0,0 +1,1339 @@ +package tangle + +import ( + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +const ( + GENESIS uint64 = iota + A + B + C + D + E + F + G + H + I + J + Y +) + +// TODO: clean up create scenario with some helper functions: DRY! + +// preparePropagationScenario1 creates a tangle according to `img/scenario1.png`. +func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transaction.Transaction, map[string]*payload.Payload, map[string]branchmanager.BranchID, *wallet.Seed) { + // create tangle + tangle := newEventTangle(t, New(mapdb.NewMapDB())) + + // create seed for testing + seed := wallet.NewSeed() + + // initialize tangle with genesis block (+GENESIS) + tangle.LoadSnapshot(map[transaction.ID]map[address.Address][]*balance.Balance{ + transaction.GenesisID: { + seed.Address(GENESIS): { + balance.New(balance.ColorIOTA, 3333), + }, + }, + }) + + // create dictionaries so we can address the created entities by their aliases from the picture + transactions := make(map[string]*transaction.Transaction) + valueObjects := make(map[string]*payload.Payload) + branches := make(map[string]branchmanager.BranchID) + + // [-GENESIS, A+, B+, C+] + { + // create transaction + payload + transactions["[-GENESIS, A+, B+, C+]"] = transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(GENESIS), transaction.GenesisID), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(A): { + balance.New(balance.ColorIOTA, 1111), + }, + seed.Address(B): { + balance.New(balance.ColorIOTA, 1111), + }, + seed.Address(C): { + balance.New(balance.ColorIOTA, 1111), + }, + }), + ) + transactions["[-GENESIS, A+, B+, C+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(GENESIS))) + valueObjects["[-GENESIS, A+, B+, C+]"] = payload.New(payload.GenesisID, payload.GenesisID, transactions["[-GENESIS, A+, B+, C+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-GENESIS, A+, B+, C+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything, true) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-GENESIS, A+, B+, C+]"]) + + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-GENESIS, A+, B+, C+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if payload metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-GENESIS, A+, B+, C+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address GENESIS is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(GENESIS)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 3333)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address A is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(A)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address B is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(B)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address C is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(C)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + } + + // [-A, D+] + { + // create transaction + payload + transactions["[-A, D+]"] = transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(A), transactions["[-GENESIS, A+, B+, C+]"].ID()), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(D): { + balance.New(balance.ColorIOTA, 1111), + }, + }), + ) + transactions["[-A, D+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(A))) + valueObjects["[-A, D+]"] = payload.New(payload.GenesisID, valueObjects["[-GENESIS, A+, B+, C+]"].ID(), transactions["[-A, D+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-A, D+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-A, D+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-A, D+]"], mock.Anything, true) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-A, D+]"]) + + // check if payload metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-A, D+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-A, D+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address A is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(A)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address D is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(D)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + } + + // [-B, -C, E+] + { + // create transaction + payload + transactions["[-B, -C, E+]"] = transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(B), transactions["[-GENESIS, A+, B+, C+]"].ID()), + transaction.NewOutputID(seed.Address(C), transactions["[-GENESIS, A+, B+, C+]"].ID()), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(E): { + balance.New(balance.ColorIOTA, 2222), + }, + }), + ) + transactions["[-B, -C, E+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(B))) + transactions["[-B, -C, E+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(C))) + valueObjects["[-B, -C, E+]"] = payload.New(payload.GenesisID, valueObjects["[-GENESIS, A+, B+, C+]"].ID(), transactions["[-B, -C, E+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-B, -C, E+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-B, -C, E+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-B, -C, E+]"], mock.Anything, true) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-B, -C, E+]"]) + + // check if payload metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-B, -C, E+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-B, -C, E+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address B is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(B)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address C is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(C)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address E is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(E)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 2222)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + } + + // [-B, -C, E+] (Reattachment) + { + // create payload + valueObjects["[-B, -C, E+] (Reattachment)"] = payload.New(valueObjects["[-B, -C, E+]"].ID(), valueObjects["[-GENESIS, A+, B+, C+]"].ID(), transactions["[-B, -C, E+]"]) + + tangle.Expect("PayloadAttached", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-B, -C, E+] (Reattachment)"]) + + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-B, -C, E+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if payload metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-B, -C, E+] (Reattachment)"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address B is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(B)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address C is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(C)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address E is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(E)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 2222)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + } + + // [-A, F+] + { + // create transaction + payload + outputA := transaction.NewOutputID(seed.Address(A), transactions["[-GENESIS, A+, B+, C+]"].ID()) + transactions["[-A, F+]"] = transaction.New( + transaction.NewInputs( + outputA, + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(F): { + balance.New(balance.ColorIOTA, 1111), + }, + }), + ) + transactions["[-A, F+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(A))) + valueObjects["[-A, F+]"] = payload.New(valueObjects["[-B, -C, E+]"].ID(), valueObjects["[-GENESIS, A+, B+, C+]"].ID(), transactions["[-A, F+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-A, F+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-A, F+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-A, F+]"], mock.Anything, true) + tangle.Expect("Fork", transactions["[-A, D+]"], mock.Anything, mock.Anything, []transaction.OutputID{outputA}) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-A, F+]"]) + + // create aliases for the branches + branches["A"] = branchmanager.NewBranchID(transactions["[-A, D+]"].ID()) + branches["B"] = branchmanager.NewBranchID(transactions["[-A, F+]"].ID()) + + // check if payload metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-A, F+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branches["B"], transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-A, F+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["B"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address A is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(A)).Consume(func(output *Output) { + assert.Equal(t, 2, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address F is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(F)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branches["B"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address D is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(D)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branches["A"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-A, D+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["A"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the branches are conflicting + branchesConflicting, err := tangle.branchManager.BranchesConflicting(branches["A"], branches["B"]) + require.NoError(t, err) + assert.True(t, branchesConflicting, "the branches should be conflicting") + } + + // [-E, -F, G+] + { + // create transaction + payload + transactions["[-E, -F, G+]"] = transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(E), transactions["[-B, -C, E+]"].ID()), + transaction.NewOutputID(seed.Address(F), transactions["[-A, F+]"].ID()), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(G): { + balance.New(balance.ColorIOTA, 3333), + }, + }), + ) + transactions["[-E, -F, G+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(E))) + transactions["[-E, -F, G+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(F))) + valueObjects["[-E, -F, G+]"] = payload.New(valueObjects["[-B, -C, E+]"].ID(), valueObjects["[-A, F+]"].ID(), transactions["[-E, -F, G+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-E, -F, G+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-E, -F, G+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-E, -F, G+]"], mock.Anything, true) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-E, -F, G+]"]) + + // check if payload metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-E, -F, G+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branches["B"], transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-E, -F, G+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["B"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address E is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(E)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 2222)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address F is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(F)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branches["B"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address G is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(G)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 3333)}, output.Balances()) + assert.Equal(t, branches["B"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + } + + // [-F, -D, Y+] + { + // create transaction + payload + transactions["[-F, -D, Y+]"] = transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(D), transactions["[-A, D+]"].ID()), + transaction.NewOutputID(seed.Address(F), transactions["[-A, F+]"].ID()), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(Y): { + balance.New(balance.ColorIOTA, 2222), + }, + }), + ) + transactions["[-F, -D, Y+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(D))) + transactions["[-F, -D, Y+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(F))) + valueObjects["[-F, -D, Y+]"] = payload.New(valueObjects["[-A, F+]"].ID(), valueObjects["[-A, D+]"].ID(), transactions["[-F, -D, Y+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-F, -D, Y+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-F, -D, Y+]"], mock.Anything) + tangle.Expect("PayloadInvalid", valueObjects["[-F, -D, Y+]"], mock.Anything, mock.MatchedBy(func(err error) bool { return assert.Error(t, err) })) + tangle.Expect("TransactionReceived", transactions["[-F, -D, Y+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionInvalid", transactions["[-F, -D, Y+]"], mock.Anything, mock.MatchedBy(func(err error) bool { return assert.Error(t, err) })) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-F, -D, Y+]"]) + + // check if all of the invalids transactions models were deleted + assert.False(t, tangle.Transaction(transactions["[-F, -D, Y+]"].ID()).Consume(func(metadata *transaction.Transaction) {}), "the transaction should not be found") + assert.False(t, tangle.TransactionMetadata(transactions["[-F, -D, Y+]"].ID()).Consume(func(metadata *TransactionMetadata) {}), "the transaction metadata should not be found") + assert.False(t, tangle.Payload(valueObjects["[-F, -D, Y+]"].ID()).Consume(func(payload *payload.Payload) {}), "the payload should not be found") + assert.False(t, tangle.PayloadMetadata(valueObjects["[-F, -D, Y+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) {}), "the payload metadata should not be found") + assert.True(t, tangle.Approvers(valueObjects["[-A, F+]"].ID()).Consume(func(approver *PayloadApprover) { + assert.NotEqual(t, approver.ApprovingPayloadID(), valueObjects["[-F, -D, Y+]"].ID(), "the invalid value object should not show up as an approver") + }), "the should be approvers of the referenced output") + assert.False(t, tangle.Approvers(valueObjects["[-A, D+]"].ID()).Consume(func(approver *PayloadApprover) {}), "approvers should be empty") + assert.False(t, tangle.Attachments(transactions["[-F, -D, Y+]"].ID()).Consume(func(attachment *Attachment) {}), "the transaction should not have any attachments") + assert.False(t, tangle.Consumers(transaction.NewOutputID(seed.Address(D), transactions["[-A, D+]"].ID())).Consume(func(consumer *Consumer) {}), "the consumers of the used input should be empty") + assert.True(t, tangle.Consumers(transaction.NewOutputID(seed.Address(F), transactions["[-A, F+]"].ID())).Consume(func(consumer *Consumer) { + assert.NotEqual(t, consumer.TransactionID(), transactions["[-F, -D, Y+]"].ID(), "the consumers should not contain the invalid transaction") + }), "the consumers should not be empty") + } + + // [-B, -C, E+] (2nd Reattachment) + { + valueObjects["[-B, -C, E+] (2nd Reattachment)"] = payload.New(valueObjects["[-A, F+]"].ID(), valueObjects["[-A, D+]"].ID(), transactions["[-B, -C, E+]"]) + + tangle.Expect("PayloadAttached", valueObjects["[-B, -C, E+] (2nd Reattachment)"], mock.Anything) + tangle.Expect("PayloadInvalid", valueObjects["[-B, -C, E+] (2nd Reattachment)"], mock.Anything, mock.MatchedBy(func(err error) bool { return assert.Error(t, err) })) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-B, -C, E+] (2nd Reattachment)"]) + + // check if all of the valid transactions models were NOT deleted + assert.True(t, tangle.Transaction(transactions["[-B, -C, E+]"].ID()).Consume(func(metadata *transaction.Transaction) {})) + + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-B, -C, E+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if payload and its corresponding models are not found in the database (payload was invalid) + assert.False(t, tangle.Payload(valueObjects["[-B, -C, E+] (2nd Reattachment)"].ID()).Consume(func(payload *payload.Payload) {}), "the payload should not exist") + assert.False(t, tangle.PayloadMetadata(valueObjects["[-B, -C, E+] (2nd Reattachment)"].ID()).Consume(func(payloadMetadata *PayloadMetadata) {}), "the payload metadata should not exist") + assert.True(t, tangle.Attachments(transactions["[-B, -C, E+]"].ID()).Consume(func(attachment *Attachment) { + assert.NotEqual(t, valueObjects["[-B, -C, E+] (2nd Reattachment)"].ID(), attachment.PayloadID(), "the attachment to the payload should be deleted") + }), "there should be attachments of the transaction") + assert.True(t, tangle.Approvers(valueObjects["[-A, F+]"].ID()).Consume(func(approver *PayloadApprover) { + assert.NotEqual(t, valueObjects["[-A, F+]"].ID(), approver.ApprovingPayloadID(), "there should not be an approver reference to the invalid payload") + assert.NotEqual(t, valueObjects["[-A, D+]"].ID(), approver.ApprovingPayloadID(), "there should not be an approver reference to the invalid payload") + }), "there should be approvers") + assert.False(t, tangle.Approvers(valueObjects["[-A, D+]"].ID()).Consume(func(approver *PayloadApprover) {}), "there should be no approvers") + } + + return tangle, transactions, valueObjects, branches, seed +} + +// preparePropagationScenario1 creates a tangle according to `img/scenario2.png`. +func preparePropagationScenario2(t *testing.T) (*eventTangle, map[string]*transaction.Transaction, map[string]*payload.Payload, map[string]branchmanager.BranchID, *wallet.Seed) { + tangle, transactions, valueObjects, branches, seed := preparePropagationScenario1(t) + + // [-C, H+] + { + // create transaction + payload + outputC := transaction.NewOutputID(seed.Address(C), transactions["[-GENESIS, A+, B+, C+]"].ID()) + transactions["[-C, H+]"] = transaction.New( + transaction.NewInputs( + outputC, + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(H): { + balance.New(balance.ColorIOTA, 1111), + }, + }), + ) + transactions["[-C, H+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(C))) + valueObjects["[-C, H+]"] = payload.New(valueObjects["[-GENESIS, A+, B+, C+]"].ID(), valueObjects["[-A, D+]"].ID(), transactions["[-C, H+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-C, H+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-C, H+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-C, H+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-C, H+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-C, H+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-C, H+]"], mock.Anything, true) + tangle.Expect("Fork", transactions["[-B, -C, E+]"], mock.Anything, mock.Anything, []transaction.OutputID{outputC}) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-C, H+]"]) + + // create alias for the branch + branches["C"] = branchmanager.NewBranchID(transactions["[-C, H+]"].ID()) + branches["AC"] = tangle.BranchManager().GenerateAggregatedBranchID(branches["A"], branches["C"]) + + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-C, H+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branches["C"], transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if payload metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-C, H+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.NotEqual(t, branches["C"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + assert.Equal(t, branches["AC"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address C is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(C)).Consume(func(output *Output) { + assert.Equal(t, 2, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address H is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(H)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branches["C"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // Branch D + + // create alias for the branch + branches["D"] = branchmanager.NewBranchID(transactions["[-B, -C, E+]"].ID()) + branches["BD"] = tangle.branchManager.GenerateAggregatedBranchID(branches["B"], branches["D"]) + + { + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-B, -C, E+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["D"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-B, -C, E+] (Reattachment)"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["D"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + } + + // check if the branches C and D are conflicting + branchesConflicting, err := tangle.branchManager.BranchesConflicting(branches["C"], branches["D"]) + require.NoError(t, err) + assert.True(t, branchesConflicting, "the branches should be conflicting") + + // Aggregated Branch [BD] + { + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-E, -F, G+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["BD"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if transaction metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-E, -F, G+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["BD"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + } + } + + // [-H, -D, I+] + { + // create transaction + payload + transactions["[-H, -D, I+]"] = transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(H), transactions["[-C, H+]"].ID()), + transaction.NewOutputID(seed.Address(D), transactions["[-A, D+]"].ID()), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(I): { + balance.New(balance.ColorIOTA, 2222), + }, + }), + ) + transactions["[-H, -D, I+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(H))) + transactions["[-H, -D, I+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(D))) + valueObjects["[-H, -D, I+]"] = payload.New(valueObjects["[-C, H+]"].ID(), valueObjects["[-A, D+]"].ID(), transactions["[-H, -D, I+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-H, -D, I+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-H, -D, I+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-H, -D, I+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-H, -D, I+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-H, -D, I+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-H, -D, I+]"], mock.Anything, true) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-H, -D, I+]"]) + + // create alias for the branch + branches["AC"] = tangle.branchManager.GenerateAggregatedBranchID(branches["A"], branches["C"]) + + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-H, -D, I+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branches["AC"], transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // check if payload metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-H, -D, I+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["AC"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address H is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(H)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branches["C"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address D is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(D)).Consume(func(output *Output) { + assert.Equal(t, 1, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branches["A"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address I is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(I)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 2222)}, output.Balances()) + assert.Equal(t, branches["AC"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + } + + // [-B, J+] + { + // create transaction + payload + transactions["[-B, J+]"] = transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(B), transactions["[-GENESIS, A+, B+, C+]"].ID()), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + seed.Address(J): { + balance.New(balance.ColorIOTA, 1111), + }, + }), + ) + transactions["[-B, J+]"].Sign(signaturescheme.ED25519(*seed.KeyPair(B))) + valueObjects["[-B, J+]"] = payload.New(valueObjects["[-C, H+]"].ID(), valueObjects["[-A, D+]"].ID(), transactions["[-B, J+]"]) + + // check if signatures are valid + assert.True(t, transactions["[-B, J+]"].SignaturesValid()) + + tangle.Expect("PayloadAttached", valueObjects["[-B, J+]"], mock.Anything) + tangle.Expect("PayloadSolid", valueObjects["[-B, J+]"], mock.Anything) + tangle.Expect("TransactionReceived", transactions["[-B, J+]"], mock.Anything, mock.Anything) + tangle.Expect("TransactionSolid", transactions["[-B, J+]"], mock.Anything) + tangle.Expect("TransactionBooked", transactions["[-B, J+]"], mock.Anything, true) + + // attach payload + tangle.AttachPayloadSync(valueObjects["[-B, J+]"]) + + // create alias for the branch + branches["E"] = branchmanager.NewBranchID(transactions["[-B, J+]"].ID()) + + // check if transaction metadata is found in database + assert.True(t, tangle.TransactionMetadata(transactions["[-B, J+]"].ID()).Consume(func(transactionMetadata *TransactionMetadata) { + assert.True(t, transactionMetadata.Solid(), "the transaction is not solid") + assert.Equal(t, branches["E"], transactionMetadata.BranchID(), "the transaction was booked into the wrong branch") + })) + + // create alias for the branch + branches["ACE"] = tangle.branchManager.GenerateAggregatedBranchID(branches["A"], branches["C"], branches["E"]) + + // check if payload metadata is found in database + assert.True(t, tangle.PayloadMetadata(valueObjects["[-B, J+]"].ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.True(t, payloadMetadata.IsSolid(), "the payload is not solid") + assert.Equal(t, branches["ACE"], payloadMetadata.BranchID(), "the payload was booked into the wrong branch") + })) + + // check if the balance on address B is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(B)).Consume(func(output *Output) { + assert.Equal(t, 2, output.ConsumerCount(), "the output should be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the balance on address J is found in the database + assert.True(t, tangle.OutputsOnAddress(seed.Address(J)).Consume(func(output *Output) { + assert.Equal(t, 0, output.ConsumerCount(), "the output should not be spent") + assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1111)}, output.Balances()) + assert.Equal(t, branches["E"], output.BranchID(), "the output was booked into the wrong branch") + assert.True(t, output.Solid(), "the output is not solid") + })) + + // check if the branches D and E are conflicting + branchesConflicting, err := tangle.branchManager.BranchesConflicting(branches["D"], branches["E"]) + require.NoError(t, err) + assert.True(t, branchesConflicting, "the branches should be conflicting") + + } + + return tangle, transactions, valueObjects, branches, seed +} + +func TestPropagationScenario1(t *testing.T) { + // img/scenario1.png + + // test past cone monotonicity - all value objects MUST be confirmed + { + tangle, transactions, valueObjects, _, _ := preparePropagationScenario1(t) + defer tangle.DetachAll() + + // initialize debugger for this test + debugger.ResetAliases() + for name, valueObject := range valueObjects { + debugger.RegisterAlias(valueObject.ID(), "ValueObjectID"+name) + } + for name, tx := range transactions { + debugger.RegisterAlias(tx.ID(), "TransactionID"+name) + } + + // preferring [-GENESIS, A+, B+, C+] will get it liked + tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + + setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, false, true, false, false) + + // finalizing [-B, -C, E+] will not get it confirmed, as [-GENESIS, A+, B+, C+] is not yet confirmed + tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + + setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, -C, E+]"]) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, false, false) + + // finalize [-GENESIS, A+, B+, C+] to also get [-B, -C, E+] as well as [-B, -C, E+] (Reattachment) confirmed + tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + + setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"]) + verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, true, false) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], true, true, true, true, false) + + tangle.AssertExpectations(t) + } + + // test future cone monotonicity simple - everything MUST be rejected and finalized if spending funds from rejected tx + { + tangle, transactions, valueObjects, _, _ := preparePropagationScenario1(t) + defer tangle.DetachAll() + + // finalizing [-GENESIS, A+, B+, C+] will get the entire future cone finalized and rejected + tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything) + + setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"]) + verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], false, true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], false, true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], false, true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], false, true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], false, true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, true, false, false, true) + + tangle.AssertExpectations(t) + } + + // test future cone monotonicity more complex - everything MUST be rejected and finalized if spending funds from rejected tx + { + tangle, transactions, valueObjects, branches, _ := preparePropagationScenario1(t) + defer tangle.DetachAll() + + // initialize debugger for this test + debugger.ResetAliases() + for name, valueObject := range valueObjects { + debugger.RegisterAlias(valueObject.ID(), "ValueObjectID"+name) + } + for name, tx := range transactions { + debugger.RegisterAlias(tx.ID(), "TransactionID"+name) + } + + tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + + setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"]) + verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false) + + tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything) + + // finalize & reject + //debugger.Enable() + setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, -C, E+]"]) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], false, true, false, false, true) + //debugger.Disable() + + // check future cone to be rejected + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], false, true, false, false, true) + + // [-A, F+] should be rejected but the tx not finalized since it spends funds from [-GENESIS, A+, B+, C+] which is confirmed + verifyTransactionInclusionState(t, tangle, valueObjects["[-A, F+]"], false, false, false, false, false) + verifyValueObjectInclusionState(t, tangle, valueObjects["[-A, F+]"], false, false, true) + verifyBranchState(t, tangle, branches["B"], false, false, false, false) + + // [-E, -F, G+] should be finalized and rejected since it spends funds from [-B, -C, E+] + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, true, false, false, true) + + // [-A, D+] should be unchanged + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], false, false, false, false, false) + verifyBranchState(t, tangle, branches["A"], false, false, false, false) + + tangle.AssertExpectations(t) + } + + // simulate vote on [-A, F+] -> Branch A becomes rejected, Branch B confirmed + { + tangle, transactions, valueObjects, branches, _ := preparePropagationScenario1(t) + defer tangle.DetachAll() + + tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + + setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"]) + verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false) + + // check future cone + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], false, false, false, false, false) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], false, false, false, false, false) + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], false, false, false, false, false) + verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], false, false, false, false, false) + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, false, false, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-B, -C, E+]"], mock.Anything) + + // confirm [-B, -C, E+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, -C, E+]"]) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, true, false) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], true, true, true, true, false) + + tangle.Expect("PayloadLiked", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-A, D+]"], mock.Anything) + + // prefer [-A, D+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-A, D+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], true, false, true, false, false) + verifyBranchState(t, tangle, branches["A"], false, true, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("PayloadDisliked", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionUnpreferred", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionDisliked", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-A, D+]"], mock.Anything) + + // simulate vote result to like [-A, F+] -> [-A, F+] becomes confirmed and [-A, D+] rejected + setTransactionPreferredWithCheck(t, tangle, transactions["[-A, F+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-A, F+]"]) + verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], true, true, true, true, false) + verifyBranchState(t, tangle, branches["B"], true, true, true, false) + // [-A, D+] should be rejected + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], false, true, false, false, true) + verifyBranchState(t, tangle, branches["A"], true, false, false, true) + + tangle.Expect("PayloadLiked", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-E, -F, G+]"], mock.Anything) + + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, false, false, false, false) + setTransactionPreferredWithCheck(t, tangle, transactions["[-E, -F, G+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-E, -F, G+]"]) + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], true, true, true, true, false) + + tangle.AssertExpectations(t) + } + + // simulate vote on [-A, D+] -> Branch B becomes rejected, Branch A confirmed + { + tangle, transactions, valueObjects, branches, _ := preparePropagationScenario1(t) + defer tangle.DetachAll() + + tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + + // confirm [-GENESIS, A+, B+, C+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"]) + verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false) + + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-B, -C, E+]"], mock.Anything) + + // confirm [-B, -C, E+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, -C, E+]"]) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, true, false) + + tangle.Expect("PayloadLiked", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-A, F+]"], mock.Anything) + + // prefer [-A, F+] and thus Branch B + setTransactionPreferredWithCheck(t, tangle, transactions["[-A, F+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], true, false, true, false, false) + verifyBranchState(t, tangle, branches["B"], false, true, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-E, -F, G+]"], mock.Anything) + + // prefer [-E, -F, G+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-E, -F, G+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], true, false, true, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-A, D+]"], mock.Anything) + + tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadDisliked", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionUnpreferred", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionDisliked", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("PayloadDisliked", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionUnpreferred", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionDisliked", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything) + + // simulate vote result to like [-A, D+] -> [-A, D+] becomes confirmed and [-A, F+], [-E, -F, G+] rejected + setTransactionPreferredWithCheck(t, tangle, transactions["[-A, D+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-A, D+]"]) + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], true, true, true, true, false) + verifyBranchState(t, tangle, branches["A"], true, true, true, false) + + // [-A, F+], [-E, -F, G+] should be finalized and rejected + verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], false, true, false, false, true) + verifyBranchState(t, tangle, branches["B"], true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, true, false, false, true) + + tangle.AssertExpectations(t) + } +} + +func TestPropagationScenario2(t *testing.T) { + // img/scenario2.png + tangle, transactions, valueObjects, branches, _ := preparePropagationScenario2(t) + defer tangle.DetachAll() + + // initialize debugger for this test + debugger.ResetAliases() + for name, valueObject := range valueObjects { + debugger.RegisterAlias(valueObject.ID(), "ValueObjectID"+name) + } + for name, tx := range transactions { + debugger.RegisterAlias(tx.ID(), "TransactionID"+name) + } + + tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything) + + // confirm [-GENESIS, A+, B+, C+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"]) + verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false) + + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything) + + // prefer [-B, -C, E+] and thus Branch D + setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, false, true, false, false) + verifyBranchState(t, tangle, branches["D"], false, true, false, false) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], true, false, true, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-A, F+]"], mock.Anything) + + // prefer [-A, F+] and thus Branch B + setTransactionPreferredWithCheck(t, tangle, transactions["[-A, F+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], true, false, true, false, false) + verifyBranchState(t, tangle, branches["B"], false, true, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-E, -F, G+]"], mock.Anything) + + // prefer [-E, -F, G+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-E, -F, G+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], true, false, true, false, false) + // check aggregated branch + verifyBranchState(t, tangle, branches["BD"], false, true, false, false) + + // verify states of other transactions, value objects and branches + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], false, false, false, false, false) + verifyBranchState(t, tangle, branches["A"], false, false, false, false) + + verifyInclusionState(t, tangle, valueObjects["[-C, H+]"], false, false, false, false, false) + verifyBranchState(t, tangle, branches["C"], false, false, false, false) + + verifyInclusionState(t, tangle, valueObjects["[-H, -D, I+]"], false, false, false, false, false) + // check aggregated branch + verifyBranchState(t, tangle, branches["AC"], false, false, false, false) + + verifyInclusionState(t, tangle, valueObjects["[-B, J+]"], false, false, false, false, false) + verifyBranchState(t, tangle, branches["E"], false, false, false, false) + verifyBranchState(t, tangle, branches["ACE"], false, false, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-H, -D, I+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-H, -D, I+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-H, -D, I+]"], mock.Anything) + + // prefer [-H, -D, I+] - should be liked after votes on [-A, D+] and [-C, H+] + setTransactionPreferredWithCheck(t, tangle, transactions["[-H, -D, I+]"], true) + verifyInclusionState(t, tangle, valueObjects["[-H, -D, I+]"], true, false, false, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-A, D+]"], mock.Anything) + + tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadDisliked", valueObjects["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionUnpreferred", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionDisliked", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-A, F+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("PayloadDisliked", valueObjects["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionUnpreferred", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionDisliked", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything) + + // simulate vote result to like [-A, D+] -> [-A, D+] becomes confirmed and [-A, F+], [-E, -F, G+] rejected + setTransactionPreferredWithCheck(t, tangle, transactions["[-A, D+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-A, D+]"]) + verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], true, true, true, true, false) + verifyBranchState(t, tangle, branches["A"], true, true, true, false) + + verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], false, true, false, false, true) + verifyBranchState(t, tangle, branches["B"], true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, true, false, false, true) + + tangle.Expect("PayloadLiked", valueObjects["[-C, H+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-C, H+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-C, H+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-C, H+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-C, H+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-C, H+]"], mock.Anything) + + tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadDisliked", valueObjects["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionUnpreferred", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionDisliked", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("TransactionRejected", transactions["[-B, -C, E+]"], mock.Anything) + tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + tangle.Expect("PayloadDisliked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything) + + // simulate vote result to like [-C, H+] -> [-C, H+] becomes confirmed and [-B, -C, E+], [-B, -C, E+] (Reattachment) rejected + setTransactionPreferredWithCheck(t, tangle, transactions["[-C, H+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-C, H+]"]) + + verifyInclusionState(t, tangle, valueObjects["[-C, H+]"], true, true, true, true, false) + verifyBranchState(t, tangle, branches["C"], true, true, true, false) + verifyBranchState(t, tangle, branches["AC"], true, true, true, false) + + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], false, true, false, false, true) + verifyBranchState(t, tangle, branches["D"], true, false, false, true) + verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], false, true, false, false, true) + verifyBranchState(t, tangle, branches["BD"], true, false, false, true) + // TODO: BD is not finalized + + // [-H, -D, I+] is already preferred + tangle.Expect("PayloadConfirmed", valueObjects["[-H, -D, I+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-H, -D, I+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-H, -D, I+]"], mock.Anything) + + // [-H, -D, I+] should now be liked + verifyInclusionState(t, tangle, valueObjects["[-H, -D, I+]"], true, false, true, false, false) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-H, -D, I+]"]) + verifyInclusionState(t, tangle, valueObjects["[-H, -D, I+]"], true, true, true, true, false) + // [-B, J+] should be unchanged + verifyInclusionState(t, tangle, valueObjects["[-B, J+]"], false, false, false, false, false) + + tangle.Expect("PayloadLiked", valueObjects["[-B, J+]"], mock.Anything) + tangle.Expect("PayloadConfirmed", valueObjects["[-B, J+]"], mock.Anything) + tangle.Expect("TransactionPreferred", transactions["[-B, J+]"], mock.Anything) + tangle.Expect("TransactionLiked", transactions["[-B, J+]"], mock.Anything) + tangle.Expect("TransactionFinalized", transactions["[-B, J+]"], mock.Anything) + tangle.Expect("TransactionConfirmed", transactions["[-B, J+]"], mock.Anything) + + // [-B, J+] should become confirmed after preferring and finalizing + setTransactionPreferredWithCheck(t, tangle, transactions["[-B, J+]"], true) + setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, J+]"]) + verifyInclusionState(t, tangle, valueObjects["[-B, J+]"], true, true, true, true, false) + verifyBranchState(t, tangle, branches["E"], true, true, true, false) + verifyBranchState(t, tangle, branches["ACE"], true, true, true, false) + + tangle.AssertExpectations(t) +} + +// verifyBranchState verifies the the branch state according to the given parameters. +func verifyBranchState(t *testing.T, tangle *eventTangle, id branchmanager.BranchID, finalized, liked, confirmed, rejected bool) { + assert.True(t, tangle.branchManager.Branch(id).Consume(func(branch *branchmanager.Branch) { + assert.Equalf(t, finalized, branch.Finalized(), "branch finalized state does not match") + assert.Equalf(t, liked, branch.Liked(), "branch liked state does not match") + + assert.Equalf(t, confirmed, branch.Confirmed(), "branch confirmed state does not match") + assert.Equalf(t, rejected, branch.Rejected(), "branch rejected state does not match") + })) +} + +// verifyInclusionState verifies the inclusion state of outputs and transaction according to the given parameters. +func verifyTransactionInclusionState(t *testing.T, tangle *eventTangle, valueObject *payload.Payload, preferred, finalized, liked, confirmed, rejected bool) { + tx := valueObject.Transaction() + + // check outputs + tx.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + assert.True(t, tangle.TransactionOutput(transaction.NewOutputID(address, tx.ID())).Consume(func(output *Output) { + assert.Equalf(t, liked, output.Liked(), "output liked state does not match") + assert.Equalf(t, confirmed, output.Confirmed(), "output confirmed state does not match") + assert.Equalf(t, rejected, output.Rejected(), "output rejected state does not match") + })) + return true + }) + + // check transaction + assert.True(t, tangle.TransactionMetadata(tx.ID()).Consume(func(metadata *TransactionMetadata) { + assert.Equalf(t, preferred, metadata.Preferred(), "tx preferred state does not match") + assert.Equalf(t, finalized, metadata.Finalized(), "tx finalized state does not match") + + assert.Equalf(t, liked, metadata.Liked(), "tx liked state does not match") + assert.Equalf(t, confirmed, metadata.Confirmed(), "tx confirmed state does not match") + assert.Equalf(t, rejected, metadata.Rejected(), "tx rejected state does not match") + })) +} + +// verifyValueObjectInclusionState verifies the inclusion state of a value object according to the given parameters. +func verifyValueObjectInclusionState(t *testing.T, tangle *eventTangle, valueObject *payload.Payload, liked, confirmed, rejected bool) { + assert.True(t, tangle.PayloadMetadata(valueObject.ID()).Consume(func(payloadMetadata *PayloadMetadata) { + assert.Equalf(t, liked, payloadMetadata.Liked(), "value object liked state does not match") + assert.Equalf(t, confirmed, payloadMetadata.Confirmed(), "value object confirmed state does not match") + assert.Equalf(t, rejected, payloadMetadata.Rejected(), "value object rejected state does not match") + })) +} + +// verifyInclusionState verifies the inclusion state of outputs, transaction and value object according to the given parameters. +func verifyInclusionState(t *testing.T, tangle *eventTangle, valueObject *payload.Payload, preferred, finalized, liked, confirmed, rejected bool) { + verifyTransactionInclusionState(t, tangle, valueObject, preferred, finalized, liked, confirmed, rejected) + verifyValueObjectInclusionState(t, tangle, valueObject, liked, confirmed, rejected) +} + +// setTransactionPreferredWithCheck sets the transaction to preferred and makes sure that no error occurred and it's modified. +func setTransactionPreferredWithCheck(t *testing.T, tangle *eventTangle, tx *transaction.Transaction, preferred bool) { + modified, err := tangle.SetTransactionPreferred(tx.ID(), preferred) + require.NoError(t, err) + assert.True(t, modified) +} + +// setTransactionFinalizedWithCheck sets the transaction to finalized and makes sure that no error occurred and it's modified. +func setTransactionFinalizedWithCheck(t *testing.T, tangle *eventTangle, tx *transaction.Transaction) { + modified, err := tangle.SetTransactionFinalized(tx.ID()) + require.NoError(t, err) + assert.True(t, modified) +} diff --git a/dapps/valuetransfers/packages/tangle/tangle_test.go b/dapps/valuetransfers/packages/tangle/tangle_test.go new file mode 100644 index 0000000000000000000000000000000000000000..b0d1273e98b444a5c9084b2281c420216458d248 --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/tangle_test.go @@ -0,0 +1,1645 @@ +package tangle + +import ( + "container/list" + "math" + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/iotaledger/hive.go/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestSetTransactionPreferred(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + tx := createDummyTransaction() + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + tangle.storeTransactionModels(valueObject) + + event.Expect("TransactionPreferred", tx, mock.Anything) + + modified, err := tangle.SetTransactionPreferred(tx.ID(), true) + require.NoError(t, err) + assert.True(t, modified) + + event.AssertExpectations(t) +} + +// TestBookTransaction tests the following cases: +// - missing output +// - transaction already booked by another process +// - booking first spend +// - booking double spend +func TestBookTransaction(t *testing.T) { + + // CASE: missing output + t.Run("CASE: missing output", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + tx := createDummyTransaction() + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + + cachedTransaction, cachedTransactionMetadata, _, transactionIsNew := tangle.storeTransactionModels(valueObject) + assert.True(t, transactionIsNew) + + event.Expect("TransactionSolid", tx, mock.Anything) + + // manually trigger a booking: tx will be marked solid, but it cannot be book as its inputs are unavailable + transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata) + assert.False(t, transactionBooked) + assert.False(t, decisionPending) + assert.Error(t, err) + + event.AssertExpectations(t) + }) + + // CASE: transaction already booked by another process + t.Run("CASE: transaction already booked by another process", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + tx := createDummyTransaction() + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + cachedTransaction, cachedTransactionMetadata, _, _ := tangle.storeTransactionModels(valueObject) + + transactionMetadata := cachedTransactionMetadata.Unwrap() + transactionMetadata.setSolid(true) + + transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata) + require.NoError(t, err) + assert.False(t, transactionBooked) + assert.False(t, decisionPending) + + event.AssertExpectations(t) + }) + + // CASE: booking first spend + t.Run("CASE: booking first spend", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + // prepare snapshot + color1 := [32]byte{1} + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + // build first spending + tx1 := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + balance.New(color1, 3), + }, + }), + ) + + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx1) + cachedTransaction, cachedTransactionMetadata, _, _ := tangle.storeTransactionModels(valueObject) + txMetadata := cachedTransactionMetadata.Unwrap() + + // assert that branchID is undefined before being booked + assert.Equal(t, branchmanager.UndefinedBranchID, txMetadata.BranchID()) + + event.Expect("TransactionSolid", tx1, mock.Anything) + // TransactionBooked is triggered outside of bookTransaction + + transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata) + require.NoError(t, err) + assert.True(t, transactionBooked, "transactionBooked") + assert.True(t, decisionPending, "decisionPending") + + // assert that branchID is the same as the MasterBranchID + assert.Equal(t, branchmanager.MasterBranchID, txMetadata.BranchID()) + + // CASE: booking double spend + t.Run("CASE: booking double spend", func(t *testing.T) { + // build second spending + tx2 := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + balance.New(color1, 3), + }, + }), + ) + + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx2) + cachedTransaction, cachedTransactionMetadata, _, _ = tangle.storeTransactionModels(valueObject) + txMetadata := cachedTransactionMetadata.Unwrap() + + // assert that branchID is undefined before being booked + assert.Equal(t, branchmanager.UndefinedBranchID, txMetadata.BranchID()) + + // manually book the double spending tx2, this will mark it as solid and trigger a fork + event.Expect("TransactionSolid", tx2, mock.Anything) + event.Expect("Fork", tx1, mock.Anything, mock.Anything, inputIDs) + + transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata) + require.NoError(t, err) + assert.True(t, transactionBooked, "transactionBooked") + assert.True(t, decisionPending, "decisionPending") + + // assert that first spend and double spend have different BranchIDs + assert.NotEqual(t, branchmanager.MasterBranchID, txMetadata.BranchID(), "BranchID") + }) + + event.AssertExpectations(t) + }) +} + +func TestCalculateBranchOfTransaction(t *testing.T) { + + // CASE: missing output + t.Run("CASE: missing output", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + tx := createDummyTransaction() + cachedBranch, err := tangle.calculateBranchOfTransaction(tx) + assert.Error(t, err) + assert.Nil(t, cachedBranch) + }) + + // CASE: same as master branch + t.Run("CASE: same as master branch", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + // prepare snapshot + color1 := [32]byte{1} + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + balance.New(color1, 3), + }, + }), + ) + + cachedBranch, err := tangle.calculateBranchOfTransaction(tx) + require.NoError(t, err) + assert.Equal(t, branchmanager.MasterBranchID, cachedBranch.Unwrap().ID()) + }) +} + +func TestMoveTransactionToBranch(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + // prepare snapshot + color1 := [32]byte{1} + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + balance.New(color1, 3), + }, + }), + ) + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + cachedTransaction, cachedTransactionMetadata, _, _ := tangle.storeTransactionModels(valueObject) + txMetadata := cachedTransactionMetadata.Unwrap() + + // create conflicting branch + cachedBranch2, _ := tangle.BranchManager().Fork(branchmanager.BranchID{2}, []branchmanager.BranchID{branchmanager.MasterBranchID}, []branchmanager.ConflictID{{0}}) + defer cachedBranch2.Release() + + err := tangle.moveTransactionToBranch(cachedTransaction.Retain(), cachedTransactionMetadata.Retain(), cachedBranch2.Retain()) + require.NoError(t, err) + assert.Equal(t, branchmanager.BranchID{2}, txMetadata.BranchID()) +} + +func TestFork(t *testing.T) { + // CASE: already finalized + t.Run("CASE: already finalized", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + // prepare snapshot + color1 := [32]byte{1} + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + balance.New(color1, 3), + }, + }), + ) + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + _, cachedTransactionMetadata, _, _ := tangle.storeTransactionModels(valueObject) + txMetadata := cachedTransactionMetadata.Unwrap() + + txMetadata.setFinalized(true) + + // no fork created so no event should be triggered + forked, finalized, err := tangle.Fork(tx.ID(), []transaction.OutputID{}) + require.NoError(t, err) + assert.False(t, forked) + assert.True(t, finalized) + + event.AssertExpectations(t) + }) + + t.Run("CASE: normal fork", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + // prepare snapshot + color1 := [32]byte{1} + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + balance.New(color1, 3), + }, + }), + ) + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + tangle.storeTransactionModels(valueObject) + + event.Expect("Fork", tx, mock.Anything, mock.Anything, []transaction.OutputID{}) + + forked, finalized, err := tangle.Fork(tx.ID(), []transaction.OutputID{}) + require.NoError(t, err) + assert.True(t, forked, "forked") + assert.False(t, finalized, "finalized") + + t.Run("CASE: branch existed already", func(t *testing.T) { + // no fork created so no event should be triggered + forked, finalized, err = tangle.Fork(tx.ID(), []transaction.OutputID{}) + require.NoError(t, err) + assert.False(t, forked, "forked") + assert.False(t, finalized, "finalized") + }) + + event.AssertExpectations(t) + }) +} + +func TestBookPayload(t *testing.T) { + t.Run("CASE: undefined branchID", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + cachedPayload, cachedMetadata, _ := tangle.storePayload(valueObject) + _, cachedTransactionMetadata, _, _ := tangle.storeTransactionModels(valueObject) + + payloadBooked, err := tangle.bookPayload(cachedPayload.Retain(), cachedMetadata.Retain(), cachedTransactionMetadata.Retain()) + defer func() { + cachedPayload.Release() + cachedMetadata.Release() + cachedTransactionMetadata.Release() + }() + + require.NoError(t, err) + assert.False(t, payloadBooked, "payloadBooked") + + event.AssertExpectations(t) + }) + + t.Run("CASE: successfully book", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + cachedPayload, cachedMetadata, _ := tangle.storePayload(valueObject) + metadata := cachedMetadata.Unwrap() + + metadata.setBranchID(branchmanager.BranchID{1}) + metadata.setBranchID(branchmanager.BranchID{2}) + + _, cachedTransactionMetadata, _, _ := tangle.storeTransactionModels(valueObject) + txMetadata := cachedTransactionMetadata.Unwrap() + txMetadata.setBranchID(branchmanager.BranchID{1}) + + event.Expect("PayloadSolid", valueObject, mock.Anything) + payloadBooked, err := tangle.bookPayload(cachedPayload.Retain(), cachedMetadata.Retain(), cachedTransactionMetadata.Retain()) + defer func() { + cachedPayload.Release() + cachedMetadata.Release() + cachedTransactionMetadata.Release() + }() + + require.NoError(t, err) + assert.True(t, payloadBooked, "payloadBooked") + + event.AssertExpectations(t) + }) + + t.Run("CASE: not booked", func(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + cachedPayload, cachedMetadata, _ := tangle.storePayload(valueObject) + metadata := cachedMetadata.Unwrap() + + metadata.setBranchID(branchmanager.BranchID{1}) + metadata.setBranchID(branchmanager.BranchID{1}) + + _, cachedTransactionMetadata, _, _ := tangle.storeTransactionModels(valueObject) + txMetadata := cachedTransactionMetadata.Unwrap() + txMetadata.setBranchID(branchmanager.BranchID{1}) + + event.Expect("PayloadSolid", valueObject, mock.Anything) + payloadBooked, err := tangle.bookPayload(cachedPayload.Retain(), cachedMetadata.Retain(), cachedTransactionMetadata.Retain()) + defer func() { + cachedPayload.Release() + cachedMetadata.Release() + cachedTransactionMetadata.Release() + }() + + require.NoError(t, err) + assert.False(t, payloadBooked, "payloadBooked") + + event.AssertExpectations(t) + }) + +} + +// TestStorePayload checks whether a value object is correctly stored. +func TestStorePayload(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + tx := createDummyTransaction() + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + { + cachedPayload, cachedMetadata, stored := tangle.storePayload(valueObject) + cachedPayload.Consume(func(payload *payload.Payload) { + assert.True(t, assert.ObjectsAreEqual(valueObject, payload)) + }) + cachedMetadata.Consume(func(payloadMetadata *PayloadMetadata) { + assert.Equal(t, valueObject.ID(), payloadMetadata.PayloadID()) + }) + assert.True(t, stored) + } + + // store same value object again -> should return false + { + cachedPayload, cachedMetadata, stored := tangle.storePayload(valueObject) + assert.Nil(t, cachedPayload) + assert.Nil(t, cachedMetadata) + assert.False(t, stored) + } + + // retrieve from tangle + { + cachedPayload := tangle.Payload(valueObject.ID()) + cachedPayload.Consume(func(payload *payload.Payload) { + assert.True(t, assert.ObjectsAreEqual(valueObject, payload)) + }) + cachedMetadata := tangle.PayloadMetadata(valueObject.ID()) + cachedMetadata.Consume(func(payloadMetadata *PayloadMetadata) { + assert.Equal(t, valueObject.ID(), payloadMetadata.PayloadID()) + }) + } + + event.AssertExpectations(t) +} + +// TestStoreTransactionModels checks whether all models corresponding to a transaction are correctly created. +func TestStoreTransactionModels(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + tx := createDummyTransaction() + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + { + cachedTransaction, cachedTransactionMetadata, cachedAttachment, transactionIsNew := tangle.storeTransactionModels(valueObject) + cachedTransaction.Consume(func(transaction *transaction.Transaction) { + assert.True(t, assert.ObjectsAreEqual(tx, transaction)) + }) + cachedTransactionMetadata.Consume(func(transactionMetadata *TransactionMetadata) { + assert.Equal(t, tx.ID(), transactionMetadata.ID()) + }) + expectedAttachment := NewAttachment(tx.ID(), valueObject.ID()) + cachedAttachment.Consume(func(attachment *Attachment) { + assert.Equal(t, expectedAttachment.TransactionID(), attachment.TransactionID()) + assert.Equal(t, expectedAttachment.PayloadID(), attachment.PayloadID()) + }) + assert.True(t, transactionIsNew) + } + + // add same value object with same tx again -> should return false + { + cachedTransaction, cachedTransactionMetadata, cachedAttachment, transactionIsNew := tangle.storeTransactionModels(valueObject) + cachedTransaction.Consume(func(transaction *transaction.Transaction) { + assert.True(t, assert.ObjectsAreEqual(tx, transaction)) + }) + cachedTransactionMetadata.Consume(func(transactionMetadata *TransactionMetadata) { + assert.Equal(t, tx.ID(), transactionMetadata.ID()) + }) + assert.Nil(t, cachedAttachment) + assert.False(t, transactionIsNew) + } + + // store same tx with different value object -> new attachment, same tx, transactionIsNew=false + valueObject2 := payload.New(payload.RandomID(), payload.RandomID(), tx) + { + cachedTransaction, cachedTransactionMetadata, cachedAttachment, transactionIsNew := tangle.storeTransactionModels(valueObject2) + cachedTransaction.Consume(func(transaction *transaction.Transaction) { + assert.True(t, assert.ObjectsAreEqual(tx, transaction)) + }) + cachedTransactionMetadata.Consume(func(transactionMetadata *TransactionMetadata) { + assert.Equal(t, tx.ID(), transactionMetadata.ID()) + }) + expectedAttachment := NewAttachment(tx.ID(), valueObject2.ID()) + cachedAttachment.Consume(func(attachment *Attachment) { + assert.Equal(t, expectedAttachment.TransactionID(), attachment.TransactionID()) + assert.Equal(t, expectedAttachment.PayloadID(), attachment.PayloadID()) + }) + assert.False(t, transactionIsNew) + } + + // retrieve from tangle + { + cachedTransaction := tangle.Transaction(tx.ID()) + cachedTransaction.Consume(func(transaction *transaction.Transaction) { + assert.True(t, assert.ObjectsAreEqual(tx, transaction)) + }) + cachedTransactionMetadata := tangle.TransactionMetadata(tx.ID()) + cachedTransactionMetadata.Consume(func(transactionMetadata *TransactionMetadata) { + assert.Equal(t, tx.ID(), transactionMetadata.ID()) + }) + + // check created consumers + // only reason that there could be multiple consumers = conflict, e.g. 2 tx use same inputs? + tx.Inputs().ForEach(func(inputId transaction.OutputID) bool { + expectedConsumer := NewConsumer(inputId, tx.ID()) + tangle.Consumers(inputId).Consume(func(consumer *Consumer) { + assert.Equal(t, expectedConsumer.ConsumedInput(), consumer.ConsumedInput()) + assert.Equal(t, expectedConsumer.TransactionID(), consumer.TransactionID()) + }) + return true + }) + + cachedAttachments := tangle.Attachments(tx.ID()) + assert.Len(t, cachedAttachments, 2) + attachmentPayloads := []payload.ID{valueObject.ID(), valueObject2.ID()} + cachedAttachments.Consume(func(attachment *Attachment) { + assert.Equal(t, tx.ID(), attachment.TransactionID()) + assert.Contains(t, attachmentPayloads, attachment.PayloadID()) + }) + } +} + +// TestStorePayloadReferences checks whether approvers are correctly created. +func TestStorePayloadReferences(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + tx := createDummyTransaction() + parent1 := payload.RandomID() + parent2 := payload.RandomID() + valueObject1 := payload.New(parent1, parent2, tx) + + { + tangle.storePayloadReferences(valueObject1) + + // check for approvers + approversParent1 := tangle.Approvers(parent1) + assert.Len(t, approversParent1, 1) + approversParent1.Consume(func(approver *PayloadApprover) { + assert.Equal(t, parent1, approver.referencedPayloadID) + assert.Equal(t, valueObject1.ID(), approver.ApprovingPayloadID()) + }) + + approversParent2 := tangle.Approvers(parent2) + assert.Len(t, approversParent2, 1) + approversParent2.Consume(func(approver *PayloadApprover) { + assert.Equal(t, parent2, approver.referencedPayloadID) + assert.Equal(t, valueObject1.ID(), approver.ApprovingPayloadID()) + }) + } + + valueObject2 := payload.New(parent1, parent2, createDummyTransaction()) + { + tangle.storePayloadReferences(valueObject2) + + // check for approvers + approversParent1 := tangle.Approvers(parent1) + assert.Len(t, approversParent1, 2) + valueObjectIDs := []payload.ID{valueObject1.ID(), valueObject2.ID()} + approversParent1.Consume(func(approver *PayloadApprover) { + assert.Equal(t, parent1, approver.referencedPayloadID) + assert.Contains(t, valueObjectIDs, approver.ApprovingPayloadID()) + }) + + approversParent2 := tangle.Approvers(parent2) + assert.Len(t, approversParent2, 2) + approversParent2.Consume(func(approver *PayloadApprover) { + assert.Equal(t, parent2, approver.referencedPayloadID) + assert.Contains(t, valueObjectIDs, approver.ApprovingPayloadID()) + }) + } +} + +// TestCheckTransactionOutputs checks whether inputs and outputs are correctly reconciled. +func TestCheckTransactionOutputs(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + // test happy cases with ColorIOTA + { + consumedBalances := make(map[balance.Color]int64) + consumedBalances[balance.ColorIOTA] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1000), + }, + }) + assert.True(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + { + consumedBalances := make(map[balance.Color]int64) + consumedBalances[balance.ColorIOTA] = math.MaxInt64 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, math.MaxInt64), + }, + }) + assert.True(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + { + consumedBalances := make(map[balance.Color]int64) + consumedBalances[balance.ColorIOTA] = 25123 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 122), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 5000), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 20000), + }, + }) + assert.True(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // test wrong balances + { + consumedBalances := make(map[balance.Color]int64) + consumedBalances[balance.ColorIOTA] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 122), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 5000), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 20000), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // test input overflow + { + consumedBalances := make(map[balance.Color]int64) + consumedBalances[balance.ColorIOTA] = math.MaxInt64 + consumedBalances[[32]byte{1}] = 1 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1000), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // 0, negative outputs and overflows + { + consumedBalances := make(map[balance.Color]int64) + //consumedBalances[balance.ColorIOTA] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, -1), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + + outputs = transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 0), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + + outputs = transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, math.MaxInt64), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // test happy cases with ColorNew + { + consumedBalances := make(map[balance.Color]int64) + consumedBalances[balance.ColorIOTA] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorNew, 333), + }, + address.Random(): { + balance.New(balance.ColorNew, 333), + }, + address.Random(): { + balance.New(balance.ColorNew, 334), + }, + }) + assert.True(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // test wrong balances + { + consumedBalances := make(map[balance.Color]int64) + consumedBalances[balance.ColorIOTA] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorNew, 122), + }, + address.Random(): { + balance.New(balance.ColorNew, 1), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // 0, negative outputs and overflows + { + consumedBalances := make(map[balance.Color]int64) + //consumedBalances[balance.ColorIOTA] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorNew, -1), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + + outputs = transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorNew, 0), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + + outputs = transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorNew, 1), + }, + address.Random(): { + balance.New(balance.ColorNew, math.MaxInt64), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // test happy case with colors + { + color1 := [32]byte{1} + color2 := [32]byte{2} + + consumedBalances := make(map[balance.Color]int64) + consumedBalances[color1] = 1000 + consumedBalances[color2] = 25123 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(color1, 333), + }, + address.Random(): { + balance.New(color1, 333), + }, + address.Random(): { + balance.New(color1, 334), + }, + address.Random(): { + balance.New(color2, 25000), + }, + address.Random(): { + balance.New(color2, 123), + }, + }) + assert.True(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // try to spend color that is not in inputs + { + color1 := [32]byte{1} + color2 := [32]byte{2} + + consumedBalances := make(map[balance.Color]int64) + consumedBalances[color1] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(color1, 333), + }, + address.Random(): { + balance.New(color1, 333), + }, + address.Random(): { + balance.New(color1, 334), + }, + address.Random(): { + balance.New(color2, 25000), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // try to spend more than in inputs of color + { + color1 := [32]byte{1} + + consumedBalances := make(map[balance.Color]int64) + consumedBalances[color1] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(color1, math.MaxInt64), + }, + address.Random(): { + balance.New(color1, math.MaxInt64), + }, + }) + assert.False(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } + + // combine unspent colors and colors + { + color1 := [32]byte{1} + color2 := [32]byte{2} + + consumedBalances := make(map[balance.Color]int64) + consumedBalances[color1] = 1000 + consumedBalances[color2] = 1000 + consumedBalances[balance.ColorIOTA] = 1000 + + outputs := transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(color1, 1000), + balance.New(color2, 500), + balance.New(balance.ColorNew, 500), + }, + address.Random(): { + balance.New(balance.ColorNew, 1000), + }, + }) + assert.True(t, tangle.checkTransactionOutputs(consumedBalances, outputs)) + } +} + +func TestGetCachedOutputsFromTransactionInputs(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + color1 := [32]byte{1} + + // prepare inputs for tx that we want to retrieve from tangle + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + // build tx2 spending "outputs" + tx2 := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1337), + }, + }), + ) + + // verify that outputs are retrieved correctly + { + cachedOutputs := tangle.getCachedOutputsFromTransactionInputs(tx2) + assert.Len(t, cachedOutputs, len(outputs)) + cachedOutputs.Consume(func(output *Output) { + assert.ElementsMatch(t, outputs[output.Address()], output.Balances()) + }) + } +} + +func TestRetrieveConsumedInputDetails(t *testing.T) { + // test simple happy case + { + tangle := New(mapdb.NewMapDB()) + + color1 := [32]byte{1} + + // prepare inputs for tx that we want to retrieve from tangle + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{}), + ) + + inputsSolid, cachedInputs, consumedBalances, consumedBranches, err := tangle.retrieveConsumedInputDetails(tx) + require.NoError(t, err) + assert.True(t, inputsSolid) + assert.Len(t, cachedInputs, len(outputs)) + cachedInputs.Consume(func(input *Output) { + assert.ElementsMatch(t, outputs[input.Address()], input.Balances()) + }) + assert.Equal(t, sumOutputsByColor(outputs), consumedBalances) + assert.Len(t, consumedBranches, 1) + assert.Contains(t, consumedBranches, branchmanager.MasterBranchID) + } + + // test happy case with more colors + { + tangle := New(mapdb.NewMapDB()) + + color1 := [32]byte{1} + color2 := [32]byte{2} + color3 := [32]byte{3} + + // prepare inputs for tx that we want to retrieve from tangle + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(color1, 1000), + }, + address.Random(): { + balance.New(color2, 210), + balance.New(color1, 3), + }, + address.Random(): { + balance.New(color3, 5621), + balance.New(color1, 3), + }, + } + // build tx spending "outputs" + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{}), + ) + + inputsSolid, cachedInputs, consumedBalances, consumedBranches, err := tangle.retrieveConsumedInputDetails(tx) + require.NoError(t, err) + assert.True(t, inputsSolid) + assert.Len(t, cachedInputs, len(outputs)) + cachedInputs.Consume(func(input *Output) { + assert.ElementsMatch(t, outputs[input.Address()], input.Balances()) + }) + assert.Equal(t, sumOutputsByColor(outputs), consumedBalances) + assert.Len(t, consumedBranches, 1) + assert.Contains(t, consumedBranches, branchmanager.MasterBranchID) + } + + // test int overflow + { + tangle := New(mapdb.NewMapDB()) + + // prepare inputs for tx that we want to retrieve from tangle + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, math.MaxInt64), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{}), + ) + + inputsSolid, cachedInputs, _, _, err := tangle.retrieveConsumedInputDetails(tx) + assert.Error(t, err) + assert.False(t, inputsSolid) + assert.Len(t, cachedInputs, len(outputs)) + } + + // test multiple consumed branches + { + tangle := New(mapdb.NewMapDB()) + + // prepare inputs for tx that we want to retrieve from tangle + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{}), + ) + + // modify branch of 1 output + newBranch := branchmanager.NewBranchID(transaction.RandomID()) + output := tangle.TransactionOutput(inputIDs[0]) + output.Consume(func(output *Output) { + output.branchID = newBranch + }) + + inputsSolid, cachedInputs, consumedBalances, consumedBranches, err := tangle.retrieveConsumedInputDetails(tx) + require.NoError(t, err) + assert.True(t, inputsSolid) + assert.Len(t, cachedInputs, len(outputs)) + cachedInputs.Consume(func(input *Output) { + assert.ElementsMatch(t, outputs[input.Address()], input.Balances()) + }) + assert.Equal(t, sumOutputsByColor(outputs), consumedBalances) + assert.Len(t, consumedBranches, 2) + assert.Contains(t, consumedBranches, branchmanager.MasterBranchID) + assert.Contains(t, consumedBranches, newBranch) + } +} + +func TestCheckTransactionSolidity(t *testing.T) { + // already solid tx + { + tangle := New(mapdb.NewMapDB()) + tx := createDummyTransaction() + txMetadata := NewTransactionMetadata(tx.ID()) + txMetadata.setSolid(true) + txMetadata.setBranchID(branchmanager.MasterBranchID) + + solid, consumedBranches, err := tangle.checkTransactionSolidity(tx, txMetadata) + assert.True(t, solid) + assert.Len(t, consumedBranches, 1) + assert.Contains(t, consumedBranches, branchmanager.MasterBranchID) + assert.NoError(t, err) + } + + // deleted tx + { + tangle := New(mapdb.NewMapDB()) + tx := createDummyTransaction() + txMetadata := NewTransactionMetadata(tx.ID()) + tx.Delete() + txMetadata.Delete() + + solid, consumedBranches, _ := tangle.checkTransactionSolidity(tx, txMetadata) + assert.False(t, solid) + assert.Len(t, consumedBranches, 0) + //assert.Error(t, err) + } + + // invalid tx: inputs not solid/non-existing + { + tangle := New(mapdb.NewMapDB()) + tx := createDummyTransaction() + txMetadata := NewTransactionMetadata(tx.ID()) + + solid, consumedBranches, err := tangle.checkTransactionSolidity(tx, txMetadata) + assert.False(t, solid) + assert.Len(t, consumedBranches, 0) + assert.NoError(t, err) + } + + // invalid tx: inputs do not match outputs + { + tangle := New(mapdb.NewMapDB()) + + // prepare snapshot + color1 := [32]byte{1} + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + // build tx spending wrong "outputs" + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 11337), + balance.New(color1, 1000), + }, + }), + ) + txMetadata := NewTransactionMetadata(tx.ID()) + + solid, consumedBranches, err := tangle.checkTransactionSolidity(tx, txMetadata) + assert.False(t, solid) + assert.Len(t, consumedBranches, 0) + assert.Error(t, err) + } + + // spent outputs from master branch (non-conflicting branches) + { + tangle := New(mapdb.NewMapDB()) + + // prepare snapshot + color1 := [32]byte{1} + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + balance.New(color1, 3), + }, + } + inputIDs := loadSnapshotFromOutputs(tangle, outputs) + + // build tx spending "outputs" + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + balance.New(color1, 3), + }, + }), + ) + txMetadata := NewTransactionMetadata(tx.ID()) + + solid, consumedBranches, err := tangle.checkTransactionSolidity(tx, txMetadata) + assert.True(t, solid) + assert.Len(t, consumedBranches, 1) + assert.Contains(t, consumedBranches, branchmanager.MasterBranchID) + assert.NoError(t, err) + } + + // spent outputs from conflicting branches + { + tangle := New(mapdb.NewMapDB()) + + // create conflicting branches + cachedBranch2, _ := tangle.BranchManager().Fork(branchmanager.BranchID{2}, []branchmanager.BranchID{branchmanager.MasterBranchID}, []branchmanager.ConflictID{{0}}) + branch2 := cachedBranch2.Unwrap() + defer cachedBranch2.Release() + cachedBranch3, _ := tangle.BranchManager().Fork(branchmanager.BranchID{3}, []branchmanager.BranchID{branchmanager.MasterBranchID}, []branchmanager.ConflictID{{0}}) + branch3 := cachedBranch3.Unwrap() + defer cachedBranch3.Release() + // create outputs for conflicting branches + inputIDs := make([]transaction.OutputID, 0) + for _, branch := range []*branchmanager.Branch{branch2, branch3} { + input := NewOutput(address.Random(), transaction.GenesisID, branch.ID(), []*balance.Balance{balance.New(balance.ColorIOTA, 1)}) + input.setSolid(true) + cachedObject, _ := tangle.outputStorage.StoreIfAbsent(input) + cachedOutput := &CachedOutput{CachedObject: cachedObject} + cachedOutput.Consume(func(output *Output) { + inputIDs = append(inputIDs, transaction.NewOutputID(output.Address(), transaction.GenesisID)) + }) + } + + // build tx spending "outputs" from conflicting branches + tx := transaction.New( + transaction.NewInputs(inputIDs...), + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 2), + }, + }), + ) + txMetadata := NewTransactionMetadata(tx.ID()) + + solid, consumedBranches, err := tangle.checkTransactionSolidity(tx, txMetadata) + assert.False(t, solid) + assert.Len(t, consumedBranches, 2) + assert.Contains(t, consumedBranches, branch2.ID()) + assert.Contains(t, consumedBranches, branch3.ID()) + assert.Error(t, err) + } + +} + +func TestPayloadBranchID(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + { + branchID := tangle.payloadBranchID(payload.GenesisID) + assert.Equal(t, branchmanager.MasterBranchID, branchID) + } + + // test with stored payload + { + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + cachedPayload, cachedMetadata, stored := tangle.storePayload(valueObject) + assert.True(t, stored) + cachedPayload.Release() + expectedBranchID := branchmanager.BranchID{1} + cachedMetadata.Consume(func(metadata *PayloadMetadata) { + metadata.setSolid(true) + metadata.setBranchID(expectedBranchID) + }) + + branchID := tangle.payloadBranchID(valueObject.ID()) + assert.Equal(t, expectedBranchID, branchID) + } + + // test missing value object + { + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + + event.Expect("PayloadMissing", valueObject.ID()) + branchID := tangle.payloadBranchID(valueObject.ID()) + assert.Equal(t, branchmanager.UndefinedBranchID, branchID) + } + + event.AssertExpectations(t) +} + +func TestCheckPayloadSolidity(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + // check with already solid payload + { + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + metadata := NewPayloadMetadata(valueObject.ID()) + metadata.setSolid(true) + metadata.setBranchID(branchmanager.MasterBranchID) + + transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID} + solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches) + assert.False(t, solid) + assert.NoError(t, err) + } + + // check with parents=genesis + { + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + metadata := NewPayloadMetadata(valueObject.ID()) + + transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID} + solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches) + assert.True(t, solid) + assert.NoError(t, err) + } + + // check with solid parents and branch set + { + setParent := func(payloadMetadata *PayloadMetadata) { + payloadMetadata.setSolid(true) + payloadMetadata.setBranchID(branchmanager.MasterBranchID) + } + + valueObject := payload.New(storeParentPayloadWithMetadataFunc(t, tangle, setParent), storeParentPayloadWithMetadataFunc(t, tangle, setParent), createDummyTransaction()) + metadata := NewPayloadMetadata(valueObject.ID()) + + transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID} + solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches) + assert.True(t, solid) + assert.NoError(t, err) + } + + // check with solid parents but no branch set -> should not be solid + { + setParent := func(payloadMetadata *PayloadMetadata) { + payloadMetadata.setSolid(true) + } + + valueObject := payload.New(storeParentPayloadWithMetadataFunc(t, tangle, setParent), storeParentPayloadWithMetadataFunc(t, tangle, setParent), createDummyTransaction()) + metadata := NewPayloadMetadata(valueObject.ID()) + + transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID} + solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches) + assert.False(t, solid) + assert.NoError(t, err) + } + + // conflicting branches of parents + { + // create conflicting branches + cachedBranch2, _ := tangle.BranchManager().Fork(branchmanager.BranchID{2}, []branchmanager.BranchID{branchmanager.MasterBranchID}, []branchmanager.ConflictID{{0}}) + defer cachedBranch2.Release() + cachedBranch3, _ := tangle.BranchManager().Fork(branchmanager.BranchID{3}, []branchmanager.BranchID{branchmanager.MasterBranchID}, []branchmanager.ConflictID{{0}}) + defer cachedBranch3.Release() + setParent1 := func(payloadMetadata *PayloadMetadata) { + payloadMetadata.setSolid(true) + payloadMetadata.setBranchID(branchmanager.BranchID{2}) + } + setParent2 := func(payloadMetadata *PayloadMetadata) { + payloadMetadata.setSolid(true) + payloadMetadata.setBranchID(branchmanager.BranchID{3}) + } + + valueObject := payload.New(storeParentPayloadWithMetadataFunc(t, tangle, setParent1), storeParentPayloadWithMetadataFunc(t, tangle, setParent2), createDummyTransaction()) + metadata := NewPayloadMetadata(valueObject.ID()) + + transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID} + solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches) + assert.False(t, solid) + assert.Error(t, err) + } + + // conflicting branches with transactions + { + // create conflicting branches + cachedBranch2, _ := tangle.BranchManager().Fork(branchmanager.BranchID{2}, []branchmanager.BranchID{branchmanager.MasterBranchID}, []branchmanager.ConflictID{{0}}) + defer cachedBranch2.Release() + cachedBranch3, _ := tangle.BranchManager().Fork(branchmanager.BranchID{3}, []branchmanager.BranchID{branchmanager.MasterBranchID}, []branchmanager.ConflictID{{0}}) + defer cachedBranch3.Release() + setParent1 := func(payloadMetadata *PayloadMetadata) { + payloadMetadata.setSolid(true) + payloadMetadata.setBranchID(branchmanager.MasterBranchID) + } + setParent2 := func(payloadMetadata *PayloadMetadata) { + payloadMetadata.setSolid(true) + payloadMetadata.setBranchID(branchmanager.BranchID{3}) + } + + valueObject := payload.New(storeParentPayloadWithMetadataFunc(t, tangle, setParent1), storeParentPayloadWithMetadataFunc(t, tangle, setParent2), createDummyTransaction()) + metadata := NewPayloadMetadata(valueObject.ID()) + + transactionBranches := []branchmanager.BranchID{{2}} + solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches) + assert.False(t, solid) + assert.Error(t, err) + } + + event.AssertExpectations(t) +} + +func TestCreateValuePayloadFutureConeIterator(t *testing.T) { + // check with new payload -> should be added to stack + { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + solidificationStack := list.New() + processedPayloads := make(map[payload.ID]types.Empty) + iterator := tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads) + + // create cached objects + tx := createDummyTransaction() + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + cachedPayload, cachedMetadata, stored := tangle.storePayload(valueObject) + assert.True(t, stored) + cachedTransaction, cachedTransactionMetadata, _, transactionIsNew := tangle.storeTransactionModels(valueObject) + assert.True(t, transactionIsNew) + + iterator(cachedPayload, cachedMetadata, cachedTransaction, cachedTransactionMetadata) + assert.Equal(t, 1, solidificationStack.Len()) + currentSolidificationEntry := solidificationStack.Front().Value.(*valuePayloadPropagationStackEntry) + assert.Equal(t, cachedPayload, currentSolidificationEntry.CachedPayload) + currentSolidificationEntry.CachedPayload.Consume(func(payload *payload.Payload) { + assert.Equal(t, valueObject.ID(), payload.ID()) + }) + currentSolidificationEntry.CachedPayloadMetadata.Consume(func(metadata *PayloadMetadata) { + assert.Equal(t, valueObject.ID(), metadata.PayloadID()) + }) + currentSolidificationEntry.CachedTransaction.Consume(func(transaction *transaction.Transaction) { + assert.Equal(t, tx.ID(), transaction.ID()) + }) + currentSolidificationEntry.CachedTransactionMetadata.Consume(func(metadata *TransactionMetadata) { + assert.Equal(t, tx.ID(), metadata.ID()) + }) + + event.AssertExpectations(t) + } + + // check with already processed payload -> should not be added to stack + { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + solidificationStack := list.New() + processedPayloads := make(map[payload.ID]types.Empty) + iterator := tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads) + + // create cached objects + tx := createDummyTransaction() + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + cachedPayload, cachedMetadata, stored := tangle.storePayload(valueObject) + assert.True(t, stored) + cachedTransaction, cachedTransactionMetadata, _, transactionIsNew := tangle.storeTransactionModels(valueObject) + assert.True(t, transactionIsNew) + + // payload was already processed + processedPayloads[valueObject.ID()] = types.Void + + iterator(cachedPayload, cachedMetadata, cachedTransaction, cachedTransactionMetadata) + assert.Equal(t, 0, solidificationStack.Len()) + + event.AssertExpectations(t) + } +} + +func TestForEachConsumers(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + // prepare inputs for tx + outputs := map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1), + }, + address.Random(): { + balance.New(balance.ColorIOTA, 2), + }, + } + genesisTx := transaction.New(transaction.NewInputs(), transaction.NewOutputs(outputs)) + + // store tx that uses outputs from genesisTx + outputIDs := make([]transaction.OutputID, 0) + for addr := range outputs { + outputIDs = append(outputIDs, transaction.NewOutputID(addr, genesisTx.ID())) + } + tx := transaction.New( + transaction.NewInputs(outputIDs...), + transaction.NewOutputs(map[address.Address][]*balance.Balance{}), + ) + valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx) + _, _, stored := tangle.storePayload(valueObject) + assert.True(t, stored) + _, _, _, transactionIsNew := tangle.storeTransactionModels(valueObject) + assert.True(t, transactionIsNew) + + counter := 0 + consume := func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *CachedPayloadMetadata, cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata) { + cachedPayload.Consume(func(payload *payload.Payload) { + assert.Equal(t, valueObject.ID(), payload.ID()) + }) + cachedPayloadMetadata.Consume(func(metadata *PayloadMetadata) { + assert.Equal(t, valueObject.ID(), metadata.PayloadID()) + }) + cachedTransaction.Consume(func(transaction *transaction.Transaction) { + assert.Equal(t, tx.ID(), transaction.ID()) + }) + cachedTransactionMetadata.Consume(func(metadata *TransactionMetadata) { + assert.Equal(t, tx.ID(), metadata.ID()) + }) + counter++ + } + + tangle.ForEachConsumers(genesisTx, consume) + // even though we have 2 outputs it should only be triggered once because the outputs are within 1 transaction + assert.Equal(t, 1, counter) +} + +func TestForeachApprovers(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + + valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + + // create approver 1 + tx1 := createDummyTransaction() + approver1 := payload.New(valueObject.ID(), payload.GenesisID, tx1) + _, _, stored := tangle.storePayload(approver1) + assert.True(t, stored) + _, _, _, transactionIsNew := tangle.storeTransactionModels(approver1) + tangle.storePayloadReferences(approver1) + assert.True(t, transactionIsNew) + + // create approver 2 + tx2 := createDummyTransaction() + approver2 := payload.New(valueObject.ID(), payload.GenesisID, tx2) + _, _, stored = tangle.storePayload(approver2) + assert.True(t, stored) + _, _, _, transactionIsNew = tangle.storeTransactionModels(approver2) + tangle.storePayloadReferences(approver2) + assert.True(t, transactionIsNew) + + counter := 0 + consume := func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *CachedPayloadMetadata, cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *CachedTransactionMetadata) { + cachedPayload.Consume(func(p *payload.Payload) { + assert.Contains(t, []payload.ID{approver1.ID(), approver2.ID()}, p.ID()) + }) + cachedPayloadMetadata.Consume(func(metadata *PayloadMetadata) { + assert.Contains(t, []payload.ID{approver1.ID(), approver2.ID()}, metadata.PayloadID()) + }) + cachedTransaction.Consume(func(tx *transaction.Transaction) { + assert.Contains(t, []transaction.ID{tx1.ID(), tx2.ID()}, tx.ID()) + }) + cachedTransactionMetadata.Consume(func(metadata *TransactionMetadata) { + assert.Contains(t, []transaction.ID{tx1.ID(), tx2.ID()}, metadata.ID()) + }) + counter++ + } + + tangle.ForeachApprovers(valueObject.ID(), consume) + assert.Equal(t, 2, counter) +} + +func TestMissingPayloadReceived(t *testing.T) { + tangle := New(mapdb.NewMapDB()) + event := newEventTangle(t, tangle) + defer event.DetachAll() + + // prepare snapshot + unspentOutputs := loadSnapshotFromOutputs( + tangle, + map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + }, + }, + ) + + // create transaction spending those snapshot outputs + tx := transaction.New( + transaction.NewInputs(unspentOutputs...), + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 3), + }, + }), + ) + + // create two value objects for this transaction referencing each other + parent := payload.New(payload.GenesisID, payload.GenesisID, tx) + child := payload.New(parent.ID(), parent.ID(), tx) + + event.Expect("PayloadAttached", child, mock.Anything) + event.Expect("PayloadMissing", parent.ID(), mock.Anything) + event.Expect("TransactionReceived", tx, mock.Anything, mock.Anything) + + // submit the child first; it cannot be solidified + tangle.AttachPayloadSync(child) + + event.Expect("PayloadAttached", parent, mock.Anything) + event.Expect("PayloadSolid", parent, mock.Anything) + event.Expect("MissingPayloadReceived", parent, mock.Anything) + event.Expect("PayloadSolid", child, mock.Anything) + event.Expect("TransactionSolid", tx, mock.Anything, mock.Anything) + event.Expect("TransactionBooked", tx, mock.Anything, true) + + // submitting the parent makes everything solid + tangle.AttachPayloadSync(parent) + + event.AssertExpectations(t) +} + +func storeParentPayloadWithMetadataFunc(t *testing.T, tangle *Tangle, consume func(*PayloadMetadata)) payload.ID { + parent1 := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + cachedPayload, cachedMetadata, stored := tangle.storePayload(parent1) + defer cachedPayload.Release() + + cachedMetadata.Consume(consume) + assert.True(t, stored) + + return parent1.ID() +} + +func loadSnapshotFromOutputs(tangle *Tangle, outputs map[address.Address][]*balance.Balance) []transaction.OutputID { + snapshot := map[transaction.ID]map[address.Address][]*balance.Balance{transaction.GenesisID: outputs} + tangle.LoadSnapshot(snapshot) + + outputIDs := make([]transaction.OutputID, 0) + for addr := range outputs { + outputIDs = append(outputIDs, transaction.NewOutputID(addr, transaction.GenesisID)) + } + return outputIDs +} + +func sumOutputsByColor(outputs map[address.Address][]*balance.Balance) map[balance.Color]int64 { + totals := make(map[balance.Color]int64) + + for _, balances := range outputs { + for _, bal := range balances { + totals[bal.Color] += bal.Value + } + } + + return totals +} + +func createDummyTransaction() *transaction.Transaction { + return transaction.New( + // inputs + transaction.NewInputs( + transaction.NewOutputID(address.Random(), transaction.RandomID()), + transaction.NewOutputID(address.Random(), transaction.RandomID()), + ), + + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1337), + }, + }), + ) +} diff --git a/dapps/valuetransfers/packages/tangle/transactionmetadata.go b/dapps/valuetransfers/packages/tangle/transactionmetadata.go new file mode 100644 index 0000000000000000000000000000000000000000..753e70593a2e141c092ff2553a31e340d386c3ee --- /dev/null +++ b/dapps/valuetransfers/packages/tangle/transactionmetadata.go @@ -0,0 +1,480 @@ +package tangle + +import ( + "sync" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" +) + +// TransactionMetadata contains the information of a Transaction, that are based on our local perception of things (i.e. if it is +// solid, or when we it became solid). +type TransactionMetadata struct { + objectstorage.StorableObjectFlags + + id transaction.ID + branchID branchmanager.BranchID + solid bool + preferred bool + finalized bool + liked bool + confirmed bool + rejected bool + solidificationTime time.Time + finalizationTime time.Time + + branchIDMutex sync.RWMutex + solidMutex sync.RWMutex + preferredMutex sync.RWMutex + finalizedMutex sync.RWMutex + likedMutex sync.RWMutex + confirmedMutex sync.RWMutex + rejectedMutex sync.RWMutex + solidificationTimeMutex sync.RWMutex +} + +// NewTransactionMetadata is the constructor for the TransactionMetadata type. +func NewTransactionMetadata(id transaction.ID) *TransactionMetadata { + return &TransactionMetadata{ + id: id, + } +} + +// TransactionMetadataFromBytes unmarshals a TransactionMetadata object from a sequence of bytes. +// It either creates a new object or fills the optionally provided object with the parsed information. +func TransactionMetadataFromBytes(bytes []byte, optionalTargetObject ...*TransactionMetadata) (result *TransactionMetadata, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseTransactionMetadata(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// TransactionMetadataFromStorageKey get's called when we restore TransactionMetadata from the storage. +// In contrast to other database models, it unmarshals some information from the key so we simply store the key before +// it gets handed over to UnmarshalObjectStorageValue (by the ObjectStorage). +func TransactionMetadataFromStorageKey(keyBytes []byte, optionalTargetObject ...*TransactionMetadata) (result *TransactionMetadata, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &TransactionMetadata{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to TransactionMetadataFromStorageKey") + } + + // parse information + marshalUtil := marshalutil.New(keyBytes) + result.id, err = transaction.ParseID(marshalUtil) + if err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseTransactionMetadata is a wrapper for simplified unmarshaling of TransactionMetadata objects from a byte stream using the marshalUtil package. +func ParseTransactionMetadata(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*TransactionMetadata) (result *TransactionMetadata, err error) { + parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return TransactionMetadataFromStorageKey(data, optionalTargetObject...) + }) + if parseErr != nil { + err = parseErr + + return + } + + result = parsedObject.(*TransactionMetadata) + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ID return the id of the Transaction that this TransactionMetadata is associated to. +func (transactionMetadata *TransactionMetadata) ID() transaction.ID { + return transactionMetadata.id +} + +// BranchID returns the identifier of the Branch, that this transaction is booked into. +func (transactionMetadata *TransactionMetadata) BranchID() branchmanager.BranchID { + transactionMetadata.branchIDMutex.RLock() + defer transactionMetadata.branchIDMutex.RUnlock() + + return transactionMetadata.branchID +} + +// setBranchID is the setter for the branch id. It returns true if the value of the flag has been updated. +func (transactionMetadata *TransactionMetadata) setBranchID(branchID branchmanager.BranchID) (modified bool) { + transactionMetadata.branchIDMutex.RLock() + if transactionMetadata.branchID == branchID { + transactionMetadata.branchIDMutex.RUnlock() + + return + } + + transactionMetadata.branchIDMutex.RUnlock() + transactionMetadata.branchIDMutex.Lock() + defer transactionMetadata.branchIDMutex.Unlock() + + if transactionMetadata.branchID == branchID { + return + } + + transactionMetadata.branchID = branchID + transactionMetadata.SetModified() + modified = true + + return +} + +// Conflicting returns true if the Transaction has been forked into its own Branch and there is a vote going on. +func (transactionMetadata *TransactionMetadata) Conflicting() bool { + return transactionMetadata.BranchID() == branchmanager.NewBranchID(transactionMetadata.ID()) +} + +// Solid returns true if the Transaction has been marked as solid. +func (transactionMetadata *TransactionMetadata) Solid() (result bool) { + transactionMetadata.solidMutex.RLock() + result = transactionMetadata.solid + transactionMetadata.solidMutex.RUnlock() + + return +} + +// setSolid marks a Transaction as either solid or not solid. +// It returns true if the solid flag was changes and automatically updates the solidificationTime as well. +func (transactionMetadata *TransactionMetadata) setSolid(solid bool) (modified bool) { + transactionMetadata.solidMutex.RLock() + if transactionMetadata.solid != solid { + transactionMetadata.solidMutex.RUnlock() + + transactionMetadata.solidMutex.Lock() + if transactionMetadata.solid != solid { + transactionMetadata.solid = solid + if solid { + transactionMetadata.solidificationTimeMutex.Lock() + transactionMetadata.solidificationTime = time.Now() + transactionMetadata.solidificationTimeMutex.Unlock() + } + + transactionMetadata.SetModified() + + modified = true + } + transactionMetadata.solidMutex.Unlock() + + } else { + transactionMetadata.solidMutex.RUnlock() + } + + return +} + +// Preferred returns true if the transaction is considered to be the first valid spender of all of its Inputs. +func (transactionMetadata *TransactionMetadata) Preferred() (result bool) { + transactionMetadata.preferredMutex.RLock() + defer transactionMetadata.preferredMutex.RUnlock() + + return transactionMetadata.preferred +} + +// setPreferred updates the preferred flag of the transaction. It is defined as a private setter because updating the +// preferred flag causes changes in other transactions and branches as well. This means that we need additional logic +// in the tangle. To update the preferred flag of a transaction, we need to use Tangle.SetTransactionPreferred(bool). +func (transactionMetadata *TransactionMetadata) setPreferred(preferred bool) (modified bool) { + transactionMetadata.preferredMutex.RLock() + if transactionMetadata.preferred == preferred { + transactionMetadata.preferredMutex.RUnlock() + + return + } + + transactionMetadata.preferredMutex.RUnlock() + transactionMetadata.preferredMutex.Lock() + defer transactionMetadata.preferredMutex.Unlock() + + if transactionMetadata.preferred == preferred { + return + } + + transactionMetadata.preferred = preferred + transactionMetadata.SetModified() + modified = true + + return +} + +// setFinalized allows us to set the finalized flag on the transactions. Finalized transactions will not be forked when +// a conflict arrives later. +func (transactionMetadata *TransactionMetadata) setFinalized(finalized bool) (modified bool) { + transactionMetadata.finalizedMutex.RLock() + if transactionMetadata.finalized == finalized { + transactionMetadata.finalizedMutex.RUnlock() + + return + } + + transactionMetadata.finalizedMutex.RUnlock() + transactionMetadata.finalizedMutex.Lock() + defer transactionMetadata.finalizedMutex.Unlock() + + if transactionMetadata.finalized == finalized { + return + } + + transactionMetadata.finalized = finalized + transactionMetadata.SetModified() + if finalized { + transactionMetadata.finalizationTime = time.Now() + } + modified = true + + return +} + +// Finalized returns true, if the decision if this transaction is liked or not has been finalized by consensus already. +func (transactionMetadata *TransactionMetadata) Finalized() bool { + transactionMetadata.finalizedMutex.RLock() + defer transactionMetadata.finalizedMutex.RUnlock() + + return transactionMetadata.finalized +} + +// Liked returns true if the Transaction was marked as liked. +func (transactionMetadata *TransactionMetadata) Liked() bool { + transactionMetadata.likedMutex.RLock() + defer transactionMetadata.likedMutex.RUnlock() + + return transactionMetadata.liked +} + +// setLiked modifies the liked flag of the given Transaction. It returns true if the value has been updated. +func (transactionMetadata *TransactionMetadata) setLiked(liked bool) (modified bool) { + transactionMetadata.likedMutex.RLock() + if transactionMetadata.liked == liked { + transactionMetadata.likedMutex.RUnlock() + + return + } + + transactionMetadata.likedMutex.RUnlock() + transactionMetadata.likedMutex.Lock() + defer transactionMetadata.likedMutex.Unlock() + + if transactionMetadata.liked == liked { + return + } + + transactionMetadata.liked = liked + transactionMetadata.SetModified() + modified = true + + return +} + +// Confirmed returns true if the Transaction was marked as confirmed. +func (transactionMetadata *TransactionMetadata) Confirmed() bool { + transactionMetadata.confirmedMutex.RLock() + defer transactionMetadata.confirmedMutex.RUnlock() + + return transactionMetadata.confirmed +} + +// setConfirmed modifies the confirmed flag of the given Transaction. It returns true if the value has been updated. +func (transactionMetadata *TransactionMetadata) setConfirmed(confirmed bool) (modified bool) { + transactionMetadata.confirmedMutex.RLock() + if transactionMetadata.confirmed == confirmed { + transactionMetadata.confirmedMutex.RUnlock() + + return + } + + transactionMetadata.confirmedMutex.RUnlock() + transactionMetadata.confirmedMutex.Lock() + defer transactionMetadata.confirmedMutex.Unlock() + + if transactionMetadata.confirmed == confirmed { + return + } + + transactionMetadata.confirmed = confirmed + transactionMetadata.SetModified() + modified = true + + return +} + +// Rejected returns true if the Transaction was marked as confirmed. +func (transactionMetadata *TransactionMetadata) Rejected() bool { + transactionMetadata.rejectedMutex.RLock() + defer transactionMetadata.rejectedMutex.RUnlock() + + return transactionMetadata.rejected +} + +// setRejected modifies the rejected flag of the given Transaction. It returns true if the value has been updated. +func (transactionMetadata *TransactionMetadata) setRejected(rejected bool) (modified bool) { + transactionMetadata.rejectedMutex.RLock() + if transactionMetadata.rejected == rejected { + transactionMetadata.rejectedMutex.RUnlock() + + return + } + + transactionMetadata.rejectedMutex.RUnlock() + transactionMetadata.rejectedMutex.Lock() + defer transactionMetadata.rejectedMutex.Unlock() + + if transactionMetadata.rejected == rejected { + return + } + + transactionMetadata.rejected = rejected + transactionMetadata.SetModified() + modified = true + + return +} + +// FinalizationTime returns the time when this transaction was finalized. +func (transactionMetadata *TransactionMetadata) FinalizationTime() time.Time { + transactionMetadata.finalizedMutex.RLock() + defer transactionMetadata.finalizedMutex.RUnlock() + + return transactionMetadata.finalizationTime +} + +// SolidificationTime returns the time when the Transaction was marked to be solid. +func (transactionMetadata *TransactionMetadata) SolidificationTime() time.Time { + transactionMetadata.solidificationTimeMutex.RLock() + defer transactionMetadata.solidificationTimeMutex.RUnlock() + + return transactionMetadata.solidificationTime +} + +// Bytes marshals the TransactionMetadata object into a sequence of bytes. +func (transactionMetadata *TransactionMetadata) Bytes() []byte { + return marshalutil.New(branchmanager.BranchIDLength + 2*marshalutil.TIME_SIZE + 6*marshalutil.BOOL_SIZE). + WriteBytes(transactionMetadata.BranchID().Bytes()). + WriteTime(transactionMetadata.SolidificationTime()). + WriteTime(transactionMetadata.FinalizationTime()). + WriteBool(transactionMetadata.Solid()). + WriteBool(transactionMetadata.Preferred()). + WriteBool(transactionMetadata.Finalized()). + WriteBool(transactionMetadata.Liked()). + WriteBool(transactionMetadata.Confirmed()). + WriteBool(transactionMetadata.Rejected()). + Bytes() +} + +// String creates a human readable version of the metadata (for debug purposes). +func (transactionMetadata *TransactionMetadata) String() string { + return stringify.Struct("transaction.TransactionMetadata", + stringify.StructField("id", transactionMetadata.ID()), + stringify.StructField("branchId", transactionMetadata.BranchID()), + stringify.StructField("solid", transactionMetadata.Solid()), + stringify.StructField("solidificationTime", transactionMetadata.SolidificationTime()), + ) +} + +// ObjectStorageKey returns the key that is used to identify the TransactionMetadata in the objectstorage. +func (transactionMetadata *TransactionMetadata) ObjectStorageKey() []byte { + return transactionMetadata.id.Bytes() +} + +// Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters. +func (transactionMetadata *TransactionMetadata) Update(other objectstorage.StorableObject) { + panic("update forbidden") +} + +// ObjectStorageValue marshals the TransactionMetadata object into a sequence of bytes and matches the encoding.BinaryMarshaler +// interface. +func (transactionMetadata *TransactionMetadata) ObjectStorageValue() []byte { + return transactionMetadata.Bytes() +} + +// UnmarshalObjectStorageValue restores the values of a TransactionMetadata object from a sequence of bytes and matches the +// encoding.BinaryUnmarshaler interface. +func (transactionMetadata *TransactionMetadata) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + if transactionMetadata.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { + return + } + if transactionMetadata.solidificationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if transactionMetadata.finalizationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if transactionMetadata.solid, err = marshalUtil.ReadBool(); err != nil { + return + } + if transactionMetadata.preferred, err = marshalUtil.ReadBool(); err != nil { + return + } + if transactionMetadata.finalized, err = marshalUtil.ReadBool(); err != nil { + return + } + if transactionMetadata.liked, err = marshalUtil.ReadBool(); err != nil { + return + } + if transactionMetadata.confirmed, err = marshalUtil.ReadBool(); err != nil { + return + } + if transactionMetadata.rejected, err = marshalUtil.ReadBool(); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// CachedTransactionMetadata is a wrapper for the object storage, that takes care of type casting the TransactionMetadata objects. +// Since go does not have generics (yet), the object storage works based on the generic "interface{}" type, which means +// that we have to regularly type cast the returned objects, to match the expected type. To reduce the burden of +// manually managing these type, we create a wrapper that does this for us. This way, we can consistently handle the +// specialized types of TransactionMetadata, without having to manually type cast over and over again. +type CachedTransactionMetadata struct { + objectstorage.CachedObject +} + +// Retain overrides the underlying method to return a new CachedTransactionMetadata instead of a generic CachedObject. +func (cachedTransactionMetadata *CachedTransactionMetadata) Retain() *CachedTransactionMetadata { + return &CachedTransactionMetadata{cachedTransactionMetadata.CachedObject.Retain()} +} + +// Consume overrides the underlying method to use a CachedTransactionMetadata object instead of a generic CachedObject in the +// consumer). +func (cachedTransactionMetadata *CachedTransactionMetadata) Consume(consumer func(metadata *TransactionMetadata)) bool { + return cachedTransactionMetadata.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*TransactionMetadata)) + }) +} + +// Unwrap provides a way to retrieve a type casted version of the underlying object. +func (cachedTransactionMetadata *CachedTransactionMetadata) Unwrap() *TransactionMetadata { + untypedTransaction := cachedTransactionMetadata.Get() + if untypedTransaction == nil { + return nil + } + + typeCastedTransaction := untypedTransaction.(*TransactionMetadata) + if typeCastedTransaction == nil || typeCastedTransaction.IsDeleted() { + return nil + } + + return typeCastedTransaction +} + +// Interface contract: make compiler warn if the interface is not implemented correctly. +var _ objectstorage.StorableObject = &TransactionMetadata{} diff --git a/dapps/valuetransfers/packages/test/tangle_test.go b/dapps/valuetransfers/packages/test/tangle_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a45803700ff263a6b7d8e293f386c17f04698071 --- /dev/null +++ b/dapps/valuetransfers/packages/test/tangle_test.go @@ -0,0 +1,121 @@ +package test + +import ( + "fmt" + "testing" + + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/iotaledger/hive.go/types" + + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/consensus" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" +) + +func TestTangle_ValueTransfer(t *testing.T) { + // initialize tangle + valueTangle := tangle.New(mapdb.NewMapDB()) + defer valueTangle.Shutdown() + + // initialize ledger state + ledgerState := tangle.NewLedgerState(valueTangle) + + // initialize seed + seed := wallet.NewSeed() + + // setup consensus rules + consensus.NewFCOB(valueTangle, 0) + + // check if ledger empty first + assert.Equal(t, map[balance.Color]int64{}, ledgerState.Balances(seed.Address(0))) + assert.Equal(t, map[balance.Color]int64{}, ledgerState.Balances(seed.Address(1))) + + // load snapshot + valueTangle.LoadSnapshot(map[transaction.ID]map[address.Address][]*balance.Balance{ + transaction.GenesisID: { + seed.Address(0): []*balance.Balance{ + balance.New(balance.ColorIOTA, 337), + }, + + seed.Address(1): []*balance.Balance{ + balance.New(balance.ColorIOTA, 1000), + }, + }, + }) + + // check if balance exists after loading snapshot + assert.Equal(t, map[balance.Color]int64{balance.ColorIOTA: 337}, ledgerState.Balances(seed.Address(0))) + assert.Equal(t, map[balance.Color]int64{balance.ColorIOTA: 1000}, ledgerState.Balances(seed.Address(1))) + + // introduce logic to record liked payloads + recordedLikedPayloads, resetRecordedLikedPayloads := recordLikedPayloads(valueTangle) + + // attach first spend + outputAddress1 := address.Random() + attachedPayload1 := payload.New(payload.GenesisID, payload.GenesisID, transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(0), transaction.GenesisID), + transaction.NewOutputID(seed.Address(1), transaction.GenesisID), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + outputAddress1: { + balance.New(balance.ColorIOTA, 1337), + }, + }), + )) + valueTangle.AttachPayloadSync(attachedPayload1) + + valueTangle.PayloadMetadata(attachedPayload1.ID()).Consume(func(payload *tangle.PayloadMetadata) { + fmt.Println(payload.Confirmed()) + }) + + // check if old addresses are empty and new addresses are filled + assert.Equal(t, map[balance.Color]int64{}, ledgerState.Balances(seed.Address(0))) + assert.Equal(t, map[balance.Color]int64{}, ledgerState.Balances(seed.Address(1))) + assert.Equal(t, map[balance.Color]int64{balance.ColorIOTA: 1337}, ledgerState.Balances(outputAddress1)) + assert.Equal(t, 1, len(recordedLikedPayloads)) + assert.Contains(t, recordedLikedPayloads, attachedPayload1.ID()) + + resetRecordedLikedPayloads() + + // attach double spend + outputAddress2 := address.Random() + valueTangle.AttachPayloadSync(payload.New(payload.GenesisID, payload.GenesisID, transaction.New( + transaction.NewInputs( + transaction.NewOutputID(seed.Address(0), transaction.GenesisID), + transaction.NewOutputID(seed.Address(1), transaction.GenesisID), + ), + + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + outputAddress2: { + balance.New(balance.ColorNew, 1337), + }, + }), + ))) +} + +func recordLikedPayloads(valueTangle *tangle.Tangle) (recordedLikedPayloads map[payload.ID]types.Empty, resetFunc func()) { + recordedLikedPayloads = make(map[payload.ID]types.Empty) + + valueTangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *tangle.CachedPayloadMetadata) { + defer cachedPayloadMetadata.Release() + + cachedPayload.Consume(func(payload *payload.Payload) { + recordedLikedPayloads[payload.ID()] = types.Void + }) + })) + + resetFunc = func() { + recordedLikedPayloads = make(map[payload.ID]types.Empty) + } + + return +} diff --git a/dapps/valuetransfers/packages/tipmanager/events.go b/dapps/valuetransfers/packages/tipmanager/events.go new file mode 100644 index 0000000000000000000000000000000000000000..13a4c05e28bf239b9e9b2f144aabbe7d2723d7f3 --- /dev/null +++ b/dapps/valuetransfers/packages/tipmanager/events.go @@ -0,0 +1,18 @@ +package tipmanager + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/hive.go/events" +) + +// Events represents events happening on the TipManager. +type Events struct { + // Fired when a tip is added. + TipAdded *events.Event + // Fired when a tip is removed. + TipRemoved *events.Event +} + +func payloadIDEvent(handler interface{}, params ...interface{}) { + handler.(func(payload.ID))(params[0].(payload.ID)) +} diff --git a/dapps/valuetransfers/packages/tipmanager/tipmanager.go b/dapps/valuetransfers/packages/tipmanager/tipmanager.go new file mode 100644 index 0000000000000000000000000000000000000000..edb1ac8d1edddc0e1df8c6eb3413c19b37414eaf --- /dev/null +++ b/dapps/valuetransfers/packages/tipmanager/tipmanager.go @@ -0,0 +1,83 @@ +package tipmanager + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/packages/binary/datastructure" + "github.com/iotaledger/hive.go/events" +) + +// TipManager manages liked tips and emits events for their removal and addition. +type TipManager struct { + // tips are all currently liked tips. + tips *datastructure.RandomMap + Events Events +} + +// New creates a new TipManager. +func New() *TipManager { + return &TipManager{ + tips: datastructure.NewRandomMap(), + Events: Events{ + TipAdded: events.NewEvent(payloadIDEvent), + TipRemoved: events.NewEvent(payloadIDEvent), + }, + } +} + +// AddTip adds the given value object as a tip. +func (t *TipManager) AddTip(valueObject *payload.Payload) { + objectID := valueObject.ID() + parent1ID := valueObject.TrunkID() + parent2ID := valueObject.BranchID() + + if t.tips.Set(objectID, objectID) { + t.Events.TipAdded.Trigger(objectID) + } + + // remove parents + if _, deleted := t.tips.Delete(parent1ID); deleted { + t.Events.TipRemoved.Trigger(parent1ID) + } + if _, deleted := t.tips.Delete(parent2ID); deleted { + t.Events.TipRemoved.Trigger(parent2ID) + } +} + +// RemoveTip removes the given value object as a tip. +func (t *TipManager) RemoveTip(valueObject *payload.Payload) { + objectID := valueObject.ID() + + if _, deleted := t.tips.Delete(objectID); deleted { + t.Events.TipRemoved.Trigger(objectID) + } +} + +// Tips returns two randomly selected tips. +func (t *TipManager) Tips() (parent1ObjectID, parent2ObjectID payload.ID) { + tip := t.tips.RandomEntry() + if tip == nil { + parent1ObjectID = payload.GenesisID + parent2ObjectID = payload.GenesisID + return + } + + parent1ObjectID = tip.(payload.ID) + + if t.tips.Size() == 1 { + parent2ObjectID = parent1ObjectID + return + } + + parent2ObjectID = t.tips.RandomEntry().(payload.ID) + // select 2 distinct tips if there's more than 1 tip available + for parent1ObjectID == parent2ObjectID && t.tips.Size() > 1 { + parent2ObjectID = t.tips.RandomEntry().(payload.ID) + } + + return +} + +// Size returns the total liked tips. +func (t *TipManager) Size() int { + return t.tips.Size() +} diff --git a/dapps/valuetransfers/packages/tipmanager/tipmanager_test.go b/dapps/valuetransfers/packages/tipmanager/tipmanager_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f3d2db45b7b979aa6884ab74c7a7efbe1f262dba --- /dev/null +++ b/dapps/valuetransfers/packages/tipmanager/tipmanager_test.go @@ -0,0 +1,132 @@ +package tipmanager + +import ( + "sync" + "sync/atomic" + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/events" + "github.com/stretchr/testify/assert" +) + +// TestTipManager tests the functionality of the TipManager. +func TestTipManager(t *testing.T) { + tipManager := New() + + // check if first tips point to genesis + parent1, parent2 := tipManager.Tips() + assert.Equal(t, payload.GenesisID, parent1) + assert.Equal(t, payload.GenesisID, parent2) + + // create value object and add it + v := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + tipManager.AddTip(v) + + // check count + assert.Equal(t, 1, tipManager.Size()) + + // check if both reference it + parent1, parent2 = tipManager.Tips() + assert.Equal(t, v.ID(), parent1) + assert.Equal(t, v.ID(), parent2) + + // create value object and add it + v2 := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + tipManager.AddTip(v2) + + // check count + assert.Equal(t, 2, tipManager.Size()) + + // attach new value object to previous 2 tips + parent1, parent2 = tipManager.Tips() + assert.Contains(t, []payload.ID{v.ID(), v2.ID()}, parent1) + assert.Contains(t, []payload.ID{v.ID(), v2.ID()}, parent2) + v3 := payload.New(parent1, parent2, createDummyTransaction()) + tipManager.AddTip(v3) + + // check that parents are removed + assert.Equal(t, 1, tipManager.Size()) + parent1, parent2 = tipManager.Tips() + assert.Equal(t, v3.ID(), parent1) + assert.Equal(t, v3.ID(), parent2) +} + +// TestTipManagerParallel tests the TipManager's functionality by adding and selecting tips concurrently. +func TestTipManagerConcurrent(t *testing.T) { + numThreads := 10 + numTips := 100 + numSelected := 10 + + var tipsAdded uint64 + countTipAdded := events.NewClosure(func(valueObjectID payload.ID) { + atomic.AddUint64(&tipsAdded, 1) + }) + var tipsRemoved uint64 + countTipRemoved := events.NewClosure(func(valueObjectID payload.ID) { + atomic.AddUint64(&tipsRemoved, 1) + }) + + var wg sync.WaitGroup + tipManager := New() + tipManager.Events.TipAdded.Attach(countTipAdded) + tipManager.Events.TipRemoved.Attach(countTipRemoved) + + for t := 0; t < numThreads; t++ { + wg.Add(1) + go func() { + defer wg.Done() + + tips := make(map[payload.ID]struct{}) + // add a bunch of tips + for i := 0; i < numTips; i++ { + v := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction()) + tipManager.AddTip(v) + tips[v.ID()] = struct{}{} + } + // add a bunch of tips that reference previous tips + for i := 0; i < numSelected; i++ { + v := payload.New(randomTip(tips), randomTip(tips), createDummyTransaction()) + tipManager.AddTip(v) + } + }() + } + + wg.Wait() + + // check if count matches and corresponding events have been triggered + assert.EqualValues(t, numTips*numThreads+numSelected*numThreads, tipsAdded) + assert.EqualValues(t, 2*numSelected*numThreads, tipsRemoved) + assert.EqualValues(t, numTips*numThreads-numSelected*numThreads, tipManager.Size()) +} + +func randomTip(tips map[payload.ID]struct{}) payload.ID { + var tip payload.ID + + for k := range tips { + tip = k + } + delete(tips, tip) + + return tip +} + +func createDummyTransaction() *transaction.Transaction { + return transaction.New( + // inputs + transaction.NewInputs( + transaction.NewOutputID(address.Random(), transaction.RandomID()), + transaction.NewOutputID(address.Random(), transaction.RandomID()), + ), + + // outputs + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + address.Random(): { + balance.New(balance.ColorIOTA, 1337), + }, + }), + ) +} diff --git a/dapps/valuetransfers/packages/transaction/id.go b/dapps/valuetransfers/packages/transaction/id.go new file mode 100644 index 0000000000000000000000000000000000000000..f1acc5e7ef17d5d5702d6472b3dcae0877e2aac8 --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/id.go @@ -0,0 +1,88 @@ +package transaction + +import ( + "crypto/rand" + "fmt" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/mr-tron/base58" +) + +// ID is the data type that represents the identifier for a Transaction. +type ID [IDLength]byte + +// IDFromBase58 creates an id from a base58 encoded string. +func IDFromBase58(base58String string) (id ID, err error) { + // decode string + bytes, err := base58.Decode(base58String) + if err != nil { + return + } + + // sanitize input + if len(bytes) != IDLength { + err = fmt.Errorf("base58 encoded string does not match the length of a transaction id") + + return + } + + // copy bytes to result + copy(id[:], bytes) + + return +} + +// IDFromBytes unmarshals an ID from a sequence of bytes. +func IDFromBytes(bytes []byte) (result ID, consumedBytes int, err error) { + // parse the bytes + marshalUtil := marshalutil.New(bytes) + idBytes, idErr := marshalUtil.ReadBytes(IDLength) + if idErr != nil { + err = idErr + + return + } + copy(result[:], idBytes) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseID is a wrapper for simplified unmarshaling of Ids from a byte stream using the marshalUtil package. +func ParseID(marshalUtil *marshalutil.MarshalUtil) (ID, error) { + id, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return IDFromBytes(data) }) + if err != nil { + return ID{}, err + } + + return id.(ID), nil +} + +// RandomID creates a random id which can for example be used in unit tests. +func RandomID() (id ID) { + // generate a random sequence of bytes + idBytes := make([]byte, IDLength) + if _, err := rand.Read(idBytes); err != nil { + panic(err) + } + + // copy the generated bytes into the result + copy(id[:], idBytes) + + return +} + +// Bytes marshals the ID into a sequence of bytes. +func (id ID) Bytes() []byte { + return id[:] +} + +// String creates a human readable version of the ID (for debug purposes). +func (id ID) String() string { + return base58.Encode(id[:]) +} + +var GenesisID ID + +// IDLength contains the amount of bytes that a marshaled version of the ID contains. +const IDLength = 32 diff --git a/dapps/valuetransfers/packages/transaction/inputs.go b/dapps/valuetransfers/packages/transaction/inputs.go new file mode 100644 index 0000000000000000000000000000000000000000..bfc8ea13980fa6ead451063438495904ab2e51b9 --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/inputs.go @@ -0,0 +1,161 @@ +package transaction + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap" + "github.com/iotaledger/hive.go/marshalutil" +) + +// Inputs represents a list of referenced Outputs that are used as Inputs in a transaction. +type Inputs struct { + *orderedmap.OrderedMap +} + +// NewInputs is the constructor of the Inputs object and creates a new list with the given OutputIds. +func NewInputs(outputIds ...OutputID) (inputs *Inputs) { + inputs = &Inputs{orderedmap.New()} + for _, outputID := range outputIds { + inputs.Add(outputID) + } + + return +} + +// InputsFromBytes unmarshals the Inputs from a sequence of bytes. +func InputsFromBytes(bytes []byte) (inputs *Inputs, consumedBytes int, err error) { + inputs = NewInputs() + + marshalUtil := marshalutil.New(bytes) + inputCount, err := marshalUtil.ReadUint32() + if err != nil { + return + } + + for i := uint32(0); i < inputCount; i++ { + readAddress, addressErr := address.Parse(marshalUtil) + if addressErr != nil { + err = addressErr + + return + } + + idBytes, readErr := marshalUtil.ReadBytes(IDLength) + if readErr != nil { + err = readErr + + return + } + id, _, idErr := IDFromBytes(idBytes) + if idErr != nil { + err = idErr + + return + } + + addressMap, addressExists := inputs.Get(readAddress) + if !addressExists { + addressMap = orderedmap.New() + + inputs.Set(readAddress, addressMap) + } + addressMap.(*orderedmap.OrderedMap).Set(id, NewOutputID(readAddress, id)) + } + + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Add allows us to add a new Output to the list of Inputs. +func (inputs *Inputs) Add(input OutputID) *Inputs { + inputAddress := input.Address() + transactionID := input.TransactionID() + + addressMap, addressExists := inputs.Get(inputAddress) + if !addressExists { + addressMap = orderedmap.New() + + inputs.Set(inputAddress, addressMap) + } + + addressMap.(*orderedmap.OrderedMap).Set(transactionID, input) + + return inputs +} + +// Bytes returns a marshaled version of this list of Inputs. +func (inputs *Inputs) Bytes() (bytes []byte) { + marshalUtil := marshalutil.New() + + marshalUtil.WriteSeek(4) + var inputCounter uint32 + inputs.ForEach(func(outputId OutputID) bool { + marshalUtil.WriteBytes(outputId.Bytes()) + + inputCounter++ + + return true + }) + marshalUtil.WriteSeek(0) + marshalUtil.WriteUint32(inputCounter) + + return marshalUtil.Bytes() +} + +// ForEach iterates through the referenced Outputs and calls the consumer function for every Output. The iteration can +// be aborted by returning false in the consumer. +func (inputs *Inputs) ForEach(consumer func(outputId OutputID) bool) bool { + return inputs.OrderedMap.ForEach(func(key, value interface{}) bool { + return value.(*orderedmap.OrderedMap).ForEach(func(key, value interface{}) bool { + return consumer(value.(OutputID)) + }) + }) +} + +// ForEachAddress iterates through the input addresses and calls the consumer function for every Address. The iteration +// can be aborted by returning false in the consumer. +func (inputs *Inputs) ForEachAddress(consumer func(currentAddress address.Address) bool) bool { + return inputs.OrderedMap.ForEach(func(key, value interface{}) bool { + return consumer(key.(address.Address)) + }) +} + +// ForEachTransaction iterates through the transactions that had their Outputs consumed and calls the consumer function +// for every founds transaction. The iteration can be aborted by returning false in the consumer. +func (inputs *Inputs) ForEachTransaction(consumer func(transactionId ID) bool) bool { + seenTransactions := make(map[ID]bool) + + return inputs.ForEach(func(outputId OutputID) bool { + if currentTransactionID := outputId.TransactionID(); !seenTransactions[currentTransactionID] { + seenTransactions[currentTransactionID] = true + + return consumer(currentTransactionID) + } + + return true + }) +} + +// String returns a human readable version of the list of Inputs (for debug purposes). +func (inputs *Inputs) String() string { + if inputs == nil { + return "<nil>" + } + + result := "[\n" + + empty := true + inputs.ForEach(func(outputId OutputID) bool { + empty = false + + result += " " + outputId.String() + ",\n" + + return true + }) + + if empty { + result += " <empty>\n" + } + + return result + "]" +} diff --git a/dapps/valuetransfers/packages/transaction/outputid.go b/dapps/valuetransfers/packages/transaction/outputid.go new file mode 100644 index 0000000000000000000000000000000000000000..4d6aff44511f87566350219356b0aa76f195bd6e --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/outputid.go @@ -0,0 +1,94 @@ +package transaction + +import ( + "fmt" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/mr-tron/base58" +) + +// OutputID is the data type that represents the identifier for a Output. +type OutputID [OutputIDLength]byte + +// NewOutputID is the constructor for the OutputID type. +func NewOutputID(outputAddress address.Address, transactionID ID) (outputID OutputID) { + copy(outputID[:address.Length], outputAddress.Bytes()) + copy(outputID[address.Length:], transactionID[:]) + + return +} + +// OutputIDFromBase58 creates an output id from a base58 encoded string. +func OutputIDFromBase58(base58String string) (outputid OutputID, err error) { + // decode string + bytes, err := base58.Decode(base58String) + if err != nil { + return + } + + // sanitize input + if len(bytes) != OutputIDLength { + err = fmt.Errorf("base58 encoded string does not match the length of a output id") + + return + } + + // copy bytes to result + copy(outputid[:], bytes) + + return +} + +// OutputIDFromBytes unmarshals an OutputID from a sequence of bytes. +func OutputIDFromBytes(bytes []byte) (result OutputID, consumedBytes int, err error) { + // parse the bytes + marshalUtil := marshalutil.New(bytes) + idBytes, idErr := marshalUtil.ReadBytes(OutputIDLength) + if idErr != nil { + err = idErr + + return + } + copy(result[:], idBytes) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseOutputID is a wrapper for simplified unmarshaling of Ids from a byte stream using the marshalUtil package. +func ParseOutputID(marshalUtil *marshalutil.MarshalUtil) (OutputID, error) { + outputID, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return OutputIDFromBytes(data) }) + if err != nil { + return OutputID{}, err + } + + return outputID.(OutputID), nil +} + +// Address returns the address part of an OutputID. +func (outputID OutputID) Address() (address address.Address) { + copy(address[:], outputID[:]) + + return +} + +// TransactionID returns the transaction id part of an OutputID. +func (outputID OutputID) TransactionID() (transactionID ID) { + copy(transactionID[:], outputID[address.Length:]) + + return +} + +// Bytes marshals the OutputID into a sequence of bytes. +func (outputID OutputID) Bytes() []byte { + return outputID[:] +} + +// String creates a human readable version of the OutputID (for debug purposes). +func (outputID OutputID) String() string { + return base58.Encode(outputID[:]) +} + +// OutputIDLength contains the amount of bytes that a marshaled version of the OutputID contains. +const OutputIDLength = address.Length + IDLength diff --git a/dapps/valuetransfers/packages/transaction/outputs.go b/dapps/valuetransfers/packages/transaction/outputs.go new file mode 100644 index 0000000000000000000000000000000000000000..f287b1839b305c7f6057e5a29b7c050c60ed1381 --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/outputs.go @@ -0,0 +1,174 @@ +package transaction + +import ( + "bytes" + "sort" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap" + "github.com/iotaledger/hive.go/marshalutil" +) + +// Outputs represents a list of Outputs that are part of a transaction. +type Outputs struct { + *orderedmap.OrderedMap +} + +// NewOutputs is the constructor of the Outputs struct and creates the list of Outputs from the given details. +func NewOutputs(outputs map[address.Address][]*balance.Balance) (result *Outputs) { + // sorting outputs first before adding to the ordered map to have a deterministic order + toSort := make([]address.Address, 0, len(outputs)) + for a := range outputs { + toSort = append(toSort, a) + } + + sort.Slice(toSort, func(i, j int) bool { + return bytes.Compare(toSort[i][:], toSort[j][:]) < 0 + }) + + result = &Outputs{orderedmap.New()} + for _, addr := range toSort { + result.Add(addr, outputs[addr]) + } + return +} + +// OutputsFromBytes reads the bytes and unmarshals the given information into an *Outputs object. It either creates a +// new object, or uses the optional object provided in the arguments. +func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *Outputs, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Outputs{orderedmap.New()} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to OutputFromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read number of addresses in the outputs + addressCount, err := marshalUtil.ReadUint32() + if err != nil { + return + } + + // iterate the corresponding times and collect addresses + their details + for i := uint32(0); i < addressCount; i++ { + // read address + addr, addressErr := address.Parse(marshalUtil) + if addressErr != nil { + err = addressErr + + return + } + + // read number of balances in the outputs + balanceCount, balanceCountErr := marshalUtil.ReadUint32() + if balanceCountErr != nil { + err = balanceCountErr + + return + } + + // iterate the corresponding times and collect balances + coloredBalances := make([]*balance.Balance, balanceCount) + for j := uint32(0); j < balanceCount; j++ { + coloredBalance, coloredBalanceErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return balance.FromBytes(data) }) + if coloredBalanceErr != nil { + err = coloredBalanceErr + + return + } + + coloredBalances[j] = coloredBalance.(*balance.Balance) + } + + // add the gathered information as an output + result.Add(addr, coloredBalances) + } + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Add adds a new Output to the list of Outputs. +func (outputs *Outputs) Add(address address.Address, balances []*balance.Balance) *Outputs { + outputs.Set(address, balances) + + return outputs +} + +// ForEach iterates through the Outputs and calls them consumer for every found one. The iteration can be aborted by +// returning false in the consumer. +func (outputs *Outputs) ForEach(consumer func(address address.Address, balances []*balance.Balance) bool) bool { + return outputs.OrderedMap.ForEach(func(key, value interface{}) bool { + return consumer(key.(address.Address), value.([]*balance.Balance)) + }) +} + +// Bytes returns a marshaled version of this list of Outputs. +func (outputs *Outputs) Bytes() []byte { + marshalUtil := marshalutil.New() + + if outputs == nil { + marshalUtil.WriteUint32(0) + + return marshalUtil.Bytes() + } + + marshalUtil.WriteUint32(uint32(outputs.Size())) + outputs.ForEach(func(address address.Address, balances []*balance.Balance) bool { + marshalUtil.WriteBytes(address.Bytes()) + marshalUtil.WriteUint32(uint32(len(balances))) + + for _, bal := range balances { + marshalUtil.WriteBytes(bal.Bytes()) + } + + return true + }) + + return marshalUtil.Bytes() +} + +// String returns a human readable version of this list of Outputs (for debug purposes). +func (outputs *Outputs) String() string { + if outputs == nil { + return "<nil>" + } + + result := "[\n" + empty := true + outputs.ForEach(func(address address.Address, balances []*balance.Balance) bool { + empty = false + + result += " " + address.String() + ": [\n" + + balancesEmpty := true + for _, bal := range balances { + balancesEmpty = false + + result += " " + bal.String() + ",\n" + } + + if balancesEmpty { + result += " <empty>\n" + } + + result += " ]\n" + + return true + }) + + if empty { + result += " <empty>\n" + } + + return result + "]" +} diff --git a/dapps/valuetransfers/packages/transaction/outputs_test.go b/dapps/valuetransfers/packages/transaction/outputs_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4c76e4cc44032b9078e95138af2c10dbc15d86c5 --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/outputs_test.go @@ -0,0 +1,45 @@ +package transaction + +import ( + "bytes" + + "github.com/stretchr/testify/assert" + + "testing" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "golang.org/x/crypto/blake2b" +) + +func TestOutputs(t *testing.T) { + rndAddrs := make([]address.Address, 15) + for i := range rndAddrs { + rndAddrs[i] = address.RandomOfType(address.VersionED25519) + } + + theMap1 := make(map[address.Address][]*balance.Balance) + for i := 0; i < len(rndAddrs); i++ { + theMap1[rndAddrs[i]] = []*balance.Balance{balance.New(balance.ColorIOTA, int64(i))} + } + out1 := NewOutputs(theMap1) + + theMap2 := make(map[address.Address][]*balance.Balance) + for i := len(rndAddrs) - 1; i >= 0; i-- { + theMap2[rndAddrs[i]] = []*balance.Balance{balance.New(balance.ColorIOTA, int64(i))} + } + out2 := NewOutputs(theMap2) + + h1 := hashOutputs(t, out1) + h2 := hashOutputs(t, out2) + + assert.Equal(t, bytes.Equal(h1, h2), true) +} + +func hashOutputs(t *testing.T, out *Outputs) []byte { + h, err := blake2b.New256(nil) + assert.NoError(t, err) + + h.Write(out.Bytes()) + return h.Sum(nil) +} diff --git a/dapps/valuetransfers/packages/transaction/signatures.go b/dapps/valuetransfers/packages/transaction/signatures.go new file mode 100644 index 0000000000000000000000000000000000000000..2a5879c03e454d7b577025c8beae6b09ee1be959 --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/signatures.go @@ -0,0 +1,173 @@ +package transaction + +import ( + "github.com/iotaledger/hive.go/marshalutil" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap" +) + +// Signatures represents a container for the address signatures of a value transfer. +// It internally manages the list of signatures as an ordered map, so that the serialization order is deterministic and +// produces the same sequence of bytes during marshaling and unmarshaling. +type Signatures struct { + orderedMap *orderedmap.OrderedMap +} + +// NewSignatures creates an empty container for the address signatures of a value transfer. +func NewSignatures() *Signatures { + return &Signatures{ + orderedMap: orderedmap.New(), + } +} + +// SignaturesFromBytes unmarshals a container with signatures from a sequence of bytes. +// It either creates a new container or fills the optionally provided container with the parsed information. +func SignaturesFromBytes(bytes []byte, optionalTargetObject ...*Signatures) (result *Signatures, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Signatures{orderedMap: orderedmap.New()} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to FromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read version + versionByte, err := marshalUtil.ReadByte() + if err != nil { + return + } + + // 0 byte encodes the end of the signatures + var typeCastedSignature signaturescheme.Signature + for versionByte != 0 { + typeCastedSignature = nil + // perform signature scheme specific decoding + switch versionByte { + case address.VersionED25519: + marshalUtil.ReadSeek(-1) + signature, signatureErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return signaturescheme.Ed25519SignatureFromBytes(data) }) + if signatureErr != nil { + err = signatureErr + + return + } + typeCastedSignature = signature.(signaturescheme.Signature) + + case address.VersionBLS: + marshalUtil.ReadSeek(-1) + signature, signatureErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return signaturescheme.BLSSignatureFromBytes(data) }) + if signatureErr != nil { + err = signatureErr + + return + } + typeCastedSignature = signature.(signaturescheme.Signature) + default: + // unknown signature type... + } + if typeCastedSignature != nil { + result.orderedMap.Set(typeCastedSignature.Address(), typeCastedSignature) + } + + // read version of next signature + if versionByte, err = marshalUtil.ReadByte(); err != nil { + return + } + } + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Add adds a new Signature to this container. +func (signatures *Signatures) Add(address address.Address, signature signaturescheme.Signature) { + signatures.orderedMap.Set(address, signature) +} + +// Get returns the Signature, that belongs to an Address. +func (signatures *Signatures) Get(address address.Address) (signaturescheme.Signature, bool) { + signature, exists := signatures.orderedMap.Get(address) + if !exists { + return nil, false + } + + return signature.(signaturescheme.Signature), exists +} + +// Size returns the amount of signatures in this container. +func (signatures *Signatures) Size() int { + return signatures.orderedMap.Size() +} + +// ForEach iterates through all signatures, calling the consumer for every found entry. +// The iteration can be aborted by the consumer returning false +func (signatures *Signatures) ForEach(consumer func(address address.Address, signature signaturescheme.Signature) bool) { + signatures.orderedMap.ForEach(func(key, value interface{}) bool { + return consumer(key.(address.Address), value.(signaturescheme.Signature)) + }) +} + +// Bytes marshals the signatures into a sequence of bytes. +func (signatures *Signatures) Bytes() []byte { + // initialize helper + marshalUtil := marshalutil.New() + + // iterate through signatures and dump them + signatures.ForEach(func(address address.Address, signature signaturescheme.Signature) bool { + marshalUtil.WriteBytes(signature.Bytes()) + + return true + }) + + // trailing 0 to indicate the end of signatures + marshalUtil.WriteByte(0) + + // return result + return marshalUtil.Bytes() +} + +func (signatures *Signatures) String() string { + if signatures == nil { + return "<nil>" + } + + result := "[\n" + empty := true + signatures.ForEach(func(address address.Address, signature signaturescheme.Signature) bool { + empty = false + + result += " " + address.String() + ": [\n" + + /* + balancesEmpty := true + for _, balance := range balances { + balancesEmpty = false + + result += " " + balance.String() + ",\n" + } + + if balancesEmpty { + result += " <empty>\n" + } + */ + + result += " ]\n" + + return true + }) + + if empty { + result += " <empty>\n" + } + + return result + "]" +} diff --git a/dapps/valuetransfers/packages/transaction/signatures_test.go b/dapps/valuetransfers/packages/transaction/signatures_test.go new file mode 100644 index 0000000000000000000000000000000000000000..61d03a26e949792c3de6cf5bb866c1af4207d4e8 --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/signatures_test.go @@ -0,0 +1,51 @@ +package transaction + +import ( + "testing" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" +) + +func TestSignatures(t *testing.T) { + dataToSign := []byte("test") + + address1SigScheme := signaturescheme.ED25519(ed25519.GenerateKeyPair()) + address2SigScheme := signaturescheme.ED25519(ed25519.GenerateKeyPair()) + address3SigScheme := signaturescheme.RandBLS() + + signatures := NewSignatures() + signatures.Add(address1SigScheme.Address(), address1SigScheme.Sign(dataToSign)) + signatures.Add(address2SigScheme.Address(), address2SigScheme.Sign(dataToSign)) + signatures.Add(address3SigScheme.Address(), address3SigScheme.Sign(dataToSign)) + + assert.Equal(t, 3, signatures.Size()) + + signatures.Add(address1SigScheme.Address(), address1SigScheme.Sign(dataToSign)) + + assert.Equal(t, 3, signatures.Size()) + + signatures.ForEach(func(address address.Address, signature signaturescheme.Signature) bool { + assert.Equal(t, true, signature.IsValid(dataToSign)) + + return true + }) + + clonedSignatures, _, err := SignaturesFromBytes(signatures.Bytes()) + if err != nil { + t.Error(err) + + return + } + + assert.Equal(t, 3, clonedSignatures.Size()) + + clonedSignatures.ForEach(func(address address.Address, signature signaturescheme.Signature) bool { + assert.Equal(t, true, signature.IsValid(dataToSign)) + + return true + }) +} diff --git a/dapps/valuetransfers/packages/transaction/transaction.go b/dapps/valuetransfers/packages/transaction/transaction.go new file mode 100644 index 0000000000000000000000000000000000000000..760ded1db4a41edd801eb03722a6f0aea8d105fa --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/transaction.go @@ -0,0 +1,463 @@ +package transaction + +import ( + "errors" + "fmt" + "sync" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" + "github.com/mr-tron/base58" + "golang.org/x/crypto/blake2b" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" +) + +var ( + // ErrMaxDataPayloadSizeExceeded is returned if the data payload size is exceeded. + ErrMaxDataPayloadSizeExceeded = errors.New("maximum data payload size exceeded") +) + +// region IMPLEMENT Transaction //////////////////////////////////////////////////////////////////////////////////////////// + +// Transaction represents a value transfer for IOTA. It consists out of a number of inputs, a number of outputs and their +// corresponding signature. Additionally, there is an optional data field, that can be used to include payment details or +// processing information. +type Transaction struct { + objectstorage.StorableObjectFlags + + inputs *Inputs + outputs *Outputs + signatures *Signatures + + id *ID + idMutex sync.RWMutex + + essenceBytes []byte + essenceBytesMutex sync.RWMutex + + signatureBytes []byte + signatureBytesMutex sync.RWMutex + + dataPayload []byte + dataPayloadMutex sync.RWMutex + + bytes []byte + bytesMutex sync.RWMutex +} + +// New creates a new Transaction from the given details. The signatures are omitted as signing requires us to marshal +// the transaction into a sequence of bytes and these bytes are unknown at the time of the creation of the Transaction. +func New(inputs *Inputs, outputs *Outputs) *Transaction { + return &Transaction{ + inputs: inputs, + outputs: outputs, + signatures: NewSignatures(), + } +} + +// FromBytes unmarshals a Transaction from a sequence of bytes. +func FromBytes(bytes []byte, optionalTargetObject ...*Transaction) (result *Transaction, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = Parse(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// FromStorageKey is a factory method that creates a new Transaction instance from a storage key of the objectstorage. +// It is used by the objectstorage, to create new instances of this entity. +func FromStorageKey(key []byte, optionalTargetObject ...*Transaction) (result objectstorage.StorableObject, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Transaction{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to FromStorageKey") + } + + marshalUtil := marshalutil.New(key) + id, err := ParseID(marshalUtil) + if err != nil { + return + } + result.(*Transaction).id = &id + + return +} + +// Parse unmarshals a Transaction using the given marshalUtil (for easier marshaling/unmarshaling). +func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Transaction) (result *Transaction, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Transaction{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to Parse") + } + + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ID returns the identifier of this Transaction. +func (transaction *Transaction) ID() ID { + // acquire lock for reading id + transaction.idMutex.RLock() + + // return if id has been calculated already + if transaction.id != nil { + defer transaction.idMutex.RUnlock() + + return *transaction.id + } + + // switch to write lock + transaction.idMutex.RUnlock() + transaction.idMutex.Lock() + defer transaction.idMutex.Unlock() + + // return if id has been calculated in the mean time + if transaction.id != nil { + return *transaction.id + } + + // otherwise calculate the id + idBytes := blake2b.Sum256(transaction.Bytes()) + id, _, err := IDFromBytes(idBytes[:]) + if err != nil { + panic(err) + } + + // cache result for later calls + transaction.id = &id + + return id +} + +// Inputs returns the list of Inputs that were consumed by this Transaction. +func (transaction *Transaction) Inputs() *Inputs { + return transaction.inputs +} + +// Outputs returns the list of Outputs where this Transaction moves its consumed funds. +func (transaction *Transaction) Outputs() *Outputs { + return transaction.outputs +} + +// SignaturesValid returns true if the Signatures in this transaction +func (transaction *Transaction) SignaturesValid() bool { + signaturesValid := true + transaction.inputs.ForEachAddress(func(address address.Address) bool { + if signature, exists := transaction.signatures.Get(address); !exists || !signature.IsValid(transaction.EssenceBytes()) { + signaturesValid = false + + return false + } + + return true + }) + + return signaturesValid +} + +// EssenceBytes return the bytes of the transaction excluding the Signatures. These bytes are later signed and used to +// generate the Signatures. +func (transaction *Transaction) EssenceBytes() []byte { + // acquire read lock on essenceBytes + transaction.essenceBytesMutex.RLock() + + // return essenceBytes if the object has been marshaled already + if transaction.essenceBytes != nil { + defer transaction.essenceBytesMutex.RUnlock() + + return transaction.essenceBytes + } + + // switch to write lock + transaction.essenceBytesMutex.RUnlock() + transaction.essenceBytesMutex.Lock() + defer transaction.essenceBytesMutex.Unlock() + + // return essenceBytes if the object has been marshaled in the mean time + if essenceBytes := transaction.essenceBytes; essenceBytes != nil { + return essenceBytes + } + + // create marshal helper + marshalUtil := marshalutil.New() + + // marshal inputs + marshalUtil.WriteBytes(transaction.inputs.Bytes()) + + // marshal outputs + marshalUtil.WriteBytes(transaction.outputs.Bytes()) + + // marshal dataPayload size + marshalUtil.WriteUint32(transaction.DataPayloadSize()) + + // marshal dataPayload data + marshalUtil.WriteBytes(transaction.dataPayload) + + // store marshaled result + transaction.essenceBytes = marshalUtil.Bytes() + transaction.SetModified() + + return transaction.essenceBytes +} + +// SignatureBytes returns the bytes of all of the signatures in the Transaction. +func (transaction *Transaction) SignatureBytes() []byte { + transaction.signatureBytesMutex.RLock() + if transaction.signatureBytes != nil { + defer transaction.signatureBytesMutex.RUnlock() + + return transaction.signatureBytes + } + + transaction.signatureBytesMutex.RUnlock() + transaction.signatureBytesMutex.Lock() + defer transaction.signatureBytesMutex.Unlock() + + if transaction.signatureBytes != nil { + return transaction.signatureBytes + } + + // generate signatures + transaction.signatureBytes = transaction.signatures.Bytes() + + return transaction.signatureBytes +} + +// Bytes returns a marshaled version of this Transaction (essence + signatures). +func (transaction *Transaction) Bytes() []byte { + // acquire read lock on bytes + transaction.bytesMutex.RLock() + + // return bytes if the object has been marshaled already + if transaction.bytes != nil { + defer transaction.bytesMutex.RUnlock() + + return transaction.bytes + } + + // switch to write lock + transaction.bytesMutex.RUnlock() + transaction.bytesMutex.Lock() + defer transaction.bytesMutex.Unlock() + + // return bytes if the object has been marshaled in the mean time + if bytes := transaction.bytes; bytes != nil { + return bytes + } + + // create marshal helper + marshalUtil := marshalutil.New() + + // marshal essence bytes + marshalUtil.WriteBytes(transaction.EssenceBytes()) + + // marshal signature bytes + marshalUtil.WriteBytes(transaction.SignatureBytes()) + + // store marshaled result + transaction.bytes = marshalUtil.Bytes() + + return transaction.bytes +} + +// Sign adds a new signature to the Transaction. +func (transaction *Transaction) Sign(signature signaturescheme.SignatureScheme) *Transaction { + transaction.signatures.Add(signature.Address(), signature.Sign(transaction.EssenceBytes())) + transaction.SetModified() + return transaction +} + +// PutSignature validates and adds signature to the transaction +func (transaction *Transaction) PutSignature(signature signaturescheme.Signature) error { + if !signature.IsValid(transaction.EssenceBytes()) { + return errors.New("PutSignature: invalid signature") + } + transaction.signatures.Add(signature.Address(), signature) + transaction.SetModified() + return nil +} + +// String returns a human readable version of this Transaction (for debug purposes). +func (transaction *Transaction) String() string { + id := transaction.ID() + + return stringify.Struct("Transaction"+fmt.Sprintf("(%p)", transaction), + stringify.StructField("id", base58.Encode(id[:])), + stringify.StructField("inputs", transaction.inputs), + stringify.StructField("outputs", transaction.outputs), + stringify.StructField("signatures", transaction.signatures), + stringify.StructField("dataPayloadSize", uint64(transaction.DataPayloadSize())), + ) +} + +// MaxDataPayloadSize defines the maximum size (in bytes) of the data payload. +const MaxDataPayloadSize = 64 * 1024 + +// SetDataPayload sets yhe dataPayload and its type +func (transaction *Transaction) SetDataPayload(data []byte) error { + transaction.dataPayloadMutex.Lock() + defer transaction.dataPayloadMutex.Unlock() + + if len(data) > MaxDataPayloadSize { + return fmt.Errorf("%w: %d", ErrMaxDataPayloadSizeExceeded, MaxDataPayloadSize) + } + transaction.dataPayload = data + return nil +} + +// GetDataPayload gets the dataPayload and its type +func (transaction *Transaction) GetDataPayload() []byte { + transaction.dataPayloadMutex.RLock() + defer transaction.dataPayloadMutex.RUnlock() + + return transaction.dataPayload +} + +// DataPayloadSize returns the size of the dataPayload as uint32. +// nil payload as size 0 +func (transaction *Transaction) DataPayloadSize() uint32 { + transaction.dataPayloadMutex.RLock() + defer transaction.dataPayloadMutex.RUnlock() + + return uint32(len(transaction.dataPayload)) +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// region IMPLEMENT StorableObject interface /////////////////////////////////////////////////////////////////////////// + +// define contract (ensure that the struct fulfills the given interface) +var _ objectstorage.StorableObject = &Transaction{} + +// ObjectStorageKey returns the bytes that are used as a key when storing the Transaction in an objectstorage. +func (transaction *Transaction) ObjectStorageKey() []byte { + return transaction.ID().Bytes() +} + +// Update is disabled but needs to be implemented to be compatible with the objectstorage. +func (transaction *Transaction) Update(other objectstorage.StorableObject) { + panic("update forbidden") +} + +// ObjectStorageValue returns a bytes representation of the Transaction by implementing the encoding.BinaryMarshaler interface. +func (transaction *Transaction) ObjectStorageValue() []byte { + return transaction.Bytes() +} + +// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. +func (transaction *Transaction) UnmarshalObjectStorageValue(bytes []byte) (consumedBytes int, err error) { + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // unmarshal inputs + parsedInputs, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return InputsFromBytes(data) }) + if err != nil { + return + } + transaction.inputs = parsedInputs.(*Inputs) + + // unmarshal outputs + parsedOutputs, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return OutputsFromBytes(data) }) + if err != nil { + return + } + transaction.outputs = parsedOutputs.(*Outputs) + + // unmarshal data payload size + var dataPayloadSize uint32 + dataPayloadSize, err = marshalUtil.ReadUint32() + if err != nil { + return + } + if dataPayloadSize > MaxDataPayloadSize { + err = fmt.Errorf("%w: %d", ErrMaxDataPayloadSizeExceeded, MaxDataPayloadSize) + return + } + + // unmarshal data payload + transaction.dataPayload, err = marshalUtil.ReadBytes(int(dataPayloadSize)) + if err != nil { + return + } + + // store essence bytes + essenceBytesCount := marshalUtil.ReadOffset() + transaction.essenceBytes = make([]byte, essenceBytesCount) + copy(transaction.essenceBytes, bytes[:essenceBytesCount]) + + // unmarshal outputs + parsedSignatures, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return SignaturesFromBytes(data) }) + if err != nil { + return + } + transaction.signatures = parsedSignatures.(*Signatures) + + // store signature bytes + signatureBytesCount := marshalUtil.ReadOffset() - essenceBytesCount + transaction.signatureBytes = make([]byte, signatureBytesCount) + copy(transaction.signatureBytes, bytes[essenceBytesCount:essenceBytesCount+signatureBytesCount]) + + // return the number of bytes we processed + consumedBytes = essenceBytesCount + signatureBytesCount + + // store bytes, so we don't have to marshal manually + transaction.bytes = bytes[:consumedBytes] + + return +} + +// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// CachedTransaction is a wrapper for the object storage, that takes care of type casting the Transaction objects. +// Since go does not have generics (yet), the object storage works based on the generic "interface{}" type, which means +// that we have to regularly type cast the returned objects, to match the expected type. To reduce the burden of +// manually managing these type, we create a wrapper that does this for us. This way, we can consistently handle the +// specialized types of Transaction, without having to manually type cast over and over again. +type CachedTransaction struct { + objectstorage.CachedObject +} + +// Retain overrides the underlying method to return a new CachedTransaction instead of a generic CachedObject. +func (cachedTransaction *CachedTransaction) Retain() *CachedTransaction { + return &CachedTransaction{cachedTransaction.CachedObject.Retain()} +} + +// Consume overrides the underlying method to use a CachedTransaction object instead of a generic CachedObject in the +// consumer). +func (cachedTransaction *CachedTransaction) Consume(consumer func(tx *Transaction)) bool { + return cachedTransaction.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Transaction)) + }) +} + +// Unwrap provides a way to retrieve a type casted version of the underlying object. +func (cachedTransaction *CachedTransaction) Unwrap() *Transaction { + untypedTransaction := cachedTransaction.Get() + if untypedTransaction == nil { + return nil + } + + typeCastedTransaction := untypedTransaction.(*Transaction) + if typeCastedTransaction == nil || typeCastedTransaction.IsDeleted() { + return nil + } + + return typeCastedTransaction +} diff --git a/dapps/valuetransfers/packages/transaction/transaction_test.go b/dapps/valuetransfers/packages/transaction/transaction_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d260017163dc87b8fda6f6cfd58e74dd2e304a73 --- /dev/null +++ b/dapps/valuetransfers/packages/transaction/transaction_test.go @@ -0,0 +1,206 @@ +package transaction + +import ( + "bytes" + "strings" + "testing" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" +) + +func TestEmptyDataPayload(t *testing.T) { + sigScheme := signaturescheme.ED25519(ed25519.GenerateKeyPair()) + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + tx.Sign(sigScheme) + check := tx.SignaturesValid() + + assert.Equal(t, true, check) +} + +func TestEmptyDataPayloadString(t *testing.T) { + sigScheme := signaturescheme.ED25519(ed25519.GenerateKeyPair()) + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + tx.Sign(sigScheme) + check := tx.SignaturesValid() + + assert.True(t, check) + + t.Logf("%s", tx.String()) +} + +func TestShortDataPayload(t *testing.T) { + sigScheme := signaturescheme.ED25519(ed25519.GenerateKeyPair()) + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + dataPayload := []byte("data payload test") + err := tx.SetDataPayload(dataPayload) + assert.NoError(t, err) + + dpBack := tx.GetDataPayload() + assert.Equal(t, true, bytes.Equal(dpBack, dataPayload)) + + tx.Sign(sigScheme) + check := tx.SignaturesValid() + assert.Equal(t, true, check) + + // corrupt data payload bytes + // reset essence to force recalculation + tx.essenceBytes = nil + dataPayload[2] = '?' + err = tx.SetDataPayload(dataPayload) + assert.NoError(t, err) + + // expect signature is not valid + check = tx.SignaturesValid() + assert.Equal(t, false, check) +} + +func TestTooLongDataPayload(t *testing.T) { + sigScheme := signaturescheme.ED25519(ed25519.GenerateKeyPair()) + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + dataPayload := []byte(strings.Repeat("1", MaxDataPayloadSize+1)) + err := tx.SetDataPayload(dataPayload) + assert.Error(t, err) +} + +func TestMarshalingEmptyDataPayload(t *testing.T) { + sigScheme := signaturescheme.RandBLS() + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + tx.Sign(sigScheme) + check := tx.SignaturesValid() + assert.Equal(t, true, check) + + v := tx.ObjectStorageValue() + + tx1 := Transaction{} + _, err := tx1.UnmarshalObjectStorageValue(v) + assert.NoError(t, err) + + assert.Equal(t, true, tx1.SignaturesValid()) + assert.Equal(t, true, bytes.Equal(tx1.ID().Bytes(), tx.ID().Bytes())) +} + +func TestMarshalingDataPayload(t *testing.T) { + sigScheme := signaturescheme.RandBLS() + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + dataPayload := []byte("data payload test") + err := tx.SetDataPayload(dataPayload) + assert.NoError(t, err) + + tx.Sign(sigScheme) + check := tx.SignaturesValid() + assert.Equal(t, true, check) + + v := tx.ObjectStorageValue() + + tx1 := Transaction{} + _, err = tx1.UnmarshalObjectStorageValue(v) + + assert.NoError(t, err) + assert.Equal(t, true, tx1.SignaturesValid()) + + assert.Equal(t, true, bytes.Equal(tx1.ID().Bytes(), tx.ID().Bytes())) +} + +func TestPutSignatureValid(t *testing.T) { + sigScheme := signaturescheme.RandBLS() + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + dataPayload := []byte("data payload test") + err := tx.SetDataPayload(dataPayload) + assert.NoError(t, err) + + signature := sigScheme.Sign(tx.EssenceBytes()) + assert.Equal(t, signature.IsValid(tx.EssenceBytes()), true) + + err = tx.PutSignature(signature) + assert.NoError(t, err) + + check := tx.SignaturesValid() + assert.Equal(t, true, check) +} + +func TestPutSignatureInvalid(t *testing.T) { + sigScheme := signaturescheme.RandBLS() + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + dataPayload := []byte("data payload test") + err := tx.SetDataPayload(dataPayload) + assert.NoError(t, err) + + signatureValid := sigScheme.Sign(tx.EssenceBytes()) + assert.Equal(t, true, signatureValid.IsValid(tx.EssenceBytes())) + + sigBytes := make([]byte, len(signatureValid.Bytes())) + copy(sigBytes, signatureValid.Bytes()) + // inverse last byte --> corrupt the signatureValid + sigBytes[len(sigBytes)-1] = ^sigBytes[len(sigBytes)-1] + + sigCorrupted, consumed, err := signaturescheme.BLSSignatureFromBytes(sigBytes) + + assert.NoError(t, err) + assert.Equal(t, consumed, len(sigBytes)) + assert.Equal(t, false, sigCorrupted.IsValid(tx.EssenceBytes())) + + err = tx.PutSignature(sigCorrupted) + // error expected + assert.Error(t, err) + + // 0 signatures is not valid + assert.Equal(t, true, !tx.SignaturesValid()) + + err = tx.PutSignature(signatureValid) + // no error expected + assert.NoError(t, err) + + // valid signatures expected + assert.Equal(t, true, tx.SignaturesValid()) +} diff --git a/dapps/valuetransfers/packages/wallet/seed.go b/dapps/valuetransfers/packages/wallet/seed.go new file mode 100644 index 0000000000000000000000000000000000000000..9e94c3d79eb7a4ed7dffc10c0541767aeececf15 --- /dev/null +++ b/dapps/valuetransfers/packages/wallet/seed.go @@ -0,0 +1,26 @@ +package wallet + +import ( + "github.com/iotaledger/hive.go/crypto/ed25519" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" +) + +// Seed represents a seed for IOTA wallets. A seed allows us to generate a deterministic sequence of Addresses and their +// corresponding KeyPairs. +type Seed struct { + *ed25519.Seed +} + +// NewSeed is the factory method for an IOTA seed. It either generates a new one or imports an existing marshaled seed. +// before. +func NewSeed(optionalSeedBytes ...[]byte) *Seed { + return &Seed{ + ed25519.NewSeed(optionalSeedBytes...), + } +} + +// Address returns an ed25519 address which can be used for receiving or sending funds. +func (seed *Seed) Address(index uint64) address.Address { + return address.FromED25519PubKey(seed.Seed.KeyPair(index).PublicKey) +} diff --git a/dapps/valuetransfers/packages/wallet/wallet.go b/dapps/valuetransfers/packages/wallet/wallet.go new file mode 100644 index 0000000000000000000000000000000000000000..88ab072fa649fa6840db5fc2df8c525dc59fa9a3 --- /dev/null +++ b/dapps/valuetransfers/packages/wallet/wallet.go @@ -0,0 +1,20 @@ +package wallet + +// Wallet represents a simple cryptocurrency wallet for the IOTA tangle. It contains the logic to manage the movement of +// funds. +type Wallet struct { + seed *Seed +} + +// New is the factory method of the wallet. It either creates a new wallet or restores the wallet backup that is handed +// in as an optional parameter. +func New(optionalRecoveryBytes ...[]byte) *Wallet { + return &Wallet{ + seed: NewSeed(optionalRecoveryBytes...), + } +} + +// Seed returns the seed of this wallet that is used to generate all of the wallets addresses and private keys. +func (wallet *Wallet) Seed() *Seed { + return wallet.seed +} diff --git a/docker-compose.yml b/docker-compose.yml index 42affc44a75af0bfe92eef90cdba5415b34e9496..c1e5289ad27008d3edd3642169487e68250ff6bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,21 +10,51 @@ services: dockerfile: Dockerfile container_name: iota_goshimmer restart: unless-stopped + command: > + --node.enablePlugins=prometheus # Mount volumes: # make sure to give read/write access to the folder ./mainnetdb (e.g., chmod -R 777 ./mainnetdb) # optionally, you can mount a config.json into the container volumes: - - ./mainnetdb/:/mainnetdb/:rw - #- ./config.json:/config.json:ro + - ./mainnetdb/:/tmp/mainnetdb/:rw + - ./config.json:/config.json:ro # Expose ports: # gossip: - "14666:14666/tcp" # autopeering: - "14626:14626/udp" # webAPI: - "8080:8080/tcp" # dashboard: - "8081:8081/tcp" - # graph: - "8082:8082/tcp" ports: - "14666:14666/tcp" - "14626:14626/udp" - #- "8080:8080/tcp" - #- "8081:8081/tcp" - #- "8082:8082/tcp" + - "9311:9311/tcp" # prometheus exporter + - "8080:8080/tcp" # webApi + - "8081:8081/tcp" # dashboard + + prometheus: + network_mode: host + image: prom/prometheus:latest + container_name: prometheus + restart: unless-stopped + ports: + - 9090:9090 + command: + - --config.file=/etc/prometheus/prometheus.yml + volumes: + - ./tools/monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro + depends_on: + - goshimmer + + grafana: + network_mode: host + image: grafana/grafana:latest + container_name: grafana + restart: unless-stopped + environment: + # path to provisioning definitions can only be defined as + # environment variables for grafana within docker + - GF_PATHS_PROVISIONING=/var/lib/grafana/provisioning + ports: + - 3000:3000 + user: "472" + volumes: + - ./tools/monitoring/grafana:/var/lib/grafana:rw \ No newline at end of file diff --git a/go.mod b/go.mod index 64b1abc333eb6822359c5bc61def51cc4eb1846a..d2cccad7ef466f54e3fa85135425b4fd05fc2c79 100644 --- a/go.mod +++ b/go.mod @@ -1,43 +1,39 @@ module github.com/iotaledger/goshimmer -go 1.13 +go 1.14 require ( - github.com/dgraph-io/badger/v2 v2.0.1 + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/dgraph-io/badger/v2 v2.0.3 github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/dgryski/go-farm v0.0.0-20191112170834-c2139c5d712b // indirect + github.com/drand/drand v0.8.1 + github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99 + github.com/gin-gonic/gin v1.6.3 + github.com/go-ole/go-ole v1.2.4 // indirect github.com/gobuffalo/packr/v2 v2.8.0 - github.com/golang/protobuf v1.3.2 - github.com/googollee/go-engine.io v1.4.3-0.20190924125625-798118fc0dd2 - github.com/googollee/go-socket.io v1.4.3-0.20191204093753-683f8725b6d0 - github.com/gorilla/websocket v1.4.1 - github.com/iotaledger/hive.go v0.0.0-20200219224037-2d5f5238c0de - github.com/iotaledger/iota.go v1.0.0-beta.14 - github.com/kr/pretty v0.2.0 // indirect - github.com/kr/text v0.2.0 // indirect + github.com/golang/protobuf v1.4.2 + github.com/gorilla/websocket v1.4.2 + github.com/iotaledger/hive.go v0.0.0-20200625105326-310ea88f1337 github.com/labstack/echo v3.3.10+incompatible - github.com/labstack/gommon v0.3.0 // indirect + github.com/labstack/gommon v0.3.0 github.com/magiconair/properties v1.8.1 - github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.11 // indirect - github.com/mr-tron/base58 v1.1.3 - github.com/oasislabs/ed25519 v0.0.0-20200206134218-2893bee822a3 - github.com/panjf2000/ants/v2 v2.2.2 - github.com/pelletier/go-toml v1.6.0 // indirect - github.com/pkg/errors v0.9.1 - github.com/sergi/go-diff v1.1.0 // indirect - github.com/spf13/afero v1.2.2 // indirect - github.com/spf13/cast v1.3.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/mr-tron/base58 v1.2.0 + github.com/panjf2000/ants/v2 v2.4.1 + github.com/pkg/errors v0.8.1 + github.com/prometheus/client_golang v1.7.0 + github.com/shirou/gopsutil v2.20.5+incompatible github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.6.1 - github.com/stretchr/testify v1.5.1 + github.com/spf13/viper v1.7.0 + github.com/stretchr/testify v1.6.1 github.com/valyala/fasttemplate v1.1.0 // indirect - go.uber.org/atomic v1.5.1 - go.uber.org/zap v1.13.0 - golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c - golang.org/x/net v0.0.0-20200226121028-0de0cce0169b - gopkg.in/ini.v1 v1.51.1 // indirect + go.dedis.ch/kyber/v3 v3.0.12 + go.mongodb.org/mongo-driver v1.3.4 + go.uber.org/atomic v1.6.0 + go.uber.org/zap v1.15.0 + golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 + golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect + golang.org/x/tools v0.0.0-20200330040139-fa3cc9eebcfe // indirect + google.golang.org/grpc v1.30.0 + google.golang.org/grpc/examples v0.0.0-20200617041141-9a465503579e // indirect gopkg.in/src-d/go-git.v4 v4.13.1 - gopkg.in/yaml.v2 v2.2.7 // indirect ) diff --git a/go.sum b/go.sum index 5540a9b7466b686876d5687b7daa424c5c2d6a5b..4ad17fa5119419a6284af20f0750ce3a35bcf541 100644 --- a/go.sum +++ b/go.sum @@ -1,168 +1,275 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/blake2b v1.0.0 h1:KK9LimVmE0MjRl9095XJmKqZ+iLxWATvlcpVFRtaw6s= +github.com/dchest/blake2b v1.0.0/go.mod h1:U034kXgbJpCle2wSk5ybGIVhOSHCVLMDqOzcPEA0F7s= github.com/dgraph-io/badger v1.5.4 h1:gVTrpUTbbr/T24uvoCaqY2KSHfNLVGm0w+hbee2HMeg= github.com/dgraph-io/badger v1.5.4/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger/v2 v2.0.1 h1:+D6dhIqC6jIeCclnxMHqk4HPuXgrRN5UfBsLR4dNQ3A= -github.com/dgraph-io/badger/v2 v2.0.1/go.mod h1:YoRSIp1LmAJ7zH7tZwRvjNMUYLxB4wl3ebYkaIruZ04= -github.com/dgraph-io/ristretto v0.0.0-20191025175511-c1f00be0418e h1:aeUNgwup7PnDOBAD1BOKAqzb/W/NksOj6r3dwKKuqfg= -github.com/dgraph-io/ristretto v0.0.0-20191025175511-c1f00be0418e/go.mod h1:edzKIzGvqUCMzhTVWbiTSe75zD9Xxq0GtSBtFmaUTZs= +github.com/dgraph-io/badger/v2 v2.0.3 h1:inzdf6VF/NZ+tJ8RwwYMjJMvsOALTHYdozn0qSl6XJI= +github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM= +github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3 h1:MQLRM35Pp0yAyBYksjbj1nZI/w6eyRY/mWoM1sFf4kU= +github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190323231341-8198c7b169ec/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20191112170834-c2139c5d712b h1:SeiGBzKrEtuDddnBABHkp4kq9sBGE9nuYmk6FPTg0zg= -github.com/dgryski/go-farm v0.0.0-20191112170834-c2139c5d712b/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE= +github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= +github.com/drand/drand v0.8.1 h1:wAGnZKa+HbyNvRQOwLGIVnJR14o9kS/0+w9VroJ1AO0= +github.com/drand/drand v0.8.1/go.mod h1:ZdzIrSqqEYZvMiS1UuZlJs3WTb9uLz1I9uH0icYPqoE= +github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= +github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99 h1:BxLbcT0yq9ii6ShXn7U+0oXB2ABfEfw6GutaVPxoj2Y= +github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99/go.mod h1:Rzu9PGFt3q8d7WWdrHmR8dktHucO0dSTWlMYrgqjSpA= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc= github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM= github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/packr/v2 v2.8.0 h1:IULGd15bQL59ijXLxEvA5wlMxsmx/ZkQv9T282zNVIY= github.com/gobuffalo/packr/v2 v2.8.0/go.mod h1:PDk2k3vGevNE3SwVyVRgQCCXETC9SaONCNSXT1Q8M1g= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51 h1:OdVal38kmXn0U3M3CYmPF4cpMLLvD4ioshwrooNfmxs= -github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51/go.mod h1:eJfRN6aj+kR/rnua/rw9jAgYhqoMHldQkdTi+sePRKk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/googollee/go-engine.io v1.4.1 h1:m3WlZAug1SODuWT++UX2nbzk9IUCn9T1SnmHoqppdqo= -github.com/googollee/go-engine.io v1.4.1/go.mod h1:26oFqHsnuWIzNOM0T08x21eQOydBosKOCgK3tyhzPPI= -github.com/googollee/go-engine.io v1.4.3-0.20190924125625-798118fc0dd2 h1:6LbNP1ft0muA4LgoPMvwbxFpVhsRAGimY0Rp+4L7Q1M= -github.com/googollee/go-engine.io v1.4.3-0.20190924125625-798118fc0dd2/go.mod h1:iaugrHMOoal16IKAWvH6y6RrXXIzfOULxjNwvXBCV4o= -github.com/googollee/go-socket.io v1.4.3-0.20191204093753-683f8725b6d0 h1:7yrvhLv25w1vtVKrcg8CZAn4Pnkb6pzCAqnZ5y9O4q8= -github.com/googollee/go-socket.io v1.4.3-0.20191204093753-683f8725b6d0/go.mod h1:yjlQxKcAZXZjpGwQVW/y1sgyL1ou+DdCpkswURDCRrU= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY= +github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/iotaledger/hive.go v0.0.0-20200219224037-2d5f5238c0de h1:J9G9YWM5q7r3DObMIx/Qc8CUjrpD+c90EPVKjsBrR+E= -github.com/iotaledger/hive.go v0.0.0-20200219224037-2d5f5238c0de/go.mod h1:wj3bFHlcX0NiEOWu5+WOg/MI/5N7PKCFnyaziaylB64= -github.com/iotaledger/iota.go v1.0.0-beta.9/go.mod h1:F6WBmYd98mVjAmmPVYhnxg8NNIWCjjH8VWT9qvv3Rc8= -github.com/iotaledger/iota.go v1.0.0-beta.14 h1:Oeb28MfBuJEeXcGrLhTCJFtbsnc8y1u7xidsAmiOD5A= -github.com/iotaledger/iota.go v1.0.0-beta.14/go.mod h1:F6WBmYd98mVjAmmPVYhnxg8NNIWCjjH8VWT9qvv3Rc8= +github.com/iotaledger/hive.go v0.0.0-20200625105326-310ea88f1337 h1:F6PzAkymPcKr1vJVK3/80wiVovjkL47c9FMjUOesXGA= +github.com/iotaledger/hive.go v0.0.0-20200625105326-310ea88f1337/go.mod h1:42UvBc41QBsuM7z1P1fABMonTJb7kGqkzshRebClQvA= +github.com/iotaledger/iota.go v1.0.0-beta.15 h1:HI8PqerEnO1CCIqmXHJ6zh1IaSFXU+S0qlUAEKshho8= +github.com/iotaledger/iota.go v1.0.0-beta.15/go.mod h1:Rn6v5hLAn8YBaJlRu1ZQdPAgKlshJR1PTeLQaft2778= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1 h1:qBCV/RLV02TSfQa7tFmxTihnG+u+7JXByOkhlkR5rmQ= +github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3 h1:Iy7Ifq2ysilWU4QlCx/97OoI4xT1IV7i8byT/EyIT/M= +github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3/go.mod h1:BYpt4ufZiIGv2nXn4gMxnfKV306n3mWXgNu/d2TqdTU= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/karrick/godirwalk v1.15.3 h1:0a2pXOgtB16CqIqXTiT7+K9L73f74n/aNQUnH6Ortew= github.com/karrick/godirwalk v1.15.3/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -170,139 +277,152 @@ github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8 github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/oasislabs/ed25519 v0.0.0-20200206134218-2893bee822a3 h1:xhsvlWpWPdHXHt8i5eaXf2WbAxHLciGqrfup6zAPjVQ= -github.com/oasislabs/ed25519 v0.0.0-20200206134218-2893bee822a3/go.mod h1:xIpCyrK2ouGA4QBGbiNbkoONrvJ00u9P3QOkXSOAC0c= +github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= +github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= +github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e h1:07zdEcJ4Fble5uWsqKpjW19699kQWRLXP+RZh1a6ZRg= +github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e/go.mod h1:79GLCU4P87rYvYYACbNwVyc1WmRvkwQbYnybpCmRXzg= +github.com/oasisprotocol/ed25519 v0.0.0-20200528083105-55566edd6df0 h1:qmiMZ6ZhkeQZkV/Huajj+QBAu1jX0HTGsOwi+eXTGY8= +github.com/oasisprotocol/ed25519 v0.0.0-20200528083105-55566edd6df0/go.mod h1:IZbb50w3AB72BVobEF6qG93NNSrTw/V2QlboxqSu3Xw= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/panjf2000/ants/v2 v2.2.2 h1:TWzusBjq/IflXhy+/S6u5wmMLCBdJnB9tPIx9Zmhvok= -github.com/panjf2000/ants/v2 v2.2.2/go.mod h1:1GFm8bV8nyCQvU5K4WvBCTG1/YBFOD2VzjffD8fV55A= +github.com/panjf2000/ants/v2 v2.4.1 h1:7RtUqj5lGOw0WnZhSKDZ2zzJhaX5490ZW1sUolRXCxY= +github.com/panjf2000/ants/v2 v2.4.1/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= -github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U= +github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.5.2 h1:qLvObTrvO/XRCqmkKxUlOBc48bI3efyDuAZe25QiF0w= github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sasha-s/go-deadlock v0.2.0 h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y= github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shirou/gopsutil v2.20.5+incompatible h1:tYH07UPoQt0OCQdgWWMgYHy3/a9bcxNpBIysykNIP7I= +github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/simia-tech/env v0.1.0/go.mod h1:eVRQ7W5NXXHifpPAcTJ3r5EmoGgMn++dXfSVbZv3Opo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk= +github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4= -github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= -github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -311,17 +431,22 @@ github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= @@ -329,144 +454,241 @@ github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= +go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= +go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= +go.dedis.ch/kyber/v3 v3.0.12 h1:15d61EyBcBoFIS97kS2c/Vz4o3FR8ALnZ2ck9J/ebYM= +go.dedis.ch/kyber/v3 v3.0.12/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U= +go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= +go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= +go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo= +go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.mongodb.org/mongo-driver v1.0.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM= -go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E= -go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4= golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200427175716-29b57079015a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190214204934-8dcb7bc8c7fe/go.mod h1:E6PF97AdD6v0s+fPshSmumCW1S1Ne85RbPQxELkKa44= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200308013534-11ec41452d41 h1:9Di9iYgOt9ThCipBxChBVhgNipDoE5mxO84rQV7D0FE= golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200330040139-fa3cc9eebcfe h1:sOd+hT8wBUrIFR5Q6uQb/rg50z8NjHk96kC4adwvxjw= +golang.org/x/tools v0.0.0-20200330040139-fa3cc9eebcfe/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2 h1:KlOjjpQjL4dqscfbhtQvAnRMm5PaRTchHHczffkUiq0= +google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.30.0-dev.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc/examples v0.0.0-20200617041141-9a465503579e h1:AY+Ce5Wpmo18EeO38rySZDuOuWHefL7dR0DIFjEqxmo= +google.golang.org/grpc/examples v0.0.0-20200617041141-9a465503579e/go.mod h1:wwLo5XaKQhinfnT+PqwJ17u2NXm7cllRQ4fKKyB22+w= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -474,10 +696,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/h2non/gock.v1 v1.0.14/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= @@ -492,14 +712,18 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/images/autopeering.png b/images/autopeering.png deleted file mode 100644 index abbe28a3663f83182813c5eb9dd70c1ef994394a..0000000000000000000000000000000000000000 Binary files a/images/autopeering.png and /dev/null differ diff --git a/images/building-blocks.png b/images/building-blocks.png deleted file mode 100644 index 2099b05c261c1975311306d0380df298918cbf0e..0000000000000000000000000000000000000000 Binary files a/images/building-blocks.png and /dev/null differ diff --git a/images/docker-network.png b/images/docker-network.png new file mode 100644 index 0000000000000000000000000000000000000000..cffa7fc8bf4d723f86449e2d2f72a82a69df959a Binary files /dev/null and b/images/docker-network.png differ diff --git a/images/integration-testing.png b/images/integration-testing.png new file mode 100644 index 0000000000000000000000000000000000000000..9138c7d33aac5f40c560e362688f94efc7f9519a Binary files /dev/null and b/images/integration-testing.png differ diff --git a/images/layers.jpg b/images/layers.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cfb1b27aac4931661b441845396c03b423ca72c9 Binary files /dev/null and b/images/layers.jpg differ diff --git a/images/ledger-state.png b/images/ledger-state.png new file mode 100644 index 0000000000000000000000000000000000000000..7d24175105e3032297f9af36fc754015625100ba Binary files /dev/null and b/images/ledger-state.png differ diff --git a/main.go b/main.go index b45501bafaac45113f5b9cbbfda612dcdb98c2af..9ab8148051344244923af21b6651ac6a221a6e2b 100644 --- a/main.go +++ b/main.go @@ -1,66 +1,20 @@ package main import ( - "net/http" _ "net/http/pprof" - "github.com/iotaledger/goshimmer/plugins/analysis" - "github.com/iotaledger/goshimmer/plugins/autopeering" - "github.com/iotaledger/goshimmer/plugins/bundleprocessor" - "github.com/iotaledger/goshimmer/plugins/cli" - "github.com/iotaledger/goshimmer/plugins/gossip" - "github.com/iotaledger/goshimmer/plugins/gracefulshutdown" - "github.com/iotaledger/goshimmer/plugins/graph" - "github.com/iotaledger/goshimmer/plugins/metrics" - "github.com/iotaledger/goshimmer/plugins/remotelog" - "github.com/iotaledger/goshimmer/plugins/spa" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/goshimmer/plugins/tipselection" - "github.com/iotaledger/goshimmer/plugins/webapi" - webapi_broadcastData "github.com/iotaledger/goshimmer/plugins/webapi/broadcastData" - webapi_findTransactionHashes "github.com/iotaledger/goshimmer/plugins/webapi/findTransactionHashes" - webapi_getNeighbors "github.com/iotaledger/goshimmer/plugins/webapi/getNeighbors" - webapi_getTransactionObjectsByHash "github.com/iotaledger/goshimmer/plugins/webapi/getTransactionObjectsByHash" - webapi_getTransactionTrytesByHash "github.com/iotaledger/goshimmer/plugins/webapi/getTransactionTrytesByHash" - webapi_gtta "github.com/iotaledger/goshimmer/plugins/webapi/gtta" - webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi/spammer" - webapi_auth "github.com/iotaledger/goshimmer/plugins/webauth" + "github.com/iotaledger/goshimmer/pluginmgr/core" + "github.com/iotaledger/goshimmer/pluginmgr/research" + "github.com/iotaledger/goshimmer/pluginmgr/ui" + "github.com/iotaledger/goshimmer/pluginmgr/webapi" "github.com/iotaledger/hive.go/node" ) func main() { - cli.PrintVersion() - cli.LoadConfig() - - go http.ListenAndServe("localhost:6061", nil) // pprof Server for Debbuging Mutexes - node.Run( - node.Plugins( - cli.PLUGIN, - remotelog.PLUGIN, - - autopeering.PLUGIN, - gossip.PLUGIN, - tangle.PLUGIN, - bundleprocessor.PLUGIN, - analysis.PLUGIN, - gracefulshutdown.PLUGIN, - tipselection.PLUGIN, - metrics.PLUGIN, - - webapi.PLUGIN, - webapi_auth.PLUGIN, - webapi_gtta.PLUGIN, - webapi_spammer.PLUGIN, - webapi_broadcastData.PLUGIN, - webapi_getTransactionTrytesByHash.PLUGIN, - webapi_getTransactionObjectsByHash.PLUGIN, - webapi_findTransactionHashes.PLUGIN, - webapi_getNeighbors.PLUGIN, - webapi_spammer.PLUGIN, - - spa.PLUGIN, - graph.PLUGIN, - ), + core.PLUGINS, + research.PLUGINS, + ui.PLUGINS, + webapi.PLUGINS, ) } diff --git a/packages/binary/datastructure/orderedmap/element.go b/packages/binary/datastructure/orderedmap/element.go new file mode 100644 index 0000000000000000000000000000000000000000..d8c4c03143999b3f752171cbeccd9322d19800fb --- /dev/null +++ b/packages/binary/datastructure/orderedmap/element.go @@ -0,0 +1,9 @@ +package orderedmap + +// Element defines the model of each element of the orderedMap. +type Element struct { + key interface{} + value interface{} + prev *Element + next *Element +} diff --git a/packages/binary/datastructure/orderedmap/orderedmap.go b/packages/binary/datastructure/orderedmap/orderedmap.go new file mode 100644 index 0000000000000000000000000000000000000000..dc6f19be417e3818dc745614b7ba2e6131cf117f --- /dev/null +++ b/packages/binary/datastructure/orderedmap/orderedmap.go @@ -0,0 +1,133 @@ +package orderedmap + +import ( + "sync" +) + +// OrderedMap provides a concurrent-safe ordered map. +type OrderedMap struct { + head *Element + tail *Element + dictionary map[interface{}]*Element + size int + mutex sync.RWMutex +} + +// New returns a new *OrderedMap. +func New() *OrderedMap { + return &OrderedMap{ + dictionary: make(map[interface{}]*Element), + } +} + +// Get returns the value mapped to the given key if exists. +func (orderedMap *OrderedMap) Get(key interface{}) (interface{}, bool) { + orderedMap.mutex.RLock() + defer orderedMap.mutex.RUnlock() + + orderedMapElement, orderedMapElementExists := orderedMap.dictionary[key] + if !orderedMapElementExists { + return nil, false + } + return orderedMapElement.value, true + +} + +// Set adds a key-value pair to the orderedMap. It returns false if the same pair already exists. +func (orderedMap *OrderedMap) Set(key interface{}, newValue interface{}) bool { + if oldValue, oldValueExists := orderedMap.Get(key); oldValueExists && oldValue == newValue { + return false + } + + orderedMap.mutex.Lock() + defer orderedMap.mutex.Unlock() + + if oldValue, oldValueExists := orderedMap.dictionary[key]; oldValueExists { + if oldValue.value == newValue { + return false + } + + oldValue.value = newValue + + return true + } + + newElement := &Element{ + key: key, + value: newValue, + } + + if orderedMap.head == nil { + orderedMap.head = newElement + } else { + orderedMap.tail.next = newElement + newElement.prev = orderedMap.tail + } + orderedMap.tail = newElement + orderedMap.size++ + + orderedMap.dictionary[key] = newElement + + return true +} + +// ForEach iterates through the orderedMap and calls the consumer function for every element. +// The iteration can be aborted by returning false in the consumer. +func (orderedMap *OrderedMap) ForEach(consumer func(key, value interface{}) bool) bool { + orderedMap.mutex.RLock() + currentEntry := orderedMap.head + orderedMap.mutex.RUnlock() + + for currentEntry != nil { + if !consumer(currentEntry.key, currentEntry.value) { + return false + } + + orderedMap.mutex.RLock() + currentEntry = currentEntry.next + orderedMap.mutex.RUnlock() + } + + return true +} + +// Delete deletes the given key (and related value) from the orderedMap. +// It returns false if the key is not found. +func (orderedMap *OrderedMap) Delete(key interface{}) bool { + if _, valueExists := orderedMap.Get(key); !valueExists { + return false + } + + orderedMap.mutex.Lock() + defer orderedMap.mutex.Unlock() + + value, valueExists := orderedMap.dictionary[key] + if !valueExists { + return false + } + + delete(orderedMap.dictionary, key) + orderedMap.size-- + + if value.prev != nil { + value.prev.next = value.next + } else { + orderedMap.head = value.next + } + + if value.next != nil { + value.next.prev = value.prev + } else { + orderedMap.tail = value.prev + } + + return true +} + +// Size returns the size of the orderedMap. +func (orderedMap *OrderedMap) Size() int { + orderedMap.mutex.RLock() + defer orderedMap.mutex.RUnlock() + + return orderedMap.size +} diff --git a/packages/binary/datastructure/orderedmap/orderedmap_test.go b/packages/binary/datastructure/orderedmap/orderedmap_test.go new file mode 100644 index 0000000000000000000000000000000000000000..0b202a0878ec52a82dba784cb149d992c1fce03d --- /dev/null +++ b/packages/binary/datastructure/orderedmap/orderedmap_test.go @@ -0,0 +1,169 @@ +package orderedmap + +import ( + "fmt" + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestOrderedMap_Size(t *testing.T) { + orderedMap := New() + + assert.Equal(t, 0, orderedMap.Size()) + + orderedMap.Set(1, 1) + + assert.Equal(t, 1, orderedMap.Size()) + + orderedMap.Set(3, 1) + orderedMap.Set(2, 1) + + assert.Equal(t, 3, orderedMap.Size()) + + orderedMap.Set(2, 2) + + assert.Equal(t, 3, orderedMap.Size()) + + orderedMap.Delete(2) + + assert.Equal(t, 2, orderedMap.Size()) +} + +func TestNew(t *testing.T) { + orderedMap := New() + require.NotNil(t, orderedMap) + + assert.Equal(t, 0, orderedMap.Size()) + + assert.Nil(t, orderedMap.head) + assert.Nil(t, orderedMap.tail) +} + +func TestSetGetDelete(t *testing.T) { + orderedMap := New() + require.NotNil(t, orderedMap) + + // when adding the first new key,value pair, we must return true + keyValueAdded := orderedMap.Set("key", "value") + assert.True(t, keyValueAdded) + + // we should be able to retrieve the just added element + value, ok := orderedMap.Get("key") + assert.Equal(t, "value", value) + assert.True(t, ok) + + // head and tail should NOT be nil and match and size should be 1 + assert.NotNil(t, orderedMap.head) + assert.Same(t, orderedMap.head, orderedMap.tail) + assert.Equal(t, 1, orderedMap.Size()) + + // when adding the same key,value pair must return false + // and size should not change; + keyValueAdded = orderedMap.Set("key", "value") + assert.False(t, keyValueAdded) + assert.Equal(t, 1, orderedMap.Size()) + + // when retrieving something that does not exist we + // should get nil, false + value, ok = orderedMap.Get("keyNotStored") + assert.Nil(t, value) + assert.False(t, ok) + + // when deleting an existing element, we must get true, + // the element must be removed, and size decremented. + deleted := orderedMap.Delete("key") + assert.True(t, deleted) + value, ok = orderedMap.Get("key") + assert.Nil(t, value) + assert.False(t, ok) + assert.Equal(t, 0, orderedMap.Size()) + + // if we delete the only element, head and tail should be both nil + assert.Nil(t, orderedMap.head) + assert.Same(t, orderedMap.head, orderedMap.tail) + + // when deleting a NON existing element, we must get false + deleted = orderedMap.Delete("key") + assert.False(t, deleted) +} + +func TestForEach(t *testing.T) { + orderedMap := New() + require.NotNil(t, orderedMap) + + testElements := []Element{ + {key: "one", value: 1}, + {key: "two", value: 2}, + {key: "three", value: 3}, + } + + for _, element := range testElements { + keyValueAdded := orderedMap.Set(element.key, element.value) + assert.True(t, keyValueAdded) + } + + // test that all elements are positive via ForEach + testPositive := orderedMap.ForEach(func(key, value interface{}) bool { + return value.(int) > 0 + }) + assert.True(t, testPositive) + + testNegative := orderedMap.ForEach(func(key, value interface{}) bool { + return value.(int) < 0 + }) + assert.False(t, testNegative) +} + +func TestConcurrencySafe(t *testing.T) { + orderedMap := New() + require.NotNil(t, orderedMap) + + // initialize a slice of 100 elements + set := make([]Element, 100) + for i := 0; i < 100; i++ { + element := Element{key: fmt.Sprintf("%d", i), value: i} + set[i] = element + } + + // let 10 workers fill the orderedMap + workers := 10 + var wg sync.WaitGroup + wg.Add(workers) + for i := 0; i < workers; i++ { + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + ele := set[i] + orderedMap.Set(ele.key, ele.value) + } + }() + } + wg.Wait() + + // check that all the elements consumed from the set + // have been stored in the orderedMap and its size matches + for i := 0; i < 100; i++ { + value, ok := orderedMap.Get(set[i].key) + assert.Equal(t, set[i].value, value) + assert.True(t, ok) + } + assert.Equal(t, 100, orderedMap.Size()) + + // let 10 workers delete elements from the orderedMAp + wg.Add(workers) + for i := 0; i < workers; i++ { + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + ele := set[i] + orderedMap.Delete(ele.key) + } + }() + } + wg.Wait() + + assert.Equal(t, 0, orderedMap.Size()) +} diff --git a/packages/binary/datastructure/queue/queue.go b/packages/binary/datastructure/queue/queue.go new file mode 100644 index 0000000000000000000000000000000000000000..33cd34f9344607d86596e422cb7c8d539b4a5c66 --- /dev/null +++ b/packages/binary/datastructure/queue/queue.go @@ -0,0 +1,66 @@ +package queue + +import ( + "sync" +) + +type Queue struct { + ringBuffer []interface{} + read int + write int + capacity int + size int + mutex sync.Mutex +} + +func New(capacity int) *Queue { + return &Queue{ + ringBuffer: make([]interface{}, capacity), + capacity: capacity, + } +} + +func (queue *Queue) Size() int { + queue.mutex.Lock() + defer queue.mutex.Unlock() + + return queue.size +} + +func (queue *Queue) Capacity() int { + queue.mutex.Lock() + defer queue.mutex.Unlock() + + return queue.capacity +} + +func (queue *Queue) Offer(element interface{}) bool { + queue.mutex.Lock() + defer queue.mutex.Unlock() + + if queue.size == queue.capacity { + return false + } + + queue.ringBuffer[queue.write] = element + queue.write = (queue.write + 1) % queue.capacity + queue.size++ + + return true +} + +func (queue *Queue) Poll() (element interface{}, success bool) { + queue.mutex.Lock() + defer queue.mutex.Unlock() + + if success = queue.size != 0; !success { + return + } + + element = queue.ringBuffer[queue.read] + queue.ringBuffer[queue.read] = nil + queue.read = (queue.read + 1) % queue.capacity + queue.size-- + + return +} diff --git a/packages/binary/datastructure/queue/queue_test.go b/packages/binary/datastructure/queue/queue_test.go new file mode 100644 index 0000000000000000000000000000000000000000..67d5351b2683004d13108403c2f0aafcf4c094ed --- /dev/null +++ b/packages/binary/datastructure/queue/queue_test.go @@ -0,0 +1,112 @@ +package queue + +import ( + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewQueue(t *testing.T) { + queue := New(2) + require.NotNil(t, queue) + assert.Equal(t, 0, queue.Size()) + assert.Equal(t, 2, queue.Capacity()) +} + +func TestQueueOfferPoll(t *testing.T) { + queue := New(2) + require.NotNil(t, queue) + + // offer element to queue + assert.True(t, queue.Offer(1)) + assert.Equal(t, 1, queue.Size()) + + assert.True(t, queue.Offer(2)) + assert.Equal(t, 2, queue.Size()) + + assert.False(t, queue.Offer(3)) + + // Poll element from queue + polledValue, ok := queue.Poll() + assert.True(t, ok) + assert.Equal(t, 1, polledValue) + assert.Equal(t, 1, queue.Size()) + + polledValue, ok = queue.Poll() + assert.True(t, ok) + assert.Equal(t, 2, polledValue) + assert.Equal(t, 0, queue.Size()) + + polledValue, ok = queue.Poll() + assert.False(t, ok) + assert.Nil(t, polledValue) + assert.Equal(t, 0, queue.Size()) + + // Offer the empty queue again + assert.True(t, queue.Offer(3)) + assert.Equal(t, 1, queue.Size()) +} + +func TestQueueOfferConcurrencySafe(t *testing.T) { + queue := New(100) + require.NotNil(t, queue) + + // let 10 workers fill the queue + workers := 10 + var wg sync.WaitGroup + wg.Add(workers) + for i := 0; i < workers; i++ { + go func() { + defer wg.Done() + for j := 0; j < 10; j++ { + queue.Offer(j) + } + }() + } + wg.Wait() + + // check that all the elements are offered + assert.Equal(t, 100, queue.Size()) + + counter := make([]int, 10) + for i := 0; i < 100; i++ { + value, ok := queue.Poll() + assert.True(t, ok) + counter[value.(int)] += 1 + } + assert.Equal(t, 0, queue.Size()) + + // check that the insert numbers are correct + for i := 0; i < 10; i++ { + assert.Equal(t, 10, counter[i]) + } +} + +func TestQueuePollConcurrencySafe(t *testing.T) { + queue := New(100) + require.NotNil(t, queue) + + for j := 0; j < 100; j++ { + queue.Offer(j) + } + + // let 10 workers poll the queue + workers := 10 + var wg sync.WaitGroup + wg.Add(workers) + for i := 0; i < workers; i++ { + go func() { + defer wg.Done() + for j := 0; j < 10; j++ { + _, ok := queue.Poll() + assert.True(t, ok) + } + }() + } + wg.Wait() + + // check that all the elements are polled + assert.Equal(t, 0, queue.Size()) +} diff --git a/packages/binary/datastructure/random_map.go b/packages/binary/datastructure/random_map.go new file mode 100644 index 0000000000000000000000000000000000000000..ff1692c441440377d9dc325d1745401e738d7f3d --- /dev/null +++ b/packages/binary/datastructure/random_map.go @@ -0,0 +1,129 @@ +package datastructure + +import ( + "math/rand" + "sync" + "time" +) + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +type randomMapEntry struct { + key interface{} + value interface{} + keyIndex int +} + +type RandomMap struct { + rawMap map[interface{}]*randomMapEntry + keys []interface{} + size int + mutex sync.RWMutex +} + +func NewRandomMap() *RandomMap { + return &RandomMap{ + rawMap: make(map[interface{}]*randomMapEntry), + keys: make([]interface{}, 0), + } +} + +func (rmap *RandomMap) Set(key interface{}, value interface{}) (updated bool) { + rmap.mutex.Lock() + + if entry, exists := rmap.rawMap[key]; exists { + if entry.value != value { + entry.value = value + + updated = true + } + } else { + rmap.rawMap[key] = &randomMapEntry{ + key: key, + value: value, + keyIndex: rmap.size, + } + + updated = true + + rmap.keys = append(rmap.keys, key) + + rmap.size++ + } + + rmap.mutex.Unlock() + + return +} + +func (rmap *RandomMap) Get(key interface{}) (result interface{}, exists bool) { + rmap.mutex.RLock() + + if entry, entryExists := rmap.rawMap[key]; entryExists { + result = entry.value + exists = entryExists + } + + rmap.mutex.RUnlock() + + return +} + +func (rmap *RandomMap) Delete(key interface{}) (result interface{}, exists bool) { + rmap.mutex.RLock() + + if _, entryExists := rmap.rawMap[key]; entryExists { + rmap.mutex.RUnlock() + rmap.mutex.Lock() + + if entry, entryExists := rmap.rawMap[key]; entryExists { + delete(rmap.rawMap, key) + + rmap.size-- + + if entry.keyIndex != rmap.size { + oldKey := entry.keyIndex + movedKey := rmap.keys[rmap.size] + + rmap.rawMap[movedKey].keyIndex = oldKey + + rmap.keys[oldKey] = movedKey + } + + rmap.keys = rmap.keys[:rmap.size] + + result = entry.value + exists = true + } + + rmap.mutex.Unlock() + } else { + rmap.mutex.RUnlock() + } + + return +} + +func (rmap *RandomMap) Size() (result int) { + rmap.mutex.RLock() + + result = rmap.size + + rmap.mutex.RUnlock() + + return +} + +func (rmap *RandomMap) RandomEntry() (result interface{}) { + rmap.mutex.RLock() + + if rmap.size >= 1 { + result = rmap.rawMap[rmap.keys[rand.Intn(rmap.size)]].value + } + + rmap.mutex.RUnlock() + + return +} diff --git a/packages/binary/drng/dispatcher.go b/packages/binary/drng/dispatcher.go new file mode 100644 index 0000000000000000000000000000000000000000..4e79a85a2a1d229be302c6c8352b676a095792dd --- /dev/null +++ b/packages/binary/drng/dispatcher.go @@ -0,0 +1,51 @@ +package drng + +import ( + "errors" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/drng/payload" + "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon" + "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/events" + cb "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/marshalutil" +) + +// Dispatch parses a DRNG message and process it based on its subtype +func (drng *DRNG) Dispatch(issuer ed25519.PublicKey, timestamp time.Time, payload *payload.Payload) error { + switch payload.Header.PayloadType { + case header.TypeCollectiveBeacon: + // parse as CollectiveBeaconType + marshalUtil := marshalutil.New(payload.Bytes()) + parsedPayload, err := cb.Parse(marshalUtil) + if err != nil { + return err + } + // trigger CollectiveBeaconEvent + cbEvent := &events.CollectiveBeaconEvent{ + IssuerPublicKey: issuer, + Timestamp: timestamp, + InstanceID: parsedPayload.Header.InstanceID, + Round: parsedPayload.Round, + PrevSignature: parsedPayload.PrevSignature, + Signature: parsedPayload.Signature, + Dpk: parsedPayload.Dpk, + } + drng.Events.CollectiveBeacon.Trigger(cbEvent) + + // process collectiveBeacon + if err := collectiveBeacon.ProcessBeacon(drng.State, cbEvent); err != nil { + return err + } + + // trigger RandomnessEvent + drng.Events.Randomness.Trigger(drng.State.Randomness()) + + return nil + + default: + return errors.New("subtype not implemented") + } +} diff --git a/packages/binary/drng/dispatcher_test.go b/packages/binary/drng/dispatcher_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bef89e1c38367216081d971603eae6a7bbf85c4d --- /dev/null +++ b/packages/binary/drng/dispatcher_test.go @@ -0,0 +1,70 @@ +package drng + +import ( + "encoding/hex" + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/drng/payload" + "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + "github.com/iotaledger/goshimmer/packages/binary/drng/state" + "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon" + cbPayload "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/stretchr/testify/require" +) + +var ( + prevSignatureTest []byte + signatureTest []byte + dpkTest []byte + issuerPK ed25519.PublicKey + committeeTest *state.Committee + timestampTest time.Time + randomnessTest *state.Randomness +) + +func init() { + prevSignatureTest, _ = hex.DecodeString("962c0f195e8a4b281d73952aed13b754e8d0e6be1e0fd0ab0eae76db8cf038d3ec7c82c0f7348f124c2e56df11c7283012758bda8fed44d8fa26ad69781e5853b9b187db878dedd84903584fb168f1287741fae29fe9a4b76a267ae7e0812072") + signatureTest, _ = hex.DecodeString("94ff0de5d59c87d73e75baf87b084096e4044036bf33c23357c0d5947d3dc876f87a260ce2a53243cd6e627b4771cbdc12c5751b70e885d533831f2b9e83df242dceee54f466537e75fdb7870622345b136c7f5944f84b1278fe83f6d5311d6b") + dpkTest, _ = hex.DecodeString("80b319dbf164d852cdac3d86f0b362e0131ddeae3d87f6c3c5e3b6a9de384093b983db88f70e2008b0e945657d5980e2") + timestampTest = time.Now() + + rand, _ := collectiveBeacon.ExtractRandomness(signatureTest) + randomnessTest = &state.Randomness{ + Round: 1, + Randomness: rand, + Timestamp: timestampTest, + } + + kp := ed25519.GenerateKeyPair() + issuerPK = kp.PublicKey + + committeeTest = &state.Committee{ + InstanceID: 1, + Threshold: 3, + Identities: []ed25519.PublicKey{issuerPK}, + DistributedPK: dpkTest, + } +} + +func dummyPayload() *cbPayload.Payload { + header := header.New(header.TypeCollectiveBeacon, 1) + return cbPayload.New(header.InstanceID, + 1, + prevSignatureTest, + signatureTest, + dpkTest) +} + +func TestDispatcher(t *testing.T) { + marshalUtil := marshalutil.New(dummyPayload().Bytes()) + parsedPayload, err := payload.Parse(marshalUtil) + require.NoError(t, err) + + drng := New(state.SetCommittee(committeeTest)) + err = drng.Dispatch(issuerPK, timestampTest, parsedPayload) + require.NoError(t, err) + require.Equal(t, *randomnessTest, drng.State.Randomness()) +} diff --git a/packages/binary/drng/drng.go b/packages/binary/drng/drng.go new file mode 100644 index 0000000000000000000000000000000000000000..15f6eadad97bcb5c31c54556b846f9bb0997c12c --- /dev/null +++ b/packages/binary/drng/drng.go @@ -0,0 +1,24 @@ +package drng + +import ( + "github.com/iotaledger/goshimmer/packages/binary/drng/state" + cbEvents "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/events" + "github.com/iotaledger/hive.go/events" +) + +// DRNG holds the state and events of a drng instance. +type DRNG struct { + State *state.State // The state of the DRNG. + Events *Event // The events fired on the DRNG. +} + +// New creates a new DRNG instance. +func New(setters ...state.Option) *DRNG { + return &DRNG{ + State: state.New(setters...), + Events: &Event{ + CollectiveBeacon: events.NewEvent(cbEvents.CollectiveBeaconReceived), + Randomness: events.NewEvent(randomnessReceived), + }, + } +} diff --git a/packages/binary/drng/events.go b/packages/binary/drng/events.go new file mode 100644 index 0000000000000000000000000000000000000000..a3420fcaca949bb995910044b0a3d74b42092151 --- /dev/null +++ b/packages/binary/drng/events.go @@ -0,0 +1,18 @@ +package drng + +import ( + "github.com/iotaledger/goshimmer/packages/binary/drng/state" + "github.com/iotaledger/hive.go/events" +) + +// Event holds the different events triggered by a DRNG instance. +type Event struct { + // Collective Beacon is triggered each time we receive a new CollectiveBeacon message. + CollectiveBeacon *events.Event + // Randomness is triggered each time we receive a new and valid CollectiveBeacon message. + Randomness *events.Event +} + +func randomnessReceived(handler interface{}, params ...interface{}) { + handler.(func(state.Randomness))(params[0].(state.Randomness)) +} diff --git a/packages/binary/drng/payload/header/header.go b/packages/binary/drng/payload/header/header.go new file mode 100644 index 0000000000000000000000000000000000000000..e3afed632e154e843fb22d1f2cfb09bbc1ec3e49 --- /dev/null +++ b/packages/binary/drng/payload/header/header.go @@ -0,0 +1,89 @@ +package header + +import ( + "github.com/iotaledger/hive.go/marshalutil" +) + +// Type defines the data model of a DRNG payload type +type Type = byte + +const ( + // TypeCollectiveBeacon defines a CollectiveBeacon payload type + TypeCollectiveBeacon Type = 1 +) + +// Length defines the length of a DRNG header +const Length = 5 + +// Header defines defines a DRNG payload header +type Header struct { + PayloadType Type // message type + InstanceID uint32 // identifier of the DRNG instance +} + +// New creates a new DRNG payload header for the given type and instance id. +func New(payloadType Type, instanceID uint32) Header { + return Header{ + PayloadType: payloadType, + InstanceID: instanceID, + } +} + +// Parse is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. +func Parse(marshalUtil *marshalutil.MarshalUtil) (Header, error) { + header, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) }) + if err != nil { + return Header{}, err + } + return header.(Header), nil +} + +// FromBytes unmarshals a header from a sequence of bytes. +// It either creates a new header or fills the optionally provided object with the parsed information. +func FromBytes(bytes []byte, optionalTargetObject ...*Header) (result Header, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + var targetObject *Header + switch len(optionalTargetObject) { + case 0: + targetObject = &result + case 1: + targetObject = optionalTargetObject[0] + default: + panic("too many arguments in call to FromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read payload type from bytes + if targetObject.PayloadType, err = marshalUtil.ReadByte(); err != nil { + return + } + + // read instance ID from bytes + if targetObject.InstanceID, err = marshalUtil.ReadUint32(); err != nil { + return + } + + // copy result if we have provided a target object + result = *targetObject + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// Bytes returns the header in serialized bytes form. +func (header *Header) Bytes() (bytes []byte) { + // initialize helper + marshalUtil := marshalutil.New() + + // marshal the payload specific information + marshalUtil.WriteByte(header.PayloadType) + marshalUtil.WriteUint32(header.InstanceID) + + bytes = marshalUtil.Bytes() + + return +} diff --git a/packages/binary/drng/payload/header/header_test.go b/packages/binary/drng/payload/header/header_test.go new file mode 100644 index 0000000000000000000000000000000000000000..03edf75346b7a3c83ede3012f093dd881e002df6 --- /dev/null +++ b/packages/binary/drng/payload/header/header_test.go @@ -0,0 +1,19 @@ +package header + +import ( + "testing" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/stretchr/testify/require" +) + +func TestParse(t *testing.T) { + header := New(TypeCollectiveBeacon, 0) + bytes := header.Bytes() + + marshalUtil := marshalutil.New(bytes) + parsedHeader, err := Parse(marshalUtil) + require.NoError(t, err) + + require.Equal(t, header, parsedHeader) +} diff --git a/packages/binary/drng/payload/payload.go b/packages/binary/drng/payload/payload.go new file mode 100644 index 0000000000000000000000000000000000000000..fe9768f70983397509e321fc211a9fd6af708891 --- /dev/null +++ b/packages/binary/drng/payload/payload.go @@ -0,0 +1,156 @@ +package payload + +import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/stringify" +) + +const ( + // ObjectName defines the name of the dRNG object. + ObjectName = "dRNG" +) + +// Payload defines a DRNG payload. +type Payload struct { + header.Header + Data []byte + + bytes []byte + bytesMutex sync.RWMutex +} + +// New creates a new DRNG payload. +func New(header header.Header, data []byte) *Payload { + return &Payload{ + Header: header, + Data: data, + } +} + +// Parse is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. +func Parse(marshalUtil *marshalutil.MarshalUtil) (*Payload, error) { + if payload, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) }); err != nil { + return &Payload{}, err + } else { + return payload.(*Payload), nil + } +} + +// FromBytes parses the marshaled version of a Payload into an object. +// It either returns a new Payload or fills an optionally provided Payload with the parsed information. +func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Payload{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to OutputFromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read information that are required to identify the payload from the outside + if _, err = marshalUtil.ReadUint32(); err != nil { + return + } + + len, err := marshalUtil.ReadUint32() + if err != nil { + return + } + + // parse header + if result.Header, err = header.Parse(marshalUtil); err != nil { + return + } + + // parse data + if result.Data, err = marshalUtil.ReadBytes(int(len - header.Length)); err != nil { + return + } + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + // store bytes, so we don't have to marshal manually + result.bytes = bytes[:consumedBytes] + + return +} + +func (payload *Payload) Bytes() (bytes []byte) { + // acquire lock for reading bytes + payload.bytesMutex.RLock() + + // return if bytes have been determined already + if bytes = payload.bytes; bytes != nil { + payload.bytesMutex.RUnlock() + return + } + + // switch to write lock + payload.bytesMutex.RUnlock() + payload.bytesMutex.Lock() + defer payload.bytesMutex.Unlock() + + // return if bytes have been determined in the mean time + if bytes = payload.bytes; bytes != nil { + return + } + // initialize helper + marshalUtil := marshalutil.New() + + // marshal the payload specific information + marshalUtil.WriteUint32(Type) + marshalUtil.WriteUint32(uint32(len(payload.Data) + header.Length)) + marshalUtil.WriteBytes(payload.Header.Bytes()) + marshalUtil.WriteBytes(payload.Data[:]) + + bytes = marshalUtil.Bytes() + + return +} + +func (payload *Payload) String() string { + return stringify.Struct("Payload", + stringify.StructField("type", uint64(payload.Header.PayloadType)), + stringify.StructField("instance", uint64(payload.Header.InstanceID)), + stringify.StructField("data", payload.Data), + ) +} + +// region Payload implementation /////////////////////////////////////////////////////////////////////////////////////// + +var Type = payload.Type(111) + +func (payload *Payload) Type() payload.Type { + return Type +} + +func (payload *Payload) Marshal() (bytes []byte, err error) { + return payload.Bytes(), nil +} + +func (payload *Payload) Unmarshal(data []byte) (err error) { + _, _, err = FromBytes(data, payload) + + return +} + +func init() { + payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) { + payload = &Payload{} + err = payload.Unmarshal(data) + + return + }) +} + +// // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/binary/drng/payload/payload_test.go b/packages/binary/drng/payload/payload_test.go new file mode 100644 index 0000000000000000000000000000000000000000..7a6ac612028ab923c61307fc725e4c6097dffe16 --- /dev/null +++ b/packages/binary/drng/payload/payload_test.go @@ -0,0 +1,33 @@ +package payload + +import ( + "testing" + + "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/stretchr/testify/require" +) + +func dummyPayload() *Payload { + header := header.New(header.TypeCollectiveBeacon, 0) + data := []byte("test") + return New(header, data) +} + +func TestParse(t *testing.T) { + payload := dummyPayload() + bytes := payload.Bytes() + + marshalUtil := marshalutil.New(bytes) + parsedPayload, err := Parse(marshalUtil) + require.NoError(t, err) + + require.Equal(t, payload.Header.PayloadType, parsedPayload.Header.PayloadType) + require.Equal(t, payload.Header.InstanceID, parsedPayload.Header.InstanceID) + require.Equal(t, payload.Data, parsedPayload.Data) +} + +func TestString(t *testing.T) { + payload := dummyPayload() + _ = payload.String() +} diff --git a/packages/binary/drng/state/options.go b/packages/binary/drng/state/options.go new file mode 100644 index 0000000000000000000000000000000000000000..8ced6516f37939c64c382a3dd3d433f2c34fb54d --- /dev/null +++ b/packages/binary/drng/state/options.go @@ -0,0 +1,26 @@ +package state + +// Options define state options of a DRNG. +type Options struct { + // The initial committee of the DRNG. + Committee *Committee + // The initial randomness of the DRNG. + Randomness *Randomness +} + +// Option is a function which sets the given option. +type Option func(*Options) + +// SetCommittee sets the initial committee +func SetCommittee(c *Committee) Option { + return func(args *Options) { + args.Committee = c + } +} + +// SetRandomness sets the initial randomness +func SetRandomness(r *Randomness) Option { + return func(args *Options) { + args.Randomness = r + } +} diff --git a/packages/binary/drng/state/state.go b/packages/binary/drng/state/state.go new file mode 100644 index 0000000000000000000000000000000000000000..95e45d37be3c34f2d252ab177ae62f0ee8fbecf3 --- /dev/null +++ b/packages/binary/drng/state/state.go @@ -0,0 +1,91 @@ +package state + +import ( + "encoding/binary" + "sync" + "time" + + "github.com/iotaledger/hive.go/crypto/ed25519" +) + +// Randomness defines the current randomness state of a DRNG instance. +type Randomness struct { + // Round holds the current DRNG round. + Round uint64 + // Randomness holds the current randomness as a slice of bytes. + Randomness []byte + // Timestamp holds the timestamp when the current randomness was received. + Timestamp time.Time +} + +// Float64 returns a float64 [0.0,1.0) representation of the randomness byte slice. +func (r Randomness) Float64() float64 { + return float64(binary.BigEndian.Uint64(r.Randomness[:8])>>11) / (1 << 53) +} + +// Committee defines the current committee state of a DRNG instance. +type Committee struct { + // InstanceID holds the identifier of the dRAND instance. + InstanceID uint32 + // Threshold holds the threshold of the secret sharing protocol. + Threshold uint8 + // Identities holds the nodes' identities of the committee members. + Identities []ed25519.PublicKey + // DistributedPK holds the drand distributed public key. + DistributedPK []byte +} + +// The state of the DRNG. +type State struct { + randomness *Randomness + committee *Committee + + mutex sync.RWMutex +} + +// New creates a new State with the given optional options +func New(setters ...Option) *State { + args := &Options{} + + for _, setter := range setters { + setter(args) + } + return &State{ + randomness: args.Randomness, + committee: args.Committee, + } +} + +// UpdateRandomness updates the randomness of the DRNG state +func (s *State) UpdateRandomness(r *Randomness) { + s.mutex.Lock() + defer s.mutex.Unlock() + s.randomness = r +} + +// Randomness returns the randomness of the DRNG state +func (s *State) Randomness() Randomness { + s.mutex.RLock() + defer s.mutex.RUnlock() + if s.randomness == nil { + return Randomness{} + } + return *s.randomness +} + +// Update committee updates the committee of the DRNG state +func (s *State) UpdateCommittee(c *Committee) { + s.mutex.Lock() + defer s.mutex.Unlock() + s.committee = c +} + +// Committee returns the committee of the DRNG state +func (s *State) Committee() Committee { + s.mutex.RLock() + defer s.mutex.RUnlock() + if s.committee == nil { + return Committee{} + } + return *s.committee +} diff --git a/packages/binary/drng/state/state_test.go b/packages/binary/drng/state/state_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2dbd5490eef3c26928ce9e189b5f61bfa822bb0b --- /dev/null +++ b/packages/binary/drng/state/state_test.go @@ -0,0 +1,51 @@ +package state + +import ( + "testing" + "time" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/stretchr/testify/require" +) + +func dummyRandomness() *Randomness { + return &Randomness{ + Round: 0, + Randomness: []byte{}, + } +} + +func dummyCommittee() *Committee { + return &Committee{ + InstanceID: 0, + Threshold: 0, + Identities: []ed25519.PublicKey{}, + DistributedPK: []byte{}, + } +} + +func TestState(t *testing.T) { + // constructor + stateTest := New(SetCommittee(dummyCommittee()), SetRandomness(dummyRandomness())) + require.Equal(t, *dummyRandomness(), stateTest.Randomness()) + require.Equal(t, *dummyCommittee(), stateTest.Committee()) + + // committee setters - getters + newCommittee := &Committee{1, 1, []ed25519.PublicKey{}, []byte{11}} + stateTest.UpdateCommittee(newCommittee) + require.Equal(t, *newCommittee, stateTest.Committee()) + + // randomness setters - getters + newRandomness := &Randomness{1, []byte{123}, time.Now()} + stateTest.UpdateRandomness(newRandomness) + require.Equal(t, *newRandomness, stateTest.Randomness()) +} + +func TestFloat64(t *testing.T) { + + max := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} + r := &Randomness{1, max, time.Now()} + stateTest := New(SetRandomness(r)) + require.Equal(t, 0.9999999999999999, stateTest.Randomness().Float64()) + +} diff --git a/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon.go b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon.go new file mode 100644 index 0000000000000000000000000000000000000000..c539e6e37f0c97800a56e4f777ff993918054aac --- /dev/null +++ b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon.go @@ -0,0 +1,120 @@ +package collectiveBeacon + +import ( + "bytes" + "crypto/sha512" + "errors" + + "github.com/drand/drand/beacon" + "github.com/drand/drand/key" + "github.com/iotaledger/goshimmer/packages/binary/drng/state" + "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/events" + "github.com/iotaledger/hive.go/crypto/ed25519" +) + +var ( + ErrDistributedPubKeyMismatch = errors.New("Distributed Public Key does not match") + ErrInvalidRound = errors.New("Invalid Round") + ErrInstanceIdMismatch = errors.New("InstanceID does not match") + ErrInvalidIssuer = errors.New("Invalid Issuer") + ErrNilState = errors.New("Nil state") + ErrNilData = errors.New("Nil data") +) + +// ProcessBeacon performs the following tasks: +// - verify that we have a valid random +// - update drng state +func ProcessBeacon(drng *state.State, cb *events.CollectiveBeaconEvent) error { + + // verify that we have a valid random + if err := VerifyCollectiveBeacon(drng, cb); err != nil { + //TODO: handle error + return err + } + + // update drng state + randomness, err := ExtractRandomness(cb.Signature) + if err != nil { + //TODO: handle error + return err + } + newRandomness := &state.Randomness{ + Round: cb.Round, + Randomness: randomness, + Timestamp: cb.Timestamp, + } + + drng.UpdateRandomness(newRandomness) + + return nil +} + +// VerifyCollectiveBeacon verifies against a given state that +// the given CollectiveBeaconEvent contains a valid beacon. +func VerifyCollectiveBeacon(state *state.State, data *events.CollectiveBeaconEvent) error { + if state == nil { + return ErrNilState + } + + if data == nil { + return ErrNilData + } + + if err := verifyIssuer(state, data.IssuerPublicKey); err != nil { + return err + } + + if !bytes.Equal(data.Dpk, state.Committee().DistributedPK) { + return ErrDistributedPubKeyMismatch + } + + if data.Round <= state.Randomness().Round { + return ErrInvalidRound + } + + if data.InstanceID != state.Committee().InstanceID { + return ErrInstanceIdMismatch + } + + if err := verifySignature(data); err != nil { + return err + } + + return nil +} + +// verifyIssuer checks the given issuer is a member of the committee. +func verifyIssuer(state *state.State, issuer ed25519.PublicKey) error { + for _, member := range state.Committee().Identities { + if member == issuer { + return nil + } + } + return ErrInvalidIssuer +} + +// verifySignature checks the current signature against the distributed public key. +func verifySignature(data *events.CollectiveBeaconEvent) error { + dpk := key.KeyGroup.Point() + if err := dpk.UnmarshalBinary(data.Dpk); err != nil { + return err + } + + msg := beacon.Message(data.Round, data.PrevSignature) + + if err := key.Scheme.VerifyRecovered(dpk, msg, data.Signature); err != nil { + return err + } + + return nil +} + +// ExtractRandomness returns the randomness from a given signature. +func ExtractRandomness(signature []byte) ([]byte, error) { + hash := sha512.New() + if _, err := hash.Write(signature); err != nil { + return nil, err + } + + return hash.Sum(nil), nil +} diff --git a/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon_test.go b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon_test.go new file mode 100644 index 0000000000000000000000000000000000000000..62d991fb9ebcb1ff1ddc4965f53948194f749114 --- /dev/null +++ b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon_test.go @@ -0,0 +1,141 @@ +package collectiveBeacon + +import ( + "encoding/hex" + "log" + "testing" + + "github.com/drand/drand/beacon" + "github.com/drand/drand/key" + "github.com/drand/kyber/share" + "github.com/drand/kyber/util/random" + "github.com/iotaledger/goshimmer/packages/binary/drng/state" + "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/events" + "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/stretchr/testify/require" +) + +var ( + eventTest *events.CollectiveBeaconEvent + prevSignatureTest []byte + signatureTest []byte + dpkTest []byte + issuerPK ed25519.PublicKey + stateTest *state.State +) + +func init() { + prevSignatureTest, _ = hex.DecodeString("962c0f195e8a4b281d73952aed13b754e8d0e6be1e0fd0ab0eae76db8cf038d3ec7c82c0f7348f124c2e56df11c7283012758bda8fed44d8fa26ad69781e5853b9b187db878dedd84903584fb168f1287741fae29fe9a4b76a267ae7e0812072") + signatureTest, _ = hex.DecodeString("94ff0de5d59c87d73e75baf87b084096e4044036bf33c23357c0d5947d3dc876f87a260ce2a53243cd6e627b4771cbdc12c5751b70e885d533831f2b9e83df242dceee54f466537e75fdb7870622345b136c7f5944f84b1278fe83f6d5311d6b") + dpkTest, _ = hex.DecodeString("80b319dbf164d852cdac3d86f0b362e0131ddeae3d87f6c3c5e3b6a9de384093b983db88f70e2008b0e945657d5980e2") + + kp := ed25519.GenerateKeyPair() + issuerPK = kp.PublicKey + + eventTest = &events.CollectiveBeaconEvent{ + IssuerPublicKey: issuerPK, + InstanceID: 1, + Round: 1, + PrevSignature: prevSignatureTest, + Signature: signatureTest, + Dpk: dpkTest, + } + + stateTest = state.New(state.SetCommittee( + &state.Committee{ + InstanceID: 1, + Threshold: 3, + Identities: []ed25519.PublicKey{issuerPK}, + DistributedPK: dpkTest, + })) +} + +func TestVerifySignature(t *testing.T) { + err := verifySignature(eventTest) + require.NoError(t, err) +} + +func TestGetRandomness(t *testing.T) { + _, err := ExtractRandomness(eventTest.Signature) + require.NoError(t, err) +} + +func TestProcessBeacon(t *testing.T) { + err := ProcessBeacon(stateTest, eventTest) + require.NoError(t, err) +} + +func TestDkgShares(t *testing.T) { + dkgShares(t, 5, 3) +} + +func dkgShares(t *testing.T, n, threshold int) *payload.Payload { + var priPoly *share.PriPoly + var pubPoly *share.PubPoly + var err error + // create shares and commitments + for i := 0; i < n; i++ { + pri := share.NewPriPoly(key.KeyGroup, threshold, key.KeyGroup.Scalar().Pick(random.New()), random.New()) + pub := pri.Commit(key.KeyGroup.Point().Base()) + if priPoly == nil { + priPoly = pri + pubPoly = pub + continue + } + priPoly, err = priPoly.Add(pri) + require.NoError(t, err) + + pubPoly, err = pubPoly.Add(pub) + require.NoError(t, err) + } + shares := priPoly.Shares(n) + secret, err := share.RecoverSecret(key.KeyGroup, shares, threshold, n) + require.NoError(t, err) + require.True(t, secret.Equal(priPoly.Secret())) + + msg := []byte("first message") + sigs := make([][]byte, n) + _, commits := pubPoly.Info() + dkgShares := make([]*key.Share, n) + + // partial signatures + for i := 0; i < n; i++ { + sigs[i], err = key.Scheme.Sign(shares[i], msg) + require.NoError(t, err) + + dkgShares[i] = &key.Share{ + Share: shares[i], + Commits: commits, + } + } + + // reconstruct collective signature + sig, err := key.Scheme.Recover(pubPoly, msg, sigs, threshold, n) + require.NoError(t, err) + + // verify signature against distributed public key + err = key.Scheme.VerifyRecovered(pubPoly.Commit(), msg, sig) + require.NoError(t, err) + + msg = beacon.Message(1, sig) + sigs = make([][]byte, n) + // partial signatures + for i := 0; i < n; i++ { + sigs[i], err = key.Scheme.Sign(shares[i], msg) + require.NoError(t, err) + } + + // reconstruct collective signature + newSig, err := key.Scheme.Recover(pubPoly, msg, sigs, threshold, n) + require.NoError(t, err) + + dpk, err := pubPoly.Commit().MarshalBinary() + require.NoError(t, err) + + log.Println(hex.EncodeToString(sig)) + log.Println(hex.EncodeToString(newSig)) + log.Println(hex.EncodeToString(dpk)) + + return payload.New(1, 1, sig, newSig, dpk) +} diff --git a/packages/binary/drng/subtypes/collectiveBeacon/events/events.go b/packages/binary/drng/subtypes/collectiveBeacon/events/events.go new file mode 100644 index 0000000000000000000000000000000000000000..8425e20c1fbc6593ab695ec0ad989d328bed00d7 --- /dev/null +++ b/packages/binary/drng/subtypes/collectiveBeacon/events/events.go @@ -0,0 +1,30 @@ +package events + +import ( + "time" + + "github.com/iotaledger/hive.go/crypto/ed25519" +) + +// CollectiveBeaconEvent holds data about a collective beacon event. +type CollectiveBeaconEvent struct { + // Public key of the issuer. + IssuerPublicKey ed25519.PublicKey + // Timestamp when the beacon was issued. + Timestamp time.Time + // InstanceID of the beacon. + InstanceID uint32 + // Round of the current beacon. + Round uint64 + // Collective signature of the previous beacon. + PrevSignature []byte + // Collective signature of the current beacon. + Signature []byte + // The distributed public key. + Dpk []byte +} + +// CollectiveBeaconReceived returns the data of a collective beacon event. +func CollectiveBeaconReceived(handler interface{}, params ...interface{}) { + handler.(func(*CollectiveBeaconEvent))(params[0].(*CollectiveBeaconEvent)) +} diff --git a/packages/binary/drng/subtypes/collectiveBeacon/events/events_test.go b/packages/binary/drng/subtypes/collectiveBeacon/events/events_test.go new file mode 100644 index 0000000000000000000000000000000000000000..3100a36097e4067d5fe90e12f1a043ff2a2f1812 --- /dev/null +++ b/packages/binary/drng/subtypes/collectiveBeacon/events/events_test.go @@ -0,0 +1,27 @@ +package events + +import ( + "testing" + "time" + + "github.com/iotaledger/hive.go/events" + "github.com/stretchr/testify/require" +) + +func TestCollectiveBeaconEvent(t *testing.T) { + var cbReceived *CollectiveBeaconEvent + + eventTest := events.NewEvent(CollectiveBeaconReceived) + + eventTest.Attach(events.NewClosure(func(cb *CollectiveBeaconEvent) { + cbReceived = cb + })) + + cbTriggered := &CollectiveBeaconEvent{ + Timestamp: time.Now(), + } + eventTest.Trigger(cbTriggered) + + require.Equal(t, cbTriggered, cbReceived) + +} diff --git a/packages/binary/drng/subtypes/collectiveBeacon/payload/common.go b/packages/binary/drng/subtypes/collectiveBeacon/payload/common.go new file mode 100644 index 0000000000000000000000000000000000000000..13d8225f467a223f5d514b2f7920c158b1a2f649 --- /dev/null +++ b/packages/binary/drng/subtypes/collectiveBeacon/payload/common.go @@ -0,0 +1,8 @@ +package payload + +const ( + // BLS Signature size in bytes. + SignatureSize = 96 + // BLS Public Key size in bytes. + PublicKeySize = 48 +) diff --git a/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go new file mode 100644 index 0000000000000000000000000000000000000000..d53be6f1bf2689d305e90a2319f046f665842dd4 --- /dev/null +++ b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go @@ -0,0 +1,189 @@ +package payload + +import ( + "errors" + "fmt" + "sync" + + "github.com/iotaledger/hive.go/stringify" + + drngPayload "github.com/iotaledger/goshimmer/packages/binary/drng/payload" + "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/hive.go/marshalutil" +) + +var ( + // ErrMaximumPayloadSizeExceeded is returned if the payload exceeds the maximum size. + ErrMaximumPayloadSizeExceeded = errors.New("maximum payload size exceeded") +) + +// Payload is a collective beacon payload. +type Payload struct { + header.Header + + // Round of the current beacon + Round uint64 + // Collective signature of the previous beacon + PrevSignature []byte + // Collective signature of the current beacon + Signature []byte + // The distributed public key + Dpk []byte + + bytes []byte + bytesMutex sync.RWMutex +} + +// MaxCollectiveBeaconPayloadSize defines the maximum size of a collective beacon payload. +const MaxCollectiveBeaconPayloadSize = 64 * 1024 + +// New creates a new collective beacon payload. +func New(instanceID uint32, round uint64, prevSignature, signature, dpk []byte) *Payload { + return &Payload{ + Header: header.New(header.TypeCollectiveBeacon, instanceID), + Round: round, + PrevSignature: prevSignature, + Signature: signature, + Dpk: dpk, + } +} + +// Parse is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. +func Parse(marshalUtil *marshalutil.MarshalUtil) (*Payload, error) { + unmarshalledPayload, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) }) + if err != nil { + return nil, err + } + _payload := unmarshalledPayload.(*Payload) + if len(_payload.bytes) > MaxCollectiveBeaconPayloadSize { + return nil, fmt.Errorf("%w: %d", ErrMaximumPayloadSizeExceeded, MaxCollectiveBeaconPayloadSize) + } + return _payload, nil +} + +// FromBytes parses the marshaled version of a Payload into an object. +// It either returns a new Payload or fills an optionally provided Payload with the parsed information. +func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Payload{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to OutputFromBytes") + } + + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // read information that are required to identify the payload from the outside + if _, err = marshalUtil.ReadUint32(); err != nil { + return + } + if _, err = marshalUtil.ReadUint32(); err != nil { + return + } + + // parse header + if result.Header, err = header.Parse(marshalUtil); err != nil { + return + } + + // parse round + if result.Round, err = marshalUtil.ReadUint64(); err != nil { + return + } + + // parse prevSignature + if result.PrevSignature, err = marshalUtil.ReadBytes(SignatureSize); err != nil { + return + } + + // parse current signature + if result.Signature, err = marshalUtil.ReadBytes(SignatureSize); err != nil { + return + } + + // parse distributed public key + if result.Dpk, err = marshalUtil.ReadBytes(PublicKeySize); err != nil { + return + } + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + // store bytes, so we don't have to marshal manually + result.bytes = bytes[:consumedBytes] + + return +} + +func (payload *Payload) Bytes() (bytes []byte) { + // acquire lock for reading bytes + payload.bytesMutex.RLock() + + // return if bytes have been determined already + if bytes = payload.bytes; bytes != nil { + payload.bytesMutex.RUnlock() + return + } + + // switch to write lock + payload.bytesMutex.RUnlock() + payload.bytesMutex.Lock() + defer payload.bytesMutex.Unlock() + + // return if bytes have been determined in the mean time + if bytes = payload.bytes; bytes != nil { + return + } + + // marshal fields + payloadLength := header.Length + marshalutil.UINT64_SIZE + SignatureSize*2 + PublicKeySize + marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + payloadLength) + marshalUtil.WriteUint32(drngPayload.Type) + marshalUtil.WriteUint32(uint32(payloadLength)) + marshalUtil.WriteBytes(payload.Header.Bytes()) + marshalUtil.WriteUint64(payload.Round) + marshalUtil.WriteBytes(payload.PrevSignature) + marshalUtil.WriteBytes(payload.Signature) + marshalUtil.WriteBytes(payload.Dpk) + + bytes = marshalUtil.Bytes() + + // store result + payload.bytes = bytes + + return +} + +func (payload *Payload) String() string { + return stringify.Struct("Payload", + stringify.StructField("type", uint64(payload.Header.PayloadType)), + stringify.StructField("instance", uint64(payload.Header.InstanceID)), + stringify.StructField("round", payload.Round), + stringify.StructField("prevSignature", payload.PrevSignature), + stringify.StructField("signature", payload.Signature), + stringify.StructField("distributedPK", payload.Dpk), + ) +} + +// region Payload implementation /////////////////////////////////////////////////////////////////////////////////////// + +func (payload *Payload) Type() payload.Type { + return drngPayload.Type +} + +func (payload *Payload) Marshal() (bytes []byte, err error) { + return payload.Bytes(), nil +} + +func (payload *Payload) Unmarshal(data []byte) (err error) { + _, _, err = FromBytes(data, payload) + + return +} + +// // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/binary/drng/subtypes/collectiveBeacon/payload/payload_test.go b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload_test.go new file mode 100644 index 0000000000000000000000000000000000000000..03a782468a2560dfd4572602f8a424c4a831e646 --- /dev/null +++ b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload_test.go @@ -0,0 +1,39 @@ +package payload + +import ( + "testing" + + "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/stretchr/testify/require" +) + +func dummyPayload() *Payload { + header := header.New(header.TypeCollectiveBeacon, 0) + return New(header.InstanceID, + 0, + []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), // prevSignature + []byte("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"), // signature + []byte("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC")) // distributed PK +} + +func TestParse(t *testing.T) { + payload := dummyPayload() + bytes := payload.Bytes() + + marshalUtil := marshalutil.New(bytes) + parsedPayload, err := Parse(marshalUtil) + require.NoError(t, err) + + require.Equal(t, payload.Header.PayloadType, parsedPayload.Header.PayloadType) + require.Equal(t, payload.Header.InstanceID, parsedPayload.Header.InstanceID) + require.Equal(t, payload.Round, parsedPayload.Round) + require.Equal(t, payload.PrevSignature, parsedPayload.PrevSignature) + require.Equal(t, payload.Signature, parsedPayload.Signature) + require.Equal(t, payload.Dpk, parsedPayload.Dpk) +} + +func TestString(t *testing.T) { + payload := dummyPayload() + _ = payload.String() +} diff --git a/packages/binary/identity/constants.go b/packages/binary/identity/constants.go deleted file mode 100644 index b8fb985060952f9cdca9bffc0a5b058f12b9d597..0000000000000000000000000000000000000000 --- a/packages/binary/identity/constants.go +++ /dev/null @@ -1,7 +0,0 @@ -package identity - -const ( - PublicKeySize = 32 - PrivateKeySize = 64 - SignatureSize = 64 -) diff --git a/packages/binary/identity/identity.go b/packages/binary/identity/identity.go deleted file mode 100644 index fd52c6f3ff73724dd4d2e9c9f17a738af25b09e3..0000000000000000000000000000000000000000 --- a/packages/binary/identity/identity.go +++ /dev/null @@ -1,48 +0,0 @@ -package identity - -import ( - "crypto/rand" - - "github.com/oasislabs/ed25519" -) - -type Identity struct { - Type Type - PublicKey []byte - PrivateKey []byte -} - -func New(publicKey []byte, optionalPrivateKey ...[]byte) *Identity { - this := &Identity{ - PublicKey: make([]byte, len(publicKey)), - } - - copy(this.PublicKey, publicKey) - - if len(optionalPrivateKey) == 0 { - this.Type = Public - } else { - this.Type = Private - this.PrivateKey = optionalPrivateKey[0] - } - - return this -} - -func Generate() *Identity { - if public, private, err := ed25519.GenerateKey(rand.Reader); err != nil { - panic(err) - } else { - return New(public, private) - } -} - -func (identity *Identity) Sign(data []byte) (sig []byte) { - sig = ed25519.Sign(identity.PrivateKey, data) - - return -} - -func (identity *Identity) VerifySignature(data []byte, signature []byte) bool { - return ed25519.Verify(identity.PublicKey, data, signature) -} diff --git a/packages/binary/identity/identity_test.go b/packages/binary/identity/identity_test.go deleted file mode 100644 index f5fc0d525240ef9d53eed0e5499b612e4398485a..0000000000000000000000000000000000000000 --- a/packages/binary/identity/identity_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package identity - -import ( - "sync" - "testing" - - "github.com/panjf2000/ants/v2" - - "github.com/stretchr/testify/assert" -) - -func BenchmarkIdentity_VerifySignature(b *testing.B) { - identity := Generate() - data := []byte("TESTDATA") - signature := identity.Sign(data) - - var wg sync.WaitGroup - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - wg.Add(1) - - _ = ants.Submit(func() { - identity.VerifySignature(data, signature) - - wg.Done() - }) - } - - wg.Wait() -} - -func Test(t *testing.T) { - identity := Generate() - - signature := identity.Sign([]byte("TESTDATA1")) - - assert.Equal(t, true, identity.VerifySignature([]byte("TESTDATA1"), signature)) - assert.Equal(t, false, identity.VerifySignature([]byte("TESTDATA2"), signature)) -} diff --git a/packages/binary/identity/type.go b/packages/binary/identity/type.go deleted file mode 100644 index cc207b0279d2b24bf0b86190431a3753f0b34124..0000000000000000000000000000000000000000 --- a/packages/binary/identity/type.go +++ /dev/null @@ -1,8 +0,0 @@ -package identity - -type Type int - -const ( - Private = Type(0) - Public = Type(1) -) diff --git a/packages/binary/messagelayer/message/id.go b/packages/binary/messagelayer/message/id.go new file mode 100644 index 0000000000000000000000000000000000000000..2dfd4f2856498d5dae24551288aa82b2d3936815 --- /dev/null +++ b/packages/binary/messagelayer/message/id.go @@ -0,0 +1,80 @@ +package message + +import ( + "fmt" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/mr-tron/base58" +) + +// ContentId identifies the content of a message without its trunk/branch ids. +type ContentId = Id + +// ID identifies a message in its entirety. Unlike the sole content id, it also incorporates +// the trunk and branch ids. +type Id [IdLength]byte + +// NewId creates a new message id. +func NewId(base58EncodedString string) (result Id, err error) { + bytes, err := base58.Decode(base58EncodedString) + if err != nil { + return + } + + if len(bytes) != IdLength { + err = fmt.Errorf("length of base58 formatted message id is wrong") + + return + } + + copy(result[:], bytes) + + return +} + +// IdFromBytes unmarshals a message id from a sequence of bytes. +func IdFromBytes(bytes []byte) (result Id, consumedBytes int, err error) { + // check arguments + if len(bytes) < IdLength { + err = fmt.Errorf("bytes not long enough to encode a valid message id") + } + + // calculate result + copy(result[:], bytes) + + // return the number of bytes we processed + consumedBytes = IdLength + + return +} + +// ParseId is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. +func ParseId(marshalUtil *marshalutil.MarshalUtil) (Id, error) { + if id, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return IdFromBytes(data) }); err != nil { + return Id{}, err + } else { + return id.(Id), nil + } +} + +func (id *Id) MarshalBinary() (result []byte, err error) { + return id.Bytes(), nil +} + +func (id *Id) UnmarshalBinary(data []byte) (err error) { + copy(id[:], data) + + return +} + +func (id Id) Bytes() []byte { + return id[:] +} + +func (id Id) String() string { + return base58.Encode(id[:]) +} + +var EmptyId = Id{} + +const IdLength = 64 diff --git a/packages/binary/messagelayer/message/message.go b/packages/binary/messagelayer/message/message.go new file mode 100644 index 0000000000000000000000000000000000000000..6415cacba10e56ca2f779f08532a92f73842262e --- /dev/null +++ b/packages/binary/messagelayer/message/message.go @@ -0,0 +1,350 @@ +package message + +import ( + "sync" + "time" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" + "golang.org/x/crypto/blake2b" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +// Message represents the core message for the base layer Tangle. +type Message struct { + // base functionality of StorableObject + objectstorage.StorableObjectFlags + + // core properties (get sent over the wire) + trunkID Id + branchID Id + issuerPublicKey ed25519.PublicKey + issuingTime time.Time + sequenceNumber uint64 + payload payload.Payload + nonce uint64 + signature ed25519.Signature + + // derived properties + id *Id + idMutex sync.RWMutex + contentId *ContentId + contentIdMutex sync.RWMutex + bytes []byte + bytesMutex sync.RWMutex +} + +// New creates a new message with the details provided by the issuer. +func New(trunkID Id, branchID Id, issuingTime time.Time, issuerPublicKey ed25519.PublicKey, sequenceNumber uint64, payload payload.Payload, nonce uint64, signature ed25519.Signature) (result *Message) { + return &Message{ + trunkID: trunkID, + branchID: branchID, + issuerPublicKey: issuerPublicKey, + issuingTime: issuingTime, + sequenceNumber: sequenceNumber, + payload: payload, + nonce: nonce, + signature: signature, + } +} + +// FromBytes parses the given bytes into a message. +func FromBytes(bytes []byte, optionalTargetObject ...*Message) (result *Message, err error, consumedBytes int) { + marshalUtil := marshalutil.New(bytes) + result, err = Parse(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + return +} + +// Parse parses a message from the given marshal util. +func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Message) (result *Message, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Message{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to Parse") + } + + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// StorableObjectFromKey gets called when we restore a message from storage. +// The bytes and the content will be unmarshaled by an external caller (the objectStorage factory). +func StorableObjectFromKey(key []byte, optionalTargetObject ...*Message) (result objectstorage.StorableObject, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Message{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to StorableObjectFromKey") + } + + marshalUtil := marshalutil.New(key) + if id, idErr := ParseId(marshalUtil); idErr != nil { + err = idErr + + return + } else { + result.(*Message).id = &id + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// VerifySignature verifies the signature of the message. +func (message *Message) VerifySignature() bool { + msgBytes := message.Bytes() + signature := message.Signature() + + contentLength := len(msgBytes) - len(signature) + content := msgBytes[:contentLength] + + return message.issuerPublicKey.VerifySignature(content, signature) +} + +// ID returns the id of the message which is made up of the content id and trunk/branch ids. +// This id can be used for merkle proofs. +func (message *Message) Id() (result Id) { + message.idMutex.RLock() + + if message.id == nil { + message.idMutex.RUnlock() + + message.idMutex.Lock() + defer message.idMutex.Unlock() + if message.id != nil { + result = *message.id + return + } + result = message.calculateId() + message.id = &result + return + } + + result = *message.id + message.idMutex.RUnlock() + return +} + +// TrunkID returns the id of the trunk message. +func (message *Message) TrunkId() Id { + return message.trunkID +} + +// BranchID returns the id of the branch message. +func (message *Message) BranchId() Id { + return message.branchID +} + +// IssuerPublicKey returns the public key of the message issuer. +func (message *Message) IssuerPublicKey() ed25519.PublicKey { + return message.issuerPublicKey +} + +// IssuingTime returns the time when this message was created. +func (message *Message) IssuingTime() time.Time { + return message.issuingTime +} + +// SequenceNumber returns the sequence number of this message. +func (message *Message) SequenceNumber() uint64 { + return message.sequenceNumber +} + +// Payload returns the payload of the message. +func (message *Message) Payload() payload.Payload { + return message.payload +} + +// Payload returns the payload of the message. +func (message *Message) Nonce() uint64 { + return message.nonce +} + +// Signature returns the signature of the message. +func (message *Message) Signature() ed25519.Signature { + return message.signature +} + +// ContentId returns the content id of the message which is made up of all the +// parts of the message minus the trunk and branch ids. +func (message *Message) ContentId() (result ContentId) { + message.contentIdMutex.RLock() + if message.contentId == nil { + message.contentIdMutex.RUnlock() + + message.contentIdMutex.Lock() + defer message.contentIdMutex.Unlock() + if message.contentId != nil { + result = *message.contentId + return + } + result = message.calculateContentId() + message.contentId = &result + return + } + + result = *message.contentId + message.contentIdMutex.RUnlock() + return +} + +// calculates the message id. +func (message *Message) calculateId() Id { + return blake2b.Sum512( + marshalutil.New(IdLength + IdLength + payload.IdLength). + WriteBytes(message.trunkID.Bytes()). + WriteBytes(message.branchID.Bytes()). + WriteBytes(message.ContentId().Bytes()). + Bytes(), + ) +} + +// calculates the content id of the message. +func (message *Message) calculateContentId() ContentId { + // compute content id from the message data (except trunk and branch ids) + return blake2b.Sum512(message.Bytes()[2*IdLength:]) +} + +// Bytes returns the message in serialized byte form. +func (message *Message) Bytes() []byte { + message.bytesMutex.RLock() + if message.bytes != nil { + defer message.bytesMutex.RUnlock() + + return message.bytes + } + + message.bytesMutex.RUnlock() + message.bytesMutex.RLock() + defer message.bytesMutex.RUnlock() + + if message.bytes != nil { + return message.bytes + } + + // marshal result + marshalUtil := marshalutil.New() + marshalUtil.WriteBytes(message.trunkID.Bytes()) + marshalUtil.WriteBytes(message.branchID.Bytes()) + marshalUtil.WriteBytes(message.issuerPublicKey.Bytes()) + marshalUtil.WriteTime(message.issuingTime) + marshalUtil.WriteUint64(message.sequenceNumber) + marshalUtil.WriteBytes(message.payload.Bytes()) + marshalUtil.WriteUint64(message.nonce) + marshalUtil.WriteBytes(message.signature.Bytes()) + + message.bytes = marshalUtil.Bytes() + + return message.bytes +} + +func (message *Message) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + // initialize helper + marshalUtil := marshalutil.New(data) + + // parse information + if message.trunkID, err = ParseId(marshalUtil); err != nil { + return + } + if message.branchID, err = ParseId(marshalUtil); err != nil { + return + } + if message.issuerPublicKey, err = ed25519.ParsePublicKey(marshalUtil); err != nil { + return + } + if message.issuingTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if message.sequenceNumber, err = marshalUtil.ReadUint64(); err != nil { + return + } + if message.payload, err = payload.Parse(marshalUtil); err != nil { + return + } + if message.nonce, err = marshalUtil.ReadUint64(); err != nil { + return + } + if message.signature, err = ed25519.ParseSignature(marshalUtil); err != nil { + return + } + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + + // store marshaled version + message.bytes = make([]byte, consumedBytes) + copy(message.bytes, data) + + return +} + +func (message *Message) ObjectStorageKey() []byte { + return message.Id().Bytes() +} + +// Since messages are immutable and do not get changed after being created, we cache the result of the marshaling. +func (message *Message) ObjectStorageValue() []byte { + return message.Bytes() +} + +// Update updates the object with the values of another object. +// Since a Message is immutable, this function is not implemented and panics. +func (message *Message) Update(objectstorage.StorableObject) { + panic("messages should never be overwritten and only stored once to optimize IO") +} + +func (message *Message) String() string { + return stringify.Struct("Message", + stringify.StructField("id", message.Id()), + stringify.StructField("trunkId", message.TrunkId()), + stringify.StructField("branchId", message.BranchId()), + stringify.StructField("issuer", message.IssuerPublicKey()), + stringify.StructField("issuingTime", message.IssuingTime()), + stringify.StructField("sequenceNumber", message.SequenceNumber()), + stringify.StructField("payload", message.Payload()), + stringify.StructField("nonce", message.Nonce()), + stringify.StructField("signature", message.Signature()), + ) +} + +type CachedMessage struct { + objectstorage.CachedObject +} + +func (cachedMessage *CachedMessage) Retain() *CachedMessage { + return &CachedMessage{cachedMessage.CachedObject.Retain()} +} + +func (cachedMessage *CachedMessage) Consume(consumer func(msg *Message)) bool { + return cachedMessage.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Message)) + }) +} + +func (cachedMessage *CachedMessage) Unwrap() *Message { + if untypedMessage := cachedMessage.Get(); untypedMessage == nil { + return nil + } else { + if typeCastedMessage := untypedMessage.(*Message); typeCastedMessage == nil || typeCastedMessage.IsDeleted() { + return nil + } else { + return typeCastedMessage + } + } +} diff --git a/packages/binary/messagelayer/messagefactory/events.go b/packages/binary/messagelayer/messagefactory/events.go new file mode 100644 index 0000000000000000000000000000000000000000..873b0aca65fffed325b455f3bdb758c27f89b6ca --- /dev/null +++ b/packages/binary/messagelayer/messagefactory/events.go @@ -0,0 +1,26 @@ +package messagefactory + +import ( + "github.com/iotaledger/hive.go/events" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +// Events represents events happening on a message factory. +type Events struct { + // Fired when a message is built including tips, sequence number and other metadata. + MessageConstructed *events.Event + // Fired when an error occurred. + Error *events.Event +} + +func newEvents() *Events { + return &Events{ + MessageConstructed: events.NewEvent(messageConstructedEvent), + Error: events.NewEvent(events.ErrorCaller), + } +} + +func messageConstructedEvent(handler interface{}, params ...interface{}) { + handler.(func(*message.Message))(params[0].(*message.Message)) +} diff --git a/packages/binary/messagelayer/messagefactory/messagefactory.go b/packages/binary/messagelayer/messagefactory/messagefactory.go new file mode 100644 index 0000000000000000000000000000000000000000..4a206e2d18e66e5cd4e252a783d6fa1d89e5ba10 --- /dev/null +++ b/packages/binary/messagelayer/messagefactory/messagefactory.go @@ -0,0 +1,144 @@ +package messagefactory + +import ( + "fmt" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" + "github.com/iotaledger/hive.go/kvstore" +) + +const storeSequenceInterval = 100 + +// A TipSelector selects two tips, branch and trunk, for a new message to attach to. +type TipSelector interface { + Tips() (trunk message.Id, branch message.Id) +} + +// A Worker performs the PoW for the provided message in serialized byte form. +type Worker interface { + DoPOW([]byte) (nonce uint64, err error) +} + +// ZeroWorker is a PoW worker that always returns 0 as the nonce. +var ZeroWorker = WorkerFunc(func([]byte) (uint64, error) { return 0, nil }) + +// MessageFactory acts as a factory to create new messages. +type MessageFactory struct { + Events *Events + sequence *kvstore.Sequence + localIdentity *identity.LocalIdentity + selector TipSelector + + worker Worker + workerMutex sync.RWMutex + issuanceMutex sync.Mutex +} + +// New creates a new message factory. +func New(store kvstore.KVStore, sequenceKey []byte, localIdentity *identity.LocalIdentity, selector TipSelector) *MessageFactory { + sequence, err := kvstore.NewSequence(store, sequenceKey, storeSequenceInterval) + if err != nil { + panic(fmt.Sprintf("could not create message sequence number: %v", err)) + } + + return &MessageFactory{ + Events: newEvents(), + sequence: sequence, + localIdentity: localIdentity, + selector: selector, + worker: ZeroWorker, + } +} + +// SetWorker sets the PoW worker to be used for the messages. +func (m *MessageFactory) SetWorker(worker Worker) { + m.workerMutex.Lock() + defer m.workerMutex.Unlock() + m.worker = worker +} + +// IssuePayload creates a new message including sequence number and tip selection and returns it. +// It also triggers the MessageConstructed event once it's done, which is for example used by the plugins to listen for +// messages that shall be attached to the tangle. +func (m *MessageFactory) IssuePayload(payload payload.Payload) *message.Message { + m.issuanceMutex.Lock() + defer m.issuanceMutex.Unlock() + sequenceNumber, err := m.sequence.Next() + if err != nil { + m.Events.Error.Trigger(fmt.Errorf("could not create sequence number: %w", err)) + return nil + } + + trunkID, branchID := m.selector.Tips() + issuingTime := time.Now() + issuerPublicKey := m.localIdentity.PublicKey() + + // do the PoW + nonce, err := m.doPOW(trunkID, branchID, issuingTime, issuerPublicKey, sequenceNumber, payload) + if err != nil { + m.Events.Error.Trigger(fmt.Errorf("pow failed: %w", err)) + return nil + } + + // create the signature + signature := m.sign(trunkID, branchID, issuingTime, issuerPublicKey, sequenceNumber, payload, nonce) + + msg := message.New( + trunkID, + branchID, + issuingTime, + issuerPublicKey, + sequenceNumber, + payload, + nonce, + signature, + ) + m.Events.MessageConstructed.Trigger(msg) + return msg +} + +// Shutdown closes the messageFactory and persists the sequence number. +func (m *MessageFactory) Shutdown() { + if err := m.sequence.Release(); err != nil { + m.Events.Error.Trigger(fmt.Errorf("could not release message sequence number: %w", err)) + } +} + +func (m *MessageFactory) doPOW(trunkID message.Id, branchID message.Id, issuingTime time.Time, key ed25519.PublicKey, seq uint64, payload payload.Payload) (uint64, error) { + // create a dummy message to simplify marshaling + dummy := message.New(trunkID, branchID, issuingTime, key, seq, payload, 0, ed25519.EmptySignature).Bytes() + + m.workerMutex.RLock() + defer m.workerMutex.RUnlock() + return m.worker.DoPOW(dummy) +} + +func (m *MessageFactory) sign(trunkID message.Id, branchID message.Id, issuingTime time.Time, key ed25519.PublicKey, seq uint64, payload payload.Payload, nonce uint64) ed25519.Signature { + // create a dummy message to simplify marshaling + dummy := message.New(trunkID, branchID, issuingTime, key, seq, payload, nonce, ed25519.EmptySignature) + dummyBytes := dummy.Bytes() + + contentLength := len(dummyBytes) - len(dummy.Signature()) + return m.localIdentity.Sign(dummyBytes[:contentLength]) +} + +// The TipSelectorFunc type is an adapter to allow the use of ordinary functions as tip selectors. +type TipSelectorFunc func() (message.Id, message.Id) + +// Tips calls f(). +func (f TipSelectorFunc) Tips() (message.Id, message.Id) { + return f() +} + +// The WorkerFunc type is an adapter to allow the use of ordinary functions as a PoW performer. +type WorkerFunc func([]byte) (uint64, error) + +// DoPOW calls f(msg). +func (f WorkerFunc) DoPOW(msg []byte) (uint64, error) { + return f(msg) +} diff --git a/packages/binary/messagelayer/messagefactory/messagefactory_test.go b/packages/binary/messagelayer/messagefactory/messagefactory_test.go new file mode 100644 index 0000000000000000000000000000000000000000..ad909fcf1d235f4b960f7bbd1f1708459d2e243d --- /dev/null +++ b/packages/binary/messagelayer/messagefactory/messagefactory_test.go @@ -0,0 +1,135 @@ +package messagefactory + +import ( + "context" + "crypto" + "crypto/ed25519" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/packages/pow" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/identity" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/stretchr/testify/assert" + _ "golang.org/x/crypto/blake2b" +) + +const ( + sequenceKey = "seq" + targetPOW = 10 + totalMessages = 2000 +) + +func TestMessageFactory_BuildMessage(t *testing.T) { + msgFactory := New( + mapdb.NewMapDB(), + []byte(sequenceKey), + identity.GenerateLocalIdentity(), + TipSelectorFunc(func() (message.Id, message.Id) { return message.EmptyId, message.EmptyId }), + ) + defer msgFactory.Shutdown() + + // keep track of sequence numbers + sequenceNumbers := sync.Map{} + + // attach to event and count + countEvents := uint64(0) + msgFactory.Events.MessageConstructed.Attach(events.NewClosure(func(msg *message.Message) { + atomic.AddUint64(&countEvents, 1) + })) + + t.Run("CheckProperties", func(t *testing.T) { + p := payload.NewData([]byte("TestCheckProperties")) + msg := msgFactory.IssuePayload(p) + + assert.NotNil(t, msg.TrunkId()) + assert.NotNil(t, msg.BranchId()) + + // time in range of 0.1 seconds + assert.InDelta(t, time.Now().UnixNano(), msg.IssuingTime().UnixNano(), 100000000) + + // check payload + assert.Equal(t, p, msg.Payload()) + + // check total events and sequence number + assert.EqualValues(t, 1, countEvents) + assert.EqualValues(t, 0, msg.SequenceNumber()) + + sequenceNumbers.Store(msg.SequenceNumber(), true) + }) + + // create messages in parallel + t.Run("ParallelCreation", func(t *testing.T) { + for i := 1; i < totalMessages; i++ { + t.Run("test", func(t *testing.T) { + t.Parallel() + + p := payload.NewData([]byte("TestParallelCreation")) + msg := msgFactory.IssuePayload(p) + + assert.NotNil(t, msg.TrunkId()) + assert.NotNil(t, msg.BranchId()) + + // time in range of 0.1 seconds + assert.InDelta(t, time.Now().UnixNano(), msg.IssuingTime().UnixNano(), 100000000) + + // check payload + assert.Equal(t, p, msg.Payload()) + + sequenceNumbers.Store(msg.SequenceNumber(), true) + }) + } + }) + + // check total events and sequence number + assert.EqualValues(t, totalMessages, countEvents) + + max := uint64(0) + countSequence := 0 + sequenceNumbers.Range(func(key, value interface{}) bool { + seq := key.(uint64) + val := value.(bool) + if val != true { + return false + } + + // check for max sequence number + if seq > max { + max = seq + } + countSequence++ + return true + }) + assert.EqualValues(t, totalMessages-1, max) + assert.EqualValues(t, totalMessages, countSequence) +} + +func TestMessageFactory_POW(t *testing.T) { + msgFactory := New( + mapdb.NewMapDB(), + []byte(sequenceKey), + identity.GenerateLocalIdentity(), + TipSelectorFunc(func() (message.Id, message.Id) { return message.EmptyId, message.EmptyId }), + ) + defer msgFactory.Shutdown() + + worker := pow.New(crypto.BLAKE2b_512, 1) + + msgFactory.SetWorker(WorkerFunc(func(msgBytes []byte) (uint64, error) { + content := msgBytes[:len(msgBytes)-ed25519.SignatureSize-8] + return worker.Mine(context.Background(), content, targetPOW) + })) + + msg := msgFactory.IssuePayload(payload.NewData([]byte("test"))) + msgBytes := msg.Bytes() + content := msgBytes[:len(msgBytes)-ed25519.SignatureSize-8] + + zeroes, err := worker.LeadingZerosWithNonce(content, msg.Nonce()) + assert.GreaterOrEqual(t, zeroes, targetPOW) + assert.NoError(t, err) +} diff --git a/packages/binary/messagelayer/messageparser/builtinfilters/message_signature_filter.go b/packages/binary/messagelayer/messageparser/builtinfilters/message_signature_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..a7195d61e1d026f49be76cc1833cb4ca930c5028 --- /dev/null +++ b/packages/binary/messagelayer/messageparser/builtinfilters/message_signature_filter.go @@ -0,0 +1,69 @@ +package builtinfilters + +import ( + "fmt" + "sync" + + "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/autopeering/peer" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +// ErrInvalidSignature is returned when a message contains an invalid signature. +var ErrInvalidSignature = fmt.Errorf("invalid signature") + +// MessageSignatureFilter filters messages based on whether their signatures are valid. +type MessageSignatureFilter struct { + onAcceptCallback func(msg *message.Message, peer *peer.Peer) + onRejectCallback func(msg *message.Message, err error, peer *peer.Peer) + workerPool async.WorkerPool + + onAcceptCallbackMutex sync.RWMutex + onRejectCallbackMutex sync.RWMutex +} + +// NewMessageSignatureFilter creates a new message signature filter. +func NewMessageSignatureFilter() *MessageSignatureFilter { + return &MessageSignatureFilter{} +} + +func (filter *MessageSignatureFilter) Filter(msg *message.Message, peer *peer.Peer) { + filter.workerPool.Submit(func() { + if msg.VerifySignature() { + filter.getAcceptCallback()(msg, peer) + return + } + filter.getRejectCallback()(msg, ErrInvalidSignature, peer) + }) +} + +func (filter *MessageSignatureFilter) OnAccept(callback func(msg *message.Message, peer *peer.Peer)) { + filter.onAcceptCallbackMutex.Lock() + filter.onAcceptCallback = callback + filter.onAcceptCallbackMutex.Unlock() +} + +func (filter *MessageSignatureFilter) OnReject(callback func(msg *message.Message, err error, peer *peer.Peer)) { + filter.onRejectCallbackMutex.Lock() + filter.onRejectCallback = callback + filter.onRejectCallbackMutex.Unlock() +} + +func (filter *MessageSignatureFilter) Shutdown() { + filter.workerPool.ShutdownGracefully() +} + +func (filter *MessageSignatureFilter) getAcceptCallback() (result func(msg *message.Message, peer *peer.Peer)) { + filter.onAcceptCallbackMutex.RLock() + result = filter.onAcceptCallback + filter.onAcceptCallbackMutex.RUnlock() + return +} + +func (filter *MessageSignatureFilter) getRejectCallback() (result func(msg *message.Message, err error, peer *peer.Peer)) { + filter.onRejectCallbackMutex.RLock() + result = filter.onRejectCallback + filter.onRejectCallbackMutex.RUnlock() + return +} diff --git a/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter.go b/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..38f708cb4cbe22ffc51d8c0d63774025071f3617 --- /dev/null +++ b/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter.go @@ -0,0 +1,108 @@ +package builtinfilters + +import ( + "crypto/ed25519" + "errors" + "fmt" + "sync" + + "github.com/iotaledger/goshimmer/packages/pow" + "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/autopeering/peer" +) + +var ( + // ErrInvalidPOWDifficultly is returned when the nonce of a message does not fulfill the PoW difficulty. + ErrInvalidPOWDifficultly = errors.New("invalid PoW") + // ErrMessageTooSmall is returned when the message does not contain enough data for the PoW. + ErrMessageTooSmall = errors.New("message too small") +) + +// PowFilter is a message bytes filter validating the PoW nonce. +type PowFilter struct { + worker *pow.Worker + difficulty int + workerPool async.WorkerPool + + mu sync.Mutex + acceptCallback func([]byte, *peer.Peer) + rejectCallback func([]byte, error, *peer.Peer) +} + +// NewPowFilter creates a new PoW bytes filter. +func NewPowFilter(worker *pow.Worker, difficulty int) *PowFilter { + return &PowFilter{ + worker: worker, + difficulty: difficulty, + } +} + +// Filter checks whether the given bytes pass the PoW validation and calls the corresponding callback. +func (f *PowFilter) Filter(msgBytes []byte, p *peer.Peer) { + f.workerPool.Submit(func() { + if err := f.validate(msgBytes); err != nil { + f.reject(msgBytes, err, p) + return + } + f.accept(msgBytes, p) + }) +} + +// OnAccept registers the given callback as the acceptance function of the filter. +func (f *PowFilter) OnAccept(callback func([]byte, *peer.Peer)) { + f.mu.Lock() + defer f.mu.Unlock() + f.acceptCallback = callback +} + +// OnReject registers the given callback as the rejection function of the filter. +func (f *PowFilter) OnReject(callback func([]byte, error, *peer.Peer)) { + f.mu.Lock() + defer f.mu.Unlock() + f.rejectCallback = callback +} + +// Shutdown shuts down the filter. +func (f *PowFilter) Shutdown() { + f.workerPool.ShutdownGracefully() +} + +func (f *PowFilter) accept(msgBytes []byte, p *peer.Peer) { + f.mu.Lock() + defer f.mu.Unlock() + if f.acceptCallback != nil { + f.acceptCallback(msgBytes, p) + } +} + +func (f *PowFilter) reject(msgBytes []byte, err error, p *peer.Peer) { + f.mu.Lock() + defer f.mu.Unlock() + if f.rejectCallback != nil { + f.rejectCallback(msgBytes, err, p) + } +} + +func (f *PowFilter) validate(msgBytes []byte) error { + content, err := powData(msgBytes) + if err != nil { + return err + } + zeros, err := f.worker.LeadingZeros(content) + if err != nil { + return err + } + if zeros < f.difficulty { + return fmt.Errorf("%w: leading zeros %d for difficulty %d", ErrInvalidPOWDifficultly, zeros, f.difficulty) + } + return nil +} + +// powData returns the bytes over which PoW should be computed. +func powData(msgBytes []byte) ([]byte, error) { + contentLength := len(msgBytes) - ed25519.SignatureSize + if contentLength < pow.NonceBytes { + return nil, ErrMessageTooSmall + } + return msgBytes[:contentLength], nil +} diff --git a/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter_test.go b/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter_test.go new file mode 100644 index 0000000000000000000000000000000000000000..fe53a9d71cb715dec6a9ad5e26fc87365a680493 --- /dev/null +++ b/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter_test.go @@ -0,0 +1,75 @@ +package builtinfilters + +import ( + "context" + "crypto" + "errors" + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/packages/pow" + "github.com/iotaledger/hive.go/autopeering/peer" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + _ "golang.org/x/crypto/blake2b" // required by crypto.BLAKE2b_512 +) + +var ( + testPayload = payload.NewData([]byte("test")) + testPeer *peer.Peer = nil + testWorker = pow.New(crypto.BLAKE2b_512, 1) + testDifficulty = 10 +) + +func TestPowFilter_Filter(t *testing.T) { + filter := NewPowFilter(testWorker, testDifficulty) + defer filter.Shutdown() + + // set callbacks + m := &callbackMock{} + filter.OnAccept(m.Accept) + filter.OnReject(m.Reject) + + t.Run("reject small message", func(t *testing.T) { + m.On("Reject", mock.Anything, mock.MatchedBy(func(err error) bool { return errors.Is(err, ErrMessageTooSmall) }), testPeer) + filter.Filter(nil, testPeer) + }) + + msg := newTestMessage(0) + msgBytes := msg.Bytes() + + t.Run("reject invalid nonce", func(t *testing.T) { + m.On("Reject", msgBytes, mock.MatchedBy(func(err error) bool { return errors.Is(err, ErrInvalidPOWDifficultly) }), testPeer) + filter.Filter(msgBytes, testPeer) + }) + + nonce, err := testWorker.Mine(context.Background(), msgBytes[:len(msgBytes)-len(msg.Signature())-pow.NonceBytes], testDifficulty) + require.NoError(t, err) + + msgPOW := newTestMessage(nonce) + msgPOWBytes := msgPOW.Bytes() + + t.Run("accept valid nonce", func(t *testing.T) { + zeroes, err := testWorker.LeadingZeros(msgPOWBytes[:len(msgPOWBytes)-len(msgPOW.Signature())]) + require.NoError(t, err) + require.GreaterOrEqual(t, zeroes, testDifficulty) + + m.On("Accept", msgPOWBytes, testPeer) + filter.Filter(msgPOWBytes, testPeer) + }) + + filter.Shutdown() + m.AssertExpectations(t) +} + +type callbackMock struct{ mock.Mock } + +func (m *callbackMock) Accept(msg []byte, p *peer.Peer) { m.Called(msg, p) } +func (m *callbackMock) Reject(msg []byte, err error, p *peer.Peer) { m.Called(msg, err, p) } + +func newTestMessage(nonce uint64) *message.Message { + return message.New(message.EmptyId, message.EmptyId, time.Time{}, ed25519.PublicKey{}, 0, testPayload, nonce, ed25519.Signature{}) +} diff --git a/packages/binary/tangle/transactionparser/builtinfilters/recently_seen_bytes_filter.go b/packages/binary/messagelayer/messageparser/builtinfilters/recently_seen_bytes_filter.go similarity index 57% rename from packages/binary/tangle/transactionparser/builtinfilters/recently_seen_bytes_filter.go rename to packages/binary/messagelayer/messageparser/builtinfilters/recently_seen_bytes_filter.go index c0a6002f0cdadf0290cbab19057bba3f6c3536d4..45b3bfee8ba4b3e3bd6d428c896fecd7241646df 100644 --- a/packages/binary/tangle/transactionparser/builtinfilters/recently_seen_bytes_filter.go +++ b/packages/binary/messagelayer/messageparser/builtinfilters/recently_seen_bytes_filter.go @@ -1,65 +1,68 @@ package builtinfilters import ( + "fmt" "sync" "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/bytesfilter" ) +// ErrReceivedDuplicateBytes is returned when duplicated bytes are rejected. +var ErrReceivedDuplicateBytes = fmt.Errorf("received duplicate bytes") + +// RecentlySeenBytesFilter filters so that bytes which were recently seen don't pass the filter. type RecentlySeenBytesFilter struct { bytesFilter *bytesfilter.BytesFilter - onAcceptCallback func(bytes []byte) - onRejectCallback func(bytes []byte) + onAcceptCallback func(bytes []byte, peer *peer.Peer) + onRejectCallback func(bytes []byte, err error, peer *peer.Peer) workerPool async.WorkerPool onAcceptCallbackMutex sync.RWMutex onRejectCallbackMutex sync.RWMutex } -func NewRecentlySeenBytesFilter() (result *RecentlySeenBytesFilter) { - result = &RecentlySeenBytesFilter{ +// NewRecentlySeenBytesFilter creates a new recently seen bytes filter. +func NewRecentlySeenBytesFilter() *RecentlySeenBytesFilter { + return &RecentlySeenBytesFilter{ bytesFilter: bytesfilter.New(100000), } - - return } -func (filter *RecentlySeenBytesFilter) Filter(bytes []byte) { +func (filter *RecentlySeenBytesFilter) Filter(bytes []byte, peer *peer.Peer) { filter.workerPool.Submit(func() { if filter.bytesFilter.Add(bytes) { - filter.getAcceptCallback()(bytes) - } else { - filter.getRejectCallback()(bytes) + filter.getAcceptCallback()(bytes, peer) + return } + filter.getRejectCallback()(bytes, ErrReceivedDuplicateBytes, peer) }) } -func (filter *RecentlySeenBytesFilter) OnAccept(callback func(bytes []byte)) { +func (filter *RecentlySeenBytesFilter) OnAccept(callback func(bytes []byte, peer *peer.Peer)) { filter.onAcceptCallbackMutex.Lock() filter.onAcceptCallback = callback filter.onAcceptCallbackMutex.Unlock() } -func (filter *RecentlySeenBytesFilter) OnReject(callback func(bytes []byte)) { +func (filter *RecentlySeenBytesFilter) OnReject(callback func(bytes []byte, err error, peer *peer.Peer)) { filter.onRejectCallbackMutex.Lock() filter.onRejectCallback = callback filter.onRejectCallbackMutex.Unlock() } -func (filter *RecentlySeenBytesFilter) getAcceptCallback() (result func(bytes []byte)) { +func (filter *RecentlySeenBytesFilter) getAcceptCallback() (result func(bytes []byte, peer *peer.Peer)) { filter.onAcceptCallbackMutex.Lock() result = filter.onAcceptCallback filter.onAcceptCallbackMutex.Unlock() - return } -func (filter *RecentlySeenBytesFilter) getRejectCallback() (result func(bytes []byte)) { +func (filter *RecentlySeenBytesFilter) getRejectCallback() (result func(bytes []byte, err error, peer *peer.Peer)) { filter.onRejectCallbackMutex.Lock() result = filter.onRejectCallback filter.onRejectCallbackMutex.Unlock() - return } diff --git a/packages/binary/messagelayer/messageparser/bytes_filter.go b/packages/binary/messagelayer/messageparser/bytes_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..96d928e582ee330dfc732c002b4119c561e6f19b --- /dev/null +++ b/packages/binary/messagelayer/messageparser/bytes_filter.go @@ -0,0 +1,18 @@ +package messageparser + +import ( + "github.com/iotaledger/hive.go/autopeering/peer" +) + +// BytesFilter filters based on byte slices and peers. +type BytesFilter interface { + // Filter filters up on the given bytes and peer and calls the acceptance callback + // if the input passes or the rejection callback if the input is rejected. + Filter(bytes []byte, peer *peer.Peer) + // OnAccept registers the given callback as the acceptance function of the filter. + OnAccept(callback func(bytes []byte, peer *peer.Peer)) + // OnReject registers the given callback as the rejection function of the filter. + OnReject(callback func(bytes []byte, err error, peer *peer.Peer)) + // Shutdown shuts down the filter. + Shutdown() +} diff --git a/packages/binary/messagelayer/messageparser/events.go b/packages/binary/messagelayer/messageparser/events.go new file mode 100644 index 0000000000000000000000000000000000000000..d02a52d85a376ac09e2986e4bba3fcb57847e57b --- /dev/null +++ b/packages/binary/messagelayer/messageparser/events.go @@ -0,0 +1,13 @@ +package messageparser + +import "github.com/iotaledger/hive.go/events" + +// Events represents events happening on a message parser. +type Events struct { + // Fired when a message was parsed. + MessageParsed *events.Event + // Fired when submitted bytes are rejected by a filter. + BytesRejected *events.Event + // Fired when a message got rejected by a filter. + MessageRejected *events.Event +} diff --git a/packages/binary/messagelayer/messageparser/message_filter.go b/packages/binary/messagelayer/messageparser/message_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..f303a5b6ffc3833391377f69dc8b37224ceefeda --- /dev/null +++ b/packages/binary/messagelayer/messageparser/message_filter.go @@ -0,0 +1,20 @@ +package messageparser + +import ( + "github.com/iotaledger/hive.go/autopeering/peer" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +// MessageFilter filters based on messages and peers. +type MessageFilter interface { + // Filter filters up on the given message and peer and calls the acceptance callback + // if the input passes or the rejection callback if the input is rejected. + Filter(msg *message.Message, peer *peer.Peer) + // OnAccept registers the given callback as the acceptance function of the filter. + OnAccept(callback func(msg *message.Message, peer *peer.Peer)) + // OnAccept registers the given callback as the rejection function of the filter. + OnReject(callback func(msg *message.Message, err error, peer *peer.Peer)) + // Shutdown shuts down the filter. + Shutdown() +} diff --git a/packages/binary/messagelayer/messageparser/message_parser.go b/packages/binary/messagelayer/messageparser/message_parser.go new file mode 100644 index 0000000000000000000000000000000000000000..8e491be4949927c1eb26e1bb05b1a6632b740108 --- /dev/null +++ b/packages/binary/messagelayer/messageparser/message_parser.go @@ -0,0 +1,147 @@ +package messageparser + +import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser/builtinfilters" + + "github.com/iotaledger/hive.go/autopeering/peer" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/typeutils" +) + +// MessageParser parses messages and bytes and emits corresponding events for parsed and rejected messages. +type MessageParser struct { + bytesFilters []BytesFilter + messageFilters []MessageFilter + Events Events + + byteFiltersModified typeutils.AtomicBool + messageFiltersModified typeutils.AtomicBool + bytesFiltersMutex sync.Mutex + messageFiltersMutex sync.Mutex +} + +// New creates a new message parser. +func New() (result *MessageParser) { + result = &MessageParser{ + bytesFilters: make([]BytesFilter, 0), + messageFilters: make([]MessageFilter, 0), + Events: Events{ + MessageParsed: events.NewEvent(func(handler interface{}, params ...interface{}) { + handler.(func(*message.Message, *peer.Peer))(params[0].(*message.Message), params[1].(*peer.Peer)) + }), + BytesRejected: events.NewEvent(func(handler interface{}, params ...interface{}) { + handler.(func([]byte, error, *peer.Peer))(params[0].([]byte), params[1].(error), params[2].(*peer.Peer)) + }), + MessageRejected: events.NewEvent(func(handler interface{}, params ...interface{}) { + handler.(func(*message.Message, error, *peer.Peer))(params[0].(*message.Message), params[1].(error), params[2].(*peer.Peer)) + }), + }, + } + + // add builtin filters + result.AddBytesFilter(builtinfilters.NewRecentlySeenBytesFilter()) + result.AddMessageFilter(builtinfilters.NewMessageSignatureFilter()) + return +} + +// Parse parses the given message bytes. +func (messageParser *MessageParser) Parse(messageBytes []byte, peer *peer.Peer) { + messageParser.setupBytesFilterDataFlow() + messageParser.setupMessageFilterDataFlow() + messageParser.bytesFilters[0].Filter(messageBytes, peer) +} + +// AddBytesFilter adds the given bytes filter to the parser. +func (messageParser *MessageParser) AddBytesFilter(filter BytesFilter) { + messageParser.bytesFiltersMutex.Lock() + messageParser.bytesFilters = append(messageParser.bytesFilters, filter) + messageParser.bytesFiltersMutex.Unlock() + messageParser.byteFiltersModified.Set() +} + +// AddMessageFilter adds a new message filter to the parser. +func (messageParser *MessageParser) AddMessageFilter(filter MessageFilter) { + messageParser.messageFiltersMutex.Lock() + messageParser.messageFilters = append(messageParser.messageFilters, filter) + messageParser.messageFiltersMutex.Unlock() + messageParser.messageFiltersModified.Set() +} + +// Shutdown shut downs the message parser and its corresponding registered filters. +func (messageParser *MessageParser) Shutdown() { + messageParser.bytesFiltersMutex.Lock() + for _, bytesFilter := range messageParser.bytesFilters { + bytesFilter.Shutdown() + } + messageParser.bytesFiltersMutex.Unlock() + + messageParser.messageFiltersMutex.Lock() + for _, messageFilter := range messageParser.messageFilters { + messageFilter.Shutdown() + } + messageParser.messageFiltersMutex.Unlock() +} + +// sets up the byte filter data flow chain. +func (messageParser *MessageParser) setupBytesFilterDataFlow() { + if !messageParser.byteFiltersModified.IsSet() { + return + } + + messageParser.bytesFiltersMutex.Lock() + if messageParser.byteFiltersModified.IsSet() { + messageParser.byteFiltersModified.SetTo(false) + + numberOfBytesFilters := len(messageParser.bytesFilters) + for i := 0; i < numberOfBytesFilters; i++ { + if i == numberOfBytesFilters-1 { + messageParser.bytesFilters[i].OnAccept(messageParser.parseMessage) + } else { + messageParser.bytesFilters[i].OnAccept(messageParser.bytesFilters[i+1].Filter) + } + messageParser.bytesFilters[i].OnReject(func(bytes []byte, err error, peer *peer.Peer) { + messageParser.Events.BytesRejected.Trigger(bytes, err, peer) + }) + } + } + messageParser.bytesFiltersMutex.Unlock() +} + +// sets up the message filter data flow chain. +func (messageParser *MessageParser) setupMessageFilterDataFlow() { + if !messageParser.messageFiltersModified.IsSet() { + return + } + + messageParser.messageFiltersMutex.Lock() + if messageParser.messageFiltersModified.IsSet() { + messageParser.messageFiltersModified.SetTo(false) + + numberOfMessageFilters := len(messageParser.messageFilters) + for i := 0; i < numberOfMessageFilters; i++ { + if i == numberOfMessageFilters-1 { + messageParser.messageFilters[i].OnAccept(func(msg *message.Message, peer *peer.Peer) { + messageParser.Events.MessageParsed.Trigger(msg, peer) + }) + } else { + messageParser.messageFilters[i].OnAccept(messageParser.messageFilters[i+1].Filter) + } + messageParser.messageFilters[i].OnReject(func(msg *message.Message, err error, peer *peer.Peer) { + messageParser.Events.MessageRejected.Trigger(msg, err, peer) + }) + } + } + messageParser.messageFiltersMutex.Unlock() +} + +// parses the given message and emits +func (messageParser *MessageParser) parseMessage(bytes []byte, peer *peer.Peer) { + if parsedMessage, err, _ := message.FromBytes(bytes); err != nil { + messageParser.Events.BytesRejected.Trigger(bytes, err, peer) + } else { + messageParser.messageFilters[0].Filter(parsedMessage, peer) + } +} diff --git a/packages/binary/messagelayer/messageparser/message_parser_test.go b/packages/binary/messagelayer/messageparser/message_parser_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2e33aad3d231fb15852b182fbdbe7453891052b4 --- /dev/null +++ b/packages/binary/messagelayer/messageparser/message_parser_test.go @@ -0,0 +1,61 @@ +package messageparser + +import ( + "strconv" + "testing" + "time" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/events" + "github.com/labstack/gommon/log" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +func BenchmarkMessageParser_ParseBytesSame(b *testing.B) { + msgBytes := newTestMessage("Test").Bytes() + msgParser := New() + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + msgParser.Parse(msgBytes, nil) + } + + msgParser.Shutdown() +} + +func BenchmarkMessageParser_ParseBytesDifferent(b *testing.B) { + messageBytes := make([][]byte, b.N) + for i := 0; i < b.N; i++ { + messageBytes[i] = newTestMessage("Test" + strconv.Itoa(i)).Bytes() + } + + msgParser := New() + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + msgParser.Parse(messageBytes[i], nil) + } + + msgParser.Shutdown() +} + +func TestMessageParser_ParseMessage(t *testing.T) { + msg := newTestMessage("Test") + + msgParser := New() + msgParser.Parse(msg.Bytes(), nil) + + msgParser.Events.MessageParsed.Attach(events.NewClosure(func(msg *message.Message) { + log.Infof("parsed message") + })) + + msgParser.Shutdown() +} + +func newTestMessage(payloadString string) *message.Message { + return message.New(message.EmptyId, message.EmptyId, time.Now(), ed25519.PublicKey{}, 0, payload.NewData([]byte(payloadString)), 0, ed25519.Signature{}) +} diff --git a/packages/binary/messagelayer/messagerequester/constants.go b/packages/binary/messagelayer/messagerequester/constants.go new file mode 100644 index 0000000000000000000000000000000000000000..7d26d3e96bb5eaa2d23c4b413bfdac4bc47800cf --- /dev/null +++ b/packages/binary/messagelayer/messagerequester/constants.go @@ -0,0 +1,10 @@ +package messagerequester + +import ( + "time" +) + +const ( + // DefaultRetryInterval defines the Default Retry Interval of the message requester. + DefaultRetryInterval = 10 * time.Second +) diff --git a/packages/binary/messagelayer/messagerequester/events.go b/packages/binary/messagelayer/messagerequester/events.go new file mode 100644 index 0000000000000000000000000000000000000000..77e9ed89c73805d7686a9431ac7a78e813b5fa2e --- /dev/null +++ b/packages/binary/messagelayer/messagerequester/events.go @@ -0,0 +1,11 @@ +package messagerequester + +import ( + "github.com/iotaledger/hive.go/events" +) + +// Events represents events happening on a message requester. +type Events struct { + // Fired when a request for a given message should be sent. + SendRequest *events.Event +} diff --git a/packages/binary/messagelayer/messagerequester/messagerequester.go b/packages/binary/messagelayer/messagerequester/messagerequester.go new file mode 100644 index 0000000000000000000000000000000000000000..5018520849e4a3a1b7beb0ff15626101e569059a --- /dev/null +++ b/packages/binary/messagelayer/messagerequester/messagerequester.go @@ -0,0 +1,81 @@ +package messagerequester + +import ( + "runtime" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/events" +) + +var ( + // DefaultRequestWorkerCount defines the Default Request Worker Count of the message requester. + DefaultRequestWorkerCount = runtime.GOMAXPROCS(0) +) + +// MessageRequester takes care of requesting messages. +type MessageRequester struct { + scheduledRequests map[message.Id]*time.Timer + requestWorker async.NonBlockingWorkerPool + options *Options + Events Events + + scheduledRequestsMutex sync.RWMutex +} + +// New creates a new message requester. +func New(optionalOptions ...Option) *MessageRequester { + requester := &MessageRequester{ + scheduledRequests: make(map[message.Id]*time.Timer), + options: newOptions(optionalOptions), + Events: Events{ + SendRequest: events.NewEvent(func(handler interface{}, params ...interface{}) { + handler.(func(message.Id))(params[0].(message.Id)) + }), + }, + } + + requester.requestWorker.Tune(requester.options.workerCount) + return requester +} + +// ScheduleRequest schedules a request for the given message. +func (requester *MessageRequester) ScheduleRequest(messageId message.Id) { + var retryRequest func(bool) + retryRequest = func(initialRequest bool) { + requester.requestWorker.Submit(func() { + requester.scheduledRequestsMutex.RLock() + if _, requestExists := requester.scheduledRequests[messageId]; !initialRequest && !requestExists { + requester.scheduledRequestsMutex.RUnlock() + return + } + requester.scheduledRequestsMutex.RUnlock() + + requester.Events.SendRequest.Trigger(messageId) + + requester.scheduledRequestsMutex.Lock() + requester.scheduledRequests[messageId] = time.AfterFunc(requester.options.retryInterval, func() { retryRequest(false) }) + requester.scheduledRequestsMutex.Unlock() + }) + } + + retryRequest(true) +} + +// StopRequest stops requests for the given message to further happen. +func (requester *MessageRequester) StopRequest(messageId message.Id) { + requester.scheduledRequestsMutex.RLock() + if timer, timerExists := requester.scheduledRequests[messageId]; timerExists { + requester.scheduledRequestsMutex.RUnlock() + + timer.Stop() + + requester.scheduledRequestsMutex.Lock() + delete(requester.scheduledRequests, messageId) + requester.scheduledRequestsMutex.Unlock() + return + } + requester.scheduledRequestsMutex.RUnlock() +} diff --git a/packages/binary/tangle/transactionrequester/options.go b/packages/binary/messagelayer/messagerequester/options.go similarity index 62% rename from packages/binary/tangle/transactionrequester/options.go rename to packages/binary/messagelayer/messagerequester/options.go index 05db5db4c3c00448dbc6b6ccc805f109d9194ba0..a3b3a0cb6c79a17e36e1726423124ede19e9c025 100644 --- a/packages/binary/tangle/transactionrequester/options.go +++ b/packages/binary/messagelayer/messagerequester/options.go @@ -1,9 +1,10 @@ -package transactionrequester +package messagerequester import ( "time" ) +// Options holds options for a message requester. type Options struct { retryInterval time.Duration workerCount int @@ -12,7 +13,7 @@ type Options struct { func newOptions(optionalOptions []Option) *Options { result := &Options{ retryInterval: 10 * time.Second, - workerCount: DEFAULT_REQUEST_WORKER_COUNT, + workerCount: DefaultRequestWorkerCount, } for _, optionalOption := range optionalOptions { @@ -22,14 +23,17 @@ func newOptions(optionalOptions []Option) *Options { return result } +// Option is a function which inits an option. type Option func(*Options) +// RetryInterval creates an option which sets the retry interval to the given value. func RetryInterval(interval time.Duration) Option { return func(args *Options) { args.retryInterval = interval } } +// WorkerCount creates an option which sets the worker count to the given value. func WorkerCount(workerCount int) Option { return func(args *Options) { args.workerCount = workerCount diff --git a/packages/binary/messagelayer/payload/data.go b/packages/binary/messagelayer/payload/data.go new file mode 100644 index 0000000000000000000000000000000000000000..6092956c7f1a7d42f5c6c7b274924d2c68b72038 --- /dev/null +++ b/packages/binary/messagelayer/payload/data.go @@ -0,0 +1,109 @@ +package payload + +import ( + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/stringify" +) + +// DataType is the message type of a data payload. +var DataType = Type(0) + +// Data represents a payload which just contains a blob of data. +type Data struct { + payloadType Type + data []byte +} + +// MaxDataPayloadSize defines the maximum size of a data payload. +const MaxDataPayloadSize = 64 * 1024 + +// NewData creates new data payload. +func NewData(data []byte) *Data { + return &Data{ + payloadType: DataType, + data: data, + } +} + +// DataFromBytes creates a new data payload from the given bytes. +func DataFromBytes(bytes []byte, optionalTargetObject ...*Data) (result *Data, err error, consumedBytes int) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseData(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ParseData parses a new data payload out of the given marshal util. +func ParseData(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Data) (result *Data, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Data{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to ParseData") + } + + // parse information + result.payloadType, err = marshalUtil.ReadUint32() + if err != nil { + return + } + payloadBytes, err := marshalUtil.ReadUint32() + if err != nil { + return + } + result.data, err = marshalUtil.ReadBytes(int(payloadBytes)) + if err != nil { + return + } + + return +} + +func (dataPayload *Data) Type() Type { + return dataPayload.payloadType +} + +// Data returns the data of the data payload. +func (dataPayload *Data) Data() []byte { + return dataPayload.data +} + +// Bytes marshals the data payload into a sequence of bytes. +func (dataPayload *Data) Bytes() []byte { + // initialize helper + marshalUtil := marshalutil.New() + + // marshal the payload specific information + marshalUtil.WriteUint32(dataPayload.Type()) + marshalUtil.WriteUint32(uint32(len(dataPayload.data))) + marshalUtil.WriteBytes(dataPayload.data[:]) + + // return result + return marshalUtil.Bytes() +} + +func (dataPayload *Data) Unmarshal(data []byte) (err error) { + _, err, _ = DataFromBytes(data, dataPayload) + + return +} + +func (dataPayload *Data) String() string { + return stringify.Struct("Data", + stringify.StructField("type", int(dataPayload.Type())), + stringify.StructField("data", string(dataPayload.Data())), + ) +} + +// GenericPayloadUnmarshalerFactory is an unmarshaler for the generic data payload type. +func GenericPayloadUnmarshalerFactory(payloadType Type) Unmarshaler { + return func(data []byte) (payload Payload, err error) { + payload = &Data{payloadType: payloadType} + err = payload.Unmarshal(data) + return + } +} diff --git a/packages/binary/messagelayer/payload/id.go b/packages/binary/messagelayer/payload/id.go new file mode 100644 index 0000000000000000000000000000000000000000..1320572d1822cd2cd1af25f7628f22519b6ad5e8 --- /dev/null +++ b/packages/binary/messagelayer/payload/id.go @@ -0,0 +1,19 @@ +package payload + +import "github.com/mr-tron/base58" + +// ID represents the id of a data payload. +type Id [IdLength]byte + +// Bytes returns the id as a byte slice backed by the original array, +// therefore it should not be modified. +func (id Id) Bytes() []byte { + return id[:] +} + +func (id Id) String() string { + return base58.Encode(id[:]) +} + +// IdLength is the length of a data payload id. +const IdLength = 64 diff --git a/packages/binary/messagelayer/payload/payload.go b/packages/binary/messagelayer/payload/payload.go new file mode 100644 index 0000000000000000000000000000000000000000..a0282c323f6617809ffcfd0cd652a26f742375fb --- /dev/null +++ b/packages/binary/messagelayer/payload/payload.go @@ -0,0 +1,90 @@ +package payload + +import ( + "errors" + "fmt" + + "github.com/iotaledger/hive.go/marshalutil" +) + +var ( + // ErrMaximumPayloadSizeExceeded is returned if the payload exceeds the maximum size. + ErrMaximumPayloadSizeExceeded = errors.New("maximum payload size exceeded") +) + +const ( + // ObjectName defines the name of the data object. + ObjectName = "data" +) + +func init() { + // register the generic unmarshaler + SetGenericUnmarshalerFactory(GenericPayloadUnmarshalerFactory) + // register the generic data payload type + RegisterType(DataType, ObjectName, GenericPayloadUnmarshalerFactory(DataType)) +} + +// Payload represents some kind of payload of data which only gains meaning by having +// corresponding node logic processing payloads of a given type. +type Payload interface { + // Type returns the type of the payload. + Type() Type + // Bytes returns the payload bytes. + Bytes() []byte + // Unmarshal unmarshals the payload from the given bytes. + Unmarshal(bytes []byte) error + // String returns a human-friendly representation of the payload. + String() string +} + +// FromBytes unmarshals bytes into a payload. +func FromBytes(bytes []byte) (result Payload, consumedBytes int, err error) { + // initialize helper + marshalUtil := marshalutil.New(bytes) + + // calculate result + payloadType, err := marshalUtil.ReadUint32() + if err != nil { + return + } + + payloadSize, err := marshalUtil.ReadUint32() + if err != nil { + return + } + + if payloadSize > MaxDataPayloadSize { + err = fmt.Errorf("%w: %d", ErrMaximumPayloadSizeExceeded, MaxDataPayloadSize) + return + } + + marshalUtil.ReadSeek(marshalUtil.ReadOffset() - marshalutil.UINT32_SIZE*2) + payloadBytes, err := marshalUtil.ReadBytes(int(payloadSize) + 8) + if err != nil { + return + } + + readOffset := marshalUtil.ReadOffset() + result, err = GetUnmarshaler(payloadType)(payloadBytes) + if err != nil { + // fallback to the generic unmarshaler if registered type fails to unmarshal + marshalUtil.ReadSeek(readOffset) + result, err = GenericPayloadUnmarshalerFactory(payloadType)(payloadBytes) + if err != nil { + return + } + } + + // return the number of bytes we processed + consumedBytes = marshalUtil.ReadOffset() + return +} + +// Parse parses a payload by using the given marshal util. +func Parse(marshalUtil *marshalutil.MarshalUtil) (Payload, error) { + if payload, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) }); err != nil { + return nil, err + } else { + return payload.(Payload), nil + } +} diff --git a/packages/binary/messagelayer/payload/type.go b/packages/binary/messagelayer/payload/type.go new file mode 100644 index 0000000000000000000000000000000000000000..4f2241bd0200994057b80240baf53d7373e3068e --- /dev/null +++ b/packages/binary/messagelayer/payload/type.go @@ -0,0 +1,4 @@ +package payload + +// Type represents the type id of a payload. +type Type = uint32 diff --git a/packages/binary/messagelayer/payload/type_register.go b/packages/binary/messagelayer/payload/type_register.go new file mode 100644 index 0000000000000000000000000000000000000000..eb22e51eca3eeb6d2f5e3342be35de3edb33d9bf --- /dev/null +++ b/packages/binary/messagelayer/payload/type_register.go @@ -0,0 +1,56 @@ +package payload + +import ( + "sync" +) + +// Unmarshaler takes some data and unmarshals it into a payload. +type Unmarshaler func(data []byte) (Payload, error) + +// Definition defines the properties of a payload type. +type Definition struct { + Name string + Unmarshaler +} + +var ( + typeRegister = make(map[Type]Definition) + typeRegisterMutex sync.RWMutex + genericUnmarshalerFactory func(payloadType Type) Unmarshaler +) + +// RegisterType registers a payload type with the given unmarshaler. +func RegisterType(payloadType Type, payloadName string, unmarshaler Unmarshaler) { + typeRegisterMutex.Lock() + typeRegister[payloadType] = Definition{ + Name: payloadName, + Unmarshaler: unmarshaler, + } + typeRegisterMutex.Unlock() +} + +// GetUnmarshaler returns the unmarshaler for the given type if known or +// the generic unmarshaler if the given payload type has no associated unmarshaler. +func GetUnmarshaler(payloadType Type) Unmarshaler { + typeRegisterMutex.RLock() + defer typeRegisterMutex.RUnlock() + if definition, exists := typeRegister[payloadType]; exists { + return definition.Unmarshaler + } + return genericUnmarshalerFactory(payloadType) +} + +// SetGenericUnmarshalerFactory sets the generic unmarshaler. +func SetGenericUnmarshalerFactory(unmarshalerFactory func(payloadType Type) Unmarshaler) { + genericUnmarshalerFactory = unmarshalerFactory +} + +// Name returns the name of a given payload type. +func Name(payloadType Type) string { + typeRegisterMutex.RLock() + defer typeRegisterMutex.RUnlock() + if definition, exists := typeRegister[payloadType]; exists { + return definition.Name + } + return ObjectName +} diff --git a/packages/binary/messagelayer/tangle/approver.go b/packages/binary/messagelayer/tangle/approver.go new file mode 100644 index 0000000000000000000000000000000000000000..5526a104b2bb2a39595c2ddff22665164fd984b3 --- /dev/null +++ b/packages/binary/messagelayer/tangle/approver.go @@ -0,0 +1,160 @@ +package tangle + +import ( + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + "github.com/iotaledger/hive.go/stringify" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +// Approver is an approver of a given referenced message. +type Approver struct { + objectstorage.StorableObjectFlags + // the message which got referenced by the approver message. + referencedMessageId message.Id + // the message which approved/referenced the given referenced message. + approverMessageId message.Id +} + +// NewApprover creates a new approver relation to the given approved/referenced message. +func NewApprover(referencedMessageId message.Id, approverMessageId message.Id) *Approver { + approver := &Approver{ + referencedMessageId: referencedMessageId, + approverMessageId: approverMessageId, + } + return approver +} + +// ApproverFromBytes parses the given bytes into an approver. +func ApproverFromBytes(bytes []byte, optionalTargetObject ...*Approver) (result *Approver, err error, consumedBytes int) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseApprover(marshalUtil, optionalTargetObject...) + consumedBytes = marshalUtil.ReadOffset() + return +} + +// ParseApprover parses a new approver from the given marshal util. +func ParseApprover(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Approver) (result *Approver, err error) { + if parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return ApproverFromStorageKey(data, optionalTargetObject...) + }); parseErr != nil { + err = parseErr + return + } else { + result = parsedObject.(*Approver) + } + + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +// ApproverFromStorageKey returns an approver for the given key. +func ApproverFromStorageKey(key []byte, optionalTargetObject ...*Approver) (result objectstorage.StorableObject, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &Approver{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to ApproverFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + if result.(*Approver).referencedMessageId, err = message.ParseId(marshalUtil); err != nil { + return + } + if result.(*Approver).approverMessageId, err = message.ParseId(marshalUtil); err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// ReferencedMessageId returns the id of the message which is referenced by the approver. +func (approver *Approver) ReferencedMessageId() message.Id { + return approver.referencedMessageId +} + +// ApproverMessageId returns the id of the message which referenced the given approved message. +func (approver *Approver) ApproverMessageId() message.Id { + return approver.approverMessageId +} + +func (approver *Approver) Bytes() []byte { + return approver.ObjectStorageKey() +} + +func (approver *Approver) String() string { + return stringify.Struct("Approver", + stringify.StructField("referencedMessageId", approver.ReferencedMessageId()), + stringify.StructField("approverMessageId", approver.ApproverMessageId()), + ) +} + +func (approver *Approver) ObjectStorageKey() []byte { + return marshalutil.New(). + WriteBytes(approver.referencedMessageId.Bytes()). + WriteBytes(approver.approverMessageId.Bytes()). + Bytes() +} + +func (approver *Approver) ObjectStorageValue() (result []byte) { + return +} + +func (approver *Approver) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + return +} + +func (approver *Approver) Update(other objectstorage.StorableObject) { + panic("approvers should never be overwritten and only stored once to optimize IO") +} + +// interface contract (allow the compiler to check if the implementation has all of the required methods). +var _ objectstorage.StorableObject = &Approver{} + +type CachedApprover struct { + objectstorage.CachedObject +} + +func (cachedApprover *CachedApprover) Unwrap() *Approver { + untypedObject := cachedApprover.Get() + if untypedObject == nil { + return nil + } + + typedObject := untypedObject.(*Approver) + if typedObject == nil || typedObject.IsDeleted() { + return nil + } + + return typedObject + +} + +func (cachedApprover *CachedApprover) Consume(consumer func(approver *Approver)) (consumed bool) { + return cachedApprover.CachedObject.Consume(func(object objectstorage.StorableObject) { + consumer(object.(*Approver)) + }) +} + +type CachedApprovers []*CachedApprover + +func (cachedApprovers CachedApprovers) Consume(consumer func(approver *Approver)) (consumed bool) { + for _, cachedApprover := range cachedApprovers { + consumed = cachedApprover.Consume(func(approver *Approver) { + consumer(approver) + }) || consumed + } + + return +} diff --git a/packages/binary/messagelayer/tangle/events.go b/packages/binary/messagelayer/tangle/events.go new file mode 100644 index 0000000000000000000000000000000000000000..399d28002aa5ecec6336a9ec20b2efa1fd911770 --- /dev/null +++ b/packages/binary/messagelayer/tangle/events.go @@ -0,0 +1,47 @@ +package tangle + +import ( + "github.com/iotaledger/hive.go/events" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +// Events represents events happening on the base layer Tangle. +type Events struct { + // Fired when a message has been attached. + MessageAttached *events.Event + // Fired when a message has been solid, i.e. its past cone + // is known and in the database. + MessageSolid *events.Event + // Fired when a message which was previously marked as missing was received. + MissingMessageReceived *events.Event + // Fired when a message is missing which is needed to solidify a given approver message. + MessageMissing *events.Event + // Fired when a message was missing for too long and is + // therefore considered to be unsolidifiable. + MessageUnsolidifiable *events.Event + // Fired when a message was removed from storage. + MessageRemoved *events.Event +} + +func newEvents() *Events { + return &Events{ + MessageAttached: events.NewEvent(cachedMessageEvent), + MessageSolid: events.NewEvent(cachedMessageEvent), + MissingMessageReceived: events.NewEvent(cachedMessageEvent), + MessageMissing: events.NewEvent(messageIdEvent), + MessageUnsolidifiable: events.NewEvent(messageIdEvent), + MessageRemoved: events.NewEvent(messageIdEvent), + } +} + +func messageIdEvent(handler interface{}, params ...interface{}) { + handler.(func(message.Id))(params[0].(message.Id)) +} + +func cachedMessageEvent(handler interface{}, params ...interface{}) { + handler.(func(*message.CachedMessage, *CachedMessageMetadata))( + params[0].(*message.CachedMessage).Retain(), + params[1].(*CachedMessageMetadata).Retain(), + ) +} diff --git a/packages/binary/messagelayer/tangle/messagemetadata.go b/packages/binary/messagelayer/tangle/messagemetadata.go new file mode 100644 index 0000000000000000000000000000000000000000..e1abe276b1179fb296fa08136797191cb131ae70 --- /dev/null +++ b/packages/binary/messagelayer/tangle/messagemetadata.go @@ -0,0 +1,170 @@ +package tangle + +import ( + "sync" + "time" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +type MessageMetadata struct { + objectstorage.StorableObjectFlags + + messageId message.Id + receivedTime time.Time + solid bool + solidificationTime time.Time + + solidMutex sync.RWMutex + solidificationTimeMutex sync.RWMutex +} + +func NewMessageMetadata(messageId message.Id) *MessageMetadata { + return &MessageMetadata{ + messageId: messageId, + receivedTime: time.Now(), + } +} + +func MessageMetadataFromBytes(bytes []byte) (result *MessageMetadata, err error, consumedBytes int) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseMessageMetadata(marshalUtil) + consumedBytes = marshalUtil.ReadOffset() + + return +} + +func ParseMessageMetadata(marshalUtil *marshalutil.MarshalUtil) (result *MessageMetadata, err error) { + if parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { + return MessageMetadataFromStorageKey(data) + }); parseErr != nil { + err = parseErr + + return + } else { + result = parsedObject.(*MessageMetadata) + } + + _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { + parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + + return + }) + + return +} + +func MessageMetadataFromStorageKey(key []byte) (result objectstorage.StorableObject, consumedBytes int, err error) { + result = &MessageMetadata{} + + marshalUtil := marshalutil.New(key) + result.(*MessageMetadata).messageId, err = message.ParseId(marshalUtil) + if err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +func (messageMetadata *MessageMetadata) IsSolid() (result bool) { + messageMetadata.solidMutex.RLock() + result = messageMetadata.solid + messageMetadata.solidMutex.RUnlock() + + return +} + +func (messageMetadata *MessageMetadata) SetSolid(solid bool) (modified bool) { + messageMetadata.solidMutex.RLock() + if messageMetadata.solid != solid { + messageMetadata.solidMutex.RUnlock() + + messageMetadata.solidMutex.Lock() + if messageMetadata.solid != solid { + messageMetadata.solid = solid + if solid { + messageMetadata.solidificationTimeMutex.Lock() + messageMetadata.solidificationTime = time.Now() + messageMetadata.solidificationTimeMutex.Unlock() + } + + messageMetadata.SetModified() + + modified = true + } + messageMetadata.solidMutex.Unlock() + + } else { + messageMetadata.solidMutex.RUnlock() + } + + return +} + +// SolidificationTime returns the time when the message was marked to be solid. +func (messageMetadata *MessageMetadata) SolidificationTime() time.Time { + messageMetadata.solidificationTimeMutex.RLock() + defer messageMetadata.solidificationTimeMutex.RUnlock() + + return messageMetadata.solidificationTime +} + +func (messageMetadata *MessageMetadata) ObjectStorageKey() []byte { + return messageMetadata.messageId.Bytes() +} + +func (messageMetadata *MessageMetadata) ObjectStorageValue() []byte { + return marshalutil.New(). + WriteTime(messageMetadata.receivedTime). + WriteTime(messageMetadata.SolidificationTime()). + WriteBool(messageMetadata.IsSolid()). + Bytes() +} + +func (messageMetadata *MessageMetadata) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + + if messageMetadata.receivedTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if messageMetadata.solidificationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if messageMetadata.solid, err = marshalUtil.ReadBool(); err != nil { + return + } + + consumedBytes = marshalUtil.ReadOffset() + + return +} + +func (messageMetadata *MessageMetadata) Update(other objectstorage.StorableObject) { + panic("updates disabled") +} + +var _ objectstorage.StorableObject = &MessageMetadata{} + +type CachedMessageMetadata struct { + objectstorage.CachedObject +} + +func (cachedMessageMetadata *CachedMessageMetadata) Retain() *CachedMessageMetadata { + return &CachedMessageMetadata{cachedMessageMetadata.CachedObject.Retain()} +} + +func (cachedMessageMetadata *CachedMessageMetadata) Unwrap() *MessageMetadata { + if untypedObject := cachedMessageMetadata.Get(); untypedObject == nil { + return nil + } else { + if typedObject := untypedObject.(*MessageMetadata); typedObject == nil || typedObject.IsDeleted() { + return nil + } else { + return typedObject + } + } +} diff --git a/packages/binary/messagelayer/tangle/missingmessage.go b/packages/binary/messagelayer/tangle/missingmessage.go new file mode 100644 index 0000000000000000000000000000000000000000..1fb9e4b2f01532c77a40b9963c5d0e27502b9861 --- /dev/null +++ b/packages/binary/messagelayer/tangle/missingmessage.go @@ -0,0 +1,84 @@ +package tangle + +import ( + "time" + + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/objectstorage" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +type MissingMessage struct { + objectstorage.StorableObjectFlags + + messageId message.Id + missingSince time.Time +} + +func NewMissingMessage(messageId message.Id) *MissingMessage { + return &MissingMessage{ + messageId: messageId, + missingSince: time.Now(), + } +} + +func MissingMessageFromStorageKey(key []byte, optionalTargetObject ...*MissingMessage) (result objectstorage.StorableObject, consumedBytes int, err error) { + // determine the target object that will hold the unmarshaled information + switch len(optionalTargetObject) { + case 0: + result = &MissingMessage{} + case 1: + result = optionalTargetObject[0] + default: + panic("too many arguments in call to MissingMessageFromStorageKey") + } + + // parse the properties that are stored in the key + marshalUtil := marshalutil.New(key) + result.(*MissingMessage).messageId, err = message.ParseId(marshalUtil) + if err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} + +// MessageId returns the id of the message. +func (missingMessage *MissingMessage) MessageId() message.Id { + return missingMessage.messageId +} + +// MissingSince returns the time since when this message is missing. +func (missingMessage *MissingMessage) MissingSince() time.Time { + return missingMessage.missingSince +} + +func (missingMessage *MissingMessage) Update(other objectstorage.StorableObject) { + panic("missing messages should never be overwritten and only stored once to optimize IO") +} + +func (missingMessage *MissingMessage) ObjectStorageKey() []byte { + return missingMessage.messageId[:] +} + +func (missingMessage *MissingMessage) ObjectStorageValue() (result []byte) { + result, err := missingMessage.missingSince.MarshalBinary() + if err != nil { + panic(err) + } + + return +} + +func (missingMessage *MissingMessage) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { + marshalUtil := marshalutil.New(data) + missingMessage.missingSince, err = marshalUtil.ReadTime() + if err != nil { + return + } + consumedBytes = marshalUtil.ReadOffset() + + return +} diff --git a/packages/binary/messagelayer/tangle/storageprefixes.go b/packages/binary/messagelayer/tangle/storageprefixes.go new file mode 100644 index 0000000000000000000000000000000000000000..24a31eea08c886d9f649b490c1fa77e444896447 --- /dev/null +++ b/packages/binary/messagelayer/tangle/storageprefixes.go @@ -0,0 +1,8 @@ +package tangle + +const ( + PrefixMessage byte = iota + PrefixMessageMetadata + PrefixApprovers + PrefixMissingMessage +) diff --git a/packages/binary/messagelayer/tangle/tangle.go b/packages/binary/messagelayer/tangle/tangle.go new file mode 100644 index 0000000000000000000000000000000000000000..240935094518e00300173b0535636634ecb3cb82 --- /dev/null +++ b/packages/binary/messagelayer/tangle/tangle.go @@ -0,0 +1,342 @@ +package tangle + +import ( + "container/list" + "runtime" + "time" + + "github.com/iotaledger/hive.go/kvstore" + "github.com/iotaledger/hive.go/types" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/storageprefix" + + "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/objectstorage" +) + +const ( + // MaxMissingTimeBeforeCleanup is the max. amount of time a message can be marked as missing + // before it is ultimately un-marked as missing. + MaxMissingTimeBeforeCleanup = 30 * time.Second + // MissingCheckInterval is the interval on which it is checked whether a missing + // message is still missing. + MissingCheckInterval = 5 * time.Second + + cacheTime = 20 * time.Second +) + +// Tangle represents the base layer of messages. +type Tangle struct { + messageStorage *objectstorage.ObjectStorage + messageMetadataStorage *objectstorage.ObjectStorage + approverStorage *objectstorage.ObjectStorage + missingMessageStorage *objectstorage.ObjectStorage + + Events Events + + storeMessageWorkerPool async.WorkerPool + solidifierWorkerPool async.WorkerPool + shutdown chan struct{} +} + +func messageFactory(key []byte) (objectstorage.StorableObject, int, error) { + return message.StorableObjectFromKey(key) +} + +func approverFactory(key []byte) (objectstorage.StorableObject, int, error) { + return ApproverFromStorageKey(key) +} + +func missingMessageFactory(key []byte) (objectstorage.StorableObject, int, error) { + return MissingMessageFromStorageKey(key) +} + +// New creates a new Tangle. +func New(store kvstore.KVStore) (result *Tangle) { + osFactory := objectstorage.NewFactory(store, storageprefix.MessageLayer) + + result = &Tangle{ + shutdown: make(chan struct{}), + messageStorage: osFactory.New(PrefixMessage, messageFactory, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), + messageMetadataStorage: osFactory.New(PrefixMessageMetadata, MessageMetadataFromStorageKey, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), + approverStorage: osFactory.New(PrefixApprovers, approverFactory, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(message.IdLength, message.IdLength), objectstorage.LeakDetectionEnabled(false)), + missingMessageStorage: osFactory.New(PrefixMissingMessage, missingMessageFactory, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), + + Events: *newEvents(), + } + + result.solidifierWorkerPool.Tune(runtime.GOMAXPROCS(0)) + return +} + +// AttachMessage attaches a new message to the tangle. +func (tangle *Tangle) AttachMessage(msg *message.Message) { + tangle.storeMessageWorkerPool.Submit(func() { tangle.storeMessageWorker(msg) }) +} + +// Message retrieves a message from the tangle. +func (tangle *Tangle) Message(messageId message.Id) *message.CachedMessage { + return &message.CachedMessage{CachedObject: tangle.messageStorage.Load(messageId[:])} +} + +// MessageMetadata retrieves the metadata of a message from the tangle. +func (tangle *Tangle) MessageMetadata(messageId message.Id) *CachedMessageMetadata { + return &CachedMessageMetadata{CachedObject: tangle.messageMetadataStorage.Load(messageId[:])} +} + +// Approvers retrieves the approvers of a message from the tangle. +func (tangle *Tangle) Approvers(messageId message.Id) CachedApprovers { + approvers := make(CachedApprovers, 0) + tangle.approverStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + approvers = append(approvers, &CachedApprover{CachedObject: cachedObject}) + return true + }, messageId[:]) + return approvers +} + +// DeleteMessage deletes a message and its association to approvees by un-marking the given +// message as an approver. +func (tangle *Tangle) DeleteMessage(messageId message.Id) { + tangle.Message(messageId).Consume(func(currentMsg *message.Message) { + trunkMsgId := currentMsg.TrunkId() + tangle.deleteApprover(trunkMsgId, messageId) + + branchMsgId := currentMsg.BranchId() + if branchMsgId != trunkMsgId { + tangle.deleteApprover(branchMsgId, messageId) + } + + tangle.messageMetadataStorage.Delete(messageId[:]) + tangle.messageStorage.Delete(messageId[:]) + + tangle.Events.MessageRemoved.Trigger(messageId) + }) +} + +// Shutdown marks the tangle as stopped, so it will not accept any new messages (waits for all backgroundTasks to finish). +func (tangle *Tangle) Shutdown() *Tangle { + tangle.storeMessageWorkerPool.ShutdownGracefully() + tangle.solidifierWorkerPool.ShutdownGracefully() + + tangle.messageStorage.Shutdown() + tangle.messageMetadataStorage.Shutdown() + tangle.approverStorage.Shutdown() + tangle.missingMessageStorage.Shutdown() + close(tangle.shutdown) + + return tangle +} + +// Prune resets the database and deletes all objects (good for testing or "node resets"). +func (tangle *Tangle) Prune() error { + for _, storage := range []*objectstorage.ObjectStorage{ + tangle.messageStorage, + tangle.messageMetadataStorage, + tangle.approverStorage, + tangle.missingMessageStorage, + } { + if err := storage.Prune(); err != nil { + return err + } + } + + return nil +} + +// worker that stores the message and calls the corresponding storage events. +func (tangle *Tangle) storeMessageWorker(msg *message.Message) { + // store message + var cachedMessage *message.CachedMessage + _tmp, msgIsNew := tangle.messageStorage.StoreIfAbsent(msg) + if !msgIsNew { + return + } + cachedMessage = &message.CachedMessage{CachedObject: _tmp} + + // store message metadata + messageId := msg.Id() + cachedMsgMetadata := &CachedMessageMetadata{CachedObject: tangle.messageMetadataStorage.Store(NewMessageMetadata(messageId))} + + // store trunk approver + trunkMsgId := msg.TrunkId() + tangle.approverStorage.Store(NewApprover(trunkMsgId, messageId)).Release() + + // store branch approver + if branchMsgId := msg.BranchId(); branchMsgId != trunkMsgId { + tangle.approverStorage.Store(NewApprover(branchMsgId, messageId)).Release() + } + + // trigger events + if tangle.missingMessageStorage.DeleteIfPresent(messageId[:]) { + tangle.Events.MissingMessageReceived.Trigger(cachedMessage, cachedMsgMetadata) + } + tangle.Events.MessageAttached.Trigger(cachedMessage, cachedMsgMetadata) + + // check message solidity + tangle.solidifierWorkerPool.Submit(func() { + tangle.checkMessageSolidityAndPropagate(cachedMessage, cachedMsgMetadata) + }) +} + +// checks whether the given message is solid and marks it as missing if it isn't known. +func (tangle *Tangle) isMessageMarkedAsSolid(messageId message.Id) bool { + if messageId == message.EmptyId { + return true + } + + msgMetadataCached := tangle.MessageMetadata(messageId) + defer msgMetadataCached.Release() + msgMetadata := msgMetadataCached.Unwrap() + + // mark message as missing + if msgMetadata == nil { + missingMessage := NewMissingMessage(messageId) + if cachedMissingMessage, stored := tangle.missingMessageStorage.StoreIfAbsent(missingMessage); stored { + cachedMissingMessage.Consume(func(object objectstorage.StorableObject) { + tangle.Events.MessageMissing.Trigger(messageId) + }) + } + return false + } + + return msgMetadata.IsSolid() +} + +// checks whether the given message is solid by examining whether its trunk and +// branch messages are solid. +func (tangle *Tangle) isMessageSolid(msg *message.Message, msgMetadata *MessageMetadata) bool { + if msg == nil || msg.IsDeleted() { + return false + } + + if msgMetadata == nil || msgMetadata.IsDeleted() { + return false + } + + if msgMetadata.IsSolid() { + return true + } + + return tangle.isMessageMarkedAsSolid(msg.TrunkId()) && tangle.isMessageMarkedAsSolid(msg.BranchId()) +} + +// builds up a stack from the given message and tries to solidify into the present. +// missing messages which are needed for a message to become solid are marked as missing. +func (tangle *Tangle) checkMessageSolidityAndPropagate(cachedMessage *message.CachedMessage, cachedMsgMetadata *CachedMessageMetadata) { + + popElementsFromStack := func(stack *list.List) (*message.CachedMessage, *CachedMessageMetadata) { + currentSolidificationEntry := stack.Front() + currentCachedMsg := currentSolidificationEntry.Value.([2]interface{})[0] + currentCachedMsgMetadata := currentSolidificationEntry.Value.([2]interface{})[1] + stack.Remove(currentSolidificationEntry) + return currentCachedMsg.(*message.CachedMessage), currentCachedMsgMetadata.(*CachedMessageMetadata) + } + + // initialize the stack + solidificationStack := list.New() + solidificationStack.PushBack([2]interface{}{cachedMessage, cachedMsgMetadata}) + + // processed messages that are supposed to be checked for solidity recursively + for solidificationStack.Len() > 0 { + currentCachedMessage, currentCachedMsgMetadata := popElementsFromStack(solidificationStack) + + currentMessage := currentCachedMessage.Unwrap() + currentMsgMetadata := currentCachedMsgMetadata.Unwrap() + if currentMessage == nil || currentMsgMetadata == nil { + currentCachedMessage.Release() + currentCachedMsgMetadata.Release() + continue + } + + // mark the message as solid if it has become solid + if tangle.isMessageSolid(currentMessage, currentMsgMetadata) && currentMsgMetadata.SetSolid(true) { + tangle.Events.MessageSolid.Trigger(currentCachedMessage, currentCachedMsgMetadata) + + // auto. push approvers of the newly solid message to propagate solidification + tangle.Approvers(currentMessage.Id()).Consume(func(approver *Approver) { + approverMessageId := approver.ApproverMessageId() + solidificationStack.PushBack([2]interface{}{ + tangle.Message(approverMessageId), + tangle.MessageMetadata(approverMessageId), + }) + }) + } + + currentCachedMessage.Release() + currentCachedMsgMetadata.Release() + } +} + +// MonitorMissingMessages continuously monitors for missing messages and eventually deletes them if they +// don't become available in a certain time frame. +func (tangle *Tangle) MonitorMissingMessages(shutdownSignal <-chan struct{}) { + reCheckInterval := time.NewTicker(MissingCheckInterval) + defer reCheckInterval.Stop() + for { + select { + case <-reCheckInterval.C: + var toDelete []message.Id + var toUnmark []message.Id + tangle.missingMessageStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { + defer cachedObject.Release() + missingMessage := cachedObject.Get().(*MissingMessage) + + if tangle.messageStorage.Contains(missingMessage.messageId.Bytes()) { + toUnmark = append(toUnmark, missingMessage.MessageId()) + return true + } + + // check whether message is missing since over our max time delta + if time.Since(missingMessage.MissingSince()) >= MaxMissingTimeBeforeCleanup { + toDelete = append(toDelete, missingMessage.MessageId()) + } + return true + }) + for _, msgID := range toUnmark { + tangle.missingMessageStorage.DeleteIfPresent(msgID.Bytes()) + } + for _, msgID := range toDelete { + // delete the future cone of the missing message + tangle.Events.MessageUnsolidifiable.Trigger(msgID) + // TODO: obvious race condition between receiving the message and it getting deleted here + tangle.deleteFutureCone(msgID) + } + case <-shutdownSignal: + return + } + } +} + +// deletes the given approver association for the given approvee to its approver. +func (tangle *Tangle) deleteApprover(approvedMessageId message.Id, approvingMessage message.Id) { + idToDelete := make([]byte, message.IdLength+message.IdLength) + copy(idToDelete[:message.IdLength], approvedMessageId[:]) + copy(idToDelete[message.IdLength:], approvingMessage[:]) + tangle.approverStorage.Delete(idToDelete) +} + +// deletes a message and its future cone of messages/approvers. +func (tangle *Tangle) deleteFutureCone(messageId message.Id) { + cleanupStack := list.New() + cleanupStack.PushBack(messageId) + + processedMessages := make(map[message.Id]types.Empty) + processedMessages[messageId] = types.Void + + for cleanupStack.Len() >= 1 { + currentStackEntry := cleanupStack.Front() + currentMessageId := currentStackEntry.Value.(message.Id) + cleanupStack.Remove(currentStackEntry) + + tangle.DeleteMessage(currentMessageId) + + tangle.Approvers(currentMessageId).Consume(func(approver *Approver) { + approverId := approver.ApproverMessageId() + if _, messageProcessed := processedMessages[approverId]; !messageProcessed { + cleanupStack.PushBack(approverId) + processedMessages[approverId] = types.Void + } + }) + } +} diff --git a/packages/binary/messagelayer/tangle/tangle_test.go b/packages/binary/messagelayer/tangle/tangle_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f0baac00765c9f5d564c879e98faf8ebcebfd848 --- /dev/null +++ b/packages/binary/messagelayer/tangle/tangle_test.go @@ -0,0 +1,88 @@ +package tangle + +import ( + "fmt" + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/kvstore/mapdb" +) + +func BenchmarkTangle_AttachMessage(b *testing.B) { + tangle := New(mapdb.NewMapDB()) + if err := tangle.Prune(); err != nil { + b.Error(err) + + return + } + + messageBytes := make([]*message.Message, b.N) + for i := 0; i < b.N; i++ { + messageBytes[i] = newTestMessage("some data") + messageBytes[i].Bytes() + } + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + tangle.AttachMessage(messageBytes[i]) + } + + tangle.Shutdown() +} + +func TestTangle_AttachMessage(t *testing.T) { + messageTangle := New(mapdb.NewMapDB()) + if err := messageTangle.Prune(); err != nil { + t.Error(err) + + return + } + + messageTangle.Events.MessageAttached.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *CachedMessageMetadata) { + cachedMessageMetadata.Release() + + cachedMessage.Consume(func(msg *message.Message) { + fmt.Println("ATTACHED:", msg.Id()) + }) + })) + + messageTangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *CachedMessageMetadata) { + cachedMessageMetadata.Release() + + cachedMessage.Consume(func(msg *message.Message) { + fmt.Println("SOLID:", msg.Id()) + }) + })) + + messageTangle.Events.MessageUnsolidifiable.Attach(events.NewClosure(func(messageId message.Id) { + fmt.Println("UNSOLIDIFIABLE:", messageId) + })) + + messageTangle.Events.MessageMissing.Attach(events.NewClosure(func(messageId message.Id) { + fmt.Println("MISSING:", messageId) + })) + + messageTangle.Events.MessageRemoved.Attach(events.NewClosure(func(messageId message.Id) { + fmt.Println("REMOVED:", messageId) + })) + + newMessageOne := newTestMessage("some data") + newMessageTwo := newTestMessage("some other data") + + messageTangle.AttachMessage(newMessageTwo) + + time.Sleep(7 * time.Second) + + messageTangle.AttachMessage(newMessageOne) + + messageTangle.Shutdown() +} + +func newTestMessage(payloadString string) *message.Message { + return message.New(message.EmptyId, message.EmptyId, time.Now(), ed25519.PublicKey{}, 0, payload.NewData([]byte(payloadString)), 0, ed25519.Signature{}) +} diff --git a/packages/binary/messagelayer/test/data_payload_test.go b/packages/binary/messagelayer/test/data_payload_test.go new file mode 100644 index 0000000000000000000000000000000000000000..03d30b2782b7ce6ead30ca4295070f6c0d63e182 --- /dev/null +++ b/packages/binary/messagelayer/test/data_payload_test.go @@ -0,0 +1,74 @@ +package test + +import ( + "runtime" + "sync" + "testing" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/async" + "github.com/iotaledger/hive.go/identity" + "github.com/iotaledger/hive.go/kvstore/mapdb" + + "github.com/panjf2000/ants/v2" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +func BenchmarkVerifyDataMessages(b *testing.B) { + var pool async.WorkerPool + pool.Tune(runtime.GOMAXPROCS(0)) + + factory := messagefactory.New(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), messagefactory.TipSelectorFunc(func() (message.Id, message.Id) { return message.EmptyId, message.EmptyId })) + + messages := make([][]byte, b.N) + for i := 0; i < b.N; i++ { + messages[i] = factory.IssuePayload(payload.NewData([]byte("some data"))).Bytes() + } + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + currentIndex := i + pool.Submit(func() { + if msg, err, _ := message.FromBytes(messages[currentIndex]); err != nil { + b.Error(err) + } else { + msg.VerifySignature() + } + }) + } + + pool.Shutdown() +} + +func BenchmarkVerifySignature(b *testing.B) { + pool, _ := ants.NewPool(80, ants.WithNonblocking(false)) + + factory := messagefactory.New(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), messagefactory.TipSelectorFunc(func() (message.Id, message.Id) { return message.EmptyId, message.EmptyId })) + + messages := make([]*message.Message, b.N) + for i := 0; i < b.N; i++ { + messages[i] = factory.IssuePayload(payload.NewData([]byte("test"))) + messages[i].Bytes() + } + b.ResetTimer() + + var wg sync.WaitGroup + for i := 0; i < b.N; i++ { + wg.Add(1) + + currentIndex := i + if err := pool.Submit(func() { + messages[currentIndex].VerifySignature() + wg.Done() + }); err != nil { + b.Error(err) + return + } + } + + wg.Wait() +} diff --git a/packages/binary/messagelayer/test/message_test.go b/packages/binary/messagelayer/test/message_test.go new file mode 100644 index 0000000000000000000000000000000000000000..fa5ed95d3df8710f6ee136a67cf52ec5ba34479c --- /dev/null +++ b/packages/binary/messagelayer/test/message_test.go @@ -0,0 +1,69 @@ +package test + +import ( + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tipselector" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" + "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +func TestMessage_StorableObjectFromKey(t *testing.T) { + key, err := message.NewId("2DYebCqnZ8PS5PyXBEvAvLB1fCF77Rn9RtofNHjEb2pSTujKi889d31FmguAs5DgL7YURw4GP2Y28JdJ7K4bjudG") + if err != nil { + panic(err) + } + + messageFromKey, consumedBytes, err := message.StorableObjectFromKey(key.Bytes()) + if err != nil { + panic(err) + } + + assert.Equal(t, message.IdLength, consumedBytes) + assert.Equal(t, key, messageFromKey.(*message.Message).Id()) +} + +func TestMessage_VerifySignature(t *testing.T) { + keyPair := ed25519.GenerateKeyPair() + pl := payload.NewData([]byte("test")) + + unsigned := message.New(message.EmptyId, message.EmptyId, time.Time{}, keyPair.PublicKey, 0, pl, 0, ed25519.Signature{}) + assert.False(t, unsigned.VerifySignature()) + + unsignedBytes := unsigned.Bytes() + signature := keyPair.PrivateKey.Sign(unsignedBytes[:len(unsignedBytes)-ed25519.SignatureSize]) + + signed := message.New(message.EmptyId, message.EmptyId, time.Time{}, keyPair.PublicKey, 0, pl, 0, signature) + assert.True(t, signed.VerifySignature()) +} + +func TestMessage_MarshalUnmarshal(t *testing.T) { + msgFactory := messagefactory.New(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), tipselector.New()) + defer msgFactory.Shutdown() + + testMessage := msgFactory.IssuePayload(payload.NewData([]byte("test"))) + assert.Equal(t, true, testMessage.VerifySignature()) + + t.Log(testMessage) + + restoredMessage, err, _ := message.FromBytes(testMessage.Bytes()) + if assert.NoError(t, err, err) { + assert.Equal(t, testMessage.Id(), restoredMessage.Id()) + assert.Equal(t, testMessage.TrunkId(), restoredMessage.TrunkId()) + assert.Equal(t, testMessage.BranchId(), restoredMessage.BranchId()) + assert.Equal(t, testMessage.IssuerPublicKey(), restoredMessage.IssuerPublicKey()) + assert.Equal(t, testMessage.IssuingTime().Round(time.Second), restoredMessage.IssuingTime().Round(time.Second)) + assert.Equal(t, testMessage.SequenceNumber(), restoredMessage.SequenceNumber()) + assert.Equal(t, testMessage.Nonce(), restoredMessage.Nonce()) + assert.Equal(t, testMessage.Signature(), restoredMessage.Signature()) + assert.Equal(t, true, restoredMessage.VerifySignature()) + } +} diff --git a/packages/binary/messagelayer/tipselector/events.go b/packages/binary/messagelayer/tipselector/events.go new file mode 100644 index 0000000000000000000000000000000000000000..2e39a68d1d5dd6206f4bdef35bb7eabbcb32bc3c --- /dev/null +++ b/packages/binary/messagelayer/tipselector/events.go @@ -0,0 +1,19 @@ +package tipselector + +import ( + "github.com/iotaledger/hive.go/events" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +// Events represents event happening on the tip-selector. +type Events struct { + // Fired when a tip is added. + TipAdded *events.Event + // Fired when a tip is removed. + TipRemoved *events.Event +} + +func messageIdEvent(handler interface{}, params ...interface{}) { + handler.(func(message.Id))(params[0].(message.Id)) +} diff --git a/packages/binary/messagelayer/tipselector/tipselector.go b/packages/binary/messagelayer/tipselector/tipselector.go new file mode 100644 index 0000000000000000000000000000000000000000..2828b637a1ea7b9e33f8b825f6b13a73157de1c0 --- /dev/null +++ b/packages/binary/messagelayer/tipselector/tipselector.go @@ -0,0 +1,73 @@ +package tipselector + +import ( + "github.com/iotaledger/hive.go/events" + + "github.com/iotaledger/goshimmer/packages/binary/datastructure" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" +) + +// TipSelector manages a map of tips and emits events for their removal and addition. +type TipSelector struct { + tips *datastructure.RandomMap + Events Events +} + +// New creates a new tip-selector. +func New() *TipSelector { + return &TipSelector{ + tips: datastructure.NewRandomMap(), + Events: Events{ + TipAdded: events.NewEvent(messageIdEvent), + TipRemoved: events.NewEvent(messageIdEvent), + }, + } +} + +// AddTip adds the given message as a tip. +func (tipSelector *TipSelector) AddTip(msg *message.Message) { + messageId := msg.Id() + if tipSelector.tips.Set(messageId, messageId) { + tipSelector.Events.TipAdded.Trigger(messageId) + } + + trunkMessageId := msg.TrunkId() + if _, deleted := tipSelector.tips.Delete(trunkMessageId); deleted { + tipSelector.Events.TipRemoved.Trigger(trunkMessageId) + } + + branchMessageId := msg.BranchId() + if _, deleted := tipSelector.tips.Delete(branchMessageId); deleted { + tipSelector.Events.TipRemoved.Trigger(branchMessageId) + } +} + +// Tips returns two tips. +func (tipSelector *TipSelector) Tips() (trunkMessageId, branchMessageId message.Id) { + tip := tipSelector.tips.RandomEntry() + if tip == nil { + trunkMessageId = message.EmptyId + branchMessageId = message.EmptyId + + return + } + + branchMessageId = tip.(message.Id) + + if tipSelector.tips.Size() == 1 { + trunkMessageId = branchMessageId + return + } + + trunkMessageId = tipSelector.tips.RandomEntry().(message.Id) + for trunkMessageId == branchMessageId && tipSelector.tips.Size() > 1 { + trunkMessageId = tipSelector.tips.RandomEntry().(message.Id) + } + + return +} + +// TipCount the amount of current tips. +func (tipSelector *TipSelector) TipCount() int { + return tipSelector.tips.Size() +} diff --git a/packages/binary/messagelayer/tipselector/tipselector_test.go b/packages/binary/messagelayer/tipselector/tipselector_test.go new file mode 100644 index 0000000000000000000000000000000000000000..fbcf727d4b61b2f56312b052e2f73a468d3e5c18 --- /dev/null +++ b/packages/binary/messagelayer/tipselector/tipselector_test.go @@ -0,0 +1,56 @@ +package tipselector + +import ( + "testing" + "time" + + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +func Test(t *testing.T) { + // create tip selector + tipSelector := New() + + // check if first tips point to genesis + trunk1, branch1 := tipSelector.Tips() + assert.Equal(t, message.EmptyId, trunk1) + assert.Equal(t, message.EmptyId, branch1) + + // create a message and attach it + message1 := newTestMessage(trunk1, branch1, "testmessage") + tipSelector.AddTip(message1) + + // check if the tip shows up in the tip count + assert.Equal(t, 1, tipSelector.TipCount()) + + // check if next tips point to our first message + trunk2, branch2 := tipSelector.Tips() + assert.Equal(t, message1.Id(), trunk2) + assert.Equal(t, message1.Id(), branch2) + + // create a 2nd message and attach it + message2 := newTestMessage(message.EmptyId, message.EmptyId, "testmessage") + tipSelector.AddTip(message2) + + // check if the tip shows up in the tip count + assert.Equal(t, 2, tipSelector.TipCount()) + + // attach a message to our two tips + trunk3, branch3 := tipSelector.Tips() + message3 := newTestMessage(trunk3, branch3, "testmessage") + tipSelector.AddTip(message3) + + // check if the tip shows replaces the current tips + trunk4, branch4 := tipSelector.Tips() + assert.Equal(t, 1, tipSelector.TipCount()) + assert.Equal(t, message3.Id(), trunk4) + assert.Equal(t, message3.Id(), branch4) +} + +func newTestMessage(trunk, branch message.Id, payloadString string) *message.Message { + return message.New(trunk, branch, time.Now(), ed25519.PublicKey{}, 0, payload.NewData([]byte(payloadString)), 0, ed25519.Signature{}) +} diff --git a/packages/binary/signature/ed25119/ed25119.go b/packages/binary/signature/ed25119/ed25119.go deleted file mode 100644 index d4b65997bf4657ceeaa43427a8f0b43a58fc2dfe..0000000000000000000000000000000000000000 --- a/packages/binary/signature/ed25119/ed25119.go +++ /dev/null @@ -1,18 +0,0 @@ -package ed25119 - -import ( - "crypto/rand" - - "github.com/oasislabs/ed25519" -) - -func GenerateKeyPair() (keyPair KeyPair) { - if public, private, err := ed25519.GenerateKey(rand.Reader); err != nil { - panic(err) - } else { - copy(keyPair.PrivateKey[:], private) - copy(keyPair.PublicKey[:], public) - - return - } -} diff --git a/packages/binary/signature/ed25119/key_pair.go b/packages/binary/signature/ed25119/key_pair.go deleted file mode 100644 index ad0c31bbe6ef5e06df08138dd66282e843322af4..0000000000000000000000000000000000000000 --- a/packages/binary/signature/ed25119/key_pair.go +++ /dev/null @@ -1,6 +0,0 @@ -package ed25119 - -type KeyPair struct { - PrivateKey PrivateKey - PublicKey PublicKey -} diff --git a/packages/binary/signature/ed25119/private_key.go b/packages/binary/signature/ed25119/private_key.go deleted file mode 100644 index 89dc1a15ecc01f5b088a0aca871390dbbcbd101e..0000000000000000000000000000000000000000 --- a/packages/binary/signature/ed25119/private_key.go +++ /dev/null @@ -1,15 +0,0 @@ -package ed25119 - -import ( - "github.com/oasislabs/ed25519" -) - -type PrivateKey [PrivateKeySize]byte - -func (privateKey PrivateKey) Sign(data []byte) (result Signature) { - copy(result[:], ed25519.Sign(privateKey[:], data)) - - return -} - -const PrivateKeySize = 64 diff --git a/packages/binary/signature/ed25119/public_key.go b/packages/binary/signature/ed25119/public_key.go deleted file mode 100644 index c9d58e254413349234283406c817f8c68c7d30e5..0000000000000000000000000000000000000000 --- a/packages/binary/signature/ed25119/public_key.go +++ /dev/null @@ -1,25 +0,0 @@ -package ed25119 - -import ( - "errors" - - "github.com/oasislabs/ed25519" -) - -type PublicKey [PublicKeySize]byte - -func (publicKey PublicKey) VerifySignature(data []byte, signature Signature) bool { - return ed25519.Verify(publicKey[:], data, signature[:]) -} - -func (publicKey *PublicKey) UnmarshalBinary(bytes []byte) (err error) { - if len(bytes) < PublicKeySize { - return errors.New("not enough bytes") - } - - copy(publicKey[:], bytes[:]) - - return -} - -const PublicKeySize = 32 diff --git a/packages/binary/signature/ed25119/signature.go b/packages/binary/signature/ed25119/signature.go deleted file mode 100644 index bd33e1138e42da2809b0dac22afa1a140d5b8c3b..0000000000000000000000000000000000000000 --- a/packages/binary/signature/ed25119/signature.go +++ /dev/null @@ -1,19 +0,0 @@ -package ed25119 - -import ( - "errors" -) - -type Signature [SignatureSize]byte - -func (signature *Signature) UnmarshalBinary(bytes []byte) (err error) { - if len(bytes) < SignatureSize { - return errors.New("not enough bytes") - } - - copy(signature[:], bytes[:]) - - return -} - -const SignatureSize = 64 diff --git a/packages/binary/spammer/spammer.go b/packages/binary/spammer/spammer.go new file mode 100644 index 0000000000000000000000000000000000000000..5758f898fd70c5f8e72b06dab1ad02d904270f34 --- /dev/null +++ b/packages/binary/spammer/spammer.go @@ -0,0 +1,67 @@ +package spammer + +import ( + "sync/atomic" + "time" + + "github.com/iotaledger/hive.go/types" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" +) + +// IssuePayloadFunc is a function which issues a payload. +type IssuePayloadFunc = func(payload payload.Payload) (*message.Message, error) + +// Spammer spams messages with a static data payload. +type Spammer struct { + issuePayloadFunc IssuePayloadFunc + + processId int64 + shutdownSignal chan types.Empty +} + +// New creates a new spammer. +func New(issuePayloadFunc IssuePayloadFunc) *Spammer { + return &Spammer{ + issuePayloadFunc: issuePayloadFunc, + shutdownSignal: make(chan types.Empty), + } +} + +// Start starts the spammer to spam with the given messages per time unit. +func (spammer *Spammer) Start(rate int, timeUnit time.Duration) { + go spammer.run(rate, timeUnit, atomic.AddInt64(&spammer.processId, 1)) +} + +// Shutdown shuts down the spammer. +func (spammer *Spammer) Shutdown() { + atomic.AddInt64(&spammer.processId, 1) +} + +func (spammer *Spammer) run(rate int, timeUnit time.Duration, processID int64) { + currentSentCounter := 0 + start := time.Now() + + for { + if atomic.LoadInt64(&spammer.processId) != processID { + return + } + + // we don't care about errors or the actual issued message + _, _ = spammer.issuePayloadFunc(payload.NewData([]byte("SPAM"))) + + currentSentCounter++ + + // rate limit to the specified MPS + if currentSentCounter >= rate { + duration := time.Since(start) + if duration < timeUnit { + time.Sleep(timeUnit - duration) + } + + start = time.Now() + currentSentCounter = 0 + } + } +} diff --git a/packages/binary/storageprefix/storageprefix.go b/packages/binary/storageprefix/storageprefix.go index 1e55f2db25ff3bd2703056c8ea61c0aa048fda84..28ad9403e71a214a1d956f0eeb8a90e3206c4bc1 100644 --- a/packages/binary/storageprefix/storageprefix.go +++ b/packages/binary/storageprefix/storageprefix.go @@ -1,17 +1,10 @@ package storageprefix -var ( - TangleTransaction = []byte{0} - TangleTransactionMetadata = []byte{1} - TangleApprovers = []byte{2} - TangleMissingTransaction = []byte{3} +const ( + // the following values are a list of prefixes defined as an enum + _ byte = iota - ValueTangleTransferMetadata = []byte{4} - ValueTangleConsumers = []byte{5} - ValueTangleMissingTransfers = []byte{6} - - LedgerStateTransferOutput = []byte{7} - LedgerStateTransferOutputBooking = []byte{8} - LedgerStateReality = []byte{9} - LedgerStateConflictSet = []byte{10} + // package specific prefixes used for the objectstorage in the corresponding packages + MessageLayer + ValueTransfers ) diff --git a/packages/binary/tangle/events.go b/packages/binary/tangle/events.go deleted file mode 100644 index d2bf35523764694fd393df88ff9936244ddd5b54..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/events.go +++ /dev/null @@ -1,39 +0,0 @@ -package tangle - -import ( - "github.com/iotaledger/hive.go/events" - - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transactionmetadata" -) - -type Events struct { - TransactionAttached *events.Event - TransactionSolid *events.Event - MissingTransactionReceived *events.Event - TransactionMissing *events.Event - TransactionUnsolidifiable *events.Event - TransactionRemoved *events.Event -} - -func newEvents() *Events { - return &Events{ - TransactionAttached: events.NewEvent(cachedTransactionEvent), - TransactionSolid: events.NewEvent(cachedTransactionEvent), - MissingTransactionReceived: events.NewEvent(cachedTransactionEvent), - TransactionMissing: events.NewEvent(transactionIdEvent), - TransactionUnsolidifiable: events.NewEvent(transactionIdEvent), - TransactionRemoved: events.NewEvent(transactionIdEvent), - } -} - -func transactionIdEvent(handler interface{}, params ...interface{}) { - handler.(func(transaction.Id))(params[0].(transaction.Id)) -} - -func cachedTransactionEvent(handler interface{}, params ...interface{}) { - handler.(func(*transaction.CachedTransaction, *transactionmetadata.CachedTransactionMetadata))( - params[0].(*transaction.CachedTransaction).Retain(), - params[1].(*transactionmetadata.CachedTransactionMetadata).Retain().(*transactionmetadata.CachedTransactionMetadata), - ) -} diff --git a/packages/binary/tangle/model/approver/approver.go b/packages/binary/tangle/model/approver/approver.go deleted file mode 100644 index b08bf342d269616674e883d31791650dcdd29006..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/approver/approver.go +++ /dev/null @@ -1,59 +0,0 @@ -package approver - -import ( - "github.com/iotaledger/hive.go/objectstorage" - - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" -) - -type Approver struct { - objectstorage.StorableObjectFlags - - storageKey []byte - referencedTransaction transaction.Id - approvingTransaction transaction.Id -} - -func New(referencedTransaction transaction.Id, approvingTransaction transaction.Id) *Approver { - approver := &Approver{ - storageKey: make([]byte, transaction.IdLength+transaction.IdLength), - referencedTransaction: referencedTransaction, - approvingTransaction: approvingTransaction, - } - - copy(approver.storageKey[:transaction.IdLength], referencedTransaction[:]) - copy(approver.storageKey[transaction.IdLength:], approvingTransaction[:]) - - return approver -} - -func FromStorage(id []byte) (result objectstorage.StorableObject) { - approver := &Approver{ - storageKey: make([]byte, transaction.IdLength+transaction.IdLength), - } - copy(approver.referencedTransaction[:], id[:transaction.IdLength]) - copy(approver.approvingTransaction[:], id[transaction.IdLength:]) - copy(approver.storageKey, id) - - return approver -} - -func (approver *Approver) GetStorageKey() []byte { - return approver.storageKey -} - -func (approver *Approver) GetApprovingTransactionId() transaction.Id { - return approver.approvingTransaction -} - -func (approver *Approver) Update(other objectstorage.StorableObject) { - panic("approvers should never be overwritten and only stored once to optimize IO") -} - -func (approver *Approver) MarshalBinary() (result []byte, err error) { - return -} - -func (approver *Approver) UnmarshalBinary(data []byte) (err error) { - return -} diff --git a/packages/binary/tangle/model/approver/cached_approver.go b/packages/binary/tangle/model/approver/cached_approver.go deleted file mode 100644 index c52844320472f2dd0ed38a3c02ba2b1334959d76..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/approver/cached_approver.go +++ /dev/null @@ -1,33 +0,0 @@ -package approver - -import ( - "github.com/iotaledger/hive.go/objectstorage" -) - -type CachedApprover struct { - objectstorage.CachedObject -} - -func (cachedApprover *CachedApprover) Unwrap() *Approver { - if untypedObject := cachedApprover.Get(); untypedObject == nil { - return nil - } else { - if typedObject := untypedObject.(*Approver); typedObject == nil || typedObject.IsDeleted() { - return nil - } else { - return typedObject - } - } -} - -type CachedApprovers []*CachedApprover - -func (cachedApprovers CachedApprovers) Consume(consumer func(approver *Approver)) (consumed bool) { - for _, cachedApprover := range cachedApprovers { - consumed = consumed || cachedApprover.Consume(func(object objectstorage.StorableObject) { - consumer(object.(*Approver)) - }) - } - - return -} diff --git a/packages/binary/tangle/model/missingtransaction/cached_missingtransaction.go b/packages/binary/tangle/model/missingtransaction/cached_missingtransaction.go deleted file mode 100644 index f50f532127ba98e5f9baaaa5bd1095ba0c9d4216..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/missingtransaction/cached_missingtransaction.go +++ /dev/null @@ -1,21 +0,0 @@ -package missingtransaction - -import ( - "github.com/iotaledger/hive.go/objectstorage" -) - -type CachedMissingTransaction struct { - objectstorage.CachedObject -} - -func (cachedObject *CachedMissingTransaction) Unwrap() *MissingTransaction { - if untypedObject := cachedObject.Get(); untypedObject == nil { - return nil - } else { - if typedObject := untypedObject.(*MissingTransaction); typedObject == nil || typedObject.IsDeleted() { - return nil - } else { - return typedObject - } - } -} diff --git a/packages/binary/tangle/model/missingtransaction/missingtransaction.go b/packages/binary/tangle/model/missingtransaction/missingtransaction.go deleted file mode 100644 index ea1715c8d0a127324dd5f6a82ac9b2e2719bd0c0..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/missingtransaction/missingtransaction.go +++ /dev/null @@ -1,53 +0,0 @@ -package missingtransaction - -import ( - "time" - - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" - "github.com/iotaledger/hive.go/objectstorage" -) - -type MissingTransaction struct { - objectstorage.StorableObjectFlags - - transactionId transaction.Id - missingSince time.Time -} - -func New(transactionId transaction.Id) *MissingTransaction { - return &MissingTransaction{ - transactionId: transactionId, - missingSince: time.Now(), - } -} - -func FromStorage(key []byte) objectstorage.StorableObject { - result := &MissingTransaction{} - copy(result.transactionId[:], key) - - return result -} - -func (missingTransaction *MissingTransaction) GetTransactionId() transaction.Id { - return missingTransaction.transactionId -} - -func (missingTransaction *MissingTransaction) GetMissingSince() time.Time { - return missingTransaction.missingSince -} - -func (missingTransaction *MissingTransaction) GetStorageKey() []byte { - return missingTransaction.transactionId[:] -} - -func (missingTransaction *MissingTransaction) Update(other objectstorage.StorableObject) { - panic("missing transactions should never be overwritten and only stored once to optimize IO") -} - -func (missingTransaction *MissingTransaction) MarshalBinary() (result []byte, err error) { - return missingTransaction.missingSince.MarshalBinary() -} - -func (missingTransaction *MissingTransaction) UnmarshalBinary(data []byte) (err error) { - return missingTransaction.missingSince.UnmarshalBinary(data) -} diff --git a/packages/binary/tangle/model/transaction/cached_transaction.go b/packages/binary/tangle/model/transaction/cached_transaction.go deleted file mode 100644 index 5f177ea76c1ce12c474bfe7a1be0ab2b3d0315af..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/cached_transaction.go +++ /dev/null @@ -1,31 +0,0 @@ -package transaction - -import ( - "github.com/iotaledger/hive.go/objectstorage" -) - -type CachedTransaction struct { - objectstorage.CachedObject -} - -func (cachedTransaction *CachedTransaction) Retain() *CachedTransaction { - return &CachedTransaction{cachedTransaction.CachedObject.Retain()} -} - -func (cachedTransaction *CachedTransaction) Consume(consumer func(object *Transaction)) bool { - return cachedTransaction.CachedObject.Consume(func(object objectstorage.StorableObject) { - consumer(object.(*Transaction)) - }) -} - -func (cachedTransaction *CachedTransaction) Unwrap() *Transaction { - if untypedTransaction := cachedTransaction.Get(); untypedTransaction == nil { - return nil - } else { - if typeCastedTransaction := untypedTransaction.(*Transaction); typeCastedTransaction == nil || typeCastedTransaction.IsDeleted() { - return nil - } else { - return typeCastedTransaction - } - } -} diff --git a/packages/binary/tangle/model/transaction/id.go b/packages/binary/tangle/model/transaction/id.go deleted file mode 100644 index dd5ca1544b311f85740893dd416a04358cb74267..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/id.go +++ /dev/null @@ -1,34 +0,0 @@ -package transaction - -import ( - "github.com/mr-tron/base58" -) - -type Id [IdLength]byte - -func NewId(id []byte) (result Id) { - copy(result[:], id) - - return -} - -func (id *Id) MarshalBinary() (result []byte, err error) { - result = make([]byte, IdLength) - copy(result, id[:]) - - return -} - -func (id *Id) UnmarshalBinary(data []byte) (err error) { - copy(id[:], data) - - return -} - -func (id Id) String() string { - return base58.Encode(id[:]) -} - -var EmptyId = Id{} - -const IdLength = 64 diff --git a/packages/binary/tangle/model/transaction/init.go b/packages/binary/tangle/model/transaction/init.go deleted file mode 100644 index 5805588c0b6309d978159aa094c6c4966f73a8c9..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/init.go +++ /dev/null @@ -1,10 +0,0 @@ -package transaction - -import ( - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload/data" -) - -func init() { - payload.SetGenericUnmarshalerFactory(data.GenericPayloadUnmarshalerFactory) -} diff --git a/packages/binary/tangle/model/transaction/payload/data/data.go b/packages/binary/tangle/model/transaction/payload/data/data.go deleted file mode 100644 index 8b41b99ce062ee65fee8cbd25b5561bc50b7a538..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/payload/data/data.go +++ /dev/null @@ -1,52 +0,0 @@ -package data - -import ( - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload" -) - -type Data struct { - payloadType payload.Type - data []byte -} - -var Type = payload.Type(0) - -func New(data []byte) *Data { - return &Data{ - payloadType: Type, - data: data, - } -} - -func (dataPayload *Data) GetType() payload.Type { - return dataPayload.payloadType -} - -func (dataPayload *Data) GetData() []byte { - return dataPayload.data -} - -func (dataPayload *Data) UnmarshalBinary(data []byte) error { - dataPayload.data = make([]byte, len(data)) - copy(dataPayload.data, data) - - return nil -} - -func (dataPayload *Data) MarshalBinary() (data []byte, err error) { - data = make([]byte, len(dataPayload.data)) - copy(data, dataPayload.data) - - return -} - -func GenericPayloadUnmarshalerFactory(payloadType payload.Type) payload.Unmarshaler { - return func(data []byte) (payload payload.Payload, err error) { - payload = &Data{ - payloadType: payloadType, - } - err = payload.UnmarshalBinary(data) - - return - } -} diff --git a/packages/binary/tangle/model/transaction/payload/data/init.go b/packages/binary/tangle/model/transaction/payload/data/init.go deleted file mode 100644 index 547bca2c68e3ad3ac12adc1b97ab82ae3878a764..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/payload/data/init.go +++ /dev/null @@ -1,9 +0,0 @@ -package data - -import ( - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload" -) - -func init() { - payload.RegisterType(Type, GenericPayloadUnmarshalerFactory(Type)) -} diff --git a/packages/binary/tangle/model/transaction/payload/id.go b/packages/binary/tangle/model/transaction/payload/id.go deleted file mode 100644 index a20ce75f2b069a4299bf70a633deafd1c41c2f93..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/payload/id.go +++ /dev/null @@ -1,5 +0,0 @@ -package payload - -type Id [IdLength]byte - -const IdLength = 64 diff --git a/packages/binary/tangle/model/transaction/payload/payload.go b/packages/binary/tangle/model/transaction/payload/payload.go deleted file mode 100644 index 23ff09be788c7dc242b3fd640813e43641a72f76..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/payload/payload.go +++ /dev/null @@ -1,12 +0,0 @@ -package payload - -import ( - "encoding" -) - -type Payload interface { - encoding.BinaryMarshaler - encoding.BinaryUnmarshaler - - GetType() Type -} diff --git a/packages/binary/tangle/model/transaction/payload/type.go b/packages/binary/tangle/model/transaction/payload/type.go deleted file mode 100644 index a1594aa40bd8d8cfe3bd7d7533304b3c778f182b..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/payload/type.go +++ /dev/null @@ -1,3 +0,0 @@ -package payload - -type Type = uint32 diff --git a/packages/binary/tangle/model/transaction/payload/type_register.go b/packages/binary/tangle/model/transaction/payload/type_register.go deleted file mode 100644 index aac9a9195eae5282e9514790cff2a957e01bafb1..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/payload/type_register.go +++ /dev/null @@ -1,36 +0,0 @@ -package payload - -import ( - "sync" -) - -type Unmarshaler func(data []byte) (Payload, error) - -var ( - typeRegister = make(map[Type]Unmarshaler) - typeRegisterMutex sync.RWMutex - genericUnmarshalerFactory func(payloadType Type) Unmarshaler -) - -func RegisterType(payloadType Type, unmarshaler Unmarshaler) { - typeRegisterMutex.Lock() - typeRegister[payloadType] = unmarshaler - typeRegisterMutex.Unlock() -} - -func GetUnmarshaler(payloadType Type) Unmarshaler { - typeRegisterMutex.RLock() - if unmarshaler, exists := typeRegister[payloadType]; exists { - typeRegisterMutex.RUnlock() - - return unmarshaler - } else { - typeRegisterMutex.RUnlock() - - return genericUnmarshalerFactory(payloadType) - } -} - -func SetGenericUnmarshalerFactory(unmarshalerFactory func(payloadType Type) Unmarshaler) { - genericUnmarshalerFactory = unmarshalerFactory -} diff --git a/packages/binary/tangle/model/transaction/test/transaction_test.go b/packages/binary/tangle/model/transaction/test/transaction_test.go deleted file mode 100644 index 1ca51d61b5d7b49fcf31df68a5da4a9b1b6b8708..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/test/transaction_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package test - -import ( - "runtime" - "sync" - "testing" - - "github.com/iotaledger/hive.go/async" - - "github.com/panjf2000/ants/v2" - - "github.com/iotaledger/goshimmer/packages/binary/identity" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload/data" -) - -func BenchmarkVerifyDataTransactions(b *testing.B) { - var pool async.WorkerPool - pool.Tune(runtime.NumCPU() * 2) - - transactions := make([][]byte, b.N) - for i := 0; i < b.N; i++ { - tx := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("some data"))) - - if marshaledTransaction, err := tx.MarshalBinary(); err != nil { - b.Error(err) - } else { - transactions[i] = marshaledTransaction - } - } - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - currentIndex := i - pool.Submit(func() { - if tx, err := transaction.FromBytes(transactions[currentIndex]); err != nil { - b.Error(err) - } else { - tx.VerifySignature() - } - }) - } - - pool.Shutdown() -} - -func BenchmarkVerifySignature(b *testing.B) { - pool, _ := ants.NewPool(80, ants.WithNonblocking(false)) - - transactions := make([]*transaction.Transaction, b.N) - for i := 0; i < b.N; i++ { - transactions[i] = transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("test"))) - transactions[i].GetBytes() - } - - var wg sync.WaitGroup - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - wg.Add(1) - - currentIndex := i - if err := pool.Submit(func() { - transactions[currentIndex].VerifySignature() - - wg.Done() - }); err != nil { - b.Error(err) - - return - } - } - - wg.Wait() -} diff --git a/packages/binary/tangle/model/transaction/transaction.go b/packages/binary/tangle/model/transaction/transaction.go deleted file mode 100644 index de18ffc47ed6514c4883dc1382da60d23184d758..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transaction/transaction.go +++ /dev/null @@ -1,277 +0,0 @@ -package transaction - -import ( - "encoding/binary" - "sync" - - "github.com/iotaledger/hive.go/stringify" - - "github.com/iotaledger/goshimmer/packages/binary/identity" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload" - - "github.com/iotaledger/hive.go/objectstorage" - - "github.com/mr-tron/base58" - - "golang.org/x/crypto/blake2b" -) - -type Transaction struct { - // base functionality of StorableObject - objectstorage.StorableObjectFlags - - // core properties (they are part of the transaction when being sent) - trunkTransactionId Id - branchTransactionId Id - issuer *identity.Identity - payload payload.Payload - bytes []byte - bytesMutex sync.RWMutex - signature [identity.SignatureSize]byte - signatureMutex sync.RWMutex - - // derived properties - id *Id - idMutex sync.RWMutex - payloadId *payload.Id - payloadIdMutex sync.RWMutex -} - -// Allows us to "issue" a transaction. -func New(trunkTransactionId Id, branchTransactionId Id, issuer *identity.Identity, payload payload.Payload) (result *Transaction) { - return &Transaction{ - trunkTransactionId: trunkTransactionId, - branchTransactionId: branchTransactionId, - issuer: issuer, - payload: payload, - } -} - -// Get's called when we restore a transaction from storage. The bytes and the content will be unmarshaled by an external -// caller (the objectStorage factory). -func FromStorage(id []byte) (result objectstorage.StorableObject) { - var transactionId Id - copy(transactionId[:], id) - - result = &Transaction{ - id: &transactionId, - } - - return -} - -func FromBytes(bytes []byte) (result *Transaction, err error) { - result = &Transaction{} - err = result.UnmarshalBinary(bytes) - - return -} - -func (transaction *Transaction) VerifySignature() (result bool) { - transactionBytes := transaction.GetBytes() - - transaction.signatureMutex.RLock() - result = transaction.issuer.VerifySignature(transactionBytes[:len(transactionBytes)-identity.SignatureSize], transaction.signature[:]) - transaction.signatureMutex.RUnlock() - - return -} - -func (transaction *Transaction) GetId() (result Id) { - transaction.idMutex.RLock() - if transaction.id == nil { - transaction.idMutex.RUnlock() - - transaction.idMutex.Lock() - if transaction.id == nil { - result = transaction.calculateTransactionId() - - transaction.id = &result - } else { - result = *transaction.id - } - transaction.idMutex.Unlock() - } else { - result = *transaction.id - - transaction.idMutex.RUnlock() - } - - return -} - -func (transaction *Transaction) GetTrunkTransactionId() Id { - return transaction.trunkTransactionId -} - -func (transaction *Transaction) GetBranchTransactionId() Id { - return transaction.branchTransactionId -} - -func (transaction *Transaction) GetPayload() payload.Payload { - return transaction.payload -} - -func (transaction *Transaction) GetPayloadId() (result payload.Id) { - transaction.payloadIdMutex.RLock() - if transaction.payloadId == nil { - transaction.payloadIdMutex.RUnlock() - - transaction.payloadIdMutex.Lock() - if transaction.payloadId == nil { - result = transaction.calculatePayloadId() - - transaction.payloadId = &result - } else { - result = *transaction.payloadId - } - transaction.payloadIdMutex.Unlock() - } else { - result = *transaction.payloadId - - transaction.payloadIdMutex.RUnlock() - } - - return -} - -func (transaction *Transaction) GetBytes() []byte { - if result, err := transaction.MarshalBinary(); err != nil { - panic(err) - } else { - return result - } -} - -func (transaction *Transaction) calculateTransactionId() Id { - payloadId := transaction.GetPayloadId() - - hashBase := make([]byte, IdLength+IdLength+payload.IdLength) - offset := 0 - - copy(hashBase[offset:], transaction.trunkTransactionId[:]) - offset += IdLength - - copy(hashBase[offset:], transaction.branchTransactionId[:]) - offset += IdLength - - copy(hashBase[offset:], payloadId[:]) - // offset += payloadIdLength - - return blake2b.Sum512(hashBase) -} - -func (transaction *Transaction) calculatePayloadId() payload.Id { - bytes := transaction.GetBytes() - - return blake2b.Sum512(bytes[2*IdLength:]) -} - -// Since transactions are immutable and do not get changed after being created, we cache the result of the marshaling. -func (transaction *Transaction) MarshalBinary() (result []byte, err error) { - transaction.bytesMutex.RLock() - if transaction.bytes == nil { - transaction.bytesMutex.RUnlock() - - transaction.bytesMutex.Lock() - if transaction.bytes == nil { - var serializedPayload []byte - if transaction.payload != nil { - if serializedPayload, err = transaction.payload.MarshalBinary(); err != nil { - return - } - } - serializedPayloadLength := len(serializedPayload) - - result = make([]byte, IdLength+IdLength+identity.PublicKeySize+4+serializedPayloadLength+identity.SignatureSize) - offset := 0 - - copy(result[offset:], transaction.trunkTransactionId[:]) - offset += IdLength - - copy(result[offset:], transaction.branchTransactionId[:]) - offset += IdLength - - if transaction.issuer != nil { - copy(result[offset:], transaction.issuer.PublicKey) - } - offset += identity.PublicKeySize - - binary.LittleEndian.PutUint32(result[offset:], transaction.payload.GetType()) - offset += 4 - - if serializedPayloadLength != 0 { - copy(result[offset:], serializedPayload) - offset += serializedPayloadLength - } - - if transaction.issuer != nil { - transaction.signatureMutex.Lock() - copy(transaction.signature[:], transaction.issuer.Sign(result[:offset])) - transaction.signatureMutex.Unlock() - copy(result[offset:], transaction.signature[:]) - } - // offset += identity.SignatureSize - - transaction.bytes = result - } else { - result = transaction.bytes - } - transaction.bytesMutex.Unlock() - } else { - result = transaction.bytes - - transaction.bytesMutex.RUnlock() - } - - return -} - -func (transaction *Transaction) UnmarshalBinary(data []byte) (err error) { - offset := 0 - - copy(transaction.trunkTransactionId[:], data[offset:]) - offset += IdLength - - copy(transaction.branchTransactionId[:], data[offset:]) - offset += IdLength - - transaction.issuer = identity.New(data[offset : offset+identity.PublicKeySize]) - offset += identity.PublicKeySize - - payloadType := binary.LittleEndian.Uint32(data[offset:]) - offset += 4 - - if transaction.payload, err = payload.GetUnmarshaler(payloadType)(data[offset : len(data)-identity.SignatureSize]); err != nil { - return - } - offset += len(data) - identity.SignatureSize - offset - - copy(transaction.signature[:], data[offset:]) - // offset += identity.SignatureSize - - transaction.bytes = make([]byte, len(data)) - copy(transaction.bytes, data) - - return -} - -func (transaction *Transaction) GetStorageKey() []byte { - transactionId := transaction.GetId() - - return transactionId[:] -} - -func (transaction *Transaction) Update(other objectstorage.StorableObject) { - panic("transactions should never be overwritten and only stored once to optimize IO") -} - -func (transaction *Transaction) String() string { - transactionId := transaction.GetId() - - return stringify.Struct("Transaction", - stringify.StructField("id", base58.Encode(transactionId[:])), - stringify.StructField("trunkTransactionId", base58.Encode(transaction.trunkTransactionId[:])), - stringify.StructField("trunkTransactionId", base58.Encode(transaction.branchTransactionId[:])), - ) -} diff --git a/packages/binary/tangle/model/transactionmetadata/cached_transactionmetadata.go b/packages/binary/tangle/model/transactionmetadata/cached_transactionmetadata.go deleted file mode 100644 index 8b327806525d359f39dcbf0dd54e699cdc195f61..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transactionmetadata/cached_transactionmetadata.go +++ /dev/null @@ -1,25 +0,0 @@ -package transactionmetadata - -import ( - "github.com/iotaledger/hive.go/objectstorage" -) - -type CachedTransactionMetadata struct { - objectstorage.CachedObject -} - -func (cachedObject *CachedTransactionMetadata) Retain() objectstorage.CachedObject { - return &CachedTransactionMetadata{cachedObject} -} - -func (cachedObject *CachedTransactionMetadata) Unwrap() *TransactionMetadata { - if untypedObject := cachedObject.Get(); untypedObject == nil { - return nil - } else { - if typedObject := untypedObject.(*TransactionMetadata); typedObject == nil || typedObject.IsDeleted() { - return nil - } else { - return typedObject - } - } -} diff --git a/packages/binary/tangle/model/transactionmetadata/transactionmetadata.go b/packages/binary/tangle/model/transactionmetadata/transactionmetadata.go deleted file mode 100644 index f29a6e3425262f50a312892714e3ca32020eb3cb..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/model/transactionmetadata/transactionmetadata.go +++ /dev/null @@ -1,94 +0,0 @@ -package transactionmetadata - -import ( - "sync" - "time" - - "github.com/iotaledger/hive.go/objectstorage" - - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" -) - -type TransactionMetadata struct { - objectstorage.StorableObjectFlags - - transactionId transaction.Id - receivedTime time.Time - solid bool - solidificationTime time.Time - - solidMutex sync.RWMutex - solidificationTimeMutex sync.RWMutex -} - -func New(transactionId transaction.Id) *TransactionMetadata { - return &TransactionMetadata{ - transactionId: transactionId, - receivedTime: time.Now(), - } -} - -func FromStorage(id []byte) objectstorage.StorableObject { - result := &TransactionMetadata{} - copy(result.transactionId[:], id) - - return result -} - -func (transactionMetadata *TransactionMetadata) IsSolid() (result bool) { - transactionMetadata.solidMutex.RLock() - result = transactionMetadata.solid - transactionMetadata.solidMutex.RUnlock() - - return -} - -func (transactionMetadata *TransactionMetadata) SetSolid(solid bool) (modified bool) { - transactionMetadata.solidMutex.RLock() - if transactionMetadata.solid != solid { - transactionMetadata.solidMutex.RUnlock() - - transactionMetadata.solidMutex.Lock() - if transactionMetadata.solid != solid { - transactionMetadata.solid = solid - if solid { - transactionMetadata.solidificationTimeMutex.Lock() - transactionMetadata.solidificationTime = time.Now() - transactionMetadata.solidificationTimeMutex.Unlock() - } - - transactionMetadata.SetModified() - - modified = true - } - transactionMetadata.solidMutex.Unlock() - - } else { - transactionMetadata.solidMutex.RUnlock() - } - - return -} - -func (transactionMetadata *TransactionMetadata) GetSoldificationTime() time.Time { - transactionMetadata.solidificationTimeMutex.RLock() - defer transactionMetadata.solidificationTimeMutex.RUnlock() - - return transactionMetadata.solidificationTime -} - -func (transactionMetadata *TransactionMetadata) GetStorageKey() []byte { - return transactionMetadata.transactionId[:] -} - -func (transactionMetadata *TransactionMetadata) Update(other objectstorage.StorableObject) { - -} - -func (transactionMetadata *TransactionMetadata) MarshalBinary() ([]byte, error) { - return nil, nil -} - -func (transactionMetadata *TransactionMetadata) UnmarshalBinary([]byte) error { - return nil -} diff --git a/packages/binary/tangle/tangle.go b/packages/binary/tangle/tangle.go deleted file mode 100644 index 185937043da051b0a1c8f1ea33db0a72726f48f8..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/tangle.go +++ /dev/null @@ -1,323 +0,0 @@ -package tangle - -import ( - "container/list" - "time" - - "github.com/dgraph-io/badger/v2" - "github.com/iotaledger/hive.go/types" - - "github.com/iotaledger/goshimmer/packages/binary/storageprefix" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/approver" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/missingtransaction" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transactionmetadata" - - "github.com/iotaledger/hive.go/async" - "github.com/iotaledger/hive.go/objectstorage" -) - -const ( - MAX_MISSING_TIME_BEFORE_CLEANUP = 30 * time.Second - MISSING_CHECK_INTERVAL = 5 * time.Second -) - -type Tangle struct { - storageId []byte - - transactionStorage *objectstorage.ObjectStorage - transactionMetadataStorage *objectstorage.ObjectStorage - approverStorage *objectstorage.ObjectStorage - missingTransactionsStorage *objectstorage.ObjectStorage - - Events Events - - storeTransactionsWorkerPool async.WorkerPool - solidifierWorkerPool async.WorkerPool - cleanupWorkerPool async.WorkerPool -} - -// Constructor for the tangle. -func New(badgerInstance *badger.DB, storageId []byte) (result *Tangle) { - result = &Tangle{ - storageId: storageId, - transactionStorage: objectstorage.New(badgerInstance, append(storageId, storageprefix.TangleTransaction...), transaction.FromStorage, objectstorage.CacheTime(10*time.Second), objectstorage.LeakDetectionEnabled(false)), - transactionMetadataStorage: objectstorage.New(badgerInstance, append(storageId, storageprefix.TangleTransactionMetadata...), transactionmetadata.FromStorage, objectstorage.CacheTime(10*time.Second), objectstorage.LeakDetectionEnabled(false)), - approverStorage: objectstorage.New(badgerInstance, append(storageId, storageprefix.TangleApprovers...), approver.FromStorage, objectstorage.CacheTime(10*time.Second), objectstorage.PartitionKey(transaction.IdLength, transaction.IdLength), objectstorage.LeakDetectionEnabled(false)), - missingTransactionsStorage: objectstorage.New(badgerInstance, append(storageId, storageprefix.TangleMissingTransaction...), missingtransaction.FromStorage, objectstorage.CacheTime(10*time.Second), objectstorage.LeakDetectionEnabled(false)), - - Events: *newEvents(), - } - - result.solidifierWorkerPool.Tune(1024) - - return -} - -// Returns the storage id of this tangle (can be used to create ontologies that follow the storage of the main tangle). -func (tangle *Tangle) GetStorageId() []byte { - return tangle.storageId -} - -// Attaches a new transaction to the tangle. -func (tangle *Tangle) AttachTransaction(transaction *transaction.Transaction) { - tangle.storeTransactionsWorkerPool.Submit(func() { tangle.storeTransactionWorker(transaction) }) -} - -// Retrieves a transaction from the tangle. -func (tangle *Tangle) GetTransaction(transactionId transaction.Id) *transaction.CachedTransaction { - return &transaction.CachedTransaction{CachedObject: tangle.transactionStorage.Load(transactionId[:])} -} - -// Retrieves the metadata of a transaction from the tangle. -func (tangle *Tangle) GetTransactionMetadata(transactionId transaction.Id) *transactionmetadata.CachedTransactionMetadata { - return &transactionmetadata.CachedTransactionMetadata{CachedObject: tangle.transactionMetadataStorage.Load(transactionId[:])} -} - -// Retrieves the approvers of a transaction from the tangle. -func (tangle *Tangle) GetApprovers(transactionId transaction.Id) approver.CachedApprovers { - approvers := make(approver.CachedApprovers, 0) - tangle.approverStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool { - approvers = append(approvers, &approver.CachedApprover{CachedObject: cachedObject}) - - return true - }, transactionId[:]) - - return approvers -} - -// Deletes a transaction from the tangle (i.e. for local snapshots) -func (tangle *Tangle) DeleteTransaction(transactionId transaction.Id) { - tangle.GetTransaction(transactionId).Consume(func(currentTransaction *transaction.Transaction) { - trunkTransactionId := currentTransaction.GetTrunkTransactionId() - tangle.deleteApprover(trunkTransactionId, transactionId) - - branchTransactionId := currentTransaction.GetBranchTransactionId() - if branchTransactionId != trunkTransactionId { - tangle.deleteApprover(branchTransactionId, transactionId) - } - - tangle.transactionMetadataStorage.Delete(transactionId[:]) - tangle.transactionStorage.Delete(transactionId[:]) - - tangle.Events.TransactionRemoved.Trigger(transactionId) - }) -} - -// Marks the tangle as stopped, so it will not accept any new transactions (waits for all backgroundTasks to finish. -func (tangle *Tangle) Shutdown() *Tangle { - tangle.storeTransactionsWorkerPool.ShutdownGracefully() - tangle.solidifierWorkerPool.ShutdownGracefully() - tangle.cleanupWorkerPool.ShutdownGracefully() - - tangle.transactionStorage.Shutdown() - tangle.transactionMetadataStorage.Shutdown() - tangle.approverStorage.Shutdown() - tangle.missingTransactionsStorage.Shutdown() - - return tangle -} - -// Resets the database and deletes all objects (good for testing or "node resets"). -func (tangle *Tangle) Prune() error { - for _, storage := range []*objectstorage.ObjectStorage{ - tangle.transactionStorage, - tangle.transactionMetadataStorage, - tangle.approverStorage, - tangle.missingTransactionsStorage, - } { - if err := storage.Prune(); err != nil { - return err - } - } - - return nil -} - -// Worker that stores the transactions and calls the corresponding "Storage events" -func (tangle *Tangle) storeTransactionWorker(tx *transaction.Transaction) { - // store transaction - var cachedTransaction *transaction.CachedTransaction - if _tmp, transactionIsNew := tangle.transactionStorage.StoreIfAbsent(tx); !transactionIsNew { - return - } else { - cachedTransaction = &transaction.CachedTransaction{CachedObject: _tmp} - } - - // store transaction metadata - transactionId := tx.GetId() - cachedTransactionMetadata := &transactionmetadata.CachedTransactionMetadata{CachedObject: tangle.transactionMetadataStorage.Store(transactionmetadata.New(transactionId))} - - // store trunk approver - trunkTransactionID := tx.GetTrunkTransactionId() - tangle.approverStorage.Store(approver.New(trunkTransactionID, transactionId)).Release() - - // store branch approver - if branchTransactionID := tx.GetBranchTransactionId(); branchTransactionID != trunkTransactionID { - tangle.approverStorage.Store(approver.New(branchTransactionID, transactionId)).Release() - } - - // trigger events - if tangle.missingTransactionsStorage.DeleteIfPresent(transactionId[:]) { - tangle.Events.MissingTransactionReceived.Trigger(cachedTransaction, cachedTransactionMetadata) - } - tangle.Events.TransactionAttached.Trigger(cachedTransaction, cachedTransactionMetadata) - - // check solidity - tangle.solidifierWorkerPool.Submit(func() { - tangle.solidifyTransactionWorker(cachedTransaction, cachedTransactionMetadata) - }) -} - -// Worker that solidifies the transactions (recursively from past to present). -func (tangle *Tangle) solidifyTransactionWorker(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *transactionmetadata.CachedTransactionMetadata) { - isTransactionMarkedAsSolid := func(transactionId transaction.Id) bool { - if transactionId == transaction.EmptyId { - return true - } - - transactionMetadataCached := tangle.GetTransactionMetadata(transactionId) - if transactionMetadata := transactionMetadataCached.Unwrap(); transactionMetadata == nil { - transactionMetadataCached.Release() - - // if transaction is missing and was not reported as missing, yet - if cachedMissingTransaction, missingTransactionStored := tangle.missingTransactionsStorage.StoreIfAbsent(missingtransaction.New(transactionId)); missingTransactionStored { - cachedMissingTransaction.Consume(func(object objectstorage.StorableObject) { - tangle.monitorMissingTransactionWorker(object.(*missingtransaction.MissingTransaction).GetTransactionId()) - }) - } - - return false - } else if !transactionMetadata.IsSolid() { - transactionMetadataCached.Release() - - return false - } - transactionMetadataCached.Release() - - return true - } - - isTransactionSolid := func(transaction *transaction.Transaction, transactionMetadata *transactionmetadata.TransactionMetadata) bool { - if transaction == nil || transaction.IsDeleted() { - return false - } - - if transactionMetadata == nil || transactionMetadata.IsDeleted() { - return false - } - - if transactionMetadata.IsSolid() { - return true - } - - return isTransactionMarkedAsSolid(transaction.GetTrunkTransactionId()) && isTransactionMarkedAsSolid(transaction.GetBranchTransactionId()) - } - - popElementsFromStack := func(stack *list.List) (*transaction.CachedTransaction, *transactionmetadata.CachedTransactionMetadata) { - currentSolidificationEntry := stack.Front() - currentCachedTransaction := currentSolidificationEntry.Value.([2]interface{})[0] - currentCachedTransactionMetadata := currentSolidificationEntry.Value.([2]interface{})[1] - stack.Remove(currentSolidificationEntry) - - return currentCachedTransaction.(*transaction.CachedTransaction), currentCachedTransactionMetadata.(*transactionmetadata.CachedTransactionMetadata) - } - - // initialize the stack - solidificationStack := list.New() - solidificationStack.PushBack([2]interface{}{cachedTransaction, cachedTransactionMetadata}) - - // process transactions that are supposed to be checked for solidity recursively - for solidificationStack.Len() > 0 { - currentCachedTransaction, currentCachedTransactionMetadata := popElementsFromStack(solidificationStack) - - currentTransaction := currentCachedTransaction.Unwrap() - currentTransactionMetadata := currentCachedTransactionMetadata.Unwrap() - if currentTransaction == nil || currentTransactionMetadata == nil { - currentCachedTransaction.Release() - currentCachedTransactionMetadata.Release() - - continue - } - - // if current transaction is solid and was not marked as solid before: mark as solid and propagate - if isTransactionSolid(currentTransaction, currentTransactionMetadata) && currentTransactionMetadata.SetSolid(true) { - tangle.Events.TransactionSolid.Trigger(currentCachedTransaction, currentCachedTransactionMetadata) - - tangle.GetApprovers(currentTransaction.GetId()).Consume(func(approver *approver.Approver) { - approverTransactionId := approver.GetApprovingTransactionId() - - solidificationStack.PushBack([2]interface{}{ - tangle.GetTransaction(approverTransactionId), - tangle.GetTransactionMetadata(approverTransactionId), - }) - }) - } - - // release cached results - currentCachedTransaction.Release() - currentCachedTransactionMetadata.Release() - } -} - -// Worker that Monitors the missing transactions (by scheduling regular checks). -func (tangle *Tangle) monitorMissingTransactionWorker(transactionId transaction.Id) { - var scheduleNextMissingCheck func(transactionId transaction.Id) - scheduleNextMissingCheck = func(transactionId transaction.Id) { - time.AfterFunc(MISSING_CHECK_INTERVAL, func() { - tangle.missingTransactionsStorage.Load(transactionId[:]).Consume(func(object objectstorage.StorableObject) { - missingTransaction := object.(*missingtransaction.MissingTransaction) - - if time.Since(missingTransaction.GetMissingSince()) >= MAX_MISSING_TIME_BEFORE_CLEANUP { - tangle.cleanupWorkerPool.Submit(func() { - tangle.Events.TransactionUnsolidifiable.Trigger(transactionId) - - tangle.deleteSubtangle(missingTransaction.GetTransactionId()) - }) - } else { - // TRIGGER STILL MISSING EVENT? - - scheduleNextMissingCheck(transactionId) - } - }) - }) - } - - tangle.Events.TransactionMissing.Trigger(transactionId) - - scheduleNextMissingCheck(transactionId) -} - -func (tangle *Tangle) deleteApprover(approvedTransaction transaction.Id, approvingTransaction transaction.Id) { - idToDelete := make([]byte, transaction.IdLength+transaction.IdLength) - copy(idToDelete[:transaction.IdLength], approvedTransaction[:]) - copy(idToDelete[transaction.IdLength:], approvingTransaction[:]) - tangle.approverStorage.Delete(idToDelete) -} - -// Deletes a transaction and all of its approvers (recursively). -func (tangle *Tangle) deleteSubtangle(transactionId transaction.Id) { - cleanupStack := list.New() - cleanupStack.PushBack(transactionId) - - processedTransactions := make(map[transaction.Id]types.Empty) - processedTransactions[transactionId] = types.Void - - for cleanupStack.Len() >= 1 { - currentStackEntry := cleanupStack.Front() - currentTransactionId := currentStackEntry.Value.(transaction.Id) - cleanupStack.Remove(currentStackEntry) - - tangle.DeleteTransaction(currentTransactionId) - - tangle.GetApprovers(currentTransactionId).Consume(func(approver *approver.Approver) { - approverId := approver.GetApprovingTransactionId() - - if _, transactionProcessed := processedTransactions[approverId]; !transactionProcessed { - cleanupStack.PushBack(approverId) - - processedTransactions[approverId] = types.Void - } - }) - } -} diff --git a/packages/binary/tangle/tangle_test.go b/packages/binary/tangle/tangle_test.go deleted file mode 100644 index c8ff887c1f0659f340749dd564f3d7f001811be2..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/tangle_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package tangle - -import ( - "fmt" - "testing" - "time" - - "github.com/dgraph-io/badger/v2" - "github.com/iotaledger/hive.go/events" - - "github.com/iotaledger/hive.go/database" - - "github.com/iotaledger/goshimmer/packages/binary/identity" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload/data" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transactionmetadata" - "github.com/iotaledger/goshimmer/plugins/config" -) - -var testDatabase *badger.DB - -var _ = config.PLUGIN - -func init() { - testDatabase = database.GetBadgerInstance() -} - -func BenchmarkTangle_AttachTransaction(b *testing.B) { - tangle := New(testDatabase, []byte("TEST_BINARY_TANGLE")) - if err := tangle.Prune(); err != nil { - b.Error(err) - - return - } - - testIdentity := identity.Generate() - - transactionBytes := make([]*transaction.Transaction, b.N) - for i := 0; i < b.N; i++ { - transactionBytes[i] = transaction.New(transaction.EmptyId, transaction.EmptyId, testIdentity, data.New([]byte("some data"))) - transactionBytes[i].GetBytes() - } - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - tangle.AttachTransaction(transactionBytes[i]) - } - - tangle.Shutdown() -} - -func TestTangle_AttachTransaction(t *testing.T) { - tangle := New(testDatabase, []byte("TEST_BINARY_TANGLE")) - if err := tangle.Prune(); err != nil { - t.Error(err) - - return - } - - tangle.Events.TransactionAttached.Attach(events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *transactionmetadata.CachedTransactionMetadata) { - cachedTransaction.Consume(func(transaction *transaction.Transaction) { - fmt.Println("ATTACHED:", transaction.GetId()) - }) - })) - - tangle.Events.TransactionSolid.Attach(events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *transactionmetadata.CachedTransactionMetadata) { - cachedTransaction.Consume(func(transaction *transaction.Transaction) { - fmt.Println("SOLID:", transaction.GetId()) - }) - })) - - tangle.Events.TransactionUnsolidifiable.Attach(events.NewClosure(func(transactionId transaction.Id) { - fmt.Println("UNSOLIDIFIABLE:", transactionId) - })) - - tangle.Events.TransactionMissing.Attach(events.NewClosure(func(transactionId transaction.Id) { - fmt.Println("MISSING:", transactionId) - })) - - tangle.Events.TransactionRemoved.Attach(events.NewClosure(func(transactionId transaction.Id) { - fmt.Println("REMOVED:", transactionId) - })) - - newTransaction1 := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("some data"))) - newTransaction2 := transaction.New(newTransaction1.GetId(), newTransaction1.GetId(), identity.Generate(), data.New([]byte("some other data"))) - - tangle.AttachTransaction(newTransaction2) - - time.Sleep(7 * time.Second) - - tangle.AttachTransaction(newTransaction1) - - tangle.Shutdown() -} diff --git a/packages/binary/tangle/transactionparser/builtinfilters/transaction_signature_filter.go b/packages/binary/tangle/transactionparser/builtinfilters/transaction_signature_filter.go deleted file mode 100644 index 9160d821cfa2ff6c1d1946ca34953010f8ddf38b..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionparser/builtinfilters/transaction_signature_filter.go +++ /dev/null @@ -1,66 +0,0 @@ -package builtinfilters - -import ( - "sync" - - "github.com/iotaledger/hive.go/async" - - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" -) - -type TransactionSignatureFilter struct { - onAcceptCallback func(tx *transaction.Transaction) - onRejectCallback func(tx *transaction.Transaction) - workerPool async.WorkerPool - - onAcceptCallbackMutex sync.RWMutex - onRejectCallbackMutex sync.RWMutex -} - -func NewTransactionSignatureFilter() (result *TransactionSignatureFilter) { - result = &TransactionSignatureFilter{} - - return -} - -func (filter *TransactionSignatureFilter) Filter(tx *transaction.Transaction) { - filter.workerPool.Submit(func() { - if tx.VerifySignature() { - filter.getAcceptCallback()(tx) - } else { - filter.getRejectCallback()(tx) - } - }) -} - -func (filter *TransactionSignatureFilter) OnAccept(callback func(tx *transaction.Transaction)) { - filter.onAcceptCallbackMutex.Lock() - filter.onAcceptCallback = callback - filter.onAcceptCallbackMutex.Unlock() -} - -func (filter *TransactionSignatureFilter) OnReject(callback func(tx *transaction.Transaction)) { - filter.onRejectCallbackMutex.Lock() - filter.onRejectCallback = callback - filter.onRejectCallbackMutex.Unlock() -} - -func (filter *TransactionSignatureFilter) Shutdown() { - filter.workerPool.ShutdownGracefully() -} - -func (filter *TransactionSignatureFilter) getAcceptCallback() (result func(tx *transaction.Transaction)) { - filter.onAcceptCallbackMutex.RLock() - result = filter.onAcceptCallback - filter.onAcceptCallbackMutex.RUnlock() - - return -} - -func (filter *TransactionSignatureFilter) getRejectCallback() (result func(tx *transaction.Transaction)) { - filter.onRejectCallbackMutex.RLock() - result = filter.onRejectCallback - filter.onRejectCallbackMutex.RUnlock() - - return -} diff --git a/packages/binary/tangle/transactionparser/bytes_filter.go b/packages/binary/tangle/transactionparser/bytes_filter.go deleted file mode 100644 index c8e2bab61a1ff376f860cd97c7dfa640dda9286d..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionparser/bytes_filter.go +++ /dev/null @@ -1,8 +0,0 @@ -package transactionparser - -type BytesFilter interface { - Filter(bytes []byte) - OnAccept(callback func(bytes []byte)) - OnReject(callback func(bytes []byte)) - Shutdown() -} diff --git a/packages/binary/tangle/transactionparser/events.go b/packages/binary/tangle/transactionparser/events.go deleted file mode 100644 index 9bde1a04963fa72ec3f53bd91cd81947e66e886c..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionparser/events.go +++ /dev/null @@ -1,9 +0,0 @@ -package transactionparser - -import "github.com/iotaledger/hive.go/events" - -type transactionParserEvents struct { - BytesRejected *events.Event - TransactionParsed *events.Event - TransactionRejected *events.Event -} diff --git a/packages/binary/tangle/transactionparser/transaction_filter.go b/packages/binary/tangle/transactionparser/transaction_filter.go deleted file mode 100644 index 39dfc277c5932c6f6ce1ee8cca2d525605c04235..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionparser/transaction_filter.go +++ /dev/null @@ -1,12 +0,0 @@ -package transactionparser - -import ( - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" -) - -type TransactionFilter interface { - Filter(tx *transaction.Transaction) - OnAccept(callback func(tx *transaction.Transaction)) - OnReject(callback func(tx *transaction.Transaction)) - Shutdown() -} diff --git a/packages/binary/tangle/transactionparser/transactionparser.go b/packages/binary/tangle/transactionparser/transactionparser.go deleted file mode 100644 index 1d5f53660d3b4b3714e26377a686ea1969f4ab82..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionparser/transactionparser.go +++ /dev/null @@ -1,137 +0,0 @@ -package transactionparser - -import ( - "sync" - - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" - "github.com/iotaledger/goshimmer/packages/binary/tangle/transactionparser/builtinfilters" - - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/typeutils" -) - -type TransactionParser struct { - bytesFilters []BytesFilter - transactionFilters []TransactionFilter - Events transactionParserEvents - - byteFiltersModified typeutils.AtomicBool - transactionFiltersModified typeutils.AtomicBool - bytesFiltersMutex sync.Mutex - transactionFiltersMutex sync.Mutex -} - -func New() (result *TransactionParser) { - result = &TransactionParser{ - bytesFilters: make([]BytesFilter, 0), - transactionFilters: make([]TransactionFilter, 0), - - Events: transactionParserEvents{ - BytesRejected: events.NewEvent(func(handler interface{}, params ...interface{}) { - handler.(func([]byte))(params[0].([]byte)) - }), - TransactionParsed: events.NewEvent(func(handler interface{}, params ...interface{}) { - handler.(func(*transaction.Transaction))(params[0].(*transaction.Transaction)) - }), - TransactionRejected: events.NewEvent(func(handler interface{}, params ...interface{}) { - handler.(func(*transaction.Transaction))(params[0].(*transaction.Transaction)) - }), - }, - } - - // add builtin filters - result.AddBytesFilter(builtinfilters.NewRecentlySeenBytesFilter()) - result.AddTransactionsFilter(builtinfilters.NewTransactionSignatureFilter()) - - return -} - -func (transactionParser *TransactionParser) Parse(transactionBytes []byte) { - transactionParser.setupBytesFilterDataFlow() - transactionParser.setupTransactionsFilterDataFlow() - - transactionParser.bytesFilters[0].Filter(transactionBytes) -} - -func (transactionParser *TransactionParser) AddBytesFilter(filter BytesFilter) { - transactionParser.bytesFiltersMutex.Lock() - transactionParser.bytesFilters = append(transactionParser.bytesFilters, filter) - transactionParser.bytesFiltersMutex.Unlock() - - transactionParser.byteFiltersModified.Set() -} - -func (transactionParser *TransactionParser) AddTransactionsFilter(filter TransactionFilter) { - transactionParser.transactionFiltersMutex.Lock() - transactionParser.transactionFilters = append(transactionParser.transactionFilters, filter) - transactionParser.transactionFiltersMutex.Unlock() - - transactionParser.transactionFiltersModified.Set() -} - -func (transactionParser *TransactionParser) Shutdown() { - transactionParser.bytesFiltersMutex.Lock() - for _, bytesFilter := range transactionParser.bytesFilters { - bytesFilter.Shutdown() - } - transactionParser.bytesFiltersMutex.Unlock() - - transactionParser.transactionFiltersMutex.Lock() - for _, transactionFilter := range transactionParser.transactionFilters { - transactionFilter.Shutdown() - } - transactionParser.transactionFiltersMutex.Unlock() -} - -func (transactionParser *TransactionParser) setupBytesFilterDataFlow() { - if !transactionParser.byteFiltersModified.IsSet() { - return - } - - transactionParser.bytesFiltersMutex.Lock() - if transactionParser.byteFiltersModified.IsSet() { - transactionParser.byteFiltersModified.SetTo(false) - - numberOfBytesFilters := len(transactionParser.bytesFilters) - for i := 0; i < numberOfBytesFilters; i++ { - if i == numberOfBytesFilters-1 { - transactionParser.bytesFilters[i].OnAccept(transactionParser.parseTransaction) - } else { - transactionParser.bytesFilters[i].OnAccept(transactionParser.bytesFilters[i+1].Filter) - } - transactionParser.bytesFilters[i].OnReject(func(bytes []byte) { transactionParser.Events.BytesRejected.Trigger(bytes) }) - } - } - transactionParser.bytesFiltersMutex.Unlock() -} - -func (transactionParser *TransactionParser) setupTransactionsFilterDataFlow() { - if !transactionParser.transactionFiltersModified.IsSet() { - return - } - - transactionParser.transactionFiltersMutex.Lock() - if transactionParser.transactionFiltersModified.IsSet() { - transactionParser.transactionFiltersModified.SetTo(false) - - numberOfTransactionFilters := len(transactionParser.transactionFilters) - for i := 0; i < numberOfTransactionFilters; i++ { - if i == numberOfTransactionFilters-1 { - transactionParser.transactionFilters[i].OnAccept(func(tx *transaction.Transaction) { transactionParser.Events.TransactionParsed.Trigger(tx) }) - } else { - transactionParser.transactionFilters[i].OnAccept(transactionParser.transactionFilters[i+1].Filter) - } - transactionParser.transactionFilters[i].OnReject(func(tx *transaction.Transaction) { transactionParser.Events.TransactionRejected.Trigger(tx) }) - } - } - transactionParser.transactionFiltersMutex.Unlock() -} - -func (transactionParser *TransactionParser) parseTransaction(bytes []byte) { - if parsedTransaction, err := transaction.FromBytes(bytes); err != nil { - // trigger parsingError - panic(err) - } else { - transactionParser.transactionFilters[0].Filter(parsedTransaction) - } -} diff --git a/packages/binary/tangle/transactionparser/transactionparser_test.go b/packages/binary/tangle/transactionparser/transactionparser_test.go deleted file mode 100644 index c7dc3b18a91c82260b4196d7794e499cabec13c1..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionparser/transactionparser_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package transactionparser - -import ( - "fmt" - "strconv" - "testing" - - "github.com/iotaledger/hive.go/events" - - "github.com/iotaledger/goshimmer/packages/binary/identity" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload/data" -) - -func BenchmarkTransactionParser_ParseBytesSame(b *testing.B) { - txBytes := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("Test"))).GetBytes() - txParser := New() - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - txParser.Parse(txBytes) - } - - txParser.Shutdown() -} - -func BenchmarkTransactionParser_ParseBytesDifferent(b *testing.B) { - transactionBytes := make([][]byte, b.N) - for i := 0; i < b.N; i++ { - transactionBytes[i] = transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("Test"+strconv.Itoa(i)))).GetBytes() - } - - txParser := New() - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - txParser.Parse(transactionBytes[i]) - } - - txParser.Shutdown() -} - -func TestTransactionParser_ParseTransaction(t *testing.T) { - tx := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("Test"))) - - txParser := New() - txParser.Parse(tx.GetBytes()) - - txParser.Events.TransactionParsed.Attach(events.NewClosure(func(tx *transaction.Transaction) { - fmt.Println("PARSED!!!") - })) - - txParser.Shutdown() -} diff --git a/packages/binary/tangle/transactionrequester/constants.go b/packages/binary/tangle/transactionrequester/constants.go deleted file mode 100644 index b9f59769fe276ba7d9ba7b68267aff806599b3a2..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionrequester/constants.go +++ /dev/null @@ -1,10 +0,0 @@ -package transactionrequester - -import ( - "time" -) - -const ( - DEFAULT_REQUEST_WORKER_COUNT = 1024 - DEFAULT_RETRY_INTERVAL = 10 * time.Second -) diff --git a/packages/binary/tangle/transactionrequester/events.go b/packages/binary/tangle/transactionrequester/events.go deleted file mode 100644 index e845d790496fc0c849c9ca0d4c81a7bfa2fefba2..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionrequester/events.go +++ /dev/null @@ -1,9 +0,0 @@ -package transactionrequester - -import ( - "github.com/iotaledger/hive.go/events" -) - -type Events struct { - SendRequest *events.Event -} diff --git a/packages/binary/tangle/transactionrequester/transactionrequester.go b/packages/binary/tangle/transactionrequester/transactionrequester.go deleted file mode 100644 index 6f036e810abd8f17844ec0bd5f1ffb8c06a3c024..0000000000000000000000000000000000000000 --- a/packages/binary/tangle/transactionrequester/transactionrequester.go +++ /dev/null @@ -1,74 +0,0 @@ -package transactionrequester - -import ( - "sync" - "time" - - "github.com/iotaledger/hive.go/async" - "github.com/iotaledger/hive.go/events" - - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" -) - -type TransactionRequester struct { - scheduledRequests map[transaction.Id]*time.Timer - requestWorker async.NonBlockingWorkerPool - options *Options - Events Events - - scheduledRequestsMutex sync.RWMutex -} - -func New(optionalOptions ...Option) *TransactionRequester { - requester := &TransactionRequester{ - scheduledRequests: make(map[transaction.Id]*time.Timer), - options: newOptions(optionalOptions), - Events: Events{ - SendRequest: events.NewEvent(func(handler interface{}, params ...interface{}) { - handler.(func(transaction.Id))(params[0].(transaction.Id)) - }), - }, - } - - requester.requestWorker.Tune(requester.options.workerCount) - - return requester -} - -func (requester *TransactionRequester) ScheduleRequest(transactionId transaction.Id) { - var retryRequest func(bool) - retryRequest = func(initialRequest bool) { - requester.requestWorker.Submit(func() { - requester.scheduledRequestsMutex.RLock() - if _, requestExists := requester.scheduledRequests[transactionId]; !initialRequest && !requestExists { - requester.scheduledRequestsMutex.RUnlock() - - return - } - requester.scheduledRequestsMutex.RUnlock() - - requester.Events.SendRequest.Trigger(transactionId) - - requester.scheduledRequestsMutex.Lock() - requester.scheduledRequests[transactionId] = time.AfterFunc(requester.options.retryInterval, func() { retryRequest(false) }) - requester.scheduledRequestsMutex.Unlock() - }) - } - - retryRequest(true) -} - -func (requester *TransactionRequester) StopRequest(transactionId transaction.Id) { - requester.scheduledRequestsMutex.RLock() - if timer, timerExists := requester.scheduledRequests[transactionId]; timerExists { - requester.scheduledRequestsMutex.RUnlock() - - timer.Stop() - - requester.scheduledRequestsMutex.Lock() - delete(requester.scheduledRequests, transactionId) - requester.scheduledRequestsMutex.Unlock() - } else { - requester.scheduledRequestsMutex.RUnlock() - } -} diff --git a/packages/client/address.go b/packages/client/address.go deleted file mode 100644 index 9107cd39b3e9448c1eedc9964038885ba8e79985..0000000000000000000000000000000000000000 --- a/packages/client/address.go +++ /dev/null @@ -1,30 +0,0 @@ -package client - -import ( - "github.com/iotaledger/iota.go/consts" - "github.com/iotaledger/iota.go/trinary" -) - -type Address struct { - trytes trinary.Trytes - securityLevel consts.SecurityLevel - privateKey trinary.Trits -} - -func NewAddress(trytes trinary.Trytes) *Address { - return &Address{ - trytes: trytes, - } -} - -func (address *Address) GetTrytes() trinary.Trytes { - return address.trytes -} - -func (address *Address) GetSecurityLevel() consts.SecurityLevel { - return address.securityLevel -} - -func (address *Address) GetPrivateKey() trinary.Trits { - return address.privateKey -} diff --git a/packages/client/bundle.go b/packages/client/bundle.go deleted file mode 100644 index da25cb6f3ad615eb5a1b7e6e68edeaa33961e338..0000000000000000000000000000000000000000 --- a/packages/client/bundle.go +++ /dev/null @@ -1,39 +0,0 @@ -package client - -import ( - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/iota.go/curl" - "github.com/iotaledger/iota.go/trinary" -) - -type Bundle struct { - essenceHash trinary.Trytes - transactions []*value_transaction.ValueTransaction -} - -func (bundle *Bundle) GetEssenceHash() trinary.Trytes { - return bundle.essenceHash -} - -func (bundle *Bundle) GetTransactions() []*value_transaction.ValueTransaction { - return bundle.transactions -} - -func CalculateBundleHash(transactions []*value_transaction.ValueTransaction) trinary.Trytes { - var lastInputAddress trinary.Trytes - - var concatenatedBundleEssences = make(trinary.Trits, len(transactions)*value_transaction.BUNDLE_ESSENCE_SIZE) - for i, bundleTransaction := range transactions { - if bundleTransaction.GetValue() <= 0 { - lastInputAddress = bundleTransaction.GetAddress() - } - - copy(concatenatedBundleEssences[value_transaction.BUNDLE_ESSENCE_SIZE*i:value_transaction.BUNDLE_ESSENCE_SIZE*(i+1)], bundleTransaction.GetBundleEssence(lastInputAddress != bundleTransaction.GetAddress())) - } - - bundleHash, err := curl.HashTrits(concatenatedBundleEssences) - if err != nil { - panic(err) - } - return trinary.MustTritsToTrytes(bundleHash) -} diff --git a/packages/client/bundlefactory.go b/packages/client/bundlefactory.go deleted file mode 100644 index dc2d653493548dd64f63969c9ffe697da29d1a3f..0000000000000000000000000000000000000000 --- a/packages/client/bundlefactory.go +++ /dev/null @@ -1,145 +0,0 @@ -package client - -import ( - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/iota.go/consts" - "github.com/iotaledger/iota.go/converter" - "github.com/iotaledger/iota.go/signing" - "github.com/iotaledger/iota.go/trinary" -) - -type BundleFactory struct { - inputs []bundleFactoryInputEntry - outputs []bundleFactoryOutputEntry -} - -func NewBundleFactory() *BundleFactory { - return &BundleFactory{ - inputs: make([]bundleFactoryInputEntry, 0), - outputs: make([]bundleFactoryOutputEntry, 0), - } -} - -func (bundleFactory *BundleFactory) AddInput(address *Address, value int64) { - bundleFactory.inputs = append(bundleFactory.inputs, bundleFactoryInputEntry{ - address: address, - value: value, - }) -} - -func (bundleFactory *BundleFactory) AddOutput(address *Address, value int64, message ...string) { - if len(message) >= 1 { - messageTrytes, err := converter.ASCIIToTrytes(message[0]) - if err != nil { - panic(err) - } - - bundleFactory.outputs = append(bundleFactory.outputs, bundleFactoryOutputEntry{ - address: address, - value: value, - message: trinary.MustPad(messageTrytes, value_transaction.SIGNATURE_MESSAGE_FRAGMENT_SIZE), - }) - } else { - bundleFactory.outputs = append(bundleFactory.outputs, bundleFactoryOutputEntry{ - address: address, - value: value, - }) - } -} - -func (bundleFactory *BundleFactory) GenerateBundle(branchTransactionHash trinary.Trytes, trunkTransactionHash trinary.Trytes) *Bundle { - transactions := bundleFactory.generateTransactions() - - bundleHash := bundleFactory.signTransactions(transactions) - - bundleFactory.connectTransactions(transactions, branchTransactionHash, trunkTransactionHash) - - return &Bundle{ - essenceHash: bundleHash, - transactions: transactions, - } -} - -func (bundleFactory *BundleFactory) generateTransactions() []*value_transaction.ValueTransaction { - transactions := make([]*value_transaction.ValueTransaction, 0) - - for _, input := range bundleFactory.inputs { - transaction := value_transaction.New() - transaction.SetValue(input.value) - transaction.SetAddress(input.address.trytes) - - transactions = append(transactions, transaction) - - for i := 1; i < int(input.address.securityLevel); i++ { - transaction := value_transaction.New() - transaction.SetValue(0) - transaction.SetAddress(input.address.trytes) - - transactions = append(transactions, transaction) - } - } - - for _, output := range bundleFactory.outputs { - transaction := value_transaction.New() - transaction.SetValue(output.value) - transaction.SetAddress(output.address.trytes) - - if len(output.message) != 0 { - transaction.SetSignatureMessageFragment(output.message) - } - - transactions = append(transactions, transaction) - } - - transactions[0].SetHead(true) - transactions[len(transactions)-1].SetTail(true) - - return transactions -} - -func (bundleFactory *BundleFactory) signTransactions(transactions []*value_transaction.ValueTransaction) trinary.Trytes { - bundleHash := CalculateBundleHash(transactions) - normalizedBundleHash := signing.NormalizedBundleHash(bundleHash) - - signedTransactions := 0 - for _, input := range bundleFactory.inputs { - securityLevel := input.address.securityLevel - privateKey := input.address.privateKey - - for i := 0; i < int(securityLevel); i++ { - signedFragTrits, _ := signing.SignatureFragment( - normalizedBundleHash[i*consts.HashTrytesSize/3:(i+1)*consts.HashTrytesSize/3], - privateKey[i*consts.KeyFragmentLength:(i+1)*consts.KeyFragmentLength], - ) - - transactions[signedTransactions].SetSignatureMessageFragment(trinary.MustTritsToTrytes(signedFragTrits)) - - signedTransactions++ - } - } - - return bundleHash -} - -func (bundleFactory *BundleFactory) connectTransactions(transactions []*value_transaction.ValueTransaction, branchTransactionHash trinary.Trytes, trunkTransactionHash trinary.Trytes) { - transactionCount := len(transactions) - - transactions[transactionCount-1].SetBranchTransactionHash(branchTransactionHash) - transactions[transactionCount-1].SetTrunkTransactionHash(trunkTransactionHash) - - for i := transactionCount - 2; i >= 0; i-- { - transactions[i].SetBranchTransactionHash(branchTransactionHash) - transactions[i].SetTrunkTransactionHash(transactions[i+1].GetHash()) - } -} - -type bundleFactoryInputEntry struct { - address *Address - value int64 -} - -type bundleFactoryOutputEntry struct { - address *Address - value int64 - message trinary.Trytes -} diff --git a/packages/client/seed.go b/packages/client/seed.go deleted file mode 100644 index c746f73cdbecfb68b74eab999a7069c11dfd7094..0000000000000000000000000000000000000000 --- a/packages/client/seed.go +++ /dev/null @@ -1,55 +0,0 @@ -package client - -import ( - "github.com/iotaledger/iota.go/address" - "github.com/iotaledger/iota.go/consts" - "github.com/iotaledger/iota.go/signing" - "github.com/iotaledger/iota.go/trinary" -) - -type Seed struct { - trytes trinary.Trytes - securityLevel consts.SecurityLevel - subSeeds map[uint64]trinary.Trits -} - -func NewSeed(trytes trinary.Trytes, securityLevel consts.SecurityLevel) *Seed { - return &Seed{ - trytes: trytes, - securityLevel: securityLevel, - subSeeds: make(map[uint64]trinary.Trits), - } -} - -func (seed *Seed) GetAddress(index uint64) *Address { - addressTrytes, err := address.GenerateAddress(seed.trytes, index, seed.securityLevel) - if err != nil { - panic(err) - } - - privateKey, err := signing.Key(seed.GetSubSeed(index), seed.securityLevel) - if err != nil { - panic(err) - } - - return &Address{ - trytes: addressTrytes, - securityLevel: seed.securityLevel, - privateKey: privateKey, - } -} - -func (seed *Seed) GetSubSeed(index uint64) trinary.Trits { - subSeed, subSeedExists := seed.subSeeds[index] - if !subSeedExists { - generatedSubSeed, err := signing.Subseed(seed.trytes, index) - if err != nil { - panic(err) - } - subSeed = generatedSubSeed - - seed.subSeeds[index] = subSeed - } - - return subSeed -} diff --git a/packages/database/badgerdb.go b/packages/database/badgerdb.go new file mode 100644 index 0000000000000000000000000000000000000000..4246add326298926822ae81a1a17c713b8da3f02 --- /dev/null +++ b/packages/database/badgerdb.go @@ -0,0 +1,98 @@ +package database + +import ( + "fmt" + "os" + "runtime" + + "github.com/dgraph-io/badger/v2" + "github.com/dgraph-io/badger/v2/options" + "github.com/iotaledger/hive.go/kvstore" + badgerstore "github.com/iotaledger/hive.go/kvstore/badger" +) + +const valueLogGCDiscardRatio = 0.1 + +type badgerDB struct { + *badger.DB +} + +// NewDB returns a new persisting DB object. +func NewDB(dirname string) (DB, error) { + // assure that the directory exists + err := createDir(dirname) + if err != nil { + return nil, fmt.Errorf("could not create DB directory: %w", err) + } + + opts := badger.DefaultOptions(dirname) + + opts.Logger = nil + opts.SyncWrites = false + opts.TableLoadingMode = options.MemoryMap + opts.ValueLogLoadingMode = options.MemoryMap + opts.CompactL0OnClose = false + opts.KeepL0InMemory = false + opts.VerifyValueChecksum = false + opts.ZSTDCompressionLevel = 1 + opts.Compression = options.None + opts.MaxCacheSize = 50000000 + opts.EventLogging = false + + if runtime.GOOS == "windows" { + opts = opts.WithTruncate(true) + } + + db, err := badger.Open(opts) + if err != nil { + return nil, fmt.Errorf("could not open DB: %w", err) + } + + return &badgerDB{DB: db}, nil +} + +func (db *badgerDB) NewStore() kvstore.KVStore { + return badgerstore.New(db.DB) +} + +// Close closes a DB. It's crucial to call it to ensure all the pending updates make their way to disk. +func (db *badgerDB) Close() error { + return db.DB.Close() +} + +func (db *badgerDB) RequiresGC() bool { + return true +} + +func (db *badgerDB) GC() error { + err := db.RunValueLogGC(valueLogGCDiscardRatio) + if err != nil { + return err + } + // trigger the go garbage collector to release the used memory + runtime.GC() + return nil +} + +// Returns whether the given file or directory exists. +func exists(path string) (bool, error) { + _, err := os.Stat(path) + if os.IsNotExist(err) { + return false, nil + } + if err != nil { + return false, err + } + return true, err +} + +func createDir(dirname string) error { + exists, err := exists(dirname) + if err != nil { + return err + } + if !exists { + return os.Mkdir(dirname, 0700) + } + return nil +} diff --git a/packages/database/database.go b/packages/database/database.go index 1a1465ca4a87055e1414a954443d2a3d07ec21ef..200cc67cfb75cddb22e574c79672948225f07cd3 100644 --- a/packages/database/database.go +++ b/packages/database/database.go @@ -1,87 +1,18 @@ package database import ( - "io/ioutil" - "os" - "runtime" - "sync" - - "github.com/dgraph-io/badger/v2" - "github.com/dgraph-io/badger/v2/options" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/hive.go/database" - "github.com/iotaledger/hive.go/logger" -) - -var ( - instance *badger.DB - once sync.Once - ErrKeyNotFound = database.ErrKeyNotFound + "github.com/iotaledger/hive.go/kvstore" ) -type ( - Database = database.Database - Entry = database.Entry - KeyOnlyEntry = database.KeyOnlyEntry - KeyPrefix = database.KeyPrefix - Key = database.Key - Value = database.Value -) - -func Get(dbPrefix byte, optionalBadger ...*badger.DB) (Database, error) { - return database.Get(dbPrefix, optionalBadger...) -} - -func GetBadgerInstance() *badger.DB { - once.Do(func() { - dbDir := parameter.NodeConfig.GetString(CFG_DIRECTORY) - - var dbDirClear bool - // check whether the database is new, by checking whether any file exists within - // the database directory - fileInfos, err := ioutil.ReadDir(dbDir) - if err != nil { - // panic on other errors, for example permission related - if !os.IsNotExist(err) { - panic(err) - } - dbDirClear = true - } - if len(fileInfos) == 0 { - dbDirClear = true - } - - opts := badger.DefaultOptions(dbDir) - opts.Logger = nil - if runtime.GOOS == "windows" { - opts = opts.WithTruncate(true) - } - - opts.CompactL0OnClose = false - opts.KeepL0InMemory = false - opts.VerifyValueChecksum = false - opts.ZSTDCompressionLevel = 1 - opts.Compression = options.None - opts.MaxCacheSize = 50000000 - - db, err := database.CreateDB(dbDir, opts) - if err != nil { - // errors should cause a panic to avoid singleton deadlocks - panic(err) - } - instance = db - - // up on the first caller, check whether the version of the database is compatible - checkDatabaseVersion(dbDirClear) - }) - return instance -} - -func CleanupBadgerInstance(log *logger.Logger) { - db := GetBadgerInstance() - log.Info("Running Badger database garbage collection") - var err error - for err == nil { - err = db.RunValueLogGC(0.7) - } +// DB represents a database abstraction. +type DB interface { + // NewStore creates a new KVStore backed by the database. + NewStore() kvstore.KVStore + // Close closes a DB. + Close() error + + // RequiresGC returns whether the database requires a call of GC() to clean deleted items. + RequiresGC() bool + // GC runs the garbage collection to clean deleted database items. + GC() error } diff --git a/packages/database/mapdb/mapdb.go b/packages/database/mapdb/mapdb.go deleted file mode 100644 index e9627130049cc2b2a7bcba0787c2c30036d420ab..0000000000000000000000000000000000000000 --- a/packages/database/mapdb/mapdb.go +++ /dev/null @@ -1,220 +0,0 @@ -// Package mapdb provides a map implementation of a key value database. -// It offers a lightweight drop-in replacement of hive.go/database for tests or in simulations -// where more than one instance is required. -package mapdb - -import ( - "strings" - "sync" - - "github.com/iotaledger/hive.go/database" - "github.com/iotaledger/hive.go/typeutils" -) - -// MapDB is a simple implementation of DB using a map. -type MapDB struct { - mu sync.RWMutex - m map[string]mapEntry -} - -type mapEntry struct { - value []byte - meta byte -} - -// NewMapDB creates a database.Database implementation purely based on a go map. -// MapDB does not support TTL. -func NewMapDB() *MapDB { - return &MapDB{ - m: make(map[string]mapEntry), - } -} - -func (db *MapDB) Contains(key database.Key) (contains bool, err error) { - db.mu.RLock() - defer db.mu.RUnlock() - - _, contains = db.m[typeutils.BytesToString(key)] - return -} - -func (db *MapDB) Get(key database.Key) (entry database.Entry, err error) { - db.mu.RLock() - defer db.mu.RUnlock() - - ent, contains := db.m[typeutils.BytesToString(key)] - if !contains { - err = database.ErrKeyNotFound - return - } - entry.Key = key - entry.Value = append([]byte{}, ent.value...) - entry.Meta = ent.meta - return -} - -func (db *MapDB) GetKeyOnly(key database.Key) (entry database.KeyOnlyEntry, err error) { - db.mu.RLock() - defer db.mu.RUnlock() - - ent, contains := db.m[typeutils.BytesToString(key)] - if !contains { - err = database.ErrKeyNotFound - return - } - entry.Key = key - entry.Meta = ent.meta - return -} - -func (db *MapDB) Set(entry database.Entry) error { - db.mu.Lock() - defer db.mu.Unlock() - - db.m[typeutils.BytesToString(entry.Key)] = mapEntry{ - value: append([]byte{}, entry.Value...), - meta: entry.Meta, - } - return nil -} - -func (db *MapDB) Delete(key database.Key) error { - db.mu.Lock() - defer db.mu.Unlock() - - delete(db.m, typeutils.BytesToString(key)) - return nil -} - -func (db *MapDB) DeletePrefix(keyPrefix database.KeyPrefix) error { - db.mu.Lock() - defer db.mu.Unlock() - - prefix := typeutils.BytesToString(keyPrefix) - for key := range db.m { - if strings.HasPrefix(key, prefix) { - delete(db.m, key) - } - } - return nil -} - -func (db *MapDB) ForEach(consume func(entry database.Entry) bool) error { - db.mu.RLock() - defer db.mu.RUnlock() - - for key, ent := range db.m { - entry := database.Entry{ - Key: []byte(key), - Value: append([]byte{}, ent.value...), - Meta: ent.meta, - } - if consume(entry) { - break - } - } - return nil -} - -func (db *MapDB) ForEachKeyOnly(consume func(entry database.KeyOnlyEntry) bool) error { - db.mu.RLock() - defer db.mu.RUnlock() - - for key, ent := range db.m { - entry := database.KeyOnlyEntry{ - Key: []byte(key), - Meta: ent.meta, - } - if consume(entry) { - break - } - } - return nil -} - -func (db *MapDB) ForEachPrefix(keyPrefix database.KeyPrefix, consume func(entry database.Entry) (stop bool)) error { - db.mu.RLock() - defer db.mu.RUnlock() - - prefix := typeutils.BytesToString(keyPrefix) - for key, ent := range db.m { - if strings.HasPrefix(key, prefix) { - entry := database.Entry{ - Key: []byte(strings.TrimPrefix(key, prefix)), - Value: append([]byte{}, ent.value...), - Meta: ent.meta, - } - if consume(entry) { - break - } - } - } - return nil -} - -func (db *MapDB) ForEachPrefixKeyOnly(keyPrefix database.KeyPrefix, consume func(entry database.KeyOnlyEntry) (stop bool)) error { - db.mu.RLock() - defer db.mu.RUnlock() - - prefix := typeutils.BytesToString(keyPrefix) - for key, ent := range db.m { - if strings.HasPrefix(key, prefix) { - entry := database.KeyOnlyEntry{ - Key: []byte(strings.TrimPrefix(key, prefix)), - Meta: ent.meta, - } - if consume(entry) { - break - } - } - } - return nil -} - -func (db *MapDB) StreamForEach(consume func(entry database.Entry) error) (err error) { - _ = db.ForEach(func(entry database.Entry) bool { - err = consume(entry) - return err != nil - }) - return -} - -func (db *MapDB) StreamForEachKeyOnly(consume func(entry database.KeyOnlyEntry) error) (err error) { - _ = db.ForEachKeyOnly(func(entry database.KeyOnlyEntry) bool { - err = consume(entry) - return err != nil - }) - return -} - -func (db *MapDB) StreamForEachPrefix(keyPrefix database.KeyPrefix, consume func(entry database.Entry) error) (err error) { - _ = db.ForEachPrefix(keyPrefix, func(entry database.Entry) bool { - err = consume(entry) - return err != nil - }) - return -} - -func (db *MapDB) StreamForEachPrefixKeyOnly(keyPrefix database.KeyPrefix, consume func(database.KeyOnlyEntry) error) (err error) { - _ = db.ForEachPrefixKeyOnly(keyPrefix, func(entry database.KeyOnlyEntry) bool { - err = consume(entry) - return err != nil - }) - return -} - -func (db *MapDB) Apply(set []database.Entry, del []database.Key) error { - db.mu.Lock() - defer db.mu.Unlock() - - for _, entry := range set { - db.m[typeutils.BytesToString(entry.Key)] = mapEntry{ - value: append([]byte{}, entry.Value...), - meta: entry.Meta, - } - } - for _, key := range del { - delete(db.m, typeutils.BytesToString(key)) - } - return nil -} diff --git a/packages/database/memdb.go b/packages/database/memdb.go new file mode 100644 index 0000000000000000000000000000000000000000..2ff8d979774021e9a61584f3fea326858437e8d2 --- /dev/null +++ b/packages/database/memdb.go @@ -0,0 +1,32 @@ +package database + +import ( + "github.com/iotaledger/hive.go/kvstore" + "github.com/iotaledger/hive.go/kvstore/mapdb" +) + +type memDB struct { + *mapdb.MapDB +} + +// NewMemDB returns a new in-memory (not persisted) DB object. +func NewMemDB() (DB, error) { + return &memDB{MapDB: mapdb.NewMapDB()}, nil +} + +func (db *memDB) NewStore() kvstore.KVStore { + return db.MapDB +} + +func (db *memDB) Close() error { + db.MapDB = nil + return nil +} + +func (db *memDB) RequiresGC() bool { + return false +} + +func (db *memDB) GC() error { + return nil +} diff --git a/packages/database/parameters.go b/packages/database/parameters.go deleted file mode 100644 index 8d647e65a59ea193f461fa9b6a5292e24f1435aa..0000000000000000000000000000000000000000 --- a/packages/database/parameters.go +++ /dev/null @@ -1,13 +0,0 @@ -package database - -import ( - flag "github.com/spf13/pflag" -) - -const ( - CFG_DIRECTORY = "database.directory" -) - -func init() { - flag.String(CFG_DIRECTORY, "mainnetdb", "path to the database folder") -} diff --git a/packages/database/prefixes.go b/packages/database/prefix/prefix.go similarity index 79% rename from packages/database/prefixes.go rename to packages/database/prefix/prefix.go index c9dc488d40b5fbe557467e1be275e6aa56052aec..ddfbad3bdfd918c73f48fdd7ba33b87b55acab9a 100644 --- a/packages/database/prefixes.go +++ b/packages/database/prefix/prefix.go @@ -1,4 +1,4 @@ -package database +package prefix const ( DBPrefixApprovers byte = iota @@ -7,5 +7,5 @@ const ( DBPrefixTransactionMetadata DBPrefixAddressTransactions DBPrefixAutoPeering - DBPrefixDatabaseVersion + DBPrefixHealth ) diff --git a/packages/database/versioning.go b/packages/database/versioning.go deleted file mode 100644 index a848eb0e508a7ecbf3b9c61773700fdfdaa79b1c..0000000000000000000000000000000000000000 --- a/packages/database/versioning.go +++ /dev/null @@ -1,47 +0,0 @@ -package database - -import ( - "errors" - "fmt" -) - -const ( - // DBVersion defines the version of the database schema this version of GoShimmer supports. - // everytime there's a breaking change regarding the stored data, this version flag should be adjusted. - DBVersion = 1 -) - -var ( - ErrDBVersionIncompatible = errors.New("database version is not compatible. please delete your database folder and restart") - // the key under which the database is stored - dbVersionKey = []byte{0} -) - -// checks whether the database is compatible with the current schema version. -// also automatically sets the version if the database is new. -func checkDatabaseVersion(dbIsNew bool) { - dbInstance, err := Get(DBPrefixDatabaseVersion, instance) - if err != nil { - panic(err) - } - - if dbIsNew { - // store db version for the first time in the new database - if err = dbInstance.Set(Entry{Key: dbVersionKey, Value: []byte{DBVersion}}); err != nil { - panic(fmt.Sprintf("unable to persist db version number: %s", err.Error())) - } - return - } - - // db version must be available - entry, err := dbInstance.Get(dbVersionKey) - if err != nil { - if err == ErrKeyNotFound { - panic(err) - } - panic(fmt.Errorf("%w: no database version was persisted", ErrDBVersionIncompatible)) - } - if entry.Value[0] != DBVersion { - panic(fmt.Errorf("%w: supported version: %d, version of database: %d", ErrDBVersionIncompatible, DBVersion, entry.Value[0])) - } -} diff --git a/packages/gossip/common.go b/packages/gossip/common.go index 237e11ab3608c0d557ee7e84533e8ef4f21afea4..854d7214deccf4d4e64bd4df3e4d7c9fc4f481b3 100644 --- a/packages/gossip/common.go +++ b/packages/gossip/common.go @@ -1,6 +1,9 @@ package gossip import ( + "net" + "strconv" + "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/peer/service" ) @@ -12,9 +15,9 @@ func IsSupported(p *peer.Peer) bool { // GetAddress returns the address of the gossip service. func GetAddress(p *peer.Peer) string { - gossip := p.Services().Get(service.GossipKey) - if gossip == nil { - panic("peer does not support gossip") + gossipEndpoint := p.Services().Get(service.GossipKey) + if gossipEndpoint == nil { + panic("peer does not support gossipEndpoint") } - return gossip.String() + return net.JoinHostPort(p.IP().String(), strconv.Itoa(gossipEndpoint.Port())) } diff --git a/packages/gossip/errors.go b/packages/gossip/errors.go index 554e38618c97aff2cda1b3c97cc3cbd805a6888d..4c217b59304599eb96d781a00951218c24cb8237 100644 --- a/packages/gossip/errors.go +++ b/packages/gossip/errors.go @@ -3,10 +3,16 @@ package gossip import "errors" var ( - ErrNotStarted = errors.New("manager not started") - ErrClosed = errors.New("manager closed") - ErrNotANeighbor = errors.New("peer is not a neighbor") - ErrLoopback = errors.New("loopback connection not allowed") - ErrDuplicateNeighbor = errors.New("peer already connected") - ErrInvalidPacket = errors.New("invalid packet") + // ErrNotRunning is returned when a neighbor is added to a stopped or not yet started gossip manager. + ErrNotRunning = errors.New("manager not running") + // ErrUnknownNeighbor is returned when the specified neighbor is not known to the gossip manager. + ErrUnknownNeighbor = errors.New("unknown neighbor") + // ErrLoopbackNeighbor is returned when the own peer is specified as a neighbor. + ErrLoopbackNeighbor = errors.New("loopback connection not allowed") + // ErrDuplicateNeighbor is returned when the same peer is added more than once as a neighbor. + ErrDuplicateNeighbor = errors.New("already connected") + // ErrInvalidPacket is returned when the gossip manager receives an invalid packet. + ErrInvalidPacket = errors.New("invalid packet") + // ErrNeighborQueueFull is returned when the send queue is already full. + ErrNeighborQueueFull = errors.New("send queue is full") ) diff --git a/packages/gossip/events.go b/packages/gossip/events.go index 96bec6af5fa399c178f8f7235d48febc4f0f10a6..96f303c60a4e2aa89dd6aa17271a921af39c9bad 100644 --- a/packages/gossip/events.go +++ b/packages/gossip/events.go @@ -5,40 +5,34 @@ import ( "github.com/iotaledger/hive.go/events" ) -// Events contains all the events related to the gossip protocol. -var Events = struct { - // A ConnectionFailed event is triggered when a neighbor connection to a peer could not be established. +// Events defines all the events related to the gossip protocol. +type Events struct { + // Fired when an attempt to build a connection to a neighbor has failed. ConnectionFailed *events.Event - // A NeighborAdded event is triggered when a connection to a new neighbor has been established. + // Fired when a neighbor connection has been established. NeighborAdded *events.Event - // A NeighborRemoved event is triggered when a neighbor has been dropped. + // Fired when a neighbor has been removed. NeighborRemoved *events.Event - // A TransactionReceived event is triggered when a new transaction is received by the gossip protocol. - TransactionReceived *events.Event -}{ - ConnectionFailed: events.NewEvent(peerAndErrorCaller), - NeighborAdded: events.NewEvent(neighborCaller), - NeighborRemoved: events.NewEvent(peerCaller), - TransactionReceived: events.NewEvent(transactionReceived), + // Fired when a new message was received via the gossip protocol. + MessageReceived *events.Event } -type TransactionReceivedEvent struct { - Data []byte // transaction data - Peer *peer.Peer // peer that send the transaction +// MessageReceivedEvent holds data about a message received event. +type MessageReceivedEvent struct { + // The raw message. + Data []byte + // The sender of the message. + Peer *peer.Peer } func peerAndErrorCaller(handler interface{}, params ...interface{}) { handler.(func(*peer.Peer, error))(params[0].(*peer.Peer), params[1].(error)) } -func peerCaller(handler interface{}, params ...interface{}) { - handler.(func(*peer.Peer))(params[0].(*peer.Peer)) -} - func neighborCaller(handler interface{}, params ...interface{}) { handler.(func(*Neighbor))(params[0].(*Neighbor)) } -func transactionReceived(handler interface{}, params ...interface{}) { - handler.(func(*TransactionReceivedEvent))(params[0].(*TransactionReceivedEvent)) +func messageReceived(handler interface{}, params ...interface{}) { + handler.(func(*MessageReceivedEvent))(params[0].(*MessageReceivedEvent)) } diff --git a/packages/gossip/manager.go b/packages/gossip/manager.go index 49a9d0d9921b930a89fa2be9963a405039b6bc81..e31c6f78e2c33092774b7e9f0785d9b971234364 100644 --- a/packages/gossip/manager.go +++ b/packages/gossip/manager.go @@ -1,74 +1,89 @@ package gossip import ( - "errors" "fmt" "net" "sync" "github.com/golang/protobuf/proto" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" pb "github.com/iotaledger/goshimmer/packages/gossip/proto" "github.com/iotaledger/goshimmer/packages/gossip/server" + "github.com/iotaledger/hive.go/async" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/events" - "go.uber.org/zap" + "github.com/iotaledger/hive.go/identity" + "github.com/iotaledger/hive.go/logger" ) const ( maxPacketSize = 2048 ) -var ( - ErrNeighborManagerNotRunning = errors.New("neighbor manager is not running") - ErrNeighborAlreadyConnected = errors.New("neighbor is already connected") -) - -// GetTransaction defines a function that returns the transaction data with the given hash. -type GetTransaction func(txHash []byte) ([]byte, error) +// LoadMessageFunc defines a function that returns the message for the given id. +type LoadMessageFunc func(messageId message.Id) ([]byte, error) +// The Manager handles the connected neighbors. type Manager struct { - local *peer.Local - getTransaction GetTransaction - log *zap.SugaredLogger + local *peer.Local + loadMessageFunc LoadMessageFunc + log *logger.Logger + events Events wg sync.WaitGroup - mu sync.RWMutex + mu sync.Mutex srv *server.TCP - neighbors map[peer.ID]*Neighbor - running bool + neighbors map[identity.ID]*Neighbor + + // inboxWorkerPool defines a worker pool where all incoming messages are processed. + inboxWorkerPool async.WorkerPool } -func NewManager(local *peer.Local, f GetTransaction, log *zap.SugaredLogger) *Manager { - return &Manager{ - local: local, - getTransaction: f, - log: log, - srv: nil, - neighbors: make(map[peer.ID]*Neighbor), - running: false, +// NewManager creates a new Manager. +func NewManager(local *peer.Local, f LoadMessageFunc, log *logger.Logger) *Manager { + m := &Manager{ + local: local, + loadMessageFunc: f, + log: log, + events: Events{ + ConnectionFailed: events.NewEvent(peerAndErrorCaller), + NeighborAdded: events.NewEvent(neighborCaller), + NeighborRemoved: events.NewEvent(neighborCaller), + MessageReceived: events.NewEvent(messageReceived), + }, + srv: nil, + neighbors: make(map[identity.ID]*Neighbor), } + return m } +// Start starts the manager for the given TCP server. func (m *Manager) Start(srv *server.TCP) { m.mu.Lock() defer m.mu.Unlock() m.srv = srv - m.running = true } // Close stops the manager and closes all established connections. func (m *Manager) Close() { m.stop() m.wg.Wait() + + m.inboxWorkerPool.ShutdownGracefully() +} + +// Events returns the events related to the gossip protocol. +func (m *Manager) Events() Events { + return m.events } func (m *Manager) stop() { m.mu.Lock() defer m.mu.Unlock() - m.running = false + m.srv = nil // close all neighbor connections for _, nbr := range m.neighbors { @@ -78,72 +93,65 @@ func (m *Manager) stop() { // AddOutbound tries to add a neighbor by connecting to that peer. func (m *Manager) AddOutbound(p *peer.Peer) error { + m.mu.Lock() + defer m.mu.Unlock() + if p.ID() == m.local.ID() { - return ErrLoopback + return ErrLoopbackNeighbor } - var srv *server.TCP - m.mu.RLock() if m.srv == nil { - m.mu.RUnlock() - return ErrNotStarted + return ErrNotRunning } - srv = m.srv - m.mu.RUnlock() - - return m.addNeighbor(p, srv.DialPeer) + return m.addNeighbor(p, m.srv.DialPeer) } // AddInbound tries to add a neighbor by accepting an incoming connection from that peer. func (m *Manager) AddInbound(p *peer.Peer) error { + m.mu.Lock() + defer m.mu.Unlock() + if p.ID() == m.local.ID() { - return ErrLoopback + return ErrLoopbackNeighbor } - var srv *server.TCP - m.mu.RLock() if m.srv == nil { - m.mu.RUnlock() - return ErrNotStarted + return ErrNotRunning } - srv = m.srv - m.mu.RUnlock() - - return m.addNeighbor(p, srv.AcceptPeer) + return m.addNeighbor(p, m.srv.AcceptPeer) } -// NeighborRemoved disconnects the neighbor with the given ID. -func (m *Manager) DropNeighbor(id peer.ID) error { - n, err := m.removeNeighbor(id) - if err != nil { - return err +// DropNeighbor disconnects the neighbor with the given ID. +func (m *Manager) DropNeighbor(id identity.ID) error { + m.mu.Lock() + defer m.mu.Unlock() + + if _, ok := m.neighbors[id]; !ok { + return ErrUnknownNeighbor } - err = n.Close() - Events.NeighborRemoved.Trigger(n.Peer) - return err + n := m.neighbors[id] + delete(m.neighbors, id) + + return n.Close() } -// RequestTransaction requests the transaction with the given hash from the neighbors. +// RequestMessage requests the message with the given id from the neighbors. // If no peer is provided, all neighbors are queried. -func (m *Manager) RequestTransaction(txHash []byte, to ...peer.ID) { - req := &pb.TransactionRequest{ - Hash: txHash, - } - m.log.Debugw("send message", "type", "TRANSACTION_REQUEST", "to", to) - m.send(marshal(req), to...) +func (m *Manager) RequestMessage(messageId []byte, to ...identity.ID) { + msgReq := &pb.MessageRequest{Id: messageId} + m.send(marshal(msgReq), to...) } -// SendTransaction adds the given transaction data to the send queue of the neighbors. +// SendMessage adds the given message the send queue of the neighbors. // The actual send then happens asynchronously. If no peer is provided, it is send to all neighbors. -func (m *Manager) SendTransaction(txData []byte, to ...peer.ID) { - tx := &pb.Transaction{ - Data: txData, - } - m.log.Debugw("send message", "type", "TRANSACTION", "to", to) - m.send(marshal(tx), to...) +func (m *Manager) SendMessage(msgData []byte, to ...identity.ID) { + msg := &pb.Message{Data: msgData} + m.send(marshal(msg), to...) } -func (m *Manager) GetAllNeighbors() []*Neighbor { - m.mu.RLock() - defer m.mu.RUnlock() +// AllNeighbors returns all the neighbors that are currently connected. +func (m *Manager) AllNeighbors() []*Neighbor { + m.mu.Lock() + defer m.mu.Unlock() + result := make([]*Neighbor, 0, len(m.neighbors)) for _, n := range m.neighbors { result = append(result, n) @@ -151,18 +159,19 @@ func (m *Manager) GetAllNeighbors() []*Neighbor { return result } -func (m *Manager) getNeighbors(ids ...peer.ID) []*Neighbor { +func (m *Manager) getNeighbors(ids ...identity.ID) []*Neighbor { if len(ids) > 0 { - return m.getNeighborsById(ids) + return m.getNeighborsByID(ids) } - return m.GetAllNeighbors() + return m.AllNeighbors() } -func (m *Manager) getNeighborsById(ids []peer.ID) []*Neighbor { +func (m *Manager) getNeighborsByID(ids []identity.ID) []*Neighbor { result := make([]*Neighbor, 0, len(ids)) - m.mu.RLock() - defer m.mu.RUnlock() + m.mu.Lock() + defer m.mu.Unlock() + for _, id := range ids { if n, ok := m.neighbors[id]; ok { result = append(result, n) @@ -171,12 +180,12 @@ func (m *Manager) getNeighborsById(ids []peer.ID) []*Neighbor { return result } -func (m *Manager) send(b []byte, to ...peer.ID) { +func (m *Manager) send(b []byte, to ...identity.ID) { neighbors := m.getNeighbors(to...) for _, nbr := range neighbors { if _, err := nbr.Write(b); err != nil { - m.log.Warnw("send error", "err", err, "neighbor", nbr.Peer.Address()) + m.log.Warnw("send error", "peer-id", nbr.ID(), "err", err) } } } @@ -184,83 +193,74 @@ func (m *Manager) send(b []byte, to ...peer.ID) { func (m *Manager) addNeighbor(peer *peer.Peer, connectorFunc func(*peer.Peer) (net.Conn, error)) error { conn, err := connectorFunc(peer) if err != nil { - Events.ConnectionFailed.Trigger(peer, err) + m.events.ConnectionFailed.Trigger(peer, err) return err } - m.mu.Lock() - defer m.mu.Unlock() - if !m.running { - _ = conn.Close() - Events.ConnectionFailed.Trigger(peer, ErrNeighborManagerNotRunning) - return ErrClosed - } if _, ok := m.neighbors[peer.ID()]; ok { _ = conn.Close() - Events.ConnectionFailed.Trigger(peer, ErrNeighborAlreadyConnected) + m.events.ConnectionFailed.Trigger(peer, ErrDuplicateNeighbor) return ErrDuplicateNeighbor } // create and add the neighbor - n := NewNeighbor(peer, conn, m.log) - n.Events.Close.Attach(events.NewClosure(func() { _ = m.DropNeighbor(peer.ID()) })) - n.Events.ReceiveMessage.Attach(events.NewClosure(func(data []byte) { - if err := m.handlePacket(data, peer); err != nil { - m.log.Debugw("error handling packet", "err", err) - } + nbr := NewNeighbor(peer, conn, m.log) + nbr.Events.Close.Attach(events.NewClosure(func() { + // assure that the neighbor is removed and notify + _ = m.DropNeighbor(peer.ID()) + m.events.NeighborRemoved.Trigger(nbr) + })) + nbr.Events.ReceiveMessage.Attach(events.NewClosure(func(data []byte) { + dataCopy := make([]byte, len(data)) + copy(dataCopy, data) + m.inboxWorkerPool.Submit(func() { + if err := m.handlePacket(dataCopy, nbr); err != nil { + m.log.Debugw("error handling packet", "err", err) + } + }) })) - m.neighbors[peer.ID()] = n - n.Listen() - Events.NeighborAdded.Trigger(n) + m.neighbors[peer.ID()] = nbr + nbr.Listen() + m.events.NeighborAdded.Trigger(nbr) return nil } -func (m *Manager) removeNeighbor(id peer.ID) (*Neighbor, error) { - m.mu.Lock() - defer m.mu.Unlock() - if _, ok := m.neighbors[id]; !ok { - return nil, ErrNotANeighbor - } - n := m.neighbors[id] - delete(m.neighbors, id) - return n, nil -} - -func (m *Manager) handlePacket(data []byte, p *peer.Peer) error { +func (m *Manager) handlePacket(data []byte, nbr *Neighbor) error { // ignore empty packages if len(data) == 0 { return nil } - switch pb.MType(data[0]) { + switch pb.PacketType(data[0]) { - // Incoming Transaction - case pb.MTransaction: - msg := new(pb.Transaction) - if err := proto.Unmarshal(data[1:], msg); err != nil { + case pb.PacketMessage: + packet := new(pb.Message) + if err := proto.Unmarshal(data[1:], packet); err != nil { return fmt.Errorf("invalid packet: %w", err) } - m.log.Debugw("received message", "type", "TRANSACTION", "id", p.ID()) - Events.TransactionReceived.Trigger(&TransactionReceivedEvent{Data: msg.GetData(), Peer: p}) - - // Incoming Transaction request - case pb.MTransactionRequest: + m.events.MessageReceived.Trigger(&MessageReceivedEvent{Data: packet.GetData(), Peer: nbr.Peer}) - msg := new(pb.TransactionRequest) - if err := proto.Unmarshal(data[1:], msg); err != nil { + case pb.PacketMessageRequest: + packet := new(pb.MessageRequest) + if err := proto.Unmarshal(data[1:], packet); err != nil { return fmt.Errorf("invalid packet: %w", err) } - m.log.Debugw("received message", "type", "TRANSACTION_REQUEST", "id", p.ID()) - // do something - tx, err := m.getTransaction(msg.GetHash()) + + msgID, _, err := message.IdFromBytes(packet.GetId()) + if err != nil { + return fmt.Errorf("invalid message id: %w", err) + } + + msgBytes, err := m.loadMessageFunc(msgID) if err != nil { - m.log.Debugw("error getting transaction", "hash", msg.GetHash(), "err", err) - } else { - m.SendTransaction(tx, p.ID()) + m.log.Debugw("error loading message", "msg-id", msgID, "err", err) + return nil } + // send the loaded message directly to the neighbor + _, _ = nbr.Write(marshal(&pb.Message{Data: msgBytes})) default: return ErrInvalidPacket } @@ -268,15 +268,15 @@ func (m *Manager) handlePacket(data []byte, p *peer.Peer) error { return nil } -func marshal(msg pb.Message) []byte { - mType := msg.Type() - if mType > 0xFF { - panic("invalid message") +func marshal(packet pb.Packet) []byte { + packetType := packet.Type() + if packetType > 0xFF { + panic("invalid packet") } - data, err := proto.Marshal(msg) + data, err := proto.Marshal(packet) if err != nil { - panic("invalid message") + panic("invalid packet") } - return append([]byte{byte(mType)}, data...) + return append([]byte{byte(packetType)}, data...) } diff --git a/packages/gossip/manager_test.go b/packages/gossip/manager_test.go index 83dba46e475868a0ff03943701f359519d6a59bf..cef576ddb901ced0eb0b2e9007c54ebb691297fe 100644 --- a/packages/gossip/manager_test.go +++ b/packages/gossip/manager_test.go @@ -7,12 +7,13 @@ import ( "time" "github.com/golang/protobuf/proto" - "github.com/iotaledger/goshimmer/packages/database/mapdb" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" pb "github.com/iotaledger/goshimmer/packages/gossip/proto" "github.com/iotaledger/goshimmer/packages/gossip/server" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/peer/service" "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/kvstore/mapdb" "github.com/iotaledger/hive.go/logger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -22,37 +23,31 @@ import ( const graceTime = 10 * time.Millisecond var ( - log = logger.NewExampleLogger("gossip") - testTxData = []byte("testTx") + log = logger.NewExampleLogger("gossip") + testMessageData = []byte("testMsg") ) -func getTestTransaction([]byte) ([]byte, error) { return testTxData, nil } +func loadTestMessage(message.Id) ([]byte, error) { return testMessageData, nil } func TestClose(t *testing.T) { - _, detach := newEventMock(t) - defer detach() - - _, teardown, _ := newTestManager(t, "A") + _, teardown, _ := newMockedManager(t, "A") teardown() } func TestClosedConnection(t *testing.T) { - e, detach := newEventMock(t) - defer detach() - - mgrA, closeA, peerA := newTestManager(t, "A") + mgrA, closeA, peerA := newMockedManager(t, "A") defer closeA() - mgrB, closeB, peerB := newTestManager(t, "B") + mgrB, closeB, peerB := newMockedManager(t, "B") defer closeB() - connections := 2 - e.On("neighborAdded", mock.Anything).Times(connections) - var wg sync.WaitGroup - wg.Add(connections) + wg.Add(2) // connect in the following way // B -> A + mgrA.On("neighborAdded", mock.Anything).Once() + mgrB.On("neighborAdded", mock.Anything).Once() + go func() { defer wg.Done() err := mgrA.AddInbound(peerB) @@ -68,8 +63,8 @@ func TestClosedConnection(t *testing.T) { // wait for the connections to establish wg.Wait() - e.On("neighborRemoved", peerA).Once() - e.On("neighborRemoved", peerB).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrB.On("neighborRemoved", mock.Anything).Once() // A drops B err := mgrA.DropNeighbor(peerB.ID()) @@ -77,24 +72,22 @@ func TestClosedConnection(t *testing.T) { time.Sleep(graceTime) // the events should be there even before we close - e.AssertExpectations(t) + mgrA.AssertExpectations(t) + mgrB.AssertExpectations(t) } func TestP2PSend(t *testing.T) { - e, detach := newEventMock(t) - defer detach() - - mgrA, closeA, peerA := newTestManager(t, "A") - mgrB, closeB, peerB := newTestManager(t, "B") - - connections := 2 - e.On("neighborAdded", mock.Anything).Times(connections) + mgrA, closeA, peerA := newMockedManager(t, "A") + mgrB, closeB, peerB := newMockedManager(t, "B") var wg sync.WaitGroup - wg.Add(connections) + wg.Add(2) // connect in the following way // B -> A + mgrA.On("neighborAdded", mock.Anything).Once() + mgrB.On("neighborAdded", mock.Anything).Once() + go func() { defer wg.Done() err := mgrA.AddInbound(peerB) @@ -110,39 +103,38 @@ func TestP2PSend(t *testing.T) { // wait for the connections to establish wg.Wait() - e.On("transactionReceived", &TransactionReceivedEvent{ - Data: testTxData, + mgrB.On("messageReceived", &MessageReceivedEvent{ + Data: testMessageData, Peer: peerA, }).Once() - mgrA.SendTransaction(testTxData) + mgrA.SendMessage(testMessageData) time.Sleep(graceTime) - e.On("neighborRemoved", peerA).Once() - e.On("neighborRemoved", peerB).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrB.On("neighborRemoved", mock.Anything).Once() closeA() closeB() time.Sleep(graceTime) - e.AssertExpectations(t) + // the events should be there even before we close + mgrA.AssertExpectations(t) + mgrB.AssertExpectations(t) } func TestP2PSendTwice(t *testing.T) { - e, detach := newEventMock(t) - defer detach() - - mgrA, closeA, peerA := newTestManager(t, "A") - mgrB, closeB, peerB := newTestManager(t, "B") - - connections := 2 - e.On("neighborAdded", mock.Anything).Times(connections) + mgrA, closeA, peerA := newMockedManager(t, "A") + mgrB, closeB, peerB := newMockedManager(t, "B") var wg sync.WaitGroup - wg.Add(connections) + wg.Add(2) // connect in the following way // B -> A + mgrA.On("neighborAdded", mock.Anything).Once() + mgrB.On("neighborAdded", mock.Anything).Once() + go func() { defer wg.Done() err := mgrA.AddInbound(peerB) @@ -158,42 +150,42 @@ func TestP2PSendTwice(t *testing.T) { // wait for the connections to establish wg.Wait() - e.On("transactionReceived", &TransactionReceivedEvent{ - Data: testTxData, + mgrB.On("messageReceived", &MessageReceivedEvent{ + Data: testMessageData, Peer: peerA, }).Twice() - mgrA.SendTransaction(testTxData) + mgrA.SendMessage(testMessageData) time.Sleep(1 * time.Second) // wait a bit between the sends, to test timeouts - mgrA.SendTransaction(testTxData) + mgrA.SendMessage(testMessageData) time.Sleep(graceTime) - e.On("neighborRemoved", peerA).Once() - e.On("neighborRemoved", peerB).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrB.On("neighborRemoved", mock.Anything).Once() closeA() closeB() time.Sleep(graceTime) - e.AssertExpectations(t) + // the events should be there even before we close + mgrA.AssertExpectations(t) + mgrB.AssertExpectations(t) } func TestBroadcast(t *testing.T) { - e, detach := newEventMock(t) - defer detach() - - mgrA, closeA, peerA := newTestManager(t, "A") - mgrB, closeB, peerB := newTestManager(t, "B") - mgrC, closeC, peerC := newTestManager(t, "C") - - connections := 4 - e.On("neighborAdded", mock.Anything).Times(connections) + mgrA, closeA, peerA := newMockedManager(t, "A") + mgrB, closeB, peerB := newMockedManager(t, "B") + mgrC, closeC, peerC := newMockedManager(t, "C") var wg sync.WaitGroup - wg.Add(connections) + wg.Add(4) // connect in the following way // B -> A <- C + mgrA.On("neighborAdded", mock.Anything).Twice() + mgrB.On("neighborAdded", mock.Anything).Once() + mgrC.On("neighborAdded", mock.Anything).Once() + go func() { defer wg.Done() err := mgrA.AddInbound(peerB) @@ -219,42 +211,42 @@ func TestBroadcast(t *testing.T) { // wait for the connections to establish wg.Wait() - e.On("transactionReceived", &TransactionReceivedEvent{ - Data: testTxData, - Peer: peerA, - }).Twice() + event := &MessageReceivedEvent{Data: testMessageData, Peer: peerA} + mgrB.On("messageReceived", event).Once() + mgrC.On("messageReceived", event).Once() - mgrA.SendTransaction(testTxData) + mgrA.SendMessage(testMessageData) time.Sleep(graceTime) - e.On("neighborRemoved", peerA).Twice() - e.On("neighborRemoved", peerB).Once() - e.On("neighborRemoved", peerC).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrB.On("neighborRemoved", mock.Anything).Once() + mgrC.On("neighborRemoved", mock.Anything).Once() closeA() closeB() closeC() time.Sleep(graceTime) - e.AssertExpectations(t) + mgrA.AssertExpectations(t) + mgrB.AssertExpectations(t) + mgrC.AssertExpectations(t) } func TestSingleSend(t *testing.T) { - e, detach := newEventMock(t) - defer detach() - - mgrA, closeA, peerA := newTestManager(t, "A") - mgrB, closeB, peerB := newTestManager(t, "B") - mgrC, closeC, peerC := newTestManager(t, "C") - - connections := 4 - e.On("neighborAdded", mock.Anything).Times(connections) + mgrA, closeA, peerA := newMockedManager(t, "A") + mgrB, closeB, peerB := newMockedManager(t, "B") + mgrC, closeC, peerC := newMockedManager(t, "C") var wg sync.WaitGroup - wg.Add(connections) + wg.Add(4) // connect in the following way // B -> A <- C + mgrA.On("neighborAdded", mock.Anything).Twice() + mgrB.On("neighborAdded", mock.Anything).Once() + mgrC.On("neighborAdded", mock.Anything).Once() + go func() { defer wg.Done() err := mgrA.AddInbound(peerB) @@ -280,59 +272,55 @@ func TestSingleSend(t *testing.T) { // wait for the connections to establish wg.Wait() - e.On("transactionReceived", &TransactionReceivedEvent{ - Data: testTxData, - Peer: peerA, - }).Once() + // only mgr should receive the message + mgrB.On("messageReceived", &MessageReceivedEvent{Data: testMessageData, Peer: peerA}).Once() - // A sends the transaction only to B - mgrA.SendTransaction(testTxData, peerB.ID()) + // A sends the message only to B + mgrA.SendMessage(testMessageData, peerB.ID()) time.Sleep(graceTime) - e.On("neighborRemoved", peerA).Twice() - e.On("neighborRemoved", peerB).Once() - e.On("neighborRemoved", peerC).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrB.On("neighborRemoved", mock.Anything).Once() + mgrC.On("neighborRemoved", mock.Anything).Once() closeA() closeB() closeC() time.Sleep(graceTime) - e.AssertExpectations(t) + mgrA.AssertExpectations(t) + mgrB.AssertExpectations(t) + mgrC.AssertExpectations(t) } func TestDropUnsuccessfulAccept(t *testing.T) { - e, detach := newEventMock(t) - defer detach() - - mgrA, closeA, _ := newTestManager(t, "A") + mgrA, closeA, _ := newMockedManager(t, "A") defer closeA() - _, closeB, peerB := newTestManager(t, "B") + mgrB, closeB, peerB := newMockedManager(t, "B") defer closeB() - e.On("connectionFailed", peerB, mock.Anything).Once() + mgrA.On("connectionFailed", peerB, mock.Anything).Once() err := mgrA.AddInbound(peerB) assert.Error(t, err) - e.AssertExpectations(t) + mgrA.AssertExpectations(t) + mgrB.AssertExpectations(t) } -func TestTxRequest(t *testing.T) { - e, detach := newEventMock(t) - defer detach() - - mgrA, closeA, peerA := newTestManager(t, "A") - mgrB, closeB, peerB := newTestManager(t, "B") - - connections := 2 - e.On("neighborAdded", mock.Anything).Times(connections) +func TestMessageRequest(t *testing.T) { + mgrA, closeA, peerA := newMockedManager(t, "A") + mgrB, closeB, peerB := newMockedManager(t, "B") var wg sync.WaitGroup - wg.Add(connections) + wg.Add(2) // connect in the following way // B -> A + mgrA.On("neighborAdded", mock.Anything).Once() + mgrB.On("neighborAdded", mock.Anything).Once() + go func() { defer wg.Done() err := mgrA.AddInbound(peerB) @@ -348,26 +336,85 @@ func TestTxRequest(t *testing.T) { // wait for the connections to establish wg.Wait() - txHash := []byte("Hello!") + id := message.Id{} - e.On("transactionReceived", &TransactionReceivedEvent{ - Data: testTxData, - Peer: peerB, - }).Once() + // mgrA should eventually receive the message + mgrA.On("messageReceived", &MessageReceivedEvent{Data: testMessageData, Peer: peerB}).Once() - b, err := proto.Marshal(&pb.TransactionRequest{Hash: txHash}) + b, err := proto.Marshal(&pb.MessageRequest{Id: id[:]}) require.NoError(t, err) - mgrA.RequestTransaction(b) + mgrA.RequestMessage(b) time.Sleep(graceTime) - e.On("neighborRemoved", peerA).Once() - e.On("neighborRemoved", peerB).Once() + mgrA.On("neighborRemoved", mock.Anything).Once() + mgrB.On("neighborRemoved", mock.Anything).Once() closeA() closeB() time.Sleep(graceTime) - e.AssertExpectations(t) + mgrA.AssertExpectations(t) + mgrB.AssertExpectations(t) +} + +func TestDropNeighbor(t *testing.T) { + mgrA, closeA, peerA := newTestManager(t, "A") + defer closeA() + mgrB, closeB, peerB := newTestManager(t, "B") + defer closeB() + + // establish connection + connect := func() { + var wg sync.WaitGroup + signal := events.NewClosure(func(_ *Neighbor) { wg.Done() }) + // we are expecting two signals + wg.Add(2) + + // signal as soon as the neighbor is added + mgrA.Events().NeighborAdded.Attach(signal) + defer mgrA.Events().NeighborAdded.Detach(signal) + mgrB.Events().NeighborAdded.Attach(signal) + defer mgrB.Events().NeighborAdded.Detach(signal) + + go func() { assert.NoError(t, mgrA.AddInbound(peerB)) }() + go func() { assert.NoError(t, mgrB.AddOutbound(peerA)) }() + wg.Wait() // wait until the events were triggered and the peers are connected + } + // close connection + disconnect := func() { + var wg sync.WaitGroup + signal := events.NewClosure(func(_ *Neighbor) { wg.Done() }) + // we are expecting two signals + wg.Add(2) + + // signal as soon as the neighbor is added + mgrA.Events().NeighborRemoved.Attach(signal) + defer mgrA.Events().NeighborRemoved.Detach(signal) + mgrB.Events().NeighborRemoved.Attach(signal) + defer mgrB.Events().NeighborRemoved.Detach(signal) + + // assure that no DropNeighbor calls are leaking + wg.Add(2) + go func() { + defer wg.Done() + _ = mgrA.DropNeighbor(peerB.ID()) + }() + go func() { + defer wg.Done() + _ = mgrB.DropNeighbor(peerA.ID()) + }() + wg.Wait() // wait until the events were triggered and the go routines are done + } + + // drop and connect many many times + for i := 0; i < 100; i++ { + connect() + assert.NotEmpty(t, mgrA.AllNeighbors()) + assert.NotEmpty(t, mgrB.AllNeighbors()) + disconnect() + assert.Empty(t, mgrA.AllNeighbors()) + assert.Empty(t, mgrB.AllNeighbors()) + } } func newTestDB(t require.TestingT) *peer.DB { @@ -379,23 +426,22 @@ func newTestDB(t require.TestingT) *peer.DB { func newTestManager(t require.TestingT, name string) (*Manager, func(), *peer.Peer) { l := log.Named(name) - services := service.New() - services.Update(service.PeeringKey, "peering", name) - local, err := peer.NewLocal(services, newTestDB(t)) - require.NoError(t, err) - laddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0") require.NoError(t, err) lis, err := net.ListenTCP("tcp", laddr) require.NoError(t, err) - // enable TCP gossipping - require.NoError(t, local.UpdateService(service.GossipKey, lis.Addr().Network(), lis.Addr().String())) + services := service.New() + services.Update(service.PeeringKey, "peering", 0) + services.Update(service.GossipKey, lis.Addr().Network(), lis.Addr().(*net.TCPAddr).Port) + + local, err := peer.NewLocal(lis.Addr().(*net.TCPAddr).IP, services, newTestDB(t)) + require.NoError(t, err) srv := server.ServeTCP(local, lis, l) // start the actual gossipping - mgr := NewManager(local, getTestTransaction, l) + mgr := NewManager(local, loadTestMessage, l) mgr.Start(srv) detach := func() { @@ -403,36 +449,32 @@ func newTestManager(t require.TestingT, name string) (*Manager, func(), *peer.Pe srv.Close() _ = lis.Close() } - return mgr, detach, &local.Peer + return mgr, detach, local.Peer } -func newEventMock(t mock.TestingT) (*eventMock, func()) { - e := &eventMock{} +func newMockedManager(t *testing.T, name string) (*mockedManager, func(), *peer.Peer) { + mgr, detach, p := newTestManager(t, name) + return mockManager(t, mgr), detach, p +} + +func mockManager(t mock.TestingT, mgr *Manager) *mockedManager { + e := &mockedManager{Manager: mgr} e.Test(t) - connectionFailedC := events.NewClosure(e.connectionFailed) - neighborAddedC := events.NewClosure(e.neighborAdded) - neighborRemoved := events.NewClosure(e.neighborRemoved) - transactionReceivedC := events.NewClosure(e.transactionReceived) - - Events.ConnectionFailed.Attach(connectionFailedC) - Events.NeighborAdded.Attach(neighborAddedC) - Events.NeighborRemoved.Attach(neighborRemoved) - Events.TransactionReceived.Attach(transactionReceivedC) - - return e, func() { - Events.ConnectionFailed.Detach(connectionFailedC) - Events.NeighborAdded.Detach(neighborAddedC) - Events.NeighborRemoved.Detach(neighborRemoved) - Events.TransactionReceived.Detach(transactionReceivedC) - } + e.Events().ConnectionFailed.Attach(events.NewClosure(e.connectionFailed)) + e.Events().NeighborAdded.Attach(events.NewClosure(e.neighborAdded)) + e.Events().NeighborRemoved.Attach(events.NewClosure(e.neighborRemoved)) + e.Events().MessageReceived.Attach(events.NewClosure(e.messageReceived)) + + return e } -type eventMock struct { +type mockedManager struct { mock.Mock + *Manager } -func (e *eventMock) connectionFailed(p *peer.Peer, err error) { e.Called(p, err) } -func (e *eventMock) neighborAdded(n *Neighbor) { e.Called(n) } -func (e *eventMock) neighborRemoved(p *peer.Peer) { e.Called(p) } -func (e *eventMock) transactionReceived(ev *TransactionReceivedEvent) { e.Called(ev) } +func (e *mockedManager) connectionFailed(p *peer.Peer, err error) { e.Called(p, err) } +func (e *mockedManager) neighborAdded(n *Neighbor) { e.Called(n) } +func (e *mockedManager) neighborRemoved(n *Neighbor) { e.Called(n) } +func (e *mockedManager) messageReceived(ev *MessageReceivedEvent) { e.Called(ev) } diff --git a/packages/gossip/neighbor.go b/packages/gossip/neighbor.go index a529aab2af7ede70439dd696a3d15f2e7a1cd8c4..76868f7533bb0212ea5b01c9e6981e5888895cfb 100644 --- a/packages/gossip/neighbor.go +++ b/packages/gossip/neighbor.go @@ -1,30 +1,26 @@ package gossip import ( - "errors" "io" "net" "strings" "sync" + "time" - "github.com/iotaledger/goshimmer/packages/netutil" - "github.com/iotaledger/goshimmer/packages/netutil/buffconn" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/netutil" + "github.com/iotaledger/hive.go/netutil/buffconn" "go.uber.org/atomic" ) -var ( - // ErrNeighborQueueFull is returned when the send queue is already full. - ErrNeighborQueueFull = errors.New("send queue is full") -) - const ( neighborQueueSize = 5000 maxNumReadErrors = 10 droppedMessagesThreshold = 1000 ) +// Neighbor describes the established gossip connection to another peer. type Neighbor struct { *peer.Peer *buffconn.BufferedConnection @@ -36,6 +32,8 @@ type Neighbor struct { wg sync.WaitGroup closing chan struct{} disconnectOnce sync.Once + + connectionEstablished time.Time } // NewNeighbor creates a new neighbor from the provided peer and connection. @@ -52,14 +50,20 @@ func NewNeighbor(peer *peer.Peer, conn net.Conn, log *logger.Logger) *Neighbor { ) return &Neighbor{ - Peer: peer, - BufferedConnection: buffconn.NewBufferedConnection(conn), - log: log, - queue: make(chan []byte, neighborQueueSize), - closing: make(chan struct{}), + Peer: peer, + BufferedConnection: buffconn.NewBufferedConnection(conn), + log: log, + queue: make(chan []byte, neighborQueueSize), + closing: make(chan struct{}), + connectionEstablished: time.Now(), } } +// ConnectionEstablished returns the connection established. +func (n *Neighbor) ConnectionEstablished() time.Time { + return n.connectionEstablished +} + // Listen starts the communication to the neighbor. func (n *Neighbor) Listen() { n.wg.Add(2) diff --git a/packages/gossip/neighbor_test.go b/packages/gossip/neighbor_test.go index 36c61534baf178c3fd637406302661e6b75687bd..841ed0dd9ca35478abd3fb55074fd2f17f6ce62e 100644 --- a/packages/gossip/neighbor_test.go +++ b/packages/gossip/neighbor_test.go @@ -9,7 +9,9 @@ import ( "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/peer/service" + "github.com/iotaledger/hive.go/crypto/ed25519" "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/identity" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -118,15 +120,18 @@ func TestNeighborParallelWrite(t *testing.T) { } func newTestNeighbor(name string, conn net.Conn) *Neighbor { - return NewNeighbor(newTestPeer(name, conn.LocalAddr()), conn, log.Named(name)) + return NewNeighbor(newTestPeer(name, conn), conn, log.Named(name)) } -func newTestPeer(name string, addr net.Addr) *peer.Peer { +func newTestPeer(name string, conn net.Conn) *peer.Peer { services := service.New() - services.Update(service.PeeringKey, addr.Network(), addr.String()) - services.Update(service.GossipKey, addr.Network(), addr.String()) + services.Update(service.PeeringKey, conn.LocalAddr().Network(), 0) + services.Update(service.GossipKey, conn.LocalAddr().Network(), 0) - return peer.NewPeer([]byte(name), services) + var publicKey ed25519.PublicKey + copy(publicKey[:], name) + + return peer.NewPeer(identity.New(publicKey), net.IPv4zero, services) } func newPipe() (net.Conn, net.Conn, func()) { diff --git a/packages/gossip/proto/message.go b/packages/gossip/proto/message.go deleted file mode 100644 index f9404c1ebbdae75067d3e94615dcbab1ac57e20e..0000000000000000000000000000000000000000 --- a/packages/gossip/proto/message.go +++ /dev/null @@ -1,30 +0,0 @@ -package proto - -import ( - "github.com/golang/protobuf/proto" -) - -// MType is the type of message type enum. -type MType uint - -// An enum for the different message types. -const ( - MTransaction MType = 20 + iota - MTransactionRequest -) - -// Message extends the proto.Message interface with additional util functions. -type Message interface { - proto.Message - - // Name returns the name of the corresponding message type for debugging. - Name() string - // Type returns the type of the corresponding message as an enum. - Type() MType -} - -func (m *Transaction) Name() string { return "TRANSACTION" } -func (m *Transaction) Type() MType { return MTransaction } - -func (m *TransactionRequest) Name() string { return "TRANSACTION_REQUEST" } -func (m *TransactionRequest) Type() MType { return MTransactionRequest } diff --git a/packages/gossip/proto/message.pb.go b/packages/gossip/proto/message.pb.go index 06ab295e24de3ad10c34445c204f1a4573e1f661..e78ad3a77435b90b5fee57c316ad2ce941dd0f37 100644 --- a/packages/gossip/proto/message.pb.go +++ b/packages/gossip/proto/message.pb.go @@ -1,12 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: packages/gossip/proto/message.proto +// source: message.proto package proto import ( fmt "fmt" - proto "github.com/golang/protobuf/proto" math "math" + + proto "github.com/golang/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. @@ -20,105 +21,103 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package -type Transaction struct { - // transaction data +type Message struct { Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *Transaction) Reset() { *m = Transaction{} } -func (m *Transaction) String() string { return proto.CompactTextString(m) } -func (*Transaction) ProtoMessage() {} -func (*Transaction) Descriptor() ([]byte, []int) { - return fileDescriptor_fcce9e84825f2fa5, []int{0} +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { + return fileDescriptor_33c57e4bae7b9afd, []int{0} } -func (m *Transaction) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Transaction.Unmarshal(m, b) +func (m *Message) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Message.Unmarshal(m, b) } -func (m *Transaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Transaction.Marshal(b, m, deterministic) +func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Message.Marshal(b, m, deterministic) } -func (m *Transaction) XXX_Merge(src proto.Message) { - xxx_messageInfo_Transaction.Merge(m, src) +func (m *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(m, src) } -func (m *Transaction) XXX_Size() int { - return xxx_messageInfo_Transaction.Size(m) +func (m *Message) XXX_Size() int { + return xxx_messageInfo_Message.Size(m) } -func (m *Transaction) XXX_DiscardUnknown() { - xxx_messageInfo_Transaction.DiscardUnknown(m) +func (m *Message) XXX_DiscardUnknown() { + xxx_messageInfo_Message.DiscardUnknown(m) } -var xxx_messageInfo_Transaction proto.InternalMessageInfo +var xxx_messageInfo_Message proto.InternalMessageInfo -func (m *Transaction) GetData() []byte { +func (m *Message) GetData() []byte { if m != nil { return m.Data } return nil } -type TransactionRequest struct { - // transaction hash - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` +type MessageRequest struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *TransactionRequest) Reset() { *m = TransactionRequest{} } -func (m *TransactionRequest) String() string { return proto.CompactTextString(m) } -func (*TransactionRequest) ProtoMessage() {} -func (*TransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fcce9e84825f2fa5, []int{1} +func (m *MessageRequest) Reset() { *m = MessageRequest{} } +func (m *MessageRequest) String() string { return proto.CompactTextString(m) } +func (*MessageRequest) ProtoMessage() {} +func (*MessageRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_33c57e4bae7b9afd, []int{1} } -func (m *TransactionRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TransactionRequest.Unmarshal(m, b) +func (m *MessageRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageRequest.Unmarshal(m, b) } -func (m *TransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TransactionRequest.Marshal(b, m, deterministic) +func (m *MessageRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageRequest.Marshal(b, m, deterministic) } -func (m *TransactionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_TransactionRequest.Merge(m, src) +func (m *MessageRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageRequest.Merge(m, src) } -func (m *TransactionRequest) XXX_Size() int { - return xxx_messageInfo_TransactionRequest.Size(m) +func (m *MessageRequest) XXX_Size() int { + return xxx_messageInfo_MessageRequest.Size(m) } -func (m *TransactionRequest) XXX_DiscardUnknown() { - xxx_messageInfo_TransactionRequest.DiscardUnknown(m) +func (m *MessageRequest) XXX_DiscardUnknown() { + xxx_messageInfo_MessageRequest.DiscardUnknown(m) } -var xxx_messageInfo_TransactionRequest proto.InternalMessageInfo +var xxx_messageInfo_MessageRequest proto.InternalMessageInfo -func (m *TransactionRequest) GetHash() []byte { +func (m *MessageRequest) GetId() []byte { if m != nil { - return m.Hash + return m.Id } return nil } func init() { - proto.RegisterType((*Transaction)(nil), "proto.Transaction") - proto.RegisterType((*TransactionRequest)(nil), "proto.TransactionRequest") + proto.RegisterType((*Message)(nil), "proto.Message") + proto.RegisterType((*MessageRequest)(nil), "proto.MessageRequest") } func init() { - proto.RegisterFile("packages/gossip/proto/message.proto", fileDescriptor_fcce9e84825f2fa5) -} - -var fileDescriptor_fcce9e84825f2fa5 = []byte{ - // 155 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2e, 0x48, 0x4c, 0xce, - 0x4e, 0x4c, 0x4f, 0x2d, 0xd6, 0x4f, 0xcf, 0x2f, 0x2e, 0xce, 0x2c, 0xd0, 0x2f, 0x28, 0xca, 0x2f, - 0xc9, 0xd7, 0xcf, 0x4d, 0x2d, 0x2e, 0x06, 0x8a, 0xea, 0x81, 0x79, 0x42, 0xac, 0x60, 0x4a, 0x49, - 0x91, 0x8b, 0x3b, 0xa4, 0x28, 0x31, 0xaf, 0x38, 0x31, 0xb9, 0x24, 0x33, 0x3f, 0x4f, 0x48, 0x88, - 0x8b, 0x25, 0x25, 0xb1, 0x24, 0x51, 0x82, 0x51, 0x81, 0x51, 0x83, 0x27, 0x08, 0xcc, 0x56, 0xd2, - 0xe0, 0x12, 0x42, 0x52, 0x12, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x02, 0x52, 0x99, 0x91, 0x58, - 0x9c, 0x01, 0x53, 0x09, 0x62, 0x3b, 0x99, 0x47, 0x99, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, - 0x25, 0xe7, 0xe7, 0xea, 0x67, 0xe6, 0x97, 0x24, 0xe6, 0xa4, 0xa6, 0xa4, 0xa7, 0x16, 0x81, 0xdc, - 0x91, 0x91, 0x99, 0x9b, 0x0b, 0x64, 0x61, 0x75, 0x5a, 0x12, 0x1b, 0x98, 0x32, 0x06, 0x04, 0x00, - 0x00, 0xff, 0xff, 0x9f, 0x78, 0x4d, 0x0f, 0xba, 0x00, 0x00, 0x00, + proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) +} + +var fileDescriptor_33c57e4bae7b9afd = []byte{ + // 147 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x4d, 0x2d, 0x2e, + 0x4e, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x53, 0x4a, 0xb2, 0x5c, + 0xec, 0xbe, 0x10, 0x71, 0x21, 0x21, 0x2e, 0x96, 0x94, 0xc4, 0x92, 0x44, 0x09, 0x46, 0x05, 0x46, + 0x0d, 0x9e, 0x20, 0x30, 0x5b, 0x49, 0x81, 0x8b, 0x0f, 0x2a, 0x1d, 0x94, 0x5a, 0x58, 0x9a, 0x5a, + 0x5c, 0x22, 0xc4, 0xc7, 0xc5, 0x94, 0x99, 0x02, 0x55, 0xc3, 0x94, 0x99, 0xe2, 0x64, 0x1e, 0x65, + 0x9a, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x99, 0x5f, 0x92, 0x98, + 0x93, 0x9a, 0x92, 0x9e, 0x5a, 0xa4, 0x9f, 0x9e, 0x5f, 0x9c, 0x91, 0x99, 0x9b, 0x9b, 0x5a, 0xa4, + 0x5f, 0x90, 0x98, 0x9c, 0x9d, 0x98, 0x9e, 0x5a, 0x0c, 0x12, 0x2a, 0xce, 0x2c, 0xd0, 0x07, 0xdb, + 0x9c, 0xc4, 0x06, 0xa6, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xb0, 0x39, 0x6d, 0x98, + 0x00, 0x00, 0x00, } diff --git a/packages/gossip/proto/message.proto b/packages/gossip/proto/message.proto index 8d6bc2851d74093df240a7ff27cea20afacd3e47..213a1126531f120c49504ed0b3a07ce80050c51e 100644 --- a/packages/gossip/proto/message.proto +++ b/packages/gossip/proto/message.proto @@ -4,12 +4,10 @@ option go_package = "github.com/iotaledger/goshimmer/packages/gossip/proto"; package proto; -message Transaction { - // transaction data - bytes data = 1; +message Message { + bytes data = 1; } -message TransactionRequest { - // transaction hash - bytes hash = 1; +message MessageRequest { + bytes id = 1; } \ No newline at end of file diff --git a/packages/gossip/proto/packet.go b/packages/gossip/proto/packet.go new file mode 100644 index 0000000000000000000000000000000000000000..f905af818a0ea22d648c8804a6e07049d65d8d04 --- /dev/null +++ b/packages/gossip/proto/packet.go @@ -0,0 +1,36 @@ +package proto + +import ( + "github.com/golang/protobuf/proto" +) + +// PacketType is the type of packet type enum. +type PacketType uint + +// An enum for the different packet types. +const ( + PacketMessage PacketType = 20 + iota + PacketMessageRequest +) + +// Packet extends the proto.Message interface with additional util functions. +type Packet interface { + proto.Message + + // Name returns the name of the corresponding packet type for debugging. + Name() string + // Type returns the type of the corresponding packet as an enum. + Type() PacketType +} + +// Name returns the name of the message packet. +func (m *Message) Name() string { return "message" } + +// Type returns the packet type id of the message packet. +func (m *Message) Type() PacketType { return PacketMessage } + +// Name returns the name of the message request packet. +func (m *MessageRequest) Name() string { return "message_request" } + +// Type returns the packet type id of the message request packet. +func (m *MessageRequest) Type() PacketType { return PacketMessageRequest } diff --git a/packages/gossip/server/handshake.go b/packages/gossip/server/handshake.go index 719ff0dea33ce26994ba2bf83b4bea904a8ed356..86bef3f74ad82ab7aea532c1476661bf713ba4a1 100644 --- a/packages/gossip/server/handshake.go +++ b/packages/gossip/server/handshake.go @@ -50,13 +50,6 @@ func (t *TCP) validateHandshakeRequest(reqData []byte) bool { ) return false } - if m.GetTo() != t.publicAddr.String() { - t.log.Debugw("invalid handshake", - "to", m.GetTo(), - "want", t.publicAddr.String(), - ) - return false - } if isExpired(m.GetTimestamp()) { t.log.Debugw("invalid handshake", "timestamp", time.Unix(m.GetTimestamp(), 0), diff --git a/packages/gossip/server/server.go b/packages/gossip/server/server.go index 6185df511f9b6c0f794ac532611b1bb3d5b8c249..133e92efce596ff0cf49e380059579825d59932e 100644 --- a/packages/gossip/server/server.go +++ b/packages/gossip/server/server.go @@ -7,16 +7,19 @@ import ( "fmt" "io" "net" + "strconv" "strings" "sync" "time" "github.com/golang/protobuf/proto" - "github.com/iotaledger/goshimmer/packages/netutil" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/peer/service" pb "github.com/iotaledger/hive.go/autopeering/server/proto" "github.com/iotaledger/hive.go/backoff" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" + "github.com/iotaledger/hive.go/netutil" "go.uber.org/zap" ) @@ -46,10 +49,9 @@ var dialRetryPolicy = backoff.ConstantBackOff(500 * time.Millisecond).With(backo // TCP establishes verified incoming and outgoing TCP connections to other peers. type TCP struct { - local *peer.Local - publicAddr net.Addr - listener *net.TCPListener - log *zap.SugaredLogger + local *peer.Local + listener *net.TCPListener + log *zap.SugaredLogger addAcceptMatcher chan *acceptMatcher acceptReceived chan accept @@ -72,25 +74,21 @@ type acceptMatcher struct { } type accept struct { - fromID peer.ID // ID of the connecting peer - req []byte // raw data of the handshake request - conn net.Conn // the actual network connection + fromID identity.ID // ID of the connecting peer + req []byte // raw data of the handshake request + conn net.Conn // the actual network connection } // ServeTCP creates the object and starts listening for incoming connections. func ServeTCP(local *peer.Local, listener *net.TCPListener, log *zap.SugaredLogger) *TCP { t := &TCP{ local: local, - publicAddr: local.Services().Get(service.GossipKey), listener: listener, log: log, addAcceptMatcher: make(chan *acceptMatcher), acceptReceived: make(chan accept), closing: make(chan struct{}), } - if t.publicAddr == nil { - panic(ErrNoGossip) - } t.log.Debugw("server started", "network", listener.Addr().Network(), @@ -123,21 +121,22 @@ func (t *TCP) LocalAddr() net.Addr { // DialPeer establishes a gossip connection to the given peer. // If the peer does not accept the connection or the handshake fails, an error is returned. func (t *TCP) DialPeer(p *peer.Peer) (net.Conn, error) { - gossipAddr := p.Services().Get(service.GossipKey) - if gossipAddr == nil { + gossipEndpoint := p.Services().Get(service.GossipKey) + if gossipEndpoint == nil { return nil, ErrNoGossip } var conn net.Conn if err := backoff.Retry(dialRetryPolicy, func() error { var err error - conn, err = net.DialTimeout(gossipAddr.Network(), gossipAddr.String(), dialTimeout) + address := net.JoinHostPort(p.IP().String(), strconv.Itoa(gossipEndpoint.Port())) + conn, err = net.DialTimeout("tcp", address, dialTimeout) if err != nil { - return fmt.Errorf("dial %s / %s failed: %w", gossipAddr.String(), p.ID(), err) + return fmt.Errorf("dial %s / %s failed: %w", address, p.ID(), err) } - if err = t.doHandshake(p.PublicKey(), gossipAddr.String(), conn); err != nil { - return fmt.Errorf("handshake %s / %s failed: %w", gossipAddr.String(), p.ID(), err) + if err = t.doHandshake(p.PublicKey(), address, conn); err != nil { + return fmt.Errorf("handshake %s / %s failed: %w", address, p.ID(), err) } return nil }); err != nil { @@ -154,15 +153,15 @@ func (t *TCP) DialPeer(p *peer.Peer) (net.Conn, error) { // AcceptPeer awaits an incoming connection from the given peer. // If the peer does not establish the connection or the handshake fails, an error is returned. func (t *TCP) AcceptPeer(p *peer.Peer) (net.Conn, error) { - gossipAddr := p.Services().Get(service.GossipKey) - if gossipAddr == nil { + gossipEndpoint := p.Services().Get(service.GossipKey) + if gossipEndpoint == nil { return nil, ErrNoGossip } // wait for the connection connected := <-t.acceptPeer(p) if connected.err != nil { - return nil, fmt.Errorf("accept %s / %s failed: %w", gossipAddr.String(), p.ID(), connected.err) + return nil, fmt.Errorf("accept %s / %s failed: %w", net.JoinHostPort(p.IP().String(), strconv.Itoa(gossipEndpoint.Port())), p.ID(), connected.err) } t.log.Debugw("incoming connection established", @@ -300,7 +299,7 @@ func (t *TCP) listenLoop() { select { case t.acceptReceived <- accept{ - fromID: key.ID(), + fromID: identity.NewID(key), req: req, conn: conn, }: @@ -311,15 +310,15 @@ func (t *TCP) listenLoop() { } } -func (t *TCP) doHandshake(key peer.PublicKey, remoteAddr string, conn net.Conn) error { +func (t *TCP) doHandshake(key ed25519.PublicKey, remoteAddr string, conn net.Conn) error { reqData, err := newHandshakeRequest(remoteAddr) if err != nil { return err } pkt := &pb.Packet{ - PublicKey: t.local.PublicKey(), - Signature: t.local.Sign(reqData), + PublicKey: t.local.PublicKey().Bytes(), + Signature: t.local.Sign(reqData).Bytes(), Data: reqData, } b, err := proto.Marshal(pkt) @@ -356,7 +355,7 @@ func (t *TCP) doHandshake(key peer.PublicKey, remoteAddr string, conn net.Conn) } signer, err := peer.RecoverKeyFromSignedData(pkt) - if err != nil || !bytes.Equal(key, signer) { + if err != nil || !bytes.Equal(key.Bytes(), signer.Bytes()) { return ErrInvalidHandshake } if !t.validateHandshakeResponse(pkt.GetData(), reqData) { @@ -366,29 +365,29 @@ func (t *TCP) doHandshake(key peer.PublicKey, remoteAddr string, conn net.Conn) return nil } -func (t *TCP) readHandshakeRequest(conn net.Conn) (peer.PublicKey, []byte, error) { +func (t *TCP) readHandshakeRequest(conn net.Conn) (ed25519.PublicKey, []byte, error) { if err := conn.SetReadDeadline(time.Now().Add(handshakeTimeout)); err != nil { - return nil, nil, err + return ed25519.PublicKey{}, nil, err } b := make([]byte, maxHandshakePacketSize) n, err := conn.Read(b) if err != nil { - return nil, nil, fmt.Errorf("%w: %s", ErrInvalidHandshake, err.Error()) + return ed25519.PublicKey{}, nil, fmt.Errorf("%w: %s", ErrInvalidHandshake, err.Error()) } pkt := &pb.Packet{} err = proto.Unmarshal(b[:n], pkt) if err != nil { - return nil, nil, err + return ed25519.PublicKey{}, nil, err } key, err := peer.RecoverKeyFromSignedData(pkt) if err != nil { - return nil, nil, err + return ed25519.PublicKey{}, nil, err } if !t.validateHandshakeRequest(pkt.GetData()) { - return nil, nil, ErrInvalidHandshake + return ed25519.PublicKey{}, nil, ErrInvalidHandshake } return key, pkt.GetData(), nil @@ -401,8 +400,8 @@ func (t *TCP) writeHandshakeResponse(reqData []byte, conn net.Conn) error { } pkt := &pb.Packet{ - PublicKey: t.local.PublicKey(), - Signature: t.local.Sign(data), + PublicKey: t.local.PublicKey().Bytes(), + Signature: t.local.Sign(data).Bytes(), Data: data, } b, err := proto.Marshal(pkt) diff --git a/packages/gossip/server/server_test.go b/packages/gossip/server/server_test.go index d3e954184da75295687c3710db34a9fd317aa756..7fa8defa98cc42d7e947c7fa27abbecd3090e828 100644 --- a/packages/gossip/server/server_test.go +++ b/packages/gossip/server/server_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" - "github.com/iotaledger/goshimmer/packages/database/mapdb" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/peer/service" + "github.com/iotaledger/hive.go/kvstore/mapdb" "github.com/iotaledger/hive.go/logger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -19,7 +19,7 @@ const graceTime = 5 * time.Millisecond var log = logger.NewExampleLogger("server") func getPeer(t *TCP) *peer.Peer { - return &t.local.Peer + return t.local.Peer } func TestClose(t *testing.T) { @@ -57,8 +57,8 @@ func TestUnansweredDial(t *testing.T) { // create peer with invalid gossip address services := getPeer(transA).Services().CreateRecord() - services.Update(service.GossipKey, "tcp", "localhost:0") - unreachablePeer := peer.NewPeer(getPeer(transA).PublicKey(), services) + services.Update(service.GossipKey, "tcp", 0) + unreachablePeer := peer.NewPeer(getPeer(transA).Identity, net.ParseIP("127.0.0.1"), services) _, err := transA.DialPeer(unreachablePeer) assert.Error(t, err) @@ -81,8 +81,8 @@ func TestNoHandshakeResponse(t *testing.T) { // create peer for the listener services := getPeer(transA).Services().CreateRecord() - services.Update(service.GossipKey, lis.Addr().Network(), lis.Addr().String()) - p := peer.NewPeer(getPeer(transA).PublicKey(), services) + services.Update(service.GossipKey, lis.Addr().Network(), lis.Addr().(*net.TCPAddr).Port) + p := peer.NewPeer(getPeer(transA).Identity, lis.Addr().(*net.TCPAddr).IP, services) _, err = transA.DialPeer(p) assert.Error(t, err) @@ -174,18 +174,17 @@ func newTestDB(t require.TestingT) *peer.DB { func newTestServer(t require.TestingT, name string) (*TCP, func()) { l := log.Named(name) - services := service.New() - services.Update(service.PeeringKey, "peering", name) - local, err := peer.NewLocal(services, newTestDB(t)) - require.NoError(t, err) - laddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0") require.NoError(t, err) lis, err := net.ListenTCP("tcp", laddr) require.NoError(t, err) - // enable TCP gossipping - require.NoError(t, local.UpdateService(service.GossipKey, lis.Addr().Network(), lis.Addr().String())) + services := service.New() + services.Update(service.PeeringKey, "peering", 0) + services.Update(service.GossipKey, lis.Addr().Network(), lis.Addr().(*net.TCPAddr).Port) + + local, err := peer.NewLocal(lis.Addr().(*net.TCPAddr).IP, services, newTestDB(t)) + require.NoError(t, err) srv := ServeTCP(local, lis, l) diff --git a/packages/graph/graph.go b/packages/graph/graph.go new file mode 100644 index 0000000000000000000000000000000000000000..3e354a77a452647d2dddfaee8330ad9a131eac83 --- /dev/null +++ b/packages/graph/graph.go @@ -0,0 +1,152 @@ +package graph + +import ( + "runtime" + "sync" +) + +type nodeID int32 + +type symbolTable map[string]nodeID + +func (s symbolTable) getID(name string) nodeID { + id, ok := s[name] + if !ok { + id = nodeID(len(s)) + s[name] = id + } + return id +} + +// Graph contains nodes and a symbolTable of a graph. +type Graph struct { + symbolTable + nodes +} + +// New returns a graph. +func New(IDs []string) *Graph { + g := &Graph{ + symbolTable: make(symbolTable, len(IDs)), + nodes: make(nodes, len(IDs)), + } + for index, id := range IDs { + g.nodes[index].ID = nodeID(index) + g.symbolTable[id] = nodeID(index) + } + return g +} + +// AddEdge adds an edge to the given graph. +func (g *Graph) AddEdge(a, b string) { + aid := g.symbolTable.getID(a) + bid := g.symbolTable.getID(b) + + g.nodes.AddEdge(aid, bid) +} + +type node struct { + ID nodeID + + // adjacent edges + Adj []nodeID +} + +func (n *node) add(adjNode *node) { + for _, id := range n.Adj { + if id == adjNode.ID { + return + } + } + n.Adj = append(n.Adj, adjNode.ID) +} + +type nodes []node + +func (nl nodes) get(id nodeID) *node { + return &nl[id] +} + +func (nl nodes) AddEdge(a, b nodeID) { + an := nl.get(a) + bn := nl.get(b) + + an.add(bn) + bn.add(an) +} + +// Diameter is the maximum length of a shortest path in the network +func (nl nodes) Diameter() int { + + cpus := runtime.GOMAXPROCS(0) + numNodes := len(nl) + nodesPerCPU := numNodes / cpus + + results := make([]int, cpus) + wg := &sync.WaitGroup{} + wg.Add(cpus) + start := 0 + for cpu := 0; cpu < cpus; cpu++ { + end := start + nodesPerCPU + if cpu == cpus-1 { + end = numNodes + } + + go func(cpu int, start, end nodeID) { + defer wg.Done() + var diameter int + q := &list{} + depths := make([]bfsNode, numNodes) + for id := start; id < end; id++ { + // Need to reset the bfsData between runs + for i := range depths { + depths[i] = -1 + } + + df := nl.longestShortestPath(nodeID(id), q, depths) + if df > diameter { + diameter = df + } + } + results[cpu] = diameter + }(cpu, nodeID(start), nodeID(end)) + start += nodesPerCPU + } + + wg.Wait() + + diameter := 0 + for _, result := range results { + if result > diameter { + diameter = result + } + } + return diameter +} + +// bfs tracking data +type bfsNode int16 + +func (nl nodes) longestShortestPath(start nodeID, q *list, depths []bfsNode) int { + + n := nl.get(start) + depths[n.ID] = 0 + q.pushBack(n) + + for { + newN := q.getHead() + if newN == nil { + break + } + n = newN + + for _, id := range n.Adj { + if depths[id] == -1 { + depths[id] = depths[n.ID] + 1 + q.pushBack(nl.get(id)) + } + } + } + + return int(depths[n.ID]) +} diff --git a/packages/graph/list.go b/packages/graph/list.go new file mode 100644 index 0000000000000000000000000000000000000000..bae5fd673439998d6bb2e73f20ee6a3f7f778d0b --- /dev/null +++ b/packages/graph/list.go @@ -0,0 +1,54 @@ +package graph + +type listElt struct { + next *listElt + node *node +} + +type list struct { + head *listElt + tail *listElt + + free *listElt +} + +func (l *list) getHead() *node { + elt := l.head + if elt == nil { + return nil + } + + // Remove elt from the list + l.head = elt.next + if l.head == nil { + l.tail = nil + } + // Add elt to the free list + elt.next = l.free + l.free = elt + + n := elt.node + elt.node = nil + return n +} + +func (l *list) pushBack(n *node) { + // Get a free listElt to use to point to this node + elt := l.free + if elt == nil { + elt = &listElt{} + } else { + l.free = elt.next + elt.next = nil + } + + // Add the element to the tail of the list + elt.node = n + if l.tail == nil { + l.tail = elt + l.head = elt + } else { + l.tail.next = elt + l.tail = elt + } +} diff --git a/packages/metrics/events.go b/packages/metrics/events.go new file mode 100644 index 0000000000000000000000000000000000000000..91d94c6b73e5beee4d088c2483eebcfd9c6e01e8 --- /dev/null +++ b/packages/metrics/events.go @@ -0,0 +1,85 @@ +package metrics + +import ( + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/hive.go/events" +) + +// CollectionEvents defines the events fot the metrics package. +type CollectionEvents struct { + // AnalysisOutboundBytes defines the local analysis outbound network traffic in bytes. + AnalysisOutboundBytes *events.Event + // FPCInboundBytes defines the local FPC inbound network traffic in bytes. + FPCInboundBytes *events.Event + // FPCOutboundBytes defines the local FPC outbound network traffic in bytes. + FPCOutboundBytes *events.Event + // CPUUsage defines the local CPU usage. + CPUUsage *events.Event + // MemUsage defines the local GoShimmer memory usage. + MemUsage *events.Event + // Synced defines the local sync status event. + Synced *events.Event + // ValueTips defines the local value tips count event. + ValueTips *events.Event + // MessageTips defines the local message tips count event. + MessageTips *events.Event + // QueryReceived defines the local FPC query received event. + QueryReceived *events.Event + // QueryReplyError defines the local FPC query finalization event. + QueryReplyError *events.Event + // AnalysisFPCFinalized defines the global FPC finalization event. + AnalysisFPCFinalized *events.Event +} + +// QueryReceivedEvent is used to pass information through a QueryReceived event. +type QueryReceivedEvent struct { + // OpinionCount defines the local FPC number of opinions requested within a received query. + OpinionCount int +} + +// QueryReplyErrorEvent is used to pass information through a QueryReplyError event. +type QueryReplyErrorEvent struct { + // ID defines the ID on the queried node. + ID string + // OpinionCount defines the local FPC number of opinions requested within a failed query. + OpinionCount int +} + +// AnalysisFPCFinalizedEvent is triggered by the analysis-server to +// notify a finalized FPC vote from one node. +type AnalysisFPCFinalizedEvent struct { + // ConflictID defines the ID of the finalized conflict. + ConflictID string + // NodeID defines the ID of the node. + NodeID string + // Rounds defines the number of rounds performed to finalize. + Rounds int + // Opinions contains the opinion of each round. + Opinions []vote.Opinion + // Outcome defines the outcome of the FPC voting. + Outcome vote.Opinion +} + +func queryReceivedEventCaller(handler interface{}, params ...interface{}) { + handler.(func(ev *QueryReceivedEvent))(params[0].(*QueryReceivedEvent)) +} + +func queryReplyErrorEventCaller(handler interface{}, params ...interface{}) { + handler.(func(ev *QueryReplyErrorEvent))(params[0].(*QueryReplyErrorEvent)) +} + +func uint64Caller(handler interface{}, params ...interface{}) { + handler.(func(uint64))(params[0].(uint64)) +} + +func float64Caller(handler interface{}, params ...interface{}) { + handler.(func(float64))(params[0].(float64)) +} + +func boolCaller(handler interface{}, params ...interface{}) { + handler.(func(bool))(params[0].(bool)) +} + +func fpcFinalizedEventCaller(handler interface{}, params ...interface{}) { + handler.(func(ev *AnalysisFPCFinalizedEvent))(params[0].(*AnalysisFPCFinalizedEvent)) +} diff --git a/packages/metrics/metrics.go b/packages/metrics/metrics.go new file mode 100644 index 0000000000000000000000000000000000000000..b39b8901e534152efede51f8bb0e10e49596af0d --- /dev/null +++ b/packages/metrics/metrics.go @@ -0,0 +1,36 @@ +package metrics + +import ( + "sync" + + "github.com/iotaledger/hive.go/events" +) + +var ( + once sync.Once + metricEvents *CollectionEvents +) + +func new() *CollectionEvents { + return &CollectionEvents{ + AnalysisOutboundBytes: events.NewEvent(uint64Caller), + FPCInboundBytes: events.NewEvent(uint64Caller), + FPCOutboundBytes: events.NewEvent(uint64Caller), + CPUUsage: events.NewEvent(float64Caller), + MemUsage: events.NewEvent(uint64Caller), + Synced: events.NewEvent(boolCaller), + ValueTips: events.NewEvent(uint64Caller), + MessageTips: events.NewEvent(uint64Caller), + QueryReceived: events.NewEvent(queryReceivedEventCaller), + QueryReplyError: events.NewEvent(queryReplyErrorEventCaller), + AnalysisFPCFinalized: events.NewEvent(fpcFinalizedEventCaller), + } +} + +// Events returns the events defined in the package. +func Events() *CollectionEvents { + once.Do(func() { + metricEvents = new() + }) + return metricEvents +} diff --git a/packages/model/approvers/approvers.go b/packages/model/approvers/approvers.go deleted file mode 100644 index d84e02216ebea3066095ed4c70884afee86dca5a..0000000000000000000000000000000000000000 --- a/packages/model/approvers/approvers.go +++ /dev/null @@ -1,149 +0,0 @@ -package approvers - -import ( - "encoding/binary" - "fmt" - "sync" - - "github.com/iotaledger/goshimmer/packages/model" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -type Approvers struct { - hash trinary.Trytes - hashes map[trinary.Trytes]bool - hashesMutex sync.RWMutex - modified bool -} - -func New(hash trinary.Trytes) *Approvers { - return &Approvers{ - hash: hash, - hashes: make(map[trinary.Trytes]bool), - modified: false, - } -} - -// region public methods with locking ////////////////////////////////////////////////////////////////////////////////// - -func (approvers *Approvers) Add(transactionHash trinary.Trytes) { - approvers.hashesMutex.Lock() - approvers.add(transactionHash) - approvers.hashesMutex.Unlock() -} - -func (approvers *Approvers) Remove(approverHash trinary.Trytes) { - approvers.hashesMutex.Lock() - approvers.remove(approverHash) - approvers.hashesMutex.Unlock() -} - -func (approvers *Approvers) GetHashes() (result []trinary.Trytes) { - approvers.hashesMutex.RLock() - result = approvers.getHashes() - approvers.hashesMutex.RUnlock() - - return -} - -func (approvers *Approvers) GetHash() (result trinary.Trytes) { - approvers.hashesMutex.RLock() - result = approvers.hash - approvers.hashesMutex.RUnlock() - - return -} - -func (approvers *Approvers) GetModified() bool { - return true -} - -func (approvers *Approvers) SetModified(modified bool) { -} - -func (approvers *Approvers) Marshal() (result []byte) { - approvers.hashesMutex.RLock() - - result = make([]byte, MARSHALED_APPROVERS_MIN_SIZE+len(approvers.hashes)*MARSHALED_APPROVERS_HASH_SIZE) - - binary.BigEndian.PutUint64(result[MARSHALED_APPROVERS_HASHES_COUNT_START:MARSHALED_APPROVERS_HASHES_COUNT_END], uint64(len(approvers.hashes))) - - copy(result[MARSHALED_APPROVERS_HASH_START:MARSHALED_APPROVERS_HASH_END], typeutils.StringToBytes(approvers.hash)) - - i := 0 - for hash := range approvers.hashes { - var HASH_START = MARSHALED_APPROVERS_HASHES_START + i*(MARSHALED_APPROVERS_HASH_SIZE) - var HASH_END = HASH_START + MARSHALED_APPROVERS_HASH_SIZE - - copy(result[HASH_START:HASH_END], typeutils.StringToBytes(hash)) - - i++ - } - - approvers.hashesMutex.RUnlock() - - return -} - -func (approvers *Approvers) Unmarshal(data []byte) error { - dataLen := len(data) - - if dataLen < MARSHALED_APPROVERS_MIN_SIZE { - return fmt.Errorf("%w: marshaled approvers are too short", model.ErrMarshalFailed) - } - - hashesCount := binary.BigEndian.Uint64(data[MARSHALED_APPROVERS_HASHES_COUNT_START:MARSHALED_APPROVERS_HASHES_COUNT_END]) - - if dataLen < MARSHALED_APPROVERS_MIN_SIZE+int(hashesCount)*MARSHALED_APPROVERS_HASH_SIZE { - return fmt.Errorf("%w: marshaled approvers are too short for %d approvers", model.ErrMarshalFailed, hashesCount) - } - - approvers.hashesMutex.Lock() - - approvers.hash = trinary.Trytes(typeutils.BytesToString(data[MARSHALED_APPROVERS_HASH_START:MARSHALED_APPROVERS_HASH_END])) - approvers.hashes = make(map[trinary.Trytes]bool, hashesCount) - for i := uint64(0); i < hashesCount; i++ { - var HASH_START = MARSHALED_APPROVERS_HASHES_START + i*(MARSHALED_APPROVERS_HASH_SIZE) - var HASH_END = HASH_START + MARSHALED_APPROVERS_HASH_SIZE - - approvers.hashes[trinary.Trytes(typeutils.BytesToString(data[HASH_START:HASH_END]))] = true - } - - approvers.hashesMutex.Unlock() - - return nil -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region private methods without locking ////////////////////////////////////////////////////////////////////////////// - -func (approvers *Approvers) add(transactionHash trinary.Trytes) { - if _, exists := approvers.hashes[transactionHash]; !exists { - approvers.hashes[transactionHash] = true - approvers.modified = true - } -} - -func (approvers *Approvers) remove(approverHash trinary.Trytes) { - if _, exists := approvers.hashes[approverHash]; exists { - delete(approvers.hashes, approverHash) - approvers.modified = true - } -} - -func (approvers *Approvers) getHashes() (result []trinary.Trytes) { - result = make([]trinary.Trytes, len(approvers.hashes)) - - counter := 0 - for hash := range approvers.hashes { - result[counter] = hash - - counter++ - } - - return -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/model/approvers/approvers_test.go b/packages/model/approvers/approvers_test.go deleted file mode 100644 index 926c5c070c83b7360447c022f5bac89e2ee5a1ee..0000000000000000000000000000000000000000 --- a/packages/model/approvers/approvers_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package approvers - -import ( - "fmt" - "testing" - - "github.com/iotaledger/iota.go/trinary" - "github.com/magiconair/properties/assert" -) - -func TestApprovers_SettersGetters(t *testing.T) { - hashA := trinary.Trytes("A9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - hashB := trinary.Trytes("B9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - approversTest := New(hashA) - approversTest.Add(hashB) - - assert.Equal(t, approversTest.GetHash(), hashA, "hash") - assert.Equal(t, approversTest.GetHashes()[0], hashB, "hashes") -} - -func TestApprovers_MarshalUnmarshal(t *testing.T) { - hashA := trinary.Trytes("A9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - hashB := trinary.Trytes("B9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - approversTest := New(hashA) - approversTest.Add(hashB) - - approversTestBytes := approversTest.Marshal() - - var approversUnmarshaled Approvers - err := approversUnmarshaled.Unmarshal(approversTestBytes) - if err != nil { - fmt.Println(err, len(approversTestBytes)) - } - - assert.Equal(t, approversUnmarshaled.GetHash(), approversTest.GetHash(), "hash") - assert.Equal(t, approversUnmarshaled.GetHashes(), approversTest.GetHashes(), "hashes") -} diff --git a/packages/model/approvers/constants.go b/packages/model/approvers/constants.go deleted file mode 100644 index 9c777856affc38393feed697e40986d33afd46b9..0000000000000000000000000000000000000000 --- a/packages/model/approvers/constants.go +++ /dev/null @@ -1,14 +0,0 @@ -package approvers - -const ( - MARSHALED_APPROVERS_HASHES_COUNT_START = 0 - MARSHALED_APPROVERS_HASH_START = MARSHALED_APPROVERS_HASHES_COUNT_END - MARSHALED_APPROVERS_HASHES_START = MARSHALED_APPROVERS_HASH_END - - MARSHALED_APPROVERS_HASHES_COUNT_END = MARSHALED_APPROVERS_HASHES_COUNT_START + MARSHALED_APPROVERS_HASHES_COUNT_SIZE - MARSHALED_APPROVERS_HASH_END = MARSHALED_APPROVERS_HASH_START + MARSHALED_APPROVERS_HASH_SIZE - - MARSHALED_APPROVERS_HASHES_COUNT_SIZE = 8 - MARSHALED_APPROVERS_HASH_SIZE = 81 - MARSHALED_APPROVERS_MIN_SIZE = MARSHALED_APPROVERS_HASHES_COUNT_SIZE + MARSHALED_APPROVERS_HASH_SIZE -) diff --git a/packages/model/bundle/bundle.go b/packages/model/bundle/bundle.go deleted file mode 100644 index d54092ed0ebd37649781360f745ec91268550da7..0000000000000000000000000000000000000000 --- a/packages/model/bundle/bundle.go +++ /dev/null @@ -1,183 +0,0 @@ -package bundle - -import ( - "encoding/binary" - "fmt" - "sync" - "unsafe" - - "github.com/iotaledger/goshimmer/packages/model" - "github.com/iotaledger/hive.go/bitmask" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -type Bundle struct { - hash trinary.Trytes - hashMutex sync.RWMutex - transactionHashes []trinary.Trytes - transactionHashesMutex sync.RWMutex - isValueBundle bool - isValueBundleMutex sync.RWMutex - bundleEssenceHash trinary.Trytes - bundleEssenceHashMutex sync.RWMutex - modified bool - modifiedMutex sync.RWMutex -} - -func New(headTransactionHash trinary.Trytes) (result *Bundle) { - result = &Bundle{ - hash: headTransactionHash, - } - - return -} - -func (bundle *Bundle) GetHash() (result trinary.Trytes) { - bundle.hashMutex.RLock() - result = bundle.hash - bundle.hashMutex.RUnlock() - - return -} - -func (bundle *Bundle) SetHash(hash trinary.Trytes) { - bundle.hashMutex.Lock() - bundle.hash = hash - bundle.hashMutex.Unlock() -} - -func (bundle *Bundle) GetTransactionHashes() (result []trinary.Trytes) { - bundle.transactionHashesMutex.RLock() - result = bundle.transactionHashes - bundle.transactionHashesMutex.RUnlock() - - return -} - -func (bundle *Bundle) SetTransactionHashes(transactionHashes []trinary.Trytes) { - bundle.transactionHashesMutex.Lock() - bundle.transactionHashes = transactionHashes - bundle.transactionHashesMutex.Unlock() -} - -func (bundle *Bundle) IsValueBundle() (result bool) { - bundle.isValueBundleMutex.RLock() - result = bundle.isValueBundle - bundle.isValueBundleMutex.RUnlock() - - return -} - -func (bundle *Bundle) SetValueBundle(valueBundle bool) { - bundle.isValueBundleMutex.Lock() - bundle.isValueBundle = valueBundle - bundle.isValueBundleMutex.Unlock() -} - -func (bundle *Bundle) GetBundleEssenceHash() (result trinary.Trytes) { - bundle.bundleEssenceHashMutex.RLock() - result = bundle.bundleEssenceHash - bundle.bundleEssenceHashMutex.RUnlock() - - return -} - -func (bundle *Bundle) SetBundleEssenceHash(bundleEssenceHash trinary.Trytes) { - bundle.bundleEssenceHashMutex.Lock() - bundle.bundleEssenceHash = bundleEssenceHash - bundle.bundleEssenceHashMutex.Unlock() -} - -func (bundle *Bundle) GetModified() (result bool) { - bundle.modifiedMutex.RLock() - result = bundle.modified - bundle.modifiedMutex.RUnlock() - - return -} - -func (bundle *Bundle) SetModified(modified bool) { - bundle.modifiedMutex.Lock() - bundle.modified = modified - bundle.modifiedMutex.Unlock() -} - -func (bundle *Bundle) Marshal() (result []byte) { - bundle.hashMutex.RLock() - bundle.bundleEssenceHashMutex.RLock() - bundle.isValueBundleMutex.RLock() - bundle.transactionHashesMutex.RLock() - - result = make([]byte, MARSHALED_MIN_SIZE+len(bundle.transactionHashes)*MARSHALED_TRANSACTION_HASH_SIZE) - - binary.BigEndian.PutUint64(result[MARSHALED_TRANSACTIONS_COUNT_START:MARSHALED_TRANSACTIONS_COUNT_END], uint64(len(bundle.transactionHashes))) - - copy(result[MARSHALED_HASH_START:MARSHALED_HASH_END], typeutils.StringToBytes(bundle.hash)) - copy(result[MARSHALED_BUNDLE_ESSENCE_HASH_START:MARSHALED_BUNDLE_ESSENCE_HASH_END], typeutils.StringToBytes(bundle.bundleEssenceHash)) - - var flags bitmask.BitMask - if bundle.isValueBundle { - flags = flags.SetFlag(0) - } - result[MARSHALED_FLAGS_START] = *(*byte)(unsafe.Pointer(&flags)) - - i := 0 - for _, hash := range bundle.transactionHashes { - var HASH_START = MARSHALED_APPROVERS_HASHES_START + i*(MARSHALED_TRANSACTION_HASH_SIZE) - var HASH_END = HASH_START + MARSHALED_TRANSACTION_HASH_SIZE - - copy(result[HASH_START:HASH_END], typeutils.StringToBytes(hash)) - - i++ - } - - bundle.transactionHashesMutex.RUnlock() - bundle.isValueBundleMutex.RUnlock() - bundle.bundleEssenceHashMutex.RUnlock() - bundle.hashMutex.RUnlock() - - return -} - -func (bundle *Bundle) Unmarshal(data []byte) error { - dataLen := len(data) - - if dataLen < MARSHALED_MIN_SIZE { - return fmt.Errorf("%w: marshaled bundle is too short", model.ErrMarshalFailed) - } - - hashesCount := binary.BigEndian.Uint64(data[MARSHALED_TRANSACTIONS_COUNT_START:MARSHALED_TRANSACTIONS_COUNT_END]) - - if dataLen < MARSHALED_MIN_SIZE+int(hashesCount)*MARSHALED_TRANSACTION_HASH_SIZE { - return fmt.Errorf("%w: marshaled bundle is too short for %d transactions", model.ErrMarshalFailed, hashesCount) - } - - bundle.hashMutex.Lock() - bundle.bundleEssenceHashMutex.Lock() - bundle.isValueBundleMutex.Lock() - bundle.transactionHashesMutex.Lock() - - bundle.hash = trinary.Trytes(typeutils.BytesToString(data[MARSHALED_HASH_START:MARSHALED_HASH_END])) - bundle.bundleEssenceHash = trinary.Trytes(typeutils.BytesToString(data[MARSHALED_BUNDLE_ESSENCE_HASH_START:MARSHALED_BUNDLE_ESSENCE_HASH_END])) - - flags := bitmask.BitMask(data[MARSHALED_FLAGS_START]) - if flags.HasFlag(0) { - bundle.isValueBundle = true - } - - bundle.transactionHashes = make([]trinary.Trytes, hashesCount) - for i := uint64(0); i < hashesCount; i++ { - var HASH_START = MARSHALED_APPROVERS_HASHES_START + i*(MARSHALED_TRANSACTION_HASH_SIZE) - var HASH_END = HASH_START + MARSHALED_TRANSACTION_HASH_SIZE - - bundle.transactionHashes[i] = trinary.Trytes(typeutils.BytesToString(data[HASH_START:HASH_END])) - } - - bundle.transactionHashesMutex.Unlock() - bundle.isValueBundleMutex.Unlock() - bundle.bundleEssenceHashMutex.Unlock() - bundle.hashMutex.Unlock() - - return nil -} diff --git a/packages/model/bundle/bundle_test.go b/packages/model/bundle/bundle_test.go deleted file mode 100644 index d00bb6ec462fe91ce7c4a4d78bd6d8e1f9654a09..0000000000000000000000000000000000000000 --- a/packages/model/bundle/bundle_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package bundle - -import ( - "testing" - - "github.com/iotaledger/iota.go/trinary" - "github.com/magiconair/properties/assert" -) - -func TestBundle_SettersGetters(t *testing.T) { - bundleHash := trinary.Trytes("A9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - bundleEssenceHash := trinary.Trytes("B9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - transactions := []trinary.Trytes{ - bundleHash, - trinary.Trytes("C9999999999999999999999999999999999999999999999999999999999999999999999999999999F"), - } - - testBundle := New(bundleHash) - testBundle.SetTransactionHashes(transactions) - testBundle.SetBundleEssenceHash(bundleEssenceHash) - testBundle.SetValueBundle(true) - - assert.Equal(t, testBundle.GetHash(), bundleHash, "hash of source") - assert.Equal(t, testBundle.GetBundleEssenceHash(), bundleEssenceHash, "bundle essence hash of source") - assert.Equal(t, testBundle.IsValueBundle(), true, "value bundle of source") - assert.Equal(t, len(testBundle.GetTransactionHashes()), len(transactions), "# of transactions of source") - assert.Equal(t, testBundle.GetTransactionHashes()[0], transactions[0], "transaction[0] of source") - assert.Equal(t, testBundle.GetTransactionHashes()[1], transactions[1], "transaction[1] of source") -} - -func TestBundle_SettersGettersMarshalUnmarshal(t *testing.T) { - bundleHash := trinary.Trytes("A9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - bundleEssenceHash := trinary.Trytes("B9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - transactions := []trinary.Trytes{ - bundleHash, - trinary.Trytes("C9999999999999999999999999999999999999999999999999999999999999999999999999999999F"), - } - - testBundle := New(bundleHash) - testBundle.SetTransactionHashes(transactions) - testBundle.SetBundleEssenceHash(bundleEssenceHash) - testBundle.SetValueBundle(true) - - var bundleUnmarshaled Bundle - err := bundleUnmarshaled.Unmarshal(testBundle.Marshal()) - if err != nil { - t.Error(err) - } - - assert.Equal(t, bundleUnmarshaled.GetHash(), testBundle.GetHash(), "hash of target") - assert.Equal(t, bundleUnmarshaled.GetBundleEssenceHash(), testBundle.GetBundleEssenceHash(), "bundle essence hash of target") - assert.Equal(t, bundleUnmarshaled.IsValueBundle(), true, "value bundle of target") - assert.Equal(t, len(bundleUnmarshaled.GetTransactionHashes()), len(transactions), "# of transactions of target") - assert.Equal(t, bundleUnmarshaled.GetTransactionHashes()[0], transactions[0], "transaction[0] of target") - assert.Equal(t, bundleUnmarshaled.GetTransactionHashes()[1], transactions[1], "transaction[1] of target") -} diff --git a/packages/model/bundle/constants.go b/packages/model/bundle/constants.go deleted file mode 100644 index 1575f582e69874f4cc852600bf8ea29d5389ec89..0000000000000000000000000000000000000000 --- a/packages/model/bundle/constants.go +++ /dev/null @@ -1,20 +0,0 @@ -package bundle - -const ( - MARSHALED_TRANSACTIONS_COUNT_START = 0 - MARSHALED_HASH_START = MARSHALED_TRANSACTIONS_COUNT_END - MARSHALED_BUNDLE_ESSENCE_HASH_START = MARSHALED_HASH_END - MARSHALED_FLAGS_START = MARSHALED_BUNDLE_ESSENCE_HASH_END - MARSHALED_APPROVERS_HASHES_START = MARSHALED_FLAGS_END - - MARSHALED_TRANSACTIONS_COUNT_END = MARSHALED_TRANSACTIONS_COUNT_START + MARSHALED_TRANSACTIONS_COUNT_SIZE - MARSHALED_HASH_END = MARSHALED_HASH_START + MARSHALED_TRANSACTION_HASH_SIZE - MARSHALED_BUNDLE_ESSENCE_HASH_END = MARSHALED_BUNDLE_ESSENCE_HASH_START + MARSHALED_BUNDLE_ESSENCE_HASH_SIZE - MARSHALED_FLAGS_END = MARSHALED_FLAGS_START + MARSHALED_FLAGS_SIZE - - MARSHALED_TRANSACTIONS_COUNT_SIZE = 8 - MARSHALED_TRANSACTION_HASH_SIZE = 81 - MARSHALED_BUNDLE_ESSENCE_HASH_SIZE = 81 - MARSHALED_FLAGS_SIZE = 1 - MARSHALED_MIN_SIZE = MARSHALED_TRANSACTIONS_COUNT_SIZE + MARSHALED_TRANSACTION_HASH_SIZE + MARSHALED_BUNDLE_ESSENCE_HASH_SIZE + MARSHALED_FLAGS_SIZE -) diff --git a/packages/model/error.go b/packages/model/error.go deleted file mode 100644 index b060d2d30bcc10c7a327b936e38d2d3287b89e74..0000000000000000000000000000000000000000 --- a/packages/model/error.go +++ /dev/null @@ -1,8 +0,0 @@ -package model - -import "errors" - -var ( - ErrUnmarshalFailed = errors.New("unmarshal failed") - ErrMarshalFailed = errors.New("marshal failed") -) diff --git a/packages/model/meta_transaction/constants.go b/packages/model/meta_transaction/constants.go deleted file mode 100644 index 399fd041fc35e8a338734cc8ada6c5e53e11ba65..0000000000000000000000000000000000000000 --- a/packages/model/meta_transaction/constants.go +++ /dev/null @@ -1,41 +0,0 @@ -package meta_transaction - -import ( - "github.com/iotaledger/iota.go/consts" - "github.com/iotaledger/iota.go/trinary" -) - -const ( - SHARD_MARKER_OFFSET = 0 - TRUNK_TRANSACTION_HASH_OFFSET = SHARD_MARKER_END - BRANCH_TRANSACTION_HASH_OFFSET = TRUNK_TRANSACTION_HASH_END - HEAD_OFFSET = BRANCH_TRANSACTION_HASH_END - TAIL_OFFSET = HEAD_END - TRANSACTION_TYPE_OFFSET = TAIL_END - DATA_OFFSET = TRANSACTION_TYPE_END - NONCE_OFFSET = DATA_END - - SHARD_MARKER_SIZE = 11 - TRUNK_TRANSACTION_HASH_SIZE = 243 - BRANCH_TRANSACTION_HASH_SIZE = 243 - HEAD_SIZE = 1 - TAIL_SIZE = 1 - TRANSACTION_TYPE_SIZE = 8 - DATA_SIZE = 6993 - NONCE_SIZE = consts.NonceTrinarySize - - SHARD_MARKER_END = SHARD_MARKER_OFFSET + SHARD_MARKER_SIZE - TRUNK_TRANSACTION_HASH_END = TRUNK_TRANSACTION_HASH_OFFSET + TRUNK_TRANSACTION_HASH_SIZE - BRANCH_TRANSACTION_HASH_END = BRANCH_TRANSACTION_HASH_OFFSET + BRANCH_TRANSACTION_HASH_SIZE - HEAD_END = HEAD_OFFSET + HEAD_SIZE - TAIL_END = TAIL_OFFSET + TAIL_SIZE - TRANSACTION_TYPE_END = TRANSACTION_TYPE_OFFSET + TRANSACTION_TYPE_SIZE - DATA_END = DATA_OFFSET + DATA_SIZE - NONCE_END = NONCE_OFFSET + NONCE_SIZE - - MARSHALED_TOTAL_SIZE = NONCE_END - - BRANCH_NULL_HASH = trinary.Trytes("999999999999999999999999999999999999999999999999999999999999999999999999999999999") - - MIN_WEIGHT_MAGNITUDE = 12 -) diff --git a/packages/model/meta_transaction/meta_transaction.go b/packages/model/meta_transaction/meta_transaction.go deleted file mode 100644 index 59c546ea97e85bc57b7daedd3479c7a92368075e..0000000000000000000000000000000000000000 --- a/packages/model/meta_transaction/meta_transaction.go +++ /dev/null @@ -1,577 +0,0 @@ -package meta_transaction - -import ( - "errors" - "fmt" - "sync" - - "github.com/iotaledger/iota.go/consts" - "github.com/iotaledger/iota.go/curl" - "github.com/iotaledger/iota.go/pow" - "github.com/iotaledger/iota.go/trinary" -) - -var ( - ErrInvalidWeightMagnitude = errors.New("insufficient weight magnitude") -) - -type MetaTransaction struct { - hash *trinary.Trytes - weightMagnitude int - - shardMarker *trinary.Trytes - trunkTransactionHash *trinary.Trytes - branchTransactionHash *trinary.Trytes - head *bool - tail *bool - transactionType *trinary.Trytes - data trinary.Trits - modified bool - nonce *trinary.Trytes - - hasherMutex sync.RWMutex - hashMutex sync.RWMutex - shardMarkerMutex sync.RWMutex - trunkTransactionHashMutex sync.RWMutex - branchTransactionHashMutex sync.RWMutex - headMutex sync.RWMutex - tailMutex sync.RWMutex - transactionTypeMutex sync.RWMutex - dataMutex sync.RWMutex - bytesMutex sync.RWMutex - modifiedMutex sync.RWMutex - nonceMutex sync.RWMutex - - trits trinary.Trits - bytes []byte -} - -func New() *MetaTransaction { - return FromTrits(make(trinary.Trits, MARSHALED_TOTAL_SIZE)) -} - -func FromTrits(trits trinary.Trits) *MetaTransaction { - return &MetaTransaction{ - trits: trits, - } -} - -func FromBytes(bytes []byte) (result *MetaTransaction, err error) { - trits := trinary.MustBytesToTrits(bytes) - if len(trits) < MARSHALED_TOTAL_SIZE { - return nil, fmt.Errorf("invalid size %v", len(trits)) - } - result = FromTrits(trits[:MARSHALED_TOTAL_SIZE]) - result.bytes = bytes - - return -} - -func (this *MetaTransaction) BlockHasher() { - this.hasherMutex.RLock() -} - -func (this *MetaTransaction) UnblockHasher() { - this.hasherMutex.RUnlock() -} - -func (this *MetaTransaction) ReHash() { - this.hashMutex.Lock() - defer this.hashMutex.Unlock() - this.hash = nil - - this.bytesMutex.Lock() - defer this.bytesMutex.Unlock() - this.bytes = nil -} - -// retrieves the hash of the transaction -func (this *MetaTransaction) GetHash() (result trinary.Trytes) { - this.hashMutex.RLock() - if this.hash == nil { - this.hashMutex.RUnlock() - this.hashMutex.Lock() - defer this.hashMutex.Unlock() - if this.hash == nil { - this.hasherMutex.Lock() - this.computeHashDetails() - this.hasherMutex.Unlock() - } - } else { - defer this.hashMutex.RUnlock() - } - - result = *this.hash - - return -} - -// retrieves weight magnitude of the transaction (amount of pow invested) -func (this *MetaTransaction) GetWeightMagnitude() (result int) { - this.hashMutex.RLock() - if this.hash == nil { - this.hashMutex.RUnlock() - this.hashMutex.Lock() - defer this.hashMutex.Unlock() - if this.hash == nil { - this.hasherMutex.Lock() - this.computeHashDetails() - this.hasherMutex.Unlock() - } - } else { - defer this.hashMutex.RUnlock() - } - - result = this.weightMagnitude - - return -} - -// returns the trytes that are relevant for the transaction hash -func (this *MetaTransaction) getHashEssence() trinary.Trits { - txTrits := this.trits - - // very dirty hack, to get an iota.go compatible size - if len(txTrits) > consts.TransactionTrinarySize { - panic("transaction too large") - } - essenceTrits := make([]int8, consts.TransactionTrinarySize) - copy(essenceTrits[consts.TransactionTrinarySize-len(txTrits):], txTrits) - - return essenceTrits -} - -// hashes the transaction using curl (without locking - internal usage) -func (this *MetaTransaction) computeHashDetails() { - hashTrits, err := curl.HashTrits(this.getHashEssence()) - if err != nil { - panic(err) - } - hashTrytes := trinary.MustTritsToTrytes(hashTrits) - - this.hash = &hashTrytes - this.weightMagnitude = int(trinary.TrailingZeros(hashTrits)) -} - -// getter for the shard marker (supports concurrency) -func (this *MetaTransaction) GetShardMarker() (result trinary.Trytes) { - this.shardMarkerMutex.RLock() - if this.shardMarker == nil { - this.shardMarkerMutex.RUnlock() - this.shardMarkerMutex.Lock() - defer this.shardMarkerMutex.Unlock() - if this.shardMarker == nil { - shardMarker := trinary.MustTritsToTrytes(this.trits[SHARD_MARKER_OFFSET:SHARD_MARKER_END]) - - this.shardMarker = &shardMarker - } - } else { - defer this.shardMarkerMutex.RUnlock() - } - - result = *this.shardMarker - - return -} - -// setter for the shard marker (supports concurrency) -func (this *MetaTransaction) SetShardMarker(shardMarker trinary.Trytes) bool { - this.shardMarkerMutex.RLock() - if this.shardMarker == nil || *this.shardMarker != shardMarker { - this.shardMarkerMutex.RUnlock() - this.shardMarkerMutex.Lock() - defer this.shardMarkerMutex.Unlock() - if this.shardMarker == nil || *this.shardMarker != shardMarker { - this.shardMarker = &shardMarker - - this.hasherMutex.RLock() - copy(this.trits[SHARD_MARKER_OFFSET:SHARD_MARKER_END], trinary.MustTrytesToTrits(shardMarker)[:SHARD_MARKER_SIZE]) - this.hasherMutex.RUnlock() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.shardMarkerMutex.RUnlock() - } - - return false -} - -// getter for the bundleHash (supports concurrency) -func (this *MetaTransaction) GetTrunkTransactionHash() (result trinary.Trytes) { - this.trunkTransactionHashMutex.RLock() - if this.trunkTransactionHash == nil { - this.trunkTransactionHashMutex.RUnlock() - this.trunkTransactionHashMutex.Lock() - defer this.trunkTransactionHashMutex.Unlock() - if this.trunkTransactionHash == nil { - trunkTransactionHash := trinary.MustTritsToTrytes(this.trits[TRUNK_TRANSACTION_HASH_OFFSET:TRUNK_TRANSACTION_HASH_END]) - - this.trunkTransactionHash = &trunkTransactionHash - } - } else { - defer this.trunkTransactionHashMutex.RUnlock() - } - - result = *this.trunkTransactionHash - - return -} - -// setter for the trunkTransactionHash (supports concurrency) -func (this *MetaTransaction) SetTrunkTransactionHash(trunkTransactionHash trinary.Trytes) bool { - this.trunkTransactionHashMutex.RLock() - if this.trunkTransactionHash == nil || *this.trunkTransactionHash != trunkTransactionHash { - this.trunkTransactionHashMutex.RUnlock() - this.trunkTransactionHashMutex.Lock() - defer this.trunkTransactionHashMutex.Unlock() - if this.trunkTransactionHash == nil || *this.trunkTransactionHash != trunkTransactionHash { - this.trunkTransactionHash = &trunkTransactionHash - - this.hasherMutex.RLock() - copy(this.trits[TRUNK_TRANSACTION_HASH_OFFSET:TRUNK_TRANSACTION_HASH_END], trinary.MustTrytesToTrits(trunkTransactionHash)[:TRUNK_TRANSACTION_HASH_SIZE]) - this.hasherMutex.RUnlock() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.trunkTransactionHashMutex.RUnlock() - } - - return false -} - -// getter for the bundleHash (supports concurrency) -func (this *MetaTransaction) GetBranchTransactionHash() (result trinary.Trytes) { - this.branchTransactionHashMutex.RLock() - if this.branchTransactionHash == nil { - this.branchTransactionHashMutex.RUnlock() - this.branchTransactionHashMutex.Lock() - defer this.branchTransactionHashMutex.Unlock() - if this.branchTransactionHash == nil { - branchTransactionHash := trinary.MustTritsToTrytes(this.trits[BRANCH_TRANSACTION_HASH_OFFSET:BRANCH_TRANSACTION_HASH_END]) - - this.branchTransactionHash = &branchTransactionHash - } - } else { - defer this.branchTransactionHashMutex.RUnlock() - } - - result = *this.branchTransactionHash - - return -} - -// setter for the trunkTransactionHash (supports concurrency) -func (this *MetaTransaction) SetBranchTransactionHash(branchTransactionHash trinary.Trytes) bool { - this.branchTransactionHashMutex.RLock() - if this.branchTransactionHash == nil || *this.branchTransactionHash != branchTransactionHash { - this.branchTransactionHashMutex.RUnlock() - this.branchTransactionHashMutex.Lock() - defer this.branchTransactionHashMutex.Unlock() - if this.branchTransactionHash == nil || *this.branchTransactionHash != branchTransactionHash { - this.branchTransactionHash = &branchTransactionHash - - this.hasherMutex.RLock() - copy(this.trits[BRANCH_TRANSACTION_HASH_OFFSET:BRANCH_TRANSACTION_HASH_END], trinary.MustTrytesToTrits(branchTransactionHash)[:BRANCH_TRANSACTION_HASH_SIZE]) - this.hasherMutex.RUnlock() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.branchTransactionHashMutex.RUnlock() - } - - return false -} - -// getter for the head flag (supports concurrency) -func (this *MetaTransaction) IsHead() (result bool) { - this.headMutex.RLock() - if this.head == nil { - this.headMutex.RUnlock() - this.headMutex.Lock() - defer this.headMutex.Unlock() - if this.head == nil { - head := this.trits[HEAD_OFFSET] == 1 - - this.head = &head - } - } else { - defer this.headMutex.RUnlock() - } - - result = *this.head - - return -} - -// setter for the head flag (supports concurrency) -func (this *MetaTransaction) SetHead(head bool) bool { - this.headMutex.RLock() - if this.head == nil || *this.head != head { - this.headMutex.RUnlock() - this.headMutex.Lock() - defer this.headMutex.Unlock() - if this.head == nil || *this.head != head { - this.head = &head - - this.hasherMutex.RLock() - if head { - this.trits[HEAD_OFFSET] = 1 - } else { - this.trits[HEAD_OFFSET] = 0 - } - this.hasherMutex.RUnlock() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.headMutex.RUnlock() - } - - return false -} - -// getter for the tail flag (supports concurrency) -func (this *MetaTransaction) IsTail() (result bool) { - this.tailMutex.RLock() - if this.tail == nil { - this.tailMutex.RUnlock() - this.tailMutex.Lock() - defer this.tailMutex.Unlock() - if this.tail == nil { - tail := this.trits[TAIL_OFFSET] == 1 - - this.tail = &tail - } - } else { - defer this.tailMutex.RUnlock() - } - - result = *this.tail - - return -} - -// setter for the tail flag (supports concurrency) -func (this *MetaTransaction) SetTail(tail bool) bool { - this.tailMutex.RLock() - if this.tail == nil || *this.tail != tail { - this.tailMutex.RUnlock() - this.tailMutex.Lock() - defer this.tailMutex.Unlock() - if this.tail == nil || *this.tail != tail { - this.tail = &tail - - this.hasherMutex.RLock() - if tail { - this.trits[TAIL_OFFSET] = 1 - } else { - this.trits[TAIL_OFFSET] = 0 - } - this.hasherMutex.RUnlock() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.tailMutex.RUnlock() - } - - return false -} - -// getter for the transaction type (supports concurrency) -func (this *MetaTransaction) GetTransactionType() (result trinary.Trytes) { - this.transactionTypeMutex.RLock() - if this.transactionType == nil { - this.transactionTypeMutex.RUnlock() - this.transactionTypeMutex.Lock() - defer this.transactionTypeMutex.Unlock() - if this.transactionType == nil { - transactionType := trinary.MustTritsToTrytes(this.trits[TRANSACTION_TYPE_OFFSET:TRANSACTION_TYPE_END]) - - this.transactionType = &transactionType - } - } else { - defer this.transactionTypeMutex.RUnlock() - } - - result = *this.transactionType - - return -} - -// setter for the transaction type (supports concurrency) -func (this *MetaTransaction) SetTransactionType(transactionType trinary.Trytes) bool { - this.transactionTypeMutex.RLock() - if this.transactionType == nil || *this.transactionType != transactionType { - this.transactionTypeMutex.RUnlock() - this.transactionTypeMutex.Lock() - defer this.transactionTypeMutex.Unlock() - if this.transactionType == nil || *this.transactionType != transactionType { - this.transactionType = &transactionType - - this.hasherMutex.RLock() - copy(this.trits[TRANSACTION_TYPE_OFFSET:TRANSACTION_TYPE_END], trinary.MustTrytesToTrits(transactionType)[:TRANSACTION_TYPE_SIZE]) - this.hasherMutex.RUnlock() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.transactionTypeMutex.RUnlock() - } - - return false -} - -// getter for the data slice (supports concurrency) -func (this *MetaTransaction) GetData() (result trinary.Trits) { - this.dataMutex.RLock() - if this.data == nil { - this.dataMutex.RUnlock() - this.dataMutex.Lock() - defer this.dataMutex.Unlock() - if this.data == nil { - this.data = this.trits[DATA_OFFSET:DATA_END] - } - } else { - defer this.dataMutex.RUnlock() - } - - result = this.data - - return -} - -func (this *MetaTransaction) GetTrits() (result trinary.Trits) { - result = make(trinary.Trits, len(this.trits)) - - this.hasherMutex.Lock() - copy(result, this.trits) - this.hasherMutex.Unlock() - - return -} - -func (this *MetaTransaction) GetBytes() (result []byte) { - this.bytesMutex.RLock() - if this.bytes == nil { - this.bytesMutex.RUnlock() - this.bytesMutex.Lock() - defer this.bytesMutex.Unlock() - - this.hasherMutex.Lock() - this.bytes = trinary.MustTritsToBytes(this.trits) - this.hasherMutex.Unlock() - } else { - this.bytesMutex.RUnlock() - } - - result = make([]byte, len(this.bytes)) - copy(result, this.bytes) - - return -} - -func (this *MetaTransaction) GetNonce() trinary.Trytes { - this.nonceMutex.RLock() - if this.nonce == nil { - this.nonceMutex.RUnlock() - this.nonceMutex.Lock() - defer this.nonceMutex.Unlock() - if this.nonce == nil { - nonce := trinary.MustTritsToTrytes(this.trits[NONCE_OFFSET:NONCE_END]) - - this.nonce = &nonce - } - } else { - defer this.nonceMutex.RUnlock() - } - - return *this.nonce -} - -func (this *MetaTransaction) SetNonce(nonce trinary.Trytes) bool { - this.nonceMutex.RLock() - if this.nonce == nil || *this.nonce != nonce { - this.nonceMutex.RUnlock() - this.nonceMutex.Lock() - defer this.nonceMutex.Unlock() - if this.nonce == nil || *this.nonce != nonce { - this.nonce = &nonce - - this.hasherMutex.RLock() - copy(this.trits[NONCE_OFFSET:NONCE_END], trinary.MustTrytesToTrits(nonce)[:NONCE_SIZE]) - this.hasherMutex.RUnlock() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.nonceMutex.RUnlock() - } - - return false -} - -// returns true if the transaction contains unsaved changes (supports concurrency) -func (this *MetaTransaction) GetModified() bool { - this.modifiedMutex.RLock() - defer this.modifiedMutex.RUnlock() - - return this.modified -} - -// sets the modified flag which controls if a transaction is going to be saved (supports concurrency) -func (this *MetaTransaction) SetModified(modified bool) { - this.modifiedMutex.Lock() - defer this.modifiedMutex.Unlock() - - this.modified = modified -} - -func (this *MetaTransaction) DoProofOfWork(mwm int) error { - this.hasherMutex.Lock() - powTrytes := trinary.MustTritsToTrytes(this.getHashEssence()) - _, pow := pow.GetFastestProofOfWorkImpl() - nonce, err := pow(powTrytes, mwm) - this.hasherMutex.Unlock() - - if err != nil { - return fmt.Errorf("PoW failed: %w", err) - } - this.SetNonce(nonce) - - return nil -} - -func (this *MetaTransaction) Validate() error { - // check that the weight magnitude is valid - weightMagnitude := this.GetWeightMagnitude() - if weightMagnitude < MIN_WEIGHT_MAGNITUDE { - return fmt.Errorf("%w: got=%d, want=%d", ErrInvalidWeightMagnitude, weightMagnitude, MIN_WEIGHT_MAGNITUDE) - } - - return nil -} diff --git a/packages/model/meta_transaction/meta_transaction_test.go b/packages/model/meta_transaction/meta_transaction_test.go deleted file mode 100644 index 7a349f2d0e3d928f53960c2f917b6cd84cbf93f1..0000000000000000000000000000000000000000 --- a/packages/model/meta_transaction/meta_transaction_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package meta_transaction - -import ( - "sync" - "testing" - - "github.com/iotaledger/iota.go/trinary" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -const ( - shardMarker = trinary.Trytes("NPHTQORL9XKA") - trunkTransactionHash = trinary.Trytes("99999999999999999999999999999999999999999999999999999999999999999999999999999999A") - branchTransactionHash = trinary.Trytes("99999999999999999999999999999999999999999999999999999999999999999999999999999999B") - head = true - tail = true - transactionType = trinary.Trytes("9999999999999999999999") -) - -func newTestTransaction() *MetaTransaction { - tx := New() - tx.SetShardMarker(shardMarker) - tx.SetTrunkTransactionHash(trunkTransactionHash) - tx.SetBranchTransactionHash(branchTransactionHash) - tx.SetHead(head) - tx.SetTail(tail) - tx.SetTransactionType(transactionType) - - return tx -} - -func TestDoPow(t *testing.T) { - tx := newTestTransaction() - require.NoError(t, tx.DoProofOfWork(10)) - - assert.GreaterOrEqual(t, tx.GetWeightMagnitude(), 10) -} - -func TestMetaTransaction_SettersGetters(t *testing.T) { - tx := newTestTransaction() - - assert.Equal(t, tx.GetWeightMagnitude(), 0) - assert.Equal(t, tx.GetShardMarker(), shardMarker) - assert.Equal(t, tx.GetTrunkTransactionHash(), trunkTransactionHash) - assert.Equal(t, tx.GetBranchTransactionHash(), branchTransactionHash) - assert.Equal(t, tx.IsHead(), head) - assert.Equal(t, tx.IsTail(), tail) - assert.Equal(t, tx.GetTransactionType(), transactionType) - metaTx, err := FromBytes(tx.GetBytes()) - require.NoError(t, err) - assert.Equal(t, tx.GetHash(), metaTx.GetHash()) - - assert.EqualValues(t, "KKDVHBENVLQUNO9WOWWEJPBBHUSYRSRKIMZWCFCDB9RYZKYWLAYWRIBRQETBFKE9TIVWQPCKFWAMCLCAV", tx.GetHash()) -} - -func BenchmarkMetaTransaction_GetHash(b *testing.B) { - var waitGroup sync.WaitGroup - - for i := 0; i < b.N; i++ { - waitGroup.Add(1) - - go func() { - New().GetHash() - - waitGroup.Done() - }() - } - - waitGroup.Wait() -} diff --git a/packages/model/transactionmetadata/const.go b/packages/model/transactionmetadata/const.go deleted file mode 100644 index 100a51ddaafa9632f30ed2d5d7888f116860df01..0000000000000000000000000000000000000000 --- a/packages/model/transactionmetadata/const.go +++ /dev/null @@ -1,21 +0,0 @@ -package transactionmetadata - -// region constants and variables ////////////////////////////////////////////////////////////////////////////////////// - -const ( - MARSHALED_HASH_START = 0 - MARSHALED_RECEIVED_TIME_START = MARSHALED_HASH_END - MARSHALED_FLAGS_START = MARSHALED_RECEIVED_TIME_END - - MARSHALED_HASH_END = MARSHALED_HASH_START + MARSHALED_HASH_SIZE - MARSHALED_RECEIVED_TIME_END = MARSHALED_RECEIVED_TIME_START + MARSHALED_RECEIVED_TIME_SIZE - MARSHALED_FLAGS_END = MARSHALED_FLAGS_START + MARSHALED_FLAGS_SIZE - - MARSHALED_HASH_SIZE = 81 - MARSHALED_RECEIVED_TIME_SIZE = 15 - MARSHALED_FLAGS_SIZE = 1 - - MARSHALED_TOTAL_SIZE = MARSHALED_FLAGS_END -) - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/model/transactionmetadata/transactionmetadata.go b/packages/model/transactionmetadata/transactionmetadata.go deleted file mode 100644 index 66a2796601db9d236556d2d079340f0954c163a0..0000000000000000000000000000000000000000 --- a/packages/model/transactionmetadata/transactionmetadata.go +++ /dev/null @@ -1,277 +0,0 @@ -package transactionmetadata - -import ( - "fmt" - "sync" - "time" - - "github.com/iotaledger/goshimmer/packages/model" - "github.com/iotaledger/hive.go/bitmask" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -// region type definition and constructor ////////////////////////////////////////////////////////////////////////////// - -type TransactionMetadata struct { - hash trinary.Trytes - hashMutex sync.RWMutex - bundleHeadHash trinary.Trytes - bundleHeadHashMutex sync.RWMutex - receivedTime time.Time - receivedTimeMutex sync.RWMutex - solid bool - solidMutex sync.RWMutex - liked bool - likedMutex sync.RWMutex - finalized bool - finalizedMutex sync.RWMutex - modified bool - modifiedMutex sync.RWMutex -} - -func New(hash trinary.Trytes) *TransactionMetadata { - return &TransactionMetadata{ - hash: hash, - receivedTime: time.Now(), - solid: false, - liked: false, - finalized: false, - modified: true, - } -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region getters and setters ////////////////////////////////////////////////////////////////////////////////////////// - -func (metadata *TransactionMetadata) GetHash() trinary.Trytes { - metadata.hashMutex.RLock() - defer metadata.hashMutex.RUnlock() - - return metadata.hash -} - -func (metadata *TransactionMetadata) SetHash(hash trinary.Trytes) { - metadata.hashMutex.RLock() - if metadata.hash != hash { - metadata.hashMutex.RUnlock() - metadata.hashMutex.Lock() - defer metadata.hashMutex.Unlock() - if metadata.hash != hash { - metadata.hash = hash - - metadata.SetModified(true) - } - } else { - metadata.hashMutex.RUnlock() - } -} - -func (metadata *TransactionMetadata) GetBundleHeadHash() trinary.Trytes { - metadata.bundleHeadHashMutex.RLock() - defer metadata.bundleHeadHashMutex.RUnlock() - - return metadata.bundleHeadHash -} - -func (metadata *TransactionMetadata) SetBundleHeadHash(bundleTailHash trinary.Trytes) { - metadata.bundleHeadHashMutex.RLock() - if metadata.bundleHeadHash != bundleTailHash { - metadata.bundleHeadHashMutex.RUnlock() - metadata.bundleHeadHashMutex.Lock() - defer metadata.bundleHeadHashMutex.Unlock() - if metadata.bundleHeadHash != bundleTailHash { - metadata.bundleHeadHash = bundleTailHash - - metadata.SetModified(true) - } - } else { - metadata.bundleHeadHashMutex.RUnlock() - } -} - -func (metadata *TransactionMetadata) GetReceivedTime() time.Time { - metadata.receivedTimeMutex.RLock() - defer metadata.receivedTimeMutex.RUnlock() - - return metadata.receivedTime -} - -func (metadata *TransactionMetadata) SetReceivedTime(receivedTime time.Time) { - metadata.receivedTimeMutex.RLock() - if metadata.receivedTime != receivedTime { - metadata.receivedTimeMutex.RUnlock() - metadata.receivedTimeMutex.Lock() - defer metadata.receivedTimeMutex.Unlock() - if metadata.receivedTime != receivedTime { - metadata.receivedTime = receivedTime - - metadata.SetModified(true) - } - } else { - metadata.receivedTimeMutex.RUnlock() - } -} - -func (metadata *TransactionMetadata) GetSolid() bool { - metadata.solidMutex.RLock() - defer metadata.solidMutex.RUnlock() - - return metadata.solid -} - -func (metadata *TransactionMetadata) SetSolid(solid bool) bool { - metadata.solidMutex.RLock() - if metadata.solid != solid { - metadata.solidMutex.RUnlock() - metadata.solidMutex.Lock() - defer metadata.solidMutex.Unlock() - if metadata.solid != solid { - metadata.solid = solid - - metadata.SetModified(true) - - return true - } - } else { - metadata.solidMutex.RUnlock() - } - - return false -} - -func (metadata *TransactionMetadata) GetLiked() bool { - metadata.likedMutex.RLock() - defer metadata.likedMutex.RUnlock() - - return metadata.liked -} - -func (metadata *TransactionMetadata) SetLiked(liked bool) { - metadata.likedMutex.RLock() - if metadata.liked != liked { - metadata.likedMutex.RUnlock() - metadata.likedMutex.Lock() - defer metadata.likedMutex.Unlock() - if metadata.liked != liked { - metadata.liked = liked - - metadata.SetModified(true) - } - } else { - metadata.likedMutex.RUnlock() - } -} - -func (metadata *TransactionMetadata) GetFinalized() bool { - metadata.finalizedMutex.RLock() - defer metadata.finalizedMutex.RUnlock() - - return metadata.finalized -} - -func (metadata *TransactionMetadata) SetFinalized(finalized bool) { - metadata.finalizedMutex.RLock() - if metadata.finalized != finalized { - metadata.finalizedMutex.RUnlock() - metadata.finalizedMutex.Lock() - defer metadata.finalizedMutex.Unlock() - if metadata.finalized != finalized { - metadata.finalized = finalized - - metadata.SetModified(true) - } - } else { - metadata.finalizedMutex.RUnlock() - } -} - -// returns true if the transaction contains unsaved changes (supports concurrency) -func (metadata *TransactionMetadata) GetModified() bool { - metadata.modifiedMutex.RLock() - defer metadata.modifiedMutex.RUnlock() - - return metadata.modified -} - -// sets the modified flag which controls if a transaction is going to be saved (supports concurrency) -func (metadata *TransactionMetadata) SetModified(modified bool) { - metadata.modifiedMutex.Lock() - defer metadata.modifiedMutex.Unlock() - - metadata.modified = modified -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region marshaling functions ///////////////////////////////////////////////////////////////////////////////////////// - -func (metadata *TransactionMetadata) Marshal() ([]byte, error) { - marshaledMetadata := make([]byte, MARSHALED_TOTAL_SIZE) - - metadata.receivedTimeMutex.RLock() - defer metadata.receivedTimeMutex.RUnlock() - metadata.solidMutex.RLock() - defer metadata.solidMutex.RUnlock() - metadata.likedMutex.RLock() - defer metadata.likedMutex.RUnlock() - metadata.finalizedMutex.RLock() - defer metadata.finalizedMutex.RUnlock() - - copy(marshaledMetadata[MARSHALED_HASH_START:MARSHALED_HASH_END], typeutils.StringToBytes(metadata.hash)) - - marshaledReceivedTime, err := metadata.receivedTime.MarshalBinary() - if err != nil { - return nil, fmt.Errorf("%w: failed to marshal received time: %s", model.ErrMarshalFailed, err.Error()) - } - copy(marshaledMetadata[MARSHALED_RECEIVED_TIME_START:MARSHALED_RECEIVED_TIME_END], marshaledReceivedTime) - - var booleanFlags bitmask.BitMask - if metadata.solid { - booleanFlags = booleanFlags.SetFlag(0) - } - if metadata.liked { - booleanFlags = booleanFlags.SetFlag(1) - } - if metadata.finalized { - booleanFlags = booleanFlags.SetFlag(2) - } - marshaledMetadata[MARSHALED_FLAGS_START] = byte(booleanFlags) - - return marshaledMetadata, nil -} - -func (metadata *TransactionMetadata) Unmarshal(data []byte) error { - metadata.hashMutex.Lock() - defer metadata.hashMutex.Unlock() - metadata.receivedTimeMutex.Lock() - defer metadata.receivedTimeMutex.Unlock() - metadata.solidMutex.Lock() - defer metadata.solidMutex.Unlock() - metadata.likedMutex.Lock() - defer metadata.likedMutex.Unlock() - metadata.finalizedMutex.Lock() - defer metadata.finalizedMutex.Unlock() - - metadata.hash = typeutils.BytesToString(data[MARSHALED_HASH_START:MARSHALED_HASH_END]) - - if err := metadata.receivedTime.UnmarshalBinary(data[MARSHALED_RECEIVED_TIME_START:MARSHALED_RECEIVED_TIME_END]); err != nil { - return fmt.Errorf("%w: could not unmarshal the received time: %s", model.ErrUnmarshalFailed, err.Error()) - } - - booleanFlags := bitmask.BitMask(data[MARSHALED_FLAGS_START]) - if booleanFlags.HasFlag(0) { - metadata.solid = true - } - if booleanFlags.HasFlag(1) { - metadata.liked = true - } - if booleanFlags.HasFlag(2) { - metadata.finalized = true - } - - return nil -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/model/value_transaction/constants.go b/packages/model/value_transaction/constants.go deleted file mode 100644 index 06a4c749b4b9ae08c8a030dcedb095c4bb6edb8a..0000000000000000000000000000000000000000 --- a/packages/model/value_transaction/constants.go +++ /dev/null @@ -1,31 +0,0 @@ -package value_transaction - -import ( - "strings" - - "github.com/iotaledger/iota.go/trinary" -) - -const ( - ADDRESS_OFFSET = 0 - VALUE_OFFSET = ADDRESS_END - TIMESTAMP_OFFSET = VALUE_END - SIGNATURE_MESSAGE_FRAGMENT_OFFSET = TIMESTAMP_END - - ADDRESS_SIZE = 243 - VALUE_SIZE = 81 - TIMESTAMP_SIZE = 27 - SIGNATURE_MESSAGE_FRAGMENT_SIZE = 6561 - BUNDLE_ESSENCE_SIZE = ADDRESS_SIZE + VALUE_SIZE + SIGNATURE_MESSAGE_FRAGMENT_SIZE - - ADDRESS_END = ADDRESS_OFFSET + ADDRESS_SIZE - VALUE_END = VALUE_OFFSET + VALUE_SIZE - TIMESTAMP_END = TIMESTAMP_OFFSET + TIMESTAMP_SIZE - SIGNATURE_MESSAGE_FRAGMENT_END = SIGNATURE_MESSAGE_FRAGMENT_OFFSET + SIGNATURE_MESSAGE_FRAGMENT_SIZE - - TOTAL_SIZE = SIGNATURE_MESSAGE_FRAGMENT_END -) - -var ( - EMPTY_SIGNATURE = trinary.Trytes(strings.Repeat("9", SIGNATURE_MESSAGE_FRAGMENT_SIZE/3)) -) diff --git a/packages/model/value_transaction/value_transaction.go b/packages/model/value_transaction/value_transaction.go deleted file mode 100644 index 393e6560a0d3b57915c2d2ad7d655026910055d0..0000000000000000000000000000000000000000 --- a/packages/model/value_transaction/value_transaction.go +++ /dev/null @@ -1,257 +0,0 @@ -package value_transaction - -import ( - "sync" - - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/iota.go/trinary" -) - -type ValueTransaction struct { - *meta_transaction.MetaTransaction - - address *trinary.Trytes - addressMutex sync.RWMutex - value *int64 - valueMutex sync.RWMutex - timestamp *uint - timestampMutex sync.RWMutex - signatureMessageFragment *trinary.Trytes - signatureMessageFragmentMutex sync.RWMutex - - trits trinary.Trits -} - -func New() (result *ValueTransaction) { - result = &ValueTransaction{ - MetaTransaction: meta_transaction.New(), - } - - result.trits = result.MetaTransaction.GetData() - - return -} - -func FromMetaTransaction(metaTransaction *meta_transaction.MetaTransaction) *ValueTransaction { - return &ValueTransaction{ - MetaTransaction: metaTransaction, - trits: metaTransaction.GetData(), - } -} - -func FromBytes(bytes []byte) (result *ValueTransaction) { - trits := trinary.MustBytesToTrits(bytes) - result = &ValueTransaction{ - MetaTransaction: meta_transaction.FromTrits(trits[:meta_transaction.MARSHALED_TOTAL_SIZE]), - } - - result.trits = result.MetaTransaction.GetData() - - return -} - -// getter for the address (supports concurrency) -func (this *ValueTransaction) GetAddress() (result trinary.Trytes) { - this.addressMutex.RLock() - if this.address == nil { - this.addressMutex.RUnlock() - this.addressMutex.Lock() - defer this.addressMutex.Unlock() - if this.address == nil { - address := trinary.MustTritsToTrytes(this.trits[ADDRESS_OFFSET:ADDRESS_END]) - - this.address = &address - } - } else { - defer this.addressMutex.RUnlock() - } - - result = *this.address - - return -} - -// setter for the address (supports concurrency) -func (this *ValueTransaction) SetAddress(address trinary.Trytes) bool { - this.addressMutex.RLock() - if this.address == nil || *this.address != address { - this.addressMutex.RUnlock() - this.addressMutex.Lock() - defer this.addressMutex.Unlock() - if this.address == nil || *this.address != address { - this.address = &address - - this.BlockHasher() - copy(this.trits[ADDRESS_OFFSET:ADDRESS_END], trinary.MustTrytesToTrits(address)[:ADDRESS_SIZE]) - this.UnblockHasher() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.addressMutex.RUnlock() - } - - return false -} - -// getter for the value (supports concurrency) -func (this *ValueTransaction) GetValue() (result int64) { - this.valueMutex.RLock() - if this.value == nil { - this.valueMutex.RUnlock() - this.valueMutex.Lock() - defer this.valueMutex.Unlock() - if this.value == nil { - value := trinary.TritsToInt(this.trits[VALUE_OFFSET:VALUE_END]) - - this.value = &value - } - } else { - defer this.valueMutex.RUnlock() - } - - result = *this.value - - return -} - -// setter for the value (supports concurrency) -func (this *ValueTransaction) SetValue(value int64) bool { - this.valueMutex.RLock() - if this.value == nil || *this.value != value { - this.valueMutex.RUnlock() - this.valueMutex.Lock() - defer this.valueMutex.Unlock() - if this.value == nil || *this.value != value { - this.value = &value - - this.BlockHasher() - copy(this.trits[VALUE_OFFSET:], trinary.IntToTrits(value)) - this.UnblockHasher() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.valueMutex.RUnlock() - } - - return false -} - -// getter for the timestamp (supports concurrency) -func (this *ValueTransaction) GetTimestamp() (result uint) { - this.timestampMutex.RLock() - if this.timestamp == nil { - this.timestampMutex.RUnlock() - this.timestampMutex.Lock() - defer this.timestampMutex.Unlock() - if this.timestamp == nil { - timestamp := uint(trinary.TritsToInt(this.trits[TIMESTAMP_OFFSET:TIMESTAMP_END])) - - this.timestamp = ×tamp - } - } else { - defer this.timestampMutex.RUnlock() - } - - result = *this.timestamp - - return -} - -// setter for the timestamp (supports concurrency) -func (this *ValueTransaction) SetTimestamp(timestamp uint) bool { - this.timestampMutex.RLock() - if this.timestamp == nil || *this.timestamp != timestamp { - this.timestampMutex.RUnlock() - this.timestampMutex.Lock() - defer this.timestampMutex.Unlock() - if this.timestamp == nil || *this.timestamp != timestamp { - this.timestamp = ×tamp - - this.BlockHasher() - copy(this.trits[TIMESTAMP_OFFSET:TIMESTAMP_END], trinary.MustPadTrits(trinary.IntToTrits(int64(timestamp)), TIMESTAMP_SIZE)[:TIMESTAMP_SIZE]) - this.UnblockHasher() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.timestampMutex.RUnlock() - } - - return false -} - -func (this *ValueTransaction) GetBundleEssence(includeSignatureMessageFragment bool) (result trinary.Trits) { - this.signatureMessageFragmentMutex.RLock() - - result = make(trinary.Trits, BUNDLE_ESSENCE_SIZE) - - this.addressMutex.RLock() - copy(result[0:], this.trits[ADDRESS_OFFSET:VALUE_END]) - this.addressMutex.RUnlock() - - if includeSignatureMessageFragment { - copy(result[VALUE_END:], this.trits[SIGNATURE_MESSAGE_FRAGMENT_OFFSET:SIGNATURE_MESSAGE_FRAGMENT_END]) - } - - this.signatureMessageFragmentMutex.RUnlock() - - return -} - -// getter for the signatureMessageFragmetn (supports concurrency) -func (this *ValueTransaction) GetSignatureMessageFragment() (result trinary.Trytes) { - this.signatureMessageFragmentMutex.RLock() - if this.signatureMessageFragment == nil { - this.signatureMessageFragmentMutex.RUnlock() - this.signatureMessageFragmentMutex.Lock() - defer this.signatureMessageFragmentMutex.Unlock() - if this.signatureMessageFragment == nil { - signatureMessageFragment := trinary.MustTritsToTrytes(this.trits[SIGNATURE_MESSAGE_FRAGMENT_OFFSET:SIGNATURE_MESSAGE_FRAGMENT_END]) - - this.signatureMessageFragment = &signatureMessageFragment - } - } else { - defer this.signatureMessageFragmentMutex.RUnlock() - } - - result = *this.signatureMessageFragment - - return -} - -// setter for the nonce (supports concurrency) -func (this *ValueTransaction) SetSignatureMessageFragment(signatureMessageFragment trinary.Trytes) bool { - this.signatureMessageFragmentMutex.RLock() - if this.signatureMessageFragment == nil || *this.signatureMessageFragment != signatureMessageFragment { - this.signatureMessageFragmentMutex.RUnlock() - this.signatureMessageFragmentMutex.Lock() - defer this.signatureMessageFragmentMutex.Unlock() - if this.signatureMessageFragment == nil || *this.signatureMessageFragment != signatureMessageFragment { - this.signatureMessageFragment = &signatureMessageFragment - - this.BlockHasher() - copy(this.trits[SIGNATURE_MESSAGE_FRAGMENT_OFFSET:SIGNATURE_MESSAGE_FRAGMENT_END], trinary.MustTrytesToTrits(signatureMessageFragment)[:SIGNATURE_MESSAGE_FRAGMENT_SIZE]) - this.UnblockHasher() - - this.SetModified(true) - this.ReHash() - - return true - } - } else { - this.signatureMessageFragmentMutex.RUnlock() - } - - return false -} diff --git a/packages/model/value_transaction/value_transaction_test.go b/packages/model/value_transaction/value_transaction_test.go deleted file mode 100644 index c1f732d69dee0eca2717b88e362a4859b89e564b..0000000000000000000000000000000000000000 --- a/packages/model/value_transaction/value_transaction_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package value_transaction - -import ( - "fmt" - "testing" - - "github.com/iotaledger/iota.go/trinary" - "github.com/magiconair/properties/assert" -) - -func TestValueTransaction_SettersGetters(t *testing.T) { - address := trinary.Trytes("A9999999999999999999999999999999999999999999999999999999999999999999999999999999F") - - transaction := New() - transaction.SetAddress(address) - - transactionCopy := FromMetaTransaction(transaction.MetaTransaction) - fmt.Println(transactionCopy.GetAddress()) - - assert.Equal(t, transaction.GetAddress(), address) - //assert.Equal(t, transaction.GetHash(), FromBytes(transaction.GetBytes()).GetHash()) - - fmt.Println(transaction.GetHash()) - fmt.Println(transaction.GetAddress()) -} diff --git a/packages/netutil/buffconn/buffconn.go b/packages/netutil/buffconn/buffconn.go deleted file mode 100644 index c1ad9eaa28544f3091a1a3788798a4d2cdf6ae83..0000000000000000000000000000000000000000 --- a/packages/netutil/buffconn/buffconn.go +++ /dev/null @@ -1,190 +0,0 @@ -package buffconn - -import ( - "encoding/binary" - "errors" - "fmt" - "net" - "sync" - "time" - - "github.com/iotaledger/hive.go/events" - "go.uber.org/atomic" -) - -const ( - // MaxMessageSize is the maximum message size in bytes. - MaxMessageSize = 4096 - // IOTimeout specifies the timeout for sending and receiving multi packet messages. - IOTimeout = 4 * time.Second - - headerSize = 4 // size of the header: uint32 -) - -// Errors returned by the BufferedConnection. -var ( - ErrInvalidHeader = errors.New("invalid message header") - ErrInsufficientBuffer = errors.New("insufficient buffer") -) - -// BufferedConnectionEvents contains all the events that are triggered during the peer discovery. -type BufferedConnectionEvents struct { - ReceiveMessage *events.Event - Close *events.Event -} - -// BufferedConnection is a wrapper for sending and reading messages with a buffer. -type BufferedConnection struct { - Events BufferedConnectionEvents - - conn net.Conn - incomingHeaderBuffer []byte - closeOnce sync.Once - - bytesRead *atomic.Uint32 - bytesWritten *atomic.Uint32 -} - -// NewBufferedConnection creates a new BufferedConnection from a net.Conn. -func NewBufferedConnection(conn net.Conn) *BufferedConnection { - return &BufferedConnection{ - Events: BufferedConnectionEvents{ - ReceiveMessage: events.NewEvent(events.ByteSliceCaller), - Close: events.NewEvent(events.CallbackCaller), - }, - conn: conn, - incomingHeaderBuffer: make([]byte, headerSize), - bytesRead: atomic.NewUint32(0), - bytesWritten: atomic.NewUint32(0), - } -} - -// Close closes the connection. -// Any blocked Read or Write operations will be unblocked and return errors. -func (c *BufferedConnection) Close() (err error) { - c.closeOnce.Do(func() { - err = c.conn.Close() - // close in separate go routine to avoid deadlocks - go c.Events.Close.Trigger() - }) - return err -} - -// LocalAddr returns the local network address. -func (c *BufferedConnection) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -// RemoteAddr returns the remote network address. -func (c *BufferedConnection) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -// BytesRead returns the total number of bytes read. -func (c *BufferedConnection) BytesRead() uint32 { - return c.bytesRead.Load() -} - -// BytesWritten returns the total number of bytes written. -func (c *BufferedConnection) BytesWritten() uint32 { - return c.bytesWritten.Load() -} - -// Read starts reading on the connection, it only returns when an error occurred or when Close has been called. -// If a complete message has been received and ReceiveMessage event is triggered with its complete payload. -// If read leads to an error, the loop will be stopped and that error returned. -func (c *BufferedConnection) Read() error { - buffer := make([]byte, MaxMessageSize) - - for { - n, err := c.readMessage(buffer) - if err != nil { - return err - } - if n > 0 { - c.Events.ReceiveMessage.Trigger(buffer[:n]) - } - } -} - -// Write sends a stream of bytes as messages. -// Each array of bytes you pass in will be pre-pended with it's size. If the -// connection isn't open you will receive an error. If not all bytes can be -// written, Write will keep trying until the full message is delivered, or the -// connection is broken. -func (c *BufferedConnection) Write(msg []byte) (int, error) { - if l := len(msg); l > MaxMessageSize { - panic(fmt.Sprintf("invalid message length: %d", l)) - } - - buffer := append(newHeader(len(msg)), msg...) - - if err := c.conn.SetWriteDeadline(time.Now().Add(IOTimeout)); err != nil { - return 0, fmt.Errorf("error while setting timeout: %w", err) - } - - toWrite := len(buffer) - for bytesWritten := 0; bytesWritten < toWrite; { - n, err := c.conn.Write(buffer[bytesWritten:]) - bytesWritten += n - c.bytesWritten.Add(uint32(n)) - if err != nil { - return bytesWritten, err - } - } - return toWrite - headerSize, nil -} - -func (c *BufferedConnection) read(buffer []byte) (int, error) { - toRead := len(buffer) - for bytesRead := 0; bytesRead < toRead; { - n, err := c.conn.Read(buffer[bytesRead:]) - bytesRead += n - c.bytesRead.Add(uint32(n)) - if err != nil { - return bytesRead, err - } - } - return toRead, nil -} - -func (c *BufferedConnection) readMessage(buffer []byte) (int, error) { - if err := c.conn.SetReadDeadline(time.Time{}); err != nil { - return 0, fmt.Errorf("error while unsetting timeout: %w", err) - } - _, err := c.read(c.incomingHeaderBuffer) - if err != nil { - return 0, err - } - - msgLength, err := parseHeader(c.incomingHeaderBuffer) - if err != nil { - return 0, err - } - if msgLength > len(buffer) { - return 0, ErrInsufficientBuffer - } - - if err := c.conn.SetReadDeadline(time.Now().Add(IOTimeout)); err != nil { - return 0, fmt.Errorf("error while setting timeout: %w", err) - } - return c.read(buffer[:msgLength]) -} - -func newHeader(msgLength int) []byte { - // the header only consists of the message length - header := make([]byte, headerSize) - binary.BigEndian.PutUint32(header, uint32(msgLength)) - return header -} - -func parseHeader(header []byte) (int, error) { - if len(header) != headerSize { - return 0, ErrInvalidHeader - } - msgLength := int(binary.BigEndian.Uint32(header)) - if msgLength > MaxMessageSize { - return 0, ErrInvalidHeader - } - return msgLength, nil -} diff --git a/packages/netutil/buffconn/buffconn_test.go b/packages/netutil/buffconn/buffconn_test.go deleted file mode 100644 index e24506b433b79c298c391acfde015d412b57f629..0000000000000000000000000000000000000000 --- a/packages/netutil/buffconn/buffconn_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package buffconn - -import ( - "errors" - "io" - "net" - "sync" - "testing" - "time" - - "github.com/iotaledger/hive.go/events" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -const graceTime = 10 * time.Millisecond - -var testMsg = []byte("test") - -func TestBufferedConnection(t *testing.T) { - t.Run("Close", func(t *testing.T) { - conn1, conn2 := net.Pipe() - buffConn1 := NewBufferedConnection(conn1) - defer buffConn1.Close() - buffConn2 := NewBufferedConnection(conn2) - defer buffConn2.Close() - - var wg sync.WaitGroup - wg.Add(2) - buffConn2.Events.Close.Attach(events.NewClosure(func() { wg.Done() })) - go func() { - err := buffConn2.Read() - assert.True(t, errors.Is(err, io.ErrClosedPipe), "unexpected error: %s", err) - require.NoError(t, buffConn2.Close()) - wg.Done() - }() - - err := buffConn1.Close() - require.NoError(t, err) - wg.Wait() - }) - - t.Run("Write", func(t *testing.T) { - conn1, conn2 := net.Pipe() - buffConn1 := NewBufferedConnection(conn1) - defer buffConn1.Close() - buffConn2 := NewBufferedConnection(conn2) - defer buffConn2.Close() - - go func() { - _ = buffConn2.Read() - }() - - n, err := buffConn1.Write(testMsg) - require.NoError(t, err) - assert.EqualValues(t, len(testMsg), n) - }) - - t.Run("ReceiveMessage", func(t *testing.T) { - conn1, conn2 := net.Pipe() - buffConn1 := NewBufferedConnection(conn1) - defer buffConn1.Close() - buffConn2 := NewBufferedConnection(conn2) - defer buffConn2.Close() - - var wg sync.WaitGroup - wg.Add(2) - buffConn2.Events.ReceiveMessage.Attach(events.NewClosure(func(data []byte) { - assert.EqualValues(t, testMsg, data) - wg.Done() - })) - go func() { - err := buffConn2.Read() - assert.True(t, errors.Is(err, io.EOF), "unexpected error: %s", err) - wg.Done() - }() - - n, err := buffConn1.Write(testMsg) - require.NoError(t, err) - assert.EqualValues(t, len(testMsg), n) - - time.Sleep(graceTime) - - err = buffConn1.Close() - require.NoError(t, err) - wg.Wait() - }) - - t.Run("ReceiveMany", func(t *testing.T) { - conn1, conn2 := net.Pipe() - buffConn1 := NewBufferedConnection(conn1) - defer buffConn1.Close() - buffConn2 := NewBufferedConnection(conn2) - defer buffConn2.Close() - - const numWrites = 3 - - var wg sync.WaitGroup - wg.Add(numWrites) - buffConn2.Events.ReceiveMessage.Attach(events.NewClosure(func(data []byte) { - assert.Equal(t, testMsg, data) - wg.Done() - })) - go func() { - _ = buffConn2.Read() - }() - - for i := 1; i <= numWrites; i++ { - _, err := buffConn1.Write(testMsg) - require.NoError(t, err) - if i < numWrites { - time.Sleep(IOTimeout + graceTime) - } - } - wg.Wait() - }) - - t.Run("InvalidHeader", func(t *testing.T) { - conn1, conn2 := net.Pipe() - buffConn1 := NewBufferedConnection(conn1) - defer buffConn1.Close() - defer conn2.Close() - - var wg sync.WaitGroup - wg.Add(1) - go func() { - err := buffConn1.Read() - assert.True(t, errors.Is(err, ErrInvalidHeader), "unexpected error: %s", err) - wg.Done() - }() - - _, err := conn2.Write([]byte{0xff, 0xff, 0xff, 0xff}) - require.NoError(t, err) - wg.Wait() - }) -} diff --git a/packages/netutil/netutil.go b/packages/netutil/netutil.go deleted file mode 100644 index b9c4932c95410068dcfc522fe583a914dc1ee972..0000000000000000000000000000000000000000 --- a/packages/netutil/netutil.go +++ /dev/null @@ -1,104 +0,0 @@ -// Package netutil provides utility functions extending the stdnet package. -package netutil - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io/ioutil" - "math/rand" - "net" - "net/http" - "time" -) - -var ( - errInvalidData = errors.New("invalid data received") -) - -// IsIPv4 returns true if ip is an IPv4 address. -func IsIPv4(ip net.IP) bool { - return ip.To4() != nil -} - -// GetPublicIP queries the ipify API for the public IP address. -func GetPublicIP(preferIPv6 bool) (net.IP, error) { - var url string - if preferIPv6 { - url = "https://api6.ipify.org" - } else { - url = "https://api.ipify.org" - } - resp, err := http.Get(url) - if err != nil { - return nil, fmt.Errorf("get failed: %w", err) - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("read failed: %w", err) - } - - // the body only consists of the ip address - ip := net.ParseIP(string(body)) - if ip == nil { - return nil, fmt.Errorf("not an IP: %s", body) - } - return ip, nil -} - -// IsTemporaryError checks whether the given error should be considered temporary. -func IsTemporaryError(err error) bool { - tempErr, ok := err.(interface { - Temporary() bool - }) - return ok && tempErr.Temporary() -} - -// CheckUDP checks whether data send to remote is received at local, otherwise an error is returned. -// If checkAddress is set, it checks whether the IP address that was on the packet matches remote. -// If checkPort is set, it checks whether the port that was on the packet matches remote. -func CheckUDP(local, remote *net.UDPAddr, checkAddress bool, checkPort bool) error { - conn, err := net.ListenUDP("udp", local) - if err != nil { - return fmt.Errorf("listen failed: %w", err) - } - defer conn.Close() - - nonce := generateNonce() - _, err = conn.WriteTo(nonce, remote) - if err != nil { - return fmt.Errorf("write failed: %w", err) - } - - err = conn.SetReadDeadline(time.Now().Add(2 * time.Second)) - if err != nil { - return fmt.Errorf("set timeout failed: %w", err) - } - - p := make([]byte, len(nonce)+1) - n, from, err := conn.ReadFrom(p) - if err != nil { - return fmt.Errorf("read failed: %w", err) - } - if n != len(nonce) || !bytes.Equal(p[:n], nonce) { - return errInvalidData - } - udpAddr := from.(*net.UDPAddr) - if checkAddress && !udpAddr.IP.Equal(remote.IP) { - return fmt.Errorf("IP changed: %s", udpAddr.IP) - } - if checkPort && udpAddr.Port != remote.Port { - return fmt.Errorf("port changed: %d", udpAddr.Port) - } - - return nil -} - -func generateNonce() []byte { - b := make([]byte, 8) - binary.BigEndian.PutUint64(b, rand.Uint64()) - return b -} diff --git a/packages/netutil/netutil_test.go b/packages/netutil/netutil_test.go deleted file mode 100644 index 99fca2cb3dd85242dd2e7cc26f4d97fddf7c68c1..0000000000000000000000000000000000000000 --- a/packages/netutil/netutil_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package netutil - -import ( - "errors" - "fmt" - "net" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestIsIPv4(t *testing.T) { - tests := []struct { - in net.IP - out bool - }{ - {nil, false}, - {net.IPv4zero, true}, - {net.IPv6zero, false}, - {net.ParseIP("127.0.0.1"), true}, - {net.IPv6loopback, false}, - {net.ParseIP("8.8.8.8"), true}, - {net.ParseIP("2001:4860:4860::8888"), false}, - } - for _, tt := range tests { - t.Run(fmt.Sprintf("%v", tt.in), func(t *testing.T) { - assert.Equal(t, IsIPv4(tt.in), tt.out) - }) - } -} - -func TestIsTemporaryError(t *testing.T) { - tests := []struct { - in error - out bool - }{ - {nil, false}, - {errors.New("errorString"), false}, - } - for _, tt := range tests { - t.Run(fmt.Sprintf("%v", tt.in), func(t *testing.T) { - assert.Equal(t, IsTemporaryError(tt.in), tt.out) - }) - } -} - -func TestCheckUDP(t *testing.T) { - local, err := getLocalUDPAddr() - require.NoError(t, err) - assert.NoError(t, CheckUDP(local, local, true, true)) - - invalid := &net.UDPAddr{ - IP: local.IP, - Port: local.Port - 1, - Zone: local.Zone, - } - assert.Error(t, CheckUDP(local, invalid, false, false)) -} - -func getLocalUDPAddr() (*net.UDPAddr, error) { - addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") - if err != nil { - return nil, err - } - conn, err := net.ListenUDP("udp", addr) - if err != nil { - return nil, err - } - return conn.LocalAddr().(*net.UDPAddr), conn.Close() -} diff --git a/packages/parameter/parameter.go b/packages/parameter/parameter.go deleted file mode 100644 index 7d390f1fb76675fdb95a58512c1b04544af5a4c5..0000000000000000000000000000000000000000 --- a/packages/parameter/parameter.go +++ /dev/null @@ -1,64 +0,0 @@ -package parameter - -import ( - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/parameter" - flag "github.com/spf13/pflag" - "github.com/spf13/viper" -) - -var ( - // flags - configName = flag.StringP("config", "c", "config", "Filename of the config file without the file extension") - configDirPath = flag.StringP("config-dir", "d", ".", "Path to the directory containing the config file") - - // viper - NodeConfig *viper.Viper - - // logger - defaultLoggerConfig = logger.Config{ - Level: "info", - DisableCaller: false, - DisableStacktrace: false, - Encoding: "console", - OutputPaths: []string{"goshimmer.log"}, - DisableEvents: false, - } -) - -func init() { - // set the default logger config - NodeConfig = viper.New() - NodeConfig.SetDefault(logger.ViperKey, defaultLoggerConfig) -} - -// FetchConfig fetches config values from a dir defined via CLI flag --config-dir (or the current working dir if not set). -// -// It automatically reads in a single config file starting with "config" (can be changed via the --config CLI flag) -// and ending with: .json, .toml, .yaml or .yml (in this sequence). -func FetchConfig(printConfig bool, ignoreSettingsAtPrint ...[]string) error { - err := parameter.LoadConfigFile(NodeConfig, *configDirPath, *configName, true, false) - if err != nil { - return err - } - - if printConfig { - parameter.PrintConfig(NodeConfig, ignoreSettingsAtPrint...) - } - return nil -} - -// LoadDefaultConfig only binds the flags, but does not load any config file. -func LoadDefaultConfig(printConfig bool) error { - // only bind the flags - flag.Parse() - err := NodeConfig.BindPFlags(flag.CommandLine) - if err != nil { - return err - } - - if printConfig { - parameter.PrintConfig(NodeConfig) - } - return nil -} diff --git a/packages/pow/pow.go b/packages/pow/pow.go new file mode 100644 index 0000000000000000000000000000000000000000..3d60d13c55ebc0e3a1e945e11f40f2a1c4717643 --- /dev/null +++ b/packages/pow/pow.go @@ -0,0 +1,158 @@ +package pow + +import ( + "context" + "encoding/binary" + "errors" + "hash" + "math" + "math/big" + "sync" + "sync/atomic" +) + +// errors returned by the PoW +var ( + ErrCancelled = errors.New("canceled") + ErrDone = errors.New("done") +) + +// NonceBytes specifies the number of bytes required for the nonce. +const NonceBytes = 8 + +// Hash identifies a cryptographic hash function that is implemented in another package. +type Hash interface { + // Size returns the length, in bytes, of a digest resulting from the given hash function. + Size() int + // New returns a new hash.Hash calculating the given hash function. + New() hash.Hash +} + +// The Worker provides PoW functionality using an arbitrary hash function. +type Worker struct { + hash Hash + numWorkers int +} + +// New creates a new PoW based on the provided hash. +// The optional numWorkers specifies how many go routines are used to mine. +func New(hash Hash, numWorkers ...int) *Worker { + w := &Worker{ + hash: hash, + numWorkers: 1, + } + if len(numWorkers) > 0 && numWorkers[0] > 0 { + w.numWorkers = numWorkers[0] + } + return w +} + +// Mine performs the PoW. +// It appends the 8-byte nonce to the provided msg and tries to find a nonce +// until the target number of leading zeroes is reached. +// The computation can be be canceled using the provided ctx. +func (w *Worker) Mine(ctx context.Context, msg []byte, target int) (uint64, error) { + var ( + done uint32 + counter uint64 + wg sync.WaitGroup + results = make(chan uint64, w.numWorkers) + closing = make(chan struct{}) + ) + + // stop when the context has been canceled + go func() { + select { + case <-ctx.Done(): + atomic.StoreUint32(&done, 1) + case <-closing: + return + } + }() + + workerWidth := math.MaxUint64 / uint64(w.numWorkers) + for i := 0; i < w.numWorkers; i++ { + startNonce := uint64(i) * workerWidth + wg.Add(1) + go func() { + defer wg.Done() + + nonce, workerErr := w.worker(msg, startNonce, target, &done, &counter) + if workerErr != nil { + return + } + atomic.StoreUint32(&done, 1) + results <- nonce + }() + } + wg.Wait() + close(results) + close(closing) + + nonce, ok := <-results + if !ok { + return 0, ErrCancelled + } + return nonce, nil +} + +// LeadingZeros returns the number of leading zeros in the digest of the given data. +func (w *Worker) LeadingZeros(data []byte) (int, error) { + digest, err := w.sum(data) + if err != nil { + return 0, err + } + asAnInt := new(big.Int).SetBytes(digest) + return 8*w.hash.Size() - asAnInt.BitLen(), nil +} + +// LeadingZerosWithNonce returns the number of leading zeros in the digest +// after the provided 8-byte nonce is appended to msg. +func (w *Worker) LeadingZerosWithNonce(msg []byte, nonce uint64) (int, error) { + buf := make([]byte, len(msg)+NonceBytes) + copy(buf, msg) + putUint64(buf[len(msg):], nonce) + + return w.LeadingZeros(buf) +} + +func (w *Worker) worker(msg []byte, startNonce uint64, target int, done *uint32, counter *uint64) (uint64, error) { + buf := make([]byte, len(msg)+NonceBytes) + copy(buf, msg) + asAnInt := new(big.Int) + + for nonce := startNonce; ; { + if atomic.LoadUint32(done) != 0 { + break + } + atomic.AddUint64(counter, 1) + + // write nonce in the buffer + putUint64(buf[len(msg):], nonce) + + digest, err := w.sum(buf) + if err != nil { + return 0, err + } + asAnInt.SetBytes(digest) + leadingZeros := 8*w.hash.Size() - asAnInt.BitLen() + if leadingZeros >= target { + return nonce, nil + } + + nonce++ + } + return 0, ErrDone +} + +func (w *Worker) sum(data []byte) ([]byte, error) { + h := w.hash.New() + if _, err := h.Write(data); err != nil { + return nil, err + } + return h.Sum(nil), nil +} + +func putUint64(b []byte, v uint64) { + binary.LittleEndian.PutUint64(b, v) +} diff --git a/packages/pow/pow_test.go b/packages/pow/pow_test.go new file mode 100644 index 0000000000000000000000000000000000000000..8c000aee844002c42f0338f08780e2cce6488c8e --- /dev/null +++ b/packages/pow/pow_test.go @@ -0,0 +1,78 @@ +package pow + +import ( + "context" + "crypto" + "math" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + _ "golang.org/x/crypto/blake2b" // required by crypto.BLAKE2b_512 +) + +const ( + workers = 2 + target = 10 +) + +var testWorker = New(crypto.BLAKE2b_512, workers) + +func TestWorker_Work(t *testing.T) { + nonce, err := testWorker.Mine(context.Background(), nil, target) + require.NoError(t, err) + difficulty, err := testWorker.LeadingZerosWithNonce(nil, nonce) + assert.GreaterOrEqual(t, difficulty, target) + assert.NoError(t, err) +} + +func TestWorker_Validate(t *testing.T) { + tests := []*struct { + msg []byte + nonce uint64 + expLeadingZeros int + expErr error + }{ + {msg: nil, nonce: 0, expLeadingZeros: 1, expErr: nil}, + {msg: nil, nonce: 4611686018451317632, expLeadingZeros: 28, expErr: nil}, + {msg: make([]byte, 10240), nonce: 0, expLeadingZeros: 1, expErr: nil}, + } + + w := &Worker{hash: crypto.BLAKE2b_512} + for _, tt := range tests { + zeros, err := w.LeadingZerosWithNonce(tt.msg, tt.nonce) + assert.Equal(t, tt.expLeadingZeros, zeros) + assert.Equal(t, tt.expErr, err) + } +} + +func TestWorker_Cancel(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var err error + go func() { + _, err = testWorker.Mine(ctx, nil, math.MaxInt32) + }() + time.Sleep(10 * time.Millisecond) + cancel() + + assert.Eventually(t, func() bool { return err == ErrCancelled }, time.Second, 10*time.Millisecond) +} + +func BenchmarkWorker(b *testing.B) { + var ( + buf = make([]byte, 1024) + done uint32 + counter uint64 + ) + go func() { + _, _ = testWorker.worker(buf, 0, math.MaxInt32, &done, &counter) + }() + b.ResetTimer() + for atomic.LoadUint64(&counter) < uint64(b.N) { + } + atomic.StoreUint32(&done, 1) +} diff --git a/packages/prng/unix_ts_rng.go b/packages/prng/unix_ts_rng.go new file mode 100644 index 0000000000000000000000000000000000000000..58c212e37b9a17b65c815eadb227fb88f6829327 --- /dev/null +++ b/packages/prng/unix_ts_rng.go @@ -0,0 +1,88 @@ +package prng + +import ( + "math/rand" + "time" +) + +// TimeSourceFunc is a function which gets an understanding of time in seconds resolution back. +type TimeSourceFunc func() int64 + +// NewUnixTimestampPRNG creates a new Unix timestamp based pseudo random number generator +// using the given resolution. The resolution defines at which second interval numbers are generated. +func NewUnixTimestampPRNG(resolution int64, timeSourceFunc ...TimeSourceFunc) *UnixTimestampPrng { + utrng := &UnixTimestampPrng{ + c: make(chan float64), + exit: make(chan struct{}), + resolution: resolution, + timeSourceFunc: func() int64 { return time.Now().Unix() }, + } + if len(timeSourceFunc) > 0 { + utrng.timeSourceFunc = timeSourceFunc[0] + } + return utrng +} + +// UnixTimestampPrng is a pseudo random number generator using the Unix time in seconds to derive +// a random number from. +type UnixTimestampPrng struct { + c chan float64 + exit chan struct{} + resolution int64 + timeSourceFunc TimeSourceFunc +} + +// Start starts the Unix timestamp pseudo random number generator by examining the +// interval and then starting production of numbers after at least interval seconds +// plus delta of the next resolution time have elapsed. +func (utrng *UnixTimestampPrng) Start() { + nowSec := utrng.timeSourceFunc() + nextTimePoint := ResolveNextTimePoint(nowSec, utrng.resolution) + time.AfterFunc(time.Duration(nextTimePoint-nowSec)*time.Second, func() { + // send for the first time right after the timer is executed + utrng.send() + + t := time.NewTicker(time.Duration(utrng.resolution) * time.Second) + defer t.Stop() + out: + for { + select { + case <-t.C: + utrng.send() + case <-utrng.exit: + break out + } + } + }) +} + +// sends the next pseudo random number to the consumer channel. +func (utrng *UnixTimestampPrng) send() { + now := utrng.timeSourceFunc() + // reduce to last resolution + timePoint := now - (now % utrng.resolution) + + // add entropy and convert to float64 + pseudoR := rand.New(rand.NewSource(timePoint)).Float64() + + // skip slow consumers + select { + case utrng.c <- pseudoR: + default: + } +} + +// C returns the channel from which random generated numbers can be consumed from. +func (utrng *UnixTimestampPrng) C() <-chan float64 { + return utrng.c +} + +// Stop stops the Unix timestamp pseudo random number generator. +func (utrng *UnixTimestampPrng) Stop() { + utrng.exit <- struct{}{} +} + +// ResolveNextTimePoint returns the next time point. +func ResolveNextTimePoint(nowSec int64, resolution int64) int64 { + return nowSec + (resolution - nowSec%resolution) +} diff --git a/packages/prng/unix_ts_rng_test.go b/packages/prng/unix_ts_rng_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4756f38bf8840cb41efc8842d8c7ca2e136f17c1 --- /dev/null +++ b/packages/prng/unix_ts_rng_test.go @@ -0,0 +1,30 @@ +package prng_test + +import ( + "testing" + + "github.com/iotaledger/goshimmer/packages/prng" + "github.com/stretchr/testify/assert" +) + +func TestResolveNextTimePoint(t *testing.T) { + assert.EqualValues(t, 105, prng.ResolveNextTimePoint(103, 5)) + assert.EqualValues(t, 110, prng.ResolveNextTimePoint(105, 5)) + assert.EqualValues(t, 105, prng.ResolveNextTimePoint(100, 5)) + assert.EqualValues(t, 100, prng.ResolveNextTimePoint(97, 5)) +} + +func TestUnixTsPrng(t *testing.T) { + unixTsRng := prng.NewUnixTimestampPRNG(1) + unixTsRng.Start() + defer unixTsRng.Stop() + + var last float64 + for i := 0; i < 3; i++ { + r := <-unixTsRng.C() + assert.Less(t, r, 1.0) + assert.Greater(t, r, 0.0) + assert.NotEqual(t, last, r) + last = r + } +} diff --git a/packages/shutdown/order.go b/packages/shutdown/order.go index b8347d1eaeac6069fbf3c9cc835d5b598987630e..25003c92ba91d53476a626109b20ae5d27c9e7af 100644 --- a/packages/shutdown/order.go +++ b/packages/shutdown/order.go @@ -1,17 +1,20 @@ package shutdown const ( - ShutdownPriorityTangle = iota - ShutdownPriorityRemoteLog - ShutdownPrioritySolidifier - ShutdownPriorityBundleProcessor - ShutdownPriorityAnalysis - ShutdownPriorityMetrics - ShutdownPriorityAutopeering - ShutdownPriorityGossip - ShutdownPriorityWebAPI - ShutdownPriorityGraph - ShutdownPriorityTangleSpammer - ShutdownPrioritySPA - ShutdownPriorityBadgerGarbageCollection + PriorityDatabase = iota + PriorityFPC + PriorityTangle + PriorityMissingMessagesMonitoring + PriorityFaucet + PriorityRemoteLog + PriorityAnalysis + PriorityPrometheus + PriorityMetrics + PriorityAutopeering + PriorityGossip + PriorityWebAPI + PriorityDashboard + PrioritySynchronization + PrioritySpammer + PriorityBootstrap ) diff --git a/packages/transactionspammer/transactionspammer.go b/packages/transactionspammer/transactionspammer.go deleted file mode 100644 index 00493158b87578f095deb48939f49321475ded94..0000000000000000000000000000000000000000 --- a/packages/transactionspammer/transactionspammer.go +++ /dev/null @@ -1,104 +0,0 @@ -package transactionspammer - -import ( - "strings" - "sync" - "time" - - "github.com/iotaledger/goshimmer/packages/gossip" - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/goshimmer/plugins/tipselection" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/logger" -) - -const logEveryNTransactions = 5000 - -var log *logger.Logger - -var spamming = false -var spammingMutex sync.Mutex - -var shutdownSignal chan struct{} -var done chan struct{} - -func init() { - shutdownSignal = make(chan struct{}) - done = make(chan struct{}) -} - -var targetAddress = strings.Repeat("SPAMMMMER", 9) - -func Start(tps uint64) { - log = logger.NewLogger("Transaction Spammer") - spammingMutex.Lock() - spamming = true - spammingMutex.Unlock() - - daemon.BackgroundWorker("Transaction Spammer", func(daemonShutdownSignal <-chan struct{}) { - start := time.Now() - - var totalSentCounter, currentSentCounter uint64 - - log.Infof("started spammer...will output sent count every %d transactions", logEveryNTransactions) - defer log.Infof("spammer stopped, spammed %d transactions", totalSentCounter) - for { - select { - case <-daemonShutdownSignal: - return - - case <-shutdownSignal: - done <- struct{}{} - return - - default: - currentSentCounter++ - totalSentCounter++ - - tx := value_transaction.New() - tx.SetHead(true) - tx.SetTail(true) - tx.SetAddress(targetAddress) - tx.SetBranchTransactionHash(tipselection.GetRandomTip()) - tx.SetTrunkTransactionHash(tipselection.GetRandomTip(tx.GetBranchTransactionHash())) - tx.SetTimestamp(uint(time.Now().Unix())) - if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil { - log.Warn("PoW failed", err) - continue - } - - gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: tx.GetBytes(), Peer: &local.GetInstance().Peer}) - - if totalSentCounter%logEveryNTransactions == 0 { - log.Infof("spammed %d transactions", totalSentCounter) - } - - // rate limit to the specified TPS - if currentSentCounter >= tps { - duration := time.Since(start) - - if duration < time.Second { - time.Sleep(time.Second - duration) - } - - start = time.Now() - currentSentCounter = 0 - } - } - } - }, shutdown.ShutdownPriorityTangleSpammer) -} - -func Stop() { - spammingMutex.Lock() - if spamming { - shutdownSignal <- struct{}{} - // wait for spammer to be done - <-done - spamming = false - } - spammingMutex.Unlock() -} diff --git a/packages/vote/fpc/fpc.go b/packages/vote/fpc/fpc.go new file mode 100644 index 0000000000000000000000000000000000000000..62571445f2af56d2f8b3b7a8657ceb97bd56de4f --- /dev/null +++ b/packages/vote/fpc/fpc.go @@ -0,0 +1,300 @@ +package fpc + +import ( + "container/list" + "context" + "errors" + "fmt" + "math/rand" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/hive.go/events" +) + +var ( + ErrVoteAlreadyOngoing = errors.New("a vote is already ongoing for the given ID") + ErrNoOpinionGiversAvailable = errors.New("can't perform round as no opinion givers are available") +) + +// New creates a new FPC instance. +func New(opinionGiverFunc vote.OpinionGiverFunc, paras ...*Parameters) *FPC { + f := &FPC{ + opinionGiverFunc: opinionGiverFunc, + paras: DefaultParameters(), + opinionGiverRng: rand.New(rand.NewSource(time.Now().UnixNano())), + ctxs: make(map[string]*vote.Context), + queue: list.New(), + queueSet: make(map[string]struct{}), + events: vote.Events{ + Finalized: events.NewEvent(vote.OpinionCaller), + Failed: events.NewEvent(vote.OpinionCaller), + RoundExecuted: events.NewEvent(vote.RoundStatsCaller), + Error: events.NewEvent(events.ErrorCaller), + }, + } + if len(paras) > 0 { + f.paras = paras[0] + } + return f +} + +// FPC is a DRNGRoundBasedVoter which uses the Opinion of other entities +// in order to finalize an Opinion. +type FPC struct { + events vote.Events + opinionGiverFunc vote.OpinionGiverFunc + // the lifo queue of newly enqueued items to vote on. + queue *list.List + // contains a set of currently queued items. + queueSet map[string]struct{} + queueMu sync.Mutex + // contains the set of current vote contexts. + ctxs map[string]*vote.Context + ctxsMu sync.RWMutex + // parameters to use within FPC. + paras *Parameters + // indicates whether the last round was performed successfully. + lastRoundCompletedSuccessfully bool + // used to randomly select opinion givers. + opinionGiverRng *rand.Rand +} + +func (f *FPC) Vote(id string, initOpn vote.Opinion) error { + f.queueMu.Lock() + defer f.queueMu.Unlock() + f.ctxsMu.RLock() + defer f.ctxsMu.RUnlock() + if _, alreadyQueued := f.queueSet[id]; alreadyQueued { + return fmt.Errorf("%w: %s", ErrVoteAlreadyOngoing, id) + } + if _, alreadyOngoing := f.ctxs[id]; alreadyOngoing { + return fmt.Errorf("%w: %s", ErrVoteAlreadyOngoing, id) + } + f.queue.PushBack(vote.NewContext(id, initOpn)) + f.queueSet[id] = struct{}{} + return nil +} + +func (f *FPC) IntermediateOpinion(id string) (vote.Opinion, error) { + f.ctxsMu.RLock() + defer f.ctxsMu.RUnlock() + voteCtx, has := f.ctxs[id] + if !has { + return vote.Unknown, fmt.Errorf("%w: %s", vote.ErrVotingNotFound, id) + } + return voteCtx.LastOpinion(), nil +} + +func (f *FPC) Events() vote.Events { + return f.events +} + +// Round enqueues new items, sets opinions on active vote contexts, finalizes them and then +// queries for opinions. +func (f *FPC) Round(rand float64) error { + start := time.Now() + // enqueue new voting contexts + f.enqueue() + // we can only form opinions when the last round was actually executed successfully + if f.lastRoundCompletedSuccessfully { + // form opinions by using the random number supplied for this new round + f.formOpinions(rand) + // clean opinions on vote contexts where an opinion was reached in FinalizationThreshold + // number of rounds and clear those who failed to be finalized in MaxRoundsPerVoteContext. + f.finalizeOpinions() + } + // query for opinions on the current vote contexts + queriedOpinions, err := f.queryOpinions() + if err == nil { + f.lastRoundCompletedSuccessfully = true + // execute a round executed event + roundStats := &vote.RoundStats{ + Duration: time.Since(start), + RandUsed: rand, + ActiveVoteContexts: f.ctxs, + QueriedOpinions: queriedOpinions, + } + // TODO: add possibility to check whether an event handler is registered + // in order to prevent the collection of the round stats data if not needed + f.events.RoundExecuted.Trigger(roundStats) + } + return err +} + +// enqueues items for voting +func (f *FPC) enqueue() { + f.queueMu.Lock() + defer f.queueMu.Unlock() + f.ctxsMu.Lock() + defer f.ctxsMu.Unlock() + for ele := f.queue.Front(); ele != nil; ele = f.queue.Front() { + voteCtx := ele.Value.(*vote.Context) + f.ctxs[voteCtx.ID] = voteCtx + f.queue.Remove(ele) + delete(f.queueSet, voteCtx.ID) + } +} + +// formOpinions updates the opinion for ongoing vote contexts by comparing their liked percentage +// against the threshold appropriate for their given rounds. +func (f *FPC) formOpinions(rand float64) { + f.ctxsMu.RLock() + defer f.ctxsMu.RUnlock() + for _, voteCtx := range f.ctxs { + // when the vote context is new there's no opinion to form + if voteCtx.IsNew() { + continue + } + + lowerThreshold := f.paras.SubsequentRoundsLowerBoundThreshold + upperThreshold := f.paras.SubsequentRoundsUpperBoundThreshold + + if voteCtx.HadFirstRound() { + lowerThreshold = f.paras.FirstRoundLowerBoundThreshold + upperThreshold = f.paras.FirstRoundUpperBoundThreshold + } + + if voteCtx.Liked >= RandUniformThreshold(rand, lowerThreshold, upperThreshold) { + voteCtx.AddOpinion(vote.Like) + continue + } + voteCtx.AddOpinion(vote.Dislike) + } +} + +// emits a Voted event for every finalized vote context (or Failed event if failed) and then removes it from FPC. +func (f *FPC) finalizeOpinions() { + f.ctxsMu.Lock() + defer f.ctxsMu.Unlock() + for id, voteCtx := range f.ctxs { + if voteCtx.IsFinalized(f.paras.CoolingOffPeriod, f.paras.FinalizationThreshold) { + f.events.Finalized.Trigger(&vote.OpinionEvent{ID: id, Opinion: voteCtx.LastOpinion(), Ctx: *voteCtx}) + delete(f.ctxs, id) + continue + } + if voteCtx.Rounds >= f.paras.MaxRoundsPerVoteContext { + f.events.Failed.Trigger(&vote.OpinionEvent{ID: id, Opinion: voteCtx.LastOpinion(), Ctx: *voteCtx}) + delete(f.ctxs, id) + } + } +} + +// queries the opinions of QuerySampleSize amount of OpinionGivers. +func (f *FPC) queryOpinions() ([]vote.QueriedOpinions, error) { + ids := f.voteContextIDs() + + // nothing to vote on + if len(ids) == 0 { + return nil, nil + } + + opinionGivers, err := f.opinionGiverFunc() + if err != nil { + return nil, err + } + + // nobody to query + if len(opinionGivers) == 0 { + return nil, ErrNoOpinionGiversAvailable + } + + // select a random subset of opinion givers to query. + // if the same opinion giver is selected multiple times, we query it only once + // but use its opinion N selected times. + opinionGiversToQuery := map[vote.OpinionGiver]int{} + for i := 0; i < f.paras.QuerySampleSize; i++ { + selected := opinionGivers[f.opinionGiverRng.Intn(len(opinionGivers))] + opinionGiversToQuery[selected]++ + } + + // votes per id + var voteMapMu sync.Mutex + voteMap := map[string]vote.Opinions{} + + // holds queried opinions + allQueriedOpinions := []vote.QueriedOpinions{} + + // send queries + var wg sync.WaitGroup + for opinionGiverToQuery, selectedCount := range opinionGiversToQuery { + wg.Add(1) + go func(opinionGiverToQuery vote.OpinionGiver, selectedCount int) { + defer wg.Done() + + queryCtx, cancel := context.WithTimeout(context.Background(), f.paras.QueryTimeout) + defer cancel() + + // query + opinions, err := opinionGiverToQuery.Query(queryCtx, ids) + if err != nil || len(opinions) != len(ids) { + // ignore opinions + return + } + + queriedOpinions := vote.QueriedOpinions{ + OpinionGiverID: opinionGiverToQuery.ID(), + Opinions: make(map[string]vote.Opinion), + TimesCounted: selectedCount, + } + + // add opinions to vote map + voteMapMu.Lock() + defer voteMapMu.Unlock() + for i, id := range ids { + votes, has := voteMap[id] + if !has { + votes = vote.Opinions{} + } + // reuse the opinion N times selected. + // note this is always at least 1. + for j := 0; j < selectedCount; j++ { + votes = append(votes, opinions[i]) + } + queriedOpinions.Opinions[id] = opinions[i] + voteMap[id] = votes + } + allQueriedOpinions = append(allQueriedOpinions, queriedOpinions) + }(opinionGiverToQuery, selectedCount) + } + wg.Wait() + + f.ctxsMu.RLock() + defer f.ctxsMu.RUnlock() + // compute liked percentage + for id, votes := range voteMap { + var likedSum float64 + votedCount := float64(len(votes)) + + for _, opinion := range votes { + switch opinion { + case vote.Unknown: + votedCount-- + case vote.Like: + likedSum++ + } + } + + // mark a round being done, even though there's no opinion, + // so this voting context will be cleared eventually + f.ctxs[id].Rounds++ + if votedCount == 0 { + continue + } + f.ctxs[id].Liked = likedSum / votedCount + } + return allQueriedOpinions, nil +} + +func (f *FPC) voteContextIDs() []string { + f.ctxsMu.RLock() + defer f.ctxsMu.RUnlock() + var i int + ids := make([]string, len(f.ctxs)) + for id := range f.ctxs { + ids[i] = id + i++ + } + return ids +} diff --git a/packages/vote/fpc/fpc_test.go b/packages/vote/fpc/fpc_test.go new file mode 100644 index 0000000000000000000000000000000000000000..58488bdc568810d8c1bf63b86f272667c873b103 --- /dev/null +++ b/packages/vote/fpc/fpc_test.go @@ -0,0 +1,189 @@ +package fpc_test + +import ( + "context" + "errors" + "testing" + + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/packages/vote/fpc" + "github.com/iotaledger/hive.go/events" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestVoteContext_IsFinalized(t *testing.T) { + type testInput struct { + voteCtx vote.Context + coolOffPeriod int + finalizationThreshold int + want bool + } + var tests = []testInput{ + {vote.Context{ + Opinions: []vote.Opinion{vote.Like, vote.Like, vote.Like, vote.Like, vote.Like}, + }, 2, 2, true}, + {vote.Context{ + Opinions: []vote.Opinion{vote.Like, vote.Like, vote.Like, vote.Like, vote.Dislike}, + }, 2, 2, false}, + } + + for _, test := range tests { + assert.Equal(t, test.want, test.voteCtx.IsFinalized(test.coolOffPeriod, test.finalizationThreshold)) + } +} + +func TestVoteContext_LastOpinion(t *testing.T) { + type testInput struct { + voteCtx vote.Context + expected vote.Opinion + } + var tests = []testInput{ + {vote.Context{ + Opinions: []vote.Opinion{vote.Like, vote.Like, vote.Like, vote.Like}, + }, vote.Like}, + {vote.Context{ + Opinions: []vote.Opinion{vote.Like, vote.Like, vote.Like, vote.Dislike}, + }, vote.Dislike}, + } + + for _, test := range tests { + assert.Equal(t, test.expected, test.voteCtx.LastOpinion()) + } +} + +func TestFPCPreventSameIDMultipleTimes(t *testing.T) { + voter := fpc.New(nil) + assert.NoError(t, voter.Vote("a", vote.Like)) + // can't add the same item twice + assert.True(t, errors.Is(voter.Vote("a", vote.Like), fpc.ErrVoteAlreadyOngoing)) +} + +type opiniongivermock struct { + roundsReplies []vote.Opinions + roundIndex int +} + +func (ogm *opiniongivermock) ID() string { + return "" +} + +func (ogm *opiniongivermock) Query(_ context.Context, _ []string) (vote.Opinions, error) { + if ogm.roundIndex >= len(ogm.roundsReplies) { + return ogm.roundsReplies[len(ogm.roundsReplies)-1], nil + } + opinions := ogm.roundsReplies[ogm.roundIndex] + ogm.roundIndex++ + return opinions, nil +} + +func TestFPCFinalizedEvent(t *testing.T) { + opinionGiverMock := &opiniongivermock{ + roundsReplies: []vote.Opinions{ + // 2 cool-off period, 2 finalization threshold + {vote.Like}, {vote.Like}, {vote.Like}, {vote.Like}, + }, + } + opinionGiverFunc := func() (givers []vote.OpinionGiver, err error) { + return []vote.OpinionGiver{opinionGiverMock}, nil + } + + id := "a" + + paras := fpc.DefaultParameters() + paras.FinalizationThreshold = 2 + paras.CoolingOffPeriod = 2 + paras.QuerySampleSize = 1 + voter := fpc.New(opinionGiverFunc, paras) + var finalizedOpinion *vote.Opinion + voter.Events().Finalized.Attach(events.NewClosure(func(ev *vote.OpinionEvent) { + finalizedOpinion = &ev.Opinion + })) + assert.NoError(t, voter.Vote(id, vote.Like)) + + // do 5 rounds of FPC -> 5 because the last one finalizes the vote + for i := 0; i < 5; i++ { + assert.NoError(t, voter.Round(0.5)) + } + + require.NotNil(t, finalizedOpinion, "finalized event should have been fired") + assert.Equal(t, vote.Like, *finalizedOpinion, "the final opinion should have been 'Like'") +} + +func TestFPCFailedEvent(t *testing.T) { + opinionGiverFunc := func() (givers []vote.OpinionGiver, err error) { + return []vote.OpinionGiver{&opiniongivermock{ + // doesn't matter what we set here + roundsReplies: []vote.Opinions{{vote.Dislike}}, + }}, nil + } + + id := "a" + + paras := fpc.DefaultParameters() + paras.QuerySampleSize = 1 + paras.MaxRoundsPerVoteContext = 3 + paras.CoolingOffPeriod = 0 + // since the finalization threshold is over max rounds it will + // always fail finalizing an opinion + paras.FinalizationThreshold = 4 + voter := fpc.New(opinionGiverFunc, paras) + var failedOpinion *vote.Opinion + voter.Events().Failed.Attach(events.NewClosure(func(ev *vote.OpinionEvent) { + failedOpinion = &ev.Opinion + })) + assert.NoError(t, voter.Vote(id, vote.Like)) + + for i := 0; i < 4; i++ { + assert.NoError(t, voter.Round(0.5)) + } + + require.NotNil(t, failedOpinion, "failed event should have been fired") + assert.Equal(t, vote.Dislike, *failedOpinion, "the final opinion should have been 'Dislike'") +} + +func TestFPCVotingMultipleOpinionGivers(t *testing.T) { + type testInput struct { + id string + initOpinion vote.Opinion + expectedRoundsDone int + expectedOpinion vote.Opinion + } + var tests = []testInput{ + {"1", vote.Like, 5, vote.Like}, + {"2", vote.Dislike, 5, vote.Dislike}, + } + + for _, test := range tests { + // note that even though we're defining QuerySampleSize times opinion givers, + // it doesn't mean that FPC will query all of them. + opinionGiverFunc := func() (givers []vote.OpinionGiver, err error) { + opinionGivers := make([]vote.OpinionGiver, fpc.DefaultParameters().QuerySampleSize) + for i := 0; i < len(opinionGivers); i++ { + opinionGivers[i] = &opiniongivermock{roundsReplies: []vote.Opinions{{test.initOpinion}}} + } + return opinionGivers, nil + } + + paras := fpc.DefaultParameters() + paras.FinalizationThreshold = 2 + paras.CoolingOffPeriod = 2 + voter := fpc.New(opinionGiverFunc, paras) + var finalOpinion *vote.Opinion + voter.Events().Finalized.Attach(events.NewClosure(func(ev *vote.OpinionEvent) { + finalOpinion = &ev.Opinion + })) + + assert.NoError(t, voter.Vote(test.id, test.initOpinion)) + + var roundsDone int + for finalOpinion == nil { + assert.NoError(t, voter.Round(0.7)) + roundsDone++ + } + + assert.Equal(t, test.expectedRoundsDone, roundsDone) + require.NotNil(t, finalOpinion) + assert.Equal(t, test.expectedOpinion, *finalOpinion) + } +} diff --git a/packages/vote/fpc/parameters.go b/packages/vote/fpc/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..3ea8dd355c0f11be8360e211199b245005d01f2c --- /dev/null +++ b/packages/vote/fpc/parameters.go @@ -0,0 +1,45 @@ +package fpc + +import "time" + +// Parameters define the parameters of an FPC instance. +type Parameters struct { + // The lower bound liked percentage threshold at the first round. Also called 'a'. + FirstRoundLowerBoundThreshold float64 + // The upper bound liked percentage threshold at the first round. Also called 'b'. + FirstRoundUpperBoundThreshold float64 + // The lower bound liked percentage threshold used after the first round. + SubsequentRoundsLowerBoundThreshold float64 + // The upper bound liked percentage threshold used after the first round. + SubsequentRoundsUpperBoundThreshold float64 + // The amount of opinions to query on each round for a given vote context. Also called 'k'. + QuerySampleSize int + // The amount of rounds a vote context's opinion needs to stay the same to be considered final. Also called 'l'. + FinalizationThreshold int + // The amount of rounds for which to ignore any finalization checks for. Also called 'm'. + CoolingOffPeriod int + // The max amount of rounds to execute per vote context before aborting them. + MaxRoundsPerVoteContext int + // The max amount of time a query is allowed to take. + QueryTimeout time.Duration +} + +// DefaultParameters returns the default parameters used in FPC. +func DefaultParameters() *Parameters { + return &Parameters{ + FirstRoundLowerBoundThreshold: 0.67, + FirstRoundUpperBoundThreshold: 0.67, + SubsequentRoundsLowerBoundThreshold: 0.50, + SubsequentRoundsUpperBoundThreshold: 0.67, + QuerySampleSize: 21, + FinalizationThreshold: 10, + CoolingOffPeriod: 0, + MaxRoundsPerVoteContext: 100, + QueryTimeout: 1500 * time.Millisecond, + } +} + +// RandUniformThreshold returns random threshold between the given lower/upper bound values. +func RandUniformThreshold(rand float64, thresholdLowerBound float64, thresholdUpperBound float64) float64 { + return thresholdLowerBound + rand*(thresholdUpperBound-thresholdLowerBound) +} diff --git a/packages/vote/net/query.pb.go b/packages/vote/net/query.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..30a964a05b939b3ecc5e2e974c70eda9a745458e --- /dev/null +++ b/packages/vote/net/query.pb.go @@ -0,0 +1,206 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: query.proto + +package net + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type QueryRequest struct { + Id []string `protobuf:"bytes,1,rep,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *QueryRequest) Reset() { *m = QueryRequest{} } +func (m *QueryRequest) String() string { return proto.CompactTextString(m) } +func (*QueryRequest) ProtoMessage() {} +func (*QueryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_5c6ac9b241082464, []int{0} +} + +func (m *QueryRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_QueryRequest.Unmarshal(m, b) +} +func (m *QueryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_QueryRequest.Marshal(b, m, deterministic) +} +func (m *QueryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRequest.Merge(m, src) +} +func (m *QueryRequest) XXX_Size() int { + return xxx_messageInfo_QueryRequest.Size(m) +} +func (m *QueryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRequest proto.InternalMessageInfo + +func (m *QueryRequest) GetId() []string { + if m != nil { + return m.Id + } + return nil +} + +type QueryReply struct { + Opinion []int32 `protobuf:"varint,1,rep,packed,name=opinion,proto3" json:"opinion,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *QueryReply) Reset() { *m = QueryReply{} } +func (m *QueryReply) String() string { return proto.CompactTextString(m) } +func (*QueryReply) ProtoMessage() {} +func (*QueryReply) Descriptor() ([]byte, []int) { + return fileDescriptor_5c6ac9b241082464, []int{1} +} + +func (m *QueryReply) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_QueryReply.Unmarshal(m, b) +} +func (m *QueryReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_QueryReply.Marshal(b, m, deterministic) +} +func (m *QueryReply) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryReply.Merge(m, src) +} +func (m *QueryReply) XXX_Size() int { + return xxx_messageInfo_QueryReply.Size(m) +} +func (m *QueryReply) XXX_DiscardUnknown() { + xxx_messageInfo_QueryReply.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryReply proto.InternalMessageInfo + +func (m *QueryReply) GetOpinion() []int32 { + if m != nil { + return m.Opinion + } + return nil +} + +func init() { + proto.RegisterType((*QueryRequest)(nil), "net.QueryRequest") + proto.RegisterType((*QueryReply)(nil), "net.QueryReply") +} + +func init() { + proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) +} + +var fileDescriptor_5c6ac9b241082464 = []byte{ + // 148 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0x2c, 0x4d, 0x2d, + 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xce, 0x4b, 0x2d, 0x51, 0x92, 0xe3, 0xe2, + 0x09, 0x04, 0x89, 0x05, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0xf1, 0x71, 0x31, 0x65, 0xa6, + 0x48, 0x30, 0x2a, 0x30, 0x6b, 0x70, 0x06, 0x31, 0x65, 0xa6, 0x28, 0xa9, 0x71, 0x71, 0x41, 0xe5, + 0x0b, 0x72, 0x2a, 0x85, 0x24, 0xb8, 0xd8, 0xf3, 0x0b, 0x32, 0xf3, 0x32, 0xf3, 0xf3, 0xc0, 0x4a, + 0x58, 0x83, 0x60, 0x5c, 0x23, 0x5b, 0x2e, 0xae, 0xb0, 0xfc, 0x92, 0xd4, 0x22, 0xb0, 0x62, 0x21, + 0x7d, 0x2e, 0x76, 0x7f, 0x88, 0x84, 0x90, 0xa0, 0x5e, 0x5e, 0x6a, 0x89, 0x1e, 0xb2, 0x1d, 0x52, + 0xfc, 0xc8, 0x42, 0x05, 0x39, 0x95, 0x4a, 0x0c, 0x4e, 0xec, 0x51, 0xac, 0x7a, 0xd6, 0x79, 0xa9, + 0x25, 0x49, 0x6c, 0x60, 0xb7, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb4, 0x93, 0xeb, 0x61, + 0xaa, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// VoterQueryClient is the client API for VoterQuery service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type VoterQueryClient interface { + Opinion(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryReply, error) +} + +type voterQueryClient struct { + cc grpc.ClientConnInterface +} + +func NewVoterQueryClient(cc grpc.ClientConnInterface) VoterQueryClient { + return &voterQueryClient{cc} +} + +func (c *voterQueryClient) Opinion(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryReply, error) { + out := new(QueryReply) + err := c.cc.Invoke(ctx, "/net.VoterQuery/Opinion", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VoterQueryServer is the server API for VoterQuery service. +type VoterQueryServer interface { + Opinion(context.Context, *QueryRequest) (*QueryReply, error) +} + +// UnimplementedVoterQueryServer can be embedded to have forward compatible implementations. +type UnimplementedVoterQueryServer struct { +} + +func (*UnimplementedVoterQueryServer) Opinion(ctx context.Context, req *QueryRequest) (*QueryReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Opinion not implemented") +} + +func RegisterVoterQueryServer(s *grpc.Server, srv VoterQueryServer) { + s.RegisterService(&_VoterQuery_serviceDesc, srv) +} + +func _VoterQuery_Opinion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VoterQueryServer).Opinion(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/net.VoterQuery/Opinion", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VoterQueryServer).Opinion(ctx, req.(*QueryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _VoterQuery_serviceDesc = grpc.ServiceDesc{ + ServiceName: "net.VoterQuery", + HandlerType: (*VoterQueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Opinion", + Handler: _VoterQuery_Opinion_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "query.proto", +} diff --git a/packages/vote/net/query.proto b/packages/vote/net/query.proto new file mode 100644 index 0000000000000000000000000000000000000000..8c594680a83ba1871f02325ab10596bfb9b4d184 --- /dev/null +++ b/packages/vote/net/query.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package net; + +option go_package = ".;net"; + +service VoterQuery { + rpc Opinion (QueryRequest) returns (QueryReply) {} +} + +message QueryRequest { + repeated string id = 1; +} + +message QueryReply { + repeated int32 opinion = 1; +} \ No newline at end of file diff --git a/packages/vote/net/server.go b/packages/vote/net/server.go new file mode 100644 index 0000000000000000000000000000000000000000..97209c509c500011758a414921b971ddf3d69000 --- /dev/null +++ b/packages/vote/net/server.go @@ -0,0 +1,81 @@ +package net + +import ( + "context" + "net" + + "github.com/golang/protobuf/proto" + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/hive.go/events" + "google.golang.org/grpc" +) + +// OpinionRetriever retrieves the opinion for the given ID. +// If there's no opinion, the function should return Unknown. +type OpinionRetriever func(id string) vote.Opinion + +// New creates a new VoterServer. +func New(voter vote.Voter, opnRetriever OpinionRetriever, bindAddr string, netRxEvent, netTxEvent, queryReceivedEvent *events.Event) *VoterServer { + return &VoterServer{ + voter: voter, + opnRetriever: opnRetriever, + bindAddr: bindAddr, + grpcServer: grpc.NewServer(), + netRxEvent: netRxEvent, + netTxEvent: netTxEvent, + queryReceivedEvent: queryReceivedEvent, + } +} + +// VoterServer is a server which responds to opinion queries. +type VoterServer struct { + voter vote.Voter + opnRetriever OpinionRetriever + bindAddr string + grpcServer *grpc.Server + netRxEvent *events.Event + netTxEvent *events.Event + queryReceivedEvent *events.Event +} + +func (vs *VoterServer) Opinion(ctx context.Context, req *QueryRequest) (*QueryReply, error) { + reply := &QueryReply{ + Opinion: make([]int32, len(req.Id)), + } + for i, id := range req.Id { + // check whether there's an ongoing vote + opinion, err := vs.voter.IntermediateOpinion(id) + if err == nil { + reply.Opinion[i] = int32(opinion) + continue + } + reply.Opinion[i] = int32(vs.opnRetriever(id)) + } + + if vs.netRxEvent != nil { + vs.netRxEvent.Trigger(uint64(proto.Size(req))) + } + if vs.netTxEvent != nil { + vs.netTxEvent.Trigger(uint64(proto.Size(reply))) + } + if vs.queryReceivedEvent != nil { + vs.queryReceivedEvent.Trigger(&metrics.QueryReceivedEvent{OpinionCount: len(req.Id)}) + } + + return reply, nil +} + +func (vs *VoterServer) Run() error { + listener, err := net.Listen("tcp", vs.bindAddr) + if err != nil { + return err + } + + RegisterVoterQueryServer(vs.grpcServer, vs) + return vs.grpcServer.Serve(listener) +} + +func (vs *VoterServer) Shutdown() { + vs.grpcServer.GracefulStop() +} diff --git a/packages/vote/opinion.go b/packages/vote/opinion.go new file mode 100644 index 0000000000000000000000000000000000000000..2299e81d1d179a341a0f4e2c41e176cf865f36fa --- /dev/null +++ b/packages/vote/opinion.go @@ -0,0 +1,91 @@ +package vote + +import ( + "context" +) + +// OpinionGiver gives opinions about the given IDs. +type OpinionGiver interface { + // Query queries the OpinionGiver for its opinions on the given IDs. + // The passed in context can be used to signal cancellation of the query. + Query(ctx context.Context, ids []string) (Opinions, error) + // ID returns the ID of the opinion giver. + ID() string +} + +// QueriedOpinions represents queried opinions from a given opinion giver. +type QueriedOpinions struct { + // The ID of the opinion giver. + OpinionGiverID string `json:"opinion_giver_id"` + // The map of IDs to opinions. + Opinions map[string]Opinion `json:"opinions"` + // The amount of times the opinion giver's opinion has counted. + // Usually this number is 1 but due to randomization of the queried opinion givers, + // the same opinion giver's opinions might be taken into account multiple times. + TimesCounted int `json:"times_counted"` +} + +// OpinionGiverFunc is a function which gives a slice of OpinionGivers or an error. +type OpinionGiverFunc func() ([]OpinionGiver, error) + +// Opinions is a slice of Opinion. +type Opinions []Opinion + +// Opinion is an opinion about a given thing. +type Opinion byte + +const ( + Like Opinion = 1 << 0 + Dislike Opinion = 1 << 1 + Unknown Opinion = 1 << 2 +) + +func (o Opinion) String() string { + switch { + case o == Like: + return "Like" + case o == Dislike: + return "Dislike" + } + return "Unknown" +} + +// ConvertInt32Opinion converts the given int32 to an Opinion. +func ConvertInt32Opinion(x int32) Opinion { + switch { + case x == 1<<0: + return Like + case x == 1<<1: + return Dislike + } + return Unknown +} + +// ConvertInts32ToOpinions converts the given slice of int32 to a slice of Opinion. +func ConvertInts32ToOpinions(opinions []int32) []Opinion { + result := make([]Opinion, len(opinions)) + for i, opinion := range opinions { + result[i] = ConvertInt32Opinion(opinion) + } + return result +} + +// ConvertOpinionToInt32 converts the given Opinion to an int32. +func ConvertOpinionToInt32(x Opinion) int32 { + switch { + case x == Like: + return 1 + case x == Dislike: + return 2 + } + return 4 +} + +// ConvertOpinionsToInts32 converts the given slice of Opinion to a slice of int32. +func ConvertOpinionsToInts32(opinions []Opinion) []int32 { + result := make([]int32, len(opinions)) + for i, opinion := range opinions { + result[i] = ConvertOpinionToInt32(opinion) + } + return result +} diff --git a/packages/vote/vote_context.go b/packages/vote/vote_context.go new file mode 100644 index 0000000000000000000000000000000000000000..5566c9c13f511602acb855395ba82f3cfb9ad27e --- /dev/null +++ b/packages/vote/vote_context.go @@ -0,0 +1,63 @@ +package vote + +// NewContext creates a new vote context. +func NewContext(id string, initOpn Opinion) *Context { + voteCtx := &Context{ID: id, Liked: likedInit} + voteCtx.AddOpinion(initOpn) + return voteCtx +} + +const likedInit = -1 + +// Context is the context of votes from multiple rounds about a given item. +type Context struct { + ID string + // The percentage of OpinionGivers who liked this item on the last query. + Liked float64 + // The number of voting rounds performed. + Rounds int + // Append-only list of opinions formed after each round. + // the first opinion is the initial opinion when this vote context was created. + Opinions []Opinion +} + +// AddOpinion adds the given opinion to this vote context. +func (vc *Context) AddOpinion(opn Opinion) { + vc.Opinions = append(vc.Opinions, opn) +} + +// LastOpinion returns the last formed opinion. +func (vc *Context) LastOpinion() Opinion { + return vc.Opinions[len(vc.Opinions)-1] +} + +// IsFinalized tells whether this vote context is finalized by checking whether the opinion was held +// for finalizationThreshold number of rounds. +func (vc *Context) IsFinalized(coolingOffPeriod int, finalizationThreshold int) bool { + // check whether we have enough opinions to say whether this vote context is finalized. + // we start from the 2nd opinion since the first one is the initial opinion. + if len(vc.Opinions[1:]) < coolingOffPeriod+finalizationThreshold { + return false + } + + // grab opinion which needs to be held for finalizationThreshold number of rounds + candidateOpinion := vc.Opinions[len(vc.Opinions)-finalizationThreshold] + + // check whether it was held for the subsequent rounds + for _, subsequentOpinion := range vc.Opinions[len(vc.Opinions)-finalizationThreshold+1:] { + if subsequentOpinion != candidateOpinion { + return false + } + } + return true +} + +// IsNew tells whether the vote context is new. +func (vc *Context) IsNew() bool { + return vc.Liked == likedInit +} + +// HadFirstRound tells whether the vote context just had its first round. +func (vc *Context) HadFirstRound() bool { + return vc.Rounds == 1 +} diff --git a/packages/vote/voter.go b/packages/vote/voter.go new file mode 100644 index 0000000000000000000000000000000000000000..a061ca3480033db8637160d1c915a3ef9b68f5bc --- /dev/null +++ b/packages/vote/voter.go @@ -0,0 +1,78 @@ +package vote + +import ( + "errors" + "time" + + "github.com/iotaledger/hive.go/events" +) + +var ( + // ErrVotingNotFound is returned when a voting for a given id wasn't found. + ErrVotingNotFound = errors.New("no voting found") +) + +// Voter votes on hashes. +type Voter interface { + // Vote submits the given ID for voting with its initial Opinion. + Vote(id string, initOpn Opinion) error + // IntermediateOpinion gets intermediate Opinion about the given ID. + IntermediateOpinion(id string) (Opinion, error) + // Events returns the Events instance of the given Voter. + Events() Events +} + +// DRNGRoundBasedVoter is a Voter which votes in rounds and uses random numbers which +// were generated in a decentralized fashion. +type DRNGRoundBasedVoter interface { + Voter + // Round starts a new round. + Round(rand float64) error +} + +// Events defines events which happen on a Voter. +type Events struct { + // Fired when an Opinion has been finalized. + Finalized *events.Event + // Fired when an Opinion couldn't be finalized. + Failed *events.Event + // Fired when a DRNGRoundBasedVoter has executed a round. + RoundExecuted *events.Event + // Fired when internal errors occur. + Error *events.Event +} + +// RoundStats encapsulates data about an executed round. +type RoundStats struct { + // The time it took to complete a round. + Duration time.Duration `json:"duration"` + // The rand number used during the round. + RandUsed float64 `json:"rand_used"` + // The vote contexts on which opinions were formed and queried. + // This list does not include the vote contexts which were finalized/aborted + // during the execution of the round. + // Create a copy of this map if you need to modify any of its elements. + ActiveVoteContexts map[string]*Context `json:"active_vote_contexts"` + // The opinions which were queried during the round per opinion giver. + QueriedOpinions []QueriedOpinions `json:"queried_opinions"` +} + +// OpinionEvent is the struct containing data to be passed around with Finalized and Failed events. +type OpinionEvent struct { + // ID is the of the conflict. + ID string + // Opinion is an opinion about a conflict. + Opinion Opinion + // Ctx contains all relevant infos regarding the conflict. + Ctx Context +} + +// OpinionCaller calls the given handler with an OpinionEvent (containing its opinions, its associated ID and context). +func OpinionCaller(handler interface{}, params ...interface{}) { + handler.(func(ev *OpinionEvent))(params[0].(*OpinionEvent)) +} + +// RoundStats calls the given handler with a RoundStats. +func RoundStatsCaller(handler interface{}, params ...interface{}) { + handler.(func(stats *RoundStats))(params[0].(*RoundStats)) +} diff --git a/pluginmgr/core/plugins.go b/pluginmgr/core/plugins.go new file mode 100644 index 0000000000000000000000000000000000000000..03191820233abc9204e3984a79342ad8c5787065 --- /dev/null +++ b/pluginmgr/core/plugins.go @@ -0,0 +1,47 @@ +package core + +import ( + "github.com/iotaledger/goshimmer/dapps/faucet" + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/banner" + "github.com/iotaledger/goshimmer/plugins/bootstrap" + "github.com/iotaledger/goshimmer/plugins/cli" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/database" + "github.com/iotaledger/goshimmer/plugins/drng" + "github.com/iotaledger/goshimmer/plugins/gossip" + "github.com/iotaledger/goshimmer/plugins/gracefulshutdown" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/iotaledger/goshimmer/plugins/logger" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/iotaledger/goshimmer/plugins/portcheck" + "github.com/iotaledger/goshimmer/plugins/pow" + "github.com/iotaledger/goshimmer/plugins/profiling" + "github.com/iotaledger/goshimmer/plugins/sync" + + "github.com/iotaledger/hive.go/node" +) + +var PLUGINS = node.Plugins( + banner.Plugin(), + config.Plugin(), + logger.Plugin(), + cli.Plugin(), + gracefulshutdown.Plugin(), + portcheck.Plugin(), + profiling.Plugin(), + database.Plugin(), + autopeering.Plugin(), + pow.Plugin, + messagelayer.Plugin(), + gossip.Plugin(), + issuer.Plugin(), + bootstrap.Plugin(), + sync.Plugin(), + metrics.Plugin(), + drng.Plugin(), + faucet.App(), + valuetransfers.App(), +) diff --git a/pluginmgr/research/plugins.go b/pluginmgr/research/plugins.go new file mode 100644 index 0000000000000000000000000000000000000000..66e4037f1494e4443988c35e824e20376e4b8ca1 --- /dev/null +++ b/pluginmgr/research/plugins.go @@ -0,0 +1,20 @@ +package research + +import ( + "github.com/iotaledger/goshimmer/dapps/networkdelay" + analysisclient "github.com/iotaledger/goshimmer/plugins/analysis/client" + analysisdashboard "github.com/iotaledger/goshimmer/plugins/analysis/dashboard" + analysisserver "github.com/iotaledger/goshimmer/plugins/analysis/server" + "github.com/iotaledger/goshimmer/plugins/prometheus" + "github.com/iotaledger/goshimmer/plugins/remotelog" + "github.com/iotaledger/hive.go/node" +) + +var PLUGINS = node.Plugins( + remotelog.Plugin(), + analysisserver.Plugin(), + analysisclient.Plugin(), + analysisdashboard.Plugin(), + prometheus.Plugin, + networkdelay.App(), +) diff --git a/pluginmgr/ui/plugins.go b/pluginmgr/ui/plugins.go new file mode 100644 index 0000000000000000000000000000000000000000..e3a2dc1a71c2b565e34b1eb8e9ec545e95872863 --- /dev/null +++ b/pluginmgr/ui/plugins.go @@ -0,0 +1,10 @@ +package ui + +import ( + "github.com/iotaledger/goshimmer/plugins/dashboard" + "github.com/iotaledger/hive.go/node" +) + +var PLUGINS = node.Plugins( + dashboard.Plugin(), +) diff --git a/pluginmgr/webapi/plugins.go b/pluginmgr/webapi/plugins.go new file mode 100644 index 0000000000000000000000000000000000000000..704c4657d4f771d224ff45bc15be32fecf0a3f1f --- /dev/null +++ b/pluginmgr/webapi/plugins.go @@ -0,0 +1,30 @@ +package webapi + +import ( + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/goshimmer/plugins/webapi/autopeering" + "github.com/iotaledger/goshimmer/plugins/webapi/data" + "github.com/iotaledger/goshimmer/plugins/webapi/drng" + "github.com/iotaledger/goshimmer/plugins/webapi/faucet" + "github.com/iotaledger/goshimmer/plugins/webapi/healthz" + "github.com/iotaledger/goshimmer/plugins/webapi/info" + "github.com/iotaledger/goshimmer/plugins/webapi/message" + "github.com/iotaledger/goshimmer/plugins/webapi/spammer" + "github.com/iotaledger/goshimmer/plugins/webapi/value" + "github.com/iotaledger/goshimmer/plugins/webauth" + "github.com/iotaledger/hive.go/node" +) + +var PLUGINS = node.Plugins( + webapi.Plugin(), + webauth.Plugin(), + spammer.Plugin(), + data.Plugin(), + drng.Plugin(), + faucet.Plugin(), + healthz.Plugin(), + message.Plugin(), + autopeering.Plugin(), + info.Plugin(), + value.Plugin(), +) diff --git a/plugins/analysis/client/connector.go b/plugins/analysis/client/connector.go new file mode 100644 index 0000000000000000000000000000000000000000..269b764763784be4cd1e8ed9240fd74a7449fde9 --- /dev/null +++ b/plugins/analysis/client/connector.go @@ -0,0 +1,115 @@ +package client + +import ( + "errors" + "net" + "sync" + "time" + + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/netutil" + "github.com/iotaledger/hive.go/network" +) + +// errors returned by the Connector +var ( + errNoConnection = errors.New("no connection established") +) + +// time after which a failed Dial is retried +var redialInterval = 1 * time.Minute + +// A Connector is a redialing Writer on the underlying connection. +type Connector struct { + network string + address string + + mu sync.Mutex + conn *network.ManagedConnection + + startOnce sync.Once + stopOnce sync.Once + stopping chan struct{} +} + +// NewConnector creates a new Connector. +func NewConnector(network string, address string) *Connector { + return &Connector{ + network: network, + address: address, + stopping: make(chan struct{}), + } +} + +// Start starts the Connector. +func (c *Connector) Start() { + c.startOnce.Do(c.dial) +} + +// Stop stops the Connector. +func (c *Connector) Stop() { + c.stopOnce.Do(func() { + close(c.stopping) + _ = c.Close() + }) +} + +// Close closes the current connection. +// If the Connector is not closed, a new redial will be triggered. +func (c *Connector) Close() (err error) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.conn != nil { + err = c.conn.Close() + } + return +} + +// Write writes data to the underlying connection. +// It returns an error if currently no connection has been established. +func (c *Connector) Write(b []byte) (int, error) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.conn == nil { + return 0, errNoConnection + } + n, err := c.conn.Write(b) + // TODO: should the closing rather only happen outside? + // TODO: is the IsTemporaryError useful here? + if err != nil && !netutil.IsTemporaryError(err) { + _ = c.conn.Close() + } + return n, err +} + +func (c *Connector) dial() { + c.mu.Lock() + defer c.mu.Unlock() + + select { + case <-c.stopping: + return + default: + c.conn = nil + conn, err := net.DialTimeout(c.network, c.address, 5*time.Second) + if err != nil { + go c.scheduleRedial() + return + } + c.conn = network.NewManagedConnection(conn) + c.conn.Events.Close.Attach(events.NewClosure(c.dial)) + } +} + +func (c *Connector) scheduleRedial() { + t := time.NewTimer(redialInterval) + defer t.Stop() + select { + case <-c.stopping: + return + case <-t.C: + c.dial() + } +} diff --git a/plugins/analysis/client/fpc_heartbeato.go b/plugins/analysis/client/fpc_heartbeato.go new file mode 100644 index 0000000000000000000000000000000000000000..5a50cc78f0f21e269afd5511e8861fcf2b7ef18a --- /dev/null +++ b/plugins/analysis/client/fpc_heartbeato.go @@ -0,0 +1,93 @@ +package client + +import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/hive.go/identity" +) + +var ( + finalized map[string]vote.Opinion + finalizedMutex sync.RWMutex +) + +func onFinalized(ev *vote.OpinionEvent) { + finalizedMutex.Lock() + finalized[ev.ID] = ev.Opinion + finalizedMutex.Unlock() +} + +func onRoundExecuted(roundStats *vote.RoundStats) { + // get own ID + nodeID := make([]byte, len(identity.ID{})) + if local.GetInstance() != nil { + copy(nodeID, local.GetInstance().ID().Bytes()) + } + + chunks := splitFPCVoteContext(roundStats.ActiveVoteContexts) + + for _, chunk := range chunks { + rs := vote.RoundStats{ + Duration: roundStats.Duration, + RandUsed: roundStats.RandUsed, + ActiveVoteContexts: chunk, + } + + hb := &packet.FPCHeartbeat{ + OwnID: nodeID, + RoundStats: rs, + } + + finalizedMutex.Lock() + hb.Finalized = finalized + finalized = make(map[string]vote.Opinion) + finalizedMutex.Unlock() + + // abort if empty round and no finalized conflicts. + if len(chunk) == 0 && len(hb.Finalized) == 0 { + return + } + + data, err := packet.NewFPCHeartbeatMessage(hb) + if err != nil { + log.Debugw("FPC heartbeat message skipped", "error", err) + return + } + + log.Debugw("Client: onRoundExecuted data size", "len", len(data)) + + if _, err = conn.Write(data); err != nil { + log.Debugw("Error while writing to connection", "Description", err) + return + } + // trigger AnalysisOutboundBytes event + metrics.Events().AnalysisOutboundBytes.Trigger(uint64(len(data))) + } +} + +func splitFPCVoteContext(ctx map[string]*vote.Context) (chunk []map[string]*vote.Context) { + chunk = make([]map[string]*vote.Context, 1) + i, counter := 0, 0 + chunk[i] = make(map[string]*vote.Context) + + if len(ctx) < voteContextChunkThreshold { + chunk[i] = ctx + return + } + + for conflictID, voteCtx := range ctx { + counter++ + if counter >= voteContextChunkThreshold { + counter = 0 + i++ + chunk = append(chunk, make(map[string]*vote.Context)) + } + chunk[i][conflictID] = voteCtx + } + + return +} diff --git a/plugins/analysis/client/heartbeat.go b/plugins/analysis/client/heartbeat.go new file mode 100644 index 0000000000000000000000000000000000000000..c8691302ef6846158db2ce834f88ce566f8ea0fa --- /dev/null +++ b/plugins/analysis/client/heartbeat.go @@ -0,0 +1,77 @@ +package client + +import ( + "io" + "strings" + + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/hive.go/identity" + "github.com/mr-tron/base58" +) + +// EventDispatchers holds the Heartbeat function. +type EventDispatchers struct { + // Heartbeat defines the Heartbeat function. + Heartbeat func(heartbeat *packet.Heartbeat) +} + +func sendHeartbeat(w io.Writer, hb *packet.Heartbeat) { + var out strings.Builder + for _, value := range hb.OutboundIDs { + out.WriteString(base58.Encode(value)) + } + var in strings.Builder + for _, value := range hb.InboundIDs { + in.WriteString(base58.Encode(value)) + } + log.Debugw( + "Heartbeat", + "nodeID", base58.Encode(hb.OwnID), + "outboundIDs", out.String(), + "inboundIDs", in.String(), + ) + + data, err := packet.NewHeartbeatMessage(hb) + if err != nil { + log.Info(err, " - heartbeat message skipped") + return + } + + if _, err = w.Write(data); err != nil { + log.Debugw("Error while writing to connection", "Description", err) + } + // trigger AnalysisOutboundBytes event + metrics.Events().AnalysisOutboundBytes.Trigger(uint64(len(data))) +} + +func createHeartbeat() *packet.Heartbeat { + // get own ID + nodeID := make([]byte, len(identity.ID{})) + if local.GetInstance() != nil { + copy(nodeID, local.GetInstance().ID().Bytes()) + } + + var outboundIDs [][]byte + var inboundIDs [][]byte + + // get outboundIDs (chosen neighbors) + outgoingNeighbors := autopeering.Selection().GetOutgoingNeighbors() + outboundIDs = make([][]byte, len(outgoingNeighbors)) + for i, neighbor := range outgoingNeighbors { + outboundIDs[i] = make([]byte, len(identity.ID{})) + copy(outboundIDs[i], neighbor.ID().Bytes()) + } + + // get inboundIDs (accepted neighbors) + incomingNeighbors := autopeering.Selection().GetIncomingNeighbors() + inboundIDs = make([][]byte, len(incomingNeighbors)) + for i, neighbor := range incomingNeighbors { + inboundIDs[i] = make([]byte, len(identity.ID{})) + copy(inboundIDs[i], neighbor.ID().Bytes()) + } + + return &packet.Heartbeat{OwnID: nodeID, OutboundIDs: outboundIDs, InboundIDs: inboundIDs} +} diff --git a/plugins/analysis/client/metric_heartbeat.go b/plugins/analysis/client/metric_heartbeat.go new file mode 100644 index 0000000000000000000000000000000000000000..38d12f4e49e17ccdc35569b53fbc927294e80bb6 --- /dev/null +++ b/plugins/analysis/client/metric_heartbeat.go @@ -0,0 +1,55 @@ +package client + +import ( + "io" + "runtime" + "time" + + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/hive.go/identity" + "github.com/shirou/gopsutil/cpu" +) + +func sendMetricHeartbeat(w io.Writer, hb *packet.MetricHeartbeat) { + data, err := packet.NewMetricHeartbeatMessage(hb) + if err != nil { + log.Debugw("metric heartbeat message skipped", "err", err) + return + } + + if _, err = w.Write(data); err != nil { + log.Debugw("Error while writing to connection", "Description", err) + } + // trigger AnalysisOutboundBytes event + metrics.Events().AnalysisOutboundBytes.Trigger(uint64(len(data))) +} + +func createMetricHeartbeat() *packet.MetricHeartbeat { + // get own ID + nodeID := make([]byte, len(identity.ID{})) + if local.GetInstance() != nil { + copy(nodeID, local.GetInstance().ID().Bytes()) + } + + return &packet.MetricHeartbeat{ + OwnID: nodeID, + OS: runtime.GOOS, + Arch: runtime.GOARCH, + NumCPU: runtime.GOMAXPROCS(0), + // TODO: replace this with only the CPU usage of the GoShimmer process. + CPUUsage: func() (p float64) { + percent, err := cpu.Percent(time.Second, false) + if err == nil { + p = percent[0] + } + return + }(), + MemoryUsage: func() uint64 { + var m runtime.MemStats + runtime.ReadMemStats(&m) + return m.Alloc + }(), + } +} diff --git a/plugins/analysis/client/parameters.go b/plugins/analysis/client/parameters.go deleted file mode 100644 index b875fadf36853578cfc8ef31e1d843459e72cfa5..0000000000000000000000000000000000000000 --- a/plugins/analysis/client/parameters.go +++ /dev/null @@ -1,13 +0,0 @@ -package client - -import ( - flag "github.com/spf13/pflag" -) - -const ( - CFG_SERVER_ADDRESS = "analysis.client.serverAddress" -) - -func init() { - flag.String(CFG_SERVER_ADDRESS, "ressims.iota.cafe:188", "tcp server for collecting analysis information") -} diff --git a/plugins/analysis/client/plugin.go b/plugins/analysis/client/plugin.go index fa9623609aa4b56d7bc9c776908010df081dda69..16d2401cd87dcc74b244ab51cd31b0a935e04f02 100644 --- a/plugins/analysis/client/plugin.go +++ b/plugins/analysis/client/plugin.go @@ -1,193 +1,81 @@ package client import ( - "encoding/hex" - "net" "sync" "time" - "github.com/iotaledger/goshimmer/packages/parameter" + "github.com/iotaledger/goshimmer/dapps/valuetransfers" "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/analysis/types/addnode" - "github.com/iotaledger/goshimmer/plugins/analysis/types/connectnodes" - "github.com/iotaledger/goshimmer/plugins/analysis/types/disconnectnodes" - "github.com/iotaledger/goshimmer/plugins/analysis/types/ping" - "github.com/iotaledger/goshimmer/plugins/analysis/types/removenode" - "github.com/iotaledger/goshimmer/plugins/autopeering" - "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/hive.go/autopeering/discover" - "github.com/iotaledger/hive.go/autopeering/selection" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/events" "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/network" "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/hive.go/timeutil" + flag "github.com/spf13/pflag" ) -var log *logger.Logger -var connLock sync.Mutex - -func Run(plugin *node.Plugin) { - log = logger.NewLogger("Analysis-Client") - daemon.BackgroundWorker("Analysis Client", func(shutdownSignal <-chan struct{}) { - shuttingDown := false - - for !shuttingDown { - select { - case <-shutdownSignal: - return - - default: - if conn, err := net.Dial("tcp", parameter.NodeConfig.GetString(CFG_SERVER_ADDRESS)); err != nil { - log.Debugf("Could not connect to reporting server: %s", err.Error()) - - timeutil.Sleep(1*time.Second, shutdownSignal) - } else { - managedConn := network.NewManagedConnection(conn) - eventDispatchers := getEventDispatchers(managedConn) - - reportCurrentStatus(eventDispatchers) - setupHooks(plugin, managedConn, eventDispatchers) - - shuttingDown = keepConnectionAlive(managedConn, shutdownSignal) - } - } - } - }, shutdown.ShutdownPriorityAnalysis) -} - -func getEventDispatchers(conn *network.ManagedConnection) *EventDispatchers { - return &EventDispatchers{ - AddNode: func(nodeId []byte) { - log.Debugw("AddNode", "nodeId", hex.EncodeToString(nodeId)) - connLock.Lock() - _, _ = conn.Write((&addnode.Packet{NodeId: nodeId}).Marshal()) - connLock.Unlock() - }, - RemoveNode: func(nodeId []byte) { - log.Debugw("RemoveNode", "nodeId", hex.EncodeToString(nodeId)) - connLock.Lock() - _, _ = conn.Write((&removenode.Packet{NodeId: nodeId}).Marshal()) - connLock.Unlock() - }, - ConnectNodes: func(sourceId []byte, targetId []byte) { - log.Debugw("ConnectNodes", "sourceId", hex.EncodeToString(sourceId), "targetId", hex.EncodeToString(targetId)) - connLock.Lock() - _, _ = conn.Write((&connectnodes.Packet{SourceId: sourceId, TargetId: targetId}).Marshal()) - connLock.Unlock() - }, - DisconnectNodes: func(sourceId []byte, targetId []byte) { - log.Debugw("DisconnectNodes", "sourceId", hex.EncodeToString(sourceId), "targetId", hex.EncodeToString(targetId)) - connLock.Lock() - _, _ = conn.Write((&disconnectnodes.Packet{SourceId: sourceId, TargetId: targetId}).Marshal()) - connLock.Unlock() - }, - } -} - -func reportCurrentStatus(eventDispatchers *EventDispatchers) { - if local.GetInstance() != nil { - eventDispatchers.AddNode(local.GetInstance().ID().Bytes()) - } +const ( + // PluginName is the name of the analysis client plugin. + PluginName = "Analysis-Client" + // CfgServerAddress defines the config flag of the analysis server address. + CfgServerAddress = "analysis.client.serverAddress" + // defines the report interval of the reporting in seconds. + reportIntervalSec = 5 + // voteContextChunkThreshold defines the maximum number of vote context to fit into an FPC update. + voteContextChunkThreshold = 50 +) - reportKnownPeers(eventDispatchers) - reportChosenNeighbors(eventDispatchers) - reportAcceptedNeighbors(eventDispatchers) +func init() { + flag.String(CfgServerAddress, "ressims.iota.cafe:21888", "tcp server for collecting analysis information") } -func setupHooks(plugin *node.Plugin, conn *network.ManagedConnection, eventDispatchers *EventDispatchers) { - // define hooks //////////////////////////////////////////////////////////////////////////////////////////////////// - - onDiscoverPeer := events.NewClosure(func(ev *discover.DiscoveredEvent) { - eventDispatchers.AddNode(ev.Peer.ID().Bytes()) - }) - - onDeletePeer := events.NewClosure(func(ev *discover.DeletedEvent) { - eventDispatchers.RemoveNode(ev.Peer.ID().Bytes()) - }) - - onAddChosenNeighbor := events.NewClosure(func(ev *selection.PeeringEvent) { - if ev.Status { - eventDispatchers.ConnectNodes(local.GetInstance().ID().Bytes(), ev.Peer.ID().Bytes()) - } - }) - - onAddAcceptedNeighbor := events.NewClosure(func(ev *selection.PeeringEvent) { - if ev.Status { - eventDispatchers.ConnectNodes(ev.Peer.ID().Bytes(), local.GetInstance().ID().Bytes()) - } - }) - - onRemoveNeighbor := events.NewClosure(func(ev *selection.DroppedEvent) { - eventDispatchers.DisconnectNodes(ev.DroppedID.Bytes(), local.GetInstance().ID().Bytes()) - }) - - // setup hooks ///////////////////////////////////////////////////////////////////////////////////////////////////// - - discover.Events.PeerDiscovered.Attach(onDiscoverPeer) - discover.Events.PeerDeleted.Attach(onDeletePeer) - selection.Events.IncomingPeering.Attach(onAddAcceptedNeighbor) - selection.Events.OutgoingPeering.Attach(onAddChosenNeighbor) - selection.Events.Dropped.Attach(onRemoveNeighbor) - - // clean up hooks on close ///////////////////////////////////////////////////////////////////////////////////////// - - var onClose *events.Closure - onClose = events.NewClosure(func() { - discover.Events.PeerDiscovered.Detach(onDiscoverPeer) - discover.Events.PeerDeleted.Detach(onDeletePeer) - selection.Events.IncomingPeering.Detach(onAddAcceptedNeighbor) - selection.Events.OutgoingPeering.Detach(onAddChosenNeighbor) - selection.Events.Dropped.Detach(onRemoveNeighbor) +var ( + // plugin is the plugin instance of the analysis client plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger + conn *Connector +) - conn.Events.Close.Detach(onClose) +// Plugin gets the plugin instance +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, run) }) - conn.Events.Close.Attach(onClose) + return plugin } -func reportKnownPeers(dispatchers *EventDispatchers) { - if autopeering.Discovery != nil { - for _, peer := range autopeering.Discovery.GetVerifiedPeers() { - dispatchers.AddNode(peer.ID().Bytes()) - } - } -} +func run(_ *node.Plugin) { + finalized = make(map[string]vote.Opinion) + log = logger.NewLogger(PluginName) + conn = NewConnector("tcp", config.Node().GetString(CfgServerAddress)) -func reportChosenNeighbors(dispatchers *EventDispatchers) { - if autopeering.Selection != nil { - for _, chosenNeighbor := range autopeering.Selection.GetOutgoingNeighbors() { - //dispatchers.AddNode(chosenNeighbor.ID().Bytes()) - dispatchers.ConnectNodes(local.GetInstance().ID().Bytes(), chosenNeighbor.ID().Bytes()) - } - } -} + if err := daemon.BackgroundWorker(PluginName, func(shutdownSignal <-chan struct{}) { + conn.Start() + defer conn.Stop() -func reportAcceptedNeighbors(dispatchers *EventDispatchers) { - if autopeering.Selection != nil { - for _, acceptedNeighbor := range autopeering.Selection.GetIncomingNeighbors() { - //dispatchers.AddNode(acceptedNeighbor.ID().Bytes()) - dispatchers.ConnectNodes(acceptedNeighbor.ID().Bytes(), local.GetInstance().ID().Bytes()) - } - } -} + onFinalizedClosure := events.NewClosure(onFinalized) + valuetransfers.Voter().Events().Finalized.Attach(onFinalizedClosure) + defer valuetransfers.Voter().Events().Finalized.Detach(onFinalizedClosure) -func keepConnectionAlive(conn *network.ManagedConnection, shutdownSignal <-chan struct{}) bool { - go conn.Read(make([]byte, 1)) + onRoundExecutedClosure := events.NewClosure(onRoundExecuted) + valuetransfers.Voter().Events().RoundExecuted.Attach(onRoundExecutedClosure) + defer valuetransfers.Voter().Events().RoundExecuted.Detach(onRoundExecutedClosure) - ticker := time.NewTicker(1 * time.Second) - for { - select { - case <-shutdownSignal: - return true + ticker := time.NewTicker(reportIntervalSec * time.Second) + defer ticker.Stop() + for { + select { + case <-shutdownSignal: + return - case <-ticker.C: - connLock.Lock() - if _, err := conn.Write((&ping.Packet{}).Marshal()); err != nil { - connLock.Unlock() - return false + case <-ticker.C: + sendHeartbeat(conn, createHeartbeat()) + sendMetricHeartbeat(conn, createMetricHeartbeat()) } - connLock.Unlock() } + }, shutdown.PriorityAnalysis); err != nil { + log.Panicf("Failed to start as daemon: %s", err) } } diff --git a/plugins/analysis/client/types.go b/plugins/analysis/client/types.go deleted file mode 100644 index dabbb160013a8823d2bcb0b2c8d87dfe97834d15..0000000000000000000000000000000000000000 --- a/plugins/analysis/client/types.go +++ /dev/null @@ -1,8 +0,0 @@ -package client - -type EventDispatchers struct { - AddNode func(nodeId []byte) - RemoveNode func(nodeId []byte) - ConnectNodes func(sourceId []byte, targetId []byte) - DisconnectNodes func(sourceId []byte, targetId []byte) -} diff --git a/plugins/analysis/dashboard/autopeering_feed.go b/plugins/analysis/dashboard/autopeering_feed.go new file mode 100644 index 0000000000000000000000000000000000000000..431061f4c9d8bacc736a32d25fd1cc7c2a2f9584 --- /dev/null +++ b/plugins/analysis/dashboard/autopeering_feed.go @@ -0,0 +1,172 @@ +package dashboard + +import ( + "fmt" + "time" + + "github.com/gorilla/websocket" + "github.com/iotaledger/goshimmer/packages/shutdown" + analysisserver "github.com/iotaledger/goshimmer/plugins/analysis/server" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/workerpool" +) + +var ( + autopeeringWorkerCount = 1 + autopeeringWorkerQueueSize = 500 + autopeeringWorkerPool *workerpool.WorkerPool +) + +// JSON encoded websocket message for adding a node +type addNode struct { + ID string `json:"id"` +} + +// JSON encoded websocket message for removing a node +type removeNode struct { + ID string `json:"id"` +} + +// JSON encoded websocket message for connecting two nodes +type connectNodes struct { + Source string `json:"source"` + Target string `json:"target"` +} + +// JSON encoded websocket message for disconnecting two nodes +type disconnectNodes struct { + Source string `json:"source"` + Target string `json:"target"` +} + +func configureAutopeeringWorkerPool() { + // create a new worker pool for processing autopeering updates coming from analysis server + autopeeringWorkerPool = workerpool.New(func(task workerpool.Task) { + // determine what msg to send based on first parameter + // first parameter is always a letter denoting what to do with the following string or strings + x := fmt.Sprintf("%v", task.Param(0)) + switch x { + case "A": + sendAddNode(task.Param(1).(string)) + case "a": + sendRemoveNode(task.Param(1).(string)) + case "C": + sendConnectNodes(task.Param(1).(string), task.Param(2).(string)) + case "c": + sendDisconnectNodes(task.Param(1).(string), task.Param(2).(string)) + } + + task.Return(nil) + }, workerpool.WorkerCount(autopeeringWorkerCount), workerpool.QueueSize(autopeeringWorkerQueueSize)) +} + +// send and addNode msg to all connected ws clients +func sendAddNode(nodeID string) { + broadcastWsMessage(&wsmsg{MsgTypeAddNode, &addNode{nodeID}}, true) +} + +// send a removeNode msg to all connected ws clients +func sendRemoveNode(nodeID string) { + broadcastWsMessage(&wsmsg{MsgTypeRemoveNode, &removeNode{nodeID}}, true) +} + +// send a connectNodes msg to all connected ws clients +func sendConnectNodes(source string, target string) { + broadcastWsMessage(&wsmsg{MsgTypeConnectNodes, &connectNodes{ + Source: source, + Target: target, + }}, true) +} + +// send disconnectNodes to all connected ws clients +func sendDisconnectNodes(source string, target string) { + broadcastWsMessage(&wsmsg{MsgTypeDisconnectNodes, &disconnectNodes{ + Source: source, + Target: target, + }}, true) +} + +// runs autopeering feed to propagate autopeering events from analysis server to frontend +func runAutopeeringFeed() { + // closures for the different events + notifyAddNode := events.NewClosure(func(nodeID string) { + autopeeringWorkerPool.Submit("A", nodeID) + }) + notifyRemoveNode := events.NewClosure(func(nodeID string) { + autopeeringWorkerPool.Submit("a", nodeID) + }) + notifyConnectNodes := events.NewClosure(func(source string, target string) { + autopeeringWorkerPool.Submit("C", source, target) + }) + notifyDisconnectNodes := events.NewClosure(func(source string, target string) { + autopeeringWorkerPool.Submit("c", source, target) + }) + + if err := daemon.BackgroundWorker("Analysis-Dashboard[AutopeeringVisualizer]", func(shutdownSignal <-chan struct{}) { + // connect closures (submitting tasks) to events of the analysis server + analysisserver.Events.AddNode.Attach(notifyAddNode) + defer analysisserver.Events.AddNode.Detach(notifyAddNode) + analysisserver.Events.RemoveNode.Attach(notifyRemoveNode) + defer analysisserver.Events.RemoveNode.Detach(notifyRemoveNode) + analysisserver.Events.ConnectNodes.Attach(notifyConnectNodes) + defer analysisserver.Events.ConnectNodes.Detach(notifyConnectNodes) + analysisserver.Events.DisconnectNodes.Attach(notifyDisconnectNodes) + defer analysisserver.Events.DisconnectNodes.Detach(notifyDisconnectNodes) + autopeeringWorkerPool.Start() + <-shutdownSignal + log.Info("Stopping Analysis-Dashboard[AutopeeringVisualizer] ...") + autopeeringWorkerPool.Stop() + log.Info("Stopping Analysis-Dashboard[AutopeeringVisualizer] ... done") + }, shutdown.PriorityDashboard); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} + +// creates event handlers for replaying autopeering events on them +func createAutopeeringEventHandlers(wsClient *websocket.Conn, nodeCallbackFactory func(*websocket.Conn, string) func(string), linkCallbackFactory func(*websocket.Conn, string) func(string, string)) *EventHandlers { + return &EventHandlers{ + AddNode: nodeCallbackFactory(wsClient, "A"), + RemoveNode: nodeCallbackFactory(wsClient, "a"), + ConnectNodes: linkCallbackFactory(wsClient, "C"), + DisconnectNodes: linkCallbackFactory(wsClient, "c"), + } +} + +// creates callback function for addNode and removeNode events +func createSyncNodeCallback(ws *websocket.Conn, msgType string) func(nodeID string) { + return func(nodeID string) { + var wsMessage *wsmsg + switch msgType { + case "A": + wsMessage = &wsmsg{MsgTypeAddNode, &addNode{nodeID}} + case "a": + wsMessage = &wsmsg{MsgTypeRemoveNode, &removeNode{nodeID}} + } + if err := ws.WriteJSON(wsMessage); err != nil { + return + } + if err := ws.SetWriteDeadline(time.Now().Add(webSocketWriteTimeout)); err != nil { + return + } + } +} + +// creates callback function for connectNodes and disconnectNodes events +func createSyncLinkCallback(ws *websocket.Conn, msgType string) func(sourceID string, targetID string) { + return func(sourceID string, targetID string) { + var wsMessage *wsmsg + switch msgType { + case "C": + wsMessage = &wsmsg{MsgTypeConnectNodes, &connectNodes{sourceID, targetID}} + case "c": + wsMessage = &wsmsg{MsgTypeDisconnectNodes, &disconnectNodes{sourceID, targetID}} + } + if err := ws.WriteJSON(wsMessage); err != nil { + return + } + if err := ws.SetWriteDeadline(time.Now().Add(webSocketWriteTimeout)); err != nil { + return + } + } +} diff --git a/plugins/spa/spa-packr.go b/plugins/analysis/dashboard/dashboard-packr.go similarity index 68% rename from plugins/spa/spa-packr.go rename to plugins/analysis/dashboard/dashboard-packr.go index cf8854b06de8330a1c8f8495285b258a79fb7f1c..173f3779512003421138356e2d11ba97129fae80 100644 --- a/plugins/spa/spa-packr.go +++ b/plugins/analysis/dashboard/dashboard-packr.go @@ -3,6 +3,6 @@ // You can use the "packr clean" command to clean up this, // and any other packr generated files. -package spa +package dashboard -import _ "github.com/iotaledger/goshimmer/plugins/spa/packrd" +import _ "github.com/iotaledger/goshimmer/plugins/dashboard/packrd" diff --git a/plugins/analysis/dashboard/fpc_activeConflictSet.go b/plugins/analysis/dashboard/fpc_activeConflictSet.go new file mode 100644 index 0000000000000000000000000000000000000000..4cb31eda6f2d6c23208440dcbdaf70c711098352 --- /dev/null +++ b/plugins/analysis/dashboard/fpc_activeConflictSet.go @@ -0,0 +1,74 @@ +package dashboard + +import "sync" + +// activeConflictSet contains the set of the active conflicts, not yet finalized. +type activeConflictSet struct { + conflictSet conflictSet + lock sync.RWMutex +} + +func newActiveConflictSet() *activeConflictSet { + return &activeConflictSet{ + conflictSet: make(conflictSet), + } +} + +// cleanUp removes the finalized conflicts from the active conflicts set. +func (cr *activeConflictSet) cleanUp() { + cr.lock.Lock() + defer cr.lock.Unlock() + + for id, conflict := range cr.conflictSet { + if conflict.isFinalized() { + delete(cr.conflictSet, id) + } + } +} + +func (cr *activeConflictSet) ToFPCUpdate() *FPCUpdate { + cr.lock.RLock() + defer cr.lock.RUnlock() + + return &FPCUpdate{ + Conflicts: cr.conflictSet, + } +} + +func (cr *activeConflictSet) load(ID string) (conflict, bool) { + cr.lock.RLock() + defer cr.lock.RUnlock() + + // update the internal state + if c, ok := cr.conflictSet[ID]; !ok { + return c, false + } + + return cr.conflictSet[ID], true +} + +func (cr *activeConflictSet) update(ID string, c conflict) { + cr.lock.Lock() + defer cr.lock.Unlock() + + // update the internal state + if _, ok := cr.conflictSet[ID]; !ok { + cr.conflictSet[ID] = newConflict() + } + + for nodeID, context := range c.NodesView { + cr.conflictSet[ID].NodesView[nodeID] = context + } +} + +func (cr *activeConflictSet) delete(ID string) { + cr.lock.Lock() + defer cr.lock.Unlock() + + // update the internal state + if _, ok := cr.conflictSet[ID]; !ok { + return + } + + delete(cr.conflictSet, ID) +} diff --git a/plugins/analysis/dashboard/fpc_activeConflictSet_test.go b/plugins/analysis/dashboard/fpc_activeConflictSet_test.go new file mode 100644 index 0000000000000000000000000000000000000000..62629aab45c7443cecbd54618cfceaa17ec49a86 --- /dev/null +++ b/plugins/analysis/dashboard/fpc_activeConflictSet_test.go @@ -0,0 +1,60 @@ +package dashboard + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestActiveConflictsUpdate(t *testing.T) { + // ConflictRecord creation + c := newActiveConflictSet() + + // test first new update + conflictA := conflict{ + NodesView: map[string]voteContext{ + "nodeA": { + NodeID: "nodeA", + Rounds: 3, + Opinions: []int32{disliked, liked, disliked}, + Outcome: liked, + }, + }, + } + c.update("A", conflictA) + + require.Equal(t, conflictA, c.conflictSet["A"]) + + // test second new update + conflictB := conflict{ + NodesView: map[string]voteContext{ + "nodeB": { + NodeID: "nodeB", + Rounds: 3, + Opinions: []int32{disliked, liked, disliked}, + Outcome: liked, + }, + }, + } + c.update("B", conflictB) + + require.Equal(t, conflictB, c.conflictSet["B"]) + + // test modify existing entry + conflictB = conflict{ + NodesView: map[string]voteContext{ + "nodeB": { + NodeID: "nodeB", + Rounds: 4, + Opinions: []int32{disliked, liked, disliked, liked}, + Outcome: liked, + }, + }, + } + c.update("B", conflictB) + require.Equal(t, conflictB, c.conflictSet["B"]) + + // test entry removal + c.delete("B") + require.NotContains(t, c.conflictSet, "B") +} diff --git a/plugins/analysis/dashboard/fpc_conflict.go b/plugins/analysis/dashboard/fpc_conflict.go new file mode 100644 index 0000000000000000000000000000000000000000..a7880b962f52a6a94e0e362f076a5dc80a181e04 --- /dev/null +++ b/plugins/analysis/dashboard/fpc_conflict.go @@ -0,0 +1,54 @@ +package dashboard + +// conflictSet is defined as a a map of conflict IDs and their conflict. +type conflictSet = map[string]conflict + +// conflict defines the struct for the opinions of the nodes regarding a given conflict. +type conflict struct { + NodesView map[string]voteContext `json:"nodesview" bson:"nodesview"` +} + +type voteContext struct { + NodeID string `json:"nodeid" bson:"nodeid"` + Rounds int `json:"rounds" bson:"rounds"` + Opinions []int32 `json:"opinions" bson:"opinions"` + Outcome int32 `json:"outcome" bson:"outcome"` +} + +func newConflict() conflict { + return conflict{ + NodesView: make(map[string]voteContext), + } +} + +// isFinalized returns true if all the nodes have finalized a given conflict. +// It also returns false if the given conflict has an empty nodesView. +func (c conflict) isFinalized() bool { + if len(c.NodesView) == 0 { + return false + } + + count := 0 + for _, context := range c.NodesView { + if context.Outcome == liked || context.Outcome == disliked { + count++ + } + } + + return (count == len(c.NodesView)) +} + +// finalizedRatio returns the ratio of nodes that have finalized a given conflict. +func (c conflict) finalizedRatio() float64 { + if len(c.NodesView) == 0 { + return 0 + } + count := 0 + for _, context := range c.NodesView { + if context.Outcome == liked || context.Outcome == disliked { + count++ + } + } + + return (float64(count) / float64(len(c.NodesView))) +} diff --git a/plugins/analysis/dashboard/fpc_conflict_test.go b/plugins/analysis/dashboard/fpc_conflict_test.go new file mode 100644 index 0000000000000000000000000000000000000000..dcb68627da5a8a676951399d68baa10ae393b039 --- /dev/null +++ b/plugins/analysis/dashboard/fpc_conflict_test.go @@ -0,0 +1,79 @@ +package dashboard + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// TestIsFinalized checks that for a given conflict, its method isFinalized works ok. +func TestIsFinalized(t *testing.T) { + tests := []struct { + conflict + want bool + }{ + { + conflict: conflict{ + NodesView: map[string]voteContext{ + "one": {Outcome: liked}, + "two": {Outcome: disliked}, + }, + }, + want: true, + }, + { + conflict: conflict{ + NodesView: map[string]voteContext{ + "one": {Outcome: liked}, + "two": {}, + }, + }, + want: false, + }, + { + conflict: conflict{}, + want: false, + }, + } + + for _, conflictTest := range tests { + require.Equal(t, conflictTest.want, conflictTest.isFinalized()) + } + +} + +// TestFinalizationStatus checks that for a given conflict, its method finalizationStatus works ok. +func TestFinalizationStatus(t *testing.T) { + tests := []struct { + conflict + want float64 + }{ + { + conflict: conflict{ + NodesView: map[string]voteContext{ + "one": {Outcome: liked}, + "two": {Outcome: disliked}, + }, + }, + want: 1, + }, + { + conflict: conflict{ + NodesView: map[string]voteContext{ + "one": {Outcome: liked}, + "two": {}, + }, + }, + want: 0.5, + }, + { + conflict: conflict{}, + want: 0, + }, + } + + for _, conflictTest := range tests { + require.Equal(t, conflictTest.want, conflictTest.finalizedRatio()) + } + +} diff --git a/plugins/analysis/dashboard/fpc_livefeed.go b/plugins/analysis/dashboard/fpc_livefeed.go new file mode 100644 index 0000000000000000000000000000000000000000..f99c03274c5c6503b19e5e4c254179ac2645754f --- /dev/null +++ b/plugins/analysis/dashboard/fpc_livefeed.go @@ -0,0 +1,184 @@ +package dashboard + +import ( + "runtime" + "time" + + "github.com/gorilla/websocket" + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + analysis "github.com/iotaledger/goshimmer/plugins/analysis/server" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/workerpool" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +const ( + liked = 1 + disliked = 2 +) + +var ( + fpcLiveFeedWorkerCount = 1 + fpcLiveFeedWorkerQueueSize = 300 + fpcLiveFeedWorkerPool *workerpool.WorkerPool + + fpcStoreFinalizedWorkerCount = runtime.GOMAXPROCS(0) + fpcStoreFinalizedWorkerQueueSize = 300 + fpcStoreFinalizedWorkerPool *workerpool.WorkerPool + + activeConflicts = newActiveConflictSet() +) + +// FPCUpdate contains an FPC update. +type FPCUpdate struct { + Conflicts conflictSet `json:"conflictset" bson:"conflictset"` +} + +func configureFPCLiveFeed() { + + if config.Node().GetBool(CfgMongoDBEnabled) { + mongoDB() + } + + fpcLiveFeedWorkerPool = workerpool.New(func(task workerpool.Task) { + newMsg := task.Param(0).(*FPCUpdate) + broadcastWsMessage(&wsmsg{MsgTypeFPC, newMsg}, true) + task.Return(nil) + }, workerpool.WorkerCount(fpcLiveFeedWorkerCount), workerpool.QueueSize(fpcLiveFeedWorkerQueueSize)) + + if config.Node().GetBool(CfgMongoDBEnabled) { + fpcStoreFinalizedWorkerPool = workerpool.New(func(task workerpool.Task) { + storeFinalizedVoteContext(task.Param(0).(FPCRecords)) + task.Return(nil) + }, workerpool.WorkerCount(fpcStoreFinalizedWorkerCount), workerpool.QueueSize(fpcStoreFinalizedWorkerQueueSize)) + } +} + +func runFPCLiveFeed() { + if err := daemon.BackgroundWorker("Analysis[FPCUpdater]", func(shutdownSignal <-chan struct{}) { + onFPCHeartbeatReceived := events.NewClosure(func(hb *packet.FPCHeartbeat) { + fpcLiveFeedWorkerPool.Submit(createFPCUpdate(hb)) + }) + analysis.Events.FPCHeartbeat.Attach(onFPCHeartbeatReceived) + + fpcLiveFeedWorkerPool.Start() + defer fpcLiveFeedWorkerPool.Stop() + + if config.Node().GetBool(CfgMongoDBEnabled) { + fpcStoreFinalizedWorkerPool.Start() + defer fpcStoreFinalizedWorkerPool.Stop() + } + + cleanUpTicker := time.NewTicker(1 * time.Minute) + + for { + select { + case <-shutdownSignal: + log.Info("Stopping Analysis[FPCUpdater] ...") + analysis.Events.FPCHeartbeat.Detach(onFPCHeartbeatReceived) + cleanUpTicker.Stop() + log.Info("Stopping Analysis[FPCUpdater] ... done") + return + case <-cleanUpTicker.C: + log.Debug("Cleaning up Finalized Conflicts ...") + activeConflicts.cleanUp() + log.Debug("Cleaning up Finalized Conflicts ... done") + } + } + }, shutdown.PriorityDashboard); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} + +func createFPCUpdate(hb *packet.FPCHeartbeat) *FPCUpdate { + // prepare the update + conflicts := make(conflictSet) + nodeID := shortNodeIDString(hb.OwnID) + for ID, context := range hb.RoundStats.ActiveVoteContexts { + newVoteContext := voteContext{ + NodeID: nodeID, + Rounds: context.Rounds, + Opinions: vote.ConvertOpinionsToInts32(context.Opinions), + } + + conflicts[ID] = newConflict() + conflicts[ID].NodesView[nodeID] = newVoteContext + + // update recorded events + activeConflicts.update(ID, conflict{NodesView: map[string]voteContext{nodeID: newVoteContext}}) + } + + // check finalized conflicts + if len(hb.Finalized) == 0 { + return &FPCUpdate{Conflicts: conflicts} + } + + finalizedConflicts := make(FPCRecords, len(hb.Finalized)) + i := 0 + for ID, finalOpinion := range hb.Finalized { + conflictOverview, ok := activeConflicts.load(ID) + if !ok { + log.Error("Error: missing conflict with ID:", ID) + continue + } + conflictDetail := conflictOverview.NodesView[nodeID] + conflictDetail.Outcome = vote.ConvertOpinionToInt32(finalOpinion) + conflicts[ID] = newConflict() + conflicts[ID].NodesView[nodeID] = conflictDetail + activeConflicts.update(ID, conflicts[ID]) + finalizedConflicts[i] = FPCRecord{ + ConflictID: ID, + NodeID: conflictDetail.NodeID, + Rounds: conflictDetail.Rounds, + Opinions: conflictDetail.Opinions, + Outcome: conflictDetail.Outcome, + Time: primitive.NewDateTimeFromTime(time.Now()), + } + i++ + + metrics.Events().AnalysisFPCFinalized.Trigger(&metrics.AnalysisFPCFinalizedEvent{ + ConflictID: ID, + NodeID: conflictDetail.NodeID, + Rounds: conflictDetail.Rounds, + Opinions: vote.ConvertInts32ToOpinions(conflictDetail.Opinions), + Outcome: vote.ConvertInt32Opinion(conflictDetail.Outcome), + }) + } + + if config.Node().GetBool(CfgMongoDBEnabled) { + fpcStoreFinalizedWorkerPool.TrySubmit(finalizedConflicts) + } + + return &FPCUpdate{Conflicts: conflicts} +} + +// stores the given finalized vote contexts into the database. +func storeFinalizedVoteContext(finalizedConflicts FPCRecords) { + db := mongoDB() + + if err := pingOrReconnectMongoDB(); err != nil { + return + } + + if err := storeFPCRecords(finalizedConflicts, db); err != nil { + log.Errorf("Error while writing on MongoDB: %s", err) + } +} + +// replay FPC records (past events). +func replayFPCRecords(ws *websocket.Conn) { + wsMessage := &wsmsg{MsgTypeFPC, activeConflicts.ToFPCUpdate()} + + if err := ws.WriteJSON(wsMessage); err != nil { + log.Info(err) + return + } + if err := ws.SetWriteDeadline(time.Now().Add(webSocketWriteTimeout)); err != nil { + return + } +} diff --git a/plugins/analysis/dashboard/fpc_livefeed_test.go b/plugins/analysis/dashboard/fpc_livefeed_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a5c4a8ea7c00fc8cad3153e0d2675c75bccb1657 --- /dev/null +++ b/plugins/analysis/dashboard/fpc_livefeed_test.go @@ -0,0 +1,52 @@ +package dashboard + +import ( + "crypto/sha256" + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + "github.com/stretchr/testify/require" +) + +// TestCreateFPCUpdate checks that given a FPC heartbeat, the returned FPCUpdate is ok. +func TestCreateFPCUpdate(t *testing.T) { + ownID := sha256.Sum256([]byte{'A'}) + base58OwnID := shortNodeIDString(ownID[:]) + + // create a FPCHeartbeat + hbTest := &packet.FPCHeartbeat{ + OwnID: ownID[:], + RoundStats: vote.RoundStats{ + Duration: time.Second, + RandUsed: 0.5, + ActiveVoteContexts: map[string]*vote.Context{ + "one": { + ID: "one", + Liked: 1., + Rounds: 3, + Opinions: []vote.Opinion{vote.Dislike, vote.Like, vote.Dislike}, + }}, + }, + } + + // create a matching FPCUpdate + want := &FPCUpdate{ + Conflicts: conflictSet{ + "one": { + NodesView: map[string]voteContext{ + base58OwnID: { + NodeID: base58OwnID, + Rounds: 3, + Opinions: []int32{disliked, liked, disliked}, + }, + }, + }, + }, + } + + // check that createFPCUpdate returns a matching FPCMsg + require.Equal(t, want, createFPCUpdate(hbTest)) + +} diff --git a/plugins/analysis/dashboard/fpc_storage.go b/plugins/analysis/dashboard/fpc_storage.go new file mode 100644 index 0000000000000000000000000000000000000000..66506742d89d6f184630889b3fd40a5561acde25 --- /dev/null +++ b/plugins/analysis/dashboard/fpc_storage.go @@ -0,0 +1,146 @@ +package dashboard + +import ( + "context" + "sync" + "time" + + "github.com/iotaledger/goshimmer/plugins/config" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "go.mongodb.org/mongo-driver/mongo/readpref" +) + +// FPCRecord defines the FPC record to be stored into a mongoDB. +type FPCRecord struct { + // ConflictID defines the ID of the conflict. + ConflictID string `json:"conflictid" bson:"conflictid"` + // NodeID defines the ID of the node. + NodeID string `json:"nodeid" bson:"nodeid"` + // Rounds defines number of rounds performed to finalize the conflict. + Rounds int `json:"rounds" bson:"rounds"` + // Opinions contains the opinion of each round. + Opinions []int32 `json:"opinions" bson:"opinions"` + // Outcome defines final opinion of the conflict. + Outcome int32 `json:"outcome" bson:"outcome"` + // Time defines the time when the conflict has been finalized. + Time primitive.DateTime `json:"datetime" bson:"datetime"` +} + +// FPCRecords defines a slice of FPCRecord +type FPCRecords = []FPCRecord + +const ( + // defaultMongoDBOpTimeout defines the default MongoDB operation timeout. + defaultMongoDBOpTimeout = 5 * time.Second +) + +var ( + clientDB *mongo.Client + //db *mongo.Database + dbOnce sync.Once + // read locked by pingers and write locked by the routine trying to reconnect. + mongoReconnectLock sync.RWMutex +) + +func mongoDB() *mongo.Database { + dbOnce.Do(func() { + client, err := newMongoDB() + if err != nil { + log.Fatal(err) + } + clientDB = client + }) + return clientDB.Database("analysis") +} + +func newMongoDB() (*mongo.Client, error) { + username := config.Node().GetString(CfgMongoDBUsername) + password := config.Node().GetString(CfgMongoDBPassword) + hostAddr := config.Node().GetString(CfgMongoDBHostAddress) + + client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://" + username + ":" + password + "@" + hostAddr)) + if err != nil { + log.Fatalf("MongoDB NewClient failed: %s", err) + return nil, err + } + + if err := connectMongoDB(client); err != nil { + return nil, err + } + + if err := pingMongoDB(client); err != nil { + return nil, err + } + + return client, nil +} + +// pings the MongoDB and attempts to reconnect to it in case the connection was lost. +func pingOrReconnectMongoDB() error { + mongoReconnectLock.RLock() + ctx, cancel := operationTimeout(defaultMongoDBOpTimeout) + defer cancel() + err := clientDB.Ping(ctx, readpref.Primary()) + if err == nil { + mongoReconnectLock.RUnlock() + return nil + } + log.Warnf("MongoDB ping failed: %s", err) + mongoReconnectLock.RUnlock() + + mongoReconnectLock.Lock() + defer mongoReconnectLock.Unlock() + + // check whether ping still doesn't work + ctx, cancel = operationTimeout(defaultMongoDBOpTimeout) + defer cancel() + if err := clientDB.Ping(ctx, readpref.Primary()); err == nil { + return nil + } + + // reconnect + ctx, cancel = operationTimeout(defaultMongoDBOpTimeout) + defer cancel() + if err := clientDB.Connect(ctx); err != nil { + log.Warnf("MongoDB connection failed: %s", err) + return err + } + return nil +} + +func connectMongoDB(client *mongo.Client) error { + ctx, cancel := operationTimeout(defaultMongoDBOpTimeout) + defer cancel() + if err := client.Connect(ctx); err != nil { + log.Warnf("MongoDB connection failed: %s", err) + return err + } + return nil +} + +func pingMongoDB(client *mongo.Client) error { + ctx, cancel := operationTimeout(defaultMongoDBOpTimeout) + defer cancel() + if err := client.Ping(ctx, readpref.Primary()); err != nil { + log.Warnf("MongoDB ping failed: %s", err) + return err + } + return nil +} + +func storeFPCRecords(records FPCRecords, db *mongo.Database) error { + data := make([]interface{}, len(records)) + for i := range records { + data[i] = records[i] + } + ctx, cancel := operationTimeout(defaultMongoDBOpTimeout) + defer cancel() + _, err := db.Collection("FPC").InsertMany(ctx, data) + return err +} + +func operationTimeout(timeout time.Duration) (context.Context, context.CancelFunc) { + return context.WithTimeout(context.Background(), timeout) +} diff --git a/plugins/spa/frontend/.gitignore b/plugins/analysis/dashboard/frontend/.gitignore similarity index 100% rename from plugins/spa/frontend/.gitignore rename to plugins/analysis/dashboard/frontend/.gitignore diff --git a/plugins/spa/frontend/.prettierrc b/plugins/analysis/dashboard/frontend/.prettierrc similarity index 100% rename from plugins/spa/frontend/.prettierrc rename to plugins/analysis/dashboard/frontend/.prettierrc diff --git a/plugins/analysis/dashboard/frontend/.sass-lint.yml b/plugins/analysis/dashboard/frontend/.sass-lint.yml new file mode 100644 index 0000000000000000000000000000000000000000..17b8e1f11272651b1beac018af993f2704198051 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/.sass-lint.yml @@ -0,0 +1,33 @@ +options: + merge-default-rules: true + formatter: stylish +rules: + class-name-format: + - 1 + - + convention: hyphenatedbem + hex-length: + - 1 + - + style: long + leading-zero: 0 + no-color-literals: 0 + property-sort-order: + - 1 + - + order: smacss + no-important: 0 + mixins-before-declarations: 0 + mixin-name-format: + - 1 + - + allow-leading-underscore: false + convention: hyphenatedlowercase + shorthand-values: 0 + zero-unit: 0 + no-url-domains: 0 + no-url-protocols: 0 + nesting-depth: + - 1 + - + max-depth: 5 diff --git a/plugins/analysis/dashboard/frontend/README.md b/plugins/analysis/dashboard/frontend/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b60c22747e88cae7ed19b1a731e2c0c5d3c3f3f2 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/README.md @@ -0,0 +1,24 @@ +# GoShimmer Analysis Dashboard + +Programmed using modern web technologies. + +### Dashboard in dev mode + +1. Make sure to set `analysis.dashboard.dev` to true, to enable GoShimmer to serve assets + from the webpack-dev-server. +2. Install all needed npm modules via `yarn install`. +3. Run a webpack-dev-server instance by running `yarn start` within the `frontend` directory. +4. Using default port config, you should now be able to access the analysis dashboard under http://127.0.0.1:8000 + +The Analysis Dashboard is hot-reload enabled. + +### Pack your changes + +We are using [packr2](https://github.com/gobuffalo/packr/tree/master/v2) to wrap all built frontend files into Go files. + +1. [Install `packr2`](https://github.com/gobuffalo/packr/tree/master/v2#binary-installation) if not already done. +2. Build Analysis Dashboard by running `yarn build` within the `frontend` directory. +3. Change to the `plugins/analysis/dashboard` directory. +4. Run `packr2`. +5. `plugins/analysis/dashboard/packrd` should have been modified. +6. Done. Now you can build goShimmer and your Analysis Dashboard changes will be included within the binary. diff --git a/plugins/analysis/dashboard/frontend/package-lock.json b/plugins/analysis/dashboard/frontend/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..2d4443eb089629bdb756d175baa9bb8ea6cd4faa --- /dev/null +++ b/plugins/analysis/dashboard/frontend/package-lock.json @@ -0,0 +1,9742 @@ +{ + "name": "goshimmer-analysis-dashboard", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz", + "integrity": "sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.3" + } + }, + "@babel/core": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.3.tgz", + "integrity": "sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.3", + "@babel/generator": "^7.10.3", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helpers": "^7.10.1", + "@babel/parser": "^7.10.3", + "@babel/template": "^7.10.3", + "@babel/traverse": "^7.10.3", + "@babel/types": "^7.10.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.3.tgz", + "integrity": "sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz", + "integrity": "sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.3", + "@babel/template": "^7.10.3", + "@babel/types": "^7.10.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz", + "integrity": "sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz", + "integrity": "sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz", + "integrity": "sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w==", + "dev": true, + "requires": { + "@babel/types": "^7.10.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz", + "integrity": "sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz", + "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.3.tgz", + "integrity": "sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.3", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.3.tgz", + "integrity": "sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA==", + "dev": true + }, + "@babel/runtime": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", + "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.3.tgz", + "integrity": "sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.3", + "@babel/parser": "^7.10.3", + "@babel/types": "^7.10.3" + } + }, + "@babel/traverse": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.3.tgz", + "integrity": "sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.3", + "@babel/generator": "^7.10.3", + "@babel/helper-function-name": "^7.10.3", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.3", + "@babel/types": "^7.10.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz", + "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.3", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@types/anymatch": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", + "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", + "dev": true + }, + "@types/classnames": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.10.tgz", + "integrity": "sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==", + "dev": true + }, + "@types/glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/history": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.6.tgz", + "integrity": "sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w==", + "dev": true + }, + "@types/html-minifier-terser": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz", + "integrity": "sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "14.0.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", + "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/react": { + "version": "16.9.41", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.41.tgz", + "integrity": "sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/react-dom": { + "version": "16.9.8", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz", + "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-router": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.8.tgz", + "integrity": "sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg==", + "dev": true, + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "@types/tapable": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz", + "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", + "dev": true + }, + "@types/uglify-js": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.2.tgz", + "integrity": "sha512-d6dIfpPbF+8B7WiCi2ELY7m0w1joD8cRW4ms88Emdb2w062NeEpbNCeWwVCgzLRpVG+5e74VFSg4rgJ2xXjEiQ==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/webpack": { + "version": "4.41.17", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.17.tgz", + "integrity": "sha512-6FfeCidTSHozwKI67gIVQQ5Mp0g4X96c2IXxX75hYEQJwST/i6NyZexP//zzMOBb+wG9jJ7oO8fk9yObP2HWAw==", + "dev": true, + "requires": { + "@types/anymatch": "*", + "@types/node": "*", + "@types/tapable": "*", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/webpack-sources": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.0.tgz", + "integrity": "sha512-c88dKrpSle9BtTqR6ifdaxu1Lvjsl3C5OsfvuUbUwdXymshv1TkufUAXBajCCUM/f/TmnkZC/Esb03MinzSiXQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "add-event-listener": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/add-event-listener/-/add-event-listener-0.0.1.tgz", + "integrity": "sha1-p2Ip68ZMiu+uIEoWJzovJVq+otA=" + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.0.tgz", + "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "browserify-sign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", + "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.2", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camel-case": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", + "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", + "dev": true, + "requires": { + "pascal-case": "^3.1.1", + "tslib": "^1.10.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + } + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "csstype": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", + "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==" + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-helpers": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz", + "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^2.6.7" + } + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + }, + "domhandler": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.0.0.tgz", + "integrity": "sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1" + } + }, + "domutils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.1.0.tgz", + "integrity": "sha512-CD9M0Dm1iaHfQ1R/TI+z3/JWp/pgub0j4jIQKH89ARR4ATAV2nbaOQS5XxU9maJP5jHaPdDDQSEHuE2UmpUTKg==", + "dev": true, + "requires": { + "dom-serializer": "^0.2.1", + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0" + } + }, + "dot-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz", + "integrity": "sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz", + "integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-2.13.1.tgz", + "integrity": "sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "concat-stream": "^1.4.6", + "debug": "^2.1.1", + "doctrine": "^1.2.2", + "es6-map": "^0.1.3", + "escope": "^3.6.0", + "espree": "^3.1.6", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^1.1.1", + "glob": "^7.0.3", + "globals": "^9.2.0", + "ignore": "^3.1.2", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "optionator": "^0.8.1", + "path-is-absolute": "^1.0.0", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.6.0", + "strip-json-comments": "~1.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "file-entry-cache": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-1.3.1.tgz", + "integrity": "sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "file-loader": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz", + "integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "follow-redirects": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz", + "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "front-matter": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-2.1.2.tgz", + "integrity": "sha1-91mDufL0E75ljJPf172M5AePXNs=", + "dev": true, + "requires": { + "js-yaml": "^3.4.6" + } + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "^1.0.0" + } + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "gintersect": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/gintersect/-/gintersect-0.1.0.tgz", + "integrity": "sha1-moy2qAt9bpVawzUVSVsSEmJ7GBY=" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "gonzales-pe-sl": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz", + "integrity": "sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=", + "dev": true, + "requires": { + "minimist": "1.1.x" + }, + "dependencies": { + "minimist": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz", + "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "html-entities": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "dev": true + }, + "html-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-1.1.0.tgz", + "integrity": "sha512-zwLbEgy+i7sgIYTlxI9M7jwkn29IvdsV6f1y7a2aLv/w8l1RigVk0PFijBZLLFsdi2gvL8sf2VJhTjLlfnK8sA==", + "dev": true, + "requires": { + "html-minifier-terser": "^5.0.5", + "htmlparser2": "^4.1.0", + "loader-utils": "^2.0.0", + "parse-srcset": "^1.0.2", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "dev": true, + "requires": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + } + }, + "html-webpack-plugin": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.3.0.tgz", + "integrity": "sha512-C0fzKN8yQoVLTelcJxZfJCE+aAvQiY2VUf3UuKrR4a9k5UMWYOtpDLsaXwATbcVCnI05hUS7L9ULQHWLZhyi3w==", + "dev": true, + "requires": { + "@types/html-minifier-terser": "^5.0.0", + "@types/tapable": "^1.0.5", + "@types/webpack": "^4.41.8", + "html-minifier-terser": "^5.0.1", + "loader-utils": "^1.2.3", + "lodash": "^4.17.15", + "pretty-error": "^2.1.1", + "tapable": "^1.1.3", + "util.promisify": "1.0.0" + } + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "in-publish": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + } + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "is-my-json-valid": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz", + "integrity": "sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==", + "dev": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-base64": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.1.tgz", + "integrity": "sha512-G5x2saUTupU9D/xBY9snJs3TxvwX8EkpLFiYlPpDt/VmMHOXprnSU1nxiTmFbijCX4BLF/cMRIfAcC5BiMYgFQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "known-css-properties": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.3.0.tgz", + "integrity": "sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=", + "dev": true + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "dev": true + }, + "loglevel": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", + "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lower-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", + "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, + "mini-create-react-context": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz", + "integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==", + "requires": { + "@babel/runtime": "^7.5.5", + "tiny-warning": "^1.0.3" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mobx": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.4.tgz", + "integrity": "sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw==" + }, + "mobx-react": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-6.2.2.tgz", + "integrity": "sha512-Us6V4ng/iKIRJ8pWxdbdysC6bnS53ZKLKlVGBqzHx6J+gYPYbOotWvhHZnzh/W5mhpYXxlXif4kL2cxoWJOplQ==", + "requires": { + "mobx-react-lite": "2" + } + }, + "mobx-react-lite": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-2.0.7.tgz", + "integrity": "sha512-YKAh2gThC6WooPnVZCoC+rV1bODAKFwkhxikzgH18wpBjkgTkkR9Sb0IesQAH5QrAEH/JQVmy47jcpQkf2Au3Q==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "ngraph.centrality": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ngraph.centrality/-/ngraph.centrality-0.3.0.tgz", + "integrity": "sha1-jMDsAxnvCjdDV/wQRMFpdbF50J0=" + }, + "ngraph.events": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-0.0.3.tgz", + "integrity": "sha1-OPVTFvPSB61jH/lPZiLKjywOh9A=" + }, + "ngraph.expose": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/ngraph.expose/-/ngraph.expose-0.0.0.tgz", + "integrity": "sha1-dGw0kDo4SMRdAzsUvGRhnqhf5ao=" + }, + "ngraph.forcelayout": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ngraph.forcelayout/-/ngraph.forcelayout-0.5.0.tgz", + "integrity": "sha1-UVEcPh20XT1UNtp137HWrwl5FvU=", + "requires": { + "ngraph.events": "0.0.4", + "ngraph.physics.simulator": "^0.3.0" + }, + "dependencies": { + "ngraph.events": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-0.0.4.tgz", + "integrity": "sha1-css2RIjdD9fwV0WESfajsXpyLZo=" + } + } + }, + "ngraph.fromjson": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/ngraph.fromjson/-/ngraph.fromjson-0.1.9.tgz", + "integrity": "sha1-ZpELZkxp+jxQoc553R391bq0b24=", + "requires": { + "ngraph.graph": "0.0.14" + } + }, + "ngraph.generators": { + "version": "0.0.19", + "resolved": "https://registry.npmjs.org/ngraph.generators/-/ngraph.generators-0.0.19.tgz", + "integrity": "sha1-VSwNCH+UK50NKwxsqarENr76dlk=", + "requires": { + "ngraph.graph": "0.0.14", + "ngraph.random": "0.1.0" + }, + "dependencies": { + "ngraph.random": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ngraph.random/-/ngraph.random-0.1.0.tgz", + "integrity": "sha1-G26Vc1KeCAZ32m/6CYeQ12oJSKk=" + } + } + }, + "ngraph.graph": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-0.0.14.tgz", + "integrity": "sha1-1HrJSWfJIKr3aVLYpOczRuHfLbc=", + "requires": { + "ngraph.events": "0.0.3" + } + }, + "ngraph.merge": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/ngraph.merge/-/ngraph.merge-0.0.1.tgz", + "integrity": "sha1-5OgM43WBo8lrF9VF46Q8hUNLkCU=" + }, + "ngraph.physics.primitives": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ngraph.physics.primitives/-/ngraph.physics.primitives-0.0.7.tgz", + "integrity": "sha1-Xcnhebofkubex3SwHNaJFBILeVs=" + }, + "ngraph.physics.simulator": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ngraph.physics.simulator/-/ngraph.physics.simulator-0.3.0.tgz", + "integrity": "sha1-fKb8PjYXxz4QgFcuqo4E27d+AQI=", + "requires": { + "ngraph.events": "0.0.3", + "ngraph.expose": "0.0.0", + "ngraph.merge": "0.0.1", + "ngraph.physics.primitives": "0.0.7", + "ngraph.quadtreebh": "0.0.4", + "ngraph.random": "0.0.1" + } + }, + "ngraph.quadtreebh": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/ngraph.quadtreebh/-/ngraph.quadtreebh-0.0.4.tgz", + "integrity": "sha1-xwDUTm5K8HttBQAbo5h/9eLc1iw=", + "requires": { + "ngraph.random": "0.0.1" + } + }, + "ngraph.random": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/ngraph.random/-/ngraph.random-0.0.1.tgz", + "integrity": "sha1-wAji67/f+vF+0Q5LvJE+VnFmvPg=" + }, + "ngraph.tojson": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/ngraph.tojson/-/ngraph.tojson-0.1.4.tgz", + "integrity": "sha1-OfAEZYhECt5iLVhzTVideXSgs7w=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "no-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.3.tgz", + "integrity": "sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==", + "dev": true, + "requires": { + "lower-case": "^2.0.1", + "tslib": "^1.10.0" + } + }, + "node-forge": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "dev": true + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "dev": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + } + } + }, + "node-sass": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", + "dev": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "param-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.3.tgz", + "integrity": "sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA==", + "dev": true, + "requires": { + "dot-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascal-case": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz", + "integrity": "sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "portfinder": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", + "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", + "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", + "dev": true, + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.16", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.0" + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + } + }, + "postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "requires": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "dev": true, + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + } + } + }, + "react": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", + "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "react-hot-loader": { + "version": "4.12.21", + "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.12.21.tgz", + "integrity": "sha512-Ynxa6ROfWUeKWsTHxsrL2KMzujxJVPjs385lmB2t5cHUxdoRPGind9F00tOkdc1l5WBleOF4XEAMILY1KPIIDA==", + "dev": true, + "requires": { + "fast-levenshtein": "^2.0.6", + "global": "^4.3.0", + "hoist-non-react-statics": "^3.3.0", + "loader-utils": "^1.1.0", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.1.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "react-icons": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.10.0.tgz", + "integrity": "sha512-WsQ5n1JToG9VixWilSo1bHv842Cj5aZqTGiS3Ud47myF6aK7S/IUY2+dHcBdmkQcCFRuHsJ9OMUI0kTDfjyZXQ==", + "requires": { + "camelcase": "^5.0.0" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "dev": true + }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "recursive-readdir-sync": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz", + "integrity": "sha1-Hb9tMvPFu4083pemxYjVR6nhPVY=", + "dev": true + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "renderkid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", + "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "dev": true, + "requires": { + "css-select": "^1.1.0", + "dom-converter": "^0.2", + "htmlparser2": "^3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + } + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "^1.3.0" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass": { + "version": "1.26.9", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.9.tgz", + "integrity": "sha512-t8AkRVi+xvba4yZiLWkJdgJHBFCB3Dh4johniQkPy9ywkgFHNasXFEFP+RG/F6LhQ+aoE4aX+IorIWQjS0esVw==", + "dev": true, + "requires": { + "chokidar": ">=2.0.0 <4.0.0" + } + }, + "sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + } + }, + "sass-lint": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sass-lint/-/sass-lint-1.13.1.tgz", + "integrity": "sha512-DSyah8/MyjzW2BWYmQWekYEKir44BpLqrCFsgs9iaWiVTcwZfwXHF586hh3D1n+/9ihUNMfd8iHAyb9KkGgs7Q==", + "dev": true, + "requires": { + "commander": "^2.8.1", + "eslint": "^2.7.0", + "front-matter": "2.1.2", + "fs-extra": "^3.0.1", + "glob": "^7.0.0", + "globule": "^1.0.0", + "gonzales-pe-sl": "^4.2.3", + "js-yaml": "^3.5.4", + "known-css-properties": "^0.3.0", + "lodash.capitalize": "^4.1.0", + "lodash.kebabcase": "^4.0.0", + "merge": "^1.2.0", + "path-is-absolute": "^1.0.0", + "util": "^0.10.3" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selfsigned": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "dev": true, + "requires": { + "node-forge": "0.9.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shelljs": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz", + "integrity": "sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "simplesvg": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/simplesvg/-/simplesvg-0.0.10.tgz", + "integrity": "sha1-N9LsGN4sFU3Ztp956K0gvx4eX90=", + "requires": { + "add-event-listener": "0.0.1" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + } + }, + "sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + }, + "style-loader": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.2.1.tgz", + "integrity": "sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.6" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", + "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^3.1.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "dev": true, + "requires": { + "glob": "^7.1.2" + } + }, + "ts-loader": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", + "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-loader": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.0.tgz", + "integrity": "sha512-IzgAAIC8wRrg6NYkFIJY09vtktQcsvU8V6HhtQj9PTefbYImzLB1hufqo4m+RyM5N3mLx5BqJKccgxJS+W3kqw==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.26", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vivagraphjs": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/vivagraphjs/-/vivagraphjs-0.12.0.tgz", + "integrity": "sha512-Air+vUHXAWj8NTWUnbU800yKC7SiHpCVwpKIPfDtr5436YoMd7cpg8blt6Fn9xarx+sz1osRxGHBHTaHvcsR6Q==", + "requires": { + "gintersect": "0.1.0", + "ngraph.centrality": "0.3.0", + "ngraph.events": "0.0.3", + "ngraph.forcelayout": "0.5.0", + "ngraph.fromjson": "0.1.9", + "ngraph.generators": "0.0.19", + "ngraph.graph": "0.0.14", + "ngraph.merge": "0.0.1", + "ngraph.random": "0.0.1", + "ngraph.tojson": "0.1.4", + "simplesvg": "0.0.10" + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", + "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", + "dev": true, + "requires": { + "chokidar": "^3.4.0", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.1", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "webpack-cleanup-plugin": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/webpack-cleanup-plugin/-/webpack-cleanup-plugin-0.5.1.tgz", + "integrity": "sha1-3y1wa9dTZMBuZbBRGGMW1nTrlq8=", + "dev": true, + "requires": { + "lodash.union": "4.6.0", + "minimatch": "3.0.3", + "recursive-readdir-sync": "1.0.6" + }, + "dependencies": { + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "dev": true, + "requires": { + "brace-expansion": "^1.0.0" + } + } + } + }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "webpack-dev-server": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.20", + "sockjs-client": "1.4.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "webpack-hot-middleware": { + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz", + "integrity": "sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "html-entities": "^1.2.0", + "querystring": "^0.2.0", + "strip-ansi": "^3.0.0" + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true, + "requires": { + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/plugins/analysis/dashboard/frontend/package.json b/plugins/analysis/dashboard/frontend/package.json new file mode 100644 index 0000000000000000000000000000000000000000..2d0e812c7c05b49edae31ee9911f9dbd0eded528 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/package.json @@ -0,0 +1,55 @@ +{ + "name": "goshimmer-analysis-dashboard", + "version": "1.0.0", + "private": true, + "description": "GoShimmer Analysis Dashboard", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "webpack-dev-server --mode development --hot --progress --colors --host 192.168.1.215 --port 9090 --open", + "build": "webpack -p --progress --colors", + "prettier": "prettier --write \"src/**/*.{ts,tsx,css}\"" + }, + "license": "MIT", + "devDependencies": { + "@babel/core": "^7.2.2", + "@types/classnames": "^2.2.7", + "@types/glob": "^7.1.1", + "@types/react": "^16.7.20", + "@types/react-dom": "^16.0.11", + "@types/react-router": "^5.1.7", + "@types/webpack": "^4.4.23", + "babel-loader": "^8.0.5", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-loader": "^1.0.0-alpha.0", + "html-webpack-plugin": "^4.3.0", + "node-sass": "^4.14.1", + "prettier": "^2.0.5", + "react-hot-loader": "^4.12.21", + "sass": "^1.26.8", + "sass-lint": "^1.13.1", + "sass-loader": "^8.0.2", + "style-loader": "^1.2.1", + "ts-loader": "^7.0.5", + "typescript": "^3.2.4", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cleanup-plugin": "^0.5.1", + "webpack-cli": "^3.3.11", + "webpack-dev-server": "^3.1.14", + "webpack-hot-middleware": "^2.25.0" + }, + "dependencies": { + "classnames": "^2.2.6", + "mobx": "^5.15.0", + "mobx-react": "^6.2.2", + "react": "^16.7.0", + "react-dom": "^16.7.0", + "react-icons": "^3.10.0", + "react-router": "5.2.0", + "react-router-dom": "5.2.0", + "react-transition-group": "^4.4.1", + "vivagraphjs": "^0.12.0" + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/App.scss b/plugins/analysis/dashboard/frontend/src/app/App.scss new file mode 100644 index 0000000000000000000000000000000000000000..b22c27ba9b691b5092713ba1a6e91f0356969f1a --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/App.scss @@ -0,0 +1,94 @@ +@import '../sass/colors'; +@import '../sass/fonts'; +@import '../sass/mixins'; +@import '../sass/media-queries'; + +.root { + header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 20px; + background-color: $dark-gray; + + @include tablet-down { + flex-direction: column; + align-items: flex-start; + } + + .brand { + display: flex; + flex-direction: row; + align-items: center; + margin-right: 20px; + padding: 4px; + outline: none; + text-decoration: none; + + &:focus { + box-shadow: 0 0 3px 0 $light-green; + } + + img { + height: 48px; + } + + h1 { + @include font-size(32px); + + color: $white; + font-family: $metropolis; + white-space: nowrap; + } + } + + nav { + display: flex; + flex-direction: row; + align-items: center; + + @include tablet-down { + margin: 20px 0px; + } + + a { + @include font-size(16px); + padding: 8px; + border-radius: 6px; + outline: none; + color: $light-green; + font-family: $metropolis; + font-weight: bold; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &:focus { + box-shadow: 0 0 3px 0 $light-green; + } + } + + a + a { + margin-left: 20px; + } + } + + .badge { + @include font-size(12px); + + margin-left: 20px; + padding: 6px; + border-radius: 6px; + background-color: $danger; + color: $white; + font-family: $metropolis; + font-weight: bold; + + @include tablet-down { + margin: 0px; + } + } + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/App.tsx b/plugins/analysis/dashboard/frontend/src/app/App.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e376d211d878e6f3474ba828967d7b583910ceae --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/App.tsx @@ -0,0 +1,52 @@ +import Autopeering from "app/components/Autopeering/Autopeering"; +import Conflict from "app/components/FPC/Conflict"; +import FPC from "app/components/FPC/FPC"; +import { inject, observer } from "mobx-react"; +import * as React from 'react'; +import { Link, Redirect, Route, Switch } from "react-router-dom"; +import "./App.scss"; +import { AppProps } from './AppProps'; +import { withRouter } from "react-router"; + +@inject("autopeeringStore") +@observer +class App extends React.Component<AppProps, any> { + componentDidMount(): void { + this.props.autopeeringStore.connect(); + } + + render() { + return ( + <div className="root"> + <header> + <Link className="brand" to="/"> + <img src="/assets/logo-header.svg" alt="GoShimmer Analyser" /> + <h1>GoShimmer Analyzer</h1> + </Link> + <nav> + <Link to="/autopeering"> + Autopeering + </Link> + <Link to="/consensus"> + Consensus + </Link> + </nav> + <div className="badge-container"> + {!this.props.autopeeringStore.websocketConnected && + <div className="badge">Not connected</div> + } + </div> + </header> + <Switch> + <Route path="/autopeering" component={Autopeering} /> + <Route exact path="/consensus" component={FPC} /> + <Route path="/consensus/conflict/:id" component={Conflict} /> + <Redirect to="/autopeering" /> + </Switch> + {this.props.children} + </div> + ); + } +} + +export default withRouter(App); \ No newline at end of file diff --git a/plugins/analysis/dashboard/frontend/src/app/AppProps.tsx b/plugins/analysis/dashboard/frontend/src/app/AppProps.tsx new file mode 100644 index 0000000000000000000000000000000000000000..9bdf07f32a0c522d94a364361d63277060810ed2 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/AppProps.tsx @@ -0,0 +1,6 @@ +import AutopeeringStore from "app/stores/AutopeeringStore"; +import { RouteComponentProps } from "react-router"; + +export interface AppProps extends RouteComponentProps { + autopeeringStore?: AutopeeringStore; +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/Autopeering.scss b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/Autopeering.scss new file mode 100644 index 0000000000000000000000000000000000000000..956186544e50f711c0d3bb67d6b0361ec4f8b485 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/Autopeering.scss @@ -0,0 +1,101 @@ +@import '../../../sass/colors'; +@import '../../../sass/fonts'; +@import '../../../sass/mixins'; +@import '../../../sass/media-queries'; + +.auto-peering { + margin: 40px; + + .header { + display: flex; + flex-direction: row; + justify-content: space-between; + + @include tablet-down { + flex-direction: column; + } + + .badge { + @include font-size(14px); + + display: flex; + align-items: center; + justify-content: center; + margin-left: 10px; + padding: 8px; + border-radius: 6px; + font-family: $inter; + text-align: center; + + @include tablet-down { + margin-top: 10px; + margin-right: 10px; + margin-left: 0px; + } + + + &.online { + background-color: $dark-green; + color: $white; + } + + &.neighbors { + background-color: $gray-5; + color: $white; + } + } + } + + .nodes-container { + display: flex; + flex-direction: row; + + @include tablet-down { + flex-direction: column; + } + + + .nodes { + flex: 1; + + .node-list { + height: 140px; + padding: 2px; + overflow: auto; + + button { + width: 100px; + + &.selected { + background: $main-green; + color: $white; + } + } + } + } + + .node-view-container { + display: flex; + flex: 1; + max-height: 240px; + margin-left: 20px; + overflow: hidden; + + @include tablet-down { + margin-top: 20px; + margin-left: 0px; + } + } + } + + .visualizer { + top: 0; + left: 0; + width: 100%; + height: 30vw; + border-radius: 20px; + background: $dark-gray; + overflow: hidden; + z-index: -1; + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/Autopeering.tsx b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/Autopeering.tsx new file mode 100644 index 0000000000000000000000000000000000000000..58e3bf6a769137ab5fe2ebba01bfaaa7528b6c6c --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/Autopeering.tsx @@ -0,0 +1,87 @@ +import { shortenedIDCharCount } from "app/stores/AutopeeringStore"; +import classNames from "classnames"; +import { inject, observer } from "mobx-react"; +import * as React from 'react'; +import "./Autopeering.scss"; +import { AutopeeringProps } from './AutopeeringProps'; +import { NodeView } from "./NodeView"; + +@inject("autopeeringStore") +@observer +export default class Autopeering extends React.Component<AutopeeringProps, any> { + + componentDidMount(): void { + this.props.autopeeringStore.start(); + } + + componentWillUnmount(): void { + this.props.autopeeringStore.stop(); + } + + render() { + let { nodeListView, search } = this.props.autopeeringStore + return ( + <div className="auto-peering"> + <div className="header margin-b-m"> + <h2>Autopeering Visualizer</h2> + <div className="row"> + <div className="badge neighbors"> + Average number of neighbors: { + this.props.autopeeringStore.nodes && this.props.autopeeringStore.nodes.size > 0 ? + (2 * this.props.autopeeringStore.connections.size / this.props.autopeeringStore.nodes.size).toPrecision(2).toString() + : 0 + } + </div> + <div className="badge online"> + Nodes online: {this.props.autopeeringStore.nodes.size.toString()} + </div> + </div> + </div> + <div className="nodes-container margin-b-s"> + <div className="card nodes"> + <div className="row middle margin-b-s"> + <label> + Search Node + </label> + <input + placeholder="Enter a node id" + type="text" + value={search} + onChange={(e) => this.props.autopeeringStore.updateSearch(e.target.value)} + /> + </div> + <div className="node-list"> + {nodeListView.length === 0 && search.length > 0 && ( + <p>There are no nodes to view with the current search parameters.</p> + )} + {nodeListView.map((nodeId) => ( + <button + key={nodeId} + onClick={() => this.props.autopeeringStore.handleNodeSelection(nodeId)} + className={classNames( + { + selected: this.props.autopeeringStore.selectedNode === nodeId + } + )} + > + {nodeId.substr(0, shortenedIDCharCount)} + </button> + ))} + </div> + </div> + <div className="node-view-container"> + {!this.props.autopeeringStore.selectedNode && ( + <div className="card"> + <p className="margin-t-t">Select a node to inspect its details.</p> + </div> + )} + {this.props.autopeeringStore.selectedNode && ( + <NodeView {...this.props} /> + )} + </div> + </div> + <div className="visualizer" id="visualizer" /> + </div> + ); + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/AutopeeringProps.ts b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/AutopeeringProps.ts new file mode 100644 index 0000000000000000000000000000000000000000..36b65d4baad2a533e7a317672492a239c906f00a --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/AutopeeringProps.ts @@ -0,0 +1,5 @@ +import AutopeeringStore from "app/stores/AutopeeringStore"; + +export interface AutopeeringProps { + autopeeringStore?: AutopeeringStore +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/NodeView.scss b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/NodeView.scss new file mode 100644 index 0000000000000000000000000000000000000000..4d7e0e7bb941f44c9ce953b799f2df42be3333bc --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/NodeView.scss @@ -0,0 +1,49 @@ +@import '../../../sass/colors'; +@import '../../../sass/fonts'; +@import '../../../sass/mixins'; +@import '../../../sass/media-queries'; + +.node-view { + h3 { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + + .col + .col { + margin-left: 10px; + } + + .badge { + @include font-size(12px); + + margin-left: 10px; + padding: 6px 10px; + border-radius: 6px; + background-color: $dark-green; + color: $white; + font-weight: normal; + } + + .node-view--list { + display: flex; + flex-wrap: wrap; + max-height: 112px; + padding: 2px; + overflow: auto; + + button { + width: 100px; + + &.preview-incoming { + background-color: #1c8d7f; + color: $white; + } + + &.preview-outgoing { + background-color: #336db5; + color: $white; + } + } + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/NodeView.tsx b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/NodeView.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5282b7e94c90f3e466d0ed8843d59d030fb5ab51 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering/NodeView.tsx @@ -0,0 +1,67 @@ +import classNames from "classnames"; +import { shortenedIDCharCount } from "app/stores/AutopeeringStore"; +import { inject, observer } from "mobx-react"; +import * as React from 'react'; +import "./NodeView.scss"; +import { AutopeeringProps } from './AutopeeringProps'; + +@inject("autopeeringStore") +@observer +export class NodeView extends React.Component<AutopeeringProps, any> { + render() { + return ( + <div className="card node-view"> + <div className="card--header"> + <h3> + Node {this.props.autopeeringStore.selectedNode} + </h3> + </div> + <div className="row margin-t-s"> + <div className="col"> + <label className="margin-b-t"> + Incoming + <span className="badge">{this.props.autopeeringStore.selectedNodeInNeighbors.size.toString()}</span> + </label> + <div className="node-view--list"> + {this.props.autopeeringStore.inNeighborList.map(nodeId => ( + <button + key={nodeId} + onClick={() => this.props.autopeeringStore.handleNodeSelection(nodeId)} + className={classNames( + { + "preview-incoming": nodeId === this.props.autopeeringStore.previewNode + } + )} + > + {nodeId.substr(0, shortenedIDCharCount)} + </button> + ))} + </div> + </div> + + <div className="col"> + <label className="margin-b-t"> + Outgoing + <span className="badge">{this.props.autopeeringStore.selectedNodeOutNeighbors.size.toString()}</span> + </label> + <div className="node-view--list"> + {this.props.autopeeringStore.outNeighborList.map(nodeId => ( + <button + key={nodeId} + onClick={() => this.props.autopeeringStore.handleNodeSelection(nodeId)} + className={classNames( + { + "preview-outgoing": nodeId === this.props.autopeeringStore.previewNode + } + )} + > + {nodeId.substr(0, shortenedIDCharCount)} + </button> + ))} + </div> + </div> + </div> + </div> + ); + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/Conflict.scss b/plugins/analysis/dashboard/frontend/src/app/components/FPC/Conflict.scss new file mode 100644 index 0000000000000000000000000000000000000000..8363d1e0b10a316245954476446a0846e2fddfed --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/Conflict.scss @@ -0,0 +1,41 @@ +@import '../../../sass/colors'; +@import '../../../sass/fonts'; +@import '../../../sass/mixins'; +@import '../../../sass/media-queries'; + +.conflict { + margin: 40px; + + .header { + display: flex; + flex-direction: row; + justify-content: space-between; + + @include tablet-down { + flex-direction: column; + } + } + + .node-grid { + display: flex; + flex-direction: column; + + .node-details { + @include font-size(16px); + + &.like { + border-right: 4px solid $success; + border-left: 4px solid $success; + } + + &.dislike { + border-right: 4px solid $danger; + border-left: 4px solid $danger; + } + } + + .node-details + .node-details { + margin-top: 10px; + } + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/Conflict.tsx b/plugins/analysis/dashboard/frontend/src/app/components/FPC/Conflict.tsx new file mode 100644 index 0000000000000000000000000000000000000000..62a13b7668d808860a31e3070141737ec865115f --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/Conflict.tsx @@ -0,0 +1,54 @@ +import classNames from "classnames"; +import { inject, observer } from "mobx-react"; +import * as React from 'react'; +import "./Conflict.scss"; +import { FPCProps } from './FPCProps'; + +@inject("fpcStore") +@observer +export default class Conflict extends React.Component<FPCProps, any> { + componentDidMount() { + this.props.fpcStore.updateCurrentConflict(this.props.match.params.id); + } + + render() { + let { nodeConflictGrid } = this.props.fpcStore; + + return ( + <div className="conflict"> + <div className="header margin-b-m"> + <h2>Conflict Detail</h2> + </div> + <div className="card margin-b-m"> + <div className="details row middle"> + <label>Conflict ID</label> + <span className="value">{this.props.match.params.id}</span> + </div> + </div> + <div className="node-grid"> + {!nodeConflictGrid && ( + <div className="card"> + <p>The node data for this conflict is no longer available.</p> + </div> + )} + {nodeConflictGrid && nodeConflictGrid.map(nodeDetails => ( + <div + key={nodeDetails.nodeID} + className={classNames( + "card", + "node-details", + { like: nodeDetails.opinion === 1 }, + { dislike: nodeDetails.opinion === 2 } + )} + > + <div className="details row middle"> + <label>Node ID</label> + <span className="value">{nodeDetails.nodeID}</span> + </div> + </div> + ))} + </div> + </div> + ); + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPC.scss b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPC.scss new file mode 100644 index 0000000000000000000000000000000000000000..194ef030b042211021c0142a99ad961226bc0f4b --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPC.scss @@ -0,0 +1,24 @@ +@import '../../../sass/colors'; +@import '../../../sass/fonts'; +@import '../../../sass/mixins'; +@import '../../../sass/media-queries'; + +.fpc { + margin: 40px; + + .header { + display: flex; + flex-direction: row; + justify-content: space-between; + + @include tablet-down { + flex-direction: column; + } + } + + .conflict-grid { + display: flex; + flex-direction: row; + flex-wrap: wrap; + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPC.tsx b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPC.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5ef3a48d845cac97c69d7ff2df07e4eee74a4911 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPC.tsx @@ -0,0 +1,47 @@ +import { inject, observer } from "mobx-react"; +import * as React from 'react'; +import { CSSTransition, TransitionGroup } from 'react-transition-group'; +import "./FPC.scss"; +import FPCItem from "./FPCItem"; +import { FPCProps } from './FPCProps'; + +@inject("fpcStore") +@observer +export default class FPC extends React.Component<FPCProps, any> { + componentDidMount(): void { + this.props.fpcStore.start(); + } + + componentWillUnmount(): void { + this.props.fpcStore.stop(); + } + + render() { + let { conflictGrid } = this.props.fpcStore; + return ( + <div className="fpc"> + <div className="header margin-b-m"> + <h2>Conflicts Overview</h2> + </div> + <div className="conflict-grid"> + {conflictGrid.length === 0 && ( + <p>There are no conflicts to show.</p> + )} + <TransitionGroup> + {conflictGrid.map(conflict => ( + <CSSTransition + className="fpc-item" + key={conflict.conflictID} + timeout={300} + > + <FPCItem + {...conflict} + /> + </CSSTransition> + ))} + </TransitionGroup> + </div> + </div> + ); + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItem.scss b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItem.scss new file mode 100644 index 0000000000000000000000000000000000000000..81ad83f1c9d2eebbd73c98649e7aa10e9bd15ff2 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItem.scss @@ -0,0 +1,59 @@ +@import '../../../sass/colors'; +@import '../../../sass/fonts'; +@import '../../../sass/mixins'; +@import '../../../sass/media-queries'; + +.fpc-item { + @include font-size(16px); + + display: inline-flex; + position: relative; + align-items: center; + width: 200px; + height: 30px; + margin: 5px; + border: 1px solid $gray-4; + border-radius: 15px; + background-color: $gray-4; + color: $dark-gray; + font-family: $inter; + text-decoration: none; + overflow: hidden; + + &.enter { + opacity: 0; + } + + &.enter-active { + transition: opacity 300ms ease-in; + opacity: 1; + } + + &.exit { + opacity: 1; + } + + &.exit-active { + transition: opacity 300ms ease-out; + opacity: 0; + } + + .percentage { + position: absolute; + top: -1px; + left: -1px; + height: 30px; + transition: width 1s ease-in-out; + border-radius: 15px; + background-color: $main-green; + z-index: 1; + } + + .label { + display: flex; + justify-content: center; + width: 100%; + color: $white; + z-index: 2; + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItem.tsx b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItem.tsx new file mode 100644 index 0000000000000000000000000000000000000000..82e887fabcf4f7cee56ead41ac028c7d020208dc --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItem.tsx @@ -0,0 +1,30 @@ +import { shortenedIDCharCount } from "app/stores/AutopeeringStore"; +import { inject, observer } from "mobx-react"; +import * as React from 'react'; +import { Link } from 'react-router-dom'; +import "./FPCItem.scss"; +import { FPCItemProps } from './FPCItemProps'; + +@inject("fpcStore") +@observer +export default class FPCItem extends React.Component<FPCItemProps, any> { + render() { + const total = Object.keys(this.props.nodeOpinions).length; + return ( + <Link + to={`/consensus/conflict/${this.props.conflictID}`} + className="fpc-item" + > + <div + className="percentage" + style={{ + width: `${Math.floor((this.props.likes / total) * 200)}px` + }} + /> + <div className="label"> + {`${this.props.conflictID.substr(0, shortenedIDCharCount)}: ${this.props.likes} / ${total}`} + </div> + </Link> + ); + } +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItemProps.tsx b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItemProps.tsx new file mode 100644 index 0000000000000000000000000000000000000000..97d652507ba3729f77902ebf699c034cf37e25e2 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCItemProps.tsx @@ -0,0 +1,8 @@ +import FPCStore from "app/stores/FPCStore"; + +export interface FPCItemProps { + fpcStore?: FPCStore; + conflictID: string; + likes?: number; + nodeOpinions: { nodeID: string; opinion: number }[]; +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCProps.tsx b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCProps.tsx new file mode 100644 index 0000000000000000000000000000000000000000..abbb163463212d6a3e031e0295c8c123bdec7912 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/components/FPC/FPCProps.tsx @@ -0,0 +1,8 @@ +import FPCStore from "app/stores/FPCStore"; +import { RouteComponentProps } from "react-router"; + +export interface FPCProps extends RouteComponentProps<{ + id?: string; +}> { + fpcStore?: FPCStore; +} diff --git a/plugins/analysis/dashboard/frontend/src/app/components/Root/Root.tsx b/plugins/analysis/dashboard/frontend/src/app/components/Root/Root.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/plugins/analysis/dashboard/frontend/src/app/misc/WS.ts b/plugins/analysis/dashboard/frontend/src/app/misc/WS.ts new file mode 100644 index 0000000000000000000000000000000000000000..72acf888ee82879820d1e6d8c351278c3218489d --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/misc/WS.ts @@ -0,0 +1,53 @@ +export enum WSMsgType { + Ping, + FPC, + AddNode, + RemoveNode, + ConnectNodes, + DisconnectNodes, +} +export interface WSMessage { + type: number; + data: any; +} + +type DataHandler = (data: any) => void; + +let handlers = {}; + +export function registerHandler(msgTypeID: number, handler: DataHandler) { + handlers[msgTypeID] = handler; +} + +export function unregisterHandler(msgTypeID: number) { + delete handlers[msgTypeID]; +} + +export function connectWebSocket(path: string, onOpen, onClose, onError) { + let loc = window.location; + let uri = 'ws:'; + + if (loc.protocol === 'https:') { + uri = 'wss:'; + } + uri += '//' + loc.host + path; + + let ws = new WebSocket(uri); + + ws.onopen = onOpen; + ws.onclose = onClose; + ws.onerror = onError; + + ws.onmessage = (e) => { + let msg: WSMessage = JSON.parse(e.data); + // Just a ping, do nothing + if (msg.type == WSMsgType.Ping) { + return; + } + let handler = handlers[msg.type]; + if (!handler) { + return; + } + handler(msg.data); + }; +} diff --git a/plugins/analysis/dashboard/frontend/src/app/stores/AutopeeringStore.tsx b/plugins/analysis/dashboard/frontend/src/app/stores/AutopeeringStore.tsx new file mode 100644 index 0000000000000000000000000000000000000000..67b90849f54933dc3a90e4419553317e854f431e --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/stores/AutopeeringStore.tsx @@ -0,0 +1,622 @@ +import {action, computed, observable, ObservableMap, ObservableSet} from "mobx"; +import {connectWebSocket, registerHandler, WSMsgType} from "app/misc/WS"; +import {default as Viva} from 'vivagraphjs'; + +export class AddNodeMessage { + id: string; +} + +export class RemoveNodeMessage { + id: string; +} + +export class ConnectNodesMessage { + source: string; + target: string +} + +export class DisconnectNodesMessage { + source: string; + target: string +} + +export class Neighbors { + in: Set<string>; + out: Set<string>; + + constructor() { + this.in = new Set(); + this.out = new Set(); + } +} + +const EDGE_COLOR_DEFAULT = "#ff7d6cff"; +const EDGE_COLOR_HIDE = "#ff7d6c40"; +const EDGE_COLOR_OUTGOING = "#336db5ff"; +const EDGE_COLOR_INCOMING = "#1c8d7fff"; +const VERTEX_COLOR_DEFAULT = "0xa8d0e6"; +const VERTEX_COLOR_ACTIVE = "0xcb4b16"; +const VERTEX_COLOR_IN_NEIGHBOR = "0x1c8d7f"; +const VERTEX_COLOR_OUT_NEIGHBOR = "0x336db5"; +const VERTEX_SIZE = 14; +const VERTEX_SIZE_ACTIVE = 24; +const VERTEX_SIZE_CONNECTED = 18; +const statusWebSocketPath = "/ws"; + +export const shortenedIDCharCount = 8; + +export class AutopeeringStore { + @observable nodes = new ObservableSet(); + @observable neighbors = new ObservableMap<string,Neighbors>(); + @observable connections = new ObservableSet(); + + graphViewActive: boolean = false; + @observable websocketConnected: boolean = false; + + // selecting a certain node + @observable selectionActive: boolean = false; + @observable selectedNode: string = null; + @observable selectedNodeInNeighbors: Set<string> = null; + @observable selectedNodeOutNeighbors: Set<string> = null; + @observable previewNode: string = null; + + // search + @observable search: string = ""; + + // viva graph objects + graph; + graphics; + renderer; + + constructor() { + registerHandler(WSMsgType.AddNode, this.onAddNode); + registerHandler(WSMsgType.RemoveNode, this.onRemoveNode); + registerHandler(WSMsgType.ConnectNodes, this.onConnectNodes); + registerHandler(WSMsgType.DisconnectNodes, this.onDisconnectNodes); + } + + // connect to analysis server via websocket + connect() { + connectWebSocket(statusWebSocketPath, + () => this.updateWebSocketConnected(true), + () => this.updateWebSocketConnected(false), + () => this.updateWebSocketConnected(false)) + } + + // derive the full node ID based on the shortened nodeID (first shortenedIDCharCount chars) + getFullNodeID = (shortNodeID: string) => { + for(let fullNodeID of this.nodes.values()){ + if (fullNodeID.startsWith(shortNodeID)) { + return fullNodeID; + } + } + return ""; + }; + + @action + updateWebSocketConnected = (connected: boolean) => this.websocketConnected = connected; + + // create a graph and fill it with data + start = () => { + this.graphViewActive = true; + this.graph = Viva.Graph.graph(); + + let graphics: any = Viva.Graph.View.webglGraphics(); + + let layout = Viva.Graph.Layout.forceDirected(this.graph, { + springLength: 30, + springCoeff: 0.0001, + dragCoeff: 0.02, + stableThreshold: 0.15, + gravity: -2, + timeStep: 20, + theta: 0.8, + }); + graphics.link((link) => { + return Viva.Graph.View.webglLine(EDGE_COLOR_DEFAULT); + }); + graphics.setNodeProgram(buildCircleNodeShader()); + + graphics.node((node) => { + return new WebGLCircle(VERTEX_SIZE, VERTEX_COLOR_DEFAULT); + }); + graphics.link(() => Viva.Graph.View.webglLine(EDGE_COLOR_DEFAULT)); + let ele = document.getElementById('visualizer'); + this.renderer = Viva.Graph.View.renderer(this.graph, { + container: ele, graphics, layout, renderLinks: true, + }); + + let events = Viva.Graph.webglInputEvents(graphics, this.graph); + + events.click((node) => { + this.handleNodeSelection(node.id); + }); + + events.mouseEnter((node) => { + this.previewNode = node.id; + }); + + events.mouseLeave((node) => { + this.previewNode = undefined; + }); + + + this.graphics = graphics; + this.renderer.run(); + // draw graph if we have data collected + this.initialDrawGraph(); + } + + // fill graph with data we have previously collected + initialDrawGraph = () => { + this.nodes.forEach((node,key,map) => { + this.drawNode(node); + }) + this.neighbors.forEach((node,key,map) => { + // Only do it for one type of neighbors, as it is duplicated + node.out.forEach((outNeighborID) =>{ + this.graph.addLink(key, outNeighborID); + }) + }) + } + + // dispose only graph, but keep the data + stop = () => { + this.graphViewActive = false; + this.renderer.dispose(); + this.graph = null; + } + + @action + updateSearch = (searchNode: string) => { + this.search = searchNode.trim(); + } + + // handlers for incoming ws messages // + + @action + onAddNode = (msg: AddNodeMessage) => { + if (this.nodes.has(msg.id)){ + console.log("Node %s already known.", msg.id); + return; + } + this.nodes.add(msg.id); + if (this.graphViewActive) { + this.drawNode(msg.id); + } + console.log("Node %s added.", msg.id); + + // the more nodes we have, the more spacing we need + if (this.nodes.size > 30) { + this.renderer.getLayout().simulator.springLength(this.nodes.size); + } + } + + @action + onRemoveNode = (msg: RemoveNodeMessage) => { + if (!this.nodes.has(msg.id)) { + console.log("Can't delete node %s, not in map.", msg.id); + return + } + + this.nodes.delete(msg.id); + if (this.graphViewActive) { + this.graph.removeNode(msg.id); + } + console.log("Removed node %s", msg.id) + + // the less nodes we have, the less spacing we need + if (this.nodes.size >= 30) { + this.renderer.getLayout().simulator.springLength(this.nodes.size); + } + } + + @action + onConnectNodes = (msg: ConnectNodesMessage) => { + if (!this.nodes.has(msg.source)) { + console.log("Missing source node %s from node map.", msg.source); + return; + } + if (!this.nodes.has(msg.target)) { + console.log("Missing target node %s from node map.", msg.target); + return; + } + + // both are in the map, draw the connection on screen + if (this.graphViewActive) { + this.graph.addLink(msg.source, msg.target); + } + + // update connections + this.connections.add(msg.source + msg.target); + + // Update neighbors map + if (this.neighbors.get(msg.source) === undefined) { + let neighbors = new Neighbors(); + neighbors.out.add(msg.target); + this.neighbors.set(msg.source, neighbors); + } else { + this.neighbors.get(msg.source).out.add(msg.target); + } + + if (this.neighbors.get(msg.target) === undefined) { + let neighbors = new Neighbors(); + neighbors.in.add(msg.source); + this.neighbors.set(msg.target, neighbors); + } else { + this.neighbors.get(msg.target).in.add(msg.source); + } + + console.log("Connected nodes %s -> %s", msg.source, msg.target); + } + + @action + onDisconnectNodes = (msg: DisconnectNodesMessage) => { + if (this.graphViewActive){ + let existingLink = this.graph.getLink(msg.source, msg.target); + if (!existingLink) { + console.log("Link %s -> %s is missing from graph", msg.source, msg.target); + return; + } + this.graph.removeLink(existingLink); + } + + // update connections and neighbors + this.connections.delete(msg.source + msg.target); + this.neighbors.get(msg.source).out.delete(msg.target); + this.neighbors.get(msg.target).in.delete(msg.source); + + console.log("Disconnected nodes %s -> %s",msg.source, msg.target) + } + + // graph related updates // + + drawNode = (node: string) => { + let existing = this.graph.getNode(node); + + if (existing) { + return; + } else { + // add to graph structure + this.graph.addNode(node); + } + } + + // updates color of a node (vertex) in the graph + updateNodeUiColor = (node, color, size) => { + let nodeUI = this.graphics.getNodeUI(node); + if (nodeUI != undefined) { + nodeUI.color = color; + nodeUI.size = size; + } + } + + // updates color of a link (edge) in the graph + updateLinkUiColor = (idA, idB, color) => { + let con = this.graph.getLink(idA, idB); + + if(con != null) { + let linkUI = this.graphics.getLinkUI(con.id); + if (linkUI != undefined) { + linkUI.color = parseColor(color); + } + } + } + + // highlights selectedNode, its links and neighbors + showHighlight = () => { + if (!this.selectionActive) {return}; + + this.graph.beginUpdate(); + + this.graph.forEachLink((link) => { + let linkUi = this.graphics.getLinkUI(link.id); + linkUi.color = parseColor(EDGE_COLOR_HIDE); + }) + + // Highlight selected node + this.updateNodeUiColor(this.selectedNode, VERTEX_COLOR_ACTIVE, VERTEX_SIZE_ACTIVE); + this.selectedNodeInNeighbors.forEach((inNeighborID) => { + this.updateNodeUiColor(inNeighborID, VERTEX_COLOR_IN_NEIGHBOR, VERTEX_SIZE_CONNECTED); + this.updateLinkUiColor(inNeighborID, this.selectedNode, EDGE_COLOR_INCOMING); + }) + this.selectedNodeOutNeighbors.forEach((outNeighborID) => { + this.updateNodeUiColor(outNeighborID, VERTEX_COLOR_OUT_NEIGHBOR, VERTEX_SIZE_CONNECTED); + this.updateLinkUiColor(this.selectedNode, outNeighborID, EDGE_COLOR_OUTGOING); + }) + + this.graph.endUpdate(); + this.renderer.rerender(); + } + + // disables highlighting of selectedNode, its links and neighbors + resetPreviousColors = (skipAllLink: boolean = false, toLinkHide: boolean = false) => { + if (!this.selectionActive) {return}; + this.graph.beginUpdate(); + + let edgeColor = EDGE_COLOR_DEFAULT; + + if (toLinkHide) { + edgeColor = EDGE_COLOR_HIDE; + } + + // Remove highlighting of selected node + this.updateNodeUiColor(this.selectedNode, VERTEX_COLOR_DEFAULT, VERTEX_SIZE); + this.selectedNodeInNeighbors.forEach((inNeighborID) => { + // Remove highlighting of neighbor + this.updateNodeUiColor(inNeighborID, VERTEX_COLOR_DEFAULT, VERTEX_SIZE); + // Remove highlighting of link + this.updateLinkUiColor(inNeighborID, this.selectedNode, edgeColor); + }) + this.selectedNodeOutNeighbors.forEach((outNeighborID) => { + // Remove highlighting of neighbor + this.updateNodeUiColor(outNeighborID, VERTEX_COLOR_DEFAULT, VERTEX_SIZE); + // Remove highlighting of link + this.updateLinkUiColor(this.selectedNode, outNeighborID, edgeColor); + }) + + if (!skipAllLink) { + this.graph.forEachLink((link) => { + let linkUi = this.graphics.getLinkUI(link.id); + linkUi.color = parseColor(EDGE_COLOR_DEFAULT); + }) + } + + this.graph.endUpdate(); + this.renderer.rerender(); + } + + // handlers for frontend events // + + // updates the currently selected node + @action + updateSelectedNode = (node: string) => { + this.selectedNode = node; + // get node incoming neighbors + if (!this.nodes.has(this.selectedNode)) { + console.log("Selected node not found (%s)", this.selectedNode); + } + const neighbors = this.neighbors.get(this.selectedNode); + this.selectedNodeInNeighbors = neighbors ? neighbors.in : new Set(); + this.selectedNodeOutNeighbors = neighbors ? neighbors.out : new Set(); + this.selectionActive = true; + this.showHighlight(); + } + + // handles click on a node button + @action + handleNodeButtonOnClick = (e) => { + // find node based on the first 8 characters + let clickedNode = this.getFullNodeID(e.target.innerHTML) + this.handleNodeSelection(clickedNode); + } + + // checks whether selection is already active, then updates selected node + @action + handleNodeSelection = (clickedNode: string) => { + if (this.selectionActive) { + if (this.selectedNode === clickedNode) { + // Disable selection on second click when clicked on the same node + this.clearNodeSelection(); + return; + } else { + // we clicked on a different node + // stop highlighting the other node if clicked + // note that edge color defaults back to "hide" + this.resetPreviousColors(true, true); + } + } + this.updateSelectedNode(clickedNode); + } + + // handles clearing the node selection + @action + clearNodeSelection = () => { + this.resetPreviousColors(); + this.selectedNode = null; + this.selectedNodeInNeighbors = null; + this.selectedNodeOutNeighbors = null; + this.selectionActive = false; + return; + } + + // computed values update frontend rendering // + + @computed + get nodeListView(){ + let results; + if (this.search.trim().length === 0) { + results = this.nodes; + } else { + results = new Set(); + this.nodes.forEach((node) => { + if (node.toLowerCase().indexOf(this.search.toLowerCase()) >= 0){ + results.add(node); + } + }) + } + let ids = []; + + results.forEach((nodeID) => { + ids.push(nodeID); + }) + return ids + } + + @computed + get inNeighborList(){ + return Array.from(this.selectedNodeInNeighbors); + } + + @computed + get outNeighborList(){ + return Array.from(this.selectedNodeOutNeighbors); + } + +} + +export default AutopeeringStore; + +// vivagraph related utility functions // + +function parseColor(color): any { + let parsedColor = 0x009ee8ff; + + if (typeof color === 'number') { + return color; + } + + if (typeof color === 'string' && color) { + if (color.length === 4) { + // #rgb, duplicate each letter except first #. + color = color.replace(/([^#])/g, '$1$1'); + } + if (color.length === 9) { + // #rrggbbaa + parsedColor = parseInt(color.substr(1), 16); + } else if (color.length === 7) { + // or #rrggbb. + parsedColor = (parseInt(color.substr(1), 16) << 8) | 0xff; + } else { + throw 'Color expected in hex format with preceding "#". E.g. #00ff00. Got value: ' + color; + } + } + + return parsedColor; +} + +// WebGL stuff // + +function WebGLCircle(size, color) { + this.size = size; + this.color = color; +} +// Next comes the hard part - implementation of API for custom shader +// program, used by webgl renderer: +function buildCircleNodeShader() { + // For each primitive we need 4 attributes: x, y, color and size. + var ATTRIBUTES_PER_PRIMITIVE = 4, + nodesFS = [ + 'precision mediump float;', + 'varying vec4 color;', + 'void main(void) {', + ' if ((gl_PointCoord.x - 0.5) * (gl_PointCoord.x - 0.5) + (gl_PointCoord.y - 0.5) * (gl_PointCoord.y - 0.5) < 0.25) {', + ' gl_FragColor = color;', + ' } else {', + ' gl_FragColor = vec4(0);', + ' }', + '}'].join('\n'), + nodesVS = [ + 'attribute vec2 a_vertexPos;', + // Pack color and size into vector. First elemnt is color, second - size. + // Since it's floating point we can only use 24 bit to pack colors... + // thus alpha channel is dropped, and is always assumed to be 1. + 'attribute vec2 a_customAttributes;', + 'uniform vec2 u_screenSize;', + 'uniform mat4 u_transform;', + 'varying vec4 color;', + 'void main(void) {', + ' gl_Position = u_transform * vec4(a_vertexPos/u_screenSize, 0, 1);', + ' gl_PointSize = a_customAttributes[1] * u_transform[0][0];', + ' float c = a_customAttributes[0];', + ' color.b = mod(c, 256.0); c = floor(c/256.0);', + ' color.g = mod(c, 256.0); c = floor(c/256.0);', + ' color.r = mod(c, 256.0); c = floor(c/256.0); color /= 255.0;', + ' color.a = 1.0;', + '}'].join('\n'); + var program, + gl, + buffer, + locations, + webglUtils, + nodes = new Float32Array(64), + nodesCount = 0, + canvasWidth, canvasHeight, transform, + isCanvasDirty; + return { + /** + * Called by webgl renderer to load the shader into gl context. + */ + load: function (glContext) { + gl = glContext; + webglUtils = Viva.Graph.webgl(glContext); + program = webglUtils.createProgram(nodesVS, nodesFS); + gl.useProgram(program); + locations = webglUtils.getLocations(program, ['a_vertexPos', 'a_customAttributes', 'u_screenSize', 'u_transform']); + gl.enableVertexAttribArray(locations.vertexPos); + gl.enableVertexAttribArray(locations.customAttributes); + buffer = gl.createBuffer(); + }, + /** + * Called by webgl renderer to update node position in the buffer array + * + * @param nodeUI - data model for the rendered node (WebGLCircle in this case) + * @param pos - {x, y} coordinates of the node. + */ + position: function (nodeUI, pos) { + var idx = nodeUI.id; + nodes[idx * ATTRIBUTES_PER_PRIMITIVE] = pos.x; + nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 1] = -pos.y; + nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 2] = nodeUI.color; + nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 3] = nodeUI.size; + }, + /** + * Request from webgl renderer to actually draw our stuff into the + * gl context. This is the core of our shader. + */ + render: function () { + gl.useProgram(program); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, nodes, gl.DYNAMIC_DRAW); + if (isCanvasDirty) { + isCanvasDirty = false; + gl.uniformMatrix4fv(locations.transform, false, transform); + gl.uniform2f(locations.screenSize, canvasWidth, canvasHeight); + } + gl.vertexAttribPointer(locations.vertexPos, 2, gl.FLOAT, false, ATTRIBUTES_PER_PRIMITIVE * Float32Array.BYTES_PER_ELEMENT, 0); + gl.vertexAttribPointer(locations.customAttributes, 2, gl.FLOAT, false, ATTRIBUTES_PER_PRIMITIVE * Float32Array.BYTES_PER_ELEMENT, 2 * 4); + gl.drawArrays(gl.POINTS, 0, nodesCount); + }, + /** + * Called by webgl renderer when user scales/pans the canvas with nodes. + */ + updateTransform: function (newTransform) { + transform = newTransform; + isCanvasDirty = true; + }, + /** + * Called by webgl renderer when user resizes the canvas with nodes. + */ + updateSize: function (newCanvasWidth, newCanvasHeight) { + canvasWidth = newCanvasWidth; + canvasHeight = newCanvasHeight; + isCanvasDirty = true; + }, + /** + * Called by webgl renderer to notify us that the new node was created in the graph + */ + createNode: function (node) { + nodes = webglUtils.extendArray(nodes, nodesCount, ATTRIBUTES_PER_PRIMITIVE); + nodesCount += 1; + }, + /** + * Called by webgl renderer to notify us that the node was removed from the graph + */ + removeNode: function (node) { + if (nodesCount > 0) { nodesCount -= 1; } + if (node.id < nodesCount && nodesCount > 0) { + // we do not really delete anything from the buffer. + // Instead we swap deleted node with the "last" node in the + // buffer and decrease marker of the "last" node. Gives nice O(1) + // performance, but make code slightly harder than it could be: + webglUtils.copyArrayPart(nodes, node.id * ATTRIBUTES_PER_PRIMITIVE, nodesCount * ATTRIBUTES_PER_PRIMITIVE, ATTRIBUTES_PER_PRIMITIVE); + } + }, + /** + * This method is called by webgl renderer when it changes parts of its + * buffers. We don't use it here, but it's needed by API (see the comment + * in the removeNode() method) + */ + replaceProperties: function (replacedNode, newNode) { }, + }; +} diff --git a/plugins/analysis/dashboard/frontend/src/app/stores/FPCStore.tsx b/plugins/analysis/dashboard/frontend/src/app/stores/FPCStore.tsx new file mode 100644 index 0000000000000000000000000000000000000000..74e84627f0aec8a4f626c9bc6b448941f09df3a9 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/app/stores/FPCStore.tsx @@ -0,0 +1,130 @@ +import { registerHandler, WSMsgType, unregisterHandler } from "app/misc/WS"; +import { action, computed, observable } from "mobx"; + +enum Opinion { + Like = 1, + Dislike +} + +class VoteContext { + nodeid: string; + rounds: number; + opinions: number[]; + outcome: number; +} + +class Conflict { + nodesview: Map<string, VoteContext> +} + +export class FPCMessage { + conflictset: Map<string, Conflict> +} + +export class FPCStore { + @observable msg: FPCMessage = null; + + @observable conflicts: { + conflictID: string; + nodeOpinions: { nodeID: string; opinion: number }[]; + lastUpdated: number; + likes?: number; + }[] = []; + + @observable currentConflict = ""; + + timerId: NodeJS.Timer; + + constructor() { + } + + start() { + registerHandler(WSMsgType.FPC, this.addLiveFeed); + this.timerId = setInterval(() => this.updateConflictStates(), 2000); + } + + stop() { + unregisterHandler(WSMsgType.FPC); + clearInterval(this.timerId); + } + + @action + updateCurrentConflict = (id: string) => { + this.currentConflict = id; + } + + @action + addLiveFeed = (msg: FPCMessage) => { + let conflictIDs = Object.keys(msg.conflictset); + if (!conflictIDs) return; + + for (const conflictID of conflictIDs) { + let nodeIDs = Object.keys(msg.conflictset[conflictID].nodesview); + for (const nodeID of nodeIDs) { + let voteContext = msg.conflictset[conflictID].nodesview[nodeID]; + let latestOpinion = voteContext.opinions[voteContext.opinions.length - 1]; + + let conflict = this.conflicts.find(c => c.conflictID === conflictID); + if (!conflict) { + conflict = { + conflictID, + lastUpdated: Date.now(), + nodeOpinions: [] + }; + this.conflicts.push(conflict); + } else { + conflict.lastUpdated = Date.now(); + } + + const nodeOpinionIndex = conflict.nodeOpinions.findIndex(no => no.nodeID === nodeID); + if (nodeOpinionIndex >= 0) { + conflict.nodeOpinions[nodeOpinionIndex].opinion = latestOpinion; + } else { + conflict.nodeOpinions.push({ + nodeID, + opinion: latestOpinion + }); + } + + this.updateConflictState(conflict); + } + } + } + + @action + updateConflictStates() { + for (let i = 0; i < this.conflicts.length; i++) { + this.updateConflictState(this.conflicts[i]); + } + + const resolvedConflictIds = this.conflicts.filter(c => + Date.now() - c.lastUpdated > 10000 && + (c.likes === 0 || c.likes === Object.keys(c.nodeOpinions).length) + ).map(c => c.conflictID); + + for (const conflictID of resolvedConflictIds) { + this.conflicts = this.conflicts.filter(c => c.conflictID !== conflictID) + } + } + + @action + updateConflictState(conflict) { + conflict.likes = conflict.nodeOpinions.filter((nodeOpinion) => nodeOpinion.opinion === Opinion.Like).length; + } + + @computed + get nodeConflictGrid() { + if (!this.currentConflict) return; + const currentConflict = this.conflicts.find(c => c.conflictID === this.currentConflict); + if (!currentConflict) return; + return currentConflict.nodeOpinions; + } + + @computed + get conflictGrid() { + return this.conflicts.filter(c => c.likes !== undefined); + } +} + +export default FPCStore; + diff --git a/plugins/analysis/dashboard/frontend/src/assets/index.html b/plugins/analysis/dashboard/frontend/src/assets/index.html new file mode 100644 index 0000000000000000000000000000000000000000..29b7920dc463346a76787602a122956eb604d366 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/assets/index.html @@ -0,0 +1,10 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8"> + <title>GoShimmer Analyser</title> +</head> +<body> +<div id="root"></div> +</body> +</html> diff --git a/plugins/analysis/dashboard/frontend/src/assets/logo-header.svg b/plugins/analysis/dashboard/frontend/src/assets/logo-header.svg new file mode 100644 index 0000000000000000000000000000000000000000..e698bd5f4e2ad949dbe86d7134a1a67b4285731b --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/assets/logo-header.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 75 48" width="75pt" height="48pt"><path d=" M 32.321 10.317 C 33.516 10.317 34.485 9.351 34.485 8.158 C 34.485 6.966 33.516 6 32.321 6 C 31.125 6 30.157 6.966 30.157 8.158 C 30.157 9.351 31.125 10.317 32.321 10.317 Z " fill="rgb(246,248,252)"/><path d=" M 34.755 40.805 C 35.95 40.805 36.919 39.839 36.919 38.647 C 36.919 37.455 35.95 36.488 34.755 36.488 C 33.56 36.488 32.591 37.455 32.591 38.647 C 32.591 39.839 33.56 40.805 34.755 40.805 Z " fill="rgb(246,248,252)"/><path d=" M 32.939 15.713 C 33.942 15.713 34.755 14.902 34.755 13.901 C 34.755 12.901 33.942 12.09 32.939 12.09 C 31.936 12.09 31.123 12.901 31.123 13.901 C 31.123 14.902 31.936 15.713 32.939 15.713 Z " fill="rgb(246,248,252)"/><path d=" M 37.77 16.406 C 38.773 16.406 39.586 15.595 39.586 14.595 C 39.586 13.594 38.773 12.783 37.77 12.783 C 36.767 12.783 35.954 13.594 35.954 14.595 C 35.954 15.595 36.767 16.406 37.77 16.406 Z " fill="rgb(246,248,252)"/><path d=" M 32.321 20.299 C 33.175 20.299 33.867 19.609 33.867 18.758 C 33.867 17.906 33.175 17.216 32.321 17.216 C 31.467 17.216 30.775 17.906 30.775 18.758 C 30.775 19.609 31.467 20.299 32.321 20.299 Z " fill="rgb(246,248,252)"/><path d=" M 37.151 20.956 C 38.005 20.956 38.697 20.265 38.697 19.414 C 38.697 18.562 38.005 17.872 37.151 17.872 C 36.297 17.872 35.605 18.562 35.605 19.414 C 35.605 20.265 36.297 20.956 37.151 20.956 Z " fill="rgb(246,248,252)"/><path d=" M 41.016 22.459 C 41.869 22.459 42.561 21.768 42.561 20.917 C 42.561 20.065 41.869 19.375 41.016 19.375 C 40.162 19.375 39.47 20.065 39.47 20.917 C 39.47 21.768 40.162 22.459 41.016 22.459 Z " fill="rgb(246,248,252)"/><path d=" M 35.721 24.655 C 36.468 24.655 37.074 24.051 37.074 23.306 C 37.074 22.561 36.468 21.957 35.721 21.957 C 34.974 21.957 34.369 22.561 34.369 23.306 C 34.369 24.051 34.974 24.655 35.721 24.655 Z " fill="rgb(246,248,252)"/><path d=" M 30.891 24 C 31.638 24 32.244 23.396 32.244 22.651 C 32.244 21.906 31.638 21.302 30.891 21.302 C 30.144 21.302 29.539 21.906 29.539 22.651 C 29.539 23.396 30.144 24 30.891 24 Z " fill="rgb(246,248,252)"/><path d=" M 39.624 26.158 C 40.371 26.158 40.977 25.554 40.977 24.809 C 40.977 24.064 40.371 23.46 39.624 23.46 C 38.877 23.46 38.272 24.064 38.272 24.809 C 38.272 25.554 38.877 26.158 39.624 26.158 Z " fill="rgb(246,248,252)"/><path d=" M 33.789 27.469 C 34.43 27.469 34.949 26.951 34.949 26.313 C 34.949 25.674 34.43 25.156 33.789 25.156 C 33.149 25.156 32.63 25.674 32.63 26.313 C 32.63 26.951 33.149 27.469 33.789 27.469 Z " fill="rgb(246,248,252)"/><path d=" M 37.692 28.934 C 38.333 28.934 38.852 28.416 38.852 27.777 C 38.852 27.139 38.333 26.621 37.692 26.621 C 37.052 26.621 36.533 27.139 36.533 27.777 C 36.533 28.416 37.052 28.934 37.692 28.934 Z " fill="rgb(246,248,252)"/><path d=" M 28.997 26.775 C 29.638 26.775 30.157 26.257 30.157 25.618 C 30.157 24.98 29.638 24.462 28.997 24.462 C 28.357 24.462 27.838 24.98 27.838 25.618 C 27.838 26.257 28.357 26.775 28.997 26.775 Z " fill="rgb(246,248,252)"/><path d=" M 31.664 29.358 C 32.197 29.358 32.63 28.926 32.63 28.394 C 32.63 27.862 32.197 27.431 31.664 27.431 C 31.13 27.431 30.698 27.862 30.698 28.394 C 30.698 28.926 31.13 29.358 31.664 29.358 Z " fill="rgb(246,248,252)"/><path d=" M 33.325 32.017 C 33.795 32.017 34.176 31.638 34.176 31.169 C 34.176 30.701 33.795 30.321 33.325 30.321 C 32.856 30.321 32.475 30.701 32.475 31.169 C 32.475 31.638 32.856 32.017 33.325 32.017 Z " fill="rgb(246,248,252)"/><path d=" M 31.277 32.557 C 31.661 32.557 31.973 32.246 31.973 31.863 C 31.973 31.48 31.661 31.169 31.277 31.169 C 30.893 31.169 30.582 31.48 30.582 31.863 C 30.582 32.246 30.893 32.557 31.277 32.557 Z " fill="rgb(246,248,252)"/><path d=" M 29.461 30.552 C 29.93 30.552 30.311 30.173 30.311 29.704 C 30.311 29.236 29.93 28.856 29.461 28.856 C 28.991 28.856 28.611 29.236 28.611 29.704 C 28.611 30.173 28.991 30.552 29.461 30.552 Z " fill="rgb(246,248,252)"/><path d=" M 26.834 28.703 C 27.367 28.703 27.8 28.271 27.8 27.739 C 27.8 27.207 27.367 26.775 26.834 26.775 C 26.3 26.775 25.868 27.207 25.868 27.739 C 25.868 28.271 26.3 28.703 26.834 28.703 Z " fill="rgb(246,248,252)"/><path d=" M 26.795 21.456 C 27.328 21.456 27.761 21.024 27.761 20.492 C 27.761 19.96 27.328 19.528 26.795 19.528 C 26.261 19.528 25.829 19.96 25.829 20.492 C 25.829 21.024 26.261 21.456 26.795 21.456 Z " fill="rgb(246,248,252)"/><path d=" M 27.22 18.064 C 27.689 18.064 28.07 17.684 28.07 17.216 C 28.07 16.748 27.689 16.368 27.22 16.368 C 26.75 16.368 26.37 16.748 26.37 17.216 C 26.37 17.684 26.75 18.064 27.22 18.064 Z " fill="rgb(246,248,252)"/><path d=" M 28.147 15.289 C 28.532 15.289 28.843 14.978 28.843 14.595 C 28.843 14.212 28.532 13.901 28.147 13.901 C 27.763 13.901 27.452 14.212 27.452 14.595 C 27.452 14.978 27.763 15.289 28.147 15.289 Z " fill="rgb(246,248,252)"/><path d=" M 26.524 13.978 C 26.994 13.978 27.374 13.599 27.374 13.13 C 27.374 12.662 26.994 12.282 26.524 12.282 C 26.055 12.282 25.674 12.662 25.674 13.13 C 25.674 13.599 26.055 13.978 26.524 13.978 Z " fill="rgb(246,248,252)"/><path d=" M 35.528 30.822 C 36.062 30.822 36.494 30.39 36.494 29.858 C 36.494 29.326 36.062 28.895 35.528 28.895 C 34.995 28.895 34.562 29.326 34.562 29.858 C 34.562 30.39 34.995 30.822 35.528 30.822 Z " fill="rgb(246,248,252)"/><path d=" M 24.322 12.861 C 24.855 12.861 25.288 12.429 25.288 11.897 C 25.288 11.365 24.855 10.934 24.322 10.934 C 23.788 10.934 23.356 11.365 23.356 11.897 C 23.356 12.429 23.788 12.861 24.322 12.861 Z " fill="rgb(246,248,252)"/><path d=" M 24.979 16.947 C 25.512 16.947 25.945 16.515 25.945 15.983 C 25.945 15.451 25.512 15.02 24.979 15.02 C 24.445 15.02 24.013 15.451 24.013 15.983 C 24.013 16.515 24.445 16.947 24.979 16.947 Z " fill="rgb(246,248,252)"/><path d=" M 23.897 20.839 C 24.537 20.839 25.056 20.321 25.056 19.683 C 25.056 19.044 24.537 18.526 23.897 18.526 C 23.257 18.526 22.737 19.044 22.737 19.683 C 22.737 20.321 23.257 20.839 23.897 20.839 Z " fill="rgb(246,248,252)"/><path d=" M 20.38 20.839 C 21.127 20.839 21.732 20.235 21.732 19.49 C 21.732 18.745 21.127 18.141 20.38 18.141 C 19.633 18.141 19.027 18.745 19.027 19.49 C 19.027 20.235 19.633 20.839 20.38 20.839 Z " fill="rgb(246,248,252)"/><path d=" M 16.284 21.764 C 17.138 21.764 17.83 21.074 17.83 20.222 C 17.83 19.371 17.138 18.681 16.284 18.681 C 15.43 18.681 14.738 19.371 14.738 20.222 C 14.738 21.074 15.43 21.764 16.284 21.764 Z " fill="rgb(246,248,252)"/><path d=" M 11.801 23.962 C 12.804 23.962 13.618 23.151 13.618 22.15 C 13.618 21.15 12.804 20.339 11.801 20.339 C 10.798 20.339 9.985 21.15 9.985 22.15 C 9.985 23.151 10.798 23.962 11.801 23.962 Z " fill="rgb(246,248,252)"/><path d=" M 7.164 27.662 C 8.359 27.662 9.328 26.695 9.328 25.503 C 9.328 24.311 8.359 23.345 7.164 23.345 C 5.969 23.345 5 24.311 5 25.503 C 5 26.695 5.969 27.662 7.164 27.662 Z " fill="rgb(246,248,252)"/><path d=" M 9.985 19.452 C 10.989 19.452 11.802 18.641 11.802 17.641 C 11.802 16.64 10.989 15.829 9.985 15.829 C 8.982 15.829 8.169 16.64 8.169 17.641 C 8.169 18.641 8.982 19.452 9.985 19.452 Z " fill="rgb(246,248,252)"/><path d=" M 14.468 17.254 C 15.321 17.254 16.013 16.564 16.013 15.713 C 16.013 14.861 15.321 14.171 14.468 14.171 C 13.614 14.171 12.922 14.861 12.922 15.713 C 12.922 16.564 13.614 17.254 14.468 17.254 Z " fill="rgb(246,248,252)"/><path d=" M 13.81 13.169 C 14.664 13.169 15.356 12.478 15.356 11.627 C 15.356 10.775 14.664 10.085 13.81 10.085 C 12.957 10.085 12.265 10.775 12.265 11.627 C 12.265 12.478 12.957 13.169 13.81 13.169 Z " fill="rgb(246,248,252)"/><path d=" M 17.907 12.244 C 18.654 12.244 19.259 11.64 19.259 10.895 C 19.259 10.15 18.654 9.546 17.907 9.546 C 17.16 9.546 16.554 10.15 16.554 10.895 C 16.554 11.64 17.16 12.244 17.907 12.244 Z " fill="rgb(246,248,252)"/><path d=" M 21.423 12.244 C 22.063 12.244 22.582 11.727 22.582 11.088 C 22.582 10.449 22.063 9.932 21.423 9.932 C 20.783 9.932 20.264 10.449 20.264 11.088 C 20.264 11.727 20.783 12.244 21.423 12.244 Z " fill="rgb(246,248,252)"/><path d=" M 22.08 16.329 C 22.721 16.329 23.24 15.812 23.24 15.173 C 23.24 14.534 22.721 14.017 22.08 14.017 C 21.44 14.017 20.921 14.534 20.921 15.173 C 20.921 15.812 21.44 16.329 22.08 16.329 Z " fill="rgb(246,248,252)"/><path d=" M 18.564 16.368 C 19.311 16.368 19.916 15.764 19.916 15.019 C 19.916 14.274 19.311 13.67 18.564 13.67 C 17.817 13.67 17.211 14.274 17.211 15.019 C 17.211 15.764 17.817 16.368 18.564 16.368 Z " fill="rgb(246,248,252)"/><path d=" M 14.738 26.621 C 15.122 26.621 15.434 26.31 15.434 25.927 C 15.434 25.544 15.122 25.233 14.738 25.233 C 14.354 25.233 14.042 25.544 14.042 25.927 C 14.042 26.31 14.354 26.621 14.738 26.621 Z " fill="rgb(246,248,252)"/><path d=" M 17.52 26.274 C 17.99 26.274 18.371 25.894 18.371 25.426 C 18.371 24.958 17.99 24.578 17.52 24.578 C 17.051 24.578 16.67 24.958 16.67 25.426 C 16.67 25.894 17.051 26.274 17.52 26.274 Z " fill="rgb(246,248,252)"/><path d=" M 20.573 25.118 C 21.107 25.118 21.539 24.686 21.539 24.154 C 21.539 23.622 21.107 23.19 20.573 23.19 C 20.04 23.19 19.607 23.622 19.607 24.154 C 19.607 24.686 20.04 25.118 20.573 25.118 Z " fill="rgb(246,248,252)"/><path d=" M 21.307 28.201 C 21.948 28.201 22.467 27.684 22.467 27.045 C 22.467 26.406 21.948 25.889 21.307 25.889 C 20.667 25.889 20.148 26.406 20.148 27.045 C 20.148 27.684 20.667 28.201 21.307 28.201 Z " fill="rgb(246,248,252)"/><path d=" M 17.598 28.933 C 18.132 28.933 18.564 28.502 18.564 27.97 C 18.564 27.437 18.132 27.006 17.598 27.006 C 17.065 27.006 16.632 27.437 16.632 27.97 C 16.632 28.502 17.065 28.933 17.598 28.933 Z " fill="rgb(246,248,252)"/><path d=" M 14.313 28.895 C 14.783 28.895 15.163 28.516 15.163 28.047 C 15.163 27.579 14.783 27.199 14.313 27.199 C 13.843 27.199 13.463 27.579 13.463 28.047 C 13.463 28.516 13.843 28.895 14.313 28.895 Z " fill="rgb(246,248,252)"/><path d=" M 14.351 31.554 C 14.885 31.554 15.317 31.123 15.317 30.591 C 15.317 30.058 14.885 29.627 14.351 29.627 C 13.818 29.627 13.385 30.058 13.385 30.591 C 13.385 31.123 13.818 31.554 14.351 31.554 Z " fill="rgb(246,248,252)"/><path d=" M 18.293 32.056 C 18.934 32.056 19.453 31.538 19.453 30.9 C 19.453 30.261 18.934 29.743 18.293 29.743 C 17.653 29.743 17.134 30.261 17.134 30.9 C 17.134 31.538 17.653 32.056 18.293 32.056 Z " fill="rgb(246,248,252)"/><path d=" M 22.892 31.555 C 23.639 31.555 24.245 30.951 24.245 30.206 C 24.245 29.46 23.639 28.856 22.892 28.856 C 22.145 28.856 21.54 29.46 21.54 30.206 C 21.54 30.951 22.145 31.555 22.892 31.555 Z " fill="rgb(246,248,252)"/><path d=" M 25.597 34.908 C 26.45 34.908 27.142 34.218 27.142 33.366 C 27.142 32.515 26.45 31.824 25.597 31.824 C 24.743 31.824 24.051 32.515 24.051 33.366 C 24.051 34.218 24.743 34.908 25.597 34.908 Z " fill="rgb(246,248,252)"/><path d=" M 19.916 35.37 C 20.663 35.37 21.269 34.766 21.269 34.021 C 21.269 33.276 20.663 32.672 19.916 32.672 C 19.169 32.672 18.564 33.276 18.564 34.021 C 18.564 34.766 19.169 35.37 19.916 35.37 Z " fill="rgb(246,248,252)"/><path d=" M 16.709 37.991 C 17.456 37.991 18.061 37.387 18.061 36.642 C 18.061 35.897 17.456 35.293 16.709 35.293 C 15.962 35.293 15.356 35.897 15.356 36.642 C 15.356 37.387 15.962 37.991 16.709 37.991 Z " fill="rgb(246,248,252)"/><path d=" M 19.375 41.383 C 20.229 41.383 20.921 40.693 20.921 39.842 C 20.921 38.99 20.229 38.3 19.375 38.3 C 18.521 38.3 17.829 38.99 17.829 39.842 C 17.829 40.693 18.521 41.383 19.375 41.383 Z " fill="rgb(246,248,252)"/><path d=" M 26.486 42 C 27.489 42 28.302 41.189 28.302 40.189 C 28.302 39.188 27.489 38.377 26.486 38.377 C 25.483 38.377 24.669 39.188 24.669 40.189 C 24.669 41.189 25.483 42 26.486 42 Z " fill="rgb(246,248,252)"/><path d=" M 22.583 38.762 C 23.436 38.762 24.128 38.072 24.128 37.221 C 24.128 36.369 23.436 35.679 22.583 35.679 C 21.729 35.679 21.037 36.369 21.037 37.221 C 21.037 38.072 21.729 38.762 22.583 38.762 Z " fill="rgb(246,248,252)"/><path d=" M 29.461 38.146 C 30.464 38.146 31.278 37.335 31.278 36.334 C 31.278 35.334 30.464 34.523 29.461 34.523 C 28.458 34.523 27.645 35.334 27.645 36.334 C 27.645 37.335 28.458 38.146 29.461 38.146 Z " fill="rgb(246,248,252)"/><path d=" M 15.086 34.677 C 15.726 34.677 16.245 34.159 16.245 33.521 C 16.245 32.882 15.726 32.364 15.086 32.364 C 14.445 32.364 13.926 32.882 13.926 33.521 C 13.926 34.159 14.445 34.677 15.086 34.677 Z " fill="rgb(246,248,252)"/><path d=" M 60 8 L 61 8 L 61 40 L 60 40 L 60 8 L 60 8 Z " fill="rgb(246,248,252)"/></svg> \ No newline at end of file diff --git a/plugins/analysis/dashboard/frontend/src/main.scss b/plugins/analysis/dashboard/frontend/src/main.scss new file mode 100644 index 0000000000000000000000000000000000000000..206a014072c79b201b199eba5332d88fb33329df --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/main.scss @@ -0,0 +1,52 @@ +@import './sass/cards'; +@import './sass/colors'; +@import './sass/fonts'; +@import './sass/forms'; +@import './sass/layout'; + +$font-path: 'https://webassets.iota.org/fonts/' !default; + +@import './sass/inter'; +@import './sass/metropolis'; + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + background-color: $gray-05; +} + +h2 { + @include font-size(32px); + + color: $dark-gray; + font-family: $metropolis; +} + +p { + @include font-size(14px); + + font-family: $metropolis; +} + +button { + @include font-size(12px); + + margin: 0px 10px 10px 0px; + padding: 6px; + border: 1px solid $main-green; + border-radius: 6px; + outline: none; + background: $white; + color: $gray-5; + font-family: $metropolis; + font-weight: bold; + cursor: pointer; + + &:focus { + box-shadow: 0 0 3px 0 $light-green; + } +} diff --git a/plugins/analysis/dashboard/frontend/src/main.tsx b/plugins/analysis/dashboard/frontend/src/main.tsx new file mode 100644 index 0000000000000000000000000000000000000000..4f89e586c1758f24e8cc8cff2879d57dddbbb97a --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/main.tsx @@ -0,0 +1,26 @@ +import App from 'app/App'; +import AutopeeringStore from "app/stores/AutopeeringStore"; +import FPCStore from "app/stores/FPCStore"; +import { Provider } from 'mobx-react'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { Route } from 'react-router'; +import { BrowserRouter as Router } from 'react-router-dom'; +import "./main.scss"; + +const fpcStore = new FPCStore(); +const autopeeringStore = new AutopeeringStore() +const stores = { + "fpcStore": fpcStore, + "autopeeringStore": autopeeringStore, +}; + +// render react DOM +ReactDOM.render( + <Provider {...stores}> + <Router> + <Route component={(props) => <App {...props} />} /> + </Router> + </Provider>, + document.getElementById('root') +); \ No newline at end of file diff --git a/plugins/analysis/dashboard/frontend/src/sass/cards.scss b/plugins/analysis/dashboard/frontend/src/sass/cards.scss new file mode 100644 index 0000000000000000000000000000000000000000..f9739c6c939a762f463375a2a926a4cffcd0a20d --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/cards.scss @@ -0,0 +1,26 @@ +@import './colors'; +@import './fonts'; +@import './mixins'; + +.card { + display: flex; + flex: 1; + flex-direction: column; + padding: 20px; + border: 1px solid #f2f5fb; + border-radius: 6px; + background-color: $white; + box-shadow: 0px 4px 30px rgba(132, 147, 173, 0.1); + overflow: hidden; + + .card--header { + border-bottom: 1px solid #f2f5fb; + + h3 { + @include font-size(20px); + margin-bottom: 20px; + color: $gray-5; + font-family: $metropolis; + } + } +} diff --git a/plugins/analysis/dashboard/frontend/src/sass/colors.scss b/plugins/analysis/dashboard/frontend/src/sass/colors.scss new file mode 100644 index 0000000000000000000000000000000000000000..22112a599eacc466d53b6307c38cc1fb94c5b7a6 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/colors.scss @@ -0,0 +1,19 @@ +@import './variables'; + +$white: #ffffff; + +$dark-green: #2e8698; +$main-green: #0fc1b7; +$light-green: #00e0ca; + + +$dark-gray: #131f37; +$gray-5: #485776; +$gray-4: #8493ad; +$gray-3: #c3d0e4; +$gray-2: #eef2fa; +$gray-1: #f2f5fb; +$gray-05: #f6f8fc; + + + diff --git a/plugins/analysis/dashboard/frontend/src/sass/fonts.scss b/plugins/analysis/dashboard/frontend/src/sass/fonts.scss new file mode 100644 index 0000000000000000000000000000000000000000..c578069704ed34ad9e3ff3127d40675169f2d624 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/fonts.scss @@ -0,0 +1,22 @@ +$fallback-fonts: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; + +$metropolis: 'Metropolis Regular', $fallback-fonts; +$metropolis-italic: 'Metropolis Regular Italic', $fallback-fonts; +$metropolis-extra-light: 'Metropolis Extra Light', $fallback-fonts; +$metropolis-extra-light-italic: 'Metropolis Extra Light Italic', $fallback-fonts; +$metropolis-light: 'Metropolis Light', $fallback-fonts; +$metropolis-light-italic: 'Metropolis Light Italic', $fallback-fonts; +$metropolis-thin: 'Metropolis Thin', $fallback-fonts; +$metropolis-thin-italic: 'Metropolis Thin Italic', $fallback-fonts; +$metropolis-medium: 'Metropolis Medium', $fallback-fonts; +$metropolis-medium-italic: 'Metropolis Medium Italic', $fallback-fonts; +$metropolis-semi-bold: 'Metropolis Semi Bold', $fallback-fonts; +$metropolis-semi-bold-italic: 'Metropolis Semi Bold Italic', $fallback-fonts; +$metropolis-bold: 'Metropolis Bold', $fallback-fonts; +$metropolis-bold-italic: 'Metropolis Bold Italic', $fallback-fonts; +$metropolis-extra-bold: 'Metropolis Extra Bold', $fallback-fonts; +$metropolis-extra-bold-italic: 'Metropolis Extra Bold Italic', $fallback-fonts; +$metropolis-black: 'Metropolis Black', $fallback-fonts; +$metropolis-black-italic: 'Metropolis Black Italic', $fallback-fonts; + +$inter: 'Inter', $fallback-fonts; diff --git a/plugins/analysis/dashboard/frontend/src/sass/forms.scss b/plugins/analysis/dashboard/frontend/src/sass/forms.scss new file mode 100644 index 0000000000000000000000000000000000000000..ac9b168fd2357feccf1d0b4021407fbf6b86eb8f --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/forms.scss @@ -0,0 +1,66 @@ +@import './colors'; +@import './fonts'; +@import './mixins'; +@import './media-queries'; + +label { + @include font-size(14px); + + color: $gray-4; + font-family: $inter; + font-weight: bold; + text-transform: uppercase; +} + +.value { + @include font-size(14px); + + display: flex; + align-items: center; + min-height: 40px; + margin: 0px; + padding: 0px 20px; + border: 1px solid $gray-3; + border-radius: 6px; + outline: none; + color: $gray-5; + font-family: $inter; + word-break: break-all; +} + +label + input, +label + .value { + margin-left: 20px; +} + +input { + @include font-size(14px); + + height: 40px; + margin: 0px; + padding: 0px 20px; + border: 1px solid $gray-3; + border-radius: 6px; + outline: none; + color: $gray-5; + font-family: $inter; + + &:focus { + box-shadow: 0 0 3px 0 $light-green; + } + + // sass-lint:disable no-vendor-prefixes + &:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 $gray-5; + } + + &.input-plus { + position: relative; + border-radius: 0px 6px 6px 0px; + + &:focus { + z-index: 1; + } + } +} diff --git a/plugins/analysis/dashboard/frontend/src/sass/inter.scss b/plugins/analysis/dashboard/frontend/src/sass/inter.scss new file mode 100644 index 0000000000000000000000000000000000000000..0f363adb9185f1a25eb661f872a198180e579075 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/inter.scss @@ -0,0 +1,161 @@ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url('#{$font-path}inter/Inter-Thin.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-Thin.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url('#{$font-path}inter/Inter-ThinItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-ThinItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url('#{$font-path}inter/Inter-ExtraLight.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-ExtraLight.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url('#{$font-path}inter/Inter-ExtraLightItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-ExtraLightItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url('#{$font-path}inter/Inter-Light.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-Light.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url('#{$font-path}inter/Inter-LightItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-LightItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('#{$font-path}inter/Inter-Regular.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-Regular.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url('#{$font-path}inter/Inter-Italic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-Italic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url('#{$font-path}inter/Inter-Medium.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-Medium.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url('#{$font-path}inter/Inter-MediumItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-MediumItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url('#{$font-path}inter/Inter-SemiBold.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-SemiBold.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url('#{$font-path}inter/Inter-SemiBoldItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-SemiBoldItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url('#{$font-path}inter/Inter-Bold.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-Bold.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url('#{$font-path}inter/Inter-BoldItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-BoldItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 800; + font-display: swap; + src: url('#{$font-path}inter/Inter-ExtraBold.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-ExtraBold.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 800; + font-display: swap; + src: url('#{$font-path}inter/Inter-ExtraBoldItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-ExtraBoldItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url('#{$font-path}inter/Inter-Black.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-Black.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url('#{$font-path}inter/Inter-BlackItalic.woff2?v=3.13') format('woff2'), url('#{$font-path}inter/Inter-BlackItalic.woff?v=3.13') format('woff'); +} + +@font-face { + font-family: 'Inter var'; + font-style: normal; + font-weight: 100 900; + font-display: swap; + font-named-instance: 'Regular'; + src: url('#{$font-path}inter/Inter-roman.var.woff2?v=3.13') format('woff2'); +} + +@font-face { + font-family: 'Inter var'; + font-style: italic; + font-weight: 100 900; + font-display: swap; + font-named-instance: 'Italic'; + src: url('#{$font-path}inter/Inter-italic.var.woff2?v=3.13') format('woff2'); +} diff --git a/plugins/analysis/dashboard/frontend/src/sass/layout.scss b/plugins/analysis/dashboard/frontend/src/sass/layout.scss new file mode 100644 index 0000000000000000000000000000000000000000..5a3008bb223e8252bd2b515cd7ee774c2e86150b --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/layout.scss @@ -0,0 +1,38 @@ +.row { + display: flex; + flex-direction: row; + + &.middle { + align-items: center; + } +} + +.col { + display: flex; + flex: 1; + flex-direction: column; +} + +.margin-t-t { + margin-top: 10px; +} + +.margin-t-s { + margin-top: 20px; +} + +.margin-t-m { + margin-top: 32px; +} + +.margin-b-t { + margin-bottom: 10px; +} + +.margin-b-s { + margin-bottom: 20px; +} + +.margin-b-m { + margin-bottom: 32px; +} diff --git a/plugins/analysis/dashboard/frontend/src/sass/media-queries.scss b/plugins/analysis/dashboard/frontend/src/sass/media-queries.scss new file mode 100644 index 0000000000000000000000000000000000000000..97fa61a14a0b1f8c5e69c3296060d9014c8a8026 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/media-queries.scss @@ -0,0 +1,21 @@ +$desktop-width: 1024px; +$tablet-width: 768px; +$phone-width: 480px; + +@mixin desktop-down { + @media (max-width: #{$desktop-width}) { + @content; + } +} + +@mixin tablet-down { + @media (max-width: #{$tablet-width}) { + @content; + } +} + +@mixin phone-down { + @media (max-width: #{$phone-width}) { + @content; + } +} diff --git a/plugins/analysis/dashboard/frontend/src/sass/metropolis.scss b/plugins/analysis/dashboard/frontend/src/sass/metropolis.scss new file mode 100644 index 0000000000000000000000000000000000000000..50fae46dd79f840cc049b9fac417d1bf1762532f --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/metropolis.scss @@ -0,0 +1,126 @@ +@font-face { + font-family: 'Metropolis Regular'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-Regular.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-Regular.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Regular Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-RegularItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-RegularItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Extra Light'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-ExtraLight.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-ExtraLight.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Light'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-Light.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-Light.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Thin'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-Thin.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-Thin.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Extra Light Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-ExtraLightItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-ExtraLightItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Light Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-LightItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-LightItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Thin Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-ThinItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-ThinItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Medium'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-Medium.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-Medium.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Semi Bold'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-SemiBold.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-SemiBold.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Bold'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-Bold.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-Bold.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Bold Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-BoldItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-BoldItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Medium Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-MediumItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-MediumItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Semi Bold Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-SemiBoldItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-SemiBoldItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Extra Bold'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-ExtraBold.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-ExtraBold.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Extra Bold Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-ExtraBoldItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-ExtraBoldItalic.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Black'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-Black.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-Black.woff?v=11') format('woff'); + } + + @font-face { + font-family: 'Metropolis Black Italic'; + font-style: normal; + font-weight: normal; + src: url('#{$font-path}metropolis/Metropolis-BlackItalic.woff2?v=11') format('woff2'), url('#{$font-path}metropolis/Metropolis-BlackItalic.woff?v=11') format('woff'); + } + \ No newline at end of file diff --git a/plugins/analysis/dashboard/frontend/src/sass/mixins.scss b/plugins/analysis/dashboard/frontend/src/sass/mixins.scss new file mode 100644 index 0000000000000000000000000000000000000000..181ae46bc72126ce3bda492eff61c28d69353696 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/mixins.scss @@ -0,0 +1,15 @@ +$rem-base-font: 16px !default; + +@mixin font-size($font-size, $line-height: 0) { + font-size: $font-size; + + // sass-lint:disable no-duplicate-properties + font-size: $font-size / $rem-base-font * 1rem; + + @if $line-height > 0 { + line-height: $line-height; + + // sass-lint:disable no-duplicate-properties + line-height: $line-height / $rem-base-font * 1rem; + } +} diff --git a/plugins/analysis/dashboard/frontend/src/sass/variables.scss b/plugins/analysis/dashboard/frontend/src/sass/variables.scss new file mode 100644 index 0000000000000000000000000000000000000000..7a06adf59c1a1e7eff465b905e2e20d73859bedb --- /dev/null +++ b/plugins/analysis/dashboard/frontend/src/sass/variables.scss @@ -0,0 +1,4 @@ +$success: #28a745; +$danger: #dc3545; +$info: #17a2b8; +$warning: #ffc107; diff --git a/plugins/spa/frontend/tsconfig.json b/plugins/analysis/dashboard/frontend/tsconfig.json similarity index 100% rename from plugins/spa/frontend/tsconfig.json rename to plugins/analysis/dashboard/frontend/tsconfig.json diff --git a/plugins/analysis/dashboard/frontend/types/global.d.ts b/plugins/analysis/dashboard/frontend/types/global.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..dd2e02926c48bf21ab8fd9853e9d8660ab2bb16d --- /dev/null +++ b/plugins/analysis/dashboard/frontend/types/global.d.ts @@ -0,0 +1,12 @@ +/** Global definitions for developement **/ + +// for style loader +declare module '*.css' { + const styles: any; + export = styles; +} + +declare module "*.svg" { + const content: string; + export default content; +} \ No newline at end of file diff --git a/plugins/analysis/dashboard/frontend/webpack.config.js b/plugins/analysis/dashboard/frontend/webpack.config.js new file mode 100644 index 0000000000000000000000000000000000000000..0ebf5fb85f5ec63ba1b41506d43daddb86c65a26 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/webpack.config.js @@ -0,0 +1,125 @@ +let webpack = require('webpack'); +let path = require('path'); + +// variables +let isProduction = + process.argv.indexOf('-p') >= 0 || process.env.NODE_ENV === 'production'; +let sourcePath = path.join(__dirname, './src'); +let outPath = path.join(__dirname, './build'); + +// plugins +let HtmlWebpackPlugin = require('html-webpack-plugin'); +let WebpackCleanupPlugin = require('webpack-cleanup-plugin'); + +module.exports = { + context: sourcePath, + entry: { + app: './main.tsx' + }, + output: { + path: outPath, + publicPath: isProduction ? "/app" : "http://127.0.0.1:9090/", + filename: isProduction ? '[contenthash].js' : '[hash].js', + chunkFilename: isProduction ? '[name].[contenthash].js' : '[name].[hash].js' + }, + target: 'web', + resolve: { + extensions: ['.js', '.ts', '.tsx'], + // Fix webpack's default behavior to not load packages with jsnext:main module + // (jsnext:main directs not usually distributable es6 format, but es6 sources) + mainFields: ['module', 'browser', 'main'], + alias: { + app: path.resolve(__dirname, 'src/app/') + } + }, + module: { + rules: [ + // .ts, .tsx + { + test: /\.tsx?$/, + use: [ + !isProduction && { + loader: 'babel-loader', + options: { + plugins: ['react-hot-loader/babel'] + } + }, + { + loader: 'ts-loader' + } + ].filter(Boolean) + }, + // scss + { + test: /\.s[ac]ss$/i, + use: [ + // Creates `style` nodes from JS strings + 'style-loader', + // Translates CSS into CommonJS + 'css-loader', + // Compiles Sass to CSS + 'sass-loader', + ], + }, + // static assets + { test: /\.html$/, use: 'html-loader' }, + { test: /\.(a?png|svg)$/, use: 'url-loader?limit=10000' }, + { + test: /\.(jpe?g|gif|bmp|mp3|mp4|ogg|wav|eot|ttf|woff|woff2)$/, + use: 'file-loader' + } + ] + }, + optimization: { + splitChunks: { + name: true, + cacheGroups: { + commons: { + chunks: 'initial', + minChunks: 2 + }, + vendors: { + test: /[\\/]node_modules[\\/]/, + chunks: 'all', + priority: -10, + filename: isProduction ? 'vendor.[contenthash].js' : 'vendor.[hash].js' + } + } + }, + runtimeChunk: true + }, + plugins: [ + new webpack.EnvironmentPlugin({ + NODE_ENV: 'development', // use 'development' unless process.env.NODE_ENV is defined + DEBUG: false + }), + new WebpackCleanupPlugin(), + new HtmlWebpackPlugin({ + template: 'assets/index.html' + }) + ], + devServer: { + contentBase: sourcePath, + hot: true, + inline: true, + disableHostCheck: true, + historyApiFallback: { + disableDotRule: true + }, + stats: 'minimal', + clientLogLevel: 'warning', + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS", + "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization" + } + }, + // https://webpack.js.org/configuration/devtool/ + devtool: isProduction ? 'hidden-source-map' : 'cheap-module-eval-source-map', + node: { + // workaround for webpack-dev-server issue + // https://github.com/webpack/webpack-dev-server/issues/60#issuecomment-103411179 + fs: 'empty', + net: 'empty' + } +}; diff --git a/plugins/analysis/dashboard/frontend/yarn.lock b/plugins/analysis/dashboard/frontend/yarn.lock new file mode 100644 index 0000000000000000000000000000000000000000..bc9b4fcceb86a00b51ce8eb9d56638ad4570cd91 --- /dev/null +++ b/plugins/analysis/dashboard/frontend/yarn.lock @@ -0,0 +1,6487 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.3.tgz#324bcfd8d35cd3d47dae18cde63d752086435e9a" + integrity sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg== + dependencies: + "@babel/highlight" "^7.10.3" + +"@babel/core@^7.2.2": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.3.tgz#73b0e8ddeec1e3fdd7a2de587a60e17c440ec77e" + integrity sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w== + dependencies: + "@babel/code-frame" "^7.10.3" + "@babel/generator" "^7.10.3" + "@babel/helper-module-transforms" "^7.10.1" + "@babel/helpers" "^7.10.1" + "@babel/parser" "^7.10.3" + "@babel/template" "^7.10.3" + "@babel/traverse" "^7.10.3" + "@babel/types" "^7.10.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.3.tgz#32b9a0d963a71d7a54f5f6c15659c3dbc2a523a5" + integrity sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA== + dependencies: + "@babel/types" "^7.10.3" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-function-name@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz#79316cd75a9fa25ba9787ff54544307ed444f197" + integrity sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw== + dependencies: + "@babel/helper-get-function-arity" "^7.10.3" + "@babel/template" "^7.10.3" + "@babel/types" "^7.10.3" + +"@babel/helper-get-function-arity@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz#3a28f7b28ccc7719eacd9223b659fdf162e4c45e" + integrity sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-member-expression-to-functions@^7.10.1": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz#bc3663ac81ac57c39148fef4c69bf48a77ba8dd6" + integrity sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-module-imports@^7.10.1": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz#766fa1d57608e53e5676f23ae498ec7a95e1b11a" + integrity sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-module-transforms@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz#24e2f08ee6832c60b157bb0936c86bef7210c622" + integrity sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg== + dependencies: + "@babel/helper-module-imports" "^7.10.1" + "@babel/helper-replace-supers" "^7.10.1" + "@babel/helper-simple-access" "^7.10.1" + "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/template" "^7.10.1" + "@babel/types" "^7.10.1" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.10.1": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz#f53c4b6783093195b0f69330439908841660c530" + integrity sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg== + dependencies: + "@babel/types" "^7.10.3" + +"@babel/helper-replace-supers@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz#ec6859d20c5d8087f6a2dc4e014db7228975f13d" + integrity sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.10.1" + "@babel/helper-optimise-call-expression" "^7.10.1" + "@babel/traverse" "^7.10.1" + "@babel/types" "^7.10.1" + +"@babel/helper-simple-access@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz#08fb7e22ace9eb8326f7e3920a1c2052f13d851e" + integrity sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw== + dependencies: + "@babel/template" "^7.10.1" + "@babel/types" "^7.10.1" + +"@babel/helper-split-export-declaration@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz#c6f4be1cbc15e3a868e4c64a17d5d31d754da35f" + integrity sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g== + dependencies: + "@babel/types" "^7.10.1" + +"@babel/helper-validator-identifier@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz#60d9847f98c4cea1b279e005fdb7c28be5412d15" + integrity sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw== + +"@babel/helpers@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.1.tgz#a6827b7cb975c9d9cef5fd61d919f60d8844a973" + integrity sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw== + dependencies: + "@babel/template" "^7.10.1" + "@babel/traverse" "^7.10.1" + "@babel/types" "^7.10.1" + +"@babel/highlight@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.3.tgz#c633bb34adf07c5c13156692f5922c81ec53f28d" + integrity sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw== + dependencies: + "@babel/helper-validator-identifier" "^7.10.3" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.3.tgz#7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315" + integrity sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA== + +"@babel/runtime@^7.1.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.3.tgz#670d002655a7c366540c67f6fd3342cd09500364" + integrity sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.10.1", "@babel/template@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.3.tgz#4d13bc8e30bf95b0ce9d175d30306f42a2c9a7b8" + integrity sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA== + dependencies: + "@babel/code-frame" "^7.10.3" + "@babel/parser" "^7.10.3" + "@babel/types" "^7.10.3" + +"@babel/traverse@^7.10.1", "@babel/traverse@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.3.tgz#0b01731794aa7b77b214bcd96661f18281155d7e" + integrity sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug== + dependencies: + "@babel/code-frame" "^7.10.3" + "@babel/generator" "^7.10.3" + "@babel/helper-function-name" "^7.10.3" + "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/parser" "^7.10.3" + "@babel/types" "^7.10.3" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.10.1", "@babel/types@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.3.tgz#6535e3b79fea86a6b09e012ea8528f935099de8e" + integrity sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.3" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + +"@types/classnames@^2.2.7": + version "2.2.10" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999" + integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ== + +"@types/glob@^7.1.1": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987" + integrity sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/history@*": + version "4.7.6" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.6.tgz#ed8fc802c45b8e8f54419c2d054e55c9ea344356" + integrity sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w== + +"@types/html-minifier-terser@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz#551a4589b6ee2cc9c1dff08056128aec29b94880" + integrity sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA== + +"@types/json-schema@^7.0.4": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" + integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "14.0.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.14.tgz#24a0b5959f16ac141aeb0c5b3cd7a15b7c64cbce" + integrity sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ== + +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + +"@types/react-dom@^16.0.11": + version "16.9.8" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423" + integrity sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA== + dependencies: + "@types/react" "*" + +"@types/react-router@^5.1.7": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.8.tgz#4614e5ba7559657438e17766bb95ef6ed6acc3fa" + integrity sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg== + dependencies: + "@types/history" "*" + "@types/react" "*" + +"@types/react@*", "@types/react@^16.7.20": + version "16.9.41" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.41.tgz#925137ee4d2ff406a0ecf29e8e9237390844002e" + integrity sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@*", "@types/tapable@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== + +"@types/uglify-js@*": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.2.tgz#01992579debba674e1e359cd6bcb1a1d0ab2e02b" + integrity sha512-d6dIfpPbF+8B7WiCi2ELY7m0w1joD8cRW4ms88Emdb2w062NeEpbNCeWwVCgzLRpVG+5e74VFSg4rgJ2xXjEiQ== + dependencies: + source-map "^0.6.1" + +"@types/webpack-sources@*": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-1.4.0.tgz#e58f1f05f87d39a5c64cf85705bdbdbb94d4d57e" + integrity sha512-c88dKrpSle9BtTqR6ifdaxu1Lvjsl3C5OsfvuUbUwdXymshv1TkufUAXBajCCUM/f/TmnkZC/Esb03MinzSiXQ== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4.4.23", "@types/webpack@^4.41.8": + version "4.41.17" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.17.tgz#0a69005e644d657c85b7d6ec1c826a71bebd1c93" + integrity sha512-6FfeCidTSHozwKI67gIVQQ5Mp0g4X96c2IXxX75hYEQJwST/i6NyZexP//zzMOBb+wG9jJ7oO8fk9yObP2HWAw== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +acorn@^5.5.0: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +acorn@^6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +add-event-listener@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/add-event-listener/-/add-event-listener-0.0.1.tgz#a76229ebc64c8aefae204a16273a2f255abea2d0" + integrity sha1-p2Ip68ZMiu+uIEoWJzovJVq+otA= + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.0.tgz#5c894537098785926d71e696114a53ce768ed773" + integrity sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw== + +ajv@^4.7.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.5.5: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" + integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" + integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== + +babel-loader@^8.0.5: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + +bn.js@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" + integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.0.tgz#545d0b1b07e6b2c99211082bf1b12cce7a0b0e11" + integrity sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.2" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + +camel-case@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" + integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== + dependencies: + pascal-case "^3.1.1" + tslib "^1.10.0" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +"chokidar@>=2.0.0 <4.0.0", chokidar@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8" + integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classnames@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + +clean-css@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= + dependencies: + restore-cursor "^1.0.1" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0, commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.4.6, concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-loader@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" + +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +csstype@^2.2.0, csstype@^2.6.7: + version "2.6.10" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" + integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.1, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +dom-converter@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-helpers@^5.0.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.4.tgz#4609680ab5c79a45f2531441f1949b79d6587f4b" + integrity sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^2.6.7" + +dom-serializer@0, dom-serializer@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domhandler@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.0.0.tgz#51cd13efca31da95bbb0c5bee3a48300e333b3e9" + integrity sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw== + dependencies: + domelementtype "^2.0.1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.1.0.tgz#7ade3201af43703fde154952e3a868eb4b635f16" + integrity sha512-CD9M0Dm1iaHfQ1R/TI+z3/JWp/pgub0j4jIQKH89ARR4ATAV2nbaOQS5XxU9maJP5jHaPdDDQSEHuE2UmpUTKg== + dependencies: + dom-serializer "^0.2.1" + domelementtype "^2.0.1" + domhandler "^3.0.0" + +dot-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" + integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +elliptic@^6.0.0, elliptic@^6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0, enhanced-resolve@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d" + integrity sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^2.7.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-2.13.1.tgz#e4cc8fa0f009fb829aaae23855a29360be1f6c11" + integrity sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE= + dependencies: + chalk "^1.1.3" + concat-stream "^1.4.6" + debug "^2.1.1" + doctrine "^1.2.2" + es6-map "^0.1.3" + escope "^3.6.0" + espree "^3.1.6" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^1.1.1" + glob "^7.0.3" + globals "^9.2.0" + ignore "^3.1.2" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + optionator "^0.8.1" + path-is-absolute "^1.0.0" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.6.0" + strip-json-comments "~1.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.1.6: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter3@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-entry-cache@^1.1.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-1.3.1.tgz#44c61ea607ae4be9c1402f41f44270cbfe334ff8" + integrity sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-loader@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f" + integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.5" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.12.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6" + integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg== + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +front-matter@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/front-matter/-/front-matter-2.1.2.tgz#f75983b9f2f413be658c93dfd7bd8ce4078f5cdb" + integrity sha1-91mDufL0E75ljJPf172M5AePXNs= + dependencies: + js-yaml "^3.4.6" + +fs-extra@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +gintersect@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/gintersect/-/gintersect-0.1.0.tgz#9a8cb6a80b7d6e955ac33515495b1212627b1816" + integrity sha1-moy2qAt9bpVawzUVSVsSEmJ7GBY= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^9.2.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globule@^1.0.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4" + integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + +gonzales-pe-sl@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz#6a868bc380645f141feeb042c6f97fcc71b59fe6" + integrity sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y= + dependencies: + minimist "1.1.x" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +history@^4.9.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" + integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^3.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^1.0.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^1.2.0, html-entities@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" + integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== + +html-loader@^1.0.0-alpha.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-1.1.0.tgz#91915f4d274caa9d46d1c3dc847cd82bfc037dbd" + integrity sha512-zwLbEgy+i7sgIYTlxI9M7jwkn29IvdsV6f1y7a2aLv/w8l1RigVk0PFijBZLLFsdi2gvL8sf2VJhTjLlfnK8sA== + dependencies: + html-minifier-terser "^5.0.5" + htmlparser2 "^4.1.0" + loader-utils "^2.0.0" + parse-srcset "^1.0.2" + schema-utils "^2.6.5" + +html-minifier-terser@^5.0.1, html-minifier-terser@^5.0.5: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + +html-webpack-plugin@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.3.0.tgz#53bf8f6d696c4637d5b656d3d9863d89ce8174fd" + integrity sha512-C0fzKN8yQoVLTelcJxZfJCE+aAvQiY2VUf3UuKrR4a9k5UMWYOtpDLsaXwATbcVCnI05hUS7L9ULQHWLZhyi3w== + dependencies: + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.15" + pretty-error "^2.1.1" + tapable "^1.1.3" + util.promisify "1.0.0" + +htmlparser2@^3.3.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +htmlparser2@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78" + integrity sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q== + dependencies: + domelementtype "^2.0.1" + domhandler "^3.0.0" + domutils "^2.0.0" + entities "^2.0.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-parser-js@>=0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77" + integrity sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ== + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore@^3.1.2: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +in-publish@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" + integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34= + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-my-ip-valid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" + integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ== + +is-my-json-valid@^2.10.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz#1345a6fca3e8daefc10d0fa77067f54cedafd59a" + integrity sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-regex@^1.0.4, is-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== + dependencies: + has-symbols "^1.0.1" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +js-base64@^2.1.8: + version "2.6.1" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.1.tgz#c328374225d2e65569791ded73c258e2c59334c7" + integrity sha512-G5x2saUTupU9D/xBY9snJs3TxvwX8EkpLFiYlPpDt/VmMHOXprnSU1nxiTmFbijCX4BLF/cMRIfAcC5BiMYgFQ== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.4.6, js-yaml@^3.5.1, js-yaml@^3.5.4: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +known-css-properties@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.3.0.tgz#a3d135bbfc60ee8c6eacf2f7e7e6f2d4755e49a4" + integrity sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ== + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash.capitalize@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9" + integrity sha1-+CbJtOKoUR2E46yinbBeGk87cqk= + +lodash.kebabcase@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.union@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= + +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.3.0, lodash@~4.17.10: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +loglevel@^1.6.8: + version "1.6.8" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" + integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== + +loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@^2.1.26, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.4: + version "2.4.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" + integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +mini-create-react-context@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz#df60501c83151db69e28eac0ef08b4002efab040" + integrity sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA== + dependencies: + "@babel/runtime" "^7.5.5" + tiny-warning "^1.0.3" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + integrity sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q= + dependencies: + brace-expansion "^1.0.0" + +minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@1.1.x: + version "1.1.3" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8" + integrity sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag= + +minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mobx-react-lite@2: + version "2.0.7" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.0.7.tgz#1bfb3b4272668e288047cf0c7940b14e91cba284" + integrity sha512-YKAh2gThC6WooPnVZCoC+rV1bODAKFwkhxikzgH18wpBjkgTkkR9Sb0IesQAH5QrAEH/JQVmy47jcpQkf2Au3Q== + +mobx-react@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.2.2.tgz#45e8e7c4894cac8399bba0a91060d7cfb8ea084b" + integrity sha512-Us6V4ng/iKIRJ8pWxdbdysC6bnS53ZKLKlVGBqzHx6J+gYPYbOotWvhHZnzh/W5mhpYXxlXif4kL2cxoWJOplQ== + dependencies: + mobx-react-lite "2" + +mobx@^5.15.0: + version "5.15.4" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.4.tgz#9da1a84e97ba624622f4e55a0bf3300fb931c2ab" + integrity sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw== + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= + +nan@^2.12.1, nan@^2.13.2: + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +ngraph.centrality@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ngraph.centrality/-/ngraph.centrality-0.3.0.tgz#8cc0ec0319ef0a374357fc1044c16975b179d09d" + integrity sha1-jMDsAxnvCjdDV/wQRMFpdbF50J0= + +ngraph.events@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/ngraph.events/-/ngraph.events-0.0.3.tgz#38f55316f3d207ad631ff94f6622ca8f2c0e87d0" + integrity sha1-OPVTFvPSB61jH/lPZiLKjywOh9A= + +ngraph.events@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/ngraph.events/-/ngraph.events-0.0.4.tgz#72cb364488dd0fd7f057458449f6a3b17a722d9a" + integrity sha1-css2RIjdD9fwV0WESfajsXpyLZo= + +ngraph.expose@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/ngraph.expose/-/ngraph.expose-0.0.0.tgz#746c34903a3848c45d033b14bc64619ea85fe5aa" + integrity sha1-dGw0kDo4SMRdAzsUvGRhnqhf5ao= + +ngraph.forcelayout@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/ngraph.forcelayout/-/ngraph.forcelayout-0.5.0.tgz#51511c3e1db45d3d5436da75dfb1d6af097916f5" + integrity sha1-UVEcPh20XT1UNtp137HWrwl5FvU= + dependencies: + ngraph.events "0.0.4" + ngraph.physics.simulator "^0.3.0" + +ngraph.fromjson@0.1.9: + version "0.1.9" + resolved "https://registry.yarnpkg.com/ngraph.fromjson/-/ngraph.fromjson-0.1.9.tgz#66910b664c69fa3c50a1ce79dd1dfdd5bab46f6e" + integrity sha1-ZpELZkxp+jxQoc553R391bq0b24= + dependencies: + ngraph.graph "0.0.14" + +ngraph.generators@0.0.19: + version "0.0.19" + resolved "https://registry.yarnpkg.com/ngraph.generators/-/ngraph.generators-0.0.19.tgz#552c0d087f942b9d0d2b0c6ca9aac436befa7659" + integrity sha1-VSwNCH+UK50NKwxsqarENr76dlk= + dependencies: + ngraph.graph "0.0.14" + ngraph.random "0.1.0" + +ngraph.graph@0.0.14: + version "0.0.14" + resolved "https://registry.yarnpkg.com/ngraph.graph/-/ngraph.graph-0.0.14.tgz#d47ac94967c920aaf76952d8a4e73346e1df2db7" + integrity sha1-1HrJSWfJIKr3aVLYpOczRuHfLbc= + dependencies: + ngraph.events "0.0.3" + +ngraph.merge@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ngraph.merge/-/ngraph.merge-0.0.1.tgz#e4e80ce37581a3c96b17d545e3a43c85434b9025" + integrity sha1-5OgM43WBo8lrF9VF46Q8hUNLkCU= + +ngraph.physics.primitives@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ngraph.physics.primitives/-/ngraph.physics.primitives-0.0.7.tgz#5dc9e179ba1f92e6dec774b01cd68914120b795b" + integrity sha1-Xcnhebofkubex3SwHNaJFBILeVs= + +ngraph.physics.simulator@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ngraph.physics.simulator/-/ngraph.physics.simulator-0.3.0.tgz#7ca6fc3e3617c73e1080572eaa8e04dbb77e0102" + integrity sha1-fKb8PjYXxz4QgFcuqo4E27d+AQI= + dependencies: + ngraph.events "0.0.3" + ngraph.expose "0.0.0" + ngraph.merge "0.0.1" + ngraph.physics.primitives "0.0.7" + ngraph.quadtreebh "0.0.4" + ngraph.random "0.0.1" + +ngraph.quadtreebh@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/ngraph.quadtreebh/-/ngraph.quadtreebh-0.0.4.tgz#c700d44e6e4af07b6d05001ba3987ff5e2dcd62c" + integrity sha1-xwDUTm5K8HttBQAbo5h/9eLc1iw= + dependencies: + ngraph.random "0.0.1" + +ngraph.random@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ngraph.random/-/ngraph.random-0.0.1.tgz#c008e2ebbfdffaf17ed10e4bbc913e567166bcf8" + integrity sha1-wAji67/f+vF+0Q5LvJE+VnFmvPg= + +ngraph.random@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ngraph.random/-/ngraph.random-0.1.0.tgz#1b6e9573529e080677da6ffa098790d76a0948a9" + integrity sha1-G26Vc1KeCAZ32m/6CYeQ12oJSKk= + +ngraph.tojson@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/ngraph.tojson/-/ngraph.tojson-0.1.4.tgz#39f0046588440ade622d58734d589d7974a0b3bc" + integrity sha1-OfAEZYhECt5iLVhzTVideXSgs7w= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" + integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== + dependencies: + lower-case "^2.0.1" + tslib "^1.10.0" + +node-forge@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" + integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-sass@^4.14.1: + version "4.14.1" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5" + integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g== + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash "^4.17.15" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.13.2" + node-gyp "^3.8.0" + npmlog "^4.0.0" + request "^2.88.0" + sass-graph "2.2.5" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + +object-is@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" + integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" + integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== + dependencies: + dot-case "^3.0.3" + tslib "^1.10.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse-srcset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" + integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE= + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" + integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pbkdf2@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU= + +portfinder@^1.0.26: + version "1.0.26" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" + integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" + integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.16" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.0" + +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" + integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" + integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== + +pretty-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" + integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +prop-types@^15.6.1, prop-types@^15.6.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0, querystring@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-dom@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" + integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.1" + +react-hot-loader@^4.12.21: + version "4.12.21" + resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.21.tgz#332e830801fb33024b5a147d6b13417f491eb975" + integrity sha512-Ynxa6ROfWUeKWsTHxsrL2KMzujxJVPjs385lmB2t5cHUxdoRPGind9F00tOkdc1l5WBleOF4XEAMILY1KPIIDA== + dependencies: + fast-levenshtein "^2.0.6" + global "^4.3.0" + hoist-non-react-statics "^3.3.0" + loader-utils "^1.1.0" + prop-types "^15.6.1" + react-lifecycles-compat "^3.0.4" + shallowequal "^1.1.0" + source-map "^0.7.3" + +react-icons@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.10.0.tgz#6c217a2dde2e8fa8d293210023914b123f317297" + integrity sha512-WsQ5n1JToG9VixWilSo1bHv842Cj5aZqTGiS3Ud47myF6aK7S/IUY2+dHcBdmkQcCFRuHsJ9OMUI0kTDfjyZXQ== + dependencies: + camelcase "^5.0.0" + +react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-router-dom@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" + integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.2.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" + integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.4.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-transition-group@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" + integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + +react@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" + integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== + dependencies: + picomatch "^2.2.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +recursive-readdir-sync@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz#1dbf6d32f3c5bb8d3cde97a6c588d547a9e13d56" + integrity sha1-Hb9tMvPFu4083pemxYjVR6nhPVY= + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" + integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" + integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== + dependencies: + css-select "^1.1.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" + strip-ansi "^3.0.0" + utila "^0.4.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request@^2.87.0, request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-pathname@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.3.2: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +rimraf@2, rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k= + dependencies: + once "^1.3.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-graph@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.5.tgz#a981c87446b8319d96dce0671e487879bd24c2e8" + integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag== + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^13.3.2" + +sass-lint@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sass-lint/-/sass-lint-1.13.1.tgz#5fd2b2792e9215272335eb0f0dc607f61e8acc8f" + integrity sha512-DSyah8/MyjzW2BWYmQWekYEKir44BpLqrCFsgs9iaWiVTcwZfwXHF586hh3D1n+/9ihUNMfd8iHAyb9KkGgs7Q== + dependencies: + commander "^2.8.1" + eslint "^2.7.0" + front-matter "2.1.2" + fs-extra "^3.0.1" + glob "^7.0.0" + globule "^1.0.0" + gonzales-pe-sl "^4.2.3" + js-yaml "^3.5.4" + known-css-properties "^0.3.0" + lodash.capitalize "^4.1.0" + lodash.kebabcase "^4.0.0" + merge "^1.2.0" + path-is-absolute "^1.0.0" + util "^0.10.3" + +sass-loader@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d" + integrity sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ== + dependencies: + clone-deep "^4.0.1" + loader-utils "^1.2.3" + neo-async "^2.6.1" + schema-utils "^2.6.1" + semver "^6.3.0" + +sass@^1.26.8: + version "1.26.9" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.26.9.tgz#73c10cbb88c12b22a9e0107725bfd62296f4978f" + integrity sha512-t8AkRVi+xvba4yZiLWkJdgJHBFCB3Dh4johniQkPy9ywkgFHNasXFEFP+RG/F6LhQ+aoE4aX+IorIWQjS0esVw== + dependencies: + chokidar ">=2.0.0 <4.0.0" + +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.7: + version "1.10.7" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" + integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== + dependencies: + node-forge "0.9.0" + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" + integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shelljs@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8" + integrity sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg= + +signal-exit@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simplesvg@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/simplesvg/-/simplesvg-0.0.10.tgz#37d2ec18de2c154dd9b69f79e8ad20bf1e1e5fdd" + integrity sha1-N9LsGN4sFU3Ztp956K0gvx4eX90= + dependencies: + add-event-listener "0.0.1" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" + integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.20: + version "0.3.20" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855" + integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.4.0" + websocket-driver "0.6.5" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== + dependencies: + readable-stream "^2.0.1" + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= + +style-loader@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" + integrity sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.6" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8= + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + +terser-webpack-plugin@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz#2c63544347324baafa9a56baaddf1634c8abfc2f" + integrity sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^3.1.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2, terser@^4.6.3: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +tiny-invariant@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" + integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + +tiny-warning@^1.0.0, tiny-warning@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== + dependencies: + glob "^7.1.2" + +ts-loader@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-7.0.5.tgz#789338fb01cb5dc0a33c54e50558b34a73c9c4c5" + integrity sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^4.0.0" + semver "^6.0.0" + +tslib@^1.10.0, tslib@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@^3.2.4: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.0.tgz#c7d6b0d6b0fccd51ab3ffc58a78d32b8d89a7be2" + integrity sha512-IzgAAIC8wRrg6NYkFIJY09vtktQcsvU8V6HhtQj9PTefbYImzLB1hufqo4m+RyM5N3mLx5BqJKccgxJS+W3kqw== + dependencies: + loader-utils "^2.0.0" + mime-types "^2.1.26" + schema-utils "^2.6.5" + +url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= + dependencies: + os-homedir "^1.0.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@^0.4.0, utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.3.2, uuid@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" + integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" + integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vivagraphjs@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/vivagraphjs/-/vivagraphjs-0.12.0.tgz#6fd06ef6136aaeca5cffea86d6d6f8bfaff7f52b" + integrity sha512-Air+vUHXAWj8NTWUnbU800yKC7SiHpCVwpKIPfDtr5436YoMd7cpg8blt6Fn9xarx+sz1osRxGHBHTaHvcsR6Q== + dependencies: + gintersect "0.1.0" + ngraph.centrality "0.3.0" + ngraph.events "0.0.3" + ngraph.forcelayout "0.5.0" + ngraph.fromjson "0.1.9" + ngraph.generators "0.0.19" + ngraph.graph "0.0.14" + ngraph.merge "0.0.1" + ngraph.random "0.0.1" + ngraph.tojson "0.1.4" + simplesvg "0.0.10" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +watchpack-chokidar2@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" + integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.2.tgz#c02e4d4d49913c3e7e122c3325365af9d331e9aa" + integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.0" + watchpack-chokidar2 "^2.0.0" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cleanup-plugin@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/webpack-cleanup-plugin/-/webpack-cleanup-plugin-0.5.1.tgz#df2d706bd75364c06e65b051186316d674eb96af" + integrity sha1-3y1wa9dTZMBuZbBRGGMW1nTrlq8= + dependencies: + lodash.union "4.6.0" + minimatch "3.0.3" + recursive-readdir-sync "1.0.6" + +webpack-cli@^3.3.11: + version "3.3.12" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a" + integrity sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag== + dependencies: + chalk "^2.4.2" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.1" + findup-sync "^3.0.0" + global-modules "^2.0.0" + import-local "^2.0.0" + interpret "^1.4.0" + loader-utils "^1.4.0" + supports-color "^6.1.0" + v8-compile-cache "^2.1.1" + yargs "^13.3.2" + +webpack-dev-middleware@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@^3.1.14: + version "3.11.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c" + integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.3.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.8" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.26" + schema-utils "^1.0.0" + selfsigned "^1.10.7" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "0.3.20" + sockjs-client "1.4.0" + spdy "^4.0.2" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "^13.3.2" + +webpack-hot-middleware@^2.25.0: + version "2.25.0" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" + integrity sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA== + dependencies: + ansi-html "0.0.7" + html-entities "^1.2.0" + querystring "^0.2.0" + strip-ansi "^3.0.0" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.43.0: + version "4.43.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.43.0.tgz#c48547b11d563224c561dad1172c8aa0b8a678e6" + integrity sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.6.1" + webpack-sources "^1.4.1" + +websocket-driver@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY= + dependencies: + websocket-extensions ">=0.1.1" + +websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1, which@^1.2.14, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + +ws@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" diff --git a/plugins/analysis/dashboard/parameters.go b/plugins/analysis/dashboard/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..b4026dd7a362f964d33acbd151ce32ff83e6742a --- /dev/null +++ b/plugins/analysis/dashboard/parameters.go @@ -0,0 +1,38 @@ +package dashboard + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgBindAddress defines the config flag of the analysis dashboard binding address. + CfgBindAddress = "analysis.dashboard.bindAddress" + // CfgDev defines the config flag of the analysis dashboard dev mode. + CfgDev = "analysis.dashboard.dev" + // CfgBasicAuthEnabled defines the config flag of the analysis dashboard basic auth enabler. + CfgBasicAuthEnabled = "analysis.dashboard.basic_auth.enabled" + // CfgBasicAuthUsername defines the config flag of the analysis dashboard basic auth username. + CfgBasicAuthUsername = "analysis.dashboard.basic_auth.username" + // CfgBasicAuthPassword defines the config flag of the analysis dashboard basic auth password. + CfgBasicAuthPassword = "analysis.dashboard.basic_auth.password" + // CfgMongoDBEnabled defines the config flag of the analysis dashboard to enable mongoDB. + CfgMongoDBEnabled = "analysis.dashboard.mongodb.enabled" + // CfgMongoDBUsername defines the config flag of the analysis dashboard mongoDB username. + CfgMongoDBUsername = "analysis.dashboard.mongodb.username" + // CfgMongoDBPassword defines the config flag of the analysis dashboard mongoDB password. + CfgMongoDBPassword = "analysis.dashboard.mongodb.password" + // CfgMongoDBHostAddress defines the config flag of the analysis dashboard mongoDB binding address. + CfgMongoDBHostAddress = "analysis.dashboard.mongodb.hostAddress" +) + +func init() { + flag.String(CfgBindAddress, "0.0.0.0:8000", "the bind address of the analysis dashboard") + flag.Bool(CfgDev, false, "whether the analysis dashboard runs in dev mode") + flag.Bool(CfgBasicAuthEnabled, false, "whether to enable HTTP basic auth") + flag.String(CfgBasicAuthUsername, "goshimmer", "HTTP basic auth username") + flag.String(CfgBasicAuthPassword, "goshimmer", "HTTP basic auth password") + flag.Bool(CfgMongoDBEnabled, false, "whether to enable MongoDB") + flag.String(CfgMongoDBUsername, "root", "MongoDB username") + flag.String(CfgMongoDBPassword, "password", "MongoDB username") + flag.String(CfgMongoDBHostAddress, "mongodb:27017", "MongoDB host address") +} diff --git a/plugins/analysis/dashboard/plugin.go b/plugins/analysis/dashboard/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..da6ab6e0ad79f52d2e44cb33bd9b8e83fde8720c --- /dev/null +++ b/plugins/analysis/dashboard/plugin.go @@ -0,0 +1,113 @@ +package dashboard + +import ( + "context" + "errors" + "net/http" + "time" + + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/labstack/echo" + "github.com/labstack/echo/middleware" +) + +// PluginName is the name of the dashboard plugin. +const PluginName = "Analysis-Dashboard" + +var ( + // plugin is the plugin instance of the dashboard plugin. + plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) + + log *logger.Logger + server *echo.Echo +) + +// Plugin gets the plugin instance +func Plugin() *node.Plugin { + return plugin +} + +func configure(plugin *node.Plugin) { + log = logger.NewLogger(plugin.Name) + configureFPCLiveFeed() + configureAutopeeringWorkerPool() + configureEventsRecording() + configureServer() +} + +func configureServer() { + server = echo.New() + server.HideBanner = true + server.HidePort = true + server.Use(middleware.Recover()) + + if config.Node().GetBool(CfgBasicAuthEnabled) { + server.Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) { + if username == config.Node().GetString(CfgBasicAuthUsername) && + password == config.Node().GetString(CfgBasicAuthPassword) { + return true, nil + } + return false, nil + })) + } + + setupRoutes(server) +} + +func run(*node.Plugin) { + // run FPC stat reporting + runFPCLiveFeed() + // run data reporting for autopeering visualizer + runAutopeeringFeed() + // records and organizes data that was received by analysis-server + runEventsRecordManager() + + log.Infof("Starting %s ...", PluginName) + if err := daemon.BackgroundWorker(PluginName, worker, shutdown.PriorityAnalysis); err != nil { + log.Panicf("Error starting as daemon: %s", err) + } +} + +func worker(shutdownSignal <-chan struct{}) { + defer log.Infof("Stopping %s ... done", PluginName) + + stopped := make(chan struct{}) + bindAddr := config.Node().GetString(CfgBindAddress) + go func() { + log.Infof("%s started, bind-address=%s", PluginName, bindAddr) + if err := server.Start(bindAddr); err != nil { + if !errors.Is(err, http.ErrServerClosed) { + log.Errorf("Error serving: %s", err) + } + close(stopped) + } + }() + + // ping all connected ws clients every second to keep the connections alive. + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + // stop if we are shutting down or the server could not be started + func() { + for { + select { + case <-ticker.C: + broadcastWsMessage(&wsmsg{MsgTypePing, ""}) + case <-shutdownSignal: + return + case <-stopped: + return + } + } + }() + + log.Infof("Stopping %s ...", PluginName) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := server.Shutdown(ctx); err != nil { + log.Errorf("Error stopping: %s", err) + } +} diff --git a/plugins/analysis/dashboard/recorded_events.go b/plugins/analysis/dashboard/recorded_events.go new file mode 100644 index 0000000000000000000000000000000000000000..b5e31954d1a3e1eb8480cb78a835c756d059a7c3 --- /dev/null +++ b/plugins/analysis/dashboard/recorded_events.go @@ -0,0 +1,264 @@ +package dashboard + +import ( + "strings" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/graph" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + analysisserver "github.com/iotaledger/goshimmer/plugins/analysis/server" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/identity" +) + +// the period in which we scan and delete old data. +const cleanUpPeriod = 15 * time.Second + +var ( + // maps nodeId to the latest arrival of a heartbeat. + nodes = make(map[string]time.Time) + // maps nodeId to outgoing connections + latest arrival of heartbeat. + links = make(map[string]map[string]time.Time) + lock sync.RWMutex +) + +// NeighborMetric contains the number of inbound/outbound neighbors. +type NeighborMetric struct { + Inbound uint + Outbound uint +} + +// NumOfNeighbors returns a map of nodeIDs to their neighbor count. +func NumOfNeighbors() map[string]*NeighborMetric { + lock.RLock() + defer lock.RUnlock() + result := make(map[string]*NeighborMetric) + for nodeID := range nodes { + // number of outgoing neighbors + if _, exist := result[nodeID]; !exist { + result[nodeID] = &NeighborMetric{Outbound: uint(len(links[nodeID]))} + } else { + result[nodeID].Outbound = uint(len(links[nodeID])) + } + + // fill in incoming neighbors + for outNeighborID := range links[nodeID] { + if _, exist := result[outNeighborID]; !exist { + result[outNeighborID] = &NeighborMetric{Inbound: 1} + } else { + result[outNeighborID].Inbound++ + } + } + } + return result +} + +// NetworkGraph returns the autopeering network graph. +func NetworkGraph() *graph.Graph { + lock.RLock() + defer lock.RUnlock() + var nodeIDs []string + for id := range nodes { + nodeIDs = append(nodeIDs, id) + } + g := graph.New(nodeIDs) + + for src, trgMap := range links { + for dst := range trgMap { + g.AddEdge(src, dst) + } + } + return g +} + +// configures the event recording by attaching to the analysis server's events. +func configureEventsRecording() { + analysisserver.Events.Heartbeat.Attach(events.NewClosure(func(hb *packet.Heartbeat) { + var out strings.Builder + for _, value := range hb.OutboundIDs { + out.WriteString(shortNodeIDString(value)) + } + var in strings.Builder + for _, value := range hb.InboundIDs { + in.WriteString(shortNodeIDString(value)) + } + log.Debugw( + "Heartbeat", + "nodeId", shortNodeIDString(hb.OwnID), + "outboundIds", out.String(), + "inboundIds", in.String(), + ) + lock.Lock() + defer lock.Unlock() + + nodeIDString := shortNodeIDString(hb.OwnID) + timestamp := time.Now() + + // when node is new, add to graph + if _, isAlready := nodes[nodeIDString]; !isAlready { + analysisserver.Events.AddNode.Trigger(nodeIDString) + } + // save it + update timestamp + nodes[nodeIDString] = timestamp + + // outgoing neighbor links update + for _, outgoingNeighbor := range hb.OutboundIDs { + outgoingNeighborString := shortNodeIDString(outgoingNeighbor) + // do we already know about this neighbor? + // if no, add it and set it online + if _, isAlready := nodes[outgoingNeighborString]; !isAlready { + // first time we see this particular node + analysisserver.Events.AddNode.Trigger(outgoingNeighborString) + } + // we have indirectly heard about the neighbor. + nodes[outgoingNeighborString] = timestamp + + // do we have any links already with src=nodeIdString? + if _, isAlready := links[nodeIDString]; !isAlready { + // nope, so we have to allocate an empty map to be nested in links for nodeIdString + links[nodeIDString] = make(map[string]time.Time) + } + + // update graph when connection hasn't been seen before + if _, isAlready := links[nodeIDString][outgoingNeighborString]; !isAlready { + analysisserver.Events.ConnectNodes.Trigger(nodeIDString, outgoingNeighborString) + } + // update links + links[nodeIDString][outgoingNeighborString] = timestamp + } + + // incoming neighbor links update + for _, incomingNeighbor := range hb.InboundIDs { + incomingNeighborString := shortNodeIDString(incomingNeighbor) + // do we already know about this neighbor? + // if no, add it and set it online + if _, isAlready := nodes[incomingNeighborString]; !isAlready { + // First time we see this particular node + analysisserver.Events.AddNode.Trigger(incomingNeighborString) + } + // we have indirectly heard about the neighbor. + nodes[incomingNeighborString] = timestamp + + // do we have any links already with src=incomingNeighborString? + if _, isAlready := links[incomingNeighborString]; !isAlready { + // nope, so we have to allocate an empty map to be nested in links for incomingNeighborString + links[incomingNeighborString] = make(map[string]time.Time) + } + + // update graph when connection hasn't been seen before + if _, isAlready := links[incomingNeighborString][nodeIDString]; !isAlready { + analysisserver.Events.ConnectNodes.Trigger(incomingNeighborString, nodeIDString) + } + // update links map + links[incomingNeighborString][nodeIDString] = timestamp + } + })) +} + +// starts record manager that initiates a record cleanup periodically +func runEventsRecordManager() { + if err := daemon.BackgroundWorker("Dashboard Analysis Server Record Manager", func(shutdownSignal <-chan struct{}) { + ticker := time.NewTicker(cleanUpPeriod) + defer ticker.Stop() + for { + select { + case <-shutdownSignal: + return + case <-ticker.C: + cleanUp(cleanUpPeriod) + } + } + }, shutdown.PriorityAnalysis); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} + +// removes nodes and links we haven't seen for at least 3 times the heartbeat interval. +func cleanUp(interval time.Duration) { + lock.Lock() + defer lock.Unlock() + now := time.Now() + + // go through the list of connections. Remove connections that are older than interval time. + for srcNode, targetMap := range links { + for trgNode, lastSeen := range targetMap { + if now.Sub(lastSeen) > interval { + delete(targetMap, trgNode) + analysisserver.Events.DisconnectNodes.Trigger(srcNode, trgNode) + } + } + // delete src node from links if it doesn't have any connections + if len(targetMap) == 0 { + delete(links, srcNode) + } + } + + // go through the list of nodes. Remove nodes that haven't been seen for interval time + for node, lastSeen := range nodes { + if now.Sub(lastSeen) > interval { + delete(nodes, node) + analysisserver.Events.RemoveNode.Trigger(node) + } + } +} + +func getEventsToReplay() (map[string]time.Time, map[string]map[string]time.Time) { + lock.RLock() + defer lock.RUnlock() + + copiedNodes := make(map[string]time.Time, len(nodes)) + for nodeID, lastHeartbeat := range nodes { + copiedNodes[nodeID] = lastHeartbeat + } + + copiedLinks := make(map[string]map[string]time.Time, len(links)) + for sourceID, targetMap := range links { + copiedLinks[sourceID] = make(map[string]time.Time, len(targetMap)) + for targetID, lastHeartbeat := range targetMap { + copiedLinks[sourceID][targetID] = lastHeartbeat + } + } + + return copiedNodes, copiedLinks +} + +// replays recorded events on the given event handler. +func replayAutopeeringEvents(handlers *EventHandlers) { + copiedNodes, copiedLinks := getEventsToReplay() + + // when a node is present in the list, it means we heard about it directly + // or indirectly, but within CLEAN_UP_PERIOD, therefore it is online + for nodeID := range copiedNodes { + handlers.AddNode(nodeID) + } + + for sourceID, targetMap := range copiedLinks { + for targetID := range targetMap { + handlers.ConnectNodes(sourceID, targetID) + } + } +} + +// EventHandlers holds the handler for each event of the record manager. +type EventHandlers struct { + // Addnode defines the handler called when adding a new node. + AddNode func(nodeId string) + // RemoveNode defines the handler called when adding removing a node. + RemoveNode func(nodeId string) + // ConnectNodes defines the handler called when connecting two nodes. + ConnectNodes func(sourceId string, targetId string) + // DisconnectNodes defines the handler called when connecting two nodes. + DisconnectNodes func(sourceId string, targetId string) +} + +// EventHandlersConsumer defines the consumer function of an *EventHandlers. +type EventHandlersConsumer = func(handler *EventHandlers) + +func shortNodeIDString(b []byte) string { + var id identity.ID + copy(id[:], b) + return id.String() +} diff --git a/plugins/analysis/dashboard/routes.go b/plugins/analysis/dashboard/routes.go new file mode 100644 index 0000000000000000000000000000000000000000..442af15b3f604d66c1c97a10437d51c5d1725e23 --- /dev/null +++ b/plugins/analysis/dashboard/routes.go @@ -0,0 +1,111 @@ +package dashboard + +import ( + "errors" + "fmt" + "io/ioutil" + "net/http" + + "github.com/gobuffalo/packr/v2" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/labstack/echo" +) + +// ErrInvalidParameter defines the invalid parameter error. +var ErrInvalidParameter = errors.New("invalid parameter") + +// ErrInternalError defines the internal error. +var ErrInternalError = errors.New("internal error") + +// ErrNotFound defines the not found error. +var ErrNotFound = errors.New("not found") + +// ErrForbidden defines the forbidden error. +var ErrForbidden = errors.New("forbidden") + +// holds analysis dashboard assets +var appBox = packr.New("AnalysisDashboard_App", "./frontend/build") +var assetsBox = packr.New("AnalysisDashboard_Assets", "./frontend/src/assets") + +func indexRoute(e echo.Context) error { + if config.Node().GetBool(CfgDev) { + res, err := http.Get("http://127.0.0.1:9090/") + if err != nil { + return err + } + devIndexHTML, err := ioutil.ReadAll(res.Body) + if err != nil { + return err + } + return e.HTMLBlob(http.StatusOK, devIndexHTML) + } + indexHTML, err := appBox.Find("index.html") + if err != nil { + return err + } + return e.HTMLBlob(http.StatusOK, indexHTML) +} + +func setupRoutes(e *echo.Echo) { + + if config.Node().GetBool("analysis.dashboard.dev") { + e.Static("/assets", "./plugins/analysis/dashboard/frontend/src/assets") + } else { + + // load assets from packr: either from within the binary or actual disk + for _, res := range appBox.List() { + e.GET("/app/"+res, echo.WrapHandler(http.StripPrefix("/app", http.FileServer(appBox)))) + } + + for _, res := range assetsBox.List() { + e.GET("/assets/"+res, echo.WrapHandler(http.StripPrefix("/assets", http.FileServer(assetsBox)))) + } + } + + e.GET("/ws", websocketRoute) + e.GET("/", indexRoute) + + // used to route into the dashboard index + e.GET("*", indexRoute) + + e.HTTPErrorHandler = func(err error, c echo.Context) { + c.Logger().Error(err) + + var statusCode int + var message string + + switch errors.Unwrap(err) { + + case echo.ErrNotFound: + c.Redirect(http.StatusSeeOther, "/") + return + + case echo.ErrUnauthorized: + statusCode = http.StatusUnauthorized + message = "unauthorized" + + case ErrForbidden: + statusCode = http.StatusForbidden + message = "access forbidden" + + case ErrInternalError: + statusCode = http.StatusInternalServerError + message = "internal analysis_server error" + + case ErrNotFound: + statusCode = http.StatusNotFound + message = "not found" + + case ErrInvalidParameter: + statusCode = http.StatusBadRequest + message = "bad request" + + default: + statusCode = http.StatusInternalServerError + message = "internal analysis_server error" + } + + message = fmt.Sprintf("%s, error: %+v", message, err) + c.String(statusCode, message) + } +} diff --git a/plugins/analysis/dashboard/types.go b/plugins/analysis/dashboard/types.go new file mode 100644 index 0000000000000000000000000000000000000000..943780e0a4841ebffe3bf840ea7ce4a2918edd45 --- /dev/null +++ b/plugins/analysis/dashboard/types.go @@ -0,0 +1,21 @@ +package dashboard + +const ( + // MsgTypePing defines a ping message type. + MsgTypePing byte = iota + // MsgTypeFPC defines a FPC update message. + MsgTypeFPC + // MsgTypeAddNode defines an addNode update message for autopeering visualizer. + MsgTypeAddNode + // MsgTypeRemoveNode defines a removeNode update message for autopeering visualizer. + MsgTypeRemoveNode + // MsgTypeConnectNodes defines a connectNodes update message for autopeering visualizer. + MsgTypeConnectNodes + // MsgTypeDisconnectNodes defines a disconnectNodes update message for autopeering visualizer. + MsgTypeDisconnectNodes +) + +type wsmsg struct { + Type byte `json:"type"` + Data interface{} `json:"data"` +} diff --git a/plugins/analysis/dashboard/ws.go b/plugins/analysis/dashboard/ws.go new file mode 100644 index 0000000000000000000000000000000000000000..c4eb5b49a52eb9ed49c28bafbbe1a37eeff89cc7 --- /dev/null +++ b/plugins/analysis/dashboard/ws.go @@ -0,0 +1,118 @@ +package dashboard + +import ( + "net/http" + "sync" + "time" + + "github.com/gorilla/websocket" + "github.com/labstack/echo" +) + +var ( + webSocketWriteTimeout = time.Duration(3) * time.Second + + // clients + wsClientsMu sync.Mutex + wsClients = make(map[uint64]*wsclient) + nextWsClientID uint64 + + // gorilla websocket layer + upgrader = websocket.Upgrader{ + HandshakeTimeout: webSocketWriteTimeout, + CheckOrigin: func(r *http.Request) bool { return true }, + EnableCompression: true, + } +) + +// a websocket client with a channel for downstream messages. +type wsclient struct { + // downstream message channel. + channel chan interface{} + // a channel which is closed when the websocket client is disconnected. + exit chan struct{} +} + +// reigsters and creates a new websocket client. +func registerWSClient() (uint64, *wsclient) { + wsClientsMu.Lock() + defer wsClientsMu.Unlock() + clientID := nextWsClientID + wsClient := &wsclient{ + channel: make(chan interface{}, 500), + exit: make(chan struct{}), + } + wsClients[clientID] = wsClient + nextWsClientID++ + return clientID, wsClient +} + +// removes the websocket client with the given id. +func removeWsClient(clientID uint64) { + wsClientsMu.Lock() + defer wsClientsMu.Unlock() + wsClient := wsClients[clientID] + close(wsClient.exit) + close(wsClient.channel) + delete(wsClients, clientID) +} + +// broadcasts the given message to all connected websocket clients. +func broadcastWsMessage(msg interface{}, dontDrop ...bool) { + wsClientsMu.Lock() + defer wsClientsMu.Unlock() + for _, wsClient := range wsClients { + if len(dontDrop) > 0 { + select { + case wsClient.channel <- msg: + case <-wsClient.exit: + // get unblocked if the websocket connection just got closed + } + continue + } + select { + case wsClient.channel <- msg: + default: + // potentially drop if slow consumer + } + } +} + +// handles a new websocket connection, registers the client +// and waits for downstream messages to be sent to the client +func websocketRoute(c echo.Context) error { + defer func() { + if r := recover(); r != nil { + log.Errorf("recovered from websocket handle func: %s", r) + } + }() + + // upgrade to websocket connection + ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil) + if err != nil { + return err + } + defer ws.Close() + ws.EnableWriteCompression(true) + + // cleanup client websocket + clientID, wsClient := registerWSClient() + defer removeWsClient(clientID) + + // replay autopeering events from the past upon connecting a new client + replayAutopeeringEvents(createAutopeeringEventHandlers(ws, createSyncNodeCallback, createSyncLinkCallback)) + + // replay FPC past events + replayFPCRecords(ws) + + for { + msg := <-wsClient.channel + if err := ws.WriteJSON(msg); err != nil { + break + } + if err := ws.SetWriteDeadline(time.Now().Add(webSocketWriteTimeout)); err != nil { + break + } + } + return nil +} diff --git a/plugins/analysis/packet/fpc_heartbeat.go b/plugins/analysis/packet/fpc_heartbeat.go new file mode 100644 index 0000000000000000000000000000000000000000..a02f508435fea88b535af97d1dac69cf3802109f --- /dev/null +++ b/plugins/analysis/packet/fpc_heartbeat.go @@ -0,0 +1,97 @@ +package packet + +import ( + "bytes" + "encoding/binary" + "encoding/gob" + "errors" + + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/hive.go/protocol/message" + "github.com/iotaledger/hive.go/protocol/tlv" +) + +var ( + // ErrInvalidFPCHeartbeat is returned for invalid FPC heartbeats. + ErrInvalidFPCHeartbeat = errors.New("invalid FPC heartbeat") +) + +// FPCHeartbeat represents a heartbeat packet. +type FPCHeartbeat struct { + // The ID of the node who sent the heartbeat. + // Must be contained when a heartbeat is serialized. + OwnID []byte + // RoundStats contains stats about an FPC round. + RoundStats vote.RoundStats + // Finalized contains the finalized conflicts within the last FPC round. + Finalized map[string]vote.Opinion +} + +// FPCHeartbeatMessageDefinition gets the fpcHeartbeatMessageDefinition. +func FPCHeartbeatMessageDefinition() *message.Definition { + // fpcHeartbeatMessageDefinition defines a heartbeat message's format. + var fpcHeartbeatMessageDefinition *message.Definition + fpcHeartBeatOnce.Do(func() { + fpcHeartbeatMessageDefinition = &message.Definition{ + ID: MessageTypeFPCHeartbeat, + MaxBytesLength: 65535, + VariableLength: true, + } + }) + return fpcHeartbeatMessageDefinition +} + +// ParseFPCHeartbeat parses a slice of bytes (serialized packet) into a FPC heartbeat. +func ParseFPCHeartbeat(data []byte) (*FPCHeartbeat, error) { + hb := &FPCHeartbeat{} + + buf := new(bytes.Buffer) + _, err := buf.Write(data) + if err != nil { + return nil, err + } + + decoder := gob.NewDecoder(buf) + err = decoder.Decode(hb) + if err != nil { + return nil, err + } + + return hb, nil +} + +// Bytes return the FPC heartbeat encoded as bytes +func (hb FPCHeartbeat) Bytes() ([]byte, error) { + buf := new(bytes.Buffer) + encoder := gob.NewEncoder(buf) + err := encoder.Encode(hb) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// NewFPCHeartbeatMessage serializes the given FPC heartbeat into a byte slice and adds a tlv header to the packet. +// message = tlv header + serialized packet +func NewFPCHeartbeatMessage(hb *FPCHeartbeat) ([]byte, error) { + packet, err := hb.Bytes() + if err != nil { + return nil, err + } + + // calculate total needed bytes based on packet + packetSize := len(packet) + + // create a buffer for tlv header plus the packet + buf := bytes.NewBuffer(make([]byte, 0, tlv.HeaderMessageDefinition.MaxBytesLength+uint16(packetSize))) + // write tlv header into buffer + if err := tlv.WriteHeader(buf, MessageTypeFPCHeartbeat, uint16(packetSize)); err != nil { + return nil, err + } + // write serialized packet bytes into the buffer + if err := binary.Write(buf, binary.BigEndian, packet); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} diff --git a/plugins/analysis/packet/fpc_heartbeat_test.go b/plugins/analysis/packet/fpc_heartbeat_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6ce656b61d42176d030f303445d03d6ff62ad338 --- /dev/null +++ b/plugins/analysis/packet/fpc_heartbeat_test.go @@ -0,0 +1,59 @@ +package packet + +import ( + "crypto/sha256" + "testing" + "time" + + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/hive.go/protocol/message" + "github.com/iotaledger/hive.go/protocol/tlv" + "github.com/stretchr/testify/require" +) + +var ownID = sha256.Sum256([]byte{'A'}) + +func dummyFPCHeartbeat() *FPCHeartbeat { + return &FPCHeartbeat{ + OwnID: ownID[:], + RoundStats: vote.RoundStats{ + Duration: time.Second, + RandUsed: 0.5, + ActiveVoteContexts: map[string]*vote.Context{ + "one": { + ID: "one", + Liked: 1., + Rounds: 3, + Opinions: []vote.Opinion{vote.Dislike, vote.Like, vote.Dislike}, + }}, + QueriedOpinions: []vote.QueriedOpinions{{ + OpinionGiverID: "nodeA", + Opinions: map[string]vote.Opinion{"one": vote.Like, "two": vote.Dislike}, + TimesCounted: 2, + }}, + }, + Finalized: map[string]vote.Opinion{"one": vote.Like, "two": vote.Dislike}, + } +} + +func TestFPCHeartbeat(t *testing.T) { + hb := dummyFPCHeartbeat() + + packet, err := hb.Bytes() + require.NoError(t, err) + + hbParsed, err := ParseFPCHeartbeat(packet) + require.NoError(t, err) + + require.Equal(t, hb, hbParsed) + + tlvHeaderLength := int(tlv.HeaderMessageDefinition.MaxBytesLength) + msg, err := NewFPCHeartbeatMessage(hb) + require.NoError(t, err) + + require.Equal(t, MessageTypeFPCHeartbeat, message.Type(msg[0])) + + hbParsed, err = ParseFPCHeartbeat(msg[tlvHeaderLength:]) + require.NoError(t, err) + require.Equal(t, hb, hbParsed) +} diff --git a/plugins/analysis/packet/heartbeat.go b/plugins/analysis/packet/heartbeat.go new file mode 100644 index 0000000000000000000000000000000000000000..49fe1c066fe164f5674c0b792edf803d3a0c6e56 --- /dev/null +++ b/plugins/analysis/packet/heartbeat.go @@ -0,0 +1,172 @@ +package packet + +import ( + "bytes" + "crypto/sha256" + "encoding/binary" + "errors" + "fmt" + + "github.com/iotaledger/hive.go/protocol/message" + "github.com/iotaledger/hive.go/protocol/tlv" +) + +var ( + // ErrInvalidHeartbeat is returned for invalid heartbeats. + ErrInvalidHeartbeat = errors.New("invalid heartbeat") +) + +const ( + // HeartbeatMaxOutboundPeersCount is the maximum amount of outbound peer IDs a heartbeat packet can contain. + HeartbeatMaxOutboundPeersCount = 4 + // HeartbeatMaxInboundPeersCount is the maximum amount of inbound peer IDs a heartbeat packet can contain. + HeartbeatMaxInboundPeersCount = 4 + // HeartbeatPacketPeerIDSize is the byte size of peer IDs within the heartbeat packet. + HeartbeatPacketPeerIDSize = sha256.Size + // HeartbeatPacketOutboundIDCountSize is the byte size of the counter indicating the amount of outbound IDs. + HeartbeatPacketOutboundIDCountSize = 1 + // HeartbeatPacketMinSize is the minimum byte size of a heartbeat packet. + HeartbeatPacketMinSize = HeartbeatPacketPeerIDSize + HeartbeatPacketOutboundIDCountSize + // HeartbeatPacketMaxSize is the maximum size a heartbeat packet can have. + HeartbeatPacketMaxSize = HeartbeatPacketPeerIDSize + HeartbeatPacketOutboundIDCountSize + + HeartbeatMaxOutboundPeersCount*sha256.Size + HeartbeatMaxInboundPeersCount*sha256.Size +) + +// Heartbeat represents a heartbeat packet. +type Heartbeat struct { + // The ID of the node who sent the heartbeat. + // Must be contained when a heartbeat is serialized. + OwnID []byte + // The IDs of the outbound peers. Can be empty or nil. + // It must not exceed HeartbeatMaxOutboundPeersCount. + OutboundIDs [][]byte + // The IDs of the inbound peers. Can be empty or nil. + // It must not exceed HeartbeatMaxInboundPeersCount. + InboundIDs [][]byte +} + +// HeartBeatMessageDefinition gets the heartbeatMessageDefinition. +func HeartBeatMessageDefinition() *message.Definition { + // heartbeatMessageDefinition defines a heartbeat message's format. + var heartbeatMessageDefinition *message.Definition + heartBeatOnce.Do(func() { + heartbeatMessageDefinition = &message.Definition{ + ID: MessageTypeHeartbeat, + MaxBytesLength: uint16(HeartbeatPacketMaxSize), + VariableLength: true, + } + }) + return heartbeatMessageDefinition +} + +// ParseHeartbeat parses a slice of bytes (serialized packet) into a heartbeat. +func ParseHeartbeat(data []byte) (*Heartbeat, error) { + // check minimum size + if len(data) < HeartbeatPacketMinSize { + return nil, fmt.Errorf("%w: packet doesn't reach minimum heartbeat packet size of %d", ErrMalformedPacket, HeartbeatPacketMinSize) + } + + if len(data) > HeartbeatPacketMaxSize { + return nil, fmt.Errorf("%w: packet exceeds maximum heartbeat packet size of %d", ErrMalformedPacket, HeartbeatPacketMaxSize) + } + + // sanity check: packet len - min packet % id size = 0, + // since we're only dealing with IDs from that offset + if (len(data)-HeartbeatPacketMinSize)%HeartbeatPacketPeerIDSize != 0 { + return nil, fmt.Errorf("%w: heartbeat packet is malformed since the data length after the min. packet size offset isn't conforming with peer ID sizes", ErrMalformedPacket) + } + + // copy own ID + ownID := make([]byte, HeartbeatPacketPeerIDSize) + copy(ownID, data[:HeartbeatPacketPeerIDSize]) + + // read outbound IDs count + outboundIDCount := int(data[HeartbeatPacketMinSize-1]) + if outboundIDCount > HeartbeatMaxOutboundPeersCount { + return nil, fmt.Errorf("%w: heartbeat packet exceeds maximum outbound IDs of %d", ErrMalformedPacket, HeartbeatMaxOutboundPeersCount) + } + + // check whether we'd have the amount of data needed for the advertised outbound id count + if (len(data)-HeartbeatPacketMinSize)/HeartbeatPacketPeerIDSize < outboundIDCount { + return nil, fmt.Errorf("%w: heartbeat packet is malformed since remaining data length wouldn't fit advertsized outbound IDs count", ErrMalformedPacket) + } + + // outbound IDs can be zero + outboundIDs := make([][]byte, outboundIDCount) + + if outboundIDCount != 0 { + offset := HeartbeatPacketMinSize + for i := range outboundIDs { + outboundIDs[i] = make([]byte, HeartbeatPacketPeerIDSize) + copy(outboundIDs[i], data[offset+i*HeartbeatPacketPeerIDSize:offset+(i+1)*HeartbeatPacketPeerIDSize]) + } + } + + // (packet size - (min packet size + read outbound IDs)) / ID size = inbound IDs count + inboundIDCount := (len(data) - (HeartbeatPacketMinSize + outboundIDCount*HeartbeatPacketPeerIDSize)) / HeartbeatPacketPeerIDSize + if inboundIDCount > HeartbeatMaxInboundPeersCount { + return nil, fmt.Errorf("%w: heartbeat packet exceeds maximum inbound IDs of %d", ErrMalformedPacket, HeartbeatMaxInboundPeersCount) + } + + // inbound IDs can be zero + inboundIDs := make([][]byte, inboundIDCount) + offset := HeartbeatPacketPeerIDSize + HeartbeatPacketOutboundIDCountSize + outboundIDCount*HeartbeatPacketPeerIDSize + for i := range inboundIDs { + inboundIDs[i] = make([]byte, HeartbeatPacketPeerIDSize) + copy(inboundIDs[i], data[offset+i*HeartbeatPacketPeerIDSize:offset+(i+1)*HeartbeatPacketPeerIDSize]) + } + + return &Heartbeat{OwnID: ownID, OutboundIDs: outboundIDs, InboundIDs: inboundIDs}, nil +} + +// NewHeartbeatMessage serializes the given heartbeat into a byte slice and adds a tlv header to the packet. +// message = tlv header + serialized packet +func NewHeartbeatMessage(hb *Heartbeat) ([]byte, error) { + if len(hb.InboundIDs) > HeartbeatMaxInboundPeersCount { + return nil, fmt.Errorf("%w: heartbeat exceeds maximum inbound IDs of %d", ErrInvalidHeartbeat, HeartbeatMaxInboundPeersCount) + } + if len(hb.OutboundIDs) > HeartbeatMaxOutboundPeersCount { + return nil, fmt.Errorf("%w: heartbeat exceeds maximum outbound IDs of %d", ErrInvalidHeartbeat, HeartbeatMaxOutboundPeersCount) + } + + if len(hb.OwnID) != HeartbeatPacketPeerIDSize { + return nil, fmt.Errorf("%w: heartbeat must contain the own peer ID", ErrInvalidHeartbeat) + } + + // calculate total needed bytes based on packet + packetSize := HeartbeatPacketMinSize + len(hb.OutboundIDs)*HeartbeatPacketPeerIDSize + len(hb.InboundIDs)*HeartbeatPacketPeerIDSize + packet := make([]byte, packetSize) + + // own nodeId + copy(packet[:HeartbeatPacketPeerIDSize], hb.OwnID[:]) + + // outbound id count + packet[HeartbeatPacketPeerIDSize] = byte(len(hb.OutboundIDs)) + + // copy contents of hb.OutboundIDs + offset := HeartbeatPacketMinSize + for i, outboundID := range hb.OutboundIDs { + copy(packet[offset+i*HeartbeatPacketPeerIDSize:offset+(i+1)*HeartbeatPacketPeerIDSize], outboundID[:HeartbeatPacketPeerIDSize]) + } + + // advance offset to after outbound IDs + offset += len(hb.OutboundIDs) * HeartbeatPacketPeerIDSize + + // copy contents of hb.InboundIDs + for i, inboundID := range hb.InboundIDs { + copy(packet[offset+i*HeartbeatPacketPeerIDSize:offset+(i+1)*HeartbeatPacketPeerIDSize], inboundID[:HeartbeatPacketPeerIDSize]) + } + + // create a buffer for tlv header plus the packet + buf := bytes.NewBuffer(make([]byte, 0, tlv.HeaderMessageDefinition.MaxBytesLength+uint16(packetSize))) + // write tlv header into buffer + if err := tlv.WriteHeader(buf, MessageTypeHeartbeat, uint16(packetSize)); err != nil { + return nil, err + } + // write serialized packet bytes into the buffer + if err := binary.Write(buf, binary.BigEndian, packet); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} diff --git a/plugins/analysis/packet/heartbeat_test.go b/plugins/analysis/packet/heartbeat_test.go new file mode 100644 index 0000000000000000000000000000000000000000..53d02b7d49d255048d67392f32314b9ef0bf5ce1 --- /dev/null +++ b/plugins/analysis/packet/heartbeat_test.go @@ -0,0 +1,232 @@ +package packet_test + +import ( + "crypto/sha256" + "errors" + "testing" + + . "github.com/iotaledger/goshimmer/plugins/analysis/packet" + "github.com/iotaledger/hive.go/protocol/tlv" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ownID = sha256.Sum256([]byte{'A'}) + +func TestNewHeartbeatMessage(t *testing.T) { + testCases := []struct { + hb *Heartbeat + err error + }{ + // ok, packet with max inbound/outbound peer IDs + { + hb: func() *Heartbeat { + outboundIDs := make([][]byte, HeartbeatMaxOutboundPeersCount) + inboundIDs := make([][]byte, HeartbeatMaxInboundPeersCount) + for i := 0; i < HeartbeatMaxOutboundPeersCount; i++ { + outboundID := sha256.Sum256([]byte{byte(i)}) + inboundID := sha256.Sum256([]byte{byte(i + HeartbeatMaxOutboundPeersCount)}) + outboundIDs[i] = outboundID[:] + inboundIDs[i] = inboundID[:] + } + return &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: inboundIDs} + }(), + err: nil, + }, + // ok, packet with only inbound peer IDs + { + hb: func() *Heartbeat { + outboundIDs := make([][]byte, 0) + inboundIDs := make([][]byte, HeartbeatMaxInboundPeersCount) + for i := 0; i < HeartbeatMaxInboundPeersCount; i++ { + inboundID := sha256.Sum256([]byte{byte(i)}) + inboundIDs[i] = inboundID[:] + } + return &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: inboundIDs} + }(), + err: nil, + }, + // ok, packet with no peer IDs (excluding own ID) is legit too + { + hb: func() *Heartbeat { + outboundIDs := make([][]byte, 0) + inboundIDs := make([][]byte, 0) + return &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: inboundIDs} + }(), + err: nil, + }, + // err, has no own peer ID + { + hb: func() *Heartbeat { + return &Heartbeat{OwnID: nil, OutboundIDs: make([][]byte, 0), InboundIDs: make([][]byte, 0)} + }(), + err: ErrInvalidHeartbeat, + }, + // err, outbound ID count exceeds maximum + { + hb: func() *Heartbeat { + outboundIDs := make([][]byte, 5) + for i := 0; i < len(outboundIDs); i++ { + outboundID := sha256.Sum256([]byte{byte(i)}) + outboundIDs[i] = outboundID[:] + } + return &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs} + }(), + err: ErrInvalidHeartbeat, + }, + // err, inbound ID count exceeds maximum + { + hb: func() *Heartbeat { + outboundIDs := make([][]byte, 0) + inboundIDs := make([][]byte, 5) + for i := 0; i < len(inboundIDs); i++ { + inboundID := sha256.Sum256([]byte{byte(i + 10)}) + inboundIDs[i] = inboundID[:] + } + return &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: inboundIDs} + }(), + err: ErrInvalidHeartbeat, + }, + } + + for _, testCase := range testCases { + hb := testCase.hb + serializedHb, err := NewHeartbeatMessage(hb) + tlvHeaderLength := int(tlv.HeaderMessageDefinition.MaxBytesLength) + if testCase.err != nil { + require.True(t, errors.Is(err, testCase.err)) + continue + } + + require.NoError(t, err, "heartbeat should have been serialized successfully") + assert.EqualValues(t, MessageTypeHeartbeat, serializedHb[0], "expected heartbeat message type tlv header value as first byte") + assert.EqualValues(t, hb.OwnID[:], serializedHb[tlvHeaderLength:tlvHeaderLength+HeartbeatPacketPeerIDSize], "expected own peer id to be within range of %d:%d", tlvHeaderLength, tlvHeaderLength+HeartbeatPacketPeerIDSize) + assert.EqualValues(t, len(hb.OutboundIDs), serializedHb[tlvHeaderLength+HeartbeatPacketPeerIDSize], "expected outbound IDs count of %d", len(hb.OutboundIDs)) + + // after the outbound IDs count, the outbound IDs are serialized + offset := int(tlvHeaderLength) + HeartbeatPacketMinSize + for i := 0; i < len(hb.OutboundIDs); i++ { + assert.EqualValues(t, hb.OutboundIDs[i], serializedHb[offset+i*HeartbeatPacketPeerIDSize:offset+(i+1)*HeartbeatPacketPeerIDSize], "outbound ID at the given position doesn't match") + } + + // shift to offset after outbound IDs + offset += len(hb.OutboundIDs) * HeartbeatPacketPeerIDSize + for i := 0; i < len(hb.InboundIDs); i++ { + assert.EqualValues(t, hb.InboundIDs[i], serializedHb[offset+i*HeartbeatPacketPeerIDSize:offset+(i+1)*HeartbeatPacketPeerIDSize], "inbound ID at the given position doesn't match") + } + } + +} + +func TestParseHeartbeat(t *testing.T) { + tlvHeaderLength := int(tlv.HeaderMessageDefinition.MaxBytesLength) + type testcase struct { + source []byte + expected *Heartbeat + err error + } + testCases := []testcase{ + // ok + func() testcase { + hb := &Heartbeat{OwnID: ownID[:], OutboundIDs: make([][]byte, 0), InboundIDs: make([][]byte, 0)} + // message = tlv header + packet + // ParseHeartbeat() expects only the packet, hence serializedHb[tlvHeaderLength:] + serializedHb, _ := NewHeartbeatMessage(hb) + return testcase{source: serializedHb[tlvHeaderLength:], expected: hb, err: nil} + }(), + // ok + func() testcase { + outboundIDs := make([][]byte, HeartbeatMaxOutboundPeersCount) + inboundIDs := make([][]byte, HeartbeatMaxInboundPeersCount) + for i := 0; i < HeartbeatMaxOutboundPeersCount; i++ { + outboundID := sha256.Sum256([]byte{byte(i)}) + inboundID := sha256.Sum256([]byte{byte(i + HeartbeatMaxOutboundPeersCount)}) + outboundIDs[i] = outboundID[:] + inboundIDs[i] = inboundID[:] + } + hb := &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: inboundIDs} + // message = tlv header + packet + // ParseHeartbeat() expects only the packet, hence serializedHb[tlvHeaderLength:] + serializedHb, _ := NewHeartbeatMessage(hb) + return testcase{source: serializedHb[tlvHeaderLength:], expected: hb, err: nil} + }(), + // err, exceeds max inbound peer IDs + func() testcase { + // this lets us add one more inbound peer ID at the end + outboundIDs := make([][]byte, HeartbeatMaxOutboundPeersCount-1) + inboundIDs := make([][]byte, HeartbeatMaxInboundPeersCount) + for i := 0; i < HeartbeatMaxInboundPeersCount; i++ { + inboundID := sha256.Sum256([]byte{byte(i + HeartbeatMaxOutboundPeersCount)}) + if i != HeartbeatMaxInboundPeersCount-1 { + outboundID := sha256.Sum256([]byte{byte(i)}) + outboundIDs[i] = outboundID[:] + } + inboundIDs[i] = inboundID[:] + } + hb := &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: inboundIDs} + // message = tlv header + packet + // ParseHeartbeat() expects only the packet, hence serializedHb[tlvHeaderLength:] + serializedHb, _ := NewHeartbeatMessage(hb) + // add an additional peer id + serializedHb = append(serializedHb, ownID[:]...) + return testcase{source: serializedHb[tlvHeaderLength:], expected: hb, err: ErrMalformedPacket} + }(), + // err, exceeds max outbound peer IDs + func() testcase { + outboundIDs := make([][]byte, HeartbeatMaxOutboundPeersCount) + for i := 0; i < HeartbeatMaxInboundPeersCount; i++ { + outboundID := sha256.Sum256([]byte{byte(i)}) + outboundIDs[i] = outboundID[:] + } + hb := &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: make([][]byte, 0)} + // NewHeartbeatMessage would return nil and and error for a malformed packet (too many outbound peer IDs) + // so we create a correct message(tlv header + packet) + serializedHb, _ := NewHeartbeatMessage(hb) + // and add an extra outbound ID (inbound IDs are zero) + serializedHb = append(serializedHb, ownID[:]...) + // manually overwrite outboundIDCount + serializedHb[tlvHeaderLength+HeartbeatPacketMinSize-1] = HeartbeatMaxOutboundPeersCount + 1 + return testcase{source: serializedHb[tlvHeaderLength:], expected: hb, err: ErrMalformedPacket} + }(), + // err, advertised outbound ID count is bigger than remaining data + func() testcase { + outboundIDs := make([][]byte, HeartbeatMaxOutboundPeersCount-1) + for i := 0; i < HeartbeatMaxOutboundPeersCount-1; i++ { + outboundID := sha256.Sum256([]byte{byte(i)}) + outboundIDs[i] = outboundID[:] + } + hb := &Heartbeat{OwnID: ownID[:], OutboundIDs: outboundIDs, InboundIDs: make([][]byte, 0)} + // message = tlv header + packet + // ParseHeartbeat() expects only the packet, hence serializedHb[tlvHeaderLength:] + serializedHb, _ := NewHeartbeatMessage(hb) + // we set the count to HeartbeatMaxOutboundPeersCount but we only have HeartbeatMaxOutboundPeersCount - 1 + // actually serialized in the packet + serializedHb[tlvHeaderLength+HeartbeatPacketMinSize-1] = HeartbeatMaxOutboundPeersCount + return testcase{source: serializedHb[tlvHeaderLength:], expected: nil, err: ErrMalformedPacket} + }(), + // err, doesn't reach minimum packet size + func() testcase { + return testcase{source: make([]byte, HeartbeatPacketMinSize-1), expected: nil, err: ErrMalformedPacket} + }(), + // err, exceeds maximum packet size + func() testcase { + return testcase{source: make([]byte, HeartbeatPacketMaxSize+1), expected: nil, err: ErrMalformedPacket} + }(), + // err, wrong byte length after minimum packet size offset, + // this emulates the minimum data to be correct but then the remaining bytes + // length not confirming to the size of IDs + func() testcase { + return testcase{source: make([]byte, HeartbeatPacketMinSize+4), expected: nil, err: ErrMalformedPacket} + }(), + } + + for _, testCase := range testCases { + hb, err := ParseHeartbeat(testCase.source) + if testCase.err != nil { + require.True(t, errors.Is(err, testCase.err)) + continue + } + require.NoError(t, err, "heartbeat should have been parsed successfully") + assert.EqualValues(t, *testCase.expected, *hb, "expected heartbeats to be equal") + } +} diff --git a/plugins/analysis/packet/metric_heartbeat.go b/plugins/analysis/packet/metric_heartbeat.go new file mode 100644 index 0000000000000000000000000000000000000000..8f3f0b21f089e90c50228c5dbf1a859249f3252c --- /dev/null +++ b/plugins/analysis/packet/metric_heartbeat.go @@ -0,0 +1,94 @@ +package packet + +import ( + "bytes" + "encoding/binary" + "encoding/gob" + "errors" + + "github.com/iotaledger/hive.go/protocol/message" + "github.com/iotaledger/hive.go/protocol/tlv" +) + +var ( + // ErrInvalidMetricHeartbeat is returned for invalid Metric heartbeats. + ErrInvalidMetricHeartbeat = errors.New("invalid Metric heartbeat") +) + +var ( + // MetricHeartbeatMessageDefinition defines a metric heartbeat message's format. + MetricHeartbeatMessageDefinition = &message.Definition{ + ID: MessageTypeMetricHeartbeat, + MaxBytesLength: 65535, + VariableLength: true, + } +) + +// MetricHeartbeat represents a metric heartbeat packet. +type MetricHeartbeat struct { + // The ID of the node who sent the heartbeat. + // Must be contained when a heartbeat is serialized. + OwnID []byte + // OS defines the operating system of the node. + OS string + // Arch defines the system architecture of the node. + Arch string + // NumCPU defines number of logical cores of the node. + NumCPU int + // CPUUsage defines the CPU usage of the node. + CPUUsage float64 + // MemoryUsage defines the memory usage of the node. + MemoryUsage uint64 +} + +// ParseMetricHeartbeat parses a slice of bytes (serialized packet) into a Metric heartbeat. +func ParseMetricHeartbeat(data []byte) (*MetricHeartbeat, error) { + hb := &MetricHeartbeat{} + + buf := new(bytes.Buffer) + if _, err := buf.Write(data); err != nil { + return nil, err + } + + decoder := gob.NewDecoder(buf) + if err := decoder.Decode(hb); err != nil { + return nil, err + } + + return hb, nil +} + +// Bytes return the Metric heartbeat encoded as bytes. +func (hb MetricHeartbeat) Bytes() ([]byte, error) { + buf := new(bytes.Buffer) + encoder := gob.NewEncoder(buf) + if err := encoder.Encode(hb); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// NewMetricHeartbeatMessage serializes the given Metric heartbeat into a byte slice and adds a TLV header to the packet. +// message = TLV header + serialized packet. +func NewMetricHeartbeatMessage(hb *MetricHeartbeat) ([]byte, error) { + packet, err := hb.Bytes() + if err != nil { + return nil, err + } + + // calculate total needed bytes based on packet + packetSize := len(packet) + + // create a buffer for tlv header plus the packet + buf := bytes.NewBuffer(make([]byte, 0, tlv.HeaderMessageDefinition.MaxBytesLength+uint16(packetSize))) + // write tlv header into buffer + if err := tlv.WriteHeader(buf, MessageTypeMetricHeartbeat, uint16(packetSize)); err != nil { + return nil, err + } + // write serialized packet bytes into the buffer + if err := binary.Write(buf, binary.BigEndian, packet); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} diff --git a/plugins/analysis/packet/metric_heartbeat_test.go b/plugins/analysis/packet/metric_heartbeat_test.go new file mode 100644 index 0000000000000000000000000000000000000000..c32d9320f9db47d0c5dbbe1e54312bf6b4225e8b --- /dev/null +++ b/plugins/analysis/packet/metric_heartbeat_test.go @@ -0,0 +1,58 @@ +package packet + +import ( + "crypto/sha256" + "runtime" + "testing" + "time" + + "github.com/iotaledger/hive.go/protocol/message" + "github.com/iotaledger/hive.go/protocol/tlv" + "github.com/shirou/gopsutil/cpu" + "github.com/stretchr/testify/require" +) + +var nodeID = sha256.Sum256([]byte{'A'}) + +func testMetricHeartbeat() *MetricHeartbeat { + return &MetricHeartbeat{ + OwnID: nodeID[:], + OS: runtime.GOOS, + Arch: runtime.GOARCH, + NumCPU: runtime.GOMAXPROCS(0), + CPUUsage: func() (p float64) { + percent, err := cpu.Percent(time.Second, false) + if err == nil { + p = percent[0] + } + return + }(), + MemoryUsage: func() uint64 { + var m runtime.MemStats + runtime.ReadMemStats(&m) + return m.Alloc + }(), + } +} + +func TestMetricHeartbeat(t *testing.T) { + hb := testMetricHeartbeat() + + packet, err := hb.Bytes() + require.NoError(t, err) + + hbParsed, err := ParseMetricHeartbeat(packet) + require.NoError(t, err) + + require.Equal(t, hb, hbParsed) + + tlvHeaderLength := int(tlv.HeaderMessageDefinition.MaxBytesLength) + msg, err := NewMetricHeartbeatMessage(hb) + require.NoError(t, err) + + require.Equal(t, MessageTypeMetricHeartbeat, message.Type(msg[0])) + + hbParsed, err = ParseMetricHeartbeat(msg[tlvHeaderLength:]) + require.NoError(t, err) + require.Equal(t, hb, hbParsed) +} diff --git a/plugins/analysis/packet/packet.go b/plugins/analysis/packet/packet.go new file mode 100644 index 0000000000000000000000000000000000000000..cf5a9740e76a85dab4c378f3f1de2609e0b9870f --- /dev/null +++ b/plugins/analysis/packet/packet.go @@ -0,0 +1,37 @@ +package packet + +import ( + "errors" + "sync" + + "github.com/iotaledger/hive.go/protocol/message" + "github.com/iotaledger/hive.go/protocol/tlv" +) + +var ( + // ErrMalformedPacket is returned when malformed packets are tried to be parsed. + ErrMalformedPacket = errors.New("malformed packet") +) + +var ( + // analysisMsgRegistry holds all message definitions for analysis server related messages + analysisMsgRegistry *message.Registry + fpcHeartBeatOnce sync.Once + heartBeatOnce sync.Once +) + +func init() { + // message definitions to be registered in registry + definitions := []*message.Definition{ + tlv.HeaderMessageDefinition, + HeartBeatMessageDefinition(), + FPCHeartbeatMessageDefinition(), + MetricHeartbeatMessageDefinition, + } + analysisMsgRegistry = message.NewRegistry(definitions) +} + +// AnalysisMsgRegistry gets the analysisMsgRegistry. +func AnalysisMsgRegistry() *message.Registry { + return analysisMsgRegistry +} diff --git a/plugins/analysis/packet/types.go b/plugins/analysis/packet/types.go new file mode 100644 index 0000000000000000000000000000000000000000..c0ae21d4cd236b12028133e0981ee7c29de4f5d5 --- /dev/null +++ b/plugins/analysis/packet/types.go @@ -0,0 +1,12 @@ +package packet + +import "github.com/iotaledger/hive.go/protocol/message" + +const ( + // MessageTypeHeartbeat defines the Heartbeat msg type. + MessageTypeHeartbeat message.Type = iota + 1 + // MessageTypeFPCHeartbeat defines the FPC Heartbeat msg type. + MessageTypeFPCHeartbeat + // MessageTypeMetricHeartbeat defines the Metric Heartbeat msg type. + MessageTypeMetricHeartbeat +) diff --git a/plugins/analysis/plugin.go b/plugins/analysis/plugin.go deleted file mode 100644 index 1dc75fff1e3613bdd05dbced7c3bc4e832109a9a..0000000000000000000000000000000000000000 --- a/plugins/analysis/plugin.go +++ /dev/null @@ -1,36 +0,0 @@ -package analysis - -import ( - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/goshimmer/plugins/analysis/client" - "github.com/iotaledger/goshimmer/plugins/analysis/server" - "github.com/iotaledger/goshimmer/plugins/analysis/webinterface" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" -) - -var PLUGIN = node.NewPlugin("Analysis", node.Enabled, configure, run) -var log *logger.Logger - -func configure(plugin *node.Plugin) { - log = logger.NewLogger("Analysis") - if parameter.NodeConfig.GetInt(server.CFG_SERVER_PORT) != 0 { - webinterface.Configure(plugin) - server.Configure(plugin) - } -} - -func run(plugin *node.Plugin) { - if parameter.NodeConfig.GetInt(server.CFG_SERVER_PORT) != 0 { - webinterface.Run(plugin) - server.Run(plugin) - } else { - log.Info("Server is disabled (server-port is 0)") - } - - if parameter.NodeConfig.GetString(client.CFG_SERVER_ADDRESS) != "" { - client.Run(plugin) - } else { - log.Info("Client is disabled (server-address is empty)") - } -} diff --git a/plugins/analysis/server/constants.go b/plugins/analysis/server/constants.go deleted file mode 100644 index b4c1f739dd4a89df83743403082fcf930e553634..0000000000000000000000000000000000000000 --- a/plugins/analysis/server/constants.go +++ /dev/null @@ -1,24 +0,0 @@ -package server - -import ( - "time" - - "github.com/iotaledger/goshimmer/plugins/analysis/types/addnode" - "github.com/iotaledger/goshimmer/plugins/analysis/types/connectnodes" - "github.com/iotaledger/goshimmer/plugins/analysis/types/disconnectnodes" - "github.com/iotaledger/goshimmer/plugins/analysis/types/ping" - "github.com/iotaledger/goshimmer/plugins/analysis/types/removenode" -) - -const ( - IDLE_TIMEOUT = 5 * time.Second - - STATE_INITIAL = byte(255) - STATE_INITIAL_ADDNODE = byte(254) - STATE_CONSECUTIVE = byte(253) - STATE_PING = ping.MARSHALED_PACKET_HEADER - STATE_ADD_NODE = addnode.MARSHALED_PACKET_HEADER - STATE_REMOVE_NODE = removenode.MARSHALED_PACKET_HEADER - STATE_CONNECT_NODES = connectnodes.MARSHALED_PACKET_HEADER - STATE_DISCONNECT_NODES = disconnectnodes.MARSHALED_PACKET_HEADER -) diff --git a/plugins/analysis/server/events.go b/plugins/analysis/server/events.go index 979dddec563888fc68a2c18a572a8f3f83741d83..75828e1f8de203a8f0d6ff05089a4501b5a6b91a 100644 --- a/plugins/analysis/server/events.go +++ b/plugins/analysis/server/events.go @@ -1,31 +1,59 @@ package server import ( + "github.com/iotaledger/goshimmer/plugins/analysis/packet" "github.com/iotaledger/hive.go/events" ) +// Events holds the events of the analysis server package. var Events = struct { - AddNode *events.Event - RemoveNode *events.Event - ConnectNodes *events.Event + // AddNode triggers when adding a new node. + AddNode *events.Event + // RemoveNode triggers when removing a node. + RemoveNode *events.Event + // ConnectNodes triggers when connecting two nodes. + ConnectNodes *events.Event + // DisconnectNodes triggers when disconnecting two nodes. DisconnectNodes *events.Event - NodeOnline *events.Event - NodeOffline *events.Event - Error *events.Event + // Error triggers when an error occurs. + Error *events.Event + // Heartbeat triggers when an heartbeat has been received. + Heartbeat *events.Event + // FPCHeartbeat triggers when an FPC heartbeat has been received. + FPCHeartbeat *events.Event + // MetricHeartbeat triggers when an MetricHeartbeat heartbeat has been received. + MetricHeartbeat *events.Event }{ events.NewEvent(stringCaller), events.NewEvent(stringCaller), events.NewEvent(stringStringCaller), events.NewEvent(stringStringCaller), - events.NewEvent(stringCaller), - events.NewEvent(stringCaller), events.NewEvent(errorCaller), + events.NewEvent(heartbeatPacketCaller), + events.NewEvent(fpcHeartbeatPacketCaller), + events.NewEvent(metricHeartbeatPacketCaller), } func stringCaller(handler interface{}, params ...interface{}) { handler.(func(string))(params[0].(string)) } + func stringStringCaller(handler interface{}, params ...interface{}) { handler.(func(string, string))(params[0].(string), params[1].(string)) } -func errorCaller(handler interface{}, params ...interface{}) { handler.(func(error))(params[0].(error)) } + +func errorCaller(handler interface{}, params ...interface{}) { + handler.(func(error))(params[0].(error)) +} + +func heartbeatPacketCaller(handler interface{}, params ...interface{}) { + handler.(func(heartbeat *packet.Heartbeat))(params[0].(*packet.Heartbeat)) +} + +func fpcHeartbeatPacketCaller(handler interface{}, params ...interface{}) { + handler.(func(hb *packet.FPCHeartbeat))(params[0].(*packet.FPCHeartbeat)) +} + +func metricHeartbeatPacketCaller(handler interface{}, params ...interface{}) { + handler.(func(hb *packet.MetricHeartbeat))(params[0].(*packet.MetricHeartbeat)) +} diff --git a/plugins/analysis/server/parameters.go b/plugins/analysis/server/parameters.go deleted file mode 100644 index a8d66903b7079edcfd7d0b87f0ed154366327dfa..0000000000000000000000000000000000000000 --- a/plugins/analysis/server/parameters.go +++ /dev/null @@ -1,13 +0,0 @@ -package server - -import ( - flag "github.com/spf13/pflag" -) - -const ( - CFG_SERVER_PORT = "analysis.server.port" -) - -func init() { - flag.Int(CFG_SERVER_PORT, 0, "tcp port for incoming analysis packets") -} diff --git a/plugins/analysis/server/plugin.go b/plugins/analysis/server/plugin.go index 215eefa19743648dbc073eacd69b164f686f81f4..6c7173fc3828adca685ff7541a74ec4710866191 100644 --- a/plugins/analysis/server/plugin.go +++ b/plugins/analysis/server/plugin.go @@ -1,349 +1,162 @@ package server import ( - "encoding/hex" - "errors" - "math" + "io" + "net" + "strconv" + "strings" + "sync" + "time" - "github.com/iotaledger/goshimmer/packages/parameter" "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/analysis/types/addnode" - "github.com/iotaledger/goshimmer/plugins/analysis/types/connectnodes" - "github.com/iotaledger/goshimmer/plugins/analysis/types/disconnectnodes" - "github.com/iotaledger/goshimmer/plugins/analysis/types/ping" - "github.com/iotaledger/goshimmer/plugins/analysis/types/removenode" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/events" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/network" "github.com/iotaledger/hive.go/network/tcp" "github.com/iotaledger/hive.go/node" + "github.com/iotaledger/hive.go/protocol" + flag "github.com/spf13/pflag" ) -var ( - ErrInvalidPackageHeader = errors.New("invalid package header") - ErrExpectedInitialAddNodePackage = errors.New("expected initial add node package") - server *tcp.TCPServer - log *logger.Logger -) +const ( + // PluginName is the name of the analysis server plugin. + PluginName = "Analysis-Server" -func Configure(plugin *node.Plugin) { - log = logger.NewLogger("Analysis-Server") - server = tcp.NewServer() + // CfgAnalysisServerBindAddress defines the bind address of the analysis server. + CfgAnalysisServerBindAddress = "analysis.server.bindAddress" - server.Events.Connect.Attach(events.NewClosure(HandleConnection)) - server.Events.Error.Attach(events.NewClosure(func(err error) { - log.Errorf("error in server: %s", err.Error()) - })) - server.Events.Start.Attach(events.NewClosure(func() { - log.Infof("Starting Server (port %d) ... done", parameter.NodeConfig.GetInt(CFG_SERVER_PORT)) - })) - server.Events.Shutdown.Attach(events.NewClosure(func() { - log.Info("Stopping Server ... done") - })) -} - -func Run(plugin *node.Plugin) { - daemon.BackgroundWorker("Analysis Server", func(shutdownSignal <-chan struct{}) { - log.Infof("Starting Server (port %d) ... done", parameter.NodeConfig.GetInt(CFG_SERVER_PORT)) - go server.Listen("0.0.0.0", parameter.NodeConfig.GetInt(CFG_SERVER_PORT)) - <-shutdownSignal - Shutdown() - }, shutdown.ShutdownPriorityAnalysis) -} + // IdleTimeout defines the idle timeout of the read from the client's connection. + IdleTimeout = 1 * time.Minute +) -func Shutdown() { - log.Info("Stopping Server ...") - server.Shutdown() - log.Info("Stopping Server ... done") +func init() { + flag.String(CfgAnalysisServerBindAddress, "0.0.0.0:16178", "the bind address of the analysis server") } -func HandleConnection(conn *network.ManagedConnection) { - conn.SetTimeout(IDLE_TIMEOUT) - - var connectionState = STATE_INITIAL - var receiveBuffer []byte - var offset int - var connectedNodeId string - - var onDisconnect *events.Closure - - onReceiveData := events.NewClosure(func(data []byte) { - processIncomingPacket(&connectionState, &receiveBuffer, conn, data, &offset, &connectedNodeId) - }) - onDisconnect = events.NewClosure(func() { - Events.NodeOffline.Trigger(connectedNodeId) +var ( + // plugin is the plugin instance of the analysis server plugin. + plugin *node.Plugin + once sync.Once + server *tcp.TCPServer + prot *protocol.Protocol + log *logger.Logger +) - conn.Events.ReceiveData.Detach(onReceiveData) - conn.Events.Close.Detach(onDisconnect) +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) }) - - conn.Events.ReceiveData.Attach(onReceiveData) - conn.Events.Close.Attach(onDisconnect) - - maxPacketsSize := getMaxPacketSize( - ping.MARSHALED_TOTAL_SIZE, - addnode.MARSHALED_TOTAL_SIZE, - removenode.MARSHALED_TOTAL_SIZE, - connectnodes.MARSHALED_TOTAL_SIZE, - disconnectnodes.MARSHALED_PACKET_HEADER, - ) - - go conn.Read(make([]byte, maxPacketsSize)) + return plugin } -func getMaxPacketSize(packetSizes ...int) int { - maxPacketSize := 0 - - for _, packetSize := range packetSizes { - if packetSize > maxPacketSize { - maxPacketSize = packetSize - } - } +func configure(_ *node.Plugin) { + log = logger.NewLogger(PluginName) + server = tcp.NewServer() - return maxPacketSize + server.Events.Connect.Attach(events.NewClosure(HandleConnection)) + server.Events.Error.Attach(events.NewClosure(func(err error) { + log.Errorf("error in server: %s", err.Error()) + })) } -func processIncomingPacket(connectionState *byte, receiveBuffer *[]byte, conn *network.ManagedConnection, data []byte, offset *int, connectedNodeId *string) { - firstPackage := *connectionState == STATE_INITIAL - - if firstPackage || *connectionState == STATE_CONSECUTIVE { - var err error - if *connectionState, *receiveBuffer, err = parsePackageHeader(data); err != nil { - Events.Error.Trigger(err) - - conn.Close() - - return - } - - *offset = 0 - - switch *connectionState { - case STATE_ADD_NODE: - *receiveBuffer = make([]byte, addnode.MARSHALED_TOTAL_SIZE) - - case STATE_PING: - *receiveBuffer = make([]byte, ping.MARSHALED_TOTAL_SIZE) - - case STATE_CONNECT_NODES: - *receiveBuffer = make([]byte, connectnodes.MARSHALED_TOTAL_SIZE) - - case STATE_DISCONNECT_NODES: - *receiveBuffer = make([]byte, disconnectnodes.MARSHALED_TOTAL_SIZE) - - case STATE_REMOVE_NODE: - *receiveBuffer = make([]byte, removenode.MARSHALED_TOTAL_SIZE) - } +func run(_ *node.Plugin) { + bindAddr := config.Node().GetString(CfgAnalysisServerBindAddress) + addr, portStr, err := net.SplitHostPort(bindAddr) + if err != nil { + log.Fatal("invalid bind address in %s: %s", CfgAnalysisServerBindAddress, err) } - - if firstPackage { - if *connectionState != STATE_ADD_NODE { - Events.Error.Trigger(ErrExpectedInitialAddNodePackage) - } else { - *connectionState = STATE_INITIAL_ADDNODE - } + port, err := strconv.Atoi(portStr) + if err != nil { + log.Fatal("invalid port in %s: %s", CfgAnalysisServerBindAddress, err) } - switch *connectionState { - case STATE_INITIAL_ADDNODE: - processIncomingAddNodePacket(connectionState, receiveBuffer, conn, data, offset, connectedNodeId) - - case STATE_ADD_NODE: - processIncomingAddNodePacket(connectionState, receiveBuffer, conn, data, offset, connectedNodeId) - - case STATE_PING: - processIncomingPingPacket(connectionState, receiveBuffer, conn, data, offset, connectedNodeId) + if err := daemon.BackgroundWorker(PluginName, func(shutdownSignal <-chan struct{}) { + log.Infof("%s started, bind-address=%s", PluginName, bindAddr) + defer log.Infof("Stopping %s ... done", PluginName) - case STATE_CONNECT_NODES: - processIncomingConnectNodesPacket(connectionState, receiveBuffer, conn, data, offset, connectedNodeId) + // connect protocol events to processors + prot = protocol.New(packet.AnalysisMsgRegistry()) + wireUp(prot) - case STATE_DISCONNECT_NODES: - processIncomingDisconnectNodesPacket(connectionState, receiveBuffer, conn, data, offset, connectedNodeId) + go server.Listen(addr, port) - case STATE_REMOVE_NODE: - processIncomingRemoveNodePacket(connectionState, receiveBuffer, conn, data, offset, connectedNodeId) + <-shutdownSignal + log.Info("Stopping Server ...") + server.Shutdown() + }, shutdown.PriorityAnalysis); err != nil { + log.Panicf("Failed to start as daemon: %s", err) } } -func parsePackageHeader(data []byte) (ConnectionState, []byte, error) { - var connectionState ConnectionState - var receiveBuffer []byte - - switch data[0] { - case ping.MARSHALED_PACKET_HEADER: - receiveBuffer = make([]byte, ping.MARSHALED_TOTAL_SIZE) - - connectionState = STATE_PING - - case addnode.MARSHALED_PACKET_HEADER: - receiveBuffer = make([]byte, addnode.MARSHALED_TOTAL_SIZE) - - connectionState = STATE_ADD_NODE - - case connectnodes.MARSHALED_PACKET_HEADER: - receiveBuffer = make([]byte, connectnodes.MARSHALED_TOTAL_SIZE) - - connectionState = STATE_CONNECT_NODES - - case disconnectnodes.MARSHALED_PACKET_HEADER: - receiveBuffer = make([]byte, disconnectnodes.MARSHALED_TOTAL_SIZE) - - connectionState = STATE_DISCONNECT_NODES - - case removenode.MARSHALED_PACKET_HEADER: - receiveBuffer = make([]byte, removenode.MARSHALED_TOTAL_SIZE) - - connectionState = STATE_REMOVE_NODE - - default: - return 0, nil, ErrInvalidPackageHeader +// HandleConnection handles the given connection. +func HandleConnection(conn *network.ManagedConnection) { + if err := conn.SetReadTimeout(IdleTimeout); err != nil { + log.Warnw("Error setting read timeout; closing connection", "err", err) + _ = conn.Close() + return } - - return connectionState, receiveBuffer, nil -} - -func processIncomingAddNodePacket(connectionState *byte, receiveBuffer *[]byte, conn *network.ManagedConnection, data []byte, offset *int, connectedNodeId *string) { - remainingCapacity := int(math.Min(float64(addnode.MARSHALED_TOTAL_SIZE-*offset), float64(len(data)))) - - copy((*receiveBuffer)[*offset:], data[:remainingCapacity]) - - if *offset+len(data) < addnode.MARSHALED_TOTAL_SIZE { - *offset += len(data) - } else { - if addNodePacket, err := addnode.Unmarshal(*receiveBuffer); err != nil { - Events.Error.Trigger(err) - - conn.Close() - - return - } else { - nodeId := hex.EncodeToString(addNodePacket.NodeId) - - Events.AddNode.Trigger(nodeId) - - if *connectionState == STATE_INITIAL_ADDNODE { - *connectedNodeId = nodeId - - Events.NodeOnline.Trigger(nodeId) - } + onReceiveData := events.NewClosure(func(data []byte) { + if _, err := prot.Read(data); err != nil { + log.Debugw("Invalid message received; closing connection", "err", err) + _ = conn.Close() } - - *connectionState = STATE_CONSECUTIVE - - if *offset+len(data) > addnode.MARSHALED_TOTAL_SIZE { - processIncomingPacket(connectionState, receiveBuffer, conn, data[remainingCapacity:], offset, connectedNodeId) + }) + conn.Events.ReceiveData.Attach(onReceiveData) + // starts the protocol and reads from its connection + go func() { + buffer := make([]byte, 2048) + _, err := conn.Read(buffer) + if err != nil && err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") { + log.Warnw("Read error", "err", err) } - } + // always close the connection when we've stopped reading from it + _ = conn.Close() + }() } -func processIncomingPingPacket(connectionState *byte, receiveBuffer *[]byte, conn *network.ManagedConnection, data []byte, offset *int, connectedNodeId *string) { - remainingCapacity := int(math.Min(float64(ping.MARSHALED_TOTAL_SIZE-*offset), float64(len(data)))) - - copy((*receiveBuffer)[*offset:], data[:remainingCapacity]) - - if *offset+len(data) < ping.MARSHALED_TOTAL_SIZE { - *offset += len(data) - } else { - if _, err := ping.Unmarshal(*receiveBuffer); err != nil { - Events.Error.Trigger(err) - - conn.Close() - - return - } - - *connectionState = STATE_CONSECUTIVE - - if *offset+len(data) > ping.MARSHALED_TOTAL_SIZE { - processIncomingPacket(connectionState, receiveBuffer, conn, data[remainingCapacity:], offset, connectedNodeId) - } - } +// wireUp connects the Received events of the protocol to the packet specific processor. +func wireUp(p *protocol.Protocol) { + p.Events.Received[packet.MessageTypeHeartbeat].Attach(events.NewClosure(func(data []byte) { + processHeartbeatPacket(data) + })) + p.Events.Received[packet.MessageTypeFPCHeartbeat].Attach(events.NewClosure(func(data []byte) { + processFPCHeartbeatPacket(data) + })) + p.Events.Received[packet.MessageTypeMetricHeartbeat].Attach(events.NewClosure(func(data []byte) { + processMetricHeartbeatPacket(data) + })) } -func processIncomingConnectNodesPacket(connectionState *byte, receiveBuffer *[]byte, conn *network.ManagedConnection, data []byte, offset *int, connectedNodeId *string) { - remainingCapacity := int(math.Min(float64(connectnodes.MARSHALED_TOTAL_SIZE-*offset), float64(len(data)))) - - copy((*receiveBuffer)[*offset:], data[:remainingCapacity]) - - if *offset+len(data) < connectnodes.MARSHALED_TOTAL_SIZE { - *offset += len(data) - } else { - if connectNodesPacket, err := connectnodes.Unmarshal(*receiveBuffer); err != nil { - Events.Error.Trigger(err) - - conn.Close() - - return - } else { - sourceNodeId := hex.EncodeToString(connectNodesPacket.SourceId) - targetNodeId := hex.EncodeToString(connectNodesPacket.TargetId) - - Events.ConnectNodes.Trigger(sourceNodeId, targetNodeId) - } - - *connectionState = STATE_CONSECUTIVE - - if *offset+len(data) > connectnodes.MARSHALED_TOTAL_SIZE { - processIncomingPacket(connectionState, receiveBuffer, conn, data[remainingCapacity:], offset, connectedNodeId) - } +// processHeartbeatPacket parses the serialized data into a Heartbeat packet and triggers its event. +func processHeartbeatPacket(data []byte) { + heartbeatPacket, err := packet.ParseHeartbeat(data) + if err != nil { + Events.Error.Trigger(err) + return } + Events.Heartbeat.Trigger(heartbeatPacket) } -func processIncomingDisconnectNodesPacket(connectionState *byte, receiveBuffer *[]byte, conn *network.ManagedConnection, data []byte, offset *int, connectedNodeId *string) { - remainingCapacity := int(math.Min(float64(disconnectnodes.MARSHALED_TOTAL_SIZE-*offset), float64(len(data)))) - - copy((*receiveBuffer)[*offset:], data[:remainingCapacity]) - - if *offset+len(data) < disconnectnodes.MARSHALED_TOTAL_SIZE { - *offset += len(data) - } else { - if disconnectNodesPacket, err := disconnectnodes.Unmarshal(*receiveBuffer); err != nil { - Events.Error.Trigger(err) - - conn.Close() - - return - } else { - sourceNodeId := hex.EncodeToString(disconnectNodesPacket.SourceId) - targetNodeId := hex.EncodeToString(disconnectNodesPacket.TargetId) - - Events.DisconnectNodes.Trigger(sourceNodeId, targetNodeId) - } - - *connectionState = STATE_CONSECUTIVE - - if *offset+len(data) > disconnectnodes.MARSHALED_TOTAL_SIZE { - processIncomingPacket(connectionState, receiveBuffer, conn, data[remainingCapacity:], offset, connectedNodeId) - } +// processHeartbeatPacket parses the serialized data into a FPC Heartbeat packet and triggers its event. +func processFPCHeartbeatPacket(data []byte) { + hb, err := packet.ParseFPCHeartbeat(data) + if err != nil { + Events.Error.Trigger(err) + return } + Events.FPCHeartbeat.Trigger(hb) } -func processIncomingRemoveNodePacket(connectionState *byte, receiveBuffer *[]byte, conn *network.ManagedConnection, data []byte, offset *int, connectedNodeId *string) { - remainingCapacity := int(math.Min(float64(removenode.MARSHALED_TOTAL_SIZE-*offset), float64(len(data)))) - - copy((*receiveBuffer)[*offset:], data[:remainingCapacity]) - - if *offset+len(data) < removenode.MARSHALED_TOTAL_SIZE { - *offset += len(data) - } else { - if removeNodePacket, err := removenode.Unmarshal(*receiveBuffer); err != nil { - Events.Error.Trigger(err) - - conn.Close() - - return - } else { - nodeId := hex.EncodeToString(removeNodePacket.NodeId) - - Events.RemoveNode.Trigger(nodeId) - - } - - *connectionState = STATE_CONSECUTIVE - - if *offset+len(data) > addnode.MARSHALED_TOTAL_SIZE { - processIncomingPacket(connectionState, receiveBuffer, conn, data[remainingCapacity:], offset, connectedNodeId) - } +// processMetricHeartbeatPacket parses the serialized data into a Metric Heartbeat packet and triggers its event. +func processMetricHeartbeatPacket(data []byte) { + hb, err := packet.ParseMetricHeartbeat(data) + if err != nil { + Events.Error.Trigger(err) + return } + Events.MetricHeartbeat.Trigger(hb) } diff --git a/plugins/analysis/server/types.go b/plugins/analysis/server/types.go deleted file mode 100644 index 2dd1e29a5bde698bb18b5036d27584637e84ac1a..0000000000000000000000000000000000000000 --- a/plugins/analysis/server/types.go +++ /dev/null @@ -1,3 +0,0 @@ -package server - -type ConnectionState = byte diff --git a/plugins/analysis/types/addnode/constants.go b/plugins/analysis/types/addnode/constants.go deleted file mode 100644 index a112e89aa7550521b7dd59e85e6862e8e9facf3c..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/addnode/constants.go +++ /dev/null @@ -1,17 +0,0 @@ -package addnode - -import "crypto/sha256" - -const ( - MARSHALED_PACKET_HEADER = 0x01 - - MARSHALED_PACKET_HEADER_START = 0 - MARSHALED_PACKET_HEADER_SIZE = 1 - MARSHALED_PACKET_HEADER_END = MARSHALED_PACKET_HEADER_START + MARSHALED_PACKET_HEADER_SIZE - - MARSHALED_ID_START = MARSHALED_PACKET_HEADER_END - MARSHALED_ID_SIZE = sha256.Size - MARSHALED_ID_END = MARSHALED_ID_START + MARSHALED_ID_SIZE - - MARSHALED_TOTAL_SIZE = MARSHALED_ID_END -) diff --git a/plugins/analysis/types/addnode/packet.go b/plugins/analysis/types/addnode/packet.go deleted file mode 100644 index da2ba9925b765ba15835f694d9d8c287f0c0a361..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/addnode/packet.go +++ /dev/null @@ -1,34 +0,0 @@ -package addnode - -import "errors" - -var ( - ErrMalformedAddNodePacket = errors.New("malformed add node packet") -) - -type Packet struct { - NodeId []byte -} - -func Unmarshal(data []byte) (*Packet, error) { - if len(data) < MARSHALED_TOTAL_SIZE || data[0] != MARSHALED_PACKET_HEADER { - return nil, ErrMalformedAddNodePacket - } - - unmarshaledPackage := &Packet{ - NodeId: make([]byte, MARSHALED_ID_SIZE), - } - - copy(unmarshaledPackage.NodeId, data[MARSHALED_ID_START:MARSHALED_ID_END]) - - return unmarshaledPackage, nil -} - -func (packet *Packet) Marshal() []byte { - marshaledPackage := make([]byte, MARSHALED_TOTAL_SIZE) - - marshaledPackage[MARSHALED_PACKET_HEADER_START] = MARSHALED_PACKET_HEADER - copy(marshaledPackage[MARSHALED_ID_START:MARSHALED_ID_END], packet.NodeId[:MARSHALED_ID_SIZE]) - - return marshaledPackage -} diff --git a/plugins/analysis/types/connectnodes/constants.go b/plugins/analysis/types/connectnodes/constants.go deleted file mode 100644 index 09889329a44e0c98c8207eb1cc8d6a0175c7ef0b..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/connectnodes/constants.go +++ /dev/null @@ -1,21 +0,0 @@ -package connectnodes - -import "crypto/sha256" - -const ( - MARSHALED_PACKET_HEADER = 0x03 - - MARSHALED_PACKET_HEADER_START = 0 - MARSHALED_PACKET_HEADER_SIZE = 1 - MARSHALED_PACKET_HEADER_END = MARSHALED_PACKET_HEADER_START + MARSHALED_PACKET_HEADER_SIZE - - MARSHALED_SOURCE_ID_START = MARSHALED_PACKET_HEADER_END - MARSHALED_SOURCE_ID_SIZE = sha256.Size - MARSHALED_SOURCE_ID_END = MARSHALED_SOURCE_ID_START + MARSHALED_SOURCE_ID_SIZE - - MARSHALED_TARGET_ID_START = MARSHALED_SOURCE_ID_END - MARSHALED_TARGET_ID_SIZE = sha256.Size - MARSHALED_TARGET_ID_END = MARSHALED_TARGET_ID_START + MARSHALED_TARGET_ID_SIZE - - MARSHALED_TOTAL_SIZE = MARSHALED_TARGET_ID_END -) diff --git a/plugins/analysis/types/connectnodes/packet.go b/plugins/analysis/types/connectnodes/packet.go deleted file mode 100644 index 1e672c3ad4a5714ca390f2289155b1cc39585f04..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/connectnodes/packet.go +++ /dev/null @@ -1,38 +0,0 @@ -package connectnodes - -import "errors" - -var ( - ErrMalformedConnectNodesPacket = errors.New("malformed connect nodes packet") -) - -type Packet struct { - SourceId []byte - TargetId []byte -} - -func Unmarshal(data []byte) (*Packet, error) { - if len(data) < MARSHALED_TOTAL_SIZE || data[0] != MARSHALED_PACKET_HEADER { - return nil, ErrMalformedConnectNodesPacket - } - - unmarshaledPackage := &Packet{ - SourceId: make([]byte, MARSHALED_SOURCE_ID_SIZE), - TargetId: make([]byte, MARSHALED_TARGET_ID_SIZE), - } - - copy(unmarshaledPackage.SourceId, data[MARSHALED_SOURCE_ID_START:MARSHALED_SOURCE_ID_END]) - copy(unmarshaledPackage.TargetId, data[MARSHALED_TARGET_ID_START:MARSHALED_TARGET_ID_END]) - - return unmarshaledPackage, nil -} - -func (packet *Packet) Marshal() []byte { - marshaledPackage := make([]byte, MARSHALED_TOTAL_SIZE) - - marshaledPackage[MARSHALED_PACKET_HEADER_START] = MARSHALED_PACKET_HEADER - copy(marshaledPackage[MARSHALED_SOURCE_ID_START:MARSHALED_SOURCE_ID_END], packet.SourceId[:MARSHALED_SOURCE_ID_SIZE]) - copy(marshaledPackage[MARSHALED_TARGET_ID_START:MARSHALED_TARGET_ID_END], packet.TargetId[:MARSHALED_TARGET_ID_SIZE]) - - return marshaledPackage -} diff --git a/plugins/analysis/types/disconnectnodes/constants.go b/plugins/analysis/types/disconnectnodes/constants.go deleted file mode 100644 index adf347455bccef6bebdac55f671930bd86289ad3..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/disconnectnodes/constants.go +++ /dev/null @@ -1,21 +0,0 @@ -package disconnectnodes - -import "crypto/sha256" - -const ( - MARSHALED_PACKET_HEADER = 0x04 - - MARSHALED_PACKET_HEADER_START = 0 - MARSHALED_PACKET_HEADER_SIZE = 1 - MARSHALED_PACKET_HEADER_END = MARSHALED_PACKET_HEADER_START + MARSHALED_PACKET_HEADER_SIZE - - MARSHALED_SOURCE_ID_START = MARSHALED_PACKET_HEADER_END - MARSHALED_SOURCE_ID_SIZE = sha256.Size - MARSHALED_SOURCE_ID_END = MARSHALED_SOURCE_ID_START + MARSHALED_SOURCE_ID_SIZE - - MARSHALED_TARGET_ID_START = MARSHALED_SOURCE_ID_END - MARSHALED_TARGET_ID_SIZE = sha256.Size - MARSHALED_TARGET_ID_END = MARSHALED_TARGET_ID_START + MARSHALED_TARGET_ID_SIZE - - MARSHALED_TOTAL_SIZE = MARSHALED_TARGET_ID_END -) diff --git a/plugins/analysis/types/disconnectnodes/packet.go b/plugins/analysis/types/disconnectnodes/packet.go deleted file mode 100644 index b810fa8fefa0a53d56facc09c03a3e2d48805f84..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/disconnectnodes/packet.go +++ /dev/null @@ -1,38 +0,0 @@ -package disconnectnodes - -import "errors" - -var ( - ErrMalformedDisconnectNodesPacket = errors.New("malformed disconnect nodes packet") -) - -type Packet struct { - SourceId []byte - TargetId []byte -} - -func Unmarshal(data []byte) (*Packet, error) { - if len(data) < MARSHALED_TOTAL_SIZE || data[0] != MARSHALED_PACKET_HEADER { - return nil, ErrMalformedDisconnectNodesPacket - } - - unmarshaledPackage := &Packet{ - SourceId: make([]byte, MARSHALED_SOURCE_ID_SIZE), - TargetId: make([]byte, MARSHALED_TARGET_ID_SIZE), - } - - copy(unmarshaledPackage.SourceId, data[MARSHALED_SOURCE_ID_START:MARSHALED_SOURCE_ID_END]) - copy(unmarshaledPackage.TargetId, data[MARSHALED_TARGET_ID_START:MARSHALED_TARGET_ID_END]) - - return unmarshaledPackage, nil -} - -func (packet *Packet) Marshal() []byte { - marshaledPackage := make([]byte, MARSHALED_TOTAL_SIZE) - - marshaledPackage[MARSHALED_PACKET_HEADER_START] = MARSHALED_PACKET_HEADER - copy(marshaledPackage[MARSHALED_SOURCE_ID_START:MARSHALED_SOURCE_ID_END], packet.SourceId[:MARSHALED_SOURCE_ID_SIZE]) - copy(marshaledPackage[MARSHALED_TARGET_ID_START:MARSHALED_TARGET_ID_END], packet.TargetId[:MARSHALED_TARGET_ID_SIZE]) - - return marshaledPackage -} diff --git a/plugins/analysis/types/ping/constants.go b/plugins/analysis/types/ping/constants.go deleted file mode 100644 index 41de5de4342d2f55f4fa5e9b053bdead43d37fd8..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/ping/constants.go +++ /dev/null @@ -1,11 +0,0 @@ -package ping - -const ( - MARSHALED_PACKET_HEADER = 0x00 - - MARSHALED_PACKET_HEADER_START = 0 - MARSHALED_PACKET_HEADER_SIZE = 1 - MARSHALED_PACKET_HEADER_END = MARSHALED_PACKET_HEADER_START + MARSHALED_PACKET_HEADER_SIZE - - MARSHALED_TOTAL_SIZE = MARSHALED_PACKET_HEADER_END -) diff --git a/plugins/analysis/types/ping/packet.go b/plugins/analysis/types/ping/packet.go deleted file mode 100644 index 68193e5153630da265a8776b527356cf4a34e1fb..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/ping/packet.go +++ /dev/null @@ -1,27 +0,0 @@ -package ping - -import "errors" - -var ( - ErrMalformedPingPacket = errors.New("malformed ping packet") -) - -type Packet struct{} - -func Unmarshal(data []byte) (*Packet, error) { - if len(data) < MARSHALED_TOTAL_SIZE || data[MARSHALED_PACKET_HEADER_START] != MARSHALED_PACKET_HEADER { - return nil, ErrMalformedPingPacket - } - - unmarshaledPacket := &Packet{} - - return unmarshaledPacket, nil -} - -func (packet *Packet) Marshal() []byte { - marshaledPackage := make([]byte, MARSHALED_TOTAL_SIZE) - - marshaledPackage[MARSHALED_PACKET_HEADER_START] = MARSHALED_PACKET_HEADER - - return marshaledPackage -} diff --git a/plugins/analysis/types/removenode/constants.go b/plugins/analysis/types/removenode/constants.go deleted file mode 100644 index b8edb5d1795c5199e38b3b95ea7b08ef1f206999..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/removenode/constants.go +++ /dev/null @@ -1,17 +0,0 @@ -package removenode - -import "crypto/sha256" - -const ( - MARSHALED_PACKET_HEADER = 0x02 - - MARSHALED_PACKET_HEADER_START = 0 - MARSHALED_PACKET_HEADER_SIZE = 1 - MARSHALED_PACKET_HEADER_END = MARSHALED_PACKET_HEADER_START + MARSHALED_PACKET_HEADER_SIZE - - MARSHALED_ID_START = MARSHALED_PACKET_HEADER_END - MARSHALED_ID_SIZE = sha256.Size - MARSHALED_ID_END = MARSHALED_ID_START + MARSHALED_ID_SIZE - - MARSHALED_TOTAL_SIZE = MARSHALED_ID_END -) diff --git a/plugins/analysis/types/removenode/packet.go b/plugins/analysis/types/removenode/packet.go deleted file mode 100644 index aeb890357109db49775d45fe0b52cfe08748e3a0..0000000000000000000000000000000000000000 --- a/plugins/analysis/types/removenode/packet.go +++ /dev/null @@ -1,34 +0,0 @@ -package removenode - -import "errors" - -var ( - ErrMalformedRemovePacket = errors.New("malformed remove node packet") -) - -type Packet struct { - NodeId []byte -} - -func Unmarshal(data []byte) (*Packet, error) { - if len(data) < MARSHALED_TOTAL_SIZE || data[0] != MARSHALED_PACKET_HEADER { - return nil, ErrMalformedRemovePacket - } - - unmarshaledPackage := &Packet{ - NodeId: make([]byte, MARSHALED_ID_SIZE), - } - - copy(unmarshaledPackage.NodeId, data[MARSHALED_ID_START:MARSHALED_ID_END]) - - return unmarshaledPackage, nil -} - -func (packet *Packet) Marshal() []byte { - marshaledPackage := make([]byte, MARSHALED_TOTAL_SIZE) - - marshaledPackage[MARSHALED_PACKET_HEADER_START] = MARSHALED_PACKET_HEADER - copy(marshaledPackage[MARSHALED_ID_START:MARSHALED_ID_END], packet.NodeId[:MARSHALED_ID_SIZE]) - - return marshaledPackage -} diff --git a/plugins/analysis/webinterface/httpserver/data_stream.go b/plugins/analysis/webinterface/httpserver/data_stream.go deleted file mode 100644 index c096ffeb631cd9bd7b42808c3b7f9d943d80a217..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/data_stream.go +++ /dev/null @@ -1,97 +0,0 @@ -package httpserver - -import ( - "sync" - - "github.com/iotaledger/goshimmer/plugins/analysis/server" - "github.com/iotaledger/goshimmer/plugins/analysis/webinterface/recordedevents" - "github.com/iotaledger/goshimmer/plugins/analysis/webinterface/types" - "github.com/iotaledger/hive.go/events" - "golang.org/x/net/websocket" -) - -func dataStream(ws *websocket.Conn) { - // create a wrapper for the websocket - wsChan := NewWebSocketChannel(ws) - defer wsChan.Close() - - // variables and factory methods for the async calls after the initial replay - var replayMutex sync.RWMutex - createAsyncNodeCallback := func(wsChan *WebSocketChannel, messagePrefix string) func(string) { - return func(nodeId string) { - go func() { - replayMutex.RLock() - defer replayMutex.RUnlock() - - wsChan.TryWrite(messagePrefix + nodeId) - }() - } - } - createAsyncLinkCallback := func(wsChan *WebSocketChannel, messagePrefix string) func(string, string) { - return func(sourceId string, targetId string) { - go func() { - replayMutex.RLock() - defer replayMutex.RUnlock() - - wsChan.TryWrite(messagePrefix + sourceId + targetId) - }() - } - } - - // wait with firing the callbacks until the replay is complete - replayMutex.Lock() - - // create and register the dynamic callbacks - addNodeClosure := events.NewClosure(createAsyncNodeCallback(wsChan, "A")) - removeNodeClosure := events.NewClosure(createAsyncNodeCallback(wsChan, "a")) - connectNodesClosure := events.NewClosure(createAsyncLinkCallback(wsChan, "C")) - disconnectNodesClosure := events.NewClosure(createAsyncLinkCallback(wsChan, "c")) - nodeOnlineClosure := events.NewClosure(createAsyncNodeCallback(wsChan, "O")) - nodeOfflineClosure := events.NewClosure(createAsyncNodeCallback(wsChan, "o")) - server.Events.AddNode.Attach(addNodeClosure) - server.Events.RemoveNode.Attach(removeNodeClosure) - server.Events.ConnectNodes.Attach(connectNodesClosure) - server.Events.DisconnectNodes.Attach(disconnectNodesClosure) - server.Events.NodeOnline.Attach(nodeOnlineClosure) - server.Events.NodeOffline.Attach(nodeOfflineClosure) - - // replay old events - recordedevents.Replay(createEventHandlers(wsChan, createSyncNodeCallback, createSyncLinkCallback)) - - // mark replay as complete - replayMutex.Unlock() - - // wait until the connection breaks and keep it alive - wsChan.KeepAlive() - - // unregister the callbacks - server.Events.AddNode.Detach(addNodeClosure) - server.Events.RemoveNode.Detach(removeNodeClosure) - server.Events.ConnectNodes.Detach(connectNodesClosure) - server.Events.DisconnectNodes.Detach(disconnectNodesClosure) - server.Events.NodeOnline.Detach(nodeOnlineClosure) - server.Events.NodeOffline.Detach(nodeOfflineClosure) -} - -func createEventHandlers(wsChan *WebSocketChannel, nodeCallbackFactory func(*WebSocketChannel, string) func(string), linkCallbackFactory func(*WebSocketChannel, string) func(string, string)) *types.EventHandlers { - return &types.EventHandlers{ - AddNode: nodeCallbackFactory(wsChan, "A"), - RemoveNode: nodeCallbackFactory(wsChan, "a"), - ConnectNodes: linkCallbackFactory(wsChan, "C"), - DisconnectNodes: linkCallbackFactory(wsChan, "c"), - NodeOnline: nodeCallbackFactory(wsChan, "O"), - NodeOffline: nodeCallbackFactory(wsChan, "o"), - } -} - -func createSyncNodeCallback(wsChan *WebSocketChannel, messagePrefix string) func(nodeId string) { - return func(nodeId string) { - wsChan.Write(messagePrefix + nodeId) - } -} - -func createSyncLinkCallback(wsChan *WebSocketChannel, messagePrefix string) func(sourceId string, targetId string) { - return func(sourceId string, targetId string) { - wsChan.Write(messagePrefix + sourceId + targetId) - } -} diff --git a/plugins/analysis/webinterface/httpserver/packrd/packed-packr.go b/plugins/analysis/webinterface/httpserver/packrd/packed-packr.go deleted file mode 100644 index 4241a1363e26fa3ef3ccb451ccf0b00e14fb98f8..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/packrd/packed-packr.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build !skippackr -// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT. - -// You can use the "packr2 clean" command to clean up this, -// and any other packr generated files. -package packrd - -import ( - "github.com/gobuffalo/packr/v2" - "github.com/gobuffalo/packr/v2/file/resolver" -) - -var _ = func() error { - const gk = "4c80c379ef2b80415266c114d9f8d6a8" - g := packr.New(gk, "") - hgr, err := resolver.NewHexGzip(map[string]string{ - "166310f2d73113b478111b0a976a0eea": "1f8b08000000000000ff9c57793494fbff7f701b528454f6a6414d0bb330c34c46b319141a63494a356661304b331343ca9232527675254b961a85b2e5226d52e426a25c1165c992352d971a7ec7fdd5fdfeceefdc73fff87ece79ce799ecf79bd5eefcffbf5bc9ef7394f1cd5c55e4d554f150000354707320d0000e6f2a5020200403090ee0e0080aed8ce4becc6678b43e842164060f27d5960472edd8f4563d199a1479b593600a0c4e6b87b89bd9c9db00c3ed79cbe8c31977005c0f2b2d92511d019812c31d897e5c7e1e120d375f720600e1307d98772863b0b482c7f8e439890e516e6e2ce080b646098905db6601b0956c2157059623a58c20de289b0121ce42f5d2c4f845dde8641c07f41c48138c8ff1ecacb990a26f1852c30cadcc28c014720c068b439c2128546237680917004120647c2e0683384251685c622adc03f16c4166c2364b2b13432e5472d21938d83f88bc5022c0c161212621e6261ce17fac110180c66590389341332d966a2509e982e31e3898c7f2a9059228690231073f83cf0f233dd977f4c8c83407eb6c015383bff2dcc13fd308ac1e7c22474010c610e8771b9b09f689198c662ff3b5ae41e2a60c1682c11ff9890c1a2b1d8c6ffa7d4bf539781026767ec5e21c78fc3a30791f98c635c164fec48c641245c813993c3c492e0d61696240286802212ed3008040665412158a348186b22dc9a6205ffa9f14f5c0ba2350a498193ec50966404c20e43b023910948b21d91444121d094bfb98e3c9198ce63b07e7239ffe112ff958b25095974315fe8cee707fd4c00d59f2fe68bfcf90230c90d0d86eee3f098fc10d1d6e5d7f3e3a42c212798c5a408f95cf05ffe6239ff509f648724a0911824c5924859eedbdadace92842120890822c20e4db484fce032ff1bcf60b6601bd8ff0bcbcf2d1a99b27cfb77f46dc1fff978583c260e2284ecb2456c7c1a0100aad71cc90477c9eb091f1f2783ae757d1972852f1b2fbcf94c73d3d5dbd2d4b6704d637f00637f952fd3f4d9814ec87ed4f5dac71f1999328f02879262cfaa8517b15f1acf2b30b679941ffeded95975c3ab64d89aaad963b6127de445658bf98e6f4b4b56f256f6556f2a42837d41579828c6357c6eed3d3e15f2bc6624fbf894615642f275697e0408045aece8eb9b82673ebb1a6e7b737bfaee4bb23b6095dadd857983d6a5bd9d9deec80ca733be653298b6eacbf09219aaf9c563eab1f96fe7e6074043f506f18dde5cf401739dd52e8f078faa3b71cee88ab3779348a7ba0667c56834baf5667171cc8b31cb9bebf0b2ecb7044047f9b28b9f85822f79f39a4b7afafac7dd185ae6e08cbadada430a16bb769b684d1fbc77527e1b84f268895bbbe5a4aa6d8206d820ec02909efe48fec8b3dfd2dafa37c6c1a400c38d1bf9163aab2903efde3e3815353535158707e7769c4d4b4c4878519818135d701a682760ad470f2fceddd1783ed90b3479c4e28df6b9dcecfa905b2b79f144676fc152c70baf56d20a9187c6fd18a3b0ae5c5643cce3b566fafb6411eb941463623d3e5a1ba83f47e48b4680a8b36a1448f25645135b14eab33c08fd6d73e045c3fc4f0db16b22d4a82e49976a37a89ede761176d8bc22b81b71c96573ea4646244c0b6cf7ca68a70b0b31761b97d4404c7d23cc53f0d62b48372a2eb229dc818cdb1097f86ca69c8b87375c4c5750fc7562f6a0f935e30d525a2455d7fd42bbbf89687f7282697d6aaf6b5a9349bf34c74c41f8fe775d25d53181b5812de09a96baf23a74b344f1bd8665c9af898dbe7b1c149d67864076e27d495e1278e2383943f1e9fba16db17d24eea9e6eb9ad33e4e85b4bd7442ba8a06c6342633236336d4263be7ca7d05787a5ef3af079da8ac76b71515dd0715ffe0e73fe853300e3565f7fed2f4e8510cb7ffee897e5243fde98f9fa039c64569f11b03f493d6599efd66456d7dcaceee51053fdeb2373b5c572dadf117b656d388abf4960fc804b7eab3fb2daf1d86b27065fcd1c1a75b0b7b62636343af758c9130874f55ee6c3f5ea4bcebf4183fa5a5e37cad9b6e74cfe4a24a0aad77e278b5a2038bc532958a1dcb5598b79113caea0692c691b9faf657af3c15496713defb838d1d37466ec8d583f9d4054f5ef8dd2e491a936c8b89580ce754f48d9400448de771631126b12257b1d6c995290f3b70f3e2f12301aa26a793b4de5c21c52ebe7cf912b5f59a1badbccfe19823c3dea77807e6727c4a40b46ae79ebb45619ac53bd41917930d5276634cabf35e856685490fafa2e21cb82e8e879e48151e4a151e02f44740f73a930fe525cce3a91bed2f4575c4f85764bb9450cd72aafa401849fa0a8d222dcb95014141c5afe75272b6673ef3ec601b047a839bf73819f90ea4ffa92df7bc2191dfc96d5254f1002c7a37bb4fd839691fbecfdcee57d12d39b894ec60b299f3a54e1fd8046f3aaf1e37ba028c7b5b455cf9953db378ff08dc29aaeb61b004d5b4c9b0a1a161a1afaf6fe4cb44f7dcfa6de1e55428d5cbef21af3a316db7a990eca9db8e75251dae0f7b193adeb97517b6e703bba21b7448ad92a75432b3b3b23171b6225aefb1c6e0c444d09ecda9f3403debc13bc104e9f45eb49555ddcad5351b2282b534a8fa05773b2683ad9415a30e5ca1fab7fa9669df39345d07402b7c9c6f71f1642bfbadebe39fe5e62d51606521c1c1775ff7f52da67846dfae1e6573f0f9736dc07e07f91fcf32adfaed959d6a0e96162e2e2e965bde9a96c5fc295fd4daa669d26ea8af2f72f32336fef686b9bfe4d2f6993bf83d5d381c4e4176ab3b2a4a212a32c9f8fe81f53e908cc8826c9971fbc0b9d2d6433d6199f59543abaa8aef09de45833f9ac587de8c11f657e16d48ac8a0cac280bee1b09c777b20e21f19d96d4dd9efaf37169de2f0a919d680e4ae68c241fb03daf1bd13e26f6243816d2ca63d25fb5ae15d618d48408037ab885b53e6efeb27064467833affa498967a081d6c711df329d8bc605eee268ac4b8eed09e4faf8132b724394d26c86e3dfd9af4e42dd0e5fa1969e919525bfdd321cb64e8b68d4cc07e392480b140ae59c7da2d1e4e7b0fafca473a0c8078d83b3d052c5d3c9d7e9dbab2e019a79eda34a0e8f8605d64179d6fd0909096bdef0be469fabafe68485d59a66b92c81c0969074c192f6f052fa78ee1953450f00a25e9cdcd8d8d8e3301dd75d5817326d9eb333a4146a3cda4d861cfdda9e6fffd5d4ec8cb6a19eded3cea9e1235ad18f67bec97565e79cb846a6b3a3abf7ebad6269cf66e327eb64169d81a2a4aba0635bd53d9b439b2b82f714b1a61ad8e341be4dcbe176bd78881d19aee050d47a55966eb7a5def14062f396aa8c26dbe6775b30f282b55d43e74ea6eda82db9e05a51262bcfb69379e3c9a0add2e2daf964452564c6395e7d56695e4f5ead0bb7ccebface0ac0b7900a756faa81da1fbcd8b9890a4a444aceda6a575f4e47303640c767748fe5f7bf40500db2d741035ce39a0b6891eed53af690645bf84cc3d5ab57b5819a158fd94bfda1d24f56c31be21b471e0c554f04d73d0b427f18c30c2d29ccb7f47cfe72f689c278db561bc97448f20ecf1b55e7cab5a0733087c4ae1bfa18f4ec84e8cf672d72b9fc5bfb832fa9e24d39fd2e7fc80622a510e777bb0ac910cdcb3939fd394e9b238605d690ca28a3f98a0f9f7bcbca102db3834f0ef7d4854cc3e25cc74b9af6becdd8e9d0221cfddedeeedaf1ae21f65e02f26402b2f81720ec7823bb62be7d70e3cd6ab470f8e9ba9632c6930425e9e1dc7ceb077ee67ae74f9e5dda56bcc52340b14011ce265e699b6694fd7a8c4ebf3231376f4b31762add5067821c528d6de09694940c1716161eff2de753587d84bd71382456e45a7c60b0b7f7f28af1e9eaa483abfa22548edc91524a836e69b03333329a2536d97ba8856a49a536f7bfabcc2fa56d37dae3884f696969f99a34fa9df23477a6b1a9ad8dca53cadaf380ad38293d4dae5f155773eece2dadd6c6b1b1b13582bdb16bbf038c275645bd6ad9f1574ed5c77eb27ae3a7ccdf6d333c6c64cf547e34fd75c4f5815d514aca92bf85ba0db6360af4bab5d5656aa0317e486e96b23ba9e5779311885e44f2ea187d2b9e25f1fc6bf4f81bc8de1aef6b439e92d7b3841375ea361c5cbde7e926ee544262e29c4e9b73e6093e2e2be57aa6ceaba3d5e9dbdea85c3f8fa597aea5acd6a0acd600a91883549462349562fe1eb1f4ca339db777916146330fbb9a9b9bda073664ed837ca54df080980b24681b5e4a8618707fdf273c1e29fe8db039f5cac76dc29bdf397a1a47cd0e78797b2fb40d0bb32abc4b4282d00708cd3ecec05d9dd5a0e9cacacaefcdbceafeab70d3dbbb982870cb6851c49d88a593aa69631f3edc80ca88bf44ca3950ed5acdf39441434343ccd572cf1b6b381996508582211de19789fd0b52fc25dae4751325a61ab46a95dbe7c5f204ef81a4aa85c9871efae1a3ab9407089c75b534f74dc97fbe5bff2c5ce6951ae9f04a036573a23b125bddccdc2655e6bf870614d6d4d42ce89ff58a7b3278f624766cd51a15b5bbfefe58c19ce262f84981809a78af4e5873d9d6407de997f9fea84f6d5dea46830bc1d8ac562db013513b2f3959f3446060e0f36463fb85f63f606d21e1636bfba2f060657ced79cae0beb14c1adc0f073cc9adeaa056e9f411b246a129f99ea92547951a93fbba4eaca7374935f37d48063dca3273dfa9907f723e7279862e8f511d043e5849be2f5201703603e3e232da84cbbf828e762ee452e291e8ff090000ffff241161e8770e0000", - "2f53e054245e3cec681be9135541dbcb": "1f8b08000000000000ff9c544f8f9b3e14bce753bc9f7fe7e06c0e55d5029736daaeaadd54bbabae7a74cc039cf89fec076dfae92b2024e44f2f3d016fc6e399b145fadfe7f5a7d71fdf565093d1f92c1d1f288a7c0600901a2401b216212265aca172fe9e013f80a448637eef5e6a650c0698c313d24f1776f05dc54668f51b43ca07d6b0422bbb83803a6391f61a638d480c68ef316384bf88cb1819d401cb8cf1488294ec46dcba607abda4231cc4a20ccad374f556b462983288419e34b691b7aa155510be9e2f92bb65b2488cb2c936b23ce5c3927f5235e24a25e5437fb374e38a3df44133b611725705d7d8e203fcbf5c2cef96ef3e8e410ad5822a32a65de50eb37eeefb69df1fcbefd72f5f1e1e1f57cfe926e44fabd7b7f5f3d794fb095d990aa416311e94cecd2a53f1cac5c4db8a81d094b1e3c18d3e78a1da7c76eea9af4c76f96e80ca96370c771b367d25fe0616509833c68932ca461441d66f41787f34774a697d4313daf4fa30f05a48ac9d2e308c04285d00eb0a4c92848168c84967bc46c28cb9b2bcad3f686e1a226759bf9bd428028356e806c7af1c4ee6877eaeb2741bc7b5d5cae231d02d706c78daf3b510098a9786fd117e282e4a9fe0cafe1d730d5d9ed629cde135e5dd6dee6e35efff127f020000ffffe59390183c040000", - "853579e9f8c28c5a0ea8a5ed642bbad0": "1f8b08000000000000ffecbded7adb38b230f87faf82d6798f06b04ab424dbe90e15c4eb244e4fce3a4e3671cf4c3f1a1d0f2d42123b14a006415b6a4917b03ff70af616f712f6c1074990a2ec74bfe73dbfb63b8f450085ef42a15055281c4d333691316788e24d3c452d7eff2b9dc8162172bda47cead1d5920b99b6dbad8c45741a331ab58ef2c4058fb28462f3e35b5042111ed224a59e2a2f2fbf2cd194d26e9b5f3f5c44d87ca2d118a8c9ba790885c7864d753ec62ce28f178c988fa0096696f0fb30b960c47c34c2a43499b6db8811f58181f97f8b1f42d5f6dd0e1583823782ca4c302f8ff128622041e04d11c35108991ebc23390ac7e68be92fd58b94348c81a0bf65b1a0edb6fd18aa3c59bb9d625b5f8a4238ea61151fe771b18d53a54e09a38fde95105ca0d6db90312ebd69cc223b25de5f5a9db0d3fa4b0b0fe55cf0476fea4f784449ebe3a7773f5f5fdddd7cbabd7bffe9e79b772d98ee547913a2da4e36760e83cd6e37547d18f5c6fe244c1234c9a7175c8c515925d180fdf1888e87b6a91cc90b1950bc830994392998b1db592855659eb89b72815471f1f78c1784a4370c5f093fa16c26e7c3b0d3c11c0935e845137668d30f46656b55e5a6c58250d46233112ee7be0859c4172d0c9c6c92f0f7f5d54a521605fb185066595031a32dec87cb65b246721ea7108a59b6a04ca67807a6c40f928a5072d15092f0ab20b620d150ca13b91b73d107f511946d35112dbc1b72ff271543360f54a431670ac83fb101ffd7b48541677132ebbf2d0c29157198c4bfd386de6c121e46ef055ffcc7d74f374edea9e08b5f53ce5476c905bde53500c94df26e0713caa4089358ae4da32e931917b19c2fd29332c934912fd598c59ca57ba06592ed0d6d1abf4dcc2415299d4855c0ac08b53014df5f6caa7ff2b38c93f4a492a00bdfede091decf1203f5777affd3f5898e3055ebcf0f6c99c9ab62422a604e5ade5876105f9c09c9a154134017126c1426a9af8f210b675498ba74cc492da9deb8861c7b89a6bba00722d844229cb148f065a5963cd294afc8d05542154a7ee6692c0b5c3383d9906cf2c97891b7c540ea887c78e4bb7841595a2bcc8db723499d113740f7e1e4db6328a2b77cb10c657c9f5067e477701daeb91ac7291713fa2e16742269e462b28a4f34500bc384b35486cce287c97b9247da12ff16d3c760734b573213d49d7b69a29c79b89449b88f1e3ad69dad4538a3373ca29f059f8970b18f4f350027ef75ccbe1dcae6a439399eaae8601db4a970b7a75f7fcb42b10f65a2eb7d6deea003a569593cb143a706fca4126f40ef749cc28260b30c454adff2840bb7f032d6ce5dfa306b28db8935250bca222a727cd53079940198a469518eb3a4cd6eececdd0e9c17a75e4497824e424923dffb9cd030a55e96528f2711159e25d61e9f7a0ff143a8d1d343afbc9eff03f6e2a9b7e699c7288dbc58daaea8e97a1f4e2417eb275b5105fdaf6ec8842f161953e4fdc991c8a19ea8beac4d5756ab0b3c2ebc7fcda55ca6c1c9c92c96f3ecde9ff0c549c81ec26fe1895dd069b20cff6519254dcaebf45ee4645e0da14a48e3c532a1e9c3ac85e18de08f29151fd89457884c196d3189150c31dfc1e6a96d2d387d014fed65c1e90ff0144d0f4e7f84666a1c9cbe84a7697b70d6836642169cf5e1bb686870368043e3109c9dc273a43f383b87c3143d387b018777e2e0ec07d89bb7e0ec25ecef22c1b9eee9de5a0dce0770609d07e7a77090bc04e76770808e04e7e7d044f483f317b0cf2f04e73fc001fa1f9cff0807086170feb229a946a08317bd3a5495f5085ef4a1996e072f06fb29df2a659fc293bb43f0e20c0e51fbe0851e2287ff0c5ebc80921f0b4ea1c6c3062fa1694b0efa7dd8633a837e99dd619a82fe195499dba0ff02aa7c7dd0ff016a8783e0b40735b63538ed43411582d3c16e0c83fdc346714614283ffb14074a32dd6e51c4279a77f7c328d273721da752b5f76213465110835804e12ed0814c05d21d86a9822e0adc3907d1ffd24ac4a2a18eb8ac83ee9587ead0a10b2de8823fd0a733646586788a04dedf24cc51374be9db70a996951733b5297db86ae121f54329c3c95cd7815a9cb53a6a1acae253b73d116d82154ded241cc45e6f897048bcc84fe55992ec60b31bc3e9f7a0037088418b0fb4a800a63081081258c203cc61060b58c30a1ee19e6c56410fd6416f979f6f5322ba0c2684762524441eb32e3d163023e931ef4c8ee34e020b921e879dc971d649a07744c8acdd563f8b767bf69af40859bc266717aac1019a92ac1b434478378425098fe32e3fcee0814c8f69273a669d25ccc9f45876a263d159eac21e4c61f376fb4117367f4d7ab6b035498fa3eef478023d42c8dac6aec8fa55efa2bb3e1904eb9301ac480f1ec9e478d98d8e13b8f757043dbeea5d3c7657c16367854fd6f048a6c749373d5ec2bdbfde4bbdc718ef9cf137837eb63fe8058c1fd199a094e84d3b15931313361b7d09754fe523a58cd1342d419dc83afc24e129ad42175175583ad11b7f3c89e5ba0477632defb069ae37d03473af8ae005ec7529f8010e141ffcb81bc3f973d8e98425a278331fd1f10919ec5c281debc7d198f42a54086f52a2e2214329861855e80756072d44150dbf0a2773b565a0100f27b928c7a46bf91f99f84bbe44182441fdcec3888df1c972c4c62048a47e38e90d792904ea74b859473111233e1e3e8ce271872c47f1f858eed8112169bb8de62336ee105dd6ae42a8f0e661bf3319aa0d0cdec44841e15a874d7b55ca50358d8cc690a8df6e1f548bdd3263059f8ce89810d2edb7db487f27a370dce9c3d45f66e91c518cc1829884761b2d475477271c4334a263031862bcdb1f4fae72cb31e9c152fd14c54a3c9c96e3acda1c92a99fcee3a9446a0a6c915094a6767c1a993902010cef769650a91e4ed49f887cd222637f2268282952ab1d43d218bb6c8c7d688c9d37c5e6c4afda5de1b438ef3fdb6e6dfe6f749da239ce0190c430dfa71c2ffee88298ee638bc68fd0a07eacc691a30a9e9821a7c46d588afd45b844ae503527f0233ade617f1a27928a26007aa410688741219e995590446db45136a1c8ed4e99a7c37678285ff72ea6a3704c10ebf6f1890c74a082a37b78ef60786a30fbf012d00016bbf577aa96621f328361ac11690586d4206d56606b56c5d6986405b636e1680cbcc0d11032859e6923724dbf1fb9641db90486e93efefcf087f087e5a273eacfa8543d4811536465988d98462b8124e818dd190159638be3296204b1edb675cfe5bc857dc9aff923156fc394220c269610a22062a6d86515c08284a5862666792437ba17ad06ca64eb48c5ee716057aba5969079e519d633db8ef72d669117a7811733f07826d571dcb46b2848bc3b34bc598d85cdc7a6a7b52234577fc861be3108d21b8a5739ce0f4587f4b1ec103a12635ff20f91eace453fe8e5132a6bfcebff5405ea8cf16415a1bb442ff24282de3ecefcf8df48737ac31ad5c9c961d1826258d48a1dd257b2dd469448ac0e038a3cd0ff9f3cfc79f2f0f2e9a9ce87e770b51bce4ae9993e39187d6da12b2b149b8da7a624b90f27dfbc38f568be7e25f7eea91716aacd96d12cc6848d64a1c88bb75b6462c8688c213643bfc90b0c044ce42ae03b0c74077c3aadb4d1f48a1347fd5a68f4a45a7b3c5f7a8d3d07ad165575e7d3dbd45ba3228d684225f574d33565cb9772a81b0f19e90db35761c92a66381c6546b7a93a420811ed76e8a7cb249e509441bfd052d21d4c63419d9ee55a445d9b222122ef07d543c887854ece56f85aa13a279742846b7f29b8e4aaf9b636a3602db2401fe361a90ded0d6397c58d73be4d8ce2f1302c3a60d581a13f912be04ee377b5756848de3e595747db78baf6ca13b6370d9374ed198b002f4c3d2388f1d2ccd80894ad6464a44ed0d05203d582169f4e5b63500456be6265db258ea788faf330fdf4c83e0bbea442aecd04ef37e8aba9256fcf3d35d5c7d39846e0a5319b502f965e98081a466b6f1ea6ded216e9fda5d551a56a05b8b3165d1e4a8dc5d0b45dadbf7271734698cf19509f4fa7ea733a552b3c169430fd037467d674bff7fc113f4795d6c80ea34681b1da712dc697d820f95729623633f820f5ee2e701513a48b0956e0338ac7b886f45ecc3c6ad3c37d1191c682bd8990b846528ac5aaa7c88cd050d382a2dba5ace981c791d73b22445c20aa60d47121505fbbdd3e3dec37a8e69db16b2090eef675d3bc7d5174a38e850cef6a32a87c1ad4889a761242241624377729c809bda081dea30a2b144e981a28b58de892f482cf09d75010eec751bedabe8dc4b822cc2a46e74631f38e1c0a6f1492a1d6641eb2198d5a30719a3c5519ef34b2a1562ac3fb84b6803a0013cd0cd8c936cb8cbacb2cb77250f4a915468aec12e19bba6ed74b7a8184cf7844dbedc47e294e13849fc4ec5bbbfd80cc17c641cb48c3ea05b4db45094bfb55669f17d9779f09530caeda18d3b73c63d2654e2284379f490f5865ff74176962cedaf0b943f439c7ddd3d1835354521aa3a891d6735492e9bc096a9d1b72bd476d6216cb373c5a23ec3d86a9a756208dbcc758cebd8c7d63fc9179aa935e1cd96d9213e12fad12c3a284dda46648e0212757aad637349537f451959c6b3c508c77925cf96114a9e84ba94eabd28f234241b59d4858208a618d046eb791f4e3f473cc188dc851cf15592cab4c15a89eb3f150716dea434b22c16e8b7a595c59c9a6eea6c4cee83da8a2168adfd2bc2d560dd08c744e216f4679da58d76352c7204c3fbe2e15d9d2c2dc1c0df1f057444160f86659565156372f27cba6aa016c9aaea241bc126b9a26daed05121a3fb8fae4fad3f6d8165c74da3651ba23382b47706450866abc2d8cb0d8b05c631f4339f717314316263f700f3098d3821c763a05c7638146620c31e1b61b4744cfd4c5cd288f1907ea5b8fe5306eb7638551ed36334c565c6ce2ac6cf3a26c738ee8cc5f84694aae15d2dc648b7b2afc38bd096f6c42c3d6aa86d153695e3ae75912193e90e9bc2d072fd6ee49469d060a5cdc6ea91f85326cb7cd6f91e0e45ed59a9a7766bb456ab98289c6e0f4eed1b1292b0fc6e5ee2c2ffa9d7c073c390dfa3b6d6ab7df41ada6f35229b289d611943c44c9891adcbe774cc196f3751a4f523f8d1759124a2e5a18aec8bd62f1afc9a35a590d5ba3d4c4ef6398a6ed36ba2665d0947fd3c8d87e239b1d28d2f72bb9f2532a65cc66a99f6a1cbd15214ba75c2cb65b3e8c10861499a22ec9511feec8269574e92ad2e32952dbd9678bb547bda139f15df90a12e1e19d9f84a9fcc81f28a1506e2b74d9cad7373df90c92b057c4eff5f3b1be3c224411934b2241ad4e0c7207760d16763d0d522935ed0a8f77903e016cea55b043a646a0d0071b3696c11eab7c8053862b3f660f611247a1a46fdef015c2ba995a5779b8e66ff9e2b1a3b6510b32607a5daad683e401f325d73dd1056a9cd29602fb165a86d6dbcaed1ea5c86c20601933350841551a67707c65b6b7a14be38fd80ee2548f9b8e3930c42a5f916b07519c2e794adda669ceb5c26014736fa1a396192addd24c7d192a1984502c81e0ca5a0532c891c8d141c5e80ec35d55dce0f27a8eeaa328f1e905678fa00d068cb0a9eb83fb03385c52d07fa9d8cc06a56c813ea3b3f1e8a5b670b5969c1553ca4d942d035dc67768f272fe9211b6dd729044aa1f415aa9e6e81d73ea8bfff8fae9c6d7e60288e2c01c1843c8488c70853d353c54badd3a318ab6a4fbe4cedaff263c8c3c631da318179e494f17e1852cd2dc4b6a8f6cb9f1ac8e2bf9c63037586696a54bb53dada2b169fdacd0528cd021c2ab392545c242e9c5a967d767e0dd180e4ac52de2345503838799e220f4c69e2a3626d5fb8911001546bece865bb6734aa46534cb764ef7da6936da16de6e1b12d5ce7bb81baae8fd6ef8de1b2ee79e29570fad2ac50b05cdad94a3bc579a4d9ddabd1ea67aa387a9eda05d4259ed785e9cdbebba65775158c35c674d14d60c0a611bb4a0eed9aa2e55d49ccf764b5ff5f647e283e9b4650e3c7516b488a4491808c290412a7b0ce9f6f5094414fd97203b7d0c6504ed48a09d5aa48e2af67907b8db87c131ed2ae09ad0f3cf379b11e93015aca8ac07baa23282e675b326218aaabbbf5ff7a5f4121aa6d2938fdc54ab91a390bb4db9f0267cb1d47caa9dc97c3415a35b1d4f3d9a2a2c88ecf48742c7082c8fb4c08a3b03281cd3f78abc5b16ed3d927abcb65bd9346806eba3c2fa4a37bbc0fa9bea506a094338997bcb50c8d89c6a0b6672a6991de1c979c8bc9eed9e367628ba6745ecba332acc091df257b423b51a372efa258017fd8a6b42f6ff1ac4150501ea6190a45f8cba839ddd3e38d859b557b1d294577d35ac0df870a0256a0067228e2a28508e513c457d42086db7fb46566187c06d6c7c60247b43fe4a96eaf090880e3fa643f1baa7ce1879a74210ddbe4ac0c0f7523a8877fbf89816742aae5ad1e4263a79b7b75bf127fa7e5ae9bcb58569eabef929c4ac993b0a99bba7e9eda11c05aa474185adf8ac94a0a6243ca6c712a68477e263da49877a141cc20dbcdb374918e2bdb40e8af508a9d4703f55e543a18638964dd47e6a31f88f60af1ab7fb3009d984469e149456d119b839a62ef9231a0035e8dd33c35862793fc7725eca8a6222212483e31832f557119aa23731842ea58e212bba236a22a943dda9d38e9252bc26057d68d84cca6568752d0d4b30324b704f7156958ee99278595287e1611348a90174a9ad43663b0c4487e19dc1fdef99b94912ff96512dfd52f36783b198246afae229fa4eaa61327e8d7fa70dc5e4edd6fb071864a71ad90592101f4b8bc2654fe2631ddfed97db86b311f2bad84eed82dc15b859eb3563a8f79ac806b674ce794abd7411260915debfbefdcbf73eb802fd2414b37c97a863fabfd8bf2c5e849041da7063cb7ea078bb3d1b609816c863488134a4a098f2b01ca4895926d3842bf2793250ac4844fac3e8d564d8e944b85e484650d409f1bf4b637a696964660a7c2a633c45a9cfe84abee3d97d42117e65497242c26151aaeee592184824313c90252124d96ea785e43981a5391eb4dbd352329260cb152b1ad9ede30967326619d50d1b3e0cf1f794aa6a9f133752f5cccacd74cc1c3b1d5779f2f53fdde597c0c228a22290903336012f3edfc48645a0410c39f17a13b35b416930856528e7410893584cb22414d7a620016a7b508752b54b042930ae7b1c4ce0319432fd2a059f85f2f720017721049151eef27d5e79e8f0d3da3ea838994ecda507ad99386c1c9c9b02f7cf1587fd8cf95c2e656859991a71d50b1db544de8592160c287df43862759332398f533fa534aa6adead425f553a8cb8c7c8e05843ba68a6d89503f194b063d691c772f8388f138ae86bd2df6ef5265172c4c77a7da4bf0989ba031348f80c517c422b9a95dcb8a0686aa14623b433e80f7e78d91f0cfa671d445fbdea0f70fb6cf0f2ece58b1f062fcf819232d046a7a767e7bd1f063ff47aff49ff93be7efdbaff12832ae4f487b31f5ef44f5f9eea32ce9f2882764ecfcf7b2f4ecffbfd17ff495fbdb2059c0dcefb2f5f9efef0f2075dc2e9538de89d0dce5f9e9dbf789937e205066716000d5efc78767a7e767edea6f8240fbc68d6f83824666f1e8e69dd28b97226b3e8a3982cbd924bfbae6e7fc85ef786dd2ec392c46669337d92d2ca1ed08a373a62ea8b8d8928e6c3c5ad5cfea408b8dd6d9df2a52e5f629197af4f6a5c1bbf80fae3d4c481218e8779ee769b213aea8d8dcd524cd8762b0c2fd7a0b837a537d82a64a9e48b2f7ab97911a7a9a7768b452827f3f20c75f9f943e0e9d6e1f26a7645ac908bf58c302ee090ceb3e934a181dc1d90509915de1095dfd32529704722a9aa27d95e94996312561232164fb958d462676196a671c8486c95a2cf18213a21869c002d2591bff9f77416b39f97512829794fbec16f3e65910dff443ec31b22e11311f09bd674432e71fdcd157e19eaa520861acc411f69b0f58b35044962f62da0506a0603e62a5f45155a6ded4f404f0cb42b056bb054283823234db23601a28587efada45c92a8a2344052cb5c08834f48422bd383d1c23840525fa3374661f0b5d331006114b530860f461bf713c2202bfc6631da1f2a5adda424fc51ae6acce5cb477da775cc48adacd6cb86b4c2ae6681e668fb055e203912e362efb58a2ed504f8daedc227c420d7d662dde8a35e455b68f0296f85d06ddc6e15df0e9c4488e90053cce3cf16381fc1db5c210521121063a04784b0763b448a01843728b663a6ab8d2b8a45d708c2503a77dbcb1aae98cc9b3201276febe23ba187986fb76b0d82377cbb456f1585eae572e4d6ffdeea789d8e8a1ceaa23a31b08ea3593bd086596d2a73f00b3b5981bee751d5cab9b684477d2b68e288c2adb1d37cd5abe002dce6c6460cfa0ede163a4f3d43b9aed3a2b27658a1ca94565309ec35e9b5db36e896884114d0a20a2d9aa0df20fa04feac1dbd85699955a56fb747a2a635cdf1d89cabf6c4b7325792e6c25b6344c54bcb4aaace29b921272e845a4ef9ae9651e3347c6c321cd8e98e34e81715f3d46cea42b1d9717b20c96dde68a6f9798629bad517078a02efabb89a0f8b28c6b8516758f4495e5ce7226c50e31b5c5582653d57c57690d3077bf981365c7ea0233e8690c4aea96aacc733c8e3742389441f46e118625ca80e1dedf8f51fad521be23975b6dbb68ad85a0bc4b8b1a21b843765e81bc29b771de2588f7e56315dd2d7b789deb5db5f729bba5ebb8d7eb32aad42cdf505430e407ace08fe5aee918e25d1c565e0a8af2e73273887d0a262a4a92d913ee043666ee8c3888de478ecf4b9a8e8eea98aacef1b8d86eaa4ffa128ce2d6b4709dd6e373b68654c1d80d4f1e843d48a8da67ec259ca13ea3f8682554f4281f755aae3189b6915467195bbe7f7cfbc7fb965fdab760ffb9fece7947aff5a64898c7551fff2f8d2305e2c95348cfec95ad0d27f6eb8a48127e75450554898a4dc3333a43a14d1699825d2bba7f3f021e622f0deab9630fee8f1472b55d615fc93c5a9a7ba1247541416ab8a1d0cbdb219defdba2812e9cc349ae97a4d6fb0dfc240fd3203d1fc58d14f0c25b7e140697b0727d39125d21f9afcd35494fc170d2aff60b3835b321ac35bb2d9c157d28377a4071fc9af08c3cf957a2fe6c1037c51a06fc80d7c2237f09edcc04fe4067e231b2bcc0826608fe3c112ca837ab0b0010d93e4dafa20828a30a74181fdb5d0991f04c989610919ccc031dc0a3ec29ec57570efc6058fe030a7c17b2818d3e02798243414c10aac142258abafb2f526ae503c4fd16f1818c2f0dbdedd0197ebeaf68d814ccc22bafa342d76a83c22b701d5a2c77c013b5bd75076481f5b2364cd8d165705f20af6ae16e8c39eb6e6d25f256f67c28611ad5d91c51b6b3074915b175943f8c086c9888d1b6fc9ea322dcdb535ea8d9339b549c8db24f64e9d85d96b6e7c8a70a7f5fffe3ffff7ffe5b53acc89dc53474ebf4f47af15e8df713746cf829a2cbadd224a363b0c4c935c2d33657a0e9aec557373abbd24885de35508c911df6e731a3b92e32342e26178a18fb10a22283d9f9158ad7d6dc2aa7fc05828ef9a54b3f6e0f61d3739f41c2c794a8cb84733b5264ed087cf0df1fa92bb8935110f34e1fae6a813a74dbffa7b8b80b6dbb9ecc9316d358288558358ca5f5d507f15f44ca1eb2688f505f5d7414f1d9a0e9572419f28815db0a0b77f93bc3630f6c678c3d05453cac1091b06276c1e9cbc88ff85c363207e6f82f8fd82fabfffcf0ee0c1f2e58554c35ba2e6c61a20fd8d4e24178328e0a0624ea320b671a75110ee40b84656a52116a91a2cb9d3e1af483e67fe2aa73a79daba4c5b13b6abc83b044da924ced66207c2f6b8b783f83b1a53e2cc1f6e4e35edf732ed772277107e7f53ed2cf4f29b004f5fef6992ee516064996f39da104d51bbb91fb3940af98647314dd1120f59b73bc494e86bcfaefda5b91d35b12d4518e6be916ba8497eaf52b411b18d44d4de2961e4a138d4a892173980b9115d78c7f34f92f8fec458246ae7780eb55f2d79aace88ae458af5890761c3b6306424460c36a6b46b731deeb40726fc96d3e934f89176cf6026c28758ae836edf1f809c531906fe8f1089d002f9bd81f612f655d26530e8edcce69d116659adff330ba35b41e9765b36e2b72c8ca4a0f45e3bb22b40dff08c45a906345dbdd7112dad47b230ef4438d323e98045795c0bc3a48034767375d8b48c6d618888623b249d6959a20346b3848a0f454a0b43e234335a3ba065640bc352f1880feacf9c6488619891142dd5f6b1205a90b3260aad60458e7af0487a704f36f71aaf8225fc66872a98db69488307c82d51030675235369c5469444aa0e3f9f86423431cb1149df04b3c6ed15e3c503178f149c62d61de3295be432bf0bef947829bfbbccdc3abf56b839c3258e546799735bc07650dac8d72b2a24424b977d542dd0b21d5c94e68855f499755988c767c56a552738284ce7832af128f4aada66a7c1bed91afc8551a4a5219e9942753ed234c1730d2af7363ad96e2349baf63813ea0d33774812bf26bd8b38e8f61dab9b87c22d40a879ff5b2ec3e4237fd07e9c1a0e0a8ff920eef5ad3a8c0fee30e69cf9eb6eff023d5486f0a8870373423386b80d772a9a8c6467cefd8be2ee05b516af6ff8aaa1e5ab761b3978bc52673e98f9f77cb583aa91b19b59adaf5d41bb1a5a52dc8ca21788f916905098fbe6fc9ca24d9e9bee0c7f838302706729e1b3056bb06ab126a75ba88ed9ed4a3fad0cee3184e81ec37d8dafad12c660a01d49d5a85030e8c31e650c06033840db82c12954f7966070060df432189c3fe1ffc96e4141bff784f32687f2078317bb310c1aeeeb355c0eacefdeb9929339bbb51e74d7c8c45ebcf878f98fbbbf5d5eff7c05623f8a17511f6e6c54b81735a46a5bded88d6d44c7c3acd8f52f5066b99cac647e20b3dc4d19b7c601722088cd050e848d5b639b7df5ca90051b2aa25f737d71b516bd7e25b474af56c8fa75d86ea3b088dec5feaa4f24c4fe6a4038c4feba4f84fa1990705f515fb7eb381b281663b3ea073d58ab3fab81fa1a94f6e79b7bbe0a62300b3610a0896be56a84aa5f57db338dd075f75c32f2c41d811804e9694fc3fab6a4bdd8544cbab9524cdd2bc5a243e8281bdbe10e9dd07a284e4a2f1d61f9bdd317370541cc5ff53bcc5f0df0c90042155eabf05a8587c6604dfa2e0b950fc22a101d6e54b529eea627035807613566a7fe2b0fe7a55b33b52abec349726e5ebf14f12296f183b6a36cbe57eb285684afaf9a51ecd6dd5054d0ff51b5a3c154bf6975169e33f6784fd1c0a40e19918af7ac3091bbfc0adfc6a28edb819caf5e7509f38b6cc7b43861fa2bc861d60761d6258d1588018751ab806b8d3170774c9e22676a649ebd80502a667ac015ae1bbc85ac40b3a1bd2594e56c4acf917365a5562635dafd296127e6fc3c4c9d8e77c8f438cdc7079c94b59bb21e1a232b3727446e700d09294d4c26c7934e741ce161a2afc9bbd9c8e424a9d443a29344cd343bae941e5723d6608f831d22ece7ba4362e01d536d789f2281d5022d82854e10f163de098f437c92ed0b7a064f9bd6175edd1cc15c2996cbcf9f563b61c5721385124498c0238d6773b97fbae7173ce83734a7c10ee9cfaf992602dc74f0cbd7947b7e1ba8f35be580f7637e3e8b1b97996d901e22558b2fb93a50dac179d5bb6015621794b4937033b75d996f6b36666d63d6903ad8151e879dec38c34385fea9de9f90a85a45f9e7f8e45cad9603094dc5e56ef8d36e0c13828ea899c8edd67e383d302364e3f1f1f4243da676a687325f4d1d32390e210fae5530035ed22295ca4bb23339ceaa5c5c0ca396535d0b5aeef02992137f2fc969707fa970ed3b3c64e5b445ab1ca9e6c07a41df09f58381131a04a74ee8b4a6542f7c15548a23b25a2091d5228934856af58d2e96c8461f108d4219321b2d8a9baaf402e5956af97d5ea31318b881d33c70cfa375fead6590e6e71ff6f717d2d3f7a4a7da59975ef00afd9744e594922f480f07c84837a7a05a4428864e6701b4e645ae3013d3d7069696e6f7604afa30213d6dd4aa8ddf47bd31590fa796b17c20f16832861979d04d1d4ebb0abe438cd1c282cc14773b9cb5db8b0b24c9cc2e376a979bb0316b1bb3cecdcef5fa90c7b2238e8539f972cd53d66c60f355250e253415878191e478a6c7efd80ce389a2d4c75c9371762c21533f02070b5de98319f213f3eb34de44fc524df86fea037a30f3dd7dd0d38f4ff8abf905523d7bf89e9ea107838eed368a47d198d8204c3ba40f5187f43198a87e15a2bf0f31a8420cf6214eab10a70e04c63b5ad2adb064873a24abfb54d418fae461a8888abfe77c0469c9d31881666a2499f64e201db19cff9e9481f5706a8f2c530cd3d7b1ea9bfa9cbc32e79b0986893dbc4c8c14342271574042c2aeb1918c5e271721e19d288889d0ce557bb0261261589ba52c606d17730c6bbd9c39acf3051d022369b76fed6fd0da9008d53c2be1cd90b6da5ce39a31a93e6c1452232b8a5903c5c3a3073f4eaf164bb9467858ca548cc3cc98307d831342c2cc1ad7c619ea2b3f5bc6b578eb30c21c3121547f713ea8a7c3886f72a6ce457748088a2d4ec706a78f27b024ba4cd5f36eac86021f4f86f9d1d5807592e2dcaa213a4b505468678c92a7af7bed76ad2939073bdd4b31e47a67072786ac18a81842bc2b3cb9cc4968316366bfd6c3d81068f3d309f50fc4965cdb5f1b7d3cb709bfd8845ff28499a59b3dc8bb078fc5b87456ea40776fba0957e5d074eed5c96efefab1dd460bb5b656e4111e89cd8661f6facaa4a8dc577045f28c86f5b82602c5b0c0c3eb0bdbdb6b087180ae35525e1ba45cc1b546c57bb8b6c8f908d739525ee9cf684d42e0aa28b8c678b7dbe93bcc9b1d94a2aa7d55549e74517c050abbad0caa015e275cd8dfc0ffd19e680f339ffd973f9e61981a5d8442652d70d721a322f92ac3c9372d573791e9d77051f81ab04274dbb65c54ae36d409cc896d06cc5474b19087c50331a50626086146e517ce9b049deb1dd4542e410c56f6d624aea317a8412d68dbd86ea38414210c0d90bad1ed369a13fb9d8bf50af161626585f3fcc05f1dac60a09d02d7862a18681ff37a8c83c1cb03dcdfd33afcfcb682aa460daa55ac2d3f44ab9a6fe04299a8eacbcf4686fe54ecb21db524d95842d73007da915359d90ed44a6874b6503670e464180fb57970de18db121c1c807695f49d4eb5625ef7cae124bfee15962365c1ddae5bf46e5f7c551d45ab6b1c34d81a348962ca9e17675c759060fe4a9dfa9cb87597f9ebd2c4f4559f767f6cb785fecdeb6cd06f36d4695b5cee263ae870d045b85f0b0f6ae15327ac0974affcfe871bf8250f6872d7cb8fdacbfc3367a84dc890c05c6b7bfa8cffb6efbbc503153571e1cf9055eebfb0bdfb2fecd0fd17f69fccde7f518538f75f58fdfe4bb508e6de7f61fafe8b2ac0bdffc2eaf75fd8a1fb2fb6112fb07be785b9775e726aa9b8812662e75e7f31175ea0641c1a16b244b8e6aab044e027ef91c8ffd67b2475998a3e79d96bd8ce251aa12fd108cc89691e129dbe56988ff818d41fe73a4d0c0cc54d97688a2b2bce68597eda5edc69bc1824f23ad9fec59dfc62101f3afe211d9b11fbea9ca83f62c7f325f3b4dbbec64594593f239a474911c5f58b6e996bf336ad0294c75cb28923ed9aaf107b94ea2feb8b0a3163f066c215af0da1538e31970b724b7bd096d1c6d2fe8f946dd8687da7250d466330170346e31da40a63639812b9dd86cfbb2cd7d72a3906ed19c6388c89a76b9435bc6f70faec2323f99ae156395dd8b6b22637c7ae2933cbef0d1ff2360a997ee971d8523d6d1142c20b73ef006538907e28a5d0d76277fb3e9179edf292a3c3dc6ed10389d1122bae5d9746312c6b178e543f6d8670ffd9912558d3b06583f4a8c8d6f4fe48534e47452d2a5602e1724959f4761e27913116a85f5cb2900335343507b017da0cf8881076b1f4532a2fa514f17d26e9cd57642445c070b0b48ddc4fc5b054c9b3a69cb8f972d27e13f66a4ea1b5d237b8e6824e5b876aa942d5bd2e36e8a297bea42bf99633499924d414ea44edcc8567edde77df43125edaa75dfde2e11aa371b64f47dd7c4559fe4eaca73573c5433c5537bc0fe5d41510e4a8074b8daa6402f99492292c35ea91084c4349024b9f3322d5cf744a382cf5baffca336d7708cb1ab33ae18b659cd0d274ca46141ead0a905bba5826a1dc07bd93362537a30aa3a8ab75dfddc4e26b0b43465a732997c1c9c9e3e3a3ff78ea73313b19f47abd93f461d682b429b9fff2e5cb133d85ad52af9f3730382d54f27b0d094ecfa0a919c140d1a267d4527823c5ba38fb688204218a8defabf7822fac6d3185961af293d52269e162ceed64e3dd44edd888150fc635f8332ed6eb5f568b84a5819ae7a746c9d3604f82fc45bfa4a0b90574f29faffef9d839c1152f9572d41b17fee1730a9f66f7a914a80702775a5eabc3f4df225ee0dd21531e3d285ecc9699f4d46804b9e31dd5d68b96755a1e1ba489f842c3dba70635b2f8fe49f592bb9e69ffa4159c6a6b8c4a9ee0f45c4de033caace79d92e74721730dd4e5021df2cdf0461bde54f79a7d07beb474ab4dc743e1bcd7b13bcc1a52cd5cdcae971404d1ae62b6db53f5639c271b59d730f776ac69b7be088170a1eff42745acde198d5e3f75f5fa1ca5a34c3b168ea7e8d438a43186fba0df9c32a4322d64904e9c53e4d42d32465355a4bee6b56bb08aae4e046bdc3342a0a3d45a6d7242fd8730c9a8f1ab6eef65718bc2997d49daeee6d44ff8244c6ec2058594c4a3fe18a6242decb15a7e0bbf328f234cf719eb82967a934c08ca64b22ef9eb345b2afcf3184d157f7d1fb32866b3dcedd284c8513a1e4e2eec53330207268a8cc478b7dbbb1551c52233d77f539d246c148f736bd532da99744e44a5efe590a8de8604c5b5eec2ffc6b423edf022ccdf1708425d0fd9f3616ded4e4f361be4772ef06e7762d9b3a7fd42e49b65933ffc779f3e7ed6ebf36253239001df05fab0994354fd2deecd4f01a70e32ce9ca8e9586bf983a7a8fb948b45f1b6265f5275ee4933eae94b5b87dfd0749ec2744704613b024f6b098b57989d87adde96af3f73302f893851719dde1b9a94b9ef74395c5a58f1a35179ed23b30f80552e218748e2da29c161535d06928ee4b84b2bf7703456da0e7da3eb80815e818186daeddf364414fb29172a9b7ef447627b8828c5a0e5a32afbd47c1f24385343fe9c68ceb630a22cad5a2842f5191ad7ddcfd095af5ddc843701bb28dfaab14027481e23d9ed631c0c8e9f486d72007ffa071f3fc9cd926267170e4bafd03f7fb0be5463c25188a1d1532f67faee63bb1de79fa8883c98e59d08672687fa4279d41355f0655e035fa23c0a83b09eb063ad914031b111b8dd46b12fa85e89a8f0609da75a2ab7298dde6216a916dcbc137c597367312c8ceafcdab3dc86f1ab3f0eab26e2fb9e26d15ae60cec1385a40709e9c1921cf5e181f4604ef6cde77afa666ce91066bbb56cbd662681facb7046ffb1dd9a8f5f2eb43443c769de4b47e200517f92c494490d693e7fc1fa667b91d2a99f17ee79b4f6d389e049724da7722fbdc6643aa0ba6a5bcb53c5def2e577967aabe67ec4408e7730ab5e64117823db6d85dc9b55c0ba11ac03d14d76faae00246aa52c48d5342d957cf959f06538d3af035fecc5201c507f12b2094dde64f7f709d5c6c9eb5a314ba1e7e09db935db6ed76314355f3599f569cff447fd1d3c564bdc9b5dc5d617f303e5c4ede09ed40dc2f7322f71b53aeb1c413b04f4ef3329396bb7ed79dacd68fd185910c7ff4754e20a24e504c384505f866246a542ae544cecd401d35238352d6a52d49470fd5cc38267a97191008f95b86cd9822b6c3cf7a77be757ce529ad0894c15a5816943ba5a9826f5c9bc640513179aace0a85f98c7c3d533b3c28d4fe8bd5e1491b61b4fb721adb5610a1323ae17edb6d026f6d715339be68bee19de684d63a5816c0f35eb310803f3cdcc1a4e30470f1044dfe1e044ede2da723810a3deb8cb47bdb15a59a3befaee8f77434998ff38a734794713ad952c0327a72f7a01d36fc3c6c949f72564fa598318ef767053e9d551d66eb38bd623bdff169b5ba3be7dfbfaa2e1655c33bcba9e165ceb496b827af7e9e34705f855938e1c326bb78f58bb8d0e54d624d86aacaf11b0b14a0c19613bf856d327590bc962317559fe858f1b633b45ec2f45ec2f0eac1bbb83cf75d26056bce4d9645e38aad62f55148eebf3c4516f3c5434a7a81a9c827349d1a0b138435cbe21b72c2803fdb179e141be7ab810a4db0fe4eb076d49d2c790210a425109376fd1827553f42f3b0c0fe51b1fda38fad74abff5a66a17a5ce6e56ea675c89a42c6ac1afd53843f775747d455eba3329cd18eaea2122d2a18df2cfd0c6e5768b96e4a86709e25ea3d97e9bd95e93f10eee9ab69c261cb8b8d4db4b39b88604364e70bb8dcace3e3c39cf18ef4a59ce81251cf147d6827b7df0df83d06569a2d8823b0c1bcb5b36e9c798d57defc0f0934d30d281513c64138c7061f4126e82ba519d376096d174954a4f9110a7bf8d40b52e7fef0ef33f8bdf37460ed5702ce7561a665eff2f78b2e2c17b7b6fb580b074f4039bf2aa38cd244f631659cc2fdea828f8e903650467a7f0541382b33378b686e0ec7c3786b367df182b153e4c1bc6ab651f93cd0ec2fd37c3a5afe7e01d7f64f5e7610985d05f91927e86feba08fd0236a77d741d89fc06456c1ff0c9e581ed362f8f59c5276210ea3b8fd814f373f5c15b999f7e3e56ebb0ddb1b4be56952243c5712bff426e2d1ff943fd15dc523e24493c126e798a132f8e7bf917629a352f76b6d05fc1ba08ffd20dfdf50e3f397047bddd0e43edd0566b943d183260dbad3dfdd9b827f0fbeff4fea7eb93477a3f4b3eb065e662b8c5cdc310c18bbec2ad6795b9f5970272d773233ade318571b05984ab7f04fddee00c16e1ea17f395521a05ad775452b188599cca78e2198532a369ea2dc2887a0bea455c4ba35abbdc235d8c9876b5a9b90fedf261cf46f46044611f5a8f50fcf86607d386bd4571885655eeab7e60c5263a11bfa8cd7952e381a8bf7ac5fc555fab84577d42fd95228eabd7cc5f0d4ce4208f5cbf62feda40ae15e45a47be66feda40ae073a7207d19f762a9454fa1559549a2a7a3f41360819dec1d23553319aed9acca7dd4699ead1de1867aaf50db1abc1be796ea63ab5175b557e276ab37fa8343cb50da7bb9a2ca174bbd51b32f7b65d29bbd2cf9ed9d7e850fedc9d749fbb4bac89170eecf28a46327ff66e8cad33bd43991f90492f32a7231361c433bb66057f5257f03fa888ca937f730c1b91556f1e5af330ba5447f0fa25fc5c9d69a8dc738f12658dcf0251f75920d586679f1b525535bf62b4ff1e94fc8ea797d2f23130f3ea925a6db9d343c975507b3ddc3df58454c5ed9e2e51bf49b8220c84bf2652617c124e68add985087e7fb9d10b342514d4e81ab3caa9e6ce9b0970ed1a557cd892b5c64f08b588f718883c36387bf9bdf771ce9e3105a9398b2ddc5156df3da97073e6e153b68ba78503b984cf50eb761ea7de82ca398f6a3ee172fd419652ef6ff14368ef6a239cfb846b61281fd8a65690e318d770963f706482d369253c8d052de5381bba9294450db84e15fb1ba8e220558cb22e6917e4195853eade05e4d25f49a3dcdd756975f6b4eedbc83c1ab43c46d8b1dd1e59a947fd4122163ec433e3b8217f98ccf29641ab05d6575fd0eab576d61b872da7c8e76729159733ca64ed2978464e90111fe091f7cf93311afdf3d11f77f00948728254fd214617817f6c2bc1173530414ed0228d29f6ca38aee2f8ef7192d8cc179e7808f2747c71a22f22d0159d685fb3b2fc14e5272d157113be588632be4f680bbfd2af151450a38266e403128ffae3edd6199678345011bdd6ae493375f6b4b6bb66c8428a29cbd9f78b30d8701670fdca75bcaf8f2e84657bc7c2aa2bcfb806de74aad239acaa56dbbf6749e2f077c37af7f64082b31f5597bfd34dbd91d46b25399f4e532a3f8782328923eeb10ec9238d78bc0cdff2a5f5216f45b188925a0139ad31e2ef3d1dd0d9b3feae1dff2e9b054dd3704683dc646246a5fb58119f968f3b7a13ce6418332aec422995057f8f233977a4fc7f35f7302d6e25742a831e2822d18347051a30986b909aa6c5f6e059d7765a6fa2dfb581b4c031639c469d94ed56fbe9ad40ab38a9e3582d8e69b3b53cae2464b398492a52f33877b5b1655270aa1afeb4faade0900b8ce78674f2dde1d7fe8a95f68c46a9e2bb5071d0db6deef5ac4f5811580d882c5306446cb7bdfd19386f3820a30396287513c4ca06c949e80bfa5b465379c9e285d6a6bc17e182aa7335458a7cb9ae845569a1d5b4d4e03906eede7a50c3c9b75b86ec4c151b30c2b0d1a32a41502d4309c46e573d7219ec45b9b539564cfb6dbc50243d7f94365ca11ef45f7411eb66581d9a433f35403c93c8e5fd10eb28c6a8f4ec9d11d691206a2af6d0d7de38f312a8f5e7af1f67ea414a46ad45da82d682ffde825c260d2dde1adbe7579c9defa8baf35d989fa009825ed06053363c10e0b622103b6b9e5a0af68e0ecc5869b83a25a97926bf118e84a369a7f5a529a93586e6d93579de36a4b4c6dbad9378a0d89d638fda00b0dda2438d95f84093749ec6b6f28a95aaa8ae5785ced8be353f8f53689a9359c2efc3e4c2fc34ce5a4a93e985fad3985a9df5cdce5288f3a7250f4fd9c9d8129fd98c2d5bf47d5bb105fe5fb8119f7f87d97693a465cf38f6b78bdf1caf59af492f68dd739ed0d0b910f1db76fb5b75d27f223f157ab68a321b3e914fdbad1a864dcd7703d49d3bec30bc27efb7db500117db6bf0937e96bdcec60aca222ab431480b6fb788f94e0c39ea61a3e83391c4f956f4fe6782defbda12f263c8c2998a4c31a2f0be62798c37efcd53175f7446ab162c2a69b7dfbb4184210f5bf33f78ef5316e599dd87128a5dfa1fe4933d8ab7db477f83441dbbff517b35fdcb768bbe38079a8ba94b70154bd5257da0af7a39253f2a1e5866bbf23cbf838feabcb9848fb8f21202defc7dbb45ff20477df8e2db3d02e1ca4305e6acb17fe3b21853ab433581d7bdc2913925bd217de5a40d6987f471de67f77583dc3bc227df9539e853c504fda4762244fdd5a043fd551f9f0c40a8f05a85d72a3cfcab650bff4198afb9aa934117c9e3bffae9244c685762c8217e21cc37fc96021105885013a6cf616fa96264de1a210a2a4a2e4bc0f00b39ead75e31b796ac7e4d60618d86de17af845509847ec2fc7d2e9d36008dcf0998925dc1875bb27d4b94551f0e704a3600557fffe60a216a99bbaf0efafcec5784c96a3deee999f04635c915ec208ae1936fe53888825a847f23473d982becabeba01ce1caa131fbe4a70df120fc5547faab133b7120fc7547faeb3c6c2b4d4ca555a516deb80d641ab4bfdbe1eaa30478b33f0046175440dd68ea10b3582ae4accae5d67b84a22aa67bc4d5b7088a39423f61f74d82f2729a16240e73d121734587487ba2be527f7e69b71708e3207f62630ff45a41add41f63c4b22f9cfd45514e1ce4efd7d44a68b79d228a7a2b2f20386e7792987dd3d72f6cb3a95312ae0dd02392e56d0ba7fd4fe5b9afe4295b5cc9a3cf752de302de53842bb758d536a66a97a291efdd7e7af729f03ee451de821eb56a6f36580b357b27ae2228668aa61921311899efc567247190cb7c7f550d9dbbe4ee0ee1cd0261a8d0c00f086fdeb4dbe88d63a8f786d4f0eeb62e5f8d5a70e9a4bf753dd4dba950f473c8c86615c89c34c23a900511dc59fbbfe261cfbe7f06f4a2eb0f027f50f0f1767591f7e61709b57cd486f51ff973ff2aba05c52ab41f65dbbe22bcc9b47c5ad034fe9d6a6dee0775ca40da73594b61e01b12a915f526d78e55c5c1ef7d29429626a1a45f688298bf02e6afabedd045294a8875c9c644ce94bddddaf24d0546998dea6cd35bc45ef540ea02aa2bfb0ac32dda13b2bbe3ff0ee1cdef6a2f5570aa6f99992ca7c7ffa163307cd18675a82ec4770f967b184ff1aede26175ed12e5819a84fbe15cd230cdfecb9f02339ed0dadf3052db4f819bec01bf844989f846b9e49786f5c1a2ce7f124859fd4eacff930f88d9417fdb49b61114e64fc40b7db4a1074f7152101cd54280a0b7f577ffe4a3676270d7a6077d2a0071a4b82fe0efe8370b4d915f761eb7a0b8b87bf6fb748f1623384e1066150ebe82bc2aada1e8607d70aa176d7fdbd7172f255a3afc99823757f07cb30abaa31feaeba904f922e2e5bd4012a3c938231f3d5203e4e50deaedf395f7cca9ad4296fd1510f1b800fac39bd6fbccbdeaa5530e562d100f5d71d28f279cb83fada798ab9e9d29c112ad99c2e3b2e56b3de4e73d62c9ea40d15bf37ef7668446a48fed4a82c7a67b6e9a0c90accfb0fdf46e4f627d3e941c0e9d4817c5aa5924be12b3a15ed5fc8ac82c242e3247d98e51d36961b5945d3620e3caee1476ad3b536fc245213599e320cc8b452848c1779c2a49230a3f25d217a340051b5f07de3eb27ea0d4e7f84037983d397f044bdc1d90b68686f70de83c323119c6bafbdb5f10bce4f9f70b9ebce40d0efab43ed733a9022408b0304472d7d75a43803a998590b9bcbc3adfb6c3aa582465db352d5d1175ad19a858b78a21ff1a95dc1a53bc7365d8ba672df679b1d44644f3d5e885f5b42cb486db57adf6d41bf974798cdd78d99c649d282d6bff57ae180fed8aaead3ad5d80815cb580f9abee799e73adc2ebeef99ecabb6c4c12335a342695827fa3aaae972f5faa8ae67baf1f1455f5755d454d3ab8ce83ab410ba493aa836b5cb542d7fe4ef5ce2ca8262691aa72519a0ec1daf95e39df8fa47ad065f91cb716a114f10ab53ad34e0bbc9efa67be5b9d4cff4d3b2ddc1a32db309993cb1650bcdb0d25a1d6d9fc3dd914d73b9a769bc9888e8be7889a41b4a90ab0ba12f8d0db5bf97e5018d5ed5d6c7c26e74391f329edb3b7ac825dd76bb160f302cc1175b8047a078510a31abdbf9bd468734628a484c1a322f1aeb42508c165e3dc6cc5d5badc0ce5ebdf7efacc63753cd18abe19956f6f3f2245a0f7217c8316c5e6a82fe03d50a178203ce4fae90eeeaf89006eae2d1e0406058cb8bfea86fe0a1fc77ea83322eeafbba1bf563111c43eed10eeaf20f6a7ea636defec95d819fba1839fb11f69dc54f9cceff41096667867f9a2ef1b1bdd39e1af4cf7b4afc1fd0e96a3e70e8bb9b2e814f9d1b41e97acb61a085532b6ac3f75d3ba2ab1ab52217426c83c37b64cd628c6c32909fd103212fa0a23427f6aaf6a96231556462ab42315da910aed48956605f5019b288650db54c0d4b27e5fabe3873753eb7db2a41f7d5ba3673f9eac8296559805a34eff35bfceeee621b1c2fca63b5cda645ae2064359aaafebd0763b3785cd8bda15afb139085108501ef24721731a21fcfc690a22edd39c84426eba2580991bc9d626549fff5ff72e58fe340c9d72a14f788a70a752370207acd23d8141143dd8a32ee6e4692b1cea47456b3d82c24eca5e4283fce5b9a61e26cff4d07ad79a383d3cd8d83d8a698fc9dfd1d849d15847d25bc1b15cf2e9c5cc9be0788a2675d1352d246d6a73192eb46567de197f050b6ddc5944ac6189182cc00881f02eafdabc8f77a8ea48551d1dae5adb33adab554f055ff82b5857ebd7b16b585561a55af5ab2aa4e4fe1ae688c11ad4b15c1bb4ed2a8786aa97bb272da5da6d242f28923810441de974395f1f66071ce5c9d2482ede7b69a23c0038578b2bcc7f7122089fe5dfbf8bd1dee3718b8a83d381626c9ff58b40c90451d85016de27f44d42f525f7e0a8074b45dcc4037d27c2c798cdde687e3638ea1b55e65b9ef05a48df610a3622e8c32ce8c37dd08730e8efac49ace16c234860090f308719e9597f85a33ef4ecff8d5f635891d1181ed59f7bc5085fa93fd72456077312225cb9db53da0ca2bd6b38362545a7bdfed98f2f7f7cf1e30fb87265056faeed9b29e56eb6c670d31059b9878237dfd18dcaa510bc61edb6a20011b1c2b25203ceecb9d8d877f4b1becb62f8f87d2063f4a1a0f44bbd0f317d54d888549d112418aedbedbc535fe3df298a4e06909c0c30dcb4db374d0978071f9e63ab87f269c736a83509d943983b4bb8d5dcef61d6f62ae77e0f33c8f77f8afbfdf6a7b9dfcfffa5dc6fc94b57f853fe0799e1c5eb9e9a4d91eb09672a7c53847770af359f31fb76cbdf0bcee4becdaa5a86e45ab14f1ac0bc1b8bf0f0dad7796d3e443188d76a0fb2d793e30824791c8931a83fe471c4cc977e8a13549048fda32218fe0eae7d3dea0fc664704c4fa26e1fd6a3fee998f4bb83637692c0afa899112944cd8b4e0704f9ec98800a55b1daa1f5f38b706df1518b3a058647fd06265c15fbb668e4038a0a66ba826f072a30fc002bf9811b5b5dee106d65aabb77ab3b7414c9c7a24306c7eb516fac46e464ad6f7aaa41e9eae8f3b11a9813f56146678f6b2f9a3e3866fe4a0faa3003eaaf4f92c2f2b44b746520f4c7a9ae44d52d8f51bf4bb1a9b3434411ec8d8f0905dd024255ddf0c172a72aed100f6cabbb44e6edf63b8455d69ca32da94e7057636f0be7269b9d31e36bdc87b49f81c614a392271c5495975a975e63960591faf4c099a42b895a74b5a42256542b4cbafa8a490b620c4722f7ccd07acbb32432da1c16cb384ce2dfa9a7afa4f8de574a17a997c4dfa827e7d4b3169dda8b0cfb4be94426967e6b68fc9be4061d0915d23c45a6fb59dd81b505f8bd0abccfd80409ffeb97b77797d79fff7a09c2ff747375f7f1c3cdcf5fef8a580cc2968084ffe6faeae69d562a94bb73ee2bdb8d338e66841383325f40e6cf20f3ef21f3ad5b5ed73aa1e221d4e444c27ffbe9fad397bb373fbf7f7ff5e5eecd875bbcdb5dfb090f35477c60fb29d21b77218d690d047ade6ecffff099264ebfe68e63ea1e28e9f76e64c0882ebb449d6aa811914ae9e0e1238c26ea68d125fdfc2ab0a552437b18b041b8f6cbf7b111b3cf3d13e6c7fa0d7cf96aa137b51e2164b1dd2e0821d26e66f64ed2e368311e5a4268a8d9eef059456f2d68e6b4eabeda2a1b841bbf7ca8bba955b3a255b3ed76b6dfaad568361eaedc56e922f5766a0f14314d1103519e490e1f871ca99ed19ecedcfb35ab111b0fa9bf22d23d08517fed46ac61d96e2f915407f19b225a870f1f8ae2293ad24b852f62e33ae64b2ef7c5cd8d2bbfcdcb458bf2e5223555720c9ce8cd469f8c86cc5f691910f3d7a4cbb5e4c5a44a0ed4a6d13ceda1dd7e50c76ad585ebb20b26e6bfe0a834b747a5dc6c42f09908177bcf598a769be21b424bff86564f7e53578c5b3be8f4315c7ae93c8ca8f038d304759aac7ddff77ea1d26fe90ab565ca53155eff575658c865de6a13eb5baec7ed2de7228a592869b377747fa5181bbb0bab5951fb3055fbb09e2bedbd5aefbbd86cf40a44bbafd6bb2f36dbbc82a4feea5891447dd98e507f7d8cba9a3a52a769ba49b7dcb4f03b9aa61a5629f4242fd4d6a8dad4316c425ead6a51c7300c790f3a7d7caca8b56e7cbf4bfd353e4e54b8e0e42fa569d3679ed6ef8936fa3f2efcbaeaabb2c6fff573e3af38b4f2ed42b590667a21c553c490222baabdaa8dc5aba62ad218ba38b5ed9cf7f86f31dc1ebcab6acee3e54dd48aca2ddebfd0eaa06bf54eb603e3aca1aaf6cf81f9fa5b160a5a55fe55aba18edaaf2e6e98ec5ff4aac8171afb139c19cd5b4335c18b414392dbd1e0c5691da2d6cde0c5591da2ec64f0e2a94733dd27e5cebff36648bf77d63f3b3d3d6ff6d4aa08473c4567daaea7f0b64009cdb722748246fff96f637c3283d6ffe8ff8f7e0b6378e9406346b4b3bb0feaf0947bc9ec63e8bf30c6430ae57f3872e03561fa8be6ba4a27de31f3e674e529840fa5f718cbb9b7147442154be8b5feade57b57feccf7feadd79b4e7b3ddffb894bcf386af3fed2a1c3c36d78f5eac7ede0fc5cfb0fd977026f0e790eb3b27f37e1d9fb2de60538cd2c7d374b65f248fb16b989aeb0548328878ad377b1906b72d40717d8884edc182b28a10d7d78e686cbbebfbcdc2ba3d559e87d02496c0e2666db306e748d9512cd1de35a4881e148b38826fc3914e1824a9500d47ffbe9e3e70fd757775f6f2f6f7ffe8a739d8b03ff814df9359f21819b4e0e1c03cfcd6e857bd342960a9cbce576d519dd96e264fcbf5d7db9bdfac7ddd7bf5ebebbfaa2352aba51efbf5cfef4f1eae6364f303d0da50c2773db29ae0e477b71a18a4b4a12a09a67fa6e23cace2b7ee5fac3cdff51ed79d6d473ded8f30c4396f79cbbe6e1764ee329d20ee38fe56b5a718d23f455fcf7090fe5e9e05288705dbc857a2c8f07ce513fa54604b22b2e6516d584f655ddc2f1f866079cf486fc952c6f7417a75839e2630849b76f2c14b5bfa3516fdc6eb7eecc777fac1b1c9aee1bbfa8d77c623ca03135d62121a4dbdf775e6a07b6386acec3075abc0eee156e5b03afd589f1508c623fd52f510ff09884bb9c26b5b2d69169d376dbba33dffd71c33bddea0cacaa99c6b34c508f67d25bf34c78b1f683ed7b9749e2652c56a42bf5d2b93e326b832543c6fe92ddfd45d1b269bc022f644e03530b10defda5a511ce8ec5cfa6b0ea60a8bd9a1012fed1e1b02d3b3018e53ab236619565134830976f35ca0402267cb9d6df9f4321030e8a8b2cc3b156e3db56a741081343cd025abfdc61ee8ee59864904868eca123d6d12f2bc80e1fefb9d43d94cbe29cc93cac9401e687c40d37ffce9ff15fd970fd9a6a9eebcaa5cac606ffb15c03143f8ee8d80169bc0eb61ed1f1d09891da3bfa7aa9d843a64a057534868536073432ef1cb237cc0d4f8b141064821678b8440264eed9653dba1f2dc6a567170b5c9407f7a3fc734c14a8b92051bbf766733fd67cacda68d5d2ca836796cd5d37e8c61852d0962fb0e7655a10b90f8b70464190c5503fa5a5764f9ea69f443c8b1969858cb3f58267690ba4cf59c2c3c815c9a8864f91be68897720fd544c888b7769f906387df462343f9ee1e1a3f112ec5aed4fab6e09268a1af2dcae32a0bba1d0cee533418d838cd7e4b1609b52946bfb1f4735b0f13056fbbd1f89f051f7539debfd094f8e67207cc11f8f6730831986fb111d13a69a0feb91fe1deb67b70b6cea81da02dd770b4a33f613faea550f0461ff4ed531f964ae823111ff5e3c345d69542041f0c780c38427951b5811c29b2bb7ca15e9c103a9beed99a8116db7919dbdca75c3070c2b3587260f86d5eb7eef22423878c85924e776630467bd5ee5fa8e23d47d1cd1da485a7e0704791cb1bd34b902aead6ad5c8c68499b11d0a67e4a5e657543a2d471e38c466061a6a7446a2a1ce32559bb23dc0dc7938926eb7fddee00cab999891392c481fd66aeb54436a557b234308b85a22e6d87e1b2734f5965478b6ae7c63b9a7de923faa43fbd4938fdc6f6984bb221bdb88423369420c8c8cca38f5b83565a58100cd6b9607e610d47a0ab2e2307855bb4eeab81246b44dbb7dec3ab3b78ddcbb4f676ed339a9c1f90b45779fbd5c5cdc5dbeb399831edcd935d88334fe9d068d2f3a9d0e201593803510fb17cfbe14e5107b6b0dc842193f50e3b5a7dd5ef88638db6144d5f45c00b8b0ac670e85870bdf186ee7318b51ebf6ea1fb73f7fb96a75d818c342df8529527d9b7837780752a54abad2883b78574decc1c2fff2d39bcbf2e7e79baf1f7ebab97a77f7e697db2ba076a5d8320a4634ae1653063e5efe74f7fec3f5edd51758284ef5eaf2cbf7e7fd7053cf7bf7f1c3e78f979fefd4f7d5d75b55d48c322a42493fc6cb45b8ac94a5922db3d28fd1e3a895868b6542851a2373c670479bc8ea35ee788ae6f942b4841e2499fb0ed623232f31dbb574b7eb23e9ecd7edb60eb9956db70ca948a07838f7cbe585dc6b4d42d1e10561b022196218e6d6fd15c53023abda79e457f8acfb9b16318af09095ef72506806a35678f740859a019eb6a015de9927b18a6704546476974e04a5ecabbe00d1caee1c9b2a9568c6b1e706fa6e60e0064e4d098afe7ca6c28e5d6beccece143dfa3500a00ac0e861fea6db6b5a68ce1a8f7ed187a7c1ea9dc3b02ed693d172b9f779d2aaf7f3383afe36bc1b49b57daebad4575402ee46b2d31f932ed34f1d17518331393ba6be25293aea54e7eb384067fbf9ce2bf93a7d1df962afc61f4c4eb7b01fab39073af2e57e5b7bfb59fbfda6bcfdc15e83fba7fb2dee9f3535b97fbe9ff94543cd3f54339fd65e58ba232bdf3921a03bb8846f182ef367a899598115a9a56269f0905d14a516dc6880cab81ecc8d9a4cc34341b83559ae67dce10a3f44f1e6522b712ebba4af08471cbdba6cb74d9c2eafdd9e5be58d6d0facfccad906dd814128b83cfe06df70f579268575ac6845d19edaa34a378a5db826748fb1b92714ae080305e05e45c69b3a45303b83c5fc857ff9e5cbe52f56d9086b9dac93de8532ac27dfc1c27ff7cbcde5c70f6fefde7db9fcbb367b4137eac052ac6463887a367d500b3aa71970d4876b67b90fd4722f090cdcc31556c90fcefad546b254b80b1d06b0f0df5f7fbabc55059e1ebbc2075f6d4f5fef3e5f7db9bbbabefa7875730bbdc345d68902f4ff50c93f62904895ae18400d94aa7de7cb87cb9b9faeafbe420f5e1c5f1a6e660e335868e3ba47d54db8861bf846fa3fc267c211865fb5e595f6c8ad5d245e921edced4b565e9c1537ac34532520d743052994d612c1144afd6130813dcd5f1041cdfa2a485c0382a555c9050f357f2ed65f4f6b29e8244ef5ed6f1ac5d962e94d553b872d683d84621db399f7402767de84275cd4624fbd074bdaf5e255a9161fbc7cd778e7957bcb33e9fd67d207cfa49fead6f138f21661ccf47b78d8dbb4a0e5795e3cf550a5adfeef1e215ecf2f203c6f96dcbd17e1ccc89c49ce530fdea1b20750edb0bf5ae3a1c9bef3ac52adb19efe1faba7ff67eb19fcb17a067fb69ed33f56cfe9b3f56ceaa5289c438549781f0fbd5d0b5abbd6d8ff95c70cb5fec95a15ff1e254217923355c6c0735823556599aad1dcdbe7955c2cd325b89c939bb808e599e7f0516e9a297c8f457a7efd1cc0df597297dfbef7885ba9776c86cae9e689dbe07cf85ad0326d9a70c1a81ae1058fd07eefc13bf31d68d5fe0f2ca22b9bc1bcf3ba9fcd3b51f960bfc7b5b254ca17fee8114f9f7b9f03573df0d4f23971325741def2245b30dbbca2b9e0d6562bd4d46f5faccd339cd4e1b56b4433548a4ef4f2a9a823b2c1d5012a86b958394efefef3f9fb4fe51f7c57fd3d37ffb3b5596885732e90774c8aa11fd613fd95d721eeb01f3f01bbce61d5803f05f87b311d4fa3d74933bad48882e3c4476b4d2f651256ae8d9ae8036288222d38d74fa8578b08ce7fdc8de1c533ee946b12e1554d24a6c5bb2b97e513cf59967cce459070597b31f7a95cdf9a7285cfe5ba69ca953d97ebba2957fa5caeaba65cd3e772dd37e59a3c97ebb12957e468c5b4fd9a3ad5949acd9c27034e4c52a9035b75f92bd66eb357c25f7578bb2dfc7597bf92edb67c25fc7527573ebacc7b52be22e6156e3f1c2b10c420aa4a38fffc4b40ce89c131c7b68ffa148973e7700c424b3e8c9548e1554376481fc75324081dc9b11f2e97c9da3e350c0ce3fd4ece9cf7971d1b2ef34805e9434cca07d5c38a21fd1cddc048021d6360dad4a67ce0635d3ee5b383cc95e8ef3f4310ee3f43a0eff155ef23e8f17fc3336d4e6a66c0783ada0d0fb9142bbc47a41852d4fc2e84d38ebaf5d50a6f44a7f3ef3f1042d41153952072f3410e3139ea0f2bddeeaef553f7d5de77d7bee44be024d12fe0b4dbf288107e8164bb3d47f73092630c92a8e2e2ed768e1e750c0eac5e30876fb7910528b218097cdc6e2fb52fe4277a67de89a85bce0bd38314d526efa95e0832d2dda06310a3def802c5648eae4034bcc114eebdc19461583cf3fcd2d38f1b3d802442bf2862b133effc137d5715eff79c9728fddd533834db94ee7f4642fd90a920a370bb95f978945a93033d5800efc6afce7abd763bbb98a3cf20703047dfd400c684c31c5d83c0a65378878d1d75fd9180c263f35e8a6ea13ee89ae129d41070a5fe5cab3f37eacf37f5e7b3faf3ab5956aef124c2c319fad560f925d9e851bc5267f660023a704dc30775cc2ddeab0852b04f47041914cf3b04214c9278f22d8821ba4fdeea4f01ee5315dab7e6dee3120173dcb6d7bb482ee172f75d4f8934bcb7fbc49b1f8a4778d66977ae4bd757c5b85e75ce9b7eda52491f860e302a5580e0fc5c55fa9ca30623f2aeb8aab5cffcbd80840c8ed1e0194149e7e7981d4ec5b0247f46a270f0cce39e080bf02abf070fe4fbcf7cbadef0ae28ea4f9ff3fe6847fef4e1cd57e70abf971f972776306c1ffcf07ed6342673d28399163ae999b2b2c1fe8be34451cd3d61d40cc35ac73ab3ab225735cf0f68dee9e3e3e4f5ccbf5f4b7aedd80ed1bdca06c71528600dd6457ae3a9554bf1506a03a3b56e2aac898419a18505aa119715ed0af186911084790c941251d3a13cc052ed488ec4543f1927aa3a14daa4435103fcb4e244732a871415b1abcf780a4c57a487a2aec4286582f5559d33a871049c88e368b818712dac87c58877faea730deb11ef0cc6849a1a74cae998480b74a63e0dd07901b483f26258c5407a8530cc3ba40fa1ae7507e5658b0adc5ccbcfe7a54c7ddefeffa83b831d3761200cdffb14cd1e10a65304c9de56ee6d0f95508ad4dea21c28260b6263455936218df2ee950788c70636d9b4aad4cb6ac1662e197d1eff33633bf86e6b69e787463b17907b4285bd3d19935a4df9248015cf8cde28b366ba3be622c57b30fb0740d93e20a96a2e4d59bcc261ad9a5bc34f202dd53c751c37e59350799aad9a17a66abe627ad274e51654357f8517a6868724eec250cde5fb54f331938d63dc83b492c293e02ac95c52b95c6242f73b0430f5720609cf3f876dcbe550bb65d2f64f6e7da33ecc5d777e91a05f40820e952887c2ca79d29739d051979c8c55f4da9dbe5a3b2fdd1a707ec85a18c60a86fb2f3cba8a86d19fd1b06430e7124a5e61b6e844cb10d851f00c7678e707a47c6721f0117e3210d4fd53061f367c673230bd998162146e1bcac0b7a6b50c7ce66234915bd989dc87f9a2f2ea867af86f97c36d9f107d98a52cf179a62967466258b2b3a6824c7b5e74ce33b58cc2c1d851a38212a35bc69a73b1e3e0bb9dc5b9b2f1e71a62af869a5149851d339741fc898766051a9542d8d1fee504059730c9f48cc31a5cd67004c202d7c1715cac4f147d706d4c70ad999e345db91b0aae1c9e981a1ea20cf1019881d0e0aaaf00d798c90e5ca20fae8b66c3a9b24bc825fcf8dbd7f90f85aeb8d10f537a144393ede3f7b0e797a0f87678ac764fff3a3a7eb4a3e3d9ff1c1dfbf5612cbbd1592a64d5660de877bf3e7ad4f422582e82e5fb62ea68289ede23966d94470cca1eca2306f1f99af4268a953ac0ab7af1cf96c63a054d03273441fc3a90137e39c73f37af8617da8648f1dd789d5d1840b7bb957f63773bd064a33fbc0bfc30f0c33bace3537f60112e991bb2137bf81d0000ffffce0c5d9bfc000100", - "f256e6f5a46e10e60db6a2444386dc4e": "1f8b08000000000000ffdc7d6b73db38b2e877ff8a8eb237a21c85923d4976d61e65af9f19573976ca76923b3737d7059190843545f000a06dedacfffb293c48822028c94eb2a7ced187a9986c34fadd0da0c18968ca05ec9ded9dfe717972797d7974f1f9e8e2fad3c5298ca0b3b5f536dc1e6e87afff166efdf5d70ebc84ce20460271c1309a777637f4e8b3f3c3a3eb93c3ebd3a3b3f757bfc308debededdd8180c604219703ac7c00543e91403c388d314229a5026dfce91e00a0ac753cc01a531a434c61c528c631014c6186232996086531186214488e1499e3c33331f1dbe3fba3e383f3dbfb83e3c3adefb747a25c97efe5afd4afa2ca8f34f57efcf4fcede2bb05f7e791b8fdff8c04ece0ece3f14605bd1aff15f2725d8e7a38baba3ffd39c7578ff56fdfc807b0757279f8f349c336f0deee0fcecece8e0eae85083fae7be3cf9bf12d59614739420cee198d154e034863f3700001434cb23415980b2ac671ecb9f98111ea22c8311a02cdb759e4782dce2331a631841b7ebbce518b1687685d9dc791bd3289f4b0da1383ebac5a938255ce014b3a01b2524bae9f621c03d18bdb3e8903f32816086f8816421c0a1406c8a451fba69b7d77340e52fc10266629e18fa8a01bb5e40694727318cca11214953cc7ebffa70babbd11841261521c5803e74b53cfcd4d8c20c19e658ec95d20b7a4da2e48f6191b3b4f9eea149d1600057e787e73b80e218341da0752dbd84e139bdc59051cec938c140c50c330e418a23cc39620bed7b4a6130c148e40cf79a9394f4d7a9d7b2eb83603976387928ff7ae8c304255c02d4cd84a4445caa990b3118f6ec1796404beb9962719460f9cffdc5491c7434f99d9ec7ac6ef022cfdacc4aaaff1625b96d24a17a100a46e6412f14f494de617680b85295639481193c1a41a7e353bd6253a9bccee72a553b6a6e3a959ab83ea6c119c33c4f048711a4f80e2eb170679f5016280f003aa9341cf35085d6f3342129f6714526411a728198e05f88986929b49abe2143ea26483dfc3fb4984d832732090a5c9cfc538a1db67c930e06901021120c3314ddc8e4802269ec80b5cdf8a3008c4a4a153f3ce88529be17412ff4081b96f8448b3b34351a139e2568715649bb60d01afc609b5dab07440946cce7001d15573b2d0eb0cc3e1fea3e59837a9453161ed6e9ac9b2656454b43129fd13b4dd131c149bc16595d3de91786b20cb36e2fe46291e030e2fc0adf0b49a5d1cace38a1d1cd6ea73621169702899c7f90b1738a83399fae270b35aad3ab520b8c60cea7bb0decb25e7aea1c72ec7a33cde89d94e729496fb80ae27d483199cec694f1b526d381df99463e94a51f907447d68025ca90a4da65e54b9a0be72dcd857a6d197a91c1a542481ad13949a7baf6db01cb8c060328de96cf6a51cd26a1077fd6038a9ae0e5085245d70b8618db0555bcca42f5b7317b674d55052619fe1a9c8d4630941314383b29853ae1cf3a168e56c192d411aa446809a6100acdc594b60aa578bb4a283417ad525142e8b8a251b25a4f34855abdb2a9d3bf9e6c682ebcc2a9fb90a73cc9b31809fc3be2b391ae441a65ae5dceea51bb3653150237e1cc0817942d4286b3044558ba2e0ed23c49faa0ffdb7dde7da931dab1b56ee9a5cc6054cfc3c5f3af1ac337378036fc58725b79723380dbb1d4e2643080286772ed942c8a1a5279f31d491248282f4b4a49ecbdac2d260cf3d99a8b82d542826e6f5752a18884844648109ac20cb97328808a670f8bd6cb2747323b55adefaa6b8d6a1a7131cc30e1a90a5aeab1c140c904e4739893e94cc86530820c33b5644e230c372449307b568eb150c108f618438b70c2e8bc3647c82913b57ad78ac75f2d2bac8795f6aa51c60519061c33f1556f729630cbf92ce8fec633946ac31b755263979d77dd320c0d24c0bb8e5b6a014e387e0cea35707a82dd52933282f0c4abf01f94a441a7539aee43b1363fd43b2679241761dfb940d7bb23ded2bf7a5fdac172a8c9641db043c2239aa63812385e026b60084d979267454409f301658eaf4f8b5aec4a15e975b740b7d322945af3a96cb4b90d03085c19bcdaeac10ebcda92468a53c1163afc0528b9430b2e7db2e4ad574ea4576ea0f50d5421da5159d2455f563f41fdad2db312a6a793ee2b3839e42ebaaa8c7a5566fe02c0e5d480a1dba9060a1e210ff5ead5564fae808fc93d8e83edbaf8511cab2c42e23d5bf664123cb3a89d21ae205c47b740e4b25082ec7a16486671e5ab8a3b288e717c45251119a589665123f2e2d1295c2309fca9b8dc4911789e51a63647c8bdda2099a03c110b40294a169c70e098dd6216424c21a542961d663f926a6709dd958e4a4b269c575496796b4e4d567e9a3c6594a0090e316394059d0a1f8c73a12824a92130215cec74fa1e51b91b119664c82468315a8ba236bb8e718285e1ba5e2bd65ddd83ab7ce5e0f013664c77b5d119401ba9df68a60c653303f7193381ef9f64ab963e64ae35a1a2cd6c2b11b5b0694c6c0d3e0de46a46d7a65c636c27dd4ff23a81e0c711992e89091ee12e0d11d5bac271e0ef76d21aca1fe4a7b28e9fe1e806c8a486cd4cc2b16821fab1ae53456dafa6b4dfa0386e771a492ac34860936f25a965d29fa3cc337fb91a22f1deb732bf2b2467c5bbf3f13f70d4d8e96c894c4fcd3d35d555565669c457813e0e2bf01b926538f661f7ebbbd4b529d71c65ffb0f8f114df8c8f199d9ffb62878fab751cb245ed162ba63a731622e94e5573f66baf682ebcef1e7c7140b3e206829f524014eefe83c28db18efff975c1b3efb1f8efac4ad736f57ac08e31106eedc4e83ae1bf65b1a33dde53e73cd9e1b5dda86d9120a2a9b254f99ffdef4fc536eea59ed1972357bac75262f67f1431fbeb11d3b01e7b0128499248bcd6b34cc93522dd54a5169eefcc5ffb76f1e5cb8b72b91ec72af256a449d35f48a718533133ac23865d8f80155e012f5e343da1d0837c29a97d3672ada8c535501c1fc553ec585fcbc1a02d66194db4ae1ab08381d99d86b8b6fba37306aff68621a1f426cffc93d54b23b5f3ae23582b79f688fd6f2149db429e21d2f411a8fadade0d5106d918f033f2c2bab8f7d7c2bd5fcf170d8daf63f8ab0dbe81b66d170296ed5b160122a1d336cfc344cc30d32944c60bed279d563375f733abbde79f19671df4ffe5a1f611f4fcf4686b031a2b6d4ee8cdd5de98e486d8a70799b60063bbd2f2013abeb42f22dc22880317244960866e71b5287483bed6f70c71a9bb7221b02ab89451ce892ccb102e8d28659cf5b6782c0b258ef5ad174d56ef67faa2482d82b856ffa420520b1b5e25582478cf38eb26b5ebaedb02cf21bbaf69a007ef60d833d4944729efa57f7ce711ca8c4c670999ce048ecf569ca658a0eae8b10e5a8755ae0b23f84c6e51a8e8d48f1a48d55312f13aec6782efc23b3c9e26efcdfbe6110b4aa23c4182b2fad008a782a184884593aa042d682eeaf0a7ea5938a12cc28784297b0f2ad2fa8e91f18c91747a8ad3a998edc02fc3bee7ed01c593c90e0cc3e170b855078819b25e6fd75f4e19ba2562b103afb6c2edca08fdc225110f1392de0481fcafa7edc9989857aaa7725ddf6c176eebc8aacf6a16d91f199d32340fc63949e203c2a244ed4e5ece508c59d06b1f2f5d2f5047b1ed544bc3fa82c7ef4f35e2c06af5ed7b7b8e9792ce701a638699c7c88a574b54aead66c736a186de14673b7546fb6e741288a498edb4b76da99151d7d9b3d1242a97db515d774b38252911aa37ce5d59ea482a15f4891cd08432d311a59acffbc0d12d1ea98e3e37a2c9112745382b7538d536f0e944ebd1ee2381c08c7936823c8df184a43876ab010d12ead6f791a6a2adc490b479ab093776e9eecb3a3d0f4d21484916422882fe6a414434ad49418a40620a7cf50899c85a454a20cd93c4255ea2934eeb97ab22ef448e0f49ec2446295d33729974d5240aac94708618c79a67f56879e7668bd47d925776592cfe9a14b7d4e00d4dec2fe41f27b1626fb536568a4f05c5ba59ae21b8f585f67813ad04e5d056df7bad753b719ca884e4f6911485772325bf8321fceb5f2deea1ca8b77aa4dad519a2618a5906745638ebf1c5bd2d7ef6e74691f19e329493f295d373a6d56f783d9dc7fdbaded2796bc151b892aa2d44968863c1b61df7723a5d7364bd9e568ad604ac865cd984d417a2271bfe5d68baf2c6ec6b0b40f75c63c57775a7b012a16692e1ecfa3eeadfc373059e730edfbae31ad34479cc69531d6de176540c8b0fea7e7b2469157ddd21aabe7f5da42555927699617a3ea9581455423856b74e19ce61c1fa502b3d65ac95e7c390da132102f2913ec394e31bac541e0bd90f423a30cac1169e011b7881e6afc81d320f991e15b4273aeacc7a3b4e5f1a97969c465f389566faad5eab290c7608bc913dfe44a014b26f7a6d4bee76ae052127e88cff87792fd8a40715c2ba6ec8da862dbae6d1fc8531aacacd43c24e8cd5f056825e88a17ebb4a89587b2bbc943f9caf14e839463d35ac0eec84a07791a349b2df7b22c21a6cdb8b94f90b3a4813067098c20678923a34971a5522ffa8b1b962a40b8f28c8bad815aafa717b4d82790d02a7216505e36e5ecca6a551b35e120661890c5234a1846f1020af8bf3b4c2494c667f80e463074f993afce9358bfaa55644febb6d73af535afbb322844db72edd06acb5fbbd5bd66559e68d842c08a9b482b2e0615e9a210be374ad9cc36b1edba4be67243affbbfa21af80e74e125ccf9b40f5d559befc865f8a2db5a57af75efe8092cf871ae60a431e8b1ecd437465dcd37646bdc3274fa899b37cdf4e9a13e17b1d1722c4e642d728b92a25468dc5b748553dc7b0b13b55bd65613f8af86b64bdd7375a060afd69c5f09ae0fbf0c878ef3c870e9240e59e311941ccb487045e6981de7690423f09746a69db80c29ef9c38f212b6865e7e2b0d79b6cbc3300486234c6e715c353d9793bc848e3412b7711f3c51ac3670dd33b8042356eab9dc50aa09a56d6a7555f642f90d49a74b8a35cf8e556d0218d5accdab953ebc29355ac3f4058f398d6eaaddebc2b61deaeafd4c3724baa19389491bf6953237fb089663efc666582f81a0d17bf9e3346e557bcd93119b2de32960b7eeabfbf2c54d788293b82d17b9d74e3db7b26ac1a26de5ac0e5a32c4398e81a4b2b2a8ef02141f26b823694cefc2e2565438437c16f27ccc85d2d8566d33a7c8a4bef0eccba26d61d43199461c55cf4d79f2058f2f355c6dce207029cf181534a289be323f1322e33b9d1efc1d3a779cef0c061dd891ff94ffea15fab6c56288f59112d29466386d094afed8df2909073916c7219c5214cb85beb43d379678227d8bc36b8ab8ac023bd78dbb447d19ff6c1f7d58ca963aac967cb52e749731a647d3b16a388c43f89860c431309c5014872e6dce01791b9a4e1fea17dc977330d764b5f1208d5d2c32fd15861809f475f86db701215f9410c6fc6bb65f0092780f4660430dfbcea767bca3f6eb0fdd1cfecc2d7feae1e8e5cbc60930bf23229a412079f3a5bb482aa273ddd969bc01152a746fe84c9ae32b2082c33f722e0041668761fb376618dd389aa84fb6d73259ed80d8acd6406d85f87b422b226142128119d05c009e67620124e65e5832918bb7a2e4198d5c9db47c3f02aab593671de9fe9afd4296605a8482d6118a75c9600db914047b17ae2dd441bbda0e5a2824f1be63ea7599aeb07b2fa3b5de009bd5beba4ed669eb7ab3d9ae35119178efa5dab758d232b79e18a27fa318dc2e89274ac2eda8fa71c2385fc76aeb770a1e61b86d37d61e4f277d0c9da63bfd09845a1df92b292d7ecd13b8878d8d0d990d543788a95e682a53a55358e8a61159fc581b4981e7f368861ab56b2b57566a8a8d8d499e46c51577f359ab04cffbfa4af2199a9709c39cfacbb7a17a794ab808cd91390f2af85d89b944db389f33e86e11d3efe203739237bc1f0eff86f1af938909906a01b7c8309d98efafc962adab8bcd2ebc78013584c508f5b00aee23782d53e46000cfd974ecd418d6c976f14d8060107cfdffcfbff5067299ff97adbf6c990f02c4b9962e068ca299ccd432d9e0fb08670226847101cfc38da642bd24fdad24894da7e3314235baea62517f9da4c26029eb8d3e6cbd6db65b79a7fbab998eb262c670c984c1d219e1b7dfe0d71efc0b86f75251cef46e4dc8e81d7435627c9fe9465d92c20cdf9b8fe9c11d1133c8e4ea4a95bb9de79d108ec26908cf87c3c964380ce13d351fc7d21b308d3e0487fba6c5a4f97c8c59d736943ac716ca72e34e19bb05a6ac7a63b0b9b9019bbaed05b8c82713d880cd8165ef76470c27ff2cda378ac9753daa3e4602fa533350355ed6a879d8180ce00cdf0b88e81ceb7dd41962b1244ac83a6c9ee9be14bdad4a27b0f7f1447552463917740e5c75f9482c996e03ea432e5778e305a8a3af620796ed54d4b7340a19e2070338969a940e90313227eafb1c77587ffcf03520211819e702f31db8efc3c2f0aed7b3e49fe62e91f4fcbdabab8b93fd4f574797d71f8f2eae3f5e9c7c38319f1b7c5d75d6a845f1f1258ce06bcdaebad25e089704cf714cf27906938422b1dbad77e5746f115b48abbac5d16b23d706082531cc114903f9af1efce902181f0ea6c9f5474a527140298bc37b7805c3f04d0f36a1edcd4bf7cda2754cf9e6371886db6ffc54004c93eb63d59c661b8a07b270c6759048d104c39e178dfbeca1fb4d7f34a2fbff52bb034ae9e9b3474fa541c869b6015ddfaa03968f94bbf30d06f01145378ec100490595630565211cab282b13502ad4fd24d38082239ac6f0ca32310beb2549230c4474b9b611690e9994bcb4db08990b1e39c7b0fd1ac64480a0909594f0306c6014b39c034ab219826886d21427929898d12cc3715fd14e2480fa6003e23c9f975f06dd0a57c847bbee5ee9470db5e429918153c3e7d73c6218a7973290b441ce91780df9b56028e5f2c1cf721265d19ca83032b227844d6d6496f60736e57d18f661cb6b8185975cea80d994cfd7ad6fb0694ff675f84d2eda3db894f621f2a3f10fd1f96f0c2398d33888fab0fde66d38eced2a2c72bdcd8268609eb50e9f7edf70b6d670e33783116cbf79130edbd12118c19607a0eedabb5589665247093d4daa7f8ff3c904b3eaef627bcd6aabcc0549b813298af349a9905fb6d5a77f82b7afdd787240f354c8b2b07a1ea1f416f12f2416b3bef9e3774ca633d187d2002a68c20f14c8216162b16ba7756b6359e6f3e2b7090728497c1952baafaabd6512d6795587a669a29a46f1bdb03c7b73604904c53b50a6d7609a1c68707793619ac008cab7f5d581a2e59314a4a781c542591f653407236bbcb9a45eb4059bb8dd2f12ad83619a84392f810d3e77c7aa50797d9e2916a7c59ba02c3fbe76ad18d0ed43b7e989f2a91d1cf4dfa576bbdf9a34e2148d137374af1169932a490bcb399f32d8a5d0c1a17d4029cf48775f3da935def59f6270e6a68cde9c2f222b49950d9a5991a4d5c267a3fedf1992ea378dbeaff4b6e59cc6385145a2c4521e9ae86f0c59a5ab9e47e658c471cf8336a31c5ec19fb2ca7b804816312445425d1b57a8558393d7250a566cb7d044f6e53bd731641022f1bdf91cdea79390c4750528dbfd2a41365bcbca6f721d457978fff8a1f012b6e4f05772fce249e3b7bf55d43bab974760f9c5c252ad1c969bd705fe8f1c73a16f4b362d0c45224749b28098a13ba039334b1a15dac40cdba8ac480757d2324c6b474419964a57a35564f4ab5dcf6b2bbd190257879b69128e491a1b179b26e1dec5c5de1fd7fb9f8e8f8f2efac62d3c63d4f3432450738c127f5f421dfe71b6f7e1e4e0faf062ef8ba7a9bb964fbc9f23b601ca36980698e453d7661f9060e4fef5e4d60a375522d3e3add4e6d94faa706d4f2c247671d59a345b8f7f0de25b2b28aa2a0c335f4cedc3b692def1e9f9de554974ab216fd6f27eb8ff470172747af4e1e8ecaa0fc3a6fe9693e246e81f4ed1366cc2eb2655d26bd4182eadeae3f9c9d9d5a52a66abfae5fb92c0dd0ca77269c2804728c17c90a1d4789dd2a3de3cd1374dbd4ea753c8556140b5908befcae78d33dab27457955a09e7f88463eefadcfd87b0cbb08c704f60559abcc3e5816dffe5dfc605dceb8915ac66dd1abceb81d4586c50fde4270b4aa8f3383291eb5610332474cac577e65ba9889bcfd2c445bda0fa1fbc7233dfafa1317613b2ef3e9053e6e17b81d358574c268e56b6dfee723d4f02d4e5fecb116cfd0cd1146231df04d10971b960aa13b3558229ee53191e740f95cdd52bc955e39e2f145de0f09b0dfce205349035e2fe600077b8f8660fc33a89ab165640e9421fd5963ceaec17fa909ca45c60144b64fc0e6506475c7c7357cc14824e82b8e898efc2a4f5caa0c255d4a4690c319666c531cc11bbc1ac280a2d3c21bc27b798434a220ce7c156cf87d1fa7e6c5fdd899fa31b5971c418b8ea5c49166a4b54ea7d86522002229a27318c71f3a8c75e05d16ca18cf62362c2365ca98cf622cc36eea5606bdafdc31a86ae4aad391633aa7695a2a5b153f23f43e91473b549ac8a7122b88d4f2b8987f0459a4fda156aeb8b0898616684acf6ca528c633dd1dec7130838c6a6da9bd7ffcf059b4584b10e987b86e05e8b5fa973968f8c66980982b9ed5ee665718504df995b5585841e76371e36fe330000ffff85c9196802680000", - "f3aa7c7c063ea75f55c6f07e3b99f877": "1f8b08000000000000ffcc595b8fdbb8f57fd7a738ff0cf2327fcb97997a67a1c13eb4db6c11a08b14cd027d580430251d59ec50a44052633bd97cf7821749d4cd49da9da26320b128f2dc2fbf436f6eff0fb8901561f423ae33a5e0f9fbf576bd83dfe0e7b7bfc05f69865c21fc0647aacb265d67a2da70cc04236a333c77bb89a2cd2dfc59644d855c4700f0c3eff6e7a9df46700bbb35fc28a4c44c832e1118e50825d263a98172208c412ac549a1546bb3fd6e0d7f93f88c5c03c9ffd9286da453200a2804d7a0e84704526894202445ae89a6824356127e446528d277ef0da14d1495ba62f029027b322e4845d925814a70a16a92e1aafffa089b5bd8994360058c9d8009ecd6bb7df8323e61fa4475acf1ac63234bec844c60b7ddbeb63befcccecfd6b8ef3133d2a99733eedfb112cf680d5b117934ea4f6dba89a254e4176b0ab72b81ed6304209e51164c9c1228699e237f74727bca3c4769291f2a42f90190a1f10564822baa3472cd2e86dddb379e89d96699e454d58c5c124899c89e42aa612404fee4792bbee07028771d330527aa4bcae1a09c2d0f66b3a1742052d38ce1c1c863dc619dff632945852bf8894a2cc4796549bf270591b40d8a5d1f1286790277583d8696597ff78095319073e25fa4686aca8f8ecf0b67ca1ff3dcda26f3764ac5d998c8b0a7bcd5aacd93f7a538d9ddad1fcd9e37f9d119b4734b29adc6a938c78e54d2aa12a7e21c46771bf5db70b10f9267aa68ca7014e573494e7989926ac233278bca08333a0cb27821fb433a22cfe180d5a13be50d3113e1b5c46fcff5200a76588dd3f71793e40c9f9181c28a704db3ff4e2a1f25b9404ab2a7a3140dcf4d52904cd3675b3d9f944b3ad86dbdeac4f9b7db1f67820999809684ab9a48e4fa71e8ab80572ab41615a4429a74ef5208f60fb177c838264db2418e9990aef6066967826f056fdface05d8d92cca41f4953f9aba69ae1071f95866feca448800b3e7090adb33daf041a53954c89ee9d756d17e4426bcce74276ac960db153d798862a4df4485791d252f0631f74279f3da96039cac7ffa9ecc8448eabe829cd57912255fd3b67cab23d9754d94491aacce2a8167fbf7d1d1aae450207d5a4b6f29b6f75d01d0a292a2045619a033fce000c43658e79631cd8d463fe0ffbd78f630c605b652d1475b1259111938b66f5194d13222c268c1e790229516883d3e8a09ad487b88bed78bbbedb9b5e63df39d65ad4f645bbbeb98537558a798ef9cbf79b4115b0e96fb2b9220e48299a2fd41b5a1dc3dc55fac2d0a7aed7e12721ab172c95269f2ce00b708411422d65cd2c4cf2dd7426b71bad055f4594d78d5e45a2d6a6aed6ab4821c34caf22536f8844f29fa5510b18bf0677f6b06d26f36671806bffc6548b30614e5df874b5f50f006267d3b0a089c23508db7c0a21ab96db0894f5f27d0ba1000105923bbf0c44b72da13b3a88ce0910a59ca494517d012d5c2041c668f6445286a02f7537572c87caaf66db0fafdce3ab0fdd8244853a78564d5a51fdcaf5be769820758d441aa513701416edcc51b6b96a64a9499e4fb161275792c495f81817226b546c0f4f24bdb2c5cb7e6547abcd74cb627d8056e6a443d85e4ba5856c133a6b549bd10d57a821bdd837b5c4672a1a05b261c3f00d2490941fa77a2ebc6f955c78dd69387c6fd5138d36399bc0ae3e7b9c017fb2ec0c705c0ab645971514596e74fd3430d2fa7e6fa691f583fbefbbbbbe55cc610b9b322749eada3319cd03630c61a1e220ef6c4b3db4d204bdb62f2af783a46d355202720396458d520191085c68c848633ab168349c4ae4e6c4053ea21466c9100358e236d3b7191e91e79379a643918371c6c360af5c0818bb01559376a0e90aed393ed15c97d3021d04ae59bd77aba7926a8c6da14ffcd54c7f68191db5c8012c72b073f5d2f86aa17437e588a344a5ac05aea28f69f5c8b1200d0b58ab4c0ac65222bb06ffff9ecda0c1f55d80345a8c62effac0daa18651130e922004163ee9b212b3a7549cc33a4a722a5e7df84ac78f3c356a9783f06fa412d2177d5100e59974b71cc6f239b64fae8c04570c43897953a5286d21f435dd56c158d594c7a31e31dd2b1a3ddc6bd56ca1c08cd1c74340df4082016ed8ab26b3832b5e5e73ca876dadad7e4864565ee956264e6cee0e2e0c1ce9581485429d407c579fe7fc30696c41544c7430d0b4225977b73792b037a65b09a6c145e1c7906032a5fd7ba8c05adaa1538b4c6b690aa2a6a80ca183af468789cd7b150aca306e6a26481e06c415b83042983335cfe1f2b75ca37457092f82cee72a9dafb53d0c7495c6d5b6610bcc5113cad4f21de217e8cf0e7a5545e465489251a563aafb99eb67aab2971b57ae483caaba55cd88c6a1b0e330fd12b53641dc95ee87456271ff274e3c788acdf11b268ec29e0d665f922ac11a6d611c00c3a29d8ebb0165b7adcf6ea19b64b6dd52df57cdcae7285a074cc6feee89c68e91ab83c1b20ceb63407fefef106eec359327efb1c051e2c56db603826f9c199abc70ebe184f68756f2f07e27152c1fe8dc9ac097afee2e6befb5bca1bcf882296570d3d0b72f67cc9154bbbb56a840037bde31539ae8468dd98597169de0dbb1c6f30a43afb1b3e20d21c43d7f8c29cff16c7cda729748aa6f9001eeea336ccd27e4e0dc6409da72fe0f0368fd543189e62f333186842ddc9b7f9704b77cc60c28b79d2c08c9fe967574bf6a5f5a3432ce89b15bdb671fae77dbdecd57a33474b2953671839293b99b467aa3786ace5de658c6904c8cf8a23a3a7c95402da84bb1a99a9d60d7d4e93795068e0e93ba8fc7c945b0554d975234c7d252896eb8c851bdb34afbb01ac5290c63a82d64df7775ac05c4f125f1187a2ead3a53ec5dd8cd3b78128881785ff6d4e676e0ac9491ece9d1b7fb012555137ea5d00e64ddb77a8eeee6ed984b548939dc3c64e6b3e0e339e66bff03c6d071f7f7dfe5e97efe445250a9749c9594e5fe9817c85e9ace49d392799b87bf756ec35b877d5b03662bdc959f1ba241f5835e644df45796ba87c55207be4face0c60cca9fae8593af62e6c05192baccc6cc61d85bc26976dc995fcf056e1f928fd1e77f050000ffff222970aa71200000", - }) - if err != nil { - panic(err) - } - g.DefaultResolver = hgr - - func() { - b := packr.New("Assets", "./static") - b.SetResolver("css/normalize.css", packr.Pointer{ForwardBox: gk, ForwardPath: "f3aa7c7c063ea75f55c6f07e3b99f877"}) - b.SetResolver("img/gos.png", packr.Pointer{ForwardBox: gk, ForwardPath: "166310f2d73113b478111b0a976a0eea"}) - b.SetResolver("index.html", packr.Pointer{ForwardBox: gk, ForwardPath: "2f53e054245e3cec681be9135541dbcb"}) - b.SetResolver("js/main.js", packr.Pointer{ForwardBox: gk, ForwardPath: "f256e6f5a46e10e60db6a2444386dc4e"}) - b.SetResolver("js/vivagraph-0.12.0.min.js", packr.Pointer{ForwardBox: gk, ForwardPath: "853579e9f8c28c5a0ea8a5ed642bbad0"}) - }() - - return nil -}() diff --git a/plugins/analysis/webinterface/httpserver/parameters.go b/plugins/analysis/webinterface/httpserver/parameters.go deleted file mode 100644 index 0bee3d52e7250dbac3afcdb00715f4965b1e7c51..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/parameters.go +++ /dev/null @@ -1,15 +0,0 @@ -package httpserver - -import ( - flag "github.com/spf13/pflag" -) - -const ( - CFG_BIND_ADDRESS = "analysis.httpServer.bindAddress" - CFG_DEV = "analysis.httpServer.dev" -) - -func init() { - flag.String(CFG_BIND_ADDRESS, "0.0.0.0:80", "the bind address for the web API") - flag.Bool(CFG_DEV, false, "whether the analysis server visualizer is running dev mode") -} diff --git a/plugins/analysis/webinterface/httpserver/plugin.go b/plugins/analysis/webinterface/httpserver/plugin.go deleted file mode 100644 index 1603b36ad2d5304a7e990cd47266d46cd939bc20..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/plugin.go +++ /dev/null @@ -1,88 +0,0 @@ -package httpserver - -import ( - "errors" - "net/http" - "time" - - "github.com/gobuffalo/packr/v2" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/logger" - "github.com/labstack/echo" - "golang.org/x/net/context" - "golang.org/x/net/websocket" -) - -var ( - log *logger.Logger - engine *echo.Echo -) - -const name = "Analysis HTTP Server" - -var assetsBox = packr.New("Assets", "./static") - -func Configure() { - log = logger.NewLogger(name) - - engine = echo.New() - engine.HideBanner = true - - // we only need this special flag, because we always keep a packed box in the same directory - if parameter.NodeConfig.GetBool(CFG_DEV) { - engine.Static("/static", "./plugins/analysis/webinterface/httpserver/static") - engine.File("/", "./plugins/analysis/webinterface/httpserver/static/index.html") - } else { - for _, res := range assetsBox.List() { - engine.GET("/static/"+res, echo.WrapHandler(http.StripPrefix("/static", http.FileServer(assetsBox)))) - } - engine.GET("/", index) - } - - engine.GET("/datastream", echo.WrapHandler(websocket.Handler(dataStream))) -} - -func Run() { - log.Infof("Starting %s ...", name) - if err := daemon.BackgroundWorker(name, start, shutdown.ShutdownPriorityAnalysis); err != nil { - log.Errorf("Error starting as daemon: %s", err) - } -} - -func start(shutdownSignal <-chan struct{}) { - stopped := make(chan struct{}) - bindAddr := parameter.NodeConfig.GetString(CFG_BIND_ADDRESS) - go func() { - log.Infof("Started %s: http://%s", name, bindAddr) - if err := engine.Start(bindAddr); err != nil { - if !errors.Is(err, http.ErrServerClosed) { - log.Errorf("Error serving: %s", err) - } - close(stopped) - } - }() - - select { - case <-shutdownSignal: - case <-stopped: - } - - log.Infof("Stopping %s ...", name) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - if err := engine.Shutdown(ctx); err != nil { - log.Errorf("Error stopping: %s", err) - } - log.Info("Stopping %s ... done", name) -} - -func index(e echo.Context) error { - indexHTML, err := assetsBox.Find("index.html") - if err != nil { - return err - } - return e.HTMLBlob(http.StatusOK, indexHTML) -} diff --git a/plugins/analysis/webinterface/httpserver/static/css/normalize.css b/plugins/analysis/webinterface/httpserver/static/css/normalize.css deleted file mode 100644 index a0feda7664c4890b3ba635708e0e925d05319945..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/static/css/normalize.css +++ /dev/null @@ -1,504 +0,0 @@ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ - -/* Document - ========================================================================== */ - -/** - * 1. Correct the line height in all browsers. - * 2. Prevent adjustments of font size after orientation changes in iOS. - */ - -html { - font-family: monospace, monospace; /* 1 */ - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/* Sections - ========================================================================== */ - -/** - * Remove the margin in all browsers. - */ - -body { - margin: 0; - overflow: hidden; -} - -/** - * Render the `main` element consistently in IE. - */ - -main { - display: block; -} - -/** - * Correct the font size and margin on `h1` elements within `section` and - * `article` contexts in Chrome, Firefox, and Safari. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/* Grouping content - ========================================================================== */ - -/** - * 1. Add the correct box sizing in Firefox. - * 2. Show the overflow in Edge and IE. - */ - -hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ - -pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/* Text-level semantics - ========================================================================== */ - -/** - * Remove the gray background on active links in IE 10. - */ - -a { - background-color: transparent; -} - -/** - * 1. Remove the bottom border in Chrome 57- - * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. - */ - -abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ -} - -/** - * Add the correct font weight in Chrome, Edge, and Safari. - */ - -b, -strong { - font-weight: bolder; -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ - -code, -kbd, -samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/** - * Add the correct font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` elements from affecting the line height in - * all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* Embedded content - ========================================================================== */ - -/** - * Remove the border on images inside links in IE 10. - */ - -img { - border-style: none; -} - -/* Forms - ========================================================================== */ - -/** - * 1. Change the font styles in all browsers. - * 2. Remove the margin in Firefox and Safari. - */ - -button, -input, -optgroup, -select, -textarea { - font-family: monospace, monospace; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ -} - -/** - * Show the overflow in IE. - * 1. Show the overflow in Edge. - */ - -button, -input { /* 1 */ - overflow: visible; -} - -/** - * Remove the inheritance of text transform in Edge, Firefox, and IE. - * 1. Remove the inheritance of text transform in Firefox. - */ - -button, -select { /* 1 */ - text-transform: none; -} - -/** - * Correct the inability to style clickable types in iOS and Safari. - */ - -button, -[type="button"], -[type="reset"], -[type="submit"] { - -webkit-appearance: button; -} - -/** - * Remove the inner border and padding in Firefox. - */ - -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule. - */ - -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - -/** - * Correct the padding in Firefox. - */ - -fieldset { - padding: 0.35em 0.75em 0.625em; -} - -/** - * 1. Correct the text wrapping in Edge and IE. - * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. - */ - -legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ -} - -/** - * Add the correct vertical alignment in Chrome, Firefox, and Opera. - */ - -progress { - vertical-align: baseline; -} - -/** - * Remove the default vertical scrollbar in IE 10+. - */ - -textarea { - overflow: auto; -} - -/** - * 1. Add the correct box sizing in IE 10. - * 2. Remove the padding in IE 10. - */ - -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Correct the cursor style of increment and decrement buttons in Chrome. - */ - -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. - */ - -[type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ -} - -/** - * Remove the inner padding in Chrome and Safari on macOS. - */ - -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * 1. Correct the inability to style clickable types in iOS and Safari. - * 2. Change font properties to `inherit` in Safari. - */ - -::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ -} - -/* Interactive - ========================================================================== */ - -/* - * Add the correct display in Edge, IE 10+, and Firefox. - */ - -details { - display: block; -} - -/* - * Add the correct display in all browsers. - */ - -summary { - display: list-item; -} - -/* Misc - ========================================================================== */ - -/** - * Add the correct display in IE 10+. - */ - -template { - display: none; -} - -/** - * Add the correct display in IE 10. - */ - -[hidden] { - display: none; -} - -/*-----------own------------*/ - -#logo { - position:absolute; - left: 0; - margin:10px; - height: 100px; - width: 100px; -} - -.logo { - display: block; - margin-left: auto; - margin-right: auto; - width: 50%; -} - -#title { - color: grey; - text-align: center; - font-size: 14px; - font-weight:bold; - margin: 0; - padding-bottom: 5px; -} - -#info { - position:absolute; - right: 0; - padding:10px; - - font-size:12px; - text-align:right; -} - -#status { - position:relative; - margin:0; - font-size:14px; - font-weight: bold; - color:#aaa; - z-index: 10; -} - -#streamstatus { - position:relative; - margin: 2px 0 0 0; - color:grey; -} - -#searchWrapper { - display: none; - position:relative; - margin:10px 0 3px 0; - z-index: 10; -} - -#search { - display: inline-block; - background: transparent; - border: 0; - margin: 0; - padding: 0; - width: 200px; - - color: grey; - text-align: right; -} - -#search:focus { - outline: none; - color: #aaa; -} - -#clear { - display: inline-block; - background: transparent; - border: 0; - margin: 0; - padding: 0; - cursor: pointer; - - color: grey; -} - -#clear:focus { - outline: none; -} - -#clear:hover { - color: #aaa; - text-decoration: line-through; -} - - -#nodesOnlineWrapper{ - position: relative; - height: 80px; - overflow-y: scroll; - margin:0; - padding: 5px 0; - - color: grey; - z-index: 10; -} - -#nodesOnline { - display: inline-block; - /* background: black; */ -} - -#nodesOnline span { - display: block; - padding: 5px 5px; - border-bottom: 1px dashed #7c7c7c; - cursor: pointer; -} - -#nodesOnline span.active { - color: #336db5; -} - -#nodesOnline span:first-child { - border-top: 1px dashed #7c7c7c; -} - -#nodeId { - margin:0; - padding:5px 0; - font-weight: bold; - text-decoration: underline; - color:#aaa; -} - -#nodestats { - position:relative; - margin: 7px 0 0 0; - color:grey; -} - -#in, #out { - margin:0; - padding: 3px 0; -} - -#graphc { - position: absolute; - width: 100%; - height: 100%; - margin:0; - z-index: 1; -} \ No newline at end of file diff --git a/plugins/analysis/webinterface/httpserver/static/img/gos.png b/plugins/analysis/webinterface/httpserver/static/img/gos.png deleted file mode 100644 index e47b66f9e93837d8e58bb764015047a14bdf8451..0000000000000000000000000000000000000000 Binary files a/plugins/analysis/webinterface/httpserver/static/img/gos.png and /dev/null differ diff --git a/plugins/analysis/webinterface/httpserver/static/index.html b/plugins/analysis/webinterface/httpserver/static/index.html deleted file mode 100644 index 211feba0c7f4799871401ab96dfc4cf51b9583e4..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/static/index.html +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8" /> - <title>GoShimmer - Network Visualizer</title> - <link rel="stylesheet" type="text/css" href="/static/css/normalize.css"> - <script type="text/javascript" src="/static/js/vivagraph-0.12.0.min.js"></script> - <script type="text/javascript" src="/static/js/main.js"></script> -</head> - -<body style="background: #202126;"> - <div id="logo"> - <p id="title">GOSHIMMER<br>NETWORK</p> - <img class="logo" src="/static/img/gos.png" alt="GoShimmer"> - </div> - - <div id="graphc"></div> - - <div id="info"> - <p id="status"></p> - <p id="streamstatus"></p> - - <div id="searchWrapper"> - <input id="search" type="text" placeholder="search for node..." autocomplete="off"> - <input type="button" id="clear" value="clear"> - </div> - <div id="nodesOnlineWrapper"><div id="nodesOnline"></div></div> - - <div id="nodestats"> - <p id="nodeId"></p> - <p id="in"></p> - <p id="out"></p> - </div> - </div> -</body> - -</html> \ No newline at end of file diff --git a/plugins/analysis/webinterface/httpserver/static/js/main.js b/plugins/analysis/webinterface/httpserver/static/js/main.js deleted file mode 100644 index 8ede0c5a13038ee5b9ceade73e9c47e9e01be8d4..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/static/js/main.js +++ /dev/null @@ -1,819 +0,0 @@ -const ANALYSIS_SERVER_URL = "116.202.49.178" + "/datastream"; -const NODE_ID_LENGTH = 64; - -// for some strange reason color formats for edges and nodes need to be different... careful! -const EDGE_COLOR_DEFAULT = "#444444"; -const EDGE_COLOR_OUTGOING = "#336db5"; -const EDGE_COLOR_INCOMING = "#1c8d7f"; -const VERTEX_COLOR_DEFAULT = "0x666666"; -const VERTEX_COLOR_ACTIVE = "0x336db5"; -const VERTEX_COLOR_CONNECTED = "0x1c8d7f"; -const VERTEX_SIZE = 14; - -class Frontend { - constructor(app) { - this.app = app; - this.activeNode = ''; - this.searchTerm = ''; - document.addEventListener('click', (e) => { - if (hasClass(e.target, 'n')) { - let htmlNode = e.target; - let nodeId = htmlNode.innerHTML; - - if(hasClass(htmlNode, 'active')) { - this.app.resetActiveNode(); - return; - } - - // TODO: add active class and remove possible others (necessary for search feature) - - this.app.setActiveNode(nodeId, true); - } - }, false); - - this.initSearch(); - } - - initSearch() { - document.getElementById("search").addEventListener('keyup', (e) => { - let value = e.target.value.trim().toLowerCase(); - - if(value === "") { - this.resetSearch(); - return; - } - - this.searchTerm = value; - - let results = new Set(); - for(let n of this.app.ds.nodesOnline) { - if(n.startsWith(value)) { - results.add(n); - } - } - - if(results.size == 1) { - // little hack to access element - let n = results.values().next().value; - this.app.setActiveNode(n, true); - } - - this.displayNodesOnline(results); - }); - - document.getElementById("clear").addEventListener("click", (e) => { - this.resetSearch(); - }); - } - - resetSearch() { - document.getElementById("search").value = ""; - this.searchTerm = ''; - this.app.resetActiveNode(); - } - - showSearchField() { - document.getElementById('searchWrapper').style.cssText = "display:block;" - } - - setStatusMessage(msg) { - document.getElementById("status").innerHTML = msg; - } - - setStreamStatusMessage(msg) { - document.getElementById("streamstatus").innerHTML = msg; - } - - showNodeLinks(node, neighbors) { - document.getElementById("nodeId").innerHTML = node + " in:" + neighbors.in.size + " out:" + neighbors.out.size; - - let html = "incoming edges: "; - // incoming - for(let n of neighbors.in) { - html += n + " → " + "NODE<br>"; - } - if(neighbors.in.size == 0) { html += "no incoming edges!" } - document.getElementById("in").innerHTML = html; - - html = "outgoing edges: "; - // outgoing - for(let n of neighbors.out) { - html += "NODE" + " → " + n + "<br>"; - } - if(neighbors.out.size == 0) { html += "no outgoing edges!" } - document.getElementById("out").innerHTML = html; - } - - setActiveNode(nodeId, updateHash=false) { - this.activeNode = nodeId; - if(updateHash) { - history.replaceState(null, null, '#'+nodeId); - } - - let neighbors = this.app.ds.neighbors[nodeId]; - this.showNodeLinks(nodeId, neighbors); - } - - resetActiveNode() { - // currently active node will lose class at next refresh - this.activeNode = ''; - history.replaceState(null, null, ' '); // reset location hash - this.resetNodeLinks(); - } - - resetNodeLinks() { - document.getElementById("nodeId").innerHTML = ""; - document.getElementById("in").innerHTML = ""; - document.getElementById("out").innerHTML = ""; - } - - displayNodesOnline(nodesOnline) { - // this line might be a performance killer! - nodesOnline = Array.from(nodesOnline).sort(); - - let html = []; - for(let n of nodesOnline) { - if(n == this.activeNode) { - html.push('<span class="n active">' + n + "</span>"); - } else { - html.push('<span class="n">' + n + "</span>"); - } - } - document.getElementById("nodesOnline").innerHTML = html.join(""); - } -} - -class Datastructure { - constructor(app) { - this.app = app; - this.nodes = new Set(); - this.nodesOnline = new Set(); - this.nodesOffline = new Set(); - this.nodesDisconnected = new Set(); - this.connections = new Set(); - this.neighbors = new Map(); - } - - getStatusText() { - // avg = this.connections.size*2 / (this.nodesOnline-1) : -1 == entry node (always disconnected) - return "nodes online: " + this.nodesOnline.size + "(" + this.nodesDisconnected.size + ")" + " - IDs: " + this.nodes.size + " - edges: " + this.connections.size + " - avg: " + (this.connections.size*2 / (this.nodesOnline.size-1)).toFixed(2); - } - - addNode(idA) { - if(!this.nodes.has(idA)) { - this.nodes.add(idA); - - this.app.setStreamStatusMessage("addedToNodepool: " + idA); - this.app.updateStatus(); - } - - // TODO: temporary fix for faulty analysis server. do not set nodes offline. - this.setNodeOnline(idA); - } - - removeNode(idA) { - if(!this.nodes.has(idA)) { - console.error("removeNode but not in nodes list:", idA); - return; - } - - if(this.nodesDisconnected.has(idA)) { this.nodesDisconnected.delete(idA); } - if(this.neighbors.has(idA)) { this.neighbors.delete(idA); } - - if(this.nodesOnline.has(idA)) { - this.nodesOnline.delete(idA); - this.app.graph.deleteVertex(idA); - - this.app.setStreamStatusMessage("removeNode from onlinepool: " + idA); - } - - if(this.nodesOffline.has(idA)) { - this.nodesOffline.delete(idA); - this.app.setStreamStatusMessage("removeNode from offlinepool: " + idA); - } - - if(this.nodes.has(idA)) { - this.nodes.delete(idA); - this.app.setStreamStatusMessage("removeNode from nodepool: " + idA); - } - - this.app.updateStatus(); - } - - setNodeOnline(idA) { - if(!this.nodes.has(idA)) { - console.error("setNodeOnline but not in nodes list:", idA); - return; - } - - // check if not in nodesOnline set - if(!this.nodesOnline.has(idA)) { - this.nodesOnline.add(idA); - this.app.graph.addVertex(idA); - - // create entry in neighbors map - this.neighbors[idA] = this.createNeighborsObject(); - this.nodesDisconnected.add(idA); - - this.app.setStreamStatusMessage("setNodeOnline: " + idA) - } else { - this.app.setStreamStatusMessage("setNodeOnline skipped: " + idA) - } - - // check if in nodesOffline set - if(this.nodesOffline.has(idA)) { - this.nodesOffline.delete(idA); - - this.app.setStreamStatusMessage("removedFromOfflinepool: " + idA) - } - - this.app.updateStatus(); - } - - createNeighborsObject() { - return { - in: new Set(), - out: new Set(), - } - } - - setNodeOffline(idA) { - // TODO: temporary fix for faulty analysis server. do not set nodes offline. - return; - - if(!this.nodes.has(idA)) { - console.error("setNodeOffline but not in nodes list:", idA); - return; - } - - if(this.nodesDisconnected.has(idA)) { this.nodesDisconnected.delete(idA); } - if(this.neighbors.has(idA)) { this.neighbors.delete(idA); } - - if(!this.nodesOffline.has(idA)) { - this.nodesOffline.add(idA); - - this.app.setStreamStatusMessage("addedToOfflinepool: " + idA) - } - - // check if node is currently online - if(this.nodesOnline.has(idA)) { - this.nodesOnline.delete(idA); - this.app.graph.deleteVertex(idA); - - this.app.setStreamStatusMessage("removedFromOnlinepool: " + idA) - } - - this.app.updateStatus(); - } - - connectNodes(con, idA, idB) { - if(!this.nodes.has(idA)) { - console.error("connectNodes but not in nodes list:", idA, con); - return; - } - if(!this.nodes.has(idB)) { - console.error("connectNodes but not in nodes list:", idB, con); - return; - } - - if(this.connections.has(con)) { - this.app.setStreamStatusMessage("connectNodes skipped: " + idA + " > " + idB); - } else { - // add new connection only if both nodes are online - if(this.nodesOnline.has(idA) && this.nodesOnline.has(idB) && idA != idB) { - this.app.graph.addEdge(con, idA, idB); - this.connections.add(con); - - // update datastructure for fast neighbor lookup - this.neighbors[idA].out.add(idB); - this.neighbors[idB].in.add(idA); - - // remove from disconnected list - if(this.nodesDisconnected.has(idA)) { this.nodesDisconnected.delete(idA); } - if(this.nodesDisconnected.has(idB)) { this.nodesDisconnected.delete(idB); } - - this.app.setStreamStatusMessage("connectNodes: " + idA + " > " + idB); - this.app.updateStatus(); - } else { - console.log("connectNodes skipped: either node not online", idA, idB); - } - } - } - - disconnectNodes(con, idA, idB) { - if(!this.nodes.has(idA)) { - console.error("disconnectNodes but not in nodes list:", idA, con); - return; - } - if(!this.nodes.has(idB)) { - console.error("disconnectNodes but not in nodes list:", idB, con); - return; - } - - if(this.connections.has(con)) { - this.connections.delete(con); - this.app.graph.deleteEdge(con, idA, idB); - - // update datastructure for fast neighbor lookup - this.neighbors[idA].out.delete(idB); - this.neighbors[idB].in.delete(idA); - - // check if nodes still have neighbors - if(!this.hasNodeNeighbors(idA)) { this.nodesDisconnected.add(idA); } - if(!this.hasNodeNeighbors(idB)) { this.nodesDisconnected.add(idB); } - - this.app.setStreamStatusMessage("disconnectNodes: " + idA + " > " + idB); - this.app.updateStatus(); - } else { - console.log("disconnectNodes skipped: either node not online", idA, idB); - } - } - - hasNodeNeighbors(idA) { - let neighbors = this.neighbors[idA]; - return ((neighbors.in.size + neighbors.out.size) > 0) - } -} - -class Graph { - constructor(app) { - this.app = app; - this.highlightedNodes = new Set(); - this.highlightedLinks = new Set(); - - this.graph = Viva.Graph.graph(); - this.graphics = Viva.Graph.View.webglGraphics(); - this.calculator = Viva.Graph.centrality(); - - this.layout = Viva.Graph.Layout.forceDirected(this.graph, { - springLength: 30, - springCoeff: 0.0001, - dragCoeff: 0.02, - gravity: -1.2 - }); - - this.graphics.link((link) => { - return Viva.Graph.View.webglLine(EDGE_COLOR_DEFAULT); - }); - - this.graphics.setNodeProgram(buildCircleNodeShader()); - - this.graphics.node((node) => { - return new WebGLCircle(VERTEX_SIZE, VERTEX_COLOR_DEFAULT); - }); - - this.renderer = Viva.Graph.View.renderer(this.graph, { - layout: this.layout, - graphics: this.graphics, - container: document.getElementById('graphc'), - renderLinks: true - }); - - this.initEvents(); - } - - updateNodeUiColor(node, color, save=true) { - let nodeUI = this.graphics.getNodeUI(node); - if (nodeUI != undefined) { - nodeUI.color = color; - } - - if(save) { - this.highlightedNodes.add(node); - } - } - - updateLinkUiColor(idA, idB, color, save=true) { - let con = this.graph.getLink(idA, idB); - - if(con != null) { - let linkUI = this.graphics.getLinkUI(con.id); - if (linkUI != undefined) { - linkUI.color = parseColor(color); - } - - if(save) { - this.highlightedLinks.add(con.id); - } - } - } - - updateLinkUiColorByLinkId(link, color, save=true) { - let linkUI = this.graphics.getLinkUI(link); - if (linkUI != undefined) { - linkUI.color = parseColor(color); - } - - if(save) { - this.highlightedLinks.add(link); - } - } - - showNodeLinks(selectedNode) { - if(this.highlightedLinks > 0 || this.highlightedNodes.size > 0) { - // clean up display - this.app.resetActiveNode(); - } - - this.graph.beginUpdate(); - - let neighbors = this.app.ds.neighbors[selectedNode]; - - // highlight current node - this.updateNodeUiColor(selectedNode, VERTEX_COLOR_ACTIVE); - - // highlight incoming connections - for(let n of neighbors.in) { - this.updateNodeUiColor(n, VERTEX_COLOR_CONNECTED); - this.updateLinkUiColor(n, selectedNode, EDGE_COLOR_INCOMING); - } - - // highlight outcoming connections - for(let n of neighbors.out) { - this.updateNodeUiColor(n, VERTEX_COLOR_CONNECTED); - this.updateLinkUiColor(selectedNode, n, EDGE_COLOR_OUTGOING); - } - - this.graph.endUpdate(); - this.renderer.rerender(); - } - - initEvents() { - this.events = Viva.Graph.webglInputEvents(this.graphics, this.graph); - - this.events.mouseEnter((node) => { - this.app.setActiveNode(node.id) - }); - - this.events.mouseLeave(() => { - if(this.highlightedLinks > 0 || this.highlightedNodes.size > 0) { - // clean up display - this.app.resetActiveNode(); - } - }); - } - - resetPreviousColors() { - this.graph.beginUpdate(); - - for(let n of this.highlightedNodes) { - this.updateNodeUiColor(n, VERTEX_COLOR_DEFAULT, false); - } - - for(let l of this.highlightedLinks) { - this.updateLinkUiColorByLinkId(l, EDGE_COLOR_DEFAULT, false); - } - - this.graph.endUpdate(); - this.renderer.rerender(); - } - - addEdge(con, idA, idB) { - this.graph.addLink(idA, idB, con); - } - - deleteEdge(con, idA, idB) { - let link = this.graph.getLink(idA, idB); - this.graph.removeLink(link); - } - - addVertex(idA) { - this.graph.addNode(idA); - } - - deleteVertex(idA) { - this.graph.removeNode(idA); - } - - render() { - this.renderer.run(); - } -} - -class Application { - constructor(url) { - this.url = url; - this.frontend = new Frontend(this); - this.ds = new Datastructure(this); - this.graph = new Graph(this); - - this.rendered = false; // is the application already rendered? - this.floodNew = 0; - this.floodOld = 0; - - } - - setActiveNode(nodeId, updateHash=false) { - this.graph.showNodeLinks(nodeId); - this.frontend.setActiveNode(nodeId, updateHash); - } - - resetActiveNode() { - this.graph.resetPreviousColors() - this.frontend.resetActiveNode(); - } - - setStatusMessage(msg) { - if(this.rendered) { - this.frontend.setStatusMessage(msg); - console.log('%cStatusMessage: ' + msg, 'color: gray'); - } - } - - setStreamStatusMessage(msg) { - if(this.rendered) { - this.frontend.setStreamStatusMessage(msg); - console.log('%cStreamStatusMessage: ' + msg, 'color: gray'); - } - } - - updateStatus() { - this.setStatusMessage(this.ds.getStatusText()); - } - - showOnlineNodes() { - setInterval(() => { - if(this.frontend.searchTerm.length > 0) { - return; - } - this.frontend.displayNodesOnline(this.ds.nodesOnline) - }, 300); - } - - run() { - let initialFloodTimerFunc = () => { - if (this.floodNew > this.floodOld + 100) { - this.setStreamStatusMessage("... received " + this.floodNew + " msg"); - this.floodOld = this.floodNew; - } else { - clearInterval(this.initialFloodTimer); - this.startRendering(); - } - } - - this.initialFloodTimer = setInterval(initialFloodTimerFunc, 500); - this.initWebsocket(); - } - - startRendering() { - // kickoff rendering - this.rendered = true; - - this.graph.render(); - - this.setStreamStatusMessage("... received " + this.floodNew + " msg"); - this.updateStatus(); - - // display nodes online and search field - this.frontend.showSearchField(); - this.showOnlineNodes(); - - // highlight node passed in url - let nodeId = window.location.hash.substring(1); - if(nodeId) { - this.setActiveNode(nodeId); - } - } - - initWebsocket() { - this.socket = new WebSocket( - ((window.location.protocol === "https:") ? "wss://" : "ws://") + this.url - ); - - this.socket.onopen = () => { - this.setStatusMessage("WebSocket opened. Loading ... "); - setInterval(() => { - this.socket.send("_"); - }, 1000); - }; - - this.socket.onerror = (e) => { - this.setStatusMessage("WebSocket error observed. Please reload."); - console.error("WebSocket error observed", e); - }; - - this.socket.onmessage = (e) => { - let type = e.data[0]; - let data = e.data.substr(1); - let idA = data.substr(0, NODE_ID_LENGTH); - let idB; - - if(!this.rendered) { this.floodNew++; } - - switch (type) { - case "_": - //do nothing - its just a ping - break; - - case "A": - console.log("addNode event:", idA); - // filter out empty ids - if(idA.length == NODE_ID_LENGTH) { - this.ds.addNode(idA); - } - break; - - case "a": - console.log("removeNode event:", idA); - this.ds.removeNode(idA); - break; - - case "C": - idB = data.substr(NODE_ID_LENGTH, NODE_ID_LENGTH); - console.log("connectNodes event:", idA, " - ", idB); - this.ds.connectNodes(idA+idB, idA, idB); - break; - - case "c": - idB = data.substr(NODE_ID_LENGTH, NODE_ID_LENGTH); - console.log("disconnectNodes event:", idA, " - ", idB); - this.ds.disconnectNodes(idA+idB, idA, idB); - break; - - case "O": - console.log("setNodeOnline event:", idA); - this.ds.setNodeOnline(idA); - break; - - case "o": - console.log("setNodeOffline event:", idA); - this.ds.setNodeOffline(idA); - break; - } - } - } -} - - -let app; -window.onload = () => { - app = new Application(ANALYSIS_SERVER_URL); - app.run() -} - - - - -function hasClass(elem, className) { - return elem.classList.contains(className); -} - -function parseColor(color) { - var parsedColor = 0x009ee8ff; - - if (typeof color === 'string' && color) { - if (color.length === 4) { // #rgb - color = color.replace(/([^#])/g, '$1$1'); // duplicate each letter except first #. - } - if (color.length === 9) { // #rrggbbaa - parsedColor = parseInt(color.substr(1), 16); - } else if (color.length === 7) { // or #rrggbb. - parsedColor = (parseInt(color.substr(1), 16) << 8) | 0xff; - } else { - throw 'Color expected in hex format with preceding "#". E.g. #00ff00. Got value: ' + color; - } - } else if (typeof color === 'number') { - parsedColor = color; - } - - return parsedColor; -} - - -/** - * WebGL stuff - */ - -function WebGLCircle(size, color) { - this.size = size; - this.color = color; -} -// Next comes the hard part - implementation of API for custom shader -// program, used by webgl renderer: -function buildCircleNodeShader() { - // For each primitive we need 4 attributes: x, y, color and size. - var ATTRIBUTES_PER_PRIMITIVE = 4, - nodesFS = [ - 'precision mediump float;', - 'varying vec4 color;', - 'void main(void) {', - ' if ((gl_PointCoord.x - 0.5) * (gl_PointCoord.x - 0.5) + (gl_PointCoord.y - 0.5) * (gl_PointCoord.y - 0.5) < 0.25) {', - ' gl_FragColor = color;', - ' } else {', - ' gl_FragColor = vec4(0);', - ' }', - '}'].join('\n'), - nodesVS = [ - 'attribute vec2 a_vertexPos;', - // Pack color and size into vector. First elemnt is color, second - size. - // Since it's floating point we can only use 24 bit to pack colors... - // thus alpha channel is dropped, and is always assumed to be 1. - 'attribute vec2 a_customAttributes;', - 'uniform vec2 u_screenSize;', - 'uniform mat4 u_transform;', - 'varying vec4 color;', - 'void main(void) {', - ' gl_Position = u_transform * vec4(a_vertexPos/u_screenSize, 0, 1);', - ' gl_PointSize = a_customAttributes[1] * u_transform[0][0];', - ' float c = a_customAttributes[0];', - ' color.b = mod(c, 256.0); c = floor(c/256.0);', - ' color.g = mod(c, 256.0); c = floor(c/256.0);', - ' color.r = mod(c, 256.0); c = floor(c/256.0); color /= 255.0;', - ' color.a = 1.0;', - '}'].join('\n'); - var program, - gl, - buffer, - locations, - utils, - nodes = new Float32Array(64), - nodesCount = 0, - canvasWidth, canvasHeight, transform, - isCanvasDirty; - return { - /** - * Called by webgl renderer to load the shader into gl context. - */ - load: function (glContext) { - gl = glContext; - webglUtils = Viva.Graph.webgl(glContext); - program = webglUtils.createProgram(nodesVS, nodesFS); - gl.useProgram(program); - locations = webglUtils.getLocations(program, ['a_vertexPos', 'a_customAttributes', 'u_screenSize', 'u_transform']); - gl.enableVertexAttribArray(locations.vertexPos); - gl.enableVertexAttribArray(locations.customAttributes); - buffer = gl.createBuffer(); - }, - /** - * Called by webgl renderer to update node position in the buffer array - * - * @param nodeUI - data model for the rendered node (WebGLCircle in this case) - * @param pos - {x, y} coordinates of the node. - */ - position: function (nodeUI, pos) { - var idx = nodeUI.id; - nodes[idx * ATTRIBUTES_PER_PRIMITIVE] = pos.x; - nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 1] = -pos.y; - nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 2] = nodeUI.color; - nodes[idx * ATTRIBUTES_PER_PRIMITIVE + 3] = nodeUI.size; - }, - /** - * Request from webgl renderer to actually draw our stuff into the - * gl context. This is the core of our shader. - */ - render: function () { - gl.useProgram(program); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.bufferData(gl.ARRAY_BUFFER, nodes, gl.DYNAMIC_DRAW); - if (isCanvasDirty) { - isCanvasDirty = false; - gl.uniformMatrix4fv(locations.transform, false, transform); - gl.uniform2f(locations.screenSize, canvasWidth, canvasHeight); - } - gl.vertexAttribPointer(locations.vertexPos, 2, gl.FLOAT, false, ATTRIBUTES_PER_PRIMITIVE * Float32Array.BYTES_PER_ELEMENT, 0); - gl.vertexAttribPointer(locations.customAttributes, 2, gl.FLOAT, false, ATTRIBUTES_PER_PRIMITIVE * Float32Array.BYTES_PER_ELEMENT, 2 * 4); - gl.drawArrays(gl.POINTS, 0, nodesCount); - }, - /** - * Called by webgl renderer when user scales/pans the canvas with nodes. - */ - updateTransform: function (newTransform) { - transform = newTransform; - isCanvasDirty = true; - }, - /** - * Called by webgl renderer when user resizes the canvas with nodes. - */ - updateSize: function (newCanvasWidth, newCanvasHeight) { - canvasWidth = newCanvasWidth; - canvasHeight = newCanvasHeight; - isCanvasDirty = true; - }, - /** - * Called by webgl renderer to notify us that the new node was created in the graph - */ - createNode: function (node) { - nodes = webglUtils.extendArray(nodes, nodesCount, ATTRIBUTES_PER_PRIMITIVE); - nodesCount += 1; - }, - /** - * Called by webgl renderer to notify us that the node was removed from the graph - */ - removeNode: function (node) { - if (nodesCount > 0) { nodesCount -= 1; } - if (node.id < nodesCount && nodesCount > 0) { - // we do not really delete anything from the buffer. - // Instead we swap deleted node with the "last" node in the - // buffer and decrease marker of the "last" node. Gives nice O(1) - // performance, but make code slightly harder than it could be: - webglUtils.copyArrayPart(nodes, node.id * ATTRIBUTES_PER_PRIMITIVE, nodesCount * ATTRIBUTES_PER_PRIMITIVE, ATTRIBUTES_PER_PRIMITIVE); - } - }, - /** - * This method is called by webgl renderer when it changes parts of its - * buffers. We don't use it here, but it's needed by API (see the comment - * in the removeNode() method) - */ - replaceProperties: function (replacedNode, newNode) { }, - }; -} diff --git a/plugins/analysis/webinterface/httpserver/static/js/vivagraph-0.12.0.min.js b/plugins/analysis/webinterface/httpserver/static/js/vivagraph-0.12.0.min.js deleted file mode 100644 index 6872dddec6b8486d728ef75708eb2d6b768d2abf..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/static/js/vivagraph-0.12.0.min.js +++ /dev/null @@ -1,3 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.Viva=e()}}(function(){return function e(n,t,r){function o(a,u){if(!t[a]){if(!n[a]){var s="function"==typeof require&&require;if(!u&&s)return s(a,!0);if(i)return i(a,!0);var f=new Error("Cannot find module '"+a+"'");throw f.code="MODULE_NOT_FOUND",f}var c=t[a]={exports:{}};n[a][0].call(c.exports,function(e){var t=n[a][1][e];return o(t?t:e)},c,c.exports,e,n,t,r)}return t[a].exports}for(var i="function"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(e,n,t){var r=e("ngraph.random"),o={lazyExtend:function(){return e("ngraph.merge").apply(this,arguments)},randomIterator:function(){return r.randomIterator.apply(r,arguments)},random:function(){return r.random.apply(r,arguments)},events:e("ngraph.events")};o.Graph={version:e("./version.js"),graph:e("ngraph.graph"),serializer:function(){return{loadFromJSON:e("ngraph.fromjson"),storeToJSON:e("ngraph.tojson")}},centrality:e("./Algorithms/centrality.js"),operations:e("./Algorithms/operations.js"),geom:function(){return{intersect:e("gintersect"),intersectRect:e("./Utils/intersectRect.js")}},webgl:e("./WebGL/webgl.js"),webglInputEvents:e("./WebGL/webglInputEvents.js"),generator:function(){return e("ngraph.generators")},Input:{domInputManager:e("./Input/domInputManager.js"),webglInputManager:e("./Input/webglInputManager.js")},Utils:{dragndrop:e("./Input/dragndrop.js"),findElementPosition:e("./Utils/findElementPosition.js"),timer:e("./Utils/timer.js"),getDimension:e("./Utils/getDimensions.js"),events:e("./Utils/backwardCompatibleEvents.js")},Layout:{forceDirected:e("ngraph.forcelayout"),constant:e("./Layout/constant.js")},View:{Texture:e("./WebGL/texture.js"),webglAtlas:e("./WebGL/webglAtlas.js"),webglImageNodeProgram:e("./WebGL/webglImageNodeProgram.js"),webglLinkProgram:e("./WebGL/webglLinkProgram.js"),webglNodeProgram:e("./WebGL/webglNodeProgram.js"),webglLine:e("./WebGL/webglLine.js"),webglSquare:e("./WebGL/webglSquare.js"),webglImage:e("./WebGL/webglImage.js"),webglGraphics:e("./View/webglGraphics.js"),_webglUtil:{parseColor:e("./WebGL/parseColor.js")},svgGraphics:e("./View/svgGraphics.js"),renderer:e("./View/renderer.js"),cssGraphics:function(){throw new Error("cssGraphics is deprecated. Please use older version of vivagraph (< 0.7) if you need it")},svgNodeFactory:function(){throw new Error("svgNodeFactory is deprecated. Please use older version of vivagraph (< 0.7) if you need it")},community:function(){throw new Error("community is deprecated. Please use vivagraph < 0.7 if you need it, or `https://github.com/anvaka/ngraph.slpa` module")}},Rect:e("./Utils/rect.js"),svg:e("simplesvg"),BrowserInfo:e("./Utils/browserInfo.js")},n.exports=o},{"./Algorithms/centrality.js":36,"./Algorithms/operations.js":37,"./Input/domInputManager.js":38,"./Input/dragndrop.js":39,"./Input/webglInputManager.js":40,"./Layout/constant.js":41,"./Utils/backwardCompatibleEvents.js":42,"./Utils/browserInfo.js":43,"./Utils/findElementPosition.js":45,"./Utils/getDimensions.js":46,"./Utils/intersectRect.js":47,"./Utils/rect.js":49,"./Utils/timer.js":50,"./View/renderer.js":52,"./View/svgGraphics.js":53,"./View/webglGraphics.js":54,"./WebGL/parseColor.js":55,"./WebGL/texture.js":56,"./WebGL/webgl.js":57,"./WebGL/webglAtlas.js":58,"./WebGL/webglImage.js":59,"./WebGL/webglImageNodeProgram.js":60,"./WebGL/webglInputEvents.js":61,"./WebGL/webglLine.js":62,"./WebGL/webglLinkProgram.js":63,"./WebGL/webglNodeProgram.js":64,"./WebGL/webglSquare.js":65,"./version.js":66,gintersect:3,"ngraph.events":9,"ngraph.forcelayout":11,"ngraph.fromjson":13,"ngraph.generators":14,"ngraph.graph":16,"ngraph.merge":17,"ngraph.random":30,"ngraph.tojson":31,simplesvg:32}],2:[function(e,n,t){function r(e,n,t,r){return f=f||(document.addEventListener?{add:i,rm:a}:{add:u,rm:s}),f.add(e,n,t,r)}function o(e,n,t,r){return f=f||(document.addEventListener?{add:i,rm:a}:{add:u,rm:s}),f.rm(e,n,t,r)}function i(e,n,t,r){e.addEventListener(n,t,r)}function a(e,n,t,r){e.removeEventListener(n,t,r)}function u(e,n,t,r){if(r)throw new Error("cannot useCapture in oldIE");e.attachEvent("on"+n,t)}function s(e,n,t,r){e.detachEvent("on"+n,t)}r.removeEventListener=o,r.addEventListener=r,n.exports=r;var f=null},{}],3:[function(e,n,t){function r(e,n,t,r,o,i,a,u){var s,f,c,d,l,p,v,h,g,m,y,x,w,b={x:0,y:0};return s=r-n,c=e-t,l=t*n-e*r,g=s*o+c*i+l,m=s*a+c*u+l,0!==g&&0!==m&&g>=0==m>=4?null:(f=u-i,d=o-a,p=a*i-o*u,v=f*e+d*n+p,h=f*t+d*r+p,0!==v&&0!==h&&v>=0==h>=0?null:(y=s*d-f*c,0===y?null:(x=y<0?-y/2:y/2,x=0,w=c*p-d*l,b.x=(w<0?w-x:w+x)/y,w=f*l-s*p,b.y=(w<0?w-x:w+x)/y,b)))}n.exports=r},{}],4:[function(e,n,t){n.exports.degree=e("./src/degree.js"),n.exports.betweenness=e("./src/betweenness.js"),n.exports.closeness=e("./src/closeness.js"),n.exports.eccentricity=e("./src/eccentricity.js")},{"./src/betweenness.js":5,"./src/closeness.js":6,"./src/degree.js":7,"./src/eccentricity.js":8}],5:[function(e,n,t){function r(e,n){function t(e){h[e]/=2}function r(e){h[e.id]=0}function o(e){s=e.id,u(s),i()}function i(){for(e.forEachNode(a);c.length;){for(var n=c.pop(),t=(1+v[n])/p[n],r=d[n],o=0;o<r.length;++o){var i=r[o];v[i]+=p[i]*t}n!==s&&(h[n]+=v[n])}}function a(e){v[e.id]=0}function u(t){function r(e){i(e.id)}function o(e){var n=e.id;d[n]=[],l[n]=-1,p[n]=0}function i(e){l[e]===-1&&(l[e]=l[a]+1,f.push(e)),l[e]===l[a]+1&&(p[e]+=p[a],d[e].push(a))}for(e.forEachNode(o),l[t]=0,p[t]=1,f.push(t);f.length;){var a=f.shift();c.push(a),e.forEachLinkedNode(a,r,n)}}var s,f=[],c=[],d=Object.create(null),l=Object.create(null),p=Object.create(null),v=Object.create(null),h=Object.create(null);return e.forEachNode(r),e.forEachNode(o),n||Object.keys(h).forEach(t),h}n.exports=r},{}],6:[function(e,n,t){function r(e,n){function t(e){f[e.id]=0}function r(e){a=e.id,i(a),o()}function o(){var e=Object.keys(s).map(function(e){return s[e]}).filter(function(e){return e!==-1}),n=e.length,t=e.reduce(function(e,n){return e+n});t>0?f[a]=(n-1)/t:f[a]=0}function i(t){function r(e){var n=e.id;s[n]=-1}function o(e){var n=e.id;s[n]===-1&&(s[n]=s[i]+1,u.push(n))}for(e.forEachNode(r),s[t]=0,u.push(t);u.length;){var i=u.shift();e.forEachLinkedNode(i,o,n)}}var a,u=[],s=Object.create(null),f=Object.create(null);return e.forEachNode(t),e.forEachNode(r),f}n.exports=r},{}],7:[function(e,n,t){function r(e,n){function t(n){var t=e.getLinks(n.id);u[n.id]=r(t,n.id)}var r,u=Object.create(null);if(n=(n||"both").toLowerCase(),"both"===n||"inout"===n)r=a;else if("in"===n)r=o;else{if("out"!==n)throw new Error("Expected centrality degree kind is: in, out or both");r=i}return e.forEachNode(t),u}function o(e,n){var t=0;if(!e)return t;for(var r=0;r<e.length;r+=1)t+=e[r].toId===n?1:0;return t}function i(e,n){var t=0;if(!e)return t;for(var r=0;r<e.length;r+=1)t+=e[r].fromId===n?1:0;return t}function a(e){return e?e.length:0}n.exports=r},{}],8:[function(e,n,t){function r(e,n){function t(e){f[e.id]=0}function r(e){a=e.id,i(a),o()}function o(){var e=0;Object.keys(s).forEach(function(n){var t=s[n];e<t&&(e=t)}),f[a]=e}function i(t){function r(e){var n=e.id;s[n]=-1}function o(e){var n=e.id;s[n]===-1&&(s[n]=s[i]+1,u.push(n))}for(e.forEachNode(r),s[t]=0,u.push(t);u.length;){var i=u.shift();e.forEachLinkedNode(i,o,n)}}var a,u=[],s=Object.create(null),f=Object.create(null);return e.forEachNode(t),e.forEachNode(r),f}n.exports=r},{}],9:[function(e,n,t){function r(e){var n=Object.create(null);return{on:function(t,r,o){if("function"!=typeof r)throw new Error("callback is expected to be a function");var i=n[t];return i||(i=n[t]=[]),i.push({callback:r,ctx:o}),e},off:function(t,r){var o="undefined"==typeof t;if(o)return n=Object.create(null),e;if(n[t]){var i="function"!=typeof r;if(i)delete n[t];else for(var a=n[t],u=0;u<a.length;++u)a[u].callback===r&&a.splice(u,1)}return e},fire:function(t){var r=n[t];if(!r)return e;var o;arguments.length>1&&(o=Array.prototype.splice.call(arguments,1));for(var i=0;i<r.length;++i){var a=r[i];a.callback.apply(a.ctx,o)}return e}}}function o(e){if(!e)throw new Error("Eventify cannot use falsy object as events subject");for(var n=["on","fire","off"],t=0;t<n.length;++t)if(e.hasOwnProperty(n[t]))throw new Error("Subject cannot be eventified, since it already has property '"+n[t]+"'")}n.exports=function(e){o(e);var n=r(e);return e.on=n.on,e.off=n.off,e.fire=n.fire,e}},{}],10:[function(e,n,t){function r(e,n,t){var r="[object Array]"===Object.prototype.toString.call(t);if(r)for(var i=0;i<t.length;++i)o(e,n,t[i]);else for(var a in e)o(e,n,a)}function o(e,n,t){if(e.hasOwnProperty(t)){if("function"==typeof n[t])return;n[t]=function(r){return void 0!==r?(e[t]=r,n):e[t]}}}n.exports=r},{}],11:[function(e,n,t){function r(n,t){function r(e){Object.keys(N).forEach(function(n){e(N[n],n)})}function a(e,t){var r;if(void 0===t)r="object"!=typeof e?e:e.id;else{var o=n.hasLink(e,t);if(!o)return;r=o.id}return k[r]}function u(e){return N[e]}function s(){n.on("changed",c)}function f(e){_.fire("stable",e)}function c(e){for(var t=0;t<e.length;++t){var r=e[t];"add"===r.changeType?(r.node&&l(r.node.id),r.link&&v(r.link)):"remove"===r.changeType&&(r.node&&p(r.node),r.link&&h(r.link))}P=n.getNodesCount()}function d(){P=0,n.forEachNode(function(e){l(e.id),P+=1}),n.forEachLink(v)}function l(e){var t=N[e];if(!t){var r=n.getNode(e);if(!r)throw new Error("initBody() was called with unknown node id");var o=r.position;if(!o){var i=g(r);o=E.getBestNewBodyPosition(i)}t=E.addBodyAt(o),t.id=e,N[e]=t,m(e),y(r)&&(t.isPinned=!0)}}function p(e){var n=e.id,t=N[n];t&&(N[n]=null,delete N[n],E.removeBody(t))}function v(e){m(e.fromId),m(e.toId);var n=N[e.fromId],t=N[e.toId],r=E.addSpring(n,t,e.length);j(e,r),k[e.id]=r}function h(e){var t=k[e.id];if(t){var r=n.getNode(e.fromId),o=n.getNode(e.toId);r&&m(r.id),o&&m(o.id),delete k[e.id],E.removeSpring(t)}}function g(e){var n=[];if(!e.links)return n;for(var t=Math.min(e.links.length,2),r=0;r<t;++r){var o=e.links[r],i=o.fromId!==e.id?N[o.fromId]:N[o.toId];i&&i.pos&&n.push(i)}return n}function m(e){var n=N[e];if(n.mass=L(e),Number.isNaN(n.mass))throw new Error("Node mass should be a number")}function y(e){return e&&(e.isPinned||e.data&&e.data.isPinned)}function x(e){var n=N[e];return n||(l(e),n=N[e]),n}function w(e){var t=n.getLinks(e);return t?1+t.length/3:1}if(!n)throw new Error("Graph structure cannot be undefined");var b=e("ngraph.physics.simulator"),E=b(t),L=w;t&&"function"==typeof t.nodeMass&&(L=t.nodeMass);var N=Object.create(null),k={},P=0,j=E.settings.springTransform||o;d(),s();var A=!1,_={step:function(){if(0===P)return!0;var e=E.step();_.lastMove=e,_.fire("step");var n=e/P,t=n<=.01;return A!==t&&(A=t,f(t)),t},getNodePosition:function(e){return x(e).pos},setNodePosition:function(e){var n=x(e);n.setPosition.apply(n,Array.prototype.slice.call(arguments,1)),E.invalidateBBox()},getLinkPosition:function(e){var n=k[e];if(n)return{from:n.from.pos,to:n.to.pos}},getGraphRect:function(){return E.getBBox()},forEachBody:r,pinNode:function(e,n){var t=x(e.id);t.isPinned=!!n},isNodePinned:function(e){return x(e.id).isPinned},dispose:function(){n.off("changed",c),_.fire("disposed")},getBody:u,getSpring:a,simulator:E,graph:n,lastMove:0};return i(_),_}function o(){}n.exports=r,n.exports.simulator=e("ngraph.physics.simulator");var i=e("ngraph.events")},{"ngraph.events":12,"ngraph.physics.simulator":19}],12:[function(e,n,t){arguments[4][9][0].apply(t,arguments)},{dup:9}],13:[function(e,n,t){function r(e,n,t){var r;n=n||o,t=t||o,r="string"==typeof e?JSON.parse(e):e;var a,u=i();if(void 0===r.links||void 0===r.nodes)throw new Error("Cannot load graph without links and nodes");for(a=0;a<r.nodes.length;++a){var s=n(r.nodes[a]);if(!s.hasOwnProperty("id"))throw new Error("Graph node format is invalid: Node id is missing");u.addNode(s.id,s.data)}for(a=0;a<r.links.length;++a){var f=t(r.links[a]);if(!f.hasOwnProperty("fromId")||!f.hasOwnProperty("toId"))throw new Error("Graph link format is invalid. Both fromId and toId are required");u.addLink(f.fromId,f.toId,f.data)}return u}function o(e){return e}n.exports=r;var i=e("ngraph.graph")},{"ngraph.graph":16}],14:[function(e,n,t){function r(n){function t(e){if(!e||e<0)throw new Error("Invalid number of nodes");var t,r=n();for(t=0;t<e-1;++t)r.addLink(t,t+1),r.addLink(e+t,e+t+1),r.addLink(t,e+t);return r.addLink(e-1,2*e-1),r}function r(e){if(!e||e<0)throw new Error("Invalid number of nodes");var n=t(e);return n.addLink(0,e-1),n.addLink(e,2*e-1),n}function o(e){if(!e||e<1)throw new Error("At least two nodes are expected for complete graph");var t,r,o=n();for(t=0;t<e;++t)for(r=t+1;r<e;++r)t!==r&&o.addLink(t,r);return o}function i(e,t){if(!e||!t||e<0||t<0)throw new Error("Graph dimensions are invalid. Number of nodes in each partition should be greater than 0");var r,o,i=n();for(r=0;r<e;++r)for(o=e;o<e+t;++o)i.addLink(r,o);return i}function a(e){if(!e||e<0)throw new Error("Invalid number of nodes");var t,r=n();for(r.addNode(0),t=1;t<e;++t)r.addLink(t-1,t);return r}function u(e,t){if(e<1||t<1)throw new Error("Invalid number of nodes in grid graph");var r,o,i=n();if(1===e&&1===t)return i.addNode(0),i;for(r=0;r<e;++r)for(o=0;o<t;++o){var a=r+o*e;r>0&&i.addLink(a,r-1+o*e),o>0&&i.addLink(a,r+(o-1)*e)}return i}function s(e,t,r){if(e<1||t<1||r<1)throw new Error("Invalid number of nodes in grid3 graph");var o,i,a,u=n();if(1===e&&1===t&&1===r)return u.addNode(0),u;for(a=0;a<r;++a)for(o=0;o<e;++o)for(i=0;i<t;++i){var s=a*e*t,f=o+i*e+s;o>0&&u.addLink(f,o-1+i*e+s),i>0&&u.addLink(f,o+(i-1)*e+s),a>0&&u.addLink(f,o+i*e+(a-1)*e*t)}return u}function f(e){if(e<0)throw new Error("Invalid number of nodes in balanced tree");var t,r=n(),o=Math.pow(2,e);for(0===e&&r.addNode(1),t=1;t<o;++t){var i=t,a=2*i,u=2*i+1;r.addLink(i,a),r.addLink(i,u)}return r}function c(e){if(e<0)throw new Error("Number of nodes should be >= 0");var t,r=n();for(t=0;t<e;++t)r.addNode(t);return r}function d(e,t){function r(e,n){for(var t=0;t<e;++t)o.addNode(t+n);for(var t=0;t<e;++t)for(var r=t+1;r<e;++r)o.addLink(t+n,r+n)}if(e<1)throw new Error("Invalid number of cliqueCount in cliqueCircle");if(t<1)throw new Error("Invalid number of cliqueSize in cliqueCircle");for(var o=n(),i=0;i<e;++i)r(t,i*t),i>0&&o.addLink(i*t,i*t-1);return o.addLink(0,o.getNodesCount()-1),o}function l(t,r,o,i){if(r>=t)throw new Error("Choose smaller `k`. It cannot be larger than number of nodes `n`");var a,u,s=e("ngraph.random").random(i||42),f=n();for(a=0;a<t;++a)f.addNode(a);for(var c=Math.floor(r/2+1),d=1;d<c;++d)for(a=0;a<t;++a)u=(d+a)%t,f.addLink(a,u);for(d=1;d<c;++d)for(a=0;a<t;++a)if(s.nextDouble()<o){var l=a;u=(d+a)%t;var p=s.next(t),v=p===l||f.hasLink(l,p);if(v&&f.getLinks(l).length===t-1)continue;for(;v;)p=s.next(t),v=p===l||f.hasLink(l,p);var h=f.hasLink(l,u);f.removeLink(h),f.addLink(l,p)}return f}return{ladder:t,complete:o,completeBipartite:i,balancedBinTree:f,path:a,circularLadder:r,grid:u,grid3:s,noLinks:c,wattsStrogatz:l,cliqueCircle:d}}var o=e("ngraph.graph");n.exports=r(o),n.exports.factory=r},{"ngraph.graph":16,"ngraph.random":15}],15:[function(e,n,t){function r(e){var n="number"==typeof e?e:+new Date;return new o(n)}function o(e){this.seed=e}function i(){var e,n,t;do n=2*this.nextDouble()-1,t=2*this.nextDouble()-1,e=n*n+t*t;while(e>=1||0===e);return n*Math.sqrt(-2*Math.log(e)/e)}function a(){var e=this.seed;return e=e+2127912214+(e<<12)&4294967295,e=4294967295&(3345072700^e^e>>>19),e=e+374761393+(e<<5)&4294967295,e=4294967295&(e+3550635116^e<<9),e=e+4251993797+(e<<3)&4294967295,e=4294967295&(3042594569^e^e>>>16),this.seed=e,(268435455&e)/268435456}function u(e){return Math.floor(this.nextDouble()*e)}function s(e,n){function t(){var n,t,r;for(n=e.length-1;n>0;--n)t=i.next(n+1),r=e[t],e[t]=e[n],e[n]=r;return e}function o(n){var t,r,o;for(t=e.length-1;t>0;--t)r=i.next(t+1),o=e[r],e[r]=e[t],e[t]=o,n(o);e.length&&n(e[0])}var i=n||r();if("function"!=typeof i.next)throw new Error("customRandom does not match expected API: next() function is missing");return{forEach:o,shuffle:t}}n.exports=r,n.exports.random=r,n.exports.randomIterator=s,o.prototype.next=u,o.prototype.nextDouble=a,o.prototype.uniform=a,o.prototype.gaussian=i},{}],16:[function(e,n,t){function r(e){function n(){function e(){return q.beginUpdate=F=k,q.endUpdate=G=P,B=t,O=r,q.on=n,n.apply(q,arguments)}var n=q.on;q.on=e}function t(e,n){R.push({link:e,changeType:n})}function r(e,n){R.push({node:e,changeType:n})}function c(e,n){if(void 0===e)throw new Error("Invalid node identifier");F();var t=d(e);return t?(t.data=n,O(t,"update")):(t=new i(e,n),S++,O(t,"add")),I[e]=t,G(),t}function d(e){return I[e]}function l(e){var n=d(e);if(!n)return!1;F();var t=n.links;if(t){n.links=null;for(var r=0;r<t.length;++r)m(t[r])}return delete I[e],S--,O(n,"remove"),G(),!0}function p(e,n,t){F();var r=d(e)||c(e),o=d(n)||c(n),i=U(e,n,t);return T.push(i),a(r,i),e!==n&&a(o,i),B(i,"add"),G(),i}function v(e,n,t){var r=s(e,n);return new u(e,n,t,r)}function h(e,n,t){var r=s(e,n),o=C.hasOwnProperty(r);if(o||y(e,n)){o||(C[r]=0);var i="@"+ ++C[r];r=s(e+i,n+i)}return new u(e,n,t,r)}function g(e){var n=d(e);return n?n.links:null}function m(e){if(!e)return!1;var n=o(e,T);if(n<0)return!1;F(),T.splice(n,1);var t=d(e.fromId),r=d(e.toId);return t&&(n=o(e,t.links),n>=0&&t.links.splice(n,1)),r&&(n=o(e,r.links),n>=0&&r.links.splice(n,1)),B(e,"remove"),G(),!0}function y(e,n){var t,r=d(e);if(!r||!r.links)return null;for(t=0;t<r.links.length;++t){var o=r.links[t];if(o.fromId===e&&o.toId===n)return o}return null}function x(){F(),M(function(e){l(e.id)}),G()}function w(e){var n,t;if("function"==typeof e)for(n=0,t=T.length;n<t;++n)e(T[n])}function b(e,n,t){var r=d(e);if(r&&r.links&&"function"==typeof n)return t?L(r.links,e,n):E(r.links,e,n)}function E(e,n,t){for(var r,o=0;o<e.length;++o){var i=e[o],a=i.fromId===n?i.toId:i.fromId;if(r=t(I[a],i))return!0}}function L(e,n,t){for(var r,o=0;o<e.length;++o){var i=e[o];if(i.fromId===n&&(r=t(I[i.toId],i)))return!0}}function N(){}function k(){D+=1}function P(){D-=1,0===D&&R.length>0&&(q.fire("changed",R),R.length=0)}function j(){return Object.keys?A:_}function A(e){if("function"==typeof e)for(var n=Object.keys(I),t=0;t<n.length;++t)if(e(I[n[t]]))return!0}function _(e){if("function"==typeof e){var n;for(n in I)if(e(I[n]))return!0}}e=e||{},"uniqueLinkId"in e&&(console.warn("ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\nUse `multigraph` option instead\n","\n","Note: there is also change in default behavior: From now own each graph\nis considered to be not a multigraph by default (each edge is unique)."),e.multigraph=e.uniqueLinkId),void 0===e.multigraph&&(e.multigraph=!1);var I="function"==typeof Object.create?Object.create(null):{},T=[],C={},S=0,D=0,M=j(),U=e.multigraph?h:v,R=[],B=N,O=N,F=N,G=N,q={addNode:c,addLink:p,removeLink:m,removeNode:l,getNode:d,getNodesCount:function(){return S},getLinksCount:function(){return T.length},getLinks:g,forEachNode:M,forEachLinkedNode:b,forEachLink:w,beginUpdate:F,endUpdate:G,clear:x,hasLink:y,hasNode:d,getLink:y};return f(q),n(),q}function o(e,n){if(!n)return-1;if(n.indexOf)return n.indexOf(e);var t,r=n.length;for(t=0;t<r;t+=1)if(n[t]===e)return t;return-1}function i(e,n){this.id=e,this.links=null,this.data=n}function a(e,n){e.links?e.links.push(n):e.links=[n]}function u(e,n,t,r){this.fromId=e,this.toId=n,this.data=t,this.id=r}function s(e,n){return e.toString()+"👉 "+n.toString()}n.exports=r;var f=e("ngraph.events")},{"ngraph.events":9}],17:[function(e,n,t){function r(e,n){var t;if(e||(e={}),n)for(t in n)if(n.hasOwnProperty(t)){var o=e.hasOwnProperty(t),i=typeof n[t],a=!o||typeof e[t]!==i;a?e[t]=n[t]:"object"===i&&(e[t]=r(e[t],n[t]))}return e}n.exports=r},{}],18:[function(e,n,t){function r(e,n){this.pos=new o(e,n),this.prevPos=new o(e,n),this.force=new o,this.velocity=new o,this.mass=1}function o(e,n){e&&"number"!=typeof e?(this.x="number"==typeof e.x?e.x:0,this.y="number"==typeof e.y?e.y:0):(this.x="number"==typeof e?e:0,this.y="number"==typeof n?n:0)}function i(e,n,t){this.pos=new a(e,n,t),this.prevPos=new a(e,n,t),this.force=new a,this.velocity=new a,this.mass=1}function a(e,n,t){e&&"number"!=typeof e?(this.x="number"==typeof e.x?e.x:0,this.y="number"==typeof e.y?e.y:0,this.z="number"==typeof e.z?e.z:0):(this.x="number"==typeof e?e:0,this.y="number"==typeof n?n:0,this.z="number"==typeof t?t:0)}n.exports={Body:r,Vector2d:o,Body3d:i,Vector3d:a},r.prototype.setPosition=function(e,n){this.prevPos.x=this.pos.x=e,this.prevPos.y=this.pos.y=n},o.prototype.reset=function(){this.x=this.y=0},i.prototype.setPosition=function(e,n,t){this.prevPos.x=this.pos.x=e,this.prevPos.y=this.pos.y=n,this.prevPos.z=this.pos.z=t},a.prototype.reset=function(){this.x=this.y=this.z=0}},{}],19:[function(e,n,t){function r(n){function t(){var e,n=p.length;if(n)for(h.insertBodies(p);n--;)e=p[n],e.isPinned||(e.force.reset(),h.updateBodyForce(e),y.update(e));for(n=v.length;n--;)m.update(v[n])}var r=e("./lib/spring"),o=e("ngraph.expose"),i=e("ngraph.merge"),a=e("ngraph.events");n=i(n,{springLength:30,springCoeff:8e-4,gravity:-1.2,theta:.8,dragCoeff:.02,timeStep:20});var u=n.createQuadTree||e("ngraph.quadtreebh"),s=n.createBounds||e("./lib/bounds"),f=n.createDragForce||e("./lib/dragForce"),c=n.createSpringForce||e("./lib/springForce"),d=n.integrator||e("./lib/eulerIntegrator"),l=n.createBody||e("./lib/createBody"),p=[],v=[],h=u(n),g=s(p,n),m=c(n),y=f(n),x=!0,w=0,b={bodies:p,quadTree:h,springs:v,settings:n,step:function(){t();var e=d(p,n.timeStep);return g.update(),e},addBody:function(e){if(!e)throw new Error("Body is required");return p.push(e),e},addBodyAt:function(e){if(!e)throw new Error("Body position is required");var n=l(e);return p.push(n),n},removeBody:function(e){if(e){var n=p.indexOf(e);if(!(n<0))return p.splice(n,1),0===p.length&&g.reset(),!0}},addSpring:function(e,n,t,o,i){if(!e||!n)throw new Error("Cannot add null spring to force simulator");"number"!=typeof t&&(t=-1);var a=new r(e,n,t,i>=0?i:-1,o);return v.push(a),a},getTotalMovement:function(){return w},removeSpring:function(e){if(e){var n=v.indexOf(e);return n>-1?(v.splice(n,1),!0):void 0}},getBestNewBodyPosition:function(e){return g.getBestNewPosition(e)},getBBox:function(){return x&&(g.update(),x=!1),g.box},invalidateBBox:function(){x=!0},gravity:function(e){return void 0!==e?(n.gravity=e,h.options({gravity:e}),this):n.gravity},theta:function(e){return void 0!==e?(n.theta=e,h.options({theta:e}),this):n.theta}};return o(n,b),a(b),b}n.exports=r},{"./lib/bounds":20,"./lib/createBody":21,"./lib/dragForce":22,"./lib/eulerIntegrator":23,"./lib/spring":24,"./lib/springForce":25,"ngraph.events":9,"ngraph.expose":10,"ngraph.merge":17,"ngraph.quadtreebh":26}],20:[function(e,n,t){n.exports=function(n,t){function r(){var e=n.length;if(0!==e){for(var t=Number.MAX_VALUE,r=Number.MAX_VALUE,o=Number.MIN_VALUE,a=Number.MIN_VALUE;e--;){var u=n[e];u.isPinned?(u.pos.x=u.prevPos.x,u.pos.y=u.prevPos.y):(u.prevPos.x=u.pos.x,u.prevPos.y=u.pos.y),u.pos.x<t&&(t=u.pos.x),u.pos.x>o&&(o=u.pos.x),u.pos.y<r&&(r=u.pos.y),u.pos.y>a&&(a=u.pos.y)}i.x1=t,i.x2=o,i.y1=r,i.y2=a}}var o=e("ngraph.random").random(42),i={x1:0,y1:0,x2:0,y2:0};return{box:i,update:r,reset:function(){i.x1=i.y1=0,i.x2=i.y2=0},getBestNewPosition:function(e){var n=i,r=0,a=0;if(e.length){for(var u=0;u<e.length;++u)r+=e[u].pos.x,a+=e[u].pos.y;r/=e.length,a/=e.length}else r=(n.x1+n.x2)/2,a=(n.y1+n.y2)/2;var s=t.springLength;return{x:r+o.next(s)-s/2,y:a+o.next(s)-s/2}}}}},{"ngraph.random":30}],21:[function(e,n,t){var r=e("ngraph.physics.primitives");n.exports=function(e){return new r.Body(e)}},{"ngraph.physics.primitives":18}],22:[function(e,n,t){n.exports=function(n){var t=e("ngraph.merge"),r=e("ngraph.expose");n=t(n,{dragCoeff:.02});var o={update:function(e){e.force.x-=n.dragCoeff*e.velocity.x,e.force.y-=n.dragCoeff*e.velocity.y}};return r(n,o,["dragCoeff"]),o}},{"ngraph.expose":10,"ngraph.merge":17}],23:[function(e,n,t){function r(e,n){var t,r=0,o=0,i=0,a=0,u=e.length;if(0===u)return 0;for(t=0;t<u;++t){var s=e[t],f=n/s.mass;s.velocity.x+=f*s.force.x,s.velocity.y+=f*s.force.y;var c=s.velocity.x,d=s.velocity.y,l=Math.sqrt(c*c+d*d);l>1&&(s.velocity.x=c/l,s.velocity.y=d/l),r=n*s.velocity.x,i=n*s.velocity.y,s.pos.x+=r,s.pos.y+=i,o+=Math.abs(r),a+=Math.abs(i)}return(o*o+a*a)/u}n.exports=r},{}],24:[function(e,n,t){function r(e,n,t,r,o){this.from=e,this.to=n,this.length=t,this.coeff=r,this.weight="number"==typeof o?o:1}n.exports=r},{}],25:[function(e,n,t){n.exports=function(n){var t=e("ngraph.merge"),r=e("ngraph.random").random(42),o=e("ngraph.expose");n=t(n,{springCoeff:2e-4,springLength:80});var i={update:function(e){var t=e.from,o=e.to,i=e.length<0?n.springLength:e.length,a=o.pos.x-t.pos.x,u=o.pos.y-t.pos.y,s=Math.sqrt(a*a+u*u);0===s&&(a=(r.nextDouble()-.5)/50,u=(r.nextDouble()-.5)/50,s=Math.sqrt(a*a+u*u));var f=s-i,c=(!e.coeff||e.coeff<0?n.springCoeff:e.coeff)*f/s*e.weight;t.force.x+=c*a,t.force.y+=c*u,o.force.x-=c*a,o.force.y-=c*u}};return o(n,i,["springCoeff","springLength"]),i}},{"ngraph.expose":10,"ngraph.merge":17,"ngraph.random":30}],26:[function(e,n,t){function r(e,n){return 0===n?e.quad0:1===n?e.quad1:2===n?e.quad2:3===n?e.quad3:null}function o(e,n,t){0===n?e.quad0=t:1===n?e.quad1=t:2===n?e.quad2=t:3===n&&(e.quad3=t)}n.exports=function(n){function t(){var e=g[m];return e?(e.quad0=null,e.quad1=null,e.quad2=null,e.quad3=null,e.body=null,e.mass=e.massX=e.massY=0,e.left=e.right=e.top=e.bottom=0):(e=new f,g[m]=e),++m,e}function i(e){var n,t,r,o,i=p,a=0,u=0,f=1,c=0,d=1;for(i[0]=y;f;){var v=i[c],g=v.body;f-=1,c+=1;var m=g!==e;g&&m?(t=g.pos.x-e.pos.x,r=g.pos.y-e.pos.y,o=Math.sqrt(t*t+r*r),0===o&&(t=(s.nextDouble()-.5)/50,r=(s.nextDouble()-.5)/50,o=Math.sqrt(t*t+r*r)),n=l*g.mass*e.mass/(o*o*o),a+=n*t,u+=n*r):m&&(t=v.massX/v.mass-e.pos.x,r=v.massY/v.mass-e.pos.y,o=Math.sqrt(t*t+r*r),0===o&&(t=(s.nextDouble()-.5)/50,r=(s.nextDouble()-.5)/50,o=Math.sqrt(t*t+r*r)),(v.right-v.left)/o<h?(n=l*v.mass*e.mass/(o*o*o),a+=n*t,u+=n*r):(v.quad0&&(i[d]=v.quad0,f+=1,d+=1),v.quad1&&(i[d]=v.quad1,f+=1,d+=1),v.quad2&&(i[d]=v.quad2,f+=1,d+=1),v.quad3&&(i[d]=v.quad3,f+=1,d+=1)))}e.force.x+=a,e.force.y+=u}function a(e){var n,r=Number.MAX_VALUE,o=Number.MAX_VALUE,i=Number.MIN_VALUE,a=Number.MIN_VALUE,s=e.length;for(n=s;n--;){var f=e[n].pos.x,c=e[n].pos.y;f<r&&(r=f),f>i&&(i=f),c<o&&(o=c),c>a&&(a=c)}var d=i-r,l=a-o;for(d>l?a=o+d:i=r+l,m=0,y=t(),y.left=r,y.right=i,y.top=o,y.bottom=a,n=s-1,n>=0&&(y.body=e[n]);n--;)u(e[n],y)}function u(e){for(v.reset(),v.push(y,e);!v.isEmpty();){var n=v.pop(),i=n.node,a=n.body;if(i.body){var u=i.body;if(i.body=null,d(u.pos,a.pos)){var f=3;do{var c=s.nextDouble(),l=(i.right-i.left)*c,p=(i.bottom-i.top)*c;u.pos.x=i.left+l,u.pos.y=i.top+p,f-=1}while(f>0&&d(u.pos,a.pos));if(0===f&&d(u.pos,a.pos))return}v.push(i,u),v.push(i,a)}else{var h=a.pos.x,g=a.pos.y;i.mass=i.mass+a.mass,i.massX=i.massX+a.mass*h,i.massY=i.massY+a.mass*g;var m=0,x=i.left,w=(i.right+x)/2,b=i.top,E=(i.bottom+b)/2;h>w&&(m+=1,x=w,w=i.right),g>E&&(m+=2,b=E,E=i.bottom);var L=r(i,m);L?v.push(L,a):(L=t(),L.left=x,L.top=b,L.right=w,L.bottom=E,L.body=a,o(i,m,L))}}}n=n||{},n.gravity="number"==typeof n.gravity?n.gravity:-1,n.theta="number"==typeof n.theta?n.theta:.8;var s=e("ngraph.random").random(1984),f=e("./node"),c=e("./insertStack"),d=e("./isSamePosition"),l=n.gravity,p=[],v=new c,h=n.theta,g=[],m=0,y=t();return{insertBodies:a,getRoot:function(){return y},updateBodyForce:i,options:function(e){return e?("number"==typeof e.gravity&&(l=e.gravity),"number"==typeof e.theta&&(h=e.theta),this):{gravity:l,theta:h}}}}},{"./insertStack":27,"./isSamePosition":28,"./node":29,"ngraph.random":30}],27:[function(e,n,t){function r(){this.stack=[],this.popIdx=0}function o(e,n){this.node=e,this.body=n}n.exports=r,r.prototype={isEmpty:function(){return 0===this.popIdx},push:function(e,n){var t=this.stack[this.popIdx];t?(t.node=e,t.body=n):this.stack[this.popIdx]=new o(e,n),++this.popIdx},pop:function(){if(this.popIdx>0)return this.stack[--this.popIdx]},reset:function(){this.popIdx=0}}},{}],28:[function(e,n,t){n.exports=function(e,n){var t=Math.abs(e.x-n.x),r=Math.abs(e.y-n.y);return t<1e-8&&r<1e-8}},{}],29:[function(e,n,t){n.exports=function(){this.body=null,this.quad0=null,this.quad1=null,this.quad2=null,this.quad3=null,this.mass=0,this.massX=0,this.massY=0,this.left=0,this.top=0,this.bottom=0,this.right=0}},{}],30:[function(e,n,t){function r(e){var n="number"==typeof e?e:+new Date,t=function(){return n=n+2127912214+(n<<12)&4294967295,n=4294967295&(3345072700^n^n>>>19),n=n+374761393+(n<<5)&4294967295,n=4294967295&(n+3550635116^n<<9),n=n+4251993797+(n<<3)&4294967295,n=4294967295&(3042594569^n^n>>>16),(268435455&n)/268435456};return{next:function(e){return Math.floor(t()*e)},nextDouble:function(){return t()}}}function o(e,n){var t=n||r();if("function"!=typeof t.next)throw new Error("customRandom does not match expected API: next() function is missing");return{forEach:function(n){var r,o,i;for(r=e.length-1;r>0;--r)o=t.next(r+1),i=e[o],e[o]=e[r],e[r]=i,n(i);e.length&&n(e[0])},shuffle:function(){var n,r,o;for(n=e.length-1;n>0;--n)r=t.next(n+1),o=e[r],e[r]=e[n],e[n]=o;return e}}}n.exports={random:r,randomIterator:o}},{}],31:[function(e,n,t){function r(e,n,t){function r(e){u.nodes.push(s(e))}function o(e){u.links.push(f(e))}function i(e){var n={id:e.id};return void 0!==e.data&&(n.data=e.data),n}function a(e){var n={fromId:e.fromId,toId:e.toId};return void 0!==e.data&&(n.data=e.data),n}var u={nodes:[],links:[]},s=n||i,f=t||a;return e.forEachNode(r),e.forEachLink(o),JSON.stringify(u)}n.exports=r},{}],32:[function(e,n,t){function r(e,n){var t=o(e);if(void 0===n)return t;for(var r=Object.keys(n),i=0;i<r.length;++i){var a=r[i],u=n[a];"link"===a?t.link(u):t.attr(a,u)}return t}function o(e){function n(e){return v||(v=i(p)),v.link(e),p}function t(e,n,t){return a.addEventListener(p,e,n,t),p}function o(e,n,t){return a.removeEventListener(p,e,n,t),p}function f(e){var n=r(e);return p.appendChild(n),n}function c(e,n){return 2===arguments.length?(null!==n?p.setAttributeNS(null,e,n):p.removeAttributeNS(null,e),p):p.getAttributeNS(null,e)}function d(e){return arguments.length?(p.setAttributeNS(s,"xlink:href",e),p):p.getAttributeNS(s,"xlink:href")}function l(e){return void 0!==e?(p.textContent=e,p):p.textContent}var p=e;if("string"==typeof e)p=window.document.createElementNS(u,e);else if(e.simplesvg)return e;var v;return p.simplesvg=!0,p.attr=c,p.append=f,p.link=d,p.text=l,p.on=t,p.off=o,p.dataSource=n,p}n.exports=r,r.compile=e("./lib/compile");var i=r.compileTemplate=e("./lib/compile_template"),a=e("add-event-listener"),u="http://www.w3.org/2000/svg",s="http://www.w3.org/1999/xlink"},{"./lib/compile":33,"./lib/compile_template":34,"add-event-listener":2}],33:[function(e,n,t){function r(e){try{return e=o(e),a(i.parseFromString(e,"text/xml").documentElement)}catch(n){throw n}}function o(e){if(e){var n='xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"',t=e.match(/^<\w+/);if(t){var r=t[0].length;return e.substr(0,r)+" "+n+" "+e.substr(r)}throw new Error("Cannot parse input text: invalid xml?")}}var i=e("./domparser.js"),a=e("../");n.exports=r},{"../":32,"./domparser.js":35}],34:[function(e,n,t){function r(e){var n=Object.create(null);return o(e,n),{link:function(e){function t(n){n(e)}Object.keys(n).forEach(function(e){var r=n[e];r.forEach(t)})}}}function o(e,n){var t=e.nodeType,r=1===t||3===t;if(r){var u;if(e.hasChildNodes()){var s=e.childNodes;for(u=0;u<s.length;++u)o(s[u],n)}if(3===t&&a(e,n),e.attributes){var f=e.attributes;for(u=0;u<f.length;++u)i(f[u],e,n)}}}function i(e,n,t){function r(e){n.setAttributeNS(null,a,e[s])}var o=e.value;if(o){var i=o.match(u);if(i){var a=e.localName,s=i[1],f=s.indexOf(".")<0;if(!f)throw new Error("simplesvg currently does not support nested bindings");var c=t[s];c?c.push(r):c=t[s]=[r]}}}function a(e,n){function t(n){e.nodeValue=n[i]}var r=e.nodeValue;if(r){var o=r.match(u);if(o){var i=o[1],a=(i.indexOf(".")<0, -n[i]);a?a.push(t):a=n[i]=[t]}}}n.exports=r;var u=/{{(.+?)}}/},{}],35:[function(e,n,t){function r(){return"undefined"==typeof DOMParser?{parseFromString:o}:new DOMParser}function o(){throw new Error("DOMParser is not supported by this platform. Please open issue here https://github.com/anvaka/simplesvg")}n.exports=r()},{}],36:[function(e,n,t){function r(){return{betweennessCentrality:o,degreeCentrality:i}}function o(e){var n=u.betweenness(e);return a(n)}function i(e,n){var t=u.degree(e,n);return a(t)}function a(e){function n(n,t){return e[t]-e[n]}function t(n){return{key:n,value:e[n]}}return Object.keys(e).sort(n).map(t)}var u=e("ngraph.centrality");n.exports=r},{"ngraph.centrality":4}],37:[function(e,n,t){function r(){return{density:function(e,n){var t=e.getNodesCount();return 0===t?NaN:n?e.getLinksCount()/(t*(t-1)):2*e.getLinksCount()/(t*(t-1))}}}n.exports=r},{}],38:[function(e,n,t){function r(e,n){function t(e,t){var i;if(t){var a=n.getNodeUI(e.id);i=o(a),"function"==typeof t.onStart&&i.onStart(t.onStart),"function"==typeof t.onDrag&&i.onDrag(t.onDrag),"function"==typeof t.onStop&&i.onStop(t.onStop),r[e.id]=i}else(i=r[e.id])&&(i.release(),delete r[e.id])}var r={};return{bindDragNDrop:t}}n.exports=r;var o=e("./dragndrop.js")},{"./dragndrop.js":39}],39:[function(e,n,t){function r(e){var n,t,r,u,s,f,c,d=0,l=0,p=!1,v=0,h=function(e){var n=0,t=0;return e=e||window.event,e.pageX||e.pageY?(n=e.pageX,t=e.pageY):(e.clientX||e.clientY)&&(n=e.clientX+window.document.body.scrollLeft+window.document.documentElement.scrollLeft,t=e.clientY+window.document.body.scrollTop+window.document.documentElement.scrollTop),[n,t]},g=function(e,n,r){t&&t(e,{x:n-d,y:r-l}),d=n,l=r},m=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},y=function(e){e.preventDefault&&e.preventDefault()},x=function(e){return m(e),!1},w=function(e){e=e||window.event,g(e,e.clientX,e.clientY)},b=function(e){if(e=e||window.event,p)return m(e),!1;var t=1===e.button&&null!==window.event||0===e.button;return t?(d=e.clientX,l=e.clientY,c=e.target||e.srcElement,n&&n(e,{x:d,y:l}),o.on("mousemove",w),o.on("mouseup",E),m(e),s=window.document.onselectstart,f=window.document.ondragstart,window.document.onselectstart=x,c.ondragstart=x,!1):void 0},E=function(e){e=e||window.event,o.off("mousemove",w),o.off("mouseup",E),window.document.onselectstart=s,c.ondragstart=f,c=null,r&&r(e)},L=function(n){if("function"==typeof u){n=n||window.event,n.preventDefault&&n.preventDefault(),n.returnValue=!1;var t,r=h(n),o=a(e),i={x:r[0]-o[0],y:r[1]-o[1]};t=n.wheelDelta?n.wheelDelta/360:n.detail/-9,u(n,t,i)}},N=function(n){!u&&n?"webkit"===i.browser?e.addEventListener("mousewheel",L,!1):e.addEventListener("DOMMouseScroll",L,!1):u&&!n&&("webkit"===i.browser?e.removeEventListener("mousewheel",L,!1):e.removeEventListener("DOMMouseScroll",L,!1)),u=n},k=function(e,n){return(e.clientX-n.clientX)*(e.clientX-n.clientX)+(e.clientY-n.clientY)*(e.clientY-n.clientY)},P=function(e){if(1===e.touches.length){m(e);var n=e.touches[0];g(e,n.clientX,n.clientY)}else if(2===e.touches.length){var t=k(e.touches[0],e.touches[1]),r=0;t<v?r=-1:t>v&&(r=1),u(e,r,{x:e.touches[0].clientX,y:e.touches[0].clientY}),v=t,m(e),y(e)}},j=function(e){p=!1,o.off("touchmove",P),o.off("touchend",j),o.off("touchcancel",j),c=null,r&&r(e)},A=function(e,t){m(e),y(e),d=t.clientX,l=t.clientY,c=e.target||e.srcElement,n&&n(e,{x:d,y:l}),p||(p=!0,o.on("touchmove",P),o.on("touchend",j),o.on("touchcancel",j))},_=function(e){return 1===e.touches.length?A(e,e.touches[0]):void(2===e.touches.length&&(m(e),y(e),v=k(e.touches[0],e.touches[1])))};return e.addEventListener("mousedown",b),e.addEventListener("touchstart",_),{onStart:function(e){return n=e,this},onDrag:function(e){return t=e,this},onStop:function(e){return r=e,this},onScroll:function(e){return N(e),this},release:function(){e.removeEventListener("mousedown",b),e.removeEventListener("touchstart",_),o.off("mousemove",w),o.off("mouseup",E),o.off("touchmove",P),o.off("touchend",j),o.off("touchcancel",j),N(null)}}}n.exports=r;var o=e("../Utils/documentEvents.js"),i=e("../Utils/browserInfo.js"),a=e("../Utils/findElementPosition.js")},{"../Utils/browserInfo.js":43,"../Utils/documentEvents.js":44,"../Utils/findElementPosition.js":45}],40:[function(e,n,t){function r(e,n){var t=o(n),r=null,i={},a={x:0,y:0};return t.mouseDown(function(e,n){r=e,a.x=n.clientX,a.y=n.clientY,t.mouseCapture(r);var o=i[e.id];return o&&o.onStart&&o.onStart(n,a),!0}).mouseUp(function(e){t.releaseMouseCapture(r),r=null;var n=i[e.id];return n&&n.onStop&&n.onStop(),!0}).mouseMove(function(e,n){if(r){var t=i[r.id];return t&&t.onDrag&&t.onDrag(n,{x:n.clientX-a.x,y:n.clientY-a.y}),a.x=n.clientX,a.y=n.clientY,!0}}),{bindDragNDrop:function(e,n){i[e.id]=n,n||delete i[e.id]}}}n.exports=r;var o=e("../WebGL/webglInputEvents.js")},{"../WebGL/webglInputEvents.js":61}],41:[function(e,n,t){function r(e,n){function t(e){return d[e]}n=o(n,{maxX:1024,maxY:1024,seed:"Deterministic randomness made me do this"});var r=i(n.seed),u=new a(Number.MAX_VALUE,Number.MAX_VALUE,Number.MIN_VALUE,Number.MIN_VALUE),s={},f=function(e){return{x:r.next(n.maxX),y:r.next(n.maxY)}},c=function(e,n){e.x<n.x1&&(n.x1=e.x),e.x>n.x2&&(n.x2=e.x),e.y<n.y1&&(n.y1=e.y),e.y>n.y2&&(n.y2=e.y)},d="function"==typeof Object.create?Object.create(null):{},l=function(e){d[e.id]=f(e),c(d[e.id],u)},p=function(){0!==e.getNodesCount()&&(u.x1=Number.MAX_VALUE,u.y1=Number.MAX_VALUE,u.x2=Number.MIN_VALUE,u.y2=Number.MIN_VALUE,e.forEachNode(l))},v=function(e){s[e.id]=e},h=function(e){for(var n=0;n<e.length;++n){var t=e[n];t.node&&("add"===t.changeType?l(t.node):delete d[t.node.id]),t.link&&("add"===t.changeType?v(t.link):delete s[t.link.id])}};return e.forEachNode(l),e.forEachLink(v),e.on("changed",h),{run:function(e){this.step()},step:function(){return p(),!0},getGraphRect:function(){return u},dispose:function(){e.off("change",h)},isNodePinned:function(e){return!0},pinNode:function(e,n){},getNodePosition:t,getLinkPosition:function(e){var n=s[e];return{from:t(n.fromId),to:t(n.toId)}},setNodePosition:function(e,n,t){var r=d[e];r&&(r.x=n,r.y=t)},placeNode:function(e){return"function"==typeof e?(f=e,p(),this):f(e)}}}n.exports=r;var o=e("ngraph.merge"),i=e("ngraph.random").random,a=e("../Utils/rect.js")},{"../Utils/rect.js":49,"ngraph.merge":17,"ngraph.random":30}],42:[function(e,n,t){function r(e){function n(){var n=o(e);return n.addEventListener=n.on,n}if(console.log("This method is deprecated. Please use Viva.events() instead"),!e)return e;var t=void 0!==e.on||void 0!==e.off||void 0!==e.fire;return t?{extend:function(){return e},on:e.on,stop:e.off}:{extend:n,on:e.on,stop:e.off}}var o=e("ngraph.events");n.exports=r},{"ngraph.events":9}],43:[function(e,n,t){function r(){if("undefined"==typeof window||!window.hasOwnProperty("navigator"))return{browser:"",version:"0"};var e=window.navigator.userAgent.toLowerCase(),n=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,r=/(msie) ([\w.]+)/,o=/(mozilla)(?:.*? rv:([\w.]+))?/,i=n.exec(e)||t.exec(e)||r.exec(e)||e.indexOf("compatible")<0&&o.exec(e)||[];return{browser:i[1]||"",version:i[2]||"0"}}n.exports=r()},{}],44:[function(e,n,t){function r(){return void 0===typeof document?a:{on:o,off:i}}function o(e,n){document.addEventListener(e,n)}function i(e,n){document.removeEventListener(e,n)}var a=e("./nullEvents.js");n.exports=r()},{"./nullEvents.js":48}],45:[function(e,n,t){function r(e){var n=0,t=0;if(e.offsetParent)do n+=e.offsetLeft,t+=e.offsetTop;while(null!==(e=e.offsetParent));return[n,t]}n.exports=r},{}],46:[function(e,n,t){function r(e){if(!e)throw{message:"Cannot get dimensions of undefined container"};var n=e.clientWidth,t=e.clientHeight;return{left:0,top:0,width:n,height:t}}n.exports=r},{}],47:[function(e,n,t){function r(e,n,t,r,i,a,u,s){return o(e,n,e,r,i,a,u,s)||o(e,r,t,r,i,a,u,s)||o(t,r,t,n,i,a,u,s)||o(t,n,e,n,i,a,u,s)}var o=e("gintersect");n.exports=r},{gintersect:3}],48:[function(e,n,t){function r(){return{on:o,off:o,stop:o}}function o(){}n.exports=r()},{}],49:[function(e,n,t){function r(e,n,t,r){this.x1=e||0,this.y1=n||0,this.x2=t||0,this.y2=r||0}n.exports=r},{}],50:[function(e,n,t){(function(e){function t(){function n(e){function n(){o=a.requestAnimationFrame(n),e()||t()}function t(){a.cancelAnimationFrame(o),o=0}function r(){o||n()}var o;return n(),{stop:t,restart:r}}function t(e){var n=(new Date).getTime(),t=Math.max(0,16-(n-u)),r=a.setTimeout(function(){e(n+t)},t);return u=n+t,r}function o(e){a.clearTimeout(e)}var i,a,u=0,s=["ms","moz","webkit","o"];for(a="undefined"!=typeof window?window:"undefined"!=typeof e?e:{setTimeout:r,clearTimeout:r},i=0;i<s.length&&!a.requestAnimationFrame;++i){var f=s[i];a.requestAnimationFrame=a[f+"RequestAnimationFrame"],a.cancelAnimationFrame=a[f+"CancelAnimationFrame"]||a[f+"CancelRequestAnimationFrame"]}return a.requestAnimationFrame||(a.requestAnimationFrame=t),a.cancelAnimationFrame||(a.cancelAnimationFrame=o),n}function r(){}n.exports=t()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],51:[function(e,n,t){function r(){return"undefined"==typeof window?a:{on:o,off:i}}function o(e,n){window.addEventListener(e,n)}function i(e,n){window.removeEventListener(e,n)}var a=e("./nullEvents.js");n.exports=r()},{"./nullEvents.js":48}],52:[function(e,n,t){function r(e,n){function t(e){return"string"==typeof q?q.indexOf(e)>=0:"boolean"!=typeof q||q}function r(){G=G||window.document.body,O=O||i(e,{springLength:80,springCoeff:2e-4}),F=F||a(e,{container:G}),n.hasOwnProperty("renderLinks")||(n.renderLinks=!0),n.prerender=n.prerender||0,U=(F.inputManager||s)(e,F)}function l(){F.beginRender(),n.renderLinks&&F.renderLinks(),F.renderNodes(),F.endRender()}function p(){return X=O.step()&&!V,l(),!X}function v(e){R||(R=void 0!==e?f(function(){if(e-=1,e<0){var n=!1;return n}return p()},M):f(p,M))}function h(){W||(X=!1,R.restart())}function g(){if("number"==typeof n.prerender&&n.prerender>0)for(var e=0;e<n.prerender;e+=1)O.step()}function m(){var e=O.getGraphRect(),n=c(G),t=(e.x2+e.x1)/2,r=(e.y2+e.y1)/2;H.offsetX=n.width/2-(t*H.scale-t),H.offsetY=n.height/2-(r*H.scale-r),F.graphCenterChanged(H.offsetX,H.offsetY),Y=!1}function y(e){var n=O.getNodePosition(e.id);F.addNode(e,n)}function x(e){F.releaseNode(e)}function w(e){var n=O.getLinkPosition(e.id);F.addLink(e,n)}function b(e){F.releaseLink(e)}function E(e){if(t("node")){var n=!1;U.bindDragNDrop(e,{onStart:function(){n=O.isNodePinned(e),O.pinNode(e,!0),V=!0,h()},onDrag:function(n,t){var r=O.getNodePosition(e.id);O.setNodePosition(e.id,r.x+t.x/H.scale,r.y+t.y/H.scale),V=!0,l()},onStop:function(){O.pinNode(e,n),V=!1}})}}function L(e){U.bindDragNDrop(e,null)}function N(){F.init(G),e.forEachNode(y),n.renderLinks&&e.forEachLink(w)}function k(){F.release(G)}function P(n){var t=n.node;"add"===n.changeType?(y(t),E(t),Y&&m()):"remove"===n.changeType?(L(t),x(t),0===e.getNodesCount()&&(Y=!0)):"update"===n.changeType&&(L(t),x(t),y(t),E(t))}function j(e){var t=e.link;if("add"===e.changeType)n.renderLinks&&w(t);else if("remove"===e.changeType)n.renderLinks&&b(t);else if("update"===e.changeType)throw"Update type is not implemented. TODO: Implement me!"}function A(e){var n,t;for(n=0;n<e.length;n+=1)t=e[n],t.node?P(t):t.link&&j(t);h()}function _(){m(),p()}function I(){B&&(B.release(),B=null)}function T(){e.off("changed",A)}function C(e,n){if(!n){var t=c(G);n={x:t.width/2,y:t.height/2}}var r=Math.pow(1.4,e?-.2:.2);return H.scale=F.scale(r,n),l(),J.fire("scale",H.scale),H.scale}function S(){u.on("resize",_),I(),t("drag")&&(B=d(G),B.onDrag(function(e,n){F.translateRel(n.x,n.y),l(),J.fire("drag",n)})),t("scroll")&&(B||(B=d(G)),B.onScroll(function(e,n,t){C(n<0,t)})),e.forEachNode(E),T(),e.on("changed",A)}function D(){z=!1,T(),I(),u.off("resize",_),J.off(),R.stop(),e.forEachLink(function(e){n.renderLinks&&b(e)}),e.forEachNode(function(e){L(e),x(e)}),O.dispose(),k()}var M=30;n=n||{};var U,R,B,O=n.layout,F=n.graphics,G=n.container,q=void 0===n.interactive||n.interactive,z=!1,Y=!0,X=!1,V=!1,W=!1,H={offsetX:0,offsetY:0,scale:1},J=o({});return{run:function(e){return z||(r(),g(),N(),m(),S(),z=!0),v(e),this},reset:function(){F.resetScale(),m(),H.scale=1},pause:function(){W=!0,R.stop()},resume:function(){W=!1,R.restart()},rerender:function(){return l(),this},zoomOut:function(){return C(!0)},zoomIn:function(){return C(!1)},getTransform:function(){return H},moveTo:function(e,n){F.graphCenterChanged(H.offsetX-e*H.scale,H.offsetY-n*H.scale),l()},getGraphics:function(){return F},getLayout:function(){return O},dispose:function(){D()},on:function(e,n){return J.on(e,n),this},off:function(e,n){return J.off(e,n),this}}}n.exports=r;var o=e("ngraph.events"),i=e("ngraph.forcelayout"),a=e("./svgGraphics.js"),u=e("../Utils/windowEvents.js"),s=e("../Input/domInputManager.js"),f=e("../Utils/timer.js"),c=e("../Utils/getDimensions.js"),d=e("../Input/dragndrop.js")},{"../Input/domInputManager.js":38,"../Input/dragndrop.js":39,"../Utils/getDimensions.js":46,"../Utils/timer.js":50,"../Utils/windowEvents.js":51,"./svgGraphics.js":53,"ngraph.events":9,"ngraph.forcelayout":11}],53:[function(e,n,t){function r(){function e(){var e=o("svg");return n=o("g").attr("buffered-rendering","dynamic"),e.appendChild(n),e}var n,t,r,u=0,s=0,f=1,c={},d={},l=function(e){return o("rect").attr("width",10).attr("height",10).attr("fill","#00a2e8")},p=function(e,n){e.attr("x",n.x-5).attr("y",n.y-5)},v=function(e){return o("line").attr("stroke","#999")},h=function(e,n,t){e.attr("x1",n.x).attr("y1",n.y).attr("x2",t.x).attr("y2",t.y)},g=function(e){e.fire("rescaled")},m={x:0,y:0},y={x:0,y:0},x={x:0,y:0},w=function(){if(n){var e="matrix("+f+", 0, 0,"+f+","+u+","+s+")";n.attr("transform",e)}};t=e();var b={getNodeUI:function(e){return c[e]},getLinkUI:function(e){return d[e]},node:function(e){if("function"==typeof e)return l=e,this},link:function(e){if("function"==typeof e)return v=e,this},placeNode:function(e){return p=e,this},placeLink:function(e){return h=e,this},beginRender:function(){},endRender:function(){},graphCenterChanged:function(e,n){u=e,s=n,w()},inputManager:a,translateRel:function(e,r){var o=t.createSVGPoint(),i=n.getCTM(),a=t.createSVGPoint().matrixTransform(i.inverse());o.x=e,o.y=r,o=o.matrixTransform(i.inverse()),o.x=(o.x-a.x)*i.a,o.y=(o.y-a.y)*i.d,i.e+=o.x,i.f+=o.y;var u="matrix("+i.a+", 0, 0,"+i.d+","+i.e+","+i.f+")";n.attr("transform",u)},scale:function(e,r){var o=t.createSVGPoint();o.x=r.x,o.y=r.y,o=o.matrixTransform(n.getCTM().inverse());var i=t.createSVGMatrix().translate(o.x,o.y).scale(e).translate(-o.x,-o.y),a=n.getCTM().multiply(i);f=a.a,u=a.e,s=a.f;var c="matrix("+a.a+", 0, 0,"+a.d+","+a.e+","+a.f+")";return n.attr("transform",c),g(this),f},resetScale:function(){f=1;var e="matrix(1, 0, 0, 1, 0, 0)";return n.attr("transform",e),g(this),this},init:function(e){e.appendChild(t),w(),"function"==typeof r&&r(t)},release:function(e){t&&e&&e.removeChild(t)},addLink:function(e,t){var r=v(e);if(r)return r.position=t,r.link=e,d[e.id]=r,n.childElementCount>0?n.insertBefore(r,n.firstChild):n.appendChild(r),r},releaseLink:function(e){var t=d[e.id];t&&(n.removeChild(t),delete d[e.id])},addNode:function(e,t){var r=l(e);if(r)return r.position=t,r.node=e,c[e.id]=r,n.appendChild(r),r},releaseNode:function(e){var t=c[e.id];t&&(n.removeChild(t),delete c[e.id])},renderNodes:function(){for(var e in c)if(c.hasOwnProperty(e)){var n=c[e];m.x=n.position.x,m.y=n.position.y,p(n,m,n.node)}},renderLinks:function(){for(var e in d)if(d.hasOwnProperty(e)){var n=d[e];y.x=n.position.from.x,y.y=n.position.from.y,x.x=n.position.to.x,x.y=n.position.to.y,h(n,y,x,n.link)}},getGraphicsRoot:function(e){return"function"==typeof e&&(t?e(t):r=e),t},getSvgRoot:function(){return t}};return i(b),b}n.exports=r;var o=e("simplesvg"),i=e("ngraph.events"),a=e("../Input/domInputManager.js")},{"../Input/domInputManager.js":38,"ngraph.events":9,simplesvg:32}],54:[function(e,n,t){function r(e){e=c(e,{enableBlending:!0,preserveDrawingBuffer:!1,clearColor:!1,clearColorValue:{r:1,g:1,b:1,a:1}});var n,t,r,d,l,p,v,h,g=0,m=0,y=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],x=[],w=[],b={},E={},L=i(),N=a(),k=function(e){return u()},P=function(e){return s(3014898687)},j=function(){L.updateTransform(y),N.updateTransform(y)},A=function(){y=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]},_=function(){n&&t&&(d=t.width=Math.max(n.offsetWidth,1),l=t.height=Math.max(n.offsetHeight,1),r&&r.viewport(0,0,d,l),L&&L.updateSize(d/2,l/2),N&&N.updateSize(d/2,l/2))},I=function(e){e.fire("rescaled")};t=window.document.createElement("canvas");var T={getLinkUI:function(e){return E[e]},getNodeUI:function(e){return b[e]},node:function(e){if("function"==typeof e)return k=e,this},link:function(e){if("function"==typeof e)return P=e,this},placeNode:function(e){return p=e,this},placeLink:function(e){return v=e,this},inputManager:o,beginRender:function(){},endRender:function(){m>0&&L.render(),g>0&&N.render()},bringLinkToFront:function(e){var n,t,r=L.getFrontLinkId();L.bringToFront(e),r>e.id&&(n=e.id,t=w[r],w[r]=w[n],w[r].id=r,w[n]=t,w[n].id=n)},graphCenterChanged:function(e,n){y[12]=2*e/d-1,y[13]=1-2*n/l,j()},addLink:function(e,n){var t=m++,r=P(e);return r.id=t,r.pos=n,L.createLink(r),w[t]=r,E[e.id]=r,r},addNode:function(e,n){var t=g++,r=k(e);return r.id=t,r.position=n,r.node=e,N.createNode(r),x[t]=r,b[e.id]=r,r},translateRel:function(e,n){y[12]+=2*y[0]*e/d/y[0],y[13]-=2*y[5]*n/l/y[5],j()},scale:function(e,n){var t=2*n.x/d-1,r=1-2*n.y/l;return t-=y[12],r-=y[13],y[12]+=t*(1-e),y[13]+=r*(1-e),y[0]*=e,y[5]*=e,j(),I(this),y[0]},resetScale:function(){return A(),r&&(_(),j()),this},updateSize:_,init:function(o){var i={};if(e.preserveDrawingBuffer&&(i.preserveDrawingBuffer=!0),n=o,_(),A(),n.appendChild(t),r=t.getContext("experimental-webgl",i),!r){var a="Could not initialize WebGL. Seems like the browser doesn't support it.";throw window.alert(a),a}if(e.enableBlending&&(r.blendFunc(r.SRC_ALPHA,r.ONE_MINUS_SRC_ALPHA),r.enable(r.BLEND)),e.clearColor){var u=e.clearColorValue;r.clearColor(u.r,u.g,u.b,u.a),this.beginRender=function(){r.clear(r.COLOR_BUFFER_BIT)}}L.load(r),L.updateSize(d/2,l/2),N.load(r),N.updateSize(d/2,l/2),j(),"function"==typeof h&&h(t)},release:function(e){t&&e&&e.removeChild(t)},isSupported:function(){var e=window.document.createElement("canvas"),n=e&&e.getContext&&e.getContext("experimental-webgl");return n},releaseLink:function(e){m>0&&(m-=1);var n=E[e.id];delete E[e.id],L.removeLink(n);var t=n.id;if(t<m){if(0===m||m===t)return;var r=w[m];w[t]=r,r.id=t}},releaseNode:function(e){g>0&&(g-=1);var n=b[e.id];delete b[e.id],N.removeNode(n);var t=n.id;if(t<g){if(0===g||g===t)return;var r=x[g];x[t]=r,r.id=t,N.replaceProperties(n,r)}},renderNodes:function(){for(var e={x:0,y:0},n=0;n<g;++n){var t=x[n];e.x=t.position.x,e.y=t.position.y,p&&p(t,e),N.position(t,e)}},renderLinks:function(){if(!this.omitLinksRendering)for(var e={x:0,y:0},n={x:0,y:0},t=0;t<m;++t){var r=w[t],o=r.pos.from;n.x=o.x,n.y=-o.y,o=r.pos.to,e.x=o.x,e.y=-o.y,v&&v(r,n,e),L.position(r,n,e)}},getGraphicsRoot:function(e){return"function"==typeof e&&(t?e(t):h=e),t},setNodeProgram:function(e){if(!r&&e)N=e;else if(e)throw"Not implemented. Cannot swap shader on the fly... Yet."},setLinkProgram:function(e){if(!r&&e)L=e;else if(e)throw"Not implemented. Cannot swap shader on the fly... Yet."},transformClientToGraphCoordinates:function(e){return e.x=2*e.x/d-1,e.y=1-2*e.y/l,e.x=(e.x-y[12])/y[0],e.y=(e.y-y[13])/y[5],e.x=e.x*(d/2),e.y=e.y*(-l/2),e},transformGraphToClientCoordinates:function(e){return e.x=e.x/(d/2),e.y=e.y/(-l/2),e.x=e.x*y[0]+y[12],e.y=e.y*y[5]+y[13],e.x=(e.x+1)*d/2,e.y=(1-e.y)*l/2,e},getNodeAtClientPos:function(e,n){if("function"!=typeof n)return null;this.transformClientToGraphCoordinates(e);for(var t=0;t<g;++t)if(n(x[t],e.x,e.y))return x[t].node;return null}};return f(T),T}n.exports=r;var o=e("../Input/webglInputManager.js"),i=e("../WebGL/webglLinkProgram.js"),a=e("../WebGL/webglNodeProgram.js"),u=e("../WebGL/webglSquare.js"),s=e("../WebGL/webglLine.js"),f=e("ngraph.events"),c=e("ngraph.merge")},{"../Input/webglInputManager.js":40,"../WebGL/webglLine.js":62,"../WebGL/webglLinkProgram.js":63,"../WebGL/webglNodeProgram.js":64,"../WebGL/webglSquare.js":65,"ngraph.events":9,"ngraph.merge":17}],55:[function(e,n,t){function r(e){var n=10414335;if("string"==typeof e&&e)if(4===e.length&&(e=e.replace(/([^#])/g,"$1$1")),9===e.length)n=parseInt(e.substr(1),16);else{if(7!==e.length)throw'Color expected in hex format with preceding "#". E.g. #00ff00. Got value: '+e;n=parseInt(e.substr(1),16)<<8|255}else"number"==typeof e&&(n=e);return n}n.exports=r},{}],56:[function(e,n,t){function r(e){this.canvas=window.document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.isDirty=!1,this.canvas.width=this.canvas.height=e}n.exports=r},{}],57:[function(e,n,t){function r(e){function n(n,t){var r=e.createShader(t);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){var o=e.getShaderInfoLog(r);throw window.alert(o),o}return r}function t(t,r){var o=e.createProgram(),i=n(t,e.VERTEX_SHADER),a=n(r,e.FRAGMENT_SHADER);if(e.attachShader(o,i),e.attachShader(o,a),e.linkProgram(o),!e.getProgramParameter(o,e.LINK_STATUS)){var u=e.getShaderInfoLog(o);throw window.alert(u),u}return o}function r(e,n,t){if((n+1)*t>e.length){var r=new Float32Array(e.length*t*2);return r.set(e),r}return e}function a(n,t){for(var r={},o=0;o<t.length;++o){var i=t[o],a=-1;if("a"===i[0]&&"_"===i[1]){if(a=e.getAttribLocation(n,i),a===-1)throw new Error("Program doesn't have required attribute: "+i);r[i.slice(2)]=a}else{if("u"!==i[0]||"_"!==i[1])throw new Error("Couldn't figure out your intent. All uniforms should start with 'u_' prefix, and attributes with 'a_'");if(a=e.getUniformLocation(n,i),null===a)throw new Error("Program doesn't have required uniform: "+i);r[i.slice(2)]=a}}return r}return{createProgram:t,extendArray:r,copyArrayPart:o,swapArrayPart:i,getLocations:a,context:e}}function o(e,n,t,r){for(var o=0;o<r;++o)e[n+o]=e[t+o]}function i(e,n,t,r){for(var o=0;o<r;++o){var i=e[n+o];e[n+o]=e[t+o],e[t+o]=i}}n.exports=r},{}],58:[function(e,n,t){function r(e){function n(){var e;for(E.isDirty=!1,e=0;e<w.length;++e)w[e].isDirty=!1}function t(e){var n=y[e];if(!n)return!1;if(delete y[e],m-=1,m===n.offset)return!0;var t=c(n.offset),r=c(m);p(r,t);var o=y[b[m]];return o.offset=n.offset,b[n.offset]=b[m],l(),!0}function r(){return w}function a(e){return y[e]}function u(e,n){if(y.hasOwnProperty(e))n(y[e]);else{var t=new window.Image,r=m;m+=1,t.crossOrigin="anonymous",t.onload=function(){l(),f(r,t,n)},t.src=e}}function s(){var e=new i(h*g);w.push(e)}function f(e,n,t){var r=c(e),o={offset:e};r.textureNumber>=w.length&&s();var i=w[r.textureNumber];i.ctx.drawImage(n,r.col*g,r.row*g,g,g),b[e]=n.src,y[n.src]=o,i.isDirty=!0,t(o)}function c(n){var t=n/e<<0,r=n%e,o=r/h<<0,i=r%h;return{textureNumber:t,row:o,col:i}}function d(){E.isDirty=!0,x=0,v=null}function l(){v&&(window.clearTimeout(v),x+=1,v=null),x>10?d():v=window.setTimeout(d,400)}function p(e,n){var t=w[e.textureNumber].canvas,r=w[n.textureNumber].ctx,o=n.col*g,i=n.row*g;r.drawImage(t,e.col*g,e.row*g,g,g,o,i,g,g),w[e.textureNumber].isDirty=!0,w[n.textureNumber].isDirty=!0}var v,h=Math.sqrt(e||1024)<<0,g=h,m=1,y={},x=0,w=[],b=[];if(!o(e))throw"Tiles per texture should be power of two.";var E={isDirty:!1,clearDirty:n,remove:t,getTextures:r,getCoordinates:a,load:u};return E}function o(e){return 0===(e&e-1)}var i=e("./texture.js");n.exports=r},{"./texture.js":56}],59:[function(e,n,t){function r(e,n){return{_texture:0,_offset:0,size:"number"==typeof e?e:32,src:n}}n.exports=r},{}],60:[function(e,n,t){function r(e){function n(e,n){e.nativeObject&&m.deleteTexture(e.nativeObject);var t=m.createTexture();m.activeTexture(m["TEXTURE"+n]),m.bindTexture(m.TEXTURE_2D,t),m.texImage2D(m.TEXTURE_2D,0,m.RGBA,m.RGBA,m.UNSIGNED_BYTE,e.canvas),m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.LINEAR),m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.LINEAR_MIPMAP_NEAREST),m.generateMipmap(m.TEXTURE_2D),m.uniform1i(w["sampler"+n],n),e.nativeObject=t}function t(){if(h.isDirty){var e,t=h.getTextures();for(e=0;e<t.length;++e)!t[e].isDirty&&t[e].nativeObject||n(t[e],e);h.clearDirty()}}function r(n){m=n,x=u(n),h=new a(e),g=x.createProgram(j,P),m.useProgram(g),w=x.getLocations(g,["a_vertexPos","a_customAttributes","u_screenSize","u_transform","u_sampler0","u_sampler1","u_sampler2","u_sampler3","u_tilesPerTexture"]),m.uniform1f(w.tilesPerTexture,e),m.enableVertexAttribArray(w.vertexPos),m.enableVertexAttribArray(w.customAttributes),y=m.createBuffer()}function s(e,n){var t=e.id*k;_[t]=n.x-e.size,_[t+1]=-n.y-e.size,_[t+2]=4*e._offset,_[t+3]=n.x+e.size,_[t+4]=-n.y-e.size,_[t+5]=4*e._offset+1,_[t+6]=n.x-e.size,_[t+7]=-n.y+e.size,_[t+8]=4*e._offset+2,_[t+9]=n.x-e.size,_[t+10]=-n.y+e.size,_[t+11]=4*e._offset+2,_[t+12]=n.x+e.size,_[t+13]=-n.y-e.size,_[t+14]=4*e._offset+1,_[t+15]=n.x+e.size,_[t+16]=-n.y+e.size,_[t+17]=4*e._offset+3}function f(e){_=x.extendArray(_,A,k),A+=1;var n=h.getCoordinates(e.src);n?e._offset=n.offset:(e._offset=0,h.load(e.src,function(n){e._offset=n.offset}))}function c(e){A>0&&(A-=1),e.id<A&&A>0&&(e.src&&h.remove(e.src),x.copyArrayPart(_,e.id*k,A*k,k))}function d(e,n){n._offset=e._offset}function l(e){N=!0,L=e}function p(e,n){b=e,E=n,N=!0}function v(){m.useProgram(g),m.bindBuffer(m.ARRAY_BUFFER,y),m.bufferData(m.ARRAY_BUFFER,_,m.DYNAMIC_DRAW),N&&(N=!1,m.uniformMatrix4fv(w.transform,!1,L),m.uniform2f(w.screenSize,b,E)),m.vertexAttribPointer(w.vertexPos,2,m.FLOAT,!1,3*Float32Array.BYTES_PER_ELEMENT,0),m.vertexAttribPointer(w.customAttributes,1,m.FLOAT,!1,3*Float32Array.BYTES_PER_ELEMENT,8),t(),m.drawArrays(m.TRIANGLES,0,6*A)}var h,g,m,y,x,w,b,E,L,N,k=18,P=o(),j=i(),e=e||1024,A=0,_=new Float32Array(64);return{load:r,position:s,createNode:f,removeNode:c,replaceProperties:d,updateTransform:l,updateSize:p,render:v}}function o(){return["precision mediump float;","varying vec4 color;","varying vec3 vTextureCoord;","uniform sampler2D u_sampler0;","uniform sampler2D u_sampler1;","uniform sampler2D u_sampler2;","uniform sampler2D u_sampler3;","void main(void) {"," if (vTextureCoord.z == 0.) {"," gl_FragColor = texture2D(u_sampler0, vTextureCoord.xy);"," } else if (vTextureCoord.z == 1.) {"," gl_FragColor = texture2D(u_sampler1, vTextureCoord.xy);"," } else if (vTextureCoord.z == 2.) {"," gl_FragColor = texture2D(u_sampler2, vTextureCoord.xy);"," } else if (vTextureCoord.z == 3.) {"," gl_FragColor = texture2D(u_sampler3, vTextureCoord.xy);"," } else { gl_FragColor = vec4(0, 1, 0, 1); }","}"].join("\n")}function i(){return["attribute vec2 a_vertexPos;","attribute float a_customAttributes;","uniform vec2 u_screenSize;","uniform mat4 u_transform;","uniform float u_tilesPerTexture;","varying vec3 vTextureCoord;","void main(void) {"," gl_Position = u_transform * vec4(a_vertexPos/u_screenSize, 0, 1);","float corner = mod(a_customAttributes, 4.);","float tileIndex = mod(floor(a_customAttributes / 4.), u_tilesPerTexture);","float tilesPerRow = sqrt(u_tilesPerTexture);","float tileSize = 1./tilesPerRow;","float tileColumn = mod(tileIndex, tilesPerRow);","float tileRow = floor(tileIndex/tilesPerRow);","if(corner == 0.0) {"," vTextureCoord.xy = vec2(0, 1);","} else if(corner == 1.0) {"," vTextureCoord.xy = vec2(1, 1);","} else if(corner == 2.0) {"," vTextureCoord.xy = vec2(0, 0);","} else {"," vTextureCoord.xy = vec2(1, 0);","}","vTextureCoord *= tileSize;","vTextureCoord.x += tileColumn * tileSize;","vTextureCoord.y += tileRow * tileSize;","vTextureCoord.z = floor(floor(a_customAttributes / 4.)/u_tilesPerTexture);","}"].join("\n")}var a=e("./webglAtlas.js"),u=e("./webgl.js");n.exports=r},{"./webgl.js":57,"./webglAtlas.js":58}],61:[function(e,n,t){function r(e){function n(){x=null}function t(e){x=e}function r(e){return"function"==typeof e&&P.push(e),A}function i(e){return"function"==typeof e&&k.push(e),A}function a(e){return"function"==typeof e&&N.push(e),A}function u(e){return"function"==typeof e&&L.push(e),A}function s(e){return"function"==typeof e&&E.push(e),A}function f(e){return"function"==typeof e&&b.push(e),A}function c(e){return"function"==typeof e&&w.push(e),A}function d(e,n,t){if(e&&e.size){var r=e.position,o=e.size;return r.x-o<n&&n<r.x+o&&r.y-o<t&&t<r.y+o}return!0}function l(n){return e.getNodeAtClientPos(n,d)}function p(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function v(e){return p(e),!1}function h(e,n){var t,r;for(t=0;t<e.length;t+=1)if(r=e[t].apply(void 0,n))return!0}function g(e){var n={x:0,y:0},t=null,r=1,i=+new Date,a=function(e){h(N,[t,e]),n.x=e.clientX,n.y=e.clientY},u=function(){o.off("mousemove",a),o.off("mouseup",u)},s=function(){y=e.getBoundingClientRect()};window.addEventListener("resize",s),s(),e.addEventListener("mousemove",function(e){if(!x){r++%7===0&&(s(),r=1);var o,i=!1;n.x=e.clientX-y.left,n.y=e.clientY-y.top,o=l(n),o&&t!==o?(t&&h(b,[t]),t=o,i=i||h(w,[t])):null===o&&t!==o&&(i=i||h(b,[t]),t=null),i&&p(e)}}),e.addEventListener("mousedown",function(e){var r,i=!1;s(),n.x=e.clientX-y.left,n.y=e.clientY-y.top,r=[l(n),e],r[0]?(i=h(E,r),o.on("mousemove",a),o.on("mouseup",u),m=window.document.onselectstart,window.document.onselectstart=v,t=r[0]):t=null,i&&p(e)}),e.addEventListener("mouseup",function(e){var r,o=+new Date;n.x=e.clientX-y.left,n.y=e.clientY-y.top;var a=l(n),u=a===t;r=[a||t,e],r[0]&&(window.document.onselectstart=m,o-i<400&&u?h(P,r):h(k,r),i=o,h(L,r)&&p(e))})}if(e.webglInputEvents)return e.webglInputEvents;var m,y,x=null,w=[],b=[],E=[],L=[],N=[],k=[],P=[],j=e.getGraphicsRoot();g(j);var A={mouseEnter:c,mouseLeave:f,mouseDown:s,mouseUp:u,mouseMove:a,click:i,dblClick:r,mouseCapture:t,releaseMouseCapture:n};return e.webglInputEvents=A,A}var o=e("../Utils/documentEvents.js");n.exports=r},{"../Utils/documentEvents.js":44}],62:[function(e,n,t){function r(e){return{color:o(e)}}var o=e("./parseColor.js");n.exports=r},{"./parseColor.js":55}],63:[function(e,n,t){function r(){var e,n,t,r,i,a,u,s,f,c,d=6,l=2*(2*Float32Array.BYTES_PER_ELEMENT+Uint32Array.BYTES_PER_ELEMENT),p=["precision mediump float;","varying vec4 color;","void main(void) {"," gl_FragColor = color;","}"].join("\n"),v=["attribute vec2 a_vertexPos;","attribute vec4 a_color;","uniform vec2 u_screenSize;","uniform mat4 u_transform;","varying vec4 color;","void main(void) {"," gl_Position = u_transform * vec4(a_vertexPos/u_screenSize, 0.0, 1.0);"," color = a_color.abgr;","}"].join("\n"),h=0,g=new ArrayBuffer(16*l),m=new Float32Array(g),y=new Uint32Array(g),x=function(){if((h+1)*l>g.byteLength){var e=new ArrayBuffer(2*g.byteLength),n=new Float32Array(e),t=new Uint32Array(e);t.set(y),m=n,y=t,g=e}};return{load:function(a){n=a,r=o(a),e=r.createProgram(v,p),n.useProgram(e),i=r.getLocations(e,["a_vertexPos","a_color","u_screenSize","u_transform"]),n.enableVertexAttribArray(i.vertexPos),n.enableVertexAttribArray(i.color),t=n.createBuffer()},position:function(e,n,t){var r=e.id,o=r*d;m[o]=n.x,m[o+1]=n.y,y[o+2]=e.color,m[o+3]=t.x,m[o+4]=t.y,y[o+5]=e.color},createLink:function(e){x(),h+=1,a=e.id},removeLink:function(e){h>0&&(h-=1),e.id<h&&h>0&&r.copyArrayPart(y,e.id*d,h*d,d)},updateTransform:function(e){c=!0,f=e},updateSize:function(e,n){u=e,s=n,c=!0},render:function(){n.useProgram(e),n.bindBuffer(n.ARRAY_BUFFER,t),n.bufferData(n.ARRAY_BUFFER,g,n.DYNAMIC_DRAW),c&&(c=!1,n.uniformMatrix4fv(i.transform,!1,f),n.uniform2f(i.screenSize,u,s)),n.vertexAttribPointer(i.vertexPos,2,n.FLOAT,!1,3*Float32Array.BYTES_PER_ELEMENT,0),n.vertexAttribPointer(i.color,4,n.UNSIGNED_BYTE,!0,3*Float32Array.BYTES_PER_ELEMENT,8),n.drawArrays(n.LINES,0,2*h),a=h-1},bringToFront:function(e){a>e.id&&r.swapArrayPart(m,e.id*d,a*d,d),a>0&&(a-=1)},getFrontLinkId:function(){return a}}}var o=e("./webgl.js");n.exports=r},{"./webgl.js":57}],64:[function(e,n,t){function r(){function e(){if((P+1)*w>=L.byteLength){var e=new ArrayBuffer(2*L.byteLength),n=new Float32Array(e),t=new Uint32Array(e);t.set(k),N=n,k=t,L=e}}function n(e){d=e,v=o(e),c=v.createProgram(E,b),d.useProgram(c), -p=v.getLocations(c,["a_vertexPos","a_color","u_screenSize","u_transform"]),d.enableVertexAttribArray(p.vertexPos),d.enableVertexAttribArray(p.color),l=d.createBuffer()}function t(e,n){var t=e.id;N[t*x]=n.x,N[t*x+1]=-n.y,N[t*x+2]=e.size,k[t*x+3]=e.color}function r(e){y=!0,m=e}function i(e,n){h=e,g=n,y=!0}function a(e){P>0&&(P-=1),e.id<P&&P>0&&v.copyArrayPart(k,e.id*x,P*x,x)}function u(){e(),P+=1}function s(){}function f(){d.useProgram(c),d.bindBuffer(d.ARRAY_BUFFER,l),d.bufferData(d.ARRAY_BUFFER,L,d.DYNAMIC_DRAW),y&&(y=!1,d.uniformMatrix4fv(p.transform,!1,m),d.uniform2f(p.screenSize,h,g)),d.vertexAttribPointer(p.vertexPos,3,d.FLOAT,!1,x*Float32Array.BYTES_PER_ELEMENT,0),d.vertexAttribPointer(p.color,4,d.UNSIGNED_BYTE,!0,x*Float32Array.BYTES_PER_ELEMENT,12),d.drawArrays(d.POINTS,0,P)}var c,d,l,p,v,h,g,m,y,x=4,w=3*Float32Array.BYTES_PER_ELEMENT+Uint32Array.BYTES_PER_ELEMENT,b=["precision mediump float;","varying vec4 color;","void main(void) {"," gl_FragColor = color;","}"].join("\n"),E=["attribute vec3 a_vertexPos;","attribute vec4 a_color;","uniform vec2 u_screenSize;","uniform mat4 u_transform;","varying vec4 color;","void main(void) {"," gl_Position = u_transform * vec4(a_vertexPos.xy/u_screenSize, 0, 1);"," gl_PointSize = a_vertexPos.z * u_transform[0][0];"," color = a_color.abgr;","}"].join("\n"),L=new ArrayBuffer(16*w),N=new Float32Array(L),k=new Uint32Array(L),P=0;return{load:n,position:t,updateTransform:r,updateSize:i,removeNode:a,createNode:u,replaceProperties:s,render:f}}var o=e("./webgl.js");n.exports=r},{"./webgl.js":57}],65:[function(e,n,t){function r(e,n){return{size:"number"==typeof e?e:10,color:o(n)}}var o=e("./parseColor.js");n.exports=r},{"./parseColor.js":55}],66:[function(e,n,t){n.exports="0.10.1"},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/plugins/analysis/webinterface/httpserver/websocket_channel.go b/plugins/analysis/webinterface/httpserver/websocket_channel.go deleted file mode 100644 index 0b75fefe284f958ddbdf54be568035b5a1483ac2..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/httpserver/websocket_channel.go +++ /dev/null @@ -1,58 +0,0 @@ -package httpserver - -import ( - "fmt" - - "golang.org/x/net/websocket" -) - -type WebSocketChannel struct { - ws *websocket.Conn - send chan string -} - -func NewWebSocketChannel(ws *websocket.Conn) *WebSocketChannel { - wsChan := &WebSocketChannel{ - ws: ws, - send: make(chan string, 1024), - } - - go wsChan.writer() - - return wsChan -} - -func (c *WebSocketChannel) Write(update string) { - c.send <- update -} - -func (c *WebSocketChannel) TryWrite(update string) { - select { - case c.send <- update: - default: - } -} - -func (c *WebSocketChannel) KeepAlive() { - buf := make([]byte, 1) - for { - if _, err := c.ws.Read(buf); err != nil { - break - } - - _, _ = fmt.Fprint(c.ws, "_") - } -} - -func (c *WebSocketChannel) Close() { - close(c.send) - _ = c.ws.Close() -} - -func (c *WebSocketChannel) writer() { - for pkt := range c.send { - if _, err := fmt.Fprint(c.ws, pkt); err != nil { - break - } - } -} diff --git a/plugins/analysis/webinterface/plugin.go b/plugins/analysis/webinterface/plugin.go deleted file mode 100644 index 68d1a33d2a70efaa1db252192725c5118304b1a0..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/plugin.go +++ /dev/null @@ -1,16 +0,0 @@ -package webinterface - -import ( - "github.com/iotaledger/goshimmer/plugins/analysis/webinterface/httpserver" - "github.com/iotaledger/goshimmer/plugins/analysis/webinterface/recordedevents" - "github.com/iotaledger/hive.go/node" -) - -func Configure(plugin *node.Plugin) { - httpserver.Configure() - recordedevents.Configure(plugin) -} - -func Run(plugin *node.Plugin) { - httpserver.Run() -} diff --git a/plugins/analysis/webinterface/recordedevents/recorded_events.go b/plugins/analysis/webinterface/recordedevents/recorded_events.go deleted file mode 100644 index 2e2a9a724b3524f9ce017e6a0fa5e49e40d899ae..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/recordedevents/recorded_events.go +++ /dev/null @@ -1,115 +0,0 @@ -package recordedevents - -import ( - "sync" - - "github.com/iotaledger/goshimmer/plugins/analysis/server" - "github.com/iotaledger/goshimmer/plugins/analysis/webinterface/types" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/node" -) - -var nodes = make(map[string]bool) -var links = make(map[string]map[string]bool) - -var lock sync.Mutex - -func Configure(plugin *node.Plugin) { - server.Events.AddNode.Attach(events.NewClosure(func(nodeId string) { - plugin.Node.Logger.Debugw("AddNode", "nodeID", nodeId) - lock.Lock() - defer lock.Unlock() - - if _, exists := nodes[nodeId]; !exists { - nodes[nodeId] = false - } - })) - - server.Events.RemoveNode.Attach(events.NewClosure(func(nodeId string) { - plugin.Node.Logger.Debugw("RemoveNode", "nodeID", nodeId) - lock.Lock() - defer lock.Unlock() - - delete(nodes, nodeId) - })) - - server.Events.NodeOnline.Attach(events.NewClosure(func(nodeId string) { - plugin.Node.Logger.Debugw("NodeOnline", "nodeID", nodeId) - lock.Lock() - defer lock.Unlock() - - nodes[nodeId] = true - })) - - server.Events.NodeOffline.Attach(events.NewClosure(func(nodeId string) { - plugin.Node.Logger.Debugw("NodeOffline", "nodeID", nodeId) - lock.Lock() - defer lock.Unlock() - - nodes[nodeId] = false - })) - - server.Events.ConnectNodes.Attach(events.NewClosure(func(sourceId string, targetId string) { - plugin.Node.Logger.Debugw("ConnectNodes", "sourceID", sourceId, "targetId", targetId) - lock.Lock() - defer lock.Unlock() - - connectionMap, connectionMapExists := links[sourceId] - if !connectionMapExists { - connectionMap = make(map[string]bool) - - links[sourceId] = connectionMap - } - connectionMap[targetId] = true - })) - - server.Events.DisconnectNodes.Attach(events.NewClosure(func(sourceId string, targetId string) { - plugin.Node.Logger.Debugw("DisconnectNodes", "sourceID", sourceId, "targetId", targetId) - lock.Lock() - defer lock.Unlock() - - connectionMap, connectionMapExists := links[sourceId] - if connectionMapExists { - delete(connectionMap, targetId) - } - })) -} - -func getEventsToReplay() (map[string]bool, map[string]map[string]bool) { - lock.Lock() - defer lock.Unlock() - - copiedNodes := make(map[string]bool) - for nodeId, online := range nodes { - copiedNodes[nodeId] = online - } - - copiedLinks := make(map[string]map[string]bool) - for sourceId, targetMap := range links { - copiedLinks[sourceId] = make(map[string]bool) - for targetId := range targetMap { - copiedLinks[sourceId][targetId] = true - } - } - - return copiedNodes, copiedLinks -} - -func Replay(handlers *types.EventHandlers) { - copiedNodes, copiedLinks := getEventsToReplay() - - for nodeId, online := range copiedNodes { - handlers.AddNode(nodeId) - if online { - handlers.NodeOnline(nodeId) - } else { - handlers.NodeOffline(nodeId) - } - } - - for sourceId, targetMap := range copiedLinks { - for targetId := range targetMap { - handlers.ConnectNodes(sourceId, targetId) - } - } -} diff --git a/plugins/analysis/webinterface/types/types.go b/plugins/analysis/webinterface/types/types.go deleted file mode 100644 index 475da9ad04a9b8b575313dea63f66d1108a2389f..0000000000000000000000000000000000000000 --- a/plugins/analysis/webinterface/types/types.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -type EventHandlers = struct { - AddNode func(nodeId string) - RemoveNode func(nodeId string) - ConnectNodes func(sourceId string, targetId string) - DisconnectNodes func(sourceId string, targetId string) - NodeOnline func(nodeId string) - NodeOffline func(nodeId string) -} - -type EventHandlersConsumer = func(handler *EventHandlers) diff --git a/plugins/autopeering/autopeering.go b/plugins/autopeering/autopeering.go index 191d847156a40c63aebe74b487fc9b9df6c28901..4b3707cc7acb3e7034f17e1c103256ffcc8ce7f0 100644 --- a/plugins/autopeering/autopeering.go +++ b/plugins/autopeering/autopeering.go @@ -1,142 +1,179 @@ package autopeering import ( - "encoding/base64" "errors" "fmt" + "hash/fnv" "net" + "strconv" "strings" + "sync" - "github.com/iotaledger/goshimmer/packages/netutil" - "github.com/iotaledger/goshimmer/packages/parameter" "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/goshimmer/plugins/cli" - "github.com/iotaledger/goshimmer/plugins/gossip" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/hive.go/autopeering/discover" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/peer/service" "github.com/iotaledger/hive.go/autopeering/selection" "github.com/iotaledger/hive.go/autopeering/server" - "github.com/iotaledger/hive.go/autopeering/transport" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" + "github.com/mr-tron/base58" +) + +// autopeering constants +const ( + ProtocolVersion = 0 // update on protocol changes + NetworkVersion = 2 // update on network changes ) var ( - // Discovery is the peer discovery protocol. - Discovery *discover.Protocol - // Selection is the peer selection protocol. - Selection *selection.Protocol + // ErrParsingMasterNode is returned for an invalid master node. + ErrParsingMasterNode = errors.New("cannot parse master node") - ErrParsingMasterNode = errors.New("can't parse master node") + // Conn contains the network connection. + Conn *NetConnMetric +) - log *logger.Logger +var ( + // the peer discovery protocol + peerDisc *discover.Protocol + peerDiscOnce sync.Once + + // the peer selection protocol + peerSel *selection.Protocol + peerSelOnce sync.Once + + // block until the peering server has been started + srvBarrier = struct { + once sync.Once + c chan *server.Server + }{c: make(chan *server.Server, 1)} ) -func configureAP() { +// Discovery returns the peer discovery instance. +func Discovery() *discover.Protocol { + peerDiscOnce.Do(createPeerDisc) + return peerDisc +} + +// Selection returns the neighbor selection instance. +func Selection() *selection.Protocol { + peerSelOnce.Do(createPeerSel) + return peerSel +} + +// BindAddress returns the string form of the autopeering bind address. +func BindAddress() string { + peering := local.GetInstance().Services().Get(service.PeeringKey) + host := config.Node().GetString(local.CfgBind) + port := strconv.Itoa(peering.Port()) + return net.JoinHostPort(host, port) +} + +// StartSelection starts the neighbor selection process. +// It blocks until the peer discovery has been started. Multiple calls of StartSelection are ignored. +func StartSelection() { + srvBarrier.once.Do(func() { + srv := <-srvBarrier.c + close(srvBarrier.c) + + Selection().Start(srv) + }) +} + +func createPeerDisc() { + // assure that the logger is available + log := logger.NewLogger(PluginName).Named("disc") + masterPeers, err := parseEntryNodes() if err != nil { log.Errorf("Invalid entry nodes; ignoring: %v", err) } log.Debugf("Master peers: %v", masterPeers) - Discovery = discover.New(local.GetInstance(), discover.Config{ - Log: log.Named("disc"), - MasterPeers: masterPeers, - }) + peerDisc = discover.New(local.GetInstance(), ProtocolVersion, NetworkVersion, + discover.Logger(log), + discover.MasterPeers(masterPeers), + ) +} - // enable peer selection only when gossip is enabled - if !node.IsSkipped(gossip.PLUGIN) { - Selection = selection.New(local.GetInstance(), Discovery, selection.Config{ - Log: log.Named("sel"), - NeighborValidator: selection.ValidatorFunc(isValidNeighbor), - }) - } +func createPeerSel() { + // assure that the logger is available + log := logger.NewLogger(PluginName).Named("sel") + + peerSel = selection.New(local.GetInstance(), Discovery(), + selection.Logger(log), + selection.NeighborValidator(selection.ValidatorFunc(isValidNeighbor)), + ) } // isValidNeighbor checks whether a peer is a valid neighbor. func isValidNeighbor(p *peer.Peer) bool { // gossip must be supported - gossipAddr := p.Services().Get(service.GossipKey) - if gossipAddr == nil { + gossipService := p.Services().Get(service.GossipKey) + if gossipService == nil { return false } - // the host for the gossip and peering service must be identical - gossipHost, _, err := net.SplitHostPort(gossipAddr.String()) - if err != nil { - return false - } - peeringAddr := p.Services().Get(service.PeeringKey) - peeringHost, _, err := net.SplitHostPort(peeringAddr.String()) - if err != nil { + // gossip service must be valid + if gossipService.Network() != "tcp" || gossipService.Port() < 0 || gossipService.Port() > 65535 { return false } - return gossipHost == peeringHost + return true } func start(shutdownSignal <-chan struct{}) { - defer log.Info("Stopping " + name + " ... done") + defer log.Info("Stopping " + PluginName + " ... done") lPeer := local.GetInstance() - // use the port of the peering service - peeringAddr := lPeer.Services().Get(service.PeeringKey) - _, peeringPort, err := net.SplitHostPort(peeringAddr.String()) - if err != nil { - panic(err) - } + peering := lPeer.Services().Get(service.PeeringKey) + // resolve the bind address - address := net.JoinHostPort(parameter.NodeConfig.GetString(local.CFG_BIND), peeringPort) - localAddr, err := net.ResolveUDPAddr(peeringAddr.Network(), address) + localAddr, err := net.ResolveUDPAddr(peering.Network(), BindAddress()) if err != nil { - log.Fatalf("Error resolving %s: %v", local.CFG_BIND, err) + log.Fatalf("Error resolving %s: %v", local.CfgBind, err) } - // check that discovery is working and the port is open - log.Info("Testing service ...") - checkConnection(localAddr, &lPeer.Peer) - log.Info("Testing service ... done") - - conn, err := net.ListenUDP(peeringAddr.Network(), localAddr) + conn, err := net.ListenUDP(peering.Network(), localAddr) if err != nil { log.Fatalf("Error listening: %v", err) } defer conn.Close() - // use the UDP connection for transport - trans := transport.Conn(conn, func(network, address string) (net.Addr, error) { return net.ResolveUDPAddr(network, address) }) - defer trans.Close() + Conn = &NetConnMetric{UDPConn: conn} - handlers := []server.Handler{Discovery} - if Selection != nil { - handlers = append(handlers, Selection) - } - - // start a server doing discovery and peering - srv := server.Serve(lPeer, trans, log.Named("srv"), handlers...) + // start a server doing peerDisc and peering + srv := server.Serve(lPeer, Conn, log.Named("srv"), Discovery(), Selection()) defer srv.Close() - // start the discovery on that connection - Discovery.Start(srv) - defer Discovery.Close() - - if Selection != nil { - // start the peering on that connection - Selection.Start(srv) - defer Selection.Close() - } + // start the peer discovery on that connection + Discovery().Start(srv) + srvBarrier.c <- srv - log.Infof("%s started: ID=%s Address=%s/%s", name, lPeer.ID(), peeringAddr.String(), peeringAddr.Network()) + log.Infof("%s started: ID=%s Address=%s/%s", PluginName, lPeer.ID(), localAddr.String(), localAddr.Network()) <-shutdownSignal - log.Infof("Stopping %s ...", name) + log.Infof("Stopping %s ...", PluginName) - count := lPeer.Database().PersistSeeds() - log.Infof("%d peers persisted as seeds", count) + Discovery().Close() + Selection().Close() + + lPeer.Database().Close() +} + +func hash32(b []byte) uint32 { + hash := fnv.New32() + _, err := hash.Write(b) + if err != nil { + panic(err) + } + return hash.Sum32() } func parseEntryNodes() (result []*peer.Peer, err error) { - for _, entryNodeDefinition := range parameter.NodeConfig.GetStringSlice(CFG_ENTRY_NODES) { + for _, entryNodeDefinition := range config.Node().GetStringSlice(CfgEntryNodes) { if entryNodeDefinition == "" { continue } @@ -145,32 +182,24 @@ func parseEntryNodes() (result []*peer.Peer, err error) { if len(parts) != 2 { return nil, fmt.Errorf("%w: master node parts must be 2, is %d", ErrParsingMasterNode, len(parts)) } - pubKey, err := base64.StdEncoding.DecodeString(parts[0]) + pubKey, err := base58.Decode(parts[0]) if err != nil { - return nil, fmt.Errorf("%w: can't decode public key: %s", ErrParsingMasterNode, err) + return nil, fmt.Errorf("%w: invalid public key: %s", ErrParsingMasterNode, err) + } + addr, err := net.ResolveUDPAddr("udp", parts[1]) + if err != nil { + return nil, fmt.Errorf("%w: host cannot be resolved: %s", ErrParsingMasterNode, err) + } + publicKey, _, err := ed25519.PublicKeyFromBytes(pubKey) + if err != nil { + return nil, err } services := service.New() - services.Update(service.PeeringKey, "udp", parts[1]) + services.Update(service.PeeringKey, addr.Network(), addr.Port) - result = append(result, peer.NewPeer(pubKey, services)) + result = append(result, peer.NewPeer(identity.New(publicKey), addr.IP, services)) } return result, nil } - -func checkConnection(localAddr *net.UDPAddr, self *peer.Peer) { - peering := self.Services().Get(service.PeeringKey) - remoteAddr, err := net.ResolveUDPAddr(peering.Network(), peering.String()) - if err != nil { - panic(err) - } - - // do not check the address as a NAT may change them for local connections - err = netutil.CheckUDP(localAddr, remoteAddr, false, true) - if err != nil { - log.Errorf("Error testing service: %s", err) - log.Panicf("Please check that %s is publicly reachable at %s/%s", - cli.AppName, peering.String(), peering.Network()) - } -} diff --git a/plugins/autopeering/local/local.go b/plugins/autopeering/local/local.go index c9cb2efae43b935f71681cb39e97672297f4e259..d3fbdf923cad36b8e5ca204ab56a90f42dd24d94 100644 --- a/plugins/autopeering/local/local.go +++ b/plugins/autopeering/local/local.go @@ -1,19 +1,20 @@ package local import ( - "crypto/ed25519" "encoding/base64" + "fmt" "net" - "strconv" "strings" "sync" - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/netutil" - "github.com/iotaledger/goshimmer/packages/parameter" + "github.com/iotaledger/goshimmer/packages/database/prefix" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/database" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/peer/service" + "github.com/iotaledger/hive.go/crypto/ed25519" "github.com/iotaledger/hive.go/logger" + "github.com/mr-tron/base58" ) var ( @@ -24,57 +25,61 @@ var ( func configureLocal() *peer.Local { log := logger.NewLogger("Local") - var externalIP net.IP - if str := parameter.NodeConfig.GetString(CFG_EXTERNAL); strings.ToLower(str) == "auto" { - log.Info("Querying external IP ...") - ip, err := netutil.GetPublicIP(false) - if err != nil { - log.Fatalf("Error querying external IP: %s", err) - } - log.Infof("External IP queried: address=%s", ip.String()) - externalIP = ip + var peeringIP net.IP + if str := config.Node().GetString(CfgExternal); strings.ToLower(str) == "auto" { + // let the autopeering discover the IP + peeringIP = net.IPv4zero } else { - externalIP = net.ParseIP(str) - if externalIP == nil { - log.Fatalf("Invalid IP address (%s): %s", CFG_EXTERNAL, str) + peeringIP = net.ParseIP(str) + if peeringIP == nil { + log.Fatalf("Invalid IP address (%s): %s", CfgExternal, str) + } + if !peeringIP.IsGlobalUnicast() { + log.Warnf("IP is not a global unicast address: %s", peeringIP.String()) } - } - if !externalIP.IsGlobalUnicast() { - log.Warnf("IP is not a global unicast address: %s", externalIP.String()) } - peeringPort := strconv.Itoa(parameter.NodeConfig.GetInt(CFG_PORT)) + peeringPort := config.Node().GetInt(CfgPort) + if 0 > peeringPort || peeringPort > 65535 { + log.Fatalf("Invalid port number (%s): %d", CfgPort, peeringPort) + } // announce the peering service services := service.New() - services.Update(service.PeeringKey, "udp", net.JoinHostPort(externalIP.String(), peeringPort)) - - // the private key seed of the current local can be returned the following way: - // key, _ := db.LocalPrivateKey() - // fmt.Println(base64.StdEncoding.EncodeToString(ed25519.PrivateKey(key).Seed())) + services.Update(service.PeeringKey, "udp", peeringPort) // set the private key from the seed provided in the config var seed [][]byte - if str := parameter.NodeConfig.GetString(CFG_SEED); str != "" { - bytes, err := base64.StdEncoding.DecodeString(str) + if str := config.Node().GetString(CfgSeed); str != "" { + var bytes []byte + var err error + + if strings.HasPrefix(str, "base58:") { + bytes, err = base58.Decode(str[7:]) + } else if strings.HasPrefix(str, "base64:") { + bytes, err = base64.StdEncoding.DecodeString(str[7:]) + } else { + err = fmt.Errorf("neither base58 nor base64 prefix provided") + } + if err != nil { - log.Fatalf("Invalid %s: %s", CFG_SEED, err) + log.Fatalf("Invalid %s: %s", CfgSeed, err) } if l := len(bytes); l != ed25519.SeedSize { - log.Fatalf("Invalid %s length: %d, need %d", CFG_SEED, l, ed25519.SeedSize) + log.Fatalf("Invalid %s length: %d, need %d", CfgSeed, l, ed25519.SeedSize) } seed = append(seed, bytes) } - badgerDB, err := database.Get(database.DBPrefixAutoPeering, database.GetBadgerInstance()) - if err != nil { - log.Fatalf("Error loading DB: %s", err) - } - peerDB, err := peer.NewDB(badgerDB) + peerDB, err := peer.NewDB(database.StoreRealm([]byte{prefix.DBPrefixAutoPeering})) if err != nil { log.Fatalf("Error creating peer DB: %s", err) } - local, err := peer.NewLocal(services, peerDB, seed...) + // the private key seed of the current local can be returned the following way: + // key, _ := peerDB.LocalPrivateKey() + // fmt.Printf("Seed: base58:%s\n", key.Seed().String()) + + local, err := peer.NewLocal(peeringIP, services, peerDB, seed...) if err != nil { log.Fatalf("Error creating local: %s", err) } @@ -83,6 +88,7 @@ func configureLocal() *peer.Local { return local } +// GetInstance returns the instance of the local peer. func GetInstance() *peer.Local { once.Do(func() { instance = configureLocal() }) return instance diff --git a/plugins/autopeering/local/parameters.go b/plugins/autopeering/local/parameters.go index 9ffa15c81fe7fbc745b3c85723dda0af8a32a20a..6fa316d72d93528d134f3d72d9e9e2f7c897727c 100644 --- a/plugins/autopeering/local/parameters.go +++ b/plugins/autopeering/local/parameters.go @@ -5,15 +5,19 @@ import ( ) const ( - CFG_BIND = "network.bindAddress" - CFG_EXTERNAL = "network.externalAddress" - CFG_PORT = "autopeering.port" - CFG_SEED = "autopeering.seed" + // CfgBind defines the config flag of the network bind address. + CfgBind = "network.bindAddress" + // CfgExternal defines the config flag of the network external address. + CfgExternal = "network.externalAddress" + // CfgPort defines the config flag of the autopeering port. + CfgPort = "autopeering.port" + // CfgSeed defines the config flag of the autopeering private key seed. + CfgSeed = "autopeering.seed" ) func init() { - flag.String(CFG_BIND, "0.0.0.0", "bind address for global services such as autopeering and gossip") - flag.String(CFG_EXTERNAL, "auto", "external IP address under which the node is reachable; or 'auto' to determine it automatically") - flag.Int(CFG_PORT, 14626, "UDP port for incoming peering requests") - flag.BytesBase64(CFG_SEED, nil, "private key seed used to derive the node identity; optional Base64 encoded 256-bit string") + flag.String(CfgBind, "0.0.0.0", "bind address for global services such as autopeering and gossip") + flag.String(CfgExternal, "auto", "external IP address under which the node is reachable; or 'auto' to determine it automatically") + flag.Int(CfgPort, 14626, "UDP port for incoming peering requests") + flag.String(CfgSeed, "", "private key seed used to derive the node identity; optional base58 or base64 encoded 256-bit string. Prefix with 'base58:' or 'base64', respectively") } diff --git a/plugins/autopeering/netconnmetric.go b/plugins/autopeering/netconnmetric.go new file mode 100644 index 0000000000000000000000000000000000000000..c31d5b349f09c47d007924b9b2135ff844356226 --- /dev/null +++ b/plugins/autopeering/netconnmetric.go @@ -0,0 +1,38 @@ +package autopeering + +import ( + "net" + + "go.uber.org/atomic" +) + +// NetConnMetric is a wrapper of a UDPConn that keeps track of RX and TX bytes. +type NetConnMetric struct { + *net.UDPConn + rxBytes atomic.Uint64 + txBytes atomic.Uint64 +} + +// RXBytes returns the RX bytes. +func (nc *NetConnMetric) RXBytes() uint64 { + return nc.rxBytes.Load() +} + +// TXBytes returns the TX bytes. +func (nc *NetConnMetric) TXBytes() uint64 { + return nc.txBytes.Load() +} + +// ReadFromUDP acts like ReadFrom but returns a UDPAddr. +func (nc *NetConnMetric) ReadFromUDP(b []byte) (int, *net.UDPAddr, error) { + n, addr, err := nc.UDPConn.ReadFromUDP(b) + nc.rxBytes.Add(uint64(n)) + return n, addr, err +} + +// WriteToUDP acts like WriteTo but takes a UDPAddr. +func (nc *NetConnMetric) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) { + n, err := nc.UDPConn.WriteToUDP(b, addr) + nc.txBytes.Add(uint64(n)) + return n, err +} diff --git a/plugins/autopeering/parameters.go b/plugins/autopeering/parameters.go index 138b8d56e451c9024fd85c1b4296965337061c4d..76ec6a7f8a60871b776fe56ac5bbd5e7e47233d2 100644 --- a/plugins/autopeering/parameters.go +++ b/plugins/autopeering/parameters.go @@ -5,9 +5,10 @@ import ( ) const ( - CFG_ENTRY_NODES = "autopeering.entryNodes" + // CfgEntryNodes defines the config flag of the entry nodes. + CfgEntryNodes = "autopeering.entryNodes" ) func init() { - flag.StringSlice(CFG_ENTRY_NODES, []string{"V8LYtWWcPYYDTTXLeIEFjJEuWlsjDiI0+Pq/Cx9ai6g=@116.202.49.178:14626"}, "list of trusted entry nodes for auto peering") + flag.StringSlice(CfgEntryNodes, []string{"2PV5487xMw5rasGBXXWeqSi4hLz7r19YBt8Y1TGAsQbj@ressims.iota.cafe:15626"}, "list of trusted entry nodes for auto peering") } diff --git a/plugins/autopeering/plugin.go b/plugins/autopeering/plugin.go index c8e5003ad59db51b8beb0af41d2698a22b580f6f..40c31a2bb4af6dbe8c024832348bfcbdf72ec355 100644 --- a/plugins/autopeering/plugin.go +++ b/plugins/autopeering/plugin.go @@ -1,12 +1,11 @@ package autopeering import ( + "sync" "time" - "github.com/iotaledger/goshimmer/packages/gossip" "github.com/iotaledger/goshimmer/packages/shutdown" "github.com/iotaledger/hive.go/autopeering/discover" - "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/selection" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/events" @@ -14,53 +13,65 @@ import ( "github.com/iotaledger/hive.go/node" ) -const name = "Autopeering" // name of the plugin +// PluginName is the name of the autopeering plugin. +const PluginName = "Autopeering" -var PLUGIN = node.NewPlugin(name, node.Enabled, configure, run) +var ( + // plugin is the plugin instance of the autopeering plugin. + plugin *node.Plugin + once sync.Once + + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} func configure(*node.Plugin) { - log = logger.NewLogger(name) + log = logger.NewLogger(PluginName) configureEvents() - configureAP() } func run(*node.Plugin) { - if err := daemon.BackgroundWorker(name, start, shutdown.ShutdownPriorityAutopeering); err != nil { - log.Errorf("Failed to start as daemon: %s", err) + if err := daemon.BackgroundWorker(PluginName, start, shutdown.PriorityAutopeering); err != nil { + log.Panicf("Failed to start as daemon: %s", err) } } func configureEvents() { - // notify the selection when a connection is closed or failed. - gossip.Events.ConnectionFailed.Attach(events.NewClosure(func(p *peer.Peer, _ error) { - Selection.RemoveNeighbor(p.ID()) - })) - gossip.Events.NeighborRemoved.Attach(events.NewClosure(func(p *peer.Peer) { - Selection.RemoveNeighbor(p.ID()) - })) + // assure that the autopeering is instantiated + peerDisc := Discovery() + peerSel := Selection() - discover.Events.PeerDiscovered.Attach(events.NewClosure(func(ev *discover.DiscoveredEvent) { + // log the peer discovery events + peerDisc.Events().PeerDiscovered.Attach(events.NewClosure(func(ev *discover.DiscoveredEvent) { log.Infof("Discovered: %s / %s", ev.Peer.Address(), ev.Peer.ID()) })) - discover.Events.PeerDeleted.Attach(events.NewClosure(func(ev *discover.DeletedEvent) { + peerDisc.Events().PeerDeleted.Attach(events.NewClosure(func(ev *discover.DeletedEvent) { log.Infof("Removed offline: %s / %s", ev.Peer.Address(), ev.Peer.ID()) })) - selection.Events.SaltUpdated.Attach(events.NewClosure(func(ev *selection.SaltUpdatedEvent) { + // log the peer selection events + peerSel.Events().SaltUpdated.Attach(events.NewClosure(func(ev *selection.SaltUpdatedEvent) { log.Infof("Salt updated; expires=%s", ev.Public.GetExpiration().Format(time.RFC822)) })) - selection.Events.OutgoingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { + peerSel.Events().OutgoingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { if ev.Status { log.Infof("Peering chosen: %s / %s", ev.Peer.Address(), ev.Peer.ID()) } })) - selection.Events.IncomingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { + peerSel.Events().IncomingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { if ev.Status { log.Infof("Peering accepted: %s / %s", ev.Peer.Address(), ev.Peer.ID()) } })) - selection.Events.Dropped.Attach(events.NewClosure(func(ev *selection.DroppedEvent) { + peerSel.Events().Dropped.Attach(events.NewClosure(func(ev *selection.DroppedEvent) { log.Infof("Peering dropped: %s", ev.DroppedID) })) } diff --git a/plugins/banner/plugin.go b/plugins/banner/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..5603df69d13a2c1fadc32ce202ac620178fb142a --- /dev/null +++ b/plugins/banner/plugin.go @@ -0,0 +1,51 @@ +package banner + +import ( + "fmt" + "sync" + + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the banner plugin. +const PluginName = "Banner" + +var ( + // plugin is the plugin instance of the banner plugin. + plugin *node.Plugin + once sync.Once +) + +const ( + // AppVersion version number + AppVersion = "v0.2.0" + + // AppName app code name + AppName = "GoShimmer" +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) + }) + return plugin +} + +func configure(ctx *node.Plugin) { + fmt.Printf(` + _____ ____ _____ _ _ _____ __ __ __ __ ______ _____ + / ____|/ __ \ / ____| | | |_ _| \/ | \/ | ____| __ \ + | | __| | | | (___ | |__| | | | | \ / | \ / | |__ | |__) | + | | |_ | | | |\___ \| __ | | | | |\/| | |\/| | __| | _ / + | |__| | |__| |____) | | | |_| |_| | | | | | | |____| | \ \ + \_____|\____/|_____/|_| |_|_____|_| |_|_| |_|______|_| \_\ + %s +`, AppVersion) + fmt.Println() + + ctx.Node.Logger.Infof("GoShimmer version %s ...", AppVersion) + ctx.Node.Logger.Info("Loading plugins ...") +} + +func run(ctx *node.Plugin) {} diff --git a/plugins/bootstrap/plugin.go b/plugins/bootstrap/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..1fc856b4087d2656b58271148b0cd8ec1edb9228 --- /dev/null +++ b/plugins/bootstrap/plugin.go @@ -0,0 +1,88 @@ +package bootstrap + +import ( + goSync "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/spammer" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/iotaledger/goshimmer/plugins/sync" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + flag "github.com/spf13/pflag" +) + +const ( + // PluginName is the plugin name of the bootstrap plugin. + PluginName = "Bootstrap" + // CfgBootstrapInitialIssuanceTimePeriodSec defines the initial time period of how long the node should be + // issuing messages when started in bootstrapping mode. If the value is set to -1, the issuance is continuous. + CfgBootstrapInitialIssuanceTimePeriodSec = "bootstrap.initialIssuance.timePeriodSec" + // CfgBootstrapTimeUnit defines the time unit (in seconds) of the issuance rate (e.g., 3 messages per 12 seconds). + CfgBootstrapTimeUnit = "bootstrap.timeUnit" + // the messages per period to issue when in bootstrapping mode. + initialIssuanceRate = 1 + // the value which determines a continuous issuance of messages from the bootstrap plugin. + continuousIssuance = -1 +) + +func init() { + flag.Int(CfgBootstrapInitialIssuanceTimePeriodSec, -1, "the initial time period of how long the node should be issuing messages when started in bootstrapping mode. "+ + "if the value is set to -1, the issuance is continuous.") + flag.Int(CfgBootstrapTimeUnit, 5, "the time unit (in seconds) of the issuance rate (e.g., 1 messages per 5 seconds).") +} + +var ( + // plugin is the plugin instance of the bootstrap plugin. + plugin *node.Plugin + once goSync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) + }) + return plugin +} + +func configure(_ *node.Plugin) { + log = logger.NewLogger(PluginName) + // we're auto. synced if we start in bootstrapping mode + sync.OverwriteSyncedState(true) + log.Infof("starting node in bootstrapping mode") +} + +func run(_ *node.Plugin) { + + messageSpammer := spammer.New(issuer.IssuePayload) + issuancePeriodSec := config.Node().GetInt(CfgBootstrapInitialIssuanceTimePeriodSec) + timeUnit := config.Node().GetInt(CfgBootstrapTimeUnit) + if timeUnit <= 0 { + log.Panicf("Invalid Bootsrap time unit: %d seconds", timeUnit) + } + issuancePeriod := time.Duration(issuancePeriodSec) * time.Second + + // issue messages on top of the genesis + if err := daemon.BackgroundWorker("Bootstrapping-Issuer", func(shutdownSignal <-chan struct{}) { + messageSpammer.Start(initialIssuanceRate, time.Duration(timeUnit)*time.Second) + defer messageSpammer.Shutdown() + // don't stop issuing messages if in continuous mode + if issuancePeriodSec == continuousIssuance { + log.Info("continuously issuing bootstrapping messages") + <-shutdownSignal + return + } + log.Infof("issuing bootstrapping messages for %d seconds", issuancePeriodSec) + select { + case <-time.After(issuancePeriod): + case <-shutdownSignal: + } + }, shutdown.PriorityBootstrap); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} diff --git a/plugins/bundleprocessor/bundleprocessor.go b/plugins/bundleprocessor/bundleprocessor.go deleted file mode 100644 index 6085e2a97dfe54457ee630c7064f51a6d03c9f7f..0000000000000000000000000000000000000000 --- a/plugins/bundleprocessor/bundleprocessor.go +++ /dev/null @@ -1,101 +0,0 @@ -package bundleprocessor - -import ( - "fmt" - "runtime" - - "github.com/iotaledger/goshimmer/packages/model/bundle" - "github.com/iotaledger/goshimmer/packages/model/transactionmetadata" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/hive.go/workerpool" - "github.com/iotaledger/iota.go/trinary" -) - -var workerPool = workerpool.New(func(task workerpool.Task) { - if err := ProcessSolidBundleHead(task.Param(0).(*value_transaction.ValueTransaction)); err != nil { - Events.Error.Trigger(err) - } - - task.Return(nil) -}, workerpool.WorkerCount(WORKER_COUNT), workerpool.QueueSize(2*WORKER_COUNT)) - -var WORKER_COUNT = runtime.NumCPU() - -func ProcessSolidBundleHead(headTransaction *value_transaction.ValueTransaction) error { - // only process the bundle if we didn't process it, yet - _, err := tangle.GetBundle(headTransaction.GetHash(), func(headTransactionHash trinary.Trytes) (*bundle.Bundle, error) { - // abort if bundle syntax is wrong - if !headTransaction.IsHead() { - return nil, fmt.Errorf("%w: transaction needs to be the head of the bundle", ErrProcessBundleFailed) - } - - // initialize event variables - newBundle := bundle.New(headTransactionHash) - bundleTransactions := make([]*value_transaction.ValueTransaction, 0) - - // iterate through trunk transactions until we reach the tail - currentTransaction := headTransaction - for { - // abort if we reached a previous head - if currentTransaction.IsHead() && currentTransaction != headTransaction { - newBundle.SetTransactionHashes(mapTransactionsToTransactionHashes(bundleTransactions)) - - Events.InvalidBundle.Trigger(newBundle, bundleTransactions) - return nil, fmt.Errorf("%w: missing bundle tail", ErrProcessBundleFailed) - } - - // update bundle transactions - bundleTransactions = append(bundleTransactions, currentTransaction) - - // retrieve & update metadata - currentTransactionMetadata, err := tangle.GetTransactionMetadata(currentTransaction.GetHash(), transactionmetadata.New) - if err != nil { - return nil, fmt.Errorf("%w: failed to retrieve transaction metadata: %s", ErrProcessBundleFailed, err) - } - currentTransactionMetadata.SetBundleHeadHash(headTransactionHash) - - // update value bundle flag - if !newBundle.IsValueBundle() && currentTransaction.GetValue() < 0 { - newBundle.SetValueBundle(true) - } - - // if we are done -> trigger events - if currentTransaction.IsTail() { - newBundle.SetTransactionHashes(mapTransactionsToTransactionHashes(bundleTransactions)) - - if newBundle.IsValueBundle() { - valueBundleProcessorWorkerPool.Submit(newBundle, bundleTransactions) - - return newBundle, nil - } - - Events.BundleSolid.Trigger(newBundle, bundleTransactions) - - return newBundle, nil - } - - // try to iterate to next turn - if nextTransaction, err := tangle.GetTransaction(currentTransaction.GetTrunkTransactionHash()); err != nil { - return nil, fmt.Errorf("%w: failed to retrieve trunk while processing bundle: %s", ErrProcessBundleFailed, err) - } else if nextTransaction == nil { - err := fmt.Errorf("%w: failed to retrieve trunk while processing bundle: missing trunk transaction %s\n", ErrProcessBundleFailed, currentTransaction.GetTrunkTransactionHash()) - fmt.Println(err) - return nil, err - } else { - currentTransaction = nextTransaction - } - } - }) - - return err -} - -func mapTransactionsToTransactionHashes(transactions []*value_transaction.ValueTransaction) (result []trinary.Trytes) { - result = make([]trinary.Trytes, len(transactions)) - for k, v := range transactions { - result[k] = v.GetHash() - } - - return -} diff --git a/plugins/bundleprocessor/bundleprocessor_test.go b/plugins/bundleprocessor/bundleprocessor_test.go deleted file mode 100644 index e7b90366bd676bf6a0ba3d284ba6e241a368b3f9..0000000000000000000000000000000000000000 --- a/plugins/bundleprocessor/bundleprocessor_test.go +++ /dev/null @@ -1,143 +0,0 @@ -package bundleprocessor - -import ( - "io/ioutil" - "os" - "sync" - "testing" - - "github.com/iotaledger/goshimmer/packages/client" - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/model/bundle" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/goshimmer/plugins/tipselection" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/consts" - "github.com/magiconair/properties/assert" - "github.com/spf13/viper" - "github.com/stretchr/testify/require" -) - -var seed = client.NewSeed("YFHQWAUPCXC9S9DSHP9NDF9RLNPMZVCMSJKUKQP9SWUSUCPRQXCMDVDVZ9SHHESHIQNCXWBJF9UJSWE9Z", consts.SecurityLevelMedium) - -func init() { - err := parameter.LoadDefaultConfig(false) - if err != nil { - log.Fatalf("Failed to initialize config: %s", err) - } - logger.InitGlobalLogger(&viper.Viper{}) -} - -func BenchmarkValidateSignatures(b *testing.B) { - bundleFactory := client.NewBundleFactory() - bundleFactory.AddInput(seed.GetAddress(0), -400) - bundleFactory.AddOutput(seed.GetAddress(1), 400, "Testmessage") - bundleFactory.AddOutput(client.NewAddress("SJKUKQP9SWUSUCPRQXCMDVDVZ9SHHESHIQNCXWBJF9UJSWE9ZYFHQWAUPCXC9S9DSHP9NDF9RLNPMZVCM"), 400, "Testmessage") - - generatedBundle := bundleFactory.GenerateBundle(tipselection.GetRandomTip(), tipselection.GetRandomTip()) - - b.ResetTimer() - - var wg sync.WaitGroup - - for i := 0; i < b.N; i++ { - wg.Add(1) - - go func() { - ValidateSignatures(generatedBundle.GetEssenceHash(), generatedBundle.GetTransactions()) - - wg.Done() - }() - } - - wg.Wait() -} - -func TestValidateSignatures(t *testing.T) { - bundleFactory := client.NewBundleFactory() - bundleFactory.AddInput(seed.GetAddress(0), -400) - bundleFactory.AddOutput(seed.GetAddress(1), 400, "Testmessage") - bundleFactory.AddOutput(client.NewAddress("SJKUKQP9SWUSUCPRQXCMDVDVZ9SHHESHIQNCXWBJF9UJSWE9ZYFHQWAUPCXC9S9DSHP9NDF9RLNPMZVCM"), 400, "Testmessage") - - generatedBundle := bundleFactory.GenerateBundle(tipselection.GetRandomTip(), tipselection.GetRandomTip()) - - successful, err := ValidateSignatures(generatedBundle.GetEssenceHash(), generatedBundle.GetTransactions()) - if err != nil { - t.Error(err) - } - assert.Equal(t, successful, true, "validation failed") -} - -func TestProcessSolidBundleHead(t *testing.T) { - dir, err := ioutil.TempDir("", t.Name()) - require.NoError(t, err) - defer os.Remove(dir) - // use the tempdir for the database - parameter.NodeConfig.Set(database.CFG_DIRECTORY, dir) - - // start a test node - node.Start(node.Plugins(tangle.PLUGIN, PLUGIN)) - defer node.Shutdown() - - t.Run("data", func(t *testing.T) { - bundleFactory := client.NewBundleFactory() - bundleFactory.AddOutput(seed.GetAddress(1), 400, "Testmessage") - bundleFactory.AddOutput(client.NewAddress("SJKUKQP9SWUSUCPRQXCMDVDVZ9SHHESHIQNCXWBJF9UJSWE9ZYFHQWAUPCXC9S9DSHP9NDF9RLNPMZVCM"), 400, "Testmessage") - - generatedBundle := bundleFactory.GenerateBundle(tipselection.GetRandomTip(), tipselection.GetRandomTip()) - for _, transaction := range generatedBundle.GetTransactions() { - tangle.StoreTransaction(transaction) - } - - var wg sync.WaitGroup - testResults := events.NewClosure(func(bundle *bundle.Bundle, transactions []*value_transaction.ValueTransaction) { - assert.Equal(t, bundle.GetHash(), generatedBundle.GetTransactions()[0].GetHash(), "invalid bundle hash") - assert.Equal(t, bundle.IsValueBundle(), false, "invalid value bundle status") - - wg.Done() - }) - Events.BundleSolid.Attach(testResults) - defer Events.BundleSolid.Detach(testResults) - - wg.Add(1) - if err := ProcessSolidBundleHead(generatedBundle.GetTransactions()[0]); err != nil { - t.Error(err) - } - - wg.Wait() - }) - - t.Run("value", func(t *testing.T) { - bundleFactory := client.NewBundleFactory() - bundleFactory.AddInput(seed.GetAddress(0), -400) - bundleFactory.AddOutput(seed.GetAddress(1), 400, "Testmessage") - bundleFactory.AddOutput(client.NewAddress("SJKUKQP9SWUSUCPRQXCMDVDVZ9SHHESHIQNCXWBJF9UJSWE9ZYFHQWAUPCXC9S9DSHP9NDF9RLNPMZVCM"), 400, "Testmessage") - - generatedBundle := bundleFactory.GenerateBundle(tipselection.GetRandomTip(), tipselection.GetRandomTip()) - for _, transaction := range generatedBundle.GetTransactions() { - tangle.StoreTransaction(transaction) - } - - var wg sync.WaitGroup - testResults := events.NewClosure(func(bundle *bundle.Bundle, transactions []*value_transaction.ValueTransaction) { - assert.Equal(t, bundle.GetHash(), generatedBundle.GetTransactions()[0].GetHash(), "invalid bundle hash") - assert.Equal(t, bundle.IsValueBundle(), true, "invalid value bundle status") - - wg.Done() - }) - - wg.Add(1) - Events.BundleSolid.Attach(testResults) - defer Events.BundleSolid.Detach(testResults) - - if err := ProcessSolidBundleHead(generatedBundle.GetTransactions()[0]); err != nil { - t.Error(err) - } - - wg.Wait() - }) -} diff --git a/plugins/bundleprocessor/errors.go b/plugins/bundleprocessor/errors.go deleted file mode 100644 index 7b488de18a26dca073df29488a5a00d0d54d9d21..0000000000000000000000000000000000000000 --- a/plugins/bundleprocessor/errors.go +++ /dev/null @@ -1,7 +0,0 @@ -package bundleprocessor - -import "errors" - -var ( - ErrProcessBundleFailed = errors.New("failed to process bundle") -) diff --git a/plugins/bundleprocessor/events.go b/plugins/bundleprocessor/events.go deleted file mode 100644 index 46eeaa5ca6ee676b4e28b692fad037d5cdf7be9d..0000000000000000000000000000000000000000 --- a/plugins/bundleprocessor/events.go +++ /dev/null @@ -1,27 +0,0 @@ -package bundleprocessor - -import ( - "github.com/iotaledger/goshimmer/packages/model/bundle" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/hive.go/events" -) - -var Events = pluginEvents{ - Error: events.NewEvent(errorCaller), - BundleSolid: events.NewEvent(bundleEventCaller), - InvalidBundle: events.NewEvent(bundleEventCaller), -} - -type pluginEvents struct { - Error *events.Event - BundleSolid *events.Event - InvalidBundle *events.Event -} - -func errorCaller(handler interface{}, params ...interface{}) { - handler.(func(error))(params[0].(error)) -} - -func bundleEventCaller(handler interface{}, params ...interface{}) { - handler.(func(*bundle.Bundle, []*value_transaction.ValueTransaction))(params[0].(*bundle.Bundle), params[1].([]*value_transaction.ValueTransaction)) -} diff --git a/plugins/bundleprocessor/plugin.go b/plugins/bundleprocessor/plugin.go deleted file mode 100644 index d8a6303dfe71ab83d96c0dcd6a151dfb113828ee..0000000000000000000000000000000000000000 --- a/plugins/bundleprocessor/plugin.go +++ /dev/null @@ -1,52 +0,0 @@ -package bundleprocessor - -import ( - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" -) - -var PLUGIN = node.NewPlugin("Bundle Processor", node.Enabled, configure, run) -var log *logger.Logger - -func configure(*node.Plugin) { - log = logger.NewLogger("Bundle Processor") - - tangle.Events.TransactionSolid.Attach(events.NewClosure(func(tx *value_transaction.ValueTransaction) { - if tx.IsHead() { - workerPool.Submit(tx) - } - })) - - Events.Error.Attach(events.NewClosure(func(err error) { - log.Error(err) - })) -} - -func run(*node.Plugin) { - log.Info("Starting Bundle Processor ...") - - daemon.BackgroundWorker("Bundle Processor", func(shutdownSignal <-chan struct{}) { - log.Info("Starting Bundle Processor ... done") - workerPool.Start() - <-shutdownSignal - log.Info("Stopping Bundle Processor ...") - workerPool.StopAndWait() - log.Info("Stopping Bundle Processor ... done") - }, shutdown.ShutdownPriorityBundleProcessor) - - log.Info("Starting Value Bundle Processor ...") - - daemon.BackgroundWorker("Value Bundle Processor", func(shutdownSignal <-chan struct{}) { - log.Info("Starting Value Bundle Processor ... done") - valueBundleProcessorWorkerPool.Start() - <-shutdownSignal - log.Info("Stopping Value Bundle Processor ...") - valueBundleProcessorWorkerPool.StopAndWait() - log.Info("Stopping Value Bundle Processor ... done") - }, shutdown.ShutdownPriorityBundleProcessor) -} diff --git a/plugins/bundleprocessor/valuebundleprocessor.go b/plugins/bundleprocessor/valuebundleprocessor.go deleted file mode 100644 index 984c2b244b354abfc26562859b69d82eae5810e2..0000000000000000000000000000000000000000 --- a/plugins/bundleprocessor/valuebundleprocessor.go +++ /dev/null @@ -1,80 +0,0 @@ -package bundleprocessor - -import ( - "github.com/iotaledger/goshimmer/packages/model/bundle" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/hive.go/workerpool" - "github.com/iotaledger/iota.go/curl" - "github.com/iotaledger/iota.go/signing" - "github.com/iotaledger/iota.go/trinary" -) - -var valueBundleProcessorWorkerPool = workerpool.New(func(task workerpool.Task) { - if err := ProcessSolidValueBundle(task.Param(0).(*bundle.Bundle), task.Param(1).([]*value_transaction.ValueTransaction)); err != nil { - Events.Error.Trigger(err) - } - - task.Return(nil) -}, workerpool.WorkerCount(WORKER_COUNT), workerpool.QueueSize(2*WORKER_COUNT)) - -func ProcessSolidValueBundle(bundle *bundle.Bundle, bundleTransactions []*value_transaction.ValueTransaction) error { - bundle.SetBundleEssenceHash(CalculateBundleHash(bundleTransactions)) - - Events.BundleSolid.Trigger(bundle, bundleTransactions) - - return nil -} - -func CalculateBundleHash(transactions []*value_transaction.ValueTransaction) trinary.Trytes { - var lastInputAddress trinary.Trytes - - var concatenatedBundleEssences = make(trinary.Trits, len(transactions)*value_transaction.BUNDLE_ESSENCE_SIZE) - for i, bundleTransaction := range transactions { - if bundleTransaction.GetValue() <= 0 { - lastInputAddress = bundleTransaction.GetAddress() - } - - copy(concatenatedBundleEssences[value_transaction.BUNDLE_ESSENCE_SIZE*i:value_transaction.BUNDLE_ESSENCE_SIZE*(i+1)], bundleTransaction.GetBundleEssence(lastInputAddress != bundleTransaction.GetAddress())) - } - - bundleHash, err := curl.HashTrits(concatenatedBundleEssences) - if err != nil { - panic(err) - } - return trinary.MustTritsToTrytes(bundleHash) -} - -func ValidateSignatures(bundleHash trinary.Hash, txs []*value_transaction.ValueTransaction) (bool, error) { - for i, tx := range txs { - // ignore all non-input transactions - if tx.GetValue() >= 0 { - continue - } - - address := tx.GetAddress() - - // it is unknown how many fragments there will be - fragments := []trinary.Trytes{tx.GetSignatureMessageFragment()} - - // each consecutive meta transaction with the same address contains another signature fragment - for j := i; j < len(txs)-1; j++ { - otherTx := txs[j+1] - if otherTx.GetValue() != 0 || otherTx.GetAddress() != address { - break - } - - fragments = append(fragments, otherTx.GetSignatureMessageFragment()) - } - - // validate all the fragments against the address using Kerl - valid, err := signing.ValidateSignatures(address, fragments, bundleHash) - if err != nil { - return false, err - } - if !valid { - return false, nil - } - } - - return true, nil -} diff --git a/plugins/cli/cli.go b/plugins/cli/cli.go index bd362093255aa46f242c20b562551fdb983aa4d3..740d23b13c96990f68186bbf4bc5fd919411c6e6 100644 --- a/plugins/cli/cli.go +++ b/plugins/cli/cli.go @@ -14,6 +14,7 @@ import ( var enabledPlugins []string var disabledPlugins []string +// AddPluginStatus adds the status (enabled=1, disabled=0) of a given plugin. func AddPluginStatus(name string, status int) { switch status { case node.Enabled: diff --git a/plugins/cli/plugin.go b/plugins/cli/plugin.go index 7243e23b36e061fa22fbe51a2543f0eeb3de889b..168aa3d33482fb6cdf2358ac5176b007c8700ebc 100644 --- a/plugins/cli/plugin.go +++ b/plugins/cli/plugin.go @@ -3,84 +3,53 @@ package cli import ( "fmt" "os" + "sync" - "github.com/iotaledger/goshimmer/packages/parameter" + "github.com/iotaledger/goshimmer/plugins/banner" "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" flag "github.com/spf13/pflag" ) -const ( - // AppVersion version number - AppVersion = "v0.1.3" - // AppName app code name - AppName = "GoShimmer" -) +// PluginName is the name of the CLI plugin. +const PluginName = "CLI" -var PLUGIN = node.NewPlugin("CLI", node.Enabled, configure, run) +var ( + // plugin is the plugin instance of the CLI plugin. + plugin *node.Plugin + once sync.Once + version = flag.BoolP("version", "v", false, "Prints the GoShimmer version") +) -func onAddPlugin(name string, status int) { - AddPluginStatus(node.GetPluginIdentifier(name), status) +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled) + }) + return plugin } func init() { + plugin = Plugin() - for name, status := range node.GetPlugins() { - onAddPlugin(name, status) + for name, plugin := range node.GetPlugins() { + onAddPlugin(name, plugin.Status) } node.Events.AddPlugin.Attach(events.NewClosure(onAddPlugin)) flag.Usage = printUsage + + plugin.Events.Init.Attach(events.NewClosure(onInit)) } -func parseParameters() { - for _, pluginName := range parameter.NodeConfig.GetStringSlice(node.CFG_DISABLE_PLUGINS) { - node.DisabledPlugins[node.GetPluginIdentifier(pluginName)] = true - } - for _, pluginName := range parameter.NodeConfig.GetStringSlice(node.CFG_ENABLE_PLUGINS) { - node.EnabledPlugins[node.GetPluginIdentifier(pluginName)] = true - } +func onAddPlugin(name string, status int) { + AddPluginStatus(node.GetPluginIdentifier(name), status) } -func PrintVersion() { - version := flag.BoolP("version", "v", false, "Prints the GoShimmer version") - flag.Parse() +func onInit(*node.Plugin) { if *version { - fmt.Println(AppName + " " + AppVersion) + fmt.Println(banner.AppName + " " + banner.AppVersion) os.Exit(0) } } - -func LoadConfig() { - if err := parameter.FetchConfig(false); err != nil { - panic(err) - } - - parseParameters() - - if err := logger.InitGlobalLogger(parameter.NodeConfig); err != nil { - panic(err) - } -} - -func configure(ctx *node.Plugin) { - fmt.Printf(` - _____ ____ _____ _ _ _____ __ __ __ __ ______ _____ - / ____|/ __ \ / ____| | | |_ _| \/ | \/ | ____| __ \ - | | __| | | | (___ | |__| | | | | \ / | \ / | |__ | |__) | - | | |_ | | | |\___ \| __ | | | | |\/| | |\/| | __| | _ / - | |__| | |__| |____) | | | |_| |_| | | | | | | |____| | \ \ - \_____|\____/|_____/|_| |_|_____|_| |_|_| |_|______|_| \_\ - %s -`, AppVersion) - fmt.Println() - - ctx.Node.Logger.Infof("GoShimmer version %s ...", AppVersion) - ctx.Node.Logger.Info("Loading plugins ...") -} - -func run(ctx *node.Plugin) { - // do nothing; everything is handled in the configure step -} diff --git a/plugins/config/config.go b/plugins/config/config.go deleted file mode 100644 index 70513880fa272a3878d840c6cb7211fa26eb8df6..0000000000000000000000000000000000000000 --- a/plugins/config/config.go +++ /dev/null @@ -1,64 +0,0 @@ -package config - -import ( - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/hive.go/parameter" - flag "github.com/spf13/pflag" - "github.com/spf13/viper" -) - -var ( - // flags - configName = flag.StringP("config", "c", "config", "Filename of the config file without the file extension") - configDirPath = flag.StringP("config-dir", "d", ".", "Path to the directory containing the config file") - - // viper - NodeConfig *viper.Viper - - // logger - defaultLoggerConfig = logger.Config{ - Level: "info", - DisableCaller: false, - DisableStacktrace: false, - Encoding: "console", - OutputPaths: []string{"goshimmer.log"}, - DisableEvents: false, - } -) - -func init() { - // set the default logger config - NodeConfig = viper.New() - NodeConfig.SetDefault(logger.ViperKey, defaultLoggerConfig) - - if err := Fetch(false); err != nil { - panic(err) - } - parseParameters() -} - -func parseParameters() { - for _, pluginName := range NodeConfig.GetStringSlice(node.CFG_DISABLE_PLUGINS) { - node.DisabledPlugins[node.GetPluginIdentifier(pluginName)] = true - } - for _, pluginName := range NodeConfig.GetStringSlice(node.CFG_ENABLE_PLUGINS) { - node.EnabledPlugins[node.GetPluginIdentifier(pluginName)] = true - } -} - -// Fetch fetches config values from a dir defined via CLI flag --config-dir (or the current working dir if not set). -// -// It automatically reads in a single config file starting with "config" (can be changed via the --config CLI flag) -// and ending with: .json, .toml, .yaml or .yml (in this sequence). -func Fetch(printConfig bool, ignoreSettingsAtPrint ...[]string) error { - err := parameter.LoadConfigFile(NodeConfig, *configDirPath, *configName, true, true) - if err != nil { - return err - } - - if printConfig { - parameter.PrintConfig(NodeConfig, ignoreSettingsAtPrint...) - } - return nil -} diff --git a/plugins/config/plugin.go b/plugins/config/plugin.go index 0626fa17396b321ac567b28a3fb536bac9b39d42..76b2cf7e80deefef0b058ceef5bd4ba4d1b561a4 100644 --- a/plugins/config/plugin.go +++ b/plugins/config/plugin.go @@ -1,12 +1,105 @@ package config import ( + "fmt" + "os" + "strings" + "sync" + + "github.com/iotaledger/hive.go/events" "github.com/iotaledger/hive.go/node" + "github.com/iotaledger/hive.go/parameter" + flag "github.com/spf13/pflag" + "github.com/spf13/viper" ) -// define the plugin as a placeholder, so the init methods get executed accordingly -var PLUGIN = node.NewPlugin("Config", node.Enabled, run) +// PluginName is the name of the config plugin. +const PluginName = "Config" + +var ( + // plugin is the plugin instance of the config plugin. + plugin *node.Plugin + pluginOnce sync.Once + + // flags + configName = flag.StringP("config", "c", "config", "Filename of the config file without the file extension") + configDirPath = flag.StringP("config-dir", "d", ".", "Path to the directory containing the config file") + skipConfigAvailable = flag.Bool("skip-config", false, "Skip config file availability check") + + // Node is viper + _node *viper.Viper + nodeOnce sync.Once +) + +// Init triggers the Init event. +func Init() { + plugin.Events.Init.Trigger(plugin) +} + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + pluginOnce.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled) + }) + return plugin +} + +// Node gets the node. +func Node() *viper.Viper { + nodeOnce.Do(func() { + _node = viper.New() + }) + return _node +} + +func init() { + // set the default logger config + _node = Node() + plugin = Plugin() + + plugin.Events.Init.Attach(events.NewClosure(func(*node.Plugin) { + if err := fetch(false); err != nil { + if !*skipConfigAvailable { + // we wanted a config file but it was not present + // global logger instance is not initialized at this stage... + fmt.Println(err.Error()) + fmt.Println("no config file present, terminating GoShimmer. please use the provided config.default.json to create a config.json.") + // daemon is not running yet, so we just exit + os.Exit(1) + } + panic(err) + } + })) +} + +// fetch fetches config values from a dir defined via CLI flag --config-dir (or the current working dir if not set). +// +// It automatically reads in a single config file starting with "config" (can be changed via the --config CLI flag) +// and ending with: .json, .toml, .yaml or .yml (in this sequence). +func fetch(printConfig bool, ignoreSettingsAtPrint ...[]string) error { + // replace dots with underscores in env + dotReplacer := strings.NewReplacer(".", "_") + _node.SetEnvKeyReplacer(dotReplacer) + // read in ENV variables + // read in ENV variables + _node.AutomaticEnv() + + flag.Parse() + err := parameter.LoadConfigFile(_node, *configDirPath, *configName, true, *skipConfigAvailable) + if err != nil { + return err + } + + if printConfig { + parameter.PrintConfig(_node, ignoreSettingsAtPrint...) + } + + for _, pluginName := range _node.GetStringSlice(node.CFG_DISABLE_PLUGINS) { + node.DisabledPlugins[node.GetPluginIdentifier(pluginName)] = true + } + for _, pluginName := range _node.GetStringSlice(node.CFG_ENABLE_PLUGINS) { + node.EnabledPlugins[node.GetPluginIdentifier(pluginName)] = true + } -func run(ctx *node.Plugin) { - // do nothing; everything is handled in the init method + return nil } diff --git a/plugins/analysis/webinterface/httpserver/httpserver-packr.go b/plugins/dashboard/dashboard-packr.go similarity index 62% rename from plugins/analysis/webinterface/httpserver/httpserver-packr.go rename to plugins/dashboard/dashboard-packr.go index 38f8e3fb83c1cc95108d36b76797055b16716b30..173f3779512003421138356e2d11ba97129fae80 100644 --- a/plugins/analysis/webinterface/httpserver/httpserver-packr.go +++ b/plugins/dashboard/dashboard-packr.go @@ -3,6 +3,6 @@ // You can use the "packr clean" command to clean up this, // and any other packr generated files. -package httpserver +package dashboard -import _ "github.com/iotaledger/goshimmer/plugins/analysis/webinterface/httpserver/packrd" +import _ "github.com/iotaledger/goshimmer/plugins/dashboard/packrd" diff --git a/plugins/dashboard/drng_livefeed.go b/plugins/dashboard/drng_livefeed.go new file mode 100644 index 0000000000000000000000000000000000000000..01d468efb7ba9958c7ba31f5729f37a6aa46d942 --- /dev/null +++ b/plugins/dashboard/drng_livefeed.go @@ -0,0 +1,66 @@ +package dashboard + +import ( + "encoding/hex" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/drng/state" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/drng" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/workerpool" +) + +var drngLiveFeedWorkerCount = 1 +var drngLiveFeedWorkerQueueSize = 50 +var drngLiveFeedWorkerPool *workerpool.WorkerPool + +type drngMsg struct { + Instance uint32 `json:"instance"` + DistributedPK string `json:"dpk"` + Round uint64 `json:"round"` + Randomness string `json:"randomness"` + Timestamp string `json:"timestamp"` +} + +func configureDrngLiveFeed() { + drngLiveFeedWorkerPool = workerpool.New(func(task workerpool.Task) { + newRandomness := task.Param(0).(state.Randomness) + + broadcastWsMessage(&wsmsg{MsgTypeDrng, &drngMsg{ + Instance: drng.Instance().State.Committee().InstanceID, + DistributedPK: hex.EncodeToString(drng.Instance().State.Committee().DistributedPK), + Round: newRandomness.Round, + Randomness: hex.EncodeToString(newRandomness.Randomness[:32]), + Timestamp: newRandomness.Timestamp.Format("2 Jan 2006 15:04:05")}}) + + task.Return(nil) + }, workerpool.WorkerCount(drngLiveFeedWorkerCount), workerpool.QueueSize(drngLiveFeedWorkerQueueSize)) +} + +func runDrngLiveFeed() { + if err := daemon.BackgroundWorker("Dashboard[DRNGUpdater]", func(shutdownSignal <-chan struct{}) { + newMsgRateLimiter := time.NewTicker(time.Second / 10) + defer newMsgRateLimiter.Stop() + + notifyNewRandomness := events.NewClosure(func(message state.Randomness) { + select { + case <-newMsgRateLimiter.C: + drngLiveFeedWorkerPool.TrySubmit(message) + default: + } + }) + drng.Instance().Events.Randomness.Attach(notifyNewRandomness) + + drngLiveFeedWorkerPool.Start() + defer drngLiveFeedWorkerPool.Stop() + + <-shutdownSignal + log.Info("Stopping Dashboard[DRNGUpdater] ...") + drng.Instance().Events.Randomness.Detach(notifyNewRandomness) + log.Info("Stopping Dashboard[DRNGUpdater] ... done") + }, shutdown.PriorityDashboard); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} diff --git a/plugins/dashboard/explorer_routes.go b/plugins/dashboard/explorer_routes.go new file mode 100644 index 0000000000000000000000000000000000000000..cc5cab1715c709e25941b2194d785cd51d91c820 --- /dev/null +++ b/plugins/dashboard/explorer_routes.go @@ -0,0 +1,217 @@ +package dashboard + +import ( + "fmt" + "net/http" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/labstack/echo" + "github.com/mr-tron/base58/base58" +) + +// ExplorerMessage defines the struct of the ExplorerMessage. +type ExplorerMessage struct { + // ID is the message ID. + ID string `json:"id"` + // SolidificationTimestamp is the timestamp of the message. + SolidificationTimestamp int64 `json:"solidification_timestamp"` + // The time when this message was issued + IssuanceTimestamp int64 `json:"issuance_timestamp"` + // The issuer's sequence number of this message. + SequenceNumber uint64 `json:"sequence_number"` + // The public key of the issuer who issued this message. + IssuerPublicKey string `json:"issuer_public_key"` + // The signature of the message. + Signature string `json:"signature"` + // TrunkMessageId is the Trunk ID of the message. + TrunkMessageID string `json:"trunk_message_id"` + // BranchMessageId is the Branch ID of the message. + BranchMessageID string `json:"branch_message_id"` + // Solid defines the solid status of the message. + Solid bool `json:"solid"` + // PayloadType defines the type of the payload. + PayloadType uint32 `json:"payload_type"` + // Payload is the content of the payload. + Payload interface{} `json:"payload"` +} + +func createExplorerMessage(msg *message.Message) (*ExplorerMessage, error) { + messageID := msg.Id() + cachedMessageMetadata := messagelayer.Tangle().MessageMetadata(messageID) + defer cachedMessageMetadata.Release() + messageMetadata := cachedMessageMetadata.Unwrap() + t := &ExplorerMessage{ + ID: messageID.String(), + SolidificationTimestamp: messageMetadata.SolidificationTime().Unix(), + IssuanceTimestamp: msg.IssuingTime().Unix(), + IssuerPublicKey: msg.IssuerPublicKey().String(), + Signature: msg.Signature().String(), + SequenceNumber: msg.SequenceNumber(), + TrunkMessageID: msg.TrunkId().String(), + BranchMessageID: msg.BranchId().String(), + Solid: cachedMessageMetadata.Unwrap().IsSolid(), + PayloadType: msg.Payload().Type(), + Payload: ProcessPayload(msg.Payload()), + } + + return t, nil +} + +// ExplorerAddress defines the struct of the ExplorerAddress. +type ExplorerAddress struct { + Address string `json:"address"` + OutputIDs []ExplorerOutput `json:"output_ids"` +} + +// ExplorerOutput defines the struct of the ExplorerOutput. +type ExplorerOutput struct { + ID string `json:"id"` + Balances []utils.Balance `json:"balances"` + InclusionState utils.InclusionState `json:"inclusion_state"` + SolidificationTime int64 `json:"solidification_time"` + ConsumerCount int `json:"consumer_count"` +} + +// SearchResult defines the struct of the SearchResult. +type SearchResult struct { + // Message is the *ExplorerMessage. + Message *ExplorerMessage `json:"message"` + // Address is the *ExplorerAddress. + Address *ExplorerAddress `json:"address"` +} + +func setupExplorerRoutes(routeGroup *echo.Group) { + routeGroup.GET("/message/:id", func(c echo.Context) (err error) { + messageID, err := message.NewId(c.Param("id")) + if err != nil { + return + } + + t, err := findMessage(messageID) + if err != nil { + return + } + + return c.JSON(http.StatusOK, t) + }) + + routeGroup.GET("/address/:id", func(c echo.Context) error { + addr, err := findAddress(c.Param("id")) + if err != nil { + return err + } + return c.JSON(http.StatusOK, addr) + }) + + routeGroup.GET("/search/:search", func(c echo.Context) error { + search := c.Param("search") + result := &SearchResult{} + + searchInByte, err := base58.Decode(search) + if err != nil { + return fmt.Errorf("%w: search ID %s", ErrInvalidParameter, search) + } + + switch len(searchInByte) { + + case address.Length: + addr, err := findAddress(search) + if err == nil { + result.Address = addr + } + + case message.IdLength: + messageID, err := message.NewId(search) + if err != nil { + return fmt.Errorf("%w: search ID %s", ErrInvalidParameter, search) + } + + msg, err := findMessage(messageID) + if err == nil { + result.Message = msg + } + + default: + return fmt.Errorf("%w: search ID %s", ErrInvalidParameter, search) + } + + return c.JSON(http.StatusOK, result) + }) +} + +func findMessage(messageID message.Id) (explorerMsg *ExplorerMessage, err error) { + if !messagelayer.Tangle().Message(messageID).Consume(func(msg *message.Message) { + explorerMsg, err = createExplorerMessage(msg) + }) { + err = fmt.Errorf("%w: message %s", ErrNotFound, messageID.String()) + } + + return +} + +func findAddress(strAddress string) (*ExplorerAddress, error) { + + address, err := address.FromBase58(strAddress) + if err != nil { + return nil, fmt.Errorf("%w: address %s", ErrNotFound, strAddress) + } + + outputids := make([]ExplorerOutput, 0) + inclusionState := utils.InclusionState{} + + // get outputids by address + for id, cachedOutput := range valuetransfers.Tangle().OutputsOnAddress(address) { + + cachedOutput.Consume(func(output *tangle.Output) { + + // iterate balances + var b []utils.Balance + for _, balance := range output.Balances() { + b = append(b, utils.Balance{ + Value: balance.Value, + Color: balance.Color.String(), + }) + } + var solidificationTime int64 + if !valuetransfers.Tangle().TransactionMetadata(output.TransactionID()).Consume(func(txMeta *tangle.TransactionMetadata) { + inclusionState.Confirmed = txMeta.Confirmed() + inclusionState.Liked = txMeta.Liked() + inclusionState.Rejected = txMeta.Rejected() + inclusionState.Finalized = txMeta.Finalized() + inclusionState.Conflicting = txMeta.Conflicting() + inclusionState.Confirmed = txMeta.Confirmed() + solidificationTime = txMeta.SolidificationTime().Unix() + }) { + // This is only for the genesis. + inclusionState.Confirmed = output.Confirmed() + inclusionState.Liked = output.Liked() + inclusionState.Rejected = output.Rejected() + inclusionState.Finalized = output.Finalized() + inclusionState.Confirmed = output.Confirmed() + } + + outputids = append(outputids, ExplorerOutput{ + ID: id.String(), + Balances: b, + InclusionState: inclusionState, + ConsumerCount: output.ConsumerCount(), + SolidificationTime: solidificationTime, + }) + }) + } + + if len(outputids) == 0 { + return nil, fmt.Errorf("%w: address %s", ErrNotFound, strAddress) + } + + return &ExplorerAddress{ + Address: strAddress, + OutputIDs: outputids, + }, nil + +} diff --git a/plugins/dashboard/faucet_routes.go b/plugins/dashboard/faucet_routes.go new file mode 100644 index 0000000000000000000000000000000000000000..efaf0c4945f61adad9d1e647f7fdb0f72e83221e --- /dev/null +++ b/plugins/dashboard/faucet_routes.go @@ -0,0 +1,45 @@ +package dashboard + +import ( + "net/http" + + faucetpayload "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + + "github.com/labstack/echo" + "github.com/pkg/errors" +) + +// ReqMsg defines the struct of the faucet request message ID. +type ReqMsg struct { + ID string `json:"MsgId"` +} + +func setupFaucetRoutes(routeGroup *echo.Group) { + routeGroup.GET("/faucet/:hash", func(c echo.Context) (err error) { + addr, err := address.FromBase58(c.Param("hash")) + if err != nil { + return errors.Wrapf(ErrInvalidParameter, "faucet request address invalid: %s", addr) + } + + t, err := sendFaucetReq(addr) + if err != nil { + return + } + + return c.JSON(http.StatusOK, t) + }) +} + +func sendFaucetReq(addr address.Address) (res *ReqMsg, err error) { + msg := messagelayer.MessageFactory().IssuePayload(faucetpayload.New(addr)) + if msg == nil { + return nil, errors.Wrapf(ErrInternalError, "Fail to send faucet request") + } + + r := &ReqMsg{ + ID: msg.Id().String(), + } + return r, nil +} diff --git a/plugins/dashboard/frontend/.gitignore b/plugins/dashboard/frontend/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7c9c6dc25cd209b21a2f047900f0643ae0c6466e --- /dev/null +++ b/plugins/dashboard/frontend/.gitignore @@ -0,0 +1,7 @@ +.vscode +.DS_STORE +node_modules +.module-cache +*.log* +build +dist \ No newline at end of file diff --git a/plugins/dashboard/frontend/.prettierrc b/plugins/dashboard/frontend/.prettierrc new file mode 100644 index 0000000000000000000000000000000000000000..f38b57120764e1c81df7de5585fd01a4be682de0 --- /dev/null +++ b/plugins/dashboard/frontend/.prettierrc @@ -0,0 +1,8 @@ +{ + "arrowParens": "always", + "semi": true, + "useTabs": false, + "tabWidth": 2, + "bracketSpacing": true, + "singleQuote": true +} diff --git a/plugins/spa/frontend/README.md b/plugins/dashboard/frontend/README.md similarity index 74% rename from plugins/spa/frontend/README.md rename to plugins/dashboard/frontend/README.md index 029aea503242edd6b42524fcb5f8aea709a1a6c1..157f960074485cb4d1ec05cc980bd07ecfce0ce6 100644 --- a/plugins/spa/frontend/README.md +++ b/plugins/dashboard/frontend/README.md @@ -1,8 +1,8 @@ -# GoShimmer SPA +# GoShimmer Dashboard Programmed using modern web technologies. -### SPA in dev mode +### Dashboard in dev mode 1. Make sure to set `dashboard.dev` to true, to enable GoShimmer to serve assets from the webpack-dev-server. @@ -10,15 +10,15 @@ Programmed using modern web technologies. 3. Run a webpack-dev-server instance by running `yarn start` within the `frontend` directory. 4. Using default port config, you should now be able to access the dashboard under http://127.0.0.1:8081 -The SPA is hot-reload enabled. +The Dashboard is hot-reload enabled. ### Pack your changes We are using [packr2](https://github.com/gobuffalo/packr/tree/master/v2) to wrap all built frontend files into Go files. 1. [Install `packr2`](https://github.com/gobuffalo/packr/tree/master/v2#binary-installation) if not already done. -2. Build SPA by running `yarn build` within the `frontend` directory. +2. Build Dashboard by running `yarn build` within the `frontend` directory. 3. Change to the `plugins/spa` directory. 4. Run `packr2`. 5. `plugins/spa/packrd` should have been modified. -6. Done. Now you can build goShimmer and your SPA changes will be included within the binary. +6. Done. Now you can build goShimmer and your Dashboard changes will be included within the binary. diff --git a/plugins/spa/frontend/package.json b/plugins/dashboard/frontend/package.json similarity index 84% rename from plugins/spa/frontend/package.json rename to plugins/dashboard/frontend/package.json index d491b342b5c0414cf556ca69945c8538492b753f..04639ae2815d6ecdc3a109b68a63a7d3936698e0 100644 --- a/plugins/spa/frontend/package.json +++ b/plugins/dashboard/frontend/package.json @@ -13,6 +13,10 @@ "license": "MIT", "devDependencies": { "@babel/core": "^7.2.2", + "@jimp/custom": "^0.10.1", + "@jimp/plugin-blur": "^0.10.1", + "@jimp/plugin-color": "^0.10.1", + "@jimp/plugin-resize": "^0.10.1", "@types/classnames": "^2.2.7", "@types/react": "^16.7.20", "@types/react-dom": "^16.0.11", @@ -23,8 +27,10 @@ "file-loader": "^3.0.1", "html-loader": "^1.0.0-alpha.0", "html-webpack-plugin": "^3.2.0", + "jquery": "^3.5.0", "mini-css-extract-plugin": "^0.5.0", "mobx-react-devtools": "^6.0.3", + "popper.js": "^1.16.1", "postcss": "^7.0.13", "postcss-browser-reporter": "^0.5.0", "postcss-import": "^12.0.1", @@ -39,9 +45,9 @@ "tsx-control-statements": "2.17.1", "typescript": "^3.2.4", "url-loader": "^1.1.2", - "webpack": "^4.29.0", + "webpack": "^4.43.0", "webpack-cleanup-plugin": "^0.5.1", - "webpack-cli": "^3.2.1", + "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.1.14", "webpack-hot-middleware": "^2.24.3" }, @@ -58,17 +64,21 @@ "classnames": "^2.2.6", "dateformat": "^3.0.3", "favicons-webpack-plugin": "^2.1.0", + "history": "^4.10.1", "mobx": "^5.15.0", "mobx-react": "^5.4.3", "mobx-react-router": "^4.0.5", + "moment": "^2.24.0", "prettysize": "^2.0.0", "react": "^16.7.0", "react-apexcharts": "^1.3.3", "react-bootstrap": "^1.0.0-beta.16", "react-chartjs-2": "^2.8.0", "react-dom": "^16.7.0", + "react-icons": "^3.10.0", "react-router": "^4.3.1", "react-router-bootstrap": "^0.25.0", - "react-router-dom": "^5.1.2" + "react-router-dom": "^5.1.2", + "vivagraphjs": "^0.12.0" } } diff --git a/plugins/spa/frontend/src/app/App.tsx b/plugins/dashboard/frontend/src/app/App.tsx similarity index 100% rename from plugins/spa/frontend/src/app/App.tsx rename to plugins/dashboard/frontend/src/app/App.tsx diff --git a/plugins/dashboard/frontend/src/app/components/BasicPayload.tsx b/plugins/dashboard/frontend/src/app/components/BasicPayload.tsx new file mode 100644 index 0000000000000000000000000000000000000000..401b8511c37a49f35b8c66c270377e4ab846454e --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/BasicPayload.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import {inject, observer} from "mobx-react"; +import ExplorerStore from "app/stores/ExplorerStore"; + +interface Props { + explorerStore?: ExplorerStore; +} + +@inject("explorerStore") +@observer +export class BasicPayload extends React.Component<Props, any> { + + render() { + let {payload} = this.props.explorerStore; + return ( + payload && + <React.Fragment> + <Row className={"mb-3"}> + <Col> + {payload.content_title}: {' '} + {payload.content} + </Col> + </Row> + </React.Fragment> + ); + } +} diff --git a/plugins/spa/frontend/src/app/components/Dashboard.tsx b/plugins/dashboard/frontend/src/app/components/Dashboard.tsx similarity index 86% rename from plugins/spa/frontend/src/app/components/Dashboard.tsx rename to plugins/dashboard/frontend/src/app/components/Dashboard.tsx index 673575cc56a500330c36026790b5f3d5f1b17855..a5020fa740be21ecbcbe7d9db9293d76fb2beba6 100644 --- a/plugins/spa/frontend/src/app/components/Dashboard.tsx +++ b/plugins/dashboard/frontend/src/app/components/Dashboard.tsx @@ -4,7 +4,8 @@ import Row from "react-bootstrap/Row"; import Col from "react-bootstrap/Col"; import Uptime from "app/components/Uptime"; import Version from "app/components/Version"; -import TPSChart from "app/components/TPSChart"; +import MPSChart from "app/components/MPSChart"; +import TipsChart from "app/components/TipsChart"; import NodeStore from "app/stores/NodeStore"; import {inject, observer} from "mobx-react"; import ListGroup from "react-bootstrap/ListGroup"; @@ -44,7 +45,10 @@ export class Dashboard extends React.Component<Props, any> { </Col> </Row> <Row className={"mb-3"}> - <Col><TPSChart/></Col> + <Col><MPSChart/></Col> + </Row> + <Row className={"mb-3"}> + <Col><TipsChart/></Col> </Row> <Row className={"mb-3"}> <Col><MemChart/></Col> diff --git a/plugins/dashboard/frontend/src/app/components/Drng.tsx b/plugins/dashboard/frontend/src/app/components/Drng.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c0d87dc1a517560eaa599f5b3aba55a47ffdaedf --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/Drng.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Container from "react-bootstrap/Container"; +import NodeStore from "app/stores/NodeStore"; +import {inject, observer} from "mobx-react"; +import {DrngLiveFeed} from "app/components/DrngLiveFeed"; + +interface Props { + nodeStore?: NodeStore; +} + +@inject("nodeStore") +@observer +export class Drng extends React.Component<Props, any> { + render() { + return ( + <Container> + <h3>dRNG Beacons</h3> + <DrngLiveFeed/> + </Container> + ); + } +} diff --git a/plugins/dashboard/frontend/src/app/components/DrngLiveFeed.tsx b/plugins/dashboard/frontend/src/app/components/DrngLiveFeed.tsx new file mode 100644 index 0000000000000000000000000000000000000000..774545a0b3b32080492a9d70aafdcf6d87b622ed --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/DrngLiveFeed.tsx @@ -0,0 +1,51 @@ +import * as React from 'react'; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import NodeStore from "app/stores/NodeStore"; +import {inject, observer} from "mobx-react"; +import Card from "react-bootstrap/Card"; +import DrngStore from "app/stores/DrngStore"; +import Table from "react-bootstrap/Table"; + +interface Props { + nodeStore?: NodeStore; + drngStore?: DrngStore; +} + +@inject("nodeStore") +@inject("drngStore") +@observer +export class DrngLiveFeed extends React.Component<Props, any> { + render() { + let {msgsLiveFeed} = this.props.drngStore; + return ( + <Row className={"mb-3"}> + <Col> + <Card> + <Card.Body> + <Card.Title>Live Feed</Card.Title> + <Row className={"mb-3"}> + <Col xs={12}> + <h6>Collective Beacons</h6> + <Table> + <thead> + <tr> + <td>InstanceID</td> + <td>Round</td> + <td>Randomness</td> + <td>Timestamp</td> + </tr> + </thead> + <tbody> + {msgsLiveFeed} + </tbody> + </Table> + </Col> + </Row> + </Card.Body> + </Card> + </Col> + </Row> + ); + } +} diff --git a/plugins/dashboard/frontend/src/app/components/DrngPayload.tsx b/plugins/dashboard/frontend/src/app/components/DrngPayload.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f7492b2142b3cc0a9581537329fcf6af09c07d81 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/DrngPayload.tsx @@ -0,0 +1,81 @@ +import * as React from 'react'; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import {inject, observer} from "mobx-react"; +import {ExplorerStore} from "app/stores/ExplorerStore"; +import ListGroup from "react-bootstrap/ListGroup"; +import {DrngSubtype} from "app/misc/Payload" + +interface Props { + explorerStore?: ExplorerStore; +} + +@inject("explorerStore") +@observer +export class DrngPayload extends React.Component<Props, any> { + + render() { + let {payload, subpayload} = this.props.explorerStore; + return ( + payload && + <React.Fragment> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Drng payload subtype: {payload.subpayload_type} </ListGroup.Item> + </ListGroup> + </Col> + <Col> + <ListGroup> + <ListGroup.Item>Instance ID: {payload.instance_id} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + { + payload.subpayload_type == DrngSubtype.Cb ? ( + <React.Fragment> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Round: {subpayload.round} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Previous Signature: {subpayload.prev_sig} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Signature: {subpayload.sig} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Distributed Public Key: {subpayload.dpk} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + </React.Fragment> + ) : ( + <React.Fragment> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>{subpayload.content_title}: {subpayload.bytes} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + </React.Fragment> + ) + } + </React.Fragment> + ); + } +} diff --git a/plugins/spa/frontend/src/app/components/Explorer.tsx b/plugins/dashboard/frontend/src/app/components/Explorer.tsx similarity index 81% rename from plugins/spa/frontend/src/app/components/Explorer.tsx rename to plugins/dashboard/frontend/src/app/components/Explorer.tsx index 1f9b8e7bb7b3c399cee590ea3bd514c9dad49d8b..6a8e3cf085dd17e19fc5275624732d98bf45bf54 100644 --- a/plugins/spa/frontend/src/app/components/Explorer.tsx +++ b/plugins/dashboard/frontend/src/app/components/Explorer.tsx @@ -21,16 +21,15 @@ export class Explorer extends React.Component<Props, any> { <Row className={"mb-3"}> <Col> <p> - Search for addresses or transactions by supplying - their corresponding hashes. + Search for addresses or messages. </p> - </Col> </Row> <ExplorerSearchbar/> <ExplorerLiveFeed/> <small> - This explorer implementation is heavily inspired by <a href={"https://thetangle.org"}>thetangle.org</a>. + This explorer implementation is heavily inspired by <a + href={"https://thetangle.org"}>thetangle.org</a>. </small> </Container> ); diff --git a/plugins/spa/frontend/src/app/components/Explorer404.tsx b/plugins/dashboard/frontend/src/app/components/Explorer404.tsx similarity index 100% rename from plugins/spa/frontend/src/app/components/Explorer404.tsx rename to plugins/dashboard/frontend/src/app/components/Explorer404.tsx diff --git a/plugins/dashboard/frontend/src/app/components/ExplorerAddressResult.tsx b/plugins/dashboard/frontend/src/app/components/ExplorerAddressResult.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8ac00ca0808d0b808d4ec6f54e640561a6dd2458 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/ExplorerAddressResult.tsx @@ -0,0 +1,175 @@ +import * as React from 'react'; +import Container from "react-bootstrap/Container"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import NodeStore from "app/stores/NodeStore"; +import {inject, observer} from "mobx-react"; +import ExplorerStore from "app/stores/ExplorerStore"; +import Spinner from "react-bootstrap/Spinner"; +import ListGroup from "react-bootstrap/ListGroup"; +import Alert from "react-bootstrap/Alert"; +import * as dateformat from 'dateformat'; + +interface Props { + nodeStore?: NodeStore; + explorerStore?: ExplorerStore; + match?: { + params: { + id: string, + } + } +} + +@inject("nodeStore") +@inject("explorerStore") +@observer +export class ExplorerAddressQueryResult extends React.Component<Props, any> { + + componentDidMount() { + this.props.explorerStore.resetSearch(); + this.props.explorerStore.searchAddress(this.props.match.params.id); + } + + getSnapshotBeforeUpdate(prevProps: Props, prevState) { + if (prevProps.match.params.id !== this.props.match.params.id) { + this.props.explorerStore.searchAddress(this.props.match.params.id); + } + return null; + } + + render() { + let {id} = this.props.match.params; + let {addr, query_loading, query_err} = this.props.explorerStore; + let outputs = []; + let available_balances = []; + let total_balance = new Map(); + + let get_balances = function (balances) { + if (balances.length == 0) { + return "empty"; + } + return balances; + } + + if (query_err) { + return ( + <Container> + <h3>Address not available - 404</h3> + <p> + Address {id} not found. + </p> + </Container> + ); + } + + if (addr) { + for (let i = 0; i < addr.output_ids.length; i++) { + let output = addr.output_ids[i]; + + let consumed = "Spent: "; + let conflicting = "Conflicting: false"; + if (output.consumer_count) { + consumed += "true"; + if (output.consumer_count > 1) { + conflicting = "Conflicting: true"; + } + } else { + consumed += "false"; + } + + let status = "Status: "; + if (output.inclusion_state.confirmed) { + status += ' confirmed '; + } else if (output.inclusion_state.rejected) { + status += ' rejected '; + } else { + status += ' pending '; + } + + let balances = []; + for (let j=0; j < addr.output_ids[i].balances.length; j++) { + let balance = addr.output_ids[i].balances[j] + + let oldBalance = 0; + if (total_balance.has(balance.color)) { + oldBalance = total_balance.get(balance.color); + } + if (addr.output_ids[i].consumer_count == 0 && addr.output_ids[i].inclusion_state.confirmed) { + total_balance.set(balance.color, balance.value + oldBalance); + } + + balances.push( + <ListGroup.Item key={balance.color}> + <small> + {'Color:'} {balance.color} {' Value:'} {balance.value} + </small> + </ListGroup.Item> + ) + } + + outputs.push( + <ListGroup.Item key={output.id}> + <small> + <div>{'Output ID:'} {output.id} {' '}</div> + {output.solidification_time != 0 && + <div>Solidification Time: {dateformat(new Date(output.solidification_time * 1000), "dd.mm.yyyy HH:MM:ss")}</div> + } + <div>{status}</div> + <div>{consumed}</div> + <div>{conflicting}</div> + <div>{'Balance:'} {balances}</div> + </small> + </ListGroup.Item> + ); + } + + total_balance.forEach((balance: number, color: string) => { + available_balances.push( + <ListGroup.Item key={color}> + {'Color:'} {color} {' Value:'} {balance} + </ListGroup.Item> + ) + }); + } + return ( + <Container> + <h3>Address {addr !== null && <span>({addr.output_ids.length} Ouputs)</span>}</h3> + <p> + {id} {' '} + </p> + { + addr !== null ? + <React.Fragment> + { + addr.output_ids !== null && addr.output_ids.length === 100 && + <Alert variant={"warning"}> + Max. 100 outputs are shown. + </Alert> + } + <Row className={"mb-3"}> + <Col> + <ListGroup> + {"Available balances:"} {get_balances(available_balances)} + </ListGroup> + </Col> + </Row> + <Row className={"mb-3"}> + <Col> + <ListGroup variant={"flush"}> + {"Outputs detail:"} {outputs} + </ListGroup> + </Col> + </Row> + </React.Fragment> + : + <Row className={"mb-3"}> + <Col> + {query_loading && <Spinner animation="border"/>} + </Col> + </Row> + } + + </Container> + ); + } +} diff --git a/plugins/spa/frontend/src/app/components/ExplorerLiveFeed.tsx b/plugins/dashboard/frontend/src/app/components/ExplorerLiveFeed.tsx similarity index 84% rename from plugins/spa/frontend/src/app/components/ExplorerLiveFeed.tsx rename to plugins/dashboard/frontend/src/app/components/ExplorerLiveFeed.tsx index 5da8e96dff013957da845d840ca42e1cb87ab386..5af0a39c56cd49c16a62f67dd840fa9c843eecce 100644 --- a/plugins/spa/frontend/src/app/components/ExplorerLiveFeed.tsx +++ b/plugins/dashboard/frontend/src/app/components/ExplorerLiveFeed.tsx @@ -17,7 +17,7 @@ interface Props { @observer export class ExplorerLiveFeed extends React.Component<Props, any> { render() { - let {txsLiveFeed} = this.props.explorerStore; + let {msgsLiveFeed} = this.props.explorerStore; return ( <Row className={"mb-3"}> <Col> @@ -26,16 +26,16 @@ export class ExplorerLiveFeed extends React.Component<Props, any> { <Card.Title>Live Feed</Card.Title> <Row className={"mb-3"}> <Col xs={12}> - <h6>Transactions</h6> + <h6>Messages</h6> <Table> <thead> <tr> - <td>Hash</td> + <td>Id</td> <td>Value</td> </tr> </thead> <tbody> - {txsLiveFeed} + {msgsLiveFeed} </tbody> </Table> </Col> diff --git a/plugins/dashboard/frontend/src/app/components/ExplorerMessageQueryResult.tsx b/plugins/dashboard/frontend/src/app/components/ExplorerMessageQueryResult.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d1a6b71e594945102794c04acd4233bc0a2ee37e --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/ExplorerMessageQueryResult.tsx @@ -0,0 +1,201 @@ +import * as React from 'react'; +import Container from "react-bootstrap/Container"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import NodeStore from "app/stores/NodeStore"; +import {inject, observer} from "mobx-react"; +import ExplorerStore, {GenesisMessageID} from "app/stores/ExplorerStore"; +import Spinner from "react-bootstrap/Spinner"; +import ListGroup from "react-bootstrap/ListGroup"; +import Badge from "react-bootstrap/Badge"; +import * as dateformat from 'dateformat'; +import {Link} from 'react-router-dom'; +import {BasicPayload} from 'app/components/BasicPayload' +import {DrngPayload} from 'app/components/DrngPayload' +import {ValuePayload} from 'app/components/ValuePayload' +import {PayloadType} from 'app/misc/Payload' + +interface Props { + nodeStore?: NodeStore; + explorerStore?: ExplorerStore; + match?: { + params: { + id: string, + } + } +} + +@inject("nodeStore") +@inject("explorerStore") +@observer +export class ExplorerMessageQueryResult extends React.Component<Props, any> { + + componentDidMount() { + this.props.explorerStore.resetSearch(); + this.props.explorerStore.searchMessage(this.props.match.params.id); + } + + componentWillUnmount() { + this.props.explorerStore.reset(); + } + + getSnapshotBeforeUpdate(prevProps: Props, prevState) { + if (prevProps.match.params.id !== this.props.match.params.id) { + this.props.explorerStore.searchMessage(this.props.match.params.id); + } + return null; + } + + getPayloadType() { + switch (this.props.explorerStore.msg.payload_type) { + case PayloadType.Data: + return "Data" + case PayloadType.Value: + return "Value" + case PayloadType.Drng: + return "Drng" + case PayloadType.Faucet: + return "Faucet" + default: + return "Unknown" + } + } + + renderPayload() { + switch (this.props.explorerStore.msg.payload_type) { + case PayloadType.Drng: + return <DrngPayload/> + case PayloadType.Value: + return <ValuePayload/> + case PayloadType.Data: + case PayloadType.Faucet: + default: + return <BasicPayload/> + } + } + + render() { + let {id} = this.props.match.params; + let {msg, query_loading, query_err} = this.props.explorerStore; + + if (id === GenesisMessageID) { + return ( + <Container> + <h3>Genesis Message</h3> + <p>In the beginning there was the genesis.</p> + </Container> + ); + } + + if (query_err) { + return ( + <Container> + <h3>Message not available - 404</h3> + <p> + Message with ID {id} not found. + </p> + </Container> + ); + } + + return ( + <Container> + <h3>Message</h3> + <p> + {id} {' '} + { + msg && + <React.Fragment> + <br/> + <span> + <Badge variant="light" style={{marginRight: 10}}> + Issuance Time: {dateformat(new Date(msg.issuance_timestamp * 1000), "dd.mm.yyyy HH:MM:ss")} + </Badge> + <Badge variant="light"> + Solidification Time: {dateformat(new Date(msg.solidification_timestamp * 1000), "dd.mm.yyyy HH:MM:ss")} + </Badge> + </span> + </React.Fragment> + } + </p> + { + msg && + <React.Fragment> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item> + Payload Type: {this.getPayloadType()} + </ListGroup.Item> + <ListGroup.Item> + Sequence Number: {msg.sequence_number} + </ListGroup.Item> + <ListGroup.Item> + Solid: {msg.solid ? 'Yes' : 'No'} + </ListGroup.Item> + </ListGroup> + </Col> + </Row> + + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item> + Issuer Public Key: {msg.issuer_public_key} + </ListGroup.Item> + <ListGroup.Item> + Message Signature: {msg.signature} + </ListGroup.Item> + </ListGroup> + </Col> + </Row> + + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item className="text-break"> + Parent 1 Message ID: {' '} + <Link to={`/explorer/message/${msg.trunk_message_id}`}> + {msg.trunk_message_id} + </Link> + </ListGroup.Item> + </ListGroup> + </Col> + <Col> + <ListGroup> + <ListGroup.Item className="text-break"> + Parent 2 Message ID: {' '} + <Link to={`/explorer/message/${msg.branch_message_id}`}> + {msg.branch_message_id} + </Link> + </ListGroup.Item> + </ListGroup> + </Col> + </Row> + + <Row className={"mb-3"}> + <Col> + <h4>Payload</h4> + </Col> + </Row> + + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item className="text-break"> + {this.renderPayload()} + </ListGroup.Item> + </ListGroup> + </Col> + </Row> + </React.Fragment> + } + <Row className={"mb-3"}> + <Col> + {query_loading && <Spinner animation="border"/>} + </Col> + </Row> + </Container> + ); + } +} diff --git a/plugins/spa/frontend/src/app/components/ExplorerSearchbar.tsx b/plugins/dashboard/frontend/src/app/components/ExplorerSearchbar.tsx similarity index 88% rename from plugins/spa/frontend/src/app/components/ExplorerSearchbar.tsx rename to plugins/dashboard/frontend/src/app/components/ExplorerSearchbar.tsx index 85bf7aabab959ed193c6a68414f326611577c575..3840abd342331829ed281dcc981a9de3d1e6fe6b 100644 --- a/plugins/spa/frontend/src/app/components/ExplorerSearchbar.tsx +++ b/plugins/dashboard/frontend/src/app/components/ExplorerSearchbar.tsx @@ -36,8 +36,8 @@ export class ExplorerSearchbar extends React.Component<Props, any> { <Col> <InputGroup className="mb-3"> <FormControl - placeholder="Address- or transaction hash" - aria-label="Address- or transaction hash" + placeholder="Address or message id" + aria-label="Address message id" aria-describedby="basic-addon1" value={search} onChange={this.updateSearch} onKeyUp={this.executeSearch} diff --git a/plugins/dashboard/frontend/src/app/components/Faucet.tsx b/plugins/dashboard/frontend/src/app/components/Faucet.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a6ebd10d7aefd70a736080d5b08fb362f3704e63 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/Faucet.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import Container from "react-bootstrap/Container"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import NodeStore from "app/stores/NodeStore"; +import {inject, observer} from "mobx-react"; +import {FaucetAddressInput} from "app/components/FaucetAddressInput"; + +interface Props { + nodeStore?: NodeStore; +} + +@inject("nodeStore") +@observer +export class Faucet extends React.Component<Props, any> { + render() { + return ( + <Container> + <h3>GoShimmer Faucet</h3> + <Row className={"mb-3"}> + <Col> + <p> + Get tokens from the GoShimmer faucet! + </p> + </Col> + </Row> + <FaucetAddressInput/> + </Container> + ); + } +} diff --git a/plugins/dashboard/frontend/src/app/components/FaucetAddressInput.tsx b/plugins/dashboard/frontend/src/app/components/FaucetAddressInput.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a5378c4c8fa7a2787b82ce69fdbea07ea422db71 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/FaucetAddressInput.tsx @@ -0,0 +1,81 @@ +import * as React from 'react'; +import {KeyboardEvent} from 'react'; +import NodeStore from "app/stores/NodeStore"; +import FaucetStore from "app/stores/FaucetStore"; +import {inject, observer} from "mobx-react"; +import FormControl from "react-bootstrap/FormControl"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Button from 'react-bootstrap/Button' +import InputGroup from "react-bootstrap/InputGroup"; + +interface Props { + nodeStore?: NodeStore; + faucetStore?: FaucetStore; +} + +@inject("nodeStore") +@inject("faucetStore") +@observer +export class FaucetAddressInput extends React.Component<Props, any> { + + componentWillUnmount() { + this.props.faucetStore.reset(); + } + + updateSend = (e) => { + this.props.faucetStore.updateSend(e.target.value); + }; + + executeSend = (e: KeyboardEvent) => { + if (e.key !== 'Enter') return; + this.props.faucetStore.sendReq(); + }; + + btnExecuteSend = () => { + this.props.faucetStore.sendReq(); + }; + + render() { + let {send_addr, query_error, sending} = this.props.faucetStore; + + return ( + <React.Fragment> + <Row className={"mb-3"}> + <Col> + <InputGroup className="mb-3"> + <FormControl + placeholder="Address" + aria-label="Address" + aria-describedby="basic-addon1" + value={send_addr} onChange={this.updateSend} + onKeyUp={this.executeSend} + disabled={sending} + /> + </InputGroup> + </Col> + </Row> + <Row className={"mb-3"}> + <Col> + <Button + variant="primary" + size="sm" block + onClick={this.btnExecuteSend} + value={send_addr} + disabled={sending}> + Send + </Button> + </Col> + </Row> + { + query_error !== "" && + <Row className={"mb-3"}> + <Col> + Couldn't request funds: {query_error} + </Col> + </Row> + } + </React.Fragment> + ); + } +} diff --git a/plugins/spa/frontend/src/app/components/TPSChart.tsx b/plugins/dashboard/frontend/src/app/components/MPSChart.tsx similarity index 83% rename from plugins/spa/frontend/src/app/components/TPSChart.tsx rename to plugins/dashboard/frontend/src/app/components/MPSChart.tsx index b19beb2345bea07bc28f4c20c46cbfe727a2b993..3491bb200b5653c64c1f3fc9118a314abb577bd8 100644 --- a/plugins/spa/frontend/src/app/components/TPSChart.tsx +++ b/plugins/dashboard/frontend/src/app/components/MPSChart.tsx @@ -49,17 +49,17 @@ const lineChartOptions = Object.assign({ @inject("nodeStore") @observer -export default class TPSChart extends React.Component<Props, any> { +export default class MPSChart extends React.Component<Props, any> { render() { return ( <Card> <Card.Body> - <Card.Title>Transactions Per Second</Card.Title> + <Card.Title>Messages Per Second</Card.Title> <small> - TPS: {this.props.nodeStore.last_tps_metric.tps}. + MPS: {this.props.nodeStore.last_mps_metric.mps}. </small> - <Line height={50} data={this.props.nodeStore.tpsSeries} options={lineChartOptions}/> + <Line height={50} data={this.props.nodeStore.mpsSeries} options={lineChartOptions}/> </Card.Body> </Card> ); diff --git a/plugins/spa/frontend/src/app/components/MemChart.tsx b/plugins/dashboard/frontend/src/app/components/MemChart.tsx similarity index 100% rename from plugins/spa/frontend/src/app/components/MemChart.tsx rename to plugins/dashboard/frontend/src/app/components/MemChart.tsx diff --git a/plugins/spa/frontend/src/app/components/NavExplorerSearchbar.tsx b/plugins/dashboard/frontend/src/app/components/NavExplorerSearchbar.tsx similarity index 100% rename from plugins/spa/frontend/src/app/components/NavExplorerSearchbar.tsx rename to plugins/dashboard/frontend/src/app/components/NavExplorerSearchbar.tsx diff --git a/plugins/spa/frontend/src/app/components/Neighbor.tsx b/plugins/dashboard/frontend/src/app/components/Neighbor.tsx similarity index 100% rename from plugins/spa/frontend/src/app/components/Neighbor.tsx rename to plugins/dashboard/frontend/src/app/components/Neighbor.tsx diff --git a/plugins/spa/frontend/src/app/components/Neighbors.tsx b/plugins/dashboard/frontend/src/app/components/Neighbors.tsx similarity index 100% rename from plugins/spa/frontend/src/app/components/Neighbors.tsx rename to plugins/dashboard/frontend/src/app/components/Neighbors.tsx diff --git a/plugins/spa/frontend/src/app/components/Root.tsx b/plugins/dashboard/frontend/src/app/components/Root.tsx similarity index 74% rename from plugins/spa/frontend/src/app/components/Root.tsx rename to plugins/dashboard/frontend/src/app/components/Root.tsx index f61f447b1290879e0d8430621b159c635a77d7c4..e319bb932f94ac7f90c5a51bff2eb98861aad7c6 100644 --- a/plugins/spa/frontend/src/app/components/Root.tsx +++ b/plugins/dashboard/frontend/src/app/components/Root.tsx @@ -10,10 +10,12 @@ import {Explorer} from "app/components/Explorer"; import {NavExplorerSearchbar} from "app/components/NavExplorerSearchbar"; import {Redirect, Route, Switch} from 'react-router-dom'; import {LinkContainer} from 'react-router-bootstrap'; -import {ExplorerTransactionQueryResult} from "app/components/ExplorerTransactionQueryResult"; +import {ExplorerMessageQueryResult} from "app/components/ExplorerMessageQueryResult"; import {ExplorerAddressQueryResult} from "app/components/ExplorerAddressResult"; import {Explorer404} from "app/components/Explorer404"; +import {Faucet} from "app/components/Faucet"; import {Neighbors} from "app/components/Neighbors"; +import {Visualizer} from "app/components/Visualizer"; interface Props { history: any; @@ -50,7 +52,17 @@ export class Root extends React.Component<Props, any> { </LinkContainer> <LinkContainer to="/explorer"> <Nav.Link> - Tangle Explorer + Explorer + </Nav.Link> + </LinkContainer> + <LinkContainer to="/visualizer"> + <Nav.Link> + Visualizer + </Nav.Link> + </LinkContainer> + <LinkContainer to="/faucet"> + <Nav.Link> + Faucet </Nav.Link> </LinkContainer> </Nav> @@ -66,10 +78,12 @@ export class Root extends React.Component<Props, any> { <Switch> <Route exact path="/dashboard" component={Dashboard}/> <Route exact path="/neighbors" component={Neighbors}/> - <Route exact path="/explorer/tx/:hash" component={ExplorerTransactionQueryResult}/> - <Route exact path="/explorer/addr/:hash" component={ExplorerAddressQueryResult}/> + <Route exact path="/explorer/message/:id" component={ExplorerMessageQueryResult}/> + <Route exact path="/explorer/address/:id" component={ExplorerAddressQueryResult}/> <Route exact path="/explorer/404/:search" component={Explorer404}/> <Route exact path="/explorer" component={Explorer}/> + <Route exact path="/visualizer" component={Visualizer}/> + <Route exact path="/faucet" component={Faucet}/> <Redirect to="/dashboard"/> </Switch> {this.props.children} diff --git a/plugins/dashboard/frontend/src/app/components/TipsChart.tsx b/plugins/dashboard/frontend/src/app/components/TipsChart.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a5dcbc865c84c78cae5aa29f033410f8c0ca28bb --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/TipsChart.tsx @@ -0,0 +1,67 @@ +import * as React from 'react'; +import Card from "react-bootstrap/Card"; +import NodeStore from "app/stores/NodeStore"; +import {inject, observer} from "mobx-react"; +import {Line} from "react-chartjs-2"; +import {defaultChartOptions} from "app/misc/Chart"; + +interface Props { + nodeStore?: NodeStore; +} + +const lineChartOptions = Object.assign({ + scales: { + xAxes: [{ + ticks: { + autoSkip: true, + maxTicksLimit: 8, + fontSize: 8, + minRotation: 0, + maxRotation: 0, + }, + gridLines: { + display: false + } + }], + yAxes: [{ + gridLines: { + display: false + }, + ticks: { + callback: function (value, index, values) { + return Math.abs(value); + }, + fontSize: 10, + maxTicksLimit: 4, + beginAtZero: true, + }, + }], + }, + tooltips: { + callbacks: { + label: function (tooltipItem, data) { + let label = data.datasets[tooltipItem.datasetIndex].label; + return `${label} ${Math.abs(tooltipItem.value)}`; + } + } + } +}, defaultChartOptions); + +@inject("nodeStore") +@observer +export default class TipsChart extends React.Component<Props, any> { + render() { + return ( + <Card> + <Card.Body> + <Card.Title>Current Tips</Card.Title> + <small> + Tips: {this.props.nodeStore.last_tips_metric.tips}. + </small> + + <Line height={50} data={this.props.nodeStore.tipsSeries} options={lineChartOptions}/> + </Card.Body> + </Card> + ); + } +} diff --git a/plugins/spa/frontend/src/app/components/Uptime.tsx b/plugins/dashboard/frontend/src/app/components/Uptime.tsx similarity index 100% rename from plugins/spa/frontend/src/app/components/Uptime.tsx rename to plugins/dashboard/frontend/src/app/components/Uptime.tsx diff --git a/plugins/dashboard/frontend/src/app/components/ValuePayload.tsx b/plugins/dashboard/frontend/src/app/components/ValuePayload.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c3c667c9e1ebf5dd5db56278f5305870b580950d --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/ValuePayload.tsx @@ -0,0 +1,143 @@ +import * as React from 'react'; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Badge from "react-bootstrap/Badge" +import ListGroup from "react-bootstrap/ListGroup"; +import {Link} from 'react-router-dom'; +import {inject, observer} from "mobx-react"; +import {ExplorerStore} from "app/stores/ExplorerStore"; +import {IconContext} from "react-icons" +import {FaChevronCircleRight} from "react-icons/fa" + +interface Props { + explorerStore?: ExplorerStore; +} + +interface OutputProps { + address: string; + balances?: BalanceProps +} + +interface BalanceProps { + value: number; + color: string; +} + +@inject("explorerStore") +@observer +export class ValuePayload extends React.Component<Props, any> { + + render() { + let {payload} = this.props.explorerStore; + + return ( + payload && + <React.Fragment> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Parent 0: {payload.parent_id_0} </ListGroup.Item> + </ListGroup> + </Col> + <Col> + <ListGroup> + <ListGroup.Item>Parent 1: {payload.parent_id_1} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Transaction ID: {payload.tx_id} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + <Row className={"mb-3"}> + <Col> + <div style={{ + marginBottom: "20px", + paddingBottom: "10px", + borderBottom: "2px solid #eee"}}>Inputs:</div> + <React.Fragment> + { + payload.inputs.map(input => ( + <Inputs address={input.address} key={input.address}/> + ))} + </React.Fragment> + </Col> + <Col md="auto"> + <IconContext.Provider value={{ color: "#00a0ff", size: "2em"}}> + <div style={{ + marginTop: "40px"}}> + <FaChevronCircleRight /> + </div> + </IconContext.Provider> + </Col> + <Col> + <div style={{ + marginBottom: "20px", + paddingBottom: "10px", + borderBottom: "2px solid #eee"}}>Outputs:</div> + <React.Fragment> + { + payload.outputs.map(output => ( + output.balance.map(balance => ( + <Outputs key={balance.value} + address={output.address} + balances={balance} /> + )) + ))} + </React.Fragment> + </Col> + </Row> + { + payload.data && + <Row className={"mb-3"}> + <Col> + <ListGroup> + <ListGroup.Item>Data: {payload.data} </ListGroup.Item> + </ListGroup> + </Col> + </Row> + } + </React.Fragment> + ); + } +} + +class Inputs extends React.Component<OutputProps> { + render() { + return ( + <Row className={"mb-3"}> + <Col> + <div> + <Link to={`/explorer/address/${this.props.address}`}> + {this.props.address} + </Link> + </div> + </Col> + </Row> + ); + } +} + +class Outputs extends React.Component<OutputProps> { + render() { + return ( + <Row className={"mb-3"}> + <Col> + <div> + <Link to={`/explorer/address/${this.props.address}`}> + {this.props.address} + </Link> + </div> + <div> + <Badge variant="success"> + {this.props.balances.value}{' '}{this.props.balances.color} + </Badge> + </div> + </Col> + </Row> + ); + } +} diff --git a/plugins/spa/frontend/src/app/components/Version.tsx b/plugins/dashboard/frontend/src/app/components/Version.tsx similarity index 100% rename from plugins/spa/frontend/src/app/components/Version.tsx rename to plugins/dashboard/frontend/src/app/components/Version.tsx diff --git a/plugins/dashboard/frontend/src/app/components/Visualizer.tsx b/plugins/dashboard/frontend/src/app/components/Visualizer.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8cab0b5e70cf87c61ced578479c5b7a595a67037 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/components/Visualizer.tsx @@ -0,0 +1,187 @@ +import * as React from 'react'; +import {KeyboardEvent} from 'react'; +import Container from "react-bootstrap/Container"; +import {inject, observer} from "mobx-react"; +import {Link} from 'react-router-dom'; +import VisualizerStore from "app/stores/VisualizerStore"; +import NodeStore from "app/stores/NodeStore"; +import Badge from "react-bootstrap/Badge"; +import FormControl from "react-bootstrap/FormControl"; +import InputGroup from "react-bootstrap/InputGroup"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Button from "react-bootstrap/Button"; +import Popover from "react-bootstrap/Popover"; +import OverlayTrigger from "react-bootstrap/OverlayTrigger"; + +interface Props { + visualizerStore?: VisualizerStore; + nodeStore?: NodeStore; +} + +@inject("visualizerStore") +@inject("nodeStore") +@observer +export class Visualizer extends React.Component<Props, any> { + + componentDidMount(): void { + this.props.visualizerStore.start(); + } + + componentWillUnmount(): void { + this.props.visualizerStore.stop(); + this.props.nodeStore.registerHandlers(); + } + + updateVerticesLimit = (e) => { + this.props.visualizerStore.updateVerticesLimit(e.target.value); + } + + pauseResumeVisualizer = (e) => { + this.props.visualizerStore.pauseResume(); + } + + updateSearch = (e) => { + this.props.visualizerStore.updateSearch(e.target.value); + } + + searchAndHighlight = (e: KeyboardEvent) => { + if (e.key !== 'Enter') return; + this.props.visualizerStore.searchAndHighlight(); + } + + toggleBackgroundDataCollection = () => { + if (this.props.nodeStore.collecting) { + this.props.nodeStore.unregisterHandlers(); + return; + } + this.props.nodeStore.registerHandlers(); + } + + render() { + let { + vertices, solid_count, selected, + selected_approvers_count, selected_approvees_count, + verticesLimit, tips_count, paused, search + } = this.props.visualizerStore; + let {last_mps_metric, collecting} = this.props.nodeStore; + + return ( + <Container> + <h3>Visualizer</h3> + <Row className={"mb-1"}> + <Col xs={5}> + <InputGroup className="mb-1" size="sm"> + <InputGroup.Prepend> + <InputGroup.Text id="vertices-limit">Vertices Limit</InputGroup.Text> + </InputGroup.Prepend> + <FormControl + placeholder="limit" + type="number" value={verticesLimit.toString()} onChange={this.updateVerticesLimit} + aria-label="vertices-limit" + aria-describedby="vertices-limit" + /> + </InputGroup> + <InputGroup className="mb-1" size="sm"> + <InputGroup.Prepend> + <InputGroup.Text id="vertices-limit"> + Search Vertex + </InputGroup.Text> + </InputGroup.Prepend> + <FormControl + placeholder="search" + type="text" value={search} onChange={this.updateSearch} + aria-label="vertices-search" onKeyUp={this.searchAndHighlight} + aria-describedby="vertices-search" + /> + </InputGroup> + <InputGroup className="mb-1" size="sm"> + <OverlayTrigger + trigger={['hover', 'focus']} placement="right" overlay={ + <Popover id="popover-basic"> + <Popover.Content> + Ensures that only data needed for the visualizer is collected. + </Popover.Content> + </Popover>} + > + <Button variant="outline-secondary" onClick={this.toggleBackgroundDataCollection} + size="sm"> + {collecting ? "Stop Background Data Collection" : "Collect Background data"} + </Button> + </OverlayTrigger> + <br/> + </InputGroup> + <InputGroup className="mb-1" size="sm"> + <OverlayTrigger + trigger={['hover', 'focus']} placement="right" overlay={ + <Popover id="popover-basic"> + <Popover.Content> + Pauses/resumes rendering the graph. + </Popover.Content> + </Popover>} + > + <Button onClick={this.pauseResumeVisualizer} size="sm" variant="outline-secondary"> + {paused ? "Resume Rendering" : "Pause Rendering"} + </Button> + </OverlayTrigger> + </InputGroup> + </Col> + <Col xs={{span: 5, offset: 2}}> + <p> + <Badge pill style={{background: "#6c71c4", color: "white"}}> + Solid + </Badge> + {' '} + <Badge pill style={{background: "#2aa198", color: "white"}}> + Unsolid + </Badge> + {' '} + <Badge pill style={{background: "#cb4b16", color: "white"}}> + Tip + </Badge> + {' '} + <Badge pill style={{background: "#b58900", color: "white"}}> + Unknown + </Badge> + <br/> + Vertices: {vertices.size}, Tips: {tips_count}, + Solid/Unsolid: {solid_count}/{vertices.size - solid_count},{' '} + MPS: {last_mps_metric.mps} + <br/> + Selected: {selected ? + <Link to={`/explorer/message/${selected.id}`}> + {selected.id.substr(0, 10)} + </Link> + : "-"} + <br/> + Approvers/Approvees: {selected ? + <span>{selected_approvers_count}/{selected_approvees_count}</span> + : '-/-'} + <br/> + Trunk/Branch:{' '} + { + selected && selected.trunk_id && selected.branch_id ? + <span> + <Link to={` / explorer / message /${selected.trunk_id}`}> + {selected.trunk_id.substr(0, 10)} + </Link> + / + <Link to={` / explorer / message /${selected.branch_id}`}> + {selected.branch_id.substr(0, 10)} + </Link> + </span> + : "-"} + </p> + </Col> + </Row> + <div className={"visualizer"} style={{ + zIndex: -1, position: "absolute", + top: 0, left: 0, + width: "100%", + height: "100%", + background: "#ededed" + }} id={"visualizer"}/> + </Container> + ); + } +} diff --git a/plugins/spa/frontend/src/app/misc/Chart.ts b/plugins/dashboard/frontend/src/app/misc/Chart.ts similarity index 100% rename from plugins/spa/frontend/src/app/misc/Chart.ts rename to plugins/dashboard/frontend/src/app/misc/Chart.ts diff --git a/plugins/dashboard/frontend/src/app/misc/Payload.ts b/plugins/dashboard/frontend/src/app/misc/Payload.ts new file mode 100644 index 0000000000000000000000000000000000000000..bbb8923a80bc0a45a14977d1d5f73fefada2cfd2 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/misc/Payload.ts @@ -0,0 +1,56 @@ +export enum PayloadType { + Data = 0, + Value = 1, + Faucet = 2, + Drng = 111, +} + +export enum DrngSubtype { + Default = 0, + Cb = 1, +} + +// BasicPayload +export class BasicPayload { + content_title: string; + content: string; +} + +// DrngPayload +export class DrngPayload { + subpayload_type: string; + instance_id: number; + drngpayload: any; +} + +export class DrngCbPayload { + round: number; + prev_sig: string; + sig: string; + dpk: string; +} + +// Value payload +export class ValuePayload { + payload_id: string; + parent_id_0: string; + parent_id_1: string; + tx_id: string; + inputs: Array<Inputs>; + outputs: Array<Outputs>; + data: string; +} + +export class Inputs { + address: string; +} + +export class Outputs { + address: string; + balance: Array<Balance>; +} + +export class Balance { + value: number; + color: string; +} diff --git a/plugins/spa/frontend/src/app/misc/WS.ts b/plugins/dashboard/frontend/src/app/misc/WS.ts similarity index 78% rename from plugins/spa/frontend/src/app/misc/WS.ts rename to plugins/dashboard/frontend/src/app/misc/WS.ts index e3f442bfea2eb99cae08eb609a5e22b1521b6226..f29a52ec747c103aa34b4add71afa34ca9dc11ec 100644 --- a/plugins/spa/frontend/src/app/misc/WS.ts +++ b/plugins/dashboard/frontend/src/app/misc/WS.ts @@ -1,8 +1,12 @@ export enum WSMsgType { Status, - TPSMetrics, - Tx, + MPSMetrics, + Message, NeighborStats, + Drng, + TipsMetrics, + Vertex, + TipInfo, } export interface WSMessage { @@ -18,6 +22,10 @@ export function registerHandler(msgTypeID: number, handler: DataHandler) { handlers[msgTypeID] = handler; } +export function unregisterHandler(msgTypeID: number) { + delete handlers[msgTypeID]; +} + export function connectWebSocket(path: string, onOpen, onClose, onError) { let loc = window.location; let uri = 'ws:'; @@ -41,4 +49,4 @@ export function connectWebSocket(path: string, onOpen, onClose, onError) { } handler(msg.data); }; -} \ No newline at end of file +} diff --git a/plugins/dashboard/frontend/src/app/stores/DrngStore.tsx b/plugins/dashboard/frontend/src/app/stores/DrngStore.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c7175d6086029dd3bea9cf6351e147a85848ad89 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/stores/DrngStore.tsx @@ -0,0 +1,72 @@ +import {action, computed, observable} from 'mobx'; +import {registerHandler, WSMsgType} from "app/misc/WS"; +import * as React from "react"; +import {RouterStore} from "mobx-react-router"; + +export class DrngMessage { + instance: number; + dpk: string; + round: number; + randomness: string; + timestamp: string; +} + +const liveFeedSize = 10; + +export class DrngStore { + // live feed + @observable latest_msgs: Array<DrngMessage> = []; + + // queries + @observable msg: DrngMessage = null; + + // loading + @observable query_loading: boolean = false; + @observable query_err: any = null; + + routerStore: RouterStore; + + constructor(routerStore: RouterStore) { + this.routerStore = routerStore; + registerHandler(WSMsgType.Drng, this.addLiveFeed); + } + + @action + addLiveFeed = (msg: DrngMessage) => { + // prevent duplicates (should be fast with only size 10) + if (this.latest_msgs.findIndex((t) => t.round == msg.round) === -1) { + if (this.latest_msgs.length >= liveFeedSize) { + this.latest_msgs.shift(); + } + this.latest_msgs.push(msg); + } + }; + + @computed + get msgsLiveFeed() { + let feed = []; + for (let i = this.latest_msgs.length - 1; i >= 0; i--) { + let msg = this.latest_msgs[i]; + feed.push( + <tr key={msg.round}> + <td> + {msg.instance} + </td> + <td> + {msg.round} + </td> + <td> + {msg.randomness} + </td> + <td> + {msg.timestamp} + </td> + </tr> + ); + } + return feed; + } + +} + +export default DrngStore; \ No newline at end of file diff --git a/plugins/spa/frontend/src/app/stores/ExplorerStore.tsx b/plugins/dashboard/frontend/src/app/stores/ExplorerStore.tsx similarity index 51% rename from plugins/spa/frontend/src/app/stores/ExplorerStore.tsx rename to plugins/dashboard/frontend/src/app/stores/ExplorerStore.tsx index 4cc4149a1ac07ae2b7bd55388ae6fd05ddf42320..82cc54755820000fd4c70d9c59d6802ec4e609d7 100644 --- a/plugins/spa/frontend/src/app/stores/ExplorerStore.tsx +++ b/plugins/dashboard/frontend/src/app/stores/ExplorerStore.tsx @@ -1,50 +1,73 @@ import {action, computed, observable} from 'mobx'; import {registerHandler, WSMsgType} from "app/misc/WS"; +import {BasicPayload, DrngCbPayload, DrngPayload, DrngSubtype, PayloadType, ValuePayload} from "app/misc/Payload"; import * as React from "react"; import {Link} from 'react-router-dom'; import {RouterStore} from "mobx-react-router"; -export class Transaction { - hash: string; - signature_message_fragment: string; - address: string; - value: number; - timestamp: number; - trunk: string; - branch: string; +export const GenesisMessageID = "1111111111111111111111111111111111111111111111111111111111111111"; + +export class Message { + id: string; + solidification_timestamp: number; + issuance_timestamp: number; + sequence_number: number; + issuer_public_key: string; + signature: string; + trunk_message_id: string; + branch_message_id: string; solid: boolean; + payload_type: number; + payload: any; } class AddressResult { - balance: number; - txs: Array<Transaction>; - spent: boolean; + address: string; + output_ids: Array<Output>; +} + +class Output { + id: string; + balances: Array<Balance>; + inclusion_state: InclusionState; + consumer_count: number; + solidification_time: number; +} + +class Balance { + value: number; + color: string; +} + +class InclusionState { + liked: boolean; + rejected: boolean; + finalized: boolean; + conflicting: boolean; + confirmed: boolean; } class SearchResult { - tx: Transaction; + message: MessageRef; address: AddressResult; - milestone: Transaction; - bundles: Array<Array<Transaction>>; } -class Tx { - hash: string; - value: number; +class MessageRef { + id: string; } const liveFeedSize = 10; enum QueryError { - NotFound + NotFound = 1 } export class ExplorerStore { // live feed - @observable latest_txs: Array<Tx> = []; + @observable latest_messages: Array<MessageRef> = []; // queries - @observable tx: Transaction = null; + @observable msg: Message = null; @observable addr: AddressResult = null; // loading @@ -55,12 +78,14 @@ export class ExplorerStore { @observable search: string = ""; @observable search_result: SearchResult = null; @observable searching: boolean = false; + @observable payload: any; + @observable subpayload: any; routerStore: RouterStore; constructor(routerStore: RouterStore) { this.routerStore = routerStore; - registerHandler(WSMsgType.Tx, this.addLiveFeedTx); + registerHandler(WSMsgType.Message, this.addLiveFeedMessage); } searchAny = async () => { @@ -86,16 +111,12 @@ export class ExplorerStore { this.searching = false; let search = this.search; this.search = ''; - if (this.search_result.tx) { - this.routerStore.push(`/explorer/tx/${search}`); - return; - } - if (this.search_result.milestone) { - this.routerStore.push(`/explorer/tx/${this.search_result.milestone.hash}`); + if (this.search_result.message) { + this.routerStore.push(`/explorer/message/${search}`); return; } if (this.search_result.address) { - this.routerStore.push(`/explorer/addr/${search}`); + this.routerStore.push(`/explorer/address/${search}`); return; } this.routerStore.push(`/explorer/404/${search}`); @@ -109,25 +130,25 @@ export class ExplorerStore { @action updateSearching = (searching: boolean) => this.searching = searching; - searchTx = async (hash: string) => { + searchMessage = async (id: string) => { this.updateQueryLoading(true); try { - let res = await fetch(`/api/tx/${hash}`); + let res = await fetch(`/api/message/${id}`); if (res.status === 404) { this.updateQueryError(QueryError.NotFound); return; } - let tx: Transaction = await res.json(); - this.updateTx(tx); + let msg: Message = await res.json(); + this.updateMessage(msg); } catch (err) { this.updateQueryError(err); } }; - searchAddress = async (hash: string) => { + searchAddress = async (id: string) => { this.updateQueryLoading(true); try { - let res = await fetch(`/api/addr/${hash}`); + let res = await fetch(`/api/address/${id}`); if (res.status === 404) { this.updateQueryError(QueryError.NotFound); return; @@ -141,25 +162,39 @@ export class ExplorerStore { @action reset = () => { - this.tx = null; + this.msg = null; this.query_err = null; }; @action updateAddress = (addr: AddressResult) => { - addr.txs = addr.txs.sort((a, b) => { - return a.timestamp < b.timestamp ? 1 : -1; - }); this.addr = addr; this.query_err = null; this.query_loading = false; }; @action - updateTx = (tx: Transaction) => { - this.tx = tx; + updateMessage = (msg: Message) => { + this.msg = msg; this.query_err = null; this.query_loading = false; + switch (msg.payload_type) { + case PayloadType.Drng: + this.payload = msg.payload as DrngPayload + if (this.payload.subpayload_type == DrngSubtype.Cb) { + this.subpayload = this.payload.drngpayload as DrngCbPayload + } else { + this.subpayload = this.payload.drngpayload as BasicPayload + } + break; + case PayloadType.Value: + this.payload = msg.payload as ValuePayload + case PayloadType.Data: + case PayloadType.Faucet: + default: + this.payload = msg.payload as BasicPayload + break; + } }; @action @@ -173,31 +208,28 @@ export class ExplorerStore { }; @action - addLiveFeedTx = (tx: Tx) => { + addLiveFeedMessage = (msg: MessageRef) => { // prevent duplicates (should be fast with only size 10) - if (this.latest_txs.findIndex((t) => t.hash == tx.hash) === -1) { - if (this.latest_txs.length >= liveFeedSize) { - this.latest_txs.shift(); + if (this.latest_messages.findIndex((t) => t.id == msg.id) === -1) { + if (this.latest_messages.length >= liveFeedSize) { + this.latest_messages.shift(); } - this.latest_txs.push(tx); + this.latest_messages.push(msg); } }; @computed - get txsLiveFeed() { + get msgsLiveFeed() { let feed = []; - for (let i = this.latest_txs.length - 1; i >= 0; i--) { - let tx = this.latest_txs[i]; + for (let i = this.latest_messages.length - 1; i >= 0; i--) { + let msg = this.latest_messages[i]; feed.push( - <tr key={tx.hash}> + <tr key={msg.id}> <td> - <Link to={`/explorer/tx/${tx.hash}`}> - {tx.hash.substr(0, 35)} + <Link to={`/explorer/message/${msg.id}`}> + {msg.id.substr(0, 35)} </Link> </td> - <td> - {tx.value} - </td> </tr> ); } @@ -206,4 +238,4 @@ export class ExplorerStore { } -export default ExplorerStore; \ No newline at end of file +export default ExplorerStore; diff --git a/plugins/dashboard/frontend/src/app/stores/FaucetStore.ts b/plugins/dashboard/frontend/src/app/stores/FaucetStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..529ffe6dfe95e8dca355cc214be3d043db563982 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/stores/FaucetStore.ts @@ -0,0 +1,75 @@ +import {action, observable} from 'mobx'; +import {RouterStore} from "mobx-react-router"; + +class SendResult { + MsgId: string; +} + +enum QueryError { + NotFound +} + +export class FaucetStore { + // send request to faucet + @observable send_addr: string = ""; + @observable sending: boolean = false; + @observable sendResult: SendResult = null; + @observable query_error: string = ""; + + routerStore: RouterStore; + + constructor(routerStore: RouterStore) { + this.routerStore = routerStore; + } + + sendReq = async () => { + this.updateSending(true); + try { + // send request + let res = await fetch(`/api/faucet/${this.send_addr}`); + if (res.status !== 200) { + this.updateQueryError(QueryError.NotFound); + return; + } + let result: SendResult = await res.json(); + setTimeout(() => { + this.updateSendResult(result); + }, 2000); + } catch (err) { + this.updateQueryError(err); + } + }; + + @action + updateSendResult = (result: SendResult) => { + this.sending = false; + this.sendResult = result; + this.routerStore.history.push(`/explorer/address/${this.send_addr}`); + }; + + @action + updateSend = (send_addr: string) => { + this.send_addr = send_addr; + }; + + @action + updateSending = (sending: boolean) => { + this.sending = sending; + this.query_error = ""; + }; + + @action + reset = () => { + this.send_addr = null; + this.sending = false; + this.query_error = ""; + }; + + @action + updateQueryError = (err: any) => { + this.sending = false; + this.query_error = err; + }; +} + +export default FaucetStore; diff --git a/plugins/spa/frontend/src/app/stores/NodeStore.ts b/plugins/dashboard/frontend/src/app/stores/NodeStore.ts similarity index 69% rename from plugins/spa/frontend/src/app/stores/NodeStore.ts rename to plugins/dashboard/frontend/src/app/stores/NodeStore.ts index 461efb1424b463605cdb95b0d69ad657ea3d6234..8e3bc7b5731a397f1c0772c91f37ed51a8de9d15 100644 --- a/plugins/spa/frontend/src/app/stores/NodeStore.ts +++ b/plugins/dashboard/frontend/src/app/stores/NodeStore.ts @@ -1,9 +1,9 @@ import {action, computed, observable, ObservableMap} from 'mobx'; import * as dateformat from 'dateformat'; -import {connectWebSocket, registerHandler, WSMsgType} from "app/misc/WS"; +import {connectWebSocket, registerHandler, unregisterHandler, WSMsgType} from "app/misc/WS"; -class TPSMetric { - tps: number; +class MPSMetric { + mps: number; ts: string; } @@ -29,6 +29,11 @@ class MemoryMetrics { ts: string; } +class TipsMetric { + tips: number; + ts: string; +} + class NetworkIO { tx: number; rx: number; @@ -150,15 +155,47 @@ const maxMetricsDataPoints = 900; export class NodeStore { @observable status: Status = new Status(); @observable websocketConnected: boolean = false; - @observable last_tps_metric: TPSMetric = new TPSMetric(); - @observable collected_tps_metrics: Array<TPSMetric> = []; + @observable last_mps_metric: MPSMetric = new MPSMetric(); + @observable collected_mps_metrics: Array<MPSMetric> = []; @observable collected_mem_metrics: Array<MemoryMetrics> = []; @observable neighbor_metrics = new ObservableMap<string, NeighborMetrics>(); + @observable last_tips_metric: TipsMetric = new TipsMetric(); + @observable collected_tips_metrics: Array<TipsMetric> = []; + @observable collecting: boolean = true; constructor() { + this.registerHandlers(); + } + + registerHandlers = () => { registerHandler(WSMsgType.Status, this.updateStatus); - registerHandler(WSMsgType.TPSMetrics, this.updateLastTPSMetric); + registerHandler(WSMsgType.MPSMetrics, (mps: number) => { + this.addMPSMetric(this.updateLastMPSMetric(mps)); + }); registerHandler(WSMsgType.NeighborStats, this.updateNeighborMetrics); + registerHandler(WSMsgType.TipsMetrics, this.updateLastTipsMetric); + this.updateCollecting(true); + } + + unregisterHandlers = () => { + unregisterHandler(WSMsgType.Status); + registerHandler(WSMsgType.MPSMetrics, this.updateLastMPSMetric); + unregisterHandler(WSMsgType.NeighborStats); + unregisterHandler(WSMsgType.TipsMetrics); + this.updateCollecting(false); + } + + @action + updateCollecting = (collecting: boolean) => { + this.collecting = collecting; + } + + @action + reset() { + this.collected_mps_metrics = []; + this.collected_mem_metrics = []; + this.neighbor_metrics = new ObservableMap<string, NeighborMetrics>(); + this.collected_tips_metrics = []; } connect() { @@ -183,6 +220,9 @@ export class NodeStore { @action updateNeighborMetrics = (neighborMetrics: Array<NeighborMetric>) => { + if (!neighborMetrics) { + return; + } let updated = []; for (let i = 0; i < neighborMetrics.length; i++) { let metric = neighborMetrics[i]; @@ -203,33 +243,69 @@ export class NodeStore { }; @action - updateLastTPSMetric = (tps: number) => { - let tpsMetric = new TPSMetric(); - tpsMetric.tps = tps; - tpsMetric.ts = dateformat(Date.now(), "HH:MM:ss"); - this.last_tps_metric = tpsMetric; - if (this.collected_tps_metrics.length > maxMetricsDataPoints) { - this.collected_tps_metrics.shift(); + updateLastMPSMetric = (mps: number) => { + let mpsMetric = new MPSMetric(); + mpsMetric.mps = mps; + mpsMetric.ts = dateformat(Date.now(), "HH:MM:ss"); + this.last_mps_metric = mpsMetric; + return mpsMetric; + }; + + @action + addMPSMetric = (metric: MPSMetric) => { + if (this.collected_mps_metrics.length > maxMetricsDataPoints) { + this.collected_mps_metrics.shift(); } - this.collected_tps_metrics.push(tpsMetric); + this.collected_mps_metrics.push(metric); + } + + @action + updateLastTipsMetric = (tips: number) => { + let tipsMetric = new TipsMetric(); + tipsMetric.tips = tips; + tipsMetric.ts = dateformat(Date.now(), "HH:MM:ss"); + this.last_tips_metric = tipsMetric; + if (this.collected_tips_metrics.length > maxMetricsDataPoints) { + this.collected_tips_metrics.shift(); + } + this.collected_tips_metrics.push(tipsMetric); }; @computed - get tpsSeries() { - let tps = Object.assign({}, chartSeriesOpts, - series("TPS", 'rgba(67, 196, 99,1)', 'rgba(67, 196, 99,0.4)') + get mpsSeries() { + let mps = Object.assign({}, chartSeriesOpts, + series("MPS", 'rgba(67, 196, 99,1)', 'rgba(67, 196, 99,0.4)') + ); + + let labels = []; + for (let i = 0; i < this.collected_mps_metrics.length; i++) { + let metric: MPSMetric = this.collected_mps_metrics[i]; + labels.push(metric.ts); + mps.data.push(metric.mps); + } + + return { + labels: labels, + datasets: [mps], + }; + } + + @computed + get tipsSeries() { + let tips = Object.assign({}, chartSeriesOpts, + series("Tips", 'rgba(250, 140, 30,1)', 'rgba(250, 140, 30,0.4)') ); let labels = []; - for (let i = 0; i < this.collected_tps_metrics.length; i++) { - let metric: TPSMetric = this.collected_tps_metrics[i]; + for (let i = 0; i < this.collected_tips_metrics.length; i++) { + let metric: TipsMetric = this.collected_tips_metrics[i]; labels.push(metric.ts); - tps.data.push(metric.tps); + tips.data.push(metric.tips); } return { labels: labels, - datasets: [tps], + datasets: [tips], }; } @@ -320,4 +396,4 @@ export class NodeStore { } } -export default NodeStore; \ No newline at end of file +export default NodeStore; diff --git a/plugins/spa/frontend/src/app/stores/RouterStore.ts b/plugins/dashboard/frontend/src/app/stores/RouterStore.ts similarity index 100% rename from plugins/spa/frontend/src/app/stores/RouterStore.ts rename to plugins/dashboard/frontend/src/app/stores/RouterStore.ts diff --git a/plugins/dashboard/frontend/src/app/stores/VisualizerStore.ts b/plugins/dashboard/frontend/src/app/stores/VisualizerStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..dff4fa73fa54880838950fc704adb2ff0f99d6f9 --- /dev/null +++ b/plugins/dashboard/frontend/src/app/stores/VisualizerStore.ts @@ -0,0 +1,416 @@ +import {action, observable, ObservableMap} from 'mobx'; +import {registerHandler, WSMsgType} from "app/misc/WS"; +import {RouterStore} from "mobx-react-router"; +import {default as Viva} from 'vivagraphjs'; + +export class Vertex { + id: string; + trunk_id: string; + branch_id: string; + is_solid: boolean; + is_tip: boolean; +} + +export class TipInfo { + id: string; + is_tip: boolean; +} + +const vertexSize = 20; + +export class VisualizerStore { + @observable vertices = new ObservableMap<string, Vertex>(); + @observable verticesLimit = 1500; + @observable solid_count = 0; + @observable tips_count = 0; + verticesIncomingOrder = []; + collect: boolean = false; + routerStore: RouterStore; + + // the currently selected vertex via hover + @observable selected: Vertex; + @observable selected_approvers_count = 0; + @observable selected_approvees_count = 0; + selected_via_click: boolean = false; + selected_origin_color: number = 0; + + // search + @observable search: string = ""; + + // viva graph objs + graph; + graphics; + renderer; + @observable paused: boolean = false; + + constructor(routerStore: RouterStore) { + this.routerStore = routerStore; + registerHandler(WSMsgType.Vertex, this.addVertex); + registerHandler(WSMsgType.TipInfo, this.addTipInfo); + } + + @action + updateSearch = (search: string) => { + this.search = search.trim(); + } + + @action + searchAndHighlight = () => { + this.clearSelected(); + if (!this.search) return; + let iter: IterableIterator<string> = this.vertices.keys(); + let found = null; + for (const key of iter) { + if (key.indexOf(this.search) >= 0) { + found = key; + break; + } + } + if (!found) return; + this.updateSelected(this.vertices.get(found), false); + } + + @action + pauseResume = () => { + if (this.paused) { + this.renderer.resume(); + this.paused = false; + return; + } + this.renderer.pause(); + this.paused = true; + } + + @action + updateVerticesLimit = (num: number) => { + this.verticesLimit = num; + } + + @action + addVertex = (vert: Vertex) => { + if (!this.collect) return; + + let existing = this.vertices.get(vert.id); + if (existing) { + // can only go from unsolid to solid + if (!existing.is_solid && vert.is_solid) { + existing.is_solid = true; + this.solid_count++; + } + // update trunk and branch ids since we might be dealing + // with a vertex obj only created from a tip info + existing.trunk_id = vert.trunk_id; + existing.branch_id = vert.branch_id; + vert = existing + } else { + if (vert.is_solid) { + this.solid_count++; + } + this.verticesIncomingOrder.push(vert.id); + this.checkLimit(); + + //clear trunk and branch tip state + let trunkVert = this.vertices.get(vert.trunk_id) + let branchVert = this.vertices.get(vert.branch_id) + if(trunkVert) { + trunkVert.is_tip = false + this.vertices.set(trunkVert.id, trunkVert) + } + if(branchVert){ + branchVert.is_tip = false + this.vertices.set(branchVert.id, branchVert) + } + } + + this.vertices.set(vert.id, vert); + this.drawVertex(vert); + }; + + @action + addTipInfo = (tipInfo: TipInfo) => { + if (!this.collect) return; + let vert = this.vertices.get(tipInfo.id); + if (!vert) { + // create a new empty one for now + vert = new Vertex(); + vert.id = tipInfo.id; + this.verticesIncomingOrder.push(vert.id); + this.checkLimit(); + } + this.tips_count += tipInfo.is_tip ? 1 : vert.is_tip ? -1 : 0; + vert.is_tip = tipInfo.is_tip; + this.vertices.set(vert.id, vert); + this.drawVertex(vert); + }; + + @action + checkLimit = () => { + while (this.verticesIncomingOrder.length > this.verticesLimit) { + let deleteId = this.verticesIncomingOrder.shift(); + let vert = this.vertices.get(deleteId); + // make sure we remove any markings if the vertex gets deleted + if (this.selected && deleteId === this.selected.id) { + this.clearSelected(); + } + this.vertices.delete(deleteId); + this.graph.removeNode(deleteId); + if (!vert) { + continue; + } + if (vert.is_solid) { + this.solid_count--; + } + if (vert.is_tip) { + this.tips_count--; + } + this.deleteApproveeLink(vert.trunk_id); + this.deleteApproveeLink(vert.branch_id); + } + } + + @action + deleteApproveeLink = (approveeId: string) => { + if (!approveeId) { + return; + } + let approvee = this.vertices.get(approveeId); + if (approvee) { + if (this.selected && approveeId === this.selected.id) { + this.clearSelected(); + } + if (approvee.is_solid) { + this.solid_count--; + } + if (approvee.is_tip) { + this.tips_count--; + } + this.vertices.delete(approveeId); + } + this.graph.removeNode(approveeId); + } + + drawVertex = (vert: Vertex) => { + let node; + let existing = this.graph.getNode(vert.id); + if (existing) { + // update coloring + let nodeUI = this.graphics.getNodeUI(vert.id); + nodeUI.color = parseColor(this.colorForVertexState(vert)); + node = existing + } else { + node = this.graph.addNode(vert.id, vert); + } + if (vert.trunk_id && (!node.links || !node.links.some(link => link.fromId === vert.trunk_id))) { + this.graph.addLink(vert.trunk_id, vert.id); + } + if (vert.trunk_id === vert.branch_id) { + return; + } + if (vert.branch_id && (!node.links || !node.links.some(link => link.fromId === vert.branch_id))) { + this.graph.addLink(vert.branch_id, vert.id); + } + } + + colorForVertexState = (vert: Vertex) => { + if (!vert || (!vert.trunk_id && !vert.branch_id)) return "#b58900"; + if (vert.is_tip) { + return "#cb4b16"; + } + if (vert.is_solid) { + return "#6c71c4"; + } + return "#2aa198"; + } + + start = () => { + this.collect = true; + this.graph = Viva.Graph.graph(); + + let graphics: any = Viva.Graph.View.webglGraphics(); + + const layout = Viva.Graph.Layout.forceDirected(this.graph, { + springLength: 10, + springCoeff: 0.0001, + stableThreshold: 0.15, + gravity: -2, + dragCoeff: 0.02, + timeStep: 20, + theta: 0.8, + }); + + graphics.node((node) => { + if (!node.data) { + return Viva.Graph.View.webglSquare(10, this.colorForVertexState(node.data)); + } + return Viva.Graph.View.webglSquare(vertexSize, this.colorForVertexState(node.data)); + }) + graphics.link(() => Viva.Graph.View.webglLine("#586e75")); + let ele = document.getElementById('visualizer'); + this.renderer = Viva.Graph.View.renderer(this.graph, { + container: ele, graphics, layout, + }); + + let events = Viva.Graph.webglInputEvents(graphics, this.graph); + + events.mouseEnter((node) => { + this.clearSelected(); + this.updateSelected(node.data); + }).mouseLeave((node) => { + this.clearSelected(); + }); + this.graphics = graphics; + this.renderer.run(); + } + + stop = () => { + this.collect = false; + this.renderer.dispose(); + this.graph = null; + this.paused = false; + this.selected = null; + this.solid_count = 0; + this.tips_count = 0; + this.vertices.clear(); + } + + @action + updateSelected = (vert: Vertex, viaClick?: boolean) => { + if (!vert) return; + + this.selected = vert; + this.selected_via_click = !!viaClick; + + // mutate links + let node = this.graph.getNode(vert.id); + let nodeUI = this.graphics.getNodeUI(vert.id); + this.selected_origin_color = nodeUI.color + nodeUI.color = parseColor("#859900"); + nodeUI.size = vertexSize * 1.5; + + const seenForward = []; + const seenBackwards = []; + dfsIterator(this.graph, + node, + node => { + this.selected_approvers_count++; + }, + true, + link => { + const linkUI = this.graphics.getLinkUI(link.id); + linkUI.color = parseColor("#d33682"); + }, + seenForward + ); + dfsIterator(this.graph, node, node => { + this.selected_approvees_count++; + }, false, link => { + const linkUI = this.graphics.getLinkUI(link.id); + linkUI.color = parseColor("#b58900"); + }, + seenBackwards + ); + } + + resetLinks = () => { + this.graph.forEachLink(function (link) { + const linkUI = this.graphics.getLinkUI(link.id); + linkUI.color = parseColor("#586e75"); + }); + } + + @action + clearSelected = () => { + this.selected_approvers_count = 0; + this.selected_approvees_count = 0; + if (this.selected_via_click || !this.selected) { + return; + } + + // clear link highlight + let node = this.graph.getNode(this.selected.id); + if (!node) { + // clear links + this.resetLinks(); + return; + } + + let nodeUI = this.graphics.getNodeUI(this.selected.id); + nodeUI.color = this.selected_origin_color; + nodeUI.size = vertexSize; + + const seenForward = []; + const seenBackwards = []; + dfsIterator(this.graph, node, node => { + }, true, + link => { + const linkUI = this.graphics.getLinkUI(link.id); + linkUI.color = parseColor("#586e75"); + }, + seenBackwards + ); + dfsIterator(this.graph, node, node => { + }, false, + link => { + const linkUI = this.graphics.getLinkUI(link.id); + linkUI.color = parseColor("#586e75"); + }, + seenForward + ); + + this.selected = null; + } + +} + +export default VisualizerStore; + +// copied over and refactored from https://github.com/glumb/IOTAtangle +function dfsIterator(graph, node, cb, up, cbLinks: any = false, seenNodes = []) { + seenNodes.push(node); + let pointer = 0; + + while (seenNodes.length > pointer) { + const node = seenNodes[pointer++]; + + if (cb(node)) return true; + + for (const link of node.links) { + if (cbLinks) cbLinks(link); + + if (!up && link.toId === node.id && !seenNodes.includes(graph.getNode(link.fromId))) { + seenNodes.push(graph.getNode(link.fromId)); + continue; + } + + if (up && link.fromId === node.id && !seenNodes.includes(graph.getNode(link.toId))) { + seenNodes.push(graph.getNode(link.toId)); + } + } + } +} + +function parseColor(color): any { + let parsedColor = 0x009ee8ff; + + if (typeof color === 'number') { + return color; + } + + if (typeof color === 'string' && color) { + if (color.length === 4) { + // #rgb, duplicate each letter except first #. + color = color.replace(/([^#])/g, '$1$1'); + } + if (color.length === 9) { + // #rrggbbaa + parsedColor = parseInt(color.substr(1), 16); + } else if (color.length === 7) { + // or #rrggbb. + parsedColor = (parseInt(color.substr(1), 16) << 8) | 0xff; + } else { + throw 'Color expected in hex format with preceding "#". E.g. #00ff00. Got value: ' + color; + } + } + + return parsedColor; +} \ No newline at end of file diff --git a/plugins/spa/frontend/src/assets/index.html b/plugins/dashboard/frontend/src/assets/index.html similarity index 100% rename from plugins/spa/frontend/src/assets/index.html rename to plugins/dashboard/frontend/src/assets/index.html diff --git a/plugins/spa/frontend/src/assets/main.css b/plugins/dashboard/frontend/src/assets/main.css similarity index 59% rename from plugins/spa/frontend/src/assets/main.css rename to plugins/dashboard/frontend/src/assets/main.css index b4d5b3006adec2d178029f9404cbc7f8363990b1..0c04ad85991f01c919d54c8615c8ea3f875014c1 100644 --- a/plugins/spa/frontend/src/assets/main.css +++ b/plugins/dashboard/frontend/src/assets/main.css @@ -9,5 +9,11 @@ } .hidden { - visibility: hidden !important; + visibility: hidden !important; +} + +.visualizer { + position: absolute; + height: 100%; + width: 100%; } \ No newline at end of file diff --git a/plugins/spa/frontend/src/main.tsx b/plugins/dashboard/frontend/src/main.tsx similarity index 71% rename from plugins/spa/frontend/src/main.tsx rename to plugins/dashboard/frontend/src/main.tsx index 1c4cc77eb0c722eb5bfa31c308bbaac07526054c..684d1b31ce7012732dd92ff35aa5eed912780c14 100644 --- a/plugins/spa/frontend/src/main.tsx +++ b/plugins/dashboard/frontend/src/main.tsx @@ -8,15 +8,24 @@ import {RouterStore, syncHistoryWithStore} from 'mobx-react-router'; import {Router} from 'react-router-dom'; import NodeStore from "app/stores/NodeStore"; import ExplorerStore from "app/stores/ExplorerStore"; +import DrngStore from "app/stores/DrngStore"; +import FaucetStore from "app/stores/FaucetStore"; +import VisualizerStore from "app/stores/VisualizerStore"; // prepare MobX stores const routerStore = new RouterStore(); const nodeStore = new NodeStore(); const explorerStore = new ExplorerStore(routerStore); +const drngStore = new DrngStore(routerStore); +const faucetStore = new FaucetStore(routerStore); +const visualizerStore = new VisualizerStore(routerStore); const stores = { "routerStore": routerStore, "nodeStore": nodeStore, "explorerStore": explorerStore, + "drngStore": drngStore, + "faucetStore": faucetStore, + "visualizerStore": visualizerStore, }; const browserHistory = createBrowserHistory(); diff --git a/plugins/dashboard/frontend/tsconfig.json b/plugins/dashboard/frontend/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..5552b9bb232fc45ff3ecc47c37be7c86235521a5 --- /dev/null +++ b/plugins/dashboard/frontend/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "sourceMap": true, + "target": "es6", + "jsx": "react", + "module": "es6", + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "declaration": false, + "noImplicitAny": false, + "noImplicitReturns": false, + "noUnusedLocals": true, + "removeComments": true, + "strictNullChecks": false, + "outDir": "build", + "lib": ["es6", "es7", "dom"], + "baseUrl": "src", + "paths": { + "app/*": ["./app/*"] + } + }, + "exclude": ["dist", "build", "node_modules"] +} diff --git a/plugins/spa/frontend/types/global.d.ts b/plugins/dashboard/frontend/types/global.d.ts similarity index 100% rename from plugins/spa/frontend/types/global.d.ts rename to plugins/dashboard/frontend/types/global.d.ts diff --git a/plugins/spa/frontend/webpack.config.js b/plugins/dashboard/frontend/webpack.config.js similarity index 100% rename from plugins/spa/frontend/webpack.config.js rename to plugins/dashboard/frontend/webpack.config.js diff --git a/plugins/spa/frontend/yarn.lock b/plugins/dashboard/frontend/yarn.lock similarity index 95% rename from plugins/spa/frontend/yarn.lock rename to plugins/dashboard/frontend/yarn.lock index 580d279505a481b14bc908c3763946ffed70e609..f589754c26ff1f56f788131668721d7143ec8b5e 100644 --- a/plugins/spa/frontend/yarn.lock +++ b/plugins/dashboard/frontend/yarn.lock @@ -1,7761 +1,7966 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" - integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== - dependencies: - "@babel/highlight" "^7.8.3" - -"@babel/core@^7.2.2": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.7.tgz#b69017d221ccdeb203145ae9da269d72cf102f3b" - integrity sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.7" - "@babel/helpers" "^7.8.4" - "@babel/parser" "^7.8.7" - "@babel/template" "^7.8.6" - "@babel/traverse" "^7.8.6" - "@babel/types" "^7.8.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.8.6", "@babel/generator@^7.8.7": - version "7.8.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.8.tgz#cdcd58caab730834cee9eeadb729e833b625da3e" - integrity sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg== - dependencies: - "@babel/types" "^7.8.7" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== - dependencies: - "@babel/helper-get-function-arity" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-get-function-arity@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" - integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-split-export-declaration@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" - integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helpers@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" - integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== - dependencies: - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" - -"@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.8.6", "@babel/parser@^7.8.7": - version "7.8.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.8.tgz#4c3b7ce36db37e0629be1f0d50a571d2f86f6cd4" - integrity sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA== - -"@babel/runtime@^7.1.2", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.7.tgz#8fefce9802db54881ba59f90bb28719b4996324d" - integrity sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.8.3", "@babel/template@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" - integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" - -"@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" - integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.6" - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" - -"@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.7.tgz#1fc9729e1acbb2337d5b6977a63979b4819f5d1d" - integrity sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw== - dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@csstools/convert-colors@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" - integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== - -"@jimp/bmp@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.9.5.tgz#5678cc6029a1a45ec62fe0fe71f345fe2a891805" - integrity sha512-2cYdgXaNykuPe9sjm11Jihp5VomyWTWziIuDDB7xnxQtEz2HUR0bjXm2MJJOfU0TL52H+LS2JIKtAxcLPzp28w== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - bmp-js "^0.1.0" - core-js "^3.4.1" - -"@jimp/core@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.9.5.tgz#391da8c9bbc34a61ff25ac27a931c05d15b519e1" - integrity sha512-P1mlB9UOeI3IAQ4lGTmRBGw+F/mHWXd3tSyBskjL4E3YJ1eNK7WRrErUj/vUOvSBIryotu7nGo8vv8Q8JZ7/8w== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - any-base "^1.1.0" - buffer "^5.2.0" - core-js "^3.4.1" - exif-parser "^0.1.12" - file-type "^9.0.0" - load-bmfont "^1.3.1" - mkdirp "0.5.1" - phin "^2.9.1" - pixelmatch "^4.0.2" - tinycolor2 "^1.4.1" - -"@jimp/custom@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.9.5.tgz#e1a637562580aee30a19dd86e41514e8a7a98d94" - integrity sha512-FaR7M0oxqbd7ujBL5ryyllS+mEuMKbKaDsdb8Cpu9SAo80DBiasUrYFFD/45/aRa95aM5o8t4C4Pna2bx8t3Tg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/core" "^0.9.5" - core-js "^3.4.1" - -"@jimp/gif@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.9.5.tgz#113fe8f02399cbb58fd322bd4bdc6309c68207ad" - integrity sha512-QxjLl15nIz/QTeNgLFUJIOMLIceMO2B/xLUWF1/WqaP7Su6SGasRS6JY8OZ9QnqJLMWkodoEJmL6DxwtoOtqdg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - omggif "^1.0.9" - -"@jimp/jpeg@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.9.5.tgz#fb34d933f32a063a60d46fee4addce1de647fb2a" - integrity sha512-cBpXqmeegsLzf/mYk1WpYov2RH1W944re5P61/ag6AMWEMQ51BoBdgBy5JABZIELg2GQxpoG+g/KxUshRzeIAg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - jpeg-js "^0.3.4" - -"@jimp/plugin-blit@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.9.5.tgz#c84fd86bdae7831ed123468153d56e17684a2f80" - integrity sha512-VmV99HeCPOyliY/uEGOaKO9EcqDxSBzKDGC7emNCLFzlbK4uty4/cYMKGKTBiZR9AS1rEd63LxrDtbHKR8CsqQ== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-blur@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.9.5.tgz#404c6a41eb81e53dfc338f08e356dcbea00f68fd" - integrity sha512-FnAEhMW9ZK8D6qCLDeMAloi4h7TCch9ZWFdonj49gwllpvLksBpnL9PTft4dFXCwZgOAq2apYwW7cwTAIfAw4A== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-color@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.9.5.tgz#54ed58df392dc4397d30a4b34d8063da9641d5f1" - integrity sha512-2aFE0tRdhAKCCgh+tFLsLPOSgrk3ttl2TtTP5FAXeKmzlLj7FZ/JKj0waaGWZKdJ+uDxsVpX3EhuK3CfukIyrg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - tinycolor2 "^1.4.1" - -"@jimp/plugin-contain@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.9.5.tgz#51ff0f8b07e02b1fafae6fa83b7b34aeabda6b8e" - integrity sha512-zhaCJnUqd8hhD8IXxbRALU6ZzCWWbQDulc8Tn8Hxnub0si7dlq/DxBQT7og6kCxswBj2zPBtRAHONEwLdt7Nfw== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-cover@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.9.5.tgz#bdd140fc200d0340ad3eaa9daf771e7529725301" - integrity sha512-rG7vtx7vV9mHCFR4YP9GzGEsaop0IkMidP3UFPULbDcBdEEkehEG7a0h2X4w/Nt07J3k8wVoXYTjrb/CXpWkaw== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-crop@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.9.5.tgz#e0b7d6359d2cad2be1ada2c57aaccca51dc41784" - integrity sha512-yoScC43YhYlswTKyL4fmawGwF73HyuIRpp1R3mXa6qbMA9mjX9QiqNdAIMB3UMHeBcIgkOD/Zy1f90/skBMpxg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-displace@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.9.5.tgz#1d5b59ed90f31d1e095a9589b3f505cad3bb09aa" - integrity sha512-nwfB72qNP8kNyBnlaY0vgJys7RUjvI61Qp3AMMbKKaRSsthCx7aeKU9Cyv+AHMfcVkkt3NdTmh7ScE+hkNFUhA== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-dither@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.9.5.tgz#9b705a8961239582193123defb950bba6d2a81a3" - integrity sha512-Pp1ehm5Hon6LcttRG+d+x1UN1ww00P4cyBnMVRR3NMhIfgc0IjQgojik9ZXax3nVj7XkqXJJh8f5uxC1cvYUnA== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-flip@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.9.5.tgz#28c1c2e7817327ceedcb8c2508a175e30125e411" - integrity sha512-rKbg8c9ePst3w2t1kxQt2H05/rUR5/pjjafhZ97s01pxH/SOJudy5d76nJGzRBYoaRnxpvDzpN+2+iA08wDY5Q== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-gaussian@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.9.5.tgz#11c91ba2542d129431533b1a7df3e0eda6461e07" - integrity sha512-8HloHpVPgSsoWekslJ5uUPK2ddoLrGXQAVOyo3BT2pVgwbL317+r96NxPGKTxrY20fqex9SQrjx3kHeSWbysEA== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-invert@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.9.5.tgz#46b7db7a988373c9c43d14adda3b8f001ef5899a" - integrity sha512-tqfMqQqsU4ulaif0Kk/BydqmG5UbjT67dmMjwnDL7rke+ypJ8tzq7j9QeZ9SDFB+PxUQcy/kPEw/R2Ys7HHi8A== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-mask@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.9.5.tgz#de0044e710f922c3ba422478faa0d676ce2d52f4" - integrity sha512-lIOrKb/VT1laDIA1H1nPOdtOB4TVhMRlxanXoEP8uKdE6a2goqZHXbKLn9itkm0MxtsTlT9KIXwzGxjCV38B3w== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-normalize@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.9.5.tgz#b5b50041608e4403dc3897aeaa6507fcfced91de" - integrity sha512-gayxgPLDp2gynu2IacvdCtqw0bdcC2feUqYOBjTtCpAwIz1KP2Qd6qKjV1dAVGiLO9ESW5maMa0vIBiBkYOovg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-print@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.9.5.tgz#c1021763f56b9dcf6bbd5cef2ce9538a16c36b35" - integrity sha512-/BUSyCfvVhuFdf+rBdH1wbuY8r9J0qhn4Icy7HqO58By7I+V7q7jayoeiLk+zEBsAXpCUbWiZG3KWNtZhLWeQg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - load-bmfont "^1.4.0" - -"@jimp/plugin-resize@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.9.5.tgz#bb965222ffd4addd759ab4eaa1ba53e7ab9423d8" - integrity sha512-vIMleLPbEv0qTE1Mnc7mg5HSFc4l4FxlbDniVUvpi8ZMFa8IkigcTeAgXUKacevNL7uZ66MrnpQ49J3tNE28dQ== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-rotate@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.9.5.tgz#d2885252b8e7b2e5e24915f6f6d309222f27205d" - integrity sha512-BHlhwUruHNQkOpsfzTE2uuSfmkj5eiIDRSAC8whupUGGXNgS67tZJB6u0qDRIeSP/gWV5tGGwXQNMn3AahwR1Q== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugin-scale@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.9.5.tgz#da9bbf131db46b113e9a5b9846504fb07313508e" - integrity sha512-PDU8F77EPFTcLBVDcJtGUvPXA2acG4KqJMZauHwZLZxuiDEvt9qsDQm4aTKcN/ku8oWZjfGBSOamhx/QNUqV5Q== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - -"@jimp/plugins@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.9.5.tgz#366f279bd95cee8690f83aca7e0038bc5d70a133" - integrity sha512-3hvuXeRLj36ifpwE7I7g5Da9bKl/0y62t90ZN0hdQwhLBjRRF4u1e1JZpyu6EK98Bp+W/c8fJ2iuOsHadJOusg== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/plugin-blit" "^0.9.5" - "@jimp/plugin-blur" "^0.9.5" - "@jimp/plugin-color" "^0.9.5" - "@jimp/plugin-contain" "^0.9.5" - "@jimp/plugin-cover" "^0.9.5" - "@jimp/plugin-crop" "^0.9.5" - "@jimp/plugin-displace" "^0.9.5" - "@jimp/plugin-dither" "^0.9.5" - "@jimp/plugin-flip" "^0.9.5" - "@jimp/plugin-gaussian" "^0.9.5" - "@jimp/plugin-invert" "^0.9.5" - "@jimp/plugin-mask" "^0.9.5" - "@jimp/plugin-normalize" "^0.9.5" - "@jimp/plugin-print" "^0.9.5" - "@jimp/plugin-resize" "^0.9.5" - "@jimp/plugin-rotate" "^0.9.5" - "@jimp/plugin-scale" "^0.9.5" - core-js "^3.4.1" - timm "^1.6.1" - -"@jimp/png@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.9.5.tgz#d1dff33a336f40fd5e3c8119bb57890aecbd5113" - integrity sha512-0GPq/XixXcuWIA3gpMCUUj6rhxT78Hu9oDC9reaHUCcC/5cRTd5Eh7wLafZL8EfOZWV3mh2FZtWiY1xaNHHlBQ== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.5" - core-js "^3.4.1" - pngjs "^3.3.3" - -"@jimp/tiff@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.9.5.tgz#0b4dfcab5238fdabb5725d12a06bb102e12af7c2" - integrity sha512-EcRtiHsAQ9aygRRMWhGTVfitfHwllgt93GE1L8d/iwSlu3e3IIV38MDINdluQUQMU5jcFBcX6eyVVvsgCleGiQ== - dependencies: - "@babel/runtime" "^7.7.2" - core-js "^3.4.1" - utif "^2.0.1" - -"@jimp/types@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.9.5.tgz#32214f76723342b780d2957572f7c2e6efd1d40f" - integrity sha512-62inaxx8zy24WMP+bsg6ZmgsL49oyoGUIGcjDKzvyAY/O6opD+UMNlArhl0xvCCdzriQxbljtSv/8uyHxz4Xbw== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/bmp" "^0.9.5" - "@jimp/gif" "^0.9.5" - "@jimp/jpeg" "^0.9.5" - "@jimp/png" "^0.9.5" - "@jimp/tiff" "^0.9.5" - core-js "^3.4.1" - timm "^1.6.1" - -"@jimp/utils@^0.9.5": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.9.5.tgz#d661bfb7c2f5aef986efc5bcc7cd3af3e42105ac" - integrity sha512-W9vse4/1AYmOjtIVACoBMdc/2te1zcPURhMYNEyiezCU7hWMdj/Z1mwiWFq3AYCgOG8GPVx0ZQzrgqUfUxfTHQ== - dependencies: - "@babel/runtime" "^7.7.2" - core-js "^3.4.1" - -"@posthtml/esm@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@posthtml/esm/-/esm-1.0.0.tgz#09bcb28a02438dcee22ad1970ca1d85a000ae0cf" - integrity sha512-dEVG+ITnvqKGa4v040tP+n8LOKOqr94qjLva7bE5pnfm2KHJwsKz69J4KMxgWLznbpBJzy8vQfCayEk3vLZnZQ== - -"@restart/context@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" - integrity sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q== - -"@restart/hooks@^0.3.11", "@restart/hooks@^0.3.12": - version "0.3.21" - resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.3.21.tgz#5264d12019ffb844dc1fc44d55517ded7b580ee2" - integrity sha512-Wcu3CFJV+iiqPEIoPVx3/CYnZBRgPeRABo6bLJByRH9ptJXyObn7WYPG7Rv0cg3+55bqcBbG0xEfovzwE2PNXg== - -"@types/anymatch@*": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" - integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== - -"@types/classnames@^2.2.7": - version "2.2.10" - resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999" - integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ== - -"@types/events@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== - -"@types/favicons@5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/favicons/-/favicons-5.5.0.tgz#c1cb3d2a14955eedf479f3cc51948630c56e3a64" - integrity sha512-s76OlRaBfqtGu2ZBobnZv2NETfqsQUVfKKlOkKNGo4ArBsqiblodKsnQ3j29hCCgmpQacEfLxealV96za+tzVQ== - dependencies: - "@types/node" "*" - -"@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== - dependencies: - "@types/events" "*" - "@types/minimatch" "*" - "@types/node" "*" - -"@types/history@*": - version "4.7.5" - resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860" - integrity sha512-wLD/Aq2VggCJXSjxEwrMafIP51Z+13H78nXIX0ABEuIGhmB5sNGbR113MOKo+yfw+RDo1ZU3DM6yfnnRF/+ouw== - -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - -"@types/node@*": - version "13.9.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72" - integrity sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ== - -"@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== - -"@types/q@^1.5.1": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" - integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== - -"@types/react-dom@^16.0.11": - version "16.9.5" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.5.tgz#5de610b04a35d07ffd8f44edad93a71032d9aaa7" - integrity sha512-BX6RQ8s9D+2/gDhxrj8OW+YD4R+8hj7FEM/OJHGNR0KipE1h1mSsf39YeyC81qafkq+N3rU3h3RFbLSwE5VqUg== - dependencies: - "@types/react" "*" - -"@types/react-router@^4.4.3": - version "4.4.5" - resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.4.5.tgz#1166997dc7eef2917b5ebce890ebecb32ee5c1b3" - integrity sha512-12+VOu1+xiC8RPc9yrgHCyLI79VswjtuqeS2gPrMcywH6tkc8rGIUhs4LaL3AJPqo5d+RPnfRpNKiJ7MK2Qhcg== - dependencies: - "@types/history" "*" - "@types/react" "*" - -"@types/react@*", "@types/react@^16.7.20", "@types/react@^16.8.23", "@types/react@^16.9.11": - version "16.9.23" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.23.tgz#1a66c6d468ba11a8943ad958a8cb3e737568271c" - integrity sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw== - dependencies: - "@types/prop-types" "*" - csstype "^2.2.0" - -"@types/source-list-map@*": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" - integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== - -"@types/tapable@*": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" - integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== - -"@types/uglify-js@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" - integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== - dependencies: - source-map "^0.6.1" - -"@types/webpack-sources@*": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.6.tgz#3d21dfc2ec0ad0c77758e79362426a9ba7d7cbcb" - integrity sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ== - dependencies: - "@types/node" "*" - "@types/source-list-map" "*" - source-map "^0.6.1" - -"@types/webpack@^4.4.23": - version "4.41.7" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.7.tgz#22be27dbd4362b01c3954ca9b021dbc9328d9511" - integrity sha512-OQG9viYwO0V1NaNV7d0n79V+n6mjOV30CwgFPIfTzwmk8DHbt+C4f2aBGdCYbo3yFyYD6sjXfqqOjwkl1j+ulA== - dependencies: - "@types/anymatch" "*" - "@types/node" "*" - "@types/tapable" "*" - "@types/uglify-js" "*" - "@types/webpack-sources" "*" - source-map "^0.6.0" - -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn@^6.2.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== - -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5: - version "6.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" - integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= - -ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== - -ansi-html@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -any-base@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" - integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -apexcharts-react@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/apexcharts-react/-/apexcharts-react-1.0.0.tgz#258fb12dd2e7a5cb38d74b400e92f18f13e5df55" - integrity sha512-kJbLRJ9B0LmY17Lz4/NWZjAvdEQovcmZ3Gn14zCR5WJQyIBi8YLWAZenf4hEzU3xBfpcp1q8Kbu9c7H8ZQw7oQ== - -apexcharts@^3.10.1: - version "3.16.1" - resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.16.1.tgz#96e6a478e71d2903562087ce2ecf2e88d4cd9a06" - integrity sha512-3MpUk6+clv9tGtb3OQBPRjyLc6g6nHvO2Gk1v8gBhD3tY3MiFi/RP4ItaHyW4SaqBtyK8oHugsgGlanZDTviVQ== - dependencies: - svg.draggable.js "^2.2.2" - svg.easing.js "^2.0.0" - svg.filter.js "^2.0.2" - svg.pathmorphing.js "^0.1.3" - svg.resize.js "^1.4.3" - svg.select.js "^3.0.1" - -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== - dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -author-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" - integrity sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA= - -autoprefixer@^6.3.1: - version "6.7.7" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" - integrity sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ= - dependencies: - browserslist "^1.7.6" - caniuse-db "^1.0.30000634" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^5.2.16" - postcss-value-parser "^3.2.3" - -autoprefixer@^9.6.1: - version "9.7.4" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.4.tgz#f8bf3e06707d047f0641d87aee8cfb174b2a5378" - integrity sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g== - dependencies: - browserslist "^4.8.3" - caniuse-lite "^1.0.30001020" - chalk "^2.4.2" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^7.0.26" - postcss-value-parser "^4.0.2" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== - -babel-loader@^8.0.5: - version "8.0.6" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== - dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" - pify "^4.0.1" - -balanced-match@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" - integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -bignumber.js@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" - integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg= - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bl@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.1.tgz#8c9b4fb754e80cc86463077722be7b88b4af3f42" - integrity sha512-FL/TdvchukRCuWVxT0YMO/7+L5TNeNrVFvRU2IY63aUyv9mpt8splf2NEr6qXtPo5fya5a66YohQKvGNmLrWNA== - dependencies: - readable-stream "^3.4.0" - -bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bmp-js@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.1.tgz#5ad0147099d13a9f38aa7b99af1d6e78666ed37f" - integrity sha1-WtAUcJnROp84qnuZrx1ueGZu038= - -bmp-js@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.3.tgz#64113e9c7cf1202b376ed607bf30626ebe57b18a" - integrity sha1-ZBE+nHzxICs3btYHvzBibr5XsYo= - -bmp-js@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" - integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -boolbase@^1.0.0, boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - -bootstrap@^4.3.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01" - integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA== - -brace-expansion@^1.0.0, brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" - integrity sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk= - dependencies: - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" - -browserslist@^4.6.4, browserslist@^4.8.3: - version "4.9.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.9.1.tgz#01ffb9ca31a1aef7678128fc6a2253316aa7287c" - integrity sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw== - dependencies: - caniuse-lite "^1.0.30001030" - electron-to-chromium "^1.3.363" - node-releases "^1.1.50" - -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-equal@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" - integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - -buffer-json@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" - integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -buffer@^5.2.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" - integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -cacache@^12.0.2: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cache-loader@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" - integrity sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw== - dependencies: - buffer-json "^2.0.0" - find-cache-dir "^3.0.0" - loader-utils "^1.2.3" - mkdirp "^0.5.1" - neo-async "^2.6.1" - schema-utils "^2.0.0" - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - -camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caniuse-api@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" - integrity sha1-tTTnxzTE+B7F++isoq0kNUuWLGw= - dependencies: - browserslist "^1.3.6" - caniuse-db "^1.0.30000529" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30001035" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001035.tgz#3a182cab9d556a4a02d945f1f739e81c18e73bfa" - integrity sha512-kLUON4XN3tq5Nwl7ZICDw+7/vMynSpRMVYDRkzLL31lgnpa6M2YXYdjst3h+xbzjMgdcveRTnRGE1h/1IcKK6A== - -caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001030: - version "1.0.30001035" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz#2bb53b8aa4716b2ed08e088d4dc816a5fe089a1e" - integrity sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chart.js@^2.9.3: - version "2.9.3" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.3.tgz#ae3884114dafd381bc600f5b35a189138aac1ef7" - integrity sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw== - dependencies: - chartjs-color "^2.1.0" - moment "^2.10.2" - -chartjs-color-string@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71" - integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A== - dependencies: - color-name "^1.0.0" - -chartjs-color@^2.1.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0" - integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w== - dependencies: - chartjs-color-string "^0.6.0" - color-convert "^1.9.3" - -chartjs-plugin-streaming@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/chartjs-plugin-streaming/-/chartjs-plugin-streaming-1.8.0.tgz#3cafcf5e733dbbe0de3ac39df00c65075d83bc5c" - integrity sha512-r7kHyNvSAz12J+W5FBmI/K400z4MXqfNYhA5xaTKJ6PA3ZA6Vq+2d5/OCGyVZF/7UsUDWDRK5tHHYj8jqe+nOg== - -chokidar@^2.0.2, chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chownr@^1.1.1, chownr@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -clap@^1.0.9: - version "1.2.3" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" - integrity sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA== - dependencies: - chalk "^1.1.3" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -classnames@^2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" - integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== - -clean-css@4.2.x: - version "4.2.3" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" - integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== - dependencies: - source-map "~0.6.0" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= - -clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -clone@^2.1.1, clone@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -cloneable-readable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" - integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== - dependencies: - inherits "^2.0.1" - process-nextick-args "^2.0.0" - readable-stream "^2.3.5" - -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - -coa@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" - integrity sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0= - dependencies: - q "^1.1.2" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.3.0, color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" - integrity sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE= - dependencies: - color-name "^1.0.0" - -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" - integrity sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q= - dependencies: - clone "^1.0.2" - color-convert "^1.3.0" - color-string "^0.3.0" - -color@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -colormin@^1.0.5: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" - integrity sha1-6i90IKcrlogaOKrlnsEkpvcpgTM= - dependencies: - color "^0.11.0" - css-color-names "0.0.4" - has "^1.0.1" - -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@2.17.x: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== - -commander@^2.19.0, commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== - -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-js@^3.4.1, core-js@^3.4.5: - version "3.6.4" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" - integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@6.0.5, cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -css-blank-pseudo@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" - integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== - dependencies: - postcss "^7.0.5" - -css-color-names@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= - -css-has-pseudo@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" - integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^5.0.0-rc.4" - -css-loader@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea" - integrity sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w== - dependencies: - camelcase "^5.2.0" - icss-utils "^4.1.0" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.14" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^2.0.6" - postcss-modules-scope "^2.1.0" - postcss-modules-values "^2.0.0" - postcss-value-parser "^3.3.0" - schema-utils "^1.0.0" - -css-prefers-color-scheme@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" - integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== - dependencies: - postcss "^7.0.5" - -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== - -css-select@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-select@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" - integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== - dependencies: - boolbase "^1.0.0" - css-what "^3.2.1" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-tree@1.0.0-alpha.37: - version "1.0.0-alpha.37" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" - integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== - dependencies: - mdn-data "2.0.4" - source-map "^0.6.1" - -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - -css-what@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" - integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== - -cssdb@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" - integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== - -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -cssnano@^3.4.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" - integrity sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg= - dependencies: - autoprefixer "^6.3.1" - decamelize "^1.1.2" - defined "^1.0.0" - has "^1.0.1" - object-assign "^4.0.1" - postcss "^5.0.14" - postcss-calc "^5.2.0" - postcss-colormin "^2.1.8" - postcss-convert-values "^2.3.4" - postcss-discard-comments "^2.0.4" - postcss-discard-duplicates "^2.0.1" - postcss-discard-empty "^2.0.1" - postcss-discard-overridden "^0.1.1" - postcss-discard-unused "^2.2.1" - postcss-filter-plugins "^2.0.0" - postcss-merge-idents "^2.1.5" - postcss-merge-longhand "^2.0.1" - postcss-merge-rules "^2.0.3" - postcss-minify-font-values "^1.0.2" - postcss-minify-gradients "^1.0.1" - postcss-minify-params "^1.0.4" - postcss-minify-selectors "^2.0.4" - postcss-normalize-charset "^1.1.0" - postcss-normalize-url "^3.0.7" - postcss-ordered-values "^2.1.0" - postcss-reduce-idents "^2.2.2" - postcss-reduce-initial "^1.0.0" - postcss-reduce-transforms "^1.0.3" - postcss-svgo "^2.1.1" - postcss-unique-selectors "^2.0.2" - postcss-value-parser "^3.2.3" - postcss-zindex "^2.0.1" - -csso@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.2.tgz#e5f81ab3a56b8eefb7f0092ce7279329f454de3d" - integrity sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg== - dependencies: - css-tree "1.0.0-alpha.37" - -csso@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" - integrity sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U= - dependencies: - clap "^1.0.9" - source-map "^0.5.3" - -csstype@^2.2.0, csstype@^2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" - integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== - -cuint@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" - integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -dateformat@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.0.0, debug@^3.1.1, debug@^3.2.5: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.2, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -default-gateway@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" - integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== - dependencies: - execa "^1.0.0" - ip-regex "^2.1.0" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -del@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= - -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" - integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - -dom-converter@^0.2: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-helpers@^5.0.1, dom-helpers@^5.1.0, dom-helpers@^5.1.2: - version "5.1.3" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.3.tgz#7233248eb3a2d1f74aafca31e52c5299cc8ce821" - integrity sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw== - dependencies: - "@babel/runtime" "^7.6.3" - csstype "^2.6.7" - -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - -dom-walk@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" - integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -domelementtype@1, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== - -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1, domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.363: - version "1.3.376" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.376.tgz#7cb7b5205564a06c8f8ecfbe832cbd47a1224bb1" - integrity sha512-cv/PYVz5szeMz192ngilmezyPNFkUjuynuL2vNdiqIrio440nfTDdc0JJU0TS2KHLSVCs9gBbt4CFqM+HcBnjw== - -elliptic@^6.0.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -entities@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - -entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== - -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: - version "1.17.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" - integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-promise@^3.0.2: - version "3.3.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" - integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.1.0, estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -eventemitter3@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" - integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== - -events@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" - integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== - -eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== - dependencies: - original "^1.0.0" - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -exif-parser@^0.1.12, exif-parser@^0.1.9: - version "0.1.12" - resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" - integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI= - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= - dependencies: - homedir-polyfill "^1.0.1" - -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -favicons-webpack-plugin@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/favicons-webpack-plugin/-/favicons-webpack-plugin-2.1.0.tgz#a95e88dc234cd8589e16018b3f9f3a518b305f86" - integrity sha512-tHASGU/7pDbjma8Z6c6tmLe4zTcglRPVuE57L+qBCLYu2ELKsXu9h66a8S8Rjb4aFHXvJgTY3voghYzrhEAV6Q== - dependencies: - "@types/favicons" "5.5.0" - cache-loader "^4.1.0" - camelcase "^5.3.1" - favicons "5.5.0" - find-cache-dir "^3.2.0" - find-root "^1.1.0" - loader-utils "^1.2.3" - parse-author "^2.0.0" - -favicons@5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/favicons/-/favicons-5.5.0.tgz#4badbecac81ddf2793b8149d0823d97c2077445b" - integrity sha512-xZ4B+fZDuq2y999iorrYq4KuBT3OIZHU+CVfjOWQbjOC1OiU0xbf6pp4Ju/yAfJn7W74RVrC3Cv0oqR5CLvviw== - dependencies: - clone "^2.1.2" - colors "^1.4.0" - core-js "^3.4.5" - image-size "^0.8.3" - jimp "^0.9.3" - jsontoxml "^1.0.1" - lodash.defaultsdeep "^4.6.1" - require-directory "^2.1.1" - sharp "^0.23.3" - through2 "^3.0.1" - tinycolor2 "^1.4.1" - to-ico "^1.1.5" - vinyl "^2.2.0" - xml2js "^0.4.22" - -faye-websocket@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= - dependencies: - websocket-driver ">=0.5.1" - -faye-websocket@~0.11.1: - version "0.11.3" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== - dependencies: - websocket-driver ">=0.5.1" - -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== - -file-loader@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" - integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw== - dependencies: - loader-utils "^1.0.2" - schema-utils "^1.0.0" - -file-type@^3.1.0, file-type@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" - integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= - -file-type@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" - integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw== - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-cache-dir@^3.0.0, find-cache-dir@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" - integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-root@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" - integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -findup-sync@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -flatten@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" - integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -follow-redirects@^1.0.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb" - integrity sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ== - dependencies: - debug "^3.0.0" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-stream@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-modules@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -global@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -global@~4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" - integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= - dependencies: - min-document "^2.19.0" - process "~0.5.1" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - -gud@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" - integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== - -handle-thing@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" - integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.1, has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.2.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -history@^4.7.2, history@^4.9.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" - integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== - dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^3.0.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^1.0.1" - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hoist-non-react-statics@^2.5.0: - version "2.5.5" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" - integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== - -hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - -html-entities@^1.2.0, html-entities@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" - integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= - -html-loader@^1.0.0-alpha.0: - version "1.0.0-alpha.0" - resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-1.0.0-alpha.0.tgz#3f4ae7b490a587619be6d1eaa8ce16683580c642" - integrity sha512-KcuaIRWTU0kFjOJCs32a3JsGNCWkeOak0/F/uvJNp3x/N4McXdqHpcK64cYTozK7QLPKKtUqb9h7wR9K9rYRkg== - dependencies: - "@posthtml/esm" "^1.0.0" - htmlnano "^0.1.6" - loader-utils "^1.1.0" - posthtml "^0.11.2" - schema-utils "^0.4.3" - -html-minifier@^3.2.3: - version "3.5.21" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== - dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" - -html-webpack-plugin@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" - integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= - dependencies: - html-minifier "^3.2.3" - loader-utils "^0.2.16" - lodash "^4.17.3" - pretty-error "^2.0.2" - tapable "^1.0.0" - toposort "^1.0.0" - util.promisify "1.0.0" - -htmlnano@^0.1.6: - version "0.1.10" - resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-0.1.10.tgz#a0a548eb4c76ae2cf2423ec7a25c881734d3dea6" - integrity sha512-eTEUzz8VdWYp+w/KUdb99kwao4reR64epUySyZkQeepcyzPQ2n2EPWzibf6QDxmkGy10Kr+CKxYqI3izSbmhJQ== - dependencies: - cssnano "^3.4.0" - object-assign "^4.0.1" - posthtml "^0.11.3" - posthtml-render "^1.1.4" - svgo "^1.0.5" - terser "^3.8.1" - -htmlparser2@^3.3.0, htmlparser2@^3.9.2: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -"http-parser-js@>=0.4.0 <0.4.11": - version "0.4.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" - integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= - -http-proxy-middleware@0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" - integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== - dependencies: - http-proxy "^1.17.0" - is-glob "^4.0.0" - lodash "^4.17.11" - micromatch "^3.1.10" - -http-proxy@^1.17.0: - version "1.18.0" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" - integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -icss-replace-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" - integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= - -icss-utils@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -image-size@^0.5.0: - version "0.5.5" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" - integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= - -image-size@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.8.3.tgz#f0b568857e034f29baffd37013587f2c0cad8b46" - integrity sha512-SMtq1AJ+aqHB45c3FsB4ERK0UCiA2d3H1uq8s+8T0Pf8A3W4teyBQyaFaktH6xvZqh+npwlKU7i4fJo0r7TYTg== - dependencies: - queue "6.0.1" - -import-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" - integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= - dependencies: - import-from "^2.1.0" - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-from@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - integrity sha1-M1238qev/VOqpHHUuAId7ja387E= - dependencies: - resolve-from "^3.0.0" - -import-local@2.0.0, import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - -infer-owner@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -internal-ip@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" - integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== - dependencies: - default-gateway "^4.2.0" - ipaddr.js "^1.9.0" - -interpret@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -ip-regex@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" - integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0= - -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -ip@^1.1.0, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.1, ipaddr.js@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= - -is-absolute-url@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-function@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== - dependencies: - is-path-inside "^2.1.0" - -is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== - dependencies: - path-is-inside "^1.0.2" - -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4, is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-svg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" - integrity sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk= - dependencies: - html-comment-regex "^1.1.0" - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-windows@^1.0.1, is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -jimp@^0.2.21: - version "0.2.28" - resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2" - integrity sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI= - dependencies: - bignumber.js "^2.1.0" - bmp-js "0.0.3" - es6-promise "^3.0.2" - exif-parser "^0.1.9" - file-type "^3.1.0" - jpeg-js "^0.2.0" - load-bmfont "^1.2.3" - mime "^1.3.4" - mkdirp "0.5.1" - pixelmatch "^4.0.0" - pngjs "^3.0.0" - read-chunk "^1.0.1" - request "^2.65.0" - stream-to-buffer "^0.1.0" - tinycolor2 "^1.1.2" - url-regex "^3.0.0" - -jimp@^0.9.3: - version "0.9.5" - resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.9.5.tgz#78da6ddb33925cfb6b80d502d52a590b141c62ba" - integrity sha512-gjrzz+lT4In7shmP4LV1o/dfL0btnh4W9F5jPCXA6Qw4uEAF8+8GDwAR69hbUQCZH7R5KoCtq81tpfzydoJtSQ== - dependencies: - "@babel/runtime" "^7.7.2" - "@jimp/custom" "^0.9.5" - "@jimp/plugins" "^0.9.5" - "@jimp/types" "^0.9.5" - core-js "^3.4.1" - regenerator-runtime "^0.13.3" - -jpeg-js@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.1.2.tgz#135b992c0575c985cfa0f494a3227ed238583ece" - integrity sha1-E1uZLAV1yYXPoPSUoyJ+0jhYPs4= - -jpeg-js@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482" - integrity sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII= - -jpeg-js@^0.3.4: - version "0.3.7" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d" - integrity sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ== - -js-base64@^2.1.9: - version "2.5.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" - integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1, js-yaml@~3.7.0: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json3@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== - -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -json5@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== - dependencies: - minimist "^1.2.0" - -jsontoxml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/jsontoxml/-/jsontoxml-1.0.1.tgz#07fff7f6bfbfa1097d779aec7f041b5046075e70" - integrity sha512-dtKGq0K8EWQBRqcAaePSgKR4Hyjfsz/LkurHSV3Cxk4H+h2fWDeaN2jzABz+ZmOJylgXS7FGeWmbZ6jgYUMdJQ== - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -killable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" - integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -load-bmfont@^1.2.3, load-bmfont@^1.3.1, load-bmfont@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b" - integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g== - dependencies: - buffer-equal "0.0.1" - mime "^1.3.4" - parse-bmfont-ascii "^1.0.3" - parse-bmfont-binary "^1.0.5" - parse-bmfont-xml "^1.1.4" - phin "^2.9.1" - xhr "^2.0.1" - xtend "^4.0.0" - -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - -loader-utils@1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -loader-utils@^0.2.16: - version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" - -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" - integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - -lodash.defaultsdeep@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" - integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.template@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - -lodash.union@4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - -lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.3, lodash@^4.17.4: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== - -log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" - -loglevel@^1.6.6: - version "1.6.7" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56" - integrity sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A== - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -make-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" - integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== - dependencies: - semver "^6.0.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -math-expression-evaluator@^1.2.14: - version "1.2.22" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.22.tgz#c14dcb3d8b4d150e5dcea9c68c8dad80309b0d5e" - integrity sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdn-data@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" - integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memory-fs@^0.4.0, memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== - dependencies: - mime-db "1.43.0" - -mime@1.6.0, mime@^1.3.4: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.0.3, mime@^2.3.1, mime@^2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" - integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= - dependencies: - dom-walk "^0.1.0" - -mini-create-react-context@^0.3.0: - version "0.3.2" - resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz#79fc598f283dd623da8e088b05db8cddab250189" - integrity sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw== - dependencies: - "@babel/runtime" "^7.4.0" - gud "^1.0.0" - tiny-warning "^1.0.2" - -mini-css-extract-plugin@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz#ac0059b02b9692515a637115b0cc9fed3a35c7b0" - integrity sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw== - dependencies: - loader-utils "^1.1.0" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" - integrity sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q= - dependencies: - brace-expansion "^1.0.0" - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minipass@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" - integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== - dependencies: - yallist "^4.0.0" - -minizlib@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3" - integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mobx-react-devtools@^6.0.3: - version "6.1.1" - resolved "https://registry.yarnpkg.com/mobx-react-devtools/-/mobx-react-devtools-6.1.1.tgz#a462b944085cf11ff96fc937d12bf31dab4c8984" - integrity sha512-nc5IXLdEUFLn3wZal65KF3/JFEFd+mbH4KTz/IG5BOPyw7jo8z29w/8qm7+wiCyqVfUIgJ1gL4+HVKmcXIOgqA== - -mobx-react-router@^4.0.5: - version "4.1.0" - resolved "https://registry.yarnpkg.com/mobx-react-router/-/mobx-react-router-4.1.0.tgz#de014848207d8aa32f6a4e67ed861bd2cb6516e5" - integrity sha512-2knsbDqVorWLngZWbdO8tr7xcZXaLpVFsFlCaGaoyZ+EP9erVGRxnlWGqKyFObs3EH1JPLyTDOJ2LPTxb/lB6Q== - -mobx-react@^5.4.3: - version "5.4.4" - resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-5.4.4.tgz#b3de9c6eabcd0ed8a40036888cb0221ab9568b80" - integrity sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ== - dependencies: - hoist-non-react-statics "^3.0.0" - react-lifecycles-compat "^3.0.2" - -mobx@^5.15.0: - version "5.15.4" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.4.tgz#9da1a84e97ba624622f4e55a0bf3300fb931c2ab" - integrity sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw== - -moment@^2.10.2: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== - dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -nan@^2.12.1, nan@^2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -neo-async@^2.5.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== - dependencies: - lower-case "^1.1.1" - -node-abi@^2.7.0: - version "2.15.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.15.0.tgz#51d55cc711bd9e4a24a572ace13b9231945ccb10" - integrity sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg== - dependencies: - semver "^5.4.1" - -node-forge@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" - integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== - -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-releases@^1.1.50: - version "1.1.52" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.52.tgz#bcffee3e0a758e92e44ecfaecd0a47554b0bcba9" - integrity sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ== - dependencies: - semver "^6.3.0" - -noop-logger@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" - integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= - -normalize-url@^1.4.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.1, npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -nth-check@^1.0.2, nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -object-is@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.values@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -omggif@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" - integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -opn@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" - integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== - dependencies: - is-wsl "^1.1.0" - -original@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== - dependencies: - url-parse "^1.4.3" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-locale@^3.0.0, os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== - dependencies: - p-try "^2.0.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-retry@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" - integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== - dependencies: - retry "^0.12.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -pako@^1.0.5, pako@~1.0.5: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" - integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= - dependencies: - no-case "^2.2.0" - -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-author@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" - integrity sha1-00YL8d3Q367tQtp1QkLmX7aEqB8= - dependencies: - author-regex "^1.0.0" - -parse-bmfont-ascii@^1.0.3: - version "1.0.6" - resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" - integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU= - -parse-bmfont-binary@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" - integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY= - -parse-bmfont-xml@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389" - integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ== - dependencies: - xml-parse-from-string "^1.0.0" - xml2js "^0.4.5" - -parse-headers@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" - integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - -parse-png@^1.0.0, parse-png@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/parse-png/-/parse-png-1.1.2.tgz#f5c2ad7c7993490986020a284c19aee459711ff2" - integrity sha1-9cKtfHmTSQmGAgooTBmu5FlxH/I= - dependencies: - pngjs "^3.2.0" - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -phin@^2.9.1: - version "2.9.3" - resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" - integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pixelmatch@^4.0.0, pixelmatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" - integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ= - dependencies: - pngjs "^3.0.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pngjs@^3.0.0, pngjs@^3.2.0, pngjs@^3.3.3: - version "3.4.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" - integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== - -popper.js@^1.15.0, popper.js@^1.16.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" - integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== - -portfinder@^1.0.25: - version "1.0.25" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" - integrity sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.1" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss-attribute-case-insensitive@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" - integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^6.0.2" - -postcss-browser-reporter@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/postcss-browser-reporter/-/postcss-browser-reporter-0.5.0.tgz#ae069dd086d57388d196e1dac39cb8d7626feb48" - integrity sha1-rgad0IbVc4jRluHaw5y412Jv60g= - dependencies: - postcss "^5.0.4" - -postcss-calc@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" - integrity sha1-d7rnypKK2FcW4v2kLyYb98HWW14= - dependencies: - postcss "^5.0.2" - postcss-message-helpers "^2.0.0" - reduce-css-calc "^1.2.6" - -postcss-color-functional-notation@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" - integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-color-gray@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" - integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== - dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.5" - postcss-values-parser "^2.0.0" - -postcss-color-hex-alpha@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" - integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== - dependencies: - postcss "^7.0.14" - postcss-values-parser "^2.0.1" - -postcss-color-mod-function@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" - integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== - dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-color-rebeccapurple@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" - integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-colormin@^2.1.8: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" - integrity sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks= - dependencies: - colormin "^1.0.5" - postcss "^5.0.13" - postcss-value-parser "^3.2.3" - -postcss-convert-values@^2.3.4: - version "2.6.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" - integrity sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0= - dependencies: - postcss "^5.0.11" - postcss-value-parser "^3.1.2" - -postcss-custom-media@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" - integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== - dependencies: - postcss "^7.0.14" - -postcss-custom-properties@^8.0.11: - version "8.0.11" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" - integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== - dependencies: - postcss "^7.0.17" - postcss-values-parser "^2.0.1" - -postcss-custom-selectors@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" - integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-dir-pseudo-class@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" - integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-discard-comments@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" - integrity sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0= - dependencies: - postcss "^5.0.14" - -postcss-discard-duplicates@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" - integrity sha1-uavye4isGIFYpesSq8riAmO5GTI= - dependencies: - postcss "^5.0.4" - -postcss-discard-empty@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" - integrity sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU= - dependencies: - postcss "^5.0.14" - -postcss-discard-overridden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" - integrity sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg= - dependencies: - postcss "^5.0.16" - -postcss-discard-unused@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" - integrity sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM= - dependencies: - postcss "^5.0.14" - uniqs "^2.0.0" - -postcss-double-position-gradients@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" - integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== - dependencies: - postcss "^7.0.5" - postcss-values-parser "^2.0.0" - -postcss-env-function@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" - integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-filter-plugins@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz#82245fdf82337041645e477114d8e593aa18b8ec" - integrity sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ== - dependencies: - postcss "^5.0.4" - -postcss-focus-visible@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" - integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== - dependencies: - postcss "^7.0.2" - -postcss-focus-within@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" - integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== - dependencies: - postcss "^7.0.2" - -postcss-font-variant@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" - integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== - dependencies: - postcss "^7.0.2" - -postcss-gap-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" - integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== - dependencies: - postcss "^7.0.2" - -postcss-image-set-function@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" - integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-import@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.1.tgz#cf8c7ab0b5ccab5649024536e565f841928b7153" - integrity sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw== - dependencies: - postcss "^7.0.1" - postcss-value-parser "^3.2.3" - read-cache "^1.0.0" - resolve "^1.1.7" - -postcss-initial@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" - integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== - dependencies: - lodash.template "^4.5.0" - postcss "^7.0.2" - -postcss-lab-function@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" - integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== - dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-load-config@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" - integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== - dependencies: - cosmiconfig "^5.0.0" - import-cwd "^2.0.0" - -postcss-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" - integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== - dependencies: - loader-utils "^1.1.0" - postcss "^7.0.0" - postcss-load-config "^2.0.0" - schema-utils "^1.0.0" - -postcss-logical@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" - integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== - dependencies: - postcss "^7.0.2" - -postcss-media-minmax@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" - integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== - dependencies: - postcss "^7.0.2" - -postcss-merge-idents@^2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" - integrity sha1-TFUwMTwI4dWzu/PSu8dH4njuonA= - dependencies: - has "^1.0.1" - postcss "^5.0.10" - postcss-value-parser "^3.1.1" - -postcss-merge-longhand@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" - integrity sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg= - dependencies: - postcss "^5.0.4" - -postcss-merge-rules@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" - integrity sha1-0d9d+qexrMO+VT8OnhDofGG19yE= - dependencies: - browserslist "^1.5.2" - caniuse-api "^1.5.2" - postcss "^5.0.4" - postcss-selector-parser "^2.2.2" - vendors "^1.0.0" - -postcss-message-helpers@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" - integrity sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4= - -postcss-minify-font-values@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" - integrity sha1-S1jttWZB66fIR0qzUmyv17vey2k= - dependencies: - object-assign "^4.0.1" - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-minify-gradients@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" - integrity sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE= - dependencies: - postcss "^5.0.12" - postcss-value-parser "^3.3.0" - -postcss-minify-params@^1.0.4: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" - integrity sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM= - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.2" - postcss-value-parser "^3.0.2" - uniqs "^2.0.0" - -postcss-minify-selectors@^2.0.4: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" - integrity sha1-ssapjAByz5G5MtGkllCBFDEXNb8= - dependencies: - alphanum-sort "^1.0.2" - has "^1.0.1" - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" - -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" - -postcss-modules-local-by-default@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63" - integrity sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - postcss-value-parser "^3.3.1" - -postcss-modules-scope@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" - integrity sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - -postcss-modules-values@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64" - integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w== - dependencies: - icss-replace-symbols "^1.1.0" - postcss "^7.0.6" - -postcss-nesting@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" - integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== - dependencies: - postcss "^7.0.2" - -postcss-normalize-charset@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" - integrity sha1-757nEhLX/nWceO0WL2HtYrXLk/E= - dependencies: - postcss "^5.0.5" - -postcss-normalize-url@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" - integrity sha1-EI90s/L82viRov+j6kWSJ5/HgiI= - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^1.4.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - -postcss-ordered-values@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" - integrity sha1-7sbCpntsQSqNsgQud/6NpD+VwR0= - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.1" - -postcss-overflow-shorthand@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" - integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== - dependencies: - postcss "^7.0.2" - -postcss-page-break@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" - integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== - dependencies: - postcss "^7.0.2" - -postcss-place@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" - integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-preset-env@^6.5.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" - integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== - dependencies: - autoprefixer "^9.6.1" - browserslist "^4.6.4" - caniuse-lite "^1.0.30000981" - css-blank-pseudo "^0.1.4" - css-has-pseudo "^0.10.0" - css-prefers-color-scheme "^3.1.1" - cssdb "^4.4.0" - postcss "^7.0.17" - postcss-attribute-case-insensitive "^4.0.1" - postcss-color-functional-notation "^2.0.1" - postcss-color-gray "^5.0.0" - postcss-color-hex-alpha "^5.0.3" - postcss-color-mod-function "^3.0.3" - postcss-color-rebeccapurple "^4.0.1" - postcss-custom-media "^7.0.8" - postcss-custom-properties "^8.0.11" - postcss-custom-selectors "^5.1.2" - postcss-dir-pseudo-class "^5.0.0" - postcss-double-position-gradients "^1.0.0" - postcss-env-function "^2.0.2" - postcss-focus-visible "^4.0.0" - postcss-focus-within "^3.0.0" - postcss-font-variant "^4.0.0" - postcss-gap-properties "^2.0.0" - postcss-image-set-function "^3.0.1" - postcss-initial "^3.0.0" - postcss-lab-function "^2.0.1" - postcss-logical "^3.0.0" - postcss-media-minmax "^4.0.0" - postcss-nesting "^7.0.0" - postcss-overflow-shorthand "^2.0.0" - postcss-page-break "^2.0.0" - postcss-place "^4.0.1" - postcss-pseudo-class-any-link "^6.0.0" - postcss-replace-overflow-wrap "^3.0.0" - postcss-selector-matches "^4.0.0" - postcss-selector-not "^4.0.0" - -postcss-pseudo-class-any-link@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" - integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-reduce-idents@^2.2.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" - integrity sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM= - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-reduce-initial@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" - integrity sha1-aPgGlfBF0IJjqHmtJA343WT2ROo= - dependencies: - postcss "^5.0.4" - -postcss-reduce-transforms@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" - integrity sha1-/3b02CEkN7McKYpC0uFEQCV3GuE= - dependencies: - has "^1.0.1" - postcss "^5.0.8" - postcss-value-parser "^3.0.1" - -postcss-replace-overflow-wrap@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" - integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== - dependencies: - postcss "^7.0.2" - -postcss-reporter@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" - integrity sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw== - dependencies: - chalk "^2.4.1" - lodash "^4.17.11" - log-symbols "^2.2.0" - postcss "^7.0.7" - -postcss-selector-matches@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" - integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" - -postcss-selector-not@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" - integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" - -postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" - integrity sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A= - dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== - dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" - integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-svgo@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" - integrity sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0= - dependencies: - is-svg "^2.0.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - svgo "^0.7.0" - -postcss-unique-selectors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" - integrity sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0= - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss-url@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/postcss-url/-/postcss-url-8.0.0.tgz#7b10059bd12929cdbb1971c60f61a0e5af86b4ca" - integrity sha512-E2cbOQ5aii2zNHh8F6fk1cxls7QVFZjLPSrqvmiza8OuXLzIpErij8BDS5Y3STPfJgpIMNCPEr8JlKQWEoozUw== - dependencies: - mime "^2.3.1" - minimatch "^3.0.4" - mkdirp "^0.5.0" - postcss "^7.0.2" - xxhashjs "^0.2.1" - -postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - -postcss-value-parser@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" - integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== - -postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" - integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== - dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-zindex@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" - integrity sha1-0hCd3AVbka9n/EyzsCWUZjnSryI= - dependencies: - has "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.8, postcss@^5.2.16: - version "5.2.18" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" - integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg== - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.2.3" - -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: - version "7.0.27" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" - integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -posthtml-parser@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.4.2.tgz#a132bbdf0cd4bc199d34f322f5c1599385d7c6c1" - integrity sha512-BUIorsYJTvS9UhXxPTzupIztOMVNPa/HtAm9KHni9z6qEfiJ1bpOBL5DfUOL9XAc3XkLIEzBzpph+Zbm4AdRAg== - dependencies: - htmlparser2 "^3.9.2" - -posthtml-render@^1.1.4, posthtml-render@^1.1.5: - version "1.2.0" - resolved "https://registry.yarnpkg.com/posthtml-render/-/posthtml-render-1.2.0.tgz#3df0c800a8bbb95af583a94748520469477addf4" - integrity sha512-dQB+hoAKDtnI94RZm/wxBUH9My8OJcXd0uhWmGh2c7tVtQ85A+OS3yCN3LNbFtPz3bViwBJXAeoi+CBGMXM0DA== - -posthtml@^0.11.2, posthtml@^0.11.3: - version "0.11.6" - resolved "https://registry.yarnpkg.com/posthtml/-/posthtml-0.11.6.tgz#e349d51af7929d0683b9d8c3abd8166beecc90a8" - integrity sha512-C2hrAPzmRdpuL3iH0TDdQ6XCc9M7Dcc3zEW5BLerY65G4tWWszwv6nG/ksi6ul5i2mx22ubdljgktXCtNkydkw== - dependencies: - posthtml-parser "^0.4.1" - posthtml-render "^1.1.5" - -prebuild-install@^5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.3.tgz#ef4052baac60d465f5ba6bf003c9c1de79b9da8e" - integrity sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g== - dependencies: - detect-libc "^1.0.3" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.0" - mkdirp "^0.5.1" - napi-build-utils "^1.0.1" - node-abi "^2.7.0" - noop-logger "^0.1.1" - npmlog "^4.0.1" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^3.0.3" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - which-pm-runs "^1.0.0" - -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prettier@^1.16.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -pretty-error@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" - integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= - dependencies: - renderkid "^2.0.1" - utila "~0.4" - -prettysize@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prettysize/-/prettysize-2.0.0.tgz#902c02480d865d9cc0813011c9feb4fa02ce6996" - integrity sha512-VVtxR7sOh0VsG8o06Ttq5TrI1aiZKmC+ClSn4eBPaNf4SHr5lzbYW+kYGX3HocBL/MfpVrRfFZ9V3vCbLaiplg== - -process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -process@~0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" - integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -prop-types-extra@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" - integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== - dependencies: - react-is "^16.3.2" - warning "^4.0.0" - -prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -psl@^1.1.28: - version "1.7.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" - integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -q@^1.1.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0, querystring@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== - -queue@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791" - integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg== - dependencies: - inherits "~2.0.3" - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-apexcharts@^1.3.3: - version "1.3.6" - resolved "https://registry.yarnpkg.com/react-apexcharts/-/react-apexcharts-1.3.6.tgz#6c06e5dacfddd0e0373ec8f614503e655c049122" - integrity sha512-ahpMOnuw1ZdD3/fkk9MYRLpqYQ66cZz72+he1R00HaT1VcSjfYc9editQDhE2jGRDuxubmaxVcO3z4FtAk5N0w== - dependencies: - prop-types "^15.5.7" - -react-bootstrap@^1.0.0-beta.16: - version "1.0.0-beta.17" - resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.0.0-beta.17.tgz#09d4789633b2fb24d408fa493b4a80a496e87c82" - integrity sha512-7VP9doezV4rX0EcajzMvyD6ywtrLfulF3ZAev+uTx8syWQybUkccOpecUO5kPomng/bJMgK/h+44PkZ15Dv44g== - dependencies: - "@babel/runtime" "^7.4.2" - "@restart/context" "^2.1.4" - "@restart/hooks" "^0.3.11" - "@types/react" "^16.8.23" - classnames "^2.2.6" - dom-helpers "^5.1.2" - invariant "^2.2.4" - popper.js "^1.16.0" - prop-types "^15.7.2" - prop-types-extra "^1.1.0" - react-overlays "^2.1.0" - react-transition-group "^4.0.0" - uncontrollable "^7.0.0" - warning "^4.0.3" - -react-chartjs-2@^2.8.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-2.9.0.tgz#d054dbdd763fbe9a76296a4ae0752ea549b76d9e" - integrity sha512-IYwqUUnQRAJ9SNA978vxulHJTcUFTJk2LDVfbAyk0TnJFZZG7+6U/2flsE4MCw6WCbBjTTypy8T82Ch7XrPtRw== - dependencies: - lodash "^4.17.4" - prop-types "^15.5.8" - -react-dom@^16.7.0: - version "16.13.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866" - integrity sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.19.0" - -react-hot-loader@^4.6.3: - version "4.12.19" - resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.19.tgz#99a1c763352828f404fa51cd887c5e16bb5b74d1" - integrity sha512-p8AnA4QE2GtrvkdmqnKrEiijtVlqdTIDCHZOwItkI9kW51bt5XnQ/4Anz8giiWf9kqBpEQwsmnChDCAFBRyR/Q== - dependencies: - fast-levenshtein "^2.0.6" - global "^4.3.0" - hoist-non-react-statics "^3.3.0" - loader-utils "^1.1.0" - prop-types "^15.6.1" - react-lifecycles-compat "^3.0.4" - shallowequal "^1.1.0" - source-map "^0.7.3" - -react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: - version "16.13.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" - integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== - -react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-overlays@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-2.1.1.tgz#ffe2090c4a10da6b8947a1c7b1a67d0457648a0d" - integrity sha512-gaQJwmb8Ij2IGVt4D1HmLtl4A0mDVYxlsv/8i0dHWK7Mw0kNat6ORelbbEWzaXTK1TqMeQtJw/jraL3WOADz3w== - dependencies: - "@babel/runtime" "^7.4.5" - "@restart/hooks" "^0.3.12" - dom-helpers "^5.1.0" - popper.js "^1.15.0" - prop-types "^15.7.2" - uncontrollable "^7.0.0" - warning "^4.0.3" - -react-router-bootstrap@^0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/react-router-bootstrap/-/react-router-bootstrap-0.25.0.tgz#5d1a99b5b8a2016c011fc46019d2397e563ce0df" - integrity sha512-/22eqxjn6Zv5fvY2rZHn57SKmjmJfK7xzJ6/G1OgxAjLtKVfWgV5sn41W2yiqzbtV5eE4/i4LeDLBGYTqx7jbA== - dependencies: - prop-types "^15.5.10" - -react-router-dom@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18" - integrity sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew== - dependencies: - "@babel/runtime" "^7.1.2" - history "^4.9.0" - loose-envify "^1.3.1" - prop-types "^15.6.2" - react-router "5.1.2" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - -react-router@5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.1.2.tgz#6ea51d789cb36a6be1ba5f7c0d48dd9e817d3418" - integrity sha512-yjEuMFy1ONK246B+rsa0cUam5OeAQ8pyclRDgpxuSCrAlJ1qN9uZ5IgyKC7gQg0w8OM50NXHEegPh/ks9YuR2A== - dependencies: - "@babel/runtime" "^7.1.2" - history "^4.9.0" - hoist-non-react-statics "^3.1.0" - loose-envify "^1.3.1" - mini-create-react-context "^0.3.0" - path-to-regexp "^1.7.0" - prop-types "^15.6.2" - react-is "^16.6.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - -react-router@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e" - integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg== - dependencies: - history "^4.7.2" - hoist-non-react-statics "^2.5.0" - invariant "^2.2.4" - loose-envify "^1.3.1" - path-to-regexp "^1.7.0" - prop-types "^15.6.1" - warning "^4.0.1" - -react-transition-group@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.3.0.tgz#fea832e386cf8796c58b61874a3319704f5ce683" - integrity sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - -react@^16.7.0: - version "16.13.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.13.0.tgz#d046eabcdf64e457bbeed1e792e235e1b9934cf7" - integrity sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - -read-cache@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" - integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= - dependencies: - pify "^2.3.0" - -read-chunk@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194" - integrity sha1-X2jKswfmY/GZk1J9m1icrORmEZQ= - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -"readable-stream@2 || 3", readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -recursive-readdir-sync@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz#1dbf6d32f3c5bb8d3cde97a6c588d547a9e13d56" - integrity sha1-Hb9tMvPFu4083pemxYjVR6nhPVY= - -reduce-css-calc@^1.2.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" - integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= - dependencies: - balanced-match "^0.4.2" - math-expression-evaluator "^1.2.14" - reduce-function-call "^1.0.1" - -reduce-function-call@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" - integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ== - dependencies: - balanced-match "^1.0.0" - -regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: - version "0.13.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" - integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -relateurl@0.2.x: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -renderkid@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" - integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== - dependencies: - css-select "^1.1.0" - dom-converter "^0.2" - htmlparser2 "^3.3.0" - strip-ansi "^3.0.0" - utila "^0.4.0" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -replace-ext@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= - -request@^2.65.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -resize-img@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/resize-img/-/resize-img-1.1.2.tgz#fad650faf3ef2c53ea63112bc272d95e9d92550e" - integrity sha1-+tZQ+vPvLFPqYxErwnLZXp2SVQ4= - dependencies: - bmp-js "0.0.1" - file-type "^3.8.0" - get-stream "^2.0.0" - jimp "^0.2.21" - jpeg-js "^0.1.1" - parse-png "^1.1.1" - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-pathname@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" - integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.1.7, resolve@^1.3.2: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== - dependencies: - path-parse "^1.0.6" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -rimraf@^2.5.4, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@>=0.6.0, sax@~1.2.1, sax@~1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -scheduler@^0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.0.tgz#a715d56302de403df742f4a9be11975b32f5698d" - integrity sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -schema-utils@^0.4.3: - version "0.4.7" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" - integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== - dependencies: - ajv "^6.1.0" - ajv-keywords "^3.1.0" - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.0.0: - version "2.6.5" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" - integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== - dependencies: - ajv "^6.12.0" - ajv-keywords "^3.4.1" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -selfsigned@^1.10.7: - version "1.10.7" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" - integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== - dependencies: - node-forge "0.9.0" - -semver@^5.0.1, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shallowequal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== - -sharp@^0.23.3: - version "0.23.4" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.23.4.tgz#ca36067cb6ff7067fa6c77b01651cb9a890f8eb3" - integrity sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q== - dependencies: - color "^3.1.2" - detect-libc "^1.0.3" - nan "^2.14.0" - npmlog "^4.1.2" - prebuild-install "^5.3.3" - semver "^6.3.0" - simple-get "^3.1.0" - tar "^5.0.5" - tunnel-agent "^0.6.0" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" - integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= - -simple-get@^3.0.3, simple-get@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" - integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sockjs-client@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" - integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== - dependencies: - debug "^3.2.5" - eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" - -sockjs@0.3.19: - version "0.3.19" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" - integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== - dependencies: - faye-websocket "^0.10.0" - uuid "^3.0.1" - -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@~0.5.10, source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" - integrity sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== - dependencies: - figgy-pudding "^3.5.1" - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - -stream-to-buffer@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9" - integrity sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk= - dependencies: - stream-to "~0.2.0" - -stream-to@~0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" - integrity sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0= - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -style-loader@^0.23.1: - version "0.23.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" - integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== - dependencies: - loader-utils "^1.1.0" - schema-utils "^1.0.0" - -supports-color@6.1.0, supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -svg.draggable.js@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz#c514a2f1405efb6f0263e7958f5b68fce50603ba" - integrity sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw== - dependencies: - svg.js "^2.0.1" - -svg.easing.js@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/svg.easing.js/-/svg.easing.js-2.0.0.tgz#8aa9946b0a8e27857a5c40a10eba4091e5691f12" - integrity sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI= - dependencies: - svg.js ">=2.3.x" - -svg.filter.js@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/svg.filter.js/-/svg.filter.js-2.0.2.tgz#91008e151389dd9230779fcbe6e2c9a362d1c203" - integrity sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM= - dependencies: - svg.js "^2.2.5" - -svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/svg.js/-/svg.js-2.7.1.tgz#eb977ed4737001eab859949b4a398ee1bb79948d" - integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA== - -svg.pathmorphing.js@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz#c25718a1cc7c36e852ecabc380e758ac09bb2b65" - integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww== - dependencies: - svg.js "^2.4.0" - -svg.resize.js@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/svg.resize.js/-/svg.resize.js-1.4.3.tgz#885abd248e0cd205b36b973c4b578b9a36f23332" - integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw== - dependencies: - svg.js "^2.6.5" - svg.select.js "^2.1.2" - -svg.select.js@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-2.1.2.tgz#e41ce13b1acff43a7441f9f8be87a2319c87be73" - integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ== - dependencies: - svg.js "^2.2.5" - -svg.select.js@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-3.0.1.tgz#a4198e359f3825739226415f82176a90ea5cc917" - integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw== - dependencies: - svg.js "^2.6.5" - -svgo@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" - integrity sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U= - dependencies: - coa "~1.0.1" - colors "~1.1.2" - csso "~2.3.1" - js-yaml "~3.7.0" - mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" - -svgo@^1.0.5: - version "1.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" - integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== - dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.37" - csso "^4.0.2" - js-yaml "^3.13.1" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" - stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" - -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tar-fs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad" - integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== - dependencies: - chownr "^1.1.1" - mkdirp "^0.5.1" - pump "^3.0.0" - tar-stream "^2.0.0" - -tar-stream@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" - integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== - dependencies: - bl "^4.0.1" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/tar/-/tar-5.0.5.tgz#03fcdb7105bc8ea3ce6c86642b9c942495b04f93" - integrity sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ== - dependencies: - chownr "^1.1.3" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.0" - mkdirp "^0.5.0" - yallist "^4.0.0" - -terser-webpack-plugin@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" - integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^2.1.2" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - -terser@^3.8.1: - version "3.17.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2" - integrity sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ== - dependencies: - commander "^2.19.0" - source-map "~0.6.1" - source-map-support "~0.5.10" - -terser@^4.1.2: - version "4.6.6" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.6.tgz#da2382e6cafbdf86205e82fb9a115bd664d54863" - integrity sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g== - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through2@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" - integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== - dependencies: - readable-stream "2 || 3" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== - dependencies: - setimmediate "^1.0.4" - -timm@^1.6.1: - version "1.6.2" - resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.2.tgz#dfd8c6719f7ba1fcfc6295a32670a1c6d166c0bd" - integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw== - -tiny-invariant@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" - integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== - -tiny-warning@^1.0.0, tiny-warning@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - -tinycolor2@^1.1.2, tinycolor2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" - integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-ico@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/to-ico/-/to-ico-1.1.5.tgz#1d32da5f2c90922edee6b686d610c54527b5a8d5" - integrity sha512-5kIh7m7bkIlqIESEZkL8gAMMzucXKfPe3hX2FoDY5HEAfD9OJU+Qh9b6Enp74w0qRcxVT5ejss66PHKqc3AVkg== - dependencies: - arrify "^1.0.1" - buffer-alloc "^1.1.0" - image-size "^0.5.0" - parse-png "^1.0.0" - resize-img "^1.1.0" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -toposort@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" - integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -ts-loader@^5.3.3: - version "5.4.5" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.4.5.tgz#a0c1f034b017a9344cef0961bfd97cc192492b8b" - integrity sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw== - dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" - micromatch "^3.1.4" - semver "^5.0.1" - -tslib@^1.9.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" - integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== - -tsx-control-statements@2.17.1: - version "2.17.1" - resolved "https://registry.yarnpkg.com/tsx-control-statements/-/tsx-control-statements-2.17.1.tgz#1afc67e03c90d489537ed3a31ec0ad2116592e6b" - integrity sha512-KiacW90lksaaoRrh5A4P9CbnhU4Bxvb99IJ2QAsybe4kMv2lF9pbNCFRQI6IofLGMZIHQvw1jEei04fhiIcIxQ== - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@^3.2.4: - version "3.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" - integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== - -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== - dependencies: - commander "~2.19.0" - source-map "~0.6.1" - -uncontrollable@^7.0.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.1.1.tgz#f67fed3ef93637126571809746323a9db815d556" - integrity sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q== - dependencies: - "@babel/runtime" "^7.6.3" - "@types/react" "^16.9.11" - invariant "^2.2.4" - react-lifecycles-compat "^3.0.4" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-loader@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" - integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== - dependencies: - loader-utils "^1.1.0" - mime "^2.0.3" - schema-utils "^1.0.0" - -url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -url-regex@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" - integrity sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ= - dependencies: - ip-regex "^1.0.1" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -utif@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" - integrity sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg== - dependencies: - pako "^1.0.5" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util.promisify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util.promisify@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - -utila@^0.4.0, utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^3.0.1, uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" - integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== - -value-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" - integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -vendors@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" - integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vinyl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" - integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" - -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - -warning@^4.0.0, warning@^4.0.1, warning@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" - integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== - dependencies: - loose-envify "^1.0.0" - -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -webpack-cleanup-plugin@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/webpack-cleanup-plugin/-/webpack-cleanup-plugin-0.5.1.tgz#df2d706bd75364c06e65b051186316d674eb96af" - integrity sha1-3y1wa9dTZMBuZbBRGGMW1nTrlq8= - dependencies: - lodash.union "4.6.0" - minimatch "3.0.3" - recursive-readdir-sync "1.0.6" - -webpack-cli@^3.2.1: - version "3.3.11" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" - integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== - dependencies: - chalk "2.4.2" - cross-spawn "6.0.5" - enhanced-resolve "4.1.0" - findup-sync "3.0.0" - global-modules "2.0.0" - import-local "2.0.0" - interpret "1.2.0" - loader-utils "1.2.3" - supports-color "6.1.0" - v8-compile-cache "2.0.3" - yargs "13.2.4" - -webpack-dev-middleware@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" - integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== - dependencies: - memory-fs "^0.4.1" - mime "^2.4.4" - mkdirp "^0.5.1" - range-parser "^1.2.1" - webpack-log "^2.0.0" - -webpack-dev-server@^3.1.14: - version "3.10.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz#f35945036813e57ef582c2420ef7b470e14d3af0" - integrity sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ== - dependencies: - ansi-html "0.0.7" - bonjour "^3.5.0" - chokidar "^2.1.8" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - debug "^4.1.1" - del "^4.1.1" - express "^4.17.1" - html-entities "^1.2.1" - http-proxy-middleware "0.19.1" - import-local "^2.0.0" - internal-ip "^4.3.0" - ip "^1.1.5" - is-absolute-url "^3.0.3" - killable "^1.0.1" - loglevel "^1.6.6" - opn "^5.5.0" - p-retry "^3.0.1" - portfinder "^1.0.25" - schema-utils "^1.0.0" - selfsigned "^1.10.7" - semver "^6.3.0" - serve-index "^1.9.1" - sockjs "0.3.19" - sockjs-client "1.4.0" - spdy "^4.0.1" - strip-ansi "^3.0.1" - supports-color "^6.1.0" - url "^0.11.0" - webpack-dev-middleware "^3.7.2" - webpack-log "^2.0.0" - ws "^6.2.1" - yargs "12.0.5" - -webpack-hot-middleware@^2.24.3: - version "2.25.0" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" - integrity sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA== - dependencies: - ansi-html "0.0.7" - html-entities "^1.2.0" - querystring "^0.2.0" - strip-ansi "^3.0.0" - -webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.29.0: - version "4.42.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.0.tgz#b901635dd6179391d90740a63c93f76f39883eb8" - integrity sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.1" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" - webpack-sources "^1.4.1" - -websocket-driver@>=0.5.1: - version "0.7.3" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" - integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== - dependencies: - http-parser-js ">=0.4.0 <0.4.11" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== - -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" - integrity sha1-+HfVv2SMl+WqVC+twW1qJZucEaE= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which-pm-runs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" - integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= - -which@^1.2.14, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== - dependencies: - async-limiter "~1.0.0" - -xhr@^2.0.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" - integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== - dependencies: - global "~4.3.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xml-parse-from-string@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" - integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= - -xml2js@^0.4.22, xml2js@^0.4.5: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -xxhashjs@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8" - integrity sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw== - dependencies: - cuint "^0.2.2" - -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^13.1.0: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" - -yargs@13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.0" +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/core@^7.2.2": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.7.tgz#b69017d221ccdeb203145ae9da269d72cf102f3b" + integrity sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.8.7" + "@babel/helpers" "^7.8.4" + "@babel/parser" "^7.8.7" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.7" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.0" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.8.6", "@babel/generator@^7.8.7": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.8.tgz#cdcd58caab730834cee9eeadb729e833b625da3e" + integrity sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg== + dependencies: + "@babel/types" "^7.8.7" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" + integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helpers@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" + integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.4" + "@babel/types" "^7.8.3" + +"@babel/highlight@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" + integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.8.6", "@babel/parser@^7.8.7": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.8.tgz#4c3b7ce36db37e0629be1f0d50a571d2f86f6cd4" + integrity sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA== + +"@babel/runtime@^7.1.2", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.7.tgz#8fefce9802db54881ba59f90bb28719b4996324d" + integrity sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" + integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.8.6" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.7.tgz#1fc9729e1acbb2337d5b6977a63979b4819f5d1d" + integrity sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== + +"@jimp/bmp@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.9.5.tgz#5678cc6029a1a45ec62fe0fe71f345fe2a891805" + integrity sha512-2cYdgXaNykuPe9sjm11Jihp5VomyWTWziIuDDB7xnxQtEz2HUR0bjXm2MJJOfU0TL52H+LS2JIKtAxcLPzp28w== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + bmp-js "^0.1.0" + core-js "^3.4.1" + +"@jimp/core@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.10.1.tgz#9c7cee4a1a151786a53d6c5defb141f640396cf9" + integrity sha512-ChyLkGb1+x2mRpsdcnQuRNb523qVqUc7+zCbuO/VAMaqvbMKuRalVz3aHXcVwNi8vOAOgce4LOBT7kjdKTtR/w== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.10.1" + any-base "^1.1.0" + buffer "^5.2.0" + core-js "^3.4.1" + exif-parser "^0.1.12" + file-type "^9.0.0" + load-bmfont "^1.3.1" + mkdirp "^0.5.1" + phin "^2.9.1" + pixelmatch "^4.0.2" + tinycolor2 "^1.4.1" + +"@jimp/core@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.9.5.tgz#391da8c9bbc34a61ff25ac27a931c05d15b519e1" + integrity sha512-P1mlB9UOeI3IAQ4lGTmRBGw+F/mHWXd3tSyBskjL4E3YJ1eNK7WRrErUj/vUOvSBIryotu7nGo8vv8Q8JZ7/8w== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + any-base "^1.1.0" + buffer "^5.2.0" + core-js "^3.4.1" + exif-parser "^0.1.12" + file-type "^9.0.0" + load-bmfont "^1.3.1" + mkdirp "0.5.1" + phin "^2.9.1" + pixelmatch "^4.0.2" + tinycolor2 "^1.4.1" + +"@jimp/custom@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.10.1.tgz#1147f895272351adc3fd8192b73a2d4ccf563535" + integrity sha512-hiiOL5sGcV1p8hCFTabALUOmXs4VP9VwhfBZtsFueKGbwWz6dmaZvkMBsk3Mz1ukBP3xb09goWG+zAIdTm88fw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/core" "^0.10.1" + core-js "^3.4.1" + +"@jimp/custom@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.9.5.tgz#e1a637562580aee30a19dd86e41514e8a7a98d94" + integrity sha512-FaR7M0oxqbd7ujBL5ryyllS+mEuMKbKaDsdb8Cpu9SAo80DBiasUrYFFD/45/aRa95aM5o8t4C4Pna2bx8t3Tg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/core" "^0.9.5" + core-js "^3.4.1" + +"@jimp/gif@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.9.5.tgz#113fe8f02399cbb58fd322bd4bdc6309c68207ad" + integrity sha512-QxjLl15nIz/QTeNgLFUJIOMLIceMO2B/xLUWF1/WqaP7Su6SGasRS6JY8OZ9QnqJLMWkodoEJmL6DxwtoOtqdg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + omggif "^1.0.9" + +"@jimp/jpeg@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.9.5.tgz#fb34d933f32a063a60d46fee4addce1de647fb2a" + integrity sha512-cBpXqmeegsLzf/mYk1WpYov2RH1W944re5P61/ag6AMWEMQ51BoBdgBy5JABZIELg2GQxpoG+g/KxUshRzeIAg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + jpeg-js "^0.3.4" + +"@jimp/plugin-blit@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.9.5.tgz#c84fd86bdae7831ed123468153d56e17684a2f80" + integrity sha512-VmV99HeCPOyliY/uEGOaKO9EcqDxSBzKDGC7emNCLFzlbK4uty4/cYMKGKTBiZR9AS1rEd63LxrDtbHKR8CsqQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-blur@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.10.1.tgz#2f9f6e494183a4044cffb1883bbdff42aee914ea" + integrity sha512-0PzdzPGuv8RlhiMbLcM0tIekkHhuaPTY+frEWmO8BuCeqW9Tg9W4RxdwZtMqIVRG+kZBgyltYee31Q4JWlu9Hg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.10.1" + core-js "^3.4.1" + +"@jimp/plugin-blur@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.9.5.tgz#404c6a41eb81e53dfc338f08e356dcbea00f68fd" + integrity sha512-FnAEhMW9ZK8D6qCLDeMAloi4h7TCch9ZWFdonj49gwllpvLksBpnL9PTft4dFXCwZgOAq2apYwW7cwTAIfAw4A== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-color@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.10.1.tgz#1b80654cbf4cd0bf6663b5ca94aa7317b8827e3d" + integrity sha512-SmW2+hFtNmQ33WYVsgKvreS8peCc5qItAvqGR58lKNoIMEZSNpyGwIu9g83HtDIImGsXpz3DWGMR1h8sLYCFcQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.10.1" + core-js "^3.4.1" + tinycolor2 "^1.4.1" + +"@jimp/plugin-color@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.9.5.tgz#54ed58df392dc4397d30a4b34d8063da9641d5f1" + integrity sha512-2aFE0tRdhAKCCgh+tFLsLPOSgrk3ttl2TtTP5FAXeKmzlLj7FZ/JKj0waaGWZKdJ+uDxsVpX3EhuK3CfukIyrg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + tinycolor2 "^1.4.1" + +"@jimp/plugin-contain@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.9.5.tgz#51ff0f8b07e02b1fafae6fa83b7b34aeabda6b8e" + integrity sha512-zhaCJnUqd8hhD8IXxbRALU6ZzCWWbQDulc8Tn8Hxnub0si7dlq/DxBQT7og6kCxswBj2zPBtRAHONEwLdt7Nfw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-cover@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.9.5.tgz#bdd140fc200d0340ad3eaa9daf771e7529725301" + integrity sha512-rG7vtx7vV9mHCFR4YP9GzGEsaop0IkMidP3UFPULbDcBdEEkehEG7a0h2X4w/Nt07J3k8wVoXYTjrb/CXpWkaw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-crop@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.9.5.tgz#e0b7d6359d2cad2be1ada2c57aaccca51dc41784" + integrity sha512-yoScC43YhYlswTKyL4fmawGwF73HyuIRpp1R3mXa6qbMA9mjX9QiqNdAIMB3UMHeBcIgkOD/Zy1f90/skBMpxg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-displace@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.9.5.tgz#1d5b59ed90f31d1e095a9589b3f505cad3bb09aa" + integrity sha512-nwfB72qNP8kNyBnlaY0vgJys7RUjvI61Qp3AMMbKKaRSsthCx7aeKU9Cyv+AHMfcVkkt3NdTmh7ScE+hkNFUhA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-dither@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.9.5.tgz#9b705a8961239582193123defb950bba6d2a81a3" + integrity sha512-Pp1ehm5Hon6LcttRG+d+x1UN1ww00P4cyBnMVRR3NMhIfgc0IjQgojik9ZXax3nVj7XkqXJJh8f5uxC1cvYUnA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-flip@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.9.5.tgz#28c1c2e7817327ceedcb8c2508a175e30125e411" + integrity sha512-rKbg8c9ePst3w2t1kxQt2H05/rUR5/pjjafhZ97s01pxH/SOJudy5d76nJGzRBYoaRnxpvDzpN+2+iA08wDY5Q== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-gaussian@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.9.5.tgz#11c91ba2542d129431533b1a7df3e0eda6461e07" + integrity sha512-8HloHpVPgSsoWekslJ5uUPK2ddoLrGXQAVOyo3BT2pVgwbL317+r96NxPGKTxrY20fqex9SQrjx3kHeSWbysEA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-invert@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.9.5.tgz#46b7db7a988373c9c43d14adda3b8f001ef5899a" + integrity sha512-tqfMqQqsU4ulaif0Kk/BydqmG5UbjT67dmMjwnDL7rke+ypJ8tzq7j9QeZ9SDFB+PxUQcy/kPEw/R2Ys7HHi8A== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-mask@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.9.5.tgz#de0044e710f922c3ba422478faa0d676ce2d52f4" + integrity sha512-lIOrKb/VT1laDIA1H1nPOdtOB4TVhMRlxanXoEP8uKdE6a2goqZHXbKLn9itkm0MxtsTlT9KIXwzGxjCV38B3w== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-normalize@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.9.5.tgz#b5b50041608e4403dc3897aeaa6507fcfced91de" + integrity sha512-gayxgPLDp2gynu2IacvdCtqw0bdcC2feUqYOBjTtCpAwIz1KP2Qd6qKjV1dAVGiLO9ESW5maMa0vIBiBkYOovg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-print@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.9.5.tgz#c1021763f56b9dcf6bbd5cef2ce9538a16c36b35" + integrity sha512-/BUSyCfvVhuFdf+rBdH1wbuY8r9J0qhn4Icy7HqO58By7I+V7q7jayoeiLk+zEBsAXpCUbWiZG3KWNtZhLWeQg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + load-bmfont "^1.4.0" + +"@jimp/plugin-resize@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.10.1.tgz#0a294b8dae1efd96ac53bdcd40f7ab58cc2e4f5e" + integrity sha512-aG42+tRmhAYKvybZteSD7s48dAcYSkipyM+e2aizRa0D0FHNIQlIHribiKfRTiX+ewx/fhHVu0vpFKOg0N2hDw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.10.1" + core-js "^3.4.1" + +"@jimp/plugin-resize@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.9.5.tgz#bb965222ffd4addd759ab4eaa1ba53e7ab9423d8" + integrity sha512-vIMleLPbEv0qTE1Mnc7mg5HSFc4l4FxlbDniVUvpi8ZMFa8IkigcTeAgXUKacevNL7uZ66MrnpQ49J3tNE28dQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-rotate@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.9.5.tgz#d2885252b8e7b2e5e24915f6f6d309222f27205d" + integrity sha512-BHlhwUruHNQkOpsfzTE2uuSfmkj5eiIDRSAC8whupUGGXNgS67tZJB6u0qDRIeSP/gWV5tGGwXQNMn3AahwR1Q== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugin-scale@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.9.5.tgz#da9bbf131db46b113e9a5b9846504fb07313508e" + integrity sha512-PDU8F77EPFTcLBVDcJtGUvPXA2acG4KqJMZauHwZLZxuiDEvt9qsDQm4aTKcN/ku8oWZjfGBSOamhx/QNUqV5Q== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + +"@jimp/plugins@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.9.5.tgz#366f279bd95cee8690f83aca7e0038bc5d70a133" + integrity sha512-3hvuXeRLj36ifpwE7I7g5Da9bKl/0y62t90ZN0hdQwhLBjRRF4u1e1JZpyu6EK98Bp+W/c8fJ2iuOsHadJOusg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/plugin-blit" "^0.9.5" + "@jimp/plugin-blur" "^0.9.5" + "@jimp/plugin-color" "^0.9.5" + "@jimp/plugin-contain" "^0.9.5" + "@jimp/plugin-cover" "^0.9.5" + "@jimp/plugin-crop" "^0.9.5" + "@jimp/plugin-displace" "^0.9.5" + "@jimp/plugin-dither" "^0.9.5" + "@jimp/plugin-flip" "^0.9.5" + "@jimp/plugin-gaussian" "^0.9.5" + "@jimp/plugin-invert" "^0.9.5" + "@jimp/plugin-mask" "^0.9.5" + "@jimp/plugin-normalize" "^0.9.5" + "@jimp/plugin-print" "^0.9.5" + "@jimp/plugin-resize" "^0.9.5" + "@jimp/plugin-rotate" "^0.9.5" + "@jimp/plugin-scale" "^0.9.5" + core-js "^3.4.1" + timm "^1.6.1" + +"@jimp/png@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.9.5.tgz#d1dff33a336f40fd5e3c8119bb57890aecbd5113" + integrity sha512-0GPq/XixXcuWIA3gpMCUUj6rhxT78Hu9oDC9reaHUCcC/5cRTd5Eh7wLafZL8EfOZWV3mh2FZtWiY1xaNHHlBQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.5" + core-js "^3.4.1" + pngjs "^3.3.3" + +"@jimp/tiff@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.9.5.tgz#0b4dfcab5238fdabb5725d12a06bb102e12af7c2" + integrity sha512-EcRtiHsAQ9aygRRMWhGTVfitfHwllgt93GE1L8d/iwSlu3e3IIV38MDINdluQUQMU5jcFBcX6eyVVvsgCleGiQ== + dependencies: + "@babel/runtime" "^7.7.2" + core-js "^3.4.1" + utif "^2.0.1" + +"@jimp/types@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.9.5.tgz#32214f76723342b780d2957572f7c2e6efd1d40f" + integrity sha512-62inaxx8zy24WMP+bsg6ZmgsL49oyoGUIGcjDKzvyAY/O6opD+UMNlArhl0xvCCdzriQxbljtSv/8uyHxz4Xbw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/bmp" "^0.9.5" + "@jimp/gif" "^0.9.5" + "@jimp/jpeg" "^0.9.5" + "@jimp/png" "^0.9.5" + "@jimp/tiff" "^0.9.5" + core-js "^3.4.1" + timm "^1.6.1" + +"@jimp/utils@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.10.1.tgz#35187bd28268dbb4cfc2b07c71e59f6be0303bf8" + integrity sha512-Q0ZT2FGPQo3lXkUheAsg0dVWo0Ko+vYCVJLEUxQMxmPiDLUquE22iya+tMONPOaRj1GG3cznaSqaEHDNgoyYbw== + dependencies: + "@babel/runtime" "^7.7.2" + core-js "^3.4.1" + regenerator-runtime "^0.13.3" + +"@jimp/utils@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.9.5.tgz#d661bfb7c2f5aef986efc5bcc7cd3af3e42105ac" + integrity sha512-W9vse4/1AYmOjtIVACoBMdc/2te1zcPURhMYNEyiezCU7hWMdj/Z1mwiWFq3AYCgOG8GPVx0ZQzrgqUfUxfTHQ== + dependencies: + "@babel/runtime" "^7.7.2" + core-js "^3.4.1" + +"@posthtml/esm@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@posthtml/esm/-/esm-1.0.0.tgz#09bcb28a02438dcee22ad1970ca1d85a000ae0cf" + integrity sha512-dEVG+ITnvqKGa4v040tP+n8LOKOqr94qjLva7bE5pnfm2KHJwsKz69J4KMxgWLznbpBJzy8vQfCayEk3vLZnZQ== + +"@restart/context@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" + integrity sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q== + +"@restart/hooks@^0.3.11", "@restart/hooks@^0.3.12": + version "0.3.21" + resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.3.21.tgz#5264d12019ffb844dc1fc44d55517ded7b580ee2" + integrity sha512-Wcu3CFJV+iiqPEIoPVx3/CYnZBRgPeRABo6bLJByRH9ptJXyObn7WYPG7Rv0cg3+55bqcBbG0xEfovzwE2PNXg== + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + +"@types/classnames@^2.2.7": + version "2.2.10" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999" + integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ== + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/favicons@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@types/favicons/-/favicons-5.5.0.tgz#c1cb3d2a14955eedf479f3cc51948630c56e3a64" + integrity sha512-s76OlRaBfqtGu2ZBobnZv2NETfqsQUVfKKlOkKNGo4ArBsqiblodKsnQ3j29hCCgmpQacEfLxealV96za+tzVQ== + dependencies: + "@types/node" "*" + +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/history@*": + version "4.7.5" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860" + integrity sha512-wLD/Aq2VggCJXSjxEwrMafIP51Z+13H78nXIX0ABEuIGhmB5sNGbR113MOKo+yfw+RDo1ZU3DM6yfnnRF/+ouw== + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "13.9.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72" + integrity sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ== + +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + +"@types/q@^1.5.1": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" + integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== + +"@types/react-dom@^16.0.11": + version "16.9.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.5.tgz#5de610b04a35d07ffd8f44edad93a71032d9aaa7" + integrity sha512-BX6RQ8s9D+2/gDhxrj8OW+YD4R+8hj7FEM/OJHGNR0KipE1h1mSsf39YeyC81qafkq+N3rU3h3RFbLSwE5VqUg== + dependencies: + "@types/react" "*" + +"@types/react-router@^4.4.3": + version "4.4.5" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.4.5.tgz#1166997dc7eef2917b5ebce890ebecb32ee5c1b3" + integrity sha512-12+VOu1+xiC8RPc9yrgHCyLI79VswjtuqeS2gPrMcywH6tkc8rGIUhs4LaL3AJPqo5d+RPnfRpNKiJ7MK2Qhcg== + dependencies: + "@types/history" "*" + "@types/react" "*" + +"@types/react@*", "@types/react@^16.7.20", "@types/react@^16.8.23", "@types/react@^16.9.11": + version "16.9.23" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.23.tgz#1a66c6d468ba11a8943ad958a8cb3e737568271c" + integrity sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@*": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" + integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== + +"@types/uglify-js@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" + integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== + dependencies: + source-map "^0.6.1" + +"@types/webpack-sources@*": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.6.tgz#3d21dfc2ec0ad0c77758e79362426a9ba7d7cbcb" + integrity sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.6.1" + +"@types/webpack@^4.4.23": + version "4.41.7" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.7.tgz#22be27dbd4362b01c3954ca9b021dbc9328d9511" + integrity sha512-OQG9viYwO0V1NaNV7d0n79V+n6mjOV30CwgFPIfTzwmk8DHbt+C4f2aBGdCYbo3yFyYD6sjXfqqOjwkl1j+ulA== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn@^6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +add-event-listener@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/add-event-listener/-/add-event-listener-0.0.1.tgz#a76229ebc64c8aefae204a16273a2f255abea2d0" + integrity sha1-p2Ip68ZMiu+uIEoWJzovJVq+otA= + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +any-base@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" + integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +apexcharts-react@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/apexcharts-react/-/apexcharts-react-1.0.0.tgz#258fb12dd2e7a5cb38d74b400e92f18f13e5df55" + integrity sha512-kJbLRJ9B0LmY17Lz4/NWZjAvdEQovcmZ3Gn14zCR5WJQyIBi8YLWAZenf4hEzU3xBfpcp1q8Kbu9c7H8ZQw7oQ== + +apexcharts@^3.10.1: + version "3.16.1" + resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.16.1.tgz#96e6a478e71d2903562087ce2ecf2e88d4cd9a06" + integrity sha512-3MpUk6+clv9tGtb3OQBPRjyLc6g6nHvO2Gk1v8gBhD3tY3MiFi/RP4ItaHyW4SaqBtyK8oHugsgGlanZDTviVQ== + dependencies: + svg.draggable.js "^2.2.2" + svg.easing.js "^2.0.0" + svg.filter.js "^2.0.2" + svg.pathmorphing.js "^0.1.3" + svg.resize.js "^1.4.3" + svg.select.js "^3.0.1" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +author-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" + integrity sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA= + +autoprefixer@^6.3.1: + version "6.7.7" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" + integrity sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ= + dependencies: + browserslist "^1.7.6" + caniuse-db "^1.0.30000634" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^5.2.16" + postcss-value-parser "^3.2.3" + +autoprefixer@^9.6.1: + version "9.7.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.4.tgz#f8bf3e06707d047f0641d87aee8cfb174b2a5378" + integrity sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g== + dependencies: + browserslist "^4.8.3" + caniuse-lite "^1.0.30001020" + chalk "^2.4.2" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.26" + postcss-value-parser "^4.0.2" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +babel-loader@^8.0.5: + version "8.0.6" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" + integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== + dependencies: + find-cache-dir "^2.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + pify "^4.0.1" + +balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +bignumber.js@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" + integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg= + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.1.tgz#8c9b4fb754e80cc86463077722be7b88b4af3f42" + integrity sha512-FL/TdvchukRCuWVxT0YMO/7+L5TNeNrVFvRU2IY63aUyv9mpt8splf2NEr6qXtPo5fya5a66YohQKvGNmLrWNA== + dependencies: + readable-stream "^3.4.0" + +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bmp-js@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.1.tgz#5ad0147099d13a9f38aa7b99af1d6e78666ed37f" + integrity sha1-WtAUcJnROp84qnuZrx1ueGZu038= + +bmp-js@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.3.tgz#64113e9c7cf1202b376ed607bf30626ebe57b18a" + integrity sha1-ZBE+nHzxICs3btYHvzBibr5XsYo= + +bmp-js@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" + integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +bootstrap@^4.3.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01" + integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA== + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: + version "1.7.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" + integrity sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk= + dependencies: + caniuse-db "^1.0.30000639" + electron-to-chromium "^1.2.7" + +browserslist@^4.6.4, browserslist@^4.8.3: + version "4.9.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.9.1.tgz#01ffb9ca31a1aef7678128fc6a2253316aa7287c" + integrity sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw== + dependencies: + caniuse-lite "^1.0.30001030" + electron-to-chromium "^1.3.363" + node-releases "^1.1.50" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-json@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" + integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.2.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" + integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2: + version "12.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" + integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" + integrity sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw== + dependencies: + buffer-json "^2.0.0" + find-cache-dir "^3.0.0" + loader-utils "^1.2.3" + mkdirp "^0.5.1" + neo-async "^2.6.1" + schema-utils "^2.0.0" + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-api@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" + integrity sha1-tTTnxzTE+B7F++isoq0kNUuWLGw= + dependencies: + browserslist "^1.3.6" + caniuse-db "^1.0.30000529" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: + version "1.0.30001035" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001035.tgz#3a182cab9d556a4a02d945f1f739e81c18e73bfa" + integrity sha512-kLUON4XN3tq5Nwl7ZICDw+7/vMynSpRMVYDRkzLL31lgnpa6M2YXYdjst3h+xbzjMgdcveRTnRGE1h/1IcKK6A== + +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001030: + version "1.0.30001035" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz#2bb53b8aa4716b2ed08e088d4dc816a5fe089a1e" + integrity sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chart.js@^2.9.3: + version "2.9.3" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.3.tgz#ae3884114dafd381bc600f5b35a189138aac1ef7" + integrity sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw== + dependencies: + chartjs-color "^2.1.0" + moment "^2.10.2" + +chartjs-color-string@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71" + integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A== + dependencies: + color-name "^1.0.0" + +chartjs-color@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0" + integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w== + dependencies: + chartjs-color-string "^0.6.0" + color-convert "^1.9.3" + +chartjs-plugin-streaming@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/chartjs-plugin-streaming/-/chartjs-plugin-streaming-1.8.0.tgz#3cafcf5e733dbbe0de3ac39df00c65075d83bc5c" + integrity sha512-r7kHyNvSAz12J+W5FBmI/K400z4MXqfNYhA5xaTKJ6PA3ZA6Vq+2d5/OCGyVZF/7UsUDWDRK5tHHYj8jqe+nOg== + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1, chownr@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +clap@^1.0.9: + version "1.2.3" + resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" + integrity sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA== + dependencies: + chalk "^1.1.3" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classnames@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + +clean-css@4.2.x: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +clone@^2.1.1, clone@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +coa@~1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" + integrity sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0= + dependencies: + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.3.0, color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" + integrity sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE= + dependencies: + color-name "^1.0.0" + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^0.11.0: + version "0.11.4" + resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" + integrity sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q= + dependencies: + clone "^1.0.2" + color-convert "^1.3.0" + color-string "^0.3.0" + +color@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" + integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colormin@^1.0.5: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" + integrity sha1-6i90IKcrlogaOKrlnsEkpvcpgTM= + dependencies: + color "^0.11.0" + css-color-names "0.0.4" + has "^1.0.1" + +colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@^2.19.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^3.4.1, core-js@^3.4.5: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" + integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@6.0.5, cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + +css-color-names@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea" + integrity sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w== + dependencies: + camelcase "^5.2.0" + icss-utils "^4.1.0" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.14" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^2.0.6" + postcss-modules-scope "^2.1.0" + postcss-modules-values "^2.0.0" + postcss-value-parser "^3.3.0" + schema-utils "^1.0.0" + +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +css-what@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" + integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano@^3.4.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" + integrity sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg= + dependencies: + autoprefixer "^6.3.1" + decamelize "^1.1.2" + defined "^1.0.0" + has "^1.0.1" + object-assign "^4.0.1" + postcss "^5.0.14" + postcss-calc "^5.2.0" + postcss-colormin "^2.1.8" + postcss-convert-values "^2.3.4" + postcss-discard-comments "^2.0.4" + postcss-discard-duplicates "^2.0.1" + postcss-discard-empty "^2.0.1" + postcss-discard-overridden "^0.1.1" + postcss-discard-unused "^2.2.1" + postcss-filter-plugins "^2.0.0" + postcss-merge-idents "^2.1.5" + postcss-merge-longhand "^2.0.1" + postcss-merge-rules "^2.0.3" + postcss-minify-font-values "^1.0.2" + postcss-minify-gradients "^1.0.1" + postcss-minify-params "^1.0.4" + postcss-minify-selectors "^2.0.4" + postcss-normalize-charset "^1.1.0" + postcss-normalize-url "^3.0.7" + postcss-ordered-values "^2.1.0" + postcss-reduce-idents "^2.2.2" + postcss-reduce-initial "^1.0.0" + postcss-reduce-transforms "^1.0.3" + postcss-svgo "^2.1.1" + postcss-unique-selectors "^2.0.2" + postcss-value-parser "^3.2.3" + postcss-zindex "^2.0.1" + +csso@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.2.tgz#e5f81ab3a56b8eefb7f0092ce7279329f454de3d" + integrity sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg== + dependencies: + css-tree "1.0.0-alpha.37" + +csso@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" + integrity sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U= + dependencies: + clap "^1.0.9" + source-map "^0.5.3" + +csstype@^2.2.0, csstype@^2.6.7: + version "2.6.9" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" + integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== + +cuint@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" + integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +dateformat@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.0.0, debug@^3.1.1, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +dom-converter@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-helpers@^5.0.1, dom-helpers@^5.1.0, dom-helpers@^5.1.2: + version "5.1.3" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.3.tgz#7233248eb3a2d1f74aafca31e52c5299cc8ce821" + integrity sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw== + dependencies: + "@babel/runtime" "^7.6.3" + csstype "^2.6.7" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1, domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.363: + version "1.3.376" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.376.tgz#7cb7b5205564a06c8f8ecfbe832cbd47a1224bb1" + integrity sha512-cv/PYVz5szeMz192ngilmezyPNFkUjuynuL2vNdiqIrio440nfTDdc0JJU0TS2KHLSVCs9gBbt4CFqM+HcBnjw== + +elliptic@^6.0.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: + version "1.17.4" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" + integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-promise@^3.0.2: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" + integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exif-parser@^0.1.12, exif-parser@^0.1.9: + version "0.1.12" + resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" + integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +favicons-webpack-plugin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/favicons-webpack-plugin/-/favicons-webpack-plugin-2.1.0.tgz#a95e88dc234cd8589e16018b3f9f3a518b305f86" + integrity sha512-tHASGU/7pDbjma8Z6c6tmLe4zTcglRPVuE57L+qBCLYu2ELKsXu9h66a8S8Rjb4aFHXvJgTY3voghYzrhEAV6Q== + dependencies: + "@types/favicons" "5.5.0" + cache-loader "^4.1.0" + camelcase "^5.3.1" + favicons "5.5.0" + find-cache-dir "^3.2.0" + find-root "^1.1.0" + loader-utils "^1.2.3" + parse-author "^2.0.0" + +favicons@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/favicons/-/favicons-5.5.0.tgz#4badbecac81ddf2793b8149d0823d97c2077445b" + integrity sha512-xZ4B+fZDuq2y999iorrYq4KuBT3OIZHU+CVfjOWQbjOC1OiU0xbf6pp4Ju/yAfJn7W74RVrC3Cv0oqR5CLvviw== + dependencies: + clone "^2.1.2" + colors "^1.4.0" + core-js "^3.4.5" + image-size "^0.8.3" + jimp "^0.9.3" + jsontoxml "^1.0.1" + lodash.defaultsdeep "^4.6.1" + require-directory "^2.1.1" + sharp "^0.23.3" + through2 "^3.0.1" + tinycolor2 "^1.4.1" + to-ico "^1.1.5" + vinyl "^2.2.0" + xml2js "^0.4.22" + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + +figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +file-loader@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" + integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw== + dependencies: + loader-utils "^1.0.2" + schema-utils "^1.0.0" + +file-type@^3.1.0, file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" + integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.0.0, find-cache-dir@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +findup-sync@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb" + integrity sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ== + dependencies: + debug "^3.0.0" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.11" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" + integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stream@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +gintersect@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/gintersect/-/gintersect-0.1.0.tgz#9a8cb6a80b7d6e955ac33515495b1212627b1816" + integrity sha1-moy2qAt9bpVawzUVSVsSEmJ7GBY= + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +global@~4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + +handle-thing@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" + integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +history@^4.10.1, history@^4.7.2, history@^4.9.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" + integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^3.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^1.0.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@^2.5.0: + version "2.5.5" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" + integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== + +hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-entities@^1.2.0, html-entities@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +html-loader@^1.0.0-alpha.0: + version "1.0.0-alpha.0" + resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-1.0.0-alpha.0.tgz#3f4ae7b490a587619be6d1eaa8ce16683580c642" + integrity sha512-KcuaIRWTU0kFjOJCs32a3JsGNCWkeOak0/F/uvJNp3x/N4McXdqHpcK64cYTozK7QLPKKtUqb9h7wR9K9rYRkg== + dependencies: + "@posthtml/esm" "^1.0.0" + htmlnano "^0.1.6" + loader-utils "^1.1.0" + posthtml "^0.11.2" + schema-utils "^0.4.3" + +html-minifier@^3.2.3: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +html-webpack-plugin@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" + integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= + dependencies: + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + tapable "^1.0.0" + toposort "^1.0.0" + util.promisify "1.0.0" + +htmlnano@^0.1.6: + version "0.1.10" + resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-0.1.10.tgz#a0a548eb4c76ae2cf2423ec7a25c881734d3dea6" + integrity sha512-eTEUzz8VdWYp+w/KUdb99kwao4reR64epUySyZkQeepcyzPQ2n2EPWzibf6QDxmkGy10Kr+CKxYqI3izSbmhJQ== + dependencies: + cssnano "^3.4.0" + object-assign "^4.0.1" + posthtml "^0.11.3" + posthtml-render "^1.1.4" + svgo "^1.0.5" + terser "^3.8.1" + +htmlparser2@^3.3.0, htmlparser2@^3.9.2: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +"http-parser-js@>=0.4.0 <0.4.11": + version "0.4.10" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" + integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +image-size@^0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + +image-size@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.8.3.tgz#f0b568857e034f29baffd37013587f2c0cad8b46" + integrity sha512-SMtq1AJ+aqHB45c3FsB4ERK0UCiA2d3H1uq8s+8T0Pf8A3W4teyBQyaFaktH6xvZqh+npwlKU7i4fJo0r7TYTg== + dependencies: + queue "6.0.1" + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-local@2.0.0, import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +interpret@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip-regex@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" + integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0= + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-function@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4, is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-svg@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" + integrity sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk= + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jimp@^0.2.21: + version "0.2.28" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2" + integrity sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI= + dependencies: + bignumber.js "^2.1.0" + bmp-js "0.0.3" + es6-promise "^3.0.2" + exif-parser "^0.1.9" + file-type "^3.1.0" + jpeg-js "^0.2.0" + load-bmfont "^1.2.3" + mime "^1.3.4" + mkdirp "0.5.1" + pixelmatch "^4.0.0" + pngjs "^3.0.0" + read-chunk "^1.0.1" + request "^2.65.0" + stream-to-buffer "^0.1.0" + tinycolor2 "^1.1.2" + url-regex "^3.0.0" + +jimp@^0.9.3: + version "0.9.5" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.9.5.tgz#78da6ddb33925cfb6b80d502d52a590b141c62ba" + integrity sha512-gjrzz+lT4In7shmP4LV1o/dfL0btnh4W9F5jPCXA6Qw4uEAF8+8GDwAR69hbUQCZH7R5KoCtq81tpfzydoJtSQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/custom" "^0.9.5" + "@jimp/plugins" "^0.9.5" + "@jimp/types" "^0.9.5" + core-js "^3.4.1" + regenerator-runtime "^0.13.3" + +jpeg-js@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.1.2.tgz#135b992c0575c985cfa0f494a3227ed238583ece" + integrity sha1-E1uZLAV1yYXPoPSUoyJ+0jhYPs4= + +jpeg-js@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482" + integrity sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII= + +jpeg-js@^0.3.4: + version "0.3.7" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d" + integrity sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ== + +jquery@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9" + integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ== + +js-base64@^2.1.9: + version "2.5.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" + integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1, js-yaml@~3.7.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" + integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== + dependencies: + minimist "^1.2.0" + +jsontoxml@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jsontoxml/-/jsontoxml-1.0.1.tgz#07fff7f6bfbfa1097d779aec7f041b5046075e70" + integrity sha512-dtKGq0K8EWQBRqcAaePSgKR4Hyjfsz/LkurHSV3Cxk4H+h2fWDeaN2jzABz+ZmOJylgXS7FGeWmbZ6jgYUMdJQ== + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +load-bmfont@^1.2.3, load-bmfont@^1.3.1, load-bmfont@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b" + integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g== + dependencies: + buffer-equal "0.0.1" + mime "^1.3.4" + parse-bmfont-ascii "^1.0.3" + parse-bmfont-binary "^1.0.5" + parse-bmfont-xml "^1.1.4" + phin "^2.9.1" + xhr "^2.0.1" + xtend "^4.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.defaultsdeep@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.union@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.3, lodash@^4.17.4: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +loglevel@^1.6.6: + version "1.6.7" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56" + integrity sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" + integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== + dependencies: + semver "^6.0.0" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +math-expression-evaluator@^1.2.14: + version "1.2.22" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.22.tgz#c14dcb3d8b4d150e5dcea9c68c8dad80309b0d5e" + integrity sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.0, memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +mime@1.6.0, mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.0.3, mime@^2.3.1, mime@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +mini-create-react-context@^0.3.0: + version "0.3.2" + resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz#79fc598f283dd623da8e088b05db8cddab250189" + integrity sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw== + dependencies: + "@babel/runtime" "^7.4.0" + gud "^1.0.0" + tiny-warning "^1.0.2" + +mini-css-extract-plugin@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz#ac0059b02b9692515a637115b0cc9fed3a35c7b0" + integrity sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + integrity sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q= + dependencies: + brace-expansion "^1.0.0" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" + integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== + dependencies: + yallist "^4.0.0" + +minizlib@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3" + integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mobx-react-devtools@^6.0.3: + version "6.1.1" + resolved "https://registry.yarnpkg.com/mobx-react-devtools/-/mobx-react-devtools-6.1.1.tgz#a462b944085cf11ff96fc937d12bf31dab4c8984" + integrity sha512-nc5IXLdEUFLn3wZal65KF3/JFEFd+mbH4KTz/IG5BOPyw7jo8z29w/8qm7+wiCyqVfUIgJ1gL4+HVKmcXIOgqA== + +mobx-react-router@^4.0.5: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mobx-react-router/-/mobx-react-router-4.1.0.tgz#de014848207d8aa32f6a4e67ed861bd2cb6516e5" + integrity sha512-2knsbDqVorWLngZWbdO8tr7xcZXaLpVFsFlCaGaoyZ+EP9erVGRxnlWGqKyFObs3EH1JPLyTDOJ2LPTxb/lB6Q== + +mobx-react@^5.4.3: + version "5.4.4" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-5.4.4.tgz#b3de9c6eabcd0ed8a40036888cb0221ab9568b80" + integrity sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ== + dependencies: + hoist-non-react-statics "^3.0.0" + react-lifecycles-compat "^3.0.2" + +mobx@^5.15.0: + version "5.15.4" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.4.tgz#9da1a84e97ba624622f4e55a0bf3300fb931c2ab" + integrity sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw== + +moment@^2.10.2, moment@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +nan@^2.12.1, nan@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +ngraph.centrality@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ngraph.centrality/-/ngraph.centrality-0.3.0.tgz#8cc0ec0319ef0a374357fc1044c16975b179d09d" + integrity sha1-jMDsAxnvCjdDV/wQRMFpdbF50J0= + +ngraph.events@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/ngraph.events/-/ngraph.events-0.0.3.tgz#38f55316f3d207ad631ff94f6622ca8f2c0e87d0" + integrity sha1-OPVTFvPSB61jH/lPZiLKjywOh9A= + +ngraph.events@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/ngraph.events/-/ngraph.events-0.0.4.tgz#72cb364488dd0fd7f057458449f6a3b17a722d9a" + integrity sha1-css2RIjdD9fwV0WESfajsXpyLZo= + +ngraph.expose@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/ngraph.expose/-/ngraph.expose-0.0.0.tgz#746c34903a3848c45d033b14bc64619ea85fe5aa" + integrity sha1-dGw0kDo4SMRdAzsUvGRhnqhf5ao= + +ngraph.forcelayout@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/ngraph.forcelayout/-/ngraph.forcelayout-0.5.0.tgz#51511c3e1db45d3d5436da75dfb1d6af097916f5" + integrity sha1-UVEcPh20XT1UNtp137HWrwl5FvU= + dependencies: + ngraph.events "0.0.4" + ngraph.physics.simulator "^0.3.0" + +ngraph.fromjson@0.1.9: + version "0.1.9" + resolved "https://registry.yarnpkg.com/ngraph.fromjson/-/ngraph.fromjson-0.1.9.tgz#66910b664c69fa3c50a1ce79dd1dfdd5bab46f6e" + integrity sha1-ZpELZkxp+jxQoc553R391bq0b24= + dependencies: + ngraph.graph "0.0.14" + +ngraph.generators@0.0.19: + version "0.0.19" + resolved "https://registry.yarnpkg.com/ngraph.generators/-/ngraph.generators-0.0.19.tgz#552c0d087f942b9d0d2b0c6ca9aac436befa7659" + integrity sha1-VSwNCH+UK50NKwxsqarENr76dlk= + dependencies: + ngraph.graph "0.0.14" + ngraph.random "0.1.0" + +ngraph.graph@0.0.14: + version "0.0.14" + resolved "https://registry.yarnpkg.com/ngraph.graph/-/ngraph.graph-0.0.14.tgz#d47ac94967c920aaf76952d8a4e73346e1df2db7" + integrity sha1-1HrJSWfJIKr3aVLYpOczRuHfLbc= + dependencies: + ngraph.events "0.0.3" + +ngraph.merge@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ngraph.merge/-/ngraph.merge-0.0.1.tgz#e4e80ce37581a3c96b17d545e3a43c85434b9025" + integrity sha1-5OgM43WBo8lrF9VF46Q8hUNLkCU= + +ngraph.physics.primitives@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ngraph.physics.primitives/-/ngraph.physics.primitives-0.0.7.tgz#5dc9e179ba1f92e6dec774b01cd68914120b795b" + integrity sha1-Xcnhebofkubex3SwHNaJFBILeVs= + +ngraph.physics.simulator@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ngraph.physics.simulator/-/ngraph.physics.simulator-0.3.0.tgz#7ca6fc3e3617c73e1080572eaa8e04dbb77e0102" + integrity sha1-fKb8PjYXxz4QgFcuqo4E27d+AQI= + dependencies: + ngraph.events "0.0.3" + ngraph.expose "0.0.0" + ngraph.merge "0.0.1" + ngraph.physics.primitives "0.0.7" + ngraph.quadtreebh "0.0.4" + ngraph.random "0.0.1" + +ngraph.quadtreebh@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/ngraph.quadtreebh/-/ngraph.quadtreebh-0.0.4.tgz#c700d44e6e4af07b6d05001ba3987ff5e2dcd62c" + integrity sha1-xwDUTm5K8HttBQAbo5h/9eLc1iw= + dependencies: + ngraph.random "0.0.1" + +ngraph.random@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ngraph.random/-/ngraph.random-0.0.1.tgz#c008e2ebbfdffaf17ed10e4bbc913e567166bcf8" + integrity sha1-wAji67/f+vF+0Q5LvJE+VnFmvPg= + +ngraph.random@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ngraph.random/-/ngraph.random-0.1.0.tgz#1b6e9573529e080677da6ffa098790d76a0948a9" + integrity sha1-G26Vc1KeCAZ32m/6CYeQ12oJSKk= + +ngraph.tojson@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/ngraph.tojson/-/ngraph.tojson-0.1.4.tgz#39f0046588440ade622d58734d589d7974a0b3bc" + integrity sha1-OfAEZYhECt5iLVhzTVideXSgs7w= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-abi@^2.7.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.15.0.tgz#51d55cc711bd9e4a24a572ace13b9231945ccb10" + integrity sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg== + dependencies: + semver "^5.4.1" + +node-forge@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" + integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-releases@^1.1.50: + version "1.1.52" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.52.tgz#bcffee3e0a758e92e44ecfaecd0a47554b0bcba9" + integrity sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ== + dependencies: + semver "^6.3.0" + +noop-logger@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^1.4.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.1, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@^1.0.2, nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-is@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" + integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +omggif@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" + integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-locale@^3.0.0, os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@^1.0.5, pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parse-asn1@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-author@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" + integrity sha1-00YL8d3Q367tQtp1QkLmX7aEqB8= + dependencies: + author-regex "^1.0.0" + +parse-bmfont-ascii@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" + integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU= + +parse-bmfont-binary@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" + integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY= + +parse-bmfont-xml@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389" + integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ== + dependencies: + xml-parse-from-string "^1.0.0" + xml2js "^0.4.5" + +parse-headers@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" + integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse-png@^1.0.0, parse-png@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/parse-png/-/parse-png-1.1.2.tgz#f5c2ad7c7993490986020a284c19aee459711ff2" + integrity sha1-9cKtfHmTSQmGAgooTBmu5FlxH/I= + dependencies: + pngjs "^3.2.0" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +phin@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" + integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pixelmatch@^4.0.0, pixelmatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" + integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ= + dependencies: + pngjs "^3.0.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pngjs@^3.0.0, pngjs@^3.2.0, pngjs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + +popper.js@^1.15.0, popper.js@^1.16.0, popper.js@^1.16.1: + version "1.16.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== + +portfinder@^1.0.25: + version "1.0.25" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" + integrity sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^6.0.2" + +postcss-browser-reporter@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/postcss-browser-reporter/-/postcss-browser-reporter-0.5.0.tgz#ae069dd086d57388d196e1dac39cb8d7626feb48" + integrity sha1-rgad0IbVc4jRluHaw5y412Jv60g= + dependencies: + postcss "^5.0.4" + +postcss-calc@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" + integrity sha1-d7rnypKK2FcW4v2kLyYb98HWW14= + dependencies: + postcss "^5.0.2" + postcss-message-helpers "^2.0.0" + reduce-css-calc "^1.2.6" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-colormin@^2.1.8: + version "2.2.2" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" + integrity sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks= + dependencies: + colormin "^1.0.5" + postcss "^5.0.13" + postcss-value-parser "^3.2.3" + +postcss-convert-values@^2.3.4: + version "2.6.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" + integrity sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0= + dependencies: + postcss "^5.0.11" + postcss-value-parser "^3.1.2" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-discard-comments@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" + integrity sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0= + dependencies: + postcss "^5.0.14" + +postcss-discard-duplicates@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" + integrity sha1-uavye4isGIFYpesSq8riAmO5GTI= + dependencies: + postcss "^5.0.4" + +postcss-discard-empty@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" + integrity sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU= + dependencies: + postcss "^5.0.14" + +postcss-discard-overridden@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" + integrity sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg= + dependencies: + postcss "^5.0.16" + +postcss-discard-unused@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" + integrity sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM= + dependencies: + postcss "^5.0.14" + uniqs "^2.0.0" + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-filter-plugins@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz#82245fdf82337041645e477114d8e593aa18b8ec" + integrity sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ== + dependencies: + postcss "^5.0.4" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" + integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== + dependencies: + postcss "^7.0.2" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-import@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.1.tgz#cf8c7ab0b5ccab5649024536e565f841928b7153" + integrity sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw== + dependencies: + postcss "^7.0.1" + postcss-value-parser "^3.2.3" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-initial@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" + integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== + dependencies: + lodash.template "^4.5.0" + postcss "^7.0.2" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-load-config@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" + integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + +postcss-merge-idents@^2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" + integrity sha1-TFUwMTwI4dWzu/PSu8dH4njuonA= + dependencies: + has "^1.0.1" + postcss "^5.0.10" + postcss-value-parser "^3.1.1" + +postcss-merge-longhand@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" + integrity sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg= + dependencies: + postcss "^5.0.4" + +postcss-merge-rules@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" + integrity sha1-0d9d+qexrMO+VT8OnhDofGG19yE= + dependencies: + browserslist "^1.5.2" + caniuse-api "^1.5.2" + postcss "^5.0.4" + postcss-selector-parser "^2.2.2" + vendors "^1.0.0" + +postcss-message-helpers@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" + integrity sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4= + +postcss-minify-font-values@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" + integrity sha1-S1jttWZB66fIR0qzUmyv17vey2k= + dependencies: + object-assign "^4.0.1" + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-minify-gradients@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" + integrity sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE= + dependencies: + postcss "^5.0.12" + postcss-value-parser "^3.3.0" + +postcss-minify-params@^1.0.4: + version "1.2.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" + integrity sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM= + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.2" + postcss-value-parser "^3.0.2" + uniqs "^2.0.0" + +postcss-minify-selectors@^2.0.4: + version "2.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" + integrity sha1-ssapjAByz5G5MtGkllCBFDEXNb8= + dependencies: + alphanum-sort "^1.0.2" + has "^1.0.1" + postcss "^5.0.14" + postcss-selector-parser "^2.0.0" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63" + integrity sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + postcss-value-parser "^3.3.1" + +postcss-modules-scope@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" + integrity sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64" + integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w== + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^7.0.6" + +postcss-nesting@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + +postcss-normalize-charset@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" + integrity sha1-757nEhLX/nWceO0WL2HtYrXLk/E= + dependencies: + postcss "^5.0.5" + +postcss-normalize-url@^3.0.7: + version "3.0.8" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" + integrity sha1-EI90s/L82viRov+j6kWSJ5/HgiI= + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^1.4.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + +postcss-ordered-values@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" + integrity sha1-7sbCpntsQSqNsgQud/6NpD+VwR0= + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.1" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@^6.5.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-reduce-idents@^2.2.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" + integrity sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM= + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-reduce-initial@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" + integrity sha1-aPgGlfBF0IJjqHmtJA343WT2ROo= + dependencies: + postcss "^5.0.4" + +postcss-reduce-transforms@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" + integrity sha1-/3b02CEkN7McKYpC0uFEQCV3GuE= + dependencies: + has "^1.0.1" + postcss "^5.0.8" + postcss-value-parser "^3.0.1" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + +postcss-reporter@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" + integrity sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw== + dependencies: + chalk "^2.4.1" + lodash "^4.17.11" + log-symbols "^2.2.0" + postcss "^7.0.7" + +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" + integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" + integrity sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A= + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^2.1.1: + version "2.1.6" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" + integrity sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0= + dependencies: + is-svg "^2.0.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + svgo "^0.7.0" + +postcss-unique-selectors@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" + integrity sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0= + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss-url@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-url/-/postcss-url-8.0.0.tgz#7b10059bd12929cdbb1971c60f61a0e5af86b4ca" + integrity sha512-E2cbOQ5aii2zNHh8F6fk1cxls7QVFZjLPSrqvmiza8OuXLzIpErij8BDS5Y3STPfJgpIMNCPEr8JlKQWEoozUw== + dependencies: + mime "^2.3.1" + minimatch "^3.0.4" + mkdirp "^0.5.0" + postcss "^7.0.2" + xxhashjs "^0.2.1" + +postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" + integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== + +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-zindex@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" + integrity sha1-0hCd3AVbka9n/EyzsCWUZjnSryI= + dependencies: + has "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.8, postcss@^5.2.16: + version "5.2.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" + integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg== + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: + version "7.0.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" + integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +posthtml-parser@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.4.2.tgz#a132bbdf0cd4bc199d34f322f5c1599385d7c6c1" + integrity sha512-BUIorsYJTvS9UhXxPTzupIztOMVNPa/HtAm9KHni9z6qEfiJ1bpOBL5DfUOL9XAc3XkLIEzBzpph+Zbm4AdRAg== + dependencies: + htmlparser2 "^3.9.2" + +posthtml-render@^1.1.4, posthtml-render@^1.1.5: + version "1.2.0" + resolved "https://registry.yarnpkg.com/posthtml-render/-/posthtml-render-1.2.0.tgz#3df0c800a8bbb95af583a94748520469477addf4" + integrity sha512-dQB+hoAKDtnI94RZm/wxBUH9My8OJcXd0uhWmGh2c7tVtQ85A+OS3yCN3LNbFtPz3bViwBJXAeoi+CBGMXM0DA== + +posthtml@^0.11.2, posthtml@^0.11.3: + version "0.11.6" + resolved "https://registry.yarnpkg.com/posthtml/-/posthtml-0.11.6.tgz#e349d51af7929d0683b9d8c3abd8166beecc90a8" + integrity sha512-C2hrAPzmRdpuL3iH0TDdQ6XCc9M7Dcc3zEW5BLerY65G4tWWszwv6nG/ksi6ul5i2mx22ubdljgktXCtNkydkw== + dependencies: + posthtml-parser "^0.4.1" + posthtml-render "^1.1.5" + +prebuild-install@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.3.tgz#ef4052baac60d465f5ba6bf003c9c1de79b9da8e" + integrity sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.0" + mkdirp "^0.5.1" + napi-build-utils "^1.0.1" + node-abi "^2.7.0" + noop-logger "^0.1.1" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + which-pm-runs "^1.0.0" + +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prettier@^1.16.0: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +pretty-error@^2.0.2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" + integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +prettysize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prettysize/-/prettysize-2.0.0.tgz#902c02480d865d9cc0813011c9feb4fa02ce6996" + integrity sha512-VVtxR7sOh0VsG8o06Ttq5TrI1aiZKmC+ClSn4eBPaNf4SHr5lzbYW+kYGX3HocBL/MfpVrRfFZ9V3vCbLaiplg== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +prop-types-extra@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" + integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== + dependencies: + react-is "^16.3.2" + warning "^4.0.0" + +prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.28: + version "1.7.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" + integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0, querystring@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +queue@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791" + integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg== + dependencies: + inherits "~2.0.3" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-apexcharts@^1.3.3: + version "1.3.6" + resolved "https://registry.yarnpkg.com/react-apexcharts/-/react-apexcharts-1.3.6.tgz#6c06e5dacfddd0e0373ec8f614503e655c049122" + integrity sha512-ahpMOnuw1ZdD3/fkk9MYRLpqYQ66cZz72+he1R00HaT1VcSjfYc9editQDhE2jGRDuxubmaxVcO3z4FtAk5N0w== + dependencies: + prop-types "^15.5.7" + +react-bootstrap@^1.0.0-beta.16: + version "1.0.0-beta.17" + resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.0.0-beta.17.tgz#09d4789633b2fb24d408fa493b4a80a496e87c82" + integrity sha512-7VP9doezV4rX0EcajzMvyD6ywtrLfulF3ZAev+uTx8syWQybUkccOpecUO5kPomng/bJMgK/h+44PkZ15Dv44g== + dependencies: + "@babel/runtime" "^7.4.2" + "@restart/context" "^2.1.4" + "@restart/hooks" "^0.3.11" + "@types/react" "^16.8.23" + classnames "^2.2.6" + dom-helpers "^5.1.2" + invariant "^2.2.4" + popper.js "^1.16.0" + prop-types "^15.7.2" + prop-types-extra "^1.1.0" + react-overlays "^2.1.0" + react-transition-group "^4.0.0" + uncontrollable "^7.0.0" + warning "^4.0.3" + +react-chartjs-2@^2.8.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-2.9.0.tgz#d054dbdd763fbe9a76296a4ae0752ea549b76d9e" + integrity sha512-IYwqUUnQRAJ9SNA978vxulHJTcUFTJk2LDVfbAyk0TnJFZZG7+6U/2flsE4MCw6WCbBjTTypy8T82Ch7XrPtRw== + dependencies: + lodash "^4.17.4" + prop-types "^15.5.8" + +react-dom@^16.7.0: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866" + integrity sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.0" + +react-hot-loader@^4.6.3: + version "4.12.19" + resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.19.tgz#99a1c763352828f404fa51cd887c5e16bb5b74d1" + integrity sha512-p8AnA4QE2GtrvkdmqnKrEiijtVlqdTIDCHZOwItkI9kW51bt5XnQ/4Anz8giiWf9kqBpEQwsmnChDCAFBRyR/Q== + dependencies: + fast-levenshtein "^2.0.6" + global "^4.3.0" + hoist-non-react-statics "^3.3.0" + loader-utils "^1.1.0" + prop-types "^15.6.1" + react-lifecycles-compat "^3.0.4" + shallowequal "^1.1.0" + source-map "^0.7.3" + +react-icons@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.10.0.tgz#6c217a2dde2e8fa8d293210023914b123f317297" + integrity sha512-WsQ5n1JToG9VixWilSo1bHv842Cj5aZqTGiS3Ud47myF6aK7S/IUY2+dHcBdmkQcCFRuHsJ9OMUI0kTDfjyZXQ== + dependencies: + camelcase "^5.0.0" + +react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" + integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== + +react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-overlays@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-2.1.1.tgz#ffe2090c4a10da6b8947a1c7b1a67d0457648a0d" + integrity sha512-gaQJwmb8Ij2IGVt4D1HmLtl4A0mDVYxlsv/8i0dHWK7Mw0kNat6ORelbbEWzaXTK1TqMeQtJw/jraL3WOADz3w== + dependencies: + "@babel/runtime" "^7.4.5" + "@restart/hooks" "^0.3.12" + dom-helpers "^5.1.0" + popper.js "^1.15.0" + prop-types "^15.7.2" + uncontrollable "^7.0.0" + warning "^4.0.3" + +react-router-bootstrap@^0.25.0: + version "0.25.0" + resolved "https://registry.yarnpkg.com/react-router-bootstrap/-/react-router-bootstrap-0.25.0.tgz#5d1a99b5b8a2016c011fc46019d2397e563ce0df" + integrity sha512-/22eqxjn6Zv5fvY2rZHn57SKmjmJfK7xzJ6/G1OgxAjLtKVfWgV5sn41W2yiqzbtV5eE4/i4LeDLBGYTqx7jbA== + dependencies: + prop-types "^15.5.10" + +react-router-dom@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18" + integrity sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.1.2" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.1.2.tgz#6ea51d789cb36a6be1ba5f7c0d48dd9e817d3418" + integrity sha512-yjEuMFy1ONK246B+rsa0cUam5OeAQ8pyclRDgpxuSCrAlJ1qN9uZ5IgyKC7gQg0w8OM50NXHEegPh/ks9YuR2A== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.3.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e" + integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg== + dependencies: + history "^4.7.2" + hoist-non-react-statics "^2.5.0" + invariant "^2.2.4" + loose-envify "^1.3.1" + path-to-regexp "^1.7.0" + prop-types "^15.6.1" + warning "^4.0.1" + +react-transition-group@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.3.0.tgz#fea832e386cf8796c58b61874a3319704f5ce683" + integrity sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + +react@^16.7.0: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.13.0.tgz#d046eabcdf64e457bbeed1e792e235e1b9934cf7" + integrity sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= + dependencies: + pify "^2.3.0" + +read-chunk@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194" + integrity sha1-X2jKswfmY/GZk1J9m1icrORmEZQ= + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +"readable-stream@2 || 3", readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +recursive-readdir-sync@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz#1dbf6d32f3c5bb8d3cde97a6c588d547a9e13d56" + integrity sha1-Hb9tMvPFu4083pemxYjVR6nhPVY= + +reduce-css-calc@^1.2.6: + version "1.3.0" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= + dependencies: + balanced-match "^0.4.2" + math-expression-evaluator "^1.2.14" + reduce-function-call "^1.0.1" + +reduce-function-call@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" + integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ== + dependencies: + balanced-match "^1.0.0" + +regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" + integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" + integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== + dependencies: + css-select "^1.1.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" + strip-ansi "^3.0.0" + utila "^0.4.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@^2.65.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resize-img@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/resize-img/-/resize-img-1.1.2.tgz#fad650faf3ef2c53ea63112bc272d95e9d92550e" + integrity sha1-+tZQ+vPvLFPqYxErwnLZXp2SVQ4= + dependencies: + bmp-js "0.0.1" + file-type "^3.8.0" + get-stream "^2.0.0" + jimp "^0.2.21" + jpeg-js "^0.1.1" + parse-png "^1.1.1" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-pathname@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.1.7, resolve@^1.3.2: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + dependencies: + path-parse "^1.0.6" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@>=0.6.0, sax@~1.2.1, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scheduler@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.0.tgz#a715d56302de403df742f4a9be11975b32f5698d" + integrity sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^0.4.3: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.0.0: + version "2.6.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" + integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.7: + version "1.10.7" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" + integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== + dependencies: + node-forge "0.9.0" + +semver@^5.0.1, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +sharp@^0.23.3: + version "0.23.4" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.23.4.tgz#ca36067cb6ff7067fa6c77b01651cb9a890f8eb3" + integrity sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q== + dependencies: + color "^3.1.2" + detect-libc "^1.0.3" + nan "^2.14.0" + npmlog "^4.1.2" + prebuild-install "^5.3.3" + semver "^6.3.0" + simple-get "^3.1.0" + tar "^5.0.5" + tunnel-agent "^0.6.0" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^3.0.3, simple-get@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +simplesvg@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/simplesvg/-/simplesvg-0.0.10.tgz#37d2ec18de2c154dd9b69f79e8ad20bf1e1e5fdd" + integrity sha1-N9LsGN4sFU3Ztp956K0gvx4eX90= + dependencies: + add-event-listener "0.0.1" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" + integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.19: + version "0.3.19" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" + integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.0.1" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.10, source-map-support@~0.5.12: + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" + integrity sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +stream-to-buffer@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9" + integrity sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk= + dependencies: + stream-to "~0.2.0" + +stream-to@~0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" + integrity sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0= + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.trimleft@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" + integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" + integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@^0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + +supports-color@6.1.0, supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +svg.draggable.js@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz#c514a2f1405efb6f0263e7958f5b68fce50603ba" + integrity sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw== + dependencies: + svg.js "^2.0.1" + +svg.easing.js@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/svg.easing.js/-/svg.easing.js-2.0.0.tgz#8aa9946b0a8e27857a5c40a10eba4091e5691f12" + integrity sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI= + dependencies: + svg.js ">=2.3.x" + +svg.filter.js@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/svg.filter.js/-/svg.filter.js-2.0.2.tgz#91008e151389dd9230779fcbe6e2c9a362d1c203" + integrity sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM= + dependencies: + svg.js "^2.2.5" + +svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/svg.js/-/svg.js-2.7.1.tgz#eb977ed4737001eab859949b4a398ee1bb79948d" + integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA== + +svg.pathmorphing.js@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz#c25718a1cc7c36e852ecabc380e758ac09bb2b65" + integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww== + dependencies: + svg.js "^2.4.0" + +svg.resize.js@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/svg.resize.js/-/svg.resize.js-1.4.3.tgz#885abd248e0cd205b36b973c4b578b9a36f23332" + integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw== + dependencies: + svg.js "^2.6.5" + svg.select.js "^2.1.2" + +svg.select.js@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-2.1.2.tgz#e41ce13b1acff43a7441f9f8be87a2319c87be73" + integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ== + dependencies: + svg.js "^2.2.5" + +svg.select.js@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-3.0.1.tgz#a4198e359f3825739226415f82176a90ea5cc917" + integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw== + dependencies: + svg.js "^2.6.5" + +svgo@^0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" + integrity sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U= + dependencies: + coa "~1.0.1" + colors "~1.1.2" + csso "~2.3.1" + js-yaml "~3.7.0" + mkdirp "~0.5.1" + sax "~1.2.1" + whet.extend "~0.9.9" + +svgo@^1.0.5: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar-fs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad" + integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== + dependencies: + chownr "^1.1.1" + mkdirp "^0.5.1" + pump "^3.0.0" + tar-stream "^2.0.0" + +tar-stream@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" + integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== + dependencies: + bl "^4.0.1" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/tar/-/tar-5.0.5.tgz#03fcdb7105bc8ea3ce6c86642b9c942495b04f93" + integrity sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ== + dependencies: + chownr "^1.1.3" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.0" + mkdirp "^0.5.0" + yallist "^4.0.0" + +terser-webpack-plugin@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^3.8.1: + version "3.17.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2" + integrity sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ== + dependencies: + commander "^2.19.0" + source-map "~0.6.1" + source-map-support "~0.5.10" + +terser@^4.1.2: + version "4.6.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.6.tgz#da2382e6cafbdf86205e82fb9a115bd664d54863" + integrity sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +timm@^1.6.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.2.tgz#dfd8c6719f7ba1fcfc6295a32670a1c6d166c0bd" + integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw== + +tiny-invariant@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" + integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + +tiny-warning@^1.0.0, tiny-warning@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +tinycolor2@^1.1.2, tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-ico@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/to-ico/-/to-ico-1.1.5.tgz#1d32da5f2c90922edee6b686d610c54527b5a8d5" + integrity sha512-5kIh7m7bkIlqIESEZkL8gAMMzucXKfPe3hX2FoDY5HEAfD9OJU+Qh9b6Enp74w0qRcxVT5ejss66PHKqc3AVkg== + dependencies: + arrify "^1.0.1" + buffer-alloc "^1.1.0" + image-size "^0.5.0" + parse-png "^1.0.0" + resize-img "^1.1.0" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +toposort@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" + integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +ts-loader@^5.3.3: + version "5.4.5" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.4.5.tgz#a0c1f034b017a9344cef0961bfd97cc192492b8b" + integrity sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^3.1.4" + semver "^5.0.1" + +tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tsx-control-statements@2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/tsx-control-statements/-/tsx-control-statements-2.17.1.tgz#1afc67e03c90d489537ed3a31ec0ad2116592e6b" + integrity sha512-KiacW90lksaaoRrh5A4P9CbnhU4Bxvb99IJ2QAsybe4kMv2lF9pbNCFRQI6IofLGMZIHQvw1jEei04fhiIcIxQ== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@^3.2.4: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +uncontrollable@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.1.1.tgz#f67fed3ef93637126571809746323a9db815d556" + integrity sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q== + dependencies: + "@babel/runtime" "^7.6.3" + "@types/react" "^16.9.11" + invariant "^2.2.4" + react-lifecycles-compat "^3.0.4" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" + integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== + dependencies: + loader-utils "^1.1.0" + mime "^2.0.3" + schema-utils "^1.0.0" + +url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url-regex@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" + integrity sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ= + dependencies: + ip-regex "^1.0.1" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +utif@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" + integrity sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg== + dependencies: + pako "^1.0.5" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@^0.4.0, utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1, uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + +value-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" + integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vivagraphjs@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/vivagraphjs/-/vivagraphjs-0.12.0.tgz#6fd06ef6136aaeca5cffea86d6d6f8bfaff7f52b" + integrity sha512-Air+vUHXAWj8NTWUnbU800yKC7SiHpCVwpKIPfDtr5436YoMd7cpg8blt6Fn9xarx+sz1osRxGHBHTaHvcsR6Q== + dependencies: + gintersect "0.1.0" + ngraph.centrality "0.3.0" + ngraph.events "0.0.3" + ngraph.forcelayout "0.5.0" + ngraph.fromjson "0.1.9" + ngraph.generators "0.0.19" + ngraph.graph "0.0.14" + ngraph.merge "0.0.1" + ngraph.random "0.0.1" + ngraph.tojson "0.1.4" + simplesvg "0.0.10" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +warning@^4.0.0, warning@^4.0.1, warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + +watchpack@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.1.tgz#280da0a8718592174010c078c7585a74cd8cd0e2" + integrity sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA== + dependencies: + chokidar "^2.1.8" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cleanup-plugin@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/webpack-cleanup-plugin/-/webpack-cleanup-plugin-0.5.1.tgz#df2d706bd75364c06e65b051186316d674eb96af" + integrity sha1-3y1wa9dTZMBuZbBRGGMW1nTrlq8= + dependencies: + lodash.union "4.6.0" + minimatch "3.0.3" + recursive-readdir-sync "1.0.6" + +webpack-cli@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" + integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== + dependencies: + chalk "2.4.2" + cross-spawn "6.0.5" + enhanced-resolve "4.1.0" + findup-sync "3.0.0" + global-modules "2.0.0" + import-local "2.0.0" + interpret "1.2.0" + loader-utils "1.2.3" + supports-color "6.1.0" + v8-compile-cache "2.0.3" + yargs "13.2.4" + +webpack-dev-middleware@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@^3.1.14: + version "3.10.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz#f35945036813e57ef582c2420ef7b470e14d3af0" + integrity sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.2.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.6" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.25" + schema-utils "^1.0.0" + selfsigned "^1.10.7" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "0.3.19" + sockjs-client "1.4.0" + spdy "^4.0.1" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "12.0.5" + +webpack-hot-middleware@^2.24.3: + version "2.25.0" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" + integrity sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA== + dependencies: + ansi-html "0.0.7" + html-entities "^1.2.0" + querystring "^0.2.0" + strip-ansi "^3.0.0" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.43.0: + version "4.43.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.43.0.tgz#c48547b11d563224c561dad1172c8aa0b8a678e6" + integrity sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.6.1" + webpack-sources "^1.4.1" + +websocket-driver@>=0.5.1: + version "0.7.3" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" + integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== + dependencies: + http-parser-js ">=0.4.0 <0.4.11" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whet.extend@~0.9.9: + version "0.9.9" + resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" + integrity sha1-+HfVv2SMl+WqVC+twW1qJZucEaE= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + +which@^1.2.14, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +xhr@^2.0.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xml-parse-from-string@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" + integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= + +xml2js@^0.4.22, xml2js@^0.4.5: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +xxhashjs@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8" + integrity sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw== + dependencies: + cuint "^0.2.2" + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^13.1.0: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yargs@13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" diff --git a/plugins/dashboard/livefeed.go b/plugins/dashboard/livefeed.go new file mode 100644 index 0000000000000000000000000000000000000000..8e491becd120cd28f612d878d8af1e54ad27b828 --- /dev/null +++ b/plugins/dashboard/livefeed.go @@ -0,0 +1,54 @@ +package dashboard + +import ( + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/workerpool" +) + +var liveFeedWorkerCount = 1 +var liveFeedWorkerQueueSize = 50 +var liveFeedWorkerPool *workerpool.WorkerPool + +func configureLiveFeed() { + liveFeedWorkerPool = workerpool.New(func(task workerpool.Task) { + task.Param(0).(*message.CachedMessage).Consume(func(message *message.Message) { + broadcastWsMessage(&wsmsg{MsgTypeMessage, &msg{message.Id().String(), 0}}) + }) + + task.Return(nil) + }, workerpool.WorkerCount(liveFeedWorkerCount), workerpool.QueueSize(liveFeedWorkerQueueSize)) +} + +func runLiveFeed() { + newMsgRateLimiter := time.NewTicker(time.Second / 10) + notifyNewMsg := events.NewClosure(func(message *message.CachedMessage, metadata *tangle.CachedMessageMetadata) { + metadata.Release() + + select { + case <-newMsgRateLimiter.C: + liveFeedWorkerPool.TrySubmit(message) + default: + message.Release() + } + }) + + if err := daemon.BackgroundWorker("Dashboard[MsgUpdater]", func(shutdownSignal <-chan struct{}) { + messagelayer.Tangle().Events.MessageAttached.Attach(notifyNewMsg) + liveFeedWorkerPool.Start() + <-shutdownSignal + log.Info("Stopping Dashboard[MsgUpdater] ...") + messagelayer.Tangle().Events.MessageAttached.Detach(notifyNewMsg) + newMsgRateLimiter.Stop() + liveFeedWorkerPool.Stop() + log.Info("Stopping Dashboard[MsgUpdater] ... done") + }, shutdown.PriorityDashboard); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} diff --git a/plugins/dashboard/packrd/packed-packr.go b/plugins/dashboard/packrd/packed-packr.go new file mode 100644 index 0000000000000000000000000000000000000000..1dce2fa62d0cdb5390dbd1112f5d52d72ae49fa8 --- /dev/null +++ b/plugins/dashboard/packrd/packed-packr.go @@ -0,0 +1,75 @@ +// +build !skippackr +// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT. + +// You can use the "packr2 clean" command to clean up this, +// and any other packr generated files. +package packrd + +import ( + "github.com/gobuffalo/packr/v2" + "github.com/gobuffalo/packr/v2/file/resolver" +) + +var _ = func() error { + const gk = "146aabd0d057fd435d4dba21e21a4978" + g := packr.New(gk, "") + hgr, err := resolver.NewHexGzip(map[string]string{ + "04f9f8b72e32aedb4d0f836ef9ad9e65": "1f8b08000000000000ffacbd5957e3b81630fa5f58f556e94301359efb7265c7092623190aa86f7d8ba5c44a62706c63d921e1fef9bbf620590e7417dd7d7810b6ac716b6bcf52febf939d2a749ca527ffbd689de8ac2a964a9ffcf7ff9c3cab452e978fff3d3d3dfdcf7f4ed32c52f7db2caa12a54f0b2597e5699c466aff9f077dd2faabb2db6cb13f4de2053efc87727f5b093bf8a3c8aa5215a74a6f1b19bfadfdff2ee44225a7459596f1569d6e5492ab42633b6a5faa34d2ef1af51f34cd28d625bee3eb7f94defe9b01c4e9461571a9fb59a67f0f877a187f2471a98ec60259ff763cd9e2412dcb9bb8dc6455392eb25c1565acde39bc324e0f7fc4e94e16b14c1952cdbc770daf503a4b76ea8f5c969b546e15af7833f3b7adec6452a93fd45325136cc079ff6ddd4daccbac38603d7efe7d7ff14eae0b996f1ef4a92e96f8fedb4a7991e57f94875ce9776e1f17f1ff88b2edabdd0099bf6d25c581fe47ed545abeb7675d1e12f54792c94815b4b4067fe21470660adf759896193ecde4fab74d2eb57eb34199c7bfaf9b48ad0111de3b7e9ef356156bf5b7805d1632d5711967e91feb22ab7204f9cc667621cfcfd252edcb77b608ebf6b7065dc8f4fd75f8d3e9a28a93284e4fd749b67807ce1fe3ef8d5a74fbd0d8faf775799898be7394c7dd85695e95a751b6c587814ce5fa1da4fd4f5a29e43a8d8a2c7ff746d8e7997e2f56bc0da85c165af95992fd7ed03adee689d2bbf57b59669cc67f2c0b254bc5c47f49e846bb86d8c87b1a02daf94799fd51a8b5dae7efacb48ed352155abd9bc3ff0522e1f2044875fe7633f3324ef469942dabad4aff5d23699524ffaa8145913d6b5584e92afb872dace2340a12055319674448fe21b2d780fda79b86460494f79fd65dabb21d6f550a72e3ef61ca9b6e95154b95c84356bd17b3b862be39e878a9ffa3e36d95c8322bfe2162d2d80bb5fc3ddd7e1ba7610f56c53b44913fdf11a24ce4dfc742a7817e9c3e8e8b6c5dc8dfb3fdbf68669845ea7fd04c3f4eff1538a64f95fc0700fd19abe753bd5b77210f50e3770d9098fb87d43a5ea77f4b1a88df2b6f6cb258977fa459ca345b97b28c979a68f69f7cfccff2e1f763cf8b6ca9b425427f5f3025fdeedddbb4c8b60f3a7b2f94b85699fd8d3ac72314c93a2be272b3d5a74b9596854ce2f2f70238f75cd7f87b2376eac11822b52ed4ef31f1edca0b553e2b95a64abf9b1a1eb5b04c32adfe457db5c48c78f91ec8fd05fc410194e5bbc8fadbe4d54a0f93f7d0592348aa14bacd8abf29dc3bf5feb518fd279c5f2e1f9f6511f9d9369765bc48d43b05893fe55d49bc38d57911a7bfd797b88da74a4665a1d4e2bdb2f6eb7af0f91f75a755514e4bb97cfc27b5f5546ed5bbc59dbf84d822abde63b7f9cb36404de88010f2bf58bcff4143aa4a40a62cd51a71f8df3546fa829745ef269ca69dbc88b77119effeae66edca73ffdada70bcfbfad4ee324b7529d37f2ab091acbc956bf53f9277b0ad7f26ae60fd770b2cb5ce888b9b6df3f81d76d366ad086856f11e91e1cddeee4bb5cd1359febe5b19457fe06aff91c4ba049afc0f571d0155a83452c53fd64d9ee334ca9edf49a5c9c4bb7ce0a7ffe44516554b2457dbf8f724cb31e7ade4b2cc8ac34d5c6e669b227b8ed3f574136fdf25de993600f81318c7b8c8f219644dd5b250bfc7fe2345bff12dd6b228e47b85232bf45a98fc11ebbf0b96daea55b71265dbbfdb8c5e6e143cbd179beaf2d0ad7dfbbbdd46d9f60fd7445ea86db6537e22df219cfd85057199a5abf8f73cff5d36c87fd38a3f9dfe8d868e8121a3e87d9038aeb891fa5f83b0c20dee6fe2241ac83c7f8f08f57e93eebff1a2480d72d26c13eb308dcb5826f18b8aa0c1ffdb3a419bf5c97fffcf09b573d23a51fb3c2b4a8d4fa54aa329298327ad93e8a475b238699d8c505d3d699d6805b4a0cc803e8c5627ad93fbfb1cdeefef4f5a2702f6f549eb243f699d6ca41e3da7ecc039604152764f5a27f6015b3c699dc427ad13fc50acd1b80679894ad7e5065a33fd9db44e963249a05c9e27d066b98935368dbe1578cc4e5a27db93d6c9f4b05d6450342e4920871ed41e3ac4b230b72c5558b95012e60945140e023aad34f4ad8a02abdedfeb9c8b2db37429a19d60309edddd8bc944dc9db44e5685522fca668fbcabc09f9db44ed6aa1caa7d19425532840374a1e0365becbb550c1f563286b16e95d6720ddfacbf0a3adca8e52334cc63c9d225145955e9924a668f0a1a49b30c001f6bbb58b11e27324eed3b4292c6d45c441945977114295c2fe8c2a9910fe516c1a55671aa9c055569b555855c200a3d1771c98f44572af385e4c010c5a6a5ca56e34245f192409052d3cb44bebc9cb44ef638e660fa7520735add747dd23aa137fc3055302a4a6116f5f47aeaa01b8382b74775a0d951710721093fa0cc2a2b02b984c57e7c55aaadf4b28873429f55910166e912a4ed7875e861e36536c50c18967928b3b111614f5a271f60a1617794583fd663954671ba9ea7d942ab6287da2d7ef0549cae4798892b4adf55813b315ead7e32e626529762b9545aabc8834124d9b3d225d72c0c82856d55c4d4bcc91a8e66f7b389f07be1b08ba8e4a965b6556e9f47597d16a0704bf2b353cc4ca251b7ce746b170aa88cd31565f81b99aef15d97b2283d59e262306c0887a633d10f10077390c5d265acb499d27c7c3f1bddb7c52c4018ce0ab9a455802735c8229af7304038ad31374c579933de6929b11bc076b996a5aac7a4d2c88c28d6bc8284d1fc720caf4b9946c99f80a8fe268bf505fc6394484b552c555e5e66d923ee209093b1601ca9b48c71bf4942be6a5956854c101a2a0f9e2a7e5ec92aa14d0fe5363249b267a632ed389a54695fbe1c6a6e50684b22a108e3645b2d33b25f34f652bd0f7cb9dce0cecdd2e02f3e1388cc36727a6deca89ca8cd922bad715bc7b6b0a119c476605fc982caa8fb3320ca1227ee8cf8918800fcc312f4808f398fc5879161ef913b14dbccccf4617384c39414b756a8b22ad2c6442de89cce78e2c921706965e494444e166eb72a8a65a990a97144868a1a8bf154c9e5a3eec78f4ab83de9245e12d35a6b8312e906a0065f770025e609ce768ab5e1d492ff5729917740f92d92db42ad54a1d2a5729a4bd5b32141346f3b924e5638e554fd6820c14ce4feafe1acebf5371dd5e880e0722662d99a8ca23a97395881f49f2dd538a45dbd4b100794d3528e0646865f5dee6849f70831fdd7b51b8b43bbd0cd8adf9a809b6956c6cd330cb0ce210e58a895db76a15653a40f6e66964406946b559a45ea14d9b61e77563fd91e3aa83ec608c645869c395d6645a1966572986b1509ed76530fcdf486812ec70baa2deabc9ef1f17c8f670ba854cba80d845eabb27db464384304703dcf85d40eee1e52b98d976f2cc77107231b9254c72311b82d45a61d788e325cb9c922467720e495bb93111c96aa81eec225186dd9afee547dbda2e60bf57946eb0703326d9915f065b5de94c11e380b89184b59692200afbfe94d5625663c88cc467838699d8c47d369e8f5efee0d27ce0bb51380dcc886274a463002d9cc990243e7c2f3b42ce49224d5ca3c9b02d9a2463e62de0949a134d6a37945b186654179d8cbaa34928ca7b6dd208d5e8f863297c8dadbc782c42cfb6444ed708539832c8a5720a802f28842e16c71f81b438548aed1f14bbdd658bcad72d45cea019040418408cd9462699012878c929a8a3a55ba6488af88de8e1c9854291a9ddb2ad77e56a16e50546948a29426ee0fa00611e79125517e6cbb8b0965dc76497a1c3a9dbd161ce34f247e615fdb6c67e49dc2a5bff8b688718816bc28df2b5934675223835c3ac37abd6a50bd2a0a959604329c2e6872ceeb8ac106bbae2160b0a4667a90b614544a71abab65e59488f5205becedab5e66a87602984964441975166f150ff81560c51b6bfe0a0f0cdea75919af0ed3fc600787f301e1af31df7becd60e4b15c85daa3c2f94d668a08bb314f7c39bdd11e6dfab34b24ddceb2ac7e5ba671d7a23f53c25895c45540ff55e224a44e51c98e2370e5e45cc40be6277a872040005d319d6a2c37ce85f8a613768935ce77cd9481d1a5198a6b23403b122b21d1a5b043652bb4a0641d4cdb135b1b011c00bb5863285d35fad700176c4856a8a65a646bf5682caec6a3a1a1a93029b43b632479dded02dc2f8584faa348dd3f554952556d6e681a5fda92bda17eaa98a0b65d7166559958b84544aaba80ce461e1682b716a9415dc5f2275e8f99172e383965e6cb1dab32c52b1c8aad212e989b175606db33eb9528f585c4f2b8d3bbca6a891e9143113bf1218b5bb5d4c4bb22ab3a2327b660e4a7eb6b8eda27d0416cd8480439faf95655de71b006917c66ea6ce1bd8402698c69661ad4c3bac75f21afc053f9a4f0df9a3169bdea8691af59b76916db67ca4099300639fc95f60c78aa892ac907ba70355ac55b761468a7596c0aaca24c145b8bf077dcee84e8651506e0d60ad7059b28ac85044bb3651d8e453a52ad5c98a630b4551a52e689358974c1e329c529201aa7b9340f4f073ca42789c966d95cf0a85fb96fe45cc231fb2383dd2ec11a7e22432821d7f3970030e932c549e4814a51c78676998ee641247041fe5acb1b3b38e14a276acf34c1300633d65533dbf2243650d997218d1904550516cc5ade700cbda3aacbc15a60dc6011b90041b1804cf9b5e0c4be5ed8533029ae5154a3e8eb39856370638a304b956a528b32d88bfac50f5475d077fcd108ba3f5bc44eb31718fc6a62a4dfc056e2656370bb595f1f1568b5dacd7aa9cbcd12588e0eebb46de1765299446b370275609f294546e1533aca6fc6c154254c5a90face51693c5fab3e1dc96eb91928b32a3cddbc5ead9818fb3a4641748e4c1ddfe556a0c60c61e6b8be370883dda2936152d0743b030ca73c60a30cb1c830711c70dd983784da1f5856386d3648184422e8933f657873834298692b5624edb4ddd83ea72bf30269373fbc0d60e8daa95235929fe94d7f660a022b3ecd5768d4b4536ae48ed91457692ecd987692689b44498b65563535a9bfe46b29c9c6abb4620b58862cdc089d8b0ca8321b8ec64624dd963d0de67854405526271b58f7569edad8e195bd50600c7a6818eeb30b50e046b60c2ff443a1de33809c9d0ff73daabad52bc8c13b54a8c811dfdd40148529ab164cca6062bb9182ad5948de2686f91c1d8da9115bf65b2d5c6d86380006083f7be71b3e0d7c638623d9443dacacda2d933598a8e7478116de334d66561c81a910b509c8d8e9f485df6d2ec39b56da5eaf9279b298ee4486db086540c5216e0bf557e10c651fd643ea4ead9b6cfca83db5f58aa2daa8b39b088a3a925917d8e54524abbb8a6f181c48f5b09e3dac6f53cb1d9302d333b7a1246b183a9a19c4e1efa0de739f329fa60b425962e79ff9049375e95a83b9927409d822c1a09f9b2745694b544d9495937628de79599e9d582ddcb0f67c79698812c1e954378db128172efa0b3f181cc24b2c7884b6ca4264b0e1e79e11ce25fc5819622e0c78d6462764f8b62e4c47b1959b59f3f5d62ab816d635f868c245bf9088b60042c0c3f24694226c98244d3fb258e10d52158ee72632c9bbc4b577152b2703f1e5d8d90d45d507a7f766c95b2b0b9674bbee909419f356d62ba519b8c4aaf56809d8c2cdd1aa71690aaa679ce901a122a694363e8a16a9a42e9bb452f534d44516c9556ca1a3da7ca352fbdd5c3d1783b59e1daaf4c0b6624ee373b8e2c699aeee224516b99903b8b690b35625c7aaf4da6afa026d3c38c9d85af0689a64828835183c074cd039ee0e2bd51a5cf05e2aa2c686f20c1f489d92df8ff466adc1f6b554e4924bfbf1f8cbcdbfb76f073361af5a7f7ddfec813fdfbcbd1a887aa339d4c1b900350edcb426a23d52eaa35f7cd07fc7c6bfb03393091c6664e1205bc447591d79938b2091ec18381a1f0f50196204b15122ecdec3fc9960630dc3331df011038127919fdfa75498a0faffbaf52e22c96c5109f30220623d124cbca016ba4e6dc243f421b45428c556e699d83bd44a6786f1cd54b33fc761c0d98fedabc9b3849e6e9d632833452b57d828fb61037ddc5f469cb4341eda2c031bb00eac72bb53c2c49a34b5ff5d78e6b620d6c7bccf6e82cb5d9595a0f08bd5a8669982d31a699db30616e3f4e54fdc465f24295284a4c541417242ddc93cdd96c51035a84157cfbc0610b7e96ea6a4b73467b340fd959501c1ee24c3d507c4520f118ee6bcf8079fca07891cc7ffb4197454c3122e6a1fea430b06547aebcfab95051855c113b25dc6b42010747ac812c0a803bc6cb48d1654dc8e11cd45e2d71eedbcc6c8adab88e25d0ecf5c1b814960e16c828ea2b09e83f4da4267491853013cb3da915e3f1a27ed4d5429735facd277dbb696add73fa1cd382298b9d7e8d8ab1fe095a6b8db9c8d5ebd7e7b8dcd8fdeda3b02af35c45168527881c563533f87973540c769e56f55676cc7874da1e1ed0378cb6479a5054074ca4ead9ba8eb57960b5c7e693e7cb78a7b3c583a07f9e1184f93fbc931213ebd24be412559993d6c9870fe52157d9aa1667ccc6e591633862bdaa330e106a7e6439de80a2f6133572d0f68ea40bd435a38fbcf1c9d4dac6fb386507636efad2aa6c04d16cb3c57e600aa28f9d90bc0d4aa8e1beb486649890c9c06cd6fb0451e29e0258926cf9481ea7f2a74ceca6c676f7dc88631581cae75cfb9cb60c621d8eda76416dd801ae55699fb3a439c8ac88d771ea0c2f55cf8d02c61bfc6a62e8d1e0e9235b76542434536926981400f218e713a4e3b4e363ddc98a659cae89c05226487918b86711da713ed88d8c258eb905f2c486ab0b3fd5e4db04d0f873eee8955f19b6fcc4b01a1c4abdfb4039dd19425e0bcc56faa67ab033ad296923b54137740bd9a114dc9aed4b39aebac234c402b0414b78361c1895d4cb2cb1c00409d57d077e305132321536b28e0859e18870469dac78964534512bfb15f3076a9bd99cac5e01d4c29dd0b241b6b8352cf8587ca9df410c214bc47e9954a4eb11316221f0feafee85b02e13a32a54b048ab5afbab0914f413a250467bbc900bccd328b193b836c400495a5e6755512831a076da585908d1ce70488b134a661ab508c968b15665687b6d8cc833022002c7d447039a8196fd62c78ea29c7ba507f126b31dd0eb635ec8be1ceab9066687bc6ae26056fc671f2aad3a0d644563328ad425fd6393efa25a9b1531f6333f5132ad72e289c0c7fa8118cec7f7fd40f482f6fd2410fe2c1c0da7f7a2330b26f783b0df0fa7286f2eb3ed362ed1386f2cf12bd2267555286e77166f55511b6741954ee7afab9272fe7cd23a69d30ccada658a7544e960b5ef2e592733664cff68252bed3a45cd848d33d6a2876323b5de5952986b4248c83a6b7eaeb46a80b4d22a58ad68cd6befc40a911309f1e178a02c12b9efc0756afbe4b14461355607084e1e62bacfe1a9c00a3b5562c81d2a3b6ca0949aa927903bc8afa31dac1a1a6bb1d05942921a19544629d3a55921e3c411c8ca6c2c295e190a961c9b69f2623dcbc4829ed00c8ecfdb4a97411ad14b2251c6a872a21cd6a867e415b553a8154903eb85794011f0483ecc0bb58af738ae7ef6ac0a9fc24c36523bb222563c9e08478f91a8ab952c904f6fdc8faec8cea62c477f937a63ac1f54ddbca1b9921b8ed4328bd47c129eb44ee693d0301ca3076a51d8895bc4e340743ed14fcbbbcdeb08707a66e6432f4bf228d695671c6b3cd748fae1a355d87350311d576aac85e59e329d6bd51e0dd03140b72d5043478d7087f4ed925459ab80d2e9333aa17c69d5dc4a5aba57675287f57b2a77f19ab5b34aab42ac159b1555a42fa5def80d332b2bac48f3e9e103f2f2895a150a57f2e8950b352153e73faada1ce93e833c3a1af45f69ef66caf7e438fce0e8f70405da8574f6d418d28f56971ce3e32cb73e821dcd39a60d9baaacd2e32c471b42c0df6c25fb5c03c7cc7a08184231e58fbc4f9d19c086715e0cf2ca2431d6b822db9adc75666c9edc22cb57fde3f95e92966c4cdf4607c7e01e80a06b128f229c8db396644b3ece8db5075238c5ff50fba06b1b70813065c6099b8287cffe49536a9d7964795a672c560169817629ba879f008ab075fd2ca251c2365f48e44e2a85bddcd8d8fc92669aa98afd0f24e7929e618770b3565b257ec76374be3214a5ded47b8271134632b38117e6f1be39622a05405ba75961c647238ff84d26093c19621c5aef10302cb2233f55aa384c55626535558ab22ce205c733547ae30c1a4911b7b84c240ae00950638f7d6c15e859e685a608326c71783549c6abc0da8f5f65340b9a853f7a8511058e0d3aed0202ff8c771227fd42ce96c86ecdb03ea94227554f5a27783c93a4c29c78445107c326998c80c171100a0a83331392521fc7c70041c789bb5675d0b9e60054f78c3c1d3a5a27e6bf73670eca1639c60c1c5d94d4285ce7e10948286d2e44420bfbab9b675072dc1abbafbdc9e5a47542c76e0d3569a3214c452628890ec8fc240fee8c2e433123c18b4decb08e8edc9a7ce7f21293f57629db2c5d10d268d7bc98b3b4488b2103666f7831decc04ab545f12623539525db5763ee8dd1a064251b807d21bb6150b75bc4a7a87e116f55540f59bb513f1ad753397d0a659b145246ae4d66acc74136fd11c9a3e8a74b971951cc56a4e9ca6aa609196b825d20190ef4903a89f0aa5c95c587b3bdbf6b082b5cf603e2eeca22a4b1cd056952c40caa4a487655924f4843e306325a0504d1519c60423678be8b9f9ffc1b5f135e78a06c13a8bec83855a7d90452c7dab4136dfa800ca2cbee347f8b31cbc92cef539b0086ce41e7e35bc9b5ff1ca3bf71900a99732b774b4be858e63697c37435726a6b9507404e5262bd06e640264a6b604d11c502d09a54dbc1b83952cdda69c714d94fb3aaa0e4bac568e174c73201dff730f5298228cb66cb43f1a42ac4749140680d659066a19310e32662c8858d873049a2efde3b7cbd9a01f760ab9750ca8681b4ccb762d536ec8dba6f9e6c076b6351a79a4f6de21c4c337abd83989c32f7c0473965195985ccf1ca76f0b92971e7b661104f56e8c2ab4068e41f3b845ed98e6d05a8339e6ea8b43e24c491a86481aad3d2ce3324aaa68856e9f43ab4a34166585aa6580191963f8cd7441b129d3385d27aacc5262ce08b2e946299e16575d6a3da46032d624d4be3419d02f3c6b2b6499a1d0083db5a2d1708fd4119574e7b32833548753da0956b4984f425749b55c918feb996844d3a93613729f711911f295356ec04c1db50ab09f6644433b5a118cd97e30624d031552f5ccc66d787af5f9de043b545a4d1dd460b425e8f23163177bf81d04a7af9f81a692b980becf27fddab05f3f4db28c1bbc89cb0d3732ab8f32327e1b64bdae481f8e545421c4655228191dc22dc50b0f6c713af6eb123a6d5e28141a637664b166d131e6702a3ada75297558d6075250e936867d94defd009dae6826fa2baf6b5e9553455644fa472296b146cbbdd1e7574966cf06b7b38ac3682a5d66db895198802827f6ed01b94fb55ad1c9135ca09c023ac6644a60ef8e0dd2d7cf3277bf97289cae13f7f8188b1ba0dca8fd742323554c8b256a40720dadb979795d5ed7a64d2c00e250309905b7f7d34bd10e26d00294e94c4477100c6775b62c4bb9dcd85a494312a213c2f032964044694ff4c361ef7e3a13b3f914a0a8d9df4e6d0025ef6300a84c88de905fc984fe2caad58a0829c5c978e6dd806bac8a9062c5a8a2b2553b4926cb8b73f3ba56d60682d4328d5759b11d15964818b45b81b4ef16b52a8423f7801a4e2db8ee6e9c1213356d60440f53e32463afa305a105850b337f341887fdc0015b9594b191e7ab347eaa14c82b74ae81c9232c8636658368cde43d52354e5188b565cd7c8a992953668f443b4ac52a2bc2d47967fb12c94aa86847a485473c82306223b81d5fac076644bc0e545b572bb2802ded9987422db32282efd620405930449b85a1acee491b8a76298fb2105cbc7b6414f12c651439a3e7ccb532e4b9ccf821a1425c7c9635c837b7402fcd3674edbdc789be7ae745a13328b40090afcc00b32236522d7f1e710ef79ad8d26e1bc32c3d2ae7340e3b49ade33ae640a57558021e86c0321b691831ca6bc4ffd0d89bbe05f68922bbe711e839fb782d1bd9f57a72f6364be3322ba6d5422f8b78a19c831c4ccb79641891c070e4f050e6a3616af6ba5959c64dfb48fed175ad30c142d8dd8067900ab91eb64976868ff3b05e597cc6c34d74fc2c85c29cc5c7471345565ccd65222aa197458612280c9e8c13ee29376867ead4a8efcd80cc5bf3708793a9969b3045324ba14f799c2e37bfb26c6b4d7e1c43ba4c001b6eedd31d69fbf9988f7498888e74a912af5a101323a9bc4d67e5a2a6cd6e90555a0da87127a79d21ebd6c5b296679af7dd36cbcfd1ae976a0483b6c084899b37a7f4cd46a9c49e9d360c780b9fc619ce3fd37bfa87fe49b956b7fcff0e63a5a3835d80be5a350667874b9f6726147e50b7ce6c66b45a693e3c9b385f9f61706d1bf059d2851c24044eb14d0b00eac2af630a170d0d9cdf9889be5ad2559cae5571669fce2d90668010bc28881c4847f1a936fe6383b631a7229df17232a68d1598c6eb34511dec72c64d66e9d460b3acd60680aa2ce3744dae4a3259a0fd2232060ce67a33be8b8b4c4116387b2069c86b4135f168cfecd6ae1286d523a82f13c756cf45865394c7f9fa2f6ec72a2facb7b0946b39f1368b10b52aad7c99b315c85583b0d5235502f3d6c785a079df4adcd21529d80a93a50fba3eb8830f333a43e768b1013a1cd1b45e1f91f2e2d2094ab147e965b2ac92fad6092e756fbce61f9ca817c837c15d1fde8c7c616bc1bdab0a293b98b522fdc76f9c33760224968a8d119a4316f0b44cd468f1dcc44f9d538b6622e69a0b330174989f633be69e815c969b593631715b8859a4a421aa3faa54cf322794c5644dd43ac01a6331bbbc9f04dde0768c8630cea672eec9fd24dec6a539c2619fd97842960aa2034b8b307813136193d1f3a52e5511eb47f613c6ccf772256b3545928d0f209cda2ebadc16bd59bdeab5a63a36617ef6138c89a3cefc2c52e88a2eb3799e5bcf2245cba1d897c8b5b6950d2010f9cd8606f4302ebf926c7124fa5b1f05241c22a7d2083542177e08166dc3ed9acb576a7bb0a0ce279ddbc9d803bd3b40b2077cc0a8a4fd053c41b207adf50089c4033df07581c763e06989318af0845413096601d50a5476558a5a595a6dcd791ab68e2263616a600432cc0b40f871c83766f695dca9e34ce087c779f3fc380748b693b74ce2e5a3f31e2d12ff28ab20ed3bcf8cfba3c36e0978b6c21cbc604d3e3f49373d59aee439735dab125fe374eda384c0f909b1c9d2b0c321e2131521beb7743a485f7dd5726b646264e87d13eabb56a53156b32941e67103c00dc0ba00ad01e902d00cc501d8d11ad652d9a0999b176a196b65e3106a9fc246260d73a4bf91785ea3be7ebf8e5d3b167334016d59150cc465555016518eb1644330bdb240422f33764fba7e13730d969b0782d2da22273a61529938e75101057871762a8df84c74a264511fde2cd453a57429d2981ce368f4b415c6263681a4c357a540ace01ed6caf455c65b35cb7c32b5e2b076928241edf1f78241649e0b65243e36fc713e702519938de7398ed8661d23bfa1b78d8ad79bd2665f9a57be0d765acb2326c75c335b9b3e9c1c40e201c537c1a39745e47fa34b72350992b1a348633e062dacb262cb6e3c8f844d7864852a4b11e1ebb3d6cf524fcdc92c5de2cd08b05c8ccc71fdd13c0ee9502fed42c7f385f6667b491ff7ac5f15039cabdf627bc4d5f3f07616d649dd0a79618f44e0d81d62417558ade42e41c0a6eb07e2d4a0a41ec7299df58a519fb4af487122b6c64c4d4fda5908deac56d9c63706660a8bbc2074decafdd079c5133975d3e6935d47e8986eab8042ce746584b013a54321a303a3028d7ec471acc9c1ce836442ee0f944d7e2c337e905164a7c7065ff3baa5b687d57641e1dde603fd9a8b45cfeb4a467c1892d6c4caeff4ea670add26eb42eec8c1576e14292285b45f61534e09cfccd5ca15456d3305339749d7dba2be179af7f1bae033e3f68e67a735830404e7a77ad00bd3916e3418391d2e16d97ea854a4eb1312d522899702b902dbf74dd32bae542892c0ead532cdc9e5b2424ca24043cdaaf0d646e83b287bc6ffcfed006f0c0971c01b2f631b4634cb4a990ceaf66a9472d06929d39d39ac534bcbb16ec714bd5cc689d263b211121f8ae00bd36532577091096e7cfd44c6df1894b117c3e0fb998c5414d2514e7ade4ab2a0e9c7385791ed8ffad1266c5045f322b1ecc0948ab7eb399eaa59665911c5a924cf10740ae218db1390d227ca6f945966398557178fa6352857778b80706bc078a9cf93d689f184c7db351f1bc8b4a60d87d4930bc348ec868117370480faaa3f5bd0b2f2ebc0ba90cfa6c7258620170464b48fc357a40392430a9d4ed0983f734761674c041a88806f16bfcc7c7471922f1fadcdfc3f71cccaab224b4b6b242d1d5ea2e31765a0e9ddcd82e9fd3898dcf7c361af9111f48341309c9db44ee671ea58bad10edc999aa79ff6c9722feb2bc52ad6a66e8420abc653bcaf737e4b3b5e073a3ffc137d0fa40d9b01903f824545a213a60b18c73c36b19719418bfe5790bd3894ca123a63d1af7dbb2667ec8cd4e4f966c414db1ba459b5ded455895eb82c3b55cfee2b9b6d68973db33dd00e1c6f6cbdf7e69d0efa41c82fc131b6edbba11884fe7d7b226e6ad7c2409645bcffbcdad559e72bb2042995723f3b077c782f0376d6e98f04aeeb701a768741fb1e16dda0a83967d80f87c1144d47a83675009d68c3751a985523cc70d40e8c4b00f1039f103ff864a061bbe8ca6ddc5b361e85c3d994ec32be239ee9dd9a6579107b1c758584da5bfb7447510d954ca64bba38532689f1ecca24716de35e1527e41d491d71c6691cd0a82e943822cc5121b4d9aee2424d40a7a63b36f07458c4e889cf1d8b8cf43ecb5ce49dda29b2b8848d2ea87ba73f041a833055cf63783dfe6c4519fa8cd671c726a8d6715a1fde004d8d9fd166eda305debdb8a71136852424c12bb0f0724f2041c8f0781a3fbbe6e60f20cab3813da343c68122de37055a734e5cf37ae17f8a2db2064dd3a2ed82b0de1d8df148e57c219256a5c1004019e3e4674b9edf3899597bfee1cda08851cd6e362a9d2869054abb4e7991e5a16e5c9f692fd76c66979935b6974a9767fcffdc907436a770f6056ac7e62a263c0f34d76a28cd21457bda0d23eb437822a7f3742666a10fdba7371cdd0c9d77980be93cf0a028620829ff20188c9c82b3bb71e0bcaee9d82cb931623da0438b1df75409e7d9bb2cec7dd8786c6e98d1352e752be44d6f1cfe4553a99bb348e4f291aff0b1578eba05a891ba516aa27ea70d36752f12a22cbfa9a0b2498e0a36b28e0a16555abfac2a27e4fdba5268617ce2ff5141471c4d9609cfa0f31ef950edcd81142c69aa97b6f5ad39b85f54e9d128d8079dd66d94714954ae58efeabba9b471291e450ebfca104011eb9063b58dd95b741402cf39a374e9b601ac8b0fa63cd36d5b515c90b409dc682bd138f9a0593f35f7b038db1f88a7fb8e71a27510aca946567e13ac831110c3a39628b77fd49ef35b53be1b745a663fe39dec1a7247f99dacd8a2edd4a98508b12e946a547fa44b8fe80bae2dff2015c0d0f9712944df36d5674b3ad93a41ca874d53956f7c8dd3b7f3593d6fdb5e0901192cd7a0e5d15245744e1ff756bcde4aa3ba5adf26de3c6b8c67185f44ee8ae9262b8002d9531f25ba9d66d92f55d09977d2f7a00f6882eff4b31a11f72b39560ce8d386cc0b91d2339e344ebe1ddbeb84b672dfa6c14678fcfa4018648269e99e9782d5a64556d26d162b1b7d9ac828b2072cf99630f3e8c5681aa7d82c99408f9117a7ac3c266a873c2c47e17a191700eba26fda5b17182007ff8024bf20fe1aeef02ccb524fcb225bcbf2c5351bb0c805625f660e664cd433851a2e93f8a9527e5c2c13e7d544e0e11bd7e78038cc3a699d749d53f92ce6c1d064a5752c532b9fe2348f7f840b6380197ec6c9c25af427fe7fc6ffcff9ff05adbe291ad63f6d454623e7a7aaac4c6b2859dc284c9121e6ea6dc2d830b55775ab6746c381b8bdff29fa73101d07e1d03eaf55c9ec9668bc3187a08de860886c6db5d8c4ab9254d6bcd21b7a8ae21546301ab3d0566a7dcbffef382ece9e334bc97a43e74bb639a2a386c930f1cd12a3e1170a03e8cdf201dca83fcd73cfb39c321cf8d5dec61c849a33f3704e2aa13169c4e99aec60789b038a896bc74eb6901a1dd0f0ff0ee97e9231c1419d109f76f0b43bd4d6490c56c5a1ffc4830be711e75c44360f1f2bad0ac7b8b9957b02d7fe8ec3d570db1db2cac69a58a9d4958cb18411ae485fc22089daa26891c73502528e6b62aceba3bed1a85f5f02e75cb1343e1ecec810bf1b37fe5ef27fde51672bcb48841bbc7a9fd58e799ca8614529ca64a33a90198f51d5a6001a33f6c69964838271cf26a11876fba85cd12d4e75bd3a4095de294ebb7e07c65bbfcd82dbd97c12dc9fb7c93081c6077c99743d417936ec2b762a0c44f7be13f667a86b82a22726eed77078fcf57e108e07627c0fcfc174e65c1e328873ba9bdd80324647ac0309e0035e624f97e71cf5dd2ee43320bbd180d16464fdf9f6c5de13def4ec00a2be5a6b37ff48f5491b072828f4a6a9e1b9ef47cafcdcd2dd5abd08d931621550e33aa037eb31d8c5ea39a71bb05093a6682fa34deb62599b68148660221570696c4cd1da284a1e1c9fba5958241d005f0e249d4efc7bd11f5f02028c86b89cf3e9bd9b6baf66f3fac1b08df180fdd184ad0ff75e38235a5fe514486b23ef1c6b1d9a098dae4af166475feb90a62df92bb47b5cdbb812ea25c133eafca2d96f6033acf98a1c81b38c24b8a63dd194c16fb38c8a1ed9131d3f22fdea1bd91838a8b294b5195c467861bace25c934581c3479eb376f8f0663d38671d86d6dab918dfe9349e291c0accd19e465291a99281edb236cbe1b951e819a68ef638182759452a4f064b3b972c70b87ed70d8bd0f6ec713f37ddcfcad03a3a73a7d63ccbdd13a0d8169469bd8f035873eda089201c7b944cd8f508f3b45f3a63979628ad82eb1b2e3e28c044602c06e23cd206a2bcec892280cec677cb3df287ec0849445ca7d93c6c3f8ca03c831768939d18526327bbb823909f516e3226b89138b5269beb959d617778f6545f7b792e7c1ce322f94bd1b8a2fa376d86e6d2d435b661d138baf6ef7f6665ee738cc0d664c94e6e1b297cb77a75c5b75621dbe3165a37fa14dc646a7d1e1d5a11bd4c88d63799b49e566993328dafbc6c14b9d84ee2dae39ff0a40a174c5652c845eb26c3bc2e581a790fd93aeba0774c79cec760eacad5569cfead591b50845c713e84cc6c4dbce631717ecf5ec44fe9ddf9422881ac9bfe91b4d9a9ecf6759fb2db384ed838e4666c38f39af11a54c537882d53f699d000df78000f141337343834acd25c9ce3d189c39699efae5dc697d3b1ac8dc1d92656064dd93d6c9657d7fae6b830909b5ab42bdfa7475d23ae981d4403f4f66eea3b357380d50a8e2dbf44627ad130c98a233e5362ae027c82227ad93b90d5502f10db63128b4209082620812e92f9484cded2f7c0eae1d6bbc5c4815471ff01a727be71f05ab23ceb985cc7d81a19e665bbee9461562599a5fd1325e882c458363878f42d0a56eab98ac6d001c172e53bc7d8c7ff7695af77c7f3f0dfc4930bb0f87b3603214fde97d7b743f1ccdeee7d3e07e34b9bf1bcdef6fc27effde0bee3be104efa7bfffb3e03cd6b2ecdd94ee3bc7c7154ada1b49ef974757df38073bf19dec7c897cc173c86c98bdd7a52c2b4da70df9071e30f4c595c1c22d1deedd297ba94aa515ed457b3f48a515db10f16a9ca8a24b6d2b6db1f4ad9ff9446b555e1e9c80bcc6fb4d5c6e26ca48ed2098c9228dd3b5d13c351d24d5a6313c20116f5ff586a2187af152e394b3c7d3656a7fa708cf877318af3d3e44260efc44e6517a4c55fd9fcbea8dac4f12b97dbbcf127f5a41e843ba6414f2b39417b7cee0205173c79e6f432fcd4d83b506daa7251d6705596662ed361eeb57cd63d6510736cfe922d675277851566d2e8eb5b35562cd4388b533086703c5bab16562ed6c9ae69d740c487bb75324d1488492141486e4814eb7a32a8bda1bac82747cb8e684e623de420dc993448d17e3cd6aa9cdb20a3cc060d607bd74f9466a154df0802ab13573e2a738cac393aec8114e5a277b480e90bc402220f124fe500e5fd6677c3e6dc80820e940d295782b03902a48ae20e9495c5cbc10182d684065211943722dc966a7f252f3d9557d1c4e8ce22edf4c33d7eee5d15a8210f4c2b708cea1ad9fd20457f3ed163748a02199423243d20cc91d24bf20f9808358607806c6d501302159e1d959483690c4903ce0e5df78bd38245b48524872489e1624b2d34f782daab5a1ddf46603b101a78c241aa7b58fbd80fa7ac19c9b4bece19d7eba13af3a323f8b51dfb593e5ee6fd940f1c3c2ec6064c32f0bc79b6073eff9563dfb13092453d605c482658a22e35f4df020c787a40d49b03057d13aa7854970ab775d170a7520b9c4e9e13108320c1b97479dc3e730008770ccc04d8aacd2c961aaca304d5571391bc0725fc1e71e247d4806900ce9375801bb20b9c60f5391e77cd7e53cd572855705250ead4e0d92515071ec743259980053b63e4e2163b67005783275da576b0372334dd05f7da70cd59a434b3f21b969b4d9280a080c5fef20f905c9072c0c9af562897624f9c8676031ac63497701a82265c90ad91b9d13b6177e82286e163e529b4354b031680525364b34c72f120e8dc39f5085e40192474812ba229a451bd7756333cd45fdda5e3bcfc770a66596e71c2f375685c6cae8708246d166803fa2a6f38c7ed6443bf894e1d94e489e9614b5db573b9530d5253b9851b3c83907e340f02e95e65be131000649e6f4a04bb5ed7084b85eba62349f552921b3826407c933247b480e90bc402220f120f12169431240d281a40bc925242124bda5b9d0464578d0acbf34b65755a0e56500194348c64bbacc1c45fcfba24ae907d6e28c9da679fdc88b08980f9526687a816406c9bcd190f93506574832df8678f185d3c74fc43248ee20f905c907c432ba8962b130710614466e40eb34b1c0efb8c523b7afb956055e198437b1dae28489e8f2c0f33a788d3ee25f63b3597dcd08908bac00356e2bd76a54952472397953be5ddec93246b245b6ef24e81de52773346191ed4768af494cce324baaaded92dee89401d65f51e5677e24858b7e2d2951fbe9a6e0c38a89da0fd55a3adf4645eded1105fefe043c52601c3fd101267e99e63275de98cac0ab8fa36abcd435e9dda9cc195c7f95a5a50d0e04fee49b8b82e254593362964b36f3673cecacc837c4c04bb930614571943d43d68b713e83c24c2c3019d92656499645f52bb034f7adc81e555bea8d391f53e7587338650d80fce2990c9b75dc8e59f047b42252241a0adbdbc85edb667fab836e804d2bfe750e498bb24023d176c1d75c99c014521ad7cadcca626eed06306015ba601a1d5e6806c10e7104b82720d945e682524b7cf7517dbbc18df9d1a383931944f647a5db901d40d289f8f7a33ad91275a32eb2fcfb4db905d1f612592c245790f4ccd5d77156e9baeb3ed222747de20e84640cc9352413e488e84060de9d37f4d939f6d820c13f21eb06925b48ee20f905c9071c2eee4d543e14baaa4a55ac48fa8b75fbf51d38e839254a437ad18ab899f3336ce6a0321420b317b11b5b714367858888697b02c044cb603431617fac6745a54b8eebc6907cc885e441e1da3b472d594ba09fb022f72220004d7085b7ab12c6e0c13262f4fccb8b7586d9904e561d388c811ed4ef81237670263b6bdfc4fdb789e9ee73b68ea23a4b6e583a1d68fe9574a6416df937d6b394ae57975a3f6705df0d41bf2887e6512eff4cbf75b687e70324b8eb059af2510b44ac446b0e241d72200302e20a437205490f923e1a6414ddb35f9f0171cdfe43f83ac23e50cff7493ac57ab8e3a6fcab1f63658eb6d2293523eb5c93168f3f8f8eb76101a22af439da50c55bfb74676f5a62d322084956375b15d9b6964bcaac7e3661d8b7cef31d8a6aec6fd2e48b2a01a62948dd6327334eb022fcc723d0cf84b02c20189d5e8f8b782bd13872abeacfe65811bf9a834577ca3952493781d12d2d96a47c4063385e2e87ce47545d575662474112268d31f8906c2079a84b38186b33f82746f17eacfada80a9f96cbf598bee0ac81597c467fbe5912c1553331ab4e45951c0dca79ac85cabc8fc969e5655e42ecb8a3c2ef9229345c4c1ac29b6bb72ce12424d780f501a9c826eb0c09dc3c797f04cd684f9201fd66ae3aeb8c1d8c2814ad1289ae379407b7a7890bd8c8b38455a4d77723d412fdf4f5a273f4e5a2767e7905c40f215926f90c0c733f87afe0912c8bb80721750eee233245f20811a17f8156a5c408dcf50e3337cfd8ced51fbd4c1d9674cbf604a5fb13beaef8c86f309d3334cb1ee39d6fd8c75b1e1f373fcf1304481159f36262338c567aeac083eb327b5f9906f9d5141a9ddcafc92d06de398f9adc9be6b64df99ec5fe68109ee33b433c573d1483bc64945f19e81dd0ccd7c325836f308c59a795e4db59b1f0ed0e30b2402120f129f8ccc1414c96ed9012b5df3742bf5a38a8e0e18ff49e9c15b65db889cf823619074ffa237fc25c4e3fa9778fb31245790f456ae444efccfd10bfa8dcf7c8e6e2c290c76d0f84897450f1b796b650cd946beef73acd3a851cefe8ca8a3068ca1c435249346d97ef6ec949a36db8912b789197c9c374a501ceb5dac50fafb896622486e21b983e417241f90bee09d5118570849843a34242bd48bf1727abc051c9207481ed17b87079ff0e279bc3003c30cd636f2779fc785f5fe011d58db6bb7ec22a9e342782594a60356a81893b65de25de36b7be7b9e408336da3a0406e66d9c7843c904900aae3e501cfaefbc1ca6fb93cf071943dbc1e2079c149a05d106f5584c447d7332401241d48aed6648e7750b2139391ab0b9f2ef1300c243d14342119ace90480e804f77f75de7e682e544a65ae3719df886625a3b75a78f357714ce608da1bafc99350d84bc8af2167b2660b90f511e07da5e605d7ccbe4da1f08c2f06c3a1206a00310206644c3b3f21f706925b48ee20f905c907b4e4a3364ad72100c66dc8a468f81b5e8e81779de2a9d08d63ce31f00109592646998c372ec60096a2f6034982b5311816bdd728f041f2847528880dcfd9018a41b2db20196698b02f2aaa3d254aae5571f46a50d2ad612d4fac33008e417280e40512b131a27c4657aae1d43cfcd91e48da9004907420e94272094908c915243d48fa900c20196ef887c31ac77b260e64f0eaf8952a8afa47d42bed5cf30db8028d8c21b98664b2419113967d536f30b31073c8fb09c90d24b790dc41f20b920f1823806780d0a71e233c006a785c28fe1354b678fe76ee3ac62bafebc1d4b34d311792277426c71c38786002f380fdbe611092bb2c8e669b5877ea8f8f311a04e8ce678ef3d4ee8f6e4c9d9f00e77b62e05f4dfb388319f7164713a3d9917cd3033a43a1eae314a842a5e6007c196330131a19007f203940f2028980c48bd93c3a4509d287d70e240124ddf835dffc139a7209454348ae6223980286c5788d2aa02324034886908c201943721d5b4238c9b2d23d493489515601e489eb9f33c3d36d785d2f9d704d51ac04f481e40e925f907c884f9abfbae5f346920fee0713fc3a815cbc7171a9703196f01c41f288f73042b28524852483e40992026ff283a484a4826407c9f3437d566000d0d843c601921773b323aeb615c7c5832199fcd32e9c0f25c7314a857cc582dad3ef5f72392331987330af18a8f9e0307e93c5ba84077dfb90b4210920e940d285e4924696c67a8397bf3e3aafaf3a83e1da5ff6e6bcd0018675305f21cc2b7d18c469bba236105290d756893ce05b0f8a0d20193ed0b972eb1a1e21c8d1a3014fb7a08f5cc3d3d482f2782405fd6c39b1b6e7c5b14386a293f8b2b565a5157a2d5d956dc27afe0c1739aaede1fac4fec89471f7b82781c941cf95292aa528dde31d13fb43ff51e49423157107239d43973f21b979403216458a7e221226ffe0d2a4a35b747e3d3814af0e4e9378c80cef1bc1632e90a0c16205c9d592ee13a5ad6f8ebc615c395f0ee7868f6df00409d23ea28e5b1b6deddcc02e12fe6520bc1b1af701235384029077b8cc74e9fc84f1a2c2bba848a937e15d63b97c946bfb9b35ba5dfbc5345943b411a7b2d4c7df6dc1779e4323affeadbd3bdcd93b551471a42eb3ecd1b06193671817ac1e4b83f5cfb2199741cd808ea35b486e82a9ba73f40e66a8c75f74272beadf7b30edbf91c351f7aae46ff5a06aedc274c277851a1f3ef4d91e0d8c4521a9f4667a4897f502daa018618eaf581c5bd02f91d1847543496a76e26847b07ed36a51164a856999b9f47ea0b4966b0c914955a31a1ef5c750b489b1ee1580428c22b0dee7fcff0c97774b4dd111e67260df7456d8df79cd8fd42ddb1b0535f08f14d919656919a7950af66a5999405f4787eba076d2a4a9b5de677eed92df3174eecd969e0be9de0cc441ecee45e05911afedcf92c17f278ab7218ab1bb7a6a827f649ed32f0273009ab94a8aaf88c6afb6709cd618304a837d5c9a5f161aa5c68266c38a607aeeb9d642edcccee133d46e49fb429af4b059796d0f026abe49d274ccc1e8b4f2d68ac7af548e26c1bf6896451c0eb595878509c9c067e1142b9dced07a589f42b4716772e586dd6504000a0bb4c0e0276a147faf2975add678d1d90595a3b1d283290fcfec2304a070bc751334d8c667cbb0d09aaef4302b2fe54ef1b8478573e84f4651d0381b785fa8d5858548b375d4bc0d81ab878f4ebd5a469e0f07a3f97086516dc16dc80fc3593009875df368bf521e62295f590d7a37fdf8a03f9d36d055e67912abc8b7773cd36f6bf22f0f984bdfebdf2270af81e77bc0ebeba1a3c86c91375b39ffb30f174c32dd5ba729b0295d3732f107b19c5d196569e33ddfd85f6fb2237935aae6943f3867beeafbb8b732efd0796cfe8147ba53d9dcc4056bd8ac00bbef282b7d5dcadcb7d7c9f877fccccfcd8cdd631f3bfebd84d7cdf18fff51e1a1cdc09fe876bbd2e687bbd48eaf93253cb2a3a4d0322577d4f611e2d98b27edfe98981beeedeffd03f08a12d4af66d037c74ada2bba8140dbe3f3cc9b8fa08213353195ff97808e93f8ef89ee886e205a811023bf752dc41c1eaf5bbdd677cfbfbcf0fe9fe69f10b1275aa110a10fe5d65e6b2ac4149fbb7eab2bc22f5e6b242e4587be765b236c77ed093ff15abe1081df9a0b71d35ac2671f3e4fa18979df36217a6d780e42287877d90a85bf0bb04cdb290363c024ecb57a42f4b0fe08e7110c5a4a08d586fc70c8395d5326e8b506c2cfdb436e2c14d32f1e3634829c9bd68db8be6d8dc458606337439cc288403315e2d18301f8677e3d0233fd4088d079c499ce718ed7979c035fdbad50045f9cfac3564fb4673d2cd2c54a1de862f413bb5e62ce0ce734c7b9d2d0fb383fec30b8c2f9610b411f9aff1160dd109e7bd7ad8110031fca0ffaad3bd1ddf8b86c03283fc5e944f544b4d7da7a42dc22361c3c5cc920e08584b5fb6526ea6f303b4494990bee1d4618529bbef02f43ecb67523824e6b24da210d7586e914ab0c6130d7036c0aea158428b04e62d4c782d4f60c9b52980f30eb6dda380f5cb8d118a132811656389be93b66e33fb4711d309fb015b08c5ad87ad7907d8760b9f0120f273e3f9aa718614e0f3abe004cf2c3d68d104b686198785062ed0982c24088eb3535f380ff0209e3ba0e70850cf240cb8830c1656b24823d7e1d8da0a529211202a88bd902fafde6b5aea1df50f8d757d0f18020d6c10d86781ffec455028035a600000e9236e1775788f0d123580c6c2b0097e09b87d00140756f11ec5de8ae5fa3f1a501830853afde0cd8461834364328fc0b7f8b85686dbb21b68e6b388a780ff4849f638d1116edde227011cb9730ebc44bf8b3cf2b67313980420aa6961a128583bd668487459d8ae0c5a15f3dc80f7eb606a22db00842891a859e839f75d939a623dca625528f1ef4e8b7116abc970684f7425eb6ba228a5a5f3b22dc792f8d2143476b3fc296a77614fe4f6e8247e14758b87523fc4bfc0230eb5ec17e12c216ba44fad8fbe1bdb1dda15246836e4931bdada7327df1086c23a0ed90fec426b77e2bf6f02510414e04e313aed8f20c6ba488dacbb76bf82f842ef0788bbd9f63ddebb48df9591be9d9176c8957f11c0139e7124b005d45037a8291062f34085cda258efd9a16e3145b29fc3df5f94c6d779c124089723f68dd09710743fa45b4191e7ffac08b9608e5d4e72d158aadb7c2de08689f3cfc37f0a9239cd098d8c554881b20a4c19987eb4105376dece08045b1cb02516d7e0d2d2c709c11827f09eba471ea1b8ff6db049812d3e8a94ba3473838090be5231371d077da7955063668cf2d0393ea0a80134c800811d2a9b003db83311933ba30ac111229ff1795bc0bf00b6c88510e931d8a1d51d243d0d21ecc8270e23ac33eaf71c238f453ff824a7e0e5a070f087149e8f08415ba89d7ba0392209d7e8002850f1e51bfc1a700a9d518f668495342e22cc74409907b201a92101042effed5849f6f8047d29e826110fb81ece5a95763d5dd0beef607afb119027cee09f1ecd5082e68e444bdae713f7ea1717fc26d78fd8dd0b85579c25f7d6f332fba113d1e3d5684976be1c3428999209e43b218d2e33d74ebeffd1cbbef7dc63d8df3f37f7d213eb10d5acf0850c8fce1a504a62cc0912229f7775e4eb94f4884ef70940972aac24b514cea69fe14c0ec4b2a5e05b08f626ca3f47694f91cb4325c6a9fe0e2b7a4f8ee6d60b25f3c81e0ee1544ecbfd320b6306bffccbba0063e07ad734ff8fd2ff6f593071b2c75702643d8de312e5f03686fdd96e30e32f5276cf98bf7839afa18b4be42cba7f6f5b327c467affc8b96473f9a2d6f3b3c676c988b7585501b60a5bd33ef31708b671d1264a1f885072b125ff813e8e9138a8980aa5da6d7e2e61677c9b301dd0d09a2ad91f0afda5ca0015b2810246dfa464cf1573d952f01ee2ca619cf5daefb8beaca96044af5d2c5af9fba40fa9686770d603d90bbc86f58a0abbb30dadc2ba9fcf72e2c5d30fcd1358d3f7a4264a671a07adf2efc9d7f0d8248ec7de940930fde57f81f5c5d788dc542e11de46a203000d11f6d83ce0311cc3494bef081a37ff50bef33569ea66da2bb2830541e1111dc385fb1c00d151864f8efe0817c4752db170f453aed0b6ae121804f0952e21fb07ea110cff4f1b3972010f790195fb4b7fe1696f7e1a27dea31b384bdf2e09bbdda15d744f9c20c3bf90cad77c5faa2fde23d05c40fb79e383d6f0b1a1ec8441fcfdbe71e7cfc76de86d50c85f8ce1dfff03ee2326cbd279cd5a0434803a350b7b52473030cec16e6bfb832d805cbf602a285e1b507940d069827179f2e5b37e2164b7ff6da4ee90b2a7d7e898243c77c09c54dee7dbe6c5d8b21563a78974e2566ad443d3f63d5ee555d75907bdfa1ea4faeda7f5df5b83f94317be26ee77dc4972de02a52cc471fd4ab4f887acfde19e702d138f5cebbb46ed0f01702c2479246fc9acd653e31e1b380d106e50f04e4f505fe935540edf8c89a91545f63d303c04d7fe6f333703384fd3ea8c5840e88267744863f07c4336f44d0aef9ffd62b2e614bfc42b9bff708300a365e486561f79e7651aefcde758ba79e2d0f1d5f0080c26fc42f4cc9c0e1e0466e0d843f838c1891eb9b8f401efd84466e5bbe08486347e62a11d8c800a115204e77c8fa6096bf4aacb9dc92ec840d3c221ddb63cbe1122b7fc1a18084d260fe8fb801e40589f29f51f1eb413dff2c20b5c84a1708fde9058e65fa09673b2244474c1d959728a95754a0b84459f6e9b25962c46b93a02212be90cef115b48e764043c45241ea9d91b2155fb5d61ed06b94ddaecf48797e2215b5a0b7c72b5cdd04b13bd8528dd84be93dbb6a3d79a2fb8d5432dcbb5354ac06a8929d914e965d1269ae95325493a430d301ad2c267d09073a1ae11a634bdd0b9c6eeffb2592e4a0d6cc7008bd5a310bcfbaadb908592ed6d85e469be2ab877251d93e521ca0375ff468c5d19ab14250e0861d90f805226a480b7e403c2b90c70402f17bd60a6a08bad590f75fcf91c400270c917ef592ab3fb1621c70bcd7288a3d83caef972c4079242c91864ca8fa0038e4a0268ea2f2888e4c113a5b10f0a63fda68bb71ea8aca0bed3e4e7cd2c471f30eef787105c93dbeb3af7dfe34a34f731438320f8481e0c1db782e9dd9029402a222649079f27e84ad3b11149ee6f7cd25920ec2e1f92e24ed108672d592b0c94dc153fa7483f0fa4a2f5f42b609dc08ffc53f07940a59afed522da40aa88100cfac7589de6908f8b3f629ef636832e7c2ff85e2d92fce239e4959541508e1c57163c84e20cfd6eb8aae4b7ca5630deb262856100708b75da40fa8a70c11a3c6175738bfef576805c15d333e2379e73be9d2c46470733d7479e94220f728b62d3f77dd3a3f88223d23cbe8f60ce71441e9543df589367cc78174b8ea3a6053dc9bdd3df8642b3b6fd4d91267a9bcb72bfdf062e8e9d1bbadad54643d0c7646b40cc4dcd1c5cfc9b6b8f17f109a200960630061f41d0c4090143b4046b2c0fd1063fd25d1c03bda41d45798776b5e010a7720fc05c9a35f51eb1a7ff3ea3771f7e3caec4e64b1a864ddec11f556e768f51bde90c85222f9bbae7c140e1f3d84dd1281bb84750d5e82ebd6b50814a20b163e2744ba06c05de7805d5d110c91ae1c887ca3f07c837b70027df76e2ddd12b10f5bf8c167d30a0c657709fb64a091ae0d1f3d64458f64aaf3136fcb5688ae183960fee495864093d6782dfcd1236ed039697809be085c528407d9e646db4bd3b51804a6e941e917507e75fb10b8b69df555ab2b622f622b35924d5ac573ef2791491276b71e9a0993cece23f16976bc8558680be36e6b2a02927fc4d623c3f5e02bbe3e7adfe8f53bdb1c7fd0eb477e452b497bd3415df51fee3c987775698c5cfea99f84ff681b1eb573d1ce2fffde9e3c6ae09bff70f93737e8510b67fe97901c0b03a1835f1a67af76bc5c1d32f9d3be7af25070dab0f5f09c97eb91b4ab149ae992dd32fc8a12e49c8c485d14a588f4f95709f0c8cf6d42cbad4ffccca74d678983b85e0042fa3359bf88d85b00f99ec0dc1e3c1ad37504d4fa6a85680b9cf823e39d36367de0af9e5f0ba05f705d469fd06e1d95fdda3e3b25ebde739fe60efae929c99b095992b31eeda21bc77887df43463c6afad0a349fde8d53a70f0c9af77d0994f32551f90faa15390f50d4747c356431253ff6a74d3f78c0e6de79ad420357e7b5823117c0baa6e0da1cc1943f99763783f84ae5147ecfc661c2fc1a7a01e471cfcefc78122d3f2f2b7e31893948d4b825b62f44096b20a2d657d44c80733286495dec10c67febbe184683b01ee704abeab2d3ae7d06b3142a55fc4a4a3b4ddbef740aebaacd73df688841eb0e0937fd1479c697f268f60871bb9067119017043cc6f738583686fb1fef527acfedd83690558b02d026e916449edb963f8e45337f0afbb2291a89723dbe9a3c5414c3fa32769d6b7fcc31f9e933d2347be37b9003c2803d6e8c96ed8d564387840c9096936907b02f3ae6bc02cce7dce1394d5356aece8333948f63d57c4bc11dd023970985dd552d8c2129a80d82cf97e06247e30554fbc5764fd789cfe05c8b7c7fce4e75bfc4423dee45e7ee510fcfe5b049f4a26dec39543d9fb6f527653b4848f01f9dc602ea110d7240a4c70e838bde0761f1a17f2b63d239bd215a1ecda23f9eb5b8f149e8f3e28d55f11a2b2b56e0bf1d816f4f2e889ab87b018baca2e6e0af1046a8935d32d48f71891a40463df91dc44027fe69520e38fce80f0647e88d6adcc13aa15887d5b7ced52213433b1dc4714920c91f31f0dc18f0d8788ccfe0f12fc4a52526e5a646134be2a3140d7c2cd0c94899d7f8e709def6a9fc080366997448d0339a37c56a0db6ee729c2678afcf523ea993dd2a83a817d11bdc70eee0adc907785878ab9ff8c33fae45d91c08a4dac10580f4824a7dd9614bdd3f6230ee3c638e061f81307ff5e7c060fec89198add44bac8aaf0e89583e66e08a8868432b3f5108904eda819da7b3ff9a4f86e8696da063bda5f87c1db4d8e5e0827e321d1536a6d46ebc746fdae08bff9182041cebe7d07215d75d04fc66646cc63bff5ec6b40fc9b1a98d625fcbcad1144bd0d46408cd63df33610e2fa23190b4e51ccbb6669178787647e894108df50b01153dc1d53185e374199e6668352cc989d1ff8efa3d75ab27fb7d752223c6bbb5fbf7aa03cf3c69262b46b7c8d7d50fcf96bec89ee45e3f333ba2cf9f335f09376cb178f5e170d574f5468ebb57a22b84055f346a1bc89f91478b046170937310205d1f9881a8815efd00860bfc5cdbe2ff7a06484d4f3124bdc816845b275a891b20912d3c91be89d0ec8df40ee7d409f5e619c6e289717b895acce2785905bc8927ba3c377d1384f4ed511fb93c4cdb74bc0017f85cd5bbbfe8d7177b173153e2e5ad619e3971e1bde6a27c3abf2b74c27c296123d74055d0a3702c427b89392c2913e20affa1bde7c88e337238c07a16817c4c5f0cb9084100e53a8fdff31aabfdd8711c935beb5613ee2870155381d921313ed39239226dba4eba2fc8a1f4a8ce6b97b1ea06fed1775bceb028fbb424b60d5355903114c50a87c01188797ad91e8882d6e778991228b2991370c2d00100f56d847c72c40c3a902c0ec266d6ce553f8a7ad74c528a530a83b527a23e291777f5163cd0eb0a9444ae6ffb864ba0630220bb93a258be10f8fdc6ba89802f482c2ff4130f938302eb72e06b500abf52f28fa0936f41551dff590e78596d78f68f73af5be511bf110c3b54edba7b6dea3b7c0b111a17cf20ae23624117537be33d4bb6304ea9efa370d28106e571eec03da98bb3152d2f5a846aaf9b72109b83de12781267463ffeb967d9d7bb25b1c50b89b9738b63b3d445714bac7119b3b6491577bfa7e18c29eeaa260d5112f6ea678f2301e2140016be77feb37f04c213f2233f0d908b7d1a741eb5a743714f443eac2ab02e856431cc4f6fc4bda09539cf90fd6cd5328372a80355c91b1b71e531b0582c22729114d2653f4d48f69cb923f6cedb11907c067a02cc73544efc635dcfd531f0791f9bb5e4d56c2a27dce266658d69d31c8d4a007696cfcdb9d1d745a3dd14ebc03161d906832df8c10d5bf06ad3be15f91901a7ee959b7f3af7334418ef6632837266498937c407117b9d76ef54448eb197ebb629fe4396efa3dcd38f303f3159679d3ce70a8069d9e60487eea9d7a0d24ec89f08c0ce121f9e19629480f4037618b7d1fe262c2d49634b567af265acb02d77f0322ed8df0afbe228b54148cb321ef89b7f68fe6db239ffee8bc4791613ebb701067fd478ffa112e049fb19f5f17bd3f81e0c6fb8e5ddf754cd72170a2ef1e9976eba596c2dfb53f5f1a1267c11800e5fe41a0d95dc28217c1ead315f978539f4cdfd210aeaef07f211c9e02326220deaadc679487c90c8e98855f782e4ab22934146d42e50d2e7af871e8f092fe25d080cb4f636c9d7431e213223c0c5d9262a7f2abe686414e2182b428148cb2aa39dd08ad303e0596218f8c9172dca2e706e39c84c4b8a42eb374aad027d6456de42367c39269b7fd8ab240ad33ef86542d68e8c2368eaa4ba311f1442569d34f11a4e2c97bf2d9ca1f5a8d98ab3d8d80669bbe0b37533c927b638784843b3f630322290a7b2f3faa01450709f58ef161867c6f7c279ee1983d02111128ba05e218bd9c22dd0d089f1d5af2c7f018451ebcbf4003cea3f5ef7e3c0a4691ad3bd12bc955f9d423e18b0cc1386c85919df878f07e5c9b80a44f143fb3643b81ffcd7fc410be4fe8ed1195970e61cb241d0a0823e9017b247d2b3c05116540f68c302101094801e986a4ba90cdc7ad20460f031ba3778d9ebaa1200b49b8edc27060bc835f69b75eb737da22ff219a4438283944cfda1d5ad235b9e2ef42a714c6aff9e1a74b126e03a1368e3b39f64e11c50baf00a5d6a7657aea939c8e1d98708cbcfd86b4f8b18eb8fb8901446bc23f901cb50795191dd3362e1e49f77ee13db55b3762fddd83099d7ef32eaf50b8c48fb76408431be74f458de298bbb95707413e7aa81e5d0f5a53a0f1430c2b195d9ba050dee0bf885b514c74765dc325b82036fd08825d708971a0a8bd5d976352a990795040e4cfd6543cf968b9c93cf450fec2e8e4cc8e612efc2f5e3a267efab52d82593672473982d9fb57183e2112eff1d274752dfc091383b189edea82c2ca540065f7eb2e0a25dfbcbd891fa180c84dbbf5e40149dce17e113149a9644ebd0e50b27ba028e86be02342b602d17df1f2f1518f8148db0f7e00b4ffe6572b144f6d964f4fd9d9c03ad97e6011cfa7cddc169f28fe40f1ee4186905089924c0f494801b540651fc734af92a649aaca59a746fa43d769c8e760fdcc73e9df7a0864c6d0bfcdd0c964e5db7ff132af6e537b4ea7fe99d768476454167819f495076c1f0024fc8c213aa4864ebff03907b678af517c9a5f5024c957226a6907a6495b7376163682fc88d6efd1548a32ab889ec618a044b4e70eaabee08c6fd38ea30c4fd93c021bc3bfa0613e93259318433a41990543e1069fb1c0144306e73b903267e291ec271797b5c3edc13b472c1c94a33ad070a14941fb42b1e498b7fa8cbd0f7c4036816a80ff856c42838b6b8a7227abdd86bcffe838143725ac642ff1b1c96de7b63512fb07da455bafc07dd1256c215cd328258f729acbd30483d8f650ae9dfad8ddb23e7a123cd0088235ea478f88484394ea24592eab29fedb63ab034dfded26288a60b940d1e114342d829eb6fde19d06e8389a27e482f470fd63efc2336bbf27dbf7f9846449c0918709071edd0174d05f2f122f61cf2a10663f7899d46f629a4c480cc0f882dbefbd46d31cd8854d53b4d3ce2ba8b111a8b8398950df09c8fce5d3844d7545081ad10a2d3ae24e5fd3147df1f51c948a40a4e79e7f4183f98c10bedb01e1efbdb0d06a87f175c2d2010ea408f9e04057b4c567324ffa0f301e7fe37f9d905ef38db46f60063bdab7df11edc832b2f64e2756fa3d05123612e2ba40f633594fe9d354f8c30b8c3b98032b0ad0add53b84146e0febf9725dcfccdf792581e1402cef05aa86a561130e802ac4bb29aee2dc01a7188debf044ff9bcf81b6ba8f9d957da7e077826903b477250266171c41ef23612f4e6487e75c7ef84eb8cbcd69cf36ece7deb8eee51ad7d55ff010e30e12f136e9e2f20170da5f3c4e09a0c9d40234f11a201cbbc07dba62800243fbe4f14b0f0035688cba62d4bbc1607380614ed149eb0e2a84c1a64361c188fd723fe1715f03c53f42633d25a1df46857fa9cf4080864ba3cda6184ce39f769b7b606a4f60cd5f90b0ce3f0d311e13037e30f4db1767f8650ad3efef7f874ece9afbabe71e485c7334f305b7fa8adc467baaf53580dcc47f6e8ee9f3946c1437269460f432a5f06b0c3bdb78e4b9b3e59d48d807ff2812b6c79eb901a31b2d7dab2782b363387e6550dca0388edc1249f4dd2630bd5fc3721df53e2279b74d64eac6829f6b7d827904338c6448bb07afe58bac9bf8298846da0b9088155ee625ecc34346b9f53e41fe9397f8ad1b2139969eb4e3e5173e26f2405be6a9f35a3df3cffc33eafe30341aa1ffe0bd90c27d1819f5dccfbd97d15f44b6bf1d05ff37e3ddcf19e6b0d92e46ef0f819704cc9276c2a79163a4da7b6c083ae7358315de4d68281cd5cfbd22cf19d02e2613d60fb22b7f9e02149664b8f84208f675da80c237caad3a382913e58de15b1b72133d233bbefe46a7dd5a191264deca8f433ca54451ce540424a24b17359f909a5e232f11d73c43b4e0fa173e79cfae2fda30ee49c9e18bb43936a8eac81fe306a2030be226a9d68f36574332ebb7fb2ca14e857f49cfdf2f595a22e7e4351ecff037fe37e327ba11feecb2168a76de5997708304928484de0a55bc02e4562463336e956cabd71f2fc9cee56f66446d6748b53734d675d89a8bef57b8d9bf5c899c629dd847f4dd9c05b813df575f503efce84d58b1f8d34300883c7c08e0b2f5c62100b4d1fb499b86f08f8e01bc986300c771fcd476ea97483ffec92981cc13fbb537ac862023692f9901e13bf3be0e1a90710f82a4febf3b08b20edda61b27410affdf9d0469365db33ebfb4bb01f6a2df2fe89c4b2bf685d88264e3e236244cc41f87ad3be1ef91cfef3db6277f4789efc099e9cc2155f3efe8ae53e9c820df8d986e8207544ed4064f59dcc6c8f8970f6816f94901e319a2f13aa288a4471f6b043ffeede113ff1f1e3e21bc7a3178f5faf8083ae176dd3f45d9e087ffe666902d255ea233ff23e2dbc12b00df6ebf79354cae851f114cf4ac750024c847a809271d87da1235aa66b06325cde46cd81a88e984fc2d8808d32fa35a40e0a082c380b4dfcf6cb6ab83b147df886c9320802179c12dd9990d469dcf08436e4c5c6df8829473707a753c9e2fd4ddae4bdd3db48fbb0bd74837e9bc1f12d9e0f6bbeff6e66a0d74da80ec88e1d8a1cf1814bd28505cbf79f10c73a1d867c66fe62e06bfb797c2df7418c38f1811eaf85c9e3a1831210d1c5a3cfa82c7f81ef0cc0e0fa76ee85a84175e8e239a53b84328ba2f5ed66f6cce99d1456ec47549823405f03704e98df78801dc772f33238334700d65907d9bce8658c5a05e866f688d127304ffcf17b31a68cb48bc98fdbb177866e4c1e864ac29a0e9678e96d610c3372fc3a71e541467b3a674df15c14f345706b7df1a2ce5d3acd629d121ff8d66fa056df520a35e0ac69d8694b09b186fe0d613c184c20bc41742b6670a6bf276238e84ac6580bb646896e94e74776d0e34426fd88f51c31bf6a3ed622e55bfc987cdb536678ffd9058e56f8a8ff0a0f1809c405de15f663462da93bee32a1b943e3a61e7ce3cfd5ff9e81814bfbe856fec8c8f332b40bf785f1c46ef0f2f505c5168f1f35782d7e946886b1480bb854781327693fd895ae2276485264fe975324125e4eb8c780e1d30180971875198fe8689067ac0ae615c148e7546b1b35fc92af30398835f50a819112249c768638f3468b2fe52972f20fdf8bfe88c0b6944dbe12b7df02b06054cbe5dbed6073fa28d2eda50d43e5a9e8307f2189b19e091d95e6b20bab9f7dc84cb0cd004047229e443fba581d68edef4ed4dbde9d069f0f85a6d3a3d3e4078ac3619ccc2433c12d5a7f6c7065b77b4a71fde5f684fcd31bc529ecede529e5016dd0f2a58884f831f9e627ad1679589c8ea232c73ec7d6b671c4c7223a6e1031d8a799c9b3b58c2554259e713a319850f1e1b6abe8f6ab75278e6fd60ddc8513d4274ea34d59ad0a8359a827c206be371bcc876667a1ead5828d9ce5966c0b8252fa5f164f33ac6007aa1dca7395bf35b81189c7905e78ef8dc4c2b10bd17af60aff8b8661ae1ce3b230ea04786ed04222cbd92873a27907745987b25b55acd519ec338f730f57794fb3c470112ef19e86dfc3d9f32a2b2e824ef25fe0be57e6ae69e31a4e7eca180dc2fde05e5feffe4bd5773eaced32dfc81ac2a4c3697338310329631060cf80e634cce994fffd6acd50ad8debff07ffe4fbde7d4b9d9db288ca4093d1d56af2e3cc7b665ada48b145a0f8dd837efcfcd03cd1cc91e27f60771c200fed1152948eaca28e5f4940b1723f05e064e29b7894b5ab84959b1e33e3e427249f2801fba5905c38d8c7c33d6454894819d91c47bdf2364d1b4ca4eedc3a9ab47e6dad57dd9f8b05888e4adc191946666181ce266cfd040bd46b3f7497e0c941acc01f0ea49ecd1879dd05626cbf40edebe85ffb2e1c78d98f72779fc26ec5973d58f8976af652b78f79a89bcf141b1dc4d293e33d2cafb7cbafd1c848e12ed114fec2feda4fe5a9a15925a203b2aa01d29675bd4dd478fca451686cf7e6b3abe7ab7a39809bdcf456c94bd29b3e5160d59058d8446cc3ebf7be5c7cba950677dc0cfdab48148cf9e5999bf9c5d68e597184f7878a4a69f7ce4d8dc3c72f61a739d60672cddbe124c0877ab3790d43bbdb58dd44afca44d233ae82b8391db1bc1436bab2ebb5d723dd89fb147656d4a244d79684aaee7be15ba517cd590c46c68414fc57268e5b4ad28c799fd33170310d6f6c6b33ebbe1650dbbbc8ddd0a7676fa0379574ea0d1eadb76e2d9e6330d5e961b040ab0adb512f8921ad5086126115986a3fa07e9f00e273a8fde7e6785fd295d10f5671d41694cb2ce17024ddda1fc8895dfa2e6b127fb966eb766c5d64edfdbb7f1f63a4d73e6627509ffa88fcd647702d8e1d165d05c12e8e0255014847ff5c57e244440764e26387dc15c08c4d21340d4992f8c2c3f33363df985852df1988b3528dca3b926e1307d027f3a272d33f5086d734dc4263b40d050bf76c0abfd26efdd2a0f84c597f48ff9a9060258e3f803be5e2a03df10ce4e175c2227374c9eb3e2f5c49075aa1a59b765756a0071cea1969d292de12602639d8bb16a6c8cbe1633dda4bd1d15ac6c35e1f8d834a29885c4d3e918639afbf744c780b2ce1384ad17f22005f34ee8f1b3aba0a7ca6a86691a4cdfb074804ffa9abcdd1c0b99cd7cc6a2833b40e7ead46db08d13dbb36e595530655614669e330042827fdb314c37635b3d83c9466b0cd2b3cf68e5b3bc393e2e50efc74ac55ad57d3171974c14c8318e022aa5b2e4b0d83e7032d84089e38fbafaa1acd4c8956e0d0fdec3f9f2adff3375a50af59dac93272af7bc4f2574b80e356c7e49acee39abb252bb323e3ff0e3eeb1ad9de1ebedbf0a0209f8725290c4c42bcd3c6f2de03f8efc00f6e89281da54eb26508bc023c3b498d3477d405ae6c4285a53082397b39da4627a43d472e94091c1b1b5bef2c2fb9b83691ecc7444b9c3e1b49646ffca43ee253ce47fed67ff878eef7fedc5ce7542348199eb3cdfb8d009512c66ad8b3cf6d0b971189478f42e7977aaf3bb373b5785fa9faeaa3b089466b673eb78858190a59f67d4b57a56eb3579e1a21b19125b3dee86ef3854e6b9f8cb1b9fdf685d3625ebeec83def83deab8bdd6dbcd761f201ab2e637cb16133edc6edd6c654a8c2ab3737572357be1bf665878c0cde9c38d5f46bd2879578cbb1ce3f86aeaf506a6d8545e25b57c30e97febee0abcbd7684c465ab53fd0c212fb63956fb2e88ae7f4dc8117c6cc2af8eacced00b4387fec12cd9241898273dc487c4fcb31cae79714aa56ea2cab55f9a09be1a7fe46b3f5e9c655310264cb2f790c1e4a3cfdb7b973f3e9cb7096618eba4f48fe151bdffd621c151e3d3875c4e9177df9d10fbd7b756b65ce61a23ede76c0ae1b1a24882ba207e93df189301207c0bbf863a3a56f9ed24941d0cf633b00015eb9a8d161b885645391f3057b430a19d04c0e2703a3b3f3943a79671dca4973adca9d9717de59406a5ae3c245eb3c68a54666ddbd31a75765e55dcb7794bbc5361e860734ed82e864353d41b396f450a911ef3577b2874509ac2e43b2f51552c19715e6ac841d77ea46c6f85a6fa3d9df57e639dff92e573ef291b0e82bf7b9c835b1aa253d36858ad350fefbedf05cbe2f343f8fadd8e7aebbe90a07a3fd71ecda59215c6ee44964565773ea22c5b64d87d25bf201090f459a20323cf09b9ba2a6dcadc9b5923766baf1cac1ee835d674d8ad5072db036c753f7459d2f3b1de5fab1765caa873bb3a9dcd59d08b82d5c0ddd04e3e20310ae6b93e2657718c1402eb9eb0af02a6477937533c43e02ef42c4d3584bf9112e3fad0bc0a2cdc22b46004d87ae6d26cd21bf588df4f425960bb5831ba337b264f8743ce5bd679e7eaa6388432dcdecefd5bc8d56eeb61cab7476f79835f986d36642b76b6c1bfc656dbeeb839eba4f56f109ce9880c1056c8f2da4eaa77c74ffc36391f293b831f2dbb5f78fc9c95e03a2a34966979a72cbebf6371557d54a74cc8e5a56b576b3e622dd0dd071440c57a35c88af14b70a7aef89834f37e430db49ec5126ab0b386c978bffc63fd7bd30531819f05fcf4e1de8c90dacebcade2497b973a92a3329cfba6cc557264f6ee0be1be60e7b67fdcd40db30dba71f112298b5b9f662238d0902fe4512758f3d2766c44d260f9879f9bec76bd24895f12e5d676015fde2db8fce708585f18e8e972bd6e33d7d1485164883cb215d187356fc04789ab997238467cd9aebec974165f681473a577b80f70d4ad6267cd06b2282ef70879f6ed939fc04c1f1d0b815b3469967a7afdac2290934f8d3b41bce7c9759a8b32e5f159f2b6c2e4cf614f2aa906e878410516ccf6a0ac17b22d677ae5a21d68d3482aac29f079896fd39247240261d7b6d5d99ad9998981d33c175550ed38b7dd999696c8f7496461d3944523a7ed6bafa570dd92d6b51a54cefd80f8f21d2e18b51b60ef23d890e3455ed4a5991e9b18352980f41d17c673add73cc47ef89ebdcbfeb48c1280a6de8a892b8c27ed0d8dc727f451f17527ff595f79448d717662fa6e50cd67c3bc27b831d0983f3cc8bd8dab5b7093585c90bcdb4268073df725ced7ff74d419ed66362a6e9bb487992fc2065f42ea0ddb0e0d220515e94094a7f2ce6ac3bfe9ee59a68e520ad6492ad04c0333cf1ae737073d724f9ec07d1dc4a4f62ca5b9b6a624fd6ea5581dec2340bd63769b423adaa2573a13d76a8253a21f3dbd71c1e131d54cb5604be87683e573f664c6f1e446f2f142f2d78c23221b1915525eb67ceb20d83c9761e3cfbec8c10e94e6bd0be50f0bac4e70733db93357181e55e28cf8f24c312569e136644d1e4c9902314567272c7b94f48c54092eb0f841b407f6e66f92927f45783f3335806565d78767e10875e9fc4dfe72bd7c7065d516bacd9c6087b31934b254fb8b9a0ef6cd9e1ece82864a5facacb234963486e89da26c096bc453fd67676ccfca57834317b8943b766b527a089b416cb3703f3203881d0f9fdc8264e01b2c1cffc75f7e89cecee8d381697c37d68936398d20131f0991021e51225f917cfdfea4c071e5f15df3266c273cf9e7f75e3e35db4d45c5b1968de24936f5b09dfbba9bcbcfed38bdb9d5c5c0b27b24c33890ecc10ad1877da1c1bb8a1890b6da6b53350e9f25a97487f37b2e3b12cbfd8861e445ff94eeb84f99bc72c85cf5071eb32aafbdbb413af1e057c1e649b2ff0a0f914d4dbca5f8ab588d1108fb55a1e04724028d94debaa49cfdc370e2917b9c02eed9dd3235d6174cad666af8eaffc67bcc8b8f3eb8e914b0855a69c74278ddf5e05fa5a5a70f23567a836950f6ef34d27e2c99a3f7d53d6846099397332c34240a50a277d5b996799f4fcf5945c0206db4d3b9d307a0ad0163a0298caebf0e286325763dfbe5026db771e1ae142f2edea8b4892314387dc0588ed10634f1174739d9be776c7eb0ef468653b3fdbdb27fc980721161089768f05d3c84777d95fc8abc3414f99a55be850cde38d0ca084b2105c0be66a32906d43b24b3a3dd5c0aefbe29fe9a1cc2047e6299bf8a506472edd9d7d8c77d4e9e44989e364798955cfcd3d7c109ff62dca2db9f8d4c286b4ee85aa9469c56487a71e55957cf21db650b6197653833395d69d1b85538e9a4483f9276b86be107657037427c8ebb8bfdba97a9c4cb8916cfb2db99f3765e628cd300b32f4a063b7ba00e2e67120d23c7cff28434cb6dd8b959bf678ce20867ed213ec832b5dc4d46b1402c1def269054d4f7fe3f4089f6c2e648024b8a871c161bf687baf4ade9454786ef4e2ecb4baeef46bbe77ebec3ab7910a27b43a04ad99f7d87ed90004423e0a27e72ad3cab4e2c0e43b6241f790ff6b0369d00b18be81e3b2c7b8f048cf65d515ab9cebb633734da7ad563b6d52f0852ff50afbcc83dd1c3c929af939606c6a643eb5e6441ec9d5943b20e109859829e764e5bb8cc7febca8116e12c96b44f484d734718d1b1dc4350d65fc6c8f474f46a97b03fd474db47367947b76a7cc449a3c33ec024e2253d44576f688c99ee4bd7f293c31fa61e5c78b72eaca9deb319cd845bd7bc29c5d123fb26889f35d390de5beed9f38a6075eb4e645ab9653d04addf1a2f7a35c74e2455b5eb4892f7295c99af070e8fd0d33495bcec4d8f739a395abbeb0953d2fdf85600fbecf15176575060e933bcd5fdca8c0121c1b463938b3a9cef74e0196478649304703a612038b526dc0677aaf850c17d3c6ae37aaf339ccc3de95ffc15f539734d00f2766872a1fe9136f771da1a1f255b066d27dbeecc4f4ba4bbd93b43a92e73484d37d4ba6586e7642c3b62fe79062a8967c5173fded9d48173577a1d7873968c22ff52e197449d23744deb056a79adc6f9ff6d1130d9714b8c0dc31cdcf90f8ea2f9e0bfe5dd51f359c902f78a3e77af916e6774a0c9c6a77fde8b22b107c3225fd8dbb97ec995bbc55c8ddcb870a35ef18354d9a135e917a479fddbddf5e7143de0b34a3ddae265d6a4a7de664d0af20f659543ae084eda857c4eb5ded8d7d72fbc37e7ee995486ec6d480faca655e3b2d63a4f299ee85803f78c55e2684c74da1b01dc4f46a90e7ab76619c1abb68f9020b4c5d3f7e3118e5fa996dd34b99043f70644a2a770fd76d3df3ee7ce30746e459f88153ef50a90aefd168a9fab2490f81e4acf5a952f5bf3304333a984089eedf9d06a8bfec93ee5cabb633e1ec249ad4167b63fdbe2b631d25e46c502b22d20ceea164a54ccc6bb3d1db4ae452296e5de4189bd7acfddcdcd655642e02f2ac35a67d77cffd22ddb4eff1e5d455c59743c52a4c0f22ddecaf240708e81947ac0d73a83a0335ddb9c6bef764e76e08fee02de39d3b376408c3bef24687626d9a88862e30e80d6ef545ac085fdc35c87c7897636174c18e98fb56b4dd95d9baf7e69daac52bfd7da92732b5637002b8754a32388cc25b417a1792f51ee097189cfb54b6fab19bc75ff69da172fbcc15fc38413bf6a70d4aa13970a3a4e50dee993c7ed791b1622d126b83eac4f501e3407283afcc2b1d12f523c8a35e0a30193a45f4469726ef486fad41e90a2dd189b9c3604bf34121540ddd0eb1d7c1bc6574e4c6aa9ca20ff4d4ba76d5873ef7b4e907bcb19fc934cc2c595f4a76c3bbfb10cf0d7cd191bb789b60432293b169459bb7b071497c83a00881e2c7a7a9dd37a602d80751c8b74b26af3797445eb49a53531de1d63e10af91662a4ae62972d5bf2ba29fec7eaddad326bd9f4005869215fa2523ee577ef2ea435891eda2dcbf39819a95b92a0fd809eb456694c73b82ddcde2b4d8153a29228c22c4cc6ed8afc93a3cdf7fb8ca3fbb62076096d895b9d4cfb191459dba91953d50bac257aab991a46f20f45a5b216de339a49985e4834e5cef073b55f0187f904f6cbcff40edff0aa1fa92a3a7f88570591c236b7e23e3b27e53357e43ef7ffc822ceac416c4a3c93748bea9f95813e2b1619c8890ab3c095a805c0a89300e86f805f2fac25f2809eaf724c5a3a2dd99d80da17eb6e6f1f3908c2cdd7b2b3e7d950bbe7780fb34b2c7822e242491beb6bb7c6b14ffecae273a35ed47f9768e24b9438d13173d08b6246a8260aa3df4c3666beafc96e5ccba277bce86feb42d19e55226eeee9f02404df448d01b8068f752ec196406ab859ec5fc5d1262625e7c502495471a3c9c6fa72e6dccf2cf0e2f9132d22ce02160610d9f5581d6bdf80dbdafc9075b7c1542eab3179e85a5cab31ee049a4fff3c792a73c2a87f0457bc9963a0953e7eced5681c6f59b5ae24ba3ebd735099dd5950b2cab0f64af9ae9896db723cc6feb884feb8dfaf52b7463a1b10b763d62e57aa1f03167e1746a1784f7112cc6a1aaedd26b6a96e51ce2093e7346ea1b5288a49eada1d28d0953ec567a1fef8d472d176ef14d75f492e9eeac52694d36a38cdf8d094032e48f3c620cbebea98427b8639ae03bfd3cb6937368c120259e8b226c61dac7d4ee5f93b747649a8618ab78a2fa5274ad7bfaa02d8de97c6e2704408913f9d28b27b2db3af592cbf8d266cfdb4d1b369ddbddbc433ba5c06b63ded865d626363fbc31d3a69dd1455ced79c11031182c1b6980bab2bad0163b1c6d15db117d45598df9f1cea8ac8c5d8d1e033f2774354966056824652b98ff396a62561fa181049717a9f1053ea19750cdb16fb9f2846b30247397927ca72ae7e7a526db67cf9a11eb166dbf5508761af025f8a3af543f3ba0a6e52a372b560576bc95f81e867334c84c369f94b9c3b00198b689d686d014ddd8f3d94f7f10d103ff65f7dce03ae80887b59f833e14305e99c6a836ae3ee1187070af6809f2826de4b2115dd7139aa4ab2c4e860d86e79ae43cc5544d6152841d9144209daae5f00c01d13e7cc4bd342228a45c42e1939b70263227c29e8ba399be72af661aa0f10d51080c7cf64b03fb7ade06b1f3476eeba4e770eecaca908bb37a30c8830fc6128b68d25eb42b66ccfa2a332b9dfc6d928da58f8965e632de47196f7a043bd4002624cce8840caea51f439e6bd2a8e690f7b66c53887679ac224d1060966c106cbb6ede8d6be0b44bc9517ffdd3a833c1aa941cf5afe4a0f3fcf5c7a00b3bd5fe66d07bd95a027e7433e8afab979b4f18e930884a13ebc931c41e8b4c9b7fde0cb9a7ca633d6113640f9d5a11611a25ff4fe1ecab99a18df6fc331c79160f498ca337a5799da3ae8d6cbcf3db1f159e7a52e17195a9eccab17a689e00b342ca91a98b52b0a7b590eb419091afbb35059e46cdfaecbb34414492812d7559f04caba4c6a4b83bbde843402dfbacfa1135f0094bf854269b5878784efb54c7fa89a79eaa7ff9d40de5eef8dda9a9fab5fcd7aacce06a95df0fd08eb5488ea66e3ffbae8717bbdaa5e7923d5f2e7c095f83bded9fbf7f7cf414f7a81337aacd4d2798b9497e1de8265ce57f1d067fd17afc91f61db1d9b900d8bbddc2c7dfee290773b3a790cf37e4b61f73e90903d1a64f3e33aca76ddff913f510b1146f05444d58e4869cc1081067339593ced30b1515dc74552653d91b2a55ccd00b29d4f75cd82cd5d54680219ba9ac0d9ac8652a4f8bf748c9cb672acd748fc7cb48ddc9672a1d98f0b94ce511cd67ed83ae03e7bf56dbf394a9d0467978fcb1f77ec4fa67039040776e80335f937970f91aefbcaf33a1a8672c21fb1479b58e144005fa2c9067719052a72352e167b4c8612a750816bdd21f70aa383f09b1d69598a5bd00410ddad6b0281edee0d7ae37cbf214bec3dae433a134c8b1d147880e329f63caeb4d0df98e4b568a1137c8ea3394f2a4dde0dd0b2f4264df14c9139801a657cdee9f021226e50e58bcdb0f0c57910b1d9f9822342e3a8112117495384d7579844a717c54bb3e3f76fbf907e2a562f93f255eca0c6e9abeff142500a43d86590a6cbbf4fabdedb6b5380948a8af3fc2cdd59ccd0a73aa5ee4b6b74cdc60d6f606fb606e55d1837f50e5a4cb7f4195437e98e8e63fe5a4f6e77691bcc791e36f1843332eff358b0ee64660b56316644322e9e989d01f5799172eb16b726ad5f74da0eaf5e80dd8acf4cd49f49339ebbb4f2ae51e4aeff51909f2bed64fce6f343c9bdecdf78e3ea39a9d2cc25556c541627ed69624afad0a5751fcec8615eebbcf9bd616616bb6fbc80d5016cbd7ee029f2a742d0879a2111412958601ff26ae76862ad5eb721c7c1de9d22fdf2fbe8409e404608f2eaa0690e39308f8a16304af9384de313a5a4449f4203394cbc11fb01d3adfd2a456c34473db21b95b7604b0ef87b4a51e09a39659bdf81421d5e12b906aada1bca3497dde5ed116b5ca2565b7afdc73b97bdbb143511be3ddbc8377659e9d24154e87097923de2df6edf5837f172a76dd6475781d2355d8e1f352982d5e479f49ca323ae1f02d7d781dd615f61fe3aa82d186b2472e33994341c46e4dca8aa6ff630c87f0aa7c0e768844bcedda516a27f32aaafc33ff09a19afb4cfcaaca2f3b1e2cccd520f24db0aea897c951ca7d92b5df7e427923ae98f33002fa1a7a2e9b68d1cc75c72e3da8f8ca7c6fb22c100d3fcc58ea1fa38734c167843c8f8f423b0e977760c3982e225eff137ab7bf9224d89f5e7c48018895cf371c0f48cc6bf5c16910bb6fe1ae375daada0250aa3f2078bf65a0bd33e5c18c6ddf1586b3bb480aa2daecd0b6355c30834d3284906e44aab06727027890b64878139b4839f4ecb7d496f41a71070e193d86922ff9f56dea7940345656525e0fda3f2961d60c68d8576a2853d29c6ba7a1f8b438c1eb64c71eb3ee8b099f86ed6a706e41a1d48bd6ed66360c930ded177d7f2193e65ad877426a090033a2ce293edab77b78648ea5c469aed5702158e34deac32c7b2cd84d8b28ed857b893297813cd44385385f790c4cfae376b2d3e28d031565e8b1e5c2e8804c83153496c3a40623ca0b7e994fb91713fd019dd43a5381bc1b5083fdbe47c58f6a7468bcade91cfad68bb961486c007d83a3b164fe85b029b323e1dd55fd6b23d4bd1aea7c32d0aa2e2763c8d2d0bc92c6616a5fc0ecb52c9f1c8eb6a775a669d9f5e3aeebff66f92cdbbf11fc79cab58655ed593852647f9c431735cf178425d5593076c225f880585449085862b5eb469ccbb4a4a7950e7276c3fcf9473794ceec86bbf3ff7a3778502bf077ab7273bc8f1a2876b8539f76caecf5c32714147a488bf6455da8addeb3ffb3b3dcbfecac233b6b5c3b584138ab95b8a050dfc6cc75b6460ece48bb13d2a035593026d80febb3bac875f84cddd86b99d4e9bcab767aaaf2679d2e6d8e8956cde3a64e474bd4065a5f0514e4804e2138c7c535eb85b07ff768b7dce81de06814f0d391aafaf923f19c2f46fababfd83a591d9b58a2283716561b09b6e53ec7b113d600cbf335eead1476c7faee911616aaf927784372565636c6522b5aca95552261e36e13290b8cc7d8777cde8a45fd3749331b413cc8d55e7c1d3367c4dbc41affbf744363efc6e1d2cf44f431907489eeb78864eee3b6db6a8216b8bd8aa67ef2aae87b054c92fdc31594f9be7297e5f79073e337fd8858f372282c6506cddeffdcdcfc331c40b792f0af0ea9e078ca5497d57fd4e70be2e5c13ef92d514952387ee96e548e2aabefb3eeb70987e74fbee887df966f2f68582de1ae1b23c8d89bdde492987909856a3b4c2e5c89ccc736a002c41b7bbc87441f77f6f56dbd956ed75b788f477daf403966bbf529eed6caffafbdea447e8b7be1f9fcb51b575fe1abd79f62bba531fd0a177623127f07e6c79721a0a6e8a160463d65ffe5f494bb3787af50d0537206ef899ef88b36b95b2c7f697369368358685c3f1c2f645211d7d6cd7aee1e182be676e7b324d620154e3096beb3ffeefb34a8e1b19d0c1ce131332fe74172a0437fb6cf444eff6b9df0fdae3a140ed0907e95b1884077d98411820d7f244cf0e6fbac779774248a78d9be258de30a5155fe1809f97d161393bb016b778fa6780bde6339bc9510083001f6e75355d35955943ff5ef13717c522158bd290ec32f9abff4f71d55d046d4aa1d58fb95277ee5594a707c84ae37f7a83762c01d9ec3ef0ca2d0558ec0af0979ff4fd87da5ac5456a2d89947275170ca67883a61d45c1ea30e2fe9f3a3f39d524bbc9b70149af745eb37adec171e6bf378fd4e5cddb60b8886173bc727904938abef4138882a40ee51273f4935a1919ab196fb266568ad07fd43616d4485342fa0456f277b34d827ecef3bf97b63943a9802eb4e877ebee8a6867acc567e6e606e24d5ac21b06c3b75d5c8a29cb3ddda0d4a302bfed58efea9db7f06f69f203a3b882eae933acb28109254f29504e30596f1582a548f04cd89ac0fa93a96ff6db3161177bb308841b86340e0f2fa87751f260e1045e46f80e3696f2970a432dfbae60c95878958f351dafb49e598b961d2304beeb533324a4dcc01b997530fa37d6e529d4b579db88c1c25509330f9f686e106b34533c1c41ef5d7d6b83abdf91bdb1be73725ec2a566bdceb12c2dd77429a10fb900777b077fa532cbc76d66e438db4555d5ed0aafac878746787b4a2518582d6d8bb89304424c13565a6df5cc05212e428e485bff16590bef201c0c4ee91b2fdf205bf689a60d2542579374637646b17d8d5175dc38132af98a9afd701a4703cabc319be43a44abc4a99af9893393d6055dba924737f4514187e16a796e1a90247db8a9159db6e9ae3b6a24f7b901702f091a4e603cb3048a47aeccb89070762166799d8a2177eb29115a234dc03b3dd448c3b077917510d58f1b2b941c7d1d815b2b807f6a8bc8550070e68117d253eb571ee25503842542196bc95b7aff1ae4edb49baadcda5b77dfaf134153c40802df4fa66f8f159a07f53fd17ee983549ea4857f7c9ee6fec7b4984cefd80627cfe219023fcdf8ed376999f1edcd3f6d9d2910363d3cd32b0cc0f0ab2765b76a77ae3267b3cc9a41a8382e29a77f750289a538eee6dcf1eb9b91ceaff81c74c38ebc38271089d809439ffe9fc24f32f612b79db30e1b4cd022b76b04ef5d86828617274d162e3f0ea4425121a500e9efd5c876068f996d9889c50f941fcd9de51ca132c5869a35d4c9c74a71abc1a5d56810ebbf0fe8daa403342491e7f9db4b6af12c5239acabcff7d07fd52e02017f682b5df439ddaa5c62453e9764a22d3570af961f7fab34fc2eee4f045a4833f3dfe4e52816bc9557d4c2c24f45660358868bc3cbb966a6a605fb76b37063f4c54241d5c70a043e0dc87b766ac274c6a9dbd40b42d340126582f1fecd6e052fff164b3d73bcae65edae70c25ef7578f13ab93c961a60d5dffd1cde522aea48debfdba58d1c0efa61a4439a4a4cd0c434316746454e5f7f2771aefa8285440f74b004b5466f8be7a7f5ec66966d463a8e05ca94bd03485de858e758bdfd65e54fe3128658ee0813e1f59d4370534b65ab7f1453a10c363ef37ffe1b7387e5653a79974f8ca689abccf35de5d6a1579c975f1c578d1665236f7c09c24a2e30cda08ffc368835559b9bdb51db715533f8584c76a2288a74fefe215c72f902adae39baf1fcc55d2964f5f709ccf1f81e8256107e5bbad4dbb735886e3785b02cf5d6bb9de0db9bfda02064942c911d0e227b72afc90df3ebb2296969365e6a0b2d347cc6bfbcffcbb10dfe2c967e1b45aff2c7618203f6dbe24a6c4a214216d6a688b7c947a84378ca54e4e06d99965fe5d2038c91b411c6fb13c1b4fdbd4f570459dcc297f825f6fe6f8b1eb961ecfd76293f5443a5cecdd26ccd56132a60fbda8776fe3abe59cae31ebd0e7463846d2dc40e8df97f88a5a98f9101f5b2a13783e811a051b029228a4156a0bca867d60036596ae024a3e873e31873bf4cb82eef20d97a69412857a59ea851ca45ae7dfd021bac960700df2783ce3d6227c322bfc6618d1c7b8be281baf2d37a72bbb38e7492d0180ed9a7ffd5afb37be82f5f47e48b60bc0568bc71c3cfaa29f315738494a2bf95140cacddbf26bba3849c95bd2e99b027bccfe896446f6413bdd151aa93836bab76262cae18a2263aa41b099300a8931e4019e78e75a99decd05c39864f48b4689bdc432487b9d064f2e92d129ade90da997ddea48ff79ebf5892db5b72c09a2bf1a1cda573673fae0afb744d734006b236e7fff58934b01ce9d0950c9a7474fca713f91dd7bcae113e90b96c2c9592163d6f439d8728afba0c096a527a59139745544df2556214d20021d7c9629d4c663b41a0306487cf4ba4b3b183bc7def977cb6cc0888a775394e689bf2ae44465bda1ac5fed6646ac9411bb10f68fe830f5172ded32ff166b5d2ef4e5d2db59f11d0e8a4c39ae60c2e52c11803ee3fd7e972b4813df22d061934fc79fea4f57202acb3befc8c1d0f4467d389cf9d24ff98dc99883509f60839a5dd35b3181e1ea1f6c017609602ed4f369b832750d860658a8d6516e4e86e426fa5e8ed5c24065f264b6396187cc1161f5f7e7943a8a5ee56d3bfd62ca072e61b5fe9f84238142b6aec759af3d1b99495ca94375fe14556f3b8a2fec2be42dfffcdd7cccbe124fbebce4ad9fdcc3d9637006099a7ed171f4770cde60bd17c93c7c87fb7371e86219f49988f73bd3134661fb17a928563bacd8aad5070e8af31ff60814f484e73c40836ef7affa3759ee73a975cd8d56762759b0f515b366ea89db326b15d810b3891fe519ee9c4fbaf2dcd301e76936c3a54b5e2b7a579df89e529b269435f6ce9311e918e5d996f2a1e16df2a3da5bcd74bd91e7ec87baff75dc755c5bcf79ab753aa3c62c9d487bc37d1b018f3792fada734f873829a082b90d592eb0c6b804937e46224c603953a5ca41c969b6312598caad1e2ea33d320cdacd615fab17192faed6729232a0f927d15753794cf44bfa55e4b8731c99d0592ada6b8c97bc76f77b2e03da795795a2065855ea3f56704452184e5acb9dc1b6304891acbae9d2ed972395e702646af9c9e93b308de08732ccb51f2c006452b95dcd6f803eb4a022902bc9d3d2686b613cddc65f950756e5963d6ff405d3bbf1291937dfa4100e3abfa5cdfdd38be662c9391d4e3b84f01ed6c9ef65c214827fbb66aef3bff576ccbeebecc74eb85e473b26e86785403669cc00a6ad0133375a32ff124014b24c05c9ebe18e9ef32e0e5bf2602eadf25009b73a5bae1e4d1f154d0bdd7c951bc1b3a892248f5103e9ca5b9322d3350752bcde38221ee6dc1903bd8aaee58efdf92d7df560c81d8be753331ab38f23d1ad069ab74f98f5a71f7a4634951acc43b573826a1bbb22f5b59e931d463ed0a73737c5ffbe3cda9abfaebf54646fe09b2ebcd13b8df1f38d8dcadddfe0333fce7f29a258d35337e032a7df15642757735d3a4bb894a953ca0e84db17c798b6207662fc4c8bfc40e1efe776307bf850976c0a034588feb633efee9c03f8b035f2a3f2ec6d414d7d078133184c04a95bf091f1cbf870fcebf850ffe2398bbafccd8cdd1d575a63bec809db38165b40bb0332d03556248a1f8dfb7c0174fc996ff472a14cb29fe332349742871e5640196e9b03cc37f2e9b2b09b0c1e246229baf5b556afc9650a532d5ff63ac1ca852b95a724892a669065b498f045f8231fffac77aeb7f7507fcbd970b5246633ffecdc4e43a7fb106a690a55cfaffc768b14dabe9a56e141ff2a9c940fc13c547e44cb01c40f379fc179a8f3bd7a3e4e3da60f0080350e544c82f93601777dfe1b9fe0e5f87d264b666ff124555daff2caaf2d37d19479a6aca434407b5b27dc8e09a4afa1dd37d4a3c001e33fd1fc18c30d840ca2fb2c785a0eab868bc6fed78094f4cc0dd1ccc07f0c98eff6b3ed9f8a3c40fbb2cc09bbe2b946b8be11f1cb29ef2852ca78491ecdedfc8ce64b86bfc960877657ed2c1ff37c25d123338d7e28189e35d2f7f1817493d25e8fdbf11b240c635bab0f3ecd4d5abfa65dce3511c6965de2586751b7a1abf31f4f4c7deff2df424c5788b3f83e469a6a102cba85efec1e294f0fbf423e9339f628de5cded26f98bf7151bd73ff5b61ef586ea40e9e3976b46601813957757f9a3471631155a8105a40fbd4bf2bd27d4f9cfc59f7029334e7aa3e18a5dc9ae0dfd2ebc18e82fd51c7f463ee9e24f9ff4ec5675a87ed7f1b3d5f883acbafe92bcfcc63f2f40fe6f2344141c09cc7e756cf3ef855e4ef46f9dfd15eb16f6f5ffa63f13fefb911458bc528e967ef1e09f5115b0cf64cf89e68b277df853f76ffa2be922d924991692decb09bc9763ede7c47b39fa87decbf1e09b97d1577e2b8de9d2bcff747c55fde473820beae73e933ff6bbcf2eaa2124ea53969a1e9c8941d1fc8597ce8bbd74b762f24f668fff97664fe166a5ff1bb3676bd237f7fec116bd52542ec516bd7de7bfad4669fff961490277da096d40d45b72f3e573a4dda1d211c4757d2be9a2df6317c764ec820ba98575b47e8615b77b8eacb8e9ad15c74a9ec5720eeb7a54b6ad8dcbb1dd76a753d8461b171240915527b8eb211e8499d8c502dc48ba14557cb0c3ec8da09f0e240256e48089967b7c4c16f66f465ce643d2f414d38bb3bc74366057639ad1b5ca7aa775a7a932cf90e8d767753fe447d8258ad5344ea0aca60c069493282bc9fa49d20b49dcd31d9b59ffb6b5c2471c5810ba2146c3f342db4e168c7d10f782196be18f5a56fef4403365d267414785e2605b4ba1b885543780377269854e8d956048ca960412d5417af6fc0f80443f766e24d0d811c28ab74f7ffc2d3e2d3a8590962400aa4de0e77c5591f4c05fe112ee1fe112ea37b884fbaf748f1f5f70d4ff1a3d719eb976196566eebf454f04aa3637a797db09f3139fb7e54c2908733bedf1d358339a7216fbe8843271c2817b1c3271fe81883ca95723ce2c09f74b4572d01b807f8e065190edd96ea40cdb4003eb5ce519bf4cc41aa4584509f6ef06bcb7226ffc56aa72fc63b8dedce3b7fa61b85db834e1dd788edeb26ecdeeefeb6d524be6959db11cda77243470ad40da433bfb50494f92e048331f2c83c2c9b566d12291455899ae9471dfd5fe0338de8f04563bef4a32efb2a4f279c60cbb7f49181bfebfc27c375107268155fa0d308333ede31f8783df42f66e6f6f92439fe6d08f09212f70c7fc0352e67c6301873ca7f6bfbbc73d782776287f67e6ec991536b07bbdfeb293b7a813bf3d5629314be3ff0de9bc0015c58a96949a1d3390a65f64c41a559cefccf0453f79fda54b7b8274bf07cf09d4b9e63fd8575005bd057fd9d6959ec98db5a0e3f75fe16c03a1fca4f76d630992d9e4bb37d00aba47de9481b0b03ad1345d3de9bc4f751cdc83636327f9285df55f7f4c4933d737ecc29260dc80ec540dd9217f1f64f051fcd5f8e2ef0326fb200f67ead9e4b0a1cef4de4ead75baeaceedb5ab74f54e038db74e578f3adbe7b11d8392cb7475efb222f60f3a5e6ec9f64b03f1fee54959dcd956ecc4999519a6da5024efeda82fd2d55459382d647aedd08d43f466a136857ab2e2f422b6be71c2343a6978474d56277e87d36b6a98374e02c8de8e3ce569bd6cfec554cb90a4d4a4c4e43888b094d956fe65b6cdde6f6fb9fff831dff64f53bd78b7132ea3d3f68ddd7965f4753ba11683d84d809247e64c65e456513131924ba14486cb04b089fbdb6cfa29e0027cd0d3ff54b671f7bc672d3ea747602df0dfc62f053155e0e9a74fc6ddeb09a7ed484f277fdc8bccd89022a9c3524821b34eb16fb75a50243daa423f792adbb7bde7c3ffef2ec39a80d41c9bd32ebc0c9fd31b35ec5a0943e89e325f21328ebb6f9f0e2b9a019cd8824d950b7aebbe9384c3df8053c141a87ca7adbcee3e312aaa3e0d19bcd041f57fafdf8463712a2712bb97be73831d9e6fa0c96c366eed8fb05d7aaec0c018380de5bd5e3e6e27e566a213ac37f40114ed125be9bdbb69dda480f5951a123d856847a74038afb3f3ad59f4ade1a4b5372381c1b40e2231f7176bef3412f6a5c16d2b3fecbdec5f51e3ccbe29677722eb257f7f3f4c28f44589e7befd4b9df4bb4b311ab36d2db130b3b7cbe8bb125ab776efa3ff475593493baffffdb98af88f4cd678d94cb43dbcf9d6f78749eced123030ddf91273b8de3443f24c576aa43381eab7e0fc8eb4f46bf2c54792afa154f322e58ee9d34f91ba330c34488e422001f7c455a1773ecb119580466d2a11fa5122c0f13d42bf8a23f4e4f9f39cbedd57b66f8c2272b70bd9c141d911c68e72ee3f8e1d1d92b1a3a9043026f4be914bdf9b3785600439f3224cfadfc31745a9c0711339fa1681771f91d836676ee0aabea4e97fed3ac91207427977d7c354334e4355307b5aa9de4d64b6299bfc5adfe1c4034fcc74aa496c5991fac10033a685bdbdcdce226e9c5c85a1132ec15fe87d8ca524162a457d09a39ef0eb3d3cc6b832d508cbff5b7d8851e25219240852a5a32e174804997375456e16eaf915c6b0c5f38163b42cead0fafacc33ada33fdc75050ed523718052c06bcf773f7469b9ab98a08dea7a4e672792854cc71992770c99f7ef75eac7c9819480bfb04abf814629c68c30fa91d92d980f99e068efac1d5072a0cc9cce8506b17348163f1f3abe9a68c9ef5a0d31e4260d317daf9d89516a6632e0825a32db106515d4425f3169815d527e9c6d58536e6b230522b6d8d4de37d0bf26869ebf00db7b4df8dc337425c7450422c3754388cb5b9a8cef980ec4198e409351a47fe45e989491fce883e1b43ad1e0ce044d3e2a6fbc3b11033d0945ec4b8043c3ca63f72c96b214fcca57e3ce13931997bb925a7c2fc656b61a854a246b943a6a076682f9b2f331f92aae3275a2ba9a88c19bb1f0f1f589d06a12491be2ed77507cfa7247da24535f762d288c6ef2cb72768d3449fc6ddfba6a3fbeaac81c170ec617ea34a87ebaeb4489a06619d293b3ff9fc332011c62d28ad658e0a17c649ac6d224bb51180d4455e3cb6dcd8f977bf2f3e5f0505ddc1307aede1266713b745de721f9db2bcc8ecefa2de1a3534e5d796f3243161a93c253e635be36fa3057b069d3c4987bac19504f9be8e5c684a88cc6c2114f838d93d14314af52c32c34e5ab205a1fb4328d4c3539b205998859dff95e16c39c4dbefd8f3ed357eebe9ca946f30b175713d3b2bc84c9e3776fd7d857629a1a137f2f880ec24ff5559f0304d619d549b909410cb77558f32c830bda1063de1513d00388d4056574193ea83768f3c2066a657b4d78960fe4559a0ebedd8e6011a9d4004e2b72062cd15a80eb0c72f1b0af3c5ff0dd746ce119e4c1c775ee9a69ec76bd3c5da4e7f183cd7c4421ce2e9736192d54f488fa353ee2b264bf3f4395d5c1f589e4688cfef4956a5d9e44047542a6db0939939fe62d7bedb29c781c3c791c815e11f2b439a69bffe23187086fb4c2570f6eafc00c34791d366710bf6c1420785ca93935d35261137f7a114d8caaad2555d123f5961bd65a0e2fac4769d37512395eab919ac1269fb907b318f16da77bf1cd6c7b5a66db231d15c15a68b2dcabc6cd95cbf82dc86a73afb1fd7677d83dee591da3be6345f17c33ecad9a52f5a5f7cb39e927b1bb87d1f387caf304ec6c2f40e1cbda3b83573e73e0eb5b52d4715afa0fb28d97a63a26d3b8e3f0dd53be7c56988b8e47d0016645fe3b5725e7c11e6d17e417bf3a150da327d1c91995f0231686fb508392cebc96c69427dd43d3ee0c5b6e6e17a4c6b511446f52d891c859d97939919a593c6104b52c277ceca38cef9c25838dbff876e4edc4db617be692c62a1567b19d1415e524a807a55feb1f17bae571a49d305c4b104095c7026df9f0025fb9a6086dc610a987028b5e95010e5e5b2fd2ecef4183914da7be601e7949ced96d3200df6e556584aa222fde18f0a99977b9a32847c17feebeca88da81c36094d594479a5498dcace7b495f1b10fbb03fba6491112be32eb06d672139d90702e708caa19de6bff665d10b20825445ea8d53a81f23e1da35c3afe53843ce5fd24367d1d62d3b1a06c1bd8f52a8af58b9a77b406905ae5be7d246f2d924a68103329a49322e56600caea36152b554589d215d74530e7b4f44e10500d52e3841f3e65e98e33ee744f509f824cf3f74fbf4642325832a240f5b804d0ebcb1d39405235f276b8aa5455859ab5927e6e249e1af96b6edaacf72a8b1a869dbf70b91d2cc9108319ec2e583d3f8b2dad79225e6a250a1f606a6e4a088a9a1b9eddc859ecb0e5b3de569331db0c142077d4773aca9bea713faedb76a118bef2b5d14986958d8eee9f4c1f2fbed613fb6bf44907033169739da8141b7a34da4af57213c966cd4f74fc0eb9096b8853ff99da1f392de5c3217bdf486b943194c4c88b30c70455ed4190ab8b409db490dbcecd61ac9d3baddc178500fe83c6a60881b8355467b06f98a7422d32b31f8dd357e9e7774404f456ac6ce8570df0d33d4ff4f935a14c353e7f5a05739d504b7de601ff514d326bf7f0156973e83ee448a14d5f99176b83ae9e5b1b2dec3b81b3299bfc83ffe5dcbda98df691acf4ccc4f49c4e1324bfe472cd3d728f1c28f7331e94c61daad40eb2ac70f985ab6aad51d7cee185b69b5ffb6b6ce5ebf3419acd3f26a27fffaad5095add68a7ad8229ea79ba8f91c7ab47ec2e9757aaeb448c55c837b9d7f6dbcf5adabf60b94e74714a81491f548678ddec13a9917253c99e33a04f07e0831880454f2aa3b5553dadb3a4682a34e97e821ca7072278680a66dbda066bcd9061b0eb417d68a578d1081a188bc8446dd7e2e49667e237e2c77494799507507b0329f5c74b1452f3deb3df9e6f5771edcc57dd9b967dd3e1a919c929f748a6fc7a277cdfa6d5048c247886d1c027068ced5c7a36a1abca1ead0be5da2becb51dfaedc36a6e33c3882bcb3ec9e6657bbdad1ef4daaeeebc560fb3902753629c1d65ae3a3fe3d8d85d4c3ad6fd4cc98059adc22a562f63b96ac5f8137ae29d3d514c5cbbd2aab6256173dd4561d98326f151511a98cde8cd9b277ef79497d6e8a5ba1781b13e23484c40227d0e5ce344ef2b3c6ce63a8b6bff3f1da6841097e48540b92b236dd6ba7cf3b632eb023be1cc56afd8ce51278667a2b7b39f17ab66d3eee6cbf2937dabe17476f330ce3997aa7130c08bd3ae1b0a112aa8bb8ccb793ebfb9f9f04eef329c4659f9b4976fdfd253fe975da767b7e5187571e1360a2eb69b0b748e05ca69ab918eb97164f95e61a272fd5e58fc89d68aa0ccf2d157d6c024644543cda9a9ea1ab4f3c3d59c7a0eda0984b34f20dd18bdf6716e0777a6411335fe7dc66da31927df740fd1dddccebf1fb5ebf3384f4a0e98e7e77266160e534cf0910b57d1f1b69d028b859d7f1cb5cf4c7f6bddfe7b8053db1bbbef7f318ba59987776c50d7f9f7a3f691d99faf9e8f5efdc73c0f9457b10acd55db61bdd71cd6b2d35127e1b018474496eeeb017fdbb53ad353ae48627e582822b05a45336d57d62bfda8a8bb5811ef645b79d886bb6e7c14299d70e5b6a0c60c155e86d518373406a4e8dd9a79c42b662033609e38144251370290f495ead3bf04aebb3a48a79efc853dfdd27102d5f820f9b7b4d8607599cf8ad52261138df44e03c5d8e3fa7c3f000839d35b295f65158432ed3d6b4e34dee31e41c0510c2c3f628867d460c082dcf6075dfd50eade4827450d783da70f97562459cf3f0fb4dfa570b140fe305e5b9d14559c656daa3a103eacb6cb7acf97aa35a760e1ac5902770737467b8fff1a3b6428cd49233ed2571ebd74ed6b9ff5865f779d4bde1f657e83da58fcfb0850e5d130a713dbfd7023e51e20e45ef063a66128f6497548fe8aab845b7a34cc5062c565397493aab216729b83ccfb3c3996d3e1fd6d6552060c9d1e94451fe695a9f00dea5756cdc1dc47f7cdd87db5c80e5e1b1332789a17b1e5c07be5b632224e9b28b64754e821ae1b134aa6213e992ee4768f5492f6d04c33bd33febc745cd1255d3e92dbae26fdd89f626f71e77a344dbc85d725b99f6f6747ff2dde8211147d93da09aebae8656291b689cf6b6fdf91dce784953c652582368a3bd0bb22c820f59404d1a29ca3491915bdefeb8e758ef7ef8eaf7cbec73d53ccd21facac4769b6e2ac591b8277390e523fade992df0b339d65c1972816072484ab4cdeb89c2b741afb0c2ce2f2825040e3f20d2f2ff1f28d0682b519d8d950e2e504181e79f90997bb67abff9441fce18d17129da0e3a49531b19ac62fc8b306a2896c02452bbec59a6f5c91b508e898e35d91d3dd5dc7022165b02586b5976d277aa173cb5f0d1c616c86070c0594e85224db61e38128d312192947d6fa32c7324cd31ee3d1c8fe197cc8df1e45a249e3db7d82a9c6e5589432015f326d8447222f8c779e725f18a88302d6cdf5acad0b484d7f4a4b9b97063b187b6b438041607ba8f10ab9fb6027e467df09d4f06b90787a23fb46d764a10bc15bb4f2e64e0f0ac02d0de6517aafd99a3bf63bfc934f303ba52611d3e700376b116700c3a3ef93e5bc48e7f705fff5af5f54d7c94bd13884fced705048352f3c87fa6434a6e20f620a23157018e8536abfac20171c0711047eab47fc523839fbae382fad40dad067be949dc1367f4404e8a92a1de72a974a38da6b71ca62aebd72cb1595cb4e61214ac78f167d95c23b76f88a67305f794b4da0865260562859b38cc50d6b72ce47ed89c68a891c27616b5fc01a00fce5d109d4443f7d57f480f710456fe2c68a1eab84ff59d15b98b57de9bd51109ab925451d9a0b5a04fc04a925b29edf27739dd061304b09e00ef3c1a24df16ef6d7bb22891264573cc5bbe292bb22f19b1d31b58e15c2d97b509547b27e105f289a9500115ac94b0f7d224ac66f3f8e9a79f9f6680eb884fa82029a02a14988d43a6ad47ef58c132a0fc292a3bb97406eb499cc06d11e36376337019b59855e015f794f0521b4eac42f61d6fa4086510aad1ee2b2e6a80b099acb9eb172e6acb9e89b94193d6443d451b3ebd1cfcf7572d398416a4da4ca0755be3d4a3a9bbdd989666f77629a10d5bf35b9564f093ced0ec992ac897647cf36abc91c587ba6798447bb295f269f82278dcb78143fa1c328439334c64c10a833d407e77c46da663bdf1a77daca3fbf4f6ccf1f8dd5a24f865af4d5381df5a0b9200ab2d4af9030472d2183c0ee76642fbf2f87895daa4f7f683d5ae36d297996094b8e426173056261851559b559fa75ef1237e548ca826d8a3363a43dd965ea7607c4a898bd1bcfb7e695e3966246a5be83f33c6be229166fff79cd29da4adcfe204907143f73bbfbfa61849fcba4cd5ad29405196a831cb493009bedb33a0a814a7a0d2f64269d87b4ad75c95f39795cb4bef2258b12e8a35d85a479ab29cd42da31ab722ca9f20949954b48aafcdf48aa1125d55224d541163e9a0bdec8b35d4faf20a93efe7b92ea467f3fc4926a0e608dcf5da679b41f586ed114fb5d6e6da9cc6fba4e530d41358470920a722e9350e734662ecf37328b86253346ebe2de137618d52ad4450d823f80b8d67d3342118ccb2b1ae96ba4c553499402c94b52d45e6ba110b48bf9f660aa0adcabd950956e406cfe2a28e3193a4fb65067ce36252c6c6d5349894dd30368310a07a9e09e596db1aa7335d9a410dd183a5fe0c5b0a3e4b318e91aeb7e23eb7e6dcde799acfb0b050c97bd00d7f2b45458738d664b3b4f164ff9759ce890ccc14dbb938598404da53a28ac6a24bc4b90c54e2f69082f3e9d95b60b53146cdb270f9a5632b31d9d9356aea007b948deff7eeaf186b26141543f9a7f69ec94c1a18726fc68f1721872654a1c8606d19d69172bb35618384d35e862fee12a17086935108a6cd631713d715716ed350daca13e233b1ef4580f2b3b78283b3da7a0cd75277d6ee5da706f57dfa724e92c37941af5188d39f1e39c7262f24a427c14578f7313f52424e5ddc40cc85c69cdf39aaec58ad44d8dda2b4009ae17b0cb99b7b5bcc3cf48c9862d358ab4fa53863a0f35a0b001552f62fad4246b0f1a96573f576f2455477d95b4b330b63f94724ebeaaf91711098e6b6d83c82111c6581216627a618fd5003179ac5d38ed86d7052b5aeae4014f7dd0b8dcd14943e8cb8e1b65179158d38ac02da2467ae210c9b0a1d07d9d5d48869bedaed342ded657eeb52c51035f99bae7b8d654471e6e3fbf80bb2cf5ed9d5c3a8e9a051eedd3b43252ec03d5ef69487b7734eb8304211bca426bee7bac7e0b31f780febec148b4cccd0917a8cb30f4dc8abbb85194319720e61d83fc6b3a571aa5dbb3238e8820b7f8ea63ba193b137a3c82e9469828c2174e2726f08ff9bb90bbc67217e2a0f453d498315f4b4cc3c23aec12a46c318ed4985593fd45b0004eda46667c402dbea5862a58f2767e37d12ba0a66063452ee2113c7b2e4c597f4cfb2a18b1082bbee8794cdfdf0fc00c2f72af5a2e80a5a96aa3e897ab6a797d33d78db5e018e7c1729c571c298a635e1715ba7b5c655a53ee1440d5cc7a61656297778721a00f29d8e92af379f3a7541642ed2e836411b8af4cfac7afe8e18609829e9ae88f782d0ed6e24a233748567036929e54fb0931b57a71636f18727ea2696da7d9cbd7af294d11e588999bb4fb8390c37e4d39ae293c8f0b097724c90e23ef3e121bdc7686ca3c1f78e82887365ab5dff045277e0ad56f703c65994289a6883015b5a83aa277b5beddea84f4252b9aa42a3fd2c2900b656e447fc6aba71e2f857a59a6b6afccdcdbcb64de896f0f93672f0fdc2191c62fd237596f3a0d856dcbc4c42fc1236c9d476b0d55f066743874c6dba4e208320f2fab4f9c112fa8e1f116b70adb68aa5b72c44a4cfe4d0ea42c05acd0612e85d38cf8e9bd3c68c1973cfa4e1da0601809518262d8dd4d6413bdd29f19cb0bc9b3fcbb8edeec58df98222deed3068d14f4e9ba52943e2d103fd92c4ab30574a797d6f8f086eda11a24866dfa6ea39da8546269436cbb1cc49babc6752de4bc56130ce654541f447a0b94832967aab7fb72e24af8583ff3f2b3bd61a1e7d3e84a2f62ecdd900644ced53704880cb689dfbe52c01dafcbb876287bf11618b7011ba8a3b02caeb3264b5d55d481be2614c26934e5efb03c72d6346580ac3612b2a935257bf16cec918209b0d3b5b7b3c48bbb592d8fe4143936f05f01288221ef9eeae405ecd35a61233550f0dde2db2fedf46d5a1b55367994e47a5fa03284a947c4932e0d93b391902561bca38498d8c1679db13de03fc7126da2afb7a395c79ae94dc48adab01e33575911a5bfd588d405d0d7e9ed1fe92d1702c31fc4e960bad292530286a629572b6264407191a2d65b608dc067292d9f950b9a4af5539ecc0d32c8d8e13a0058d6bde79bcb8ba43841eb336caba6885475bac37692f0255f3cde714aaf82dfbe78ce4fcebab712fa6892f764e0aebc9a126345c7296c4546ae0e1cebda75aa41998031ea5d7074ab8fe6ae62a7d08f8ea723742443ba154c5dff9e95630fe3e4781caba9dd6ffb873495b1b3e3a0f3269e572b7c322a601705c65134f126f1c04325393450e6f98e87527268a1ad9dd88c1c4c1989b1f219e3b9e0f2f9ff30bd43c0272f387672985adb7bc1d86f04fe296ee4c7cc556e4a1cf49b1015d9b367461a8fb1bb813ca63e9b4ba22c0b36cf13874f9a280a57997d357e4e2a7ccea6a2ca139dab4437b014adbda1b17605c2be9e4b30b1a94c564bacfbfb610a2b1eea6fe5150e9f4e5dcda8118cb53a7ec64793215e62ea763ab54bc68573c823f1d2ac4a1a0b527cd40961679a4674dd1531e91e998669fb41f22f1f669c1bccf6f99ccb336e0e5b03ce0e7d30355b96135c308965a1497964779c3af5c340deb5ea447577be7b4dbebdd38272200cf98fa3e877a0827439c3f11d64656b59712bb39232589aebed49d9e756d4c2ed33d67a0780c84acf3107d77a86a0d54a774a80c12cf556db45684d7796c1afcd43bd5954e3eb07fdc04c39b43fadae356b26ef9183d73ac76ea0567a591d4990936669fdf88c0f3b82eaf6aa47fb30a3c445710e4948b41d0661c8925603f8338405de97da8d7e55c9ad9e72912e9dd50c240524ccca505b36a2248802ee2283dc65ead4e0cac8dee223eeb2b559b215b2248eb0a8dac79da458ee253f6f2f909e578afbbb8ff001069167f5e7076c0de274ed29490eb2da19aaa690713e2057eda59aec14bc3f00a83dce6ff3bee0ccec2df1bb89edec553d40556a6e2b84a57614704dc6bdc73bf46c278a89da92f098d586a7e4067db950e8f7ae9812fe3b7f9b4a94a0e6bd0ab61176505d1db5dae2132ef60b943f7e2777c082caf4702a434b24fedae07cb4aa9a4896df68b2390fb7fb78c64b28bc792f6f04a70e0ace07c8f978f2ad08aee4bb3709ad8b27e577d7dd0872649592cca3e3ab46b70401dcbfae9348937a06dde62de9d7edde4aac692521ac675bd10ee6e29eb6937ebc140bdf8adb6d79b1953d73f9db35438468ed73765dc757b517b826f2ec910bf419f3cacd245ac8977d1c8327d47089c9e01d43e2800b568ff7993efc91ee813eeefddf733754b9f12f8416db71550f2aeb1bacfa0b8821b33accf2ea4b0a9f773624356d94dea3f153c1a882fcd12fb91539fff6a92b7d8f35e07da565bc4ff876f773be109793d5606e89213694b327bb3d2787f144d931d159e842c1d27d18df8ac2d35ec6c45ee1aba7b5f9cb2bb0f8bf5f9190b56669cecd9f1f3ba9600a2cf5fdfc0fb7b262a24077891e817fe9b8c734bd489685f4c5b28cef3c69288f797ddcebc469e50353553068e2cb1958ad0a7b32596ba7131da786d599b7da54a6b5a0864bfc81bbffd9ea007934b6d116c01af402d4928d7edcb459a39dbf928c82b1553b6b708d3daef0b563822c486665f27addbc59b00fbef2baf792b398aa88d2d5b1a613f23a5209c8f372176a3d4f2a10a28419bbf7a24bc97b59a00e18a790955f502845016058657709f548d248bea80566125ad6540c5367558ed2dba4933b11208a14f3f5310c68f11159c50306b1789f3b78163c9d9c6a9de28e2f4a5ad28eb598822b3ef522592d245f91ecdcf69c1f369849e069be12b61d46397a64b13a418d08c6eba47776716044667e902eb792648215e81f6b07f9eaa3d509ab407b336015ec297fb124872fff6f3aa0675a90783bf107c1363621d1ab913d6ace02b3dbf704504ee2b47408058777bbfea67a62af5c6b989207439697c6a422b9279e4024de28b5e3f476eacdae5fe4dbd7e074ac3c3d4874c753a6f5206ee2fdf1c6117be2fe26751fd36bfd7d587294469deb21e1579d9a029d4ce2bfe8e4298d3f32bcba79248fc411d0ab06bbe2af3ada3b461dedaa4670b700fcf00119d67140a76f8d19c9dec1fa19ee2b80878e301fce268de553a6c77638911d6f5f09bb41f964a90148c8b7a3654a26701aaa938af90187e9470c206b21acf4f4318acd8fdd30368f40c073061b42e3899e3fb95e0007b4304966d867e94450edf473480d47d011c1eb923e400398f5958934dba1e18e6e9f1cfa6880b491c27a0292eba412df76fc6458a0ef84dc40c3cb20ee9f3a2215cf6a7e0cd7277c4de2c24418b4bf9c88131ae96b8c74f6c92e386628b0224f6ef237ddd11e629dc3875e126830b3aba589fca717f4b51a106792ac6d6bf694ff171ae676e68d3fcaccee5a7cbc006ab0fce893d77af15139a1abe61f7922eafa29f998c58979312bbd3c8941463d07da9d99bba9e0db756b4991daface4d7d1f9337b7d120b5111bec44edad336dc793db148d64057dd3abe893917391d789a55e83b3d5d4471f45f7c226051be08f25f3909b46f3fce4f494df2576eee486132a06606e91ebaa724f14076b667f9e5de895bca1bd244aa5b1e0826ba73b38cb9219f6579276a1a7ccd6cb10d7f9b17992771bc64e310c795da40f18da106d57d11173641a5cdedefc3ad2852780dbb6d5c4db5f8d5d15ed841d3ca1df439c43310ab10774611d62f859b1f479a7b84d388befe82323353febbdf4e9d7980a951238ce21b3fb712c9f3b783e2c0fcc9a2d05eebe3d67e22a73accce9a499a1b57e590c8cba728b1a4fe830570b50cba4aff94a4177ebd5bfe73a2363cbfaa423bfbe27e6d29f5cf8db0a53fb3a5bf265dcfaee3d6448aa1cb582a90ecf5261a25a4f81c1e70fc7c7e8829079984e775a785f5c252629cad682e721b4b59fda463a905772e31632eb5f5ae8c4a3abfa2969885c2c9d3515e4b0b1b5bbf51e0869bc0a55e2505d5ae12edf237a2a1c3961e6720a260af339a0c48d2e51e1054e419bfc59cfb919df89c5c4c13574b012e45562dff4e84d12e28edd9082f6084f51c93cb023c38bdba757bc2b2e33534ab366fac496320807558f88533f204e5df0ed20c71655ac4e86297b9bb2f2e6916e93bc443e69e58617f8b38300e51d57f962a59a18e5538ee39159efff6145cd2b71f057271d2e5683f056b98785031da98c4d12ce833e1ca1e0573e9221212eb574432d623751788b2ee5a7d8ff3fd25bc6b06477221c5e21f009556da2fd1d76b2a9e6a60f805afb6c4ca446fa73185df5470a19a8dbe6a0d78c1da7f564a96344fb4997fad8e9671f7607458de63b2d74102a4a9954273dc563bd90f1447ca27415a098cd57950de67709290b5ada90b5fa3213955030b4273055b85f13f48ecbea3904da19a7addcb9a0dfd394975938b1e77afd94b81b987cf3494c10be069a9b7de9dad4ac66727c3e11ee5f4f7953b360217c76d752041c88e238da171eba707319d39515450ffc7d020fd22b71d3f30b21d3781e1624895b5eefd15d7b9d9b273a9dd009c239dff3c933edd223303b561df643c6f1929d268d96e3ab62f96252b64f1eca5b3381065e3e81380f78f7998ee8926baa362ff38d840de918a5a0bbac39503b88a8dd4b2287519ea80752cc35f6943e86dde18b291cec5d5f14543b82e0b1a8299657ed65df514a829ec1b07d2b27bc12eb07a6aaaf4c0c9bf6ac599fb6f2eb91bbce5467e0796b56a299a51a8fc46aaebb4ec88d96ab36173d66d892209992387a181e73ad3419a2b8af3cd1f97dadaccd9bcc949d5424f5c9bdb18117278378fbcaf880ef1a20afb6469132b603a467f490c6f5cd69aa0793b5b3a44892c3604555968cd06dd0154ad655b080a9dd763a2a5ba1145e60d96eaa3022b655662d152a4f2f8eabf295bc7ebb99d4f0023f54aefa25f116fe5eef6ec6b171110007a00ed5db21002215af2d1ca00c0a76bf0faf3b279ecdad5c402ad6ec3935e576b72ef20fac747b2a947ff645b846b7e6fbd837940b106e50bd9246ef4f7ee4ed27718376c56d5ffe13dfb17d0d3abf892b1c1e097ba2c2e3176689a505a809d048230db17ed2279d9d27acacb3296981080dce8431b09ced83783a3d65ba2912b5981cef14ed6530ad4363669dfe411e7e123755be3b88a4608af17891b0d2f6c9002cf7112133622d5a31d4eb01dd9e397ccc463f397535d770c1aa895ed7a95958d3ac53d4762a3e3196d64b1ba7a36aaedd2e6b70f57532c8d91a435947baceb0c687bcbfd0e5d8eb4ff1fdef2ec335fdb5495f6e7c01645ef86910156f9067d69ad2ffa9cdf3597417ecb6c13cf175668baf133c1939d2631c533b81636a24704ccd048e4912513a027446d477a6b34f090404c9bdc808f905b6244dbf0c3fae066fa8f9a4abac47774bef91eed5a4e70d1718e44e560821e9a5acf0690abef0e191d3622e13628b6b6a059a7ac33db6bd36eaf8d85d20026e2de0317fbdb27f040c87da05e69ec7c4f5fab565cb76a4a06388d7e59ea7d77a2fe7575c31e4d7f5c91a65c8a1043ebc53a870ba4a1d5cbacabd7da57073654d5207e3cb89645c9c64bf65f6ee32f94e2a55069aecae5208231e4e46aba59efb17c9869c5799890d5176265b660650b4379aea8dbb00297e655ebfe57471face9d31d78ea4e49276e4412f939e32b294fdbfe0297b6f09feb537747cf5f645fc8f44823b6949fb910d12e3159a1000a361409f9f9c9d76562fa64c57fde9242ee8678171078845044a1d25a92513656ff8577102332533cdccb887aaa8be91d29f42c0debf63dcbec492c61417ec414c0a7fc4329e25e0351bd4422439c913e639fb2749c06bc8a5734764c89c328170c216c64d28885a4e229d73e4369c40e5cbe8a48b2649af7f24cbdae70e73bcb5af38428a26501b6e7733ed5f305e7351d73bcb20425f2a6f15b0530399424b434b99632db55b6a99d0be93cbdc2bd337db7bb6358227a4330e384d49c3d62b491b07995dc78380e364fbe957a2c5da0130a4e51f7fb6e72ef586ed216ac2ac9e461a34b9ee54e788246a8388d9bc15e041a453a77d16a7cc0e5c9b5e5af3a5f31741e706ec284f88d1c2a6a2f326aa6c3d2208a14ea61495bcac49f3e2c29b73e8a8569d919b18927c1f26a0d695bb2ebf888fc3553e429e6582b4c8360bad6fcd07fa77dfdea91acf251519b04417fb1b794996ab495d484085f7e1295381e6d3660e002f306081c6055682fc72c156afaeb063698d11fcf8fb25b4676a5267aa065bca8ff85fb97b5c29359cbaf2e6e51c22f5b48ca65a18e07c655e55f8a7aae3b68e644ed7947b96dce6b0213f4ad85da2039b39ba79dbfb019d3435e472d455c55f0026710f6b6aafafe29c3e914d023c5f67648be139fbb2723c73745be16ead1ad3849b88df7487a4ce76ca0d7fd99d21db4a38060a37fc71052b9a6656c90a544a7fd1b29704bb33b54c0f9477ee56a841e1a70884822a026a13c8ff271642960104f29c9140df4fa6fb5d635f8071855c4a4ecde1b7f9245ad9cd8278b513f28b3594f912d6b20be16640e435a52a4fce2432bf0e6f14363c45e08a7b3fb446f158e8b4b11b3f4fbbe205c22fbe3e7956e7d43016a416e008a4e9eb9beacc2e71740d1a0156c8e60dbedd441840ad65686775d66ca83de1ff1d8c19a977b6e5e5fdcd96298c68f570bb503e53ab3d5240f9b3fbc4f7a759f04078c6c4740f87f32757595df96331853da76ed29a334cd08bff69f2a12bc987b93ab58e7c5d14c87fd04aad101fa25e51132a304965cc521328d4a3bcc4c70ab93f8af5c4196497aa1cc66d5be6a9da431df6e8999c4a07e62b3343e300f1208170b9e0fe31f992ac69573f63b7f6b295fb2bc26bbd54e2b1aa2d4f92af18c5f70024837e7505933c82e9bad0e31751300278b002a5c4011a3e597a263b8ba4bcea0b414badf8116aed04b2d70a1fe0b75af319133ca3937d49649361a276e2244cb3d60be299f2fc2ff7c22209426bcf83851772312cf1b35e76842180aa54c55fbc08922a50aaab88e79ae35801c7b69a34f3f5f3533ce627722e4421309377c3151928c9351c2cd14a46260e5fb5764db4c23ad8f5b895a98bb714fb77853b866b966f6376eb5ed8ce77279df0c9a5ec25aef059b6408e816de8681ea914b613a9746128c3138d73291f48fd578211d6648798ea1d7952d2659d4038dfbf46efb0c00970e03b8649b1a05c3547cd5b3b2a790e12e0f2040a20139b3f83f3ed636aaa0e50c413a3b9533de1e3d8efcb9bc7dd8b9d77fed3e3eef1b82b7907ce2f893cc7051ce58b70f0c364316b4323360bcfe850c654fc8b34b067fa0b0487ed33dcc9efa849d3504e43f9cd74dfa9a9725a67582925ce14c4c6dc2d3b1da54e3a914d8c1cb06db99598c554174b3a39b5e33968f7d9b59b38c3a9185fdc50eed9bdb9b7c9b4b47c725570d6e77572a9c45334f1109ee14c8d2f0e94bb766feead3b0de53d9e39686ff77d30c41a14c0564be98f269c511bae52d62a6e205b1f581ce326725d3bf72f5000442b013118690eeb592a12a8d6ed8338b5bf8384332d099640e5e8db05d4885b3c6b675251ee47168acb4abfb1ea62469ca9c2b625ec345894ee5aef6014b95eea256ac8a570189b644e78681ad594999bb59b1c5fec4a896bdbbb171edbbf381d55b12a527c75e25c5305d3e8191d65de6f664d4df9ccaa110d6bd3e0c695dd27d4a09092581492bb4ff8c0cfd498dcd39cb12a1a69ee8c6ef14e961bbc9bb9e70e30678bee8298b0665ecee7b82f3696fb68a7b63fe39dba268bb043cf8abb41a5d17a49187309f5f48acc6a3f34a260aa2f8c32353511ee3d1234f51c4fe5a40c2769e9eebb4e5be5cb154a3a43db0fe9944447b874d8749429c3beeb60c7ec0974a2a12ee5bdf19c95565bb651d06974639bd0d586e0ef377adc064bbd1bfb1772ad84aa45e92afd2a440addd35c6217b4298f51cb76cfcd715b9d9621b7bbbcd508e4ecace988342d0937e405779a43bd907c4cdded779540877da5baf957bb06bbb80a626161ba93b63354458dcf3b2149c28b6813ee673a017c46910018efa65a804ea6da69a1919d36804ac34b3c3a1de54f49aa32c2d4699758d77184b49857ba978f3ac63c33195decca851bf3b5cc3de11aaa4be69d6aa6ecba5ce8b5de3c3b23ad3e317c6eec5278a00af48f52e7fe2ec49e72935972bf04d9af7acf8236f3f7d837ba0abd2b9121d32cb971ffe47ca7a17a52087144ed792274adc52ffa8c09e97cf8b277f54a5fe12f0cc18b3354e6482fe7838883ed55a0335f0c6849b099d27ac45ac58d3dfc9d19fb665851d738e449cfac1424a98f9094d5a84406788a6b6a0ac1eabd84a67d9371bbcdbdac82ed9a3e132764913731cfb4d71a497ab417e5ce4fadb6bf2dfbb65f36652511d275f22dcc516f5e71d59d3563cb29cd1420a9465fdf8dc261eed87576ee53471859f5178a724ab3fa87b79653763d65706a6abe9d02a5619951d46fa77ae199df6e32fbc754257c6748df8152c3f14bfc199b72d69c5e9d9a2a9a1d9a5996cf3fbe006489d1f31eccdedc7357ccafb9da253979274ca6aed357a6c8b972c0743a93d6eb4216b073d9a580a122f6055e8414af1fc96772fd2ecc0777873ef3b8c5ed0c5ba15eb35bab709331eb64cb1778a0134518c7cea4b93bd3d5772249f5ea892d1d0588b48dce7608b673f79cc8f7b87b6812d287da43bd20f5eba9379e25b54df23b6b5956bae8eeb83d3748ab56db821ce863d1e4e3a71299bfb352c54f6b2bbdab1d7012ab89bea200fb525fe4f71e89fb4b89bb4d348a3bd1c951f68f64d0cd73086e0d389866666e6802fcd4ce3de5492985fb2409689e690705aea6e545685e11869fe958573d216b98a526b066d44ac30b1966fc8b12b2781407448f5a3342658f644be6cfc65cecae5d9a31973da49549e95d4673268c25d83cd23912d99763f05563dfb61b8930d30891c110c9422e85cb8205fca6002b1e34110b6aac67d4058233dc360065a8b45d193f57405b6ddc74f9f46135e97b8d9e2d898b115bebb01eb7e44d851aa8895e2d27aeb23a8527d9631741d4bb111080490ed7a6d840561107cfb9155c72a9f902f2dc5895de7d6239b099ce86684128046538024cc6641a6231023343d630c84053d9369d30b8f8926f5b1bbfee04aaf6b2693b21a97193e4e70b5d68268c32ba8cc9868c51f0b7fa8e7c321c8df1003df640d6c12ddf85388e8f1d635c92e7d88ea3d5a4bf23a555d802ec6cd55fb3058607be4e6c81359a190f95c4963cf952ee190a77e106d07950ec5576bdb8ff387b8bf6c4521b16e36c2f5b4eddce0ce1fa6bb15b29e0869fe40fa4806903e3eb538064af0cb272f872dcf63adb96f8022050898a2348916e824378c30ccff1b6a0b8306f2799fe050cbd1cee08c9dd251b46a8485a184142667afe6e5762d5a9a9cade9a9f30efa7d60c75a96ab176cd55af5913eb40775c31a83b1d55082e7ace340bf3414f76b81744d7adb5d35785605746b49ce91f738dae6d6da57ed4698239387eb68d8e9e739ac8a2fdf746a3ebd0e8e8f952fe727ce54bd5bb9104a25d350911e8d756d8ede65d0445e39ba0d86b5a8ed6e837af32853188e60dccf1d0e5ccfb3663876bed43c80feea5804d5788ef43ac95ea3cfce2cf40293fd59f8713bfadccd8dd347f5b7f15b8c6dc5fd7dfb61259edeac97e13a301cc207fbe993e476e22c1adad67bec2cd25364b43fff1c18a83c03ee189243e838384a58deda4257da574193ced464988385350ed93dda714e307d951629b52cd4c4b4a3a0498db46caa1c8cafd48aedcc9632ca3f1da35658a4614337a981bcb30cc04da11ba517bc435f3c34a1961139fc69f0f52c60397591b19606fc7d63741b6d735ace5a748943555ed3355fff55beaeae065b12137d4dcc3bc98e8513d9e17dbfff2bc68ff9f312fee0dd350812dd9ff8fe6c5fe9963ce10c3f25fce8c20dc01be56f722d91304a9fd622b39f6ebf2837c733cdc6b6d35c2cd5f0e77e2151beae0e675cb0979f3cce3c0a9ab549976db27bdbcbeba2b3f0ec558b7c7598fc4f155ae5cc54b5f0de6ca305bb69b316457373431c4d895723c2470689744912952bd0686137cd14fb505b4896a9517708c59f991e64d47054fc8144d3c80298f92cb6ded99cf9e13a8936e155be813bcdd48ef618091ea6e4360c948a6e615109c61fe48ec05699d0e171dbf451796b19267200f6f6e5b9f686e238f2114c6f88bb6f393d2c78049a7235552573adf92fdfe1f853aecfa4c84377ce5cedd422bd15cf15f34f73de6e12b6f5b7e68854044f382fc9c1e1299ccfb84bfd66058ffdc35620f4e1527e0e433efab4678998fd284e217423cb695d09836647dd9b23e5436f21b8bbb8b26f7d7e89dc6012f93286ae92396910b01d28b6e0904311d504c54a9a7273fe5b5396a5a03bd8c843806d1e38bbf3d9e41345e3be15c256f879d8cf53c172e730c477ad9a619747df965b58d6813b5afd3efaf1584e47e53db4d9e046b566d51f591484a36ec3f9aed8bd86c2fa1f2a12fc91e37e6ba7bb45694a7966deffa97f66d472dda4506534ceb6e2d9eb07f6da8ce421010e7f0cef696b9f2ce3bf4f39ab66a81be4a08a079f98a49f36f6d5533af641a7c51bcc510bbe79180d33e1cb93bdd65d22695f6368fbd391d80722182e3a4107f4fe2a202446ec7776a20a7b156e6b6f16fac4c2f826d67d0e2ffef66a12ff46491097010bee69a0a04a0758efae129a7c7a7c829edaa5a565f426a7d44455ed0e9a4f1ee40a6b95262901ec14b1bf5919e396c817de36ebc272edf4229ec2bd3dd53a1b89ae8e5c35a7ab01d3f4f3a0db57f90d17710ca9f25bdb7fad360a4472352fe59b3f6bfee27efdb1dc75dba6132a2afd4f0c8caf93061003a70af66f616f6646d2ad6e2fcedff52f375139689e829d54bf36317659194d67a357f69bb2e7eb97d96b8fdcbff5f335ca7faf302c2aef6d54e9b8becf8edbf9cb5104c3261ed4e194d582f0219a56499ad054ebb62441616f0955f78b1cbebe066130e0c315cddff557bd6fd69cf9eeb1da7af4ef58bfe8c1398ad99eafd3453d3b8f6be9ed35f089594ff17adcf25edcd958efc02f0a5117d75e4e6771292bf86325343325aabac045db0da65189ce036e852736fdbf953e495c33f6cb475465fa2d03d3685ce98db4dec91a8a95c758bc4d99aba56ffb9715c572ad8824781afd6c9f59dc8089afff78c63da56f56f488bc55b6246cb370152eb9d6d6395999e80b760a61be26233caff623aeed92e8db3bfbda54bbd5563244e8c08fec99fea3b787efacf248fc08649a35510b2370b9fc5401b65b03695efff3ff6deac39799df917fd40b88a79aa7d25c9c6388e63081042ee084998c198994f7f4afd6bd926c9b38677ffdf7df6a93aeb623dc196655943cffd6b1aea884e58ef74fe83e2db5435484cc50ad79ae410b402d24128eaf8150c2443f93652eb3a5bd9c92840de9bfe86a9fb50d7b258b9f5cf15dbff784dffa562fb2fd7541d32abe98960a5320ba9dea17f68e2e5252987f7ab137d92a4571add2fcfc860137ed5fa20cf26de998edc78d38749a2fd63d27bd6406c653f33e97be763f95db1ac7f572c6b502c8bdf15cbc2ffaf587e572cc93381a20c4d904437877f472a132d707867fc1a3d96162359eabfcb9fc9332e631b846595329aad9c1d49d578ff55d5002e7a85134513a7d7969d5eb0cc4039a8cb2d1dfbb38c1112bf77accf446740c8461192ff5a0123c26767acaac22db697273c7afedd8fe690b72b717045f6862b73ff2baf5868fd4fc8e34b5361d806282aa9566aa1fe036fcd79fdbfeb79423c6a1788fb48f9474554142f5bd4d2c0ed93cd9001031441fa2ca27c0b25120da872a7ba91877ead1030f15945746f9d38e702818c2f352857f69c2030a6f602453b6e14821c16ae7a53b9f93666091688ab6245e3685b59933fd4248c6a845a174111b0ac079714e5e607480405f0ff36f108d25f38734e7755d9262df8cb6b2f7f22dbc11fc8f61f05ed472d680729b3d1524e4c430d6b7a45fc7e4e1ff98644f2ced34ff1893fd7ec9bd96fe2d3019ea03c6026a5608ba4235427a792d23aaa5f1afe30ef175bffb799f795170d29871b198258597221a98b3cd36e9dac86d965abbf9a98532752fb0bb647c45bf98a22ad2759420e6393ddc948601bf2d5fbd66278d69cc169da6b7ad168534dadebae70b51071bfce5f3d2b14d30c83bb5f68bd12a871747db37ae2e8bcdf08a76ee5fcbf68449f513aad7a44a50d3399c764d609aacf0500c2f7ef7dd20c3dccf2f382fd939f6fd4377ebe56c4cf67ea1b3f9faaf6d2b60213cbf479aac9547034073ebb1ff8a42b8e162f411719a7dbc9b4ce1cfeaea8c8d85e531eca4d2682832bfc776b241e3e7f951e1e1adf25064fece4462dba94d5f98dc1ebb1ec2ef2076bf7c55a72bdc3f997e55953a99a158988c635d30ce6a4cec2648ae9d9eeb34978a8a99f21e95d68d651ed7b9117a7aeae357aeb54a600aae07de19a124b3f637e6a09f6d33d94249ed4fc2884798faa64192c048433ad4abf3e16ab428d1f7360287557b004fa9e65aa13bf466b69f0e9119bbc90bb3587fa99cffeca7e69a6a22f63d3e3b9430a614f14d0bb497eccb488be5d7022c9558187423d643b1e70fc26074bab0495983a2e4b75373ef505766660663de11465fc825e86a6544432090bb9bffb8a04561f9de96127c0fc78a26e5ea884f3dbe8b69271414d3ee1cff17d9baae8c7c2ecd2ecada7ecf77a9a3e26a505d03a9937259c0775b77ccee2b759dfa3deabb99497df278caa06fc72e9c7a7a62beca1d2e88f776587ee9c4c0b9538b0cd5778876fdd39f1dd7792fec32d865ad44ed2286775d63b2b2ddd665ebf3b5629bc8b6996a3664b5009de1149ab9569556a0b2f92ebba34251a30a80f866631637acf0eda17ee491e72b05d2063ff5897964b44a4f575a967ef24e4e1d9f2ac9a540bb99156c1139fde9e7ae0fa5154ab91eb47eddf8c6f84cb19e429bbd7f11b00b0fd3f128ce99394d012799452f85e001d69309cbdb6a43c1755e61a57d30cbcbe18943d0aa0711a8bb40ceb4e56936252a15091a29aeb2346b2a54a583993c7ad2766b2901079275193d86724ef6b6185f715b62d8f0fd5427d2ba58d51a88f2df8eecfbad523e1ad50a3ec42058caf5cc0b8a9b5be5ca62ef5278a8019900bdd5d49e65157e44a56969842b4778832eedc9ed010b9acd442ace5ed89c2f6ec2975032c989aa402f8a69b9be9669e7643b5c651da5878d8ba04539bedd59db5e6af583584239fc8e85b36e1bfae701fd7c0cde38f9a4ae19037ea0bd9932841ba0db5e69929f3338e4398d0f50ce6013bb07bcdd85d2128a1faafbf7f0508002e9e70f17877f1828b57426be68b212a4d15e95600a593d991186946173945d45ad88201fa11b14be7638b5cb9341964ca518e7a43d425103a20e41d286c9fbc3d2ad891d50009b3bdb89de6b585674a72ec5881b0c5857869706debe500e289dbe68b8536d5982712b390c057084a6dfd558f979241d71e9050e38a1317bcbecadad1a01819515504150ad41f56d149ad4d67a78e5f0ddc036654906b5b037194759b54f3a99ce90de1a0009e19e7d3a3d51593672b141da70e7128d0c3b41fd6f075ad6544b948fd3d1567a5e8611f45ef2ea3e44cf9d19b1588211bfe0b9857008ff0764046453863746d6a67d06e417d4e43547c843f92cb389ee9dcd42403d2035afb60cf186735c7f849f98dc416a920c76b8d8ccd0d7045b6b457003d117c01e9d3cbeca5a195625c8e6083a6d40e1110e4a5935291d35bf2c953b9e7faccdf8ae7ad805bbf4b8be7cdfeaaf8355c0f7b067a61472b938b3268ecee95469496d4d36a44ab84022e65b835a11d6f2990001135640d7316f66af497db7ee3266560d5d3d4c5270d059764c70886bbb73f8c6ba805fb0394e123fd8382dcc9afc502518e6a4a7f0c5fb54ae21ddf92bd45e8230cb1495b4f04bb0b035c2ba07f5479635660d92103aefb96dd83696dcd9e58cb83aae113d74ce0cae4baab67095c852c07a8c871eba4146e21af9d94c67dda8419d6067e1ecdcd6594a16b8cbab6e5b7dde89e4f50ca175918594925e8d46a151a1d3f8681ec28cb78aa326208e68c71edc61b4225dfadf2786c52c753354df34816439d155c3d90aa19cb25481e2d973fd20bf18ea3f19947c36b8834ce2389349f33b48c14ae6eb9ea2ae8284518a80552037a64bef12784d9823e470b3cbdd4b4402d2477962d3ccf27f11b07f0fe44d721c7b1f83d6198f5b1a9979ed27c5e1adc30e7f6f0989edb95fcc7e7f66779deed86e9d4ee11dbf2769566fff7f4d66ea0c6ced9fded0c83f5027d4edd1c84c184a854398c29936d251b63ac29a9c58c57310b11c351911c57a1664e015ac41acda9e8c185e3280e9d243aa96a4321201c09f5741a65ac4c1ed7af76847a45593298162c5f28bb446171933d3603b83ce4bcb014428228133788b836c328f76c39a2ae22f92d3da808f3edbd447a85df15189c9ba9fa17189c08a2194683dfd283183c98db9c3ed3c4a618fc66614ebe2fd4d375681015f66a27b711c9a89f30deb4f09194b07601345bf7c6c5fa13fa79e60bc0307685f8d40d9da67dbac90ca9a590316ce1dc160ed8b90faf37d5199d4d324b719e64d668f686f750adfff6540b19bd36d14d9a3a246eaa936c5efff7a8e69eedb257690dac893af462b520aa1d265073a25721565ce38c832bf6f129135899c1c7ac36597bda1b084d0605a9358d53dc38098031a4a94751e6b12fb2603e395c9a5411513e2060de2260201ab8d7d53be85388cf2d706927f93c00703390f44bfe7baa4fa4c3a3a0862eb6c0a67573a7531690082c93fde3fa2c874f90baf502049cdce081d257a7d8520c524a31a92a3523ec811ae3a5ee81614c26b44152370c45d6a9d6f3e18b6cbee9b0eb9f0c8babd8c22bbc2dd4ca219dabb9a432c033b8c32869179032d9db008e2e03e4a6b7ca33bcbc5e80d2572a50ea11612d3de12c148539f57b96a9f330689bd1a3e46557d815624d1fe41ee37c1d247afe362daa28e7646b706172f4d2013a14ba64ef6dcc42ac07e5ccd4facb34e972c0156f22607d3da51da88b8cb0f6d9ad73c6a5413c55e9d6592973f932a5b977735353c88a5c6e285435c8734d06707257cf32bbe31ab469dc3e0b86bae747e32bf4294fe811b370374238617d0f0745f7a3e50eef51efeb8430f6603d394e99892f0095190c51cd86c48830222c1abf0de114154b0df4a0d7fa2793205cbd3719b0a084069fedcca4a8bae4cbe32ab2206f88990e767c99b45cdf27251291a79aa0c44e6fa2f7d59602543cc2396f03e4b64b140f32c0c401f00631ac2ef2e569ae267ad7ab2ab2b3bb34c121f9d72614cf7990af30913c52506e50d52282dd2297b7e35b43bd1023d147084dbf3cb23c11407c0b2b80e3b8c5303134be182d9b081ba9f6dd2263bd94e85ff76237b5dcec75729069d292da909842387a0deaf29202334111bb849c4432e496412270535c2980f8c4c222d764ce3f662364ea44bd9d1b48dc11665dcd1b295b5252b5e8a3acf360f50dad5152e13cd741e022ace90e7b283595d51453d3a40d2dafd39932a5b47ce1ad8c7cc6631c605c2e07db646e7a544edf1567f97636f5a4e17a4a5cce3b647d531d54b64dc54803a3a0c147c0456437e87e060162334b918cd5015f6fee1d00b2e39e676431fde408332de1a818bc0f4014443b3d38d9d719fc8e3d1a8d2fb0190537bd1b3dcab86a63946c24a7b8d377957c5bbf3cfb4157e677e86829f232a718af29b8235c41dc253c34f5564137648240f0bfdedb40d9c6c928777ebda15676814dce20c0245b85a8e8fa60862cdc0513dc9da1839a46c47c718f535d56a60bd794dced22ce8c06dee4729567fc8ba5547579b8a56ae273058d7dae9f4c437ca9b067a09ab9f8565bc3b05a37177de1d264bd025aa9c595044727845286cba5b4c65a567abdbbbc5e229d7a46e9134e99d0b97483d554194ea6be34ef4f1da5d00010afb840dca74f42833ac96b49425da0a0f627bc8bbbdad244b94cfbdd740371626bb59445f25b16d85b4d0cb257ef40b7e8112a1c99f5c7755eef5a8991d45d8a4cee1ac3460c6bdf908e27eae070f121ba4ed199cec6868bcb4e9b76f539ec5204ca8398b1586be043118e388a7319e068d8b1540da6e7a086f498228409ffcc42c52547b4af43c466234b28f33b2d23fe41ce10d2c81744d8a4ccdd9734f8b78a06bd759543e38be90306b716aab25fa458b03ba1b1c5167757cb8c5cc3b0544309377294bb719ae43f010f2085df6e01f11a5a2a59a960be2b9b02a11497e3d43332ca0045a444afc665da7035665ff3157c2fe65aa65657784584d66c8184b5951b448b97393b015276974c9f6a019ecc0993c1890b48d2498f817858bb71bdfd01f35d623e41f65e0828a9fb7be60412a1a832b21e2e7a0b8a7ef2502820d85274de7364a7bff4f6d10b81a2a0559e9e1cd17a7553e94ae2cea08e62aa8d2712b091f1b8525ba6a6e8f8ac3b76383765b84124c27b09d3125c6d5a3f3b73d32d4b2e8231cccf690bbd1f21ca0705e26f6344e73899679c93323de61088a8157a9f437ca08821603f5c31c45a215bc2d3acc4fd84a91750c13a5fc5bcab378622e7ab0df2c87f5262c6bb07d4d95865cf11919b67aa602bf94ec566fe6bf5841b49943f1b1324a9fa42bdd7d03ada421ced132ff074aed875027eba968051c135bd4dcab42db45e1bacbcc3dfae324c6e07ce58d3fb8577c6d2b14642bda2429e59a29b9dde738b5c3ecfccf6e1fb46f085c7014a398ef0f4cdc411c17760acee3145b8a7c27196802a41853594b86cd8dfa5f7701e5ed05d85dd732a790a1e89169cd2c0f6e9ae892db2e4739329b5d602b57d049c7dcfc049e7cda9a6dc3f5875c2bd636ca5aa6cdf70b1b75fff9347bac229db078ca4a0ee5845599a97232fe214ffd2cf0a887f0795033e9235129716a1c056e41a58d845233f8609d3088e0eecb30646b18f083b5c17c30fb3aaae58b76ef2ec00dffda2a7ca3f8114a2a44958a7ee15c9c33b394fb89c890d81afec25fd1d42c9ed668f93de5f4831d0db8cbc119963a5d51b142e0937b4a526f7c74b6d5a9af5b4d86b5a07e708f458bac279afd296f39f0e80ae4ded1283dcd088745e52ab9c30ed493b729ff50e1a124ee6520a71907145263b6ba485f1ec05ad15cc6cb8a169b31dd98857a6221507c91264c8b5285ca10a92a4490eac0b115d52ab48e657ae6889bb31b9c26148a2aaca2ff110c035e7089527f07fe14f51ef86ea5e7b22b5a8c5cb1f12e9766914c6e5f7722079b29b31e22f8b76b65f33d82f4b056ddf48daf7b2981f67e4f81d0bf828ac3cae40baaa5778eb5e03cb49c15c1d2eb97b37aa06c5f506091aa6e3ed19f77246e8cfc9b03694b3e7d1f76e14172019cd6dd8fc34c9255d3073315670fa2234acbe4db523f6ae7b79c961c28e15681d72d53dc8189585b2bb694f15858c487c42748466e9475b2b7bb18dc5f4abe4891fa6cee5a60de1eb210db8a4d43c652a7cd057ec6dc2f59faa033e2ad8a1584f94f18b0ef89e8fd9a2f0b2232e8d4f5122613bd8a13e6eb151c14e0d2c3431a648249cdb3be204cdc457e18ae19036f6eb2791ad7115881fbda460fe5f322275b36b6cadcdd942e4ec030ba23b326ba9221c66315fdd2fc07cacaef888e1a700a31ffa24e0c7f54cb02a92bfd4cc861c34a7609c0dafeb1a3d0d03c8d414d8c02f59739d73bd1dea8e31c409952335a9b7e2664718de4627fe4d6db60b4e804a4a3006228c1d78a88e08b178a77dafc8fdd97948fb27a6d59ba50f9e9c873309f4e2289b778bedc0c1eec5e95a2a8144d437c8f16fe6ba00d22d5f5f2e1224367765c3889dbcd117fe0bd94a7c44eb621a972b93b49544957fd164be69fee9f439d58b8cb18945160e6eaeed9b70dcabcc640232f47e4294a2d50fa24419cefec33d3d7278a31b7d389e61579183d8354e74f15421444ad54248e051c2c6a50f83bfc914452a9b294ca90e57eeece67f121d0e3e58dae64c0b9767b68499ed2e50d4f54665915d63b23dca1517d6b602e11fd4944015953bdb250be802e319aa7cb6e70a7aa694ee5ed5286a6fe67cb7623bf3e094ea63071f2b24cdf8755460cabd5981f03aab16c210674eff7fe9ff5c4db8867aef8c85c334fa94ea196e79a5ac4fb26393958b0461f73925e82036047c70f9b97cbf5797e229bca27d705aa9a4ba9442e2b2cff71e51f40d2f22654c4f3b0336c0e4fa4667704b8afb1b29ee65f814bb11eac4f9bba526cd648b16de6cadb2e0cecb066d4e38c9bcc34a258172550cf28c81744163162b7601e81dbe0695cfc3368b0492e4a5477aa9f39c19286df79774dfd5b16d436c63f58a446afd0ab222e0c57e15b0aa5ddeec1e7eab992ae142f2c6abbe1eb0c1cddccca727db9d4a44c084e48f2dabdd9a236872d0ab1129a662795867399a6ed6a532bfbe6821e797a2780f327180ab8ed5152da2ab0e01d65c54dbf2ac89ea886c5f3d722af696ac821d38a3d3ce08f365b2af2b804c71908cfe5c78a3bc4286649429f02b24f34256aaecd61f49bd58c24245f20b3acf6152264d786ec28d97365491d29a1301f9c5c830eb9651f441eae7064482f9c1050957bd29e59ab8453b9f5e77cd90e8715728823f88e594f24d9cfeb7a6c749662af862903eef8b6001cbb89e112d71d4659f9269c82d1994d6ec8a0ead86548a4bc6ed34b5722859ac8200d28d52d654d14fc88cc2ca492172d2b67aa275d1643bd0e776f0a09f7454e6aee809587d884d150b40136c3888c087df3bd7b17c11ce64a1000da07eb781c04a036ba26e923360f750e8c273274d90a2472a883ffbb0c12c38239a02335fc8046d9b5ceaa1e85202dea73514361216a165e6b5446ecfe85916b4725adab3f3eafed25d5b8703291039f0c992b9c76534679c04ac8770a1d3fc99c8ee6891bfbb4a81b5d98edcef1d0542bd5943024d66f61fb4231cfd302b43a200f76583637cddc083825473bda3c25839c03a488291db562062b5908bcddd2a28a1bef6b0b911b953cf14195e510c23ba81ed296c3458e74c5765023150363b4031c80885b1cc01b8a348835771a6a4f68eff3ea3c2a1f167b61b32a3784dd22c642f0f47877bc6fe718bf42fd34cd413405dde207e80ab4bb7e29a86890b79a6f8794063f3c884ff8e762498c3c50560f560da449ad10c67937f0bdffcbe3c20359edf4d3fe185725ee75cff76818232fd4232beae504f15033ec47128be084f72dee4ef1f9ada3d37fedeffcf7cb70b74d3c283155a13b56871b6fa921e741f38607468148acd5a8fc4d6cf533d0c47add7264dcf4dd821db7a34417bb708739680a13569772680d45d0f605ce05c0b2f261f7218ab6898d9eae78db25c6ba2aece22e3559a6c98f42e51bfe6c4759bafc88a396424c2eafa87245341e4d55ce29eda289e15f4e6171914c6ac130ccf040de131d0610dbd4e621e07da04478cc35b4ee5bf1f07bcb05c15b6814bc181d72f3b087592bf0c2d19efdd57a8bafcfde3f40b5c31732359cfd01687d8fa678dea6a38efd9f48789d82355e608558d2b031fb28a2abdc9a55409f58eea5a19b56e8e2deb86d6a77e0e3211ca7ed3fe5f4323777b7a83045545be0c00060ec8aa8a7472d6c71f7fdce073414a8f8bf2c99ac8392f18d68893aae83e2a2eba63245c28a1a24cc1af0019889fac6552461705b0d8a2c945770a5743bdb5c824d222797a8b47aa33b646e2a8b88a04e437b8d5551af5ecd3d98693d56724082c68739308af2e7bf3e75bb685f03013abb869dc9b6eb90f4dbca8d65b0b90be93d394357c787b5fd98f0506e38a99dd39208a8e68cf9793f9fbaa45c039d0b7f7928da05ba3f9251118bc23c8cf77d9fed8e9475c3acb68fb3deae0c46550a083b1a47c96a72d0be4db650251a16646570884785bcc52a308d0b0de52cd69a4950d6ccd25e116af2453f72123d7ba05c40f2ee5814d4e307d65838416267f4409d150f479eeccd9618c9f6c2cf21bade48960ad8f0cf3db7f30ceeee297b75d5df1842fa51258f6422ee7f7436773e15a9eee867ef9a5b38212a2c2436fda7f33745704111452ccfac5e9dceac88698920fd145a23259f6c65c35328271982b46ece0dfecc1ade806b44f9b244b7a642a688b332cff6e83caeaa17c77d78665cc64bd43142693c41b773535662748d47c759ee465294a9fa00042f9cb219e640ef1e9f63787f8d3f2adb9545fafe528a58d6107a7791f20bb612e85fd7067c90d84b3910518afae84dff764555c943a57c25a3f08afb541cad0b58920a31be87bb7d0a4350d1e6e50704e12766f6a38d63bc7b4d417460cde5cc607935831c7fcac643dca865a9de5a9f72df20a66ea837364ef2d15d2029d4ea31d2842f4ddd01c4738c8b2b84ec2d52eeb5d0e8fb324d0c311974991a1b73699f10fc5bc7fe26a9cc3941606b3164cc520702d2b314c0ddbdc8a22b0c8da34418070314268df7a879b880b21fe87c2e1ddc7e451b0ae8d72290c0ecff7107a92d4bef6b8e4a826a0ef498ba45c786634d8f5e83ef4391fdfc4117b281ee94f1fef3f8f3c167a1b2fe48135d2d6f709507f3301b3cc6b167ff79a5ea4b896986b9c996bd9dc40ce91b90d5fc99b2bcc34b672467fa84832a359cb05fde12ee472cb262b25861f692efab8afff3e879cfefcf1e3bbeaf24a27182c022e59ac11748421b2e3de3107a06d3d90038a3cecc1a8f04631457c3fc4e11eaa1fdb28524778bbf49710984c442102afe081a86de7c22e85d0c921841c78b627ad64c6516afc41bc80a991d21b58a1de32244f84a1e6f19d8e9304980cded26093dedb633245613f4074fad0687f04cd11f46bf2db7576772fc85136fa9a134e79eda98550329551ac2e45f6d173b0090a1b82a0997b60304713501088d353597a443668b8ef0d627ee7e71692d0382b1be6cbc1792739ed8b02b67f791f02343196342efd08b25ae3e0d5982cef0a31d8de993adfc96744ceb2cc09840f7ab32b1c128b10dbd263fdf1ceabc5ceea45f45d88e0b4a1067b1bd95518450076c058f9a68fe8b4214afb75f89b7b5bb80902ce0c03fb0c896f3a91296726cab235403c6319ef30737cff21616cc3a9b343afdf3eb3fe5ff9ccf72b020d3e5fbf7da6febc8ef92a1f5fc52d42e1d635e7b587f5edfd3cec89807ebe727c127fff3b11017194f53f7fbe2756cf07bbb2d35c6ad96509b8ba63d89b3bdb00011374b201cf50b25127c8bf9b1b6202bd79666e421302e7517e0ec279f32ac77a3acf3d4d8f2f66dd8dacc4c8e222812f783f2290807ef9af31593bae21500db60070101f1026296ee1c69fb0c5b70f239e831c0521392b59d20c310ec51122134928833e2c243da25bc3fe2bd306577409e94c804df62ea00b49b284c70bc7c8cf31c5279ee4ce4f7f3a2fd6500cb49cff2cf8fa164165078e51203fb6aa2a0c74804cc211eeaef9ee4de5f9f79459c2dd6f7723eb992108bfa1598f03ef465886d73f58eed8fcbcd3331ccb8ddad2067242125a8e12d662f8d5772c7107578e1e8ad8bebd4dc3f75e0b91ca649f5d2593d71477b685ae2e38b041a1f4179d5d0799be0aa59f9db168057e7371d3b0ddcf081eaf5736eca7f2b2b78958dc2e49e1aee476ab525e772bfca49963a2d16f3e68a68fb07c7f7a922932d2dbb9059673c1738135128fa70c9e9d5762fa042ec843bdc82b45fa239f3ef374570437b9e74027440f0cc0221c18783da1c80c9c8435de31151886d8b3438fbb08828303c5b3526cbf3f31257d8c718fcd47f4aa2b2237315730748caaa52c45518ce3bd4bf017d5fb7d0b20fa025d041ec7e887da79ddb3ff7c9f09f88fd514849269e3e0b6d72b37bc6996dc09d751e67bd53b80a37eccec400b03052a7beb84543d2713163a6ca533633261f8db1de085e4f90494a0c0ed59ef098ac66ca4bf3ddef3cb9cbb989e235c92828be897cfd9aa0b7e02fd23bcca212b2a3986e677f586b913b69c94e56d25213caea43721776bf50f0385444c32bda2586cd54f61e4825f87e595658386ae5acd3ff40a1b004ac5c19ed9e784e1db1f7badcb1d7a4b04b50104355e19ded8c8392da46e6f879474e554698fd80e00a3920d9c932ce6e8356c52dc183b15cc0e65ef9ce573757cff970d884ecd8efd85a31fee39fae29ead1ad67ef85582c9d13699d4138945eb303905dc3384a0e85bdeab19678537e98568234f4c25021070d914c9249a8f5b44d13e2d5fd8075935f73da1062094b35d9aa452543b8c6e907f00e1d5bcb5f080b83171dfde15432ec9bf8f58d9286e332166461a10c499532b13325b43ae5ecbd1cd73ecbf8fcdcfe95fc204996fa7a71f611e9e11128cb8b3e0f0839587bc1273dc7c945e2fa0ef499946e9b18373a55961fb213be2e5a319b2f0571461d905fd55af08c4fd2666a12458b2973c114f257013d6a07609aa4a652ad9a8cea0d6655325e22b636a6656c198314e9489d80b2acffaec8392549fd34ba25b22f007949673f23434dba98178063147e990bbc28512e2b77fec74b4f6eb101c7d407d215b317139684697835600de82776187ea01072fc87ce1ceaa24d57814d2a566f260820090fde1334217478cd4b62a650b7566fffb650a3ce87ec0650d73c2cac41316394be7feeca90ee76c2667f15ead7466df1e20632d55087445c819302b84c0fda6ad2ff04dca8c7e07811609e01f71c4c38f32b8896f87e8e747a9b7df666542d5f07a8c8f96b12570513c10dad30a38da347a0e8ef02f2b658dada9549b952caa08f668ad947a1da4795618ac664a3cbe990599666d8b9d0623721ab8ec33d89459e8db655d92041e8b5829af80807b42ce83b043d3d703afa1f4e4415c4e656e4ff3f219ee32f2fe9602ecc6eccd2ce3f95aa0f9c94a9e00c07a44c5f27ae6a6e3d31391e48b8d00080c173c7186e5ac99b9e904fc045fccf113373c71c513f9cc4df786d492e1eaee134430d3c281824db80720b1bb36a1501bfeccb0d0038648e747abae881975dbcb73817a200fe9a56c5d6415186899d88db5ac21d410f4e68cac07f2182851467d4bc1752ef9aafebf47ff67cf02619df7933f9dbe424a3b25564ae38e70c45a9acacf4080c1f976a78858ef71083801277038e5619fb8c48462d7598d390c8ed305f4cf6b703d7c2a24bcb0696b53fcbfea3ff0df2ec131613084e14312968ac0979ce50146e4b55c614074652985a82457d60746ac72855375165d2b41c919ac9aac18726f4d40812ee50a6a055d594ae136e5b26b25983d838846e1709eecf2c0b6d61591724585225e7787ecb8638cfb8237b1c3753d80484475579d990498886fe61883d233ad15cf197fcefca0ac81de937ea6fb030674c180fef80ef5b6d52be522caee6ec0de11b8f178e916ce71cae8100bb98864d24b02e4f2ce1941dcd8cddb47a0b396317e1eb97ac55a56f7e9f8bbc27da5b6e3225fadb8e433aea288fff1a0a8ee038a7db1f416c43f37967bc6c64ab6d495a0f39d830222c609a181643b20682395874d3ab9a3659db3fedbadcb4e3a2bc42698992d29ce3c4ceb885edfac895658f1cea93cdcdf2ebc5923e1ccd4a5faf32931255aa266287d319c43eda70c6d92f00f74960af281978896f7766061f2af760fc0a93e375037e993a72158957b77477f324d86d39487dfc708da31439eb919242ede38dc5733eb7e1e0b04aba557060af346560e2c1bd2e8ab071387edd209a212be47cced2bd1a5137efcfcb050a8976b9b9cd2adec999c4be13e990bb54302be672cad873388df91fe2dbac8ed6e1ae28138b403d33547a84ef2e7484b342f6276fce3889c9733656ff71647263947243e81d0e7cd393d6aa146f5c1b06799b65dfd31c7f48c688d207bba29aa6f72d719138141fd7ea72dc71cc7ad6501460f36f7b6634e5aa29ca2b8f570378e3977d8fcb5433a16a3cd1f3ad4af73172d3a860046d5d35a69290a9f1e9d8e9c9d793e325dac5224c056e67b08f1ab2013879cf72f865d946266467ac2071667edaabc8ca12ebb2558fbef1a78c2dba80585a1d8e284222285234d6150e44fc56f20277c998ba5631215e75e24bb0a791bba4724a62c2f522b5b31280683b72aa03b42d11fd003ce9ccc52176954d4ae506f2bb6f3d44cc03b6dd1e52b73595738373bbffade06f88cd956451bc2c6904c1d6af0e73735428e92a037cd337d549337a56df0a6a49527bc8b83148b1ee901ee7be6ab7b1966cff10db03f2c308bc859e9228278c416e55feea999c33767b89936d50f4eff78cfad3acb2c3bdd9c989d7226559a7eeb6c9193dbdd9c69a0b4c92e727e54df883b0759e32531fe4d1e06b5c58e4cf831370e623064709e20d2d2852ade8d6471507f1a8bc351b0bbb3c2fc3e8152ce7e8e4078d1f78b9e9e42c674a37cefe7dc852db31785b0e113aa01a0964df62ec1319c4efcac2b9c372ee8f07ddfd3c18ec8a5ea6e7e8eca454658af0ef6e76e22f9b3cd8696bb6c73a20e7dac5af14133aba06612b16ae253d3725f782779c427b380763a312da9edefe4d3e10f56d7e880d541b04e6e0d85182dbb2024f9fb5b5a26c4ad95aaff0d4f3bca8d3c9fb24ced72ca30b5bfda81841c7c90bc713f939d444769f357f3e10ae7ab84a5e915325b4f7d31e27db201bbc2f9fa6fca53ee42d1feb1c5cf45c88a5866a67911cc2dbd08fb2e74cefcfd2dbd087baa92519494d47896b75356fcbddbfa3ccddf8f859ee81e41371fff6e3e1b46a45baa7f73ee0231b839848072fa41d7f587038fffa06e3f28baa6c50d42ed9b514a761b90d808bb8df692899116dbcf7b760dd0bf8aca9c07c27dd57b3f6418cb418c47bee889eb9e6dac784298271ad9270ed9271ab4218226f9ef14da07afbb33a4106a5f47318c0506953bb24f297fe418317e476eaf4cfcacf3745a7ee72f7a564a5ca5e0f683fbe859a98de03886fdeedfc8adaa09b7f7ff14017056ea3539daf92e53e8886dd39693c046ef596e711294e7159bf42c56d9276a27570834cd21e47ec31ba68a60b22e651728a0557935aed6968fe4f76c09440173bcd8cca092d3d3d8304e2b7bcde8e7c6eaac05f612b9575ecae4ee6955d8a35d67fa96279adc212832a75599a5777d715191442945323b4ce1052cc8ca057afc8c7d75c73776febbc2ae01f3a9acf28cbbf06b262c85c739f94c786d8c37674d923b1ecc6a96410adba81a7866f7c718288e97dabad994b29a0da7397163856c866f0f2f1c5ab48b9ca9ccf72296762b6b1795f194c1900c703fcb4d507a5f6ce8357ae81ead6b7bc79041a0b3553a5deab9c2c3c7d505ea2a769112df13ce079e9923ed859e0a857ae68f9ed40b6cda674756c40994482dec9260464072e8c698a9d18dfb0584ab9a2344cec1405a710b27efaf7bf619c18f7033eafcc95b026632f0bd9498e0f2aa2b64b645b29fc766e17070809d393c29deeaf50e319b3360bd1a823a961210a85ea9cf1699a4e1cc86f06b2e10543a591f73524f22c1b7e0e113754fe104a9daa7c8a8f584c8a7c336b1a375bd234dd933aa0e8f0f5b1eaf9e8623be1b996dfd3d8366cc1af70ad2448fb52c6369d5a428c98aba6cc969975799bca8eb962137e9d11b75b5947d2b14ef823b1eba06465d9d103339f452b3f14a9a4cdbc4ea1c21a47a7872b3cd8e443e87416a465f1943e6736a859fc9257914864dd43915881c6ba0a055c8786a34135ac4c0d1e8d196a0282c9782515ac00fe68a816bc900961e39986c16e92e2e7220c9f5fdf59cbaf85608fc36190f40b2f60a28cd178111d1291f1cde98b15e911ece7af4fd23aaa8fa69e74dfa122ffab5f338db79fcc6fce9fc579dd7b39dfba0c04f6902157b48bb2528b9deba9d1c8e96a890597958a5f4a6513366f62fd20e1b38fefee198487c497d7e2366be713e2715dd0a85781992b07f04a5180e8895d081af667b710eca341972003535aa93c2ee36e5127fa0aed4709476d3c48d1b97f385d4eacf901a4ec9b15eb59d0eea6d79c98e8426b3473c3f8e3888fe18fd7cd507da4d845bc58b68e1fc102f19e985b951a88698c92b82cc05023fc7c4ee78dbbfeb4f4574ef706c8dc5cc6dc794bcdd6d02f4e6468497ca867842bce173548ba99723bc7eeab79c41ac06b64de2b85c466c488af0a177bc0b7aeb7035ffee31e684dbf59585d4267c0131325fca30f974f7cc253ef545e29d2bda1faaf59139e3fe6cc77aac59528c8c28de674c7ccbdb7034f159d3e4862434beb32d02546a3f222911953f6a52e87f72285ff3aa4f6288d4bf1109219e1088c6bc72969ee58acf0b9533e84d9b2c225e2ec653456e893cbb4189c066ca521b10cdd185bce3eaa3c471fc06cff2f84c845e56181641371e57d17826b9354afef5165f2932ecf222530b45480b1854f324ae2ee4ec117d25e95075ca51efe7dcf41d88e81a54b6fc1d452c6fb741588fcf058e903f3432685c04a2ab6e299a95e8d6519cb870d1a7e1e8b1a38d238b40650b5deb53d4dbf03656e494235961d5c8e4e52063e7a24e324f47b9a0c4f4c48248458a9b7ad5c4c86e9ff8a05b5729d4561ef1f3f384a26c5d93cb7e559e1508a7681720619d215f1d696edd88eb2c1f645a68b9a9fb27183ec63ee9ee20b00f2f57f5ad008e98f85620d4499dafe0f97dec8b3a0c3bc1093158d1a3166c2e8a2a4277fa94a0d940e9520c64c0901d1cc20222dbdb50ade02d5cfc2b251a8c78d53818af8d5e5b8e0d870ee53ca4ab42427f6f47ca90f83c5ce17ae591f64e74dd3dd87865983b48ab406e2472b8a96805190245860f87bb4a1211850d0f72500306f97d9a65496be97805da482db102e91ce6fd6fcf13b653034e5f2e8e46fd7445d34609e8b9e3cef5e22d1c91fba4df831b2520e56d623c4f2717a90c89d91a1863532031dde40c91bf014cdad3ccaf86bd920cb641b9161f34610d6425dc8023b24758fd4e46f8840159bcaacec5b18662dbd2d27d2b923839942becbe2feee7b8bbe220d8e9fa7e9e0a344975a7c9493f1b36006088ebd6426ee0cb4651ac0c4ecbf27b418f8170df75dbbc5a6b923fb58b5ad774c0667acb16d7f1596ecdeea7cc1e27c96f1e2cce0c707246587887eca76d7867e3bb33b3bf3b33fbcc9981228f0a915f383588d71ad5ff74662eaab2486211d47bccbef8fdd588d0232d43c0971073956c5842271992e5ea7e5bb48b0e1211378e3511ced3076a22e3d2edc8299e4aa88ffa8f374d84ffae5f14491ccd0b6f6b7cf051de32d9178332a3fe5c082172a9088b6aa6c49acb843ffd768a628e9385f2fbc9e68181fe4de524f3bc7172578311da15334f6fb4a9572144773772d17f74442ed856c26d52e52d710e68cb350829437d25c73dbdec0a312e025da3ca7c07d5c85dc6353982147c9ad1f02edb6e08b4a8f9eb286f34caebf7516e8ed2daa140d350f38afabf1ae5016525670c6ca9473914de499d59d26c5906be084a85d7fcad1ff5fc87ee571409ec146583440aef1572c8ea98d6dcf9b24211b5c77ac9b76def671d9d9ed8b46f7206e8d004d4634211d889b8a0f50d57acdb8fe679def1414cc38edac8275ccb12792d8eed67a213459b8e720947d96da51eee5ece0614fbfcfe38ab1fc7b93b3d235081e4b0473e405c2770677e78fa5c76ada552791f911515defae0dbbef00ff254c82ab547faa516f292bddc3d170cb227a970b7bb9b4baa6bb24740ee52f236f3375b03a747597c5bd6991073a4324d30d4839b57a720d36da180f25e6b488b2b55be7b6ba940d95773ba1bce54d6a2813f193bc92deb43100aaba0e5eb4333837167f9a287a8ba79d3c4a4a4e3ea52c865471076361de947c1d177e4f7eb6fce2ca338423d2db9be16f9305ccba03077d62716266ff8582e245ed8264e3c64bdcf5495c37dcff8775467a4ab02fefdccc0c72c408dbcca836592f09f6b786c5037c1875a126df0789b7cf1dab7020ad074c58320bd55746bb0887ac51d63d8a074fdaec4ca45cc38b1269fb288973b1db2c34cb1635a31dc34dd9d71c884c25ee98dee43f138e0a9b001baec5511ecf68a1a273d069ca251bf6fe0795eb7934baf39feba7cf6eba66cdc9fedd28b6f734e0058642e7e99ac80557ad1fd3a8f290478c95ea32a9313aefcfd96485908aaf53844784b87fca5896469a4d13e37af9c0f0c1c8e06c50aabd8e6e04e0806efa42acc6996292e45d551560445c9df1fbedfcec3ec30aa9a8fd69276897ea803dc1503942f5210899eee3e84dcd139c909077a7106fa833f1a2703d7c109886a258f5399a9f4d0cb90133b03ed6167aabfda194c632fb9ceb05423b2218e60d881c94dff0fd9ba5439626cf5c464a525a0beb7e11d5641008e7721c55c7d8070a63b74c6c4a4ea13a0ac84e1e50f0be876707d2b6188201db120116866c0e000708f087fbfde600be6d00823eb1c5a33d29b31270947a18d66b675f81ac0d31a67225a6bd964318aad7fa8d2712112e013941b637b57785fd38f32a0d0832353bafa8d428b0ef2478ceb34d32241267f06c88db9372b1074ca4c6e8b2c5b14558a8b91339890a17187d303fa8b2a05f684e88d835277758af7f4622e33a5e7066ff1bf28555b53ca477c51e935257e392a581096513e8c42743eb604e8600f98f893dfc15e93d1a577c54297e4e159cbeaceccbe2d7e18247efb766c760e613ff2f7f2b6c067719ea0b171739b574be9253505726d5144e7dd1cdeeb17c866134424e7ba5c985e2f529f53dca8501f9c1f57766a52c4ebc052c2f9401da60f6b20d4739929e4f5cc96ec1985999199df1169364f63865d4942582b793d1da2b5145e64231f85ed2ac52bcde39b1e088adb9871bc6bb53453b1e3f38fdd2e95105b759c666114eb64c601a25fd3e5b9cb78015e936804ce09e06d469faf9ebf7dd4e48fefdee1931227c7eee78a1739f107c1d9bbb5322bee921db025a664791a40ab62d1252810508db3929530bbfddd42119fd9e2c4a0648cf86e163abe8d92448dedd58c838e87d6bdf672f59c99b4da3374565fb827af08018e24b72736500c7261b2f87ac7b39b2a889183bf27c951de6c4b890a614d19845600206b19abeabc77ad81a83847b5a2ad5d752e723a04e9ea192f2993aebcfa97a4abe40cdd641a3de1c4f6bea0fed5fcfdb2c67f9ebd11a89f2fdc4d5bcfd7f703a2e7a8460725b66379dfe26c03c7f0465707008498e2e1094ca3195076e125f4bd26a9ca5957f436c022cb41fc1b77d8af923c135c9afc0c433b74c5e0c2b83b8c2d8ddd5a44180e431717102fe3eaab8903a38dab3db02394d8aac3f0fa9160de19f9704a076664e8f5d9a933089b01aea545ea3619d17bcf31fc9c43df3dc444fb5ff75c9aed00285afaa98aea601bd966d04f29f756d3f2d643936cd0294cb1231aefc0d80f39e0912cd631d4aa1d65677d4c8f491c8edbae17ff9b445bf503224cc45bc63d0c2d83f3cfd0596bfc3bee6588adaacac2945520adcfc030657624c5d972c089df84597a8d713c09a6a89ab43d5a0cb121ba454edec9f43abe28da8f4f1ec52a3db0af0f64b16d184257b8aac90fc3806a7af0a9ca7ab6f3fbfb81f037eaf75bbe08b9d81f090c237ad9f8c0aee144e5f0856aaa0a0bb3a02bd53d97138f59ccbe21822d4752fb52966d4a18adc22ad43ea27414e4866c1f5c385f78d98ef4e4168acc4df48721a461a4b5fe668b6403db99d106527a4f7a8284dac1f968046e17f8a6a25be52703e196ed2bdbe369d593b42511707ec17322b978420ce9047cd671de8f18dda47c644a33494f519764c38effaf8f92db47930c983655fe1d934a4f9461f570e00a658b53f266835f24bc1a2721200054f815885b2b07f33aa6603b2abd8370e00cc86dfee791cbe152582d6664c485e24c34dedf54388575042a1aa19e4a37aeebed0bf56cf4029a821e083cb482aed17631a5ac13240da01258a196108163a3d7aa7ece7cf6d4fb6a1c08dbf773852f0632f9cc2e303529d23ebbb4c90b7e36e10799c572c9d2c4a0b1575607f58cb617a51f13c20676bfbc94e984e4e51c2d837a81b397c0a7c6bc39fc26b4104ee1c37b456ff9697585bf62184da2caade06e2b128141d7977c6a75a03dea57c03d787b3a1b6cab697b21a7479a12ecbe06cf0359b262376e61f77051bcec4c182fd10e0fa2665650e50d4e85a8c5009b150f1cddb22aede85dbbecbbca3b85109271d4ca18640a1432a39c6519f3fafdff5c5fe1db7597abf9fd68fe4b0707f9973d13a68efa8ab66c815142759a405e23ee0abf000135afa526204f624a926907c06d3ef06ab4d41292efe8e905270189b154ac6ea0af3f464845e11b76e6ffbaf361dff245e795cc3d3e50ad49cdf583cc5bf42287743c3b845500a84b228dc00322a3119727b37c31977d1a718bc6fb64a5354931de368d975899dfc98cb78df10e3237fe30de30333accc730f391a374bcce3f196f4038ee13cb17f6072491177e613a7295c423d02353c484c009de4de23504a219923f1589ff0132b982fe2fbd5254b0410a6c1233f69785c41487be3a5a88092b44323a8474135614509e11bd1164078c05f4d17593bb5ebea36bce104fba7ed15d0fd0f50b753de0ae9b4a2bb5142eb460a311178f49a3ee9cba0908cd2079156409995b974c96ec2426b1c7e138240412f14564c8769d25d15dd1d01fd077981d236f987eec580afef9c3c410d18f25102b7eb9c350f7f841a1c3e73612a6b906d726134b46717e4f75acc58f53e93c360eccbe93722c06dacbe4730b2f264c5a279608de4698712f3629375b901f30f7354a7502ce6951462a839a3285e271781cf2cdd95b2f5364f2d63116cf447bcf2971c57debf2570f4d80dd3f0fe4f4843b5330c9c2773b9324a38e7a4c13ae52b8b1dc189c7fce8fe0d0f0d29461433433739906c4539906de6acd444f46119659f8e68ee05e0f5a1bf686d0375d6864ee4912de98685b9c12eb7c515ef589423a6ce75c81f31889f6b5873f4f9b18ec815a35a7ddd5446ad9af9348e0de684c5e21a729eb73b6fdce791b6992e47c90603639ccd94fb0c71f36d4cf57de8a7a81e9dc34c1fe47873998c219122ca090a7728ec8a5b7cc6384ab0c7da38fb78839bdc5bcd613eaa27eefe7fbeb551960f8247abe34094ca0c5a099ab837e87779039acc5dfae9a72a61e2d00b0de69019c8d5c529918f1f8df5a860bd31dfaa8eb29590bbd5d66383d17787dd710443f79325ed0b2485153ce4d7182f6bfc94674ea72c1b6d0df920f9d953afd39bbd099296cced102a3f6a9328c9ce397a627ce2f6b12fc614d867fb9268513dc8890e5369c32b5041dfb1f5e16dad6f422d74a3157b1262a46cee7906c635bf902216f915dc412c6ba962f591248b54a548793fc7ecb84749bb2e2d3d7125b1b71a22889a7c4519a84a1e750e8686b291151e795e5fac45c811064dee06fe883c395293647152517f63007230a8bb256d682a63d5c91c43a594facb514eeed3bef78d61aead269215a7943e449050681c315aacfa8436b7928b117fb8b4b505115127a2276080faf60733fd12ffd544c3fa73ff753b73b7a072fd1cf9a36aeab55d44c3fb512efeacb5d3fb7bbf1d81dad0d1514c3131ed04f2fdb4fa3c4769ddb5d3fa7bbf1a88e4f41093c9ed32fe3c999f114ff623caa135801e13ff684f8bca09b61b69b2954f449f9ae97f86e34b2135a3ddab3e4f7bda19b6eb69b7999a59fea5d3f97bbd1c84ed71a8b31e3fa56171c8ac89529b6b24a6812ef91ac2d28c2af0b5cb485115642d13e201ab53ace8848622dafb48981f952b23b2964c9b808044d76ac71648e4962a810d61ed789084fac1debfdc91bf66ca0df80c0592254872fd6b683cc534676e30712ea7106510af5a6490461af56f8d98ae84059ded19333dbc82e702898a70fbfb5720d62601a9b2c333486f77b4c26bf49e39d716d2176934fd3cdb327ebd1ca66226dee010bd4c337bc02a7f503aec021b49a5e6a3662d481f29f500792211ba1efcc67a48ae807269dab07007724a033773a7f15acaa5c3546108684e1248fa5342d9a801572036b2844b086eb92c2a53646edd182fdcd432805a731b0d7df139f377c5b952410c4c90c6f0716b9cf10f27a57c54ce8ec651ab827cc31c364c17a671e3e240f171487731fb30faf64511569c14caa0701f7758538cba3af3fe6bd40f3ce751c2a640571fb69046bf52d513ad48341fe7745bf7b7da3722b5dc6bb2f96f5217ee9c776f236d7a11e007c24bc3ad9d1d5c33c8740d7056abf3c96ca08102b6b06654dd4d34ba60f3362d896295c774deed7921434e2e20b22b7c74215ed4cfdfa33bb295da15e2e75697c961ee2d6d9f5ee6fa68cf53035d5ccf5ff677a5306918af4c97818586729bc80fdc7c727cb13ed376ba784274e4f996b4f7a6bdf5f532fb4d1dc680c8bd88475a6878db4a64a7873550b32ad2975c269a55f714581cedb8eb54c2e25a56299efd21dd45de41bbeb8c8e7f34ed22cba0b993f2beb3ec9a726a71d2bad123765dc39b2c9b1e544ab5cb45c0b862958ee29048c0428af45d6cb19df5aef29f9fc8bae0ecc03db3d4e3da58388aa8c18a04924dd7d5259fca40499c113a623f41acb553d1d37d07c4abfa3f95c517c9db5d4e213d4af12ae6a31e7c368a644942e892c219421a30985e7c08f1d226e374a2c4150461b72be2185f1c41853650446a823c8c3a44aa63cf5c1e1f0ff8176d915cecb16f2d607c18d4f25b366c270244a32dc8ec130ebb01c32348f1f6beaf5e0c1d3ca216800138a650a1fa437e0c200da902ce812ceaa7a5e6702bc2f0bc6a22de01da377262b9fc8ea14e9dcfefdc83c1a59fb7e6480208a650a3a3410ce130d641ea4537dbb9bea1b9bb6ab4c57958154fcf67e0e3c258b1511f5a7fb9737f8e5294612d9d07f01f1f926c39ba52ba8bb1df35d7acf3d242bec0977e3247cf73f3037508969efd95262d4de48a61d14057b0f515595bfcfbe08a85b7592c21a0815fcd62a1445bbce95ed462c327172e75caaa799b246a2d412900d2a9a029e5afd5fc8b3271c87204904c544b41d136895a2b30fd23a7d38fa3d50647fa51078656f99c0971c2ba4f4eb9150eb341b431198ab23c88e443b6574e893b67fac0013e54405da3d46b43cfcb0f15750f5b17bab2103f808eab9dd294de2c555366bc946501bc4ede66a199379b75ae3f49542fae85e52c50846486078c14fca4dd8d8315fdeef94b5d3a2d0e19776a224e3ef977352b891632ef310553fca5cd84b51a3580ab193f9aacc18dc96a8a40eefd7023591c225053419e3dff8d230b5323d334bb4697630f50f9f009798a76de1b30f2658b6b4424ff1b717b926b1afb74416d7d0d187784381094e9bc436e4da057cd711eaebf4667962613f98fef4bc1cf5871dee276a6d3f83f0476f38ffe681f50e3545166f962f1636ede18036e8671d463210861d0dca7de0f2229e7034b3f11e2308ecc4519d27bd873f4965a00a23aaadac407c20d387227f3ac88f2cde4fbbd893bb5b45ea50231ada3ed688e0659facde7f91d8490f7b47808679a269b73ccdf5947a58c853e33bb7decb632393928b0c463bd1375ac52acb38539bc03629c00a1412882503aa96cd965be0d30d3c6b4c9a6352192bb24dd6abea2808128e504f533b0dea7d7638fb9238f4422e643933d8310f3661d194f5ccc879fe8c3ced77e5f22b1c167254944fe909e5d568d8f6328913d063519ae21166fe866caa85970778b8aad482935fb802e601a133fb2e2b1118412828a2ce11007762844946e5d6c28eade5a1f2cb4296ea24a51e91d75dc7224da5abf746156c0f0085fada20a9308ab3546d644b5984a8adb26718382ba970a029a4f3c1e2ca13a8f1e2114ee747564bf33413f3a785c3ba071e3a70285021d4bb9f90be078cf45d9457f0ac1ed7f432a8831fe7310c88be66f5a6875a97d2312b5d52f657f2c6d777add42ab79b681dde3f986fe4c236ce1b57ceb794089fafbc15870c8cb8e5d80fc678319aa531622189f60d5f3db442e1cd142ab77b05f21253708bfb55c4b5cb084ed12eb0884b0f3bb9d653517c58d07eb6bb101b3bb0de7822a4e57e44f1e589878c6d180635753b3e109ae4e1a1ade85724abf72fa2b8a889e589e8e14511c87952b285e491e74ce65b813d0cc56784a06ad97b10a986937da2fc9c15b5916f5f78ca3ca89a1297fdca13ad893e5554db90f3dbaa5ce46788f031aea98bdcc7363cef9e66543508cc73b9a6fc90ee46de0d3dee6706b2276db0077b6b37ee7120946b6ea98cfab1a8825fcfb11343feede7289044ade4c5d4c884612984c954b86712ef07915cb7005636e4ccd9d0602053724850945ac0c8d98cbebf59b0f9a039ce26a04e117a3ad2028811547be72ac072540402e03638536f6f505fb46c7393c878a379a842fa0a50354cbd310c06a7a9995353978d77ce037745104b865b2348b58d019c200b95295272df81f01aefd64004b16aaef8e543a13acb050b6dadd42d349f60f64ff73b712cc2d7f587d53546cab93c6570ce6bc855af778991aee4b9670d4445b2d96f81f40d955971050b485788710c30c3fe1698f980c8647cac572a2e4801852ec20ac3996785c279b79470103eb5645c35083f53a0f272b55ac5a1d39ae873993b2dc6bd72c4152bdcab870c7ac2716c36a1272eea6b3aa05921a7a8ffba98814911b872a7c6e018962bfc37e2e9651a446ffe443ab36e7556b0e2a1f4fd27f6b6c9aa256561f743245c67b204be15fce24251e49feb35b806d106f57ca876d241e266a805a091508f2b0842e1d926303c439639d9405ff6936de26c0c3c55782586a8fa57547ce33404ba1c0a67ac37e3812ca8e65d63a1debebdcbd4be29c62abdec2c240876f28a259dfe5139cebec2bbc93dbd7a6278c496421a278847ea6d31aec5b3955677617a560bcc664ca71ab74844819bfb82c0ac70ce50f08d0eed9b5eba4753ecfd444a28736c72c30809c29b722c4e3ce7f346450e810beb33c831390a20b8ebfd7c44d9fa1215744bf5e9ada914947c90cfa123065619f0d3b501ac61f7f5e33e4f1cb1030d61f6607d074f0f0daa9afa119cbfcc995aedb954d788ff11bcfa4aaef1cc28860d9601d6f38c009de354853d74e2e8d94aa0f4c560dfcb5ea46434356bed07e4ce4214f1c2259fa8cc01e0b8de606adf407e3dceacbe7770c6a42b2f4df9bb9562cb4750b341dff724d68ba37c20cfb75d0dc1ff0226ff30b4452e28ee81428efdab9e49e725a570aed6bc1d445e2cc90ff5b9d2cc6cde02f4fb54a14a856a9aa49514febe46a86c62ccc12054c1424bb433ae51ce152dfcdac81a88592bb22728195326fc6c7593676c5b7f171a56ebf38120ad7db4da66631cce58b3dea5985d0cf5011bd5fd415969beef09d5ca5e15034d433eb21fefac58cf9ccb0222b3a30e5503814578897292373e9757da149fb77ebaec2a92a541f62aadbbc3e030b4bbc590e12bb2db459525009d0637f573db14e5114244ccccbc668aa927293e5d80d2f8e51da933797bd96003fe0991977b2acf7490460e7936dc412b20e7777decd81f30c264f733738dbddcfbe5598626f4a807a417bf404b6011865d84860665ab4d14e50a3dfadbc1cf3698b98b2cc22b1f6cd92e10e15fff4a62aeee04e6d31a4373d5f1afbbd44285b39186e76506ed4472cdb69906945b22537b83ad850c72ec7c26b2bfd15f872c5db66099f2da21bd0ea2610f2ad3421660e7bfcd58d2e460d26b472f6c9489d7afb22c6a4d95984a7689d76a2cf2407e2dfe712c3ec9480f3ef6797bfe94e120fd1fed3de1bc53cb78f81a658cd6a25bc921d4d8320152c07df29ab02c98cbeb57ae3950d4c49750e15fbf99a912442f97031984b7249ad4339da88554df2fd4b93a607269262bb1bc7bf7596de4522fcd413d4450728a1cc85a3873ecb5a29a4821244957f81f28f064f9227887dc6179a2fbc2e918ae083a2aa139af8c561708eff3e91b3e948a6c7ae367199f520ad94c980cd7666d13f4b7570959cd4c5a1c6c76b8d5d1a2068ff12e6dc18846a3261ae408ce2785852b73214580c7f4a69dbbdb4e55f1a4ea9587ca058d189c62f481531442615fa3135add31dcb08b0e08fc966e4d3af89e3ac75aed5009bc0fe2520d8154bea71871f8b2d8fc31d23aebc75392afe83cab248fb1fb524f9317fd7efc98dc095f2a8fd07247a2f0f0ac8f30987e4cc0d682a154bd5c1ebbb69ad7ccdff92212a079bfdb22e1613a05de3bea8cd2177de529fd463d32d26a08521fe6092ece7d2834c9b9f21c233873f9cc580a5de1bc4220eb314471c48a2650ac06d1042e2d2db2fb276986b86eb0a44bb60af5469fd5d6acee6189d18d3678728be3b669e881cc1ecbb230b52dd7d4410243a0d8b5816b5688d21c349f74299ebc854314ae08404e54f4a61ff433aad8e919e4c8ca941e4a2b561d98f46c251973757fb52626a99c83503247b8d1a3a09ee71d032c4732455ad3e97bd7b312775d9349fd218e670aafe0bc5582b0e2a0815afb2fdebaed00b98cde6ab283129ffba3569b38bd19c908c174c11fb104759b170c44939f69a5cfff0bd55c33ed0f1cbe9d9613a25aa162254d0bbdefba42f51bbc0f433def7aebf5fa5599cecddcd0561a05a238a057008ca78e543bcabf2146aede331c2167e64e091799700b396fc21fcf01720c914649079087e05b8002c02acbddeb6b2689274172c1dfae4d156c5cc221055a61375fc3324c4922759f046a54da8cef8ca84a2b14a7368d64ee11066fa2bedfd8657ebf460a6b14336ccf16e3eee6a758a3e95ca5b110d48a935555df342d2eee97c7d3d3d6152dad3704adfd0ca23023a93c5869a954bc329c9b32c90b3dfdc146bd1ab381df21cf1e1d44d56aa7674a75c844c790d70cc67ea21c057726cf1705ac080a545dda494b37925f994398635fdf2ff89953b0e1de3124ede1847a4d1bb9c406eb5d0a0c16ab8450b51be30a916ea322a9a509471cd33e7ac28ba44afd3e17bcfaeb2fde7c4692c4056f5efcfee6c60d9d5e726c91ba7ff3598f7e005904a193e186c8e9e0d8410a4ecca88903b62278d6449d3afd68960a0f3e6acdff9edb4076e8190730d58a2a81fee0a07859e784c8c62ff79a7c2ff7cbbd3cdf9b96eeeee9f1f5237928ab6fe39bcb33d8ca2604dec89402537acd586523fdea1daa586d0d84aaaa3c23b33400021b3459afe56743ce060d08347a0aeb45636a43607184fa6af245f3c08d8c87dd4d5ddd5d3e11dc5c8f6277b470d6e792ad0c6e96c5c58c12ac8dae183030e916859588ae7814c7fe8068f6497dce93cbffb611f0688cfbea60231886aaf7503979084726669d9cda5f89999de30508c48dcbf13200ad2be68f4bd9a45db1786cede88fe52351b7858cb15b4c80912b168f0c415a5162faf882184d7db76afc3453e82381a584ffbcf54c9694df1f5a439193adb4c0e66c6e03dc4bcb116c89f5f0042d429fdf7e17d8844bbdf2ccb63225c5cc65fd1dae10ee8e6f5bae68ca8b6c2ef556e108c2a92cac38fd34054f21317eec73389c67322e92b28141df1a8887d034235af0c4f1fbbe70fd1082a496c29272d18e81d0c8d1639fac61b44cd3ae1850225547cc43049cda5612a3e62c24a93e28cd30a6151e3d2075eb44c25eaff1947969c4d1212337ed5e0cf8da0355095194ce46a593ed8e96d38f36af4648e1acae68aacec0fa14735867cf944f648cc28fc9a7575524bb962f7298cf09c96cddd54ca58282570307182fe604eef3b9c74e6fca158cd93dd3c0d7dc3d9bc88ac45570ae03b31f129bd4065bbb4bbaacf3222c532e4f2d24e5d9792e2474720dc23ee525e047afcf9627c64fd801f49211d282ca1838c345cf214900ed722d8770862250900a63352169135ea0cb45db199307a113bc375f4e2a3767ad40775c67d5640d5be184f0a32f0ad5cf8b8606cd34a36c91e54e515cd1f821dda573c9a51da027d16b9d321c809f4dce24c9cd11f085449f20593511402e1920957a8cd02a588210f349199ceae0c20804a09709c2f2c788d9460fe3095fd35a388d28a967f9d994e6f83a3779c01af7d634c375f9b8a7cc02642b84ad64f63de1c6b2848d41afa2000f5f146d6488931df2d8820d1c218a6bb99389a2ae1c3e5a7c7ec82ee65d54eaef29496b229ed6b29b34703922242cdae43a780c69259612561022a6c14d91f3fb31f433f77a7568e46b946d2cfadfe9d6473725bbec0ba54c7fc9802c9e70da9491d25a71fef17905eb4881aba307263d427d990e02e17e058670ab996ca00669c41bc3f44440bf43ae893321f01224aa323c15db6683e35ca6fe778fe1f5c74ddec05049fc460ea5fec906a9aa8a111158fe8de015778f0d809e57519a72a318ffd7db7165895243a6fb4fbd730539af4cabe556f82eed44e70b9e0522b762401339ba413ef297801b37fbf8c4a35cf3e56f5b999080d9126dd2b17665996ef4a2ebfdfab5d5640bab93eafdfea9dc84a2069a8f9c7d7e55df797e7d79276c0d85d202e1557a28f1af04c5f0722506d1784f6abc395ce9ed4488a5820cc562ef25f763fc23e6d204f60a2fff8ef0ba0923e9912566445e7f75721ccb94f67bb24a52eb067bfaff96fe8f2b3e55866514a540381dde47fc58831a15a456fe6af47785feded3ffb923e7bebb7cda5dd899c2fb3bd61f6842a740dc4606f4a103528c85a79ba7097d166905aa8e441be85e648f1969a9642feb99b88f05c36fe8258253eb3d4fc6183ff74171b9a4e273e99b29633797a9c5a082dce2fc8484c933b08c6df8632f1fd84c9f74c6aa1f2443d4e88111a2076e5802e603080ba32070d253a1b84ca5703628e3e4ce3f293ceb2c192505593ab15a7dfe7a7bd1b742e1c4aa898dcb0595d69fba4f77260fb0eed0ff8e998a97bdd481a9bc85e6d6378798d1d9e923cc363c11968f13cb29d7f2bbb08b02bc3d4fe295aaca23e42c7d3b8103346d6a903fd59995e15ba60dbf261ae86d5595b5fe8f5ee6b09e432654cd5fdf64dad069544df9d76f0a853b53511be00f946af86e79a2ac6c6b682c243e70a749647cc47982696e0cfb87122e307a3c3636d2dfef7adf414c88c172ba632d7314c189b75c7702d1aeeb0f2433387c5c3d94a4d03b172a2edffaac371956b5c9ce1758ae2855f40dd8dbf4779f37034109a80f4a3115a8640096038727db1a8a28fc12cbed433a117baa13faf56e71b416eb605009d4387950cf670d2466c2a15d14b244a245107dd01959eabd9aa704b45c0be5b7f9e17ceb8d2e96548da4837c8bb4a3b55b96eb04eb17c5b8c8740d0f07e1e5bfe1e34b0046902a1d3b08fa853d061006ba547c5f3d6f80301c1355ed579ed11df5d0cca530988f0c4af4ed24f391fca26b0ba211eef28b8c2cb34f902573e2d06673d7e6c4bc134462fb654d84735224dd2821d22f8bd060f7c529118c84e6402375181047cdec0d1aeebf00d686667be0d9a22e6fa8f528b7a9eac473dcf3174734c32e3a98b37d4cdf638a72fd32aa09fee76d3eb34c03f1e4917bf8f8b5c305674f10c83f8dc02d7c21492149158f7e76e89c4c87254c5c191357f94aba8361ff7dc59931d8c25db3e5dcbc5c039c15c12aef30eeace9544c36f40f7bc93672cd211a2b6c4f22f91b4fefa7b5376a266d5db1f188d6adbda9bda367361e698f3b8fb37c00f1232c8621f54eb2c282bede45efc0e4535640a1830fecc16bffbd0ce0fc850c90830ca01ff145fc07eebf51a264d8bf9ef3dbe7ef9c7f29855a39859487bfa5acdff9c1fac5e19cf06ad56643133f96b07e9561fddf3a2a10eb3fdaf79d9ed24ec3361776fac1f5d7ac81add4bfe3fbea26a37723520469e163f5b87eb37cb167051542c0db7f28044c197488a580d9f437e2f17f8b1870536f24065414e727a2047377fe98710f6eea1cf20c2f5e183fc2e000e69f6f115bcdb5360437e10ab1546b3cc1d1fe6a66833dcf5c6a3a753706990269e641d21e81fab17da4860bb49fdfb527b4091e09e70f9eec356df00ddaafdd8381a7f8d6be615ba158d8915d1be8afdfda8c14c3e6cb3f7094c87ed364f4683265b33c25fe873ce562bfaddeaca12825e9b688d778bb2266854056bf12beeabeddbec5b214dadff8ea495dc73f18eba5addf7f6ebb5ce08c1fbfb49fe9f25115dad48a62bace765d963eaca1d83a2d6b24eab6488c6d3eb63685cdfae70fd8cd19212b1576caff5cd8a9fe47c2cee63f16763cb1b6df483d16f1c4cc6ae47c543e34993b3a2d6b2c62c7a993f14dffd45ffe7f9cd1b7fe9b8cbefa1f31faa6478a71c36bd8bf31fb72fb3f61f6798fac35396feefc60f89e709aed5f19fe76ca105bfa47fd03f10c339f51ac81ba9464963a37d9cc98ccbba664fac5b87698d6fb8f84b719ce10f3331d8021cf24c793e0fa9fba4525f69d3ca302ee6e6ee24bb977ef3186057e8f58d2bec0ae67946457f8178a10fb65045f07d9cc94ce1a24fabff0965b3b61e66eb69c7b2661916c682f7f61c127a83563cca7a271176381d54b7f35a97f5da1ecf5c0c49c130fd5524d121ace848a7ed3ea8c845b965bda4e472efd3c4e9988132b4e003fa3161c9197ab6b65b3c1605bda1ed5cf169c11a637745d5eb11418ffec2333fccb9319bde89ad1b376eb1ed43e3b3a50b16a46d76d2ace343f0d53d8f312299da4cb12c9494697bd59e364a3ed2603985ea19ba49bd2d6bb7bd2dca4b409b72a2b5caa12096def50ab91a31707260cda5d495e9f11923697194f47063c489d6403fd4d01cad2fc53c3b2cc99b9d4edf27f68e7dce411bc195ee50f0495254fb25364057a4c114a083a06306722178b003171f46722d4a9c825e23a2ebfe04b47428caf3dcb175e59ad753fe767911e0318e9f206033d14c10a0ecd46c4d66473cb17eacdec821d65299112af00a3dead2ec164809c8db4bcfcb30db10e61722756f59550af5e1a3750974c4d086b6a82659aa01eddfc236d77f9ccb4abc12c54d773358ae4a220538353e10a8b939ed71cdcdf112d3fc1f8b6a852ba980ca904db6c6b5b8118bd1e77198bd5f5e3f7e7fd574a3ca3dd36211f203fdf7d9d6f6dc4921965da5965eaa11d096d56cde48a9abbafeb7fd63ca2e6c1eb6e6bc3ad32a6f02e7a722cfc3765c2a92802013bc6404a344dc5d6c18a36a27a5963430e36c8957f39125c4bf0b0b649b18b0f30ffee0f3255f432ae680e6fbe44d8d6a50d4491065165f516f3f53dae8fa7143f6dc2dee059e0c6622e5d0e2fe2de9c6b4436a18b5de70b25f45659011af2642e7330478d40869d27331a60425422fb977e47545e744d6e49bf7cd7fd74cd45e5f92e92259c29f934cb326a272fa567f1f264105398e1c319e03bfc13dfd727c229031bcf6110d18b4cdfabfafc9e398592f97127d3ad038765cd008eeac58e96997121bf63346b27ef627cfee47dc91593f2db319754d5d955d46ff4c113ee46ede1624f577e6c72dd888def7e5df999bcddafd90e933a8ae95fb592e5fbb5db61da4631fdebac643989d0b95f44e8a2d849a2e75a43aa6747414fd8ebde7681a1ec1597e143b0f06a971d909b79bfab45cabce4703797dcba432acf903ce1268e117e425d5abcb2f79b5bf47a00de58d9501ece18cda4bcc96ea399bc22046e70e3ebb444ea6d8f791a143776ba4c0aa895eba2fa2f2cbf5745e9e53fec0157387999e3a4d40de57e3c2d378476faba6303e0502806a0d794dafb208afaf8ad37bb457e89993c0fef3ad36262f87a3659a1545399c29ddec187666f481f5c723015911ca7021abc908868eb405fd37a523796f9b7b408f41a050e2b8049ae92befd8a9e0f23a840a4520d9ab23c49439580aeba7de26c354a9640d421e20420140125c05f6ac6d37bb442f1cc894c117dc81049262b8947c3d5478abfcda6895e9dfe3181e8db35478b10cd1f579429bf44e1140c46305b12311e57382e176d2f1456e5e4d519be827199b9ef91acd0ce81f2a47baf331f6c437f2522bc393a7f09f6f9f86358ea24b7a44028b0a2f1827bae2d29c17b25bf3f13680e5ef3d255a872f15b16e4590780c0da2b91183b623999e7744b3e419ad4279e5442364a2795c5dda82cb3b30ad1be57bfa47a392599ebc649dc7b3237671f7c1653d3e866a666ab327383d1881e4c01df7a5727b97ba4e9e1decdfc341e303dbf3c1508af2e77a8e44dd98a2f69d658b4c659a811e950291e8ee8e537f62f95ac69845c5bc7bc6b6163a277cce08d28cb253e78327b2792c85553d64c3bf6125760c44cda9d8c7307f777d2281f10e016efc962743543dd15d46f9f16f3a7357e7e9a969a7eff349651786736cd97ed71796264ef125b7471f67a378e67fb80c7b8615af3f79558dbfcd67a890378522cb68ff2bff7bec23675633a6c6aa372b83fcaffdebf690f5ebf5105338d9081805388e3fd6068455774abce32ccba64d6cf7aa352b26b670e49ef40557e54bb09b37583ad444d96201136432812ee0c57c3d75c867093e84cbefaee17116ec06ff5261ca0e88ad9cb2ba43c28e39609c4ff2820fb20b9b091872ede8e4bfeffd2ff39aac50b59c6293acb1b629bae0e79bbf33262cbd4a3955636ef5b9f42ad5461c7d123f99d9db9bbdcd95ae370b8fc01f63e20214d0114a155ec4c2876a5ca954cae36e5fae8ce3625cea3d75f9b535fc0b026c34055916580ec474832f538942314ea35094043ee5f09a3ec424b5bdba6988d73428acc72cd79ec2ef453b524dbc44dad62b45d9f25db797208500e61b233eff19fbfe504527a4dfbb6fb118ac7df4e64e9bae3d76a12b8e1616d21db8f8b3b322b5238930fe8c6b3b43e45fbf5e5db90a6750c298f702884d4dc28b0b88a3ecffca2cb8ed240dbe7a1b130a8c4e2e561aa181c598fdf7bb302d1169cb8572f67b2819ac70c4650658d784c1b2f3165da7ce17e5957296ce7c0b3c8f9dbd574a5b8ce7a03dfda5d1512d347d084792826c08767d3d6eb5eab1c8674e25e519508f1ec289d54a1084dffe0589e78c0a29cc836e98812adb42d2206bda92160be77232b85dbcfff48d07419082c14a20bdc384b515a4342351b7ada5b7d60f9d57176480a1cb4494607eac02714f1062689008eea122e5ee1d6e12f46cd2bff0915ab686ae8e81d29d2af28732c7ee6f1ef1e0822b3cc5836cef7f13778ef9771400d90fd6ec799995a45c80c0c1324ba4dda2aeaa40a88c073b79831ba41ce0a44b7dfb70f563812fa21cfaa4915b79e6e9bd470687c7c81be67b392528b39e08f8f68b04ae0a495e6cfa7a9e28078c49c23ea8b918426a9a12ff9b3e9a62d72ae417275a0da1624156273f47c7eff95942950c6dcac5e8b2353a8c2792854ee06d6241999015266f6af8febe9cf5c4ffe5cc476da68c95b59738f478e4446a9a881b18bd7597f215dd4fbfd5bd7eddf879dab24d1cdde2683aa385c2c524386f0ae705874015ab202f8c24b8eae7a2d166e1324cda1104181eebdcc6c18a189017507d648cc24655e5f321f10ad335f7f6cfdf517b862f4bee35857f48a122a5ac61831d4ca69cb3bf8c2444e0b28ea224b08d5dccbcd596629a5aacb62fc070e470cbe24abb85c7108ad69a5600198cb884933bf610ee57929e37dcaf4f6aa2e333b3d66f08102ea7cb024314fff71856ada6caf9a93bd8a1a36f4de7240efe1169fd36e6347b98fce0e18c1e796ea7b3991414424627794a446e5916997bcd9b5b8fe8a2bbc265c567568bfe11103dfca5d432296404bb29e502d9c72d437f2cb2e265a617e731b4d398272a6421d87d40361388021c2c73532e10d43e83acdf80763e45223f9f637dc052e488bf4c060c719ba1e00ca29090b7d4d221ab2182cb77626897db5a5abc31daece394821e6cbdbfbcb112e9337bc0e73eb95de38860c7495950defba053de990f3cf71c855f399335b72863ffe1ff6deac3b755d691bfd4130067d37ce95241cc77108218490e42e2d604c674cfbebcf503d255b069239f7deebddef77c677d6c59ac19664b555a56a9ef20f0ecb099a952dafd30c275a22f1f25f2a2467f7aed7492c1b0fa2c14e5cf1ad4d375d3128b00b6d4c6b736b45c8ad9810cd144573134ac3eab4d4d2945a29b13621bccc07860a0eb2b4edc8a57c4568c7c304c89752e40fab8c90ad9925233a716907ff5c65ea8e1d529132eefc8c1fabd7b3c61c6accf152a7f90927d6602f73dd712d47b8406fe592bcf613da5089716186334755394b22aa724af4b35a0e606d4cb58ed8aab926cf1456e710d569afa1d2f8e621bce82138e2404370d8f43547076ff90333ca1eee103095434e13ed9d518c6c1ff26f427d88fc9b6ee501ea476c136e641a31e5d07b289024e4ed2882d0a173c6c62f92341f902e56b7f2ac8c539b131a5aaf2fbf04e7f4a697c70d91f49b18c53d294cde62a264ea7d83398087c75b22fe62f66aa807042a646ddbae357b5377e5b59e49ef21c53bbb4d1d7b28df00080412673fa4f4e128af4c5fdce754886ed181ead4bf93af74857a2aae3929a512ee3de5f2a9e2e0d1e5ea9bf382f842c160fe56f826d37595fe819ae28db213be5490a33150e5834a9d000b17beea8ce51a93f2a55bfe4ea66eee7cc36dc2cfa79849af20c0b4ba06905bc0cadfd76706be243e17a333b3c399492af19179c0e2639f7c5a6d38d48633e4580b022da961ebb478eba407646a7662c13e20e535bbe558b5dcdbcb1570360eb4bea3764325386c9e668c92f5bc697698311400dfc10da8f33abdc6a8e7608d462737099adc0b030687d7795fd4e4a391e1270001236ef06c193362e659f4e348ed74faa98cde4780082d46db7eec2441c0e9c6b4f98f63c9f92423870af0467e98244ed6b301640b7d5d57ccdb89b8f8c96d0013c8b311530c2700a703c9da663e35622277bc10b8220cf5a0fa73c949b7d6e87f9d364b0729ce4baff6ac7ae19a49ba6ff2eaeba9ed09a785d89e5e7d02dcbefc80820f115ad32b862af1d60f6529416c3278c29f6c2d98b0d657af678beb4efd0448399421d1e85ece2c160998052e59852391cf40cfefbcb2a30096b180264ac5929f2fe976d8a55430dfa66c19fa41c686fee4c793a00d97c2106d1c4d1bd3a0cdf6b539de34cc9b5980b12cf1dc7c6011b4598113e145c95458056d4e3b19d31ba765de94fba921b0403ab29ec99be934d402c8a0eba09dea57f55d1e8e640933e6f4ef9a17bb4bb942cb9ba06dd65a7ca04d5fa8b9dab2cd6417b46d6b0f54b5e9a53cca4801dc66d1d4219512f2dee53f547cbb5463d8b48c8431c88fa46a07327d08b4e58fd1d6c808a0b56e928891e8eecd15243c0e2ddbae591fbe33e927f9c59e7e3b0579a03fda1b08be9f647211fb157c074634991dc22a74c814407c4179e10657f726fcd77b3b22082e191356e4304a67acca9ac02024eded4e550a32fb260c25aeb6d66accad5876f6720fd52989586dec064467bc3c0509db737e4a1484aef0c3c9549a9340cbc9d97d2e39ac6da05ed51d6b586bba31d0076dddaf2a02e73b6520d134614a18568071e7f1cd675822e016a3a3607cdf4b0309c214a3eae2400c02d51a5f02b476526db9e42c4af41d2eebcf234404d1219f45270f7b421ddbe7e39b39f6f8aa181fe8206ea79c7ed30f80d73ae15fae1e68034a87c20d4158c218bb3bb2774602cb526248184c92bbcd71141058b43e1325b5675da78512f361704c8bc74427ec926693b81147a19387c4a82e0d628bba4f72e9bab7b9291f042d292c98694e54a56a875096dcb4a10332c47b8528f57eec0bb73baf52d94f208313645557a8fb52897b5882adc586b4ea24cad41291e39abc9d1454da9d5cda9d405adda934a4d59f7a660d6845d4bbcaac84cc0f85eb2f8128f8b982f7805ea04b3d9cb8d6f265fab72495f7b52863e80038f5efd82df7c8a10d98ac2e4f78a730e7c07930e48fb84a6939436520e6eabdfc9b18702bef688347d89d7023e30547d8c7dc08f9ad3c934b419ab4795f940860fb66b7e05cc49eabbcd15e38b7036fc0b51c933b81d3c02827642d6c0fd9b175a877d50ba18751387b85219e16ac79982f58fbb69049fa0bd1d5e7b4dd314dd4198534b2ca7ac2c39906cc6f551e8176c1c82135ee8d41d484f9e3e5f89eef50de50021058d2e131ce29a13c819ba43817fe455797ebfecacdfba283ecc30bd9b8e27a897fb9c827202cb79c6c7ac160d1110dad25f7b296398184b09334b0dbb6096f7943f775b5952e637d3016f1432c6b3653ebd5b76d23fe3102926a650a14b7ed2c7e51a42a9902cd6d3b0339a5e6aa902990dbc219872f1ff90f3553b165f798c956c83bcdc2c4f49878f7120702bfc0c5689e735058db22eb7c7ba6345998e432cb938c252a52b32da93606dc2ca3060ab7ce68c7068c8a9b746a0c0c41fde2642aacec1bcfec0184ffcb03a862670f0f2703685d1880833318c06d17bb9e36a0e3d8d8cf579aa056da11bb305b38d6a314c7ba282d77031ab698338e53e3fe04efd9add0897acb0f44fb7d42763d7ddd21599140521b14cca0b4602e1ea788cd8b2427146cc388e5b2c4f6485e268ffc525f791499fc281bc8e34d92a1857179cc9d60d3165763b900391b11824297e193e2a2455d3da28b75a6aec6756803ea7202a4bdb5e00ce9341d0f4cd9ddbc6dd02fc261f523e49db3b5fcf8bbe2664bf534cf6dc9c7b097cc7987213ecc9c1f7ac9cd6fe88d88fd3c8bd459f62ef9d3817ebabbdcb54f56c2896493c1a2a24b2f7378d98bcf5fc6b20a73eafcfb747963b982abce9b21a556bd829c2cadf9fd3a9ddf55c8342f949949cbfbe27b2f5b6e5a752aadba9e284a44d14f55fd11961f60b1a2f04c66d8a48166fd018932949c61d38f90b398ae74df6be6f131221986f077d9705ef2ad29ea8b5886d2140e6630fad1cd6acac1e8a1f5702c9b10a79de50677e535181a4009cdcb68db36583e8071f526b87b2f606572e63b24ca58ecb802b736a2ed705fe4a400bb1efb96853069b8074673a223ecce419d793e46e43cf3f50997f61669174923f38ef49c7eed26ef0be73efda54914ffdab217a21ee4529a6e9a4196e952e2deda0d89ee69554f387bb9631374039e464861d8d9b36955b2e3995fa1afbb9569326e4f44f2bb386be79589a41a041bcd738f6a2f676439e4c40b1fa59aed17e347e4cbeca4fb8d5c6e6686dbebaec2cb314e9785125ab1b2bfca1e7d45eaabb3ad10dec85daec2d9db09c39a93ecac19a891c7d5b801399e91fe005828189bfa1c334b48b9446706d8d117cd78fb49a81999987063f62ae4e1eb35d98f717e64f720a6731139b974cc24ef79eaebf4db896408ac8f1df9533d444516ac569c37659e0ec2179f15b9f0f31d31976e0d285ad701e3489c885361459f56bfc42970afe124cf700a24f178d0575eb3088c5723361d35d18daf799daffa55b8bdd5bc13aa91ff508576242b93346ea2cb811f59424a22abcf84f43625a4ee8dfb038174a35f089d5fa0847a2243edfc7f81dadd66a95d2f43ec16bf12bbfebf46eb72f10959f3c5d30ff4eb9fa55487f7cb14a988726fa0a8bd124812d3d9170eb6805a070d376f92b3ed0945bbfedd8cea3fa3501d11abe791ff23a1e87eef9019fea5b5cb38721ce6c8fc1dcc52c7933e49fd0289948c2e943553dddda79e34b85cedaf92ebf78806fa282809a2bb2bb27d9189d90e5a7835db59828c1854162a6dac82f052e7789ddee90f50f11eaf29a16dbb8e93305c110f683f7ee5938cd503f6a6a0ba64cfa1b24fe417e574ae12681187121685522d4b905ee6f23168ca13f1657d72eae89c7b7cea6ed253e7fc9f78ea46ffffa9fb6f9dbaf0d753d7f92e6f920b8efa0cf6178f5e0540453d56dfa5b7b3115d583b4d704e9f2d43cf6cb218948a50da1539ce5dffee08b72057dfd629115f74aeee6b0659cb17ef2ae2bdff9ad9fab8aa7be6aa3ebc5eef6d057889159725693918c7703be801d296b30cb0a281c2a59e28dc40917f82279c07d2d0f72adcd8aac7e0c54828d967f39f47e93af5e271bb3f94d35f5335190156af05ccb7a489bd5c6647d717622339e11c62b7fcc94b3ec12feded4903740e0759c1ba85b423078b4fab3e8491d9cbcff509d2395b958bb7fff4694fa8b9a9ba2e49ab38eb7e91c82b5697eb06a775b97cdbeaffc5bad0c3b0589643e09699d52eeb600168d0db32e867aade811240b0b3545f1cda1c90af398f2b3a6303e3ebdaf95bd56b7afb9db04279dd4e92498570bdddd1bde44ac043ae4a5b0a4e8f7ebc39534ce078b42db3e18e3301ee67963edd3cdcce589f4fbfd55ceef1a0b3034ac3037dd51951aed51ea70f73f1d2e7540a4ede152de77ebda2ac3d932b1a7a5516c0f7dcbea658f07df249c7dd0176cf633eb14ef69319b19d3577fc77f52a3b25a6f7ed6b7b4adc7f634ab6f8d7dd647f7b7d1806b0005bf9cb1c78413a07917bbf59917aa479cbc804e33d2dff56a61ee934ccbbf385af2ac629723cd8adaec8b4940e50dd1c6102e8853026f8bb8395f42ea44fb914d14988c2ea8a13b73839e63eae70a1f03acc1215184f522f421ab2fe8a93b9e87dcdc6b200087e9357d2e61c5f92a371ff409e18457a4272c97d09e9dc713b418e0433711ba2549d1e1870e1d2bbe20b032feb290d28226a7b775f1bebe16e5cc07b348805765efff640956576f7b445915719d34a2ed057a2069a6ecd95737b3ccfb393d94bdcd0c9ce30c55d02018457a9de2ac7ebfbe24ae6bfc44231e0e61cbb637999383c5d1e0b878eecd83ab6c01ee93688d078f0b53f643b461d4a0643aeec2725f82582b613876ff579a09e07edc7325939abd75883e53e3dda5d80c45f3ccddfe787f960b6f9aff4cd7d8084a5f772b4615737fad52738397235199d6d6f755d682740ac7e69f6fbf265488155a8152aebfcc3aec89cbfc248240d04c365e988fa6ea79370b2371a7ca1e78a67b5c9dbce9021f6d8b85cddb53b4da1a02044055ce5b162d1cd7d95d265ee6e90ff3e4a564cffbf4e9ba53707598af7edb3c5232dc32e21a51917002dcdd28fe2c95a266cc5dd92dcdabe63d7dcbf58d5f46f7c16f9f3dba2b13a3d97d9453e4eced66f1d03fe3d8eed850ece3cccffd3cd50e4e4120134d5ded861e6418ac3d9d3cf3b4578933d7f37dcfffb9bc634e40a7554256616fffae6b19aa92833187acbcbf7437fb2fbd724cc42cd642e5ce13720498ea8587c7bdf5cc97c4facef4c523850c1ef3fb3c869e2e4b0e180dd84061b1ef9774240314b398e0419e5be5ac47ad9bdcfad64fe43547b5710a1f77c82304a77eb2492832b062d9ca431031661f4eef908168e70e952e29811b88853b88a399a33b1f8916f2f9de87b985f3ce104edfe3f3458f2e4639fc5e29e151405ce0d7f98b3cb072f7fc20f6a72737edca6b8a14f64087460684cfdfd1fa86f9114b6a2d3a48b1b49a7468da1be0f1739ab8b3a5dceb7c1357fe90a837bffa92bb4763bcefd58bf27ab6865969e77b62cc1a3ba4ba12aeaf997fe3bdff6bcf61880ab5b811381ff0a156f19afbfe0fdbd8f891ef678829dc5158dbcc22adc1dbd561162c6e9535f18a4708a0e5d4e02c07775c6f493b0e2615f0cf455dbbd228d4419e7fcf69fee993367cf7cb69bc11de5b42ce3105724a3ac396be02391c1fd7d99a15a4c99b87d9f71c90352d1cc07f7b348e6dfc4ba7b05cd15952508815e609c288d986a9dc39a615d9336b9b7137839acbb6f27451ba6e8a84d3e095a4884f900ce3eecc7e55c5f387fcd3dcdc6570b543e50a303be012d7f81697e8e16c339ca42ca04d41dfb891967222355e6f6e79519e3cb9fb749ec0b2a999ad4a11aa22ba1a3e03c1ba15af6089284f6cd9471be63e3e409ff73dbfe7dc63a8be4c6da2b75e17a68baccfe5d46d49c39c8d541178b3f36927eefd71b6b8bcd0fc864a95ab2747b69ba1000d2e17c7e5e441438e8b1734919ea24969afdcf7fea32f1db25d461ac04509ded0fb78734dcd2094e8b98790523b2fef6b08d7e68d1147445770e15ec0fede6cfaf006e28215136d4f311a798dd2e99484019e21e6594712e29b3164de4ddfc87f2d9b72832c93e296bc9277b75eaf98567e58a3d2b035c740f9211f5081244df87bc02f0cd2770d31a8cd78ce8530ac1ba8af897027f168a6ca37d4223b9a74610049d2ddc1fc3b780c69ca3f8f282ccbf88f6983edfc68bbacabf897643598f4ecb3a46474716c92f61d836fd56df48ea98f749981ea6055ca4e5528dcc530ab4b5db31c53eb91d4fa8bd3a1f36e5541a08712f106d9a1f8856bb25c799b55bd3d97103b9ad486bd1d670d3a241a8fdc9cb4343df5d57081ed07757bc6c368d874a1243fc41fc62245bf77047a75f08858c640e89ced0711559d78a15ffbd2397ca54b9d6d4d2e242b2b498fb80ee4dd7283038a7b975e0c2c7c00020373bd86da39bc49bcabd4e4f220d345486b4b4adae315ab467623d9cc460dc1991b4a79e18f99e7f0bdffcdedf604ff2b7f750b09335e679c26984030a5972ef8b49ff7a423d54197c744beac74ede171519c8494bcf806be552e104e9ffdf19b80bfcdce24dde1747e7f98030b341638f50017d2a0e0a0e9d1f6be46b8134be676436239236b88f4de450f8baca7b62a9f6aa095928697132539cfcda117ea0aa27af9b4c9e1af4dc69c9d3029abbf629266d285c4c3adfd45c24d8659835a5ef54ca19437b04edc052b6329d44fc6f4d8e3f326596f252a125bb6fe32b4c8819d20dd8038f4b4ecf86801ea3ee7358d9c415d7ef4946a18e416b6e717aa13d220443ba0fbaec825833bed365c041251711274a5c4e5393c254ede6007fd0ffbf12fb1da5e7edb14272a4a58b0d0d95b3ea5016c2c77c4fdc346500e086c709f68db375f37da19e4a089a78328fe79a90a97e0b8f9fcd634aefeb5d5be93ef60c3439d4b74672c92529d179dc52d094b771cd6748be42cac0eda3f9880fc4006ead4eadf9d669a3095dc92393c3e62d90d3493dc1eebe3379ac4bb6d61ceafc283cc09cd89ed21ff7f721bb47ffa13fddfc870ad56b3c4e4976877dfa767081661044e41483aba72e09e4e386d22222e5ad42e8c886b29daad73967ff9be1e6e24faad8c14b7e7e9312ff4f58eb8a90819168f2bdb4e5c4df30e99539df3a6dd135f33f24c6aaf7f76d1b4003e8219de9753ec93044b0cf0f54692a43224d7e9972b582b83f1c610c4b5e56ed97a5939775fb65e5e465132fe9bcd9fea1fd42da2f5d0e1917d1c682966898e998e835280b2d9c184f8a54b9480b4560f0392953e73285d3325e5aa6c965c6941bb0f53857a5678b7353efd71de2fe32cde3437440bd7302bb95e2c8ec06aca83d7ebec93ce8b3975cc5314f390bdd04d543d9ca3e5f9d3e208bc292ed908b2cd548d4177aea2b6a040c5cf3567daf70514cfd976313ef9dd09dad44b6e74176186a298bc045241535448ebc898d53a1c449ea653beb8c25503f291bc27bfa2d154846199abeebaf3ea6a4a0d1cfbf899cc757ccfb04b8c9730a740e6f9c0547029711b5b81a688af559809b57d17ef8dac2c3031eae330f77d643e7f508db7667c60400c958dd6ff0ef2a650a82475eed0bf17b497a68c66d296263530e564de2a755d06506f40ea561284536929e150492772899b179393235a93b04d41728f8d4b906779a1ced77c111efcc27466b69bd85c06e6a4e33ef427a071ba15745c662bf423b8a8408f5daec9f3d7ba8e2070decde7a237c7ae33c659e510beeebc8cf9b7c3a99f5f785ba2a71aa2b104d1073bf48b014bd08700f5015f96426eca0e033b4027ef985a8684461609fc0c1e2452339977c31d4fd8a93b2d7103c98c999eb44067acc17ea76c7de719bcfa4882f2ab763b93eb64d7e4d0537ee88f0671f779a068b9dc97fd7a4d0d24fca9c35a70da244bda092c07d250212c76e9c03dc9e7a2b4db5bc7bcc1bdbb4cd9fb72a7f8a51ec188c6202317e05210326d1911e3dd3700eef700c574922aa06fb37d7314b9d09f187ef186e2ddd3dcfd1ae4630f19f2b38f1225316edd797c487df63a8a73d3c76fa53645828c910957a3bfad77b02c4b65f436a88ba679d0be14d61f11846eff67109541d1ea37e235b8bc18da770fc4c6ad16397d2f25f3d2d19d4b6f899c9f0b803b517c9ded57f77845791f08f31eee9ac8dc42d92e26038454ba7f463092342fecd273de11764abc0468032dfaa7b205570623a00e8fa38000b6cd982a98052727340af974c7f787b3d110e9ee844fcb8495446b5cbbe26a28fbc144b76f599202f6f2fc8f1efa5b2bf9f5d9346b22611579f72f5f0f7ea581c7288fd5717c7ff6f2f8e2fbc9234e36bd659c0e044fd5548f6bd3de7735de5e08fa0c2727635f7cb8b13f20fada727fc3bd3452d26f584ba6f016381c43d312cb4d2b71dcde7ed63cca8049a6c9972556ea570b195aa6965f27b2b756e65ec5e6aa56e5a19fdde4a935b092eb6d234ad7c9d35e28bce1cf895c331625c4204d3f870075531dc4493b765c6a7a458a1a517134e8bc10dedef08b40559a179954690d2b6900287151228962c139607e6615f387d2a18497e581a408882df473179d815ee67810e917b05c54b4e25d9e4d523c2def4a6f4dfa94f75cda81de8d562a6e40bfc4ba82c5f24e87f7a11b23e5c89bc2d4a6bdef65e69da8bca0f6b4d7b8df861a3694f393f6cf1433008049dbf1aae61b67bb0bc4c5e0cbda0c550866a54711ebbb5c9e55357e794270d7e9fab334c83279cb05d4029e834cb2425a86776b61922b98a8c4839e036e40ad08a7e44ff6e6e1e5933cd2eb87be2579f14b68088b5977d5fafdceb0ef94c6b7ccb33dc73a48560e79bcb12e03b10d06ddddc0be3d0b7685caa2411e7dc5d63fc8398ee822a90bb1adf76c18c072dcab1eccc19623ac39acbea9a9227d067386898536d9b222e55bc12d98ab464cec3017dfe32ee4d24cdfb0dcf305b1fc09d2e675e9c91d0fcc5b63b63a483fd29600d5aed33a5bf6a2cab4c97977f20a611d9f6c6aa3900a13b6657b960ed02ddfb987072968acd59dcf3449cc042257b6ad7838a67769b29cc52c47e90d960285cd18591a0b4271ca4a3f882e1fef729eb0807285d2b061198511a95b5fc433d5ff8477dbbf76e9a6f995d06aed1d9e438d90e38e7e96bbdac5d51711ef34a38482e305e6332466b953f13b9d47b724d607fef8c6ca502c9d372769af9f7f13e15555443fe74d8cdef23bb70b36873c4453c56bc52a73284f95d3aa9467e101ebbc74d5689f0ab5e1bb84a18f281a557af53ca7cd537dbcd6cbff005ba7db263e1141bc2827da09e517360769ed989a8d985cf7fc47ec3707c5177401607bcf3527297a6242c03d1ba6777a42b9ce79815c11ba4b9bd2b665aa8c12b1d2ddc3164b0d5a19e70d9a33ec0d35eb591d5fc1c721c0a84f4ab6fd72bbc48f6cf06de32c5aa260b4f7b593246d6a6b22f65c48ade5bb818777240900446cf6b819f8e7872a1c81ad7f96ec113474fbfb99f1d7c0fed3aef1bd0a1442f74c036a09cb1fdfc87aaf4c2136dcc50b8df8cffd1dc2843d13aaf2dce193239b45376151c30d6a9fd30e48733fbe19c1f2ed287eefb921f6e72fc217d91ddb2ee6e736c27dcec7d7b44c95dfad07ddff3437dc5e7eaea35acb24ab0ca203a9a61cdf9e16a97c4a0abcf68c75dda719b5efe434512d9f8a7b46b6e63eee1a8d836ea21f53e2e3274523169ad2e4369c799d7384db1a61e944ec24cdffa295df5d7f82933cffae15e8de5122195c62a796c039b8976e9cbf1c041f04aefe3a6756326d4288a8e10635939a67dec09672c97784020d5038bb6a5499443f842756b6ff6903bf6687b7ac34704fbeab721fdc457d680d650494c8b32b1dd5d273be772834932bdb37923c29d6c3b8ce3396e32c4ea50f347ca36f07cba180a66d8a098ae5d4f889efdddbe7003351e40313614ea3a189daca94f2aeb586e4b19641eb214eef0acc7ca691a006cf67ebce2fe96f19826a4cbbe8ade1aff7663f8ac8c932bdff67235b662af19fb252675b8c301fa469f441b93d5199491eaa62583d569af077504c8f7827b0bfa2006087afe4cc5e90975542b7ce12baf84708ec4a5615157bffd49a9fa2d95e30a2b3623a04ce7b64558a0136599230a8032f572055b3da8be53df4aba4b0e3561879df4a296f2f53fd3528e816713f1c9d1e21914772b6414b3555aae509ffcd85f757593f7087139d5bf1819e110c29a74dc33b6d5a9f010678586a43ccd9e5392672f784b5d1642d2f6ed867e904a08c8eef439f79fb5a4dfac25754fcbb8c279bdd8854489ca5583ebbfa91a6734ac5c757c7da1c7af17c5ab4401cb55c30b55bd50ee30192fd8d3b01d07f2402acd976de6e1060ff799873b3c8ccd43572c9d404e7c03efa5ee5603fb03874c236ca9ce7c6d936991ac10aaec9387c10288f600f3ab718a0d323ebc9005fed5cd27910fcafce97080c69898fba005448e1eb846fe67ecbd09df9a74058343a562352a11b1ed17e8bb832077510b5f92d53dcaf167cfca41575593e595b2db43f7d45c368b99fafaf98bbea2d5f9398cec15cc5299e66c70fc4a18fd5e95e915728f0c4a285744b97d528ef1b83c44717fe1e4f6575d7db3aa597e1ab07c09d73806ed7359e7c2358637927c8bd153d56e818dba55ecb1def10f95ba087e6bb5c3d119cd5e772cb8c5ea2059678ae01acb3a8374e9ce3e844f29fafafa1666001c82e943565d0334badc11b9b080f9e1d75980698040856d73344d6d56e734be7ead4de4aa1b6b263a968cc4e48a8f48568b32afc4ab38e2023ac0683ab541de605b6d25373acc77c4d08d416b4cf659e75bc0121bc8479680ff76a6d498b3015ee473bda33a4c9279f432f3b87ac53c52ab7078ec1d3968af4662fc771992758fc584124d93fade4245d29fb01a296825e097c25be1ba5c3ec2e3831361a188aab49b0c593c4f4006325770b4d8a964087e431a516299adc564917d81935ab88c36e4bfa22f76194057dc0504ceacc468f1dfd6edbb2cb8b43875198c591ee52e79686e0125dde8e35b14a8dd4f7ff1cd41f847e00ff6aa47245f61b3a4a9b0cbb43d63d3e3546f0c67ef1e11857d9739545546eb255ea58e9257e12e7376aa0cef496cd4490addffdad23c53e8bc254ff814981ea9e4b82d5424037d7242f5eb79e3e1bfd10d8da0b33ef2be18291166cf9ef8a25c652d0970bea3ca9c40c764366501f33e39898eb72789ee4a304e3bd2b04e3be66ff51e742e3d77def7ac02cc5a8c1da46280a70531557595e7ac191c3d53fb3a656955ec36bc70190cff17b96eb2e3830e44b5b9653a726a92d53336b9b457ad06bd994d73c1408da063114a7b214feb41d3cafa9811433732f8d729ad9ecb0968931f9c16201ea4e63280939eb779ca1c32e4fe3c3fe60d19aed90dd713ea6e325317be2bbc91f9ec9a1d80cf0ab2d039e1018404b2eb1e25cc2fc23fded8737c32ae5642d34a978b51eb4eeb92ec8ab9a5663e6b67364e8a0523beec7c4ec8aedbd11bcebe81556ec12cf1f678f2b6a4dfbac83ad39b742ecea2f0749bc4b32a46635d2e279a35935f3f2e9fb2fdfe886ed80a4e6050bdaf48fbdb432fe24fba9e7a1cc3bd465ef8f981c3798012f86ddcf1ca15d68410961872972db3652b89efdec6be940f2f952d24654723a338d172f71344e3b0c4c00a450622d62fbbd0ba997796bea70787e6f2c54f7d8fa19c9fc22f0b4e819fc615915506f40a6e570092e30c024eeaf67e54a6ce52da95d815c4618ded449e3cf028dfb24afc1a154a99cea4dfa2af44275fb95cd0d50207f0fed95011598326323867c4a4316b12330b78c002c6972bb5924a99857cfbad4ea84c9dcc822e7841979716b48f055d9e2f681f0b5a1ffefa49192258f27f6f6551d9ec641034531bf8c6c299e2df893c79c0fbc24cdb3fb22f5030db9f9f7650a97d543cb3866c28a1bed765a8f8e8927a87fb1bfdfd740ae60017bbe12b7b099618debca9d2b47e35e06b98a3b8572714225140f0e078932662aa0005e7b74925660827b429115375b73ec66a81a3d18fb8678b51829cad8ed2e8ea9acaee40d3e45a76c57029cde18aff34366b5736d4c9e1f99f1a236a9dcc2723729e1c7a6ff59a4ccc488ed582bc82fadb7f63624e369747b25ca1dd90275b491fdf2a8107d71d701844ada8ad89ea7732e9e26a2d7902f4c15198f54ce66f689f4909d115aa240b85e4241a492d87471f35e0de42f950825ab18977bdf908f0d50be0087e1428223203213ee5bf478e1053877b410539a9dcfceae88e4649fa0497747f1e27cde93208d375de151d8e93f4401d6a2375865a69693ad71be85cf24906e06144a19483f537eb5c913a6e2685788fbfc909c10acffb3ac11310de02ba83e10d088043c02bba0fb7be43b90cc5e96bf1a66953055937fa61411a5da650e5ef8422508f3cbe523981baa78c6bc00849e1c775ef91e4a227da554693d6bdf66a8864bffa695a54494e0832c97da419f1d20ec2dede5e233bc07ba43be58cd5ecdb14e9716a8eb695a6e4e52e6d40ede5126b6f6f9d1d1e0da291a5b70a9579bc1f4111951b490ea2205dda01cb53e040030081b87a966b78d2a44de33e0e53dbc9adf13df42955d02d6621d3c3c0a4414c6205342ff56ef5beb6f26078424572831e8e6430c6b61d529115395d76972fb47ed7508b68ae03a780d448f0a749c880c89751e0ebda9a14d590fcf8ad06dbd77184036dd27eddd16848293946e0fb6bde1391d3a754fd0bf9997785b75714870763ac9f84c9880f070226541ef02fa5b9fa20dfd19a846b334d7017e85b64318ce53364e7fbc7c628bd6c7e205623c1756bd6190a18dab47d89ed47f8577750156462c654f7d69f8d2d3b6cd495f090b8b3c950315b56c92cf0ef5b85e0db554536197e0f97800a7bd28e656a7010c36870e1d71abfe2e4d750a8f0aaccbdd4c20ffdc9badee5a8cd11ab0971d923e2a9c8572e234ae78a889965df973dd89e5b3417ae9362fa780dc78a36cd06016ca1ac956dd4bb9ddcf64f8e33c0634a0e2792dda193313ad9922b5cfc5f22fc9ba6128626742a319ca70aeae560ed19ccde517d8e34aac6b19863cc0715f204efb0929755beb89a5359b8f5a1d259e5232a1f120db1aebcfea9f2967560ecf6504265561bb31279d34ecaa2322a9d55dea3f22ed139ebca2bbb72f7d8ce4509f3b93071fe0cf9344acae4cfa33457fa55496eb1f13b0b02d4739eeae0ee894edcb67dc5125abf44117ef1a5b151d806b298e15acd003286b2586e59f1cc48b5e5353944c5486cc7db630fe8c1b19a22a0e88583fb4d06efe90d5401c507504e84d3f653503a8ed43e472c9ab1667dbc3a257311cb4c7456fa88a716bdf98ab3dde279979c00d48cec62b16493ecb44eb37c5f5df29cb738bbd1ae9d7fd36336bbbc913ef779cd7ccd437923740f55cac930e1e68f98aaa4fd9c693fe01c28ba3c7dc0cc5325485ff898afae185040fc8dc8420497d76cc08f7857d47b78bee2e77b7ebe22884f0aa31dae88debce795e85e6fd9370b3af426c214c76576e02057d10ea1819299dcbda6b0e2f2ab1e719712248f5fa1cf1d9a54bfc567cd3e9fe7adc49f44dd4de185d2395c81795182d88fbc273a7b3993d03bea672d73f3cd730acede7375aed25cf335065da893b373ef285f09020037233f903effa4c2d1a3651118f12298ad8879dba6f4f5bac2f1c6659358740c072a329faa9a0c0376672dcbccfb40bfef8ed5ecd1fe78e5013b7491b9443120641d1781ce0836bf8659ac3a7144b0d0ec1de3a1cebfd23b842766722c67399966401a75f349968722887b0192fbfd3d980beb6128a956b755d27707ffa608d3c5546ab6e8078cc8fd8a511e1fc05e917102803cd4635f8c8d741c6056ff6c6f51a1aa036835cf191a4652b90cf3b9801f6592bd434512712eb6b28c93b39328d023512027179430d86900db156a0bc169d8c50dfd1fa113a2f99e8488b82226f18ca06094587bc99b4f413be0704b14e5365f9642094a4e2af24dfaff485df8bf2328b3a9c84fe949aeadff7ff88bbf27f47f5f2811ef38e77247d43ad71bf2021add71379a527f624d15ebf4a12afd7fa6b8634907360e3da1e755fa3ba7d29253fadca84dad592dd47ff87b98fee9e93afc6d950ea3ee98016cd3011cbbd775c4880ae09f4e817c30d33ba74b9ec0ea7d9e807c0aef13a9673dd16d5852cfe22def8b0da0273f40c65f0b5077e6c8e6734b123c80347be4faee8c65f5216d173ee9f32758afe6b4bd18b5bc53f8a0dcb7ecebdae74c7c638ec11f7d91bf71ed9304fe3a5501ac7be7f84ebd85faa06f99495694a64c5f5047124f88b89dfc6f2d8513f9746b73ab5bdc0978af975442d228b5d116202e93affc4e6ad60a3dfe6042cc2452e1d7c5d7d53e090791aa405eed4341eecebe74ebadf66b7c9bef8b89c3909e15e45698dce6ddc43802209dc6152d62fd6a2ea70c1417b16d7983a0a825c09abb33709a846e55e1b7dadde6f48aebbb1623aa2cd76c6ca5d4d5a616d3b5ea44dab50275568b5c7ef59f41d223cdb27bfa9e5a8acf0bfb7fe8d8f8fc13ff70c790a53356ff57f4ceb7b7c2e5de8517c7b4f9a577dbf3de6566e172ef2eccc2ff6dbd73c5f66aab6af7f9a12802c476212b2c6dcc11a85c7d03297c27c191b1ae3493de5f6b39fd70dd3090358ef17faf022f75078b7238207d1c748e2e299c54ac805676054f0677f340c260054e51ad3b7d5c8f72fa60bf24b32f684a8004fd75ab49e8a5fab85394e44fedbe88b9db90f39bfc50ec5c1e30b41c9f1506978273988be9715fd9fa16c1dc57a470a80f91148d1417580ff5c01e67a4aee8cceb9c5d9f679cdeba31b20675969fc457888107375a2a9bdc88a6f5a1e0e69e1eae55f19acac4fafe3e510d59fdd4947b0154d2b2ac92e0f65161d6c4014eb0ec4039d3cef7c5fcba2083074ddad7d70cd3cb310d25990695e2fa420e04f1f5abca0fc5e19aa70813bd7f84ac3723ced45b2150764ec6f97e4492d463f5010dbaa274fddaca69b9b07e0d57cee2f812df04979b7cd3b380b8b53bfd263e38fe823dd13027949967cac051b38bb3e32ebef31f9aad9197bcba12e9e0962414b8ab6fb2984c242a0c1c93869f8184c6ed390aaebf89eb424d325813b4ca0bc237bb8ebe7cd754837695bbfba6e4a30b096f01cd7a07dca6cbecf7f06d9c10f03f6f4e7cff6df441a0f7c8e3b274e3cf8b0d56fb9c398dde36708dfcab3697d70d175eb46e72ebed444fb83029765c524e4459ccdb4e13d9cc87ec0a321fd064e2aebd9d9c43bea178bf326ea798f60d691eb7c664c1735778fdd2cf3ccd95dbf90f4d08a0700c9fecb764cdf0c6aa88b3d529e99e54dd8709496922c4a172cbd810156c88d92e9d784868efb558938692c77716ce74f5d5a233da9f0384b62267f04ae8d51f75979ec6dcfc624722da473048df722675c48e7e9992ab1d5284c532e2276bae1bf36fba848d579c896b847b92bbd921a3e0964bed76a47d7e7960532d3f3ee0f1f078520c87921f6a4ae3ebb9fae9f737c99bb022f50ab8b53a4b888f65ee6ee5e40ba6f12a1b2516b2c64fea847ea34aed86598c3f34d14c9a68f193dc4ee6375238a576819f8cf6241a7f8df7691b2f9ae29846267b08c3635a125299be18104812888fca5acc378212f3f31faae15464ab925e0d7d4e5eb6035460bd6865e8d5170befba38306821fe33b8a5fea4ff345f90ee8313e2223c6d211903cd15dda3aa235f4397418622f91d5b97d285e4fc0470489c73f4eab9f755248bebb6511990a15de9d9029892da4b325782b6290374a884fa5c569283aa6e0e69665c7513cdad1f9c72054840a4fa879fa0a07b8c12db3daec414418b5b705f943facfb71a8b9f3ab187fe5f956aede67efe9df003d23cfd3bc01d94bfea71effdd67aef0de0b89231bc334102acbc39a7a32d48f01ce803f393ef223bcd587ef73825c111fe32679a099df23e8651aa42b60c09e6e936ea3eef3285b2696569965175bf14db8919ca2e001b72f19621fbf4ce95a254660b7aa263710481afdf4b927dcb142bcf24a2283388b2db83e9ecfcdd3bf3b879e708fb2cada94a150b711d963deea1f04a95363c18ffe79ab7d00c0a709298b355418e760f509ff404df8db213c4f8aa857fa202356d0ba546ffd898bae9e8cf6181851e49620dcc9019adeb4bf608b946f400b0314a7fa8560a705448925729b53691836490a6cd73facb295fe4f657dd12b39e8f65710c0d6d184a9ab714f442d3f100ec7f1ec70a9a730e3e7dd3b584edf68c2152747a8632e1a5a2076975a1c4dca35a4556e455fed477ae65f9672cf4977a960912067146188e4403c11c2de792635eb8cb34c92d79bf3385eb4f31df1f2bc59a9b48dc3e7e526fc6732d02eb809024755dc44ff79b268a75a430ac40861d00560f34eb6eed9998b2ab8cfb39f2ad4b942832b2ca942e779b74026d625b164ff7b124bb85fbc89de273cc7f5cebc01402e008c10bdf312910ad5799d4c65fa6e06a9e865491ee2de925c57014e86e0888744d9ab3cba57808c5d09481e1f5b343e23f9d06b4948992f9032df90e1289204c32e3e72a0e74b220f2a920097142f4412f19c0cd91bc64f2ba0779d3a3adb784b7f892ffed5dc1a4f3bbbb0788be020edaf264cf833e5c51b3b709a4ff0e3618caca6fe9a04966e4b2f31d2edd37c1cc38c235d4bd6a15d1dc0f19a6e98b067782b28bcfb6c30f79262a967aed7406d6f03aed190a3cfbc2ffa37e146a6da79f829c309c2e46665e7dd012104d1c0fc1590ae40657b9437fb5eec20a79458c97e0012ee4301b46d79078b115d309cc71293dd0949edc3f23b747b21947a931de071a8aefa84ada8df40c017db9e8a649050ef5aa6e83f37ded238821a03c26f82766a89e26114c80146dd8fd0d68207422c65400379100708f53f8da4744b62c78e7c3f3e21a8bac76d1affe93c552189bfec1f20fd4ad65c6274d3ece8163c3ae4764c73be5ae3739f8b9c1539714b413aa4a31c234c467f9c0805c45e22c07e8e4ea6bf255b7ddf6c0b6204e2e75a230480c677600369ad56bba86bb837cb7b189493ce10c4b5c37237eebbd874c0797e8966997d4a942c5020c0beb545b9342cf63e76ea0725d97e15c54f60253c99cdadc672f5044084e499c388b734b2ee02af4ddb7474b7e97c7557d6fbd63d8660deeb25d81096d7f8fc993396b3fbbc2796b7e017adc8f660e8471d683b5ec4e2f6533323a599ed5c9355e7ae0cd3a06ecd8d64f58a7c59f2433178cc77c5a3c875c9e9be452a5c25725f794f78a2a939a0e34655dd46f77913b64970274ef33a715266d21a8099909f30a82f11c60f52d7bf7a63d8c07be5753bbf93423de09a33959134a2ab2bdc962a81d6ee29cae1b5de4367c8df45e09e3e18bf92785b2fb1e118e2a85936f1163ee3e20e7dfae245d72d295842c83b9bd3cbe60ffac8e43ba22df6074e4d7380f70a21b0133840472fd58d174138e969b97ba2bbcf80bfaeaea16f1d1ca3e296f17b58e1dfd583d41d512d59e32775fe56837f370fa4817e8f7886aa6bcc711a6ee7459c616dcb0eff7548ff6a2963eec60a20ca432ed969312969e2df4e84280952cb884e69cf9e1e9cd63540c68782daba08755f7036f5a150df0d56cd341873b6ce8e8fb903090dde522e3192971c82bf4bef1062867f14c39c8a62d3c87898a9ca19807f91cba8f28844a82a849740c60fc9b289b7d143de13bd488e239952e81959395f21fb8d64e303304238baf10bd4982470f75af2209349009c600bfbdaab15e40f72604c30a8fd32182dbcfa9d5987da9977cc2fda9d1b290605b56ca79ea5213235caf26b9e35881c0b40bd5c42c4645792db13c634d49b01b9dab3fcca8964138e22d856c3d1671a8be58d48949eb03d9a851355832be202d78089dc12997b61f01c18e23c21be19539b7cedbe08b24211cd746f52c6f7c63a80ceea1d5ac508e819d51d7be72b482e70468caa6c28afea2f0cf632f8b0e667a1304187a3fc6586a017ea1fdeceb81b4d52d34c5286ed3991acc338ffb28f719448f56b266a12f35c04f8832d593c536b3353ac01f9c35455714f3f9f2bd66d745c7c190aeddcc599daf24ce1d3fe58624e5eb60f9c2b33c045784a6a2eafa5c21eae6343404adec0431279c73a748d34c686bce5deecd1a53a32c9745205df1ab3fd11b37695548658803507deb0d4315f223fe0b4ca6e0826c41bb20a8b35ec85a596f2d45d6102ab46520ec6f9b19c6ea85dc180bb01526e2def888fc80d6ef62f8d2fa8f76ecd5b5f78811af5cd642884e957968c1e5523df52ef314d7051601f023d45635bd3694d913e7c75169275b9c2f8877281bc309707ca2f2e3e38b2f0d25cb27cbac45c3ef35c7616242bb18ceb158e8c563519b3268fbb914c29f43863993305ea1ccf14db96231548e36692fdc09e6def65b81677cc749cb4ff39c2f3ceb871b1f9e75976e9422c1d91a93e71a2adaa10af7f99f6ede533257cd12da9a863545b44d935edef535eaefb09fc57623a6eea7a469e2b62de85c0413cc009e598b6fe571db8dd78dc7bce9196913d7194e5b9be4536f0ce860e9a7b8f5df9512787ade7bcc9d6a4eee1ed5b6c8bc1a7b2da6affd2168b061fd5c3cfadbd7d3af9a9126206bfb5565d37f871d434e41913e9b0469ca60a9a3e7ee4dbf7b49a1cc3dee694adadc8b538bd18bf6191caddcad05441c462a6758f833707c9450462fb5eeda7eda439aa966dde4b2e96998aae55b17d3218371d4c0f92efe960ec6f90dc0c9ada877747486e6a83e75cbd6dcf66e1c7d9fca7be9d9d43e7e7394cb45d038426d873e8fc3687998aeed69e434a319cf99c3d980bbbc2bdb421dc54c626836bccb3e93e4f6aca469bc841621c1690971b898512298d544c40e82505eab2c6e191bc24533249b95b95fa7196ea6706a62cff519c71ac8ce09cb77dcf623dc22ba2fe20c224b8ab0affde21f00df6d8e6975dc9ad3fe9ee9938caaee82299e40c62429f1c21c98a389e4a7880cf89a200f9bb07077562c2b3f44945aab32724d1dac8dfb8c3270f96724df7d361f2642e6b19b73932267cf26501f8f6a9ff9ce6399c91c23c72421931b2441a843d91c50611a96f5dc221151da529b8815122585aca1988b61d424b23bdd99c21f466f8d7d7bf3b700e5576be5772cd62681cf8d9bf305e1b798db8112907d511d3be63216d6cdc3ac9ba4bba4ff11d2e65bee908b16234295308ef9dbd9386c754aaed243e662cefaad5b666d31f5760c931a6c75be1dfaec79af76bcca3be144411197514320074233030c4d5c38ca49e8853bd20bb4ef2658f3325b9e2359441db9e73637c3d48b2e97e361bedfc80a37ae0c1666c3c418d429f232ba6775ad3851f3c4591582290e366dab8c7810ea3a6c1494d64cc8f46e32c4d3d45057d9039bfbf59723463ca8d91c2cef5e60dfdea5aac1a3005d3f4f4dc7c9f0163da847b2648712426e66f873d401da4e9006a4ccf33d6ab349f1cba87508f7195a475ce821506676edc1bf4e165d968a7213b4bb56870efc93af0b26dc0643ca37f3d28e4de1d4239b883af437cc0695960d30042cf8b40307a133ecc8783029e2cf587c991260a0e1bc8ea1c7359c11f9de214db7f8a7881204db02746341bace374403168b2bf2847aed2c2ffd548b25fed76c4993e7d3dcb0c72f542e71a1889ee354778eeeb8c3d49bcec8ac9c80c31322f94316985683a3d01fe162929709b181b37e25666c0e2a5b264d5310d3d6e97a48be083d7647bb0d91b83eb35aa6c7fee0a87fda78be050bd77ab8099cae83c81620e6bd8a9d94bdba2bd4ce3c4db022fed14a5a9274b721950d9ddab675a9fa5886dde34ea1cc56901b8975306bfd4002acc56d7ee2ea7a7e4ee717b5076c6fec991befb36afa419fbfbd750f1adc1565e62b8dc84d2a5a59b5475d127be49de63a95f4455cd61cdeae439fa4beffff9d1de8faa90dd8fbcbfdff4b6ef10954cd40cb779f223fecbdde89a05b3aa01fad8c4fa0cf45df3f1747b92b6f96a81ce66762799b89dc00aa50c3963dcae4db073d80a679bf2a76d3c69f0367efc691b6b3927b38d4772bf62df7cb38f474b780dd0d2f34a0fe255baa9bbf90f35778236c3c84da4d2c47822038948ce0327960ea1001c8e21f70f8a6b3d89dda526a677e28016fb74e1b85fcee153722033937aa4deb6701afc6215d41392896296aa4bd4aa48d45b4789370abbf05c1292c8b58c53565dea8a27b6b2a6c2b73c077bc3bc2580c75ba9a6bc5e0c8af4cb6160a2f294a5055f38380f9529cf44f1f7a107ffa5a1b7f0cedbe1dd0fdd796bb01f0faff1d52f655549edd8cba63455ecf4052bc54949b78256abdceacddfb57a9c2a76d3da5c6c15f8687d131271fb5bab3548a3c448db76ea4e3e694dcac1b8c0497711da43c7f168b5478c85beb9631a75f7fb37cd487a697b25ab2c099cb19aabb99becac9c3a09af1c0d71efc97ba2e74cc81d458c3491f922f3ea523a942ceb8645c7a130f03c4e5b4b915dcd24e650a80d9166b84fc95cd5529649127ca9c0bdb0ec6b6a15c903622937ea8848d7a35ccd999aae2952a82ad9f3951ebc08b7d656897733a5dc71d921d6d9ca3dc0f091d0e3303260229407469937cef392382169fc9e560ca80a80f8e4cf11c779bbc27dcc111dfbda9a9ba127dc345273705bd8cb2490ba8f98aaafd77c57bcfb557d1a76ee23898d25dcb05e68cade963365eba3a784c97454d5d89c4c824ce698773074922f63b59acac4d9e293f19cbac2f98efbd68ab4601d83eda18b88e0f208660e82d57ae07598ef115e4f47bf22677b9efc57f30df728315dfde21ab147255e8fe21ab1d57abe2aea38807e3e8007c484422d463202face04c24777d4276fd446bb4c1ad29d7f87ec747a9d4c36804ab6fda2b43f386027a9c049af9afbd6b92f2320754d95e11e50e23efa3a4185ee96e4ba9a7fdfa4adb2babf61efbafe04e0643131c8cf0a1493260a6f5a241bed67cd6c4c3d59ea79690cfd3880237283d9de8fa526f5aba73bda05b8eb9670f77549582ad30fa744e514cbd4fa748c39bc6324e79c2cb4aaef79ea35eaea8d4a46bc7e08a029777a84f021635c81a6147bf2060fb46e01f3e1e6186ab8b08499595501da29c85cf0d662af20826d28eb5b8d57921c21f9917f11ea99ee258c4370d22fa72637e8f0c712d30e456089ed5a23ccfadb1e066285e418c8de802cc7fb41be2bbc8aac6d32f35dc67c8798201183ed9fc738b6866359a7ac948e08251309572cbc1a090645597339e085b265bb064ecc132cc78c9112cf8f0f74a297b209a02b72e082f8afefd7ae71f165ff2b4597a92e257f7584b7c5952f77ad5921b996879dbbbc2726ed4092a83b916342cd7d1a97c9dde67102540f4226be2dc19b75f4a937d563f391c68cf0bcc1fa2a4d5a26474f69a5d0a27b90565b1490ea067237b5720bcecfcaedc79420329033884f033dd407d224d0a7bba5163ab9c89d266b9ab349dc13eef7e2e92481e13279d9f95e3d819a0c4d4eccca9b96e51fab6fa84420048d8c074b2819a4b13ffa2025d44cd6889f0c40b007e134ab84c3d4746398dfd728346f65156e6bbddc6aeb1e06795f74ae3e128b026259033ab29dc7291b84616bd06f0a781185c91c94fb8f9bb06d73a209acf0e496089088b71869221101bb69b147104dfcdb986054d4fb0e3c9a164cd371782a692af2c61e58fd77885d23d72637393a386ff3a26ec60b24521ee93393d4abd065431de56ac957d368c9d79c359ebcc54b5addefc59cc315c2767e208edefd1479d5fa3dba2cccba794f8c6f031993ef190d08d8e70c1a12c33f6c0785e4db92099c55442d893debad341aa99463dad023db6c2b639e3eab888aa895aee83e43680551f9581845572749eb3896c4fe386dcb4b6b8c7bcf08961b6406f826cb1b95748522f7df8d44cb5f241cb3cf40bff99eff10ee6deb3943f1e115b8f8cc7f68a902bf66fa977a44dc413ff7ae6516eeeb53ded397c9aeb8162c0d0c571ca9bc8533eab04cbf55436a01cee945546c23a1a83a608b5d13048e7753b2a59d191ae2f3fc86c3dc5fa10652dc2047c6cb94fee9d6bef35f7ac6261366324c57df0edff06ea9c389668b639741361e54520cde48cde0fbd4d9a3a4811048e0144cc9a3aadfd947384793f9510ba4a16ac2afc2cf873d7798de35c91f2776cc53546fa27a09ae977daa5e46f528533d47d5b7ce71fd1b45e9476dd37a5f38c776f529912cdda375eb7f6bccdb7937f1f328e2207dc560acf391644d6430b78dd5aaa0a6700088908cda389e15970c91485fb8490e257d61526171e4811821ace95a3cd7659b38b26f0d246935fd41bb5f8c75d9fae6ee441cde7e93e9cc129d8139a9487cd674e53e212fd43844d1fe947bf2687564053bf644c650c780c1fa33046d7de82f905f93079dc521895172c7b2441af2b7c23bf963cc39fd3f605cd61599729c353bac4040edc670e4640481b132f46bff8dd9e520021085ddbc6ddf04464a9fadabe02053f6732246311ed31a2afbfef10f8b7b542bbe40054991b9558462d89aacaa8ea015f312590cff6639991aab29e2984c6a14069220d1ed8ca739a1aa3f26637442908fabdacee2fd5506acb0a688bc3ab0d922b9e4f44ef98ef0f75859d8c713b6719453ccc4d97a75c444f26db569784d1cb7f32922c38ed7c702d3707a67881c2f423dced8278ccfd9fb7ad1ce6caff70d5e5c9182956036442cb751a695b12c1fe42f3ccf25c40e425899c0bb841156d403721d23b386d341eb8555dafadbdfb4eebcd7cdf1bc340c4f7811a63867a66b9b99ae03eb7f0c9c08c04114e4bce265ac91db8d6373a7c363421e7ac279e28ac30b155fb3152dc9e20f153985427edd161e58d484a4902f1bd7c540bab814b0065ee4831cfd84f2a2f7ec759e91f1d55c5d0078f184ba23739f7a3cdd7188e2a129d30749360d2e11a6d88be588d20c2160b4cf5ebe5724b70dd2e794fbfffa9b230f89d550ecbefa2c6e99656ac90b39dffb0bb4622e2706fa448b91930f8b588e8805765674b8fdf930a5363e47a1aac4fa537dbac09955a026ddbc01bb7a6577597702aa92725302938ed8d770c2f85816b37459b8024ffe68714692dd8113a07bfafaacefbfa40581244ffac35b5179b7d92bdc3ffb450a2ce9583ebe2db5195cba5c6a9ace09d3987ab5a491dbaff23dd178634bcb9eb8b96d43855e63949a62f7f2237f628aad33e859f2682be730594cd37a2599fa273286c9592d123bd9a64bdab36fc64a9826315254f48b3926708759e63dc62c9116192c8fc13d13ad250ab8116b2bd9dde6daae1c9bcabb89cc2a275120947b85ebe2a97d728df2cfb3a1bef0e00e03ddb06bd92a6bafa9d7ca8d97b8e63df60eaf79efffe1ff5cd585bf5b01c1b34e3e05791977f1048e0403e22b00dadff1d93fe22aefa0e020f38ee783b64d197cdd692024e3b424582aa0b231530e04e8d38270a4a382117fdabd546e85d8095daeca9f6e5dfeb4d562011bc899dffca1601584ca6985179bb4c6dd62678de5c582562f71cf7196ab3f0d7b0162e1c4fb8b4d92db2bf904f3b00b9787fd21d41e00954d2ec8ab1c17dad63a63f7424d0dfb8d134f58b99500171eafd1c0a12dc4a18d504567b649b713107e9d4251a57889dd26022fbd1a10415df2f05c4c150befdb0085735c8c9d05a4100739376d53982d7f7d722d540137a13a74d30e1932d00c3c7cbbecd3e099af9094692c03fc8337a39e49fe8cd1e5e14aec94603273f8cb551e40a9c8b0b2b7d4d725913c87fdb7771d9ad5125163670a52391d91bb3e90159d31ff2a8f21b5e7e8cee34e80bdb024eb789fec7a752b3999d3f85fe84d7bedc2757a3972687a7723c76c7b5dea26f3723395e9366a7c9adeba0810152ec7cb1ff811f6a1c08f8e71a182eb480dff4c19fe997ad858c84c4f173923a3ebbd4f98bcae3d43b4ccb3b193e9e30a116dac589961183c5ba6e129c7e4cd6423db3079fecf3fabbc1231b7b91865beb186cc70e0a7bc205c16f7117e8556832d79a2bfe418adba04ac48a7caffde268debbd6d9a55f935a88a63cea84acf42618f91d0248e0ebc9dc70e1dc80feac823d90bd663eb042d5b345a4873652ffdbb08e88a2ef3c50147728efbd6f68ceb17b767e21d4b7454a6e76c3d57e9d21e27d68f7443d4b8731eb27a0cd852d0c725cd99214dc7963ae970e1d95d5a6e8e7dbfc366aa4fac63ce51d7fa9dfe26741e4e99a7a3c2878299531d1b2fc724361e3b34791b3ce65135b1971a4995846e4234731a5d8b2a5a048744443ca8905ce4ac101ed9df6d13483d04dd3ae1cc5ae5f40b3b6616ad034c93eb7b0cb27b4a9a577812c193c9f08ec61e8bf5401deca57d631e6dfad35c5b0b788c52f3a8709a81344860c22b3164350f3cf092229ac19126a9bf8f92693b9f44336377164bd0235e2d4d0a099ee53eb60f8e48006bb559e790d780f7c704edb440d026131c067c489f97be507ba068aff9c0ecebed742f32f16272d5656412337c2d07ebd3c91d2b6255ebe67491eef9e184c92002c4299d1f1cead251a59473cda421dac2832c5d7ed2323b8b1defcc0aad7f934aeddb2d927a9d1cf4fc11e6a184efac262048cb09fa88061889bcce33d0e0ce94ef889c346eed637c98b01d9c542be670256b95fd6ab9dece7c8eb3859a0f850b657fa13ce2a65da16aefb664ed5490bb88e77de5196f56e19f7c899eb11b8e5362d2a2ff57440f266ee23fe323abba93abcb644458a8327f554fbc2ebddab2fcb6c144150986bc8c9b66953f56fb81141a58dece3c9599da21ec7f75aed3f8c36ea060281c8222d200900053629efa4296694f08a7789dac07ccab5500a93b7927e1c75dcad0831126af19ea5d74e379fa4de8f82dfb38de7163c635824bd9cdea8391ac8639b6f423e19a35fe3067a1344b8beb5637193e75f2cae219d72973d8f0ae6af1ec81405d277413aaa0ad714a40e1c8e640226d2cfdb30b92d1bc41820075220f37ce245ff8ff3a154c6d9341bf9501356cfad88ca0f2dce9ef3d779e57ac419ff90275d1678cc431662b5b2e5b4613d359ba3d7aac7bc7b7ab57b6c8250c0534e39d281ea596731afc7e8aa448ee9ce59b590d0330bf35d35b2bab954e22c325931778f6a74a389907ec37e4b85e2215682333e8008791b66b5d96c3cca84bd20c1b1f2ae294427d72329b8e99cd3af5f063b4bf34439a541b6184448392251a98d3792a83524ddc20eaccbcf8665729651c15e16eeb96ef0daa263b0eed72d6f6a70a5b1ac24ae9812aebf49bfd9b211f5652fe64a39b3d6e7128235ea72cca12ae89455eb7c8f037929376baa3cd714a050bdf500eb4de61ac3bc867fc9511ec8aa93fe6d8da83dce4e13adf116e4ee5eae4fadd2d70df83b62d7a8dae1212e3d9264167dcc80c95af9d4cd01964eee0da249daf3b5c3247b728b587f16e0aad921b34fe2cae32b5611e53b8b737ace13286c1887fab57a2bf64269aa531ec5aeb84fc6f0d3dc91d99eaea9af38db217da370b05ebcc8efb657c3a75ff6e628a27188af3ada3577d1afd265c1d6e11260cc9719f08db24efa17b455c7ceeec8be882948b9d590982cb96bbb5a96b7eeacd1c82d171e63cced2358c5fd7271b24e50a2ccb4fdae976666a0c8a91d95a93479ad4c3aa9d72143804ad6566a51dc3cc93dd77ba0217f8318b42c9b6496e34c9b46e3059db6e2ac96df0f73c272f776d0afff9448698e0fb812c315d9bf1bf73fed7b0b47d98f4c813e26dc512e172679df1fac4baed8547eb8e48639e1dad2b45c4035f9889386331e1c2a2a0a7c4b2c35963ba3103a4e066b066f710d6d86ca4101b28681d8fb170f915110368a2a115837552137f56a7e9724724e5a25e7973be2e2d30c705c05537f9ce40e5e3ef748911b074460192d54ba4b4ae0991038be3c3c8fe435d21c6b2c9b2ccc97985d023edf60746926baa8472f69bff724f56f254d81ce1d35b793cd928a9e06bb64c1579745f80de425b84488691e77597383c958509eb5baed1c799e02c5ee76aa39d0ea8d6b8c0595ccde974d9509527cea5d305619588fff5096d1b32b95a074e0a2bdab03f63533c5b83f0f3b6f4846a7dd51015b39b414e6db20817e3ead62b06a0b615beca713aa3323f6ef13d09ebdfab060e0caabca0dc483dc09405011a79c5c6344d2316d0997360592e70f2b3b610b336e19e47b721aaf5462bbe638371c85f374d9737cdc7c579d0138629e0e36e388c75f7995f1b0aae278cefcd2969b6afda46da670aca376e9e4a4deb532d46878297533ab470c8b180bad41786ab5067eb7cf7e2d96466c38d376128a3abfb070b0efd0a2c7a864b1c9d7434b6baa7c76ce2009d6996c3ad5e524546e31da3f57e2a509e73b207e6073f2890a6475c778b6ccb301aa4ea01cf23965257d0dbd186ee9b36a7a07130e5ed59d3c3dc10f124ae5d34595214890eea67b5d382afdfe6fb46837bae782a597a27d38718c176cdc3d9c5687f7e33b2544d14819828a22e2a9e7a99eec0bbc4d22decdeff24a9a8fd378b2abc0916d83d6653edf9aa3f469dd908c475d9c2c62ee0c46db6b00fe09cce9313e70ad1f4f565bbe2f3beb52e8e9a241e2c69fac04e5c3ba3b6fc24d5ed5a36981c34996ab04789b36eb66977c4fc7bd36c63c7117fe708066c4599dcb87b91c5e658989e9bed5747a8ce9e8212399798c33eebad6f9a71a6838b1946dce4cb6d88a3da5b4d9d74268ecd73f29ee39d1f339c03b63fc30e778578e472d3476badfa472bbaa6b79e3a960d2759ec7d91592591219cf0de8ac157d19f853c9165cd9c87267fe4041b7afb056a870fe6384409d1d8aaf2c5daa9de666a71994ab3fd43eb073e15454487d478bdea4d4c37fdb0fa5e9a321d5f5ad0d8cbb1bdab2e88e323267fe382b27779110ad71e14dd9175b3c466c408cb53273577149ad94b23e928266006459845ac226923eb9535d7a589fcb111cdc97441ab4cdacae1c067496f65ce3cde33184ed889ab9f9bdeee40c6ac3269d3d5a9634c7b74076dfdac7f9bb261b46c2cf1170a7b42c51f05ac6daf3e758ca5b04fc0993fcf6135712b6b5d98c5e6d44905a4f09766eab81a84971ac94d9d7429e67f31ce2696ee42512273669086ded3101796e8b76a80202e8f6020c142da2768143aa9c96fd96a9f57ccc9e49d556ff384b918e6374a7d47884a2f42b9ba61f70e5f38ec8b46d82a8fd69f02e570354090a45351f390ce57374d61040ab7c2733faab27334992d0775e852be623a5003f6c69921fa73097d249da52115f84e5d1f0bb0cc71aca5e682ea353fbb15fe15419a4d4953e0055dc466aea550b7138a417a6047cb36bc79f53ce9be5f61407e0428b1b715b9fb74c234bb25c76bcf65d8408c418ea45d754f6a9a0e81bcdfcd810ad781e4afee10ff714b40861518ff7a1050d403527aded1df47a0e2f70e24b0390fc4377d8206bd25fd4e9fca3d961a88acda4191f708241f42347c1f3042b623d46b0dcaf14e91ac16ea0e807954ee6940bd27c0aa7b4a99387c26bfe7177afe4acfa316a2b656245d3bf76f48cc0270c431affa8c3280fa14e07e0595fdd71bc515bd53e82525bdaf4b356f3f1ead7d71b590f9513bffa11e2b0867e6ddd2355a98be01849d2082bf048b0a3eba55e1cc36a24eb0fbc720bcb3d0c9fba9bf4d8fa3ebe7331643a12c5dcb0bfe354dc0523835e6286bf9a3ab498165c8cb052d0f1bc6cb7258ec382d69f99a2c6145624dea6941cb7b65f39291c87f6972c13e364632fda568c8249d0db8bf0c3d1c71c9eec592cc0248a437769bcb63877b09dae4e97cfdd3d88d0bd4ed9fc6637ca08e742954cbefd3b2d07a64bca06a97fb9978f91827a8c7df8b19cfa6c2cdc5721421683b369566ed3f0ddb30dcf1e5d561f71acbb569fcc39cf3c755080e68fc9b8eabf6998748c6c8ea64b4d213b64504fcaf11c5f02dc301c9a26c8c4dddf432cc9711dcfb60fa8b2d2d095053f1772ffd73175a86a24ac512b5a2fbf4130b16f91371cf243dcf5a89071cd4ebc733aba1b1d58bebf44fbbc87a6f29818ec6892ff9daa4d64ec75e195986e7f2c849955e2cd5d72c4e6d74907a25c87c811b1f5c4e7b9b1984f23da318b1566d37c30d761c3a76e9c3cc484b25a330613d4af22262455e04cad02bcf300a06f0738c4cb261d4c43d3cc21d640c33fa18d33c22177bd519cfe3ccd6b0ecd618d19147c8ca9b3ad3f00a1556e3efabbcadd39937f98a3867e188b537e3229b68eff3b6fa26e65b1c9297356796c01d16ac699ef28e0dd9aa763aedb36b5b6b999b19472bb64db758c5349a3b86d8905c55f86525614a74790926d99ad16f350fecdc6116693a7752393d2efccb7e11458058b9667167732755656d7f1d032803567f31b7c4dffd6fd56ab07ff2f658cd9d54be3dfe566f4c8022c74f6ca0f5ba9dd62b4d7feb26bec73b6c3db7c4e2d26fdf63c33d76e0c61e5ee5b76a6cad77cd1eddd9f359fbade6048612dec407fb8b8ddfea2d3131c8f5dc2bce1d43fae9e6f6f38eb0bdfc845135ea1f55e80a9758df856b3b29b8b502837fa2b701f44a4b4cd60237a2912162f8ded8a669b642c6ecc123efc1d175e671cce6dafa55e6f1886f4186d226c5d967b07ef2981b47a2cce4f10e308c6e50c8160f11c1eb1eda99c798996d20334fe71c4710c2d7bdcc9b397ecabba9b47915e312b503566f9ea1f244bf65784beaefcd62549eaf59bc6d9ab994b5baff673afe8a091b082796e789deb664c46701440b197b0c892356e2cb463ce3ddc4f49e9dcecacce0eb10f4e28da5dd1cc181638fdb0252bed7d1f39a974f52be0fd21a50201beff822ab728c670db92fdeb10a8c9c625e891706afe9e42f664ea28675a335dbcf482258b7d3372a7dce7f92bd2bb6ac320db8f68e46171aac3ca632027be6b84b9622fe9369ab4f7eea7d198155aede9f343960dd6e6146cb3e43b482665aa703cbfca9c66fa960e3eecfbb9c2c85e9379b3058f9cf5289d11d8fa0e6bcc20490df50bb4ef0b72f6653fe07d301e4e0a39c4066706b33876d9c7a4cb77adc1f559e8744e6052b658fb8dad439ddec8295392d8e14d8d165d85dd9bbc39ef9a6d41b270170b6b74f81007f54eb7153235f0d77b930dec65d3eea5d36cd89cc7ca5ce22e7cbe50a55bbe635f28cff082638dde5c660521d9d8cde8bb80bab05cf196f5f437f760ce61e219eb8170f2c56640855f2a4c01eb2c9fc1175ae597e046ccb752b075683253d3197f3ddc249af5c95d0f9b1c1b265602bd1012fc8dd22dbbc69d46c27f3fbb070009b627d1f722bd51ff23e331e600ddee9c609c15cd139d2d3617033f66ae43ee8d53566a86486a2dd8519daf32d6e073801775f62f9836f71d880a08eece5a62f243b935e40b885c0f23d80160dbb3e67dfcce2c4b39abc0510f1e732648f534037cd7dac7e0b1975cf5e315d2dacf3b4d4dac66d00262ef7c87729fd0682f5767cb91993e9ce78375aa61d72a797e7d363ee5bc5eb7c57a800561236f6b9a5cdcf96da092e43ee72ec9c19ad932fe80e982dba183b990adc68935734ca3ee64d346cf066dbe62c2fede9be9d4f7c41dd8b7faaf44f8bc8c6e3d484d8e76378cb5c1e9a56c872252c70c2cc53b231bf46f481998a644f9cd0e899cd7c0f7cd00b7327a96d3f3f1e605669d8b64a1c0a9e9de341fe4209680bafe4599b242e739ba75b849a4e108c06f87341da93f1b19d18685612eabee6b7eef9008f5adff96e2695811ed42868ff81dfb56c7e57314b91ce2d0797b8b161f3c934b02cbe1b5bc2d37276ce4fa0d72ef19e6671af3ac60d305ada5eb24d66cfad393e3641662877cf42a7a955e3df6c420f1f5303d89aab34782807ee1e0688ec63cbb993ba5b0bb738b69844e9a4ded1c8bb24d38e9d94e7dc9e701653d2d40c97ec39837f7101006ab270ad6571eca9efd87ec8c6ec9b12347efb014d0c3672d99ce16532c3c96cb019d52d8c134126bd925d671e91059227cf7854fc2c9bb89667f05f94249ff4397bf97a26ba08865ad7b3e586e4cf94c5432385a8540e2ff40821cf2309596fe2578e72a39d7adef99440320b8075fe72c149515abdf0cc472162843f344ef0a07645958e957757f34988e613063e5e9d074f5597ce0552e914206d1be939fe4ba991d829dc13a7cbc4e648d7de95e5b221ec3f9d34aaaf0a3f988f02bb74ccf058ef65dcb7f62c473de3a2917ca254645d300712ee6e8845800e9940c251df9c5beb93ab25745d89d7323976bc1962aff6aff98d27c4c62bdea4dec3ad8d4cbd859b4c9f2717424ed7ca9ebe941fa7acd84f8de5f81fcfd9d4a4dd142ad5c5e1275dced2081a7aab97b2a5ce3a65df7c0fa90b5bd2d9c2d2ea6c0e0a77d6bba79db52b9e7699bb497d487437173af26fcc4e732d1309557f52b53ef14d7a58957413a10f4314aa6dffe945d9dd09b1bb1b1928f27f70e5cfc6767cb5d696945974e3d5c3fbe7c7957e49b7ffcfacd669f3c6b192ffa747f33ff3a1d4f3e27f64d731359d9499365a6e144c5403c756d9252765b5d13b55159ef3c54009510c5434f9c346ba705a393621473a36759c2980df9646ed7ffdfca6232a3b42949d3f6eec3ff58739e7bfd79b91a2bca1e9420e817227864053fa2b62f6cf7567a784d8a8d3eefc4056ff89133fffd8e38e591eb5d3a8eac4e8f5824cf7e6fe46b495a7cce5782c957a02833be8f69757ff83a760c1a700bea4ee54e6676da1e6f0b6864ada9d073f4a71c9c7596098b2f3fd915dd8203f30b854ba7c1de3a85db71c7f3974f2817a3827c51f0ceaf8dc47ea7bff9956ca6723f433bf4fdff7c4fd9c3c295e5291f5e2804c1fbbfa777b71f5d7756848f6b470fccd4425c155d082d15210cc990964a4cd990956e492f4cc08082ef242d91f62efe45d116e5e33324fce5525139b6656bfb2b243497d8272d16d9bb84963b745baf1c745e040dff6871d90f6d6cd044a5a0f932e3bd9d8859271eff739f7265eb248977ddac97b694c64b6fc041e04c1173ef6d34b8fb1039c6c1fbb51bbb9c2505b2b2733462ba4862283cd0848c56fbbb6d1097818d3c97931718e3d21dc1d5b0582a593c8bea480815fd4d7e9fb29bf3ff27b0e21742b4774a106edc3c0581b4a70d0c3341f266965f3b09ff7446f7ab5e6c52cacac503f334ca30dd935136fc12906c7fbfed0808e260c2cb549e2b0774cb583a8dde0edc70efc75f606218b736429e74c4d1c7b84f11439bad4e81c99484c4eae124c72768bc4e6472e087c6fb83c204f883733643d09cfe6fb09f1e9ea6e9282f70113a8b75cce56535a7bfc442f348900775d39288b7099bb9de9d1e94c56c997ab1d77737ca98c56d024b144bc5af1fa5f1b171dcd29a2a3e5c23b825b745ab32e85a827354bd7178298bac209a1716b5ea734a9c5dc143a995a068dc7f8cccc980b31e7d5857e728d5a70d1b17fb9a8e517b6e2a2c10f452d57a635170d7f286af90915406367ec51f45bab1b6e75fee70eecb8e8f287a2d60c1cb868f44351cbe7abc845e33f0fabcc45b77fee6b958bee7f28ba91426d4120eb5cf4f843d1c4bad0e482a53f15cc71c1ca0f0513d7af512ba30cdcaf9c1f60a058e9104f53193d13546c459693726007c3ee9c23cb5753d09d68ea24bfc9658a7feb1e1555c262d411beb11bfedc76ea6445848e850a9086216703d0536647b0dbe26d0c01a6d2ce67a397b9f3e5f6693d7b80a4700c2cbd3c44079ff2b7a40f93608cf9ae7da9ec2af3988451fdd8bf54d632c360c5acce0653e7b4b7197085c5c8fe0e13ead3ce5a8fdd5478da471955efe64b7f03990d6a72cc8613fe24d216bc1dd9d3b0c953abf9244fe7e83335099a62f4249116d5fc3b2d528eac4ba09f2cbe639968a958d572ef7033c5365f29924735b4dc09e766ca5209b1de04a16d70a043b399a6d1f18d9635b301d30d47c7821fefa7ced9c52ad12572dccff5d97a4dad68cc53e1eac7bf4ee42cfdc1b86c63126442447b066c82715e986316391024365217c485f2147e43252bf4e8c20a146d7ca606cb2246425b94d9c765cdea73e014ce215832528575bb6fc044c7963aac060335ada0b5af016faab739b2d63db1a2ce8dca7ce52482bc57623b6b028e0466674ca3793f9565f5581bb63f0a77af749f8859b64c835a556cf99aa544a715570132dc6ed61858cbec096c76377ba9b880a272fad70bc74a7585b596c90d12f601fe46e1c2fe3b248e0dc96666b706268a214f9aee8f71dcd41716160ef420b746253ea0383157384700d215799041681bf2a6a199ed90dbd34f3e441bc9a15ec2f0bc9bbbf5c910687a089e9ea73dc1d370986b73842c62ee5ef6081744dc9a65852d66ed23964186ed8d34120fd6b7c41060739038e6fb23bbeaf3157f19b38b52623aaa3060108bab3117601f60b3f3b8dee4568fa6e16f6197d821ba2feba9424d57db7aeb9002dd2df2b53a09b53ee293ef6c82d28fd6d7e9c6c06c94aecfa6230bc582d3b001d1d85fffa14345b8e04e0d4ad341e94d328378bbdeb1b890743128b2d3cfda727f9cf31638e99afe6711b2d722659acf6c20b5ff06427998f4aa23c4a6dd5ce36e15859653f39a3f1187cea946207bbf3f3929f8145f432a6be7528d53bf8c5191f45b5f4131bda9ac48d80adbc56b9bf21e4ef6393ab4092da76dfa6bcb431cd32db63be2805b320abed5416c5337119eda79985e3ba1c2daf1e0f7a173760cce06115b9d589a81ebe2afe9e24f6344d5114a6eb7558361857667b7b2a759a079ea6e228b542d2bb6b860086991671ab9c98e2fac04a6cbe72ffd853b84e1334785dd42178263f66174b46a6407396617ffd3df53763689b9c7e5b2e51db0e549e11b03fbacf3af59317bd134a3e35b9f6e34e28f347dea5e6ec5252b32d5d3c6a6238f20f29aa8190b1b1bc82946e431bb6614b61c27dd4b74984d16a45a99092559ee55d86c20269bfc4472fe78a375a4efa31299ef02d80676316fe3ec3a6de24b5fcb2e9f99516b32756f4b760093196932f32c6b4051c7bcba93081c893064e67e0c86cca7867fcd60cb74ac42464a7579f1bad6bb04d764c6bea83fd5cb22482582c4c0c45437c9aa56914c7a539548be6f1423fa390bf77a76673c8d2670211b257daaa0e92449bec444fe5e75c55ebc66eef541492e81e6f4e8ad90287bed73812f70e09c7308cd93d02a4360a8c68e4fa2c1ec673bfec908f48cddd90f789a12067b7f618bf86657cc1fed794f001354e64810cf943f3db2356ee6f8c6132739aca6cf9610c11b25dd694c18ac96ca11a811cf2f05b13f9e0a9515126e3ff8b65469a7be93fc289d6eb30029f9341935fdbd892e4c5bd58f9be4c5a6b680f1af57e4a52d5235a74a4fa671cf363c71663ec5f92f66c46840588d80663e6ac60bd543a42e4e276362975967476577d973966907ef76803098c065d65dce6c320344919271456f58b7ae5d288107e20ad15bce900d9e0e67e819f3c2a58bdb869a5cb68db2b7508574330e11afd9b4a0b732b06adc0e4f61478817b43a693763d674f3a15900877a50f9c2a04101960828e81f70a5c0c2add9e93b3e5f3827b507d05cbe32b1616c3c6212c379279d11ebea955ea4ea690800d734b26c8bc1eaa1c36f5876235b539f6003c34268b8ef39e7375888c5ac029bdbe5d34fcaceaccbdf9cbbc1c7cd3c5e54392662cd7dba3a7b4de2d1dac85cc4a3fe5ff2feabbb6da6571f873f90bc962a550e498a9215c7711cdf4ee29ca5d8eaa21a55f8e9df45e0c20c86a46ce77e9ebddffd5bff93c462194ec160502e00a8a9e37e61d3e254fe631457a1eac5d9838b60db525c424eb166c345ec6673f0509c47f408e37e568ac390a35e22b6d60f297f36a93d2c4a4e89027ba1c93fc8cf2c7711675cbecb586c12e9a1e0917817c9484646164f1c1e8727373b5601178963f1f1061636d50994f83c4ef0f1911fae596a637e5e5fbac77ece4c17279158c2499adae650864641956cfd79e1f31c58f9b2710a95e839d923e293d6e4b9c072ccd17a84edce5bbe2d1043b0b3c358d62c8894fdc63de888461c45ecd3dab18f411e85a9fd681b51a63d4f4bb7edb0646686c06fdedacc80b5adc6ca9aa77cb3678d6c58098a2d4a30ace20579e0b9e9dac8c9815a9c2af7d0e43013b0fa1ab098cd0617cb628aa98187775e5988d7454531196861c698be8fcc8dd4d02863d86d4ec073cf6d11e10b1a06396fb7a173645d38ad8e2a70498c62b5ebe281b64d5506cf23f6656f79d180136f1999d6393bf2872672633deddc58a3949f9356947c4277f0e987ab4ae0fbff106b3c0eaeda811ff6be2b856cb2725039d68c756bd280b2d78bafde4956e3ab4d4819deacd56a1c52dc0a9de36874b62ae25ad97d830bd3d066a71de3a51473461daf980ca700f8e30c37f7223f6c322264be92dc5f66fa572b6dd067a476bc12232d2b8f605c048c4aa2c2c11b59986c263ff33b677ec79842b6abc2c17de7fb8f20218f1c7a950f9026f28c144bb803d09d8a5ddcb34b76a98f9a0451b99383cd8dd5186474511f3412d90b748c439ae97c66d2a1ba7d71df9ade26070cf41fc66bdf99b0d09f13988ad1e07ac3009f1edcc25d567a9ee4f706bfb7b9fb44ae076840c93c745e6a74f8a1f5ccdecff48b1927faaa41223fad8aa74e3e43405edcee22050e9f7f5fd4a4183ff14a1993f748c500f67ea47efd11269f204de00a99b44a766c2452e2f200c3d7ea1503c7d0f7e79460af9a939bba3b06f61ce0664f6a0c2cd9205f145373a2483b27231ab78021777ee0c13c403cc153514eccb380a8a035631d6008bf914a328e1466ec58fca0aef3a6e4ace41c58c38c90afdfda7533ca6158bf55dc67112bc7df183f26b16249858ba43a615f37574548e1c8f79fa0b97c31acfee03ccffa57f610013f743a685f09aa3b733c92aea53d027da74f652999b0b2bdef0982126a508d3d776f5232899fda5fb7dd881d218656cf2b75073591895ad019b7ced521751cb027ce90e2796cf095c6d88d7c73f5e48727ce99c7bdc672f397471058e9122fbe44552866ccebfb09ac9cba812482bb4fbebffb94761508a9d6d509e6d9e41ec21b4d51b03b95856d0e11c08b8be7e6f208cf12a7911c5171db84b6e49a16ec0149b49458c36aed68bcb3743032f514f8714a941cae190fb7936f947c3f17115d12f0d48d23eba93d1ce11267c98ed3510930e603af54b61d3d276eec8a2cbd23c13b6c218ef261f8508949029b075edbcd24848fb86d6d3e143c5a7a3cf35dcecd6856a18db4b093b576cf5b07db195e7fcb8e173b47d398ae4978e1593f3148a17ea497e6a468ff396b75b6cbc3da043267aa99b1c522d58f05df78e3a8d3d49a0140b9d4dd6fc7766595abb02c12efd68f26dcce924d5e6b6e88bcf75fb217fb7b72323df99788c450c288b2da45e6f46285269b82ef08e452143712cb5db14780b1d6c76e08d28d5bd4c0f0374da07054e49d5ba02051ea0f3b40d20dad9caed5c747aac20dff574b2215054f3aa52ad4f564c6f907e56e045f769d5d847329d9b902973553d2eb78e5cc69e43c70db6b85411e996473d2adf3579ec16ba5475961c0788b19e685a055c83c2d9bf2793845c0b24afdd3c64ac9e3306ed4b4eb3b9e28f37da69ce79791e75714b56cd229d70a32397da00fc9ace40a2a353ee706ce47625315fc401cba247ac55cb43a41e96428e537e4ece5dc4aae1c87fdbc2587ac91e30c0a53aada714a86ec570eb45048cd78f049af7352ddb67a81c536a4eb3027f5617c128f0c52281f5fe8bdbc3140e9874ba076809bd37b075852a8c334b539bd3d4072d3ce7336823b714308b534da2c3e9f849f90e120bc4063f40579752741ead9b3dbf525f6228f9f531680eb1e878f4c972e0a9499dd32a81cd9f6b9e770d107c58647b9b422e7eb9c8d2c7f1499b7e42c91f38901ccda7d09cef99d3abeffae7fcdd8feef9cb6e6716257a603fbef0e2b357aaf045b1f2315524693597aa26f58bff3541e3206455dbb07beea56d634d581804a6a5b2af4ddf402ed861e0b2ab094ac5fb5cf5d363dddc983c8b006b5e2a6a414ceddf65a5f5cd022894a54273df4e60f6fe5a1ee0c2fb894cce0e738efcf23a49942c366130b3a8b93922f42e74e948b8e9da274c4695dea983ad5cb6a6fc0a2c682683372de10750a0d8d117a59b3c7aaa1dfb38818377e8888504039d70574b30a49766485860ddeecb8dbac65ee5033b35354366166a761812df1702b4c300d5e9cf63a02ecf970e2ed3547d87c2ea90a2b0d6d6511b1839b96bf924766db81d10436b13e2df7b287cb5d13abda5b1baf7ac6ee6a1d6699a76568c12015cc6f95ff3fd297b7a1b690e18901d4265a5127ac5d9eb048d0fb746d4518926cfe39ae5deaaa7113770a6fb9cd9ff3c66e8b881fde6998ac3922f7cbb3fa2c289e3fecb14d750c78ee84ff6fd37ea80f1c3f3f4f0eec058d159b28d61e57e3af75fa57b5c0f76bc16ca32963ba61d0d598a7546e2635ce697d4012bc654f120b2b73c41c9d5ae880e54482f50557f34497a141fc72e5d51bdfffb9e170ba0dbde10d7af540d977bbf5206fc87a9832d837155f954e1aa5d15dcc77bee980fdd649eb31968e25e41a3c7a1359e0ee1633b2db44d6ae25b0ca447089a4e7e1e271c3f2f0ea8443c01c575d088e3db07df9dd39a87c07a1c7a1c167f429ddbc1e2344bbf3641bbe730a06b2c3a402f347b545f8dd063db58d267c624e8f3c5e192a624b32858475faf539d282d1fcc8535145592028104ba8606b7eecc1117ea847f90fd536f92f8ccf6ed3d96fd526591ba14e85bd5be5a06a6e2eeae9b248d28631f744a58644ba62a25cb0960b140e6da71ab33d52294c9c9a62ce9d25c497d54e6fbcdd9a5b1e7f7002d889ba30193b66ef7b2d064033c035c5c3e42b8c96c1a7d4470cf04d5acf86404e852fae632893106fc53cbad8396ec54bd3016734cce48733f38792883d3592fc14cb7611d731db445c2f943cbbed2a3f87a9df75b03c52762c450560c0f0d598dd9dbd2b292650f24336791df82d53e8c4102aebf15dfc7f973b78b56ec24b59cc9ad740323091f954d9401e38b2ce353ca46a835f737ca3e6113a844708d2dfa949db15593d5440d60b887d1f393b711735ac7ae0e4fb39c81f99dbf695c01eae1be467ec1579506e61538f5fab3f2a0d2cef51a2f31a1bf574b63034b2858ccc9eba318a11bb9b8ee7dc2ba60454e1ce3d941eb39b0d96d7789ee23ccad73ab06eddc296a62bcbb53de808ff901bc3d9a0e89c5194e1c0dd125c2c9fc020b5aa998c66a494b3b95697251f2accba749f2d9857777eb8ffcae4b3d55e30f977e4bb195cec3d1d8952fe27a93c40225412c5e1aab8383e4485566bf7be5fbb6f569501b885845e57e36bdf1f5f7bf65ed8648f641b4f74b617cfbc4865ad31074bedc47ca187f7648ff7a470dd99f72fcbcf83039f04374bf8aa16d0e7927608f6122a47c539c5e1b92dfa3215ba284fb59b6d64675251c5134422fe2b7ce399ece02a7f4618fa0deadb13417229e0bb942be8643db7c5554cb2aa18ae5c8e7be35088b4f8a6c9a582f8c1dd5b6b12d9cc36367c6ca68bbc66fc954adf30b37900db6d63aaf6e945f76baeedbb3a79499fb239ff02be8a656aa6c47a7fd6c01bea676329b56a68c6d0f9d885e4f14018f568c23ad212c79ee08ab454b143bb1df044c8ddb66be9e882645183357d7fd452a88e16be1a62b5bee4e11a38959ff8896cd4c6d22e42247be8b97ed7c13a16b7bc350e29671304d4697a96600bc1836f047844723e0ca2ec4c9dabd356f083d231b110d588febb54db7edbdfa351f93adb507bae0d4afc0dd2844829b7beffd3dbe41a30267d369c1f76f939f4dde75d58ff019435ad8173ef5c46519448ebb8d24092db26b47e912aec8745562d2e7805676d9349734a27622f304b4e3a0198590fff97addb30a32fad548575c63ccd319cb4b837b3cb71c5a26c1c87403590cd6e14a1654d59de0e813d30205910399c60d43623853121deead53033b3dee616913177f7bebf0884558ba36fa128865c407f5898db4639811b63fc2faea45e4471dba8d927d6239bfedcb79114dd338b6ed81e8b001637dbdf3b498636424291d96bcf8ce16c2b3c033365c2b39f1c78352758dcdc6565156cee9c134b8d2de3edd9d894ddd3d969dfa1a01b2a98c8fc9c23d8115211abcf82fdbba6f44c4c99ccf57bb24b156041a58e8fb186eb9a96a340409aaeaa27a5d7eec0e80f817d7abdcd235e4bf2554fb11dab659a86a3b275b1dcb39e9b0ff288633123de910dfdc92e0bd3a910b6f2c4064bceb2bc03dbe7ffb63a00768786904e7c8b27f523091e418272a47a39e091a31c9da08226ff9ccb1c3997ed39632725c110b7673b29376a2a62698951b5378d5ef0ea14dc3a39473e98b6ef497bca0eae2ef65fa2aae93e51e4db131bcb269520cfd61bb03f717bab34db856195edf6c75abf207dd2f17244b5f8a3a28d032e1ee522ad3d6d698a4cc5d567df7f46532c25e10794401a29fd830ba5ffd9a748947a82bc729fff073219fe33a10bcc9ce81fb75ddb1a3217e03ffb3d9b20ea912ab0db3bb97fcc2744326758b16d842cc61086f64560936b39292af70a0e6e36f59be95f7305b9971a5fe1b80ca1e2d28d698dc19c12a857b9b6474677603facf21453d4db2dad016a8945310a9c497422070d5ff33c11f4f53b7d6d5c6741b60a0e56abd9538c0ea9913a36cfb839736f3658f2ee225eb0099e43526e987e9d4b74633b5bf6f634584ddcbc066173162c27a0fdf88befc75ff28ff843794057dd310b07bfc166e0fb9bc141bf7b9c58ab3438365f58d422845cb1b8f0d919b60077c157877ed8fb457f868e7c9fa4d15537f0fd2eb6d549a43323941eb500922dc882ec0a796538afff3b8ab8b636545f3160081536e43412380cf29e3e012ef3e0b85586be0ed3072fad434ae8aaa298e9937dedacab3e9a978585e2eddebbdea61af3781161633d293479e1c53c1ea47b1496728056d0b7d357bb7efb190e879741ef5fb553b751626f7065f227778094ac8da1f59f615fe604a34395af9e9e671f8a87b72e27b63512471b199f166d64d3e6eaf850eb19c9d67bbddb9bba761e35cf25333df972a98191819399256a179283477963feae1ee5c4a09315bf1fa4d0a8a8a1dba693071f692fb4ede115630af19fb3f51dc009e1ba10e00e88cfaec0fd66c236c1fa9e5cf349fddae21e58724fdf3192f4f49e552f190bbef54fef23805a175e8f7279933b5638b9d1223f7f80514d3f8c40f77aa3234dc62aefc31c53c36ad87723fbfdbbd696688da7efab1113ffaa35e32670315e2d36b0cdc948740a196b9ac21c3a877b1c0719476b367113d57b683960eeb9dc999b4ceeb09d51125169771ef9f4a997f7833be9fdcb7e20dc0d0af743e7432365884b337d17ff218c425a20fda1cdd49077f0d5956b541d4f1530b1cdc8cc2bddcb6832c68ff52652b5f6e4147e7da7024b400844715ec183f3b52e1637ec82fa89ba95a8885d81e4c11e5c6f07b9ed2f529c091674313422c86145375826cbb64ec85193034b0ab44aa0a95e02b864f6cd8a93752e579bc7888e06f8232e12c455d4d446e737ce91d339b12dc80b62b0a2f3565063d98d2a0ab3575227be4ac1c22fad7e5b855ffd350998b9bfbaf1c3352b9fe344293a2670853d014b763cf28f392b17253f1ec4fc14da7c25a1442046024f7f2a3e7d0b096718b265b1d0c653a66214ae7e132ee0bca6da55afa90f97b7fb9c2d10ff3996ec16f9deabc7d5b7d555f56d635774aeaa3fefe1f277ff5453812e87f517a7cf6a244ee72eaf8b1ada4f9886473a6ad0a42a33f266fb5a67e23896cbc4c6536668900bf02a995705df99d7386d99e7ba0649fd813cb3aa737cd3f2da21cc49a2763ee4fa5d0b35cf5a91f044a92190b4ec116f35819fae367ae3fb8b2097d5a94566b565b01dbf12ed61274f6b067c200afbf402ebc55b70fafb2354e4746a77af9e53277544db0dbaa440225711ae0060e14d2d8c746871c95a4f1efafd7f3c5894f9706b417de91da3427ee306ac1e69aaee35f55418e80c75671258287803a96eb798d6b9d47227c10bb52753acb5ac79b6b80f7eb8453d3548289da6b298779bda07cc5ccaec96e636b23f5adbc88a2b5e4d1dd3ed5aa037a67928adab876a75e721b3390f7bf5c1e3ded9abe6f94ed2b76f9cbeda1b3b4ef296d15eb8f8476dafe6a908c9f47307d019c43c394576a3623fc6883da36b1290162791ce6c5908b41ea17650e4a0cf9c666da8b61ba6bc46eca3043af3076625d1c5571441c5fb5dcac664cd36b86384b549a277f5f7c689c296c636638420f03764c76e50148d51d2bd92c24c2404c168c522ba77ba60b492a0cb47950ff0d696b3ac7225bfb6f2f57e500a810583dca8d21dda71abafeabf0178bcd48a755be994d1822c1198172d01efde0a2f71cf1967d2770c73679695ea7d0f4011c57f925a5f852a01ee9787ff21fb1b1701ae054dc97604f8672fce5bdf2f2250b3897c615b1154a90384acbe968d973ad2b135cbd65d7071885ae6b78f7dce0773e3fba7be70b0915407df0400173ef89c2464e4fbf3308f4d27a8358a762d51e7588ab82771684963725427a480cbe2d0c2396a6bb8cacf913e2bedcecf07cfdaab2676496eb17f0f0d8920aaa8f8c8f5ecd7819c4bdd99f37192603f58d4d59399521778efbb9b3ea41a7454b5700601bce686bb554320f438c4b931d407b7842b460eeeefc800c91868aa5fac1fd40cb4cb4e909bc5d242e28a9d07e81581c5747d32d707beb94581b198c0a523134cbe70ed57ca4e4d0f88171973d9a3c896b0f999f1e5f33017d220b0c5842df61380273ce693a9c70e4690caa61dc8ee772377bac8c96e2528ea83272666de8b0d9523ac89140b6d55858d9693a705dcd680e73cdaf0d560727624beec0bcfbe3f0e27f3be2d95d3a3240ca1c7d88f8a07ffd2b9145fa9566211398926c7b0a42f5aa18d733dd4002ee3544ec65d695359de4a9e22a9d0f9d19a3bdfbe44b86073c93851a42080fa5472d6883e140b2900a0348efffc06fa2787f1ca5d33856ae4186ebb3885b0a3733278b98f99c1c917bf51b82afd995d767234e7e507be6a24880b97ed414d9efbf2f35b5f6621627e6bd5654c1c63b027f308bdcc4e36da18775349018a47aa017a6fd3bdf04603ec7092e621545a4805ee15886165aff41c57be9c65967c27dd7e9eff59573c679458b0d9768a0eccd2a28c3c4f9daa5df44fb31dd983ef9c8f3ccc9dbaae3d649d8bacaaa030c2d5d01f8c3f5cddfa516714df67bfe29bab3b3ff23ef8f4e303fde066ef72dff27459081b3073ef0f6a19014733d1deee73b9cf0a23748f4c78733aeca76833e5aece81c534b654f49c84e5907cd80878ee718989888debb01db13393ca8f1f589e8623a67319e21da74a87ecc822b839015c5fa54cb304368cbfe4162b0fc05a2e50de12d548a70b0b1ea0c45c7f660b57f94b8eb4c5195f22a1bfbbefd6c1bb2bfab9f752e787d44f06f2e68950c36a4d77f3be1d332384c15bb8374b5be419bd05457c3013c427ef2dceca5c7c7505e73270e21cd3fda2b749cc70bc9b35cca6bb14c87372b1e1a2c9944d4b3bcf5de4cce26f3c698cbb7291ad05825e48b54fc5eec3d79ba369c145296dc9ca47be8ca6f12a250c0c3bb96b15c1cd81e1848b5f0a2493eabe39f06e37117549afa583431e7ce83157a9a1c57a5a547ef21bc08c8b6620cd072f3a76900aca7f2eceaa4b1dcd649821e40cead075afed63a93e382d4cfa925685f21c39d82b500faf5cb5da98d6bab8e5be9aee654267c82658892deac9f77f3989f6589c48f8ec4c3f5e3885add1abae8249459ae55417565e1b3a357d54990323ed3ae50e6ecbabd886b33169e10fc8f56228d7b7dbe088c8c9665a30f98d94a0b8ecb874234ce5bce0c458f50730ec664c5d36c474ec8868cb4af21ab159f6fafa64cd85118ab5f09d8fce1bf6bab786b5873cb9a0e88ebb57ec0cb6d2c8ed624ec66ec62ebe0f40aee6421903f3d0d60e273e44b0aaa440c71c2d3a517e5bca7b9252917efc61d5074f9f1639f37e464265292a1517c8b5fa87dd59971a7ce4b0da911fee21c18b13aab8f64315e32a34e73b2b9e3ec86a60fede2291f4013b7092e649e0bf4e1aac3b8c01db98d4a28b54913e00eddd7a70e642c88093e6a50aac28f0d219fecf477fb6532554dc942a0fe6cff0f408d9deecf07ee1242719907190f380b9c724008bc69c4f96ae80413ad50347f8d1ba773d3d058b36f38c791b56a39815e2d5ccf1bcbd58011e685e2d5d27ae3484dac58004a01a976f4f8a16547c245630a971145210ad0f51bd3efb5faad76b0f25655c32b8ff88b333a8af91375e2606121f305f2b0547733f7a87adcea6b371d71ea330baa96512c50c4ed5261dec91670148f91e0f7dbf35505a3dc9efb3214369976da6440f948742bb9b36b0b81da0a1510d0d0e8055d7550ae4ad2f1c0fcdd17de7e004fc2cea1e242c43cab6e19e22e727f786010778a0a57991786df9b9842b06d4d95f8e386d7e595cad70758ee9ccf1aef9bd712712e73d656610c2fd8623bef54d7ecfed918f8b0b3e4c373b1dc0d46bf352c5c708fca5461be9916f0cb7481f2cdca9f6364605a3c9f879b677f69df2d0d9efce538719eda9066944dba0c97739a7c14fd91397bffcd8d5f2955d8f6478f925b10cecba38a56a8e7191aa780cad5dbc1114537a8847a05d53b10beb4e5498804c42193957b76da7143b3b93d0835e4d6bc58d9a72b837b100155cfce82ccb71c990db98b8cbf5e2630af23f7311fb683fb60103e1b8c2a9f138093bd4e26e2fd0ce509acb0332fb6397c826da6fb4bd7bd70c9c3200d96fc89dece6941bd31880d23834bf8d9bf584d47119a14bb23cc282ed4d596a9b627015bea35b2b79511ecfae2032181dc38d64c547ed41fdfe8d551df550d2c46e94332b50f07364bd3a60e53708c73e32ef3e7124d9994fa85b05221ef9e1facfbe9bad51ff2819bbca7851987202e41938abfbe822b0849b63741d00b6841f0ad909db64d5bbc004d678cd2ec3c06117cba35c5fe1c9b9b942f351a533256afdb4e4568db5da796345f37395a36d951e4cc94e1e75412fe34c0af5555379795d2fe885711d399ab76c4ee138bcdd27a14aa6f65094cfb0f794fee24d0298389948b67dbb3fd36baba03b1a812864a860c794f2d152ea1fcde617bc0d38793fb24a8c03ab2bfeb6273b1f244b3a2c66d70c3c9dbaa99e3a5c47e55bbb667f674dfd2e3c955d3d32516d9c94509b25a233c12c68c0eca69b77995f9cc091442a5dfe61bb7c8a526529cae42188a2b964aeccd24863095bc6af8ce0114d53fbc59ccb9d72ca23b50fac24726c42c17ae3b97353fb31cc28ac08882e3cb24a2fa234777bb9529c7f854750a821e5e9ddacfa90a8d812b05b65341b2ebeaac6b77833a3e5ac698afe42d3dc933d79036fe78f786b64abbb1af186ff640bc61e708d78d9b7a1f5cbb3936ad4d8687b8f25f87bf03e6056f87edaeb5bdcbdec06a2556a2b5bef0ddc75bc714b1be6cd8e86d902691a4efabe9ff4e3dff6f49c6ffaf225f2287d2d6b7213f861e7194d726e64d3e4b9effb67a7c9e5a6af333ccc4a9be40c9b6892a1f1a6c95adff76ba6499ae74d5f300ee1e451f90db68d379c142ebe4d10e70b24ab83d3bbd28b94e7c23886d800d18bcc33d6cf618b2c5b938b9839cbddd959fb2788ff3d56327e5bfffb2cd076b04a4c1333e7e9a9c69a291833b951418e2d030089eaf7da31914df8e92b75b6c262cae42b73746ab798c328ba508d9b2e6cc410d0d3e19f8519b796a7114a7375f7b2d75439d366cf7ae6c51086440ef27c640bbad49da759d2ce3dedd42af5f07ced33ab4077beffb44b34b25d284772e20a58d27e1c624db6c0b386815bd82221cb18ec193e223bcc79e0878b8f57777e3fbe953a05adbdb2b1d645e4e1857e6055650f635c7ebe66b9ebd2358ea85875114bd2e6610e8c59e40bb346af0353b5a8d597f4e4e5168434a2441e80a6e0a39f39df00216cc3f4a5feb994685c05b65b47fe2b3ed6bea9e0f51a02a42877dd6f33f9ea856cd7b4a1df4f00f0b5a515d52f1a0bb490166df0eb848b677bf537b803e891546b28fe8746a81e10c947a3009715fa246530bef9245bcf7ffc6427cf62d47b7567931d1724313d549a7cc8dcdaf36d0d82542cebd61f4e9e1a0dc0b015c10efd01b3ac279597d09cabe38aa256ecc74303b1af75feff29cf3e95336c8350271d48d5b71ddd28bcd9a1a11d96f9f4277624c2ac6eac90285edb2aca4cc090b2acb2a0bac2ef799545b0057e973d7fe77802e5cd4d053eb9ecc7b612998b04fce945d62ff5c7b9c53383e79715e52a5d78eeb1bfddf6cd43368ad18e5591d72fbbf9f7e04df38a32832ff0bd23bc6e0e1544b37fbaad90a8a0a3a8e056a5f21ef724068070da014c09191da6f89e1ba8e3df9cf1a92ab2148805b0ded17a5af608933222793a4aa347c84a60cf035f9e212dbfa2a0d89d9d42177677e5606917efabc08be6cff50f0b4bdcfcd07869f3c862a3a08b993462109127fdd9b3feb1f5d4633bafcf77ccc98db0bde67f8a09b9953a78020c9129ea615d35b0830ae3851e93cebcaae672b153b69b46bd2cc013895448ac611660e4ab6edff7bb8e7cc54e34a854f56699dd9cd3a534fbc68d866c3dcb5f1c4a60dda2e4fdfd986f22a3b8fa34b48a5accd5c0867594f0e8c2650303f4a37264379a8acb94a3553a7824971d11f61bdcecf1ff5ca20b4535ff9932da17c9019ef29ea40adead368be856716644cacd673a7dae1af0ae2435e4d17f5228b9e604d1cdbc4473e4dbfaa479ae41db7147172dad4299d27cd19495f5764da41c830ff0d0f55a53e4077d55675a24350605c25ad766220da92d9133ebca98a03ef076feea2c02e790d2cf223b2f2d063fbb6a9583f11f514524fb316d11fb81312d65b0e1972340876bde118fc75e5fcfe11226046cbc48b774a312e8ad9d798ce17854934a7f3e99103a96129aceecdaf42cdb5609793cda74b1cedb87aa22ce0a7eec5f6961689daf171aeb57a3313b896ece6cafee7db223e87442a51d731045b4572af3b31fd519a1d052bac3e13b533837f80cb734034766dfff952681d3632c8e0cfc3f66fbd29ecdc212f486e477921aa7b5c97153332d9d79505839caa28958ab2f565b5aa2dec8b2a5ca5db2a365dd5314d1c28f356a33d75aa1dd07755c3cb6d4089b485e5edb71cb92644b8dc654a7ae026ada9e3bd5a9eb0808de7cb127c5f68b5ce25a6a7072b442bbc1d3960eb0e07f25931f443bb6a754850fc2907ae7acd3d2496e98a248145c5f121e0a48a1fd9c24cfdc8a5a52c7e1d75ec0d748e8464954c6234bdad04db60abbc2ed7152e933cec50e316bc7bed46b8556034e1a268144b87d691c14f5aa9cb958ea6c3af12eff49939c4bfb556d150ff99cf196e1bc9220663c906a96e341eeca84cb1960a66a68b9ced6a35b478260163ff514d08592a3ae181aa582a343fda74a7397cb78c776bcd55e89c7d324d0f65af3e7fa1c965e4795375c367f36eff5d326e86a60a5d9be7d2099888109013393be7d6e3aedeba60c43a97b05ab71cd33f405b8630378e1a6fc5eb149b029ce550fec23f77c64add31d4f9f015cd63e2fdc7a0a2eb4975a5163d2b21927f80bde677c26f148857bbeb68dae3d23dc91e6f3513f783f99a8ea0bedf1e0ca89501e3ddaeef6deee6e97ba1b3639e4e080a65b25fd5da153c7627fb7a5fdc583f733dddfaed3df8c44d8d0c400e449a2a8af26c67422b9a6a22da507cd178aa2429d2d3b2ca545e74f836c08ad114f3184551cdae23395c4b8c1c8b774d2b6577a2a9b89f354bdd27dd72b2dc9b2955ddefe7053d9b8efd05f4cd46dfdd65ebf15ce2665aff103dd8dd20aea3fa8170947e99f7ebceb808e541a80910d83674f20a293b98b4098e05c61a41e9042341f2a46723a320d92d03ae890d07b2f6e8f0485070f38638ef85df59869379bda6d7c6b4c2fa85731e588a7d9379c77d9b75088024fb450fb7c564148c739c2010b5e80df5bd6571e3727554837023c634ccca9173a009b7af908ce5b26812a0be9267ae0def7bb01b90efe917a3748d3f4539da117ab40dca9dfd98f6f1bc17a184b05fb2504519203d63918fadf7e98f22a01c8083b26fbd9ef24644412602d78bb3ca71076c0f486d846cf270f9f7c22ce4215b7ae5d82196544066e2cdefcdc57781d3a6387b1a2fe97279ce69bef8fc954b6ff182b9ca1d0a290cb0eb9339a10640c19910999290356637974c2c68e618b45a10927a8693571744819fa5690179832497bc9112a1d4e50c249e98003e2a30b5ec4a50dc1a0ecc58cff32455326a893225f5dc1dfb70d0abbf5d25705e3ba6721750ab165698935fb304ecedb35df26b5ea136f90dd8a1a7f9a808e621b904484fa658df2a290df15e4e816a2e624c0527700ea72f1a4586f01ff666b37823fe58308abd49cd4f00af424946311cf2ac785c39d8431a1473b9829f7f83f63ebee8bd28396446248d6051cb92229c443fb62f62c35604c8f29da3db0748ba8c4034ff1fca000d53d821786cd970b3dc43bf9cf2700b958b53feb0139ae3ee0157ee45671e34ea418c58ea67d4382e02c18639802b538b2849b040b2e2c379a70e9897b7cb8c3e2f3442b0a82905c1501a2f4fb567d7d5cfa7521baf9a5afef4175fcf5ba86a7b6e1c4e8b48b5fb7840367468f654f4e1421fdf6607a939cced9dc262ad1f981b7349f8bcf16e8cadb505a1144cfadd54a1327c180390b11dcce9182955b7b7efb666bddf83eac31b59d838cde4e59ca8671c6bb56bf3c52ce9e3ec8493f542e0fe83223150c6c94083ade4c82187b17c0ee54fd88fbc99419f41e1df94dd3f5cfd5b31f7618e33fc713d576d19eb1c3bd4ebbe09881d7947e72a4d6f95aeb00ea467a9d570eaedce4b7c2319b5c955612050004018464a46f75464af357f8e36c402f7ae1dd0fbde4e9ac9dc32ebfd8293f62ec994c4e7ba8c8dd4933ce4d91781ba50073397054f54b609c6b7605d7d05efae32a079f305a8d6fcc40d9a1bb1b6815da48ef939f7f67649e0e7c7f3ad046e6e5413991cac30f8d121bd6bf28955cc0a2af55381fb34c38f9a656438aa9d00b3dd4da1e77d9ec35e9ea50efc63e32519bc398d123d475317590ab9511dd1df64e12237fa4717fc4d6652cda390039ade69a4fb28c7ead2324367b80c8255f1b18dd6e4f077632d823773fd70cdc938ad38c0e7bdd6e0500bf2aa49dec37e92e9ced72bd631921deb3025d09fab46c2c78a5f8c0791f222d26553fc3d5da3e84a584620770b5c1cf6e827f94b19af9d862af122cccf10317a30bae83b92432cd880446b78ef64bdeccffb1c65b28a308d15b82eb2f983266357bd485750e1ca874948a54fd49639f322274f1f36f54a4c8789e9752ce67e4fbdbc83aa547b66e625e45a185d1e45805394e418e33871c33fd654a5987d9dfb354900b18dca4d0fa09ff43718b5145a3f1d37e8bfe5977c33cb712f9d863eb5ab254f1231267b1633d2565376aa389e04f82962c7430b6f2c27b037b3de7ab573d35aaca8ed67216e099574dc4bf55091222886f47d8c1d73d152301c9a4c5d8c771d0e20d59859a319e80c94ef977174c92bd7eb678803d7a0a5ef02bb778c1306705b9ca4569d9982f6399f0f316bbf5be6837bf11544b76a166bb199e5ef20d1b8ff15d796bc643dd980102c339ba1de36aeb18d8145f8e45c5c4b48ba85b7c797c0aec86da77350a8147a10dd4bb2ec2fdf74c09957de4180a7b3cd98e01334e02db0f9de7e7d42df5cc8a647deffbecc73f30d7dbb3c8c7f5ed7e398980baac6d02123a1f686004cdb393505140bf23a7f8f2b72b1b17a78023462a0d4f5c23acd68df459abccd566ebe27857953394e59a19b67a40b560b4143c904d9bf3e79d240b30006e8124aa2e4592b0097fdae4ec446eaffec91d3524507c4095fab067fd95c2afa9abea59d59832f015666828e68fe203aaddc264bdfa67387979ffc3657f72df5ff993fb4e7f72df4752b107e096ebe2ae3840cf640f824a7ccc0437cbd75b921a317366037500c8669c0e79da77de3272f7343815c3cc759e86c8588c49e8fb2266631079b6454719b3a28a86a103a4f1667d964eadbb558010083fb58ddf74113e7700ae25dbe0c405092d486a23c28219aef4f32fbc154b15efdd8e55e69c247498d3111f2089c461743ffdb0f7ecebfe568e91cba348136a00e845ac52c30bdf3507f8655a191200d22005ea0db74bfecfd77bf46f3e49b3c202f181c7e458fb8fb5c0169b40fe8412daed4d944bead808f5e163e2200e71bf74b5a2d2958d95c7899c4cfcd9fdb278606de3be2d7c38f7a2d2f3aec23baa5332c86e2db047d17a3c50936ebdf5887a1883e2c6811f2e5ee46120fdc703feb4158499305e6d72a79af4c7c1de69329126c94aeddcea8a1f84648aa6a2f272bf49fd8521c40cc398dcfe2bc77f0b16f115b2f5fdb24f40a055a66bd2cc074a0832dd65551a74bb4db468637177ae4c64d48eaade1416b26d1ef4aaf0e0750b0fda8247244a4bb2ff6fa5b03f0b0e2f8389dbbf6c37cb9ecb26f944027ab89a063bef95cedb86dc3a5aefb946b00bf8fbdac519b2126cd9cb64bac7ac559c97c94ef7fd157dff80f8ea6937ff5acabec3131e983b7bc064195a88b3bd55ba5829d034cbe2db76dedc57566871535cfe6211b1ab42ce063b536ea1b2fc358af6ea328c7a12549c75a598042c06b4e40a71984f1bd2580f41bde384f54bb8a1e4e1e994ba0c32a1ce1ce671ac14b6c3a2a4203a1b278693987f3262a5cdc78b079b79eddaf76bd767a449e236b8bacc33e155864b5e45c230faffb488773c37e90c198ef9de0c98cf8cc76c5ea02248b61c0e105920747588bbc88c9308d81f34371e4869671d1771638f5b15d2c3bc9aeb7d451d4f957d98c232270eee79cc6753b7d5578de8bf21dcdffae1fe0f5325daadba651b6af1e0ca22aa517938f795451c38bf9b87c02814a3463cb08399e1236cd138316063ecb1c036d137276764eacd84aba9e728b10fa66ad27a32b8ba645e33d99b5908889f6cbcd36ea39cb495b34ec3147383b072998c2b4314ccb74751251e5c7543dfef86bd589d02885e5b0fae6aa1ef335d3d0095f051991278a1db8ca8146f974474c3f260fd7e43df8f11b2d7fc4c685fc7439575f39bef3f9d5fae5aa1efb74c9744919c4877162b5a8d470d13adb24d6bc5c0a6b32d6bd371b4dec68c723a489984568f6320eb58351ad090364b34ba32d9401294a73b4d0ac1d6862aba5b90de894ff1b1a7f0a3bdc5a0b8cf094017b12fb23ee16539f2ffd190dbda2ad4d72e15044f792746c5023758792e77b10fbc89232ec45b8ef4dd04e2dd108f671aea3c5c9c14f8a8d28e553951492fe869ef60f61ae1c759eeeb9df8ff963a01bc92f4b13bc835524f98b81d3e967d7ea662a0c6bae8b1537a235e439b62d3d2998492bd939cc39219e53ac664342683ab46e8fb8df01f7007e29b2bbb9ad9f66e73490cacd60cf0b90a2ca9bc5a9c6a27dbf38f9cf73b5cb34b06955587de5faf1c604f521b3e9bbb6e58a4a4dec6ade577867d2d4f2a319b533ad8581bb3c19b78b08d0115f7c120377cdaf8ced3d705c20d4f1fd8ce02caadaff82bb6ec4e8dc1c84ddcb0c5de967cc3c38df66a00f7078c53b85e590d4c2823111146368d07caf6b0c0d5653cb89a861981c2e027f3100f10a9094509d76dd9a031aa5b08633525e880a63e09ab8a074efdae3aae67e787eea7a234598cae7af51e54f1301357abb1a6cc830b425dce98b9620b5aaca0457db931148b0e4c09a479071484fc1be7925103560e4ecc4afbe6cba517c3775f2cbc6e529da7ab1ccfbc137dfd08724f6148d52e4a0bbd2193ba586cddcb51d9c5f0dd17a377f7f48c9ed667fa88a779ff22261b0c0283796c8b6d3c27151093dba22cd0ac8c9170b38607e4daeda2ddde052644ddc50f8fdfe9926a0a0575391b68b32a01faf08918ffa3e02023f2774c805f0d91df98ac1e8f95a9caeef19c9bddaff603aced61b0f215b5d0381eab185a7b967d25ac3ec3076144d12ff63451de5595dc9dee6ff1217b346973766bc3af5affc7d006d3d5dd0561c345639833fc892f59253732ccc0260a1e42a6112fc59defdf8eeb9a102937745d9963e9c9317cd1be9aa5c964e06428228300668b9789d3dc8d9adc2526ea795d05a2d25cb2ec582d25bb07debc4fbebfa3d74e1c34af22232358eaeba13ef2da9c0b4e097152bf7f3277497fc850237b92776764dc3a2b7fd96643f4b63215fc9faca0f0435ab05240d64226abb468f80f0785f5ba51617d3a695904348021254f576ba86d1565553b7dcb1dc6dd37fdee2a3aa934e8335ce822a7fbb935cd0875cae7e5cb0dc82b31abcaa319a6d45820d9807a4d8a716fa6a200c600201c728b604e0427cdac266b53e62d56fa460f6684e37c00357eb673c4fae20d363fd5b58f7dd308d5435a4172efdc61d2876fb6c1aafd6da61f94371559abbac98e692cc66d4175b893d4c02a2c7039c64a5902d8017ab5c21368faf3d533257b24b282c2341f7082413cd9980f2094af31059b1db0df9976e9e1b1ecb59f1c1d2d49857903754a36557bcb6c793d1fd80dafd550eade921eee0c00ffc927a08cda18f57aeeb007aa67a3a017b54f0c5f6765ffb863c08394cf3c0686b7314389376a43d9d3412b5571895235c799e06d316de8dcbea600de951a721b44540720bbbe02f125bb814d44f45db1d2f586e7eaa4b46e09d8eef66d1db35a9c2f2509a6b6d036e0e9ae6f33948c3d46e6cf16905ed7ec9a9dfeb6807d05050a2d6f317f86e90ff5adfdc2596b878ce5cb75e4a8a9a5dcf9d9aeef3094f4b50e2e06f094516838aececd55121c7175b9184068cababac5d50d9e55669083d3692e2b3f1b9c5566fe06b6441384765cf0efd91e1d101532228c81f26c9cb69175502cc63641ce334b09d3a16580352c54dde98faa5eb60a0a13fa539059ec58ee512df117b720503611f754e6d72005664d5720c02638698025aec5d827eb5a58fa1bef487e6afed67d87385db8e600ab780ff171f1b6c1c930f1ac9f4dd43e5b229bd0aa691fe63af3f7beff07b91b27b94248989f7130f528d8360ef204d3c4deb3c3b76fdb6bd6c7ff3753122e38a06d83b17b8bd7cbe86997c9c0d930dd56ae78e1a8d775220cbb1b1ece7ec13b4b203c95cd00ba84756364bf4f0b5b704e7138839a3707ec1169a94ef87f81589d3bfdab8daf75905620ffbb76721b69e033177a792329cbfe3411672001891965fcf4fd0d3d3809b68e0de8c8910849701a2350d20bcda4588776619c178648afc43c4d55981531cb3d494993fd73f864844c0176d2df8d4265a2eccbf303f2a18c7c9f5583312349272f4662672ebe0a3a1ff1552915cb388d38d8ee06b9654a980d2145008302176dfb5ef6fb27430571b582ab55e4f49f704ac7311b7885834d0c228b7f0b333b1e3167c7102e994041a3b281a27e4c93678126235cbdecd6dc4f91b7923ea464bb8c30dd75b7787209737a4b6fc3734ba7fec8fedace8a81b0688ad14d9b81cdacf8bf3215641b17a90ca390b5acb40573735ae4d71230be688dff2750d64f7da69c3bdfffa7232112924d08eb5f67eef8b012356fab12fc65571039bd0c7cff65cbf4b58627f7bca3c4a2d39003d1c49c057062a7cae6eadd0e5f12b3d3542983124a81c8067997eead9d525d91c52b468dcfd9a2248cc80288b2414987c6cae2945d4e6c2e612f5cada1036583f973f482b2d18cc3ed2e78d7008e9c7bbe1638bdc548262a0d9f7ca06ce0767095b99290d9d50a72cb08e59b1f7acf33a6b34a1c1927f773465a3f6464c21fa79cf2751acc20596617885512281427a4d0c41e5c777924b6f7d3080f3ff4dea81f0958310f6a47788f80681f89a6601850914d3f482eaf6f4d1914b0437f79226cf1bf9c5f3370d6374e885b0168880553a2dab9133ff4ee5f0572706b16bec54cde3b9f6fa2b9232cfa1e42d157bc0545083cf54c0ee248c9cc3d0a2c0b4f8c0d6ac36f375996592e38eeb219e44c15dd1d2f6c0ffc517e672361b94da4582d30ab658510d6e4d3e64fce0ae414b982088605c451da9800a86c4eacce8be14f9ce5f014e49fcda6b989b3cfa9f685a0cf1b38794cf9843267029982c63aff10b279fcb4c7b1a87b55e409aa5fc3165edb04568b9cb14565b8ed32d8a5d256b9678e3bf82b8acb125961ac6b4a8d6573f05d6f1c0c621f847ac2331ac8187a37ac23f78363048a4a0c3a866cdacadb2b373352632493681c220b8a42d4a36c6561f307bd37d5c93baabbc06a385bcf7a7deff440364b760c6c82d31f584a236bc5bb3d7a7df1c45102c36232703d18dba4054c8caa508ec609ebaf0b50b52ce36943fddc045bf0d725dff8235ad534e1076789e355f6c4079badf606bc708177488d47daa1dfc621fcc2014a5cef6d984099103dcb833119f6a71368a3cee8dee9c464f8ce1a39fc9f9d898dd241a57ef3fffcf48c2726cd3001d75cfc83a3afe6666581f0e225d27a4c30b8c65ecf4a78785ec14a38e51b7fd6e0f731a85e32b5c81a70f1714ccb52abe634fc055ff9dd77d8587d024d73ef2ae1a8643e4fdcd14bf6487690a323e965ae1239a12472c80d4d564c9ac375209284034cd885f54e28b81814cf9a2f035cf1103a843878046a984a03cf640d935036cad835661fe22ea840c2f2766e50d91946c626805114e11276ee9d042df5d293cdfa944d200886dd5d52a37733c09c00cfd86c4937ef7ecba661f10da6bee62f7b04393e740926ef221f33cfa580303c80195a387d73cef47330c388216792ab1e300d88d25bd2068e61823004c1c8601764a3a0b32a5607b19b216081eccaa8bd2f8c9ec622c743774ea32638da436f1e988b645eccfd6650032eb6a780fd2069db1acb207efbed5a0b04ddbd6cb9adddb66f0360662b53f6227200305b46ad3dd2e249a1ea187ba3f9eaa13ab482873338160e6478ad348447dc0377caaeb06b7e9cb398f09b30a12783ab79e8fbf3700b36925d619fbbe431901743d301320cf2f1172fe1fddc0598b1c9c499c9b941bc8555ae922995523aaf8fbbc4b2238b755a21151b83af2bb10b649aa226f1f68f43491d043527d069120835c83a2ff65e3ebd46259bede9e22e9390b68f3435ad8abbdb108b7f7ed766bbef8131a1318997960d3565f75903e9b6c43c668aaf620e7a481218bc32230dce17d3314b26d0af6d70d5cac4a8fe1c39e972721f7242ccb1635f9977321e30c1c91ece5a67c2140177cd9daced06524a126fe0bc6fec04ee811b627f6ced088211ee9f53506fdb1d2f9e9f0192943dcf44eab92d58489557f866535d699107f2943033531f23b3058a1cdbadb0aaea1845d3290a5b8effc3f553332b843d9dcb87b7ec29d14a32d3f59c7339ee13f6c4743f5cddfb6193ab289ee74290e56005d188bf6be72a3dc8258ea766ddb091a62a86ad588830de596b1401f9bfaf77fa14c7fda75cc94a7968d700e48ce6655d02cb35ca51a402cdcf69f04e9cd60895d28dc75a60f7435b689fa29f6914c518fb25a32c3127ab4ffaa2fd95357c9eb00bb0ca94f6009bd9f213e542c3b392486e987324736f371314519c00ffba6791b90901d67dcabac49b88fc4163621409f42fae5974b35cb1a34df57228d361331098e9cc2307cd8af4607131eb4f78876affe2ecdf98490d27ec568f577060ae8a2ed2627415db57b7f7ee07e859de2de998bd83ecbd9bf2544f8c719a9e14a457310742fc5d19718942bff3176efc70cd826e1727fd76a56034a9234a6864aa298a654c1048c100b34e32b060b0c9c1f1521ef8d6da73fd54f2caca035e08d7b3e7295ffb6150784eed444fd52a91a65bedc0820668405e5b6f5fe718afa9a49ecab44aa2ddb5122ef2328096612bc7289f209b426ae45871ec33bcaf5476d97ddf12fdaa902c8f334c8d608ee3a0b8d348df3a455a31739ea821e5fe73a1cb5ddd65913079ae1c41913bcdf99e57a1102f8825b5449e6d067c8d2ecd98d2366b1bd8f5e47cc6156372b34ba1665f433d86269d1b08686801fae0105fc22967dac1e9a8c5bc06a5fbb89f370387be8e54e1365cb01e656cae5073f433fe2331157ea43fffc9db9d63f2915066cbd5203853c821d4e94eb097d0b927a9a56b9ace646fe9302beda9eb23bb2483dee57085232705d9adef7f936c634b6cc483e76ad58d1573e2ed81d9e8ee0383464cb6d11b9b0cc549f92a49a00f4c1778e3816905d53c71b6fdd518b0600b4493236aa23ea5af3cadb8d47cb7d015124e62cec6cf7cee38794d5e188afaee0eb8ae07bcc39ca59833c9775d9bc2317c8273e764bf6f34bbf5a0747ee34fffba730f7535b76d2426bbfe0fe8838d5691d9a41466f00106c214737ceeb2236d7b761f9c2e399de1feb98ee9a9791c54bb0bf6e0d70926b0f9df24baecffd3c1e69ebcadfebe448072945fac4e17b185c59dabfae7b736d311e3f25e19179ace86b71dfef7f614bc6c8565b70206cb3aa69eaa23e52af1efa022905607074227c3387965dd31782ca7f9dc89657db898c1ad4a165aa92a78c2b66e1dfb2484a02f4812c30167ea98a359bbbdb8cfa4cf99d05fb6d1e8219cc24209b9f18906c09ec5baaa71be407a63a1ebc3bf9eb71a44ae3ae96ae1e1a5820486d56df1f4c7d74e97bf268b7b5ffec976522e90baa28af8405f2b10ea961122579203d75075cc357dc4a74bd448ff885649ef6d4ea5679fb3629d128a6febc428e55458dfbc4585194b27490382691aeae3e76e8ad0c11ea49872ce22e740c286b4edd278d1b2772be17b4e4523852e3541ec2f74f3f63d8781599406c8a1873ce3cb06dc670d45ebc585f9f20e66caaa6a8edc96c5b86eb2af73defa747391e0d4ace99586f1214f4ca1f7bc447f17f47f7ffa427b255c48b65b443aee6db8e737e7bc7de56397a96a7991b79d665a08fd6945fc030bbee7c8911fa417e748454f437cfba794fe003307478024dcbdd5d477983bbee033af257fdf8bca5e57f88ccdda125f23dc03fae191ecb10f1d37d0bf19dd372963ada6bd0d87541356ac316a4549cda8ec0bc760a7b389e60094258b9cf3d5308e1e2ea14e223688121a150c56ba158828762fa328f689e28adcdd1bbb615677f66ff61c4b86cc2d93fe063528b37f769e469bd06667f7c7b0b1b691c4b4f9cf4c7df38d4aded5c4439b3f34b81de76f6b60dc7bc7d2c74fe092dc3a1f6c41bcd196211429161c4e2766006dace702b160eba5de3459c7da9d7e6ea3acab7d254eedaa0a75bd205776b87f59ab166274aafb990bbe423782b4c4152b642e05f757390ac42a903936ed1d20092eef3004a0b070e46da00863d872798cffd7e88d4c19d3271238e65785fee9d65c7329f7385149d3b85b9fd43c11bef0f5a59e034189a7260e0a6653b22eb7c879aee7697b9727c54bd384eefd70e6283d44eaea937d5946974d0adedc3bf0912fefa16686292d02a1dc14299ab1b8bc40cb5c1bf921b7150f9ec375dd62525aa0fbf157bb5a739c40ab2e53e91107b6f421bb4e80a7dc4c4e4146fbb729ae824717398a5bdd3b97e75c3f9a6b93a4e102300f246bdef539fa5f254ad3e685b67146ddfafe139254b39d0532dd04049ce76273c5c590325b0aaa765a7a77b3b1789fa8c3be5aa8d71d1e9ea56ffddaf30944202f7161ae9b39055b854d36ec6c8f2551c896a96eab3a1732982bd26abc93a332fb3ea033f593daac0cd295cd5ead0052b866ee7a162521ff6ab669d970347d2ee3b9b2a68ae7ce71294f056c4e6652e8b83c17942ebd9bc010bdfc94e3b9b2c48ae73ab82b5096e6b9fe70a2f480185fa895b25ce4da6de578ee12647d2ad901c2a5b068821b3de5ce1b0c5b2e1ff1ff5aed08c33407ce0af1decd715a747419e558ed4a65dce4e3ffefd6fb086be334d73f30df56a59f5f1fe2bd4834ff9e332a375f7288ae73f385334a2ec75525b7743aca3d81117fd52c1863fccbb1b3a5756bc60e83678ac5071316a62c8de4a66265682d9cbc8c3de77cef81298f5502a63198f22cc794a5f9d905a6fc3f36c5c2942776f31081467fc1943b5655e78c606d836d8a2cd8e73853fcd8305b5647ba375a1db1065346fe928260e4f014e35b7ca46bcc4bbb378a2b758ca26a9c8ea7effa73bf0bca4ff6fb8f1d05f3dbe3afa20624ca4fb6e528f9e597a54433db4eddb3aad051a908db2a89a61ae007ea697c93e37238ae76ab1c265e32e2f5f3b363da3e409716e31dd666be23fba671dc60e7406bc7ecd979fbe6fb4f8e0152a0d8cad758537fdb981d7caf3246719686e9aa896f1043337731dcbefc651f2f1bc33be6d1a1c54db966d8d2710c95875c4d9c9c2cdf5c8db2537493cd91be7a0d4c875a991bdf1fad61613bc3e6d54336b28e6351613f90b1802d900ad904fb10eee68e0b281786937d46ec044becd86635d2937f72f6cdfca3ee4299d131ebc0c8f76faa8b72a3a3ddded955894deaacc36207cf5bc54380d537657908c537438182993ed146b6fe0b961f9d674650bea5a0898fcc9901981f4c0ef010ac60f4dee53d04cd2970fd53867beccfee83f010f8d34032f1b5aaaadc7d3d673cc724558ea5b4dd73e090b56f17ccff1777df5d9e6ae1d825aa0d35d1d66d668070f5629dbb1997974e89495692e5011498a787d215ae2b67f30e529e596165789a8e2e984c152356579b05af852ce0be11fcab892eba2ecc00085e542f4ce8c8742916d7d9bf9ba0ecd5d2b999c2eb3ca92ad9aec5a11bc3ce22bfdd9cd394ac4b5067b65d253689142bf141a5efd349f85d54a5e9d835714e29a92ff1da0d174a1af56ed499060a9b174e29fb17657e993b711f8c0fc94343047b92fd18ff2140c9844fe4264b5cd979c2f52dbaa7b2356241a08625fa7e65429a589bff612ffcb433a742116663e6e16368188abb2c72b786f6d6cab915ce5e740a0a9d0fcf875d45e5f9eaed4a42f3698432116cadc33b925789fd1c6c60d887920b6d97300df43001727d83eb6bb422d9b8625c67c96a113b1edb71b79fed2214b5536b4a540a2a730ec0a3a41e5e1c05fdc2a9043e5a266fa163d994cda33a2074352e0eb00debfcc721d020125f77ac3567548cc7147b9b7dc524e3ddaf349d1d630a459b074d1e29cd104185f05b66c03b2880d0fcc87bd9cbbdb4c7ef04bf0ff87dc46fb8318708d7a3ad1eebbc1619a19884e99236b1824fa330043ff2732aae156c6b99270bb02275970b5bc0bb3a6a21b3de5beb3d69ab0cec47d8949a78381678ec980fbb05c21f248759d96c9895eded55524753ad73e8876b4e3b5983b2eec50af3ab5175b922d5eee18e789f4867303042821c060281a91d23557c376bafc7c9f2385afbc58138b583ab9f7e1a6d3239f11c4d46126cbbce38541aed4674bd791ddfdbcb00829d16309b94f4f011f3f220fef5dd7180acf63f4dace388109c43dfff7138c2167f24f8281fffa763a4dab7c7e4ee3b6f230a7ffdae2fcd58cfdc7e502374df313173fbef0e60cb88815ad1eb1e41b56ef47d0fa7ebe603ab961fe417c1ac941f551cd3b61b9b0fba8302d64a5791beec3e5482ebb2be8cda0b75ab1abb4e60333de723074c4e20dd221d4ae736a3cc0363ca6a4704eb2da8ebc3e63532b536f652688d6f98283eb9414d4eb01ba853dfed9fa1fdb391e4f39dd4b94e18f3c3fdbe5f380958958e8f38dad725a8cbbb4bb5a50c6788dc984bd91fbf39656ccd3d47118ad9ada98c5152da4b577a1a2ab099b09fab626da72a8f60097d69bf7e67c0d1d0f7e7748056afe7a272481ada1470fea91e95d9edd94c1bc4bba466a18b48e312ef0636a50d5c6fd5b1a22bb1b9aba99548861dc271600758bb1072d7d77adb09ccf7f8583c6a71422a46da7f3897c2d0f757017083a6ab52928d4a2018daeedc164587c949e5093e22f2a16f8970362d999a315cc1320d092225d2cb037cb070696780a3ec50cf5eeef5074e9b904586ab934570df4da7d0ce8cd1274ac7dc5191b359bac3eee2817cb3c399aa3d75db39daa0c1db7699ddddca55120bd4580fece9d55cabec06260e8a66c8493064fedc5755c45367db3780644e0808833a0ebd88e09051f713674cbfe3e1b661a1e344a9c86a57c72470b69d07b9c97be91028140ad9c30fead06553175a5d76f8c5c6270ec28d95354a9f0b66ac14d50e17fc115f9515e196156347904ae9b86404b69778535e5a8010a7f89d75d930ec026bbb006c7f3442b2acd8b3ef7f4eef4c8bc34c6b91d16111534e35199d81994125315cade1aa2c6d8b47e771354cbdc6b7ff95c5457e2c7ac2c0ec0fc0ebae4b0e34f654e9d5032037654408c71524279899d6c514789b13d37c0abb8af0f10d4e203bfbe9773bfdd5f3857cbac4c93b9211aeba568186d03765cdc5b5d0b351413a8d82e4c59e36f30980563d6d12b25624ed6526f314dc7f928881d5cc1bf5b79b0aa83c3190d41895fef53626acb4b49b2e9d4fb68a89e8654275126d1068e00bbcb56036826dcc64fda1684a1e433574cf0b1e35405230181f573834e888c2c48da73a471c292f07d5cd0ad2cd9ca0f44b1b9c7966abb2ff52918e2e136d8f3bdafd48bf2a630ea6e948b0f84e320b932344a588206f35742cb59180a4933c42b04d42cfdff04ac11624564e9855903b0358745ea5718df7dc71cd68dedef3691d982b3a2f86891aac40ce25fbd5bc98a0a7fe46869effd179ba53f9799a9548af78f63d365c4ad83c04b536e487c9c6b58da3edd9c6b12ae1a52e873fa2d33cf275df06bec4a2f967d3a331619b5cde2cd8de65ad64f664974d21131e50dace6a6d2c4c347e596b8da4901229af09010fef60174d7a4e34a56c2e01b943d2ad7442d464f04e4a5e5075c4e42b92ea62dccd8e88f0f44b250e5c6ffe0ff0553154661da4901c89264a5d0eb57227a6a8194b20233383b48cbf1187cae56bd37c8d1a033f9548729846c1c89a0d0e606e349c70a505137e1b1e06d46a1c9e61879432ecaaef6fd387c4d5d2e014395071507956510df57d99a78fd9344f1fbe6542e1ea2bd753c041bb2d218898096249c69a9e44246652a6662d4a3d96fe1b05464e48b6ffc60392201603c71e66c88bd2c3555532c78acae5f80174c4bd946a8d8b0df5e56eb919a80ca87b4f5973971b148c605992cd00b9fece044d49a20766e2b0792dcc7c4e468aeaa79a4a5b799e2351108cc515667b272e203f3d736e902d9c62bb2e52269d811eb749dd186b35092073b644e6fc9cf57617882ac8e42e517d140ec9a1e9d9933af527ac4478728f53723614396e68ac4af9ccd5d93b94cab19a0cde6e6498dbd89712364e87aa5b6801824558f8ca10d965c30e6c701b75a4fca13f9b63550fb386d0cbe6abebe7e0e5930310fbd0d35a9f386215fa0682eeda30d4ee26da7082d56b71096c988c46997a5957106ddfd2d7ee0ccef0fefe1dd1bffd69c01f1999d2abca62476f343ef3139163724ba0495bf949822e5b6d681377d9d83825cd0fe13fc2fa5a1b4a36cd07e802fdaf88c5096aabb885da1bdacf4b4a7df0035e21354b1172765879e85b1b04fe2fe7bdd82276327adad914a32be2b3b6e0d29bb9a7740bbd9216368516bc92168e78aafa5a0b9108c54e0be18a09fa8cc7443257ead4d0a853438ef2e66de51aa4e9e16c5e2560e31e35b5d964b109cade6b1cdc6a49ba01b9972df09e3ade42711ea47d986dcb82e7dab443eaa1d589593dfe0df13455f83d60cc33ea7e9284fc769ad83735692b369f3ee9e19ac006ea1522f495f8b372a652004438ef6eeac24ec8a7b68eec9ed3d56869f21ecf0acd29551bd6b985d296cc738759e0f6edaddc777869b76d4bf202347554ae561e57177bb277d4e1fb596bdf6cc3c34293324edbe9479ac8b0ca2c7783816dff8f0faca609598eb2374789d5db4902f152e2758bf7cc914f5d151a9545877631943d53c32708f1301bbcfd8212ae5a1875ba678be51926fbecf76f38e21e168237c9cdb28c6d88b9184981db0a3c66d2ea6a46e0e01967b01b83dbec8bc753611a5e4bb0f6a013acf19e6695f345a4dd57b3ac2541b69b32ed4fe6a90d4cb840a43ba12d29aaf20cb89a3939ac59aa871cdde6248f0c66db468e7d06061931bb0c8d87f86de30b3f2d093090485238362c2fd02b9071fb672fe6855a76fad68abc48b57e2ace026d271e4e2488172a3c768bb870c43e207e37370dca4a105226e5212b19baae375c125d94c62735ea1448f962cce3f1c41970baaa5cd80ad0504986d6380d20a8a71557b916c922212185f3014d42c10ab70e486c022f83a44942968a133776131fa0cc1e8ce5c9b00d466d4c89ec7f6ed63a9b5cb8180784b7087992e393322eb53963539df7686fc53fb76c1e9d2c99d0c6dce1c8ebb1b1b5d583a7fd115aca9e9f4f1e61d838f0ef238a32f3aff3231faafc2b1df3f177e6226e518db7639def767accc4daf85277cad4dfe3bcb851652ae0852aae8c675c5a77c2a99a87edb1028a8cc3b2518a7f3d45fa9f258ef3aa47508a47a47d1b76f6814ed138e995a568fcb7a77da370dadfbce7b4276939097412cd59af7f59ec33ad2bb18fe4e7b9aa17bdc8b5a0cfbb239d77612f3bb7facb3feb578fbdf33b0fa670360e9ca369b8ecc176459cba74a65d9e0c2b4e42fad1e2c6e997f4dd7a522d8b437ac69c854a8c5048a9b51c70b766030732b7fb2b155e4c41f38d7087e689d5f8d6e9efd478c18329353e9b8a69acaa45cfd829c929ccffa840515d0f94aa19c097d60a44fe13b340dc63a7c414c7efa9ca953436408370e56fd4beabc946e4643daf484c73605cc5f492539e79eb81238a512b13ca7a4f19c94d7fd4baa8de64a4863a4c0bf913feafe4060b8ca71e539da8b59643c2def37e1fb0e79ff06336ab72268f318f88d38155c9ebdba271a97b5229bb0528eca9b153458acfda806d17be856d0c42b9cc1ab4b5e77c6db61f85d0761443ac94b27d0122d52f30c43108a06718e254204a86157531f719d3a4bc7c78629170f9ac06b209762670a5e11b7bac9db55cd7760277cbba3ff9ef106103b3c018ba034cca6fd1a029bbd928d060f37f8506fd87ff9804c3d3381037238fbedef93b2a6c830aa3ff800a779a0abbff7fa342616dabe95b5438c6939fff9b5438052bfcfcff392af4a33668f0f37f970643efe5dd4478ec2980a2f3675981abde2b0bd99296cc7c5aef8ad7c39a1c901535235e9d47ea466aec4b788d245d94dc646fe48531a9e52231c48a2571b762e78958ad77c849183a59ef64fde4ae64bd93eb47b472cab5c259efc23aa7a96d630a26bba2c54fe0af45b8b98680bab5c0cfd0e3ee7dbf1921eb8e52d380737e5c0371bb9dc89e3fd41098b763216cd10a2d2228bb49a57fd0259dcf58cc0677aa7f77be1f9311b8132ae956f2f1ef06b62e5a3d1d988e19d96fc241814f6f7f6d98518680d908e1b8ffc250a71440ba9d32a2b4b77960c01e9fdfa4eab16daad0020ec13ab51dcf7827bf7421257abdf1fd35802b67c4c275e63084ccb990f62668ff2869a182faaa183dd2aba2068bd06885cd0228a7d49d06c6283084db9cc7fad0dd6ac4f509e4267bb889ddd9c2531ec70ea4708f277361ca3d094efb9bde44f9de306358624d563bc5df34c36ad93aed775e907fc6ec07ed3d733649fea21b8f81d62beb819a82d0e3f4b492487fbd2b843248cdc01cf454591f6f9d6165d43632d055f3bc905c2e7ba865f41fdd013d00516da68f7bb301516ddb0e56be1d5b14e5687f74a97b8bff13fc9fe3cd2eb50a0db43c8a6be0f4209fc63ff5186fb5d63ab720f531eddf4e20139f6dd1759007e13d53d27770ebf93a329e49764ff6f625c95d35068ec96ce2b4bb3c5372c671e0790a6e7a2e80eb2d3925b5be427c53bcc4d2e5ac959e0121f606eb6ca9bb8364c8e8f8bcc5cc7088ecb2cc3b76d544b2009d2329c6e9dfaecec6c67ceff7069d0f57b77e77b0bb6175bd37a88ef87b1f7cfef9817fb243e1de031ad9c99c8339783a3377a169f521b912c5bbdd11f69adc5b13a9c1344f507e822fffa35a8149dbad7dc740fb3507680f4fd750d9e7eb3c1a7c010462bdfd6a9e321cb1df2d72aac306c529622aea079510ae90d45ec2d7dc946bedcf9ce8a112384fb3d65e833f7ff716783b7baae240b3bc43601cbaa3fd379654800ba27c915dba5f0f2a0061194b38229980c08188f7067e1c716d9d4fbc1129828e5e1cb5b8be556b28b6738458708fb6776513df57c37a84617af79d12068c10702128ead90ea9207225438fc88bca58299c0cb63eed618312bdd6a46c907b6d9c4eeea453044bb867d3a6b83fd337172632a87a1535006bba3ad2abc6a6ec4894ca4fba6407f7a8bb43ba2ecedc325256bbde2f5b3e62031853ba51dac259aac16dc8cebeebf7244bfcaa3c2b29a33cfeb144cdb76338f5eb55da7237071e859be2bb3ed0071c07933c38c1301dd21bea43cc9e092c626a0427e6948d4b0884158cbee94efc66e5e247edc48f7c3f2133e257b1db4be114de780fe957f5a854091134eb74ddcf26aa16d4116d49b992348b4fd95fb40c646e5b5c61fc462aa2f4d8c9000f510db5ce756af427d43bc9535c8da667284e8ba34d6c1f09414bc2e4ceaa6fc6af32c2fe8b0519fae18ad1760d499af657346e44a519af6305077855809131cbdb87e3e0d579a1d43655c5d14f160a4c8371e3349a73772397ef619ed1510359ffbdd747d650788c165ee9ec2e2b9072daf2aaf22cd4ad9476e7a42c44595a883918fe39a66d17e95cd2e21de490c1f62c784fd7bb4a4e15ec3470341398e2c6b074e46a7130a0601dce203e2f3da80b40d8d6906fa05b7a68c811f4cea8a3ffeea9615265f2c8fe6f1d1c4dde543541e5bc6ffd684eabeec2d95303e5833850fd8c855aadd981cb0b45f788677c295f32c83148f7b6560595bd89d6d54dad65d2c0e162498e251735a31a36b864ce2a1914c649b23ffce8fb92fb6a1ee039bcba734213347ed13945c5872bc359c138b100754a28e86c0d506d9b034e364ba5504b8e1c93eace63f323525f8ef18dc3c6a993931692db608303ea5ae7ff8f5013a66d6777a5410b89f4d2b7372b9d3a57120f4ccb01ac6226ce7255992d927942869032a9f885e1ce577dc4552eb01cf200c6385ef5afe6a11feeffe0c604c74d728bf2305ff9b8412fdb3c8363568a8f48abb0966a4bb9b3bacd60bf562f2fbe9fc07200c410c4eb16454f0fa887d61b0bf142af74ea7f08b44fc0cd70e67b6e9b279cd232020e8e43ee824a178b7166ac771bd9a3a4cc096bd6a304e7a5b77769f9805581f916e7a0ea00eafb42e0de71a2e7514dacdc6e6b92204390e2dc0c3281b2bc76b82b5bc4e5aaef56145a6111e355dfad07b45637e2c295d2476de32b75a51df87e9b1e0dd367b9719888a9bfb7080aa79ca91d238b7cf96962b54737b85bc2b84367757b48772c5b59f67befd6211121a88594052fdff91ddea2cb34d45480d89937fa9b1e6134bcf7fd07f96e9e5dd570c6efdd12f873270ff1652ed6e151cd39bb2facae8d059f6ae919ac42ea10c2e802317b0ca4c505e677e4e43b93a08409fea68ad01462f1fb7f96f13dfafeb4bf3f28ce3609c7450e98d1e3b24fd4377b6efc32acce29c4b5005582c5f9f3f07f8bc579b0c47baf7337438cf17bb81b38fae475ee86ceb341a6d1fb6f7237f0a3499ebb6d918d6f89e6dec7ddc02b5116f755eeb6ef639da4df7bb0ac7d1fd52f8565a91bcccbf415debbf51a5961d3170ca775a3bf290918ed37e563d9156683696da0f973eb46cfa934d01907e8c26959c22c72acd0d2ee21c9c9c4a474b94f676df3606a3b5e7dc97d2f46d93a96a22daaaeac55bd4c902be90c448c4ef81f364fe10bef62e475589e37b37731722319cc5e63e4343de1e2252715fd3f3681e6643165e41b301e4a65e077e860a1870c92e777bdeaaafeafa9c8c210af6cc61539f54cc6159a03147b9095bc92342fa473c2d821c9385a523a361bf2a6125ed0f887361961ee9cdd20570f70739216e88ae1ab18eb47bd7ab0cfad8c80cd663048d953ae6cdca0f95f8c26f94d1d69df2e4d19d290c95cc00cb36cc1e9516a29a64f7a3cb9b0825c788fb1be18c86906e33cec0039e5593fa65ace877d5650db740619e5b535f926660c9dfb66037960b12fc2094a3cacf4bb061b0f2fc569e21225ee7ae0b8d96f6408c495da2706307cd2bf12d418cdb5c67749c91ceda685cc5f443ee7e8ead90fd7cf5723ff2efe7e647abe1517c1d0ff9c7e57c098ed3cb0bb74373715e4c245a880096971a7c9ec54429ec66628c7a26b843de055e8f0b59401c81358c436586f490955fb6eec021b32a5556f11f0ad36a7c898475efe69b0efd9bd417b609011ca4dced897cbdb62159b2147971b6385defcc6d8e26c8d5c5319272637e28304ccee5242305000ff8db831937400ada3be502ed32ea76689ee983b66dddff2b4dce7edf19c97982b634bc9baec53548317d179ec48bb354c2d24c8f0d0f73d000c244a172f3e48f7a45e39736cd9a5c216ee773aef12490ca4d77db6e90f6f25b177534a0fa96c51f910566c3b9f731c3979aa60f43e7f15b3af694be7ff85a5f8049ae42ffa8687defb61f32741887f2da4d894c04e626b8f8e341ccad6130a672f4830253565912959daca6713cbf64ed6f604766c67280fb03cc6a4822cc2dc1195cc19f324ce549db3e829375f31b8a8e3ccb3713fae2747bcb2268d4b4870846c0f2114e8ab533fbb4d318e8f478fa312d3b525a1311164357443bc85840e4840b1c30c4b89446c1136838f83ed66f0160dddfbfe6315da0d3fbb0aff867e1e7cff1114c32712bb18c581b9aff009513904e55435a930592528258fccdff0dbaf894b756914fb81e41195ca6252548c23376e8ed76ab0463c997758cc939785f8360d89e8a79fb35ce4fa05fac2b8242636a6dcc28bbe34da96f5283dabb1cf84fc8e07b756e465320c572ff830d9a0be0a9df9aaf50733c5a1efb371b713fdf71890eccb5226a102bd0c9318226a89094e5254fddfe35a7e4c64e30dff05d7ca4f4e9e69a10bedc04a7c4d1c58f166f02fc8cf656f098d6d1bbc4d4017a5489c692e4986f5ef8c314556116fefc8f0521d0ece8ef56ea0711efa72c12926846bfc07142509771152853642a75913a6a2ae932d08ff1fe67947e650dc743bf8db3a7fa3b8b04f30e71d360c9d3e01365db84930d6397b000e58b82451a5bba62bb650e1dca9a3c4721529036a7596e13ae0eedd6a6833e4b17cd8c3d69def19b1b9ad464e87e749dff9bc4825bd27db8b2edb8797495f7766859205877f9c3e89ee15277da76fe0d39ba46fbbb84513bba4ef7456fce7b555df747ae887293bc1e6f0778b57e8b59820b403a1b673324e75facc9151ad1df8daa1e661563708cddba7a5e81ed4075f3aac791e5c49c6bf7d6062452589d6998c8f9bc063c6cb92a46ffe8c1c8df65b3e86d1116fadac8d0c170c65fc2d1e47c561d1df1cee68e85fc8cf6aa06fc464817993f2f90d7019d9e0cb4427fc22b487987ed1cc72fdda1b5a0612fd34eb942320485a542723b7efbc63d2a23226443442f68aabc875a51664ccbc2439aad11a5908c0375bbcca60debad912a8a717e8d3c26447b54d1506238f5625fc3bc2783e9f91089a3dd613a624754c86ce29b93ee843219cbc589ed9492ce5dc64a4c2b5adbe8acbdd55b61f7156da49abb0f177cae5be64cd047fdee0e051449f7539abab17231b33770a2db899a759d622d8f3073904abec1a79429aa14093af7ba2338d7e35cdab26cd912abfe98523e877cf8c9eb5499cc5d280e4d380090379609e4c54f50d57f3cefe9c0552f61d2c302c76f931d76533a3e957b309519c8aaaf940e2c0a4d512d27093c2c40e73710dae8cc309109d9644d498c1945e2e7a541d10205a6843ec7366ada593bcbc3d6719474b86c5664ce803a1edeffc92f7696724aeb863a7d1957bab0cf16c00ac702ae2241cbea378c5e63b1d111e0abf7fb6b07e2c20b61aab4a9cdc9b1259510e2b1273f603638c61934e04dd8ae5b66d43592515505ae379ec6a66a376d9202ff063497654d34c7decc8706491a051ce4251b0a001fe48dd32dffcc64f41a422ac41221a5c65e696572927d2ea300f61aec24d1d969b2339d9a0f1f3fb35d382b266e9a1a7e9e10648f8a4e27ad84a2253e689cde8c840f566dd917c25e5c39509fa17d1c67edc2b16fc950afbcdb6b54be4d9a0931d5b664778acf9ae96a6dc713bace9e96203a6e3f5fa20d7f1924ac5e0e94f27a5075fe0dfdcf1aac9ed979f5be9c104d3ef0c297fb139574393362b3243d91ee790f0f102d6efbf160379ab8860bc2b2f8061241af557d95d7bedf5bb664ef25fcbaeede97ee44d0c6a95d87d5d77cd7d637ecd672b525fd0e20ed9444ad90486bdad6b07db704cc253b295123813d0d22266916c1e835ea045c87df96d8fdcd57e90a796f6674e400dc6db49074aa6d49eac87dc685a7ca6ad91f04536f6b22dd1b9c37cfd851e4ac1c901ff4f6e8253f85c885d5a7e946deef31634b3cf63ec22ab1608a1cbfe290597e29719991b75911e4bd3deba0e246ae7b42c048684a771602885810cb3406245a42e855374e2693eb7d36e2483be227df9e609553672734778a9be3ec2e1496594ff2410876a17ce7fc928cfef547015a5b21e3a9f94ac29eba6ffca48052577999cd713951edd3ee3fe25685fc580ce5088d6076ea7c1fbbe86921715f6f6a778aa7e9dff0885494d2caae6bea423655da28c1a65ef998b1746f5f68b64682ebe98adde5bcfd0b4ee257e19d853d6f5cef06170c4245e3d02f4d984873b2fb43da8647ef19e748a2657ca6ac59c2862bb8480b0e4d3b3530bfefe33d9063aa35cca3ef977dd6ea8643c07da3987a082c4c487264e30264b71d7dca0a455e43ba5abd69f89db5596ca0bc79e74f673e9443ef44076a420321465fff941f1b775cf1c7d7ae3f8e9b95d1afa16503029ab45cc27f7325dbcd4024f159a697011c1e1218ecc404652aba2cdbc7183c1c90c1e54c644f1975b926a6f30dfc04f3440624d87c4801d709775dceb3baf1ea1869e9202f1e6f88411fde13b07d0607e08ae1efdb0fed2813c3b6f3060396561dd9bb98643311303b6dd537522d90c5d00cb8bd925792227c293402e18c7c456ac78e93a84a0b63479532c9688a23ff1f9dd392197370a187b8854690dcc6343896d4b9b0cf282ea2598e4f5041973ee7dffa11273e033a17f92e0e0544eda2095c21656ca6e3760a187a9eb84b8dd2eb3c20fa55f59cfad67201c2327c3b5bc97adcce5f786364a6fa412bb8bed13a95ea60dce77d38405b091d090285fec70d60053216fd7dd1878a7498bf112fbcf72972c34d74e57da37f01ba71b7c1872053719a7eef925fa0a2e4b984917e097b563c87ef09db354a435f9f4f80c0c49d324cb1ffafea30aa678d76118f65eeaa8e77adeba80b6d74f47c9d7ad8841ea83c8f1189f9917204d869c8f133c96a2d2e32bdf2d1c98efe8ebbb0e5069478e6e16d2df6efced8608bdf176438503f69dab2007aeb78884c2872ad37d0541df27f7b6f912e598c297baa7b7cfe3bab5b8d1ca2e9d66730f4b78d442391ce4e89e6097655b918a254ce1be3a87f648fc65f9408d9c52d4f843addafffbdeeb63dea36e877bca47a7a76bda41ca97e57f345d4408eeb26d20358834b03929455110cbbb44317b6054a486839211f67cb4c69f7322029f2ec8ee2f7591b32e4349821c2a368a25168d61a0847b664bdf3af8a37631a0d05b1a20b9cbc7419d0ff2d54ab734224eff5bcb227fac8c5285a188b293718248495e735ab91dd29248fe195e2e3cb80c7d7f19226a85a13348f8fc9b12de115f62d5c50824326bd94271f71a1b772117227bd947c65c3679b842c61ac86d3c4d1955199fc565f965b6e0ffa74bfc76688c5c4cab971cc13676eebb5dbcdb5b960b30d94f9c7135d6e2c69c12e6dcc1396cbc1f9bb5600e2379de18aa6d8b783d415ef099dab51cc273e7fb5fd763debb22acf3a77fefd0f9fdd2a93e2087ef7adccf096e26955eca52a770990b0d4867f0f84f25012ac98d9fd93f723015fc8ec7c411db5884ddb7ccc969a3855d18ec1d0aeb4597557163d4cadb4d86546a4ead5bce3a50837560ef5a0754360ac116e75c737abbfc8da27f78917211e5e68e185bcf51f61fb4b25f16402a9fddafc51e172968b484224f51b64124216925e1f4e54f6b00f9738b70ebfb375ebb90c7e4b2409cedf8ea9a2d481d0691dee4ad08ae5c95a6aa8c9b9b4989e9fa1060a52292a08693a91e684d4087ca49aa31cf4f8498c70509003e35ec1c8ed46cb0efcc248fb46e0b4410e6f363cb2cb7b104815ea95d80a5a70c225d93632bd239447a6d357ac4a272558445e07a65d82b70f4c847be0cb9708214318719677a1870e584d961602ed0f2eeb5997d0974c01ee800f53605bb4a79126242e1fe6551fa36ef46dc6a2491b1a7df7bec2f1be914ff7907a649b3df5c21d7ccc8d6d79079ed4612a7310288e0eb16fef93547a07c3ba336637781d39bcf83684564f4b4bc3177c998c84f8df8ee70c986d8ca22345d18d91a8977bd94939e5540a2557c9b9f96ab131841ba2973f4d318d963eb1c9f5de46b746ee44dbcb597ecc2377707c05d0466b65578acdc232d484c6fdb948752fde010d4576a5f1da9f7dba0b8bd9e6527d2f6acd1fc6e43538bc6eebb8e0361af04ece2ecc14b05bcc531218e8390adfa0eda1454b09e780befc5c7bfe192f86609d9e89b18f450d87bbe1afafde58b864684b3175eefb1b33fb423d9b38975f843d927bfc35ad482ddb5391e30e985be7ffe90fd79fa50926261b88177c2747f48ee71daa3b99dbf23444c628a9b88ada2038b6ca72cb887c60c263696a4d189bbc7193ce1ec5dff9be4d01e734ae967f91d16e6e34050ef3b31bcb04cf6493cc4ac32de9f75748260d50c432044081842bc1fd8c295c27ee6ea492ec4f24732d5b91ef038a89703e1d648ec2039c1255937527100edc7884500009381f521a798b3b6ae452d94dc3ea95a9bb21cc7afd68974fa9aebd209e0b2e39cae84cde77cfff2a926a4d88e0b4b7401a0d263c9a220a248bef3927f4a0066f971e493164ce6fc5b68fc338d0c83d2e36c6a0c0d2983ddc8996df9dde72c98b87aee7272a811ad710757dbb82ace796c53f6f03588afac823ddb14c93e4127c557ff4ac521506ef04709b901d57a1a9293698cd47fa39c09f2217bf55bd6c81731b2a9bd7d23d59dcb367533898c08b0c46616d88881725fdace303d16ec8d97b8c54879d76a75f641d11be2bd6dd5a112c006df1e1b8c64b87abebaf7fbb567ceaa10aec7817f910b907c20bc036c81cf729b5312c043296f72ae0f00054cd199465d525c3077a886e5d6d5fc340e0b7c7e68844e11ced65236a108a5906395be5107ca0f81cf190550413c17d8eae2713cca074a5ad93f52484c1acccef3db4ce898b850a29c8ce5521f0eb50a4b0a37c6246a32db2894a129d45057b3c8ced9a6ba421b4d9dd8eb1c1e5560a0d2ca1110d2cd2a287d2e0f22a8aa7384aa1025e547865df593db11078d20d35d99447ac7deb7d9de0228db82cf61c640762c1e52409143a440b3e2cd6d59c9bd911f6ec781c05ee63b557c7b83f8bc5e52705617b390c201bf92baaf1f5d61295b23a941ae52590aba8e7cda8313a3f7eedd5c97946cee1afa062bfe92c1cfe942857adb09ce829a2bf5ec8fe8dc1bc10c740aea9328dfa92792dcb2596a96241d6c4383127ff2c55e3e3ab8492394368457c69745cf362caf24452ea92f93a05adad379a0d36ebe77bacabf342cc3492c93a044de75a4e8fd5c0fc556a937c8d20a28a89a430f19b8ea99e71ba69a162a8b6ca1dbcfeb5c23a0c2dc6f46de9f5970f8d3aea944a2aeaba1a4127c3e1c32fbc4aea293fae474f25d23b0d42b19767770940ab2b7d16175ffc8a5facea92924615a4bd3c06d8f102b0d375e877a900fe20170574275b435d3bc67a0bbd9cbfac8c8c12535e2ab04b72ba0a7c38eb98d090fda850e745737e5c2d8e40d616682dbd52d1547933dfde8879387b1307afada9b01046676dd0a3922d9d17d8f758d114e0c23c9ecbe89b51c66ebf537c9b4914b06c29555f6418d339ee60c49a6c219e9c549de6c2aa0ce043e5c0faebc261cdfe8d6dcf83fd0a71512565edb233a67d384f17659e1864fcbd286bb68586ebfbfe1de9d7da27b67276f76675d18ec258f7eda272ff83ab0abf39fa3dcf1fcb933c6d12b1f479c44ceedcbe3504653343d3f80da9126061bac5de113fe0cc13de92b632a76f87e49d6866600cd6d28c0051861beb51582f7f74227af42c7ef48f268c16728af031f2197d9b8897bc7998e707cf4c3eab3ca2abf47d2759316466cc1fcd60d92e054976c2d04306f7cd2059dd59f1371e0d0b4b159682754cca00ce5a3c08f0b3e8a3c68a275960437cec72da4cdb73b1852d5f2a4e1bdfc12e9bf69e86edf519b495265021a5232008e1af968b99f4c906fa6e91ed1018fd2aabb467b14bf360e115222e173e3b08556e0ac90ff28e1db435bc25b01d9a676c986c6fda55608696cecbdfddddf2d9e39e778b6c637fa90b8d39f11b2913ee1d1c94df997c2f58bfb29fb3cf955f0bcc0c00b3dcc2d6b4d3f3659a1b022a86e8ebc47f3e24167dc7691efdfcdd2e203d334b40fb0ff48124e611553fcbfba7e83f464f989fa77e84ce7a369a4e8ac901fef6ade8c516d2b19bad958977693214769409c7ef59c3f564008ad6ae9e811def9be8918afec2297bfc1aa0942534c153692cb6e72d8a1ce89ec8e057bdc8d1f7abf137dfcef2f1fff4354a1146b78898b65e4ffc68de9d2c9b8c7928dcfb594cfa81ca60beb2e0e4519b2e01ddab074ba87740aa107322acbc5f5be12b1556723e858d9cd6d43f95c795ee3063009900deb53de25482206dd2bb01f02b4486d2cd1cc2454133ac347ab2a37f8a8ebb0576da21cc5709cd41eb3d5fa66ad18757a7477cdb27ccd86825b09d771f4d530b3564ff8a40e6a293b9be316364243b4d6e984675182b224f24d16c2d492bdf1c305571b5d4223d91e8a610abe99fdf7a2d587ae0f4d864079307e48826450ddb3092f74f9bf04789920bdd84db004190606c71625171afafe1f4ca572b07ef3fddff3458054919283aa01644a7361bc145967a50c8a40b17379e66a388d4c6e7438890e83ab38f4fd38ac3654a4f8659c7ed95f76d688a60a25fec30ee7f0de81d80fce5ac1d343a6412917a25c77be61283fb5895057329f0676f625bacc73149663a0fa6c9e954ae35ac1b3e28a7d2e576b6dd365aa94daecd9ef9f4605a61a41602eccdadb4e57d63506a0c6356bee335c69da445eeaffb767683d63bd2f9eb933b600077ecf8c84fbafecba6fba49fccbe2d272cafbfb36fab78ce77da9c0e445cf6f99ff3c9a1658a72fc46ea2d4106776fc21ca3e2a0a3dd97e89cb5c2093cfd8ca76e2aa8bc099b9ca819166f94a47380fc4a7db71cdb8254f117600be8fcab3589e97fa00ab1d5d1748c60b3621d5107af2fd358cf5c217e450ecfe61ebb780f43a4d979cb85a949d4239e4ef7d7f15e44ef7ee9f8c64793ec870f559dc2dd9ebf7b046413ea904ae11475f6cd5fab9a517634dfef5caa96f0126f67171f95e7a3c9effff987b13e7b6917371f05f415c5b893d64ccfb9ad9f9bd054090a2298a92285996e3d41445410048102001f07c33fffb567f47a30152b227c9be7da9cac8001b7d7efdddc7ababa5d336572fa96212b028a70651a1c6e6e0622a6604f6f8afb2201666b198563f112dcf1e2fa3f872d3248d93cc11be05ef225bce6092ff578eb2f52127c7a3aecf31a1cbd6a50a104d5666759aaa2055e56a599c4c6290abd9a316e61e77ce342870860ea09ac47854491957c30c35d3ef50e633d4e644bd3dd2cd1a46309689dcd4ce620e4c9ddae1249507b74b53066e0291cefdbfc841f0bf9619d827885458e499aea3a6ff85e19e3019d60e5b2b88820d0a44b7e7384875a5e4dcdaaa15f0f235c219855594782045bccee50ed9add1d50c856741d298d8a5df50768a484934089cb3945a084357e7a4b2da524a2712ae229506ccd101deeb333919492f68b9e9cd2a2544c5bf1e1eddf3395fae075d77cc640e89482ff720613c26b642525506ba894ce82a6b28e6e2496dcabf17a12d92edc4ec1e55f08de206620a100c29dfd0394e76a00f1746d9ed8a2dec27b55e968e65d7ead0f7b4d6fccf1b228a9d53d01ee86630c50a0ad447e975be9d73c4744299c241e2084ab7a0e640e450e79562f89706f45831fc333893791cfbbbce0c89862f1a978be5c1cb7cc53c78c92e0e5edc4bbbe48c3e52050c93249cc8490d537d38e1dcfe8eb9ac9a624c38d083bb536c5f67c4ac8c29e0d59703ddac4c30cd097948ce773d45e5935ea333a7a2d63fe35c3b5275cff33cd6f2c5ec4eaad42939378eaa9d7ffd29c59ffbfe89bd0ba5dd67b61072b7c4f478c6897123458b806962c5549d85db82c264aab77f7d40804a0e279f4af7def6099e27f4fa951d42eb187d6dd31594be0beade509b6cad094e7d32c865511a70adce14849896ffa049252433588bc82bbfc742e6b1a910137004ccf199196b0b96a7af183f6874793835bac8b0179ee6abe62e79ac272f79bdc8b8f0cf92f5157b825cafb97d49f7857735292825b2647a05568b70a93b2bf7c58fdac5864014c4bcb86b66a860da8d0c47c3e542d111c195d1ae966eae50ef514714ddf777df8f962f5f28575f1f446b05f63a27aebff09c756923d7ad7a1677c978297a6eb530ebd3feea1462f3fec4ee2d60cf274097098d46d44faad76ef3bf9ed85045b76268b7ddcda003f7565ca469b67b2aae3f6414447b35d84f30a10346aa60a2a0bd910573c7c354de986970e27a8a468dfbe3c01bd5a59fac3894e495c91c46ae40f0dfb97c900e82dcda79f388b3390039e55086962c767fba87eefeb6b904d64e7ec53b81992eac160260930070f5bf16005f872315ca94d34ff358119ff70387b471dedc861f38a470f7a77be845bd021dd2eaec21f5b788b0de60c532c69a299b0b298ddc17ce79486a3b0a021f64922228cc02fe934b9620056f28093f7394888e139d2c8c13d28969a79e5df697a57890c04212cf814beb755ef2692dcc1c89e63055d9862bd95969cc1109911e9279377aad8f86eade48b946f7174a63b9a5b411cb5861c00252d02ee3b414a9296b904accc6c1892c815011ed16b95a52590cce6c4f1ab04d37d570efd87640bea02d32a16c948a6c5bdc51ef21a57773f4f86dae299283aea8f7a01238777042dfbc07446ef280e728d26d947c464d9595803c0a1442b53d9bb2ed48bc913380cb42833a08d1541754ed977ad3b99932d3c3369bb32dedeb6439b22945718119d58c5ed8144e41837410f12a8d86187041a9768844ae437e1809b8273c3c63161f4aeece1189ab6bf95af4d1c6eec332b280251a359679b353e8e23820095ea96183606c93a68b32b36e8c3c6fe7d329b0f39da7afe9cc934f2767ceddcb4a676d2a78c2ca0c45e32ae7c6b4409ddbf6cb9f1b50fa166dbf2886b69c631129987767618b5d23e34f70d83456fc29ef53b4008ef24b46ef019f4c9b1e0e18ad491ce8a7179eb31a31b8a5dd9f2c0ce767ae501a7602ca63b3fb8f198ab29ae4b6aa497649819473adcb894aaf85a1a5223fcb5a2949c8e667628530bbb523b7ad62d157cc4f5c84e0d56c3664c245055d70e29a9d2a68d9231e326a837ebf64b15bf082e24d384900c60cd2ce435c324e6379971a03a9f86901adab0722e1ecd7c1f6ab9842931b94288272167059bddcafc8688c893d517707d17403ef859d1e60bae13b3feb7a43997ad684f4a58b906af1144be3ef1664a4af91f6966f2cfa4190fbc8861c9c5c22e915c527879ad4a949946d52c669f55df2ce22b51cb9a8f8c76c6ab17ec65dad4011ba8ddce61647900933cd4248ee5895fa493bd5952ce5f9614994daa31e22be0d28e0567d9f0faa4fc373d9da99090c96d1b941ddc85c068eaedd6e148ff823e6dde8ca16d2bcad06e18a1de698ddd7ba3d1bb4fba31ff1b3dcfb3e3a5c9f9a99f194783fbe170aabd7c10926315951c31ff85718364c021b5983d6a9eea50d96c24697559c29dffba0eb8f65cceb502236a070c40c840064c8bb6fcb34e00143e637c62b3606f3f854ecebddfad3b19dcdaca6c66960e2d5ad5d53ebe92871a3cdf3cebc07873c8c016b4c90e9c9a9b1151e7a99d1e748429fcfbdbb6f67c37bdc4c5cf01434ce9f29bc8b98da1d8066dd58e2793cb24eb31d52760569370158e39fe33055b14f12d25966875d98328100d40dcfc6b2125e9fefc0bba36dec49e7b1c50062bcb8c42593988c2a1d1aab4a2eefd51aba87d45e52dcb5af5a5998e5eaabbc4fcc55f30611ccad68fb1033a541e00b834b67f6333a5aa93f1d9fc99c0c2ff3f159a60c9d33e7249bb21f701adc3bd1f5fb5c0e61b17766f0c2b9ab26ec308c83647af897d229dfe7d229b3b098e39c18defe9554ca525fa8aa0ad5b9fcbbc99467025eaf96c428cdeb2a0b0311b7e267afde3bfff39b2e201460b22137dffdee559384b423c82e99f5c0b8815c2bc9bd50ac18ef8bd4fe03641d557be44913f07448c8c381b06f95b01e645c4af3400fa8ec1c6dc2b1a4b08cee2d7356aaf2e3d8205f3cb44e48fd32f9521ed51c29a25bd1682539b81bdd2c61ba87753d5329d6c5c858726d9bb3c40b1e13e4afd538d5760ce450610dc16e554b31f28dd4c48a3752f55b5374d6fbb995cdb831a8ad549f0274558ba16487db5d7271c83269cbc5ddad57d98744566624676b5a61bd7ae29a3710dfc1ce99d1252a67493d58faf71699d11bb00eed12e6b779e48a63cab673e1b1943d6c67326b92ab1e2f5ceedd033336b7874ff9c5895b44d67725235f36c88160b50d786845517194d327e35f570839e0af45c989329b4f6d6baee28958adb3654a4279c40e7d6299019ce698ad6673fa6d4b0c7ae5dc699d8fc361974997dc353635240d0be3c8f445098d59d47a291d2879aaa008cc20a0f4d6d7e2402f18853b07cccc25a37647190c1b08663bfa4b908014b15fbb20abad53e594b8f8c3fe0266b4310b87549c7b9cefcc543458280fe30a263098c3ecd65dd255890187e93f3f496ec60a804a58edb438b21425e99fe2984eff0908a69b4ec2eba6d72749673af12b463aeea162e42f19bcefa7ff7c3cdb400949387d6ba5098b736f31fbe5a524777b507c791097dc4b22ca4021f0f6265479c694cb182b9048f0289a37c699d666078ba79063dc76794ef5fa28bb1da3089b75780bb73dd24200d9928e12ec48ba887aca98b208db1cf34728d97288383d4807dabedec5505e283a7730cb58db1a49512a9f2071abc5d9ccd38539b1b573980624a6facacc84b7e8a2390b6e98246f9d462fa79ae03899342c59fea49f1b86a8c730eb7491edf34f7e481735e58124d9689c1165a8ca0eaa2f10685b4d54b9b69b8034861d0c34858c82a68f00b0a3ba26fb6556a923ff536e28fe13fa59f8ed547b27f37152c79d270efb5c93d6373aa888ce3eb5bfaf2ba40017ec3e867ff7500f22a42fcb310f9eb89e3d8893b19600c33da086764cfc51428e92eb16066b46f0b7072917adbae5b4606bc6ed10d1e53134d46635f1b1e5c14a7ba2ed90f9b416650c490930928026f9e8282420a92824004315653117a466435d7fe2357307c11ebf7a12bf3a866a3201d53b1dc79c9abd708f43dd3c22b3d56e9c6c73ff7f4d412485052c677c35f66ae4afbcdcaae1ed15039d626fb3a5031fa83249f125b6be007bd0b968e68222773b4a51bde3606e26fe735a48f7ccfbbe6a954ff7202dd636cfed42f6973e3b61927ae153ea5740ead78cfd8517ca962b55ab91646a1da00eb70cdc06f11c7b64260e0eecece0e85025264ae2b3a7a4ea21a5b7a11c44030a82e46aa4f435e71ae24ad12dc0330fe0156046330c27205e687b785540d91d7a27f682795351bfc26a36c8602d9a24282034378c5cdcc40119200c311f074d05a9e6c1b77a00185f76a545696ed40ea969b22fbacf8a85f5430fd89cba7124252db9b5d8c4a51d72d9c1cd00b9eb2cded14f624ed23dd8d30c9a34d406bd3c5bf4ba7de0ec0cd045875e170ee8c515605ec33292fdc4ed65a4292975a8a7e034b327940fb7e0aed329efd5c3610fc593e662ccd2e96200504e17939d1a8f40f518d6705ddd0bcc3094291f9fceea24f63c6d5036d35899bdf2ef81ca10cae72eb31a999a542ad54b9ffbac789481aca9277a1ac8f5c6c1899d41a928a173203cda514cd11cff5427877e9712981eb3e676da6533b09366264f443a366f2c4d364d1bbe260cf00ae40092204e25a24098324dd8f5b26d19c99adeb29ba2324c1b9320f83b11e62fdcceb3e02ba637d04d1fe5ee030f70542917a84c2febcc8758ba3e6c3452809cf1b4e6f8d56702f342025cc9741e19d99b28151e0cf8e1a29b4559123ca40eca6437fcb9a138aea72bb97e2a0ef4b103c7d32bd5884f47c37cf78439c248a29ae1359187f729a96213193648470607807ffb6b0aa30c8e19648544a41093bc2201b141b9d3ca54034eb029d75bb1acf10eb0161a261ba4f5761a70363774a9524e14a61fe0de34e92f57e53ca051167d1912a35ec70fa315d5adf3d2be416a24551a96d1b8de8a0318d7879b4d176f14b80fefc8d040df54cf2eba7f2099a5b1c9be5f24d9733eaa91ee20a57b4a95044ec946977543555ab65ca085944375a79b71efdd1d19af457e36fbe97a87087f81e229ecc6d6b352905b56a58c71ddb92b5afa38461a1e1d4fd96721065c479f45abe667873004017836ce82284f3fe32aba1677c6dc82eda0fc1492b89ddd3133b1f5e250ef1eecbc07d4b1575c1bba19d9471a5050c1d8d0f5d840956fd2e8a13c27b66c0dcc3255217c8ac82b7b01abbd5d7f2a0ef49bd2006d0c0fa9b2763d4ed10669c1320a7ca2d5767a172b6b55c9c2f651d4af6409bcbd275aedf8ddb3202420c09627f385fd8ae2754a1887ba3ef5500723871ac9b2570325ad643644edec7ca2a6e24b44bb5c3d52201271416dfadb38835c55116c470f8d63deafbd8ca63b3402459675ee961c0c88784feb4466cf5c2f1bdf3bf35d0de687d16e81b1af65bcdeaa447862634b7c2057e0fbd70e6a24ad0ce2a098c2aa3ca638289cdaa070fcf70ecadc674eca01d6aa82501e32226bf472dc4448a307e354665d207407dc5811e7e5774bfa4efc07977b15e0202d4ed6b85c016628187354a5dca47dac4cb910d923de0caa64b834ce382d0ed2bc075646f5a0a49a3879fe91f66d3a914e3dc3c6a773268e06f7a5a59ec1bf701fd4bcf371ebfc7db86b5c162d7d12122088533990cc0c934b6543b342a867b7524416cebc58c062301b18128f6c6f4478b0a8795a195c7ed62b63b1da83b16d29278fa78949ea9ea5534319ec2fedee1e17e076c9281ab7d264ff78ae490b761e3bf8ca457477075265dde8fa835bef65e510292e629d14dc0535a74fccb14039322aaf049c8759b2ffcc814064e1d903794b77057ac6cbd054c93731dd054614aa047278850f95675b1ceaa69bcd52907c5f1cc5dabb9131576548d53a587cd0bf8054fa000e2cbd03aa25ff753e2ff1a8c00bfe3de1f38e17299b27b99754de20c56793184081dfbecc45ab87452f65f398156b371536ef21c7e6d508bd2de82fb379f8c85c9eb7ee65b8bc16cd6049ba2be6f2b0d6f097b9c0350ff18058230a97c1e4476bfaa47a6ec5fd750e38e9759bf680593cc90349e093ccb018aa73e64846ac8cfcf31cdf9cee74cc2721b6a2c0b52508da4fe47e86c723867670e649b79cd5b7aafa0af540d92e2061db6d75331fdee85fcb02ba1e7de340136ba1d830a956ccd42571899e27f31f1a77c8d63d3185afe041f75830de9cc4aa2b2651ef9e9f8459c2ebb8be3e77dc7411f9489077e6b2dcc78c2601557f7eaa8b5168075a744883b5f7bb19358568236b803718972d882a656047bd5cfc326974d390b24d6ce6b857a668cd7329dc9779b7485456d50c369b92ed1a3d09178fa02adc99f54e376f1600407dab08e3403f89742c6f52b7cdfee9cfcb5def8cf16196ea6179a049be7390ebc965d325ad68f36c963b8f3226b628d3e5822ec98694e95c7e95ef200c42d9b0ac2de1af9004ac73863fc40074e304c954e4aef3363f33407565d9c8e03bc5a735c5b41bf2e06c9341ab4e89d01dc4763b0c7d1a2995f951a5496ef10e09a6edab6c7cf7db107450322e2649572146edb897eed2bca66ef8aa0c627895d27a85db54676255e81c71171f5214e66d521b278ee7f31b9966270bff0530b93c97c49ecdc27e3324af7a6277ab2a82f45b8aef09ea1d321203f91379c76e661c8743db30e0c93a523a071f797c8485a44baed7342047e52d57a6920a9c4aa9d50374786904647ea03affa91f6eab452095c956a5fa06783e5dc934869b8b15674891ac34409ea785002891aaf0a4f2ff0772085daca04eff7dcd4dd370019d8cd1f7b34392527b81ab8862f651c2a2291d72e56abbe8e515d1aa0b8b2e32501d22671d8b348325ea114730b7987c21df6fca8a464a34281641283b69b2dd89e053e98cd6d7292faa64385152be29e2438d62da23c5e2813a4f6414980f5f73116e4955f788cb7d8ee210ef16f470b0c9635376570543707f4eca648fdcbe93b85794f534621404facd0b19e23a6c016deab72f20d958db28210f87ae6ad5bc0eb849ee7b7bf6283de67db19657b94f568e1a658b179d781432d65072826c8ff3235e94903ee7d2298ae9360543fab6b0e94930c43b1b989c5f76a926cbe63b232e52eaab0ee4947e6972d637b9b016e5da6048f6f32dd3182bf1e85340afe3298508d1b78510fe82124ae079910abc43a43f424058cf32505e7cd04d1fab2971cafb4364e2015b628e0883998c0b55dac04e816e580322240bb087117914b7545b67ae25babf6d91ccf87e37edba452eb3314145903d5e81332620d70d75fd0b45f8509de1889aa2bf8f63646a84fd40bf435939b044de5a8b482139e4dc7ea48eea9e621309c9b371498b0ee68a98d5c010ac021129faee489ef91baac05c913924412ca01d5eaac592024eff1065f3adab31f72b35a2d1f994960670d105ac4955e3a21df2194b0e7520500cb860c8da0064b0bbd4f5dd65a1de55983fd7280939c931968f0570a931a31731edb9b11410e019ad9e8f8e9131892cc99c34bf580dcde5ecb727580ffc51af257acb46c624e498cc07dba2b5fcc8262d8c90ecb6257cf1e490fe85f5005483a101f0f2a0ee693a03624f3290b5c3d0916849581973df54d1d9b8bf2709c8c944d9a49557dc557ad053006c249e1df2709cb78c62d990755cc21dd51c50486c7fd5e5421b63a86985da2640806d9c63195d46d1c58da7f423dbb63cd936562406e7b6ed91b70d60f83ba0c842e192923a050d23e597437c3928d1640bf817d36640f5cd270cdd579209ac98b1d8672c2831869d8604e92c71130f8a9e19accf2a933e8b9fd13bc4274d9d7f4e04932a32f8891e0e3485e35e717dc87e5756bfabd04399da8b67e00bf7a90eb5cfcbdff191f86a768feaa6a79c7c6da37c50382ae808290ff93b21a7baa61388f804d02bc1c87d14e09b413b400fa00e55213afb39bfdc964fb5487586215a653e234c1b953d31302881454e5832fa801df9655a1674d8eea90c3f69d4d8a77443fb1871a4f650d71fb12c8999605578f513d0eb90c425b9f12c0f424b61c6bd0eb10828da7de1757017c4a1dfd3bd1feafad798e4bbe615e40d02ae0bdc07beb25f4d9b7c5c3b95ac8800c58c46b45659fc0ab80a2b5e198c0ab2b95e64210e4bb1bfd5593714294945b19a50ffc4d7b8c3cc75b67c0f271797ce3e5c47a77054a3c9a9405a9f1c8c174bf5472e235953435c38e63218e75696a9295254133528013ef9d033da757657065c4b5e9825251d90802ece04c4e981125267c4b191421bbf0c332f951c4290992097530825ac28d75f3ef3d04ae9fa91b8518b5f36aff0dd583783179e397ff9f6780cc7f975f17b75fc0971bc4a7dad1ab1981bd63362e1147494e61f33b51d1990f92c144f1e9ac29b4997a8d0045062259fdf0b77cbf76109511e44fc3ab91fc5e2646686057a30e2b9bf6c27c5d3f2732b632e6e5268b4c9bf14d027aab9fb95e3ab0a71f205dc2007439e7b25e3a092c0dd020d8605835348317f01b105c79c0d4019c4432d4a1b267e3452bf9a7e1b5594fb7956ad6fa5110c823d9b7fc5449f6df2602b9f3aae569bbd3453deca60412532203c606dece1047a9dea77fc341031717624d624b29a92f5c164c0521495f232b3a252fa3a8780284b66beaf37549ec328a7c9cc68c93af1696a0aa9e3fe175db3fa8abb526a064e99c43d714b31d1f12d586f4d5fec71772de759963d26f4015924159b33c52eb05349595678a2533d6d939b103b51719fe51e31fbb207ecd30ceca09db1c62a5f55e54cd91d30e37e1065c7d81d784eecba977368dc1f52338fb89518c77099eac4289f8154cdb10b7b5dcd11c9c996960d94c139ebac784e11e28adeb269bc200b4f63602e5778e1f7e7da3d32e6e3c68a3ee38a000909bca0d189012c6f6cc49f361cfaa13022c3784de295e2aae77256c48399ea8e2922faa0ead2a5c66da966bb6e2a15025c74966951d99b16ba171fc9d5bd893aa166cb64406aa5bc4e9b34ad30ccbccb651b7020520dc44bce0c7aa4fd5f6c69276358a41d26a888f277741d77660a2afb82b26a524ed6081941319015d53be7fb5f50324c72543095f23e140465373bb6eb9174428acb0255242fa8d6836ac14af3b2453b76d8c6c8a51a319dd56637ad181da2bbdac05fa51963d10cc0795d5010513c5cab8a2e7db1511e42d4bce2c33156b204b0f05f272f9a68960ee64627e9772493476a99a14f4ab0c3415151c87a00e47801bbd3427dae5bc7e590627143ae189841260d6919f0f4a10b2bd34507bdb059f5b8b15e6d5923331f0a3ee516da0e2324d40f98e7bf445164b411edb9890cdbf62b3c6fd76a20e9c2b1f25b026a25da85baea8b446a2c3484b44c2722450f4506854d0c99107002daa121ef0bd0c835b6aeadb0f5ae8437684e7ac438e9ca4de8b3053fa6d9f15a960daa7738d2f5fb06eee8275ed006058851fd2b6c55c0fa41faf69828fe29fe56397a56e2a6aa76975288fa6bc223e86d3628af303ad07d493f608bbd442a8431e075c5276e407c555ea3c8849a6f275010d1d23398ca20c206956b85cc5715d436462b32437ba634a0f4f7e8ffe7923e3e5da2604ae40dfb848a0fc9286c1b8addda754e7d24464bc2b55ce777433a05fe1285df656c006da26a6041ac4ac6a773429d0f79a4700a29ceeee41f1549a4492e0a8ade9a9c67919855416444d907d347f64ae879b2c30bb80217146bd7972a533028f61a70754669bf64a9c36ecb578aa2699c163254f4c8682658e09fe3b19b2a9b370d022ad584a3a75b9aea47d3fa6bb2b05e1b9d266f527d9947a145adb2baa9d5ab54b0c95b6a83ef7d1073a438c51cd2722b57c59cad55ea42e4e7399b2d9852aed216660ba1fa87478015567ebcf1a84ca6531fdd76af8f64b1f2ca702b2635ca221a937775838af7d1ef0ac0cab2c1e1d5ffe8b55830338e246947d12d09e265ef2bac75854f25fc53af202a5811cd247d69b3023cc0c2a86148cce042613209b15f156dddbddc5fa37e66c33967b2d2cb444a977d88e9e26cf0037c1a1e4e722f6fca5456b7ddcdffe4b491da1f1c333f18ac6541c61d8823e9a854c8ab60c6954a1b70166bf916951e24dd41eb6bcbf0a943f11ef3f2d7da02d93a97cbdea1dd83dc7f2ea95c1668fd3e76383dfa66a79ac0e1b4892234498592e00990f99a0c232e7053e09f70bbc35bb4c743a860da5dcf5890ed783155f9c90be530761ea6f88830dba945c283874a8cc6dc22af02a046a4df2f2004b824277e81ab5127c755423f17e951eb76ab862c7a9b89966ba88ce4443092b66ece5f2a6d75efcb6d9cdb9eb8c12671218d84b2aeeda92420b102a5c050665b3eca6d82f8304ee8b6305333a72eb74b6199cf77c38d1a5f517d46de066b640738969f12927325aa3853918a186b7ce08250a4bba26a4c3e6eed8ab4ac2efb63d7333f337830f3b7bd4a69d89a04ed03ddcf237b51b471cf99b5ae6346a305f1c755daeb23fdbc5c223f5145ad43bd8d5b3e27067cf939f375b38df9977cfab97c8403bf6f46ea793a388663604dc839d95bebe4c673716ee0b06ab2d85b9139dfc59a09dfacabd85940451d8908ae51eb592188597e466bc86739bb7b6576216a60c6b556ef95d6ca84d401c7a92372cabf4dd53b42c892aca5ae92309aab1ac79ff1fa900eb7a0b8555403a4c70e61a4e40a09194aa2c787e2836e1e5fc24f78eef8760b09e49640fbb726d1fb78871d94b1bcf7b8524d9f6f74fd919f95b922aae994d0b45e2da1fc4ecb91775c30d5a52a95fc5c62b8dee1e1cc64dd0e2ee540198037d82842c01580a1b81321502b314afb0329de49dfe3515a628ffc895e61e7ea649d761b8aee296c7573ec9bd3200a4484121938540ea27eec628d16e331656f39d27e85e6297300bcdc05f58972cbbc65a486773c2cc473fd15a56aad549494a030cdf6960c63297b879ff8344b661fc1ff03947dd6fa53deb28a0867c922a9f43f0e5a46f6178493053ea1f931a21bc5734d12546d7894838ef8d2ffff9917602eb8644a9b90b74f61eca503423005d3e42108062dcb88f55cfe8a0e19b20a6466da637c189e619374d112f8c059cb45e1a0459a736e24660ea21f69e7f919110dbda48f96b0730d00fd88787525c63704b77ae2d0f048055eafd4a5f2196835797977cf672be0aa52de41f18b2328d8a9d54b12f211e314e71c4a5ec83a208f9abb4c7204b9912d2e7db1cb248601d5fc4e7ab2378c1ae5feb3f4ba511e51a281d868a3047f894fa8eebecdd92f6b6c9f4c0532b27d8464a8ab5e49510bceae570ae1986ed65bce437396cd97ed5788346e9a7b36c6ca05fa638975fa64f31bebfae5e61a6c916072e9d4f240fca89b1df4baac5ea66a400486bc3b6469af286b1912d3bd846c7557ba7c7b1fe1842a145fca55e761345d190c34aba96bf6081101a8f9d97e8b838123d4ad3cb8965113136b1a31669bf841db01671624af68f0a1ba12fbd832201d6dd338f4d8995acfdcd5b8d465eb983ede07f95215f09f7ce47651b1100e94ac2794c4dfcee895ff64b1af7e263beb8abc6ad7aa776dc40e5ba0a0ad28297060e0b2524bf34c1488c486ab34416f5f7129962613b2af6dc9b4b651ed6dfc92560e16a03bf66b3fb2d52fea6134a2a59b0db42635318ea59693902a14e4baa1345815749ad87312024e294689c25ee8f58ecd8a94b0b3c1f974a660558362465cd12c9713054b839d44118839b237ef6a7b6af14215693641c602c9b85c94ce5fa521da83335912d4da295947f79c7829d38041aa291a6c1f645df395b2f50f69073c66a60bd4af924b7c335b33e53e95e442593e85ab7a6d1ed9ab289b62ac5cef7dcf97683593e33b267b076d51cad9cb5c100542e30d4ca1f522df935fcabe2aa950fe9865b913d28270c6733c678e59f613c568a8eaa9b0dc89b947ffa00d014b503e07a667cb192cca3dc5a4d4527d6cca681f3de2b9c41ee6f8683571a26d325eb16d6a0756449920a48496e64180de4a408c3df292f03112b230827462eb3ee4172bf59a146046863cf28be9b7ab4a8a2d94d88f4a520e25d63417799fc69aae28622b9f9a221f66aa86884bea70a0c33dee5e8f8c79352762ba9b41c950b61376e053eae6ec1147e320c4dcb924051612a0538fc9328d6fc3e4189ff5b3f801f540d36c2494b9bf5bee15172976457a0b3e487b1bab61d6c0572cf23640f2d727e6b97c54b283a8e5a3c86a4657a25d420ce66279b69b72bb5b4c33f74a749270074a4428a09eab433555aadf47d4ec34c1f8212424478e4eede349388b452924aec8f211e0818334779da6321b3156dc37706e6c2addb57a29468c3abdccc6b1dbaa277d8614529ad5ae46484065a5c4c51d06c7542923f3ea6c7c8e43e0e99ea41aa614f936732129a94e48722424cb252fd1fb7b34508f93d2971776a82a44cf266b41b4be459e839e87c995e644413daa43519aabf9c986d974748873ad3443f1fc59bc132c45b7f95cdb65e688d12ed5b2558c0ddd746d3f1b5034894be4697c5ae55a40499d927c8c11015b707f94d884b681e8b8b665253561eef85c774b896adabb345be730b97e738c5c9e3814246b4663aba6f71470820e0ae4fa352ca6feb392aea0b7d02cbd2747d5fda849ce74c1e6ec356f28b9add8a3bf0930b6ef62d5db1af9b9f295de614cc8c168d10fe5d8482bbf55d83b41bd5a2c3b8c151e5fecc3bdae4f79c5d2eb052596c5eb7b2e5ecb0b7f032c3bdf7d74780d0c4601126309a858bd82174c1792082e1e989d305560473c7da9b03299927a5bdaebcdeecc4b7553fbb9f2678c1a5b847e1de2da658d5174d2b54a7b54a66d4865efc7bdcc4e30e2596c65c610d37fe13cad99e4698dd4bbe3ecd103806138536d63a93c463f1fdbb45c185884792028c882c380d22a6d982fd6edfac45e2d38499978e0d2de5c12172187362d53f2007323582dd7ca893418a98e29cb0f8d142902f9507ee3f20a3c12b80013e07a73d0c86011e9f9dc902f016673cfe8db4ee5cf8f6a82ba35e9fcb9da48353238952d6e59f5091a6f9664dbcaa4a8e274000d52bed321392e924227c28f5af411e3724e55aee7084a27e110338acdde9c01040edf670828977ba9fc5629f317721329d9c06299ad0f9f39d312655d05019d553bc65980d3552c8efea35f1442d84f6d484553378f5f2131cdd72c6751f5ad54e2f50bdd93fbc9daae7ff3821ec72118e11ee7ea912ba335dbdd343d598b626ce44b8b1d6312ae564978ac8d4a8068c1c7a8c8646dfa7abbc844fcd68122231f1ad47b27a29c1814f44f99cfea28c25d9cce8b27ab0e37e2acd6faabdd9f5de3b9bec6fa61ec3ec51d34ed1d5b94cb30ddba83a764b73e2a79a86e747d0d3ac996c9090974f547b93384a323b43b90ff59e55a81ce9b23f02a8fc785e23b9a4165a86ea0d3adc4aab2cfd295cc6e68097b148b0139f04915bd0e884a1c2376d4507e39a2e07d40cc5e58f99fc798ebf676deabefb1025a85242f52573a0b1228573216b6afebf7de20bdb3eabad7ea658ee832d34dacf732f7bfa8a6b64f3ba20bb0513bdafed98efa69562d47edc8fd373a5aa81df9b98e56d95d5aa30ef488a6b07cfda6cc30e7744c20fd1452d722c4532d23b755c53433a7790622b36250d54444d3c8f234f0796466339b0bfc260856c32747b0ec2a2b94650ff9c699cc9b949d58567c7b7b6a28a375fe3f9a9a5aae7d4701e7050aca67694cdd466202a82845acdca98aa2183c53a436c4dcadfd9a6365ba8355160ce6b6041659110250185b5be56b9b645b8489afe77871936c24d49ab4405136eda4f8829218f5b387c08c888b01e5762b203603b3530d3ba4f07843e66067bf25557f620eb09516a280ba4f504ce826c63a230d74663c5265a875b66a5a27414b7893fc1c399e8cee16057a012a1b1d790b074a16ad3689c1155237c25aba993b972b28c3356355b717523da3bbcb13eb9ec9d199ca5a67aaca2e5a68b1af219b5869764fa0578ebf2898991dfe0e17222fd19264ea40ad544dae350b2217b5e32908bf75dda6ee2255e1b0e14d2d206636303731bb00efc9ed6eb3200b4f99c24b9b9672d9faec9da7587ec80fad4ade13fc41f51a993da419920f02b3fb9ce4f95805f5fbe29fd080886bf383ca0fd60ae15e93a62a7790cc61937bee091ff9fae1bd75588a1028cf7541d2f219cdc119fc1a9296f24d754b56bf22356288d832a3102c2ec9c67f7cfd2e512e94b7013e77e1722ba54a853f421a301fd8f67f8a6abdb2383db37f9dce1b8bb4747335cbadb78991066ff79a241892b42377c457b7b0a578961245caec24abc8569e75eefa4794dc9d730bb0d6ad41893ea8badda7d43678d867fd6cb3e3a0b4bd37731ab97d9d34d13bf45c6a90938b7816c3adca300dc4149c2a0ebea4200a72c76af84068cb7052abbe873ef4f50385156f7194fd3cad4d81b832ea710114dcaef6dc2247e9cedccabda9d1dc642f330e2aedf3cce62e7a046c49df20902194ddc2200da93e8653f901e55d8613643b179647cebb35c75000c133ea7490ad1545ec7f5270c7319fe889033764d83e912bfec60c5e8e9314900e94188136bfd13294dc7e6020464241211f9b404125db8eaa214949aa8fbab95a9a6f68482577d73e86aa6c17f969efa8c6a2d30075da2821fe2aa47895d7ebfb70e28d3915b24d289d073bf92d1a18feb2af529a97d3d77db6693c73ae04fe78dd01192b346a6e9a9e46ed8d3f50df8bd984f4b743d7810f8f0d962eddad5dd0cbf677e6bd84191e8c72294130f34353a5bf748c621787a237ca94e13a38ba7fa75e6430d4388e993d79095b85adcaf6b854d7bf490b4169e552051ee4ff2f4f6002027e82d47e62326d95da5a35e2348b060e2b93024ea10c6f277b153809134f8e9f794260e7bf7c65150263bfd0afede659fcdf4c2ffd3914fda3ec5c3343b070f76323b82b42be6ed274c9a2ac982ace60bad0a60a9e3925ecd26ca9b3f0992a1e2847f09122c34941d14ed003ba6dec89475255b056f403ccec9bb4dd31c851b4d082e97e619938b3e84702405a64d3c080da63164fe2762506c7f6b5ac73523686fdcc08cd3733dc9284e11dcb7bd91174f51a287302befed87babc71f976fa59afd5f6154a87c47efdfb701a4954314cd6982219f2d97bca99502ec6597648f95acbf926abd492d9437086cea9c9b551549692587f89c5ab89dd5d3b6d36c79a6ff72461f9c5323e74ec52115d82b162700d8d2c13cd5b7b0ffd302d35fa078e190af080cd24a6d1c2e061d84a85fe32aaeca5896523917cbe70c9d285b4e738bbdc6a83d0e09dd57302fdeb0bee504a5884342b4d9add079688961430146cb2f091e8210db3a980bc7c53f878595c6e11ca908e7ee398d34db3fc32b8f683d487e78a97714955de1cca3b892e5030662e05c765b84e63dcd74774013cafe80ae0b425e937696d516350d0bca9ac215b8688fe22d0131802675d84cd06daa851e08c34282690c4af4dc4e14b7aa0e375ab3a057a254b08b4849abe95382c4f556b93528dc92005a8ade3cd494f4953bbdef43815941bf98b09c51f57ac0203dabcadc0a6480de18655403b71bdde2c2d0cd061ae2aa49360fe55b2e20648aa80b78eefa48806a4d76c98539921cc36b657f2c369191f27d8e204a55f9aa0166e73daed0a5d82745e5a280e75eda667d9e8e44bfd191b2ec65bda5d8c580fd55d863aa4a01e69cd3258bf968198c0f3b66064c792364903ab035447bc38692719163d229b61cef48940b5f472e9d5bcafa487bd2a2ec16bd5c8a14ae24c50e2a5cb16a4fbf2705e4b0b275675927556e9a99743b9c7ea7426cade050a01870ae5a6e8716d87ec6481092f2b87a2a5756651bd0356cd9860b091794842a91cabb086e2baf45c167f3f8d2454440af979418087381b3c8be89f1bad668f58b166a36b9fe2dd7aee594987e8d6ca0380b0f998c058961c7909877325403697a3884c0c535d0a9e8404aa146f0ea8d54084f53c9862ac5508b18e04f6c5745aa33cc186f54bb0de06c0a4b45710e3a458336c7abca06e0e2a63e286ed7e5b962a5591343dc20f0db6f9101652934b53ac9ef3711b18924b9e0777e2a1e2b3e301bf2162fcdbfdf76f1359d564275fb23c5dbb9d121f901b717d88b1eded3b190b421a329655ca0ef0927342fd4977c5b38d511292891b2a9162c77617d7716164e6048ace28612eaf1a78cb328430bbf7e6b0a9e3a85f99f9802ef41815cdabf33561e86f474545d851b8b0c80928a2d1d5e23493629e323410e769de06caec2c969b30235e3a0f8577a63db62f276b32535dbaacd92bc14c89547907fa04ff6aff7fc9a0d2d93624627d33277ec60a5f5ee314d8a03eb8c653686370e91891edb0691fb0f1082b30e8b74b01312eb487ea45472af63a83e243e1debfa9ceb4e4820130f4cb2a5fe4fcc8e87244233914646c81f4d3e3e95d331fb9c426925d3fd9c1d0ce9f9c51b6399116575a3c13ae70703a5df6a289d808eaae11bb283d188551bb382d8ea130a72f88a7893bd756e52f2f4582b0ed48ccc4e0daecab846fab98e38de1759833186c6d2029a01fa8d6e8c045856b383d5f3aac4fdf9a7dc1f6c36b1f3ccfc3367459cf461a358f98e1b62aff756668224281c9ae81f7da4ec0cbb764f9defbe4d8c6f239334a9d42026b9a12458ead0cb45536589a9df32a59faf9013dd6e944e718fa4a079a02471c43df02a6375908406593732e99a227a5da8f3f44b54097dd1c0817d6ab16c70fea480de384dce67e4d2649d16e761725bf8c64b87b374733b8553a23a5b87ef33cd9cd8e900f72191c99908d15292a703b29f89af96526db07b20767f54b28cbd5225e2cd192c0d4e037592852af1d3680d359c427ee9b7812f1ab1493033d8501d4cf6e9a3784b26d1c30fa59b5a51baa9c30fa59b32fd3bbccce45496dd8b93383a5c49857a4a537405cdde8f6c1e1ed092d20dd3d1bcdefc87d37845d9358bf621c57ae47bf0d5d23a99f5893e310d41e3247b59d4a404a580b4b31503df049c1d6d11ad3d5a7495811b74f027854de73082d9f88ce9f0089d056fab34d0549bb5be6d1195cd1df2042820b9a85082de353920eed7c8c1ee491e8949af9f508e28b23eed88099534beaf565131c5156c64ea5a8adf634cd3db312a59437ddd0494b830fdfaebb141e011b73a13ed850486923a94556649e683a8a4368b61c6e99ff5eee44557258308a74714dd57ae14e6472eb54e1eb8954daab81f71f61956d5677b2dbc14cba6ae97b1e18ab4898ba3dab6b5325339afb9529462d1eed49f250d9d94a9054fe3a0383db4c31a2c4fc99c56de50704587bc6860fad43226955f4253649347acfa631d233373f6e48342e750805c5b66eda138d6bb6d0c13aab113f315a67eb8529f16619633a897119fb9e8b52fdf3be45b935035822a56ca1c367dc5e3723f473a3807da66aeece28ddeddd8950bce6061fa2f4a010188ee9c923ce952be33325a714457124955b178f4c89396256f1456eff594b42cb9059218f0dcf8aa2a941698596d163da6d689d44523ab83a897bb590056330eb1e292da16f6549502446e4ab11355553cb536d08b3f938fd35b59807a7668806135c662459c353def126477e6954cf56ff5759fa3880a84b592cce8fd36bd5626a5f4946a94c4b09be4cc02cc1562458764b6ed59268f74512db5ca5dfd2c5b78341991aa61d803990a6c5980a3aa1b3eb96d701e6a05430c39edf65eadb1a920b41487e045ae1362ee242a2ada05968c17b7145d46639d71ff8c8fd8b54bc909b9336fa9a44443eaea8e1b9fc0db95f6f71ca93a5031990811753f3c92b7c9c6c2e4b7203b9021809c863a6b2bbfe923c10e538aceca9ffdd4197bd63aec82b32b874316b3598a40c352cec43a2fd1aa7ba4f00da7834ab9a000c2c0f10ab5bb042795aa029c7a9ee28811d2620c348c7c09e61be5a5927331d7d23375dd33f97519b22b7131398fca1dd45ea7e39662621aa40934b986a8e3c9f4f600c88454952008d295d5b8cadfa6a7943d413d59d4ce7fb5261c1fed55b294ae92e02eac72bc2a15f54525b24f59390f54f498d96ab264ae9570060b634ea4bf22f4e377cfafb2db818bf71864222bd118b6bd807b5aedea02eeb6dd0c23f706e01c42999f93684ebb6dc864bf533c53d269386dca08499eeceb0209526b4094514101d3cc85a2884e666703dcc92391e43565056adfa6ca23b43685dd0c42536104ceaa70a45b75838942cced70b32607f1b02b6108982edaf41c1c78c6ab304025394a7f0a02b87047a3ab42805726e750f139f992bc010d23267b4e3bdb3b9cdc822493ce79593e8be5c57f667011cd3418a99b4680eb4a30b8d46ba1d30371c06caaac2c156dd5d152707dcabeaf9786aa08619d45447422de92cc0e9aeffeea1699793ae552f575e1014fa26cfe999580530d0b0a052516b479ca4222bfd124649ddb59d49ac3f65eae2450ce3b48e23d9fe2fbe156a1c4c9379ee513d28d303a4ef99a5ea6ab72870a914928736b673bf0e9a6b19c46fbbc89143b308f8dd004f78d14744d8b25b77ee53119a490e5466a00c850127c36b82959844841b423fddbc64cf71cfe45cad065e648cf3040a0ca2127394ce71559e78607568e9850ee15ef7535db271951951efd3fbd2a0a220f8dcc2a7c4e524131e77d8e3967243bd6f5597e3ab044b372e921038333dabb27045f22be86728d87021a0eb0e8b9b14bc80842ee18f90035be2a9d3d9cc50d40545b9176465c9b941c48d275e745741662dc5bc0cbcead8201dd5b014b31e0b39a95f9a91d7659a705b71e131e0ccdf462ca34c34b50fd299ca09e5d4319c5a7e7dc01a50e3e569a05a44f5c64ea18c2a12cf50252569f6ba8d77aa9b510e545c2fa218547fa2deb4473007be6e4b2c283ca109dcf5c3a9803fd3d26d25f26c5a803be8487185bb596d963549a4d403932d6f5cff9b30dcae08469c7d4494238990f2c7490b8bb08851895b323d0f30092ccce57f760a4b0c8c5c17e9cf55273979f54532d132386c740c9831c25d7d2f1f1b571069846b8d61557a6da7da85335bcd201ce76d26c91c79e4bd37fd06b5d579c63b58b1c756f7e511ce96eb77c8bd1def25239b57c3a2497145acee124a114ffd431331cbb7a586d525a7111c180de739a193f01701962ad56a75bfbbc06e7b9e11c97e0ee9513f0d31338a17b7fb2726dad7bc4cdf306e7cac68e75bd2d183373ffb933877563d5a1eefa73b3a02444aab969048d7940b7ac350e4279bfc023b70fdc6edfb953b0771901734716db3dc96d4e99a25ef143581c14fa02edc19674272be594042d9aa042df9c4f6b5b58c5352aad0f4fc8a1d4583db98fd975cb487d046b14ea8c81aef5950ca998e95d13be0c0c0706798c6a8a61149aad0daf64140b50902397d7aa424c7979697203e48ff0b557a26a1625423aa59e0cab567a41a5d42ad5908bbf55d236f8b41307557d70ac281a65baaecb126b71b7ab1414d32c8143c8e2d34f03b9381b56d3a1e03181766a1b44723b75b8c6f674b8b0c4c916f6ab2ce4a371b39712998ec07e4b63f5252e51706b41a1da4d4c3588a5f36abc0622179245e29a03f46093de6868d2244a65bc46b50bb22555db064104deac3a651e0360bed1755273a9c5be06720022412e32f9874aa62b09216359aa8b92341c94daf9cb3ae6f3adf39415cb9799da9cccec7aa9d18d6e6ebf060edcf29bc2dc2a2ebb4220f448c7e6223cdd840e16dfa7643935dcd69bb5d347df200095ba0acf696a6e45ab7646daa7e269fa986543f5e839bdd6525ea31bea61d2c954b950e46a2e438d218ae8a0343f535e05dd8c3add53d3f811cddfe33a7295985a1f998306b30f696e1f3ed7d60ebe4620621e19ced5dc3e104aba891d4a7d097999eb59d9a3af77ba3b4129da5dd4f07fbf367db6b6cd9b88fb4788e48093eaab881c7004a996c9fff66651262f0cb18e243ecf598ade3624b8fc982c54ee28b2442d239a213bc1b9a14a88bb6e96cbac1cf43f3a0d33b8e3796c9c3e5b96411455b30094ab39cdd739978c2131de6376c958eed0e8b53638e792401065d5b197679796a1114d74f9395d192081bbacce52dc5ac8f67ae3a3f6f266e7f4d9ec469ee468a1bb39387db6f189a5b572408b0ee4e4b2911361c57fa63f283d8f7573fb1999ac9bb2d32f8658dd560cd9a97fdfe0c6eac52d1df47967e6347683bd5f243ed1f398065a608ec1dc31a92072468928a1a445c08afbb8f94c6276b16998eea474b9871ccd6360aec10ff3a638fa85fed73747288634d106c10a45d2f571fc920321759c4f1559889052035242d435d9a4d3dc7c8ea232e7bac3c883f283748b87a57e5210096c3525ad813f370e0db05ff5d2958799729ba94472996efee6018bb47c4ee9f31d4822659a4589c47b447a2d645e61382069b232985fef2aed9c2d870ed1890183a8e4f3a5392d70f8969250628ecba306b4caf638334d50ca2c15cf2156a071214d2eadb2a61a3463fe15924c702d0ef1534ce9f6a896498b6b3af2c20050070eda3d4bd0cf4d5d5e529679d354abe40559a12abae535ba965648d87490ca569f046f1bbcd470e1ee67788b8bac522d59bf8d5dec28104d85aeda4209e543819598b2da9af26dfbcc29718ca18fdd1d7c937064833a69dde38dac0e74bdca053eaa05127356dd4ca3f240d7cb74901e94022b934094713c752bb49faf024c400e9da2a52ce984e74301930d52359713e33bc0d7a2ac03dc72b155f5a1550519b4ab8a231f714296748883ff58e93f8fed1c348c4b969c02b26e7ba2e7c7033515333b851310b71b8aa9ecc4e6125e67f639bcd0f5f06259524a8c56882635bf20731328f18f5c9b4091d81b0a2fb528196443c67b42eae712f610d1db989e4d2136052f3904e43aaa3303dc511a228f832874bd413f97d5995ca567b1a2dcc1052eb55d32d29c4525cce4973bb5946374142fcb1de9d4640720843898fdacb03224691e44d3137414d2e8bc98d863c7fd349488023a65ffe2a08e8deeabf8674113f219f4c0db9c326629bb8599c85b14bd94c14b0e566172ae55158514d030abd0bc9955029cd3e7d5f0f0aa54f8039560042c8af252a918a6e48249298ea594bbab4bbf4e18f59e69775bc969dc26c0edd05f2ce55246f8c2715b842a2aac5d50440d56b6e42bec11b3e1e0856ad236079866f51eb3950d73e12a62e0752ae671daec98362f69764f645dde1852add0fa54ebd3d9bd0e6f53d6a6405aad8c0b90daef49be6949d92b0adfd6cea401a2c37ce19fb27aaddbb4f34471492a22ff07674a09a71192ca54617a900e87749232c072be62b901c1a7b4c302f307f4d7a9986943b7acf8e71708044af4d7a552297df5f4c91b2a3b7233ca2a0a1d343224a6fae5b9956dcad90f31ef21d8567082e3d7a7e7944d0554e97472b0fa2766eb502de14fca5593915c55c6133f7091e3061a8a4a0e1f8052be0159ca48f507903156e4d0b025ebe4c65368e3da513cd6bfa4ff542d6f0456430cdb53df4b04b998a4ff96c4d69ca3672b6e5243bd66ea5dabd31e281192732f1facaf4412b05bd29af281532ce448d7fb9c517573cb950705ae008eb463f27da790026acabbc8bb2a5de24996a7209606ce68a6e7a62cbd201121bba8030656ed73bba98484a69b30d0f57193e692ae0d195baa79aad0c806b115deb19b43d35c59f98dfd63f33215944c73b6df62e0da27213d2758446b418caf9f552c73297e3ada1c618cb6885717cfe93b68b3c75bb9512add829c7b891388b0d7f172478e08b7eaf251cf365174571e95165ac5d2d36a80c54747997277e4021452b7c78d997ae3a3e31d95ccc198b17c33e0aa08ac5c04f5e68e749270c148ad4b91fdfcbd981d328354de992ce259ae88d86397bc54e24d76f0d68b7c0d2b943b229e9e08878bbeafe50e0a2ea4e05aca6f942d23b79dea9e4a4ad321b7c7e2280355681e744e612aa214a3876516a65ad4b48a46c72dfa7150766604082520484cb9ad56a4248cb24d13a313af66aeb098c0011bac5a5d1511a4da9714ab5afa697a23699356dec9d0ca7cbbb470a1b467aff956905694187b21d5290ed79535a967d7bd62d50097449833bd16c23f8962e2f59e5e1fca164b0700085836eb2674fbaaea7be5a25238ae58c536244580d649055bd757bd8c88e1a900e84dd302b56439bb59bb7d9ea3d888065930fc09b2a093f3a867a89bfb5907d1c7cd62dd23cfae542e6a50d19184dac46e9fa72bdb6c894926a02e51d38ddbc72b062abb86a26b2f37bbf9933ef72fb89a9e22b62156b891a5b5969ee282c8a0c6b889a8a5daa4384eebd263c65cc2d7dbd8c8e83d77ae14f0a0603f9d557bc5e0d1a22241f339c98d658b73df42faa3386bfe53b2717d67cde7fe955b75ba1e6635b34be6041ae9928fca9279cf70c9a66bcb35972dae100192cf1b5a67e6847a5944c8ba037d61cccb27f45dd1a5e498ff3da57dd95281d04cd461ba2ec2ce7451e8494a33fc1134f9826ea75fd4a7e5678970e091f6ce23969a1151432505075058cf6550a05802f35dd512c2cc9eecf31522410e81fd967a6a7fc2c24188df37b859db2ec789e53623b496513715d0fd9432f5d30414cc32f2af5c3d1971e5bea9a0d4250103ddcd00ab150df8356ab931194384f6d8c17aab20790e8d66b2d020b1a063a8d1923c21e654db5186cb0a686f9b34b3ef2225fdd1c79a0db52949d5cd14d74a47aa395959f26a0a4a2dd93823003253a572240d8f6ed3ee941481422bfbde225e150e95ce3cc39872f815b39c7382d8949dd80724ae23f238b8591340e38c4d98d1584ae9fe24ce03c8e8931a480c7e89dd40192537c509a3e2c23257460903a6aa78a09e01c0f900110f01ea1be187fb121be4c125b243e6a27b5d7f2c6034ab03aa15b091a286c75df72445be21e91d9ea7c08e15d7a6d9dd820bfc45d12ade98bb3e703d8896eea1805c3f41deaa89f1ad0f2d8ca01a0b26c33c52d56bf19385d5456e90d9f08cd69ceb778ae9542fe9ab81ae3f427ca1b915d7a33f3880d4d0d5c5aa7b33bfdc2b8e746b632ccb90ee634a3562475e05f341cee9b950ee15c7fac6a888738a0c7d8f294646d52d2836ede250b7e65c1076b404cbbcf949008dd9139b55ea3f1627ba73f1759bf9b0d4bf293eeadec5b39035dd8b69f15e0f2f200d73d7eae0d247610580cd3356d4fbba223e4d2ea0b0a479519ce8f50bd7e850c7e50926b23475f3ebba83a296e0f0accf3cb4b39373369f31d163c9b803ff82189b3cb6da82a15b9835830fc2ad2219acc2612dcc2da63358800756bf21c6e94dc924366c82cf6234108cf8667009c4ee5e6ca0f922e675a917c7fa7ef058bcd7eb83bbe2485f1a77a826a0a8e626f6f3500351af3cde0be0db8ff536629d315ae443036a611a0d32cd87889e418e1909260ca24a9d7ed1d6fb25c3c7bec70fc0aaad292602c03e41ccd9c651a77896a07cecb4d034bdf57188ea2533df26d69f1bc4782893398d57278b396ebdb532f807fc9440a302fe05d5e1e73e3c4c8a8f7a7938d305d93e1a83a2a537868f62bb0bc3cf02863ad0a29d69d1193e141ff4e5e5dc88680475fd63418ffb3583e2c4c716a0d80dec58c368d18ec5889efad7356a566f43e0ca4c340b808b18007a184109d0b1586af7c94755cdfd3eeeaa2b6b3a82fc3e1cc559dde90e52ef317c78837b841f5ae2c4f52f80866313a8fb575857c3e08f5c625c1c882f345fb093158e7b1342309ae51ae02e5837f635103103239e035eba59a0cbc1c6a099f28b09c0eaaa0b30086959405835afbec2a9c2bfaf310f8d98d0e06b0921627c685b786326029523387f2ade00c21ce8fa137869f5604582b8f781b778112767f5f874c45eaf0d3db97a284ef5ddd557315553fe5a76d14d44d023cb378e0c34ae805ecbaa6581085142e7eaaaf8a0b7af3646c93905be1bdd74bb0c7ce142d6b130bf8a2b3dd6e763bb68ebf13832e8d68d0b99550291263b6c03e5bf490b2225acbb3ab9bd349cccb410699a8181d19a8f0d1a1d83bdef29ce9b42bf19e3ce044844dd80d8eda4a0deb4d1a2da432bafe0cf4853c3dce684f2ebb825c0d5e3badb876250680e7adc638f230812360ef8e419c7f4b5b535ca73426f1ee539813b64ba06d8956d20238fa06d9d24400127488f272bf1d48fba4062a6500e037f328f864f9d2d3d3c54b1ebae018ee7c1f5b4f8a887d75fc50debae705fc77e806a91431599adabe2581fd68c4ef6d4cbb81737d729c1ee1825f7d5b15ad78e1072dad72f6707ab5631c3d5adecce0a4c7f8b8dcadb2e7134a0d9428460aee8d778db9583f938987ff3507cd497379fbfb3301c6ba68f2ae60aa320c74e278774f401e0b0c91ef6d1badba19036de67f7a309a611d3376ece1f21f0cc8fb94d140035d5f5fb1aeae71fd10c52e9299064cd2d31e240d76fee8b7d7df2c4e7495db4abe8a7fc0521abf3fa09d46eede2a35ebf7d864dc1a0db71ab8aae1105da93af0889007063de7538e30919271e747365e29d1a5fe6377e35b92f3ee8ebc9ddb9319c1ae6947b2a4e75dfa8bc35d7e8f6b1f8a0c7b75fdeee67acaf8d8611d0d155db1693d307ddd431bb4142832c007999d7bef22c06057ecff48d8697796f17c7fa606f6c091bed3a2a366aa0aae5a124eeed20c278a9873d39eb35bd3eed5b04da14d335f927c67ccb4ffc3dd04574e71e2f0a18368a8d0ef2736408622c6c3ee9101c163cd0cc098e732676e2ab5eca2f4130b21d081434f7461572221261105f9977782d1a8664c012a382199227f5cfc5a13e785a515d5265b704da415687c6efebfd4fead033bdffccfb56ef6497444a80c90a327b9bc7ee6a92dbb323a4363623bc7ae8233d4e3e9f43c3add3cb2430d2ea682196169769b3b394cb64762c670ed71743c8bf502adad0c8b10f714dd0340bd3910e6b09d0f49b323a2b3e154d2a5d3970e7fdd3cf842c62ea269a2c9165b9f1e7e7e68a94a4e5aa9b875feb66037df446b476fcd12c754179f1882672222728d11b5d494a3a867f7662368aac0fa05eedef813e7fa98191d9ec0535d4c7459fd5239f55206ee0a963bcf27b71a07b866ff289f72580a0e7d392b8e8575852c83e5979581ac5995e7e001f5bb3c74a5474251a040de862d609146a6c06c60638b107cc3afc08e9031d636b2c20ddc2cb28417ee9d1014f38b3e762378f8b86b8cbe6179f9ebd0614c40b8c39bda8433e41f3a98115f11fdb754b0cf8d4a1e77243c875e65d85da97c10fc6bcac60a8e3e3b2650954131801cd60d3040ee86e8bc5011e774df0277ddad373dc8434862f543ce0b1da8409dcd5e8b98ebf3f35e859483413dd7c6ad173a101fd7f1690de364a0d921c803579a09c7f23024c071d8e046a00f706148fef05af88aa2dfc379c2c08d413328c4fb1aba96ecdaf05b701b2c8a884e68d18535b0022dc1851c1c2cf4cdd0cbac7858172ca48376780a09faa283a95518f362990f3e2d244f22e3a3e36d115061e10df571ba851f031a7e3c302f26f0cfc0bf0993a4e207ab33c41596814b5c426d72f315070051279e512ec130f6108da82d9a221a76d6256c6875a5decf5e6f25aa07644d397881f4d81450f55e9d0607ea29a67966e3e7739cb90f972c9659bcc5b695930af29358160f0a7b0f109b0ade6ddc60187cfc72d3e7f5da345f121c2e72f6507aed44d059f6fabf47b8d7e17ecafd86cc1fef6750bef84603beef5ad6f3c161ff59d6f60c2ca0721786c7d63529c88972b7e39112f8500b7f38d845fde8897f7c57bf1323af7f2aa7863ae7c03949fa07c5f1bab0deb13205ca8861a9c1a2afa6ef02db9b6de54d0ae0027da41875bf043bec7eafe66ab5b1c5f3c1fccd2de285afdd953616f146f2e9e077e0ccf9ffdbb62ffe2e9eb7a231817f373c030d4a2fc9998c3735c05367c0ac09d186871bf69896fac7de6517f2c77882b6fd52ce5fd8340f5d6be4b8d775f112ec519ae0bdd932f841891e9f7dec35cbaa0691dcc5dc1275e63ca8735cd60d2ea1547fd5d0f75b34dbc9ea03bec1f5105b570c407fdebe240ef6196714c57640ddb280d4791412eba02580a2025a05dea88650eda18e0895540811b452b0f2ad846e0095db212482aa50f63cc65759350b7317ced5c8040ddeaeb259482f30a2f64b0ebe8a9b4404256238c4f9e0c5508dcbcaf0d043ed85bed791f154ae27e45c6aa8b08a90fb78712b488db33444fb5fe6db223b5d69e48a8d82b450a412978808e093ba3851159a3b6ccaee42b3ac64a97f2718f0f08bae07a6fb68c8050b9295f5a89c97d150e18965323702fdee856c5c0d8809173446c4589b046714cbcfd84d4a013d17cdeadd03ab0d60bc85313dd7ca672c1ea6b55cc1ae883c06cd1a7e11ec10db620959ccc04b70063f20f0665567a650b6a720b9a38e30dc05dc70860b5bdc7e5217d6da1f3845887e59bdc717ec9097122f7429478569723c4bc47dd7c5e65579997fe06fa2091ab5cecf17ac22aafd28947946e8156e9ffe02adbd955ae6895e1ababe48ef3a79e807aa4420b7c6d0f6e4ef6e0008b359ffdec1ee4a5d2813e88e41e6cf63de4abc41e80a8b745851896dde81e18fa32ab07e61074382615c53f05dd7b05744f7e9cbc01d7784f6f74ebc82d68216d0059f3799b5d5f2aa80ef4c1d6e009edd4d3fd0a77f25f5bd9f9f9dd9fceaf40fbbfcfce2f958007faa022e777d813f216f37b928affffc0cebf85345edd5c21fbdeebe6f3313bf954241ee883a39c7c3bcd9726a6af5e8806d2e656160b65e492dad9df58be9aac21b38d79843c33a62ec1b6ef1adceb126b1fa0bbe57d04f1b26607e5220719ae6907fff228eb0629d2633436565129fb92c0a3d5303625b2f7c09fb5e8acdb402b6e6c602b7daa23073c40a2617e757190310dfae01e91b84af715f37283e7630333f852f14170fd141a078c995fa394e500397cdce2380fdc6ff15e1f6e7b3be8e2d3c2e865bf103b7ae68b1bb72710437281e68e2a6220db77c4361d2e789f50c5b74023decc5d08ceaed9ad814aa72bad109b9225e17461e4b0d081769e02d75da448350f89f67ad1a7541b5842f48013b9294ef57ecb143d746363bfe8671a0b627529fe69d5c0547ab7c7af31bfd3671c1184d28160045b5869018fa4090fc36bf1dd67d0f5f5028c1845d78361b521b6b9ff2541e7811ecf949805bbb34f67dad7f509aec81d1fd11e6444572a1b5a32fe750ed4fc122307da7d400ed4fc821c68f7013850f3f31d72a0fa439e035d3914d3f452ec9b3dd7c4a9a50c5f5f37f7700907c42e8a0fa1008f4b9ba5bc07abf78042b74091b30061c88753199f673857ad0c578a0bbd9076d451fb0239936157ef180517626d27649a9a60b2d1a6798673d67739ce39fb047dc316db399e596ceefe6bf1fb9c325d5c7d84ec72777f2b9ed4dd1b76abe395e97830e97b2ab2305a5f0989706520f7378e4b568a7f364686729b3eead5ea08ed3ba341109e0532b3616eb08583b696d8e840365733310b07e2730b882362a3256ea5b937f107076c637a6caca06bb362de9e03e31b902f8c0d5e52bc9b735a9007f7a2ef1a15df4a7fdda2e836da406c42df35aaeaaf3e7dbbd8f68093325aa5f3ba197455ccea55ac00706977b09c41670b5017dfa26ac17f2ea69a05c7105291e83234545d00c2d423f94d0e56289f081c9b58c4ce4e22d217aebd3ef00a104df8b0a2b7a127709ce91a10caf098d0ebd81392b2393750203ed2eb830761874f902be4a1426fcbdc07dcbbfb1a6bcd41d73cf80a58737bb91362c7ee125d6c46958218d0022e74b6e849b1bf665449fb31d02dd88259322ddeebdee04eecfa7d715c2cf7fac15754352c512be31835dcf6fb7ac9a2cb3ed00703ca9737695d0301de4c38c0790c28fd6a50bfc36084075d9f949ee0a00a4ff84aac040b33992d93fc4486ba7935dfa7f926eeab13b09e187bb8dde31dfc197526c5a17e07d7cb31da13e08951202b634a9a0958d4ed0a3d95e9aef0b3b8cf378159ddc0851b8bab34d2ad04475958e8c611e2da6e88fc8cfd6b243fb07eac7616833088c1f423cc8de71898e3891e6f16f8d511830de1e5cc47e7a70226be0a8d1a0adc0f75fcbb302062cb2ce19ddec1f55f1a5778105b6c74bf1a08906801af52ea9a68743f82bfd6280085cf16a5edf60294c476078d78686c83bdd6c72eaaa49150617eabf1123c9b86c1a8d8d73fed4d7c44df1e10655f82ebec9b9b97e2409f815feeb35ef7fbb88664d9cfc184e99a0b3028cdd0145b1cb067697b0ef8f9a105267ff319ed4ffa83eba35a69e1b2d9130c1ccf071cc4315077d6019f26b3861ab819b26d5881bb46c68ac3422c7e18296a6c1b212b9d05d0a0071ffb1ea18a0c6e7d6141c3f58917169f94b01d2045543e0ceabed24e9f347cbcdb98805df4b7c2137596d0ce333ea9cd4587c0d7b4b19b692fffabb8d655fcd11e8a132e75a1cd14b7017ab307e287a3f9da1c0bca56f2e44c5f8e5942f7b0c71206a6c8e11a99f7fd063ae0e357a17103d1094be3168f5e4c676982f6c337f5150102a52ed8807bfcfdd15578940b45d06f8316e6a60d5a9d4903525d99a8ee19e2ad860bafaf40c982eaa30d128907c2c460afb6c44981e9ef8170eeb89979fdf8050fa181f7a265ecbc3ea27b18054c28c040ebf77eb3275d4c06ba55e982138f3e85e37c105fddb8069636813bf4285e8df60666dde8a2f702f40a4ade8e5923cb142e4f1f4310ea14970ed4c5373731e037cc1d3b59510124501d0598bfc82863f2cf01eaab33b3ecebe6ca80ec942374cc97680c4e7df105971c93d080557bd23682ac2dbe1447fa97b9b91a7c6faa621e14c9f2f9aa817cda7f60695235fd6faf63a28746c7100b31e703b4c3f8c0ff4ce6908e66eccd52f55b7445d0087e8e631576412bad0ff7e00a070cecfd11f71a5b7bd0e9603e2c8ef5032a935184b8f750015a43941c7a74b7574dc509afa338e10df436949eea7d2267b51f74c71be956c710f80532a36c7ac5a1d910b451504a13c94a0b62d3e08b3b3251c9c8596f4f6ec9cdaede27923a17d2797763c6e6620ff47263b8700feea148d5351a4a32de711baf874617f1b0470f00816d9f3158192287cce70147725bb7e8de37275fb9262ed9335660340e0dd754a5c7d0a5ddf397822d5a5bc0a806d6779cd8167bb2140991d8df1ba7ee3b426a3899f6481ffa86fba6b397ecb9aff7e746b34c2cd3b69575ecc3dc590f1162bb5e71d0f58ca599a0579953eb09e834127343f47e8e1cd7f04590bcbdd146946197e875a16415a7607394527fc711f7aae718907464b8747ac569d77e3c0a20339f665581fabbd3eb75c512cf0b63dd2d5addd9b61b1083ef374841f7552684b9ef80ceba4479b0e02eebf22a1f8d3f7b953fc1b58d73d7142e92a068e6dc24ffd0b35719db940ce20fcea284e3b038315746d38c1bafb1573360182f066c931bce8d23c2d478edf654df08a42be367981a12efc28e74eb7bdab5d622639d86cd33e75d4cb3205855b173054f906feb694eca24e207590346c5b7d4d7906c09b28cf70383ede60068e6b50abdf7ac49bd25ee0efc2b5033940a2e68091bc5a08af0856cd345ae6f92ce73c84ea475a4cdf77af1461ff9e831f343f29619183b90901ed151ff1182e7f7c6062994bd2f90cdb80056eb9a51239119253294d24822032bad67e8d61c6a1388cf8365d6ec8e68c6ac18733cbd0744ea63f729d32c46ab0f891f4bc8bd3904f9eed39826005ec833ddbc2a916bb0079ec0e6157b2923c4599068e539026c602e9045faf41da3f1d662a3711d39bcab39a844fa367c7ef1673f0743d868e5a2061688f303ea21c69bafc5a1de9f779b802b2abdb2e091aabd39a0cf51c3e94989d03140d173e882969af8d0cbe2546f0c052f0788088de723ddfcb281f342c3686cf8e8d5e2b3d036d0cbc3c1bbe2bb17cfb7dffdfc6e6b07cf61f4b1566fb45e5a53db7e9ecdeacd69a555ad3d7f9cc7ef8aefe27013cdecd80c83c40e92773fffe3dddf36b1adc549e4cd92bffdf22df816782fdafb5514ceec38fe6807db8f57e3aef59b75f559fbf5d75fb5bfada2f079334bbc30f8db07edbfbf059ab60c9f37befdd1deafc22889b55fb5c85e6fbcc87effb78fa5d93c2e45f674967c4cbffbb8f4828ff3f86f1f7ef916fca1d97e6cff997e9eedaded87aba51d24b2936fc1bbe2bbd24f3f69a3f0e98bf677edfdec8336f266aeed6b0f769cc449344d6cad5aae34b4bf6bd572b5acfd5d1b0deeb44b6f6607b1fdacfd54fa16947efa8bf6d37ff27fdfa26f8119ae0e91e7b809cf290ae3f025d1cc305a85d114b643d37d5f8346b116d9b11d6dede78fe26339bd4df06c475ae2da9abe9ace5c9b275ed43edb51ec858156fd58d6de8b06dfded16fdfde7df8453b841b6d393d684198689bd8169d26ae176b025a347b3fb35789e605da2c5cae7c6f1acc6c6de7252e8c44dd7cd41ea98ff029997a8136d566e1eaa0852fa295324b6d9a686e92ac7e2e9576bbddc7294cf4631839251f1bc4a5cb81695d4dacbf573f96c587e2ff77178389668ebb96369868d7b7e3cf83aed5d5c6579a7ea5fda44fb4c1e427cdd0278349517b18dc5d8cefefb407fdf656bfba1b58136d7cab99e3abeee06e30be9a68e39ea65f3d8a5e8783ab6e51b3067717d6ad667db9beb526d07830babe1c58dda236b8322fefbb83abbeecf572301adce9a223d109b7149dbd35dedde0eed22a6abdc1dd9518a237bed574ed5abfbd1b98f797faad767d7f7b3d9e5845d1cfc8ba352ff4ab3bddb81cdc3d8abeaec6577f1f5cf56e07577d6b645ddd7de45d99d8b67adaea21f36ebf849116afec99f7e2cd347f1a389ba9636b4eb8b5a3c00b1c6d65474b2f169fc5a2c769f0acf9ded24b00e46205a2f89c45abff28f88b4b15896ba5397ef834f5b55bfbc5b7674951bb8ec2a517dbd440fc7f3b8d347b9fd8c1f344cc70266effcb260074f1feb9a83d0954130924a19db41b3fcded59f231b693eb284cc2e4b0b2c72fdaefbf737bf1bff7ffadfdf6db4afcfcdb6f3f6bfff8a7f687e6057122203e7cd1f4289a1eb4bffe550ea9f198daf347f99df6abf6f48bf6c7875cd7a7df88a3792f56b41277ebe9832610ead347771a8f77c17514aeec2839bc5f7df8a03dff63f54fd1ed3f56fffc45fbe317ee36b2934d1464178abd43136c28fe2fc7feed376c1cbfb9594a1f9999fff6db7b316f81193ecec2204ea2cd2c0923ed57edf917ed0f6efefc71c5fb2be60cd420d8f8bef65f7c04b3c89e26f6fba70fdacfdafbdf7ecbb64f9f8a5a60ef60505a8f0a05bffd368d63cf09540050d6a3fc4c83d2f3efbfabebc197ef13e54b58319f4c5cd43ced57ad52d4444fd3c8d9087a127ff4edc049dc5f344ffbbfb5e017cd2b14723d88ffc5ea27fff0fef94bbe4116006204009aaedc851c3c7c9c4d7dff7d5cd4045c240817b1800bb5f33fd407829244b6380120de878fd3d5ca3fbc17e75b4c67fe06306da7fec68edf87cae2c57296daaf9a987af8a24d0ecba7d00718f8f68ebffcf64e5ca2f01ff8e3472fb1a3691246ffc4cd2ecbe989ed587ee0592e71e9e187fcf4331b1fd8fbe467e5b29d3917d16d2866e069ffe7572da4c3fca085daafda36f49e9519e4f6f0bf3558f1cf5a880bf00a857f16b5e730b07fd6fe122a1b9b39843fb2d0abec5f644f9fdf87452df80f6d6066e7fe926e5df88bdabbd864b999452d1267adfdaafde39f45cd960d93e890ddb99d2b7881f7ef03980bee93b84dc1dfffaefd1fadfc41cce82fef4547de477108ef3f7cf82876e683368d3eae36b1fb3efa08bb979e9fdca1d93499b9da7b3b8ac24860188108fe5b83c79ff18ff68782615ebc60eafbb9f99d4c98f7218299453019f1cff76277bd7f7c7b879bf3eddd3f3f7ce0fdf03ebc7e8fe4a8d0abfd414bdc28dc69f64798a032bd3f72f0398d5e0580780520a01cbfc409f24cf04e00aa3983800a850fea24e1ab6924d0f36c9abc271053b1d08793fb23e717206a1d1bbdfb89a9df59dddfacdbdbf1ad26404f0f344ffcea4d83447b997abefd5cd4dc70676f893fc063f2622d7c7ad9c4b369623f6b4ff66c2aa406e025bd589b6a2977af3d6d3cfff9e3b777bf304ab746d7778fbf092eea11960e3f103a7c896cfb68bf579a7cc87d37363e59e69d009c3f5efd10dbe097f2141c3bb9b2f7c920730cb4358502f2248230da1f97e1d3bebff19ed3e3949d881d79bfb4e378ead84a3772cbdebf4c7dc1877393f49e01107d7bf7e5dbbb5fb45249db04427c71a74fbe7d3a4adaddccb5678bb43b654471f3e1d70c5ce030829e5ae29cde7f7bf70fb19a7f6adfde69058d672eee73fef455e25b426145fb49bb8ebc201107fa6caf227b06dc22cfa6a83d6d122d0cfc8326ae5ce22d916bd47ed26e615b630d7643cc55400e77613f730fda6e1a6b535fc0ee415b89a100985ec2c8c68e4a7cf6e9b723fc344e41476e5bdae8fd32768a021c0327b767af0ab2dfdea530fbeddd87339415169341bdf90194c6ca5cbebdfb1becfe3276b482f6eddddf8a42f6d2f0257481af8105b5a7e2ae9cc19d62bcd35df8e805cff67efc2216fc41fbcbafbf6a7faf7c7fee67fa01cc2d3a918d04e717fa84f65240eaca6f7fd6785927a8268936f639701a4d1776acc59b48e08a690260b18ac2adf76c3fa7c45c2091601b2eec6721442ec35840d98c81ab943973f1c37bf19423addcc1afb9a5f37ebcc638886da66f3f9ce70e3294231d462e39bff39b60f616c395e31cc4dc83305c29fc2ecc91dac8779bc05b6fecf7be1727b99547eadd102f459b8f2f61644d67eefbb4532fb19767161f2940854d7e3d852a5c1f410db44ad772020c911d9fc1a45e8c98fb3d320b2728195e03448350f1d7bf32a7843fe0950da10ba22df9feaffda917bc32885869da118cf0fbefd911fe9219e1fb970a187cc1cda7b288939141dfe7d822ea85bef9557e958a49bfffaefc2a2679669dd3e7e70beff9d906c9e13d4eb7283e5b5d4d977651cbaf9c0679b65fbcc096d2e7e97719c0b083cdd28e04b1fa19575dccb08c9197e06fe212647e9a85c18be76ca2577e26361bfee400e89555f60477f6bf61a9a7bffda7d6eac53c5753e93133efdc957fb6e359e4ad50464f614f1127bbb245b69f3c30fe45e9eaf7df05c5e1c78feaf2e0722071ffeb5f95e13ff2fea40dce9e661cdb51f26756f92ae9fecb09e90631e047f63073a581b1fbf6ce9c06419868cbe9020813f440945a3c7e4cc249127981f3fe03d1ecf029b6a3ade8bca87989205de2fbcc5e4d836709379a1700d14ba69163279ac42e673609b52703a996ba8eec674f10def70140edcc9f1e8f394060980656de8b47e1d31798bbf82225ece2c314cbfc833ffa679e8a9dd0cafd795e47a2f23d48877bb5c75f737dfe718e2d607671e7da894b72069349902784f0124d0f45edd98b23db9946cf826be2bdf77c2f399ce50ebc18747997dec2ce4c9e260e3f7ea446a2c1efbfc362f848f9fdd94b6a4d9aa3e9ea8407640e08f83a45a9389aae5eeb6662273fdccdc44ededa41b1732fa1ef873b2f707ed6c25da02dec435cd452a2229eb5bfc24f312a1db00572e9076d1ad90a123cbbad82aea5c475681f62ba5939704cbb112c89904ac452158d230bc10bfb206e0675721e1dc71fa7cfcfef17f6e10308503f4d7dff27f5e71cd6cfe23fd4a0c8699e6187166778a11f45a58b0f1fd3899c304a274bc8304bb0967017fc44a721d7512a69576122280948d5cb956f8bfb30651619d4f981a3745fd4bcc0b5232f11323bf6e6cd5234269040fc17ed4e30debb70e33f4bb97e15d94972d0ecfdca0e626f6b6b4928286e5199ca14602bb211c369f6cb8b37f3e07a92520a19fa88e0104f8786f6d2c3c95cbc97285cbe5776e7dc3d8b01dd7a2f87a17d80c3cfd20401387ffdab801f899acf716aeaef0afcd97e6c9f690d808a6dc588f92fffc8df85d17425300cdc83e5344fb6b28ca8f8fddc0c09d416dc4746cecce2a9d7ba584e571f97d39502d3bf4dcfa84541abfea4fdca7ac9dfa645adf2a10877f057edb7a77f944f35d8e93666f566d9694a9c089b90c3a5fcfedccc1570108b804d38d55f6549b4209f80cac46744a297d31592e5f3143509af236fe925ded67e5bea504c19f0e7e7b7640fedbfb46fef6078fc9558bcacaeedff12c2b3f62ba979df7f7b07cfd3e7a51778608e46ad83d475e949b8d47ed54a3ffda4fd3f337f1ac7da4f25edfd59a9958980f8df4f9a095c833605209e26e1f2a3d60b0587f8b4711c30046ea25518db31712b913d0b974b3b100278126a8eb8fd5e22be9fb23a073bbe736d2d0c0cd1dcc65315e279f02c5fde0721bf9e4d7dff693a5bc4da6c1a684fb6b689857c1f82700a0e07da721afcbfe4bd7b7f1bc79128fa559acaf949a00501a29c643750688596a884892df98a74bc7b455d6a806900630e66b0d3035288a5fbd9efafabfa51fd1a0c28d967f75cfd614b987e565757d7bbb205103432c9d83c0c7aa3120ec0ef44a873058c8e51524b21b9d2bc8fecf7173814a2f67bea2a7ac1bea57a380c92f958881f7825590dbd3724be5aa720e9a2dc149fcff94c6215dba87645b518b16f33c1e11c9792784a71005b7f689b8cd5ebb65815ff8201874cd4ac68450c941510e8056f0540555276ad6d2dda07c86d569ce73c8facfe5b5e540b7358be2ac434549335f147da34cb8bf9fc9f78013cd3097c2e33d19ecc2487cef36fb78936f52d17ad5a5103da5676ccce5ef0a640d8a202f6d5eb8bab8b3727cfff71f6eaafa1264cc294d8cd02a43ceed6eee096bd4edf15a2e5156f448460767788b012a5fa263152d115fd132061c2f860cd4a891d12b4d8678fb65bef5d46bafc1afb7449d719e8d290dd59f176590345aaeab6986f19d04b6031b6f5a601ca06f76aca7985e445d42bbeac6f29cd325c71b3d15a68e460669ba6e1555b6e59c6c08d485ede595db5fc43941e7907d2f075ddb47d10cea8c06807381e5ffbd70b1e57d9bce5cd95f39b84c26c99550ba4e0a258545949e0959525121773cbc512b8bfa2bac9ca229717aeef969fab793a762cdaac69bfcddad9d2a3219219cc1659cbd5201e141870cab9df3379293453d603fa86d0a74de372707cb135e3014a64a1dee1b42c8e4fcde5bd210ce1999cb09b79c386c103fab7acca4bde0c23945f7df298c9c400de33986c05aae5a7ae5121397562d0483b7f58b06b22e4e47b621ff1a744a2c8f93cdb942d7b2f3bbf379483dd166509cf5a51156d9195c5bfd0f96959d7d7f269ea030e501bd78e0649fef19b0fe42293a79230c2a4e1b06356dbc19b373cf470666dc335782a394bab46c879d516edf679bd5a670d6f0699ebf6a37bc3914ee362d666d66e9aacdc3144cef9faf4bf365989df63432db3b2ac6ff71a474a2091a1148aec184a894e85f09724d170a6fab263729114b42601dc8cc46be13189c0c634530b9cf82bb5e32030263e542ed1d54649079258bf28f2379beabbec5fdb3383f78dd06e219ee09017396b36152bb37f6dc93d69049521644bc5bfbee0b31aa474110cb5c6162c374de818563ab76a8fe7e084680cf068b1aa4e77b7f4e8a256a890fd12dd8a7c2e86647e4fb5345343db06ec59c76a279d4bf45f83018c0e6acc77bee720fd741cb2513b8c00ccb33010e58ddf6cc1773938012e1be0e9d729f2ae46de43dc41d0ea53b00ce12ec3979befbc16bb08764c24666731aeae21aa868d4c09aa755f137975346457996bbd87866f775d3eabc48ea82e1ceb5f4e6f19193db884ae0397ede6c1d535ede180c39dc462886b75a0391eb36f3745995b65e035687a9b6c8bfa9369dd2e95ae4d8054ef2923f51641e3726c3d9a3a95ad64634347c1453e787266ccb98b6a89c5d5114caf3c12e52fa8ba125747f009ffaa3cd39eb203fd09dcc29e265b26305aeba68f4dc7511c550d0ab06382066faff936bc634c3bcfa27d4ad2c2ba31c78b5fe4ffad590dffa546bd300dcd4f27a14b41fc0ed17f68673cb92b70c603a858773c00d3a7a709e7b8407c8c9d1cb35a5a84fafdfbde8980a3de55668f03afd5e121bbcad0550f7fdfb13116faedc94d29cfbdaba3c077cf19e1534857ec0b656eed60edbe57e5f69468debde30cb914c2d4a8015f66b3b66eb63e6577288939d9a7c9265400523f72834d0a970826812bcad96ac5f3226b79b9f5c8c48571e1836882ac64ebacc956bce50d912ec19dab68f8ac85f10ae51856cfc1534c2d6cc880e5513ee756130ce35c176b7427acdaa2e1a05fd53de548ebac6987ded2d004618c6160a4909b51ce651a1c6dcdb8642c0531b4d291129ec23e5c2cd58fe375eafe86103737bbc775250863fc3d3ab17e5fc3f87f6db2d9b5f8aeb8e62716b3ad4b5260bc62d6360ea8419db49cb39e6e5a56b4ec3613d583d6f84595c535a7eda86b1bddc2412f7778fa04068f6a170d3776b117fb3fd1f44ffa450e0618dab0835f3e0d632b38ec41d43a9798e64235824e101d7be0efc4ff21dac9a2f584a278bca9f35e4df435e86c6b6ec624f25b00ac9499aabf78d141d23de5e5535fc5baeb228587321eb3bfd88be07d0cb7cb8ea9a7746aafa69ff231945423ea63c87cf45281965d8b94fb110149882e154d78f6fa8ab29871bcb589c5c436b133b0c2909f14f845f8f20e06f041f9d2035d7fc23e7e64fe8f5f1fb2fbf71d594f59fd64c3b747ef94dd0fb9e4cb7bc461d06b00ecefe5bd433f342c58c6ef254986ce5f1329e330a2e0017549b594ef5e33b819b2ab21f3ac62e3b1b2e86515714ad2ded518bd42a50e6a9b1ddc44cdb237545d27ea15476f14d02a2bc3deacae6e78d32a53e06ad3662dcf9fd1795cdb757c22bbde5186cd86ca983741935e6068767c3b778d59ab764308739c1715cf778daf0cd93b875ec9463d063be73dd62978db3598732a519d5b378680cf2ba0990183c4e11b63eeeec6011f690cf4e35e53e1ef0850ffd734646e3a7c20ee864743b847ca77f3d746aa1d937d0686ed1ef9aee8961c99ba60f46737e9fc927fe41a51d9aace8b79c11b36269cbba429104e02f63c8c439f16154a0410880ea72a86ca514c0cd92a5b2b7d056f45dceba3e173def06ac6cdeda8f8ed3f3d35d678ac2cede8d05849d98202cb83831e213edd39288ce965accb1cda47efe41eec7b17d1d61146f4846121dade57d5adf1c50068926702f529ca919e19c594d6d1932dc4b14a7d4cd1aa2a10adcda3fdb26e0ca4b8fa4b34b2ca7c8cebdc8c95ce15da95df85d15f52314d727eaf14d65b71ed2ad4b41086c7d7d1ed718031c1d3ecce73bc26ff1cc11a2eeffd851cd70c7da0f469a21b9a14d18d92825d5e2aaf24c7838e6e1b5d9865bb438c48facbac5ead372ddcbd301289f90c240a56c0386bb710bb6a7fa7cfa89738b158c4c481545b2a044605552a948c1c477bdbc2506b676359f8b0a97946594e741720f7b9b84341306421967e721116c37308dd39057f2085430c42fac410951d8560cb6cbde69560f9068cdd9813c5aabdd1714c0da6b8513d1462a0d92f521082abde3fbb509782ea99bd4d1623ed858b0b3ea03bb86de4661a4787f0f346b4acad59ce5b3e6b5951967c9195e45a17d54d8dea2531b4816b0c328f54fc43cb6e301b46645278178ad5badc5acb0757540255e12c298f814ac80bc3657f664fa278e73a289e55b3ba01dd586c1723462fb26d91d71c3427fcc31ad46ad5d64a7131adc967cb7f9388d8d570890a88c1605cc3bfa623baaacb6a3c663f345c3394d36c21583d5750a64f4cbd568728df56702b90ac80048a9429f86a5d375953945bd550bff1721e29dbe0e1adb29feba66821dfcc2c13e8588cef001a60615a72977152aa23410ec7b1cc210364f938db140635c81d6bb36eea0f5b1cefd2e44f708392bbd7e6f98c606ccc3fb3b2c8b141c4ebf960fcffc0e3fc512efc236a3b3ffa8bfd082b3bfc5fe351cb450ba3c4225e941790863a185b50637b680f4f857a82f37dc8f26422b1b520aac104cdba6177e61703de1893d10d46d7b48794d00e6cc5f6d8c89a0586f6438a21f4788912e8eeaf7eb0ba8e30c390b42071e0fab4841740a43b515b1b1e81f1de0bd02bed6b023d5d6f0a09991701c715e5e5a8c6c2fa1328febfe7189e586b8769f8bce71001f7ef0c829c7affa15cce3e4c30a0bfbc6cea95be03eaa842bd94fa30f22faefbd8a65a193aedd274db9caf01f341940bb9b1002e21a7444f3016737401be9599a6d443654faee9030f829475b1d4ae342651c05fc0bac46e80b8a3fffcedb2982db5cc320507292ab56247371e69e6910429af64cde209fcf76b57cca3afafa857c0d1c56887cda5b143f317b4d2eabf445e00728376bdd99ffe3b2bf72c33eb6b4e3c048ee94cc8e9b8f8ebab7942cc8d2979e47041d309235a96b89c11ea59a22391d150b3126b108ca8f42bc9117154e71c80e5c76b3053f84f4e01ee52c56f290ae4599bd96b353421998e9ba43c26f9cedcc4104133736a0975bbe4cd6d21f81079f369fd818cf6d90a2093ed81ee52c9b276a7a10266c4cee690bef036ab5a5c996231dd2b61e89a8496242a88739871830c37ad3f285f2637584862b56d8626fa823b0ce4b4fe1078440d5948e6594a8cf8262246145a6828b73f0a9e9f082b515dde9bd61ffc271ed6c98e3b78af9ab297de994b24b23d4074d5fb48bd628743568f5047889c513d42c693902bc314c3c5a440a242b2f8758105737f5970f9ef0b12276f4f3b011703d42a5bff6f02d32a5bff9a3825a9ee970090e77ef81b0248f080affe9200920fc9970010d2370aa37553af05d15a76c26937b7b31fd4e202c91d0107eef62310c12c2f1b513039093209e7f3cb2754f4fad0d8db2a4e340c545858f0f685f72b1c1cc0c01e5fa0bb91c34d3301fecbb135138b12f96b6220051e2db96cab6c55cc026da69c2eecefcf8e8d7f2adae50f26747b00134401e98324a9a5822112c6fda1158be61347b24b7ad1872d506477986bcf977f1291f7acc2c67df60d342d649e2a3dd42d2f9a9cb54d31bb961cc6b514b3ea4d23e501f09dad8a192fb7cabeb24151480c5115d91665a940ae581333a1c9f8689547d7985621604562c90b9455c9783cd86e6f2b95d92332127eb3917a446c4bde700c3a7be55ab1503b6179c8fd19c4cb7ba746b551712943b6b7b5a54a12d4540684606fb312b0638cd88b22070e319bcd20ae03bc41db662b3b4bf66fc7002c1316b99f59a6b0b281241beabf953038a90480f4c9427fc52e9b536f93935cc982b78ea9050d44c2ff55f01622941d134d2194b7a43136cd6b1c710c23c0252727f99a84294fd83c132d6f18756235996c1ae398f98c9d08b1598134e9785f86e31555ceea4d2b097dce676506360e4040e5e359804e1cd87d9c7cc40659296ac8d02374fe38b478914d81d69f378723f6ed061cf41ace567c55375bb611d9828f46644d2feb6646b3acb0aabe1db279f1810bb6ac5bd6f0b2cef262c10a21365cc8f5bde1d9ac65afb2b6b8e1137a36b5d1373b27f8f6f13bf6f1a38e83617183939e1f4c4ecf15ba81c1298542d6c310a3457cff3a609e84c40e15db3ab19bfc64b90285e95633a6713da21ef36fc1e017e56d3b31a156231b30a5298b551ad9c124e2616a039b2664426c9012ab40261910cac63fac9ba7ec93561fbdac1b56f24536dbdabc06801ee07f8a3a12c14ecfff4069ad32004dd87b3dd76070c88ebf81c10fdf3f251a260a0cea676d3a66cde228a16b72b9ab273e57e53219e3b1dd794c00f1c1de5b73a478e1a358263df8dd4b66810e692eeb2c9b1c752c78f08bc1fb4f310dc3dd573f1e5b50cbd33138fbecf00ba8e28df13d8487cdc03c6497f75e168d686d46aab6b6a8f3de6a2a5986f8c921cd7e603bb7d345ec8a5fcb69f49d672d10b7e84358ccd1e49f5957ec68ba50458c84cd304d9090a42e815f279432c95e237c632440dcdff19509472419abcd98ba833b824ab861ff8e9e9847e61f97f72045ee57ea65aa7803e65af86cc3d3894ca5c1866a0c39304d65ae0f4a3bc31ca7a89b89c6f4d351c03084d9f2bfbbfa654c5fcba65c3e29cda6924738a837ad2872cea610732399415479d92c66c4e4351e33488d5a08b6ae8baa65b9994fe7975bd625046d66d5163580d9543ea3395ff32ae7d54cf23ddc6884fd05bf0d7eb8bc47536e5cde930ce323290932ff0b551556b5f1e72233eb5c04a290cf4c99895641dcf15590ac742ddff686cfb272b629b396938dfa3ad142b0db65d6aa671f0257253fb0cf0e7ffce1eae2f5d58b938b53dcdf63dc1efdd95789834011d91b463be4b0feebaabe95b7320d09ba652901a83236928c80b7079b037929e6ccae4562cd0fafcfcfcfbefdee3fafce2f4ebe3ba524d164af006f3907ff710a936b213908196e99dda0e6bf104c404a16f9173eabab9c4d8b8593aa6642fae1fe9719e60b834442721d923fe237bcd986a02019a36f97bc52196c9cec357d4ed2db139ca64256ff133dd193d819d1ec19718c85eb8a4c73043b315b0147edbc8581bf3d705519edb349b2b727b837baa54f870119827c9dc18fc7ec974f24a3c54593cdf8f7751e1035f3815033f3db5bfb37490f5eb937087f78daddebbbd77f750e0afebda3cfb76f4e4ffee18040fda241601ac3deedbfbc4d3fcf368b657b0ae58d307f539fbc5ae647affb00b22f79bc04d64a81b44cc70cfeefc7df9eaed6ed3678a6d533e64d81fbd3994888bb94bf944806334eb34546c77519f29745950b10c274f64d7854ec0da9e71ef6c39dc966ed06046c757934477e36b77d0b2ece353d399283541021863490527ddb7ea88629e6fe32f425d523581257b46caabe6322037ffab6664fd4fad4f0df6e55de427880756903da533b1c09c976d40d5647c28ce55b76cb1bae72faa071540d2bda7abd56222c64e204c2ae695f5662e0a4dd3bb0cc59c39124627e2f607b1c922ed4e8303fec7dca59db64b36b9ecb9ddb93196172c742981c61b75200129b95cab7ae32f1e3ba3ea8719d6d87a7ad1dd3701b788c5e13c5024b6ec7c0ec36dbaaf1376bb6a9daa26419640793f0f9f0a85d92c38d1af571500589819d8da0bcb82d2086994020387defa2ce32c1c38463f6e19d24349861eab4f848945b9aec6e0e343d356790523e3e86fbe64da2fe97f8aeeb3b03226c56b17a36db344c33a792a307d08ffd9458ec774f8efef487b8f299df9cc8371596f28667395443727f396fb3a61d845909e8203f561aa38f25b6e0dfb123e648ad6a7c66e7906ab416dcf0f1a01d9cda0b39549754dd947501c36ea0f8120c0c00e4f94b8569a3d89aea292a710c6299c47e4356a23a551767f1bb9b7c05a4a24b992a1e65e7fb19478d159062c6adc39375a63fa7a25e75175ad7242f44362d395406f9b6de547906fae4f4000ced4b521a1cc46395592c6855ff89db52e89f64d680fd56d0b90a46721decd82b533c1d07a28c39a85ade70813e09c449e9abbaf94a154c041651c96bab5a4ae92a189ae49bab2b3ed499ecb2b2dcb50673014eab7ce0dc8e6e18c83fdeddd323789774f738291ae4ff49c23df9613c96b071a596f7f5f4e7f70153611efba9bdedc08e9bc71fd86e27bb5d709bc9b4b2eb7b7ba7df3b1e55bc91141016d2b572adc5394f3d4f5db7b1eba1024d4afc81d881b67745972f812a7dd0248a09c18fc10f88042f7c385dd48f29b88359f781c65d2190640a223945c6631616764a61cf8462803af6f118c15157a26515bf7dc1d75ab6233d9964caabed618858640c8983e49f0cfdd7fb144452b63ad271e02c2586bb2e63a282a1c9080ceaf8ed18843254876480436f301d7c6102488ce400bc8ff263188f999f801f0f01322be8992315c2e83b0ae8e47430da75cc095c946026dbb48aa192d204b05844ad202ec3a4334b3ebb3e9bc324df4380a40a7c396938a0a4ca1ce8d90397da9684197c21e9b32587a2f81767df9064bce3313b57018110f12859a45a88426566516cbe258bb963a76eea95bb19c835cf39fbddbffde9dfa94e9e028c6cfb055f8333ce6376ffbeb3f23036e16e6e860cacc946958e818de63dcf108cb0511090602798c0593862a4ddb45079541be370eb696e47eca2297050886bddaa7009388920efe5b9138d1901bd813b32ed9a3dc792dc72063ed4b59a5554981b0ea6cee30f7ffc9a9ec7013d104bf73019ab803c4c0e227dfce8e03cafe67533e3270a9fad310b9c7dbee4e10dd2d3c6de9167ecf2de3928ee70358f2480e4c3ce2b7978f9d03f5217a1157e68209bfb2a28ba8cd80f2597b2d76d9361daa2194c52c96bf21efbbc4786afd0ea44ac62d64266f52882c4363381cd108c84fc39660388103e2e3bc682113b6938b841b4cd16d4ba7a4ed55bde609d883c5bad4b3e544a09a8006d43fbe62c53666e797beb8a57edb3d8360ed9c3d84e3cdc4f133a78610981b36773e73069ba9e04daa3a4ea36a52ded2adea0b65e002c5cf5032355f26eb3a6b245f248b22ba004c4f5a432fe26ca44c4b3dca25f908d3a30ee79eabbd30f7cb669ad2b84574aeffdfc3deaaf1b48c78fb11594b465c65695a9dced5a9377b1545a26a430f3ba59191b9468eb06e38ee5b40e4badfcad43a539561b5814424a545a63960987fbce2aa36fd4cba1ab8dea8962223de18b866c6edc1f826a4977545e808b13d7f18b5c05bee870c6ba620f5953d72bb865c0f029e64f7225d4bb06fb59955eb15aa14a6f5a5439657c759f3d5962226e54fcf6b5d660e8b4cce0c51c537168bbf44376f4f87174b84d35ad37b046f1bcde54ad93ee9fb46b36d559ce8ebd02abf0eb53ff282e34b21defe0b64ccf1d4c19d5dff831d89bb27d9a6257e27a925442381c8c1db339c6a76b5c0b6df2a13e24aaffd839204ba5728cbac6aac1c0521e980f3a84975e00a6e766c6f2b1378a9b92609e4ceb4d6bc7fba96897f0c38eaefb4a6d36d0459fbafb1cedbf942f5553d64bb791be89f29d7bbc6b00e78aa9e74a3f5fe445faf8d1b9a141835e2f1cc10278e128a9312f9c6486d0d96abc59e7a0aeb945c0c2b3a73d187c766cd79b9717f3b9600e4523f94c24d48ce521b741e88a199af2484faca64a9f1a3582d2d9d9da09200a385189727326817bec81eaba0e6efe2ee321d4a9273ad825260fd9e5bdb35717a76f5e9d7cc7b0b4b7bf06956640b09d333d3aa2c7a169357d4b6278eb74a849e32896bb83d0e37167c6f231afc8f7d0dcdd61dba1eff75f6b4898b3592cc12ee746d5614a2174ce30556f265856050a1580f544d2e54c3eea1bcc80cac521758f60ecf14459dac0ce025169436346abd911cc021ee445eb743c9ae82a41a463ded4b42118181ecb77170d121d8fb3d9776fcb842ab96ddcc68b6ae1db25543d6a5a15086854f80479add851a04e03dbc66340b722aa3f25ab00a7839cafc3411e3f7c987e22c763f6e37a9609b08e3e10d99c3f604bde70524e092cd7f2f399a58543c9dc7ad7e2bde1d8c26c104c7b46b56c59b498da02c4c52a2f5a2f4b89816070efbed98de91138f7b91dd1f9763001c16374cc8a28b3e7f3985a1fe6fc8e66ddea418b94189c63b4f863c48d01c8aae06cb9aaa5c49ed7b795bc33b77573cdb246a2377bf9924d370ba5edf8e3d1ef0fd3d7bb2ef31ed71b43acd55b009576d019c8279e87fe2d3795b88acaa7244353138c476e79d1c2fd179e4269a87cab20d6d5d6402ada11211f8ff560a5e2c35e7be76459ad65517236281f3d4a5e73a7ffdbf2ae57bde1f2b8b41249761ab294aedeb99e3e8d781cf505be13d106ffbc96b8e9e201470e91dd6602a2202474e559c2e99775bd1ea903d18e5e792d191788981f45ce542541b6c759728921160f4630cd34c320a2c7de41158f3b4eca21853d8ec977dcee86b6fe63925ef53e457a4ee7923bb2a723efafe92ed82adb6a0e4ab459c9b516135e57a22f887b8d8a1acdfbe077b8cc7256a1e21423bead57100c5d7121d8e0777f3afaa3e32fbe9b5246792ccb497830ed36ebed26cc4f1383e90241e7722f8318536c556a25cf1a337e0f16930a0b450565b7d83792990878477768729194c312382f299b003838fb0c63da9722f68a50aef0ed3b67a022ee78a1afcda3479e84e41023f4ad8863f28e03dc5da0d03d0c63821c043a43cd40c7dc5c749b402ba0cb37a16e2ba259889665080ca19d08e4af26bae42fa5977172db9b18511e4b6d1beec2aeac977a22326654c5e7fdb81b005e87e8ee7d8d73a05eec098584ca23018b705677582b4a2b064c47b2be8f14e87ccf5430e808bd9a8d35026c818327ac6ee42363deb1af6232703fc5a5ab56d9df598210e80e55c9be973d2240f6a46afbd32c24527deba47a2bd3e9f86eb96257a45843f042f9ce7101a62be5d4aa93f11943a48a7204bdc86a53b6c5bad42e041077a1f22d9acc7b2a1a014d74a0ec7d6c3caf2bfe817e38321f3462bcca56a418173b8e576f2779fb1d576df6493e5755b6e2b46659215e92d19f93825c2484cf9bf8fefdc497112de8e5ba63abea8e489433d377c8e6d590357c7e37fbd5ae20b579150d51335648934479ca4d158eda969f097249d23045b307b52e9af0eac07e0d4474e57ba18da78a43000e0d930b42e9f9215bd4ed4495ea26733915bb991fc48629a67695f8e468064b1f86ca3328e2f186840a8b5121beafa71f702876ecba367d5ee2bf3466469874751350c3a06fc2a09170d4383f64bfa0c67442e199acbb7b19e8c3232f4d3724c5ac5e7380a1ff40369beaac9ad7ec985d4109d8c800b4f34e66675ea928d1682fb3176dfa681a1f31703d58f9891d33deb8d525546d28f26b373775c5ab5ced490dddc94ef502820b4194f2cfd75b48a976bede9ea207c3e0102af7900be83c3030d145b172053928906e06ec9fe93756cd570dfe423e39557d3b0873bb94ec18ab5be88216eab9836cff8f83e6f3326b5b094fd9831a23cb903695522a09294e5a93e93785e664c2b7c53b0c6d0d5cadc57afb067cc891210c6b9c6dd7900935d374d76f805944c969fb0d74b21e448240e8b6d56fe8829dcb9ca09292bf7338dfa47011adcf1c5ac3b55f106558d56f318bf86799d35df2e180ddddd7c4fbf7d06f1aac7f12ffb9a323acd2ef063f3a9dccdd9ad8bf0ea3376762ffea34c8145f3471b8a4870fddb56594b79af8cc56f88085dc9826847abec02c8adf234f4184e4b92c8d3f992427fe741e41f1b20e672ad6a7cd66d723286bbbad37f2762f500d372faa422c59a685df67513e21bd69177e0e75741f880327fbb0bb662a5a89cd1a22fcb53b103809089f4d302b0b2e8f94dccce262a8d969e68ef7f4ccdd912aea8e104d077911518650e07c892744535539f72fac852b61df12f6c81c967d6c6264aed729588fec94fcacc03c087ec19c3d71b13f4103839f8354ff5d6c8ee66b7b2b74a2c81451ecb05d3c5eefedeca103515d7668413a9e95bd35213e1076e942ecdc7d873e03a5a6f6251ea4f1a3cbd9390a91c0239af26ebf06eeec98dc40a41b8954860c2f75685740f595d8ac9d822e575798014d0cbc51864cb5b5e66a3d4a2255a9ce803d54b58bec43ac72124544304c3f727ccc40e9f1f850e57e87e8726f9abf80a0bae0ed2bfea13dcb07875efd5897c5f6c624bc3cbc0c615755a4d4eda77fb4c994548ebda761ed952b30981c2bb0a9e22820e2623a3825f13a2c2ef4e92cf1605b29b85454e02063e895e25f222d9699f8b1d2419978a31c0aedb6be5198c44dd9243c649200d175a50f8f000a24f972d3dd8bf38cc7a84851d657b1de1a176f2c90db6655fe282b214f8f411d7f14f3fcc9b74f0910a83992f23b4a0c16de43535a0a5cc4250252f0a4447b7259af9c33372d3cdc26951a730e00d737b9bbd4bb2ae020742f9f71f2774f2ace9b2e6ae0a791c5bbc5b52d579b5e3d2624229910c3da5efabee82255f24a1a903aabd09d758b75c3e5257ca57eb6838748a87b4a70505afbe3abe77f3b79f5d7d3171104eb16faa35e325f801f0b103321edea3f1a69d1992e22f51ae8e91a1a0a9593ed0c86ebbf259bea239b98bfc55a7eea5348572e4b485ade79969f05e74e284b3625a598eb81e71e2af6c1f93ee164122c21362f337156b5bc99f1755b37025b251078a6097ba17b20a9574f5114adb41a049ac41af4c2b9108f022c881fee01aeb9ab9453f40a0783117a81438e9cc280c14133e5f60f55cb7509c42e02c4fd92854342ba86f6ae45892979a607b497459767f17db2090bf6d19316ef839ffd68b2c31c44c10b2d90cf40d4f32f9a42e9ef0ad1f28a77e033de7ab75d02857b61e84e3cef490a7793c1a4cebfc7b12dbc273496da08c1ab0c923e7c238f3cd2587b76315b4b7a45869438eb5a66555ef240cfaf65148c2c22744b1d9feeb6d70ab4ab169dbf54783164f3a2e167ab15cf8bace5e536c223f92dfcf3d263c59fdd2f4d1fc9edef462f5b2cb01bbf3ca0eb1ba320ae37b71fc8dbfaefe7af5ff5b0f5c16edc8420fdc63f077366df194c18c35b60c3091d923fbe23d9cbfacc0e3d5fcffb4c5effd014aba22d6ed40582adeeb5d7b7e750836844867ad777db6aa151e0aa76debca81b189cb4f5ea905ae1432d01ca3d67263fd90f0dcfc1737e1008df5238f27e3a840c9dd677e584552a0a17924eb54e2eb12d6beabac5700d759905d6b6815e2a25bb2a7464dc148b56f072eee60a8ba4576cf88aafa62a6b988ab052618b3471a072b760f9a6c11f541b70921b3255e9eb2be50be2c5943b6b78413c24db62c5691e3593755167550479740e5951f242d5a124911f3a87a51adacfc888d9c3684028ba82bc77e08048f9de5de5d96a5d82d3b64a1ca69c284cdac8afd8d188612e5db58907c15c7a637a5bf2940cb811d46a2cc6d8a2b8e1e845ab9bf05c9f07a61c7b32d2155455af27ce0a30c75c2cc7e7309943135c66cad2c6040dd96d56b470da5febc8a3af47ec279302d2dde2901c9a4a7397ce1d3ab29b2de67a6beadb842c31b532cc19c79b6013e0bc2591117c9c45cbd764aa452d87923f4a78f102ae8d49e8a64f7bce32ac538a596a61ab61a25bc028ea0d3d91dbe02de608c5a263b21dce7944437c2177a373fbfa656ed42442fef98a3d5765a2c0cc3c73f24240110e708fc9187180b0299ccd2864bc8b2567efe5e3f0dea69e2f041c7fcea79b85cd442eaf55c718c89a9351c49acfa448200c25c91a1a93afea18a86ab9cdaaa81083e4ceca2d435994bcdd5fa95de6c57cce1b61cf7cddf09ba2dea852632376715b9be93024dc44922bea5a16d3266bb64fd97b5d8553357f4f665343080b56a8c350b45bf5a910f2a48e8f8f0f91fcbe5799e2b3d20c07d7b1dcdab190b63b650371b6739b659e8c4e4bd75505af200f175485286fb3add04052e8902d160dc73c52366e9dcc110dc3b0c180c55c114c9bf1bedc9a148823e7c0516bb8117cbe2901596eebe6da0420def019965459d51b486d57377951652d178cb733329249dc6bd393fae9af23957e146b7e17cf666708cf371b439d722e74cab4b2ae614f593b62af378dc63f9858a8740182639f60f054f8900e0f30b90824a1c92a133ddf2edd5803733ec10c85f85692622dc644b5d1aae10fbcca8b6af1a30aded16e1589f635c9bf23d7721ea4abc31348c65ca090b5a1fe93ce2749a54fd403f2ed36d1e64e4ea3ce109d61fda6d5d5d52a5b1739d84c7e171849ba84f720025d1e72a40bc9ca64800eb9c04dcaecba61b3edac8ca05121de6caaaaa816e75812bfe3902f9a6c865398dcc1a357af5fb980b11e98bab6aa2ac8bf2a309929a99cac9f1728c5e17b5aaa4b489c74c880614b9b281fdad8f4f8ce850f8d54be28aa071091a2f95a2b8a70721c5a5d19e81136925c391d2f5cb5360bf933e95eea3be60263de1fb35645fd0989fff8d14e0cbfa654c6cf627548528d27819d2db22570d62227a1f231c474506eaa1876cc0e0e742fff63d8fd9af3f5495980d6c1f633bf86361d972327ca0b1a36d425f719fef1fb6c3be55a79e6ea84adf4b76b3a4a5653331afb91dfc928dd226ab9ee0e9172584601610bc718858b2d77a5878f28cb766df54713f0bfd7666db7dedb8d74f93536ecb2cc6f6008c586a26f957aca6b9de3cae1a329a7f3131439933f636e6ee18ac4bad401069ec4189b14ec77a8290db0c9db9172547f2e5f0e60a2672ab32b5da355f718f237213fa62221fd0c1c3aa80e6265a1ea8ec32960623ef3f1c0250111b490e3bb39b1536a6c834426b1894981f9866731d322f31d43218a9373b6e6cd9cb55cb4ec8139f2155fd52ad5dc83e4d43754abafba22878a451ca34b8878ae05381bfc239e65d853588776ae2e90c6d666f00b207952992ef1e68c9257a4ace0efdfaca2ab099c3b4cde9e845944a583f6d829ec15ae089dddf1eb282c4f1026c861bdc8e19af3ebae3b69e3377aa141724f1d1beadccd1e5bf1fd083a9d1f90198add51c32b1ec478d1a12a82ad38ae7aeeeb231e4468cf0328da6792f9a99c364a53698a1e62aa41d220abd895f54ab962caf85754a2858c73545dc973a38478e673ad2ccd574793fe26537a13c8595fa5910a8788b88404d782a57cdb762c3364ff83a10382923e5855dff1eef92d1924287deb2ab6a207ff8e9db53a1325cd138a45ff940a0311074ac3fb8ff2bd7db8388faced7a6abfa4a31571918a018b5ac346f1c809466c620a0a29a398eba41260c50eb2bcdb5e2d5bdd66e27c2340db025232f93cfe0af3951c3d79fcefecab715233b32bc75330a7ef3ae010dbb0f68275dd902b74161cca662151d67038ecd5da3a0084ad0fa89b821e963829042f845a758a71ee74158839cca9f1f6b82a14b4ce3d813b1453bdb9fa8c806e7639e77a498d7cdf600d95d8d4ccb80a477364a2b1d6e36987e49aed5d26fbf312297a4b76d7e53f193dde8a74f989ceb213779c3eba04d6aff6044ed923436372a2f46bd6855b8f1ef553bd7d3e7785c465d7a3b25b08f2d29cc4d97a870e189786a7a4661de48302838afb661edc552ff019ee22d4953bf0d78668492933ab18cc8074e820847f06db8d1c5ab669eb6653c5ad667444f2985c45dc2d9c33b3cbfbf871c756fd45ffd815a848ff74bbcbb07dbc543537719574ae6177f55135e710bdb2f19d85d52a7a71c11623e2dc2d4589f84bb80f6f18d723ecbacd77498bcac2741d8c4a5ea18a35fd9628658f4a58ea5604882979304175ef6cdcc1c9100d94362c48f6d7352dc4689a4ab05ad60bbd5ce0c6f9bbb43cd82b77f888bda8c11ac7e61bea2bb27317e19b214fbc330f3a4b668aed07f85f67433dc49e2fe275961efdf37dce0813a2871b1c76f8a0a5d6f26b78a025e6fa95fdcf9c5995f799e379e63b8d74f99d396d2fef0dddd17d9fb30bb05faba21158879237a2409d365e1b5b4317fc5cb0a3f16751cd79d5fe836fe593ff566feef29ebc2f7fdd143979bd2eef89b57548763e78a531e8a7d49d751aa533443bcdd295109c665eb0b2f32d2e06b88bd95467eebe8d373a56ca78678ef7fb7afa1f7f05488b7d2bb992ae3e0a5203080343069d47e53c1a459aa005b12da665d12a6f047433d47992585967ca9366c55775b36599fc4d923181c614d592ada4a4c0853fcb59cb8a0af1559822a42eb28956a2225465104c14aba294f7c0d66c7047f4c67f35fa76e22e04b2a036bcd405d6c067289b5d670b6edad473d83e3af214e8ec8405f26c8376c9bdb9c0b3bb22ebae1b39a8339872e1319544b359530bc156e0ac07ae4cbc6afdf5b8b561ac35891979402deb98fde169f7c12364cbadce04dbd6d71c6405512ce4d2379557d83b35a50da838a605f6e3b33e3745bd1bd45f46ea4da726da9d632f3ee749031562f5849963063355c69f413894798efd127791f5744637c797729acd96ca27d3ab19a238cea172b542e527cf59a6cfa7d9548f8a9d871177ae0917f260b129f207e0cdb19044372bb543df086d9b536e8878ceb2555d2d448ba4debfb9e1223485efb10e753645c532e54d392debd9f5333690776459dfe285c05bb6da7924c61ab973e2d77ee12b52e7ddfa3965d57655371c6f2c94c692f20126d8f706145ab338649baae442406dfd699d6f5145a31c63051c30a9208cb944bb28d75f24b3c17e21f9badfbefbb40b12eb88679770738dc601239f61096f315bf27c03a5a5e4bdd8f25627cd02df5e95056d272ea875e8d7b4d712145298aba995ee8a77c6819eedc4056d22a17387726438fd199c11ada1462b96a924ccb41ad5337f804a5faa213e9ebab834fa3fa3b7f292578624d18279806ab0e41156abf21fca8b9af14a6c1aae5fc95a709bf84e3e395b7997f9cea389e58c08342f3dc083e24c5fe0fc28b01768a76c48834ad12909d2fb3433f6beff9e7466a63e3b9ad3b2734e55355cdc4cc107ca486d9972a2a2e5c976adcb2f2cd70b11cfd7582e7d9acdae77befc9483ee73c9feaadfffac6d3379d719a6085281648a2ac275d32edb3374fcadb125148f37d771d7f290dd7032d9fc4dcfd463b53f654d25858f59a4e2a1ada195d668f47aca4351a2e7410d4e3fac7953405048799858baaa560704059df5c1c5dd3001e360d5a68c8c2d29ef1692d979c53beae37cc19df995d6bec081a44940cf8543e8b760f50d6f6e9b02f4fcd4114139021450ba00bdd5e5a3cc452b2056088cd14d9d4be9a5508550b28df01f7d25ea943cbb162370255ab6ed5a4cc6e345d12e3753895863c90efd2ce07f634c3b3b3efaf73ffe5b5f9cf453bb4636efadea05b03233139cd2709506521b5cc428e6aa5f54f29e9b6a1eaa2ee7dc1b5c7d9a5de3139655a440381472112ad20bc24416b476406aa729035a9fbd9ecd81c20fb56fbeae5d0a640c6f0c5920d6b244441ab1936a1b236524f7bbcec0259f824c8490d89a3295e0662231042a754c7ae3c1d77fdc49d87767016391744644b00f9547ab7a768d1fadd066f4070bdee2b78197084f25d0bd2daabcbe554e0f3696d6f77950ebc0d6e132c9804ac8ef3920b6ee1c50f072de7738d93609440b2784a186df2cabbee7cd82ff95a49d26ac06eae7ea52b256583d809e96fcba703ac6153ab61d3ba687f294ee181b8caeae245a69dd1f4635a8f2c3074e1385120e298fefc645af602ead34ba7f9fc57e379a08a819cd6f5dad94fe7aa7651c441afad9f838188eea4ddb6d0584e19c934ad8f29495e562c91ba4333a67f890286b8c2e4c297a18be7923f67d762d6949c3f1e7c268cb409d545733ceea06a2dedeeb44dc7cf08b4621b2cd09e018fb74f83ee6c0e69ac787ec281ace1e1c4688fd20b0a64e3c9a36328a800ffd2a58a442b3872d368190bfa9eee648bed878cc5612c62b8916102b7b9b35b9555af2241d71074e80a2ef86fdfdaa99e21727722dfc5ccb87ea70481d771f237c1a4d8d5abeecad2b5bb9ee49316fee8e1681541d56c5bebc17ae332ca832e5f39adc08a39eabb644aa2058ee13d42063f96eb2205b3d7a444869fc14832a940084a0973dc8b83b824be3775cbb4ff1273838e330738f7d99ac01e765dd00332b01ea04ea3e45c91c4bbb353cbb06c6c5d357d773c63f14d89b16f952834bfe5869af374a985fe83a4f598b29e324afaaea784385316040e578c86fe1486ef10c502e26768d85a140eaeeb83e06a2266ff635df624162daf5d04709d75a352aaa9c7f783d1f5cf3ed2120c3a3a304558275bebde65bacd64727815fcd8276a5ea3c48578357c75b1148d10af6f14ae20a4b88a468759af7ef477fc7488d6f94e23440c7bb4f48f0736c8d54c6d53836f084162754b340e131b4beb7589df2383a5dd07695ad134dcfe441f3b087e4b7e40c8a5e92ef8058256f93a525553b3b1668c1e5606f8b773aa4d46b088ec6617fe63864afb2f5db227f07f85844ca57adb2b553e65447afb635037c86426f8568251b2ccfa106232d98ceaa19f7a6fe449ebde48a0e06059afbb2f5616441b6e079a556f0d8ad8ab8e4a5ee3feab72af26ffa77bb24af0339431582f4f1a32e3871cdb74202f59036a01d1eb1a3a1375eb0c716d841f05d673f6faa6bb51db4e5aa8e87eaef5e125e5279ae267538ab3ae7a95a66f25bb27c6d78024320d259aeb8cc3e756f9de9c88db9b2544213475ce871626e98568be2592e595dd921355794b89896516a95e539aec1610148d3589cf8372c0e43bf3851d718c78931eeb0b1bdc19d3a6a961770ab24d4299c3f790fac5f29ae17daf52ea1375433ec593befcb41414daff10efff9c5312fe7256f7937f2c5e21f7d578c318391245304d969741fdae8bf367cc35fd68d63c68b2ef5d36f807ec9dbde01f827715cdcb93157aa21ab4b25ad3856aa8210ccbb36495f8818562b7406248675c33bb571a6b7b5d19df2ea9e90de631bdd611351abee68bd11cb345278a2015e600883152c636d935502a5ada1e4de4b2e71111e622337cc5530ac4455c76f4ca00eb8aa31c111300d79ad7d7b4c422f6dda7f1f867bdb2ad38a54642d5bd5f2365433f04008ac1d5fb1939bbac805db54159f7121b24662dc2c2b679b322346694fbca081bff11cfa8ab8a95014af5e9489d97511f3d1a364307458a9c988cc9efff7786c13a681f307240b2ab7d6db000b840c21ef95463552a514937f41a56f47d90e458b9055de8945ce8aa285872c73142ba6ce9c32f8ca58a118df4053d5e722c45dbef727b4899e5e969c8eb8154942544200b2b965965bab16cd45d6148b854a9ab7ac6bcf709b82c1ee8c3d89aee1954a041744a3765c9840d82cfa8e7afea19dc089da64376dbdca5a6d32e659a3cb9b03c53029d98c9450f2ec862761351e2b8f027404d1d9eee4bddf34a2b8e1e576e8a56c58158b65ab3decc85cd914141c5905fe8b43483c35ea0168e5dfd317bafd42957a78e944b4435ed47ff4d5a469b1c11582a4c38e3d15a861218e753d8be0ba254c51dbbf29cb9d7ea7e7c56a5d72c836b35269168698e99067b3255d4ab301a39d72832b722cdb93fbc6e8e79031a998e359838f9d7f656f33616dd3c6010b5de6d014eaf971d04a0868e013908f9a33701b55ae7b9aedb9aeeadb2e2746afda2bce2b0146250e270356e4de25dbba555a61f00053c76376d1143c078f54f97ed06464435637b6ee3afc6b5ab74b960976cedb21a8fd8870ae650ea8703e2b6bc147e13d222ba253bd25bffbc9b81e3e7ce7a86be2e1587b13f24e6a1b0df16771429bc80edd7de7b5eb7fb47a96b1b6ec78d7aca92d10c6bc4ddf416cd0f528ddca52518ddd77afcf53baba215b89c58461455557a5255fd1f68160fc83a4dcf2a28b9a4d317b4155b770cdd13512c3a68ab6ae4680742d5fadeb266b8a72cb96bc5c6b7f05a5e00e157e458506d3a8f8336a78be99f1c1201bb2e9213bfe867d9fb5cbd1aaa8e097887260c89e1c5275d39c0de414df1cef50151c6aa08ec7eccf8f806c800c9109b159a13f023278d17ad46446f4dea8f82d03dbbfafe6babc17d3531482dd3675b500505dde630f23cabc9558447fbfbcc7a61cbc19923d8b2ad5f3cfa93eddd04aa9ccace4f2eaf5c5a9a90d68d2ce4048019f2db3aa102b94268a0a2835d39e000d6f36685bc2c850c1a61c1c7d3795c4c659cbf352657d65672a33af4d3aab9dffda9a38064392519360b4d954a6fb03c99d34b9249fab6c3be5ac5899ac1603089c6878266a7030047a7aa80d2845cb1a605aa095de67b65e3775a65c84bf627fabd77cbe914c55626b59c34115c4e63c6b378d9ca3962fad121510bd59ad177c528a1a25ae69268a1918a125f0a8174c7d4d04aaf1982913dc74cb4eda7aa5532aab3cab1a5e0ec7e2e5084af02c545677898c14cb751e0710e41cc3e06ec55f34d104a408ee2aa1be5313181f922a58ce720e1cf02dd8cae45d1c8dea39486af8a242e6ecfab6927c6b21a14aa2531aec2bcafa96bcadd157224c96e63f84c07ddca1c47cdc6922df37fc53fe29eb05b43babe6f5201fb2d883147d3ee59fdc4df897aa32834d7b2581750feb535c3196c6435ee58e6ecbb9185e3a759574dcaa29b8ca1aed5e9abcebd2d8c45a77b93cbaf3ffa0ebf35b20ba9b2f3c30f3de099318e5e9ee70e58cb4aba55c951a78663256d473f63e7f3f643f6f44cbae395fb31880376bf0309683d3a5059bdcff9c22c975fb5f1f8389910b04c101d3ad95e2cddb12268d47fa79cb6dfaea07a02b2b6c62061b3b3d8adf2c2723e81dae15bef077b952073bc8ee17bd572e96ffa617acf325e979bd12cbff1ff11ef5be17884afe9d30a7e0ae9524328a6b7f76255ba082b993724195ac8698d8dca45cc300a8a29aa8ee04736c77ff06903948126ae770be7d737af28f48a698b2a878242e64dd1455fb82af2f1ace070b2effaa8802fc4272960e7188c007723c965c7bdb16bc79542caaba713c03a5886512475dde430f76de3cbd9462c8e565a537d101c3cbcbeaf2b2facf7a036a505eb5dcd63441872bac23a1e52ba2e8da7132983b024e3107eea1e328d027e156f29b334c266f73268e2e2fabbf6fc0c8a3c2d194433f0c0d612a8af59723086e6acfe4fca6adeb122421f9f3bae1b3427028aa92b56c5df019c85cdb7ad3b0998aa492bb340050696b2eab0b3de7bc916bde2a70e9c4fa108d20ac39eafffde3a37fc7f68fa0831c6984900618500d644a87cd9e51d046d34d8c1abe2eb3191f8cdf7ef5eef2723c5ec88b39bebc77c8b04e2926a4c0892f96dcad388375700aea8523373521eb049c1cfd5c1712bbe04733e257e34bc4c3cb7b87ddbe81ce25681bce0daee77cdd2e3d03154ea94c9cdf1cb3a3c78f7d6d11360123e2e53d88bb8598db55ddf043df82e93d4586cc3963c05ee55d3a699a6c3bc065d96db7b86db97455d64f5ecbef7f3a9d98488a79265a2e5a2b22f14c145cc8577ecb26877483300c3d08e7e90cbe46deb7d9b228739253da01307c7421cc1e4aaaa229bb29174d0294f64ad7a0fb0db0326e5d9d19123c447749152837644d10c6b567ed673d579fa2cfe164dea8b106ba8a81335adb556759e501b79b66c70e0cc2c61426ecd80151d838bac8f0c7c8928c91f5d72f02e23d735faa8ec9dd0b71fc2a15320af1a210eb5a749524b92ac4b90e3cef6c259fe26b6539ee6ca8dcd53fab4086c1667d7fee528640a555c4cd4513ff4446d7edfbe514a4d04b650ef5201c357d74061100918fa724ecf0718824ab8a6cd73bfd3e9994e87e22307553fe6b477708fa64f630747caecd2f7d5dccae593d9f938420769c71c716080cfa1d9abd16b1a4c1345d7d9ff34c7b4dec99553fbc63492b5967a2d180be272ce88ce696f3278fe79736ddfc2ccd5d8d3faf9cb8fe0355f3c99ba58ca1c6f9a381727da0cdcf6eb36ddac380edce0c4dfff4ad3eaeffe88491269bc72383cdf7bafa26f238b29423c95d73c2aa371a4a87eb28ddb3ca3e73774b0dcbd25516fad1213c3f7a7de77e2a409207b1e3fe46b23c32ed35e3a4113434437b13e46a50e51affaa6ef944fe97654c7691b762ac5236141593123efbbd2a6298548c27a989add1df5da05fb683412e8a5558a9418df07959d2f5e8ec98bd90ef4f55df4628469fb2fe7dee8abe1fe95bd1952b3de431a2996b6d958b7482ea7935b4616411e6a90f27d3872dea87b6e3b1c13fad7d06b79a66538dd8f3926715dbac696d4bcc699309067ca309fae27a1870ef0c88e0ce3cc78150b24f31901d9485d60909f3af7f115cd6487a5ae571146d0b89a216cfd9237b01f641c408b1eba46f1d7071a81ed0977d32391bf4a252598a15a56d702a74e28b30962119ed4ce71acf2891a8af0233079776c585c8162836ab1cafa7d54c0a43507f173cd266808b24bf84b9063072c5a65bc23f5aff2a8e35f4ea8a57ed90a85501aa4a971a8095ee2f9e13a277b2da817937ccdae2397869fe8b79f141bd37f5dca8f554ef292feb5b5016edd0b0f648afaf970c730dd431284d488819e3af2007884936c2a64d0d8722d97934b3af4b0e7e7b90a74ad2a46c5adf7073c09347872376517d38f0dcf522b487be8bfb57f8d06f0deca45fe18e681bb5f089fe4bb4114c825a4bf610ffb50f41a1c8d691ba29a24d9b134dda5cdfea2bbcd6f17cdc11faa45f8dcf17a042cd43548c716468f5d026d856740737cf2326bb51d1eb4378d2e0712cb3963723061646d06b82abab143da79b963559837e36b1193a853ed6b73e00bb4ba9b1ce5359f056c1b1d9590fcb1497c00ea36951c52a82356fff1792a4c85ba26b30f443993d92505b6efb6d84eac5f34d2784041745c1dcf36dc3b3eb1feaa26a2318ebb5f034aac1d7b83a55ceabd8467fc6c8cad5a69d8a9c261990597b5d39177cb00c9eeebe2401f443babbbf8a4ea429f20f9ee379d73c3a362d984ac35a0ef74d349543cf19c4ba2c665c8ee3d8113f119705e39cf87db62866acda4005fface44d7ba0bebc009e5e80575f51d99ca692f713943d0057729255f191d626601534351c56fc375962372bf065d729170bc1167555656c8ac5bf25aba1a481b2aed7da8dcc66eafefee43faede9c9e3cbf387bfdeaeaece2f4cd89fcdb39034bd153dd4aaf516b9adcfbef927c49e65ddc72d5828e6fc54593add6755920f12ce64e5b27a197a1b015bf25b9ba74f8d8ba985df39c6dd67af054a1ca6f300c7c8f9c261ef319c06240d7fc375eae35327e4a42015b2503d162994b9d674b9e495696f47b97ced6e957b4bc3181268fa977c24ff429b330f6416e236b103f4981d3f198fd8d573348df7a5b37d7e8cadaded60cfc1e30436095abf2d6b74b4ed515e331647dadab1bc8e203a5e859c35759e1ae474997193ebd666e7c8807142cc6ee1978c84bec78f89082e2f83875173ad86ae45189f646677aa5bb88264481872775f9b05c8459dc483b54fbcffbe0f21efba1a9a7d914b3926332820c6b866bb3bd0952d398a8cabc5240bd7dfcee3064111c502a62f818597ce040e2d93f23453ed51152744d8c4dfbba41884348cb118e6543126d2e8e507cf47bbd2dde514d7d2c09d6ce1be9c54a60d237a2fbefaac740aa0b9897d97b91056fdf04a4c65143ca19a799e0942a07d4294db7d234dcab9da47f77e61acc919f37cf61e5e4a97234f27e9a98fe6525d981931a8726b9d5071f525a2b87f11beeb061772dd8a39e000cdacf72f46ee165b12a2a95463e93775fdd37d1d2f9766da0ebadd101bc3aab6f6a28d32176674a1f62a9ab621abe2dde29d075411755af5f18c474e7caedec985d5d613efc81f9cb2f9f860c671eb25fbc2599247966308b1038e4a17b6b4f5fbdb83afde7e9ab0b764c073bad723dd4d338044eab5c8ff8c501608b403aadec56e240515d86898d102aef1780b5231b78248e9f1662bfcbaeddf734a6a292c8fd8e9dc9b7acaa1fd56b1b1686eaa64d51e6417685988841e4a09d29fd2237146419b3dbd86c7535e3dd39265383775ce7d1bc285b49626d993d5af31e48a55e5558f73ef01ea39439af2bf9ac00c2bc2c78993b1c39a4efdb833a5fdefb8b7aeee630964987dba829b0d04e0c8fa4bc9d638eb3177c5637595b37e0bb143e17a4f468d62c780b7589d7439673316b8a751ba8a8d1fb34f1b1135be3dbb463417d7ed9c8da6a52e53d553c25e443d4509a6595848ece9c07dcf1026220036c6631a3e678cca6d994976c0cda445c55a4919e6fc5db659de34588c1806c2c560a9c8c989e8eec3669e6bdc1d281c8119d5077b76005499336af362bde60c82996a74eb59c918cd948f8924d6f9ba2b5cd740e32bb59955560b511706abaf910ab1fdd1682abf4e0f2588b6ac99ba26593311ba0df2cfc1b787fcd36b65cb4d152fa9ff638fdba2ab713ef90d9b1a43ec7dfb05f827ec00f54455b6465f12fde5c1d41acb8813bf99430bcc40fb6df81f43c0cf720a24dc83a27694592073028fb24c54a080fa1b1214575535f733aaa4e8ea9e31e217e3635b6aeab1ca2b4036a5b52372260454ff9535a2b2f1100ecabdac9599dbd883c4c881c40e23dfa3acad6eb72ab148859b3d8ac78d58aa87ecbe6ab4b8ee6a8735456075d665fd9c39aa285f4a358d113003f43b65955ddd2b1ae7a5b9f4bff558e3fa4d03fa8c5789d6332fd2e44dd8df10bdef6c04db5af78da5838826060e10edc45adb33cff5b91e7bc923b57c78c7b761c8d71885d86816eb4006cf41f710a6709f8571ea11f3240c08b5a8bc61e1be97d4d153f45d87d6b57b07362f5c2c4d838a78c9893523e896468070a9f50afcd85794bd8987d2bc9b7a1dc23bccca9477a3c665929ea8922fab14e09a29fa2dabf218a474ec72062fa6cd8c78f899769271d253ea16fe92461f2a9c4e50a3963e72284d8219905d98ee51af5e961f73caed851759fc18e43f409452cecaed7d9dc78628533cb6e24e8a4719f7ca2a2622842bf5945b2b26671048fd513f8efd7f0dfdfbb8f8f6a3aafe4723e394122e695a3c9fe8e246baf2a46c8f195a8aaa78e8ae7ee7b2f7ba1e1f0e3477679efcf9b0aa41ab5926f2eefc1328f9c1040b5cacb7bb2a96cd17bbd4fdcf53eb9db7a118ace92fee2ade950afe9ae20c4fc2ff10545e5be004a46ac8c2ee4f7a93741c257be1e98f658bd1f84e9a36ddd67922258fa8c2d0222bd52fe4aa9120a31e3736aff4f345f269fa2385f065705fee9d096e3e8331c98e0ceaa100b5c5d328efa0a0375d2a7ca9ee1af13b613ff1d75debc8a0e6bf1d719f8c9d39daaa59d4e7836f3a79a765e8593debfcfe6559004f43d81d87b8669620494e4561035b5b9f441f9023ca94743007be082f2e3477660bf0682a1521f78858920770db89e033689215bd4adf62123730551b9feaba30a3a6abc303dd11d151f05cf29d5e5ff0a611f10c76146bfc6b87ff4118d411ebe8c0af17d3dfd70a288ff313176bad3f565f91c2b89c70e473b3837de1f4bf9ae40c7c34312f567adffcfa13fa82be102189bdb4dc16fc1e279cdf95a154e2c6ef89089da1639864660fdbfcdb6aa36828a95cda1be5ac555055437e25465da414db84daca887abea96cd370d9469dea8c40aa2969c884ed6aa33aafe659d35d90a3b5e5093a1fc45b7c12315daf3a9315761c86e97c56ce9d784106dbdb6eb81844918c26c7686cb9d6f5a53add2cbd9aa921a0de4084356af5be1e7055eb7c2f3a1c19fd8e9f73f5cfce7d5eb6fff7efafce2a9cbd17f215a02dbf2715a928e135c758c686442c9c09a6a0444c3cc62ae969ce7d0e637a633e435c763ce6633be6e8d924914f2dda35e149b0a7ccfa93ad62108100080841f817aff3e40120374259992cb20b45e2d210c24a523369bea7c5bcdd8313b80c184313ddebfaf7eca79996ddd4ed451499f991a297ceeabba5965a5c614f7bd35dc64c56ffd30db4eded5969b1e980a8a9b2a30017c429c1c29bf21f5af48906e1ff600422b347c40458744c9185c5f36f5ea3596ef83230a121be45cf201901d2084065aa74da4184c1046077c06cc54292d32432a0fafb78a6458198146b78525357277125d58b0de3075224d75a000ea811d064b7617eaba2b16918cb0741d816f5dc16fcd52a3dc80da54243a553b61ea26c40774e099512545dac72d6c177e87d5651c1a4277f8ace3db845942e31fc4b3c47269fdb821e9efc7c9e3f8cda68af97be9cbc33f800f3dbc947c3ee7b3f6bfdd5b6697187dd15e3a6f96aaf9acccc1264ba07de6d28f9a9ace6cf5f25e0daa5a9ce6625934b99da69e476b726615d39dba1f32f37ee18b95ce7d40fbe2016956d4d598d26bca9eb1db265b5387d1817b8d71a44336d17ffbfca75110d79ddeaf03885ef20055545de048d815402cbf83a4eb02e9bf3658820bd60955f61a7ede369b59bb69b2d2bd99ea733312d106ea7aaa213f7eb4ed55412d176c7bbe4cf28ed8cd7ffcc8e28c04a5829a8676445be9e46e07ddf1f63d22ed857522ed62340c9aeffd56f47c22623820798aff6bc2a0b44751d14bdfc018cf7c40375daf682484cbfaf8c423d71bf5ca763efe70e1f9875627bab0a46c107990c974142b0e10fd064aa963c60b07b851d3982629df8b10fb344b3d2f1a7e66755201a42809d22b8ab8b71f38239b8d69c5d81d47358386ba08424352a587bb388814eb60352a3e3d7593df4c33c15f565dde217ec28d585a02e2caf8b2da650965fecdef8868a78bb5c68a21e39df1e7ae734e90631c4475aaf70eb70f292da4f4f7b7babe1e5cdef3c7904f6b384c04fc914a129f31bd1da5f702dca196757d1debe8a92cdb7ae56815bf8e691517bc3d69eb15dd8f7c979d9fdd077336dd3d2afceee92a1d87cd7ff02d3b862220a08a33ee5d442f0a0aedb65ebda59dde79e8153680f267b3692fc132ecadded073de0edecea6ef125c54dd140bc901c9ee720fef9c456b4e4e363ae86187d8dfb30c721d5478c2a02a53faa5c1a63ab4b8b55f8491dc0775c00b61131044a74be4de3bdf7571307a34c9c17697acc1d176ad32a0529d34c61698ae915df46e945b7d14793cf0b3773f0c4d8ed6378afb209eefba4baa89edfc9c1833231de9e7218b4775936ef106c3a8ebbbee137cb3cddfc47287f9fdc2463427670770d28d9e7a6221348f94544e18c16245a2e3be0dde5977f935923bef6308dcdf695d973cabd0a4116d21daa600a1cdc7dd9caf1b3ecb5a9e0f2eefbd30ff50acd6bc6ed80377c00798bee90170210fd8f137ecc1e5e5e53d8876937f7930640f245cec27432fd457f97fb51ef98b6c077f410d3c7c06fb21cf725f98853b92312da63bdfc46d81fc81b3dc58fc5026381cdd24fa852cf85ed042fe8105241567906734647de5c800b2d4a408c08e19d30ab58e29edc9a7e655768f8e89ed187bccaee4c7e8a8cab0a6323875a09a36ab79280da6b521d3e523d803809d442d85424c8ea54ff1818f44c958fb80faf2ec69aa6dac90b48496a20a701133eff2b16778886c92284603610729cade4520e8ca3a9e868383d4c7f85a3a6871dfd57492f38383f4e7f88a3a887bdf1575be0f07073d5e86342e40b12fbfa4788f11a318e03ccffb9ebef7b6db93a71f124e77f1977ed7039562105232b1177af2d3c99b5767affe3a612ff874b3300554eaaadc8ea0d23c461bbf7a7d0189e56f7883664dac698f06d8f7f135bc6785601c03e2463e35d89db906c017ffd47d6d0c57e3412b1a5c1876ea8c24414f13aea52ae305471fbcfe1cff6554615c881fcaaca8d0a17740a61832c92be87f3a6ae86bbe55041d6a71bb821d9af1ad7097704d78a63c134cb60736c15f9cc1aecaba5ea3a9c9481deba65e47240fed5440d67c4c40062e8ba1f0710019944785c04ccae120b13434d1a9de86bfbe4b3f49773b36f7e8c2094790308c5616d09f88e9459d8bf5a9f4cfe629fb444f9f4fec2b9c916e56afd1b04c428f39a3eacf98b71bdf78b9e2d0698699ea88da2f951d6b0ff3056f5fdf563f989dea168e9b4924d51ebf7d41478b804a5529b3b0ca66b317c4853a06ba3cea823d644ed7c3a7ec93e33a1f209db3ba8066f6f1ad7747f03cc8190d53059017559c78c83fea8a0d5c40fa8e4cf66aba348a7f687995db17dd77ff2930a9b79e7bc84299f84b58d902dfc96f943767f0e1cfc7ecf712b91ff82b7f60b1fcc9a3df77789df9b6364df0026b5b720a614d6cfb38ac1c148475fa3ed3ae568789b94c8d011b0e575792620b94ee56d97ab482140a1141cc9cbf3a2f76cc32814e58760e620e83337548b7120e5e5832c3a0a084fb2b58d50012c9c1ac8fba0e58d01b0703cacbe20317ec7747fff6fbc7ba4746e0a41e368d965ad8d7b171ee6a46bc5aca091a1c7a955d73268043c1c372aa9d6aaf30e5a6a89609882f3cdc5637c1b9eafe81e1427f2adae50fa6c3cedbe46f2050d6e100115df05e67117314407d907fc81f3f5a854acef9daba55b167ace173db72c2e4776fe55e4df05f05449e36eeea68c8aeb221e3574f86ec6afa459d629d1b4b11415ed953d81de4f833d400e25555e5645a587780df0fb5d7a1d8acd775d3f27cc47e80e47b5899b3d9cc40a5cb3faccb6256b4e6dd5b656b79e9e564efdbfaefe7efe5f62a2efb9f73ce0a21369cfdee0fbf7f1cf3b14d3e1d1a86d77c2bf07a135ef21f7c2b68d7407b904c6a6dde2e392e307f575758f97a207f391caa0ff009ff3aaaf8877670f8941de84fa3bcaef8d364cb0e272735b3e9717534ba09ec90f40ff09172692a885e1f72a79f93d28f5c345bc8ee5a4b9c2d211d13e5a1ea866d2ab1e6b3625ef0dc86fd213b854ecec57cfb0fbe95f31fc6792bfd67774a676d7d939b86746900b85f74ae43f89d7d8ab8e8cc8b0a2a29c6d33276652f97c0338774ffbe7780f297c155664f0fe9cfe121bbcad00688bff7dcb0b35454d0ca8daa2ca55747986e28b2bf84f65fff259a4f30d876f7552188e36c260a3df78a3c495d912716f19f7857e4897b45222d1357c4bb1e4f3aafc7de6c3da5e212a3a3a3de9d34fba31cb8e2ef9e97d763baf803557e187c85055bcb9115651792d1137c56577992d3f31757085d5f298c81ecb3bc1f32812964d903ad187a2097413915a02628cbc3d3c2caba5af0c63e306cba0ddee111fb514842858915a4fc67495642a9afff44af246289e513edab21efbf22acf6c7d4d69f5171ff9a6fdfa51a4ebc7c135db07c662c698683e86a3e09f88dcfc56012006661d46910a67f142a605a7b54c5bbcf4be74ba2e25e54d9b480c7f4cf10137e3b827728315ff3ad1bab0c8ac324948231c7639b1a62a812349a1c86d97a5d163c1feaca7aefbd50e7f7b16992c0eb96c46123fef2faa68165f4b57da25fdb27ee6bfb24f2da265fdae42b6b5ed827f4857de2bcb0534bfced0b3b252fec931eb953fc97f5897d599f445fd6f0218dee2e967b3dd44484d50a95da5493b9508aa9ea9c5fd45e2fcf95c5f48ea6d8890d207ff4840c539fc0d917a6a296cd411c0d953898263fe7a454d6fdfbccfd856660a483abe4fb4e38d331db54c57f6db837e8e16895ad07b1bd44bcd48576180dc4495d24751fd83b7df687bcd3fdcbc27da99508bc1138740cbcb65efd31d6e21bcd9b7a3520d0d09d098ce9aabb21ac82b617bce24044493531038997657dfb5cd2b6b284941f985d980002626d68b2fd97dfbdfee9eaf9c9abe7a7df7d77fa42597c01bcd1b1888adef06fe81b3df0be7bf9150b115f9b5ff340c74aaa94f9a6ba64b4770417e6657d3b3030f2735df80a40f9741e3967096fe4c141f43d064729b910a3ba3bb2fef39068d54d389509fbe4f99611e5356f561a0bec957ba161bde3313b5bad4b2ee7c38c2ed34c69f2966dbb1693f17851b4cbcd7434ab57e3f6e7f1ac1e4fcb7a3a5e65a2e5cd1872388f7e161eac3b7db866ed8758b670f0066c16a00ad4400d1ae892770f1f12a40d5a2db8e7fa8f09591fc9ee45ae180e1c4a7d903cebe5bda1059e0ee69eb51fc0df50844680864b5c8d549e50d97b7f68ea550139f0e3391494fa5cb5a9f82d533d88d1a0e1a22e6fa0f6012a68a20a12d1f275a412201e082e12328bcabf062d88ffe8cb4d392fca92e772de8468d373732ea0c259d92ec1bd0123df3e67b8855c1e8adf940079f8100e14e4cd43643616bc02a66a0fe9a147112c435b41caeb5bf18a41c1e20feda0e16d1ff687667aff192c0992d4fd9f734cc0ccd17392bbfb1f7c4ea64f9a6f96d0b3f257c3db51bbe46108577786b4ac6299d8563395703a2d40eaf107726586a424750489d2674918a90d01db9f94792c1b22e91ab48f2475d27f022c567f1bf5ecafd3153bc3200c08b51b922bd5e380299d24c915e45198a293ed926b1bbc2391b8c32bea3f9a0117b2e73dc24e9080a63314ba4b6e7301933c349c4abf4e5ea728e0c17086b2d6b4ac67d7e0fbad4e63503748040e996837f379bcb6a2e2af91a15152e32051608dccca33c937d1a266fa89c5ac80793d6445fb40a83d953c3f48cd0e6be47917f2892ee473fbab9b578379bdf69d0ae2907647d046c3ed54e7ac946ca1d90729abedc1042f3aab37181320cf4543257e699065184035fd38fbdfe39aeca0c76616b52fcc7e3fb35e40f01c4031798a48ddea8f686a38b555cf8bc1e5f13d0c570077597d45a5fd4bdba52a73db0e0e231e0e266806fcfea870fada864e85c55cac2b94235606267c4cebf2f123a35fd01929fe0d62e2d4373f1e4bbb5e49493a5f1555215aac70e047e0b8d12cfec2b4cd3c36870b680b032fef4e223a71df289518625ede3b738e042e1a28de9dacbf195376b399d1240cc176aa6cacc6a65f29a1a2f475d6bbc0e961c13e39aa3e130c97f74eb5af0a3112839157edcaf86411ff9226db465d3ce04861afa39ca3ff83e708faf93b6097f74ec85d825271bc814a7e5a77cba1884721966ed491bf32e358e8a25fc4c1d06d30d197b4773c533873c8a3476b33e85df62616e4522d13fb899d8199c8eaa63b277c4af1b26b3c73c1d0a52b89ec89f0c268f770d76ad614b11a59382e7b4c1a83015efa7d6726aac7f41ae8815f114b9d0afc8d283ee521abe0e6e363c8870a597fcc2f3bae1b0d0c216e45db9d3edb11caae92db1adf9c34b58e55b73d80eeaaae1c325862b4cc8c097b1b5a2793e3911053adfef5211863192cc0f1399443a49d17fdd68427f4b3adb9e7b84b97f88da749fc52d4ddaec3a81de181b3ba4734c1d2a395f8afb232ca1e20e1e8c7a1288b16dc733303d648606780c6dd20826c6fe4b05eb9c9aa3d4621929befb7011d782d9bcb02925bb7293e050db2cb380d20ae5efffda8c0dd611af0acea6a447956e59dd0c9fec94322b0428ec54d18183aba81b11a78182c70b6cad6022fc12a5b4bea63581e7d39952742100cd24913d379767712bdb4b37ff4f46896e397b5ca208375db864c70ce7ef76f8f8f3c9ceca0e51f3fd2190f1c1aed7d2c84a5b37e475b5f2bf53d464ae384c2bf0f77b4cc7c1e3520b168bf2d290d76bf0346ff1dc829bbbcf7d944334e055364f39a6f85a400de4e23782e1bc5abcdd6d39ff5bd5c7074a64b48393e254b8f498cb9f5f4e7112c339685d81ff59c77adf4aea3226ded8400d897ad2873356460fa23c12bf0efa741f5a2bb630b5dc8e5bd07b89b07a1385e57544a55fe704345cc25ad6b2d498f973252ae8d9f892706d73c5881bfd32f149baef9f65d1c52fb6151ef1925e2c2affd66dd0bcb14f0be149e09a824f96b21915eecaf8246bc6a9be2b7c2a3b7e01fa6b1e937442733b141aa9e93ef85551a96bf0ef9822df804ec2dfc008e77891d7d1114343bdb170777609f40f02ac7c15e1c91294a70d0e39c9245ed4d8a41a19dbcf77330bf3a62456546881a31e8deae8e86a6f15bf8f7bb0ede38e9cf98a8ac1f61ac772360fa4a83fe215fb163c24504c0e31f0ad116d5c2c96b90e52b2d0618e2ed8b1961c7887c2107820a4e038218e93d873a653d4896e71e3b69071c420be59b7c6aa2dca2b3741b0712240a9e068443b087ee0113e82c07ccf2dc056cf748493a4398e76bbe5554004bc9474c1518ddb0ce1ac1cf2ab5a3a3c7a9a84cd9fa1b55d380ba5903b1d2c94d64a3686c4ef2d22aaf5d39b48444a492ad0692a6156a92a3a71e14e1fd61c72c8cd24839d6c6d1ec4b69681e4834f97ce2caac1bb09b147855df70438ceef4ce1381420db7071276dc0f95bb6c8fc13aeec6fe83fd0fbc1e4055b07639cef3db62aa3afd5f0d599799f83c4c05e7018f3704c8be9e235728411f7fef42e387ec1d53b6cb9743aef4f32f01e1f7f61cb09b37bdc380bb78528db73a02e9cf84d6fea63828f7f5ab21e082f06d1e021e38c819532e85d6d03ba96eae69bac5cf45ab8015fb3c2cd8b1be5fe7c4175ffa7d7432e062f0816bd47d3e1db2d9f475f3b268f890f9e993a34a48ddbc97a15a4dea72a7a1c1ba7b19bbacd7c124e9c163e259b2bbce0bda05985da66c0df5f4587d569436717ffe1aa9d1bbf76a557c8a122b5e9b542166ce9cb77cd63edfce4a2ebc528afcc3ba6edaefb3b538114827fc160d9f6d1ac14f6f7883fe82aa58e3a5a9d246dcc3664b3e0007182af3c493cdd8fc1476710ed6aeb2755296a1d6a0c899b5f5dfcfffc6cb356f06a2de3433bb8821bbba52ae2ee79c573eb5b5594fbd4d07e2bf1a384a92f1d3d3c87dc52f8a0699f20ebb87188fd98ba2e1b3b6dcd252ae7268356421e0173aa7faa22d9cd12a85b41e6c649276c9d98bacb5a9575ac1cbb91c7d56576d269f1d5ddfca12c5c81a483c911cae27d04287bb0ea007670eafd061f2e4e9b66d8a995bce20193f6c09d204a88a64eab012ab8b2e0c9841f5c1cc8637d5a23c4debebfc7cec653ec51c20a4c5fdfb149d001deedf773709ec985e5af49d749b4b88f90bdea14f54cdd9c78fcc4de2169f56f92b63e1272017ce0a864cdfd7b7ef2ce10854416d7d92e7ec5835f6b4965aa717410c97200518117ac68aab232bd9c3ac3ef3c9a89aae602063957e6356b03fb3f2292b1e3e8cd8e4c5d5d1dbe29deef3b6781763ffa1593fed3139129be8e1071d1ef87a6e1a481c3be72d091d0c255293163b7c2888e7523ce04aaef9c9ae83d629da0f13e72dffa8739ed7cd69365b46cedaefa001fb049457bd3120e2af1dfe440ee4c9be0a420d95afef8cfe9f058eaf47eb8d58fe7af0f87a872a332649ec85addf67eb5f155b7fdf075be5aaef8eadbe94e79fd1ef2dd3f3ab9dd3efef8ab77fd8059f5f3efd6a80f98356a1f627e8fb41e50f3bb0773c662fb3b29c027b500357208a768301c110446379b1ac62be000eae514e3a1aca136010cffeb08de43052172602e710c00d1711b0e208f06137703fc5a2e7134cb9cf8e93d58cc74c42f6366b72ac8dd516e8e61361a34d3a443727bff3b6da9489bf780290fee2a61ad0bc7f621057ba323de3bc5b648890bb338a1b1f259fb1b418a2d942bfcfa4271709e97ce9393edd4b2673baaa706c20873e0af497c022ee489203e703bf040e06bdbfb5dc9161bbae80ef7a2affffe720d7a8fcf9e143bfd44cb3106faf80e932ede5bf43060b6b85b4bcf9b6e1d9f50f7551b54185005a025b0e2cffa3d9c647ece85d279e868343f775bd1ef8524353dc20b1316eda2f9b7a75d22cc4c08dbd077cb6ede3acffe7abc8f09ca02ac1b398aaaca8449143909a14a9786e9238294f5b2088dad371c49ed7d0be616b95324b4996612f53a14da7582cd33135160ca3425c34d94c5f23f977fe7d9df3d1abd7af4e3d18e994e965bd185cde7bbbaaa71fa04a1b7fa78c2564581387fa00360a55a731057a7451f1050578f08c2cf0db37a727ff6013f2cb77afff1a21b151acb01bd3753b087efadbce04678f8352125a694512b8c39116d5e285d9cdd360a0a3e4402ac8006ecb63cf3101ba3ee9d915b34ebc3df2ab3b7985cb5f6c1accc1d6365925329dbd064ac6aacad1aa5af7a66a8b12d08e57b916fe492f5d4bfcc2fd1953e64f39548715db6ab66ceaaade8872cbaabae2ed9297f29a616735842a47ae0620e5b38197c0050928656e2b950b097cdd5f972acf2a9d3d0e7ade6642410b13c7c91d3cc0591e309893b7bc895622273b1ae81a46ed528af40b5f018dbf7a955ccdafc42cb16f82466def4270dbd275720de16dfa8c5c55b74b5e0dd60dcf8b59d672c0a4235d356db747d01164d9957d486e02f8a79b833aaaac9253db305a6705a1376f7a9d7209bf7c8a69ad834e898abca04dc112c01853167bd4a09ca36aa57667ecd25eb01e1d8a1d3b05867756d5d615f7b5d59f54d98c4b05b95b66d1ff0c4f37a43342460583b22feffdf4b7d357571767df9fbefef122952151572ad625489341ffb491caa9141dd03797d03f2a3f9b49ac44bfb991db43e72c22d7c116030e0a03ffb4e4fb1505c6f452aa94a61d4cbe748fb0e9e5bd61b4eaaf3e18c9cc608d769aac271a17a310359af0b419a90123070d684ab12e7a52b392678dc644b77930a2534134e59ca52e927f57f5c623373271e52315b2f78814800ad3bae06a0c55dd881f50642b91e6816afe006c960f540cfe03924a6b56afa6209f7819b4304cff6928bdde253993872e01dd32bdafae2457b8a806e62fbfe85318b25f98dacd44a771f874e873152a7948271deaa0282a1d8e221f24719b872271b958d8ec251ef80299d94ba77892af74a6fdc08a88bf5387493fb2451b2bffc1212a2c320492f89bac2425b4aa0516b80b3e6ab21ffd28b6ab695dd24c76e3319302f3aaf81770881376cb595e570f5ac87a0e8c0984f62a93a6cdd25be52ac7c532bb91028414014adef272cb661bd1d62b9639d65390055f6cab6c55cc94be6fa81620c712d7c59af102f2b99b49abac541eb22a661fbf4d25fb4913c117adb041383665aa808c285041141affd0d41fb6174db6764cafcb4c4c08cae9aca5951b56a46f3e12eee36306272a816c7eb9bc6772cbd7ea00cc37d9f84591bfd954df65ffda9e994a0d8d38872349c5010695f57cbf2453e281361a8fd9f73f9d4e74658bf745f59e49e84032dba9e5559fb1b339abea76c8a6bcac6fd9acce395b67edd2f0ca73c88ec7c66c55379cadf8aa6eb692fc16b38257ad37e7c5eb17af271899c7d6bc99d7cd4a5e24e088c581d718b836d735d8844f017e1f1e5220f8e7e0de1b38ac140cb55b566542abbc06306f51f969483e0d8906efbf318a208591e3841ed93b51056f47da5d3b049a5b798eda8da5d497d6dc638251db138dbf516e41b7ee08d5a568b72c049bebea267ffaa3c4e659b6111cabd6a25409e57d40f65a66927a25c632d32969ed164861c3dba6582c78c332ed6cd2b00108a7a2808849e4b086895125d1525c16666f92838acd5412aa29e45f9e6fa0c0db35dfaafae9820d04e72c2b450df9d7247d95024e94774a63388b25340a33a8469bfa5677900d95078daac560972dbc9e55dd6a5917ebd6b1bc06d993417a24f918d4e4ddb9cbf5de79afa337c3de6a91bed561d8092389f0fb129e308b83e06d749ee8ea9daa9843ab9b92afac5ec31e64e9f356de8b98c81351aec0e943896fabbeadfec1b79197381987b2631d122725411a357c5d37ad29641f5dd41b3e2ff9ac1da9550483da75ae1b7ec3ab166ad208c9a5ef5cb162ec15eb13f14c24fcfcbca9ffc52b9f614d87c5fbde5d200e1a26cbf32e956c93a757584b8ec88a051fb6d06818f04b763df2bb96fe756ff8bfcf2ddb1f5d7e79990993f6a66ec4a0a0397042e6d7f96cb3ccd48d5783538a58e9b624f97784076ff84212b586accb5d562a6f99b39ce3aeb57efcc8061d9f8fd95ba21e75560eee00416222edca593995f92277a5c83fd095c911b5df7b30a821bef90700eea33086cd1948051c14f90737e0201ac1af3b6285601fbef8e805d8c96f7e0445a5b24e9ccb17a84b31391e33728860ee58d57931470d2b38000fd9ac5e6f59d1caf72b03bde8acae669ba6e1558bada55c0b7a55c82e71f4a73f049101dee15d5d8975c3b37cd075c61f3fca433edce99614c15bc73b29e48310785ed7b7c5bb81826ac863d9c25baaefc78f6a949194198734779cc67d53dad424a6477b279888d43046a31a65ebd4645116262c9c1dcb0c8203f454311bb439adf201e052a7ae799989ef941faf501ebd719264bf8d703da65b4892d26dfb9124dd9c2c28458c4ab38ae3ae254a4ad4f1d9a54466cc2f4386ec709f4383ec28fb10a0aa6e8bf93676c277a53efd81ee5a7d4d9f881a3084bc03363fa7408c7e941e8675100fd334462ccce54add23e3d6fefdc97f5c9dfff0ddd9f3d3abf3b3fffb941db3a3c78f1f3f866ca8e79c333e5a8c6259f82517f1b380ff8da1b29e18fffb1ffea4753640ad036dcde788e23b24e84850b333c6e53d04683a69a73390946fc1cff63be815095b55ea393241c26643a600a858ee534e8289c61d48a409697c5ea351441ffa57d92b251fdc7d1d26ee1107ea5e913fda3213a4ecd99e6b89a842626fc9af211dc670255cb68b26c245935d61ed7b238e0f5b11c398dde1f409c4510a654c72d6853714dcd120eb1e3e8ee331ab362bde1433a523dc7baf2e56eede75b7d07a67619024485051695f5806f4630054293b08d11043a6cbf7eac3af6f5d0d9b83cbd67740592de9fa61f8d066e93af8c0f0de58ea37b523d79b0b057c29947a13790159b878bb19dc86014f96e77f2bf29c5790c11d123d58ede610df04c8f7e0bee9a1504c7bd967894eb44a08c3c0ca50d8a39c4a7e887bf96806841db3ac2ceb5bf0e841d149201f12568393ab408ee8a7a25de2b93f1e4ab6c099d0ebe48fae1ff974d6182ad9abb7baf398d8311b7ff515fbcbaccc84605f8d599c55343fdee5cc3d1f876521461ac1e0ff4f83cfcaaee4b82b9a8ffa30e3b546a0499989f61f557d5b7da7834f1e878d54c6568949e012654dfdbb6ed0613898deb36321adf8ed3f87ac2ef37f92781add927cc59b0e9e016f47a37792bc5043a8fe4b27ecad5fbfcef5fc4f4cc7c9bae31bb433529facd994e8d22eb177310831648e75f72e7b11e166fcfa413b76232ff80dbdd941c5397fe902a2a39c21d3fb149fb1519b559c6e32942619b51184aa31b9d248aeecfdd7a34c29ce6afa04e8ea53f05a780f4cf035786a12e3449817bdaa41d406855a8f09211d514390dcf344f24c40a32fef451ba9741f8fa31fb33ce7f984d22f2d11a69b3faf3755ebf641bc8c7641ed7d3e616fdf757d57833ef69b7cdacd4a059a0d44270de1cfc12757e0ea722431c4b997752084dd672c52a41759f1dbef62cc0065bd75132ff90c5892cdb73f47280e7ab051273b7499067ee61d7bbd69593d678de40154911ebb9cc012a4d4a5660f1d10d21bb0ab93d7d41920411d9f0602813bce37de2871cb73c56fcf5abed2ce4fc816d9411e7983048a4b57c582ca9464f778fc2883ba5bb80c0c2325aeb7e3317b55eba4814559327ec39beded92377c1416140240fb4c9eb30460f8f46c1dd731e6ed181ddd6c76e81dfba31886ec7f21d08b3a7527ea32d7b3e7bc6cb35844a16e027722c69cf5bd0cefd8f744ffcff807f9e2815794e392840e1c9b86437a6327d908d612b9cd84d2298659b5a3cce3c363dcdde7d015f7d81c20aa7c90683a06da4d5024143caec04e1fa96c09ae3d6773101728a4c449c34fa420c1f38121ad21d528f72017b0e48e44ef4cbf9501e36df3d7c0e76f5822259cee1d598037448c9ceadedf67ed72b4ca3e48494bedefa14ac819ec29eea41e0c4d8ec92c0f2a7be6fc437c994e0f8719fdf891f91f834413e19c2140bbdb5320e0df8b6ae0609bbb8bc31036964c771e39a1e6a7dfff70f19f57276fde9cfc67309a6f64960817534ac15b1658cf9489121993df8ae3c33bba9be7a260ede01135a0767068ac87694e71412978b3001d942591ae3be8410e52358785a7df2bf71d87bfd26bf4983db34decf6fdc4134448be7284eac1cd90d11a889f4214ede9f49d40335ceb0b49e5235b78444118000b561abc9303c5c7d3a1b1041dd06921176dde2cf330550fb495db0d6bfde4536b7418272c012cf8ac6a6b9494bb5f95007a14450ee0c0906575c0001f22af75214668bf83ed9f2bb31fceafc78894c38d2812d4da9da6777d6c3d807cd6939b2529a286cd9f7d3b5bda2032b8cadc57f650ad58c56a5d6543ebb3f0365cea3bb2d61d2c64d2ddd37be6053d327c3c1fd22943b2e46ae9c8bf62344a8dff5827c38eb699d5d52c6b071661120bf456d69591200e9cfd118a60f7f36551e63fc2658f6154c56fffa9522a94585b24824e38dcf95ab28107441b7aff3e2bc4f97a7b8ac1af91fcd7d8931dbbee10f07e8652a07e39552779a1f5c43ec89e7d91871469e05d1f520dba890562744d0aae13f3b7e011f57f98b869ba98764c06577b01a1455bf47e2d04ab2bd6148b253ad63088bf069fd881fc6755b72c9bd637fc7028db429fdb0cfd97368b5292ed06bdf3f3a65eb3a21db2e9a665458baecade0ad00d3aabb6acd9546db1e2acbee1cd926790132ce737bcacd72be5f8c42198a2deb4ccbc6e82b7f2592cb9104cacb710f12d4ce8b44fb00cd2ddbfcffa3e963e24c57afb06543268e5888714296665a84c5213a2cf012db71f59e4ab7b90c1f3d1dfee21643b3de711640d63ee555f1e10a7155de86791167c3863540598afa16635ff7f4451be086b3ed17fe9e2c811c4bb197cf5af2e2d2d55ecc2df55e3bbd0a9ff136eaea4747535af9bd5c4f81929e2c69bd1aafe575196d9a86e16635e3dfaf17c9cd73331fe894fc77fcf6eb27388161bbfe173def06ac6c77f851c0a572a486d0c3767ac6c15ff83e985625a3ac9065a75b5f5d17861590707ea8a65e4e5495f6b920483091d8f170c656e5400427df2bfd14064fd11c8ea63524696affa268475370991cf93b4b1824a31cae3f1716c9c86afcb6ce600ab43e2e8bda7884b018911d3326828f8d985e9241ff2cf57ec795dddf0a655bc0dcaa53a6157c60662092e0987ece7ec26c3484eab701d91715e82e371cef99acdcaba8284360cb3c0d47f3fb70dc7faaff2e7be60f66b370de920af5f750c331eb31f0566f5902d47e8a854ccb7a9b920e9561c6c64b7ff1f7befdeddc66d340e7f1558cd639131455a4ae2a65214d7969dc6ad65fbf8f2a4bf23e9c8201724375a2ed8c552329fd8dffd3d98c16580c59294aca449dffa8f44c4e23a180c660673b1e32974aaca24e3451dfbca068a6962f10e5e1d1017bbc8877da11ef4b37e4dcc4fbf642a2f47423751820c45872845d5dabffe13dc80819945673845f7eab171c84b5684f64b6b5d6eaca04c74221f59c8ceaa47bad50cf3189c82796d396d3d4426a19b11d76cb2988b3213e56889517190d8da07bf049a20beefaf94e5530c92d74f4516256110acbdeb04c162f4e5e83c673b6caf3d20164b6971561f73126e28984ccac9201d77886073b46cd61e63680d8549a8cf597bd4a14d3aebb5ab1a526fd49bf5b39ae845ed57e3d34addd08d29f575a73c5fa8e90aca068fa09ba0f8b5e2bce97fb9c1ef5bc5ed14441217d7fd1e0e9fd41c36eaa7a026e7d7bbbcdd6b0965874293a11db6db63f7bb3db6db3db99fb44e9ee6e3fa9a3c437b6f8b725d7fff017b7fff16f6ba1297a25262f5f56f2a690ec084a464b3450d91c2f292018fc686622c2b618606676ad015a94511ab70aea6f9680a8ed88ae5351bca7aca38dbf621ea303a0c67db30882ee8475d2809513dc42544f018577286b7a4999c6efef342d5e8ed9deb029689ea32af93aed9377f06b111fbae7855fa27f7f7329448fa067e9dee7b5474e9ab1c157f9ee77090c4a4c48d3e0c0347fbaa2524c9ae84726a3504bd5ebf09578171e421520624962821b0c97c09a1471213852974d60e8ea35bbcb86b5763d7d00850d3508b007f7b98e64d090a433d3bacd1f54359cf1fade45d25abe0f04370d74afc1087a5045caaea5bc5ec89148af109cf4b5533cdb04da4ccd8bce2a33a1f09d567cf45bd8d39ce8d76a88904777e731cd560b81504b51dfdf6d889239ba1f5aefeda78a907b90652a21e6c7f8d6df1fabbc0bb1f626647fa0ce869be4f07963034b60e89dfb39ddd946b0bb965635fc408128d783e1be4bf6f0b4363d3be5e0f1c26ee4e4b843f6bf0d2b80c5bc2af403acdb57694d1fae27d20db808f91671b0431491d546bccf8a8aec56c5e23d1e599bed0eca1d4cbeb8079a37dead3640004c85c3189569043b9283365ea3540816dfaec5521b44482f18ecca7715ea9ba6fad29a11f3d90a6649e560c850bb73b5cb26339fce7ca93d69a45acd5592d7a2abcd191712faf7efd2d465adfb17598321858d2a2c10c8df2126d4d1bdbba81899945ba2696403423f368679dcc2c4e25ed5e6243217d325a507da5ad10cf662da6426cd3e74b461e2f9c43516bcdb54f132cf9e099aa993009621b9805b1b4a16e3cb637f0b125ebcf3669ab2111b8b3446fdf491430b6976867833de9cbdf364a628269d3baf9049348bfc9a5eb39a71ff4573ce2af864ad3ee223492dce004f24c4b09a5b8021928aeb0427f70bfc74eec845765a86ef5d90ca86af3f25c6997fe0c9618f4d06311fdd694bbe0d5047495bcc4cf21445aec344e9dffe4892d83106d235e93537aba0536d941c9382f6a51854598cc2128334c4550f6b3cccba0a0e0aa7e96a838e3f3e07725b245f056698b5ee79369386115bd6a9e6e29390b0b6af9c6787d0785cfe58817c27ed25fce12692af45f2f429ffbd80bdb56395be588b19928bf9ec3f046472b99bc14735a093257c39f56e8e9d9e44ef181cc3f8f35b26d355c1fd11ff7998b92f7cac5d16d3801866d4fb77aab1feb7016249268ecf48b39159b21954cbe1dfb1d9ef0573b5d424db33b51f00763b9167a811ef3f931af2ec057f11704da60804a06a1312463c77cfe10824340843b1f1c42d57d1221a214aa9ef26aa106bb5f0dbfcefefcf5784f8cbfe67be3afbffae6cfd930fb6a3cdafb6ab42bbef9da0cf17851ef6f186a62f79b6f1e24677e737fd5633eb7debe4f78cd633febc40ba5f7e90c9e2689ab6726c4dce6a14ff8ae6de6a57dcce7ab7cb459c2c5d4fed97c8e37fdebff353e9e9c737dde1398d0ece7dc8668f381ac6b39ebf831346d87386e9d6eca8be204e362f62d217bcb2767b0ee634d371bccaaf1a0d21b7c274ec59a92e9e26b096ea5199fb34afc6b916b62a3bb9acb62096e3b63139cd646921a56f24a89aacf8e403e18f2a128765c6d59b191acc4cecf6a20d483c18ccffb3fab955200822ce3d67c384aeae2ab4cb942245e5169262a88c1e55035e1ed1dec21b127d20304243d95b2c86b9f61ca89a4d3093ba6709cf5c3acf45501f675753a8c958ec7e78d29339f6ba65a5aad870177339fb29b03544fb364b5cce4be7db7c750c6e0318e095bf272c25af86ff3e0f8d4cca463a714864c40e13a5c4d8f55d6d0e5a9234ed191034ae1deadff2196087bfdeda1be9530455b8bc5ae05884b9166e7d9ac2fcbc7622467e25d29edad6e2bf7429621b4d9b743d0ccfe9bb89e0294a2b0b3ebf150893ac6c3740018bd2953aefe2102e44863c5afeda08212a799cd43227a322d87f22c6b1142a9f5dc1a1bdacb56035ab4ecba100d93bd9b3b9f348e37b342d91af9b27161224cdab478e708273c39a9b4c68d3ed3520f76c6b3ec1a3da596ba1e3df1107c2ea5fc6df0f1740b677b63e4bb7dc46a46ba6d463d0a8e729b9b31b18f5d6110cbae6914db80f90686b1acdd3876e3add8683b58602c4f6e7b7b19f6db69045bb59d8d6db0ff12f6abec368d28d9e7d9b1626c9a0bb18455358c5901fa247dd3ca3c17fadf79c827afb4818dda201dfb112e4ab8519106e1d59d6cd888047f9ed8d1644b12d35d69f902c97087b8d3ad9828744f6ff20dcf768be52dbb96f5edaf873ca115aefdf719af406b2f82e6966fceb65c8fa56de36891bfa228b0eacadb7845cd204396af6c7bdd08d0781d1613653341e47925e6bc126e256eb4a6f53655315381e3dd8ba31f1fbdf8dbd327ff3157c6c6ef171b5e1904de1bde149ffbd4f19f79a9b410e034ceb23f2a01bd0ee5b09cf7b5c8c6e7c7bd705775a473d9f4d26f10af9440ef1f8f421776fb7b9d20dfca05d01bd989ef7e3acd0669d289f1d8d8606004b4997176bc146c28840de2ddc8a9bc9a7169863b64d764903eb5b9a6ada5c0ff062f364b713f47525f4933d7d3cb3f8af3d81afaf807f3d26aa36893a616aa2d2ea19354dbb8cf381c422725ba819a6cb3700a294e7f13c5c52d86906c0d8550af0b229962bdd747940c97a2e9cfda70733195da20e61c6e09be805c633a97cd701489db4e89629cbaec50b7fc015fa41bc180f457b35c13b3acb26f3638cfe46a66fc423cab45a5e7da8ca1a8475b61521df5e5e7f61dcca4c5f7d5fe7bc87ec1fddc87155b045727ae9f7bf7ceba3d96c952ece3cd9866131990c05f4c457d1f91ad4862d3a7eb6c9a169ef2ffc05d431129b9652d2dc884d9216bec5552994066ddda27b32ae37d76023c05c5876e3adea5fd47b0a3ad5a1319589bc46167fa2be1d209c67f31f1adcd2b695e63fec7ee4a7b0c4a7d0c465e8bf4184b916088112f8a211f5da4f29433ab8038dfedb1f361c4352f9b9be9bd4d46907807691d32623d769ee9c2515fe34ba77bc0ee9c677d0de383e8cb0a13bf73507d9d43689cf3ccc8a56cafdb33f8782e20a7bd7d7b381727bb6994b4cb3601e871e9a6217486f0b88ee1d78883b79e38df3ddf053381f35d76a8ff8f7975a19c7d8a1ef693b9715ae1cbcc913d87d00e167efaefcef910418838d2edb2f321aeed7cb481bdae9b06aa90f4024c52edf3dd3e26d66e59b9c7bac1975fb263514d04e3a58454b1260b6c5ed626bb2016f4984dbc0f984cbc3bdb10175ec4c3c8937a80ebbea350439a633e379d24d00da77f88ff8f7d801b00dc588034b9130b9e97c6c8c7cc20b5cf1351939a90f80e6b270cbe90df0cdf61bd8ca85b699a7ad67c8865d460112f1f7d122abe5c3535044b731ae7c3359786210b787c87c1c11d850777d476701949ec1fae33c13ebaed5ab1ea5c3d7df3602536d8adc365931cb1c0e61ef379ab05ae49287184e92372973516ddbcc08449189ff1bc9c8a2aaff1cb319f9b30bf8d31fb9842460bf0f34ad4752eaa9d7c52ca2a79f5b5ed94a773ed7863e099025e837e3868e2c9b9632259426a7557d21e387225ac667c8e50f10059a93bb8d94b2dc47958c7dfb552978d49804bd7b4fe7d096fdebdc6cdebc76cb92158fb4d7c4eb9cacfbe91e94ccd31367772ebd1654e2fb4ea55c9edecc64c9bbb7cf7ece5bb175ebe7b89cbd701abed12b6ff56829addd2a5bc727d2c7149eff94b7a2f7949b7f6189be35c8789b406516b5331dcce81190cd8a4e243703eaca798cd182926af8426814a9435e4079f0a50c86a72315cd4e0cb137d767924f93c310c2f33e38daf2bcfbc2b2e64b7afa7a264c887909112dda07f605e1426be1ba67397a5c244cbd2a958593a60a2b11efb070a8413511ff3f9f3fc42000790b29466deb5e61f0d29f2bc558cb4cd66b9527939314d4d277db4a0a72c06b928ccf49c53de45178c5c77769397051920c5ba342e204b18d257cf3931914c41e39a9781e6adfa782db984662d98df63a75b2aff3f71ba1599d1449e7fadd64b9ba9985852cda4070ed71948c402326fe929a3c01a7c1cc9729c4f16e4b383449772efaecd97ecb561d0399b6b1ed472f226948b3956c61776c6e7349acc0b975b3c38b243919713f7dc918b8cb67906016b2a01673a5bcc0b78c22927d8948f6b51e9555c8aaa364ecb33708c85de548f0dc5945fe67251b15c019b518b6aa6390d32c85a21a396af5efefde53a16409c7fd5b891bd7fc32f9ffe9384e4c180fd2458910bc687725133cc2707bd688829962d203f7ec2a4ff381f5552c9713d78bb9c0b13c5cddaf67ffbe0abb4e2459d183b70986898c3ee2114ee375fccd209ebd866b2fa57965df82a6417befae3c8ea5f7936e0abd5b23a4b47c7fdb4960898b05fac94653345ba713487a053abc881260546f93dcb27f594a95adf9243419f27d7040ebbde79fefb9b0db469d6103f54f7ace78330d6d8aa016e106c4c53a06ba9f4ac7bc58d25171b949a3c4ec70877ba75f20b085ff187166d75ea2444a1de43c1336dcd6e24e0cee916fc1f2f7eab1006e62039d0cf322f3bfa8e3eddeaa6d6c23e9d51578e36e437b7b3a28aab3e7b5be59389a89473288114938a6df32cdbeeb16d7c1fc7a02fdbc8c86cd3d3f046885f210826febf1105f34b98a5d574b24cd43c2fd4354ed0e7a400dbf00d96ddbddbd092b9fce7710c48c820a3b91b76ba65226a88f72c9302e2e6abc55cb355f1bc0e41818fc1ea8679899e7fe0cd31e373d5c800731b89b04228fe5689dd1a21448ff91c3eba90a1832fd9f625afb6d938ff201453335e143bc3455e640cae668312b1eb243a2c6de62a09de5dbd7012dd03ef8ef8c5eec169c3adef8d16724287c446859bfbfdbd11f5efd3efef8da837f2fb5be3d2f7c56ee8d4e7a0d9a81c78a8bd093c6d7c15deeef3770d2fbf37a26ef7f2d3db79732f3f256aefe5a7bbba1d2f3f25ea8dbcfc6e21d16790dd93858968c1dfaf4582b4418392ae81ace13b1f12a537a2fe4fb1ef0897f27bd5dc36df4cfd9837d5dca232c014ddb206d7c983d7d6e1ae7879696cf2cac21b3da13ac0fd31b5b86b9f5a5b7bbc9e16373c34ab4c017e28571b03349f24fe3d7a8e8d10d62f2afdd46ffe77e3c7feebbc37fc4e15086bdf1192b6ddab35a701b67db6e674b32066ff06ad69dbf1e259b6f656bd25a3f666acaddfd265f4f69c95d75037f699eec883017bfbf2c9cb7d966742637f2f7650c69f5710e67c28c0f80b32fff49892a8c032caab112fd9b0315d48ec86ef3ac3a587a4acfaec8de6dff97c5ee4021507f824ae59578ec156189fe7dbaadf4a6d60e1ce7c18912975586ee0be08e784675927ceb88774d133792bfd04d7260169d9d13fa6a7553bd2b34dddacd6203ffb1db943adf72cfa23ba29b16b588ac4a253c3a7ffdae4fd8fe3d5effd016f994a6feadbbf92e2fd31e9c76d3bf7ffee49c8753d866ecd397fa37b89a5fddd5ba4daff7abcb38dc8641c212a452337e5eed321ab9aae4e864e5c63961b3a76dc9af34610bc376ee0f43aa9c5df8abf07a8f6cd3adc9a9207c2aff8de21db4d56b1110b537186db881671f83901e7110cdada0b63b89efd3b3c7e42c458e7354651d2eedb35ba5fef05b6e9d9f83cbf2319ba2fa7b032d239fe6ab899f0208b67774d6fb28036c47dfdfb5dcc428c48d9557eb697c31b51ff5bbc1c92ae04ab6e6a50e2b7dccd2b8dd81be6835a96bd91e93a3802ac04d8ef6aba9b59daa717d16a6baf44bddad6be31a71b1adf87b8ff39860646b1c3b6a36adb46510327f5216df107304d50a2fe754c1342b8ff56a6096de35fc3444b1fccf5265a71f7eb8da3e83dee62739c20fe47376137b22dd295cec82bf7da099d74cef917bbb7e0fcb982e1685881bc11756805129b77a071c566e61df0acdf0b7bf7e61dbe189f071ae1b66f68c191eaad53f36a226acb38e2c37acf663eb2b61989876ccb7905d6198e1df36179134fff38a4be77e18fa6f184eb26919263ad29473f9a3b98990425cd262448b39e39986b84d199035bb7267ea6401b30253cbb463861230284612a569e8f35e35f5579337ce6ca3041b9c1601b5b2cb155e92064d1dc1b6c156991bb53c28e4c06d4d4745823f8d38aa04f89641d9fa26bce51eb7f9726716584b1666a77f6f1a303d5af1304e7a6cac746b30df3a1043bf239a1e90603ab4e54f325bb6b5369572adedacf8c5fb7b99af39a5ad47f77fcba0d318cfd37a2dd7f23dafd1a11edd6dc5b9b85c79f81612da2b32833eb85f7f1a379faa085843569ea7f6c84d0d9fac0a0e97b27197d9db506d086313fe4aad6f3ba7367edfdc990e4bd924ae5e03832aff359fe7f00b57df6446a190942d071a634f9e4b571fb9615f89cc058d61fac7126070370f854b5ac8ceba6f1f7b4de267c0e5442f0acc7160af236323517a39c17d6a7a9962c13a5ac053bddd232b11d1193ecd0d15645f34798dc5e14ff0610673476bf4807ee4fec2826bee51926b21caa519587160c9f83eb3ccb7cdd57959c07983fafe4fc0590141f1951b473e7eb4daf53acf24133fba5e7d55bb840ae94a86a6bba7444ac7d9c6861e7fedb9bd7a4af3a33af7656ca017b1517d76ebdf07be7b8ae1980536c7ef8dc4e274f1ea56ffaf4799c6e8bbfb92ef666a48ca65138ad15511eb0f9697bbb18517b6ca26f505e8bf0442276fb5526968737aaedf95196e52065378fef67c9733ccbacc494a4147aec9757a0f5831cc4a2122c5740cced67968951c12b91399d1ed98e39d8c825aedab5e4c034b5127af0531fbd8d316843ccd1a81b088f1d3bf926b509200394d12c47b3bf2a49c22260fa9d8fcf611ab15a9a7bfca2bbd88e5d37c0104c2cbc4134cd80eb581355b3c130ad4587df31916f134b2c7d4708361997dba1ddd19b50c26e596991e331af47d35bb2c0b9a6682a0bc28f6ca2dd61cddcb4611f77ef8605093e99a1a0b9aa913eff2bb22e78958016bb789901b32b6aa7d84f24e7241ac0b5562e140cab62ef38c32b227dacf273a1c9094893d54929dae511fbcfa52be8b4b0c20dd97a3020e15b8064c535dc6777e6212cda6fa5e0b007f39a0a8e15048185ea0df3d77f53ba24a7fa47543db0555e23a2cc5264f67364b9bc28c484178f467a55a12942c448448fb0c4779e81ebf9db69aed894cfe7a2541a6edc3370b9621c061019389e2c26537b64711a1afe79d903a93e60fdaeb88a86b1cc20cbf24a8cea62c9b862f2aaf46d641976de0f7b88fa7bda9ff4f7a3327cb07a146dc097d189f9d2244ff5b0ee3ca22e30bfb00ffb6c378e5a108f0f633dc6ae3619d326da2fe4444b3eec71a7dbffb07a88673546c941bfc9aba900b38100ce6a6add2074ff79263484b755cdeb7cb4cd6465a315d2003b067e39f4b65082bda7737bd4ffd07d1fd595d5bede3fa9f9c9ce23032122dfad01d54f53511a758eeda517a14b5e148c17571ce20fb14a386c6941123eaa17bc702ae570c001fd69d776c5abb273ba651967b60d92813d25202c6c333936e570884ce115dfec18f4d93b25d8b65de2b65565a1ca0ad6e356adb706fb6479cd70bf8076d8fef37a5be12cfe1b0383b5c4c058432253b62a3e88f2ef352886de27dd92e5a4a9437f704a8ae3fa5cd700c502e1b3c4bfdfde2265cd84d27a916b3d495f273bc935929efce6894c084bea39e8ff6637f9836737619bcb7c3793f756cb7a5ece6b26116a5ae0ac95766f70c227a2fec71a636f1fd081b7dbe0ac36d3861718a057afc5b8d017a9bc2a21a62711ccbb9a31e1e5321e1b830b9e8492ea1aa7fb61ec746fc7e81987fc21f1bd1f59dffbe0cbaa1883198931384ac418ccc21883595b8c41679245ad6a229d7eab92a012aa3f5fa8694b6eca565cfa2d43f58fd07b7f44bcf73902d97bef73e3bd3fbc81f7fee6a1fad9baf07f0ddbc1d4c9098d09dd91e12a6ee65e27d659e6ad8b9874ba4556a42b370ce582762933ba64b426dd95517f072ff72faf4a7bdf9b9811662160b619ea98adf51b6a93a082c7f39bb17b9ed53393cbd553100773ff36d9d5dc9e31df9ef10b940032a1af2b5e8bcc4666f43cdd81160872c5f06ddbf646193cd00587d909cc58c182cdae986f8dc8f49a3ba006a3d89335976d86bb0a4687d84889c19a1db677a48913cf668dc7c19536a4ceb4a2173eea94f82418a3ae1b8c67d98f799609c097104d7a7a16ddf868f16c86e7e7d418e2cae09dce3fe32808e905db8f96b91dcd007903de11797fd9ac953ba99b3d11fae3692344b64ef5c4363a631f3fd2eddba8c961937636436f34f8c895a13bd846a1455868bc6a0e2f98bcb6bce6b1460411fd4f85235db60c45c700b356f21878b9d6c9a2ebd1866c6484cf3fc88abecbc1e31d2aeec89cfc01812f31cd8283a851b7e165311418d0dca21e888f0a43365bbd8a049d4a1df2fd1014dd47657316baf8e8ad29924f3fe97d5132b614a1a5abfb64add4cdda52326a726d9f569dc6c6f958f5c4d93c1d2d07b2fd6cac6fb0f664507b50db1d7d055e796ae059e5f38ecd660888ae13bfd6b1bace1c3eebd8c56e132d2e0e9bf951a41a878e15a91a11216fce46afb39c44ac95ae463e360ff63377b02ac5aa45c90afe7f79b164575351a2dbdf3c2f20eebac4188a101207d80eb540ede312c840b528fbfdfe9a338bb3489dd975d0c5a6e65027bc1a1a8eea9f4ecb885c9a7096e5a4e7945f11b44c884aa86442904bc3c368e61dcbadd75dc22c812e02bd1f9360679169c7a609726eae41b4ff4eb79e394e706e0d326ba9c1635cb9792d670add00b95e412328260b6e4eb7257dddb05d804ff9a6b6c226d1fde63d9b70dee99ee1fe2b976f71837184a4cec26dcde1daadb1f789e9d6a77a48db1950eb04dfc66578f598f9f123f94e12ffbb1a698b0e6295f6ab221228ff411fe49f3d0062f8c2914961058e5cb9242c64f5333e372d27a27e22868b89a6cb968841272b508f0837ad98f17ba06e012eddbdcbee0464aca14c808fb6fe19580bbe1182fd69f7fe9ff75621fd2a22ef30c321ce0a2cbe267ae892427025d0a47abc244fbda9dd4b795f791242ec747e27485e4a3add79f3a18f60fc582ecacc3e26361325fcbab88e08e1afb82e9a07864686f4cb6b939968332adc626360ff707ee9890bb435ca334e399c873d18e95c5059aee65289ca718637be389a6cc375d1dee85fe4b0e67909b726f19d2784608dd4b68621417211e0b871df7ffa612e46e016a1e4cc2259acd2d980c168e3e63b6d1c5338c267e15c4a9716605bfbdd8e1d26f989b5bdfe7af7c2fa3bc13cb6a4af8055e8fbd9181aca2a9be16a44aa92680a0f977c26b2eb621e34c22c6749443b685097769927c2866be3099d4be27c867359bb08f4b9b9e4459ec19b0c32d28c2b76258a22223dd043df39857fb2fef4247e41434f6dbf85222168baffb5e04587f7d8b0c732310f3279a3f67c5e4f1b3a7328c3146ed1ecc4bf82ce3c9a0c06ec48ce7391212a25b240fdccd5f442945c0df4fe576a242b3118167238f866b4f7d59ff99f470fbedd1b0f1f7c3bcebef9eacfdfeeddff6a7c7f38dedbcb4662f7c1ded7df7ef33569d8ff59fde9f9eeeeb70f769eefee7dfb17330378f52f79c12a315a542abf440515af72a571dc0246efc1fb5c016cdef7039885ebeb31fea606538e21fc9f004f8f9689126c6aac8d045000a17bedb3f7f7310ddefdf7ce740d2844b95db3dc36ec93de345fa73985931f793593e592bd17135ebc07fc978a17671d0dd3fdc1e02abfc8fb6234e30aac60c0462693178bfe7c3a7f986787536cbfaf9b77fb74b3394c6998a2311c0ee67d7d3c76d980614dfdd79092c9f75ace7dcf34f8dc197e8fa90c61d99a3ce63504a0eaa8baca4735817f732e18ace6e34736b43f52530b63cde959bce02fde3b60e797bc1065dd33791ecb9d4a8c0bf121bf14d1787a813c35c0103e050b7dfa61ca17aa66f32a9fe535e0d1548c2e142572609575c80c8bc30f62c54123ab05a80cfc874093809de899902f1b41e308002cd8fb9393a3822b7576f61e68888f200c4f04fad30b7c41b1d402dfb3787819f98a604b14541d262fd37046ea2a87e754d74f53c5f4c666ea2b17b3a1a8c04572b228c08d745e09a57259aa1ecb782d540f2cc78652168297b8e78851185a192484400c1b69e1e374ebc470d9afc5e4e987f9d9e9d67e3409fc607b14d54864248b201a8a79d2d179216bb1cfb6b7d93d36e0831c8ec7b6fe6bbbbb62745c693cba99c12b8b5b0ad6584f450e49482aa1e6124c29aca87055f1f95c732621ca1fb07aba503df6fe74eb9bd3adf72c6f38050c06a4ba5ede7b889e03b3ea40abeefb7e0bd36c326d71c3b6c38f30d07fb4d817b09b2d8bbdf699256dcdd5fe82bfe8b25c452b7ac15f34da683cbe8707fe1e5f25dddec3a37faf99996330608f4a4b820922e48acd45359695bee67df86e50a5e7231bf6b005a4f71098f7d94320adf7089565fbf6e7bd95407ec26b118338aaf2180f4bcb461c01aee3e10acf562ddd323cd9330b82719bc70f703631c82c2f8a5c89912c339f211443d6f74912c0bc449e08278369b8da5b26c69163442c981828971c6eacd983d550c6584c2908ba0c792679113a8c2341775722d27413d00920f8726c892d8c9efa348cecc5a2291df306158b272dea963d3fe673dceb37c230298b12690ad03cc38eca31eaef76e63cd7449967408378c9f272042c0b2f58212e45913aa43fe6193ad330f1a1ae3856c4e8f7a34a706552b5225f953cb1c8767e7f084c68ead042857bf7d65bc50c2bc12f9a4f0283017b07eb66bc5c320b0067df6a6a717668c043afc6a12f1d46f60515aaf6153ba4b72c6084dd1aa840a383e1c3aa6d99cab064b88a90210073cbf5ac025b1558db115473e2b27c0c56d43523e61b2a71a2905abfc7c6ef15708130fff72aea1f2400dfefb8d2ec88ee31d87700de512d2b76c838b51de9b1a1291ed2e2861e151b03ef067f351577771c1cb1c3264396c233ac4c2cd0784bf7cc58cdeaedb8ce00c3780028e8266a774eb708044eb79896dc519c6f940f5728ed56c457ff941607e343980efcdc10c9b183ef1acd894c993a978f945acc8cec941b1bf4d17254e423868b5c54fa167a3b158c171359e5f574069532511bb51756277dfa86e06494f1796da5d3a76fd837fd5da6040a7dbbdff477f7fa5ff5181f6a397f543339174631f2feef2fdff7539a22cc60cd471790ecb6e297a2520972a29bd4dbcaa710612a2f47825d09949b4a011e1f6266ecee8d205966962c7be6c393281046f5b1c13f3e7ea4e6a043fb7598faaa4f1d06ce75ed4d205d57e56a9a178275b07467a7c9c03fcf4b01818679359af6d92b6488c08c2357fa56d7a0302e05b2d26044d11072e50397c8e438ea7351e6ff5a08560aa577896c7ae3d4c39c4f70766780ab4d1ecf4a76cdbac334fe6599f58a50b54b708e33de60930d1cc1fa945e1aa498dc1a207d18fd44b1b40c5562ef4301b6e5b6202220b432bbabd025c8e43e47a73b4ca41c30b3a51809a578b50ce0ec1124c60d3b1b530388afa973ad2be8899f0aaa3d46b2ac4559ab1ecb27a5044597160c3c470a5ac03c4288d5a86a277b47fcabc32d16f4d8d0ff89646987ed36343d37cc561152c478a38255c748c4c200f246c90771e379d3e1032dab51697790dc3bdd32b57d83017b5a1aad35afd950d653877b7a17b8799b559a8f71c795ec001b8ab1749200badc89b923de8d134b5732ecf609ea5c1771d66f770c64c1475336137a1171558420c49d37f8907e5bec4cb9fa62b733046b767d498392109cc5352ee1ff5720d2e76212900b8883d1a05070995d9346c979a749a182c2381144f80ce078e3a6615168eac293da22de57453e129df8d9e8e99b07c7d86d42779fee8a44e4e5367743a7f11e65e278373bc6d29b746c9792800ee20a37b8121b066e64606e1a278c9682c8fa2e5030d907537412c5123ec3078937a218c76bb055d2ef3dba45a7b90c17d01ba637002f51cd9a0143a3853da3630771709ca34991b1fb506cae49cf548277856ef9535e4fe5a26679cd2a59148b39c4ea7686ecc34599c1d3db98e705e335086f739997684492cfc4013ed399f68a2de6e6a4149af543627655c972c26495211dc86bf40746235627b8a3cf87621d3d7bf181cfe68570a6ae6a311746912a40fa29e488170cecf38785b16e190a3dd5a9cc351b831a6fbd3e0a0a4d74617055ebffa25b3c583c6af98ad7ac10dc5ac8d84657c20065627c782b016b81b5e533cd651971aeae725e000f016b618bb2ce0b03c8bcc8985a8c4642648af109cf91a5fc7280db88debe5fb2cea8cb8ef3d15414ec27a16a78fa126ceffeee376c47ffef5b53eff8d95bf63c1f8952890c8bcc879f443192336119a8991c7e604a2eaa915077d85bb42ee3a5b15865f2525497b9b8d2e46b2aafd8b11cfe1323e7a06fcb95ac2e4c9cbf2f11249a9d67132933865912406fcbab7adf54b28f4f3391e58b193c3efd7576e59632188a919ce5e56467bc288ae54e05cfd0976287973b79b903a47c477c98171ca3b0efc8f1cecc1b5dec7cf3cd5ffef2cdde833dbef7cdd77fea7fb81c4e1ffc2bfbf3d70108dec072d9581699a8949dd861f82f68b1c3f83c1f00193a969ac48fd1937b31442988d7f988cd443d959962e2c35c2aa7836333992d0a6163dca3e1899635faae6f786cd37d3fd3383db34a353b0ac0dc49560768f5a76fb52abf44ed5b8f55e6b51ecae7a2cc44395ab2ba1242f582208eaacf8ea4d4f8bd188f574d4a9340a567f5a8401405fc36ba416544238906e14d8fe49e7b472d331bdd3157fedc00e8fbec59392a1699553fcd207da6a8142bf20bc1de73f543c1ebf77e4e8b3a2f604eefea1c445158459f6e15b8891325cd2bf0843d6ce800bdb2c6a8091b5508696de6373f81077fdc9a6feef92ce7381ca8f3b05b7bd3b36763b6948b8a89f232af64a977b9e1fb6ddb54a61f074c63b795c9ab7252f10c4e158cfd759ffd202b06c61aec0507b5f0a332ab649ef55c4808b698eb561acc7f7f7324f52e6f91d7e1c02b0e62f36808509f287d5beb0d37a4c404b91ebb03af892bd89219ab0643ce0c7947ae08a80169dec94bcd328ea6a82a050b45f7c2c486a290573ec7a75a0c559dd7e0cc009474db0fe61f795216177e99d69530328798e0fd8b410a22cec76088e9378122943f99f45d3df68b77d573c50048f709a6b426ae7e2d547d2433719c972eadacae18aa8552b5d0c30b35dfa9ef0dedd7cdecef22f8e8fadb0e3cdbb10bf4b3bfbd78f9fae9f9f1cbc7ff3c3f7ef6e2d90fffeffca747af5f3c7bf1373bd36a211a96678381be3647174c49cd45d823a3af299388278bc5af4b5e99d7d41398be9e01e68210e525fe61d778ba75667345348228449143cc915fca8535262a3140ed0c00ab09bec67ad4c4a201a19d888f23a24f8a12a0bea028ac8f0a500760a8346584a83c95508ba206b2c935736f150279b16405af2602288dd247051b3672087cea1a9426e87c8e5bf0e4e9ffbe7df9f2f99bf3bf3d7ff9f8d1f3f31f5fbefcc7f97964491f1a5504014188f5082fb3e5859c0c3484763271594b592817b063e578fdbcd4231dcbe187301f959a2ff7f57fc23cd01fea8aabfda66849ed9ff6835f81fc167406465bfbf83f0734c2daeb7bbcaad92fd64df087425e1df172248a020e11dc053df6ec89bb88c1c187fa861cf3799483a3c7ac615d8ff1a29057d006dde3c1eae8bc519aa8f80c08bb35de4b370bebd04e5e0b9ea9a765dcce1637aa42b8855465f8d063e7a2cc1e9935358cb2a05da3b4e7692e74676b91a29e8fd008834195b0a8e72c18f372e2b7016ba6be68464935078e0b7bec1c7856bb28b7618b5a568bb267351855cff9d8f59cc797e819d7a247b59cf548c42323acf61ae1a77a6c5cc82b0049cf1aa7f5022436bf2c63f7b61258644218545830e58a004d03c72ec0e4f77a9e5f68b0aac86b5fc320578fe507114cca5b87d2bfb53cac7fb79c06da79f80b66d08bd507bd8433515866078c8e110418279ca7fd5bff513ed64284b0011e7cc9bb5292327b12cdd42b773031fe5f4fd3f867a585a1d2a36a82c46af9f7373d56577c247a34db5a4f0b74151f5de8ee6db61b107f3f1d9c965bbd2d1406351643502ef55c4a255051b4fd57305d1d545a269c89c154147351a98150b341507dfbe0b434fd20d787cd61f2e49b86da5bcdc29beff34ace7780a727957e31987a2c66b25afe98ab5a564b8bbecfe5c89c9942fa94f6609767abbce2f5947d32234cb139e95e5f9ca01c80ef755e2e774c11a9843d1dc9b2161fec6234a5d8c10f2800ee8cf03b69e79cef69f7ae90543cc7e3a6d6c3d954246de7bc9ebe95afc5447c985b40f27aba53cb9d0a0a0360e6ea7f7991674f5186d3d077c0c155e4b4ef73bc638d86e595d3e06e8814ab5a935140dbf10604540b0128da41cb1e3d2b145f616a60a889d9f75f9b2c87c06e03a6f5c3ad92e6a54ccb901c9f081121771fdcb376b1d84253b0cc3623c15b9a5fd18f9ffda22f63749eb78d82b1354f5332fbb59fe56a5ef0e50b9ab2a9740a3153ebe0b4fce4f25f195c75733a2d075ffee9fcfcd5bbd74fcfcfbf1c9c9689a99d6ebd968b5a543be69c00aff51b400cf290fd0e6036ba06b0bed875e07260faf24b90e2df7abdc9a357cf4015395fd4f04a6c76854937813e8af46606d86162025e8c3a07807ea12f2b598ab2367009296e073beab1466d98293303594fedd752d6c7203cd27d88be75345d203be140f98b653875857d76ba3538ddead9b24555c445735ef19966713fb9a25c3dfdc047f53eb36318267d70ba65b856d8bb4f66f66e8eb80c30ef576e5a2e2ba9a9cd5c8ed2181a26a40ac4bb327d98886207a4615f011b75e8176aaf0bcc72a0fa665bfbb6dcce1912423a95e13007b51a67533ebae8b39f04aa96acfad0045786ebc4a8777d5f838109c8a5f015df281e881506e46e347a06788c15a0aafeeeb5c070a4df2bd793710a33ee21acd23c5705fa1bd7b68716e3a0283642e860be5053b8ec5d4750672617658d621a98168c9e1c43783f10ea46d3bcc82a51da473bcd53c233eb956033be743d814e16f44f76ddb6859ee977b8cfdf6b38c27022eb077bdb3fcfd5317ed0288ccf5af4b3890e666f7c766882b8955ecb7007f712ef0a73cabb7ecfb1a34589bbc40ee3ad8762a2eeb0eb205d98284cd184830a0ee5045c69a2f34b28057acc0bf1c3487fdd03220ada47e046e70968d8de687bfba7ebf5930517cd1a8b0713bfc0c983e7257668498c7b6d32c0c6ef4079e00c3ec93300444c7a828f1d07a4e66ee34321d9c8e41a09945b01ec819bec22050f4f93e275fd9417c5bb72d6ba34f2ddafce4ddfe25997053fcd15178d8907988e82259d9852d32bdbf0701d7b0fbdaae4659ee93bc341c4e4af261032d8ee6330fa13d06b8523904f471b49bd99be56f6dbeea24ea271dfdd41a49be0c406530bbeb8ed339bd74b8223e49b5250b1242d18c9d1b98f1f81b2f4221836e165b531e18eda8d029068e6a483938c2e70e3d3b651ec459cb93f8d466872d7995f8f93a8faa5cc845982db72ff55da5860aff151203355a38d881bd075c6c421a007ef206a6f9490455cbe0a6ef94df5b90fad90e6fbb05b80e94b9a98cc4eb7fe9f5c6826b694b58d6d6aee200b8fef3564f79d058c59daa7357c20f757193c33419e30e5efbcbc6433905443b610a5d75b630e6977ed2ca2eb9556eface0b27cbcc7022e485e4d16fa4c5933a09e2eb1d9e3d04843d7ecf6d8391ac3dc3fc0bfbe831ef0c7bd7b8472ebf627baf48c768f25f11db592e7ebf3f9bc5836c0d56327bad5597f24cb11af3b7abc6e9a277428945230983b1e59ca836bdc9914d46d37e767517bbbe90ea421458f69f94a5ae7f5c94d024617729b642c06504ccc0c4ffb1415919406c16b6d2fa8f5acccc48780ec81b999a93411f53b252a086255cdcc85e6eb6ae89b9a1762f91c30bcb5af361a4b2197defbd58c52e733c8e19d34e5fb8ecee37b34871498f6cae2bc6ed3676f2584d6e76cb450b59c31d2073c0741dc7da73932c4ebd37b17335e8ec9e780c271e5abf7dbe9ac3e39cff3b1182d4785b805b2e8fada8026baba8d53d7a037486a50c874342b242a2952e046b86d0eda075886ad97257cefb26619158f4d88f0150c6ff2e26e7e4d5ce58d1961cd684a5818cf490beeb6bf95d3fb3c7edc4d026bc453c3d28de0b531f936026a83b43ac468a7abab3451959ccd6b6b8fb250a2b28276c92ff309874ffc8a2f4dd02da6469510a5e747dcb45f414f9df34a8c896e6e2694e2100a5e7fe89b9fee42d1855fc08381a9a0ff765fc90753c94506600f41d063fbfe2b55e7ad926c8e64a916337deb01674e73254452fe1dab017c780d7a4ad221401843c33d9abc259a83d494f03b04d7f74c2e6a956782b08248e1a26e22a267541400948f1f9df2305256c49863b7a49e4a2d29db565667312ce4e8e2602dcf40e8a2631b0c852051114d494789621ca8347441bf1268df736866d33188e115165e19688f7ad0b9211eba337ae463e58ae7f12d22ea3db38385ca103ab10ed59c6c3c67aa24a1d3477210cedf909695e0e9a4c06146ddb77f846c57d7de86d7e7a5c8717d8bc10488c4568a9763fd67e72462794825f4563fc399207ea778328db494f1194a69e5e3786d6f21ef86932b1bd7fd888fa6c29818f982e7f92cd7447df7fefdfbf7e9872343edef1f04944bd3fcbc80b73d506a1b7840fc01ddec44179eb9e344ca0e2cdc4c60567013a44f687dd337f66b08b7eb18e7f31d99b543053208986b95d630da7f85d6f7ee518ec1854bf2d53f79f2ff2a24fda6169af4bc7bfddc2bdb0da9d7bf41910b1a7a518b4a79ba9f884aeb00d8333a7d0248e82b08ec62f8542847d53e5d09b6d19da45be117dcf878f96e2ce855136f5db0dfdc673342cf33cda2ae9718b5393c4d2b6e50724fce2b39a9f86ce6721bc1c318f74c45e2dab4faf8f8e2b46616f61d066ec7a0d05104e00fe17b2dc39b1554f4e69bfedbbfb9f80fa612bd59e1c6b157abfefcc7ba5add13c78d2f57f262dabc27db548da466509eba7a01e60fed18b0376cdffd342f2ca461e155f3a1ad4227c49387d64251e30480108932802f38a7b5ec8538d6b76776df1910407a195d3178d22b8dc559d099d3c4b6f46a6f29b6cf6a8911a820491a32bbfaf0802fb1312c377034901e0cd082702ac21721922faa4f15fe6d4f36e6da762f31ee726df249f1d3c6e7f341c125df3a93cfe77a34b6e82fcf5b31c6f3447a274ecb9063bad3b07de9d0ee7a2172382d7ec84a41da21daac7f2196844bea7623deab15204996aa961a8b6e8df1b1f422c5ace893d9c2ace85b72bfc1fe988f7a8a6bd82753bfa1173febae6579c04222c1f440799aed814fed8ccf17bbe6e62679caed4da4fbf80768644de01d9b815c9419f965426c9102512a88dbe2d8243dc491e1d9cc424e6cf7675a90e9344bf542718f2d1f719460caa27237a2715f3df12568c614f16966f1c6c4ce808034518ba2f648815dec9bff7bad9f825c5b8a0ae921aff7c56ec0ed7db11bf0414701cf87833618be2f76932c9fabddceefc1f35a82dbaba5e1f592cc1db4722c5319e7b2374b3425295ecd7d8a9835629f4d5b931bebe347e3fb688c397d1afa44dff486dab71f0c896828d57c3bf3578f36d78c91c561c00bc75399d22fc4073eaa69352870f5e2cfb67e92c70aea348732a78a8c8525ae66a3826bb272b8a8175f6e0f6d30a42df4a326aad1b6abc74e12063ca7f6adc50a4c0157affa95c8162341ec2a003f45d6634472b3061c7a2fefdec53dbd63e286a5b422bab6e9c77d36bfddfd0878430826707b4df2e9f05094d93e0bf71441becfe20db4d0d8f77fdabb8df09a8e6ed159f4031264c9505c4997050b9919a1025bf7c50731f2e65c54c10415db14498baa6087d8d7c9fdb31ee541c0fdcd7c332ed6bb5dd2d41878192aec2cbc1615dd123c3577efb23ba67a6a2269a3b3e0d89a242f80060b855e7c30335b018cd222a9f1ee5d5c9f0d37f7d094efebe2b86b832cccc417b17e8cef5e3fb7159d459bf983f660f31c4bc8b189a650d81f40a058fab5a1a51cc452689e0431937085f5305942c471cee4c98558829f94be5e708f4ea0e6d9014533447f3193842bd57770404c51c2734c1749fcf17436af9747e681ab635fbacc640276da56ea8f8043f65521e24fa36b71c90bdbe489b874f58dad5e4001d0290a13fcd97a1df2fe7afde731ec2d88176ce54f5c94c88230a42e18c27b3bfe7bc2c98ff155ac73ba858229fe0214d488064b393c3d35fc1694dfd3788825fb8692e9a2efd1fd6a2917cc16197918ac09dddcb8b1bc1528bd40bc2c889fda7850337b840b36f62b216391d08210e642e5e5a4105e7be4443cca5f38ebd6db326edde0910eeafd6a0f74d0fbcd1fe99dfd8449607ab08104bab1da85309a5ef5f2c5eeafa27cd160b8b9e6a5a1ee20a613ceec8b3c797cb1db6fd82ad21b8e368f5525eddf0603f6dd1b081dfb3de3452578b6f4b9c51cc107c45f283bec7ed0a139cb9e7d6ed8acf568fd2ee827ed92a01511cd51a89773b8d9a9fced9a040278d32ab46965175c809fbad16030b32fdc907e9e3d2ab53b2bb743dac019848475edf98a2b3b631b5adb9d175a150b0f305a2d10b38582b0a14ce83bc7049ce28a58192fc9356b522542ac7c8daa10ee197cba79bd8d160d23ae44df43423321a104e2efa8bb77dd303686900b54572600445816a25ebaa929a6332404c8907b1a21353318eec6777a413fa33838e07568c1daab383e0980dee13d4c4a8c6e1ed1e3610b2c9c4d966b6e90e4a1a5a5ee03ececfeef72c9966b62ada652402e6fddd473534bcf8d1efa4a9989332b9bb89dd94f5851742c6b46b21392c3055f495a41e4f5639fb2b85aa83cb422018955f1cc44f2d52dd8b69bcc36849d28729400b6012edbfb281be89a2eae03b6467ec9b546b71e777e19d1480a64ed935a424f8b633d5fcf6b7e6ea02b0462f772dc89eb74ddc6e0a968b15123426772da56560d3f9ec626bbbf89615a2765586dc4c240d848d4eb9acc78f49ec7d3b49281f1dbfe3df0b0b6d4f4fa3da351e92a38b18996e02e3314c6682e6b70daff7668208aac010556ba361c6cb35f1f08eeeab8c1e2d2fb6ce7fef9abdbe4b4fc4af6ed01901cebac31c5bf00b907971edbb6acbb9110158598317a07a176516ac6a49245818494fceac88a5de623c12e45a578b7cf34e08d756db144e54b29d9e996f356da42d26b520e408a5ecdeb644c96824978125c0c95f8d742efaff14cdbbe150cbad3029dcf034e089a005449e0b8f5f204543ce4b4882f6779ade58fbcde14309f1a3a149e65cf0504467a53701598bb10356b7f34e5d5a3ba73bf9b32a3c09fa895480df0982ba1e59bced0fce19f09c98bc11dfbd529f50239ce0ae72b1f1bfd6b74bc2edff93dd610bcc2f74237757de5cd6f65f25a821aa2a958ebc4dc8b56637a7dd0c9bd1c43dd2e66c2b915203547822853150ce4c2e6a68183dcf8bbd7cf6347461b8411796d2fb8c7c607eecb3e09a5103cf8c6bbc1eb7cf42387e8401d7c1f261ca48d58da64303e5fa5611c7dfec7c430fc0e83093835468fd1d924541a2d67af9472aea79956a4d572be83590abc739006a01efa74cb6951b4f4ba33e240506c28c8bc86ce46bcdcae191fd50b2019862ad1f4e60e01d83334baef6962f2f342690a329255a6a023b755d6c5184c33acc18ef1f662ef94182f0a36e379592ce1a6140a8dc9ca0cbac1402d3bdec2438d44c9ab5caa581148017c0bfa40dadd066a415afdffe7fe4ca4ebfe148ede2b34145be9c74c5d99fac61c4ebc951d4f8a4eb75ebd7bf3a397a03e25c7b2e1246e61b8d74f5f3d7f74f474dd88cfadf3768a8e38c952caf9ca5e1e171222dc5fbb938d7cc0287ab6a9973d14e83492b0c1c03d4d3477cabea4ae8f54f9c25e619176ce5d98be55ba26e980be129b978d54c59689f8b81fa14291da8ea1862251cfb7a693f8e55334855160c367357208447d484744f36cbf12ed759a1d8a0cb21c8e77a38ef081d55fbdf10037742889f67c6f834ddf6bd9f5bdcdb77d6fe37ddf5bb3f17be99ddfdb74ebf736db7b57ad6d16f12b859d4642e9de52f58b805f222019346192e8b5120a0d3f564446ead04e7aece474cb0217e3429a35e20f2f809c750383016f0cebfdde012d7facc4783f0ed6a30b3b813d06a1766d1c31bb47301d1aa7cc22f1c06921e4d5cb5724888c57b3b5b1f1ad872e308ab68eafeef2eb79420eb75350c1dc58aece44ee478cebe9d6449e6e75498dc77c7491aaa5cbc39a3fc8ea8a5759aab2f944eb634488607a78bdb91ae0df1354809b8bbeeb6fe42c1cc81b1a0753fec3b1b174140c60448330b4443da037df6d2ac4e31b35d68b5b9c6935ee1cb5853458a5f3bd9e092805479a03f8ed3d810339e8b7f2040e64830d3d8157d8297869c4076ab6ba1d08c180a6372a0cb8806fc1b7219a40479b082550f1573356c0ee7fa7d60a095b855fc352c13ef0ff56a60a694305a350ec21e2a1630438e2c6465263593de5a3293d25518d5aa2d4d9ed8ff332eb74c9db37c4f1b2fa02534fdfc40aed056bc97851a05adfab387999b12bc132896669bcac498fb56475954f26fa54966c81ee8c834aa04735e4dbb892f668293c5b06afac4a9df4e675f8bc26b9fadebd7eaec87b7c1a229df3c44b478056baace11a6a2c444cdae7bb774defe1f3a3691b792b581b2a635b16b88a5a6b56fb919a83685c2065e34ace82b6d6686523db91c00cc4f71a79625083485afea94b2c4e9cbd89fb7a4a0d4302f6cd9a1698135ec8d21d7087ca9b9aa20446370d9314f35abef2b11ccff0ad32078e325e333052fb436f70974784f777f9106429e37f5f823e073abfcfa720cb1b3db29cd1349f4c45b583097c3c1dd657c208921c98a43ee02b7c293427d5f462bdcaeba9d1a0c61c90268861ecd5d32d521d2d5f3d4343ab7efcc8fc07fb9c73bad5055761dbf7113d2f4789d89f26b5aeebe9b518bb708d896f817c3de3b9469257d6106ea5a46de8efc9e956a2db40a4fe037149b03f7453f40eb0c1e7b04d2b564f54d591944977c2d93df642fdc2783fb5d9fe466931bc3a8a6203935f07f8fda7a85776e81193387a5defa6d11d27ae19965ac30d24c9d8688b4a96914f94d9101a39bb73d463c15dea1c10174a788767dc435f744053f32961e39fd14000d784914b9a4cc78d0cf9bab781f8b385aa3ddfcdbe3f64bb0ffadfb2bc6426b7194ab574559b207c0862bf8828b2a40131059e5355fd6741cf2febb3c067a92095aa2200be027799ff30f0d9455d0378d41e3e0541cffd473cfe8c78f0b37df4df8c600ca4dfc703ffcf823559dc75e14dd40201ce1fdc6843361108adcdb16d7c436778e2967b959799bc3255a33c718ebb3269130f4d6de2e377615cc6cfcfc158ff1c0ce8aa73c819757e6ec2bd1863195df602f2f2d317869fd53e3bdd3a92b3992cfffe8668fb859ae92f4fdf985c838a46989f65fadbbbe32734583cfea51787138644b99ac9a73f71a542cdc81a8dbf22b2df8fed3cd92199f309e9e32c50ee28319265c6ab654b4333d8194686879c0a8fb28c157979010c7855e7239ba4135240e625586364a2e67901f92975358d82449952484c7db74734293028d5a53433fcfd3f93e7cb36d77c3f707f895500138839efac1eca6a66ad631b0826733e112e83a2f5a4b189c4dc000de842f7d69dcd24195392d5d3bc9c287625cbed1a1271b22a9f4ceb3e79e6b70ba4dbea36d51ed230d95518fe16e356f55c50881e33ee65b642685d6215ba517e0daed8f9f98f4199635af12376e0bed1702a3d7fd07b84dfe8514ad2f377412f24553d228c01ea0f067f32f94e8ff97c9e979377af9f1f6222143c92fd9f557fc6e790b0c740c5f8ca78a9c371e356af6d73ccb8d4e05ca97c02fa4e2faad4bc9a082fa9380b9a9c1db2dd0396b3ef1a5634072c0f6c62e01861fa526a13939f118f25d7af26397969ea37347e1be53bc6b698f43852fbe16a2c4e61c513629b136ace2284b47672d0474a956521daa2d2d714dd2754fa8524554be54f6bcb5b96ca7d6692bdd1145e24abd3b5b35799ac572443aa4d09a4c78993399d9f3bb7ac5fd8ab4525880448fe1ce37ba716cf19fa390772639875284a51f44ee5e5c49c5afbfa6373d4e9236c1264c1eb92fdfb8bdd60d6266f5091d79069c8910edf898580a81edb80046d234b5a3159f2725ebf5cd470ae1fd12c6006350d1928ded4b2c29f7e1e0b25a201572d04253a0549589f6589003100644cd24ab3ee10262148264b39b5f0e18af611f34aca7401bcc2177e9a783994ee42405d919bad570531576862a39841b134889e030bca70362e2689b7981257e9c5de091b9e8017bd0fd697f8e80c77da566ea30926da466cb69ac2b1c5604c72f8f3238d313f3f36c30f063f4020a24496ca311f89a1941783f1f0673518167238183df8cb5fee7fcdbfd9dd1dfee5fefdbd070ffef2d537bb0fbedddbfbeafe83afb2ecdb3fff792f1b8fbebe3f98f3d1059f08856d55351a40d2663a97fecfcac227577462dd30697f23dccbf0e74786d7b25937f5b501c587f641c6a72bd65da6ab3f76d56374f3295f089e5d88a57ae42f2cfd1366dd0da2053d6ed678ecadb5a10febf0a927054dacf1743c3c3ce9d24bef3e5e7ab497f0c2036433c3a7ae273d1b8c53f4e8243f8387de3b06f827b6f40cb7c1ffee36ed11694e9c4f4dac341b17c776e87ce8b1a5c33bf63b40bc0f8002cb78ff3fa0d9bc06cf2e1b30aca5ff5a225204b97082361fb450b0843f978e5fd48b1d72058f11a9f5ceaa3c9b5cf1e5a025d31c8260c6552d2a581298f8c3322c6582968f0b3eba789e2b176bea8b2ff010ecb3dd1e6e0ffaf4e12f9394d3fed455dda7695ed8dc64a0fff36d5c59a2c85533b732a85b6d1964e46c29aef24b910163a19102448a15df83f6b3fc435eba5f4e23bacf7631191bf12a9d2ff172f39a7730f0eab180d134def2b5b46a7b739e26a226e70924b08efff4cab285d6f3020ffd8ab650cbbd427bae57b38ec1790ef7d6899e7e8ecee5039a6a5cdda1111bcc1c5000b77330ccb589f8929ce613a146553eaf6565c0044c6d70eabb3eb207e69cff11322e42163251b3f77a3bdeeb5fef3543fa9e4146e77247948b99a880bbeb4cf32cc3f7ba79d774f257d019995d09cb74b5b0043cd96d2efbc00544d43f42df7a3d6eb973c88e0a8de805bd8266d2969e14ae062a8e42a239d9f5ee23e9f429314c125cfca6e9a60f5f5ee575a2d878eee3b283f788802a1969434fc4c5eb2102acdfb177755ee4fa2c6040771b882515c9be87a18f2e04538b4ab0bf66b99a4b255eda70d420542b369295167d8b25cb4733748281c8f04603c4a6525e2833ba79af65685058f957cce19279568e6c2f28bfe4f0c3311cfb844d9567c24eb760355813857cdbfa1572d94ff48c7254b4adef88d6b7591a4914e31a077238d0703a82c1cdb4edfef8a59ca50b3f7eb481ef7c0458bb76d3db891fe92c5de83ba11df40b39ba502e207950f8f1a3514a06dff047a3892dfef8d1464a7461a07cad063f80ef5455a712bc38868a3d337702af8495d80d1d69d8f76c8f3dc4463b6c8fedb3fbdeb7666fb56f8df3acd12ddbbc6b0c0b041a340d425e09172f4c947062d04410778f43dec54b79016c41b1c46ca79a78ea52aba61197a2646041375a542abf144cd324e52f3edc2f105ce012af9654bd5a89fa7f799898d0833b0c47a5af94e85bc01a33d319c47db3d5626d836a4beee726a2e9d4382fc116c1f44c17b2b3134c7616206a14206516605fe2269d4541cc3e58c7a6e67c1b79f852d8fa83f9b11a65c78147d0b8ec3415581ac9f63647dd3d83a87bde0b6ccfa0aa41dcbdb423580257f71aae60e61c52cf2f53641cbe7aacb9dec8092ca5911a978d233fc74c7c0d02697ac52152d47225752522628412962f0a7aff8e2051547fbe50d3a0722c03ca22b833d6f24dab671bf676f76ed8fd49f2a2f26a83c1c0a9c4cdf584376c8e94c3d85d5662eeede270671a8baaf2893e91c736bcb8bd86fc0de22ea0525c050040fd832f4a6e6eb8ce87e1ef3e6106f769743cdc9b5e34bd80ad6ee1bee8d8c184db1c93d7ccdfcfb07556e4c6aac498d817196b0c4d3ad8614845c22e1c25097cb32bb036fae5530ffe6c410993b614eb6864a4046822ea861d3899948dc7084d55d85489ba4339659fc108731d86ea79b66aadd04db8c4664e590c6659b21cdf7b4a3056e6fa5a3411319dee7dc08db5b12bc1338037ec1c5ebe1605449f5682f109cff56ab4c0508b8246f5c224c3578295026f6ac8a1e8eada58a49930d95bf55d7c85f13671967a5ae834ed66db0be7da63a21e9121457fd2c7287078def4ada016fae29fe593690da776287ce410aee2da41f7ec6a9a8fa6a6ed5040f3848974ba173b65fa5cb2fe88c39db0ee8020e21cac11421b5d35ceabbf927b368b85179942cc2794e430989339939fa800f1289be58e64b3437cc7d02cece916fc09aa615bf99932228ec8d6480ab9afe9450e7591cf51a30e81d05776e0ebfaf6b9fa4156a3bc9ca089effa4ea206d81309ca7d218e0aae947b22b12f003e501a7c27640d0fbb095bec6b043e20863e40cd30551a3cd67413afc66fa782356bb2221f8b1dccc4a739e01a836bb142961301a7652e2b07613b7038b393d3ad737448393f3fddc2d7f9e0852854b29859a3fda2abe352c7adf8ca0edd0bcc9ba3770740d2081cd26df46c48abae3ea2657fd8678b52fc4b1393d1548c2e7ad45d437c007fbc91b0dfb8627f75af4feefc6bbaada9c9480341d7b9124571dafa6cffac7681cb8a425e196b6325587ade79e91fbc50a5e9a0aedc43fa270c6c6cada28d90ef52df6bc967c633411ef97a184622542fb89099e35c14193a8118094b7761e596bc0443d29a62520fbd4f80325602842b8683cbca46dcabc48e19416f57f8d558629bd13a5213fcab5cf951605e571a42e576cd16081c3de6508ce44ce8ee0ad80bda5dcf5c37062a15126b0f85ae19ef477925e0390eae5a258b8551a0a3270d9a0fb3bcde564c5ec110c342cc545297aea9d7cf6ae07529835ca985500f17f5f8dbc3ff79baf73f7f39fa9fbf7c75f75f87b9fa9faf1ec1c77b051f8ae27fbe7ae4a7b60373de91d54e29eb7ba87766b059fe8131d0b38175d05c5994585913606f6bdae837afad17993947267ca711736959da71d119a35d08620acb47757e19a47df46385524c28ab9c6ea51462a75bbdd4d0f8a4957abeeda07a56df595dcf8d87bc9559d549e3923a23acd6ea8a7da399eb449cd64d0ceb5226f813513ff1051d9f9dd2a834952c44ff8a57a5a1f0669fbc502cc1edcb5112ef37d0491a8c77d915576c26b37c9c8b8cf1712d2a762c87ff64bcaeb9e686fbecad3e2be688b80bc29e389bfcc7f3fd10ed46b359e885861a47dd65ca1c482ff024e2032cd7edf3c7f847d9e0223a302f407f33363a8a7136ae725166c5129fa7353832315c4c26793989b58a14d0bae33082912e899d1ea0aca43ff496d4d56254cb4a8b999db830d903fd8eefd9c01c7de763de018bf429caf791386e1d134b6fa55aef5a87c6faa9b8738cf0b75a6dc6be64cfc684ce9ae7bf62e99008941aa31a23f019fce4e5f28a2f7bae0b2519afe5ac5f098d4d681d9375bad4c9c1e476c94bb61435e325dc14fa6ac12e6d57035c63f42401f427e00d7bf83cd05ccd58562361ee6033e51d633245dc8fd84f826568dec6cb1a85a15a32f4dbe4ac90721eac2e13b51881b8a0840dd7b4c1949bec68306f62f1b88e5e3488bdd9d7615e6651b55c3984786564b143f20e8dda4e1759451f766be3d4a193d1e4a46ffd9157d0ef3bcdf1ba81a4faa2ffb8cffe266a085a050eb25f9ad4b74020f272f2259b095e1ae75592c68fd1e338e58a01ff22c66331aa15eb2881f4aa1285b8846d140a306c96ab51ff67451d7381e82dca3ccb25a40d34b6940bc8553a5c182b29c418ff2ca32933e343cd44180e434bc023a967bd008173a116bc20e3bc1182fde9db6fd880bd5a1405fbd3d75fdb8fc96d21861b169ee7691a7ac71dec203835c00558d4666f81921bff85487ade8ea53054e0340b7b8d930b4ee25997388f799b3f720e91f89c87979ffe47a64eed24f01e8e74dfd79c3f3965740176c4ae3b020d0e80a5ad0bc9d5850d4f4eb7e0cf231fb8f8cc136a5befd29cd804ef81ef033eb011e154dc27db3c0e5b107e250772f5d937aef01f46626e8de6ad1af180be855893b6e6770736305cec244371455847bb6bda505a9f8198bb44241881aeaa13623d9dbf68c48aee067ca2ab1bb0845ab6735f5a1f62ccb413c66421f8c3cb35bce689e8da29c587daf8d5e93f010ae469bded4ef7e66f21bf78e2459533f6ac664a8899a3a1ee620555dcd8a525f1b4355784a5bb9ae605c8ac263164c70415d404b7ab5901d167af302db3973bbd400bac038e173cd2915e4299d7c881b2d4ac8411296d14c40e57565f68ac63ba568c729c3fb680a7b70892b1695538609ee675348302da04d023cc73c3e5be5a54668be14dc5089d700368b6c60c0402f936a0f136dc6f285383b70066a6f1f4f23daa2494d5740e066c6a6558549396f948547a9e854d7b898a1d9cb2dfb122bf1078fb1418fc673030d713593f5eb72d8bb60c5edf42d734bc13d841928865cc217013cf5788ad514c7a9732e84759583d1fa32a39c068ddc33986bf35cd812139272da91cacb9cf1bf5e71b7a1519152a1ed57216f13b70050603527933c5060695a905b89d5d7e693c341cacda9e87138353fab4ded80695c79ea2a48d6aa81d0e299e089a7d207830f119515f0b8e1668e4ea09189c94cdbc96b61256f301dd8f3b4f76d40939179201c4ec26a1d6465e313addacd3bdad9926be7782d9272748b7383c21ee29da6515a0fb00af4f51c607c4d2266784b91f1a273c1eafc72e43af8c145a876d749383d50d22092ee6315b37c80994d7eb3fe201e347b46b2faac10cba67922957d63e9fadb6d7d7e0c74f9a43067f34b8f591a5d8c9159bf28c2939130cd58faca32f1339371a1159ba78183d548a624c68d5ed690680fde9c1fd6fd940ffef2f767270f1ffe01c3bdc44fda41f369e48fc142d89ea1bd790f34a8cd147d32cd4bb8ca416db8ce4e5aa7768f4151f4c224c3df8a97b72ba65ad734fb7ce0ec89a8ec54cde7435333193c13274c1460bd0156f3a756f4c68df91fc291eb04c8c64c56b59a58c3465e3e189b08eaeece4742b57c75a762cf545202b104a62d1316224757dd7ff3eb3fe8975b504ef417ce5d8b615b631140a8960021ca731b0d052fa760e836f3b96116c65680f46fe87723d866de17844cfeec53b7df72ea3ab25f0857546d5dd929bef39375a7533f38e7dcbd7ccb3c841a965955b4e6b2b2bb6fddaa1dd761f02e6797728033a0e3973545015349e4bb908b9e777a51ed49e3c5689b16279594bf6fe3b8b57dfbf2719751cdf6adfee17d841ed34ce3d12e4dc32df79598acac712e33534872066a00e46c735d3b97d4cf77486fd288f28df9e26439b6c67dc28f08b0e9462b42ba357dcb27727718c216dee34fca99a98624030b74fe0724c9779c56d3a23d24b18e43345f3ec46f99e625eca58b839abb438ae4b18d1c5bba6c5716c52c1613d048c211b31276ab3f62308f843e31804129ac907e6a3b8242ec1ce9d51536b046e3689729b6306989790d80186c0f381c619fdbde17e9a2be27380dc057179f4f4349620bd932221ba096dc02656024d89e9bf9ebebf034fdf704756469db2cb101f46c5221319b97e2d34ad21b0cd95eccdd19d510829c356ffc03cd2d413ce009b7acbf5584e8dba898b9bef25b9dd68b5ed2be13633af1d83b5847e31df83f5b0d5729beaabb72af26ab35be218e46339fca74dafe8828e3458abd053d984acb2513b7ef91498e6d8de02060c5c4f7d2ec896349960b9769d3063b607125b0cc34f56a2acffd7a43f8e264fe28d24164fe2932c6aa33181ef1834add997be1f82485d64f01e983de2aababe679b97b93942df242af98c905ac6fecd2e3e98da65635220e7a8b9e6733435d1a2702e17ca28feac8d9d8ddb80e632d8d4de2b46aa0d0457338e9d46b7a1e28dd8bd7f3aa4d9070e4c895adfe5ce93c6e0c5945b3394accfde08b199b5c89feaa9d851a2de91e31ddbe30ef6b833e56ac7f4b823f47cc2a7f3f8f8248f81bde713c8d44c5c1abb3ed9d0a595b096bdb6493f0e1948fb37f1ffbcd4029ef00c650b8d0f0939c53863eb8a5606e94c2a3e8412f543d9a3b647c8f683975f0fae51fb10ee7d5fdfa08542c0ec5a0cb703344f4cbb94d9d33dc468fc2a95f3d7a531f755476140b6eb9d7616deeb1d3b6e8f51f8d8e844e88ad473b3eb62413772511913a4b755fb680b8da69ca92b73258291ed716353d30d8ce94bb78a6c8393526d19b6b1bfd2e229aaead1f656434664acd074a196609f5209e50346d870a2163bf0b9c2d8bd9970a096ed34d60743c12e73950fd1cc4c131a1b042673134300251d5f093c5a17154712c4658d48e8425fbddfb0107ae64e41277d36029b19db4f837dd9a8a764ac507765b8466672a3b670a1a3205c685812d9d0243fb8661076ca02cde15730e39842e1c79dabbc9eee98b046ae3628f5d1342a5c8b0d62012ac0748fab9a11f887708bb6c01de4c768c0011700857c239f9abeecb0097d5fb187dab74f786db98f91eed795ebbbd6f5a98fcbbc1263612d37a53e4ef696c5d65deaf8e22eddb0433fe16e4a58867b363738ba6f6e8c6d8c28e2bad160dd76e6b4973c2f348772871dbbb7455443502757d089fa9bc94ba86e85276e007dfafc3c497928cb92a4c6a60b2746049ebf18ba973542f742bc2d58aab2cc432d99f1b8e89bc635bf10caa986f43103c1bec815701f185054f58c0d2e3cd16157c02d014923cc51cff40a79eb1c2a988c0a2566a49bf1b971b7b090b55dc6bde9e90232ec9b6eb1de5bf496ef68eec6e2e63c0808db6587dfbbeb81b001348a051e2a839beb7d513daadf3cb59bef63657ab74f0d5d85af75ffac3dc60ec4e1237775d0fdfdb348e9430209275c051a8a9c8d5826e8216418fa1896903ea67c6a0fbe715bb36ad2b7e62c09f1fa59e665e7746be774ab1bbdcb7c0a82c5b9901230ca7af78dd8b11e143dc41da454f50d7b7a56aabae1bb5e2dca2758af522f4b62dfdc6937d964ecc4f980c2535bb0be33f405470bf6133a5ff32515f8429fc57f88e5cbcaeae1020c8538e6ee1daa51b79932f4dc4e2bac78c6f69bad03f613466af846bbd2c82b5ab78033ddcf159e6d132802b2d9ccf89cac709c525a8e3b815a12b05bb7ed24436d906d8bf73678101755bd4c01333ddd66ed586b98ac152f2f9167b17592e33256c17a15c42870ada5a1558ca230e0c63e7e5c5999d6f56a84d1de9a31e2661678773a23afc3f7d2860feeadb9c6548dc0f9086aedadef28592574635af11814d85235a2758041933195570ce35532b51882e7905024458c9b92346f94e114fa89072e724e1b68633430eeacdebdcb36a81e2adaef5c0b896f041a8c66921bd7535ef199a845a51938c7f6b8c7137d7b07cc4bf8b4e5de40b795559a9ae728e226aaa4e60f332954b95db329bf146046e69c60e74e7a43332974b029fdb1c9d5133b4e48299b200da9254aa95916ae67e0afd52b8116e5d5a2641d03adac0b597ca6860d23a7d779ca70f5085f018fadebc621bb73c787a6892e0cf729b830bc661998eec360990f03e8a22d18cf327c0f0cfd64cd2c69689c68fc4efacba1beafd8be1ec902243190dba6789cc6edd7497e8051301aa12ec3580469b486edaaaf04bf08bdde18fafca53c95341a6ba92493a5b04fb384a6add8329f39664387a8566e829c07671324ecd983f899391c371b15852bc659a92f3a6741d07c8edb84c06c7497050c5ba4f73b9af2bcd412c7dbe55c1c4dc5e842549d4b5ee4999e9595055c1b5d01322ce4eab5f8d722af44e6240d6fac1688e434f3baaef2c3a228021978bda461d27936a2de3cf0516f1e84516f1eaccb28adbbb4716f1e6c9055dac6d9b7f15fd386d4adea98174e7bf2dd77bc94e5722617eafbef5dac6f1680c6bc84b89f1f3f3ae046066f00fa13fbf18c3599386baa6cb72b7ad083776b74f237cf2f416f26e6e44376baa5ff80e4ab41c8f3c060df09e7a11734e8125cdc778858fade194fba45eaf2f7fa9ccc7865ce4865e66cf323e6a569d8d4f9bcef8153485e2bf38c922b53d7ac0e2af5a91a2230e58b6d814c858605da60c0fe5aab1dccf18888c9ab096846c44828c5ab25863d90331b473f2f6b5195bc506c878d795e28707b51ccb9de36e6e0ce9f7908c548fa3d7672b393e6a4193ddd6ed33caec9a46aa220b2237bda21659bf91b1d988cc902ca851a288fb28c7924034d30af73355e322cd324c6e86ca3cefba459cb385e54b6a26ed48775443c92737d1583d6c47073366a62acec30c6671d1b561141f6bf2426c860c05e606627638e469edee60816a4c5f0b5498b437bf6ddbff4bfee7fd5ffc676e66eef93bffe555fc99a9ebfe5133c74db58699bde0a6e7a27a75b41136b7a73baf566a399fcc08b62c8471780a7a52c77d45c8c00938a5c73423606b0d76fcd65b11ce745414ccfd7073ab69225be385a1ec2d56f9f63186ac9d8235f737b51ee814f9d785fadc86d309bdcb6ff6b4209b64b93d1bba599e4e916d7357c1cfdc69ed1f5bf1693a71fe634d8d1cb2263576278a1a95787d7ac105cd5faaec90bf6a8cc2a7dfcbfeedf77760adb769ddbace2c0afd7535ebaeeb6f1951c6dd1acbecc0cdb673f89eda260a5ac66bcc8ff4fa09f1cb81d4022015eb3c1b0e003d7db1c45a6385f523f82808d401c8360e5416b02d21ea6042ad80e2c368087204657546ca6c931d8d5022cd87b8201effbec656973eb6998c0932e9b69723d818cb6d7c72d31ca95d804bdd298183ee4536a62e118b83024f1e809f5a12120c4b02849f7f8b5c848baa9c4447c98fb8e566f4882b5f4de2584b73cd29f64d501ab0024af88145a68d57f454ee0ed4c6ae399f8a6fce766ac9d866034e9069715ef35e1a5d0d1db2eb25fcbe7f24a54475c898e8f0a1ef21e9e39b1b17accd2090fa830ff7227829ee146b9d2ccd723a44dfb945323bd81d819652908b8ba6125f845e0a56a3a7e695075c39eb1fa665d1ff3f9c6fd1ef3f99a4e8d7629e8afa93779578a0f7331aa45e6f6691f394f07ddb6cdf147abc144470cfb1db28ed48de27b7414c6129114c939085b950e379fc25200ed8f91ce691927c45f60eb99acd8cffc9263603fc333a7f1147968230304ac7f82f17f5602178bcae556765f8e8168bb0a7ed1f85d2dc0c65a33944606582501b8fd7baf17d0f728122cca2de3de6a78813f3d15189a9e3f8934bc6d81f8a21386890a2d2234a861ed3ffef6047183609e49897c8f7dcfbe3122f91edb61df10995c77f3cd06013e9d5c0e1d6c12e47373f26d582102db843579f3158362b58baab60aa3bdd6aa1557c166cd49b57852ecd5c14a898818225f431405cf70e38d7f931bd7dd0cdd9b22cc4178fde1640873e13cf7018ef0f92026739b10ce74ae08d7b6c56c5affb3f0217b9e92a98d5566bee1c261db4ed09405fe3e3bdd6a13b26f089cf5aa8916b203614f435a937848dd005f5c6a408b2507c9ce5f8e37e8be49f2126a84b8fb633effcc990317d1ec181991cfecdb323fb67b90005f562f6f03f418f8b101f9f410b7b00156bf8260d2eba2a37c0eb8ec4a6268bd8ad3fb4658b51f17f412955e8e1bd55e8ea38ac77cbe1ffe8c2ae0ccf61b25502d0df1fd96f2154df454dbbe9809a5c1bedffa0573806026cb3b24f46393b12589a38c465519d5247a8639ab23dc1fe89084eedbb04708329aec90a6146cdada9254cc3de60da3e3874b6b1549d292b5e6f0d35341af51a1661b25f1cbcba9a8f2da7a8e2c86d62266311715b5b7b19f880b947b6cc7f3d0f16d7c25f3fcd5681cbcf61fba0a616d17ec136ad8cee3bc776abeecb9f800a287d965e6a2cc44395abead84e891d478343e65b5289f958fcc87bae2a532b1a656a5a7ebb15f6c4a35ccb47664b48a360d1df1326ee4a0333866db1bd0ae423348cc16632fe4dff851ca0b65dffa11df5c82d73b6abebc7ee780c84e0b77292aa581f1751ab7dd9d8b79359f2543c290b80a3445701c38469478de60c26bfac3ba513eb4d62073548258d5f17f7dde7ef73e6f0b257ef091ba0233367b9e307932fcd9b9dff55e54a27e9b8f2ed8a1af79b27b46dca31636e82f39ce2969ca74443ed5f9e8a2a943d4a5ec1edb8d24e49e3307b0a21b8cdbc0e55705cf4bdcbc4e23ab113ef2f95c78f8fb4e5a85ba2af71da045abc11409f56d83ed60037c92ad3102418c61d15226a2bebd4c911014a12d67e2ea3c9126b7f4271bfc7b74f1379ba33accf63811357ee93427bb36f7b50dc4efb35e376da74c6eecb59d60bd964e9428c6ebbbd0b5522ec06ef54dc1c9e71b3db2d76966f7a8c104fbcdd58817368f850fff8506f68dbf756cc8b637a3a9c81685530191b537aab4638f63093ae47c46adf79b45a789b761821727eb404582c87e6a010266735d050aac61b1b0b192c43a3c267807a8cf9c7623832d9d71e3637cdb5e67ec03cbd3fbb432555ed64fc470310115858b1ae47b0f79bcce659bfef16dc54717793979c26bee308c46c127df7daef9512178f9a8de87c7a67e29af400b7cf4fce9a317ef5e9d3f7ffae81f4f9f9cbf7efae8e8edb3972fde9c3ffae1edd3d7e7c7cf9e3f7ff6a617ee9147317b0992a75f3f74ecc9f1762ad82c2ff3d962c6ea7c266c24922b78c584e9b1c5dc46cbf3cb05b755ce48acda2f313673ec0e32e5609338e3259fa0e142b528c18ec4842d35f1976d280dd3d750b0613e61a2948bc934ce834507c19cece69e83387360fe98d7364f9c8d8eaa87b501d08702230cedd8107dfd284fdc463ba0b9adfbf7efdf3f88013ad6bcae461964a1f1a1df4054cbef00a942f00b91b95d536d5378fbecf8e9ebf3e72f5fbe5a35acdd1ee5f667b8a4f108cd5e5c0a88368cacf67801ce311850351e7e518ee46c96d7b5c86cdfafc5b8256d1e7b236a303af7137ace21f8ec36e9c7af751b316b31079cabcc2b733c055bfd08ebfe0895c2f38b58612abcd57dbdc61cfff4664df60304dd513372ab25eb224f361372517760eaef9ae051bdf63deba66d049521ac66b49763dbd7b3f173400fe2d0dab2217d9e612d1861053c22a6a9122359b99e1ea923dbb903d7ebb54367a210b5081ac4f4e5f5a2d49808c6a6c196d7d2aa20c054592e6a55730cd0ead024e94edd067d7f31a477d0076e6583017b2ee51c84564d5e7851e00cf50480478f0fe701aba77aaa1818118d97c00e62334231d1672ecf6c6c49f39828afd82121fc07ab40ddf47989bdb62d954747e728a281616e4c95e8dd464fe4fb43d741df5c4addc82eef59bdadf08ea8a55ecd52135cb06e89a0d5f7cd5c9f2ba30b93f9b2c3500dbf01f28d5704a4b324a0ad1395ff9f60df93b46e8301fb496c5f0a0c623acecb5c698e84b34a2e4a48a662d058813d640d863de8a398db64291078748648e4714a511c37205a7d5c432fb0a7c7afdefebff3978ffffef4e8ad952812e1d08ee803cb0f26016f5018b2389eab0661a6519bb2ef57bc2a45f66828173565b413aa1717ef675cf69a7df6988440c38a10e9462520d0f88ae4762751c92f206b1a479961525db94f01609bd6556b4210bb8c859d861fcb861144c0252505595d9e607f5ba31f1fcbe13fcf206c9bbee73557e418fa8ca6de31ddd3e45f3e17c1c21b690cc5945fe6f0a886f83ce24a28880082e6609aa3d8201008a8ff067fb233d81906d29b5e491aaf628b45c440cdab1005cd8f525eb043bb9bfd507bc33e7e8cf439ce23846645384c77db41cbdb3775958fea639989c1912c0d99829f6f166a2e4a8800bd8480fdc865c94515449536d7858b060db19087bccc642932365b14753e2f045056d533218b6d5c3aa09f86be9a7e5e7b86d181c552572b8490a03936560e98ad5367b4441b4b842935fc21af54edd2b040609a5cd1b42bb26263a8035703264de12ea28debc76558005d352f09084ce7575c31e720d4f7175b29ae5eb7a467b806d16b0900371830fff04323ddf46047e1a0180f262dbab8ec1cbef9e3776f3540afc4b63e122de28f66ba27b2b61e3f0b259e8258d2a1291954cd27a2a7c77329b91afd9dab9a57b5c8ce713a2654e1a226dde871b24acee710bbaecc748734b587cd9415c418afa7c2dfdb8301eb3cab6d6c6d65438c284d09fc71e819810f66d4ef528e824a9c7d2360c4ecc44f02e5118d18fa8a253031a760db66c4b00b19e923869362dcea354fa91183d7dbaef6313083dbad593187a22087d10cddc4039f8112a2d3e6e32eed8bf1aaca2f35ed04f15070956bd9e88a2f810d3666c1b9b2a9cc825ef556224d311c923b4940488a425e0563015ea010c8f29af062e41cb57061ad0421e6ca42e388a48223a1152113f0e126568d19292e4037be81c4d4e8b2e18041d2bdac98413fc846e1a829511755eec12f522475c3266673121468306047bc28204980a1a3de8fd4c2689da4162dd533fc9bd07898c3dff46ef50deb6be3af6a42a2112f24dd58627270b80eb40845eead4c8297aa34933708ae05082d6cd8434ddad7d2a0f278512f2a9ae0cf93287f02ddf953b1ca35b58d2efda6672992196431df18777eab4ad45ac4c94bb266b822864238f7f4ac1ff48099c48c976fb6005969c8337d39020505ddb26123550f33baca05bd4f886a8b2b36e7ceaa9eb3f34b512dcf219725dcb64815c3e66e017af74056d1746dde63b2d26b9a4060d60674490743515fe9f5b9cc56842c926aafc58e21323501db06dbe1959f2c505fdef2c51e087326bbb528960eb9610f2d667093ce682ef3b2a63da4af144df97afe8753e23e2b61189725f8936b91ea277ec34c2e6313f294a0e61bd3f24ff4cdd0b3a9b0a936cb340d50a7855eb8b6eba9708cadc1386456eb293dbdc8d1c2f177786fdae9db7c289831cf049d2564b0e2437929ba982f859bfcc9a04cb569c60819a71969824c3e075415d49e9b27c8cc43f3f23881ae25e94e2ae54e53edd04cb613a7da4100ee60312f97fe93c26145c6b245856a3102bf38fd4e9b81818b3f171c9c580037c4ef4a5617263d8e93173535fb302fc01f90a95acc21f494fe7f8e991958cd8b0b1f12f2eaeaaabf948b7a3114200e5ee9453cbc3c1cbdfae1ebfcb1c8e40ff7ef8e05d744fe10eaf587e26e7db8fbd5fd3f5f57e80e9694b8e28b974ec6f7710c4fadc984b19ed947fd853905162ce4d53ea57308cae25070e1c7d23b1593a4ee3e2e0679eb8abfa5e233da277daa6249d38d2688687f166513da996e6046114f2a8ad6d7d41769649a89993cd0d78dcd540b3eba429977a34c88b9e1dead749c9b7cb7d84aa9c5ccbcf5e463ac8e4607183dc18a684e118bb7aecb306c088f797781988740b380e61b337693b2d1ef8c9e33c5a653ff7a60118944d1a40cdc9591644c887c629905da4113487edfd5dfedb3bcd6e44f436622ed931bda7541fc104c539ad7aec95e9f763b92e5a5a86a0c0342e28b6926aab40ed984689b2c7d90b8b41018973ed838e0d7fc689acf06393eaf7da66294467981f1d3dca8bc5cce4cd40a16c2901d324c0de1438fc6c8d4ed260273253b69b4a4e73d19a632227841afd83a285a8bd784dcc6a802ee9218a45796499d589567932bbe1c4c65aeea9d5296463586d9c5d46058c8e160c6552daa81aa4603083fddff5959cd2bb47b5cf0d1c5f35c3916ca2607202989f02620051a0d7845b316d5e078a57f369ec35b01d96381cd190dcead3fa7627241e46ce26379275c0358781182b53a511344fcf62644c4bcec8940cf2ac31b1a0bb335f1af5ec6ec65e7dc13d92866f639bc4ec421b35d5a42f84ce4a1208c0d38dc9b9e3e7e644122ea646280567f99d84521bcffe975d08cb0df586d7f1e9b87db59ee3bd0402043b0360ff0aaf91991a839461c53f4a57b663848ee85efd1de53b0e9d771ad420eb0ae38e63c83502500501faf1c7cf26c260c70b4f3dfdcfe4db97ad58819a78c8562b443b4d1533d76aaa59d54b2b945063beaddbb415f0d1488638bbe74295b9e48b86c179092d7a09d96df0cb2e6183647e91d01656d5e261ca81aef18765e1f3fae9e571a353fd767b1b9039fe7b968416f639534ac3f1f11d7d737608cfacc0418e918090aecb1b3c7cbe772c40b08c34429c7a29857798d569e412540bd8512bec4867b490d1aa0c6359e925aa6664c5841c0fe8218b23a15159ab35ae510916e4d0ae437d65838ea03c37c7a321f566fc442744268f0e1e3c77898b6767792561b49fb73173a772917ac145a989973a5d87bd7febd66d9106970d75231e8e1f938decab695349dde69b6d81b3e0e86a6ba768b5a23d4590c84338188af186720c319369a59efc8e6ca34922a31926566b0139492fa2682feace57414b72f815c7b4dec4a482a4166198dfdfe90fdf2a9e7f757cb004454fbffd8fbf7f5366e6451147f15d8c9cf24635e24e736a1a2781c5b49b4c6b6bc6d7932f393b4e4261b243b6a7673359aba4cec07387f9e2738af781ee17ca82a0005349aa21d276bf6dac9f7cd586c0005a05028140a75618e79ec48564df27ce0e8f33dd1ce659c4aaa1e19d2436d5e66d683ca37040e04e6bb4856122fd8789f81f01f694888886c17af5dd5ce25c27158e7581243ad1f5c1f62169bb13a9f46a64250818550942d757df5b1933fb6619bd611b1c1741d011a0692fd4b566ec08ebf5aa7852dfb6cc436ba9d2675375acec86dfc7e204c36309391c6d7b6fbfb1420705f875b968b2d19d015b6bf45b0c6ff7872136866dc277825266f52dd4dbed9a2118beb7929b25426e26a71236af5e0cbcfbf8280e425788589725dc36dd787e00623f6419370581c3b072893af0467ea79f4bee3aa561ee336ae3a050844d4b8e1e14a56ab3c2bea719a29bd8083425ed7833c2be4584c9262509bd8339e02c61fe1ac6011be39c54716f0f6387b94c0ec0363790b68bf318e77c431864f6683a2685690838c09abee653d7be77442ef3c7fc386d8af4f169779ad61bed26ff1a1725e87fd86917af30b9aadf7e32ca01f987cf47dfed2e797a57ec44d6c0bb7c73cabe5d6ae8f7fe6d0fad839b4eef6efa2dfc00b7b64637883e6d10ec1dedcc9ded93311d5e52cbb16fba2a3af241584659b25592ed3ce9e17b19f0af5ae4833bc7752582b4fb7618b23f12db84869cf093b22af412832e0307b3e8478251018289c4e9786a8c5ea4ea7d70b76ad21513bbb3d2060e672f168a2ca7c5dcbee2aa91745c364d07c1d4e1749f5a8eeee60f0a5cea8637a1a8d04587389dde197d762067a2db497d532507d550e926a6e5d3fcb19b2c34fd42acfa6b2dbe316d2f0e9a890dd3c53e0a49cca6b133695fb3d42415f5ce83fc57db1db179a2874234bc217e25b516802bfbfafcb2fe05fbb00baea4976468d4e2e3c1a04382b8aac6ea688afbdcb15e6094a0879a4085cc8e43283b4ffa22853d951625de5c355526901965961ab32bf942f08a3ddbaecc32b3be303f0e81e5c32f09be874d8cb425dbe48aa5a6ffb6e5d4260ec72a8b157773ba34eaf87c1f39dfd5b552e6d7d0077ef1e7c8cb639b561a28fcb471388e50f5d3052a94bc75b32f543552eb1a281cdaac2046de5e55ad507458ab54d07fa426880707d59a457ae89afc1ec20a1523a96d94c09475ce98c60e17328c15b8095cc21ae4b1f8d7140eb9ee552af58d087a591b06757c3643ec03e1bda963baea6198e894a38e2cbbd48d4719564b93e4bf3442df638bd44a703626d02da635be724ac2d0662d730f3b00bbd35a0bddeecc38e5e24f63bfcd089a8f62310a34ea3eb159c458d4d1e8e566fe6eff0d41a0cbc89ae92ca9f68e6ab29b01c27c278b06337b6655f64bd48b03fd7fe3d0008b15eddbfdf84b65ebd1788c1a0454f71c76da61e626e0fab0bdd83c3deba508b6c567761f06c7f2154b623efdd0b48f964e70c6ec09d8e2d6324ab4bdfbe157782cd6eca7a6024d80bf78c1d4d87bfbb924d325f74489aa23993af35f549eade3d6a3a54eb89aaabee60b787431e757a06eafd7db69ddc0d789dd72d8765c0a88323132e3247b36e39f9c53f2acbc92f432a140ff9af6e4f8c1b7ecda6105de635b0c65d196a60b6c7a42f26ecfd5eaa1a23238381a690ba4e56dfa051998dad9b00d14e7a4158580272644226f77565b2622a218dc1d248a2fac78d7dd8856e3ce858e9ed5b3169c8ae66af9f46e3bf268d07feae2179bfe2a467694f88c4302e9897f9c1cbe5a5ac6eece5a79bd572e9cb11de458821186b4e4ea0ee19bf86e25f6d992b10c7364aac73a29f78051ebf4a4c942e431f09b7ad9c84a5135ff340ad359527807af7db2d35271d0ac835f1a2a55a1cf07b83af45faf55d5f00ddf542b4fa5a89489720d76b74c2c35f70b18cc7248eec430711b720c54cb171333012ca5f27c944e6a36a5dd4d9528e16325fc94a8da45a8ea8228bb7126c6d1b4c05be0e8cb0cb1ab831505df83080adc0aa91d534d5a9b3e266409f58a5ccdd3f5c35fbb1e33f952569fa5426a96175209e3745f3a6582e1e428118c38ffbf02350f669aeb1fa2dc00db7ddd58c2dd2c12251df270a642600dda74b58a40b2f28a6bd4562f530b2ab1ec48ee6f99dd1c34f3aae321b2a35246908cf82c16e6cfe5b0cb07d1a3e1afc4ee328813ebdc3eb16a4c3df4e4e6b2e015c9f76fa62d0b60a70ffd094ce7b427989a87f1f49455f1d471da7569049355d082bd691041af972a85780a0c025d12c49e793f0dca6bab81e3d26232e787b42a8ad6f584730625e77a72f82ea4cb6c4a9b40ff3a1374c5e3b18a8c549d83d6bb3dd601b0d7c7ef8ab0f636cffeaf3818ced8034513cd444d1e908f3b5ef903b2614eb6a9fd86afa1bd3f105d10d8064ccdb7b9c6c4ce930181d4394ade28dc92eb92d5e98fb8ce982a18d53a65b20cd01e8af3b38fd1e36bcbf4fdf43c60508a22663717af72166e4840f7b9c48e93d9e007fc200ebaf2158402854d7403f01a0763a6c4bb74491784a2820dea230fc171a42e08bc6d3e62218bc350d4b10777a5c98d0a6c3efb6c7a4869995d5722c306990eb95641c9b56643fe41d7b7e85a1a21765f83772f7d3e26521c31e2d4d35ba0b92bbbb1ef5fc1ac4166a4822159cba2480818b1e384507a56c9d2d8105550452d5fdf07b8bc341a4752754e27b03d164d436c880142da97a1504d2e7fdc846db303c9fcd0783c3456fbcf28744d1b236119241e0cc2c3bb690a99c96a97cfdf2b04907c6a0b061b20d9a691e1ff6f5cb430a111b31223085dd8e150b4fef7aa8b3c3b90fc97ca7f052ab6f441349e34b8742b7e818a7903cbb90f98d98a247c7e4462485317e172b594d65510f64312dc13fbcd36b591732206f510080146ec77861cca0186788b31172e90091576405242b91b51c19cd9763bff64b5d5a1308dba143f59de6ca44688bad69302e5bd45496345a87843feadcd257a8756d1e5dadc3f12d444206f7f3421614130072398b5595958e418331961d47a6845caeea9b3e381a65e09939fa0d1834a7623497043b23f8e96e3eab475553ab404d139fc94edccf7bf744326452c764e84ee36468a58cc9d09ca3c9d0d8e44de0af7bf7bc2be290cebb09feb121d452a1e0b9e5194415aa7894be55552e57ccc9e594e75753107d6eb9aabb94e07ab9728e70dbda863c3437bbaee90b3beb8bce23b1c8545d562c3926d8739785340383f045fa56dad1223a0625d8b303a0a1dbc1ed79f7f2d6c8eb7620bc6daf810bc1d30b7b88814801d5d261f6b8ec3a534be3e43897f56b05816575652a9c5224434fb4387a7234168733911425e6cfb180d15d18b21fe5929c7c217686190339b89065bfb49ee41a89e81c9ddc0859a4e49a97882b9955299e2143f103c43b007304f25022a736e76f8bc186c06b80312cc2d59d4682374f17e9ac110dbe59aea087f4bd81b91e260ec6f5e4eb66a3cd21f898a016548d2c41308cc08c23d2a08bfdb1a5e39e6d0d77e90fd91914c69b6d088cef954427c01e5c29a73cb9522406d3f4a2d9dc33f89f99489727fd165edcd09817f84ba66fa2b8049c5217657901c79c96183042902b658ed5b6775a478d192fa5b773980e46111df7bbe0c29a67aa9685ac1424fa0c595ab25ac9227d4a757822657c897b3485d37a9f6b7a5973033ce428a661cf59869888fe5ef0544f22b423c514a4e6676f1b2ee606ea5e843c98f4308bf067595e7bae4f592d973175aefe0e0b62da468c89a21cb128eb6c7663f0aafe5dcd7c184a1a866216ff0dbdac2969ae6cc3e427a689b0c7e8d8fd4997f9c841328e7da4ea3ef58e83df5429588a71f8e1949b26810d7652bc56f2c9d133481a1c89acdab1b7918e9641b0649896534075e413c51e3fc0a7fe5e10ccd563aec4aa1a07a3ddeb049a9062eaf7d0fd5682c9dac098ace5592145510e925c56b50dad8601fff48a28d8d626d3f44fc7cf9e7e6939eea317875ac62449445f478e930b495efccfca545645f6af4af3318418f15bb2b5d85fdc55e9e9e1e383e7af0e3eb439f9810e5259cb69ad463472f07b129f19373f880d00248a8cba9073b88128d88a3f03369578b1280ba9c6b16180cdd62f0aff1d54e55af79d29b5966af4e55fbe6ac69833c2db4f381e2e5eae13b16f88a3482eb339a4115d2b593d9a1b2f54cd3fbbebc4a9144d8ec107c38e513f4368a248952f863bb64e0fecf959a567e5440b4daf925952650e5450ebf1a22a41bcdc8f167b08b3b51a6f7441a0e1a1a1aa7bf744477377b09eede813dbafb0b7914a275579a524440c92603c8a2a007c1f58d08a03498ac383dd1db8301d1eecee8a145c5b86ed6bf5a25cc1908e8a9f12b5780c808258b1edcbe6b0735c65a92c6a8b97f8749010b39958abac988b79d92d7a18eb13a6617005577d05a9ddf35cac92395c9fcb24dd308f1f4b32157c0935c15852cfe803e6f24356c959797dcb5cccd224629e5dcac22d8abcc4f8552229d0abaa905a0cff594efe96d5588a2bf5683a2dd745ad283c941433c87db1486a81b4a8d7373b7a45ab5ec9240f7aa1fd5e167592c19b99d326612d08adb3aaa4027ca3ffeaf4424cd6758da25880cd0cfd9460c42fa8ab03dd5317faf371895389a8aa34b16fc4f0e32a3b7a15e09712b0103942a7fa726e266c4c101d95da2a9a76700704ef7e7359132b429b751a3ed39245f72a4de9ed5b63201a518b8d46e2f040ecee4284370841861a2685284fa653c2790cb405f14aca18e30553fbe30ad7d470f7d16a9de7a3077ff9c61bf9af560a63240a596e6003991d45ee2b405bb0b75a8ebd629aaf53bc497e262cbbea8b4aaef2646ad26a68ee02574c8f181d3935340fdf23fb32e70238a531533df81d0b3648056c96fa9f3b4e4e79f81e772c67956a6e5934acc65debc9d133b831052d824b94cbae41f372279ce3e9e4dc060376d51a07a5ad094370346e64352d906de6d816c2b9411a7a831a09163f7f0a01555eca5925413b8d5f87fcab6d11ad1a00b04b261e12731fc72a86a3f02fb36e1c314589691abdc1b701e4e30a044d3742bf5138c60b79f3942c64ccf0ec275bb75989b7e3a3f8caf56b6bd8359bd0d3b859b5a1fdf030f6daddb067f0daf4349dda371bce0c9f1c3db30f650bc6187d5fc70a8220f2726485ccb7112f64e0c27d216f588179998022f33cc160e3fef8943d57d18eb1aa1f078ba968c376cdb752f65adaa81cbc9ada77d34645f6ac137b4135cf9cfc69f243943c77eceaa26b70601861d7b12f3aff2cd7603296d4b55cae6a38c48d8ac742290b91a0947405c1965fbf7c8a634f4ba9e86d659e15f8aa02d296096401af00e2c038f942237cafc1b75a78a281a0e7f30ca3c053b1ed1baa0c9bfa25139a16f5ef84c998b188ade42b3b6e79d6edc5b5b1d0e86ff2a6e127f92ca917c32a29d272d9ed0d4d92faeee75ff58c39c183bedbcc0ddb873ad49cf3407da14e3da23c47f1a390d7b5bfdfec5b2dedb6be7075ecc631a283b1d7f30f1d63d18b751b031d86fa180bcdea5acd171e6130c42cea7ecdc9e30983280ba1af1b13770341555f78500266bae3dba4cd9eef0a6207d10d781913447b9bc6dfbce16c00da101e7b0db28023eeb9bcae5f40e8026ea6d9c45c68064256e70c04d337b540369c8e08aaedad130c238d7f4fe7c5d18b8e6ddb2490dff084e15466e54543f11e7c62c30edc254d203beaca2f342319dbbf78f9bbdb34f095bc9455ed613faae58ee99099b3890132abca65e305189d489eba232ddc627bee69e767492fdeabaa9c2493fc0663ca422426880d5dc93c834041931bbbb92ea4045fd104f48fa29c694ea5c41584e8535282fe5fe9fb4659bcaacb2a415500edcc42d53249e10508c2a41a8bd0ba143b70f3246014ebf6a228af86fcccae4b63f395e439b8b6996b9c9bf4d0b264e36f426d4847e260ecb0f35563b30d36c774089db523f81c12ef219539045535fd0f5c4dcfa405eab56f3f16fe52887949d55b9e1dc8dd99d1c3ad8cc5ca818405b12f4e0230435062eb057db19ee4d9142383cd92a98c9e813f5572d664382cb8191dde312bb528036d98397df8ebef9da6959531f9be778f0c32e3e63191cf464822977fd477ae205b276e990785d1859817014df97a3a7853d7a2d0aeaa5138b255327d0d341819e4d985f4aed02618e622516484233268843edf69531e0a58f2eb573f755809938737093e4cbee937b84caf5504f8f81c1e53b15e04e73319b3e2fd2146875e3dbc43709b1b8ff59b9b846ff414bc037bf76aefb8f16524abc9f0cf9e0b793316d18ec782296a0406fc435b8545c583050b7e8cd3653738f6820bce90f0a3ffb9e5f0228fdbcb361e195200e7930e82962889a91800d6ded941bf2f76fda6a6d9d033376c76e1589669b1f7871efaa7ad0fd5efcf9922aacc8896880210020bc116596114f494300ab5ee46cde32bdae26ff1db5049905abd21a5808aee7f1093a619fd37f2e997072f9e3e7a7cf027abfee35835d734ff1b706bb3ab165ebea4df8b5fa332dc4030af9904e7c4969c05abf17f08c735fce07763baf1c5decc76f10d9390e0933214b534fa3e995e3825c4bcec0e76dbaafe807160bddabb0d5d84314d790c5910f01ae45f0c16727aa1ef215615e4df7a7c00f7f7f1f2e45bfefb7decef0b7825a75bd63e8f0a61919ba429a874aca595f7c2d70f344b0eeb90602dfe18d26b851d3c0ef61b7a9f88477a73523bcd595472595ecadf6d2231f0dbcf25bc80aaeff3124235b7a8a426ba980c373d651433cf0c1ee298912dd745bde38a8275018031ff4870ae390362ead6a3ab3b76c8acc326bd320995cf9127a738dd2235006a1e9b1d8a28e64c597338835d8f47983f6d044344f3666b3924bea6c519e2133f47111a982f8626831b90b709359b276906149f130814f685d33015504e8fa32a6b63ca46e712e829e99b3b8e023588b196b312cb98fd4d855a30472f299bea17d8fad8fcd1376c742ce6a5fda139f298feb51f89f78edd9f54048b3bc67ffa9c818ee9dfd3309bb067e713b565f874b769cd60aabd48eac5e332457b4e40aeae37498af9d8e01a7c60409733162cd1abf9c83d57191dc49c93ef70cfe73be0fadce2e76c088150800e3cc110dcc70f1942cc3fda713de8b728550efe99114434c61d1969f09cea00b7830d9a6c09b411371c4607564aeb2a67d672dc21785de5a12f30f7aa5e704da878a8ab8b3134b2b77ccfa7f75dc34286a8abeb6262fc6c82deaf956cde4cc1528b05e837f9896a6a3d2d0b055ba016c9b42a957272da40906d95b8caf25c0bcb03c499c8ea3b76f2782b89dd88a31ed3bae07d30846ebbf0400da4a5e550578d14213e9a3433b17862441cc5cd7edc519598cf36608c1ceac823868c9ebe097f621e6bdb9c7e74f37f37bb9b9fb8b1dfef697413180532cb9b7673c12d0d69fe773061d1e4787cb3926e74e68be742ee55618df8083ac00b3bae6753edf7b661a1b5f0cf40ec5dec0747e38919d4999d9f63da7a8631284357c5b6728cbcb595ab728ba14d105e0b40b223d1e3c0bd3f6d4afe589b923f2d3d6e3767a05b25684c694bc47c441b2eb19f7ebacbbd623fb65fec7bda79b0dde76d39a6da454690d21c43c93908834711cd591b26d88e46e20052944356a6fc2ab95198ea081cf356b2ca6f06d412a3613889d8171238f80dc61e79eb63b3afc85d55f27293a102bf22dff1c8810527f01698437459469ce58e46c523e1ee34c03fb4684958d9779a4ce7c5e0ddd419ddedef471facbdcec81209b32d03404c8d452f01668b42e2acb55a8c08e3bcd708a59bc3b261cbb3c96ee44fd31ff3df9fa63f1fcdf447739e8f67fb63a06d65fca3b7841ae689aa0fe9b6c576a34343ef375b026decc85b887f77b320761268f9088eb04c9953c31e0626955d5ac262173735e4f2d7443d44878a5b0eb0ad8eaf4d47d7ad07cf56a64d9e2513aca2d817276cf10208bddf6cd2646e1ec7c95ccbd5c6edf4bfd6b2ba79257339adcbaadbd1353afca8271d4310d9c800ba77cfc0d4d7b947755d6593752dbb1dddacc37353109c5b2eea2dda69686ceef06cbd6eb1cffadd0db4e28f723ff91e7a810dc4ef6c00c506c2fefc777d57a76dda6a5c276e133819057035abd37d3d2617df801784fb3a7883672d7b41480754f9e935ad659ea35f2393daae12c5033009bd7e26d37fea01aa12085c62e52cd014426e7f239849067808f973a7c9a54cc23c28a311a4425f24b5c05828cc453493ca6465c33b2ac5415119e46babf5088f5eb050139e4cc7b4c882de0b3609dc22feb4bff1906a5066080cc2cd1083b4c06eb7cbb2cd8676bff362c6756d4d561c17c33608619b44309e5fe623580244758344929ada5c0a3e583e91409c0859d4d50d2e3fc5104bd2145ddf81d04c54a13a995ec46d001a12f51f6b67b53daff5ac1f7e7f3ba63f39eebf17c7a525fc9fc274b7507478afeaad0c387b2fe6db6a6005c07c0b2b6fc431d6d9ca38dbd9e6bb789898b835d1fb7393e69347c84cb083d6000b36393d3dd93519cb9f264eb79b3835def57f5f43a4f7e9eef44f5ba13f6d85feb415fadfcb56c831b83c59aebaa068bf92d5f7e5bad0e2d96a457ffbe159c0e77999155dfc23b9f61bf6bc967bef1140447f91cabd07e8436329977ab5da43803c830a1fc91261c3f3fca637f68d8ff3f4ae4d447450d420f0d8a6fe77dbaaa57a030c7f4b3fe98c3a67ee25bd05b25f6ae41e7f34f0351c8b5f3500c0c7b1d318830fefbf2110c6bfd7f3abf9207169fe1857fbdf2d88414674814cc45b71b1d30f2899a7cb601a6643e541e565b262f113e1521e0e9edc89f0c2ce23b68a87e10514ea78d74e86132d90de5a1fbe40a4e4b76fbdc68893de06ad33580ed963c2bb5386f4f6a74fec9f3eb15baa27d8cdd58c31a3e726574bb3249b5f856b001bb5dc7113b2285221f6023d046b6476f677ae3f4fb0e55529b1a8add817114003c1ca9b6a97a67290c3f09359c464e4df78f3668580f1311bad2b22f48df9d8b6bdb3ffe978f9a7e3e57bf08360c79e78fc807bf6fdb7ea9e427e8442833756715f142039c4c524273a6cb04a091636c48d1dc1d91fbc708105cb477838f18a434e74baddabca68249e65cb6c8ab69672915c6625e4997c72f48c29698dfd08359926186d351115e46a17c9acd6ff4ff1d97399067adbf77e12f9c8ba3e270a27c58f9b88b2418ebedac255fd8e92ddb92fdf6e12eec371fc0e4a309b46741bedd7f6baa056b01b7540db68657c346da58f31bb18391b1513e967ec00b687aff4aec0fffd8a1ba0bf31fef3b174399497f3d76864d47ed369a31fd39ff48323b0df34ceecbbbc637d768781b1ddeddf1d7df6d96905ba1e93662929e872b62ab30253e2a2264e14c952aa5532954371381337e55a5c252828ac95144aae922aa925815b96e93a8797a234bbccd27592e7376200ad924aa2a51b64b4bf92f9b45c423ea4b414aa1c228091fe47ff0ff287c06517320ffdd73aab64b753ccab64656ec19dde1eaffdf7ec3201c2d580449efcebe6006efdce170d984ee56d9510f2525673d9e95184ff7a91293f7303b47ed7c77f711887b5ac92baac36f70355877e0bea053fdedacff6f0b7858bb1f9c60d24e0f74e4fd77a6771acf13bfc51577058be949582cd6e410c47f46df88beaf4a82300dbec07fe9f2a614525ab2cc9b37fc9cdd8b4bf35bf49d21faa72f91faf8e9e377b9855e5f2175516762470c0d565258fcb788bbac4faa6fa3b0f67f8f754ef144813ed4dfc513e2fabac5e2cd5c8d5e06828577addf5366d6be76ab8768442790b05309c804e43c969cdba99db8f1e2eecd7977ef5e1e8759de56ae495c3983621e64a4ee6b907e56739f9f1e908be734cc087c362b5ae0f421af4dab02a4d8414dbecbb90e44c2bd5e9452600fd8d1d14bd59f5273a47bd6142c128a8c127c9a7d90ea0518761990f0dd6830dcd5a162f4b4c2b0730ecc0ab645ea455b98a0dd994f9839d65454a993a5e94283e44082252cb075367cb609ed810befb55e7b27e922d65d16021d882172bbf658373993693647aa18ff0c7e57295d4d924978c7a9a487d9adc94de82838def93ac02efa5083fd1c5393462a39996901fd1df3f087a64ca5a06f0f74c5ec516f5995ed437401bfff8c73fde6066ae1209ca9dc8a6d9b1bcaed7958ceca21a4b7cecd95ee0f027ed00195069cc0a945264ead1f1a33a4f5a372a14c6887f99cce5f332952faa725e25cbd68d1ed48b807a9a1517b74061552200b618c6ad2388e1d896459abcfaaf75125d1856da86b68db88a3482b3399bfa6ba4096ce415b7d0c213b9aae434a9d127616ccacfa1adde5c637ec48074f9b8cccb2a324a57e89f188cee23fc4b5dce9b94ad2ee7edd36285e1e920e8b61bb02268664a9a6d4623911a3458e29f2ae586103b6a7806544a7fcada68e1da011d8a17b94c9404d9b9ccf57d9ce4257d91bfcc2e136034a2fbadd8197eddd3d74c2d3b1752a622abed991522535dce35e9fe904cf5fd60eb61facdfe90914ecbe5725d80e8b42d2e4d8b0de373c381d10483e98bb2126f22993692e232b94846c4dc55be4aded00d868fbfc9b55b84a5cac8485ca2bd9cb39a2a5bae72a92ee75e1dbb1588154fa498264b993f4e146d04ba271e16b33276e8b952bbe19cdc8e131a224f57621f2e4a504a174178f22f573755365fd4a23bed89073bbb9f0f5695541079e887642a276579d11787c5d425bec2c3a35c57532930888312793695859229e8a031abcdb3c363f359ccca75414666126050262c31cb7269ac0babb2ac450a4730981eccd0248d7aaa2b299d9d016961e24af68ed3b17758740d48af72a8f8b512535c65cae6b01f8dc4f737fa18ccb36956e73794b1e8cdaa2a5783fa6625d51b7ba72dd1893a2bea12c8369597322f57a027375aba2101d534381e8d6693e1528e1cb041560cf460cd10610f1c1528873c826432dc7aa9b1a28c2266b8977fce6a70857fbc90d30ba9a5dd2ecd7b982992dffab17ec01484a91e7f0b261cfe3f0411dbce52cf212be6af16d9524f936c59eef6ef664bd2b5bc84dc657d717e8e7f3d2e0b2d17f5c532a9a70bd48b607eb70e4f76d6d963fa1a54c0184894bc4fbc9448a87deca36fbb7a55277536b5bfaeb27abae89b3b0ba9656cef7dcdc3ac6e67ad986267ade48ba44a960afe0478cf12807595d50b84df3a7842c079562c6495d5ea69599a8c9d9dbf4e9289cc47d5bad082f96821f395acd448aae5c8abcee00001f1ae58d97b2bb4ac179919bc09d5e760bea8ca95a66145351c99b04af4704655eaacb819d0278e01b2ffb87dee5491b7c5872d32ab7d012e7b7526b745e6a6d6ac171bf6844fc47e443f35c3ab8f1752acd07ae1d18b4350d525e25ba485ef5892272f04a2e3999ac1d03211fdec6bd89f9c9fbf78fdf2e0fc5cd7726f23e7b0ea9feafb5459b8b40f3e4d753d787dd16814da4e78f57d2ffd73cded5dc6d57fabb4a13036b1df98df709ae43969ddc2b2be38d1adce86d3b298267517b285f6c4dbb782266a010f9df63d9a370b2ba1ed9cffd4716e410516727529f67d640fe16b8da15b6025e1c3901e87f6f9c3b6fed2304382e9f9893dbb66dd9d63240e792cf8bcec1bd87491e569250b2a46a332f3f1d47b6adaf312a97a33d17c1e0fb56140681ba502ffe99d66d74011311efb0e621c44c68e2b0dd182c93c16d839b90a45999a87081e739657999465deb7da90f09192d7d4eb4235ad9197d7d97a399115475acbba6bc917b1f5244b9f91317dc4c6f7038c17d8725a4bbbd3bbdf7a03f98e8c0094e7a2a51b0dc5b10944335dabba5c0a0644dc17a77775e19be05817efde880c3dddb5ace88a7d1e9728577fa8d7dd3340b07970df97c7c64280f9ac569f7d1f8dcf3a605b305957f94f0edbc2617978b40f65af0ecdff5bf356378d8fc9587de47c6caeba3dcb34a1c1787159c8a359f7e4f4ae89a5797a57731a8a27893fe8cfb31ec7586cc5ff78aeea46f187b154c6cbb6e4a7f08c2b55995fca631e2985ed84a0b05b977d315d57952cea20e28a6f4bac371fe0cdc002acd565b7d1782cea720fa36f820d49592de191313ea248f1fb8f09a918461498ab6950189d1eff7fd36871bc33b44a782967fa8ecb87ea97741ffb637adc0245ec13a3719feceea679f0ca301f6b536877b607cf1f48c3712553cfca349b65326dcd267ce70ee5715bca3af91b9a6ee38724afbddfd3bacabd0f6a91cd74951e27baa75971f1a8982ecaca1b1eb3533fafe4ac6f8aa42e644aa2ac286485733bc700a3f8dbf2594a706cb35d9adfce7da22c1ee71938b94105fa69cb2ba9348bd878bda4319e9cde35fd138ba2cef01741d65c6a8f85b24baab9ac416da2ea21fe62c5c67dc6ba46fcfaae0f55ed49436059285ffa12e4fff3322a0b328d32b3ef593c502b66df66b22afb06c8b8a6ab0afe7d82118bba3cca012a8899f1f43bdfd8f90e42a060472f1010dac88e46660e6265bf534503025b638a6c74c3d42dbbe01b4d690e2f6545217a26eb5ae472568ba9066a6d86ef10f2b50842cb00bbe85cc97ca677108e2597b54ded8e2e9be2f42e36d83f9fe44971717a57c87a6a8df3eeb46c2437361c07c6555c62554cf1664004a1b96ec5b6a3f46e2480163a94a24305aa8776bf1453787b35818b28d619e760fab8739f7c67af61c5190a6c4b8d4643ff78ba78a691bc995f0d748d9f09a9f2aca80769a692492e0785bcae07795648f18bba1e24bbbb37a30418c56091a8c1b42c2076b1f163db289b9dde4df416b432e3bb0f15931cb71aa6995ae5c9cd738ca57a7ad7159ddef5ddf4227714942bd1dc934efa41729554527c9b7cc7ddf30c8bdcc41c1fb4724728fdd44a3cc4e21e3819c889a3611dde8afb85317e3d0e6b329e8996e9a63fdfd84fc0f14b4575c91ce33c5efea0c9ccb7e6c50f8019db8121ffa551e08fbac47f1dc3b65c790321059ae9e1e3b250eba516fb5148700b33c51a76d3dca10fbf2d26f3e95de627509418fafb5bbd26df89725dab2c95ecfe8be2dee648cda13d290dd30bd3dc30008f895e2d022281b3a6fd914fcd805fb6ab87562d1a8d2e3616a77761b73908b79f97180e0c638b37c404768a3a7eca597180892d671d84155aca7a51a6d01c378a9ba7f932b65f566bc5437260dbb8330edd1a3770f9f7e1f3efc1e99b66f0c601d66ee9b07e60621ddb6d8eb10876dd7ff79b3838864ba458dac11d53ffd93d695c717935603cfde0ee7ae67c2f2b39fb50d8700be617ec45b2b2ae0c74fbe0d7e2a4b8417450f79a0b444f25d821541eb9dc9b85199bc1f703b9327a51b786dc511d290a47adea82ba1cd3220c33f5129f0bd3c67dd4a75248bbf11b6f540063fb3b95ae7eebad0ac7150cb571b3faa5cc8ac779a21458ce741d945b747a53dbe6c3357b0ec646edde3beff4738d86b32caf65c5848e2cd48765b431877a9addd3bbe2f46e10aae09139a5aeaa64b50293830403992acd912037c5e9dd645a6797f2f4ae28f5edbf0e05a1e7c9654316fa7477dbaba22efc549f848f712f919871727a577f1cd00e3bbdeba2d2372bfbedb95c747a7795ccf5d0c78d8aeeaa09053047a005daa570ed0c3ebb3144ab37a1f863b1881c47ab07d05fd537793010f8e4a443d350ef675371da8026aff59943c5f0c3c976ea11c0e500cc375bc99c69bc52c3314b49f099b9b403b61f5c95bacadc40f0172bbcc9bd61286faa5634dd2099fe06c114e4529fdefa76bdecfaf08fb012f861ea970386498a2554e22feb5288aa51831ffa09e8307f5bd8ff93e461e213bf4d240ef47d4c2a05e279fbb621e5b1c65eb4e9f79096031d63f30beb8382e9b1f4ee26423f098073792deae4421660ab301611c3ba5596e749f58b1ae9a683ba1c54bad56a34c9cbc96899a85a5623f0011bfea23e79fa60e70117b5a59a262b1ba50f86637c9f8db3f5a87b32bcffd9c3fdffbc33fef4d777dddec9e9e9d9dbd1e9e9e9e9596f34d7eba7fffe7417cf0b2b1e83c269dfebe0a133c30915c776de4cc45f41762706c0675263e1b327bb47c6a28d9d8ce95f23658b318f3a8f51ba70138a7d71e74ed7e3780f3d06d85da2695044a50c251c1753c6f96d070f4379c263d0fdf0d080601cbc0683af88f733d8ded5c9b2cbbed03f194fd2506de92d773083ca90f78d5dbff7ee79e7eddbb7c8421a47109b8acfd369348c938fd9e6a065c3bbe07b5f913edd0d2e499feefefb5c9334affb883724e29e8dab047da7db04f88abbf58a5f7aba27462cc2d346ae6207546a35e47566ceb6ba5a4b3a82dc88f8e5c52352bfd4b28126b5052366feb16cbbb45e5b18f18f9b9742266c6f84420c287a6f32bba1e5d2e59c765b7a677c2c0adfb0b296c2e8c41c45798eb1812919b778408234d2babe888d469f9061f0b364b5ca8af9eb974ff7b919e4202d97c35f204411d884368c4aad11ba5ac3a8ac609f679a7e5ee1575bca5e50d00789b22e588b8203fe953713827e0ce1f0f65a0fe990b73566b36695d9ccab33cb2ad9a8a43f72ef63aabcd7483db869b0d6f057174891e439f66203682a0cb09c29cc5e23fe26c1361f2be1817999e46bb0084ff4bd92e09533314df27c924c2f4425a765952ab207a60a8fc272934d50796ded2c20c6ad2e5ce99f496e44a731c1fb557460507adf74c4fe77e2e45703c429e4fa625a5f8f297ec9bb33d477a1ce65ae275cd1638ba69623c43d62afab0f924098b56f674ce1d7b563e8db3940a741d409d213d869820dbb81d2f1b4854d2709d348af8349be0569b620ccab81112af54c80e322cd31b76838e7133bf6332f8aee1dd3c61bd67680c4be38396b8ec434c6a0406ca13c9c8df5ffbde3018e1aa42e2825292dc56c76cb5af4fcfc395749511f972f21d2eaa33c17fb76656c5b0ccc63b5371d3fc27000208cfcfcb72ccfb3622eca3ca5dd0b1ec99a8938ff0f5994ebf9c2c6e39d264a8e1d94ad29d33588e0a8f172ba61cd1abaea54e6b2d6d37b4c58543f94153463086b236536324ab4d2022b78adc48a5b11697b8e7e33a86dc95d7023b90cd56299f8d6c131b143c4fdfb5930609c9fad79929d0d2d4e209f559304cd7f0e3c85e1cafa7e32006ff3043fde4556f8967da28f8ee84609b6c7fba20fb8856de44df476aa04356b56c94746afe8810dd59ae23b2f3eb3f09b8a7d5472329b2dc42c2c8903e6a1d922725656ef4f001c5f87c5ac146ec5352df098c1ac962511b277f4cbeaebbe3faf4da18583c5f654e176a9db641d179ff58eff2972fec0fa67339bae60ad2444beb1a1631365991dc2eaf4dc233d5989c9ea52a63f6bb1401f119db2e8f44547cf55ff5bce661dc4586c337aada3eba1e76164a745a28eae0ad2a3dd74bdc627d9194ff113cef4f42ea1c9cc947ca66bb0cae80b95155309e1f0590cb415f504c92fef8bb03f30c4eb385d8509d38d6e4c68a367d46bf6f5215347797a78c01f2fe8539729a79772597281d0d68588bdd9bfd82b2413417461e38c7338198dc4b1541824e6f0407cbb2fbe1134cb9232169014bf489855cc6824feaaa434be5f13560594469fe83f07f2ebddf42f5f7df360f6d5979f7ffec5eed79fcfa4fc7af7cbe983070fa693bfec7c190c42c128e43588a653a9e5445527459a542905b0010fdcbad4726c79859791415e26a9ac18a8baa4e81c524ccbaa92d33abf2147b6b2185888b2b8ccaab2807d179b56a006bb9293959e93164bab6c32e29d8f32a5d6528d76bffeda4042b48befcb32974941c9a420fe3c25b6e27f0fb55c7eef9eb863c2d0d7e5a42dd594a502d8fc143a177229cbfad8d889f10cb6f83124241788b9959af081ae8da64eb0f86c036d59dd911d574b562fea09342eaf56729a69f13f5112231862ec253260cd669516da9849abf9528341962704113a7f3a7ef6f4f0075d8bd4211863d10d2c83b80e533db5b626bec8ee1bc921016bd90e1269209b490a21afa77285bb79261274fdac4b3b6085b1a7641a404ad7307148b83e28ab6c9e81692d308dac2c14afeea397fd1a92f1d31383718d404fa232267bbdc654328d8dc93a37866885bcaedb3bf5f26ac6c5159f5e78fb0d446e1a44891d40a8c3e209c494822b889f0b1f62c37d7f7398123bafba99fd936d854aaa75ae6731d8352e17911389f566cfa38cbd9ec279e4ea68d1d0f5061ba4d1394e963acf2cfe26954c2e82a3836d526cd138f52952d771f9a45c4240b83e5da31537834d211dc5b364e5f63e7e3743530e95713c68d0510440bd5aeab5d0759c3c841d887d331e480b2e1e42e5931d7d5a7a056353c0b5db6480efc67f92a567e2ed5bef2986e31b2c7e8c074996827dfce9dd9ef902006dba491fea3e75e742f5f278dbb7d1156b524e7e71e613107882e6b6ebde8e9732cd12fafcc07db64a302afafc8ce8c1cb9e9179796f6c471e1942b4be612567b2d207aaba7f7f6f43bdf54a4b8e55b79cfcd29693966f04bcdab3db9fc5c398fdcd826512fcb148d21414a4ba2747a97d7e9930231e8b5dcb4f1a2722a35c1c4db814fee661d59b56ed8592550da3322af3e60e32ef20f614f375ec1d28efb0cc9926dda4621b807d7cfb16f7a111cde97475358645a9e5a0b613161d20a086715a383f2739e51c0acecff1baee1a8b87913a639e069cc24ceb22eef8d51814761de155a4beb89037aaeb9af586b3b23a48a60b668b71215d707940de50f1249d17f2a6cf3a3eb9903767ecf522409b41302e2522ada971f36b21d7ee452c913db37b2745059dbc7d2b3afa60ed04996d02d12976f5785caef3b4e8d410ab4b24445cd87088d2844b2f2c93827279d50b490a59cda0f5af0e8ea5235689962b6a594174e602ae8243ef2642173eec03e3883e5e6479eaa1c1db3350d0d82d98bac8db2d08c1aa9b4311229b99d5c2755e25952ceae7658ad40d3aaec060c8055ba521852d298352300330288a8a30c23314a2e7e7635db0df0801ae3f7391b9861c1325a8e949e119cacde63d1be3a19a9f9eec68a19cd810d1ac9aefa868eb1adb2aba4a900155e7f4d428dfb86ce4d4e9ab557e735cbeca8a792eebb2384ee688a3beb003d4d8ebeb938a4d74aa501904919c1e8a4e47803a7d086715d80dfd15ff7427ac2d8683f65776d2ea92a952fafb3bb4aaa02f20e9ff5056a0383d3ca0402dcd65cb6666d138f1c0ffbf5a48b6c3c202dd092d2d5f519afa54a9b63d3f550aa932e4f2babd2ee9dac6d440939f2e5046b21dba4f1e57709f69f9c363db23e866edc6f1e7c124b9ac0113b9c3f79095ba4bb3eb8b76e8b113dfe3150423a2e068921fa33ae29c717a3364e16ea89ac4f61de5d9122b1c51a9fdcd0e0468b1e960e9408d4e1ffb8991025f8f463b8f510259da41ddbb272675e93ad7d3bb0f0229f88b371f38d3a44ec61a5b193edb8e7e5165b1a785e1afbee8bb3da68176d7051aab508ac5d72f0fad4f6ff73f5e1d3da737e46c76e346d4ebf57ab02f3f1b99a3e0dd7b6fbedfb2fdccb2faf8bd5a64b934006759a56a20ae8d3ba25139dc104d5addb487ed2a5a63626598a5bbd57a9fe1a600178c9d80d94605da4070b4248c72303307d75364e46b640cdbaf27f0012c13363d1c9a15f08da8eaa6f4f6ade8f2096e90780d6271a0623f76980c27599176d1828f76b81b591f0f6fe77a0fa7c987c0a9ab75543cb32649edb3689944bc4fd628187320f474bdfb7b8b18b4e72e6c963c711cee72158a0f588e6454c8ab23cb254dda17ef13ff38041eba6fb92886c78712e2a3fb8c93b252c64bf7036e1a79db893d4db849a1e9f951fbd5d1a02ffa7ed16aca21a2ea0cfae56e55749522c6369544f7833a990b55e66b72791587075f0dbee96bee335d80363f118ba44a459e2db35a57d002f527a29c896f6125bf2371b64ee64a6435eaf750f9acb73de45b751bf74e63e76a6407d713570637b3094a75cd0b8ab757cd630027288d18d2b7e8e993540abe4789aa0f3dadce0605d10662d4f4f534538ecdd36f5ceba7bc6347a874fb730f7326bb193ecd599030fb137a5182c7bcb38eb7b718cdbd6b0438e14a297fb651fd5444471434e34f781fa0f2b945f132188433c10418574f372f15612bc29f9c5b08a1e27c132ece9bc838df888df3ec6ccf7fba3ddf8891731f259c4971c49c3730d3c88eeb63f23cd04d71e0be3a8a5ed6cf49c46fbefb5ad437b7477321dcc56a2ffe6c37fa4cd77876782c9e52404c7a0abbbaba1a962b59202b1d96d57c442133d56899d503fa315c2d561ac2a375bd282b715c4eb24489bf95ab951ed25f55795125a78516bf46239022413f3a05e13d2b7e41a3a0c90d30aca952f6156c346af791d6db7b00c6c01b39ee5ac957c139607236e3ed17f294d32d7521b1a09cd97c1189820153d80ccbab2c23e09dd9d4878dbc278b2c4c4698d572191a3090873788993f67f58224eb630356b781708b6e46017992f63566cc10b9eb1a5d6d78d3a581989bee86677caa69f881b9cedbbb3c684f30484bd2402dbc621a9cd3d9b4d572b365c8bcc526c87415fa5f6b59ddf4452ad3f54a465ffe68203ceda3ff9adc3a9ca21c80866a50c944a96cee5e870c4c71728242991d54a773d6082b059a557c903f5c626cf36716c2afbe923c9848fc0001528b9f1a9b67b402363648a5aaabf5b45e23bd9b96f6e943c33fc9cef055c39503f1a5e24ea0fdc2ffe213a4270a96fa5a042f6ef1d3d23b2308b99bce067aca39b161b8a88d3e16c2fd832806d3fc9631e38bced9d6682d4a7864cf8ab5740dcc97367b3747bebd307ec99dd81617e6d9451fb9b6ed2d2667ae097f61e23be7f42e18b232ce603abfe58914b6263e626836174ac94c48d3352346c05bf33fa67bb1dc935ea6409fddd9fb00a267ea1c1a8281faf919bbdade71e521c3e77c91a956f8d099343da9cba44dc5efa989682875f9b85ca2c3b81bc15e58fff5cba70acf12aa4217a2f024c2af0d69559cde753a9ed72f9fee3b1a69807c5996f87cd0b194820581b286bd7b51272784a933bf9d1ebb0575e2cdff2ca233f648ca81f4eb81a6e8519aacb4b001c16ca7657129ab7a80f007cb6425bacf0e8f7ba77ea27087eef04679cbc687872a434ca80513fbe23769bfecb5284dea04b6ee964ab8e922a994acf7d7f56cf097884a0e3e78f7275c7f5745c3f5d6f31d8469bfa39b34a2b47f2dfe43a6e2e7a4566501a6f44fe301d88dbc0978ef0b25814b92f4f98b4caf1002992e65e5c8b9699340f9994907868f82a4e4eb0611ee4eeb8e937a316af1698d26e6eae8aa80c336b0bea34a3cc93d3aba280b1341408164f606ba2076368766a1ee80d62d105852cd3d7775bcba4031f09ca49af7f8f911b425b724f3f85acd5915b24cc52a3cd3f5dbb7c2fb8e115b3b6c64a7354d12b9ba1e841d169d2d1a3a9ab1660a7df661a8e0e536e7fa7c03d14633c3349e845b322d45d1c9eb0727002d3c38c1d8b0026bf52e32506fba94c7d6036a97ef42de88ac8091f89d6a304830d64c17b29c9b29e303afdf2618ea05868673a5ef62a3c63fde9975e4e10aa4221e27f0cdd6d46ac8b88d87f37bf78230f676a46c29280099b73e34dec68d2ba8c1704d03a1ede91f73ec10c4f261b24c1bd9855d911d255cdad0c65b5fd13a8e2d74fac637474b03106fac582dc52a995e2473095e400802a176fda62767fd3038262e03473b47c4bb1e9f2f5527bb3bc6319a088267cede5edcf90bb2fd79b1d51fade7682cfe065fbcdfe0d456d6e55e53e91bd2acbc198a27a554e0205e5ecaaaca524c6b816d3bca6b37d3dcf806122598b4cd5aec03cf5cc9bd76f48ec90a0190a8279b74e3af8820257e459dd93b9c432aac4f9d1756180ac95432f6c87021517cf50d109c11c3afeff6509e646f0c568481cd4b1b372cf35f25027b6bbd211b76f2d8e74f893ad41d93bd41a4a19749d7aa3eff9ee46be973652a01061134423f9b97369ad81ddef9dbb77633e16780005b3becacd7b89c799083cb0387b6ef0daf798560d863530bd9a8833d1a8979295229577d919645a716534d68c9a45cd7222fcb95120b59c9beb89240819888463c7a717867dc3e464e3e88476fd86df713113744b43128bdf41cd1ac12e40d6a3823f74ea69010e4e274b77fb7217138516221a7174f1e5b837827c49c9fbf3c78f4f8f8fcc9c1df8f8f8e9ebe3afff1e9d1f78f9e9eff7474f4b7f373d843b89e38196b28b5b155607225debe7d8fd64333d8c0574a8308ae3dce6fe27dd3df38a3e3499514d385c89458171aeb0b2d568b899c261a9be073c6dc0a4459e437e0a3620c8f4723bdeb5d0f7d0885098ac5b24833d3aeaed6121b67054f8c3364a39115d81910836423537596e744b6a94c52cc3224f36c99151803e32a5145a7b6b090dbe637f06c97c9d4f5f204b7c42229e6127a594aa592b91c12f93d9197c765992b51c95c336b3dfa7a281ee5aa14cbe4420ab5aea48506e82108222da51e8428a7d375059bf74a0fd9baee3937d3b2b2cf4180660b2fc1a74fb12ad1c99ac6dd70b2f9cff3ffe45e33cca27c34127f975536bb71065f80ac64525e4a78b49a485944b02853d17df2f8a093f6a8d32da9b46bfe300fadc632bcaa38ad59bc225f8445a812b540b4f745a1d15b6be9e26a9130aaf8d9fa4222115492b2a4a089ff9544a367728e2c5383322d9294fa880784e9c1780ff6adfb653fbe5ff40c1e1f201f31035a80ad809820d1c23c9e1c3d139335c46f95d7720a769aaa84a530500c1ea6496126334952b1cc8a6c46174891825e8434f5195de81c0f83996c4a8a34fd458dd0f73d2d9743379be132c31c9d416aa7ed61f19d6b00c5252a8c9646f98a2901f1692455b2ffdb68a66c3632e0f44adf5353998a172f9fff8872587d5552a04235869a02acf4ba3d10a5f49f4fcaf52497dd5e28096187ddac58adeb5752a6dcd242cad4890db6867749832041a6602cbaf7615f3e81308e2c4a1f74f2c3ba98f2c802beaefb653991552dfe43161759a13ae2f3076292d59088770e7180d5c236b5817f6988dd2efc715fec5c7f2dd32fbf4c77bfea89fb02bf7efbadd87dd0eb09714fec5ccfe8bfbd3884ff143bd7d3afbfda9d3ef87cda13ff4910befbee3bb1fb4dafb70d043d86ddafbefceaabaf27bbde18bed443d81642fa79f2e0ab2fbe6263f8f65bf1cdfb4098a55fef7cf1d5f44b6f0c9f6f0b41e361f2e597c917b39d6f023c7cd586079266b02aabd113238d931dfc6f2fa285756400748eff7d267ea4ac60ca243c37b480b467f3e2c1e10582d28ebea04ff3b5ca2e654fd49a895e839828baf2da7c773db0befe0acf29aefe73ece2e5c1ff7a7df8f2e0c9501c2d97590d69dc80b7d210ae900983eb495688e7c9733428a68c5a7a830e5d2f23f32758d072a762d36f20bd127e9e25f56238cbcbb2eaba9dd4ed89cfec78d92359df89deb7a0330596f01ed8dc8da31125272e1669402a594a7d3786c11397e90100b9aaf138ce6a31358efdc8d27a2dc842eee5a12c8e2a8e1fffd19aa5b2f1786946bc166eaa1896c318b5983b6556cb2544da80528d29c26059a1b7e467e2385b4a886b94cb6b4ac9395f275552d4d2069c38ea623cb108ff350cbf4bfd63528a9750e6e9e2f3729ae42f4dfe7f5e4ddfcf0c9af74ec3b746d66e08d4d71a44a319428377929a7b3dc60cb397f3472f0ec7e6c8e194b0cc948277cd16e734ee948e2e0dde22b7c60100ed5d5ffcd21775e0fa0fb7ef0c94985572633ce00762774f64e23bb1b3270683663802fddf2f14738ee3a99b89fb6217bd293361b743b3716d7a3cf9e56caf596c8a6cadacbd5606ef92de15dafc67f0d1ad23110ffc0fa8677428884ed9c2c39e77ce360452e09cc5e72d9a07bc5aac6733b058803d829498dff4e13aa42ffd435e7de47e286cb8696fff1fb2dc01defd0fb45fa04953bdf0ce4a9ee0bd8c42a3f1a32dab0b50cfa1c73684ea5c96a93c85c7bcae2f8e594d23a5767ad7233321ba5481ea93839d097999e410d128cfcb2b7d6f52528ac7af5ef4746dddc51c82cbc92bf183e9eaf42eebe5f42e2527f5bd68233de963859cbfadd113f47c9964b9bea807ca67aa8b3185491178b727f498b0c81e092331872b08deaa26525875055ee08b12f35ad4a5484bd21e65f5703884b63f4bb33cac19f3aa36adf1caae4a08bf8be64589ca64a5c1529e0b1bd56628b259f70eaa657ae257311c0ee3d69df33d2f61f15f67592e8f2e657599c92bf1bace727d1c9945c6a800982ddfe64470a98bff9aa005d5a322ad6426fe96a8c57491886e729108cc09ad85b9d684d1367c706390d0a3af84824fdd391a6b348541546ad9b4f4de4f1bd8ad96450a8f3d63fec344862b5737f0fb4552d563ffa789c07695ac5815efa74ba565421aaab1f7cb7683a1b5c43ce7a26d1051ecd5224965d555f0cf3124d9d544eabfb343a15ed27ce8b5aa49a50ae3c987580f5ff209625f38c8aca61648b2dcef3cf0ae9be7c3b9acb1c60be3f466a1cef3e1e3a3672f0e9f1e9cbf3a7e74fcfa552fb06e59aa390ed802392c66e5d372ce7ac3da261c432eabbabb5473578212c752cd5b640484c49fda03e41259742f6555cb6b1cc6ab6ada17b32a81670bfbc9c3f70a9b71841b48dc9ce152d9207684c8463ff37cf8f78397c707ff387ff5d3a327072f79f359a379635400e087978f7e7c76f0fc9881b0eb98d475325d50731a765f5c2ab6d4f12a335e25cf8a0b3341aa112506aae3a8c1829be7c3a787cffff6deb4c07afbadc440a0a2d4c0784077b29ecd340583ec7e587c4f3f25fa16a817b23ae426907afa5daf2e0802e2b3b085f84e20e8a658351a89834b59dd885a5f06aea4a8d685d0274539136a954c2591019c852826d557d9548a49369fcb6ac8e060dafbacd6d7a2a5a21e85cafe45d9e4971964fa7f5c162ad33c03938f2fd7799dad7289c091d72fd67329208fbfe26b85a892882c0a75ff435e26f5e70f38fe8c3cd544c367e2815b340fda50c99a9a47c2d179555bd6181b47979833604797eb229b95d5f2a8b2ee65f0d2e9ed76c8b16fdbbab00d713bc616882d11adc0001de3b6b6340c4de2594a93c1ae2d013f9464294f7628144c020fd0f069973e9dfb4f5c0c10ee3cecd786b9b638d240c20073ae7118fa4044fdac893358ddfe22b994463b9a3aeff23126510c7bf4645a7f394e74dda102abf307bd3316fcdb5de2dd03a087a2f5fba3e835aed107e028625dfabe582202f93d71c4a3eb6cf2959faf2b090ceaa65c57a05d2be07127378354eeb521a9c89aa1b33eef80e16276dd07ed320bc2801592f34e60b61ddbe4fee4bce70877bc7399cde846eab20ffa29c7ccc1618f9625b699bd7afedec52b585d8afb2273b735507fe92ff1617972a219160e490fee230c0b1efe97ab960189f0abad4713d98b4fae5eaed8845a2f0d8fcba24eb242a13906be5996337a3cabe83421c30a9732c49e5a0569bce855d1c4f0cc931b598da1deee507c2f05bcacd6a566e9104bb700bfefa3ee6e0f2a3d685422456539135a923155ddebc85fe575b25ce5686a0228c491b2079c02be0ce1ff3b78edd475f16b9282177757dfffe91c46008b4489126c2af1418db7789a1517dd077df1b96e341a89a2bca2565383c67a514949d3d31b4683d233b0f7ae51e4c684a2c28f1a920dd4244d30c1e68c30862085ce089f8b1260005031543fb26e023b96d148c067616c9341f4582619cc4ab37b25528ca295543778cd4da5a2a6c01840b630cb3514a0ddd39500a11df8da71310041e74acd17659e0251e04a57324f28702f288e6121f42d55cc41a94df54cdfa8a55562adb08d5a69925caf184459ac97b2c27406a86580381f7236cba6992cccfb6456885a56a8fc85586e37a80f0033916c96497865a53b74ab2be529992474d645f65f6ba949e630edc4cc83cc3bed5552155dc3403daa1d8b579a176b710fb6ffa5ac945ec89de1ee17e20defe08d9e522a57959c6ae40d4f4f8b8eb86f81be5652bc018911e0bea1b118bd85ae6dad833afeafe7a53ee36b7cce5722c995dded60ce80c62913b9482eb3b21a8b1ff440f5c628af0a213515202d9e161d371e78b04671d66acc8bb21689708314931b0bbe0b80643a9768ada127de1b76109e133c8da91503e2e20771747171135ea6c19d1cafc19af5156531704094484b189ed5f25b0b03444a59e436bc37ed77ca963fcf2e6521564956994d33143f2f24994598555042c95aa3014c2008d295442d95162854b9944493b0db1ebf782dbabb7ff9ff8919a41181cefc31f72c21c690b2bfefb457bd38da4c1499d3c2c44bc2481da46ef3422d8796960f639198c558fcfacec4da877db92f4e8c51da680441ee61ebe9510cf45aaba1784dbbbaae20ae770a9b13cac444d6575216f8f664d991c0f6075065dff508151e5344b41da3125aab952c5cfce89d3ef300d21c8c229ae034f40ffb76634cf028b13566ce8a20d2a4be7e6da94f1805177af3433c7fd3ed68248ed6e6287bf4e25033cccb4c239e221995147f1e8e493c79602f22aa2ab4ad50eb899a56d98419eb981d06015a49a7492dcd63a0dd7478bf7c53166fc8cc60287e2aafe4a589158aac1248729a284cb87e4306776b2db5d790713d81ac3feba29053a9943e368880a790c7085065015e497c5ed5bb8ca2de7bd313eba2ce725d0d04eca416b94c540ddbcd4eb772b6338ff5c24d24043b5daff09cb55b6e99fd2b619605a3916df6683a5d2fd7391ea4796e7b5f26a934a629382ef4ab55ae4738f0883192b067a582b1ad4535c0927100a327610bede3d558749234edf44507ddfe3ba2ac44073bebec393070b20ef4fe36bcd83b38a1b8a6505878e23a26832d08c11d05951968e05eeda0a1785bd0ba328136a8649b1e175a6f80c7d8d3be28ca72e595ea4d172b95452d2bcc03cd7241b9e2ebac8e94ee59965f9318a02f432e7ff0d8703b988096f85d2c42f708f6997894a68a905cbacd331487c8e3f16e84bc3f4b6d146408d0ebef370b31ab15fad940ee02549b2098ab4552ebcd27a6e512776b4757ec58c70da34b72c32303073d94c3940eb454761473e41f8a474473900f90cc021479a955d66ed0413bd1bd9e892445cbc624c7f19a686a05ee3848bb9ca63275c8a0e95b78c222c2cc99821968f1024dcfcddc01b0bcd21b25324bf388a07b790799a00b7995df60ffd87759c51604922206cb62e11337a00bc2d8fce17874480709ed098f12f4685c989bfc2ab95146230812ba05016dcd59565fe1de55803dc61ef0f4b50ff238640b03657e986866ba495bc9428b928729768c777d6c69a3dcda9a7569eac9226dadd5421878e668c640e141f418194388ada42ee62b49538166cdf5d19c636cfe88ae0fe69f50249169c9d4dfacf0ddc7aafdb930927e0c87c424897071f81857c05c137b9af6e6b2d63f54b7672cf65ac998ec84331ad455a228f24bba4796b1a59637af32254352c57a880df7f74684443645043d502b404f947b6d853362470d562456892231cfdcca7b0debbf0df8c2b9bc37be7077bbbfa3f8fa51d63164392eda82252b5dbb244086486ec38fbeed4b554bbbe14c671bf60d72c0acc0513a080cc965c5060558136a6deee871163897352289fed88021abad414665ecbe91945ac71d6d268356fe6050866fb11f31606d3df3e6d03ef2baac93bca16dba6520b0a7b71808ea42e819e1d6a1388545372b26e5ba40dfa8725dc38f9edba14d8274a7755c04c99038410f0b8aed8f4291ed2bfbc85307e1c8f564202ebd0f6dd6a0c33d262ad84ddc3eea605dc6f6af28aa0f8bcbf2422a9796a7243505ca0bb3c8c28768f9d5dab6e836bd770ed60fce8f5b1f7e19f495fad2009b9c96b790f7e9a3dec873637199a9cc20289c26bb998ef98fed270bcf967a5d642aba49fa4b328550ab9e380b741397ba3cd238640c0651e72f6f438af471d787716cc020badb40cc30da1d04d8312b217c61cb21554b5336b6afd29202ce95c4d282641b237d421e84c680cb2a4381349be18983f7bf9a249344d91a2d2bf51406edad97fb145db503d2574ace1362e76e3b72df1bad2d3caf1db99a622d72c7de8d8f3d17f8c37ccad06d35e6f62eaf7b9f95795e5e81c23393796a6ece7a2024b60e0c1312e862e4c458ce3740728d5695456aac7974451055070de1d58924bef2dfc8711bd6da5be5e8fabe42b5133d84d4f692aa483113d17cd8b6b2485f6360c64cd132866399c8795660a571f39edc2216aaf592c8edf611e99d33cb2ae92e2058dea1eb7f87b2201a4f25d493822b667123f4d4f5021bc555307a3bc171e312bf51a275af4a6663ab50a40d7a9ae632a9c6f84f14f41359cb69ad34f5e829302578dbadcd363d5ad1834360277ed42d7a448d85a6cf40ee2867fa2ee7f1cde747c707e3a633a2ba29ca225bc2f59bcebb6eaf5d5686f1a255a55159cb211ea9ad62f2225148cf04ff7d71d414436cab2df0b4db7b4f14e0c5a11d0546dae028d8133f407e2e14d23761624b413829f095e28f208d06f7477dcebbc805df896cad8dfcbb7eb3c1c7a12922254b53a7cc8ad268e53056689a8a3765d1edbd81fdfc46f31bfd835fa3cd1369d76aebcc53d0b22cb2baac5e59cdb0ea06394a6d93d08433d694bfd45732c98fc0bcc440c0c4b544102313361d2aa2161df640b9ae442d97abb28217d4c2f89d60e6a30aacc288275a504baec1a48165c59c0e453e00b12fd828ec641a8e7745790506c968b65697441ff0bca299b2aad7b3997586773db03345ec4795af8d6f2f65e2d21b3948ee00db8f6969c34f1e9488c238fc14a9efa990c34f549fa1c8d1a05949ca71cd9f44cc453bc9c56a3d19a9f5040f9b378626df0c9b53870922fdecb10e5399cbb946085c8e0cd15026d87170a5c4e614b9c682eebb283e6178798fb863d80259b1cf1e26dc03359dd07ec29a1cf66f8e07027e726dc7ec6f1a472f6adb175b07ba126c3d92027872810cf9834762744e78a3e983fce74790c6ab4ef068daee4375881944c2cb72d32daab165589456f3e48a7163d900b9bfd71db87f0a0f2164dfd99cd21eaf85da0b96d6285c0f5a0b788d6a8b4c0da7110507d3ffdc0a8cdeb11a8880119de068cfe0a9269516132147e80661ddecf355c47c94e32d089be7f5d942a246351882f8a0c5696467790f4a585512f2bd2b420e98772bd699ad1050c3d0bcb47bc9e622795c2d80d63cae4eb3ec7a3bc9ceda6dff28517113d19c0421c0b3599838d5d04b686f3345788b6b037dbe33115cf9768739a090d407b927d8f4b7ad866efadc5f7e84d683f066c44fe813f30ea8cba095eedb6b031fbcbe72b42c706606b181db16a870042e091a002e97a0c19e79f72c4a7d052ff3a1382a449e54d6705cacca5ab3ac24cf6fc4151884e283bd14cbb232562874ba11328f4b3be3e74eabc3c89324d23bfbfb02e7cc65121b5bc4c4e5d1634bd71454b0989bcb5c590925f3d90022f998f6fe0810c37effef7cfa72871f1d7c96c56d4b5cf60d2beea0e2cc3a36d198595b7db00006d030c96b12323a79255ac0f60956fc840b2d50368dcb12ca8fb2165596a25a0f42bd30bdc7fb8c1ef3f43e335639ba81b5d009635bf15950a05fd6f2ed5b7bd5f53a0a026edd616d3c0ee6fa3dc18ece282389c7bfc83f6b3d9b65d7625f74feda11f745f7fefd666bc7fada7121ee13281cabfdd9e623fdc18b6c9f1adff7ac62e7a178c80f8db13b34e247238c13b61a1797ee785fdace3d4b19e935642349e5f5d18c92811c16e89682fb1306e391447a2dbef542df7fe8d18aecd2a4964f4df4fb8d9c1e8c79b7e0ed50cfe7e786133ef70583db51601a0d3d5c386c7c176602f01b3467183fb0c19bb67cefd16193adc7c6ab6f3bb236d6fd9b4583e606b22b849befb9bf9b2c7b7cada45010ae9b8e276b7a0cdc72bd6add7d0ebe0be3978572a3e67577dc5e8cbc713a79ce0f5bce643ad77e832b130918ae2ef75e029f1847f0700772e317f7ee094be650d6c057ecd88c2fb09b15ea29acd57cf338cb6552756f91d684ff54e63cdf1b52b927e40fb3b4113ebae502120e8b69fd9ba12c28a681f714cc9cd7ed3b4d4b646ebeb6060aa4b0e16b0b794c5a84771bfb21df20b66f9c93f46fc90660df3e7f6d77e29c7ad76af0e672278e8bd07a3b42c0b439ec9a1f0638f423aa02cbe2baea8b7022bd0d8e553ec8e765f121506f477308b80d2647f47fadb3fa8744d51bdc1bb7e4008dcd6fca70e541bc097901a9461e323630e6959866cd0c545f660c31e2d590f771e6cbeeb8cca6696c99819d83c56fae31e7ec70c033096e2c18f4070cb3c5f71031af28af86efb12eff4e8b12e3c84593e76ec636ac5403d51b90fdf1d0bd39486a60093ecbf0cd10236aa009f81accdccdad24cf26a04f97d75a90c86a8ad0494f0704925d5decd21665b9d26788ebf8409f237d71709dd5bee21d629d283159e717bef1372881cb358c530f10fdb2fc7ea26a717778f91e08f7f7297b7ad3d9bda9156f0332d8b729d82118afefe3b0bf2f76349f351a553a4bbef38434a7b2866717fbae6b74b34ccc0be0b8fb547443c51c299868c51260bb505d9912bbc3cfaf8dab4bbd480af1466fa9ac7803517d9d0dfe2b29c59bd6882523ee5a35aa2b294713594c178359590db26270a906e5e49781eefd8d05499158757f2b59cd442d55ed892c7ccc0fc9b8e16ff24699090ab007382cccefe8fa369b35458898b8d01ad82b9e058ea25d2bb1efe51a07c6d0dbc0ac74ad165e05b9747d0ea36b9f646767bd8dfc7aea1848d1a9c55552800701442695e950bc84fadbb26987df8f8c382ed0f839e450bd4f8ae4cd18d1ffffbba2c304362aec056446696a275579a539e650bc42ef6e289d48910825574995d49262a03ef4b2fac7ae7be4d6d247a74b9a0e658a800f3429087260ca305417010c95f05ea181ef89d77016ca2288f94517a7cc3cde06179f5c16fa0fcd4e3d2a7031b8f6f78d934ef36a954538189fd93bee767ba8f97b91e4cc73169ef1569554c6d46c2f74c4059938f3556f904c0bd25e91893d66d70ad5f7f0d57f730912487b0a516664e7962b72af6457454f7b1c4ac3de9b02c812bedbfcb668b1ef171e5e5a155f59cab164441f61854c2ac07b28b46c435603d13ef616895a3cd6885375c5a2e342405ab87b65fa0cace00e663d2c556d63a7604e46a216dd6acfa7cf3e11b36bc22996e5139b2e2a21a8e27491547a508fea6e66d8348c0862b8c25f1073560ce0734fdcd7cd79c5b7b035c02f0ed210e9c5f8fc010bb97b6ae269fb43f791d3a6e8a580c77449829221cb4f785f74fedfffe7fffebf4447dc87faac6caf119ce0f70a4a9696cbc362b5ae9f254532075b7a74b34fab645ea455b9f2433fdbcf26d4334343000a5fe1fb283465539e5942ef16eb5c4abee17ee4336e40f4188d32273714ad0d63c5397f4f3da6413180c1a2a8893607b027c5c1703e04427bf5f71f2d4833262d552f931b06ecc9d13302d247a3a304cf8c9fe5e4c7a7ce662e9b3a233f0a0f422ea9148f948c708ab9584a2d0b666ab9d166580cc80495cc59228e6664f9a09c7f0d185b8027d18c022c9803961b888ab20077f9318b3addf78a9f54c99c95cabe28673325eba0daabba5c7120a6d0d8576645aa213d7f52e97adecfd3585438af06b1643349efde880bc284f7462d4757af0f8d0d5236554352b4bc3e0cb558c290cabe23f52eb6f72fd92421991e8784cc76058c816c6a76c3a60ddd475b471a375bf5a32b7683865bf7a25775cbd994ab6ed0309a98d46def13c2fa99d8f717910532eada8588b4e3c2210da492b94c9464a18dd9837ad07caf210efe213cd51094e3a6e514ac902cd3732c75387a5d67b91af9550c7b85ac7528aa1e16b332da9295f366b3ac4849507d01b923c8cc2a6c1ea9e798bbd5eb3f2b2f41548140f710b109a2b9f11a688168d8e1440a795d57094446b669665d166f0c380219990088af31a94bfbbaae4ab15c4f17c64b5e336374d500e33c991a81959f44764787c22c3c61d62eb225904f95ccd94f59a4ec979a56659eb30fab4a5ebe92b99cd6af0238ba44ef3cf39d01d15ffec1022cd88fff0c3eeab1e015947daccbf574715840482da9940942c1bbce8ae9e2ff5f96cba756dde00d602eeb67e55ac917a59f99398cb54e5635a5ba0ec6653b2ad50d2933fc42305b146fdf9aa886b0591bb5f47e97c3553297ffd075f1cf7f462313d320a8f65eeb5008465081f11739c43b24f5883f6ee9d3b4b86fa66376e77052a63743248aa77256476ad88d8ca4c72a6f9a040d6b738fc7e56aeb0e8fcb55889370354cb24e3ded3e0cc54b36e551d052ef7f8f74fa7437ff87f9a3895348e7abcfa218b2758186f2ebb5181b5062407ba52f6eecd77f9aafff746f4fad73b25b8d20ee458aff698bffd93a5f5597ab1755b94ae6c60277d3ae413a0bdaf4c4afa2f1b1dbdbb35747bdec493195f9f7ebc92497261173186fdcd24a059bea89cd0878fb88fc263820ff1b8ca70d0978d83fc1bcaaa82abda5db70b6325cb08849425bbfc0b19e35e8aed1e776ac4713b02637bbb9fb8c196c339227e5d56d64d03692706102861edd1e68e62eabc2aaaa50ff0fbaffa51e50aa07046126343823cfd665190576254db426d4a12d32d5172a2ba692da678a669b5a0d587e336cc2ba7589372cb3f0a3e9d3d0f41c0e0ffa22d70c759a67f0bc2976a3f57ec82a392bafc3ca3bcd532c539ae77ebfae6bd8beddae1c4ee887862eeeddf39609549f189009ce095677a7173dc87807d125b4bcc8d25c04539623596a8c263db062d664bd5c897f1d16a9bc7e1867aa283f0044cad5081352d5944e886807a8b0d1d713f12b0e0a99f3d8e3c838da77c83422ddfb426c59743b40aa608dd20ff7758c70da20ac577efbd72b5c940fa44f8bce9f2107cb8c3cf34ce81370dd79289e97b598acf35cd65a702d67e3c801ee8b8336aabe3b9ecb424139a02e260270b131da5e2faa69dd6cbfb13fb11f63e231bc5bc2e11db6368f62944e1651cbeb5ae020905162ba9bc383de87328a56a6fc7af5510e8790ea66b3f722dcd6e66d54fb3eeb175058d875dbba7964d5da28b480c7ff4078285290178a54efa0ad16e3e78594f9167209e920504e6d7f720a89e436d16fdbd337221635bb8cc849b7753fc46162eeacfd2849832e40e67512b95a2ddd058d5dd7ba324c6a0b7d21233f022d9deeab7987b757df48f34ae6ec3a1899bdfeef7a6c8774b27326067ea7273b61de5cf3df0d6bb7db6cb77bd66cf6aee5a278a509ea89c657fc06a14be09c7315c5487cfe15e9f41755b994a357c92ca9b2e8f57023cc54d649968b91187c03e09e95ffcaf23cb9edfe0144dd85aca47a9d39aedbc54c349c78056dad8ec86d2304fab82d0f143c35d26eba774fdc525b20b3a6875588f85acb8ae2e214d43a2be6430cb24aba714afc824266e41cd463e08a28fa1b158b5772729135d212bbff884286498a07cc53e85256c44561757d460aaca68f7bac77db6a6f5ef1cd037872f40c3ac4b5b96d10475a705091de5bb5136ed9ee6cb16e1f05cb68daf9df8be8e8187e1f5cc777a8d80ff649ebde9ccbfa4543bd661f4166593197d56e5fe01f0f1ad8371921a9e2d0693aa885f9d2139f6d55eb7e14b341cb7f365afe33023f56eb96abf0b1be2b6e712947060e374b6605b5cf2d0fbc458909edcd6ae851a06fab70bb41e8273bb1bc62e6be0f95dc9d9ffffc67e34ce75ac3c8d89bab2b28ee6bdd512211ff2acb658437ea5193af345092a5a2266975f9acfa6c8ebb8dac7482cb139ec38ebf0a919ebf0d15c6ad3cc30067f939a2e88a74f2dd7b7712ed23422be111ab2fa91c6f6eb56fa205ff6ca811455487de9c54f4febec5753390251b756e91ae61d31d14e92d7baee59d608bcb0ab4f4ee3a769f6f73d7410c17a9dffaa048b76e8c7ad0dbdb7ff48bcbab6c5ee4f2076082c7c4593c25370ceffdf59cb1150f419076c8e3506dfa6a8f6f35efaf1fa4f6f900950f6f6e7528d3a4108768d1eb5efa549dd4525c414c77a35fcc28759554aa016a02d9043b26b37f2214f88bd2f984301e46e4de6d74a9cd8d61bd9dfcff22daa7f7d81a9b206cb33b36b5df72836cc3488ca2e9231edfd63a2abaa550edeed8f0473b7683f5e8f650453e85905a10a00b983a9ccb1faac9be7d238be8e1f1de67fb6d5a720c24cfe686510555cd7d08984ef4964b555a5e15be88fda4bc2aac6f576b631834f0049f18ad690b0268a6363686335ba536365aac69533a67d0293fab9dbd47f1643fb355772958dafcb6dec08e66abde249ce4bfa1b330eff0d174baae14325b585c013739526a2f92d54a166ac89cc73c5b2f94a79ea02c853f5e9459e16757e6d98acb026f68dbcdb6a9dbe836bdc0b69f3b99ff6c4e95ec8e26638bb22e54329343f1b314cb6cbe8057b022b1d098dd8590f5346016b7df9c37efa6ade06cb9b12cc9fea12aebdb9afe3b0b90b79223bcfa7182c33f5d3ee9868597fe4b490acf9049e5659c7a84b1fa95788372d81bcf5c732eeb5a562305ffb89cc426ec197858dd085d9c1573e5b21237f27a9190670c683f138d51757f15c95c8ec5170fdef5a9ba49f685bf86c95c76519b6282d77df1a051e1c1175805e2912473291e7cb167c785e100b2bc96954c8fdf63489868702c3aff512e8acebb7e00a42f4e3aba42e7cc0cd92f1feac260ec082a5a5b0fdb0b54050db51418dada37466c96c2a0d08c94db334b99aa1fe0ab732172a66ec6ae7ba8f95ed7b4069ddd09910638929c75ace93c8368995bcc030981b5f82051d288d619307767b490f45477b6bb0b79038a6182b2550717f2260cb816b86398a690c1d96fe83c32b0348c86a2ebc4bc9810c6c985bc396b37683591ec92e9542a857e74e6d9976863280ee705ba6c9a5631f727af3b761a41d0ccc0f1090369de69099526044ed4c082da7bfcccc373113a6cdaf59a14d10e46d4eeb5c1c55649a5e4e3322f2bdf90df7def4ef5ff334a87a214ca34115eefec7c23e55f6633e6d8645ccab08e5e060ca509294a393c524fe92f5cdaff42df464723f149359f98191230fc7748f107bba3eec97f7e72d61bcdfba2f3e9eea7bb1d6407264492c4f8e539725a7a849e6595aac527436f25a3e3f8c68ea39acf2793c4befcf838805f87454d00d47aa2eaaabbdbeb8bddaf7a4d6be746375f533765657a1ac63bea6eec497cfbadf84b4fbc153bd7b01a22a28ac7887c1d0428af57926c73c5425eebedbe4ce88c5a55722a2118f1e9dd4f4eef9213c5273b3bb3d9cece50fc58d648a263f05d991205857c244e0c18bfd5ed487f920e96ef60c66ab59fcaea720e74a82ee726ebbbefbd9267931115907d33a866f1cbb15cae728cbfc900b0af7140e735d56010d372d9b4f44ed2740002f92027998fb5509773c899787a7751d7abf16874757535bcfa7c5856f3d1839d9d9d91ba9c9fde25cbeeeb3c2b2e5aabef7ef3cd3723a8020d78cad6cb39f355acebea7b6b9a4963204d91d8b7fcd9f33d045f416cd712f6d1b0220b2af4596489727d675b331ee718161c75ae65f4b8f3803fc73cd4ae890b1500d9ece9899efa3cf1da9d313f9300a0a65f8d587e9eb8a982ff1f71ff961dc82a6bd03efcbef0db36778187d6f879ea1bbc3796557aaa40b6434d6a363dc7d3bbc8b14fef3a577a0e24b45841ef752a7ffeaa0bc46c53007bee92a0e33176ca991668d5e53ca41e19271dda70a9de92495e1bb76386530bd19ad2b28c6690a8b22c5363f54841f59665a1059c55524f219a82de684563a58858f6c2a2d50a2ff3f84758cc825584456023b50fa6522ecc7392a64226eac63a8f058d5c3c63fff36ca6bfdb53589f81499d807f95098bccaaebb257202b90fb27fed86b27b553eeb5e55a7497652a733fc859b848bdc6b20197f7786bd77566883f6c847b0bfbdbdb82d5f048cf05ecade9a42fd64a3e4e56f5ba72e29965d54d5597838c7795068cf71bc86cb6ed4862ea818f3b1824d7eeb48474e71e0f9d2eb23cc533d096ef854c8008ffb1aedb85160dcd1f7c8d77ae395fc1189eef8a4ef19adb14c0be34ddc845cfb981ac1f59fefa0a6ef906771ea38dd92c3030b81a714851f7b7f81234837ab13ee66d438d87d482cd4017fa4dc88b1f53015e489ae88bd3bbf0e77851c9d9e95d4f63f091e6d5d2557c929a3576f5ff3d0ea8144e2df77dd3adcae7b7a601b25dfad5bc66c526189f5e08c65eb5b2a59649c54b994cebbef8553c2e97abb2d07d631602d1a97491beef53d5f3ac58c82aabd5d3b254922afd75924c643eaad6459d2de56821f395acd448aae5c8abcee0e84bf2f1cd4a920f74675595ab813ee315ab749554854d9edda9b3e266409f3a56227df6e81fe7af0e7f7c7ef0e4fcf3ddf3ef0f8fcf0f9f1f8b7db1bbf3f5e75f7fb1fb97079fef59f1795916bfa81ff37292e42e13f21c7e83971f9878da25ea8887bc706c1aa05811a94c05631f722b5448a8ec4bbe73596398d7c3b4cb44237df0ef8bcef939363cc754d8e7597a7edee14ee9fe14cd2dbd1bfbfcf6add8e989fb62b721a1a1a6e75075affb82eb38ae81c5dd8442d035cc6f4703dc1523714d5e0b2371b3d7d4d5786daef545fb06febcd98b2a5f4860d307ccc132d3d7634f6981911dc8d97c5f9c9c715c508f6531f60e59aacfb69ff51486c019a6dc6c29321e2d67b3b17f46b603b2c6e8951aa202abeb942e8b5814990520811a39561d0e622e79bebab9ac2329ebb84ac6b4535e3b25eb6e21afc0fcd704844abfcf6adf491d2f1ea6de5e0359145a8dcfac8190e0bd9516cfef3332dbd3c2eab4395916f90d3bc72b59f8712b1e61281a85a16e5c9d87c2fc7db27326c6f657a30324366085c02bafeb2ea5af37a84af229e4967edcc099a6c4f3171858a1fa14ba40187d71fe18fd83ab4fa7085573bd3d7e5b80af2f308445e7fc1cc73100c63ba0d24147dc0f98c37d5db7c30099eec5be187df6c9f9f98bd72f0fcecf3f1bb9153ab7ecdd2e92cfcebb06060cdbd46da62531d5ba415c83737a1133dfe0b7d867c028f1057a75b99c179a7b78af69d0722871d3dbf8e91e27c02afadc50c3404e2292386720bd185ae7a0f316fb76224e096e478f75b464f0d82da7678e1014359051c9d95e43dad25f31af3dfc79c2965ff36a3eedbe01213cd3731ad8d4a0f4e72ccf5fcaa9cc2ee135c0b3c86eadd42da8d330f2558854945e4de561a833c6a996796abc09c2f67b7e4dc3504403685091f108ef690cc2869a13caf4dbb7707bc1132b0313981ec6ec7ffdda2ee65863db076a7bcd6422b562e313e3b8c412bcff614e88722a951acae272f8fce8c9c1f9c1f3bfa330b1aaca74dde287420252b7cb27732fde293eeeb08a7dd1894d642c0e8c16168d39dc5143d16012d0b0763edf1db0a044437158a85a26a9a890f45252c4c6f8bf68da40f319bc6d3af3839a9a55b9b31f86aa1642783b6a88679f47772dc791088c944efdc78cc676c4903f7cefe197c811cdb6083b8c7ca854d5f027148fba0d9e6cf9173b726a14abf745377a2219e6132b0bb99115d287941132532f514d9cb640e8b103c91c7cdb1c480fda4e2403849f480f224792a9173d921e8467d203ef507af05ea7d283219a0ceefb5c109e19a8c25ca2cc60430f799e4354a974f9b81c466e13cc88df4e94ac2e2da33200f9d7b7c1768108365e8d7b7e17b1dd63e62beb577acadd460c8ecd93165cacfbffd8fb17ee36721c511cff2a4c76362ac572c976327367e5f664d379f4fa6edac9c44ef79dbfe5ed502a4a62bb54d4144bb6d51d7ff7ff21c077b164e73173f7fecee6ec4ecb4512244110044010087751e260340b45d2a7b55a32b3c89dc7f5c13fe2584c60dcf110bfc0ce147678d424fcd3370528326b95421abe671ddaed8824ba8d5992878b97bcf851acc3a008adc22c2509688610308680483a6be5a2421086ce9336a8046e3df6f8ff0472150d7da8969df8f5cabf398a67b32d384e8fdb6cd34892d55bf74bc6e71f6bc96182a6bac588a901f8dad6ddf3f88c03d7a98e89a3b78f1f81a7877a44eb3436eca7eb34b6ec691a1fc4291dd01cc4a9b2bb0ee28e66fd8401c49cd223fb4b5b050c8091fd1528de70ab591520308052acafcf8c22f4e95342630644e045b7594e047208e6460c7701515cfd1b67fda9d7f7bdd35e817f13f9b8a2cde24cbc677376b382a48c8f878950667eadb838874b79e302d12a7537f0fa57ab46232e5925cf844dc27d44e24f9d6ddeb3f9ab9b95d7023ff8333d5b30b2a4bc824990a5b9e0ab613264ddf0923710e0447bd8a9738ffc8e706e3542c000f0fcec3f7e79ffea8757ffe79d4e228875b2f3315eb6fda8401326a774c50a75fa43d4b35a9266411b9d2bcce5eba7ab15031a20b33504808591e94cb8c321c645d3b1d59556b09618f012e113b962534ecb4437550f12965672266a7477ef6563fd2feff706c1685fddac6a26e5ae6c36a597b01cb344afabdd8a2e59e17f07c7104a56359bf11b0d4ad515ab06f38363fe262673ec814933538aef858743dd6afc70386a986c6070c54effd9f82139fa0b391f3f1c8e1f0ec8f821c412875faa5cfdb2c78efaf82cf872e1a0d662dd300375fc900054af69fa67b29714f8c70aa4fbe70df9ce3e82ee1e8f1f5ee0ea9cabb10ef38bfeb3ecd9287b36527f8e6002d73b7dfd7796e91fb08c9fceffcbfccefa17fd9dbefad5ef3ffb74efaad9f9cee36717fd679fa09fc7fd7e6f5c5de4bf0a5e65bd4fbdfe80f4e621c37807bb9c12f409c080434a59a5d77aef795b080395bae4c9aa5158822e1f47b79a6e24961ad6fa00ac8cb7b14f26329a4c36f5c0b4f30c84380a30548f03c3fe9ef9d3f05bfb0138c211e9f5cc07cd545fb2922f399ac67447e4d123f3332f6cf1a74fa437b4ad21e5bbfae37aa1385e96d5703e798c2367376c0ac1939546105e5b2a084be0dbf27cefc27d330c054bf6bd1261e23ed44c6294702c8369ed6070648909a454a10de78ab50c3634941db2d4d785e6581e0e8d03a4718c344391ecef6b564d6dda6e70e7c0324f3c30c3d0255ec80775a6f26acd12da48855640d9d4e730406fbac873341e0ebc820add7cd4e727dee7295e89eb92a75ec9bc16eb95fefe47ef3be6b5806557457ff28a20bb029797bae87f5d78587ab7960bd80c261332cc5c9827706e7b18cb130dee647539dc8f40518040439e119e56b46e38dcb369b468728294410a87edbf8f3cae6d0876c5a842b79bf8d111e9edf4146187df1ef73cba33bc3e6ef8ec8e8685b7af701155fd78d3f9936c1a5657f04a06d7f2d3275c3c830a1f7716a1e8510e54f1e99362023b3b364809a26064b0a63670cf16daf18ddc4f5b68663db2bf064e1056781ce9ffbabe708d46e6872d30c434220f1e98df5e2b98f4c8cefe99de413fa88967fa6b9f8c486689f219e9e58f7b64447ae7ffd5233bba810e236ea702b71a173bcf7a9ac26ee1bf2ec50b8a04b4daf85205bec3ac9912a17835073286b067c03ebef342b57bbe9c1eff41f754a81d75773cc358b0aa36bbe1b29103a21692f0c66d1e5615b6cb60df24774de8278755a2d0fb2fb43c6a4fb246104a8cf7669035c30e6fdbd1e6fdeb3ee5bc7fe903cf3ec4d24d06da29f2a8df3a058d409d3a0783893bf1197d86c306ee5784a077356b1ab57d593515e0fd2b66e4c3fb635c28c9f0554b374ac299791f83e7150a36fbf0fed86a79d0ed867899058c1ba0a90a45ceebfb7c3c1e3efb978be17ce03f3f8befcf7bff0a26713f49c05edf85d8dfff93fae3c36ac5ea17104d1aa82846c92b18029083dd725626cec9295ff2122410f27105d3f8388087cc5a7c9725955ab2ff6a943d37fd7f06a2fe5958429592ea8452b8838c22823b0d243417055a119419551ecfb7a51666f825a67948dba0f774597a272e76847a1e1ebf70c66bad045538bcced6bc44b331cba062b09af54a3261332516e14ea466f44977e5007498c3c27fb202b54cea951e5a21fccb273d6aa8e1eb9ebdffca9e8d30738486909b636387f4fa7fe80dc8aca47399199cf5c79e1740c02d1d7988c9af80e430fa7e248dc0798eb943c4e4577590fe7e1b8b0812e567199722a53ae13ac75da34eba2ebe304a148dfd7c43f7c7bba72e58c3c139bf7056d3786182e72b816dce9c7450cdbf0f0825dc964dd6388028049e436378c876e1d7d19c361c966e98f078c480b20a92114fa2db0625a82a01a52aacf0a8bbd0c29015e76380ba7aebee2f987dee0b97ad49a77092be24c6d7298ac4cf362bf6aaae459df5ecfde8f8a12576c098a2f2f1437d4b6a5cc0bc1b92dbc40260d056b089697fa716221f600f28cff5bfcd002bd11801110e0773694b3eaa16fffbf4ed498e24c667665caaf1c7683ae140a19eef231bdf31dd4916a975e90adff535539f30c296ab66d3eb4724929c9bddd2bfe296fe957c47fcb91e925f831d4dc00f6b6e9e3700ab40e49cff7ad16f5f6c3f700c350723946e1c3b38dc3567753474cf1b3a09ca3de63c7e780f3a30c36a51426b7799cd98fdaab3183e0bf62519e93f036dc0f29824d02d4ccce11aa17a9a4828a7184a1e058bd20f77e3fd56e34ba9eff35601eb99f9410d87770f0329e61763347689566dc6897460afd0a64b95b0b256922443b32cf813e29be16e0dc46a1d77c98f9e4e98901e95b2e6bda8cc771e3f3bfaaf07a33ffc7e9bf5cfc7e38b4fe3f1703c1e8ff5434bf5f30ffbbd960c8833016308a8ecaa3334b74cb4fd085ed7b4add7b42ac892d16afb64b5f27fefe982ce4c326816ce173ef9333e7a30fac3783cccfadb67f8bc69e814cd3d902b924a3087e39b64ccc0c4b4d09998c7037daf406a1616a0c59310001a2987e15d84ff80824e17ffa90691d50cde4c3b3d30d7892c3538336bd56d309d1f184690012911d82e355723e016aeca8c94d69e0e2aa91d56dc8e85c19eb2a4e29a30b64a5649def02b469e911e9838782fd658d76549c4bac1058161d37b2c81de8d7e915985fb2f027663eec6d046112cc57008c9f029a9d89cc23c4a212ee982d1c23127514166de60c3389505ffd4d770b97e0c0f0db3e1789c65cf1e8cc7cffac379df3de7c3265b6306e84ed21232a4340dad6ac6aec6c35c14604d83972aeeb367478b4a9c112dce5d636c68ad9c36c688161738235abb89b6a0a9ce2debeed67cdc46f2972f22b233a3c912aa1373a27eb98dd20c39b5292db1dd6dabad9baa9319288029324c5d95289c9a9b922ec515682d451cd0d8d9dd4c9ff0c739bf887bd5f4ea9be7d0f40c030d9559adcb620ff62e0a34d994229b5e42849c5ec41770a5ae18b63abd7d3ea78d8190d76a9bb9ef5e4ce3eb9612fbbacf5a46e63e8d4634f6612b67ed0bdb77996e42f327bdf4cc36ea80c60ed547aa176d1bd95bc14ddb61fd4a1954fa8408ea1fdd26b0d7b29e7e1616230f016b3c4ae1116450a31202dd586a77868ce163eb1c60d7f5f190407d7083b2a8350cd4de456aba0f8c22f04bdb45cca6502b0fb11bede1071f4c31be313665eaaf07473ab8a7dd56620d2e8fbd9e33b343e66746c415ab7deb985a4f743121626d37a413373fd7acb2d5a8725f930a8edf5e1a6afb233431fc3bd24c839bc1762b2d99f7fdeaee62b0e75bcf02cb59cf49faee2c34e3080c455d9602d3cb8eebc66a09b68cf4fae682ac65a3d8a2b67b368ab471a63d45db772feb4523e83feb6db7c938685ba00440ec945ad0ee052b85124b1aba62fb388faf18036ae8babcef7bbb4bfecc9b857ff90f7dea3bf45ddbd2de7729222edcb5a5d97015a944b5ab37f352141864a02cc535a178194068636eb794ca00b25c1e5c883542434301d1dec05785f5c1014803051bdf2613dec09e9d8a4ac27bf1e92607ef27a8a8c17149ae68c98b6804d4f38e1a80bd865750bee445519a348deaffe0e928450d57c1c3c93208310093d50973c9f8e150e9f2c3f1439d0bb2ea355617c72274d5193fb4377c0f1069ee7a42b3b3acbd38cf82c5d91b90c4fa8cb00e48107a1bb8e5876f477f30d47feb84670c1dec8f40ede13f60b580a0dd6a87086026d57c4b0d964ee8a712335a526981ad84947c5232a52caf259eb32ba1f59f406fb06ba75d26fccbb93c1abaa6c4478f12346e94aaecd9510b3d9ffed0ef6d9596838b08d51cba6c496a6959ec44d44b5af2dfd05a30e7574cbbe8e1a93008848db661c4091ecf2bb42c6aa97c4a2b3251bb484a0c6b646e72f1e4c7f87a1020762120e13f6ae26007505f18fa0d154c4e6bae9906790da19220f4de40afccc7e15ab27a38e2c5c701f9a8807f04b0006d2aaa86f28a7c3cffdd04b8e3456fe06b46bd616fd0d287423588dc5e7c4c08581962e813a2fe134852fd943edb12b2dc8176f745f5e70a5cbe32b04d68fdef206c196f02c22bd9d06aaae4129c567c331aeaf77a5afee8b4b06b06d7ef47ccc4cc147c1462e881d69675808596db3b1d040889a20505ea84df89516abea0938ed05b904346b2691344c27c5bf339af684930d3b21c911fd7974c2ec8bb9a4a5a0cc873f010c5ddfa83c9c9fe035b92e3633211e212a07821aec48a55da0c4257ab92413a66fc30849cdf57fc37fb63f7e9bffdd97d2d3615853f86f86c1f426431994fa10f2513d342ac1acc3dfc2bbda2c805c815abc11c3bd94489a2ddfe84233270d380f856d70bd62c94e87d2d88eacbba500ca055cde48a4d15832f3744e9bca0722d984eb1bc12bc6a24c96ef6079bfd3ed9dd25d9cdc16073d0b7e34dd47d32d83cd1759f0e364ffb6e5d60b446d08099bbb2011afbd68d8275456b4e272593e46640146b452e2959834999455df08aaaf969932774aefeb0f00226ad59cdef2710f7ed96dcec93d71083cf47890f37d96af345ad6e0efe61add22d9f9053361555f19993fbb266374fff81cd42d66f383190444403feb21b62a8e118dbe8eb6e3e2395008041dd99585745de72ffb07532c5cb6ef60764b33f20370703b23918401ad0d6e240c52703b2793220374f0764f314842ad99ee618a31b18d19fee0f083d1890c9fe804c0e0664ba3f2053d5cb63f242b0d98c4f3984f1133384c2feae6402130bbbde1f90fa6040ea2703523f8556bd533eaf7a386f692b16ac124be3853b20d57a09958fd54c97ace04a158f9ad44c62925fab41dd8cbc8cdc9b9149796a5ed30cd1c34d497e6a566a466a362892c3e00d8fd1dc621f98c8014079ac24fcf143ba4f6e08d92164b24f36f063ba4fc811217b5a54d7c3a3fbe4886c0ec82ed960ce9689fa70b34f76c90d3e359cc28703f258eddc5d55f4986c0eda43ad9fa079e9a90fbe7e428e541f8fd586da51c01fab3db243a6d85bfdd4963fb5e54f4db9e961c1a69744f27905cbe73a228a0b4e44b3d0c48a05f8fb29293923a2d2489174c988e405b304b03fb00cd4b273935737e0b53817230bd44f743497478fd4e8edef4c95fc052eef954a99d54fd55f4ffb2d7901729d90e1b0122d366b1d2b3d0238d0e47c6016ec402dd853b5604f70c1d4879b276a699ee282c187a788e95d55a4709a5830249bfac0ceaf564b4dd552dfecabd5d08bbe43a6480af5812d3fb0e507a6bc63b54c2fadd5daf756eb40ad965e2a5185ab95d8fbe9a5d3ed3b16502fdfbeb77c07c1f2ed07cb77807f752e1f89d6cf84e7011cbc094666ab8d8c4491e0b421a5019b315b63a2b627a07db26f8377ea1a81bb483cc4e7d3664dcb52f1f952218bd6b94f66f6ed01c2fa0e1c0e76f18f21392023627f1f06f5f7f23db7de670b86f586078af53482cc59a3b448d4a6b98e6fa0448c7a5d4d69030909c971e3d8152d0a066ab05c4f1ab84cb6fa71b55eb29a36a2567ad74a6be8eb95a8b4d2077b9bcf2b23c2d8fafec2576b854b602e53854b205cc381803be737e48864aa1e6241fdda35131ec19f3be6e90519e27c350a103845906aa1b01b1ff8e68b815b0d46c1b1e1723130ad1f3e3f88699b0f3f34bc94c328c2feaf5247a96d89fcd76c322f8f95fc895503c9ff4751f146d49280c8bd5bb392aaf5c1e41428b4f20a41601525f8ab9d5d8986cf38936a5595043e6175fbfef9f79ff815cd4161c87fe2ec3a07404681b825c19fb17c118f3b0b6a7bba6af03d8f9bf53d53d04b787b87617d4973cda76ca020e808a3c68487f61343a55cda898f828db8bddb38282a6054c7802c4ed0b9d2bb7a85e2578a6fbc70c93fce2ffcd2378c5eb1ced297e2baea2cfcb0ea2cfa51a48142c6f6544131295f7495452990f5d789e216ef8dce69ae41446368d3e270ce1af3fbbd10e6cd34a4dac0f89a996ae687d8a02bee442f87c391f7bb85c291f73bc6e0c8fd0cf137323f62dc8ddc4f1f7323fc4f84b391fde583d154310afe1a185a83bc273f06f5121fc795276162521572ac5311d56cc9944a41ae171b176597b1821540d1db091982e6f29063b90f9e9b456b4cee257a17f127e349fa95b34a146c3b1851b0241883e976c21b3fdeb925e2ae340431b9e33d539c18278c3c89e8690f69fa0dc633fd5683b164fb95036a7191af1ed487d5b71892e3795f3d20c50ebec5907c1efdd58302fef52d46159c2b5f3d2ce0b9df6258c161f835c35ad56cca2503cd05f8c987e301f1627bea442e50008f31e1572ef96f2c7a91b08234ecba7ca5f3b77b6e4d0b5ace5c0505a01de66725647e4376b1ee771803f4867ca7bfefe0f7478f1c5055b0710d361834f43bfd1d1b7404f8b5c9136394cc5973028f885e409eca7742662b21634da3753827da0c02f4a60304b7d3f7f988677954ee21bd55967505ec67392696fa7e3d99402c0b2f71e46d6a501892f325977452320c28ee0dac33e3a0798a63f3b5c6707975252eddbe942f16945710542b7cacc3077127ba0770eaf01c3a4248ceb183ec84491e23685ee23a6c79ce2f74982f2fc8010ccbc69ac13ca35d8bd1262b6f0f2671dc92dc82d74ab0993ce881ddccb79cb940ae84945436af953c198acf5860e389ed079fe1fc3ee3f0047da762d7e4256d58d6f7b2d54539d882bc7ba15b07ae6eebcc1b90733bb2016141e64cdcd9478a445ba9637113bbb2bf1dfa534e0cefc3ca1f5c30b6af4834f74549e6fc1162b2b6ef8da0df39c68957435184e22adf6b6302f21555e8074bb21c5427b36827baac99e2b4bd413c080324fa9cb9e079c3a15674d139a3029b94be186635812058125d7f952a58ab430b1b400edd61a94e4ecc0121ed95bee8cce489eb6066d645613392b5e4dcc87728487245c2473aaabddb0b3b3be45fc9ff4abe3b1a0e757e8d062ccf9078834cd665c91ab2aa85989957a28d20056bd49a21a62320307df0a858d58c2d57faa20cb10e569b89b116d56cdad06a5e062052cbe34ac36d9d9e327a8c05dc3f763826464fd8b22dc9ae23cfbc64b366db3e0d2a37621580ae5035e938655b6109a1faa3471e6f8398b3ed75e7b3ccd6e9ff4efca2903505229dcf9b2e3a037c46acd56855e65f84dfe0cf4f9f82ce03c1adb3732fcf0ca2ebc885c3b813119f319afba2223e5842520b17ccef2f7ee2b62d55b173baf3b2706c611898acf40e86712fea57e7bc37906d7bee1fb82fd428c81139efd818eae03c0c31ad5a9cef5d6c5f7e7fb97d152b166f0832ac6b864a342b88a80805facac96b5196e25a7129c8318c0e7164c2f4e90775cd31a959fec8079cc8077eef2caf5d6dd3a7afdf3232b825723e894a4239c86251ebad756d14ff40468e20f8bb46afd51d21a6b7efb3ff1bbb4c61f93e7bac538a6c6db37fca6682b84ae12eda7ae6f8ed245d32cf7e1680383a726b74d8debb71fd4f9f4820f9de6b03df45781159a7e25edbd5d88d64fcefc8d33db8f433936c3d18d6fc22b6eca5d845fa95b5d1f1ee6c1d13beaf89d8192466e7733467c7d25db4e673477afc6414ef7e98070788696d122d873914ddf72d974cf84ee165c0c8b4a41d259888ebb87b1c6d1fb25c766be642372a5f0d6fe73eb1061ac8602266b37147768d0c983ae6f70b537958326d3190449336e4d9ec1ea053a9c43aa1a71cfb10b927162b69e4fbe5c10b250f6395102b1f67dedf8ad2f0431a8baa4401261d839cd4e25ab2fab89a0935be7a5ca9ffb7cd8362f2fbb88e2843e717c2d4879632c60f15137aa0794a948278fcb0a2577c4e1b518f1ff62d506fdeb5d913ba773222e387e3870357603c0b55c1def8a129b83dc45fb7661ec85bd7d49dc2b6ef7c2d59fd7c0eb9a8c41b716dc2f4e85ef0096a4d5505ede68a05f5359b5c72c5128719feec9f93f17878919d8fc7d7f9c54e7fa841c0842954845ffdecd9287fac87de7fd6d56a29398346ea479f242a88df78592260fd1b413f23f5d5c8d6ef3f332dd075fec80c1d032aae699f7cfa64710f234c96a861a40ab235c5008a6f67d9f8e1542c57b4e193928d1ff6e1defdd1233b54dbdc6f7f7e71e896295e7bbdf2231cfbf93e04bd0b8840e3d1d438d0352c35202d00253c1c3c3497ebaf7955606c583a91a25c378c18ab313ce9b0193451105dd139eb8aef3be355a1b399bdd320c2fd9da89089c9af81c96dbaae95c8418e0243db745d37907bc76407d1294672745a78476b3f610e0179b515a14443de815843bae59b50bcf1fa0aaa9d8160e34e5c139b534c7e257e3d33109b4eb0c3ea7dae0733d0bd5d58a669d6e5dfd1cd39f2132619bda4845657f492f6c910dc99e568389cf366b19e80073316ea35daea6af123ade89cd52e7731b0dff05ad5f7e9f8994d7e78338cef5edd819bf08ad05d64e09d30b04e0aa19539e8b03588cc36f2df86d7743e4ff928a0e8d3b0baa2e57fb85c5fbfdf0e0219567dba2123b237201bf51f67c2f34693bb8b352ff903bccd0905b66834a15de2734dabfe3ca2a1980b67afbf7e4bdef6329cc58800c138e7452c00db268f1eb9e461a202b9b625c9c51532362091f81e1823da06f9db7e6eee5043bc46666c37fbd4c57d2712dab471f88fc390586d47909235d2ea63375ee0c27b3bc581ff9d8780780c774dd36b1bcdf68e19bface9bcd55b346b55475105ec305fab84ad803bced71f7117dcf6a35144a189b6ef24b2f5a2a20be3de92dcb692ce7a9344a66cfe3d264adb6105996c743e030caa6e7cb60490e06eb55bd462a5ed30181f00cd3890007f266a72fad30f0158ebbc76cdc8926e3c802fdffea801692f6c8a61568025abea73e7a0e6e06903d10a730a90e95a366269f34193259b2e68c5e5d28fd8164e54fbc881f5735707485ba23b1e2bf254554b37bb3a49253e3495ac4107c99a3177e9370a2028d11e58cac8bb9919b4aa28f2f26a301b91ba5df514740107ccaf30747f4c785528a8272fd5828d48bcf7cc9c125a7a07fbf0d24b26f6d6834e8004e39e30e3a07b076b2249d5f9361026ea6f224ed4285068f1b443b33be390dca9ad3405c546a6553caaa4b2d1b6863d4f90ad0a81d9427b4bd91b90de52fca6fe83d2bafa257a17b63ab7bfe454ac982743b7d5b228cdaba76b415bab1519b5c95d006c4d179b8083154338ad4a9e66a7844cbe6462dd186dd6164d4b46eba0708b7a175fcd6b649ae87e8f1e9107d07bae243b269be7155f8249e6754d97ec90ecec706f3610661220bc33d11134c0737e71184c270d901c61e979006587f4dea76af76298685f8d417a584bc27e9168d50375685bfded23ba0dc96a1b12636ae8c44c4d67ef44b999f1b2dcda4b0a0bad4ed2a8d2f710efb7f564ce450e6973ec67c33c143385ad8bb94166bc66d239480177c777d7c0b1ae6849325e91a5ec9375d5f0d2c2b04db03fa90f625d3cd4e46b23af00b3f07db46a5f65c09e8e0b472feae0300c082e8ec14ecb1b52f3f9a221f49a6e7237b99471c54d184f10757a48a234f5b55187f12d3e8ec9af3bf44812ce1cf5bf309a81df27f8e3e309a77f843bd9fc157aa7447cd31e3c8000b3c1d244963900fd43afb9a22d338fac1f80266eec99dfe6d60eb563a4b651c0d63a693373730886e6cf6cef707ba71a89116ee069b8031e4fcea393aed9851cd5f6e6365117614ed775adcf3377fd92cf91b77b1d42981bbe6467428992e488fc489b45bea437d9de80ecff89ec92cc82dab5a7643f04c0dde2bbd3230b9c5adc196216db82ddf106e0e0de0e929fbd733a09e030da55bc489c4c561a885952c68b363bf30e3d55eec3bb6d0918c6a86bac5b2d0165ce9a977cc92a0946a9b8b95f9a59e71a6f4cb8611205c486140d3ea97f4b26259d33328203a6120d3c4b2a4c3ff036cda5c0b3c07b3e9cdbf406d0def323f24e344a98a72599d6424a6b1f9eace7b94f2ad7bc80b8dbb617ad22fdacbe0744b560c02edb55ff030a0eb7b35042c0c436f2a439c01088d5e1371cd208ff1b94e8218cf48f904576ae30ca986fe846ac9bc356aa2fc997eb9236a2f66d5a15684df96ab1917cead5d1f62c88e703cad26c936886fa98ae1bc68603e56ccac8844a569012c6a4c362e25189105a4f913464f8df5baca4438d548c15522b6025e50511eb26682af4ab6a3d9953d6281d4f2acadd88354692d10aa0d465d05e8d4ab7210e49aac9945610ff44fd5113715dd9864469a0106988373d09cf1d31500a8613b059e544c53046ca84e9e5295a2fb4fd653366c2680e7ec80fa861d52617cc5707f2054f60229b7a3d85305053dc7813463c613d7ef6844338fd6c0ad13ea27ab05ef3086016cfc77b1ca494ba1f15928f0cd64ef41733e578411f3d3249afa392dcc14a3bad7b7d75358d30a33e7f2f0a0e990ef0ddbece309839eb365cd6af6a18dc11f9fdd67e9c40cb173ae9e69e376bacee82611eb5b0981b5acbe3ba9f3e01b73ff4226571c501f96fcc123208a5d790c98e910505c7490c10a49613ac0ebce2cd3bacae2d74686d3913c1dda4669f549e36d4735cea7adee50c458fc93b56ab014bd806b2612b08700071f420101372055ace45cd9bc5d2b4b3edffddc8c9bf4f842819ad6e41625644a1a62237b2614bcf0908227615ac6685127226253b24af4b2a994b17985bd8670e0097ba3a865620b3750d9146a690b042908f6ae859ff23f003be5cd5e20a5d26710216e6d0c8e12c30b9380b8722e68024d0e1d3b7cab9830dc2a000efa8d815ab41eb203d1ca81755cfd810b447749b8a60ec9e79783824a7544f6029aef0668b2b9904f57c29960cd816ad1ae0b77f5fb37a43b80d65a6207ac08c5c656d6174c5736f44e6673884e710c6add497e8d0cf0aa98594e27ab76457ac24748a1187e8ac61b815253c0145c7b822e87106dc4a8dade7cf165e312a91db1bc9d05b8343bf22d7347e22ae413755cdbe83a7d6fbc1c2c013e709ab8172c492c13ea3f5843735ad37799e870108ddde797074e4771218bffc1de6d5f16c5d601b9c9426e57de6434a652d3692680b98f309f777eb6bef74fea8907d5c7cb49aaab9118d685d3b3299bbccd87078ece7b13301c359e3f855f1bd2836a66abe1272eb084f5923c3bb59b4cb42f8601c78187785f876591ba709bbc3a6bc00e9869b7469be286222bc24baecacbcb97fe5a35bf25b501b069481233b9f11ba5a957c0a04a1841e516cfa31a3f90ce4ebd368838a40c70258225235d5f96340eb2729eaf30073fdb8dce6183930576c20b349e90764bfefc0b59812af2078226dd8f7df8b1bf75c28b9eaee14307173def0ead2616eb221a5fac08bce26f9ac16cb5bf2fbcd806c6ee3883bd0184d119ded1bb1b535ab8af6c650a34cad8d6ad15a1b3ce395368b72c439d6ba085ffd4059eab14f604457931d69403073b5b1020fc846d8f246a8d240df729ce4731685d68c1ab1119e23ccdc918132a4969f8c5ee536e8c79bfd8f03f271b3ff11ae5856a842a5b6f2c79b03a879f011bc2e1b25cca3752b51db2d0508c5ef21fa875b87366b6ad1e99c35f720501d195862686046a70bdc6a7af25acc71aa05845c31a211758609dc5e7a2f46939889fa159d2ed46e1df97f7803b2e3d1665cd912b0e094e5d5705dad20de28b24ede4897713362f3e41daf946e8e67af96b4b43e4167334c19a23660dc1344802bafe9c6ad1de63ed4015379dd75a4ac78a5b85afb0e8a4b1ccc6771b59c7b6c0df99a81438ec88307e68fad0b0caf265d043a4f8105ddaf8077391a85e546cda0623143e012783514c573bbf721a96693df6bc89a0608646e03d701c8b153330cef17ef9182cb95902c2db6e2ee85e76653143d7a03222ad8545a16713876b2988669d4cdae91fe00873aec3c5ae26afa76027d4a83ae6d50ad0810c29d399dd682d331d2a4c6a493123d7680bb48ffe81e94e6c9fe685831773a44a78081bcdb9c4a2060b01ae3125f0b620f499065757cd566c1dca683e80fa61a04f441d301c13befe509b0888eee8f6e49238e0b45ad9549e585106daa45086fa318d6c24405c2484e9716a4dabe18182e1c8619454379e93724993a67da6c6bce9a53c0e2c8fd4c22fcfc3d0ca52a3717887ccb9162cb4c2c0499efa316fbee5e597b26e964ef5492b55a05b5d4c8cae27980d68cffe9064b97a0d6899953ac349f670529307ab15242b42ebc62b44e3040a3a6e897b5c631cbd8e132bae2fd3b037d784744369dd8cdacc5994b883a6c4d1bfd5c5777a673b50f0321653af11a9c63f1c580e87ad67fa7eb213b2ebda692015068e002875bc6736d041a4efb9607d7da0811afa3dbf91e31afbe94eb25333521d11076e7395fe82d7ba46b3921a8f5b4a005104d9208537b7c7403ce79d112b0a22e8643dcc05c12fb025c9fbcf39a4e00e22850ff55c7479a4d2fa854826788e9408a7ca0eaf7e3e7a9769cea871b65ecb699124f13cbed6b15f19300474558210d24b6451928fa30aaee3a8b62785dcab305ec1b11c0c632b09a731744bfd70c87b33d5790ae63c3036857036f2db106393255c1c9c05b3cfc9ce37fce362b7c92d9a345d16bb9c7e9baa927aa15c725f2aa849252eb99175644d269c1028af3ab241f7a3957928e59e0f38acf9988966dd48118d4fa92896858f79b8bdd1d04c54acfccab6f305039c7af599a82020bac194cda666c085f336a9870a7106997b7b5ae3ef01df754db73fd0bba015c9805ee9e436ab77ba279c78ed7dc082c1be126302fb37d44b66c14d0b84512adfb103bbe3e1cf353f45b04f3f8babaacc4b515317b49235a1851c6c6930987e18765b193607cbe98a017979a83fe131191c5548a5d241550269b1376ade6609f0c58d8c9216bb4b780d1023489e74df8d8109522f39e1cce3e53d45e397204f56d63f346b9d8fc48a5f416c9c70fea3e267c79b941fd057110059e08f5b37bc730f1f9404013869c8ecdfcdcd1765f0a8d08348993c0c75abb2f26819a3aadc541de07940a1d6e8b8a63596ec0c5a2a580735c4be587dd358c7ce070a2da7cdfc28b07eec2b3253502aa26ea2ac07e4d6be14ad1a5271e824ea6e10e501ad17948ec28a30b3198c8407f8d6be9d1a0472a7e4af2319ffb0768edb4ce799ea849e39cc1658b93f92b1399e5d275c335c2ee54fb7ebca260ece311936c44ab5e2374ad886413d3bb8360f5c239dc77126d070ff4e27ee2f5ca0be3b13da1937203f9a845c5c884354a73151559b2a5a837def6f618ed7970b4c07e5773916d0b8b6d75181ce598dafee6c483898e49bcca1c384d910372d03fec96f67c3829594fcbed0eac2fec41f6f766c16abd153da2b1f13614d77ed6b549c928bd2503da703d3c7ae4bacbe3f3cc220b23bcd98afd04730e85fd00cb3149a40f8fcf9120e0c058e28dbeb9c18f2405354d0cd69f7379424f32dbc63f7b5a72033c9e01c8ee7e99ea7bbf5e2207a63106b4ad8560670019634125e115185cad23091a0b096d9a9a4fd68d0e08f2583bbd2c19ad12765cedd4a1b355e504066b12f6d46c2aaa199faf6b6d167bac745eec0702e9f20646327e684edaf143af7f226ab41d018515b4a1386e131d5b8334462763fe8709527fb68d2053850ad3c05c557c1fdfe5436d8765cfd885833ed4597ca25b7cb497b843718b9011a9a036968f16908dc0f1e993fe02b3d64106e10f5ba7dfef3471745caa7dad401c0bd8879198d7092c8cbb68a5b636bdd272aa783a9348ef706f89771148845351d74cae4485fe57803cdfe9b9485306268cfb6412656829cc5db8ba0bd201b04fec0c6605e3f01dbea6668c45484dd225e25064bf5cb2aa60859d07c6b532e26a443091b7516abd802bfb67b2120f520ce6813e6534b28d5e65fe243bc43f37c8903cc9f7bcd80edd8ff36d047078462a0935064f7d676c0de7e06e27c165a29aab6312553db0e4ea633def7ab61c9fede15bd6b83493a1579a42d4a91190bc8814259f0cb167cf578c6186d4842f2114783597ac9ea72ac2771fe23dfd1389e3b94708dc4e64e019dfbc776e8fc971c16849f4a2817118082233ce5ebc720bb014052bfbee45987b5e85b5df00941179b2e745e40bbbfb0f212e7b8add5f93a9cb9792937db24ba428b959c9ee4e20cdca88ece57b7b7b7feeec4789586239497575dcf4b42d1c6e8e56acd4777fcd62ed1f85260bb70755fb592ee925a450b4f9f6f4dd213c4650c70c9d3678490afc9c8c92389bd7f48a379b11d9ddcf0f3a2772b6600df5278002f7f7b4ae9824ffe16e5db9a872f21e0c754a92bc66ac22e068ee770e9e3dd3524856a35b6723c8bef693aacd3cdc218cb9efc0954a90b90011623d5ff800b577a1424723c00b4e6147a607482a410a3e9bb1da4cc48334a9d70ddb459f5abdd50d4f040b1020d45e455a3fb8246e1b85354524dd14f2b2a673edc11b90c7074d19b214d7a4008f58f0a11bc4f45132a968865664bf13c33a55c51ede224103b8cad76e79da6f363583a2a61ea977d3c74bed86dbf0a57640cc8aa60f3b592391570d9b83a75795c2145fb253d56c440e301883b5940d87e467938d14ddc36132e28ad5352fc0f1994fc98c4e1b516f7490467cede91c6effbaa6c559cde0899871f68c4a3e7d6a71b5bfaf69d1d48c4d161e17c466102b4eb6c1e9ef3e30e4cf10b84ab6e0a8e57f0dabdf02e58adad00a53d60288e7430748bfb00d54ba520fac59b7009cf928ea041cb62e597d6c6b247007e2540b73c52601cc15f67c2fd989f1143ebf80dc5ada73181c41b8f49951c8b6bd26a7ee68e96af37747361121b9a379e0a4444d123e25682fd40169d797c14ab51628d143e1114b4423aeb68fa489b83951b29d8d186acd7c98fbbaa1e58fe6fe1494e9e1902cc4356679b537abf042bc604ad4b177aaae93d57a52f2e9f32ecf64f06153f2934144cde65c36e03a0ca2adb97e6e5d3b5b1027a261237226082d0a501c51645e4b46b4a135ebeb7dafd3feae74b823c5f744556e2c28947df0fab96152616ca82f8e69356564b5ae550519bb32e0e0476612860b1afa18d95fc92b6b8b034d83df040908cba2419b87fed188d03318d9a9a45d625063b062a0f6910715279e295c1670a7d1c51d6a1823fb2bd965d2011e8fd5f6bebe97dfbb73594f39bba7d4e42ec7f4c0018e4ea76b180f837d2bb3d8877ae936a465bd2d2e929bf3d2575215bfc9d1d21340d5ba9101bcd547e8795148d40c754a2a44431b71e12b22f3686555f325c8a23257fbf21641053e475bd6e02e609839cb07a2f1add9808ff258b74fe8fb095b141c42e0d284de95bd96ddcdf002b4cf990b8408d5dec5cd67a199d0c6e4958e5cf65a8837d6a095881db5ffc1487e1eb87686f6cbe4155d1ac976cc7760db33e63851a075adf6d50bf21e6cec7a4d40b5f956c40fda9d02be654d5a863aed9cb7ae0acc2708008a5c6727b57ce7305a2277b575cfad607c53e27b585edce0fda342ac89333709ecd070dd58dc90ef20927a0a906e2e5790f09e17374a0b0cdaeb1a5aed6f4765d73cad66920541f0a3d5f5e31a756f376a2e974c1ab3fb1d0c66a3ed12aae3ac683f456d2120c7a88d5fd30a744fc5daeb68c94dcff0c491378e26e253bbbde58c535fb89cfbe80f7630084c1ee6af9fe12debc0b754a05a99a2827d881609d0b66f5bfdb018e48f75597ad80cce592bf093f0aedcf324f3c78cfe64c6daef0f20a8754476f16590f608d3b1518cfd3d502b235ab6578a6a2e1ae177e3d0c31ae4c624cf120523b2bb1f22dd4ddd9802812dc537a6de2ddc1414f925ad2f7dc775490a5e379b3ca274ef5ab59b9321e16e7591f445f9ac0fbe1a11e9cd5973e6eb07dbfdf90355e25e8cd6b8fcde93d59a5de8880e37506e0ca25c125a993050c623994c366e0f7d0effb50ec95fc681db9bb675678d2157cc579f7dc65cd8109261c3e10db063c47f21bbfb890dd4c980b7e7afb18b97768c091cebad8f4c8b2e34037730ba1d6bb653b3cd99311137f6b2e48ad5129cedf11c6953f0f7df8b9b0ec285e327d48f53478f274edb929656edb21fa54e270d69226e5a330d5f67758c748b161fac93b1e33a20e0a11fcd19bdf61f74b8fb3a7d2bd7f0c8113afa7b0830ba6e2e56f06a34fbddf60d556f5334b6e0728babaf616f51e7dd54a92dabdf68ae00ed5e33d5fd7eab7902b8b4df95b37ea2e9d32ad34b51f0199fa239fa8a536d8121cfdf1d83d513557befcac55a68fab1837babc43ccf32df6367f7b6f6ea79953cb7855d7764fa383332bd1f47d5899bda65d7ee11c5defa81d3363cdc547288b602e22bf51a5f5a5330b6e8b72b6cb96a36d685db2e27af24ab1bed1c834030909367021991b759451e9352cc4965a3f9e960bc7c77b7e54e6767e03b9760d4002dd073eb84e0e718c29ce0c068f006431af4ed2a59112dfd013c7ca6ae0e1acffddd0a7479e2f99619630e903d81daaf60d1e3bc45d0b6180afec4b7441a06195749f8efeae5f44e34bbd216b311623d13a9e9c8384ef18bd8074aed9854b0169b69d7dcf0fec4ea0d99b38ad57cea7230b5a285405aaeec667f4094a8787330209e84acf6797eb34f8ec80d08d02656347cdfa8ef9bf6f71bc8557fd0ae0f59eeedf78e60f167eca659d72c98ca295743270d169977901013f9795352d99a94069279d91c6108535a5d5199c897824ab78ea49d8d1f62c5f143c43eb66d9498e28151e7fd0b51a95165e3870745509bcb974ab20d8e4dbfad091fe47fb38182740e4997a441cf27bc0fd7e8b82b07386028ccfebd2115e5578cf0e50a676cafff354c4928e0951c37c897a57f27550a8a716996ebb2e1ab52010267025e35025b823439670dd118afd94aed468c92aa641974a658b602f634bc64f21dabcd8c7709af0a750c3089367b5a6d4c77da41490d076f11450591d4dd063614a35d37cca46626de829899d61a24bb99a297c882cb10947bec4641c5d213bb2b188f5b822c9a9ae7ed604ade439c08f00f947faf9bb885da39fb7b074ffbe4bbef6c2c7755e794ff06029303a30b95f6f30626780c42b6c99088933ec6397bb1bc411bd321c28e0b93fee192af5861c8d9f66b28c54b040eb9f258f1a12eadefe4d88419e2f29db866f5dbd9410b1151f0a1f1c33355419d527601dd45f04a418105bd16f9f861e08234b479aed56aeb531e95a5f15db1651c9919473b24e40595faed4ce13320dee0fb4ba549056f2da5585a7ab338028737cd1166259d43f05e453dac2c636b88ae37b2f9bcda637d5132aa74826a43249f63dc331cad791014c184d06f1aacfbbd55734503edba2e51799d8ab26453cb266081341fa6860593968638d2ffddf2c4b12c1d9ab601549abaae37f2ffe8061d055680379ae860a6e83eec8cbcf02afb4af6c8c2fc1d632293916273e496ec62d8681d2a59374a667c50ddf87d5a90e144ede7e706087a6bf2c6723a5acf316868d56294963f0d80f7424fd445a080683c86879bd77fac2115bb697cbaf6309bf5bd554f2c8787b251f477da3c2937d574518b4aac65b9218a2f490f37fa8ac0ac472da4dc2d043cf1976cbaae79e3eef54abee4fad082b0266d8a571c6e644e2aab6674bf6f75bb220b5329680986ae78f24c6f870736d4dcf128cf149ff38b0e801d0f52d43ecaf872fea12ec3f41e1ee51e059cfd1c6b07cea05eedb61da3350aebc8bf056c78c6ece223305fad890ea1a3237fc83acb47c2d666a2571dcf2b5133f433060f33d9843bf87a214aa6386a1e09e1e6683d13c8d4f0e1943a5c3c52cd128309f208abfac7d5296bd2cd83d9395d632a569b2c683e08c6123e91a9d9aaa45356bc455e122da377ac9e07dd5d5c58bf50bfbd9e064921fab075529fb72b5d80f5a5ab533bf225ad2ff59609fd53b76520f7b84be8446d36062eba82211bb2116b087f9504e52f43b43134cc4eb26dbd0e16b4d030062499c6de0715a79bd29dfbafdb4d0c96d408ac4a17194e80df2c8d0d5fab28d03408dacf97737c58edaf8aa7e486fb6dc74fa0cb97f31cc29aa25b3b3922e387b412d56629d6520b53a69ea8d4d83b733ab7179fa0c67cfdbcc960880305c6c3a63300f94f8f96f35cd65372441039db78a08e79af75bb800936564152a833557cb9fab19594cd402ca386bb0bfd57da1b5f4f4b4140f7f0786ec15878696368a5798683e3d63564e31ea2714b8e886bd4c623dc3a79dde67a36589ffce5283e957c520db1da7ebea47d599c0e6a8fb0ee2e1d93085b2b2d3a57d844b206240650a6a2f4962a2aac83751c247ef513fccd21ee02c94c119c1d5fbc4155e145c83a0f93337187b76677ba960d0bed9db49dcc30220c233e9a19a7685cafe91169d526c3582a0c344535d7292dcf2c3a9230feb505c336af413dcd6228435ff18c7a54cb9968f2af4193ce3431c18c47e19ffea846ea7ffc3e47ea7f342127716fb9d789b8ce82900dad65256d15f830a52dfbaf763bbb0b2cc9052be90655564535039d999d43caf575d9a042a4b75dcd8c30ab7315059d7bfb599f1b41b4efa8b2bbbdf5e6151c14dd53f38d9c3392f910fe42f67dc78610c71d675eab233d7c2ffcba0f67409eeeed6d7d160a8297525907a411c1fe511f5f1803a0e561f0c435e45dda1e6709aa112fd0f667f99e68b5686e6c75a82a624e664a37581ab232bb03a02b8f41ba310f60fc2dfe081fefe68b037233209bad1c731b42929b620b3a12f55b0f933c8390e173f6391d79a4fe6797ecf7fbe82fd34ee637e3257b7bc5ea2bceaec94bb8f692846ac326c47dd5c11431ad13d8e17e30d9a0a625956835460752a8af0d9df0cc1082a64c45296a0b06aa630640454df3f243c3cb28692ef472974116e238d6625ed36560963593f870ec3d0de2da8468d362a52d8c1ecc50307a7e76f6fef8fb0f67af4e7f79f7eafd2fefde1fff787c76fcd32b7244fe04fee1d69d8b7049def04a3fc56baef5958dccc92b3a5d8009eb66b001e30222e6883c218fc9817bea29bdf455dfffcd74f9e6f8e43fc91139208f49a6fee7752968f3e400a37eba6aafdebcfaf1d5c919d9211f78d55dde8741abd1e1f399c72483fc673b38282f1f15e0eff5293922e7eea3fad75bd56cca21b7eb92157cbd5c91991ad3616f1055bca2f586577372c5a64f117ea28ee00559525e65ea579ffcdeaa41089997bfbc86272688b70e50b73df7e122ff55f02aeb8dc755af3ff06fb0605e3fa5e66517420df880d05fae58ddb09b7742b6fb0aea3e25f41737a6a8e6bae2b03d00e6fa1739ad19ab8069b5809aaa4bda3c25eb5f1a13502105b603b75f885d4fdef6fa258f017ce66162e8cf6040f6f2bd01d9cff7faedc9a02401eba5b193d3c9fc8b976d85bbd36b3cf7336c4ed6b39927d410b256dcc5fb5b8950703b3f8848c146f6f10a66b5a8e06da9d2c28643fb000fc462f2db2e38d9049c4dff938da8e9dce851b007bf879165fb7f228fa35ddd0f3380720cae8d4dfd5d9e69a87e7d40a8a9ecedf8545d9dcfc2fe8df7647ed010b3e07e7810fe1b0baddcea1fabe4ba66af2ab19e2f4eed5c930e29f8cf3ab0999b054a8a3504526ec0cc0fdc172271e2fa92292624bcc17789e805698e8510b4129f32b7843bfbfdc711d7fc8b598f7cb269d89b58730b46f9ea8ad51b7c9876cd48bdae885837f81a834ecdfd14601b5d079a6b3e6564c2e7733c53da1071debc2192b1a5d4140a78557800132c2b72f242bf1b206b092910cd9d20748387ef623dd7f11165bb277cc5dbc043ebd34ef26b23429d3dfd411b1e2cb386f76e1b55469dde05eb4517c5c6700e632ed686a2c4db0cb7804ead65efb718d026482162b521bfae2566fd50724e629dfc7dd79af561bbbedd77e18012351d2b882618d5f5b3256e49f809c624df95695eeacbf31645cf4bc8f6a78ba3eed65aead2f29707a68577cd72d599a0aaea4b7e2326e973746004853859eabcccd7d2d6d6b0e24a962bdb4ee6ac79633e9a560372def3cea0de80f4f491a27efa2712fe6df959efa23dab7999b38a4e4af613c07b0e073952a21d4d6efb4acceaeed6284ab57ad61c40e1debc66c4cd19b8c484a75e47bcf20f1c559777422a3ded9d6827ee74513c6f74b89a0f3ce74562975a73b7a9feb853ec8db06177cfb9337ceb61e53777d4253b64dfafbf89eae34e73950f2edc3450de69d16bbb8727608a17f71ccf5357fbaed1fc31319af412ea7442bcba0cb6ef9ab7562c71b8b6bcaf02a1253039e03f4f72515b8afbf14de391e19dd87d4606067cd7ef5ff03187f705aead7c5646f00c94d77465bca231be126a4710865d361845c94bad32578ad45a92b7d97edf77b3f3343a8046cb517b84305bf29d3fae478f486bdcc9c31a0f5fcddd21242d28c68dd0c7bddebb5c12714937986eaa0d48f349b1da004b78476b734c0d702db66cad813fd26dd5ba4a12d9aad3eb8e3e722e7f51e8a57d6d0b5ab8b232611c0a10ff355ef6241f4e2701e240c0fbc61fc3f580b4c534e3f0751d756a9dbe1687f71e6cbc0d2a257e75f855e3bf7b1d66f3329ff0aad04c7d5ee6cfdfbf7ffeb75fbefff0faf5abf7034d42a94650f09236b4dd484b110355efe5df4e9eff78fce29797ef9fffdce60b604d34734e92b98f91d0193d9c286aa13fd2a6e6374f6757dec1e61405ed5de3d63c9e5708ec60e641f11548d44df42ade996f7d5eea9319cfdd7702926aa6ceed0139009cbd7ef3f6f9991ded933bed2703b29758a1ed9dc20e1f90a7d0e18793d3e31f4e5ebdfc45811e00e5ddafdf03f2983c4d8a2b707b06da80a28f37c727af4e07642fe21707eda6e159e073ebe0d80877c30442398ad7aa2d89c58ee4c1e077f31713ae3a4980c81ed599e0d8a33d8607a6e956e6e777f68d99647a3ee913c3afb3db3e853b59ef9c35afbda65b798e712a71f5db9ed3b75f68d845e3df571b76211e1b395dd0157350e1a92eb84baf4b5a7b1eaa5f99f01dedb65f6b3df66c0d49ebb104a75e6344d6336a1991d1a66be2fbe8cf10224ffe7d4d6ba6d4fa52a796018d5f7ba0694fc8b411da1b5ae679b76e31413f05e5f79d6f8206a3b3b9ae90c06361b9c6e8e089df7f23bb68b395036ba45bf30a3d80549f8e3f9dbc7df94a9baabfcef26c038a004e7dc3f29d06e5edc6ce6e23e79da6636d7b0cac8ee1387d437168f47d9234106f330c93fb9983b79b81bf013eee6deccd6f36b1bd17de06b6e0f1aad13ed47eebdfc863bf83f3bd8bf3bd8ba0f1560371c7e298e559d94d8c7fcf4bfb13052afba73da9ed173888ec5ff736daaabde0e8e35e265b5bfb4e836d48777ebc792f61b2fd6ba1731f1b0ff840d6864919612f74ddd4678c73ef4cba9ae21b42d9ce86a75d06b53664587e67061e5edce00b04b4969ba82e706cc4755742925dc04eecfb1b543759a9ac61c4fcb21389d49b51fc21aaa80877e4fd1e381b9c525b31f795fb6d8b51afc762f7db6b0d2e85dac70dc202b53e7995d50132d2ff1d7b1eb7f684481a077c07bbcca39b1db2df6f512ef9cbd1767bf8b7b282ffa36ddfdfcae2fdb556eeafb16c7f5b7bf6fdacd877d9aeefb25827fd45c0f3b36d8b4edaa0ef617bde6e73d647f2c0c810469adfaa9eff136dcc5f665bfe129bf21db6e4789556f641bd28d887e301f1c3efb82002588a36c390cfca73bed5307c418e545d6b65bd6f3b6305de5d7946d7cf680c56613d6ce97b026983ed9d009e78009c21371d19dd6538489ac93a2c4e5bcd62e98e14998566b0d8fcd5327b253b4fbf826867e5c013c43b4062bdd72b0ad4dd28728b0982ff9ddf40c7edee803c1caa9346a9476bc902036c4fb1b89e7e1409a78d6f8af5acafdbacae6644db6c05dee8becea410be628efcae01eb76ea5db6fe08d9d6c2df5ec94896c8868fed3306104414ad411cfac7c33ef9bddd5e491a5e1aaf6d1cf4b30c9b5f6dd0ec3264769b2fbf81d1f24b4d95b71eebbfb769f249c234d9c9a23ec362f90d2c955f318c27a101b365b87cf7f6f8e40c2d978ec2fb9e73a37eacbda2b564465ff7cc3beefb3d3c0459d2b843b51da7e415d3d74e60f102efbc4ae85d016921c59c4f0985e7db038001afa740fc3229428517895fb5910baa64595a1518ab08ffb491191e134c020122f5425c637822b87bc0640e8fbb5c1319b2b3d0cb33f106179e6d8a9a487cbea98d743a2728b331c8246b74025213f753c97b356469b0b0206cb884578d8dce1c4ca662c908d5419a51ffdbbb79fffe871fbefffef973b015d23851278c62e4ad69e6fc0c6f0fbfedb29f82e92d58f817687603ff2dea27770e822018f327e4aacbfa964b0e4823008cd67b2899ae652396a414e252adb8d14c8327f8a0e5ece27f3c0d1682d3f31b566afbaaae8dcbb41b2e97a9dffb97ba9ecf27134a7b6a5d7bff52cf273d8de8b40d1171907986bfcfa31a7fd468ca244a436b852e05a5d9046a03d38f17a08d3cc36f23b2bfd7fdbe3849a8da7cfa4554a47aa8b71ac1311b8ab1e262b2d9b564929cfef403995045258a676172060065007ea5edbac6c5aac795faff16f9caabb9a1c14353098c3857410e07b44dcb2b48e0a0abdc2bdd82ae5b88e571b55a3798bc22dc67f9108a86511dbde7f4981c866d245d7935df45ccf9c8859087c05f71aea4100c63ede84b7d0d0633e92811a2c1783d575cae21c2af34f1fdab02b23cbb37e830370fa37603785804c1a676ea8dbc9abfc02cf7ac1e8c6b273bcaabf97b219ae01b3a79fc1ff4096d7dff5beb3baf78f342f395a0804e9b352d4fa7b464183cc22f2bc1de6fc24784256f749e135d327cfcab5c40f89f4a71321dda404fdf17d1bf5ff3b280856de7a2f4aa122fc6d4d53c1b3facd9b4193fecc775ecbf9c364d9d8d1f8208347e3820fb7b77574641e9beb567bc2c55ddf1c37fd9dba307eccf100ec66b85a888676cac1c06ffada97bca6e34046ba6d2af9b97541df97f84a02dcefeb2a0e5cc901e2a61c2585f43fb64045dab947a76376a6aa01f935df2c70e6c98ca1b53790395efc042c9abcbd4ba9bfbda6debaec482f1c3bee95836b5b8647a15feeddffeedee25509d6c5d0270913a4e39ab45e3c28a165ffb6a14d695ec2e8405b53777d4be3950b5b553d85d90bdba9bbb9031e3357bcfa4daee458084b9e64adb887049371330baca052d4b34f6e96824cfe246061ee64756db173bbd7bbda674ba00d3a0622e3764a484f1cd88ec851c086bbd467cdea3e699e8aae7d78ddd8e62bff16892a0067a6c3b518590e8f6031e642f4107ccc60fc94ec08177885acb3df57fe932f86a987ffce56ff0a53f7e78981a853f50433b765440429eca19b5bf0d96ecd0479b3e9d5ce207fc3beb07b5e0f6cbdce01f8568d2792b3f1c8f22be886f1ed3ccc19c4d2e81d956a2d279b8c23ed097746b1f70cab9cce55bfb309287f907b97c30fc8915e9419c4344a1f4e0c266e9f8cd0184089e96c727c84a2d33f354063b39e8884ea76cd5482fc35e0410f40d2fec555590a5521f0d022ac2307a5818dd0b34b3f691d21aae094b7b3c8bc7fcb63ed18e099440e4d0f614068457b201cf4a38c4b876dbc080b887515f6f4d1c5b172113635bfa8dc2362dd124f0758906dcb1fbb57a11afc88323b5cb0db0f1c30ec66062e542fafe428c303ad633944a75e0c7a958ae68c327a57eb527ca825cb15a7251c9e4364d9df2eef08d467a986a114400fdb6240ffeb521c9ff03295ef5f60d291e9cbfbe94e2ffd9b49e6f21f632f6a7feff0cb18792668ad8bf15a13fb71e67367f97ce0ee99c0324262086d434c66402f382f882114083c05c95bd2be9949971fb4a02fa1110d498b8746b08a1a423905ce7e59b6cb46473e2a923597f1b898095fe24668af1c8124bdda1f1c42dbf622d6068ad2701a60355b065781dda40aaf53725170594158481f3c284cd04c47bd0461e4874283dbbc4968599b039afde27fdc13f7b1ce844b160951bca8c575c2e58987ee85e036355f1e5c3c2634309a0107559ac18664240aeeea55386507060d8562a88b3bfe857aeddc38313e105ab1a56bfd0b11efd71de0cc826412ecece72d32207676bd9b4cae2cbd8bb949e36464c1e425eadd60d596a7358c965c32a603b2fdffe889635f86b558b2993c62255d474be5bed16b5586d4109f70d6da3d8f4d61aa35d9ef7ac0c7057dc0c4891c21ed8ccd176a8740293bbefa71fe0da27eb0f52e744830d9cae3267cd8bb31f3b6a0b13e5aaab8f1c752db7144dce2b75a6b0acdf4f8a3fabfc861c91a2bde0ab7ca30a36e956e488aceeeeacdd51b6028b0b4e24bfe993c7a4c96947e7d90a2c2ebaf2062b17c9013539233b6a4ced8934f90c8bd253d9aeaf36396de9a94d5e78da28f4ecfd35ebd44bbf54276d6f20b02e0454095f5e4332cd0191d35a942590c417d069c7ca79401348c605f3eb7c0ee12477804f4c20475986d908b81ff00252a5ba1a0ec90bb15cadb57f1ce20c7b26bcb2be8f4bb1962ebc690a59972964e1c576d6cfedb014690f1422fa39f4e5af895f6d17eaedaa8a9fc71272ed8eb7c92ed37b39346fa7f695e3f04dceb6f0f8269fb54afffb6e94b8bd6ff7cb9400d3a669a301398cddb1e520f6fe696bdf25f65774c9707f3cee6bdc11fde35bf290cf43cbdd425f74845b516bb2213ff12b9ac3bd4ffe1367d7b9bbdd13a4644aeda9a6356b98319111b16e56eb2604b7aac51538a2ae6ab6a2357377f381d8131ff13c7c2235dd62ab9c3a34ae56ac2a5e2c7859647a9fb731b35dc621c86f4e04dcfcc1d584a8cb027212892553e2e535e58dcedc89b0726d68d6f29e6490b308a59c2d0aa97fb90597bcf7d046fd36dd53bcfdefb1e2352b19958c88e974bd52e26fcda458d75326b72cbd6974dfd5d7c66c30e63e7a44b6550d89053df6ee2096ed98ec5654be0d2eb76e1f1d321c8c22fe05ee764b0f1aa6a0d12e26f2c7a4956d9b53b02ab428948e199ba1bb2e004d84840fc7fa79a4366ee0d5590bcb10ff19eb87b9b8125af087e37ce55ed9ac846c41d3b5608ed87bab4a6022cf7961430e1c27c716f0eaa9a2189d8f2370bc4c505bd05027bd0125dadede053566bc960d506482124d78c2bbbaf199a0c6e976b2265e54e2360efe6fb20fb83c86758448ffce874caeeb199d8676fc68541ea57f38d6ce0f9109d773e1ba346932d434d4df599fb01b365db76e371e27d955cbaed371471c6c8c16152689cfee8b3b57dee7685d2b4f5ce4f4bbbbff6f728e74b13e304cb67d57b6d203da24b7d303c0f5e841fbaedd8b1e6851b4cd8fe034dccd29f5988efc3b0f742e49734aacbfdd5e7de78ed75e1477f0525d0b3082e34bf15277a5a97929364b8af49dbc4acf6adbd58e07f6ff3e556af604a8f962f604ada1bb9e6cdd74a6594d92bceea2acd62225296b2b6175b21a7fe1e2468ed5dcd1fd1d8216e216ddbaeed0da20eb0568fb6c43b8bb72ef92a867243355e2e8f9976cd3ef68d68de14bb6694fcffcb35e22b9f728c8ecc18435a6dd6e9368d736e49a7fa96b0d7b2f63810efc7d9e5ec816ffb8d782a1b7dde72f18b4dbbe6050e50b16ac7dfade63c15e1b77292b273ae44354e2bb56ce00d87401e85e42cf1128d97f23eeec1d1ba7fa6ec4969e53974e56700de635f03b1af812f8b7a1a6b69e65f2d2d64aef3377df98977621a4b94ae7d3ed972bac316eada03f063aa79ef0cf0b56bd6734795160ef84b5e63fe335b39a3f5e8e335a28b16241afec7dfc145f66b6fc1a3dd340abf37bdb079c36bc651fb4c0772bc0e40ed58344460972d486fe052440027f4a35b4c4a96f97613b759cfef483a190ed6e1027a261237bb10f2f7c2a5aead4f044aed894cff8d4a6af37e2c37602d38e657731c16d93357f380f36f36538246f58e35cd48000f5ed9abeadbdb6e9e630e2ab7172f1ec6f361dadf5a60c8430dd7c1ebbd1abb2e8259ef5a20b27a8fdc4b5c31d3ac8caabb971aaf4abfa5286ad3b4f7a501bab29be8963c5ae15c0d0cfb6d85474c9a71dbdc025406430741e9187e159965c1b5817f81f782131ae302fdb2e9592cfab71954dfbe4945745cdc8a9a8176b39aefebde4535649467e3c3e1b571874a7b7968cc8a6e6d3a67738ae868f099325af9add824b3a299584b98bdee9bb57b496f07203fc1259e31d7da79be544c01370ccd49e278b0fb169786aba36ab5a3442b1a0e85cd5cd56b5581dcb57d57ac96a1859a2a179f8e4d73b0ca2eb37021b655714b3228d1b9d2b1a985cb52e4bf2e913317f8799a3c7cdb8c15c8c904d67b362afea5ad4594f0f04714fa6b4aa4403618150fa07f715002d6a0712df3c35f0d270dce865f64677186706403eff41b213daf02bfde874dc34f5c60c0e14b4603076dcb607f3c4527dd27d8f9be190bc640d9b3664b29ecf37de0b32c4232aa835bc69ab880057a19ffe6cdd8c720f8e792c3359cf653e5dd462c9d7cb5cd4f3e16a78f5e7219772cde4b0600de5e5335e1c3ddddfff3336c6642eb2d9d721174e1bb59db21e9d4c7bfd43e0372171ee96bc020aadd8f5ee75adf6532df5322938e710cdb357b0dea1c34f92424fe892c90c1af5cff72ef0d5d31f7bf7c7dee7cefac9de1fff14cefa00de8568d0562af512e8edabffeeec78638266e7bd5f7a6447230bc4b9170b5abf1005cb781f32fb78c3d5fdc14a1e746d57878c837ebea4abccd3f6da18c1415417a697be876bec4707fae9f5c1ebadb7b77ff0e4e91ffff4bffefc6fff54fc3ef1f1ab68aa60b3f982ff7a592e2bb1fa7b2d9b5e2e57256fd448f399a85fd1e9c29b7a097e6911f69f9ce36730e1c2af141a34962fd94666c1eecc7ebf1de0e0fafd004ba68fae91de137161deb971734ba6b4992e48c66a3793e190fccc4821aa5e43d8cd4a31015a6d6c6ee089b8d249286b718d2fba26e8a2d708c5e3249db13ce8ce0dc52437693f8c6bb1b2672464a2bec4d2d07ace9a01c1fb1b3d7093bae6d0fcd10888f2ab3928b6e9db5269cf20f5c5ee2f0977ab4492ef08ade790f4da65a894de6e03238bd93099ad7b2e75989060d76a5d52b5f1564a914278b4e5ea80d059798cf66857be11a01cea50ca5a51d4a5b7d1422bd0c933d78328ed219dac09c3e8db1e521c4843b0f809b9118e223ea6fd29eaf6e7fc229c29ccd515da297b9f0e5deddb0412a253b4118736237c24e18c2b3dca29933267d5557ef2f6e5ab5f5e9dfc844c7f558b620d74d7d32f6c5bc4eb3d629efe2a8735a3d36697cbdc35cd97bc32af9afdcc4ef70655b02b568a15680d064e7a369826934e9be3009e81a41f56db77d362b5a9e18ddbc1defe1f07e46f7421c403725c4df3b05c122d2c1620b0a02fee09bb26df9fbe246fb02827a78c21939882137205c1ebde1cbf787572fa8acc7889f19d1b562f6d2e7a35def7af9ebf38fbe5f4ecf9d9f18b5393d50f6eb674dc20255ac911862e8032f739fdd5afac3d8a1579079fb95c95140e37efeb9c352fd3f5a1a4e657ac386d68c35ed76209d2def62a319425bfe195ff41ed8f78c48d9d1752adc2d17f9ebcfdf924c651150e1ef761081c25611f4ba06ec51ffc1a969905df78b389c7f4faedfb9f9fbf7ff9cbfb57afe391f5fef007b41ef43c2026fcd9972d4d8429378c1f5ffdf8f65efd0351d6ec1b0da073a9cefef6ee953f1ef5ddff76aef767fe5ad4d7b42edeb3996271096c7635fc912d856ae2cf3cd46b94aedfd0864f65a6662d2a5699a05dc32179afe090abfd3fe5fbfbe0f93b61a5b81eeb1cf4a6172e553f5efb386d6cd43d21b711f003000e2283c975ac9b06d3b23d9cbb65bbb8507a57c0198c02044fdc41676a2b8de1f7c394720ae2ec565937d9ecb374dab0ec2593d39aaf1a0879916ced6a3800efcce67d3b0b9a79df756554f5edf784267ce891c64270d99c880ad6c910098a472fcc4218d9cafb3029e9f4b2e4d2909167208ceaa2582f4101e905891c41a684fee1c107c13a245b34cbb24f2c19e80880a0318453eb475980ab05ab79c30ad7f75184ba2c1a9c1f9c4f759000f1e8510ab09a54f768c83dd1da06ec63b623c294f617659bb6b086ba59e71cb7cb81d89786abfe934f4535a54dba49ab97566c2490ba61c67afe38dc0e6498e6207603e864abceb9a5245298443aa1bc91c371a6e7fc22228407c1098ba2f6a347e441669747fd69ff800a7dac118efed1a3703a7ecd103b8f1e85e8c29a015521aff3d84717df88f1840a44102b5e1b869ccd723824cf2188f08cf2725d3369ae8e69b10b513a5636ec98df2ce4b16d1abf649b8137e820eb8d55383156594ced96988ce01ec23eecd21f539b0fc57d08b2c997e82009d147cd2b0f5e91492dae25abad4111be1fb5c572b41354c3a1be59423c5d2f68c3141b9b9762424b88ca8d0e1c440a7c74a3747952afab8ad5523fc369d613c21b0086fc7052337a499a0544a321e4fb7543ae19a918bed0b9aee98af006ae2261051181bc22532a21681397000ced5d852a417d001cea20cf9abe8a2a0493aa435c3f50ea71e4aadbe3a6a7502279c1080580f6c098b029556a46536f86d03b93a46062d5f025047aadc894d50de51561d59c570ccd7f100c19b0756a73d41efa9f5f78997743e1454b65d84eac1b17bece595bb5a5d5e5bfd5b1bd1a3261ac22be4df5b60ddaef9b6c01ef6707deda419608f01fed37ffc074a30625d334eeb59203c41824475ee3606385f9823b5bc7b84de41af0f7a82bbd3facdbbba61f60f55e0808d6eb2800704f2444101274f09998b837c05ba5f367fdbe4785f5ba32599b67eb2a08efdc46f391bfe4514ccd4ad44b5a12565df15a80ce06fb9f568c48deac311c60fbeec8258d9ead2b2fb0e0ad15d57840a4d7141807bda2bc84bb96097e242505cb9fde0c6e16e969c4f4a224fc07714d38293b267cdfdd70cf794614aa98e88255f83f522cd944141bd8f5725ab36b7371e3e145a1a112e4387f9593252d8a8ac936b6e341c7634122cb58fff72d47358cee67181d23b406ae0bddaa21404035386d61b4c09fd81584a7917a7486f737f55a62037d68a1488b73d6d75348543646e0f6d9a03daf5a97e5808413eb9c9c9e8da41865102dca40516a10107f919aab2422663801383c21cac0825eb1c40cd401df6b165cf606642156b375596e8858d7c62c84411ca70d11f6e53f6f301b19b27d6a0032c5fb3f63f2aad3e4e43df1383c85ea75e5330a48ddceea041f7811734a9ff37d135e304d8c23c50d029efda5fca0359dd471ec98c28b60b28f1e75cffe734e897b4ffc9fc91e52e470d83a85fe191ce25bb1087f463e930827d73dc1ff27b844de1aefa958327b0f6ec705a32938b886544a2328755aa6605b5d498f7a3e0bb5c88212a80d581030212580ff7dcdd68c1c91f30b2d911735e595528e5cc86510d4f131eb5f55f543afe93164fa3822bbfba1e0ae66537d589db09be68c4f2fc3c4150f6c27b0c33dd0c156362ee3fe4e4c0ccff2490f8ed6fc037066aa413d6de68032b7cd62e1b13d556f48aaefbf77750ae385ae328fa784de1b7e1d1f4d66ae772205ac2d96d9792265b40a66041e12cd05b08553b28a1c117f3ebad1f582972c2b5915b25b0f99a6dd611be7405ee6234022d9ce8e87d6ef480c39b5acc9cc6c7e857307f222afd755b62d45e65debabfe75a243b78ee6af185b1bc93ea5c607be5e37ebd363ee1f2bbd6641d03c5f45508b45ebb9f413a164f14d35d925fb7d6f8fb4caff42f603a406a6b47d34a5b5afbfcdf5ae8f59359673ae3abc2047ae0d9ad7da5cc8a23d5fade5225353386ed812456205abef8fdb5f001017f6c18a96de218efeddcef2379fb1e05cfd9994fc9281ada6e0530c9484a783f4b6a73fac9a6e3c130197f96c5de10a1d7a1f316bc111d6c78555403c77b4da346b590a34d09cae56e5461f940e685fdf5e1b2a697803fe6e3d6dbfea7965fa93dbe4ded5b6b164994fb49e5f996d6abe9913f588f47a101f812d57cdc658ea1b4128580c6b3667372b827e36add69ecdccceb6126295990c05a63e74a44afc5115c51b88d002b3880a45356589afb359fba3497bdc050acb9f97a5a922db75d89237edafab9aad58b56594bac2db6a9ae8df552bbd8e3d9f2aba64eee12939bf2001ca261ca3d0279a7418b1e2963a4e985caf56a26e8c0d2b18d9f4ba8829d58ca737ec119f88a68b828711690b5edf3d186cd63914536dbda4d2e786fe48f60ec9ad35f29a70685c7a918ee60abbf0708e3618c80c4ecc3c6141eeede5fb7bf97e0f01b68a4b410beb5f81eec5e0ac9f08c78d0fa8fa21f543faa45fa5a8a0153e717199cae08d429c68c6a4ac63980f3468a19fddb8bf3f7d223a0378004a3fb248d5f3ec71765c688c8b6fee7010e488fcefd3b7273904677753d1891d02e1c936b0b5fcdc26368ca90d770a553297728b6bd904de0f00ac1c7382072eb86a2eba140336b51d749314f802dd71d58ae87128bd4d4951d809ad0a8c00d50b732ca933d2777ef2ba4e5e39d96407f806335ab1cc6f7fce2ffc73ef816b16bf29eaf1a2e7df10b566f7830d53aaf307e0eb01889938221830b450df965c4a58e6568613a062fd7434f386c28b8137a1bca00dbd0f8630aa581786bc87f12ddc40cb1837f03e38c6caac16cbe3a2d707d52259a311c7f7c21c3ef08e319793ef45b320d80d66fe10ea0704a083ed5f6c41e41b5ee153a51c01e814c80a84fed9c2a5ffcca1e5f8cd8becc6e3833790913fc5b524bd8afcddd5177c5931d0492e4e424e841fdf24f8d170a8dd0a4cd80a493e02f57e04847c84d5faa873fad90cb33593ebb2316e393ae9d1889c5fe8dd0eadd4df632f1ba279cbe8f3b1c468d56a6b0b92fdf65ac0c34c971434628789f975807903b11a603cb892da0718b685c2e309be4f8ccb61b555f91b7c71e6af277050e4af7cb6c91039fd3807a4011e26ef1a0ebd6cc4fe4373bc7884f312ef0c1b7ac930cd82214e32e3ac2ca405f491177ad514e57dd44a0a8c46733494cf038e05a349e79d33d30db3879b11b7a282401cd7528ac4b03fe216f938201fd5fe8051ba61b7478bdc05461bf21018497ab41d3413a23b45bc842826aa9f0debdd7e684767bda6af6905af9b808d7907162e8267c052e750c5140668bd1939265719fe0a5e27ed33cdce1eeae0c902bf6316a4c90e6bdf1717ed854ce302576a447cce66b9abb025c0e61cb2dc2c2de7bbe72c6dfd7bcdd2651c9ab2aaa969c99b54f21457d89573c8d5f8199f944436afb83873fc1223319d7942a97e0844ed028c5b397b26acb966acaa98942f2cec51fab3c66bc1e635637eedf8cbd865d0f1c69e8499cd3d01d4ab11a022f70ab2396e33eb6cfd13bfa23f9850a158ff359ca899d7aafd9e291e73361f904b5e15de70b04a3812fc662bdf7728d8ac3d8a6d6d5caf61b625ff4187572797a26eb2c9e6275aae193e9d69c47f32fd77ccf5753d1b45d5276d07f47c734176fdbf6f2e92fbda7504efd02378bef3d7081c76cc0788813df23bb8649b0b9fd7d9bd15ee94dcae8de7c42eebe910bf1bb7f5a851485f514bafb0a3f9b41492a51bdba28ea66c0a73e4d3882f606bbfd40048495838b9281759395d9710a9dde50c9086743d6694f16a0869976b3211cda2ef6518938cc113a7d170c8aafc9a5ff2152b3885074eeaafa123cd7f7909807f99fa7b3d4854f6bbaf98deea4179f721e81da46f8da67af4bc9afb9b2c808702cc2d39571bee488dfd82fcbca00d6c4075d0b7e75a315648fd42c874c18a118025a4c7ab9e22b05d574678b5db0263aa8b75d38baa8b75d35d9f57d0629764fab8eba369804f1343e5d21b619c7ccd301b94a023eea49370bc3434111d9c9a4ba0ce0b463ec303006f472483ff7efa447a0aa7bd7ede8837e29ad52fa8341709eadcc4da4a53876aaa81fb845375f93efd21912302c5f897a153930a1755f8b0035e6d03757f385bc774c788baf4f857f0368d15fedae9d5848eb91c115e0d88b7c5428dbe2dd5db7577e38b04782b6304cc36d1ae2d4c6a1386ee562753912697aed11eb1033f7c51802e109a5cbe5b3fada6af20b696c66f77ecd36c231a5a82ce6ec80bf467d977676843cb434fc38f5c6e43f59e432a5b677c01e83b4728ec295d1ec4417c5bad87f28cec9391eeff3638bcb1e3706a0962f9ef33376d1ff8f2d925b767569a0034e959ec85241a0c3a7d5693234fb00b0eafe3de52bbc9eae3e7fafa3ae7d52c5f577cf75240828ddff2820d693917c3d57a52729d747638d9bd92abc97477efcff9aa98013448145233b8f59eeac75f10d062b9c21018548bc0018f7543337c56d49c550df3d7f6af7071a1c59653bcc5502237dec929d5f6b4a1d34b2d8883fbb698c19d8f52b7442d09bea0af1bc620d76bb3d0eecfe8486dfa59a12533cdbbf15503d7594712ad55d9f6d6984a538d0d07931a8b3a372fd9c61a85f97c49ef1813dc3fb06a0aef76351451f9500a5636dd504c2d7dd3199854027daabb79c268c21a27b79c89ff1fab45c27e127262d7a0ef59851f441481dad62238c7e554d44c5a47ea092305bfe205465f6bae8502145824946e66e00e2c54c9d5dad2b28c1708a425011ed38a469a6b8eeb4e3ad501f3881cc7f1fde6ec5aa48c7eae497cce780d03a93e92d6c9f0881ca4ed34ed15080f2a0f927704ed258125d62802e688c71829f4e50351689d97ec141f4a68c4bea3cd22f31a9933914ea7eb25f494a50d3a7e052b65a4c8efa5227a9ff2ac5fc269db8f43d1fa353922a7f94aac3c9f02d80382c19d63b64f76702b9d5f5ff487b035cfaf2f82ba3ed33982bffc1aeedc296ef4c953dc90effc56bef1bcb869bd0fb9d25075ed735edcf8b7ef38baab0b7554e1f8ae2ec8639c41fce00877d7351864fc85089c3f1c895c035033fdc4eba524057a8b10d20b02ba93ee3a49c78b0790a6005ef180b0147b3ec756ae3ba2b1e4be1bd790bfa29d5177636d599a82fe9aa620b53a7fcde582cf1a8f864e11d49597993eb621e3354b763520785160595e6cfef274fee32203c7b568d1864372f2f6ec953645e193105e966883353c8c401e805d48c23bd04aa1e27162d6b0ca83c4e7155cef4d36642556eb129e6fcd9a6b5537fb81ad167c78c29a6b515ffe9f7e4e5ec249a4040a51918d58d7642d99070d5eb18050b0a41b631e2b9804abb53ac60b56ac579084db532175766156e4e44c78d024bd6264c996a2de8028a3e059000b56b33cb72e7bdaf60c48b648f324f1367e0df98454ebae2b94e817b13982fb5d275874620a7a5528b1c4d4035a74f53c7f24244757b4d739407f4ad7e1faab334bf5311557acdef8bb1d3abec61837bbfb915331de185e43962cb1ae0a9b870ba243c36dbac7690c24fca5580ef1ddaaf4feb96ebd7374239c8a35248beb1aa007381ea9225ca2b6cb755fd11a0dcf6b57d5f0689f1f7a83d4fcb9b53f23a6d621565bab532297f6b11ad4545415aaad5ab6c518bff512b261170e802fca4050f44a277b84000b57aca673a6016b0f29935add9fb611a65d286178915d96e8e0aa6d5398245f43434644ce166bec6b296a2b57b961e0c061b435be4233f9a43cc0c9f4dd768629e9be0ee57b1ddeec2e093e29c0d7dbe4f3fa3e12ba8dd3d69284ebfbcbc216c87de5e18eca6989d8424fc88eb6ec5ee25f7d87005823e1b7816e1303ebad8260fd59a2609d12063b471589842e44e1f302e9df9005fa6103552b02ae6bba191076332dd7706aedeedba489865cb0d55120e6abef61702c2da0eb7529cc93e1db7e3ee365c36a57f18a967d53ef8a96207cedeedfba290f87e494359eaa58333a5de8707c050b06688b20feef99b680d8615bbb80036db219c9f512184d12377e1760ba786976950fbc66c57acadccce860e2f92950b24326c49b17b82005c0e2e4051e357ac4a02832cb5233dd55c7c2301c61ff90d82089add8a1dd1dec85a115d354760f51b4be87305a7789a3755af0f402482684cf7a8bf859df43dcf4a48840eaf4d1d10ab9d9928deaedd251bd45eed9da51526c6b75a8f4365fa873a56991a7fe5ca1a7be53eca993824fede489047999009e2db9c2bf8f4a8816670b1654d92a3ccc318f70e34e462724d0c64a091a34c47eb347ba16154885127e4e5227bc3f92cf3ae4ffe7a8fe9fa3da3f6996f4e6252ebae385ed53b71d9b51dbc64246680fc238c6bae208a6a7ef080482751d5fd1d231a490f5769f1dbaf99639ffcfc1f13f07c73fe2e07047c2bfcf78c9de5eb1fa8ab36bf2c2b86c4e4559b2a94930b3aaf99237fccacb162c75803f2f878d0549d7cd42d4e47955d48c93ffa472315d5092d14b4a6875452fa912be4c68d6396f16eb493e15cb21167a4745eb7c73dd5b2275577eb6ccf08771180c3c5c8556fcf51f984d665fb04af26663cc5b904e1e60c3290919163d311b4c614a2b58d21bbe5c2f23b851c59c1ce72c0f3b22fb64c96825fd44cb786da08d00f0645809b2fa8cc5cce615408ce2c393971ae61ed9d5bd604412d3fdfb75a5286c44de66fbfda86df4a7f6e4402836ef90b49b5697c8a65e4f9b75dd1a8a6e5ff01aa79189955a205a92891025a355df871a5cb4b8d7198d4e6a04b78416543b775262f8b50ea96fd01c3a97ce02f4140a3727f4c43de9cd6d487ed37e8681b8833190c9c666a39fac1b12f7a9da442db812b5340648afa9d7ac07ceb9145c5c6929aa39ae703a495414afdf74e487be4569ca749b08dd6f9866e069001a12a4874b2498340ea7f880a22b799cde6a27f4e4ee6c4e7c96d9116e03167a42e8f191a119ce63f34369759f97834e777060cd595fdc89ff21ca7d80ffab9d4c2141c3ff9fbd77516f1b4712465f05f1eeb1a998a67ce9ee9995a3cee6e2f47827b7b193be1cdbeb864848629b223424658b49fc5ee729ce339d0f55000880a024a77be69ffdff93dd698b2450b8150a5585ba942cae4c5bb2897edb655caa0b9cb1d88982647d0a3236ae4252f1794820206b4846bcaaf82c24cb8390d40721591e86a43eb40d13350cb33efeecaafee58b14ce9daaaafc9ad6dbd59d0af2117ab27165a3dfbe8ac796b9efc6de59add5184356e53a3040f494dfe8b32ce377924acb70bcac28759c81b420fc2e371b6f591c4ae84d3bf67afb1ab71653aabb339a401455fc2b2faa633e9b67ac6203fdcbf9f03c9dd3a24acd12fa952c3aa29910be92e769fea1606ce0be90c5e6b49a0ee0bfaa89b4105245f15a76cc7e0e151b9b2603f8aff1e208df1cc957397f8dde20f2877c7d47abaa3caf0a3ea1d5a781fda8ba90a57f5fb0176911676280c6d3a5762bb1f86f9cbc403956a3f90b794cb0cf869782fa998353903868b02a165716916f8115b82739396b8e3dc3b4a36273a56537ebf71b3dd8a39c7cf94272f20429b0a439aed1dbe5d6293a2419c05105b8e58dc638e9f4b16bbcecda8e5bb920866efcc489f6644a4392c2058cbe1be9f725875b601459bb7c4e76491a12f8d3aa57b298e789bfa2aa6455c0e9db2961529d219b6dee9183100e80dc74870700650595ed053976bc09267e9b070bb7dbf8f3427e974065aa0f4400b8797cdc85387e34894c3c5985295f892dc6e43518a33787113eb299dafdd09e526bda3d53be6e462535f2cca5fc22b7e05ff3d51358f8769e79bfa59b52ac57e7163c58b9059f5524630289aa3b6e30f54cd9a3425c17aba9afd99dc6efdfba77aabb4ba1c06f82b1005992fca60afdd67383f1a570d1f09b8343d6eefbcd134ba61d9c76a3e5d5870d114832eb5ceb912e27579de4e12c323cdfe45d25d442a2831580652a0dd14a5e475a1820a98daef17b310a3b803dd540fde0661b8093ddf3c16be1e9a3992603e2c76cedc9811c5192ce845821e47c0c1225fd5bdfb67b04626933b9865b3de06c41aa29cdc9fe5721f757e1742ef199ec92591ba7bb30f741e82ad89a36257a4faba9e12bbe1941ef5863658cf0af72f84fb4abf77eafbd26071d6b624c369eb469ab0bed79b6665a307e5e52f0439126f66417fc0eddf26724e6d96296af3f4aa18a9c7183da7b76251f2ba09ef2c61ac1b9a076daea03a2639904fc891e9cb5685f7322341dd3a17166f8d35da766753de7b16947b4f14edcc79de8d9854aff208fa0df043770ec1e3c78cd6bf20da032065452957ac766ac2651efb7ee7abbe22b5cfe3a351fb4f94116019c0cc927172d8f5ee2e275e2243c7d2299900dff6908da2aff094414e8c343f059fcf8f47b11fbe8ab319bfc16921bcb39b88dd5e2e7a73f00c16f107f6fc813f249e0ef8d8be0ab76c0467b40c554bb651919921b60881f93d9b15bc2dd2764172b590537df31aababd731eb67756c1b8590543f520b869603d26336203faba7de9e821dae7f37359808cd29c1635a90ac6d446dd703fda5bc680e3db375f754a43c079d55180fcd07d02c6916448ded06a1acdf95d701892dc2ca0b0c7dd46fbde0d73d0b67415b8adf0f6e058a2f0136c58e039e2866df95a602255f864f5650cba50f1f5313934be60c2a9e693b4126db316a200aafd7cb2267e05601bf01e063a49ed521b8d7e30980e8e7e54ebd0c662ed90fa3d185f5cd6bb61b4bf1f3e80bd069e6e2322d6a0c0265c9b29cc198ab5403e08d408e597f3f4137327f599d699984c1d962fcdacd4690eee2d7005075c6df7d41b4d1bbbcc8099260c9acdd82a00a2bb9e5d0ab541f8c1626a459b3535db8733b3e59cdaa601669dd49eca1d33c091d1b587813e57c9185cc806d2f8c26ead4ca862f4dac52299ae180a18bd16c7c163131f9c7c3bcac6af91dbac304976651798ad57b2e34ada70f643fff597826063bb0cb324e7411ba698232ca13b3a85a3c10cb85911d34faccd36d851b5c48909a02edb5ab8cd61ea928ec247956ee9769c99c63e84e437b737de83ba4d0e2c4dbce09b6f42320f49c9b45f9ea6023f89a27baa2c296734cbf6ee789125267bda45683f4c5bfbd45ff4c6541439caa01b92335ab0b222394b27d3112f8070cbb896739ef149ed873a870ecc0b3ea2a354d9d415ec2e85ba4029583261974af3a3a237385610d2666ed9fc18657cd49fd1b26245f352062de445d92f689ef0d935cc5019cd6bf76cb9112744eea1112fa69c970ca79915e4d79b5f23725a1999a8335a4c9406c7a580bfe6bf4abad1500eec89e73e0d3fecf4e48f402cbe1026be3974488fe7bc0a3131e7ef3eb3fa7db5d2b818ca98fba67fd8ac75d315fd0a288a64a7c619e745206a183714d60653da54b3b6bbcb36901f202d6df01bdc6b90ffcb128e2d0d56c5bb5558fd3ea21f93262a602ea987aecb649ccf31d19aa508c5bcdd4146478297837087e686909f952d664f83cb3929593606b025e1d2616c9ea95ed02ce3772aeabf1693fea06983c48480621024f9255f8c3216f4c81332f7c85e323b6f6a49529e996f4964ecee832865b484d7206e31969467b8024312c85a434c532bb07f124d69092b8914164af47a2dc1ce04b4bd4d264d5808a0c766ec63bc53f1c4fcbf636a5f4b9c006f3a299961bcff8a7332a3792d6303d820629e57696e05f026b6f0d7ef93937ccc8b98291cd8ebc001b39634303486d8eafd06d34dfe98c9be6f49e71877d2ad6bee3a025b5285115631d19ccf6ac79a4d7fcda549873f19ce8cb241c078622fd9bc6031add8d396894143a6e147d851e0b4c2134617542fac384668260ec7394bc8fbb3b73f48e3a53b4e66ac9af2a454017c60e5142d6976a71bd9419e11693e5f54e7cc8ae700e7c690c888b4ba04868fc1136a873c353e0c48b02b4ebc9760376c85fd12af7f50a7289c483d37d086f319fb0111b76547c41f159ea31110653ce1529d87695e31718eca2354ca8105cd27d2867d9f04691e678b32bd653d694a0851b948003e46f0becdfbe85252363c3bf9dbc7d3b393971179374b2b08ce84bb1c3f8333af8c3394829116c6f1922783583aadffd3233702938b358388f2cbea78f5801358d9078cf7a0355074426ecc9cd02941e5f980c358e2490feab279858e0969456225192352f6d60d0a11510e0d1fac7027ca0e90aaf115acb1005de4e99817b30c72b75fec87e44021b4af3959badd96aff0842eca32a5b9a040f2a793bf57be358209420a3ec18772214b2b6b14f1e6395feebd5900a757a9388eb2d288962c213cd7fc689a57058fcb282ea37991e631ab781eb164d1ff8dded2fee151c1e205c470ef9f57c919d265f149edd32224cb90d4b0dd12ae08fa526c5db17bacb3f93139044b122c536f504650a425794c966497d4e4b16ce75e9d2585e07741575d48bd961dfa465405042aff5e54c1dea17accf824287afda21dedcfea4b8b18297aa0c2aa9cf1112b2af25f2cbf49f372871c1d9211e466442a30a5e55423366c38092840b67897ec2fffc4926fbf4d0ebeeb915d826f9f3c210787bd1ed926fbcbb1fc77dcaefcdf647f19ffe9bb83f8f028ee91ff9695bffffe7b72f01feb6b8ba60fbefbf6bbeffe343ab09afe76b3bac9113dfcee9bef8c969f3c211bb63b4efeb4ffcd77f1b756bb479b8d78f4edb7f49bf1fe7f3823fece57db43be3566605da34a8ff4c594ece33f2f5e048a0adb667886b8e043675da9393dace33455672f32e6e86f8ae6e8cac238add80c7207614a89541d9cc89aa3c3573a53f62c4b19b46eb2a005cdab26dccd3bc94b798e6075de07b27d8c8a8cdbddd807198f6976a6780ab310ec4149a575742d79781bb5f06479e44ff1d8ceb66936907086217966901c4a5bd73c7b7f3a50fc867988d8f1cced883a9fb54c7242e3e940fd08b53c85e71dd8969f4f17e37106363d62f27190591d8a65986734668a7d568278891506eac7a511c8baf1f7c16f8115110eefbd2a570486868d542e4226fa5e88467b7ba64cf41ba425b0a73a90067610a783e8935855a914f48bdf9a9007ea85fe96badf52f1adead014ab74276df590f2cb8a69968d687cf33f7beceab51a4dd0be75c05c3bcd008c0eeb5a0875ffcabafa11fcbf74dec91583848c3b9917fc361582bbd8ecb44aa5022aa3b5b22edc8fbe8b96244b47052d6a50f3003b3862000bc597a4f1db5c562a3d99240d98d382dd8261525bc1831fba2ca6c598ee6801e9cc29e4d23981f23637d3554a871a8e795ef28cc1417db985e3070943ecec44c93b4944de678c960c78a11fd35b2a7b17f4d44502de962882f468e206beb5ee359a71bf9411ba872498443c7703522bbb74f1713c5ef1752c8454fbb3d11dab2d3372999c7c9a158c26b54a9f18ca503bd6003446b165c5f26460654669e44ee7069c907b7d01c7f3011183d42fca8acfe1d5782c71b29b84aa56f1af04e14074e0b56821d6b549611b43c8504e8b0a2f4d3c8584f80da864a4d9f194e2f9b13589ed226bc4f073c12b4f1cd1415bf351329fd6651ad38c9450309215945ab2049979c4939495216864400f8d5402a095553a1e63d817cec6e3344e595e813cad3dabee583a9956ee798e0d81fae1394fea90541cff22f010e185b2b671f6a66524b564aaeeb1f109746508ca7cadf451c4ca8a069f5444341557ccf8846d37d2bd7ab6457bf97600c2804aec6352c4b424cf6991b392fc65519132059f61b8a7c926bc48ab2966793f4c20a854444e5b51260588693a99663551e9cb131240462bb124f102525f89599fc490cbbd5c1420b5622f8c90982df129e68ba264659f16f134bd65fd31cdb2fda37e5c1e1c7ed7a765994e72c88cd61fc110f6a68b2a9a56b34c13e1b6338adad888012a00a87c029f49fcf5e50b26dbd2dfa249416fd1cf5dce78eb833df5eee7810a3fa53e545306c1221d70f2b51f187e1c90fde8cf121d5059290f1892b08a15b3344fcb2a8d259f053b60ca0a1d4073e37b8783fff8f337ca14423aaf1b21bd739eb01df5f9342f5951417850bb54da7cd085d3f29cced87b5ea211ac5ddefab663c6cd6c56c0995b0976314f68c5fea61325aad6acae417abce68db60551ab61cdb4666641cfff82c6530bb2f4503fcdd5977df9419a6fe4ec0e6e571c89fab3d9afe740c006d653d8e6a0c1df16c0e23ddc98a415a4db13d4d2619e27ac3ae3bcf21f632ae632e79af9b4a64f50a757bc88d940be50e711ce8b01346777efac5d44b402def3c192669a12deddd3be6295ebdeaee7530b7735d5de592d5f0fc401b78edd488b2110f4d8e7fae172177a24036223ae6e7b807f342c8b9f758f7c8d5d66b856954b50115ac273f2c30b241182c19321c49a7bbb262605e2f7858dd457a651ac1da10fa207fc7d41937d3b5da7f1e5a0f3cb61e79723ef17c80bedfb30a365a9421988df3f9b0fbf1891fd6479694205bf95d1143c547cae7ea25ba51915d0c963ab668ddd11bdc19b2ffe8994c05df96677d72e673355ba862b07e2de944128c49eb5383f952cd6a0884d320afd2b59363f1b542c42325e1ab48c90716d3d02f0d78a69396858de693aae4e13bbee7c514ef15d638e06002ef6afa4b99a1bf3d380ef8907a972c85ea8e6ae8c4da4b044618c21629abdde1b1a211475b777cdb7181b47e6967e8e6003002f241163da8f4dca0705b6b7ed9a6e4cc5535430cb65d7761594648ca2b9000904bb840100219523c69a16d04dcb4488f4a9723580e70c5c27b2252b2a1991d96d47c88dc0c942c4c22401da6541a433b0a6aa80b5ae774a92b30a011b579cb0a0e27b34e765b4247bc68ce02b8364c2dce9c275bbb049c40b653b00dae664491e8bc6760590c724a97bd6fd32dc5fb78c31e540de735e9019cd7720915725e373d00915522df9c40aae43235997b73036efb5f81ed98fbeed913ef976dfbab044e478488d0d46a98a5a070e04e446ae5df43ca145228f12a91b8a8d642362ad179520fd18e2da0233aa49f1df4790500b9cadefb819ad04b269a9009a42e642d0b72caeacfcecb71810014ee7c7b8c6408f1f9b4b0c6ffa62a51e13f89f39bc31ecbb5b9800f375ad5f37d86164c158b9c1dea99814a1b33f302a89e84c110a72c30a464a75597697264dbccf824da4939886aa3dcd9aad052ef5b9b4adc43d5528709e3860b883eddd96273a8ae80e862765c51e1fef894973f69b71c4f58db36ffdde338ec39515ff31fbf09c17454de8882f2a8c929c2ce6d902131c44e4d449ef86e64c6858a10ebbd28188c736bda37544fe6b511ab9e1988e628c11cfd2a2acfec537b731aed331e2267942fedfff27c4502e32b783896818db05835d19d4dc42750b2e6edeb4c2930143bcea95b78f0283fc37453a0e01b1ea81c147ed350c564f0e03b8d9364a48bd693a1654ac02758240905b0676372a74b6dc13725fe659ed4019b198aafb5bdcafe48e96a4fcfb8216e93865094916688808c988c46caa2b44038a0ac95b303c6df5d96d6c5d4cde213b52902928552c4036216cf6d8e684b093147610c336534a5ad4af5848f7c882c72c59406255b889be65592dd0008324b5f911418aa66996144ccc97d3c029a0638e1ab4ac268b7cccb3844904ca389f87fa5c29d92d2b68465ebcff48e23ace986d28a5f3328218d1326542464fb2908a81c6b2c79e9292bbb3f838fca7b8d0d6a7963f4e23ba3ca0376e737f7c6f0e1fd09bc37f786f8e1ed09ba33fbe379df65fc65e43620570c66a37b53ec3be1afb2fda4c7d4c805a664bc45a0ad9162d89a237cf7ebefef1d9eb8f279a39af577e5d1e1a5f4fdfba75577e6d3c56675472e1a9118238375501183a988865402298b079a5b3d2659cdf48de8eb0258d2b32e20b4c2b30e24b15b6187cd58d8d9b6228c6634b644bf7f61c51ade9da457ae5b025e27bddfa5e5b92d4923c214b7b0fc28c2f5dfb5d55fc7bb2b437094c7247f19a3c21b50d1d56acee2afe7d1305ca58a45671d398f81ccfa15a327e8b3c31f52ec0882c0fc91e591e1852b8002a5ed60786de2511a3b3d85c6c1dd2a42c3b5414387c2852bb3a87b6de52691dda7a4bf55a294e9607e64ba541591e9a6f5195525b25b54ea53e6c9ce910970c5b25e9cd623392b27e62e18ca91aebc043dcc281ae120224f792d8b3eb839cdd598285a1428e8410d0641d31bf405849f4a053005cddc623b37c5a9ecce6551df49cbd538aafa715036b6b133e9f5bae8b521da28b4396e9b636a4f9eea844304a82d295b8529412342dde33221f41a504488dc9da80ab913c844e86600b32a6c4d8d086b6b4621086b644e2d5f691dd46eaf495fdd9969b762d1975e9abf18b2d30d935ea63471a3f33f8295c2a2de7292e97cee7059f17a9983541890b9a9bbc63bf4f9e2f2a19f4649c4a79704d25d4f1d14469db20067f592e664c1177d9f8fe4e09052daecb548142fc374b7a913bdae4ec778962ea0fadb286cab4e273eb93deee81a951dd1555004e4b7e1434ae90d7a910c38acf184ae872280c5c7a723890ace13413a17eed3abc83729b15e08f7d836dc6da7d9f200e011c86ec21e8e84094aaa66b3b643365387108edd83b6dc6ac752983202e9fe0d2319fe50bf1533a8fcb764df902363b146fcb631fd4d635b7fb6821854f857f4a1b59d11b9647e459923860cac5487909a5f612a96eba078bf1559d2fe28fe72bce58c5e79e6fdaf7b9b5bef85d4faa67c25509ada4741c584aefc48658afb75e1a538e20a464708b9d4f109f8d79b52522f73c818642d4fdfa90b3dd2e66cd1744a02a6a74c443f99e630c34a5658edc2a1876119257dd0a4aa62442a891e66259cdb3c0aa0e445f8d9526c045ea505e0ee5e259f2bcada857255ad73da831301a2e49c20113635ad4922370c9897d8d1cc826c5a112eae3a5e7511a17601f43d27c9ce62924f01825e96d5a623271325acce698778b39732067a1366896b1c66639cc285215a9f49f2543620b498d09b8356be371c92adbb147e9a28edbc551d3d5a59e792cc1f92ad62ed5ded324deaa68573566385a9aa78bc9a4fa0ad7e605dcaeade2207813d64cd55e5b62ecf7c91b7a2356aa80d30ff58962a1485a61a2e2b13c949711391d639910adf6d070d888c4354e9724b596ab3194373bf23dd927dbdb64333473260bd4a516020c870f01e7f15753ccda2d133b822621dcf8d25c8d7f5eb01890386a554de58c10f476836b473062823c55683078c776b24c1c324006da20d46e01e748480947ceb9005bd2b848c769cc48cc8b82c51518a340c0cf9a2f2a543ede3036575c0f2916796ee42ad36dbc15cb85b5daab267a26bd6f2d19d68a2807e129457b628ded7b2fa26f5cd7ea1c9aceb47a216945220fd3f1a2a8a6ccbc2e6911773c54e4325ba7b5bfa47d0ab8d9d31c6f17fbe46a925c027914e401f5f5c64db3a15a330b1db40b1db40a1db60b1db60a1db50b21e9536ff17adf761b285b0351c7af773c965902948316f4d591312acb4e6145d1c39e6db8b0a2e851cfb6645045ef2dd3bb53759c25b4a24d447871f8ea6b2672f892fc6d41930f05d367cde3fe0a9b36625a83f4fb28849415e495940138b4176b444e73432fc4f3ac6e18839204a31af4f0d0b194e73d0932c68c0764c4d38481a3221a23dad619b2302c9a11cb5377051a2e65fc49e844aa4d99f0720dcd730612d03ef9420ee4ef3df14ffe3e245fc891ee43cb1245bf3df0be3df4be3d6a0de38325e59a5a725d514aa5fbc6d841fe1515e05bcc7991a439add09b5757fa59eb5ef4ab5f6c401639f381916cb301055965e38563ce02ef14cfbcdfd885b610cb3093b3ac74df2d0ac836aecd40c53835aa0286e57bfaa601d84fb049fae10599c2d92a6d4f1de46f301f34169003026d4d4ba883fe3c772e6b2bc56ee04f354647ae49af699f18d816bba5b40cbcb8324d6fe77c2ea56b45904e4d9aacbc0ec950eb88509bb3c678dc823d342c8c5420f045393573131874df8d0898a286a819c38501fcca15fd44e90e4f77475480b592f95ed18c8c0dd4bd6cceeed4a2b420011101cb013a2a79b6a85856939cc5ac2c6951dbc53b3addb6cf3cc1c6bce79f5fe82230319161d876ecf96c4b7c9e537e77d7e898bb487c6eae51dbcad1586437328f8b0b38097b7b1d6b776fb70ccac7ceb6db882b4138acc1eaf9b53687398d6291dd1389d82700cc27249e55c6fbf001b7ae996c18772dbad521a80e2f01c31dcde28de73ccdab8390c0df43eb6a06460f37f07454ca8260a4846523ad17d1e28e5bb86e0ad7adc04601a4123f607b7f0653af5a3ef45650d266bd94bf42c9c0e3bc341c033736cbc63030d2c7439e0fcfb91834f94c960703b21f921aff2c0ff149fcd116a4b65dea882f0726186df38cc683036d17dc2e01d8483ad0d10019c1d58df9026e5b9a4b5cabeca15bf690d874127f4d58f59c95d55b76a770c2a29b2a348aa35b87193dc394224623c776c0f6112dd9cfa859153fcd3399682367d940db2fcd1f6ecaadd00ec74264bbbbc3a670fbf64c95fbc55baeeed21622e8feb0dd0fbbcc2f2bcbb409ae9aaa40cf6c04b74ec6e3a1d2f8daed58756abb4eedd47102eaa34790b641559b2932dfebba6d336c81f038d3569414b3768fecd9add8baef7aa0d6e04110f470ac3b28d7b0bbb5e11c0f57cfad2fd17767ca0a4bc9b3e41e924082524429f8eec4d10e62ba194d6af58df6ba3bed75b7da1df7daf605997381d7ef4bf3a712fcae4319aa22c57cf63c67640c9702e8b329983fc1fb3d35aa4ff99d343d9ba779cea438f2d4daebfe8bc5c6a0374acbf750d9daac2353d9850f05bb7def6cd591a9e5b24ab5cc1a5bb015b8aedb321b9cffdaecbe3518ecb2ff72ddd34c1700ff75fbc600ba2ee0371e42d7957c37004d425a0793bed26e1d43fa5abb7576d5be3a782d7fa8ec496c99dff06d4c0a2a4d6a9b2805c942a6868e19c699d1f659a0b71ad56492de32f4b833dc1923ed48a702ec612ecf7bedc9a6d225368d5ac571430e75f948947b017e874d0dab45b21f1d1879dcd6aa251c5f3bc841ca8a09f3703af07ea7b9e316d04a5f41fca0bdc31aff3d80a05a0c157ae8310dc87eb40f64f8def42ca3f3b411e490fc5a6c8d237f8d4c0ba3bda167eaa431f42dcb789c56b5b11f46a6f9d146756bdf61d1ef938c5584d1b2263416329620eccd3845199ca46632e83c0dc9c58e2eb473e538a6d179da761335f0168f331b7371b624e69684c615de8f58deb931cff30a424d00c8514da8f2eadd187fcdc657633096c4c9346bb5f6cd3a10f2e04e5899162c91feb998fb59c2a515781d47ff804d70fcbbe4823f6ae71873097b677f5fb141e6140dc89ff7576f2ad397f1e3bcf4a38c9a5655b2dfb921b19cc3db8b6d2368b3c42c881e6771cd3c010a2dbf57dcfaaaddb0e567f9fc84ec1bfeb7165e0ceca21634ed2173a85d64a07bf86417adada2b555b4b68d3336b7caefb6c9ff97b2817718fb44602cd9238ed801a60ed2173e081ec969c7375fbe10eb192283bb2b86c4606095ec89ae80a1fa63f51edde58d59c485308c496349a2139ba21f9816a5ba4ced403a340f8d0e4887e6e160416a9d011df4dd18f14e48764c94ddb9b262fa497a6f91fbf7e83fa17727c4e1c27bae501ac20323028997056b12918f252bc9c9226385ba2f04f781ec16e9b4f6d5496946d8df17a8320ea4e33fcba3bbf4269db324a5112f267df1d40768d7125acf38245438271d4718ccfd59d2f8dbf0b1344c9b2bff72794445dd6101d420593b5b28bcd66a1b31e8f38acd0d32ae4cb02adbf131a9e56bdb797213f35d993bddd9bc72cdf62d6b6527c6eb8c2e6db5824fc0b1921fe09e52c3227dcb9c4e71b816276362b8c9081dfb4ad71da56b430377ab259ca611a38fb775ebb349146f2d4a732b28cdada034b782d2dc1a2451ccea2df9de8af7ea0e6d28eaf6c9edb1bf80e8c96d6d14d0d40b9040cf6217f707ebd059aab6671c8f8ddd6143200ce147bc6eca57504e2b319365ef58e09df5aef6c5f00a2a315fa23a01c795aaeef5d1b8bb49fd8a9a5c5f1423f925d209cf3b231ae92b91392fedc06f39bb532d44cf79524389e34e6d305415e506f05fc0831fc12bf13019e85fa12a75940ce45fa3e4912e7994b454e3d08765486a337ce99c97f26642b580459aeb342986af29855ca853c6f8ae5061451179d578a02ea5d03e44c7c02c596584d568f8a5d6880ce5821a223c2c5b638a6ab34c2dcdde9d69b347dcdccb2fc9f6b60a70b2c498756ee805b856961148698eb980d1d1f4b2b95e5836715296d1d28d8e225e0db48a182ad46685566c16f14a55b0d52fadd65a5557b4d46ac76845ae979a2863cd508b3e6c6bd19bbea876f6db338fe80df3de24d8f262ad516a35e27a0bb671f7683dee1eadc5dda36443ec7507f77b11d829f3c92c231e3e7521796bb2ff87e0b9acf0c9acf0a95de1d33f7963b4bbd5ead4276b171d37dbe8e82bb7916e7195f5833eb3ca05682434cb97a5829d3cc7b7faebb11bfeeebce20505011fefce4fccb7663542e44304686fd55651d6740960d79c222ad0ab2c33c6a0ee7621f1d264fd65e13692afeaac362d121f18b887a1b96c2623c59568649c9610b637227f651045150be574c642a9db4c652850098f8f75304752b09817d257aadf97059eb9dfd14db8ac4aab6e936506e267944da0b798e7155b56caa4e833d9814ebda533b64386df938bcf0a48a36608495c2d0784a342ea0a852fb4de9d8801170ce3e4096c41ad5584b317e48b2cf3077db26f29751f423d0668d409a82437861e6647ec57e28dffaa2a897550f15ef10e9e9206465bdd2e063aa5799289651db6c67ca1fb6edf983c5275ac6e6d06c834c2317aa22aa325a4b150d69c0dc47fee4d15480bd5897581ccc7e3356be1e897ee685e7de06710fcf3599691a15e195d1749970e54b96387877100b81e577f4db30c346159a2a25796928834e9cb58ce1793a936308f69c9060d948d31b3a9e099234b2d83d6ca9d6bd6324b4a58c62a31bc177216cb57bc806ac68475a1b263b5d40dcbd56941c18d90d46f35041a26d5c886e84ebaf27b29382b6efa655e3255f222bd8af49c081cf2a0a0fad7802fe7591ab3200dcd045ecee621ddbed31bee13717478378ab33d1e3a7de891a42af98ce556602524a4490bf6ac982c6632386e0396aab74a8bfbbd93e6c5aa4a86e4194418363851985958920658e8c9930618f0700430e7eb341f73d2acb875074dac521a45223a9f6775607fab96a13d2eaf96d5bfd89752ad685b5e77f13a0ddffbc87ee5397f60fdd371adf2e92c4a46c6342b6b79ae125a6a6287b09a68e3eab42d5971cb929f045b208e881d9eef8464478c55fce5e3f10ece986f335ab5bdeb21c6a178a7292ddfdde5ef0b3e6745550756e58bf4caf4bd68e79c94d36464046338f894252129d31ca3b0a888c4530a91a9a025b273b9457689db1ed925975b3b4e4ed3ee88ba60b24d7354606f76c5f4900b26595c5a4f35313ba3fec72acdca7e2166f037a504520ae5972ae67cc1205c880cd043207512f873c0459a0e373b5a5498666e36cf52749d7a8c061e05cb1356408a948a15631ab3883ccb327e075181b31490a8e22abc3729e72c4ec769ac35c178b5f4b8397d202a2d0383e32a8d957b89f417529947edeb498890fd03664114ffbd9709202b2eab7b2f3317252bcea595926b9aac560dada142abacc637f3a5beac335f86267999d1e5cf64400ef60fbf09adb7bfb4df9698f867e76557e8d8194d1899818b90603976242a2a9c54de477126c4fb329dcdb39a8cb95897923c7b7f0a09b374e201b1fd4b3e636a923571954c4cfff16fe534cd2bb2c817254b06402b98be0a54e8aadde0ac39804415a687bc69ed2776aaf819b44c98da464d6d33a6d61b2b45302c3ce4182343f2b9393ac53fc86ff09627ec853edf1dfbee2efbe0d6c9bf1cc0a8d1d6cc1ab858f05ee896af5795ffa5e7700c2687648d00ef4f7e30e6b2e9bfda5a6133d75e4e479503db23d35410725f9ba68343d294751266b7407def98195aa00e1f00aab67a553bbdaaad5ed5eb407def18325aa00ebb41d9b38e480569561bdd88c5cca3b0a19967f2d4c7eb93818b902c2f170560e4699e5629cd2062f75aa434fa73012e44692204b6167a636d871d755028f0013351680d2e8a8a4a5358fa743ef6daf893d6b62d255d9f56072f5d3271dc55da6b29d959da6b37d90d7ba515a5553e92c942c02fccbbeaddf38cc50549eb421248dc67cfb641072fc4678922e26767433c07ac7831a5f9c46a2188e155d95a51afc88565570a5c44c74c80d46a4355c9e6b74dbcc10291773b78cae19f0fe0152476264d1237c2b4fdcfbb2656ab9e8e914ebf17f39f1488cd7d66c0150bd305bafdfade1ca467d9ffc8c97030ce6af58f990c444f03ee0327a353cebed7bbf081bbcf2a0e892fbd736117e779b083834876426717b55c564c3d9336c422608cf5acaad86c8e8cb3e47f9b94f2692e8d3d9a74c6daebd98ae467c354dcafcce1764f2e9a5a407daf0c809af3df29bb80138850a2f864ed050e895c4ad483418b8283b52af60d95c222b72cc89c1eb550533a67b179d04d24ddb97c9733b4d6d50eeecde8bafa05e53b3dba88ffc80bdc90028d4f59b14047ad9c83bf958ce7017139a24dc7a132380a818e4298d1c64bf3f3f22024f54148968721a90fef1b0b6665266a8152feb2e59cc68cf0385ecc53f4f16d52947b6665c2aa86df5c393b66b6f9335359b47e907f5fb0b2429f6bcc804431e32784092c3b7a96a4255856aeec94dca2e3b1daa3de2ddad54fab9b2fa62cbe8188cc706328b7a30cd6834e0dc7762a6a0cc329d1af60b250d74ca725601694711d4f3b1d170b2bb3f1cafecb692e5b1b0224f534ef2ff2799a93267050a97146b1c916bcf7861f87528b4b6d0b1d8ff17a6354b75b8328b7d91dad6dfc2cd88ca6398140bb2c2dbc6d1ab3354f73315d6d0f5daf8f884af1cde71b4e1664f9d0766b60680c1333aa6162d2040298c0ab3b2a63c33396633cead41e596b06f4ad44730787eb29b33a7a862b59e6c6c1ce79b11115f9acb240df3b4383c3b7bb6571fcf95cfb44b55377a28df4d32e177aea1cef5dd235043d690d119a035be2d3a42d6157bcab46c54f134bc2ee96afdd893befc0828a132a09801309c03381a5bb7436c69e269873b6b5c5c1e40b0c425c19cd9d472df77ad93adb1ea3fdadb6e267ca69e99ca13e798de8ac757a4db2ecee897cae12f52a2d136129505169512e3d587076419085425a3da84c3324386ab04a50daa4c6681aab49570b58e42e31a83d737687d5759b55914e26ac285df355107b349d5fcf7b29cd63ceeedebb22fabb02b239ed611a214c3ea1d1a39a329be2ae9b25a023f03e413dad1814cf598439a3740d9b2f50b5a710cd5c655e6e9d3ff71822c8b9bc56f6cb7647e58502f46109d56aa5604f21e73a1cf6c879ae98411d401ba76707e9ac3d430d46a525066a6709a1a5649d9dc8608f313a9a9987c3338d32c12459943846c4303b909e7514a95525b6df73d7727b35234d92a42e241976db1ab47a626838bb217ae8411787eb96f3e55bc27f2dd54dbf6fe44fa1705921993db99d5a9d0e8d1818f0b10590fa76bab646f0724a1eed58f702f95cb71ba1d20cec641d37489b7df7a7dd14bce59df89fe33463ef6e59719bb23b82e9344b427392cee844a68d021274c746930c38d934964a7ff4a53a9fd239a8f525232a23f133c3789f2eaa292fc8b33c29584afe4acb693ca524a03794d0fc96ded01ee9eba4ea93b49a2e4651cc677dfc68a556fd4974e35995d1d24e1f77a7dfab9b28f0facfe086ca53b4b9af6adda6c1f753317c98ee824f0a3ab3afb6e434c1a507231f4f618634230e00f4ad958c77a45877f91aa8869a669c48eb0229976e0e559ab1f23d2b3eb0a510c37441f322c9dbe1c0a9d91871fdc4463fbc8624d729cd31130399d1789ae60cc2c741bc26bcac31a8a8bcb7c1e25356a0f58998e4671f3e9c9d3efff8e1e4fcfafdc9d9f5fbb3d337a71f4e7f3c214372f067ed9806b3f3ea5c9bc589aebe2ae84410c3f3294d5811f4ecc23fda857f6445c596ada2ce30c1d0de7ef3e50b5c7d8174fce1ddcb7703c16e37c9fc6774492a59b44c3fe96c895420936e66aed140c693c8f4cfd1623c66857e5c088cd34f19c78c27a53d36150072df7e2dafab5e659c564787609c107cf74d33584845a19fa64c073e859928685e8a0355bf11c3799916157a0c5cb68cd2324e9301fcd79bbdfba374f13459523b7b95cc6e0313a04980cee9ad0149a44e93a5e03df2842d5d50915b56b0a27be82560b4ae624dbb69c3e79adb9dbb124a834003e3b711ca64c66fe5e7e6b7f11928f97bbd0f06ed574ee0940f6a1906ee0ba7e079fa49475911bf8d46058918c8bf97be5011051b17ac9c4a140f24fe9ad1fee4398f1fa29c56e92d7b67db6c1032c922d4913a80ecf2aed30ba0ab51800c05209c5c05482b2db388c6a2a8fa30c92e2eb73e9cfcfce1e3d909d83ea4c9f2ca283d4af3a4291bc992d7872f43e2ebd4248b2ab604e277f8d2adb01f8aef673f3c7f66fff8f8f6fcf487b7272faf9ffff2e12454bb3f8ac57953da90df2bfd62ea02371edf3cfbe1fad5e9eb0f2767f0faf5e9db9367675f03e7f46d1bcef59bd3f76f9ebdbf16bf4fce3f341ac049164d58ce0a5ab137e97c46e73664a3fd459e0afc3b48034d8e2e2eb74a2a4eaf422f02624fe35ce44105419f8c47cb254d67a4061d361cc5721d918e1849aac1540bceeab404fae45894c9a60539c46213564958a515093fd5ac93eb11a74074de0c19bb03acf0644fc469f1c87cdfb173709ffa3621661c48fd419b1b76150716678c16d070b0323f81a0d1c1247b81d6ccba1f930cf69e7c2d012c24cb23991fa39a5e5b2a1928415f1b8eaac532e8f2f2f42343042ef7bae234e4691daa33dec4bc52979230d4478d891ae88455afd54b553a2417975bf4fa16cefef7bcbcdc0a8978112fca8acf9e5555918e161593ef17d7655c30960b6aaadee853511741b4df779e0f9ce743e7f948037438b2ad2b6b4baabd366ef65ae454095d16c502c0723aca24b78303443ea001a767c398e8f5b5dc296b1a95e7b741c59fc39ba0e7dde0735300f9781a12531504f7b33a6dddc7d3284dc8e34e1651f61ff0e622c54080ca6d5ed6173c8c5b8cec920351744ff9cdaf2e7b78d574e75a86d37e4cbed1e337cb1e355dd85d03f69b0774e15b7f1764c68276f9ef369f893f19dd58d7e53f7776e3d0db8dff78c082ec3fa01f07070fecc8c1e1e6eb7270f4808539f8e6812b73f0ed037af2dd43e6e44f9d3d39f2eec3869b0d16cdd9a6e408a4a96c59b13c4152005f4243fe083bf765cfec1fca2abb66265f8ccba055d1e639fda2791d2cd2a82c629d32674c02a39271982e523de0a10937b282d5bbf7fd56ad260c45bf4f801d544aa09a55707c420862990b017b4bce98f840d26a609fca70da62e743c32ec5dbf74d7b6f584e7a4ff846f89074d5e2968c85b0038b1a1f8c18f9f7a6f37b43889f98c5b7b7492754a39a584073b43843d85bb38ccfe65c320b7c5e0306bea7456562e1bad3c1c4d595c5d6a171c7843b725ca0b4d92001aa9c25cdc6c26763adcdf2eab577a73a726090b33bfda0e16b619d0ccd8b56cdbf20bbf6c112f2fd0d09f627b80b49139b1253580ec99d048a9a0332242ad48ab7f1f68ce5a07b69b8cf15fc9d14e5242731c9a2676767cf7eb97efef1d52b21de20cf611686172f6945db8525ce4cb2e8e52f6f9fbd397d71fdf2ecd94f7688073d02035bcd51813df1b121f84a46ed0dad8a74f9cdf8d6e4d7b4c48ed5c266157a1e108726afd770a0214e7b2867bb25464f32c9c9214ff69e8379bb8fcf0bc9218cfed5eb77cf3ee83e1d91c796a62812d22cee8093d7276f4ede7e08c9be31c3ab1b73d9c3901c7c659b87e2d46a1667853c68b2bd4941ef00640962ecd9e9b3b73fbc3e390721de2203df69ae1466522bf53e968c4cb2324bc735488325680acb968bab4ff16885a6b8c03e5d6ee9e41964c69274319b93b118faf1e556a88adc52bc3bb865f13724e6192f3abe1e915b397a3820cd52128b88123c5e924648d9b0dcc186e50e372c7784e5f4382032384df340fc12b3d540511156ccd1817f39d98f5a25c54a5fbf8238741917128794990f5f06cd98437baaa265dd3bb6c11809c13ded1e7c5dbb07bfb7ddc3af6bf7f0f7b67bf475ed1e6ddcee67179ac0f6601f28c43e38c7917ba3e2fde596f87915fdc6d33cb8dcbabcccd193e9dee370ded6ecfbf722558449347e480c95808daa4d39d8aba4ad2af06d0180696a0f7c8566b4fa86180a055f196cb4a524780851d870d34db26b236686d12df218d7c798a2be3934b5660638ec75cc8b1cd400339e04ed790bc93791a79618e929a8f4b1e238e3bcf054277d513f6ccf4d074c51e28cdf912181004f9b561323248206f40d20fea22f78b698e5b2db7a18a1d97a4723d82f1ca9aed86fd75335d371a0265790c57d7731dd7d885bec30682d94260406bc83cde11d6c02eff041fddbf7c1dbb8374e6d1bffcd6ae4f1502fafb5996cd8424a3596f6f106756a55472cea26153ee9a55f8deafdd528bb8a4afa7c3c9b4b5eeb2ada88d24a0522b30c989fe65ad97f510cec72484ce16ebdc9385829aaab52bcc6c3ac77ea262f557237ca455d162cd70ac60002e4ad69508a5bf2ae5155fdba8625ac8dda1533a46fbdc1a2012d8cc4b39e5e5f2b5071a03cb7e0c9096c234b1c1dae3607047b64d5056c929c8e9bc1c67c06b664bc421bc69a2f0a927071665880625640f6265ea4933487c0b5451aa3f29dcee759ead8959173c6880cd378777717dd4c0b9ef312a234a2837f51a31545bf9cb3b8ec67b46265d5ffb76fa243c0be192f1849584585f8df354b454cc840fc9162911591b258659c22adadb45b7035a5e0605a4ad306bcda170205f83c223005f277daa214b8a78acb5cfccfbf4b9595ccb12a0657f7b0f7f2f9a27a43733a8183d674a5864ffd562969a7620201fb587d2163c280e1f7dd421e10869d483708a39007c4396e89cedaf8dddffd15d5c457bb125381043c318d217e805176addfbb5c9006c574d853687d0f51c7c4af349f44e8e88c8bddb8344b8776094825361c2d2acc88749b960b70e029552eb43c212c9934b634d213c2424fb47e50d199f7c08d038e17413226cafc8a8cd894dea6bc88c80b2481594dcac55ca0214b1aa7180995e0edd0f38c614eb13dd0f118b1dc4342d16fbbe2e0a90dcce49c162c8f219fb518403f033f671072d5a62298beadb8652f71b7a1ba87ec49f76db3858a65999c6674d6c78a6a9f4a8d9006dcfea7a852b929593a88f6fbfff66d74e86c5afb38549bd50cd42dcd7f57c4c8360c849db91dc0dc866609ff1c491777ab245c078394b5faeb8f60c83fb03b4220fef2801c84eedb89f7edc8fb968ab7e6cb7bf570dfec1fa2ef00202f202b2c300a4dcf38afec0f99f588ea31f30d6acaac57b6b994f50910d2ffc9d49a5eb84344b115fedffda4855aef27f5d5ff497c35bf5c59e516252b5a06a0fe1282767b4ba8bb9d8babf63cb45fa7795a5960cc8f34cb948bf9e7fbd0f962463470da694e0df798097aadbe3a854deb442cdc1df5c181f4f1f4f922cd123835dbbe4aee26404ed63886821e58fffdd7a2acc88cde3042254ba7425bcbd0210999e8907124a0e62010f95513f7ad091593e3efa5f29c5dd14b71ea05fbcbd191f8bff1d8d7566baa8084db33e5dc337c944a09d74fdee988b1ac917b5361eabd9d6ac6dc6c5aad3d6b10bcf13ca6428696a951d7f4d6dad92b76b2f96fc5ae768a75edf0763151f26acde89aeb9875a3c2bb51494cc9f6b645433de58971a963168dd44b08003da3cb06aabc8efc09ef240eda0b4acc8b210ba87edb09f52f48b8bbc04230860c2262649160e605a312e02c3a9724cd79e30230f054406aa32dde7bc104f4c9a102297eaf026bee71f2d983d60f037bbf1a25c669c1ce582930de0eaba026dcb3d8ea1304f30c2eb70a591ff405666bd6f96caea0a0c0699ef0bb28e131f8af48431f9506f2720b8d1f1548f390d75ce7d0ee9a74d5fb78ea77d2f3933b75ba341e7a2ba74bfa3cd86d348e0f9d6d38be0f2bdb50c280fa271df10487de7867091113a70cd9f9c6ef19eecf221b82034f72f5233c1cb4b70cf504308586681cb379657915391e69420ad65c3e48163371b669ff2895acb5e92678b8e834d0abbbab922d9c8edd3e4be720f01c832871ed218424cd8d940c328f5be3716ab7d5385dad7053b5ebb498033b6593dde10e5a2b9533ee8a3c1a0ec9e5960276b9d5417955e0987e9f543ce1038c09f75467e317d261cc67735aa5a34caa8d7896905b56944282f0d20cdff96a32144e5f8f7d752c47a93f16e9c1c9d646fa7f20ce8bd6fe409c478fe3afc4f97f36b6472bd01d56e17f4b7477f9671fba3f0cd557a3fb33adf0e0b7ac28d2a4710bd61e2725ab04aaa94c64e87f2f464749ceee1c806a1a23ed036945c69286b200b82766ad51434cd378ea004b4bf4071dd51e27c9a0b70a4556fb87ae4014af846ab874fe8ea5b0faf6dac561d58029f7aeea9f59cee89ff9fa77f4b18d2a2f400147d27cbe10e2236a6f31f43920d08c2f4aa68299621c4a48cc87e27a52d0c95ebe97147c2e6885403454534b8eab7b2553535b3c686b9037e93acd04a3c96e595143061a3262630e49f7a5f2bcac68519586b2734587466c92e66750b21507c5996f95c2d588762903596b9f7119bc224af3b46a095cfd7ee3a127165ee7f57af0e2b5660052d5ebf18fd33c2da7ac24dc08e2b3d16cb03cd96c2e94f0629b5a7a08ad29d22863bb1626b7240ebf7da807bc29da6c06be3dc123482a96e6371ff8ab82e776901ea4e19ed6216ab3280ea1ad12191b4ef565c2aa57cd47478fa4fe95458cdfbd5f2b369b7b3922b31de8bbecb7eaabb7929851b3bbdfcbd3294a7d5287d53b393428eb85ad7a2b0b96174643575ee1b95d4cd7d5cd6e5a334a41ea6cdeaca8d70007032239c1ebca620bfaf9a1f8d5c59716342f335a31c2e7327e17b28d4d807cbcc984100a4d5824c125420f576d6460395fb0bc62850a4738f0e450ea52445da0734270481e9325e9a342a347f6c8416bf0461d705238207b58af26fdc64cd43df7bc5abd609d6aad93148e6a620433fe316577517395ca21bd6cccf3b86095be71227c51cd1795034f2a4d0b322fd89c160c23740045c40029c0ad5a5195379018a0d29eb465d0f182562c1f4d12816b2e210a3145f37bcd7379a9d2224dd59e45fab9bbeb25308b54ef6cc9a3063236a1bb5a29ee0001d8f71163ec585d5b4bb850068308818bd44fb2701b8a46afa0f156d396e225ea2c26f924e74b0bbb1ce4fa83716b03d4025ebc7d8fea432d8d59c886cb8b59479635bdcba5cc0ba311cf418fb0258b172d45cfe31622b6f96ef0257800263627f92a4cb494032af2ae072d36c0466542d84649a72c4c0d36ed6dcb642f6cdfa4cee2eb30b61575f8eb31b63942ce58662d51b20c49b29ec2ef4a12dfbcddbfc2f4b69ae4f7ad8f6ba8ff5e0bdeb700cf380a2c80dfb6017ee5c900da633badb278f38ac6152f4252c605cf32f010f033f6ba415994cc45593055c8d2f91e867c341ca1063e748f976408ae024673919e4b717a7ab13faecd63d3ac5bf7f4c479f12d86ecbbd69ab62634ae9d3247575e582dcc8897e4310944bf8ca96c1f0e3606887a7567bdeeba02ef86668515ed7ceb2dfb5588449ceb8b40486ffebeea78911dbb61d545e03a69aa7d65187473f170e9e4a5a2cdd58effca4afb95dc093633c570b34f3b4ada9e5070167baf8d9d2a8dfb905163a50751e7483658bb96e0b8b14ea475da9fb1120c9bf4e99bc6a018e38b0ad747aa5e19625e44ecea1f4b365e64a84abb4d6f95415f9a134a923aa7b3346e4c4bacaa9eebee7618957f155625eaee7a9aa7b6e81c777005d21841870f41b38c4e7c575a12afc951c7566835e1afad3d037d68d522a4fa2e7b48e21524a7630376ee716f1b119dcf599ebc98a659125817e7ba65b72e06ce30efb8c175192622b8dc62cb392bd299600eb33dd0bb5d6e85ed896af709722375121d30512c2764482eb75ee808b6a90ef58d8ac1889c33362b4996de308caf54f0bb9215607998ef54cad00f62046e796982bceca5192baa60564efc94033319cdcac9663a26855bb6c15bc75027593412255e2df2389864d1f9d98beb67afdfff0503f0bc7b0bc16e3e9e5febf7fe2eeac81602c6f3d7276f5f6ea810539d6d6ce656ac492cfd9ada95c0d0aeab674db10020444588a0a289fa31523fe89a53462002ac352b2b7247eb50a64d8ac8396a38623e63643147a259f219aba660350957141da0f1e81a933b8631c1c12e5b66c557ba6843a71b22ca256c5e4da539a6f7c003adada90b5e63dce24e9958cb17ef5ebf3b930ebed7cf4f3ff8a7e77e336a63caca32524e1bdec3ec45d609389dcd3ccc7ee4c1cc98871d7fcbc13c5a60cf1d2fb244acb840109e3372475321c88eb98a7d1b497c937ab392e5095c9ddeb2bcf2ed23797368da128237c306d786661d0f596eadaa7e58a7cafac71de12a20bc8e57afa3c2af38cb5525eb38576753c77580659cb3bd4d569527d659879117bace3ab79ea62f34af9160b0ac64ad5dbd7afedbd36fc7a6479beeb4342cd0e5dd8e3aba567142e5b9aeb586f30752fd105326af0409477f0c936e1cfaee730713e06355300f41f62fa23043fc402d2a7805e9bb2c522e3079dee55a4d192a3a576bcaa0054353269e37d594c92dd3ba09ee3095f55ea099e6df10faa4cd08a8e0f01f4fc9b0ad006d2da54c17e32fb8ea38c13907fdecaa6b25d59dd34425036edd16f9466d147f620cba8beada7305c9aec8972fc47967035e71681bc61f39470e02edcdb9c235bc61411199918c96154401f79ee7be69d153434b6950a8efb79a4eafbae0b2c702b7631a94bf9afe1c69ed7f03e081a7d33f7b67831af6ab77f63f5a072e77b6570fdeb1b35b77d7ada046fe9d2d87326c2b8a57ec6c4fc1551c5c3b2a53e7ce4663536367eb1047de9ded14374333add8d9a6378cdad9ce3b1bf0c376365e9a1a3b5b45add63b5bbae16669597ddd0e7fab562dd72b61ee705fd5dc30e675773982ebdce56f75982977623a5bebf7c939a4ecd5bb53469221335a9398c6532b2eb69c908fa7cafcb04b16639094276b7463900907bc5180552aefe89c042c9a4446ec75d976074cf07985ca743e2f388da746a07b517dc7759f86e85dbdae496eb0de0d8da52cd89a397d30138fd40af6df067c1e5e937e5e82af36a9c59fb630a8839937970da4accb8acd04ce26a990600583487e5246027e71190c1bc994decaa5687c4ce4b4e12a90182ff31615492b7227607a2049df536971246b561c523c60e0a3a8b5737ca90d9b9da183d7766c2b7d2388290d3da5545216e3c62f5a7696ac9d9275a74f87d7647005c9f1960f1629c610f5ab0056510585b03a246927a88d9013d8be0d8cb94001c26729261b3a53c7b09d53b4e398a8f8fb4d505b5a4ccd362aec439f8675da087d9093ea409f6643225a405a246f49d965403640ba95a56a1d1db30b179b262beed761f2f5cd6199358d59e8bcc61255fdf396071c94230cb1ed0762b6295a5898bd0eea836dab74c23fce2b6d3e8f79fda6bc54d6f869bcda7c4ae6ec53ea0c4b0f2227e5a729cbcf18f55eb36bb372a9931a0beaa97452685fcf682298d329bdd526fd5219df22a586d2aad5f8c69a2b4743b302055a6d6ca094d151723a60dacab67613ddd8b4f285993151f6efc126642a2584329597c79b4a0599039f0447915dd101a3841176a75c8465e0019d476515c2a91467b2aa6b4aae7df97ca8f1689241e4d355e588d6ab82c64c494235ab227421160c5573b083c884a9af3a20811522336e7aa80cea3e496352090e3016bc211df105de0214ac83bdb6bdaa9b51b4494113326eed58f11ee872eb2daf0864b411648025117941734835283853395e99066b9cd55114915f58e71594d63c2e7208b2cbb344c110d351303119ad313e98826d849070b87d3d42ae35202d65d2c2ff0311d28e09f0ff2364631c5592384b21539811281b2250cb0c9d66a868f2a255d6812bd6e3e5bb3716b48265909d422d7aa3106aee0b640245079a09056c16a6bc648496653ac951e9e3cba55a71c2542eab8d3c5e7536c239d92354da8999e9fa7e5dfe0ab3ff6bfd2bd1a11bddbd26c3ef40e247325b54989468d586d4021c4eeb078e29780d9334638bce5b58a851453bad5021f28f323643ef91c6bc614a4b32a3c524cddbc641a058296670b5ef7e9b03cf1a8015db3c5af656db8dcf236df6266b18d66e9d1783743ecfea662e3aba3087e0fe9645db5a4b46ec4f308700fb96519bd766d1c7f16911bbe2d2fca70bf77557c57f1f93e62ab5cd5d61bfc47f1f93606fdd45abcad5f7602ec8d8e3aefe416ef1f6d68fc819bb65450956cb0ebc5fd7e26bd0fbf51fb8df42af0f626186166cd1ace877ec4a18dd078e83fd5fb02b1be4033dfa03d0afbf21faf53740bf07ed50dbeeb84776d758b21a3bd4363176aa7618b8f6fb24616b89d71c72601cf4c8e3c602fab0ab2b60e50a84ebb161df7cf87b76a68c0ef1ac424c7acf2d0c8ad5cb9060246f06f7d6ab5da4cd929bfa47a37637e1f94e456e727ed75cb62303057119519babd3e943f8ca41d0016ece2b960bce2cab95b42b513e61199b50990e1760ea4c49a34525d8d50e90052063ceef42a58a9ea4204d2fe662fc355fc811cc6959a233002d6a128b89e800a9531c93d38ad0bcbc13bc3624ab86a4ab621164bc898fa724e682fa11e94ee58328173d5f64d97a1baf7e9f8cd3a2acd61c242dd37350ddad27b71a77da9b1c4ef53b1d370ad005a789a4156463038ff2865302823b4ef3045c4c05194e7332e2cb56df3481538ef573ce0bf22e78db53b106691eb72f56bf5e790c79bc0d840f941239247a02a2a5f950f7d65e28694d74a43d45dc821beb2a5ab8d004a3b3e846bf4f5eb3aa895433960a7871764987e73ba680a695e29705021bc6292ad264138bc76ac4d19fc037e8cf56b8051a525a944e58cf7ec267f8dacc4a5bde4e9c00985da968633e9ba71946fc353ca9e16550de4e3e34c9e0aaa2d69944f003198247129d31f0c8287585636b3ce5ed24907d843faf0a3e3baf8414a12a84e472ab62cbaabf9c65975b3d6d78232d6e643e0612d32a9e92a0c99882621cb3d235e851d85d33b2da81508ccf52998e417231eba4aa4186646739cbf27250de4e86975b46b8dabb23080979b8bfbfdf2f6f27975b040aae29b4a3b3a6ce601c18333f8287a0ffdf4f2e2fef76fb3854d143786f653dabe8e435e41a24430471b17fa5b20f5a130e70cbc5a8ac8a603f6cea89937987ec905d7398ea9559a9a92167decc8b84932ec4ff93a2e045b0236566585b19c340001b9034c79826cb59f674c74caae10b3f8d3a87970a9d65ee0e2798bff1b9594b79b0be7cf7e6bddc20c321d9d1f14f763a03503bd83820639a667af7e732ad8fa214ecae692268671b107555af5a53d4f44d4633691bb2cd335a090a1c91f7d24470cec4f1562ee459de1932b88f59a2cbdbc9ce8af0de159b892670ab0b747a7efaf6e5e9db1fae4f7e7e7f4686a4fff97310ed3eeddddff7ed9957158384cf8c7c4590c138cb9ea760a42d5a40d1401acb0582b2e29ab36555d0b87ad61456a04213824ad6e26410b61c6f0370da3512f0c8366f585d0626ac68cc8b131a4f035df386d5569a29a093187e656876e3e286d557c796eaad6285861783fff61be8869d784b3d3428db140d108ad5017c25476426b7d27fee5b48b6e954364b248ec80ff59c9121912523f5aac9eb5ccf59632339442310ac341c0aeefbcb17e7dd5143a71e59b50d922a5335ea82aaf9292dc1b8142eea839e45e2123e836f05cb8d0ec7bab89c263717ab51ad231dab7fe2542560481c54244e5a2f651c63cc01f90cb29ea075585ea5160613cfbcea44730be82335cc465cee591191400a06e61a245220d4e42d430e7d9c4e04b72fa40030c6af3849385a15d08ac4b464cde1261a288d79a546ca92bc3dab50dc3b9f629c2f8d8404011485595c39641b995b5012e32154b7855d888d51ad6030ba52748bde146a66e1d19acc452e640e3df0a7cde4c03e140cc31b793a4365793c9bb4d2407dbb8ed5900ee29d717e836e0f14469ce6137b45447d771c198f29003eb6ba27ed656a59c56efee2e0aad975e5399c093fca496ad58e20bbc2bb71b013edf4c813c86ea88765d5eeb54f337ddea8f40859dd8c57f90ee5ac84e34daedc4ecfe0b2a475536d1c1e26056ef5f6aa9972b7aac6c907c3244372a111e11c88f19587dd71e146f345390d9c8afe3cb64e21e7f092f81d95acd20bfff61ccecd502346884be7e9beb9a9ac2d6512a0157b485e8a9382258b98916431cf524cd5e6ee30d55141fd7efc1fb6c1fe49dbe65f0aa9c501f1507c6eeaf851b9f9de81c51a39d4b4750d584b0034494e843cfc1ae29c69c713eb1d48b1adb79779abaefb024553a79647fef515128b7982a2fd101404ae5869d5085816a2608ffb3593ef43b228d90b3a87bc3c385b1aa8fc21d82a9c45ed69d21ac7532cf09926c9809455f2acaa683c0d493183c7974c3cde9381598c67c9e98959105ec8a2a2604ffcc7e0b5b13fa2f18d46e31ee49e25fadf68568ad9574d8aeed503a68265ada1065fd12e8ee961ed7ad7f0814d1b33fc80c6d371d07ae711a163d432344505930b2deef40c8a25a6107a0043097678be43767d3df1f7fe6ba62e619bb7f7fbb20fbd383fff5f997b48f5482b2d1f9a3d67cc8b98bd4c0b16a3a0e95680ef781168d42a6f273f3411c20ddda7f1c1490304fe7b9ab0988ad08f559a957db3805d35e1b3b539949c3236802a9db5aa61a3f0c52e3c61d5cb74c6f2122324b5eb9805dc9e16749243d04f6f1fd5d7a6d2a59597485d014c192d2ae5986364247a91d1b2748226a391b94483445ab5681721743cd0997b4e2b32e3795af14255478508c6cc4bd83c8d311ef44cb402372393acf6662bc2ea7ba6bb13bc0a7aeaeed9ee596457573d237b9eee86a0eee66253c15d2dd8faf02ce39033680eb14b0395972d2d941d5849ca29bfcb7b03d914695a5151ec31c750bfdf4aa1b7c8186eeab424319dd3510677f6495ace330aa93b9bb8ecad08831a2acdb2e63e624ae1622ce645c1ca39cf4137a002404326e6318df1a228a6b998ab8c56708754a6596d03d6f15321c9f19cc5e9388dc1bfbf94ee2334814c44689ad004489ca70ca354c79001a52419cf274ea7954183e8b06179a530d8e86c0fc25458bb5f74882d21bbac39197a16062d8738a3b60afbf9d8eed14fa05c6d909f156a4482c6cad06fe485bef987d47a332a58e132242316d345c9dc099480eed22c13b2109bcd2b1243fcc766276174c9f4138bc8b3ace4cd2810434a1b262a8012366770cd4794251916680c13060dd734e249ed1db23a69947bb5dc9d1432f729e4592865be5117d686c6557acbcc2c540ef8d71eabae118370d311f93065c697b4246c39c7e300d07736cf6a342491c86b83b631d9a93d62f27e34bd651139b3160146039686393444b3782176800d1e2662a794b6281179d5e09bcea9d674a16063348734900ec71e59075dd0335a91662e83f595fc4b079f4b623a7a4aba218904f9582ee05abf2175e84e2b9decca8cdfb112ae6b2a1551de6e234b47052dea889c73fbe23e973a47ab41885a5382ffa8a68078a121453fd052d2acb4b6ace10e4356a0d25bc86829ba29e74d2e30c7b8d8c52257b7af06f16c223602b68dd28938c8c5304a56c9141500d76e0bee6b335ee2a4a609a35913a81db708eee7f99c095e068d03d2198bc8f305e866635ab0f1221ba04d2f2d26b21fcefca615ecb571c1d8272bfe8e3941f382152af6f3be7e7f6fb06886f885b880b7caa15e067d916e5ffbc770b0a7a5603ec053704a0bdcf160cb5cd13c017a574a9fe03144756b42556b68a7e8d04649c5e2699ec63423091b55705b3520e37409b1b9d27cd22f1812bf349f3c32f209a6d58e38112b5ed18ccc58a9cc320577f3eaecd99b93ebd3b71f4ece7e7cf69a0cc9d1be71576e9cb5fae7972f76dc2af40705ac694a45328ba2ba723752cfe822ea9d2e64c69ad2a5da99e90cea6816345f3f1a0e8dc40c4ffd859c047fa91b905dbca4793a837df041309561634180a870aa233e4134662bd11ffa086234e23375ea0e9b3675bbe57905ac490b40291a90fd05bed5fe9e96ef29e416303fa88f66762dc3ce039d487f1e5899b1f0e52ff64b88f7666410b48db6e68b5196c69af3d706179fef7bede57c59d0898130fae251d97c186699461ecf86aefaa3c39a952403da502df4a24ec78aaf6289c32d089206d93d65145a4d001b18067c710ac29956567c1e19d93f9c04a360eb830300160b3030ad98e2b7dd7ebfe5151b886e1afc72c5e7739930422c2e84f547497432c12cc1d2b55b08edf87027582b9a24786c54536634e108b9307831669801f01577683d1b6782d3974284d16f6d025a2c72e3aad89974490d1b4402cdab67c338f64732e8deb9dca94e98384da63dd193c40cbfe46ea04473fb399f5055f08123fa7a20fab7b71334cff1fac33aa77a325af372ec966fc76cb4f718c4ce3326da9a30edcfd744d8b346d9397c4d18228c1e3b34acd49d3d2ea84b57fb06f171e6c5269991c067a303ad212e669bb40104aebb9182c13659d10e2e4f574bf8f50794758f1fb2489f389fbd5b742e9332cd82f51113d5d54301e734df080ccc45171c9b982ab750955e5d2f3eba09cd6855a44bdf169fb04adbc6afe99486b9518f10230dc69a566419d65a24f0196f37dd9af15bf6811b1d6a85f4d7fba29d0ba0496629731dfe4cf68865908d5b22246ec15fc81ea9db056d4cf161d0aa9980dcf46a61347f847a16ff8a28097bcd8258768d4d2fc4af0d7a2265327f0f50825ad33e42d8103fc58a4a41a64109d05bd12ce331fa3589f35ac56f43f59e0f398468c2bb29962044af5dca2fb8ec53f2f7455a3df2f7979b7bd25037c73ea772932b8a3aca3f88baf0f1f8ab9b1f8fbfaa7dfc6132f8cd92b502c621f3941a4c2ad8eef4319c3764c7c2a89f2abe865a2d2d54a5e569c392070624d16d637456084383ff1f0ec94e0966853b3e5c34caea3be55623df0fc97e33018d7b63577b23ce3346f3750dba736a50cc05c3bb75e5eb8a4c8f9cfa66e6f52cb598a3a6652b40affefde54b2bb8de881b0ee75a60933fbe7cb12f0d948c6bee9f39640c0233a501f9b3252bc0a7179c0974dd8ff6f7f70ff5d7fb06e30c2150fffcf2c5d43c7a9ad5631ab423493b89cc81d3d4a2de9496efee7275311eec18aa901ddbf85d5731b5250e5f63717bba42a33d18fa5e7ef96220566a5f7768dbf4c8faf0e58b7b35d25393621bb3fb11c53a869a31eab68c60af0edfab833740142bf455015f0855d79c65df8c75b1a7ba80792eb63a6604150ada1813e9145dc1aad17339b457059d3173fc868c2dcfb7b262f3a047b6b7c92347ce3e6e76ab7ba43bfbf89102bb76415688053689b3f95a0f81f123a4a8ea0abf960ec482643722305dfc0dfcc7266949d57b43c7b1d5d7fa134ff232b093652c79c30b064b547a387b637eedb26df7914b4b64832a0e0698e25ae8e8ba7a2ec95f3f4316f415f056a18390d600690267e995b4b3f9a23b8a235d6a8d70d471c028f9da50ccf4c9072ed83e32e13c513106b4b2b6d4f934ad9450fdbe52819092ddb242d4d014516c3b08b526789149c117799325d538727d04569cbca8a6d911dbd653c44d98e7f3a76a5713ef77c1fcda42578b4eb862ff9a55b685ef06ae4ec27dc6e2e6f08d146b2fde5a49f3f4812733cf9bb7d44664628b36e9942c816e295a1e925d623c1ed8fe9d50a5b6abd47695daa9d216a586766f23ed5d4bf648107bc42cb247e265af13e22f2d888d1b2e80f408640264ed393d3691053d529f3db11dfa5c73ebf970a149a0f4317583672ac781f74df2a60625ac44b132cea5676c325795cc4f65425bcd27a87098ed5e1967b20e016a64a65a354c88c59abad17f55b85cef305f1b1f0219a8d73f4c1d9637b4a0ad1fa6bf57ee3035f8550051752866448a90cedc49bb6e53a6d981f88dbd8dc93a18d6d0f27d9ae70e829974b9b9679ad11aec73478cccd88c173561e3711aa7102fd1b85f423fd729cd938c154ad110f9b8d3083c060a3a79fbb2e0738959e625427e2e0e942e419b58dd972b9d9680cff0d642268bdaced3dc40665b5f46bc5722ad4c26d6096b9dffe600c4e84cc93a949720ce40c45af02cc1d87d9b6e4df3f4f09775c299630be0828fbd80f804ae56ca5ba76eead4ed3a6dcdf68a09b427d1af0fb527f1bce2f36e24f02ea9c68c75ebeab285f797ae3ce9dfef9a6275eccf75682edde93a5bd0970d1e4222be751dcbdaf0ee84c6539810f36068cbb19b49580a20d02e93046fc88cc26c750d477e7647d4c54042aa6c08070a47acf4e0f39c76e260876f512b03a118b9fc867fb417d80e4d125be1d23e580d74f1d369a3004489f49ce80e12775ea3dc3bc2c38a9ee321e46a8bbc886a29e7dc13dae93d2280a4462875053d0c26bd6210ce4d34a8a1deb2656564d456a1a2f142714f1954f912743e6016b0137fd02cfc3158b0626b48748670a02bd019e2e56b74164fc75f83ca1b6d78e2e1b1fe3884dcb00b6d86eaebbae0c3063445dfc14080e02cabbcb8add071d22846bd2233f668679325e5390607910280bcdf7616340de5626a88aeb7a6ba1757fe9a1ee1118b68bc70a2f11ab3e289a5df4947cd796e4daf27dd46270677cab2eac1c741f927f4275031630ec1c43c433ac8a65f3bb3e2687a619a90c863dbd59b5866263dafea587cd1c79939015609e985f4809313104add253927285cc0ece09c273ba1837eabc68eb7bc7c51756570453d77477257956b7053bd01d632a0d90643842c075d92bdc592d66eb1465c3710aead0106cf8326ab29199237b49a46737e171c905db21f7d1382d7f553b2b71f1d9201d98f0e7d5a0365cda0d9179cc6ce84b88e42d7c7ef5af76963b0fb07703be16a46dbbd18c7326ba5cae65ab25900cb8182e7c14e019b0df0c9da7d6e0f566c1feb887264d5a4a013475675f788f678f06392bde950d20ad60a5a7ad5cce4ce819286422de374d9eab44515eff2c1f074174c4ad85ba158b7a70891c89924d892dd94e8c1b378df3da1e7d0be35a5805fef6050abb23e1b3b020b932764dfb32b564f495b9271d92c2f2e5ab4f2d82195f957524acf957e33e415469ac71b756eb35d646f5141f457efd1166a8a3abd2ee5bd613ee55d0090fc342eb4f8803f96ad5b27d2ea7eb4189bdf25ef38ed4ac58234f768af97690b087d37637b8913dee3b0d66fdeab005fbe285e3238928c9aa5f1c51740c92ed38aa28458b32e8452d32bd35bdc8edcc3f301e179281fc6e381f8cfa537ac8d6d43225581b24d956976855facaad0866bdb9a7801af717c7561a30327f9cf2c8d595e3272c6685c91db83efa283a3e800ccf40bf12a9a173c594037a2599a47bf95e0dd20bebfe0f31a832506718fbca2311b717e1392d33c8ed0afa52a091d8fd32c85b8aeba22a855d1dc0832c5083144f62341eb7d1086df9c7e50afc9982f044008610d305e9fbe38797b7e42c669c654f21948ce908085052f6ae514a25aaa0ac622f43ac82ff39d45095126d3b8da39065173a8b0f5720b75b77b18e5f972ab17e64333bae570389458765ecf463cdbdec6bf62af86f361feb4790c2eb7701a55cea3addee0bbfd83fda3f0effe72622bd04c15fb2e2cfcc5c6059d98f0fe1456fe8238c4eb194f982afbe770d1d176c1c57416b2e0c137e16d6741c8b4a620fe4778e72f28734f2880fbe1b26338bcb8a345725db0b12a7b18d61d235a94738113aae051f8c95f70c6665c15fa367ce62f94d14fb52874998b62df85cf375b69bc8ee7c5b1dea32f02dafb2c200b641ac9187ae5a0df87767e2b218a5ec2e3b2cf8a82177b0913a85f44d36a963d4df35b5aa434af86975bbb348c8707c7f1135a4c80c6695938dedded8d7687975bdbb498941757a230cb05988f67a72ff86cce73965781ae77115ff58e91985d6ebd4973b4d3c79d0e9d20ff269adbbddc3a26b7699956e4726b77b47bb9a52f9ec78b0c3d5ae884115e80fb1926becbf7660a60c26e09cb6fd382e7a0301095a122b4818e9f344940434f333265d91c92dad322473fdbad7bf4047e39fc9c966ff822af583268d4de9f71088f0eee4396ff7dc116ec152f62867a0cb39cfe7e869e9fe75557817310c09d8ff7e1c9f0f37db3a2af021a8ec2b8f71942a1ce0b3e2f87f4181e245e0f47f858b071393cc1df289a17c3f8cb9797f7af44b58a0b1c8ad212665eaf9368cbfc5eca3e0d759f6838ea7d4ec79a205d6e3dd2f848b7b74d44b53e8853edd190f650e18371075e047ffeb6d7b3ba18399301d99a4231e6cb2dd599cbad9eddcb7133f54647e51c39808d6552b02fb70c0000dc38e67e10abf043d3d8d068b85996bffcfe6511c8763afc8bd152ceeec80fc7a70202861ee6c5f02fc759701a1a7de81d9f4669f97e513067251fedc311f25fc3cfd2ca772096e03efceb50c6f56be6cfb69a0b5f0f3fdfb07af0683f2cd858fcb9be2e59a67ec1c13578b46fcdd21b357e885a1026c3cff7e16408e1966ee0cf713a0e1005463d4190e07cbce56942f61f0d8723312ddbdbc10dfeea85c6971b566f6f0793e1e5962004e2b1178e7a7f8d629a65c12864bdeded47af5dc33ff136482ed8d57074c1ae7a3013e3a14bbcf60e45b70e86c3e1b8976024bc82e5c3f858aada828327e3867e4e87cf8a82d6c1b817ce86fbc7b327e3e3d9ee6e6f7a31bb6a205fcc760faf8e0d60d3fb741cd0ed6d1a49c34fd1c7b29983f1d0fe128e7b38f8e1702806a0c631867120d5f9fcefff8e1b6b300fc58f010dc5824d60bd6e4240bf41125ef3bb9c1583ff8a2402dc9bd1acdee24eee0218893f00750450a95817099922822bf834c21ff7f71af83bb1fb1491577462d82607439818d5f870389c37305819d3391380f0f0fa7cb935bcdc1a5c6e0df72fb742f8251e0e2fb7eef579f2ef975bbb01200aeda93c8841ff6238b8ea4f429332486e7a7441afee7bb0f5de0ffb9797fdddfe24fcdbf0e2aad9d96788d92103aaf7378939d8a964f8b7680ea25a1215ac5c64d5901e270245df176c9c2e87a3e324129086b14009490818fc5ee4d5705f769c24f7721d100aae27c2188ca0e3833894f5072c84da837d6b3dcfc5b0a8ea066c396af444be80cec8dfaa3ffa11bb74b0ffbd1ae5f6f6df6444b69ed9d487664a7016d4b21ec3b9a0251b58f2e4cb97cb2d693c8d2f7a149b04c3a8e1a303451a86c321ed4d04dd82ed57dea5553c0d92dee798968c5c6ea1c5f7e5d6403e4b3fe3ad01d419158cde1ccb4f0ae5061248836312da1c81fc1deade8b2d3ae9c9b588030667027476f4f4722bbadcdafd18d070bf3718f5c283e3c970ff7834b40b0c048732b8dc1263012a11a525520bdaeb29027233dc3fbe794215e774b3bbdbfb9c0ce9c5cd95a44fa3dd8f4112def48e27bbc30f41128e6192ef153552932466d473f83e1dc3bc0e82f1f0f9f636bd787ef5e50bbdb8dcfacfff548ce1e5d65538eee025c74fc77040f4c28eef300c3a1c23e1a5bdf0667899ef1f3f0a92218d72b6ac825e2f4a78ce8e7bc930c16891a11ed3ee6e2fb446a569ac452012c91fc448ee69a81885a383f072eb420624c103ec0a6ac44f15000c6d70c3ea927cbedcdab5a2d7f6a2df789a07975b21b9dceaed0aee6e6b10c32af71455259386f8fca8ce3343261f0ee9d3fd81407e510d3e37153e9ae4742dcd93cc90e8dc5345e7e0641b8ca28acbf8dd47df19f07f42f8b883e512a81d1c8e42b97d7777ad8d4aa9752c0f15790893a1411b8ee9703dd86317ab9ffe1cd09085b18facd2fbde400e717b3b1087c1f6764087e2c849768347d0f6972fa3ed6d38ce054ac34c88691d48f20db3a149f8fbf072ebdfb7fbb874f027eef542a68893314f3f2bda1426386a641c8eb13b317012d844bc02fcf16878168cc209803916c840c5f41f9f07233c2d7e71b8aae6bcf8bf036c970e7f51e7ae45e06cfef7e8f0a0c13f2a458e111d7e46660eebbf4ccb39ade2292b06bf84e687e7e2ed0b9e8fd3c9e0b31241259b67967b877c40785a9ef31953c13b9ec5559a4f067a20429641edc220bb3f960ab04885f11d7e9ed1f9c01403045ee99151453ee931e2dac5d53162083081a2b01a26bb0fa5fe7023706229004603482cc84f7a3de471e8c14351ae25b2119c1fa075f761c501a1addac86fc8018cb05d3f96ab218dee439e673694741c3c12a8efacf8c13747e68a0b2e5a4fb5e6dd5fe9e97f25752ac342bf7a2f3522c345f36a51b0a6f65ff4fb7350b4bce1091b56cd4b8928c35abfbabe3e3f797176f201eddadf3e7b7d7efdf2ddf5db771fae3f9e9f5cbf3bbbfee5ddc7eb9f4e5fbfbe7e7e72fdeaf4ece4e570448d9ec719cf994c2830ec5c54717269ded6dd0987dffd29a4bd9ec49e2cf87c1f4a3eb3a7c8553819221b7a33543ca729567c6e891313fc15de0c350fdc3b6e891689295a0880c8fc0ace14a4238b6f978244fbcbb1381ea760e5de082753af7022de06ec627a35d4b331ba985e6d6febae8d9f8e2fa65703f116e9cd7485ec32ed31bfec32ed7d1e4b9965da3b565c08ca2e53905dc61ed9c50036be5f2d1e5ce642404840409848e18029b1e0e6be2122a81f7f21194e5b97d0ccc1f676301aa22d1e1d366dde85d73aa490bc1f7a9e56e560145ecb4585d8a8036a3f1f8a17d5b460347981fc72f85eaa088144862f785e2e66f2e9fe9846eab3d1f66d78add86e7aaf776da4aa0ea93b46b509de38eff136ba1eb6e9cc1b30494412477bc72398da216d488b03e98c8d872da2669f464d15a9c3b4ead0b6d4b70ca5ab3c35eaa6e58f344b1335a277c67ecfe8a77a25c067e1b518af5882b2a2d5a21cec1d84d752ba71fa386333eee0840bee93127363c851c1060dd23c059e7764c0833092e8f8ea052b8e68b3107cb3ab7b11d5a98d65da955fb2d1620218682e9355e4643c66f16af058a40dfd74369751b8fe0297272d6a6b83718bcb52e6a9b328197a786fd02bb360bb6f6fba1652551705dad5ce204876b16624b2941e8005c087dd4dc5b1905fcd0aae4ad3ad829a47b3d22d2bca94e7c3cb2d7519b575ac038eb6ef9d0ef70f8ef6645cc2d0b985fad7bd7152f199817514a7d5877aceca731617acb22f4eb374d4f795da71ee45d96c5ed5af0c5bf1fbae8f3fa5d5f48c95ac92a5fc1f31f0c94fa8a47f41e3298450378bfaef702d7375cb98609ace02d466414c35e937af582919659663ec762cf26a9165f8be8431ebeb5bbc76c7c91a0ebdb36824cde8f7c92904a92cab34cb4849c7d21217d25ac9789900236a6ecb75f60f9dcb04d8a5a2c0ecbd929952e57704854bf309d1bd2090338842d850c490aceec89ac3c8af62b47b82f096bf92398d6fe884456487ec6af81f4bd6c08ec073583f063d190b308330a476c53346138c43442b22f33a8d47d18cf51725db03407b4deb3b584f250e614511e5186d7ee754dd51911f539ec12aedc862327f55511cab7b7102cb0d771eda1e5abc39b65062c2aa738115eeb5bc2e89a0c4facde06234af1ec9177f656c8e9b2d4bcb4aecc7b2ce63d44b3457d6441213f1fdd7a88f21e06a81e362e220d8022bcae8b7f25758f9f68e04633db41b01d905ba266d01469c67d60b501e9a2f506d66bd426d85f5aa94599bcc5770cba85f29cb15bb7de8d1bbf1404da37c2d6f9aada2f29d1892f53ecdcb8ae6316b43c979c23c1d6f17e4b9a736bcc4d6ec0fe594b65fb2251553d2bcc4d736920f3a88586818d59ad4ca29afb049fcb597383217dbfe6467726a7dbbff3fee5cda91b2ab9458df3f3b3fbffef097d3f3ff8fbd3fe16edb761a46f1af62f9e4e8251fc3aa64a759c8a03a8e1d376993d8cdd234b5fcf6800448aa922845a2e345d277ff1fcc60a52827edef79fef7bef7de9ec602b10e06836d304be3bdf57f356f104d55c7cdbebe3c4618d8d0d02b47c0e65afe458dcec64b9b66ee29569bcc4fe9ceffd28c4da8f3f27f79c3f86d71987d7c72fc7f85444cf2fd422f294dbe4be88537e7ab0bbd88e66c9b422f5973c646a1977c4bdb1b422fc5d68c35a1975173c60da19771733e26772c17c85e8f4cb656a96e9db5fce5164c35c9d3ccb6206b439ee60b4dfa83f29eac7fc93d57e53fe8927973c5befc4dd59c49cbdfa0f4cdd7e64cc9789a8e747b3d72bda5d3572567923e0c29f51e939be6bcca40b41df627e4760b7ad2e9cce0e6a9fb107fa7588fdf788240e6c315b50f63b17a2abb522f64a9793b53dc2ec254ca18dfce26f823f027c79f2c52cf6b867dab78644e6dee93afa97484054bfca9f0678e3fc5666d2ae26abd861cdc89b06f0147cecd4ee285523a59eb1bdd912474e08c8e2dafdb5034244cdc840a3d3f21db67544f31aca3c2a468be496a79b99619536e327885897acdee6e1d7e2d5cab1df62fac4b943b5778c311ce9b38bfd926e777e630792c221a2ec41285ab9542ded8e50dd57075e42779d86aa857d5385a6f1633a8dc5eac708b6db29dff9de841ea567a7a1fdf4c83517a25f4386ecf2fdcfcaf9b59683a6fe5b268868b1a6ba59e7beed6ac08647b6eeee5d6b4b33d7feee677096b6b89cc2ba1a96e7bfe99df5b97ef280f648d63abc5019cb15dad9a0f076cb56212fff833c19f1c7f32fc99e1cf17f76d7d0bd5041ed954ab95f73daf7d17b5ef51edbbac7d5fd7be6f6adfb7b5efaf0e974a469e65f4ee9f9c1df974f2ffd4c3e30f121449a9f3727837df39ec743bddd95cec04c7578b6a3ad9797e351cf3706725a11894b2ccc671933147021b108692d7f78865cf9dc4455a08797d903bba7d22befaffa472ffbd54ee300b5acc7f3cbc0a0e0e1e87a17b0c4a94e403e144908ce4a420233cf38cf145cc95719504a82f640a1fe4308cabf9ed32e9b0d96c7c1ba4641caec1457a3051429ed3125b9f846b78a2e38cb67a44a07013c9e0ab505f4346972abff7462ccb7463c1285b3b22047f37020ff5c7aafe38610ab22123066a470e62d458c7dfba144abe9a72f1300b381e1c39d378122cf6da4439241ff1bda74fc230ced86a15c81e77658fc70a2163d5f989fa2d15e8ae0e8927a0c2d54953aec157e5a89c5e97fba02d32d88d997ec0fdc0e6b9a868c982348c472ce02451d2a284859bd924dce8de1f81f8c2e8d2935c9db300fa3d63464e8bc9c5e68b79a0fbc22ed82549e98c196ba20c30d60af67bcfd2b0468b4f1fc13bb64c5f3039af401220e9282fc94a5bae5606dfbe213f4de29426e8df0b993a1a2e581c8d300f765a498ea517fc525e264941b96cba629b8fcef5369f92220ce38a5d1497348b51402debcc0ab610fc9dc8878b0a8dfb81a37f59e908572d588b47e1a849e6f68a05a30b7129e92d8c056d759168b2cebc56613fb862c166341424b2601809251bd81275c89f100ef85aaf3d11c82be6881c7c95a3562bd8eb76958cc1059378bec65f07d717e96507fd0089321d8a05d0ce82d18b4b5249ca215fe1ef35f384f26f987dce6df5480a23964a34b110e4096a984a4343f017e925f4f14b43a6d5ea8b4c6f51caa14bf0b5d1a5039286610c6994c709c83326edb6a46b80fe96d1d68654a6a79086f36d6bb2b126fbbdf9fca7f090dca9b977a47e9f6f2e04c74cdd5b199dc8a0bac336e912dc6d2cfe4fba4a6e24a1acb3a894699018e509c62c482408819344d48d360943e7ba7802301cb1fe73f9bf962d8b9e337ac12ea323b9489bbc2fd4aa71c4b4b4d71123097dcee2e73288fd834ec9d14d94ec643766cf12bd45b3bdbdf09805892453078a53e6bd9c4ae86de2cfceaaee66513136e34b091faa14307acac82fb01dfd0acbb9c9f45a75421d6d8fd86aa582cf59286b20b29bee0c7be3ceb05fad9056006259bfc26e26b74d15ff4a675f67c3928dc7b74b8080c886718f78cbe80ffffb223adafff32fb67f37185c75bbc7dd7df83d79843f4ff0f3143f4ff1f3e0f454fe1c3ec6cc878f4ff0e7547ef64e21f5a0db3ddec7df13f8c1cc07bd27907adcc5cfd317f2f3b0dbedc9cf93c750f6f429a69e9e1cc3e7c9297e9e9e9e5cfe9f05ee60b0dfe9ee3f05689e3f8666bb0a8a47d8ece12936fbb07bf95f0f7e2067ec9b0a22e7b008fe56df4adfe9497cc6f038f51b93cbadd294eac64ecab99b02abfc5bd6a9c4a20a4cf4ce6fb03ab7baf1b90e189d2b2bf56e26844bc969bbdd95377a98e5b615c58252eb486204cbed2aa345cbf1a96bb01b19d8558211648fe451c9eb806e5b47a61de5dff1399659809c6d357d3dbd16f363304a8247cfa04b7eb4876fce2ab60feb1d6853c9b3befaac31bf5a3d6ff3fbb089094a69b275cd4e562b0779de206de997429fc22a22ef50039320861e1ae064e318f7a366ce0d176fd9db200931fa513d7ab5eafd94ac37c7f8ab7b925587ef1a6ae901f6f5107f1e42e398d1787f6713417943e462c6524105a64cae16d5c785d0944ed3d82874694fdb5aaf0bc4b4542b0b560eabe19df8f8ee35cd60613bc6b931d8d5c2743b9c95b9984faf16e3dbf7a27a559662fef2c39bd7da1e3cfaf7561ff8082ccf7b3ad7e26a369b8bc542399f7fc18760ab473d2e9ae497b71c0f5326a1ba1d8bc16e67311b0fab60b0bb33d80db5fa7ee05e458ee51c2bc535a0bb4b5a3dc250f2b5d50bd7617c7131d845a41f176cbe1015e8e060cc7eaaa32ec9c560177ca0494c4116f85229f2027b3a9d437c86ea081778fb7df1e56af815e2e5d7bec0cfcbcb4650d5567fd1bd8c8f2f120d75427a00f545efd2037cb09bfa388366c0b392f95accc4780c48874fd05d18ec36b7ee21ea009af467b5dbfaa09478bbaaa6efc457315f606be2a612f3928ddf69f7165a1e412126bd5a18c8e0b176fe551c8d6705fb07207940ecb2f1787a7d7a351ebf4fe742943bf0cab323e13a95ad41e87ccc6ec1eec87c3a5e182f051cfc30f22140c475e07c98565773f1aa540179919fbc9dfe8ed22562a718722eca9df1743adb29a76fd02b6b69d3a73351eeccc6ec76f1aa1c0f4bb133178c9f95e058518966cc11617c07de3af8ce42b0c9582c163bc34a4cdee3fbc73fa4eac3ef19ac14a71e207f7235ae8633351293ab4a452fc418fc257cd7701c9256b7369506bb29bab9464a9c5e97e329fbbeda1e6e4e4c49dfe30554359f5e636031bcd3842d37abefa8f85153c5f3e9f57ba840d654b179f55d55fdf80d34cbe9fb91d11f2e0683fde832b860fb7797e10fb93d97fece5c29fb8bde65a79a7e9ccd745d6bb9acca95a7acf695bd29361ee6c051da4fd8420045b1394b86e93e9824d791fb8b6298553b299be982e97838db9fb1aac0d05cd2693a1d4fe7fbe0d363a6648a9ae2f6b3e118bc1a619a7ab2555fd6b51b9f4e8625732143e728fbd618fa4e361c8ff7a733960eab5bfc0040b2f174caf7a142153679a665b59fb1c970acc2e038d784f619fffb6a51a9886a2eaab4d01fb76395510b4ec1c735a2231fdfce8a7d10aec2e0743e146585fd2da6f3e1ddb4acd8b821f1ab9857e0a51272ed33fe75ff4685a7f3613e2cf76f768613960b073563515562be2f3760f4a49a17d5b0cc558f276c3e12f37d51721d9c0c4d10a87167fa55cc615c8d2b51135315c37454caf562c68665b53f9d7331df99b172ba10fbbd9dd914c612d94b8edb4118e2b24291a07ddf419f820b827a2016d57c3812f23e7a9517160c3fdac2b2a8e6d391d8e76c5180a0941b81f6a9748cec44ca66eee7dfd361a9bf27c34a76743234051c88e427da6babc44db5cfcab498ce31cc453ac503027edb1e024fde47a68db23db82a87e9948bfd64c887e6630ea60fafca61b5d89f49ac4e76beee33b96325a21aa63b5ff70b56821fc3affb432ea6caf0d7ced7fd09ab0a3161483a5f81a9bf2f40bc78475214d0d12d060d19b95fb73bd7d3393724743d1f02054da65cecdc4cc6e522ba01739d376ac27fcf9ea139095a3bec232383f27716361d36fc6d16da8a585a5dc94d4e7dcdd3f974acbf9ce0a2985eab6035ac4cb43c56fe4b28b7c18887aae8871faeafaf3bd787f0bcd07bfaf4e90fd0e260d72ef837937124d72958f1e5c79895b9f98093f2b62de03f84e78f37af254c4f7e28f591dc85ab62c9ab928b1b3c51cea78bc5198cff77ed47bd6f6efbc71dc0c4cbb9c8542935962f4156056bd0c35b60dcb791da05d017f31473eb624cdd35f10c3c39529fff5947ba7a63fdc42863ff429f2bfeb4c1801cec362b210e76c3d52af8c43acdc935cdc8f09b353b5a8c8d553be9b4a6e5e8bdf9fce1dc8091457e5c6f3809fb922023a37f8e2ad32d4a45bf4b291570ab8b78bfd58b5ac18161d685f02c0cd7f0e4a27b292fe667e64ba695eaab07696fcd1754d48db3d52af8807c3a4178d86e07a8851f128e3c37d976ff1d0b1299a622d23e5306b48ef47d3548c2887516a2726288d2660d2351bfbef6d985f0eeae97d4d47d68ba2b6104d5db340a122afcdb31e1f518989ce47e1803a1ea26293dc49777792717ed76abab74b6415d5e024e78dfefd2dbf7f0a8933674350dc330545ab29f19fde17f079dff0a2f06f0df0f973f9017df2f1df827a32fbe4b3cf0c1968c75f9409634e7db14104cb6e46c94104cb764de1411e4db73d66404c5969c1b4282d9f68ccda27ff9362434c9fe15dbf0b021fc37fc464e23fb0716b30ebae4ef2d057cf1bfd1965cbefcdf784bae9a00e0e43b455337ad749589e29b7ec3c043e82830c78c4e92769b5d4c9226330f869dd8280ed367b87cda77580dc17e0fb4f195d25eb83441da352f2ca0d917273409c2987594521f4de2a45315a2b4db57122ebb6e6df01c9368a55962ab969b9aa9265c93fb6ab0a50efc52a1c70d9df928f551577b5aa29b1866606872cc60d15cad18e89be04a8da51b848facc6ba1675543c5296447a344ecd5a803cd007cc249dabe50413525be6dc4c744c4a6c9295c5d2898593686611260d37935ec3ac596f13170db7594f11b62a25b4673462756b7c33cbb95987304b9e44f6d0084eb9803c5cc4270af160c2a1796cc098430b0db158a9bd4089a784729b29dd94c1aee23fffad21046241a636a68cfd14044ea58d92085e29bd79d237948826549cd2e1dab53a60e8f34b62cfccd0393e5d326bada662b961b02bbebae299c3cf63fce975f1f729e0114da6a01d1c4752560b56fcc545729583250822ccf77b6040928cba38c0d74b0ea7945912708c0f634eb338c356445f067602068240a22329548e8739fe7f462b29219ac5d9036bf5e22da81ea96149dbed002bc1e762d03b9307024c97700c76075a2548a604604be8234a86c8bab375b247537857412cafaf8be15804cc31cce08a7a00d2fd5720665e81ecd34eddbe50dda8d0167b44ce33cb3681658912e7ad7791b83727b02887f940e8ba9c72c069288f94e0c3066667ed02d06e078a69994c6fd02491c4d29cf1e1143fbd17dcca69129aef3b2ccfc8b0be49aa1f0173513927e813b148e7c359359da39d186d97cebe15922424caa202bb4850b861e30290409f1c84d95d2ef56d08dae52895a06c4f5c884a1ffb2127c92844c6aa1fd8948140de1496295c2aaee62c198ba8d525b9a8364d3cee28d9b0aa182ec2355908dfd488ee6b9cd96c8485eb75785fcba2948b25b49b76ec87b128b2cc85b26ab0090f07206aa90e246bb2a8a6b30f73968e8665ee56c03a7fc1f8429a98d34189335d8c452576e470ad5df9f99b046d8a798556aba05e0dd094237c70ab37df16b32f89e6f4e01605ea48ece323ae634947f73ec04b2df62c6660ac03a9967514d5f607bbd55c926c34d80533df83dd88a1f5a93066949b6da325ef1d41d2d1b80b5828efcd91fbd47897289b140a0ed586aea30c966b397afe2b9d324640dc873c1df7d5fd50b529d348693f8d58e7afeb399bcdc41c54ce3bcadba6aa78edcddc230f363cd798d314348ab72a3f8e7075c3359de99b90cdaa1a8c533a4fb43d15c4615ffd46291cf65c68e9d20737e24445200ad062dd7c3a1e0b1ed5d72823e8e72c54781bad811b79e038d4f95ce12371c649e56db78117e03ee624c0ec71258e5471558d22bd7912a896e42a8610d947f03484a392de18a816cc823bad5c9ad4020d15c8632304643915c4199aa2509c4956b170ba75b3b936d21657c96458598b7aa05aaa41d8bc839b855c2f28eb649309a3b3f44f0007eac21e460d595d921aec86edb65b0490e6e608c358d3a71a012d3f5fa738e8b31f455bad7a2e6fe05e248e0cd23dbd92a7c76ff5438be1d9816e39b86e51cae5a82a5cb700f58ef92068c9680668ba51ab993211b8b7658a030471ba5a252ec5180248e46c7381a5c93aa5780f89d589170946c6404b4e098bc9fb1798869a520fd7272eae2de1b7e090c13a60e8475bbdefa0af0c25f5074a66480469bfd6956fe225f20bf83364b32ad70edf69fd60cd9831616638accc33e7652dd5257b9485ae552f2b78a7560b46cb60a9453ad4babe96cb87a4457a2a27824e0d43662d2925ae8d372ba597588ea53cf14d67327a812283cb04644c95ecafa0dd583c4bb5f0a0d8db0b930b34789a5e884b108f02a953da8d536b6332dddb0b056d98080fe07c965eeac50ec2fa61bb05acbac08ba32224a2dde63a5e0dc37b9ddceaa2a1caa532dd384f82348cd19e1340863d606e0f40e0f3422820e4221a2ee17b616b8db145d1d8a25edcf4145cad30a7125758ad8284ca98d0e490a3ec56efb30d5e25c6beb559af9ac576ea22c98e193f7d4af0f6fea6c381a1a36f4e88b543e1bfd4ce28d08c353198864b3cb960dd71523b24b8bb99d3cf7a7f0e5084ddb7fa98a25c6e2be8fd4435296e88951f86f2ea965e742fd7094dd76a2300e60f2e53294dd6db8e12881fa01d6f607ef53aedefd29bdb8f63ed5151634ad29659679d8d360d49d349ca31d7ac57a086c5270d754b7ccbcac49d717bed5ff65041b2126515e316b07df4f16481d4ebd0b1dd2b40e2ec4d429745351947db5fa664f260974c58556ccff7e48737ac2ae0cf9bd7835db2f89a37663de876bb3f2cbee6835d4f08f4ad7bc9b6b76bc8686ec1f7d5a6452d2594f716d98475e3b67d3f225c83d5892775adb886f2a0757f1572e4fa6f932009bf8123aae439b3e95c0cf3f2cc72db92feb71a89b461d0f384fc96342a43365ea5dfbc3f9acdda6df8e9881b917e2c172c13afa7291b6b13247dcb6cd562e5f7e60f36efa38efc79b88ed83af04d8081028479d5fdf8ee558bd2374967f13597e835128e32b8c342d631313481f3eff23ca1e7c96ad5ac5d20cf74c3af7259394f9ca283dd678baff94f60d61166c9591684d6b46eb837d87df603e680cd4936d1c986f34505878598b91fa13e5fc367e0a6a159c538a9659713b9e498dd4d03b6802b316df71bb3b8794d0fb3206db7535820c64cc5b6db8720dd5c4e3978d70c9718560745bd29aebd55863aa799f7de6aba5cc7e9458dab74298fc46e449c5e0c763f8964240fc67bec920e76aff55702896fa6773a65024173e649617dfa90d0a5f173254a1ebd4f82c1ee918e810771f3f5a2e483dd9098fcf8b4319c96f7967aa57379654156e8de72ef51b62d24e0886ee801f8c1444119fb8920aec947794e23bf2728f07b2bcf91bf27f41bd4da01412cafc7a8e8362c8d524ea0f8321f928e8b37fb411a321844dd9f0d70623f43bf671ba0d81a3c0c395f8e7aeb27cdfef908ba2d8a08e0036e581fdc68a6184310e96a4e2561d3f52e0ddb6d48fe3df12aa6c9457a59b7a3fc47423fc92174b12747f9733d7ee8d2cd9ff5d485a68e072ac5c301909a3c65b0643aaf765256ce4090167f9508d80ebfc20694975831995543c1774499ce6f671584b8fc0baab6e329e382735631159c888a994f147d9bb1ab8500115af8332cf39dd97c9acfc562b1336795500d2d841881f0ac18a1181b1a97c377530efe9fd109c9ced7e9f86aa28b5d3390a3aac92191240559942daf679f041bbd61b3befa8ddeb0994315696a8f3f09706803a68df15ae3afe27ae70d9b910458b7b04835b3f2b9531b23296568b7978d41b2ba12a15a96d55d3c4ca809c39ec26812f329149677f920e9a0d4d90796b77bdd834728a2a1cb8484d9f2fa89413fec1c22eb8ae5fdb4f6aa2a5235117a87c8b767b93d004ec4643abc131c8e7bb156d7003be94e3f88637660a3141ed1f58950cf0779922d400d40f0e6c7a74cc305586cd56d315f05bd274fc23076f19dbbf8b6e029feed32a1509563e8bc7ea1c02a3588b24d34dccad6fa869b5246384de2d8b2f115c66dad2244370f28ba237c40549e2c5c722a6a65518732a53c4ea765352cafc41a6a5a0fb340193c964531846aaeb27ef88cb318b00546423496b33490b7e658c5733f3e89339a7516c3643c2cf3752372e5ceae8094c0694a4ba9209c6648a51a3539e8921b780a84a7c00b3378bf48a980e739d3a902398390c8a988539358d0c24026872fc7ee16baf76ef583d23690413d5b1ac800826d0dd411f0147477010366045bd6f983552eef2a4c1db6409b8b6d56e550556a153cb516384a2845ced1a700426634d7f4daf26503ac590616231e7ed4f37bb57aa48366ae01ab46518dfa5523491392e87b388e26b088e464431a8615aa956854c55a4f1c8baf563a44ebe20b762d5b9bd2a6d18ee13e9ab4b5b70a38937a987adc8ecd497bd80d9d39cdbc5e6f7839596e4426a195a7985d2d0a657b40b64958ac346c13c718be363a54aba57fc12e41e48855f2a275c148726947f4ef54f328375c5430c3f14371b2763bc147ba9430bc348fd20d55e4b15e1d9d05ef2faec41bb517cb85dc736cf42b65b272b18999c4fa7fe1b41b732353d86eb718dadf99b15c1d43a7b399e04118f3bdbd106d235cf04b925ef04bf51690b4dbc66642dc0497f6e6b3099a4e192ecec57c01f9ab205cadfc775ced309db93ac993d4f249612b1aa5749806a314b4e9191da5b14624e20dc6649c02f18cd23a87e847a4aa4c6f3b8c16ac663083c51efba754b356eea1f35c80cd9dc53c55a7ead50acfa9e0c468aeaca80dcbfce3429fbbd5b6ba25d550206ed3fa5ad5679d1993ab885c512247f97baa29a475eb3c70323ad89507a23d7da4053312fa1e1027c08cfcc6b58024bec42323835d6df557a66e91308303b53d2781bd8bd4f362f50511d8a9a6b3d7e2ab18835525451025d8078743bf8e422c4bd2d1314042d574ae2dcca0a3a8596a88799636b98a9aa79e56aac9aff778590a1c68091f34160bb4caf0fe765189c9e998e50bca63e1019bc85216d2d43a18518fe86e951123f50a234e9ceaa284d8caa294981e4717971e312ebcb3902d435238540261a412d91667809934541b24ae05a99c0392e238ec289c7277ffd2eea75f95d9d41e06626e4eb4dc9c19624e0f5baa1a3c546dad09f663ae36a004b7d4f847e4273ed2af3a9b60a7b44a031e2ae99a34f45e1aea94016f0e4b3826ea147937c3f19613d91dc33006a32fce3869577d6e2e70fc511fbd58bdba06f98a3e7a68fd5b14daed60371e3d5bf8deb6d0b0cd025c6e8ddbed604cc7be5d16903cce88207928af00051d94c33428c8380cd7933428dc55f12a751ec75aa9bcaac23eb8c9fb045feb83dde86b0ae2dafa1b54043cbf65a0fb69258a92f1d5dc165389504a45610688c11b938942371a3a5217c558afc9548ed2d8b6998ea72043018b5cbb0d0db14d488725981277a4a1d4a3a9fe568fa61196d28c59942f4d1d433aedf629ba04d0573e74cca3aef0d729b949c96d4aee52b93d1cc9558d3cc7bd861cabdf13f5fb223517c8531bfc19cabc4c812f75b5107c7a5dee40e86ab6534dafd202518061b815cb005eb3d9d54d3a1ea6a31d9e8c31a034c75419f50575aaf0d50cfcfccb8ae42fd6c3e7d3199a95378c03f713338dc42d543412b7a0cc2d0357b31d10fd0275ad57108211da5100a4d3d9ed4e7a55edccd8a2123b08a3bac52b71ee8928afd014f58e1e24ff5aff4ae206486447528f02bf12181a0bf65520c2a65fc55c85648bd85f88d4e1ab6a279f560647a0e5ba339e2e6a513508dce3d72fa9cb9b4c5379407c99362ac79809b80ee357dfcc6227eeafe9a615952548730b7e56468c78fb46b2b96fa4abc3036feb10c42cb311f7368bd7aa3b1b8b42f35457a4edcf35331e36bb1998c16e74dc54c68c972da3076eb01b9d341571c6d316b2033bd88d5ea41de40406494725bce2b5856163f86d5d4d74109d36d6e92cb36f52dffe832727ef6d132d79f9d79709fa6b1ad852c47dffa56f2555395137f21bef24f5b15e391264eeb89e7934a44637d9185d55f4794adfa4c1f394d832c41a1571c75715388602c75b0ab883ab0a9c4081932d05fca1d5dc1383eef8052ebe197993062f9039978528efee54a88f98b6dea6c1d68c10b70172ea3470babd01d2ea5a03200eb6cf9d23579506fad4e5f3bfd492c161c9700d97c0c51bce3a043871eac1858a34482d19c8139b59046812cf3b57725d4ec6e2aff91598f63f9f0fa7f361751bb0ce4c055df772b7b23a233db2366e3b0f91b1e7b227147fce6f121f758091b8edfc868a6bf67dc716f6397cbfa58efa033c7c9b9c7589cc77804e67c1239b9380300b06a99ddf1a4600a6576c6df1dc48c4c435ecea51d624e5f9b23527abdff01462d7086719ff9006c8ba82b341dc7d7664c4638c51aef4a27b1937e361c924a06e4c6c6fb8d7c01eb2c7f5ff1c4f1a497d0f0fd151da01a304811151799eb6dbbfc9c5421e40d57e608a1f63e231241ed7124f30f104124f74e20bbb33be4fc3f8d4fb741c98a6dac3a8054fcb19f86446eed2d50a90de25ce24d1b64e8d5b2d27eded743e61633d7fc88714d5f8acc507a0576bbd33b04ff11fe1001aca9b8b33c2e1f2631ac0e812668ffe680cd59241aacffc5c52427a1973af73204f5ceb5cb876c7e1232eda1efa3fe2baec61fd232ebd1eb2130fd7897b69fad98390d39f2570e43b8043a661d75600cf143f031eb446a64bd0e1b959e2fca476fb674b7878d4fe94d2e59a7cb607e73f6df0414a2fd40b17ea30abd01ff212c2bc475bf2d98b739e64c99f5e8a7a74257005998dd9ad0e9f3b61e70dcd4dfee044f94f6b5ed4b18d522f6e9b61fd02d7f8c53743f3b9326064430dbb20c69e63ecb1138b965eea017ced733e4ffc4ffd00e844bda9472d0c3ee5d77be76bf3d4a5a21be0538f899b61f5b8b8f9a1de1665b8f4be76d56be366185f1f37c2f635d27c7ed49f0f24ed54fee33b19ec9a874a37ecf0bd18c755cdae1035f1487ae09ae22442feecf5d04d3670f30271d1ad19a0d9533683835e18c6195d6e31991a2d93ab24190b1e6544619e47d9de60d7e07b4d5c5ba3d105bfc4bb865e28a3641dff8927274e9230feacc359187f4a2fc425cde465837175efc7eb9bbe19aa1fbc11aabf7073c4bfcee55085df60585e28f5ad52fe337760767573ec5f86f9f42a190b15e95c7a5fd42ebf2c7f6fafc1f007af9bf8172fb8fa2ff015ccaf73273ea9df8dcf9d4bf248dc7e9cedd42ef827ee551f7e3fced44559ff855774ff2dbdf98a7fbcf5c27fe25ffe55e8e3cc7d879f1bdfa5ea26aeeee3f6791e5ee51330e8823f1bac89e32636c50b9f5f0141c4b5f7a08f1f7a3df4afff5d79ff061a9203b563fe5816c00b131237431ccf173a80ec01197a6d42c012908133c330984c3513e18d094daf2a0c9ce98065309c395c0528abc26f9cb0c384386be647402dc86ed33fd534cfc7c2fe5ca505d40f21a8fdba10628c7feba8ea8531e3c183941cd84347c2e960d7885b8c45eac879384c9b3ab3673b33482f817ed329974b177f9670b378f1bdbd502d0f09bf48f9250e252c679c3ac7af8f0b317f2eb7fe61999b4398f0b2d4ae382403d96b2b56af98328a1bd8730e8e5f53df86f79f78bd4b42ad076d643c78ff20e2ea8adc8d38cdb9e3fa36213dc23c5e422fe2b4d89a457314391d6ee659a77dd6619cc3d95bbf8d0509e1a0f1b52dc9ed55ceedc3c52f6cb57ac902ed9b7ac849467f61f12fc6dcedcf2c10fa1a6b6ddd06bf302a2fb968edd6be403b350b1e704ebc0e188b9cde4b2df79e51321efac7e1767bbff7eca5cb560d8101e2d5488ecc130dbe286077ded9271a4fd2023857dcea2035b720b656bf030ed0dd1ce152d7c9283c0c71e5d31d6dedbf61c1021e663502e1d1aa66e3db817699d2320db87a9e48fd3bbfea1c7713a05b8af36510905101af205a4c2793f58a3410618351d79d5469477b977b644a8986fbbdf3ae08adf4c5fd377bb7722d749eea7b89415afa0d8cf9cffdb2937f7347f6d21cc9d12d76ab4b12b08ef66ac272b9142f443df2bd3cedd4e23e0d795560dccde958dc38c19fe7d3ab99fa3e9b73099b894ae546645bc6cf850c66aa920c6bb8d6e1735816bf0afdfdbe980fcb91fe7a2b72e6a69e49004197773ee44773c174f81dd6a8822f4aee7cbd9fb1d2fd048151f57d0c10fa5f4e698c702b5031ba8e6c5a569fc0f698fc1a0f4b713c669399fe78699294013708ea4e4ce7b382217a2a96bc1fde413faf877c7a0d917760150b42d3e9049a1b8ec767b6a6410986039d9845359d799ff3e9489c6883747e149aa4b3716f8cd5391bb75197268c351971ea080d93c1ee046f0c20294cc084d2a556921e89db45f0376fb67536e29bd1a8f9b9c73a69c1e64755d00d6b8774d6595c25a8a31ff4c2f86f7e915cd2bff905bb5c876b473071cc6b0ea7952ccc6ae5d804f0ec262b3dcf04f56d53b0ff6435e36cbe2e2ae3ffcdeb52ac2c6cb701923e58afd84bc24e351f4e82304af606bbb39bc1aebbe44db8d63d6328366cf91df709caeafd182d61eb757bb0bbbf2f8f13828e79909204180f613cd8cdc653860a095a6d265d2c4e31328c958d265b3d1161042e07041a722f392d83a5bc4d0c2b3181e15f3235fd12b6c0d563aea6bcfc119344c02c2a207638c9e1471e966460246e7351aa5902b35dde81e5ef8ccd19903a1acf85b9316729e4b986267c19fb297765ece59a2e31afcc6cb51c55296dfd7ebbce575dfaecf03151662e9ccd627b7157adcc6809fa553e521257ad468b2c5bab6eb707bb7ffd85da22c3727bbe7a0f1ef594809d060be84bd6b6697e4825d66b38d008f0edef58a42b93420e01caec5a7165d3904ed2192eea267406bbac2ca7cad4e8cdc47dae768dafda686520356d8ada07937c9bd157f3615374369d4f58d59452828d6bf3bc365c2c8665be0fb651ade9f85edd6c7b1727cc174edf24e0d2c92e457333d39f7a9248ab55af57134d8a6adab7b1792f9527647a0db6379a05cf40baec2a0d40b68c119709bce041e8f968afb812bc02433b8d5a465aa4a9af034abd31444b498dc6e77d8146c76304f3b588572bd649a6fc56b95e72dc6260b4238cc1b553ad181cfb79fa38be4e8d79ceb35718eebe39435531a35d8bbf3845f1ccbade0da76c2f75b56c348a8759c09ed1a4dde63f19c9ec25b8af4e89da55937db68e19e56b1621dcaa8db4538a9bea3dca6ecac3a817a1edfbac65bc154f5ba7ca1fd01ae0af694f5e73dfa748bb9df419ec60ad6ec4509dc821ae562f4a3032b1915887d36418a16575362c17a8bcd537cf1f0b3454282fb56c2e348d9eab0b6ebfd50ab6260649d8ee3d0aa356cfb3cc71c303cbc5631405fe48422b1e8471627c864bdaeac895eed5e99c4d3419c5e152d298b692d4b4e6281bf19fd0938df6f8df29e62253c407178e560fc49643466b459478a612ac92d3c6b8c33107724f83e1963b52649262b5b91f375cd3c1d2f580cd1f6b1108bfd1721f2a1a28db1a0bc1e669518bacc4b8167335afc7ccd862713d9d73273ac4b23795dcd5ad9d21b4bd02b96a66f651c0f68e535036274732f0830c3d87a8fe60971c43a835d825275c89f070a5306e180f7c8bfc44725555aecb0e850e238e049c18fb6d21d7eb702be91803f88d8fce3f7bb3a6d679b4d137339298f05d4ed13a928d69243573def04c8934a6ffa333803144f18d1c5b3374f00c0103f7926f11365d88eac37022a65755df06b54afbab6da5d2b160735dcefd5025ed88ff6257726599010c7c798ba216bed4ab13dcde1d172028e1b86e12dcf855ef689dd95c7c1d4eaf167a65b5a2ffdd98e15afcc45b18ad86266715a87ea494d23bbe5ac9df63f5fbdcda8449ac965bb2bf8fd77a99e588b7dbc9dedeba010aeff22e9b7bcde91b56159d392bf974e22ab11e3ed20e640e42f24622feafbfc032e5ab12fd4b68d1ef0783ddbdd79cbc75b200f7eb252bf958cc172afdcc493fd6bc0955d83d5057aefcebc51b7e89f62a8c7280a3d0e36c177a7b4b687a71c62f57ab54164563051b6a3c2daa8fc8c625556ae83b55fa16e8530bc6d3bcdcab2d14e1b24c1b95cd2ec48ca6b10f5fb3aad45b2d782eeb5bad98045dcb2eb0d5eac796d2eb42f15915ec1ddab0091a752723d3c2958cc68f5a390c154c98ab60e2fa33abe9661cca33b795f8e09ecf84b712dababec73bc8c3a73bd6609ed6666bb74d57ac3e863613ea4a66782725173a947a768f7578f21c33c5816b712f35a5f2421e1ba38756766a5ac2839263780f238eebf264d3f2c4be3f6d896e28f4463f0d35466e2bf066fab539725b818fb386a86d995f28f1af80d31637f64bc2d5caba5fe7e0c64f6f7b7a8371ec02e28e3fd6fb05dbd8b05159a3c5376c443275aed930935a33c6e758e9abfbe03bec91419910936cb5b21c811dee5a6ea2404b69472baaa085ef6dfe272f92cb304c9b145e8669d0144f9290a44d6a307e7e130f6c54230ca3e7269cccbe0f42d7a52febfce5e9055c5cc6491ca65ae38924f41dd722218931a512779f25fbfb71f88107e94572498c9f183ed8d5622e72734aac1da0646fcfc9aede9b21b77701f8dd609eb5db29c853f97daafbe10431c9e601aa670541f9ffe1917186e613eedf0de3b2d907d96d6f24f03dc4a9ed0f6ed4953e723cb17e5647d13fd5ef03bea122c6043a4e7c6096b4071cdd459384fec989dcd370800827821a9b64c372e733ef7fe6caa4de67ee5e1d4946851e56eb2e326db741bf9d5271c12ec169648c2aa1e93e837c9cf662fe8ce63263bacf316bb6cf2fe19e1f1b00a9965a60a4f78cf77bfbda70a1838e4418b31eadae8d4e9d68ff886c1f63c00f9a3f22da539a3302da619aabc623b7678874f5d0e00c93b1d4323bc58e3210d2e07636d0769efab2a20b714993209517546c19563fd147b76de81898473a672acb2154c3c509ae88e77390c3109c6a5b49dab88f49e96f4645e0f54e6bf5a229a27e22a254e8ea3795fd68aa6dbe8223f3f5a02c839f1d6baacb19d6ae0073ad7922c6eb002b2b9a0aa50e9e63745defd7d7af4704126b57dac4ae637cdced1554e47cd3562f24db309888102d923a9d77bb712fb4b572fd8d98edf0a2e8c4735812a12e3782b6ba06e28641019867a826b9817257819226624ddc882815840b4dc65bfad948e872ffc4251e091de833418f0d9b9366636235cd3f5bb4b197db464cd36bc312edc7fb5aa7eb7518ff6cfb4397e04b03d6508413c39e83ee06f3b650959283923b2d96c2ad6da1aa809104ebb958fd7022de576c328b366d23edb08e495ead4e58253ae5f43a08d76463fa425dc3c587f9d5427faee341f97347dc54a2e49ee1254756355c3a2ba563a6b7d9d5bad2fe93b17162273ae536ac75e5c4f54e12978120a94d0b63e7830af7cb252b79bd7186024cd27187d698ac47758bab40cc41b7cf9cdbe4f7cfce4399109e100290020ed3743aaee975d61251c713699f8dc78e4c405d677347f65a66346db9fb4d26b4e66dc05c9e1fd866ae1f491f3f0dd126a6464a10c6bdee4f8d70b7db7588952eabb538225083d66491873ad6c9057c084e858899569fa6998071ce05d5d4132c39abd4852a24c5b684a1a0174f49ef901c3c26870797e46f416fc170d8b11510aadbe72123a5cb8b3935df11fd02383ac8ed7630125605d9cda7e586c6bab90fe2a6aab7d36eb746824c304bd0fa5bac5623d16e3f7926fff67a3fd19108492928f2273ad97c3a392ed8fc78ca4570781092a9a0cb4464d3b90099a8e8db8293f27ef4dc9618ec5a41ca5ad25699cac1ae2f69052fcf5a8a10e54cb59016cab6b2452506bb976be2947b51f2ef84f6d82b5407d84fdd06b312e6ac49886dd10e34228f3581310f7e9446f8c73d3042c4e5b65e408eefefc7bd7a8edfd5131408fee75d3182c4db7a8219bebf2bca6cd23fed8b3c56d056cfbd4d7c115b58dc50956158eff75a940e8579484d3a23717b0c73d7e6c726b50ed6c1c153e0a4a98c4e3e45fd9e6a20f758224a21d1687c6d3a9fb6cf9642b354b9a8d8706c9ccf34f81481050ac4d6d58b915dfce4fab3109e87fa6a1b6aea735af7782e8c7f69af9fc32c383c005c5c17c3b4f0f81c7240bac678abc192b32c18770ec03aaf186194d252b4dbca5c7954f7f380871877e7ba12e6417c21cceb77bd1bc8b669fd2dda6d4515fd805179dd94d7d03f39d59753c01361218a8d6da0472d6291c7706b424a2b483a69351fff2a6e572b60c4aad04454ec57710b56b45586765b6750a6b7d382cddbedde330ce9138031432523d13e8e87f3a6dd4167593700bc6da82720a730525ed9e0c96eac86034769db98483afb2ae81276f20fb733b188a68278660022d784a5e3514e76e76f1126d1bd14a93431949ee55474ea2bb162c0255bbb582ff5a2e4f794d102c31bc5704dd325d7997e2386878885e8038d81b6584383f26265561454483a38780a175cb59e349483ee8571d60fbce149d5f0b4dbc142ac56598b3695eb67b41effa2e4edf6429613300dc228f8cc29277ff2efe5aa2ce0ae17928ce6c29ed6820cd89520b72afa19d00b155120e85c384aa1d045951886e40f1e642111340b2375e20a181d8b7e85788caef037ec07092ddcd6a6a2e31c7cb4c02c922965b2de240c23652cdb1343a3a29f442a98f44574214872b95e936b419720fb12b5ba04b644f52b2f3b20f9b7abbff601f7835d94ba624310bf9a4c4b14dfc4174814acc2475f19068fae2064054fc8206425c6f87303025aba9dab39445f0b318a5addb55dbb6fc4bf7de0f6deb6fbadd6b5b8401ef865547f82eeb7ba11b0a4643bb712272078ffbde703ad1fe61f0a20f65b2701656201545f5c3516e7407035ab2b046c9c062cbaee8461d1d29f1dd2b9151d2c4b8cd527b8fa699d83c16e7c024f2cc0cab4c22d12214748a5e4b9a8bdaa1fc3d8805927bb8d9f3803068f5372b5bb4d5c335e36f30bbb9f59485c53656886e814f673b82f9c0a3a4daddc825c755a8d7791d5eae9b3e64b8a27d7f7b308c2e5919ca147020e1e69018b7720c7503bbd344a812f4528d1a030e2f4faa5be529af504dee05caf99edf689089e8b3004cf5f77324c18019b5421f9858580479428b73a01a72c3816ae6cf62f60e00a95016cf3afccb01ba30160533a90dd2347822612ec941c8117ce6ff6318cf4c90d576c598b633adef6758330f58b913a743a9f7607d0638be8700c6a78c480af71b5fcaee2f66b377bed01ab8994b038cef137fec67d2bc85fc305acaa8098f757b3d9745e091e9d7ee7964e93feb95c7e237597cea870562ab16da5729008c066fe635c060f67209268fcac86c8b77f218c7ac48d0890aa4e4598d3d798b0cce92fc8022ae82b017b75e002557307967dcb1d986870b5a3006ab7839cfe8a9a0e397ce468735563fe4e0439b2698a76bb0818112409639fc40246856fbc3e942bbcf5fd23e175e45cb06df02023884d214259f45fafc95b973bf27528ae913587b70bcd29199467822e8fc65534d8c563e960971c63abd160571d5a07bbe48da85834d85527dac12e795f0c33590af49f21ca5987cf9d557083296dceb6b9902bd2301baa2ef737a302164601a367e2825d86fd562bb960979e48db6ff65565e75c28fa7e276897bc977f3ec011ff23fcfd5dd0b7c2606491ce8528ff40a4e0c767c5181d0f4559fde17ea89419cbc51f36a8f32392544d0a1df88528c5b0421d7ed4fb19fd2608be4a6b4ead0c2b4eed5c8c5925789dd9eb7267bd2ce002475e0d94e41eacc5d6d25f9f75aaa90a475ec6704d26d3af10fcc36b0726aa495256e64de326415bc310f13b219b4414eb01ff20faea923c0131002315d73759f793a81b0572d0baa4eb40f3793b349fb741f35971e312fa5ec4ef2d3c9f353c1fbf09cf6784e7a386671d924f82fe6e89c8d866c181ba06ad0d08a2a77c452bf2aa7835376cfc3217653564e3733f7e38d64427838ab8aaebe14257838d7d300f02c3c5f97c3861f35b3d9bff107439319210d1b2fe981bd5452536d87cd6bc11f12ce45ccab1b85a08504fbdafe2d7684fe99f54acfa751fcce74e9686ca5dfb4aa466a8c736701fece74e16e0d5fdb326d6e4b3bfa5fef1ad8d932841b88c7ae8d03bb857bf8c2439759158cfa7e3c02468bbdda59406a27d78806205b5d521f5e6fc6ad5cadbed56e65bf0a5bc837b39a89cf22890319eb07c286f7cca59cb505caf5699120443595e7514805d11a66c0ec67c415263031eb31e85fd2a95e708a06fdf244e618d12252d4a0b141c4bace0181a154ed4331a1c0f72634f357725094be3827813a3fe600c4ab58f8de8ef789e18d33f44c7ce05889b9838a050889be9f11aecaead07bafa78358e7538a29f0481865cd2251327061a22b2111531d88d99726898f7b3e89c07791867dac521c624613ca623e75e3426ea6432c6fbd06c6fb0ab2ca2c9287ce567f1d81f313054ed5633d1ef50a9ad46d9e29251a650ad1a16739ac7330aa69079bb3d0b59b41c511e4fe82cce95ea00a3a398c58c82dc5d98efed19a582844ee22456524021dbdbd3865df27d168723193f0a49bebfafe3d97e1e8713193f0909d3f1320310e888523a59ade0c73182afe5bc06a5aa325655ac478ea22986e309459bd4237a7119f3769bb7289dc4e132a7bc5140336fb725654e9435d1113e99f130e6b20d1eae5138e5e2329eb5db3353d9ec7b2ae358d92c8c67b2b2195636a3dd78f66ca48564667b7be1ef3c185dcc7cd92765266746b995ab9a494cfdce038e991db92afbe2a9569e470fc3fec5f832ba1893f4d2bda1ff297c2d0a2579df6dc164e8fd20237a3f24e16ac5d088949ceb780d7e20b688452bedc7e1a26f42d19f82b04cbbdfb5afbbbed88b7b134e32739f7a80305a8faa9e6f6f473c02a543b73b9b4f4c86c4b718661c0383c6260b09f7227095d3f2696096d6e30bb77a4a68a91b732bc6c6f7f642b0c5ae9ce82668f37ab56ac90e5dc88f4b92e06f686b726c87016819fde60b68aff753f30b28e1195de285ee3bb947efd5edcfe71e61ec37df91acf1156d370599483efb68d360e9b7184a44e0c24932f59babdf22ab3d3bfd9df97ee4cc9e99f4138399e8a9af059444494def6c980545a6894564ab95c82415f1200d6bf2be228b1dbe837a5b1c963b69bb7d2bb3f753ba445f3d69c7cf4644c9ddc817255f47414a83d407a6ddae45f8bb3cf63094abff7b5d551092942e599916d339d8f94e3bf68360f00c15b6740a7e12182f55c48431d61470beac5bc93c6bb7932cc8339286f85e11e4194d89cff7e399ea2fc9328226f335e34fb31d88b68348454680fd4798e6938c32ef50c7b36f1eea48162e05cd56abc03f3ff9b4c02d2df0a87eac42cdd58cb644182e59b4143405430a19bd661d3d3562ebd5a21be7cf32bd06e46a0d80952ec82ef2cb5002d4ea199537799759cbdad7f2a8e851579d8db3f924a62d726ab68ba7bc243694974446859c43899e40be9553f53a9a6734cba868cae13ea9cab9d7ad995db62b40ed19f66ae69b79f51ebd601693bfb300cf2caeae93b326c84ea699da4b07e5c6f370e3fbf28eaad55384589371e6f0628c0d09b87dc0ba22c66cb610fcc35047cc16e28a9b4bbabade4ddc5ad2f170964cd91cac9c3530058087687358e542af1c0eb41f29afb965e6f24a7c06044263b7f4a9e7e5413f930317121e2655d3e83c40c5912ef2bd7a87c6614fef300c234693b8d7353cb1dea1752b70f00c4e08a066d96791deaf66195dbe58a4d160f7c5226533797b7b3f63a948d83c82f59cbc16c0a83a9acfa7d7323cd8251f673ae2e36cb04bdec15d5dc5c0c760979c4caf4b1d878a0ee4448ca3c1ee0958d11cec924f4399e1ec3db0c7caab68b07b6c6d800d76c9d16cb6d8887c0f1694a2c12e065e4fd3912c3fbd3b9f0f4b9836bf8adb68b0fbb11c725156c30c8cecadc9978c2e9f4483dde72c1d8113c0c12e791a0d763fb064b04b7a07b2a1b160f27adc3b94d85077e5de23d95631847ef71e2b78e6d3b1fc94151e8d2145d675cee0be420eba1118585b28e80e1ebbe83d3c50883d3c843239686990c387ea4b21ebf04780421e0f0f250c2fa71328fdb83616874fbcb1387c5a1f8887ddda303c9435bf2a1702e46a1e3e72c7a4079838ed4150c2777a004109dce9210465e9d38770cbef01764e7f847809d8e923084a904e1f43508273fa04502ce1387d0ac11e34d2853036082d1e408b3d68f2a16cf2edd544e1b007507b837e7020b3bc117276aec9dc9b7223715be779c1dcd2136d965dc0f7e56a05bf7846f589c67368b5d6cb82955db00caf805198c5444d2f433e5193a0010b379eb50d7bdc79f9c0aabf284065c94b99c38711dcf6ae89d615fef71cd5b99809a63865f84ebe9dd3aa57a1c665d3c3cfa054dd00f444dd35515dd956f47b5062f021eb03998d6f03e281f1af5a5a876491b9cc4bce2a06fe0a3331d75b4ce511215ac95bb8e2c71fdc28dc2ab917b77580ee19d486315a87e4caddeedca7c47fb2677ef5bb2cc615fba311db986425aa30e760174cd89d98c441c9fafbace3c4ca4184dc9fb7d7fbd9aff7b357af4ef4aaf5b334e530edfea91f76c615939730ddf56bfff4fa29fdceb7bccfc6b1209c24bd236293789d23092577ee69b6716bf9c6d189d179d67832ac9d3a192d6bf9d433a96cfa006df3c2bb4953ebda00a7732e540638ef95e073de07b61e301d9f00db1d07f867554607e5ef62d34341d3a9f57e0706e2c67518e2ba3470a27c508c5151376a8a23b1a861d831a0e9d80150d6336b313e9aac414da8b8f22afe23c16c9fd5ef9f49c4e8d8cbf240465dd5c0315e60187d5b439fb2351931fab54e25d3d9ad3310ee4069193f4627d97fe682c1771250c79863f17423d2479be72be23b9c4aa81934283f899a5147467f5ecb13b9bd0e0bcda7055929ebeb6a2d67fa6cc38165b71786f18c51f4c5669968a001873ca6c1ee3bf40526e6b0aa9c8faff261b9f37e38998d851bf3c2b0b1dd589412f24ac235cc8d71e4d39de81acf268ce7dab6e44d46dfa6f198d1df783c61f4268b4b46cf797cc382e5065cd175461a418b3e0bb2015df446900d00a351469a618cbe8a35c2749bd18b4b7297d17d472ef7a55c46bb3fdd65f05eab9d2dde661777d925c11f652a3edbdff734385e21d3e92edbdb8b554653416cab42b6e95146976bf20b5daae8e8285b935fed67abb726cf337a9439924d99afa0ae1563e402069b89afa87e942935f59a2a3b6fb779a7664ee18df2bdfab19cb0c548a07b6f7543729f68b6167cb3514c69fa2cd72403b648b6332c77d2505c649734b9c8800f1f301738c2fe1158c9f6fc9bd050e1a8e358691d2ddc9d3a591195ce5e851c6f942f956177cc4fb2205cbe0c7e0de397c12f8e1cd08bccd107ff458f7d8bd2a3ac3e9f1f3d09c3f855f00b49e4cfaf9ed1aad3cc3740eb0e25d376248e6b24d0acd6cee58ae3a2c49a90e0742331087de554b0cada0a94a2eac692f484cc922009f122a114161daf2a3ba0a49592e51a8cc81a31b70cf1ef930188d86c1b5831cffd815dad8eb2f879460d8e01950c51f9ab8e0ce3265f1c2fefc12e5a75a80fd5d3308c53792f5303f33c0bc9f639b1012c6544d20a91b44210ce3002ea51038fcc9357d97de68b7ff152ebae29c8af5e32ee7826f1b55fb3f8722516d5391b961579e32595d36bf2d68b910482c8d49080bb1072e6e57a3599083e649530e09e67df34d7fc9b97a5e650e39d97f87a7a6d52defb2df3b16df403acae1f7d4c15d3ab31ff3c14634e7ed7f2e22d4a5f67fdd799abacb9269fd4c3c21feaf733b026ffcce89b2c08c9838cf65e3cfce9cfacff266b50f29479f6ffccd69e567d1e184d8fb75910aa83fa59a619944f9fe209e7dcc63cc198df6ccc638c7967631e61cc7b1bf3a33968d46daa1c802143fbb296cbc957bb393c7daa2b3acbb0eaa74f74ccb98e79ac637ed3318f74cc3b1df3a38e799f7d2f4069ae2d0402687ae97885bb9ea3ad985b69622fe72f7a3a3b6eca73eddd9552fa29eb079f327ac12ee5c0fe92056719c9f2308c3e65c6bab3168aca1c73d979e0fa1bfa23d3face7f64b12290f8d70cc48df3c057e954255b9f3363e1e753162e3f6756951d256a917bf4298bd33c78fad4f5bc8466ffac8143a6fdbea434b96097319feea4340d5add50d9bb29b559e7f53a8c15212b336f69b8c43130b0b4db12239f326d3e61af1786043193e721496323e20b53c095ee2dcc30a43fd09e5132ea751f1f3e7ed87b72d0db0f82c0f9627bc90fbd6ef843baea867bbdf0bf1ce329c3dc3cf2a2f10badbd3c9d2dc265822abe4918a31a964df38dc5b2d07adcbf482fdbed40fe80ef0bc73a12988cceed390b55b247289242c6ea7792d7a4ca4b3994939c8e73aaf2ba033dcd2daffdefdcec442f83bf732dd4def94b9dd43a7fa964342fe0f8ef9ee5d6a1876bf5499ff73ce10275667971331be22bee87e1443c4bc2c6789a68a91d3090d2581244921acb5a9be7dfac24dc52856b42d05a6872a8e98beafb28a72c463cc300e090db5766c78f950e29fb97885db08620bcd67f82978c790e7611fcdc4a60de75806b497192633bad1e7ad2ebb6b47bb52d36910db1a39db6494e1949a88d8d13ba54441031324d1662fe55f0e7c36a1125a494b1a8966f4dba8f73d727e0a8ee22feb02b8f8ee39c26f128f7d044973e0ea22e71fb1d2564ae2f88c820549259638979b04747136362cea758984155eee9325ee5a8408eda5abf5d892b4197095b08e41bb2ce441d89e01b8c264326cd756473c1a3a5047f58e66a4a8a2c1369a5a17386e86b6e6d463b0dc689d73cbe5525db413261071c8c85b0868a753060e0611d1572dd6e5e1b98ea886704dd002d041aae0057cc79d42533763b9e32aead3ee0014d49d8595a30630063e228a9dc6cc182e3104e99d506f06363b50e911c2b9a4afb891aee285021b4c94a52152f1730558826de40dce6fe7dd4ae4f769df89a8343fab80ea6cc6f706d81099c58aa21233a106e85d105eb2eafb34efda69176b57f043be039150a5906498e10977b04c8b4e86306edc7f84371e2c46afe14eb8ce671bd4a5cd58a266c15e094b97061256e9283993c0cd71e380614148a140e758f69974c70579be1cf8d11bfd4d5637fee6811f3e932a777b5151424359f2974a69b345ecf5f27f9bb8e1f0133e00e9c56ea5970d751213b15ee3a3ae84e08452a37fd60466fe8a04c1999d05118ddd01b451a2cce7f4207d87908ab9af6ee7fd36e07265bbd0f7699fe1f843e8c8ff22027f51ac3984580db13ca4845ef62b9a2a78ca69ab15f810ced52b98e39a1956eaf7eddb7d27727e172444f901d983232227968844d46f4c4d8c9833a0fa313b5aa7d603975c2edfd87dda78f578f1ec6cab38ddb76be45f0efa4efb71b9d385b5abe5a99635a6ea4384778c673a1c4160f22395dbbc673a1456bbb3d280366415dd1c30398c36a79d69e01f3be89a2177797518e67fdbb305cdfd13b9c3516bcbbd5ea8eca1901c2c9f5d96bea54f227b067de516ffe133dff89b3b8d08ce6a4712d508ee77be82313287b424791a2d259ec4c653a89dd2a6fe2e7793096cbb34fca741cd7365c3af2d6ed63f702a571139b507d7560a135cec75ce37cc6b95c724904e566649cb2225cda78ac9853110b9adec3a8aa735d9ef6080fc3982bfb3ae11aadcc9fe4f413ebbc0393ae783e796eed439117390d4a71bdc358072c6194a2acc2ce5c640bc700b3b35324b486b4585eabc0355d4af5fee4d06eda4f22bc97a0e2aa8ff0143cf8d747060ea7cef2ee0cade1fdfc92d3e570f1667a05669b369f2e8157e6f39b4e878998877d9e062c94ad02ef58945f6413ef4585071eff59118f060dd52896f1cf791012414f72b352c59cbecc034e1811612ce8b50ccb905e0d68121b8e8a63cfb6dd0e842580348ce1dc22c2f8550eee920ca0efc46ccc52f13f0c6cc572dafbef03fa743a4f951f470fe6fb214e1162ee413c285309734ac089149730c39b1007980f2c9c8935860d6e540d9c8982932b38534f07fbd7dc158724b9f6b9a2f99dfa61bc69419787c8e9d5989b89845dee6f890f3834103926c0da6de7a3335c9c5fcd05ce5c5db4df4a50466fb5922141b230f2b9b5af739f5bdbea1141d52347a66dd6231b3c6eb2cf627930593fa38b3cc8c22810f4759084fde7596418c884fb952d484603b44dd2a2943b2f013cecc39b8c08a3a32c8c13346b16a424db5c11f49821ca9d4a544c5ffda2d5137d6f99d35ff2d819269ac449135d51f61f3fa7dc93bfe1392573de299d317ae3aca84c772d6ea6aa048d6194a09b341ebf13a9187e15c0d891e4b23511e7c5b63a3fbe7d7f74fae2af7babfe561e6c41418f4c805ff24ec34215c8bb09e4221b9c84b70dd7103bdd0468e12f681a2bb7691bdb8f80cd8abec863b85dff2b3237cf839adcb30672b7998098b3308ce10a9512013ef2b6c02761c9457522e6c3af2aee743e9d2063ae7974b2763b507b6e46d2906ca97afbe06e6b6fb56a2e01764ade976cb628a615be06e312e5176839059a680376e36de6a2456733ef6a35288384aafe916dc03535d2141b845babb807dc7b12839024f274a617a32dd42df408217513872cfee9d839dd3a197205a17f7c7f88f623cf7225d9305cc0affb8c72ee9c5c53393fdc63eab60162cd3e9f98f248f317c8f9a3331a0c83960fa4f6c0be8fbc7bd5196f4fc3509d3e523babd78d8f860f1f13166a079be0138db9be001cdf167391f99d70691f12e1a7f317bade78273270fb6834f7254212cf9427b2a4399e7b134ae98b1ccc5f630c5dae437da1667d0ec2ba3bc985b88ce41fcad672b3b16d09bbe4a38908e500c4c569cd4ee59387cae797c1732dc3d32e20a7d19dc56fb9634bc3dac66919b72db541e991c1ee050eb4523ebb04146ea89b6937134a212bec6bfad8b91e56c5ce48dc2e769683dd3d5ff9abf3f7745806835db233d80df706bbebc16e94180f61ae2f82bceef15fc901307d74493a63b6a85e00ed6bf60fef071c2e7d184d53e2e6a2a93c4f010f5745f8a971ea9645093be74affc47d670bb499d3966f14df7d77e07198403ec229ef2c941b91463f128e1b72a6bdeaeb6a923834d43d12b7e8690fcdfb1170a3849f60f78f80f1f8a4de98c3f314fa6cfd1e292356aed768579e91b0986767ca299b05faa2a7ca00efc462208df9166f1dc610bac40442ca9fa5fd2071f03b280f481a463c76230f1afc04e4410216deb502a26d11b8d54e61e78065dfdc3c2bb5ba8ed5caea59eb32f403dc253a1350ff0b49a29e5c2823499c50013419dbd886c6461b8de1729574040af3ca23088877c264344882baf17813125868a859b7e15bc1c1634e3fe601162760794d9753c6ec35f471ad96986fc0cd2ddce32d487aa891b45a25db5cd5a20b1637c6cf0c826ab2ef70a76f513a28d35aa41d82dfbf3d048e43a48bcb6f8cc7c45ce0b25acf1e6f0eff27b76d92fd2b029839224c8dee9eb67879f288109d806a50d21a209e0aaf5385dd148d8842d279f000931523f44fa6650c52494709d2915a5b1ae8280d496ae9a844efcc24b5e0a44ac2d5d40b43b80d76b9079ee528f45496ae2931c0be2da60e4f5ebfd5d6d6ec98e7a67e71d0b8e843e7a2d2d849d81c93b4794c3cef35f2e487ca99b89ec010691fd94dc3e1b046cc70a4f70c878412ccfb29c30394b2a4afc81707c6d03d98dc88ec521359e1f0070d158efd8c6a0cd270b52a939a7cbbeda59d38301288fc740bf2ef5c53205b90cc9b916c360a060a2ab9a81032505106e7f2806960456dc1343798e606d37c3ba619ca11eba580c31e9b46f0ab5be6de184828787d0c04c112d108d389b6bbfbe01fb53436a5d5b8701c176e8decd11a5a26ba881d9aa4aea7690f2e2c1024270519597f34637cd2aa94d806cdc92dcd69971ce139402173d26edf3e2b34effa766f2f5c4e702bffe9b61f1cd1897a210ba3233a31071070654a6f024126a4b8b8bd2423d7ddfa1723573469b783093d522f176b79df2827668bffe26ef189ac2c8c739a055f484e6ecdf1bbea8fe997a832a7982f7145bfc4137a24512969bfa8d9a04da1263276209a28d1915a5727741608dd01623112482826000571a09838504c484527e62032064b1513cab113b5668ee85d302182dcd69b3a92173d43d7472e3a261dbc74e81e1c0159dd46f01b1209e0d10680470e8047a4928867b2aa26efda7a450ec05ca1db1323c0ab686aac0dca94495084db5f2746f5ebdd8fdd308c0b3ac2cb4411c683d20c49b191b9175ac1da091d69eaf5c9967ca1051ce703e3fdad6ab75b5f3a7c5a0a896c2743b8ac5c4aaed45490945c79947c02945c912f688b8e8c5d623e31c42cafe59547cc9521e5933a295748ca271e294ffa237a129969444fe2093d892b2465ec834bc45548460e249522e22dbdfd02c46cfba089ec8ba2e72f1eb94850be38a07c2113fac550c108e8b9027aaec2ed2dde0515d07573ab96b407a537d7ab1a717f51c4fdc512f777412b87e09f10b7f10de9bc487092914253f837b886ed7666b70c33f619a8b38ec02e7256db40426582e91b15cb511e876a57cb1a7635162dc7aa21b4d6c335f98f942d207510189bcd71e4bc8c3f8e8659e0c01e2ed3809191c66718cbbbc9886c42ef5c2718352ee4d6bede0e34efdf7cb02d6c66506e6bc8bbbe8c48b6b5bd3580ab671e4acc61cc889acad74e07fb019747cd7a87f4c9b32019929a73e96294875150c8033356847934acde81b908496121875b44e1d6646d9a03835a9f1894cfe7911a49cb509023c8d5088ec261163c849304580ae3db6e6480662fc6cfec5fbe2077ed3e06c3c3fdc1e124ab5dbdb68c09c88fa4f8aa561b1778a61b94a6e63597d785cc62af56a78bacf5969365d67cb234064132642066c4be463dd248ec077e4789ea68c3f863870897173407e07a46922b75d3b33cc8cc212e65664181753b71d24e6cd2b8dd868376769fb3f4acdd6e8df492c03c29172570821ba8f1146977d203825ef2c60cb48f572bd629e157f99329c1c18bc35bc44ea3ecc01f397d9707ad6e483e63a817923f73ba5c93078e6cf09ff99ab0c2ff4efc6f973b8d72f4604899d23feb3ce3dee38761d8c098e20572b55e0549812a40ac40fd950739f9330f41cfc73803aecbeb239a7abd086cf859e346c6705f025801d3141fdfbd8ace12d88e906db9a199083e81fbae27f42821e08cd8a9431ddd19ba5495b827093d4be4493e5cbf0c1ee40a7657665f14a02625d35e06ac907f93c249cfb04b45901456650799d769113cc8fdc8543587cb6f9ca8377b853902ada7ae63c51caa67a66e251d0a00110008df1eded8b1ed7a435b14da71b332a8e23038e1a1003dca03fd6aa353fe7399273d1da4e075afb8e57356094eac7c498a76f3297dce9d8f637b854a8cd9c2de536a0c2d3aafc9ba597818ebccc557c1c667732ee6e8bab945a9cb676c3f7ad85075e9f9290e972aa05787244e745a2c97e66179056f1f09984944a232cc6400521f443dc695aa6eb532ac11c730363e839b4c6b53870142bbf97578c6cdf7c661e11ab75b1ac9e78811d8f4a244bbcef8bba88b149d287770624e461b89aebcd1b8a05df2168fef67f873ae2ea585272bfd5ba0b530ccc3c541cff3775c16e6dda3dcb053673d5077e3d4a885b4dba995cd4a95b529b42f07c6e5b65896b30a0c856f2c6b5cd02c7e0bd2069b620c35496b15551342ebc67fdbe9561a7b7c3ae457db9f15d1972266207185dc918d0a291d17e132a3dd984f970dcd817ee2c18f3f6575edc4435098cef6682f3ea7675b7be0803bb7a028f1bc6668d64e994511279a517766cebc67285f2889031a7fabec510249806bf13aac5d7793703d9317c6cfe2d2c39db24c6d24dbcda72361ffc506374569cffb6f6b837c4e59744ecf95ccb906e7dc52e85511b8e479a6217beb3ca0308d0dd6af8d36360f6b0dd318c265751b44d1b927a7097ce1739a9033cad0aebc85a5fe0479d893183d8323580d71670d6a093aa5493be0cc1116ffa262bea098f63f46eada20d5d56cf016aa2d0fc1fd246061e449dd5c17f6ad570e0d38e9fde2aa03c8cd650331725aa4f08af84ec8f550f077825fa5204d84ef946720d7697b9dd1b441363e731f889401e59c0a1c32fca94bcaaf9d5aa90023b49e50ac579fd07571050ceea828829f53a5a339a242ae0c78131d3548b08f9f8dd51578b221fd5dcf5f97011fd565c019603e1a75304004cbc55ca14fd6e67c621a12964a41cadaa49aa21fe4b4a01392c9637aa1981074128f7f7abb214b3a28837a241d13900946b977cd06d78a05ff50eefd7fb8cf2139ca8331a9b7226f257e5d7026752b8958c08986022fc7b2dab5a7ff386ab747403e16b719e591c2421e3f9077a3daee16ae564a4f6c63dfe371e248eb66ea0be9b7a8cd2255424df18b5a558ed7f14b7712dffc4f4d62db1e1176fe92ec9e23aa0897fe84547eb9ed4c9cee64940519c9f530905cebbfe030e488fc0722c8fe019a337b6434f885877107f7f5feaa688dee8c700fafb785ebf422d826a084960d59106e02e5b6cee03af605d5c95c8535a291ac6c9d6d0e48f4b5201b70476c8d3a8eaa34bd2b3ac9b0e4784b7b4b8c4af20619b14bbb1f1f15aed8e5b26279c4483a17b281047d364f6fa39470315b44dc5d7812fad6538ed2e8ef07095d5a0113a593e7e505c52c470645eba88551907ad229e67ad36fcc1f05bca6cfc5884ae3b516b69c8d9e1756fb5e4e1d1f53164dc745fd651508e2ad2b85c662511bfea322e8ad6429bc6411a302c0f179d1b56871b2d1828427e674a39092e7c47867ea9de9fdf36c43de32efa891748553daedb2083801f5cf45182e8f0a1074c9acffe1f5fa7b3b9879d6395e78a71189bc1f7b8fc843e26be39ffab94e9a73fdbc91eb2139c03cae3d8ec211f86a3cfc380f894148e449c8d59547de46b8f6c5ebecddb856da9cdd995789776b71dd591546e19ddaabbcd51fe883e448caaae0825daa876cbfbf2fddb99d10167ab60a7e293c77dbbf2a64541b044d2f9825c244b985bc6c602dbd2e5c054da0c4846e9434dbc4b6dd80bb1a07a5a42f7ed13337ca1d7ed1bd8cd34d105d905c11f1ffff0105e3fc2dd0acc07651b30693cbc279f0f4c94fbcfff449c45d2a6141ab1bae31fdf133de7ffad84fc72a468555f070c20dddade6b7b2ce5e48d2c0fa5573cbf0f5da5773ad81fb4d2d98fac98fd70f7c429ff052ff6807e4ea1cbfeaf7482d995e532dcefaeaec2fa2c0bb0510750b1072abd5a70cb9c0d54d1c504adf22cb40bd4bc988505e9ebb446c1c7d0bb2791c2eccf5708b3e968675b5eac2db819f01dd87264dc72b622e3fa136e091d772e23e5dd02cc8491ac6c23fd5663a02a9b288d1c54141724dc4ca6ac748ae0a8a20d6a0d9332879a859568b822ee78269c58c689193ab85b10614fd065f2a0d3ed4860ee157939998830fb097ace46381b1afd9edf4aa72f3bd11932986344da88f0c03ca3ca80c9e88e42a0743013a8fe6b6a9e44ccce7823b39c0d82978448d7e5b93d9fdfdf9b5703b84890ad217456397eaba64ff78f13ebe67f1de4097af05e6d700db9d41a79f1357c36adb6ab875251b94ee5ae68e50bddfb84a782d60c783248c9298d72f3ccea157b6cfffe5a197359c7993ef3df3f2cd33afa6bb4d2977e81ab31c7cb6b63eedfcbe21a21096dba246b5bf143ed90e8b4dba6d1a3bb867104ed38beea5bc685df42ee317ce83bdcef7cff60411b0e6ed6050a6eb3581bd2cb442b0b5f9b489a4db0237199ac80d32a189045361fbd72278bb41e41709619721b88b215fee9f9bafb7cfcdd3e6b9f9aad898403f176686bc295c7abe2ef4d03f2fecf06d9adfba2e82af05ceb3ff8651c5da6ac37afa3f37acff6a5007a502b371585f7f6b58e7ff570eebcd770eebcd7febb0defc9f30ac37ff605007e5c6b09e15ea194afdfee6bf43bdf3cee1ef8be04714fe803f5db9d9b8c22e83dd9317af5f7c787182bec336a35c15552b53ed2ba118e34dcea5be1fb85fbe020cab29c0304f01c64f758fc61f54d71ae40a7e8c5ceba97142c1b893795f47af778ecf5993bae927570fbc2f739cc80e39c820ad6e18b57a281df3c84a960f76b53766dc4f951ee3a1078e6a827c4fddbdc3c83cf1e9177d1de1997ff8a8c5147e2b8c4bec021fa3f4db353ca6292c86cb84fec20364cdbcd742343243b25ad94c8e2a1f65ae01915ef7e0c7d5418cd4775698f7a4f5bb22382be4210a22cf0bd98a5271025563c5c4fe46c548d692d8997357ffddbcd75b6b638ee9b01f51878ce5edf6a10df64c380e9d6250b583bf4f46cca345e999e3fc4be2e43723a00b2000745da2ec0d259aec8659604058ad06bb8560ca3144bb3dd84da6fc567fb57ee6a84ae0beea87ca22c779112771a82632491081de300110b116505013816de8f27a6f75562ec1681ab4365fd51e8760b58629369e6a31d6a642183ef583408921676b2a8ab30a9420534ae9112aeac0621a2e910e98df0d2391b7bf8f4491b628bde3edb6fc3d56bfcff96a95ecedad6b20add5faa72c9c9d17f4ace843135688cc6dcc3dfbfb8fe47f1401c0a716562469901bf9bc211a70765d8a3999fb66d2de39e646507cc2bc8cf73fe701ce73d46ef80335482013c458dafeb3705514525084959b9fb987cf45167f91e5451873ea3ced67ea6ddd4e84d6dcea0c79bc5dcf4e09710546e8fe8fbdc7a47e957e464583e93dda0dc9036c1f2efb0e1bb2172336e0bddf8000fd7571ce86be6082fbd0ab2edda99953cd4cc3bcdd6e25c3200ff57d8f5260a55a3b9246c835052d6536174ed6d4374769400553223f12543ba2394911d25c411a3347b90def4a4ae708a5edc044c45ce8f16256b6c6470665eb5c1ba8967d14cfb2763b1034f79704925ae089bde2f6d328c9481a08c2c1acf21c5486a149c32a5303946d0c10e859e6847f3fa4ae305c6de0fc5d92819bb8dab2b609a3b2dbd823e25916f637a530eaf4464c5fc2880f1d7d3947126de8bb067494c8a96b5632358c27a68002f5271f45074f1c39bee1a613e1d741ea1b5b88337a9c05806c3d43d3ffbbcfd0f4fe199a0d6b1a53b2d31a01ad6efcb33c58e0da0b6e1a75bf5d41306bfbdb763c70b88154cd9c8d0807dc8390bcce95922f79ab4244c8437eabeb593075170fa76d52d4a5e7e25c59e928945dbd5c9bca2063a5277a9f258eb121a6717f4c1779300ea360bc4914648c44315656022634dd6ae9027c0b37ad72936d3630f26d3630e2d9362b18f97758511994dbca6e2db45a05e03575b51a499c84edf61b394c72c51c878e59c69b8d97e95c199bb889ef40418ce49282461bf954f5372d4a47ab95b1febe5a55797fcbee30419b24925a269272362a0d4950d02a5fad7ec55c05e1e4868ce468f5837f88c27b0d89e48d8644b66d6a8dc6439a62b71a0fb917c47b128370a3c641b9099663e623f1cd7c84d1b73bb5bd34a94d52ba21c6414721d13397134d3b2362662f1d134e8bff100c4e5bbd50fb33779711659f7673393140255a85c353a5ef17d1d0a831179212b72e37e4bf69b921f72e35c1f7af350e016c596dc2ff68b1f96f5d6a082c359b33dd21156799211bcb1171aabef997cbccff8fbd37e16e1b571684ff0aedd74721135896bc24b118442f6b277db374c74927b99627064988a24c918a486f6de9bf7f07851da41ce7f6bd6fe69b337dfac42208622914aa0a855a1a8d06c89fb964e6145dfe4b648643fc96609301916e476864d3adc57e8246051bf24f511cdde4fab77ec241b1b66173c7ca061b5bf62719a4dbc2cefe7d9776b542550d61b99c58b6ce029b4f9b06d0cbe58d83ddf8f160fff5bed8b46e41542fdb88eaa5435467c16054fcdf0921a0f72acf756689eca63c9c3a071f71e01016746dfe173cd74ca7b3a1247ddae9bce2016b36fa813ed440881a1d43eeabb63e8fa435ecba4ddf4ae6419b23ec918412c16f1c02b4449eb213183fea59ea0990c521c488f1120a277012e3c788093f61bab78c3c42a031e15ee3b0a1bd703233a5b10684b222109714439e7dc9296d14700f17910c69a07e763ae273c97cd9ba732f2ddb1151866ccd327ced28cdd082d68b2b1e79df72249a66f67dacd006506d3ec179ef18bf55fc1ab8d524f427add813305ec7df8c3b3b81b66920fa04ebb09a200443e38d9e736cbcbfcfb55f3abf42dbde509a11da1d8b3ba2e5728317a8643b84d5fa38c9aa97aa8a3f5ee27e10bef6dfa271a76f1e00d9a2ca0b69dd68a7f369e247502f0dae53e34d48f1e7d4174a959e081d41b55e4268137d0edcce0ed797121d83d3763e91de4df0ef403c212ab51a462a0ea5fba0e0fe26bd9a62361c265b88582ffa0264544421550edd7103ffb32c94bb86ea685109a6ca3bb5dd03c7d1bc68e56182623334bcbbf23ad959981813e020a62688631e64cbbe9f3066d6026570c1ff291843860de164066b240222e154023d0d03e5f115838db11c73c20608da43c32f2d56b04ec2f65424bd9bd620d6b773b14de3f482f0b0493f5e935111af88a9b9fb49246ee21fe844240206ff0761b98de3b1c53ae53c7e66198cad701b48f385b297c8e4c8a742e5d7d088456d0ab128086f4a6811b735e216b246e6a95a2dcb143677e4032e17b83732850c5eefc611beceaaa7243ebd208ba482342e8c6b2b7b1cf5785893452d32bfe4a4aa0709aa49960f62f8a31763d0830248504c9161f03d5e0dfcb46b748623947655fb5c016714a80e710fa570330b62226b9c6ddcaedd2d54921d632abe1077b9636bf5660d8e69314a0ab12c95932b1a83337c96cbeb056bdf269aab86d21936613b27c149a7bfdcb1358af7f72ce732be05e11be2b06032e05b4f3ac5eabd746ddfbdb593e54e075034d68996c0b7977fe2be524d08df5c62fbe69250131dd33797c0f59accad607ae79256ef5ca2bc7389f6ced50d18499c88eb99ab6e4e0deab14a3ab8bf62bc3f69a35cee361f15b0d161cee2169faae4d6e372011839da1cc40ae46c46d40afa148701c1b1dec4a821da805737dca6c4015ca0685267e6a4a1b21364deda41f070f5098aad00944198677e8436fa88825dbde9c6103849b5e50683e9f0695bb3323b9573a32163e5b4355ea5333f7dd748654c1facc8b54db821330359f1a1f7049dbf79f47599d27a020990e58cb51589709868fb5c5a28b4d1f7d5facb865f94d1b3c114233bf5959d304c86e975ef8ec21e37227f9afa8970386ecb686605ceb3812c3e30f6a21bec6937302f739437bda6136b842c2d8e709948b159b5f7d58e35b69889c1adeda2b84d506a8338035991a13243f30c7dcfc2515164d8b6a3d27ee80ed18b3919d9c72274f272795ffe0c4897ccd990c0bec3378c863479db932197f54d9c845b6c533a86b0710ba58b35a1b2e85cdc4ae76245e76293ce090a16abf7abd82573f24d68c07db50a4b0352c1353bfccd6dd8d957848e3e82e1cb9887ff6b5c50854e280c2eeac99020b1a28f59318734e563fc57e4a75c6f00bf12f6cdd1b1bd83cb39d7150cc6f85755fdd7b5d52b48b40dd521fdc9185d4354ac01dfec2bf635bc481a2f9a8de9a0ce83317ead7a7fddec5dd28b76edc6b85b16cff20c9202b5eaf8125dc14fbb6511b3dfb84a825599f068ffa03f41a722d90b20cec4cb0a6f0ca11492ee8454ef2f0ab64674515ff993a0d319b71572a41d1f4d8e0311e3e72aa742473e0109fd94359b42159406a9dbc829e348f172e9c7f87a15a0f8e8f418f3682d6c8b8c361352a474519e55f9d521ad5f17055dbcfaf8f60d8063c2e62f051e5d529dcde70b5a55a0f728ea17490687f4cf6451c800de56bd57a0cac8caa251839cd5e5cb323eab64917f4e9a501892e5d2678b170c7c82090458e2599726fce81068f80a44cf717234390ee5f9713c64e01968efb8d6058003a250786ce05cea3bd2c0053d4fe7c48916077fb0d102f8e532ef74f2b6f2f60551cde541cb579d4e7a747abc81717e747a6cade9a8804658b9b84162ef14d018dde6c08a032697e43f5a79ee399ee37c9877bf7d9bd4b35c408e1d9887a95326a0d5e9b0d377cedd5ead25ca836060a211349f62cc20dc16f53d6798d1cc8899c37ceca6217a55ce9aff77e1643b02fa6a928bc487db34b25c8a297020b7a0661e04abb8010f8547208463c26505d31283da56217b2b46f4bf37897e701d7399c3d5641b697a1659c374951f9214759f6449c2566500d684eca4a359b129229aa1d7cd20e33176e2ac2b419737078d0c6cf9c0a6da7199e7645ed10424566710892b832b2e6e0e2271256e3188641819316258c3d6a8f86f6b6883c49664ac64ae371e1d4315585a9b07ef88785af7c5df7d19864c86d9128106e1cf43512a3e92b1b8f606a6c828a29989a237e27e37e8749e8f7d1ef951a6e093baff891f1859e263eb6e397654d83c69afb880715f366af3a389730ed2f2eb72b9f1790201ad1b572d65e647e668f70729e86663dc12b38b8a0beee69964c3b2f599f3e5a1a0b444d2c64a1a7eb99656813a8c6fd891dd8d16dd74fdf783201c15665028e2c613cbc63e4c3ab8b62f57d424a455a52da625476f93631c85c9d1bbe4188fc3c621351b2fc88cb21d22c42c715f2f9fe92c820df4d21f6de62549469b2ac4a0dc67e759424bfd05394b32f6c8550dbd903c22b19915fca54fe22372dc68a62acf1631155d51069b96beb259aa7bca662435869e67c569f3f31b063e2e1733f1c18256b4d61f5467d12cab5b3e4928dbd995f8aa2ed314486e639842b47d1241644368332bce499e89712c983837da2c8b6713c62d75903b577c4dbadf2e16ec34b2901a87eb0b52bd3dcbeb6c9ed3c1c6c6b83b130fab9fefc6106c7fe343456e1ba8d906134685eda81242e114a004d186c899062a17ed517a1c3a6c3b1db605999c0c932e1ba060bd828f127c647e8d26c78c4d3763514e3a1df773e0ea6d6df017c7c1a0c9a453252b4f8049c7280d56cd5d24d6fb3262a7f417004ab8225c076d5ef10dfcdbbef0eeb167fdf902b79e2f0a3fb10e1031264e38b1d8501737583d10b1141fc0d153f979c483b80bf9719e8bf88d21c1187fe739ddde453e0d0251c256345e64736efa43873ec1699787fa10311ffdd166929d8f361949cda49088479b8ff8778f47a3cbdd785b3e6c22aeca9b95e7941fcb89e98301a25a33007e37ab86cd8e29baceaa017bb902f1aaf13e407a21d8e8e1c688a0446db561aa7ee28d1ef0f6bfa016fcc0fc39088241a3f177873c452311849900614ec28233998d3e5ce31a141e9330c5f3044ca3ff2de47b5490209cc8d8b1b720e213dc0b2706119f48223e39466d4db512f2b68a3f49cc8945ccdb1a6c21e8c421e86d9fad21eaad43d6841d22eb4ef05fe2974d37c98f69afdad913fc6b6444ee6d5002e2b000870124060398acd369fcf4e86ccec07df9c3097efdd3b395146b8213ce372681b0529e00e31833a60161964f5dda3b0ee4a1fbf468cc98863e298f87b3c427088e68379d37c7ede74d75ecfa2382561a07c9712b47ca876e862f88e30bbff2a0d3f910c93135f9512e5effd4d172fcc3a3e5b8a9ee18b79e36c7dc11501e36633496461479a7f385f8048d518ed2e066ee4680bb119400991a1537f03702fc8dacc37ade77c263d5773a9062eb495d2fb2e8aca6fe6813ca256f5e44bea819acdf259a221b7b228c651f82dbc5c3576c02661d6ebfa4462430f64f3eb0666dbb86c1e66f66ce1343b7472cd6fc32118e2f0d2e5c5829f79a678d55e308777f908dfdd663cc77ce619ace2ceac0d2a634498c1c603f3ac0344e59ce19060e3043df3e2a260df3e398b346c4e50e0072bb3e022278f93f125102c1803fd24b0815ed2781eac2e4b3710b34fbbb8357fe5b6ed0d688f073638c62f7a63d4651a8fc9d9230c11b7d9dd2706d58646d6304b01bf88d44964865fca528563a09ba5c42557e11212f5e6445112dc6705256516286be9dbd8f226afa3a8f83817f437abf51e1d4e707796a3a5707fcb229ee743612714dadef572d0fa78d3688dc64b9058da99bf34e3f080ed9f6cb3a1dff109f651ad179f172c9fe9e65c1213ecfe09eed2253ba868f9d8e7f99f91fd1a7005db1bf175900164bf17299388ab4b081377b9696c4d54af47bf275993a6f1efc5803d33fb80127a57ecaba0ea4ede69c639c68bb08e36338c1d16091f99cca2ba86d70a8dd6064302ad81e00b6eedeb78de12a7832f1c796e75870edda32e87e6ddfb1d0405f47b1891cc2a0d4740672c25726e6f2fb6f0b7fcdfa209c24ee2c9230a03841631c9b58ddc13b4dbc47b4d11da2666f050f4f4f9dab7fa008fe1a73a4663ca9b1b28d123dd806d24ea1bebd46b4115b1a51fb865a9a0fb40e85b495a251d11860c3f951d97229db2e7bc82e877247ef52407a83bfe1d8b9666f9b22887ba0a375438fb971b6103f718a1023e3aef98854bcf66a30eeea87959d9af4b5ff1619246ab9d33423c6637d4dab74893400e318d83f486f1e1e81dcdc3f889d4851ecc0c13ae95b4a0077ef20beff7a2add0fb7536262a654e9abc2b78c6c7736c61a83756ec151b1766ba93811309a06bb2854d8ed9dbbbf8cfd602b6931df7a9c38a65a9d4eff51439121c121690a6af0e556730a1c6ff5833031cdca86be5a958699cd1804113e4305e9a1be9a180f544dc46be1b1256c6c48800ec1e0a83935df2dc20c30f7f67bbd00c5a23e32c0846394089b36c5fdcd15b0e39eb6c1173a70ac855064587b3344a6c388a1f020eaf403148b5c87ae75c97dc450a126a9953ce02fb0916fcda8f2c62726eb532129d4baaa1dd3d9eb1ddc1f9a1c08479dadbddec183e5fd3d44cc2c8dbb03c68ac357fe3fd83fbf05a1dda212e7408873b343ef0741d8de898a6926ef1ba4e30544d5b00449f186f16e64758e7e661efd03aba17522c71a61438ec90ebcc2af1c8c30bd99958882ab1208e27a9d4184aa9ac4a783ef911fa9f07e4fb3353e789f29393da4f550fc1d1cd25adf223e739cdc790f48dc70c4a78a8f6b231bb894fb0e49340df5e53c12210c0248b3619ef7989cd2c72a78ca3c92d8059190e2b2a8ca9c7641c7c4e6c36319d2e0baa2b00fcab3da8cb6c4318386abc080d773310dd6a0c8e8da6062517b1e7af0d530ddc88a19f75d15038983eb17dcb0d2e8efa5e55f62a7978f821ba2d2c20045f0d946fb3c61941d55d6b8a4fcd5bef1356f239d6b47791bb9b3339096477c63dbccaab3b37f5f5fede9982bcef1b425088c79ff15f1549d6d8e54be9b019a4bd4c3d8f05f8d031e37e2dbb7052571fdba003e96b73587a395399ddd81d8f1e2d82d36a12dc6bbc4f0feae9383fd95802ac35a53d68dcc64ba4e7c6b6bb5e5dec1918c78ce64029f9ba69140c7108000eb222eb3fa25e33aab0368d2e9240cf944a46b11ab3e86aecc18c3ffa3c3e6e77763d4370cd180ed6fea5a5de502be0dcebecefc5d144bb14ce22ec18619201c600d4cde0bcc1c38a4e997ed8b53949c515b66f2a173d465581acb64d1765ca590b4f82836f304a05be175b08a70dc76d08a3a9d67a91f4320bed0467df70b6b69c5ada091494a5846aa65e06a0933da199195ccadadf57cfdb60a2b353ab9314785d19c6e48ae0c7845e845eb745e263aadbb0de14e8774c7657c56f9f6d4ef5b246dcf26700ebddb1d28db4dc78c1ef26a350cbe65c22d7b0d8b1bb371f1377fc68c1f060ece1e2862c4515ba0fc4effb6c4e91f6a03b533943759a7f326f3a3a0cd44c5dd607b8d8d461ce26199614040b4e69181042aec35271c3cb0753c3c783088ddc0d6042732d50a04f3d251e9755c5965bfcac501c57827c018533409562a5297203504ec5e57c1ca42d0971937343199533bd8e25696dfe93ccf44b27bddecbe68d628da1bbc95cb6251bb77965060e4379276c0b0298969a4effaec88c246ca29d23c33876ed49b9034b41d2171b51da16de9ed8ec22ad48a59cb5aacd379c720a259d1fbccc831bb8f55b4ba5dfd734ffe34e1f53b7c2792806a59ca8cc02792e6bdcfc0ee46c61c5441de74d2377723f5d8468a2c1ad4c282788c47d0041bebcb88abe3c01b4268200b076eac23a57b775890becd2481fdfb9d8eff21f2796e7d76dc33dd6cfb0f82900c22b8038e31094391f2b8b89d9dfafb4cb90404329cb502dead0cd679c7ba9f7d6d737f5fffec3f94bff940cc49ec04d2e2de8bcc84d7929970dce08b62d4e4b6ae8e193f5266fc2bc8e166f7c323dc39cccb23ab5532fc03046c1405830ff29789887f38d67f80a9886286cb09f74ae011d50282e9d0d8180333346056543529628aa2e143e742c44893c9aad18560ff20c20de29632df69c267b8ac5b4191fb4d1c040356094596e70409b8f52417423e942528cb00670deea589b1d22d47f27e0c6cfc8cbb32db0123117c42fbf77316c1104781d5720e2d94c75beb7b735d3efcbbd7a50dd2b103af5b4fefc30fa6d7fadeca6fa1a6a74d622344f1461f8d511af2bdb40169cd12e52807b420b4367cf3329051bf31a64de2472de2972ac227b527bb83b19b44394c155993b5f67e506b45b1744f5e51bcd15b092f9f447bf908d9934f879ba511748a1394e318cdf069183281fe1f993f4133238dfa8caf44a7b3070fac8d994d246668266ba96b9319a4916ef3689cb552d099a2a033ede9a31b98a90aab994b39e51ba824d73c1dfa133c2ac66c82c6bd2bdbe213bdc527269530cdac4e83c1c4290840c1ad4b8c6603959b754fc3d9c886227da4c6786d266dbe98890dd80492ea394e54aa2f1054c13ad7ede736cd64633f59e38b95b4ae50a2562869f1c54af47e311287fb14e27025ee92a9bac6258125d71dde5eefd214b15fb1b36ce49e65cd2719683ab24fb7c256c208ff615fc9b425cde4a7d60414349649b2a521688a975686c658d8c329ab137e173cda5c10b048e310bd9a53a93a4a20e973a7f334e20e52f3841bd845187e258170b9ed85f4d1589ab0d17b78474afee3237a8c26eccfbdbe6d64940e67891fa3c98f8c8cd2e11f91ace7d8b57e102fbe103f46299a30deefe4c6d6f635cfc414381e8ac3ac6556f30fab866b02c3b8b4652ad6352cc5d00def2c8b1944a4c58cd84d64f88a756bd7018b9968035b9f2a1f27db44a6e5fba60dcda0ad92b2b73c3a1e301195f51aac562bfb487e3b23fb9dc0b2abd4c6250da37957d761e91bbbe2fc0d574de237639a7fc6be1b77c7d9770df5402c5c6571330ac6a860e782819ff0cb3c79e3f431837b19f3063d565efd71a85d5af98dcad80c3f8492a10f778b0cbfd7c4181b772b5a4b93b1a1f504e6ba90c61e8cb28ab2e0d659d96c5e2e6a0249ec076399ea1ecb1ac1c0b747415d15af1810d5c95ed4de66bfa86bc8668c231852d9218f2b2166a7469127d6b0a9213fde575022ad48910c19c20d5cbf5715f96057df29146ba22514ad91890c150ee3838e914e383623248c8ab1e653ff86c80a710b8ffb89b80af1bf1e57e113e8311cfd544be1cd9a739d1cc0d276ac574536b98dd40635d4835cc366291ee885f7346354635c2e5e90d8c8bb1149cef8676664b780006a314358ee9e14774992f85180a26e3da1859fa0240856ead2ecf34d97666fc97c28fe0ede92b9be34fb92e9145117a9afa3dcd424c5bb213ba85de52549f0b5d0321be9cf127539167763613765ba817fcd964bff6bc688ce3f339c04a1b8a15be948376694839b47a28e4d5773ba36acdbfa78e82a35a51eb29c99316231401510c9a7c16a255dd6ed3596d6b2ed84cf54a83f23753ce13e6b2d406af7ed4e8c8866d3219902f61cd2da3faa2759751c0cc814b0813d05480c5bc6f091f79dec657324be8000ba56af0ee10a56db1a00775c05abc05c28d81e53fc96d4936e4cb31cc55337feff7391db8a2e50d278c99303fc897b884ef143349ee2fe7d944ef1ee0eaa33dc439329eea36c8a77d0598677d17986f7d0748af7d167fc27fac84d06bef03f9f700f1de23a43a7535e904fb191d279663d15a2ce05eba49c32eefa91fd9c4ff17eaf87bef2b70c4dfb0c4df9d613df7c87ea0bf1544df1410fd5e2e96c8a7be85c363ec53dbda97e4d550a1fff73c71f4f97e934083630fe73a806d6dff219f3ddeef796bd6000f682d3e1c57470610cdeaa635df4a572af4422989e0e2fd3d95176a31a0aa191dd51d7d416a60707e087aa3fd029b277d807fee7ce780a33905f7cb2a5063c61438abb35bfe57e5b2d7bcbe5fe8b5db4b3df0bac90368990540f0e06c45827530a3d7838100df6f77ba8dfb35d9f0ec415c4c17d594bf563d6da1f10bc73a30e7377e73e630385b2d1644ced53a7b3b5455a9378be4e55a6d6fddea3b3a9100a2d44502c869b79e0cb29a7289691a2e01a6c3134007802e2cf1dcae1dce918a88319ea5c4d7d120cfc7ffa24409f315449533f0806ac24f43f77f6a0de7279f090abc20e0eb81a4c52927a3aac3925794be6fe11a4663a066ba37aca482a6bd8d7292096cbf87114743af594496e9cc2d8b7046272ffc331c624271061c6ec731fb7efd0b1a7a845b879407e29ae700bcceb1827c68092d6883811584db5197745813587751fb7c7e58bcc809052e6e2c317da0e8a1b97982bad135869c9d6ff287ccb9e8215f021c6f83ceb742e339fa24f01981d53e011d2b0c74aab3a350520b8676103a509040d12e64c2a93700476127041f33bbf8091d5369e708cd035e58ab3367fcf8a5434292fc1fe5194178568e40d3da7794870fc980ce381da823b8f21ee10a8077a036b43fe53e424eae9f45a7ad80151fcd681bac11c749ddf1759b9c8ea2b7c70609482e44653ff6a6a0a668171011f61001ed8489a5f852abb8f71e7ea34cc5b5b37cc5eebe87ad6e5ffaf2d3424c10707833efbb95ceec8927d76faebf7eefa067389822da7240950827b8f71323c3818ececf35f0f07fbf2e783c1c1be7d5c14525573a490cb76ddd4e0ea8d3e5696e561cc08f0b8d3f9c7d88f83d5daef464514b600250923ec00a165cd0649ea27e8a95d8aae05c71a3481c378ef2a089d458b56160d7c2a68204800904f4c19ad4272e267fc3dfaa73297e35b02b0466e2d60e44dfc718407371dd5ce8320089f4f7dee25fbb1d38919ff5a2e5f4c79f03cbd4e5fe401e373f87989c75311b1e025fb3629bd7a7175fd2bfbcde98bbab37ec51a9a04e2a6ba1f840543b7cf3809e3a932ed8291327233910c31c2a7532406812eb941189f7f6490bb2fd28283023129b26a4293cfe5e2940182b76d5835e82aae712d4af0a1940fa56c51675c44984c5d96bfc7d832bccba603589b9d47f1706760df949f6503316e8818cb28cb2164354c04fd1a153116572aed740cbf9e82ff323bdc9b98994f417bfb31bb379f0282a17eef110d808c95531d1fcba19782988c97cbf163862d6e051c8772d5f91aaec636868d3b1d91cb0766294a934e27e1e8d768309171f3a448c7d35ce25789ff9bb385a8ecf4b7a9e3a177fe2338de1e8a25079c3b4ed4e30e4a9481e51670a1365868a7437f0a2ca34202462feb06c6b3e9b0415e67534e42060e020c13dc6ba1c6f934d86282ac349676dfc7c1164509a65b09ea3d4ec072b5c7c8b5dfdfe93d4e86fd9dde60ef21fbb5f7b037e8f7e027fb33e81ff00a073bbdc1ee8bddc7c970f7c5ee606f174ad99f41ffe07eef6e34f5936df62b08b612143f4a44c41a81c38f4037f4435c48d6e2c2743ab036c306df0c824215d3e07a8cf3a988185f4cc304a7dde8acba7a9b15cfcff88667a78a10381180908a1acf694eaed83b3406d86df90ee8c6c1969f368e260183def811a6c3de80de4bb6c6c64c25d6ba331e1537cdd99af4ba33c7013b73fc53e0a0c35b0c21cbe1532bd3c2dfe43f57378a6e11386b45c3c840c27f85b3440667895a384b6c7196c4e22cff70390b159c8536394b6c7296a4c15962c55922c15924678dad313926f760abf2632613ae653251c8194cc81798f568ad875a8d3753dfbca1aca7d276ac9e864271c07a7115800cd7ae9f4dfd1841eb31133bd8d9ce9234de4e4dfb7680771feccce459152c99441edecf38360f8986b5ed3bb7990ededa618dd1e9ed5b3386f5421d022df82a33ae5680f6d4c1c0da5fe1565f49caf6c6dbeaa3d7891f0736ee719b9e2f8ea5551c2a6b5f692c90583e2189b8f5e367b2673ac550a5ce85862149223c472cb32ad7ffc3b4b24b274e20963d5eddb4f013aec066d141b3a83728533f094c03a78f98845f20d2a9729ee18ad24f380a0f719d85422916cea6d8d28b854213165e64b8178226ccd22989754c4a703d800d39d5c9362ac8963be3d11cf9e2bd6b09df6d839fa7cf3780ea27d2664f784c2ac3eb7c827be1eff83d7e27460fa9730d7151b923cbe59694f2104fa6e8748a23a11e0cc9409e4ad058d54629fe8226989d5d3f85a915adbdb7f7304c2d83c3b4616ba8b10e02f43513514dd6298327a0ade72039c513a57e4b959fb2084b911a94281ffaa975db905b0e78a9636b9937723a396a93dc2908064efb3cf674a36158a415cfcfd7708846733c9626b1976c5e97182eb2e67cb3b1e2bff0bcddad7803e3bf824b79f1ff97718d35dce80d36fafa901b13a30d7e6d76a93391c744b9b50f37fa03f0f28ec90d8eddacf919afba5ab131f3813ec7f3b68b1f8cf1735ea1962af8b006cdfb69105a5fe09a5fa93d976fe53acff53acf1de7e4d4b290dc39780808df8754ad0c847a10066e0429cfc2fa4083e80a5fa4bea9f286ad7505f576c2cbd44fd155b06a2085411a44ec0d8fac26d28b2315f9759e60da9d6745fa8cc41375bdf564e85be5009ccf199a4828a127a0343c45932018f813fc04148ca701522b37e974fcd6ea3c35d0042ebed220b89e004453aef8fb8edf9b821145a7280dc2537e23f61d7d0f561690f77a07f7c3794389a8acbbe6782e092b17450442ce837082b9fce0cf23263c5ecd7936b7271e5c6a78eaf264b419dc1b6d7a953cd778d090a79c2091179dd55e517a124fbd4fafbd0b5279d59cc6d938a34977342a46a3e2499278c47b7428d2e7abfab8dbed3ed6fd79932c9dd08597155e3da15ebda0d4ab4b6fbe28cfb3847ac4cb4bc208ac9715491693ba5c78e5c29be724a693324fe882d516b7d8ddd1e6bdef1183f2ea7003e351319d4278836ccae6ff24f3270cba629b0b563a3758e9ee8051b45b411cfcfaf097cc9fa35326425ea5fe1c3d0d6c6bbc3eb4c7aa5e302a7235a7e82cc273db9a48ec2a2bfc40a7b3e6deef62ed5da1320f3d8bd691eeb3a8f5224f5dcc2d971b640a787a160581bbc16f82c479847fb141711ee98cdf37a0e5ea0bfe7dea7f918e055f4073f425d677f35cd09672b5c9e0994c2ea4512d649bf2763531634f40e4806a3220862ba7b800218fd8c96de711e974fc7c8a496018d4934733f56e36c50415536c5ad83f4dc152fef145d6e9f8171926c63b7652b836d5f35fc2e00bfe03e6ab2fd71a953a9d8d4f4c406bd6fdc3381c7d989ac97511419f8286b780ed5160b8faf811033b098230995a4e8dca7bd8f206806ebf6022b96384bf98c70c2db14a74fe629a7ff7f61e066c59abcc8fd017364ec1153e2d974c3efed276976006a7efa14456322f3ab8509434c210e0d69b8d903ee6460c3408c7e227042ad79685ad03c1f1cab49a503701850ef4819d401f3063636399b2189c054cd9ec8bf9a46c34bfd8c13994558b556a3e9a91029c262d4f13b3e100f51f992ba5fa1915e637c3b5fd0c9ca9385d0522526284ffcafc2f561a052314901127a4b7f7004576aa24b3fd86cb0c22aee01bac186e1a29b19a0bf705139b0a7d09422314ce741a84ad67e1d79666c2494441da437ea8edf4980c2393f4fc6636c68e2671ea1f1ca0c3a96330638fc5b47c55c71b0f141bd68c16d3e0b65a11796e350fbbe057dc7ed23504493babc64f1e97458a0775e8730d121f3c081a3715a2cd75d74b6d372907acb45d15db139706afa77e1c84cdfb3f4cc3e4519b927728ea5a856d15d7dd09e2de005a6eb6a231de6e6854241073e351435faca880a1d3ed19350de5992618ba8cd5152a31ff0bfea8cc5182b0ffc870e119caa3b04915fc780d598811c5b145820614c703a7d0d89c2a8f062881d26983293d4ff03811aad4cb84db7c5c25204df3c86c60e49b950544e8186d427200eeba705db1a241dab5eb205a2466e18b2259f1eb7432b89e607f825327505aa7335166b919bd582e2fb222292f64b846f0b397adb1bae6331ff1298f0975da5d9022a5cfcab3a20eae27f8b44b8a78522e401e14111d45d1fbf1b8a2351a15337cca3d6ea1d2a97ce2ef41cda5bd15d04cfd1452d545c4fa294c1733d6cf1cf7d025deeaa3bfd83f31c13df41cf7508d5374256a2b9716c98c9fb0078836cc238ae59dceee06c6b5ea72b9f42ff1fc5e1e84acd68cd73a6da9f5179edf3b0d4276c0d6e59d8e3fbf279ec1d254d8a49b7605fe135c5bd16db986e90ad7618d9fac0c279c9a9d34855566145ef143dabd7b31c3f8bcd361030da078c68a9f6318281b98c9aaa03b86dd879ca9c8fe6a7cc5fa343c4356acfb09de62a2cde572097fff12b19338165e02dafd257c33f892ac260c96a2420f2af454059142eb4582af495c67e73250ee735ab363aac8530ab84013f66e902285d31f189a0d26ab700c6e945f1945e32aec8f53e5ca7b119986ad5f5d1eb1db0b82f045e67f451751107ec55f8d8d6e73d1af81d9035b851413d050c90a4264fb8ebf1ab165be839fe587c8ff6a9841f3cc1cd9d8ffdee9ef3ce49f3dc55f5b33653de5af2ff05308f6214a2fd69fa086173cc8c7e0c22232c14afa1e7ceff47bbb0f553281df339fcdcdd26d58e65df7d75439cc7c63c8e8aba30bddd91bd85ff47b3bfb4e9587769551c12bddd8f2dee0c6d70f0739fe8ade667e8a723409d0bbcccf8395b3b2ff01e4b8c02f92f02927dfdff145d740da70822fba36dab2057eba81f1f74e87fd6fd3e24ee722f19db26e227e881d82be072abfd8a4d3b94afcef4c247f8a275dd86ae8024fbab448b40287a1cc057eaac35b5bfce4fbd0ffeef010fc147db7380837269d65857f81be73ab5449bf82817f81fda7d819f5729968fef2b48dbfa00b87b38c0aff025f38ec05e5f8bb19cf5d748b523d2439ef3c4013ad6f04180cd381518d01250fd0c645975ed6b4483a9df4f1849d8cf1044d708a529cb3fece13ff3b4a0334e3bf2601ca3b9d59a7e3b323dd85c1e396cb0b83c3319e01e45d17732e062f4af8c95e296e07de84f20383eb4139afcf17f6a9088502f8e307e869b7a2352c94cf7b44b2fd005d0817bd27790ed52b3f40e9e3c9d0bfe89224e12d3c65d538087c3e02a43a0c063e34ffa2e51db2da80ffc2a7f8e818fc0a2ef0f7902d9fe61a61c0f8c485c1029ff29c35ca42fd02e5745c0f2eba55bc28f3fc0d1d3391a02ee7aae863395f056b022a7ce740639b48c6ec6003f98e7be1f7474fa5cfd7f77bf7820bfcf4e8fb319b34efd8e80f5f74d9181aef3e96737cd1adcbf98af1988de7096355cf550405495f6397357cd7b96a255b388b2cbe70167576ef773abf65fe77e410b36cec9f459c313c55317ab812eaab13f0e95c5c0c7e89f1d7a6cbed57cbe5f629fe123b77ddac68d50ed6f368781ef94f83c1b98e0af574f53f4047bf4aa1e0cf315c318fb9ac60029b31ce69a08cbd09aaa638d2c6a25f3135801f59dda1af8d489d5ff11a03c99ed02509ebf286e11e13b3cea7c3b3e9bd7b035f5a159360c07eae41d64fd34ee7d3d44c2a88127e3fcd26f5351390e3d6ed04ff33d326eee2c04b6db36e80549afa6bcef41f5de59bc4466221230fe5dad9d9bf1f743abf36b82b570075f6fb3bc172f97dba5cfa0cf63d94a4fec10333ee0a9cd4cd81048de536cff8cfc5edfb01ebbf5277ef070f1e55d3e1c18341350dc1865fb935a43e417f4ecddbf13f8d0b7c0c8a015e77a31ff2c616d350f803dc4263b0db0f64c4417954e3de75dafac03ce115cae11eae6085aa41851334634430d8053f1589ea55e6efa33840aff95fb9d5acb44264dd4e238827fd30201f1217f34382e3d5671c99f8b3d13317e8f354fb2d3cc9fc1845411861e183a47743105e724db334a0375f696d179861683b844c59e76bf36fe8105a52bb592a709a3603e24b01cecf608e81226539267df5741579cb6d5d4fac0bd373a3e3d272b92e85e32d2f20922008ae09032a04d822f8970c86ef00150c4c6206d4b80da83103aab62134cc0ecc557c3f756359d8f783c282ae9bd09cd6d48f82f023f7bbfe0419d7b869ba8c97dde934ec23c186eb63f6683e1d8271c9a7605032fa3078c24df9401ddf3404e4f70fd123482bd8b0030433a1c0c0973fad70912dee5d60cfafe710e19ea2e0c2b637c2af7816f682e777d4ee1e0e92b23e3e4cc351f161ea24c8d33ef1b4556fa81d46a89bc90dccc7acfb0b9e42e21f4a47b880e007327444f2280eae171028a3c5fd7f773001ffc92f8ea5cafe600c49cf20dc22dc64ef753ac24a87767910dfb571eadbe3e1f26cc97644362342f9afe34690aa64e25be1f51dd768c766a6116140b8fcc9ec66dd6f22795cf8da9fa6883d7380810625089d023b6b4b7f77606637b68c1b783a35ee3fdba6dc869841d2c0f4b156084fa5eba31bd099619dcafe1cda317ea3a1ca66c87d329bdf5ac64549fb6a3ce6f24f6b8677c01a394895923e748222af6823767ca1dd52a89b3e9fead486ce7cf9c5bf156d5e5ad92920ac008185be87237303eb7aed490e131949c2ba2fb1038fa1a85960de9804108fc2da86143f1bfb11fa4dcfe27bca43af515c4ef8cdc4a888508208a20df0f539cb68da13596eebedcc418256daaa618c69f7975ff8dbe03ae27622615bb6f1359133de303e2274cb1bbd10762207f59843bad9121b20df9886c99c28198abf3c62e759ea0befad14276d9c90c3b37dae69a7f392813541296361324afb02ff965af9ad28dbbd5694ca97594417380adff1cfb92d384e33be32ac68a387c646cc5a06b51efa20df4358d74885ee57d7627c5fdd1f90c135db004610ce7508266cac7e1ec5cac8a7fc121860fb8d4df7ac12b21accb73acbeb9062fd9ba33aa6e118f3197d99b23608ce529f32088a2d3256726384934ccf599bcc6bdb8c088f6faec1aafc73726395bd418489d10a1b0e37f4200104dd511a774712eddd4742cf19842b7b11544c6ab9c391cb2b91b342e0ec4a0759ea27880628e1a42de1fbd38a6bf32fb739b6da14e15724934dda83553229499939ba99f5771eee04fc4b87fcb8c457efcb21ed9a5efbe1b990aaffe25b0116216ec9fd21bf0a4530231a30a90099bc480a15d48c6722239804bf4ff06f89bf96619bb711e8fd042285fd3161140722a071abdeaf6c90304488c52483dec7611c06c649089ba7a2addd65bfb7b36725d9855dfd412c461c202ee0c8fdeca0920ab90e428fcaa0d1e97c82e7f5c8305e1fc3489a5662616fbca005fa35012c198a74be850a28002fc68dec4dfdfb01a2c2de7dad1836f46f2d8045321d07074c6ad1b80045767c5acf8543d1128a5e0b317604f91fc86ec8c5689db6442ef9170b1306c65a4aa22cc9cfdfdcb3ff9c34e8804aa1c37b759a7387f0d0accd98be5d5faf7f63ec3b37f573c3773dc67f928660db382ca48db844634c855ccc2f7e5b65e3892b1b3b05d8541e82c1ea04a722bec418ff42fd091a07c3de605d548eeeb798e4f1594e6aca53fd254fb3ba1aae2987d60c4f9660d903ffaf3148aaa902130842f2a1d3d9d027a26b938629733ba51b98a8d848fa26c49fc85034fa5c3709953db715cdd600c6a8380dae533c11ab25350f393eb512bdc81673ae7fc8555e6b382480549e77cba8a28b730e83ce3808aefb7013c143c1e546b41494739b5f7499f2d4eee1c4f5aa8f61466e3eb120ccf1a4e9969f773aaee53834e016b206e6a9821403ee69db776e2156ba861ce7dc0f802f468afb3d39c7e184cb322ae43e904c0158f9d74243153c68a2d53e299ec85989d84429b85b5d9bc9de570c7b9bc65093e05a21816c3b640df28f5255b89ae05191aef81ea6e6b65dcb7154060e793a456397682578ac9b12870b4471c524b9b1367537b104d204f934b065cb3e5a4b3bf75a8601a2a23d9640148b2a0122329df9984b6f52eb2835ac99206722f2bc3d2ffdc183bf4bbaffce990e89931262c79fa14ff0460fc1d1271810bcd157207fc3c5261a20719680a3813c49f033de468f4bbd4e7a1575786e4968a3d2d90021fe240289bcc9443a6ca9affa3a15d10e469b674542c759411393967efbf6e1c593671fbf3d7ff1e7c7f7efdf1c7efbf5cdfba74fde7c7bf5fefd3fbe7db3d5d811beb936d7f664d5f3ac62a8952c971b51b73a9bcfcb455dc1814ab6d70bb5a63aea66053bc6fa24083f998a2e99cca42c9e95b35956430b1fcab20615a5c8a27a7f8f9b854ac5b8ad8ad0ae83ab55f826fb51e332f3498c88f5a9567aafdaf4d3ff149a4d9404d7103d89e105e181944ee9158ef94f99c68807580219057e0a12c1eba823296f88a12cfc32711856184ab322a197b8178a76c6c62b2bc879c4cbac10ea50629fcca1c8f24e31eb18a1d179391b66c27f6bc15a0cc630218567d3c0140adc5b000d1547ece4edbbba1a28b537a856d21e4ef4824859945e98eb642e5fc4a3b063d29d2fcaba04658f58667f832c971ba49b553c2695d4aa1b0ae12f7a83b5c92a446939592fc3fea067c5fe2766f6193604a9880945b4bc5499d4f6fbb26caacbf6245fd8b1ac56535b496d736850a7fb313e1449af2021eb29bd4204961442b01bd846cc27c46f24444435149b39c28ddb4423b30426c824ad7130f0630739cd98efb887e2c6dd68dccc6218bb46ca41d81e2ca7dd60b81121a8616a1cdb1902c3f8e60c81617c7386c0305e9f2110ee7d2d81306ecd1018b56708748f6f6854583902a3b5390223334760a813ade9708cb1203184ff0d63a0323ce1535b38be4fa9dc628cb9cbf0b63b61c22f24d7ed11d81c90e1beafa363b665bf26418af7a505a913c49644926f7e4e65e42426fb30292312bc751c0d52fc30a44bfcc0547447aad8ca8310ab1609db2dfd1d1433a965f93040d6aec031db42b5fad5488f29f45813a7bd5dde5e203f9e444ebb939b5acb9cd60e746b661bd99a36a4f5c51a4db24999548a3cad268611240c6ca3a2ef4447a7acf8c02e4b5959df09b63e85c23dbbf0140aef8789654acbdfe5ecddcece1a6d5f7fb727d400644806721e4afd173128a50248a12d1612a9fa4c9a170363edada3afa453cd6100fa0f104109dc3d370e2b3a2a9c36885091f8e0e3fbe232f047df1b1bed4f2396dfe1c4df53a2acc2fba1fe39383a16243e0a9af38b2d55f8b5a56819105bf18204e57e265b866167b3398725343a205dbb60d5eaee444ee50c94cc24c414cb285d84a334c620452bed466a0a3c7264c6d76bdd23acb7daa1828fc709246049558296623538f6a0bf95219985e0d774afb08a4d370a2d3b19de03aad0b899563254d3ef4155b7bd1bb418b6aedc74cbb004dc27535b9e68b61292d6403d62dd7be25efc3177f5c3c646bacc7ed4345a130348840b6c9911bf774e1e47cb25387b076d5e235118dddacf23babd9f8715644566a87bdc34ebd26337a11e999e420d18f764f6dcc738fe77b8c7448fdb3e501373e075af1f203693d6d66e08c61499e613cf1c4c6a0b1aa8a34836016c5190e854136169eb20a35b8cb9ad458a9fa7dd4af8468763fc2af5c788a2340809637c314f99d372f5174603b8c78efd38e0f130fb32c54fc389aa27ccb52638363c9e27b69904b7883694d9f4b20ea5d3844e4ef9c6e77aab20b8b63f71b2e8bd15c2e55bba48294fddf2cc6e74b5620db4f9034f82d09d02a4656a9a299d8abc80fc96f714320cbd1cfb313a451343131ae30957c0c5f8c958879317b31caa5f381e442e098dc3085fb05549196b6ac48d26ab30d176d4a322e13270624607897488e404ec9528e373af41d1a5ec1fc61a09e35379e093eeccd9d8df90b1cc4d934625f834b3054aa6dc4819e8e4b56d5430cc069353e119dd382d68c594e2eb3ad645a70376688b2b236aaa7ab6dca6a9e8407414820da18e09d1e98817e6ae1a9fea88dabcf3b8d3d9805d29199b08d7c4ced48a8b23cae4101e4582ffc3a3483ee0412587bb835e102646fc3f23390f4ec2b3142e9a8fde27c738d16ee65c991d753abfc53e410760a1a7f2c5900171bcc738fffc96894df2a12c6b9cacc6a7fa642f8c1f2c4d10d091e6977a2ac12ab4da38e37a22dcc8f5d7d2084468b472cb44a7d2f114fe188d44307d6eb2ba0a8d35494f758239ae94e86f98a0e8740e9ce7be5bc17f68152c97a34d0f28ca16cc656b5e6645bd25d5c21e841527da43cc24e2138155d172e947980cdd65719d44a4ff3250292e314678c3df88f8342263501b517742aa2775bdc8a2b39afaa3cd84d4640b06ba28cb9a49f2dce027d2218542c949a0833020566620c3048a5e70eceea168782d7079b0d15b0d3881b1b64176aa4fb2d2b8a5358b181b8d3ae98eedd55f7fe6156d4ed84668e2517ceaa7413801bae69360b58a4efd08a508a29fc125fa9ac1e0c929cfcef2f34339bd6928a77a28efa666326a73602aba197ca3f1657a6a5b2dee3e228b1410a4128e118611907a75b47b3c341fb83102efe15a1e4407bf10744aaf449653c11cd881ef5e82d4e98720fb4c13b9079678b51a1517b14514acfc1ad2877c92fa2056a800e322b8772808ed6a155edacd98393a7ca8bd1b20a8bd1b04abf0ea169d42b45edb68b4a5df51f1176958894a8bb6b6343fc2a42986dc451c3b747ea3d8ca6f1471ebfd189330b67c6a622b271f84e5fa7e461757dc67aa5c3cc9735f747ac4bac1a3cd7bbf1dbe7fd7e59a9d6c7ce5c36245c1bd3bc747700057a338bec35d6822dc0ba347b174a189eedd5326d447d13148fa9c5326dd71b998f14810e5622665c23f123fe124c3cdc773c004b7ab88bd7e16c185d06ab5b2d21ad9698f889319d5497b64e62b8a3a9d57ec838d8d58e7128ad0469f2dd54b82df4ec351f1abbb6026ad01cbff3d33b65e9cfa070f11314217c84fcc907b633be45ef88a987bdaffdcf1fb4b233e7ca7e3bf99fa017a3ef5193ebeb68764850ddcb97da03f7dff747a6ab6b373bb9dbf63eefc9d6395ba7b233df5a3c0b570eaf574fc06416a848d125850e7a7f8fac5396b6a70f42e46bf27e88f045d125413f42541e6ee9b3219e37312acd073825e1094256816a3e753742de491c1467f75ccb69a6f7e2663558cb32281b3c3d3ab576555bf165917e5d0be4efdc2bf5e2182aecb73ba5864097d5596a787cad411c9626e00044515ad656427ae895888f2784293b35ca4cfe665b19b4ee3031d0fd6e7da60c335c7f9f40a063f30a746f024f649d008f00364d650f8afd09ac95bad492dd030f249c0ad8f1ba3a85e966cdc0b5a4dec99b6179665ad00256a58704aa99c399f1c97ad8255e05faf1b711da3e88c35c12492410f9dd345c598c468b37fbfdbdfedf6479b68547031922e7e27f12949e93b32a383d12617a8927236da5c0521bd849bcfeeb76f872f9e7d78f1f1dbeb771f5f7c78f7e4cde1b7e7efbfbd7bfff1dba7c317dfde7ff8f6f5fda76f9f5fbf79f3ede98b6f2f5f7f78f11ce7a7ea6bee6ef97bb9a8498e4f75391bfff3f76f417e76788850825a471971b8d3729a7c4b4289c06dc7607559c5cd1ed6ebf08560ed1e8e1f3e0cdcd3e6cefd87e83de89bbba7f4aa02078b7005a806be3b6bb14c2b42c351a1c0909f5593c3ab227608d70fddacfa0f7560966658541e28c622b6814df004a593e3903a3f9705df8a6c65ea4810a18d1ea35caaddc679e55f6db60fcd6ac089438cbad37c52b7a1d2061c3d9c4ef68c3e489b183af46d29510e448c66a36f9e7a5a5b10ae61e6812880147d1b7d0d1b65c412014d4b3835ac18776d54b1b6918d2a62269c55a1bfc1a31cf88a9ef90a1e9e45f582d2d7455dea49baec5f813c6e5f57bdb7974bb52d5b37aeeb92f7d0c20adedd461f2506a60942870d42178e8a4db479e7aca21e93d8e2fa4e382a464536f6fcf9a28c6955756971de7df7fef98b6f2fdefde9618cbd3bf345999cc1b4ee04def5a8f0bc59c988755774e4616f41bf9f650beadfe96ec7d36a5b92f345577fdb9d6545775add09c251b1f240bbf4936d25f49ce6e51cfca86543309fedbb77bdffceb318e225f2b88ce7bd6effa0db1f15de5def86d1b0f750e75939bf5a64e9a4f6fc38f05e92984665798abcd745dcf5489178595d79643ccef28c6164577df87192555e559e2d62eac56542bdacf2c45012efac80408b13eabd7dfd51167be3f28c3508811ba18d37af9fbd7877f8c21b673995011dd9e1d84bb20588dd575e39f66aa327867930866db67cd67a82b40969414f51ce7d8dd6980af14809b6cfa1ce3df696561549c1eeb2a039978ae6221f16ff63e94bb499dc3c90b6400437f64e515ef84138f7377a8804216f4f58e344c135c7f18ad61ff9658d5fa35e80a270b54267f839a969977fdfd6ac3918b131f4175b67ab706c914239d8a1d1db18b1510dfc3926c81944b06227708bca7cc7461d9ed06e620e22ce2959c8f7df835578da1c22237e79134ae37211d3970b32a31f2c16145c73c34811ba852f60774e17ec7c0419c12f65219b3b1a1557f2598f15fd25cbcc11862e9e684c88cba22a73719079a23e66fde54f8a6c06676e186dd88e4ae20bb6b16955db9f743aa2f92e05d236da841d152dca8b8a2ebca4a45571a7f684d599d7da46d77b4b4ea9579d2da8574f48ed5d956710ffd423debcccafc6599eb37dc5e39e8aa6abae37a9eb7935d8de1e47dd19dde6b29eac5f8d368335d379f293636e83d47f6ac82bf7f67f54c84558e73f76c1b64870cb2d75c1f7d34a471d7e8a2f7f6e578aea5b4f794ec56778a38f9e8bb46978ab8f5ee27df42beeb56d17af9d9e3cc6bfb26d646e93e660d6ed29125cf71e93e5b2bfb3ff880cdd85b5bff26a724a2b58a22aabb37346ad6b2fa2f505a585d70346d1dfd9471efb2c2b526fccbe64626425e3f5d61352b03ade785e315e5194b57756085461fb2e18bcc4bd476408a165c679592efcfe8bdd6d120cf6b969e82b9ebbcd22cfe8357ed5652dec84fc6fbf5b16335e056b25a845a79f073713e95f31b9f71244e8e79c5c0f5f77e765558b9e453428df58bfc0a5e42d1f003507eecf3e74a9f2734cc267cb256bb4875abe6e21c32ff095299912bf7d3ac1aa49a1fff25f0421c339e30ae737e73e932ba9088f2dc38e332ab69bd0596df51f3f7edc471493a3e4d8b205a49d4eefd13f78be35f61247881cc5c798a218f354fe9eba71d3a923c455d651ef58ca775a301427282b1d84a1b160df980330e6312fe73c9a5e2c92d81ef58e712c66c367d28334ca62c2c9232aa638c33b77fde45e3fd8eaa30293a3d9313ac7b37b7db4c0e4e8dceeb0e8747a8fffe117280e0255b8e0850b5404431fe0b040ec4bc8d9741e0c78598158d35036d32663cd4662014bb30d0796ca38a53576c93f1c7fff7251bf2e127ab915e9df969dc3301e906e966c45dd2c018af50e1f1da3f7ec9fdf711ffdc149d707bc8b0e21ab28fbe713dee89bf73d7fb25592a08ef01bffbd0e966ca548d6579fc15b56490222e261a8e082101378878c01370207a0dffc772ade055771f26e0d54fbcc060523fd53448ad9f81868faf0c67f17041fd9461cfb5fac5477d6f03b9dd4ff8c8cf16d113b33c8170e700697f053a7e3b31ed1c40f82f0106fc80c201f80d0fcc9761803d31fd0bbece38f4ec7dff0ff70a6f8380a964bd2e96c9cb2b6e47efc4301d0f0dc48826b5dce4fa21ff01fddb930d4e12907455ce4463f8f30847d584325d75cc10c8dfee8e00fccc1d9e9bc65d3fa53f953c3239fac112ef98f806f3c19b5813d1516d40b0ef5c2807a1484334651a5ab81d26d28048d0141adb5f9ca50c031bb94fe735bfd50b8cc4b93e4fd9ee31e69a40eb0bdfdfa2ff6dc7bf3fd17bb9ce1ff13e74deefc3ac9a9b29bda6f793f9bd1841dbd54a57eb3d29bf242bdde6bbe7ec784e45cd5d86dd6f87d51b2139e8851d07cffa9a28ba779199f82adb36867a745370112dfb3469e670289d54d3c6c1154640cf71797343e639f992cebe37279b85cfa6a5bb66b28b496f47713c55b04aa0f2d034869fd12ae774d33b7e6a780b42d421fbdacad190bf4faa0d04b609530a4e12465d7092116e10f2b49193ee0c8bea9d07abb0f385eb58c614eceaa76f8b55416478adf4956d4f89f2defcf8acf593d51eb6d8b1f8dcd63cf4e6c0bb16dec3912bc6bcc9198738c1a736c5965a9d768c133f376760de15a63261c2b0b1595d513c2df90ab90e2d16671368be8c28950d17b4487c93d3a48c2b8b58aca073d54bf068cf2481b23f61b51cc3ea7f7e290e0eb2c19fc7eef1e925b6510218b560f0852846f4091633f1f23c517075bfd55481f2743dfe0f49871c7f78828c76e4e9a09fc7a1f3016359cf8c1e013db648cccd2ad240898a062b411038725016aecc8a055adad576d529ee5c9d78ce649f3727ecd5a017f96bcf79dea20e2bc517349cd93e52f456d3a1d5b8460cf0e9f7319df7279eab7edf08b0599b7d2369161415968d9b36bdbca5d329fe75790bf1e29edab83fa2baeb4543c6b41218bc9b39c54d53b32a37eb9c85278425eccfe7c2c3f80b98850568abe54adae68c067c7a80f347d7139f7479bfeff5a8e46a351158c36bd7b763bde3d6fb4e90f07f07ef94b30da44de9df44e80bc3bbff4ef04aabdedd1a8bab79d22ef8e6796feafd1a8babb64fffc022fa5e252e28627e88167cc10ac5dd8187c613727a6c6e62ba6958d3df9b20befde64552dde795ee38d30a1f1753321ab2934b1ac31b99fcd2f5945ae04e617fc775407614b3fbc7673811a95ccd998c370065fd15a5b0edd814feea05b34ef753acd81752352d13f49ee2d97de9d3be608c41046c56a136d3a6b02234a84ffe3c01b93bca2a362156ea2cd6c0635bf711aca58447956ffbe28e7745167b47a539615f5c68b72e68d36ff3b2211cdb7176705a37fdb139acfe9a2daa6d56cfba6cf41612ffbc98a095d64f5ad1bb6ea9b2db14e20cd1d6fe4ce7c51ceb7d8ea57777425ae46e71540cde4be7bfefeadf97a2b29674695b82cc6592a2a74b7f9a3f1feda138ca03a9c9039f556aaea599de5d5b61aa3f1cdc70529aa8ced905f17e5d95c189caa0fdb5fdf5134d803bfda776fdf7f7af7f1c5730f7b77c48d194d9c4a2fbebc1635e865d6f2faddc7171f5ebffb152a143504b56aab229a60355abb904d5c66b56861fbaebc54a0c66c8da44f39ad2b501526b48a1759443de2d5ba2280a22ca891960a2e406ad05d951e29ca7a4217deb7f29c2e6005be7917593df1885781099597d038278c059c53efc9efafbbdedbb2822c57b3b2c8afa0b5acbe537967154d788bd90c1a9f500f80991529a8c1046cd96339f6881e114f841593c2237955428b1155eda97965c5166c73737a308fca23957741f35cdfc16c6d6da9df77efbe2b6b7af7eec03bd1103cf132d0dae5a41e978bd916498bb2aab3d88bc02b4c0eadebbd1e33e8de59b00165450a2dea01545e5678cf0e0f1154ca736fbe282312e557de05296a36fcb38adfe81c9d3c3b3c34fa3ff6a5e216360b83e75991d557dd72910a2daeee662b65f8bb1d5795511870d817554d49d2f55ed79edcdf1ec97380ff9892fa6c412b067073f202e2fc9212aebc3c9224f08ee4faab82c6b4aac8e20af288e5e4ca2bb29872fc78767868c1c19fd022a6ea02ab604417aea80c6806ed0bf4f44a115756dd5a258de84949b96e148c9ba1664427e43c2b17a223684c7f90d522d75a85d86f86ad6cc4f169e58d36610f8e360131479b6cc38d3625368dcb45b3b98a4198a1f99c01836db8baf452b62966941412c7b9932b7b554f4ab88283bb41ef65b980e6e825814d754139be278957d55739ad60e71883bf98d0828d1ac65979e5c26363ac060a68272727d3ea92a38024a00681585994d8c5244659443b715954b5978844ca1ef6767bbdc65bbe3a876ca41e060e78d7f38ce51f7827e59cc4597de5fd722ddb5acd2a8f928a6e65c55679569f20f199a839f07abc64e5f4a69b3de4a0d13d4ada3af0ae75337d6f85ccf78c2baf7bcf09abfdbe67bf773f57af572e585e928481c3bff6b262e06505e350de2af0f063cf170d3e3296242bf035afb492ac0e6b603d165f78de3527ce462becbf474976ce71055f5f1be59ed7ed76cd0542ee4b179e47d0feb1516d65f4cefe7b7d67e6116fcca6a7c7bf610e663bc9cef537c14a4ed760b9fc35485280adc6fd385d508f2ca8b7e7cd48a689b8c5e048e101cd1ff0a6b7bc13cd594f9c329a5845827b3a45b2121f83c3421837a8cb34cd69e29d6784d3a1ac3861f47cdef53eb3dd78522fcee8894dd104b34ab3a28217a3cd1782b054354969d77b7ec6462c6eea5911b21bf02eb23cf7aa4936e6628be0a795274cfd1acc0e314a61c242922bbd870d6a687ccdc853cde601c4899ab0e323f34a46c08197b3e1e5b4a65def0d65cf353915ed31a652e67979c16625a9997f4119ef3bab34fd3f3aab28d83d3a7c6e5a01834bcab8da9e94e569b5b5a063ba60bca33ba967f97f9d5514e61978ec75d04af0b4d7e27cee078a3af05d79c4f718f22a5abf869fc71ef6e4707c90d70556aa93a0de688f2cc4bec506deeff59cddd3be7fd97fdbdb6c3f5a856aeb78addb4794476775cd16b6789667f129bef681c8a809fa0c3303671850952d36c748b317de9cae6e6d67019b5563dfc22600b6cb4793555eccfaa0c97a94b6718de32b8087cb1c05637fe48ad5594034266fbfd79b559ecf3e02636b905c04b04f022fa2e372c190d4130a018f6bdb281762f4d66068ddb5870efb39abbc134001be912b26a6d41386cc13329fd3a2f2e8654ce75c12e10bc90ec995de9c068111fd09e2a2ad6f98386fe00df6b6effed7b76fbf7ffaf0e2dbb7bbdb0a7bfd6f706cfa45c71ce1874bfb5ce7eb9690d7f8028cb53cbd2374657f0ed1913ce198a78ee96c70df183d129f7afcc9c38dc6b9430868623cb7b1e5d2136dc836b993001cb43c2c2b860ce75f170241f8e90c847fe7680612ab907518675850585cb6246451c98182460c8a3c6cf5d7e9781bc67337abdecaa3c6900fbd0b8d7b03f1c45b31469f15599d91fc1002a886065c4455fec2c3dcd2560e4858c9cdab6e562800f362fe9951e8d97d78581c2a435da1b54379b654f56ccd486bc3fcaca9bfe03fdc0ff5e8c5d1ec7df1e232abd9daf26259c84077e34cd419fa670669cf5e8ed142caae20a5ba1d1ee17660b7263eb596ada097eaba422f9ba769fe3785bfa24f8d926b63107b58efb47575fc6f0b3a661b869ef3d8dfe6c663a37acd2802abd4cd0a0b93c4cb4e477fdcad04b8b001646329c45c0c304b0071f02ae8860e784dbb71ae6edbde66533a2cc8bc9a94f55320b4dcdad667c3e151de784fdbdb9ee7e5b486e9583b43bde5b8253ef33630f6787005b715c9b5afc5c0bd9527aa4a3621eb814252b5a1379c78cd2b8846587f4a27d3e9786eb182a1fad8b3e7223fb6eaac8c2713bfdb4680cd112c979e5bfce3117075d0fa01a8dffa97c406b325f916fe0a74031600beae1e36d15e07c7e2f5781d2bd304d055731b345efa0a3d8d58637c3020a720af41e584ba757daf1c0fd775bb064bf58ebb8978df88a2b211b97a06668a9da95a5b8fa0ff3a76de889a06df58dd4075ff0594bc091f5b7b75684b73dd41e242468337aff8e72ccf45a0bed63537de3bd8c6afd9df19b4df6fed2a55b6af2e4d97c5be85454202f54c1c9117978614c14441c4e518e45932067be361fecac35a8ad16d68a4949d6d70846528226e62f41becdde1b7aa778c45139d885a5df6a8d64bf6ac5eb26710cf3ebe7ffe7e206e98bcb164994c1867ebe5cdc8b45c682c77472e36320c49d90a7b43f7f5800f600d1bb26630e060b4062e3e47f62806e2afc9ff9d8536d1d05c690b3da55edac2503928b6224a71cd368bf024d783d66ff96d903b49c9db0ff53e07d345ddc2f6b6b9d9e0fc44f20b72557911d57bb65497045df9e14d486fd225732b1b64c0daf022fa11588e83c8a7a61ddc20d6595f5d66b51fac113b1df2688b9c0cc55dd2ca470a628c314e5e0df211d6d46f117c9498a48611e80569e087395f133fdae1d03843ed088a109a4714b5d5f46c4de4d7a7188e33668429b6718c47f3203350786675c604c91dbbb3a24ce8073af686de91eae7d81b7847f296ce742c843509901ed131d2309d91ab08fcf284c4ba73d46bbc7e624c85d7e91f5b23ac35a185415a443674c0f651115a0d22454c2a4d4d5489a6634529204fa45dbd579d66738f3bf1d4a5e472bcc7ed6d8691175c1169dd532dce8a42e9ecb21af4fb95a47bdf666755fd8d6dcb8ad6e606df506db0c3281fc872296e3dbbf2beb881c8644c0f6f40666bc89eb7421a437d6bf3726c140850f2231b4d7cb580c6aed43f45c0ea36f66d35a49b41ce9acbb66e988c351521d1ae9f49db3cb222bd7904cec765a165da1745e29b88f52300ae5b90b54b72d3a2fc7859d6c1d359284dc25aa51983fcb6d130a0ca0dd2b5db4aba840461502e2d44fccc663629472b69d2b2c2c05b4f97d4c666e35abbafc551d7d88c54e831feeef6b30fd13723cfae5e66d008fe1b361f5bb9462bb7d96bfaf0f883ad660fdada698d9db5dbd8599a0a83e07b33746eb1b52c70df6267dd06e43fb3919a929475fe6891b34c29b1a9776a11f51a9544a786dcf403fd559b1863c2d61cb20573290452e42997023930760e803b2ab0452ceed48cc5a9fb7f6e2f50ab8bbb0b9a2d126f41c0c3b5488409c045564f546b5244535d55ae1148567835adb8dc5d9552e09d594e70aa397161ce61e591e2ca1341e65a3b1a33ee7b41656f425c8e3538a514692da6028ab5d16e825e1b0e39ad5aabb1aec30671de6b23ce2406231cecd58b331a5a14a358d3a34fcff5bd82c453de8eb59f54d3e601466db3bd1bb0d104ace8ad7100583f5681fcd6908d81b50e4b37274e8f8d56db96c5215d668f6ba81af2263cce88ad627017515632985f7103df6b16ca5078373342dd7a52d2ea5d59bf22e754b0def78b375955d3c23ce07b586b0f368c4e4992bc281259dfd23b6cc0b897cb1b7b3056c7748876970079bd1fb13ae740680fcc51c0b183c5eeda534ea37738ed4032f92672980798e60967d73ee1c80a36faf38ac631c7e2dbf6441ab29ed956d00a135bfd736b808bef6e3aed727b2813f779892d1ede42dbe9a8156fb89ab0199743e67e998b5b150d3e03f832ba1b83b8aeada3be1b542a732b65d66bf322cba968be323fb1f513f637d63bf323a51c336bf342b31a6d19077507409bfd52a73bad95346b49f2658ecb4249777cd64bf3b3b21562651358faa0d65e97f1f866759ab4d7a68953b90989b2017a25c0b6d66c0e00e4c5d6ba76f792ccd83545a98bacf292f0460b70df68087947a34d89d0a34d04f1fbf85f133179898576bc48e83fe137d535a9aa209041d4b6569a9795660f7ab9ac679aa847d5b082abf9282b0af08c368f039759fb1264964d842adcf6489e971795d03f576c913477ae643d6094226e960841eab75b7b777f5f94e7594217c89477c0b664a0ae2c3d7ed890ce498aee60ecdd91a4f28e37546f04ed43c6aa07927d77e3bc2cd4a078918c58df2d8bfcca97ad04d6f7011f882d530aa0e9a985a362251bb58d408c7b3ca13dfc7835a7d6059f0997d0fa62ae1c00b0d71af6879d64469b3a5ace68d31b8a0b4cb050f7bcbbde13e122a02cbad8e1fcf9fbb7d2f38287b52828b7eb36ac47c5f7d250acaa497c5a9ed3c5382f2fba7139db26dbfbfdfece83fe6e6f7beffe83fec1ee0eff447ce8795bc2c447201eb7dbf3326e958e78f9890cae302795b02d572702b9c8956ad1f33c9f76d3ae77223601581fc5e4ac02d3f48547f20525c99537219588cae39198014e1a3db13ebbee08e309295246a54e4ee99518a6639ccd0e46c42c81653bf18857d00b637c7ab212a411650d326c8747ab5130da8e79ca44a373a33dbfa2d4783c6287b36dcb687d8b1575a795b6e94bb37a7216c11a09f3be75b6eb515e46dbfdddbdddfdf1c38307d12e891ef4c7f769ff2079b0b337eeefedef1fdc1fef1ff47bfb0ffbf1f6fabeffebcdeefd9dad377bbb0f82404017a88700c640fbb274ab09992b4d838cef2837b9d8a07c8f2b6514dbe4ba0176cc341bcc4400c1f7635f7c0e9b761520be5bcdad702251ea846f7269d10a6e0dc2689f9b42f14d23bd93f8315cc7289618c95095267c19c19aaadd3ef4acf27cd3da0e99067148b46598b021c3802d40dec5248b27d650ebd2038f3c69be259aa8e634cec659cc2d851cebf5aeb53b95e1267b70ed290d11332b0cb3cafe3e37abe4d8689b544a0c7df4f64ad140edbc85af4fc07299fdb3f50bff7275b2f2b67573c14a8ec631b8f494c9a3442b1561d84083b2a0efc7eca77fa40bd98a41123108559620a3be5c5afdf63830abbac87338292f6c93cad0ab17599ad205b732e6f2a3f00910e6d3c698336bb45159e68d2e1c970b81a1da75a2f2841f94974937fbfcca237959a45acdc3cd81b9dddd1aaf0de93fa3dc61469b39f9eb8ab73eda740c474b19008db50df1c4bd134092c5195d9d403b0c352b5a7b27a67874d2f59e8ca55308ff8e83c8d81c6d26aa35b9129d89d9228f9ed3828d83cb505c9e392b7246d659f724af4a81fb57de8925909d98d4c81cdddf5d0c364cbd1e5cb705be2d249ed04adad78a3dccb141b29d4306297b94ece876559edd49bc39f069f05112b616368c544f227d4e25dd27cc895a8dffdd992a171f71736120bbb19217135a88f660706cb9611015f21634258b04964b381f692be2ac3871d071a2a8abf42402ab712f2aeb8977c265eb13505b82ed3063a9e00360d3b7c7868799569116024f482eaf0e859b439e9d52d97856a427dbe2374d4eb8b6c2e4cb8fb9db124992cae3fe42d249cb054bd77b555ed07326e766e6367aec9d3cb218e963d3a90a24b2353b065663412bb65a59a19a33c67022ceb65b774f38fda515e24d5e902bb55de309b8a7d625775ff1b25ab59564631015ebfcca442a69ddf1036c7a51401e837221dd711b73a8cc56e9ad36634ba38cc8ae6bf33658ffb1e99c61b407eb35cbf23cab685c16896cdf93fc41d29f13fbf806e2ac14f76c8cfc5a9e793372a50815f1aaac4873aa7483ec70053e827a5683f53cdbf27570b9a4782e175e5624d979969c913cbfba4d6bd7921fcbe5deeff5a48422176bd72c02581b9556eb06b3a537af20374a28d7e4007a38d15ff067eb83939ef91ea867eb6b51e9bf9968e95d73bb2c6fe95df3590cd9399315219882f1c807a90ad48400b564580c2d0b8a127fde30729c1b665fdc7d3ad47aba8d76fd2a7c3337a512755467e80171a9bee5a07d73a3e5225602f694f4c27bb258902b1f6a3ef6fade907fb4e5f5bd81d70b90f7ed945e79d8eb87fcd72378cf1feedd3375fd8bb43a822a5b5effd8ec154a8fd7988ecd6b113142640bf68e60bac7ec101c93da67cd4a7ffea6989e244c6e3dabea7266923e5a2452e2ea7acf1cc95bd7e3fec0ac2176ca05ed396316c43b49ca829ea8e365d77ba2951ab372c18494827ae982c005b8ddb168312fd32cee7aca4a91f194aaceb89b55e2910a3cf4c4f1351bafa1049a335db49f8ff959b8fd847c83186f2313bef6b9b29d4d1b5c93d4def6b6b7a55f9817b3b3b19a2b8331dc17b1ad34238b5321bd3159831f8c745dd51a9ca959e7ec43a562bf63b57a878f0379dad5ab9d5a705e63cdc4a4e56cdf353046dd028c81340b7f24eefa4795ee4c1ec532b01bca339a74bd2785472feb056102339951ee9305e3c92a65ff012b509df16f186018518dc141716c4843dc5f2fabbc3266e74070a9e722aef08b1002f67f081538a17b2983b9b0fa03ef553dcb5fc8d024c694061e638a81b7f5182c270dd0974df9f83630274ad4ff7f20bf11e44d50c3bbbf096d7626fa7fc0fe09fca6c9dfa32a52cdde02f4ff5d0058335b4718fe69f4faffd54cffee5e12ea85ffe85cff4d536d62f0a8587903ef7a05f679efb8132d350c5d4a763407076176b25dc810f6326b1ce14cdd083b599425b872af9cab0c216fcb8b351ee7aa1061975053d5a2cb1dcd847e218f1bba441c36c03b499fead4a3e2536c90c825a76e21039659066d39058d0f059059d1a858d97733668022d3d1d2a8a2c21329a74af3a50e4e64f80eb915f8e7ca71d4695c7cae7c809c9858c6fd9411068b5ed6b448aa5b04a61235ade056ff7706d12249f2bee091ca44b5a49c6dc9f64992c02be303ee9773c3374668b85b06ebfae88487b222655911b99452fd3631b9b8dffb373907d3ca4496896382d015d9d1f8e0f8d4e9c897c6cf6e35cfb3da87187ae372f182c4135f9b8bc5ea0c2943086a10cbfec4f90fc2eca9911a80b32d6274a8bdff89e1da0bbc66c4320cd813f3b068e8eb8b6ace25872b2e455dc634cf657c92a322dd1251b9f4cd5d52c6559714e9594e162228079967db45cab312d0c0cbb36801b69f57e599b00b85e6d8718e51773b3056232054693862c8e049d15996d7ded9bcd4994e8e4efe66502c37209611564cb021332a563986e82a5c25a2638bd8b1b904278600612483f052b0b610d5aaf21219d345e9714f90d41f2115d842288c84d6b7a1f6eb825a90ab5e79e35a02d0b15a088fd6068a41efe4ee1637883c915f145eb948b80e1fdec8b86bf65a18b7234e5018e4cd481d43f88b93bb5b426961cc942ca81a535d7a8cde6455dd165d465d3bfc6f0dd6622d637bbc969d5e6f65d0353cda9c5d6db14d37dab4e3a7b88db3ffae479bafefe4b9b7a03185d05ffcd3adbb72ef8f36577623dbee10ed5bedb6282f2247267f1a6dfe9f12f545854382231cadf575086abdcc812b368edf025c2a821047b113113e684bec1c119d887565bd51480f2d46941178b84357ed819f6a9dc5a7ddc64e3e82741d95d8480b3acecb8b7fd97c61bfd77bb0dbdba50f760ec883bd88debf4f76faf12eddd9e9edd3bd83fefd873bfdfd9dbd68bb5ac4f63a83e1c24eefe1d69b9dfe7e20a246f11c21e2b04792441195d6e90bcb800c2e823887864bac45169f8a06b9754a564b1baab3ca36b4517d3aa067f4862f7c3be0e152940952296840afbc0bba50cb60dc0f9705e5671c410421b4a4081859943589f22b71c59555dec584d460ed0f4e76f3b2aab228e74180f8b805cb82b68465252962facda23271c523ff74e556e40a84eb46ac3913bfedca629acd6ffa614ba03b19e76ea7d79b55ed8d5e66f5dac65aeaaeedbff753fd9b9bd6e5147091375fd08a8716cce2890c3b68decdcbc89d77efd6e5ddbb827ddea98c1883b26292b0adaf77998a110ad6f4f995b86d99210f50e022ab4cd6c75b9c81fb163babc2e52bf5086368ec1c40930d8eeb6615af8cceb3f2ace2c7609b978a08960bea5557b319655b82e4c8cbbab42b4ecd771d8cce2a1dfe8954f09e716bc46f670dd222439c91a83ca79e3fcb8ab3ca9a7bc07d633236c6b804a6391726115901ca7e2595e4f4d2bd477423943ad1460d2949081a9c76fd8b02d27f19e654703a11418aa08b39f061c3fda6f4b851944415b6335b6e7cade0ab10fe8a8bd7362ffe9b31b0acc66e1106cbaadfe2fcf877afbaf4bd56efd6f75ab7b8d3ba311297b8e772df21eeffe05c783901ba54642926ca3d130b678455923a91eb951b77c12c0155c675c3ab8737ae8dc5f5e2aef77375dc3bc0227a41ab323fa74f048ca4c975d729af6e68d672dd106e38ad8dbb6e1ea6437efb0796bb871c983a2a527972034b9c3b0ddfc9ae730436bddbeff0873bde40c486be83bc3b11a9e81d378cc3b7a66f76d3d3f2677db75bfcb4ac1515912dfe3d8bbaf31f5dd59d9f5ed61d7b5dc1c5999b4ddfbc423f5a5fd608f2ee707e739b75b4e1d7ba943ff483bfcd6ad2e4dfb798bbffd1c56cb862fd703177ff5d8bd9b6b1594b3fdcd662d9d949fa368b6e79a4b7aef9ed8205ac5f72272480e1207d8bf5ddbbc5fade7e3df78e7ab724a162819ad06e27b8b0863f5c1a4e986f49592fb3faa69569f5cbffc132ac25a3b75989fd7feb4aecb7adc43a70dd8e84f109fe00668df002b700db3a7a751ba8ddffb742edfeadf1f776228082f06da80540e207e05d1372a21dba2e447e9a2b9861349b2eb92dc5d2cf1969a7db636f7bdb0393d91355c63333c435d8119a86b2b2e38177b4767cc70d1ff16f324c89ca0e634f15c8ba8d4bb159d39c887e119af5b3ea1052e1583d485f32a3cc489a637d3f5fd07176e9e1b686e4b5027f1a9a0ff7bcd1e6d66893b131bb3d46e09e19d9775a9a1d7aa34d486b24fabec719e5c068ff88951c5b0d7352f0c3a6edfe6198fc4b18acd303bc7f225edbddb17df1af74c6be5bdbd5737879ecf8a69b1bcb6a71603f1ac4c201c6c02d30aa5a1319d88f6a9bae8b6ed088536b45efb4b58c6b0278dee24a8e0b2ef309a9ec80b56616a7e64ee2bbe7083e03e8ea696dda41c0384575b7614b8b929daf039fa2ced6675dab8e1d4d112440b6f7a4dcd7e9f089f252a0beaccc6ac220091a04f7b037daf460dfb8fdc1d2fd7fcc5d5d6f1b37d6fe2b8c51c492ab28e87bf15e3835b241db2c16cd178a6c7ae104f6584359ac47436138b2ad4dfcdf173c1fe42187e338f5a64d2f1a6b86e4f0f09be79ce73c218a8a2112110bb4cf5a55aad39bcab48c587efc98b4704692ac48734e625a01f50b28b2484b5c092bcd1c552e2cae908c776e1167f04069d798b67fc4ceedad7db46db74ed78ff4f5a6d3ce81ed2e0272d9cc098e976ed1d9a6796b37a5b005391b99e2a808a9d60197151c321fd4516c5db95d96ecc5911a6c2cb681d889470cbae9617ea015fa2eadea773c424b12cc46168c303eb3b2806c6c7cf918cd86e93e3b1bf26c3e950c635312411da98f37c95c492449f6fadc269ea62c8d874cc05b4bcbd396ca1b9b9ec3d2d294f70e87718748152779888ab03089449b3f171c20145542d3274ad5db41f1b3e09033f9781302fa87660c4e4e525930cbdeea3a7d2f42254897a84c7b24d3a067553cde67ef92ec59dc86e826955c0fa87ba745e07cb23d8e63e7d35db4e47316bbc11fb7d02963b0f7fe09087dd227a5d26639cafeed4a8b4878e23c280cf519900f2c6cc4a540e1891d836880564ad90e70ec84f4ab07be0acf184104bc5e840f66c801c186a940b6d2baed7269ae750d3ba1aec0e404fc3788aa4f4cf0cbaad6eff782df458a1e7aa400d0fb28ba5a889f6cd1c99e822b43969fcdcce2579e1b1f1633a37928fe1864f5cf444ecaff4c2df595aa755f9906ac9aadedc19ab4ed15c17c9d8ea694e86f91b6c10fe02eb28304277f58d3eafa2422526c0b38d0aac702283001c75764f0ebca340c2e01ff8bc44d2645e9022f995d6b64c3c303c82c00fa90d28eca891d893106bc6057b6eb7668beaac034c663c25eeaae3375addbd4c9f5ff0098990e3a318011dd89f2022018fc426e4e67aab5b2ed62ad782eec743f47381c9812cfb4d2d71bbde8c9e325761a59f1b019fa95692f4461d05ba69f250c6d8baa6d2d8363191aeb4b30bd9f4bed7ecf7464508b5cdee17045afa17c1c62db9d9cd97e05616783bffddb885ef575448b3ff1d291e12ec02b23539e9f8c78920c1a51e360c72427002a0fd2741adcc302ed1a279d9175d2e9462f7adb21a8558c897926c5616bfbc93c97787a0ac4786c63a50166b74d8d21078474add21bb3f015011f00b100424539c008ba9bd04ac74ec73fbf7e19b81ba9bc6372729b2f9c08665157adf64393bc428c7d5cc5648fa773f53a18b3692ac412812c7307be71c32ef48d0e5de21b0dc0c58bca69978e895ffc121931947265676a4c585631f00238c0d47ae3cf2b6ddfeca0070aa84bfa5bacb643dce5fe7a47ddb23f4bdfe1bd9c52c0df2309fdad1a9379890789c896e8df93812b7953f84c2959f6913c091c2de013a05793cf4b1f1824ca8b970946a1a6597803f08b4a96f4e81cf9d2d6db26dfdc642791db2d9bdbc9d3167ffa21b8ff64a412bbb0c009d651b5a8d6baf9c92fe0a6f549c024af96a6d102a48dd30d472f95e6367eff00ff0d19a8a43110ab139ffbf5e20c1c7eee38e6d47c3e27c146db92f0b3a822539f5436509f1e2a7c551ca4636f7daf0edf3130b7f478acbc30060baf10d75b783a5a180db8c19b04032c4f9d992f7629e4cc8f29ca3f059f24813c021085d42dfe0018f423ec8e4a05ffdd109cbb41db3e8bc5b94ffbd0a2e19b894adb4f8e9ffb0317de6fbcb5ee025ebaef804a5b6a3f39e41e1ce0b5bd3e386067e7009a0e2d59d7f136c300eb6fbc5def80f5fbb3cdeab7a3af3f35bfa84db206b80bfcef1ed287b9f60d40e506827fcd09157b5e878e1f9b43f146f3d74da47b365d115d384578e10069962a7422d86c553909909a3fe607fbc332863610cd733c57629ba5e297a8d47b615c3f558347f3aaae8506fc4960bc79c0f5287d631a0c1476999689ba5d61309c96de179e7d1f2c1451b10e95e1a44ef7cffabe3367db5e4ff621d1fe2c13124a7af870583c28b1df558dfaf449edef4f4b5f03c4d2de6c6faccd6f6b8f5bdb9c347a0f1e8c57117a8259ed2799d520a047a8c64391a574839741d8e9dc5fbcae5f2f2703d94312d0f53dfa819a22c0e9380ca89739c608f53bcbbbaa31358724bcc9717b8cfefaa7b9041e6a6191a6124f6701fdd62ad42fab75b5d9f883f485067f6c481a7d8eff01307df5f1e026c63b2d968ca9d94c8a65dfa89754b85d26e5071f60ea7ec9ac06d253be100375e6abf99ca9f2903964b34995f2f804b3e4e839c8ed0742da869cf82926e09f8758cb44538c5040887275a45e8378a4439f40f8ed273c2643d8d6d08ff375b51192dc02f25b109caf04084cc47afc58755bd45bacab8d9836bad3e136e62c5ee07c2adffae4cdbeb0ebcdb6078d9fe6af7bb98eb1ebc9053969cd88321478449fc70fdd38f00004448ee96482b404a0f47f8701043ac375b58b281d4e06fa8ae0ce0e7ef7647df17bc85cfdaee31d7a65afd4c199ed5707ca9976a1d5957869d6dba6af5a6db70e6eac0701b6405316f43e7e3fb4db4134cd1ee02615f0ab0298c0dfd77108bb00dc8338abf20d3c5debee1ca3edad5111697aa7ceb4ebd5f956849b5bd8aed30bc45d8231d7b4e77366405e6efb2db067401bf929e234b619e5def6a631bdd18e210860ad78b96d7a03630e43e55c6804d1e8ca113307044bb65784fa35bdd3cd3244d3838230426db35300b580ec0bdb02d3357fbba5f064be71788483e810669e635443f7592f83596f68c1323d8ccfe1e2c2ab852f12ff17864ae568c0e95a706b83007183974bc63c5f42a6c8b83df818a0c1e07f5fe363f94258c10c44bd4fd52bde7d006c0a83c7b4ead48b8efa5d7e8ca01a7fd2d2d73d85fced74e52c879fab75371f5d4d6130cafa39603245fe425a4ba0b98ff09f4f9ff030859c9e8066b8eec3d3f7123971aefb7755b3d5cf6df7abde4d2ef42e5fcb60c569b188a7f0cf312c2d87f0ade3806b007788e76cfcf1b9ec92e445c460635c9c63100bc6e9ae8fd14faa9ebef51e296c698d3b03ab86cfcc9e0fccf3faabdeb937440b33be9683cb15a6f219d4913a665f958006f192fc8a72fa3f139a1ff1ae95c4eaf436964c1092c46b2fabe63115e61766915370ab146a4a0e43f847cec828bfbfd9ba155737b583c77633a14d16623c49d780d02854f781e04c3029e5a2df1f84f0508e41c88c513f0e9a82b350b33d5126c1d1241df78aaa72345acab1f920196a846cc7b764f1fd90cd80f48b43bf4ab6c8973e5128ae95e5e014316dd534bb1958dd684b77e41f541be062a208a20c156d773c09713af13cc85b783816d3464daa2c12dfda1094602a5dd2f89423cac3038488f072aec1a28e078f19c1cd6428430ee8e71f4110bf0f8101f769f2944e7173f18cbf563876fe0b234625ab39393f647eb554817ce9cf5847d4d8d18d1b4186ff2761a59705dd78f9aff999696b589d880d207abe995604a15102a59535256bd8b8397308579e9c3146796ad0df0c12a39332a6a5212f835314dbfc159f18b80dfd307d838d1e8e17f46ed00dbcd4fc94ae4779b7842243d74cd3a50c996346b6cab406f9e7b024da40fc748c87ffc2095eee91e1ebea28d4e25840fd402750bcab4c539a245fd0aa726f70179f5cc4cd6858d190fa15eeee13b1458fa50e25d11941a693154607e717babac46ec8ea1eb24e81682afc0c24e81021caf47a8dbe8e576ac2d6e4a9f4eee2ca3f7c883a9337746c099f9ea674c90bdb3adbe87963cf2731dcfdccaf8b534e96b43fb81ade3233bf706e1666e767665018afb290cfccd09827ec3a611f57898e891b8f9bce77466cbba4e9b8336c53ab09f92d4cc79ab6c112eed7b22160d76d529485181d6e0599c8eb82492ef2e8242e9171b3036f143c88562e215280b1fb64ac49b62d7de12f1f6ec3d9f5770dbea1da80a54f755e7f5914affbc51aab9cbf79bc5d1947a705f31fba29de5e5631dfdf185dec6e51bf240d502102987c9d4403cb76e0d9c8e96a563a010c4287c997317a1884e776f1f246bf3f7d12a72e7bf6477a6093fbb47f096a39b13de727347bf6c7f1c5875248b0a2e7277b7c1daafdda5ca24b088cf6e7d5a2b7dd4e44e8968f474e8751ff9846f67abbd28979087a2189d5bfaedaea1cd457a49b2af9caa1626192199ac0b32ca70198a2d6c15fa4e7ea85b9d0a510d769482d372bd6d140a580a2655d2d56a6c5302e50610e6ac3b4af41cd269860ed527c829665b316faa49f6ceb4c4dab3587e438d38dbd9aab670e567fb42bb3aed176a9d5ebadaded0b19ba2a8966d4dbf3f346d7aadaf6765df56601d0338aa556103856ec95ed4953516a974868410e79fee6165dd7d829ef0114f5cb75050aba9395bd3aa17ec17d8d149c60cbdb6e5824e12a36d65da4fe44027bf6de5c9b6b546856fd622542b4a96ad159e784d320aa58806643af5dd446f99992097bdff81e59717788f091e5e02b1db114dd12f1e3d6181bc0ab199ce343613198863c6eb775a3531ec1b97c88db79796f4137ff29f29bd373a1465fa113243acdf2e976a682bf9fb2ecc019c13f27914a4946f62019de21e19d3c94b99734fff01c1b36f9704290c21c26bf421270b8fc0d14f9b21406b3dd09c296f5e418882d8cea9f4d0d354fa8b9f3979394b497d9730277b21af03b7f598ba5c7d9f45e3c52efdf4dd3fc9b98764a5517ef476b1f7990f92b79eb9debfe67dd994b5d8358cf3bbbe6ed4cded08b69e435fda4d3cb946322bb24120f6e898e359f1a3e5971f8240388538a47e930fa989fb40f93ec4fc7b43d422a598ba93afc725d455240791a88a17113b57c00a4334e9d06aeb953f4b50032c140db977a5ef8dce968ca9a5698d5e3733ec9b712260f8a0904607f46b15230024f85f6221813fdf1a150a2d063e49946d1eca5d7e03a522648167322071b86e91c77205812078a64492e2c313818c8520a1ef3d5bad1bd8e17bd685715aae621a0580ed845b4a3d17f374f46ae575f09ab1629f332cc5a0084646a733acf965898e9d5fd416efc6da48f956527a837e838b13ca71cd5f2cd934c1d873d8dd78989cc13f47ac1964f1fe6cea04e975ccea537b04b175f5c9b3e990ba2038e0614df5f8eebbb33d9ad6c9eb8d9ab7c8ee7043bffc3aa8c56e466f6f9cf8880677c3ce39a7f863317aa7517e2dc70feb83f176ee93a8013d6df954e21b8eca9bf62d09513514a489756b5e7ba444ee793e3468118f0d3306d70b760e230c2246c9d2685c0e50fffff3d9cf9afe05c09310e7bab2aa04caad455477b01578b3c29a838be386c28e470fcecd1473f7a6f4468d2add3cb6dc3641ea1e0da5cb22cb6bb7088465838475807c9a826aedb09116bc19b92aec1b953a5b8ac064c1cdff0e0da47ce21aa02770e863d34babad4f3b12b1fc2b04c0b9e5581fc34d719ce94b3545ca7d71a48bd7a9b202afa55077154096ae62b179a29ffb6bfb9f32080bbb96fb6d31f9f57b5f6bd84f7e0d491f3f79569827f87a4f3d4558b7e22eb6dd31b7f7f4e183b6d9787cea502a3ddcbd9b5f6d772bc4aaeab5d70cac1f09d81644ea825c0c020084361ea33efa004ce9cc97c9afaa705a7a12b723ee29911f803919fb9b3db5ebb99326bd08ee87e319fa2c34dd503ce4a1011d2ccd229fb321597c30fa1ee954b3fed58040a640bc302e2eef2c41ff036a7d11c62a864161119bcda641214586701db3e9c040bdb5eead600dd36c803726b70237182c6d0b11139def8a90c2603e48fce85568318047170b2b884e244754620c4739afb05426f471c1b6fbf6fcb148a77247bfc12493106f0b726e8ddf827bf48ce6bd37f7b62de851293192a99b91c29a641656d2eb5da6e6a507821ad344f44a494494968c3ce73ae5bdd81deae26701a22ef4ea519e654ad902495b1a1b03ed825004c897d482c7ba86e2427b755e502b4fa4ceb36e81ac145ce32fb3b04b10e10fcd66dd7e8c835800cd636488fe266a2c27e14d5767443846d5f9c527999ee2d6c23ca0bb7537401a4b8dd39409c6c7ab7e25fa084433c3f487e20f9205fb0823e7c842b6878d4caf4edf2e76d243378a0bbc5c97c44e9e674b3144ee6e025e9cfe0481d29742e9dbd025bf56f1a54a10bfd4bd7d96ef27e0f260dd9196110101f9971ba568f94db6ee04626532071fbfbbd92c38caf0118cc3eccf69cdd760bfd9bb5fddee1dedecd7f030000ffff1762fa26a9e31100", + "146f575b9993b4bbd5fff95d27c4337b": "1f8b08000000000000ffecbd0b73dbb6b238fe5568b6d787bc8169497e53653279b54d4f5e8d9db6a71eff5d585c49ac29920520db8acceffe1f60c13725cbb1939cdf1d672616160b2c80c562b15880807519447e7ce95cc2594207e7bff0384abc96b8ebebe313db49a67c6c1d1f774ec8bcb7b7ef0ea7d140047164011184d9f30bca0ceecd4d67930e4db7dbe9101574fee605c464b08bc10dff93847a39a4536611e79712daca218dce22c29984b67348a3b3880995d04e0e697416c1157a3787343a8b109184f67248a3758486b01daa11fb18d408059d810c1e605023101a996eb7dbc12022343491c12e06350221599b6e0f831a81502c835b18d4088424a3bbdb18d40884547007831aa1a08164487717831a81900aee61502310ba90c17d0c6a0442b267ba0718d40805f9b28c5e078388d090e455af8bc10d2a24d4cb219d328b188c25b495431aad233484b4640d7bdb18d408054128833b18d40884a28dc39f24b49b431a9d45d0a984f67248a3b308c5c6de7e0e697416313a93d0410e69741611483e6c757208d14584acf6563787343a8b88a4286ef57248a331424acad616063502211544aef00d5f25dbc9219d328b982a683787345a47680869c93edc42aee80ed490e4df16f243330fa1a1e4dcd601063502a1c074bbdb1d0c224243b2b2db5d0c6a044252fab77b18c42ed9deca219d328f90e2b4bd9d431aad233484b4a45c6fef60502314345225ec62502310f265700f831a8190ecc9ed7d0c6a0442f16423a44afd6c1f942374228c933cdce9601011088da5fcec7431a81108491eeef430a811084956ed6c6150231052656c635023109a6d50a9a876767248a35544209bbcb38b418d404805f730a811084951d9d9c72076c7ce410ee9943a42432af1df92ebbb1d0c22424372d8ef7631a8110a3a57397a18d40884ce65700b831a81906ce9ee3606350221d943bb3b18d40884a450eeee62502310920cddddc3a0462024c56a771f831aa1a0502a8bdd030c6a0442b28cbd0e0611a121c9cabd2e06350221c992bd1e063542411329317b5b18d40884a4c4ec6d6350231092bcdadbc1a0462024657a6f17831a8190e4d5de1e06350221297c7bfb18d4088454f000831b13c9a0fd4e0e61ca2c42e7c3c4b2fdfb5d0cea64082912d8e22cbf8222c9e3fd2d0c6a04429231fbdb18d408846433f77730b8a166f9fddd1cd22975848630b1e4c2fe1e0635424109dd08146e3f87341a2354790718d4088464630f3a18dc5033fe413787306516a121959849e939e86150231092127ab085418d50109763fa601b831a81906cfdc10e06350221293d07bb18d40884a4f41cec6150231092cd3cd8c7a04620f48f0c1e6050231062a6db43bb92b38dc18c8512ee9660953a8fd2106650c11e063502a10b19c4565f680442973288adbed40805092a833b18d4088440067731a8111a1232bca7c31a85e04806f731a811088d65f000831a8150b891481c9a900a427416a1905d1dd6280425ffd08e149a391afa24398986a4f8a4b998811319ded6613d55f5d084cc2274862c4e832acf74b4315019767348a331e25c06f730a81108a9baee63502310fa24830718ccaa8346a586317516a5f3aa0c1781447431a89329e86a23e13095b6500fadce2c422752713385dec2a04628e8d318db88a6a682343a8b18cb66a2c1a9208dce22841435343815a4d1bb693f5b7219d4025c70092fb2c0ee3310531619cc12769a2792987930b4d698135b9c809d67814be3256331b3cce7348a62610c83c83726b13f0dc1f897f9081e99ff32edbe18b3f8d210ce20f6c133dfbc7bf1f1f5cbd3b7ef8e4e7f7cf7f1ed0b93885497cb8fe124a5ce39ccb8972f0bedb9c6be3bfb1b0642612d6ea7843a0c781c5e80171170e02a8999e01e25d4097cafb7b79f92ed6eafb1bc34a71c0c2e583010669f39b2a97d5c7232ab6b132a7f766d1279ccdab349e831abd7b149e059cceaededd944fe746c9bc41eb376f66c32f098b5ddb3892f33eed82491bf5d9b4c3d661dd8fd108431f60621e5dc802b0191cf0dee3c8f27491c4124e60c221f58d148ee0c1850012f439840242ceefcc8e8480649340d43627e4c443001c324621c70276171c29d28f6e150c40c9ca9c2da69da1f7bd596138edd4649e451369a4a92dc09211a893109bde887ad27c29545789ec79f704f737b04e2dd65f49ec50930317b017cc08244c4cc92cc74793f185a66ac929a9e276609c443e3030c431888f57533ab4203e7f83088191560875e3d2aaf6f1f420ec6306696ac78e081aeee46b71f3cf63afd6063c3b6a807c7c189bdbe6e859e255b41add076a3c73220c984b6ab02b67d7d1de6121e3dde5a5f0fd7d7752b7d18061164add4f948985ac798c08a9c33db32733e9b36899cc10919a3ec4cbcb1eae8d17d76f46fc0b81c7e0b7a9a0b2aa6dcb9c054b2c7470f3dfee57b7c843d7ee68dc84c8ef42d9b0c3d666d6dd9e4c29b03762677e76110813b1710c9de713b694a68144ca8648d3bf7a70c439d948ce30b60ee3cc7be28e118f0248e7870014fdbd02f1f3afcee1dde1fc41117c6df193728e7c128b2e67c4043e0eefceae91570f7782e82c13977e7742ae2c3f32071d73a6442af8e64eceb601208779f0ce3481c069fc0dd279320fa100bdd53326101a564c402ff751049ea7ec09390cedcb56e9a9e90992eab3d01d15518d0303ca383f3c6d4a61bfe868ab143cfb805765ad4a95bafef36398351103d157f028bddb54e9a9ea444c4712882a4548a94657a0661a5b4acacbfbe9f0bc7a7827210fc18b2e0abc887ab1347e54b8defe7458d9c0b1a4ec14eff4ad3342517383f9ede416dce1c8afab205e13c8bfdd962ec512042d0caf60d704e47c08df7c08c4318c4916fda8d5c269fd03034b33cef0fdd45da39a45c9c4e127e3a01696a38938413d36921397428998f21188d85bbd32192816e2bc549c20f8105c0499cc86ee0eedfa96d4bbd7feabdbc496b9da2d63af44ec9bb07a5716f4ae3fc41697c33a571f5ed95c6f329631009e32848f88dda42265aae2e240b337d21c377541892444d639c6b8d71e5bdbb49635ca1c6f8e05d914b69e7746cf25aae85b66df2e64183dc9b0679fb1535081fc7977fbc96c38bcb81fd8515ca6baba452ecb456ebadb28ef9824aa45c0bad466a7ae4d52a7a4426046fd93a6c0293fe97365126319b191fa59d6212d330c96b0b9c31d0e43488a61c1ee5901fc2860e33088172f0ed47e04c4e7942239d5882033a18430e734107e7a77cc6ed9b54d94fcf8de7b3811453c324e044d3c9e968404cc37a4db9401462945a4be894c3e968b0d9855d624eb86d6c18587ff367a0899b015221613655731cfa9c98c478156d7ce48a64b5c5b6447e00418308fc2aba8d05c43cb9930106939a3a7dabd5e92befcd4deaf415aad3f7de2b2574cfef3079f98bc4c91c6f653df482f2f1594c599b119bc806abe2dfd209b8e6e46c63cb4c1bc9a64ba4f63ec4f96decc3c2f9500faac06faf7e6b010b2b7c291b7c41594023e19ac370cac72dedbd74a8f34ac0a49d0646db76cbd8f8a2e59ee5e5daad85dfb5330f33faf74ef9c317a3fc3ee7499af69f3f18235fdee9f51cb5d70b69081ed8e4933404776c72247f7b388d3e5da2d194a9c3a603c94f7bcea70930cb719cbc7b6c5402d3c4a7020e81b2c1d803eff1bca41ae02a0963062cf37217292d7004652310d92a0189c1150ca6156ae6cb4800333dcf03e71c66ebeb0bc97395e96934b3ec342ddb0073c4b8403010442357a4de22428b0c82baabf7be07c8d16af93fc964494807308e431f986b3ef57d069c1b313326e8103102df24a6d4611bcaa6328b44cd14be1a3667e09fcd4cd73ca33c186c50df8fa3ae4954e7b840e2e8f9984623701b5d4ee2e8df30fb98b8cdfe237ec0e95908be2b525b0ffca70f03ff8b0efc0aa222d69956788a5ae147a9057677510dfcbca2353d9ff0117f1d5cc08f00be0bb71f43ff25568c6c8221db7037436b7ec5dd6eaf8933c7bb66cd43d952d08f0b2d423106ea9b8b906c2126cb63be6a758316f8dfe4b036db6679539cc5fe4ca783cc8049d3fecf0f03f71b0fdc9f71acfef685172147341a8560bcd455f8024b1133c9cac27942768941717e82f234c69d56197d8a966423fee705f1358fde3890ccc3d619c124c154cadf6204dc1803bd08c29911443c0918f8c6d9cc309b34a949e6630643d71c0b91707773538c4128de39311b992931ab11b6720ccaa1f4dbc350faf2c6ef6f38cd3d93d3dc5e1787ce3f0fd6eeca33f53339c883486d88af7508e5aee907178bec512942ae29e04a98cb6cc58ad9aa07bf1883813ac7719cc2e22ce91763c236f864a367960cca256667aa06d93f0f83ec1bcf57ffe008fc48bef798b5b56b939f3c666defdbe457f96bf7d78a0eb2e7700ccea1721f799d13cfc4a04964f49bf7876fd4f60af7ba279e59801a8d7385d793380c23e22d04a3f159cc242dee6d9d7866250613bd60d1c8db3ef14c19c0a8a320e159813b279e598231c16fc0045c79bb279e89c13cdfab68187b7b984786cdd4fa787d6d7df4e6a98d2ae8776f5e3ac8f76ff48dff7e0c279e288eeefd2239e24308020c894b251fff207f3659f6820aaa182603ba767200294ea195a7227fa4d30108c5230c965adfed76b3f6a7d61fd7d7d61faabaa451160ce93414581c8691caf33355dcf33333b5febcbeb6fec4e6ca4affc7635677df26000fc3f1eec391882a1bd5f9cecf6aef0404f5a9a0b6ae403d5e514f096bebb6acce7069b1eb6b8b79ef593c0938d8b665e5a92989ec792ed0a19421c166f3d8e24e0457426d2e0da89053a33d97229616e21f9453ab53a84b93c7f969d83e387e1cc1139aef1ab996f074980869d2091a0d242398142fb83458a9ce52ce2d61a7b66d3b620c911592c04e63cbe21e7768928433c904f535a48dadb065e2140fa2427374be8dc58ff134f2d5f0c80033b5385c5f5b1c7098a04942a162814806c8892da402b838cdec61eff8042d87091f79ca9c5590b49d4be03f5360b3d330a67e108dbcb56e39165839255a089e6996c153065c8ef37ab232b1dcfaf02cdb7bccc092b1e4220e7ca393fde48cfd5f4bb7a66c0b04d1c85aebd87dd9cfb84f370b20f48d21c85efe6b9326c12696b2f9fdbc5466fa974d844e0bcedf3c8e2cbbdfa0fe41354176662e35a534bf4a56e011682949b6b6ed187010da1893cd9aafcc94b4691c620d0a13b14a069a34d4f420bc527cffc63e72b4603cc1fac753919987ea6bddbf36b38979532794bc4cffb2dd16527a017633299db0426a59faedceb64edbc2a63a833c6849241904dee31acb2a3cccac00b8ad342a59788d63a52290a245200b2e42fa972d679bedceb6e779426f7d65ea5495d92e70bc500b6811305d8e681166dd2a8bdd4a8ef5e0c46efac21c2984e1eb7044b7ea961c5123bb34a6abeab3aa192bf25762e2bc50b5b058a3d6756f855a4948e7fc3290d5cfab730b9a049c84ce247c2aa7757b3ea01c8c3f9435a737c111ede5094939dae1d3b33201f2a7f3fc4c8b4e8ef12a397c168d74b87fc6809ef77599cac65c50689646daa6ae0ea3f5e9fa683f2ec89856b85696c75c0d5479028df44a068a6e2bd80acbe6c8169d4e7d3f737897bb6fa32b85bc658a768641e4abf32c96f01e0b27f0e55a3ef0a549d89a1e8dc8c75eb7a357fbf5047c1c0c85a525b98e54ca569dd4a9eb610fc8bfad8fd9f2685163ec7404c228bbf5f37333c7277d69ec96a6a5f6aa6f74fb42dabf626303b3b2d6d4c7e2a4af2787569ff6fc1c662e7302bfc59f2e1679c3ffe3bc0ea2733217b1db3ad9297a7fa544fe4ae1e682591db2b5835e6dad9b204d01ace35f9df88c03bba06721100196e9030f46912b8788499e324667f609a1e0242c16b11a3866ad8da6d6ad72c173134165f7cdd306c9091fdd0719a9a86e43e7591c8740a3069dca40b90d415ccb2ca007ec56953b142c88460d5a385cef835b1553e83ed8966b927b6099d68af740a950ef75625459022b132a99ca77a4d4b499ef91e03d926ae9cacfe1d9bdd4485b25f7422b7799dd03adf24c7d7f04d5547e4772cd89af4e70104f92a9007f21c93222a18c4e24969be4f8a44d85e7d3294e5ce80d8bc0a34042f098b5d7b549006a73028dde1856dd83d7237895ed77585fffd2a758c019c49180489c0ab5c16e6627437304ee1fc70f1ec0fb77c8b7fadd6340891adc5ea2483141acb267f415c4abed74e62244e940a672671bba29069f9ea90d2a2595f5c58f69b46e32dfb906afb4b3d178f5020bcebc8fa781af0bb59bd5f13cb9187bf2dfcad60f7295aeceffcaa5465434e45b55e83d838b209e72e3301845544c199e4e76120617a73c187df30ad6eaf5df50a51701172c3893b39df17e7a160603e3df30c3faf9c979563fdbfd2f9542d136e508e76c2680e7959773cee061cef94a73ce00d0c2f1a549d3b149a24c9b5d7d93c6f4ff51dbe6b39512551f187650ef270a3a0dfcd3ce179b6c7489dd7a89dd6fae6c8e188d385aebf94c28aeca73e0bd1f2ff3830b93ccb99885e0ce27948d82e8592c443c71cd5e27b93249427db944c922bb2af22c663eb03c617265f0380c7ce33b0030d3544ee8c95470b7e5405c5deee45c2fd33a139a58e03daea71f03996bc7b90bd9c60b39875901a50b3f5a994f7cd7a45311b7f0c407e7cc79cfe28bc00746e67896663e88c398b9e6779d0eed0c8726e1c12770cd1e4c64b356e1de519cb8e6b6e4524b86047447dcee339b2fd54befa662f56e8a3171d64fe09cd1509a682a42343b6e02e8a6d4e7b848b31335019e1d7997269e4f056d2aabaf36db534171d8c97ae4f3639af6a70fd3e3579a1ea790edf38fe1b30eeede8f4ebc850bbdb4c95bccc3996efa2b25cd58142a6ce5e4ff702b6f53ea8bcab7847c3a1800e766856ea630b44631abdf56e658a5c391c5eacaaa6516d5200bbd08fc37f13412d9fe6edb39d2922737db635a7cdc34db8f2e259b5031183bca21a6befc4cf3d27f0fc2f0633459a90296da873a8c68c2c7b17806c398c147e5022c7f3d6e40bdb835cf5b5c971b4fcfaed01cd5afb26eefd1323d9a2560d995dddb36fa133e5ab0472bb531b606cfec55375235064feef5cbfbba591e168d7284de4cd5287db0af9fedadeae88fd179145f4666764a5837e44e8d282ad418c303d00ecf967635124f6b8997ec142fa0106b0ab533d0417d0951ee57329ff0912b48656bcb6524df9a72e98dcb0fb37bc77fea8c77c3cfb3ca071a3f41043ce046e6c86ed148f90716af2275be5addfe1205d148420c8c4bca55fc084939a66dbbf4b32aa32b6144b130e8050d427a1682b1616c77b697562ccb771988b1f1ea85b44f88a9a80ce369e4ab1adda13ecbca4625ab14eded9790e699fefcaaed339384462b4d0461301a0b93546cdf0fea2a836e47ad34389f2ad7e15130517ea300ac082e8d17521f7661eb7f8513e824a7229800177492d8c4f47d67327166b3d9ccf8f967f7cd1b9773b365c26aab4c4acc43694807c360809fc22c2e9b5712ae500369067f06afbfde721dddc447da47ac867e5de537d95877f4c13f53909df6763a3903a6dd7d3af2345291371391acd55965f089f91fe0a66bbe8dbfed2a5e4a24b086b73050d1a7898a3e3d87d98d0dccc67dd32d8ae0376a6599ba802bb1a10e39c9519179563275ab9d1866cb3761371d46118e60d3e83c3b2d728a47539ab1b7bfafe28e8debdd4be3ce188d06e346eb1ad15fe64a0c73bc6d56c773aba7ed1b8a923e8958b1c1ee8717aca95b4390348acb4b4d749c98a95efb8f1ed6fedffafba891f6999fe131007d23c7ecdbacecb273b5cb5676df6085b642b57085761beb5f2ee53fd7fc2791777c4242f9275037a9bfa18914f2fc4b9acf315ab3bb396e6b4467f95a8c67592761cfb3039ce075faf083d00ecfd3c0cf86761f1e3dca4f6d96d0c77042a8671e2610093925849ef93c8e86613010925bc690861ccc3e730671c4a71360a703298f4f2cfac833059b8249eab8c75d3508ab745452b9fa78e4999aa63a0d937d02e81ab290201a84532e8d4d2ea850274b86019b80ff247ee499460e1aa6db4ccc408ec42c6d0619a6abe00422d9ff06963b289f7a655ea7cf7ea871a570c96806b28c81b4cec03ce9313b21915448ce98728b6a67cefaba157981d4a079944d3a5e834a958bebeb75fc42e6acaf070e2fa8138a3ea647914d06ed07718b49ec1c66aeced7b24750f9a0fe396e2f28ab212b0a5758b8f6cf30fa1e3f3b8d56297cc149e072c94b1c717a1b40da3358bc2497adfb6cd259f358db32a6398f9669aeb8406aa5bcfaeaac5462bc144b9762db16a8a5b63c43d1d4dc1928ab207086317b4907634ba974eff13c5ca5a7445a9501d1d2fb60db697edefa2e2a126139a9b4f45569016e5a7259d15077c434de4d93a9e0762beb1b2e023b2feec6233959c252a1ebebdd4ec7abc6e98a346b7f069565f925655110a97b24ded02bc7e8763a86deae322803838fe3cba8eda6d97bb370cda7f95494ef6a616f763ccf8abdd0d66d7962c2241133d38dbf94c5ddbc8f2fdbe7337c10340875c5a2d6632b5fda9c56565c9ca6fdd98351fdad8dea993efc385cf9c849765dc6428371d10d199f7199ce8d16ddd1180cac90711150e35fcab2fb97e107be32eff0bb381acd0cfc5281eb1b65860f82f7ad056fa85773177235b7b38352f872f962ee5637ce447efdbe99a1da21a9de3613f937dd35a3e92cbb69a64c9843e47f807fac8cce99885e964815df542ecbbac2a6603963b625581ba7917faa966e502cd562b990e368c2bbac32844b04ff5fbdd171c11d8e77bfb831f217dc9f13f9c51d3bacfd0cd25d997251b57312164c289b65a792f8c42467613c3877d73ab2f2613038775b042f6f60a9bac49418e5f633cd7613f1b695379fc7d3d08ffe250c06ff4c810b63388d7c7c11001d692f1f54ef5754bda5419d29de977ac6ff7ba519ff0e73f94ff1e138984c80197aa7fd4bde8cf7130843c4e7107163c8e289daad2d2a806c586bf570bfd43be25238ff7e10ceaf70d5dcdf7aea3f7de0f6fd3db171080f6f6c7ce33736deadba865af4c846a4ef5bd3cfe3a84df5b22b3ff021128198d94478e00cf05d9effeeab839bf3c38e997d9512f85fc9fda16e63444fe84d2f1398ef58300aa2cc35e70ce228022532a7b1c2dcf96d84db54461bb0b8e75f3a37fa057683f31b98df82b88cd9b9611d5d6d7eb8b25b666d751e2609c250aa90e6b998a358d010df29d11f199d5eb24008886c621a9b1504032a85a06d03fd8652f4ab54d97b287a30bc05f1eaddfa7a1576c45551f20d49d9550b77cb8fa76ce9c753e46815afded5de4a3984b4b802fa1d78a770d364f84e9b63e7b7501ec727d9a05f4d8de46e6aa955bdc7f305d78abcd3a7f519c9148d5ad3a44d86ac62fe659747727c23076f6de9dcec8586dcf5bcdce79c49403833f42005dfc89ace1dd326ea81e0f30723e32b9874e7daa4bb52de9c7d9b7c908103fdadfee5bdb9757e03268201e0d45ff7ef5c047c4ac3e053f546e14a9605ce1ef578d307e0d309fc9613b9897c2993b5fcaab665d55b7ae171766da0ff73301a2bd577a32faa5e4a93445e59118f46213ca383f391fa38f90515f4791c8638df355c55858219e844d1e8492b7e1a3118055c00fb99467e088c5b76fb6b53cd7425df57fba18d46030565b24d37bbcc9a39e3a47ad26369c52adeb50b2d552e10b57b899bcdcab9162a55e4b23c784a9384c517c0b84e451b28c85011b928cbab1b12f55e222203a264ce77637d57b53ba8b8f06a0d24f3dafbacee98145de74ed2562bf42eeefb62f0acb6d8ef2e792862a7896af10f764b8eb0d60cce7b060944fe428fa373045782cc03df3533d66f8492f7d2cac89487a17aa36d3e6a3a233133c12bbef11c6be65f0c1d11e3dd4c96ddea6aac28ab9a37b356bb56a766bd052d15fefa4cd41797ebbb9f57e261765355f99e7464e160d97de90b189651abf8709b8a71394735917b61e907e5d3152c188d80b9c7a67a1ddd24e6301e4cb97982f7becb94aec9f0ecbb4c2097cd754a578a92e47b122732d186f26bb79429533acff122003d5c5f467cca801b624c851147e1cc90a6ad1101f8e0ab5726c4188c42ab180137b40201756aaa594acd5b1d4f451844b0c1d55bd3ca6f5d71522f9f82ca2c9c3c310f459c18455a4326368ad4a66b6aa09c48b6a8d58ecc3f4cf8bfd39fefe5ecc03799b249b8811396fe8ac518319a8c97755aa5635a2da2d29ec3921e4e49fcc4c4acc687ac0aa68bb52bc52cfe62fb8abb73b92a7077483c1c72106eafedcbeb64d9c723d9ca517f3472964b846b7eb73bd8eb0eb64da23ff4be1c07023f86562796cc15d6a36d547b94760ff65ba87e8cf85de80eceb6cfbabb2d748f82e473699eedec1f743aad75c5afdf960d98625ad43704059f8098c4c8de7e0e24a058b9a99beee231a7cd2cf5862026d10fa2eaf7e5c7eaf1f865851e6696956112d6385ef479375b763bb6ed9a1b2defd5940a7e9a996f9b4f336badbd0ee5a52c55cd8d24f5cd1be81fb16974bef94c9dfbcf8edfadaf33fd9d43e0cbb0fe2a20f09716ba8c29c666f18acf66feac9de24c5610f22783aa5c52cdf94cfa79e5b1801cac96a03aa2f58d2dbcfaa0a4908b2929ff2aec93f2d7ba1b5d92c43cc04347f48cc7e1548049449cb81d12c250b81d7219f862ec9add4ee77f4ca2dd3a1aaa0c12390b826fa64499354591f860cae58363e1fe1d0bb5154c7d3bb3e177b8d4deb3d7377bcf5ec0c5511c87963defdcb4c42caf749567a9bcfa5bb03c6a0ae9208ed49bcdac65f28ea58286ab844a410b4726391be59f39d63f7bac1a22dbedd41ca93efcface6b8b1a1fd46d1bb6b1e072949fd4e07e9eb5428d7273d3cfdf5c6ee61838141542769346fe3c73b31eedd473ffddcdd473ffe2ead433fd7433f1e235b7556997f5c34dd4cbcbe455e9e316f6cdb4b3bdf616c2b13218c390261c2a32f0f7948b6038dbd0d7846d40d4d6bbff2cf88e37ce967faa026bade3e812ce783c3807f13c73d5361dc1d5cf6c7db9c493bc347f3f5467f97227ef5abbe5f8bd336a9f04bf777c39d6e840486b28a152f797c498e4cac07ddee2ea6ecd5d886929f739ac9abd619eb841a51ea3db53ca6ee6a8519add9ed276677bd3cd56cc05a5e1ad299573ffb66ae6f2cc5e64bf5cb9703d4c4a79ff6ecf3b68ea33bbe20b1c8c83d0671095bf43cce7106900bc7e3000bee249a6d24dfdd9e4ff1a6c7df8e14d76f8c10a9c712c6ccb9a8f032e62367321b59bf752bd06524e807b176fd596c5ae4d5e3d74ec7d3cbef5feeb3ebea52f8c7a0e737da9d20ba8ed2de1db213051df217e82ecf2a54f798ea33cf4b4356feefbcadf958a70b3fc3488bde39394fa3e3e7ca71eb47204f702b05e50014e145f5a36318bef98489560f62e453d5a6f9bfe067a8fa7c0e8572ecaaf209537b2fb227b3fa3a862835a09557934a314afea256c7cf642175018c1d53a1db7567ea37ba232a383e835e5a27a08a691be2707c69a053f746cbbbd1c38295747b5b75e2744e97616453f998b2bb79ca27a4061a396bc8a25ac352f03ea2fc828514470b7f4c95b59085237bb2dc9281d26c8d9533bcf95921f81fc0c9679746512938dcea8b5b3458cee7e8718bdee01e9daadd11d675b6da48b85f43ee4f47a5b3bc4e86e6d1363a767b745e6d458f9c34fee75fafc877669ebf3d2f79ed514c7fca4cf50c2a8237876f55f1e736513518ad9a00ebbca3e8ac3f35cdc65243bb9e51e031127699abeaabff6f07ed1db244f2bb7d0e7f2555c75ffb9a48a36d669e5d7e6372865d7e6bf5f726d7ea3944c66b25bf3713afc113c7ddecd7c150de2897a5e409d5a393e2143ed160c83088e20e278c0af707ce84f135190f689b1db214677af8b3dafef93fc5d7950ba1a5a94a39ba77f4e9343e5a631cfa64264b1727d286b5440efd0dbdbd151bfc441a4f34d02214dc2240e22f1ecc6523159bd49df0d87c30a89ac192aeae7f8025823cf62f298be51955eaf43b2ff6d69b1cc1ec67fa07e30e56e47a70ab2885ea7944fc7ed94de41fd19aa4724756f43dec9f5ee6495ae124d3e8a254c10b769709aa20cfe06de41a7a327e567add329be78a666e317fac1a5e63a317f6baab697adb23d87da84594a503cfe58c2c2a481ad9f9652847f75dee583fe0d4d4a3550dbf1a52a1c35aa504ad1a8837a2aab932d29aa470cf0c0c5bfad8ffa61dfca89127c1c0e5fa8ca1ff425e567d6f268ab944fce4505427d55ac68545ef62d179421740998baf4a22fa9112f5095733acff3e65a6b9dfc704ce3580836f997bcc98d062e6a8a4d7ea9b702a34a555d58a16ef5b44e812a4eec94baabfac0e2ef70765813d0ec89b516d985661faa32409aa1b7b10fcb92bbd828aca4aa5874ed49d0e89475c95e42d4554c9788846a80b4d0405b67da046d5c04018d1b1fb807c7ec84e48640cb69677545499f5e5f5b540dafa76013ea148635b7db47adbab8416626545a0dfa7c63e0dba9ac14aa2430e2a1d19efb1c66dcb26d819743f8c02db0afafdbd3e243d31654a5a8229e8a47c8165453f9794d67927029162b747e5de109228a37f6aa452d5682cb84a5946a91b09492e8154aa3d1c588abb5fa08fac291caf036ed2dab57b14cb32e695825d9829655d2e8454edaae9795f35f7d60b984cff73ed92c9c4fd27c4f62bed67453a0a17d19447e7ce98431dea84122cfbce4aed937c74224dc353dcfa368490ee250ddab625e72750778f4c8333737cd47d419c75c3c0235b84355cd5cf55991dd0f9d388a13883c41647010c61c3ca6c2ea33538fabf0a4f404244ac62f87efde3a09651c2c34f7e55ae2f763e1489bf6a4cfd6d7998556bf9da696b979c94d226789a53a584e32aba4eaae984abff298f01557646fde1f66aba5dd3d62740f768971505e9195638b0559f3ee9c9bc67159972e4e7ccc4efab90eac2facb85441f56594282fa34e52d57c2977abae488384e7cbc51d69296f7788b1d52971a012bd3a0b5a86fc121e9453dfc0049974152ee4aefe9c153a0fa2a789082690310847619f7bea53a16118c7cc2a4dac0ea6deecc29694fa5222beb9dbb109ff1f6fb7434419c11482290454c86ef6b66d22fec7eb6df771d09b6636cb743d0fd6d72dfac88347a6f182ce8861da04d48552452457b1e2b1d7c168f143b7f3c4ec988fc423d3355df5d7262cc7b30ccf149e219ee7789ee1b9cb6d427108c1644511fa1968623c0dc37890494c77779f18526af6764b72548ebdd9b5a1a8be8a363e72c805b1d723c6f60131f6f7cae2598a2d7c1ccbc9fa61936877bfd74655466764f972b21f2004cac1af0c9cbd5d62f4767af5f1944567a4e942d287820eceabfcddd9963aa92b97b55b65e751393a231c2d1efab1a061bde33ad845b2afca3d578ace0887650d10789d7ed050820dcbb71f640a206e28c122f17170d2d7f731c58df11f3b63a0c9299ff1aa8f49c707d194834d580bc60fc126bc8960badba4b95a4672c9782c28aa22660dfd1396f44f44b436217435a7d60bb04fc8b3eaf3a54aebdcc69d553ccf5aa5d45cdbdc86eaf366d56ac6ede7b8dc9eb57befca13e1bd922d44eb3664f307369fd57c775543f036248f16b0b334fbdd67c3cb93ea7dc852b1b6ae53d38f94aecac3faf27d55723f6aab7999afb58cc2418a797509f5aae8b76af180c41d1ad33447ef854787ad8ae0b348d5bc01f742b3b276be23c5f2daf8de2a57ac71efd79f5f2d2f5f6f5405e93e8b286cfa2f5746cd62fe7205a135fde5e8e7c66bf94de27fc07b06e4e3c31181fb3822f0fd373922f053753702b45f27a402a451c24785bf66c2471ede5620a1ca0dc8f9c6447eb9562965e9fd6ce5fbd8e87afa5ee75229ce30887c756cd912de63fd42ace70106ec6c03bf9c433bbdbc6e477bbdcac88aabab8cd0aebbdcc1551ca5f14079dc5fb068d4a8b8768294dee62e7f809ed9eca2d9ac5c8ce4dab22f3636f20b936b298fc5497fc1b7e8a6606676b1ad6247cbf71f423f164e58fe5670cbe1f1522ae4ebf22434f2e349049c2f4f573ce261e7f7b4429a7eac5b45df2fb2b67eaad96f39538a19e666624a9ee76983dc848f6e43a6b0d4aa642af27e1b82f984da460f18abd3d213f3aa744a425aa794ebff45b4ca8886fe6f70b1f559fa5f81fc0ede4f40fefd300bdcc72cf0cbd79d05c81f6ddd96d5192e2d767d6d31ef3d8b270107dbb6ac3c3525913dcf77e1433575b0d93cb6b813c195503a7640c5406adb7964819da679eaa09c5a8c597cb934792ce36497883e387e1cc1139adf3be45ac2d361228c4cf7c5438349f1824b8395ea0cf61c2c61a7b66d3b620c911592c04e63cbe21e7768928433c984ebebe313dbc656d83271da5fab903806e76d2c7e545354e7c43333c04cad5fe1fadafa15bc796a67cf36fed93ec5e677527aa649f298f2648a7760f269281af32eee2b94337e807fd40ef21ff8249d5605d94fce82ffcd766e8aeb1cf5c6745ff6074e697855ec10646ffcb54993401f25cede3accab9efea51e0be8753a6b72ae461f4b2671aae85259bfca9abf9415b77e2d18989ddac332c1f99bc79165f73988a36002f15458c5dd0b459d912d6a9faa075b25c9692f4f4a93ddb81355f336df345cc27f68580b8e3e338b53f6e27721cbbc4a17dfca5a480334525576e3b34a429b38e4bb761c44e9ce8a82782147f5c6b612aa337231afcad9a1cdb64ad37fd7a7ca5fead3125e07609f903fabaebbacfac5047733ad621e6f12abcce037932a2c8b2629948fdb505bd0c81203ebd4b445d0a0945b047fb6b9391656eeb3c9dd1ba116fedf9296f631dd437d0ae1cec929c3e63fe0fd090484c7acad9e4d84f0981359206cc2c483a5730f960e17df62bd4b4576acbd76dd52367764775c2c3e8d50b994c6ebee74f419b6d2dd379e8e2aeeabc962b2ccd959d477cc07563f30519a81da6fcdc9a82dba3aa781bf08e8e9200c06e74dd27895dfa9fafabdc8a72e6dcaec0bbc6927cfda7eb193ce038e60c1c45a726b939a9782212ee8072150967dcd6ed9fa9339cc553e53a50fc867ecd38794085a46fde25c1333e2a1017630b4e442d887ab77ba204df2b1d7b1e7c2637df5b25a9a9d8acf9aa4eb512d4bdd3c6993e2ac5ce942886a6b90519593faf8b1143087e9dbb19496b1aa7cb5fbd5b40a915fc7a45375d2156effaa0a271487a4f0c699fcc05a59dcaa67d79a6d07750e4d3d0ab5269c809f2a495f5f8752d82a10f9a1ced28078f4c8ce1f2b0c7c2524182c1ef953d17998802794929a974b69925d32aab2237d819f9d781ac3e01caf3eb3973436ab9a4d582b3eafa38d1f96c8fa8920c987479e9c4bb971641b6d9bb0f57529924b92aa6786986da74d946c04c9be88f119bdc4de2c8ea051df3f0a9257d130be430f8beb6b0b8fab51a1ae24f554b9377158b473d8aeabc0471ee8f63fe9ba19d79e6c74dd0ec97998a558ccc9060ff2b36a45e13828a552e82fa9bcf61f36874dbff24d4e7be6dcbfd8c64d3d9c3315bbbe0e99c7338b2adeafab2bc02ab9fc7ca57e5856dd5bc360125fc0dbd8474465f035c7c8c646ce5e8d2cba44e2143b5531d98d1eaf83e8dc12a571b0384d3116ec345d946ed129d976ce65aedecfe3de1d19d164fc62cea775512c4ef6659a03738d4060964c8f326d6b28b43eed2b537c7c8569f021342fd6171e2be8c798612987826615f358aaec38512e8dfa7e5e1a01bbbf5668b4eb6be1844174ced7d775c0e1f104d0e33e64f1e495afee51cc7b5e1ffbcd09ab5e2f296f54ae4584f202e432b1be6ead95c0554b2f646a41f1a54942dd9b9c92456c923d02ebeb569905e5029ee41a29bf5ac82de69b27f9ed48c58d46a5fb82b2c36cacbcd4ce2db84e496e3c211ceafc84c220ffeaf907ca88df02b8742ee16c14fea4c5c2cabe6112e574afe92c9e0a6718b301bc0858c96051a4c99c277281f95a6937b7db21083f8f613874bbb0b14db890f6ecd198011fc7a1ef3add1d3262f422103377a3477c46756aa7d3232298c0a180c4edc91681a0aeb39fda7d50171a5892bfea24cf93d6961cfe33a50cac5e67610f65075f6d771981ee0a04a41c4aa952fea25662af83082cf3bb9dfd5dd8db316dec03e6f9f1402dd9e428d4db1bcf66affcf2052c66cd406bf45b86a874447ee989cb4836d45d20a1ea4057a47255999351357c152553f1f242ae1f2d280990ed4ce2290775d5a9551c726f9b3a6a96ace64eaa29bc067a010b29a46565a73e6f20351b761a1596bd889336c1efd6f2f8014fe2c29ac50151f8a16a6b8b4cc5973d55b7595761931a77d06aa2d9db8495c9a85a2e2c5e39ad897e69efae45b713ee2dd5ebfd252b2f2ddc8417cadffc6e7fe740aa1a9b70755598b7d5e907a22c638c94d65fed6bc5478f52b2d629d2952b27156a73d231bff3b7b676f77ba69daae33f2b1709e522bbb72b526b552cb2ecc794197849d090effa1a6f352354fcfb2b1798a981b49840caa3a1bab0bbff85f8f5f55a05d3b2d8ad4a58dd025296442ec5256f7bc1b5ea32a7452a9b348566d16249552fee7f02af579745501d7e7b61cb3ba245d8729ab794a62acda66659b8fb8f334b6dd59c7ff9271758f505979da64cd49cbe5c2c724146a2ec82ccb456e1c9bc3329bc9cf7eef44a5af71ea8150afb36c4684bb5a0fe5dfae7b770c198fe02a4e13348e7fb0475d2781bd1ea848a9d902a259c79eb94b4137dd596967d817724d57415de9160c94d772fadfc6dd910bb25c55cb7dc9d8ed643772454784fee48a8b9febf27116b1ff8b76d66798eafeef884c28b4471af4020acfcab03699e46def1893d8fb20f24f5c7801de57bee47993729ecdbf36cd1161d878f1e9da805bf25b2fb5bd63a756fb55e0cdb747d9d5acc26fcfa9a39227ee5ab17a1e592352a7d8a9bdb034caf996dfb095f5f67c50a5a28f7c8da824c92b06dafaf47997bb48e725b305949e53319425a5b685e743bdbddedadad1db565a56f79cfb769720b05149a2bb55642afaf2b77fdb65afb670f5c5be081c340dd156d6d5ac7ffdf7727f6e68898df77bfef9ab64d0e4aa96de1a96f285f45c282ec1ad5ae4dbabbb8cd258db8bdb572fa318b2fffa5ee6d30e02ac1d75282c818c395318cd9840ae3321063236130007ce0ff3bd3315e3a23c7f8aed3190e3b1dc7f8291606dec26efceb11f417d7e1871ff6af7b3b3bd9c138a1ef8418a0a7f52d381f0a2384f8c29b978c127720487e0b983acdf20f90ca13b22a32026b206ce2b3685444fe8e91a5570f55f47f30ba76b9a8428542a2529264df9059a1436dcb26d33ce22d387c160d7ec6b30fbf0762acb2db5622c840d87daad77d8d338c914349e3b3295fb4dd4657ba8f6c2a9a471ddf54f172e1bf7005cfe258a8578ec9f1f176b747baa477727262f7ffff000000ffff24a95f17beee0000", + "2968a8ec00c8e84bb194cd1ade785253": "1f8b08000000000000ffecbd8b5fdb38b638feaf68997b97303579f0283494d9b51d1352080102653aa5bf5ec756128363b9b6f2a05cfef7df4747b22d3ff2a053b8bbfb9ddebb4c224b4747e77d8e64e5716d8283d021de5a7d5b590bc938b070b856ffbc36c53ddfb4eeeb954aa55c317dbf6291914f3cecd1b07274aeb3ff95432b0cd79455bab6281e41f77f60bc839f39a6a8bbeafb1c5eafffce5cd421fb6c643a1e1fb9bdb5bd33f76911c891135a959b6e99163e0d2909705851c794f818078e37e8b296320d674bd62b0da99c111b7f74f0f499c3a4cf2b8c6404d689d7771d8baed83de2c7cabde7f5647c99f34850f0e85c9f4b39e0cf8f9306f8bebffb6ef74f8cff1166c2bcb5bdbd42495d65f073180a936df5f0de7307adc858ae76dbe6dbb52fca9a678eb8bdc0339f04a0195fbf7ed5bbddafa71db5615c7e55cf5b5f5bedf3cee5d5d7af5fd794357f1c0ed794b511b1c72e3304ce9ab266faecaf453c8a3d0a1070d88e3ad8b86f8e5dd64c7cea108f4de112cb74d9879b6e3b1c5c3df8ace3d0f46c1707ac39c00327a43838e64d6c3edeadd5483aae296b67d8190c7b04c6d0a1c3fee3786bca5a17c37c63f6d72336660f3ca9af453c0f5b113683c0f4878c55aa459d89b06e21b1ee31d579476caf296b2176f998b81b6fc1366375e66bcb9371939f74c6547ee40778e2e0690cc20c2c46df01a64763d705506ccde1900434fed6971f4d4c770c2b0ca919d0f0c6a10cc0d8b74d8a6f70af9b5b88252f8a8d8968b0a6ac35c57fe1bb6331b08c329c2603b79934bbe60327f069f4a14f020b379c2086ed334538c5de0030e25f7582fb7d261681197f0ea9d973f1d530c0e190b8369f7ee2d007c6566784bb14fbc0614c4d20191904e6887573d794b5deb8df0769605215f114b0bda60e4899657a1333bc716cc0837f3b663c6058d3c0f4c23e09183c27d4e161c3096072909da36ef4e963fc4927639074d7f1eea3d94e1d8fb310f8741e23794740268f5c62d2ed2d3508cc0740d68485ba3a539b198da03004036c5209c03894be0c303d95d6893d46ba8f38a078a6521a38bd688209b49d1320c038a464c49f8f29080b9f448b68e793d06130c502af5bbc8dd1c49ec1df35658d7d78000172091b143adf3168ab6703909ee3d93144f5f252fdf455bb3e3a322e632e354ce060e3d399da6ee95f1b97ea0d5ba0e73006b44d1a38b39dfe2469da02f1b0028cbd2e9f6c222df59c381e85c98e4e3bead59ab2a67dba32ba5fcf8dcbafc6a9d136ceaeb8a44d81286c35e79dd6d95537d68f2b89f91e9eca5f790731ab87a77a4a88e286588e3841851e7bfc3f7846b167471c09f0884ca21e16f11fe0c13957c000fbae693146fb38a00e0e93b6c8be78b199b8c1bde6a9ee04165858cced2cb1c6236e7f07981a2e665fb487961d730828c5acb4e978f099379f3ade3d88d284b989480e5b9e3fa646d464b98e751f9b5e864537b286e00cc62136042be0cb2936c1428e3d1bf71d0fcc4130f6c03e3bd431dd46604e235bd327816182d5bbc78c4e23d3176c13cb2589c9048b67daf62957bc9012e8eb843e0971c2b5c88c727b2ac0d0c0618c259e6a47241d85035895700a210152ba64c06711fa1619b8d0198d5d9382ec13ef5266a78d5d4c01574f98da33e177784ccea637830116ece17602ba379cd04a8fc03327a4cc72f235320cf8272e4049b398db8c97c357cfbe5c3bba5052d10f349a3f670092e78eadc25f8d93401835e82e66e6c6c00c421c8d0987647aec0c86ae90fd1e1e38de35004ff829f074bc14efb067c71d031c9b8e0087989e335f48c6214c03b4bb777cd57505244ad8876387ab963d88d189989ef2c689a86a634a89d7f17421c43812e8b8afe3793838be6a9fc2136c0659094f2426c5f50cabf3acf44db016c4ebf8d8e3d2e17241259e110444b82da6748e6793a9e4c5d8ba0287bb3b4a2cc23cc39084e028426e03b86b076024826fc5f0b1804fbc110e4373c05a3f743b67113399d472734c790076ee7883243c90e107381cbb6008dcc89b53724aa638d0cd9013d0c6b34e1f042914f60fd81dd9be7e4046d1c476c43761dfa2f61618af70dc0b29582ad70cc3337384390d7c06d7cc6467804897061cf344d44e9d308afdc0009298f9922d913ab18f22cea1e43cc09613721600822c28012985508b831b9ade400efad81a7d2b428a4ba43e0e02ecd1284807d346c12ef966608e224245cf9b017859d6d4c0d4e4b18bebdcc38cbee3718c6c27146d9450934945a7778701fa3d7e886076787f088c09672accc18349fa00766e2a9c599b4b69df255c209d7b1c4a63045ee01c2148680664ec4b1d982674bbc97311b671a329c4894d1b3041375dde2af212b077263cb7868e6b0720c79d78b9d11c3c8cc9d2133cc1041fe128b0158b94d1e786964b64449e70c2993d21142701986b521cd2646e9210b1ef783003f40a293761aca5c14d9907ba2b51bec534420c8c3e7b24110d815c97f2f147e7baa05ad0e2c9066d31873a010e178c09235325750b7048dc09d32f41079ba3ee72cf2c61c7c2762e443c6967a9e0c8f47dc71b846bf5b57d4335545531d4c6bdae18aa7aa134557da8c3e71d4d69a9c63b4d574e54f544d15595b777e06f4bb9efa8eaa8a39ca8c6ee79031e1c2b17aa7aad2a4d8568fad91d1bafb64ed8a33607de52f523187dcdbf9fa82d5d7134f568a2a9d00c7f2f74e546554d80796100cc23e5446d5674de0950813fc7123e06fbdb55da6af39d0e1337a3ce86ad7454d5d1948eaadf690c36d194a66a9c7f808130bcdb549a6aaba69d490be148b7e0b3d252be69fa50f3f48f3f46ad515553d5fdaac6e835d9d2fe22d832824d470d551d930623d8f05be32f822d2358f5cd1faafa303519c1dc07334bb01d5d3f3bbd5160b57f285d55fda432e097ca48537595d148579507f8fb06fe8e7468d1d5b30f6cb24faad266cb3f5171c0e90ef3deb0755e32785df83ed0e03f234d67d02b9c805d4369aaaaa92b8652b5f496a731506dd6b175a558aadee26b6243d41301bba5eaf6113437594b1b9a99348cb4211faf18ea5863e3a9f68975540dd67c011dd9f03fa05157ae55f553dc38d444eb2755b5a256e35dd4ea68aabaa52986aaf7450b617acb5a9a059db6a3265355c7ecb33e895aa69aaa8e7568d245d383a6aa53689ae90916211bd1a4d1382e484d75aced454d166b028af4228c554e32eb0efa9cb4802096d255f53d3698518a31c760b27873cc58419974726169f659f78ed2525bbfc3144d406d0778a68eb58003bd60a2a17ed34c3664cf10c8b4b95ae91f38c6271d20c73d9063a29d43db588b39710223da0de54235665c6e0c2e27f0b4014f0dc1fe81a61a42dabbf0f8033c3e11985baa6a712688193a8aaeea41e38291df628bb481a24c05f41e30fe8651ed7780ccc8da62faa9336965f641ff283e36e123003c51dffceeb18e6fb40b8688ae16ff6dc25f906955b5742e0cec3f3e7f7e0d7fc79abacbc7bc65ff714d75a6c1ea1e60196d50c10fb0d49a2691e24153ae55efe852b1d46f479e56e383b634b68eb7bf5f9d4686473f53b6405943f84bb8121fb3bf6fe1b395e87387fd61c0dbdc80b455dd9601ed6b6a4b55bee9c9e09d1ce8b101f01ad00e3def1bd25f23e9c9a63889266adb778dc83eabadfb06e397c998f15d030c40c23e2abada3a06e4dac016b0207fdcc1da4f1c10b0539b7767047339c19c48c09aaafe4e73a1f7750ba47fa081c87c04e241875dfd927d691230d2378106420376fc133767f71a204739c5b923b054152bdf3450550ca23bd054dd6bc28866a881ae4f359fcffd8dc1d60366098a1e879a72af25cfbb4098e603c0bc1846c2c9d7cf5d5553d56792c56d1f816567ee44bfd3ee9836ed36c60cd84ee34e1b80a9bdd7012c78287d577759a73ddee92def64a8aa035eaccd7b328ae9770d8f3d79c77beecb3d9965e613b799e4780d9f3da9f09e6f8a7b7618eb270db069178c281f3cbd80fca20d7cf28dcfbf7d03936af9dc8bf070a919f22e34d56506f37646bc71ccb8a507fa10cca5caf48bf1cb6086ff1c7a4cb9fd76340ee6ba0530010668e3b071c63902f6e37ac27b4d61ea4f3452fa966af80d90dde616f71144fbae47fcbf16109b42067680041d465ac365bdf60d62ec7149db07795047408bede33dbd1068a82566566dceb2602b06f47b636c1582755b02ec3ea7e03bfeed8de00cfb1cb0359d0cf530b695b10a4eb46de8ff690b4cd91f355d50b5a99ef8da16a74c22b103eefa5d7d085cb3dec0289bcf89f9b7fe5e0ac67e0a061bac7d0711ba08b9569206b3eb9f6a5caec09606cdbed254c3260bec9adcfc9fb8294847205dbb7a6232e29efa50df81f69319b8cb131ffe63a9bc6f533d097410979bb001366497cdec1e33d1b83f361f8e92b1ee31d89cfb63a7011aee1edf3594965a3dded6068d880731712c5db950fdfeb65ee3d12431327ea0c5d8393c622efb435731d5f028d0b60dc9679cc4d15081cba81ddd319bb775e46991a93520d2e2f1196686cc62bc993461d0b4c99edc00b4e191046ddf8021b366d6dbde35ee8f40be21b43dd98508e31ac05cec1b91616f7a8dc4607157ee71f0e448a89f0734bcfe1efbf38e6acc1a84731822b9ce101cf6c73d1e06ee37854a088f306348355d9d8b4807f4f8930b43fa62880951de20e6d689dadcd544ff13e8ef65fa33dc2cc222ced644bb3b8e28cb88a4722b2210e694eb5e2b6dd5b05dde7174cc306c5d41a4042135e3fd89aaf7bd63294c1b40507e01be851b8893a926128513e61329ef3d3e86296a9033ba9ac0f104ccd29be62218c61e439335d68e800f0e4cd98508d89e1d4b4c6ddf73489c9dec73dbd745347dc20322fdb8763c37d413741831e9d3edede354fcd7565b3c4055bf3599680c7814fbc71eef6631f3d37d03eef78629463b0e79af8595d54f872d89746f8f451ac056bacd644cf7b4b70d5801cfc92092ad6ac7518f1396ad05864c7e1e3f7f9060f4450758a07e7a2e93bf9bf43368662e4e8ee3a447f39d969aeb9b20620b4c9a2153ecad06264d7819208f59d1d2632fd4139fc7ddfb0d4ebf7306ea7c214d4e98a8a7b0202df01397d28a5dad70c95c24a63c6d707469e9ef324be7864d5e7a25b7749103e8de0f2cbda3feb1db78484d497455fda64b9c75b4bd06508718ccb4dd6b5720df60d0e793e85ab9505bc2ecd7e6f6ba6133cf3445674ea1a95eb6b65b73e92554a823c0339ffa3106d29ae862681b56bd7f2c891f74ee469d4db5a9d7c0707bbab03d5cdbc75c64ff88f167c9a6aeeaa20e1140b8cb735ce6a1745f83cac2b5507e59e0194a3ad5044a1cfc9477e849f8072d96b055b4d385585c4c5ac533342b3a60b9c2726e72cba1f396f381f1ac396aa50878a1ea81569bbb9c1b580e5db61cc0e2a2d62a9ea1f94ebf9425710bb2e5e3027e9bea9ee637aee4ce535d551f84d8b20e1fbecf7fce02ff6ffa1dd779ae64df349ba7ad90d60f23296441da00a826aa3153a01aaeb464c97ce0ae66a8158aa64ec14b9fb091068bb01a6a4fc62cd4190b8b9679a13627c6766aaaea31188d235ee5aac8227f2fdb9fb4c85fa8fa773d258cf3a5ec9b0c0686be5b3034c5d1711a830bd5d84b73741faa3c454bedaa27efb895f1210ef80422ad77843b16abdfe2840e1841dbefb4f4c31dfe10a87d224a46631e1b128dbb701ea705c0a70e8401ef385b210aedba86148974778e61b9b3068fce09ccf2b112a53c5192a65e40c8d23f13c9d809a4382df544d49ade1a320a3c1ce67f870c7d7d9b63e040f8d4fefea140b03a62505365794d9365ae6d553d1721b7aeea7f486160ed83bc88fb162c0280b77c66a9f46d6d0792f98f0ff2525c081c2f786478e3b36f6dca43946f472c381f408c75bec7c177d9a28c8f5732b6e39662a9c6efef524b98b6a056b4d70497ea360a90fb0ea1c9c90838eee9cd0491d9e5b182d59dcba1b6cb81920f40cc7bcde7dfaf15539d5d5e2a37cca1b4d46f979ef6111edc8872c003388dee0e2cd5d5872769309f1443fd7e79c4c63387115eba9ae812465da0c46d895636dfde654d53b0fae6d217737d8268e8419b3693f0cfd345fc174fb5cba46ef7b2a1dca84d9683542f5d4df489e7a2c9aa546b9f91c5edc264dfbabe960e28ab8caefaef7727b2cbafb2f8a5e56a5251358ce40e6a8e42f09ba21eaa4f0c304dc18960ea80479e1d55dfd58a780b72c652d9e115563ea9f7577d8873a00ae75e7d6299d4d550a3277399e55d9d3362b3106270f5c77c5e19c5bca25767d1707275b99455aab5f301b6ce1a02a5025619f358954c55bdba5cce2915ef337569ce1a901137fc939fa706d71f981a5c7b911a2c91814f6a47c8c009149743ad66f07054584c401b8f186c23caca52d1d95d4bf4c3ccf34d8f6523fe86f944dd8b7a58aa11f0fa32146a3e1538ffdda4af5ed365a657f946cd2735893ca49d89778d23896b3bbcb424fa1ec9db15cc731b474286e5ec89cbf0db0facf184678c7ce22dc8918c8954f1b36a9c8e184a1155884b8c77bc9e3fd0951b708427e92479079c8dc8a7761bd03ae6adbac763899aac5b0ec412943fb98a69ac3adae04431607f82c50762ccce89f24d53dba7bbfceb08bef24d2fb5ad34d5e644f7849471468f34265f27bb9a482df9ce0253f43b2d0112b2d0da93b404b31ebe96660c6bab68bf4b0cd882b621dff14908dd54b73f4eb41e2f4af172c3e814d46b8fcff186c52cfa8c898cd4879c4269e09d5800b32ffa368b34a43edf4e41bf2abccf430b2ac27bfa5eaa53782a483be4a2b7df62eb6ef90de5a611344029aada28d941502fb8a38412d8ae544169eb6207a40bfb1ab0ddd9568d1b86e79d885a5a5060e571040b703e42b18b7b7dde0370ed5c31d5facea50bcc5224d6d742ce8d8906fade342052fb1d6a7e900537c1365d434b8f970d5b718bd18360a009fa6582f80aefcf4b988ee644db3c4c25797dc2a8327b21628716149fd516e199638d07fd5b6dc65bd8bd3278856cc21ff09dc56fad648c4e350ad277ca7779eff9b391a174f4b7da1f4d45577d1da2a56f3ad496d436e59b214453aa607e19e57d5e17f7b5d51fb5d4f1c75d1db652b961193193a3efc324efb4493ba9777406c7f09f2a23afeef1d2f6b5e8c1c254a33fe20be4b95d5bda0995eb475d416258eac94e136c83ce835e79baadd3c8773655fd7b8397553d835392f1a2253617b8af60f43bf9a874d463f503ef7a04b34d2142ebf1e4b87606136cb1ff1867acadf53bb3003a0fb30db1bdcbfabc6b0bdd7dd0d4d6b6062ace7bddb7f3dd3eb1d4caffa3cfc4e177a5a57c6ba8fa4df4e541feb2d5509bf19791217d191852b71d790ca303d13f2a6d655f57f5ef9adcfe4d5795b6f2465759ca5a3447d8501d9d45dc0d5d69295343dd32e26f3b0df522fef2d050479afc8824dff61bea3401e218eaf438fe766fa883a4e7d8e05b56f06564c820ef0dd58cbf9023354c1e85477c278c8338523b50ece873f7fb210aa09baa10ffd61834c452baaae1c2b2bff17d868f13d80f3a074631096bfe2e3f55799cc61e9cc07ef3876f00ef8e1fb2680f5a0ce2d910a05ff0b6698b572c616fa4ab1a433162d68a867454e30c6c88c58bcfdff9932a1717b01090ed830e4613d6a4e1ad9e029b876f0d557d63c0ec47c1115f239e0ff384efa180216cef35e009332e27bfc3906dbe3db80d06ab2d72ae9948c80c9155311b1915b98c28f752c6bfeb2ee6a7544c36bac794749f795226655dae097a4b196b4c9b78b005bb83bff32695b70ca0a5aab1d55f7b5cf7c899d01e5e4ddf6e2b586dd6743eeea13d0f5487353097d9110d9672a31a3df0ac6dd1c4165d3c4bad2d02e27d1e26be6d29a66ad0233e05cf4ac1087e2c1e0f653a7cd7e47b134dbe23cb6ca8def2a0f164043b96a760c760dfa0fdbd10d2248a73aa00a5d2388d77fbcf5920039e56251a38b79b59218c19a359cb35b6c0dc76cec4665ae3baaf74f40f438daf4aff1984fbde16e1fd5b99709395097722ea3dbe4cbabd7f3dd2fdd1576e745fec485c284df5c8875a6f074e059c334ffe49692ad56b9d1f65f9061d03d8a77fd0954faa114072a8b7dcc2792b2c7c6b0e41ccf596388192558523a5037dba913366a19ae1703566981a7bcccba937766eb85ed3258d3c92d54fd6a26fd042e0d0434ebbe48691a60c74d5382fe6ea1dd0adfb61ce33790381f96e1e1d092b93250cafb48d78f7e23e0948f69fd1071801e531964feadf993834ed94480ec0e0ebadb9f827383299b6984ca400ece76867651b1ea0cb8eae36f9f9b3d635478c19af3fc46e1ba3ec6995ef420ea1267cee9cc1ae1c6d40cef1fda450ed8e606f01f68be38c69c4d8dadc1678fece9130551d4e83cd34886b4d8f195b75a0d52075ec544f81538c0d355dd93a528de31188ae1970e5e31ad97f19853461ff78d8996bf85547db670154eb5d434d29e451a0f5958e51d532d66caaa9fad55c4f62817b4a79920bc62396e3356336aa9f94aace146d119cef70ae45158719d993938f51ef6bb55511d334222ea8e63b5eb165ec9f19fce0138bc18e2a59434234e546d9bfd68f78015c3625213325ba2b4c4990d20653ec8587507e705344c562058c7815966c34a921991186be3138e19150d0c94235a86c3c6cbea44fc5b6635f67d94cda54647b869162e8ea123793c1bbad36bf3738a8fd56ac75573c051072ef6a32638fd4e6393c56090fe11cadc25dcd801f1e1416f70e8a30270ee45e9f6ae2c06b479257386586d91f5d550d02eacbd3a0194f753e01457d28fe19a01bfc1cd28ce7b19f0ce5466d6e0bb908349914d342527045fc04d5c8401c3a01d7b32b24e6932c30ceefba9e17986f203077c2673062ee6b2221ef8882bc7ab29be2f8033f5c1600cfbd06e73c977510165dd51b21cf6b612d63ed5d6afc161c13a3faae16098af19113598d4dd2c7b7c9c18b63c89baff52487ee78e732c0013f9bc94fbbb107db8cbacd3ea7e4448b28a67f04054b4bd0163f91b5a709c3f1e19b76a7299d56a0edeb69573ce047883e2a176a9f9fe160dee968bb88d8e1b5aee689ed00b1f734ae9db59c1ea9dded36c37ca615b979de63d2644e7ea6659cfc169356d5d182f3ec10660d72ca99f3d75c399d465639991314fe811fcc36f71871f58f2cbf333e70beefc313501fa85bfd0ea268568ea33dd2a6aadbbc6bd21376493e06c22edfa8fac77747dca340a6d2bd646df635f72127aa7195d853be15ad1e2937eaaee6f123618c159342567cd49b9c1510b29d3146dc432662733e4cce8bacf83786581c4c25049ce892f9d8d772b2cf145574502fb6346ed2f9f168186ff28e5528e889518cd9135d507fab08a6cde1b0568be53b132d3f2bf400ef64a9adef62ba6d21fd64bedfdb6bc3d3c8f16db5630bd381aa9dab27734149ea38f9ce4fe3bbe2643ecb71768cd826523ddb118c0abcb5a0f363d527e0f9a431b5dc985dd191534cea7ad748baf2f340fdd8811ac3acd161aa77a7d344582e335e9579b7b1de555afab0f151578cc6a001cefe46692a614f1f362071e547e9f4867879e041538fe0258113353a454db4d3e890be75a5586a8f1fd11f82b2de8b234dd0e430177572a63455a32db687e282d5bd260edd0fb9c37ed0f6985bd683e8acc9fd85e8bc77aa34a1c004a7654ed9aab0071b5e7c6b88f04ac7774d36e89012b4be31dba1f31ae409d359e394d3bdcdb7644f54d5e2f60b94d5d59353ecd7dbc5f05800cb6be99fa6dcce371290707645bdae361471c4589c92e0202d5e10c94361e2b80de507bff1b6c1ebcc894755bb47d267d788e255c333def0339442c11d28c15c5f0b3fd204a6b1f0981f1cc52a9f8185c1173c9aec866050acc8f574d4f35d6d2622335dd5cf2f19fd785d43351307a5bb9acbcfe8c2b699b6d79111185ef27dab0ba525cef2814f8577477871b8fb11d482705303a8b601211e95a9372a4f8b88c103177e5424357604a3eeb519041ad770a2c9701baedc6797d385ad64a26db1ac42577720fcef4264d2bad3be5ff01d8a4b11a8ef3274878d007c406bfb5c2efa572f81d33e5fdee882d1c6d73d0ee11b1c3ab8d67986030568de6f7c0966670a671419f72e67b063a26e69b54ba575f1a05d1e47e06f2e67da77ed3b1c66e81a4af3e241fb63eb12a291d965344d577d238c2df78fbccaeff2d36c40442065cb9479f2bdc10fff9c31bd99e8667ad5dea5dcf71d635c739757f343801b32a4a42e0f5c396c389aaf4bd5ff0b588b215ec26947e5c83f409c8d190cc3fc3c23fbc6487625e9d980e773953802ebaafa6ec3e5a79dc20f6999fea41abd44f7e0c504ab0a87908334ba9fee2ee6205fa021278121a8c25fd1e25173f71856d794a4eb2d3f632d8e3b43af4f1ea43b9ff8022f76b8ecfb474a476d7d6f4a2c9bb5651bc75f2fdbd6c43a0c26d7eec54a3a5de9448058c43001e3003d7443e5b21bc071f106146e4e3e888d0cb6feb4d2c644b980140ff663fed8fa9030ca6feeca65f55343b9662eabd38d1aa70db513d7d4df34d4fba478fdcd908ad75b0d759c54ca778e5527e9e8b4a48ed323a9504e8ed4f6b572a1609d1ef795b66ab41ff4d8cafeae74d5631178187032d5d1d4635e4866c159674f8493923f75b4c8d77d5ce6fe87fc4db3efe21c4c1ca6352320708eec5d533e8bcdd23e7dc6ec09c3c13b56e6bfc9d8fa777a9391fca93719bf390d551ddcc1ab9fdfef73af7e8e567bf5f3ff2182ddbb9aaa8e209e327647b9978bff22584ec2ee34550de16cba51b9ff5182fd1bbd5c7cc2ef07c06bf535d3f7cbb5b736dec6bb96699a556c6e57adfdeadbf25d728b4da88b3bdeea9fd72a15d41ac19d71b7dec40cd0826be3d0210af0b7b113e0d2ed5ab95c89ffdf2336fecaaf920b2b56186ebac4b47150b19d905682b1479d11ae98be53be0b6fd7360e6e3d714b1d3a5c345da96fba2166dd2b15c4efa18b4796fd71382c7de673961d5b41b76be5be6f3d8ecc60e078f59daa3f7b620da83cc40c9747db097dd77ca8f75d3c3b607f366db8e2cc215e3d20d383bb71489dfec3a6b8feae1efaa685377b984e31f69efe39c2b663a2d2c89c6dc2751b75b4f776df9f6d3ca626c9c0b5883b1e794f0291e8228bcd41e0d84bf181a66960fa75f6e7e9f6d6bb5d63abbc5dfb224862cc04db041512a28a4f07b71e5c761220d37752ccfbdb5ceec19d2285fc73bc3b6cd12e7b1eb63c4ae0d3953988998aa47f6c5241c9f4c4f367ceca8d751796efc205989a7306a42e2de5a8a5914b10139fcac94d87e81f71a3b8f110d5a3961c20a78f4af4c1c7a49fc03c3c44eb21dc64b3be811ed3fde5a93fcbc22b9a15b4befee54b86944f6c56464f71ef223a448f4f808a68283b5e880306f3768dc9e1edda41f22c74bc818b29f1d021027d3a88c0f1cb48d021138e528c8018c789c6fe2f275c1179f8e58fe87fff97a1b3a6fc8719924d87e2d1639f78743374bee37aedad3f3b90be06787410a9b0e3b98e87374193a30bf8ea01764dea4cf081e93a030fc085750b7b140707dc826c55abfeec600817cfd5b7d96761bc76fdd9418f04360eea357f8642e23a36fa657fe7ddb6698b079b81693be3b05e83bea6753f08c8d8b337e14abf7ad4577cab6dd7fadb7b1cfbbe3972dc87faededed1adc38c33e289ba6efbb78337c08291e299aeb78f76dd3eac2d723e25185f5eae201c1e8ba05232e498f50a21c637782a963998a1a38a6ab84a6176e863870fa30446560115c13858c11b97360ac0c6c5e73f761d4232e6b3aa07846376d6c9100eed3aa7bc4c307648283be4ba6f5a163dbd87b8a5956060a3f12dfb41cfa50af669f6c9a70ebe7238d6f39aa8bbe68bb5a1d85089b21de74bc8308424d863073e8e3bc07ab4126637a50801c2afb3860d2610ef0632c43662f24ee98e2034afcfa66cd9f1db8b84ff927596ea42941b4502d5e074cb892cc54fb56adb777f07d132e01939787caaed9c36eda6565fd654ab46bd5ea7f47d2d7eff763a05b2fe3c7fe2f3cd8eabe6b45af15dd94fd97c7faf7f058ff22be2a2084a2a218b7c0ef2c8c710f7cd3b61d6f50af55fd19daaa161a09ee4a1685c3323e85e1700a31e80197173f3dc94351b91798def228b96091dc896e06601e6119d1c276fcd9011953e6acb91729722d4568d4fbc41a878f3d32db0c87a64da6f52aaaa26d7f86aae8976a15572db368187246834761a777f6594252d0675893a28cedad5494b1c5a20cc98c663d781bd380f8c4754274890763d7fc3770e7d3a143f126485edd2390dba4c8e299931fe0fa8a1209d04594c54403b13431373f3297047e9140edc7815ae45bdf66452c72ae2024ff110c84354cb954f7886bafa04540d3fa90056d8fd9de63cfc601a357d190e7ea1d8c7a630a166f42b4b455cd6b9e690fb0cce3b4da95f7761997b34062b6bf2d647bde58dad6f6eeceee7f9a0267f9bfaaea09aa0bed03c5fbf9c1e0ab47822b86812bc680f1ef9efc1504fe1b0481ff2211a06506058152bd96f59c22fc8aac188ff0726586fe567fb7df5bc9be318b26db667f8676fc196229290a063db354dbde526a3b7b4a6d6f5ba9966b1bf9b49de18ee0efe6a6081ac5cc3d422919e5312b1a8386db9235878549c6bdbc259b7301173a8975ececefeeedbdfd4f30ce4f3c519716bf93f66cfbdcb5a5cb44ffa685a1e24024fe1d90fad8f7716099217e2ac385dfcbc9b22c7f1a39de6614cf4bf53a39364872a79c6659db7615efac1830ce91c97f13d64c49606ff6026cded7e1efa6e9ba5c36df389e3fa60aff2cf8928bd6a0cf7276fdc58a152c02d07295409a77dc1c91ef9bd09bc5028f9c04a053be19b06002944c02524582401c4019fe6efaee387cccd7c2d304670c7a2bfe17b35d0220b0962a9201992e4b0ea15379e4d8b68b1f0b12c5b245dcd5bde553590827dda4919c52e2438d447a16cacfb6d2cf46f23396e0c7cf7a09ccc8db55538fc3c7bcd3921e8f328f01f83f859c5ac2de09895d07715d175ac4c2ddba478291e9a6cc68ad5ae5df23028553d33f0803ab3e0edc1293a721a57e58af54a6b8678621a661d921d42c9360506103c30afc944f0566dbbc1a3a5e794afafdad7f4c0eb7cbb56d06610331eb6c5200070fa155f973332c9a001a9f4118879aae63bd34615a30cbcb93479ae76712a9407ab67e2e918c190dcc5306f965899499e78525e9c588f41af25438db0b4bd5f6cf25d82b08d4abc9d24b90e635c4e8952568e7e7924924832f4b2279921796a29f4c9ed710a0d7939ddd9f4b9c36b69df1e8658923cdf1c292f322c4790df9c9cdf4c252f4f6e712aa8b478e465cfb6589949ae58525e98508f41ab25430d70b4bd3decf25d6cb4bd26b49d10b10e63524e875a567ff0512909717a1f4342f2c472f45a2574bd15e57a2defd64b5734debfe85352e9ee28525e92548f32a262933d19f24139a98abd41e5131b9a0c53347d8de74bc909a9e85ebeb22415aff71620664647ae5c9ea99dc33d7585c467cce1a3903fec412390a3f658df9ddd0650c154dcf427e14cf524926cc65dcb5da4f11f8e593cd9febb9c442112f5f99661963f11a944b9b8d3f4b3ff067082a46af47bc82d2f38b522e5f82feb3647b6582bd22ad7e2a99ae868ef77a544aed87bd2891e47db19fa881af6ec5e66e6fbc923afe5c5bf67f43c35727df0b508ec9f3ab13ae6097f6c595f6e7928dd7395f8f6299f2f68b522b5de6feb394eae2918358dafc7ac4ca55715f945cd96aee9f25d8ebd2eaf5e8f4b369f4ea56aba0d0f4e2047b09abf5ea842bdc7e7a0513f67389171bb257a7df9c4d9757b16a2f9173beae85cbd7d15f3ec4fd99b62ea1d9ff4d92f0da9237a7cefea75d866b5af7afe82c52b5f697f51372cdfda790e9f55d6b41f9fde569f60c01fb357ebd2e3905cf5fd171beb32ff1bb35b3a71eb11f1e0bdee979dbdfef5b4fc3add5de4a9e73b5c8bfe3ab33fef2170efe1396d91b534abc155f7e8523fab5f84ff14bb0f28b15e21291252f562462c75f22fb8f7b0f2bff6e92350e4212d47d02db33820babbc96f1e3efc8f22f087be311bae9b6c3c1d5838fd1e36dc05fd43c77bc81127d393ad7e3cfaa6d9f111bc7df2ff1884c70aa49279e872dcadac2b8b1e18456b6fd89fd1188c0ca995567d8e03034071236f4c1c775e48d473d1c1c448db649cd3a32bd87831816fb1feb8b1a26358f4dcf7671800e5129eeba810e7f4313e2d8075177175334e43da3b750c51381587fecc13b1f28c00327a43810704b234eb35623c24c8900d5e5f937926544f37c8e877e4187516b7a15d9c9c7ded2e9a5896cec628a8be65b3c8be0d00dee7589758f69c937e9b08ef8abbf0a225ec7c71efbafee9210b30f4610107966464e9758e8104d1dcf265378a396c13e907b8c03071da2f569585f8fc91dbd7bec12abec0784128bb8fccd63ee1ed7a559d8bf18460484bf572c3eb0a76f0ed17aa5b28ede308cca431252f406b115a5e664f84c19eb3d3c45c9cac781b391ea370dcbc4233ef6d0a120c441ea91c54802cf8038e9879891091e02c1f2804742e40f51098390a6d6ca701c8583baa41b87e843b77356f6cd20c4255c6612be71208fa954d087714891897c609e4d9047e8d0f106722f46f151382883d61c1e26a6a0cc2c4086e4ec5f80e938f052333d65511dc69a274b20ccf1e5203bfbdf86393d5975ae61a20a19023c2572bea6ac39f00a377a3441ca156491913fa6d85610e9853898983d172ba8137f6e9bbefcb58be913ea0764846ed746a4378377d12398599551b2764249681a43317dbf327242ab72d34d018bdece3743f4d19998a2fffac4999883c0f48777e13abcc32ef4d672cd308c2c726234b92ad991de1e304264072566fb79e364db9e19c96f0f954683e5368301a6516311c48c63f83940cf9873ed91208c97e5d55117d3f77cc86f021019d36c337f60112fa4c1d8a22428a56e3ca043272c3b9e30175d4c4bf28510f0948c69c1e3278126404646a3697cd53ba79dcbaf0de348bd3ebd829b0e7ee9f7f7ecb756bf0f5291eb7adc6a1872bf9d6a71bfcef555b3d33a6bf2bedbdb6feddeee3c98ad33bdd38efbd6ac7d7baf9feafbd1b8bc327e2f40b63a33f7ed2a7e3bafafaa5fb53e1aa2abd5dbe9d5e6766d9d7d3d335acd63ad7329fa7344e6f5ef5c5f6507f055e607745b7f301c6a3b450f121cb78a9feb9db33343bf321a0cc47edc25a4261d87b1ce9f9b74086854a62160904823ef3e2401c51eb65b0d7d68063a19c36d19fb05ba3ca6c4c798096397922056837f26860a794c4d8484a58c542c6ba9deb1266447b44d5fc8bd12abcb6f8530847e8a8b3a8ae7e5a3c04a7d74f05485eb0eeba847888b4df9a28e2cf029ee854045615ab05d348a8fab5450885d868a374026b270404dc7038ae4018b9ec45b1d173e04833d8dcc0b5bf1d87597f46e79310d531665b5d19d317dee703fc013074fe7632a51cc0cac611102ac5d1accb20899d4cced708e22d2bbc3164b2a62261f489f1d2b145f03ecd93860c1ec32439a0d6793c023ca308435f5c477d9cece1f2ca523d1f8a4693510a9f425022237ae06269bf0449032ed927f88092f9e234a90e999ee43e88488b10d0768e29889c6c42466bdd3e4cd45f205264b49475b25883b014b7e8d4edc39d6cc120dc678e307c6f15b6b7e78e0469e46360e9c09467488517fecba600350ab817a66886d443c78121b5e78dc6aa052df09e619646b6806a1986980e9d1d875cff8a843548211fc6ba431224c8f97d427418945bffd6420e9f3e581c9e6f75984a58d8dc7fc8d4bc9a0325c7818de387428cfba5170f15214214b53e6ef592af82846097d473c5e16a4fd270f92451635872d8c2256ce5c27ecccdb747ec712ff2cdb182bc026c528b233a667a3bee3bac8a168ead02124f922126464611367e90e33661c0f3a444c54b3a1199fe41082eb72937de14da5f47d5a8c8b916183b2417a089b862d71e03645a782f1aef9c0034169e029b495fb24b07003ee92602a1523a664391cfa4cce4eb1376059f87655297aac13dcefd751b55cad566b991e76604acfb7b2e329f30357c3008743e2daac4f6d37d367109813873ed4d16676347546b84bb15f475b59c4e810539381db971e3cc96633a26ed975bcfb5289fdcdb25512d442da9f3a1e2ee5e3687996e229430c2a751e9041608e4abdb1e3daba13582ef888eed0b47150da4873341ecc34b954627f17e02b2a09cd530eb62445944a613cbd1c694e2798f359d4908131b1c42ed30d9b58e311f6687980a9e162f6517b68d9a5f589138e4dd7f98e83f55c5e13f9f60265881e2d12668b782c58c3419d21a1c44b5384aa2822783875bcfbb00eea9b959ecc5226d883baa6840dd0a2e5f9636ac0d352324b825a1a140753b65cc7ba9fcf5918cdeb0d2025516c0903ca8e9de3606e82111987d8f0280e96cc2245762ca2e3f0e70948f134a7d89c2c10d38269c69e8dfb8e877313c92b4948e8588cf099e02f2729e560eca5f263e6b703732a8cbdd347538c86e604839947167179489c4bb71dea986e2330a7cdd85aa34c3c005e83c38d1d470c1ed64ac6a1fb909d240b7bae83e12ebc4f02c3b4869cb4ca3d7e5046a63f97c46cad8cbe9c1129ca66a147d1ffea33542aa8e3b90fc826cc59f649808887a152cec28e18a082cc90757042648f7dd7b1cc1481d93f1031e198f8dc24c9475a0d367941e8910843d9b46da6b525862d4a8fcdc6231b7922a4a23a27f4498811612b1376a437a6e81e631f223a391e20fe33c20139e5cb0baa98375fcc89220629b17a5a102a7521a78280113ec9e95921a2613420e95fa681332a94f1789f8271dbf12c326289db3444a27a1ca24aa510b9388962984121395d34cca206778026523f3443a8b13a762e7665f91d7171d92583d2ed1a4cf1df2132dd009bf603baf7c8d42bdfae29480c3f282ef01605a9d2fca66d97f200622433ccce05ca695dcc037a4aa54d45cbb16d6c679691326a4c324724886a33c2ec28497be89b16f00a230fcbfa97a174e87cc7e837b45d2d5e442caf034c793059da2887ce68ec9a940465395ecc422d5870b120cb09732c2eb9727191c4fc6d8ec8144402129175d35ba7d18e95c729ae208f50e4786864fa4bc527b5ae42f9e1c0ffb408716317c4a4788e287102dad102a5351588928bc3b04894a0fd79a274f87f2c4b72dd2496a6824d8455e589ef072c93a9b613868c46bc774474be9b025f64b912209f619ae621c7f72556458ef75e829c00b902722929ea113a446680990e8111327d85875eec5b52cf45c443a11560ecfd39a5882280849ef3d0cf622a6e6c964acc1915969ec48e40f0f54d668e14e06b0e38a97f8f4cbf4859e2c86b80a92c62b0f71c87c5b9c5b30c245b5b8f6bb8a52cc39259589c152da398b919b4c2145a4a022a455584dd10173268ee0297a09262d4027289912f442ec7cb307d456a71ac7e06b5c4fa1663922256c6bfc525306ed1ff3b449bbf492e60bebaccb3a9990a726c568b7752e7c67659f52ee0189e3921656ec0f1eed1a1acf0cc69aca6f0d19c7f9381151633d37483392362b1f46524ec26184ac0623909e57f39a389d2561d15f97958640af367d9322868c632b5c0b24921ca1ce3b6444c65a59680ad3c5e12f31c2e69db9a6653227445123e873bf9d486e759701530b60521e574260adf99b07b0b922a596a73129bcac5d31a118dc90966ded5161a8f4a8565098812b112bee9350ef02297595c1bc8132722079c8464d9bdc90385d2040714cf36222fcf95424a47d904d70e3fad2808a770280a8240ae807aacd3752b453bc70a23f25db7720833f289417f5be402789fb225b081ff66ed3eef02a1eb2160f86cc2b8cc6c94b0cd0cdf3cb2303d96c8e2d8aa821c5b13a429228a05bf355160ffa2b159892ab1117fe375834267c8f02c263360d762000a521e3821c7872e24364c03fd6282c35131587489af73e95e51aaf6e00c86ae3318d230b573ad2087863053a1ad0b87647a1c8d2caad624a17466bb7e033d72d57b3a282e41967b78e0783ccacbecbf489d4449eb74e13643cc0f67013f58870286f0714544ce1cdcc9d6ff529e23a151445ce95043bca49c529724ca45fc283883a3149c79c9b98439a71992a2a0e3a56b8285f1531e45799832f7d88f527ceca630dacb2971668e02a2141c785a588f9d7738634189744572a4c629f38f35fd39821490203371c171b1f9122a2914f66c49e7521d92b23fe61f0b8b98b6139a3d1787894561ae9af49f6356021c627a2e8afab0628882c37bc7575d97112277da474194b007c78e9d3f0af46356e959360902137b8023af93dfabcbc52409c239f33e0712b3330be2535e849a4bf89f6372c46a52f2fbf38dcdfcd544a2f2678dd3b2752cc68289eecf315d31ab5fda60fd24922e3270af44d3e5d66f2e51333640b2288bca5f2b4519e84f461a68d568a3e050415666f295f29f64dd535b54fd007e56cd8eb6ea93744e8adda120390e02ec51f7a1c816156eb325bc5d9611e684416caaa7b7a5e34a6cbcad5690b517d57d73e097957fbbf20a619fa34fc69e8d4aff1d6edcae15988005fb0be99a5a4166bf10d8224b0c25bae8f33f520539549f7ff67d9e194287680e3c32a6cb01c6fe77ceb9ae549a91974b59344304273d10f1a22c9abf6d57206bc9710f0dba743c1d864aefe8c822d4773cc1d4d419447ee2701f8e179a16c5b240416ac960c692c975513e7d58c2a26a52763c0f07c757edd3acf12f3a9722812d3c623ac4d67d88a6434c873848ce4a2327d9bde53f590f5b4f5eacaecb14b40017382d98a0334f51e3c2643ee6cae7c0055a7d7828d3b23023ae545083879fd28a8987426c11cf16923165cb1590e283a4e60867c2a314072c179b419a01ab97200b0b4a02dd2996513191edf4fbccfed239d8542afc6044ca77b21510e0333771fd0866e1788f508ce8d0e4f1aaa8ad88379342d433ad7b4409ba5d1b3a36be5d9b439082081d0e0f2ba0bfcb4b0f28eddd6583bf4cb4133dc766102d1f161ef3bc406ef31c9c7bb8a4686d0b2d61fafc4861978ce95dd23b635ae777970d67f6044c4a18d3c7cff9eb71881f588ecadab137e7ee9f51563a6e120de25f23777aea84f4a383a7a58d4c412dc02113a7a2bd787e12469c8229bbb0030dda9ddfc8165062dfc7bcf2d2526d32a8c8eba00507bee645755105b44cc92999e24037435cda28c30fd375fae955c93d36d06f6c550510253c61d7295b732dd016940ff164823b365bf1e72fa92c339a22b5cae2ecc0b1c5efcb8a2e7392117102d6b1c38c5c15084892fa303149898800a30681f950ee07649437f892c6e437ccf2934909c08fcc266b5c6a3af9ddc3e8f5cdec5b5c4073f1424d66a3833aae431fe237b0a318397e233b57b4e5e7d105f28cb1d0c38e8a01d559b5fa0ee3fd7e3f6674ea079da1d7e1215ae7ef8caf67dec9013ac895f9a7c550c48f42a3bfff3daa9d671c3ab4ca4abc9353e24a05fd120c7a4a723e1161d31ab2c5511c203cb3b04f4518f54b391b5a4b9b09e500fbae69e152a5f4f9fffbe5cb4665a0a0f5ffaafd576d7d4e085d88e0bb620483c1a0d733cdf49334ede15bcba3026638ee853428d53614547b5bb0fd5c38fb5ed1ec248810282f9abfb41001f4fe3ddadf40ff8baa33108e0c36b9e4362053b4ce41e399cf633ec743433c13b7cbf073b67e802d6c336770bbf6cbed5a1919e54119fd52adf6fbd56a193509e56ea48ed6d19bdca64f76a34148a0b4aee82de44a851fa947211df7fb5935914fdb87ce77ac64c491eb736e5b496cc3a637a49e60b2333ca3cc138a0c75680636438ba24de48c7c7e66dee4f1631fa9e72d4878ad7148c90885f00e0180f1f95b060a1ab394a0f780e0847afc9e5c5d5ac39c1711a225542ae888f182a9861f382307dcba38058676904969e0f4c61487753453d0832001944fd99285e84ccc00a95757972dedfacae87e3d372ebf9e5fb6da2df11eec8e74e61e3ce05197b98db470ac33a63b21437a0497d4f9a8ef12931eac675e04599f98c103938d09b6760481f37d8863a391e97825f669033de67a08552d0ddcafe7c4f1a84e48609767681355cbbb1be85734efc99bec9387b963e227ef51b5bcb53b070d8406eed72378ab46169aa2ae915ead0486d1a754dd2806946b7c5aff52be238e575abfbdf5d637b22cfb58c4b2583cd85c5bc8fccaf78ecf49989bb45241e72cca4fcb0f723c4ad8604a82323a02738c5d3cf2e06c79b4a9cc13a94d59e224b05dc7b33072e87ac8058689065c7a03798ee9f173dfe310a3ad1dd473e00d483f46252c97f320e970cc32567f68b20cdbf3b00b47dd03e2fbd856007b4869a7e64388cc301c8f306cd3f730aa9597d188ebb31a6b569e3f63cf61d6900f187fe567e9baccc2cced3a32e90e1a7f8d7f8afc05b506449cffcc323a94e744bf729193c4a02263afa0aa826ac5f218e94d979bd33c953ed7bea05fe5d93e57bf7cae7e2904066280ac623873c670efd643876844ec92a5a0adddb7e5eac60180e9bb84c54a15d1367ffce04f8e0f561a2f94a87288b67677cbd505f04c74886a453d32da7e90d8f1c8b9240306aef4a537eef77120354477f184521bf8a36beab861d68c8804e98871687b0b82e3d2db9d9cb5896e33905f02b44c6f6286378e4d878af8720cd75db1f45f0885d4dd0975e8d37002fa70908a04e412dbafbf4a94f915e9a6eb16f954a6dd2e316df10630f3a2dc760d5c78090dcfa8acf8bf56640299763db90ea93470753e2017950d5c7488e2c799cc2ca169c1db6912d0cc30c14e74280128f31764a39715857d5722df9c053170cbe330ee2d00e68e2c4462909e6980e969f4a414c72d9fd7251bb1aea0f5bc9eb256d978f0ef31a3d7bf1460893db3e7e28f009843e20216e3568e27fda1d1591cb340b86e000f0589356849d5029e941f933e5130819a53f433f7d1612431b1c9f09501a680ffd33799208853559bfc65b611b1b10b61268323e61315e7921400f399984f3643bc5104d72721da448f2c4a7c42160b7f1c0f8abbf0be3a477c9e8ac43fdb2fa909c75361cf728ac2ec9463cfc4a6cb752bfd2e238aacc867d6e7d7b991e917965e91b03cfb81b1e80daab1f19b0cc0c38f01d8fa922c60dec1b515c06c4b60b2a7db16c8da25fe36c621e5275ff3e2665a746cbaee033fe04fc681c891c0e8d1214ec1928c20ba6252e2882d3812c08b83301c8ce63c09e053cbfc2fb08e2b98a1815bee399e2df46ee096d5cb4bf5d357edfae8c8b85484a2140d82070d939af9411ebf6a63e0961b9fced4764bffdab8546f8a0ed1a57c4ee16641aa4741fd545e2c0fedda260d9cd94e7f2219a2c4dfc5e750a296a2825e026cab2f419123b3b9ce7541555d809e4816f39c5f3659647115b405343c3aeda85731de73e5fad7548c50d63e455d8c53a36d9c5d29a85ac0c6c5b864edf74f47690bfd8a760ad0623a048342265de79dd6d95517a2e124d8f9d32e027698c6210e5068992e0e2bbee9092d0476f2ca0a2f40cf5142ee62ae22514a59633c8ddbf38716e20c00a2bbb863564332b29fd974fd93ab0e30337e3fb462a60299c5eab23ec4df854ae4f6e293ce9c02d2e883a2ae1c8edc97b7bc02c128dcd8e8f45946cc37e4c039e329f7f9533314d7a7d805279d73f4e35df9066cda75179ed4ce04877846b167f3284b18d94421e62b62eec59e24637873886a2f44a1883a8178e912fce632fa24ef752ea54fb4df2356f21bec4cc96bdb646bcbdadf7897c8b1d17bb9f7dfff8e72d0f29e816f06f35b3c5180b9c3e76fcd9ade035cec992c94fbc87221949617526cda0c5a38357d01440492a0870cc2ed9a6b86f4762d3a1593092412705140ebd9c8c64cc8428c4666708f83289c4c812aa3a633c121f21c0ba34ea9b65108d4c70114993d0bf30b0046e63d8b516c8c42d8d6761fa024cb6460687ac8a1c82263d7463d5ccf0394d329e23f80149f9b0195259971657eec264bfbc26eab2ac2d36a920f11da08d321813296b5d0b63a70879537c02154aa219c77689802c8b91596d10d93256f9d42b5cda1688803416a28cf7918db7c26f5bc854a21c6224a1c8db047532085ed91de8bde10286fcc5535d8a7390f888f03eae050d638f1509cdbf3f80d254cbf223a3df11a7d72af2b5c9d78668e7018ddaf0a2d1e6bb95d839b60a30b568b6ffe4addcb1a5212e0b092ddc3cb0272bc3b6cd1e806591ca0d415b19b01362d9a1ef32b324374c9dac5b5aed0675dee72bb56aeb0e5c2a53aa115e6d097b062d40ba359d7cb95eca3e466e57f725c4bb76b666e511bd0215a847427b4b847552083b8fd17f8977532f289873dfa3e3babc28c91747b717454307db9af28ee94b217febeb79d49c2cec3db35cb0cb861da9c38787abbf65b76c4dc519b9b430cbb30c56360dc707bee33f60f8e6e3c8acb72881f96b3e44bed103fcd9da632679ef715db99acb6a2804c11bf747f936e868bd694a3057117748721aed9c36e6a9098aab749978c65ff5ae2c4e4b27eef43dff452d3f44c7b806fd77e5b99c6f25171d861a0a40b3bd0a58da7f715067ff14a2bb0d4c57db2048ca56f73d375c25508b27039e9430fe591e9f31315363afc2daf1085188a038b2b7465ffeef1c3e1239f62ae8866ff117ed2f1f051baa271ce7ae6dd89d5b237569e2e21f76362cb57a245f42f7775f8b27fb76be2feabcde8c0efed5a1d459c383c5cb866e9eaace7ccbb323d56a3dc52398cfe09ee47e701aa4aa1175c6dd2f7152e7d4b27df580c6fbeed4b3ffd17b2739d311d90d7b173a93738fe4d0d5de6c0d55f960efd5f5b3a1209f05f96ee5fd0d2adf624dfba91fef193ec6f5efcac8ce73949d68be546128a3f273d8a47c6894e8c6a928989597e38958a8e85e6aef8ffa1ac2ae2b615f56e38769b31b5b451879f364a9b88852e879a019c7e96052807ffc671dd6b6ff4a353107fde0cc5b9a18ba928a64587c7157139227a420badd50f65980cc8a680b26a7ec9334b14470fa38549e6d66f32cb3fc637ecbeaf0cb756cfe302322ffd9d3b04c20ee93db6e50e5d9de0c06463e07070ea1ed1fa6a9e67912cf0b2f2dfffbebc53740f6215fd6355d35fda42bf2e042cdfb603e02b2be2b151a6e43c3af058dada9062b15591aba3eab2ae7fc287a0f9cc279eeb787805cef39ba478f7fae2c02ea18c1c95be9e0b2c5c2e20b519df319de8e6f38a2551b96999b21417681cdb76f16a53c7809607ead13f71b7ec2ab1d82af13ff4733c7f4c57991c6ab243e2da3838bc5d836baca3f7271dfb766d25d3f0e0334a513ca3ab0d8073e3878fdcf8af14b3114f8702f8e1a3784373911ccb37f6262f59c2a4cb23c4ca92fcebd9fa0ad9d7aa7997ec1d536f4831eb2ade3412cdbff1c6d5f22dffb7ab210e30dc1ce911b10f4809623940b23524ded68ebc329c29c2140761f97dc55f1e2e2fa56d7a792c6f8cf2acbf32c7d7cc1ca38a447d7184977d0997afecaf7471de1a5ec657a2c5259dd8332e312f8f7f5b99d7ab5895420fbb828583b17e51ad8e42ad8eeb51e48128418e17faacc5a121b231351d77356bb4dc522f66d7ca25bdd5c815a7a18fe5723901fdb4c4dfccc7f1a70457c9af82dcae21c7ceb6e4717b6e95e25fa2b8a013afef3a162dac2c1c9debd98a42d454b4d1daf7ade75505a2c9e79604a2d9b21bac056580b9d9798495087d74eec7a3a94b52cf9149ad61193c7bc8afa2f991043e82dc0c1c3b9bbc47b8a47e0a173d6b6f58407fa9ac3d664903ecc9dc74fd198a04f9c56a0864870aa386924463a5ed8e6415adc64abb02b9cd0b0888339b1719f158b625f1d332bccd41e02c721f8f7fcb89dd32b3fba31e8ac7cadcffc0f17c7e301f5e85131477421644bbc41bb06469623aaed973f152b7b4d825cd37f58f456bcfb6c5db300d214fcb226a469f65b488c36701b4ccef08581a37fd784c1bb14959ad33c88ed0a015073d22d7b9c77ca3245a16f11d0f5ea53b3c4435f4b4221cdb091783da5a1e002f0e42960beb9fb62631246e42cef8af2dae5a67408b2d4b81e8acb0c989564bb4176b533161ffc5f65e5e28e8794470c7fa93dc613320638a834d9b8c7201d2d1b9dea278342f3e62cf0a62a4b8f9a7c44902e0a230299e70b5b368fc1e354aa8e9a243d4811fba2ddfe387508e87985476b8ca86d19d34072b452d8cc4452246c9e1e3ff54d8e4d80bc76125f21a95ff921d6dd4da6a3cfd4fa1a4cafad4f7ad4d87e251beba36d7c3ced30b19ac8f030b7bd41ce0f965bb903eb8f8f071618961ead8745847fff35f8f6d930ecbfc455999c8cc4a86a8c279b1817e455bd5eac6933ffb9f79509f0a49529c2ae54c2058ae45b1c4ffcce1c4d272411da546c2b29e5085b5b295cde1e43c9bc304e85946e7856c85deedc2db22f0f69f8292cfcd808cfd8c15a1f1d3cd017b5c644b0aec48a4ddf116ac6878ed6cece85cff1989d892cdd2381dfbf9fbb012e81fdb7fb5564ddda2612ba76d7ddf7ae98c2d449d090e260e9efe94a44d405d9a7cc834cb55e51707d999c2bb152f8412b8437f61d2b0a0fa93d1d2c5a53f2b9b27c499cc2a65f7f72903b14a44b89aef2afa070947849dec2457194c9d1126637af8b85dad2e1db05a681b99a955ebcee5728cf44a282faefe010a9514f917570b17950b5791989f131ecba722a48838b677a9a858fe0cbf5a2e80c4e58d620847e77a5cd7938731033f7fc4d1b92e775edda52e75a8e9d05b4197d886df0157d0258bbb15d49d3a144eba08f8d9a05c9e054e44f97eec47a57350be9f3bff249a52484c1d3a848983e21901eab2534f923ff5c41127df9f7fb449e011bbcfa5ceb3c8bfcd3bdd91bffb577272795fb5d85305844071312fffdc31153c4151c89f3e8b11989e7dbbc662fedbb54a21c878b0331aa030b05847330c310d2b2e1910f1324b399c0c6ed790e9d2c3dbb526e90e9dd1080748f54cf7218c6af1f3610f6bbf6506f16348b5792b11c167f143cf9c2c9a0ca8c0576ccababb600cfb27ebf982a47e0162d9d9e31c6be9dc7adcf3c7667e5f994f93e2033ae97db9f9ae79e1aedc14f74262dd639afcd4dcdffffecc82507444fd8c5014ff9e97b0e873213d2d2cf716b88db97af39edbbd79b4031b857c930e73e294988ec34749769ee66a82008667cc3a4720251991011e9deb4b01e54024a97c9dc58b32bcc8152d022a3c4291ea148e7a5f994bbb54fe3a745c3bc0de53a1d3965d76643f8b6e364d1c4649f5fd8d0339ef0cf0c009290e8ef94f0028e8a6db0e07570f3e56d0d8cb3c4d57c1464e68556ebad9348fdfcfacc41712470e182ef04eb960e9882ef6c623246a35496673eadc6374886a71cdb6c1abb2715c721b7baf8f846271435332de233676ece8eaf238ae09c8d8b3c3ba383019378bea6efce0f397e4d1985a648453433208c4314d6af690e53375d436fdf71c0945c6f4b7149cd43b9c47e7baf829483959150906a66990d1dc8be181dd49a0fd53620bfc12a53465743bb59477cadd6344eab9aa9c88e973348f08d28989cc771ba5ae1103222aa3278903ec9f6b8694ffd0859d631e3c77ee71f88fdca3a7cf5fc425caf39693de524587e8764d924d24d28fa065d7e120df876ef98a7d3f4867fc1efff940924ace53b9bb2819645fab4de9582956c0f2d1b92e7e59027ea977828f3096767551145d09e4e0f7e869cba36c5d6e493ae124768ec5fabad4a4382c6d2868ab5aadce2933f012441ad39c3d48e39ac60cae668f9191f19c336374b1bbf85ab8dbcd7ff82ff35b045972e4d9e9d82b4d295139fe79d64429f2b389df1814221f660ad1a370509634364d1df8511269ec467cb17b6663bd4f0254e2d5eea43b82fb9ca5c1b9126ef49b904bd1fa9cc0f9528e2d561ad90c1e1c2e9c33e73314cc1fe13091ccf2215a69eecf1cea971c0a114c97892f8d9cc5a13c47b443177e2e6a8cca3b9ba8f62547e822a64615b418e772dff1ec92c524c1922a18fc672ce2af79eae5583e87644832a2e870f1e1bf64be855b9a29a3d930292e7b645ada5838266da83f7f995bca2f5c28927e2a57900deea08fd75e382abed17a0959cad282d0a1b4a262a8f3d89c88b25868cbb3f10c256c4ced1e01dfa147c9238cfb1e117b9ec9e1c9056ccf4df39bf85d84656b9571f89c85f225d98f4eebc49fa36f6addc0b88562c8d7be509c62bf9ec272ae503d9393f33cdc02794b55d29e9ee18d321e344d4d3091f0ab0de810550f9083de67f540ec4122e7cd9b02f6cf5d491aca67e74b7a4939d270e10e7048dc09b623582d3b2c32682ecb0b9849cba293a816da44564aef7e43b56ab55a65196b6650c9123b82bc86febfff8be406d9115985fbb3a9b7733678413b6b6e3756f79205349847f8a47cbf884869bbffb7b4ddff1962559ae32212fbc7a939d75001aab2c9d9e0062bfe9e3ac612b5b1542bb7479e463dfe790ed110fd5c8c7c5229ab13c98faf65a2b254c09396db7cfcb6ba132e9caa20f25a0199e87735d25d53d47e06a1ac054412332d143ace75266fc9cf471714ea6ff39ba351e6172b8d54ccf77d516a66f9bceafb529d397bb865c5f32f52ad7edeb0e851bafa7d1e908963273586f5a448bffe8c1a7dd2a1d169a776b7f9e19864425e082a3a4793eaa605641ae24014dc19f054e9bde8008e5cea1f998e97d4fa6f3d2ee2d1666c745bb7a00814c2798f6cbd50f4cc92bcb4110de0c485a0116442de40afc7132ad1c3fc9e403d37a7722b7ec7bb5211157904ab458d4efbd68b882c7e6352d4e5dfc77c7c2c97cb1ca927a954c5eb6fd96aa2a8ca4945b71214c0c074bd6762caa0c5a7ead395b8f79514ccf7950885dfc46a6d628d47d8a3e501a606ff1110eda16597d60342e8fac6ad0725b1891920d367be3bc0dfc64e804bb76b7f2b972bf1ff33cdff3a22f6d8c56105cece6cbac4b47150b19d905682b1c712dc0adf76e9b2e761cba3043e5d9983f25d78bb96bd518e4d0a37fbc26decd2c4f367b6c23035af751796efc205989a730614bc989ffef56361920572e253f9eb571cb60136fa47dc18199b7ad4920394fa29220153fa31a282db1393a93f7fe68b293bb612352b687dfdcb97fc057db71ea329f1a3bbd21fb9088b86b2e38538e0259e21366dd0cae859e878031753e249f7067370e26ef0432620a51801318e138dfd9fc0921be050a2994b2cd30d5934f4f8c464ad52412db0112187fff5eb57bddbfd7ada511bc6e557f5bcf5b5d53eef5c5e7dfdfa3525162b0b45248ca6efc47297a0b560ba12ff69ed03507acee67824cf06645edcae95e557f11ff9a18ffa4ed59f3da59ea032df4578b49dd077cd877adfc5b303f6679357ce597e1090e9c1dd38a44eff615350ae1efaa685377b984e31f69efe39c2b663a2d2c89c6d8a93697b6ff7fdd9c663f16c99092ce28e47de53316aa80cdb298f7de2d1cdd0f98eebb51d7f76907c2defefed067874905a82e93a030f0e4184750b7b1407b92588667120c6c57d5aaf55fdd9816fdab6e30deafbfeeca047021b079b81693be3b0fe369ab76f8e1cf7a17e7b7bbb06a534f641d9347ddfc59be14348f148d15cc7bb6f9b5617be1e118f2aac57170f0846d72d1871497a8412e518bb134c1dcb54d4c0315d2534bd7033c481d387212a038bf88fdb182372e7c05819d8bce6eec3a8475cd67440f18c6e0251c4ba9fcbb3880dd19b63c4e7d412df036730a4a916202813b8856c2df3b7e41f7ba6753f800d804db812befecb16de7ffb6eff407cebf7fb8be1c4772b1480dad9dfdddb7bbb0054e685f765dab03aedb2805713fcecfbf7bc0106d76bab75e6ff8177a01f879833674796ee2d7f76402638e8bb645a67109f0d57fcd6ef232740ad5a605c568511bfdc2731affe4bb56fd57a7babb34dc04dbfa299e765bd76c0f826a8b2b59395d9adaa4c9aa163dbcfb1702be12429d1d62a2a93bc21f8c8c6540f78cf8398f4ff7d2096b35d9d4c33560b6690e95adbaef5b7f7b24b3cf8be09bfb159dfac3dddde7ab76b0a6cb77c113ec79809bf9873a6e2d3016430ffef456b992b66ff0ad5fe0ad59e19aac516020db71fc151c7aa895dd7f143273c980e1d8a3721eaaa7b641a987ece444970ca1671dfb03f8fd9e826d52b17586da5032b1e57cd0d90defa33040df928690577ce279a72b3e5916064ba29e432372816f86446853a9042b2e73558c4022f377f8a4287b6b47b397bf769410052b3f6edbd7eca93ad0e37ba69b000eef6f65bbbb72bc3fdcb72af6eb933efa8ff65b9ffb2dccfb4dc5155389d60c73bc52f9e5ce7669a975f241de337bf17622506168d131fc54bafb2f7789bf21eb5008f56000015f4c7c8838009dff1672824ae63a35fb6f6cdbd9dddc8c1800bca3d5d6512f1daf0dc796c6b7b77fe3cfce90af3bc49d326932bff659c9f619c9377dafeb2cbaf6197bf286b21190716be2484aed5d7d69efeff000000ffffe9cd0663295f0100", + "360c94a3ccf2d956c9a83e60f5b96cdd": "1f8b08000000000000ff8c54df8be33610fe57123f080d99539da30f25dea1ef857285eb9b1187e2c8bb6eb59218cbb75dbcfedf8bec38bedbbb858540c6d2fcf8e6fb46b36f07dfa42e7869615ced1d4b86b10d2cbf1ade79741889eb52a321ae8f1a5be2faa3c6864aeca9d655731795b3fe3e3d54cde1008e62dd68fc74fec73649450e29a4e768d583e93f3df9bf3844cbe95935c63919d08110a1765a885ec5a17f90f9a32e356036a8ac320ebfebfccec0bb521af42084b4b5d7646aaf61ced009d14986aa5f9142affa87ae4d1224546cd3c07e37cc089489d13dcb01db97975a032609d38d9a2437662c329515df0d6b4e3e1cb6db4443cd1a3ded4b8c74ace25d5afd62f6cb3e86521d7555ee89426db410d2d3fe089317420eaa8fae6bace40f1ff00868c949a77a4a991c98ae90ed346b44e38481c6e3a99c70c89adc00bbac65d74a5fb3866b50b695fd2f064e7db560cd473476274677da1ff17a791aa76925c7e6a099e1b4c662c2cd768049b9dceded6c72ea912c3ad59047a72eb44d1b3226189d0ad9849797abb417db76deae82ce6ea3f5c3a3657376f6b42ff1dea6539a6042a798be9dde62f04bf4a5d8539e8ed0ee3e3f3f9e831362f957297c4edcf9fbbfcdbd106f55fcd117c7afc60df654fc192e83b3c504f85670f1e58bedaf6e6bd8be5ce0a6efda9f45390acea34a4e5a00fc4df0aa90adba56fe9a6f8b30972a68edc90a917f6aabb4052d5a5ec1356c4db2d20fce414ee714cbf416f484c5c5b66670a978cdf8d2859d003fce80fa99978d640bb755919fa905a72e32a1c75bbb0ce3374334a973e72f332ef4707b7c2973e4bf9334e7647ad5edef378f2dabba629f4e3fb9bc4d70c6c5589802199073b9f04a92abe3bbf64c0ec8392215bf98188b99fc484f9dbf8427f564cfd134fffed107ffd3b3bc5ad0505c36ce4c48846af924c64851f5f3eb5fd657cedde665b8addaf6700096b16e35cca53b32555e55b2d650fd1f0000ffffec34951bd8050000", + "464b6c41f07a2f39a73d7d50cf88fd94": "1f8b08000000000000ff94597b53dbb816ff2a5affb124b3da045abaed869bb9232bc135294d434a294b18c6c40a3138b66b2b3cdae5bbdf3947922d27a6bbf79f9048e7f13b4f1d891fcebdc88b284d9cde6bea14e93a9f8bc2e95d380fe23a0be677bd6eb7abbf76afd35416320f32e7923a49b0aa111e156992f1208eaf83f99d439d309081439d551aae63e1870e75e6cb7572677f2b703f17c74803bfc4a398afa5b51039d4c94591c6f7f83316c98d5c3ad4195fdf8ab974a893e5a94ce553261cea2c8362fc907ccad34ce4f209f404710c42924206712c420e7a414eb62e9625385c08729148b4e1709dcc2538843ac5325a8092502c449e8bb0c21564598c1a96627e37d8dace45b18eb7391dea2cd6f122022c0e756e9120439714591ccd81e0ea4a3bf42a17dfd6512eaeae60db36a3d2b3873ecbd25c16a539e026f801e84081a362e550e746482972873aa9421625c2729648d62b9107d7b12605331cea4c9f56d7290894e954e65172f339b871a8731fc46b20944aaf422e8ad2ce0400cd731148f8752740c37594201a4060c5cf00c8c025100196e7012c3c4449983e00751c6e8506dd75499d559065517253383d27607c48a78c4d191d32f6cde5d46393b72ef5d927467d76ec73583f85cf8f5ff0fbd97bf81c518ff1a5ebc3f7f951b992b823f81eb91fcc92fffe18be22a1a7040061c607b88cc2a6233a666c72487dc6bfbb47a54636f5941a0ff6c79c9ee286604c703a626cc495b2afd467ecfc0c7edce00f9e1d228ee918c90666c7636c4a7d367ce467d6127c1fbe019b993f0086738f0e19ff6bf482d613e00dded311e3d9600e3f2621c8413676fe9efa6c1473eab3434fc0fa37179d9bba4b977a6c28f918b1713a613c446cd35350f5f90bf5d87840c7ec3dd3f88e50e1881e33763c50c65e83c83b40ebdd0f045873a203885f7d36606809f886fb8bcaf908c23f5782bf941e6723ca99d745bc8af3c6559a8e14e95f10835b1eb96823483de19b520fe1538428f4c63552f99fbc84c226186a3104691e2cbf76bf2a05e760e4fc5089f7d8f035071cfcf083da9e6018322dd563fc8d2bd069c7caabdab90ad347544247cc9743e403aff9270863027b2b306394402c86e847ce78ee46f80bb2cd637fe90d8f79d245d74e95863d5c7b837ef0f6b593f0274f5c54565b64a7ef5c3a615e623961fade263807e5df39a6aa07d6f2f7371ca5e3f7433a51f97a0ad1fac81464956ba7679819292e8d0748a9dcccac952300dc1da082314a86a07947839266b43852c6614efa09c8f31edd73b538297dea3dba876a6daa620f7ef95085e118a4f3d7fcab2242fee189def7198ff91be5a2df5caca4cf162be58c0d7d7aaeb20b4441a421f547cba116a87252a9c584fc4a5397b1af01d8b9eb325daa01e37b3ce3db9a024d70ce5880fa38d4d4989eb1e1db41dec04003c6e6482970938ed8e47e80fe61a99b5a70943321af87f7e085c1292c60fb64a7e8b489615b4112f32efefa34c43e87c2818a67ae6946b0e731f6cea591cbd817ac8cc265d8be30bcc71e3d036f012f64145f6225fb5892a3efca9c5df5871e33ef1e441fb247d776e6700c7e94eef79af5a7cab0534002d67faee2826d688cb5290715cc7d05f3f3a12e2f00821fc790a263acc8b1f10066cf109ba63f5467846a5e1e401d1bfa63481a3651fd163e8e07a0f64f5fbbcb63fec9bd16f9ca8a85c46a5c72ad1f02f911cb455545e4d233c6dfc2277b50f978ebaa2e43a78c77396cbc531b4cf56a3a6603f6c1068fb02798a34cb5238678ecd45768949f275cd53a08edf217ce94575c93faccfbeebdd5a6bdd3a68dd9f0d1adba488052beb990a33ed3dfe7e6501e7215088cc7d91b257fcdf549028039b3b6c67044f0d87d85210dd4960767d3a315cbfbc166cb4f71e52c1e5827c927354428516719c6ecf51005605e15ee3e80f3f7dc474e7d18eda258383de76df8c79faf7783bdf97eb0ffc79ed80f8337bb9d5b1887f474cdd3448a44c2ec4c66b2db257ab02301399a8e3f7e22733d4593459a139c95499c066194dccc1232930b3d0591a6c9bb0573779bfc40ca99bc0fb4043f2c489fc0e6c5eee581b56b0de08660af46509fc90dcd2ba0d154dd2e09c290ccec617ee6109912b914440fd9448d7cb4e2914b9190451cdc10307e56de0a660e090ab45884244842b28872513aa5065ddd2da831919288f4c92e25e6ca40fae4a2346691e6ad8388fca77448475d270e48f4db6f95cb6652ef937e497911955266325ab4d4f5a3535e3e3af5ab4707c0b636ae1d25ca36f9f557b2b179a1f72e6d1c3369ece8c085655360c973b17bd9aee03d57405fa0071f19fa67cb39c69f244aecb4b021fd5bdb2d765ac6a95d374e27c685d9065c165fb5be6d9bf91b2d5a0d37b736695854855125edc3328a45ab74b04a051b60b985b7c056bbd5b67c56cf7c91c8fca94cf4459eae4cfaaaea9529311741124785d4dc1bd74a0c72076f96ad8d2dba59857fff4d2e2edbb512ccd749a5c56079801a83f2422005c945103e699e5cc8759e90a62bacb1f5f9a0de719a696bdd465d7ded9a8355accb0302d5b769f50b45085c7552683d75de5a59024379bb267d22f3b5a8760d905bd2277b07e4760b4889e3b68ec320c9b021d4792e6e2dfd988d9b25877c97e4977e9fecb66bf016415c88c6aa5db44aba3a904dcfa9378356f4fbef94ecb50fea7d631d4bd2270daf09ad86b54eb16d5b6353a9525f678f1d6eb3d9ed92cf65e327f360be14b88e89b0f18841fae4c7f341c5a84e09a89842a6b9b08f017d06ea54360ceb44bd6494ed9a24a9d46c9424eb382e37b25ca8f56e968b8590f3a5088d984f79ba8a0a51d26a6594ecd6963443cd12156a3044bb66af4776cbf229e937a2678e26db633a1ec4d45bbdf89a6259b656505ef5020e754aa285894154404faf2251cfd5ad865b6f8318e797893bfa016af3440118f8fe430292880703a505a1ccd692449244899e1110597beb6827fd9fe8b51c3e9351af9a06cac5b8a7aaac5ad1507be44799d0b51e3a545dd69a5beab16838b4cc79873d44cb37479ef95bad37c4b0dec50f611eb2d49793504d7f27ae1a5cc57ba24205dc5a21491796b07ae5d6a159156c3212760ad130c311ab85e89dab2b15bda6deb2c2731dc90e7e22dd4acf2629f38664b0c4a92640d4136719349ca09741be4a9327e3931735605736d34219b1245809aae55675112d5abf34c948eb8cb589470f4ef587d74d453f48f50edbc310a3f29eb1ecb95dafb3e76d1f54efb0244dfed1eabcc1ea9a9d30e3a50ba2de81f124db297bee0e8cb26aa763bd0fff1f566f33830ff075b9477694193b5b56ffa3d89dca093b9640f06729cc76dddc74aa45702730144516cc854e7843b54a43417e257b3d250fda6a50b6d89096fd3bdae478d5232b91df081cc5f4937724b03cb524d30993628375bf4774c12a4a3dd1e1204792a219e1bbbff77ae45a2c837b41e2e8ae3c595ecc026967012ac2de256a9960cc6f6b28cde305ee95f1aad8deb56b86580486621f6f463adfb40a48376522e69a5a355f3a55949b85c35192c051abd34585b905534189b0b1285a49511234a75a0259168a45b08ee54e73ddeaa453989f1b5cf26acbde5ffa64a7c04ad8691333b3de892738be95639b7cde0911ce9d78a25514efc4539bfca8b9e5e24e3c5d1e90e7ce759484e805646a97d03471526c57c88d900365ed108bacde63e7e92a0b64741dc5917c220f915c92244d7e37ad57b7ff17d32fb1d36fa5036adf2a74f7330709f84d9f5f56b7fb6f35ed1b6c15ea96e50cc57a51860f7c427a8ddc4ab432b9d89671409e7f9647614b01a76427d8294f910d6fabd56d8fff9b8bf68b1e4d6d8feaa717d379ecbcf857b7f92d7e65b6015ae9cfd6d77134bfca02b9bcba7a115b46fa64e674832c9b39f6845cfdf38ff489fae7dfc5acf6ffe59973f9b32dbc151f94f236ff6d48fa960a75dbc642a816756836a84065c353db266d5d3cfe83d2dca31baec11669ed06dcf8a857115f44e65a06f21ade39487fcbee037baa6b7c26c0278b542e456edfae5e7c19702ecd63e6499a4aa7e738cfff0b0000ffff625b5b8d48200000", + "4d68cce57fd2733e1b5f2e94dee17498": "1f8b08000000000000ffccbd7b77dbb6b238fa7f3f85c4dbe80026244bb6e3b474105dd78fc46d64a7b1933491b9bd6811b6d848a04a42f18b3a9ffd2e0c0012a428c7d967dff3fb355d16010c0683d76030180cd04dc4c3f8a673c32e67c1e8ebef69cc67b4262ecb863eeecce6e9180d871b3e195ecdf9484431478c08c2f183334f592315493412ce0eef844810277008cae1f043c2c43ce18df90263a2212e6b21a205c63bdf82a491508e7a9804f461144fe2c4fb164761a34bd2e89e99efd12448d3e3609a47a4e26e920702214cae058968d219252c106c2fe682dd8a56ab1281024c62ba44108ae9c9e5df6c243a419a46d73ccb8adae387ab384192584138ed918406c9f57ccab8483b13c6afc57887bf4c76b8eb6203183422de1005dc90fb58e39f25b188c5dd8c75c6417a72c3df25f18c25e2ae330a26132448805b2dc486814fc530f0f18e6e30b6c09d60369bdc21318e529263c60b9252bba7f0832480d387c58ea12691d4b0a711c048825b2dd18978c86e4fae50825f765b2dc487894fd930f1f14e7485f87c326952d66a39a66487528932be6ae852ae99b0709fde4d2fe349aa680b6817484be863b088e19de065625a38705d6c51259bc610360c7ca04dfee2856e2fbed831b435e6b20f757cde54228f3223e460c26493a20989d1030cab183d2c08ebc86fbc2002931c25b3f20bd95ed360868a710ef365057ad111c1b52ce22bbbf3f88208859f30243aa3713409315e60bc402c0f2df26227b2263012a95d11e8711250d691f326cb84fe757a6ceaec884e3e836483512b8c09ab2422dee7aed3703cc7c1ae95a8666b44556b9039651d11890923139a2246868e8c768803914e316eabb577d26fd78eac7d2a92f82bf39cd13c4918177b72f63be42a9a4caa710af253148ab1e7741dd362242213f2503007aef9428c342b611df895cd011f32238010a67e3119b3e87a2cbc80dc00f680dc4e273cf59cb110336f7dfde6e6a673b3d98993ebf58d6eb7bb2e695f60322fb84a5e2d556f2267069943b3cace4b18c70bd3148a4935298dfad5ec51672fe6e97cca128501d9dcc70c33c4e4c0f0240b5b2cc8a3dc9975d8ed2c4e444a39da78b189bf039e8fafa46088c9931822eded88974bec50b8ae6143050b147e9921f1a731240e0c0949de432517ca67f86a8ef8e8da94c8c9b5d41ca5062f5acfca5e6a30b5182445c30545014253051d695195c34656a7b246c45311f091649dbb4912dc6599338ca16154d87728a54b2d25e2539144fc5a336d0b7b6c612ff8b441a910fd28ced4c2a94631a5942dea18acc3e7d34b9614eb01b32a740c693f5afa64557bed07c2c62e833f8a3bb4964c92d0a11aa39c7677f84b6686b3eb729c28c9482036e43ee1b8607005b29142a6139eb8dc0a8b9a2b85c04c130e52041ec1720273804ba98017dc552639a6760ec0e495a522ffc40400bf0593393bb9d2703a4485f9c2c4ead2b19a1924c9ebf3569828d2ece2ce5c8c9045fab432ec28659d8bd915947431bba20f6c3a13775eb347e67c9eb2f02cfeca78ea0d7d1d3ee2b3b990c1f81b4bae26f18dd7de20a37190a46fd99538f9c612af0bbc5101367b24e2df8249140e622ec61e4c361d731827d30040e6294b8e5464205808b9d258fecc822465a11c31ef8244001d53964461c4a60a577235daf8656343c2de30f6350cee06513a0dc468ec357b0bc9e02f665745f567b2fa5a3282aa47e94759ac59ad65f3102ea55390f23a95f26b19be9ebd52960e68334a8f8363d998a19497cea22943182435d360521c6a8a0eb4337cd90d64477c52f581a84add202e6f653b936a5488a9b46aab859aa2635a4faeb6e6bbd5e2202eb2ce85629cad160a68d06a49f621851dab774da43d3af4fc6bb5729e233a97d1f59b789e60a25a474fb2283d4ce27bc65bad4a046218ebe60c768a6ea141be8ae47145675e1452d6181d07c7f974d33dd2bf4253243061d893bfd506a1cd2e118b8402fbb6e67f1a4f59bf2ed2ab5f5a55556075936347e8e678f5ea559724b4bb93bce43b89ebe2e80ac1822a5a2da6c7975c10c530f14942846980665757a3d95bc002764783ce3496ab93e649114b81039a76f856628e24907d9922215b6c770019158938cb105b8aa53580446537190044475ee948c9902eae74e444474e280454a41a4b3a45056811ad60c4fd540388fb29d511baf4f4c3d95e4ef287b33d9a472a80f8ea2a6506bf0ad0225ac1cc0cb9b32b2ac780a1371e0513668886002da2c99de9c22e2e9699bb7c13e9ba38450115c384de0db9ef031e29f704d63650f6c6356df68a6eba84e1aa3a9d61227f3b1721e5ec069644b35beb5c84fd32fbf0e4d856f07a0e2059e41202098649b34729bd6eb5d0b51ce041673e93a3fd045a450f524997b5260c562ddc9759968b26397595b152a0b9b1d1bcecf607811877462c922b7996753d085f4de238292dedb7c52c7619916dad7148115cb45a517a18f148c89d1cec7c6ea01b7981e0ad110e416425018582a61147463220664e6212a9d4e032cd53db456a9c6f79e5b40d60da22de6ac9de95d40c133fcb9abcd5ba850ec74d4a6f918c952c3e765d437aec46057d5f6505a157824e3a9fcd1296a6fb6c96b05120d33f05098ff875da6a39731eb2ab88b3d0691ab16c14f3349eb0564b7f746e82849743c8b1b0356e143aafe1b8762b9fd93a879cc534ae902d7ae72a83a0131628df043c9c48ce5f17abc467b968162c312111951202edeec4cb9b8e586e3a242fa48e431c2513166268b10f89fd02632af966e252e79c0f1d37761dbfe11432fbb0ebe3c4a5a9ebc85adbd1c3d4771dd27076129a74d2493462a84bda1b78c126296b580aa261ecef444a744cf0e22b62ae73ce774daa44bbb420486c8a8d47b8f3771c7124b7e2ce39775c24a7e44192c409eea422187d95eb42b3b7a8ec3caafb212c854c59ddcf641ff442a6f34e55e7fd70dfc85c647fc8fc2c435f91fea6cdae352e4e56cdfd430d6109ee26ea4785f783b2f07e05da1aac24f88ae81c83f02c27130201ba8f12294c3f2cc8157c1148360100c19e6a1719e82746f4f642366182351210c3f3a21896c2bf2caa69cacc8b5445017590ab6eebf04e3657ce1381034bb6caf0e2d1b94d9b3d52d7431466cf67d3985fd95ddab7be4b0287516ceabd8f28aa231923d7fb9e420652c2c3dfa581b4677301d9656fe31b96ec05294378e76f59fdbf87dc7552477e08dfde3bee5a7bc754ed638abd63ff6f18647f0f2b387da3f1cdd1bcb1aa4212a3fdacf40d12741771acfa449261efa5129822c7a57a1daa7a1dcbe16dad4847a595813a8e5b307f29ac8b76aeb7d4da14f68a76fbbcefb88ee7389ed376b0ca328b6f50af4bd4ca12dca22e0930ce873cc29d747e998a04f5b0abe87b4fd7d1f970f8aff3a1bf76eee30c9d9fe33e1abe19fbd3294a53dccf06713618f4e5bf6c3fcef6f7e14f5ffecbc230ec87fd2c8cfbd9cd30ce6efc7ef66918679ffc7ef667dccf3ec37f59f137fbfc39bbbe46d7d7d77ddccf5ebf46af5fbf965f2c3bc8826c371b8ffbd99b37fdecebd77e369df6b334ed67a70f3df2eb22bbcdfecaeeeffbd9972ffdac83d7afc97d2de16fcf4eb3b767d9dbb77df92f9b3cf4c8d642827f9273f3b752677c2cb6a44a8d9cec2c8d9804b618cb5a1f39a386898f243364ad16fa4df6688089806f31ecfa7e4dae2314d4b35422863dc926367c899003125e870166b212fff6031120dc899330e2c16425668617168bfb505229b0424eeb2341ff4182b012764c3ec9712dff941576f9cc002d31ecf5d07bc5bf04ed124e835c77f79283feeeb7613014bedf977fa90e7810400995bf58a3593f1f0ecfd3f3537f1df7934ec2669360c4d0fabfce87d9b9fff3fa35711cec5909e7e72a6ea746236f5679c7b1c425bdcb71e9090aa448d4977fcd7109c39e0ceee4e74a0bb91ec906905b3fafdc3c66330b52add5caffd8ecebb9ad0eb5d4af9d49ccaf654eb51506e1932d2499f79d49908a231eb25b29d1bfa2dd56ebbe23582a817630a32caffd3d493029c113dea6bdb278ff3b5d3f0fd7c96bf9233f7e961f0f9b8b75f2077c6d2dd6c95f747de8b6fdfe79f8b0bd58277f2ad8fe3af9a2be7488b122a8a304443df48844c84d40e24c5881b44724da0092dd75121549ee3a89195dff92c9b0c4e9f581cceb88a4a578d4f75412eecbc4b944d16dffea3f74c9c6f3edc5f0bf82f6fdf9bcdbddedb6cfe7dde78787e7f3ee8bae0cecbf9081c35f2170b8bf2703fb871038ecbe907f7b2a7070e83ff4005b363c9f77b7214377fbf0f07cdd24a0f374ad5f4e344958fe2ed623326125461332c3df274cf2891324705f588ba6a515933b983ef78475483362a5493b42134618ee03ae62ff4a8a7da127c5baf7ecfae07686ae182a468b737eeec8a9624f1e743ec499fcf171763e44c37f9dfb92a5e2735fc602ab4565edb69cf4c530ce329e654996050b8cb1ad7b64b6c45694386c9faf9f9fffebe735b7df41381b9efb0f0b5fcee0f3f39f5b8e922bc7e5f69bb2b2602660322fafeead166274c87c4ce66a1396d827991c3f70c96e6ee1dc835474b272b33c6643b982fbd412a466ba6ca0c16e08d30c9d8b1b2aff64d9c38208d9979d8b1b485bd8cd71918f012d05b65a2334961dd96a8d554f12deb9080827b6487a67b7e23719e86f6e6f7b9bdbcf0b986fa5967eb64525bf60cf7add6e9376b38c3ddbea7629ed2e3e22e7b343baa45b3ac6908dca28ac2b772c4850a11a78497ffdf5d75ffb8ee332cf711d1734871f51970c9dcf9f1db2e15730d94b94422569b033c96c5b329b23d31d3be1b3439eaf48f9ec906dd2ecdaa97b487d11e7cec1e4d0847a98840c6a1931fdf9d9217f92d72620839c913f8af06787248cfc6545e431538672da4c924fba90a071a1f249b95cf7e906a5d40cab7ea034b36737f17e741d89cfb25918f6d4183498eaf1d467cd73d567822c475c8ec35e17806bd0d01ae5b0a4c845f2efabed5ffabd5fbb5d6f836d62259c5f3372c9e88021e7703e997c86b66e7671314307651695e3e715e533efa35ba6354b84e33aad8fdc0a82f6c7bb3190f689f50d5b29c1b0ce453874ae9970dc5c17d7773e9ceda9c367e12b0d95a5d1c9e7a485a6d5d2aa7110f08b0a5350f2c8b9a607376eb57ad0d5d3988bb1ccb8f12b844390063439e923e4709267266f991d0449e3bbd96dfef256b74b7485b4661f6799faca35b68de3e078c73051249e214e7b1bd8e5f819cf27bd4b91682778bdb74164ed92be623a1bbf7a1bbf789bbd76f2ecc5b38dc5355bd2466b538a2585b48e5fde221a617147bc5452ad391c1338ba829e97dc9a5266a8179ac8766f413e2267e090a133180023720671ede12c20d66deaf6142b72063253990db247046cc89e9e8ee344e4e33147f46f60b291ec2107221de20c1423d3c15f14431a38e44ffd35b01819945b99feb95869d1fb9e5d33c36a74beef66b4f300071c48e2068ebfcc6f7a6a316df70ad881825e86b7f759dc482abac8779241c99553ae805aedbea395487d2826f0a688e3d209141c64c168fecae8fafe30def7fb7a4378eecb2d61769e625792d25f27678c3abf077c1e24771787ec32818f41908cc617bbb3249a5c0c82bb8bdfe79c5dfc3e9fdc5decceafe7a9b8386533c1a6972cb938198958fe1ec7df54c43e1bc187d34967934820e7c2c1e4b32a459620914bd406b1c42bd14a9c129bc42491d8f90b76bacf2aaa62129158eb4164bbd9da90e80a359586dd6a4c380e588aa5435f6bf3e5d663509790ca61534951bba6dec68eeb2638a26334dc609b24f1f18a3cc3c4a7c5c4d3332702b9b3a602f5145570acce9eab91fa30f82497eeb77b4d4a5140afade3ab6532498c713f00a59c579fa342939de1df292ccb7eb89827675885fb914a176bc7a92d5fc380b2d643c37d994c5892b98157afffeb3c747f5e573b5481b1a0b748e01dd05d4b6c732428ab63856ae20b6c1562bad33e1c510baa5c22cdda4b048623f3c7564807aaed80605d32453861cb87e27d749a4b1bb55249b35b154b347eb563396074cec83bf9b798c67f33841f2c13bf32bbd5873a46545c14cac6a14f02f927ca75a8b04af6364091c2cd0c143e26c68ca43addb89c2f20fc55924d4af40329364aa547e9a432069aca7c45f957895ad08b5e31d08f6212e810e87bacaa6d6c0170a4932348b6f917ac4ad4dad73aff428e1be9f38c4c763776881339869f545741ba84ad0c08ab4e7d29c1934a790c435283a1188f7bacd8574b46af26625aecc37a5db9a17b45bb7d9416a7a8ccddea764bf9487e049976ae9930a22b88aaa0ffcf6318c69e8daa8c26b5b4e9ac90d7a22b64d162d45b8f9c37155ac81d2e37279ae2a25cf9a7f3e16ccfb670e3d8aa07d8f27e38db2b5545c8aad8914c9f937d0773414ebe6a583af837e53597be7045db88c56df4c2952d41ba24c19aa4fde00ee1b6c0cf5eb849bb57e03966b696048c5c494c52da735fac21d1ee6117bd70793b9119df28a9a7388e4f5fd26e3fa6770c459449d8d44b5f810ea02f63dc1e8969da8608ecc91819c6e44172452f2261707772259bc48bad2dd3e1b23441dfd8bc54f2c7985ac7dec073352a84db51bb87d75f6037572bc62f7bfd84c6ee1143013578da3dc0e4c5af8e2ac8fb28a171bb1a4b8aac6e0f7b162692d01893871bc6be7a0981ba05567d8e2a3d95f71c09e0db558498a31268ad76e20678fd4581e47d751fa94e5d0579813ba3988f0281587e122b305e7c44ce8ddc71dcdca81dc74dec10479208ca0ae7934cfbf449a57d9269511a7f52c97b480112e746854c12713e29a95f253f87ef3cf1b912da6ff23d802c3adf037ccaa365a9103d9322f88d2ce606501399542b878b61624e82baa4878d520c6a12ca2d8d13ca2a84c19daa5d18fec83e471b81a5838857764ce1bf87a86ef315fe9bb82a6898c2e1e86455dd031da9bb42c5ef21680fe2844597aa0856ea551577a03a1602bd5edec976d886ef69d55598f72acbbf0ef22f59e355bb37abd1abdbbef029f96a378ce193b2dab9600cca4caa5485e1497b4183edf1dd6027ac6c0675132abb46553a7489ec8255633f1fefb07fbc67d4399df330b8bb18c4f0733667a9fcfdc442aebecec6f3043e0e9348fe9c06629ec89eb3f77f9f14228945a290d9654699476628c1fe06b01783f8e26c7ef1895d9c8d2f0e938bd3a07e43f8f1dfda10965ad4da1296e22b7bbf4ff569d3882fa5a87de18bf2b6b0e763b976a004afc899efec6c2ef1bddde132694b689eb6cdbc7914c793b69930a21fd9fa958a28ed19bf9371b992dfdf0a565bb75ade8f51fae82e72a99c55d0dfa3e9c7db6055494faec063243d3dc7ff988c477b1836801f601ff90ffcfdbdbc9b7cfdefed2635af18fa24957fe6f2cfa4bcb17c51de579a292ca420b63455611b4882bac9a792a2ca9c52b1b1315a23a9fa0a3099abaf0893499e3ac953272615288df3ed659a7fcdf3af4965f3a96a94eaed640a7bcfb90ecd2134d1a189b5d52cad674b9bb8c9ea6de0f21a4a6b305680cd42fd04d0c7f696f32792f5188ef4fb3806117f0c43fce80ef7675651c98fe3799222fcacb79165bd8d02f00f3dac3fc25e6bf5f1625997a4af07201bb5227f1af1b960102c1fc7fe559d3f17060b4c4b29edbf9112fd9b37faa0d391789574389609e3b14ef89941e45719f9f5eb778e45357159b6b1a5e5cff174ba7c26abcdd71cf7676659f560f708556ab5810b3469fa3f4264e252368a795842fee6511aed8a3d42e19bef50f83d34abe8fb83212780e348f8dc7548b307e238741871c64a1057a1dea6926b0387fca54f88778bcf37b9a03dcebfbee65f7228e4bb2fd9fd7940767b91221beb4bfe2debcc0c7e2be94d910427276f1c224bf0c9a68e90bbc3af5f974558b3eb9512ec8e186efa74630b0eeaba5e929fc3040e7176ebf2f2ce4594be9b5a627794be1bc065a2620a28591a108d650b8eeb3041d1920802d2b8be47439b5d73420d0db182f8dca47d63c7e029f6a309c6440cb74ab1326e7539b225bf57d216e81b7eb458b201b1cf4bb1c16a62defc872b6de1fddfafa4d920fdc9c81775fc2f6b9baac9c6047d9003888741e23da4c194ed07779e333c8bc3e0ae1108bff1f6cc219cdd0a133f8d9324be2925495948c9a98da1899f04a9cef299a58225363a99a6f20cdf06a9f01be5ac928a8349ca3ce7adb32065fb3aefe1edd9a9e78cbde9d44bd3c6ae43de9ea9207c7bce60b0bebfbfaeec3ade42783068ec938689a94435f2ac902409218d3a8005b1ac043d475fec6a8481600ed1d69b9ef32c7494fa0e4e154e5434ac459e32a8db0083ba4920a26fec2c9a32efe16a2ee609f39c88379ea50e9905a9f09c676923b88e1d927a4ed0b862370dcd2f1d92a6b294223c95108ac33a643a8544cd701d32f69c803714d31c8f216dacfa3e94d940671186102fa503870c009b3abc1e0c1432508e3be44e2629039dbb3b489181d4591005e19d316229d2bdcf0cae487a0f617ce3754918df79db0b736b32f5ee19b18412efb722a8b27f62a4b4967bebc360e69f77fad3fe79a7bf1e2d8810f46141b828199981f898ab03fb1503f1c284eec2214edbc19e75a01488dcd6140ce5d5165c0c856fae1a362965ad96fcdf5c05c722b97b48e89fac73115c5e2684a38d17bf60e474d61d5760120994e0c5080c62197ec86f6448a4d6cd6f611fdc15168408719a2281fb6031eac50a0cf7ff64947bfff6ed1db5296e382e739d068f45e32a9ef3b0d3d88fc2c65d3c6f5cc5c935130d11372671103622d1773026a686d68d72919baa28b50eb56cfb189c33888ecc4299be9529c490f9f814398a7045c8c937962451c81c0257e9d5cd437d72a720905ae28e832923b28a57d13596e48dc601bf668d8037d86d948a885f37f46268b0d8e5d46249c7f17c1236623eb96b5cb2c63c65a1ac7f03dc30488441438ac82a6be394b1867601a10af83bed8ce2e9faf53c0a59bafeffacebcb50e9ba2ab8adf2ad03ca699cb046c4afe28e031b32d9169d0b45487ec6aadba9330b12c685221c17f162584ef271521359c25adc3e469cca115ec69d1fd9f2253459869623e9d0c764395aedf11e7830651e23aa784f2cd475dc9d44ca292ad29a01cc87edc73b7480e03aaa44cbfc560b7e3a577172108cc6a8a4159643ae230b21aca3bb50aeac91da32ca7c06bfbe8e0371a47c4c0e93c93a0b93b3594b51d6a71aed608a5a89c3a499db32fd09c7e9cd08310c134150b0002f4c9dc0907551b5a72bfb0e529b7bdadd890a3b560520280aa8e468c3c8c746a3d8763036170db9ec5505e0f67c8cfbdc820275c48e78d5ddd117e0028102eb3044eff5243e4370026e7c5a2d6e6ea452d16abd4501e15258784545bb872f13167cdd11edf62272dd45de108bd21dacb9b0ef10c996cb556fad567b8352b8fa9e5f52873b387cd8f35f76b34cfebeeaf5fa3d8f0f37fc973d19b3e1bf7acb101f767d2293717fc3e3c34d0dbee9bfdad8929b314aa90cb55a48b26a3edcf2b34c7d3dcfbfb67ddcdff4649acabce5bf7afe6b7fcb93302ae639c43cf724ac8ad9f65ffdfaebaffd6dafdd2340f785217cdf9cafc91a4860f16a43dd28dac0155029f0a4ad56bba74c1091a02fea40e00abe05f48b0632305494ac2026c2c890154b0866eea9f58567dd5e0d45f9de873ad51cfada5ee4225423af6c5caaaecbe6a7b24187c737a8387e659d8b79ca3e9cedf587cb27bdc4440db489a4c84f5e055cd95279aa194ad01a540e31c23a1737ea7a30385408861b7e29d8f35bad15575c5465c9bcf05505162d1737b8f3fab5b97b2c3a9f8acf031cd11e89e916e1742299e7ebd7044ae9fae490a1af0261d2235b184e3c255b07a04fa4870942810a1d901ec6721407af5ec8a131a7cd2ed6bcd9e62d52fce984f10d9c085463ef40829f5053684462bca369babece699a9409b9211350e019b708a213f6255da2136239588357db394566b874581f20981b11243a0c0675875990d80b68b44864959257470c71a0a65f33da69b3abd1ce6b92c3e04e02a0941e4b24b9dd82ae0c55e6e7601f6466194d8b136d0cc3a1b8c56ecdc45856dfb44932ecfa98201be4d51d4331ce32f05763c5cb2aae98dfb2e284d35d8662d22dd1a409eef9945746ba1e9e79bc1ac646b9b9591ab6c2079359fd4d41e79918e748b92ab4945ccadddf00757ccfeb7a061ff043084896d835812d3bf0dc0e6cfbca2f8bdeedd16697e8ecb4abecb4282ae6fa2ef3f618b62d33524c60446b00e355c058597826024245cf89fb292cbca136081968759195df44e136d33e1b0a3215cd8152a118fe50c8eb9d8b9b4e08f86f3a6193d2c8f471c5c709dc53067dfb48d0f57f9da76b08f53d7569e9617b91c1052bdc467def3c3c0fdbf24ff6497faa8f4cdda5821f8c51df436759032373e7a9f23bec10ff3c74711ffea1e1b97bbe743f2a3b4fd7bec8f49fd7c9d5235469a20a9a9e4652f9e747091a8b55b7bac854d0a1b9f5d11e0cdafbfb0e59cf896ee70db8eeebcb213910d4a702f0faf5ebd7ede127ffd3a7f6410e629abe02514e5f27cd5e5ec47ea98087cd855d7aa9683bdbe7cf83814d7eaf5be4d329e7e1c32f8b9c0e2023a7f35351529e68a76d2cecc272125f2cd67d9fcca019dfbc51ba8ecee9e9e929249f875efee7bc731eba80dfc0915a3852055b822852ed241d3b9d9609c8ff59c54b18520343ca2095d43cc58ad7713a4636c5058cfef5be64a1e7089db7fb72a8ae47c5c6ff4ed4aef6e04284cce94874d82d1ba11467d955fe2d2581b99278802744690c6e7ae0eeeb54542fbf4657682ab7eec39eaf30cca52c8a1f02aaa2e56a439bbd26d5e10d7f07a4e545be090bb0e52f0d599e879a3d45cc70d337b2bfa4615647c3ac42c3a6a421a2683edcf0b3cc6938d89d697aaae5478f942fa19a8971bdf218a4a274cb877d45732c0c215b3e7e2c574c9d2fce029cf9042e8ab2cc71b08b62f825372237002c650396fc4d76bf645f8398676773967d626176369e678749949d06223b9d734cfae729ee23ad66c3e729fa3de0d921bbcc064192edce926c10dc65bfcf79f6fb7c92edceafb35336cb4e46223b8ebf65fb6c24b3c83949b616eaf33cc49efa91ec4d7de1fe792a29f97096bd1e9c65c383bdc13b7f78baef9fe10c0dbfdcfbf247f18aad05c63faf1743f4ba18a2951b5eb921e34bbaf56b7f836dbac21370710fee70c910b4c3a5a00f1fcebc2e793d907f0ff6cfbcf6c656971c9c9e79edcd6e97eced9b0f88d9ee92c1bef990315b1b5df26edf7c40cc2f5d4b7d36a89f45644ebfe95e969d635d3c45c37f617fed1c67c3737e2ee00668c3be998aced3f3d4c54bf1ff92f16beb956bac32eee77565a1aca6a6127b91a07274114ee568270995439d04743e7cee9388ce87db3e89e97cf8028ec7af0512987cce2f2d218e49dede896cef22189483910cfa246eb5f4f9769e12cb144c14cf685615f8da8516cbb24f45b10ccb0da9d93509c91e0a0701b9209465084e2196e511c2ed8940e414058e432624d731ec48d9874e88766955a52b9254e8c17529860cf679c2c474b5afe5bc921c5a23a0c9b35ed738ed41493bc0ebbd6e776dbbeb0692825f7c321ffe2afff4a4680d82e12eb3254149944af811990e58b0f6b0479bdd3a66505c2014dab59e64274d4a83ced1e9c9c52fdbdd1eb623df1fee5d4874f801da69e8ab42c01b1e6d7677aa1b61c771f582616eb29149eea4e91fc04bf2dd19ce3d2664d9d0d7627d627b3b8d4086278853946ae0114391ec3ef0ab2db726ad1642314d8bc39dd41ab7b9aae755b7d502d22dbf886a84c698a4323be875ecbc2ecf1d4d4d5c5a047e1b467e1ff1bedd123dcf42aeddec19ab8e0b493127ca6f42eeb2afc94b0495f3ec404ac9931f9db72724fd6e6d526cf61c2f696fa3d56a768dae489fd281282fd3250e64a75025f4eb715471a5083b1ca3fcd220c5416971689aef786a8fe8764aae2c795f78661763f24b42fae520dc5cc901a3f4dda08f50a23f95df19f152d6150997f6363049b2acb7d1a454649914033011d8138bc2779ca191587463122a639a6219055eae54cb201c593766ad8508863ba8e8ae2c7d8e7652977f65590a3bea89dab751202ef7bfc85b2d4799835da007cb1b677781bd9acb466ac7165161293a66099b996b44648004ee4bc67989e67015c9431319059c467811e2b8bf52c723399cded25e9931af2ba6643cdb73a5e4b24654a9bab683591fd0ee4ef0d2c2052ec7232a85c46fcab354b193551b5fd991e6bb88c54448c147621a06be1477042633e5e02072c15b6079c290c8a5bdee9a7225b9ecfe9240423a8a134623a2c5bb24cba29789f299207b55c85a2046789609d09778bc0f9c73f91e2f0c849d346fe6256d9f37594ecb9dc4caf4e58e5eee247a618911ca1e18c60d8211aa9c09161cbfd5425a915fc491c1932103ed4efb3089a730220f83c9e432187d450c9bbbd9455d5cb936ab468a644d41ab4043240aae5167a2be7c551f2622f66289c4ce5068585553bcd18da0cb190aa5efd2377889e884c15d9609b837470418d5c844583689d01634103399442ae4d792c85aad15542ea0baf39a8ec5de63ad07aab719322e2d43d04561b9445857d945f5068d14231f8cdff326a8e35b2dd82ef12c4309e584e73c1cc588e1b22637ba42b52f031c075396e6224de12bae064ace7f3d8dadcbebca1b18880d6567ccc59dfb662f277ba1eee403795dcb4904b84fcee99f2f3b3e6d7665ace60b73e36534909113ca210765f2e78a0af9a37d9826445f170366782bd05c0e5e5bfd95768230443d75a5212df4778616eb22d857f1a803e71e5eacec767a8694abe8c62c89bf45210b1b510a07c8116f048d848de26b1eddb3b0f1fe704fca5c8d38691c9d9e34ae80d39a435938a416c95cbb97092693b421d13744dcf83b55a30f93c6cd381a8d4d01099b44c1e58435825112a76923984c1a97497c93b2246d043c6c7c63491ac53ced348e636eca5f9785cbc9a329481b41c21a61948ee279125cb310b2de4412196b246c1a7f9375e28d8037e6b3513c8df875631afc1d27920016a4acd37807bf8d845db14452fcb4e3e0bfd3b6a463e9209854fccbdb3350f206d752b73a0d732556fb0331f2aeed5e6c410a91b7140fc3fd4cc83e54b4222c39896c60e3269085a4619dc04f835bf0cfc882b0f3c46a4e23de9e06b7eb4e8d679aaf2bfcdfefd8769596f78e924710f02cd1977f3ce65d206880cf95ca487257574656f5ff92cabc5aae8ce53240947c244959068e02739fd711ec23d511237c91a6a848395f05d22e28018224b4b793bc1485678e048b61e2977ca5c88821f311971c9d83e759cbb5a3a4e654d0a1f1d6f3cf3c4804935fc6ed85be18a72e4d69934d6394e4a8b50962f295cab11c4a9f58e2e81be5115dad8559d62509151d5d9e0c0654af8f321051757b49ae92fa1a968c8ea95e3bbb24a56ae194df736a564f199a50b384ca50484beb689675b531b9d97bd69edde70b079cd79a4b02a782089cbb3206f321edcb65287c6b41c9fdf9cbcdbdba85735aea25b9220d4f655f284d1b2ff2c27a7e38890351808077e03c04ce8b9b5df32e865cb744719927af694addd0edb1cdb589bbcdb6d6e6f09dae6dcbddbef1191ddca5d48ddd176b51e9be34750377732d717b1b6b3c0715017d58e4ce206013918afcdecee5fcf27252f2b177205679843db16ef5be131567cfedde1a5c744de2390f51bbb7c6b06745d89b9dbfc56a6374cb6bd65c8cb4a30039fe1cd7292e6e7761656f3319df7630e1ee11faefff466c7dbb0b26cd02c2ecd9765719332ffe16c8f9e210c7733081ef2fe0af0d2c86bf3824d586c45ff43798e84a902f5f5618fb6aa141a984c4fd94ee0a9432525c7edb13745d1fd9a8c39ef56b4b37be6b73158a04685cb53e82e54f37c98d1cb636b85a3984101f1ae541bbe783dec22df2efc9b13e74da6013ee93806e77d79261cf776f5132dc28b8881495827ed7735cb9534c865dbf1f78edc0bab95d617d854dbf7209a19f288a3983abc5680072d8043129bbe6db104f4a38d8da96b4791190ad071a2970740e813ccd4d963c4670b041e706270c677bec1edba3b2f77cad6d8f40cba5fa7dcc0d4abcde7b6e613814b9ed7cb3595d350c03822d253c730011cae1fca24cebf2627f042af3f37676eee23eea7be83c5cc3c34ec30715b98bcf3df8417dcf7c9d7724883adc7b0fb955e67732f7b0edfafd61b7fd2be9f86bf8b342598e1cd4457eaa8bdc87c8b3e584374fc67baa082dc6f8bda83c4ba035d713ca88da9f9811052ca73fa10fd3546e016d6648424f1deda7640069c0e816de1caeee4f80b5f5e1ce11f3269d121b65d843213d32db5b8ce58075da72b087c39edf6ff7bc1e99d0873baf4b42ef16857272ac713286ef4df89ec2f7167ca7f0fd5cc5cbc03b81246f0e87db3ec66b7c01e5bd7f42799f04144638260315d884c08d0a6c41205481e71018abc03604a62af00202a90afc22030ba5d4a274221b73e12d39579fb45ac8b94ae2a913f1c624cb1c11c317a83ce85781261d998a49ac0222c624a0913d0762dbb56d4cdf081493081309f31bbb8a138662dc4fe96f024524c61e42f02d6170b97bda69294c8c531448802f4c52ec3dd8405ed798367717047a1f77a6290dca98269d01bc98a1702420c19f0834c104065aab35428c387a318447769265fd1a269665eda712bb36bb77bdda1726ccc4214ec7c9cdb090f177d7ef7a1caf59abe76fa2f202a061f2a60d8471aed666859bb58d35248c4f88dc591e3c0c072c18f69c0603f83deb44e9ee956009e8b4daed3c8d977bc2156df7112cf6530b1fc50a7f84f9c5f3b24216f45fd00a6e2205d9532448b145705ce13a68c692280e49433d4885cb9b867c8357ec1df28c2a03692804b8f303e6c04118b623fe8d258285ed599004d31a9be000f41f09496880c907ed27e15ec8595d55acf1becb3dd908e6610fcbadc60751be9b0fafa994066c4cdf0924149bc324d5213d80774a3e14514273c56242d2560b7c4c81f346e337c94dd7382671ab056e189d7db80f71537c633796005161e2038b2f2b2fbe91848177054a2b30237196a5182fee45e78ad313eb0100729f3f4254e360fb5e800e572d85ff08fa51a01e7182307430f91d82ed1e71d2f9a5488291b0efe8bf2e4d96fa59e0a29a1923e77e655cebfd519a7bb56e23ee22d14e5e76fbca3f234ada953c922e930b7b1aaa02e35a30ed04639c6596cffb9f2d0367eb345ebdced6b7457365d0ec15c690601b0d9b4b5b8037ae3c1741276457c17c22b4f2dcb2dd393376255f1c5201fb2046b590c32fbe7a32ef8ff2567e12f06bb434318fd4f69d94a7a67d83b421e206dc5c18b386c4310fae99b6f49f27f00c42a7f1613933b22f13987c695539b3a221edf23d2b46fba5282eaa8aca1552ddb645affd59e275883d13aec0cf2c2efea56ae96b7b945a762785dbbd8ded8d8d17bf747f61cfbdb28f284b3e2ef033fe087ee3886915fe221dd20aac829bdd57970c1931ca529f744b4fdc71bee46ea9ccda59ff503b6c931030113d245ea1881e19ef4b4a2912619270ebbdab02ad555cb25c1c2d797c2231dd6528521af92e892cb3d39d2507c9f1b27b2b62b92c8dcb66a13a0dbce1c555cb50c9cb95cfe4ebebef5c42be61ecebe71affccaf5f7f27a3d69494f30a8e9ceb6b59a863103b456c4df4ebd7b220c74266252ca7684f3bcae9b0ac9ced6b47c7be7e5db851fa6c3c411f56a0b4879dd78573e8ebe253169c5fe19554e7014554e1345a55aa086baa0b27d2bada2a021cd2e87630eda1aba9327edf3dd386e59e49a353555eeddd66b5ebe88fc8f913fc3bfd195bea3868d24237f7a76acd3ce285aad89f0ef95ddd46fdb3c6f974cfa79b6b48f9833545ed3b64e8ecef2ba758fbcaa39460c69712a8f8f68d9f2419fa5515b49fdfb99679f39ed88f57b922627da1edaa976e4f6699e85cc4f675ca95a06f198f1817f9dde77d49debee3930d55eb9af2c570435d9a552a8d3fc12ec3a856020e77669560d3ece21dd922fbba4de4efa66c957ddd2e9a4be48ea6741020725f522672cb34cfbe4304cb03fb0ef9d910bfafc8870ad469860ad378cbf7d75412379d1a9f075a11abfc141ba5ec543b2ad6e19ea6659a779acc0f9d06844c6596a9e3932dd52ab16a9581b969daec41c3a4b2e43435256b5d2f949c6b815355b209f7b483b4342f59e62f4a4e6596d4f1c9735572cac95c157e6aeec0cac2afe2047d44cee92adf04fffddfc619412e0a23306bc205eb3c3d5dc93a57652fe53e85c1d02d2bbaade453ed37bf8633f7ba6bcbf84bb865eee72b733f21fba943b657e5679b4fc87fea90172b116c3d05c1a9437e5989e1f993309c3ae4d79528b657a080815f740971a6a919fe566c6f5b8dbf53391b259384800abd362115fc19939453d5a73ba9518fbea4bfeea4dca5cea9834386524e02660981939cdd6c4b76231b1d39dd8ee3c2b9799c2040b902df14f04db89a04a1997ec5be2e9f83f7daeddd7dccd9eee5a57677726f471f0753e6284c234e2f8b5d5541ec55c9826031e272eb41ff116404d215380ca06536aaf5155906579412fa4620753000cfd225e2e40a695f84110d7224fadd1c25dbe12c73ccf57f87c47007ee048961e4e3befc6b09761c7b105f92c7d4492f8ab36cd9c18c2910a9630cf2558081dd026a24b75735fb4875eeae763f122e8caeaeea4dc38ce951458d6bfbec97a9089a85a966c1f570e94d2497a1806eb3ad3594d84713edea59052682ee2281f1c32848993aa0f322fa3a6fd0f5de863202df010075605782b0938db05046b16983e8d9e24514d2e195015682d06b8a0db1cdb66c083821b4d337b7d9731b400e9322bd1de0f55fb6b7ca2070e45886d9ee6efd9203e93da8a71c59b59345eefb2df26e50a4fa93f1f0e46af9aea3ecaa7cab8718dd4560b1596217721398652bba5bc6aa371aa8a5c6ef33ee7d11a67f59a9cf04555e36735faaa44b7ab8ddabed9d0ab0bddbd04344079e6dba9b4b68f418780c89db5bcaa5dafbb14cd6c64653a16d9a11765f54b019f7a84f4788eccd0b206df796f1c2c0d15f720c3e15bd5badae1aa242779fa5ab22c2a572b8b6ff1448b8c8eedeaeb76dd6c1d21495e0d53ed073644501db6c0bf0936db655c969e6df8a9c3db6a972f6d8266e178f806a58a37f138ffb4787c9a198696976b02c43fac0344a3f8811c2fd656d8f5789520b8da01f8cd3d69d954ec066712a340f176a865e25f194d67b2ead9c97c18960c9d80256226673d9febd400f2206550d91a83db6c81541b6fe06e3ce783e0d7874cf505394743bb58fc619528fe39bba7779d4e294c453757d97a90c22fe0fd70c6a047513f17fb266227eac5e222ed5ea9a893ad013f5188c62a672398790aff566905317bc2b6a5662e517aeb807af32a813875a39640027c3eaecd618ef5557e72c6b72ab0d5b2d5465f1482daf15deafa82f26de2beb90d9b3bed5933846776b8420619f4feb7aa8d3acffe315796957a4443cac9425d26dd8a21ae286314e57f909b6eb42223a504fe87d15c54bb2cd26aa0effc00e44956a22a85c42932c731076e4d6bdaf11a8d3a8404a8aa6b9f4a1a18c83dc581923f4f23c1a20b233293c32ca54f33498d6f615499eda5bc97fa2b724ed567f216e07c977c7de4bca5b2dfe927ea79f4bb53e49ea665c996f493888d752b86941195542553be8bf874bf79085ece38a43a09925b84f027e4dff80dd8b3ed5f8d90a48c647ff828869704b3fabaf88d333f89a05491af1ebc349709dd694036f386bfea44a2b5964182f494be7e3ca99b39ae4cb96f2dab72b242b43337d45e661ce23e171324ba23889c49d773ce4fea258549513d5152ab68ec9d516f927e87f178881f11dd6a6683c7faad87531f06a3e4cfc8e2cdb47cc0a142fc45438bc2d0bc3cb88a5755fb5931a95ff370ae0207eff4f85ef0a8a2708de951cff23a11bffff2070e3ff84b08d9f2868b7e90fcad84f96b0156690ae9f2c5beb3c52aefe9f48d5e6d099fe2e9468054fafd05aab443d6186f9931ac54b83f97b4a0c0c5c551a54193e8df60b622d6d98afe5397d27e1b152e13992d4cbcbd6b630050992002fa7031c0b7a2cf7dcab9d107accf2ff6a0c6b98e5ffb5647153a2364578a1c995b2e80af58cbaaf525a178dd07a747aa25e4ca7d57b38f54c23b77a1414aea730c2a9e89796c7b9dcf378562b35b86e1f7015a5bf5fc193ab1f1027a25ff283313cf36d7f0ec32fbee33d06f0c5c1de897a06a7789bc7aa18ee6bfa5413216c2722ecad682077bbbb3485d6e4c02e672f6c8dbe3844d6c6f9e260ec59f5fa4ead56d5494bfbe9ac320657768db60e303b04b4bed6d0be862f22d769acad63654ac0a8867488a08eb3a391bd55a69bb079cd2d29adbaf70dfeb918399e09c0e9db97983340f6452b4c3975868ecbdcff428eff5f72b17c693fbbabcd36f590d04fef82ef512f7f9736a0c2fdafa183fdffaad35d7237719dda8673dcc08cecdf4f4f8e57bd2b5f58cce991511a10f3c944e3a84e8d321633e0f5aed161dcc18644270cc306f848dd573e520d958de1ebc199ffc5f4f09c47b735f8ad278acac3721d78abcca9a356116733e636684985651b9b655dadd505378e3107f16e09d54304b754f52822aa6e3a784554bd7550dfbb8515c8b35623a2ee68e92815502c4b0e007ac99480fa9605b3f28bbdf663d0d68051649bf3efba5d34afd8369805df2cb0f9e24f96f7f5858bb1d5697746a8ce8fdc9f4a85ce624ab6e506f0910678b510458bcfb416bfb6f980913262d104a1b27612af6feafda98ada5c43f0d05659fc526542909e405f84c15d7ac4d5cba3cb9df196ad145f8a9ea1fa37ad91d997db15fa067606557b163d6a8230442f24f502c3053ebbf969f159579ab188010f74b2a01f2902aa70c4abc3d2ba11b13c3e0cfea3723b3118536c69f4d4a0af47900f0f294ad080eb9ea2bac37e60f56e6ac32ccfbc912c4ae2bf611eb657322b0e22762ae850fd06d51865e6ce77599f79e6cde6bea3ac45f3bd1e6254549f46c2583b69f42ab773f5f150a903f468945dc9da02ba117b22efc9d09620ff9d56425a3c075d7dfb11de819fbd78649819daec61f03fa02d77d4988ff9c7baa2d858f7971bfbd98b2c7b517410b43bab6fead2aa0c4fa8e46df3ec85ac6dfb457907102a3f2e2ff418361619cb33d6ba20826ad533ea7cb45d9fa65ecdd74761d63b7edfeb07299153fd9bd22f4c2b37e682d1fc2ba531579a0b2979d3fc2ba573aee073b19c8e2a16dd2140e4e2d48af3d18856d6e8474e4b1f1d08750fd8325c383a067d81be1f55d20768b718b20f82cb1431fcb2b7ad1c9920b646b773374c4d8b65b45a02cca08f85d6ef10bb16540f1f7d97bbd9d5be20122d06caae4894ad4da49c87a3a6d09aac0b65727ac4df25f175c2d2b46f197db376a4b281db1faf3e4396a1fa0449c863fbd09a1c70815fef524b9296629c91671a60a1fb7ae56940215677cd8900ccae95194c43a39aece5e6ed11a61bd66ca291210b5acbda65e7b27b657ba1bd9c0256713fc59532f304d2ec11e3a7b551fb64b222ccac98bb02c5f960300fdd6923e1023dd35d6957b2b8a359e8c5c641ba3b89ae390bdfc4f364695aadbe338618657d7534646d6fbc2ea9362e6e33fc6cbb4b69d7f0eafdd3b355e2b695ed55893529e1a85b2a4c0fefefe4795ecaa349785b1e27abab69cf509df7c332fb79d2d5ba223b3d14fafb6c4f7f1b139a95fb90f26bd50b93e7b8743e509f672f56f68c82858d0f3cfac692349834cea229cb51c9f99bd2336557993682d188a5699c544de33fa44cf9393057dc1d12709c8bbea9b2ae975f8fa2001083c321270c9b8d0c60808f4711488822ffa5ca2f9ba364de2f23565fd547d6b8f8d12bfb12f3fa2ae3d25c9c5b16dcf4f55ecd6cacd94acccd076fc9ee6681713e6d4ec7d19560a1aca51dae36d10f3c1f908a76aa90542e0ac92d6a14f3b25302b98ea6b992b420a0b4f89593b4b2e461018a76638f4410a3e01b0a772e02db2f108cd83178c451b761e5c7ce325a5a9d686f019408a3e64418bfd28edd6a72e75e566a128d39ee98d37775f66ad3a5b346b8771ed1b114a1988047060cfa60c87d70c3565c0998d93ef3e670de8ee4fa5eb87461946599e3185fdab9532953b056ef2b321378fb5d3b8eebee242f7b1b7092120c139f4296c4ce62e82ae8b9b0eae35cc6f18405dc9670d15cf98ee2541091d328a8badcedc978a0bed9238f422a1b6712a9e68a29eb4785b0ef750bc98b5b1516047137c6cf5e90443f2fac4c734d9595d7ac17e02b2b1d065063415050c9a311a68bf10a9bc2e26d242db668a021f373294a47758cd9e04e6e6f90e07ea2f51484632f5990b19445ece78456ede12fca60f08ac48a948e883fcc66e685193f1fc159d6e47de1a115f8282ffc5e0e068341361864fbfb591886e1fa75bd1b27ed884ad9e5af408ba1929605c7ea65a880813cdaba7eb598a6010aa5f0b3d001096fcc73f76df48a433037e3d111f693472b8d03543136e890fb457706b81fe459bca068be67e17a941312a4e2105e54aab5a5a82982bdeaf61df50893e33932bf6315ca719f23813dabb79ea5eb111c3e8fab07bdb9273ae57e459dda9e483632e4c6e285fb54edd386ce85e3ca90e6a3eaa65abea378f47283fd70237a0cbe93c6f364c4cc64899793b0eb648e9b3f4e6562a1765a7c58715923326facaa9ba37d3b34cc4f897caf145fcad389523570b3ec2bc31dc1528104ee3b6ae8389e938a808781141c1ddf46f958d1a5f23a0506ab46f0c2d4d3aa05a0e502206a550555e257f66f57665581cba5d4d74dbdebfca889b28d09c00f6e8351be9eedb3eaed3975b9622957befdb40bce9f9a969c69509700afe796538ccd815e23e50a1c98676c131f139e4bfc15acc3c4b72eab5693cacf9b3a9672384541c9f3b0d301072daef373e9d5d42aa98fe354afe73e8e18832bc66aab0d133fcb50446b89749d6c6539a40e954d6254a5c450d16ac133788e7a6766550baa51cc96de0772aa596b5aaa366f939b1cd3c78117d690566fd5ae5c97aa03b98f466af03a17567e0767d9dfd6d0c684952759f12c6e69aa410cf656e2444bc0f41d2b778c85bad5fa9152ab2ceb7fa7212acf0c2f339e154d52a42db58b45fd41b5712ac52db5d013c981b682f3999af6396446d15b39032b8ebd202f20b98a1278bab2aac5adb4b6c959c9f3a944427d9e9b9cd8caf14621a8449547c9cd8a90bf9f580e0e59abd5d4ef139653f235f63b2b52eedf122eb7bf6788571a0c7baccf874c29bb7d8f97ea3088789d7e2a4756a66910d5215f82290a5b4a2a155e5dcebf573cc07f9700b3ccd792008925229ebcee96329456de8f8faebca57cf9fc2a179f2fb2d577ef2bcbef8ab4abf964524d326bf38be5a5d9bc309fd82bf4120e7b8dae4bac5d51f367e76b96d3f3f34e7fc55afd43b857aed7f505549bf47be807117f02f2ea03edf5f240b9392c89a0a62e35a939292b0a7baac42037a7a565bfae3f57ca0cd5ccb53df648ee52e69adef88ec051adf40a91a3f480ffeab57679165bab6d09875c0c5fd7aeb779e72dad6e2504f64abb8419d564a01f58b5a76b17d8a796bfcc6cff371ba77efd5f26a7ae996a45929a9afcb3dc602bc5921f27acba52fe2fb6de20e2ab4934a4d4b59c49ab69b7bc06bf2fb55ab9b8e5367b1a394a8595be1bd4b4913383eb110c3c5096df761e8d836457a0ae169bcde30ed525d96cf45ff57a7dde776653c773de0d1c8ff79d407eef0e9c05890458bc9187ef3ce68dc4384b45c6c32c09f17afe0ef8b256913deb75738fa22e38f5bd4532b2bbdeebe2be23c68e079e7efb4e2a1c4fbde6e7f0d0f136d567123a9e84c28b052681bacf901fab40b0fe4c4725ab078c8bf3a1481824601b574624a3be8b4c01e508537dcbef8e5373c05ee8e6bf2da9faee05e864ad17276c8b0297266b41c56b99f6cba893c04563eea0d1c02b2f72accecfec35af7890b58c108def583034b3cf042eed4c5bbf74bb6b6cbdb7b5ddfdf5450133b06154e21a5b97c0d6633536cc8abd4190823f7ed93cb79cde70a47c14bc55dff2f3ab8e763039539f630793cfea337430d9579f370e26a7ea73e06072a23eff743039509f77b6bfb3774fa0ad62510a6e7e87ccf78e836345f1df9cbee3a54b4c92e03d155b44ec1a30e5340493372a42bd498fc9b10ac253f4981c6a68ede88c1ca9b07a751e93f7dc32a721f79c3ea4a9b7b545526feb3999ca3f636f638384dec6361978bd9ef5cad5a792fb2773f65252522391653dd26c72c24882a192bfd50ded8f56f321f6aa8bdb88bdece22c732ddf5e1f1eb56daeb9065bba81a9ceea24bdf4376eb6d5564b83d92c498a44e5d82fb0a08d6f3f7a8338782d16f446fb2fe6cfe8769730f9774739c2ba41c17a6f03939806cf686f83a43421732a8c27d53eef88f830ba6521dab4dfeeeaf4bbae7abbcb731c32a27a549f1a537e90c646c69efb5d775f596c5fd1d1cb6edf693b32d7987eacd0dca4326a840dc4b480806a56d3671606bb8d2a7086f15cb9ce3bc745517fec46aef319fcebbb28ee8fddd875063a98f6a76eea3afb3a38cfb24996857de7cc44f467eedc75dee8e0a43f732745eeb03f7343d73985200ca47fca9e0c0d2dff3c76974d5549a72fc83f5c0ec315869b303fcb27a9257badbbda16b2bd7ddf958792dd23566eedf2b47c6743a697638aeb283ad18a37c6673a1304cc95161d0b9ff9cd17039a97adec1320123e8d0dd03fca6149ad92ff1b2ff6d83d0cb0f9ad9cef6668eb1cc153ed5273234bc970e872cbcb89a10f82cb97ddcc8d3375d14d99ffc96facefafe5b794e4ba9828b3c0fc9852af8c971c094ccc4d377d01cd9844542eb699e8f5cd1deb5e5c1edbdb5007f775a55b868d83caf8284a5797d9ccb85c7fe126c66347719bcca49afad877c474dac6d69a4c069721a59b5ef922bcd505886db655bed6a5017ed9deea2a881edb34288a7b85def2350520654d6037c9dd8a887112dfc005a483248913e47ce05f797cc31b731e8986e3cac55c0d13db490fbde52a52b345fa961b203511beeaf01b9800673ab42f27e5671d50e6e0fb26a39a15a73af8a7b1aa3fd1119f617e1c40e83bb72aaacb7c4924d34d5074b9ddc9cf7a1b6b1bcf7fdd60dbee66eff9e636db5ebb2d8d02b9a080b820c9d0e2d912f722f91b5e35b384c4d67823696994cbe56989f145af68b7d58ae16ffa8a76b32c7a0931f0377d296350e45255b16b2e076e8add582e7c5d925278c4a7c4d9a26772a1958b68043755c83ce76be0fcbf5854e73963133281d31b247482e26cfcd9c616895d588f37b6e4627d832e398a3126a94b0312b7a9a228800bb937085a90a4b020cf95557c2c8b51bd9f92b9668449c1fe56f934bacf2d39ff59e9ac41312152332c86cc7552c747457796dae86f186826b4c715806a8b5d08a9067803df508f63f8ac5ca9c829b9c9adaf5384d75f28aa75b50f21a7aaf89142ae3d5b3c91353f45f2aab9d541aa0e0e8c95ca3d585e069729925dfa9ea344caf5527ac7242ac260aa1a17e1b10ca7453894e179111ec8f0a408dfc970488397f49e77d2b4d5022f79819f65c14b1903113a267a497b323c752070cf3b53084e1d12f95916ebe4b103817bde194370ec90d8cfb25427870e04ee79278460e890d4cfb2b94e1e3810b8e79d0104070e99fb5936d1c9773279e8dcdd396492db5684c30d9f0a120e377deab2575d120eb77ccac9276e3fae13e285b65d6696fd1653e64c96b507027e4438c644d85e64b81a30f65dd00f5cc5548270a54e050a0f01ff543d04285ca9c97c861c2bb8ecb5d872275eba876776ce0dc463118d18382d1e05b3480493143be403c750b6f65af011397f69f76d731edd2a8f6eb73a467375fdbec86de10df52ffd6c79ff3c74e17587871ed95ce0feba7284f99753ef51b27883aac736d76cdff3f004ae76ac290bfa4ef65b29c7a8c7aaf4035dd4d9e86c6c75ba0e11f4ab2041e78ad3112701f85a58126687beb278520aaefc992552bc97bc2f90633c42285ba4001c38fcdba8c05185c1c46d9f37394382cbb83cbee99b0f843dd7d459669b8b111dcbdfd2edc782b77e550f39686a1f31b1d12689f90e58c2472918754d4860466924dbd17842bf204127d4deaee93da4a4ea113a3a2041fd91a3a514cb8d0e1d03a94aadb5a6cfab53ff18569109010e6b1ea58ab07d43e881c85be211d39c727300a0a2aefe10f23b151b445ce50ed955c4d95bd598b1c82f4ee89825371ec6fcb378698432a10dfe514203e3423da08931ea92fbed0314108109e2303fde2181a1851817ba2001568642d90692a878c75517281324db2b42a5fc7d957339c12be5d7af6442a8b8e82443451fd52dc39f9110a5c65eeea8479bdbea2e2e39f324ba671f782452ba4bca9a97f7721751bdb36ff66185fbf5f7dc730c846517db6aa1f79c32b85551417c364e583a8e27ab368580bb49e93d572d9d1726fa10e521f8a1823829ecc35a2d04eb2f15ed1e9625429165bf96f52e32c18f241244a9bae0a289d966bd6c6ff70b17981e7fd9eef59d49900ae5bd83bfecaae0bedc2df1973d05ac431b7d473ffe28432f5448652c70c28436ca07c57edf9c0dde3ebf381c9cd187fdddb383b3a3c1c1c5db93bdddb7de92e37e8794212e4e0ff64e8ef74f97213d2982548007f57070bb1d60ed6487c89c9ea3cb053479694511103fb0a214b64f07077f78e09ebb3dfce47ffae490c1c9f1d99bbc00d90e0b8417d8f6298a5efc8261d522d591edc8355cddf07676782791db6a0b26918b5f28bbf4e7697c79ebd4f9a73d936ba1863a9cc4377b011fb1c90478206c226b737d1556b6a37d9644df20c7a9008fd43539feb4329c5ca62cf9165c4ed82098d5425ff25af053266ac16f6df0f72c182ddf47d090bf330bf222984ce21ba0790fee9ea5f5d81fcf73c4d328647bf17436172cac6fe41518deb3204c0f787da6e963994e4590d4b7c5b8948df17077756bdc9460af99d80da7118f5291d4dce8d079fee6953caf27f1653059ddf387a542222e5832623301d5a8cd702a4a1952d5b411bf2ec6596dbeb85450c2d2efd37654ca02975a1f69ae810dfdc8200bec0a04731127f37ac0b90d388aa77289ac9f702715c095438db312a47a68a4bef2b352e9f0c0eeae88a7f57d6281866c1427ab5af4c246cab848a215b3eaa804782b180f8b895e9be3cece7135896f6aa13edb50d72b18c66f15a095f57ec7cb80fbec727e0d9eaaeba0f796a0678c878c8feece12569fe5b242896a0396accc7063671807f58dfbc906caa75cfdc82a81a68f0cffb8029924c1dddbe8eb8a7a95607f8b6fd9f7ba779f95b23cca50df895ad877495cbf9efc5d867ffa427756cef89d2aecae8286b6aa1fd47c4596554be3605506e53dab36cfc1aa3c2b1beccdaa9aac5a82dfda457c6577f5e3f2d8461b3fde987f2c81d6c37d2ce1e4bfb1513c657a1ad58f9eabba1c1f78fc589e71398f1132568f9cd7f6704e1e934946a204398d5754f4be0437e747fc91c91ad9c0e98a4e7b5f029ad58f50660389f8f7d37ac1aa049504a3fa3abcae80f1f49186f9c3069e7389f5eb8aee09edd606e553fd003cb451de8c597dc17f49a89d9fd6d79a8db5ffe47f3fedc5b3bb24ba1e8b061ae1c6201a25711a5f89c65e9ccc62f31ed8ee64d200a0b421851839243b3fbd8d468ca72c6ccc79c81250cdedce82d19835740a697c54faacc646a7db4012c0d1490ede69dcc5f3c634b883a7ebe729fb496e2d1a57d18435d8ad5c1b1a116f48c1621249bed8b889c4180ad1283a8dcf1a417c2902785c7f14cfee1ae0748019ea1a8130b7896f6e6e3a0110d88993ebf5890248d7df1eed1d1c9f1eb4373add9f7e3a7b7374dad83bd93f681c9d36debd3ff978b47fb0df38396eec1e37d6764f1b47a76b8ddf764f8f4e49e3d3d1d99b930f678d4fbbefdfef1e9f1d1d9c364ede37e4beebe8ece8e4f8b47172d8d83dfefcd31f47c7fba4717074f6e6e07de3e0af77ef0f4e01f268f0eeedd1c13e691c1defbdfdb07f74fc3a47f9f6687074b62bb1480c06f2a7c74a3a3b3a7b7b401a874767c712ffe1c9fbc66ee3ddeefbb3a3bd0f6f77df37de7d78ffeee4f480fc343878bff766f7f86cf7b7b747679f25a2e393e3f6d1f1e1fba3e3d7078383e3b3ce4f3f9d326677a8dd8fa661afe2a491ced828ba8a46c54372d7f13706d7b31b33964ca354664b7f0a78d89844d348c0784aad11633af3a7ffe8a86eacadffa42ca8ea741828a06a65eaa44cbc335bfc93ab2c7bb8b8802dffc58537f417d62bdbb05ab65a656cac938353b1c8b2726ac92badc0a2330ed2931b2ed73796883bc4c10f055c741c721f2fb0f2d5abad4b9638008a0cd1419a46d7dc2ece7a6b9d70da2309cdf58bc63d2d7f99ec70d7cd5de9064055012749d0f80b0f8a658acd1de140111e48c283423bc616586b3841475068382d8ba2b8b0f4abd14a9dde4d2fe349abc586eaab13099604224e7cc2696e1628fa4251c2b0f7c0d9adf06a1688568bbfa2e6153d705c602e743f002bf6982c86bbae4fc29833afc9160beb75d0d45643fd10a5ca98da1c9cb19dfc6603e5866a12d3a1bf23923be8b51d4b819665a2dd6ebceae256ab89121a7564f510c61d49e30e8e956363edbc1a2f46fa65f287803e30b9ea7b6cb1b88a783099dc3d48fc49abd54c20331c04451d45166eb5343111cee1a32b1460755a1f7400dbc2f85b898b8699a362aca91b11b4bb235e2e0d37e1ba9851d619c57c140894166709f0b87f316624a2896c0f3df8ae12c6ee199ae8f77be883357a467907bbee31eb4ce3cbdbd7f3282ca8bb928da1ea3046cd1e6198387f3945fa38d74e37195eb24c184a847ec371e1e5f75d396fbf05491470d1b80aa2090b49631cdfb06f9a73411b35a2b4115f5ecd5338c86a5cb25130d74e1b6452d098257138d76692f36812761c8c17e5ba869699e1b498208597076b7cc3196d7e2c4b9b5dc2564c3a68d959f9c1f3bc988b8a134175236ad9f376d17477a8e43b8a6599812e1c8468ba9a3d7d20acab795d62b2c87ad782525ae53959a64bb09ef4fc66948b1a581d45e48c54263e303e9fb2444aee5eb3476e9248a8ef2ec99f36d56135fff9c2b67a2d4df7281dc4977f392e2b5c85e7e44976ddec921a9dfb05f8c25077a986dcb798c9a50505eb4847ef54e165fe3b5eb2a51dd8d6050d6b051a0433cb527615d429b3daedb6184c72989f32b1ec2a1d1ecacd7ba4e8318bef2b169722068e4d0f82d1d8f29a5ef44a39d33e4b47493413718218e1b853f44fab654a9572af6a1078f2c37ee8f4ad5dc1568be5e7d0fde253fbedd50186ad8402d1d72577999429af76cba3bdef382ef3144f3aa3aadac8915ca11194b590987cb667565e1a8316cf4f5f60e17176453cfd7f1d77947b27e4c194d1dc1de83b06e73866b3a78efa9a3d93fc1b8bf8b5d93be6f17a6398a4a667b5dff0e8eaeaa31cdfb4ab1df605a9d8055f442cfced2e8f8d6f589aeb75401749ffec1c9f9c5d9cbddfddfbe3e8f8b561fdb63fe5ea46d66e01455405e06d940ac65992eabb452bd36bc695d5fde0456841ea482976c82b89294056915303f1c304256c1627a2ae6574a60fcc58132d67535afb52aedf18c2a4629cc36afb8dd23f3ba767bb6f0f34f7dda907d340841543a7a692023f48f6aa5584114b8b323ebcbb383bb9d8df3d3b68b590e844e959128c227edda4f44be7f8e4f8a0d5fa872101cee8f2a63d15ea291d5287559324db525fcbf90867e0651fde8fbb5f96536941d80261b24faf91a3b4a69fad15f534373dcac52c705934c3248fe1201ecdb44b2298529fed75aa49e9acd5ba52ce910857c1b10c724c12e01727f4210a191791b8f36acf4d19ac692415c97c24e649e9f68b05f686eb273b8c01652d9466b951aa81d3311cc63c8692f4f062410eca6c2d8cc24632e78d49707fd7887824223871868b03efcaa033c5a61a5ad51e03ccdff46141f64a42da6ec98f4cff6f6f2f3fb3057744080e871faaabb2b57e0b72cdea84fa377a9428f33a7f41521b4ce0870a00150b7b917f633b9e917214dc031f1ef8c62a8d0ddf81f89ee00729711cc079b3da45ced1a32b6382894effcaee6410e7e2bddacdc528c024cd05fa9d66aa44fa224a1131a1c9503bfaf67726721e40397b090bd44aaae2c8a413e6eb2b04749f9c05c9351376ccae2511e6fb05b162bf90b65a9ab227ed178496a185d92fd85ba8e3d218b47ad3bc009447c9ed514c5225dccae998e602ae4e837906af0e4890276d5313f24eb7e99c26b263bfc92812a1870599e3dc95a44c923bd907d9ac5e402a2dee095234b417934a437b09596e688f2fc82e0a08c30b33f20f8bed0fee234e2724a937060287644a242aaa576791854982adc63eb46ed76c48c943efc3b26cd30ac10b4a4b2e61873d3fcb9c148672391a67d996953d976e37fda2e4a38a49cbae500f3b5505ddfe1f9d407d9207c9b4a500eee904258821a619b205305000d36056ca77a3a295f3c122dadaaebc2fbdca9a47df4b363146c23c51708c9add92799e36ac562327a6493fe9586cb11ccab5107a43ee29f277ce3858b78661f9500371124b660d96ca2837a301e996f16fd635bfa4c3f8580af409157a79f9441f42c66692534275754be94562df0c42133f4be2db3bafd9b5f8f26f357ee33f79353ea1557b3262cacb7179acb271fda49af123bd4747987ca0f768c9d2b15c60961df062d3936503f5f3963f75cc68a27adf1d3b1660dd18b292ebc692957c859aca91dc3ff41ebdc7e4f7476aa9d7eebef0d8025b22c8eb9277ba6a9ff597a3f2fef79a3d9880929efe7bef08c6c2cff4e132beadacf5550dccab8d56eb2fe45cc6b7f97b1cbf594f4b8188c31023af9164ad20471139b83aec9f793091722a34fdd34a01d0da72ae78b90cbc20d360f634acd360b692f6cb65bc2569e031bc29132bf1de2ee35523ccabf6f9d2cc29345c3d1fcad1fb4b2355fe26f7d972fdeac17b7430ad706e4720d72589393122c73721c58a88aa243dbaf54f82494c138ea29cf66b8162c81f60122f48c2aebc7f72a9f0831acf1fb5f0e9fdbe207f2c9924d6396fb6ab54b346d8c9b97396fa854d567cd77623a135a3b43a8dc105e5238c405426b4a8cc60813d06429c64ad858b0b358d8b29f91728cd9173703b6323c1c246cc59234e1ae2262eaad51071a33811ee382e739d4e633f0ae1e82a188d40e297d250432477127a9eb2a51c8d202d84e6be936bff4054fcffd87bf72fb76d6b7ff4f7fe15149b45131546d6a449ceb792611dc7761a371edbb5c74d134577cc11a1116309544168c6ea48f76fbf0b1b6f3e3493a439eb7bd6ba3fd823922088c706b09f9ffd599b4ec5ed16df4936f633c9ec6a58d7bfe31f31a5f2dc3aadbb95ab285d756e41c00aae08202fe22dc9a6c3d97e7f7b706793ef9f00ef17e9ade4684a5847159e974cd04f72270376498a7094509adeaafd61f47ae0249903c2ac89e9d38a066ea79f76d3c931856492c8d5535fd877d6aa68ad519d9888d1edc11dbb570055cf01aeb245eb2f8bc343cc950e47fdd9efa9fe1bc758a963528e0e6346f518114103599e4e69a06c2127a73312fb77622ccb38919b0c67247697eaf19bd7efdebdf8fae50f172046135947784b15534f3f9f9158dd3ca47fdfefd3bf935b39a9cd66bd521f933fd4fb2f5fff15ea7ef95a37ebebb7cf9f7c0715c2aff890feb8dfa73f42856aa4c3b82210d4412f4ea8b70433daa5c4e41ec75640299389b0a94550319391af9f185935b47ee48fec48df83b1302587a664387e236b55234b9af686083332a790b3dfa8510a768533c2351de2820cc7c5a36c5cf4fb96859c162055bea669896055bca283bca8e406018687afcb2dcb335ed00a959202538da62f05327dc3496ee658a5f2885299f47ac3032887dad536be6aa8fe9a118236728c71f0f0d4132e4a9ad68d05afe8005c1f020f48cf7c463d440f4fe15415ffa68f87e35774a01c0655d629ba11cbc743c82001db347e45070d97d6fdbe279224d69ec5aa09942d4a3ea7cae5a4daefd526ef6c55348c3a53733856bda503466f5e9b3904958f3e6ddcccea59ed9f0e87f2852dbb9453f58c6eaaa7e5960932c474c0b7ec454ec01e053f2d4e74eb108dd5f4371f802b3e815e75d04646b4d99379f4e1ddf4ad81b2375c76d3cc70fb370bdc6a420e889bf957241c35cc03bd20cec81017a43950b824c371f9a81897725940aad28ab06939434e619d24a9afbe3ec5598f9032495226c5f30ae1acdf47b86a52f9630e89475a9ea08349ce4ab2c67ccb03a220c2d82bc1125b9c9c8c6dfbc4b408dbf76f9a5698421b9c96fd002f66f022407b8f4f4df7b223dd1be2b7aa3674908c4a4dbbdab69639a60dadea4112f25a1e36d843445fb52cbe825d8dfd79f493e6ba4160b21bffa6a998b219a668dcd68e9a99c07e35f7be2af7485080790a73a3365ac8fdc5db5c64591d7cd6be628e52304ca3775a2ca0151d2bccb3037b8d0d361bf000f73e597b4228f6cc6b6bf3b146290f2e9f5ae57d632c6b138f6edbc7db9518772dd17006e5f475d8005c5dca3e7c2149712797db352577d9f17cafb403c2b1e479a4744393e41a2cfd56a1eb0ef9abda1edce295ab4b28bcdfc06dc4f2656091fda4f679d21b62ee19576923773a557a9c80046df01de6de4e19b83b102a294993e90d4d339f4ccf6afd18e24c91f9d726feb920b71b4eaf1dc18136915e3fa99f64a3978a97081f02e58c0c9b518a62b17bb7d98d7aa7184200ce8b351d71ac3c135fe4a31dedf7b10a5f7b62ee5d503b64179414035318179ee118e8f142d21eb505e4b91bebd0c828d347b8c8e61f07602090c2cea2e4575448116751b0a25a4619d3252731c21794d041d81aec145c6a7893449e7cd576b3e1b4aa0267d58ac84e7fa4291db48e186c72f5673060ca64245917f5d88d3e9cf06618f1912f9f7af6721ae6a87f29070ba88811e1ed611f81bf371c9167b4eeda56743f5a3716fd2cdc5a3e36b7165bce953aa79e4983b470556d9c1619428f04f177e5b672cca65b82ade28790a9b78d008432ab3535163575287b715270ee192bb82d964100a89c7d7bab4892b420af8d4e4c2dae92f898af5c274f32e3593a7d29c3a516cd70a95559a4c0e5609955ef99b2b6d25c0d25e99de252696e094b85af5b39d4ad16caa1cf74d9da98e72553129edc3d0e99ca84e3992f89f16599e8bd5585b4a4028d52e615f38c19204032743096546706c829f45131102dba02bbe09427802acd27c1554a9194e8fd6aeba919a03c8c8a6456538d95a41257d057f406be9f5284140ffefed5d36f9fbcfaebf367e8563b17545478c50ee1d76af5d4f1272a6d25c719d379e4f472aa34b2d0add6c6c185ac7114ab306490bcffa15cfb0e4acf66950d7e33c772b44d51ebe5a03a69a8c88060c32838970dedbda1a8ca4bc98b299af89f6819e1d6fe7aa8196abcdd4fe31d12f807a4086ff5b024496e06241c047f78dc80e07295ab9fe280c2c65db565028bbc8f1b9f069b9ade23436f106ad5da009f364a2d0d4c54ed252d28b6c71d8b24a1e97da6df9b18db6db5360e08af3a3e7d3c55b412c26b2fdced98d08fa71a61189ad38f6771584937d0904a86ab3e1c7ed9789c8af20d2fd68528aee9acab1136f9f3018b43fa03c2cf28b94aebbb728c7fa008bfa3dd1e4d7ae28fcb02be63929231f4d269c85d473d9bee7088baafe39392cb7f85179427cf42a916a95f81285dacb34d9193f88f70a8793b8611bf2157a4e9948d18f53afa76cb58c1aede512128f7ee6bcf1aed578397292c531c833b3dbb8aca8d12764a1e99c0cb517445456c97a8137ae04dcfebcc682a8dfed73b97017f4e1810f24ab5ea4a2f7245cf27ea6eac8aa26047948c1efcd8ef53c54e649cbeb34ae2fddea84327beee78e44e7a7d7ccccb8df61c16f49330fbe0bfb605a7967923bd1e6ddc54453f52ba79b22aae2994b157c71cda409ef6a9bf771fcfabbaf87687fb55a85afc8ff961b5adcadaa77ea9b39673c86a77bafbfffdff9a0daa1da3f5450f12d6d3dd7c45a39c0a6571d2d14d9ae78ef449a1d6d9c85ce69e4033541c57c1be96f2eb7e6f79bd50c1aa13e758ca9fa4c6f71017d4b00f500494244f98b105a5c80f70f9bfc0e530a4e3c9111fc2d1bd564b5733bd45ec681f8ddc68a92df026e3ecc965b915ef4ddc9f94415384c159d3dbffb56c0083aaf8a4dea9925435482d09996cb084685f2aaa2c252e402220b34d2d6b8a575bfd7bbface2ba1460d270a8fd1edd2e2d345c7068e1f87c492355282a17f6388aa06fd18380a81f44451509be9347982823c5b84585a8e86ae1ccaa927364b9572063d185b3a95ea8aab1450653e17eeecbc6836b12a38e73560bc0ae7b4eb454a70f24bc346e71ed47f541610e419449efb4eeb41aaeab8e09d3d205e960ae489dbd626df33c449813b1dfc34cc31f86f6fb9e2fa850dfb3c8d0b2665410e661d3fdda9bc28acdce12f03343dca23ee8f73145826819a1ce977847bdcb1d7d8701c48e94a9a43e6d9e5de4eeb2be33649bb9a4de9f9393764eaeb68cb6959cc7c6516037e3fd3e5d51cf4d554f840e4eab1d72ade2904bd088392430d72f9b29de8a4051ab54934c1b16e528f3fd5e18e324a83069da2e44322753154e94ca0ea06f2bd10158d68c148dc3b07da30c42916a4edef710be7ea957b813be3c2a7011224a18a3bf4618a3bf5918037ff5d7208b057c788cdf51849f53328d4d705b0c51f0963189711c5a3d6307bef2b6c60fc72ec8df3cf2c1223cb08396376b368d18c7edcb325671ffb29d560112cff01bda580306dbf04b45f8b634b93d60c78eb4d877bc6dcf5763b6c87966d0ccb56695cce5a645b0acac9caa9f9a31700feceeef1e1959ada99eed0deb4f944dc8dc0f67cf56e4cfb1fdf0154005050aeb6f3396affc325d936f6bee26819a4cdd4608b688f9cc53cfca631fb65386eb5ba7e61dff4c83d881a7ced320de3215e697bb00c39b82e5e5cd44fd19597d279ff0515b71c9574ce47fa39f554cd7132aa7e15b68f8ab9663597ede4bb57121c9e985764b01d9fff130497ae6890272aa922495f59e4af1b9f6a076c3ac801e2129801b52646eb94a9ed049edb549dada963e39ad7fd1ad2910c13b9e91db43a3ad68d4fe91e637886ef928ad2858a5cada81f32dddef17a9e40b398d324ea3f576258acd8ae2282f160bca291391ee7625b9b7b3f2f29f604bbaa683e82cfb48a36acba9ba5d54d1aacc72f0cf5beda292cdc14b6f5bd1e88345924a6fa3a22a5799a01eb6d628127c4ba303fa10a303c2a708eb861f52cf33f71bcfb5e595675979e1acd2ea35677a55819327a78490e75218cbe9a7d70b9539fc159d8a1991ffa171abeda6d7705af13cd6a9011570d25296e7004bdf26b73c6e11793a659c96b29ea3ccbf5b3ead0030e5d7c1e7bf266326c9f734085b85cb5bedaddcaec283c67569f780876cdd9f55cc3b45dec7a4bc75eb24e17edf3d924296145e86849c9cb822e8f63bb9b65de47ad7d7743c3bf5e3d80d1ae554ccc6ec887e1222c91a0395b2baaab3ed9e7c9fb568245284300b037c9384193e53b2235d3d21533f06f97d689aecf6b3d00e5e62920a75b682053754a02a320b75aaba341681be772a1afad37e7f4628a6f501801dab312843dc543ba508018ae8286da74c37eb72bb06c2c4815fd8bfa885019897ac2a5772cd5ce9f87f181a3a93a22bf5e5566d1e8728ff7c4ba57c9a457358d751c14620ea9af23182fe19352e213f2a9f494349d3d9b8e729d8b5f742b1488dbfd263724aff8c7cbb1e53cb204e339647eb8ceda275c9298ad1d83c89fbce878da3c1cf65c1d2f8271123ddae7a0c669284d7edaa19abf28246f64f9582e452c841656657fdc6bc10e7f4727b7545f9f827f6f04f3f313d02c160fec47e623f945b381a281394833a605954d125a7d9c76853164c582005c7bb3766e492c29b72baf2480e8b3f05b2002b6f22b9d7ca6285701a85c14fec6fdb4a448b526ed0a03d006f07a80a7410d5b2dcae72a8a0a214905296b22dd7a22c57e0162e6f6f389d17155deda29b6526a24d41e5e9b49035f0685ee654364276c3f6507dff27766e3eb9e0d95a7d520ec7aa2ce5a204c57e514599885634ab44f4ff7e75f27f54f9137841563490e318f7d35af43f0493b4883b2e01d1f44fb39f1e3ebcc2f143c84084fab1ace91cfae7a801da006df66620e374a43ecb0c7d3155c19f1efec4a2288a62946ae489bf759a93acb74e2d4cdeb0870d2701e54b209923518f9e2fd90bbb2e89b615508f4f262cb41f78cc2fbf97bdcadcbc9ff1ebb815ea1759928aea59516dcacab38c5d14d5bbf992e6db557853aeb28ffa50f2ef6ba9a5d3b0f48b4c225a75a23e5f97c7cdfdc60b7e936d82c4a01bfec16fe52bb5a5292dc977b42e740ffc0a3a846dff23b590fbad45caf35ff6925f9881879b4eb75b1f7ea31e765d0d27c25333fa64ea55e797f79dd2acedfd39e0a015f275775283530544cab7681dbb127ab83e81c3dab04924430dda62347626a20e8dbbe8a98bf4dcd792c42abb320a3cf29d9d134a4dadb100dad0125adfeb70acb00a4b7f53408d3bdae14329108fbbe86b65ba0e1f339841cfd95cae68cae1288ab66c9e6daf964203d9819b943c226eb22a820a5874b98bb2c8c8e652a6316c0c68b24b4699c096b1581695642bc69d6e6c13c3c8dc649c5924a354431431f7a1ba46de5447731c2d8a4f1ad4a85cd8732b336e96abf206c568643e0405538629b8eb1fd154b463c6186e53e117a0fa4ce78a805a4c6a86b4cc6ee2ef930daadeefd5fab554083698a6e94e57c13b34f5ba3583cb82e5aa22ab25989ecf942e96de574369cfb9693015756d243023215587e7a53c0fff2a9c370b0d04dbbffac135774c9016b070adf320281c7bcfc8be148d05a48fbaa37cb5591573c9499e6a1ee1b3563f36b9ee5d47be0b65bdc7c3fd5e5e355472fbfd6734fda72f92fed3bcd9a2be1bb68a82b600488146067c3c1ca3dbd3e190907e5f24491aae003b9d515ed28a3d10d1bc64d7945f6911a1021c2af947d0285b08caa3d3e13052787170d6456f7879995dae7692c9e454c186cdc156ac194fb57aafa9f5471c45719f4e873370d950a33a44c873e9f76e63e5ac6c448b317f94418a7a36e533ff304c41946cd575c264fd1dd4d54e43fc37ea91db8f9e78f9191dfb13eba5124e5b704d85c281f244552a3c6268d9d706d566378b5ec85162e549b991a3544759abe2809cbdda8590ec681828c4445b6e572796e9ffb5a39b2aa76104c1bfdd3cc12108591de2c403253be820df004f406f2ab7f7ae057b2fb7e0a540db322fed353ad8902fae3270b523c7d981e1c706a61d8c4d3e3c06eed23bada3bb34715cae7596099ca9885e7438e81d23aba752910dd1ed6b0b0c4d92b6e427133932c611ead196c95fc6f1fd718c2982bcd2f7aa4b4c5484031a757cbe89af00d436ea29cd3513a940ed41ab4ac1adb0efbc060bcc3cc754e4ef9585083c262f690bdac7848e8e74bd75b4e84849568621f422033dfa68cf32a3104382000e2f4c50d8a00ad34bd93b386629f2357e5bddb31a8653aec3f8319737443d1af789ca73a0044ae5126c45159e243d49bcab6c8754aea1bfd19407c8cbce289596e8a03ca5e044c3a245a0d4cca35ad7b99c565c90dee9b8a3f262bf4f0bb0df06bb62a114813e9fc3bc36a07bb4c39b9e14dd52b9bf1a6ecb13e030f3199f141d323100f1b47381c154f2496a66cd6c7ae0e63862935fb6ea75932acdc1d8fa647f1b182b8ad215ae93d0c04f421c46776c95212204ba751f930c537d1b3aa84d79d59ee831604a7211207a589a9a78bf475451d7a4459de6994e04d6e5d061b4f22240e6a2815ba650ca34cd43c0052e0933c41eaa4f7045329196a053065a99a49cd80b9c11e19f8f5ea054d67128b808642f10434aa2682410de921e0b9616539dc22bb91418c20b49ea4b49dc6bc29acea1a14b28b38ea4d639146fcc322a8365b4d8efb7938b148d96fb7dba941f59a517b04a5c6759eb6ab5237da1a47f685c6f13c8ca168875a3d760ddb382119a6ed05890c57edf5ba7056672d543de814592b0c1a2e0f4c57a4df3221374b54b922a2df00661591cdcf7f67b732749d28564ea5d54b6bf5a37b5d5ea221e450d84662dd2969403aa8c170179ec353fef40fdc5b5a8c7dbb56cfc7cf206d804347ac3d446d85a888f182e09edc7cebdc10856d9b49c4de47f60032bd048fe362edfe9b49821efacb216df6c4a671360ee460d494e5630a63aba166c5b85b16d29bb814ef926cbf93cd046f8e1b4a1f50ea2a3bb2cf08012d06637c719e9522f40f8b411d68db689cb413a62c7c795b582b4d9f0c7c6b54a1ec375336992a4699b02cec087f9fea6ade20152c1838d8a8d0efd924672bf006ce445e9d975b9aa28cad8ceaa2724dbfe2d18e99fc8968111ef294d519b693a4952ef91b14e1b94ef57c6706b15c972b5194038ed316532742b0c89de10b021624bfba3ad1414c12a01f810bd535580d16bcae1e9a9f7d44013a832d9ea26db55b290b9af8b5a58c734d63a41ed2bb92879f42024af074afbd38f1fe0881aa09a07f0f907387aa0bef120922f9a463f88418cab79996c5b2115086c41db0055617bb0a3c554c466b783498f79635baad2c7bc4d7aa557be52e58fb99ef42adc125cdd3bfa96f7051eb63ff45ce971af6496246a856449120a9cdf3f79fbeac5abbf8e2248b2142d6826b69c8233c24051f24db15a45af5e9f479ccecb6bcaa3052fd74a8d5645374bcaa20fed4bfd835c0494c927f920062d5a971f4d2f43b848921f29e02fda734bdc01524f279e4269447dc8456ae298c594cec621dc1247fb7dcac994cf0c14d55d81e1a0052c081f709a6fe7be982f3cf90cca81b60f67685c2449bb00290b1592d90a1215209e661e6abc1d845de338ba1629275f0306a7c50da5089f43f641857396d9483f8445925c993a32e463095c8ba3b06dfb7dea83b3fd6bf40f1f50bcde2c5ca84871c969014e04f9948a1025744bcab4427845b6162574a55042dd2d555b4e565a049cdf393702e768ac74fb0b92b22481c0033661d37c369acbf726948e384a29cef11c204f175d53238b2c7c1cd1aebc03ab24d16d8760deadc3112d14f7b83d9e77c03e5446003bac97a1807b26d2374c6b086c9933e10545634e349ca1420a76de5dd6ee97244dc497c7c324497960f423691d74613ac3a23d4e049c8398a71f95aca0d6b242ae1f04e0656702211fcae026ecdda7b6de7df2b891d69eb5c92ece45c275d6c1f11ca081a9f042eb3c50f6e3f5c97755673e41341828695e0a3274ecf5476144e935adaaec8a92f89b97afbfbf78fae4d5d3e72f5f3e7fe6e56738175d90501f3dd1e8072875da6bd3b72c524819aa8fcb2a3ab5686ee02230cf182b85644ab615cd0364b6d8a4b16faa4716abf2e671dc928dc12a1f405872cdc105e9f75f0a5c4a214cf4e3e844b23b453e8ae27e019752c48db155c1710cf8c03a047dab78175eae8b8a0668937697f306786b28828d4d0d1ab3a0ebe3bb82aef228ee67fd3e2e6167d1c95d4b4c9b58535c522dc0f5db4fae7ee32761b9ffc26fe6a9cedc21f6fb16d65f0cc492dabc2b02369f094d85d6528cd28ae8011d705a95ab6bf70cc1abe916afd0585593e698a303231c6f53a3f472e7c9763087447d9d9d558fc3345e1a5ef999482b130454ea6dd17c028b4613b557ba6dd7468a8acf40b9c4c087f4a3f0064f998611c25b6fcf7c06aba58d3dd0dd907b82fae5cb95ef440078228588b300bbf519c41671f2b3bcb486d31e00bc5abc31138864f490bd0610a02aa2aa91cc411dcc803b240325d8a5ee4e17461ff3751b5e711305ee7af9ba2606b754c826a142cc2570542d76a1ee925c0d826518b3e1bde19717aabcd79ee722c89fee202c7ba772187d49c62089fa03ae4af5e8f47ca608a71a2cb32a1528ccccc2883e586cda0f5f4bf83af4ec7ce3efc90d44d5533d2bcf45f0d2cfc151d69c7defada0ff4fc323503923529b641c1c137b8ac692a4d9cd918617eec110ecf7cfe0eaef2a360afae57deb89dfb1aed3a4778af0d3b06fdfdeaf6f4feb7d7be57fefb9823c963db8a2e23bbaab52340ae090bd33982aac5084463bf51a9cb8692b8d890332a0c5cecbb9f965684cad1acfdd6f2a66b29eb3fb9485b81830e28f5a5aaee6c76f3bc099a78d46bef8858d9c0a2c9b79df76cae2baa5b38ea6ead4c0f71a6759ddac65a8df0a0ffef4f316a2d2d38b8a45aa56ae4d3e703e0324494dd0aaa9e36cc20737bc1054a9d3780bac38b0b9463c796e049b8389aa83b14110e10975d870bb97fa817232773bf8aeb983c76cbbbea4dc2372954223e3157dc164bda74384f032158fc910c7af4a116591526e00136cf518b109960d93b319983ed13f4530ab8429ff1f689407b1250289a994a24c8160cc4b5c80e22e941c3c1f77b7b3aa7187b5a7529b9aeefbc365fddf1be3153ef99f18321aba4e38a7fb70b7548b461d327a3f0c01d6cd5d45ddca67c3f9bad749f96b3762fa43a8b67989995e7966659975239fd46afb87a8db93ee71d67ada0373da6ad14301b9d9520d74eee0c435ef80265b97387cf430554808cf040a18f75411df7b416e55ec3ec4f15760e1fab429b938cb36d5934a5501b7399d6f79459f5f53be13cb825d8d7aa79ef5e85f8da188e4fa75554b8ecc2c57ecd94bffe66b7cf4d91d5f96e58a663e07048416b6551c1016fb7d2ac87ba11cc1dd43e28caac1fd494fdd6be94db370ad4eb05449fef42cdb384f8cc0d7bdc79a352749ef8970ec8a0a386ee49913c16303b1853c9e01dcfe7cf1f1592668f0d633ea7d468a0210dca960031554b94049f24a28a45c10e7c3fe99388924e1218fa560a4e5f6502cd29d3c81f6fb50c1269091e2fe051985f074a6ec46a2fb90d50327a590ccec96850f5eaae27987906446df2e1f5580b80aa613b93b5ae3ca416d67b269ed39fa042284bca3de12710c271bb490bdd1aceb1e196c1e1779dea62a11e8760bc78fe91e52c28bca84e30fce1db5acb476c5af667550bbf91d9d3ccb36bfb093b9dfc9b36c7357f370866e7358cf190e5a984347e7a6badbc37d6a9a4fb319f1c801cf0f4ab7d756cba754b4e1cb67e876a1ab9966335bd3c2ee8dce8d50fc927c9ff2e0f6f37c6a61a3773a6eee52746ace9d93d3196c1774b0293706228393cf2437a702d66bb2622db446c1d91c8de4e1d6df55e88814ad788f11f6ab63131da933fa71f0f2b5876e0b8d7128e41a755e418f0f47cecdb225ae0aca9c9a3252f09a0e6748ddfebc761b43d61def84ffaeddefc5280cbeae03ed1ae37d9d0f724e9175bb6f9bdbd27e2f5ab0f7c5e4479d60e1efc240b6defac2f4df6b2a03c302b9e37d2094d783426c6e8f1f95335e48de2c70c44f8dd2c4cbd7fafdb7cf5f5d9cbf387bfefafd79ac48c51afdad9fb6bda37423d8b60199141fce85e2fb2535ce426a7fbea22933c85774b190c381c19c1db459a05bc0ce4985f1144e11e649325fd18c9b2e7284b3543926d8e5e9e1b2fe181cedd7360d5d5309e865798001e7b84821ab9540f856f77594c98322886f2853d90035664ef50aea2287b3abf55accd74ad340f53b3df7723f09ef51d3d36cbf6f10006d4b3405fb1763e476995535bd893cc60921e7fb7dec416dc63a553221c42010e9e80546a0b576139573336186ed55a1bb35c79f5ff61d908cfd4f614e584d642b1629f7798f1fcc69cf350847a0e2525647d3469c1dfcb67b0fa8757c6a67757b3dfd466a4550dc1b421e4129ae181b4eab62cabd0b7d725291aaa1bc61dfd15d356a330540f98f74573d11e5ba8918f9962e56f2e4d555c83508b8c79489e79f04651004de56f1228d9fed58b62ee65e3e95486d4995a7c65ff0f2df94c52a638163b1390b53dfbee1e5a75d4a316381ebbe4ac243840fbd9bb562aa7a8896a532a3f8d7d66ce4f9de05702d617115ebeadd205397465d5b8a04c2eb86bb11f5ac4a028d4f4e559a1466e4438a5580a6f3b00c5a6171d9cd89cec936ad376d3a431ac8df64b518678f8a244997692f15844fb399e460f77b3100bcdaf885793d5a6a4f7fe3fb617a5402731f95dc85cc9adc4858a071d6efbb25eb03c533ffe4da76cc8baad0c3766bdc6a999d556d766a6f2804c3f0deef364779638e94e750f8799d98d25ac56186524eb8d1a7216fb66048f54c8df54002afc9c86d73f733432f774050498e6255156c80564909c2cb4b7890a251636f179335b894eaac78924f68ea46f7fba27a95bd92dbf29ad5f236aa9b53311b81fe20accde94d504baa2f4f81efb55c6b88abb0e90ce166db93640da9926ce3e5f6d938aafce62b2dd5287ccd6ba5da7fefbfdb39a55e04a9aeeeb1c92d584b30ad7212f5aa83be77c7d49a7c25b8c40adb63c952a6f2906544831655b820e7b824156ef70b90af7726606fbae5aac889f2a0bebdf53668fbbdb94a9556e90d7a8b214ba261bb957ca860f4c726aee8fb422c957c3dc4434c014f7e658d1a4aa85cb26341c90638f286d1dc040eabf6388c20688e36d30a032dfb1d2b6f98222f13d39b89726df208eff75dd3a11181b479ca36cdd70c097985693f9e0e06b3d87987d2df0719bcabdaeafef5ba997a3cd42af4e079e33bf7c68abe1b1cadce5a29710942c7ebf0d16a2e3588b422a1182bd5eb1067794e730f49ba32bbac7a020e88c1639dff49714ef9683a333f55d13af4742dfed0db9fba029ab356feaad98406ac636bdd4ad3d1d051d3fd9e3e1a6ad9c993b4943c0dfbd22c7abd1551b988b83c9e2010cd384e341b23d7300573a5fcf158b8f38bf919974e0444a98df9237a226c709a752c50f858e11a177888993672b416a0589cd4475ac12fb40f881603a8a1e6dabaee1893597456e6c5a2982b80041bee3b82b83d206c96ad22e3db0ef01019f3595a1854080c56077e3e8875c475ad057d52c71a0c7bdcc8bfa71dfc964535d6b0fa404446b66d9f2d17643aa16438a28fb30925d9883e1a42d0e95926968375f6291de2ac4fe50e46da140893ec848e9462564c8623ef2df5b30065d609458d1cecab3af47fd10afd7f64f1d270e509bd96994e0a5018496e351690e0da95c58c1403287d6044e97c7577d888d54d819eeade4b1be0398b2811dda3cd1782aeab174c946a43d5d364584abd5bf99fd540be2a8b09ccf13bc342325cb6c0f1576959076668fb723ba58c3dfc9947a7f40b3d4e29f72905e91aaddbd2369d522c6698a136baaa747369dff91af8c76ab3ac3cb907f392cd3379f0b5d4d517484ac9412fbd117aba2c56f97b58e71d0ba2e70ef92401004b9354011724dbeff9a493d00c3ea621349772c0c163b20310feb8be69bb1c0e994bde50a0ce8ea8a9fecff7a163b18c9839f3c2e563282238f7cc51f34b7b7a48115e33726b0ffc365e1882bcce679e9b8c4ac20b675ebbe4d276dceb5a8ce90f5c313068e45aa2d0bc559a0ed1016bb09c51dd5f5a9d71d3f39953d337994f51e30920d544f9b7779ddf559c852af4fa555731f95496521fac0d843b5625e7413e1ff3a68a5e9fab279ffb4a7a3ef396adec98d6713732ac86baeee9aca6d7ce9a07705dc7dd52c473f86a7d2a8f785cbbdf65ea3533de558d94d8fdb1fdad568d1a25b0c687598d0e402861756e6d536eee20487b7a9a1e06359c9ce221c2a7683a9c1d70b52c166d5196017d9bc25bd628febb8fc9b06314a490cc2bda8cdaf2578873ded6c5f52944fd38455c955c742cdc7a4562200b1b9b49508bda04bb370048ba179ebdc29e911e30861989c727a736b1869a07404f03fdea15ed6ab01ccb62a11d5fe9a3dacee29c5d3b84835aae1efdf694ced0b80d5741f3f74f84a0eb0de0a5719a019e8d6252a15b510a49ad9102b429aaa854e200c40e57f269ad95fd180da2372b2af782f992ce3f46ea7eb428782506469c80f7e5278a39ad54548dd67e6808e9e87207113752066ec9f51e10a0a7950711e411b7db58455316f0c17c4a61903396329fe7641da995983e4e9b4c408dc304fed2669a4a05618e53143883045a5992a4b2014460d6c1c6a42aabbbf685d2228aedcf7151ed05cc583043385249c98b2a5a65fc8a7239912c8afbb6ca7173d9523cc453314387c3613c8d157b16e358aec25d8ce345b182a430b13635c738d64b20c6f1cf65c1621c4b69e685bdb9ce36804e9d6f252fa27fbc2dae96b2da4a71287155aee51f03a5033f5f96f36c45f58d597bf8c59a4d4314ee7041752c17b38575ad6abb94a774669349faa8199a03de307cc1c22c4b30884ff275c18a4a28d897182f991783bcf339a00bf06ebd60299d9ecf1028aeae19be62e4f6802fefd060f9229ce2865e34642caf6567d9a65d17e5e70c527cf874c366e44af3e417c6e443def9e981b49faacebce0c0d1d57c9d675733129fc1d4371df8cfb24d939a8198d7d9263211dcb258b42957bb85dc211448218de65b0eb0c297bcbca9281f444f61a3b9cc2ee9eac4968674499c9efc5c3da4d5570fd7d966f07365a4ed8b3c13997159d29d5c66d559b6096fae29bff25305f8ecbb7ca14d87e53e00d6bcba5aa2fe56085fd66b752b4041d5aa56ef10366d078ba376a3b0d283d2bdfca07502fa65fc16fb1319f75fa614f5e3498c7ba76688749d1505bb33c24b5103b5b0079229aa7d2521ecc9a150b420fa87f947c20dddf64fedd29e72803be500ecd56c6276eb519ce579473a3c8155e0d4a1e65e02232e086fa407644a557aa1ead6990db1404ababac8f2dcdd8351aceb51e5201c99e2cc66f5eba5f52ec5eaed5a5774fb43bf7f7facccf859b99013363952a34b10e86855d18e8e34d49f54229f1e97ef42cf0de1b685862828cce87d0b84f19c092e8f1510d5c2cff9e9236d608c2ee29313664ebae4606b3163118e7ef3bbc709cd5b350ccc765e7b046aadbbae78afd7ea750f726a4a56a09e5053b424d4d4265a338519e19323e91e9d0a2298329f4151b337c4f55e61eec632ab63f159faeeeca1d52fdaf947f8bb661a126ef71dec5821ccc22d07b61ba6c7ccee34c238c663d6414843295574d2dfc1ba95b58d6673abe818b97098ba1380d5b67eb524270d7d5dda5c6c2ac7c8a859b43543ccef64f891a3d809acdaedece1f546f1012df955aa768845296c62e6c79d42653aecc5ec372f587acbe8a75609f79155d66a6436e593cea6a2df9f219c978c8e7aa787d1adfa353c1c0eb5f6e9f08fff7403e5c66c1b67170234cb00bea9064fb98e50e16866dbab37b5ce564fd30d23e758735a0a55b0e4a833098d8d7109fbaef9e8b6158e79e0329291d2691a6da07aa102d5dd2de30f5ca5855eb89f4368fb7438c339d94e4f676393d119e758e578f123cb594764799124fa6360c0ce5c64b9c625ca82c87266584a1b591e741b98b9ae83590fdb990a364b29a15a07d7d8dc7672757f92cbf718d6a980ed8c613a653388960abdc2218ca2559e511b6d95c2184ada19ce7046981cc3a06a2e3725844667b22e48c1695dd97ae0e8acb2102ab70287b1a5102be6abacaa68a5c57ab6a4bc10eac959b601339f5f9f46946f6d306ee93240978d6c385f6b33249b0f1f8cfbea806f7252a0bf6d5fa0e3da9ce4b471fe08cc6ade4fa50bad83d82b43ce99226777cbe805329db4cfc3103af899c4da89364b125d25c85fdc11adce4bc603a2159a6885255ad44c38a955d477106fcb29cc3027bb94118a4c5272180156a7478626dd46af0adc98a643157d0739e7ce24adfb0175cc462dbae9bea2229277d5443f88fb0c229cc6febe6a5e1b28b542dbf70160817b7ab6036a5b7bde311cb28ec2897196ce3a202fbcccec7155fc9bc6f8b61dc9ee179c8eb29e43008f37ac3bc91c500d4ef8cdebbfbd6e50be94f9c9eda141d596c3b99ba2ab34731bf4961472735991426e2e6cdaf080da4eb6a397e916cdc8cad0bd40b7d4d0bd3842f7c2a77bd146f7d466aad4746fc4af66b6b896e34d4be96d896b8fe79753637b9f1473de6ee357a0b3cddd4671bf833fe88ceb79990aa4b2bd7a61b43ab7028e62d48fa3431d19faa8e74b9793c9fd7d6c0e29c267350516e86c2e19c237a084faf49f5542bda3225042f94aa76b3623370cd7543436edf74556d3411dd33cbda3a255f3f48e8a0ecd534585d33cbda3e23fa479aaa8f0344f4dff2f1af87f51ccc180451d7a3e64f268d741fd4e22c1ef71f2aacdd00688ff6f3b817f279eb92285eda266902b5cfd0f32c8ff9983f088bfdaaf3d04b33c3fa2444bad1202ac3bce8da855abd6ad1df4d46a91d5c17a623cba6daabda0431047dfe20c04eaab36ff08a39468d7d21d6ba1d5e3f82ab083d7e8df5b0169754ded4ac8dfa883bc53cdd8ea6df25b94844715f777923284e8343436b4be61742a1886587469165a740e76c33ca675d0a012d664de27a7983774245331e533cca67c36bb8f86e4985ec8b4ea2e9dcf91211ddfa96ea99d18bf522f14ccd22f5010dd4fe47a79b7bea02ef8eff73720b20b75cca61d82b527cd40d0f47d846ac9c1dc2154ffcefce4fd38f77754b473eef74af4dce4bc6b4c748d879ea6d7bf486be611b7648f5fd6d863602c3f31843f1e658c83380dc5175b8804258964fc8a0a93dbccf8483698e23ad68b4965666db22aee80697b6cdcca27f22023376deb6fa093ae65f8e6853862f1501dc181eba86700e161ce3ac415da85035471563e79f8a645fd486a317f28af8cfd9eb528efed1115ba6428530cbfb72926f4b23c628a716db1471abfd326c3eb3699d07bf2705f9bb1c172fe8eee2a9324c9bbe5488e11e1cd89b5289b54f1dad3b4d73285a6a4b1e7f0a3c6632cb41d87e9a40375626a401a35bd5e43d9b16d1198067bf4d7b41767479cc9f77b6e66c763c01ade3d9923a5cc9192924d9c79ab65389c1ddd3834c3a014080bc3f177b0de1c53dcb2527f60533adbef53f84b8e665f1876645f10daa3506e06e09650cfc4620a28082af0d73c2000fdd43d049725d3d227795ed8fda031c726d37dfb0c7b290dfc29ac85e8d787558421301a3407ce93942184534a082901cf9842d203b999dc0599cb7186d07edf3bed11520cfc714d127dd384b749e9a20b2b57b44dda333d69cf5a26ad03acfa5e7934de693aef9e4a5ba23697a2a9595e97d7b41e2be40fb3cfde8bce15075b777974c58970c5a92fc7fe7ecd770efe2b90249adb12ce089752aedabee43123af2449583702ff946cca0f5e8d5686c0f5fdd3e821eaf7ed569a24057cb4778a0e3aa5803742533ad391215614d2bd6e3b40bcb8822cf4c00864bfb2017b16f26aab15bdca562a5973edd00efd400df51aecb1a85c40da5df9f326aba24ce77b862486dbab25a8c0ec87a2f9322bd8207a5fd1e881c6d5a50fe0aca7591e8932cae97c95716a5edb404838d419150272a41573d90d5b7f211e545179c3288f7f49fcdf7f946b6ddfe35a999ffbc8f1766e3d46a98b2b90e77220c0b65363d6498d5992282f8ade101d8e927fc39be1bb9ab0a70d0ee3b65a1a5e94d359ab4dc2f852fe6ad3c4b8989ece7c6c0d6aa1b5b7e87fd62211a45b3c67ddbaef386e28bf5f2073d4071c9d771c9988f2730752363d9f8d95b4980a9236cdb14198f16b8dafd08fad6a1dde6b14d18f3dc8998f60c3d53e8f2f5528bbc52c914d9284c881e5f981d590f32017147ed67adb8dd63b8f65a57e34cd7e9f0258bf737c7d5d13b554bd755fda8fbe2fed736f51f77aca995655fb5abbd4fae8b62ef4b30178442dca9b3a02039447a7473730b100369089723db66091fed4596c49033ad1c0811113cf83699442c226e71c24d07ecf020f3540e150dfe66ab420880fba2a9204307093844ec50c07a8cc6222ebf6d1731bb58d2c72f333879dab91746daf2cc4687bea37591846db1f050b78108043fe1c6edf5436247e0e10ee05bb8aaa72ed21867850c03f330b913f6a36146cd21efce5c8119782b9809aa0293e0471d0161f78587fca800c079503d0e4e80d0cb302e497f3f1c42e84a64ac311ecb7f550a6da6e7172da845094acb2c52db2b29b4e2975fa501072fa90397844b1dfab1f2c54d6f63cdcc41e61266855c35d8c83b955495e1c1a63786520be42a4e98a3cd10616058c54f588bdc33cc5b18e3aab5498593c55d5466fe9d5f34f9b99cea963eeaaf19bc53ab02c8efb829038ee2bac355bec1504b7db627dd1237d31e9b31ee9b3d190c88bd3877d355223f9b75ec1b34cd0fab7bf5638765eadcdf7945ac9b56fcb946c907b26472892245a0305cbf0f5c28c1421a4ed0143e177ceb2e6d05021bf0bc8aebcdf3f08f20a127031f99719c00d5b1c9466b39810a2cc1cdb6023f4615bee9ae81511fe818473c8f266af65ed7223cd93a4d7b65dac9264e52b8556adc9367395bdc496ca519204805d058b44f3966beaa158a4807ee21acf21b29dcb45362e48b1df4f15833e276946328043f26136c7f39393b1146db2e97ce6c38e16ea1ad65c66e1810af58b21ac86369d13133d8b7a2ed2db3527f8468fa6623a9f6126ffe327a7b0e85d676cbec905f13d7904c24b839d502cd239599808c4d0df47dfed1132eff8fe922ce4977bdfb094e1a51489658396b241cbb606d9504e0072949d87bfbd611358f295cf79d791c1cffcfdf5a60b13dd83ebf6b2f67c131e25f764b37c9cf61721e05d4d493c236f999f25e86d4d9d2249cc5bf19676df28aebfed91fac2118489cb7f465ff69d23025405e94cd49b06166d10bd5844bb72cb23caae0b5e32487b62d25257db8d64d5ed3b5cd7a35fc6d146c5e8e5e50dbbe2590ef9abe1db5f0ca26f4a1e418aade8550699a89fb09c97458e21417391531e6d37f22d795cffedddd392d3418cc60d96eae2e2ecf5d7ffbc78f6fc1fe7af5fbf7c77f1d797afbf7ef2f2e2dbd7afbfbbb84892a38f070593959d95979fd2db6ab31b5181e927c1b36a747b450564e87a2505a9a7ec803f9363373a3fa08397ae92a57ff90bc22cfde22f081d705d05156f2b1a99646d767e79474286db83493d8b33727bc045b006a94ac6ad404d8a20029b14533ec3c23aaf31f4980cf7fb349bb21901df5007d3cb06792a709cc56d5136fcd0d60bc506fee1e19f7a7f88a2a7e566c78baba588d2398a3e1f9efe57f4379a47df67a22ad9e00f51f4b2985326057a4996caa3e5ecc5b9b91da5672fce118e2a4aff10454b2136a3870f7fa6f98d7affaa10cbede5a0281f82f3a8e47aaa3ffce961cf6b6a30a68aefbd3dd4d6a01bebec1784206b0b671084ac20d2b47e462799f4b38f1022377887fe450a44d506cd1dcc7b3d195a92f0c079bb24999faf99a3719924ba9ad2c1ee3bd22705329daaa282451c199f135cc9daa7d5cc5650f9004fca8215c5e840351a71354933a3f82619b6b749a6b345cbc32de52d66acec60c39ca733c9e9a7ee658e0ee95deb4153e2bc95122f2898da8f11eb27bfc8656b91ef5c90064bbf4038232c3d8574aa0396660897f2fa2b2469fb4fd17faf3489ca757e025907a3eb2f075f0cbef843f42715a93c5897f97645073f577f88fe24ef3656c397d159315fd255f43dad04489374a0cb9e2f8b2aaaca2d9fd3685ee690957fd5be584c4b163a82593e9055bc7cf1f4f9ab77cfa345e165f22f4b11e505a79237d94592b7f23e243885063cfc835d12953b8bd2aa2ddf8de1241bae9ab5736bd266eb3308acadd09ead2c98f95ca07eb0fc6a92d09ee55ded993b316d1bd90fa220a3cad6eeb1bd34c8fa2590772a9eef36549f8cdace2d57519429d7f528aba2cce6e68ac364552144c670cc1e192e6cccdc5e22a66c36e603a76e27fec57edf3bc53c300790de10c7c0a24b361320f5ac6580f486a8cb950a73794a48a1dd4f6f5583b3489255e07425c09965a5ec681e0332afbf0828b7936eab84f68360c77daf3c04bfe1018d74520eefbb0ba73869ba540a0790df3e83efb61bca23fa69c36955415ee16d25225a8825e5d12505147f0518eaa6744c3b333640f6773756b71e718e8cdf87dfa386a7d9015426eb1a2be8a5244b97e6935580223f69c5966f5d50838b0b68e2c54517223d45b595b10e7411ebf626ecf7ad4a70ef7b4460587341e7360104709b8c27fc2dc04f70149a861c669837d76fe98272cae666c2619f5b66c08a5e52caac938adc504f24774a798a82122a6f70eca5fd4c291a7950bd17617f53416ef59936ba3d1cb030271c723f412db3c3d7e4a29ed7a77dc1081c5f5cd0ea0c8e92d8ac1db924343b73648fd4fbe0a2e4600f7097690c07d680aea8e45d6234fa6a783afcb33cf15a4ac976672b5de82b791eb6145af0eccaabebbfe469d9524c1de717eb32a7bae4ffc155fb5779290f2eae8a9d7e81b75dc5ae25fbaf6bfb0b5eb5169b974cd04fba75a7439cb796caaa1d9b7b8d3b3dc5f3aeeab4e375587ad13e3625bfc9787ec1e94297fc1c2fdb87675b6de459ae8bfd19af5b8bade9bad445bec49bd622abecdf3b5de42b3fd53cbd87aa592bc6079f7da69ed6f254477c641211100a18ccfa7e0ebaa068aefe14ea4fa5fe94068589da0cd4ae12799c9b8fe9ba56eab585fab36dbe6d4e9bc3014a64de0d2f3b6f0dd58210323f28dce8d70b7281c5e0899cf2b332a724c762f0d4ce2bdc9aab5b92729e96ac92a71559b97b6f34ed912d1683e76a2d118ec5e01b35e16fe9822ce4a55e1ba4c062f046d335a9e4052c2d92613178072b033e5b4ae9acfa47b62a725dab3cb85a4c86ad98f72dbaf0fd9e2ad143fe99ab3f95fa53aa3f4bb7fbb6d104e4c832334408d9ecf7c1f5ba76bdad5daf6ad70b74803ebad16f39af94ad494f5bae5ea84dd0cedc0ca6a8a52e5dcbeae0bf60e7affb85ad7ac14c6ecb141c1db5a0d35cd5e51347e77717baaca19cee92852a69c9aabb64a54b2a9aeb2e97a9721e4176972d017626dd916b9424bb813baaac5bca71cdd70ec77a41c75081be185feb358aafdd0ac5d7b5f5a96ef853efee98b9c5d76665e26b6f5dca0b3db6f8daae49f91346075f7beb115fb7ac46b8e937ad4e9be656ad790de2837bae893e7da84bd74c37cbeac234d59f2be00aae42ee02dd3a59fb5a8ac197e476be2c56b96e8aec4fa59952735dbb84c77a72e40caaeba2daacb21de8bc948bd7b35a09b8c58b6b9a4302fd6f78b956f941da9fd9f7d6c5a782c1af0d2f37b6014235ec80cf74eee9de10ebdc71aaa84e352fdb2e79376e7fc13dabab511785d8416537e4f630be995e79e43123b766e1aa7c6a52e0bec710f8ad55fab94fa495afc32fdbbdc0644515fed8fe509df2153ebfcb830cff405af97bfcac610e84463aa7e820435a033e5fb917586fd41f52a63c3c7a843c4b12f96a662cc10579299f7e84fceb854154fd98328490972fec662aec1639dbef2f71456ea62cbcb525c3f1d62931fbfdad41602fa65b50baf5d2b3e96ab6dff324e1f0a34a920a7e9449524e57339bb7fe3c65906599ef6e3fa502af70eea52f3e58dd97703ff0eb0e976a74bb35fe3a1a89ddcbd460de9752f5f4f623dd8de292c51a79feb8ff7e589749db8eeb51d44478853cc03fc8f7c0a438ea1e7b887f87c301abf6d07521da5a54fb7e6bbe33171b0861698719aaf9a33c9735d92b708ac41ae4df6942b60ddc66c9bd5b58eeede3af26db93af46438473f2d5387fb41de7fd3e5a4df393af7cf4c7dc5af51571a77cb0651ab40fd5533b81892d7ef4286325dbadcb6df5f8718c2bc90d65585ba8a7d94c59b62d5886caf0271f4c6279118f3c33cad88b22d0b2e6f9924671bfecc7d187b85ff5e30f515145eb8c7f5429dfb5210574751f2067f7071c5d6e4554882a820991e53fc47dde8f3f0c9cfbbcfcb4d3ce2a75aa4e0530b5c33b336b6da542060db15c162c571a63c861667cad8beaad6e4d586618247e7ce348b5f21cb01b001231e0fec5a34089a68ce813c329b542e83aed21a1fb7d1abfb397621afff77f7b71b4f1ac95c735326f9075511bb60ea9c0b271560be8397e84094c7ddc0c47aff7a72e9a246f522020485029ca97e50de54fb38aa628c80f09bb5f4dae8a9fa8c12b091f14550dbd6f7cc969f651d9dfb56f55a3a0baef973ccb36cd6267d9469731b254c3f2f79e51707ea139e8b78121886243594293d51696046cc065ba4566576e6e6f6fb48fbf6793d090a21d393263086918d74b284a326538bda29f36b1dbaad3addc29e8248e4a1efd9c5d67ea3c942ba93617fdf8433c8adb96ee0ba672e08277a859bde50254d5f27a25afabed66b32a28b894da056c47ec03846ebbf10657d60f713fefc7f5c58cc24c3c4fef438df7de3dbf9c6c4fbe54bbe797c1eef9e5afde3ddbb471a83988d68dd71bc079b9de948c3261462c5a665554e8e17ea319a78895027cea06b1b1c5c825aa970652e3d08ce15129f78c5d72ec86481228cec950f6df301072188a459a72226a9be816e76a94fbf114e66b16fbdb29eafe6273527f4e7ba7b6ddf869b8ff62f5542e4ff3db384ccacb61c78b4335264f882a635e819bdf129582ee95e4669d378227b2bd529effaf0270525a9bd7ba538071ef87abd4a6da882f2e3ef32c5f766ba0388ed2d822e87f8b63e4f4a7dff6fb58a8e00dd908d8435e906fd2782339b033e0f96384dfda5b347f260fd942abdf6daffe1d24cf9abe98c17ffbfded01e089c40cfe93d72eb5e0aa9c7fac88febbdf0f311faca95896b9bca97fedf7d3999f7af0fbbae546b94137175ee62d3cfef8f3093ff95c2ebc827c3e2e1ef1710149708b10f9bc988d856a4dbf0f0ca93a133c4a82a8cab42436aba6c27d43b8743ec5aa869313ac5222c39564fe748fdac338a9c38f55fc9bedf1d7c10ee433be760c1a9de75ee719e46e1b678f984d01e675399b8dbf07b95f7fff7b3c551c3416769df1a03dffa8cf809afaffe01c78b98bc7e5a3cce62e3666b98a64d372366676440daf5da147c32471f78dfd5c6d3c77c5f8c85e2897b7fdbeb79dbe9d99d313dc6573f21e4c65dbc9d6b3006a133b0611a6dbbe96fb03f8de847e9aac9d052ec9d7a994d30ca9cdd382dc1ef05b60fae66981e32b2a5a2de425e4fb9525aab044664374c00a63bf603dc40af25e91af694b47fb759902e08cd5a77c4b59ecdae8862586e4d530eeff22b772577a274a4eabd193c3d8daabb255fa2fb579fd0da29e9c62a30345e25f7590ef7aacca5979f9297a012e41251f45bb721b416809df15ec4a72069910d97c197df0bff621820c8fde6968e254f2e8a610cbe8837232fa10a5258f3ee82013fe0145dfbe7e6a61ccab0d9d178b9d0280f16a9795cb7b373cdb6c68ee7d45c7c00ca2178099ae625e8acb150d22693ee8179f9af73ec4e8d030cc06e160075c547224ec40580bd531736768faf573cafd354c3412abe13889fb3ab9ad56b6ecf7c244e4f98e001046d10c4b78cf3eb2f2461e212c4952de27f1891cec93b8af5d520b2ff79927b7722fec646b6260c647b6c22cdc0a0b321c178f98d97b6a3b8f36aa0aa230a3704ac9526e7ffe0e49d50e6977c70c21840695a4efba02590cf4ecbdd05c0aa1076c15198b94cb6592a7dce8239452aba10130c7aae4224cf48cf21e51a1439b0ab99ff50c8a1c25490ab9b35c99299f9941d600299a64076ea9c2d1ad8356f55304c7b7dd9d65130ac4ea99e49b9ae99eefb4007e4d5e60a1ec31841ceef7291b70bad06919f4781a878934d3767dad974529388f1e6608f3439a0decfa7099947de2241cbf4b0b48d43ca8af28225a9d320a5aa505fe9bdcc72cf57de62768b4ca17cfd3a203a4c1bab1440cf95781338be6d4c1bfb2b09b18cc868db82b2a4881905d67c54a2ed55e74967da451b5e5342a601fd1d657c88d0041126fac39760c01a642f279e079e5271537cb6adcce7aba55329cd9e00de2dfc5be324ad1eb5fd591ea2936fc6d89f44e71cac80544e5369e0d3173a426c8748695934ec3f18ff5fb484c99bf9099a5454a3e4b85a7a87313f557c89825b443dd498c743ad47f123e00367abf8fe16f8cff2e99dfa27acfd6e596094810ffa36c3ca5f27f01ff334ada7cfabfa7d9c7b36c3391d3ab7f1b8e81abbce5af714665fdd5c762f3562d7f840baa3ef94dc9e705bb52491f62844bdae65b90196bf65bba30369ed4bf89ea7e0d07849c25d9f99559b036bd1cbafca24da2d323fe44617cf2113f22bdd7313f693c00e5c855520e1605cb9fbd3e7b55e6147949ed7527c3e729f514c72dfa39f8ed5cc0a85386c007c722491895ff74cc384598d3015d1722bd8584ad6e83567fcf8b351dd18192bbd4e43d67f94978e79dc8b8c0a214d90aca3fcb041db0f22645ad052d7f30a2989539800c0061e69a5edc7ccda975b75aa89f2ef37910b2010a4213ed43a8efd5432a1544a61e89308083d5fc9731af0515f8f9e1fc0c2441e880324c800062d3112b71bfd746600283b26ebfefc94e4de5c50c0bf5d78b0e323df59ccf68e8fa03d173900f7abf3f7d4809397d2846140438d1239ec271495b322c80ef12b55b9df318f764de1ae6dd96e87113261b2cf3622e562a6343a0bef9118cf80d22208e46945dc44c44ca0717d96a55de80794ec5e95628ed9de20af98077f4d0acf939cbfd7a01f7471f3eb9a67281b0b0bbf5c18b690fb93c83b7a07f06bc5e5abfd5f26e033378bf8f1f59ba7f1c1bb8870b5064bcd009330d0ba5110fdb1f0e2e78590ab91bbc78a6bff6ab6ac9e9e5f6aaa38a6f8a4bca5bdf8727f66583808f3395d3c05c1670a943e1a8d225a9087149405a61c807105a21c924b69a9c02c77f748a9c12c79a7d82ec2a35b5606f9b24e916bc519b278618d8e1febe58ade0538a4fafdf85509d1e2162fa7763b1a3a43704aa941d82de0c1116d38ccef67b8f0f0b5111e7541d62269c0dcb53d3aa4c6c4da708d3245901d19495c22d70985eab010cb7c7b84104c7f49f33a2d0c2f578108699b7608192d754ca985ef7f4715e836587ce526a0859d537fde7cce26cea6bd742052efaf7991cea1fed1069207f34a6f65071f811f55325a795e0e52ef6367fd533b9ffd3033a1cdc9367457e566ff78f49b2a2062acb2fa9c6bcb3a84ac96f87b35e3ad84d6992b4e40753bac69914612b4ad71a2a3c8b383d51430539fe1751a623853ce9b78a042faeae289762f652fbc32bb887285522f64955e41445eb32a756ce5e5b76d7d6558190afbe47f3a864ab5d54b2398dbc5a063affd0407e81aa90d8de5c0b3f2013618a7ca177437d85e637da874f1e5517cee882e30b605fbe2d57c0b8219c1d299a89726d4bba2f1535ec9d6cb6dfdbad03db8d5f493f9048437fa1b8a6510cb94ff57b87230cd9af81022abc45d40e763865b3a64e061e14723bd0033c65334cd1c4748a618a46a97f85fdad722865b4c6871d264bb8ad02608d73a6742c51d311af296a29d90a829422b518a24bea24a8ac5259ee626074ea96551b3a4ff7fb5480e37fb0421e8036caa88b46d1fb0a1683be8e44a985bc0844dd4aae889c6e389d83e6a92a24057f31182aec940fffad0acb6e959c9ec63852bf3e8f51f4dfb652bb969faeb2aafa1095dc68afda5e4ccd7be93c780fa10f16a1a55c441f6cfde9b459cb0cd5bffa4052e4e43b3f228aa2f40240d4462d2e0b7ad274f01ca196ffaa4b8cf52da836c03f34d47ddb8a460f4c8107a0e7f3b620b557ad38cdf21d58be1ea8a17a60371be8815fc3255d488a81fbf21be68d1832cd58d77a42b2c19b2da77660eed9f22d9048d862d838c3da06d1f992563412376594cd9705bd56bfcbcda6ac0a41a3ab325b55100daaa95aa74ddc024e4f7945c512e4cc12a0523c7fc8925a070b7dd6d5e3fd4d0c5d7331a9f260a5054363b9889cf716400581e6c20fde08a5b92e91d59ca956c0771a9e9a5228dd51f018690d8d0c0d8bca4b06a10328635a7ac8f67be66bad58436b250b1415cc0f107ec8fe8067a08de26048b30625aef08a5cd034ad4819280b3dd71cdb68ade114086b85e4321528303dd96483c8a9154174cd5371a75ad16a665c3cac772006aa3fd0b48950d386cb40c5c6425e5fe1b3e172e0abc3150480bdc4e5c0fae741022cfd5bd6ecb9f5c9aabd4b5c399ef05dbac20ce1d541a5b36b50a55ec91b08078b9465dbdb024a6fb569abed9c7853bddfb371cf9fa569dc60c5621cb77196fe6dcb8bb5e6a714e8b617725d6063c36b0a0936d5ee8810a683568e6dd271bf47c8bae3517d3f8223a6b5a43c09a28c79768fe832ab02430638ae5460adb8a4cbecba28391c1bee0db913ad21ca72a551bfb6ce9b85d36abb12d5203acbd81690be8af546ad67b91b7ea89ebeff50dbc718a539b08d94e93dd331a383188d3a7add391c87742e3770386dfe090b5af339a088dcd0748e63581331d257c0466a825993b9d92c8df9ce0822cdb5b6f45409788d0e5809da3b0a7b42d34f870ec02d98538619a13ade1d736236219c495616b6691b7395057e4d6a619898dfb49ee7f791e9aa6647c8603078f858299aa355c9ae2837380134b727a33c5935fba20d5c94cd5725cc45c3c4a5c7a924dfa50ca519eadebf4bd8be01057d4783cd2536cd5431e3d7f534f89e3595c466c8c0ab6962f6bf91bbaf5bd016983115b3d628573a2d66930eaf249c97409a5bc867acbe0144afcf441de95b656b1a89622d87ee43dc6768d472eed41bd0bb4f03a20f713fabb94555296c1f2dce51ace61c65bef541ae1d45459e247445c3ccdbbefaa6cb613cad1f23b05ed0d8ba50a89b54c06b4178e325b51eaff679d3b470ff96042608f83c9b3080d23b78ba17af01675a8630fe1fcc339c199049e8ced8dd37f8cc70dfc0335f84daa1772cdb54cb527cb3caaee4b672ac8cfaca1515e6c6d7c078eaeccf0c7b90745e2398df087e38eca877bade6a8ff96b8a0d898eaee9015fd1c1c58524104eabea9916408a927d9f71563068e9e5dd45ceee2c02cbf686ea3007f9f5de104bf6049cf917e0f6ff89767144d4e1583458a394139f3b72dbab7c094cb3723c6e0ff82585386b458b98ff7a86291b3cd59d18944cb362dafa6a7a87ac53f715154fbdc88e0eebae6ca0858bef34caca76beac692db0ef5f410f87c3cc74a36b4d345dcc4da83d6d9c1cd69710c4b2d01e60b2717da41e705068216816691185fe696d942329d900407db97072b81690a58836576a0027a1c176057701154e95cc1437a20a6bce43eecf72c8b2ab4c008e4db65ad9cd3a46b84707867eb5ae01865413b085eb60104a8f3ed2141022a76cd62300d17247bfde049d3169ce8ef4496516f86d9d7251d22ddcbbdbe15f3aad09ede8682a2c148ddb293f52cfc67f43a7541e5c470631964375f844438920740fc29f34c7f3b4b38ce7207fc06d1c938ba4010adeef7bc20a6ab6fb0d49e169c694eed0a6685220124ecfa8f4406d4773e7f1d31e2ddfb5b3bbb5a60e1e8526a3fe64c4acc9bb15fa20964c18899b77e351ebebef5fbd7bf2cdf38b66799598abf3718cee655f98d3e21a1492d584d75ae53ffc058df35f03b0b6d6360695dfa7a95aa2ca6a8d7c6f3288dfb77946cc4ab3f6865993be0e4c65ca06db2384db5f969fa5a1604db560dde60bd04d8993cee32045319c15adbc068ac76aa5d830842a5bd06845afb2f92e5a150b3adfcd57b48a6ee48ad1f29942698084689e965e496a72c53909e1c99b17d5e027f613030774c940573a4ce7722ba26c5595e04d97154ced7e8b72b52a6f643d8d168ce27e6a467312ffc4a228eeb3511c237b9b9bdb3cb89d99db19dc8e6573e431945d96d7d4efa253112b7cee7c10bda41967d11a948297e55628ec9e1bb5df454bcae9e827b61462538d1e3e5c5c0ed6f421307c27806b706207e2c47ee66459961fab181453bf6882e526ddb20d902b8a8fac4772493bd645d71ed5157430686a3b5a375938b3cc16db497675e20165ad16b3947d236a7e2f45461ab547408cc6ad4b9c9c516d826d6bf8b8ed667b82027217af3f395660c4c655c0b10a80003aa49f281a7f93c6daccf89a19a592ce3831387290794100161f5099df442989d73a8fe9caf8a0daecee578dbcd7524b0bfd94832dabc0c9e7e252c50da841acac8792c34da228bde5dadcfd4e16ddae281f75d670a8072eb5822b1ec50d9c786f8caaf46859a3b93da704200661b8da5106b518aa2f0f07fc033572d75bb062513ee2d49968bfdebd2a73fa965e1595e0bb11eb7844d533f01fb1f35ed52cd76d63a05dce3a60248df116ea0d143795f133b48a1fe36e6a935ac668fce37e9ffe487a4374388cef8bd2a89c0a7ea0f89c4a09a9bea2daf0e5dac1e3ca034263967e8e304b3fffea4b8712770a2871039672955ad1a898343f99de4af219d8f0ff62607874c70f97bee9d7856055a60e94168eb5deef55608bb8ab3ba6819f2b18bb2f01c62efd0a40ec062c2d10ae54f3b7705d21bc222cfd3f08e7641a7f5ac5385e5dc5385ee7318eab758ce34f553cc373b21df88693baab9fb6a90d2eab379c2e8a4f58b213c0d84a12c515a183acc273629587d524ce8beb78546103219b66830ca5144f6353498c635b458ce3ac8a67081b30ac74258b331ccfcb558cf09a4c677843a6d62733efce68aef5786431a510c3a87365c84bcd28650e5fdaf93fba3ca0d5266363e13a53ecf70566241b948b4505d9a7b241c973ca1526a32099d64ccac194d2c9243e89fb7414c75a55259264adc2487a0a8e3d8efbcb7e39527ffab2b4304c1c4f928d2a1bc337625d809b02cc2b00ed312518a8f7d75a42deeff52797086f1b2ad2b97309c8507a7bc00b7ccbe96224b09d925139c86a61748575575fe30dd2b6aff13c54b13e2d573116838ccc7f07524e59fac51772b5fef94b24691a487b4e58fa5f5f21bc90afff45d2905ccd92687e05552b9708bc52fcb23c38723c0fa87d4de8e03ae345c604dee8374a862fd422d8113a008f9cefe80e5f133a28d9d35531ff88af8e2d04f5d518c7e69bb5c5a1bfa74b964cad171c9b2fc538d6df8967686cf79b5c2fa2555189932b5e6e372785a06bad4abf34c52ad896b2d5ea329b7f440da7f3957360dc70f8a286034935663e1d54a2dcbcd12a04d861c7d749720d280278bac2d70e7bb6498b8b4116522310e2015fe15bd33ded249c2e079728dde1abc192d305c25935bad8efd3cd44dd98c4593c8a2fb742942c1ec10684b01e96d1a54fd9294ae798e12249ecc8af92c41bfc75923058546bbc513ff5b81ba25f87a6c55b3d41232565439da3de2936354240cd3a5c282f8b4afc55cec90b392530231bb2c617f7a15a8b0aacf6498a6fd537bf538014efe84a6e6e07b9840a8f7417a470d4be84ec608a8ed7a4182c4b5efc5b8a492bbc2185a4e50bb7076ef486bec1bb808e0b3c0d08d5a36947b3ae66b3cfdb308f8052173ea54ab196ac27b063ae277e1d23ef424e911af4964dae83b076f856524e8d202abcc0cb2459c0b42f31333f9999f28b6353ee5aa4ac02f8a263b2637c3190134e3663b9495efc7ee7fdafd8fc58f9d7ad109457e648cfdb8ef4703b3c7ac0db0acd86e568a5edb0e7e54d7c64a7c85ba773816feb4b7b094b9b952757faeb660ef37056de963731ce6bf36adb0c8b564e52de9c2407bcc4d2cfffeb2fe84e9ce3df30912c3dfd429d725ffe599f725fc9c1fbcd3c9b59fd79837fcb2771b1be8a47f9fdf937ef88eae0e4329e9fc85a8fccf0bc6586ebeb74b28475598d96b890a3ae667659e342329ebf585fc5787964d51eb4e57d8937a6b173f9dd78f9658cf045edde5731729b1fec57aa4b9765be8b11befe6df321e7e0f20ad696940ef0525e0307080c87fc08701bd690aff98d6b3769177a855e1ce73582ed5a0a03caa014abafc18f5c3214d6026066f4b26d466384cf023ee28caecbd0f14acdf6ad2cfd2dcd72cabfd68d195df6e39325dc8a0f9253b8bc834fb06296c14b3d3bb4ecfbd75dec44484805bec47992c4975727713fc7f32481913889fb737910e8f1908781e462d693e68776ca4f6c83468a1b1e5f378930c6d7350a94c30b5bcbf5e0c5fa8aacf1f5e0bc102bda425a42de8ff1ad95d7479b03c2d78377db4bd1f14aa51f056f5dc05b5f97f98eecf0f5e065c13eb6bcba2ad8c7e0b5388be1c573fa49b4b50ee8c62fbf51e5d52cb7bca1e71a01645f295acb2ce0019479b1be7a7d4df92a6b5b76c5faeaa4544f413d9791ebdfa20a58f820f1c736e98727e9003dbcd2196f60cb5ec1d3ad279034c357233a1dce06a27cbfd958b09a1452329bf4df6985d356b77911be76007334007fe90810e1395a2cfcddc6cb00767b180980bcf72814579e903b99a7148d0a387fec94e2852bb1d5dbcb560a58a12bdd9aacbaf63eabe32c88088e1fe176c22d11b5f3673b59c077fc6d4c74b39a6a7f5a07545261eac57cdce3a061b8be3facd1012fd5cad615d5d8fe658da7aff0fa7754e0fc8af365b1da16f97f8a9983caeec7c869730bace3356978d117a0212946f189aaf33fc0f2154aa9b21e2d3b78bda7b6490d8e0f1a718cdb0b66d07a59025660a834ed39c5f1dbe74f9e9e7726a46951761f7f65305fd2f9c7674f9fa35b153875cfe2413cab712e80a493f2c9e190221cf2b25ffcd20c3647c0f3dd13146401f5533c501ce0c9ff9ad434b55d9e43623255cdd74ad3fcb6dcca43a5adcab9973fe4dbac5a1e29baf08abe84c3b2a5d0b557e85576dd59eecc3f70fefc1532c793e49ff8ee482bf820f33ef18697eb4d3baa0b1f5c7a05df52951ea4a3a83f0cf0f18e7279bd5c5723fdbc2cef2022eb68717f6cdf017c5e47c12bafe0c585aad37a45b5beb1f4deb8a28cf24cd03799e8fa40e1155fcb9573a4eccf5ed96d45bf2d2a51f25d47e18f61e197e55c67196d2dbd0a4bbfc978b6ae3acaaec3b230286759f71832affc4d218ed13c1f948650216fce7fa903ebb476607d3e942756cad253654c41eadcfa52f1449fffb9ce1405710a16a101ff56142a0bbd428f81ad708454502e1a2cd58c390946321a1a0ec581ac846c08455834e2385abcb4cbc669c60714dfea4faa9ccdfac27953b678011ed0018b432aabf31cafae213fdfff8a31bdfcdf34a6cbd6ccdf6d4e14139a0a34a207bc6e7fa5113b38b1233297cc15088ff09faa66d32a361cf0052903ce6fec24fe24492fc846357cd74c3d6278c28231cadfd205b8fcb3ecbab8ca04c599679da8eb93a7b17927c6b17923b032806a59a719cfcddb5b6d4e2af0ad51bc07419d2a5376e69812816e4d26ec866d411ca863d4e019cdf77b88ad1e282d3f0042c717155d2d0086c24f58e33235a774b0a622fb8eeef67b3ac85642ff9a0bbed23fab65b190b7d141e5c16e690d4f214cd41920395d904d0f2641ecf70c37495332313932db674b6a18333fd6668e33c7a3b3c96ec4808bd70222f0f1a20496ddcee8a23171b6b218c7facd18c7a28cb19b53a767695b504b67d9ae05c251744b4d8e212566191402d90db3f03859a74b29800d56fa8c43c1ef15e113a6bffa2da78b94a3511c3be5dad619259792e35f614381758767416adf19a7c58499011ba90cee2815feccc19c4d760a256abf9f8f767634c9bc651633bcd32205beea58a1979d2bf43249d24b72a5c6e88c5c7650c034ce78919de83403f12ca48378935dd158138332f43cf524694f8637e6ac510154a2aede89dd4a8a76bea0b72192ebcfe602f48845f544993d77c48d253e2354e7f5c137f05356f349d1e04b9f063f366830e88d316f3ef5adfdae65359524b44ad2aa6e538ce395e59462cde5cb1fead5df9fae6183b08352006d7fc20c41c42029069b4c2cc197f29cac926465d5390fd3e9a0ffa709f97f7aa3cf6e0f299afe34db3ffce9a7197a7885e39f7efaec3446f807723eb102eecf2865aeb65bf96b748e613c461bac7a3e3a3b2065717a467abdf4627291fe80191afd80f03bf26ce22d0f97efb271fc0beff8a7486362d1e32058c238e1a7ad4b00212fab64bac0151a2df06bf26c525bd237f8f680e76874839f87ab3d2499d1b324c9940faba795798761d647afb12847c5017fb4b37dd523e472f2dcace997a3e76e4dbf6c59d3d7f8b909ddfdbf495d630c3272a3df14ab155805dca29d2b3d8ea7939b4fe26a93b17834af29cb6aaa1b679c91d5b67adeaceb3a9ccb2cbfa2c78c358b56ddccb2ae9bc9f11a5749b2eec727eae385ba88fb4587aae66bf872434d23dfbeb796e6a81ae1ecce9ca1e75e89bcb5c433af447bf6d28d5762d19edfd42bd12e70af43b5b49fd2d6a52a7a08f0fa83f932e34f443af4822b8a06d0b1e4fdfba7c0fb99e4c18fb231eb9353ccfbe4145115a2c16763aab26c1f946f538d7aad623949524162ed51c22483992414125388347e1823805e2e092003d5ee56b2acec07decae7592ae4eaa9f6fbed5841eecb679392f011b7613f69a9737f97a4f4440fdc2b43d8b0f821a0cc974186dd9c945373e7e4743666241ec8a1cbf7fb78607fc15fe5dac588073f362743bc20a54ddafe980cc78b931355f59294d3c56cacea5b4e8ab4c40b34d2b52e27a9ba81e7fd3e1acd93c45e9f9c28f08015b209d2e7089c5625479aca0ad0b8b7d2cd2aa7c3d97e2fff978323ffa2fdde2b6d63894bbd1b3f74eb972549fc5072c9eb41b5bdac044f4f4e5192a4eb3e91c5f0da33225441764930b5bd5e4cecaf148d1a49a0f4238def67d0923d55292cd162910ac9d20418730a374e1800399755bf099862d1e96a292a208c4acf0c71e9efe54d7a4df92e3048703fb32366533e834da82d7d9e68499f667db621237e46aa94d941e60a142883f0019a729cd9a1825836fd3babaae28ac9f3508e0a6ab43168e194cf6c230f66680e70ce7cfe676f47c88fec08133a8a1fc6fd30bbeb91d286444e8314f88b761071ff2620de8539192cb0763d6f4692404e9bf8e1e48fb1cb74639a61a61369ec02d728fbc46fdbb2b33fd4ae78a8030c67437c12766d1d847e191e4c1ed015cdf87c0992f332ab962a545e6e2fdeba9ac42a374f9af5493c898102dd68b2513c89fb0c619e24f11f6551ae8bfe5116e55e513e8aff08be9e592d9d2a6636327ddca258488b96ec1c14da89198963cce57f1971d9e1e33fc63aa75006914fc28c6e86b07057439c2183f2ebbd3cb1fb0a54514080977da9a8555120a4d859c8ed25b01ad2911ea9492c451b39b6233d20f20e3f404201130c3d72c00469416aceabb29ca95eeeadf6421e4cb8d0533851d3642edda8c32beaa69cbdbeb94023773bc6054cff444da0baa855216fc939edab9ff275752b566e92008197244e5c539d539f57ddd4508d5e0f723a2f73fafeed0baf5b3e4ca3529ef83933debf7d010efa10e66f2ed2076ff4cb51fca0efaaea3f88a3b98f8aa1be970f54a272484efe91ae76d13c03dc9fcb5d94319bdd6343f99c327142d9bccc0b7635782017955b186921b73dc210ce26ee9b13750eb91bb571b47d2fbd0b9cb9eecb91b585dc7defee7e1f50813cdf8acef4beae2021c22324b3f6e1b6fa296fc29cca5bf287bc21bb28af3fd25d926c53aa26130b1d23ee672d3561da365790703eedb72af9f27a23daf0ad28117eaa30aa792f559502f7638b82afcf79c62a48ac715e8e7c2bbcc2b6d0c76dcfa4832d5ae3ff26eab81ed1e65e534c5a5ee0139e16f2accbd2de10fe875d01292e0a6e1e70b6d95096bfd409c81ac9d218e90d7ddb22ba657270030f7407546493032927771ee4516300a94c8e8bac721b861c199895a258ec4cc38290982342340b85684e8663fe888e79bf8f0028dd09d17c3616ede10a9602835e2a8f5385247d4d7aad41393705cbcb9bfdbea77e0cf2720e5f6bdea9219e7b901c1aa122d52f680292bbae07a4912aadad6ea92eaa157d8ac0f7fbdb431d32f9d64fd67b06536c737903d5de1e10beb61a97ff8fbd77ff6edc6612447f9fbf42e6dc288404d12265f9411baded747726fd6dbf26dd996f338ac6034b90c434053a20e8472ceddf7e0f0a00094a94db9dccdcdd73bfe49cb845a000140a8542e15155a97be2223127f57630257e2f54a25fda1c73209881458d78be505dab96a7e77c26547b51e0819601d37327f728e8ab9dc876f6dbec2a4959eb239d53916880831ac08ba5c856ac29e7ef805cdefab0cc38f3948653ef48bbed297605934b2fd926274ec881eee7fe4e566d7d12c90ce272abbd10c339c9b48bd41fd95cb07c890b522e3a79bb9de329c98205933fe5705daa469a1abb05e73461114ff15b922951f646b3f96d95fd76741cbf8503c02b9a3390e44b7fe6579f08c59ef33ee04d4d1579d860ae8524066d43ea2b08d355e77cad12e85d6ac46e9782b0b52ad71d049f9cfb09be43085ffb09166ad2940d7f7676fa542e0341f92c5bf928b0e1e6fcc131b2ea49846ff56ee513b977231dfeacb077158dd79821fcda6e32ec16037f0ab6e487ffbaeacd6b631de220f752d5db2405aa1962f502e0854799e08548de7ff47470fff5fa95ffc6ae3eee1cfee8a3079575e52313e0ed3dec6b6dfe2b63e7f11ea974fcb36fe2bb7c0a1ad6149f61efc3fb0f1ebec4358f3a72f4b3ffa03b1b6b004b84986d5043684c874a9cfcea6c123eb37ba59912ad5173d22f0386399b840a4880fada2fafa87be25c69b4efc9411f3ff7296c1fb44055001f88a603fe958c3fa85a26151d5e388371d75dd51c0a3d57793c5864766ffb037156ab772a1704d40f5dc250bbad7eb39195ac74367b75c3b8b42ce27bd7d9b576fe855f229c9462621750b1bd76d6e1e18f08c58a3f7e68b76dcdda84fc699537c26ed50f5dfbdeba207f4d1e4c14de92db9b47f803ae2e73e21758c9b878f7b85310bd95f9ecc33c2aaf6c9af94c60efc34f1f7fa8331a33fe450c0fbdd0f69902a44a468c571eb593a708bcca97d2d607673609068038dbd87b575ca02d0904a6444456218e7287f12ab48103714a7e2d7794793744e7a9d14774f6af24c5eeb480fe9454131ba3203563b081d3697b95f55f40ce1f5f7d78f3fcc5ab3f475183cfd712d55e8a48f424c2ea9d69de6efbbf8ef30931e4744859f6e5cbd4ac9ad6145d64f173bcc8bea3eee5347a78eef742c835fe46eb792aeb2acdb6eeb3b7949a5283219f82529977c2aa7ebf5efbeffc10e1efc941bfa6b15a8076db57b30fbf53c8202c7da59fea98bd0d22f45350d7a99da6a019a701a850d7577a887a0db3fd963c28217045f9227e808d1c3c8e8a775728efa0e154e9e0d0eb4e9550c47ae7f8f4b2b53326a585e729cd97351ca66ea5b30dde8598d5219c33cc3bf744a776ea610f2ee05d348bab3321e908fc37e55ead6976e2c72bf5bcd8764f691bb21bd6b413861ef631e99ddfd41cea7affec75ddf5e8d357ead4db1a3527fe5394ccef13c1e6d99d8794ee43096fd420934a45a4a3454ce16e4cf114c4d377eea7b3910723e8c5192ebea046e229b91de7137c49a64135def88a4c836ac4cf9d3d861dae2bff8d5f3dd82e8032739fe1025445f647743df995ba9e6ae1a59ac61ff546bf6ce77d15770c73f2c657dbc64b9feb10286a438a3efb6e743d4adec25547d50af8da7809972e14fb8c64e8cf9c5ed8d37455eb4742c84ae94b2649e38eb7168a97e8e557e888c97fa58ef82248692e5f1bd65cf91235ab89db700c3dae29bedcd5147d6ad4c55730481fc8a5ff0a9dbf3a20e443bbfdd9ffa0abf81546e70519affc5f91a3473ed751dbbe4e577c9206f8be54009faad3bddfabd2c9c755ba5f5d956e7764cad385df0a26eeb5bd71267c4fcd61b0dcad8230c3d5df82c9e7528ae4aa90ccf7944cf320a41cd923f010e620f32efda2ab8f24f669951cd420737462fef9b23ac4ad7699ecd785563ed713b4e8ea28456f7c0493f4e1a37b18d720cd6192b18d9acb9ad7b679d24150a95b2fca25882a2532d14aa454cc953ca24072abf2fceca32f698b7f984ca5a6f5644a1932b5dbbea293926815199246125417112fc67442e417543dd5efbf54b9ba2ae7ae65d80d26082720ab84fbfa07bdd38176778e24769509430006e7364d0bbfbe4f4a6442d3575c8a84e5755d60ec1d7a13d0074a389802759da00fda8074ce9c52d710ec382ef0acbe5c4fb797eb2bb55c5fd9e5fa2a601a1b2be1663bcbf655b5b05ced1ed1ccbfeefc28d53276497ef673dcc74975df882f4912ace875e3a9af331f1b6ef4e63e8ae19863bd9e9b485b3764553bbdb5bcf3b37fa5e75597e13edeeebd4243543419cbc9f96cef865b2d017ceb5ddc68ba6fd116189a8de506c553304cdc68bf22768db97c7c8db91c2f27a68a2536f8c597eec273f3a5b384b90f035f8ab1fd5d03d1c9f7cb304bc3107387838c5c46e7f604e4991c7178c832853b124b64890532cf4dd50e7aba7fd36f695676b894665fdeea3fb9b7a5ccdc1ecc76dbaf58c1747942848b70e3d61a5979bb6890b78b47e4ed02e4ed94f27fc91ac45ec9b8a5b2f08cf4db6d79b1cdc54d227be7dcd44a6e3cabc9ec46b15b3ee3de91bb9554bd7aaa31a7e32e6cd755d834e35264e9eb99f58aaead95e97fcbcbc3f0c8b142fe032f10f3e477fdcebc7a7598ee7887488df568fab8bda8aaabe9a961f97262db4d51c2af8bcafbcbd3bc43341883e6dab50fafbd31dc7a28efb6d5d32ce06ddbb1d660ae053340abfd40bb16f1f03a73b3e324ebb52a64fcc14cb57dfd0a4f831fe92cc99ade98efd26285f778bdd108797552a96525f684aade83f7126a4e062f966cfaf92abbfbef6b716a5a701a7d0ec426733c0d3e689a92e593fc8529983a076b67e33b7e095f73f3dcb535a749ca66de179d04eab936f6bebb972cf7b0f7f93b0f7b6fd59f7f517f3ea93f1fd49f57df7993f3ca5eb65e29a638d106c13bcfc84cd81e22cf25c9029ee5d774aaf4aa2cc838c394640188fe7cbd0e71a2208ad57b9ede9bfb7342d7ebea1d628e0bd23f2f2eeca3c8f36eb7d0f5a7448c8b09c4424f495aee2942a37fcff094803e739dddfa613f3ac2053a67cfc8b4ddf6fd1931aa8dcf0ea74ad3f93eb96333884b5e1d07057d0f11426676d58bda6d7f4666d5a3aa0829b134ebfa7006e6b53cd44dd1265faffd9c787dcf4df7f9488cfb1307cb587d57473749bbede7e45db1ba6222b8a62267dfa719957eaedaf8ef30b32f9dcb9df48d73b928d47e774e95f878925b2e9096a5449d13162816006f2e205a578405c94c7b722925ac36c1f8379a2633b0c048721396031cc85da73481a5042fc01688ce146be02b2d96df5662f96a6466627c856f1f13cce0d2b694cfc9b6b339830afc328878d82bd100b3228d44f978fcaeee4ace7ab854823d28d73f08605b73aa93626f9e8955cf807808df203f517b8f71daf57a559310189393040e9d5ae03b3849994708996bd2bf39f7df94e520cf1479b3294fd33e9ffb9f350ce47d0658afbb9c9025e6e4f366afe47bbbed2df1166bf936c7da4391a547bcc0c92c5eadd7775bbe24ae31c797edb697e43d43cf7bfd655e52950eaae6f575e2fb4cac5e18e2e079f03d63b32b3afd4cd28082cc9c3fed157cf31bf7c47d5bfe980aa3264fe36b4ff3946864440743b179c5bbd9a7e240734e302cda306f139c6125e4fc841cce1e427cb459aff43ff7f7fe28bebf47a3b53ffe61f936ff2427e89770b41ebf49b38ffffef77793b537fe0f6fd2f1d6df8effe3db49e7dbc305cec8e12f57fe281e7f78fbe2d5f3c9f8e3cb0f934f6b7f147fa0d3649e4cd7e0e09a267cfd42a99c345dbfa2b96482af9fcb9472994c51cb1fc51f25e5332a66eb97f43e4d164bb9fe20d80d4dd2842f50eb53b262aace7f79fb69fdd3a71748b5d7eb4e7e993d1c6dd008fd7275b8c039391cff47affbcbec79efdf27878b2dd260014b079c836c3d355aafedfef0809039dcf41ffe323b0c24cba53657549b74660401c23e236cbd560be24b2a19729e06be84e73abe0e02fe5207cd4138c9dfd177ea975e493fdd5fb3ade840b32a4e1525beb44b4511ac68fe39d79e6bd76bf369ad364a2f357d7c84cebd9f3ebd883d7dcae3fdcbdb4ffa37e02e0d9c92bd106b18b2897d997ad047d6329783fff99f3ebdd0bee63d254ec7cbaef71282a2f948c955fd7d0f9f97faf36dc6e51212ee75c2f7459afecca880b41b9df64356881c1216a654c20ba50ea8a42b9df4914d333ed3496f2d549a26b9937e4bf8a81f838775c515bf679cbd073fadbe1293339f21fc864cd53f9fc9c32c5ee1d92c4efd15c2b3d92c2e82243ce5c14ccfff7c7c3d51c90de9dd93095ec597dd10af5671ea5f76438457ab95055ca91e6bd0cb89ca68cce986d104dfdfc76638efed804508dfdfdfdfc7f77819df7c1346eb7518e1e5324e7dfb85f00ff10dfee1079584f0db7881dfbe8d537f81701e5fe13c8f53ff0ae1344efdb77880f01bf5034e52b282cffcb787a15a61657c7311462383984c564ce3d59fc43b69e104cb7df05103fc60823fed013f6a001f4ef0a77df0c70df02713fcefb118294ef5623ef28025fd520c06e037c2cfd07a3df6bc09d2362b8ea327cf43388bfddb67fd91d7f362afab14253fecf73b40a6799a6542538c5ee5fe2d3a3ceea3aef3fdcdb19a54f8633cf6e412ac213dec71b54c8b993719afbe09fbcf06a37eecab5ffd9efa7b40c23eeaa85f13fcf7f80ebf8bdf6c2ae33e8bdad621af7da0d84a78ebf3e8f3984dcaebd2103b0feb61f5aa0ea7d2caec8891922a5812b95e47e7b6dc853c470cd44256c598a99b33e853824a5aa95965272f78ae593009b3db7e0018523becdc7cc82ab9673fee7dd43d46df9c7407d6c8b36c426e3501c28b97b571b736de5c9bd0c7a5dbb3bfc79b5235a6207c74dbfa27ea894adef6b86280a35336b4740abb0e9f50b465d6616fbd2d76e78e718636d83a4158d6ec3a6a4b3a5c4879ea971757a72b3577f7768b5345af19d91ff1768ce391a70320c70f9bf204d5da0919663ac5bd10d5cd43366639210f663d89bdd96cd65aad56add9aca5e453eb871fe2b76fe33cf770becc040c4becad0e6787f7f71e5eb15952ac4c9a2a84a19087d38c2fca64277d5ea4a94e572217b7eab9d0821abcd85bc66fdfb63e7db24d5489719e43ba6a613bb5f5ef1e4ef24c37a0aaecad56bdd90c12356cd51b03a7932bd86f3f7d6b613200fa494e2b38b5be36c27efbefdf7a98dd5d2782e5da339fd22aa9a6276e199ad608dafa776f83b5d0230f76d189c7dec782ab8d3158627f2ad45ee1efe0aafad3b2f0b0f7bd483cec7da44a167d2cf88cde6b60fde353c172fdebef6cc6edef4fcb42989fdf8b44fff8486521d4cf09ae56ab78ecfd8daa76bf6757aa5a2a3cec3dbf16f05b95fa1be0f6b72255e9c542d5c3ae3decbd0773f177d98d87bd976caa60282fa8b8d77509f3f32d15d3a5ae3249dd4a99aef55e575b80a4fdc8ae2553fb525d7fa67fbdcb6e6ce24b36d53f27b85c34e2b147d53e4a6d9a56ea87faf3dcc3de07f5ef5bf5e3ad37d9e0cad0a5c9014ab131913e30c71233a4bd55d8030981365ff444fba8cdeaf48b96b1aea3a666ebdae5176d676b56ad43bd45d79e854a0f4221dadeab1fd736eb07219e916c67ab02d610784a3c769748c59b73e2312e19a8cf78693ec0c5b78681f4eb7d7e749c3d8b206ed05595a1fddd68298d13c2dbed031dfeb580a0b323194063b18433665a061d14e6fba3a4b2c8f5330b19247c948c7c4aa6782b7f8e624a963125322874fc96f7fcd55d22d76b19d84fd58e92cff0ade4f3d48628240f395413d30d16016777d23a7a3781c1360d8e78f645076ade05b220e1edb6d3ba7e7202cd8e6cf3d38de3729713c774b43c0e0e768222bbfc0f4e7c0a08dea209e3dbf0972eb5d006f3c7a3ee944a850984c60e88139bb3161a1408683ae2c4e95443c5d556acdd56ff2c61459da3d84d838dcd0a6d1ab00eb1ac63e9847bdee9f054eddcd277ceb0f950d8681259e19e423a8f8b6c8c518db0d4a0e7952d11e1445411273c0ea76c4e6476b84a11819a2158aa1f8ac330af6c0a2c938eec8f5822fca0e063860ddf6393c3370a65970abb07b90db73826b2967c8414869be0682ee1b397efdfbecb663ab4253a978490b90e9c74cdc43c132b98273ec70cc5b5e4bb44fadcbca570c8569b6e36dcacc3138490e976145acbefce74d8c088b9286c5bd3972c571f364d744adc389ea35a50cf4ada8077571bf0d5b2063c1ea3a3c40e51a2ab3c3f90edf68158af535d5b4ee7ece37607969b9ae4e606a74c0b1b36d36fa562376ca9c9f319a608efaf79fe68cdb0575015f020e3d5bde62b3ef319ceb64afe41cc31b5de3fe05282bb8cd0202a6064786d64d4bc100df43e57ab403adaa28ae22ff6184956759465ada8dd3d35d0c3ccd07ad9c616a68fb56047d35024de8fe8d3aa51d26d67b6ba72ca4e6dd58ebb262951ba9d66aaf20dfd76963068ce45766b769938c8399335d921ed7894f1a38d5cde02dccf0f07fd72ffbc83585948801da3af4d121bd65fe60b45b07dbd265b668d0d909bdd99b21364ae9102bcd4c1b4038676fbc0615b3a9bbdaaeec5cf99921835beae031839d894e5b35da4ad7497ed765ece9fddb1c712a1f851803e8cd9aebfc09b2ad6786d19d7fe7a1d4da51eadb81a60131a59a92aa5cf7d5ab33c0787d4d649fe0439b1a66890705cfe7695b42ab5b6b854c95a5257dfac5e8ad580cdbaee94ae11be4acfb65baf84ed4e1a9bd5926a0d9602693b89cd9ae23f5a571e0ddeb8663bbefc75dc140ed2d9ba1c00ff8cb528d9a5af0dffe97502649af11230514d347a802c75ff4b1f3d6caedd20c36486afdd50e81b7cbde5a028e1f14188dde156dfb581560966313e088d9e74d0c7a0371df4b11982f8125703547db099fead80ed8f12000621be5458fdf4eeedfb9fde7d7af592f4f175f0ea7fbd563f43f5f3dda7573fbe7ef72f24b21faf5e92818151e947e73260e47acfbd0d781ce9abeddace0d77ced2b99acaf66fa0270ab1a1bc752a4e8858afe97afdbdadde7324a8877ce45cae27752cac9a543b5d72c0f99f7108b57515664ede7625bf1bc7ef473647ce334d37ebd57ccea6b21e054306c6b919611b84c70c626957fc96548dd03db53645e872820498eadbedf2a7312b97aedd3cc26339697a10516ec7e1cafc21a5bfdfbfba938ccf1a42d773ff68806ced6a31741ac0fab5e46bc904959968282d823a88a94834d4f248e9c652e0b3338fb97fd4479b731afc8ba0d74bf270c3440e0f87fdc1c931c20b951a73fff404e19c8984a6c9efac01d38734a333b5f9fddbc7f7efa0b02a2033c13e6565d229385fd0578789bc87b43384b36bd5b924e30a9bc1e910e1056beacf43a26676cea632e67e743444b84cf851270e4e8f5513b7ec6a91c6dc3f1e22fd1bde10bdb21d8e8e54c7b477eb46aaab8a4ed00643b1f841d15ffd7a4b395d30a1a871ea565ca547c3106df04f3249f3f86126e882cf4476ad0a9c21ac765d46aa7ec8b4fe0145fa080ebe74f94861265f262bc6730b3040d5600d4ecfd006bfa1f799c20cacd85f82af723603d82384c1633cc4edf18ffa11dae07f4bd86dfcf089ddc94230803a31e83f9729058a0ccb0eade882a98de107912d045d41250393f926e19fabf4687866d2ebf0d171bf8287f68e4393f0f1b7826a148e23b74168e5c8a400232653cd9a43842f215511357e80b72d2fb23453d43a53c4ce6f164e81e87880b0d67080a047611fe1699e9720b54383adc7500e5c2bc95b33762dd8944a360b5a1f524673d65242324b674cb4cc346965f3d64d7243619ab4fc8b563f3841ad64debacf8a16676cd64aa4a7b15444fa9e4ec1f7f26358d441ffab119966ab55c1d5e47b941216ea91e6abd6a0b1adb6702b13adffb481b817895c1657c1345b1d527e433fd3430e45833cbda6ffd95a65b32265f0f6cc4ce468788c14d1d42847089bd004aff93c83f9abe640b59c7de97968ed9aeed1b5ed6acf330fedc73dda3a663dda7e517a74026fa102eea7fa3154747c0451c802ee4fab2793c6a759dd0373e9849c84e7f262fb5dc3b9ec76edaa5e794b9193f2a59b6825bcc5d18eafb925cddfdf72a5743121eff5a92cc702b5db3e1b8b09d1ded2ca2bc56a915db98ac4c3a6de104395e1a340cf48df9a527ea165a65b06a72faaf9ea7deb960f2ffd60d1af396b92c879bfe8bcbc3021ce55032dda82c7442d9ab768e975cd433bfe8cb69f43fec8e64c303eb57542e8e525cdf9b7b275c5186f199b8c2467b356af9517d74cf8a806a163f097e6ad078e3fbc2a66bb1bcda44a1db158baae8f2c8a4db0ed7679d6d7488d8f0ab516bbbb162c07c1b02a72d962895c32d1ba62b0755373b3220f067f565eb77c8079fe489812a5329599f8c1894e129b7d04c38c172b26e8550a713d6f4522f5ef3eb601c8cdf76683b06cb7adab3ffd105d57fd7e3e6a4c05dac4b53028c878ff29cf5bc1a293f19b76dbbb16d9acd024dcf248eddc5ca0876b7353610f492f4d74f8ea16a37a6bc98325e5b394bdd74edb9b8ecbc1745bbe36ac8b0531e76a9812612ec569cee473ad92800f8105934637b0a9592d35b7c939116a1f6952018573f0132f776bf619182327ed76a2b3eb4d98ecacddce6ad9793d3f6fb7f347f2f599423dbc020f9806250c0eb85c7210ebbac94a9dfbdd98065fbeddd06bfc0b55b1af76a77b0a6f5f6968b79ad5e98b6033416f917b363563b914d9bda95a5f31ee3679eedc563462912fb3229d95dbe5bd772bb5f3135f1a8cb00c7428204164905d83720c3664d769b148788e13b0b45e303e0393b1254b164b09a1c26e93995c82edb3769053eba2f6229a415c005d66bdcee10b8ad57d8d423aa0e1261fcc20e01733cda3dd4c8199c5d9c9d55e4ea1bb52509ecf33b152ecaa56886a170715e8a3a8259d65b716021768bd864c8a99a5c2be817fec96a83ebcf50a76f06af21419cca8a4e77b435dc891397a333300c5b2dec88aadb2e477669bc8f733a76aa8763ab74b37e736ae76c05a271e5982eb47fc30d3e2218f752fd44f252bedefbdf677babc3ef3b647f337ec85de3a1b9993fb08b3cdd68840642d93bf434c4e5cf97c408895d8f0bb7ebf6350fc9fecde9e5b813bb105936fe8154b9fe7ff93dd3b9e9a9f81435cde6ed376fb4058ff7d07e1396bf62ec7825455b35efb0939e883114cd26ed763807d3b168c4e650fa4d9af792f9ab4fe4e054ff8226ea91a5b0647508195fe51f0e4b782b53eb3fba0f5dd7dcb1c80e1965cb29607ed79ad6ba31fb532de626e2549aeb4ec59d07a9e4a263895c90d4bef31e8d82b7aaf0a2a32b468cbdba58da7152055794b2ea96ce971dc42ea5bb4355c0b26b7c6b4e15585be547325ba39cfaea5696bbb058cdb97f24bfe5bafc7932d29bacb66cd27d75a1edb8a48ed0b1caad9fba71da66d600888d4664b8fd95e16f4259a1009b7382ed2ceaad08c2c76c57e29decdadd9b67ca8cd712b206ab4440fd25e06d5696c6a863bdf254baf99c80ddddf32b1608f14c1b2dc08ed251cec8edca13b37f53973de9af527640e0bc3a3331a9d3f914f08dd9254e54625f9c26819a9c0615983b717ea87526ab5b0d51d2a8d56f59771a18ccd678300c1c216553b1b697f6de07525ac179a962bb80851098e6d1f0857b5272b1d75aa721569cfb53dd4cae7a6ac4a54e51fa79616fa8fc3e00c35416806f6b7c583a300edb93eb27a4cc54782584501a433ec1a1252aee04a7971164b9cef9903a80a1323d66bd0116a170ab60d81d66b9f9b2f229a7a07ef578b80fa99b14ca1589122ceb1c139e6d86017279bada9ed6a0f4d0bf7f6bcdcbb549e6baa993d0eec9ccc4cb723fcf4d9c09ac6d060ba67101f1d3f592a873094a019c2402633cbb374d7b2714af90dcd3dac6d4db5c23cc7ba9e5862a825e63899c502db80573a0699bb9d32c1c668fdaa69515fe81b430be9157c8317eec5138c6c16d0009e11ab447f0c9f4077b8ed52754d5090e43fb2df8a44b019ded947c5160eefeca19ab2f29d3c4305f5ad9f0f61cda1b18b4b7d535715b66ce9c05afe5449f060f8fddcafb211d63a3f645f65598ab505d6d6199952d7c1804b1b4da54ce4633696934979cb5bb7134d93590b78aca5aa6bfda7d755d05def3f5b79717d9d266cd692994ae65def3f030f6dcc983bbdde15ca6537d5c0d5af080d891e8c95577cd0c7d7f6dcdcbbcaa4cc56de4677cd9b65c562c90be9595287c3be697ed0ef5b7a1c8425311f364dc86cf1d9a67e74583b32283d539893035c9e1934def5a04dc336f7b1b9b87fa62d7025d9f5847da8391e725f1bd6259fbef0729376e8073e9dd0d6fcc3ff2054b84e98679c5aed063bbcda7f7cf4d554d87ff2f17f0f31d2846b6a34c8e37f94697145c53ff68c586622f93de392a6df5952fc835242d0d93f3805aeb3948ae782d17f682a5c15575769f332f18f42827c4aa5647b2683d2288d1e976f906306c2fdb3b327c71074ee5eb5797cb3f5ca9f79c754d4c3c5b9be2f4274cefd33376054e6b8e735bdf3ba8e8bde40663f5d5f5b7bbcaee3b0b7bad7cbab43e49d27fdbb368236c457f5e892d9e0b1e38ff7abab2c0d64f64124ab4426370c0e36ca0bb0ea8992bd7695eb7589772d7c5765c6609b11e78df78affe37f38cde94b45cb74adeb321d36b24af7370f0f2b6f6d441ad707b17653827c06d1aa2c843d0ef172e85ced40dd5a5dbb4e878b9a5d8d1b384ca240b0593165ce090dc7d6ef0b9e118ea76436cefc024df09cccc6c5642b22e40c432e2e2670ce94238457442ab8eb9de7c29ad0a674523e76ab2e2351f51416b2e10535f225d81b8cfb139c133a0e276e100a865322eccbb4ca14ca3e8a2bf041d16ea7ed76a6a3244170b57131627186dd969a1ec1d55e1a3c1aec5c3e0b47b217c6f088313ca717d2063def855b61cfe144ad169765ccdc68e73887c7ee78cc2768b2f1e7788ad9783541f8925c2b0adc93eb7138d979c7a71d882cb1efa7e08ba498904b9c8e5713728f53b88a606803d670ae3975ed40c3b99fde6ba9e5bb471fe52368746e3c766c5badb8aea5673eab1e8cebecdd33c9a723a238fabce62f848fb87e981b5c257c666ea26b26ccf06c5fdcbb6de9ae08e745b76391654f8b4c142dfd717909571baf395c35a41f39bdce9799fc3ea50b624dc7f6c094e7c336e13b36cf04d3f79df0d464334f384dd3fb070709ee2221369b34b8bccc8b6b78b4f0d2bc374a326eee57140eb32f424cbf04f167568b375f1506b5d960f4fd178d3d5f7c31c8e9dd1703a5fee8402c1a217e7720968d10b70e44d208f1d181f8b511e25707e27323c4bf39106923c44f0ec4aa11e23707823742fccd81c81a21fe5e7bf575626c6c411508b84fe1d517bcfeca212183575f7ed4d78fbece8e761e7d9d548fbe2ac9b4ac96ff2a8e5956f7b468427431b4c1d9bcee4bba314657b5004ab56c68c7934c363c69651b9cbb19e04487a979d87cff65ab85bb8d2ac6d68a24db9a98fb8cadf2ee257042bccb4b0dd93317a7ba40cfebce7de4a3ae7779e9e1acf958a58c5a6f4d1824d9a32c6bd36214b055a2b452b2f4ada515282308cbcdcc4760c9680779d7a0168432584f985eede8d9160f70f73b4e26e6de42378ad9068bfafb831fd99425376cdb1678fb8e1f708487161a5b4b3eb20d03d727f0ebdcf713221021c4cf084523a53124eb75789810121e6671724012d00d3234e2a41ffbbc29709d1c491d7335ec9f0c4e8ec2d36880554d3e5f933e328b9ee99e5add7cd33ae6c6756d8233d5e9dd6d897b4fac3b602d7f3698abfd82739094e9bc1795e9484e7c9f5b1ae7e599b67b3e6f8cb1aa90b98a617738c71931f938e718e36ff37c4d71c2bfa99f3e3c32cdf8f6d31d5839fa07c4f7fb6b1664573913376cf65d2273d4e6484713b0a6800d75aa5a0d47ca4739f269ec645fa5b878e8e5de4db1766ba36ab46359e3d9bd2fadccac1d27137b8f5f26048a1ad0942192bdd6726fb79f821773f1da9d4b7b2dbe1f436d3edfc24d556bc761efbb86b282d176850b267da491dbc7f37eade7a529dc8e931736ee4f6266df3981c99d9efd9a7cbbd3a474b737ad4f14b13b51b040f8a1ba5dc12f329e172b26e262b3c1d73a1032bed45bde7bb57c0d11be81c5ea1ee105f1b91f1d0d10567b6184af60393b45f82d405c217cdbc07cabca6d8eacf9e463586e7cefc7ac904c7808dfed751d61c49e9db1bcee3f627ba296ce9665195dd1266d300f2e8da5379b9183507d5f333e4bf8e28d81b15e24546dc9b45cc57c1e145c7b3f264ec590e06f3d21af9a187167b6d742743434ac166884f9a66e1909e73c8adf0bc97ecc32f996cae9b2e18a13c202c7dea1870b91c2bfd754d015dc6525f9ab3b3a95b189e7bcf993be235c125af57fab333bc6fcd5a834816f9eeec7c18e8269c17efa7bac57ad59daced1d7ad63e268e762dc303ff5490bd6a2fac10cbc0b680301d57ba8e76de91b1fdc98c5bb03e9370057e179718d09dd466b191b732d9eec5e4bbdd97f2d556ef4317f7cabcf95cadb3fa717dc6ef1b736f88e0ea6e6a5594e191e2b84dd9dbe9da98664f6e0a30866c8aa654a216bd8e93fe1bc73ef48dfe1fab0d9017b6cd4f753f4f3172ffa1ed5447766f79f9b8ad66900e4d62cc74d9a2b2915ed9fe0d5a55689cedfaa59276e556d1e7b3f69129715e9fcedea756a13ea7b875ddb27ef0e5939409f5c7568c5f29c2e7458fadb25531a75f98248cdf8f347c4865d32b513ef9d280865d8b06b13360c1f88f59ad567ec8ea5bc42c42e2ae09f7f3f069ff18319dbb8fe46553030bf224ae1dd603b4a71fd1d9ab07d3f3061af6d31f0fbe756a1ebd043d1dc9292b9a6b6586ecaa8153f93870d7ee9466afa583b8ddd72500331c5cb34ed55ef6183b059ac462cde22f1cf63563e4251bf8dab811b78acb2ba4e52e698fdbebc08d951bb0d8588c42fbb5d25617ca55ee1876bc1a4bc8f0ffa1be7d4ecbdcb28465ecf405803bbc80c1e3ba99d38a68e179f765bfc41aed96519a3f7972c8133b2c54038277424008b58589f9338ad24ea14f972b4130d858f3eaa8d45a05503141bf04b7398caf1431902fea35f2d445509a5b994b4cd467eeea7da01058a9fc6a9e841156966cff24cb4d68b4066e8bc4c99ab9dd116da2986f09910f072a35619dd84cc202288e1ca578a2b3fb85cf9ab697297f5fc1dc2c9f5baaea74b843438a85d7253ca716dcf43e512aea898d2bbca583eda69af0eeba7cf15cb003e078464ed760616833903072437ac8cdf734048d16e1786f063674dddbdcc285f6ff176dbf3e0bec79536c9dc2fc58f348cd634069ed79501e3b3ae34a8aa1f256282bc1af3c97aedab7f20c45132f7853331859d98948c2738210f822dd8dd757ce3239f618a25c29fd97d1ed3d275ea073353554992e00f6aa6261b9fe307c667101b556111e7b8c4224e37088ca674dd6013a52ac505a101bb63532507e01ddb8ebc9d9162dc9f40640fe38415e13961849099e335ff603e5225623dc8dc6ad63a529ea7fe9d8dbc432f9e951af6dc6addd9eec0d4a349b1b10cd4dc9a90e9984f30db20fc00f16bf474029e7df127758d3fa648ed5e1c7f8d4093e841360b34253df5126f35ddf55a562ab228b36b4277d4981adb543532a35f5d596572502cb5f3e0ea82cdca0b89abed8855cdc506a2bf9bdb919c64d506bd501f56a3c029c90ccd2c75ea822147edb69226569586d80bda99e2e39b10bdc3a01b4c35dea37cd47030978f729fa2388f8bd16e7505a6284e47a98200c6dd5f816632d4a8e6968cf6dcb9d73e6c08597be8751d3fc33fb8c6b33509c3c9736749ee1fb8f1354b4b618e46727b4192ce82e41431d7e73666147297ef770ecebbc1c0585cae240cd52eebbe775e0b3b93618b91375581d73e7a8059fae3ff9d7b2c7837fda1c89b0e0b5ad246ab6526c8e84f1f7ff0e035bb2ef7a3d6289e52d446b9724a6bb7490d5afaeb0ae63ba5e5ee01f9aa4d5285cd5e6780e59d272f43e396ba1b21448c3c2f1670a1634ed07056e526a3874d9c9c6726ba1d91382b85d61e379ea347d858cd846ec5cb1b14cb8d4fb1abf230847016142225effcaaad2fbbe7aadee797bde4553f20608c04316b7b59a3c1c3261620024b895c0f387ce8c559a5612eca6828a6290f7ba65a0f7bb60a6f82f08c3cec09806ae5a7cfbbef7464d2e6e8763f542a1fd027474847b3730c0414a39771df9c74c3c87891c5dffbc8865cd33f6d9035f565029b392535139b68694e3a30ee66ffd278d7a09edaf387d9d6890edd2381d5a0fefeffafc51f0bb8a3daaf00b8ed959ecaeced23db3e35dfde77eb9b02d16eabe226ee8ec59721f4c009339652aee6a036e6fa6b2eb2d5b920d9e8579f56bac4d6485af540eb83d906954ac6668310167a4976fda37147d5a0b8aec2888d5e86bfb40affbdda907ab7895cea1373dfebfacc3d4f577d8153c3ae873ccc49c35393e056d0eb6b56d99dffc8e658d4a6b4c463af01ca3148fb4a7eb0abc6eeb9c86e453b04174a742ab1c18d4fcd4aecbb370912f3e0ef5b481386df9a8b5d58a5bf83bbe92aa65245df7fab66d477fe6d793a59adf43f6d0194d70925c46fe5cc01006089d247b0d260ed517c55e46fae75d2e857ff271f393a2c8aab8abe14a1ab16ceadd239d8aec6211d8d8321cc49ff9c5fb073deed22a9f67195c6c127d59dcdcebb02b61db668831af6a18fb929690e359726b3d67383023c2ec4fa2561c6d3caa2d9d696e356194501dc09295c02aff6420ace8f6a870f96387f561dab895ea1846aedbbdac63df145ebc940b57810623043b72fb632f2b060b2754df33cb96115175278aea4b2323e75d21302399b7311d076dbdf1b095db25c7a38c319c28f853fb760077d843653b8ae6046e7dd89d8a7832e8976dbbbcab294515e73817d90d8b87d225028839f9229bd968560b820fcfc2069b7b376db2f080f2e2f1548f570a4c57c51faf5d8455362867384b9735c2c4057d2f5900261b64b03890b4c4722ced1a631179ea66d3f2428bbaa0f369a7b3b2a7b168b73b60765aefd326b14dbedbd60060253b4d909dba85131439f97296e84eba24cdd3ce2a8303a330f9ca3b313b4272863e95eaaf60c51a85d1bb7e158b7dd4c36d5841e0eb656eea6c0934087647edf9a6aef4d6acacc699adfb7f435768be62dedf4ae9517faa9323aaf5eae8e3d08ac314f84524bb3f9dc9b186127ab508f1c25737fdb1195afe420da45e8a36ec5e273c574f3c93c51d2274ff894b512d9a2a9607476df5ad2bcf2ddf0add755b576bd6f3db4f1998d06be7b535e77a604f2a3e92518a852fb44abd8c57d6a1efab692bcc5eeaec11b604b66aa13ae172c63892f1dd99f80c70b581ac613b560c3fbb3075b612cf054de292516b3ad2769562054b72ae5894053373183734945fb7ddd326e72013d702f6f879b02823821fdf3e48256e39b203a4e268145968076581aef27384455ac24ac58c5c1decc0daceb8633445a3db4df5e3a9e85105e4d9f0339de29a0252d96ca221043d4a2de80b311930af5f3ac44deac2e593095778e2b00b6d96c9c831516a8ed699071cc826c3e573fe773cc02d539781f2818f860d99603ff74d839f8a756a70576ebc1af79eb260ace82814ab22efa6e6f6f03e3d924c8c44265f953d48afae159550ce22b265785cc44ae207ed4d7443358a805383679fbfa53eb4d32653c67ffd4ea1cfe53b388a82d914c7becda9aa795bdc288598b929899a9f54015e5afd282c5e3e8a88fa3a3531c0d87134cb94c7e2bd8ed32912a6bd8c7d16088a35065fd56d078dc577006f6b782aea848388bc76174a233c26882e9ef4ab6eb8a2df0154b169036c4f07fd49fe0ab24ff0d305040d1290ecf8e27f82a551367dcc77ddc872f3e5db2194d57199f195085515fd509f82b48dd445ab09b244b998cc7e1e0141f0d7014a91a4576cbe371783cc447113e8a26f8aa10e9fd6d96a90aa30887a747381c0c27784a674cea5acf86381c9ee2f0b83fc130ae8215b9d35148cea6594a8150611f87fd211ea8e44cd05463aa804f75129fa7d92d13baf2b0dfc7e1d1198e06273a334fd2cfa6736a241471a62259e5195718f671d4c780c83de5b5219851f1b9a2423838d349162e1c9c55898b2c9d312e54a775878f70189a2c41ef1581ceb0f9df2633a6ebe9c36098b426d0cf4bfa3951159fe1f07480c3fe894e5fd105e392aa01397331ccd2e48699fa4f870a1e1f992299a07c61b8223c2a1bcec4749928dc8703acd8b27fa4d3059bd9da0d640ecc128fa3c10087c33e0ea3c864306a9a0c8f06383c3dc5e1d1c064a971d4943c89f07158610a399a404727f8e40c9fd433d84e862cc46f4596e4302a51ff18477d935372e7d1a9625a203f63d7d709b7a3aff8e244a7e69fefedd08667a119ef6465c6aa3fc4e67f93ca7652b3d9c232dc40d57ba4eb5052ee4a246a928527a77870840747133c4f15db96f35ef197120bfd099e6782e5d2104e31cde04c9728a6cb3ca11ada4cc1054d787e9589ccb0adfe7f8217cb2c97b672c5e156de28a634ed8530a91c2e8d4235ff8678104db0e9b51212fa7f9564b9333a8592eafb9ea56976ab7a368059a2886968e3965d669cddcfd8ad23a454579799acc60208a9666fc26709e5c067517f88cf227c16e9d445168f4f86c0d70aee2613f79678a646332fa0151884fe04a7f4064e951487eae468e8245fa545beb4c2408dc150e5dd72cbba911ac748f53865ab8c4f97c97c0eec6e074d0d3ec48d35c24691223c560d99742ba18efa15457406c88d085a301206d2cb41b1e48576d4ffa1ad530f501486d8fc5fa69b097784a3819a70475546630167004e231c9e0d4c7a39ab55ceb199d53aa79cd683082b960e4f2c56e51c0a61cd38369486ac6a5e87a11293c7381c0eea99ac395332965ada1eab550b47253215850c1744d0e115b372bbaf3f0dc67abcb0c68a336e48abd965824bf1e9ccb1151559c6354383ccd3b1016bab713f826a81103adb592b157fe8c452a69e1ee3d3a11e049d735d88eb54d5747482c330c2517866b32a72ab513839c3613828f32a311a466a1980512f73af45c217e5bc553d0d874736d7119b270afd332de375a6969c5ad69f9de1480968d56a32e315a7478ae40a5d95c1a5d29f5746e5d07343a5e7f25e64b9a3754491a247369dd23ce18e32721a4e30a737f4d7cc958a4a5d381940cebd5975d5f4c9d2191cac8fa3e1402b386af86095ab448f4d99097aa506e904874711568a476dcd3b0626d1495aea0c87f8f84c27ea0103d108c37234c1d73465aed81c9ce2086642dfe49929388c70340c71388c74ba43f0f0648875b9539de7d03b5213208cf4c2744dafe93dbd5d26d7561753833198e06b46a7cbeb623eb7d25c5170a8d245a1e5663818e06305594df03335ce2a292dd440a9513d562b4638c1d7d9edac54974ed40c3bd2342d3913d81f882fd8159b4e6999d38f30f473a0b26676f2f4275864f9bdd506f5eaaf350091dd5333a38fb5e007a6c8e96c96325b6070a60641cd834a141901aa4621a77c662b8f8e8e70787c84953e5b4d97a363583b4f4f20315fb234b5627ea8299f278c73a52c1df7f1698495e4cf93f4462d158a56e6ff09de156b8a89dcc9d73fc66766aad7045da4115652b826e3dc745ec92fb334ed4c5c506d27d8918427b008ea0553c22a12c2975ef224530b8eb3dcc86592cb1434e763adde84c7132cb31595996efcec0c9f8413ec30e9f191e682fee9045b4d0ad61458454f27f876c9a834131ee6e9994a73341ab3a6415abeca3ebb1b1245ec6de1ddb749e5143ab2e27a83f7dd6dfa923c983d5bfc00dec3cc17aa7e6eea87c5cd5ec22592db9b3ae3fe5b8ec56442cab0bdd51ef1412caee287e99272ced23c1e6070ea95c79e585c791bbcccd3c6dc659e42eecd9edc1b957bdb5cf3f256d53c5ddd7f76b28fca6c95e16df0ddfdef8da5efee7ff736eaab3137a5aaee74ba6cce9d2e155eeccec90d6deed85bb23b6fb2c19fd9fd6d2666cd302653c1519e27e1713398ceb350d1f011b0680870cbe9a209e7b1b7f4c0bcd55b406dd74a6035c289f05841c1df2bdd36cce1c686558e37d954fc9328fea12899fb749b8512649cc37bb6264fc18e93a653bd5592e7095fb42c68796617b7bc6ea2df8ef9da17eb5754d3d2051a2a8303299d6bce7c0e08d1a754068386d33b5329e5335d716b9a155ce6ad5592eba74bbafaeadca8ac0c7c07942d9edb405335103751c3993bb840dfad94845510b822aa7daf946dd0a3050cf12c78be411b1a88c555b0ccd3dd235008b7c9c6fdc9a1924f94b071a87f26848d23fd332310b17b95705f608a21da824ea17736a520792fb3c76239bc5f90a41f0b42483e92c4a7bd041d163135df51d74f7a42a5242a051e761e757dd1a3e8b040d8975593c7fd8ec483e33e42177d05d725ea0373e267dd1c1d46782c71d8ef777cdd6a3fe61724188e8a433fef66282e0efda897f73284008aab5962c871d34c0ed5219c5544c92ba2141551d28a0419ce7181f08ca4bd126b93366d78cfe3a73d860e8f0f67dd60b871e39bcf469424a41ffb09991da65892a99fa98e4efd1c6141a67e81704608494794881e8f73f33b3c1c74654fc485fa6eb77d4aa2c34197f724c2f4a23fa25d12c6148e4c698f8408e1f1e0b8dfa1408f04fea615556eaf9acc19c7fd09e640076097c81e588f4bd6f2195240a1224ea72483c4e54f8e05421d38a952a32548d87381e95d094cef34302ab15242bf69b0aa4112d520d172902c92d0a01ff678cf65acb0c771d81338ec5184d0a11ff6245aaffb9a4f14b8e8c9a664ba9b2c4b4ccd02b083ac207cacbdc2388e5d6e74f8659ce19c8487fd52da167ab54ee6fece825d20e33745fb3f99113f210c6724d5b4bbce6efd64dc9ff432351811ea3aa9a14a0db75323951aa954743ebbc8e1f1e40c53529467def040d2f44bf5b1f189da989524b8bbff7d0f0bc1f0f06aa444f34805476174d4f12591cf82fe51ff68382af1f56537e80f87e83054ffe0283842b13c0ca3e02c42dd60303c39eef89cf0dd727cb71c2fcb85a7fda1e248b15b4eec9613a69ce188200aa3e38eec0627e130eaa8764ea2a8236c6e3f3c1ba8dc303c83dcb3617fd811156ba7b469c29594d4af06a41a4d41a41abe84c86afeb5c42151532a51ff9c06a7a7032518f921391b06fda313f42ce8f74f4f87c7558f380e0f07283e094e4e4f3abc1b1e1f86e1311e87e1b1a5c05601e11610a600ea85c778a83ac87b02e1086674cf4f48b25b41e25690d80a34059679bac3528d827870dcb78258f5d708e2b00f510ee0f5af9956e38428a152e00427937349a24ed1f339292ed49ad0f1c36e8ee2a29bf78a4e8e3025e65ea09c7a29e99fa71783f3b4db45be2059373c1c747a7eda0bf5fa23ba5d2c942c15bd1e4ec871475c8423d9556cd793a823e20852783ce8888b6824bb3add8f0e073d813ac7b1c4749c4e00c7e4dc9d618a148d6b922b7da1f3a2ec3ca684e3c45d8c837e75cbc63bc4171d12a10b128e441cf504a61d92a8af248e7a49b972eae78851871efa4997a238eaf0435f74394218fe398c94dc360376d33c607a988efb7b110524e76996095fa26f8e151ff76a693803aa888e92cc4ac7a8be3aa06138df7ed84b103acf6f13395d422795e0470f539ab3563f36ac207081b3c93924863631c7a24c8c6c6286052e4ce2a04accb130894736b1c0599938ac1aca703ed95802edd5b4606dea4f40b93234ca2a1ae5ae4ae10ea4207ed44b5027c39c249d1c8ff5daedeba9ee4b939dc340cb38aaad58e2904466b2dd5e7d69b229ada59a706985e6ac42734ad2eecc927e0a7a457a48a6787648a64a4f3956334ebae37ddc2910c2fd03e2876d89e0ea3654628392b42b3abecf49d89ba15e8ad4b6d75e2d02858f6333a209e1382314e7243dbf128c7eb6a39a10b0eed9ce88e284a42683ba190393a1aae26ec691a92addce189ac65506358be218e6afdad37732f89b0385959ef2d8f450e4db373fd878a0059ad3821f561a6588a5faa6a84b11c2bbb9fcd15c51e502a677f7bf3fc60b15ba8dac5a4a18d20bce8e4fcf3ab41b06a727c3d34ed20dfa47a1a28a206ac93ce9d06e2f88fa474af207fde14927c352b1ec20888efac72a370c868393a893747bc1d1d9e9712783556b100efaa72358763be55222957e191ca19e4a8e6119ee283590ef2dc11b4aa82d8fd85b42349410580f87a33d9653b58f25c2a1253a6f84e00e8468841000510e4db356b0570d6f71ad06884a0d50447e440d90eea22ceb6a80a1e713f4864a0d904a64475a21f81a3d427739a57bd446871bcfa5e6c461bfdf55928f76c36304756041784f6b92fdbe7954e3e03d407607ab3b3e28f7af1aad41b5603aea4b12fbbc67903c04a4b12459999dc5bedcca16242fb3f3d8175bd963d931c38179478f56c78e56498474cbd384bbcf317b1cb3bfa9ec53d4660eba4325e5914fb14087d121a47c785ddf348fb9de26e4bf09e98b8ee8d20e4558ef5ed2e9b299edeacd97af54b530508d471dd398aa5fe88f69065e10cd57aeb68295ceab8fbf9ec4e03821219c3dd9e73ca3ea55683889cbadbcda7e4613ab0cfa86014456f0999f1c0efbc846be6a0dfae6e466d0effa0e9450fb10747111ad9d446e124337514262c93511212469b7fdac4b148d33ab0534f4d2ea7b0e15fc52a782f06de368825c3245c3a7d1a91a163095e4a0d1c98bd351781ccb67d1d1e9281a84b1d3095ff64ed1617474d2898e50371a447178dc1d1c77b6fbd919a26e2d95dbd46dda758680b9eed6be55f09bb0d4d8e57a7da2fe299f793d1b5a5e0d86088f259187613f1876946e27b19c189ba440ad6dddfffdbf7d55a01c8631e8161d0ed0be7cf62c6c87ee67547e4e2c96d17017cd64eeb367241a4416e3b0dff1594f25744f6d5312d0d9b83e725aac47940075b41e76383846871a7d27d9e7847da372ca4cfecdb1fe559dc2b0bb06e2f9be1f0d876d87ee8a0f9062cf63d46dc80c21f3147577b3a20942289099f1e41a1e6fb9ccb5de5ffbf09f670c00c1e9abb501ec4ae07476b76facebd5c3d1a97f38a6bd79bf77367938deaccbdf83cda139fcb5dc60f765c68e42c9ff816296717f52997972c2e1cd9ff43d0fed0d96c6baf05cfed72ce10acedafa43e8e2d76031121e975c249e3d0b8fdb7038f1ecd969db5cdcb4453534d3c51f3889723769b5432e4c917bbe5a3b2d53793949aa735549f20bd21ff5e1d0948ff47169fecd317c8b51d4f5698fa3c33c3eeac2befc30ef1e6179488ef5899f2fbf21a1de15e4e6c8f4221c65877ed8cb51dcaf76e48d7dacf4405ea9ad8284f06edf2c468270b5cf8e3ab2c363f517b672e802ce1e89cf7bc1b023e0f04c2084c720c6142202fed27287f93508c80e77506889aab12fb6345d3ca6ac0ff66d66ad00b32f6c413714d8f93bb1477bf67c0167447e13768e714eb26f425c90b097db2d94231b32546e6193717f42429c8cc309c971328e26a4bfb5f351108586081b20220dd1af41e45b7b2107a2d010e1d6a64841e41aa25f87b03b35175503529487870458a0d4a079474177a955973baa54ed33529fe5f8ec3b1129394176edb074e04c168b8a17f8b33e6c36e521dfe501eeb4d1b05d6fe236dd42371876e44e33c0f8aa293fea7014f3672418aad4d060e04766323c8ac99ed3f7bdbdb562abac118e9bb0c9e7d5beff8b332aec39738af7e41f9c537003b9e79478ac8f8886c3815ef7a075f733723e2b6551d5b8b736c53650065ba95b7e46ce27d4b610f4fe51d4543734267b3eaa6a14cf943f6f9a6a54135f9575cadc3636ad9fc3d641772e3cdc55710b765b69775942c99eaafd46ada241a5b0dd855b365f1afd42822a21ff98d6507a0ee8723bb00aa726c40185ae1a4e6076743880718413c80d72cc344583037fd71aef61834bdb07f044cf75fc5e637ea6edcd04d89bb1b11cd3c9843ccc121d5b21ee85f89a0ac6a5b618ad2c177c55c998e92363396693c0965113c65a16a0ca584204d7d9b58f7052c7654c276ae94f2c3a39e99fe717d9796e23cb172419e713ac6f7ace7b2121242ddb6ab7fdea8328e4cbaf6e88d340e34e281641c1f36532977e819c8886251169edb1896b9061617de673e4fa61487491f26d09190319749398a93d1b77932663060b6095722ec759f91b55283ac98a5e149ea664553dd9042708aaaa8a9746b2d38cdf309127192702271bae980c733553e1ef8dfa7bab52d4e4c23cb8bbff1d73357bd4dfe95265b33bcced5517e6662b637e4443f56b395d60ed5b9f610e2c6c76930f9bf33aab3507b6cdc66ca218b3f9065fe5365cf97370df6f52f75effebc25bd7ff5054a76d9aeca02a132ea1af9a1e36a5fb161bbe0167843ec2a5749c4fce6d10fc716107061e16151392f8059615eb71b09fd98a0fb14baad2580ecc8154d7c67cd220bd5cc3e7d228dd71b7d4683924772d871a0c8750e944c797b5181d95732f54cd01de2456d424774f2260d2976a83152a5ec5b95ec25b6a6e4b979b99f301bed404c2862281a04d1e601bccc1adc36119fb7f8a269881a7ba3f8ebab62b3fd736ad192efeb21dfacb76e82fdba1bf6c87feb21dfacb76e82fdba1bf6c87feb21dfacb76e82fdba1bf6c87feb21dfa0adba114fc16fdb8b8a231c4cbff214f690c31f07f5c5cc5bb1bc499e3c402028b6a9fbc7d3cd011ab7ec8d38652d32f95babd8ae7eac7f3f47a49bfd4ec7aedeb2a11fc9aab5f23391e4cac771bbc6477264665a36594ac7c35cb767b00de52f58e762463361e4cb0f7cf5ef75edf92c2bfa1f9379aa0ae2f9f917ebb2d2fc2d1bdfb0e201a0e3b12a1d8f3d0068bc5d5a3185c84ebb56aa9dd567f2fc2d112f2c13ecaf7ba7092e9e196a78f33cdaf68d2f59007955353fb52c9a629e3b2b1b564eeefb4648f3856da3d903ea9d83ec735e7a6080bb275315c6551b275315c66d93dbeee0bef7adf28fc85f99776bd6f542f0ce2b6272bbcccd3afa3d9b5a1d9324f1b68f64d4534686f99a7b6ad6bbcbc7d747cb63c8d57013dc783c948fd894384bde56dd358b9ed7a5ddf65b5f0009c7b2a00a9f8440fa7350c6bb882be193367ae8061953d4c9dd9570765303a73dac04908ae43cdbdf97ffcb33fa6bdf9f3def7fac61c1f6dd0ff7398a8f1f33c6d57f040892f88505c3e1e4cb67cde947e9812f03d974caa0b70314e265df5072ec2295cac3b3c51c2d12e5510257f1caa3f1b700da4dadf8bebf1a6f6196dd00850d7a78f94887134c11a71fc65640d21a34e82a34ed28dd097b07e22ce6a368e7ef17fc93bfeb8db9b8c7e9975d12f79077f31c11fc555daf897d92fc104d2d1e817a79b4f19856e3841e75c277d9f6654251e4d9e866ed9f037351c9f92fce73ae08ace6038ecd4b0872e3db54ffe2fb75d74a8cd093d2928cff549b2473453d7eec0fada49942f493156b913fbc06bf318b297befa47ef5e9c677f7cbdee13c247973e577a1c8a43ac1622c2b1dcd4a2bbd6a76a351a4a286d338f3f8a676c81468d846f1e8e2f8dc621d2d1048c81af4354a9886a6f832f2bee978a70b80f0674d8a4db1211e4c022b09533707392fc1d7de773340a634d9dc9c621cafc11a2dc5efd439264f907d620359d1f551860b18185a66c67e5b6636bd8a70298056d9f1ad0941ded64fb522fddeb7588eab85cff9175374f9bfaec2ebc0dbdbedc0aebb0fb9a1a9c2e73c7d3fcfdde47694db7d72d2b362ea291d7574bbc84a77e37ae41fda295f056816ec6c5783199900528608da671ac959878fdd9bc7535d2beb2eb693a2619b863250721b65f053306f8562558e6a9f3fba6fa7d5bc180e17c292331054d3cdc40bc9fdd282b6ce44b920666efa0357013460ee232e63e58fa2bf5cc02aaad4523e0324feb80b7570aae0a4c5702deea1a77eed358bb5de959be240c0562bdae34af40b0d95efc1cb0b456088ec238cbf3bd183bc037b5a230080dc56eb68bddd68ac19eaeb9c55b175935418269bbed7edd53aedd89bbc5c0e901960821147376dbba2a9d5a6eceafaa2b3bf260fc7037041cae580c361efb2072263f5ed3293374ad2efeb4b3872f960292d64bdd3ca5d4cd56a9db276008c4744b01ef7fb19826a65b4e2caee0f2f311b2152c0fc4e20aa8f014d8659e42df9f067b033dde8175220d68502ba14288500c737bc4e07d9709473136a9131443baa6c9539050707a4bfa74349836cede6e5aefd1bea69a659e365543778e11b6d71733394d1f34bcbf3d7b20d9034ffc3aaa9d608dbb345bee857e6961a6401fc2ece9439727170aa1109c463db94c046596cd4574e4369f7d03861c17fdd1e0b8df65b1e953ad3298821aeb9cca42685ff84f41034a6ad44ba1f9f482d15693374f2c7a63db2cc5e6d30ade3a74a6d3cf5f575023abdfc83c194d5d082ea69e52460b1a3d12f6f2e4e9e574d7cc29e0d38b451545bea2d440f3deee795b59300dca5c7f4b28369f933925cbdced927867f6a2dab1d89ecae857d4b6e75ccda9b006f1a43a1b4eb85c3ad95c7f6b41d857d763bdadb29f56dbee79985bd96dd3382c6f9b7bb9739ee5d464f29e3a9eef8ad515138f2e06aa78b9208cfb938b8bf078ad36041717a76bb51bd8e0b458253ccb1379df146060a7362cc9d87a21b707c31079c1bc2c6363ae7d4f80bb6d714182fee02c3a1d19ff0ef1634e20cc6b36e3fb416d60b4fb07b5b7341e2024e03ccdb81434970d87e1806ed5271f41b44b37a1dc903ce323edf9021d6a4f162836ff1e9af40d4ed90d6b3ab42fe3a62b34dcf3f767e4240847def3e7cfbd583e2347c1507d78b1e76de081c85387cb8fcece3ab0891b9e9e74600f1786471dfd763764838b303a350bca2e2f1d409daa398827cd16b50895eee88e275892feb9bc189c4bfd6217bc28f4b6901acbca16ae69a760564c83d0d69aee50ac9a6865756a4b0ace373a0cefd94a98ba557fbeb6eaded3aa36eb2bfb9aca43c03b7c02deec8f55df7b5af57a81ff52d5b7574fc35c6fa54cd5b0e07d5ddd8f8d66adee8560f7f994a6ec8b33024b120cf45c0886677a2e0461d8a959683671a53129b42d4e5346852b301b7b0302765fb546e9953dd929593ebba6bf15ff35d5769d6a45269fc43198131f642543df0c8efbd548f427841b9596c7fc0b4cb44aee1a43d83237a4b41c05c358624aa28ee88538d1a800f23eea71fb0b67c4f7692721a4178e68ecd36e820efdb04b3b0942dd101d463827a1638007215116577ed631d151663eeae61dae7f61930c9b0593617edb2cb5253039fa2732b8b8087644b744b1a3cd6d3658667ffbf8feddbe5d9c424ae9a669c677d914838f0476dbbac2c21d1408986bf662354f7f02895d377fb003816b226f6c8282c01e6fe21138ad79d894676bfad530436844c7c98494975f282e8b6a9500ca4a03154f339e67290b9876c457f03278c6344b33d1d2eaba92e1ce23ea0dbeaa8580a0d3f2d8cc136ce6610f86c0c39e22b8674ed1bc65c13cec55bb150f7be59ec733c76b4d40808367cedc0c40b9718146cc5ec4b367719eda3078d8335b000f7b5aa9b7c0dea4de8515bd2b7b507b2a00880f8ef513d8b06f0f01eb290aad5a8a46c27c96c9f5261776b2edb10d7079064c04c0faadd2aa04bc752f63950a34016b8fb198b8271652f374bbedf380da2f84f9d60836e052ce72f006e1626366b61e769ce92fa0202e48085703ced96a1f1b01460861a820f2dc5e439556cd14c29697b7b5b68b0817aa4be66b5296ab4efdc64ea8d689265e83ee498d258303ced1e4bc50e4d834549a28f8fe6462bdbe25d6f2e8d1bad3319f984a557737e0b7137e12c7e788e31ea6149cc5c800c60542356a197d2ddcd7ba68acdad82960831b42f6977b6f28aa002d33257e12343bd0c1eae9783621b92a319bf8aa6439f30ffa3b6c03e77bcd2149c7fd9213ab0039faeca8e47d9fa1d8f738c825c7c6032e961fb18d90086daf580cf3f2ac690b47b3efde0a2b551abb549cadc6791763319693d807ef0e633959af7df50fd959321916a8c4c02ba3b655d17d7410b22a62d90b255fc9953e547e8b6fc915be230f3ccbaeddc564838b6416fb6f491fef2e436fbbdd0dc249feae48d3f7e227d566d30184b643611b6cc237c75bde176ab19ddbed7aa867662f790ffae7b5084e158db79720fb88655c5e36a8d9adc319f7f1096ab7bd6a152b737ac74861a86bdfd70dcda3e58aa681a19e2f62a52aff3ee1896c3a7dda6542b65ed7ae91f4e289da6d5b8b5f9e66bd172f8d59f6e32f62d848c6cc94792e5f4348e8c6a2ce55db5d506fc2bf734666a47664b162fd0d2ee3556d5794cc7d45329becf4102853ba0231e19738966883199d2eb76a2a43c2e104674acabb98a064ee27e55b302c907e6692f4c273fa8cf4cf69af87a41e098ed9984e304555842b6dbf9580fd56339469ce44ce6408e917077e56b39b6308d54dc276aaccc67432c1ea2fda60aa907ff55b41d3bc49bdd50edae0c9035baf0fe47acd2a87c6e5e2b52da3e1019195d117c2c660a370f68175a0314c5dce32d32ed949d34e9eef02074f9fe2a49c9061b97ad10342920a954a5c6f29a77abedfed4eee16035f1e773ab02b3adfa1b7a3993c6c30df223b6e30c6eb762992630e36bea65e9fe9efea40a40af2852f574c2c6a3ba57a2042a5dd80992b9b9c3bb851d46e3b9f091add0550932215162856e54a04125436f47abe3355acf9239b28357dab21516f88960dbd9efb025314ef388e65f0cad26d9eaa5d05146a6edbf108580d924423198fe504a7a4285fd70063b8036409097c28880f2f6c1e3648e328d6ebbbc074dc8c500a23a4f43052a8a9e65427f5fcca495fedd6922ddb543bc7c028b5dbcd91f0c16a5a77c4893767a8d32c15ed28a9520f66e84b145fcf374a08dd49c66726987d40f33c59f02a62a6b33254758d278d369438446523db8487015283bd516d267cc94422f33d5b6bcc9b03b5a96d9414c554660282b539df4ddbc7e698d64ac77780ed29a2ad8894d6ab2de15c403b6b1ee64ebada7c0acc034d45c54fa66b982946d6c9be53029e700497977971cdc4e565bde20dbe9cb16bc1a654d66ef2ca39eabcd5b47bca5b2ab8cfbadfc62defdb2eef7eebb592bc55d512b43e40e83c087ce97ddb1500c173c9e8ec5bb4d9e037e4eefc0e46f2858d6f7857460b54fc0a2be87c47b13344da56200db8d107007483ef4a65b45c62c9f69aeb006d2fdb16763b1d54a5cfe4214d38a3a2f176512db2397bcdffb5a08d57a3ac6340de17720f4c8f81a32c64abda0fe9b343120cd145380a861dd661712f1876fc9eada0179675bc28ae92e91e7c1c8cf681f9ac4742a440bba183d67ef03a5e1d162bc4542d91aea5eaddbf1654342a86ac53c76d1f60cfafb0eb30a7cf8f94d945d012afc2b1e38ec1bf16097f0ccb1a9ecda02e965b74dc5f6417cd1d5a6ed1f363c21b2f628d13d36996fbace31b3f8387114225e2fb4a968e079bca01fe7b4a0241cb564dd10e73f9f2d5dd75d6d4a656acfbd5d55184b5ffb8d041785fe1100a87b1e9b22ede0bfb1de622fda5a66d2db54168c207c623da6eabd763158d5e24a279f63d23e188c53dbf722619f6984b2235cbf61476cb58e6723bb8a75cd59f6a7cea2dc7dbe996d950d719b994e6726bf61b477fc1493f1c9e62ad3687e7fbe8cad76b9f936080b0b80847be202196841f1ea158fde397ce309171caa958303c1408f7c4ee389010a1ca45a6cfb4aff0b28a43eef2cdff39d46b986b967c1ceb6e4d9efd61cc2342ccb83be81f0dbf1a7f76118efe10f53bbd6018eff4fe694583a14385efb6df63d4fa7fee8865df975d35277ab21afa27952e25b5ada12b514d5e3fb1163bcf343261d7971d1206c3688834569d605897e53b40aae14ab47f97157cba47b87f0e6c0f01484d66a7d77b0bb28bf0300a4e86a39360781c6925825d44b534204730843485537032543026c5858a82c8013b1b9c0ce35aee712dfbf468703274a9fa0896c150495fdd494b083fea309055db7d8f400de806c3cd067f220f6c3e675399c79f37e76f1464c217af7412f90c1addcfc4badd7d497e3e0c4ffbf823893a3fe3f7e4e7c308bf223f1f1ee10f2ae570807f250f70a75843930553a936838c8a1fd54e0b5c8b05b7c94c2e310b962c592c150fc2192d9bfd583f09c3a5d778d8c69771b4cb93df04d3c3088bc308e19cc86e860bc2bb194e89ec8a5e86678477692f3b67c12abb619f325fe202e1fc226db78b8bd9c8670115533fc705ce70ef67dc7b8fb04e4a75d27bdcaf526638c37d5c82e490f01eff8c509c5fa4aa32d3488ef94e3d4eb14217ebbe47286ec2a25f6fa10f2d6cc1fcac60a66996b30f542e7df555f6901bbb171608d8da6a12a20d9e097afb21abab532e8581b66a2b8e5567a7c44fd6eb3eeabc840b8e767be725b56cb7fdf260f2874f6fdfbc5ed1057b9532b5b9d317761991d55b7884d6eb1afc0bca6f68ee16c89ce3999cde30e81958e9a454323875c02cd077c1fe54fd569d82767d897b5233d661a47e6ade3a8cb049c53609e99b08459f5c6682f926249835b858aff905e923f4607c67b2e08a2d126e28ed440fd083a2a8c7711f7fdc1a13c7c5a5274542f922655e5c0e94e896927d8a3a1cd34a0955df084fbbe4036681da50fd3780ef455531cd8f7a367a714a78cf9f9160181e7778e9d21c6ae9be429d1417a46a47a718a2f4724c7b85e2a3decf785acd2cd12d30ede590f11e4fabe41cd32ec0e369b782ee15987601bafb1e4fbbdb7cbf8db817ab914cd083899cf5f15f7ffc145e461d8ecd6c10bd14d35e8aa30efc6f2ad84cbbe495db7de9c56e5f1505dd9e22a8d00ea4ee2a72890f7daca540f7dc14ddb347fa3315599e032a157690f627712b31291971075b839b8b4d2ea9f8ffac61c5ccaff0ff815eaaacff925eba95ce68be7427be1662f5895ab645eb13176d58304fd21404612e45f699f968b3c197490ea2fc357f2e186d3e7064c1dd3319a46c2e7b21eb1db7db2cb8bb90815032b06b53ee9f29097d5d42dc5fc8e02a93325b01c8064fd3e4baa10d473ebbd2d12e3ad02c86aab169b25726eafa7b90ab274072eda30d2e784363aaa952506fb026dbde33731ee4925d5fb3d99b843308cea82d3d57c96c9632b5c4500d9a105f06775d1edca1c3e8bc1c8e048b110fee6319dc3b83a45265701ff3e05e2fae1e9d4bb83b23b4dd3e10ebb549388004312a4bcae00eab527199c2833bac6a3fafa59435b7782019cf938c8f14657f4f98785108cd3823a9df5866298cfd07c16e92acc8ff575c4f7fc7eee4ffc2fba07f6e80fe197abd5347cc9bdb6b84fe790ff4cf9837d2007abcc12fc8afe76fb47e487ed5ffe237b0aaff58a984b076923a4fb85cf76be0e88fe6a8f957f79c1974d9e7e4e132677bee2cdf981375b94cf2319bacd7f61779d8a8457fb3397f1ea8e2beb748b32b9a7ad8ea0170af1d6bdb4863131784c8c326fbfb8c5b907f3e3e3eaea57f4f57497a1f7bdffec0d21b2693296dbd6305fb16b7aa14f5f15c2434fdf6ff65ef5fb8db36b24451f8af4838690eca2c42947ba6d739a0cbfcfce874dc63279ed8e94e86cda355228b1212b0c0148a322912fffd5bb5eb0d80b29cceb977ee59d3bd6211f57eeedaef8dcf6acaeb51cd44b18a9af950dcb3fcf2699424f725cb135e89b51aabc951b7e21b4082f2cbec29ae6fab4f2aa9cecfc7c673e737e405fe96bc6d3384bf26075905b5fb1420d2241932e783ff7fa7baef63fa8fe5309de6ffc8feb11ca2294a37bb235b1fff00f6f91af3e2c7a31d2821847b33ecb3cbece913697d983332e4b3a773cc677f9c6b17e6c96697e44e0e04297f487206716a9c1bda27acc1b27a4f97cbd8854314fd65e28e4120629aa6920c998252c7e31873f51b2099fa12ea4b0332f549d5a7026f0a65ce25e1441095a6f20eb2dae41243d59c635d29175815cf29d648692e8702039e9ad32157105e5b0657bc4fadfb9b4c1f42ccc9b729cb56e60c60f0d71a9e0a840539acf429b325f5a18bcbea3404e0d56cf1dbacdaa85eeb2cdcf954b5e24bf9567c11a4e89f5a1d498e6b38866e8ceaab35489584f027dd27df9625d6f6a3799204d21f9dd663fa7ace8e47b569814648ca32d53beacbd04b81a6aaa35c1554dd4fcddf61729680ab8d94657a4053fbc365e9b687c96677960c6d7be02d553458b0ba2aefdaa2ce488f00d7e45c07e1a404025f59d9227d5658f9a4374fad089bd1390a4d5665af6a433518a415a952a990f4f34b43e2a8f27c3078eb24ab15d2e5667cde2ee7492f31189cd783412ab2055ddc327a5d32285a350d7e430e572bba909550fbdb7399c86c6e1dc100879469b52b492e27f299d05af57f90848c41436fb3ad6fd598cd2f76215110908e90747c14683030d94215ac2b214377c721c233920d42c613366f7059dd5c1a3e39fc8c45a9fa26d9dcd4721bdf7ef797cbf19f71e4e7437a212f213eacd3e5187334e5b96c1afc3d793379abbb216ff45f80a7f7e42dfe3bf9885f9257f86fe46bfc03f91effaa1d29c9f2c5926e648f84d67636ed9be621504de6610092a11cf106d74cfe1dc0483857491410643bf9a22c6efa0ccb9205e306a36153962700acf457a2e05462931abc7b5f6edbea23c1060058fbba126fa5385da8698051918773892485bdb378780aaada43631b3e666c4dd3e0ea8e09512cd947b693af0b85cfc6b68d81becc242925607dea560a59c2cfe331156496826362e07068e882b21b26ad001d64ab69b2b4cd27ea6807f9ef45518942eea3227375fc7d99300f4b9c14eb4d2524e53251a8eb46b0bb68064480552a60d2a7a6e63d1874aa4f4208949a00e33de5703cebd3039e8de718dc6428dceade701fc9dff1bda94f5ee27bfb0491bfe17b8558dc921ff07d2664497e85dbf5d7e845b8b7327e5033b066ab052f6441cbe29e9d504298b87a7f0d14000e57ea8f31a2c7be91bcadb0705b2c978c93f3cb066f8abb4af61b70783be4abbb827d3a1e53f38bb8de0f0d66d9d5ba5ab212a91dbc523437681fa9cb2b28af8b13db651435a4a90d0108746d4cd54fd58f5366d7aea5d834a5c763eab201cd157074a5ef19e1079f32cb2ac42b7cdb0a82103c71b73d4f5c49f8ac22b7a09cd65123aab41a51352725c2690d9ef8d139c41d4faed415ab66e3b9d6f3ebadca54d51ae174699fc712d99732dd12950dfa7bde5305594273e9827c4ab7086955eec1205d914f6969bfd101c6b4cad6c52e5d6081029b533451b44fc1b7ac713a6af799d39cdca2c120f82c91696b3b4ccbd1163d11beba9e77d318bea23ac5284f65cf61e108bbad02c44982054755ca62f3be6a1f96e0f98063ab8f4ab6c3fbe87bdf34f896d67f8b8d961d80bc078c6a7dcd441ab562e6d793a5a83c84ff6ab572ee9d560e5ce0bf90bfe2afc85fdcacc0f3b84603175b21c064966df231e6dbb5fa55e77f1a630d2af224c142fb1586f2157fc18b359850bc17d58d6075ddc97855ad370a70e9781b08ff3bf96ad21fe8e0ab001424d4d6d76513acdeef135632cdc9d809519330d13746fff1c10641855fc29318bfe92e8f30d5e9376df2d48d3a3f2cad85fe25fba35bbe507924c1c1aadd67bcaa3638582e9dd2181af147e2dbae7385f0b15fb7ac36fb46974bb7de0f61c2c65cca35a4f1443b232c3338d91f8b3523afa96419af3ea5eac4dbb9100ef08ad926f80d390757830ae6543d30a79ad1b969dedb1a80b2326411892695c3482f09718d18ef3266966e725f0bba069ed442ed61d937690ba0efb355c197a03195b6a68d3d2e1bf82ff4e36c109a8c2ecdb3dbaa0b81e9162c95f81238e67e212ee1adef19ef89d7496bcc1366273918a4ee37b90fa70ead689532add71f4c40f3ea7425380b4c6fe2ebe286d532450d42a8c14152e731a5cb3bb598a979bb83a99a3012e3cf6d8669a1d7bed74abbda47cf7804a42eb08e2429237456cc91de08b09ab620c8d23726d4a23f9c23e6cf2cba60eea43ee16878a9f0220fd1bc085328387eefb4fc60d91550c3330873235b993d500ecf74b9a883e7844fd35335edbdb63565747430b5e7aac09708e5c361d134f83f88c3c63243e7e2ff24b3445d9804279b6a93e00422eca8bf503fc18909ba93ccbd334ac6228bcaec0a56f8e77a52ac7c44169e95452d1967a2c69408abcaa82831b80c7430107694549d7ee10ec8f198fe674fb01790db69a47526e70d42d8e1b07604a8011f5cb26ddfd342232131c01a250bd1c62595b466d248353f2a1c12ae824aef245ec5a5bfdb18909aa83dbb01e2135887094eae2bb164e215dd00c7c42744d9af296c86fff86eb5aa9974497fad0a1ed7072a2b99eb913c7e18d1976e439d81c2307492792fc61c5a4b01d471d09eeb1d2612ab9de7bf7c58d092d58a8ccfe87269c6a5bfafb4b2afa296de31495394a984066f374b2a19c0d8ee3ba95b67203f308d9f30b476cd62ebd6c0000099817d766dcd5b6f987cad772f458066dbdba18bd968452cdbbdd815f59bd7207fd13fcf0ac0c3cf854d8077ccfc26412a553f593d1bcfb36289b06b72ef9bdcb79bdc074dee5d937bdfe43e68125c2a9b693c887f64ea7c64e6b8d633bfa87368422dd9c3f57d3fb0bcbe013d06d893af2bf1e6b4d724dd8e5edd199b37f8ca2a2943e537273d92f9936256415785a3f2e8aabbb0aaeff5818a7e4a06216e0d37558f613c902f6c2d9c01b426586b1f75517d35d2f33102f70b5254fb6e21b5b7830163a9ffb4d67d0bc1a8646a217a8e4a7077bab0cf91bd8301679fce587ad0c0360fae960582faeafa83d1747a3e65fedf82ad81fb70d5a9fc924ef115fcc95903b884033dfdf6ee2d88d10319606cc7e30c0c6ce003f05c46c6581217c98f3d9393e19069c3600af2273dd668fa2943136e1799b85fbd65a1f370062ff8f27bd6a62142ef2d9dae5a170000807972191e5b6709993e5ca697546286e19c5d6f8b72f99df821cc7d6015c1a0aa05528559bc54ff20b3b99a3fec9c4601521e1c5bf35ba153743030245851ff7907f2d4eb9281e5542a09c70ab943eed99f7a0cc0631d9610c8d37e628ee1c4564af06151f15571b315f4ba64f9f91833be5d33f375693c801d5cdbb942401a844fa029fa814c2aaed622194a6ff21dbb121d5a0b7285fe1085d59ca065c1e2e831436cedce23c3b5c14e05ac35cf2dbfcf180505aaeefae22862619fb1e68c83f7763e376d03d68510a64d038404e002702ea8fa2958bde70b8f2934f8ca4eb9cbb33359e4de487d0f0d9e056f8c7dc9e3e70e100f1dc9213aa9f3939656c9d59a499a181b5ed59af97d6fedbeac598e8236064c7791173f114b175d816466a986f0dd46d686fde36f2398ea9ae60c357f8281d8f2bfe0619942781cec3a61edc81545ed1b06a061176d30703fe3225a11f111d817f3fd731f5155102d3e63be23f713f406523411cff864381448cec4dca4692403a4917d52ab0e2077d03572cb12ed84089caab2a959c02b431bbdee43ec5301168a79ca0848867beab42ae861c08370683043089f6b2f17aba22c07031b11133e8fc754662d8c9dc82cc0d811960d7e7084a7cd820dc306d7a4324fe896547641704914f5598334fcd0e025a9dd2562e64aceaa1efc20802dfa7a41f5856ab99734c22b7268f02d318cc21a9b5279153f1ed1eb5e99a7fdb6ba6322974d60b9bc685b2e53b23066cbd304ca27437a1200530780738a57333a27ff91ceca5931c75bf5cf7256cce7f8d681c355bcf89f5f79fb328205a65e5e40235ad71ff49c14ee6f795a14d8748e454f0c9d85975057efd88294dd2de26d54aa7f7f56c480ded6e6dcaacd59dbcdd134af41b0dc46f10736ca50810dde9083933de7e7a281d813046e0fbe77d2ec95b6daadc818d7646577b27a564f86c30addceb66435abe6b02962b655fbb19de3c56c3b9fe33596781318e4eb365a96bf2b6ff91b365ab41a5d418bddc6cd666cbc185d632c2dd86d7a5c09c6ee597a8b10be5588fcbaba63dfa803d8055af6d5b2d222ccb2af3646dd0a4a0394f1fc8d381338c9275a0ef1c11eaa8f6511da3c07b6984698c10b4000012871a32bc83db8ea565d02189ab487440e2db095d33620c3011853b9fe0b074c0897035f0dee3403db96c1c57ed9ea40f6271769a71134376a13806b8663099b0f4628bb49d06c0099fb9a8449749afcbb55666f2745d582f600eaa8e3646e5ddfdef73fc2ee0d648eeb1a1f4b78ceaf6a77a11f68da5b1a58d67fa71b5c93035cf5ca4603a9ec19a28f795d2b4579604d5aa522bacad45f654b6bd5334ec48ccde7a400883fe38af4e2f349d53e9d75039475805e3e9677d4a104e1c6c0a572e88c0b20229ef1298bc82c81f948a05c3ce766fd0b5e33211d92cbb11871b0e10f935b2f89c5f0b43b2509af9ce1b5b769c3940d55739af278bfad6fbbf36cc7759ef48dab7feea6c688811f60d349ecfca78fe404751e5bfec36db1ea3238da442ac479f7756031f31e9eee29e2563ad581685a0cb7670f66d0ba971f34a7bb33b6561be34e1b201f95ec848094332219168c38bb3fcf49a71127dd08cc5ef09b92c1b1627ca93f2891d9a6d8b1f21d153705c705a11732abb69289efe9b2d8824fb36c876b22b3fda4add04dc5225588445c838f0a2c8605c2322b38b7c9cfe934d5ad0789511b41fa88aa16a0a5f3b1b37152c5548633a7c67ce44dab3b664f4677dcad49c162df260974a8fd2e69f008fa431331357a8c1ac83e7d2243e86954bfff5a159c2400f81385b507154e17bf6677ac047d9ed5b62c5f156251b27a3038290925dced9476650258824d028d76bbad43c1306c3a57cdbb2245f841a21a83416b1841d34322583ccad1087515fad5a618856d60d3fb7d6d0f2dfcc646163ba1cfa22e806ef4a60c86943bdd63ebd4853db4ba7f4c778d5b7d45bdd9a5fccdfddb95fcdc32b99bd859a1f6717603ed48f32d8e9e1fa858e41d84c96a0467a1527a843425ff63b55a2511b6f414075722b73a808d95f3572cd0ccd0ea5009158b0417fc2dbd66e5f710c3f504fe182a1d9d9fcbc1c0a94db29102364fd133972233014b3534588d59b8a7f0b4b57b89a923d38f961ddaa74e688c1396f96b51adc12021e5f8b0cb19dee7b2313c2bd88682886c5968450c5c45b707d7e1e5ac9f551354ab5b03a776429fd7134447fe5be553c85783d812fa9c5483017d466a5c92e239898ec560503c233c3c5d9660d80e0665e33c5ee11b265fc1c6b46c3723cc035641a13d2cbc14cc9f500547556e3082210b7b47174f274e4388653b6f9724d1138ef739cbf6de3649a53530b6d85ca73ba849e892e1fd9b2769ea47350a478b42e37a64bc2cc07989aee053340a72c27bf6143dacffd4b35cd16a9d1e9859bb6018a3a86b74f17418257cf94af6f2c41c834813630bb9c3e1a9c7e1f3c6c3e76d9afdf18ff91853725044f50e83e9120e0698c7202a9859ee3c6c46877324f018e1008bc805f64b9447b7c6ae621e40be0026e781f604cf1685586cd72b26185fb00bc1105000d29a9769d696c6c3798728940660bafc80c2a2e13b60c240fa6792b6de2e191bf90238a7d90ed36c8f697400c39a98066f40bb52b8c034c0c6da6f808cdf00329eb067b4f58831248d1de0e4d4245a4bf907c19aff3293b283c73c449b068382817d3a5525bc915f8370cdc87ddb0669cb48ef2b3779e0ad5468597e30167579f6afb8fd6e6e59f422fe317a325da655bbc893ebad94f6117d4debdb7c36c76d758b7c8c5bea1679b22ed4d38a1774f3128cfa0098d7f9f918ab95c9cfc7eed52d7b5e5db04b3d0523143ea33985ea51d390413d6a01d4a8d451d950fe17baa971adf38a722918371c4c84b7dea8a8245bc71204c4162fc9e8122f54bdb2aa36ea823aeae550ac5293ae2f993ec08e3e5467177ceedd6796aa7e23d93a0505edf37ac6e67ac859fd4bb1190c64f0850e35a9cd0019b2c19b6aef371921bc2095b5e11e0c8cd4ae9e8de74887e8b460a48079bca21be2d82e664b8fc7b295828bac6660cfa4b67430883e1ddb467df8baeacbf6e20f02a959545ea7e2b29364ab0205616bb8d3e3bb7149a6bca645825e343952865faaed104a467ca7e3711b638c450432524e405304f604c1a61c8f69614d99ad1d275e1260bc5cb6379e13bfc15892d125216439ed3909793d5b827983ee015c338f2e0783f3ea7834b53abde6d652c09be99ad3a390fa256168b250bb1702a2c261d8b808210eb04bbb2067710ae4387a73c51e85f7d2eb5ae3bde85988ec165283d287d07dd0aaca0fba52fe47ecb5acf264010f44d2816a0b16c1b1450ce42eb1eb58fdf61877feafb8cd55cc2f1d60baed014c3098e4b158ba5d151e51031ca881a1a706460a5909e903ee576ac8cdf219ea202444182ef88fc1ef9f7e038162376a7f62a3be001d8f90408df6f5a3cc2d0cd92f846b2a9cf31760b83d23c01b6308cbecec58c4326f63a23d6be67050ffbe0822337f2e81e1044e5a8a8ae382d8850cd94cedf726ba5dd2c2012f5f3d1edd6d8f7d1f402456048c8d10cac918ca955aafd000cc254b63fe4df0dec13462f8c9031cb42361556dbba139173b29c7c2d8c8500418cdfab3a064c3e2587c3ea2ad76601384a7652df3655c38691303c3e5c256ba780a64ce6e5400eb79372cacfaf2bae0a93a102cbba6357331fa15e61f24a31cdaf2ce74c2ca3b579987957db2202cdb8f0a9006ed8705c207307a9658569b5cb44da26910df78cfdac69010c483e74c7bd5cf992f7bc77a7d0a1316ef31e9b373d3253efc526c366c0971279cc07f9ab2ecb612c57dc5252da77a4ecf59b6032da2bd425db56d2436b691c0c354859eb16c1f14d2d34b7022ab4d8210e6333927e763cc51ce9b205ad6bd373eafd1341564585be373aa7e3be3f3427d79e3f34a7d3ae373412829884ad3c6e7f95637229e8da7e35c3ce75345bb897c6bdba390419fcba9cc29beceb7aee902720aa852e032df9a5e2a48afa046156cda4d8bf96aac0a24a6f6a70207e7e05e5c0c06140d067094ed021483412a8e47f99c14d0d360209f91428f535d717a3c729527abcd60c055961ee983ec32611d48749966ebf899749fe638e46ee7c2d7d363ead73d0fa2ebed04bade019d2dc8da3da3b042a00113b951d1aa1dde910aa604ee01370ed12cec072a2f3fec72536f9febe29f728e6f73d168ae802f30a459690b0d692655c111cdca11cd84aa30a2991cd1ec1a6c78b5a60c74018a09d0d6843d042fb1ce05677022db6191edb1c83e6191dd22f5831042b34f8381c86ee1e72d28323fe46ca6d38a950ae0d64002e680a9eae9da4f98eaaa40a826ec8ef16ab94c7427064d84e895ed1073a7f85d1a128cd4a37f023d32056f58f0d063d0723bc5607d00a952809fa3e90d4b3966a0288e72f87096811e37eaea57b7c700f59b7e14aab78ab6f6419f458fbcd66ccfe05346c03b0e4979b61f72fd865c3c057d2985f5fb242c09d01d8ea1fb45ac48fd469a07f28947fbb2fdc83c5cb97df1c2dc9dcdfd6771302037de317268f027462a86778c940cbf65e496e15f18b96693772c7b2116e413c3ef58a6684fb2839fb0aae42dfcf69e717ed11ce78f8a8209bc96e39fba248d47375e775f4de0b0898fb7858e2e05f85a2de9e29757d5964b40dc8003a8883abc25f72df71a059a3ea43ec6b22b431a6adb600899d6b6d30b9c3b56d82dbe9cd1f948cee8e8728e50e43de386c98fc5e2973a45ed9684ce7daf06fc752554a994225c11fa7c3cedeb448c384279853911f6a4544d6a2c0eb09d3aca479793c81a365a805490ed139ea9f5bfa9c4febd8efb4a6f18c0c76b2a7c0aca53418a2715a6e412e1c3e276cb7fc9c54585c16a2ca79abf9ad72371f1b4712fdc3515093e6855b6c3ba5ab23c2915ac481aac4d23f203d88ce4b3837e91ec50125c69eed4f918df8862a91dff1c74e25f5cc2f9b869e6781f35a19dba27cdbcd7ced4aa07a9f755e487eed4f3ec7fe268e679f6bfdc23fa8111cedc2bdab6920a8ff93f65a3649ef48ecd52342efdedce7f8293ee6420c8daee655c6c5df09754bc850378c2f6a90d00279c45aefa5b4e0a78e0a100a791bd13d277b2a52faf1301f3160ab9541032b611499155f8c31f191ca4334043122ce38389137d92b2d9ee623f5727216b2f9355b88dd3516fc31e9ef4b61bae63d0ac4fee69b5e77a75dbeedd3bdb434f66a71fde32d9f10b98851bded375741e7ca75172cfb45a07abafe1ced1736db772bc0278afcbab3e152c6d81adf5acb625f365be575fa0d53456d0d1a9fe809ab5443d66206226e75862af866e323a2af23e261970afbd0655a1bfbca66845c4439ad2eac199b0ec4a9f755d39b099a2d6800b3c6bec4f15da07854255476b828aadbe2391ce5947577bb17a507bb1ead15eb41447d5224843c2a38ac859333ac013f322833700c3bfb908953721a99ec979a8395b68b57209aea5ec3ce2ae81625318f955b4817f61d59a49b1378a1415b89a29ee2ad0b7ea2f7ad25923ec7ae115452b423b370ef4cd6f987c496b064f39882aaaaca8bf71a4798a70a9aac2a13d1e6978649784660b5a2eb62595ec2515d0363454a7d4eca9c402e145ab206c7ba76089059a14015b806c71015821e1d33a5fc24f5c643bb29dea845b4697f922d3ba15b8c8f6643bb59fb92f820b83714236784fb3ae67349e4ab6539d90eb6c6d3af84101fd9ed83dfe8ab7df002d2452f78ccac56dc16ffe56807594ba7646730f48597d039d4dabea872d618b8ce6624d6673e3db6b3c91cf2a8861a8ce144ecf2f092185e1dcd7ce789beb66d0f1e8f87a45604361b39d1cc72658ebe073421802886311b0da98755814f594fda45f2a8727fa9a6d93e13695e5eb0247cbfb419af2c02edda385306b31b51633a34b4565db23f91045d4de29615758abb4f6a92cb6745a855db800f1d5aea634818603b35bc721d078ad95e7e7dcf89481fa98f1a54a617ca9bf3d39903bcb5497a4ae2b98b1f206e2f3f5ddbafe1700471e8542c3eb05e9319e4d115e91451b08dc9265acb08ed764f1b8b3be5105c1e3a25eaedb199b3b1889af088f5ffc3d5974aec65d7b83344276e303466fb4907c3ace37eab97e4ec683c14635fc9c8ca7f04367e0eb6e9d4da676a2bf1edd8d5ced828f741befc83a889db60feedc3e602ddf211d3d6d3c11cfde0d062925eb9998237fdfc08e8a1a8c9390bbc1202dfce8d2b2b36e0656fad543660625cca034e31e0c4a339729fcd0193885293c1b0f06c5b3f1f1e8e75b3c1fabb7ea66480aef22b0228bee49bf510f445af7660daf111a55dee9e15520f5d9a267578341ba2557b826d7d0e9f9ea78bc5683594dabd1555e0daf103e006cde6205e8f30a0378afb181e7f570ab68357ce22139f91226ab92ed12053622d4777ae2ae383a1c17602dac88ebe7e3299db1d1e5dc38d124ccf933195daaaca1cdda923efad4f907d38c5aed50b218a5e6bb9e8242f1c86819e7f5a840da2181ca1c0cd29a14c3625429a8558cd2621450d83542174f9f6c2d89eb56bc1e55907111711934f5dba2950d6c12da712016287fcdcc2f1b9e3902e729c37db711694d08d51698756df92f4f0afb0b02b1bb61ffc452d141c82f2fc608db8a3483a13a38aa4fc4a8be78aa4f4535543fcdc9a8b447d4fa94aa5708f2e40990d73653d41605fdee289cbd6661ec259d8ccafad84e213407d621a281778626c5333a190e5d9c0d19dd6d6d853d2be668a24325546aa1d0f1e8bee80e1d8f7c5638a34bd7a977edadbb458f33850b1707cbd8fb59649b76b22d673cecc969a4cd964ed1c6c264f6d17d4e36149f4ef2134bdb07b65504b5686157c51faeb800ea257375b51ef2b7af30ea9294ba7efb58778a41cde0c123fa36844f605c0061098ecf7a7428feccba9e839ccad6f5f6faba646d86565d8004e51447cbb0a3f0c6b25f9d9ca658e6c96e4477453d1a27a7d858413d2dbe53b5f6be9663efd6f9c1fa4faaf3832c649f838e24690cd9d58b4186c67391ed9c26cc8ec7240151cec962dafed73caa0e480f93fc2c4d862cdb0101384c30b823de075f2213c304258de3b4bdff1ca70d98cbbf8b27a03e4b3a971cd56beb9bd824ad6ea1beacea45ec60082756c120999f647478c7982d4687714cc0032f04f01acb161b836381196ad03fc3c688cc22ab871813f5430c89ede7d91fb86cf14c2c0e86978e7fb1207c5a8598d16bb628d6b44cb37f4379d545993a517fca69997f4bbfc5122f1512cea7758b3ccfeb6e2b25140fd83355c085a9d56febe875dbe1bc2c1fc773d93ec873d99eb418dd465c15af18b5f54a3fa1cad536d473b14730df7a7517a3a7c5a76395aaebd7bf149bbc304a2dfab55cb8777385f02e5fe07dbe6a425ecae78c741dd7041e33ff787db9ad6d57441bae9c3cb972b10a8d99b7d5f56970d717c177eaede935b2156947b71bc18b1998d606b5830141cdc08ed6d7d2aa3eed5a7ab03c56f0b1832656b96cc8434394df6ab66fcdee69dbb54d0728507b53e1bb265f86dc44b282ad35bf17bde6f7b4dfe2de3d2c1df3748bdd87b897c2a16abb667f66e9ac701a5e99c0cec7804d141d470346cb4ae7cff156012ff09cfa730f02f18ab920742f1879fae415c3df30f28a5d3c7568c4b2dadedcf2ad8cbd9eea9fec7b0817969f8fb149d0aeb6ce2f1bdc8f7594ec86f1a50dc17c2a640459560b5874e33ac9be19c9b64cf416037a5e91c2f3236a6238b5da67435633f9424a515c6f254b934549eb3ac12c2b96c364a44791206cdd9022c36cc31c1c20470c20cb8a4f05a1ea54a8f1df16e5323d35c8b24810428f2a5a6f284f808cdf97ac73a96128ad44f5e4d433391f0cc4433d7c643bf96db564690d7c027b068d65c2371fdfbdb57b911ff4aae5871bc699a092bdd5df7d70115e7887a8eb8ade93abdb0c93347545d67493b6f0014d9db3b6f3bab1da5f6ac3dd944c3fdb60102f1c3928d94ee61c3b0d94bce8c0d9406151e50660cde92aba74fb3e2d978ce7fae508b046731c66628e8e476a7f1bdfe458bb34134d83503e9b370daef8abb2888e764b5c4fa4c117aa80300dfca6a455cc693b1e6773d4f6a5925252b5978e2364c9c8c120a5f6b7f3a2de4e4193cafa34424d83175b596d652049feb7b17f8547df301cd9c0e42fd8ef8acb1b598ac5c6b120497e960cbf147bf772188ea62927ce0803cdc6f32111391f1281b9c7dcbffd1ce6fe422c42cf96c6e5d3ef81c9074665ff1c5e3f071678c16fba1e3abd0f2a05dbc613fe8c792f055a9455d4e610190e6ecad160301c7aef4c0f4b3bf59156afb202c7fa55768e8c5e084641a66491a8925ce225b9c40b32c62b32c6b7a40830fa35b9d5907d43b659fb3c5e5c8ec7c7e3185fa9bcf028e23d2980ada096e0ef3a944e6138f1ea2db87af6c20cf88e786cf20f2f18be21e9dd90dc3d27afd874f482e577cf46afd8f405cbc7687885af7dacba3b84dff9487577087ff2793708ef7cde0dc26fc9dd33321e0c6e9e93f1f178f39cbc60f81795f60d83c46f98491d7ec3f047953132392393f50ab27e22778490d12b9b361d5de68e87768daf9f6cf027fce9c906e1d7e46394f90ebf7bb2c13bbc53991fc8dbe9a5373d8c2a7e477e09f3c27a9392a41f463fa18ba77849d2ef46afd5af0519a51f8690b822a3f4bba14a6d0c9f1b53cf1717c0ed1268ad40a5a3408a87c82c55140bad8214c963cd11a1bbe0cc83c43c357abb23ada23b8a6aa10b85bfa756997704fabeed224b5c85b67a5ed3da2da522412f9ee2b1c21502033d5f326ae0c94697d4d89761f0c44546556cde9aeab36b2e9fb98afa147fac40f8723c5eaa36b536d18f64f1a48a1d4c989c9fc8aa95739b49d582ba9696696e9ac44534edf600c3e13f69df2d6d56e56e182efad7a578a8cdbd5aa61347a668310af4b9f8727d070d8a009970a04891031614a9693b8c166f49aa15a3875629fae2292e55a2ac3643a70d0db7a1f224e922fc58b5f52a6e091f0cac3774832c1f8fccbcbfd3712efccebc0a415aba72329e2769d532e47dc114a40c5b86b7099a0b6d483727ca8447e42aa0701581e45d6f337c881db98ad88babc49a48eeaa7e5f3d48f45e9d247aaf22742c749f70151a60e35dbe1d527b1df03e2fddd74fa1ddf4d21b4b2f5ab8cb6d6495bd89acb7d7064d31b4d20b3d7b4732a52ba30f22316d6981208b53ec1d0761d2b7ffe93eb0e8256330bef0a728172d8eda4c8e2ee7568fc45905efbda972d8dc701f1f964887248602274de2a323dce3bf71dcf241aa3ddb45fc3e8a0ecc705e67748e354ecdd0f1c8cdd93f1e5331245e031881ff51118c31ba0fa78ca60247e56a4a0e65793e1e0cce6dafd317ccb83cd05d5d48948fb56bede84d398ddf386f7fe348800e111659403bb664e46d0ab258a5cb2eba25915aac549065c791b741e8b13c27c4ab17809c580424920db5ac8763d6603cf1e362ed9150f0698b8ba97a7d42c79bd5c36f34c512a11c94892c18356e12ce09a9c25b0a8c8d58adaa24a94205dbe82b7a9e96a47e5e4eebbc44d36d5e3a6ab5fcff1cabae8f35f7f33fc59afbf937b1e6dab5fa58735acba9fdaeff2ed4432a875ece1a60e5dc732264bbfb3e4308874cfc6c2c227a3d27ce4d20497c89f0d84ceb243af5901a5307c739d567e05eccf1c9bcdedacbae1a39dcdb04d35d51e7c9fecba56f1d799bd73c6f4bdc1eaf89dee07e4baed84e0b5a6d42c15dff941e565f8f56e78b15d9bf66e48327d2bf3c36c1eeb7c726b0610d1a84dff43050bfef91c0e27b95d86b51eb4d44fe1e876a190c988f095b2c7e01640cf8dc82dd3151334c49a0cdb72ef854e6635c448974a7122d93cca8754c8b9c82aa9998d2bc082c0a5fb62d0a2f9e624a605ca0f9f177964a1cf0dcaa4d5e28a4c398968287126b5e5a6814c4c4ddd51f41577f6b1bd5f69865ea98c01012188039f4021a03ba0f307455edfb18c0ec33f17fbd658776f27108833263ebb4233fbfc4bfc9e6e37112f1b604dc1ce91f3a7ca756641b639cd4096e130b93ff0b04b8c1c9627b5d2cde70c9c4a62a01897d572d55b15551962702e074de5f2d81ee30c022376bba4838f6f0250eb3cdd0bccc51677ee325de7d2fb22dd5cb8a6b3fc251e1704c1d3f0f9d827674817b88a08c1d61e88d2214cf8bb0862decc807936c25f88f3055e888d5dd43e7c467e029beb644b523a14170eedc948becca5e30f286a5dbcc7ee1dafdac357f473cc698403cc698a00c03386f6d80ff40f579ab5d98d8f434faf635102eb2abdaf466fa5549bd960a8577f2432af5a505e7e2334e740bd589a1c6acc547d546cd458bfd5159730f58b872305013b55dfaf9da6ada05d22b4d1b684f48e9c9be54db9e3c7c04772566f6fa3353c752d7adcef45464490cbb082fc9d6a94e2cd43cf439c02bf5db2cfb2d71feec2d7abf7e982e010b15d1a797da51b2584e9746c9a20465bee9aaad6411b0cb60017f4a97bab4d7b158043a16ab50c762ddd1b128fb752c76b9c0fb9c6afd853ad25f104e7f81227bd9d756e01b008575afbec4daf3a33a36f90f9238eb9324ce3a22e3acc7af372cadedf9c3b7d35bfb3b1f235c4ba6b04775e3f3f3f3dbc1e0360b9202b0bc0efcbf3c3e7e423738af01421d4fe9b205b114708bfd6f55a735023a43b0a15802a500a72fed9c8029d8c7bd4b30ef1d0ce1caae912e1300225c784054856b45be67e94c44abc7a3afc27ecd55cd45596cc8df580aedab0ffc92a5d2dd32e9ee58cc0847085701ef451ffbdf6a4eb0b7377a8c6fc97852acd28e46bf262d6b32841bfbbd42dff4756548b30996da36a412922d635a4e1b18389fe39a1ff5ac04a6c83652b0d7814a689b2b332bac8c51a385448153b5f78341e1a2ba11b2c8204c715a750749bd02feb3f1f47648aae3719caff45f6f40f36c3ced0148b7c31ae53de9ab618d8c6bd2b39e6ccffeee81f0273dc287db53b4397981fa8405b375c42ddf9a02eaf5f7944bd9f21ed3959980e75f899a6295fa6b01faffdb6c5594928934ed52fbe7ce584e01c3469dc9645df14a567a93aaac1fcf44f7e05d9cb3575b71c7de991ae9360841a18d7cb66d931e4eb6e042cd46f68e1a4a5baed4b69821c76cc2f719673bd9c9a8fc2de69641075bf4de34f52311ae59f0b5d657e8a7b0d0be55e85bb693aa15d57fa70595f993cddc6b45988e82909a62d6f296881ebd4cf72ce5b806e3c6e7e3c1e09ea55bb08d7047483b8cea9f7c792a076b111e3612bd53cbf7d3c9167ec220e0c356de871066cfb6ce4ac30e74f8e040f5dab6bb80d4cf0c502f7c5fcdeec04e8569ea44c5ec0f9c6422dec9e0a216ea0bf80d58475b7176c4deecd862e06ae37c08267be5e0a9e8da31683f3adab314581e6a127c3acea916b932e33107087053023ea6c6b632a7fa7b68297a45b19b82b2da404bb2da8c34e16f087893afbfa6d67c132290a894a1cd6ad436c401aa709f5d044c0321176a46cc2a634741ffef54077df34ff19cdffc269e73bbd6c3eaa0beb473e5ae73c0a3dbaf0f193628e02fd4be26f8a06d220dcb453540cbb786f102ec4cc3ff5c16f5a6a47b504c0cd8a2202a2ba9c8cfc78dc6ac8dee5b5401f871f901dc23bd90ffc94405fc53fc7875c871130a2647d9bf5967dcffad0ff9dffa90ffad0ff97f5e1ff2a40e64ac02f97b2834b64e83d3501c823ea3b523f20a887ffdbf4201f1b1829520d074562c1f1f67ba5def618d44ebfe82b6dd9cd08867455b31493d8c3e1ec7784ba831d7afc96caedd60c09b029f4bc3a3d21eb3ac270ffd96a54089575b2ee1e66eb9154706c1d635702d3a90550e87683b9373a2300c9a5d2daaf5662b198c2a9508972a4fe07a48c424543c6801e7e54c067a77f421ded912188c08d316e371e9fdcc44b33b6942ca8278ee1e37153e7cbbf3835af0941bd53dae11486ed5f4b8c203d144f6abe551ad8a27fb55ce444767741ab57371391e3fe916ca2f759bb1d25e54732463a53db07a8bf912d64b4314cb82b45b89b4e098737c134e873d50e537aac075dcfd9cd682a3c6275b4922f526e0dbeeb4fb41bc20db6c6f7eaf4815c627b8258176db16ba35f15fbe16d55ad7713c0def2a07af417a00974d1dbb0d590fd3484fce5c3de333a2a3d5f6055dedff1995378d6f6e4feabeed1fc4f0f72731fcfd49ddb77d4bf76d89f7f922d2581b47da6c7c7a95df46f1433a2a68d355be0e2289f4e56f3ea305576209a008b0f550c5ac07da9d8ee8e78f644f8ce4b69a996cab994985361925af0025914ec58c0f870d4298ff6e241ea65da78fff2f6a16d17f86c8a3bf85c6a38f522b0adfac07b8f6b1a2c5427ba8d006c5a1bb85c0c258513246466283377b1c9439bb16a70107a17aadd19eb4917a9de91e73a67b2236dd932dd3bd5f593a6b49123c3b8d8a850977e5622c5df0392ed4cb19e8076d0a96e0fb6c51569ca5df64d6ac0e79b5192871e8bc4e638328fe85916f19feaac7efa86d40d025a81e859a0da709e450fd47c77281702909808ec48979bc4fe67fffa755164ea0b15fa2c410e3ae9f5170f8129586ffd655f82fa0abf05f898cf88dba111a7d0a3423004dff9d5514eac7ab269455b521e7e3dfa6a5f0db9414fe9fd145b0fb13497c7b5d5b861b637c1e6ad981519d7458a2c4019ef8055e21e258cb169758823f088334e775663d44ec5dca7ec2ec8e560f7b6a78d047a6450a41978046ba044be4bd22d8cbb8edd125f8acef85ff333e21ec23f3154ba9d32528a765a84bd0eb37e2f1ca021d22d5ea0a704bb006ee89be581580f5a80208af0af0154ba55705e0812a8070aa0050265405e02d519dbbfee2b78b8043101640c2d832aa2bebad1f2debd56c9096542990fd56a4fa32d9af1646565d6164f578996d8521625eafd8b69df779c96d9d46b25b6d2e868bcf492ca36a7b0c0665d81994f54a77551523df7db8172d7674c53badff5f29dcfaea9f126e7df59b845bed5a0f0bb7be7a48b8e5d0f57a4125442e7ca487ae40dff832c18fb7180834901fa8a7f5fc7f070f5d2eef01275ac677d6431603667572a7b49d9ffb78693fc2f913f90786b59bb3fc3dc396a4cabf6538b637f89a819423ff8161273cccffcaf0a660f95f1806ba29ff77866d9f3fb0c6c3c0ff6011639f659ccae28e4da3b01339dc97ef59097916b1808a5e0dfe3f594fec065ce3ad718bf780bad3c4da58175e3f43403406816ccc868aa41c54a0000c07411b2a08da90d684cfe81c0551208f4799d6c100990c8d1266ceab020c3c02db2c3381575205a464b6478301d71e72c1a917e6be5529db3e39bfddaeaf99c8de7ff7e1cdc7377ffbf3d59b6fbf7ef3ed9b8f3fe1e2c14e8b557ace8fc76edfd6a92248cf821829c0e517a9c4159ad4cf2080fe8ccd312535ca6b42081d0c0a376835eac28f9a4b0f244797102acc7a244e7609c2bc93ba4f1c0a1020acde25f7340a7822b21d020b0e3e8dc2a4886c8f9c11877e70eb5f85f4319b6914d1af80d8cc7ed842c648f27f3088e236e199020044ff391e935d32d1c3e232d589088294146af16ab69053380c02e5b07d029f5f6208f1e137a8b062cdf4b3c7375b55e2cf74711bbffda114755640304ce3cd430e06e7320a5e5ae97d9270b82a902dc2f82501b0a90046d1e237f9936c16417b7d7ee878f9a36523612287d49973820558aaba48a997c8824021adf4d3fb84eaa75c4e6ecafe37ed4a7b439e8f411bb2234bd64b1cd2159a6651e71e9ba725e917679a6375700351d01819a589fe2a30523353d460f5deb0faf758112770d74b10ac0ea6a8c1bb87bbc094cce6b820e7970f43371dd12955d77430a06ef7fd0931b1b110acf5f958433d3f96c1e0bc00afcfb339c2b4c16d5ffdbf71583fd9cef7bfcbb09a0617def9ab7ff42a19ede57df6e99689ce80dc93b8a91438950d0a1e935ab6decdba1232040001253fe53984b69cb29c7b324a9b75eaa865f0736ac8e091f1849ddb32235b221ac1367878da040c9bf13996333e37b054a7099526e6411ba5ec0de554ed20ead29aeedeeba09f93029cf017f7a06037e36a49e623a293d40ea8bf8487510f9d5e9b5195c3b6dad054c36045613ad003a8499896a249a510fed01b89d63594d5466bf3ac6498695418c18c0e54c015ae181630b6764e5911579af008cb683d3eab08d914ab5458392720c2a3ad04eaaa15c11158f95add46ef992d26ab4de22239222c7458cee391c28f5be40ed0272230cb6e09c5d13a9a0ab929eff76e29631f53c16ef9f7d23e44826835c73168288e8d4ae3d8aa248e1b1f7daef731133336f7ab24159ec1676c6efc1ad8339db2e92c5e97793e8b57203c7d8beee973be084c0003ed4585b5bda8a415514f0028c45f573b64d55ccc593b1e65f6c905c600a1195eca340cbf812542b894e00abc40a0be7d3ec6a5536f4a6b055ed409596dcbf2efbad55243a4c26bc10f060b2d2ee4e878dcfaa9adfaa7467866c2e8e22d84b42d89ccf60fcd349e280ea73035479e04639ceae36f6336daf31d96e0e16136e7dc867054cba6ef5ce92f5039accc4ae2ca841431ed8ecc9d2b892d8c723ba8adeb7c3b34d54cd33a8ca46b5e078c545b64bb71ad8df485dfdafed044663bb255583129bba13b4bbaafb6323fd848c587feb3aeed67bde4e756e2b52407135bb7ce0f0da6cbe5cbaa1dda83a91d60358495845ff0ca48bfb4448687e5fc12cbcc52a0c4ff3c1ef58d90f605b03f8ec73196d95549f74cd4c4fd3a1e3b84e9ec709f8f3b6ad65a49b8c78a475bc3eb313b44130bb6aeee58779ac6665b179fda6a71bc12200ef8606073eb0de08b1cf045e771a38313588f0b42e103895b2b70d0ac1727c1895e8c640ee20863065391f1a40282b04282d05935574092d6df7de2ef45b56142ee5301ae1966624e383c725df1871e8442842d50f466e9faec18bb2aaf9d2b2bfb18097b7381c9a89e647da4091f517b3dea9e28aca794b87c0c1ccc49ca22bd3f2788d08e4c0c2274b07a1ad7d52e177853d5b970a72ae009e4a21ddf442fa9c3271aaf21dae810b1b54c2be9c212237c0e0eac5caa8d52ac684b9b062189a160e113ed33e77437557b2ff8f263b5c981b7b7a012ecfe54832ff8f2a53169b75905c28e699beb26dd7782f01d13b258d0d2b725503871eadb691a7b4b11de923ab3557149eaf01958126da19fad0463f72c3d78e0984b1c3ce8397711d029a677b428e97569554bf1ddcb6af78eeecce7c5d30bcbc7c0b73ac734525d3c6d105e9042a607ff60e7eab35114e8a7bcc0b7798577c60401efb50581ca9c9c9fd0320dd449598feaa842069101dc347c3fa85a200fb2060399b52626b37062d81ef4a819552d9a64936eed3e94082f115ec8748b17e65709bfe0dd34897d44731f32c35387520798089f8f00dbf5a669ea734804160dcbf643c253735659b6832f73c679ea70379eba93dba40b845732d5efa83eba66ecaafa22fb8417aad54576ab8bc54759170d426318bc6ba177533d480b78d3f4a3a49387aa55f33a41ee7091dd36d86806d5811c23500ff288df75b59b1432e551440ecc2d4ea4877c0bcee89b066f24496f65fbd45f5d8164e8ea4a477a316f619e5c3cf9073f7b72f6fabb7767466c7326185f3251f09bb325930c4603656ea5dcd4f9c5c592de15cb4fb4ac6f334ed7ec42971af16ac94605afd53dd4352efec1ff7fbfb0fd4ad035ab752cc39feb916e7ee4b4f6ce0effe0ff902b51adcf0e67d5862e0ab9cfcfc6d9fffa5f93b34665c92accb8845495619c68fb26d7152f64257483debce174cfe36c3cbeac27a6b9dea5a88bfbd32b7153c8dbed75b6a8d6176b2a163f5f2cea7a64ea8e7edd3251b0da2c841baba28cec48f189f411db6d285f9eccae6f45c17fd1f3742cf0337a5d57e556b2894a5e16420f383f2ba5802438a767e3895ed38dfda90faaf93087d47c55774caccaea537e66d4cd7587408d8fd81d28df9cf18aeb2eef8abab82e4ad8a5a0fcfd483f6b67a3cb497be37a267df6fc6c59dc3d38376d9975763986ff6d76906888d1566aef9c1f188359d9478fe1e978fc87a87b9770aae7a4416830b89599b982c7e3adc45792cc12772e8d0a53f2895dff52c81736f90324cff15e9283acb68b5bed22275957db9a2dab4f3cc190acb03e93aa7e9a54c6972671bb310a2f4c6849be4e86df2e47b517356dd23b8d9bf4eda6db7ac9a82b5c6da54b5738bc4f0d64157711c57bef6d45405b41288494676b2a17b7e9c5ff4effb11ca2f41f99fa33ddecbebaf012eca9e6d0a762763947265a22f05b6f24393fefc8d6cf2f2752eccdd364e0e692ad0ace1cee796870b2a1755da8291f6e58144f9091f3b1a2353e157c597dcae872f9677537de16b5649c893461890bb6be80d13374b034356b5234181c4ce3f9f938588f6b4764b26eab0acfbc09e533ef82d21af7ff4c854f8ec184a9a53cb4aa1dc346e9106b69514e8f4798c12e77aa407ccaf55bb2f769622a202de0e8ef0241c429bba96571e7850f3203ebae6fe99a11065170a46feded09b29b655f99fb0cd49bfd208746638700c899e841df77324dfa4001c8484e651a5895a84379b28c862509708503d3ae1db84f113d69324ae3ed04a112ae04ab594074a003cfea85a8caf2ad22ca2fd99fb04df8586de05bb40b88b8406358d411a5a9fb4911662972bca36b858424ba728269765df0a54ab1ab81f0b54c45a7844a316b81b06cd254847d15abd4ed8f73e6e5c329d3824b5af017f5862de4f70a102aaa744315ecfab65a324cd5a9cb1665c1b8d448ed7822d34f324d74a309e66abd0783a8d033aa6089b6b51d0c3ae59b0698d92030c2c1602b02eed903351b10a4640b5a9669106b83127a3c6a339ee31138d9f83e13ecd72dab01a07fad70225d4b438d00f34307e85a18429fe24aa176eabf5e02e1c1b3af5db029b4e7bda876fbe8fc27a7f0a204cc97dda7ba896a895063a3235dc9185135704a186ebd600a6920e7e7cc38b67d0fbba5d05775b3154052e02c6d0fc0ddbc26e2d4f71d114542f8333091838104ed449fa6a8168d8dbe64ab4ab0748b65b62a442de13621bc7567bc89d8eebfc8904ef14b7b68c034c80c63b2642593eccc25f452393db5dd5e4cf860909e585007cad582063db9ca285a4c0ded1f5c4f84e1f10cd727fc324d58c8038fe547490ecba256c4e2ab0f1fdef09f0d42797e89af1857c9cb3cd972fd522e9373eba2481fe8c1a02fcfbe00aa857a2bd8db8a2ed9326f8bc941c7aba76fbfb2374c7e5f5530f669f495a2dc76f2c5d7053ce26a15255a70ad29542b081ba7e820fac9c593b357a086f6730d287e3294130dbe4eda078356319a889639b35a9c042792eda4222192f6f370ca1a5822750ee237a2695299dd56b59c4ab7103a8ef4462ab04617bf6e0bc15e551ccc6ee3154a6aa9083fef6e8a4d999fcd8dd3227cb97fb34c19ca9967a733c266e339c2e00bd2c255956a3e342bd6f88abc61d20c20fe4a93a74b8f09700fa215449a1a5710e1c95107bb7f936bad0baa8f4ab0d61a5107794e3b0b70fa044e41782e0a5ec88296f9c1e0f8021bd71018faf0d6f63c33bfb029c92ddf5057e09a47a388745794b85fc763725d568b5f121b3b952ae447fdd5932a08a0c76e940ee92a2052bb66ff1420d0320d08d38040c52a4d3454d7a6e97a58c8fe20a6fa45ea0d44a87f708fc7a7da1b8dd153d1e3b00bd91e8865f103874ee1ed1c699c100b56325af71c3d7fadf56eab1d906e073c23c4a664664b26333b0abb2cf3d3aa1a82f0199b4feeb3a2fe765b96df891f14784a059a5a00ea8f0243b98cef2833af9b731a0e0b0970bd2513963a6bc6e7843580d57d32b203cd5076e0dccea601714484ab9f10b687eb63b1957342a4d5d1e12168e3316803cc4ce2942adc65578098c3fd5625d04cbb53b84a86724ec2d788a77d576c2f670c1c4fcd8f47fdc3ea5df6ea91d94bfd49e190121b393f66a8312a16a80187476fd53839d8edf61031bf7161d294476f31f28b7068a2894fe860f04e2f153523fa4502589ddc3b1a8c5c4b40e7dcf0c83b0dfa7f92e4a3cceceb38fd28f3c34978eb550b4e414cccfaa0a3a6c49a06bf0ec3de9a1b51dc476a8ea7c1bdca3b751fd1e1a113a96b3eb033e8d034f827e935459dfc6e536e6f0a5ee7072b99fb20c9e1caa6cee65887987bb3ccc758b01bd5b238e53bdf569bcce69619cd4e286a41d87de9245c0c29dc3050f6d3ed99ae87c3066ff9efd8bb055ebe7b275d93915cad6f248b92d16869a3de1571d2ad0221f84ff9093735cdbb0d61045e94a7dd8a9be20de6952c56279480024d508db8b17a218a8dac44ad3de26d437f4ec6e39d0e96b24a13dba4433ad29aa40549a9f187a7878066728eb443bb19736bce41aa86f4663aab7084c103933572287085ac229cd34f3a1f37381867ef63f49599bdc613ed9a1b3c5166c59298b80676f9916361044d4fac3a2ae8ef29b403ee3bc8508dd18f1bf960e01d9eb9ce0f8efe8eb7d04adb7cc9d9fcc4192c56295c021e9c423fcf6289292966723e395707930e06e9f958eb97a69478a34f7d8f6d77e0890673af586884983a3b67d84c24a76a0a209c80d730581a22302c63b4885834f8aae077b42c3ad66de6edf4bbd134f83b490e8b8ad7526c17b095870687a27e7b95c1b60e0c3adb87585b94044dccd89c486cceb26e4925d995e008ee0d34f8ca57eb83ed9da6db426d86a67ddd5ba6a5ebe7b59dd1a94eec407b3ab8cfd64cdcb0f4d0e0d937c690ac3db9395250d988d44ff5a81effcf743618a43deb665ea9760e9608c153a3ad6a3f566fb5824738478370313dee3aa69363dd0c7b735c5aac9fe12e9695a8070a1a36cf8462580383e265b5d32af0c00ffab3ecfacf7fafd2842c01eb91e58b25dd4826ba0f9f374ab084f3f9186bbb3fcd43d5b61346c934b46ba0774cd01b96e0407575dc31674bc4cd354dc718fe9ffd4f9460b078f8ba7256add755b934a91f367451f09bfca9fe7c47c54dc18da0fe4fbea269f97fac562b53517b7430fa5fd7d572ef5b525f9d4a2a31aab3aa2af06ad11a954ef68de96f3dae8fd526ff535031ea4027475decadc4fd4f78e77f2ea8705a87f953fdf941e14aff861795f0be28fe84d7db5216ffcef6de36c77666c834180078e08feca5c30d40b1b1f418079628d7c08cfa08f628c688bc659c12a0d82602bcf161a2199dfa25cdc79a4ab51ad396445434f8c4784e9b72eb432d2f8c210b24e99f397d3e1e0c8c33d9670ad473229c7359e7cb953798ae2413d188f5245e56cb7d9cf2d638dd80a47f2ef47dc00348f910a2692ae22ba6dd98be8f68ca87c45ae7e4f01bd23137baed7a8ffa87d252328f0784e2309d5aa5dfaabe84fbcf63fbb0d6f5ec98753566601fd94eb606d742c02c608a2e98d99368b921a5bb255fc315b169abe80baa44059ccadccf921c0ce8e930e7eca9f32895373a1f630a563e0f866fb2e62e0ae3285669351854ea21d146ccc86a0a5799819a8e8c4413312475b6c354fdd9e3e1b068cc393dec727151e07d4e2f8aa65f5bbfedb50d3cb6657b5c9fb4e77948ed061adb82ea8d9ac37630d876e6a010df8e45cf92dc674be3e9e725939f18e3c6b65ce2124d96cf74506d85926d51d314abd4f07f1684f6ac484116309345b6f74ba116a26a9a4092f82ad66697c07ab6b166259ab6a51a0a957336c212e5ccaa1522cc3cabfc85f45848dae51d1e8fecace07aaad5eaec03e42385fd3aa3a37ff0043d1f5d4e1950425227e44117df04dc788b81da0be8003ccbec4f0fff59667fe29d7e2158a67fe0bdfdd63fb09065ced4338e151dfcda694eb02cfa6e3d722cbe93f8ca7e7e4dd745b9cfff2c535f44a76127f5f769c857d48f62544f5bb447d520c9d4b21371bfdd18e1758b9b2aeedb2d816e7ff890ebd2e6ab8d0ab02c4ec057ee3b9c722bf1c49c5bf8495cf3f4ac7d1137bf28a96f825701f2628aebb58ab0219313cd3d428d4c8130ad8397b0ac9582af7c42b848edd413abd446985a754faf5350c62d549cd6bb522142652be8b58a71349b6757ab8db1d97c9712a05c2c73bf63e44b11c5feb3f388761caa62ab1336b67e68556a80b8b1ac8bcdb5d0389645df114ec74eda7cb3c8b5950756df4650365968951a8890c9b2ddd072d99fe64631b19d33f2802cd7c9f6d3f7f175007315589fcd3180612db37b23c95f3ec313d47885f6bdf18d091277e53827fab3a4b57cb190c51d23b33910a11fdb16d46db714d6f61edc275a7c17e4cf01cadbe3760253c2f5cdeacb2c08cf3cfed9572234e9acc82b99566a3d045239f68b465f05d2f4fb4b8fc576b1afaf5b2be3e79479ecd7aae28327173724d37ad46e8872aad26a5dba4d6badf1d86f5ccb66cdf804d363c86773b00c07de292c533e9b379357322dcc28612db2003bd73a071cab012184a12834818546bea3023a1f5ad62d79bcb3d510b596330d027bc11b265f388cf48b96d721b20fadaec15a3f7f1e83c50555da0029ee3b4d8adc5a9dcca5446601d2dc7f60030b6375e40ab5701ca91cfb25a22f8afa4c194e8470c54b13a704afc8c25fba5bf561430d2d82dbbd4278a312285c667ca57e831fc23d3918b4e8b68516dd1ab4a8c177e4b053d978af121b7c430e5a90796b445946cc796b647e0dbed63500c0ff08d5e0e74f8dc29137966e38ac3303ba89a61dde91d91c7f522b774d7e96b39563d1ccf5295be00d5e6457a0716a715f4da7ec62338b4d9bd4d8e963990ab201430b1370d0451ec495fd51db1f5bfba3b43f96f607252ef217b86a32b1628e4761fc2081bf266d050e3eb5226b65e3550b54065a54678d0217d9c0308f5d8901dda013bd9fb014e183a5e5a7e01a183ebeae04544c2b5ca33c49b0a18b8b6971ba8c26d6cb69920ccbd3a580aace97aad4f27429adee5bc53e096bbccb85f592a34e94fbd837084d56c6bbce6090eec8ee01573b67b664caf015e845e1555648b6fe5009696a772c756550db9605e6af69c180da5d0c6adfe9b3b30a6093e726d883c9d4c1843d45087f3a51c391f97db514c05ceb1750470083a72edde12b95ee1f1b9de91f2d57c2e705a90e8aea2c078b6dbe06723a5343339bb323d7d90eafb33db9cef6789d85bc33b28a3ef13a58919abcb3df6ebe35f984d7c043d1342ed9e11bd2afaf612ec642eeb0204f9f484fbe698e828489429000c196db053bb1c36c68a1bc810543ed9eaaf69fb036560286f0184daaa17b1be0e5898b064913cd9b9006633126405bff6a9894d21671e8f6d2ccc0252c5c259b04ec8d2725567fa6693dba444f644495e4639d27bba488ceaa9e2ce1cf34ad74ed90b88312dba96ce3e626e3c942e7a75b5d35c6f8b537521d142bbc2434f06e8d79b666b4de0ad0504a99b1491aaebc0629cf561597e41efe6886405a62995d7568bf3671e96ea9993cbe45b8afb5a5aadb269f5bb479d056b0e9469e166c3a529dac888c8984e972f8341fdb268a1868387185c1bf6e5d5fcce059618ac6acc07407028ef54d68a1c6dfa5f93a846530299da57a320f361dc295725c12abc9d4341abd5a237c4762b15818d46107413af6e033c0136fb5fd7aef2c9e5b245c49b8452e96845b76cb82544385bf6c87b539169e1c2aa774643565f280802a078334f559174fd1d0fc7c2ef45f90559adf239387307d36868c3142daa29110b29c1643b2c88b11b1466190280d16335ce4f6e7c5531c8c6139d532063d4cd544306ed5cb882c501e96199155bbcc90acd4b39d53bccf8ba649d7f806effb40220e95db0d6eb77570129701c874d6634b62878b17eee7a4cef6cfec8ca60b02cb90d7d9fef9d6248e6cee60902edca22073e3d352dbb095c644fbe229be5589b2da0c4b6b157ef17412acd4629a72d2a7e9f28cac1a2c7ab39eaf1a949face6f6fd6475b28df71eec30696f597b7486b53fcdf6b739cbcf4d6b0d2e7a9bb0bd8c8226467113cfc60dae4e4ce776aa77c1b93bc33cadb31d9aa64b6204591412068334dad42aadb33d42281741b63e61b878b006ece63aa08c1c1755a3fd6b7353a7f647beb414c1dadcdca9fd912f2ce0b8411e93d1da521eb7775ea06c8b646fa1816d88ec2d505078c79dc13bee00efd05a733786d4585bbdc21bab536930931f0dbaa2090dc0591c01b4c66c30581907abfe97c5c2d6082f7430b357aaf2496a3dc64d74ca5dc13e05de29a18150df0d0b34312132ab9466bb4b4cb3fda57ab27cda5395f6344efba34afba32672a3463f1fce92f000382b781bc1e28587c52b0f8b6f01baaf01ba6f9c8ae215b1100114eafcc55ea19aac87570a2e5a30b798a694a482dca251a988225c917aa840553d2a516ef2861b3474b923c81d9626c2a1ea21684c909492dbe17258ea06e9b0440110f52536a3e5282ca3d3cd1afce8331cdc57834f2bb24630804a6bb4eaa4e1151aea44b5aa7b524cd45805f13295cb5ce0ddd39ce2dd1ff302ef2ff30aef9fe635deff31df36fa107decc8715bdb647142f0e26bf0c96295d65698f45e211f208600c770fa0903ea96653bf2ad4ca5c38b60f710b8fddc497d95b6fe77da5bec25ad993a68245917cb25b8b7ee60a994c418a7c2486c58a6b0b0e689f6a12be291d85c41c6930202da154877024863352be6789bedd4941166d97e282e9eea1f440c292e86a0da059ac6fb21e9c1844714990de9b0e04e448105543cc2cd5724429df12d3138a40156961ad9b471437c45c6784f36d36f036f0bf918dff56f6e480d497408d641e23bbd08c32b3dfb855b86c570d5e06b7217ecb73926e171b83db9eb2791cccf62cdee185ea3d6c18845613dd8b57a29aec866303057f99c90eb6900596ea78b8ba7c3cb7c01b8754dc6b8246b7b496a5017acb57f1141d6b35a87906c119b2ab9b0c93e291c29b563b34c5135ae2d19e3a5820342a3e8ce4dc7f6d972321c6e41ecbdd147e79d7aa5d2bd02eee1fc7b0510a6e7efd942a67780447d5d89b752a4eff002f6122fd40f0dfeb512d325844776b1ce481cebcce67dbe453fb66e2cb553a3bacb76efcb6d9dbec397082f46e6b85daa9ffa335ac8e626ad66db396adc826a62e60635ea0eb823e08829b5d22cdb8f140aa86e679b85db0dd46ee91845f37b7059590581c781cb408865ee4f87008ec0681d83d1a8fa4370b4255d8b8f475b2a7812703e8acea364ecdca20620a398d139ae4f81ce16416f41a4979675c9bfd615ef1ca3f0a0cad641f5473af2446c4c4da54545d42e1ba05a012a52032ab2b5941cb8a83708df92c808a599f00c825abea7f236559bb3aeee1416550d97b8f6cf7e311868bd438be7812d8747baaae176041578f6eb962e0595c502dc71eb3c5c63f877b8442131583848a615653fd705ae87e56879ba936189cd400065f184e9e7876feaf4b5acdbb57db7866f91aecf8e5e4fbebf7d6c569b678bb2aa99db0b7572d2961beae7e3c1c09e9af45418e10ec62d038c5bddfff13901854d20322c9a6ef81c32164c48279810e4b0cb25309e65b66f6c28377a5da7aead67d9787c89a6e3dca5c0f10c397dc7630f9b1012e3cf36db50a5450cc2492cfd325aa1838136a1aae91d83586c5adfe545b9b9a58462b74bfed682a10a38b1171ab439aea9d64badee9810c51218724e9145ddf058b505f9b635f7199a0d528175dc4e347c6393ac3b14ac9695f87c7fcc964c41b9f696f265a90d4afa84605da1a9672886c2eae80b229b783f133a66f37ec3a6dccac3c86c9ea7fe8b07d2191bfdeb8584417d5d8977d512ccc032455baa0b2232c1ee98a8c194d6b461935284702ac9f97d4685a0fb3fffbaa565edbbc2d140910ee5dd9a8829990a7b3a8e47610858533e928791c8a1b7f70e743e06257d1d9904ecef1b84bf97e46789ef25792327f75e499a899a7caf2d99feded576f6da642f651af856f5cae5f313d6f00728d27eeb21fed92a4dc0413c6ccff198ecdd87613f5abf8a33368fa282cfd8fc78843fda172cbc8935bc89159456af6141fe2ed34a1ba705fd4c930595eca612fbc4f99247983e27d2f73218c087b66968103e97ba4d68ec78d48d0e06faaf024941b6d3b8378978f61d1caa48af3e2d10aee6286f97ad0c23e53ebbd2cbe656ab690233f5bffd6e7b609e6458503047013bc944ebdbebf582657e29538a0b94eb9c20c3764f4fcc13d604e10226fbe0a47e886cefed557fd004606dad37036d7d2cc9dfa43358c1dfccacbd8db657c412e25c9a68352ecf2648cc326d63accd12bea177eccdeb1a00f2f5b62897df891fbc99844e378a993e068eb4497590eb1572d260d2bfb67d9af4320db5b9916826cbea20881cf2e1b0f9745b942cbdcf56055f6a192cc3143d27de559af0ddfc35501cb2b891ba711ed508d42eff12eb8bba0185ce88d53151439ab1f994cfe47c2466729eabd4914a6bbafe3b7dc4b6061bf751b3d09750e02a285994c5e297446171d6d391fd80b2736ca24e541cc27cf49a51443613ce9fc5ebadd08ec1fe753cf6019e75fdaeb7115555b07a5371e39f27f87ad169d246bbfb4a925ee9646ceba3eda3555a10c6f32be9f570b1b76c3ac99d9cf4b8a02429f8ce39345a81dd38a98f4cc99c0e7ea08e0f2fa6b53770860790eaef4bfb66e92be5f2a157cc9a5422e30de1b5cc622b543d6d4ab44f16b075c58542439d9fcd4a7f013237e1eae8df67db620998e542ee88a2308c6300aa63caac8a1b2231b7ee6bb135bd2705e6a12d3b29a6d545a1779bfb2bef8228f1ecea7abb5a31c196df83170d727ea95f6b70da3a9b63e3398c701fcca6648270fc15381c016de77aa6063d271cf7bb93e238516bde7525e5b01a039354298882136145513661ea451783019da63c02311e0940285707a92a59c684a8449a7c4d8b922dcf6475a67d4a682779f9d982f27f916766bfce167ac3cec03b9fbc656737c51de3678564eb0435b85fc1d0a3f1f6b07d9099b61f4d194e34fefc8617122c3a049305a75aa185f963942dd95db160ef8b1d2b61e300fa165c5b256ba06b8bfa0b391830e38f05f01e06cbf1b1aaca8fc52645381a07e0e86618acc7d2d6bdadfaa0655000a41ee6cae25a569b9e1a3faa1a0b563ae81055d2c37b20ae6810cf4bdadb4109eff78424633f0d70ac0b2f921f63f8b92aab4aa4609bff8eee8af5760df4582a102846f617a7d3e282e66125edfd136a29422c35d4d6392105b8e086ec73422a859f8ad8ed0129b025e49d70815458188714a6cc30d9ec1297684be9d4f8a8a8bbde3d22e7cc998f188ab0b0b460d54cfcf64bec9c3dcdeab9ba2815ff9e69f7f7fe772a15652b33b5cf40cb9adb74585a70cfb3071e834611363d88c40992d76ebbc27c34a263bc0699cf8963a90122db763ba1100430542e96e457e94ad9904bdaab150a9404f68f6a4597b201985c2b6096a50a71a8605042d4e01e04e9012d4daf341ccdd9184a1bd8f90bdbd729479f51fb99c9b902d5ac41f8d0a089099858ab93489cfbe1d426ebd5d116d36bbae9d3343b58fb6586973aea94231af0b21bb0aa018acf36bfff0dcddba056cb7654ab0601e1a6db566fa6264a6c033636e4b2274a2e2e6a83872bcc2568d97b5d6edc99105df7b361f8fb8288ac58e24ad15442d35432834ed1e4af2ac9b68ece09f9ab3a3cae3f0d10025b5c9f83e9ac9893f3b1d1ac52100ce2249f15da01d0acd0341551700582401573e41e6e816b400818b08a8c275dc2bcb79a2d094892c0583badb4b7a7adb1629bd484b34f67dbf4502cf3428719ab9c09bbc00ba9c86bd5897e28d539e3b31a5ef9baa93505f4b158fc52db089b10e7dfaebe66ebe8e0a7e135a4b8759cd9f1688cdc154add8083277da614320166c9b1b1b47e5c5a17ef95c34bfa232b5a7e0a5c33ae23e55b245073d0217c210dc317b2e1d0aa9fd3199be38af08ef124c235290c85cc439a0b18f76d92b90620b264b514d5bed54e6feb08ebbaa4c655067c4552e8bfc7e31857daac8c305c0588190a3f0c0437b4128a0a663ebc738ac203f4239be96ec1d2cf87bd45f256549fced4b1f9332055ff92fccb50971cfe4b7256d467bc9267546356676056f72f68524548231c398ebdfb8468e88d0bbc017883e74a9d40b71ca11c6d6814731e607c6b6179a87d9c59a778c8f8e0a9630c15deaa6830a96109f652b99f8f510c86cc83415201b48fcc075346fc5bcb7049eff7b96369cc2ee70dc23f808bf80f320b5c46a814f064e11f7c61f14e7d3f12840ec213ed8046eb98ec464021b253f7c904b3d3fae6225ee950fb5c0e8748b4575a462b1d75e15773628fa9b9e0ea6c38af5c16c950cf402731b38b3518f4c117ed18d6ecae6a557763065843477d9b08a6218141108ed615f068bbac585852496b61ff45a6c97d8293ab62b94ba0cf1679358d52c03f66b8e76e4698d15a9b45e91ffa30b04cfd6972617c2342203c1caede899bd23a1e8e2cd19512f55ead1dbea7d11575c4b574017e1a176a9885b4a1d7feac765d5f15572e708642dcfd571ab41259deda441f352445fa6206157a1cbee860266acd21a8550fdd0370ce6d5a37dfae83bbc0f690e4b15bced63ac24a99a5b435fc8db3d141f4e3a2c5087dd7c706cb851251f7294393766f30de76674d6bdca7fc38751f304e0e6b26696ea3e1b1a67d587a2669bac5330e4e8a6478cbaf2c0d8e1f1a79d802805d759c4f8c7af29bc1e5c47a3de8800e2c145a17dc3770be68bfb4b744d5e0a467d3ed62e81b9d208b2684a38f8ac3c46d697cefcc2552aec9af57d57aa37020ac7dc480f5908278d673807a36ff3d3df0edfa83649b3a1717977fcafef4a7368c50388881169df50cdd8ceb32195badd842d6336912e69a02df0ac1b8541d614ac485cc6cb7130652b094a714618a056a70c51d15f85e543782d575ae26643fc202769279d1a0c98f0ab10b1806b802a7dc5a12a0e3fea40817697be663eba8bb41de8176d316adf6beb9c270347adc6a20f0437709ef81a0dc6a35227c6ec9fa67647c3c5a82fe1919a3c1e0d48bfb5ad04f89da490301d4abe9e01a19abc7d2895c14ce9bdd3f236330de822f98ba08025f9818fd2addbd5c0c05cd3c5457645720e4d4af9c9a52f72df3036e1aece71f2da7056526ba4f1796f586fb8162456d866d428da6121901fc83c842b4119308e18ab21aec839986514c4f9c86384ad123e7c10683f3537351c742fb8ae89d521866de220880c1273801800b584238899e88ac27bda5f4ce3c3d1f1b6583ee23e6d7a20fb0f5bc66ddd39c5a05858763c8da451c5d4ef873329e8c461c3949ba7ddee48ccff1e7deb8e87c06b57ba19b7ecc987dcc34896400259812e6f2310f9ce9533f6f2c3c9770c7e4c38f9bafad8e6770014f3dcbe664abc7d8fccc6534e8875f65d37a346807447b07daa9a135b00d526e9400fa7caf5109fa0075a6e3f7ea365954bb7e4c7510b598da519cda71d36eecc717bba2d70f9c6d6c6683e1ce1fd760a8e170c2c1aa6b5a5aebe6aedfc6333115b6430e218eb1bffe8f5983a5bd05a7071ddca9536727025f33369fc8ec4a5d82e33135bfc085a3c5842065a6a1d9d2996ef3e331ede6121d1d434750a292e6b3b90b950c89fe5ee86f1d0647ffdea96d7bf3dac4cc083f00fee5d273322ce689308759c700e555dbc1678c578f0d7be73469faf053c486431768abc1ed228f46a4ed31b9aeaa92d1e094c84cafcaf4dcfecacf7b37cee4aa15e04c288a0e946c4f017f17e84fabe25a94d2b0c7ba5ca653332996bd0ba850515040522702347ef4d1984f0430374390a8fb4a9deb7e5fd88fe441be9c956e1aad6e2380d0fbcb1f269a4e30d460943cdbf24886d6126e71845fcb2c760b9c82c4157981ab119d2ee40e7e860095e3c4749eb8b977a5a20d96d54b5ab33ffdeb9b75e45fac2525d72393959ac80fdfbf0ddc4138b1988f80890349df099adfe96100fd702fd3c395e1e562fde38d19a74a80ebad1969f8cab1ea83b0915ab9a30158efd7f4218f14a5f1945c1310eb04255906da10df80125c9f5b89c6b3f69cca20f417b018043abc96dd304110631c611d3753f393fbe4a6696b40468a8a1adcdf68102c05db181884a3068727ec51ab31918341ea1cbbfa7427a96af32f5fcbdef0460c73adfde37816a018a21d273d6495c3a749cd649227bad5042e9d363a776edf28c426a5281584cde8fc04c62edae1e93d509855c3c48f2799a7024d125318fc00f5b7c87a62de078d2657c9b01a26a646d43e322a36e6503d24703687f921d21e96dae2bdb2ab2301816ddb7c3c90e5582952a0e1a9c01107c11ccfae40b567ca5bf9b938b69322cccda06dc1b09c66797b182e14ead446504929ca8522612cfb83df0082e8e4bca69867a6788609681d651d5d22cd6c51680ac23dcb73796a79b0fc12e5d740c5067c91c060bc266ca43ffa283d58af06eb7ef307b55fa9d67ea511d74664ff7ff6debdb9711bdb17fd2ab6ee6c15604134e57e244d195625ddc94c4eda494fbaf74c7a543a2e58842ca629500382b6dc96befb2d2c3c085294edccd9f7fe755295b6080220de58cfdfb2465820128001b20964ca2313418cb80fccf489e143c51dbbc6f4fbd6e2cba7e8caac711608bbcd4f0f3bd4ae170cd67d9f6b8942d43e0b5098cf75e8185c3359b3ac7977a00ed62c1f63d261eeebad7d03635fd29a289b07ec72c3cb923e98c05c3f2bfa97c0f6f677054a98a6e6a9f7699995472bae9645ea144fd96a6d6691a7c911cfd492cb23511c3183517c3467e2e89a1f2d8a4aa447853c62e22813732b933ad2a4f78d59da4777ac3c5acbe2364b791af502c3c5bf834561487c19a3b3dd5f54546b4ce85f94ee979e52b8f9be5abde02597379cfe4391af46c1699ebfd7cfd612eeef0d4bb84521574c95c9ef8aac992cb9fe61d2f42f96a6fa4f9a2d16fa2f9c2abfc24f2e52f3e3ca583a758660d083ff77e5cde5690bd2a1a33d1c9be9f997a20f57a0e2fabbda112ea86da8665d9207b0a0ee64d66af84d8e273ce9f5067c478c09c0011eccc9b72e5e4cc4f46c3614d3d12cd1ff0cc5349e8dbd4383c417a37e9f1f531a58f3804c4f523e6ca4b953f36b941737a31805756092d15ecf395c709c2d90b713f2d90484fc091e859772cc303e1ff1e14b27b3ddfb843ed1cbb089050e1bc7f0b8a4cd2fae32814a7216630241a9353df7c3665d082e54c672541a71a9d5da0e4727cddaaa8edaaa666d3f661b9ea2ca8a5d33da8b3d0e71b6237971c364a696ab6c7e280cc929d4bc2eeed0a8657a653acf712d008b8d257adc4b462656cf99f9f3cafcd1afd576ab00b5df0deaa4dd679cf47abbdd8e2841fd8222c23c04225d22c53e7839f369df19d2a2c3d27f8f62324193c0d001399196b738cb3485c686230cce5c375c816dd68f85d4f951860d9605ec4d7863002db848e109e80f6408033d246ce227ac1896a41a1638815199a0fdca477858e0d3b30415c38e2f0f47189f9e11540c6876ae2632194a7c5e0e477cf87abb2d2eaa81fee583441c15f51957b60de59b8ec36441966445d6e48adcfb7922b7743a2337fa9f6b276035fe09f74044423c3b2aa6cce25d93ca3cacd81f859c28f337517a3c0b49b8f115cc691519845d925239cd67f0cf76fb009ccac38edccc41e432a715386e19633db2a04b1a13215089b75ba5ffc0e7cd2fddb08cc6a4a09e8dccc0af30c32b5a4eb3992eb83205f51fb4005bff00e287a486454aa31b3d162b4c96033ab71be8a9dc25264b3a1fdf5ad42c4c6eccaf2526d7e6d7fcf42c0c701a584f19ebbe5b705a889d8ddf8d7d345107936bf3e8ad289af2d1c3f88ac2840d9b038d65c6e5f44caf4e76a19cd4371e8b730648d09e7501a8703915b3d958bac02e316126bc2092e41e9335bdf5d8c76e715b760fa8c15b8cc915bd7934cf0dc6e4010219269728c6441313c925bad7dbee2ed3fc777289d6982cb39ba579b8c2014669d5f42a302e5ff32fa53e5ab2f9974b26bfbcb710f375a1bc2129af0b1bd7f70952f4aba790afe076feb100a29d88e08d2aac731ae2910db5afa9e57ab50e9cd5360e3f9e362dfdfc75dcf9c987458db42b056021798c5d1e3c60b270e0b83e1b38ee72ffd36601feb1ce036eb9bcfe8d49dd7e932dd87d3c78c03b4c1ee6802cfb3564c18bfc96a3a9a9dd78cff2e0b78fba1280f5c29b190e1d67e6015f07e3c5cde9e16e9b07784a1431670b37678cf32c9bb8223a11272a582e8b3616a53bd00ee0a2fb60704801383ab670889a9ab610e29e21abbfb23c74ca522990d017745e5f3152203d46164c32f8957ad879c83be7598e1498c6234511a37228f06948149c2aa041aa71791e8f713a183882c4f8565683f444197d6360535d91188fb3f37c9c0d06b8a05c1f9319a5b49ca0c2769666e4406538b1c745618e7eef23630c68898f25781c939619a83bd58e47e44666e97bc07d0df3cf3b42818c708f7857ec6464613140de7c1cc3d3afe2ad538fba24380ff443eb4018c5e42b97c5fba03ef7dc1586e4ec15eef90ce6a3ef58b94ca6b38ed45f4de7dcd9fd57dfc3e391855e7665aff7caec088c9e81b9ac476464502d8d7b7dd2eb117be6240faa58272f898d75ff52934f990dce719389efd4bfb82c74f155267e2b9475ec212bb6f14faf62b2ca34e7a5b3b96a63629d3f7562302fac52c5c72fd93afcfdc1978136fade3b9e3ae122aaf90843a595c46ce2879dddc50f3e5cc34a04b0cf6e700df0664c6eead0277ba2d60708530f2c9cedc67bbe50fa0ed56314a67f2ad63a591ac7eae0c56f3a45bfb2e319be33882c70071347361e54dec22418cd2f4ce5214379e3a30bc67a9df27febb484ac8ae36f85ccbe1642696a79c26df4933271f142345dc4034fa71dd933e56dc6be0bed08c3378140a4d19e303f0155d2accb2cf2703c35c083f577a86e1749691e954cf3ea801b992d50d5f80ec2a4d287954160e0e6e16fd6fb029e24c432abe307c23a70d36b66dfcf68bc2302e225c3c78ddcaa8a1a0f5766ab655f799db46266ac611fd39854515e881b5e9ad9354d0b5201c785cd979cee2781c4ab8aaedcc1f793e2abd6b71b49662c3e72f52e5b71515a7bec2a2af7528c35dc5e72adfc7e9fad32651253aeb85c65a29dee55dd419a4509a8b23cb5cc122968654c3e6d02c8e5d031d2e90630a07e59e0ed56ff7fec80a270bf6f871ca8f6c2c4938b09a336d95dc412c852890beb2560307b6da6a99cd9b3e378b4f317b19fd98294343d2f6ab6ae022bc55b2ecdd6fd54982d83ca499396761a481be6ce5dc9a78a74c8d1d9804aece2c64d1b4cfaac8efdbb4305497152c0c20b4d25ddd8be65f9bcca9982adea4e66783f3ff80686f970418b0e9e29785ad8bf06f1db3e9891fa54bc93ec8ee68e02eef7511eb9b37dbbede99f00f918954525e71c4faae8cabd47054e0a52f6fbe8f000373f84b1df6f996b50b8d133a177de8ed4e3f48476b1719a38cc82b1689f960804c97ca140ed68e01f134854c51ad2cc0941243d06c49080b7a70072e0787bf0cdbcb21f8294129c38afccbaa06ac86d50a3e71fac41f6fa5cedd8f9cf3fa41bc5ea3acb43b535948b7b63679ddab83f8881545d281a136e06d3c55dd6835a8762f64735788eaf21bb1967ca03b3e3e0be862cf53d1d3ec2ed1c26982b99c676b8fff448ed976a0f7e7d123e7fe4eb32756d1dc76d2372d59ffb4eab48bbd1f5d9fbfc46d76582daea7a1a81b93aaa6fdaf43a524680a8d61d9893b005cdbe34be4ef80c27008dac0f89e716b2f96778bbb53f8d3adb06ec987fb1e7d15b38a2ca8611e45383d359bc1ea7ae53ef71c748d3406bf908ddac7f82931d8faa124e776893a6ea5cfb883502b19144fec37e1d2edd5e4c9d37ccf387aeb37830744fd5ee0ffc0043188efe8ad66ea6b9231c484acb0e99ee9ce651c00069027fa1936a2e088477c765749595ce7e48532c791dd07e7e4117db6d7a4e47dbedf11e2d6e4975571d9d2708800b8c29e57b4f50220c40e2bc74e84e429f8346bae5108ceb04c33f1259cb0bcafa0076cc83450ac6440d5e5f204d439962933aef699ac853940e4780cec3283c209f317a958c404752d6e7f5b012a88a3c738e87b93b7487b97e5373a9deebbafcb754489da8813811982ce9d74815eff88de4bcacb514466552ba5f3a09b54760f01a9f32a29bd4913b3b2df4ab61fd4a9c1618eb0f7ab1c69cf8ec0bb2d42fdbf3b3743be83f5ede874bb777d08f997afe7ef9315375f94576c0e707cc4e2ca9e4bcc3bde438368ed6065b5b069ec98c4abb4d322a831984481f7eaa8d6223d807a40ac1c56bd757c0ed6eee03cdbde513b5472d2425182598e44aa0020f7281328c493e31af2cc510bef390670d3a82d574aa059b4de91cdc16e6baddaddd06a16540c00c716572562a882a63f620c493b16b8f5cd1e8e5496a448da1dcf39e32b7f4a17be6a3b7145489cd65456e60d1ffc6d28c8912b5de62726d857945896e30b9b4db2613fae98e5e9e58a0e8c1f5095abbd300dd4ed676a32631c603743b89932b3cf683e3977a384a7e2bdd0dee6d7419f29e7ce9d064c578684839f2895a52ae43ebd4a1291b8ef0f8768236b49a5c9f2c6ccb2f4f16aeb1972768e13ae11231794fabc9e509726176864bf726b93e59fa4aea54b4a10b07824eded3a5c7cc6f518d7eefa3cdf00b3e71e1c91ce53afc82498c072fdac4645decfdf05347b14fa658ad8cfd4c5964c465933871f3753fb81abbd5dd9c0e17bad9e4fb8c9bb4eda2c6e66fd3b44bff6ab7e3d67ac8807cea559d8724b9e33b840fbc66452230adc1a3b484780bba0228f606c0050928f8ba767f3db9fa54b10e9e2c7abe3301b28d3dc862d86260821fb6b79e92c60493662e4c1acde828f4a95837f384456473f29b8ba29d2f2c687997fd923688e2de70b87be6999780cb5bdf01e101fb0451e90ee6f1e3c058242b7f7451c59f3240f6e1c741e609c3639c1642ca3f5b20a17f3895f32fec17c054e90908467b388aaa09568bfbfde3acfc311399e2fbb580b54687f8133eeb35343cdae0b0fd8dc60288ecce01b40765ee1f2d738f03dbf14ed1c6a11867668d83aadc92f7fc1074c6918def0ca1e61e6337100610834e090bc7dbadfd12618fd0f6089303aa2e3e1556814fd554cc6af73bd2bc511fb582f5b97c71805f09e5a98a96fa6404ec091158001b692009af19c2f744a7415a2077550d8a1a13dd6850a2eeafd4608e1a4cea04293ae85a046013240ebc1bcd70489b2b02bea5fe6cd0cf9a917511d704e5dd15e95a38619463f2b0ca4422c98a6d12660cbf12b0fa4ac4cefa91d5daa10336ff41df6bd78523bfea5564ac547bd3dec0fe1ef4c8917ee0221df466bda4bb91700234a2a439a940402c9821afd3e1f9c742c2fb8efc7aae0f75c4ad0dcb05b9f815a18498483a3af5032e86484de26484c9a8debae7f176cb2fc4703411559e27ae6bae01eff83c5bb11cf11339406a224fcf3495b523fb59ba0cdf4c8b1aa240e36e3a74d8b2811471c04f4c928dd6053e40a66e3f425de877c37645f834ac677cb82d93d15025ca84f06436f1d089df9e44eff3a84bba50e0beaad6d66a5c47ab4c3897f815db349a1728252771c2cfe37e5f9dc71395f00bfdf3229e70cdbe78f1f2e120921de21452d0705c00be65c536709c80a06cbb2d4eeb35f4117c0206235241bed084e019eea5bc8d8fc1a7ca5a3d795423154057228e21c229addcd24d69358d67644eab693e1c011e4b7e51e20efb9e26947cacfb398d9de5426d1e20f439128fe5b96f9b1c0c30a37c2a6744524a8b09624eab2fa196c1203b1133afc86756918f38a9487e5a62022613e0617d28a49657ef750f1a0fd0eee5f9591d67dfb45e1fb044d1d158c145a4f465af4772c8a76a389a1d532aea22b53a85639253a46a4ee4543610908efc9990ebb3c06899625252c4e8d768a55f5e2dd85c697a82a32a74682dcecb713118e886a08cb26931c317b9ab361b77d5bf4315e124262526f9456c34486695e4c3915f2060172249355533fdcf60542b8818cd2f4613341fa6f814e5c311b61e77a644dba59de1499ca4434652ecb2ccbb32b9a14fe6036667d2598f99622e91f8fdf01ca925510d261732b4f85c5123927b8657617f59fa74cdfaea74567b1d3798f78cf2a86565002671944d58e3d21f6410684327b744495912374ea0b6dcee445c142772529c8aa43c95497922cf8b1331294f45529cca1da9052107a492811edff5c3c33e1a4105c41d022dda31a5cc2de7631680531dc0de717e708070b0e7e00866d00041b00f2e15590f4d4a9d23e0762ba2fb76a223b68fdd201d8f80d45dad2bc5ff1a2aa89f17ce37342125b78636bca1b77678aee9ad97455dd2eb40e47447af6bb1d2865e462dcb19f29edeb6a68e7ca1b70dc522f944bfb860976833192531269f6925d02526ef00e9875e46b5cdd08409745987762031897112935fe9c7d333f203fd1a5db13cbb11c6b6f743178cf10fe88670f211ef60221db775a769c90fe8d63180a4a4eef7f033c9a91afe4ae6f403027d181efc0a61ab6cde24e0d37c3dc0bacec1a67b4d9650d2661ffe4a4aaa06bf929c42b6c1e720649f2f6f79d882da9fc3cfa48256a4501770d3835fc9c2497f8064fd60c3a96092522b1e5a40769365f8abbe3e06bf928a9a7c83cfc05a8cc5f927e02724fd321506835b0864c371e37e5f9c7ff1610490a094de460d139f7effdace3da57433412b7a1935ecb4c83a4831668557414a6d84051609f79daf8c85d2761be304ad686b1d0832c2646d52e7260008d9b343c3f0d1ebfd8fb50dbaf447486d47c86821d02d717195b75b41362093cfa85e4d8cac30793f29684553baa05952d29ccee99266e49d3581509b515210753f4a4aa236674945d4fd599293cd2849c9fd289993cd59b220f767c99218b9f0ca1ad3ad43dbb3ab7dd3b3fb5d60d0ffce9cf5c6588e7e22ef6ccf80eea38abcab8f89f7de62e509bd4d7d489883614917fe3858d1a5bd5dd674591f05577465a56de49e2eda27c02d5d344f801b3a176885c9355d39b90cb9d447c032d064903b3a0c2fb045fbf6f271b8dd965e4f5046176e135f0eaf4941ef6c004d1fd8b3b1796d09bd272f0736bb89b012e6775b753d418c2eecee44579338b9c4f0912bff11531862d02dcc86b3f906369fabdd44e9b2eed5b7ed8b445224e8ed94cfb0b5d6d79b136fb7a8a48b3d99aff0ab94e3818d866cd68a26be2a80f1fda390931b6be47f63cd7443e1794a95fec2c4d99e272372af7b5b121bbcd3741fdd4d4649f40a0f537c9227e86e12eba7931c272883bc6804af4ecf30b161d05ddc51229dd2e6ce46fe9660ebac7706df28bbb8e7c447424a8a005f6863313cf44df30c1ce37a19018c93bbe13b6cdd40c491531bd194a4ad0b654e45eb2e12fb77d182aa969998c17d685a8e01fadafe850d1e51b553c4a2ed1421a99e74002035325f464b7be0c97e9ff5fba872b15baa2002922455235612339668efc1b4a15c9a62f5332a8323d1d5541f3ab4dc3b318ded52180ac99bf142e536305219a9cd889491ba1fb96a6dea19a49e615734300a6e5600e55bc5a13414ae7c701f5205f15df4bccfcd7cd7ce3273724b5b53b8080fd0e1485f2a377086f85374acf6cc6c96348508d270dfdee3e1fde91959d93423bcbfc583dbd333b2a657f40627686d5f6ad2c0e6bfb249d69ac91658d215bd69cee4bc3d93ba036601c4ed49f0a3b624eb60bc56e42a1ca8ddceeea6c74c2040a6db32da6a6ca3bd3bc302e2a65ec6e8b642e3196208b76f24846b844b49d39a6737cce643b6400545194da76a86c15381e46ed5e7068b2a678aa32cda902cbad78970dce814e92f8cdc783515cea7290f628d157648f303e1d6f2205c5b56ff06e18573a832e9f6e8adbd9d04984c96b528d7f8f0e47514b55e6f504ec58cc4a4c2a41ad022389a4dc0d2207309d9c679bdd8fd7cb6a281ee897ef5f48840d12ca908d4cb06a0ad31c706ac406acaf019ee219a86ee74909198549d3e39b2f6c9c9f508f95e9f9e4134594f60cc696c16644bb9c02cd53be05ef99835436c3b2a7c980f2bfb33e12690f4a0d27f6bd8dd05f5577d3a667431b175db8c8953bbea9af44e360e9ceb01afd58373ba980ca357c60df4c34f49fd73a7dc8255c182652403e77fb358e7d806ad32ebcc4754560716a50a173031ee3cb474cb5bd56bc612f6c62d01ae2d03a0e1d6cf3e769f61f403eb827edf8810fc358cbce8b40ee115a6589d07c06f19e8bd6781b25ba3b07edffe88be820b0055f59daedff907785fbb87359b2c8e2995fdbe713903100268da64faf035917bb1e078ddb90e3c14c2839e76e1a5ecc8c3d7441caad50c4767b959323d5052a77417315a864ba6e6cb4cdcd82e1f00ddabc9a39615888fcb622c949e4093d3cb4971891af02fa60a740cd00916331d041e622243e14694a5890c051b5196e21dc6bb1d1eaf44ede36e068b3692740ad846ac055d0972b5ef6a7c2fe85a78bf822e23ce7d96a71e95dafb036112a0cf3b4d1d95202bcff45fb6214642593b488f3ddfc840a920bc2b25c3f882c6fd3e2a280fd8cbac952d73d94a9d0d7c7081c9863dbd621bf3509a37544c8b9949a7625ace1ae69fdd62c146ff9417fe43b54e5de33e13da3ac6062346c0c6a9ddc1136ec27d2145c460d4a56fea0205acc56f3578c8a3e093574e2d05aab49f52846b79d8a443f3d5c2a8022c4ea69866a292bd6198f2d9a3a6eb7b2753addde2d62874dd58b5be2a0316022ad0e66e338450d31cfdb89d62a25c388775c3c5733f59430446801065e60ad4d1bf3171c36b55a65f94b582ada9236bab5a3be2850786c15702c035af0412d07c4d257947a87aa4851d6935c3e44a80961b495a74f841255c1367b56a5f6eb7b59abfdfcfca5fd82f4859ebc7a2b970f91e9a0092101a920e47c7545387ccef288ef1244b1471158237a6c1f2efd02922352cc211c7a74538bccd117c4c136a164653a3592b3fba159b568937e533c2078dad69bedbd4ccee7f3870f70cf48f50caeb875bda4bc4b1d570069d6c6a4cbc2527e8c76387b61fa8748723fc3c85a5a1b9763b4c6e057dd80f6232be17d19525254b7a2be0a4bfd1673c28a1aff74ffbcbc6697fd8dec59ad7187228b06e990c78d2d8bd8d2acc06560e53d3584981dda81ea70ef7bc030786590cd90242927b756a8d005d6637607c96813eb07e661b3c16e771bf2fcfe3093cd33811173a41ff638ad018ef0c8c4a6030b0ca44b09f5454563737bc543cbd84db2bccc9360772b2cdb859e3c47c0f7e27072ad7d77d95e7704f8445c23c89490ccdee32419a7970704942236dffe177f7c7d9a6f1f1a04898273189813998bec89b793026cc5cced0b40b539d3e896c95903c18d98e40da70848dd7bbfbba3593db0c06a431eddb2d641b0eb1774a05c2e4105dd222416030155f035a8034e351ebcbfd853ae1a117babdd64f4503e3c61d31a7020f4609f2b18f0d4bee1b069490dc6e4723e3ccce035f78a24f525e4b963b7be3acc3c0742cfaf0ebc79f3efdf48f1fae7efae5c79f7ef9e9d367b7b17c785e96bf5dea0d562637e24992667fa3c1c51c8e2c74e0c18d5322eac93f230213bd9a614d830d0f0c28594b3ecf4a83bde67f1337eec9def5a319ac0d4f3fba89a9e708ef00b5c690511dd490139cd0e90cccb8fddc56b4dc6e47204b714d1f8e40a4a29b3a37c9a003aa1bb8a4b623d476431f9dd99cff52ad105a0d97f8343fadf049a5cfa2f5f9880f472ffbfd6b81520c7fe64eb9385d92d56cec6007600dad4ed78dc5b33c5d637c91f7fb28fc4876b2b69fc0a4dc6eaf055ae0891d708b4bf4551ff170097dc8d99c97688d71829a791698ac836faf4f043e155e195d37e064edacb77c1b4fd6e0db786c7bf53562f9aa28d53f9745ce517aba26ebd3117f61e0a8524c8ea1dbed7cf3301fa37370b5406c28f1a9e6f55d660bb49691e0e6cdb02d39692426752b33df111b431b7ae73a62d29849b35eb4d097894c52231ad3ebe68a8ec657800a79e57c6d83e2480eae4ed6d80c9b3b13eacae678c2923926c50e76f0d8592befef40642c69376082b141cc9d715f61fb33233b00a27582581d7d9a7063a66617298fb8b00b172c97fdbb4cd4efd8e64ff9658ded9efaae34e74ae93699e548741b1a7a4affde518631268dabbfebdb8e847fc2b9b56620036348693723339bf1712e41e9a16c3218fd7e1d9900c921e57605ee93f82332c2a767840d0cd318720c523f73919a27a69f026e810da5a6c6ee1ad49881fbb098140710210c52dc6e5743756dbaac8c02714e49bb41cba6c2c472f381ad54bfef7f0bbd54e65f2696414e7a3d629366d11f4526502feab5ec25f5f53b95337d4f4de50cfa954c6744f09b643adb61a253774891c2d4c3530017a0608a0d9247c101e22a8cf66dd0b35240cfca286fd86bca299b61cb5d64b0c2b75bffc43678bb35dce8943944e9ed16555336a3fa9fed3626b97ec8ed4311499e03b4e4872213aa9c40d6511c2750b96624a0def378a28b0c28242795fbad77919f93f71db66822ec98313ecbc0639fb53a26a6d2778c353ac66cc794c59c0a3ad649d999d2a493f03275190af68ba0977f567413586f13cdf6b9e55650d6c5a09292b2e890b80cfca632bf2e72fab003efc4da1c0e7a420f1132a633eef52f3ffcf5bbe6eb20769bb5231a1f57fd3e8795c5714543f4a21254bed0166775347639052da63e0bec0cc376936ab21188911c263d79af7feb5f0ebe396f828d494d3b14a58b4ec9f5d2c766b6ea29844762ce7b0916ef8d598447626e07698273327b4378070133ffe032502fa609fc49625b61333bdb34b2b30d64679b644458d4cd8621fc04150a0be631c3b216bd6c94082f63801ce8d465ec53e7d6fdb1aec46a031a405cf8118237686f4713b7db80f7f697ed9352b7bd18255ecf835a88369d22b347a546072d92bd44a5db347dd89650380be9b6b0e5b0d0a3d1adff4cd4f1e7c4399ed4f88fe53a58dfb69f04bd13e32fa1a8e39311757cee80c97c279cf92b6078928f7ffeaeae8143c30bfbd736ae5de0d0d3eff30b1a4f78a2e060fee13f90a9d72a61733897b4f08773e5a487605cdd3ca0d33d6961dde47930ede984074a8522cad284074a059db02b1e3fae8bc78f6b28fd4b014cfbc14ac6465b58ba5ba311a37381eb933bf7863dc65259d1aa23fc5bd56d333a07c165d32164fe053f2ce8713cbe969c7dd9650be41bb1dd2eacbd037dd88d0fb40132ace8b4bb25b84595f9ba03eacc3603e08389daa7cb0017ea607f606c7c5dcbe94ad36cfa0f9dceb005ee4192e6536e8e22dc04f1b11d5843c9b1a0c541aa4c348817d1245e02aa4c38024b18026bbb456b4d7cad2d69b6061acb94dfedec95ba6c5ea9a098b638c9b13b41cce569d12881f4c1e3a279cb16460486ed9aac9167e17a1506c4d3a09afecfad285c471a7874a0ff3f1adcd610400eb3e9f68641186d1bd44ef40e80ccfd3e6aecd1aeaaec3b8cdd9007e79cf9d604fed850386d5ac47c72027f7c96fa8bedcadcd726e1932967c88183a4cbffa16cd9d0ddbf0aa42c531d50dc2615d87018bfb694d23856c278ea96baa74948ccef634abf73126b6c259f6ebe0e65d564fe60844100a0eb1dd942a3186312ca8cbd60fbc9ea86a346d15ae64a7d9f264f367f30c2c9286e36c1ce9c6bc9453c09934d1e23483e1f355f3dd9669c34f28ff0d35adb4e11e7715ba90832ce4c246e11601067bac97f8e18924e6724a39f1ddb76b82ba67e8c3d8e48f806c4e765287d06d173585b81f1581ffad9c4c9fd9a55fb4ddb94f885ef1af509e03a40ba9561925179d27a9bec7d276b579eb56b34180c1515e7f1fe2202b8798c93d1382d1eea4f8f624a07036930c449450703a1e9a85152618752ee647ecdaf9d54f8b4dadd2db39c23715e6cb77a8316fdbe3c2f4d3b723b2f6c43b2da09c97c38c7847949de338575821e8bff504a4744bfcf42f6e329a19da7a0e1fa6800273959dd3305711648e9ff477ee729a6c074e9ff802100e39d1f3359427f0ff83fb7162fc74d1dad8da7d058c10ae393e6f333ad1cf4740b1a3f69d460657548590c97661f5078ca69cae7f39eef780d7add654608ba93530f6601760e815c531f15b5ed83354d162d6388fad81d427e7c8a4643f11443db309472f66488d381dae362f18532371638c32261be8887aac5d986ad1aa846a3f5aeec609bc5f354fea1dc799fdf0d633d887edfd0ecfa528c93c6d268b0cf480c5b2d3c514db67c87c907413f8af10f210ffbc1f0b07f74f0b06f0f867a20df8508ed168e9cfc4dd01059da843be24d506a1f55b74798b8c9f97f0648fd34b67300763dcfe4bcca19a0973a9ebb5c16c69eef7b36ff92ca026096afedef1096faecd52be2fe8fa36f5ee19ecf664d603f2767eda4df93b34398cc56024fd645261c6071d87b8f2f3f0a609dbb63cf0442815f82b5c59b462caa4671aaa1f7ff6880d71fdcc783b31315ed753700d9ffd16b0f08ab9b6642917008c6f160a11586e2f40ce015d4409c9eed127eaeb35c8419cceb5df210a231a8810870e57f0a872036882ba36f6d4c146b6b9bf0f3d1b771cb9fa7aee2b74e858788ee07d2846ba843ec34582dd50eeac66be35c35653322a20d29302906541a8bef30837d5b37e3ab97f1bfb1fd38fbc6f44344f743aaa2e5e95982f8c5d937fa6a3a7f138345a67d15d4f3cf76742023f130e1816210037ddf90cf3f0f96b40384b41369348058fa25b82930e02c6ddec28c34020a85a852f7fbef3da2e930ac1b9bfca9647799b8d1a747a8abe828401c44eae9593722e82316f620e07a44fc240f8a9e9cbcbeadbca8450d8c642690ca3e779f6117f348b5c50199d704984a1ba10d998b9b3f6859412185c756a385b7db625f9b1530f119a9d5f49a06cd88510aec4ce847305aa5f4e0984ce24458b650d6d9f6c667122792f0ff541110524eb5a43e5813a7bf88866c1fff39c5f4e57395ca7ad9d7a7b75b3266ce0d227c0b82a8162879282a1e4049f9aa6ae4516f284e6a6a40d9e84e1395f47a3bfc5c7aba4b8eff3c72fa2026a26bfb9887774bd81177cf1c426dea8efbd235269a017bc89398c8c4ee69a292985c279dfb7e470afab01b839f8cf1a560ce9782475775b50622693a03d2c7bacb764e64a07455341eabf31410264007a7c93f5de3074bdc20d53ca306af4ce8aab9da908ab2d05933a78df19aaa19094271a11c4f1eee92af212a132a4969dda63059264e887852ed9287bba46c444cca9da3e132a9761d1d9faa193554dfdc740356cf77261239268b069ee81cffd78bd73159d21f055a10196d8888ee484c46dfc698ac5cea3d11d192bc89c9d937311e2f0d137a9e4579bf8fb228a7368514514ee7982c355f7a9145125e4b0acfa488a47eb9f2a515bc5674e54b2b93c194be86d7d774654b5f430ca9a8e4ea379e567373ac34a644dff57867f851c3de955c995b08a6d2119c06bebbaee540e436b83498260d4e3dca8688722f3400dbdb480ea59d8f1887f92426051daa489d7ae80e1129bd668641e9eb21926ea9cbf04ef4b59982d778cce83f415e90e9bf99aefd9f0215bac27f0a546222bb6fd0f07a1e2236c8e0ba6da616037da7635d476bc4acfba019b1e0457200c5a6d6f95b38dd216bcc5041f9a0995252d14ad1bbc90e090b8664289b758d591709820ae8e18059d805d649879483ca6452c57a107ec49cbbf58e392465707404e227e8c5ebf8b4eb5cc10354436d6fb70f3b6c163a54bcddc618f69e6365c5793c118317afe34460e793767276fae2756c00ae3283f6f7a32c56a6434fb0c98ed80dc16c9aa080d6efa371c91ab9e0d0c8126b26a33336c0c466e6f8442488db4227263c7de3ec3cec70d23c9eb83566fcf0d3e9990b52b549ea6d804f94b9f0ecc493fba4de71fea59df0dd7e3b3a1d2cf695e58d639f13afba3e38054805905e1d9d6e2c1d23cae984f53ad45ec421face3ef2973a8ffb7d583989bad03f2fe2894af401d7e18dbf0fb703ae53fa02cba80c8c74b206887116d5ac3ca9e81f0295817f7651ffc624376f8da7aef5d8058d63d6453ff4fbfb23d4ed031b14264cb322c2601a3d3e29a2b55c0305813e3d0f78c28e033fd0a63bf2012f4f6ffdd94d2c7a2fb4f282c6e37238c4361829287027ecf42c898162d85b7925c90695263352fab6e9e15b3ee2e33b0e9d4ed3037440b94f078c43cfd69f045a60f255dffe1d044639d364ca6f86240a091dfd82148df876a11b2bd277623dfb96eb7158da81ca56dfc1a0500449a67c629e65cb10642a66981c4459b34b4c33624e74441e9b3952e9d1570ed26138d2cbfcad8be96736814e05a4d662bb2d71bf5ff5fb397082995b4b590322a02259002090ebb70de887c6b3a6121a0039d8960ee01f5437604ed6001f2870163139479e75af997422484ccedcb5838dcb35eb5a94b1e625330763c0a28dbe616b0be8948ec6e979394e0d62de7ef9d494b7c007aefc2e8be6795172dbd2acc68cc8423768244901141a98b4050789197003146b479c05235c11d618ff5c3f3746bcf18cbe13681a226a68eab37e98ce66d8d51fcc41bb90c51928f693625d9eeba3f7f069c1f569c18743fcf4facf5ae71c78c326d2aa854cf1bd3bcda0e4d68b83b929957e7548b73a5c673f15480087708ffd80223c660d4ff527812bba900e6a67ac2e2c98bde32b3e787e0b4d0fffa1e9efe7e0213c7ad67b0c808efd126002647f1213c08598dd3bf53252e107d0fb57dbad70b36943743fb104da66f7d36a868988f6e4e0e038a11aec64e6d8c9f0de1051435a6edffdc6e70a0dd9e9d950b4e5c6bf93a11c1651997de55daf3f1336383be928658a74bdfb8c71a3496588979091980cad65abda5f7e0667c33828ee30f987a07f13e3ef43bdc83f0c87fcdf9a2fbf4af95af239533c25ffeed27cfcaf0eedc95fbd0cf1f2a75fae3e7ef7e30f573ffdf2e987bffef0db763b7c13c7df8cdebc397bf5f29b97f19b3723f2973af777bfb772ef65fe59d0875596e759c9e78548938779b15a1522398e4909ba0370792a93117fa1d9b2ee3cfc85cda5f98755262ac5f732bde62f834ccba2927b595ebce6af6c9eb3973b92b2fbbd2cdfbe7ee9f3bc8877e48ef32f75a691fd54fcf25b9febe58eac0aa1967b559dbd3efb96bf76dd3bdb917f574c2a2ef7aafbe6db6f5ffa8c2f77e49eb38eb68f5ebde4dfec76e477417fbdfe83cf55f485df97e86711582ffebdc903f0a1aaa5efff6a4adf5bde657acfad9c22de461cca4420bc0739fd93c541c7ef0216857e024ab679ebb698c25dbacea4330642a6466005d082e29c9663204618e553246931282f2e4678389a6db76004951964db6307a9f9905beba86596643b20dfa76a762e7041e56064680308cbcea66a762170508cd9322595c3918bb1ad5f64fa85ae74b7b3ad0721415e00d2e844ff4af8d437fe6c9600a26dd1c8b3ccc23c239d673423252da66a36cc000f96961324e0373e2d81b046c554eab772864f2a1fb97f2a6783bc1e6b2143ce9447572c656bb8031b77d48a03c704d78dd41dd86ea555ff6982d2c50b70d5d62ecd0c3026182a3026a1791ade6e5141f73ca0b389301f4105c970e21fac61d531a5c5645024886db7f5c78e7d69a83443aaeb5b415db8a1b29276083ac406ca8b0df4d7c76e901ae322298ce1be96a28ede684cb9245c6e452552b8d906f5601be9c8af0b2489cd813191750b597b43d83056bf8ba65bd0ef22c01918b3f37238324e4216a4ea6731fd5d4cd90c3c39f8ba9c64e66ff21741b2c81c22fd7ead894062a8f0292a4e32b8ac303ea7d20d085434ae1fcae16856b73893fbae3ed31948b14959eb1c6ba79fd284e99c32aaa67236a392648d909dac2352a7a618ca7e5f4c1e01960e97744907851f6a358d67e664220002a5a6b5998c7d6147b51cb3735a8d992ecdd214313222126394513d041620454d330bde4d8fe35a7ea4f7bc9e2b81930c9496850c6dd7f502cd58dec24d36129276dcddb659525db6618cd40ea5fb04a0d18a0322a0fe411f761047c00f1815fceee85f2aba82d89a2ab2c9a5a6db6bfdcd7f0bd4d3c58f6cd06e67164020d53ef4ec9339407a98ec97d2d749cf5d2c90df5e2cddb9d9c6e5669b3a37dbf4f4de87c1fb29a0a97f845694c41d5a25c2ade134e3d60569f448dc12777706c6f01ca4fb5cff6d7de1312c873febc410c6b073ae0b65bdd2d320b4dd9ca6e6c2ad44a6b6db5ecaee7b6441ff22c892fe559095de976bfdcf150508da261c8d879816f4bec60215e0f7756576a894a824f7533ec3616ed4f2a400febd5dc321937c0c9776ab0667100e67bb216b109b6a96527f753de533dd0103d4c7da407d1985661a289895b790d4a5a66a463363da00955c593340cd6b6db7684557ce25ed4a735f7a7bd799a7b3f155ed16bba041d8b82b08fd1104955b92abe9557dc860dd105f7445c5c5e8a062f1610707e8a1f001ba876c2a299faad96cbb456c2a67f4387667a8acefa26c8756382a0ba9d0df054e56fe2769b47db5dff6d574d568fbc28ce8bf044a31de6e17646912b834094bb2a00b4ae95fc46490fb63f79dde64a2b84398cc71a20b2d29a57f853c5ca4ed1c8351b22465d3327f419698944d8bfcc5606452af14bbce39a01744577ad9978aadd6257dd02b275911b79892b5c17a2d93abdda326cf6da171136f4b060ec585656c2bf8b5e224a7326c034975b3e6462c61e2eab0359b67ea1e313d9ca50d8f4c961464854a66d795ae1c663da73dddf61ea57411c4545ef4fbbd92cb8c97fa6939c9618b243dd339c831c9ad8ce590ea0ae40cfeec687a49dbaee873c69c1f4c22988fff1699b2b5909cfe1b44401e2cc264f6f013a3192629ed69fe48b7a8eaf7cb282b8b7f72fe2565f7644e1559e8d59d2d90a68de67490f90533273d9bb5473459d47a994ee040038be628cd160b24882215be18f1572739564b59dc1da941ef8889f4a83710fa97e447aa288e16baef6b26d5d15da69647aef147c5e2a837c807bda3dea0b224c07cccce85a600324b01e4a4c278617617ab0da08de4d65c463d4dac46d79a9a2bb75b9f972c76c81ce2736cafad1ead73f6fb797d26309a6b5e20a3f9340ff69e5e871249bdf50abdd3f4044202972621b3e8cd791bbd1909f0abc11794f5fbe29c66fd7e6a1a56ebbc608953466089d38cc8e84a4f26adec0240a58fa8306112557e3198bd617686dedbadc5e62d7a486151857f0f90eab28b907a15789c0d87866efd5d4cb319f9594c8b99275103d219e69c11490a7c41d570e4e8d322a04dc5a4517712cff41ca45eceddd505d0095f0145a75f4164d320c24bbfdfd3acb79e643b408db3db31a8aa49930f46440454bb3bbab30532a4b99ab93e0664b6d2ad35dfc0166a4837cd1c74fb5b3a5ba09eb1c6ec19a6e3d85d150e4de5416fe94491755126f18e9847018fa39db11d09c173a7337d72a9d9b8361ae46da34154520ec4b0eaf7cb73e19755694802bfc8ac235dda2e5fd174ca0623cd21a4533604e6369db2598dba540434566599148b2e520d0a7c7a8629a5e5769b3b987bdda9123ac54e51361ce19a71c86140eb93d99015bacf4b98750378d18688682c6152d29854de1efb8879940c55efdf8c822803e8d41ed11c07e9ad8bb28749494760fd6ce35a8f8659829a79472eef30c3a7679ac96ebc0e98155767d5acb34850313c50e8cc150293086b985a82616a454c589b64748acac1685081f6c12e3792821d49a16f5a2ba6d5535d03ad64fa184a1b3be7cfc03082ced3df448c8a40510060110dce1b642470b3f5fbfcbca54998b8e7299f25bd1e202d74d8838d0313534b5396186416a2c5d097585f31aa287295ad0d3f3171ec041212093d2cad0c38d99370149322e928d6e45380c3d27dc4c6b2db24ff6847ed5113947af89a11ae40bb0d7c408b2502291214d427cc4cb3c2f0e42790e4b49856fa10d067119953ab76210bbd11f37e3fd56b00b2932565ae6f9cc8ed162d2679a2476e451793b985f99f4700f34fd64036ac6af3c05523663999d76fe68d3775dca3f5648d96065e62f99455e4334371e903d985df726e35cdf187f8525676a048e0fd221bae1cd668ff50903d7bc8683edc629fd93d66b72bb75b74cf4e620f23d2c6e013f8444566f33e1b5a93825c2b8c69a982735680a0ca053c6b9c96165e13d82927df82dc523aaed68bec643b48667384907cbe8f538d67e47d9c40fec2cffdb977e0234ab38f30672636d6b3fd591a337510cbe1d40dfd10a2206a8ea135ab7a32891571b466d513335773c999e230228d58564f4538f4607c60a2a5360d4517778a2eb91f77ab053a02764d3e8839d835d5614d581d7c5a7a5bc01280584841ffd7f37c2f9c75d35d224ed8a038c9c8321127d9a03861bbfaa66885966dc36b844303ddab4b3a9eea39b1389cfcb67d24322aa702c8ddd976ab6942af92028789ae1381c4faee5364ca674485b71f61184c2e9a6dcebc4faaf325dd9b08e3505044773e8af969112d3b4cd31ce1510e87a4bc88279a8adb6152ca0e4c5312f29589a31389e13d12c3611227e74b1ef4edb3e2c98311db25c723a20745ff05d24bff680c9d4ea8193bfd6429eba4170c62af59487fc73b30f9b88dc72362d8e1c4f0ba56fefb60e9efe478b4dbedc6850c549ba5343eb2923ecc99e23785bc4fee05319d4cbe0812408f243f0822f546c8df9bd7df0bd3d742ee482e415e003770d2bbbcbc3c7a478e3e7ffefc991c2d93d52a29cb23d623a1a6b267d3a38f1f3fea77ad64931d549190a49f41ebd85b7ed703dda2f94acfe8107b79deb38a4248d79fee7995606ffaf7d9df8f86361514803df8bd1b3b616d54dc7229b394a30e950c9f3c5c6569d25b152b2e548f588968874f422e7704a63e091c33c441f85ad5efefa58989a280c78d1315066e06b133053509d18bff1f2ccf5258f7d6d50fb963da34afb30547babca7a5f08eb0346d6424b2995533ef3ab1fec88e6806f2d142c06172088e8977c48a1e0e95307daa65169452315181b403855f4f9417658846a34014f6489f8da8ac59c65e1e41a94699dd2e79d861f2b7e84a5f873d733cf7c8c33aaf20ccfac322cb732e9387b52cd6ecc67838ee763be3f09d9a2dc1ba291ae31206949491464bda81a1aecfd57e5fec0b7c15eef7a5232ba2abf932cb53c905c444cbbc2c3788a6904dbaed58cfb37e9f69e2ecea36e37746cbbbb3eb08ce3826bb2e061eb997fa7a98a8c8826b4878b887879051706e7493a6e19e6bc554cc761d77d783a9155604d79f20f72e414e78749fc85dc3f971ded6a1511e5dad8a94e710154f0f8c1ef506c44f065ce7f13103a3921b38a56d049463cd1d66664cf4af3a2a6ab640c77190d42b647693899e89da6a4c8cf282299491518c8957ac4a6cf970738749cd813b5aaf37ec1d539a4de359bfdf1bb8df00bfae06ba35486a6675bb95e7f1762b2fa8d06b605cde656abe44197e98b392bb5b2bf1070e93aa378657aa58fb742e529bfa95cbc227bb6ec01bfb90c083a9c8fcd685131f9dd55e26890f6659eb3417815503e211cfa32b50471903f74316cc8744fa5639e96be946a4ea32cbccdd764badccb40e5a0b0bd5f0356d93758319535823ec8eb799480cbc8fa4c5617bec180ce80080b2b20094763429a5f9760bc3a97f4e1ea98491a0cc4425022745d43222470c93205a9a37590523d1f9864a08a834bfa732ba27d652db343c30976381593d26a953fbb8bd9c4250e58e09b213536f36495b130ebb116621f33c540d19d8341bc816a8ee2f9b38bc730328aa2bfc1e96f944ba28408de4c40d6957c94fc57a222104509d50c391db343099cfc2a7444621403e1c1acd24e4d937e3d9598708893601879845f77564636b40610721f3e6319b046c995b019226c62c86dc27cac05264ce6c06464d4f4dbdf796fb67a13ee6ed044c95d9075e6a6a22e38e8f4726f4c9108ebe20f889310b3aee983006152169c4998d335246b7e6be0af27aa93ea3125ab3f307876ffb4a765c943d7bdbf57cd85cf0818481a81792c2e0cfda73d7530f93544ec50c711c0cce5a3675d1c73c2abf64eb3ac395ec94601200de96fd3e33026bee2c61c136620302cbe85e737aa371067ad40c7f8de64cdcb2d299c572a2a6d97034d37f66b87117095d1cf6a5c19df396b420e08d36c4fe802f30d001c4e3e1b0eb1ba00210e6435eff6a6272c357e61b52da5ff7a4b28ce9bfa5421e57025e6e860539c38366e2fdb02467b8dd060e06e34604aebf6e3a62db601f8e631c5c0ff7c12093cc3a3db7031b7bf12c595319956b26fecad6a553bd4f67e496c6e486c64691de3462072bb71584171f0c0a9c528172aaa6152dfe6b65291e521189c99cae25ca3159e8bf2926590092b7ecf7e710cf6735404b5a0c46189379bfbf98a05b7ae5f17b6ee8bdf99d629cdcf6fb37fd3e5a4fd0bcdfaff32cfafd2013823506419bc90d26b7f486c675b7301e37dff386d53b0fac5d997d420684f756d207cdac18e2b447d8427169c9c7f2bf5bb62e1d30f6881f3643004b244fed92ca09058d4552011649e6742788516471fc439a5662ec6ac6fd3eb33746bfcf4256e79247fa0a8343f6c11e2109dfa7822526ba97c95c5a7d16011220e184e709db6122a2bf9861a019a9fc5dd66e31ca6835953388090c2349971255449212dc22ec49421712c0a9a2155bafb9a42bfd8877e49a2f0ae9c26b95efdac1d73ac22b5abc9d47c273b9008c36627f556bfdc405d5db4d60a468351533d741dcef2b77da821e54938d11cfb15de6fab66ab20905a09aebae80a4bf45fd6eb76d7994b1ee2efafdb2dfcf6a8d8d3f7ae679b6fe4e72867262791afd84c9bd4439f49c9192c8e82a2f8a3526be5825ea8218e3dd8edc48fa35922a076d82cabfb3c2f96be9c2c85cca3d1beb9a07b8934d23dda82a0d12376c967e5f732e06c9e2424d54523feef6f8bc9cdf70913640596af190a6a6094497f5e185c9a2caad1cee382696504c8e47e40e845160685d88b779535a1be873dcce30d1bc5a61eef742ce0b3c6616c3815a16c53d4f8ee57e5c27f3caf269d67a4b73c185f85b71cba5454714ef39bbe5e6c11a413cb8214a5ec6c4fabf26a398dc70c125b3b13fbb62d5b54e92861787195c4b2a0aaf9572bf9ad316c404f41ba715d0ae09b4209c82478461c874595d1d9293d8d27c5ebaaaf846256a2a1c1cb70904ea4fd9646f87103b9ec71d0793ad058324ed2d5bebd2e0d9f396ada13ae21c82fc1b70176aba0935deb928d099e0ffabc8847fa71fea2acd34b977c6e32cf066aadb013d58fb014e58543fd4e19d998fb84ac2a599d8feed76269814442d3513fab60ba928b4cb4a8b3998094646f6f243cef513ea5579cf386a3696ccd8fa6971f59d3252588e7af39c95658ff0284b07bda1f96e0f13a399ca42cd941a0c30929445fa9c13e95b7dfea1432dc8b31ec6f859593519d2c3382af570b51706cd34a1dd5e2d90088baadf978f7de413dfa85f8a94a3ba040e00038b4a71f9b74f97ef9d9c6923e95f1f358fe5f8e1abcb60154dc63fd88cdcdf32f57db101100c1bf173a98f039efea4f88ad6d0a76951dd2c45a52e8b94d3e391bbf82c45712df7ec68f700126a7b99b028c2c67cc4b8df71f3605c4229d89730799389920ae2ca7d0c818b90452268a500d5b39fd154f07d95e5691d2532ba6e3d43e1bd4c50f447138d285ad8bf90f5c7f021ec55263e665ff98e042ff448757443273f0f90a91dc0ba13a229e70bbd1d6c945bea4090127400bd49156bc86ed869ea72e11ad8e9bdab31007a0a1e41ed1f2618561c52ec30d00768441213537912efecc8ec8dc4de344162f0f834ccaab946e07e1121de8e8a9ad716995a6a654638d68491718a565c021ea0d88f941ac82ddd4b4142a760bcc3009654fb8659bb0fd108b063b69f09a42dec48b4bbecd69c7e3888c2b367a46efa0ef16b2ced02c217e3bd7fc817b2a0c667c13a06b58f868afa8904eab405f19e2d503e41d5fe5aacdc829393519cc438f1994c429d215891d89a6531e36a99f928dfa6db29e5b5c76e49a7f10c824ab3d0b7d200ebb3a73c2b83496878952b7770dd198393410118200d2531d46d35c563141be96c3a4d6b43a381047745bb252e6ccf35a3311fd062e0df90a01452173104fc9cd1181380e879d09d4962a28a751213b38ba4db45c58e34bf49655df10ea2ea9b9c033adf05f1b1eb8febf99a1779b5126e406764e5d3cc8c94c6e8bd2e744563724fe3f1fffc48023ac5fda0189c9d2c2e5ce3353b3da057c1902d0d3f77e58dd3efb16b94fee10d9daf34837faf877bf1acd1d443a63fd5f9013b8303badeb973d726d5b878aec93b8bfdd7c846f7b2d1d8ee7dbbcdc38db5af6104bec305cfad51b20c57b2dd06e1d23b73b4a3833fef1871ac2070210d7650b395dc504546f804227ad331039510ae213844cc68e58d2d6c426b36bcb95332a7371229cd09da0badbe4aec3e82e079fa545bd24bd9f0e3961d01ed57078fbe355dc1d1375e0427c8bcfe8dcc6982c9e2c071b2080004a25764d1401058924520ad81277da8adeca13636d1e06077ac31b9df3b7dc96d685629f18355f9a808d84fabf8b10a1a1f8fd96e93f19ec6860f654b6783f8303832f0e99966c2f78ff894de4c1e36890da47f8b2a9283cfc3bd8dc15f6f4d3d1849bc4beadcf53b97fb1615a484f23637314cbfd3c3eb83c1c7d741669a8d9fbc4f35f4ef350d3efdd471a49ce9df922e1a47900a8f20b2a25783f5e9d960492e691a6dc81d4da3fbf15cd39930c9686f25de4c20a2ebe5605537e6c276be95b9df4750df805e931416ce6060be431b636bdecd304ea0eabbc1f58519baba3e7f369ae29783e641eeaa082f1af74168020de7c27fcfb015741e6dd0251e1f37087a732f1f2383277985b7dbab731a63fcb0b0f00863035d7929910c504fb29023056a21dc1390d93f1286ed867acbd675456fd9da57e3d868973180d6f0f903a639dbe3a35d41cd3dd745f493cfec196bdcd8de456b7743e120c1b4be8118d278448d06369a8601995d34451f66b996f4ca20ae7cfcfb6f9fce4ecf48a5a7e7435e958893abd3334c72aaf4921d7bc19a3ee80d30db82c890bb370276e9597b1797a4c66d98c332fcb190efc11afa0a1345aef4e164cdcadd083c9a79bc68c0b16cc81d5198dc4fe5cc70278d721bf3c26e26f8ad5992bb43d83c747d7a46b2700c06c66a6cc0c68b1afb41c0ae06ac3f22ac00acdf478b869a209cdd33b2702a1d28b4701a15f7a54c5313f0c2619a60db3702a7401a6d0634380312b3d177e0ccadcf373b26cf39de76d6a4d19f64dfa9c3927b0fe4c62f4006b250fd3e3fa799e100fb7da59355b1eef7954e3574824535ceda378ea0f1589c7b97c0c14060533392944d05e803ec07a439b2a43bdbd40595fe3bf06be0500bbdde333c9ca762167a7dbb402a3fdc72d161374302ab7747aa30da5b1555c92b208c38c43d9af4e67936ffd24bcc23289421939e5c500d9b734c4656fad9efc36f107eda76ee1c7a81adeb589732afc6ae2c08735d7e4545d49e30c4a30d8148f9b616504bab7edf970e7e1a1757cd4c0a882049144e906f56bfaf40431dca67000aba99e0f3efd5d6cc895bcf54735df570d826c25347bbf06e172063bc6f6022087e77b491e861aef4fd0f085a361a8e720a9a1d1eaf54e46312204e2078d24a452c4dbf2f36601ee479642a4c7849abd9b2123f726529cf64e338e59f44d66d6cd5943a8f55bf6f9bdc12633d5dd61abf9b6a26a8f69c56b505af798d8998a0ae5efaa54b154e6c3b70a20fa6958a242c513f0429cfb9d25c84add3f20aeded110252d8c6c155126c263068239f9c1665bca7ee508084536b3b4606821ec4c3bdeb224f5b0a8e4013d0528b802cbdd7737a8f33fec2092b3fffcf092b5b33f7e9ff0a209f2980fcd42d80fcf47f0590f548ec0b203f3505909fe4bec0ee5328b0fbd42db023fb46f52eceb469e20e60845bac97b7b79f204e83b80486bec113f3d75ed7c9089f1ce07403b8c55030459413c9d9bfccb83598adce89f2323cf7834db809b46fe57549bb86fd22a198e3d36131c73eb8b8175e8c9b2210de1077f027451b2d1cb94308728fc2c5858095a4a2e5e959c8f6d218c0c355b186f0fe20b35850b7a841ce06dba181bbb987f6f43c3cba3d18bafd8dc9e87c8096c339065a391d544452fd982066e5a36016e78677321f54c97258415eb418a6ba9ca48b614a72ea50865157c161f42a895e815dbac7c8ab31f118c9020cbcfccf61e08d4d904bb3c09b41395636022504918cc9158dc757e7ab9a66bdc2010adc6a7a352331596bf27d3da0a531880a33809f26e0fc056c4b48e4bcdb23723effcf103970f17e9f17f32f96d0f928f539f0aba4b792fc20e917493e58d207b20694cfe767533e5052133eeffe34e1034561ebd42d3d48fb4096e7913eef9e49fad45fc5bb9d870ffd431e65e2e8a3111c70497f95e4a37404e30ff00005e907497ed6c751bee6b2a45f497042d4f86b0d62617cc05d834f9c75f74f42210eb6ddc31140d8384bc9de7ff50c0ca33c1dc5f1898ad64c72010a5dcd37e1446a0a23406e0b0c118df528eff77ba2105cf31b3c801d43a13162ad46b707c33f327e07279766403ef86f9a532b8b6eb87a6b226aa4c60242e0a99c41b4f4bd5705bccaa94225262955a8c2647e387eaef37cd96ed389471cc9271c95441086933949271c55a480079c98ceedbe46774b2e792b9461638373dcefc3af0012c828dcb0b707b10a38852dd4d834f04f3692c0667c5705b50a23d0e7000a2976e46bb4c8440ab60d74ff8bf6cda44d58068db059c0ed64b747818ac00a79c213e1d7b0a43168e6ec9925cf9931a15b20e5792e3d1992d470ec6e750e47aeddbff08dfae7de60ea0fb7d1d904c40ea2c3110e9a2006a3b13caf1be122f332c0fa03d17c68eebb739ffd20f96d5654e59ffab44756081b301c8de5058dc7d2215e3ff66917d888eefb8bd880f381ff05c7b8df0fe262eb0a58be2a4af5c3bf2b96b7010b9ab165d87589f850e1735117fbe7b2c8db8bd6acbc005fa186fa124375ae77b418a80b4da24060c78e961ff148f2b49a73843afd744cc7149ef0c42bb6e014c7e4508c1de8eb2a13ff135fcb44eb6b7bc7007cadd437baf571bd11938e0ffb977a2ebabc55634a11a703ee231243f82a7e114f468959f1de1db7b36327c8b92f8cbe8db1c96f81cb0fe41f7d1b9f3a306b9dff2a35aeca1f72366f156a9aeb731ca2968c4068162e8213854f953ec4c7589dd0514cc460e0d7052ce51b6e023cfc288b15886a3b17968a36431e813d60743fe4d1bd732b067b6d712206f2a4f62e668a893324490d4f939d0fa3570eafbbdf47d980d6f0dde4012cb3930cfc5c9998f3c46c33f7f83d57779c0b685e3bf06c63521bc6e3aecda1edb86bfd19b6db306325784e744ecc7f9d511a4fe2247a059302aaae76ee90bfe7d1bc92fada7bc76fb3b971c9f88da9ac208c0a1f22e22844415143864f243e950306ab770d6a864ade7681c4d86309fc04262ae124a30ac2c5d904e1dc939b0391459b216b0d4416dd0f9919886ed3fb22da0cb356a122ba1f66b6504ecb53884b42525ad95f732a4f504ecda6c9f1244ec09e5d9ea0d426a63a31f5068f6b7b7c270f9b44b7727e02df65d10693fb44b71152a0a9784704df289b75b068673529362b2c9f1f3e7cfce9fdafbf38b2c13e6eb7233e1cbd6c0ef665210a55084e9f309b86d04c881b7bf4a6b967ed3108e6e48973fbd334a4623f273159fdacb97d40c34af76339cd1da8d03192349d2afd015d1e2617f6bda0ea229ea453351ccd1267e0aecee7c3914e1cd844dcef1fb34651636be1d23643e97e8d65641a07a1ae1713e4f2dcfb3cf7f87491c4bb63137ddd573a91d1ea67ea8a27c76cbb657baf857b6d621be913d725e1636b1c00a9ae1e6ccac509fcf19907fefde9d92e1830c04955d88c1661d40c029141439acdda6e51f3eaf55f26365c895d23b621ccb406dcac563f9ffacc05bca99f515587ecce9a3b46ef9573fa66bb45257d715aefb30a44633fd3eca43cf1f5c0f78a20055b70c6708574ac0e70376aaf8d8ea54144bf7f1c4e63bf8f728afc7a18ba771b7cfac28fa3355e364e8176c3fe4eeb42f9a3393ffb9cf7c3fc44f71913d65aa2a6191d0bf4503334b5193461d0dd049d2bf8fcc07e1e4e7e7d9480c6e100f125269a58aa4330f3693c4bb819caf69b26c4b3cea2bfe0ceb627be724ee3fd2af41ffb267609d0ea6cce7fa95687693fe3d3fb35ca8b9b51aca90322296f052577119cd4449e8fa257935122cf5f4cce1279fecde455328a13794e47904acf2099be8274dc0a370ed612fcdf152fd577225bfd28d98ad35ea529ed4cf0b46659ef329116770d528c23bc4b4c7a5807e882a1a2edd6bebde3d75f32f5dba37956c5d7c733144f942f0fbcef200a6c9192ab4fd98a1715f0e0fcc5e96b43e9dd70f51bcf4143e57c620f46cae791716f66392847b65b0ec6e78ac91bae9fa252ceadb9b78972c4d5f79a6ac8c4cddb3ce34281ee1b83eb8c2aaaf99297e3b2df772ec717f104095a827f1d64ff9dc8f0f13344b467c14be6dfd8b0f50117f3b5f65cc848cf8a1b87c6264953034f6655c55ae74c9fce6982e4c23df9645e2b7c0564d3c248368705483d87d53005504e93655844aa580ff3e1bc8ed4d5609890f005f1e9e224b3502eea104da7c90ed9a840ba6fe0d3e549e6e05f0e57e0e8efb7852895649930863d5da4a85e3bbd15db0ca1513d50e4729bbf87f7eab19aa3c72a32adf3359912a6aaab39cbe755ce14b7b12d0e1c5f48d16052408cd690415d0c471371e265558a8c627c3a8ae3a499049f6c488cf6a930ca03219607d3e9f77bd302e0df8e3e2e595adcfd56146a068687912a3e82e40c6108caa4a265512a4c941dab4bb6c956d56a7fc05d70d4960c8b83c1d0b1aaa53ec10cf8d074411a91540c3bc612a9d6ee21023f95cf6c0802604e5d2b2660f60d99cdf044d66cb3240c37bbddb13efe64bf4d0dad8e5b9dc4337a0e2adaa73beef08fba7a6e3ef6fcae1b4d4727f3e8f936c833693e4ed52ce99274ee0b2d39f8de1b500959acb954f72eaa80b92b5526d8c7393b20bc39c83d52b5dd06f7ea71f35eedf7ed9594b68a6db7e0003f3aa634e450c1320b6e1f6b229b39cde8b856ad9d08e2b468d9097816a88d01224002a2335bb723937fbb75cf5064bb45cdf7940d7aeb4d8f3472d10c12cd2968b4fcf2f0590368c0bd01d7658e7a0390860501690f32cb485269a03e52a6c07498296691586474c3e435bbe16f8b3ce773b59700ae1826909dc1d843ae06da5dc174464c760a5a63f36bdcf229a73159d0460c8882c6e3e27c312e0603cd001a193ccaa9981633cdce69ee2c8cc78be7f46bd378dd401393dc3ad93744d8b9d15119e8530f2e5c9e57e37230c0c66b13a5349f9633bcddd6e552bcdda2435f4aad89e6d23bbb9978f5cb0bd7332398325d5b42d7ac32854db369319b8d3360c0e71cc564891d88c41c2486f5070fa3b9521584b2c8b65b6452286fb49739735ae1401f30c92e0ce861868904aa1ae403bf2e40850eb8251d27e3e871997e5363e0c8f90b05978f173843fc27fd4988ce47efbac4933cf4427f0bbbf5af92a5fa7c8510059d3ed198dc1d9266ce0b5116398fb89485443dc81efd511e89421d2d34e172dcc384db43124cad8c07e1f39af68129c5a5d86e1f69f68427b6c788e3a864aa924c7114bdd29b527ee10245231cc99b6b7763ef7608939f9547582ce9bf947ef6e439fd593f32f7f8914b7df4d1df756aed6b5bd2dfb94eb18eb16ffd0b2a20dd43d0fd4d3f594a9bfe553f387f027a09397f128a4b06c34119342567f745a54aba82a775ced4a2902bface3e023817fd084fe6c45f0bfd1b8e50d7dc5fe1352063520eaf3f19185afa5505ea42b3de2ad9f668695517497e93958a4bf8dea7fb35478a70c26ba83d587e1f25fe28a3252b7fbd13ee96427f48dcefd70df755a18f72fa879ce171d0c7208489b5b47e2be9cf3e98d023f714b217d5db25938afeac608edd83fe6d8c16a957a1464ec76cc649e59c3a8d6ae39569b61bd6ba1ffadd07f8f93d2be1859d646ffeb58336983bf16f563b1b8cbcbd2cfd7c079fb00b009a0d588430ecf09d4bb1377bd3def74cf648effbeafa3ae73dd27b673d597ba4a78bf748ef439133f99de4ac477abfb114b27f9cc3f6eacd9a87cdcf6aca67b413674ef0bba39f35611db40034e448c0adf7a0e724319e82df2914e34815ef8b3b2edfb292233ce0368cc6482f161056be953b14a8ab95bcaf7989177837674a9f86f8416f5abc23edebbb5795fca854329b2b634821a940679a9e13e815261915e8350621b630f89a48a0b3976798083402d9b47e516a0e53a017105c56a06f356b28d08b979aeb13e8f56b4c9654a06f5e63b2a2550460c6774ca6bff1455bbbe448adebf283e48b6c6302ace6ac2c7f612b6e23ab1a840af00f622599d79ad37cd24bb3db5e92930575b14c22861127d39eab11582a5b9ffe6d6beb911e2b7b3506b28bf186525d81203dc16e8799e2ab1e26ba0b4d6fef39b1b9a5cefdb0230bf220f92251c47f2b29104619117887096cf5f1ca5916fd0292995fd8ed4fbafeb1b15659912b2ad0cbd798dceb317c83c92d7d48b3d201751256265711db919bff64485d456644fdf8ea215d4abe00db247ecb85fa99df837d923ec5350d05164aac24abc706d8d5de1a6b5d738ff45cbd3dd273b53e6bf4f34c7ce91cfdfb88b5c77f451ef4d7929c986970df4ce67adc96c40f64465c1b92456bb24a2248d6efd7bd813d87f1f8666fe2deeba6911b7765e983bba4b7d6f7e8865c3e678a48465664ed3a9e9b617dd0b7da2dd72daf076b87c9155deb59b8afd7fe955dfb57e496aeebc9bea1ebe896c98c0945aee9da20655dd275f44755aa6c714feee83a12ecf69a49b2a1eb602dbcd74f6eaf7dd1df734d219f1a93bf26533d7b245c01f6933d0218433dd2b39febc1545ec3e979681bbacfe8f570db5808b750ba67ed84dd2b0002d1d403df288ce611c3e45df7bb45548715f93c4119fd5c0fd49d0548b9db6eef70f20e8207bd8be64ca67fe32ce5f27b9bb16b012edb0b9095c9bd5d79f5047e69adaf0d4142332a627a3ba3c777444cb3416fa83b38a3fa6935e80d7b839b193d3e5ee94cf5e38d7d84b19dd16bfb68c638e3696f462f21ac31f984c97b58b3977b6bb6472e9bebf5c1ce11987567799e1c8f76e4320201f99a5cea7bf40bbd1eab88d1cbe645821f78c437eb4206eadf2303506bada51420d33eec405c2180e101db2c701a116d7a47620fbebfff8a641e06772a67e363b6dd3aa8dca99c1d539a4df40faadf263d237fea59144f78c1e10fd1efb1676cd4ee59776370d3eec675a7e51385fda0b440e57854dc092edf59f9c576eb24193b11a548911eeb11b40f212c77ffe1553e6a5ce502bdf826305eac022b19beddf6fe1feb2b23b395c50dcb69f1acab86952444559cf4582f31f7b5bf7752b8537ee6f7ef8a3b41e67bb7091c28c13de2f3f6669aaad86700e7e6e21274ee5c65c628df6e2ba430707c6b097780b3a0c5249ff0a854c5fa83c52a83114e44bf0f8627ee98a890a9181cf22359e49c9a3fdb6defba52aa103d6272d816c0c06192437ec5ae8dc5d87044e6d39e3e1487be53337a1c6352ec9d2659f32c81636447e6e4c10343113f1a893fe7186e2abb7b4766fabef07bcd97eef77f01788798a4ee5acb9b47c447b6e0df89f9b200cb5b46f3fd15e716d9376ff078ff0468c8f0ac45e913ab56455757bcbc2cd22ae7f4382640bc7fd1e737cb049754b37a29df3413cd42b32b3e437a559f61bdec33a0555fe2608d67edfd577f6fc29307e7f4cc77bbce4f799ff1bd9631f7a67d32c29e180bbabf8bd5322b77088f35c92ea8d86e3573e0c1ef7b41ae1e4601255f9f696d064e50f313efead91087a7edf5c81c0e676f5e98e3e1eccd4b7d4048403f35dcfe27766361b03a67b861984a299ff85dcf275ef8ffdf8ee79cf5129ff84b95e7b35e52f4fb85be08ec3ae678c210c7899ea7ddd3974ca7656c7b78f85e4581c5ac3f3f7a46cc145af2f264a0a7e41d539c744c203a7bfdedcb17af5ebe7ad5478abe3c7bf3f2cdeb6fcedebceaa317f1cbb3576f5ebe7afde67f23455b2ff7535ebc78f92afee6ec9b38d6d9d5e06c74f6cd9bd1d9d9e8e500a9f3f3d119eed7d9f1ff56171717a337180f5e7cf3f29bd7a3176f5e40b6578d5c8317af5ec5af5fbc1a8d5eff6f757eaeb3bf3c7b357af3e6c5376fbe81fc2f3a6a7d8d313e75dd7aed0ec10730ec3964aa6774da02e1136e6d80de15d575ce3ba0ef05d8cbd7d3f82099488b552288f9f193e292a9427678ad49aab65b6150643a82144bb018b091e9f4a4fd60c469f3aa54c5ea37a8fd282db891abadf4563ae29b359f2b9e1e7df7e1a7e4489747f8a83e29caa355569699b8f171451e1685fc81cd970d307843bb33925920461e02311a1c46464df390188c00c06cca66848330742af42f31a3195128d3a7a8434d54884fe319de9172592d16f95ef059450461d6fa24f8a6826f2a2cdc37d5007679fd253e55fa979a51e631f376fabf3f455040473425013ed5202428e1b9c0402176ac96ec10ed100a48b2bdeb10d89a367fa70c7f2d0292ba4418a9807fe1f65e7b56c7cc39684ec1577b3d2295bee4ce8c946304428e48a0dc8839cebe35628e6f5e62b2a408494de64ee7d1f58cf6ca6571d723723a8f58fd84c98aa6cfa2a3eacec850f051386a2973d452272b35c335979e031f6401ae5a9482cdb280ca344152881f04805bf99f60064fa645cda1a7fb32908893908ab3021096a63f88f47d562a2eb84caa88ed48a16919a83859ed705b701a7e212ffe5ff2fe6dbf71dce81b85cf7315149f09076841b2d49bd9508dd1dbd376a7fdc46ef7dbf664d291190f254212c714a880946dc5e2057c87df15ac5b5c97b07e2800244851ee4ef2bc07ebb74e6c1104b147a1aa50f52f5e5620eac5c322a84fbf3b0f23e6124e0420d066d6002e272c300b42e95e6aa24fcca5d4932b9311ffc5604056e986e717ba9510a3c5a43ca8602de17acd42889d4d1a9a9c77d00ab90b56ff030a375871353ddb0f4acdf6f23bb900ff0de58fd10764942938af99e4d9414e557039d5a8c94f9374760b604f92d692b5e2ef6f9ed2ff54d2bf2cbe94e91b323f14ec1257166b1440645b538070e24e73ee627247a5c43c275b32f3bcb2b82d88c431597a9efca90bccd493dbcde0b4b851fcbbe1e7f7d66db4af3dba2152825f933615de1db929a598a67268947b1ebae94b6120c764bddba11b1834ba522a8b055d5762c3e8608b162deda91a71a797f0acbee87e2e8591facad673e1bb6b11af42b175b5464287192ad589a078366d2b60f5cebe72f5be7c6571d8616d13efcb6976d72ae30008f168ddde1bdbaf0231dc76939f2b8134a64768f2a6f7b7001f2d34aaccd1df5759efa86a4f669d4007dc1cd6493803aba5de3743b7a1718706982c29717babace7aaca37f4e8ef08954e8c3be5bdb8834b1f8cfebafbbcfbdbee4584c7bb55988bf801c1ef351399643be23bb6cb6ed9bdcc87c7f89ba3b8716c56bbd77589a0aeab231e34a20355861feaee7ecfb8219302f06e17ea816c793952532225c54c87fe915c8e454aea77baf16e07814dc69d16f71ad461bb5d67d3cf5906ae35050af19877698642dc757dc7edc65d77e4faa24bc3ae8be0113bae6fdaaf1cfc4a758ffc0ceec5006ab14b5d18ee792a56b228218bc2c47c3bcbb22bf69077a93b72bbfc5f6468be92f69a3b8ee14b75fac3e1ff1fdf69841949bef6c64229ca4b0df9acd2904f43d19b4a4e5a6b48239aed762801fa073a180d4a7b98f2444dca933c758f016468bea7589c86e2676885b240202b3a276b3964df63b8d378a5ef34244375a719a885524691a966a4cee9a376c09fb80a5ce12a5dbb44ff567efb6ea091f94c9633b0d7d20fe0ecef060534e29e22b404beecae3f0ba83b4b93245c67cc25cbc95d3faa52e4e682b4694b5a687de928666e89c9c37fc63d90c8a00af8ae31fa5b585803fb71264ba79f89aba2d4b95d292af4f3f497f5bae5a63020829e5b515979b734f0d3b37d23673b2702b0d686037c38c35065280a725663f12d6755cbe389701a8ac54643ffa9f00002dca2353681897ac34761b78b851489ca0f2af3119070666192f4c3f53ad9cacd912fe32ce8cf523e0b7324248103906903662287bdd63e4d222679df1e5b8403ea0ee0b4b33eac5b39552e56f52f47a6481ee8408497339126497de2c04db9513e8bbeb2690aeca8fcf621de3709fc52bb141bbcb79e10270c2ba32f3dc353751ed7ab6b8ec4179b5ae8d2d66abd305c5a2096ceb2e52aac95b1af5d6989b1072e20aa47e5a619b72522ecb72517841f9ca8039687133783cc6e37dfdf6279b5c5602c65f982f188d5ee096a101355b314bc87a210100053ff8ef9024268e8471691443d3dc43989ca9f32db8cdaf2ee5c3e191171593b4d7232717579a04a3715550f5ac72e4b2e7fa80c0744cb91b6165b56c34bcaa4bdf5a6211a749b16d0263912d6ae2000b2f9540ed9e5185792476b2616914c1e2387f2c8514ce4f9f2440600417ce294bcab245d7ddd579771b752c65d9247a5ef670feb90472c72fd255c1c8c97fd989b480a5a0826d59cf86b52ce897f43d454f85352ce897f5e13996de5c9a62932cf9be739b725097992cfc87c4f56be9fe4017195293bdc21d477bbe7e977469e26798164d592494f39e3391e9dd5a590075800b7f48c5c69c390cf5fc934952b3ab639a8748f59b22e904bbea9d256c4356e292eb9a5920f68bbd5bd822ef16cb392ab13fcf95a0488fdef6eeb832e9903c51583e213d6022e48da56a5d275edb15c7101b7b98ae1fadcc670bd351d81813ea69fc9a51ce8212617ff19779ad87300a0da2ae885625a97d52ddf7c6c84477f0eda027d5b556dea7fc114072a51bcaea44650d0535c6f9e2e1609139aefbd69bffdbfea87188cacb6f4a69ff22bf886dcd19b725ac8c27c79b9779fb6f2bc1562986c3d6f8b6022f439a57badc240a1b512f84d6aabb5407353aecd8c9b0bbe0551a4430d831fed73dfa473e77925330ada0792ec762d2b0a587e7bd7f3aedb8b6752c857ebe9a26d3da9c171c945439b002df25df5dae1e15dac6e4e5dc5679fd00bf251b2f4df61f2fb572dbc86b98b9909df3513e4164ad35caecf88723d6160a76d94594b9967415600c7ffc0224022cff27876bb955287b5a4b7f2c92ce93bcae5425e540bf96e0c4626fe9d1446aaa5714e79b568eee1415b443d40041935131726f1acb6ea797dd5ab426b8ab2e9026c651ee02056cd7ed252cd14a20f6e335fb64555b34d72031d20847ae3dcd6374e8bba183fde7bdebde6c3d590919263c7e4c1f3a69e778e3a43d017df93073225e7011e95a37b0667a0e7c11877285d781e5269d4b5969331f189bbae3e40ddd19ef223f23cf4997e065d5f8435e5b37b70ce5669bdf5fa22c70c58cb1dd539ea4c7141cc6cf93129d7e4b4909d8a75970ed27f796e7c14e95d1c31411e01b9cb3f2e5a08c1c7968cb76d1917ad160167cdb3fc86c424f2bccf64ee79318cca9c2c3dcf9d2e7a6e7749d610495aaeac9edb5d9395e7a905d773bb2b395d5bac08c2ef8d3daffaef7706a4d425264a4e6dae305086ffde464f5cf27b1f940274457eefabc1a727e4f7be39b8e8b14c670f79cde0aba4efec2177c963c960684d46a1ee9a7eff3fa0e9013382579870f40378457edd21ba67f80226791c743c1601b30fd8997dc0ee9bad360deb0eb1e37a356635829a11779daed33b267a4b30626b3d8fdaed4de6cdd59581a50899610591f0fff60199a6d1f63f198e08ac78f570fc5b2a40d029838d7cdd08570e07c8d9ea32a612e918384fc80f247f150a91dec316256b8a583f9b2d59b449345a1b61fd74935fcc7f56a10963969127d8b0b2298d018566d4cf1edd04790a950d90396bb5cb83a85ebb1b604b7433973b7a329e5249b65cff2a66499e19be9b2b970c974053fd88b80fbdaa377ebc67d37b23574fcfac02b71be382ac0ff3e2b58aabb254e7dd82ac3026cb719b4538480c73eccf8d9ab44654cb36faae721f2dc85cfb504464de7fab4699ced4adc0611b9ee73f68aaf6fc0763c4f3c34b7581fdfc87578ab23dffe1bba6999fba8be90d89890bc8c6039fd5504f20b060c24281f0a8dbcd5ff351e9a538c9839182076139129341a0348345b1b140d1e05b2a889da6340434ac252e58ae626f9629cb30a3692d256339cd486539b27962449eff70d81acda8262b3b8d11eff546389e2381d88407b233791569ba02527ba2c21f71ff72bb9aa6c9d316a126ff8b1fb1d6ab12572d1a177fe59783ef0e77cd74ebe6260af3f0e6a6443246391ef3c9fed5d1d824f9ee32cc966ee0f3fe2a5c3fd1d31f0e540ff037fb5088bb9d4015289d5202e594755d73f7e90e5cf0db1c1e314a7bc3a3c1d8ed0d5cbf698b5b37d8320ea4662a95065940dc7436c9bbcaaca61b06856d75fbd457fa724b7d3caa9541d43f1adb664b2d98426a1e3f8a7421c255c555d660a16a7910d8310360fa5f4e3e5d9dfcf5e6f2fd9be3934f10a10009c2faef3ebdf9d3f9c9872bf30280fbfb619e87b3e5e5529ee60a36752f2d0554f498df9aaa424c3ae66650267c0c45b862396466fdb3d30f7fbeb9bc7a73f5cb2536912420b72af094cfd3b37481423c52d655da4b2c4c9800f8c7ac28b1f788f2db02e5fe1ec2613c47608cf48cff543a5c9a95c5ee1d409178f15c3b69ea0ccff8b3e7b882e496e48661228ad26e89ccd2f516bef9180a40d8ba0fd7d5b3200b969fa533102a2cb86a6850852e0888ca700f5141c396cb824fc280a4b407deda6e08a6e49341e079ee8dfa3d0ca073100f1da56aec54284a5333ca498cf1be759a9e0f304ce3dfe6ce32bc638e60ffd8c482454e68c259c2ad291e8949ac15cecf7140d32af6c0460a52b24dbb9d7ba37e0f83fddadea69b2492d528bc5527dde4ce36dd082786b3a6efbc491267c3e3792a5699932d657607620639f771be74bedddc7cebac15ffe284dc6a60a6338437dfbacac25fc59a35a3f18b2af43f1b0eddb203835194a6f164a6143e3e2b46d6b5541d070eb6a2de315c6fad0c1e2fd38d98312408b888cfd2d53a4e4c4e6136927aaef691dcaf6f2fce3f9e9e9dd4b752d8b69544eb560a3109ab5e7cededb532e1ed7328b41fd2b0e444b4de0be6e26bbd05a0b4362b09292bee195db2b16d0859e223d0bc9063bf6fcea00b2b59aa272474a7ed6c0b61f3d310e5254db0dbaa4df789f03c30582b0c20e584913cf83a3bc0fa88b68fa51ae7ff33d605cab8107da75d289f7ff7f5b28536e0aaab6fe70058a49c104082289dfa56b653dfdad2d7de28b16dbb2f79b5197199c20ffaf519edad31f0baab3450538c9664abccb32ad56b8b3bd7b4fd5d24df9d533e9a7a1eda1aaf8c3c9c2671964b3a38d569fa2595ef5c4cb61357b2483d31ed419b7bb76ceb06f48e6cfb7144a71ac7443ba39f46e80e3e018dacf65ecfdca0912f52f9ce353b2dd72218a4df8da795e31ca5f4cee718464d9e1d5bad0c43dbca53e47c3cf77bc3b2c20cc651b974616dcb600b51351df5daf3d67207e8aa3d0f81d6fa8e304c169eb7805f96eeba45dcba692aa7b74de5f4fd9e36fabc32c9b3ac426ae28e6569a66ccb5a449aff81fd337c5e33ce55ded4513fd400f8fd1890c4e47142c20c5e6837f5abed9a155fbfd59ed06ad4af4ec064326a5762d4b6d176cddca7948a71735ea276cb9c8c249e9774ddde9cb1681ace6edd03863aefcc7b7d01284720a333d29c39651778172671e4fe9f9cba1fbe5ecb76d098b5449c503a1463da6a69935a6ead60eed4955535774f5e5a555afbb2c2cad4b5a9a6af6639c0e48622ded48164eb9873265c8c95d1eae135b06cd54cad9b9aa915b92191e7dd28bd38b8304b7aa9741d5a63358a1ace5eba1130c1d1574ef0f72ff40c7fa7a6f8c50fe03dd40f3dcf957431e40a618ff1c88d0d345fcd32538b97e54e021fa65758d7d01992905a487e3536a18efea744cb662c768869e4bebf3a3f839f992bcfee98c7b97e536f22e90c486720b93e3934613e5b96419194fd7bde8518c875e3fb6621b546d2cea0c0e431e533e6cb9f7b6c0b7e043589e96188498a7051347927eb8e3f1da3f288418232b2a92d556137e87823f475ca6ee7ba24a120a36c2a14b855e6e2f190bdf08784db607e1bfc2cd9ed0698642acec2d35dce31f665c60119e8a9231b927cd9d72fa41d74189072b7eb18e4acd23db69952df205fe272eb5eb8acaface71450d97fec705b3b88ff70f4ec59e70fce33e77fcde3845ddc317117b37be7cff1ec36cc322789a722145b274f1dd50110a74025e8acd3f59a89cce14c2ee9258b8523d89c09c667cc29e3e842d9774c64b23bc3fef0bbfe1092a444c433267fbf4dd75b502d3a68869de783e177ce3b163111cf52e76ff15d9aa4502b7034528a4b45f607e799fcf22313e0faa4bca0964cb0e9d6598890e72c22ce5c30e6a47367b60cc58211d989906f1dd9e8943be9340f631ef385133a523697e569d32d274be7f97d28546fc32c4b677198b3c831b3096bd591239639285f32c7bdd45fb818ea895898c802632e47c6316f41fa94d2ac606a36e409e0c47c966c22d912f33a8957b1ae447e0e8323fb2c8bde648c408389b34aa3782eff33e8df7a23f9c92571a238d3f22e71329908430da2f0512a9c8c25d0b859ba8e59a63a5db55149cc792ac76915e77ab8329972bf4c57f5fec4d0aaf946f0385b32f82c4a9d2c857ac17b324fe18b799a24e9bdece32ce551acb41c7a16af96cc09a7e91d836ea995c0d33c9ea9f18719595733ad5f65cb30499c29d3c3c72239d861bd67423623cb439ec761e2ac5301f5367bdc37ed787fe25c5ebcbbfaf5cda713e7f4d2f9f8e9e22fa7c727c78efbe6d239bd7489f3ebe9d5fb8b5fae9c5fdf7cfaf4e6c3d567e7e29df3e6c367e7cfa71f8e8973f2d78f9f4e2e2f9d8b4fb2b4d3f38f67a727c7c439fdf0f6ec97e3d30f7f727efee5caf97071e59c9d9e9f5e9d1c3b571750a72eedf4e45296777ef2e9edfb371faedefc7c7a767af599c8b2de9d5e7d9025bfbbf8e4bc713ebef97475faf697b3379f9c8fbf7cfa787179e2bcf970ec7cb8f870fae1dda7d30f7f3a393ff970d5774e3f381f2e9c93bf9c7cb8722edfbf393b93b5c9e2defc72f5fee2936ca8f3f6e2e3e74fa77f7a7fe5bcbf383b3ef974e9fc7ce29c9dbef9f9ec44d5f6e1b3f3f6eccde939718edf9cbff9d3097c7571f5fe043a2973aa663abfbe3f91a9b2d6371f9c376faf4e2f3ec8febcbdf870f5e9cddb2be25c5d7cba2abffef5f4f284386f3e9d5eca9179f7e9e21c7a2a47f7e29dcc75fa417efae144152447be3e41179fe0f997cb93b24ce7f8e4cdd9e9873f5dca8f755f4d7e39c9477fd07e0a4f604bb5bd33dbbefdad36064805a959531aa51da313f7245a488eeb4ac491ba917a170b364f1fdc802844ee52c79f77e91090263caf2c578a92e2cd429e22e63c64933cc03fd181515997a0728342636985f2d8d587d04791aee28c8df7f990ceb0e5a05710189d01a97fde172c4b933b86703f5f325e637264498481b5112e8a96004c4f57748075aa4a250243b8a403def1a5afb6714a07ecd6c7a2740e57016818ae34ed6919a347c53ce2690458677a4427c1c830f135e08baf02ee2c7d85c67c92073e2fda7c7c80db53568bb26ec9dd8e996fc3d3ee760cc0668bfa8d583c471dd3cc7269f6a769b41de960ea55893a9e3a54e5c3cf9f2f8e3f57e1d31b9d834220db7f9982adbcf26da1a63305e19de610e17c9ea4f710d0c33cfc15c2fe99271355e908859b3cdd2933e59d7c9b845b7ca41c707837ec0a3c66fe0665e08d53f639690221944c861ca371e3d967857228e19ed741860b3bbf3ce5eb4d7ecef2651a69adcc6ed7a9d058f58ff33462a0cff2bca3f3cbd313673830eddbdf8cd64de5dc6ae370089802913f54e002333fdaed66557f9687e7d0fcd05ce2a80ac83247c3011ed7265b03f153c31d2aacdddd4e268f3885eb2a069ed5bab8cb789ac47c31c29c2246db5ee15a51467af23c5eaea7f286c3f3d44aea502a7fc30293bfc710426ce25ebd97f4ee58fe9167891b94a4ab2a0c83994f98c733b90d5275cdaeb875178f9788639ffb72861b3bb03e4afea1e1ab867cb587be5083811eaf90fd887d2b52d9ba24131d04abcfd009082a9c5764e38b9359da09a72b5997e98e01774739f664edfde38bb7bfc06d9a0a4b74f1e1e6ddc5d9d9c5afa71ffe440484dccaa52cabc3b634e48b4f215f308447713f63f9651e8a1c0932c0049e4f78844223f9008e2c8d657356297fc3671027b08409818b860ea51b15a879b3db09b0e908639e5551acd41aa094a28ca2946e7035b7bb5db92832cf5ba2b43f8f456646e3ed324e22dca1341d2fd106fb9b9142ed59599e960910bff11aa91f24c7be9c8d15cab1c2e0ae66e9a63a689a6e3c3f0d3d4f89ed1d6ab9ec0c83b1fda063fd726ae271e663ed4f7195ae5d5fff566e5bc2a2d870d3660641983ecbdfd5adca93ab173443f51caaae982f7496ddae843f88273c28af14e5ef7204b6b5eb87e6183c6f1d83e781e7d94f44d01b295902c03e09d58302e62731e5e3ded02f4f71080cdaa5e2595cc6b9354f10429d86f01b9879fd5035f6aee634faa0c71b46d777c17d4e50f5a89496ca43ce77b5379d69831d1a6de24e531131e17679d75568f681f60edbcb21aa1c559b16d5cdbb8d19b20a1f90edbe1690bcf2b46101e1138d7b6f9eac9cbc965391f0d25fad96d5f26313c647d0ed225783e92b901ab5126158f0d77da1c7cbd7038803ec0fac2e4f6d547c79a4c069d25ca0421d3e9ed71276d1c08d680fc84559bf1e4aedf6b8407ac075720167f4f97eb8c40eaaa1ffe6f6d5aba4b2e67e38e43ccd1dc9d349e13d09b3cc0933272c794b1717e4bec68c9b3eb3a675cd60c45fe7a5858d091728680eb1fcfb8c6f564c84d38451fb61b7eb0c89284382c2fbce80b8601aebc6704022d1bf1771aedf19d5545fc90fa5df3023a27fcbb6302a4d0eb9be1eb9e73164f9a7017c3aa4c991ce01ebf8e120eab9948ed9f8501b7263d5cb49d549bf3320760fe5b3e91128097d0067e18415a515793fccb278c1eb3a4f2bb0dc287fdda44ea3dc8cba45b9267950055554f87bba829af19505b867624c0aec7988195c3d5c596054ecdaadc50f9ca1c78230f20894cad7d44b23cb1345d87c45ec0c087d616da1ab6a0b3d16808f15cf11ec1729bdb0439156343370032a4aa0b6423d286a3bca1575e524d7d45490bca4b23255d35551a8c8bf876bb26075d579f4280bf455b9244fd73ed4a537aa2eb8a75feb6d6daaee41d682c4b44d7699a2c64186fdc702e2b56a2cff5aa48bdd2ed4632c991083fe5f0f0a21f3e8d00249c9e6c2d7bd4cc1f2596ad1de469ec5c96e17a90999818c324a7af40ecd88fbe06212e9df5b79baa9da7b3421a6921e8dcc62b945a135c99fff67ce56581624ac062f2f078fc454ae2492d12b9463925029e89188a6f2a916bc26eaab53ec2a5dc34860b26c7b2d4f09f57ec43d2ff43c944154faf24c8347c919662ababdf502a67ea061f957f4163dca651243441af8ac3723b0886215e5467dd15bea35a4e7db2c9eb8dc35727e56fdd2479e0e8879d2d1f03bc2f3b431d3badea9f223c093dd7f230bc0a315348ece7a6bb2324b563f410be9b27743567a89eb87aa39eb7a736ef45a40c2f33a7c9c57dc6f82fd9c529a58225062cb346845b76845728cc9aa5a44c7ff068b6a2fa161405a94117b67f567750d125613ca6bc164b4400c77687a230eca709b76761d82c5ce6f76e5004cffc603ff464564d63f4b5e714361c5a43d01644c5483acd64dd6138aac096bc0f5ea09cb7553025bdea28db5192f6da6a5950dcf2d36dca08e74944d9c725b026193d9c2a6c935d08439abc4904e877bde25e256132e4a091e5c2595e45832eb73f46559b03a101b9f8f7213301b1a99930a46c4c5239cd3bc91df1cef1520eb6131f8a419d3646f21be6c5d882f6b0bf165406235c103359d8382a4341ccb5101012d01a81639dc7731bb5fa7225702514c8f514a421559e45169693460a3e69395de01728f2bd132a21b05ff5249979e87a22f6d06ec47d455cb5795f8253d8218a973e3338a20be3774c1c8b05159f76e7789528c633aab3a32a7fba71f59d2b939be5674ae23e3c4ea649f293a6aed8c58532cbaecc24b12eba37fa688d7ccde2bb1226274d5556f15437db3070d8900ad73507917eb326fc6dce7f07bb71b10dd269598a76b95a6c9a44a157ae797cd342fd413bca916dac71a6c1174fc59c93d95b97edf8fc4b2b7205fb52ec857b6f0fe2af0072363d56ac5ae0f3779ea366cba537a0291e763124ac205abf851119eb47e6c01aba3c2b01544f1866546c323c17ff3416afa6798c6f672d38a97523f0ab5891e0d0306939dd6f8afb2e8a2bc42571048d9c1d0b192adbd655b9f15249bb0803c868285fe47942970b902e37e968afc40c8ecbc2fb3f718fc2b202adfc604a747fbba7dc32d8b32145449967ea2b5e3c7f34495a2afb3c1692da9420d26934120bbe76ff40fb08cc9d6499c23b7e7e2c9b0c48789ba6836767b6e77e6bbae45a0dfd6dd01f656d58bd655f5c25e552fcae0a7627c8140f5949304f1ca22ed33e22494625b59ed1b7b48fe955b035cb769c82bb220376fb7e5d5cf66db49c9a1e5fd99dadaaddf7e32a7b891ded5d2ab31d85d61165f9dcbeef2a2eaef7b4bf88145ac1d84f47e51ec80d90e4ac126379cab83b115a33d64b32320498ad868ca92a7eba3452b9e413e614161df147c30d3ce29b717cc20d0aa6c394124a4bac3a2be3345b98163aa95d8ba3baa2396065bf23ff1187a647a99c9844469b0a0a71b99a061927c0d43411299a87e97184a6614c2491ad07c9206dd7cb2098e9ef704fc23e1240b28a79466e37c92053d3149023f9fbc47190e4858f5fe5d6d0b836781252bcf631e8dd53fb99a99d9ceb91c9eaa90d3466046cb7490f906a869b0675f12cf515b8560275ae1be9549ad140b740994f2021babaa77cdd8582d39cbc2cde4085c48de8e83b522974cc33e4a1cd8d49827cf3381adee43c191fb1b5855c44c94397e73e2cc89d85ab0590886259b8c395636fe5bc7c5a57edf7c25a5d9391fb13ee31a8231461c6248ea1d95f595050dbddd4bc2a44a29afb76af9ca544c72ca01c14807052be7f213525caaf27fcbc39cf5e3ec9865b948b72c32703f8f46df064044ca393193923bf80d5e568fa50b857c9a27f17aade018758bfcc7a218b19656bf455503546c6cd547f5bbcca71ed3355868f40d6bfe4e32ec98582ea8f47754cf59faa6b654fed5f599c9ccfab267fd69e90d6a24aba772eb2093b299260eefc7b2b9acd6c25abfe8e12e5b9dd18be403b2fbd2d657ab26bcf77d59fc13958eb57ce4bbe1344b934dce5cc2e8a9aab8ec33914bce5e526fe1e6291ad70a4eb9f2af9542016acb0ea0f9f52fd41bb8fdad56f13f1b0136b374c5f69910b9f1b8753f69ed3ab80aad9d13bfd6759293ce90b8abcc25eeaf1022da25ee79fa4f97b817ae92b9ed1057edc07544d0c148547a6461349a2185081e310dc7aedb0dbbdc0759b5e43e6a37ba1ab32c0e0cc98c0bebd2b26affcf7564fefdbd2dc7f69fcd6973010a0336b40b64a85a4e1acbf28dd9e2a8e69a8ced5da4012ccbd5e4ba2d6ff374ddfe02544dad6f943cd3fa4acb45adefeee32479bb0cf982b5be9ffc8a6c013aa0aee98d36f307bb59038795215c5f926a582eb81e58cfb32ba82e8c753eb8d3b487559556cddb5f0ef28795c1488d55d481cdab127ea92478dedfc00603a52f154416de0fa3a8d623e40aa6acbd6bd9c9e33acc3280d61d14c65c68635dbd5ad7250d09add2b254ca4bc90ce587195e3f1fa5fb2d93a5d69a41e2dd8ea10d4aedab785d390955d0cd14172824e656add129deb7b508192e134c40c69070e555949d28e220f789659cf30f841fad0d55cbbadb59548cfe829e384c48f3bcab230ed894e8bf0dea1ec947876af63c3493e773528f298fda8ab6aaa64841f9d98da456cbfea2e082e5c23db064727b742547521bde436c556b9166c2ea4502bf525bc62072352aa293a04c3233a9f335267348727b70ff64d95ab91d4a99e775546867fb5a1863cf8bb377318fe1e8a93eff461d3c5f841c2ec54cd71d69b9c1c4562f43a38344508a132618f5be5ce1797f42f98407182ce621aa31b15132273ce88285b7acf1cf60a6a42d098fe2afb153fa6b5d303ec860c359aacf4d12d24e47785edbd1dbcccf65b6f2e495ec50c4c46ba1fe174a2bd8a968c96f6e37efbabfb92485df5cfe1ed5b8f1b4eb3ae608935c78e9633bdd2a8066eb2d77a01a30544ec52d71a6ccc93682c9046d23ecc4b93365f35430f575c7c5954fb86cd4ffa613501cf5c09bd8254a8ba4fef5c085c0856b10fd56cdab4c51ef9466c8bc35f3ad52550eadfdb11faa54f321e8805416255daa14f53a207fa3ff5b731e2facb965ec7fe286e16f9589a9e46afea62be2dd213620b67f2bc5404b1b928f251771c784e48c7ca1cc0419752583ec12cea83b4bd2d9ed7d9c319708f9986e78ce44956a01b3b3a6a27a322083e08b72b99072b951151da1ebeeeeba878f0eebc8ca886118938ca66539ef50dab62d7aca503463a1982dd111d95d674760f03a4a2759e079a080943f2b1d24919c565dbcbc506cb993b17528c0a960ba75ee9771ce9c6c1dce18cab0130ab6276f86ce2c5dad4207110c26122c8cfa5aeadcd0a3ebec19b9ce9eedaeb3ee1178cf7428cdc693b49caaac9cbe0934510dd2464aff01268db4615022169b12b2ee10e3c09fa425d4714293e6c85ad1d287a072efc47e8cf7d520a9650e2c4f8c683363edaa48172e992755d818186758045d97b83d6bf6733c46b59c3497150d08c37eda78d555ef86f21d335d551ed8c1e1f552d77ad8801910a6071d2134f6af7bbbeb2e1e5f47cfaefbf22f46fd67f80893987643b9c5521a4e9e074008e34a391dcfd140ae9e6ae9fcd12d312ef4258936ee4db54def1fd7ae9f513e9a0a16de2aa3dd3f6a1bdf3f0ad73701c2322aaa5bed0c4ff2e06838183c8b0bb8a001d8d474b773efe092242d153fe6d5b8bc183c74bff435f785fed796f2c42525d6ed2e652308219f97f8eead8a1e158cabe5d096b3f727a58f092779d0a5fc19727b6ab589de3000633783644ad4e110b31a1a92a1de3519da978bca664bfcce8034e408d09a6869d7c6f52b88919aeba9a50ce73f66cb789efb8f70d0f9c3c180b0aa96396fb1bbb7d50f9ce675b528186dd735ebb124a395e9a22256527eb5f8c89486460f9119925c1e65f248aca94a3734ab6b461399d0508292883ec2f1e63fa0c7826c483cd90498301ed909dd789204bd749204d8d635690d0958f2a424aa5bfd145a416506edf913836621d6ebc2e14ea31ac1e698e851486bc39351d118e68dd9c2c66196fe0975391e4fba9c0c023f64889398a424c3fa4c036d2fd2f7721b5984b6b5a09bc930c046d17e285bd764d3c6ac90c9bc805c6028a133e9a9a360a8db92519706da2b18e898b072540705d1f11a2fb4b9bf19e8175f39d07bbab6dd6e8958dfa8258d2c3db2922ae5a2f1c45dc2cd8ce26aeb323fcc59a3300d5a2767304fd7307d70df96d17022825168141861a9b090e992c157c7edc97efb485bf3486e74838437957f5857139b5a52554946ec21a1c6303aefaf459c8a38df5a964fa53a70461f75d09c3d12c06964455490bf5f6f262cf0bc4ede67d92c5cb35fe37cf9c9341946b3a2d6131610991d63f2a00ce5382e48c666a96c605b6dd5d264f56d2f6804269555437efa4243846e48cc91fc141ad243760591bac2f1237d77834d3b9595696549de2aac1a683920609ad1ae932f86c7653422df2dbbed8e22456d22329be401d2baf73d8a14c98d62e6cd2feb1035a9706a4284e8a5e2bf227b5bc2af1b4814e496b1f555ba60f99209b3e15e7ed57160c817843a50ab479e02d59a0d6d8ad72064da4e08022902d2140c5dbd1fe5e0c1157b3ad6ddadcecb8d4cac1f08e9c15b313ec982d73112f23880e8b0f5219e6c02aadff6b83c17089f6c829f6452f6e407995cd2f274806b0e3384afbe866601eff6579b04d84a56405b24ae3d414d2b0439deda3fba355492d0b6d0a28572fd63c3c45641d6a402095c15ad4c41c12c69efabd2764d94f9eb52c9af6f3e7d38fdf027dff90d3a609af79bb3da64526476002cc249e74e9c67daf3dbf878775c4cd8c8b00c87974eb5f6321a9bb5b7a1b1b5f692c66e544ba7b6a4229aec0b14339968d9c7933958d858d1b1c85266b157dd4a264c8d85bcde936bfa06093c8982d166b20a7aebd7d9641eb42da379d0a3f25d0fa98c1893cd641e74d73f6593d5812fe4412ab3f46496167271bbf791418987ef369328387ade5b1f3d275b9ab61c91e4ce3605d8566e01b3009345e39d71869855ce10644a6f7a6d3dbdeb2dcc7e9c568743499cb34914f4d6648a096052c00a329a3afbaa0a5e50f4a082c9cf09142024ad435320dc9c2c89eb62c2e5d624ccd0bec9430f3e0d5c75f16876eb775fd8adf11cfdf3c036354026b600c6fafa5613827097177852e6dfbbd6ab6f68feef70042d9ccf1e8f50673f1b3b2aa4ef5590f9035986016069a4741218d931ef4fd932bc8b53a1844827677e4a2782848125473a5ca6328604b6538549259d817961a4cc9456451bde3b6d397533b28179111d4ab3dd2ed52239a574d31d5683fae56e6bb6688f13b299a36ad467f6b935a725932d3c6f861275f9847f9aa1085831bcdb554c86ce02e9af650e9579b733ccb5cea028892a244fd73243c558eb3c321dcad099c992da652b8b3c4c56b4d6286d7d87c99a5a8580a51e2637b45e392fcbded6bab96cf46955ebc0bad9da1b72f785d35d4892d2e9e4b069fe128a5821577a1eba536e9dcaec3386aa6512e3914e58ed769d66a6b54eab72dd487ab45fc1cf5b8d38dc52d3aa59d3b2a5a69bbd9ad6989cd3c56e371da1f96eb7ddedce15e7a0c901ed0c08bc505af974b2e94a71e85c0a4b2d1084a66036d6d5fa55f56c0c6f7d56a018d7cd1a4417c560cb16fbaedb7238283f95e672ffd04a779eb60dc070a9df4a1719510a5bcdcf16c4ec695f2b729fe4514b735f529f32bf332407261150d680181ba2febd4dd487ff9e52a3e234422accb0c454d474184f731a60d80e1a5db303f62e6b2cc3ad1a6711d078c2831ecac6f0a6c1d806fea03ef1ef518bb906bd95bc8ee44f9771c4ccd8fcf02487ff145b2a4b7189db10d59b8c69de4a3c397dd75e6a8b8e74af06e52314ae5881b175e0c9f3d658c0bed646c7caf6f5a7d2d8184c707faa4c8cb5c1ed6b4d26a1bfe062df97bdab7aa29e41f3dbafac9626ee432fdde4bd74de9b5a58efd4754b78dacef089d2865f555a67686b9e66cacc136c2eca397cf5756a910710cbb6b6caa95ac9ffc28458561fb5b958ac376f6633963005bc352aaf87e2e68d45251b34bef9cd5137dece2abd53d83fbfd93dfeadba9b0b79e4dcc7490231ede15a6e2d0985c2ec996ff28d608ec68802749e8f4a6cf93d33867529adda378efdbcd97c92d136a511d9d02b05dbf768182b3f2c79ac82440790c90df910949b410f29b7f6841684817925a9cd5db4816e3bac90820ed24e67b23d3112e621fa0229aad975cda8be86aad8a3f2caa0e76232a7f938daed66bbdde68fcf294dfef87c1cfba99f9125cdc7b16f30fb94bdee1c41a6a1e725fa7f67e679f958b9e7f486bed01c499eaefd25128ae5d006bdf2d9f01acae0778e84665500d1d620a0b1bb78c63ec60f2cf924e7eaf5f3ddaef367d9138be5e0c69ad62809e696224994e4554b69aba68e6fad9707b9319ad6788e6eec0a66e3d22728ab7c167b59edf6a26b3833bfb7d11aa52a09d83ab2b6da357fba4c6548ad194659e27d2d41f19a24f5bc154e26ab40470c4ec29cbd8890db5d77ddf50371dcee8dfa31c02e4926b3800e483299c3bf9af953351e955fcab63e04bda13f2477b51e804f3f147bf36cab0a5e3fbbab173debbab21d73b80459d0c77ae00a6b295a16dd15a9549ccba2463e4bab06fd36299f4b01f2d27add1021eb59804f69900349591faac5b4ad425754e4d010e41fbfac362326ba82f34d2bbf659a9eef2b6cc080b0ea38b1cd49f801dbe48edce17cc28271decf0c42fb260778a1090bb09fef19ec31ad80b4656fcfb32bab8f9996bb3cef1b54ffa8656c537e968691dfbcfdac6cc2dea290e48411de945e53fa3be216af16eb6c5fb4b6ddcb624c6c4b7383fac0d456244931f906e5a422f9fc8b76ae05267c7f15295a52140549d9013401cb9a06eca7d3af77101edb0ffe63313a079baecabeb666dbb51f77168c61589637ecc284b6a8c2852a463dd110594ffd29f8012ce30cd74d1ecd7e3b56727d26c7d2b2297bb48c4c25775e5af3ca879ad5963f098a86c53505c09cdf418339ce2783c0cf6d8b4d0534a45f73f99a1fb0baa68f456d1f35da6c314469f5bbf57e38c78f62bffc491e34c7a1f61242335a458fd3da6bffb150a66d35fbdb9ae3567bbf9ef4e6927c9bcf0ad2d65ef0e97ad2a34b9b62f5f2d214abd1bc43e67c96f302eb2b4a80c1b20b7e225ba42a25adb2894426c2caa906442d400d8190d5add16b17e7a34cdbdbaa26b45beab6d84bd232ccc73d6264026e70ee46077bbaabc7282fc7e793428f801d5114447d14a9a57ef8ab9fdbbe6a6beee122fed15a719b71f2e132febb5646208936c2a394f57fc9e324a3e830dce158fdf319ee2b961bbe20a975a667f47fcb67b31168cc0079396505aeaa251cbdfcf18bc0b36d70db06b0cff21c92b44915ddf252a69349a0ac928c6c0018dd196074a7c6248aa3efbe5778dddffda042153cff4e329d597ba80432a7359b8b2564fc02c23759aaf86659c980524a57637793b8fe0ac21394710bb665dc833fb32db9a30c00f5c902f2fc996d8fd37b5e450fa8c3af5b310aca22a49c90ea389afa7337b0a245a7fd4dc63e816595c06d34a5c30a4c3a433c1906e4bef1d51ca3ce1093875a723d98c159fbbb191e9d791ebaa377567c03b2a56756e7393d6b062420cb469a388d1a813eaba6a9f9ba6a4675eadc9ab01ed8f29a1869068e088a725a66219cba93bdd00a81cfd31c19df8008bb244679fdcaed4d024ea072059785352ee5dcbe09310018e3d5dd55e9a59ceeb530a369b7745ec97ea2a264d05046079864af07f05394366c9888491614e473438455f876ccf3d08de7dd401a79f0bc07f8858b913d9c27f3399be5f5a826f11c951df3bcfb724cb5bbd8c14eb78c66390e2340ce9ba7b34d86705196493b43e3ec574643dda828f0b75558c43d70f9a82518e9e782ec674c5a323e4230be3b522e47bf8ce239c5688b496365fa7cb79b93c6d2f497bbddbc68ab72dd0c7e30258fe506dd172cccbd0c84bc609281bf655b6ddff746b2e10a13ad7afe65edfa39bd42bda17d35a3de6994b42a018802641f36ef6bd4e01639e8b9b5ce4e937884c96794f7e574662cef8be98909c4c230b1e66e40ce9124f982cdfd6315e3f0aec03a32ab3c229605214d4bbcc381c91cd6bf67d37538bbfd9826db799c24bb1d62fdd20cb64e9e597f1de64bf00da8a226c007e6814e82c3905b6e92861090f8b18e76b56079cbf9cafa49513c5158fcf505c5b2a0bd9ed2a1d2f5364fcff2c0fc61a88fcc615b583beda5a32cc84acf304aa91c1105c1af714121a913a21c7b5e27441c8ff38e64cb7987725f94a53092e1b6284477565c40882648dcf370fd544cc04373aeb4cd263ad3a886cd296997abf07c5d85e652c2ba519a3fd5aee73ffea0c6e9c540c7f27831f85e85987c31f84145f37831f8f1ff4321265f48a60746e48509baf9e2fb43a1118d652d62782c10c37e08c1a9fe854ddcc41f01c0de9f7a43cf637f1c523af03cf69afe38187c3ffcf1c7e7af5e7eff72f0e38f4f05ac7c3150adff01e2761c5df777d71334f6277f9f5c07c1b31d9ab8df06188d7d34ee5c0ff1e4efd7d7c1eefaba8f9f8daf87f83a3822293dfafbf5fdb36f8e0e06a354f134718513a415f0f5a5d941a66b1d29a7ba1944d1d40fd3344d58c8d553b9863b72f4f06e8752e599c3f06ed789abdf2a63ee79cc89cb5063f993fbeed5e02932604d836e9e1de052b6c602ca566140039752b13fc9b2cef6f2dd0d8fffb1616731bf3d8ddc982346991487b1e7a1faad015f8870bdecc35fdf0128da982f9cb9485746d5ef0cfac397ce6f76910d57fbfe35ff057ced37491e4351e59d83f681b8e62e71e1cf873467be932f19842570c2244b9d192830e5f8ea83cf292f349d77b2253cbd77d27beeb070b674a0826b1e67601c25b90675ab3165706f113a55339ce9b62c12c1c72c5a40bdaa37b80f77b8d50794f5ed7e5a71e6ed5c701c5b1f7586585fccd568a09a547d1e2906645c7b523cb2ff5810790e92843e1624a20332a3833250356822c617fe09445bab2a1db7afbe8d6225439a3470179100c636dcedae148ff918ee76289988806aa8e198baffcbed3addae4c1c4151dd98e4ddb834d3e6ecde04d92102177b1139ed268cdabf212bd9d335fd4c6ee867b2a59fc91dfd4c16f4318c220006bf276114c9d1af972ef0e3b684cc7f809d792f59b1983ea01c1e72ac6e9720f3882b4fd40c93148524c38475006a3b4531c9cac6ad5146dc308a5c4cee102659a17d00a0fe5bfd00cd3a93bc02fc7a30bfb2b7e986b7f10f51015142637e7b308b890b5ae56cb93f7fb05c7df3710e215833c0bb2988d603418be6e64916c4d4305a8367b9c040897215785ea88ab3e330964b961bc1478c9be5d4c3ddb296f0a66c12827f42dc9744e43452c6df02e593b89fa7a75140e20ac8ad28906e08d82cef35fbebaa2329b56b1bab8a7c9306de12289fa44f555dd883d872b7201432ddde58310c9c071dc02da4814a8540c03966884ff2001764ca16b1711ad912c623fdfb8e00cb61af902dc2645e57059c21d68f9523ee1dc205598619b4f24afeaa16a54a2baa38cd0b4cac829564b8e8a77c24ffb468aa177dab9d744b8fc9a25fb695ded14bb2a6537243cf0914c008ebc3450d5a9052498e01e07651f16e537580afd4867c9423ee33a248fed576cdfc1a52eb793d378758010773df038ce26309d520e9f47e18d8530ed1e61c599803a13d4099eae2912129a2b6d7c4180910ac2827374810a396c4d8472ab670ace01ba36e5765001282493e610115404a44d5c887261852f9e6acb2c7373bb3c32b16a76a1d570b55bbfde827e082478df8d3f60eb9456212564e368a91852690a8d7238005a9489ca67f9d41d5b6db66fc03cd73e53484ce8369c8eb41adb544e139cda4a033b44656ef4345ad196c4e6c852840aa4ca1ba85f14f9203d54f7681242ef3c6b5bc714bdeb514f90ef6eeca560f8a6af4c56ed731edb0953f72941508b5695739cedc1057fd66c281fc8515416292daca4e5b48974ed80e1af259cacde5d331c28fb32e1ddab89af8512e7334ebd121f6bc5589c8e67968d19fc78221576d97c8252b4c4c063a6881c63c48cfd4a2ac3bd56bf4142ba4b5c0f11c31944ff8440481455acb8a4eca15fe24f9e41081ab2ccd2eaa28f5d12f079644185660e466485540edd2d002977790959bc8c84c786e8b8d7a62475c07f5912d004a6266a80ada5fd61fabfa41a28c23aa2124aa7da9e14b2411c9f7a2d9a868ead958ff57b40ee0be5401933ca8c5a2317eac50a65e56ba465856b9559bbe8d8b232a6a01696ab74c26de0ec25df7fffebffeffff3fc7ede656e257ca199529cea339741ea7318f8e45b8f8702cd2b57d9c9b031bf686fa9dd2bcaf79a95f4ed511378aa94029262d2b25eca71ce413b9dff54f54261efc4436467d217f2193f44415e9dad490ae9149c2844f640b031a83211a8aa94ec0e08d2758c294078326b3e66d61ade01f7e6cb97b7942f3423881f81f242191160a06448a1b644507644d9b1cb20a584d1e1ffcbc37235b5ff4e60526339a93391505b9a1f54bc32c4fd7523c0817702f3dde4b41e0760da8263f6fa60a20bf20db463175bd2458e537349505b96bd360dc4806be332cc8a25ea29455b555129403b4dc608effb5fcf559f255ad2acabd029663a42bc3beb21e9c6ef23c2df500d4cebddb0dac2c6304115f75ddf3f2f767b061cf43b16080889e89590942e679b99a063909720a443fe5c85da59b4c1d4864514bdbac5d728e093471439b212953ae6236837932495ade47225ca8b74f7e4bef4864e7a6773020da7c829c7f6116443f9dcf5b7a5126ea6e3cdd864da30d09d17832a914ce583d22447ee894caf023ca695e6f21de5b8af9bed23cefab55f29730d9306a1449764cb852fe1a107932684ffbbdf1c0fd75b8607f95732f7f7c1e230513bd607f056b2248c43e2a174f859bff1980bdaa65d56d0e9982192b83d9ecbd6f7ae5575915129aaae5a962afd2f557960a70ee939cf0a040a05988e5324de9e3832f2683a0174e0681a43593a1fc3d0c8a11a779ff7ec95872cc923c1cdb0f472fbe1bf8793f6279182747bd1f4906daec541e390fb579ef649e978fdd7b85f546290dfb5391de674c8c590b80162c40a8c725f7b0acdb721d5f9c9fcb8c971ae848e5cc3caf937b1e3a50592b54525b7dad195bab0438f6829cd1362b906ac5f40cdec25ff1b3d6d46e99fab94cfd6ce5b5530b72dbbc8b55a4304f37b325331c2d7ebc318c525ebd9c0c8211c4d82a29a155b0f1687cde5a9ce210ce905d16a91e8681622cf9ebd558d0ded0e73fadc08163a882050b4947ed6fcb166cdb923f1798ac406e63986c95ceb47e070de7a7265bf0b9a265b7b89608b03e57f5347512427293667dfeaaa1dd0728e16ab8a1a56456622ecb8386ff3b07cd72b7434bda19e8d365af7f7cbf7b7caf7700cd6a8f2d1eb54dade7a1aaedab276718db26a7ed7b374aefb94ba6601db997038ad2b04b9f21fe35307d7ecbe19f6bceb8208ad16bcbc3ad3c92b96bcb93da7960efb6e59282a3cea639405b95f314edb0fadb9aa9d1e5af3d7cffd385fda074d236d7fafce5f7ea3ee3f9cb1ff5e5d4ab016ede3795b2868d36dc0cfe83383e74a283d8a74675040258597c155aa9b4cf146304486b8248a969c283a228da2514a2bcb4cb0b15c03f86b0a37b718aea414805c64fa85674d993305071121c933786004efa7dfcb5d7728ada0e072f872f5fbc78d5ea6dce3c8f49e1f425ecc47207326ac172a3c9dfff2bc0470be27e33fc66e8624c7eb472e39c96c1c8581f222e0b34c464f89d8ef510cfd1f71d3bff52a4f7dfbe4d935438ec61cd66da1364c91e647f57610e91b09db560330681b1ddff72fbce497fd177fe6b3098cf0783bef3a73477944d87f36d978d0eb7e1f5eb1f76cf5fbd82d3a4ed8252324c953afc4911352529c46f8c13067a83ef8c2eaa4cbe62ab7512e6eab5be8d7e3980e5ed2ef37ced1f1ddddfdff7ef5ff453b1381afef8e38f470f5236b7e0cf525b006e11dd286b9f47ccf738f89a71ca874bd4d284e783c1e028bb5bb884e91507db2b8b57eb8465770bcb29d7dc3094ef003f13acdbe94cfe58af198f6844941e91ce09efe7ec21a74bc2fb29a71bf96f3ea709e1a052b84c3762c66846f8c8564a541417c2030bb9b789baa400a8fc86f6c18a9016b6c18caa2cf667c9de676d84b2edcba8da53a9a5d7355dd708b03514ee594d43228fbba681f8186959311ff39a59fb874b7823db817ddeb4f92fdf62c2e5eb45db97966ace8e51dbd28466cd31716161fa4bc1e6eea15aeab97023ca6d93ba32598f5c11dafb933255a89554145a635aeadd2b73be52259d3515881b3a186d5e5bbad38d9aa68466934d40229a4f9260e4c246a3942663b54251246b97eb172524aa6e235b6840cd90f5c089004e11c60c4769b8a1159b467f36d4ba43388f793c8f59e4b087195357dbe90c8caca21100ffe54be6f094f7562663c4ee1cc6ef62917239879262aa10fb9b2471982cd559b12c0b172a7c7e18a970fb61e22c59b29e6f12e73e143ce68bacef5ac178123ab13a20076d30427653f3ea3cf863568bc950ce743289badd00acc01424285c918838e4b9f397384d40f9e316ea2265d39f8b70c5b2abf463baa643b229beea5053e9e5e94aeb17dfd6b90b6eb695054ecab35c6c66792ae07ee9e606dedddcd036925f1aa07cffc236b5585656377d386e686ca59893a1d5023f434ab34b725c58dfe4e92de3d9556a4c9d6dc39ef2e527b6387958d3b909ecceee1d9584262ebabebebeee6397b868727d7dd40ff0180c62fceb6b1f5d5fdf7731fc46804d28b3ee267f97ff110e70175f5f633cde3df91a4dbacfc6011eefd0f5f5338cdda0ff7b1a73e4ee5c4cdc858b474dd575a9e627824e0212d30149e98064d475e54ef43c29a627f12ace99d8eddc2377a4e81fe234ecb30736430ce39189e2c725cf3fa77c320cc89272a573971b2aeb5203c09e92252629444e521480cc71d6a5f3c930a8d6f78ab2491a9035e593e701b9a17cf222205bca272f037247f9e4554016944fbe0bc894f2c9f7c12883109ee6b65f365f9df6e754b5776d947c2bcf5b75285d937bea76257d59ec76ee33f8411ea83b6e249d410b76bb88dcd2ed6e773712e64e325c31ff66b78bbb5db2166c1e3ff86b80f02887cb3f23cafc254cfc0722d89a85b97f4fd6a1c8e330f1cf4998e54cc4d9addfe94cc93acc7326b87f3b4ed02df6a763b7ffccf5ddc9dfddee069de1ae1b74c76e51c51d4d5f5bfc9f1a5ec547a51893ccf3aac110b59b874a3fca6769c47ef974aab0a535b1985c1f8dff2b680fe2e2fed1ed2a80fdb769c40cc8bebe2e187ed740dcafa1f867cd48ae725b00178e4a469334aef7c36e175ba6859a719a8481e7213e09037b6bb97f4763dfedcab77d3d925d177fe39219c4226b42a5a39c84556b62b9d8339a83abd086a2108ca4fa6bc1f27c3b4efd72a4dea6ab75caa5cc9dd0c128a99a9a9810021165f2f0b258bed289c384ba24739a4d22a0b890515931cee1108afa66c5e0c7a8af578ae7a1b84ba3be5a6578344b791ef30d2bdac2ed7e7b625874f7dbaeaaa5fbadab0da3b463c9b7b8005b88b912c33a515f2dced6f8bd870be469eea80f8933ddc8df3316dfb1c8f9eddbee7f5f5e7ce8ab1188e75b34c75df737171be4d479a916aaf7d9f46cf4af3764ca1cb65ae7db6f7161a6754907a3e56b53d76829e7289ea319dda0f9641960d2e1932450367eb3f6e0c5559d6192ecd50b40b22ad5acb96fdd2f8ec5cc8c4597c2602cc7666afda8a2b5b83b2b4aac83198dfa86588cab7d3bb7f7edffdcaef53768feaf0dcebf3330eeb7dd59f75bf75b18083302a6d38e4cabc0638bba09b005465c8abcfdeeb331fd7bc7ffe6b14078721decae8faeaf95147c7d2da5e09a44d15e06edf8df5c1fc9c3b4edb3a8717b2ad9599adb91d26776c180c1ce7816e7f11d1bbbaeefc66e8dbfd7a19bc06e0d7130fa26399d04d832e6502101253152dc2c89a9f237ee33803200ba3518651525ca0c254a289b6441abf099e0b44b3728c1764cc40d4a0c85214bea02394d2c5aea8e7275a22498249a60781e5a7675de7977d975f1331793b44b97342977f53831846c3cefbac8857c63d7379f992499563db92a4ae28a6e106f702098aca941baee19c3064c295d95202fbb1d4a295a8f2b48ed2aa39fe2aeaa7b25ffd36f64cdd0ea78ec7ee3faa1e7ad61bed098429edd37d82511aa9d366e37253325ebd6e5a85a1cef96c9257a46492d76ba2a77dc76a9cefa1948de06b6fa1aa171e77a8c8f16404e79a99f6ad865886e17e736af220c9b02c266c5a52815b661543a43c3a9748625abd2195abccab06455c066a53c5bd5fe28e0af2f10c37bb6a9554b2741db61af599625026b3ef989eebb55873d0b3089a2e270e5b2a96645d7ba679e6a5801a4cdb700945abf3c245c8c44db0df3beeeeed18a5b0e2a4bb02311658c20f9db080c5a3e9049f431f6058171d62f2140972125f223d04686e65b1292ea37c724ec27b433a8d24ae1b8bf92627b7f4673c2fbd1bea9405fe9af76bb2762cdef3bcb88021784f745d3da7ccf715519ae7b9efa5f1e3b57e1a2c43bd8ab713faf710773cfd3689380ffff41f79e9b1b96e96ce6b3ce403537df7726187ae05445650730f9c1cb6b18832fe5db7d0ed4f380b857353501435bacbb61abf60512879a2e88ab4dd4f7dc93542f5881c973685093b1ac6cb542ad76ee47489090d817a9e55aca8342010aa88899156f2ce418b5e83069a3b7e37d4d023311848a363faaa2d2bc4528276ee882642dab4bdbc5ef3da57cfdfe406d06a03684f701fc9923decfe810176862f1f81c3fe6a53a803da52be6e8f9971ca2e5f4e55a854c42b801b14dd1d2a6843318f12ac61837c7b280b83023d1afe698da0fbb1ddc4bce523e8f171bf5be33202e2c0237569692a27f2fe25cbf3bbc19040464157680b66c1f10a4b4da726c3d9d380077128371ab0ae64962bb179d8efd48e2461f3af50482aa2ec5bb5ddc8f792ccf9af89f4c285baa5a1763caf5518eabc825fbc128b8a528167a16773b5e601263125ad01eb5faa03a684d3d7d5c7bd224d858ca90da4bed518e49a9396cd67098c0c6d03df0938e0be50f8f429a21240ec09854766182c42405588651678fb875508dc7c8dbb978f76dc8a500257be784ce2c09b3cc0933272c8f37171715d689024ee1d44dd29952109258a52141437c88accbc6da64cd5ef2c45e177e7ded13b30afc6acd6b82286a5325f6a72a2e8d9a34fec432cef2546c2dcb4cc96f3448506ab229664451198d8d0292c2c1fc4692b03e59a4357a5ae55d2883019de9e770766bcfb59d4fbe4355d6770ae4e0506efdbafc003a58feb29064ea5db21ff6322dd40aeb2fd29657d074eb774b16d3e4faa395b12897f3c8babe479c6a3c901b65797f56aeb806b606d336b1664952561401f6bcd456304b3649401a110a74035b2fade53c89fbe93463e24eaeb5803cd656676740ea8773b93e3b0362adc036671fc92d17986448d815ef756e12832b7eca0343d8172cb74ebf6396cd44bc0644f1a70ac244d8ea75619d55498317ce816f183fc103aa11e78dce3787c61a8c02fb10f997135628c5587ddbe4e56e34a8ccb5e9ec377a03bb4550d64fe0c6cf02f4e48895130f48659ba91c9fa9b54fcb2b02edb769269861c98e54338f1a6e3275feb68a413a1ce5af9b9772a3dc9cf05c6b9c2bc0a8dc468f02c82122681d5b6c74d865b03efb8a3b066d37152618d2533901b8ac251a7cfdcc3fb8c43861d8a2d5705b44443b3a935e56e0eb84ada82ee8b120793549238e04617a91632b2e344755ae2a03110561fd0daf265610568c3433f929dde44c5ce6a9606edb25d746f2293a6fb6e5b3f76ad5fd1ae7cbc31f45b2f9817df54305e2e8e5bf059ac3d1f0fb7d3eb1e49c0ddaffb8faa99c0066e96a1d0a6682747ed4a0686308f5b7db753a68f89d77301bca7179fca95b58c0ddd900ee4e56a705163f419126bd7aab6425904b8e710927213b3eb273b461933485e48a3133e5205ca8205e9a420030e73abd47cfc98b21ee0d479666cd38ae35b628db6fa86417f3fde496a631d3106b0dfeebbd6236428aea0fc9cb92516b63caea92b6c2c119f02a5eb17493a3b22870fcb34b3a67abb4deb80621fd6281c65d23b30130946860d8d8d0f3504807983024d9728e30095fd3685c964233969ba2e5a7bec5a8d602af89de7198b33e4fef111e559f436956195c96613db7cd9b2eb8c02492bc2911a42aba1bca5daafc29b9bdbee672077c87e15e92a3391888a2972f315943c20a931bcad177986ce1f906933bcad1f7af3059c82f9f633285170b6bf39ca3062155337309286ada864ed67daf11ae1e2c685b2b6e779eae7d77e012c079953fd275388bf32dfc5ea731cf99007b97cc7779ca995b903329b729cc258e5efc80c995fc3fc4e4b3ecd52b4c8e6b182c90f592b6df9c9793cdc78f85cf0187dbc02a0112f72c8967b757225e2c20084825e38c5d78e5fa31495a76e2109348d2aa6332abbd7d1b26c9349cdde2faf961eea1015344af0f173893728ff90c8fd608a34e4748da9fe66f933463ce2c5ce71bc12210606402d8e6c3854394b20c6e8896e11d734247b0b993a78e269b4e9c3b79da7764934d690813275ba69b2472a6cc5987590605c387cb307704cbd2e48e65b298d039be380797521793a4a204020834e234c7fd15cbc33fb3ed6ec7fb6192eb5fb35c24fa278489fb33dbe2ddaed37242db6e28052894532448ae6d81210c220b70891480aefa610343ac6cd76e1769f0d1d5e1dccfbf870a6fd9f66d1a31cfd39f7c91de43b4d81252a33280532e0e1ac94b17f259d6baec87fd79cca3e38bf30f69c4e0a2b6648cd0adccc2c986cc88520034d3e798a48d44f7966d376b7078cce8c484af72536e99d1c6a087aafb38005a97c1a953c223576e1206a0e830daa3dd02466cd3dc63087468fb5e0b84498c3049112607401c4b12072c14d02f464218863959499ee4a26964dea678351db4dd5729352cbe1a7f0c5df45bfd31954d29c29880f6af8418034b53737ea87772f15f6dd76ccc7c45f02af278625f64b410c816da7ea117a850b62421d89228a75ca3b0ba00a333cf0b518549f1a5c5997b9ef0bc1cc1a131c98908ea6769db378ad987daf20e04da0875d85106dfabb8b91fe9e6cbd88354c5a7a8877f81f8b79ae763e2a38e3493508346fc16a42b1255f43691f4392133cafa00200d070999d3732477f45c0ed81a0c69c80da46de98d4c5bd01b99560216decbd95f931c935b888553b6419e2232419316f2b96dd23aac9f2dd37b79c27c96a55fd0cfb2f48f34b2b05c7faf1afd5136fa2379db7af8847b874f4c4383634a52eba8d9ed62b2a1a1357c49f576530587da90888675086132ab00e923cf8bc85cd661c390926555d67cb79b93150dadded400231f0b808bdce7e9c896765067ad2099773bf3cb84e7927cc4970e41fc7853edb5f267035c18e9d0b7d584dad363053d4d48fd437f41d24d7e31ffb98470062460008ff61f880525ed9f15989cd3a99cdf7b3a955bf02b37da42b5eedc9aa7c557ec35abdb6839ae7ade0e27eb57195ad1571186462cbfa2e2788e520b074ae33c996daba7d068354ba0409d4e1e4dd8abc65c57b7a2654bc15ae9ae1f2a7d8a3d49f590b4332b826cb356f2a802e0f11a327a1580a5204a6b024be15c17636518900a45bd019d7e8f1ef7168b5e19b55694ec6b33d08515a8a1c258b797540dab7c6f21aac81da41a171ba91e0ec2a276946a2b6c7bdd588b426101234cace1d70e2d984c52929019188c6f034cce0b7445564d28c8c89ea3b88ab844ac15295b2d49e1e119fb9d3c3603aed6475347e84977bb5705f9bddfc8ac0770afd472f59989ed6ccb006c5b394e49bcae7f54e5e46df5280cec37f4ad9e39f29ebead4dd7871ad8ed5b3271554657075154d9dc008fd4908c8f3def022987c8eaa8daed8e77bb0b29a1833cf28eaaccbbddccf33ac7f294bf442bc2fa297f2f17c3a31142fc0eeb0bc39eef76d6c3b111536c11c5b732c044159874deedc1b89ed20a80123586f80379942d3313bc16e93af31fa1cffe1b40d19cea68941fed57efe1d5a290fc723c473345473e016ef0c9439c937f963fe559ffab7a92e21df9b9fa2d5ffda57a64d1e814988c3a7ae98c3cc6dc34305cafa5c02b773894ee7f226535fe3ff56f16d96a699807629aa302e999df1ad087d9803e4437c7ff9554edf47f26652bfdbf14e4b4e4c86ec7cbb2c91f539187093a25b7581b8de0d14749bad749b8fd00a6e7722926e1d6251ffb72b0254399513507d37ed89fa669621107999472763147777d8b25c83051ac0b6408f99694ac4d99027ba32cd2cc3fa4c8c1e9c7d927f68f4d2ce49a6af0669049f924119b4553cd810544ca8557d5515f8b56db275a7a26962fa0e42b9b8bbb2a4a6d8c169030d3fc91b5f4c1592ab73a545996f13dbf16222c935cfed370cc7b431f100c87a3f03557f63993b0370c2cc5761854211ed48ad177a3131618ddb4c0b820150980be685a2527b95c55a607f6e26aa6e9a13049729d379e9b5fa9556f520af2d1582ac0b6a58f7b53fc4aa94a7ea79263e5e8d54b49161fadf6bfed87d6244bfe49aed1ced05a9d101dc71283dedbc1d0cc8a03177d8b8b8ff7e0c44d4e97b8553e49624bffd58ee29bdff6439f2b8c4ab24f277e6f1e6d31b1fbc30b4cf6022d839c22470864948ace914c93ec4add533617f29bf3e0a37e9079ad26b78b4682cd4d58e3113c51debfb9b91792a845bb1db29edaccb04ae23db7d50958057a06a4873915b502c5d3058aa70a2c504cdaa169f271de3c4612a2c61bd648661f182918dacac94a525ece55de9c2b5380fd25813b7a4936fd2dc2ea8e739df5cb54d2e19e97799e1a7cacd8b8260f61be52c1d56525ea27a81d302eded737ca1bd8151fe87bf2ae7e2966d6786eabd5152d00ab80ea00d9edc043ba2e47c40a419c61629bfb08c623265a14d9ea265b7557ef8e82e4059203591ae75bfad9d3baa2b3d43a5fc129414258744998b3e84a7bd6e77d1ee6b1762f9cf060147a5e4829154aed16e2dd8e21dbe6f393bdb973ad2385b064ea440399bfdcf46953bab784d8548a9629f8f9ebb1bf943b6d0ecfb2a4d5de9ed3f5b9c44dcdf969930dbb26b7343093a5c293cc1f60b2de97659535ca0d9d8154db22eadeb56a063a911472efa4d438a5779361d04093a96ca3f7adeac6ccd72c978aa2c88a02cd31b907cee7adee533fe5c916c5983cd07b4da0cee8433fe5efd2d92623b7f0fbe76423c815fc7c2bcfd7861aa35deed64d6bea24d7d6ed0bc8dcc75f27c32bf469b22dc50fb519c9b9e28e6f007fdafe46bda7946e2b89662a393429882b858b6f9e272a81dc04985cfebbed514126cf41ec6a6b0fbcdf6bcf50b507a22efae679a212a03d175f6c0fc38fc7886172e67967a0ec23936372166072f2359f5eca4f6f3def567f7a496e034c3e7ecda7d343913530b9f2bc2b5de05580c9ef5f53dc293a8610ac225d69f2edaace0498bcfdba022e6501795afbfc32008ee36b64764375f6a3987d460ac870b1db955092563cfb452d1c178426c1bb9deb56dc5c1c799e9ba76992c72aec703d40bbe7f1464caf50c4612f62ea863e9a6e5d220b5148f9ef35527b3e9e04fea4e40c734c3e55d6871029f17d151f51b1c6d8f3d027b391e9474c9ad9204e45990dc800bd209f3419a027fb5f2c25a92cbf00541e297cd0df49f5bcc9e95bdcc24bc99477225ca8b867edfcd63bf22885c07551e99eec331ea37bf209b715fea179f8afc8634dccd8e70d0e2a1e124b7bf928e7a6d406bd014d0a50da8591272e8dd8f4b9c084635c7c6ab0c9d6c921595d7decf8133d98444f4350402c894f5fb092f8c3d1b33f28fadf0bb32c5ef03fa019762e631e09e65ca662b9c9fef0bf9278c678c69cf3d3ab3f3c3baa1956b7dab990701fcba36e365cb2d8568eb57e779a9d94362e355b0dd010eadb9376fb495da6ea893353d694530606952c52d818b20027154e7553d3343860b80dba043fe6620b376bb55aea58ac0c2437edd0e586d39972b463935701752192f02b0be9a43e78925fcc10c3934150155a593a0126f960c45f0f0760c29c4fdc1bb7ab015224e57babddca10c70155e89e83e1f3172f5f7df7fd0f3fba9d276bcd0f5faae5cac058bb76b80dc07f51510dd9dd88cd17cbf8f7db64c5d3f53f4496bb26c6b47bc088594c584081f0b77f5f8d169867d5c65eee2e6135ad98815f4e75a00c8b02e171ed9b46d4e0cae73a231bc0a620091d8e927da332f02b35d90175a5bc47aba4f024c038d4b7962492846d338902ca275180355630d82f55e2ff8c0e46b30a8161d6ede2d814904d66812a43fe92c5c0ffcaf178b3e7f8afefed21fab159c2b6274c2cd771138eb932f1709661a67d381977ca0d627b2db77c6fdbb47cb184cc6c644a2d7b1573305ad6268c0c60cc20670ca7a7e7ed7fc1ad5248f373b9652be34432304b2457bbb974865003ae3043ec4cf50ccaf25a66288a4e8330f0b6480355732cb31a3faed629a771010d69fbda1ed6b1fde0a7d64aa7a95ce42a781b49e8242011ed0c21de7135ed73841f23cfdb781e82b71b835f92d08de10112eccb8f4852fab22f11ae79d469176563ee95a1391e45b433b0a85452da608ed46ed9d0045a35ea7667aff311de78de66320bfa62c3111e4185d557c5461984431b1b57eb82526a0f026e33a85210289037dded3a027b5edb37a2561269160133228f81b6c522ecc5b2bf5484bd54e44201c4bb721057164af17c6360cffaa110e1d6c6255e23fc58847dce1ef2ab7876dbe20a54a9089ba4aa375421059af154871690f470c4f7499c3a56785db1c88351a2ecef658daafd984846ceccda6e17ed76195ae282ac6ccdc1a666ff66baac351295e13ff41d1724ece7719e30ea6aa0479794988fdaa18edfc95330ec876271077e8b7d1d1085ba6ef590a94c29a76b02c046e62e129e533e63eac77c0eff4d7c092b8f060c4a92f2161392d92acee1c75ab035e3f57275da059fd5cb4aca22f6cfd649201b3a8d7914f33ae2ee1e895d8b74c6b2cc6476624564cb78f02e0ce0ec3edad7d4b8472ebc5b46b1f8ba4a20eb812a36ab30bb6d51070d5afc356b26540d202075329ca5b3309122cbdc951c34cf9799effe77c837a188d9cd3b3615ead779188afce6cd5ac4c9cd398b6ffe7bc36376f3df9b2466376f368b4d966fb29b4bb6ced96acac4cdc56d9ecaff1fd23b9570cc32f851b223372e26aabecb652a72a854d67773aeea31b5c83a640db27059ac2c5296562be89eb1db28dc66be7b99f2285cc8e6c2ffe39867f2ffaf29533f8e531e31217ffd456ce5bfcb3087e7d6f274d32e532e4b94a5c9926421f273f96deb67e731971fdd9ccb4f6e7e4d6f8ed39bbf889bcbb0de7b26e22866ab8fa1c8987f74b7daf1d5514ce2ece3790baee2d1dff9ea9ba3320a53f1ffb0f7efcf6d1cc7a238feaf6ca68e64b20441a4fcde986629a11f718ce47e8f7c6f2a9766b686dc11b024b0cbb30fca90a15392a8972dcbb612c9b222f9418b2f917a502f5b9249a9eac2fe41bf50405c3481b88a05ddef4d6eddffe253dd33fbc4020425395672f803b0333d3ddd3db3bb3d3dbd333d5ef5467b7ad90b9d5bbbf56e32922332f91f2922ebdd4487f46f526477226be8e91e6ab39731689dfcf6eb6fc8e4d557e55c8e245e7f63bb48cb964512afcba4a7674b2ab5e5f7bffffdef49e275c84ba9542a25b980304472c96081aaaa6a42aa2fde9d80e74e57a929bf6dd11ceba17999f4fe0fbc6b9291eb935e7f832440f9f28254f19ac942f0df3136c4c94bbd2e3c4b2d81ff0abcf4a6142ce0157a5fa7d4ea93c2f5408097b21693c9eb04a356a2d713c623f9ed1d8eed984c2686614a1b2c9218a6962d930d9694665906130a4b264fe8d230a5a664b12178bc2c92b02c996c5003801c62e534dd716c92c8e5b018b23623890c163a8e4912990c963826230915c1f06c265415c12a652491e2a4e0092789548a53821cc3f3e29fd0a5414a4d92c8e7b10833bb132acdff76470a5eb8df9aaaa6d3ac78ecde54dfee4c6cdddd66d9aca0b2f62d098317c785f6649b7810d742e1397e612f766dede82696cd880cb3abf6ddf80ec86fabc64eb933a11a79f9a9ddbbdb77b7e96d4fc6ed1768ac9fc494ab5326d53192d82a93ea1724f1a44caa6749e2299954c749e26999542748e21999542749e2599954a748e2399954a749e2799954cf9144874caa9f1398b7bd0d7464d249124049265b217196c8e449488c13993c0589092293a721314964f20c24a6884c9e85c43491c97390384764f23c243e2732e9800726ceaf8b2b55bb3b786cf5ee4e19c3c5766f95d986ce8e8e17bb9ec483e53a3a5ee8eaece87ed2857676763f253fbd3b41bbdeb6e45e52395bdd57dd2f550f540f4a95d9ca54f560f5ddca3992207e46aa1eae4c552e542e01bcd72f98816b1073a6fa6ef520e94bc0235199855a588eb900e570be2f918b8a71a9baaffa6e751f17c3cb44c5700b3c313c40508c4bd57d95a9ca64751ff1f21eed70be2f91890a72b53255b9c9c510c9a8101cec8920b241013868aa324382f973915c5f428d30afbe5b3d5c3d00cf00263cc6c0968304539e09b23c5b7db732857537a8824ef548652a98277d8954b4b5d7aa872a97a115980831e420b795980931f4ea424ee00673a42f918fb2bb2964e489303b04b9ec30136677131f2ed14281e0b55050eedb9dd09a469110077a725b1b66ec182b91f6b2be5e487bdfdae1b5b26086dee5f4eaf0baf5b5279c40b83f758b96c093378d2ebc35072b53d577b137aa7b2bd3d86d227ba03255b95cb90a8d3a0b25d577abfb051c6e8b7b330f0633fb45a672b672ab72b5f215af7eb5325d99a91e002258561dadcc540f8b6cf560f57075af5f7aa9fa6ee5aac8f6d59b65a66f9619217bc908183d95a9eafeca59b8410a26272ab328e7419e9dadeeaf4cc15b5d195304eae5ca343ef8027011ee61e52acf9caf1e80c79e67b02dcd6c23976f8067885f8897c7c7e3d1983e1a51950b0a52542a9795ca45a5725ea95c8dc5c6d1eca5b7e8802dffac638dd6cd96ffbde78314fc3db085136be044ecbbcaf542f5c09646e61da91e203042b468d791ca7522439d783b0a6e9d504d959bd583954b92b899a8d0a2c655e556e512bca1cd718306574344df02ab9cad1ea85c6d4cd237c95621d98a71864fd8a5807d065aac3287004bd6da8845dac12613a91c247290f05219486420e1a55448a890f0522948a420e1a5f290c843c24ded4ec054146f7a9c0d150853561dab7e513d5b1daf4e5427ab53d5e9eab9eae70d029749baf0027bb52bef6d49274802f91996cda34fafc2f14db501753b4a3d01c42bef852dba67d0a2ebdcfa60265dbd6edbacee0acc3a2be7d1eed85b7d5781bfea5ed0c18aab9795ca590ea9ee57b84e062d82660c26a0006c16c03b5c9951825a5809ea6025a8819590fe6d38377dbc447b4c14ff94e0db40f14f3d9ce23f5bb980838aa08a0309d2411a58ff910f040f37cd6d79961bd6cefbabefacaa9db96e6e8c1951a4f18871bab931664b245bd1cdf0c234d2ccc49f898819737032929349704a2026cdc159434626becd2ea6ce41a35e95896baa8b19b46f7fa764e25ac66212ed9bca79a05b3d0854c52c1ab26805cf90a046ec7898396e8c421cda195088beb9aa048dd5a0de710d5557eff826aae21ba8952b4ae556e51a689e6b9599eac1067a47c02f55cef3646375f83809d64c19cefc04ca70e6c75086ff082b785df9ad2bbf07517e0f6a0efa1ebe4e74f06d45ffde93e8de7b0abd7b4fa373ef19f4ed3d8baebde7d0b3f73c3af63ad0aff7a83d6fe6bae76dddf3f62fee79a3ab78de68d0f3a673cf9bd9cbfa7af5469e37daccf3a6fd937ade3667f3be31a6852c20ed719983ad3bdfd69d6f8fb7f38d7ace37ea3adfa8e77ca3aef38d7ace37ea3adfa8e77ca3aef38d7ace37ea3adfa8e77ca36b73befd2bb8cf72747db6b83e5b5c9f2daecf16ff09668b0fa7fdfe89d683c4696aebe134b5ab07a32a51f1cddf47fbc1e3f11471dde87e7cb5f7636370af0f12ff7483c4bfeaf772ee207de691d9fbb6befeb97c7dd4f8571a35d6d5f9bfa03a7fe44bc0376bfa808606be483de7a59eedf0817e72ab4c36f36237b1b5c34d3deda59e94c9e6e2bc3e509cc7398497eeece808e49e41f46f2ee32462b3a30f3880e1259ff493cf40f29bcb02399089991204173ee5a93e424d65071b316956c951d356e8b0c9209957b4bca3c35f56a123ffe158b66231ddced37e533186f85537f0a2b221dadf647f4d9eeac002e80379411c682369a00b24811cd06aa0427f41775153c17f8999f6dd5396a6140fdd3d657efbd9dd537affdd53127debdbcf68ee9bcb61b0f2cbe27c2e58caf3cab79ff2f266aaf3177497f28b5d2f29c543dbdee254955f6e7b0b29f0fa8df5e22f7629bfc08a584ff9e536a885951ebd764ca652c97fc01e997e275d9cd7258b523baa0b2dda4f339112b1ed257df754f6ee295dcadc3db5c3be7bcadd01e3e3faea4f2dceeb774fe9753b67865871aa298956d4dd064bb20cdda4818d34774f8d8cdc3d954585d7af993ab2912caa6bf9bba7fcad346e3e8758927af7d47f68ff8100aef87c40866380609edae319959740077a2a8f6752bc84e63d7507c93c876a594fd169d9fab94e9a0ddc3d55b0ee9ecadc3d6516809e5a9cdf55e08f7ac339d0963fb44550dbff6dcb5ab6773dd54d903391f924490880d967bb894b9cc884935f7d13d0e636aeb00aa0450bf0e34ab0804050720df60789a38cfdc3ff3679ba4f1c68c3367476fcdcdf4664f7ea7d8582dd8b5fdf378bf48b5d9d1d1ddda07d75279bed8bd94cf4ec838d2481c05cc1105809ea064ec8118c1d677793f281d295f247a5afcb1f95164a73440e01caa34426190fb774b53457ba56facac30d0200976d2212d9d466766d62b8a5c79281c3ded2f5d2adf26869a174ad34a704b3e523a12c700f968e364586f7a0ae014a48fc23a16c5de39a22c38b54d76625d4e223a16c5d7f3445c6b71172a5eba585f27b4ae95a69a1fc9182e5c7a01cdecad27ce97a796ff983f241c54f02252f539a2b7fcadfd5d2d5d2edd235c1c4e776bbfc29d9ddabf705b5bfb9a1b3a3abab73e3464874fcacabb3b39bf676f4c9907db16b2b87bfd0f5d4c68d6d88f1426747a160f275235b3bdabb696f679f4c7bb7f6b5ef8e8ef3fdcc1fe7df16534e52de5bde571ef51afb8152fabafc7e795f690e64849b3a57ba559ac3bebf057d7cabbca73487601754de87a04fb176f950f968794fe98a4feca3d21d37f32574a3400414410ab3b72009a4ca47ca87008fb3fbbafc11804b73a53bd86528d242e93ad2fa20346e5a36d5559a357456d7aaf744abf8631a68515d7b446b4403de0bb7e7bd607bde13edf1cbfc1609404c9bea5ae4b7670e2a055bb43b6c33b96d126d112df15ae049eec92ca4f5e414127a7279b27832c4db59deb3025d2efaf4ebf2fb0a362000e2e2cc953f2def2bdd46596ea156c0246a8c43a5b9f241578a3be50fcafbf0893888daa43c5aba5cba0d6d6c785b43027cb04601e0d96924003e57ae00a5b990009a256cae2d6ff64addbda5b3e5d1f2a77d52775bb75c9ae7daa4f47579b4fc7e01b490b84b77005c7ebfbd5bea7eb34fea06eb64cbeea82d09aa121ab10042c35d28ef819b771044c39b12ef3b4063728d751f95f92895ae26634cc8d2d56462353b3280136f4c96c640bbc20d95a083c3e664e924bfb1702fbd62df4e2c9d2d1fe2f73c5417adc5fa1808bda5b3aec528b077fbc66500dddaa9613c8f8c6625559a6f6b6f7f7b805a4cea90f1f224bf3ccd2fcfc83e7529fc644498fd1cf13b79b5adfcf25483da47a282ee6ec9b42dddc187feabf03671543bf3e551346ff195074df875f9bdd2adf247526404976d1cc51319f8c15f6850c441d24e8406421c18ed8437e0e1e067d799a8a585d2edf2a1f291028ac815c091020eb21f14f0e584d7744f69ae99b91a83be7693d595c4b55a8302b9a62b6704064480552be66bf9a30234eb6a692ed6504dd8fef3c51f2b9222f82c10555c7b7a7a446aa7b8fe8ec8aefc1b3a3b7e06f6004f3c5928a0f9dad5d5b9d54f3ed90dc62fb605ae1ff1278ff4f8543691cd2021f9b90824e715ec7e64066f9d19920eb81bca1fe0730e9d7a4329ef2f5d2f5d29eff100a57948c04835870ff48dd2d7082bdd54caef9716a0cafba5af011146ecabe5517734bb0e5ab074bd340fe4a0fc76e9160c0a3e60a1743b587e0ddf050fd0d8738102ef11a20a018578cd4413420941047bc1b6817703dfcf6bfe5077db07007d18eaae88818e67610cc0c11007baebe57da52be577a1fbcaef02f21d0061b2bcb7fc6eec50573f3e5de7a3cc6d1867909be0223808aa82624ba3d595c068b56f2da35560b00a8e556bf27434777434199a8e435f94f74aa52b7503d3591c94ae878a821e59171e18acfe88bd078355b0f0c1469fc0b0f347a974a3f45569be74032c11b087e00ebb038860153ff88881ac31a91be50f22845a1c89ca7b4b5fc363141889f05d8647f986eb5b462bee56e976e96bf80f8d44a51b9edb250acee1e073034d2d78945def4b0078033d30a8b6f77afe179e850a7c48bbeecef9a0ee35789b883fb095ae8b814d501620a8ed0d74bc973cbf4c0078a3959102544901a42880c430a6dd80b1f146011ad2c0cb2142cc6ee8ec48708786e7d1e05b0e50b35f2f5d21320f452ff20b44d65fececd8b8517f616b071f1da093707f82cd91ae407eab974775283fcbcf367dce479b07b047e0c71b2d7281d1e27f527da7936743346b282fb39d8ee96652d4d42c0d93db766aa696e5e9d4ddd378fd9fcecebba77591ccba95febbcdb1b6df3d6d53bddf311dccde3d3ee4d8778f7bf9df183b03a53dccf2738d8789ff8901a47682602011480252007be08b3c9113906f1242ead7d4d494dfd8774feb774febca1bd4a43655b699b49f2adbb234a7595479cdc95165bbd6af995a3365fe6b6a2221200214a03ed485aa8d15f7afa9f21b5b7903782adbb2ca6b8eb25d7b988945f8ab1deade5e5bcbb23ea947eab5a8de1754dd8d8aa5deecddd3e6ddd37d311ff65aad13afe77fa1492e5a58cb6fd7f4faa2a096570d3d54ee6bfb5f3bba535714ac6adf3d9dbb7b5a6761022d3ab087ee1ed7ef1e77352b95faef9e963658523fc02c9958544f5349a539fec755298f04a5491b54d4a1393c1e5d1a6259a6731d2a20509e910997ca2dcff810285765029ded96aa6e1eca523281b7c42d4bb97928cba36c6e515e6437a83fc627bbdad4147e86ab4d4de387b6dad439fcc8569b9ac10f79b5a959fcb4569b3a8f5fe96a5317f0b35e6dea227e68ab4d5dc2e57ab5a949b15e0f28f2057b4093afd803aa7cc91ed0e56bf680325fb407b4f9aa3da0ce97ed017dbe6e0f38f0857bc0237ee55e7f70c1456df24c6df2766d72ba36b5b736f519a6e76a537b94dae46c6dea506df27c6dea288202c5937794dae44517f7686df2cf4a6df283dae48cc09dbc539bbc8228538714e030b5b73639eda5ae604d2839589b3c599bbc81d53e533075c825f319a62f62fa7c6d724ea94d1ea84d9e70cb8e78d0e9dae4857adc3194e246a4a0b1a20d7684dff8a6ed6cd242d1b66893a26df0a50f49dc408763d79e47acf35c284eff080ae9832ed6264f218b93d8d77ec179146e2a021aad4dde746fc24c6d723cc2e04bac74c2bdb5c10210dec76d366878a2fb124705f5e56b2856541a5f88c603cf6a9ce3d98eb6c82a6ed4da2665e45c4e0276f07c7c2606300e962d2b54b2c615280929867afc342406357eacc247f54c74a0725fcedb58770f7404a463e72689c8488515c72355021f5d79399f0624d63248e19330076f88ef8b1282020cdf9113a0a7e09d3b21b96fdf09fc9fc63b39e6cd021a94e680c807bcfa457cbef953fe99372da8836702553e764981b2f4660a75703550659253f3a60e01482a2ccceddae40d6f0e1180e40368e76b93a7e16d7427113ea4f53589b5a9a9dad4746dea5c6d6aa636355b9b3a5f9bba509bba589bba549b9a5c6575e2235c8a58e7f2c3b7f9766d72bc804fb578c00ad063f0b2cee0ff5cc155937eb9a8b6c523f8aae198112f9ae0dd897babf124e48ef604f1ea1298b36cdcc85eec7aaa502011966ee10b4f6359883d11939dcead724b8b839fea0e3095d90b9d1d00f09beb7a14a322c80ce66275dce500b547b690336014cdf3bd0bb579be79a136cf772fd4e6f9f685da3cdfbf509be71b186af37c07436d9e6f61a8cdf33d0cb579771303501446d1bcbb8d01a80aa368deddc80094855134ef6e6500eac2289a77373300076114cd37daced06f048da285cf6ab7afd6e68fd4163ec2ff63b585fd98385e5b9857ea8af7d516dea92d5ca92d4c72a4588cc9dac2b5dac2c78d303eaa2d7c0a341a149faddd3edea8ec58edf61524beaf09f16388f1a726185fd46effb176fb32a03664040db9d684c681168bf761fa4a739183d8a1fe6d62c5addfb97f9e3b17b06c01f1b3dac2e788f58edb9bd0e54ab82cc42b52f67140ae6398fda21ee96cedf6579ef0f5c527b0b3bf701b722d52ccefe4243c54d8a448f164edf6786de19677b76af3479a5ac5754d8d36af6193629a11237a8cb8ad8ac88de7c750c0c62677d4d07e70f37a55a3ba91290d7dc0fbeb0bec98fd7566356facf7982ffca96e5563dd4b7f02b5c43e41f6f649ec1dfe427ddc57677b2fecf5fab4def06e46fae3dac287deabf420c6f9c259b85701cb1ceee57197d5596e9f2f9c75552948e81be380fba1fb741caccd1fe5967808fc714403f91679188d5be40b075d2df4e7dac2bcab1c83b55de3bc0e93dbe7ee1daaabe7dae901046eaac70c1e5e25d76a0fe070c31d7a64be0eddb5deb1742da6fbfc586dfe8bdafcd9dafc786d7ea2363f599b9faacd4fd7e6cfd5e657db58f4a39aeef080fdd9edce8f6b0bf3051c38e7c5180bd03db585c9425dbf5fab2dec2fb863d8bcfbfa40b6504ff4412cfc3a2211533f4ea0b0c11f27dc8398fdf592b8f67f5c577913815801dde940ac6c721caf47363ba85f9beaaf1390c8a6d89bc2bf14d57f9a7a3b27931192e8c77f5526bb887b3498e41dac6af7b2e440869adbecb68ef6be6e2687019b58d272fa2d7e7e5a67fbee36d62eb3dd6d6fa38bdad11d9be9c2ad9cd376f1d75b65236c570657552658cc12c840086bf20ad34798a9fcf289cc4e366232534931c7dc95515eea3759564951a6a4d8ae0c1b61baf28ae13093292f1996adbcb293e969236b28af02a8c7517ecdcc5d4e63dbf615a6731e401f8823e9974618500592401188095a8d0e1371b2caeb8eee0a9962e6c01319662abfa78683323153d94e55c38cdf81e09e1ee2530112501bd96fa76a93d3431ce575401735945776468f0f697dcf42a697f5e572d23631e8f3ac6c5908891bf67ba934a2edea8b19feeb4aa400f1901dd00433de207855dba58d482a8d9a01bfa3d0eb06dd950915863e04d1e807a01e36f0848f1ffdfa334c2d667ba5ad8cd974733fd3f5f0caae277619384e3bbaa4b37ee6a892c5d286ae325d378a37bde19a69597c677232714c69c47b87c4422fa8ce02277f605a45b078b1bc555f8e29e14be7aef8724ca93f6bd05d380206b58158c5e0a91616381ecb7ef1f96ed6666fe8ec68976d78bdc50a87ced00a87a742cbec9e0fac5d122ceb162f6d22d20896ecdebdfa6123b478b930c2ecd64e1be926b47899c86484d98ff08091067b02ba50edfe5cf4a02e56895996b77ccbdcd425a4b2d890a3ab947fb86785c293fcf254b0941159a434b1102ce751b2bbc9205375ca8f81a144c62c734f8511e8b918ce6e8558c6a2baec62713a99085baa4b16b5054f230d190f3513d758408e6f2845d92d6abb4d54d518022ad5890cff2e9b542aae6583cc62038d5a8685c08ca75c7ef97c0ca5b4010f56034a58087d24b076d78f5a5660d41ac4f3b0941dfc342c6f879e96557274501974744d1974b29a42f1202cc5e2c76051dca267c055c763b0a8a9a86c00138d87ae41aa27815312d824810da40693c006feb2496093042649a09f04e249209c8c211a1e1cfc914d67ea20cb0e5265d87093438a631b261d522c53830744f9e628b3474c9b0e29c30cfe2da7dfb0e3c72021bbced424504c02a924104a2295245048028164e3114f67cab0a138b66299504919668ae53ce82ebd060bd7a22bd792f5435cb2f9dab5bae2f8c10c9e734b72ea36e839b64983e0d6d79fb9cbc49c3ea957dc32483a8105664f8690f86d8ce23c13c6815b1a4559659d9ae3ae4973dc2569feb03be87c7394996e031f68819dcb66d834be1dcb469845dbc09198db12b6b696f0da5a5d7b5a310876d18031300c5dedaeab1be60781a1ca071bc08e5fd60dfad01bd985daf34676544b8ebb967b95d1f4cda43f8c920d6a92fc58ebc20602418cde0eee1149a3250cea91a1762c4e29b49fab472d0d8a2b8ffad1c82a346da08204fd6832c518b01db872fd683245c563024d167aefddbd302a93382795498299ca24ce4f7d8273448096862bf2c52bb2569fe0cc552679fcd5275c09542605849062e5f077a5f4f41a3d7ddd6d6f5aed9b401d6c896c1b4a33aec351758bde48863b23a95054e276123ac153e2d65a94b8aa3939a6a799a26ad9aca35b8aaac1d08457366032480c1a0e5c4698ae728065d17e9b35d3e26a3aa9a8d9a4a2da49451d482aea605251413aab89f656d38a9a55545b5107147550514714357e7ddd4328ef58ef64afcadc056cd9ac80c6b82c3d3498986499d527947b365c2951a7f3a5d509641153aaa3123734c46c8ca1238e2651896c6aebfc5957176ac68ce198565b7b37c9328bc8244b49fb262236cdb8a3490c2595e58a9faf915483ed3a5c25b64eca1d03e2da97d1cc350815376ab8a458d655d6c3d4b2a8bd06b2ad2875f509fa1f4ef14240b3efa0ae5a77748bcfef82a73bf26c0e676b686e878f76b4089fe051296398d49be2650c9359de244fa3fef18e1ac0539c1c26c5e98ecc322cf4803aba44f5bce7f2a47ade6ae16c47b3a017ec4271ba401b6e8b11871273f3d814667337d189fca40713c633cc1a8ad3c4dd3bbd93fc0cdd7be477982814daf42e42497b826dd21ff1c24292652ad395e22ddd3095fe6f4fb15d4c5754a79fe9cad0c837a76da683e5688ef85736a058e630d3955dc5b16f4f152f28f037c87425ab59b6314c5565d8342c4d67032165a5232b64847c8009b250be393a02c447902ea7ca6902452016a26376f56ef94396a95bb4c4963f00354c00454ca84e3f5e813226da807c41c8fe6f3ca1d376af6ca0e0b5cb4d0d305e6c99c3784591308562612aab59781d368d2d5a5f82766df9431b766501bbb220bab2805d59105d19c7ca4db99215b0730ba2730ba2730b6ee716dcce2d64998abc9015f0412e05d1dc910120c4c9702240026ab76fd18247e7079c032f76a24779e3c6ce9f75fde77fb6b12d9d1da153f2f1914a98fcc9a60da6f5fea4b85030bbc97071ccb5dd881cccd19c3bd7b42275e8a63610cb9defe7bdf93e6997e92612ad1e9afdbbd37853241d77d26e38f5b3ff303744cbbbf89c1727e7b10acdf83362366c8a24b0c284c72a30eb0fb342b4bc8bcf5971721e2b35d28f2ac3b9bece72f51e8130711529ab7af102270cf99fbb1bf3423473df9cb68a1706a0c93ce5114fa51a759240f4eb7c7b497415cf7a0e84082fd3182232fc7b3cf2f9063c4c63085a9065e22664999d8f71270c04dc0976c858d445eedf599abd25d360590484aa90c3bcf737cb549df2b798465e66bcea54bcd4aad3af53efd5c6ab4ed7f08a5be6b04eeb5e74bcead47be19d98579f27b89a0a34aebe390faa208256b26ca249990a412ce01706853c21df9cce3265d8d02151bca0146fd9cc2c2e2896fded29ee07b1474c9b0d29c3c531b858c6ea7e1065d8003a8a654375a8a958c66abe8fe615fe817e8e18374722cbeb243991065e0f9d59d248d4e9b1ab78c1366910be76afc788c4ef9326c844e6f71e9a6b1e8ec4ba4546c0a0809bea84c83c154470ef7608e3e98020fc2908153f1328c6a7c3a51f728e8cc01be5f5c3da9c232e7dd0f159c369ad3710b978ae799fb814e33b26d27a4e71218ee233f514233db176b70a4824ec6f038c6e2391831ffc65e0077f2afce02f053ff8cbc32f2f1b8fc071f2880e761b180938934bb7be3b56de833b450f2918be62cf77c7ca7b95d29df268f9b0c243a5b8fb9aff32fbddc9f29ef2bed27ce9ba521e2deffbee98f297d9f22827801b9dbf3b565a50caef97eee01ee4efae966e29189de430461eb8d2d8d3cc05112234631f66cc7757c7b36cb4adfa4af948794f792f6e31c78dd3e551a0b00f2ee57d3ee048791f76cc1e1ff47e6941244bb7be3bf99759dc141ca27214b3d7ddece1ef8ee116f17d1cd074b335ca25e410dc91a3e025680b9a4db65a5f412a82864b41d457ca872375d7b87f6f732ab5d9d7e5dc0501b7a2f475f940e986f8c2da5b1e2dddfcee58f9c077274b0b7d524fefe6d2fc7727cb87bf3bd92734feda2bc686177970320db6797f569a2b7f00755e7f43eac58dbe0770d7fc9ed2f5bed0a6ef591e2aa201a2af67bffb883f234d288a355e7f9929dd28ef2b5d2fef151aad216551a1f431be8c0bdf9d6c56a1054517ffb9738b4feadfb66849f6161b402313b76e2f10790beff67019bce518cb0b7b07c31bbb5fa831ead007a5afe19de27bbeefc0fbbc19de1de92fb3187fe1167f073da746149c736b05b678c7ecfa464f8740f45be16fff0e80549f227f43bd7de0229bf2298987caf384f880bc87c43bc5f38988ecea7bc0f9031a1a0204ecc7f3a0074e9422bf3274bad3547e99d9c9769886a9a4e84ed3c6a5305a36aba4a8a6a45806aa2baf18e68e1d4cd7e90e65db4ecb56524cd59457f3aac976286fd081cc4ea6aacabf67687a47bec997c55f193a320346624d0cb200f24017c802552489e41aa8f39ebcaa4adb9dac8289d7b38ece53a2013ccdcc810c3379e657d4e109b1668613a0eace1616ce00751038c54c05e8b4b47206ba4f4931e5570fb770e6c70a85dc7ab0cf5799aa6a3b259a8b1ad5bfdf6198f9103cb8c0c5850716c4a8069382e0d0fa196d27b333748787d08aa996633b230b62f2ba54bcc6e378e6073279554b4b4ccb6a54a54e70358c46c51e68477754df61ca731999d09dfe6a184cab3251b59da66ea8014fa9c8e342b480a754e37ed2feeccebcaae6754f2becc8e675a6aa2d384b7730b54035bd407714b46c21afaa05a61658ba694c0842bcd8962f6eede8b6bb9eeae0eb0d9e16d767c4f53971c558415dac9bec602a9109d57422b3173b366e6cb3bb7a094910ba832488962509925755ef9f85ff76d4fdb37438b95a1e927dbdacaf3dc136d98fcc5b1b557b2a6dbe98c26a61350513ab2998bb9a82b9ab2958f3d514c02910f418390003a00fc445d0e311a0d640e159c51bba4ad34a8ee2c5d64c0bae868e17dbe0d91d26834bb678c3541be84e2115d003624009a80009a88e751b6b36ab7843c951c5d61443576c43d96142854718736e3537419d9fa0574df6859d05bd43d964f3780f9aa4d2b484686195a64939c34c333d5cc6f5d4707142cc39bd425fb76952ba38614aa11261b0898ffbbd965fda8a6e337261cd66692ad351b1ed284e089f3033031f825c404e26cc8efb1464436946264c976c2dc73c050719aee2980e1de36b389a66a8de982ee58a133abcb3ae92c32c54cb23bbe284e9e93948ff7413dfe8a23adffffe764eee254cd39994e2ebd3129833dd2c3f661611b6dbb870ce4510597e142cd374e90d9a1685394cf74197f5b24d04728c24dc942e4e73853a2943a7b6578be7faa03fb11ee6454d9ed6c5d1ac50f7359a31bdaa98e983dec69a90151531a9933e6fc9b5dd4d7bf5bede8e3e19af9d7d755e6135101d96bcc6f5e2cb422fa68ae3e62e651bea4530d45e03bdf81ae8c56d5c2f6ef7f4e26f855efc8dab177bd8ae55f4e26b544f02aba4cf2759cf26094c92403f09c49340782d0b14b61bba6ed3b4024f224d2b3d1ad32dcc6bb6bdd318c8283d86ae3313612f9b4c83eb769a837c53bbd0482a2923a9f4684925a525951e23a9bc6c2695edb4c90285ed869232941e4d49694a8fa1bc6cfe2866e1432ad4e802b3266a34c31c9b494e8ecf72ff7bc68c4c3c038a55a8d5306ed4640c97faca35cd2c9b99d1da01159b65f62e9be9de2aaa205e23fdaa052dc711c3743fb2c3eb364ca9296de71a55f754ac0f10aba900c875874edc855588680b3c55b6ddf555b6bbb0ca7e542baad6f5e33f463f6e06a97c15591c077df18fd291c5f17525b9ae24d795e4ba927ccc95e44066dd8e7c2015d9a2b65bd78debbaf1f1d08ddcddd84b563e5a39bfb26f6566e5d0cae4cae8ca3992202befae9c5fd9bf32b7321a06bfb332b532ba32bd72726506b287562eac9c40ac732b4739e89d950b70f968657665dfca1c4fceac1c5d995c39b432cdeb5c5a797f6572e5c395b9953ff13a1fae9c47327f5a39bff2cecadcca7e6428385c5c3988459782e07d2b17570ed7631f5b99466241705f4287361e5a995a39b232bd7268656ee5bd9549c0deb37269e51d9e8426ee5b995b791fdb87a0fd2b332b47fce4e8ca148afceecae4ca7bbc257b5666560e62d10ccf5e5cd9b732bdb267659a33ae775d8e345ab865fb0a4a8f68163dac39dc8628aef88a2bbce28aacb8022bae888a2bdc43f8f7b6fcc887fcaebcb372b0b0f2cecabb8d0ffa85d2351df50b3489ccebc52bae9577f099985c39b23213f521e2d37e646512aeb19f46c29e4378c0f1f13abe72bece77b8f2eeca1422bcb732b3727865dafbe4db9a0f71e5bd95f32ba32b17f0cd39b4321d5058e2119c8647c0d55c2b1fae4c237c1f3eedf00c5c5c39b0721ec4e34a4cdd204591d0e188fd014ff19f5cec5c183ae3469545518e6193e17917d899fa921937ce2cf4f1cae195c9953d2eb61a847e08f2f3af30f05cfb582917e262e465fec6eec1575c60e5c3d0191e8bb6c5f01d0f729e6fec29bdcf3ed4c1f45185c1b29ec2f88d91d3747c325ecaca64f1d4e2e5c585c53bf70e2c9ebfb777f1e6e29d7bfb94c5c9c5eb8b57eeed8d82cf40e6de7e377becde9e7b7b172f2d7e1d287793a716efdc3bbab810ce7eedd73cba7815a8df1bbdb79f83ce2e5ebfb7e7defec50b8bf3c85a607eb678ebdefe7bef07419f2cde89621d5fbcbe782b0c8c31e45e61ba16d3eecbd8883bf70e84db1d009f81ccbdfd6e96b7fbe6e2d781f2c50f79f214d65d704b78f66bbfe6016cf751d1ee037ebbaf0be105266ff73b4110b43b82c5db1d02c6b43b3e860aeb263ca006e9eab2f3c3ccd821d91b376ee91147a7d881881b1d093ba9e92a7bebb73bda301637696f6fefc605814ab46b7b5912416ded7d721023f8d8b58213d9bcc6ef97b843e28e883bc173ef7a7deff5bae86fd1c7a24f453f8abe6bf0696df1cff70ee02dbebc786bf122e2de3b000fe7bdbd8b9795c571e8ec7bfb17bf5216c717afdfdb2f5e8baf94c5cfe121c4fb891978862edf1b857b74ef00103abb787ef1cae295c5cb70fb9bcd02b8048233e778537003c2d717e7057da07979f14ae3190250423a4805692005ac8fb5c38fcc6ae3e18b9d9ddd7a37599c5f9c2732593cb37886c87a37b9b787e73f5f3c4376371c781731324f1bdb44487bd2365e377632f397d4626dedbd1d7d7523792f50eb7b33d9bd78a6fbcd64f7162d3e90881c0c2322370f22d2ccdaf00835581221cafdf1ffa56cd002583cbb7871717ef13adc73e9eddd512300941e574ea1c2e064c585fba6c0e2d4e28dc5ebf7f649c1a25617e8fa8b5fe16993506bdd59fc8a6b20901414a03bc1110c221134b0ea578b0bf195bf8a54ae5b4eeb194a31dbba1226df1ea7f8bdd9cbfa12b4cbdeb8d17637cd0987435b9bde65b66b30bfd6074053bd2ce8150aa4d7e81f6403b607ea8327ecb7084b0e9b866d80724bdac676d465c9019acdb6e9eded1b37b6995d66920e0f67f36d767b7bc2f40664f2f66e92a01b3ab7767575761354d55f1199276ededb07e374bc71756f74f17af813ad182916d098c271e0eae26569f19ad027d7efedbdf7dee2d76208b8ec4d0b1b23e464b2786171018808e8bdf7bc6fba1ee27934ac16e7172f2d5e96eebd0f4fa4f76d17b3d7eff1256f0265719eab36ef3baf00205aca65796f1fc02ff2a4f7dd578010351f40bd7708655fc0c1d8fd10ec016f2e5e5efd8bf0e257a109ebe2573fda5a68a66fdefe4a9dbb2aeffaabf24a8a9a0319cf6195575e7374a6bce664f3310eab813a87d56a0b425ec34342faf92121c3a6cb0118007d200e648124506b18184a57695e49197879c361165c7fc7549da7dec83826265e3635b86ca7b663aa34df7cb59b0e04811a50021a501dea365dec963294371ce5774c792313e3947a3c97b5bd61a8342fd51f60fd8691334cd3d829d59f602d16b6d59d56fd7b742f05c905a670af53cb7635e75a4ea9d6222bdb689a877aa2d20eb653b2d880a1abc17dc0229f030c117f27b4fa83f19dc0549740db0636023b26df084c25783afcb51f79be0f984af8f0fa2b3ff051c6b79f4a7946fd751f9069652bb0651774b560aa053bb3ea29473f0f0562facfff6cc3338fb67476b477133be31e60442cdb3dbb88e82adf2f6c7713532532603dba884d319a843aeb9ae4a7d4243f9d41b8ae4dd6b5c9a3d626c1f836ebdae4b1d226a00436a7529b7b7a02a798f524ea4e2e13a0587d1287b0ae50fecb2b9447a53dd2fdebda637d56b3ae36fe8ba88d1fd10ed1ea9785af6b927f014db2ae48d615c93f569164d715c9bfa222f92f6792ac6b8e1f73e6a2ef5a57138fa9df63dd8bba6e74fc53191d46dd4e7fc3ddea6fe05e7f83eff587cca081bbfd0d1e1c5ca1df5e007d62b83bfe4d83eff8370d373eb82176fc47a2acb6bee3ffdb0bad6ef957b51cd5bf79c750b28eaea2e4f0cfcc2193a986f2cd75faed05d55078586dd5502cda4fedf8007f6e546d2d07b4901212e2448004d46e12595b53b28e92a34a8e4115658429d643981e514f6a4fef662aa98c87710a3954634ae24c91de2cc5784f0d70eb971ad1e1be3793f69bc9dc16ade1eaa5615c33ec9f4b155ec1d4c25a62b1766a38692773492293ff967c23994ae2fa29eac2b6715883c82b86aad16f2f48832caa105386998e9604f5a10bf7f5e1ab1a33833502da70985a9a6e535721ba18ad28c461c3b2032a91ea36f010cb89794802633012a300003937ca6c581f4251462619c3348291aa01accac446752b7421640679ec154387e73ea00b2912cac38b0884842a84cce0eaaa908656a1d0471687494469613a0b9dadc2a3f2e74367aba40df76c153f2cbf16395b454752be9ae9073593f7d54cdae05a664068196da03e2a34d3790ce81d8cc780ce5113afb4df14f93c5e071d5d5cb3bc3ccd83485b8cc77b36066cbceac6088f29ad0d78319e99ce4ca3c08f4a300a396aee320a784c422147f34601956f01956f01cf46300aa07a353cf9a0204e4628e8c68880a8da8048319dbd99ec06ca70c951132eb4dfe4b93c5c061d9d5fb2589636e062b161b81803365c7463042eaa36f066b2bb7d8b563f9a040fe1c1c68843265021ef32bc5326f29191041ba3f88d091e3421205e631a0e2581c7cb0cace5ddb239954a6d166b77cdf66e3db4c63694d9fd80b17d7facfbd63c04ef8f73531f2e3aaf6ae4343d8da330b3d07e808b563c670e18596629830e1b619632a2311310ace2583f559b8fc3462e09e4840e005af0eab3241049228566c75c18ee60ac29838e32a241851ffb9c8b5e77600d1e76f17ac3b2b8638b1ae3b5784845c6c84b54cad2d8e3162c2293d64ea8c8d1e265aad335915ae5848ad608353b9f22cfcc96056af9740aaa1a2d136d65b467c1e94f860e30ff600a034fa680d13d74368500044ea7888ef88dcfa7a0fef914c50b81032a8a1768a3132a987f4245f1b23ff243a68549d0ffba151afaffd7ad47bc65727decffa71bfb37abc6faf0bf3efcffab0eff6bf2faadd50488f70436c15c3703d6cd80753360dd0c780ccd0067dd0bb06e06fc57340352a92d3d3deb66c0ba19b06e0604cd800e34039e79e4c1e52cb997e48ad775e61fdf8c79cd3d12304130b49428b5491f746f2fdbe49df09ff0d3509a937b49713e234ef40772c5f9214b4487ee83cec7f06f6ea99fb645243bac6c3bba0e756d475725cad2d4a5030040cc7032024f24554d04bb431ac3c57136e255c49c886b37e438121d84224c05c80f394e20ba1de41222a18ab876489a52cb863aee15ebf28c1fe14e147a49bb3ec2ddd63ef7ea46ba93cd5563df313bf4b99947be1b616e68f9e2b8175b1ecfa256061d1e5dbe6178f9687c79db5a35c03cd539c700bb385ec828f0e1d98e3f1e5926c3c5f90cc55ba4302b472d9eb49966693c39646473024167d941913419539992a50ebfbb4dc6beffa6bca4bca1fc5af98df2efcaeb8d07b9c6688fe589fb6f14c7759a887eab7dd5c8e55822fa9db6f7b5e2b899ce693a0bc474f23fd7bea465dd3a812fb52fb16ca4462b8a7a03be6e26b5ecc0d2159ba6a9a581beb61b9f106fbb6ad67d791fa3307475ef61701fae63dad434b52c550cdba270058bed2d832a745833795ea3f62eaab021aae9547176d98846fb9d5db64315cdc4ac639a1a55e82e6a42d57ea6ab0e6dfc223aa69d0486eec46e58c313d793c024092c60b2e72481781248278132c0d85a22516a69aaab8c2ad4b259966598ce9360918ad4ae21001a960d432e26349366a992a5a6a3f7d3e607476ae9a442610a8ae22515239d548c6c52c99a4dac512dadd0ac0293d05d8a91568cac928d3f44e221025346578d40be77c8e06664afc9f43ea9a797068f1a8b296d749c5813d4accb7a730f3fdf3d882f586663e11e05f77cf630af204ebc424953c70425d0cb6caa874e22ebd732b4ae281463ce2df0750ab577197d9112a158a8639a0cc48a546e51bdf453d3745ce5a23a2c4bfd352068f549fdd4dee50c458d417f218803186163d0415bd0305551266c4100f0c32ad28ece4b849202009a82192d4bfb99cd78a930085d20b7094db754188500781487563cd4e290b73b65f2c36592d82a931fae90c49332f9e12a493c25931fae91c4d332f9e13a493c23931fbe24896765f2c35724f19c4c7eb84112cfcbe4879b24d121931fe6608ed2f536d0914927490025996c85c45522932721718dc8e429485c2732791a125f12993c0389af884c9e85c40d2293e7207193c8e47948cc11997490dd758a774770cbf25f3fae4c550f560ffff05ef59052dd5b3d5cb9cc93072a5395cb95ab4ae50b01dbaf540f540f297ffdb87ab832593d2812885c99aa1eaecc2895abd5db9599ca54f54065ba7259a94cfdf55c650693c0c1875faa5c75338d75f3e32498afcb7f78efafe7fef79ef72ad7aa072bd3c0e052f5b09fb95a3d142cfcebc1ea2114d605546f570f56ce87ea9faf1ea8dc84848034d3f43f0d731c2f7e784fa95c522a5795bf1e54aab795ca79a572ed9fe280b4c842c2eabeca7475bf5499aa5c912a37aa872a970b95e9cacdcaa520a86164d22d31b8dc9bc75a595f88b14aeb252032a9a7db6080c1c7f372f530e05dad4c556e56eac29956f7562e572e55a66210822b0ec3a5fea053b9f4c37bb11ca207c0556ffff05ee55a5f94522b2350e552e572786136278623d05f0f560f425fccc2fb0f6f311f84fcbca46ec071085e07a972a9baef87f7aafb004d0c464150c64513327aa3920f505d146cb43738b9d9942806bd0314c5e8e466f30106d5fddef024b22d0726edfd616ef30f37fbb6a4136d31887a2febdbdddefe70714cdf541b50b7a3d403114f57195fab0742e36bf54070807de6a162a48a6f2fba91cd52293f6469d210c57f239b63124c628be3d288a601c8712c4db2980633efe2b82e0dd18cca862caa4b794c14c7fd332325fc10d3cb099304010c9d2408d6c104308004e701a9114d13658e8309bbf7d9be84ddfb1cfc3ddfd7e77b88cc3696301334a1710f91d145c8cf450040cae3fe118b88e87d92d64d728e63d31cd5b98348d77422bb300eb2357e5636b142f502e8028d0abc5c88bca63b8ecda962d22397cb11d9e88a47a1e4e7fd26a3431c33132468bb5ced8068998ca0152e0d93518364868be3da08f4adec2605295515a4ea310027402f15a437e43843146f8d2cd2962b5c2a2528d6e3d87658c47c90e4886370dc11c7f088e5f38258b014c8ec16158daef86f3f2f7476749bddf01ecbf0bac96c771b4b68ed9b88443619752eaa1d5ac042b3692ea70d398e9261599ec8519ad52c0439191b41b6e10c1990186256719c636b3a4fb12c9658f93cd6c91a439453314d8a9041c3c93a438ed3d8184319b800823b67cdf972a68223b0435ec84870e12c1a9d94e8e8baa3db1449eb1453b6a659701d62d69036a2694343069e9908b061660e72ac2c7530d1f4dc44479c7f38c414db508699926d7260c3aad8f1164d3260d12473b964234f96c1a7ac360d7f8789801352ef50d6809966b2cec4698e9a95494fd2e50873588e2fb98030245ad99ff536448ab74aece2b80e2fa8de2790c31649c631724cd769b434684d7805be25c2b42c0b510ccc7f47342d27dc6abd61c2ad3bd88ae3965d1c0f9dd868dbfcc846134c0e3391831ffc65e0077f2afce02f053ff8cbc32f2f9b8f8f636d47fd7eaae0c9a9e86d2e5e709ddb6b39397575c776741f95d6e4e4d446ce6cd4072a4d3ba6922b8ee99427ede2822580da9028ce14af0ad80eb378219d1e14b859964f5313d3cd55838e1c9036904582480b4834d712c531a8a6805a2c5ec56355d94f18242219b7892aee552d1e6d74946af1289ea5aac59ea5daf01cd5e251293d581c8b3f49d52a5e28ce59b6d3e79dc3dafa3bea448f53055a54d7c489aa63de07b6d05e254d9ca7aa89ef95b66346ce54d5c499aa9a2ed9c50b39cd3f55b5782147c5b1aa1a9eab0a75fd9355a12c2548c363599c8372ef78558468e27c55cdb6a5e258e084d5b19ff284d53a05618615c488c64c6547f1dc880909ae2246f8f218787f357881b56c96d90a358a5f7b3a822f8e31c4e218b136a6786ea0f9da186498e4ec921eb364985732c029b4a4aa786e602dae77dc91399061b82353c37d949a9263e680c9544d19648eaab9fb3135059e4ab5a92da16ae11520cc4c029124d04842fd66eb3f025b320759cc8ecc9fde83d27284886dcea0e198eaffde732ae36852f1f3a82ae96139aae9a182a01a71e1e1cd8e52101c3a699e997ab0bc15eda152dd0ae80f2d2be525cfc7fd1f0ecbfe87c32cb1e19b4577803377cd036bb6091c8a33cc31fd739931e72d7b183402fa6390ef1017cb1e8ce0e9f386e62f7bf0cf9ea77a2bbbc0995988ddfd9db0fdb8f362dad9e34d6ef836f02ed64d9889ab48bca8f2eec40aafff3f71ede9e91129b5110946daf9fc68a7c0fc5d0ca6c938e6ee1f6d23f90e331c8e735db5fdeba8b6ba2de8ebaaed5f5eb5b116745b73d5f5a3a9b047a6af32ebfaea5f525fd5b97ed6f5d5babefae9f4d523de1133487577478c6927153aec690d6f438c937637c40c792a8359751b623c979169afd56554af4ff36165aab39dd4d42cbef3832773947246a852a9c680591eb8e58507ccb1f8ee8fa80f4c737d605a531fd8a3dbfad148915a3ad3742567505d65dc510ed79d06d531611b7a9a9998dc6132a62a96ce0cbda91b4c4b2a3923a9d85a52d9095723a9ec30938a65343bf55dc3a0659af23b4379839f6c1cbf79e2a17428587c3fbe0ecd0c1a4c958c5c5477e60c6aea21785017ba705f750e3a96cd4c2958201c61c56b3bcce2d7de4250af6e2bfad36066d81396cda38f9a68ba34ccf8da7223746cb10fc8c94463e80a2bde8aacd6e2271863b1c1029a133278903116a94c0bfac0185faf85340d78c102ba13b23aaa4f281ed498effe820c506d25ac192ba8f17ad47f9b847e2b149ee317f662d7d68e6e62d9a0ee54f623862a4b07a697bde425aa17c7349324c8cb8cf6674c4a1224551c33714dfb36addf64c5319d24c82f18cdda5483de22a9e239cdce309acb9004f955f196962509f27af1964e2dac0e55a4978b5773198a947b18d54c46d54c10b89d420a48ffc6c866a996267d212524441382b95209a18440ae2c51315c21046fc14db0f2f834504ebda4a7784eea3172199d6a69a805f9d71d2e2ca453d063b6c8fcb2788eaad4700ba919c848996d06ef32c86ca776869a3ae98b28af5ed263e4407447743e080c6405459220996d0636c20e5406150655b126af08f50437ac847548df63b084294e65fd4ad73547a2e9a8cada962b8e997420132a0a055e4c47b5d6af74bd784ea25a3adee4b398210d50cd667d7ee596422f869556f1aa646534aeb8068ab786b354b20c6d400b7af0dd7c4e267af1aa9683a7c3535a0108587c543325aa4b0399aca1a53de51505ab32c9c2ad151a0cd32999e48a17029efb0ba8b4fab31a3ea5426589ecea1a4b2de8b4906b1484b1ce245389cc36747674756ded263a2532c9fd98a115d36a505f6dcb492f5303a68f14e69d649b2ebdc2a86982ad0b85a9e2e75c4be8d22b5a7f9671b82efdb238add95ecede5cfc633a97d10ccbcdffca19c85093e75e2fded4a965a37ec1c2ed0eea3e9eed297eeeea305ee829322cbcd99fc9d2818c5aa7ce406c9220af60a44ce2ca0942e2eb3e8d6a0cc50275e660eb401278899d2c57379f63a15066c8ab056da6a9c52ba8cc90648f96755599962b7e2e149936a051d50507749896a1ae06d32cd05f9aa9b3380da6a99c36a7cb4972629c0ca750afbe8a577cfdf5397404f4d136e8a157e9e3adbeb6e99b55cd49677cb51350619bb16b196a31ad911ad3eaf418d02c4eafa2c8325453337d81faada832aac37c30a0cffa33404a3374dd9dc7f6339aa6baa46a469afa86989bc545f3864e35356083611edf2aa1cf425a0c0b407dc183e32b309e431576de08cc5c2147754f91a91918c803aa0c01ffecca2c1899fe2daa33cdddd5afd56debd70ce52da77819feb3d9c0b67e3746ac633b6b8c11fb963fe50d0481d092c807fefd28107612187893deb5b9c9fc6debfeae75dcb46e324b79cbc03deb4c371f6ccb7af19c990422ae9bacd52debc573ca5b063acafeab44ae7b8b49b1fbae8b6316914971acf5cdeac5b135516aba57bd0921dada567543b71bb62c864aa38dea46649f7a8b82b5a06d63144e07c6f5f58eb87774d2de4d74b289ef69279bd86e6f53bbe6ef697fd82ded9947bda75d0f6c69d77fdac036abec68b73386aa32e182a53ada242198bf8d3d84e4e7c54e76368471d46db41dd990ebc30ded63b7fdba98cb898dec5077c430ddaa238619d8b88e056e35c8e4c4d675a8a56a965b4b45bb4955792d2c706bf1a2942b65066c354f4ec81981adec6eb12729e6c59e7621a91510d5b0023bd97959405a0bc48d6e666fb2653d6de43667a9ad878f5c60261eb8c04c25454d4bd9d6cf4f5bd0dcb310a8a66c83714fd9ce873de5b730e88983164ca587ed826bd3631692c021e9d14f06c927817a128827817212082781ea5a86bb6d9a4d4d65bb91a3a69232f474364b4de5178e3a0217935958ea0c9988a43f31429b2ee8dba6d9492096045a49a093042a492001057a93c16e9ba66ccf292943f985a3fc02982adbe3bda6ab0f75db786494de11bacbc6fdad30e871a06c5901f85a5d9c7584232755f6d2810ca37d528f91106b77a335826b7c034b7c23680d8c766d57d4567f996619adf38ff6fe8ad954b2c518d19b885aeabfa6d93a0fe9cbd4ce462ab4b6923778ba830aefd8ea1be4ed07d816dfc6cc075969439849d6b0bca6d1179dd80f38d1bd6d26b5b582650cd16c562ba8863e4c4d9a2b58541f645b3cdc570dc78c882f98746e856176e3c636d6d5d19e20408de01110ec85a7ba99cc36756e9589202f0ac044e46c04e0c5cead3e2a301670008c189a2a75b4b24deea96ece5de63be65c9e907da6db6729b317d0ed8b7c645ee56177f3d666a7703b6f6d761af7f3d666cfe186dedaec0ceee8adcdcee296dedaec79dcd35b9bbd809b7a6bb31771576f6df6126eebadcd4e8a7dbd40916fec059a7c672f50e55b7b812edfdb0b94f9e65ea0cd77f70275bebd17e8f3fdbdc0816ff0051ef13b7cd3c1d00ab59933b599dbb599e9daecd1dacca5daecdedaccc1dacc5c6d768f529b99adcd1eaacd9cc7b2b948d945ac3787657f566a331fd4666604e2cc9ddacc1544993da40087d97db599699eda5b9bb982350f2bb59963b59993b5991b58ed33055282c667c8f822a6cfd766e638ee09b7cc874ed766aed7e38ea1083722058d07b3fa5e48c6b43eb95aab93cddb9c142d4e465b9a8c362fe9b72c196ace5a464f94e93a56bdcea546beb347b0153ee8626d661fde87ab41e879147b0a45f2a12711ca1f051ffa25e64fb8fd102c8066f802341b9e3d717d2943c285640a891295c067dc7840f77b433011e4056141122eabaedb17c3a3dbc893ee3374a86e6c8f4559a363cd1b8e6389c57bdb9ad5891fcdf1453f131dd0a187a1fa95daeca138cf5b223294e38d3b545f2b30b2c36b0085a7f92bc2c7f8c45af6eaf0773230d0e39b75a836739393c4095f6de600be9af09020c2ccd5daec116feae7ea8a13f8b48de10c10dfed139cfc1df739fecc9b0ed6c133812a275c2577c29b2086816a0079d27d436e7873c630301516e6a6e00bf28ba9641d3c1fa872ddd5575f7933cc10b0f56dc8b5d9a9daec746df65c6d76a6363b5b9b3d5f9bbd509bbd589bbd549b9d5c657ff223dc8c5c67dca0eeb85d9b192fa0a69f41f5315740352b540fcfdcc61b7ce6012c1e8f45bdd91364e3d93e41415cfba7abb3235c4988f3a076902f938c7b48c39200ecd9eeb020c22a0a31970374763faaa87851a323133c8178f9d4f2e7cb27963f5c9e5696c7978f2d4fbb994f97a7972794e50f97c797a7974f2d9f01c887cba794e553cb27963f77136720f1e1f289e53f2e9f581e5bfe58591e5b1e5ffe78f95320c54ba6963f5e3ec1b39f634294fd697992271bdb0242b8abae685723625d5d55a8abae40575d61aeba625c7545b8da607bdbf2f4f287cbe7964f2c7fa62c9fe3d4cf01ede573909c5e3eb67c6af90b489e5cfed4859ef313c796679a8db1cb1f820428c61fb92c5795e5e3f0870d3ed7402c1c31973f54968f29cb7f5496ffa42c1f57964f28cbe71ee59eb6dee5637df5e35e081aff512916252b939e2d2e03dcd95ab7d555aaab1337fd6dfaa56af938defb4fa4e563dfdfee0b0f96cb9f2e9f5c9e0e9704bf382d1f5b3eb7fcc5f2f1e8fc77f9c3e599e54fe189f2eb06064c7c024e2c7fe2ba58978f2f7f088ce09191c2345b1940978f2d7fb17c62f94f81ef57cb6796c7e1c9739da5cb9fe2e33c2df10772f9c4f28c3770064139992cff69796af9b837466216cb3232e192e17818a3d9b7f26f468834b37c6af9d4f22744669b888410a0b11b064dde761c279b1001a44f43444e61fe13b21b06d3e593d0e2e573387c362123d042847c1810cb63b33e8766e5f3cd9bf579a059f855ac63e3c6ce8e9f41b168269091bd3432a81be8f05e1f27cb93057197789a3f01a7a4e5e3cb93cbc751779e5afea4e0ddc978f889e519786240414d17968f05935f80aa697c9ade963fb4052469c45d9069ffb73585c179ba9bc4c8e78e70be98c201a0773f11e88a27028f6f581c447f0ed15dc99f408518273b112fc6f4f2b187771a4c08a7c184701a4c08a7c184701a4c08a7c184701a4c08a7c184701a4c08a7c184e73498f09c06139ed360c2731a4c784e8309cf6930e1390d263ca7c184e73498f09c06138d9c069960d089daf899daf8746dfc7a6d7cae36b147a98dcfd6c6e72113005dac8ddfc6ccd1daf89f95daf881daf80c66e66a13876be35738ca6105884decab8d4ff3d4dedaf815ac7998d739591bbf81d5c615488ddfa98d8f434d009daf8dcf71ac1398ff0c090928972f843889d56f04a14d7c02d8c8a4dfb8e46a8d4a36695252b426e9b72219153d29a44efaa2ae69be2ffaff0efedfe64dbe519b388252f9a08bb5f17dd8af5782d0f328e7541074124173d8141ffa25424f8856870a407a9f7bd3c9be2bab2f6248325fa0901c51f63ed726337daf1f0407415b101624e1d2f24c1f9e9c33b58998097ea0e481e7f5011aab4de73dd406b3f8f183b5f1fa59fcf889daf89596e6ef01cce09c7d7c06eff3697884260e3dc89c1ddec043b5f17dc1693b50bdc949f2393bdce5bdb5f1d312c027f648ee6dffaa367ed69fbac3ad3d8492eeab8d8ba9fbf807b5f113c805e49cae8d07e6ed21602680fc3152f8ac367edb9fb47b4090490d20f3f773da9fb1fb90545800101dd84df8e1c1eae0f94095ebae7e094cd783c0354cd727a66a13d3b58973b58999dac46c6de27c6de2426de2626de2526de2279daec3db7fbb363e5ec0bbb7179fe39b05e8435005fc39982be0cb7dbb367ef141a6eb2e8b98e97a80a73f5d0ff38e9db1bbe23cf074dd93c99dae072571a7eb1141dc19bbc75c0ed07964d3f5e8277ffec1dfec0273d48b51a6bb31cafc6063e6a62eb1da8b47d8a0fc907056283cc92f4f054b991b904cd5eae291d9dd6490a9ba38599d1219b3dec62e3f2e591d67b7422c63515d76b1a251cb385baa4b16b5054f230d191a085f56df586a376a2845d92deac53f53d518022ad5096e7ea3814064f52d1b64161b68d4322cc47575980a4621aba39436544d6fd44758087d24b076d72d31c8046282bc2d7402b1b441f6cd517d902a232c3b48bf39ca14e3dbdbcee010556c938e408135a2f5c335ab0d63d6c4cb909135468c5d54319d411d0a2ddb18a62a552cdb51996ea4a9326c1a96a60f84375e5a36d5559a3574e632a7faa0cb9c72e6740899430130876b561bc6ac8917c11c7853dde32d586b82310d9dadb43b6c185ada6012b9269165121826815b125825815112d8248107c0ac24904f02edb5d8733a5307a16dcab0e1268714c7364c3aa458a6068fadf2cd51668f98361d528619fc5b4ebfd13c20b8ced424504c022910564b2295245048028126cb2074a60c1b8a632b9609959461a658f181db1e62c9df3f2abe3fbc7d96e444cd23cbb14d1a044757b9b91ff4339a955469bead9dab45a94376d7bf397d52afb86590e4b4f0ed949e0c21f1db18c579268c03b7348ad2898b00a4adfcf214bf3c1dacc7bd43bcceeedda17d68df1c65a6dbc0b8657c8d1b1869c2b0697c3b968d308bb6812331b7256c6d2de1b5b5baf6b46268eea201afd63074b5ebd21af60f5d218d9783a096769784b8cad85d19c295a5431ed5b9090f770efd08b58a63a64e87a54cf19cbde3db63ba34c45495e992b58b996a714c9706ace2bc5dfcd2b48b5f0e15bfd4a5e1e239dd66438862e4faa96d84c2a0fa26811e5d05c8ea0c027fc42914ec6ea217cf658a637a5eca15c72c431d66e60091e3a0ac3e7c29ddd40644dabb49b8764c2dcf18202c9d27bc5e3791dc0a1cb5bdce72a0cd3133f1548b574d186be15a1c1ba41e7626866e035c359eb24e870159a7c3015435866c1c622a9e66a6785560f354a0422a867263f47c83de3837820d3c37e2f55bc0eea0f178220c2a21bb8311715d1bb98d75132293de5cf156d6ee9348fb26d24b36d9bdbe1aeae32b857b370f19661fa937529c4864c3e298086d08895c71cc1cd01c4b298e0d9b5a56b30032e858ca60f196aef16b16aeb8d17b17eef4de150c7758bc1a897738d06abc43e08c6c912532446e7c0bfbaef0293e030d3e0c796fb822de70055e70055f6faa045f6e45bcd98a78af9b590323d4427a1e314e094940fdc6a6c088925186440d65b80e770d233e8cd330e6f7f424fda340c418ce41515868d00f9524f838111fde5d6505d569ecd4260ec1a5e403196a6eb3db3adb93b6f1bab19399bfa4166b6b3584fbcf3abababaf46e82939d9e9788ec011c00fcf706c6488e061eed60745423abd3e16859fcc27bc94c0ed06c1607eec4cf3ada83a3becdd2113a8d17f087e974b6b736da6eb024787547a8efd381b15687f1554fe4e0077f19f8c19f0a3ff84bc10ffef2f0cbcbfae3130b3193df4c7331539fa5b9a51bdfef5bfa72e9f6d2d8f77b966695ef47972696ee7cbfc7032c5dc3c41d488e2ddd02d8d279015fbabe34bbb40019974c287b5e64bf3fb07476e9c6d2c2d21dfc9f5596169626966e2ddd599a58bab6f4c5d2046734b77463e95214f8e5d28da5eb61d0f8d24414afe1ec2adcbe48ebbcb6055a166857a855a136455a14d39e98d6d4b525a6254d266b4b73d00a68c11d943c2037c87c9d8bf825bf9c776544d96e01e61c700219ae2d7d019c2f2dc5bb9a65b2746969f6fb3d4b637055b07f2f61d3bf5a1a5bfa62e99c0b9cf87e7f107473e9463d706e6976e9cba5b341d08deff77dbf67e98ba5b1a5738a808f2d9d6ba6da972e81084212bc7cbf5f59bac92fd0e4b31e55a0f845036aa8ec1f92d6a38a8d242d9d4bc62c7c5f3a974cacb6df348013af80f1f15df8fec0f77ba2134278ea97ae2c4d473fd4f3dbb974a9f14c31b43b0b482f4d4b4b334b634bd704b5e6dba896c696befc7eefd2d8d24577fa134fa345edbc34076ff1d28d80cf7d696c697e696ce96b9c142d5d5b9a95bedf0f5c9766256cf5757c8aaf03c873b8d717e464f2fd9ea51b4bb796263c37bb0fc8c884cbeb79d5ddac2a136890e743e799944cb075b34b0b9ec3dc07e465b27487eb58cf3dee01ea46fca5b34bb34b5fe18dbabd345610cdbdbd7463e90e02bedfebde445eee666ef0a6353eeae50f6dab545deda377d8331c96d35dda1e15d77511875913994499afbe79ac20ae9bdb40d514bedfb334def206066f4b42602b825b62787300ee78649bc866e0800b1b36031b7fc34393ed0b0f38198e0edf9a1ade13e55053c35d5198485193d9ca368cf69462b87309feb29ab24d847adaeed9ffbf15a19e7ee39aff3dab863b7f8deac00bd8001397057050b6a56d200e648124506b30aaa4343d9d7694ed4cd774653bcb528b2aff4efb1de5d734a759ca6b4e8edaca76da6fc7bbe1842c29ac8c04a0365486aa50b1b1d24fa595edbab23dabfc7bbff2eb9cf25a4ed9deff30a71dac257a40efb033e464e30f39688856f7fa0fd3b456b034aaa70b9661b2428e6669ee013e26011def4b11d2f3bf0f750676bf987c474ba14090d3037d27eaecece6fce0657fba5bb083ccf3dd9c852ca8c78f63af525393345d9344d784c7b25f30cb188a160557a5058a025bb2588e9a9a2e450a83f5b234eb04cb5b8bfd97a59138ee79aaa725a025e226f433930e534965b6e61f3728723999582cc7742d10bb8ae73250320896bb187130ad0234434d3f6615cfa400deef64a9ee8d37229787129b661c3ff20bcf3d328d15fceee63f041b3a3b3ababa3a3b0b0548feacab7377c819a727cc04e5ce382dfc85ceac73c8e98502ed26ba313464729f67f196ae3a269139ccc979b05cbd2f0e84ead636b57122c1ca7ea57659dbe466eb4f19d2bb49ae78412fdec2af6222e9d47fcd0b7372f1cc401de0a4776b9b02f4fc8c53ffb12e4c7128eb0c0d8152c74300e460de6d430044a28712c1f41d23fecb145318492c1df3850fb9a298fc4c0059dbd4c6ab40fbd5e29769bf2182a287e1128d7af678278ee90e9e2920532f87bd8329adfe2ba22f898be3f1f22a79f583bdeb310a210779455d83e2212b8e9918b2c08cf91219be1b1ea6e8fb285823edf5df20352becde2bde12279760227c7449f1027ad9f8255bbca014c7d2c55bd1034c8447af78f5218e30119cb83f0fb9f841298b57d770908948166f9b5a716ed02dd08a7323de81263bb45cce76d3c52f2d379da5ce9a0e34011e481a28222520d1249aa3a3a48a634af153534969cacb9af272f14be5f5164e3e7a345ff8f8c122ab7ce70b203538dae442c3a34dc6f06813678d479b5c90d2c5c926279b50cba6fed126c9d68745b6c3d682411d77e44dccbb879cc47bd542faeb9fc7c3a605cfdb4f335da71a86ede9372121c2f68089ce941c4da73543496b4e5a3794ac93ce6ac1d83d6ea46b3b1ae95a5b2dd0759a45dfea34700116401f880359eea0d71a39e85503ac8f01aa641d9da9c5f33c3e0f26983960643199d68c114c8c309d9990b0683fb5570bd3033451bc1c33810654879aad44e7614a5a8b8962fd581e1df2db745a936836cbea02551b39aa478b4221bfbc9240ec426606abaced53b7eb84c952c91a304ccb7b973d8291892ce9cd1a1cd5a8436ded8375bd77a06dcb1f7a3b363fdf97dce4bb13ba898d5f17359df01302bd00371b2c690745c39966071c5d13d156b448d46cad59801b4dc4b7792218dc06661d22b44d5a334cddf02c68cc6a81e8362c18de46f3a3db84c2dbe8da4f19dea65e058503edaf6ba1c7560bfd63a2e6af6ba1752df40fd74283c1b389fecf8d3d7f3f7358f93fb7dec3cb8d77e0f2b7d3a739f038e60e5ce065a33c378bb99b9f60eee85e7111842085b41aab9f4ec0db0a7f4fc2df53f0f734fc3d037fcfc2df73f0f73cfc7576e03fd6e9dc1aa5eb6ba3bf9f9cf8fbe9337f3f39a1fcfdcc6191fabf7b675dd8dc35af745aa4fedfa16322f5b7339ff15433ad244803512007848004546eac955aadb4e62388c048728f2082fcdf6e5e4bfdfdcce11e6884bf8c21000d2ba968215fcae0ed670d72c86663386463a0e1bdad91c2365555db1b1d86ffb7a387fff6ced1025c6ebfd764d50447c0a513ad9e72cf4913d9ad1baf86ffcfd7effefde4445407fffde3f743d0b02e0dee4f807bded6fe026a559eee26bd7fff64e2ffedb9dc875dfbfa1b4428ee505c44e031edf1a8d7d781fd0d3ee91798cfe36f070e37e211d6bfab289fbf9f9c68f19b8c1a7744881f660a9e8eb8cf2e8d3e15c23df1b439dc29d0e67f3f31f77fa7fee86a714ce664d2f9b7c3075ddd8dc90ca89253fbfedf477f7215b79b53a1049e53aeb531999249e7ff7ff44bd0204263bbb93cd0be79cdd5d7907c448a76e4d17f141a7e341f85acc047a1e1963e0af16f3a866528ffcefa1de5d70c3f0ab19cb3936650d2d63f0bb17ea80e95a1e29a3e0b0dff737d1662faa0a6a70b9696e75f86749be9055da559e701be0d716281af43f9869f87808ffb8108d93df00722c1d4fb44940f7d23423eb26011af5b7b344092861d5d1b32e23f15a5fa993e48f5f4dabf16d12c95766a7a5a6bf6c168880d333d3dc4ccb57e35da89ed93343d1dfe74a4e9e92110d7238c5acba23b994d776a56936f48b6a3a7d3342b35fe96e462c47f5352b133fd80af228bdf957686be2bed0c7d570a7d567a945f95a22a6f28605bbe1d5ce7757ff4e3fba31fde1f3d737ff404263ebf3ffab1727ff4e4fdd1e3f7478fe1ffe76ed99f79d96917f10b9efff0fee8a7bc6204e5e3fba3633cff319238530ffa7310f4e1fdd13f229483beb83ffa8982a9e3f74727307f1c497b6241a54fdcb24feacbce2034a6d29f3073aabe2ca4c7dcc57e719d34d6a493c6229d3416d349412cdedcb1fa7e1aabefa7b1d87e1a6bde4f634dfa69ac513f8d35e9a7b1260beebcdef27bc8ef0fbf27fcd6fbedf69bebb7d26f99df085f645fc6f89132f2b09f72bbedf3fba31f727a9fdf1f9d4666c7f0ff2417680c33a763cb3ec1d4c5d8b28bf747cf6226a6ec53f791f810e9f35e3dc1cba2e80d9ec390fcde7dad6fc25893268c3569c25893268c3569c2587d13c281e0354b18035bdaee8f9ec7269cb93ffa6101abf1878bdfc73fb66fd91db552bc76fbcdf5dbe7b7c697dd97d497abb13dc3c90bda82b0a02a480a7a82d8aab60e6ecddf268c1d3732c0b607b0763c420dcc1c511e3fc2638f4e62a78ef165dff7473fba3f7a3cb4ba1cdb27145704c91fcff1453c8b8d87fb16434c7cf6aabf9bc2055547d8abe03f0b1eaac06cc918885999c71f30fee87f5cc00c7f9e21c31f9a0fbdfc791413b46bbbefd90aec6cbf3ffaf1bf6d4910de76d22eb34d6e5a78bb1e5600718f0a0838717ff478bc1c6d1cfb783b970614bfe4751e6997b7049bd2a0253e022772de1b5642a45c43d48237e373b721fc7ef291e9f4fdd1e352b0919e511506e664126cbd6758858119c00a758b6761d5c155c0155de6995b01480aca45477a365700921712897ef0acaf10b0f1b4bca3d0b9992315782f6c8eaea6bc3f7abce9e1281d7c51a4ec2f8e144c71977fa1c05ee8eaece8d8b8916dd8dad1d5d5c1d7ff40aa9b088e64139379bde38fce5e14c18a3a64b2b97cb8fc1149747aa9ad5eea492ff594977ada4b3dc35347308491803de7a59ef74a3b3bbce4563ff9a49f7cca4f3eed0bf48c0f7dd6873ee7279fef08b0f0c0f5718c868602b3ffbf9c2ecdfde56c795f69aebc4729cdfde574e94e69aeb4a094164a73e5d1f29ef291d2574a79ef77a7caa3e58f0065be34579a2f1f11c9f2e8ffc7debf3e47752409c3f8bfd2dbf18c07fd108d842f33d3338c821d3ce30b1af32cde9d277e724f45495dee3eeaee73b4e722564c7b431220c918068f0de6628c8c2d591260dd058d4022622545bc1f4fe32f12fe727a3f3ee3fd1fdec8acaa73efd6c5d89e99d711a0aecacccaccaa53a7aa4e55566675a0fa9efd88802cfba1bd682f11600624f67df2e463a0b4979fccd80fec257b998038fb3e4a8064b5df9ead8ed8b3c4be672fd90fab83f6ea938fab0380afbf81c05516ca0a45858a423da19a504a282494112a08f142709d4d06442e5707ec257bc59eab7e44ec45a8890f80c920e0ab6bd57e7f91b910857defc91ce8473c58a30d0aae83902ce4092982b7e028f8d59fe5ed7bc88773813f9c0394e7a5577eb073a99d07c6b2fff264c65ea87e64af24a09f3cf9d09ead0e86bfdbedcbd5feeaa0bdf4e4f35822ff377818efcdf9f6757ba93a622f4558f866efaf26ab83f632347bc29eb51f63475ba9bef7e47379f0142ebbc37b0ad58fb0ebaec0fbe4fbbeb7e79ecce12bb9821ff6d075aafdf68aa727f4d6d350cc9d8f82c0922c94b01fd9157ba57aba3ae84e4a7e50de25f46ae04e4a7e50d6e3086ff98a3b27c96cbb47306b3f70a7249ee9f390f7aaefd90fdde94864b7dd1f3eb00f1aaa0ca3deb631b9cc0e962997cd0e985078e2d730d5b4c160a95ac562262632d7b79b4d5ad3c9dae82d9c416aa39fe1fc511bfd1c678fdae818ce1db5d1719c396aa35fe0bc511b9dc059a3363a8973466d740a5ddfd5463f15aeef8023777d073cb9eb3be0ca5ddf015feefa0e3873d777c09bbbbe03eedcf51df0e7aeef4002777d0732e25ddf157c370093b59b576b37fb6b37afd76ede23987a08a0d10f6a37afd4464708e22bb59b1f72fcd5dae840ede628cf4c60ea8ac4dcbc5fbbf93e96ffd065d68f9cfa6b37cf71d02832fbd4c5bf8bf87779fe2216fe98676e20bfb3881fc2743f477c80a00f6b371fd59f55fe616ae54d5fb59b9fd56edeabddfc0b96ba88e4d708f27a1f0a42fe2f04a9ce606610c9af93dacd8f50830f300598eba8eb28a62fa182f76ba317783d1ecada5dc7fce859201fbdd06852e39a812a201ea478920453f869f0c5fa2d187cab80dbdf41fcc7d0d6bcafc91fd46ef697a12340fe0c3e9cb3752f64254384bb3a8e0c094da623dcea7c62df7c5f508d9ec62e35501b1d4ee0ebf16e6df44cede699f0dc2c7bd167b5d1c1dacdfe3ab4fe293a4ae1fb3017afe82876f18fe5dbf76e0cdbf0ee3b16ba84a52f621d3fad8d5e4006f0e266e2e4ee6cf686176eb4bf76f3a23773bb6c71de46b1ef8a0102e45f45f91fca77fd43f9d656bccfca1854490c5a2bb59bd74218f1951900e603e45ed5bc6fcd00301b20f79eb2f7d11900b607c8076aa383ded7a7c8f6054886e4e875af363ae47d8686e0f51700bc5a6219e0b350e1f09f64933bf611581bbd551bfdac36fa796d74ac363a5e1bfda2363a511b9dac8d4ed5463ffd3e7d043e23bb1a9fe3dd05e178774138de5d108e771784e3dd05e178774138de5d108e771784e3dd05e17877c175bcbbe03ade5d701def2eb88e77175cc7bb0baee3dd05d7f1ee82eb7877c175bcbbe03ade5da8e778b7e08febe6ccdf70e6279df925677ed6997f4c9cf93bcec290337fd759b880200f31edccaf420610d79d850bc499bfe8ccdf96848f9df9790e9d060e0b9709f05e1804f608bee12c0c20cd90b3f01171e6879cf92bce7c05cb8f72920acabe2d4143cefc20a8824289337fd699bfece116069d85cb7e34562352e816aa5609211a78e9c5160937c40f56fff86a076a1baee46e3cfcce7f89b59a44dd96780da522a281a7fd88696cc42bcefc821f7a178b4ff8415710341be27b0ff3977d9dcb4540851ebba086ae7e7d4a87750da8e869165028ac8727be81cf5f941990264409214282e00d3f3b74fe1b76f9bb7747bfdbbaf7ade7d4777e189bec0b676120e2da17da65151ef7c2d08e1cfc8ac738894d3be996f23bfb85761f926fc690333fb3177fbf2067d0991f83bee273f93bff00c5f3da0c71afbf5cdefc3cbe300309f9dcef3bf39f8baebc30e079ff156fd1653960dcc2aee2929580e1076e7b256485a7f1ef7dcf2b70189e8f14bc829951d453ba070e00b391225ff0c6f59c047b90f608f1986c0a5779e92d3806d51729be24073b9fdb603f70176e8317269c85496761ca59b8ed2cdc7116ee3a0b5f3a0bd3cec28cb3f083ba0d864168159a430ee2657c9b87707c7b8caff405fc3b54c6473981f9192cf48077f132f41868b61bcec2d05efc0a47748871305c4729cfd9701de562bd0efbf4ddb3e3e1a8d2d203713d55a537e27a9a4ab7c47eedd27182b68f9d29069685cbdb6d62255dcaef2e4e5141f32db75abff9f81239047f9e873f2fc09f17e1cf4bf0e767f0e7e7f0e717f0a7b505ff62995628d4c0d6fad9f1f51607df7cf2e89beb97bef9e411f9e6e34b22f53fd764ea9b91ab22f5d7db5322f57f2b23926ee8539e6a34910bd6c014d80123600185ebcfc43b2db4cb1937d667dc5fcf9e117ee0a0269ec175001e9a7da378fc409644c5902869441d12558c857b5ceae0fda26227fb6fae8efdf5dcd5e024ffd7c145281bb3591098dbbff968f19b4f6f8466f36f26faff3a78e39bcf1f25dc023b9cc1ffe7e333be89fb9b4fcfe064fdd7dbc3896f1647e4748cc9523ad9fad77b67e4d48ac97c3af93f976f24be79efc6ff9d75bfb9652e0bc8ab7ffddc9d27b149db7991bfbe77574e8498ecc32e95f8ebd933729a83e4f683cc379f3c2a7ff3f1a5f2379f3fdaa9a39b6d8caa41cbf04d7d007f7c49806322f5ee4f7ef3f9a35853ecd054f7cdd5b16f3e3d53fee6ead8ff7c7ca6feae17c7ef6ab38b734ea665d96ffb95bdc5b7f8b7f80eff16dfe0dfe2fbfb5b7c7b7f8befee6ff1cdfd2dbeb7bfc5b7f6b7e4cefe96dcd8df92fbfa5b725b7f4beeea6fc94dfd2db9a7bf25b7f4b7e48efe96dcd0df12fbf9cdfae18ee4d3a9cd89ada1ad91ada1afcf273667b646b646bebebc7536d99cdc5cdc1ad99cdc9cd8bc0d992f362736e7372736e780c1d0d7e73717a09cc07c7d5e6036bfdc1ad99cfffaf2d7e737e724fe36f0db3a0b08c968121340b67506246e9d41c2cdc5cdb9afcfa3265f9ffffaf2d669a9891f13d071ebb44f7b28f3740a3199e8f4e5f381aa07261ddd37557c7d7e6bf8bffbcf6f9dde5ce409501c12848b8d8217befe7304f874686b041a2482d85afdfacf5b439b77a38861fce555246174a3b927aa7158d5a08e51e5a25aed451d9cd38078866c2e90a743646b956c0d93cdc5bfc7cdf6cd2fbefe336f25ac70797352b407f4b6afcfd7f77e162ab8abf05e3006850425d3c910c73a9fbe9b5f8847b439f7f55002de8acddb4faf6e9dfdfacf9b73e14fe1908cbad4fe5df1381aef63193a1c74a1afff1ccb2cbcc51e47b393c976eb0c2a1e306ec7c9f6e910affdd0e64ce2e9d0e6dcd669d97df9abc167611f26f1932c4ec72e4562731a4621975e7cfc86a0797f89602ddc2fdf3038eb2ff3f4f2d7434fafba5fbd32db1ee07b169ecbd319f72bd703f405345ed89c78bae47ed28aecce3f66b76e6d7db6f5f9d6d8d6f8d6175b135b935b535bdbed6a7ba537cf1fcc35279b93cff2abd6a36c06e69be79381bdef97f063a6f5d0b737e41a7e32230cb986ed8a30e4c2d4f32ef60537f5a28b4543ae61d7900b613f7753bfe0d8d3d2900b93875adc32cf7bd0173ce88b9e422f79506ec8c50578c95fb4f844b8e562f6c5fb7c1f6ad58bf68a3d6fcf56fbabe749f58cbd64cf57fbed59fb61f53c3787eaaf0e123452e947532b0eb51f10bb52fdb3bd0279482062d69eb717d0b46b5058155507ab17ed39e46dafdacbfeec8abdea6516ed257bd99ee5d9fa5f7f5c59a16658bded14132a0945840242743d43ae8fd00a66c45eb21fd9737685d897d0906be4ab29003c9921f6249a69f9282651291fe02f618a8faaa7d190cbbeea411b9a727dc44db950b69028e408ee82a7e0d8c094eb23e4c38bc31fce01ca8bd27f37a65c4f66842957ac21d7970143aec6665c758db886ab17aa171251928011d7575321232e7b451a717153a6273399b09c1d7e38da1578afa3d65c8fd0c0f2b46bcd65578435d7f02eacb9a050c27e041a7e3515b0e6f240799750ea1fb0e5f25972716e0d2cb938411d4b2e8edcb325d7b05d29c3b85886f10e52a7ff966cbac2f1c1bc60207f2aa53b924ccd25da15d532cd643364982eb399e6bcc09f30355575d13c9769ce0296a989a3342770254c679adb119368d72cd574513c9769eee3c8d734a6bb38cc64def9a51bd98b76a8998e964c1a7f5b3301278a4d7f52dedec70ee31ae255156ad5dad2d4ac18bfa7bfdfc79a9a388f7f6afd2550fdaa45e65b78be5502122ffcea307bee39f6abc33f939816de30e661782a5217755f0bdfba3dd8da92369bdee1b4ec85a63fbdade9fb7e89cfed974dece0617f1126036640fae0e156f67c53c4295eb133729959de6526ed6b634c3f458e74ea6b778a45d2ce98ff36b395b30cb3b187db53db5f664ea1b41469d74fa540524a8a498198148849a19014084801f71470de4d1cac139aaa66598eb4af4d299838ba764735baf21c76c7344f6a5d797254535526a0bfd59902bf276889431a4d4c27b414b04e015b48dd4991a35a8afc564f9113b4412cac131a14835250881cd5c86f7572223ef6d6cea261253a8e584ccf045de679c0bdc5c6f2ca370a9125a9eaf994b5cc84558a8efbfeebc216d35d9af00c25e1dedcf4bbb53b4657def495d98d631c375a94747a738c2137d58d13558a778e23e84264efd4f38510f791b08fa50cabd330f57d2dcd2c053df23fde781b43263535b5256922b99fa59354f5b9c4d93d975e45b7382348095e463ac9123dd0cc2758017abbea4e8d1e40c4b102201f810128625a21a52908b36953ce714719cbc10c67ca590ddf3413e63553ce6438b8feedb80d2cfa8f699ce55bcef29cb33cec2c0f38cb5f3acbd708a62a88b8e92ccf134c2d39cbd730f3b01ff3b739e6a6b37ccf59be84f9593ffda2b3fc1172e1a596079c87179ce571a41a70961f3acb9708965a44d9772415e872cd59bec0f39791c5b82b6bd6591ec12203c459be2289279ce5f906562eff8835f4d9b54095e69176918b1ce1a5086278c5cf20c9352ea2c2c9b8b03b482234ada058a8ff6dac40bc4cb75dbf3f91dc3065f90a88e242ce003bcef20ee7040d76fb6f682b119f1ab44a5dff69e1237ae80cd03fb139ce41733c7cd7599e2ffb1003d85786eb9f6a44697775c2514f87643a8e731d231b783bee63b96bf05a3d7c17994df06e1e31bbf1a8bfc4c488941e2920ad6a64c3a297a00ee7e10dae63b490cf58c79332c13b6603e5fc163c61595875c1a62e839d7cde6175979ce581c066a5b37c035b806b780b5a1e0d7b96afc3e8f27004655dc1c782540f4fe3d834816fe23539102c79363e31a8523ad99a088184254f0098e774e7a4b409e7e120ea34ec19f1c463b3bca46872cf84c783b4230554e61280b05f79463b61781fe7f731aa250d7478b6feb4ba8fd7c37938d21431f68d7d710435ac17becd0622b43c8f8fb97e85f0c4c6aab2b120d2ccc02780aefad6af10f16b88c435fe2c02d0f50b509a076336f0b1f4d22255b394f05fcd1089f5b3fcc184c01b0b22410d7c345985a994c05fcdc01f2897150801da58c01f28d19e4e96d6afa89646e087198a4cac8b0d6801a68a24006d79ca32f0e19598095866028699088d05bf131b39d3fb28dda736c147a9ce53ad9934fe1ecac40645c45800fc26f0af5b5be04bf3508b474843dbcb7eaf1c2e91824a28cd1aff303544c48040981663bfbaaf05a83a5a32cd5a53da6c33f6ef0335dae83e4528a980da4d69adcdd82f81b1448732319fa9665cfc686ac183e8a506d5158d14b45e8d74f2a7bdaa6824c772d6c62a74a04e45df58654545234585f56806d1ad5c4ff7c69df50b8a066963fd4ab7468c1e8a24b4a7a02b88cae99686bcea479106150ca182012a5043e8a018ae06ae02062a40a57c5331a478c5e0f20d211f50285e31ea38c238daa11dcdb4ed7baba3e38f6f75bc95c9fcffdeca94df329af6c314db56c6bf51242f74301c909a5a5005501f9407bd41655096e8b91ea2e7503b508de4f46c1d5729ee63618512c5576a86f428ba9ba6aaa9cbb4a9b3f50b8acc1598d9abe8a65b88a90537b3718b6ddc92b9facf41ca540c4fa662783215c32f131e954f261472652a865f66dde6f77c2b461d8e9c6005725cd1c911d5246fea8cbcce4c729ca964e353b671abc18600394e8e9037c9ebe438d03eeb651c2cbb0eb4b71ff03b984c74945219615094e8c8a6323eaba7084ec43f4b74f4d2622ae337808a21e5fb04c102c5a012d2a6294689625d5c846723d2a80ef1abb58d4f157863e1f33fb830fb973e53eb8edd92082eadfe8d16a81e59381dd7e9fa956ecb589fc9ecce5eaa470b069e661bb744e4e9e04c1c9818920518e28c849c778d645ae7c08d85846f0e4ea6114825253392efc0524991d100141963539111001419014091110094edb7a4b56e653b7b4ca089f142f1ed6eee786b0f6688f5c6fa8725b9f2f05620818f655c6e6cdc31192e3736ee98504480e46fa8c81ecae4d3498caf400d82bfeb03259ea0e22744be4b7ab9ae112b9a8112f1963961d25dd0e2f2e643956ddca244241456e24998fd242c58684fa5fad2c91ccd529283c1b7043f06a683443ba18aaea2bcbdb336131745adcf3d0789967f422f8b1d873269d6f17c261d8b6c01646b708dc5a32879bd3991dcafee333b68a69935eb4d81555680d44f1459e8f40683d4f4ae0fc0c202a350f36489ea2646aa59bf8341a8a9d26d90ee8d3baaf82dc22fc6a0360d19ae06ca690553c3847029af182204b51e9ae3b60958a3a03094c4e34fcb68350da34f1bbdeb1f9abc87c1fccc539aa9f384a9b38d5b3cd9056de452b282481acce0a9863bf1bde4387983bc497e438e17c8890633ed0e08bfd58689dc660f04a4ee804e9b917be781b8d4415473d4ad7394c437c1d69dd53468b2448f552c1866cce4b67ec78c4106fd73fab1a1f92e11c5ca898fe6d607baad8d5beb0372a73c48bba34970fdc32eff34a8e825236616f4cf8059bab1ea9fd7d208591f2825dc7980cf757a73294d6108d79bf3690a03adde9c4d531816f5e6f63485e14b6fee4b53186cf41f6edb5a4c6927353d6ba46166eb10535bb25924a89b529299e652ba23d9cdb25478c54f36434ed5723c4b810248245240dd043f6ce50c0cea2b6e508e05344720047f406e369bee4866a99a6c86bf54fe64a01d3b92a56e66b02e108309eaa6a0685f5fba2399d3a0f192cd3cc164822633ef347769bacebaccdfe9b454a2a6d2458bbfa101bb2dff651bfc1a3571b8fef5e14378b2fa429b09df96267c22379b3a558d223503e57da7d1660adbba43cff83f70f55491a93933dfa6b6517e20dc9a49f311df4cc5ebb78f35d3a677a2664725161ce02d1184cce231c84c1e2684946837e9b654d26d1509edc5a3563196539d0fe554172339d5c5404e1b071e4b819c14084981905458460a24a480790a38a780eb6e8e595596ed66c56e4a7a34992c10cbd4745a2086ae40af22eb1798d9ab9bb4407a18fc35ac4ecd6c38a6ab2c9b028e296095024629e492020e2960d0e0885565a4472396490c1d0a911e468c7887d63b3b607d06c1c8b60943d660388737ca4858e151dce8b64c9dfae1bb8f0e6265121de2994192f3c24b0889e70344fc3986695e0ad2c0330d93b4a683e7aef8f3a2bf9c3850958146bcb9a6db5abfc064fdea87bbee4876f4e8dac6ad22f32ac35c2d9a2556cb65121d6e0f2dd03a14d06fe390cc6d847abc4517afcbb987c5e2986c398f6fa6c37b64999d45e93e45831f8edd4ccc98499515b4a252d01272b28069d04cb9e3617329980b66f3c15c300b9f1294bbaff683e103400cfceded010cacdf6178b7700bd487790613ed33f2785d527cc3f4eb5a5e3960ae0f988cbc6229074caae62cdd22c735cbdcb873c0640774aae614729c3235470f9cccaf0fc07ff20ad5a96951725ce9517485bcb27141cd690afc27af309d1d302d5d3950d8b850581f20ed340f2cff9057740598ac0f1c50ad4210c0a5bc420b4a9ed1fa433d680b7a827ea013ea814a4815503c8a04fe0754fea353e41dc3f85f588efd47fae0beb674c74fe981536f592dad2dadf0f785a3f0f7a57fceec7feb405bd39f5a9b9f7fe7a022b5c196dd5b51a8c8de4bee56f22128efcd63ffb23e60d21e8bb45395913737eee84c217f602a83df37d707149391e354a78acec82b40aa33a5d104f62625ed14f8903f302c4f8e5328587fd6da5189eff004b743c96c6799ea91c4cf554ac2640a4b94689eaab439a184272ddaa3f5687eb0ffa343097f6d282a55695e4928f117254ee66981962cd3527354d2ec64b05412ba666a092514062051b278f8299325f2eb1f16349526607986507ea228c07888956789125399a9f81dff3311810a58507f0c2a91cb62394cf1634148b6736654a725eac59f12d93e449ad4f2bbfcff5b8a3f55f23b46ad5e4533e0d3e8a4b4e25ad4bb80b04d7dc57ec8615749f52a5ae85678e22110472cea1f5707d1647c9e334353767bd503acd8ab7e3cb7ab77010d2ceb51eda065bddfaede554f2817b0a97fecb7a9b797b6b1a95fb19790e0a13d4becc7f6aa0fb06257ec6562cf439dd0a619b2d501bc7ab068cf92eab0bd541dc4f6845a2f43f92591448be4397bb53a683774aac2c509c942969021f80bae8263036bfa1546ecc71af2e06e51a13c9626d581bd07f9dd951d7d6333fa0656f497d08bec52752061cfdbab110bfacfab83d02421a4d8e5b03f00a0b07277097ce6f31f604bf6dbb389207ae70b74b1040fadb2edabf67dee6fd49e45e7c383f66c44911dadbb439c2ad071229c7616f62f097da93a603fb4977c03aab831b32897a1d8ef96ed55fba1bd5c3d1d30c9b72bb196fa3677d6e6f957b567639caedadc475b75d89ead0e78f6f9988502d97412df2e9f613e6601d78edc97406875c8b3cc7741c0bb2f9db417ec555087179206fa1eb0b213337d1858ca20b80c3a97ed79bb528631a90c55a963b0ef998337abf8e3da78b7b86ec0816f320d7955e657926915cffcd55f1d6a41203613fa0e3739d13ce40fb9791c1cd33fe311867eee913d02b0cbe03b8b32532afa6d32176f388b93ced280b3b8e42cce3a8b8f89b378c7591a7216ef3a4b170014c44d3b8babced22367f13aa2e12f71162f3a8bb705f9e2636769050997869dc5198ebfe12c0d3a4bcb32b538ef2c8d1067f14367f18ab358c19273ee5f82a021c95222160751a747c459fcc059bc8cd05167e93d173a897a7a54b74097c58a0b6a60b7295b211553fb9457eb54b8aaa99d5434256a9a8aaf582a5ca194579754a01abbd92672166f82ce8b33d874abcee2227f5ec4591c4386d7307fd9595c08a1af3b4be7403ae49742b8bbd81b2650bf008293cf08680437046220bf80b2674214f7906118d1d022d4ad1e3eea60959656c3d5f0a9bef430aaee608c969e5a0dcc44510b215fc814a20242047b60b9436f2a8903bc4386bdaaf8e07bf467e6e3d0d8af994b58c7f4727118f117f8df88ada5e8220bced2ce5c9cf9d9c16b13e3e20c7aeb223ee99b4878732f2ece224c9ca50b7e5f67f03e0f384b0ff95bca4d2217cf3a4b2bcee2ed84eca7d3f8f7beec72d79ca555cf0e52bce497656f7c08ef30b02a01ab0ff8a892904c38436ff4f32c24eb12e4237c3e471a57e2208c76aee1645d826c90cf1748b3c4c71acf92320c6f8f485f7551ed9e4417d817a45fc2d9e33e4709fb4a3f306aab0c23ed2abc6372d42d4bd0126a069da5ec2cbeebce49f10fb98c6246b0fe03beae3b8cdc06cb513907953d381e8b70416f60cf3dc77e7df8857239b9bd9e32f46063757d3ec6766471fd425b9c6a69618a1d694fd7b1d8f6ea4a17638dd54dc7897f76971cc5da5e153e810cd7978fd996ac9ead5eb017f1ef4af0766aba3e0e031870074186e1f30cb4cf6c4b8699440b36f19225e15aa8540a73f0c53148fb73fed279513a9f8fc81fb267ed05948c29bb623ff0ca498748d96cb8dc5753f6e25753d57e280969dc12f0956c1725dbdb636a3ccbcbf1945fcf3e51aaaf2f52cb7b76c57e8835c4942b2dea5929b24af5fbd3b53fa95eb01730bcc842f542f582b8245ced27f6b8bd5afd4bb5df5eac9eb617f09ab087fbb07a1add0bccc7622f414b7c3505d818be9fd52d7705b90234962b7e74c5613eb167ed07f6a358dce5ea40ac16ef37d01f70f3f6acbd92b057ea368f47543d5bb7a51a78c0938c0ec9c4f332f1824cbc28132fc9c4cf64e2e732f10b99686d71532eefd643f5f5a8b7bcb53fa95eb41f4173cf62fd66897da37ad15e909b491f57cfe28b310f98d12733d5feea057b9ed87fc18a0ff0f0417f011ef6dc365b387e49428ae02f380bae825f832d9c4faa17910f72411ec801cb63e9efc516d55eb557aaefe17a0fdee2c451bf316a0419b745dd9032327f3f99fe6ab2fc64da1e6f109c1cd0bbba3c044c93695e2e7e7dfad5a4bdf2d5941cf1225b4e37708b94bf0723d13da7abd061aa677d06a5de52f5ab497495b0e0e71c70d560afd80b80aa0e7c35e57a68d88d2f86451e75caf63be1452f202b5f4dc18ad4c453457989d49417474d795bd494b7444d7937d4dc76d3c49d1c9e8ddb3d6fae8919ecbfadc7f871e1317e5c788c1f171ee3c785c7f871e1317e5c788c1f171ee3c785c7f871e1317edcf5183fee7a8c1f773dc68fbb1ee3c75d8ff1e3aec7f871d763fcb8eb317edcf5183fee7a8c1f971ee303368d01df0cc9e42f95b7f7994dd1450c3d9c74c62e3b63abced80367bc3fe18c559cf161040d3a635f247fd9a9335af09629f430aea71b509504d38bced8e5843336ed8c3d76c626f1ef6890b0e4b10b5039e3c301c27c90e3186a5b0992e43d5e71f86c90c5172868294295f5b8d421698fd4ee81547d3548d81ea89da40a55ad2fc86ec9199b75c62f3863f783547d1e2f8f0478bdc38ad08177fb581131b8b3871b43eb7fc4ced86ae4f9859aa2fe838eb2ce47588bc719661af3c463d86523ecbce71ae618fff46398b6c755df7dc0179cb1999d7606411b16d01711e07bea21d675fa06672afd8650cfd9d84fb20795661635582ee9fe4ddbb11bc861123bc212a6679df17ee28cdd41d05d1433eb8c0f84d0d33273c119bb4eb00ab7052dd4791e49c6870948181f74c626796ac0199b77c6478833f61767ec0af6c00bced828c107c0198ca2e041903d36cb092f4bc47b2e7412334b8878102a710b55a8f8a10d766c7d4d908aa9772a5cd954b8b62951d79457d954a0b62951dd544c3553e11aa6e22b970ad76b575bb8a0e792eceaabbc952a2864da0f9ac6f6bae28c2df8a177b122137ed01504cd62653de83d845e960de347889140801aeec74a5d3d15039a790a05f4088bf7a436d87475db414810bc0563c1127e76bad72a6b78838f55913dd7287eaf7baf514edbecc1860bd4d98b1d1b72c66e44b660c7de85a1520e633bda8515b352cced74f13a5d71c6fb11bfdb9d57643021b4191ff6dd4387576b50bea84bce783f2c7175693fae4bfb715dda8febd27e5c97f6e3bab01fdf71e884f109677cd2199f72c66f3be3779cf1bbcef897cef8b4333ee38cffa0a113e0355a85672d06b2fe320e3efca92cf0fc17f8c6dc76c7f5b29c0767f075f368f7123721a2404cdc84a0465eb8848866b18112ea28bbe7a009518d65d084909e724b33aaa6dcc2aca75a3a4eca7716dba064449c8529d25b9842da69173982c6ebed4c21af592a79cd2a5285bc91d38c867ec214637b3f6120464af0f3276fe49039b00596c0ad8ec9cd913ccd92570d5551c90956a40625ff423b2df27a9e961483bc66952835c909da69c65b880b5d8ee49109b080f2501cca42c1fa33c3913c79d520278ae45f3ac9eb25f25a899ce8dc81355fcab779922a95527bb3e6ebb10a56319390ecea59f405c822ef7f0fcd296593a9399aa7ba52ee61265573e5122dd2d21e5e66e0e6be9d2e57efa56c755f4a2e489e3ca0bc3dbd8fadad6d5c2abc6b2fb6f98402e0176d52505ac8a8e7c74c57128aaa24446305a7b5970dad10c6042f53b9286f627b9d154b5457d44408eb2f58643dd4f013ec6462cb423d82a68d7d54cd2590199e1e76b24ea6d31e9a302835dd53429e29a593062b29aa627a668d3c97074c372db9c77898ce0214db531ecff14c3bc03bad2255dd433891eb038c49f396eab36884dc77675f621c28f5fd3882fd3882fd3882fd3882fd7d8e606670f852a94e7eab539db453fd94e58e5ddddd1659ffd452bb2d72cc2a765be4c8c9938a6158e40433f13ab845de304d0b7ef918a65be4a8b2fe1ea6b619c4740ac2c420d68d6240088800f6c0588c62ebefd519c65e2d1e58ff8266b3e455f3c09b2aeb563151549849c9b1032feb9db9f5094a38150c6c90fa542971a871e084d269361adf8037795365e4cda2425ed63b09b021c0819c501a0c71eb5f50f2a64ade2c929775280345c809e5fbba75f12d7c81bf5a2c5aa5c4db4af14026f83eff6e7d82666910e37f2d5d84f736bf5a3cd0a9309dae4f2402d8c0dbac24e06164b334e3e3b19357faedffeebf16ba6e51b4f0557edb54cc84c10a9abc9b866fb2cc4b7760d4ff2e5be29285a13050c77d9d45dec4777afd96a5ab785759bcd5ebb774aa32135fecff8001d47dadff236fe9e2ad56a9fb4a1baaf2435eb3f00e976a030378b8541b18c4c3a5dac0693c5caa0d9cc1c3a5dac0593c5caa0d0ce1e1526d60180f976a032378b8541b78170f976a03fde2700938f2c325e0c90f97802b3f5c02befc700938f3c325e0cd0f97803b3f5c02fefc700924f0c32590111f8e38b002abf50fd7fa2fd5fa97f1ef27b5fe3bb5fe8f6bfdd3a4d6ff51ad7f4efebd8b1401f4b55afffbb5fe6552eb9fa8f55faef53f72c17304b9ae70c63c335bebbf51ebffb2d63f53eb3fc3a137b1cc208204a7b3b5fe7e94f43ea7aaf55fadf5df25b5fe5b520b17cd5909f42599ff2454ee835aff34caf7a0f54757b72d44e503956c5cc3b8ba79f50957c0d358a858679846e197a4f20fb0b12ea158502084bbe1b6949ffc0ea9f55f41cd3e40d087b5fe517c1a1582ba3c42a56e62fdde471d2b5c7d57db479cef5994167f0bc56d3f4f39a18dd02022d293411af0c549e19971fd3e678e1d4f1cb5feeb5cd514acca121dd8bd566bfd7733fe5904a19764efff086b0b3d2fbe4cc0475610edcd3292e55caad6df1fe5e3dbde75fb7eadbf52eb1fa8f5cfd7faefbb2ded9a3004cbef642ae2cf134b9dc38add4ffcc448b85ce41485642b72940acbe745705f38295fb807f817e853f8425c92022af8725caff52fbb135ca4cc7dc496c4db7716cb5dc3b7f512cfba1360049e0f14ba849583d1d29d1783c06c80fc63fe78dd59d207690f10de70a74b4cf78585ae4a75c4f41900ee7c23bc3630501b18ac0d9cae0d9ca90d9cad0d0cd506866b0323b581776b03fddfe746f877745d52ed6ce807c470fd8028a4db52e14f51116e9da42710263c8130e90984e924cbb6db8a087802a92b26c61988b19b234263ada266698e9428fe988a6ec0afa6e28fa9f1ecdb3a839fe25a45cfd28641168cb50a289c22a692229a9a22a696226feb2928dbc00188b15621254a4c85682a3135f2b60e05be3b7f4f3bf301d25128a662ae5827ea12d5bb649da5b904920597fd4aa2a4e939a60671fe15bc8bf05db24ee4d6c6f5440023c6e0b7355d57726ed003976427c3ac16fa8237942cc61d4827558da9d25593ee5ff20b40299d64a6c917fa6670dd6f023e9f4e3235612a25e68e7090d17168632a348e3b9c65690e10ed8828ad8dab2cebddb0c62ce34b7f90b836aebbc317a47f70f74f7fb7966591418f858d4526a5f5495d1b913a062267e30c44c6465c4309bf8108941ce165aea001946b2302f2fcf613d39816761f671b588a7c1925f79b5378886d2c452677642312ae6f6adbdaa6447553e16aa6c2154b05ea14b40bd99d51c89033368cd60077a3462177fd4621d750f81554f66ed42ec40f024db8d9d3dd7a762177a376217777621722d44d796aa6c2eaa53cb5520175526135529ef806d391333624c50959835284e42f39e36f3cabed67aa23a8d77bd252e32e768e61693ee2437223120fbf7bf3917a92ea9a8fc417f8873291187b5cf6759655676cb22c4d03df75c6067807708d23069cb14fbe9541c4d8e338538880fc802944508f46a610a0da9e0e2b9e6f0bea27af7385b402f04b6d714a850c1f50917490e7ee2c8ebec4577cde197b1c8da50145b8ec2f9cf1f7f832a7a339123e430c4437902662857445d85d8619ecc20869d57fdd53cc56ab7c3ce6d73d81fdb06b9a7b59da6c7eee5df1746d70e1efe748708bdfef0c1b5603c1a877a7330ccffb8a5c95acd044d7bdbe198667d3614be949efb2a607694fd7b38376af6986e17dbe22773d5b67f79aa61ff8ccac5ff8e2cbffbda49bd27322c3cfa5147c2ea5ea7c2e857c27aa873d5fbadccba3e4c2fd2f6ee349573fdc71f08fdd543da8341ffce3dbac137f4b94ea6619d46afb5f08a03d3a47308503ba2db5434965da64aee8cb512b87bf06ebc15fad60e2afaaf5e26f96751d5432cdf4f0c13feee31fa84a597ca12a652e1a3f1ecb25a694bbad0eb59851cafc0bd532caee376a597ca396e5376a997bab647ab99baa6fa5da8029fc9474137e688f0e3f9c2102ac1cfc18ac077eb40252a95a2ffc6459d75ba9b6a6834a74a9598c7c5f2bf2035b21a8befcf665d14f6ccb68fc91ddd5f823dbd7c93c0fedacede081f6f6f60322dab9ded4a676b01416dbd794499b81cc3b01d76b34ea188dc6b959fb8e1e545303ff6a28b2ee53f424eef849fa9799691d9737ed0188013a0441de2af49426b61df8be4356e11b0e2735c613590d3e2e21d5ab2bddf07b8a9a6cbbdd87531adf7cc82a2972524b91ac9622bd7a8a9c6a14dff194464a946415725223598df4eae4d49e833bd6df7938d0de7ee0bbdf28ee85e6a4b984560acfac62a741ab13b8518b046ecc2986c9745f11df2c4adfceb1a2d6e38561d4626246d6dd69e8657a70af21c78a4cee3630a6267a28d51306eb823ea0fa761c24a0944eae4dad4d71e7c95668cf81c741140496a5bbf320a6b31213de755071c2136ca157fa3cbb512eb64fe2bb29f5761e30b3edd6c33ec364e52cdb36d42f3a46e64e7d58b9cc7e7d18565786c992e96496259fdd36e78f93e6dff7a479a033ea9ffac779f3c779f31f6edefc7e0e587f9c377f9c37f7763ca8fe70c783d1802f75e7db7a96ca86c58793b5717efcd7d7e8f48f5adb9efe592af20246c00558407128dbe0f0cf8242c4ecab7ff8f77d1cf37dcb53be57c5299f5628d0f020f22a1ef4696a041d3cebf3703e3b3f79dc17448a01e5b76b159de5d6c6e14df38efd3cd23d9efc5179f257d059420632091cfcf1633fa5ceb11f3ff453a2a77e549cfa299181848a633f859ffbd1e0b91f75cffd94bfd173bf2971ee3725cefda6c4b9df9438f79b12e77e53e2dc6f4a9cfb4d8973bf2971ee37e59efb4db9e77e53eeb9df947bee37e59efb4db9e77e53eeb9df947bee37e59efb4db9e77e53f5cefd7ae801c53fa03993379cc9496772c9999c75a6fa893379c7997c04191f68da995c45d075e24c9e75266f3b53171039e24cce73fc08014e5383cee4244f0d3893f3586c8497b9e24c569cc931c27f9ca95967f2ae3339cb91971134e88250211fc917504ae61b9ce3fd9d57c6778437f93e7001b55779a98a33f51e2ae781a691cb15d4cd83de457527fca02567aa5fb682cb6ef211104ecda1c251dce42416baeec7353cc5438d3d4503fa796a79daf894400d02821b1cdc7d77721a5dff8626b8e14c0d472f7efb307bbef2ede3b1dd656f97b4cea10bf4c0e8a10bd43c2674b9e8cbd0b7fdb7b57d272dbe82fe3396c9dbcee46367f263283b35bc171f9b508fc7d8fdaefbcf5a828cf959cbe4657c789f24f0c95dc672b3cee4a877d6128697a0d4b033793981af8c0717472c01609e13e39b907026af72b833e93b5f7181533c9cb89ffe0b54d877bee241da8394d3cee403ec9393c85c1eb1f8e1c0bf2f58aa82efdebc77c4e2427671523b35e14c4d3a5353ced46d67ea8e3375d799fad2999a76a6669ca91ff4a4164697556772ac8cd55a72a6869dc9d932b4213cf2dbd032d098b365f9d6ae3a93d37b39a39582620e687d92bdd3d98806b1a7b33ea5f67c39ddd54cde49f7eb232fa447d591e7b27e15d23e6ecffaf4cd30fbba4eb18d33a468997df051728a7591c249857529002dd16ed2758ae9002045a5077e0c85e93d883da99f6206a67ae8c672f694c274552990a262985a0fcd929c6e0170e34c78d311a5aa0a05a92ca781dc2e8a624d80966837e562bb2848eda25c28e040e6c6c790f2cba4ae508a525525b0a5f1cbbaa1db7ff5e273cfc1efaf5b9f7bee3fff731f3bd8dad2f493d6967f3adc1a8c2f8aadc99d76f1f0ec61df4e9eab502a82ae8bb0817d49192ed7e71cd4f3512aaeddc870fcd792bf0c3b0e75f921459f24f5390bf5b8e5b4ec294505763ce5f2f3b91275f971923e97d87506da1e279b19cafad92e86e2217dadabcff503da172d50a458ab2235934d51279f3dbed3c33a9b924978f5f4b6e4bee47eff7ee4fe6439b9df0c009a92e9837c56ddd516a6fcf635fba01be20779e1a422bb3cf43be875d0e1b0ab410f83be55676da72a0c3a6311c3f3619a6e0cb20239696a3a2b908d8f752d0b9dfa24d54d56203dcafa59f835b46d03f4654f014b72d20426c081f49850aefe6aeaf759725c257f30c9c6759dfce614396e9213da33fc2effaeeed91d3da56c7c9cd0c2eb9cd72c53d7fce0dd07e0fb43423e9ff56b82d32f45e00e978425f8b30ae09ff7b1c067182aff920f8fcfd2c307bd1f263bfee06e1e4663f0fda1eb94a6d36e59c9dd0531f13438c58c531b83eb67ebd5f6f938daedaae5126e573f41d917a9e7ae23ebfdc44898acc42f2e16946281fa3733a88c2d4b656c590aabb7d684986bdccd0995df2e964317aecd282cc474ad800b2ffac3ed404406c4d0cd63a6e81af92deb653aa6daa9be36a191239d7801992a1a79cd52f3f0b798d7c8919c66981a39c1f0f2b146deb04c0b7ec5e5638d1c65a730b19d03855e7ef7b8530719ae038523398d5f3db6c4d56376aace2078542b292a52e72c354b0fbccd149d923799be362133ffdba2bae96514d5cd9c60ffe1a5d76e75d2acd6685c3caa95400e7007a6c00b5860d1fa43e3518d1cfaafdbe4f9ffba4d5ef8afdbe4c5ffba4d5efaafdb50e8bb3f02e9c8b20c1f093115183f6370f123697dc23a0e09b46e9658fbd4080faa474a54cdaf7d1e44f9b7355d84374abda19aac940820e2638562e01c6fa42a975f0ae4db921d6bd78ba652d2e4502179a6258686313b1b45987f4f34bf764b864532b0436a866f3754024ae9a455e2fb9f5a703b14b079c0d2443e10634ed3a9815f8c56299155bcabcf5905e0ed9ce1da6dc3db0a650633f01bd02a25a8aab99f7d54d58cbfa520733de6814efdc791e8c7912838c0f0b770c7e3919ffcc751a9fea8d4a3595d9a91f8471b9c9e496c0ffeb5ad1f866f6dfef8f66168b65f1f3ed48207c5ad2d2dfcd3bde5f0e196a6e79edb07b45996483635b3fdfafe3f1938ec77596a96f196e3a7e5bca1349df18639a514196f89a205eb45a83a5595e43b1d6a26f2d5aa6bbea151e1162dcc35de61185f5e61fce818b30a512c556144b1201f3c3e86025a97a9f194aa2902c68d5b7485d51f221561fd8531e63dfb2f2e2e05d23cfb2f330552f616713e6b951455e95a3f4da07140d6fff3b1424a0ad3bb2c5d21dd9a427a1595e90a31d63e2b75ae9f36d74f371c28ad123966a938b4b72b8cbca629e4df14959c58fbacd460a0b4c8318bb453d2ae90d734f26f0ad0ef39ece5f713f7929e5212c5c8717269ed3345650144c0ed4be4105961bac7277061d430ddb1a8b88b33e31e66982cf8a1b536ad262cbdb47e1a87a4aeb5cf4cd60bdf5be2cd11f1069216b73ee127c6260c3d5a42d3a194883f90d412a7b86f271346192d51b454408b6004c08072474ee633f3df5467d068a662c848a22b30b5cd6c0bc6b7f487bbac9ec6d88b89e4fe7dfae1fdac991e86a1c36c4b068264ce9260a81f120e27e4c79e6e488c0d185488f8e30091408820bfa275c9704ce3c138898cc92913abf63c1fea7840ceea79622fda2bd58bf8632fd90ff8f0c7c371562f56878897e49ac9cc922dce2b78504e226273ce12fba1bd541dc43133601efa93d696c3875b9f7b0e122dff74b8b5b58d76b464d290fdf5e1431cfeabc32fc0d80d14bf6a6d29977539c837b5d18ed64c9a761cca34bd038f553ddc71f08fd58bf68a3d8fa6a03c8a302679f0179ec468c22eb4c37e50bd98e1d94af5cff68a977c28e9e7ed05ce109e9220c048c33cb962af562ff224461c3ea86422eb66ddf266863f89439524d71583265d744334dbb3f643687c11a0195a6f56047175e11709d7552610e10bd22c7be34a75b07ad19e43fe5c632f8b5acb0c0fd03ccbb381a1d330a99aa5454d65017dcf07f53d1f0928bde442ed0752dbf352dbf33121a53d5dcf07753defd7f57c50d7f37e5d83fbb6a1564eb90aa784ae29a16a6abb364db90aa684662957a594d027b54da345c5bb4d95daae95762dff1d6f8afe935f157b1e03042fc3e3112ccff348d1bee8d7d5f33b8e7f8db1951788fdb87ab13a086438205407aaa7edb9d818d8f2913c13456014adaf088eb19e22d5e0ba4331c452e0e05b1d89b60efb037b3e9368dbd796c6bebb5a1db11f564f57ff5ce6e1944156f5cfd57739e802706b6a4bb4bd9549b4c10c7bf09d4864a8f9ea00d4662510941b437af3eede289cf7eecafa8d8ed588d1b11a353a560306da07ffb8cf7bab3baae7ab1733650e782bd556f6bfe31229406d80f706299946a83b0288321c200bf011b7cc7bbba4c00c5260dff7831f0a9ebed14de651c7c0e021b51440aea56f34918c118448776c912801e0457d838dc4232860f2edb36effb13d9f457b06edf4fd0d7ab17a3e136a4604055aced75e2eb2a37ad17ee0b512878bb6e199508b84db811305aace41be0a7340a08e006a7c0d41760f7f5710f5e9a80ea6bcc71d578ff3d58ba98cff21a732eeb3f43f35f709f99f87dbf6a0e0b3f9464ad80ba998ef247b21d5bccdc7924712ffc564dfb297c48272a57ab13961cf4722b75d819a5707a1637878ef63c9fe00e78b00367a5ac89afea4bcbd8fa56050ded724378078ae49ec131d0aef0bd91fd8ae295587e08d12c3c05f6e7f4a677f90084e3bf692bd14e183855ad3e28c127f5e68c0a2623f8867f13c2ffb623a74ac1761017fc32cc411e5df5e037ad3b8bdba87c6f3ad02dedb43c3051711318db6932f71d15797ecfbc1cf717bc59eb5efdbb3f0a168a493b05e82a594bd8a2ba6657b35188336120f507c067a9fe5f2b3cffb34f73ee9bcaf73feeac9cff3903d178e29c376a58c5f9efdf66c99bfa5655c9a8997ae7e90c7837fdc1743dff4bf84b5066bdaa14d9554437abb90da48732a2e2489eb4f57ccf61b9807f6d90fca50ff72f562ec7d95981888325e6e363e06e201fb81b0bb098117ec558138294afe214050bd181735f1d99abd772437ef6e0d6d8d6cce6d9d4b3627b706b6ce6d4e6ece7980b39b139b734f8792cdc9cd89ad55806e9de1f02f9060f3eed6c8d6904c9cd99cd8bcb5f53e643f7b3ab3b9b0b502c985ad735bab5b2b5b678135c7ddde5ad91a115990efe29e9edb5c10994cb30afa7df67488975a40324c4e3c9d03bdb64630b339b739b9f90092d35b67b7ce6d2e7075ce22ece9f0d6d0d3616017f95037b2de87ba19f8a034bdaf2a35b4e057034b78f57bbd0ab7793ed67c26f4866e2e6d4e6e7e59de5cdc9cd83a7bb06eb4558edf55bc55ce39999665e367efcd89a767c2f3f5e6c2d3fecd89a70fb7cec56f776e4e3c855e3294d81ade1ad8bcbd752e017fc2b3fad3db9b135b67b686b78623bba04f6736e779ef7459c83d518fd30e2d97b756b746366ff9c661d00e47e0a7435b439b3309e8d14f6f6f0d3d3de71ed3f841a574726bf8e9edc4d6d9ad217803c4518dcce605fae96d785f9ede768f6b3c4056925c8446d91a86374c1cddf841ed9ea061848eb8073912b43981a73948b6b900cde71ee988ec8e6d8c37cf1fcc35279b93bb31176e86229be7bfc3cb7b86ff0eb5b6fe97f5bfd06e9a63a5b55baa6a919ca5f5f6529151bbadc2fa0599ebb2b48df734912929cc30dc428c7a19c3d294ac2a739d9aeef25ebf407dec725a3197d34c59aab076abb32471dd96d65b1499fa2739a87c37aa8caa8286a8182a848aa07c211825724128a0deed40cd546927a34aaf427a2dcd30d66ee9394a4a74e3bd8df75827cfe5a851a0bd345f2858246b693a354c6a924e46f56e9aa52629aeddeaeda57a96360c0600a250067247a6c80d19218f06f707492f29911cc9924e72ecd99927e260793495e8e84c058eb623f04487a9c4f9096d4e34268d1f02355365095389f80acd9b265ea88b1f0425dc77e653303d3ebed14eebcd6615530e70926087c35b8ed18d55e6ae33e15929a63c862e69349b95f705b3fe401f1ea4944e6a0593e219503e1426206f527e731029b28a522a59ee00c7b33c5600e279bf74c736ccf62a3c5e0017c1df19ef1ae12d3c76ea13e86e9a2f28bedbc839c5fc016f12468626c57f0defde67cebd39e77ebf73ffa273efa173ff03e2dc5b74ee5f73eeddc37c0051919973cebd2f9dfb978873ef2c929ffbeffe0b88b8eedc5b71ee9fe3b4ef3bf79679c1cf9cfb1fa11c2fb3c233679d7b379cfb9f38f74ffbb842e67dce1841ef23bb735227607fc9b9775da23ff123e69cfb3750ed9842335031c13c806b70b50f1bc86b94402b78f5df75850395f4ea13a84040e37a17f6eebdcb1f0fd25e44b6f7169cfb97641e048e3af7cf20d525f94005ee1e4ff9f2dea33c239fc92236f207a8d9399f18005d47490f7d3c00710d694f87700d6ff1c96a781510aa7b5a86f50b28e1096e7085efdebb40068c097f941e3fc14cb0d9a37d13c5bb726206a0f2aa1e4e013044c32afbe8513e05e090cd077131f8fb20cd0997531895e8909d1b3a97fcb2f764d5b99d074d3903e37187736f22e0da1f1ff4358006b10127fe02eebb9f77ef1cf6f5eb992056ded3836ecd9fff0d7c44cbae9b7e41bc439f88f06c45cff34565bd77ddb9379190efe4437e5befde97d84f79877d981045a1761f2048b8dc0fd3fd845f38c7f7974bfa40e2bfe42f0c9f49ea1120833ce017f900c0e715378bf82c006644f97bc2c7be0b41927621e222be00cb7c72712148d2974ee2c33f8d75eef36701bfed1493f0779d6ddc5e2403c4d1cf39b7f1910ec796b27ceae7c2b06b29e77e3f24e13755ffe34f5224b9af8d640cc39d7e19febab5b54d6df338a66399a53989d0d0a50ad62bf96dfd60596bb784eb0e4894a8ceba08edd1d7be2c92d2daad6ed2bdb6acc29f62acfb8eb585ed3d28f9bd6449af1d11ce8d1c65d5b97ef6ebd6e79e63bf7a3172d1ac99723b16a5ce5533efc257b94cdb923d6bb77458aaad2dabd964dacd5a6a969614b1db64840a29b177d49043535ad99f0c970f5f595b5b3669324d65dae297d2d6964dcd8a5e600b4ae4747d6e092e50f07405066eb5e5b52c5e6aa32209e230e14af35d6f0b4a43b23e4ebff6a5ca85717eaeac6ca841b36c6324994e663746b49224c9d6e19f55152055d7bee4acb31b231ee3f610e3123314da0535c784cbbdbdbd5e5b211df34af48ad6c29c2ba72f2447d70a49bce5e24ae8ebab2341d70a7d8256f0d6b542494946afec19857a3b67aaff1a1ccbb2f555bc04976545ad402c53d3b502314c9d6529d9b865f6eaa656203d0a859f1d5c7f63a4472396490c134a931e8518f1d6d8b80ad99efcdb1c846de390a6b12b9a06df8e599519d17b6fa768b7a9d36f77f1ad37c19f8815b8dee59e8db864c13b5be1db62bd097c7e4126de914aaf96900f3640f1a28f017fe0752e99f5f2bb65927fe06a5ceffa05e6b5c2de6ec6c1576a716d79676dc189571ab788e418db2ea1ca3760f8529461a821767d77ae476759f1654feb5f97a3b048a2cdedf09fdf8aa33ff08db8b02d67b3def8c2b57f40d3db922a2bd06e794d301dc8c64e8374ff61f43dd666ca4950732f6a2bc9f4218e43d62e504e8bf9649afdeac5009605b0f2c277cce4c954be8982b7a399aa49e3fe986bdf9e82c14be25a503d11a95146702c51bf76c2e8dd452ac9b40fe187c7ccbba0aba54b452d5d8bbb4cee69c949812ca09fa52b080e6966e94c805d9d2cdd85c4cccc7a1b8f3aa3a23e4a29915559ccfcec698445383d9206b4921337ebd540af3030760ae71a9498c1baa40e9861311379480d5948d2079f2000a9870d3e418449a4f7fc10dcebc1639602a8af962832e8325c5f48c72c0a42da8a129c38a06a916157434c40cd22e3f7fd11ef822424663911f51fee77c0c717f1e881af1b3df075a30bbe6e427bb7f7c1b78d17d460882ef7f64477caef3eb77707ee731bdf9e80c9a6d88d4b214cb102e1be000c5c0aad5f60267705c076e808806553c02c056c52c025854c52c021050c1a38fde4eb225323860e85480fabb78cdac145b3ef66b5d4bcf3e512c5f5526778c1d46d99ba1280ef61c1944974f0e7a565121d8257643d944974c0538c90bc142481671aa1091ba684974aee3aa1b3de62a8dbade3de96433d3aebdeb8a5620db7adab9f789b3a0748f75277c94089b6c14ed641eb17d8a9f8959019b19331a5818c29ed624c690c630a2b986fbd127a4651c98d7f0fdec8a53a39912f58ba49daa96e90e3ba522c9276da4dfe37d38dbca693d7355d570ae477969137c989bc494d4d276f32f8fbfbb53b2afc1ecd7743bef135dc13f902ded53aae2b923ff006c6c016582243e0566707fde5c4518515c9cb8957d6eea86b77c8cb8976aa9b3cb176472f583aa65f56bb4d465e4e1cd759091327f2a6a5aedd69789b4c6104b8f2eb646b7774f2b2da4d8eeb0c746b709d8cbc8297c9402e394e4ee477300a86b6e78e1f2db71fadbfd1d68edb68a9ae3cd58f98fb5a7664ded47aa82d79fc68329d6c3f9a7ce76f340cfa09cd4ca86b77c2a3eeef99b176470f62fc479c2ec21bc68e76b34400eca76789022d5ad4c77127efbeba76276848575abb93e8a1fada1ddcc0ce2a0615e1ce6928fc39c52d6ab57bed0e5f8b4309ff4d5b8a3bd088d7909d38d9e499ac4065152ce85eb6c55cbbe46bd16eef4013337d0285479fe230b35731d90fef15f5a4a6678df49f0c23dd213f6992cdee674eb3fb3994692ea53b92dd2c4bddab81905399f04b0d04402171f2feadfc9ac934e7ddf20695a5b51c64100b688e4008fe80d86c36dd81ebfa66f84be54f061ab843acb49be5a2ba59ae8f33d0ca1dc91cdf4b6ce6092613349979a7b94bd375d665fe4ea7a51235952e5afc0d0d98c8f83dd1f14571474b26cdf0321bfbd5e117dacc8ed64cdaec389479a7d9d4a96a14a91928effbaa3553d8d01d7ae6973e967aaac8d49c996f53f95d39bc03c7af279aa978fdf6b166daf44ed429aca1375c619bc1053677401d585c53b1b8a672714de5e29aee7e71ed97f1ac57d6946f3352ffd2ba573729aead016aed7c6d6d995accdadada7e6d6d99feb575bc9bb0bf8fb5353512567890372c53a77ef0ee579d96bbda849415bbd8b4c422334cf15290029e6798649ba5a5259794567455dd6dad5f60b272f5fd4774c00255dbb855646e4d98ab44b3446ab94ca243f6cc02ad4300fd350ec94403d4632cba765dbe3d2c16c764ab797c331ddeb3caec6d9f511a10a9aca015958296905303aeb653ee0808eb6e7f2e98cd0773c16c36cd477a58a3fbc0ed6939cec39add87e84bf3f1dce2a6ec1ee6875bcec74cabc1abe5c9e62060290ca888b9b67a95dfd0b45712fecbdf12be622ff9e0f6929c8003b40182e6e0b5783e23fba45407ecd9a084557b4140397d9ed7465049849bacc8e99a33048198401a3729666e7e2fc15eaa0e71c54486d37ad98a9ccac575a18a64e7659782d9d97fc4c9fd40579feedf43ab5e85d6ac9eb667abfdfc36f25cb55f64c3b7b72bf6430ebb4aaa57a193f19f8731f7b61f4347b11fd9739c115e33b35765163ac4bc1fbf888fc805d45f267075c5bde9b93a97b6e3d51317a61f07af4bdbf329217e374b09791fb97acd9e0d5c500680bd4cf0cd58c5bb88b177a4f9a5447b19ca2e89a4b8981cbd1f1dbe468ca252426c4ac84a09312921232558a704df060b116088dc9095bc5bcc614b58fcef755522878aea40a27a3abc36818af19b4001e4ee572850bac3eb0098151cc30b158e73afaa87095f8a109e9617d5c3a4dbac5b80962f5c44a9c0ca05de0b78c26ec51bae5e7cd7e6960235c5ac6411a05bb5178032f8622cdbb38de9ddb7a601e592af01b7931f78dbb6952e5ec5ed65cbb7d4277d0fab22fbbe3deb5b17f1cbc9726984ad86b7f7ec4ae4f69e5d79b62b2539c946174bfea935ba62f2a6caeae9bf9d755364ca337cb3dd3fe79552a792ed3d4955465e55b345ad97aa54a47e5a646a216f152dd24e3ba901e042fe2483ffa6425e55f345da49c9eb79ad288ae7ba00dca7a90a79b5d493a7454a8e09da9c06ff94fa13d93fe7810c64a038900522803d7935d7057c81293024afe6e2cf5cd2c9638aa1a9e6db1af9d792a1953aada255d0c83166289d4a51c1846950f36d0b932ac39f7c91aa16f9d752ae4be964c5862e0a8f2906f9d75227396674425172cc50c831230f85eb4f27c714f2af0639d6498e99e498418ee5c9bfc6536f3f8160948b23620a9141368eec61fbd2655467ff52e0e36791dfd392952fd2849a8bb8e67add32a811c204363173d1084fa656d4120144c09b172b2a3d795654f8e7626e175ebad49cff43eb24534d5640dde4a8c24aca29ebd449aad244512b755195b97b9a258110be034f59a72c773b9317b3703fb3a804dc06b212e5f92ca08a54cd799e0359890a407b3aa9a87d22dd2e824349003a1054fb6881ba1b9a4a49e18088852b2b58065395322b29f057350d5aeaa4255a669d966115ac833bd9336f6d4b0a3e7805f8c5b624b2c3cc2fda921ed7643a29f8fa34d971940929434691e042dcc011ad6ee0089f40c096cbae54246ec1af8a9674209ac436a36b606cfdee6eadf4360e4aea8b87d71d8987a77cebc3f85040bcee1d07a0f55d795bbb178c88a7348a88b7766fdb88786bf764483c2514126fed9edee04edbda3d1e144ff107c5bbb7f7db6d30aa1d686f3f20af36341e1efde1eeeac5d30cd0148b45c121703c5444b85b72fbb3a157b33417899ec783e745c6cddcdab81e895a747c6ddcbdc510b8edf02a0777187b8c8cf7f6da3d3df113236130373cdeda784e972ee5991ebaee0680521a0d7d5c7f875eb04d9d87c8c30879c110796e8cbcba21f2b6899067ee2142de3e56a675626cf26d27f693d6965f06c26dfee77f7247aa075b5b9ada922c996ee56315faec684be258f95ddedd3d193cccc611e6b772a869a75d79851c4107aaa49da1e767f853a40af72dad9013e27082bc816713c2b534254731f426ddceb17427c8000992bdcfb1740ff0148ea5eb45de7ccd2ad11ed00e1226352d4ca82a13005523478a795a520c85bcda6d9528454449339446e3cd6b3d45f29a494df21ab232a90a6cc8abdd25f25a498b5706079cd70e91d79e27afbd405e7b911c299257bbc96badcfde81f4f71400a4c8b48441238bb30233f22184181c4e2a0525a174d33ed767b341a9191e71baa91af5a1ca8b16953ead47f19ca97ac57778b3b693d22ced6372b431b50273976979a55749f4b87e54e519aabc1595a505a5401325ad5bdca7150071e7c9a034515438168699120588b8f06428054b948481a6441120ae3a954eb2534aa2c4d1ed3c04c62945de722a9da420956361b02929944b7d667e597df13567447ccd19115f7346c4d79c11f13567447ccd19115f7346c4d79c11f13567447ccd1937bee68c1b5f73c68daf39e3c6d79c71e36bceb8f13567dcf89a336e7ccd1937bee68c1b5f73a65e7c4d93fa6ff54edf70a6a79ce925677ad6997e4c9ce9dbcef463f83b7301411e62da995e850c20ae3b331788337dd14738cf41d3cecc3001ae3383c018613c33efcc8c10677ac899beec4c57b0d828c75f77668624a7514c4f63fa3617479ce9b35048a087510f0f37894a864b8c6235ae87100d6eeffe7fb8217c7784a76f22d3192c348725e69c990129f532c2179119d4610cf3d7246e349688d76a09714b827d1cdd6d1434c65b2b8a5ec2fc0c3258aca7d012ca5a40dc02e2e2e9aee3c38e4737bc7d1c6ea081682b2cf81f66b8dae17a462be6428335f1946e706d19b5131a0915844021473006dcb77152b1ab10a28de7d0e68693a8333d2cfb0334767832c54ebf8acd3412b7d71109163a3d89efcd5c88a3ff4232efc84078c1991e4bc88737cbdfa0bd0412853ac0a8e08f220acc0678d5f8a5e4e90ff0cd1c48e0737eec4ccf2764d7e0751c15fd15fb841758b4114d29c87712b1d3f8779457c70b381ac606ba33bfb7ec6335ed4c7fee4c3f4ec8069d95ec643cd2fa14d98852ab52888c4fead626a0427b448555ece99cad8c55eac14335e80b165fe2295f4bc8e8a530327f2e07d9018fc3b61f30c874cc9919d8eec6b44bb89b00a93313cecca43333e5ccdc7666ee3833779d992f9d99696766c699f94103a48aa16b9ab763194798116cb6396766a48ca9553eed95f1d17e2e67a2cbfcbd283bd37f96efe46df9e407caf25142c19d6ca11d6a4b2642ca24d3ec572f2138a0938c639af0eb86c0171018a323627f8ed8185d31d429973fed6318d5670f3b766116223aec212fc46ba87262bb2e503717165735403ef79c3f6eec338bcc1a597cfabd5d39b3379cd9496776c9999d75661f1367f68e33fbd899bdebcc5d40908798766657210388eb1c74d199bd2d091f3bb3f3cedc05249c1b26c0786e107823ec863337800423c4991d7266af38b3152c39eacc0d10cc0c4966a3981e0425501c7166cf3ab39725ee3d3f82ab1ea0bd85ba54424c1a2c3bb10952e1aaa77650e5d44e6b9b0a543115ae514ad42415507f37760728e60b2cba24949e1de442dfc37a04a0d3d832579cd98510e22e2a3e11825e41e82cfe0d20ee21e8b2afaff87150a5803e0d5775b2029ed201453de5020a8595f0043758a2cd0e09214282e02d180b96f0b3c3c0efe170ef7b0ff2be6d68f77a6b34e879c3d079e6a20b3468a861ec79033b5aa089e736892d3a195d9dc1f318dbcb220cde88f7fc2b30afeb3c7666c7a087e03a0cc0e75c059cd9c72ee57d67f673ec4ef3cedc80b70013efd66559866361e935fb81337b3921ab348d7fefa320b9e80aa35ce6795ff12bd80f47bdb5958448e2ac8f7816bbef0d0e17cb291f5016690fa807facf7b4b280991c47d3ee20a8a5e821683ca56c4cbe52e9ee20964bdb65f42cd2e054e899cd9a56464c121388eb9cfafecccbe8b2ff08c333b58c6f69c40e40c123e90cf12701504cda0962e87c1bdc46b8fa81113b8dda79717b8bdbe7eb111dceba8bce768ee51bd655877bfb632ac7b0365657cf77a0aa6e3647d874b8b68d859cb0df668e1fd32cb8bf56891d7acb539f85b2c5ae448ce324c4bc67ab444ac474bc67ab464acc706ee2f9f65ac474bc67a246f32dda0e4750cef485e5754939213cc80bfb49366e32df3a3a11c0de080c5b134146e18cc911723af5be475054a9013f47bda2ef8363bee6fe41535a1e4235bee473a6908eeb76d7011de2cf48aa62b06530a8900ce5fc86025aad2444133ad42c6c76327b391920f85872e2a5627e5de2b15d532ad44272d5a2a9f610444ecb28b9c92a5be308096dc64d7746a705c5ee6c40e7b51d33595a3b26e566cb0bf6d15a9c0b5bb59b1bd6e2aaac4f5b9d99d3810db679865355bd6b36533ffadcef4ccbc38d46b4b1a26bfbe6fb625d56c32fd3c4fead9641aa89edd299fd8f06f49270f544fdb8f92cdad6eea10a4fe0ca9e7ddd40b2ef64537f5929bfa999bfab99bfa85c7d927e490977cde13e8113cdfe289f4a02f7ac997bce4cfbce4cfbde42f7cd25adc74cc0941ce6f8aed46340984d18a0ba2150c0e254243350a9f15089ee50b9d15089cd5c0ec1a55136a0985843a8d54114a08e142ac10596754ae5eb497ab2368b63b672f118c33e165d118d1971db657abfd7ef2c7907c72df077a721fdabe7ace9e251eb4d1605ebd581db1e74032fc5407f8cf30073ec61fce13f8ad340ada049c900f72411ec8813cb9cf4bcffd1d0cf5f655fb51b5ffab19fb7e02c302e2fd8c489095517bd65eb0579f2c44887c91562ed995069cbc41bf03c01d4f16ecd9ea19348eaf24b0bfe2b59758018dcb2e544fdbf7edd9ea080022e57764ac3b67cf56cfd98b76251476e331f4479c50b0e30e63075be43256ec4af5224e26804b80f24f3eb62b4f3eb667ddef9220302f48a58aee878807c84a126c48f7cb4366dba5b047f030dc0f0d99edf30b78e87e4b886c64c3115f98b932b7797eb250e652caf006f1a7bd87c53ce7195dc04b21eee25d5429c660ce93bfd795b95022cdad015dd1907fa94d4a16f6803e6969597007d141608428c324526752f66662b38365ca65b303e6629ec030c56d3073a856b1988999709f9171b499f76f12566e399501a7f2b95399772a679cca2d82f90a223e45e84da732e754ae3995abce83f304114b98774b3ce847e814823e732ad708961a43d0a77ed6b79ccaa253f908055cf393731d069cca9ffde4b7917cd8a9dc09e9c715facccfe132321df713721d269dca08f219f0935f954c26dc120d36122bb7524ee54c0a84a79ccacd94680601c4faa79cca6700bf2929a1ae12382081b7fd7c107559426e4ac85584ec668bb0f22556e20a56f332d4119fd488ace315685d047d89a061acf0bc53f99cb752c5a95c75dbeb0e92dc762ad79dca25a7b244b0092be2190117a8ef6d5ede7970bee1dedf77a1d99e14e2fb83a80eb4f108fcf99237bbe00fbf93fc193debcb4fbb99b7b13213bc2707ee4121145a0de63c6cb925e7c148a271d9e8815265c07930820d710dc9051f7c3186cbd8c8e3e25144d00d5c06372cb7ab38328d354ca6b79355671f55b61efe5b721ebc1b68adc8d62a7489cfa19701dfe1ed0af91623a8dd35e7c1bbf00ca2d4bedd58316cde97b5e523514305fd9bb5b242192156b6c283012801f2276238ec64e983da2c399581c0ca275602dfd67d00c3275663403e8a097ce3afc9b77fc9dbd28d4195d2c9d6440824367103c03ca73b0715e7421e0c621b0e7bfbb7f1d82c2f299accdbbdf520ed4801ed75099e09763f6fd7360cefe3fc3e46b5e4f62ccf3ea369ba78a0c73f53bfac325d23c759a70ebfed54373477bbad4f23af582afe2df669dcfc15b7c4fa58a95367e48d8269c1efefb54e0139aa183c557fce7b596520ceb7e3d607524086b7e38646b09dc0aeee6d253597d3c8314b6506b032e147e9637ac12a3283bc629d649dcc20ff0c2015b7c23a69769b0b4a2ab0e3be9c14d0e924146fbceb764c21c72c74e6a490572cf2cf4a847c575f62eded078f1e0cc791698e869069aefb29c6f14182d881ebd89b7825a84f537309aad39381a001ff6c15a8915073e181080a1934615886a56ad9842a8c567da30f5014689ef6686a2064008ad340984a0b54a71498f3b23b19390c9a286a5a6742cd053f9aa86058547a28b778c59b4309033762359f61bdc897d249c5000ae1c734605bafe148c0f19a0e0c5d474b90c94a1cb497fbaaf34cbbc4755a27a9eabedf22d727b126d554f7bdc6cc2eeedfc42df99ff1fe59b287e6f2e424fdeffe6ba42b8f3f275937296a27482f60ba692f39a175e549575ed37379f28a65c6bb9917de083c47f2e14d44f5703b35f3a9b78b9aa6ef633f6965cf1f6c6d69696ad64370bea5d84c71cfb159399c4cca8d47f5d72dcf3db74fd97fd8ec5033fb93bdd42ce6934dcdba04ef4b26ffe9f061a52d9948a693c9a6fd66879ed99f2cd157924dcdb43e11cd3435276161a1b4616b24d3ca3bfb5893f4feab4befbf9e235f657f3251b47aa20e740161ba089fcf5a40e8ac27ea3a1610ddb43beacc9523f4a8df54401c7df5448c7f53680e6f9c37990e8f139824f8f3f543c4b30e10b1ee401efa803f8ffdc10f80bee1cf633f090ac13ee307bd629924a25989be120b8cd1db45f10a34bae325abedabaeaca6ac9e5b2d591db71a3ef5a5da017563d4dc997af53ebd8a5a77e955b39b7693a3f404fcf468bdf093cbbf6a16f3902a6a39fcedb4fe5d2054e8390d66b867ca13a7bf67c2f16ff322c851fa4a37ed0e2fdff18116d989c8c478ec987f098e64af58ffdd7f2dbcbc46c21dcc7831672e72dc330f1f68fda7c387594a51b3ec3fde787b5f125ab4a9cd4c1945a58bed6b693ef07cd3fe64919d48a6a3947a94f224fddf514a18532294e8c3dadc9f4cf4bcfaefc977f834fced35c586daa9ae4cdda1ae9d4069e2406b26df81a5418f7502c7695814a8b012c0c78423342c035498fc3908c66698fb5598f34f8ad1a61ba77c15a67a09d271a257617ee720d004a677f507f7a1d89a4efe5451bb143ce012a99fbba99fb578402f79289dfc2947cbc4a116997ad14d3d9f4efe74ed91dab5c68fd1dc349e4eb9b997907c7d0e0fce7e6aa95d163f3813c9e7bde44b905c9f13c4be4ccc1997dfa1e01b5db440366e5a9d14ddd09ae4f7b0c682ef89f53983bc424f293a55c99bac54b24e9123eba396616a0679b9afb8f6a8485e2e2825f23a35d6e74ae4884e8beb7385fa93c71b5d1405e1b7c1ef15837fb3d053c01c39035760091c815d9d8f96e3f414d509fe359901df0ac5f539b2364cf58d515aeaa4e438d3374659a99391df58258a7f90b2d1a87e9c9e22c74df8c229222b600225c96fcc0697f68e432172824211721ce491df987f07c372a7955b7ba426bc4b72ded8dc47f5f5b9304a6c6ae4589175b142a32b7ad9b5476a643324c7d62698bae7ab7986a6ead4f7b9b2764fed62f899d2a9e805ba369130a8aaf479be1364b68414097e1dcffd4891d93cc7823aee270acf643906dac8fd40e199768ea17deeb70924fb38b46f7daee87e9660e69db828e4aaebc248c6c070a38fcb5fcd0d47ee451577e3892b6fef430f044d9e51bd7cd771d8d2c38605b06497c7192d07f43a271acfec48a37e00903f19e98e64afc254831a098375596ad64836277f1a8264e03976b0fd498fc69fe13ef47eaa264a6b5fa2435a2c2f72dc551e90635e141569ee17efa76a626d157d6408c922cbbde00139e6455191ce346779d1538ae52b8939ee1a0f88212bcaf164a6b95de8ca0c4f5366085779a81b33982ad4c464a6b98f9781895114a1ba70960764541732209179473e69bd5c36db68879ae12ee9d44c476b26fa3973aa18b9b74d7ecb7a759a2be661645e9b20477af5b5190b8db87eb7f608adb8144a7e67195d79939b89f5529d1c530c53eb591b330df27b8d83feffac0b133b3414ebd50332b83b726602676009ecea4c0127d6968b34ab90636bcb2a5b9b50808f794a21ed6bb7f42e4b57c8ffc9af2d03c1bf296b532ad381e4c4da2dd3d21b4e02c01679a25ec00c1921172c5f7f2638b1b60c25b947f25be4ffe4c9bfa1c81d4c0629df64902a9552db3865ebc8d262911a9938ef6c015c42b2f64d101d45259368441d3991c8bef553ad9c7deba7f4a052f77821fb538dbb4a37b563da49a6a3c3c39db84b17f107a17cfaff65ef6f9be338ae4371fcfdfd1483b9f66686680c7701f069972d84e283c5984f2128dbbaabcdd460a7777784d99ed54c2f80157651a465d1922c3fc5961cc74e258a9d48f23f2a899674435191f202f7deaa54f8027c0788afa4b2742bdfe25fe774cfd3ee2c083a72e2fcaeab48ec74f7e9d3a7bb4f9f73fae9b47ee68f2ee35383ee1f39189ae6fd27d8e878daf6df8c2b2e9775b7ff26179f3db416c767de67665e98e2c968ab68fb9f428df9b1ba8214d64f000fe4b722ea85cccbacb13de5fc673e5ff005797c10cf7433a2e3d3f75ef8f4bdefc3bf77dffef4bdbffdf4bd1fdb9fbe7bebd3f75e8ec32fdb9fbef73d0cbcfce97b7f69033ca4ff1833fe3849fc5bfcf7235bfe20ca5cf8bbf1c72fec4fdf7b05bf7ef6e97b3fb7f1e7479fbef773c4f27dc42d11bffbe1a7effd35a4213936a2fcd1a7efbd3a09f88f98f0623676bae8fa7fa1c2a984c5bc3fc5bf92ec9fda31f5dfcf867faa9a258d026a7e3c167e7532cbf78a62df7d1f4ac0e07e72faf79338d403bf5fa4fd471e603bf0e4236ea27ffcf4bde7b44fdf7d775c90c7e91f7efaeedbf9f4ac404f1252898e19ff5271fd7b3fd7722085790f22cc8150e80e49ee7b3fd5e2a6fe7e46c0e7e362f1f83dec9b0f9379493eb20b50df8bc5ca8f3e7df74e32459988ef00ac64ab6f7dfaeedbc97c2516073f4d53311fce6192946412136420bf8fb319c99c01ca851f27931a442205d50b28c1be8f939cb867de51ac16cf75102a8d07f0ec6ce2286aa1cafc17a686e67c47f08c2ef2387706a1bd12feeb2f9d41f8afbfb4bb4ef8afbf8cfef597b6b7127aa1dd750683757bb0cef1af3f587fc6fe975facffef5785fdbf5f5d170e5ff1427b55fceb2fd70183cdd7d76594bbfe14fc4e5709ff81e5a692d9899cae13d9ce80c3dfc8c39fd510ffaecba8aefafde4f677074ef1f285aac117830c25dfbf0fd5efa5a4722277b5a34df84373a255479bd8d595a2a53d2e949c2872b8d0dac592a87d7039e43a404ca40d1c9e113c71084641d75b4d448d0ca86b129fdcfe6e6e8b16c3e899e85f7e96ba8e1440eabffccce3283c1c68eb586c401d505c3883603d4cc484371878a1dc9875a236cc7c637f9110e2bf4321d06fcf35b31260efc5ddd7f66edeffceee6bbbb7ecbd1bf77f70ff3bbbb7765fdbfb96bdf71cc4edfecadefdfbddd7f63edabd75ff072a76ef457bf7eff75ed87bf1feb7f76ea69fdf42c8fbdfd9bd73ffdbbbef40c677eeff60efe6eeafeebfbcfbfade0bbbb7ecddbfbf7f73efd94cc4decdbde7818238fdadfb3fd87b360e4e171fff55884e65cfde8bf75fde7b76f7ddfb2fefdddc7dfdfecb90ebf96cf09dfb2fefbd9889f8f82656248dd8fb680c62f71fee3fbff71c7c2471fb092ca0004bc5b2103fe2443c8863ba847ac8bcff2ef78e18de7b71ef85bd6fedbd70710efbf1c5bd9b7b2f7cfce699b9bd67ef3f0fdf4a581d0876f7a54941b6fb92f670792766f77b2fdeffc1eeadbd17f69ed3f69ebdff838f6fde7f79088df3f147f75fdebd35fcf82674efeeaff65ed8bba9edbe7effdbbbb780ef547c3e19f2232137877bcfde7ff9e39bbfc551f4027262f70d295571cc14e292e3ea53a88bb34b2233e7d5b347daf759bb904bac9572f9109b15c9dadbc9a3e5f25221fdd5f0e40948cb54a01a9eac5416ca4b53ab0000f32900868f97c73364ea548dab53acc8765fbffffcc76f013368bbefecbeb6fbf7f75fdefdd5b85a93b1f75f2e04516b2358e4b7a0127bcfeebd102f918c6748b5dfeeafeedfdcbb19173eb1d482ecfaadddb7a00e7bdf9c8ef0801b05990649770b32cd0a5a72ef26b413f48c8632f2d9bde7414e268a331fd9adea52206a7bcf01defbdfc658a94ab3519d0430a53dd1acd92837c588a33351b271f0628a090773a26de3e020c580e33ed1ba2af8e00b8a8960182a81319c03cedcfb08babff076040cd9f8dd85699b16d9cd8a593d1572f2b0cdba02fb7a0e282d564ff637924359077610b4fbd2e136d189fe30be7e0864d97da9e8eee417b4efa14405719490d0bb206cf89258d2ef3db7f3eb9ddbf896c0873b6febd55cc4bd67f5aade496073efdf8cf9f8578fce18219d65c4a19b515405ecb95789ecfc4b05b920949c09de7b765f605cb31c27dece056fe7821315db17185742f3f5b53381db99c0583b4c05c3b185b71b3fbcf792bdf3eece87f75e513f3bcae9c3ce3fdd7be5de8d7bdfbf771320d2c02bb90040c328bb77fdde2b3b77ec7bd7773edab90315c00f4c1fd579236b3e845fae9429ad944af0519e01dd828f054110df22828f9374b1543210e264a53c1ce2d72374be6c2ee1a3424e7dbe618eb2e701135e9e78180406d4ce47faac51c14bc31d2fb23a413f8c0c7349dfb9250fe6e9eae991097b7a3535a637d5f8d1efddb8f7cabd6fef7c78effbf6ce07f7be87ef05bdb3f391bd736be73dbcf5fa8f32edceceafefbd72ef9b1890efb7ecfc5a06be8d80bf5628766eeffcb38cbf81f132b0f36b89edde0d19fc9f3b1fedfc5a61833cf76e60c1ffbcf33672f3ce3bf81a12f4e1f773e65a241cee3a7ec05942b9ea7649fbed9df7b394abb49876194ca857c198fe1811d640a5c5755069692d54445c8f346fb626693d303d5b93d1d84d5fac8baa85aa414277427142aba232a14f5196d093509250506cebe765bf3c6bbac983aec751f7c6af1edd7b65e703e8a8e46119888031610381d8001fc9411253947f7749d2f6cf9f5effe9bdef43a7efdcbe77133964cad34b4eb3d98f2629f8de435200a2683f0abe67679ffac951d066dc9b28ff95f1f2ef00ab66cbbfa324b16a81dbb9f277dec157abf234bc926d85db390e511a6546be44c0adb45fd4e9ad0a39665acd80371d6114249749c534ab6c89d70f1b4fd6eb3b7fbef3eb9d5fdc7bb6f164c3d496c0043b6c09160943984b7adae27af5f093f52563a91a3f3607ed7cef2743f9a01334140c69883297b4a5271b13a8e2a6d3ab7a4a92dea833f54e4f354beaa8e099ad77a1993fb4918fd5ab58c0c8ff2c6fd7ef73f1fb21f37e51a776b47bd7ad8215a97bd7ad07b906cdc214d9f4dcd0eb3bafde7b498a64a9d234dd4ccc794cff094806f5a216d44a99e598f6e7f2aabe4c492c7c4cfa456c86ab3c077f804b3daea59ebecabda0a521ea9f6719272dc66a3abe8f08cde2c7b4a6e080ba176239e043f3634f3e7d39d25042ffd3bd67e5a34fe8170107f84b3080b5bc3934be973bf6fe92dad84dec0f3ddee1cdd91c7abcddab6c0b5dedfa8e4dd4715c7dfbde2b4314f71f021143a90487284254674ebd0278f8cf8c0270f34b6a74b2033d6ebeb8a4c774e05decf9253d2527f69aa4547355cf167490fbd93bef0fa1010f3affb8a826146e76feb1cf5463e77d3513c94f53a0c8c2b9c717ea42bdaeeffec3decdbde7776fdd7f4927fade8ddd5b690017fb3ebea9135d2df6bd04933a88ff7b04d8fd873d9c19ca8f6fe15c12e35ffbf8addd776052a9c3cfde73bbafefde92f16fecfe6aef7915c485be24edaddd7754a04138d0f51a82be26413fbaff92fc786eefe6c76f2119bbafefbef5f147b2f4e776dfdfbd053992e0fd1b3ad1efdfd8bbb1fbabfb37f4c6e4426de6aca9c8193622b535f898a8e739e1cdff433707765f2adc1e181b8ebbefedbebefbe670f7ddddd7f69e9b7eef56a63fd4fd5a8959afc679a72ce8fcedee3f68bbafef3dbff7cdc9859c8fdfd8fb56416276df219f9aaed77cfcd6eedbbbef425f6ac8a1bfd62621d5da4d0a9aacdae4400fb866b3fbfaeefbbb6f6524f0de37775f07c68baafac737f76eeebea5edbe73ffa58fdfd8bbf9f1f3d9559a24aa5bd5775f83a0065cbbf77e767d06839d04e0e3b73efe08e2806bd5da4c12f5e7726d4602eebe95599991818b9962765f030c6a5d260e0ed2dcefecbe96599751c1fface58c2fe8f84fff993f7846caef86ecbc95f18cf4b6bdf3e38c67a4b7ed9d57339e91deb6775ecb79467adb460f3def67235eb9f72c1068efbc1ec7edfbea2c96ae4a55a5a952146e8551e1dbc7387e0b264b3fbef72c62411c8801f363eeff94adda9c17569430fb7a45fae1bd67d1afd087896f1e90431a3e399bbb96bbf3a67aecf79d9db72740b24252597ab78b1166dc28fd251a3a6f4f87532273e717f7be09a5ee7c188bccfd8b389009fbd6ce1db038b52f47daceed7bdfdeb92d9f22578f98fe70e7f6bdeb1a4c4c914200fa68e78378790c46f2b7ee3d7bef7afcf4b712aff9c82e3af8413cefeebc8dc5dd19f39894467612e0fd7d26c518b10112511b072fa6001fedbc9f7a4dc2c0204d7c7fe776c66b920afece9cf3f49f193f79f284c3d7e203d4bebc3f73aa1732bcf66f9f1ff439fcf1ed536bed7e24ec65c685b312da9757f1e75230809f336cd559d9e794c913d933d3bd701235e05597fd07806d8ab87ac2598d3a0e5f71ec337df5b1ccd4c7e94e10aacf2bce407dfd49bfebd8cbf8bd9f207ac259458c880d31010ec88d99a7cb9d2780127b99411efb0a940719fe0bc89a47fbed3ed7a240de63d1eaae9313306743e1c86742334959c1b2dae7de78f6549c7c95353b4e51b2922297ff48b49de4364d11ae83c88d279ca73d0ef2c06b76d0c9a514188f7aa1c691802f475ae0bb9e7c6a2f0ab83770d20b362a985cb079da7b3a7bc14606e30b3641f6824d90b960b3da4fefd7e0b7ba5e13a4d76b82ccf51a2f73bbc6f37f77c37ccdcbdef8ee6cbfcadb5ac5561ff3f1c742fcb1187f1c893f8ec61fc7e28fe3f1c789f8a3524ebe12dc95f9e952e05aa75cb1af75caf3f06701fe2cc29f23f0e728fc39067f8ec39f13f6b54ea50c7f204721d26917a69b9d4f3e784de39d4feebc296cd1f9e48337b48ee3a9af15477d88fff3b6fae2ffebd9aefa8cb65fedc7809fdcf9c5603f9171fa927d6ddebeb6605f5bb4af1db1af1db5af1d9b2e270e0c9dafd5d8942d7286cdcef44b0c87ffacd9f9d261ef6196432af34b7c498f1cbdaa2f9fc2ab0bcd8e5ed54f3fa68fbe10c15587d66d14c8af4cc23ecb880550be2c4b15957f32f4c16f8892833e22fad8f6bb5d8d3b03cddfbed31c9f9d5e6a6fffcd40eb3ade586a56408afe27775ee39af8e4839f65c1325e8aa184a7fbce5862018ef0930f7e94c571c06929169d99958af0ffbcfdc9073f6ba2345cdbfe1b4f6b7bdb7f3b4824a20a75ab7af7930f7e2ab45e67fb4efae6a80a75e2d4b6f7c9077f95c8441572e3540e2d94084615ba18a74a5991bedbac828324f7ff7ab69bc8490cfcbe38471997b31b73bd88f5dd207b216d6bfbd5ed5bdb77b65fdd0ab73fb4cf6d6dbfb1126edfd9da7e15825b78bf6bab636fdfe86d85db6ffa1803097fb27d67fbd6f61b5bf69f6cdff1b7b63fb4b76f6cdfd96a6fdf89c496bdbcfd466f4b6cbfd15dd9da7e23b4b77fb4d514dbefa8c00fb7b6df59db7ea3bbb502c1ad33db6f34b7dfd8ea42689f6b6c48a6bd756efb8d154995bdb57da317e6e9c11f1f52b6efb4ed2d20c3dedafe5153d85bdb3fdc7e674d96f610d279790bd0badbaf420d2f6ebfb38581ed0fb7ec6bdb77b6dfd88a54e8ebdb6fb85bd01e91bb85f45cdbea6cdf09a32d5752772edc7e53a52c6f6dbf2ab6ef843269dfcb715bb24e17b7df811f2cd1de82a2ecad6b9ded3b122d5473df7b725bdb7790742019b30371f6b9706be2b6dcc33f78fa1fe884f7dad6f63bb223b4ed57272e51436a77fb9dad30dc7e676b3d0f91bb95f6eac405eaedbfdada7e2312c09ce3f83336e085aded572311db8009c44184dbf69b5bdbb7f29b1edbaf6eb5b7df41d1b6fdaab6d5da7e635ddb8a6024208b45a9ddb78591dbb7b620b22bc1bbdb6f6edfdadabe23b6df484f196f41e4f61d1876110a3ea8cb2dad0318ef8489e8eb6c6dbf039c89d20f9049364c1e5d46268d50fac9a2a06cd1495f5e86fcb7c4562742090830db1f6ebfb1fd6ae6fde50fb730223ac0c128d119c6cedbffab796e1f17ae83ac585dfee4cefb776f84f8d73e7bf77ac8ee5ef7d9ddebf627776e63ec75eedcbd6e9fbf7bbdbdc224c88ab7e2d997ef5e5feddfbdeef6ed53ed4feebcdf0d20a6ddbf7b83db97d7d93ab33ff9e0a5bbd7d79dbbd743c8ff28bb7bc3efdfbd21a37b88f8ee3e4b758a2ca4c8475ab8a4411210172f0b8f8b8692d3726599fb14984acf5377af7b88f0867dea29a8e5f9bbd723a4a0dde780e1a94f3ef8eedd1ba1aa800cad7cf2c1778132e1011d77afaf38776f743193d87752ac0a1b2f091187f877651ced74a12991d9a79e4244901b51480c98fd8193e64eb5dbd54e29e3533d9784e187959909a2294253a54f79a5e2ee75eeddbdae716f5c626207fa4e2e252b293ff9e0256cc1eb9a08eedee07f04fdd2d0ea31782a3f4f012f6bd9f8e9687cece20c9a83c84feeddcd7bded4563ff9e0bb4f4107e22d0cd9d54ff5efded01c67e0dcbda1b99e724da1c2ea418b2ce4aac3a5eccc46aaa72dd69dbb37561de149a04e36463d7101e5635524889b8b524f5d0451ffee75997e3109aaa72e3ef9e0bb2e0c6a993cc8c6ecfbe04552c893d184253946c1ef48ca3dd3c9df03f9cdedeb9ffffc79fb37775ec29fdb2fc0cf673ffb998cfc31869e7b53a63d2b43ff3f0cbdff5718faee0df5a310c117e29a2ec42a00370f7f16e0cf22fc39027f8ec29f63f0e738fc39017f2a65fc8b792af3e3785359f5f95ffcf5e73fffebcf7ff277b6fcfacdedebf1d79d9792b817d4d7673ffb5992fae338eeb937f7934f9ffdf075c0fed90f5f07d4f073e725197a017e002346fe18435370a170023480031060ee9ffdccc67c63991efa3a0548a5ec758acfde7ff7e2e73f7ffecce73ff9bbccc5894ceca9cefffde6fbddee67cfdf8cc5d31800c8802c901f1774f88c9c0d4f14e317c4e6e7c505454cdb34feecdb2f7dfed3d7879fffe48ddfdc7e71f89bdb2f7ef6dde787bfb9fda6fcf90efc7cfed3bffccded177f8b9b1312777cb7411611876449c9bd085954028a257eb1d7201431f1cd07454d72eb41d1935c72904d905e7250045663da8a75c96f3e78f1b35fbed1c8ab91cfffe27bd948652dffe6f677d00d735e537cfe17afc7b019cbfa37b75f4c60f3eae041c6e3e73ff9bbe1e73f7f7ef8d90f5fff82ced0030bd6e2c32e99e89f3fbfdfa1facf7ef87ae18196696b1d9fdd7c2e55669fbd20df64feecdb7ff37f5ffbf3c4f0c76ff403fdd9f337ffedcfff3a31f4e320fa7efeecedef7ffe93ff9918f77110bd3b7ff6cb3712b31ebfd1a3f36f6eff0a6a139bf37110fd377ff6febb89110fdfbf3353f999ce5c67f50f4ae4e195c8bf5dbf05d8ffedfa2d400d3f775e92a117e0073062e48f31f45f4389e41705a64bf7ff6795c79b6930f706cc03d4ca035f83f9834299a650feedfaadff5485f26fd76f3d9c4279eeb50285f2fe47d315ca0ffe22a750209828949f7e33a7507efacd7d15ca67d7bf93552871b058a17c51da43acff417bfc417bfc417bfc417b8c2f6b29f5317e8d3ad61f5aa102195fec8f3548c112d51f54c8efaf0a912cc98d23274ce2506ecc1f3f66120f3f8e9b24c08f132689e0e344d9247dfca8649e7ff0d31d07bc6c63dbae231cdba69cad6ba1c1cc1a4647de338c0afc19f9562f0c4420063d66357de684d421d93897f94c30eae522db4cd02017d371221ae5622226689f308b6df4825044d4cf57d8dc4c930a850693439bcd80e41033548cf669b1b26cb1e315b35684d6dcf45ac68c633053f9c09da9a87b16d828eaf07d3d58798a3585764ee56be852b8c4f15f619c858e08c26900a7a2016f4e4bbc12061b038c2ca888914424772775990f320c7a2c6869a254827fd6658ca794ca8f524964eacc47995b4d841b8b27c6392dc61fd399e932112c8bd0e3ede96dc8fbbe3f4399b929c241dc515c16c8cc51d301b9c0cccd512699cdea7a2665a41a5bdfa73b172aaa3f172a0b72042c54168b7b16fd050724227d99dda79512272e6596cf785b7448930af559f35a863b439ba5d28ce1974acd47dc316e68d13e70367084d7325aa5920c8a184c6b512a10b243e72aa44b67caa447e74b7c098797d239b556101a7d607f6c6d223f0561666d76b673d2ad49426dcaea9d06195051ef34a0bcc084e835ea2f05c680d8a4430461a46f5603c32603d22150d73e92260b9aa1740d3b65cd6c065c78bccf6a5d3a53a9ad84cc591d792da317f3bd20469e0520da337a4498a5926183761e0e23c3260c5bb36f2655ee59bd7e04b27e649ae66606fd88f911d3bc9661cf503a28956622245365cf412a547d254b0c068da2be8549bafb71c2fc71c909472ac00892e3538e2501f540f45c5ee757c2a0c742312011f5000003e7a3b3bcdf65a1b3e233d2a7a1317907de09dbfd2ee3221a19a6b914161d6801b9512a058acd890ebf8ce926547a22729461d3fe7e039da5b59c57027f013e3c2a4aa51961f1c065d7063d107e50cd52694220b05289954a332c03ca484403a0352681526f29b41eedb75a2c6650d2a746b414595e948b36874327477b5e901c3b6e82f82c962587ffcc58aa9687f5cadc89c693ee21f34b87a70cd6b8ce710de27bc93386a0205bc07e3b512e1fab9c38317f64f1d862f9c4894a159954e7fdee0a0b754ac3e1508f06dd95c0d76768582af1f8089e592ab147e62aa512fb7285d272a9c44eeea73416166229b35051526661de946ded595e042dea9e0a4307782a58728cc0ac86997a45d351cfc73d7a7c8ad84a784b09d452c9316291057c056a691fd2a7ebb95479b262340fd4bb49241f2392974a06afb306e8e552291542a0a4358f6b72701adc34cdd13eb4cf2f5664db1c9d2ad2cd4d90a192b5cac4a306e86990a0662cca9366e327bd9ac928ab3b86a8f3d9d986d9481eaa2a9538b03f8b2703fbb0426c3f1c518c7044195c0b47a7b474a6c1a0919758d5c1c8a53a6b543d23c0b13259606e61404933b93a10cb2f4310ddb659743170fb3ed3c9e69ae3f75975a63c3209c282454c33722c6e2a46135116eb3e41917d41e0725aaef193acc667674d51e78d14b8ce1ba90119ee8f90a708435aae8527592d9c9d35793dcc220c1b35e9be1f7a297994c66a05e159a7d9318c029b825227392a6339bd9e3f50fc45b8a93a1b78cea1c21c8d4c93384aa91865e2c58d621aa139aa29173ad077c770581b2175cc5229b4d2565d0aab9bc9dc222bb093067e40cf65ec2d63e1d862812d9f031799b2c16810d6058faf9e0eb8703cce42aa0c07c98d8a2b9c28f2da7c38cc3656dc3382566ae2e478efd4c4ec6c2c90d3ce108d5a9c2d8451cacd71253aa640a5d4e72404a9cba067a17bcd517abad3a17a4c55aa8c965122974ab1681e4bb03c216de7a50269156b8351e171d252699fe298d50c7824c27e530421a534899f89bfd38a2ec5b455930271b45760acfb8607532bdfe04665de9493abcaf1f1b9554a13cbf2134bf9898d52ef3b6e6a6c19202223e1f0269af2a6293a61b0ae81e1087ae66c1806a1a19f76380f84063da0395ad377a2487322cd4984b29ef1edd34cb1b30cbaabacc542c69b314ed0df5ac789f81f096d8531ae79dc139ee37b1173b5392deaf75868983908b4655c3d9e18cdc03446191f3399d948da2d69ec12ab8a9134a627fb7266c660569709e7ab6c301c32cbf185fa6a8ad0579f51c76b41b439221d3a3e5272a321759fa5d89e843557da2bc24cb8de9914639e12630e747cb9169c746ac1ecace9d583ac180b524d4243da9488190e0f25a218a9436423769ce299a64942abe370d767a77dafb93af1fea2a0215aa711e15458cd8ee7bb21e3c4a1c20a386601039f4b98380a6c9c5c040860076d0693ccb058685d09d91ae382b9a512fa79b156fa4204bc549a69813ada64564f429c91f08659938f44c6248135ad2e08a3192d02d20703db8b44100e6ac1523fb93f1c99d5be9c1aa0ef8ca611129ec88889b94611a7944a52ae53513c1696813135b6d10b5914413777fb91d098273a2cd456181a255a10660607d160f0e8b37109a0b993c11fcbd566c81c9877c04c3a9d476c66a44855a95c46583279a8ce54c87ae809f95d26cd80b7bc765fa59547a09c4b25439511317125467db9b554188b6d5305298254d836a8363472485636878cbb59be975cc4a8e472b9ca93f293ea2934992c3f683ad82cc2eac2f49b082b128ef09a309cd8862029ff81e43344d2f7c21281497c2a2cb6e13405712964055d86d369a729bc35761aa4d325a7cb480b3839097512886531f019e96266f8ea516179d1294c2376c1bc80d3cd515e5b315324efcd85e623b43c1c1e487d31a9bed030011d66264319dab8aeab86d2891eb7924e746c259de8b956d2891eb7924e74d5423ad145a0131d9b0773a0a227fa58d340e6cc77a6593093fc8d9b446f986440b9e2d0c742d63210316fa76a2f5adaec39a2c39d2eab46a36a6492351ac4e3df3aad08b502ee0f0c2fa9740a21719ff5198838a36f5d0dfa8211c4594de79754195f94d26849ef7369a1ba7ad53122d35c8aac9406824d50f5896c82aa4be2d6aa4e2e69657812049ee44a8fcecc18bda59ee1106e569d22a2fd802734af91d0d81c119b6c262d5badb7c89a1290291f7a4b4df95295f554e07143d774d312a1d7354c822d5ff59610539774cc6a977442d6aa0e8812b0559695e223b0e5cd111123c3b34e07dd5ec0191766ad838582cc8ae8a662a96a94d01d759c1e3336414a6662a1592c2fbaca9eee7b21738962a97d205286980e3432b339e266cec0cbce25d8e693d139969f4c4efa344d61b23fb2a5c66d9727b2a0822b41e0131164cbe1ec720b1ad2a867da0f999f8c53d3c85555f2df186ec58c63b129c34c9431366e270124cb4c344c66444f26c6037bac4146a4936aeca017d1cdb885662aaa3a3395b80a339509da9418d14799f9a051267d6bdd131d1cd0a1697426566aa6ae9e86c4211e09482487699ff8c4254dd2221dd2253d62930159236db2423737aa6532a8964760a20ca8d1a7e19c300f05b3864bd91c370f45b3468bf243628e1d0a4d529ea1d4b069ff9033eb1ef2665b66a954966b85f623b44ce9e011ba68665618006b8f1a3e8de63cf3109f359ad4990bcc43e1acd1a1c1216fce391429ac5dea1f62b3cd4362b6a3b0f64aa52e62ed3d42cbe358cb28d268ff5073ce3f94acfa6ad9e9e9dac9f2d2dcdae1f9eadae17952266dea1eeacc350fb5c88ab5418df6c9f2527bae5c6dcf96cdc36ba44dfd43adb9fea10e59b10613a92bfb2e7e1cdb67878259eb6ca5ed9fe7bdbe380b865a943cd9379122f72f084852a807f168bd4102f813c19f3efcf1e18f0b7f9ab4dea8cd8c1ba3adb44b4947a259a315d2a6b3608b9d7104232b391a07864fea1dc21a2669591b94594ddf635c7c83b4ac41127a62442e660d96d00a5a2d43ef06fd88758335a69315b092d3c87e4f2717cd1159cfe6e214b7991e0dfadcf578fb34a2beca9ac23047b5758fbbc1bae5b82e36c6052f128cb3d0d0431679cf309dac9b64dd30092b00c9d031be1231e3989b6bb3b35f3e86ab87066058a31553357548672ab55cb5e7b8e5b396c8d77e8e5b22e81143d0aed132cd52a90336ee92d12995064640ea9d860936120969381c0e0c0f63ccaa5c05a142c1974a860248b2008449c252a987ab7ae63ed57383753e563d9c0a81b2add4a05e07af8743eb5011e8f47ab9b16478746044c4c12ee405ddca73bd4a04559de5064d9c5859018f98cf9a22124e28c8bea9d4261dead4cb0db3aaf8d353d5dfaff650f2e43a3b7152b63e7037aa09123640403d4a69a76684b4ee0d871dd522c028fbd6419081e1ccb54f2e96cba552b0d4acba2434499b3a6460f4d14eede16aa1698e0ce4f9af844eafe335a3ab41200cd3547b539b58b7b35cb0fc2645c1e2082b953c39394b3637b5d68820820bcc59630740104c43702658e707c81f4dcbff78ef00b9fbd3725f0c0e44bd5f90bf89c6c983f3ba0579dd15fff401b337a7917edae94dbc31ee5086671a9803552b020218e0fc51f26ce7a42ea02dd24a17aa3ab1d2018d522a31dce78f5510b37a41e429135c2625875fac8d39e7244c8c4f86d6c6ac532a85d660ce39c94b257e32b406b3f1a2eb4c395d84ea1a991d7b60de4b81cb4e0929aeaf0491214827b366059cbec9ac48043db07d9c369aa94b1331064c8d9b0e6f32ffd1feca0a2e9ba658eccc525c0fd7402a69e220339fc4c9a45afa4eb60e6669c584a6a9f3467ea939d9e88509fd7e3a3cbb2c2897fd3793b13f21932039a5ce1b030f517616e4283012e4666f3c33531c17638a2d855075e766c0ab0e095aadaa371a1913d6604210a0cd1406d93866e304faa4ca0fb27f241779d28962429d948cc3e18c1291f9b9baa17367cd6b3b2208f5b8ed3757c2603d626155d7c91a0b2398c5e8655d2eecb3589924f9ac7ec4c2536d68cadc5ba244d0c3c63a5b59f58459d79e3cdc30ea4fae5b8d59f3b0c53658d360e67078d800321cd358aa5a875459e6d274e86ee431532b48cabc89df0cba3d47782b3ed3cd93e552e9b0d10d9ef17c5f95b2a4856bd51883b994c1518f571b930610f54a6338cc3483a8cf4344592fead062a3522e399671fb070dcca0d58a98b8e284c0326eb02966691c790174204fc3d782de68bde3f94c9dfaa006a363086219571784370a86cc7e9bc09c86863053f375734482cc1423395c92281d63ec0c83431909ac0d5c7c925668600d92d01344655512d5704cb5c1e2d599e5b9c9e26e08722ee0cba0ab339f8620814966ca23d3b494decaef5c71ab406e1b4e5c2375be68ac305c768412825efa65e4ca010d375e55af653871ab7975278b11a4b315f033a1d34ebf0c413637aa49c3cc05d6061924e127e6026b3032f76d3c5cd334c9e68ac75dc078e94c18f4c6ce01aaba5141c47028cf73682a6e34523b71282f8f166c90e54e3c4d9346e3cb9e3057c51de1bade8d74a277836774a2cb61ae133dd01bb59066e4d04c5e0e2dc99f6aba75bd24aa9bc0ea5e97057d51e5048fc02541b91ac968b9c64e7a4a81944a33a115b2a7fb2c12a7b8d7457d752e74baac363bab865c00fddea84d81a3613d98d5af1625e90d122abd5794e774418ade180e338953d08ea6d0321c1ad3a89c9423466c3f9ba0e9a1950c93707ad1111dabeb6c186552393a678839c7348947432b6d59237bf2861962969b2393f0c44672a898e5c41b99b5e2ea239985ed92db65b2b2dd87d30455c0c4742039f2cb0d936ca2a67348c8d062cf1a5f6238e486391ad5722c2ae8944633b84998610e878e9151fa0ece828bc807092868194f859a0738ba37fd70a3da02dcecb22872daac1aef25b699d05cafcb38a890480b5a5a323cb466bcafa6d4ab48a63f5ff75cdcee8fc38f31afdd89db6c13664bd53281462b937500ad0ad24110b0170eae07c6f72ed5d60f4e8034b91fd30f99d69455596129ed7abc77c58df923474c68c7804eae38a3497ac1e3ab9121d23d80a5ca2c57a3f9f042b532aa89c23d667906eba21345a59211d03428cb8ec6b694e4fcbc0f8acca765e2520f0680f0783bb2a25ee8f1f6b5d0e1512b08bbc3a1530318161f8a00ab39af5eba06085293f8b3b42267bb0a146a63d8100153ed66c7e16de6eaa423896ad2990a69d1cd48b05e356f9f81d1e82716aeb2a73c0b200db3d6b27c2712a07c28232dabe585ccd0214d8fd73f386587fd93d42a57e2866cce503c15d4a49c08ca33d91c3080c0a0267c44d4ace08a9a78146df2b70d66c2cc6444a27d80258fb6f11c336ea7292065c60b82dbbad933c8bed7943bb646b2af4b2a209d2c8faf39bee73a823dfa68b001f694e2947d4aee8350f75a466c6c6fb6c2a05b1516fc00f5440455b043b126881039f92a6be6648aaab387eb5baa70d5b98f06ee2057b062b15536888cc82c38430342c188eaa241f08ce688f43c0e0d38a6abdb929d2c2fbae271ce5c3a332346c48bb0ad31664ab7e4728d88eb45bd20cacd4f995ccacb7062c2080adad565f34ed44e1513d559030196719864768e9279572d3bf5e16648270f242c89aab03cb7c6fc88c9e52e8a9b83386000534d2ef1c9426b21053b2a399c5a0f1b231279ddbe0fd38aaa47dad0755546e26191314a43a365e667dcf9236b357e3239743c3b9b4c1d459d376abae3c2fc8886966cb06b831e5b3242942da552577de1d00f2ddfe3aba5926dc82fd3acea72be388ea0544a30f4d4579a7d90641ff93499a347a7833e17592dd54dc5261e1b82d6e2e9ba81ca07721452c249b1ed710fbbd830b5752752a748b4754f74b43e5fe5c13ad78032cd8ba5b743c36439a216afbfa2f93439f6ea9220865549d6c5452d6d76698678dc5030f1698ff9f8b01aafcdce8666c21a08540f1bc4a30e0ee1f3ee0ca5d0f44b513d8e6954e15b04e7dd460dcf85f682088f0ef4a38ee125271ec4c808cd9a43e5986691b8c4d6a12962616204e6c8e0d4b31cd785f853c2704cd3f25c2a083436e5640d7458f1f92718856a04c264d37584532ac9df24c1040a4a2583678678d91c8d2dbdc45ade7389ea6590df92029886292b1ee589a71627b04bb9698eadbfac194cb59149e01bda48a90a1ad5e3b4069623531b24942d2087398c49921c7aadb9b8694ffa6a521166577412c6ecd7054e7ebc9651c49a09414e2e569216964a6b468823cb814f073f558d15e2a4d28a449e6dc1b5b405a35813585d278a686030935cc203ca96175d722ea90473729000491aa4695127e8fb2e58358ea60e3767dab83d5658cc68c3a1d185d264b449c468945eb2b11201a6eca26412b658aee416adcccd039a693111dc5838518691c48d13eab4eca2ba9cb15806e3cb60d43118d994a6ce05ecd5ea4299c8f0e980b55ad5e36c6e1104eb9a2706d5b98a354f448709a76a1d276ee82820ab3c4f84d765cb60c2cce3c4585a587fda77dc6b216360922f9ca8982402fb1493709b28920947c0088b1360ee7a2e089b2ad35193f8499aece34cea31136f8e785cb0361e5694d1c74dd2cc94e40e64f40993b468bd413af0a72b79a04723a34598496cea437840fbf0b34667caa44d375702d76351b5459e5655a97655fb44d50e89adc52a23e3e6dbccc44c58d056e65e8b30410e762d8f472c0421ecb1c8689935313757330d465b75b96d1e0b1103cdc926b34216316198a46bf57baeaa1eb60852af220d669a35413b71815096446dc7101d286064c402c08556b0e25e4c2cef5e0c0e7c4b942cac4e99ca64470dc0695ea4856adb5f4f57d7e3e576c2128ca7c48171c6ea670cb9ac4533bb8a1f5f8401ca53c1385e50325e5ac99aa0bc4e34638893e5f42611de326e3243908a49c0a66925cb0bbda45366ca23acd3b859c4e25d7b55b7e170864fd64f4d001dd79567e524a36922d0b0ebb54456e8662dbe5d915853216e40cea9cdcf002f100a55b0f7082d2f79d5b90a494feb7464f3042609d092bb1608c707b3096cee02e3b71c37e244ddf2cdd8c936632c031f99ab2c199d5c13ce94cdf4987fb10e2eb23c7b197d9de86aa6acd547838d02cad74a2523c3c76b74a662929eb5126c8c487e5291cd0c12609488beacf51ea34dd7a40c6629402a48d70a7a001a199b716e3132093e5a564d00474a903e103182e5d1ca9c59a41833ca98bb8cb44de2196d93b40f789d0418c5dcc4e3891b15ca86c33262b706152a92c0c63ce569ca3c0d87c3f15b1ad3941266693a7ccd89263698f387dc7409a5cbea594db1413399a1ffd5b127439f7763282f3ae385620093e92c30ae75e4b2cb550fcaf6db2f3a32f5cc473cb146d3357a3a14061b0e2be5f945f3e4c932e858e2d10a09e8e68844b49c1eeac0ab8c9491f20c35dc923b575186867ecdf359a4f558a8418dfa21cb5819bd609d851acc94d6034bbe33e6aa35834d55dfea4c45ae80cad0b8d241c1dfcc368e5c1aeda7931d66c2243903128ff382e974a08ca81991dec3848a498b0c5289e1cdd18a4929156ae321bf7ec12998602a25513246cbf04cc24d12d4fdbad76828800407f1ebf167830204e94a618b824bb65b5430f2fb08703a90b7e2451626952801ce65fdc071c757cb5b4630beffc54c531890c34c67ad11ca5ac5d3e7bb4e9b11977a356f9656486435c3208a2e875edbe3547778c007dda01fe924b2020e856697cca15639a6f44c55024853e2d24dd9085536aa4596621869c53e42fb893e329aeafa383fe49844edcc37d5b984a6ba0fdbaf8f6168d43a30d62c3774d6b1168600f203ff9043222b0cd60f39c4218e49fc3a6b50614561930475fc6d50977452162a13cf80e98d4b2222cc11890006465c22a09aa965db32d23b865f8eb7b637739455c56106c32b0cd6abe1610e9fcdc0af865fe6195bbf63989bcd2c0d30fee41dc5ec8cd9dc14e9f98fdce2b33049045d26d4b99de8914a79a96398d5e4404c6675bc4316cbe5fc3639c9cc79d858d32ae143429c0f8da7890de251a19a3aa04236762dcc7405ccbb643a4bbb020f01629714949869898232d3d4fd36ce8f1e29948389454b787c1291a8438874fe90317fe89c1f3862615e2eee3dfac4b5b3cbf695b357edb317ce5e3c7be9daece31e9f9e8a36bade0b59d393970898ebf5bb3dad05386b3ad1d79c700066d11a6b2e6acdc00f428c05a5d9753c8e8b4ea6b6a9135dd3b4b66f9fc3798a1f841a4dc1477a7ccaf849ae9b3023d01d21426fa52f18609ed71c7b8d85826d5c0922c8904b5dd41c3b41d5e75e2b08bb3257df8e9a21637cd97b866513bb8e58d4fab688d7937f9b8ac4e68e46b398b44388c0c8d07b384b05d1ca56996815ab6cd624aaa66a0c5507cb596917b5499796490f0509f694bc7a6c548e1e6ac26409e2b3dd6cf4f02c3c5bd732bd6b241389cdbc7c0dcc4d4103e2d0100c50461d65025c098376e8748d0e69994458fd28896126aefab499b8a08e4a470623753d536de825592568f84c13603069301de6e016e3ce8acfbe86794f61df4a8a3d2bc1b73f181664ca4b41729e291b483ee9376ebf66c7d5d143ccf2dc9a5d0f418c6e10bb1ece56e0734006f57076be4199c48e290b0dca15d0227c4aa02309d0489d36bfe0f1fc61a799fc6682d19dad98879a8ff4ac95816072b61fdf4d19efe4f94339281089e3dd8d3754c7bb9b99358ece1306c022021882f440f0c37c75160d23a87a6c614c90dc7da45c2a195db02008009eec964a18e758cda037c042ae38a13006443622397aa84b8e9a2322adfb64bb2687d50519e8531643014b8c3bc8a18cf4a9202e1afdf20a4f6e53718c1585b5e27157b596b04e5dbd7aea09fbd1c7cf9d3b7b15cc1861ad60d2194738e3c93d22ac334f5c3a75f1fc69fbccd5535f37895b2a192e1aae961217171d117a1b8bad35c3b312be253315e29b29d07ccbf0accc388f48df84e4b50cb35e093c2e5898e56a324f8475eec2e553d700e1c2036435294f472979749108ebf14bcbe7bf72e9ec191bf29399f283d11ec7bbd1a1b38e009121ac0be72f9d5d2665327fa86b928076e72a23b2827b70c1b930e0f90582e011e87de08b68dde9a57c61a77c1190a3260990a102602834051113b0dd79b7c05c0c465fa432a40f6a84fdf52069fec7abc1d6b81a5cf8afac06ad8dc1b826245a25d68288c9e302525019a6f99ed10e6551d7cb8d7ab9f170cab353a4385d50aa1392b4632a359b95a41d10a0e57d95a7172b4f6f4c79b648735279aa9d8edfadf2740ea63c9d87569ee9e900cfad75eb8b87b8549df809ca730eb4a70ca1fe8ca0bf7b185ec8a8cafdd4848fa6f2be6a22a08c4454105fa9095062635bb7e6a68d32c7069953432566974a18e78d29b11e5994c26af1904d16cd5891e71166cf5d493d6e831e771fa19d0329f2cebf4f91f78065053028e98022370d93d8b3141709f00a949a197bf9f9f7ef5887762674a85f2a19fe141deae475683faf439dac0e0d48649ab5628597616eb290d5a18bbfb50e75f6d3a10f445b999f50a2572e9fbf740db4a86deeabcb4e3cc01dcd26d25595de681e1e4dea6b65130662357505149fba5f62d50acee2b1145158ca03946d40cb6a8dad427cba39222efc691639d7c17b464da19b16e82f43c755419d54ca71845c14ccc6b43cdfd789fedfcb65679e1dd7cd1169d1f1654e09b9a113616dcc1d89730e203c983b82ee108a89f13dce1262221106ab2066fffb891327a0a02e9d6c09555405cb4a4ac2e0200e6ecceb846752313800919a2383a9a31e218b9a8e2f8f7ad8997b6583ccf75ae6bb3d767a3c5915d4bb38d40c7db63faba3922d13f9adcf06f8379ad54dbd16d7225526043abe26c6fb57506896b576ba67c420a69d3499940ccc9d9352c6e36d9de8ee803b5dafa9c3a0707a3dc65dbc5d8da226dee75aa19b6a93f9f1f3456b817e7cae056cc462101741f8b8d4cff94c48f93cde3e6a5286ebd223e28f4f7a1e90b393e444793ba16e124f7739b089a99502eb26602bacedf1ab13527a4418778ba2f174cd690672ebb43c38344539b6418b7bbcd717171deeb45958f50876b9ef087695657c93e28e833cdc11db01cb5ffb0a0a4703a6fb7822e0f4b58b8689ab62e31096e4bb449b1b78468c8511334cb3e6581b9413c71ad090180e75f68536ad0d6a38d6c65c606d98873ccbc18c86630de6026b00312ef12c364b1d6b8378560b3e06ea4c61cafe9ee564068067b9c8fc904ffeb6a60d83c81c111c8c076c1bac5c686dc8ea59035254bfb4f5b2cd22cf6066504a3d699856d247d01080d9b490268367d3e620710e52899fe920abdbf785d7934e0cfad4b71c1250df028ef0ad96dcbac8b4949f6b295fb594af5aca572d95dc529a6830d7243d3c756b923ed81a1113cbf9f63337fbb4b20f8698968aa242531fa69ea29603c5e35e7ef2c972e24598c0f1a46008f35289836a8baf8be590087405c8d4e19518156e1ee7c76e46e176d451ae30b93a941cc6a25c9d1ea382b8f2640c0d0993fe42d4c61a9e1f7ba4bcc4e24307ac1584cc00b0961746028930abf9ea852609931a8c51165be5aa403c9994af114f8eeb281859c3bc10cbd4b0f9801a82d8a5723b28aee15462c70a8989f50f40ac9f102b150c1ebfcbf256e2714df3b8e69b5ecbf00b768a943203a552b3f1ea465c196b83d8787b238918909621884de499657314178d47a1a716ed42d1eef4a24159d506f9a2f1eceb0619e4cbc7d80159cbc38ac0da206b794811c054cb10e86540c8838a99b3b3ea1a6c81f229be7d6988256608b3ca292a6a3c54bad6cea348fd8ea55b488eb1629295f4d2ca897975c6a92ccf381d3fbe8fc3e6854505bdb0b868e6efeee0fbcf786e028fe766ec5be7a19dc64d38ffcb4c65d36b814b9ba3aa2021e5a97312a841cee5040928b71cdf0fd6cf39bebfe23457494493830241a914903e64f1a29eef0cd09d8a9f16d15f6216c74b192c0b52ed93ccf663eee56b0c256d9df3706738a9738c205c7742f72a6b0d8733d1525182e19a855614b470dff7cd11d9cc52e493a40daa21c9b640d51b659c051a21ba81dbd74de003ba2bd9ed57fe6a25db1c4537921697cee5d0d55c1fc311283c6e1c37894bfb9693ada251bc54b1125d0959cbdb404b2675731351863e4a7accc5c36b2b41e832f41a93047c1645a44599d509d65808336fb9a0d1a5cc5a7342cfe13025c7b360bd8047d23b93f2e6e9588e898b3b71f1632e8d54d13ad1e382934f2856273a160a9072f5471588be94e2e2a4e72355a20f2572a2cb3b04e8e0c8300d8f0c48b7541accea73fa6c9774e2cf0e89e46742882bc32939cd6c8424aa25a32469266963178c1d1b5177181455215035ee77688d84ac551530aea5b765392900d499cac5eec5c77d39f54a256385ae60357a262920c1f5d6f46c792b23d24e8e1cb747b8b6e050f7019c59e45bdcb6db7eb0e2f8769f7b4ff799edb9b6ad17af47c7b2b2ce1bd480bfc361d99cad8c1e785b69fa10595c8041b289d6843a7c23c7a8f4ac1687c782989c1bc310ce8cf6993288fb33631018157a6bcc5d168e60e7c2a08b07e4a6a425f9bade86c7f12b95212086256123e2d14dae4a95272514a8bc7a82b43bbecfc2e40be3926b2832e08901220be8e697be24f942d6badb734276800a17d316a123b5f834413fbb5c6079d145d60d0c662e05d5a8ceacb8dcc670e88ca27a689d4b4451234f955a847b38a246047042910d1a200bf8b4d0f12d71e3f8361319fb039046a4599c285d7c82742b4c3ec3a266e8f54400522f85c8b8e123dd09a7e205c3406a30984379a953b6e4aca474b5d08d27581d839b35a754726628ed964a90d521a139920729c130ac35f1425910fb8d6ca2d3e4e42a4344fb300fe8d13e1891362dd7ec93417ac4ca96050d6850b7e5f929c3ab0f1ac361582a85f8d12b957af811954a517dd05006dc1a6d199c0ccc9a08079bbe34b9b24efb47a3f43ac3038632b75c4310ddc93a5a49fda58fccf4e0399e152f50d939b92a9c7615976808ccacaa9b6b1e5b7f34d8a8ea65adac1da9ccc37f7d24dd9055eb12bce7884e0cef56f58bf3478e6ac79b9585635a599b5f3cae552a15fc9d5f3cbebc7062413b525ed400067e8f6b10731cc395ca09f575fc996ea5b2609dd0e6172a17e61716ad45ad525eb08e34e74e588bf87f7ed13a8a1f0b0056f6e72ac7b4ca314cd7148c06305a5903880bf3c78f581559caf105eb88b670e49875742ab82fb1a95499021fb2b00b0b474f006dc7169a71de9824ad3cb7b0f88c3e1a3546a6c1cc51cdc9da65543fe79ceeb0b530e0a7bdb0e9b3abb83a39d9c3c2ea04a2d09bf8efc2f8314011cc9b841bc7ca269841dc98af98a429ada2d601ad22cf457b28318e7c0c9cee4702443946b572f612583f5ef435c7f75c3480bce8bc3cb48b2690172da3273c625366391119a456afbda4e332945eb5c9da8479e4a1dd93da48791ac68c26553e7ea9d2f15b96ad13dd89c0246ac7a544563f624a519a866b392659a16d901e220cfcf36e6c587b1089c52a9fa34613e8f3892e63e7548e395911b39a85f288de0ac2ee5cb3c39aab3144815532183789d6c8269a41c473ab7c385cc9f8d903cbad453c30d7742f9a5335edca9017d7bc572ae9f17c704e7a22d4f12e23c8c4314e0ec2ee692010bddfe8a435e6490f35a08e55580936d4b5e60e0531ff5b58d9638ce4e718090d6ad1f5cf65944ba1b9bc2f2b280cd0dddd7dbabb47bb93ddcd2172b2bbbd89eef69d15e68f7537cf75b78228324265d278a777e24e5715a8b686c3de58cffb30e993ddd89dd28d171039f6528f7689fd5b8efad66467e1d8e6bec7198e65d78bc09e77c92033fed772e3bf4d99d562ccc5e9f04aaeaf2fe2246be033b24e99253ce133b2015f831e231728b3b091c82a65a94be76b10408ac81352989c4985c913893079822c3fbc309115d3891e576baa50892b34316d93be67b12af03be8c18feaebacc75b598544265da6ba7cfe4ba7946e0c87d76a1ebd9c63bfd638fbed2767d4559bb3d3593f657b7225070526a5694c9a1f9b49069046678924a67a79343249fd2cb94c78c3244f51e9d3e642a9345399a1f8bb4a4e17cc033be39cbf4c9494c9b4c3522a72aa1b444943d91fd50149faa3ba4662215f9d798ac49d57b5891355cf8c12773ada2419aee55857c260cd735918bf097165347dd228fd955e1c1b912bc423974ba5b883f4d90d10c6deac3ea738ca1c91d5e170122bc49c0b9d360470a5859c264f954a93803db2893c555d1f910b263106c3e19a5904e85b8e6ac8c1922eb9b5aac72a01e6b9a6941cf614c9a1137b7fd94f6495aa3395b4a1672a49b7e067dc2f331522a9d6f511b12d542eb4436c0be513956e000714143f37e68fc42b06bff5a28d9f1514689f244cde91b2a29bca8ace12f669b5437a075d95c98edf18733c846b9c16e9817618f4635f0ff6c30eb4160eae56e32119d82e62e0eef880ebc5aa26cfcb1e6a17e24b36694fb2c957b0466aa3b64d2e82c5b9b80806e709d324ebbf550f067ebfcbb1fba2f032f70705c6656c1374f7ed2c44048218d14c370a7a07918c53ba542975d5a550e65c26be36b120e5e15b60362e4879a6e27969c271824f7b84730152eb954a767af58f7640f77b4b937d79d172f2bde944d558c9a4bd39488c88ce88744db37a402b649c2bc6f1005fac4ff285b439c8fa98f8905d82ae97b14faa3315693e6ed07572e1dfbf48eb44d935f468498fba8eefebd508976dbb7dc1dc6419e38103dc41ef579047cff8b62fe40274625f64d9f9e303ad3575a011b754d201d19c2c3336eb2e4cb6ee35280edb6d955e20d71ed06e53c5c5c42c83c5c4e594afa2e35a9e8e659948ae29493e90bfe49a92e703f98b543e41af913330395d34c9f26fd3cbcac88c26047c7c1554aecb3b1169a5ddef2e61e7e85577ffb94362e8653b3f419c88f4fd18a0b0ef5b53edf97cdf4738eed71d357793857aa512cf9a0cb20f9627794127cb63832cd1c923b26c5d0dd66382cf0019925fc3605d37c9b285e29bae9065ebb4947374cd7220040a9e0ec8b225bb993e419655bf6e90650bf88faee2c2f8f2ef64cb66e1885cac58508b15c0382dc8be80e7748de3782cd738b28807718dca3cde6fb1b8bcd2b28982ac6a5b8ef22c5fe4401f525be8297eed801c29e71fc08e0ac7043f8e33596cea2bf81c8beda7c775f9a84ca12896433306c87392def48388e92432936a7a23e2174e39a39ec375b2a93ba1e7cc753cd7655cafea22ec337d44f4ed9f144f5455aeb4d8445f8d08973cba96e7d1d340d2a38adcb5cc630e03b236c6b8b2db640eb5acd0a66b64857263f1a8492ed2cda813ace3227ce87075e6b86b3904ab7d21935b737c160a7d44d6551eec02444b360ed4ddd98d3246d6916d539914516e015e604e2b2d1d7834c3105d08c516688ff264231078551184af91b85ed4f5a2c85bf11958bf565a3db292632a9e975c400232554cc0741335dd128c5b0227b671b1303d4d0a059be8625c6e47cd27658b9a64234e00f328ef4ecd36662a44fa0dbf50b4db87b3a63c4b07301f883b6b6d69257e3eb35050b6c845d22b952ecadd3c32909fd95a80b13a289a09b5c9663c223688e4b3e6c824dd6410ae1558566b7962fbbc1bf4b9b8cccf6e7802775d56c8a6c7abd1c82417cc6ab474011dcccbeaab9c2d94b99d457d428f9ff1d6f0490bf754f4d8a24e36f2a9a7b04920363b422e920d7cab2ba78264f3cdf91e5fd5c966f2724a75c5724626d9b01e638eebf176519e8e4cca65bb30923b9e1b0f10ecffedf0a143da1ffb5e93f188695799d314da5ae5a85559b0caff4d3ba4851003c3dded2312abeb71eba9e8bf698720f574d01b845ebb2334a3696ae79c265b098255a29de74d4b73b8ab7922d29c56cbf33d47b0c852d9ae75bc488b827ed8645a13dd5c459a22c145bf85a1263a4cbb78fe5a1cadb5823ea0e39000282e9c3f7df6d2f259ade5f94c456b611008cdf542d6144138c0ebfb998244c81810703839b782efe5eef3609e7a14af1584c4a3ce521a3474d92cea6117ddac1e2d57ca0b242884ea05a1707c0574944485402db562a0c08e917e2198ec36bb1bb84c411e277e71a961006d134ab0ca2271a781e13c53613b419a85606a6f59212b93567125a434b643d65290f3a4535c8f7ed4837e55600ba45b08d665dd40811c21bd4210df7966a0408e12fb00dd19bfae986efa0ef20f46ea1d217a51f5f0612ce0a9c80ac2f66137684687591806e19ccb8067439cbd2e795c8964aacf32c269a5c6275f9bc4974467a95e72c276546f0028071c8f5f3d9f8c5823fbca68f2cefa458f7b2d8fb96a642201da7fd767d9ac5ed3d6bcc8c347dc6675ad15c831d3eafbbea61c9b6a41a8c15887781ef0b96e8ccc656b1ae36b5e18702811336346c41fe1c8755c17b588e36b1de6f75a7d5f5b77428e2e3af591dc23ddf4a28b204b59c19d3eb05b197fbacffa0c9d243d8e577bc60f3c63fa5579a105cf1514022c3331993822eddcd6fd4ab237973cf4a68e5cc7dc4b850c86ac15d1b6fc96378e42ca87c3b5d4a9c045282009adfffb31af643c6d8215eb3445d2f3747344b2e991aaeda403d809478eacf0654916bf17187b72925e8e06c6f123a659cb12678d35b07ab89108a2c754e8669eba56da99935e66c6d0663a3ec6ac67f203ea8b99670733c5c4ab099954ced6b58bb58ddc23a6eb243436b2e481a6f4a22bfd908db5b1f28272816e36fb61081a12953c599d38d330fe48fa35bab9ca06f250079eedb0ed88f9f117ea16b02252467c2277e69138d25d3bae0447347e67493dd48bbec8f0f9bed4f7107051a96444f2cb2499945536c0e310ba3e8b01930873559d2dc2e75166ae8d1f49454f870ede78c7c7fd80a8fec43b9f73f340548552da379dc4daa5bc163f5d5f39d94f65a4af1e05edc3f4ae5c734ff66beeecace9d7ddeca3a0eeec7ca39641e68fe25736b2d650da027d3a96922c0100f9712dfa99270ad323379e9c5031025d15604f4578b626aa3ac40ed6390bab172cd5f519df25673287640bde8c57defc91e8b82c4aa987f26f991e7ef2f0ece136b94ceb9977a1cfa63e9dbc96713976daa84ebc5cb67a41cf489d795b218bfabea08c38d0a1724e400591b35abc4711cb9810bffb5cd072f2a8f3a6cc2e2b2e3357055a7c551e1f08ab8604b355cb998a5f91e7e955e9c89c2c43808a9034c8ef988c242829a9941fb99cf8bfb91c7b984b0b7a2a39da9bbe2446295b2a57c74f0c1127f6b913bba9ade5fcd3d3a854d25782c0670ec7e070a89ec28fb95a3a458a9f8732fb30ea9181e5129811999b4d2762f16a6e1503ea865c15a15742e6acd6305eb14355e515090348249a87d9b500338e80b7fbc9d979c30111aa534af9926ee9b3a70d41ca66959b0429ece33313697a95cfea555db964f62239b88469a6e3ad5cf3533fb97efc78b54bf9ec69101475bf417cb3d69fa5cc88888b6d398a876edc1e452f132fb9d88055b7c070325c6a974aa26e37864351d7fff88f63cb496f984b2ecacfa2cb172e922da8abe4924980fc1994679c6d08c3342d37e0ac664a726964e1160751b521503dac41227c32cf6d464aa585280349acd9162a44af4b28755caa818e7f975456e95a77950d226d539fcd7a8a16a6ba3d4e34dd9cd5477a3524ba9ed95f1c198ce83af270cad5a7b36bb2fb4b0ea58aa1b4dc83ded2d8dcd4a95ed56959277a153ee6f5f8ecb7fe257dd6d0f55966262f091faed36ae3703bff625772e89435d4bb58a018d0b9f632f2b9b1703443f9a9f80e25c4a81760e3b14d443cb0676733591ecb1fe28fa5067a8e4d44468dd107e31c6371662e5d321809092fac121ba9c7de66a01d0d90d5a592316e174d5305f2c401e80381fa00c86e299dc0d443c04a33304b7e8ca0af9d596306eb351ce21324ab6c802f4443ffe97a15bb049b38e99665a27fa97418b807fe707cd85ac9c14c2b5e4adf90942de9515d570ff6f352c9f028a0e653d01290a38f1141cf1a827888c424570c21cf4a9e1b336b526d743e7906f95cacfe323272dc405c98afa49ccf10f555ba294d2999f98c17f51cd1ecb0b07a8e64131e85d8d3f8d67375339ede29232b0b7759ea62723e5a0eba4cde7764e1a9a6f078bb9ad402660ff2d243351cd5d2e77ae966d7e94d78f7492a94dcdd646ac53a792a48538c06420bf2903071247f2074d0fca7b0f9114582477582d2b0054c0c190b0e7eca25a6f826860870401438fecb57401d2898365888189180fb936e62cfa0fbbc5c57571617b25d3d22227dae97ae10919c61a01111d615b59a407d08f44396c2ae13612de3b2c4c5c065b40f41d5fdb4438465dbcb674f5f3d7bcd3e7fe9dad9ab974e5d58b6cf5cb62f5dbe663fbe7cd6be7cd57ee2f2e3f6d7cf5fb8603f7ad63e77feead933f42ac9bf643c712d3bd343f95acd1f3d469899b84cc7dd3039d64d7481b4ca06b8dc0fa200ec4d39eeb30679fa70d8a42d4efa3431221f60974bf1037623ce29f2762daaf482143cd62c57b952b3de2d34eb5d69d6bb8dcc75a6badb289512aafc25b0c7ab102b8584bb8fd5ef4eb3fa5d7333b6f6ddf4d87593966bcd936ead89567f336bf53727acfe070be829067b1fb9522ee6aaedfc42d9afa54d502ac526213158e6487e93d84dc76ff67d40252f513fea89a82a88adfaf36bea21fb5c781e224427648e7b5a9ad0243e9821ed9fd3018ffa5d151a99c9b18d4cd12eb163439c0137c659284b6b17f3f91349cc390717310bbc8b3f81de3ba418ca38fac5d6a40c44408ce32a6b4dde4ec92b0a004ef7508afc5124f568c5971aa4b050878362cacf10b914b72f8a1eb1a156d0a89170443faace5588ada630093d5dd60d1ea0e3bbf1742fbefd91b9d387f6ac404cf8d898bcb457cc38e70d330b249f135419f763b8389ff2869bc97686adf4dbc83b34b7928589675b2dd6dc1fa504c9623cdfed81d9edadb1c7f099f509619847300eaea014b20bce20e88b03d09105cc5273715ae7c419e58d9934c355e6f69b2c7c00d50a2a4f6c3147a6595ae87e1a41c717ccc681e5ea9604576f04525d6d73141cef7ff82d923937e8fe7f739ba422b7fc4f1c977bfef3c78e645e4708feb074feb04be7d91761a4d91218f3f3c7cc4cab46e3cfcd93be94fe4a153fe8d9a605796f49a8c79e38f133779770a136e0b268668e46f1da09f1d5c326f0ad967d5a745381e66cca7eecd87134f1966e42b44b9a0898e08d1439adf4669f344cba32bd277f6cb9469add9dc9cf3ea1dec3a1aedec999636b8c0bbdc662c3ec9a13b699a0b6c1c75c3ac7a445a445ba68e775e2d7b03a5e94210a5a1b7aa93fd64b9513c79569d9a37e2dd764c3a181ce2e9bb4678e46464884320f09035b304f1a6a3ab98312fe16e6716d6de26dd8e2199a6e0e87c69a559c38366334c9fe5833d3bb02b499543a36f933d50190c37f665887ccfa934f3e79b87198ac1c70dff5225d39c0beeb7a21d4d8beeb4621d0c4beeb8542b0a27dd7d5e252c7f75daf4d03cbefbb3e510836beef7a661a94eacc0c85950a592eae72c12eede5e25a8fefd29edd17ccf6bd48913a5f26570a61733bba4f1582e476744f1782acf8417355955421a77eab5ddfc7325642bc1c52b044caa44159b03ccae8a95289d54f35864336be3caa983fbbf853b4ae10ef06ede7862ae73862388cfd492459c78f2667162dd4d235532bd61b55a51ae3a9bd8e2bddda7a1c7f458e1819bb9ac4c61c2de32fc4f1e9a45fa55c4e5262be91f167c7e32f009f8c720bbb09f131cde3cbed4fc44894d19dcca35421d7c6d3e3a9984a5faeaea907bde43426993851916f60a11a58d7c958d31bba8e6f83e8e9b56f034d0853af66e274539678a59aaedca0d252f1a7b3f1921895f254d503b6aae07aa39a222d312b3b4332d3bc897b833cab9dcbf887d36b6eb0c9aa499b0aa7ad9a7341ee5e2cca9fa3f2e798fca994e5ef89aa7281a0cb7d118dd5621f1fb12eb65d98efe09a1e2e07cbf0329a92c4a369cdb9549461a964707ac90865b44942ea118fea3a71963caa6b860356996301c341a3278ba16da2ebe6ac5e8544dfe3ca9d3e36bd5c3cd53543ce7a5d6d65a0e9b31cd24cc2a9fe24d7340d8c5f7dd6088743fd716938e8e6ac3712b39413864c014da91ef1ce4cab514f9f97c45fcd9d3778463ae33b6fe6fc025d8ddbfe6a9d3508a7e727de369aab9ce4e6986571e228ae5a41faa360c3a2f9212cb62142a729f0c9fb683c8b5ce88a0bc71d54c84b053a7745ab084f68c63b8fca1ef128af870df417d7a7b8f2f5b571c5df9f20ef04e99b66ed6bf57e837aca318167f53a4ec4dcabaced452244dfb6e87f0050fa7252e048274d131e9a1cb354fabae1d79d069ab63587ce94d57695158ee15b32be6e4cc6623e02f9ccaaa3f6fd669c71b28f93101a6934ca6c7c7e3db386f8789d35c66dbc7219dbf5717c6a833c2d5fdc485bb3ce1b96cb7a306a79d36311f2c7a3b4de205fa39b23f238fc793ac7277f927dbd66a6823d26a0619889cfcc8fb58d30134b377e59f2ea24cc7078b52e1a3394ca5d66084c54649e08d3ac41120da1e8f268c44ba5670c69747f85ce1899ed559a7ffe7b384c5654c69e0c9a9e925fcb32c997e4a8f9aafcf9c69859ffa7f1f355b4876eb3725a30d1be5f1a9f281d2f9b66f200334848f43656930b7f5d038a3532096a1d165a22c303ff03cafeead23796be11efd354bf41ebac51fd2a6529146372847f35de41f92a11f41bd023dfa0aa527f8a3e2ecdf4e5f3648f96cdce9a7f6a0860b04cc182e5964c9821321b449c657788b2fea0e47e6e02180261d8890ea382118fc1542460c85dc91c1280945df355b90b4929fdc6706840760295cba0ecb3ccb0085213423e060ba8cb38a58c8f2d24cb4a2d8f3bbe3fd8c4d209142a27943ea387ffac5e3d35f73f6c67ee9927fbe5f2e9f21cfc9c398a7f8f63e01c06ce6160fedcb927fbe5856308b670ec0cfe3d37f764bf720e52e6cbe5d373f87306fe22d87ce538a49c2e63e0dcd9734ff617cae5cadc93fd33c720cfb9139872eecc69089c39878173e7ce347e5f097b72ce2acf9d80a21f3d06c594659947b198857358cc62b971e84b8789cb1e7872a9c9401ab5584e1c75587632ac96039c6693f544f4a83c5c11d179795e6041fe2cc28f3cd49678a1c7f3cd614164d4739a8c3a32a5db8fc4e351e2b78672921ca18bfdd5c427e970f95a951239dc13de33ecf1ab17d4599b2e56223909afb90e6fb330e847fe609989f39cb3f0b16b172f68ca3ec105d83880b76098ab790954d4eff5421645682a7271d6f5d083d5d7e5224d92fcd8c0951a2749c0abe0f8989e30744d2f7a649a999b5d065a83b375d9d865325321d2e91a99a9e0b9fa7a5d974d7ebae38411133a51e1b9a68a68907afe0e007c636c7ce3118fd2a918d13bfb74df5bc3fb90a237c730d0681493a7a467bddca875193e672b2915a48294d62b8d3cb1783136d34e3ad1ddd069b7d577d463beaf2e1aeb7894439f52f258c3cc637196082e04eb2c3ced80f4182bd9e98be02a431faa3ad1d986602177fcab4c2e5626d781b0319afd485104bdc7c23576caef759c87222657bc2eddfef57d7f191d956b4e34e04d0d683a07a5e1d715df1968ea7a6914b31cfcb2508b2f53c71f573c7ca4ff3c571f5a2b08bb9782afa9fb629abcbfa3f941d0d378203deb693c4d0f7a8c6b301f89cee3e5302d648e7b99fb83e43d4e2d948de56a5133e8c10f73ba3e8b22cd13acbb0c710fcdbf0b0feea6a61c6278d112bdd1b2e4ce25d123e6b3265ebffcff73f7efcd6ddbdca328fc552c4e86431cc3aa6427694305d5e4daa48d734f93d4c7e38125d8462d810a08d9712c7df777b070272927799efddb7bbfe70f5b2008020b0bb78575fdd1e606cde5924de842234ccfbcea12a2b7fd606db73b165f36a966758633595dd6c1db1ed844fd58a577bb2a95d5e53b30abca6a45a5fac1aaee7c07b986ddc8c82f07ffef4e79581cd09d6f87e897d3b09f1fb15809e06078d857d587c5c2d5158586664131d1dc08e61dc4e718b604b86a8eac4c9cd0312861f68dcf347d85dbf5844e9e17599581f47970b85a65af5c1ae937c23c0df59b972e8d105aad8a266b36628fa8d56ae3db1e2122cf21b2bdb942fa70884e4fcf6ab659553f4f521a65bf1ab84159e9432342ae532a74d9704bb58d8d7ba2793c96d9942aba93f50829f4dd31193cc3912f06f80e42796eecf2744986fce5d92bc8af7df742acc6c8076f5067d48038ce88edb7bbc6dba26a64eff3ee538d6c9377c7f11b6cb86dcb6cb8dbcc5ead86bfabb507ae3071754ca4742b539786efa467c3b82d6cebf5a6561471c23043ab957f9ee8e73c2f66acaf58ad0a86c627b00e7a83b298d8949ef1685d2864b10fda91ce51f0034763140a95a0231fe560509c42256d121c637640136ac3c46e879af77a6e4ee7799695a22c14a1292d83653307a81b7c337485209a7002d7e730548682a279de1b188dcfacd40063394e3bf2f21d080e44470705f8f8f06bf902167d3ae3ed94089339d16e4d545adb4ab0e122587aee613a5db32cbac79cb238423e28ec9b52b01e44350564e9f96f5cf700432b59267a77f0fe47ac76aaa4536ef692a8abc7cc682a1f0165f15ed2c9399310953bc9e950940020c7fe6c2a2d6d82c5f71c201ae545676410e86bac1006bd537f33efd840230d1c115b6704e7e4badd0d6f6aa6dce60cc5c05cb566aae10e38f506099bc8f504a42f4ba9e90cebafb3c38d330d8e48d11ad7aca1b2069dc33cf256cad07a8df00ded32b19c33d3aae8878735c2d7a7cc6ad5b4e190d078e3ad87608d6b552d60649380d7ad7960a56fc677b81e95f55a6faaf152d96721aeb9df56ddcc4d2a4be3ebbaa8b9304d00d0c28cbed79983b0df6692b1be9d6563637a5d66277456b3ac6446b719b491243273a2507dd7f7824138eec8d488c5d6cbca551b5c6f5faf35d2d39b8db3b68d2f3f2eef227eb0b5599d5a311625eb1f5d4aaac905d090e8737df1a2335bf13a82ec6b02993da8fb71937a5f4b73b0b4bea37c47c63e158adac646825c30a78667d036b6bfa540b80129b94e412d25b619a6fbc6fa4156b3199b96e94ee304c861bb819c7103d4320125dafc5e584c98f7850a9fa03c072a2bd0c30ac838ffe9b9fdd45661a7d8052b949b27d242134e7e8142101f22c7059c21fac8824d153e5bad6c429706effaf044e0582cfd3b786ebe0e4af6f5f278ce61af961a3b4c5f43f5038ab5ecda279edd56d148b504c8f6cdf83374d770e2042adb05e34993a13c8f3f00ecc40510c26efa593c3b25fbe69482bea659a4d76b968ac6e77dcc06dbd89fd5ea7b3df07195fd58f63c7e7b84c83cb7f8ed01b2234d5268c29b0fb869618760a4607bec5eb366c589d54ac513c30fb6d24b288692a835c8b30a418c4cd1cc1c0186eb59543a60eee6dd02437522d4121b4c7cf6988d66b3ca73d6075dcfc78e874c278a5f787d4810c95a6250535b09fcdf414599168fa77fb31a111f188f1b3c5a428b6bc777b21be95a530285eaa039c2f120bdcebabf07b254713b5836a86d62fc2da875a1bcea2c3203e23569f5080630dfb1e46ea4e9ae6aa1dfd41a78053c3f2b1ba26430a2f785634dd3ed6da40eb25bd9b638a0879af28692820c46e23e8b15af28694ff45b9afc11876ebf82b4bbe1f780ca2d923c4211a6792e5dbec5fd3bf75a1f7f10d0ddc09065dbfa144036183836b0b31876e8ee01b520e8ddd0b3ab756e1d6a061d9cc2344d3b9b4623b7d2562b53c6b26cc0b64ce7a0b52b614fee08ee301aaf9837d2f55b51378bb229a38a0c2edce99e9cd95d87ba9f8edf5902f1f9fda441594023c114c42ad59330fdb06a9cefd89d47512f9bbdd93552ccd4cc4718f14eaf18fe4edc2c6c8918f71008890f06876b45c4daeef020d6c9408eabd69b48008b1b3d6d620bc7a4c3e919db3e5322431c330b85a6d698db8ffd362ac2e1137f1f59b5badda663ab11f6e8ea11d9b90fc9d86e32bd62b1afca72ab47667fdf3cea9a3630f3359ab9e1185803ab59a81d137a6f8bcef829e832ee1cd39a015b914a7acc27e0016fcb65eed467fc446d4de8c27d3899f1c5ce82aa339392cb1933415a7720c6e2a29a01f3bc2b6fe784cf1493b57d6775a6ec930f2db735ade65cd0183213d874e7984ece4f25e8ba9ef0d96ca75ad0095757e60100399955d574c7c48c35695fa6126ae784cef9cca66bfe8d85d40e9dfebbac95cd5092a9c9997bb89ad9825671d53c5c1a749cceae16673bfae0b3c94a722694e9ef5925f9b74a283aeb7879c1a4e2133adb82523b747ab1f3d5a62bc94fb9d8f9bac5e7f49445a89931a598dca975a7f4a306818b53dbe33995e74cee303175c939f749604f6e55174cc2b83a77d221479df1c9b96075bdb5a05ca81d8806b2b5a0a2aad9ce706b6162681ac5cb7acbc304432cd4567d461731a8fa2e67e182a41b885a497ecef436b03c3d0b60a4d9011613ad71674aeb33aab79538a33a39a9997239ba1313ba881fffadb870cf73ae7447e7dc7f1041a41f2148e516f8f0a362725649939eb24965e441e639f41074b1536486acd083a5e0936aca768ef994fb07a98f09fda4ea9d85c6ea7ceb6287ce1667f498293ed9bad839a3e214c234eff029ab4e4da8a7ad8b9d3955676c4ecdd4b9006dee1d060afb5b7a46c13cba32493f8de2a7abadcb4a4efd14ba941c66d0bc9ab2adaff399a8cbaf332eceb7beda05ff7dc141d0b0324a3b0b868f18ea9632a5921668a9a413b5a48a6dd9273991d5cc3d45c9faacbab4497045ebd2573f22dcf82918419c56fef2cbe5e565ff720fb4d987f7eeddfbe5ab71d3e479ff5fe7b352ef511986e48c425c4c9d0486e12659c07f0bcba7fd171a9edf7e118e3519c1a4e8f1733165e00e535675fd0a46fd07c512c3efc97ce6ac0f487826d989fb2cf33999a9c00eeb19e47c0f97030d742d27baa4f9801afe98f1cdf8c03cfcd7e00fbc54e511231b613a53f359861f7496d81d0c06bfd417a759a44b1af3631d23561771ccd39b6a81c27a31df501a46799faa33f8b7ff226b72676fec484415bd4c6f37561f75b5bab9024d718c9f0177fba6ae103078d7c3c5f8a978e58df6d5f8e6ea4b636afc94e1e75d463c891708cb2bdd7ff760b1c873f8e9b3af6cf241d4f484bda82674f6d4d61044145eabe6c6f21d8e9b5d3c3684d6255b377d0c82fe965f7b1fde3eef11f24023d3ab1a64a0e7a5e9339b41d4c8df768aa78c3c65ab55b7029571b48750f46d76bfbe38fd3ddbb694ecab9302052b7fb49dddff05de63459ec6912547c9034a632f262128e12238528de249d0cdb8f87a1d5badbc0d77a0c8dd665495be36e4b900f275466d6e9eef81304f5453f63e08f480db5498ecbf1de59ad0c1448559fd2da1f5af7df83c71d0d8040e896aee0a07d947767cce55b6cd0e497669d34abfd8afbe99dcb94e282c609a7e64e49a0a3e0752808969f98d15d9039791e1907e22a619c2beac5110e795d8fcc5735724fe0e08b6cddfbc0371338abc693aa0de075f90387a00b0d6f821a807fd9daa077d70ecf2877a477583010fc0c6fa18671b2b7b850581eca0da28901eeb2ee108bcfe9b25151371a00e8329fa1f795efccdc88dabc2869888500d56405c78fdc5c24a053eb27e3c58e1017714f0237473311890f08812e4360109df2703143d99e3e80b231f5891c5c06608ffd9c8e5d104f9a3f1aeb613e196c94f9acb10fe8b918c1e57525fe2c402d456ccafa5b5b7a64b53f5040ca4b7d87ca1389b6e313191570b05a9a9fe0f9674b38a4ed9744a15b5c93953d43f9a3bc6822e6b060a2bf04f53990b599d4a4d0c4baa986da866ec1c5455d8b9b92fd0d94c3f83b5c0744bf139338ec5b62eaad972ee3ebba440b0c6241ffe047ec2baec293e327abe4f1763fb5beed345b477bd896edb9f20b872a404de342f67975bfb74813f819416361e84a3cde89ff8e68e05012e0bebd319282f2986ec266b79ba48119f86a38111359a56d7831e298683ddbbba4986fa86b27f4f4f8d3cde7d8230f369afbdee0c03f68c70839e8e45c31e05faa797f970cfc866e9692047e76c5ef16f36d05fec5129a84500bf31f408f0d2f8d0f33a8893a96da9fe949d81521d9b761b2f28071720b1d774f05015c3df7e8b99b5c295ef15ac831d1bc168a57b41cb84148a402b4d561434e10d00340cc60488ad1d435510862551a35110d6da010cb553647c49194f2f3405c496e1b15a4b210975838aae0591a3492514174bb6869ad6fca4b07e15f4a72665f4ec75fd1373c48ea04a1e7345952a28c2d02e8fe539265f8d38e1fd9a1fcfb8385d77211bb6722b1525443a1805a158121ec819e3bbab37c44b0fced280b30470ae6bd21b60f799efd31260322f25a158f8974bb2f480e9d1ab4d6f97aef3ddd5735dcba6eab96e7f63f5cddedf43686dbaef470f54ee9b66a10383a5bd1e6825d1d39b269408cae9ce2cd4a892940a24d7896958b0ac6623d3d73b6e49af56775dd20fe808a4566662d85f3b5a4461e578bb66c47451f00064a629ec493de51032722628e6f3d5caa548d37a2dec5e6bffb56fd426a06d87eaee852f55c240272dd6f2de20c2a1f521a7ca963fa9a60fb571c140c7df5afa820e0743a5cd2dcc53eba30376e8024e2a541e30ac0e03a854395156ab75e66fa7468d27cf95d1a5109819b30bae1a761095dbc1a24deb686acd745ff05a31c164ad8f9190fd5c1ff562626c6d367a8d9364309291a25e8ff579ad89317a6ae9c66ab160d3028de4f63602dc1cc8432cc0c1224885559e3bebeb511754ce17601b30f786d7af99aca1bc2ad06a956ad6d878f160851e0c1754642b695ca8155c11a90aaeb03e5518e10a73e788108ac290540a61de9248dc311289a9cd67649218b8c782fda50a774ea3d807f6da1aea5a4e2c01ba5a19c20ef5279534a18ba75c9c7ea81d850a2ecad8a6b7089b03d75d77c6acbfa07a1380a0f9917c6fe64fb63f9a7a2b05235925b26d86b8d87264b23fb056aba2503753cf28552f6338b3c797be457419d3821d0b36c6705395b8bb9c28a39fa5aac50b76c166efc157ab197d017e488022765906a57a9eb81c982faa92cee583f129390df376aada5e254f5422fdf4a5dd81acbf49fd6c26f0314c8d4dd7bbab5ab1f9d3193dadc1bf660cb1c234013738dd8ceb2a196ed6544a1cd5532a1c6a2905f6fd2d0f0ea3c977a612798fff020b430eea992034a203be002b02d9e3ccfaebd0935d4f31694e0622e3f3a6128a72c1e473715285837b243d2d2afdf93e9264af67ab31f4cfc69aac4b0b7390dce9016565cec13cbf6b65ab6db0b1209f452191a55a054aa4d0cd5901f2e86ba0e8dc9b037168fd7ce9851b0f1d1a819f8868942c199694028760cdb11b59f59aa25a91bbb7e340c3305d9764305ade7fe8805a3a4f9c33f2f06079389ae5793123b3d47013943a39a6b802897eadb7b21a8271d5aaa8e3ad6fae22f5931edc9fc136aec9589cc86a36cbca3f54a1b07bc2bd018add97823d84d5ee3c9e2da52b6ef281dd6a32e0253c83aa6161338cc2afcdb21f415edcc8440fc6ccb662a29694b071e53954ce9a50b9a8755605d568c49807a310539ac28ebbb9332484fcc52223da3cffd33a2412f6fa657ce8c1fc5f287ca4f095c2174aeff1a77aabc2c776abd9b7bf97f6f76bb8cabd08c973f8e6bd22d9bc5ad66c5a5d8a2d482d175baa5a4ece4c9f4d1aaea73a61eebb74f97532e393f3ade9f1cc24acaccc7e639fa04e9b5e2eb6a6929eea8af4afa9672aabc5d6a49a3b69927e1b3d9a42e7ec0a2a3a675760ada413cbc51628dc82800a02396dc1a86c590026d5e26a6bb2d437f35ab12d03a3bd4e5b57137326965b30165b7678e2fbf5677d3c80ed8b9e251674c54c6ac6e80533c8aa2e98b429dd9ae92b64baf4526d9d56cae307cc3bb66655ddc88a5b0f87ce63d53695bc06a7106cfa4a940c273bb46aefd07bbb2b916cd214fb2dad94d1927c67e9d2c6126caf2e3bcbe2c9eeb1630b7a1c65e57ebbb4c79b2dedb0979597edc211466df180d7acfcaa2fda33a658a18f41c87f3e4dd6610bf5b6968e01285f74d6162bbfa8d4a4b0e55423d9767b84f071c1c86355846f70a4aae0eec38a3c169a9ecdf3234d863bbabd39962b22714c1a3c890ed2cfa27067298a6c293ca7f81f56242f806f092c117f8425577445988200f4de37879f74c47afce1fda55ea0c733762497e2235767af25af245757face61938947d02b5de51a0587cd7b86d712df142dd724618ec78d1b1e3a1cd59b4e69e33e621d7f955ec15e3709ef50b24981bed1076ebcc6707b5c70d43e6e1ccf1d4301631d5ff08c0acd91460e4ef1dc1b3a2b9541a42fe3cfced7e600127ed6c67e9b5561fd95e9036234b87fea2db69d95f7a93a181c8ebad1701dd85f8f453c007a962e80671888b1ff1e4d0e47e3a4ffe5a9ea83324ee175d38e559ebf56c531d8ce1c3b0f98f6e5be79b90f2ff71b2f2fcdcb4b7879e95e7e55fe22fbaf42f845f218f99256ce997400cfa91ba5b30c5fe87b8946fa00472ba49e9cb1e972161c3046ef5e56724e676ef1e0472ab18079069335f00d8b20d37c0094077064a2f145d70f5401638b5920eb8cd7b930098423e8a49e07e2702493ae81ce7fa36b7a27d4846b1889077a24304b06e0811e8028efd2e45d425e84ee14db4a53c99a203e4f202c2439d7d0a1ef0367183b835081770550085dc920ae64849ec07273f64de14d9e9f8749a7f1f312c2963c0d74d3f3907cabc881913464d8fd7e6138082a9e886986ff8c7382dc0bff11e71bd916ceaca4c2a45efb5424bd08afdefb8c54a011653c721956c691a69cbca3959ea6bf528219b6fb6d9fa990f7dae43df27960bd9afc18398a7f781c3f38b18acfd84f336a8b219d7ee7d3ad53dc64b660b162993465453469d24a67d29491d4a42923b549524182631f6cfc177c8bc501eb605a644eac135211b7e19bdd71c2fa6d282d93dde03e451c62aa7fb68787981b9649410f060d0bd96d6a4d3687088d38b9dee0d6a6bc3e5e1e43646c8e2d52a725dfce1c2ed738760b531ec8434375ba0dac546bfc1c2c7ff47d10e1a72ecd117ea90ee821e1ebf5377bfd32d4b523daed8f21d6ed7f20eacdff886eb7e97d93d6b4be23f8f59fbf9ed0e5d747e93d655a2d8f67cc6646f791278d7b093d7d176e28f0cfdc06cc7f73f770ffe1a6e77fa3ebcae3e6b5e575747f3967571f165b8dbbd7e3f81606bf1f16f60ee3fe83a431953776dfbe1e6dbc8b3d4eef6536f56111cb2aa577206d2f49f6aa14449820b93c06ed42f3d3ba353eeaba413e49af929034b84e849ee6c1ee5ff1cd6c80b09e3d7a88b6fcbf70377be253ec2b3723f9c425ccbd4da75ef814dcd574e295bfc9cd2b77bbdbf7297d8d83c42b970837bf57d1750fbeb5e9fd281ddd0e5f755f14a116c3e3703faa3a3d9db1f0b39c9c41fd9082da2fcf189b99ff09928680a4b70aef0612e0a322991744cfd824928047b7e8e6ed7bf3eddc6e7471b30f15198c1eaafb1ffd29fe506d6f23bb1d7c54070fd5211e183580bf158988a00f35930ff521ccc5a927853e24451ab70cfc05825d05f75376c774fc98d81ced0f95fa567d0ec68e9a0eb7d75d2ff996e3dd525a9bf34129c92d157921577888597cbddc1a9692fcb5b188575d239fda65d662ccfa743a0512d8491a0a8525ee0d50b9e955dcab5b316f98ad5692152e20c0278539e16cc4bd4323c10a8a5d71efcda8e08c70b45a197f46bee6bfa29a3fa8e26f85930e7863fef0c5a7944ffd45a1942acdf39de1fdf72ae26f21b81927f5e153cf01374c5bd39937a1ee44ee0c2c0b190cfbba5ba01babd7dff4da9e7383bd79ca03b154f7b122af0cddeb3fc0cebf42c408b1a5f7a1f47e67e98811624b5f42e9cbced20927c409db3d9bc25d28bf9aa5c6f12b557c35b35c8f6f8c6688a8e26aede08f386f0971f59a56f7f5beb8b1dec8b142403dbab68385190191868b50621c382f5971065719372f41d892b8b37ba3ba5c6414c05b1764a90a89107252917f80cd1ecf15734b08b34af74ed1d3916383f046ad4c153492515bb78e09e7c27c4237332ff68c33117a3aa637f22a92caa9b5a8f177ae80b0ef602b1637eb2efea322f53d7fef30e11d7a037c0cd60ecfe7f4549f69356b66bed3b46223ef239faa3393f7f5e98c7d8d92109add3ebf92530d99cf9ae8b33cb46c1e6b9d3cb1959c981a2e5dfa359c3117cc3dbf3b935c9cbba797ec94c66f5f6900c11780e4d3079251977e6b6ab4c927621a3dbd5b50113f82eea17d7e0410a64fd1d72623aec0e6b83a4e2aa13e822d817e9a71c11ecde87ce11e9ef957d6200392ae13955c9c51831e458fdff16fd0cf4b3ead2e21f31b68bb43aaaae6d01c9fcd5e859ac00c287aae55b5481e6575ce1e3bf39234cb189884bc7d6f4312f25a75b969b1c64c10af668ab3b9be4fed57df329cbd8a2f37aa191cc1bbc3f14e3d824476b5caac6a75568ad5ca59d5f6a20203e357e39f9611274379fe8f3a6087e322cbb615ea2bc9e7052ad576b6f89a45da55a271db02b795e078f16aa6df7459490b6ffd6cbcf4b88327dbd9c910a644894260a52f67128db29359454147dc2cee6c52d74f210b39f728a1624c51a96f7584aed77108b77fd4065b8fc8f636e48375acda66fdc919950f5431408dfb20ebd7cb63e31da51822fc8f3a5087e41f175fcd1a0f48416871ad2f5d5cb1390cf235b54bec98d66687907659eb1f363f66b052ce2097cf4fe14753973a71ceae4e99b02b0156b4bef8ebdf059514a6b38f358a95a4132873094dac23c90815b112363f29a43860879eab1ecc3bcd217593a16a538b69ef57cc4c68bc1fb0728d2d61bd41735ae1dd817579db7603bdb1de3ccf8e8ec066808bcda59aa0df1d5a35360b104cdf3c6f8743346f9a5fef42afa34337d2ffdf31ce9ac324cfdce9d872ccadfabc6eb8e4cea81095b502fc3af782d4d828d2e659abc549eb79a7969356de52f256de4925e754b5b2059dbb3a21febe38dd010b45ef0c6bd8f45b3530b2d65a90472c4cbca58855f0dfb082917b89a6cb6a351c36545fca86f53f1a29f2e5401d8eba5598404f69ae0a505362493cc6994822364f5de4337f812918b812e8322571aa326397b066d60d5dbcc8fd294bdd14ac56ac7f5c4daf6c8c8dc87780c90e704d848b97320293e1c4ce223596f0eaf041e725c63096042a1b39dfb3d2a8ec19d50f6f4c618cbad9b68c2d272c3a31bb0f62a6dfbd82eeb5feae94d89e766a87ad478c88352bad9e886943421ccf77469f0f5d4b9264385fe16b9d1f749bd6d27aa05e03e4325e4f67a208870cb37e85b1225351a091dae256abac3ad9627dbdbe9f3f9574eeb03f42d77a68acabf2f6a2b3ce2b3f1a67c5b36a6214fccf243b09415104e90dd746c5c6dc51a1f18291c6f7c87b3bf68465a4f93d8f558ff5f83a4f58713ab53ff16a5b795e046759f004811f8c76b6715853332a2767499662b3e47929d3e705adebcb4a4e432682afbe2a7d5839c75be0b3084a343c7d1a5effc2ca708e4433348be8148e1f2f95f21ef74c9facbe07f057ec8307c2ed2b3dd5f7ae35c36d29f83c4bc24d257d80b80d0babb2064fa232cebcdc73c7b4f0e7607048d2f5f2278e26efb4e53b253616e89bb30d907e2aba14f16aa6def339ab966a1c92ce2dc471e7279319a3d27d143fd8cfc270ee87ddc9fa2681a0aec962770a6a6e877101049db760b37cd6edddebd2506484f517925df06a59bbfd2228390f46ccec30bf25074530269b524521e8c52d201957abec56cfa7c619717e2c80f20d564a6a67076e91d92fb72ca9a9b6b7d71db0b42e8b5f05d9a7eaac2fa99856f3d8dc6eefae73f5b88bf00b41b2a323884df25c181fb54e15f656b6fd55e0f35000b85726369baccddbf7e1ed23770d361f4651e513dfbd2f0488a883654524d18c354a47c220541171f05e1cae56427fea7d7d78b576af7f61a6be230e35aa5ccaea959bf30646d3c9a7eda0090357600ed86261a314fa1816283915ba94c11fc74e25f5c9adeb5dad98ee025aadeef4acc98a512fb4c9e15e48fba4b7dcf0fa3c8e32b8e3ec5e8c223d8b15e913cff2a916fa5eccdd7b9504603d380704273d790225a6d5753bc6449efb7e8438accdef5f2754550c9739ac6202c5104c73cbe2e9c9e4a5205213563e168863e25502843ece41a4797a94e80455e271900e75e5358bef3b914d3ba7b3e87e75d191d359f4c3a2f9dc59ec8961361692f4a477e983562b9d51b8f38938f7adf6540cae2ae1ac9d59e365d638308d0a7a4fb662a2304b43b4a2fb247e203dd9d9bc0eedee0db1c2fe65d08589745c3c83a05004a686e83bd57b137d6b53508e037508caa7a24b8b5faace7cac10165dbafd69799f8f13bf8b8fdc4233be717e08ca389420eb1f254ad00787233542c29b6d28f20434864cb079efdc6a705fedec8cd0bfa21007ea103bc7d1d3cc697de853460567586a7b3b14b612de0c2706090f3cd6599e0b502c4a7bd30c4e02d670ddc3d32cfabf79509e9943b86344da7dd0dd4ec7c0d85b44be04a036b0bd78246c20724b2a3eb7bf6f9b24e33761826abcf57bd75b013b17a0983cd7171b37389812eb728f8bada762fc545877904f457c9dc19c50379c211287cc7371c00e0921f4801d423c0e68a7227287d999301ca9fba4d205e58e3245f98e3a844931f2e011a720c0f0f0be1a0f77fc05318a2a135c06c44a690fa3ec8894fd3bf26bed9db499f09cbc6e8c8c8b8f108d840b9390985760462033b6af015a44dff251cb512dd513cfb9381beb2f0fe82151854065665acac0cbb389cd60e216cad29513fa2b7f75d14578fdd805b206b5073625ce7f6508716ddf8cdb592538ac766686c625d7f8a3281fda88115d864bc4be0c78fd90fa0b872f8d124655cd1a16228d9789b5884124c4d40c5232ea69157609258a203674007c11c11c35beb682bfdde67effeb3d8446ac3f656ebc0a848783df3ba1cef326bc4d8b983fcdd20e45c8c121064b66fdc0a6e483c0cc595c912f624d8bbf45e4dbf87a61c6c20e63ec74d7cccae6f05a0fb976da45737164fca5a5f58d9b19052a5d08cf28d85e3c01a096e899f486086f9a6c1f05325e83a37912f7e146501bdf8d5b391b80354a1d0fe1d430be1aa30cd21ba01b262f00bc30c6712d64c76673e4a358e338432f8a30695a9dc4ea868dc06c9026c23c2c66eb117dd4da50da9b4ec7de6484951bfbb869b0dcaaee38c6d2fcd4d270bd46f86f113a43ae21228101020035e924da6a87f369a8cb6a676942c47c650effda56010369bc5a43f57ccede293a5f946df7345bacef5faf568fa9d237d7cb02ad716b9783ba78fd5e2e6bf7b8d65d625f1513d3c4803d526d8d399bb10fedeee8b5d6104ce78ea2e0402472646eada160230bce27398ef603143f90e4553cb388c0f1808007cb68ba81c2abeb9db409fca70025d3b54efc6dbd5ffc2188c74371adeff92e2eedad8d6ffe12e4e01e1eeee1dd5ff1deee21fe24c81f799e3d0aba380d671cf88d25477431c7c88300969121659e176f44b09f8c8b1950ff31cdbc675f55a3fe3cefbd119849fdbee87d12abd51b91e7bfddd7ff87c3dfc91b81b092c47010fa27b29a3f3aa3f2513565c5de2ec24292eb63765249064a47e5f75511b34a3c0c1f644131317db14947314bb598329c39adbc0c675ef929c31928d965876b1c7df0444c7f0cc247c9372990e9bb0d701a95c886c6d506f327af38182b6025701b69f4cf426e556b37c00e6f7f14fa1bcdb7be0fbfd19dfde90e3895db0d3d30af7fb40bd61dcb4ff5618da54c22d451d9c93d863a1c537867d823e4af20440689ef23588aae3034e4b4737677ef0117cb96f285cca48e0caba6813d61ecb7bcdbff7694160f31979153b2066318580953a6289f21bdbb5045c1f9d7d8702d4bcf52ac000b204193e43a44962c85c489dd68d9d4c1b2a42b44201488954dcc35e798d38712b2df9cff9e79d1fc506f0365f3932762baf103abeed8fac64c282f0ce24efa03da3c951cc3e883b7fa8ed650e947d61836eceede83fb811dd78eafa05b9e82e7e382c93ccfce2bf0490e621fa0d12ab95a719dd5fe780c5e539aa0e47925f3bca044df5c51593c17e1525a3c1544a28df7523dd2038430277f88408817dcdf28c61ce606a1a5d3b0a284cbc278fe76ef107e290a8e30251c95d4905c0523ff44eeedba9651734c1d62a40b00142d0ba798b50b6be7f28c4fce0ce3b4d04b7680950d501c9d09a57793a0004e44085132cfa5b42cd7c63a3244d71ac6bc6c79d1ab1cb3b209b6e1bff53e893cb7dbc5b8603014f8ad20cf05710c0758559821a339d6c08539be62489a18802b9bea4f949cfdc5ae562b608ddbd49c29fa17bb02b7ffb6409ebb023652c0e48cca3c1fde372977d5f46e8f74a671ce02c8752fba08015764dd8276c38846f35cd9796e86c00ccc0de380c645a1c8ad786e0ad98f2810a7a5686622d3135121545afb69a744383664372823d1f2806275b85ee3a524d7a0c850f606184e2cfbab69659dcedcc30e009d192519ca415b665e09a351676473460fc68832751a9ce6824e0c8844412786cdcccf57d0a771ad2c25645f32765ef60691a3bb99fc4f65b5919876dceb2de58161211f96a95cd538cbd0580065f21f3cb0ad6152724a43decd47b335e106fb8dd816233aa1978ba67e7b7a3c472e3d64aa8756304d81874932957d5381618e2064827766ceccea1f4dde0373101bc79e273650cf996c7003e73008e0f1259cb20b699928fbac00714d30b70d858ea4df3c5cbbb16b2283fdab94e0b89005ba3ed1bbf98984a37a7206276d9155c20509737d389548836b218fa03b75d0d9530064477188b13c5fc8e24c2288ee4c263a8d1906df32087386a0b7d60793574357ac98cb58779547f174a360587e64acf63538662d74c700b9b8389144a13e55dfeb1c3233c71eafba82286492ef6273c258718821d1c2833fa81dfa0d0622e16f3c5a20466a948ead4abf468513994cc7389b4ff575eb4a9299721fe8f3b3d779855badeeddefbedb99cbdd8b94269b4a7cc46bd80c019bef968b4525f5ddfdea07a935a2c6eff4b659da2b282734da6ae8a6ad26605ff797c7e2299ee7196886f9a08cc830b68fa4d7df9fc982c20cbc92a8225fcd8beb8aec4b43799263099458118393c46be337c76ba3ad284a16144d63914b639250c143655c24ba219bc8a232460b759ed705c3142b84e3d9583042d3f806486fca21a0539e4741645c0cbfcfaca0d8e5636a833dacd7f85cc60c840bce2e0d1fc610eb8e99f05e92eb07335566e65ccff023d35c99d9333fc3fb4cd132b3e44086df9df11355666015ab33a21df47374b8b4788e9e2a38657ae6f1136e7b396e67150c95bd5ec1c87b79c00e519ef77aa0881a44e53230843e4bd8f5de4932c0aff4bf274014bd86ffff4a722e3d166a0868fbc920c23c7cb69caf1967427d8a1fec9b053d659f42d29537d8b135595c9827834993b658330fcd5e968f25364259c78ad369cb8a936c46159b36b97931fb2d2902318f34491505118afc778df54ab3e9322988d6785e5d40f253d28e5e8bfe8df1e8ec9bf6f9d633c23be9c6f79dd4ed1a3ce327729c7923baa08c35f625765439288b27406e0f22483e6f84e4f306483e5b485e79485e05483ee3d7df81e4b381e4b583648df02349fe0d53c71bbf98e18160092669c204d819a2e9eaa5f4dc5971ca84e274f63acde73337d574d24e2975c96b578d69ecbde7f3f2fab5e4732aafdcba7d20c9f5dccbfccbeba620b34c75029a1c30ef6505477647871affcb9a8139e40d55c2fb1faed2f6e506385f47255ad5460e5e7062f514aabe01ded751899fa97a8d9fa527e283ef9d7b98226b4a1475df9ee071dd3a0b5724a0ab51c6e680db5288f85becede6d4c8cb1b0b5e24cb78b5ea5579dee3891a46c189ec9b2318cc19650939a9fab1be8fdb903c9c5dae56dc6a2a19dd4f778257685c5444e1e0140614105a30f96d068d3f03050094649e17aa478ce719a3caa4822a93b25ed30aeb88039515715a2455acd3e6325bd84b518ecc61ffafc44bf240f6c3a4c633ff0cb30d4fed40644029c483605c302643d73371d96af2c8561ccf3f53753cd975e5f63903ba80d9f891d59897ef445121cc5d444993a3102e96a48eee1c4b5cd9bb28dc35a6db99f1a484974e3acdf0321d03c27121924a66fe42eb2a31568958b84a386e0c2461784a142e24a9509e4f9155859e9129aec8003352133962234640d30b55dbdb4e07012b321ba991d55341ccbe190dee573b6c846a9d5f235cedecb87cb6538dd04ce7cf10662e5f17809dbf2684cc562bf8897c2f3bc69cabd056b0ae23ebb9dadebb00f21ad7e4e07024f35cf608998568cb45456454f16a55e9f76884accf3e89b0d4954ba34923752dd33c9fb66a9976d6224d2d5384a7ba161b6d604a06a3e97defe66fbabd8d1e88a23e98c6fa384b5756063d9fa9c6cb035148281af47c846702ea3de3eeed9ca2f1c1f2b03c586271b85ec3e9f8527669ca5a9b225e8f7daac1aa7287ad55d11e988530fc851132fc45af670601fd548fa8357e2a5da0e1203a4bb53002c1f83cdc795e9a641211bc65a9c27c206e16749463db2fc791493d37f9d0c7603705a1d0e20ceb99c9e218bc3f269c2c7d9986811f8c6450a192dbdbfaa6d17b2a6ddc60e34276b5eae9ae1ce88743accc2f0a35796d190dd85b9099dd20931b0e7fef96c9e16f925c9b9bd28fb1584cf8bf94c562f2be23fd086e369c870cc36949792c6daf8137725df047cb1b79687fffb6bf1f52dec5179986eff347991a077c94f7c025b437b051a54a4f38b7323ef840ee1fe56af551ef0353510864b9bee1de6fc45e5c14827c9428cfe7a614b9363129443f2d899998c6994fc4745d0a726dc268818bdb429042a450e57923233d859dbfdd5366433782301ff543a5d8245f19b315d18f1f310c12342dfa3e6d72fd07d1d31aff2df3fcb92cfe96d823e46fe0ad34d860dfa4ed287e28312c59cb07b3f776efed967c948e1d868c78fecf94a6faf67d9a0a73ab57c449afa084af56454acfa4932098008d65d924731042d7acbca6e40d2ba83e7bbff4dd12f06ae415198caafbdcadf1caae710a3e49f9417588d035d533d4097828e90dd69cf4e85a136c099d62b9f12d5648c399a2615a44e628b4658e92e7c54749a85e2ccaad94c4afa191e5fd2dc94349ecca6af95834a23fbdbe06892fd3b0c06341e17211796f8cf9eeb040f11759002f23b26f092bbde427c55be718379557b6459d5bb6aa44257e8dff48b817de701de87aa39139a38b9a4ddf7397b1a8d972eaafb84e8b22a96632e38be38a4a7035d571a7ce92024e8e997e650631cdd4b7c5bf1246437a7b37c0845ded53cc84f7425b0783158998e69d115fdf65a33c1fee39777364b8874a46141e0e3c0f69b887f0deee7d38a1c1e9f69895e6b47923c9f5937a52664fea095db00cbf5bd0093ba6b2ccb632fc829da8327b206575a99319feb0b08f1f16197e0b775cf30ce90c3fae2e85cd01ad77fc98cdcaec31781fccf0472ecaecd5bb0cef33b12cb347c14553861f2c167523eb1df8b82933f3fba29a9c6778bffaf65a72016be02f7655661f049feafbf40967d36c8dff91e4fab7327b4827e7360adcbd327b4f8f333cdc2db34733466586877b65666f96c3bb6506dcab0c0f7f35edcb6a96e1e16f65f660a673ef95d96baaaf03787750668fe8a23690ecfe1a90b6b70be8dadbd3654f9946cede6d933668d8bba35b9c6678ef6e993dabe6fa9b5f13cceefd166176ef5e8ad6db8304a9b7ef94d9735133a95fdd0df81dea3e3e1deac45e993dddd589db65f6744f27ee94d9d3db3a71b7cc9eded1895fcbece95d9df8adcc9efeaa13f7caece96f1a5583327b7a4f2786bac2814e41d5baee5d5df750577efb7699bd5cce0d3e861aaa78a876776f97d93e53345b6346e39570ceae9abc1c98f26efebf9107f07cb85ac12fd07dc94027a154ec361164988195631c983202ab0b8deda8975dd246d690b43bae6ee0f09b2affb1c0e98f0e57ab14ae32cbd6d81956fee75c41c9168c5abe8f91636ee616ba4da06befeac00860a21cacb1edc286cfbe8b068f035d17c8697f0a809f6e638db0a231f36d4a15855853274cbaad5d24d3cc7815ab63adc8f77196399aa649dec621b961183b46658db0a4f131138bc57ee6b0a2699fd94cd14f5d88366fbc9a8d299781dbafc7d1ab1dd68ff2f4d041d1cf1babfc9c54f939aef273479549818ef7bec57f9ce061a6e83e50a4a6bf9c26e4e04bf583a2a5a7ca45aa02daac8be88ab4aa82aa833e233f819e49974a449b406184d1369515d36e8cfc251362cad88af19362d73812058e7ebb39e792d0d158d61fe1064dadc0b7ee22d082c3ec4e7fda097dc7c8bfb2e9aabb49e76df4e1cdbe7aa7f5914b6fff1cb5e95d27fae70ad0a91274460e029d6db4750d183f46fd0e7e02756522ae6ceb0b83325b7fdadf3f58c9c81f7167b76ee92c9980e0420a30729ee0c5b8d02b19a134a59517570ead1ee156cb86915bf23f75351e7bf44a1012796b4c7322acc41ed06f76926ee6f423d9f047a7ef778efa7e2920a259b8ed51c73bc46abdd6ebed79d33fca6088d0e83931f17802cb076c870c67247b6b22c230090bfbf56c79cac5d63b3e5fcc589cf3c43353e35ca307927c09f78d382752fa8db2639603c2df0a84e7e495c00bf258e023f24ee03f8beb161425a7b81390f299c42d58ca1712b7c029ff94b81ba2b2966b6b8f45c9c121ae29d989b81d4baa37aec1ef3505699e8b9355d1839a1e62f363d82435ddd989fd8050ab0c47b7b75d39ff3d0e3559ed1c4aaed77842c9b5cd2fa7748d4fa2e7de708dcf2899d2486785a626b94e255e6f2eb07fa7a6b9536a0d731bc6bb32cf65bf6133be6fe3e77d10735a9f331372d5de0e62eeffc60ff75b9f19c787984390cf4a16d486e7046baf03eac36eca3c2f0a1603897e0a3a8ddc1f068a708479a4f0432369ae91aad89b5ef804301b0df4112dd0f592162714e1252d26347a7745a3302a13ea06bd47c8943617eddddf101acd740558213cd315268e652e68ea22b3318acc59ccc760e20e6b5fa9b7921807c14cdeb15cb81e1a495a250b50e4e815f09eb5dc320d7ec32f4196947db0164a9807eb61b0c810f87a9dd8a99dc61867a431f079be792c993c4dc772b59a52bd44029eb1412773e83cf16fc00f625066ba19b5bd569cbdbbf7101a8971c1881d95338af0e6b5d00295309ccc180f282a6dbe1f7f0dd13ebdc9cdea65f2b6e9c81e7f4d5e9bb3ccbf7c91d6ccbe2c59ad5e532e143e4f5e89ea12bf4f72f4dc30c87490407001fc3929f57c3e67534e15f3e03ea6df752bfb2e29d270bfff2a79f9a2baf46f9ea42d4f67a1d1d7b0bffe9b62eaac5acea69f399b4df1236ab5c27b84bca0e3173436d65ae30756dbf999fd7d49496f889f52724e0b849f533264b77f7f4ac7e7b4c3c84b97d9794a23a59cb77acbb064f17b5a20ebcef633750cb87bf70c7df438e4fc6672de859c5f4dceab9073d7e43c0939773c49d1f41eb19bf811fb46db61e3b7eedd73f57ca6a6e67bbfb99cc72ee75797f3cee5dc7539af5cce1d97f384fe203c1f6943cc0500e27d931d9935d386a34257f2d2bd886c9d9b9b3b21e4011d170f283960877a6c2f69f199e22f14a1f2017586adf8358dec7a6911fb217d469d3de7333a7293e3ab6e67fd85c68a8c5fec77bd97d4fb317940d1b59e48ce7ad5e85f1a16cc033afa488b7bf792f02cc65b577042c65c880841d4013b1c4dab6b4144d11bf848662e96cc7a8d909bc4c1379819020f4d9e6b543cf036e6db430478fc4cf1070a7185ad4628ccfe5819f4cfe6280c07bfeefd7a7bf8dbee70a7186e1745f4ccb6d52fc301faa510bf90e100ad0608fd3f9163893f6808680fce019ce162b5a851e2fd51191b3f85b0b17789ca8530c907e230cf0bfd035ef8835d35ecabb722faca5840fe65c7f093fd7d431b7ac2ffe8817c43c9274a6cd92894310f3ce45bfea8192d69718b226ce9b3234ba0f58fec7b1b533e8a3ccc83afcbd8b18d23f392f8bd963679f275c18d98f13d9fb3fb0a75e6075511701ed1f92568b5747e8b7cb8d65ef1dd6a9095356ca86b1d79a1894c4a6dcfffa284618364afdfef423dc70251e4d792735867700b16d02c69f277e0cebfaac0163a2dddd4ab96dc4fc137d4e89cf4862622d400189ffca4687beaca733fc9f74ca4c1e28dee8622211f6145aeedf8970c57c73593176cfa90abba5458e85c330dedeef489c651a2ff6a928c7b034d327ea244e1bf688218729df6be1ce0b8c7a5c2d2ddff0ce36d6db4333e699c839b2de225b42c9da9b070284f44c29c1b8b7f6381f566c9968c5c1fd39a197e5c231c37782585428e9b47259b96d71a7c2e4e2d0a4c9471075d70786907474f85a839ac92c68de0456d06c8a723604caea9cec2c4fa26e1a16136fa79bd8e264ccde3c3aa602dec336c2290d4cc58ab4320ced3728017f46a56d1a9b3f4364499790ab3019901894c0e963c0951ec9646d45be4b60b4350432750df6278642794182b3bd6656153027eb0b0f97aa9d88f888a4661c6d39b67d892c2c650718835ece67221da400684437464ff441c5cd825d0460823579b3ce54af2b4b59199b446a4cce3b126dc62c8232820b68eb15c998a97a482d647e687d40624f34396eb8ad4b85965ba912d9b31ebc38b6582a13c2f96115eead87bac06c78362427ff268624fc9c085163eb1462f5e83cf56b0f427ea9c2c6d58efa226f3c6de89ee5b8c2e5a33bb59b439d1e7fd3403e6fdbcafe8a99ffbf3be4d850530efbb64b40cdcac3d1b1727e48c2cf084cc507946ce0cda17b8fe7d9ae7c594d4267e9d8b907696e7852fd5843feccdff839023cc97458d9b35a2112b01ad4784e12b32778cf29a28bc20025f810ae6b50d63a10f9d96a2587144ae1c10085dcfc89161ef2df00cd7c86b44ccc8516235bbb5571ed98dec3d3d253bb707f77ecda39cd5dddb231b60c31f3f45dda1a896b43f4e1a2f8f9057089c19522d86c9d4bf5bea453958bbe871017de608f70091bd5dbf91e8f56a776134f64972303f2cad7ae03c2c13fdc19ccc61f4d16a35277ad647876ad15efd8e749993eef58da3cd836c5ceba64f305f276456daf97782a3254a26495567b85a1653bde5a693944c71e30425f18938e1118f496f9d1621d8a792bd87a1e07b8cc5bec77cb02a758829917e24a2fd825aa7bbee95a958128a29119dbca626e3e4de104b8446563f8fa2b5f1e07cc2c945ff2d789d34a4c6c3e0da059f71520876b925fbe0254030a1505fb2933ae284465bbfb00abc85be0b49ac480379088d5569ae0e18023aa6a81518f4361a6300d331da98a341b43c9a0527d7bcdeaf96e05ea52dcf03db19d64f39444ff9319328cfff610543bad93566e28b6ee01d53865649256e86f0e9a8c4b276bfd405c2949c70bfd78c0a4a6a5e48f2675d48cc30459822e416adbf11883c2f6834b00803914111fea386b8201eb2b76c31a313f63f0a9da2a76488e97f01e5d34a4e6c70b786e6ec4d200a03a24c41941a44a141141842a4480be2ae054b41bc430f96b260490b96486c5a8f78ac4b872b2ff06defae0d2eb86158f945607a3766ddf98584cacb5ea4f4bb5ac54f7d5ebf5e4a66969dfb78b52a7acf8dfad76aa55314f3d86fdf154f59a5bd21a6644a3177fea90de779d4ed9a628bfb1b1b1f732279c1515950b2a08542e3335a46bc5b4e0aa336d7d389a4f61aa131083f282aa754dfaac081502130ef58d0ce9f2c6032cf3d9fcfe68cedafd553b0ab5c9205c711f68116ed983684e1ff5660417f566011f10a2ea28d8fb91ee10e8d72659c4908b02199cddeb209e3170cd825797ec34b9809dd157e78f9eec1d3274737d6fbbd32a67a0bb7b96b2f78bf63a729942b851bd7f553de544688d9f7142ca26b22b00df1d33c0e3085b3849c710cd758eb912a9dcd37ce63ea8abaf9cc3be773280653972384e1c6223005171c1bc0ebd8163474a74c3d66925fd8624f653537bcaf3c2fec69c8f5f1b6a1da0d43baa9d6d5aaa338053d684117f559a58c70d56c3d71e95e28dd3517e0bcec744a4bfbed82ab55a108dd3cc9bbbec9f3aedca2130137c278c3cb0261a5c923b7c56c98c2d48d8699c23f32fc1bc0f4203ce6530b5e4a2edf3644c931b74a00bc86dfc8c37a4c35062682d08b01750e485798121bd6a17f046addd6f776f238ecd970e02dded53d17bf864481c2d79de2b6dbbf6267154f49966db346746e1579bc97ec24063f9adcf0067efa47c60bff5b7662dc86e8ccb22854e2f7ce3072a5213595a6e439d8c3991c72bdf6bc0d363601beb7d4013d2c21842a5ba3b8158a155c499cfbff08830d5f9cbfddb6b1683c1a1b05ee0d4079bfc3af7de00a05ff1f3d1f6da181ff21ce0ecc705a6ba3c38c90b69990f3326f0d6ad0d8ce81ad4baeceb6ced955bd759d6da7a63bfd7f2b2e8a0c6f65683b5b67a532516b825b05de8c98ed6e2f8eaa50fd19add51398cf8ea524c736dc87c92602c7a58840a5326c5d9b91beb50c23f70817a2e80afc5bcc852e9cdbd65eea403b66c8cb1152e6f09244f66b1b40a0d387bc0cec7ce62253fb80ea23e467ee39bb3271a68c6f31ac50e91ec1e918065fd3aad958340368830ff97e690cb8ccf764a0091af3b1c140f4292fec11ea7d02986f24363e7cf4f620633ffd685ce89e4329745f8c0b15a173170b54cab29d17497aea383c8d8f051eb5001cdce8fb84f05986433f95e8a9d5cadbaf8257a1774b4db6f7e7d59401e16e8a138d1858f2b4309e63a2fc88d1d9d98cd972549f1965514d22806e2168cd168534751aca036a3e217ebfc532b4243504927c5e16e65b0c6ec5dc97d6cd750cf9c67a222ee80d88b9ed10b35aa94d010f4d808538272d0cca59bad7703786d2691620fdd58f203d0a6e7270b8690426feb6c43b7af46b32d48fe3563585f573837d121d89ed382d5de159ecf6606659966d2bd77ada466c38194b8cdc5c0a014dfbb76e99d796efb7efbc9b093d4b949925767be89825229e25e63e83b0089008c376bb2c3ddcaf96c506a0f57175cc419fe759e1ad400d96c3278694493a6bcfa1ee801a674d62dde1600cbd2a1d87ba85ffaef038891aaf26c08c919cd91bb26cdb05a46de13e0a26e2712f36e17e0b5625100a66991242be8eedbc3483e06732381d28c3ae517a05638ff4a8ba695ace625c00c65395e8d0b9b01e00f306db6203b6e7b12b842eacca0eacfa701d30ce46f5148082099565dbbab64eb44a8f56e9d12a37a2d5576d56b384035094f0eb5a9331c215665836114eb1f9a09c99f71ab614dfd3b81b37b58529b24320610864f014d4850989691803d5b4970b3a8505c515aef13278d89f99e3776a7e26a4c20b5291013e32021a8bc3499e2f8239fa627b1b5d4fcc79fbfb625c1c918915efa0f2884c3c5500dec6c85941f104d7078b43bc8ce3ec5ea16b9b9ae4793121479621bf66793ef187f0557c082b5d15c215e1c515aef0c253bdd3f18c5c95534f525ce129b9c21372a491b82084d40def83c2d4348be09958358746471dc53121270575dd300e9d783169413189a098e02999783d8fd95a573f21129aded4cc119917134cf1226e8af9c97c14a363d237b4beebc1114ca54509bf064d472d008f22008ff054a33d503e93ee90a18e102b2866688d108ee6d491c60a5ee299d945a7e4596186b9e3de366ddea6ee0c5034258a25991ae27e895a1a9d77862884a79f103b6117a4c647a426037c65322ec812a8ebc207625ae479efa23fad041b1d6d6f4705d0f5c2cee1a3717145167861e7f015592473f814e6f0025f18f75978164fe3533f8d17795e2cc855348d177e1a9f36a7f102e19af0e214d7f8c88fcf643c25a7a55f40e4144fc8295e902b3d8d4d1fe209bc40781a41b2b01378436fdd0cbb80891cfaa2279806e5a205ca4504ca059e900b3f55a6309717309717e8fb2dce8b05a6f8a8d16a98d617317a168d697d01d3faa8bc30d3fa6761851a7f6c5a4fddb619b1e925e67abf347be54dccb73ce7fe84f0e3cec1687106ae7979e3bc305c84e98d95eae19d227b7ef1f6f9653daf4c4d437846a49bf63323439fd9137eea4fc15924cbfdb5e42745001b5deb1ecf1c221186fbc30cb7208f882c467cd0a7756a3902ada7f712d3d4779a8909c719e6c9f5226e6d0db5b8e5a6e001cf88af771d3a0637a1c7cba2d911473b2e31e0afd12f4da72f35b16b2a32651c9409b1bb8c61d6e43eb8ddf1352dfd795c17ccd304de6b8e9924e1366f249b66dc66f0741b0805f0882437dd9600bd494e5a38bd1a41e934cb0c8b6c0c8bc47ce3e5281e0df8361e8c941fb12ea426f0798ab1504f8ca0751779c83bc843ef5181932cdbe64eae2cf3fcae43d8b8d8d0a9f6589b1ee802ef6e0014e1dada161ef3827bb26ce1b70afdea59f4e6287933cd73209339c25e3594e7796fe616394b542dacea83390b5d5c361c0ec55d6c8256cd28d893ae56ac2fe037f362b42c70e84c0f8d9cfb05275f79d11b207c6e524384df7372bdc69f7950457dcfd7f871e3f95dfa1c18b9afb833e12684bce7cd13fcd7dbc1022362f73ce189abee192dde716b76f2985b8389cf1cbfe708b3c88f8b530c37281a0e4bf03816dcbe7837630a30022e003ebc7d5ebe34e70ace32d4b07453e4252b14291881489b631585642c154aaab1743733a10ac14fe87aa9e174e0c697f9d7dc98e5e8b74bdd2bf879c7a322ff02ea5ef1e21df77621ce65212f3e874c2c004aabc28b46ca68b8150d6c8924ea1c54fed85762751213880c93fe4134b4b15fe867dc0541b56e2922a621b0d6c1e78499b9ce194f223c88343744e4154b4020acb3aba9a40a6211ba80a5e05c3b443235ded48399bff3e83abc47bcabb84898ea9a0681515fb20b4667afe4d4ca01063df0801531f43a6a1649e84f746d136e2b50c0fe84ac91de73b95882c000706b95763c8f1660740465acf1a36c75ab954bc56e7ce102a67ca1b5afc3036113312bb6fbe2f732510bbdf61ab725c3709895ca6c0a4f9bca2f8f6dcc2126f1f39b1463de7232c0df8cc33afcd1fe3eb4bf7fa72aba1f78e114febd086077184fd82fa95269eab22bc4741d8c84b740c8731174888475cc635c6d819fad4e275bc16a80b79c0abde584eb1e29ac3aa4f80d255f9bd550961ae0a761cd09ef99cca5d26ac75755795161069a4214b56b23e4ad868c0c46d3caf8d76f35d72b76effcce9b57a73db0c1e5db64a847c40d4e470722684f0324d680a31b1e3de7a3cf8e2aac1c1bed6320633f72a3b606b3c4c0f02d9e1b58b5401e749e157f701fb5ec3ac19e7591ebd5aafd63a4dcfd25242355ce948ffb908fbff1c6783fe484950f3979c8adf6337e18d969dee2453c513f7207e0371ee9227bdd0f366e8cbb0103b61de6106577fecd30951696685b55e8a19eac1f3961de38c2cdb496c04d63b785c2427f8b3a14e4cdeb8fbc5355fd63acbffcc56541a2c38ce087f0ebf6b018cd7f253b58975075ac0a86ca482ef329b681e1853e3a95012cba343703ceee0df5621120b07bcbf41ec9a66fd974396192302b24fec8412b31749b13d1a1afcd6381b6b5ceaa89b1691859d306bb306ccfeb75542ba126c258acc899d4476d5d4066fba11919b5f09ad8053623546f18e6aa396b2c62a048efbfb57376d2d2496e966f6a26cf9a9ac914505fcefa2681193d65d2e24fd7163d9a77666ed937666eb5f5ac97e3a2264b32c15c13ea4bcb6120133cfdfd1b6fab47b6f2c8d4e8b31a6d6cc7c55e6a1ac8d5f5e3dad8ffc37d060ded296eb6a22f53695d40a3c69594ac90d8418146fa26acab4d0df066796ea64fc02d27b2b458a8f14b59c8e68987562b67aed43c0b75d9a07fcaed9399bf4b9c2e23fb855ddd078daaa2b0c09127f737ff536b38b4866958bda03bb88970a5e83a5d8e366a805b87702e1356705cbb41c0b5d5d8b683501bd4bf9405ff092473ece9458f5d90484798479dc8e60ed91ccb08abff4458d547ea68e3ae6a9cc6b102b5a18a9bd7376350f8fe62ec9b62fb29ec106d9d58b507a5fc8be316ec255b233f466451f58fb9989aabdb37b8e8b426501c0180552dd93323d78a9e960c4f24d3f52b132fb4ba2a059eb2455dca8ef3aa50fa1c8fcd60c68522d7419dc3164f0b01d118a97c307bb0a1325c7ce202fa92da51bc2c64c3c68861fb4e361a40b10285aa82c5b75e34299e22ed92aa290185c9f08dc7ea5b0cd3c6c0b3aa18aef467e6c615f81836ca55ac02205b4ddc82f9465a1f596547931fad3a4750559a386a2d4d4eaabe1dc688fbf3851712eb178bda5feda06256816e09c712ad7fb89b3c516aa055620e2eaae2cef02ebe8d53f93d4f4bc9ee5255abd46dbcdb285357df257ccc0ac59afec1918db61131a235b281d442414fafb3a47c725759231bd03b5274a91ab6d5c252b5620c7a1a13aa8a037688ace73ad39b3a5eb90aacf062a5962a09e43a4911f2476bf2920316e69bb221bd0ee3c97f52c5f68030db14697de24f817446a562ee20435630a7149607c34334960783c3b2106dc8342451e7cefe77816286f5fb00cdab5463fe2d2d1018f7fff6bb1cdffbad94898d3f03f37d84b02ef1eb7d39bef76ba384a9e57964a010a53b7aaae495ae7588b0284254a7f81bb95ec78c804503e00eab0dda22dd620b8e06ed461db1d6a0d20c332f5052cd4ba253c46e10f9c4e85cc38e4ccba293a687abbca31a28e6b1b925d6b7e86fdcb004ac0c097290be160f306dd2b16f396e13b76fb9bff06db01772b0ae56c06e6eda54fab905eadc1d073442ce1d44d528604ede9af0a2c20218dc34255239a611896a08cc1a576e5bb61e2018ba5e3bb31960441d55e45a32ea4c0d4ac9f1b2f68e64ca0fe6d1be344ff63c360fcfe70b2621bcd0332aa63366b35fd0ab6aa99292fb6c5ed9a49b0deee9c4a6cc9c30e9c7ec78790ad6e7be98e3a5b902274c4a368dcb80734a8851587ee06b7c7573e72655dc3919778e569d9d6b9a3efdc8f62c6ed89e5ba84acd96c2d1e78f2b8fc9b4a4d9f9221273ab6303c4376e5feb78649a1d35bb4257fd3da2bb5d28542a2c9b9796887255867295ff21e5ca3a0857f53dc255b6095737e13ac4d32cb0e4d91a771c890645a6ed7f9a937456a593f465c724ed1a33b8226049c4c1e050df900e86de2b1aad8ae621207ef21000b7345dfbbf58af1186914758ae1b6ba7ad11ff8f915b09a20e0687610aa883e1213e9854c5bc35bb0f14668708825ee08b9bd7e1c9e675c8bbd7e1b26aad9caaf24be3ac8aa7f227bfc9a82a8c5fdb65d3275efcc5cd02fb5f30aca6b6ee71e5fff78cab05b37b5c4fbe37aea7ff27c7f5cd0f8eeb9bffa5e3fae6ff3fc6f5cd7f35aec726ee13deb7bf97552257fa9a90db2f96c51da3a301ff066824126594ecf193174fde3f790c718e9a19b1ad65acb31c9b69782bf6e8223e2ee2a7d44484354c4458622292be0d14f08b2a0d641d6907dc29636f9b8d0b43a108380af2f272137c2b0a5ee9dfb6036ddaa1071dad0417bd81d55eb95bb69acb6cd45773805a5bbdbd0486efd73bdc2b6f08357f5e590583cbcacda8fd0a42487bb133d82b59a4d9e0208aec8bc23050de592d10b45af942deb750e4856238d8bd93c7566cbb66b2c1ddb338ae0843a3af5571ac89deb57ed473725f14d6ec07ac642db3f9c7ead575441d7d5f39797b704ee5fd6fe5f91d634a454ff37c2f24873e3d42d16750b5aff9b34321eb11725c05a1a846d5a57b3600006c036c3dd52837d1f849e10158adb233468d17fe3ccf8eabe9954df72e84d1cd8f65f1c87a7cd8af466a84ec82c5caa02e1e20dd8881c144a930d31e86d38bd28ab68922782777ea0426b45c8b37fc2b026f270eb951ab5891c18819093da88044ca266ea941f4707e5264bfdc02cd04e4ae5d0a5d9b39c0d28e38fd28b5b3031322bb95192588ec56cfa7c6905aadd4f6f6ba01d4daee76d62dd67e458eab31341354bbe2068d9a7f5bc4fdb82a00c2e378f334a151ab8660ffd5a56012bf4a77d7271127cf6a3e7899f6f81c6cb660b3c512952f380c3d14829c4817a68aed00045879ea93ce5fb1253bf15b99ae86ea532d92cf739d1384e9afaac4dc6b4586d8426aa5e8467fa36c78e06a7aecf215e464e7cef0d796e393fb84767872230384ff30add1986df16fd55227f0a2587b8d16f1a6dda12a5dad56e7cba242ab95bfcf54896741cf341060824b258b8a8aa4e8b828586cd9652c06ac160028b971abbf08e8c72cd272b123cd0083e00be30e36b63fa4c28f4c3f2bdb4faf6756393fc598dee7795e5052a5fb002e845fc522f4008d45f95ca2826209fe762518c50250686c11cd51d91c70635e5879c3b41b7a11294535c6283dcf1844bb6aec5e6da8ac1fbfa1ee271ab775249a1306fb4ea0f25915999305b81e54694c33bd1efcec09b6427ef89905090c88523bc51519eefe1655fdac6a87235dd04234dc0378ba91cc69a161c56e218aff68218aff730bf165d5b03a82eebabef706a3535a287b508392925ea9aeb35e73cbfbd208282f222e9ed3a7696544c8d845f8cad9b5e2539b327b5b6f308a95cee24d226a1bd74dbdb65165fd49d423e709ce7a75c0336b37b9d167c4cc4fa4d97846242f66a89c99e19e754d09a7aa2e36ba65c093aee091d34e6f0dd5266f0da349a7bf86ea07fc7b747eb6b1fc6a05a258b95a2d210e679e5fe831d11bd90ce1e09defa4250eaeac7384133c052e3caef4282e9be5b0ad5e2fcbe56a15bc7daf56948f3bdca76d4d8db70c3d31a67a92b4aa44b8a809e5abd591295563894fc0f0068d8b9f41dc66471755b7a38bce21ecaab22bb7dbbdc58d90ddf0b2401baaeb7243a1523714a8fc4e4f367f8a1b6b8fb47424c81261b7202576b36489fda224332c49fddfc020496f68f7aa746bb08e48db5b848748394b88c4507c5c977f5067c95beb2917b690e6965134f614f4b33b082eba7688e2a63d05fddcee81feefd93c3a36843025e28da3b5c1e0a8ea93ff68e368558970316d6e1c4b7cf2f31b8741f38fa0cb39dff981adc355da995d4880f3c7779050dbe6b7b6d21fd8485c6dada5f833d3b2f9f9ee9dbbe956d48544dfb8096ddd2044f37cd956205ead6e00b3f75d30fff38674877e60833ce9da204f1a1be4f4ff7b98816ddbd1d44fab847e0e94ead3c675c45e03ac8fe00e9305130d24cf7b9e6743f3fc189c4ae0de10859bc6482687c5bb2ac4fbb10a6c55e792eedc97818d623576eccd3d92bda5e47fa096e16a60ae60296b40d3c9dc5f0ecc4bc8ace18a642f10b529d314e219ff5551af07bea680d7e7551c4c353863f332792b07185fd162809bb9ad0c63126283d5943e99e7f673777cea1130864da9499e31b3795be16f15fe58e18715b96e30acb0644a5e194fe99105cedfa92604a6c45ddd835a823df3c903af908f6b7ba92964d71c42ab957db19b5728280ab070bb6c3a2cc5725cd4a437685cd5eede715a462438d069ad8e60f1d63fb1d298d5aa67327c2c14aa4bbd3fe3f5535fa4a8566408a64d0f381ee655b877c2a5ceb33d42b5797e5e159a24820275f406171c9cb34088473c68380d51784034360c720dbb32f2db985a6c389b20f85fda27672e196ca4d808795e040793b1d46d5221344035a62d17260af3e025a9b5021e567ee170ec63b45112ec353799ae988f02d30ea2fb0495bbe6a06b14d228fa14724059f4f204bdc2f87a4a25011b310cc6e73f835f04009aa41e1debba87d40eddf508d5ae31010ab80d74530d208d2d4015161ecf1477c78918dc847f81a937bc4ab7b86830447b134bc643acf94940f27f3075fdccc309a3c24d3df47ff1dc16c9b1e9daf999218896c08d5836a3938e4b1454c772df5a6ca7ae401ec49ecf9bc20e88ae4a9a994421acb81fa644f7f34b832830c44063793a45feaa695944ae79fd904ece2fa99cd61067431fd75eb9c53fbe53542a1b9a63466b554aac289f95027ec2189403c88018ad14472ad07c5d16553f6a8c285cf57dfd06ff51866f900c7005724fa00875e544d84468160ab98609b55f584969cc39fdb3a12cd8381729784bf4a6a0988381380717304e64902c56732e16323a4f1142920c73b9da4dd97b776f27365766e9d90397c5072e2bcdaa73b6a3611979335a23ebeade8af31c26a840a3c402d67cd27ce5abb026ac2c356165d8ef3589092bb009bcbffcd88895751ab1326fc4ca82116ba8208aaec39a06ac7ed2471bc75ae664a8e130a7bd6cee5a5d8bdb74d98ac8a90dee7b5249988c19a05c3894639a783612deeb21b81c8d2361d8fe81ed33083104c282f893621474f9291a17d437104bc7c0a5b4ff243a66e025fe52159a5684ed91272afd28092dec1696eb8b39023a5b741da3a3863f55bab17341a0479def1a423dcc34dea6c1bf3e5b1bb8077653bf0974559d3275c66456babe069d0c6b3fd0f5adb7c9ef18edb0cd3768fd3ffc06109d7f2a8d46d488da34725b45db2e6e60d4aeab6521fdbda2115a2a8ddd9c2c7efb41b4fe9afe8cf682eba3d8d0dc0cb026a1fcf03648a988eaf0ba29de3569b446a34505f2363f8e37d367a374926ec4f6adb6668ad9a3edfa3be3d3291359097a037a9f0d86dbf13c8ddd8ec6fe360569f818152e5210b32785be84a6b0a6d1986726ac7a568a260472c316201208e486052fc72a32e2d6152720997402572953944666ad379e5923ef8b3168fdec5a871777edef1de723c4f9c1b08e7de0e7379b6b3f72ce326ec7da3b56f1c6652d1c4718e5f9112dcc55cb856ab1655ef30235a286c2061b799d4fafcd26929b8b71d6bc643733ece698de27c34a5aad7a9f2b7006d962eb0458ef948f7801ee323a9c6a70cb104f97ac49c5bdf8667928589af01c46ccea24bf2d496b084a27532f0fa1c666f0d6bbc1cc5d58035fd6f4f8019d45d7291bc777c1b0709ab241e7f1f0e08538240acb837371486a4d43c2e2e02792ce5d8870cbe9370f6c7eac97cc9faac866159d66dea78f5955177cca2a5b942ea7bcca2c413318b1fb7fb1381ce49faaf88b1db0c3460d75b59413665a601a0fcd26f8dc059de7737aea03a37371def8086f02f2a492735356b29a295fb65e1ecfb96a969e32bd5e6bf381aa4e4f67ac0592582c55567e6585c4b5a98b8b0b3ae3d0345e8a42e0ac1226fe77967617c27f67a5ec1f5d4aba58384388eb4b5aef2f678a2f66acecf5eafedc3eac7faa7aef5cbb7cf283c0addd26b8dce2628b8a82ebafec25a946facad93fa3f5ab4ba1671293eaaa5822e7ffac3e581e8e32472467603edcf2d4341bcbbe860b563344989e8115e941f810cf0e51d972e734cbf3e69759b6ddfe58671ea2f2431b4eb78867790efd5ea2b5f39de666be19ca63a64ff5f78033d03eecc4a929f5affedf35a666f52c806d5aa6744b8780a0ee57e2d18c433c29d9afc444a7c94ca035f8aa4ddd7144c1319b9b9c892866bbb524f7c03f4ed0b02c451f7cb53fb67e90c0c6a81680c467ace008d99c71564f245fa80cac988a829165df98c65ad7494536e51719b8ec164c3e7bbfff8264f7cd37bfdfff7f7fb1a90c1b0a7f5e5d30d07b2c58ac0489cab6a3d73eafc7edd638bee675a95fae51d9010d47d861def8cc2a968461e917ce78e993a4378023f71bb839820431cf08a1b255f5cb77c62117b3bb2583dd52e2b74e3f31d2556578492abd6824fa4f765386c047dff777d419198c66d18e3af33beaec1033346ad4d2b1abb69bfac19d95c53b6bbb96d6eecad2ddb5fd45e70edb019edf65c10fdb8c5cda54b2a5b19b3744b71c67e4318b3cd2a50b97ddbc19cb6833b6f1e224be06cf95ce26f6e7804a7669dbb9573fd739b7b1cc885cc3a63d733a3986acadf56e3ed5dbf7b4b92dd6c8b9f7981ed487a3ac565733a6d7503d16a2607882ca6caa1b93d5b29e5dbd63eab95bf0b694897c342193f1a47f7474a6e6338b0794e7cf99ad223e15eaf6a93019a7a120f86a95e9df09caf3b7ae8ee68930b1efb26c5bbfae978b8564756dcf8727530e22838f540a13c982d479ee4b3d03b10aaf44e33d5daaea693559d636a3681d2435b27d9ed873a476d28d499e5f69806a3cc14b74c3e9c2e0746158e2de70f3e9c2e074619d33d834288dc7d43c87f80b0f9492fc78a9589141369c8517acb0a5d086d91ef6c5686edb23a610ae0d347ea7214ecb68f03d287612fe6d206a974e4b44e7ea0dc7e22c3a1659722c5e996db6e304144984950e95c7d6f5e66e69a278b769fc8f5531c02d4575bd71386abe1528454621226e26ed9bb70fdc45da8fd3bb13962d351e610f2673ce03720d73a243c5a910a4f81e4d80ecf9f79e7d05ef868544c836119f75a20391437f095cd2e201981c3535583a048d1daab102e2207835600972f210c566a337bf20e103e4953e321b29783b6491f037f560650de50c2bd479058dc2deeabb54649803a0c7863adc1a76dbc71a345a37067b699436175b1e9b112184459ef7a4e117c772b1a0f4dbeb42c44d02535dd5308ff8d6e3cf3521e458ef769f6bb2afa1fe5cf74c0e24f6ebd54abfbaac81f14d5ed7fedafd427ff5efb27851e3f735c28f20f5ba4608e96bff6ad5b544ad377a9832b713b641349506defdbeb9aa8737bffe003762784faf693b0b1d2fb6351b519345c7bb04e151405719e414c68088a35b5561b671c759b7a88b75b0bb98fd702e3759fd75932ffb8ceb13da30fe1a4205ec5ac6f1d46d04654e6f0e1c778d0478c30dd312be8ae7ac9997c9cc8dcbc3224f7a2147a82602179c48142b02ecb6e73be6ada6304facdd1c4398003e7812d8679324b0e505a1f6c249db42aa8fd4c88c0483bced0891a73c63cbc8ef068575e5b6c16b59027851aa17ada600370fa426eccde07cfc06b5fa26dbbbab839ed22b9bfe34ea26e849fcfeba1f3fc6c1fceb7e78587706a7720a1d61a35aed061d9e48746f8c9f80b5c651e7ea310e3193c5032e3484b732f9cec211ad856316df205a41fa1a93e78eb3edb3f6aba9dea4eb68e2b6ac2337ae2d0349eb8c10de2be4eefff39c16684776c84f7f970d59699e0fefb758060e157e33699dc59dd20d227686682463b9eeb8f023d2923de9232520dbf4108d037fbe2e7d496cde923aa12f7a0e9d63b0a76b77ad6866118d98ed3b033d44b63c96b1dc194bcb97f7729018f3c998e02efc42030da11d56b17e9599c17c3cccd56ab71ce6fa18b311749af29ebbd8b0f12389f527504eeb74fcbda0058b0f3e6f82e907d62da2db837b7773b03c6e865157abbbb7318b03ffece923b3837b6f4faf2269a0158363f7b73b9157d60dcd39f6bb2d06bea7f10df42380df68f8c73a33bcd7a82abcfa2192c3c1951a1c6f3524346f129754960bc0b061b8940ad78a4ececba78542ebf5db8aa4c6f941e4d5383f85a102ee101b9272b5baeb9288f5e9426fce869b1619a30702e4b60b65190cc29cfc50a4527e0112acb6943f12d227327ed129e3175ec62f6219bf334cf6efd7a229e2776f6241da7a8dbfa5987241d59a0a2e4698c14f8aca04720261075ee2597c6172c28ec6ddca9ee522bd9a57e49215335ce9f3085252973c38ecba8157e4b12ffb78435977c9ae0c9fa86af189e4260652b3a6c018a8c82bdfeeab76bbedcb74a4c3ec2fd31d576d195db567c955db7390a8893889ad8a41056eb4659b3f92e75557a6998cd5417d88ccc5d9719a80160689c3ccbc9e7531eff56da210269ce9c1f290649999f21bd95396a3e3594f0d0ed0ff063e115bad0a3d36c0b2661020a3bf58d667456df5dd02774eba0849f2a03ed4937a666faed558a3c4ce0cdc89edff1f776fdaddc68d250c7fef5f41f2e4d400214493da6c150df3756c67e21ecb765b4e32699aa38648502c8b44b10b282d11f9dfdf838ba5500b6525dd331f9e737c2c160a4061b9b8b8fb9d592d8a6930739cc71257d759776bf08e596ddc6e58e9cd6616453539a12e6fda01dfd90c37b489a2e5389fb4299d8df3497d0b75a90bbbab97ca2d17e17e9934074c670f6f3450a7684667a3595902499674395a56caec2a9950b73313c2b4b435a097280b2c213fd6665313f6cca2c88925db815b63adcb4ea73bfb7789281b210df959e54e69b7d9d8519b356d80c119c65b515b000b30446092504eaa2c6493c86d4b7eada36c7c2f9ae5502662dedfd3269fd05f39bb3ae36a64ffc6675c1566ee5c96bd9fcd354bacee7b7ae56d308a8b0f2c357e440046bee8bd757637262426e954c1ac0fa80f9af11ef94c1ad9ddfd3415325df21e6842f495eec3d3490e14619aab52301d9b98658b7140322819fa1c647c5e0ad35e4a8d16e4efd4df77213bcd67f53a98b4b9e60055027416715c65c91227b416a99885386b91fd7d4bed38e38f648ef68f8e43994861755104bfa888486b96a8ca04010ecc4076b8d4a06ac25a23e41989c0215160b8f77ae7e7196753f556006fb56cea8eaa6d389d83d8d2a056f46b49c2b268a94a9f1f1f849479264b19280c0f177273a590c0212361a38e3808a6aa880d3d47c8106d1c175ede108ada44b01dfa5fb4145ad79cb10ce1adb0f1805d4c6f00a800f2d8ffe9b08d103918f56386984867f1e4939d3e1e5c4d145f26d1011138805d1e266e278751604e8ec32422bcee688baca0df4daa31917245f6aaa154b804b8e5003743dee0aa560fa9fe38b8f6fc31841d0a76b422ca98264840b82c1cb079bbaadb0c4d5eea16300f7e470c0b11869ae2ae52407717c46b6bd05461ebc7553a9e4745d6d570d7fc1c29c40f2a6d6214dd8922317579c5a388f7e69a4c43d807a72a9df80aae3b88ab8b0afb5cb1b30683c922506b70d9886ae5eacbc2a12b78f393d2371476431c9c78746420dc42fefee051e829ad1ea2861be5268fa29b1c81fdc2ee1376583b6925f19aaa409a08422f05322c87134c28a2a109182c46274f63510b18cc69e612524040258bfb423f2ee182859be873020517f1756ed235fa384916d180460ceb8bb804964aea1568703cafd82b96fd84c5caf8e097b979b8a1ad0b6bf532b49dd5c4b2aab167d470c56f211f7878a88ecce8c3a2c378e6b63ec0a9b244700459673c176e721506f2f1aaaf882dac89c2795d524c6ab14f785dc2cf6b12feb2c1717514a5c24005196029154552af4710905c0671528fa88f497650fc3c743f8398e3d0ca86002ba8b430c69a4d6b964ba48a3bb108e515e4e4aa9cd27e6113a04ad84dd402f765b43d08b7f6c0612d452b4ea326484cc530bef2e101c6dbc1711967a24f1c29d2e9e0d0bd2aa27b83a778c863657d09f8706813c73e5204944be41e3084f0f296d72dbe0d6441c63bef11f2a0e15121ce3a2e7e0e9eb9df6620fba56bdd09b35a2acc04e22c840fbd342da8b75b34b685c872e50f98e86495dbaec5b7db6c54b02ba894db00102d49a8064566447a102c2ec18a26a300dfc42a4ccc29a46262ca89183d03c1b757dc674106425d8d67963c005411670d65a8d205c8e28b5e70b50924bea4192ec91c55a170cc68d63384caa734052d0f80250ef2ed654128322b54da6c9008054c65c9252bee119f45cfba23ba104955c37f73269b5e6f1127604bf0bfb6294dcb9c55d6eb7f7f7e05fef237804760e01e48adb7b7392c6d89ef254d1c5e337e67c3d289963593953ec6de729cca30f854097b318fb95abc82bb34b8947117f3b8abc541a567b183a4edfed68ac09342049e982f99f19ab8569c2c6942665490295d0e879aa04f25cac994cc3c9c4ecd2a47d1213cc0c12f9ff62999ba5adeb2670a09769b5cdda68d3870ea71e0b41083171d4c7d85edb48af7dc1b1885db5a364239cdf4f482b5d607382f0e701ee280d0cc7689e3bc52802128435112748b7d66cbc36295835c654e7d90856369d84aa7b72e9c7e13d7b8d02ff86f019d9a6856befa9dc77403d61acd6a8aa4717f12bf3f49839a424f1c7cd5eddd656e192421ac5252dd30570d06e6151745a692c7cb5cea2476c8cc669a9955b8ec85332c05f80d751d7ecb0297a13225ca9a520d1ab6351bf2d06d242993f71048b74e010a9fcd0e2e746b1b6df529c63ea993b159925a85f8dddadbd9659033378ade71a35500429a69f496da64cb8cf687ec79e2ac9c5997eebb4479c9984d48aeff740735ab5541f26f59adbee5b65659cefbc916dfe9bf92e41ab53a0d6c5955746546ddaca3f9587fe954419af02bd917f702f362f2c0bb46f34c5e32cf1465834b0ee699aa4d4b4dbd9ea06c8fd9d0be6eb0193755f226f6e349dce9e86fe2edb6c4d31fc78ff377da2f14c8c07e8757aeb76dac8234aeb89f414bb85a0306cef2dc208bb6bf697b407e52a81a82c5f3e035c100e8455511f9b11c124113ec31cac0aac49b3fbc92602450c89ebd8bb718163a5ea3db4fc20834241b3570a5806c34a4e39ee4ca89ff4749f8843a36e3778774442a78877492d53acd1413aa83e3c42504a7e66d8ccadf75f801b12a136bbf1c45acaa7ef05fc423e6ba8fada91434f2df5422181e0b08bf63bf0cbc71cfb351074c954b9a5f7751178ef18133604562231a83ce84e9a5ef1b2c3f436ff8a4ac21ff13eef3ce7f5e345c597fc07b5efc0bdef3c1d53207e941c556a2f6e67102f17949c450b935bc6ee3be2e41f011328a3bcc316b202f2b71fbfca6f5f71413d59ba7d91b365d04ba16e5eebb8b3cc8110031b2840657e3102a7a6c36b332af051728231906a110c45d5ac85d0aa953b61ed9bff1295b170aa99527b691a032413e8c896297f48088de9add2d5336a3f756701c648cca9ceac9bb78f6a6d644970642b19fe466837e82a04aef25cd30b14ab02d09f200ac1f1cc7d089dff49476c6ed1a36ab9e024ec98cb698543d6d851d1bc910b38b5ac22e952c0449a31d42521291bf626aba300ec20d8bd360e49015b6d13fcad18f12c0e68c2b34568b444e70fca33450b048a45f4c17a9c5e911f5cbfa3090d315defb576760dfe3b0fb48c49dce166f3111264f952477929e32b5e84d79b224d7727702f5cbea3b1367fd42d23e3995f480dc487a486ef5e33b2b0abbb27f3febc2df24bd90e4b52d3a9334c851fba1f4f4c6d6f9a89b7dd504aebea7fae4a52dff098adedba71feddfb750fac93efd2ee9499ffc6a9f7ed0cd7fb10f3f4bda2f4ec83f65011dfd364587cfa25b89477e38833da46fc82783fea68fe37e9bd29fe5e86719ff1c0cb9542788e8e281de04d947fb115cfb26128833b22c263e0cd2dad916875191e2e1e404bcf78bfa4596df7d1bf1010d8ef5e87d1a0419a0378139fd2b439cf437a2a78c32f8546e3647fc80ec1ff571290a49669981939398075b130afc4e9ec5b6c3c1519f0cfa252fd4d689d50c9c1cbb5afe3b61ada398d3fd07658307fbc7b86a68f94e4691bea73ecb28dadbe361fec4ff2c548847fde73f3821410900fc1d0106812585c177f6b839a929ec45317f482ca3d71980248a608b0cc0fc5ddf3031fa6ffd87f429a5b7328a7ed6b455eccbd0a1aebad99c3c335a959313130bdd675f97a35f0d3e38656b3486c434131c231f780e09faabd40812718c371bf142e128fa556af2ca8c3b60f1ec54fe6f6341794c6eef761bada62018b2282aa204b112ee05f8f32487b1d207528366812a2b6b0c65a2c0beb6c90c588576158db1d1ec5c1e680c9ca19991197e66f865e6c2381612d66de6ab56809645117a27a9f99182660bbc5a6e64147dcd11239f2506f714a63792b020ca46897801c5841e269f85b15e9c9cc00894db1f412d43ad6ae3a3515d40bac4a29edb70dde3c7445cda0eedfbfd171053e8854f33f25f22bd11b6a777fc9a2ff148c49ade56c0adf7e3e01802c8dfdba1d5c68cb9bf2c2b0b1edc02459d8f59926689baa327274129905cbf30f47719125438d0872b0a2b47f41cc356439ff324507d563a762aa7e661f61b47d72fe9e2f5c5a2bf54c11e193d398907fae766b3ef4a8ee28cf65f5094d141ff7b14dc2b0aef554a328c472727f1fe51ff0585aca747eee7d3f8e4a8e0e32c51541fa71ed3ce89819a8abda099378e6d53fa9145d12d43026f77b6534d0b9211452bb36fd8aff8078632f2b77229b9b737545c5f107dd56e711512d436b47a2e6e017ddb137f385e9a63a1f706138397032a1fc0c51d28736dab0aec908246a8a6e6d97f6a6e93758e4c90027d4d09b8a6361b91437433b73f57d2f103b772782b377470ecc3fb30ca7284874330a9caf54f8359bcca35b32ad7648efece10d6345746aea537af6244c3d76feeee53f4b524eefb5fed5f33f750f974259d010503b42112b9e0b35fd3ec4a2f81e93accfdeaab54fd2e48467f939e067494c4858c9d4ebbbc6c87474ea2b11fc3f6ec3f17a3fdb8ac4b3e957132476ef0c2f8ca19bc7206c9dc6616b3c0496ec456749a2386312941e4998ca241ff3962f495ec1ef5fb005cc6c6e4ab7489366a18d2e28f64b3495e6838a956800018269a9dd9baad8529941818c35194b40b3ebb08d79519c0ab7598b9c8668e7233a9fde8a540f3bc7c7298fbe83c2fbb66b76efe7d8bf8554611ac01004b79b078b3617a591eb12e6e59985f16f6a796a58466db947e90a31a2afd200dea882b0030ca683fae63de3389f734c9da7f81323d40008c3d7016cd681f2246555a08bcc7f0735d7bb0df7f918d06fbfdf8f099fe75f8ac1f0ffaf053ff890727a6c2c97e3f3ee0072fb2d1013f880f0fa054ff890727c7fdefef24ca9ee85fc5870500f0f34cafc5372121db0909477175c5ce0a87d93712df27f44cdad84c6f808930b7537f237b17b9bc3b4dc4ebdc9cf95389cd0a32fff6355fb2bb5349320defe0fd852a4b95e03da46b97d9108cf173ca46fd9875b3bdc44dd4c1eb1f997069c6bbf88a130c28d460c2ca6d12d053959b691b9275c58df3f76fd1688a0295365201fcfdd1cb44859789aa5d26a2e132c9c2cb443eee3211e16592952f13e12f13652f13e52fd28095baaa6a67f78f079a34fb17ee15e5af14d85cf3d1e6cde0796886ed16058cb19c1c080c716c4650c0637aded8706ca12d74bda788eeed13dde1b33fd3a15dbafbca4a783ba4c6a9f73da95e3a027abdf7069e7e2d1f8fbd01b910a159f995f16211f44a56cc85c4d01bc57afd79c99bcf4adc33ab1f33acd2ab229b8a745e7e257ba0baa35e1905bd4aca81a95a87d0a464976935f38393d838c9955ef663aebb088d76de49cac995841891decb11448de4b3a4aa2284fa20e9d937244f814d755e38c50d87c69cce1d9a1fbde3163d4fc92f092e3ce77e4f1ae21d9717dd24eff65c2fb0b22ee5be19bbb74a4ee6e85342fbe48784fe9ad0df1333dc5f9220f8c495f44123fc4e3b5cf69ba4033d7be54473431e3b468124457d92d22b49a4c947aae86749d25284ebfee1339296ace6d2469778eb2f52cddf251be5aa1264de6655722a875e68965a89998de29606128ae508a51553c0652d734d454ab1ac14e0b8da056013e3ec540b4541a6347106a0e01931a7a0de31561b50bca0d3ca9e17887181e74ec1bd08943b05e3b80a1a1b2dd2bcc809bf0ae287a0b629792890467b8681f69c9b81ade9b449f741295d9b0ae74e183d3c0719748e49a9053d37b6116bfbb6d8a3a9dba3648ea615f7edb464beb77ff26c00774a6ab48a7e0cc1bee2d4246b7c5aaccb1d954940b2d8081d77506f9fe4094ac91dded636bb2abb042b1eeb9e90da1422d794f5d689b87cc5a68b7051ae47a8f40a1667a1cf855d25720d92b79c488ce3424827e935c8e8726cf303d46b933684294429c6f746dc9f1ad9d925bd0c891a467292e2616ed44197e4126f4bab7bd83f3926d39a1ccecf35b0e9b10e0dd6e0080f253577337a8f52e343b4d9745eb640c2dff2fa830eee765ad271072de8a4e55dcd49eb22572d91b61c58b67e7edbba61b225d77c9acc133eeb7d115fc4cbd9acc55acfcf6cda6d5f9bf67abd17c5b75a8be472c1b356225a6ac15b2ae3bca5d2d63a4baf93196fb1d632651a29b612314ba64ca5592bcd5aeb259bf245ba9cf14cd7b6dadb5ea7fba35edded515b532f2670cc3e2692fe2d4592a4fe1cdb0b6f1a5c7807714e2579cc3a936582a66425d1142c3170d9ac6ca0fb815dbdd0e8e16ecdc9299d96ad61f4e9393e8c828f699869c08e173bf562de7ef1b411ad9e36abab9c066ab369ff6860f1146bcef7f1d35ed7a6bd7d00deb65792ce7274250363784579a17cf694bb7306cabdc57d418e7aeb0b195eb84e193d3a4f432164e268ade79abbd97fcea3089d49ca716092cd9f7ff0ef3e68e2e18da4a1b5629a83b5f58b8f1a843eca520e564d4edf8702eb2b39c457922ecd340b3bef7abd286a7fd5045353f5655eb012e7324cd54938f92c831006d5902ba58401c2fba220a5579e634c2e65c9078fa8c02c13be7a252977b79bd2f44071d5826d40412100daef1f3e8bae64c9ea180886ff4a91263120e0d2c0322d03987893983d0c34d02799af15ea010c9192d5c2d0d046a9ff90bd30ea798649627f26a5182edbe6a1982c26de20c08bca451129c9cd9b978fac378808a82220cb432ae94a96827315a47939ba91b7dd2895eecacd5fedb4e4bb50ea1a93c1f370bb9a3f35dafda1b83a9deac730de5632492045ff3bd5005e281e4a1197fa874f49b8be95156b72c4a850a261ee1f043376d631c5fe69b82e63a4abe22095828b1dd9e03585a9641e72f69540fbee032fd08e504a78a44294340f3a03dda2ede057864e4ec8a26a1b521dcbc262b4597abfce112ecfe89374b2eb87640a8e930cd94ff0856de63d43ef846a2cb23fc6c382c0d1336555d3baa790d7fedfa08321bb2497868966749a2381ddf0cbba31ca48f6bc49223ab2754b854d1577a9ca683f869eebbd14105fee28db1be0623485ccd32382400cda0f6a0662a702671465baae1327a12b49df05261a1a3d042e2423c7a986b801891dc80174bd254414332ae24aa1c3783e81b715ce1cecd7eea6b5a0ff7429fe16c2e8d25602c2c142d00830574d5201e18e3a8968496c38c77ba94b62d92b57215cccc2c23762b6353a67cb032f29caf53f5989361945b9b7334df8cd66739388597a63bcc35d6fba52f86cc6bb84c87a74d9cb98b8e4afd25c287c9fd3658f89e922cd8008b461706dd187f95c7245a67469bc42a1cad23d99b720772a6cecc9d4ff2c48abbcecd764b241f7c982ee0dc84affb7a67d724efbe48e4a726d2a2bef65e1eee3cbe19dc900dd3791280eda94def9af6d366841e7dd1926bad6d4d45a36d45ad17977898966938bf22842f3ae7d061b4a6b455d38ef5cd2bb3016f7105fd33b72472f878133c81d7882986982b4e29a529a4751b7bba62678c682ce31d1a5535d7a4e4d2492952e0d3fa441f9ccdd1b46ca744dd11dbdc68107c3f68e5e6e73baa7699ac566037f5736ec9c81ba0580d9cafa10985dd8e67a096d853e54e8972a0ccf05bd6753955cbb98deafb9d21ca7cda9087bcf67fa5d2c8987e04f1aa8e27c4bfea9687b405e4aca34eda6a16395874ea7050e7f5995cb1e1cf4f5a590a3979270acfb78298363bd2d5f312f251e869f31212239c98b0c2e2fa5a5d62e744f45b8af648e06c7d10544447e193ae7743a980cf69f4517a6d9a96e56a23a1d7763dedfd0538849614b6f9ab9a59bd18d894511df94b00ade3a6bf941ff00be69358f4b895e4a3dff92aca264f074bcab1299eaf2804cd7cb541254ee1fc6954683fefe51a5ceb3a63adfeafb30fe468567f14c224966f4a524392652a219ded6b7f97f07569239baa1e7829c02062717f4a617c032c9e94daf0ccde4b44de945a4e1e4a28c860b6f66e321e78cf6daa8ad369bb680a82fd49853e992038839eb900d50e8c67627882c0c1d85ee8571c7dada4b7da1a891b7bd9748e0b8dd36eed02ce36e541f539918f4df6e6bf8de59c1b8cf6f516556bd99fd61cf3db9c03efd531e452b812ef4d04f69de03f4410a29d30dcd7b5cccf4eb1b7aeab30b8437e2c5085d546e417a4a2e4a77a0b1fe5c2502dd900b633eea10318ed10d45a7b432e6cd66565c8da78fb91ad10dbda9dc8e64462fc26419f69b4416e371539e6192533f6f98f448c641352e66ba52fba6c76f1517b328922ff22842339a939c4a22e94c7f6f2ed00591984ccdaf1c9359144da30869cef426b8a2379b9be082d6371f804c516cae617891c24ffdca5fd7e0c2e71a04d736949bfa7ad3d0293db5314800f41106a709d82564be485cff98dc58cfb897cb25d4960813f9221fa19b1e9bcd4c07a7ba9a5902644640fc07718c4e75f76f1ade91521f1018f9948e2770cdded08ba1debde2900cb1bef56e827bfcd48465f226e43764c9e72abee9c969962e97eff85c1195ae7dc1e774bd3571b91ae55cb064fafcdbb018e482f68717cf4f9d97d545b78b35c88f2f26d8c53b093e456f7afaf37a294aef3ea76b7ad353e97aabafcbf65a907341d7457001774b90ea057751e40bf597db6ded723b388e6ea32891e88254d1315c6fb7f8fed44231907cef740fe5e04aef4cdf5734bc1f9d46ee65d989f5945e55d4dba7f46adbb09eef46efd0298edff9099e6effcfd0bf33d87e6515cb89217a82c5d6b37f2bb1b7dde6e4774955610a0a7b112cbe2a7f93949eccc75e5ab51520c9460bc82842d668bc620da4469a35fa458e7e90dd6e8c9cd130c731fc6c12aee651749a87512e49e6f4e13fb90534f6ea9cbe97de68dd4b0ebc31f166f3b30b105ef0fbabaae4d003202f0320045f3f3a8e20c8499d200069ddd1603fe278b3792b371bf4161c367e60e8e46929c4890b5c9ebbb1686c50dfeac2b1438f3099a3134dfbff2edde04e9e3eff5d8e4e9ec6bf4b37536b91cf1027e779a8123fb75d58b8fb24ad9ca13d189ace3e812ed059f6ef966f1c0cb00b347b2b01bf58d69207960601331aa62fd587dd8a469c1045af5729a2c21f8bf824d111119830f3775b585c04de53bb4e185864082b4cb0a0ce6b90cea9b731be95541100a076bf58d9bbdc3920e490cc9d1a7720fab71409a242e02fcc049c117cf82e8a8cb185efd80e514fa5b0e686af8147933fbe4ed854b737b02ded5adee54898a6853d57f1d6a9c94b8a9386c3281ef61fda6c1a838a3e523b92610ccb2808a76b097ffe9622a53161e3320abd8ca2be8c854d6060b650acec655ecea8c803cd64612090f5667cc915470a13b029e751f459427a496b53bed9c08f53b06fac183c8249d62bf9fca8df1f813dca6789e3af1a21c41f8db1551419bb3c5537ee8b22f51c4261d66dfb004842afbb8b92f54cd587ce99e41753b128bb6f68f9bf4a642c7509b7de6255185505689ecb4a78c7c2bfbc9e1b55944203b26ada4a900d96742b6d88bd31675e7af921a5edbef7efcc9e17a1acf49b412966d541fc1692f9bf4e51dd08ef2be48e38b47933a2c89af3b09e89d21ec8cc1f13f3dc188194239b8539282e592d20d39b0495d2a654bc8d2b0637357f7deb70c6ac637eefdca6c9244b86be6384f5ceed92818807570b4a29b49c0fb3d5be5432611417a6c993112478af88dca3287b41c5e817979c3446f548fd052c29ea13efe2918f5b62020a0e1b1a96060c493cb2e6dd78410569caab0110e3a6e3b37e0f2b41ef43a506ab2d461421564d51ce8a2caed846760fe7dbce42f9bdbb38fcdcb700b8562c05bf8bf4adbc9ec83ecce86a97c084b70b153995385baa5e10aa7230e1f5a4e72b861499b260db12e0fe09a37f4d8ca244918c70c27461399512a9191e15a16d58a3aedcada90b0f442965bdefbe336f6d9606304ca9a5f2b7f3a9859f58337d73586177bb3f841368038ce8356eea470fcf1cc8204c912d19d9bfd67d5d630f2b23cf9a2e3e83d09a8cada268a557322340cc333bf28cae9352122538c2a5488f3f26173ca38a5c9ae6609babe88f69b119ed3e044d71515ff582f5c91b5fc1ec940f29ef7574539b1898c77aa135cc07c12cffcd8055dc15b0ab7b26a4eeb99e772ef1bdff69b546fa1e3c9faa341b2aaa108475cdb8cc970a524e816d4ec9d5bb1f761719af4fcba791a2ef41d80fde62f2601f45bbfd4a3bbcdd2286c900a0c4cdc15096cc551c7adf0e5f44cc91a5cc64e36597b4b22a0d60e3d1f0558e381e0de27e719f9a46a008f54746531cded17530b4f1053efaa2438787f6610a9cfe2783f8882e3965ab1f2bfa53003a85f3406165a3e8fb876be82a1f1fae72182bfa35a8a2c761301ac7903fb9089f5726d9fbc784914ea7f051b580ec533578d458a533c84f06f766a402ebe0e6cbe2ff6428230c07a162bfd9e3fb3fd6235cb78638c9cac174bc498db725cd6ad934f68d857a35eb7711c1a7e1de1ab15e186880a489b1209f1964620c4731a927c272cd344431ac4929125cdc9e12834f16b48c35af04116a4a4f05da49e8848a267291524518bdd1441e26ccd94dc3cd033e4de6aeb1f1288762884598f0e320641b3783fefe61295c20a0c5376ea784250c3d42acc0910f37fbd5671933f4fe95dfb7665848760752824948ca7a2eb610b91600192369f3d2fbf807f0a21e527d708cc94b9b5f7627f1da90366f17d9aa5c962abb2eb2744760a29c0a262061c265100d195a3cfd5749aaf20d8a97d400da9b97b92d7f57828438dc4b77ab39c4f3cd23fbf18f1d599f5ace7eb43ad4ca089e55820837372be0a03683bebe8eb31a755f9b462d873b4928b301398c5abed205a8c78147c8ab3c42a58026de961c277350d01ba6a36f22a2bdcf504e123ceac7fd4d638090def9942da7f992296ed2d2ce7e48941ced2887cee2906f877bad5824200add4314b503b6f03ec449de28d28b431c5ecc3d604382671b104761c716e74367eb9e97e2d706bceb12df4b9adbad72a296195d96d299b9fe6646e032ebd9b5377ef89a3799f5d20bc9b36b33f528c1f87e004a16135c0ecd6ac15ac0d63a2733acf7a9121440c074aa99320b566b46f3c0c63b8a664d1d540b75072af1cba441b46ac10fedaa85d44b5a667466bc27cc4e483ae81773cc0d1154c4f0d7f8cf2d6cb1de123bcb479a17f22d49f34a624409ae63f73230bf0839b99c06d669f77eebbd55a5eed0340a624de6546eedb965e5a3bae3cef0d1921c5b6e5cf1ca4716075d599e2aa31962344b102349e157104208aef158bb919f47b80950756e28955190af7666c4543395124b7439a9aaede995c35e0d3d850d9e7e1bef7e03ddfe2bdc86e31181f71b214edb7d027c1f8e21a89b5bee3b43f430ec7829e08c2a9c142f66e5b7d50b0d1ec8d20658f7d4d897901b6b67e22573b7799104056209e91173023faff81d15e6a7cf9607e186e0ee839f0e63411dcf2b9a8ef462c2af7075cd8c74692266fc96f689ed671ebc2a05d856a6ac14be1b4acafc3214855c77a94e1096db94eb6166e67741b0d9c184a9f5f473292bae2ea8cadf8b55a9ba2a42ff35a1892e2d834e212a7d176c88a371f84db84f455de0bd0af307e0b8d659aa52ebc5d1e6bd449a484d4eb61db4fe5c11ca16b63665da4a8c1012548f0b22106bc6f58adf116e1d7d4adbcbcbacba0102ee121e1410c24b21c58bb5e0e5a0ec3846a20a0da2b461a2b619a21ec45d546d8731690ef3d29c04b516dea69604555492a08a6f244115df48822a1e4882aaaa495045631254d59c04b54a889793a0aa9d4950559804354825e923f611614f34377f8980430d7983c20070bf7940d698de0549dd370c246f52ad720c700e1e5441f2e25a667e8e253d72869ce550a8ad5b87315fe72ec28fbeef18497cccdad7b1a4cf08dbd0a7a160f79d2b2dc5b8bfb2dd21aecfc5609f08a2c8b30dab9c862b62401f7e5460287129263f94fb3a80be744fd0f203291d29f3bca3a737e59e4e7c4f61076f9a3b70c6037a61abc2521ee450f2493e0b61287cfb73aca9a9b22ce5b758d29372d199ae5609bafd51971d96cbbeeab26392958c57cdab57b1a4fbfb3ba4308383bee5d2f888c76efca1580629bd38b2716db8938465f5dcb249e823f3ba86a4cd9a3f259c6444e96eabb15002dbff33afda0bdb1e5bedd6379b7fa83687191d7a52c583f7a8f8198f27166d37f61e0a7aef4b5c705c0d9e6db1f12bd7b1113fafd66619a1d398f7ca05db70eddef8e17b7ac35ef1658f2413d830f8b4234b0a37cc905870030a5aef744028bd2d5c16cc78aacef3a58f58b6c90f4e3f146d5dbc5e4b34d57d184ac5a1af4241770416fabe3050ae7afaa3ee59e0ab97fd070a12665779e8f810180d7cacd007f53ebc035a930704a4df1751245e18f73a1ac0c0d76f764d1a03d20cc573b5cb4f426182b2176ab3e9838b8af779a8d5528ff6a5508ff7a528e6f6cace4dbda85b1c15630fd75c85ce38b535b6cb88d40b2afe1dee27ea4553835dcbd51d60a267d2d8db03e18154a8fe7f59d9ee6a541430d1122e8c61c3fa8664eb4f01ee755a7b17e02131660292ce939eb44ec6c384fe55a2843022f190835e19df2b502dfd9d43a2ab06b51636f118072e734bcd4ba96f2d8c722a02e7e1bce23c9c57848bfcd67964ab20ebdb9a21237cc0f8bedca6925bedd41289a73cbbe42667c7ab72afdbadeea0c9f136c7c3ea1c0626ee4dc5c0666993c50dcdc8969040e69a214196240f845982e6361f2a9db10acba0dc6c47aa4093b1aaa2514190a232812ca0b81e81986f83f42d5e0f9b19c23633a2681f6b37c3244f206422f94f89346949920268dee7569565982427a6b3c2b7d09dcd1338f5dc719504dbbc9627aef8de8f16e2459067acaab8f7f77511fd218ac0442abb0be273fae7d229786b3f603f44e00ba148cdbe285a7caa181469aed2ddc5564320a2a80d47d1eb4b08d3b4c581d5c7e8ff4ca8c2a72672e1e820eee36116049c6301259191240165def8b398d0ac08c3629ca16a79c90c7af81b470a0f3f37c5cee6f87ea59cc40363f2db232a6d519f9c8006b5b0f68f79c5b3cbdcbfe7893d679fd254d1ac58badfcb7c363788810796cf2795e741b5027a562ad86c3a2d38da7b90476d6f9d2642ed39495babe32b1b4978b08dbf06fc933327104da98d4c6e209b8a3c294f6e87dd1c73ec181b325a4b77f73e47291e1afa0571bcddfe94234552c2092b9c7d770ca6924f3e9923b5d92045dba88d14e5a3ea0e55dd219cbf31e03c6392633641054bda56bd05932f95ca928b5c71d49931c5f66030599aaa0ec698b455119267e8ee22e87588cb796984f7c9d527054e4f9fa8d1bd3d1a71bbbfb5a13ef0d6a605a92e731337cb5c5c9b07d6382fd658e5a53cbde192179a66685580c80f95937ef09c6597b09ad29ace87e624eed5f860320a1f6095ed12dc3b6e2fbe2157dca44cf098b8d3e966c4331a9c94f90755650e4223c75f4a84c1fee3c6b91f8e73df8e53a3f6df73a4aab6c0fbfd7e91aac32d8c512e6f3fe585b4ccdafb942c1f0ca551c30c0532c45b52ea23375911ebdbdad009c4130d576af853eefcbde14f293d3360506b86bd256b55b5d028124b38a7f2bf3204b4908fc96d036293b72e4f23392f771326a74050fbc0d63ed01fbd7bc44721d4adf910586d16069bc557bfabd9673af3b272da9a648eae38b256450232f09022418f2825e8b1d1b8043541ff0b0f154dde05cfa612c4d9caee8c13529abd5c2e91f9e8587f8476ba7f3dfbf0be67c44bc9fc0e753a5d85bbff3119836cc08e61f21f7a5cfda17a2e9c3f8aea76fde53a56901a3f33ba834cdf532b131522cd568e70fd205006a6136d5601db130db5a71c65985c71d0446cb7db5d097c7839dfa64fe063d60612389acc3b5174a66bb7dba2c88aa3487ba0b74571ca7322782d393aa9ba681f86e1ee7e65e8e419e141b802d7a81e052ff151f048c6c3430211d14f4c24f510ec0b7dd9afdea1e05739fcd527d86cb8fd353a79991b7becff86349b1813f35584c93a471a9619a74da4879de0fe1f88e7074cc0cf39f9674efe9ad3fb37d71a2bc5e3d7829c09f24190bf925fc87b513233639a3af949e02df93be19cfcb7225291754eee2d7d14b707dbc976f8cf9ca29f737a3f4fc40c78921fee7e4aa57a6b13fac5bf0972918bd9122ebfb84fae7926357eed0c8e7b83835ebf430c4ae3d94736bd6297fc3d5bf1b863a88e59baea6c716f47df55abb84e2e667c9e083e2beeb1f3f34f6f5ebefa7cfefacd2f9f3f7c787776fe9fef3efcf0f2ddf94f1f3efcd7f979d97343d1876b9b8c5d897c9d484dfecce02a97f97a9d664a1a7eccf6d71f16fe19aa9788af7caa10c7c3d3bc849c4c86db54bc4a57ab44410f1ae9826f818df9757c48ad45ae7308092c730b37a8ed96dc7cb36f970d57105e6a1afe460cdd6fc9cf39b94faf79962533fe539a5e9d15269cae38b4cce1ca85ca32f2a8cc964f177c962f6d766d5336ade6e9f8c4e7f1ce1c1e7ae3c31dffe10e261287132db374885301d906cca51f2870b664178836f4f6cf7cf44f4d4d9bf432b571c81f533df08ccb4579aacd8569aafc4ad91aa585bae46eee667af60625aa777e7ef6e6d5a7379fcfdfbefffce6d3fb97efcece5f7f387fffe1f3f9cf676fce3f7c3affedc3cfe7bfbe7df7eefc8737e73fbefdf4e635fd6b4e94f5d3fc98668a2de92fba444fe1f58753e0782ae7c64aa2abe152062562d7bde58581695d1e51a4953666053b8c322d155395563c7b86abdcfffef133f201e4fcbd2b7e67fd35bc38afb4e7aa71cf556fbecce5e2ec4e4cebc4fd4ed7acc1b322f44c53385613fea6749d04170984a4b53748911dad4a4e3c8a14fcd5135b8ab4fb9a1a24aa4e03fed90e07b6434b107aedeb4bd504266de02f2b9d1f167db7dbbc89a78a2254e10edc18ec40da831211d9d889bd494bf4a56693fa76fcd6f4e302f0c6cc201ca92985e065e94c9461c159e019c2fb5f20f0cbc3311b75965fa88cf3b742a5cd8ca61112da1516cddb571cd3cdc69fb0c63358f5d17b56da7cf3b9f6806430547b1b537f1b6f4915ac3ab9e42d4d654e5567084a397ddd5181f69f1ee36f54ffcb93efbf6ffd7fcb640a61144da8c6eb7e6f70d2ebffa5f57dcb21c84c3327b31cfae9ad12d1fb2affd2fa5ed77895aeefb2e472a15a688a5b3fb229bf48d32bd27a2ba6bd1613b356a2648bcde7c932d13bdeb3cd3e2f12d992699e4d796b9ace782b912d3b8a594b530919446c3c7dfbd915b7e669aebb83508eba8b776f5fbd797ff6a6354f96dc4578d4ec796b9664408fdfb5d2794b051fd29bac07f0c4e7082629011bb826c2c4441e087dfc7cc6ad532e25bb041b3fc1978e11871360dc6548295558417ee6d8911d9c066028d21b8487396af735b56963bc14410d015c24579f8d4a09cd481f13bedd92297dcd94be0174f3727f0da9ca8aba7bd32d29b3a86e7ca3e03319d1c389514e39a97c5d93be9513baa4411d93ae2d0907315d7296b9f7fa18a6f521b6075bb0fbf41399a7d994ff98b115ff54c2d09a10f2815ce7d46c556fcd33cd1501e5b970857ad664e59e8a3192b52b0b47560106bfe3d354c874c95d505bd7527f6af952242b1049c040870df062ab67fc9f3997aa5c3f8a6cdf3d0e08a10347e3224b6f24cf5ab3944bf11faa6589d8566317bdd629bbe22d9967bca5164cb5eed21c429bb6586b9d2eefe6c972a94f8809696abb96bdd642a9b58c9f3c995ff456fc8921e85d7dd9c1a46126e77f6cb84d0bf4bf34da6d93c5c1bcd1296bae4f01fee679999bc3b20d43062f1e7bd86cc5bd3b9314f09ab607c4bad55dd0bd0139a547e486f6870da7a055c50c2fe88d3e1721f493471c128eeffb2ff86633d83f7ace47956d2b376a2976c5256c804c5472ad11aa6a5d7075c3b968f501910ff68f484b374bc4656bae5b6aaa49ba18bb6ac184aed39aafa5c6e62255ad5c5840e0b30e8e4f69ff391f419895f9324d3334e0074f388e8f0cf37b6bf29495502b79476f7bba83fda1f93be8a56265aa3463d84bbc0bbdde50de3d051af1d220dad1bbde3a95ca7ed1467742c14ee12a0e6e68409c39b66e57c5aa979493ebcd46f7d9270d8dab6854e0fb0bba2a91621c552702c916abd8758d2e3000562014bdaa284b8d70899bd82a0a0739f0adac696ff0e2c58b0161948f33903ab55141554551fff96b934aacc8c63ace2654113e1613ca88a059f0f5cf01b356c418e2948ffb13c70704d65c4148cc717f52b029268daa9bc33a5d9b3878c2a6571df727d465f337b3e813564c367bce864eeab4ff3dcaba03bc372029e5e36442244dba0392533e96e50fa651d47ff11aa54460ec0b73539893148f104c3c27ba25a4279238366529d15d435952381105ebe8bb11d5750cbbf3d9a45baa3921c5eb8a1f7c9aa9b762c66ff754f13b880802893a792f99eda95e32038c7446c713f241fff7860ec847839abed203f20a42bf41ae68da1e1416beef51105757d1cfe883772f50a514be853215ffa62b15aba04c0026504a52eea2e2e94a241877cdc39e5ca1334d50988f86da51cbf8fc04e93b11c7a4fd1217b8e0333ac3f8a53e7b197a5b4ae3561a7c1431f42309c6b6c7c38fbc3507d3ac4814998f250863bd527d9b9ff0ebd005f7798f04261fe1dbee0b1fa308b5d1c7caac5e08bcd9f0286aa708e3a1d3987df48b57f215b82fcadd4e7decadade10f584a582b0259fbce732af050d4f061934e291f059fc9e38fd4ac6114fd86ce30798f9c0bae7e1c9a3906be081fb151fbbb3806c681245cea9959ea59b0d40293a5c69c1656979e47f710990144061bf249ef7ac52ed3f945ed0d5ce62fe7067ad4afb8bd0501fccb6e5c037e38aca8e68ff881b9bf7fa732bcf3dfce96dc9b5d1d8597f1dbd58acf34abe35f0fc2d7efd21bffe2307cf15e13ae4bffee207cf7314b35ffe4dcf283373f4b9efdb04ca75760d76cdbee97786aa0c05ed532097348e01d825489a67041d4dfdcf269ae1b8497cdcbcde6d56683fcc92af3d485acec63089f0d74ced76abb1f41351b5abbd51b01d085ed04bf2d6b942c687cf5a06121c25ad3180c7050cde544bf6e0d36fd3afc4a5559725f488ebe52b12d7d7dcd72d9bc4a154103d0ed1f592214fdbdf42617bf266ae177afcc55d5c0bc3c1717b1d1007879469c1e0433e2e18cd44333723c7f03cc10415287a86af45513fd9d7aeb94d471c9696fc697ec6e98d38ec857173c0bd08fa631f291ece6b12469fd7dea8c2a47fe57ac9181414a29d5bf494e65614e789fcce237dd2e71801e0b52429a31271e15c539a9d8b8a734efa6c4df4bf1de604bf2177284820b97e6e40a7d20dc3bd21a8409c984d107acef8b518270fc933e2c1af9e57b12634d2e047da470c3714c6a274bd397a5cd59a4f972f65bc297b306ed70754bf4956885a4701f3952c2dc49c5ed248ae0392e42f3d4a78511a54bbb21736ff5c2d96c52543ea237195b37a2207316bfba815566d474167b6cbd5ede412e73e2857b1568ded6855e7f79f27dfb2fadef5bd305cbd457b9b75ee69789d8932ae36ca5199aeb41ef999179393e53b0cbe4b67799a8457ed14bd227bb9aea36688a5bfbfdc149ebe555b248aed2d67fe592e90ef4cb4f7cc9d94eb9d65f5adf3ff94b21b52b1fffb2684faf3eef2d98fc70233e66e99a67ea0e75ec79efe011eff9b34f94a66bd403957dfc88b8c8dbbbe0cb35cf64c8c554f576159986533a3c201071313c7b37fce22a51af1eaab24a7f7ff07dfa706bd9fcba417dd420fa0133198409b3f1be0d736c9441ba4aa8d4b2ea8936efcd4d2dc0ee6f5f3b562a34b980e81ee56a10a7cb0b728c54042c75ccb04886b7c33fd1664ba44ad70f8dbb483b50ee7c68d35d07fd294c4c1cad566d925bcd7c16d092d2446ffc3593446a5e64ca96fc8c67d7c9946b6c0c715a75d9ab544895e5539566a8a3f177070f1bdfd2fa8699fad43a50d24ec6d9d274e10dfc5d6b59057a8e47b53a633eb1465746f8b0a4f76b96c950d5583846d43d84a2a85626469c2a6815f35662d590e9bca5361b046f342eef25f217b64c66481f56b0a5f830475687b92d58ad9987b0a497c8f7f972f921fb591f415424ef17459661de4bd7ba9d713a2055233957e99ccdd85af16cb35982557ca911a3590f56202309659b8db134610a725ad9656830428b22945286528c09aadfd79b4d1a2ec57b788fa328913f2622511ca578b34129ad2d66321266342825098efd4311b12d1d75d318b146f17cb2d9d40683529ae8d57bec90c24fa6788b388138809f92cb850922a03bab582b679b8de865692e66905ab55b2cb9b9423fcc51466c0d8c4960183a2def94db1907e5b05d70fff857e616923d7f0db9b12416aeb2d706bd23315613928dd504dba0fde30e5889fec0a65797309657e932cd3ac416a7d98c670d45bf2633b570459fd82cc9a57f4a8d4d9e7b3e53774bee1e7e4a2ab57f4aaf79b6e3ebe65d7d084179691c50eebbbfa8757a51eaca3c9d5d25eb359ff967d7e1a2795c8bfa9016f5d12c4a03590473cefc0fb74a93e2a42f429cecb75b73eb5980c1dfbe1e8a2842705b812af19a2d91f008ba5ab956eeda04b69dab1d1fd690d8b1cd3a7858ed9a4aaefc08508d5eabb46ed76e1eebaf99124972b274504d6694f7921959980e663613700793952dd12c430793b579546ad9c1e4dc3c0007d6c1e4ce3ca6e293fb3eb9a6bcb762b7e432d093eda144be67efd11a8f16dd55bcc6c3bb28ba434b4c96bd19530cfe935cc906a3b02959d87c544b888d666a9e72c5d0029319c8be6e5fde26f2edebcdc63cde9947231fa353e89d64d4d9fa9173235363b43f64cf334ddf694658aff68f6906dc016264819f5f0fbb5d86872965dd7dc7eff487a669fa70537a69da4acaf652e2660f6eb026e639bb45726f9ff43576edc9b5264c514a2426f366b3f869fd868d227d53bdcc327687a6633ec151a4ff84bd6d3126498f33c88da79761c92ef8529252d7452fba4f5e6def184c8feac5b83f8922e473b4a4649ae642c5728bb7ba411e45765bcdd75c872e147cde83fa7af38d6f34ba5f675c6af80623e3767fab913f26b5b3643c8dcc6a0a7d67e8a34cf4b13202fa8616626b7266deeb01c5e3ce6d87407a802c5d7ed4c8ec63c6af933497ff5d297fcf6fd57f7726c44226b49c1095a64b95ac5d3f2ce3bad2969cfbfeef76f4ff5b43ffbf95fabf2bf57fe7faffad3309a894bb927538c4db3021e532b5d9dc6f49aa1faf218afffd1648c3f3553ae34bfd08906b84f52a14d677bb99131428504254412dd7809b8cf3c91e1598a44daf5313680aa5ae568d22d4b5a411f423696b0502c6ebc7a02b8f33e735a4b52823ad95416ed774d9b36b4a2ee975efdce4672117a1125f53883fa559f27b2a145b223c8288b937fa922182ae710ccf0baec91022e8390497fa1e5deccd7a0bce66f8c99c8484dd14d2eb5df34c722049f6327f062bd88ea01a77c3ea584ee9d950ca0a2c671e3d96d3db9a52d3ed66339e1049fb24a7a9db63f93c1f76bb12dfa1742c2744587c88877e241a19fb075b41ffcacc81be8ca24b73e61b86a7dff4ce6d0bc08098acdac178a3c83cdeb9e1dfa16b22fcb66440a3afd8ad8655105d8c0713a08fe9c5de42bf4a44f1aa6f5f418bbd39315b402fb626ed6aee3227dc6bc23261cbe4f780bd082dfa87a1ed7f51d98a3a7820e720967102b71ebfcde0b4f24d02115b2f3003b60104c3f134888b1824d83c4c12920ac3902ffb33c319a1f0f68628a40dbc2b523846acd7cc902355b24bd3c7d61865c23e14a70a939273054cb1617171fca86a5b729127cbd9677db81e58283b71108b3ae655596783f6b737cb52f3e1888acf368ccab082267a9fe1e7943dff2bf635cd485ac352b28ca59615e28dcca8ea5d684258923955bd59228d3f54920ab2a0cae6fa202b9ae96341d6fa2fbb25e794f5b800f36b7217000c6cca9e24d7f46e2f2597747cd75d92bb898fd66abfe55229973f483bcb4470967588fb2e6d0f087c98ee0df8e088c0c729fcf4dfa7edbeb34d35e2ab8260219d55223ae4fe92abb8ae63b8de127d0f263d91a6eb2d7ea01376bbb393cb9e5c24738570a533411fbda9850446af70f1c06e2d2ebab6e8ea8ef8f59b55976e5eacd9c22ed9ca2ed73a58ab73e2101b1ddfeb0d8bafc93a95717f4bcce31d3c0eb61322b6649ea847c07e38d179a21e4668ea0f203207db3637b32ef03fab5728a0bd359b199ff2b9a207c43f033b0f050b30f73e6599fe16f876cc3276d3203a83490a8893c632551c6f984119078a07e6e083c94fd52d1cd6cabd7f0f196fb8c93ca3d275dc27606619f31efc2517a952e92a169618d8c6a6451f2af39e4ad7b681b0e4836dc07be6c77698f6a6cb64fd32e3364459b85b7af24ed41e6e57dacb45d1ca6a5e1ed1704b665caa2cbd0ba12658b945222b8b6763617df34adb797198706006f960b28002bdaf5526296e9096693c0aae76bab1546c05f1dd324f2d8dd564cc2785c8a52ca463901c8c063328915a633581df633e218ceac606bf20814733a3d91038b6bf32cbb8689e0a13b6dde2a19ed6652215cf4070faf96ecd5121102597e47e6d7384c51db3d71d126284d82353833262f06fed102bab92f1fd96c0893722d12c6e0f881106ea5fb948e02fc848f40f7bf07ef4351299fecaf9d58cdde9a755227ed64d3aab64b94c249fa662d6293792f17df032ee2ce2d52a96b2777676d6621d5229d645ab44e48a9b22fdbc48f32cee2c5e7688fe6ae7f4f4b4f5ba436e38bf8a3bcb6587ac52a116a6fcb7df7efbad43fe99b34cf12cee8cff36f95b6bcf96de7196c51df80dbe656649cd7ae8dbfe9ee52a3dbb4ad67a62c6a838eee8b20e815b36beb7d854f38d7aab4cdac242547e4a2faca8bc60a36e500175c626d9e018693438213b3a9400586941b06aca9a49f5d2b0128c8ade79f09cf6ce2ff2f99c677cf6c9b824b4fb9ac2dd41e5a4e149d79f6a683f28770a2a016396108e8466a43412ca48da63462d232e47dcfd4e85551414054d721763aca04f1205a62db51e16e8ded133f1e0b8777cfc3de23d91afce145fcb3def90a51ff156938671fa4d110fe080b4cef7f42cc3bce4594f654cd8247c03a0388563e6a2c8455c437aa55142d3025bc1fa9ca6b9e4e0dda739d51ed7bfacab114a30de7a1d9eec5d2ed30bb6ac633d1acc9a1f1220e0e23e993b63cef8a04f2c19170ff801f11231e3cb0414b70660a596251dc82da8cb3bfe3b1d72c1e769c6df8af0b20fc486c58882dfc04dc0fd0870ae7966a31b8208dc7ef6ef34022bf9597837f30b10b4f325d32b5aa43b241c0f55650de9bd86e2b803fdaed26bde2100263127029ac782dcc659ef96dcc559ef6ebb1d8a1e9bcd4a2340a6f52cbd111d92e9cddc51235f77c02983cd15cfca8ba2f0bd8b764e6f40f223b9fa7b9aae3439a2ffda979f5c39529a8f80e5fdb9c272050b6c2f3e584e50ab79d306c87373fbf296835a6bca14129aa9e512371f9fe27e005ecdb0219d72c166837c0453d9d377446fcad63ff0df139e819c48d2f6c07af5d855a88dbd9c9cc78204d178677861e40e56415891fb955466975184b2885e54351975c5480f809928f3d7b81c653b794981e39daca428b19275c175693ea18ea6763c7bfe20928c0ef8c113e4a5ac82f4f16673d0c746ecc5a47a9db11bd1cd369b3e49028e55df0115501fb2e720d5e2051ed5b4b2bd09bcdccd5060ba070d7a25f4926ad6d87f94b26ef62219b138010127c40330006911dfeb32fd5becaceaad3808b12d4ed6b4206134a43f0b62b5427b5a62d583712198112186754a614da3cd90af852b40c2803ca699a19299a18c6966feea937cf7a8deef76f5ae52cdd56a529a59aa9966f60726a705f9cc0d151f1c8ce635c4f7a721fd0ccdfcb2c32e7feb2839b14b81f08240d355e4a82c624c73154a1f2c1f59ad0e83af51e93be05f3d8cd587bbc53910cf538ffc1b487877258387c91fc227fa5a85992193de84bc0ba8b22b6a90b4fd63e4d3811dbb9587da2f692c0bf19598b8e4a7ec368adaef2a0c40f1721c349ae062431bdf0fd50b08d0464591fba36422ffd04012f1c04012f1f0402aef87ea797d202e4f4beff7345dfd68472569e519aeffabde9a89b04af8686b945a1562c9badb2584b800b2b841312ebfad1827397d57bd49d29e23a188f43f315936d6d4f495aea6ff6232a3f9f7687f4fe121a37569bde5cef744ef163ff14f868d07a33f833df644ef0ededb47e0d73149a87a3e187d461999e1f837f8438aa1d284d8d1d065977d8ff2bd0457d77ad74216d9ff6a4bc81eb184497d6132bb30cc2e4c17818104d846fc98661f935bbe440aef35948247b29d897ad11f7d4682247ac2fa8f9e5185586a3019e4bdef7e3747f53ccd92cb44b0e50733faf87ebb252645a46d0e3795e992944225bd7b08833c608ba17ad58f8e792f994df4ed5b79017afb6c8444b18b5941bd7820147635c277b0aa31f2d8da572e4aa08a217a6ca42752f006fd2d589165f555d4dc9425561911609f661fb3ed9678bc18d0f74c338d162a9cf001dd6272bb45021d0e30110862fb3cec6c6cdd8cd0feb33e2e102c43f8bec072897e4acca87f6599f0315a19693092c4f7be21b718035005a0c9b44d69e6cc95214a9d717d7bc596cb445cb63e66e9faf3dd9acbd6355b2633a6d24c5ae7e1e59d7361f30e6cad8b3b30ddfcc73a4bd77bfa2695ff68ad4d44945eeb67c98bfe7ad3059f5ef947845b2a6de9fdd11dac7aad4f9ccd5aab34e32da6c0dcd47b35e692ef41e3bde22b1d177241f64c58a1b7e29a650913aaf54b922eade18d0cf497aa1042f3ad09ddfecf3cc9f88c726b3176cfb28cddc59c5ca4e93236715a34cf04d650312746cd0ed6d159222ef58fbbd505546542b783f61fe6b1223ec822092220c79cb8fb172a8974c67db750920a5efc85268ac80583bffc964d55ac487919e384d4a022660129e96b524144830df00e3ff98e0de061c3767c7c797676fef9a7b7678dc13b1adcef3d54ef3fd574bd40fb07fb1a950b743038d294bcfe718289d43f0e9e827f37d23cc012ea1eea2b45ff38c6644a3b63b3462d23129c74c89c5aed4321b4296bb387cdc6c34490055991b57359ce11c7e48ee69a04bba6e723ff2530b798746248317d49ef9ade284c2e28baa6c12b2b289a7428bd1e4de36b4ce9949c5274b9a3d2e5681a5f42a51b7a4d29a438bf89a225e2261d4e7b591837b607c373daee930bda1e6c4dbdf6855389ad371bb486f39c6172bed9cc10c723569a720c49c0c8b52f30ce8c834860976dfd228ae60e6776cec1427dcd67e7e71d4cded153ff52555eea8e6e371b9f58fdd6d971221c73f299be1b29ffecec26cb235ea12bf21906b6c6cecbafddbe892254aa969626842be0ac3178033234326b50809f9fd3f1c4e5dcf89dd37ec38170907b0c0c29ec760065c652a611ba425d88ff1e11348370592eda0812cffb4612ee6d3cf60623659c3863e616589001267b7b7ea81033e4c1c1fef931b5c4f3fec8c8bc62351693f160f2a73ee592c1a0f2d7387eb137f8131d06bc75a93f463323f772d9779ef747a8db2d964a1867de31276a82712cc64c4fc9c6417f602047278d03a94210c0e20340d408863b7742b9c4ccc5848aae959dd023bf10b6779fd0842618f1fff91e164cd67ba82c1ce0f8677d83e29fedffa11d059fce9035cd5c605551aad3669b8db399793e383971b82f0df73bd8986e5798f5037392ca47611b13947a5e4ef42437313a822e820e1e98fffebe5d80fd9323bb020373c7ed1f0cf41df7e47fbe38f4dfeb8e02a3fe2f93ef9e909c3a4ea540346459bbe13493d553e919101f644a97952b8fcce9277ef9e6768d3affd3e9ce0c2699e25ec6d74b36e5e8c9f8cb97fff9aef77d7784f0f8cbe47ebb993cb9249d2f5fbe8b3a41ad72a71b4ffee3def72334a25fbe7c4178d39aa7999e8a299860ddd17783def7a30eee76beeb3c8c21daa89d208e371ba6af39cd0ae8cb6a1e4bdc535c2a9482d5cd030863a057bbb63c0965d51549292b564cd26c94f9c7cfecd2caf91f449c89bb0e25d6fcd3584ec0f10a9cd26d7333ac763f8847670250a62ed0ac3bd810546a641cda6367b8309613506192a67352a372dcf01f46c1a20871dbbc8a165a8f35b4a28c3e19ff4f6fd2fdee498fdff2296251c4206e99fbdb7bfbe6fce3a70f9f3f6c369d0ec6a3ce19d0bd4866537c3ee875ba59dce93cbce5ed248a9256a269ef07ced1091e77cecfa769c6f7beca73b96019101893a0efec31882c088ee5f295d8fb8d8fd54397dbfe893dc91aa52506a53d702718fc4fca88e57ec1e42236b7c48aadf52f946c360c3bbe015e35f9e3b9511cf4fb661407fd81259afbfb9668ee1f58a2b97f18b08b7901b17b031b715ccfba1ffba80ff3d45ecc60308ff0b0db55cf858f73a117666826c515cac6fd09c9c68309de6e434306684bb3b25504003265a5c24bae68522a593049d35289e48aca8081cd1f38f2cd374af56ace46998d5872bffdd76e6873e779b170e933819183ffc61e55a341dc27ea21bcb5df84b71ec3b834120f1001d75fa8c5a03ae7e7cb74c6e4e25c03e2b9f7523c3f87d0beee240877f1799a93e3910a5cc0feef26e2d0e3a8886ea2c7110cece1c1fc2162a3ba73dd70c347fd7840c4984f68989c5e8d1e58d3f89b74e5f1c1c3c4b9399784e30748c15df0f50d50b69e79c39acbde6613f8826d361d23c9b00f1769bae40c3cdaf4cc6187cfcf41276a8393d387d0f8eef99638043de146e2f44ff6f54d3275575f05a4f8cec06844affbf001eab06beb50ca006ebe0106cff62d521f38a43ed80f5078fa07507899177198dc643e9ccd1007bfb634389a6c36a3e1b32698c1fca48c9f93001ba7ff02c760d6ea8143839b16eb5f674a7653033e2d815edcac6971bb5df13c1be2648e14e26331219ac72c2223fb587c7f90fe808545eadbf4ac8687630318fbfbcf1cfbb06f6ffb8113910d9e61b2044ad66f9d45d8644697a3a573a07d88b8b551c497644ae63e9a86b001e21da3f29a29f64bc26f26102c9ef72eee147f074bd5a62a78da6cccbb0f604debde99a74272c529ef19032948a76b7e0e4b1f0451cb0ff062d2891dabf0d087db53a40f80662388f9a130c6e55e7f30b86cd289abb3e3d532e3f6eabfdd4a509793aeaa7408f2f2a21237f267aae06f14f19e8bc4062601f0b3dc8161d2aa1f37647dd02fa5aadbe9949b9e32dd4ec3cd82caf2ab33aeecab151d4410d278b1d9a005cd31e180a6da569c1045ed553982f89ace2d2686b4445ea648a91a661bba4fe61efb0d8ddc34358e5d0bc88d6f01c9c7ab28ae31725e1924dc3206a27c62a099635628b53f9563ca6bc7adc22df47e4e847a0680f347598412aeb5ce75b03c7e1ecd01f0337c2fc6ddae9ad07146f8040cddfed09dfc073fe83fc79b3e55e21af6fb7f962c038400715f9d9fd920121acde83d9cd1a5c3917adbdafa96c43ec2703b2f60c921d9299d0da77b7b96b798d3e5786a23e7e5a33944a52d68bb392ee4db5b0bd901302ea2c83c163efe0b0d9606d0dbfda12c2e66f313049b6e246b9a0fbbdde9f3d9d049fcf9d88c6742eea81acf272691cf3544a3cc4709ba23e7644e14d11c7f9ca0737247e610765ae230f81fa5f47a744e29bddb6c52a8a51750e2f81ae3fb156ddb2c9c5b23beee0451163a94ce2140d82a8ada56117169d295b82ae4c2e4f872cfc3cb36bd88a2522f9a95ae17a9286a37c52ebf8ca2cb8af14743ad8b28ba086b5de028422bb06fb36b2f83b3ed7f2b4c560fc2a5bbdff60f2c53fd6da28e9304d2723cd0ab23a7768a8f5df504024d7871b126f393384309110d82a64793104e7a1f4656b434041fb3ae985035169e517c885e3ed83f740b04e2c3da095edbb3fb56be11f98a67ec62c949eaea5d72159c6f83622591341d3549862ce1339ec488db1ef4666620750b94fd0505e3456090ed036f6316acb7fcb7116084d13e49e878e256d1ca80352d365428057a0cdc5c59b73ba185e036799c1ac8d41e3f24fd39289495074eeee208b1434388ed1f1c19420c54937521ede3b0ade33712835fdb228a808899c2cff62c8a6037e6feb13d8d22d0552ea8d86c669bcd74b39993155d8c32e417d09010381e4fc89aae42a601501f48df705ba388a5dbd273bcd92ca208754ce50ea5e79bcd541718e72853d031497ef403de6ce6fab521e0eceb82260b0a3ef80ef06623d1395963bcd9ac8cacfedc1fc72ae678340439877800173ec4d9581fb920b158f690c6c20ad88e06dfc0440ca440cdcadbec910c4810c8fbdb237a766820ef083408f7db613af65fff71993275b06f35d0135a7d757cd8f4eaad2391eae583e31d2f9a3f52505b4d2f5e2dd96acd67bbde377f4bbf093ed6ee93e065b0daa5464d1d95b887d21bcf01944a0bf6a65acc2b4596e02f2fb7ddc54a31d0e7a512c753940a9d1943a9d0b105a542a0eacb25964f2815fecad995fd767bd064125400740200cd3cd6c051d46ea7630dcb55d4f80d7ebce1aa80744e0d405eb32103fadd9a7c47515b05b91c1549288ba2a63ce9c649b8a8aa2fc1248a123f4a88c80c9cf1944b598e0e5ee418802699b1fe097ea24eae9265c7a4862fc2256e36e05b73914072d5e0a7ab5fca43844b7723b6542e78afa1a7cfb0f127df79ff1c3842e0a099107894845553a97a3b7180c26cf69bf1c45f07425f07fefec7fe9217b8425542e25265d076815ceb72c86685d583824f6097433ab7e07d6913156b5dbf6cd79b8d7890403c38c62848c263fd95f1bfa04bf285228478247023d017037956568f1f1c9c5865ce61df8a770e0786aa38f216500360bc50a6898225629a1858a24413004b9462b2a24b2431d1fc0dca820baa406b6dba06e94806ff07e8110db0be8959d00a70876bc0f06693042f3f66e92a91dc540023c47479cd11440d0baa01aa727da4face0f5e7a04e52a4850fcae1b8002c81c51b7f9a2548d4ad0e2c45e1915a3251238ee748c4ac40ab4321b1e7666452a0d6b64621d4fab1560a4e6ddbcfaceaf8679bfa8be876530ef56d5777e150afb711c60ebf50330748211483c48c78dbef30024ef686ac7fe275a9e71f5275ad9f93ebae5e14e013d582a169a08884f9e69da9728723f4dc53cb9cc812d8adb7dc23d93a49f401e1a0b729325ca966d31e881e983d214500437de1f99452ba4538e7dd0292439e87e4b3a1d72aff777e7fdc01e5a8a237b131c5a99f0c191d700efd662d4f05421d04991c0a32c666449d548211cdf7b23d11c32f72548927d4c96355cb60b2d1a4704779f304d9527cd8275f63c09d839a6d9b98ca4446844c63d1ff710bd7e70f87437681056121c94a47524c1f70a31c281d92709d88557ad2dca5fb2d8fae0688051f6e8fd7226500fe8981c70449101dc87e51b477d8cfef065d5409c356e93bdf8950629f03f924134222fb9cb693ae6231977bbccc8ef20993d049a2239496caa8202993d24ac3dd8b9814d60cb82d409c207f71c1ad24678d28643554fd3244504b994aa5112ef0d88a43e8ec010a951bab71777bbe9f344d3bd8336a50cc9713a01d1e7b030887cf03e3f3a7010e2cee6f1537f36cd7d7efcec61beb229bde0c82957f92889ebe4ef28b526bde3fe84f0f16082634de5c5df507a1e1c399af2c8daa6ed1f34db39fa1b9805d2b24161a61a456adc9f8cf727a304c1affe84c05f3d9406d2485048fb06c69aa4992fa859893fdd313423a02ecc02ed2e8345096d27c35a3ac8b604a808445cc3d4c3f5928a710a109d47d152cf68391e4cda94f2f172dc9f4ce236d27f415e5208a7212f8c861d69bb9951647ac27a29a6948f67134da68d0761df00c95e683c8da2369ab52a5dfbcc100babd1f542e9154dd094ccc90c64d08baa0c7a3562684ea6e480246481e355d0a753a13c64c8b1ef49d39d12d922b78951b31591e9845fcf04449d3683cc50ffa6e384a42443299e6c77700ce1389e9e38187dea4ed4a13951cf8e9cdced9993bb9d1812f9f8f09b0825055e57228547395a42c0c232a41a7062257362bfb69aed03e38f04dec71924873f7818900fbf298d66b462929619c55af5f36c24e2072f2a6375fb64fc3fbdf197c9a4bbf93246a318ed8dbeccba68147fe97d9975f1086fd0b8f31f138cf4bb51fbcb3e1effcf972f93cd972f3dfcfd087fd9c75f261b34a2d062f365fc65828b9f9bef307e724912fae4cb17f4e50b1e3db984fba2c6ce0367692770780c291ea70b96bd4a67fca5427dec19c84e4713bcced69495ee6a9b0ddbd6cc46ccd74b48e7bb4107c762b3b1c1ccb6385ce6f48155fa96657c8562f0b073d4ef432274a33115ce6a8e18351cb8fa4e177c173b5cb1fb08fdba9cbf6a438866cdd29a8ceba17ac6bf563647a646119fefd6dc7a6ebdb95df3a9e2b316f33768c7253808e857331c1fcb84304d07868903321c83d95f02890ef4e420d4f68249c4fc8d9b80328e99fe53cacb1d0c03fbd3e982d30434728c68763021e9b6fa5ef01bc47ae0b4b4d9649888ad7da219791cddb5cbfaaba6f0e874e206796da319c67145f8ffec185be3e19ac9454ee5487aa3dcdd36172019835daf06f57636122d889a95047a4e06aaccaee16ad3e0453eca9d9e5cf3bcd6c84d57b4c445bf03692b064f14a57b8327fd5167afdf891fa7a67eacaec688df33ecb435cc88dfbde58c57b73d84c28e1d97737cfc4d646e4e0607d92531912fffb8253074a04aa2af07b1f960a73ec8de4bcf0ecdb5b4fb36d21dba055dea059d51a4ac038e53a393296d0f86ddeed22baae734476abc9cd80b7f4afde875a77397266dc8291fcffd1d3bdd6cbadd659bce46d3b8dd46b386ad830b7186a32845733203855a618bffc704c00fea348fdd95fed4398558b7bf5d2b5592508f8c3e12c7ec0ffbae3488a5cd2aa8c2c7894ffed425fed037326ba7fa0d0fcbe6a089e050c7e5693acb97bc43ee8dcca2dddf62e2339294a93287571472e17893220b11db6c3acf9f33918abb559acb172f3a24a7e966931574b21867138f7946811fb0f38a6d75ba49b7d3fa47a79b773bff68dd30ebf9bbe6d3649e702061ffd1e9ca6ee71fbd8e49d6302cc0bc9a899acc2cc258be381e2df78ee33e26537a3c9c3e5f0ea7dd2e9e8da77bc793204bf5b4d09cdb2bc662dcb19ead2409c9272ec8cf0c639bd34905a9cddb83e03a0abc7d4b75faface09ae1abfdadfd846d52bf68bb6fb44f5206adebb445c15c9b24bfe2176e39994c9a528675f2948ecc150d592780f55b7eba4ebc5faa842929fe9ad10f81bca027363089241e8c771363120e0b3d26f09a3120934c0e6b80ec0045197ec1f1ee2808291210680f8ea7e25463cbef7c97602d7ebdc133d6d544e03829b499a574c686003ef70d69a2e99942d264b044ed1fbb2e89d07dd7de2739e7131757d42ceeb05834cbc179c8b968b292cf9acb5d792f99a6708976ae8eff39917ebb5d566538bb5be83541bf1586d0d93d8081b3b0eb35fd9dc90540a13ab3eda91e3c96f60194336d397caa7b2da414a9ee94568f1db75c6a5848408b9542d9ea805cf5a171c10692bcd828d2080153a5d4fcd0c83407a0ee84d0a7b5456df80dcd6cbf22dcae325e1ed2014da928a9877ab91631439158fe4eaa3ebfac37cd4580a6b136b88b58264aaf016f036090f8e09a3d790658f39ec6067f4c6f8f6433814282719728e27eb2c5d4b726fbcf63526c75ba2b6a8e8e255ba5aa7820b8587058e477d92f46e12b5f894e68a6718cdf0eecbcff826dbd4004d099daa0a73badb9fec0187b16fa7c6b759f8ffd2fabe6532509bf9ff3f961a9f3608ed8cb5551499bfbd799a1146b351f1083148a73e825c07c7c7fd41ff80248db5f4beb2a5ad74ac79ed864af38c5d067d3d05dea45ecdec182417b0359f91bcf9ab90499367a6dae010eccb1bab5d273357ad7f42668dd5a6a950fcd68e6ed027d3c65a4cde896930b8c180cc7775672356966b2f9ad726cd6e58363bcff8dcd6dc27abe6e5c9e55a8389ad7640d60f563b5f26d2ce69bf4fce1bebaef82ab5dd1d91bbc62a4bf6fb9dad724cae1bab5c2cd3e995fdd2805c364f331733a661c001cbe029b968ac9971b94e85dfb5c13372da3ccf69ba766b711286613506054dd618f62a09a30f7d67de0ead0656590d2c8b5dc64e1b54d1964f63ab63853fa9f9939b3f322ee9505bdca7f02cfad2d487fba657f65ab52cfcb9337fcecd9f65bdaf427c033592a0a020306ec3147960a74ee75bd57ba941f8349d713a251a9d3b3885a2b929d227e1552aa4bed32008b92dfb68cf125d12d5b3d7086544f57e3400fc89cfe9423fdab34e53a27aefd8ef7710d4fc94af527a4e54ef23e00b9ae89ff610d39ca8de199c7d1888d48f1688e98a287d5ff88137b036b7c00dda694eb7d0a032b75b57589a5d435fb697d9366ce0a7bebbc1d23470ebd270b13d008e2150504a99e92b58d7dddf5dd8ba6ed177d74c4d4dd891ddb5ee4c2dd8aeddb5ce4d2dbb97bbeb25b69edbe8dd357353338082dd75a5adeb406477cd95a909a9fade14518d9ab6a7961a30cc48179672bd96e6cfdcfcc9cd1f69feaccc9f754178376f392aedf9dd66537a3eaf3c2f2bcfb3caf3a2f27c5979bea83c9f569eaf21d1aba139e9cdff8d44a051ef4b58a134cbea42014993cd4614420135165e281088043e2f78abd365461aa0197e4d7c654e4ea0d2d68a5d71fd2ed5efd874aa99878b25872011b9e499d48495e67ca54aae794bf1e942a4cbf432e1b225f3e942f376729a69962be36cc633d9eb145addbc2e4d585a6942fee26894ef1dc57d4c66f468387b9e0f67dd2e5e8e677b47a13461b6539ae097c94b13962006fba6482024c43bfddea0df1b3484c1fa8663c25051b5d93022a8d07f927ace473efaebd987f736ed22c7b18955966a9acf6497f6faa2a4b74cc495dc6c821291ceb80c58bd327bbd4cd9ac7599b1f5a2a5598e34572de802c870686a7721a5fd61fadc76579875f8ecd50ad977e3d40a2cf35a8edd64d6f9ffd9fbd2e6b6756cc1bf42ab6ad4800453a46c67910cbbb2dddbae72964a7cfbdd949e5a4d8b90850e05ea91902d46e27f9fc201488214ed24f7bd99f932e52a8bd8b783838383b3e0c39efc0eadabb28e36a6af408b0b303d37723e00a11faab8154f533531780c2aae2a056d5c1e920dd82dc7b9dd4f18c5413f232a90492bfbd9b4a1823a8b245e5d851dbcdfb724caf8ea8961a8aa0f87e13aaf63b97474bd30b5aa16274858b9878a515d73f10d45aece4a225765340ef82a0d9cbcb418f8e279fd61e951c6ec8fe030a13b58bed1644a607e4693694e02059b870f663b1e8e98cbc37c5c6aeb33e862b78bb44f0713b6644509a7a2b52e3dd4112bc6ac460c7e3aae7ea9fe030d3a808ffab39e815e785cd4cc6ef06b650ac0d4370a68308202bc2800bb516f52bec8d0c12b448d07deb0e8c8ac87e9c4bd65f2813121589a42e56546de78c34edc90dd250c4c39daf962ab424bce15310c4ed4add1486209ac4ec4f418aca060ecae82356a51f9d97d63d9481ac9396d31058cf03faad9b0b306f3860999041197d92820bae756146fe39097359b91c2dcf99668a43d599038b413e7519cb232e9c44e62f3b96a9bcfb9cc20f5f4809f52ce674d8ed91b6b7e62297a54725ba9374ece4be1b6a44f7d2cfa944d9229802d480cf823af12252a1b48fedb0de85df24413352c70595432f2da16afec0caf74c90ca70e6ca880179fdb18947a28921469d31072d9c1ae8cafe30796bc09522d08dce1a2b0a78d390dc6e0014795e7a2881410a92f931bd96930219b6fd9f312641c0d13ce372ed4493072b8208e3aabe2c4d1bd19739ae43fc00096d9f03b26d56e4f91747988c7f144fd4e294782408cdae6f14f3f2ede1bcf38932909d43fde3695ed135ccaa6d56337adb151eb123d81f0226d7e977a353cd7c837b7753360273e5a5f71c9e7e1984fe4548d3556bfc73e49d52fb4134fc4947a24553f3e494aad01909d4a0a982ee886a47006360e74ce4d03233373d09388c83ac7bfe18de0d8571789099b82874b36a5f16433ed973d6058ad339b422695002e2ed9b44fd3c9664af8844d8b0ee01c3180821c836b5a1e6262e1bbfa048566644135324b5e4adb742409457e7f3391533c50134562aae68fcca9379e9fc71599322f5e7ee3c97c3ade4c16d0bdc5b497e4f2081ef4513491d33e85baf21c695198fdde46fed123ae2ea2099b0ee830afdc734735cfea78b729e1e5afc17e1bd0b66e869f38acf9cfc06efc976037d0300b62c01a589f86526e41691b6c7212d760336eb40790a91aed7611b41d4cb80599ea4407488b01d24a8c008b19344f684b2f7102b607dc058f244bdab21cfb8a720277bfd4ba38a56ec2c2cd9c35bdfb148bd297e092584d4d74e15da2cdb18f07d1483f6382c35748ffff30f2ff10464a078e0594b46e798385266c3a4ecf2578b696b85cdc542fe84f2f6649ea854ca48a926b59667db8aa21a76fe28d50d361d61164e92e3f041f46f2b23a814da601123d248e7d8c47c3de13a9f9d3421b674f690868eb166453d31490845929fbbd8a0b6ab9b5f8b28a938d380902b945dc53e27f8fdcd2765110862c1949328f57eb88d91e83cc73b6dcefe5b97f4825bd924ec482543af221d61775b84eb282785ac4895354aa2ff89dd2152a0928431a8c15112acee5b8df17587b9e167d7f9c404c82c511a549b71b9417536109f80579d9ebd77c1d2492d7baafc66f067024d420bcfd5e9c7b8f5d9c43be5240150b3d8ef2e2ac95679d786106c985c382f9d2d10d8230c232de44a173ab86a9b047e2c865201ccf8cd7f8df36e3d594b51e9df6112fc7c1b9ec0bf004cfcb8126a4ba5bf29cdc065120e62c7ccdc54dc20e5649b68deb4a0fc111872328aa83d7c56a5d542f49a07dcfafe3073424128fc1f85cb79b942c0fbf58397f2cc0317869e24290980e7b9ca4eabf5ac672389cc498d8c1d452b921eb402edb01efe787551f859eebb2cb1e26babb1ad0aa8e88639fd8dafa64ce93f9260a926bbd316ac85edd95f67bf6173a5533fe21cad63dc28e7de3d70c221819f674544eee121e1e82b33cf71518b76cc827965b5555db83154cf205f2f502835e4d25626b4d1d7f0472bd7170aee1b660eff6839e1c27175eb75b41724c92635f2560121ca4f45170ece39eb40c69c0c04f467526726decfb7df21726e0a4360306bdb6cd81fe498aa948eda9482d5e64026cbd6a2a244c850a7375b386a9e1a512534ff6048968d0e73dd9df8c612a2c861b098e7d9d84093f48eb230ed3a452e3c354550ec590a3272c2e1d11319c623f852e9a88ae426b17b44466f6f6b25177b5d56abbe9219032fd2293f82e90dfed2535af027c81928bb63bf89b651ca7cc49574114b1c4f9d7b77fb9ce9574e69a697ccb9c2848ee0a4cdb5cf07f897f99eec2c1083c9717d84d0211c62bc4f7fbd3a1bacb16e3d0ab296135a3721c71c5fc0f35465c44b1da068361dfc7644efdf1fc3c842b53b39294a2793fc6ff4b92c882f55457f85441be401b57b0ad7c1b6f6e2386f07950dec7c665ad63ada4a3736ac7ff4bfd7605cc62686e61d47456dd6e54311b1685acaf82f6631fcf6321b9d8304d50aec6f8676abd07935676648ac791f10a06316b6c0d5c95292032cac93ce2ffb5616f78328f5a0eeb564ae3705f9b4a146da676b75da77604f193085217fcc2bfb3966a2a5e983e15ab2dce1539d613069f558749d083f8e34ae833b1507dd2a44b159e4fc64d966b25f7ae76176beeaebeb4371f2be926a3d5d3f7c701c406f621d79724e883f6dbd816dafd9f3a670d2238f69b872b116aab5411b22f88ec372221aa65c6e4b14f863d09b3945bbcc300253677751180d8545341a3ce53ada4b0c118816576b6d27becabb4b78164b8c62d2dac6c331652663339b1d1c42e932bcb11a7c397a72f9f3d1fbe3ceba213ef7478f6f2f4ecd9cb7f2246513df130e6e4e4f4cc7b3e7cee792a3beb0ffde1f397fe70e89ff6113b3ff787b85b65c7ff64171717fe4b8cfb27cf4f9f3ff34f5e9e40b6b35aaefec9d999f7ece4ccf79ffd939d9fabeca7c333ffe5cb93e72f9f43fe93965a9f15566661e4040d9fbd383d393b3d3beb323c2802cfac8511d6aa685cdb1275255912c83869b9a12754eef7429fc72d82a30960a643389d6f5219af3e43ed4e18332d23be0ae47c59dd465e7dba1a3980d9b053ed38fb49cf5c88cc2d7674c0b4550796817656fa4c198b0b6f7c7c2c704075f7100037070d73a2fe81e930a2fe514e24e2ea7e58aab2821e2dce49badc2c16363e341767750dd40677ed3625b429b128da947d5011a95a6213a9bed425deb2fd96134b79084ab63dde5b471d2cbf7d1cf5183eac4427d2a096b0117c1127ab46ec5db049531e1ca884c16d751cc63b4987bd8356c158657b3ca3b227fba227f287258f186217d4dfefd58dc5325fdd8321a5ff9548743cd48128be430c0f9e54bc795c01832fd03c16691c31a8a80372a12b2697313c13876c9db0792059e83a9fd41d99399b9439ffe0f78176fb9a220c02e82c083b9854ef2fac7a4b8707c758140fe93ab858d4c20b9e1445776c2b99084787e2c22c27b118a9ba482ae3f508aa29de2a5b8a950a89d5fc1d785da65255275b6bfe05bb0da068a9167591c42baa1d9cb832363e720a4a45e8d03c668b05352e6f1ec0572d3d40e3c165306ab36fd67cfdb21842f292b9ffb509426fe45b217f34b442c3d189153a013d93da73976ea5561d15f50aa9a8574985ae14c486a05a2a5a9f3719dea98360bfdfe5d8bd4b827b2eb3c391b322e9b2fc1aa9fde1ca2593415b7e48b834bf23f785b1ce24d0d9b02495fd978525b8939785e58f9785ef8797a075563647223a99921074c76332a7a666b250d14bea91155d97bcb81d17294be4eb38e42c3d74694b04d5b711f7fdab3f67ff7875fdc73b921c460565d4d50713c50fa3e2ca34a6a4b1267565a9369e02b274d771ea6ed5708a40364ec1d3aaa02926e945d0eda2407d6ece936e17257483c9e68277bb88d38dd6fc8968702c4848f971328e2ec24b4e937e345234593856e3473001583b461664657c220764a5bd199355e1c9981324a9bace5d50afdb452a3ecca06bd8eafecc985827774c7e8e63d9b2f95739d1ee235fc761f65b9ccc0f9d99977a5b3402a66e483db2a03eacd89afae378e24de94a37bb280dd8c693e5946474063d1b2f8e55813ed5869cef69a6d0d338eb76ef2f5142333db9c7cc4c72606232139311b57110a7159a4e7a493fe805da2f0f45b28ef6dd333c38f348f058426b4d44d04d2f7357419af618fc0c10eff11ec724ed53d14b48a87e023cba87466790e7cf81feb53aaf23bed613fe2f8d01cd8cdbda99765b3be0e7f34ba44636fb9991a199c64df03eb99e5213248b3ef5c9ba4f7d4c74945fcfe11fe618d6730c0f739cd4739c5839408e63a1c0d1ddf6c1fb8a0e647d1ae6c4b8751db5d026ecb285742f1050b78b2c7484c96338afdb452576d2242e1eed0a9cb9211a1fce6b77a57549ec2f26cb4a8cef1295c87e1345a4c4f4556068074e8a006c67f3add68bea9f3fcdef57ea11ed97981a37c514bc10d3c22931f5f00831ed3c8ca81e518649bfbf24d6fd645628f585da632bc224d42f392bc2f0f8287479fa6eb59619c2e3e2e524348fc59c0a105452085fef7050c2575f053b8b37e2f57052b451db81c4ea3f2e24de4e1465770f26b9ebc04e16147103d15c43746f4e9614ea04efcb1cbc2ff7e6e38dde7f5467eb2f888ec828e4e82f49744c7d430446c020ab7745f5546dd1e820452f666e2687934d39519cc4b8b28a32a3b1c10199f9cac65c2f9ffee9c7f043b8594cf36ba27b3393f0d5247c2d123283353d726786476ecb79e9dfe1c190bcd7c3240fd5d4f4dfe3c1703cbbb8ed76d1bdda5977f496dc525e78d8cf2e1e748a2afd401e6851505fdfb734419cdce3f1f6d28c764b623c42686b1d5277640b70f79e6c0d1cde926d01830ff01966342681aa8a6cf5e3d8cfbbc3ace00682d64e2ac37e233c6c844fac302c85577dff6907be1601189857d09aebe2b3d8583aa4077be8b1c96229146c0119ccbf95fe3cd7f1fa2adc52ef40dc4adf5de29015642e8c5dd62ecf96e33dba339bb3e54c072ab36a2c276af55a1f42ab0e4eac02d3b1b844a2e88c303dc1a347726b5b40dab6bdf16f59361cafedfef105b2922fbc52b3bbaad8f8123555e7da6bf0a80917e52cfedafbbe3e3183db1431777b2cdd2d26891d971d4b37b3dc8dfaecf845b79bc0ef53f280ad9c8a1a997c0a56e0775b7fe4914cfddb0ed5d770e49517addb783b0a0c317678dd62966f03585f3377e6f1e86768e156c2b719d54efc8e5397a79fb8102cbc44a941b4a9bb4ed8fd274078a9c1b5555c8647c8ca414d2962e530711936c5b70539ad4365b421a21bd19921b31b956417b1222bcae83c70b73e152470b743ca49e0663e4dd4cf90c62de005b92193a78b404e0f48e8d72c951fd8c3a7388557dd4342990684538fc45a6ab2346551326c53ea8dd373cbe2608a791fbc359ac989ad5036e68372d9495c7de75a6a9122e16efdbe70b7437500c42a9ca970a6c26323f2eea6eb848bbb6b23a5a9416d3be27dc318dae0e3cd6048b2515c8f39c4d38f417c01a1029d9ea8fdb46b82b0426e052d774c991b26c1dd1b7557ef49f79e45f19ccbccdd92224ff6689e2caf2cf3a0971e468c4af09a5f641eb9de30c72421934e19d7990273f82f0da56d0bb78cae30eab048e21509a874654c786980ecdcbb64b55518c9cafa5f606e3ea2d81d2626333119d958647edc8bfb692fd50fee1b007394b45e0ed2c712daaad3e77d4437c79c84141d49cd4ad9efcd8735023dcd261ef7a2c1a6270daf652c2a823decc54458247b2f254105022a35a8563beca58f2cacdde6901d9f92da34bef0724c0232e958d93aa463e7e9b4fa2cfd910c98677c3cc04e26e901ee4d8b73cbb3de36d24aca61a3f9ac1195830d9016e38d05e87d1af536c564102b25b35334c91752bb2499dbc18c2cacb50c7b617fde9be3f1e2425dcdec62341c2c6aedd0f960a1c05bf66ab5f37a446608e86d5f3bd254d0d85718b45f1d99095628ab0cf2e2190f05bda01ff7623c78cad3dca9f72303364059b8afe3306bb3afd3148937a4416a1324c6c8019c3807f130d5b6a3ec62f0761c108dfe01bdc6badde2fa581946bbd4f4cdb68d9bb6bd64ee7664c8c756fe5c76c9dc6ca46e6e8fd672c99ea8415eca91875bd88eb589e126f6706aea29d5e4f096c9e1ed93c34bf4fa7f6c7a748eef6d39be5f32f7fb7f77021fad5f5c0a35bd15c0ee14608e04f90798651886a384a89893701498b89370c4739b6c074b1f867e68601f7b39dc6d41c0ab4f565b2a37abd2d405a1f67c02f4ccc135cad496293a26f889ce5430f3cbdda9a77dafd2be539113fef35d35abf0b33e718f0ec4b05ab436ee99907c911532229b94398b204a33c7d81f095247bfbe38e946abf1566ffc924e3ab1e890ce8227ac433ab1222d8879d7b61c2b61a0fc1a1a79a0b17ad8a12fba154b6685e92e72161227e562ce1c2e9d204a581066ce32489dc2c792f3b74e5fd5daeffcad83f3ca75c22131f3b8d8f2cea661cd6bcb230fab2d6faa4114dd06f36f0e4fab375419ab411c1878e4351f537cbf473a864ea658c1c4265da25d51e1282173b91d0560939cc48b45ad8f7533b5a5305aeb3009bc96c1dc3f36acc26fb2ea1e90d595a004d88ad5625a41b5be1c07133e758bce52237c9aae230e16402bc10e9613052a07865c13a2eb06c5aaa07ad86b6a0fc3396efc07d97b165ad276702a2b993eb6cd4b1ff4b9b0203be1d3715c76dee818c7ee5c6e4962d9d8ca7364bbfb8b857ece83e73bf5b95810fdb6a8885e9e30d26662ef312a4b1b15dcad82ed9f23df1b9e9255b0fdaabf52c6c251e72d932c5971c153c9e78ea6be054b53671584cc5931278c8163d0c90bd1c90049904180f72738c80e2ebf8f469477e166042629dde564d34297ecb62361ded55d350e4cb25ac45745ab446d86786a507ad902b3a35d4e42daa620050e279aa8707b2eddad0f2aa75b9f32753b66eef642badba18e1c1691d9b974339d3353393388bc906ea673664388cc91698fc43827731b3feb27e5868492ba84a8a60fe63756cdb4c46e872d6c08d5fa416c538709e7a46e15233533c372b27cc418b43796f67dbbd20098c8e958b3b8ba5dd409c2109c8ebbf36520eec06dcf656858607864904434d111aa4d4c04e8dd3e567881747a59389de808289c3fa2091c36357d172a2216a8a3ab0e3b6489c92ed9d4790f867dc6d608e744fdb6f004e7089323cdc60061f6cf6cdef61c18e724e4e93a4e6b2c28d8f84527541f72c253d563cd126a7987514dadb950791a8c47e802942dd8282b62a40f1f65ac489a567ee341197bb442d2a89962226308caf82a541b2f6dd4df7efd88a046856215cd411237a302e7042c3937bafda4357cb4a18ca8d9d5cf441bb8a854ef422beb36138141cf522ffed4d8e7af780cdaeefdd9b3277c2f0dcf8c29f4678fe89154724146e98344242473b2204b3ae9ac1336e7da641e0bf966b57616511cc8718774ee8324e3e2ceb967f353671e4771d2883d71ee6fd8566e12f6268e9350a51a191e270d56eb8825c3b7ce6666bebd1fa4fb3f481ffe20fd047aa7088155c0059004d8d97548c7711cbe7050adafee778752c773cb1c8e7317cd7e031e5114270e75a4ce3d7c8baa1190fa80dd6d86c7ba78ee18cde1d676fc5f6bc7ffabed0c7fad9de15f6de7e4d7da39f9613bbb662d0ae690471c9f38ea3f1e3b798774f2ced4fd77cc05eafca7e860b2a2934e2065c26f3792a922432798ddb344b2eda738552d54a900d54e30d3927faf8af8d4062aa86133d3165dbef0efcc4e5c05f2d4d9cc6412885445d869baf2cd4cf288a59f586206fbe3edf208b8de45b3025939d46ed4e9e999b18639b03b5ccc96ba95409fe67122989ad0551ca2c3d113e7d4b572abfe83cd4f53408bf41d167306aa1c391c71a32e95f2397e70a8032ca91f6507a16ab55b0656e17a963771b45909d3bdb2bbc46ead51a96edf0827160506cdfc209ea7a74aa105af588a26dc6ad01ca2729acb8d6295f77f5cde7faafcf0a7daf7ecf23f6ccde456306767727ab49cfa7133d1dd3a7d6a4f7bef89bc5991574df85319bf97cbf134780ddac1a58103d6544bbac175c1c36406f4beed70140c7717aa8b7160112711de7110610a5084892cb88198089a1a1afc5312df25c10aad149dc5dd4d5ac608ad9fac2895781e80f8091264d2b1b6a6424007835368c3dab1102cf7b74e34a78d1df0edc0d00e9ce81aea33d5816bb4414ffe026ddc4606c254062682db88fd03faab7b68cc53b9e5189eced61c9cba6f713375c6699f22a1da08af82f0f65ff44097780676f841e62b55986c36117d7f4a8f25087d9551c3293ded3177a6ddfc42d40994eb5b994e0fcb9dd5caf57d887c76d0e2735dd2aeec45bde410225f1ef6d53b2ceafb6d65fde14187fd93c31efba76d5df6cf0e0b3f6b69f979bdf0494ef4aa1c50b2339aba5aa4572fea8cac89ff0283d455a188a8a01c362f17816429626e9accf1585c960d50e1ea8f11aae23c225db5e374feba8fee2a973425c14737d12a4107bd5c5f78dd2e5a1f53f07bccc3f375b7abe3a0ee6e571a6522d33792baf3789dc1903e0589443362004dfdc208a131a0ee0d57ae2e560a9c89b29365770be9c89b62cbd6bab9a0471e99abfba7cea57678a3ce88321252495456d503515319c5bb2692e160f6dd6c26eebefafcf9d5d7d9eb3f7efbeddd6712433224bd0d64d04c9e11eebefdfae1d5fbab37b3b79f5ffd07268b6e172de8915f2187f7814cf8f67471af7044312672e493b98541860a8358544644428cc7dc6009bdfd3fc55c4896d8b8830c09777fbbfef8ea465578d2b3b1b2fbfaebcdbb2fb34fef3ecfde5dbf7bffeec38dc2de8f557940b7f8bf54f38b9a2914be40d2e5e95b9ec8acd02530406eb0636a949418f5c6ec5c54ec02868fc4844d8bd2dd2e844420f93dd3bc9bfd3e432a92303c96daf90e644560f88470374c8207e8678ab87bf3f9ead587dfafdf7d211e79d65bd72e8a59c1d2b1abef76b9ab1908a6aba89e5e30c00a245ce452ab15cc55be22864f3a37effebcf9e3f3bb4e5f4e0b382b535d93381bbe250085926daf56c19d22ec6b891ee1eee7df5fbfaa7efef8f0e5eaf70fefdeced44210e6ce03711fa4a68e4f4112ac986409af575305debffa7df6dbd5f5cdbbcf84bbd7571fdebdfafcf365af3e34cbcede5f7d7affead34c7dbffb72a3aaba6382258164eff97a15ac6b75d9c726479b49c79cb26a8e88c4a43edbf4c0dfde8f9cb9ec66e67e34f288c128238f28b43d6a7d9a3a199234998f5a5d14b65ff6198d10233b7d66bf8e18b87c1e1d79649db09425f7ec6d123c7071a731ca48ed7405a470f1aa87fe0166d476c9c82777239fdc8e7c02aa12e6658188828d4056644d66d42319f5c83d9df8c4337fad5f537247275372abfebda7bb9c3ca87f5b1a204cae2947987c6b7bfa8d152971d39692a213cf3f7df1f2c5b317cf714ebeda3ccaaddbc0d7e81e93eb96c89cbcada918fd781839f9527badea7605c8090bf7818772a95fc157c1161527dc7fa868e263b2a0c25d6a7d94834c7f8778952bec7643f79eb307b5c848b539270b4cb6dd6e3128858cd17c30248bc11093eb6ef7ba2d01e763411fb808e307378ce7f040d07004d0d17bd4bcce7ca43bc380fbe3aa4da4fa61c2a625d7ae3dcb7bc8229ac778edd5a502f4e2cde39b794accc19ae3af94bc294b3ec5af7396f56cd7cd560a1d88321b17eb8d7c1f88e08e25a384dcb23b2e3e1f9cd93961223c8cce1481b2356e1910263315be2ec339b905c1142ebeddc4bf25b1906d5a2d24a15b7534410695f72a4478bc75a1ac29a7ee2cc985a26eba5da46df310416f27c994a87ff47622f597cb439a905bf0210c3f2a42e29c809983374c1db76f3467b949ac4f14d93aecb1c1fcd827f71345b1fac7c39e1c2cc8573516a382db4ae367fd3e49e88df58694a886054940084192ad81476dc604935b751948c883e1e7272481065ab8c7ba811934f0ed9106f47bb6244921c17aed56c4b06aee4e37f7de6e0e88a12890ec338bdae6a24f87bdfb8937553332501f7a528e21fa6caa2666a03ef4eca4f3206aeffab027dd2d4c6aa227d4cd068b52f8e998426324818f136844b52d7ac83f6658b7d9a74919f4a63dca08f48032d536a91d0ef03a873a09830e851d9c8364842e69a41fbfd4fb5aee8ab7087012fa82b0aa189b2d6251ba5f0817dc82e2a4f01cb9cbb5fc63eb19d4eda2a03d851e79ea5e9e10d5a46a1efcfe3111be59f22854d431f80ad3d71330d28e3a6cbb6609d73e068e1fd8ed5dd42101c685b999ce1bb050216259fad1f9ce9cff60b7bf5fbbce17c656a913f16f0c9c6cdc26f143ca125010167f934eba592b54ec70e976c6fafddba0d5206289441c139ec338eba76fb78b42f756057edb88390add2f9fdfcc5e5d7ffafb2b12ba1f3f00d9f2c79759198b49686a40a1fbfafadd87b76029ac3a994b9fd46ee3b41e87560c8add84c4ee1d89dd5b12bb4671c5b570987d7c99922874df7cbcfef8d9dc2166afaf6e709e6ff53d2ec4e491a3a74c6f3d81000e5bd0b7bac421011731d079ade13fd1ed824d7c7daf2b563c273cfda2d7811d28a1b29f3ee66c3f5015f4d443adb05475f6e0f000748f32b8a3ea472a83bfc6e6c9cf04c9d6367c5192ec122c542e9038cfe0b8f3b441f8cc926a302f45b7936c3a362852e3b9bcecd5e1fd1e7a35b37af5bede2b1324d76e75f76eebd5acecd56cbf9f1df6ea6e329b8eefec5e41958d1b36321e10f521080fc7f62a160fb58ceeb6238f64232f27fad17666bfd6de4de474ccdc2d15257e77b784b9991d919165b7bb041fb8e4ba8c8670d98186a91b63dd426d9378c5b50514bd55b8b8c3ed9dabbeb5ec4f56c97daaa5125312503886e079722cdd2d0d40ba39a3c7819b95a93226cca4b1226dd5edae5042c0d3d3b61a828ec9abc75b3e4febea9c4f3e5176bb485c3224f0684d19d88d2a5e4835dbe1c08255d8ed327c4d59691ed7c852753e2834aa2e486a8fb0d0758c85f6f421583be9320859e2c4da63d122ca5cd775be32e976a04178e07daac1edff6483256fe34dc499903731cc9bc5d46ad51d74b78ae431e7b35a157542337542c35a81d6089cc85893002a0ba88dc0b98c3501a0723277db53e810642c2873b31e3a06ccc8acae41976e62ddc39fe89aea58add24151a96951f5a9af0988a259d5a3be26258a11f47ddc53981a3aef1f3337c3bd850a9734fe2ba9fbf4296e72c81ef1d7565a87de44d158eb4dfd68fe15ed56b763332ba4e724ba0333157a6794ee645524507463abb54a9262833e62f2b17a5d1f9e154e51cf5e1a87f2cf0aafa8cf86c65bf7335fbb453df5b4b3eed393279ede4f3de3fdfde5a3ce7c6592952bd6b407511a7118171a3d6080040dfe79fe9f0ffd01e81f56ca04136f5a9ad62e4020dddca632411e11b8ff3767bb8a443a4aefef686729e57a34183c3c3cb80f276e9cdc0d869ee70dd2fbbb8ecef67496bff5cbba05ce1f73c300be1d1cb821c1abefa83080a89ab8d442882440897602f15b12afb4cb36c44847e51f6c5751079767b539a4713e8759003116d5303be4b13474ea1add7bfbf1fd27d562e270e3fbb3a0179cdb4cfb495b478154c0581adb88d74c383c4d37cc59b284396a76d2d16070c7e57273ebcee3d540910edf82410ae8474dd32396e5d596d808ed1625acb06ed9abc2fc46635646a25279600f55f61c3de149ef57843b2b1b360c49125426d4256ca29b6c0dd291fe1178903f513f057c02c77419a44084c1998d70a10d26dd79193bae0cd9a5b6b42143e9844f4980f313ed9fbe4d3d8e41373419ab764762ef0e7548eadd21704d4ed2889306137f4a628ab8cb45c8b61f17a8e3763091133ec5e3f832d622a5291ec554c5d1493ab53d836a3e6bd13c64c9739825684cba41f5c465b5bba1768a35fa8d3dfa046dd4e8556db9d635d81db0372c88967807ee9d6d53b9f21153b972c2a6658ac039a8d31aca6db0db21b77f89f37c30aeeb2a90f25ec6dcfb62be0b80a0416da27975d788e279107d08568ca4944f7c2daf8ad2da8c9f7b2d52cde596718c37ae28ab8c2e15972ac152d8a11cae4c052b6a4313b5549bcb8d5ec1088f74149d44d3bc61591ddc66968f041fbe685fb9316193747ae0e118ef1243f0d6edd4d4907d5219de45e0eb0695378ba6819bcb5d1086a38024ab11cf4710885520cd31769355595daecd98d51bb5bdc62766fdb467e2c6c2fd0ff52708c3aa434df510051eeca03e6353f340b343e76e99c983027155802f50ab04792185ff2658cb0d58d475e228bc7ad751e76b2065305f421ba8138b4e5f1dc6b9b58badfe84ac2defaf69ec0a232487c0d9d12ec76e1464f146921595ee9d21bbc99a6ad791e01e97cc68298a2e5d78bdd2af2efb7d2d48327ae4937b7ae4913bf575abfebd57ff1ee84ef381ff1c79447f7d1d79867fe4e7644b13b4cb4b81869ae467525287d97e8f8eac33694dd7fb7df36e7c1b871959d225f8502f74eb4a553ad2d4b5cb3159d1d57eafd67d578e78b406cf5e4d8743d6edaa83f77b245d2b861e79782cdd75c28cc75aeb7bbff788a068e5da9cd7fd3ec5889115ce51f325ef5065a7aa4bbbed35810bcfbabf7963766ea58d599ffa785988cc224c54fb5ca275d342fb1735586b28dd6e5d3ef79de653597d8c415c376129087bfc86c915c2e41a813e6a07c37b6c88d618bbb1789b04774df3f62bd7664422a96f8e987c43ea46a8b9795015011be9e36bd449e7491c45baeefdbea89f2cdc587c81a47a1b6a1b7c47f25c519139c64ddf1cffc6e4333a903afe00b3940183ae41d6ce8b13724e379665b2cbfaba21764c7d755c14f2c17ea16d7083703eba21271ece515230190fd4b2576ec5ab34ccc107177609f573b20e367581e5f7f030efa6320699e884a59b5533834fe6aa52192452e7397c9c2fde2950d1afef71bcfab869139cfe8e8e3cac335c89f6745f1b626a1125a89e5a72a210eb4d3c6a82c521c71e3d9827a43f8f59cf4c0629e2be1ecb220e80a7c63b68370375c7e43520bc96e465ab58386035052d0ac6632d236e41fe166270b90e4f79b16aecb24f8a227ac25f02c3bb37eabaf1d1e45bbaa67bb0970d6f0cad31d89f6b7b9875b6ae89302b5bd3336a645c2cac9cd693fdf513ae246797b3925262f8827aa3ce6d1c472cb0eecdb3fd7e561d68df00cc2d762d3a403e2b3b68865af2d5205c3e4c21eba8bca916f28e1668afdb3dba05b4727457e5fcaab6c67e8fee1adbc3aaec6dc97c5dbab63281ea2d8d140a15c06618f699bbf5f1604812e091a870a6c2e3126ea9d44fa783e1311205b81e0b5c413195e6e1546549ca2c891aea533ba2aa01ab63d75250fd52dd9d966e4313417bd419af4a53baace60e4301dbae842e9dc14a7ed7a8d9d668b06b3656dced9a3fd56ad619ace47f1b547b8d3a027c4b17ed1cf96301721cea28f9f03689d7eab08ec517b56a35a32974e9da1a1b6aef2c5da3a081185178fd56e14c78bdd24753c3f4b2beb53d36674b376d892789bbed0b773b28d053e2667de16683123541a3df74a35f64dd5a8cdd410959fd3cc7d62de00dbc1b1c4c00dc82ab5caf6c130dc03f2a3476a4adb183be2081c9bfd5bffb6ef72dc278d4d164ee61d6372ad747f50fec88b6e844295a4fd5a05f479a3574bb561565bb569fff5e991461a03604066f4db79955136e608877ea1e577a35abfaff54994fb532558feb65801ffb07243a0a7f15dc961a7bf6e6e3db8f23e7aa887256eca8538dea83f5ce6d6cd6d6f4b3a422cb9056cec2b05497af90c0a342d5eaefaaa35f6dccf61bc23b450bdcd8915708ef40f2ad3c084004a30e159f9b6a4d9aca29d3bf970ccfa3127c14761bc30b8028101728fe15282acff526299d63f8ee296197c7ee70e40e4bbe4c41b7acf42f4a1470dbf41d447748b947cc87ad39e415accdd382b579a2599ba7beaf599b2f5e68cee6f06ca8599bc3b3134c4295f2f229f5a2d3177537306a128a57cfe615b18ec4782d73db0d11f2ff0a134dd7553080134b6d3980039b8377b1e9148fff77000000ffff797bef9a540f0d00", + "8f27e84f7d53f655652def702b1930b5": "1f8b08000000000000ffecbd8b57e2cab230feafe4fadd7567f66746c4b733e3be5fa789888888888e733c3f6f8016222189494071d6fcefbfd555dd9d0e04c479ed39e76ef75ab349a5fa555d5dafaeee7c5919b32876037fe5fda6b91207a3a8c3e295f7ff587964edd0e90cde170a85b5b5821f74d9ed30e88e3c161786c190f949c10b3a8ec78c78e2778cffefe666ede6a6b0f67fff73c5cc142d386158e804c330f0999fc4855698b843b696c44f2f205e62b7e6610eddb853a07d274ad692f885aa6a674d89f952ab176e182f8b5b63c365514b4edc6f074ed45d02d77e0abd206251933951a7df76a257943971c7ec90b1d734b304eaa9335eba53302f57cd3993026fcf9c891738dd39287112444ca3027f5ca28f9613bb9db4e6172724f27bcb635f3ade882d8f2efb5e6371ecf45863c4a2c9398b47de32ac220b936e376271fcea725beb5b4b601f3aa30e4b441b153f1c2dd304165a866198dbebb783a5784ba0c6cb4c831b8f1ccf7d5e8a69cf83606e574918ce7b25d8ef34e832c97a0bd0381b2de4508187945ba2c27488f390878e8b42f19fe68aef0c51580f9d30c5a3819fb0a764c55c89d8c38ab9e27667de9db338f0c66cc55cb9bd156f6e23f6307223767bbb62ae042be60a7f6b475110ad982b9da0cb1f076cc2fb536fdfb30ed62fab41d5c04b3d854104bd4efa2eff5f180521ffbf2f29ba62ae8c4009ac982b71e22423fe562a2173a5cbee9c91978064ad87891bf8fc3df318d739fca7e7fabc68c27c51c2f1dda19388d2a348feec076316e9af4be9bb88c561e0c7ee98919cb7bc85a9f69d38767bfc5dcc751e873c9127f87fe2760680314a82e6c0e5f330749e2e38f4c41dba9c4c77819f34dd67a093eb9f07896c68e83c694fbdc8ed9eb83ed4da75e3d073262be6ca44b4d3713cafed74069c585c1cf189f5bbec493e739c9a93f47957dafca1cd7aae4f92cf2ce2b399048197b8a15e1310d369332f7d5d49d890b7ee248ef85fcc80e8e26745b4489d883395157479172fdc04e6de73e2e47618c6b74396446e870f101aecf3359ee06393452ef43550b48562bc6f6939d153fe3f5520ee078f9f4e787f91ad58924c624155e8759f39e1adeb8f62a61eba9efa1d318f3931e3dd1edec6a1e32bd4e16dc7e9f4997a8e13be1c6260757f34bced756427436714337c863a03580831f6407594af31c7f581f9ce83474e71cf89e35307589e069cde276e9c94a36014c2f445aee373fa08f28fc2ae933054b5b8a45255c8a9e2443d96c00bd619698803c667238647e2a7bfd50fd7eff156b8b8978d1f06d1907738826e859ed361fdc0eb42e7039ff61dbfc7e067954d5a2172a6d3f6908e712f9616075f117cf017fc25a74fc4ee44f5c0a962d53a30ad9390ffbe6ad6e2de05feee3b7ed763510c6bb3e7c6098b8e1084ed70b44a2945e454f26731858e169582741eb54573a086a5408b82519252d47312c65917f5758c4df2de76bb1cf98197bce5152301f199459122ec6d046a7a6aee103b820aef580213a110ef6358f43afeb97c8755e3ab6cb759cc1235dfa2bf7cde46715ff497c5b1ea564d2168759da8719c06c96130f2bbea7d8a2f9848d587efd367e8086f18097e9ba4144fa1bc9e517b0a85b63360ce5191df4b9f2e85702ba10c42cdc9e74875dbe97625d7a51dbe73fdae944e80cefc1e08c3b8efde7180868aecea82d8c3cec409a72e892210b91dae247d2e9350ae8967e0e33871fc0ebb059d1a09e285111bdfc62eef1bfedb0db9986e4f1298fad089786d6ef7763df354e41d78c2aae264024d0d9da8e7fa569024c11090bb7cd0eab91d445d16a94797afe458fee0c5795d67513076710577020ff846ca49a8fd22e0eb381825a230fee2b53b1e1f5cfa8bbfb59c6e0fcb2203874ee40c85041e9f09e5ce7f371327491b3917229fb3cd5d100d9d04e714f4561c8f808adc0a881367c8fb13079edb75efdc0ea8c3ccab1e4bb20b3b660f23c62bf047c3360c144a8baa59741b8eda9edbb91502d1edf94e3242d9198dfc815ce848fa76e4f89d7e161631bfcba233c594cdd0f551a03b63c7f5b88cbbd568940489e3dda6e4ab3929856fdd6e8c3c148f86c0789dc0bff3dc4e82dc2c5e44b79d602478ace38db869731b0b8af2026e848523c6550efcbce76d785d4b35db07e98aba0197670e51c11e896c072693782cd2a516b0f35d6aacea4a06dec5ccef9e8355d94e7c7be6d56d46623221b5f81b1cac354a12107b6d2f005326f0a9e7c22f5f380235b001620d22cc02e0f32ef31337990885cc69338a225c9b9dc0f75907c619446ecfe5cd84aee7c99578fb18b949c27cf51c31985b51c3294b2a7558919cca4fd07e52a92bad2e7b13dbb050c75cdf2aca5db228713b4c597ce3ac190fcb6614332ee0872cb5f1b3704d77778fdc5edf134b28097a3d8f594e67d00389c325230d3c0f078bab1c1e80c4336a3147a7c668e5c0d4c7098883b11881641ac58e31f324c3c99fb74e1846dcba8e67b0e42b96be1a4fd1062c3df912868f428b85c84717e8bb244133897048f5318b3c677211b9bd1e102d51bfc0601922030488c62b0b4261fc5325bab9c9c791eeee7069b4153d9558d0c501fc7e961a250c6257101bc9e531502a8f6e17948ce03dae539d71db89d06a73a0ee36307e840fa7ce18ac3f7f80a6a0e78460733eb2761c74062ca15813d0843d391d2492684438b7fc77dff5ba11f395ac2ab1f14500361c097907fb2ef72839316a67cd9ab4ab9bd2dfaab161104dd2b576e186b1c212fc047df059f21844835b37008343dae7e8d13da20f23aae17c7916b8e8a5f96239c5ac13f8dd13b158b953852baa1e2668a788e5e549c3fe0e972cb7172f948b974e16151a0d35e195a03f3e65df51276c0aad8a809213f7330f75c50b003a0e5c5f9608f938ac4cad089ae98886297b03a023ce8173d0f1dd6ced1a3c53d7b9d37561da10cb9d06f0620ae4a39fd1eec9aad5746abe599c85b3612e5c73ca522330e521c958311a653aa3212a9f761d2a833dbc8ab4c2d319c99f72639ca92bc3a508a619d907a02bd66eceaca58ef61bd1ba4aa8674721eb073ddc456f9c790c6d1badfd44ef4ce0d743588d5ca10531ba4cd26af7820ec80abf0b2bc60b3ad2e51f452e864892a0038bb71fc04279e4adaa71406581acbfa3ea97fa35f0534fe0b8593f452b2d66e9b0f5aaba2022fbc128c278c428616a9dc202f402d4da6013733f97783802febba2f9d795d4bd3e4fbd6b709f6511f4a2c159c69fd2d58a7b71d694d7ac6b2ed41cbf1b0c7d7436745bf030639ca03932e57a49632366c9853b64c128fb52e173a58df113a1a12a7e2718ba7eaf1e29ebd943a9aed4dbd8756e3bc262514034376ea5b19d44ee109c7ee644cd547bba09547a27540e046fea775ad714264a74261c3eb40c4051624002e996e93d280b3716cbc08d6fa53ddce9b3ce40695eaee52e111dd59c787063bed4c115731e55c54eb77be18615ff2e406e17bf703154ba10b17242746a87c1989d629010df136107085527cd0228261f4454106d56511aaac4c52880ad8ae4674da005d16110614fa5dfe174bba20ecff50768c80ce523277c140cb179ce74002a8bfe5fbaec119570cf2ba71df09c0932cf89fc7117441d567223651185dc443951be263cd280dddde142687beca21fb1b81f78825e63b45ebb91a3f0387b37131642cc9481d70b3d693e8c9c88c9a7130ca0305872dda03312564f8f25360647ad4945483a157e829210efb1c7227c3a0c4631b37d64467838610ec470a3912f228f28608081c1987594912ee7638ca447b7b27b175712163909cc4e8f259cbc8006618213311dc2ed10b44f59abd3864500bf246ecc98cf6753e938b4fb0218213083d2a811032350c22bbeb06a31eed28e82c7984547c21cfa273758c2d0f57bf1cafb951d9b10625608a910d326a46652422fcc3a210db342e8b9d922e48afffa940b7308e9f05fdd5f0c5bb67fffdb603f9a7e7ffd4ca7b0bf8a06bffb1cbdbedd9e45886bf1dff7d62f19f2f74ce7b224fc9d96e1dfb0bf6e8e966df7478b98df89f68b61d78438fc57db6484f4400ef4ad5fdc9b06214dfeebc2bc22e49afffafc5dd264d9faf2f052d81c1199a2fe1841f62d13f00ae9fd8d4ab64a2a7766939026e58620a36699d0b105a62140aaf06f6c1df2170568ba5ee6a00040f6b695961658fb585c60c11bfb14eab2cdb23036430a38550eae88d66afcddc82264629da2555a25f67dc9ac91120144db36ab84d4cda145e8d1a16913fb0cfa7306b5f0caedcf2518461311af088db0cb14fe2d7170f5d2ac103bc48eb12bce08ad73d326f4d96a72509d02a8cd41f716d8c70c3a5e35abe6b0429f1b210cf0c1e2af22cbec101250f39ad03e359b8456cc3aff874f18e54cd431ab668bd0a36b681c8749f934b4f8bfc74f96699bc3161fae4d0e8b16e793bae9107a6656090d2cf38af246a61a7c8006efe7367845e8e1d14c83b6a0c51539ee53d16c9d37bb99d3acd9b3e8f9a598583e67bb166f8eb4f8ef53ca2b87a93ca4722d95ef2d8afc45093d13c8656277a10f750e3da2e6c022646871f8d8a2e69645c88e6596cdb8458fee65676d8ee2e3d405f83f5edaa714799f127aac2a2534fbcc1be1a3e513784939b518ff79273a8450588d36a16df1b34cecd9de73368241655b3a9c412b13bb7d96b6dfc4969a30c7c852f82fae0e9c049c1ccefac7c890679260f4b294f6dae1ebd4316ba4f29ca5bfd6076858b5e6f076eca285e03229558958c9bcaf7cdd90eb326fa073ccd9e79e9e687d818576cd8562252a8df934558ea6992f06e6f366982f80e609aee92aa125041305adc2a8e1dd29be2ba5ef6cdedf2a6708fac9dcb1cc06a1ad6d3ac3c31b144af62c6af28aca052a389ff71ee648f0489990ca3970e978b6963da41fb2aec7ff77d9b7793778b9c3edbce510b7e8131727355caa7f33e8efcba0236050ffe730e88364d026a157390cda2b992e286b6a56617a4ad30c7abc04830e4a60801ca16c6d90cb7b604f3e9387bbb9ec7949c759f68c4abf9a3d772cf940dbdbd6afe3d511ccfd55626578b64aec82753ed3ff3aa92496f37318d5cde98864d80ea9f4eda5242a2fe502e3d5c6a5394a7c58e2465c4235ee6eff00e6ae9a8cd01a98bd2d180ad0a10293dc29093bab45c8350cbe52e6b6ac6b1dc143850b02760cbfab409513f85d33af89dd3fe24ba643680f8dbb4addacc33a892d34df1abc04378b396d19fc8f7a36fe9f9c034ad30459f3685d66bbc6fb3ca6871a70aa8f9c15f667f4c427b90ce9f9dc65b85a02eee85b721dde5b6169a19ea07d8ae61a5f1ea4cd47b5cad1e8a6352d8e905b08ae6b989511e513062f535155165a0dd8b4c11d921984aa2ab669fd102e6812d2c8916dc87b7df043a4e25db5733b920fa5da88715440d726f84253bd69d9b2a744ce1d78054d522e08e4a39fd448ddec9046286877f2ba99d0eb69980d627ba2d1c36faf87739eed7f7f3d0df38adc73fe44db9ffb3b87d114135f9b6573cba287ed2c13834e25636a76ccc02236508cc092ef59f78720311a1abf4c6c900025300eeea1cbf6f010d8679fcf47d907c9465641c1b8560855c0502ea1ebf6c321f0e8ae3d5b2b6fb6bc6ba5d292d74b057bb408b1b9dc264eff70baa81dd15967894b02783efbb625779d3213146ba3f66c102a67bea33040cf9c0329afcd478b9091c509ff6471b3820416f8b65d2ed0eeada4047a6780f206d6642bc4214d6c5e6adfba06ce8e10b8c54748bba82a4fcd1679b676e54c83a839ca180ef0cbb5b4597768696ad267f5129f4fca7521e959e319fa721738a5ef37d2f38788b081a5a67564bda61f1c01dc53884bd01333ce93c9dcb2a387e68ec5dfad5b3064c07ba0a47c0c707a685e93d0da9653d08329d85e380533ab6e0f54477146754433aa63e7bb54874daae7a99870b9c5a3b897437a00b9b7b8121f95087d2c811d1c961e2c0c044c90975dae28fb5628a30b0d2e61c21c09e3503a35d4755815c5ac80b9b7fec5240ccd4818576765a58ac03ea71479acce0506207f9a9212183082015dce2efe4dab8552640494d785052d623cb0c505dcd5c01202c126b46055a724c6d022bea51442003cdaa70bc54485f6add29017e102ec33affd9a8019c5fb4289b90aff4e2cb11e2801a9464c177e8fe4dbf3634e926bc23bce997860455ae0f18a9bdee76970b16789b01018fe0554fd4d08cc39fc4dd9d72291038bbb15746c1d4a2cfa6c61d8eeba6cdaa44e782d67d8f712f61dfbf860a57d7cb0c8b1d6c72bb34aea6368e59a62191c2323875934737d64d18712c651d10d38e1c5aa40a692b961911294a81288359a55ee0982e756260fd6054c2c6fc2b708f030aaf0070e2a4754802adc4eae127a279eab10a8ab9232ba1f8472e37c626168534050158023061074a05c2eefa800ad5a42f054c1bf125857c261b9bac7e6c16dbb0682f2292881f8f3ad7d5c4bab65b0ed7b502fcc2a9551de060c0dc6ca0861f718a55ce5163b4de81010762c69bad7f982f2112738e27344861865165e5999ff3e8910233e12ae37f77caba2f336f82e7c34976344db2b0b5fa3ca3bb70f4652b5778811ff32a9445830a0d05e6c81e0f02c2f5bbac2091b49a82c0e4163182ae8a466c196e3abf33af4477075e9a50061b51db01b7ceb096b7d2c032bb8e84f828df06015f90c943769b6e035162cbe58b0200b4ee120e58a7c6e2a9b38c9a7287cd11fcc769d7372c54342f5903d875601f4e6c81262b1874cc2459abd89c2780384f1c81a5738264b59e79ea2b8db3ae2d21f03c4dc2c529cf359e71c8c00eef2b1721fb80c056a84dc6da12bbacd39c73e36af49891c6759e38e635fc596d982a5c4abf6c1bb7bb06a29d3ed5a82e9f68e80baa1e464ce73577379ae2278ae85a3dcfc9d46e9c128b7ac6a3aca502ead5e054619e9a36cbdb8b2ae391e57c9f4f81ed47575bdcc9baa814d5dc475b55346495153eb6a68a14246b9d0de44bc0df85f9d330bfdbc992d5be58b6a17615b65b17f56261521d606a24210f095b659274744b42e3a04b54ef728b7569bd0360a9f4708574064a0ba0b7afc1a8562dbc7c1061510de457857598788f55da8bf6b680b8397ef81dad8a609228d2a5c6638e34c918a794d2a3ee7008a73ea8346bb0e00d47e9edff61817b268eb81e2000116611d31d826f7805dd99c53538bd40a48d77321ff80d8e4c1daae485a8100ec81daed83582089050c125825dcd8147c2368dd40b928803ab1236b7b9efcdd2989f67d3e147b07d878b32466715216ebe34186f2cb62a289bd790cb31ee332498e38e5f6c5d253e5465cd56c1e433063ebf8a47f9c7dfdc85fdbcfd6fd14bc8714e54ad7abec5ba237284b3bc0673e46b47aa8c45ac3126e32603d3b15bef2e3ca362817b1ea6b187328731b905b0ca91554098f677a5d47c79d942bb82bc97f122c47091d97a074116dd569626da0f5648172aa162df4af628b4b13a06f75c7924483cd71e1db801f509756ac5b45db15d5ca26d5c96ca5542f13521ea0018bbe4683d412dc89e52f9fd132fa643ac03a5b56c56c98230ab6490adf2ed9668b5b4c3ba5a6062ed013b3656e596450ea29f49e4de8957cd82891b27a782c696f5c8bec5abcf803257b565a7c4b479ae80f5b25f2009c5da266d3dc2991ba7a086c32485fed95484d3db8361950f534d24bad9648437f98587a8515f530b035bcc0e6c62a3c5c99a34312582db3650e2c1ad6efd0972a0b5f6ac02d787b5ff75f1a847326a80521a374af65d302af651d6c61921f1eb9b75fe957d2550c5d0496c9eb11f90b608873f003f7ed2eb96605df83db4e874fd68cc351a1763b3b3a1746b73b3d3af489ebbcdb36370b49673c3bd031fd0903cd893ba6b109321b6b046ff9d1da42f2702561d649792c021dfd9743a78b6be72f98a83cb64c6e1956f7696289d6dc5995e4d37c4af83f9d122d429ac826578165d6cc06a9c8c0f2d32b039daf6f7c04ea4534ff60994ddefcb69886e79fde7c871047341e5b2667e28a2f1a2ffef4c6372c42d6e5d847b8ef520bed7c3ed8fcd9dd21c4165d7195b0b8c7cdb447ce16d7e4a9e41f0a4971c525c538475298b1459df652a270739e28b47f8a287cf5f438845c8b25bcc597709d7b7c3993f19d75efa078506b6effa7f31d37e90652f4ed89251f09b62fbcbe79be86ab7b876abff89c62625b9dd0aed8bcaec3e62f4087984677352bf2ec330fb7488668a12427c02ca313ce06770257a4af716b128cba3db4b2c4d32e5a501b8712e890caa61859549a1a59002a8adb44f458d45e05d7af891bf484ee56d456b9bd277ea3a50b1157eeee9770f817e9e85b48b0a662558e1c70eeafdc4bb95afe2134bc5e40c3752048631769b80734ec632e1da6d7350af86a759abc9819e083db561d424f1bfe31b83e3b8740e507a0643de26635ed5ba3128437f9bff531ddc6f677f958a888686fbd2afeff2d3ccda74c70f4ee2164df25b6577ac9ae21bdc3363afa579cc2d7e0994dc5f9bfa1ef1b79167bef50b7d8a3635dea1d419e242d1e65810e693e51d5bf1e4cb837d3c1f1345fffba0eb64839b4f4da1eb56d20a874b30cbcc68b5f8cf5287f0fc2b1cdf01859be822efeccfb53f38a3e97bdc3ac46e995b846d9a6dc91a395cdeaeceec10e5f34f4d91a1fcdbe732175aab3a9bf1a9c883d76d85daf991552f66d084257ae676b1871ce2fef5a107e7fb40218f500e2e21570af8e30f6d83accd65a25a47ebdb0559a9472da5baec7f676c9ac92f2276071d82e69e4d4d5c35814c65630942c832b18b068e38cd4b9fcd2221722fa812f1bf265882f455866aae43e568b318fb6ccec816c702aa4e915c4fe7aaac39b33d6c0c21ecb76c1c15512ec8af754c462441f64efb388d71cf864e9237931683353459d54fafaf66c99afc9635054b973dd10f146428b36aec90e2456db9cc3d38d2d1116d3eda2fb92593b7eb61f2df3c1ae4cecd04a20055bacbd3d7b5a5ae286e4834daae71b54c3dc9c91abdcd526e60437bf1fac7ddb0433b4be6bcdab1b77952616a155c0164113fb303ecab7da3660a3664b9315f61c59c1ffd93a4c93d40291d3865bcacf9698638cd05461a3a442c8b355800a2bbd4388ec6ec1eab4c7c29e3e9fd3589363d1967b345569004c579095ba87e6ba05a6ec8645ea85c3fbc305b6e9f81b3387965777b0c29f509e6e9d70bad84f62aa92a31c7c2e27eb038c120d0f7971bb28f0c779f82d428f047a70883166f8a7496adbd2063efad9838c2d429ba2170f879c35ed6dd1e9e7bc4eebf8f1a1d921b527d1d7dd9fdc574c2985fdde0ef01301516ecd44ed0e73a27623e057ba6f8d0fe5f38345aa9128bdfd7286d54febda237485ee5b4f87f2796491fab3285d783d594794548451f893fd1c7de084465688ab6558e343aaef8b21f42bafec051d81f87145f947201b9ad550be78826df62c1256fbd2025d875dfd64d1ae7ec5ecd093f6223be7f27566ce031a0d8597cd1cb462dcda4fb66296eb90b262b21a95bca450ab5c2ca0b006854a5f56a8749ffb80b6cca8c72ca507b10327936e50235448f3095392202e448966802f50a757843a5299d69eb18211ac1a38b8739aee354c70c599b895c07f3ee3e9af1dd895b97a8254f24645ed32a0ab5bd9804e37435b470e4b6699d8cf163a6a575c9c7f82da3ab09ebb98df55df42cbebec501a32f4bca8de30192d7ec2ad8a0e97af65cf2a21728394fb489ca88623e726fe06ec85d4772cb1d9413107e4b9c60bc1423c9a46b1f944ef5b4581e210fb92e0cf6b52ee420b3b5553a4a3d0bb94627bd0555ba358589e210229ef6052ca3de6ddaf96a6b769300adb8a6609a8caeec159a9840a96b2096d43fe7307ed857bf478b9c3428bd6036221c235eefb4a8406b181d69188304f3537c248c5c8eae70de4b1a4887a45e8ae0d5b5c1d07f7cf650bdc68026aa1cb4e1ac313c85829e1309b4f7c71d113115b9e4dc2e522acaa7bfe279c2d9e2dc8a7ab9ab0ff7355958df1a786d9821c14d56a93d4fab60b49e88d089a3b5ea2b9013457df3c419683f62a1022ad993046b6712231303481f97f6542f62df1ea81027b1f9b1be8996d58dbd69459378055b38bf9eba200d911a6e221b6d73fe59c768a0f0f35ed816abf4da8d579b6cc1aa9f914cf1274185a957c5c9148e43be11d0d29a80032b4b66dcc187a99247b60637e1644276864a7e4ae916a58d2c4d07e795a0cad43d2500c09461713a9b7b660d936c8b474e16a2929a149bf7d2c4dfa2a2997a13c88ade9bc5ddbe1ef424b55764dc800f2e036adddc3a9161a844ae331b695da4473bc50c10cf12bfecfaa452ad2d23b9eab9fdbafb0124ecc988ffaa9cc256ec9dee0a49a9427dcb52893a7725482933af490afd0639773caa4dc9c21eb37db29d914f83b7300531058a332679e485ad4af6d69595ba4439e8e8ac0f8ad1167adc87ab25e6198d0d39777ffea84500fe2a9ad829dafdfb399c9ded134b7ba591fd4316d7348c9b9eaea15efe97851f26ec5742899eaeb230ced49e4b4d630a7f511d23e3a05ce0df4524f691d9d4246161cfdba2ac039996c4a6b01f3b2b64e381ebbaff31aca2f64b48a4a6df38a9437b5cc4017a3179ba7f9b85c4d4304aa988330e6bcdab336f54968114231f4dde438b6c8e26c4813e86a7fa622db2f2d48c78fe6afbe9f938f0f27221c422ff1171c33cfa4e2af82a4bf7aaae8e9b8a353ae11efa957d1536b277c7cb4eb23ea23e7d1aa747a37bf7160ebc76a89810177f4748c02bf45e8f9031a9898d303e65a559c7ae3bdbaaf6392d5291f4f77ff241d0e3d4b541fcbb8c550bbe0c87d4bdf012bbeaecf107099588fc7669d24a5272a56d10016fcfecc3262da7a9f7643b620f2fc341379d6a828d6f0def7a4c0075a0a7c197ada249f13b9fce170be3793c75e31375ab4dc96a9bb64683ddb7f1fbafc8d0f5da66c953d59c1cb6c9da20bead5cde9736f6e5da43f8adc5e4f1765c33af81928f0ea47e8b9716120b36a84b555fdb655ff634ef471965de7c6d5046458f59e737019ef15c91ee1fb7e2b83ff138b23344d426518776ccd989b55b345ec4baec5c8ceb1e8ef8305b9aaa8a7ab3fabdd6b424ba2c9cdb2790d6993dfbaa1a51dbdd949ad28342d63d01ce059d3fbaa88fa722bac452811190eab30ca6a858bc13e1cb421fe89fea6ca1d53c86e95b3ff34bdd535b79debb49dad2af26613f3372fe493038b8e7b3e36349e9cbc88cee968efca6c1175a476ff64fa683b3a473deb1a84d4ee09ce9443faa5080cc68659c93b2054a1bb744a0f644fd18a7d651bd3ab2b7015c311292c58baddd439c2b04519365bf63114e82418184a3500a28aacc800d32cdb20a6b8db5196e7890bd51cc7c7218461dcc0291cca547fb8dc02bc9fd543f58a13bc50826445baca4d87cfc742e5cc399c09492ed7d3a13a50087d61675ea19d59869d8891553ce373eb5bbaa5393813ee7c0990028e34636d6e63cefee814124427d6365414e557649b0ccee5f212dbd5b9a7b6147eb13af7e05684ed4e4e45feef3eb47bfc829dab6a2e43aca8204ddd550b7c862a442acf66f8233ec36b829e665f8dceb8302a3f5bcfb3ef1ecf38e10ad6b385e1d1e2595e571a60b40b437a3317a5c955c426a76d4e13438b6cf126522bbb4928c1d8886e6437e5cf0678d0058c1f3e5a906868cb870ea15e498491ae249ceb66f1b3063fa313cc082c4c11d74d4f5426355c78bc920d307c3a33e4b30bbac3d59bd9c27bfc46634d3f9f5956c1a4b37c9b9ff3d4a3308c213959a8d434fa7f158048aa6b6191303df07df57092c645bc73ccd819e0c9a6a1456cb9c5b37798ef51f0215c61f31006046d5c7f8074e84e1512defd13dd99189cc983210ea1892d4f517157e492bf29cbdd8ffbeaaf1ff1c022959746dc4c47ccbb22463cf70c33b986b38c782bd4207b9e393e13c96230fc6d2a16a3700e5f37fead343ad1e1ddfd244c06b0884568042fe4024f913420b02fb3e2e85468e349d0852f09e1333c9e2b1c284beae6c426d550b4bf4f33ae1ba1d27543e9bb7eac7b69a333384259a49bb61ac8f996d8a31f50d81edeb248b958e2ffb3458073fcfb53648f2ea088ad932038039d33b2c436332644885df3074e9cd2ce094a9321ec1972f4aaec5d61faca062930c0523ac1fc39b400e4557a639095525ced1e2e30af223bf5a676ca786a850baca8ac72f4b8ed557e2e69065bfd7b2bbcfad115d67f420f8b25730344d7d5002341f7980e473aa343d3064de9592718ddc5eb6400834b884301853c689a94ee4f4d71ea17778c45bd2e9c63fe34bd815c2ceb1bc8eba0219b9b0dcef03edd68c8c799132955623f835d7d28c2f634b626bc346f72cb42c797f76b03cf1df7219307907b16a11db342ec4bdcc142e536000ffcdac30d8fa185c75af5cc93b4d3bb47d8e97548c5169d1e60b8838a1af0f47673f348ef34dcb547a7ab2be5d4868ae489fa5a7f486b5bafad46ca2145071d13413d111d7008e9aca649a1f7b4276ea3c295d3c403e634b1d044562635ac2d2a2ffdab137af654c7755627f4dcad23fb5c11dade3ec72e0f2cb27f7c29ecde16c48485dd3bb4548c48770e2a53f6ef3a100df30a289fedda399a65b3972ec6e7660bd4481a4e825187a728ea1cc55d0fa76a45d4d28be5a48721927749233c4d13878e94e59294662aa997d3ab2972b60f780bcfa7f2dcbe6271feafa3254994e1920f2162d3fc818a080270aba43d53f4b9f2dd459d4545b96530bf285b54345858f46a5151d722d57ba14e52895fafa529d49b829edcfe1e6bd75904e065cb24177d8e7c0bebae117a9a3466b8670ff94ad6b53fedeecbc42e10888f169cde543e329c8b3d4a9fb1c8faa90cd6727e0065870eb9bca9b548a78b1c2e2a515dae04a65da465a2d2ef5306af3f90e37f5e62341d423a691b9b4b949017b06289b1560259675f7060cf22763f9b903c848db44f21dc325b7d001364b77421e45705aed05818e21e5ba782a7e0404147a8599be2558a2a0481721dee886812b36a061d5a8a4aa2688554b55a4ecd0ea9a0dfef7177999b44dc611cf287f22ede0b48cc0a61a7aafcd5a90a5c9fe2d56ca6ba256228cf8521e40ae22f65626fcaab6bcb849ee29281f6ab63cc6144ea8e8e50f8c31981fe05660a36a1a48f97393e883301fb4dfde5365c8dd874abb80f7f9f29b9792c6ec182fbf170c7df438c0da0747b64c3497a01dc810dddab5dbdce6759a778b90d7586f294af8086d8c7c9895921955d709c31f3d6cb74683bafef669994bd92c88286583144841b78667e1ad986ab90ab291a2ffe1963219902fbf0a6688953c35ce90b841862e757092aa6e105ca4c4ae8d118f6b92bdb7589c7459338bcfdaca193ab222424dd9780e72bbb99027848bd98c17fb6792bfbf4015b184fe7af364c8794b779ff2a9f40df21298678ecb87f96d923e135044dbc785a9c01a9caaba01f21c1df8ee813a6acdc2f57f401e246bc68d9a7e206b532c18822e6ef78e2ea692d7fe778966b66339ed68f517f08be15d8cfc77091031d607ad1aee2715c1f107ec3b394e5a8868efea18ee201e38a3ba9cb8942e1cb53a0dc7394f2b395eed14c60ab095229e8f97e436eae101ad49496dc2e7dd2cf58c756726836e0229e0c7c6411b3c15dcb096687c309e3f890b81477d0778ec59e18e5bd2c3464fa3cb9b691e065beb47ae20e1b1b3678b4cdaa1e9e18e2e6f5bd35bb8d155bf01bef04a873a940e55d00f4339e57858d43ea59aaae065625dec516be14f35e47ab345b701d72720075d3a2c2bd84c771fa68e393d64379d904f44ad458863b76b85d8e27aaeb01e6dfec0373b055e086676d6f2f6ac2ef006ce79ad75444f3adc1b918126c63d17beb0e5aef1f43fb0fc7a24dd80ca79ef5782c06f204804d6b722cfb3eb2209fac46ec9a2f2e62e1ee496249297f756176c82598c464b7292efee14cfdd014f77ef03717109380fc3679ff8f8fc1ca1dc4de3883db8250350c9174eba0108a525d70d01e6e1622e8b92c8e1d6314b367c92312e4fe04deace29bc999a676061464c096b83503601164f9c4bc77350f41b6acba4ae8ddf3b1a9ddbdb00e21cdc6332ed6bd169e00dfadeb38bd331070f7f035005f74b8dabb045ddcc7b457f752046a7c3e917681a22453573c9cc186a787c8c34bb037f7a997b907e2010c012744a4874b60bd6d1ae1737c0921309890721149b37b28831b702804f32106d6891c5a83d06deba9363b98eb424b76fb81b3bb18b12c3a3ce3d6c8b6b59f813e9c711dba6d85b31daa880e1171c7c7fe215ef22182be8f48416296c9d012974fad1e42ec790bc5f2c87ac25a7b325e0367b5ca18c02797b85d506cc176015a15434c907c3c5bd2ba6801d3c5d6f689a6ee437a3ff57a13f2200b52e12bb88f3bbad1916c1c8c4271fd6e65e6caa3d596d813b93fc23d11d013208a4b78294f4525db427e6f37553d98b2aaab1e3ce0d2b3bcc3454aa7b92dd0f66d94b73154e4d2a2e0bba94dea2d60897af102be1a61c7604c978899661673f1f084e973683db77629de4824d49baa5264db6ea82ab9e68d212936c2ede646bfae6b3468b58c478daaa8439059eecfb235436c80ee5a7b9014d92863b8a38c576e4d23af63e0629bbfae3de3f2efc97d2e1f5730f6b407db9598019b94f8cc85b84518635679ffc2541703f52dc46e15169bb28964b61d544303cbbdc0f2c01a70ec8c7491973dd0fae7828e1b1afbe570a77a5dcc72a7828b7c83073048d160242354778f96d744e30127bd896162fe1b527769244e085ea1b98a372c7916225ef54b0b873c96431e948494dd41a3d52a20d3edb4c40584bbfac8223932f57a1b46d6a7d2d096f0f054da9a15f254bea7a2da7588fd6f581770ea4d6cae09723c823adeb5365bfa1296d0ed96ce32bac2d9b6fcbadef80414b947cdabbeb55d05c65b17674f3a7bf26a0e1bae14e4faa764aa5b79c489013877d7165b6735625f713178af6ec3be22f4186ff1e643c7bc72e800e6885420a85d4ff8a2c62024a98cd0ca152df105798c1fca80384319af5efb04576461180ec20d2d80b421ca59ae2888ddc6081ff8ba4ef2093f66c3ab1e40075ceb410f703cc1fd93f62ac55d023ccfdcc26b16e12ef0ca67fe26b1aa9c6c2718d887162abe6dd67bd6e3f1e7756e80fa2508af0425141ab57b3c8f39ba04cb05a82ebeff521b5f2effaa42621b33788537f12caca9d21c97e049ba04c0ccc2485ab748397aa54b30b57a35f9fc54ca730a14fe18b7524b8bdc827b98b6ca598e57d0e7d39331f91f1b734cfe9a592155dfd2dc4e6c723c8f38cf923810984d5dadf2f8b5fe52560068c479d689f3a03c2689ff0cc4891612671b2ca8eae71ce26c9e9935b094147186f388732588135beae42f886b47d26a15c47f55ae6db9f2e91875632bb5d1f842493ea54641bd847e3c04dd5c5841cd30838dcb880f671fd4040990cbd160abfb1964913e5be1863d112e57994b6bbc52c2cb20a3a982911240ee2843a35241b953263bd6a55927db1657d5e40cce3710b8bdab7e628acb6cedb6887157083dcdbcbb22769bca2c1dfbb86296e1a641795919512a14ba21eae122aeec217bf171dba7652877a4d8ea302dc7c76adfa9bc8072989eafb5cf6c2877a86ca82355ce3e058d7bcec565e5932613f0c8f4f6a7395cbf2fb9de11478a8448b0b76900a2f77af7c5a290daa815dda50f50f46a7f5ed15d5914dc4a2dacb14d6328ca0af38ade535154b8bd5ae17e09b585d3bf9e53b890e9b256745f1c7faeddcf2bfa34a76879ff95e261ca2e9f273b9b320e28d19f4e5e8ea84c6010adfbcb1cf100778fd24de1db787928c91926940d40bb35fd3c9c08b2838a02473a6f599c10dca97d817315e5e1dc433ddb560f35699287b36a4f8bfbf1bc08cf0318cb55ccd3a3e9bf9841dbe166dc7ebd58d2433c43cb3f34abe61e6cd00bf8839dbd158f6c5925b30a5fa1c8dcc14706dc6e6b40a2e378ea0599810fa66bddb18263b30a193f5ea6f49086bcda3d2a2f25e02f7632b7e10d6cfd42bd23c858134febfa45797b2572955eb567eb553cd8a4a5e335d5436c13475da8171c8adb2be1e921f3b47ea87a7165ba876483eac51e69cb6c99a3362d7c52b7383b78893378149ff012e7117c03704085d509d10c980a085d947d795df1fc5b9b5bbbe20655a88925e76695d8314cf3aebc1773f513347c7f36732b26acf5e63d7ec5c52d418a2cdd3cd64b15ea66833c59dc4a9c58f24a4cf16e9fbfb323e99b08a8d823bb33abe4537189db3003dc211657a8f6ae4d87b067fd2e4c0c552cbc0c33edece2ab30fdbcab3045e14d6861f3e58b305d38a28217615605f146e75c6d0ad8f83cc5b3b3788f7c9e24ec09f126e7a603e7ebe1ccf1995926f7a5cc3d988f700fe69092725b03df895b300796ba0573fab6cb967e4165e6a2c80dab655668dfbe34cba59edd326be66a62d1be0d5f7e8473e2d95bc9a72e25df3937cba4890c0d5bf667c8d0016c774b7b46706f13f819261eb91ef23f2616266002e8a92a627865d2100be1089b84ebc4872027c4b1a3f89aaf870ec64ab955805c929ccfb9487ceb949b7545fdb6e46d709e16dd960c26475dbb2b193e19baa1df42eed3e01c42fd904a3fc6bc82c76b5141722e7288e0b4df72f7920fcf45340d0bf7d5fde2a7eac8c79d3832f5700d0136ff1c5d772f73c7f72aa4f335f631474a64c03c2b6a74e04643dee00924e2807f7eb97d2adfb7c4edfdf2d6ddf52a5ea6fc04886dd1833d48726811bd573ba778b37a8554442c775bdcd6a1dd082d5ac008e6f6e9bc11ced6352ee75e283cbfec5319d6922f3195102a93f34fda3249d7ccfad4a5b09f4fcc9639a0c4e9e9ca68c3cabf8d754bbfea7555bfdc75a45fee3ab0499dab878d0e8d6c5c4f6e33dd8735cb64222efcbfe746d593b8f1ffe11876f5d2e805def25f4d6faeef239d8e917036b7fc11e34a6c5e88d536aa68f19127a952e432ad82e349362b10ae85c478aa4e09a620fc3416d9a8cc6e0e60b41f2f83165260ff427d55a026be2af0005c0abb314d5170f364d1f5f260115d980d75cbf7d3711a0db7ef2df00d12749b57611d5252b8d6ea68e08dfbb85bdcc248691f3dc91df89261d30394028d3f83cbc789fa398d57861048aa0f5b485b6e1bfb68bd3d6042a4f759b6d6c4f3a190c4430bc2106c8450924f79f928c0dbd4efb1c8f033882c3fd39b4d143dab2798835021150fd7edf671fa0503e84684a30e20878f9bd5872444351c7c16dfc0e810da8d3e4bb486dc97b6b278b6d920b49b4ce3c920b76789c8ea43150deeb170c4c5b7da1e8eb54bd8c14ac16324105aad3e23f206e6f472d92b42b30cecd562dee04710d1ae468ef8b81d4499e19c1b1e026b422bf861b72aec410b0dde14a91c109adcc4aaf7b85d5eb9d84207e3194e395e611a51158e70d2676b028fcd2738be7a3dc29763fe448b163ed6c55dec94508c7457e15b1527692b1d625fece39cac5f0bffe51e2f8eef35b50145f2f6ffcfa6c3272e755877171003fa467dba03bd71f617a08e2b7853de067cba88ca234f22698ffa562153b8287617a070eb19d2e92a13de559bfb9daa0af1995411f7cdab62a386738a55acf32a2acf743f0f355653cc511f1c34c304b3f4e060c2d51984b991af1aa0b5a03797c0579e33c55732e40fa77aebcf79f4e9418657631fa6a14f1f608c2515b920953e48c74f7027bdec5c75cf91a5200673fdaa19e64cb12d963b9cd5e8ace2ad1447ca6aade057b16b68fb08ff996e962498e39555199ae4d3feb5042da382a8f275ca059ce8a41a5711522c9ac2f81f34405471eedf2c69993757be932df67c06698ff4b1317f1adc53bc1946945d051fe53a0013df49814d4cd6ad10ba2de8b97a0d79581742c08b5a7b7037441dae73a091ac35704482131ff8217ed886734eb944e6adde938d633513f4a4a066cd21f6858f123376c4c767dadaa2dc954c30f5765c313b707f1f58c9c7e21813c53daddc9d42f4e19f9c1ca23d9cca185285d0ca5386748f403a36ce21dd7e96742713cc006ef37e5f6447bf0e33da84bd968bdcd16709be6ef3e5f36c8d73086e6bfbd7b02ddc39534bb7829f7c2077ba0210a5611134ee2d6d318d95fc17471aecb228b3e108350709657a199f8ec0fe6e0c20d9fb6a17bbb8e788fd7bfce6885fc2855ebfe33370c6906333a3818b0b1a8935b5b62ac4f65128220b90ce23b20ef8a2ad33f11be9519589c20ded04f3155e72c48b5f115ab0050789667bf09196c6a6956a293899af46688fb9f4521510e751e92c8794c756aac2ae0861a36fecdcb802dfb33ff416740eb424b91aa9ced548a58f16cb7a5b180ef841992eb8e42d9d6c5ab7af08f5a8a885cb3cca17a87d762a166b53008ecd16391b94cc1669ed622bfd6aea6d88b3751bd7a977b079adf51dd9d8c55418b84bd3c6885345e482c0fb5686367cd984da17e93142097ba3b58ad800ec10d229b6b586ea78b9137cd65104e4453a51554f85aa60fa9276b65f66bb7ea2e957b645065195943f2127362160582369f665d5e3c32c0be7e85a1bc0b5794dbc3a28b641fd917a9dec4a3891a5ebe4d0b3f38be3b7bd2a738b364865d70ee0be8d266eadca3467522d6b753998857d0de940fa2e2aae6250301dce064947334ff118994bb58a3c2c127e9ea6f87d698824845d86ea33dc3dd4e2ca4f7ce94cccdbd0129e385ee1dada548bbe4eecfbd203269ef541d6de09898012949e08e5238cf7d84aa9408bd61014edf53d94fc94961c686a0bc5d695c839904da3293ee2caa02c0cef025e7307e9e2dbf3391b4b3ef23541bbdb9d2976a7edd0c918f6dc8d11f63f6a8a2b74230b675219484fd2b784393b6c286fd2b3a6740177c4a5a7502c891b65702fd2c6fbf6aa846ea3ba8bc43e789dd89f846520ba00e17fda97f6cad635043046d6c0e6fee4b6b8e48de648e81c8d51b036bac08c85ce0b7aa228b4e3ceb5708ea13d520f9bdcd80f2966eae1a35226622b003be36336056c9754ba781bef7d37ed206dc3fd2b046ebcac88aef71ae60e6708783380ddb8a1e5b5f5ce8eb0b77dbc7f6fbf8d666556ab99d7e4b26b564827b482d996c51d6c3571d7a668da85a62988d5ba0b4d37bfa9e57b8b4fd5c8124a3ea6a93de97733eaa284073c39df7a9043d1fd860619ac7af1154219fc287f36cbe450fafbbd8616a9e8d37e430e38856e5bf78d2c836d5fa76c48e17ebe0a9a62680de5325b31d744050e7fe0965fb904d1455174d8351d520167b8723c972db773eaf44bc8c792ffc41de3c8ac3494cc0a2cd86f55cc32095a9f2089731e27d4c53518f4a8f91d4c77f2d9ac9066b298e97e4c535dcedf432bb4769d8cc4aa91e70b25b216ec33ac3731f353046a3ff3b53ba6e30b1d27fe84c78d7118ae633a64d3ead3dcf0e0aafeb033f56da85a66bbebc17ab2cc2a7cefef52d5a5c7ead76d52d5bf4c55d33f3ad5ccff96546043f87836c00ffb5b29de46894ca81ea3d43e4eb55522eb99ef4cad97d553cf267b540f676ed196d922e53bd43190e77fbd8ba20f677a07f764e4bf65bcf147dc14748dd7896004a28f9abc77a1eed0acb8222dc2263650bf8ecfcf705cb9b9cecd1f388b4c0bc264c38f3ef4100dbe0737c633bdb0b2cabb69360b37e8ec484b3c0441ddb850d62fed5b8f808e51c606c499ecbef5809b65a86caa13fcd09a87219f08f662ea0f30c4d6ee91a48aad64434359d1d5b11d64aa42d3fa5256545da6a209de2c6b1fea14dc68e6e1d5c989475fc2e3abeeca2b89cf1af045e63530ab1de703c8d3319bf0b97af8da1ff0f2e53de82a3c75c1c955fea4bf85b49318b264aabbbcdc311e3bbac7c4991adcd6629fe27d2be868d40617ea88dc157fdb1725bc0b59a44eecd32d0888746cccb2c7579196a6c0a9839b35b245bc0313cb5780ca3573c72664d586e60fa3431c249b5f67551c8ae5666c6d1753a7e29669d3c2f5277554aa833179466a9e55567c0abb8a0c19bc45ce045299343caeb5ce06960440f946483358b0f5d5806f839ff55254be8a1a7d701ace82140c2ab0955079ff6207b6eba1961ee5042102ab0277a934d3a3c71059e633572da157ae9d4d8463fce27e9e8a3aa18ab7bfeab72cd54939b1f68e75dbfd6ac55cb9733db6f27ec509c3b5adf5bbfd9de2d6d6dedda653dc728add9dddf6da7dbc62aec4c128eab098067ec2fc64e5fd3f56c64e640c9dd03830bedcf837c9cdca5ac1b9bb59796f14d7d7cd14b2761fcf0023841435c8bbee330237b240553c031f3c2270330b54c819b83741e05616a89033f0a183c0ed2c502167e0b140dec9021572069ef808dccd0215b20e57408d44823e7b1a44a1a5c03643c8be0651681ab00790e2ba0691683a708890a20651681a108756dcd0200a4d030608d9d4200a4d03227b14b7348842d38002b2ad41145a0aece01c1577348842d38002b2ab41149a061c23644f8328340d882c57dcd7200a2d0576b16f1beb1a44a2e9409cd38da20679e72408dcc80255f10cbcd347e06616a89075b8026acde1a837b63488424b81cc43c8b60651681ad07fd72c2370270b54c819b83342e06e16a890337031dd1b7b59a042cec07b6d04ee67810a390377711636d7b340893c0547526c16b340859c81fbb8b43737b24085acc171056d6e6a1085a60105449b9af85d5794ddce0255f10c7c24803b59a042d6e10aa83587ccb9a94d8de24c1d8833bba94d8a9a560d788773bab9af41149a067401b2b5ae41249a0e443a6c15358842d3802885b6363488e4aeadcd2c5015cfc271d16d6d65810a59872ba0d61cca90ad6d0da2d052604f7469478328340dd845c8ae0651681a10f9766b4f8328340d180cdf798ed0685bfb337055447b8573bdbdae41249a06ece32adb2e6a1085a60171aeb737348842d3803889db9b1a44a16940d1b72d0da2d034e0e49d830a717b3b0b54c829dc45826fef681085a6010564578328340d880b6a7b4f834806dbdecf0255711dae80690df7c8393beb1a44a2e94014fe3b450da2d052e040d4b6a141149a061c2064538328340d8874ded9d2200a4d032207ee6c6b1085a60171c9efec681085a601910d7676358842d380b83077f63488424b811e2a979d7d0da2d03420f66d775d8348341d880cb05bd4200a4d03e264ed6e681085960287b8ca7637358842d380b8ca76b7348842d38038a7bbdb1a44a16940942dbb3b1a44a169409cd3dd5d0da2d034202eeddd3d0da2d034a080ec6b9077439cc1bdf52c5016cfc0559d5a0d38177b450da2ca6a40d18a46f6b48914e8239fec6d6a1085a60171caf6b6348842d38048e4bd6d0df24e38057b3b59a02aaec31550ab0167646f578328b414183aef5c81b997052a640d2efab9af41149a064452efaf6b9077c241d82f6681b27806ae80690d11aeb8fd0d0da2d034204a83fd4d0da2d052608c727e7f4b8328340d8853b0bfad41149a06c415b7bfa341149a06c415b7bfab41149a064422efef691085a6011f10b2af41149a0604b26f688e7c1cbdeb4c220fc1c569b0a822fb4601b55a0464438328340d38468846fab142d3808f08d148ffa8d05260e220645b8328340dc810b2a341149a0e4c10b4ab8314a206ed21644f8328340dd847c8be0651681ad07b1722a6e6b303502267e002b5a88314a206c579d61cf7444d9b0e7cc689d73cf7e4594d7a063a44d0960e52f6e386e6ac4bb8aa25f34a41d38a46bd771d51cb4e16a89035f80021bb1a44a1694031fe3d0da2d034e03342f635483a28cd7d17605945e68daa37ad65ec225a5183a8b229f0e95d18b3113a751b9ab72fe1aa48fa6a2290373588424b81cf7d4953cdb707a042cec0fb4856cdc307a042cec0135c9e9a870f4085bc73e37ffd70e3f3ffee467e277103df7864edd0e90c20f6f894bc8dd8c31f18731c3b91e1768d83298c731607de980122af2b8958328a7ce3f656e0dd46ec61e446ecf6f6addbe5285fe7b6a6d7858dba776fff23a7a6b5e0edd0094d83230a4cec20330e0c9f3d1a761405d1db9b15eaf87e901877aedf35864177e431e3cdcd8ab1ca4b1aabc6cdca9b9b15ecf64dc2d63a419757f0a6562fb54eecdbd3fac5ed61bd755a7a2330927e143c1a0c9ebe6a631d3ae13f22f6f04f1c5c764c6b0336898d0363ce90ab6c12bf154310b5d5dbf7ac83e5f82881641f66aa8d9056f3e6e3c38d8fe35d634f611025f10ce26c9530bb1bbb7b1f56cc1577c84b19ffd77062e39c399dc4b88b82a1f126e2bfdf7cb8896e7c81721a74593309228618372b4e1816620e880beaddcd8a5ee48bebf3219a46d08e593466d157597618b49fde411ba20494f21316dd391d669c4541181b5f38d0300cc397d5fff7fbb41b50ecab2cfbffb0a9b7372b7eda973fe08d6c9c3f20918c2ebb73465e62743c278e8d5698b84366b0a784f95d4186351a0cc3c0677ef2113a631a8e3ff933ed52c4fc2e8b60460504a130b36f7518fffb88751e464e6fc8fce4cfe9f7fc4ff4e24bd277e3b590b7b9a686b23682975f67ea2d2ca8f88f0ff2e9ab22d5df330e337ec9a298afd1bf78ca6537f2e73c4e9c6414af8d11e987cc3dff5fa160b87ec71b75596c74fa4e941841c805566c24017f1331276646c8a2bb201a3a7e8799467b6274ddd8697baedf13651cdf1d3a504c233297cc82d09463d545c50729c998c77867e3f7592a7aaecfa640fc2f613e1ffb7b635d7fa348f1d594bf5477a62ae98e22015e9f2dd40fc62c9a2aa02a2a2d2a19b1380cfcd81d333207ffebeb842b75a2ae5c29f0f65d3b089238899cb0c0df6557d9cf5d98b2c489ebb3afd94ec1dcdfc7ef36a6507326fdabdeb7a11b770af0f6072dfe4ee0c70970cd14a309a5eac4b1dbf3dfaa2ae38ee3b169a67b224f1cf68f59b6733b836964c520a324680edcf0bd91442366e6a10c9da70b5ec3893b7493f7c65e2ed25de0274df799cd7b3f74fdf320912c35af9d45285f6720bdc8edf2599d37b6ae1b879e33796fdc395ecc66eacbacc17f666a9fcc23e577363933844553d3713cafed7406ef5323ecedd8f146cc345cbfcb9e4c039ee23ff28b1ba934af39497fcd69c7583c15a68bfb6664a6b53877d274e6d8ca456ab39eeb93e4338b82397c966d5d9b8df44512045ee286d3d49254caa3a2e7b499a7934fd45149d8d034ba4ee2cca19dc7122c6c1c00da1aff276649fc0fad0609acf0c9f8e71ae0e79256ccc2fffce717c0f96afce71735237a7d383b5fff67a692aff9ea02448899a7a2fef8f023cc8ada59132afda976055707b9d604bc59b382ee24f7758a72e1261efbb3c6e2d8e9b1d8386391d1649dc0ef7e2c68efe7d6110f1dcf9bfb9affd5ce9aefe718359e1327b7c330be1db224723b6bc330feba36b7a942dad65c1c2e5d8c3e737bfde4e0cbf6fa57e0bf83fcd68761dc6491cbe2afd2e839f832ad44be16f2a95b984f5e7cf7638defbf2d82bf2d82a94afeb608feb608feb608fea52c820b378cff754c023a8a22e627d0eb1f650b5c20bfcd370638434a6b80fffe85e6006fee6f7be0f7b40774ca84114b9249ec3e8be1bc49016ffe361ee0efaf301ee27ef0f8e984cbe33857b9fd6d5c2c695ca4ecfc76cace788da131c5279bafb746feb7991079749fb5267e2373a2c6863fcc9ae0d41db2a171602cda7d18b2e1875f6a832cb2256a6c184413a3153b3df6e58df166664f44ffd36777c8866b7de684b7ae3f8a99b16a6890aec78c77867a8e98c79c9875ff30560138bc8d43c7570511d4713a7d86b0550e8913a733b88d27f11f73bbf4a3eca93235e8a483da8737ed8f86b7bdce57e3ed891327f84abc01eb2a744631bbed758c82515c87bfafc3f80fe39df122fd8e9813be7f19ed1ff5f6bd6810e81780c68cbf9a46c57fd78a7967e64ec41ff9824cfe9db3c4717dd69d57c5bc99fbfacf652cc8dcf7d3d6e3a2ee190b234d6cf8b26539aff6dfc4e20c7ca07f34d7ec94085993ed3c789c57e23c78cce2d2c09b5fbb97c5151be49ad1d891722f2ee0cb6c01b9bd9a5f42bccd165111dcfc32f275b650eae4e59752efff021bfdc48d9372148cc2796456085313f32a7743e9a5396413afff929d7fd49c2527eeb7033ea89fea88cb1591bf80fb9b7faa7e7c2cf437f3b1f8fa814e9f3a4376f0e56665d87eb779b3f27581fa0c16eb8cf9ca79066bb1a29e45477dc6276a9e932f0c09b7fb752915384d8aa5108d65a83053205d1b6327721d3fe1c4bef346717f11b55fae6e8d1b8f7f7e449154f8f36361eacdab3a99165e9e1285d790e2b7a39b10ccbf35e13e169661cd451a7b166ffefa9edbadf9ddf84629f2516a384efd5fd7aad290bfb659a9975edfeac742bea8ff6ea3eb4b954d403fd863e6275fffa2dc3c51e23088867c9cd17c2b4d43c996b59f422f885834af9399f7bfc680acf8e168b13194627c9fa9c2df327d80fffd3e4b90a50d1af58665e9f582b9a31a634ed4e9b79d6879b347f67f14769d846105c681f196fd611cfc99b583347d9fe9de9a5ef62d5b4b9ca8c792b5a9adb3af1ff4e6d813eb8c32edbd37326b61b679f7ce78cbd6066c62fcc7c181f1c6e6f3f4e60f619d7d58aaa3313447fcc9db79fd9a1f3cf982854d03ffeffabdafd9600a9b99f1a58cc82512477f868da8ad8eb46659f1cbaa4e17044b28d0d0733aac1f785d161ddcac906e3762716c049131c4b414c3eddeac2c5311b740de41444fabe79b2ae9b2b813b96dd66d4f0e6e56da4eec76de39dd6ee01797ab04d8fb4070c55723f069dff17b4c0408f425f1425801ff02bfca26ad5014cf2c8fa5ca63c62eebca1e71fe7ca95c7ee041fe7dd4e4e30f33567e6e0afbcf5225bf44fdbece07ff0e857bc119655e4bf0f2df441d9eb86376c8d80f0902800a18c6bd5856faa2f49725e74bfed748f58512fd658fff15debeeee9f3c11a7cb4af72e65fafafa6476a3cc5075f8a1bcbbb971ffb3b2ac5f163a1bfb37c4160f8d7f99a499f392f0758b245f263448bcb74ffac743f1692d735258b5e72fdf4ead21f0bafece9c7c2b750a3bd6cd849fe6597de2b3bf8aad63e1696e788e522082f470f96891c2c881ae47763b6d97fbb3d825f93f732e35d7d9d13f89e419c5351aa4216d723f1fec240baecca5f1c47bf70fc9ec7546f7e6934fde580a2f062ef82c870d02561ba7313cf4d7183fa0b3fceba8637335c38677f719acbe6a02dde42bde8bbb132f60c7718e2813f482b32dcd8e83367ec7a13c3f5e3d08d58d7684f8c8fcebcdafa11bbe393d64f92307e5fe0aa2581995f0ba21e9fc50ce063c1f93397b4f3f67dff0ee3bd14c6e32f1615fa7e1fe45fd5a73875c67f47d97ecb289b2c3e57bd0053bbbee7facc70622e5fbaee78ae9fb544642b9984ece06625614fc9cdca37457eb2f130313f499f19a8e8d6d6d66e56a6224cf3aad2a377c6307a170fdf6ddcacbc2a1ef4dad8d3aca6f808d26119a12a1615f34743e3aa598b7b179390a57cd084ed639527543b6bd620575c03a15255cfa7ccedf5db41c44ba658a5c8efa9870b378ca7abb96451c29e74948a7f1798192922fa9a8aababa6683ded30e785f7863f1ab659a446dc7512e73d5ffe59a9c4718d929338478edff558c457a44285a5380edcae5a297c3df411130ed5a76b48744ce55846ace7c6098b44bd6f8748d64a49f6cc9415bdd7dbd7d69f6ce71faae83f8d0309fd904715d5f8c87fb179ada12ef358c2f2da5bdc4a27f07dd649ae58bb1974062c791b3a49ffbd112791ebf74c23f0eb21f3f9ffa917c48cff80cb62b49621bf34e81807c6a3eb7783c7352fe8809df241c71845ae7160bc798cdfbfc9882c2e17bda0c3a550127402cf38e0e2110d953753824cd5212b31f4b451fe76f5c0785328bc3156798fd6fa419c18ab061f51a64dde9fc758dc7d938e7c14b97f64f01ee3b5c00f42e61b0782101f32af3a9c24f00e88937dc93899e025106cb662195dcf575790571af7de6b6be3c0386ed64fd742278ad95b0619bbd9c4668db15326035658e34be49f1fa615d27ff4671856fee528a68ccceaa73c39d593af1fe6c9a53367e2054e372b99f8ba310eb44c7908b018074651410e9d518725c681b19191431ca758cc152dd01cc7698eda49b6399109acb748db3826d9a6aaad50302c27763ba2e333c68bfe326da28317d1df266ee231b9943e4cbdcdc0f50679afe7b5a7bd4b9b8b47ed1061b72834a71a74fd3871fc0ebb75bbb30235f27ba2708e5c9d699bb6675a8f82913f5b6f18b1f16decf6663a9307eb8683b9d4406608e7d003dece744952838f77aaa9d089f8ccb8dddbf505ef8a33ef92a7bcda5c3f1c25f17b83449133c19dbff84ff5361825faeb3a3efe39a5ccf2c69d1923569b8e4e78c24b94142d2e2ecae16dc7e30c227b6ae1e39f0baa162869d56053cdb04127f08268b6a7a90ff8c5012d641a9d60188e12d695fe18b7b1a4bfc71db2ac5b38a518cdd4e2993d0d75d59c72fcf4456b66d9dad45798a90b1053175e6686f1669b94cb77f60896e6ee0a4770f62cd820e3e7be8b8251c2a277dd6098a5c139c0c15ccf715d4531cd3994f30767b4cacc67b11b0bcd52291907c6cd4af13bff721a13c72da66cbb9ca514079edb75ef5cb41c6e1377c8e2c41986332ce5c6f108a4d97c94983d8c184741786e152cba0d476dcfeddc0ed8244f4af94e328a668569128dfcc1ad50dd7932a11d397ea7bf080386fade680781c71cffc3b4d4ca357ce7cb6824b1d8b13f6731d76d2f2e78144db76e774a3afd995737be5a387b4280c4b912042565c71bc57c66e3c449d87ba32201dcbd60ba728c474316dd768211d791d3333bcb25199ca99e7f9f944aebc97656441e12cf1db0a979bc492276cf3ac92cfccef51dcf7d9e7dd109fc3bcfed24aedfcb7be546c3e932539d437f727ae605ffbd978bef9cdd7d98e18a0cd7e4d59d169e3bfd33873f31e8d9749fc1865b4f450237c91a23164dc01e4e2b3c0d92436e4470f4f91a271b1353850b0568d2b863ac2b61ff2f552186e7242c4ee472540c9a0eec4fe3c0f8c73f33d679a1603c8ce0d4495e8d6094a726b93ff2d283723a1ea7f2148975747d0081d375fd5e5e25bc1f935b81a0d8c038c08397b9ed62111645202ce63489b18bbce2f8464e31e80521d7f3316f2318dafb2c1f2ea08b0a9b2c379c19c937539f327f531ccd38953af2bda129cc0c12306e34ea2441f4765e813f7262891aae71a03735153dcbfaf0ca5259930117accde976e58681783115e849b59b88021a0786134ffc8ef1764eb0538f98b97eef6d124d5fb99144939c83a62c3122c6dd63e7d17113e38e259dfedbff2938a15bc0c60bff89112d1141fb9fd9e3b5a28e3cc6c04a23f8364be0bf9d2d3bd3772cfa16ebcbe27f353a4ed2e91b6f5994e7c46a55a5920770f31ddb6c34f5ffa171aa9889c52c4943be73889e5915d3eb600a0b175896f7177661962abc2779845eb277512afa97ec9f9cdd581242c39f578f7160bc7933137c98edd09a10d3f366525b636be128e64c29c3d60551b4f09f5fe673e54b318d39bd12faf25b7a258a7e57af5e6c646b7d2bb781a55989335156ee2f641fe3c0989aefa55b428e7a3bab03a0c119d653bf3fcc4ac054050b29981a260be521088213d4a83f4224a68ce776f3a6973315977678800bc29b5beb5b73ceeae70bacf4e79a3496f26f34c861a5197632f4e0a246c457886551eaed30eefd42712c149fc84dfeaba73d5dd9ff5ad39e6f96be66f645d9b7bca6bf581b2fd0c3c3b83757fb2a13791a63093996f2dfdb1c52cee90cc7e454ee76a357f4660a437801df6231a4cbfcadbeec17926e18f77e7c5ff95ffce802930ce3de9a1ef4c8e1988e13333df0b6568afcdefbb92b48d4869d574f4e3c1d539f2eacf4be28b2361552370e0ef458e01a6d2fb88c069598aa40edb28baab588bbec990a3fe655f9d5605ecc7e5473d3bb1933ade501db117306331261666e2026fa0d93a3c7525f6600277166da98c1c20da3193c710bcc37f4f125bacd9268392936ab9bf81a9df6f753e3687a75895f4b36618b2dc9b7323a304700e8ab9c457345d6a245fe3d5eceac2b3c2db8ced9dd6cd70b05d876627e627447a1e7769c84c5c6dbb81f8cbcaed166c69d1327c6a39bf48dc0f726065c84565cff23d703988a1badddb97e17ee467afb16853c7eff0319c5edfe010afe5d31472eccadd2637e2fe91b7f1e6482668b2c84e91ae2be7b97e428eb99559c5b1adc8859136ece14c90d1a09e8a109a972c7f3928eee18eba6e135f9e62e888cb7fcb52b85d51ccabc338a1f0c971368fd83e1be7b97431a61c8cea9e81fee3f6768c3fb8443cf23f3c72432066c72f005a775417aeb0bf9ff1f4f5c7f6024c1c1975c1f5554ff3f2f1fc410a85cc4c749f476dd3436b7e75f8f648823fbfe6041eeeb9caee71e5198c31c469a17c6093a1ba99a0ee2ca0bb866730b7f8b8368afcf06fde1399adf9485f9ba5ccb4cbac2ab732c172417867227f43b530aa5c6fdafff9a7ef3171de795235bcbe4747c15177a19af29bae84ab3ff05473dbfe77c48668f7bb9b398df7a61d317cdce5fb0b1ff3bac663d19e8272c6653db59f9f75bd81f97bfd666fa661d483d93038a9155dea7cb7dca77fc6accdcbfb3506c2c73e1cee2e3713f73ec15914b66544ada90b50cb35f3bdcf9a775becc6d75691fdff86fe3ad612ceefd12cc9bc5ffde03bccb1fb77cfdbd4d46ce849f637adf97945a6b90f1f7da79ceb4f1ca3ba57ed46950e35f7206ce22367683516c34d3a4247d3a64aae5df33f2e2df0f9a913913f1f71cbc8468fcb83928b97112b9ed51c2bac61924f2195536c94e48371ce44cc8ef3e1f0bcd7bfdef0fe3fdaca195a9e9df5e3be9b33de3a169efda9384c5bf152ffc483ec87bf18bbf71fbb3bc46cbe9f6e65ea9032fd117fb5eaf6ff9b4eb5febc67ea974025f7c707aea13216e27f0e3cce8bf1c3ab4cfc651e05337ea78ecdcedf5734b15ee9c1febc2a67560b2f0544d2f9c3b88fffbbd4cd5858273aad651be23a5f75bddedcc5993bf2278f6bfcdcf3e83f338c6bae6686ac7775e29cd7f6fb75a0cb5983bd4e22f1dea0fbf1ef62791ec2272fc18f70db3c10838aaf56f4cb2ae3b36e264e2b1832f739302e4dfd0897aae6f0549120cdf1b372b1bebe1d3cdcac2af45182045ba5dd7efa5e58acb956b075197455a73e1131ed930fe0f63ec66e5ebd73ff134dbfb8f85ae3b5e3cce571aaf2fd2c2d0623f78706f6de8846fe1a771f0e762533ad33371224f68b5832f5085cc12fd8afb8759d8e20b21f9df1f2fede92d498e97659831ec1edcac38a32478e13ed28f9aedb176160563b7cb227979c217a9626f56fecffabab37e7777b362c2963a4c3c1bc26cbfb8a85fc3cc8662e88b20e4ad6c01572ed10c3495671cbd705327947b99530b7984fa695ae65f7bfd8b33a97fb5001067734102e0ef5789002cb226ec57a845fc7e5535304c794a17c486ac1156d9e2fdc5b97f4a2e895e4a21f44d9549135d75edeb126b46fefd91eb9a66317eb6d8fb9e2d82ae933839a6b4aafa9be2254bc5495e191f99898ec1d1f22ffa38be21fab16cd4e30589367702be3f4671a31dd1844534cf2fd3dcd26fbf4eef07de2bfba2f0cb4b1f4a53ce353f51aeee655289728abd64152f4c249a378aefb937f366eadcf1df73fa7bcce97243c4789dfc9ecdcd4a3cea74581c2f71f37d662452eb083d08c936b9efc1087d61c0d0a75fccc57fdffefaaafc39d3f8327d23c52b03a5cdd0f5175050bcfe313942cb04a5757c6081ae93b0bb201a3a920f52c09b6f0c45ebe97cb2c4d48db73aca9b9ba934a7c545358c4cc99cab4fa68bea2899b25a8ebe5e54cfad7a73f3b32fb334c0314a3afdff9efaca6ee844ce30efd3bbe911b3ec977df3b5d7cfbb775f2c0ec8e51747b75e1d8856d35472bbb560e427d3aa72eef593daf9e7a99cf3176eac94c7053534a0ff1a127ccdedce39eaaefa7ae57a5ecb1fbebebb6fe7d4dc6349d377c2b81f24165f85ac05a724de86111b03e9de1b82821c02d77efc317b9fa7c29e1e0fdcf1b960b873cec6fd18121a7312b5b327dda6a8a1adcc690acbf35a73bbf84d07b9f2cef1689dbd59e118b35f8c79c5a9235513a02c51d5dcc365699f22bfb74445738e1f65aa429cd9ca169d5152855bfec00f1efd6ce9afb9738bf6b0e8ddaf99da17c8f851d32cb3b184d74ff0475ddd2c51e14f3b4226fba32bdd6c7f164d51eedea03bbd2da8affa993b19be0ce39e99bd33c64cef8379d50623176f70c0e960e6aeb0b99745e607be5eb8851e50fa9b7f8a56e409afb937d1037ef867c5876b7ddbace7fabeebf7f853c48c472706780f6b5b9b7709fcbc1bcb8dfc232fd3945134fd39b490a7defc20319cb1e37a70d1cd3b636b7deb25ba2c728564b57004ae5242eee26ddc0523bf3bf732fd9f40c3eff862c14bfcb1800630de855f625f18431ec6bd05c140e35b12aeda73be2190418a43c75f2e0a38ed7d7b6eaf9fdcaca8ed02dc0e809d8ff746717dc99d13c3302ae2d23de3026e5cfb92fa2e6f7df66894b8e904e7d4662ee733fe2f7c30ff0fd3b859e976d786c3b5c96432318e8eded76aefe3f866657100580ded052f7e19322c3bd866e692b997863cefe2c25f3cf08f8517d964e9607a6ec7e64981b94b66f17279cd52f9f6bcc4a57312bf211f713ae6be6c39fe27d3882ef0e80868e569237ce9fd9a6fcf6afc8e1134c51d9bc6a9b86313cea94eddbcf99b0f01efe1fca256b1f1dfc69b6b16bf31de1b6f4e83f95ae287f4fe3529a5af4927fddfb5902a70956b36035c2aa2cc15afbf372b4acb4c3f59006c299fffe645ade4afe3c5cc474012f694bc838b3e96b725e04f66f7a969867cb54576e89caebd74a3c0f4e5c4cb6c204dffe557f4aa8e2ede62ca43ff8b39d6f817e6aa8d9fce5533375a7f335bcdd6f4efcd57bf8f24ec6ffd298ccb8f85fed6bfd5d07e93e58846fc54b4f55f536dcf79fbb2c396ef38fe845b39b2f74ffdd77f191fe5feafe3bb43f0c40f6e56301df166a5f0e70fbc7be3277de9f0ef1c80df77bf9f782c4ae6958197dfb2df7ff3f71e77de1eb7b84ef35f6d8f5b5e8afaea3dee7fb59de8d70cd478f54ef48fdb0a73badde83bf6c2f4ba44b2f8ec4d76709faedc9fb9954969f978499038deadca12874fcfd59cf0ed1f335b6f1cbbc712bd3ef5b53e99669e771939e703951827aed03b3830d6e7dc28a83693d9304c26da371e72674e2b21dbc816f82bf6c9e45dbc3f789f4c56fbd7ed8f71dac1f5cab364cbdc9eb8fec1708d8f90f1bf967ed3474cfe07c35d5d9d33f9295b8b6b89b5e2f2d6c479e5c4377abaf06d906608dfb2cb611f0d5d7ee0064a50fd8337702be89cc29c08e20843f6b3400b2edf557d5be54d25d1685ee50b1b30fe34f26ef29c6a68fea85e6837d71a7de99edfecc816d16d869be41f7cb6415c47cea70e7ece9d3b8d3a535f6f5a531f265a4024d1d0ea81f1c650f8c69bfc1ee3d817b4283fabb46483127d717b4b5515321f9c8c39352da2f57c8520ffd462be3f58ff60dccf2ee57fb8ff5c9b92e91f8cfbb9cb7aaae5dcb5adeafbc7fd3fe7d5b1a8eec0eb5aaafaf5858b2ba3f3d6fa4e2cf513e66dfff1c21acbb494adabc792a9ba5eb7da0c4dc84e91674a14700dca3dcc1ccc6f5916fc2f3b94787a28a691390566ac6a84786198f35e2a169a7bf1adfc9b8e8d644ea561b6fd12190b43c75b2e7af3e50d8563a46fbe1a53ad185fdee0950b9977781ee0e560c7cb3d583ae232ff7a95bc17f260e14242e712594abe05970e1bcb13178e6a7c7923bedd57290115d3263050fcf2214cfe278be5643a18ff81ab63a968156f6bf9dc8a058dbe9c59b1dcc05ee62320226a8325ebc4225259bfb69034215e55ee8d900dfa4291dd7de9fec21716ca528b64cefde3337e6546eadd0591ed74fa6fdfaa6fcfca0faa67ae6e99bde55dfecdfa5ddfb0e6961468ba945a209d1644199721e30c155f76a4bf25814e7937f05192ff38c00f794010155288de7ec97727be1af5ff9fbd6fe16edb461afd2b88ba1bcb37b41e8ef352ad74d3246d73bfbc4eec6dbf73aa5e171221893545b204245bebeabfdf832701022029c94ed27b3fefd9c62630036030180c06839925156d87c2d56873fb2e785bfb189943f8ae92d5efe2397989520635dd54641eb5fd5e63a1c96d8fd297ed66d4ba82791225b3a651d9e8cf3b78dd616d4a4306cc11c0f3f42af19e698d3e701be7fee2f46f1060ee66d47aa10c092aabeda8b50137ba49a66d4b9fc3e6aff5ffbf8bf4a8f3ef345ee2f936dc0bf8b4c8d7c02122308af994087edee596edb312beb1e725fd713e2d5098eefe42f5f62ed78ae1ef7ef7e85425beba5bb8aff6b66cf4755d32994926bfec45d349efe456c3f889fc9b0def28f650e0ce61328b911a47a5b5bb42153b9fcb5ccc6015417020077000c2286466ef7584e2902591e68950b1535d70296d77b6406ffe0badc729ccc3d72b94908db7de0e0b923ff8f20169a5fbaee31fd27c41c993fbafe3b52a9fe7bafffb25216962bc3ad79eb4b342fd21378bb65279955ed4d85f124d0bda7f37d0e7c917d8d32f2aa6fa34d6080ade90382eb1f1ec7113ddec05b3d6bdeaf7cb32a72ecb9adff62572b49116706dd421309f21c26d6abeacc1e81a4d965a4b0360ac40bbe1680adaa87389d6ec3074f09a4ef9c1a12b45a9a78b1825e127f467dbd7a331495e9b9d6a3cfa3ad495d23d092ff43b6594e7691e00ccaf074a627f5ae2d14692ff0b0568d5d6b2ee08c711d7ab95baa86aa05d66319ca0791a87281f8e5a6271d9afa05d3ff40c7114c3318a77820c119ee4d11885e335555f218e2647300cd3a4df0c89087ca8186103d2e4e51c263334bc3152d627cddc5ad3e4bfd0fadf9900d6d65923e830c2f4f819f20e510eac83aa7e6978aa49ec0a73e0d71102956f4875032e1e006679b480f9ba7e9e71f41fcafb78316a81719c4e2eeb00d2e4651c4d2ec5249aa2a976462c8eaa03b027bd767dd28e54cf3b27e6adceb9d776a6894eb63d8c5aa3d69709b0f7325dc6617240408efe5c224cc0749984f4c8a275b126aed4970a7af73f7ea5b521f76dd5cd0827a5852ab26beea7af36d1466b34cee65a26d83ede5dfdf1f2c7f46c1e2d162817ddf19f2def40b2d7dbe57e64be749728c17c46c91c81a2cb5cf1ba57bd706f7983b359c8de6aefec40fcb75ea7bb3a64bf8479e81d09cc43873b76962342d62ce5332765f1e1609fd86e372220cccb39ccc9878c446982edbc91acd44e39824ac93926b4da1ff8e878ff337314a2844464edce813149134c401c2548ef3718820f633a851d8871344bdaaa2d3c81312a1bf4ae5f5cd36fbfda1ec4d1e4d265fda33f7049d2b3cb28e34e72ce88d20b787d4e31bc8d16111980a7ce4ad33421672cdab8bb7c11259f52c28cd503d0f3b5535565637dc1f3f4eabfdfd203081e80be0d31cba390ceaa6fec6184b318aea5d763b93dfdc3e63703fbda47ea3d9bb4865035751318c76338b91c68eec84c850d409484e83ae00aadcb3559fe886da9587bed7790cc3b708c39a643b77f93dd4f60f3c9c31a3e714c988957a3795140d234265156a689a4858b56ec88aa1349e07843d022002124b0c22997018321abc6e2366344f0af1a06f99125a3ffadc3ea3b892668fdfb3f6e589d0df8c78d8bee3a6a31079bdfab7dc14ba6fa00386460e1d6be8b22f41e45b3f938cd6f4315a2544d04be7788e4d1049bc61ad5ad8eac76b1e0f5989ba156530ad543cbbb3f869830a77ea39dce6499e72821cd2cffb7188a986e8235672498879defd370dde0e290563d8f48dc30fccefc51e3bbdd1b4ab74ec377c0a7dd06984fbb5b74f7abb90c0710d33f9933d6b677e3fbc49da03f1ff268162595b7ceae9fad5f9a0335df93344910938d17296b7ceb67e05f49123f55f3ff0d4e7821d3b4f169da256fc45736395f9f4fccfcf1f3f7885ca5f925689f5f773f5d1f9e76e78f9bc3f3f34916c5f1ee01ced8cfcdc1794a603cd87215eb3a04e312965af3e22a8f084149f307efbc0ba07b3bcde70886db3cb66f1e4c0e6c2bea6e73865e72f5619f39f26824ef1179f301dcbfefd3585879875c7fd609ddabaff9167ddd96014ee9110bcc69f36478f3b0b761eaf9f0a6dca184f6e40ce511c21b9072457878533e6637c806066ed5f9ac5ed7e375bcaf18bfea2c089fc7a22c4f243e3bb22cff82d663d9057fc6941d4f4df8758cec376ccd4e50cacf7f15804bb737bfde0cf7e13f55e73fe6a57fb951e62cfa47f779c931fef0b63cab0a0ade189d12aedbcff94b30e926efa8b2d9cb395e88fb780d84868cc282388d7dafe88fd137c78dd317f6ceda75a9efb06e1b67d3f839c24b1847fff1fb57966aec2d85b63535efe337b683c3d667f438730c9fdff01b101fd32c5df97946149b301f56288fe1fa3c8f66333fa859ab89085f99bcf0dda0cc3fdfee24ec5765163bdc753328ba732be15306609546a1d7c9aad4ef0e2630f7faaeb97de2b66e21cdfc115a8a0d2947b3081394ff0493304639ae76a8fb19e5249a206e52aef7ac2b77ca81c4ef66a7b79ec125469f105e2e9036715bb7afa1a9731c647ebf3b0e50c4c7693432113426097f8a6673760aba4337428b49acc67d6421e96c16a3efe1e47296a7cb247c05097c99c6313753b99d0cd90b7717cf4d046032ab0eaf53402c930a3e953f8eb16f6e8dff2b5c1fcbfd5809fe0e786e57fe4e3e0018c54c65b1afcd44c105ccb29c8a685c0691254896f89a644b2a0024ca140ec6f3612018cd208e69e65f7904b41a670c31b9586458e8aeec25aa98c78de7c6a0b97367bdf2592cfced3c2efa751e17e01a0f6f1ed5f84cf9bd40fba396ee17577f222d50753ee6284349f555840bee1c5d131085c3514bcefc514ca77ed47a2ea52b60bca0bb2d32a80607e61dfab79f97abe87a1340b2ce28a1f95be8514bba081afcdf21e919bbd36f1f7a7c508d1da89155c4f0ad2dd3bc3102d3c5765b34b7e0a00afe56acdcd4fc24766b3aabe8ba99e9e86fb02a84c0de665910744d8a45211f5c79dcb059e1eebc2fbb57f2d3b6558ae66d78964753427c85eba374706a3293bceaf0e6d78339d5050e0270304d274b7cf0db8633c802318b792e72d7a4bc8961a3f7f8a7f28cc8165cc6ff3862befe5bac3789a5c372fa378815a0ffbc4ef0324718903924204de235b3158304a110852ce0139923edfc08222c150de48f316775b1bb4b1f1554fd9bdd66f8c421beb8e74897248e127484d1244d42e6735ff291afd6b4b7ba3bd88655e5cf4da1d481ef5810b43403456f00ed0e28fa336a81018beec63ee81543969eb0690e9f6a1ffba2a2b9a0ea01ea1248fd8f54f83aa4c2477a4ac1dd9c9dcdb1386d89b4756096c36cfe375dfae6e276da3136c6b39a4a59d17c19f3631f5bc2bc3df049d254ac594672fdeb175cab7bbeae02fa49ee0667301980470148a7538cc8001cd724726be055afdf5acb6c716325ec2839bf793c79d29f9c8c5a2a42d3a875358f081ab51ae69163b1bfeac9daec6ab6d19d7c83511d43d87ff6748f51fd3bc15fe3b826e39371fff11ee33a8fb2af6d4ce3474f9ff57a7bcd154f9b7b4be36a94be519ec507409de23b541e6e024a62fab9b066b9fd9cf51fb686ba82e706e046b3c06dba6603e048b7cf6d8246b3f0eee3d9c0b284751659bd175823629c09831fedb9f8b53a6a1700b5296a24a24ef3c4343a4c072fc798e4ed5e00fabd7a1792864968286f1e35d8721a51ed85b49b765f483be976046457d2373e3beca66b154943eca6415a493edc83a3ee518345de64b8e7f932b9ec7ecf72050d1a716d232d50d1ebfe7df5bb487415991f459aa2a80169d5c01a27695510055783ae0ab603ba407036d0595b7673a7cc4b16962d59dee8f5763998e84ff7cea8a2e6693fb228349f8f2e0d9795fc69224d6efd596318adccbb86c266316a6dd41eed6bf33fec81ca001cf50390a538e2cfac462d38c669bca49bb677b323693600bd00c4684a7c8fb7e8cf55149239c5d9eff5fe59818f3bee35a858d2375048ffe736cc6d36f43459a6ca9d3ffcdcd613666bf71405005763e87598e0a5a5fa1595f59a37af209eb3ab5f9f2f9daaa08335f396518d7c625e3e6c58d2fda7a08cf001d2e929a369f9fa24cb8d46dec3958a8ac68cb863e8771074d4357b8cc2286773cafa1e80b3ab884ce615ce4b8693936233278022956bcc2281a09672a78e0a368431147f2e9f3ac402a202e749efa40ec949efc400e50fb4ab230098f32abde7eabc3db101a69b3cdc703f6bc2e2db51e272306232611ed1b5b91e0098acbf1517f405437f37001a7b8b728f9f51b2a1cd783c88b4ef1a7a5ea23c8b4cbfa24f69da344081e657f00aadced33466ee054a04f2bc45e90461dc41c9aaf3fec3abd717afdfffcc3d3eb23c0d97cc067b604001910b8300811483210be211e5a8adaff110ad082d3e38ec88f789df9a58c45dfda9c4d37dae55d848e19cf05faa7ca21490c71b84f972b60fbf2da1d45c2e92529fdaa54dc4dc8b47ad49e11ff9dcb1750be18dae339884c3512b9e8d5a603c2bde21d82f132cb78213e656e0562738fe0e55d1c3225ec469d7f8ee87350dccf9115c92d4391005640838aa1e8e5addb0d8252a40659b1da69fa99d85f5957fab52a98c76b7ed60520889c61d5482e5737410a93dad71ffeaf555b551d61ca3ef7e78ba66768b03d464f8171fe254ec5db7383c1183e6b38d8da1aa11342fd33886194686e0f8638949345d1f4df82dc8114aaa25c1a94b03ebd600d0d6b90345b501e29e53f45fa1314e279788bc54fefcf7ef37328316f2398409f3497efecb190bcaaa9e06dc5366ca4a849baa09aa1fa1aa23e7c0b5df883aae22aec4fa90333506a06b7ad0c9209997e47ab1eb0eb553836fce9cd83421ac632b34bcadb059e6c74154ea66854ebd5b4be215aebf258792bd5b4b27bd93ee40b9bd385aa2aaf74ea8dde8b6c3a54b731d9ba6746f854f8a4e1d973828f8f188239aad81b8404ebb5ee6bfd1c4c5641ec5618e12c742d5734a2b157a533630b04c31ba6141aa999bed4c0af3d47cb273344fc9519cc210e5dd3c4d8dbaf418202b97ce389f44d551d2ed0a1d17307ce0d58777c56982a9f02fb20c0cc13c25edf68d38f36c98a3f5293b67884f4355c69e7e6983ba81ec8410b0495c12144a83081cc728001fd4efef60a69b010eacf850b5e97a658b42fefe82c6674cb407a0e4621d00cb9b3b00bf9cbdc3b3f37586ecd850bf9c690f4ef821ebddc733fea4b4b06c2f322c53e428cb11c19ee84e0c094fef57602812fc2a042b946366962b7d5f668425662ab5b7408b0178871669be2e02a9b03ca6fa37e1615eea8d095604965adbc39a23985d780ba26489edaef1a230f694e4284610a3d05d9ab2a057767b8b0b9cc1c4d3e2e262022773e429c5044e2e9d8360776bcc7be16236b14a93e5c2f5b97aa6cfa30c97f985c72cda0a8d884bf0e68386e5dac291db9fead09ab17714f27f154bb5f0801b8017790ed7a726d473f3f9a90e99f05e5f4469012ac6a141494818861c639b5f6d0e4add2bbd7f10f79f2cf7af96a4ec1524a893a4576d96834c4b3c663f4c295cfbd8cb568ed0aca7de911475d583d305bc16747b0509fc98460971c5d72a81e3793425ed8af451fc752f79f341be6bd09fd25b9d63353d0987197431075bf75cf55ec3e1eabe350417202331efad7bece5ccdb408cdb133ed324ebafee493a02fddfdc6f6a6803dcb9e92dc4561b2c876f12a26b350736e6636b2e38c4a933ab33efb577d2dd8362082b06a07346fb70e092122613f3fae0fe7d201ca62501fc39a0dd5c713d3078d38c34028ecae8cd72e71d4fee469923187af1d14227322af55c890bcb32c18e3ae75f97b5f9d1ff25151d7d8ab4b0132e2623d77660c74d0058b0490ef52123d8f16c8b211cb5ceaf47ad001ce4b3316c3f7a1880fed35e008efbcf82fee181f37baf73727870e8beed929dcaf7ecd427ad53c70f1f05a0fff024008f8e8b2ee95fbd5d2a778b3d037024ec7565dd768b3e5fd66d0a5cec39720d0dcb5864f26d0394754adf403a04dbe2915cb3d88066bd6bc73b42bdde91a8985fd7a424f72dd558c4c3e4ff5a132643180ec0afe43a00f9b519d872e3b806f5a90e95aa2c94b1ab4adfad586396f6522c734f9190284eb547fb540aae5ae264302cba2f02448e5a6f9249ba60bea93c2ee400fc5a90671ac571294a6a1c25e81c25b814b1b4b8b6e6692ae59a7c1a80c7bd00f49ff439ff17002c77d72ffcfabc5ffaecc5d1b730bc84d9195953a5fb60bc24a45cfc0ae2b931a4e2f307e1badaebf44aa5ff3b8d128974111194175833aa447cdfbc93bcbe459c6fa6d3a913a9451056f653ba42b98da5be650e6877f7f8b817c8ff570189ee1c9b153ec1305a627dfa395ca44a8ecb4514a52c7cc4ca8ab4272a4aa990ac09a4073f919fcbccc51a80f1eca5999c550b22634b07c1e614a383bd9d8c2b1a302be9149c58c5365378eab8e7b1b272f3b9db382400cf1bac0c051f2199b3bcfbdd2bac9ff8595d97b60c86e059afa72a9ab17e943f87f33885456aff3399ed9f6a27fc0f4dafd6216c53f5008cd334463001431e3dd8095772151d68b60b611b907f7b1a569aa88605cba39c02ae38006a08d0c242a09b1d2a4f9166dc22d179c380742a9741e944fbdc3332461ae6dc2b69a31dd439fee2432d7534446a7405783d7da264a6cf28dd570c0d88f161be9c90d48a0220ac904d030998f5dcb1134ab5daca3ed6e15c1a00fd2d27fb548ef2e443a0780607a0ad99cddcc1a75833300c0b36d51aa6c780a26091e1c39ac853be3e498ea12331c756e2a5a6088b9937d1d11e17650e7b04aff652f1449b32822f56881595c23d99563d6b3a77993bdf3c98b8aada36a8de1c4ca36d130232d9e8a1e0bfb87d5a11b4044bc9e9589e9e902c131daef8a351cb22999c1fab297f3dd1de9ca2d653f7b624aaa3715d149aad97e20c09c79b52e8f69201bfedd8a7ad630ce77a8d015475b55ff295b4132467a13d400f9b739f8d83736179d72fda76dc620f8b6be86f6b5b544a48db544b6c36e7e59d055aec6872b54da93aa7ee69563550d59a582b60d9c1bb18ab83d7b12419ffa5e0ef7a6a97cded43508eabea31b1bb031cdd2b017b8d78d5c666deb7b09961a51c56b5a961c50ec0efb4a6a8c8968a1e36cd9c228ca50310f69228b40d2b1abdfcd4022ae2a5798756ea4313f3b781a653beda7018889c83c2faa00213a98d434ca461642ad3c2e828bb045ea42b04c2651647134810b618801f822e413af574f212ad71fbd07307714f762a4a26f13244b87de9aaea274188624450fbb286e69b2d96a1a1b2d04558a989321e2e9d0d5c0727c06f82dfa967796048fff694ef716d553ad6f16638da922ac7cefd76612589747d9bd1a67c76ac08b6e6d457f696ec1aaaad25bb06ebbce3abdf934dad9d5244bfbe75b30b69749604e22a587244c45886fee3adb227d368ca9968c9c1368ed9d495ba7da7d3c0b5ed7c1ac06c4289e34055e26fd7b5cc22c3fe4b19be76f7b80079f7f1acb80179fc2400fd678f03f0ccb895d13fdfd90d48d5826c7219a24b023fc23dee451619b62f46e861feae2f3c1619aebceda8e41eca7415777ad1befc43c5857685f6a81780fe492f000f7b3a0719df3f030b39a440131e32846705ca7d6ed722171bd1af777f7116edc348ca03d6cd4db27bdba0e4fe612ebe0ce13a00f3749907601125ec191bbf5137f71bf10d0c01cb43368dd3346f6b279f0e6f017441bfd7eb95f41f86d70495f8bae071a976d192fced9fe071cfa842bb6ba2134dd8d854dbe2170b5708d7262a86bc0b8e4f0e5d6db27ffe098e4facfb714c72c0f3235b1b276b6308fa8e3541a11e0c592f1e80510bbca2d35142b171e17bde141daec7c706f57ce8745151e5a7a0ef2ad75a1db57aa31678c069449b1f941a668d0314635489a71abe722462962bc6226a341f8d00d8633c75182a47241741c5906495e66372adf08683f1823611a998e45b08ad055af8f7d33982d98b384e27fb6daa3f21980186a7d85afb8f9f06806ea34f1eeb3babfeb989c30cede19b6489d12df4f04d72f46f8cb4ddfff8380027cf02f0f489b1f96b9f1b77318c6fa58761ecea5fffe9b1b383f47bd31e7e12bec0b7d04b89aaa4473d791c80e347c7961e25bf37e9297320be058e3ca378ca2cf9e8849e0bfa01e83f79687871e9df1bf572bdaf169a1218db2ba6c797065d23c692d1be7f8ef38c653a6e6483f463d943fd5402cad641a5bfbc1b88c90c0f10f35df78085b1172a8c3d40723d7800a517be0d5c70bb0daa5ce91d606b874a6ed5bc038d1c533d484d4950103a50c40b0c8a04da109b79c009770ff174bd943aa4e10b18ef93979b9d1ea8785e1289701ca5c43b76000e3d3689884ba1f9c118ee2daff264265ed0695e7f09263099d88f2dc2ecd2f2fb13515c444da03ec3244c1789cb53901e3830818bac3a65fa0afd80507816fd876e737d8f7b0eed7fc93da7db65c0608a0ab5c4f4162108938b059ea90b1a8d0a8ea70cdd2ef873c9e4a80bdd02cf060619879a57b1dea71486513273a1a0d8d717a242336f200e82f29c45aed0dbd4e645b245298a85c717c507e0f451298ac1506faaa1fb01a557a05c42de8ab96e66c9d5009849bb447fdb88dbed822c472b9410ed6604b4f13c5dc621182330859880ab88cc79186916d3afdf3b2cabf4c2f4aab8a7338d9290055f6ab7796215d2e1218b8743ca16fc8f43301c0ec191ebd4e7442a2db243630954ddb2e8d0dbbde8d021b964c733df838e0666583cc372665caaff14d5de4bfaa87104fa547178ce1588a3239f6680670e242e6580f6850fd945d6532212e2a959ac48fc41aae3f7331c52a27a038b9d762bd0346a8277f30ef12b817e878da8ad61fb364ebbc40e0d5c7119217413ca08b6d8f129076abbf9d6a118345107b6ddacc50b539484fcc579c1f7eff0ec4de8de4151b25c00f64cfd759ea77901f33e253f5036710d91b7c41f66db3b2a4649c882ff204c00498178d4edd89968cd0b1886ca79b96c5d2b576ebce7614585814e91a1f98ac7b94ba6cede7c255b65298d171dd89f6008205e27139717a0917c83d1afe45bc82ae56b5b469626d2254273448f70f00a46546093c9bcfd7b17669178c5dffd874cce212679f3bbdb3b2347cab7e6de70088e7b3e0b9736988263dbc5af1dc9b3763bc0ed1263ad746d6836eff091d2eefe81d3c4b1736244cea3054a97a4ed980bcf9c70f46ddea263370e28454a26ef0d984032998336ca73dfcdab45285ab7d186edf417d309d1b6c9e3613db168adb56a545078395abb92b6123a22ea00df907fb7437254715dc37132afb8b268aa1820abc72e33c4efdb3628bc4ecb12ae96a6e2379b609a302b8bd4ca2e318f54b73fb1355a4392369ff05dbb56666796b1509c6976653eb32f282f4f9c6f6bd7763edfc97ffb88177b1dffb75216248c1c0ec4e0e7680565cf56d10ab2ec177fe003f7499a27bdaa7cfa27c31a5b052ab0af5512e10b11415df0bf5e42a2ccfceed649cea3ec4d324d2bbb56898d5b14566c80c29e70ecb1279493133b1ffdc8e8ef959ed69c9ebe272bab52fed3fea35ecfadf41491e599f9d455a7886b6f54916dc8c78f1ff290e53ad50e60c278ead7bf1aa946dd2ecbae325159b55504704e73b08a2060e966dc6a9d0c48c149e6d1fddc21d5bd34f1055a370054a555042f267134b9f45342d5e5af5b2fc48b3d6ef752580d9559cf9369f68d965469a4dd2ea02b9627ac01e9f80f657a625fbe35fe8a26c5b51e0f03a499ecf476792a17f710ef5ecd059516213ef7854d88ffbdc52b1d2a220a70f1611bdfc02255af393fde8d4854e7bf74481e2d7c4fb54aedb953f5fa1ea3c408e6329d43dbf6c2bfa7f5c699b697d95608ca07e00d41396504f62f497321ab9e4b9b89ca6ac19d802d2c536edcb2b504ddb518ad413a650d7a2c5e9768dd61b1303e4cdb46df3d57e5bc01def2255a3b8f01e31cc1cb2d6fe8ef4db979ce97e9587285a0bc49a119226d0e1f802dde2569699bea521db3b5ea3b07c865dec9cb39a88d6a2277934b57024df31caba61832672670d98a7aea5847064f0ef064b9f0bbe21af49720c972d1d4662cf49b2168532472b3f1bcc5d06f160d0e292f09741d61f150cc6610fa87e5b3cff26d0b28c7f476bb6002136e889ea55c7b5bf22c3480a4c09902897559e2ec48950bdcbf0f780fc407cfdab2014b3369b195a6933c78507ff6ee76c584730512c024141a2388420c70944c10b84260c124e1188110c158bb2ad1f030233d946a453afe83136a9223f6e885510b527d0844c9342d23502355c948869c42f26f6b2c0aa2c8542240d4070b8616d3938700355697c74f874e6093a9da85fa065b1aaa203f6e3b9954014ee66872c9f3ebdbb7fe7c52d806654f2d9d044c20416508e6554b6bffcc09e55937724e0e5df0bc8d6a046a862c0cd1b4ad3ae0a3b42ceff0938594a1de5929324221d2d6a0c3a0c06575c49aac68da2e8676e8ec5951be53d774f030d0b05577cebadab731af244efa8b639b087378c5856edbac51f782459efff86b0dfaeb409e09b715df3a0fad7cdc231a714aee7b2b37cf50b1cd841080ec4c881619598334414c374ad22b8f94a0750551ec152828ca5f77882eb997e9edad6fe7ecf37cb2c529f381d623ce83df813e18a8ed867f39a29f4cafdd95c1b6260e9b633e037b15e377eb6357f32846a05d4164f582c656503cb794fc11dc9bb0cc7c265edf4d6e25eb4ad43658b70b16f01201bcccd9662b9e0ac2640d1630bf8c9219a60cce5226f3dd758608167d756a1c42772f727d15e31a0e8151daa9ded1aa8e38162fdadc211e15fac7ceaaf3dcaf7cd8efd3b0aa7ed54207fc8c4ca2c4a12139e4f96e1bfbd1d176b8499455612e966e13c47c3931eac834786fa3e4b2b42dbba9ec032b3663cf6d45c51ab571d2b52aed3ac525a86733282aeef8a45a2270ae380dbbb559c8b22ad70f7d0115b8ee7e09e9fdbb2beed4f1df3e8796d7bf6f26ec9dcc12052e5083238bcda5fe00c99ebda721b2148ef2599177638608ebc38e874571b262d648c7994976e6df6f8c56c51bfbf7acc4af2270c80e430e86208339462c4a977a539ae63fa439a7c41955f6f9deebc6b4e5a1488068a48261a893caa50a58561e4368d145d6be471177e228b9c4e0afbf80f66707a70bd48e9980790ee8bf1d7aa214cbd1147fae77ef66576d99190027a56bfaacda2e64e8f6724ca12d0eb27bd3a2e8cf36c4505075d4288598b158ada12987e94a7ffd257e3358e15e7918d229484b816c2dc7ea2db74020f3423798930af15be09359c1fdf88aba32d7b6c7c584c0bcd2e2cc0f4e2e335031a960c8ee173b3f722146ffebb01050f123058ef454d5c07e8ed055e70a8d67f18fa2920387f00786eb74494cf0b7ec5b679ae613f48ae58b90765ad666e07867975121f996a9ec03d0b7335ef20a2f53349db29899bd5edfae43e03846e7f31ce1791a87b45eff91556b96c35544d60370746c3bb8e7506bc32e27d1029d11941921268b39400452c0a7a67bbb4d3925eae9b26eb7e97fdd1e2c3c9e0a5dfb2124d0b34f0bf6724edfd99f4b98a376bf1700efce50e06fa09e3468acb8cfdda1d1cda1935054ce09371f67d36fa304b547ad6f1e3d7d8c9e3c1ab50eed4b12c49e6585e964b94009a1bbeceb18d15fbf5fbf09db0745769503c721561adb1dcb44165533b8ca5737a01d09d4c802b180ea58868d608578504cad0b6cf46f926c495eb3d27681b8e88f8d8ea3ea2cd22546af1382f22a2e6ca4c8baae668a492ecd316ff82d82ab4af6af6d78e3982a490030b46f61adf9ece4cbc4773988499a3592c61e8717d54618e12c755fd14891edf6efa9b82632cf285e07218f930270d88e9ce54a9767b3d0f01ad5e482b23a108055045fc6d1e4f2bb0ae72beda8efb9e529538056f693a8f024004370ef9eec8285b5db058b25d36298b6e53a3f6c714cd85dcb373bafbb36d0c9d6d47f1dc87f2c18b5be79fae819539ccc760408e6de379a2bceff02fdce23cf9e8f114a7e48f32b983bde0d1455be87934b5ac7f1f6309c6279d9adcb4dd751c3f9b1dadfd3e794e2ba96b1b7713ddeb89a48a16ffbcc4eec615472e99ee7b7ac84e9ecced39c6cc03b75e1c3878f9f1e97a7cedd7d6d6ef4a2c326e4e7f4de81c0a88ac05c7a055f9886f2dcd094868a79dd542c45fcc5bc879ef0b09ab898a6f96b3899b363978a3cce86e5d0eef6254a254194aae4db51ab44bcb12957fab036700fab652babb665a5d3c43b3d2e1b655b9cca4b3b01bf41657c3b971e41cd7704cb4c685f5a71d5c77969a59ac64eada86039872ed664788db6a6ea2194b61bff96d568c7f9dc7b4d9db0db045fe356e05eb5605731b61f7db860ff7b13c8bb5736d6b66b1fa7957c971576baccd32c4221a09291f968e4680a27b492f099991392e141b73b8bc87c39ee4cd24577162f17e3ee9b0fe72f084c6631732f503b893e97c6344ec6015866f45f2634a4cd476ccd941074c9f3d5a349245520328b5179a5064e4508cb15e1f0b315f7b305bcba8e1510764c6aac84a982fa55547ef0e0376b4ea8009d8c79979481d00aea0f4c2f48c69be91414f654cf1d90a0d3a12418dfa29d9e3622002bb87f9f9b63492a8cb1ac1161d12c08a142b49abb8566c9759a6d1db35181c0b96eaaaf475dc3d246a51999b71f1725c91ea3e2e0d5c629d33cad46a45686262598e038e44be0c660665a87e745a10c7dddeb3d43e8e9746a4c3bd33dd6194aa74048a0e1101c70efc8037768397313dcd463e3f7a60794c2bcb3f6e1987d97ab8a029db815896ff2d93828ded7030427733a58ba68d1f50465044ca31c13f04dc7563f3921785339ca623841ed6efbd7fff3cd6f87dd59000efed1ff47ffa0e6d2c4eae8335f47f3d96c3c86b05c66ce0afbeb4d42045ebc1c6392b7fb8701e83f2ebfdb63f757ce3e3c71f721cd65372c6298bd685776039c9e82a787e02fd0bb16cc53ea93c3d295a757e080a347d719df68a204ccd135105979998f6596a309620fad46ad6f46ad0e78dd9975c037bdde74daeb75c08f29012b182fd1001c8007c0d6bedcb738824fb53132a0cd16c9938b0aaf3ebc33922887e9424f9cfc314f57518872fd6dd691958a993b6d7d9fa75718e53f89e4c70242bc4ad4aa1fb0704b7fe0a32c5ecea2e408931cc1055d421aca1759a6276c7e9165663e67f5322200789d4c44a3bf4464aebff43ab01e7ad958cc24d2bc56890c45fa22edb5196d10e1ae2a1bb50a0095b8df036494eb804524161b4895e900fa53731b442bd581caefb36cc0520d06cc74a02c4719cc1178978eff1bf0caf26998f978254157fa6b177af0490abd41afa528a8d5410601793d8368fab39a022c54e4e3208a64eeea538d781c4023981b6455229d703e34bfba4139b558663db68e472daddaa835d00918c82a49c15e838272aa18998c343009a7aa8505eb0c0a22a9e2a9ce26039d2caacaaacc108332290296a72d91a31d1bd2806e4c0e21a1cdf85c5574ade7b6892e00250a7bb2b74b1127ccfb6d3e9a5329d5c04da7d3e1d3b2d172d2f304fcb99dcfbd941afff44596b992be6b98ba1c95f874da952d3f1784f5de70b10cf687a3842590ff2d68e174994fd0a73425ad41abb5f9bf010000ffff0a877645b9710200", + "a1817dae2c5d2724ffa364c179e53b2b": "1f8b08000000000000ffec7df972dbb6f6f0abd06caf4226104dcab2e3506572b3b6f94db68993763aaebe5c8884243414c001204b8ec277ff0600497193ad3892dbcef48f381496838383b31300ad0526115d380b344a60f8f9ff382549d052f6f5ebf9d07692399f5ae7e7ee10ac3cd7f5c773120a4c89858000d45e5922a096776c5b079e9d37460e06a6334ec2d50cb209267edf4d96a92c309c29821162ab08f3248697fe3846cb81fcd38d30430ab2cfe862f0e79c0b3cbeec8694084484cf1318a2ee0889054224fdef0c45181ad60c2ebb0b1c89a96fdc3f394d96f6aa32480d6e48e3f98ca419222125e31887a23b6138ba161f55b46030f1e59ff40f6202d31cda003968995026782052e0b95e833e1790195892a86f0326ff777bf6c0e48261323183405c26888e2d1630e7d327c45fd3681ea347cc89d018ce63e133bbd3b15870ae68cae498437b206192608509474cf8a69cad0938269318094afc032f1d608b01620fd6e83127a6218cf9d7afab5462dadb7a25ef487a75b140b3d59812d1e5f80bf2bd93643928fd646836c86988498c09ea2a522694634d441443812fd000c678421438ee878808c4067a097bae9b2c0753842753e11fc9e78c7b8e93e56044598498ef254b83d31847c60fa7fd074730ca2aba0c4678ce7d4fb585e1e709a3731275431a53e6e76db35fde91373ebaafb11fc3198e2f7df3a544c4045d982431eaf24b2ed00c3c8931f9fc1a8667eae70b4a0430cfd08422e3e34b13bca7232a28f805c51748e01082c70cc318704878972386c7c07c2ca1194fe5b0c6f319fd139b6b00cd82b3cbd988c6e640a0a5e84628a40c2ad2114ad0805e20368ee9c29fe22842242d16c551345cd10486585cfa6ebda60b4349f7956090646b91b5358e5c77c60d0439ea6232c8217865084b2c569b2ab6834ce762d0829ce12488c9f58713b42ab8048e388de7020d044dfcae972c07311a0bfd54e68cd2908a790caf98871a702bae70c7a137ba3ff8d2c52442cbf2f40c2786231457b5425d255598d773ddffe4fc351e8f0ba0bdf40f72a74d55784d55da50159ef77750155e53a96d56158c5261b4e9f816b1bf52c70f121845984c7ccf4d9646cf6d5d412dc9579983323eade6a082986ac10564224dcb5d0d67c420b9de4ab44c52ebb02e53bcaba6914fac9f2c07742ea4aed422de26f76d68f8631acef96a44975d3e85115df8aee11a47c9d2708d1f5c17b9216ceb66e0d964950951ff541ae4963653afa4e48f7a1525df934abec4e31505fa1a0946131a636ebc4793790cff2eda7431c50275156ff9842aeb5d993881173758d72d794e41cfcc985c7c433a428df10d788d65cd59e6b4b084b96a3ba93351aedb141bfc43964861b9d09c39a271b4852428aaf953691557f5d67312212629d2d6e55b6547f5ba07b345ec2a73d4739bd203a3092aaf6255749cfbc7721deb408a853d695dd8a6c28bc2a3e3fef13f4f08eb2bbcadf86474cd244809cf267bda74689bf6f4e86f614f8fbec19e8690b5981ddfab6ba9cc98e5fca4ed65c3671ef7c6c7e3d1569c2679ab2c25c9d2e8274b437a5f069b8ca0e51df580d7bf0fbcfb47c0753cbbe9a14adc0df5b7dbcd4c7036f2880a41674dccdafa18d3a3925ca98995c4cce995052b83ab1a65f3e89f1edfbf7ff2cf1093547b9da5e9f5ab5ae454ab916a54f3b78d63dad5ba72ddc794cdfc79224300c851ea5cc0788eae9ff8751ee50c936eeee19402c8b2a65d7b930de9088f2217f5b734b06d7cf57722fe82b2a83b62087ef6d5df2e8c63cd5ff73049e602e8e78cf20deba6da5cbf20ff125bc9ada2d636ae856ed89dd12f5dd55a9aa2959ea4928b0432448416941210d7c848a00138ea6f3789e77cd54cb054492a97e024fb572c6c0940867529086674719d43ac1a39331c45315ab538c74e48e3edad56ea64ec27ba22e74419ff7bcacd2aea78b9ae57ad9b95eb64d852d48dd63073abe356aaf9aa693c4ad5b35ab502fedf8c13c34c67653cf9c71dc5947fdcc924455cc6928fd90cc61565e8b9aefe9d93882f6032e02cf4e72cb6cca91009f70f0f1768043947823b980ae850363994bdf82196a31caab1ba1fa698380b3a1ef71e5d04478e7764da86d4ae5058a62a366df01d50db819af63791000b18e370af2478a986d80f214ab077428e168ee8ed901ccf9782c15712eceec95183bd2feed80f39f6c523ad23ec8b538e76489a3d31c9fef963e744d8176bdc1657f47748902c24da3d31ca80f7c519bb24c4be98e216f8e1788764788d223c9fed9e0c25b8fbe286dd93615f3cd180be2fce38d92149ced00c3fa171b47b725420ef8b3bf6418a7df1470bfc7d71c8fd1d92653fdcb177ced83509f6c515b7c411a7bb76c7f7c31655d0fbe28dbd1063afa1c92d71c9835d0a4d0cc3cf7b909702ecbeb863e744d89beaa801bf21418c0bb855becb68278c2a217086a22e265c401222ff8f3b59a0f0c79d1b128ed11924cec5b531cc37cfad3d91f54d73d324bff1d43406df35b7e6dbaf6b17302bda1ee55931c6e17ab84664e9793766e5eb076883ff6d64318ab5ba4dead4047e5f34aa8afe4d29a5ec8ba1b21cb745a696f4e6ce69d44c73de9440b74a9a3d53652704f930c5e4b6e8517937b2737294df91ec407e6e59db6c4c8bef519876a373fe0a6add0aa1764823c99bb74ca296b7707b11b9dd1048e7db6e8b36b514eacee9524da5de94266768860d192cde16591af9c39d13a69e47bc29696e932afba5c8aea871cbdaa52549b217d2ec52bbdc32895a5f50ec49d5ec864c85c2b9654a6d48d6ef4dfbec32d6ba4d4dd4ccd5eec739dc854e5a53e7af70a46f839b36e4726facc463187ebe35f55dc9e7ee5e7397f3badf4590db366b2d29defd50e77aa6b95b1cb358efdfd54700f017f9a3d8bbbf4c4734ba5cb59c1938199f8ec374dadbee0c59db39dcbfedd6fce4facdd0ff8c898ce64250b2e55125b57dd82bfeb41f592a6febceced45eb3ad7bcd3afaa0c93ff0ac46f3744338679c323fa12a5f9fd1799b4de19b4e34f51be784cc394706170c87c21c508759429f48c2fa7c933d3858f7b057e81c39ef309904ee3030e5830964d18b774f036f18982fde3dd5058fa3e80d8d50d01b0666f6ac2bdea319bd40aaee681898eb9fbafa292504854216f0a03f0ccc72816ef20cf3b0dcea781898b53233b5f0d7af160e56a96d0f62240c12acd2413e1183cbc9db2b728e868148e56ca1ba46c10671401d62411b8c832aa100d687bf1820016493f90c11c19d18918998021e909f8e1e099fcce3380802fc08076f477fa250381324de2ec83b4613c4c4e533c443861341992569efe3011e5b26554d8bd363c67b348e51283a1d3347a151e764471391cd837a5181ef00c51c498d6ce919a20cddae37800f037700bb5ddb62013a8743bbd3b17860c959308bdb3e79281f24186efb1a59fbeb576e0f181273460cf2f0a8d3e19d4e36cb088d3141f92cb37e80a720ac50d15edd74ba3324600405b4b3f1ebe50a7a3a0863c8b991ac424ab860f35012da5e8929e60e2601410be30c09a07ed3b9c80bd254f78bdafa11c563b2257342dd9548011d5196178f7471c68098925afb0983c9f4578c168fd5dd06c181a7cb1768c469f819898cc751545471146b50b52eba1c69d992dcd62c7e49deacf16b6df1762eda9a240c5d60b46880862c9c06a699cd058917f33856033d0b50f07025f94b4a9830e8d858934c1f02e2966de3b1251c75009eff86c5d44276be8a226327d34c35f4791241817e43a3b31a5d50f07013c95086a71c20b0ece0e1aa9de86e693182d881cecff249ffb6b49240a572d9550e3789d56f1c72cb06a2d4e015bca473e18c290bd13375fa0445d67a08b0e209c364f24a899c7fe402fdfb2945e3b1efa16e1f440c663f1db707b880a3187d9832c4a7348e7cc73b0613062fb0b8f4bb3d20f00c9d0994f83d391124a0ef9ca65a5353800103047000c11884200111988219980f9023ed988582876d137b8509b2cc1fc6e3fbd14928dd35692d38522af41da3130667961505e766c25088b9549c3315a927c638a6500c4c605e407689c9c4b84061df50265795521c19338889259f6c636502d3300c3c362c6b127f7a27cdd9534a59e42c8daee13ac7b671d7d85473af5e73b9b14f51f393e13abde36260c398c49f5e28724b831cac31350c2335949edcd454cecc72edbcb109ccd41c3a7f524c2cf30f62da601a9c9b50088647738164f39e013f5d2026d0f21de5b25fa3369c7341678ff362d5684eb0749e7593f9271e3284c819fe82ca953328fac6fc5371def19b9740d14b9fee32823224e3ae9e6909f5c33216c07081e1e564c8c92e6b8ca06546e7ded0b85b867fee0ecfdd61d65db18f11b6f72c5aa9b9382323306634b24260f48e4f1cd71ea88ee398526685875959b9c7e49b7bb0ad7ae8c6c66160f48e8f1db702011a81e1e9b21a7bcc94317821677cd47bcc18bcb44efa3698072e58c514467ed9bdc20102bca464949c5ac80634e04ec8101485644e416403eccc7951426d4002a5a25fd1505d5bc02d0acecdd2924a666c505cf25769a5d5cf62dda40f891d44a472fa5581d11df54c885380beba597d4c1bb00067337a321f8f11b3ec1414070fab5e83527201727034989df7efd261209c25508ff7bc61d015ce65f6ab370c90a356242b389205320649014344061605687b55a71e76469844193ad879fcfefde3df3f3df9f8e2c5f3f780a96a55f54c3a1cb5ea19c0ceb3dfdf3c7efdf2e9a767ef1fff6683a4d3b11269b8b19349ef6b28185ef6c71716710afa82030f84f6ba516f6c11a72476108c6d597d5122ea3b1d0e94a90f7a003b2f5ebd7dfc4102ecdf2df39bf3e4f70fcfcf3ebd7bfefed3f357cf5f3f7ff301b89b41d657ea1b219f4ac811830bd5805bd879f7f6e59b0f67c005733b05dac27f28ce6b97993f0c10488203376f25e75fe3041820300e44d64cb38f34571538b3803b6829108934f7cdc01c4889bb1778920bf280a3d267fed0ed74ac7937f0a411c4d14ff34e479549bf2eb95480de4126ac19e8df950d40ffae842a0126310c73e717235e43394d955d954e9134c452194c2caf0f4c77094f23179d68bbab0cb5745fb6b3d4ca5f5904110d55242285fe798ce4e393cb9791655e603e8731fe8298690f9457a2d91fb1ba8f9397577c979012013141cc5f8049e6fff808c4cae7f145264baf30f9ccfd0337d5e88cea8aeb2549e6e2f9858c942c5472bfecc1c809631c2acf44bb6b5348a2582dcb59eefa5a92cc766a839133a3738e9e2b062d7a94dd55d972ddf0158217a8bda1b28a6e6a9790c121cf7dc89c140e9b132b6b83091618c6cf185cfcac5dc5b4bda2e47b6a07784cd973184ead2cd0ce2ba56cbc51cc60e7781401454b1fe4645ea62a4715f7d6815124d7c01240024b73d4b8a0c955aeb0579b6e84794239b2ca64512140c52d3fd39140814216192047303c2bc842491efaa32a39a690eb157d24a32c1a2327a613cb944d8dff7003c60cc1e8d2f84ce88238a61242dbb74a0060146900ad5155a753a3ae6ad93e5414a1281f0294469076e2e1919b812ac8230daa627ccb76389ecd63282873caeebd550362afa951ca776c2448b97b846224d0f513d50cb0d6666d13d6634706d113df34e3603753f62b633f85e48e30f46c72048041a83030316630c9e95f10aa92f991a49271639d5a9cce5988744c59af13904d90b0eda2e35584cb252707098afe8d603e633cddeedeba9dd6254110d46478824409d3958a8d950f980c8412660daf32dcba372ff506c24e556c72d5084d90033cb6ae46ae205515394c2a73dd809bee7c356ed9000d88832a8fe441bc62102e65b3fb3063d4fab2e8c12add5f63ce65e0a35be44c668c199de91f399be574d90c428f7605880cff825beb49c832c3d6f82ea77289fba478b5739f5cbb03912748d42a561096dd0a3a19981bb36c060a6505bd8d7a8386ced076c34e1bdc5e28a006c35fcb8545d72b7b9478a336564d7dad69bc1d87808a05086ab672a2131b16b2bf7ead2a82dc1a978d9d2cfb88550e20581b63b99038a8f80e39dc8f2f2d640fa4d13c0870a763611d86040260a51f035a1d40d2fffa01d69c02346f6403689e424d5414d8971696aa35c306753a5616140532ccb1d3dc4d98d2c52f78328df1645a4e9dd5928f9d4e89ad9d119a60f2514da1e22fe42ecaab2ce1b4da849ad2fa053ab953db77cdc21d6aac80d548614aef391cf547de89097a7dfbca2c68d3796a0ea0007ae169747f6c02efd4deb052b9175b45e507dd51bdf06c41a59c6edd1a97a3a39368747c252e4d4c242eba631917bd3c8844d5555b3bbb483f5a85d7c21047e29d749be99cabc1786069bf3138f06cadea0eda7825535c834d0ca3e2041a94429981e874ac7589e4836fe2822c8602deaeb8a001703b2ea0bb5bfb2d30685b7b8501aa28b7ef93c99b31512d6628bdaf4055059397829a27d768627ffd5ab10b39506da1a54b39a6731219d67fb86d36d7403b1d8505ae9aa396d657be51118fa49be4575e256d7cb7221bcb78b9a575e9d58edba28d0b32aee3e227eaddef5bf25406ce8a9665b7a2fc5aa6b0b10e2604b15f3ebc7e95cdaa2dca16cda18aca8a5b5317f55a45b69c41802ade8bf62f62045975d8222bd15035d6810b0edccc3369b2d1da5237a1968c581be01601ddf54bb4e68bbb14700be7efc36b31b2adead621623368d42dcab1515bbca45bd57cd20daeaa9d66bf2c7b75507bc7cdb45fc1f32f37c4591e19c0c05c70df1c64db85cc2008b893302a6848e34ec752f5dc376d00ef05e6e1a1798f3b53cac53da4347eac428ce2bd9e05ed41ec504213440201e46318538e02aa9e116394054c3dcf10e770824afcfe7f676fdf3809645cfa8dea9df040bd611497090a02ac7627e466485b1b72ae6b8703dae9504be85e696a99870b6e02c933255e6bbe7db40e5c7b9b56de96adec340f575e612e64a06065fedca088d87472254bad64efed1f65fe9e5295be85aa2fb4ab492721e5c011f4155d20f614726449873b42cbb785d0ea01ca2dec8781dbe92015b2093bdf3a2182f361fede1f558d98be565627b2d4a4702137726a96bdcafae96cb18c519a2aa3246b9a32742d5adb4329cba39da663eb9c3909082d33421c4f882f19c0047abf823d0491e65e590a4ca23797e898d906dfd6371ff486fd4ba1d7b5109e501a2348ea209a2fc56f0aa9a6bdae0573a6ee3d6e8782b24d3fd781400d926c608eef0555e6901bceac944abe316da4d8d53a4fb7e4954d4ae5bbc09d7d0f468525bb71fff206b01b82a86e11bb2190fa0eb2ef23e94601d816d006bfefbba115aed20d21357dae1a20bc0950a93c810cce642537c1f9b04d1be786d104d2b5da19e8aa79da31f09ad9caa0ab1d3ad3205a6f3e9c59454ad073fb5effe8e8586d0324f3d908b1f5deb7c28f46aaba76c7bc813a1d64e3b1d5972e77e621743a160a9093bd92b40eadf3fff7c3d03e9c00f347ef47cfb46df0a0d4da1681f2a35e1295c89b8fb860966703ef44a74aa5837fffa0dc7ecae8e28ede188396890ec23031a668996dfc3616584c8d84a11045984c0cf307d3319e3b13c7f8c175c763d7758c9fa930d4de30dfb8730f0d36e3f0d34fa75f7bc7c769be592c2d2838d16f56b50f80bf1431649671531b3ae701b5bc131b2cd486ceb90d4601b5fa36b80ca8e5dae022b0a8f5e0c806d47a706c837ff77a7ef75e4fed2c2e03bd9752bf7fe7c6a5f394ce124a1011ab3c4390bb7397d9fe8fecc5b56546f8c2042b05e00d9c21df5437f74b7dd09566d74cc1765df26bfedb3a4c8fb46002fd3ad0ccf73ed2843b702e68829094b3334119aa2606ec2d46677461ac2f97de0e611ab7b55357a9575bae6f9f365360be24219da90dd88dbe3c81a4da557df222df65b9c564cb893329618ea0da9fb1ecade850ac59b71b4b5d78f5c855b5eccc6022c38bc6287af7bb09569fd1a58f00d526d12f62ae0dd05bb716d8608dedc2b2ad55eedb75714e571fe5c1d806c0256f30b55350a82f179cdaf67674bae9e2bf9d8b09ddd7e2579296fb5ffd9addfc8b979fe694fdeee5b7ed341d2c830beb5c6b4e6be48c6ccbacc3316d3072c221586a57e1e5bfe70ebedf162953f4e60a5314e64fcf70f49ace89c8b7fb6f120f0199b0ecb4e8f71b8ee38f64b655579a58765a18bf188955d9c5f511d041a12fd2abf86db0b5d5943dbb59d7ad4c50f6519cf5f7095a0d672f379c8fd79819bf96f6996d671fb7c248a92c639d5b4981f9f80231280b959b6cd0f1badabfc68cabfc4eb6fde3aa267a3b8cfbc8eaddbdaa6df96db9ec71b81d60db11f45dbe93deead925adeabbdb104f1385aa2fa14a8aa84035fbbd15099aca7c5b6dcebbc58ec0359b6ce9dfe43edc76cd9507a53e0272cd40998dd42ca99318860ab85be6a43e4d6282950a8ba6348e10f34db59fd080fa2d128e4c20559d6f0ab41426d0118a9056660ac904f9e86a2b53cea5acdfbf282876babdd1cccca55b89e944f6f4d0ed741a70929c041fa68821033264109aed9610d490164a0765628a8c70ce1822c2d00ac750f12c128871c7b401fa6b2c6fee79f8dbba27923637f5b7d69e49c1cf660a0eb61dba85feadfcdec6af49ab3f27b43fa7099433a3a006265cc6d70616dc88908038966b646fedc335315d66090d07728e27c45a95bdb22dc957da550c7054f99d2a77e74df0724b77e78d7677ce8237e0b98ac5efff1b85ef2c0a7f7d73d7679c84658df6546b8ca7d987cdad52cb1914e1d4513a84ab9d9c0d1727eff533c3918f2ade4d3eccf65e4dfe6df57d783439a2c633256ae676b19b346c578fd0e89389b2b1b672d79ab602b797cfda4c5b33dc5346a71a73d5976a7b5d3961586ab383ef557d858dd21a2e82024a3951db038c7c690dcca5f18a299948cb7c01710c4731528a0f753a9b0d94c6445927e5e9bc7c56b3321a359d5bee668b6082558c3f23df53c6962698604a52b08a3057e5bd4ab9bda7e55559a86f5dda7c964598f93a785ed3bbb980e5faf6b5d6b79f83d7e0a9fa6ee97d1bfca91e4e6cf05669e00736a096d7b36df058fef65cef5f95bc3395fc7e9bc4a8dea88472ba7d4697bcac71e5a2bfd5fcc8f34d019b14e85b67045682fae6a1048a089ff3c35cce0ecd7b25a879694568ccfcb3f55ba9b5f567f74da0afb759e90ff0be8662eae86394a511a578f14374b7e7baf63d33599a69ba8d42d2729382fffdb86a45bfec0fa6be5169a5864c8d43e3c7154affa764e67df0f81a9979af65e655f01e3cf9372db3a3b4ccc71df826dba7634a5d9a69987097fec93809f7e99a70e3ed0562ea35c8969965dd2fb7e0d59072cb30322c0617d4e053ba705aecd45307eabe1bedf39f0eac934aeb16a04d764903093c4374aebec6d624cbab660883d6a9d68fc1936be4f9a396e72fc147f02ea056cf06cf94a1f3dc7f0dddce0cdda71da65d8b9d8ae9b7bf3b6494b6c60ad9ab41cdb2ad56b39c72639044265076b40d189e4d4cb0e22cf4cd437d7dda614c27347bffe8f08b8909602c7cf3677a36c5b31962c66302e34bae22e616e4bc5c0e6b1d5482b5a5038117574d45215e22ab4aa4967e3621b6f80db2d3d3e2c756da47a52ab7cfb13477b06d136ee4efb5cc375418c54921b32dba79e744ed547a27a79b4031add10914acea9fb52c94ea86963014fe810bb2fe6b82957a7fd9d4bbde69ed9df9382a43f8dc0a01b62d6e3541144e711c3144a472fc143cdb3231f3492bc917e043a6d5ac77cec4b63ed9e0e77f7da01d5c89f5ebed5e89d5b8bded15fe8cd45d6df2a1b8514dfac7eab2b6ecd94cad175fbf5a2ff40d6a5aa3ffd2763fd68c4f4adbdf0b8721381f6625d504527191546b7a697d44a4de0d65f90c756ef702bd40fa52a86c1f55395e5abb133c3b4f296cb9e03ab6a2ea962afbba7ee774a85f994887cb1eacfbe34affcd7dcef110b040e4e9037ebe7e2c586e084850a59a33c624921e54d9270a8280da03f2883831e4429fbf898267502087d08565fb160956ebe63e05a576feba1d28878ffef930ad2d99decc4decfcbc0c0f4825e254c8bd24115a6a0c750a42cab63de00f03f751b5f9391fe6530e985f03a5865a69083e06593b9f558f00e6ab7f26a40c4b3d96a699ebbfe216765ebc7bdae08a0c80f423d9cb28e048a88f1c5dc0d8aa6dceaf40e7960d7ae8c84e759ca0f41a1aa0400f921f633f4743a076401630cb83d9693be0e28a3414b803f4538dea59188feeddb3374ebddae51c0df335424d068ab35b32d60bdf4565ce79e8a17ea76365f1800c8bbf7ecd1e82a026116d0907dbceddfc3293966544dd0487ec9a42d8886819cc41108856322aed956189ea6cb98694335c10bc508a2e47ba3871514e495bf6fa1c634ddfe407483652b9554c5b211547271e55f1f6b3bb4824666115ab7cc7e3268ae99e07c502da69fab3de84fe6b6d0fab52dcabd41e825fca5b55677cb2deb6bba1ab3a6c51ef5860736df762fb70b57f95383528d32da1b4da8e1bc22aa98e6b21bcc84ca95daaa9ed092ed5e855d43d33c0edf3a8a88b7c53f24d51d0b3fc7e442a78e04dc4dc4c88da0875d9db31f8b0095a79b1bf05bf80df036a790fec810cf47bb9e2fc3158e5d901753cf33750f78755f1341dfc9e1d72b5ea3ef8c881cd7cc48f6d1115bc22f658fbf92d89930fad098f5446381b6f7e5271af6da7e0c151e3ae5f75afaf2447df56b7fb3ee8db83fac6728b05ccf9f409f1d7349ac7e81193ae2c9cc7c267d22566c1f939723060c03487434d6512ac30e188099ddd3201c764122341897fe0a5036c3140ecc1fa2662a60e16c6fcebd7559a8207cd3b892d21913cb6d56939ed2ca841ef38e5bd4df9dde27d3759a6951ac3d101f82aff78e23846cb81fcd38dd4559dcad9a08bc19f732ef0f85245aa720d780243d41d21b14088a4ff9da10843c39ac16557e7b38dfb27a7c9d25eb58f561b20a4f17c46d276d40c4785afd7df005e99028cf184a8dc19f743249d90c614b2e22cbf18a3b1f0bdf21ddba7c51ddbe5abb42bf7632befe66f7225b6404bd155d3ce66f6adab92133adf7041134d8fec37cbbeb8b92e5124932c75e5c2397adf55cb8df53d747af2e034bf7f7c3c1e5f0da7d8c5d6022abbbc7c33a8dadeacebf87d7bdad5016fc7daf5ad62ba4075f6bded1aebffd446a8d534fb1c6abfccbfbd6439a017888d63baf025c46f866b64d7d56b02786e8bfad81646b1e76655be7e3ebbb07eeb65cbe056f72535d7d2f70672dd32aaf4fa759eedb965d24c71147d8b0edb0aa79210f5b61199f506a195ece30e74cb4141faff0cb2e91cb9178b9a5e522394e99a7ddca136c5c197ae3ad9ec77bd0dd7de3f38bede129efc1d2ce1c9d696d05c2f8f313d5a292d59d005c5314e38e683c5140bd45546cd2774c160d2e08f121c27a4f13df96755371e95560dbb75c5b71e5aeccf49f6e1871623b4852e6df9604a05b9dad183168528a9e02b529484c95393b842c56c1ea2559b5cdbdca91f3769d1fefa5aa18a1ad91e6e7e8ea105aebe22a80cf70f62b689cdfdebc5e6f4ef2036a7df203679a450751e8b1d487b771c1b236db2aceb86c546ac2bb1ca3ab6f5cb1eb3dd4965d13da988aec7d06c0b002ae9b0cac557c94f7ffdb596de29bcdf3fcea55bc97fa3769b41b26d581bc789c2a3e3cde3e8da2dc6b957a54dcd4bdc24190fae950ccf75ff7ad148c1f9b9e7f581077a4309f0ff070000ffffc582ae9ea6a70000", + "a34512b7858425d220a55a6a2feb021c": "1f8b08000000000000ff84d0df4ac5300c06f057a9bd775dd7fd13ba82573e804f10931c56d94e4b1b077b7bd179258237b9497e84eff30f9450cecc6a957d0bfe673250f03b0b285ca15496457fc8ed71d6c14b948dc34b7a5de3be7351cf77d8cecac59b6be3cda5df129dc1533c54a445979444076f281ec1572c318baa05176d2067d376ece6a9b33890ed6de7c6a7796cdeeb17b86eff3007df2995c6f5c3749b809910fb11ecd439fa8f42ce8d1d891d0f08002d836b716e7fbf345704f3ddc967000000ffffbc82a48b29010000", + "a531f1ecaa4c59f1b1b4d21b3a1bcddf": "1f8b08000000000000ff34cd410a02310c05d07d4f11bb976e5d6402ae3c8027a8934803ad914e1ce8ed453aaefee27dfec713dbeae32d50bc550af80fc94c0100009b7886b5e4be892ff1e3cff3251ee4ea55e866f7a2ad4987eb2bd7b149c73425609a43f8301e14907507e52576338f848975ff950e4df3fc1b0000ffffcbd618b394000000", + "a8bc022275366f5e8ce8a9fc63118a67": "1f8b08000000000000ff5491d14fc23010c6dff757d4be1a56718ba0e9f622898684101023fad6b565adaebda53d26fbef0d0e34f4a577dfefcb97cb1dbf5220b16f3531e89a32e1e74f0b55268410c29d4641a411216a2ce81e77a3293d21b4d8e8f2095e8c754e073213d1542082e26c4083adb1feebb73abfa09b8246ec1b1d8dd6482fa0097a575083d8c607c69c3848e5d30a002306d11e1b098efd092c4fb374cc648cff5aeaac4f658c97c1d6a3ae83c5bea0d1886c9a8fea7ad9af6fecf6b15aacba6c6b5b27b27c31bb56cf6cbc5b4da639fbbc93efccce37abd7a5916f6172b89f77b03e6c6e171fdfe3cd65be0c1023045b5b5f50e1c1f70ef6a719589970362c9557a0fa32e1ca76c4aa820600a42567ca7647d389b2e1103f010000ffff7280bcd7a0010000", + "ab9c4d30021948033f1365fcad58b414": "1f8b08000000000000ffecbd7b771bb7f528fa7f3ec570da35064a88a69c346d87817915594e94d8922bc949fa63b99411094a1393008301f508c9fbd9efc2c663300fca72939e7bcf5dc77f581c0c06cf8dfdde1be82ee75371d7bb6357cb6cf2e1bb42f0256d29db6c4663dc5bae8a1b341abd1893d16cc5272a171c31a208c7eb7855b0a850329fa878c07aec7e29a42a2847ff7881b7e4d1da28782bf19af7a64891388b49f902af25532bc9a3f32dc6c4d6b86aadf146055526ad558ec32ad3d62abfb1a00a6bad72155699b556998655ae5babccc22a37ad55be09abe4ad555458e597d62a3c9cf487d62a97418d796b8d2c6c64d15ae55d5885b756390bab88d62abf865596ad557e0a6afcda5e235c15d95ae5cf6195a27d13c3a1a8d62a73ddcae0b3e77fe9447ff923ff7d7628960f32bfbe51119ae0e86d3e91a21033151d0ab91432d3a3e84507f37904958a48b282c95b36ed7df6269f305eb069b4e253262375c3a2836536b961917d43a21f982c72c1a317bd7e847485d8be8af1207a10ab68913d445ca86855b0cfd44d5e44b37cce22763f614b15e53c9a88c5729e677cc2a2bb5cdd4027b6895ef42fdb80b85259cea32c9a88e5432466ba961b5d94a9e846a965fafcf9dddd5d2f8301f684bc7e3e37158ae76f8e0f8f4ece8ff65ef4fa9f7d76f1edf1797478faea283a3e8fde9d9dfe70fceae855747a121d9c447f39388f8ecfff127d7d707e7c4ea21f8f2fbe3d7d7f11fd787076767072717c741e9d9e4587a727af8e2f8e4f4fcea3d3d7d1c1c9bf3efbfef8e415898e8e2fbe3d3a8b8e7e7a7776740e358fdfbe7b737cf48a44c727876fdebf3a3ef9c637f9e6f8edf1c5816e45b7e06a7ef6584f17c7176f8e48f4faf8e244b7fffaf42c3a88de1d9c5d1c1fbe7f737016bd7b7ff6eef4fc887cf6f6e8ecf0db83938b83afdf1c5ffc4b3774727ab2777cf2faecf8e49ba3b7472717bdcf3e3b672cdcd0701fddc2ce848c8a259be4b37c12cd337ebdcaae59742d6e99e439bf8e964c2ef2427f567c96f16934cf17b902782a0288719bf9d91f0ad5d15f9e7f769bc948d0902cb8c384043dbdfa854d54af60ea9d144aa887253b9d6d36ebcbcba57ebebc4c47e36dce0ba5414fcca20329b38724a9b6c67abe3a55dbcda6fa762624d263e01a8e1556bd9bac38bde3efa45832a91e10c74982d8888fa91af131de62f86c3bd0dfe4b4810150ee069d15457ecdc3eecace14e1749f489ac9ebd5827155f4e68c5fab9b01ff4a0e78b78b5d4501a32aebe921d8f6976e456a23ee4db2f91c2922ccc0851eb818e381c5506c8b7bd972397f40fa2013df32de0edc48a34c8f15c64963571853aa3b13b3e8fc617125e649c246e6572f574c664ac831e1b4effa51436546c270bae6ec5ea54d6cc99284bfa4cc4e5e0f97de8a7c1af53159df66f3154b99ee8677bb6332159ca51db6dd6eb77e9c2bb385b07d9f36d2413e431d8edd386037251124a7dc8d9a6474341e28f900bb364066649452b5d9a8bdbde8651f274907499af7f4f410c63d3dc601ce0c77247b3005bc9d646a72a35754d0359352c8946db7b39c67f3f9c35ab72f93a423e1e324419ce63d332c9c24763039f6f5f3191258dd487117891eb4b6dd3a925c2ecc1c95b0c6e8684c14ed0fd4570d7053dd2e6694f526824f328556a8043435c601cce886267a3d2cf0cd2463bf3134c1b072055d07d033f31bdced9eb0de425cdd7fb3caa7e5e8a67a31cc1c96a8b34f1826f14f71f97e69b6556f11b373e5ec2e3ad2b345f14837388ee22e529b4d7ca0cfed6d26f38cab6896e5733625d18db863b71673c11a45791189abd9aa98648a4da32b36c934df09a42c2fa22c5a4a315d99deaf56f97cda8b31de56e75ae0728a37e501e9ecbb550ae05b0f5d39e852b4d3276cc7a18395bd0df148b0920bdd8de3da56f37987529624b180719560cecaa57bd05fe433a46b534ad966e36a777c6d3baecefec0ccc04ef3ba826411f3bbaf28a5759cb3d9d81e54d9f7b5e3e96de5299be59c7944aa5fae195f2d98ccaee62cedec933b992bf3bb4f2682cff2eb9574cfe6fcf32d2e3bb8aa1cf7bc782bae7e8abbcc8fb31c9e46d79d3e0951afada49734493afa1ceb5a0132b90b6ab128202a6fb36559eb7e57ad73162cc551091f1a72cf991a54e80cc3aa974da788fb452e372140e5066b1588e1de4cc8a36c72834a9eb35ce8ea47af583191f952098918e1b8572e7992b85e351f0bb4b23793628154b0c81fc2092609eb2971ae64ceaf87e54f845398967960387851367451035ebde243fd236d02f0308ebb2c3568e69c9a69a3581ff4289b2e729e17caf0b8312687e161f1bd31587187a219d092f84089c5ff1577670863a20f5e8f670b4699f99d17ef189fe6fcfa3d17579a59860e6867dfbdfe9ae5fcfaf4caf0d1bedcd465b2703b6b8aa7f96cf6830659da3705f3ac500793092b0a36fdfac1978a3b5628dba83c579962f49fbd93d38bcb8bb383c3ef8f4fbe71d89c05045ef0afd9442c981f4cb0026650b50a6ff24231ce6491248fbf6f81ab60fb9106942d691b8a5bb447065356d9359c961a9f3c20c99642aab695b11fbd6580745b3f3bbcc9f875f5ab5f18c215c491cf106bdd374affd93bbf3878736411eaa0bd9aad4458093a2d935478ad31e692f129e3939c15651fefdf5d5e9c5ebe3ab8384a12a47a797121b349ceaf3b947ed73b393d394a92570c294d46955fda7395cd19c07d4bab76487a2dcdda9063bdb495057247ba6545fd51da12b645989cd22b04672d26870191bc74f4a0e49cf404e82d26be8403c7738b1d030687ea30243e1d4a6f93442914d781382682282231e1a60e5348108e890034f28eaef329e32a570f699b741131a05ea4507235512b99cddbabfd4b19869f4cd92c5bcd557b2d8b89f3c2562e6eb2f95cdc3dd624d9c7db2d39a962bb693e8de48a47f3ecb78728e7b9cab379fe1b93458cc941b5ead260af68ca2602985a5de70d5d6fc959851dfb25a49a6af8263d736bcb476cbcd920fd87aeebf437a0d48a5cb336f6fdd8028ffe7fc4c65b5284d5145ed72a50b50dc9f9b1279284033fded7fccde8646c4a2565a30360d4255e6bdee28474fa0650049da34709a6c4c4beffc01ef423f68cbc91db3224305979d67dd05919e6bd2c32839850395a19467e3c98e8e301fd1c4a9619026bcac8a437f564171eec9e5c64f29aa9b0e420e0fdbc64a0764806ab24b1237b9264a02cb7ac9c64100a4b6f2b3018ec26400691e541d782504656868dd5a774e55959fb4eea73a66939ecdb930452490eec9acea9d41b7bad8b488ed65b32c7d8913dfd4acbac6bbdaca920b5154f1529173acd486da153499a0b9df22df90509c2f0d641feab52d0c143c4e98448cb9feb4905fc394e11a786532aa757ccf30933b32a6b128983c57e55522df442332456e2da6c3e0f9eb4841e178066036668b43fde6ce20240b95a8c379b2f82cf3d1ffbf9b8ecf9378775ed540b85181eb2d44c222fe0af2efaa997999f64ad71b966b553fbc2f06788593c1d54b8331516d9b2f2ddbd292e98aa140782c9fb908c97c5af359a582265ce35a76f51a74f4233002720961bc8c9a81cca5e8016ab4f5edf6045efd40c7ff09b5e02cdf91acaa1719a864dc449a69135c644522bde1b098bf518bf2525732e7b8cdf683e5f5245249097afe97acad852634a98ae5d294b245e392074e54b29ee1fd24e3fc0cb3f34f86336fc3a6d82c3d0ac2723ae3fdf56ca6a22ead766197fa5afd16f98fc99be0eb9a80a54d80e379b5ff5da6c36efcc9f33f3e7ed9361c60e6affa3b013546c83a1e0751b2c05afa7a8b30f7bf6237d8dde63f2ed23b3b4b47ba85250cbfba5ff57088cbdfa9e0d9b457effd3ce3e1c403d9ee1fbf43780856fe8fa4adcd7687d5dd7f2f245927c8fe22b711f3b60ff41c3bddb1076171d31c4c8bf9046adc05e110d5c3df6eb2a9b6bf61596fe69bd40d5d67e2e54b50fbc258b6cf9b45617d972e7d8df34dbad70038fb55b30b5b3dde366bb06c2d28625b17e724a5dd6fe18fab162a76536e90f5afcd6f44b6fa9ecc1b172844e2a4d9718f09796e5104ab3153935af2c74db3f12938c2e14cafdd8738532f85e60926d8964b3f447cf15fed9c0f3af96f94cbfdd929f687d3ef9ac491bc229b5d088f0b59bc9afed844d4f1c48434d074aebc7588fe53144a06a075ad54eb0c22903264ea356bfbc03738ccb23f9bd3e9253141fdd2fd944b16924388b848cd49d28a7152911098fc37b719775e35ef42a9f82912a9b4c80e3d7dc50a4e483aebd2a58e38b282b4aa679187b3d1fb08adfb4a95a4a6cf1936663bfd1cc2e3670f14ff21df91f4db6f6490d0b69c2e5c816d77c2a5951ae1785cca918f5c79bcd7a5b92a643b158ae149b0261d2dfe768ad199a0c8ed18a4c0457ec5e2332e09630268cd1ff416b831dd277bd528ed962a2d893c0c9ab28ff6737903ca6774c127d74eaa7fa638d1a386bb4a6862a5d6f4b927bcd146544ea156bd3edebeaf09248a3d6317f361b66ffc631d108e40343126f078ad915a28c55c47b366215fd0bdddb1fd3382c8989ae534ae1b43fa671f9685ebf3b3d3f3ffefacdbf2e41b2a6ba8d6a91a966debe18d3d8146ed13f371bf44fbad63bda1cd689e94cff30dfbf39fd06da7e736a87f5f5d9d1c1f7d020fc8ab7e8bbcd067d070d1a941a8282d5d080f69bb2e0f849b64bafc9036e4d40ade22e07b1a5a958c0eb4956b0285459a45ed96c5f852b9bda32580b57b3ef6a56d72ff5b6333a63a8d3c784d309439a77739a959c5f1341a5054392d3fe20ff4a0cf26ed7b38fa31c24ca0b86320c67e284f5a679a191039817be162b3ecd64ce0a9c69084478c0e605d3e8646d0b4aa9cd71d84c93a729430a934e7f0bfaa2764d4ea82daa7fe604a0a55e635279b91f0816392b55cba146a9c87f632ffb8313d69b00260165e62bb654372ffb49a29204102e39613d20413026a3fd2a369b8e4a92d83ae174283dd1fcef4cc8093b804e8bcdc6a0ebd240c8bc6e070eb3d99181193beb717677ea7604343a966e94fb64f7a8bbdfefeb0f56fc4a2ffc2bb62c0ec58a2bda27ac2757fc784ac186043f0d1d26b91e9f92d9e443ceaf5f31991bc5edc06c66f305d57c148559edd86941ada99207bb1d1486163c3d1baea7e9f6abbdcf9cb49a7d2ba0cac3275a5d35222b8a3f22689fe4b4b95024a3fd41f6553ec83490eb69a215e5a36c8c4b8d7492a055a09fde27a243699624886b417b8589e87631593561f6a54c122469cb1bbce57607a968ecb746f73955cec608d6d37c6f6fe0c7a74679757c6f185a11066328d5e85bf850c0877af156837d373df1c8f4fae4c0b486b79ae5a8a94fdb4ea624aca136dd6a409e6ad24144606f6e397c39bf1e84fb381a97a69e7211b89ec61b86d4888f09c383b671d4ec00a53137e855633c5065051a71a7002a34b6085085aebb3616e0f613f32804c33606b8bf8051ec386165b55930d80ab23963d9b408baacbda18c04f6b3a9ebac512bb01233af9d6fac656de3f1ba7dbdcb1a835d47b4ba837afb7628f9cbb68c4df74683e2ad3e6e0b463f66a80b3dc9b698c49a8389f160c1926401d679af9a2d49f6431d0737f4b3d7b6c666d370f5f05c165851ef0d9ea79d3e91813d973946d674211a3ca5e9b86f052480cd5ff47f46c77a67c874e6e8f58aae9792dd967003ea3d767b502748695e2b87bd4f33c285ca670fe7cb87b4b34f0a954975912f582a4906c33a9ea6b7acdb25cb4c32ae0e5cd90df3f3bd6174d57395c96a5b3d4cca31ac440638bfe26c41993e13f6c075421c7fa3818ef9c635c18d737e9bcdf36994d923a4b2c9871ee8f8b5bc3213f29a292da5cc729e173751c66dcd618c07378cb25e7526a4d45199d124892679c56ab994ac28ce98f91ac85b413541be6788f55ad718b05bfd1dacb33106690ec4bc2ef70b48bbdb8224e9ec0f1ee97d7f8b44888dae5860872052430733abcfa90ab0d83df0eb4e031098e77721163ba156d462df5591cb7d13b9f87a70748faa2cb3ff502115e8239d09cb10c9b8d42d021d7266675f4d2409127a53caa23c49504edf396d93393719b5aa6538b3129bc3eb6697959a484e322bf890cc2a89684eb2de4d56bce7c6bcc9a66662b4b34f32a313a51ca9506bb1addb038c539c9bb237ea4e0437f2933e035b01d5427b2175fe20438beb2692654a53a414f1a05a602600f18ce3ad335d960af62983391a82de2285fb73604cefa6b61c569e10c35a580e9bd5926443168255d1cc2362a6b9a564fad89db03be81f318c0d4ffcfee4f0db83936f8e5ee1b5b5e6174c05d5b6d5de6aedd09a4d39b76669f2a0cc0f07dc57e699acad9e0b1e748b69bc5a4e33c540aefdc1b8c76d8d06cb0bf2e130077ab55d55ef566026e9a0085967085885d247c2ba4b18a842410d868761172d2bdc3a5f33b360bdcb9fce1da362904798dcd965499223b720d5450897a75c1022e653f3536d717570d7e1f6578dd955270264a71f8261b008b56673ae989cb0a56a83d46b3bf6fa4756706bf57b8d549230f494ed0f36c64fdb9c8d2d26f73bba56e2bbf3d3935d2b6144dcda071ff704e8c6a3b85b0ea71b8fe36a23507c3a6b69e302951d577b765e9b4abc93f92257f92d1bef1a846d1fc6be4587987c60145da13a5a8ec9110b142d750722bbed8f73e6a11f90e1f8edc16948418f3a127dc4ffe8a97e46464afe0f9c8e02e9126ab5c8e0507e79b9c896f994c67f029216e00b270cebb9623729a3c8d44b504ef46cc579ceafcf99524c06e5d691c5bab1902582434a627048e7d791581a9942c86862f5a36974cd54ec0f682982c097819397d3023ac56a40950920aa24410e89eb513dd8236ea079cf94c6a62aaee043cd7dc18fcd0619754b26d9b957bf6e364ed5380cb5b26949e72df19888a5f5bd55ec5e392cf8eb2a97cc7353b4d3618d4253f50363cb83797ecba08e7f7acc7f0ca4dbf004759ee2e85417a63ee2ed5455dbfd616e4f6da7b2d6d5a7fa4695fe4fed3e6effc7ddae39a01a11ad1f7a107b0e1f2673164d9932961c1b1f64759291a513e69ca5ee711a48197dc36fe5fc6b2d836d369ed3abaa3b0d675c42fe1039573f2298631ea00aa82c0eb833b2201c8688fc7fc0c3af0ac7c3475cf6d2279d965dc30c0e7109fb382d57cba0c0bb4cf2832bb152ef39ac1c9b6ac1106102be9101feb792012caae1923afb467c34b20ca355161bac0cd64789192b4419625001b325631f68cd4769477f9fd6705d06c8672115c0eb25eab4112d125fdcb0c8548ac4cc93a308e6163dab00f5b3282f22251f34095322326c5b94ab82cd67a5b952f38d7c1a54c8787459da2a2f4dd3046c312c9bda80b9b267e719358cf10e3adb07f13a985e29581aeaa37943ef6ed64eaab75bd088439c4667bfee235a3d573b36ccca1674077345ebec156fdbe73e2692aacd06761afe70bcd974423185851e3b0e962da38289ac0e3d6cbd29aa0c1c5854f8993e6931af74bb846145337386ea7c4940eaad6dc1f9d4ed3647f895728dd4b72db0527cbc6ee864d866bca8cf676faf9d93ab1da355a1f7b1410a3c32de6cd08a05ee9f76236c78578dc8b50a4356830e5a10bdf6c27eecb6f89faca236353a476e8d767a95e566a39ce10f74930cb58b90bc94a8f25290125b508265780b2caba0798318b623ca4a304fcda7fa09a2d7a73a6197a257000565408611c5d87f228ab1df2d8ab12dc2985c307a85aa8c784c3e304cce5903806e4d082bfdab811aaf69a0eb2d2969798ba922c0192530b70a492e20cd3d5b3ec33d2e5ba4b2c20b79f6ad63c5cb171e7596af9ca0d3d43376faf537c6bce1caabe657df50b17cf09c9beff87a2eaeb27945fdfa6dc6a7f3b08e231a670df162dfc91da6c05528c5e69a40aa8b76b6e2ba390c0c16fe653bb62be7b6538f4c0e59c5a1fd9479808b57dc44994dcbf83693b36268fea45e552887326dabae89f250ff971e1aedef25d3dbf00e067ed242d374f79eb9d0d2b1b8ba3fb6fe122038bfec2749c7bdf90676a74812a4dbddd7b267ed45adc09d800ea5c848fed815958d5cb261edb3216a1d4b97eed77b2ccf14c8af3bded1f5b631569cb677d2ecc3ea2c708a0a06361ab152156cfd8e6d3653a4992ac9a24cb268b19aab7c3967249ae6b319938cabc84ebbd0accf5b71f51358476e592f7a9b7d6051b192cc14e7453417d9149cc6e60f91e013701d5b152cfad9d9ce185a477921e69962668c70ead248c9158bb6f8e7186f31d9c7c40e7c8b0277d103e602c94bfe3e9b4e1168c05b38ed972d4cfa4eaebca56ee068f1a6a5eb299b33d0ac13f0feae494549720614de37018f6bebb7daae7482c1edd24701d7d38a144d9c33c341675a425897b25bb71b847b301318dba7746fafac82d7aff5812aa39577f56663985918bb6c99043652e3017f44a306a1468d8542bcae9c6b2bd3dff316195a53361e7a4a7d6049c21d67a409e8ae99d0511877fab66ad8da6da7b79e786a889421686008acaafc0c9855b580b63651150de54835347eddee9832c2ea0b0068a2b1287dd25494208c31e9f4718ada21b3dc758d23013049c5afe815f3a1df13c10b31d767e6dac67cc3d2b0b116b6582869592b2b44764f574c4b545934014a1be53c05e1ccd58f31cccf291e29fdce78d039481a8d079d40256caddff90c397f9797749f7d8e433b1437c72046199f468b8c3f440b21198ef1c0bd89bba50f94c4bd5f44ce51fc6f15633bae7a905e92549fdb95095e490383ecee1b913e537a51b94365afdd07f1945dadaeaf991cfc9b3fffcbbfb95d81ca62fe9bff9bff4bac001f33ae980401f6262fa22bc9b20fd152e45cf9e0f992db6cecc815832ff5764d23bd2ce116e80a5cdc459ac3d1d57255cac0bd7ff3ef56858a6642334620ef82d11c9a02a9b9b811abf9141a281883ec18377a2cb74a88393808ebe2a56493bc60f387e8ee2653d132679a24cc740b329a8829d383d0d3f03334fdff9b5fb82e67325b982ef572cc85d0871254d17911652a9ab3ac50d1fffde5dedf4dfd3df84037d4d3eb187711ab2207082b6861d07b922de7d984a1e7a3bf8cfffdfcf935899fc7388d63dc8d754b1730bf121a600c30e6600732c952d32d77f0c54d037f79fe6f1e4551146364b30dfcc67645507b6f8f5a1cb5e3c91a466d63fbd61c89aa87570b7eeccf25b5da6d1630a7945735de01c7299f646171854f33d73c6e37f924db475ebcca8ba528025bce655e9c4f6ed87435af16ea53f6c112a5b0dc8a0a3b4d219fa4c4b7c2bee9be2e41baf2c607e190371bd4328d90f07ba1c6a03423d7bf667531b11736b0433c0c3ba9c564afb81729828fc1c05d5d78282cb591f5e5770acd72aad58d081463219806cd85f54357206f2b3e82dc57b9febca4d4e00400a1d42d7ab2badab13927f09dea3781a46f1375381d938badc2835df0b40bf4cade92c4ab67a4e625ada6fcb1c929a358b5c1e26de1f4addfed7004f02ab61029e046897550302aafc71db6adfad70612b93c31477ca24f3493408aa2159f64abeb1b659397815b8f261177591141033cba7a88b2c809c45a90706c0ce85e05675c11cf58dce485662b767b420d1d23739749eeb3d7209b9686971dd575c8ae393625d12cbfb7896cc4ccd3adcc3956cdc51d8e71ea3a828a881306eede8fa807da938a386ed344b2e3fa4e4f0d00b518811c68396c12e2c906546f36e6fc7a2804ab41d3d8649b903b74cb7634bdab9c4f4d435e341f9d8f8df6903d55a7e6e9dca8b21575fd19302355a8aed24b4d0f430afbd4444c2335a66102260bc99dfd417c25c49c653c0c077682d0defe1882c3596f2996cef222e94c3382460fead85570e21fc81aff6baca48fb2dbd203a5b26c23e3fa044ee36a737c68d9e9f4bbde9bd36fb6a5030adb5ab7d0f7ad0e5d1aa194f2f6ebaa10f9b2bfd9e8a786826db379cfd0d7a1acfbb5fbb24519d76f95317d05d819b7a62ffb03bcdeeff729ed765592a0ead1f270124d052bf833154d04bf65f2daca1e052435d27f148bb2996232daeff723937c0c8868f44e8aabec6afea0b957c94c0eaa09984d2d476bd0c22df38e79691477d9a83f06ef85e53c9f30d4c738f0350f8a89a47d22a8935906f22b3190dd2ee623390ea92c0219b55573099ce20fa0b875c531f98d055a915f03b9f53d1b841bcb838d6dcb516a32100532f09fc3f0a31684d92b960fe3e858af12177b62a957a99eb2ab882ba72e68fd470d15b508966fc31e4bb1cacb7bf67febf165ead99c74e078edde906a46ab7a168d20c3d5d6ba495742d62db65a3fb915127cdc929203c6264a23905e65c74cfe8b41ac617b1ab23236fab18569cfeca55f3e963fa4b35f4f20d24c15726d86c4c937460580b75b2bae7c538f65d403b1e36b0b3f4c9296684136d42be37c82be5a71fdcb3966bf8c09c3e98ba7b6a586c6f51ea73bba6f86f003b4a51da387fe56f35bedb191465d6d12a905035684071e9a38c4953f598d49b35317093928a301faa47569586ae433c75696c0f0bd8f31f063d263016acb70a8f8fba773efaee6fab1e19e9c485da0ea219a072b25e4caca95c693d54b2c32493a1ad4e6d903e6a050fe8d215949ba5b1a845086b7c6c507381ca25ae44acb439a53f83fa040cd3571ddd178bed9a01c0c8f151c961b7d60c8eef0600cf809e308e2e8105e338d0d1dd315c8718487fc0fc2db6f580fa4d49dc701ecca7288dcae391405fe79291f7eda19b543fade19b65d7b7abe8da41b062e4da21f653301fdc8b6e947105b3545005e979d69a6a18e34b606857ef70416e27f2af1ac254c0d83df2933d0356cd1aa05660b456c3dbc4dbf0be28f98aa659b087354956ae298985ae5874ad5e36a5a4ea51cfe19c20d70aaff6a486dad24534e32cabab1b70bc6eebc8b51361eeaffc05691e354ff76cea468948f71800dbc394c8cd87808b4326d70dcba8101b351746083c89d0dc2e8774d29f41c9214aec2b0b9aa6d13a22077992721b6b7cda84804dd25064298a413aa9c5640ea457ac4c849565e5bdd66e01c38a70dcd2cd56d484982509ba2c425fc093dd95ab92d6c62851a0d3b5de7158bf41983bca5331118bda46928caf88317233517f40e2c98977a64606c396508b7d9ed920405af9ce9ce65e03d61ce8a87cbc023e55238595f0c1b0bae4ce477a70f11ddb187fd74aef96ed01e43547767df54e0ec964978bb1fbc7521c8a64e36bfcb1e0a5dc995dbaa2e11db14c5567763bdb0664246cfaae0f5cc48e9ddf81989984b2df10cba7f46a267a68f675ac87fe606fd2c06aeb866829fb7864e5320e9f34af4f47ceb578b9b00adddd6f70e0fd63633b51f33c577b2a0fecad47fcc2edf59919620cacea35f053dc8eaf8ab66fd8e0c6a8a2431274494a2a4e1df7f3c383b393ef9268d5eb1abd5753463995a490696da9e81e4bb7c3e8f4e4e2f22c926e296c96826c5c2a83b8ae8ee86f1e8e7f6a3feb33e045612edc5a0edd8e564d01198e449f22b838c690e31c90626160a49fa03248cf349ee1826bf2960f921298ff0c13398a824c95d1b0287e1b2423d9a6368b3416126a11fd35f8361e5f56191dcc4552af96042a1e91152d59476739aa11526133af729ed2626a55d59645a2be8c43293b38fc6a52a52e081513f4e29e2495268c98b0ff9a818a733fdddf07f528911230599417abe6992ec4aff5b906998f36e5736ec4992d8a14378dcbccc79971b5e63fe78366cffd2a8294b5e4b55826c560afd595951a30cf056414e4222a94dbd65925d964e1fde329124cd9c062ffb498264c52c41513dac783426aaddf77a6f1f6cd5399fb27b48c39c24dc19dae1fa090c8976560ae3305877ae1c3fbc6045915d331abf7e73fae3e5e1c1c9e1d19b3747af82fcda93ea4a18bbb25eed12cd0f3b1dc80c06b9d3c7065e8ade4d562085539b33acd3d1ef369b5378fac138665eb0aa4340119e83fd4e9bbc643253e841e1ed3c08ffa1d5484238d3e5db401301aaae322d89cd42637291f4d3c7a2dc4daa917d574703c4a83fc6a6f845ad98400abe00a2a6aa55e67104f4977aacbe93bdf12e105d5690c6e83c48eb7713bc6a93f562be5a5c31592d6be41034d9c6155ddf64452d37573e438a527abed9c441ac676cf3dd534a4fb04fd062144e305a1f59adb9d421772002b782b01a0bff69fd44ac548142574452ee20f19ae9fec0f53bb4b21e3a3c2ead1f682560d49027374622b6e1d88317cc8b30f58077bb021dfb056a751578d102e590534f619ccfd0aff0c38e538dcec724a7229c17c7837c287a7732570c62d153d19abc5012e1e8ca91a3485be7637c06bdc0d519d086773e7e6b5fd8f4e3ceacd27907e5154db183292f1c986cbdcb4c16ec98eb76f7fb189325e22f699fc427424559641832405fc07b71e37501ca7efed2e75380981e9b428477f73151233ea6d2d89660503e9340467985d4ad346c65582ff98a64a3d5b87e9eb676bb3441da122394383ad49a91b7dc5000b49e640b716b13f3e02d1177fc7bf650a42d52a7a9ff813d14074a2c9a71a4676c36d738cc36a1511ce436605c1ddd2bc6c1bfadade1298a5f3df06c914f82fc659171582ea249c6b9505a329849f11be3b1c91214dc1ca0aa19e8df4971af69f0adaa18484cd23baac2f0f807d516691dc4b90a095e8be1b3277d41f60815ba7157ab1b8fa2a0808eca0b4a2cb55398dc341cbc594019151eeced9bcc64dca9be19316e307e14579551f8ec290e94249da3fad046636cd3edb84c5203f155ae61037590a27224c6faa46c36aa0751ecf1b1fb3cbab1863527b9b919097503e18cb2744c72b90889c203d1ed96f9aec3742e3c240e773bf6c53418c47c358a5a76e7beb63bb52f4c6463b5ecbfb647478d3d32727fb57b9b08da5f8c033b842495261d2fc238d82d5852bb5303bb90faab0f8aae9b24c92dbd264b437d2cd2d8340554094a34620607ae37f002e1b44170d5f01038699b859628ec93b97a04aa369bbc38c94e34ad3c6c5c35048523354e35014aabad79a4abf9d54768533872cbbc15d5a1734c9a634f9243a0157ef01a7d36f88770f860ade469f5b3609406ff3e1ddb95e42d82d4924f407217aac565c9d0a8a03998fb6ecf2597558c646465141e9ab041de4f416deaef82e4f49c647445da651bfdf9ceab4d9a5a4f6346cab6a6ef7980a07d7f1f0c73b3b2087a4e202bb1e36c4d6672935f67b0b207ebc75cdd181fc33ee91386c93d4313af599e9bbb35d463ae5f2ea0f48eb3a973cf32e329c31f6038367f887221e7df7371c70d7839cfa94c89854be6bfd9ecda0e1bec60339a94f6c3c0c403ec0b61dd78d4eb8d63bc6d738dfa03f385ec6ab6787abbe54ebdec0f19486b95f78d7e9e9c41e2e34153757ed74824e0a0574f2a61f6d2a69630201413c3b7f549369db269905fa27058d6bc01f561e5b5cdb96838a7693a1abb9fa66a3d2145cdcb23c04fbbdcc6b256feaa398446b8676bdbc605abc1e0b2cd867dd5df71e79449793b8e4e572a12b3486af20456793ca8e737f17e1df90c31509bea1f2fc3ebe6c2bc887b0a4cf603f915db53de52ef74ac36f4a77ac615e9136ed9fdd60a8ca8bdfa4a1b27d7f605b1b21973d05c3bd73befe17a2ba6f92c9f183754ef54958213030036cfe6914b83004eb8190f595a585470bf32047fda8bad5f5b6d045d5a8f41acce78477632e36b66933b682072f99cdb77ab74e51932da4fd94b316454a4ecab3eb8f6bccdd44d6f91dda33e115da631186d33020fc51e4b4d462435eca7c157e667ce9122628fe1c65528937a42a0bc3521d0238797554f9eb26799db5441b993f1260305174a947509a7790f6a6f39352113763a3ce580c7dab204c8309990b3206327ba05b079acd8a238e64a18846ab7c9b194165b85ddda007f93720cf6f8dcb1909c642d497a0a94d5dd5fdb7a6e879441e0e5ffd53efbc2ae139221a460dba255e54832472346d49870dc0657851d2eeb96725748569b7535e576d7f15548b06babab3026a23acb60850e6ff2f9f43d9cf31d07a25312f92481c056976a89e4546c3672b813d05cdcac03b43211511936cbb700f8833ad22e333b8932a5538e774ec46cf51f3f871d8725e58ee6558f8f83880add73a4e65367ba45981c2abaf604bf8d17061bfaf9b8e40a90497a0f34af5d726923f7b615fb9dbd96683267599bdb50704a511f6f890d4948db5d7747e7e3f2cebd26f3a96a3c0124a012df9defecd77016a6d2e9c9ae6afaadae653aac2d44495635e7415f0c64d3c7d2d2d5bd17a197a51c07c7564fccaa911b49cdabeae4d1b8a63a164d025c5723b754d19bf2d85b4de249ad7c87e0e7e16657335a624fff40b7d41a24f046c7bc06072094f03ab7b614cb8f00a4a79e6e869516f6f6491f937d3cea8fb7a4b8c9676d4e2c15f8769557bc51fdbfbe26fd1daba0856459b0a6cf4578424a0394ad6ea9100b3df94821a4da7170eb0da99eaeeccc1295560c12dc8d0020356e95f62a4f234be3955f89977bfb3ee196d907885103fdea35db3560bd9670af15b0a65fd5300b2ef3b6b60b07b50c7ef6eb111be3419b93a9e5ef0f94628b2544a5499641d4806152615a11824b24b0091bc88b481871005cb30afdb636ca6e8c7bd1bb39d3b86072c3261f22531ecd7259a89e1327e07bdd453e6185b1895bed874d2d115d3d80bd5ccbc02d77ab54003030958008f295f4682c678857f8603962b0c80f0af190e7e43b122e724b4e9b4c408dc304fed2e79f448af292535444405a4d912448c2d57084ef606390b945c55a05ac88e2e7f3b8a8760c3b56d92112994b40f2229a67f21a6e09ce7814777d9383e6b165a44f466a8cb7dbed60141bf62c26b13e850f318967f91c92c5c5d6a21b93d81e8198c4bf889cc724d6d2ccb12f5c64cb98c4924d579a17b13fcef2eb1bdd6c613894b8100bfdc7052cc0cf376292cd992d18b79b900fd5a89a9da37aa0761c1787c2769deaf0d6409f28397421b61cf0a922978a56522fc2221e542f7225e72a30e1be538d3b7a2f1562a3f33106c5d58922078aaeb7e4cd473458a10867b8a1df1a325630b2b7d9b25d1715e612347cf8e8548de9812dbf74261f7a19a60d3477c8e0d8f15f2e698ad9af8bec7a4ce3b7b0f54dcfbbb7d9b209cd00cc8b6c193937525d2d5a8af9c34c6308130acaa2c94a42c6842b29ee0a267bd121209aabec8acdf77c6d48a328d9de2fc573567cf97c912d7bbf144edabe9c662a03a5c4db6c69277993156fb365b570c1e47598422864dff5076d3aacb20330b1d6d512f5afaa41629d56cb3dae346d5a0d88b01b3b18546d1c8c971e8ceee5c8ea04ecc7e43d093732ee7e400c77e3614c3afb6e896c9be66223890953359f614f905c55eb2709ae1ba5936f4ba69f6a5eb22a42f7f333583a500ec8523900b89a0f1db64ee36c3add912457992beb5cf26019aee54051d9481acc8daaf4d2b46df31d13858d7475994da76519ac625d8faa17e1912d7ef0b97e3ba83ea5d87c5d9b8a1d3f2eef3277e18476addcfa79b950523e7ca4c5326d7009ab0676acb394edd2887cce6c514d6aa24ab4d01005955bbd6f01308eb8929aac80a856ed2e4c2aed5c495c95109c082fa54b09b616b716d5d56ff6fb38a005a78683d92e188fc2ad6dd715eff55683e941a66dcd0ad4d36cab9634db06c4fd160a2a878f24812e5510952d0b1914b37b7d529f1591e55a8a7ac4a387ef9d33f4fa45bfff98d460c3621e8b7748c90ad97bed3cca0174c3ed9a794ca34fa59dd40e40ea6ba96227fc6d7d5c60db6a3651c58e95ab2ed3eec4a035d46f8ee4b0a1af43cdc366728fa5cdaaad99e3fe4b861fbd8a3bc3d7773b7b04b3317c404bdeb5a23d90550b9bc4dd346beee4bf81747aba19cf7a7dafd09ab3fb5609f72bafacb5616acc38138d54b73bc6642a384b3bfbdb746d7ef5b7db6d6d7c8c2b7096fd8307a811b31f9c3f0830ac4125ae6e248919b3c4633f5e8bd4768e7a844e153d2796d332219642e29dc9e9ec24eb7b63f9e8b6134e64c56544d0acd4347a5fdbdcf8da9645ce4f7e85727b705f8077eea83f26059d8ff6c70377cf0329c8c4047605deb17c87776c9e24b63330608bd23bd646e2888a772c772ca5f78ead4c1b98b95d84d92edb99f103458c32ab836b2037b812f2481fdfc722ca9d331a1bf1b14648cd5b2559bb3c6310ed0ac11a6ad8e98f89a05caf61a569a99112b6f751426a6eef5fd8a1f46db634d9898d5b4119c264fccd27f3ac285861c57a7ec364aecc9bb7d912cc7c617b366f4feb8049cb9421322cf59eb6adc3d06c3e7418770d816f7252a0bf6d3fa083da9ecc9be93115e135efa70c317784e1e63c07cec2807359e4f402d651711044003de11a739124b64990bf64e31a73f9916bcc713311b555517f04785ba83027923e204e191e86177f366e39e578b8dbe8b50237a6517f6ce08d9bbb93391e060892bba54dcbedbe662ad2a566a3bd7be420c4abeeb39e512bb4f5bf67aeac2df56c5bfcf8bda5aaca3aaa528cf370b6c36d3fb8af252ef2df584cd6ed81829f401d753bdb4af461bfee24b3c5b5a40def4ebf3b6d40be96f9e97adb806acfe17c1ca2574894087a4e738d5c2634d7c8858f1a1e50f3e13cfd80e6784c270eee155e3307f7ea11b85721dcab36b8673e83b5857b277e35b3c8b690372ba5b725b47f3cefac59dba7a49e0db04dd880cd42bb8ee2ee0efea0768e4acbd507a4b0c902cfac4fb7866493c18a4431eec6d1b69e7fe351cf975d4e264ff7b1d9224cce6a0a2cd0d9bc5198fc024aa8e33f560975ce544509152a9d4ed498fea2484d45e3af03b9cc6a3aa8c7344fe74cb56a9ece99daa1792a982a354fe74cfd419aa782a940f3d4f4ff6215ff2f462418b05899a308f2a5b5eba0fe4b22c17f83f21a6468c482ff0d29f07f89675ed1dc4fd132c82bb2fa5fc820ff3184f0117fb5ff940866d3e9234a34e4951060dd29dd885ab56abbb583815a2df23ad8408cc7eba6da0b260429715b9c81407dd5e61fe1afa86ed5d23d3642afc7095560db60d0ff6d05a4d735b52b217fa70ef2a36ac6566f93dfa3247c5471ff515086b8a986c686d511c64e05439fa85d9a85169d8347988f691d0c962d6f01e9d27d221b3a92911ac931e123391e3f4543f2985ec88dea633a9f479674f051754b8d62fc877aa1ca2e7d8282e86922d7db8feb0bea82ff66730f22bb326416ed10ac036946e39a2709d59a83f98850fd5fe6279fc6b99f33d5ceb93fe9028826e75d63a26b3cf4089d7c92d62c006ecd1ebfadb1c7c0581e2b4c5e3dca1857e2340c5f6c85168b4d5426af99a2ac127ad0b4c4d6a31e5dc2586f93357107dcda63e3563e51566eea606df3ade8a46b377fc85c3d62f130132115d7d1c00022ab9981b10435912aa3314b2b9f26be28af93a416f387f1cad86c788bf2de93a8aa4b8631c5c8279b62aa5e968f9862cab17892263f6a9391759b4cd57b72fb549bb1cbc4f23d7b285c2acaa0a804394e55b027dea2ecae90b19ea69d962d74359d3d473e6a3c26cada71b8cde95407a646706fd3ebb52a3bb61d0237e000fe9af662f18833f96623ddee040c58c3bb4794a0244a5032b24969de6a598ed28eee1c9a6151724c94e3f877b0de9230d27252dfab111b6f3608fed247935bf57724b752d6a3502303704ba8a7a573154c3036f86b6ef116312faa83cb921be9c1749a7b7cd0d86377014efb0eebcd23108756d9426e119fcb04575b56550d8101340289df3f30c4312688514ab3cd0649ca88a08a6864f2b1ac1f92088c379bce7e87d2bc72fb7c92d84217dea6a58b5df93e54dba6bdb69bf6ba65d376a49a79529ab2af2d9cefde4a5fa3b697aaa9595e88dbc67dcde13287ecbdda79e20075678f9e38553d71a6e738c4d7f2a10c84af48124db44404955acaf53760c1930609ef461052c9a6fc10b4e8650852c79f4e0f512ff7a8344972e8b4b38fb7362158b04223367641fd8e80d859b7119020ae40543d302ab25fd6c80050e5d5e673769dcdcd951835a25df50375d0eb9246456206971be89f77591165f6560d4815bdbabe011598ef289adc6439ef45ef0b163d9b9a543fec99bfc04f8968ca26f34c32f7d91242c2a1cd28579030369fe869f8f673f5ac88c41d6732fe94f8bf3f946b6dc771adcccf53e478bfb701a3b48b2bd074b922c0b643a3d8098d22498481c63ede3e0afe0d6f86ef6bc29e35380cda5a6978518ec6ad3609e74bf91f9b2606f9687f1c308f47cca7079ae3ffb51689ca1549bfa9ddbaef386e28bf7fc38ed45738ba801cb988f2738c837c1503232d224551d31c5b09333eb5f915bab157adc3778d2af6f5a074d07905bc9af579fc6042d97d12553d240d8812589ef7aa96a4c85c85fdbab5b85cadafc384886134cd668320df58e9f8fa434dd432edd67d695f85beb4bf06beb49d8e71a635cdfe605d6a83e40b36071644c3da9c1465baa024b1770e1912084ebab8a14777199c20d940a6c46260d2ccb0ead699a434a5568c3592f3a861e0c1942224290f9c8314de6c78c5430db27098bea5592d08e283a9aa2481f45449c2466a4c7e0d87a386baed30b155a3b574eaae963d2dd35ad924577e563ed94e5b56dd24d19561b5c355f0090f2ad9a87fac66e43297a31d41bec29c5f478558041943822c5d3f9649ccd2e640c126adffc0660c595a02974973012dc150ccf27debe1b6a98128e1eb5ff5c4a7b5c3bd17a4bf7789913467eb733f79510b26b1d9ec3f5794ee3f87349b366876b3313f7855b7daa1ca8b691dca5d8ca9cd4e31a86c85c9a8e880bafee4321a95ed1bdbc3b7160fdafc0b1dea4b78a0e7b541622b1315168f4cb3d119bb3eba5f8e6d024b576ad66f1cdb38b038ee2a4ae3b86bb28ff96a27108beeab75558776d5b0cb3bb4cbd33ed50ffbcfbb66a552fdb7dec0ab4cb17adf5f9b7b0382569bdf192d5039be964b124d9524b10a237bc3a75b294a69db0b8eabfdbccd9a4bc394eef725ed2789ec76b78a7e637287e8bfdce5c7f0d541c7358e29a52b9045e715bc156659f9d8464fa80ae90729280f9f75eb930ea5459274da4ef7244926a10e67d29a28bc30f9127dad02274925e959ce23d52c2a87ba35d7e551590e5e4220bad4876c90d37cb319197e7a4691a002b217b94035cd7c0c667b7b032d8988d16cac51ac3b3eb9798633277c369fdcfce29898a545339fb00b77cac0ec7238953e3a0ca9d16c4cb8fe4feeedc3a12f27e3b36f4f69e878a33059ba5407f90ccde8d4050c56dd736c6987d2d98efe9774aa7beefca410274b2dc1ea012df580966d03f291977071869e3cfcedf45d02b112417f13c6a7bc33e8d445d381bf99c7b5f701c60d74b2acf43cc4699027f4a72ae67f2257a4c21cedb5a481559dee98fe53857949ffa9aada0f0d62c189f7b0fbce30e96daf4c0f8f2484b8fa29fa6bb7f41b80a6e01a38f3a5cb62d68b8eed8d6c8cdfe652f005e3ca5fa951ac969ab3f6df48db8efd98444b1352371577fc5a6653b87b03fafea217bd1632827cb6d14906b7681cf0a914f994c0e512f994c968b5d45f69eafaddf9a190ac17e3418303babc7c7bfaf54f97af8e7eb8383d7d737ef9cd9bd3af0fde5c7e7b7afafde565923cfaba9773ddd85b71758fd6c5f221fd3323ec5ec9ac48d7d74c413adc132df7b44970612a4e4be15ddacd0a4dd78c03a40867189b2ca55bf267bd0fe9f9166f71999c9d70f4d7bf62c2d10b4dec495dfd14af0a16b934cbbc37458ac459dc16db7204564553e3aab5c6615063d25ae321a8316dadf126a8c15a6b2c821ab3d61ae7418debd61a67a55b3c477fd55219477d4c72ca7b1c094c328a38dadfd7cbf60f8cc98a72f4795f8b621cfd1d93897ec49a74a0cf35cb035f15984cf5577f7da1bffa1bd6c88da3bf7e8ec90dbc5f6272dba2b836e71ead7a190ec373a779b19c670f27f65ebd2d8acfc44a31b9f76d5e28211f624c16bfbfb51893874a2b1e5b68626cd875db0adc33540295e6c98d520d2ebba1ebb930996052d5bb3143ecb9a22de1bdcbbc780bb771d95b552fadc8fec6d6b15779f78c26e45070c5eeb550c47b2b3e874c703468180aaa06c2b08b21447940de6b540e8c6d71dad231d8f109dfdaa5937ae91481ab39ad4ef24c08f5162e0a6fea4ed6cb4cdda4f1f398ace41cfe2e33992d8a74bd257971749f4d942ea594327b89819e88c7f265bcb8bf61ec553e8569b4dddbe797d0ddaa559b8cf5936a997c6bf52dd65be37bfe319fcfdff3456be76e176c0fee11410b92f169f5a22ec76bf4322b081fcd9946f268d17b27c5adc6c3c45aa5d77657bd8a6859b88d26d5e103a479a8220bbd25697397504be59ede26e3255781b0b0d3ca8bed9634077f1b0c7e7293cfa792f1b005576664189bedad392df0a7525ba43b38748b8f0795470095eb5d671337320b576ff53167b301d2bf0ffecc1c047f6b6e10689685e8c118b4abcd3692d3d41a36ef6b2d9bc25ad3a0a97c22e4fa86ccfb7af3a6b46de83ba15a6f6edb06ead5bda2eb2db9a3fd5268be6f4fd8622f587d1eaac88cd66cbdc5c4a28c61350f433e43572336769cfc9553a92b3ad3b02a16cb7cce0233e5dd57fbec8b24818fa82277dd2ed6c3661a1ad64bc9947a005fb3202367785f8733c9c0a982eb3a9480049d5a54208286b705b8fbac5a8ffca1e0c56ac124dc47432a689b6d36164ae71a4a5d5a46dd8b43022bcaaa679314540c258c2295ce37c5e7b447596f82911a367265f3e13de244f50c82c6a9ad3ed1fdaeb78493b54312e93d2a3146f985a61f7e6d574354a099bb62a739eb6bb2b6c722b459e94fb6c441756b2287ca2c7a4ae0812f9961c4496dd833b2fec01e520839d862bcd9982e9448357ab7ea9d0f1a2a2f42a83c6f4d60ae410f35164e6d3655bf1d85b1a90ec44f6d3d6281ec13ba10eea0639afa919c867745089251de33fc2659d1f00a8c4cb357bd82f122d79c3b99946fe749e27ce2466397244be29ec99e10fa975b45748727491c77028d93b32a783958b9eb125bf6208ebbaac7f8b4abec50f50f3f30493f8cf878b341fa8f5e3330b9050753ba8329e8684c72ba96ec9add2fd319c288114114265ab44d85bf59e0c29e54c88891930b7d52f32de264cdf834cd891945ba227e14e9646b8c09a66d925109f2329953d163f76ce282dfe79515b8857b2020186d4ae75690ddd7bc2aa3947a57ae3c493acba1fe22359bcc1d7f63947db1fe5b0ce3e7715a783e67e9789facb93155bd211b990bc1c6743ae263c2b698acb778bbb5c70960f6f07712bf8a5c5d61eb42836f1dc537031d3e05a129bc56ed080d6ee9049ae35892cd4695bc8cf4af2b4877d85a9aba52bd33c3f31057d93738553d608f88a0357ca148c9143a1e4a6e315c9304df9215cd3c27430a9a956496cc6866d7ccad4e1531acb0c9e3b72a73bdafa8b18c3c8515145b22ccb887ab618b5a6d355c2181d3555a0c9bcd1544e074369ce91a00b8bb1b3040d6ce8579403b0dae5d30d4b837b9c9e481427d3c64fa287403edcaa537a6745815c3707a1a906410ecfd7ef9382e8e87aa4e90544090824f8ad555a1a44f588843f2fdeeb1ab22862cf594846114de4677d276f3a3bbf4d103729092fc00e1f5b6c9b0bef9ffd7992512ae1bdb7d6ec3fe0eed91f1feabac261554191f6ff19049a23fcf8b1fb2793e75e36518af3965d6ce111ef8cdc63dcda4580c24cd86e7489428a00645ee541b349e6db1c70ddb2dc6449a933417dc2f150f30842055cc23b7e6f47cecf09c957c647c97ab1ba36e407117b15019e12e84c4dd18c724f02c289d2a7b77325b2ed9d4f772c666443aac363520328a5b6ac565d6fa4f8487d2285b038b162cd65870a90fae6433cd7f01922965ac500da308effd581b3465e406611335ac7b5a15cc89a38febedfcba4b7fd2905ba35e5614f935df6c2a47d3ba2728babf2bd39ddd804aae3befd5009741e127e9ac3991e0143e9263ca47725cfae46e77dd49fba81a526e7f9f1af3eca36accb71f55639e84eac3fd36f521475f62b2a27d6bc85a07c9eb2701b29d1b9fb879256d974d51dd245f56ffeeb49cf0847c12eaf8f21214c07b708f9c4d7686e2ee4a1f2e2fb674bb4604c444771a5cd7e409d8cc9895adb1044c330da31a73665aca5a4c6ede88ebad4ed6f8c62bf61fb8d8a76a100a53f186c9de2a661fc359f707c24738c0ad0f9af6dad6dae050113e1263bcd97466888df4ef3151e66f60df75b32e17665635d083b702dcbfb1d9ec3f6794ee3f5729833004d5a16a6bcc5ceb3fffd9ac45ba4f0cc14af701956692a5fbc6e96f9f0065b027fce261c90aa8e41fab4ffaa5f5fcd513d38f604c6896c8fc964d4101f85a8a05d868da5fb9af16f97dcef50f4d2a6c5f01c02edd217b6475f51ab99b2176bb857ec26dd7b736a7b011066ee804c54b4d82dec258634c6e7d119bbed25d81735a1c10a1453d43acf1256be4ecd6c7d7a764972f5f0ce5de8b148ef38b41fe951ce4dd2e16a3bc9a3e361f0f800ff85074bbfe7abe6c10c85ae666354dbc032c27302659e998655ad8db83cb54ed5392a8de82a91b312dda6361984fc2276ab7a93f5460350cc8f06bd098bc0c26cfe1021c7db0fc3d2ac194c578b080ddb6fd2fc8c828e3880a84f2703cd7d5e4cd6da2361bdd8ce1bfcd46134fca0186460a9edd724ab332d4fedd6cfa44ba35a2fed766331a1309265c3cf0a5018ffd553f49ca726bf0b682fac75ca3a1517083df6c3a62743b76be7ae06594d176bf17000ab2a20f2827c2b12328a3eb2d1edd8e69a74fb26afea432cfc49664d5dc70b9f74606c4ea1bf5d6f58c327797bae97eb0e3d6765327c35bddc7a472b7a71e507948a9249931898ba108ca537b0f88dcdd89fe28b397ef5c51d9cb369b18c8534ceef4c9cd0bab7a65d318937b5d547cc89767802c634c8e4ca5d7424e727e6df465e1e1fe106a2a4b7db65ea1aa5e18acc14d9bf5c50d8b9af5a2793e637b9387c99c45707b4d94171117d15cf06b269d695a0f19b2abf62e2fa1ebcbcb0ea5a2f76e2559c90dc350cc7d50bed0ccc36c64fbbb0ea5e7cdd11edb81a808ae7465e0530c2c4f5b1b9a3bb35ec232baca0a362da75af462777944fb00e8f9e050733e2036c498c0035853e2d280505502a8ddbaf28bd0108db7e41a98aa16bd7d95cf826b973bb454865e61844b6f7cd3dde86a8cab8fc0618b8221732ac0637774a7cf19083b81bc7ed1926e52e3e06a875e682daf3a1f983c1be41e027cecc3112965c69cda381d5c95745c2047c5dd284950e5b9fe4923f1d066137fe597ef650cca71b894df785fcfa926ab80d1656f8af26e6c1707e1e602cf9304cdf59187a556a3bb3176c274a70f346d89949e5b1f1335ba1f6f36a214f6aae90026ac62a7c184d1cebe2773b6997d4c58924cca4d82ec02838005c56bb818da8cc1dd3514b8084dec7dfb95a068f9b0f6866fd9635a50232b1c7a442bb3fbcea5b9bc71cdfe9898ab974b390c36b5185d8da9c9cfe5e0bb2045000adbba36bdaabe303054bf157954b2e8e3e8584505630b9b7b2a8b24db333dc1a571b328b3be2c7ec735165032bfbe66924da3bb9b7c0e87dd984722648efc5e914f198e1662ca7cfee945f68145c54a0648af8832c922d31f9bc2bdcc91e0131605adf46c425b634e354e9b1d1bf26df40aa11ae9b0729d1b8a61969a225c4250c525f074df8ab9c1f0a2ad4aa6c4c2d5282123af056e89f166638f9e207eeb3f60db5e7ecba218aecbb0b5b78fb0a49f143d664fc77ec9985c6b966206c63c3f906b8c3a7d8c491e004b338cbefcd67f38c32ef066c41b1791da98b4a3f16663760054e778b874049de114050fa4c454fdd6b1940140214e83d8283dcf53ba5304f5fea03321c9253d1d968f760bf4cfbb4c4e2f259bc5b84d172b5c9533562e4158885b23c0adf6a9e7042cf2aeb5fb055b885dfdea77418ffaf1697d0daa0a534733582f2fdec215fbba458dd4ab475ebff3f4388dfe255670f2947cd0c7dc1272770bbd7c16091e65c19137b8612e59367d886eb2227a66fccb9ef9c30dec78d8c2159b0969cb751fee8b18937749c2fc8428a5ef9accc67f34de52bde1076e7572702170ae6e988c322ee0af674e848c9e9df90d7bd68b345be6dfba49eb79e4aca854853c440f62d533acd8656d5a9725736879959a8bb8535534a76fea43941644848959f4da03250483011fe6671c7b35e34780d8a10f2f5135beaba81631ca7a595d3b1966420021cc52499367daa79a6e9929b38a6343b4f572d575eaba425ec01a1fceb3a270eacf308cac78e77e3b67ef8027d0d848f3e56968c30e09c441a99e3cf8df573d692c1da52ad86a70d07adbae0167a509a01e3ce7ad00ce68b4de06a687f596e4358d19ccd1dc189757aeb7a1f9488e890aa4dd97b4bfd92031e25abee6a5325c68896e14bb31c5634c24adaa9bd11b4d9e6dd9199ba103a3d95e6f09c7b867537fedd6aebf6933ed85aecbbf047921e016ce8cacc81c7a2ccf4e984bd4d7a430148e49d61c73f53c59c84282309481764160fd07723e23d1936c46659b4a5f19bd8aa7f1c0269fa039c6645e43f59a7b1654918ccec9aa5d87a059f90295af82038404f6e1706d1f891da91da7a03586fb7557412a487f5e6b6c4e46587b2f817a431006f883cc1b0617aac8bc62ba6851e38001bbc5b0a3ff56c49dd6e03ddf553ce0540d6343adf6ee7275b3076c218abbb21be338b5afdcb357b76dc1f383cc4b083b6e3369567c10dad71662b7994120e193c2ad84f2a728b7a09046e74a135d1735ece4f5db2c9f6b6eb213bdf53c780e8cfcd29c11b8df0502bddca189f18083cbd6888d4174e1814eed6de5b6a2863a4f85d74b62c2697fc0bf6203deed62b868bd44987c3c6837339455fa63a7ba0bcb06f5652d57fa1748d9603616aef8d93e56f7182445a26cc69a3db8e7176fb76715708365f64b63747081d1b1357fa1b581f84804234629115db17247627b0b426fc7f51bf5467459b38da79be6e0b80464b7162a1a50aa6af6b7e0c4504602a51355bfdb5456f3a17ea4b1fb8fdacd561fb59b5d3d6e37b37bbb2a1898281edb95bd79ae587d7f35c288be15e243e134757e8be5273406fb9ca94833d72aba65b2d0fbf7450bf818ad6b67bfdce55539d9ac3cb3f392ef99ffefcbf704164cc7ca7aced5ef19eae3203d77f8fe309bcfafb2c9872a4bcc5a252fd6dd077e968cc6b862a3ac2b59646f0e2c2644c29129dd675f90a5cb945a6ecb0d0a7c1db5b43ea3055317f982899542b7649f7d11c646df6a1cebf44e66a6af32c57a5cdc213c58b6508ec061c171473c49d84bca21b3193f50a0ea33ea09c14b1d18f11f9810087f738c32f47809e9225ff693e40699692e2ad6e487c0e5c7094e15cfa4eb47e2f3ed07d3669cfe029355a00045eeb6f48c22ae37f375a9f3db6c261861cbbd597ed184bd8392d14dcf2cd0cceb261f34f2af08473d6b0f186608a76816acd1bcb246b02eb76dc11876a9d372b3ba53e2d63c65db2d9ae141d9d82d1154af78369d2281895be06b7245eea8afe6374dcfc7ce1162b84cbeaa3b5218267255b0a3d94c036543e4f3c90869b0c12c98d7b0ec6de1633c52540e75ed67b173fd32c8ab49dc1aec3fef6f49867019928df0ba39a99dabbc35a78fdcedd0b95e5386709995f58a326055ae2ca2bdf289134a50bcf2424f085b5ee0c9351b8dd6a5009076f6b5d84026edcc2509b274849cdd356a213d6096d31865527ae414153e6342380dc58f614d43d42add17d84bbbae1e2441619aa855e258e50e66fe0e98f976ce3d7f02e72e1de7ceebb30160be0b7c113a7de78c0019678d3742a76fdc113afd6d2568a1557a75aa022221527fb053db208df3f035a41509a20b88358e3aeb69298682638555bec469594eb2363d24585d57ed6f724f7eb224590deb0cfba9d76cbd12c0a2afe07e46d31d44ab5a0d90e6fa6f5854640b16a97ca1c5809fe32ec769b6d9acccfc42131dbfcde6f9d464f7f939ee8a6efc73246611e407fa39ee0603d76f348332cf8d21ef67b80de067123148fcc0a6d1cf6e5e3ff762bcbdef79c70c5a061e1db9cd3cda92fb2ac7eca618d702419f10025ae757ffdfd150fc5eb656f5b2a6a6a5d3c251ea5d9379c65534cbf2b9a684dbdfe35cf67126f9f0a311b0971f65a36f3f1a01bbf86814ed4dc88a7f1e28aec4237ecfdbc02253f7ad2192f2ee3e38ccba5dff4a0c38a4dfedd27dcccc36cbf1809970fbade19e6bda844606a18157302489b9d65da1f8798cc1db23d3f554bd74a5eb0a20b0fabd404043569b0d4480d877c38cca54968eea994d029081c7bb7366219dacea83163f071134ab5c6b54d06c94f96b89c7034ee31e44486c3671cfff82bfc6f6ce69e0cb36a37d32a5eefbc1f425ed0fa67b7ba6e925cd46d3f1c0b4b71ce62823539cda569743640ac8acdbc5a9666cddf3de1ede6a989f609f296186b39ebdfa18e906f0a033b1c3ca46fdf166a3ffd78ba3ffe2cd26a86db7e1866656567f5e6abd7992c4cfe30ea537ce377d6f5f8b16375d13de76b30dc5a380c777494386fe1772c4b49e48d9299b2da73fafb9db3412cc18b7c54753ca34429a5a231a4c822cb333b4cc83a10be10ed84aec91ac721b2055613c68cbb014642a2903d49cb265054950e90a95e166d2d85e4587523e6490a8310df16e55e509d1031ce3c6182b237419b003bb8166b82610e43e6893ba9e1008317bb4b68390fd4a2a8c69bbdb5a5868ec6c4abc11774c1e669a5ff5844455cb7192806a347e3efc535caa47dd307c5a13bcb55e8b6e50fe4d38b6e5cef9307fe0cb94207db2579dda4dc54dc9f9e86b46aa60999cdc80e2f42683784a0d13cfe3f0580d21842d4990e8d27808b157c16af2341e6a7e84c82489ff149b404ca8faa7186e092aabca34fe53dc95988850c835dc98e3c5062d2123286f4932c0609c84d3382652ff276849d5e33fc57800eb0f373c53e5565760a2caa73e1196fee4e1c7438f56a089dc24bd751fe5b526728cc31819629634b52b358ce39413bdb6a95d105d22b7e0fd6cd316a8b494897d7e541378b2de6ac6daef9946adfe0132dbe5760b87669bdc63b9eaf08929d4bbd7750f382d8b6392c3f60fcd069a875a13ba48ef69d7fcd49f9ba29884b9d8fc44723339d3bd9926c6e0cf13cc60ca2662cade9f1d07d30ac439eb2a1326317a7f760c4c1330d4ee013d7b673f8ee267ddb2a9eeb3389a88d57ceaee3237fd4d7bd1c54d5ec01ddcf907367f8826d9aa302af08c47b9e3a1999c30aef6189f8869ceaf7bcff4a12a0f06ca35d6a31c13312cfb1c1a325416d4d6d1cf3d0b1e48193a83f5cafa4a657950bad954a04093b77c5b7738f6f4cd570c63be808b31bbaf8bcd4f5d087baa8bf40f5da0a7a89f3fb0872499231305cd6c928cd0acfae0f5713ec653d191bf64b100a3d36259cd8aeb55122a541030cb7a31ab69d91a276db9b89019449e0a7e21d250ec36d29ca5b61dcabc64d7229a0d0db54e5913d7e46d017f7228c1c73515a8d387ff012b58074628dc926cb9647cfa06f2513099d6f115a79d7e354086ebc5ad58cf0325a737af837bb0ac684f34d7061868f7fd6c11dc510f5ed9c4a44f75032bd2167fec16030eaf1a708c24c58c083592a101478e07ead1db126ab3e4c65bdce8b868a735fbd35dcea7e26eb3e9981fbda998406fcd929ab3c2a0aee551c87e6001086e05f195eeac16c98ed45675095e00c0379b7570eb8f133e034b98515254132aacb7985cfbb8ad4918cea708a7d57e88a0082ed443cabde1d96d7e9d29217bab82c9836b3db5923cd96452d18b5e0c5c061ccfc6db2f7a7d2d88d45fbf1557f99c45e7d92c93b9a9d0a95438bc9162c1dadefc08832ba2773782b3587338d5892449acc11534f0715e5f4e92d38e99e7ee49967d5dc87ccab88a31c40443343038789eb19964c50d999761f9ab2459414cf03553ef0b260fcd4edbf42cb454b80fafd219b9a7703bee1b03e647e5ebfbe197e93df94059ef2a2b1860f2252a50f988711a079a898b0a2bb2de423eff0fec8100b7013852b8a9fa08eb3c40e85d61d16e5700b2752cd7074d26e814e5e403c6e416e5e6feb1c0cdb38c11cbd44d4f667c2a1608fb5499e8f32fb1634f5e902317c8fe80ea71c521a3f19e304cde3b19c34918e4b057c31fe87d399bf73da3bdc5950864bc6ec302e509717c01c0c2a3407028f3d3f3186f31b8151ca00b477d7025da18aff5ab3b846d9e89938a2decc0dad34fb02e27a7d62b7b7dd86ba1298891f8dde9bb982c6ab1b9c353b4b6aa6f53a192d0a9c99d06abc4e95920247c600f9a33f5268ebed37f9c054242594902fbda77f1217c4f0e34477b423b7d728c04880f06a11a7f20b30ee48c8edee856c683d0d9a5bcf6b07b53f1883a3676d76be144dbb761968e57fa2d20a8b75dca7092ec4356188759b3e9f4e89671e54004c54bb134aefae41293dca38966450df613f0ff8cc93b8c530d1f6f93c4b56c32b33fadf1d6bab5f6616abf39dfeef7746d803cf5d0debec36f882132df4a364b7f2190f1a5e97d22a91165ce119c23fb311eb4c39924f1bbf7e7df5601cd00aa87a15f34e1cf4d460dc8ac01f3868c991822143db645907d2587ac522ccdb6c65f4f6132c7350cd4bb916c465519aeb30a00af1c36402099d0332f51aebafb7830b1fc88797d4627243c16301fbf6a726b19a4f611c0957ec4a6cdf92396f3ece8dd9b83c3a3dfb7a2763c9fbaa8ee4a48859fb4b046325d25093a1badc6d42e67b0947e2e1f5fcdb26bb3a2d7223d26d7e2eb6cf22164f58ed1de3ebcb54ea4d577fad5d55c849f34991acfc1d0c39e67e683a412bf6d36e815dac7e437dae9573856572149903e7de4951e0c260a69fed4a4706b41a187bd2a4f1d7405dd041d4083a63d6f567b0fa7fd88ae3512b8caf875ba06418e6951316d52a8b8d3a255ea3c8fbb70bf313192e3d3bfade89834175eccb3e2a63a86b0d1624b9a358a6a8ded8ec0b38ad6c3292ec092c5d25227147a3e5e7859aded7492c71b8de3d44d4f731baabb5f0d42c1eb5d40fa01b57587bbf19fe07a34dfc8e127f2d4758e9a53f41426f3752ed94cdcc798c0ed25bc9583cc4b16510caf52933a4ac3d4c5c392f9e45194d26c18c30ec66946e61f6123c98c1e8d5663b2a0b35eb9dfe48ece7ae58e878650bf5de822b8786f0e2b33458ccc815564ff09afa73e91d7d33d5cea63fcce08fabe9f93cab5d817488b8d0bc44d38bd1648f13992018614f41e2c1d652fe0ab710936174110a319fe3dda0b7f8b4d3e43ef28a5379a5fb24566eca446282ef1e527f088f91fc923fed29b67853ab6a07983146e6713ebf5187e9c53bc6c728a485876f10036e90d5da0033c38e850fa2649ced11bd3c419ecce2f747483ce70c04702afa83e91577c120778e219c0a7f274273b593af5384b7716b274cd9df1da855f574c3e9cb339f8d6a2589fe11883ced987ef2509b8451c2825f3ab956228be816823d8b61d080f130e386f81e6c089e3ed2eae92031b645527f6cfc7d921eeb8cb7c372f0469d6f5019d774d4cf905c27048d7ef68f5eaacc614f421635b241dacd5613218a066b77ef12448682632f7e9de7fa1f9230c24772ccf29c21fe316ffe365f29cd69357ca2e539220bd4e1aa395cb90b72e416988f86524c6547d84d5e3dbffc3cad559b990965572f88106649173647e6426cf2969a8249acc845d00e6ee616c107e634f829b5c8f4ceefc2a2f308a9fc763e0077c3d3802559ea00fdc800a744e93f2f57cf8653a2745955ccfeae4fa4e93eb3b47aeef5c267f87e18a06d90e144e774d15cdf4d3f44713836397f414ad489fe4a5bd912c68de5b64cb56ad6f701e5b2c7a53845350736c3653641cc7aee94d457beb9389a33b73aeba8cf4497df67a18b25c93911a0f8a9d02b72601b504686c38db45b425816e53a58937f2594cef3c8d593c4e6316a3e5d836b124767ce922243cd71fd3254c116cbc4763bba706a8b399dccdafa25bc37dc20308b278190f9c06e4a51a72f06399808dc42db22212a7bc3446ec16fadd9af9097b6cf67151ffc9b3f538b3be9949824a50b0531e53190eb855b4c60edf5eb5e0dbab47f0ed15e0db49c6bf112d68cf03ae6716e0a619f5551d8adb5076436fea3037292a38bb15ed7ad7d206de2db1ea5d8b8f9973c57ad1d702d17a9efdf67074af189fb65c79c9d1fedf7639e91383548eed2d202d5fcb5eb58a6d48b6b4f2c8d7ad5f41ca9422e568ff73bc1d88de37325bded0b50da14839faeb97985cebc294a3175f60523069aeeb6e19e87a2eb2e96b2916df9d9f9ee86fff86891632d98570257f0703a5ded16c9eab075df40f4cc49299ebd1f448befc2b26d7ac6d2a6bb813b160139572f4f90b4cfcf39929fbf24bddfc1dbbba9eebe1bec0e6f7315faed4919be9e79febf6f9ced5e6e8cbbfe12d818fd2b55e76fdeb6dc6b36b2675b37f0d9b2dcb3fff3bde92f72a9f17e97a2ab36b3e9562a9eb7f89c92ce72e51e43b618ea7fee26f98a87c61befe0786845ff98271bbf45ff471b93f5ffe036fc99bec41e8418179e7552ec1f554d7dcc704628e32ae97e1ef2ff096fc90b3bb747dc1eed54a325de70b3bec0335cf748b5ff8792cb26b76a2056929ae65b6d02d7c6edfbdc9f987b2f88b2f6d71b5f6177f2b6b43577fb7cfe7bfae32d3f93fc2be74076e340070f9440fe8ef7fc5e4120af52aa6eb65260b7628e602565daf6e717b1dd4ff6b1f5b875a58c17ff431991485af107abfd79d48837a515e4453b6946c922936f511faab824590d5c287138959749bdf66701822f455d4effd0d47395c8b1371c6a651ae623346bd3aafb309dc91f0d828aa55ffe8814cc462b1e2fa90fd3fecfded76db38b62e0affefab90d9bd548004d392ec7c4946b453a954afec95a4f226a95e5d4351a7691292b042016a12b4adb27401efcf7305e716cf259c8109800429ca71baf7da679c31ce1f5bc4f7372680399fe7de9670a1eec9beca0d326be4453a32ebfc7da5d4261f9f9d2db95a1557612cd76791b88ebe466702a28679ba89fede59cba4001bbc3db173f6e21ceb36d35dfc0c931f337993b3ecb558483d291e03d727bbddc84ce5541e2ec295a740c3c13946ff12d2e4e29bcac05b5f097764ece11e813d1c1a008a64281037f433cf30492b529a736c58689e18169aa7982c8e43ef965665e45f857fb3366cca52c1d83d80191c381f03ce91c3d86bc11a2f8db218d544ed9b56620fc3fb75cafd0786db5918933a9d88bb96bc8fad636fa06ca33a946d74006e9cb432ee1e5373c163b6279bf628875279d93e3146cc3c77d8370f9d4c1bf14c87edc9358d6a06f3935264b9ee76d1355d99c1b5a6d77524f6127b2fe442b0cc20ea327763cb40875b8a97298fbf96eafde6de979159e0e2042470310212d8f0c15c0f57eee87d73ea23e8deed09277736641dd9c630d4c2cd5609dce418683719ec5b16ea12e981c3c2120a13fc58b2db01286778552825c56e5774bbc1979ca58be084d2a26e6669755d4f100bd74c45ffa10f432c8c52657fc52a4bed4fd07ffe0fb6853bbcdd0eb59426438099531915656c415727d0096ab713e470a0ea0523c76ef26f8ff74f05bd2eabb3ab98aec7827030c631dc1785e1e658f83dba3de8b832b1800436664002250352f5696584d136bdd8c3a83cf226f2bd9b8619dda00415a422e6c1b5df31cda622acce6928832bfb7573146dc9dd4a1fe362e2466013a449d1463e13c4a7e573883d5161f376e76a0c7d365d43ffa9dd6e315e97ad49172dbd28c9daa2ae90e591197a7574865e75bbe88a2ef1e4ea48dfcf8228e3d1a935c90be6f511106ca2250bec3030905780d9f22e5ad79e46f83430bec198c3f8305f1fd5366564a5475819eb9a324bd9b10648a3171092dc508f73e91614971d11c62b5029012a8faff05327fac98cc58ffe587c7930166b752341a306a50b94332041ecf94019f598b5250c48e0ca1790a02c5d606e3f20686e93f9ef1feb377ad1f0948ef478ff44042630ba3db5d35f68dcedc6e5fbdc199a85fdde94feed64fca7bb3dc2b3cff3ddd9e7cf737cb624c1e7cf7f1a061880b67ca8308ff7c1a0bbff42a06dc6d71e4dc8ade30e7965a1dbc97b7a7282d6d335fa42041e7fc1e41d7d3f7d986ee277814b949a94f7694bee31b616259d00efd18a1478bc222fe8fb6963ca7f25777bb2c0e3afe44d7d35a80fa5f1fb6e575afead72d08cdf111801e31744c931df939715adf709a557d3376ece7f1cbfa9e6fcc79639bf256f1cd212a94fdb4a76f4eb79d2b8166ab34183b3245f6c3b71249c3de2224a734779d9897203469a77f2c272414f2aa8805900037fc133d887178b606e7bc63dc54cfa7d8101afb48e048074a7b5e09a7c34b9b8f25c592c54bee02c219d9c8b18204c7c4cb2122deb87a0af53ed073f04b0673a82aa832b9a369e747b3097de954aa55fdc66657a58f6d8a20ce80348694e69911b7cc82e6b7ae00d54bedb21e34267f39211f7ce2538ce48ac6ec7728f09db13b958d4ca5837af2f5987da59e20d4cad6efb63d53226e21d281ebcc454b8e7da8d703a98f04b59f52fc772c6e7a12bac799594ee4291936139e2d99ee8a1e295de5e3e1193b601e1a8acb39b8bc0f3213c771a33a94a4c3739192bad320a19e26aa4b694d9c216eba24fa2b2f0f6581185b1ba2599074c01a61b653d4229a80aa5202c948b85feb9581016eaca818a76c608fb9631a7abf8e1e9a2ec4bf3ba6be9b4eda362b7ebde29ab5f6194a6ddaed3928e94bcc298647bc20fa94a2a606bff15db1f406ca6e64e1238f2246a9e0e6d76fffee9ed9bd73f67d1da2d54ddaef06d378e05c35af01686025b69a9d6e5b5625152295f1b7acebdc1772ffb63a6e6fb3de811cce60d13bf6a753a1ddac5a8b46f1406ab3f9a897908aac67a5dc974a5f19da2627295b1e86ba987ef83a8344c4e012f7c36b76756e6730194d8dc720e6f405751cea67c3698f7cdefb1fead4fd0b374bedb0d484e83c01d5f53a2f722f715e3890e44e3fed0d26d1786eaf52ecef3319f0de764cd121e8df96c3427b92cb298bd8d36633e3b9fefcdfbe3628aa2d962aef718963111b3bcdf27e05200804686128cc7915d6faa2619e7c40618af51421426550ae3e11e13c381872aab85ccc768397c536f1c428c5404680561e41ed173c05df7c762160a2962e6f0d7442862d06fb0ee5482a1e943a00e5498fbcff58c00699a969fdb4ed1211739cb14763f6a3a7e11e5c879ec76811eae16eb273adc135eca224dc40faab3e022e9441da878c71c51ad41d2269357d155baedac59242c1eaf5ab10e589f02d6a4fefac164f8430788ce986299de66acd55218c0ad015cfb0319903e5d94c318cc84c982a25c0fd9b66b814e6e681a732730d935c709489f45807d84c1a481a1672cdeb21086e334f81ff0bf530e6beb4182ce5d35bab330ce7312ec033c869f06d51cdae7e38a31ddf8d5870ef089dd2aba0088bcaa33787388e950ef64c20c178a4590d00ef9249aa979b7cbac86896927ed86895b20a6ae5f7f041453c409f88f59ad6db9cf33b069bca240adf4503555e65484e5cc049dd329ab0fc500020644ea6c4cd10e3c41e7f94ac9488ffd3e0d3e8bb3de1f3b65ba1b2e96bf7e784393484563402c358780b3ffcaa598e845e7f105297b43a7830ac1f238da306414d17efdf0babc7142fff3e32fef427351c4175bc431d6d3a4d33b0bb03e337fab8b32d33b60fb0d7b62aea0dd26b8def4be1f9ed49bf858a7664ee97d6554b9ae7d35a4750d15904883c89f73b14c9992c2adccd7fdfe44d0d56e875634464a6f95343148e6e6f68b70000c9787ae03ec6ce8754492d14d2d04984e7b5b6e530277bc35e126d227065da3ca2edc77adb713de235121c764faf8d3d8bced5fdd05462535b7541e098fc0017e015c811b33c628c37d390db90c31aa4a1b37bcdfb71d2d742323a5cf2c777b5cb5ef6e175c9965c3b335f7bdfdcea0126177704d11a30cd013146e03f8d30b830d10ccecb90464c07950c2e67be2a0d3687066fbd5be6d0cda840f0d62d7af028135fa249a497fb33c3ddd5722a41102484c0793b84a247689e490483cc713d00199e57e42dd2e0217b7ebea25c70ac820a9ee05e5fbfdb744c6f6735ec3e6b2a3ca1668912de112baaebe51defbb4df050de7bb1d585bb3d9b991d0b392d6136658b7dbb285ea45c6352e8a68460afabdeb4e04eb4e4a8307ae73f12aca72a668a116a74f0f56bd0293402f9a3559cb2c699c667626349bc6b3bf2fd75b5d006f67338e1fa4d4b240b5bb319b7a05e6aa654eebc9cb603339afedb1d786b485a45e24cfdb5069bbae9c8de6877bad76ad6fb4c26cb2a2baef08f09ea8d0b7af377bf9e1eb00a81fcc66b0be311204f3b9d37b33925a86eb472c185e766670373322203598f1f96c309f18535dbd91c95934a77a497549147430292a61ba70f1535a31efb25931c7137dc09ca5b3c17cbedb21d1eda254b785fee309d3820400a954b5840e80c7104cc04b8f166153309855c7f422267f38eb9dfca1d3792937db8c2f57aa8362dc190d864f3aff93259dff8c542e45f8874ee70d8f99c859d22900c149cb6c6f5f7f72ce1df4f6f5274c3a39637fe874564a6dc66767ffc5921b13df3e367279063747225ab3fc0fbdb3136f021f1c1ef529a471abe243e9f8b7697a69a5837b711db33aae23f4addd30ddd500a089944384f2dd2e10c5fa8a65f08599531532d70607382719ee76b31a764d44a5e393d2032cc39308c0c1753291dd856a08269497e3ade870d1c9b030ab7c460a9dfaac9897091415022cf3eef9ca35748aa47bc9a1d27f9bc5e30a97a1edf14fee9dfe0b99cdb17999719133bc6f3edcb65dcf39e81833c294de1a1d99b3801a5a384d304f6a5c9c65d8adab4d3a3463e7e4105d66d97c7222773bb713cfb2f909a57caa1cece6d86fd76e174059a88fcde21d211e7297615e8ee194a607810aa17b1b40e5c6b4fffed44ebc6632d76f95b5787951f5e5cb87572f5e7efaf2d3abbf7cfae597371fbffcf9cd2f3fbe78f3e5df7ff9e53fbe7c69dd93ee8f12c62b167ffde9e52b7c6718681e181cf9d8158e7d81c1e98fe13ddc52d4dff69f1c0c90b2bede7e5e4d2d8f44b7af4f963f458af968ee25beebe8f1d38bf347178f1e7591a217a36717cf1e3f193d7bd445e7838bd1a367178f1e3ffb1b52b4e179e8727e7ef168f064f46430d0c1557f341c3d79361c8d86177da42e2f8723dcad82e3bfa9e7cf9f0f9f61dc3f7f72f1e4f1f0fcd939047b540bd53f7ff468f0f8fcd170f8f86feaf25207bf183d1a3e7b76fee4d913087fde92ea638cf199abd6632702df0976abda34df40b375914a992181708fe13dd1417f92c555ca5a15a4740755bd736755cfc4514d364f7d51ed7602e123dc0e59a8336eb9222e7225d71f20f54e229901ea064edceacaf8c5fbd7e38e8e8f70c56dc1f3ce9ae75a7e2e2db3eeec4dc7f84094239270b8fc14b4820a9a88e783c9e9a9c0929ae221d11fea1503aeaaf41f80c2238096c689165326ac029d426c3698e33dc957c562911ebe7a124124e4a9fc3c15e4a9b07079aa3e1cadaa9c004e11aef7e4c4bb6edd372709546cd232ee41a6dd23033323a8d8ed7483ffec82055ea800fbb8a1072858ee861539b4066fbba0e2be59eb6e43ea1ca1d9a4df9798cd54dfb46d5f7aaca7d9fdb12a8abfbe9c4f6a6910f34f9f18da4f0476789895d769b7d59f0c4c762cac8541b07f204158f897571f3ebdfaeb978ffffee2a7571f3089a8421961e1cf1f5efcf9edab779f9c87b9b489948ae2d5c75594b00c49c2f58ad7708be0b5bdd2c143129313664909b4c37b77ad85f466fce6f5bbfff8f2f1d38b4fbf7eb4db5d4121b449f0b558c8377289249e9829e6aebe539681a85feccbcd9a30d065051964dcdc77f802c188ec89e7ac269a18dda49f5319a9f3917d75b4017aa237aac0d1c29c29004ba9de0a482c375b88f33ecad45890fc26da54df195932f5c6bed3e635401bffa87ab7270da6596f58083d65237a0a707241045b3820e8055fccefe11c2a67204622d376e65ac9e58c14e1b8e505cef607ac4ee207d55945d7254079d2292f6bc79da0cff1249b71ab503ec2731a81cc66b66cc043026cbfe08bf93d9cdf7b3fba2c32d69185ea6c65a1e51fc5840a3b2fd2b45308be90d93ab794839d5c4599855cffa1f8f2436793b105bf2520ed57b7c93640f4e507733d6b6f5f5c6bfc6a12fdd79ac396ec48635477e38e4d77cc3c735ee50981e554b43346d8a995c3e7473864a28c283d8d62b9def0d485ccdc4432dfd53cd2f3f5e52f6fdfbf7ef3aa3e9564db54ca5aa792c44456b5d8efc93d7a8bfe0a141482ffa3606fb8f8fa3a09b8301738777bdceda23a439555aa349ad99d8fba67b9587616995c977aa2837078d1f9bb9fe4df1b4a9e9fc5af39ebfc7d5da48a43527fefc88dd93745ae58947c160109e0cf3ba907af5ab18ce944a234971d635aa8656e7b22e85cb15574cd6536eefcac4b22e44d47de880e8be2550732f82c78ded155e186c3cebcf31a7aa6aa189dab6d992482c82c5942bea636380c748f5611280bfd7ae28907a15285d2c7723f5265dad522f6d69e81a72d8fc263c0b199cd49ac179d9c0e888105f5de55a6efc62fc8a6568669bb1981bd2593343e3c9dc0fdf76e67b8faf09ddced50ac0f1d03f7261efc8fa0dfe9f7b5e30492ea73a2fabc3c88e8795994fbe6fe6039f78b30698f4356baa6d7f417b2a6bf902dfd852ce92fe48ade45093c138c5f91284974ebd753cff0ddd641d1d3afa091a7457fc2e957a4e0436152d08d0d3c11ee144a222449810933507911e2a4280b778d0a1244491260b2447adb22e6e617f2ff683fa0589ff4ae01bfbeba5ff94b5908d522d7e67bd862b8f87a3488288d505cc8165396afde9bb79a2ad8bf73d0e4d9132b7b428912f7a51362a6199b774b55c3c128e876a549aef5a4562a3164d3663a755989b5ec8d5a923578f97a11799d1873ea0ca9190f957c9dccf542efb05af77b640b421811f8a0d80fcb0e18a1aadca626a3b17383db14a466d17d59effd463cec0c921da1cc61d808dd039295084e130552a4c20c8999d252fb155b72614813c65bc244627f2f01b4bf663db2459824f54bd04f88853c31ea8648cfa1288752bed4bfaa4169dcbc978aab9a95a7b98bba0aa598e83f2d92fc55e895936ee91772159665a54bfa9e5cd31bb2a6b7041260c4c1cc5df9b640fac87d556db337465c5fd9476edde26346cc920f5cf76a8f6bc86e7e68a12b773cf42b3d4e1afa13ed48df294f3a3ab14ef5c81ee0895b52b2da5ccba6280b934845549035ca4850580e6a3c464630e5902fc9fb7d130096104cd48ccd69064b89f71effd53b2203af53e9f3a9422a7433f3c4832aae4a27cc40b5d782f6cb2241d40f2ffe0cf988b299ace85d4acd223627f9e92959234102b3c4d9f5ef64d0c014316a6b6581ccb224a1f2f0f67039a8959678768c43af65ed3c34ab3583c959e358336966a65a1883c19efdf21324bc0ccb6b61794bd86bc4eea9ddcb3a8359d9fad96e77e2cae1966ad7ca4699c595cbd3afb38babf5b18a54b25a90985e6d75a581bdbd3c1979e9fbb6d6f8ce37a3c6778b3e1dd691d7e06a74714a87b8db5d39ddac41b78bae40f7090566ba24015961e202501fc3dd91981e5dcfcca0f4353b9403a4f4ce4319a816223513b36c3ef796d632a317e508bf77f9148667cda5e627b5af58a31a58f50edbdf35a9398d955033a5229ec7935722ca97fa915ec702623db6fa79b4a23de888128ae700051f1e5c784299e14aaee6a5f98645c453648adc8d34049cdaff0e9b616cbfe94c798b44253c99dcecb0b239c2b0525e6e82b83265070a54e57d7c69758efbc1fff57ffe1fffff4ed0579e63cb7df3b18768f712e2eec4aeb8487ecaa2e5bb9f32b9f1b7f3126b1a80bfdcc3546865a95f5f9b2d6ec26986a256ad20194a01e7133ddfed4f543a1e8da20b6362e85fc839dd9385dcb81ce40639274cc44c97704e391cb211a7d6c1200c670cccdcf4de6d9659e7bbf746f0e871cbddfb3dafca4418764c1293dc1e0a0664434f86644507351e2423218b6e57ffbebb1dabd305d98eb3d3648fc9822aa2470359d7726061aee4461f0fa2251cc1a7072e001810472266e98fc5d555cae8c9604fb68d64ea6631865eb66e28b36fb792586b01fe64b82757f514f559d51e83211d58cb5918a79c09f5d7f2d76f784f6e5aad2f0e12d84c91cd0c8f011cc71a0b75bbe63d94faa177bb8117648a16b4ca3b297fff4672caacb113980b65b155af230aae6b7537e84e48405d4f0a14ac65919b0d895cd5dc8a4d406e31591bde8a26daae1439687ec2b50b895bfc932c5a1adf7be3d225c9fdd074090d6244a73db9fd462f64a15c2c5a6a513ada6adc5f86b4518698d80533d2873386f7e4156da8d7b4ccd4c2a9c0f825c4074351b55890856694008597c330d25bc2e1f96b00faabf675e7a03d70b88996ecafc0ad1c2dd96f536480fe97ecaf80f20f8e788ccac103f66576e4822053faf49b4d7625936d98c7994cd3376ca10efcdd0f3be2bca090b5cde5be643fc9cd0353fda417bf992262be37e4145c0fd388dedd8eb3d9607e2a6783b95e6b6643fd7b38df4f0455e1cd8ab1f42796aa68ea7f9c9d3f1e8c55983015f1f4ecf4192900483cd25bced75abf9f14ddae9a0637ecea2b873752195e199bde296bc1b4820108f904e4150cebb6503ffdf2f6ad0ef8116ae64216ddee89ea76d191cc5a11b1daf26b0dd89a252605557bf2a9d548b41a31a7cafdc2bd56d77ee9fa5be9fa9b17d677dd938fb4a1d635b4d41a45bc2a6131f0ddbab2dd283d6783f9040043ca95d04bd8290a8c5a933312c227e4a745aa8fe1dc0896e27235cde8e9702c9eaf40ef7e8889167d32bd8efa71cb126cdb9c7fdb63b282731bc3640b4fc0e465addeb07fda650ba29bb5ec23ae39329104e465ddcdec84e0dc5cb37e7950d31e28d7e9fdbf2c29590065a4db68c43fb3d16c763bb4a12703bbbb1cd44f1c564f1cd40ee851fcb6c593b6aeed765155f6d5bd3d5ca94f1e9dbb89bc1101b981b7ab83109014ec1701f905933b2bf4b53d422b2b19ef8911f4dac2082f8c16eedac2447e1898bb6da1f4c1d106b312a07f9573dfdae1d5b73550a3ca0fdd7cffd581fdd5aa887852ebf9858127387f6cf009ceefd7a0285ff60e6cce2cad76cb760e673eab030ba7af32f9ac61967342693645f0729d818dfc4cccf7c7f464ad71d6f76bad6618df73af62d39ec939ae9b68717d8c65d69f378f51f78afa7438b8185e9c9f3faa6b79558a804c9f4c2f601a96d38f5586e0e80ccdfef6476334faa7e19f8601c6e499171a2b0a3028af85421e4e2e193eb6dafc7c819e9cf8e15799bcf90150532ad5082e3a2b76abebbb8eec0be02663314bb85876823f0661e755b80c3b7f1c0c168bc120ecfc592a634731eefcd06793e365b8bc7cba1b3d7a045bc9a1ea8d9196aabbf07bcfa71189dc131d15e8e963770f55ba7e62eb4d1a29f07d6a86f6d3677a6807562ff0e6e626bc390f65b63c1b3e7bf6ecec569fca3d1682c83ffab61cda286bef442c0e64f79a5dcebb8fa8a508a3c16070965f2f03c22ad53e16e67cbd49597ebdacecf5cab785d24fef04022c7ce842ff00157f9a13738348132242c56e15dd10114a4153fd6fb1a03111709960de3d6941443b8f9bd19ccbf4c426e679026c831bf70e1e399a3c5cdb053141fc68f141b4b625b22d665e4da8c8bbd1150de31ca26ab465dedd88dee89a5a9a534b704301a8cd331e79f71159d55c85c7a2693d52fa6222b4f7b22d660d23d0db7d0e8bd0cc99930006e618a04f8fe5520f855bd9cdaaa595e97cf48878698c022933897a4ec612b3c6285ddd9355aac48dabc3940e26e96551ada2a9e9a69816b3744e72aa66f17c12c044a394c653334251ae73d7e317c5a4327613df528844cd59d9d08e847dec11e0ec00ac4e01ee11a8bbb7283b2e537915a59f563c9f563fc76d21cdfcb6d0bb63af5dd9d8a7ee8e5b0c076ab6cf603207d7825abaac991c83ad648b697d358695ced1a0ebb1b6c747b627b9ef01778b8c0ad2c629e425aba5718f48283fd42ff5c15688a70d17919c065fbe98b09679dfaa649c067d84d259a4fd4de37e312ff05f78f2e54b30a7da73bedb0d707f88fbc1972fc151c4a35217ce472b6ac5ca7320456ccd9562198d1d3491e19cd4eb83451ae06184f54a53bdc4943243a583b464c68ccab6c281d96f758770b7c7b37c0e0af92e73c2f624abe05efe93a7e90716337e0d64d079f360e1c118415961cf36a52e9f339a6100d6077e4d10e234c3460f47e2a91e9c7cb71b9e714a8767d1989f50deed462734c25341076324da541ad454191ecae1e0c9f9938be1d3d139d12921b1a303dcedfad5330a5ab61cc2e2797212e94a1f05786ac36a22628f321fa76961fc6ca31b8e6484846be3228c4223f7853cff60358688c04d4427d53282bc1e53f78f20c3b27767841cd0eb31dcf0803726dd536a5dc96c7042111aec58e848f87fe42ac75d810dc4bab24c182d69ea541b2353dd3b321f36acdc61df2fcf04fac077a19654755af5fa58d5c6ee4f3c792b0b519b00908c9debb37c6e0747e5a00fa0262bdb58a63ecc1fc40f2a17f3cb7538a77e15ebef2fda62d1289b4ed6f5c7b1715b25306d26b8640a6153b863631fd56a5e12b0d76d39189eb2d9603e66d8940f46a15d054cf31d4e17f70aeccae3268c3c9c30446272f73e93d73c61d978411c1cce38d9efc1b0207f10bb78f9703778843de3b94da5901fc2798072cfc589ee6d37639d02997737a27c3cbf50c9af4ce49fa4533aa6458be707b67c75bba189c3ea67371de3846601fafcf9f3e710072440b3cf9fcfc2399ea2e9184dc79f3f8fd1e7cf377d0cbf11827f9f3f87bbd9dff47f84e7b88f3f7fc678babbd71bcdfabde91c4f77e8f3e71ec681332bdb059804cbc07bd86cd26b1ba0034e0724a20352d020d0d252b7abc284a57ccd15cb0c79ac915191a03264b72c069202d3070b2a66833949a8980de76443857911d5425cd1a78eac24221b2d106dfa0b87f993e0a24f93d9705ed97baf289b4573724dc56c34276b2a66e773b2a5627631274b2a668fe6e48a8ad9e339b9a162f6643e29002ec0e9621525adf72d35e5bd764f30ab6e1750b8c82b1af4b50c78b5db053df841be5a0a5ccfe9139460b7cbc947badded9693cc698c446b365eef76bcdf274631757c0d169465738d3f11a39c18a5e3af24631b16a9f12bb28932c5a3747c4ba25cb18ce75fc72727376413e95d4c8c3f4e63f4118f6fa641d80bc6c1ec6f413f459f703f98f7a7c1be32768a2ebd03ba695e73d08d302645b75b3546567b17aea43367998918ae4ef7b3cf67d33fcecf96a4cd3af2df82bee1c1792913065c38d563eef0b1fef875b37124c97b9fc8ad68226b78284fee26a00d65e340779fcde4bcdb456226e7fed40afe86a6e3a0af7d43db92fd00ff29200ba4303e3437d64bcf5d65d31804a43086ce24a5481a8be74dc694da4ea3f1a10dabb50e662dd6c14c1f30bc637929b2e77692908416b33cd4e3675ee92b272074e5a11b31f80e162d3d52ba5dc4fb54afd47a94e1895e57b928d8be5240d26bac25cb7de5ee50821ffa2697fe0f81555bb5c7881f004e03304140b1210fcde0c4df97a090aa632292ce55a17fc3b69f74fefe43bf61e39be07ef077a39ead4f724979695fafb3abd9e4fb0b72c53a6cbd51db1f2a3bd30d1d4c36972eafc946f7115fa0054d5132dbcc313911b3781e2a962bb4c0dfa87c94a607f91a7b1e707563ee87e09b6db1706dd1a7d0189ba9ebda715eadb5b8bfd8975af60b9a876eb19856f336f1e7edffba593b4e51f27d8df3cf344cf0437fd1ff21f8011ac2b580ab7447bbb9958eef6b173d9e7ac97dd0769f1bd8760ddc9ab634e8c9f84f9fcff466da162d6fe8b67c65db9c2ad24e4cdfb1344616236f1a04e380070d3e7aa0ba00ad6224c0ce8ce8633af654ed10d83901fc820141e414f88945c8444222b36eb55b53c794cd8a79eb05618ca33e4d51ece1ab24fadbad30644303584e636f2d0d26f6a220c624b60b46b78b367d1b36e96ffa01ee0598447dbaa17139aba7b15bc8a6493f4001849b066317cd3969b7ea2b70f81f29120d0904032aad11264e9dda993e6a962cab72b7431145d7d3a822cd2f038e23dc3779aff47ffa279d33949a4f833f0563d9ed5e437fa1298530bb3fe180e4a8b6db04fd882ccc7d246e01892935630f3a97d81e2535e27393eeb44de5c9a1778430a9d0d96784a6279fa7f86ce9d9111f41bd50beac923931052e042b29053e4b41e564e82495936129aa9c0c3d5965588a2aa05158a1d242a9f7f0779ce9a343534eaf4ada0ea96545960d025d6b1dc5d6ddcbc3ef05e8c4ac9270f5b0a97ac5e67a603ce0ce27c82ad76a4717f8412f29c45292134e225258ec02a33a4512b2212b724dd6644b96e48adcd0bbdbf1806cc703c051d85294d2ec54e15ed4473965a702f78a3e4aa8e8a953d6cbb0b9de58d3b427fb798ff713dced6aa76db7bb7e4e07946e9fd38b9ac6285fa06b8a625a9c72dc137db4a0f234c2bdac8f3634eaf153d92b6caa2b1af7587fd153fd8d4df5badb5d41aad7cfe9a0992a687f2e69da5b9cc6bd1cd7bcedefe5e5607aba3c1b8d97672332205734ef6d4e17bd84dc84b7145d5d0ea657a783f1557fa017d42b1af792d3b4b72137e1f6c0f73ec28af30b7c0413055e289a9409e543c581cfa4b46035cfea5c0fc448ff29f49fd418c7cce6c42068d1d97c72d2bcbf48aa1ed5471c9dcc920ec915ad8cb6ebca625b1493d986b039264978ebeb7885db4a87a6a61685ef0e9f616fda9e616b4a4cf84e188baf1f6521122e962f21e90f2c5608ef274769da3296f3df59405e61f20ab5bf8b7be568b2d09c487cb7ecf7ffed09a5836e17e91496b4e443cfe8c97052abf6a95ea116aa5efb53112ab92148d195964abbdd0dbc82a04db7bb451101696d437572d96eb7451c5c0cd82c05739b8db1ba41364019c5a06166dd2ef027eef13dd5330fe50737fa12f6dc89aed7c3eb21e94c574477fa6c309f224eb7a820b24541efa64d414f7d4337ef7ecdb735d950391bccf1d88e4f6eab7f5fed75ce87af194456c3fac1dd688dbca00122cab5883b41199df1dd6e635ba4a2813e520745b6489e5e5d5e0c06dd6e345d8c739261724525d9a29464d8d408ce9808c6bc63c7f820a572905309bd83babd12ca677f61f8ae4d41bcdbe5ee25a4bcc3da1348e00d8baed90312888e25f093bc110f885f1c8bffebe601b1d363b1dfca07953e6e891f1fe0e8b7c7cd5be22657e9210c7f7bf4c5b1a2bf8c364007e32721292bb560deb606d2614038f1d4819a7b014d48323994dcf48e02a23bff9d5536bb1bcb81030f1cdaabbaf9be3d9597aadb55975978db97dd6e166e4fe5a5e876c565166efbcefcc237565821ff1c6135d35f28b35cbf97395264e34995d7ff8a167599cabacedf060ad1a5e7d6c75ea84c155805a86a2c16d84ccced3b85e57f53be09c53d5bf8a3439b8a0ad6b6b924b19a54cd1bc1dbdee821468b8c50b7d9b203cea5545a1f7a2fa3121e41f9be05dfa7f67ae3c389483116104d10dd25e3e6b371ab18d944bc69a053ec760ee7b7a1dc1494acc7816bfa3bab433a0e02e288b08241b0b70f1cf7b0252bf946deb8a33f51f40c19d5543ceb7c3e9ba3d9e79b70dec767eea277b73b43407d85d1741cf66c5e787a3cf43ae70c775abc3c0eea58ae3791e257290bf0e5a0db3d436bf93b4f539bcbb4935d8f5d0a78eaa5513d69bb06500ec6ce358382cb5bdd180f026c6aea64837c29178b9ca9f780da881379a7fad4391a4de8eafb93dcec6f563c654e930354a76a09943871a0e9fcbd063099518db6d2ebdddee847db0346a98452ee394de207491989c25b5aa9d746e1b6fcfa8dd8a8764145d2bdf9716364e2d9d26595954cf913291281f91bc6a1ddb6eaf6a5226c59b6017cc0d8189aa66f64066f10ce5ec6fd42b57cf406d7ac6a65fe23289f493f45bd3897163bee175260cf52ca3751784bb6e5f76fa751b8dde37b1b4faf801893e3a649ba54d6b84711b5db590b1eeb5653853c6f79e642479f92db573e98fdfaa04a07faa413acf380046bf97b409c023a0964309f64adba2847344cd4548deff448e76b260b3516c6b0b8fcdcc3f6c1e860c22e79f94071928519fb47c172f5427043c10a18e1937e9f391b2d3e63f3c99170349b45fde0439b57302799ddf5dae2bc6cf109e6bb9de77924d9fd91b2ec76e858290f9711e4a467acf779dd4a0813414b42db01193e3e45ea543a7ccab265914fe6c590ea0bbcc744941292a4aa2f08dfe3497bf5a198aded52bb220efdee8343421b34abafeda2471cb9838d4e928ce57505697c6700b3f69e1612b8d2238d8604260ce1dd4e226fcf9770066e2b3e68d5d10120ae7df375f8d81aefd164dcad599e474b36d6a34148d55932d5491cab61de918b4e393b3ab1142ae282657673ad6c6bfe93276ae519c5fc3be3cb956bb23b7d541a0f886eb301b9d141c78aac208896161ebe0b1ce1f780d34f27575911eb25d5a3d5a866b603df10e86284752b4635dd1477dbe870229007ad311df6ddbde2d9f978b89fb483c1aa50c884bd8d72c0c1a5d5a7c9ba6865aa48f52e16d301c929d7c35f71b1ccc37c9371b1046ed885ccd6bb9d9ce8302cf4f028ea7bcbca187692b84f87e6a4ebe12ca035063519cf6479832dd8fec99024f42e576c33ae0b675a628c4be9d60a533cd421119e24c08bae771eca48620da2b55fe0ee3e046567f1250d07c3724a9d18caff05154451e1458bb4f4a3856922f60ef7a324de6cb107b8420ceb530968d81d0d6c86a80e3b01607c17a804b63ca0d838c2b041786821e823c57efc51de225c228adc93733a334f9c4ed2be5b64723d56605aac4b4f941c6b21146a0209c24006a2c543a5170e775b3673dbb93fca645bcbd8d7072dda4802f49a808a999aeb130390f373d1443251f8eeca0ca790e7efb9102ca127276a4f38a060189723dd528bb52709cf37b269ad01d778de482c07820d9d04a6790f6ae7d453666c0e013ec23469608b19b4d106590c752fe9279e72dd58853ca91e81f4e1d6427e404a359e964946b510e51ee5d25936df939caf8b14a013b925dd65c44d0b4f22cd5082eba7ed9a2ec0019190835e9c89f904302f8023a202e798023344c2badd95fd0553df002374bb6b647e613c76c80c8d042cb7844ee1dafeaaa26fcbe8fb9896e77303b1e3ef51ab6ad92c2c96ee8987f365e3591695931622212e387431c29d9b28efe869c71263ed5088af42de080725123844a2acbc8ab09d6385a7c3b93733056275900935a99abda4d76735a809322a1118007aa11c1a0675229b134e1de8042885f2645acc9ccb7cac7f03fece84c3959a048c7ab8dfe11ed42ccaf0445233a759aedeb11bdd146e314111de234179182589767fa190c438e40955a4008e18b2d47b58cbe40030eb7206ea93661229001cd6ff4b0fbc07a46224bc293ef0191fae7d8d459e10dbcb7afd3625b0cf685a8487f584db9b09e852e16bbfc0ddcbd2c3275996e824268362e6fce6900fb3084699690133cdc182b5d49699e4a0264d527ba2c8fcdb9c7260a63305271f78293c1c9a658164cdd502a774bb4b94c1cc92faa7849fb6c636e1b2d2b688c26fc165d58285db09c27594e7603341de81f94dc8f377d13bebd102cca78bd4d17e0e151068b6ace98ed7c6578dcc3cd3911518cf81330604f04a69af5cc08c58541ec09e0e711d64fb81329a2b82404f067a1a09347a624c7f864f8c35c0f05c4b5e8801bccc9d9173de40978ecf07c47cbf946cb1183f65a7177a55bde66a3b3e1d8623a2564c45e3f02949b2c8060a0723a0e4fea8e597111c898d78f5ff2ba2e453c69896c69f80e981831e84e7a11cdc1f69f9cbb9eb33ebcf328b4d94c798c4155a2114abf20452601672a1d812a073c1153882ab5c922db83ec324a1b339d9e83f2bd3f5d7b440096198ac690ca69d34d5ffc08ee88ade5dc984b37c9c907fd84a8c57b665f2f186382171cc48536a3b3938feaa52d9c808227af95b39f617c8062578a24e4f2718319accd41c7b6b070229326661c672a610262b4beda06b07cd01a5b78ea00aa9e8c6c77c3149af5d880dc0742137ef73dd0aa1ebbf0a2ece05d7c395d825707ce400e34f161daec3f312b832f0d471ed0d3b61658a2fd483d374bb4e2371538b857f71ef406674c9abf5b09951c51ce5a3e6e81200d8132e53f3a1967cd5b16ef7baec9493c11eead49486987ba7b775dbed4e440b34a9392b4549026fdb1d33d03a4a76a0eb3be51211e0893319ac00a0e1cdf1d4be7746a092a86cc6fc391d4cf9f8744864d93c1b877a4f2210e03e4915a55a5ad2a2768bcc3b708d7850b77a336efc66744bdff3d3e1146d6a4d78322871388c8479b8f5b6099cd7de365d6ed1cc0aa93fcadb96922fbb5de48de3253d1962721d5ec9db3da99f25fcc84b407e718b9e2fb4374dc8d414b1d006a48aacacbe518eee5c6cb53726d3785c06dcdb25f49b0943b07ab226a69f28b8ec7dc61e7285094757985c7d8726893510b81d52b6db0d0cacd2764855f9713ba2a2f219d16cb71b3cd0e6d7180644e23acaefb7094581091598ea85b1baa55e64303db2d8fec12871a178fe13cfd4569fa1fdc070c3518b6eee3a681b5ba2db722f8e6a79b8e33408acf93f3285d86e371c8c2ef0e5e5406fae84d32189e8dd9e147450a971e8f524a78c0c4e28cabbf9e9d08a17c1279eb2bcb361594757a8c898275b6ce40dcb3afa7c742343437990db9b823b5bddf1c9d0dc7a9aafe69e03ebfec26f1b731d9a56471c86f5d1d80be2a679cb213ab2a253893f7602f863560ed3be04f1533ac4941a86ca9ca9faad85a0092a7d2a48d20471200d8e66f18ccfe7364099068967eee79cea106465d65a58b74cbbe52d133f85002fa5cc122e22c5f256d40338c1a6324a9a17e40b14359fbc18c60ae9189ec262014bad1dd2afd7d192919cf209efd32129c2389379fe4bc6975cd02012526cd7b2c803528452e84cfd6b725dabda98e40e893cd1db654eef4c238cd97e528476c018d9f5394d2b1dfc05942843a22731b16ff10bab89b0981885e474d648613ed9e8a91626597403b5404a175fa63d498a3093373d49249198c4c0dc17e6594ca219fc9fd39c6caa2134201ce5788f725280d54aa1c3e809573181fac47e15bfc1bfb9c7ecbb5ac9c6ea8ce9e995c99b717626f4cf58a6e3ecdf448d150fdf2dfc32e8f9a7681d6a7085f09daa343e6a17ce0a93427799b29a3ac5f3e160ba41785caac07837e21b723118d41fc68977d2618da6b56b0fc9e014d4f453b78453659b3aa2ca34f624f3ba420008b7f667555780d61f74494b8e5e4bb4e459f9def7543e1ab5ae83a5404b84533d2c01db463d34eaf920f6e18fbf7d7af5f1cbfb571fbebc7af3eaedab779ffabf7271dc1744f46093b1980312f79a25bc586f3a0b9de62420c175946db55474cde28b4e2c539981abde33d7111770d5843b7701093a9dce32fdf2331c5052997568157c1ff82c57fa40109430ee3ae55127fa72cd32c56edfcb5c47a8f95e74a22f65521690ddc42abee471c698f8c87f67bee73a52179de28b72b7c8ff4c459cb4d3a17e4a9d1e2480bcf29ef9a5209d4138209d6138c01393546c1bc3d6218cae966d6d62f0f64ae3981f8bc5826568f8b8b7d067a503ae826b7d74d2ae5eefa2eb9238a4bebe46f84ed18848837cc8a86cb0426c4882890a8bbc7401dc6b19fa3c06865abfaab6ee255325ddf05e13c067d960813e79874c445729fb0bc435e001a6c43c2cd3bb3f18648489a04e7ab10d84f7647328befaf3ea718f853c99ac67995e466fc97a96f587fae7966c67597f34a7cca40e3ee7732a6ca00bfdd3047a5406da1393fd0186f349fd0901adfa43dc5b3cbf0eafb68abdf190aad841278f7ab5509609bf4e4d01eae38dee667802980d68ab8788d203825ceb855f1f57fb2018e9aad720c76b0f2700e9bad21204d1012f57dd2eb8c9b0467081b6c4342279dc5b91c77a8b01e1be7ca4a9a59aeb3550ef3f36941e128dadbea08ca454911c647e63a75a7b486c0c4505249cb6b554f8e2c38717bf7df9f1d79f7f7ef501f4b8c32bf0fa295251d3fb9aa8f0a7dfdebd78fbfae5979f3ebcf84f4cf26e17e520b78676b9781ba98cdf5e2cae110fcb714bb4a887ab40a305e2a137cf0b920226c9b53758df4b2e14cbfc514d4644853fbff9e5c5279de0f937d66a32389ea419a3174485bfbefbf8facfef5efdf445c72727836f27fb5427abb73708902315be79fdeed5473220a3de0a9388ae4e877b72052f6ff2e74c8afafd40f45cf73e70befb4427685d8d8b883cc624820115e90105a220a464780e5ac4c5a8950ff39fdd0ce9b71ae1fe7d902cfef76f8349731b3cff7ff33618de6e9b3b21e90cdd2e082971a1b40f6c8655bcdf3b3d3fe9d9006824bf6bf3dcb46d9c39e0f43557d20db6dbacbf926ef4023ab877f3e46ef3e48dcd33218bc3cdd3be6ffcf76e9ef2619ba7fceecdb3d209e0c96435bbe809b375c24fbd799eeaddd37cc1fe99ebfebe86ef736fabbc6f9b884154be779b882823055524b6db444995e1a7b3863567add79c096c62eb6e17dc786313bb261766b1bae8adc905761b793d415fd7caece36bbd8fe7cfe9e6411bf9e65fdbc8aff590557a80928ddec831c264dda7704900c68af664ccebe7efffe63d7473b087c6dd2e8a8feca1b2be87a6f53d54fa7b68440a8c27ed1b9e37b8c9b9bf875efcd37ba8bc6f0ffd66b2c3d1c126fafe97d7ef3ee95d748defdfcb9e1ebbe0b22b0e946b6cf924bf3b99ca38f54e4fc4712bb3e4104ef1908b6acde51b9badc186d05376e86884eef60d9ca4f23a34c858ac026c70b502b8140cc870e01ccc9da0efb2e0691a90e08f834134624f03bc27096dde729a90b70151e1ede9231773abbfb7a78ff45a76a4302917ac2c4cae32f9552fb37f7cf6ec59007441872d61b31a425e654ef0b9759fb7a38008cf173eb7785f434dd78919058f8ce571941a058fb56749b6f57e2fbddf570d85f18a37740d530d05fdb41fc0263b20e677d08fe06f0146bbae16d5664274c74f0ec0a314d5cd725dd14e76987659964d665606969c9a55868b654082642ba2358f033d297ce83b80b6b2cf5c37f4ae44df6fbb0b8c9d368b9611db83e410443457fd63540feec2ab84564d9b879e6fc4dc943161bd3dd86edcf3543dd8c1d1ca065b95c180f6e6c3c12abd274c246dcea053f392e975eba551173ab2395ee95d9c8b4da1de46225ab26ccc0974791a29f681a5adb4904e0ef8f8973fc3e208bc90a007f0f2d35b046c9007214233eecadd1c816618cb7286309ec8f0960a22c32dcd089254de1b1a87b714c9f0f6340a6f718f8711444432dc9e46e156bb248487ac4f65784b78b8d03fb65693b01afe3c8cbc09c0c30406bf8e67fe2f8e4d8302ef094cc607b60d542e0b6f4df5c22d69ab5fd57a7eb318c54b2f49b34f221c967da41b42a78c43281312bedfa9f63cd5be24f63ac8b0b46dd22de27892d2388c4844e3508f88383457ceb9d75271ada562db52b16da9d8b654859fdc6cb01c936b50b5c524d5b246ced4c77afbe1bb940eef49c19565684bd1b13f7050256d260a17bc7ef8644d64cd2bd44aad01d4140ab7c02433b88506e32e2344baa4f6874c70de86bbb10a5c59692d54aa60516175c6a822b9d187a11961064ccbbeab81d6d8f3c194399d03b6901903d2c605cf7283e70720f25ef5324cb2b2068d9239a9dc6608fa48f51a895249c7863135ac2f625e0d17dfa8a15e76a9790e72353c5ad84626aeb0f1030a1b9785351b0c28ddf963abe4b9ef70d189315fa003ee4186dd66a63795c91aac355c65c25bb206838dd2614b12a4c89a184d65bc77593788f21a59e718506b8e66ad37abc9b69e3568bcde926d3d7f70dd92653dacd2b37d590fa9a43e6a2105b0020602177b1ab3d6f0b565f369b7b7446aca90c2634161a30655d2eb653d890a6cae7a4292e806931b8f68e699556e3a37ca4da347df227dffc359ef0f4613f534ca73be147f4031ee7ce422c958e7a3cc5645fe87ff91f298899c75debefef487de99c9cc2af62e99f25afde3767d25d39cc843a0ed7af7107e186263fd5ee7af44b166993e37d7c097414cb0a07fad0838814dd3d4c4d3baf7553941a94466354d7cdb9c1661911d315d54d91614576ab9d459d2cce9d382f904d1556c4096d8ecd19c068916701f7930e4f5c67b17ad598e189e0de655a26ea42b0a6ca18389b81c0e26a2dfc76a167c09fa16bd5c8fdc97165208093ca786776b301c9d5f3c7afce4e9b3e0e4de5c9516241ad6616eb869590f637bb1531a39da0a67150794ae6ec216cb15ffafafe95ac8cd3fb25c05a0eea274c416e56f9dcb8ccd01b596b4c7af5a0b74c86b6d8ff419db2b5ac531eecab8df233cadc569086c15de5e4152a30c17d3e124be6c22311b4c31173cd70b8f234aab74f367f11c636914f605c971b78bd2593ea76296cfed9a7e57007076d9b10b3a982c2a84e445bf8fb94ba0982de6260dfd4b2703ff2bd0b9f45b80c81e8f3a1a0eda68a86ac1dd3af268a4d791bb039cd5f1c9807830928d4ff0b6b4bb00360adf3cdfa4110c33fdb9648e93a70c014e19bf660900a0fe9cc9354ce7237e65bc35bfe5027ee995a32c803205db134e0dd0cec98098c6b541cd720365d7cb4256fe02b7b22fcd07575b482ca2777ffa9359b04dadd79b28630fa8707bd90aeac342fb285a59c8f3b76c2d11c3d3685ccc58e8f29def76725fccb2f06799dd4459f2812de6f552d9fba6ef2bd49ee8347596731a4d0c54959d3166812cd7ecfc9e15842ceedf119276ef9f581e677ca36446365e88f7ae977e5990d5c14ed172ddd261c8ea6eb541fd191c81953b4b6cf4fc93ddae3ca174d5edeaa8926406a138a239cc4eb0988ac2588a385208408cb007739e6a91f79aa65a5e5ad3c1647d1955da446b93d19646b3b55115427cb69def7659b79bc18feb6ef71a7e14dd6e31dbceadacb2a40912648b277aa7898d74e12d6afbfdbed2d76f70829720d0a03a5e9ac2ef7d80517c77a06c5969737456516e91fb98e8945ba38f55d912df571ef9660a85dbc229a555c64ecaf5144b1819c06a092139a88976bb873184970a6946d74d581a486a17db8ecaece3a56db6596a0d9abf1fa81e002c1a21c07e7fd210095aa1b2abe24c3deb5c5e75a6a07c0f05698bed37ebb466d01b797b1c8df6ee4e277538492743b2a0a7435fb508dfe5dd6eeade579d86d434a6a91bde311eeb48242eb5a73608e3ba5a110053ba2bf602257892d39381279fc42509f2c4ec93298d8dda5fbfbfb854139c76bbe96c310fb342203c810cab58fbd41870981ad46f86324aa9df08aeff1ba6b2306274d868b73bc970b7db1627aba5449a49408f6801b06db064fe60391c2a993f54f440818b634fedaa620e5d148e8a288cb22cdafa5ca1d708dfed6528f4a6cae3af6dc60c25566b5348391d422b349d9f0f3d72d7e1441c0a3746a014a7c379c5823113f389c5a0d1399af263323ca165afed76f96e57a00dde939527c9678538c0db5e14ceccb1a24985bae33d91a1e22a6534b0b811012979d8e8c980c890896b2dffca30ca96d78056175a44091a04d5476e024941af09508e383c12f8962266e6c76201ff9d028617c65279a4a973cdc199adb9821f9b8ce993762d8e75fb45c4f5b4d2328943a97a36d705bde2800bd6d0106e2cb19b4cc62ccf5de00e378b6c5e6cf41a6faeae6518df248798e2c159007eab84670fcb04821ec9a25847f9d716f0f3fb749f8341381c84c3e0a116d5ee16844f80e5511a784649383da4d59902902b20892386c7cca8fc132d5fd7894a2c4df46ee7b90899b0fca8f1412aa3a40397bd7066d49b1b24d18984a113cf03230d447430892e6d72950410591442aa90f59b45e60070921e00c8f02468b1b33226e4606f686997b83e7480a2feb8f3ced8216ab735cf73dd30785284f65a09a5214f480a0676067fd795b3c1611d396c5281ac5f59ce83bb9cc0d8a60578b76bf154f2f53dd5d0491f5623ecfc28d5aa63d285a6d5a974a28cf9362d4568af03516ccde3480c167124b6157456b8de3dc8451ddec8a34079a81d80bb8d032afa7c3c9bc3a385feb12792d6184fdcba7cc79331a8764d2a02186bec8894616936df1ea315e17a80b7a465aa3a76768844d7786cec10bf27fdeaf6f7a8a57e66472facf4d2c2b835ecf51b113cfa6aee22346095b3363669d73f8f0747fa27425978c5d40d6342b03c87b43d09d647fcd54113b6cc18331b533baaba7f77c07098cbcc47f2f00148d94ccc4fd94cc16547fd32a47ac9fdcab663452c43870ebbc7472e8b1c12525599974ca82c4af58952125372cf89dffbfa6b6baa9b0ed4029db397bcf61bf97e712a73e67cce7d1f16c73a631e73b5d59e17df20f673d7c60363c27cc8fb64ec935985754b8758f4299b65f392007f3a1c0f4a048baab3b27f3983926fff5816b50560ea12190f8eb007da1d88446df81870ad7625d52aa094224591daedcc37aea377e1dd2ee042167083a530a7b224710bb8708ea224e10b74d013ed7ab08696b8de71395c3a663c74be72a1378171870bd2d1db94cc3aa634134eb3fd37267f2bcc08d0b147f671812341c045cff0e8818b67454804b8c24063d10635d2dac0e4182c499b6bdcda45f7ac75b1b5ce1ed496b846b885af6f04b3f0687a953dfa84cfd41cf06bf5ffd3a1318b877ca29998d30129f4bf21b1a8caf60a7052324c3a91210bf3155f98074e089936166366f77812d760f9e2babe33c377a7437d189ab179b70be63a349aa5f37e590286753fb33904d21e6049cfe67dc3cdc6676cee0a00a89e7a14ec3112740186e7de5a576fa0dcd64c5635ab4e8932dc005a5846d1b09fced41c9f81b17e4475fb11731beadda52c1cca6f345bcc27e92c81e225f35eb65716bd259ea9799f425a06840813b5dbf90b7f7ce4ee399eb1f9191ded2b428ab8da968052302dc7cb3f37f6db066deb6478c03ecd1f3276a37f6aec4a336675c2d20cd6fb4729f74669dbd8e424aa8dcda8911f8c4c9d69b78b206f39e3dec8d4bb398cb408465a9d55501e7faa90f6a9e28023af0c723ab41c7924a5eece9dc4b408339614f101689deb94bed251b86e9af8f9608ad2d3213e8bc7c69c0f549dc1ffff1b23ff0f8e9101698c92d6296f57a1199b4f8a4ba5573c0ab843a6730bd3a10feecc52cc4b8059627b445fb70159e3fa11a080a6efa2776335ad76601be80c891e12a7438cc7a3de3dbef7aa389eb7abeb3714f53dad3cedc33c9fdd4ebbc95a68ed26c04d35dc1430b33ab7fb74268f9ccfeed22849583656f0c0923255575e00abdbdd4e5d0e0f85a417aa93b228571d7523cd111d0e922585f142661d97a839da5bbc047b678eb007b4ab00f6487f6754f487930c5c322c4e28cdba5d591e4905c92a04c07d59ea1f395035a8a68287adc089d09518ec76e27270ecc8ec41dee97a94476663bcd8910b5b492e3a2c8a571d93216c5ca5edf412168faca35691e80c6c7d0181a1acaf11ac4dedf4b7a46a222f555f00e3352f2b9a79a0097c4faea23412314b7ee402f0401abda4daeaf5da54c162c5d46ae092eba88cb1aa5f7429893476e61b79834644e1c9c020cc67e565c7d0f5dc70222e650558c5a920111df53829f45fdd8d6575388930f13f8bf21a21db934da456ed03efe1d5aad7c2b47559e40126a6b866a0550511a7430f5332db939867719146d91b33311a37e3276cb763ff44a1a8aa9324dbdc07849d0e31a91c1819f58cd39e2c339e1c0e677539d4c3b86542ded3dd3aa9da1cacc6245fa0a1e9e0a1014a7358735ed3f123237730919766dc5a14aeac2f7b6a9219bb0357a78864a743ed81893cf0e923793ac43d852bb223a8f879ade6f69dd1d57db7cbfe890638afb5805d5edbdac0fc2bb5c10abf290aef1632830bbdaa29143485fee6fa600d4dc3dd2923eaa99e2031957dde53fd74024de15db511793a345e98f003bf3ee2d04cda373af4d5f15004217ac2bb9f23423654b9ee592e9a0b5db5ac3da7e562e64f2f7fe9aea65a6d36dd444ae51f55269791faddefd20a96267bde76047fb99232679d7c0d1a039dbf7ffd7bd879ad3c0da334ca966ea56d76f8dfc5df6d716163a4023d7e8ac32c12895c23bedb5d8c408f14f957ca0a3a332eab1155afcfb9591017a9d4b3e06cd41f62b2a0c3c9e232870353339182a2453fc2ffa648ec0df5c224785f44be4029bc43fd248bab94217c29cbd3d8a44cd541294048a43059d10da534d9ede212bd30211b18d6ab6e37aeae1a126c25463dd84f8715dd1c8893ab097e48aa3af76bea3b1678128795712dbac65ec5751c372063e053f847c15ef22c4e5bf6ea5641e3705adb44b46406aa905e9a46fdeb81eba38908b67887c95437616653ac6638d7d2584fd8e5acda4b640fdc4f87d50cf056faac2995ea653e3bce476a08089a93abaffcb9c74ab1c9285a68d14982abf4f7b8be22b20fe62e5576ea7fdd366bd781d361736f25424f95ca41f50551fd862338b5b4983a1d92514f412bedbd9b438932ff6a7511c54a665b2aefbb51adb40b00a1a4d532a8e479c1b5bb52fb9a9a33965056c767beaee893b577653672317a76f1ecf193d1b3475d743eb8183d7a76f1e8f1b3bf214651ddf3d0e5fcfce2d1e0c9e8c960a083b3fe68387af26c381a0d2ffa885d5e0e47b85b05c77f63cf9f3f1f3ec3b87ffee4e2c9e3e1f9b37308f6a816aa7ffee8d1e0f1f9a3e1f0f1dfd8e5a50e7e317a347cf6ecfcc9b32710febc25d5c716e2c8d49ca0d1e3a717e78f2e1e3dea327ce63e1e7b1d23bc5e316b6d8bd36bc5002fafe57c9e51839c3da9d9a6544863b0321d8ed3b8c8955c7f80d43b8964e629d5303096879117ef5f8f3bb0b2e14e35e3fcb73c07d06bceb0872adc7abfb2a39d958fff13f17c30393d155852533c04839b532070d37f289b09fd4bcc29270a717d3c743a1f0ab1d9608ef7245f158b45dd8ee0da1175419ecacf53419e0a0b97a7d2794a2f273653fa973ec24faa77b8bd3ec9972a03a2c69f5fcd106fab83eef7b7a39ee1e5ae27623ca9ac79584bc786eb322af29c47a2d5b46e92c83b4547bd835cb5847ec49d51d5537dd1139674823da7c3dd4e1f583c14b85e059b753a321fa95c2286cfd87d47e6e1f93da46bb114b94c1924147c5ae991c4d44ac2fb70c236198b23c592b0f31e8c023a45ce3a7fe1d751c8807a0761e03e6451126052bdbeb0ea111d5e1aa5702fe8e673b1a87d2f78e6a2deb15bc5441bba00db1329c63a2d43cd02c9b847ca9668ce12ce6bbf037a1aaa7472aa35e5ef2210749a2a995c3bed1c25a932bfaca4222cb09a648b05cdccc78d01533b58c6e5548e872d5dda7cfbf2ae83d49485ff28a264301e7a5fc3f1c8fb1a8dcfbdaff3711ddd49ba5c6ac951514f908a7a92549844c11e0492a5a2f56193e13bbd1118125407f777b88139af69f96bace787c5f16b090f1e53fb7f1c3eb55096028d06a5a83c7cf6f4c2d8353c196112e9ffe79814faff85014eb579396538bd2c4780810ac93adcd30159d1ebf21aeece071f3dc47b23825a60dcb72ffefae52f2fdefcfa8a64874eb2747afdce3af143a7a85c38278a461e20a94538d38b64b8917978ababe33eb693e25274bb48d00293e2b9ec7691d43fd34b03779962923ee7dd2ee234355aac3195a782e4949f6693f8793ee534ebc7632d90e5135d7f040d8081328e0ab20a3318c192ac4225373423abf04a2a25d79413a4a83eca3d073a41ed9e6ca168d8c75345e002862b47ac56560e52a0846a3d68eb92c593c6709f9bd30149e8107aec9a0e27d16c30a716c635b16db6a6d16c33275bba86924d92531da14f8d75c2926ef5da34d976bbcb29cae8d634ee29b38d2cadcbd6ba6c01d314710fda30eb657dd99318435323555ff3c347f8ecd180c8631ead291141d3de1600967b0cfe9d21dee33d0ee06ba297915cff9378bc844cd710e6af67e6bf5778e3f05bdde37f531dd0da0c9ad3358c227cc62f1753a46bb67e48cdd0da2c4cf034793da7f693247d3a24d77d3ac4c4380deb2186872146f510a3c310e7f510e75e0850df3098c2b77d5a10f7b1edd37c6f69785b1113d9b4456e770b50b78bbce50893630b1ec014dadf0ec7b4c44b4d1d386aeda0745d4afac96c53c26ab3292a577a504f75cb7cf531f23fcedd074c67fb1ba0c0cdbfbfdaffbf01c9072c13cc2e120c9608e61688011e2363f5c4892e116598f4fb1b9f871be0d6f5accd4b8860ab3cb4220c4f4ef290e7afd61bb54578529a53da77624e05a827e9e5decc70be401c7eb9ab2cde7037d529500a941691fe8b9d9edbb916eb8cd94d7db09384226e47343723bab7201b0a69ea8a9e725d6fdc5b4c5233ffa809d64f8871d85208d1df90f8940ead0418c3e558bd288ecc373ef0319db9779a55242d1b8a9308ef4bb0cd358dec1ab0b5bfb6136ebacffceb47f08f70db99f6bf75eeadadc76fd6e337e7b1b5abe6805cd9ea919bb25dfa57f86c446e4d35c9abaa69fab7f86c34593fbfe976d1b20fe4bb37e486da68986c9fbf323e3af62bf28aba88e6ecfe95668893259e7c9ddada7e25111e23f4d5dba4aec8571877b7e4ab1d8737e4ab1b83afe067b2a511913a29f2d5bc8b3de8050f44b86adcc0a73793caef61e37bd4f83ef7bea12b06d5efbffa1fbfb90fa8d8c0099a1bf7d34d2cf3652a7ba863ebdd27b83b0115c55fb584035f1bb9799ddcd2c181a69539b8c884391917eaae6a2767519d92e89d9d9c6d68d85a64ac32db13dd7bad6fa05501675e84f9444c91708511b624787c24b40574d5c9927ebf9eb16cb20579decf4b2e6d2fe1d3533f696b3f3f6e8e8bb215bfef69dfec98d1558e58787baac25b4c32df6d7baac26df500733964a74fbbdd0cfe7f2707615697912f8ce5deed703c205bfde776a47f8d2af697bb2b793b9656183b3c6b310f9e1ffad7f1cd988a3d44166e157c9b4eedc2efa428d1fea7a8b00b6d116e32760d6066a4b06b6de5b6c563e485a03616f14258b72db6d16f9d386dbe4a672b44379cb756cc6e24b27d1e81919873decbf07608681bb723ca890cb7439ae97f231ab50c2f080d8106260a841cf828f047999c049584d301891c25a6e520b9ab0cd40693a25297ecf70bccfb94cd0a77ba88bcafed849f95dd4ea2eaf7de282c5224c2db615f84b723bd0144fa7babbfb7fa7b6215dd439f3ac30db5db31efdb5ba1149fa66723b21d477597c375fadb5c1ec3277a3edd3587b05edc9c2c774a5958b272f45478cd521973b50d6f890bb33d1a665b59d803610862542146ee6a341f7b4c32320b4ab7600e37c3ff5455daa6704bedec5a0a37144452152a09a0c9a6bb2e075356eb85b12a3b15f4eef4c947b8d9615db6d6654b524fcc8f7a51bfe815e6b13d85618eb2d6c34171cca32d396ccd4bd3534e728a4e94b947d9edec0faf06a699ad3beec567694fd98b9689a804f6bc1711e189ecbd82c86a08685f59f576de2b8e74ac9fe7889d5e905a333e1dec3191641678c10212f86174e7cbef56ff1a582ed081c5f16aaebd85dbb706dec346516938a4e69235a6ea2c05d162927a03bd4fe35eea1a83783e5bdf676b7169fc9864e17f6e49e2f565decbfb8bde024f92e7fa68e647a3f95952cb872ece123dbc55af963aaf3b6cad007ddba79993a5fb7a05ed575b6686f592557e96c45548f6643fea45f8acb8e7eef4e9e07ea437f30e130251d4c125eca132bc950c725f1e316e66c33970879636aec6c1d5dd770399717820aeb16ef780e5844d8d7873db7693763b65e1edd8b153b485d84e59b81deb83dbd154a6ec9e14d4548d07b8e5cab1d630dcba1e364ddda76a1cded238bcbd7178b9bafeb7358f09f17b5b88dfa72cfcfd5f6dc0a3e98ba9d0cdeb597103638f207f61b192d928196744bb9c276369ddce9331dffb52bbcf2ed9587cfcee086f9dfcae7fb25a5785dbca4f9f0f6a4f2720ce1c9ca26c6a5b2dc6c80714a61a33df5d9cbadfef95dfef54ec097f78516d2f3c94c0e5e44003abc55ee39a09c5175ba71e52e4acb388d27cdb31483b9d28ef9897974e5e181648ec1952cf022902122c78c60212482d599016524610fc1a66786a26e62d46781f4d2e9eba0a3345e42c219d9c8b9875b8ea4469c6a2640b76fc0e8ca7f343d0d7a9f6831f02bc47ace4983a90658e2b2cdff922ac7d6939f2a8daf29e1aa5e955147fedf0bc7a3f55d2d0ce952994986e3351de89f1dd0e19173a9b633d268a7c85ee5c82e38cc4ea762cf740c125178b06ee5c83b0d31e205bb5b5e1a50cdafe58b52ca616140fa4ea4a4942bb11a3a125abfee558cef83c7485a556efd4724771522975b03dd14365ec6b745b9d3ad31c3e6b68874d0e8dc3e17473403dbb39c23d5b8ed496325bbd3b5df4495416deda7d4740f29195ea37cc98c8575aed5298a73c78ba33bc3706968d699997678cb4f1151d13b214cd902277ebe8f6afe3e1607441d6d1ed6fe657ce58320e7e628a656b2e78ae78dc31c2b76079de594709ebac592791706110ec9dd6a4440af40fe0f10936b283b3ef5187f228dc74c0000643d23604dadbb1b06feaa1ae0726db9ac36f5a5689db00246aa374da3266c78015db661a05cc7fcda5f0f65285b743b033bd1d52a60fc72cbc7daec2db91711c39c7eda50ab726e45687dc82e373156e4dc8ed081cf7c8e647225c03acc577e639b9a19da4cf203aeb83f68d74362daeb7a3965b089dfb816bd37aa901738bef0adb32ac09665badd98389f28fdb95ee3f50945a6a5be4b87385cf9d9bdb1b303c2e81f784e3d09d63222c0b6e7be40419ff327231330e06baef88f96fde34ef4d5ae8b8c95d56d4af1eeced19db20bc3fa07a7418af1527d57ddcd1d1b799987519bec9f0acb36a278c3ea4ed5e3d8021dba32a35e4d82b8f945549f80436d6fd7d4cdffee903800fe10249cb1c240bb754e0fb716cdb3002a728a58ce8d635af44291c54aa67a15513c0b732861f5ac6d3ea8a01ded02fce5bd0c05c9c8b4736ce1103924a23a8c67c44126011fa7ec686caf5bc736dc9cc80b2cc274ec8a3f52665d9e8a74ef1c5fe1e7cc37ff80dffd137fccfefa161e08b0eaa9535fcbd4369671096210e38272c01d5e82754d580d42b1cde6e1d3bc3be632d865bf3197e5f3ec37f369fd1f7e533fa67f339ffbe7ccebf99cf5d3315e0c628516e8778d2d9b7313e3d9c050b467527fa6274fe5e38f7fc5fa202717e26f1e28be229cbdfb3cc56f6dbd3e5bf813ccb51869832c532134c37e85a26e8b0f6a473117aa175f95f8b84ddda084699ef305ae74cc72387356ea4a57d3ec89b0eedc07dd4b7825b6a936178e645ae077929d3622d6cf1cae2123fb746a2267fab96e8229c35c383629e692abd2c0c5c5734c7ad199a235436733951bcf8c36fc71fde177ff4a0fc077efc6fe66643eb31e707eaf468d9f493a66778dbe953bfd97bf784ddbab0bac1ef0bf87bd91df70fafb3f6e1d25803aea9d17183c3c2a095e9edf1c51156b718df71d05f9228765c23992118291a1c352b2d65719f114418bbe41a478d68e3a86954ee7eba1af0b4bb8dff31f43f46fec7b949a1de52011ca2edf2345ca0346c04204c0738467893fabc38f7056b564e9fb6f8f751e40c9f3a7a39c391736ac970d6b39228c7771acde9458f855f2cd1aa763a87787d2fd0c561bc47b578fd21383e3ec8f18989e927f6b41e73048ecf0ecb3a388c3a1cb6c51d8e0e0a3c3c3f2cf1f0a2adc8c34787911fb7e4fca41ef9bc9dad87e1bb352d42a3cc6b3a754daec9f02906952b678118d65969110bf32cc613312d33a0c2f2dd8e51e536202ad433ce84273530932a9463cadd638c8f92145d0349d175455274dded1a3748bbdb55d68cc8960d98607df2a235b1034dff871ae27b3981ccbd4459c8b2b8f7733225f4644016f77232c594919c2a921ca1ee6b2e32dca71de2755ea108bc2bdaa186f79af006ed50d2eda2849e0cabc5a1a21d4aebb4430b6f0519e915c493326202ba51ad1c41698dba8f7f1f75dfb1240fe496e177a5fcb40681c2174839425967456007b9e366b6e649867c5af8e4d327c2639fee76e14b448a5f337373b3db6d9176240c4f5458515d23003c21dce73fe2e1a70faf5fbcfbf31b20127cdcbbae1d13b7ee42c74fbedbe5a1b93eb04545757f77fde51661174af75614eb70ce85cf824faffefae9d70faf82be9abb7156fa86d6f3cbe82702a350b15ba0f61dfd54f71c101e7ef8f38f2faa7f75662866b9846d1aefa32c5a33c5325e4fa6fa78fbe2cf5f7e7efde6d3ab0f8403cbe28b0f0f8ffbfa5d33ee97b7afdfbf7df1fe8bfefdeae3279dd4920996458abde59b75b4a9a5e56f9b1ca5b3c0eeb2ba8d88c2a4deda543c5cd9c84a205fecf9683c207645190fc871d2a9f311c9b378ac1eae78c1688c18b9337bf68f2903244a0324cd72965db39fb2e8868ba559514a3e763878d5bffe02d06977d9784896e321b91a0f49341eeeed15ab22c25d239015f9bfd9fbf3e6b66db75118feff7c0a896f8687a82159b2d32c54509dc4b15bb7f1d2d8699baa3a3eb4044bac294005212f91f4dddfc18585204539e9efbee79967ce3cedc4c246eccbb55f7778463af89174f0840cbab863feaf0d0df135190cf1bdfaf340966b7ca8fedc121e217c49d208e18b3ac66fa2408983ba9c45b4dfe93e7ff5fad58b572fd11a9ff914cadb76e5be8e26085fd624aef195ffdd370c638dcf4bbcaa3064da97b971e20f2cf059f2e01cc8ffae927117e13161d6adff46a19f205d95cac3306fdfa5f45e2d72a4dabcc163846fc3d00e4a5dc6d1cdee1e1eefee217c198697751968dd63d625f8988f803d60ae07e369250af41935bc9953f03ab5dda5d4a1f53ab5dd31d5c37fe475eae23ff63a75f06d5ea7e6ffd6eb54c92f94f8974ea81e158072dbd66f7c84307855bc7471e32f5675a2ce67ac3d6482dcb6cbae6023d4bb6dfbbe6615ce228c8bd948dbe4c18cdc0fc410ab3fe47e2075a89d8e89c02a4a18fca80489bec15bd664a0c0d6bdefe8ee4dab8b270305b1765b7bdfc9dd313e8bea1c017930fee3ce0e16e4c0e32009d530c3e02e87487cdb2e9c424702e17b850c087c68a8f9028b1a3f3c5e033368e0624b039a9b2dad3f1e8a2fdb0530ac9abbd6cd3df8cdd5bb002be66287ec7d371974866a467655404f4a0b92bf1faa89d955013d3b156f595ed7f7be93ed079854a127b4fdb8eb1482598b40635840601f1a516db3efa26e8b22dde60e112eda197e4728861e10aada2e59e8aef1a5677c47a92fb779a6329db98ab4efe7f308a98aadbf290fd23daf389f722ec1966b2dfc58fb068561c4eb7348b3a3f072815593aaf9b2a73c867033ca09d3e809f8b68802fa30a72255b75a92b5eee9f5240b3047c8da99090ec03405e3b2a1fa9a2659fa85367ea7d73f7e68372e289de58d2cbda50d39a50d63d71a5483d9ff7446961ba96c073dcdfd36d76a925121a314e1740de32cbfbe6118e5ed6b15395ab05194b72f3e1e5cbdfd70fed35b9cb7cf4e016cf97471e55211ce4d0d51de7ef7e1f0f43d58082b5e66cbbcf5d3e0b5eee55e4a94b4054eda139cb4af71d2365a2b6def0ef39f2ff36594b70fce3e9c7d3438c4d5bbe34bb45edf6a3c2e4778cbd3e3f26b5f20d88735d7b742e222b6c5e318abf138c680cd74618d5d5745a2e9373f7396d7a61a28764f3956bb97d016e762d45cf7d123e0a89a4565eeaf9e61f89928bef54d5e38905d8265ca9b88bd7984e7ae4308795cad1e3d9906c327ba1f3c0e7be68ad4f7dc7a8b17b18a7b5fddab8772af4c145fb60bdcbbae5733d7abd96a35dbecd5f56036ec5dfbbd822a2b187624b128bc856d7754e639f2d42cdb99cfabbd1ec8618fb61f08f35d94d1f6a39ff088e761388f18a66a5bda64886f775706762dd431e1b354db3ef9687d76a2face15612df9f358087daaa56243cc093c43c09cecc9f603786594ed47d2e2e00b51e74a8ea9c9a3366f1a86d34860a986705b0c41a7fc579c98b13e8d188aef08058351963faac90e1ba6abf230a4e892506716d7485205a7ea1a5508923a2374dc6e18a3ecf97d326fe4d3644c458333b84c6fb2c776bbddf84c653b800681bdfb5483b7ff9d0d3adac6419652262f39cc9b47d4aa551c6c3f2890c7bccf6a55d40b4dd50b0d6b052a23f022230d02a822a03302ef32d200802a49db0fdfa9eb10242c086d3f7e17b5e066a45ed7a04b975cf7f01bbaa63a56aa74d7566a5a547ddad100846d56f56847831276043b5df49dbaa9a1f3dd166d3fa2efc62aee60fcb752f7e99c572964f5425485db974596f5b4d2d4d7e65fc16e650b36332b3b27a36b3050a14f86d5bd6ba84480e87a5e6b851c45169d227c5af0d6f75f693ef9f3175a31fdf94bad98fefcb5564c7ffe0a81c1a7ee3ec223cd8b7f424cd932ea5f6f63ba7bce4868d5068433dcd0b38a3c607424dafddf6ffebadfd905b5c3428760d0193a63da76f1f3c5752e45d4c10cedfccfc6c32c63799cdf4d483095721eefeededfdfb7eff7db5c4c76f73a9dce6e7e370974b1a78bfccf1d573743eb6d3e17c09143037023e0f7c6d6e6a16aa2af850f318f84f6f87024f8ccb8d9a33850e5771f665980dc2b6d9e67cf7d926e986e52572aaa7495eebd3f3b39572d6ebac5685c3f828058639e25526d43676083cf296ba479bea08d2915b4a166278f777727a99c2eaedb233edb5540c36db29bc3c5037e9eebedc8abc350b82a74f7adeb9535b951999598159a0ef4be28be8e366cbd3fa5a0f284155a376be03fab309aae9d775e3ece412ab2db242409c37df563f727d04aa7490ee017bcd611b24a60527b6b85d45e61bb6ee14b19d26831488798a3f53e81daebb4e228744303b0ea7408ff74a8e7519f0e864af291468c940fba439c10708f3ca60f673751d00e10968374887a493fd1a2a40b142744a591c16258d058179a15e19a8722eb35cc123426db49c1dcf2dacd889fe38d3ef3472fa24c8d5ed5b6d63a06cb0dc286b7a3255a82474bdf38aedc621c570ee8d0e530b4062d5a03b3ed2e97517ba78fd6ebdd5e5947a170d24cdb7776beed86d03e99dd44a7059691f151929d26338a17241d748da3b44569c6df746aa499dd91698c16425026b3c7c2d09245a718cde1846aa73996089511a1962aeb677a054728d64964301aae2bb6d4653ba7d2b1074e2fb4e3a204d3c162b8e1ab1f2d850175cbb6694a77bd286ced46e0d826723845d5a84d7f998cc731c76216a7eb1822898a2cd608b5c5cc55b7d6a6cbca8d8ac2ce151166fde0d5ac2edc7f537f92f1b8e850552d446d0fba519f31a3b9a1d1a14bd7cce4c60749f10138d6ac911cb7d2f707c95c2ec0886e8367e3e3c3006907e4c9680a6d440167c18e7a8b4bceea8afe8c695dd97fa7a8cb8c785c049e8d966bd4ce9247be90784a647b62006e7ca76e40ce6492322af08c381174d906be95e6b7ac56a5287e24cd2e9e9066075fabd0bdfaf3a0fe1c92a5a600ff1177b00e7d8e3b8672d45de35b22a2e5da893294243e85830b1f57abc8f77a7747ee56ab2a567ccdc78f784ee6ab152f54ea9c061daeaad8ad119e92e96aa5d67de9461cdfad11961bde853cbc2a40ab5524db5e0a6976504fb6e782ea44e28557ab0e66249ab67d9aeb6ab54011c553b48eaa3cbc4d559da2ae30f4223f743cccadd3a36fbcbc1edd215d34b7a2b211c2aafd544677559bece76ab0de50c2b02c97fb5653a8bc3e2620a62b680e621e5f10fe14217c19811a6a8080139b477708b5397b2f9249d5a0fdb4ed932023a97146842f22850b6a3a1e5485c12a7aef320af291e059a6eb563784ae1f8fdb9c5d4056b90d750cde45f28d8222d70855bd717c44f828da90367e0fb3f408a4b90a587b635fc81b9279d6c8fae5758b688b74d5735178feb544fc08ade303bcdf41eb4858f2e28636f6b45d50290d59f0507bfe27dd359e278bb2a0f203b0e4dbb9e4200b2d68be98550b74f18daa542642ea329b6c79cba1886cbfbe703e3b5bd4094cbf8b9a1da40b1cb3fafcaeb6bf542344503059d6585dac973cae6e8b4d5a7d746898477fb4e8776632b04dfbdc92360d364f896a506ffd6942e507b8f06ab2e7b5e2e070aba9dda2f678a265c3bd9d7f0b29c8adc3532eab2aa7ec8382889ef09040d1f26f856e9c9a72f3b6e91e9c6543158bee10d89cab63c9366edb26c1ac6c49bfa852f0e6c62be931eb2f3d8a4bd5fbddac3f739012453f904e1c5c739ed1c4c39867abd5ac78d02e609b7b84da68e3f299fa513354475183b8634945de5379502ce435b1d75e1836efe15a695e1725cfd4d158ada2ebcaf1f02abb7264d779db572250bd25237585322030ecedd0f64317edee6101d411157f54f19edbb7446aa6e9ee5e2b6276bbb6182a7631918665aa8a085744a8a13e75228a1a907a763dc5d4f302779ab72b1a08da874e6feacce7d292030cb5d9966e77e9025ef6db4acdbe26835fb331dceed7fca154b32ee0657f3457ed651428a42540b69d66b7c74082433d25a7ef059fabc79ab30bb56a255b2964def63535d4d999b78d624644b1bad7efd59d097c2bfd3455cc2d6bac6ddb9ccddb794d3a16ed871dd67ed8b5d793683feeb0f6e3aebb9aa0d10bdde8852c1b89f13b28a16877bdf63db6fe0d1c838d09002cb82875ec5b6600ca91d5d491bea64e741e31843faa3f9330bc8a108a030de66e16fd5b953a557fc076688d2e9482f5540d9a2f52ad210cbd2a5cbb5e9f4f0a4b2214d485c0c8ade936f56a42951be2adc2e39c1fb3a2ff4f7df3a1f44dd1e3f2374089fd04990d757f596a4b89307b79f6fe2c6e1cdba4c68c36836254ef3d0eb7b1535bd2cb920a2c8bb4521682a5ea1f470cc556c5ea4475f4ccbfd9be4468a96081033ff153849620f3e61e0210be28ef8aa3aa3a9386725cfe3b47ea6cbaeda36eb71ed0fe99bdb840e1cf5e51ebb53e24ce1f46b7fd1cd37eabbd17b7f71c5dc6c22d53fd1b09b5b97df80e9203ecce8809f81a43fb86aad9d554cdef3b9aaaf9baaba99a7bdf6baae6fe6b4dd57cde413857e92f9ea06eee7f5ff6f9a2866f399d55e4b07c7da5a5c275b82194ff37e4335d97730aed292a7378aad3f506a14c8d2558e4b4a19ee2910c7aff63f7bbef1aff2b4b4794e5b4f1912623d9b8ebbe6877f7dbddffd1f8ae21544a7b2ef8780195b467296bff9dff8fc6772af780cf1fc1b657231aa1c65132a2d79cdfe2c6311bb5c1176a2af34672739366692269de369f8171df9c2fc4883646e004366f982e8c1b6aa002f81427c79736b971c317aa3a6060a82a3e1c1f1c9e5e1c366ed28c9ae486e05c36c6a9006b028f0d85f8780d4941a9eac0ae5dcbefc1c2730d1b48bbfb0f43fdaba02b9c12de2fa2ead250d342f5090e50fca2d3edece3a4b6945ace2433855ee0456da11b914cbcba5ee2acb6985eb6ab19bc7050f2151ed5b72ab89a1ba18b759fe37c5bb1bb746c8b755ee39bda6223cdf8359575f0b87e105cdc27627c25e88d29b987e7f5e358e473b5aea6d83e9ed6169bd1193745bec777b545b2e4cba329f202cfbe613953632dbd244feaabc10696d00d0dfc9d032360cc47f92e15828bd698aa3d2bda5339cbfa29bb4b449a3049821d8a9f724cbe43823011937c30544599aae3d3c7e3033e9b7346998c7c97e5f61e0c4e5206060eccc9840e34fe7fc10edd097a8dbb344f6523d8913b01788602dede22cb1a339ae7c98436b800b30d2a9d71d69ad9cac6f4ae41d95d2a388317487d0c1f42fdda4174321e038c92648d29cde6378bac719f0896b249de0ed6dac2e232cd4fd46b4e6bac6437bb6b4cd93f0bbaa06028f7d386a93697ff51b3c22fe4b60217546e66aef135597a88c67dc518079fe7d6fa86d9bdd6e086a03739b9d661fd920bc256ab4971593fa8065cecf0bf5ef3bd679420cd6131ddca93e51adf970d8dc068c92643519bdef08cc484610d939186a17ac89bc49af5d0b4c4c7e8d5f708f5fcceb52b136cfcfe638903db8b00957b77532c66c51bfb66b5dec2db9a03ef7b55f58367a4d16bc6d8d43cf47219bd6f3cf46ed594e7522cd41d4f0eb1886efdee290021cdcf178256e6b8a9dd1c5e92a5a1b76b8be3f8c272878a1196e976f88080c3e466070b7aa37eaeae729ad910bc2d71b3e36dc4b312d080b95adfc4d873d514ecf426d20b24b57b36f58039aa90023c6fb44f3f1542d8cbb9a58f60c72c08762082b04417dabc85c442a1ab0755b2a34a8df8400c891c88a1e52054afa8d69e75d89421aeb9578232e3d95781bcdd375971478e885173521053a797bfc97af9ce0e1a0df26151f320dfd91bf6bcca4620011686b43da637c92293aa8f79310319a9e438b2b1eabe1d4506a330a0ceb3677acbc72956819862b55409acd402c3498d39bee2f78c8af8b26d967eed23ea0575c21c2eb2718c0874dab6450849e1fe3b27bb7fedeeec4ef02919789cb3b72592fea9336ba8b94ba7da24b073b7d716345f649250ccd5829e0b7a933e1089795b55089618ed1d2320bc609274305f5b62377cae07ae3f8e25407c31c3e6c35860f82ceeac2bd834b5ad1bdbc945074c82ee830edb6eb8a8ee49b7f3c3a9f3be716a9df296f072ec7b28579f1342fb9db8c47b3516750cffd490ad7b1ed4db246411861e7d882c56ab4877c7eeea66d71e2db0f999a9530f1b38bf4fe5681a2dd07294e4d4d2a162881862790ca5af054d6e7b906eb6436cbe956e03e84a1a297cde48e0c3b5dadb9903c523aeae503074d10fdac1cedf91c41d143384a18719e960468afc98ed047180b5924e9aebc325112ace5ba7372a0c278d7676f44ce584edfcad2e8ac1688847a897ed101a2d700e73b9b647d7cec76ab5f17ec87e0e1318e735805394935918cac16cb85ac941f0bffe97859c8221eae7707fd6892eea132d496eee25855d757a4db8cfb4b718d41e73467b4877972c34c3159bd160353c1841816fbba34916e64913700762fbb2ed7771303086a9f4853e54a545df7cdab84fe5b4714b1ff3c632d8a9b091b5d22c6e0468275807b1c041503853ced611c54180cb8cb5bf7df2e7d33787798a556bfd4dd98465408238209d0007b10aec0556e4217816ec4441b0439195158c7607241eee4e709ddb60a9dd06af236809c5b22db9912dd97f51a2f418790995a297c89d6d2cedc1ded929135a7c2cd8de1a9813efcae851f2f53a2b5b9ca2fefb88628159ed90e81aa1d84c5f1846eaae0ec3a80a176d7b0adaea07de0309ef81eaf68d7913a886e2eccb40db3ab0566bcd77a2268c6bb5926108bb04e83c6afd82208625812976cb728e8367e1aeda3dea0f43c8734e5e22ece0d23d979220e8e9e13130d9abaa665baac5ea1e3dc192bc8d244ea112843f4452bbcaf852016b7a253a8fa6447fb1cf9f77475601c4fdbd2ef26c72a90f8fc8528352fae3f7693e4fe4684a45fc05fb19ef54ea016737e9245e5af4ce00597eb933fd16e3e3fc82cfa8a6c353f17624533689dd2814f690e4793a61b158f764fbc00211cb5932df3052e306e4b9fdd17b75e00ca9998d06d6cd314358acf1865faa27aa53d37f0cd30f55b87acc229817b66613ab0fa34d66114c0c3264582c391c881a5b3ee50148ddf0b6c3a2fd07658f1b52a3eae85496bafb7cdf5fea3596ed025abec7b27d642812648165fbdc5013c84845c062812d7b8865fb02c812277c4c49a6a266f9c91ccbf6d5d5c5e1c1c7c3cbabe3d3cbc38fa76f3f5c5cbd3fbb3a3dbbbcfa74717875f6f1eaf3d9a7abdf8f3f7cb87a77787574fcf1f03d39c2b23dca38b3e2e91bf616bd152a8f6aefc54b4c8d895e0e6201d89c75047e6b6ee92398a855574146ecb9f701f2a5ef2faa028be38c3820f22b70b9be7e14dc08384519ae8527bd2607e8bde05bd503ebf35ab03ed7607d3ef4842b06f9300c5daf467d058fc72a555f12f913507fbe0deacfd1d242fb7921867a433ae070f306a0fe1b1feabfd980fabf7e416f01d833d8955a6ccf681ed4defd8d620a40cb4bdb338c2829dabcc157a3241b2d3255952665bf4b651e4b7c65d653eb74d2727c4f25c8a9a0c9f84083d0f8dc10cc34fc73c059be9899d81ab56daed7748eaf2c204ed56eb49f105a8cceeef3339772645c30d64833022f475f43be47314092a9ba026c1d1fe94d8d97f7d243b1c68e6a572a4d37dfd5b155c9d797459aff9664e9d8f6fc0a6b52dc9355dce12b352a35a9b94ce4228f5b5d7c655018d79f199df1afbcf1538bee8df86c9e081a173ba00ff0ac849a406acad89eacdd389f22e417d22478f3e1531bce7e67d461bccfded3ebc5444b4c9628599079787343474f57a98bf8351ecfe60aec4eefe84f091b6774e3322c57502d6e4a99cab4f0c237f4c32fe8f7e664dbe2d80f5501ff838f74bc18556508377a6d4a953b5bbf238b4f6e14a2a98b560966d5c29abaa58bdf5191a79c91c0b03982352efe7b9259e2584b9db2eb7f9f5898aa58aa25717ed704d3836434a584e35ade8e87056bf8109c87c1339434091116272ec99a6759ca260df5185c3ece69de001173859ae586ff913d6e11f4a68dffa36ed9963a3ff9ff69cc93d16d32a1edc6a79c16f5b547533aba75d10835246fa8e74855306b373ed264dc9871411b896c18a1f99bebf68cee2e72da828f5b452b01322a818b364b669480175ca099377e4b7906168202bcf08813d2f7b5a809a6ff2c5241c7841a41d06502f012c5d79c6731d5140f8a352e1f53ac31b298628deaab0050ff638a13a6be83efcf6e62890d1327a63674a9af9694e53261230a85405fdb560b299cd1e2173e91389f26f04b1f92918c252e4f639ce28d5d11f342c2bded4a1286598d6066692f169b2930f09581aacedf5e5c5c5dfe747c510b5b05db05e74bb8d96ab579981c860d251482bd413bb538a74102ebc44bff3dfbb1a5a9eeffb77120bf8df3c889f806ce635a5baac2794c6a0b6d701e17b5c5ea388f597dab55cee3685bb132e731af2d56e53cded4964af24736f23ad7ede2f1b6ea0c00542e3daf9f9b1a86e6b47e7aaa0ccdbb278b5d65696ec6b4d7c1b3dab225e6e7636d9112f373525be43ae3a35bd352175fd70f73c1c68956e635b5bdc4f7b52505cde79cb955ebbec20ff5e31cf1b99d8bd73d9f93566264d551cc0a1f4e16dceb5912aca1bc724b93a5068932e9379a223bb68459f8c9f4cf42ff4c6387d11bc4cbabcba7f29b2a73fdd95cff3cea9f99fe196dd66581f1f5da90888b84e275bbf50d8644141142c66bd97eabb630a0d037808bdb7d0a49639da44e82c31ff222cda11d0a3db7203957487c01dbcf7d9c3ec1b2fd4181eb8f58b601a69b29c41eee0b92fa087f5646ef173e7a3f053cc0ebf826fca506bb5a9961de68c4a132b65b9b581a5d4d5da6967ced7fe086befd8391fe609398f01fb07eb8aeebe8299cc9b63b3765eda46f2f99e8921fea11285bea5197aa80e0d552335dcaace5f672a92967177a7bc94c97f476c1f6b20b53d66e91ed25a79b58a4027eea96a72a374c57ab3aededd58aaab9d43f63fd93e99f85fe99ea9fbb821552bfe45169cd1f57ab527c56898f2af1bc129f57e2d795f87d25fe50894f006d51d1b31b72f8df02518df9ecff46908a451d2df4f7bd11faeb765e79985af2ff09fafc5b411fad75ea135993686fef2542beaaa8636c5843ead653ed863f8e3a771cfba827c5e3521a0f1b0c8f4aface69dee64c37adf009cbe9c586319d8314be0e8fc9d2142d51c033d2ece011a1be5ac2bcd2e91cdf404157efc274678c5d4f351975aaf3eff4cfaca293f858e595a971af56c182dd327ecf5ae0b346616fe605bc4cc4844a02062dcbe7da746d81c7780a40d3dcf40824698a4ea9d956ab945556a9fbfa952184df9151af3465ab55946b7b9c7768bd06a3199a80862998d329750de8725ade0bbeae4a5d41eb9e09107570af2d10773da043ccc8c453f3d02ab2adee1b862a3d7efd0268f72aff509d0d2d58dca60f52242309c2b279f5134deeb78d831cc921d8cb05c39530db80525bf90b33ce94b08118e205910a89514dde5629ecd946f75ee30ca1deed201b92d438014cdbf36992d3f1473a4973298096719acc68aeaa1ce9cb86ab4e8dd0a8da004761f8108d067c0847a6c749b36398f66d51a9af1f3d449ba9f01d56dfa1981be98726af76fb15166a92d63e0cfae071522e077458dd3b9d0eccabca22125fc08f379b03366c8fe99cb23165a394e6b03f0ec960886fc9728d2fd59f8bd23e39f0c4da554f4146404d0cadf70185dc091a48ad557dbd5966b5ba1ec8a1a692a537918a6c0c640f4b847a2a8b08d57467bd6661781fe9c37c469a4f8856af568eae5c5114dd9e53a6e8237ca54fcdb9fe39ad5c176f0d4244c95d44d136ab2157d50bf855072167212397c6605b4fb33f14a284af222fc370a3d44c544580cefba77d27b5139f92011dc6e784faf23bd0ab73cb463ec7929caa053925664c6a0c584bb2592d52f31cd29d1df436926a7fadb7c84e346824abd20996495e943029be48025ac202be277fe32fea6efb04bbcad75c303cee730dd811424e57abe82442f8634957eb9d77143e21bf4dd4fb449a9d9e67afe4bd2550dfa42cc9b2c7e527a3dda7dfa5dfc8eeff1ec46f5b7f5e25ad2f7f2d3a9d834e4bfdbc7f017f5f41e408224710d93b3afa6bd1d97f09c5f65fbe87bf47adbf16dd2395b3d7e91cb4e0e7bdfa0bc5f6baaf54ce4107224787477f2df63b9d6eebafc5fb97ea9ba3d79073f4fe4045de1f41e4e8e8fdf0ffad1dfbabd5eeb45eaba6dfbd54cd74749b2fa099fd2368e67967f8ddb35dfccf5785359fa99be7f7d2cdf393ff9c1a8022198de85ce6efb430594ef6b47cd4befe79ae7eb410afb364a1ae5b226a12f37932a20ad7060f8f8b5c7ecaad51af47c2b013195671a8c4480e03bbceb492272c95e917fae9e307235bf8590d21b04cd4c63861132af822cf1e2fa83c668c8a9f2e4f3e340cdd01f84d367230a5a35baac06a5b2a5fcce782e61a6366f2709ccae43aa3860eedb27f7a1ceba7c565c8c78c06e0444d464123d86270e3b37a1d18bd8799eee066176bf532dcec82dee96010e8f93e982622a732c026de1a9984211e04a32cc973354101d6614855a0f7111701c80d9b14393ffc6791de0518c22d0a91e1b0be73e6921c7486bdcf60dc13fa297117fa39e80ecb5d0d46e5390a3068924f4c389fd32c8309060726d982065bda2d4dca1e34d696fc03bfa7e2406b5b95db4d16927fa47754e4aa1dfa20a96049f6916a3cc731406022468bdcf4c7da867c9bcda7c9bfe84aa9f120c9327e7fb4c8b20b3064de00626a43f5e848b505a1f32c796ca8c9113ccbed5653bf5434c629f4676c03e7e9482e043d6626a0d08ed929ff4d33a968639a8ec7943532cee70dc64ff8789129bcc5e583e1a179963ce6c72c4b195538ebf88c658f0d61a6a121f4548d1b40681c37729acc329ae78d54d2d905101fffddbeddfffa128df4c10a70305b64329dc30acc161292729a8157c76f5a847ddcec540f4930d2f63dd48ee3f72ce3c9b7d5f5bce6c005239ee5010e04bf573f5ad93cc8e709fba62a5fd45529f8fd85aa0007a0eefc4d157dff95490510e647b23bf8ab150fa341d2fa3244bb93e2eafec3976f1a74876dc93fcde7b6a6355c234cb6b46a6123c9d209a0b9adeb24a7b07112915ca7a3163808b289ad7c9adec8c62899db0f47593a6fcd1339d521a1b62378f56a817992b9e151d6a5b56ed24c52919b3cc3fa303161ed2336c67c96b2c4ef99b662daba4e46b7130164909b34cb5a7c9e8c52f9a823d0919b8cf3710b2a3461578633d9ba49666966c26a9d8b502b19ffbdc8a5499082cad1d4461e3353d0326221a23d933726d9e37cda62c98c9a20172965528f77ca45fa8533996435997754c87494640d28d54ac677ad0713e6229da4acf5d04867c9847a53935129a968a96714a2aa0b299b9811cf12714b458bb2b10dce5217848dd8e07754c0ba5a2390458a9ca6a35bf086394f52265b5c8ca968cc13c673daea36e6da8b42cbb8b1757d822566b201ec5cafabb9e473d32f08da85c8a5486fa902d1179369d18d7272d1975c0a7e4b5be3249f0217da4fd00af936450d6294ccfde8df3c65363e4ba51ae82c751f783d5251d0bf053b74ad848da65ce8f0988eb87ee975bc182190e9ca935924152358b074c4c7b4759d8e5317110a46513199b7e66a56678dbb56a21ea66b2ad351e3ae354dd8043c7eb5d231e5c65a50e3ae354be494ce12bd75ee80d0d7a22079d2503b0af6d1a30eba6de4c71e1bf75c8cdd16ba1729eca0191f536300f0214bd96de3c11cf8af3f0d16b5b2a2b83fe23f501dfc507e47a1953819c9857ac54c4c8c04cf6ccc0be6537e6f8232952e598185ff8dfdab3169d87dfdfaf52e341614b7fbc32c8bd5dd14600866099b9820c0b7db6efbff4a3ffe38f9a0faf26a975928daeb8f4caec11d99020605cff33358e96f7a74ba5f7bc93fb761f43f097a633e0a5c42a03f374b398594afcd61477538172355527f9068fc1d80d6d95b1df92f76bde3decb5f88f80f646a8b47f5d7423f4993c43e6f1256fa6a0d4122af67046309ef832616e02d71538461b4e710fd308c020ef61b069de16a159cd93052394cc7ba2ae7d4861142ab5554a5787a92bdd29740a9e436096161083ead35ffd7aa9c3a4eb1b5b6aaf57d1c45456bfc6851a020b6de57b5be8fd52cb2c96a88b6b17e935571c63818273269054d42341fda5f344de88e3af87b84c230508f2c94a4a8c22a6e7641e7400f0fb90e812d3837286fd4c80c90f97cef7d5b998491349ebbcad564ebb4ef2d2b3acd4f93d348229dfca29abc5a757f906bd7b9484ba48112213382b562b5320415dedf64d6359bff6802ffef98a2d5cac69e6150def8ad2d692e238afabfab8ddfecc4d1331d50a713ad2389ccb4836e9435a2e70c184612c5b464d2309218d42650ccabe8779f0e7809f71e1257f37ed36ee6300c8298c59124bc8cd963514d815b0a3fddbb88917d4248c44df548d3137818363b5adf2b885587b1e8d3aa6d4601c4a5cd013284105affb26151ae5e31038ccbfdd2aecfac288a20fc74ad9e56474db55e2ea9e87ce8bbea67b2fbbfa3f67768f0d75f7fed0e77f19fdf28f44429f9f31ba49e647db18ad813ab2fb521f724eacbd5093ef12d0d57259fd2ade5caa24f497db9aaecd3626bb15a99a66ccbc06b849a465bc65e956aca9f2e57166bbaa92f5c926b1ad797290936cdebcb94259ba6f43fb2fd70473d1cd36a45d5684a522d575ea32549c99486211d4ce970b5a2553d49731c5c7b336a28fe150d23ab17fe942b1f0a06dcb204eeb2d58a8238adbe8ce1d30d3189427dc90a399917835173ef07563825d0ef8174195a7ec424f322d96e719d215c46211d62b2464596dd453a23dfc8f8a076cdba562ecc3e781b925989abc5080239c50ad34cba51c08a0a9902198d0bf8154c5e5a692d22cb332dcd4c0701aeac4114a8675df683422028023e3d0a622f2d30cfed8ded13ec03fd3ee89c79394777c8e48d690c2ca22ee8211ad5893e6dfb9a13c8fb1aad7d25b382354d0b903d087a63bea44ef8ad2d938983260c10610004f879a97fba1dfdfb3ad662d841a035a63d1138cbf7be1ad3ebc504b4fd405154c72f809c8953e28d5fc31518e02d952e743ac282a438254180793f2541234a6423d8e16db5ffd4ec3bace3671c0468278855a6c2544f410a1cd6402b56068d4873e540083ed8612a0f614682bf58a3d168a4ac11ec4462b50a3e69367d8076d2b5dc210c53d81d6a36d7f7d334a39e2325594ced04a6b60c7c9ab356c095256df3928af9a6527ac192dc266418041e4bed9afad81818d0301691a9b121ae264c81a26042561b2e2b41ac0a500702e7357f088cb6b848c6a906eb3d76d93dd59603ae80fc7d2992d12d15ab555449a9515c824ef61d1935360474cc2c576742a50788bca7f948a473c9855626b6463f0ae60f966a8f04c18ee311d7f0913d8d38e65b4b71570c3849da92935369b1242886530289760b988eebb5728d2a787e3902b0682192eb8cc6cd0e9ed03a9ba1dc68f94dd31c81ef8fb20a290c0ea74521706e82f013ed52a6ee406895b58bc81ae1e5841a2db7cd7e0868bc92eb7ab0c6b9e47358d9944dfccfababaec570b4fb1cb52aebb5c26f7c76eb03adba7a68761d2bbb549936335f20459ecb5de868a457dff3581409b3c968dbecb27e20c5820671709364390d6263dc1db40305d27b22021be9ba4a8a00d52e0496a9ef914cda6a9df98e68b956935e66bd196d34ec73e76cda9d1f31b5191d77d667316d5fdd8b643ea7023496dac61397a978edf5ecb6d4338333b7fd2615a6514ec17a819ac540fa2e5414358df5189950ab16aba7ad6f7e638670a5a76459ee6a2cb049d0c3d7d64804cf323a8ecb378d15912aae1b48e957ba1a97bae25d7e976626747e248b4f5018fe1a515c706e24d080dc9717e64b5383d961131a49bb4d84e94c8183335498d726a20f6e9fd4c5a2ef54f84c81661050a54198146204f0d4d8e541bc9a5dd8bcc817d7b314ae6af53081e6104490aff4ba89829a5b15f5360d909b9cfe190c578b8430146f16f4f74c80c2d0ff0066c72f8010b6bbcfccb395a4adee28186b3989349bd552be4d5eeac9666c1d8f82cf9e1e8195252ad6b2e9e6b74988084333bf4d986c4fb11b9a7092c1765b586bde126ec7fa23ab0f1c5bada4bf31dc6283c75cbf9744ae01968c18d180bdde395a632ef04a1733f7f46581a13a56d4e2db2f397333ebed66f0f206aad7ef9d070530cd6f25e7013532980beb57faff95a988cbc5fded5fada664e5f58a96c585088f96562ec2dca36b050844b206e4285e07e14c48383a2c2ddb51280c8dc81da22d66cb75249d263bd20be214dbd50a7a269369894aa9c02e3e573939b84b07891423a4c849a7c70bdfd97c6707c941f02cd861033e1c9266074a6a4f4fd4972ce66473a33f53d00f1bdafb0ac29617dd04b253544a231c611e86c2a69bb9bfb0d9eaf55357d052f7210876d42380b0b1fba4fb4efdbec37007dc74c1f37ed780d4bca819844c23dd34af6d1af5ec4953a8b42a63440bc0d4934a416b5bc23cdc5ebf3d2bd4d4d9cc735751bd084d5558d2b37f621ff7d2935df7a6bbedf89523e03fdf6f2b8085f339634e97ee3b29b61f9695e71ddbf7c81b6575347b5a9cb66c75876939c366d4fd81d85db821ebba8f00311b74866b49d8dadcf0205f1800ea24d7db20003d37b06d7c69c3d280cb6fece69be2d9c5d1bb9029608ddafbd85da3ac787cfcef3d2373f6b6a9b96a9879ba9a44d4de43bea3968f650c4b6b2a49ca644fdfefdb575dc1067abf7a3bb7780640dceb6f5ae77c4c7399a6729605f8b8b684734f5610b44e7c54d4e2a0aa88c51b9faa050acf12397da234f0ec4e1239853f271f822a62fae440bc1df1be7cb31b82d86af574056ab6fb27406a7f6a2804f478821b2e683a6167ce7e98ec3f5d7dacad1e7da1f853ad2a926f90cea08927176fe7f330849f367da0a34f2c4f6ee8073e4ab2235343c12871d2ad4f968f6a4c06694ec01aa1754cd7559f282044ed38a99f3e1e3709395693e9c4000310b6567bd32410d973377df485922f74b5dae61e769cde050879df066ff2bbc90fc18e39c56737112a0c8ea19de0cd2ee46349be806be55cc2fbdb2b4550d987ad9fa765fa7bb252dc7772ece729acd85349392aee7f59d888f7aa525766183238ba596252c3701f588ad6f59b0f6947ccf78586d6a53b8078a4a077a57b6e59a8f70f2a1497a10247cb9cde41f03bbdbe4d65b0438724b83761a9324ef8179d3a530189991638a66499b07406c21c948de377340adeda840017e143360e10766535893ae56cfb17c7b688ff1d88dc6cff067c2a04483bee4cfd4e5dba94007b11e8d61aff43c9728d9fd192e0eeef9652f00f1dd0a15d0c880008ff9b9fac0d4348cc082417fa05e02793d5d18520fb192d554cd8400e0bab586761183da3e4c953d106712a7faa41c527654e8920320491df68db5fac22826b0ab8157aba182c481145a5c9ad76a4f8beb4405e4ce3c03f51f23b8d02bfb301c29f2ba9a9b7417eace4e56623fca1d34bcd0508ff4249905c73211ba384cd41b454ff1a69a9c678a1abd66e071a743697291d37281b89c7b984d058fd0535b98c27633a1e273231c11995898b6a2931f07e0442a5f0276593c65cf089a079de1089a4a6a19cd25b1027a5b75ae22bc932150746c5b821d319d5368e1b773c5bccec67f709881cf9823bf85730595cc7d0f99d26b727c9bc6f7ee39364eedd5d3f7b90c6afe036c3a339572d5dd1fbc64932c7bf02cb182e1e85b5b8bafef4a116cc08d5cee6930cc48b2545e69235f82c92c485e169a044f6c67cd96992a8dbd97ba19aa4a8ad65b32e9389960ab09f204c5dd811cb2d2b625fd37592499f553862303e75ccbbfb9a2c9d4c0a406b46673cfd42c70056f9c65d0be10cc0b58a11c1bc543e74701e71fe7715bc380581773aae679748db2f98c466d5d65c12755fbdf2115566cb37235a838a7a7d3484cd820b482249a0952a180e4d387e03b80c0336245d170e81291644f67a059dda2c60513b47daacadf56559ea882993fac2359120dc2e2a5a32227a23ce64ca16740d35add39bc89878539fea90567653f58ff413db832a531f239432e20843bba94fcbd2e9b29792b49da7d759ca26ebbac986abdc10840911b68f8c702c485a8033da6452b38b33d79d4c77072437d072a1d051fb991b53067dd2998270cc5c664632d731b57a0b3ddacc0ebebefa54d5b2adfa54b5bfb5faeae85f23b4d6c377ab077a6f559dcf8e9ea5fd26c8462593a736142b34c4accea7966b892510ed4bbce9426d9af6f458bfb7477ab57a61836e41b57f5cbd31ccaf592d22b1b478ad5e3155148c91ea6d0a775253da09e9593d50fdf96a6543a4ca3e2f6eafb5fbda356a02d0b69deafa832f6489784036d0eafd8e3787c69cb58c374cdb56cd39f7230a8a76468d17d85714c52635d2b18d8f067408021e895428cf806239f4bc934a4bc6db68dd79858bb44c51184acd46022fff7015c88a3262626f30efd2ba1a1bd121eba62657cf48917c6cac64e59b7406cf80b5209d9ef0c4059b545b9e9827130337f2f99c8e23d4133b3b08e66620869881ad77a088cb30b4aad5bdba5e59b3e49b1db339697e4e450ee5658456ab3253d17a41a23ecd62213d610d6319229544c8289558bd2a94a412a7d6263a1485254924c2e90635e67b4d8db13acc94dc94b4d77d9e46260b9c538b178232b6ea752e460600b5ee4b517bc485b1cc93b2c9a7dc42a8602d996ecb45583fb816dde9d3f63c5197c029183bf31c09bb97edaccab28b280157b214a5ac61c164f760ad5651249f869e5159d68de2c03c5f0a8ba893e8016d522cb5455359b2bc7f23356b5af2f9077a4733302762569f81494480886d929e52b54f6c0aec17c985b5e7a0cddbe7c5becde5a681fbb12c517e5d69fb20ab6fca26ff4bfda3986bc5ea8bc75cd2d951964c7230f5eff758625eea6e61ffdfaf2ba6b85a532cb0574f2c71514bccb01b6f3cf01d47cf6589d6e5bec04c83836a27809fe062be60561832cf9931c6a136bbda6242bf0c44f8ef8d75967bcc6e78f170f7848345857bdf7b82ec374d351afed95a93b157a11f92ef9b0059e977300c5f18baf266b73123672c12c840ad0c9528f0d55d01b4f82540743667c086c6e4b03ab8fed2a11e1881f056c98061a552609bb8ba763dc35a8c921579f1bc3072a09d88e08c747ad99b43dba9cc3a051891c34136ec8dc2301a9151d97a024898a698e304b8190b75952df008a1f542460bffea9b4a8ff5d604fc1914d4ab8445ed5737fe514612db186e7690ef490134168d60cb75b610b6b84e07017a9d00991007298bc82468b16393643e8234bf91915a8cccb432ca784e83182eae3084ca69b5572903ab9956fa46730375443303635dd852375b5d42c82fd4b36411869f8d6d5466d02f6dce1bf6ff9dc433891f259e4875c75fabab0adf9babc6bad13834bfb7052a7759042fe09b034982195fe474ccef5903428b7943f2c568aac7acc3809eaa80c67793c5c3284b47b78df175a60346dbc97c636250a7092fe68db14826aa22f5abeb190b3e6f8cf8ccea03a95c2faa0bddd247a8e8963e8226b10a2ce60d90350215a36308c1aa344c07467cfed8182d14669e4bdad07d34e8b4917b9d51b668c05a34ccf2f8f8f5997a1e403f55ed12d375497528a3c91dd593c5efa83021d59a1e2b24daf04236265cbaf9d16ed6339e5792fcd68b47e74a6e9a2c5882682a1d9fb198e2d20d2d376fe8fdbd152b5dd21c179ec4857724cf0d5c5a39829ba7cbec327fb3bbd93105dd1c05f1c36669376fa6b49dbd203edc2ceccda8295ecc6b10df2a443ba39246ea1984f4e371e91c6e4cbda9a56601e2cbdada7cc69f2c6bfb6f08f696aedd2621693fa2e44a46c537d863d3587c58922ba6e0d9309c2930dcc2edd5b55c11814bde6ebd87f48c45f62d459e4687a314ff49a35206d02d8124e29eb0128a2e0995112b9034da769b8e18733e697ba10ee87546afc482fd9ecae9b948b948e5a3c2394cb0e49ce05155b94685ef987d4d6bf1314543352911c7fdc6350d1d9eea6dafb496585dfb5f9551b00f55c0bb285985407f560fae7fc6f0e6ba60af7d5c799e6b9602d6da47f034fb70a6260797e7d9b9686f763c5ea17b3b3fe80788b95debbb9091912622c003d1ebbcb9767653acad956b39e80c7bf5d3b02cc85f57cc5f00b54bef8066580063fff569b273d42f8d3fbe966d50a78e1c5ffe5e86e10719dd8322cfbd35c66f321f74e603643e54320f75e621641edacc5be910d98f12e1cb52d4331c23ad39e3a27b96d55ade6578a2f01235e91dec9d907c34a5e34556d882f7f24eb99825993d3cf86f894a7e8861b31674c3a8e0691e03e40114196f7dd1f25846b0b69816609d3629576c0266013aa1f6011bf644696820ee58199aba0915e05aacc4b15a094c4b0b70ac16c04b3bd4698790e64d7779b6a5829215407c51ea6124c885ea1dfa7ae73461a75354e00cf3444c55d2f12be9a1b770dcacb25591138617c5a6031340e041f14b01377d2a8247920c34a721c0f6f7278a0b46c5211b07f8b39f52f0bdf08f7ebae66de1c0702a74e8dc853cee459175e912ca0c0d2fe1c026181e473964f91d1be171f957083092627f37df54483bd769072e0dac4c947e341fc545defb11cb56710927e584dccc900a5fb8f0c62bae1337fa62d832e59061d19483863b530e694e4d39a4b936a550c1c13111e38a12ff41b1c7a6826d1158b64e11f2a80defcc8d539cdf8ac016d92b6c98b121e6ea67a73bc4a92699447cd0a958b4d8e14671b48b502f25cb2db6e5e2e5f5e2fa3aa3e338c56652c771ba13d8b95c63df365b3c10430d75da0b2c966bfc09849eb55fed2f369c22fc5e0ef890a4ebf53b837e69e8da02ede64703ebe62f00f5faaf07b79bf0890e2b58df02fcea9f434f92c5c341194f19f3c575464da2878f1c56f0926472516028f0476303faafc63dec5fc0f4dcaf87aebcafa22de71efe724b1f3fcd1b15dcebbd8f85c1efa7b9c161ec5fe03496f98df5d8d7c1565cec7d192f33a14f739f57299c2f1b83241954a9606102e7f21aec43e89f0dacf1a00e833c2ca39210d4735d627aea88b9bf7cccac83b0da3d6a891aee4f819b1dba107d48f54a1eda80c6db54e8830b01aea602670e939b718bdd9db89042e32070660305e677e6a17bf0ad099f78610f3b3cab4714a1164de3b03f924f26192d7e16a329d40f21a8fd7e4a69a6ff9626a90b937424f15e0102fc2649e018d1191d791c700f8bae62dfdbb17373d1f9cdfe2349a7f78f7cf39b7bc5ff913b3bc85c07bfc9c13f72883b5a0ce099241e10f429a7e29d7a84533671a0d0efa522152c03ff047e77dd8d69a8254b4b8ff145f17f9465c3a99f40cf43c1e106dd759c6fd1df8b85d155ebc482fc213d8748127731f5d1cb463716e497ad459ce81af975b3cc9af5e9a65b7f89056e7650bc2dcb1fd51f1e6df8cb6a751259cf64bf4a9c922fbd2fd6bee071c4b12de98c0b465f488a562b302fe8aafcc5abf277193d93b8d473674ba0f8e2d73281fa2789cae06818b6ba6f0ea447d842801297eac3d78ef4ada9b57a1c3f17759718ce40ab108536437d0b7c6bf5ea9be6a63ddc42c7ae4cfc30e0f6bd24a71ae0751f606bdec1a38098d20f50faa1b6b44701b156cba1f4616de91209c472d91d7dc26292b7fa8ca5f85446b77a7babe5f5a719bc3ada5a6b0823d658835fbd02d25dbd974fd6ebd97528a61e2dcd62614a809761bd246ab3ccefa239a03076530293a5644bf6675967a023029a3a23998c0442c87243fe04f2babf553476506c2a3538994c7a96fc91566aa532e21e6fdaa88f962816fa13be9d68b1af4d9924933e7f924651aa9c1b2962876b15f3f5f464f95c6635c23fa527b5e7d00ded60aed9c1d760a6ea78964cd45396d36ae28502112b69bfa76339d5690f47197df0823f0abe989bf89918ab9eb9a4917ac28b96753457c11b53c98daee1de86cfe169b9a3367e311529bbb5b1533a49fcdc33d541d07e14e9f8ada0890d7fd4359ae0211b7bb18b79c2fc28881c9af801f4b01cf3bed6097e0526c5d671c399fc1d8c40a95896327a9025b3b98dfce4b28c252d08da4170319f267a7a64727d917e8171dea7637e0f895fc0641184389f417369969d153581fd362f9e4b3e2f4505bfa5efad5db07292b60c56a49d38e35f45da465d765bac3165c44997e260a6d0a813fe25c0c1998fd3c8aa7b36678bc7a931178cd8d52a3012d541cc562bab48d4f40a74b426f19f1b7a2b1485e19f724087fd280876246a4b91ce2214cb9d60fe10784255ac826481c968307afc98a99c3ac530e614beb48920fbec04ad5680302792450c4b859309d40b6e329e8068b83edbc128cf8f200959132d45c598a358217384afd7be13e93fe516435d9eba51910e0a417287b647d344bc95510755d040dace17d75a1f3cea22fca71cc821f9d37a783676a004233c5a2a5c2b9574068bbc4ccc11bb4e727d430873acd50f9d5d53382953484d6713f85140a50adcd2c70965e624c08956f8befa9d272281edac8d91c2fe17c908cadc43136bdf1d1ef365afd39b48b0011d3a627aa1d1a29fa8a77473aac24bfb2f31d5ceb9bf41b1c757fe713a5ce50a5f7474559b7ed1b7d5ba5a35a3e0ea0a540552b6bd5cb5eb2fba467acd7408b66f18d6340c39d5aff760d4de9b9b1493dcd266218a4d1ed8c771c320886ca779c514489030c68df9c68799e39ffad62c4d9a313739da88b77231da485b887423ed868b592237925932b375ced23c4fd9a405a6259d25ae6ed5685647b358178cfc4d8b8d97315ff2fe671a51f2ba24e0b25a75bb158997b8a2f0887a925c0ce4b0572fb904e24953198174122d79841fb1921bc8dcfa5e76784b44417bb24e83c44ac8f46dc068965544f03c43e4b4ac99b95ad1f6351f3f1abf199ebaa44e2efa75c3ac0f941e684995d42bca3a124e0abe1075f167180b0295f5ace177a125f5b4c487d3a1d07a6c7447f80a13663a317d03dca51f9c5cee121c2d0a6c5e3bd9a2eb1e256c4d63231ea2db106d461fe48516e3434b414a09d626c95aa517224d6b61bc3faca1e7c23f4f7316158f0c3536fdb124398b504f36ac2f487ed3a06d75be8f8f4432b3b3df434bb534c624cae6a13336a57fd78e02323ed272fd53416f0a47278c34bb6b2d59a35153683ca2a4f23d729e061c60e9097c4f7d8963b5bed6f6871f2eab9d3869ad308c0af3201003e3535a285babe8e73411a3692949d2ac145f88727c9ee4f93d17e32211c1570f523d56d6d408586980121503dc9ac47f675837335675b7c26a79e2d70b299db93f3d2623e601641513719db0f74a53b69dd5eb02572aacbc941cde96c60026a3e646520d628c6bf325365eb32ddc3b58e860d765566d226d7d743c3df5af94d85aa0addf3698f46b56277f97537999ce285fc87e11b49ab0f7b59f8c329a08fb911f319f15cbf950dc4e461dbb07066cfcc36ee5d2ec0d635d985bfbfdfaf8ac376faf430d9111da9e0b7a97f2456eef8b42b6b9d3a3fa8679557a280a1db271221300199e01c8b85a05cf9a2ed40f8855dd05c8b7504e92ad162091c1ee33036aca9d9d754d5f3690c55b464e12396d8b848df9ccd7b2db7f61ed4cee217cc94870750586d18e99361e6f25609f053bb70c5f14058068a5bd438b5ce71e14b907160bd61f168b735632a87fc980335d2854788c4c5f90b4c7f4844ac206076cb85a31f5a9536f76d2ec4eec426f7d0b1caaa9b221234eaedf1b584dcb96368bc674bf0ada8029565c944c3dc30c955e853a19f02bdfa2a57ab955bdab15554340abd5f74da3a9a2a50a4db0bb5f845dd0296c38311e0b197c6fd55db4fc3cf5e5e74b5e5dcac2e7fb3e6def94954ca45fc0049746f2164a8cf972d3925518ba71b8578056bfff5082aafc7ee9c7ca075034c03435149ea6286532221460e56c8e59121e67c0ebb126b174eca0240ac4d9fb82295497562d7e6239359b29b5454ff85d4d4a6dd14ff36abcb6d8a1263546823485b36280562b9510d9f78958dbb1e6552c8c73c15b9b199d655a7930b5e479536cd85ea30686d8b02a58b27ce5c0ce2a3ab4b7dfc512bbcc4204c6136d7104824812d81aac6d25eeb521d06d0eb106720832a7ac4e785fc8da742c11667522fde5f22e1d972c4dfd6d0f9a3607f04dbdf4dd03d2f65549f67930ecc91e624e5b4392b7202804aaa6ce9242aff346b65a3df491456c2087d8fa75180756d843bd32b2b0ff2177768ac286b11be0921ec2b19b751a860ce489caa3a93a060325b8fae5a916fd7f78514ef4235cb3229b6350c32eaf8156b3f04c08406da072f137d3a0e217032a7e32bf475590f11dd31ead8edcdd75c4e0e68229269f14626317077362ac0ca5acf185f5bf306300eb0bf3d1199c126e97b3708325c2900de89010c2077408ceb0a09d848816353ba1db936f48a20a8a96d445d3961cc2a6e8b9ee112b174071f78dec775b0e412ca6e2b7c252802f8bf68f97ec81b2cf3ca3dace2e8d76b999e69595b11e8bbc95b08e8b4a5a15981248f4d56a001651583eda30cdc7d5c6b3565dfaeacb011f1219311407baa5004c4c6b6f49da17a1886d39a6be72a88b2a92e6eff535782e40da818e8935d9652d7bb89cfe66520cd6b2ad76a1b642d2ff8dc5ff181f4e75fa4ac46416f3fa7bd958397ca9652f38cf2a8a2195cc9292889ec824cb7c1e1977b00abd871251c132b41df889155aa83eda0a1606abf7fdcbd708f5687b4ced7a4508773b3fd4f63a0cabfdad2ac27cd647bb284206430c0acc2a42c7e47786a955b4223fb1358f9e31cf9ae372aed7c22ca36f6650efcaeaf21a9b8066db797bb1a74dc494ebeb571322145bb79c9e9d5f7f03402d5e9c34bb086fdb6cbf31a4ed247afbc41fc3935dad7cd7df48d9d2592dcbf10e5e0d6d9eca4b20cd0e7a62f34287e75a276e63b27d6d39f21b5b633f411d8a62d36c0c12cb272e027d41c25583e0301babecbd8d0b65f3d2a9b99b34ab72eb18b72d963dd535cf5839bdac60b85e23fc8c1583214b7087a03b011dd5e19207d51a739b509711ca528088fe4a3ffeb9a9021652dbf184ead319bd90c96c1e6f5aa569d0b6cb5eadde275261aef7115ae38d5b0eea4af34bb1c86d74ad86441f2465e392deba27d1ea53367daba1f51e698dfe974aed79befa8867bad52841c14556d8db4ab1771f203f424a59fece220cfb0b0246bbbced0672ae7674c204f06706b2a56b1578668c5efcc8889b8768a9f07c6b22ff8fad39bf3032788dbbfb78ef25dedf1be25f19390bc3e0a010c1a9d8e0c03f1b704415b3843c309aede94f8661f4332bd426fd62baab7fea662ee983acd41f86cd9f19a642e547cd5fd96af5330bc3576fd4df6ef707f23343580aa22908ed1bc16707d3441cf0318df6f71066822cafe90d1714648de2af4b20069cbd2b3e080a79c472c636d1c4a02cbc14e0c00ae3053870324f010e40b62e18aeb1f7c1211b7f5b0f0f4adf943b59cedbd24f2d095911b4daa2f5e4e4057db9ab52bf3537fadff6dc48d46ee93be47e6bef9fd4dafa7affb5c8ecbf1e8095b4dd32029dfdad43305658fed518d65888929758f512d5508fa10e4b146e759b84fc52309181e37b0047d1168686ac6ccedede6ba0629952ae90ded49e3ed5b8204f68b52d67e878d3458ceb712a3c5b6415c2309012c654266986d4ed92c8046c7ef535d5327624c50466013868822c0bafce3113b8a42e1a5725b00ce8da4b6fa25f19a27175e6aa7bcc4a4331d1aeee7f47bca87ea8ae81b8fac9211b6ffdc048396e7ca337946306a596fb03c23c89e8c3ea8381de9ad650ec5656eb33ecedbd06fcc0ac6bcd57302c07c1a7fd888a300c6e39986105b60fc0688958ad5295b4f9711f8ca554bb12868908c3881385b9a238fac40aa434fac288405bf152b5d21d84704a7e6405201ea50ea3e8a7b037088fad801527a988b4b1539b87f07b16a5087392a2986b902ba2e44fcfaa5ddd31aaaea99d1861bd0f79c7c2ca65edc1d9b99fa6a3a9269c46eac876b034be10bc372176d61124f4131142a40843210cc9b5728e34d0b586358f378ce725965859edb6a6bf357f656168ae8b7e446129f011239f18b10407385598222d3856990bfd7cf93da9ce00a06cb23d9222fb853eae56401a37a11995c92ff4112c1d9b0261680b18e3c8a3a9da25dd373a64514d67ed48256a9b2c30b936a30e10b045d61bbdddb2a2de3e97669feb25d00bf3c43aa07e1449f287bf3799687b10889551d43b91aa8d28118a8ddab49521ec6bb01b8491783ce0580ed76b9c09b2044186b8d9c1f062995f052bab7060232de874a085649214a465669c69893acd9bd372309a95a9c2e0ed10646280250a323134d33f0f204f635b590848bea7f4366e763cfb7623f19ff26a3d366dbfd9ccc4409390877199afaa6d64a8590019f26f7cb08d3e52e99586b4a79f66a3b90d6a1bbe0a86f7422fe655b1f6f2f3ec59f2106539b4882a08bcd824b968eb0a34710421ed4e3bb0da551f14780fc441aced798e8d6b82b9a85003a7b00860e8a57865ef8421a23cd008d8358596ade7c947b8cbc3b6eb5b24d2b3ff580638262242cbb1bacdc7029eead1145eda28e0cc3a2ab363b8164875d7f4dcebddb5ed9d79058077e4bb390bc33b11cd05426088fa468531c5605206e12f0806abe56d9dfcf9dfd154f882ab5f9c5f7bcff3875b1423760da65823352698571c8d0591a89dc8af8d0be94d635e565581e71fc28daeba570c2744436745c4bdd14e231906eff17dfd85020e52a5b4af477aeb152eb1636a96587faa30ad474146d27ea09ece662df6b65abd7e538fd669bceeb20c8ee5025fa539dc83309b178bf99c0b85b63f7e23a04664ff5cdd98b1c13e53c2bd5b866fbb658ad957e34d7dce541a8601088539679048d3b467c209ee8f44c461f33d0a94905b9db14cc883d04027b9170084457e774ace69d2a79dd3f00d9711a62b0abc22875a17218148a28d22da25bb1151a2b5151661b88828e65822ecefc688125eb6e68cd47d5c78af0843cf64be75217846238e6d3ae6c6b4f57a8d2f844f3bb84be9bd26c16838ddd2110e0459becd641ce8273dc007bab93830cf7d804fa84ce2c0400201be98a637320e400f56257897e799f7ae6c901b1d4030a16ae7a537a919657f3329a2286e36234a0ec4800e5118369b20835a70c945410b3a1370e19d0bd2c1a7eacf5b80873ec0df8f825c08370b39b899ff434f848e7c3644af2ca54cfee1474cce3c99d03f8aa02daf67c7d464e642c7f44ceab099351da98e32be1258f3632d154e850d154ed02c91745c25e4f994b75211f0f0a0a029cf658267b1abaf4e9a09c7a582688d67fc0e827f94da5167d1e5681bceae69976e6c219c3b1766e742b5abe719bf15fdc0a9cd1572587d57a225e34e1cbd0548bbe3f5e4f3d69e7cded293cfa627a7ae27a7454f3ee30f5fe9c967dd930fb6276b84ff16e463b1759cd68b5e1e7070ad83dab5b3d9210aa45e0847986513ca649a64e7e5f434b35b4d05cd9692f7696eabd18d5d3a126f9a9f8b749688477b6e8f0559ce1cbb3f5e56799871591ca04afc727655b0a7703454f3bfc82928403e5125e47f7395662c4ff4f3dc2bb151ad67d20597d49d8aaa9fe8efb957e2df54bdc627e517f1f86bef1ee6c8281179c3372fb85fb74ac20929a6ab52c6a480a152f0341cedef855cb3ca2b079e958ef16ad54cc2b099962430a29488b67e82418151c49052963c56a8b8714090d2fbd52a35424a5aecd3bee009ea470991b8300303b2071b7d72d70cea9f01040040641846b249b4ad192dc5240b292669eca445c6f4068a13620548125f9ccd266ecc5e79ca917eec3f0a9c9163d12e36351eb938ec369c9b85080052f017411b5d2c2d5d537ba15990bf4dc5fefed355fb9b5d556ee201c005d438cb4afa697ccea204e1d4bacfd22912e128230b0fddc87062d0504033f29d40db4ec299654c539c95d780a43862a54a460e97b595687544cc6c2529ae2c24a1382712478224280c7364a4a04724c709e9604a1644f4688f1210f242c9ce8e153fc0928c7ab2674454103539bdce9ba4457b68a1d2170827ad964da7ada487462a7d8430b5e9aa00dcfc0b42c868b5821fcfdab2a5c9d90a4d05eb85a737b7302817f47c81176430ec8930144d424685b3e72821c2ab78b54a543eeaa185e6340b8485aa5c68211aa16ac9c330dfa825afad45e85a728473554bae6bc949a797bf5958d98d7c67071db36831c87d519ccc961585884faee6e59845028a16223eccd1ffd49df1e279c8517f900de34186d970bd86d7f1bda8139235ea4469de77a10a95ca3eb6463abba30f42779712d2dd55e79982fb22d924728dbf08eb55b1e09a9505300a80f15381f3bcd7c19227f24d5fb8ce01789da75ce97265d95693f3f3082a53e0f8c54f30b698cc1c83bdc712114be1d1b0f09d9e28a4a7c4ce8ec2349a5f847192a88dc6ae564d3594818a0cb1d4bfa8a8c909caa88e1d01bbec09765cb7fb433d3b0ebf1364a931a56fa3ae68674765ea8a4efb0ae3a330ac616d6268224b99bcb26927f049820bfecd9045fe31bfcfccefef65b2c54fa2ecacc83d65b25fcc47fc1a8c403bdd1a19cbf20b674fc6efce81fc6f62b5fa4ddd03398b183204df02efd71caf94458cfc2650184e7529b2d45e2858bb5c125336f6130fd9781d33b24cd868ca0518b58d188958b95761584928bfc2d6c2ee841a4755c0c747eda252ac83675a6385b5fd28864582a659db8575aafbc08badf13311869f44f44c603721cf80b652a180bd1366a0f81f81e1c81a1298c1db9d7d5bf29bb09430a439f39fcb30d5bbafc354383522452969469ca4ab55548667ca9ba0d0fee98bb80ae6208496345e72f2338db87a7b2fdaf6083809f284747ac99bd49ef1c49c710e5648d341324468c9d50eb5bc1d4e9a9d754a9a60ffb50c7b1942fc0629a4623e51132d3c4d14bea1891286d16f82707558a43d29254b869a8df74c907f0431276bc3aaa2e6faa9f3d529592f2d0eb8cf235ccc3d7b8d3ec91d0e28fe494440cbf0545b8a931ea737d19135855b66556e72391ba6aa9234fc1aff58a25e389d7580ebb5306696cc733abe4c6dc23ca78bb14371ad0045a99a5196ceaf7922c0b8540d4e1d940a581666f92bbd88e544852dfe52223494b177dd99e256fbd5a7bf3b7eaded83e186e8e6adfe5edb26a330ecee5b0373a4bb8f624a24ee761c0da9bb8ff0fede1b78a1c1cc769fc6fab5f95990e5613e8a83c37c94cc69802fe6c9885e27220e1a01fe406f641cbc1582dfab60803fcd4df4d33cc01f01c7d5710807f83dbf67260504def17b9ac5c17bb03718e0df5316076717013ea16c115b4fe82a12e0b7f3795e49ba00ab3671a07f3ff0d16d804ff8977391323803bfd0c738f8c4d2b1c2a76f523a0ed6f84f4196afe2e05d32ba05df53017e1d0797c97580bb7b717090d14404b8bb1f0706b3ecbe8803a05e05b8fb52b72f7816e0eeab38789ba9d4d771709e287400ef75e2e02099e7ba277b2f8b49dbdf83e9dadf576527544dcefe731dd6d3b0ffbd6a711ce0fd1771f0139fa96f5e966676ff9537b3fbafcbd3fabc539ad4e7dfc7c131cba950592f8af9edaa311e7555603f0e8ef654e0791c1cedabc0f77170f45c055ec4c1d1f72af0320e8e5ea8c0ab38387aa902afe3e0e8959aaa4e1c1cbd5681aeaab0a34250b5aa7b4fd5dd55953f7f1e07a78b999e8faeea95bf547b7bcfe3e084ca245863cafd93704b1fabb41cd8f276ffff2c06101fae56f00b705f69a14bce53cc3551b02f0b528e36594a099c2ed437ab1ed7311a6985c96ea9ba05855f57f9a7e99cfa68084edabd7ec541b0c656a7f23fa70a0a3aa789a1fb6816e6766aa1bd04eaeeae9a198199883b6b6c86b0e5b3af4e839b035517b068ff5507fe751b6b8425f7896fe34426e05dea860a7bb5b3d236d376c4725f20f2d24fd24fd3b894b675499e58c69a5559232cb8ffccf81cb17ff358f1f2986926933fea265ae738091b5d2e00435fefbdac166d7b696ae9a0e8e7ad557e2e55f9d9aff2734d95a50235f9aec53f2de32193c90940a47abc292f8183efe537b296be48eb9b0a60b33aa0cb13a82aa41cd41bf92b8898d449436c02289450be0965f9b01b25bf881230a5d5c4d29b684f9b0e058afe6673d608a185b18c05c22d425a05ddba0e402b4c64d75ad02ec177947c1455e3dc55386fabd56efae0ccd47b46bc5ddc6bd3194b74710ed3294bd3e99904b46ad1c618a01ff5c65d5806549531bfb2c64f14ca343e9bdf1f694cc98ffe601b7fa82451ea82752240c945695eb4d1bc9812cecbb0f2fcd14eab9b70236043c91fe23f352eee9bf22a4d88679fb19ce2cd8a6ff3fc69b3e87a4fff2d2a16e8147e67a1eff70c7c9815d81eb7b4432cd76b75de36fc3a75ba08f526447be029483ea036a42923c147ed03860a38d8e7d96292b2c6453a9b67d44f3974c4543f558b8094be047cc34ff1e47dbd649fe480f07d84f0949c327c47ae189e9173860fa2e5462fe294e3da8ec427026ff425be1478a33bf16781eb7b142fc4daa862713218e205272d8fda91717571757e5870e0e659cf58091f2cf810eb1f4d2659f056cb3701c2359964c177766c39f73d2e6a3282399c2cd7f88693a5498f73bec6732fdeecaef194939c177dbbe3656d5c2b0daf2e17b8bfcb5ab939373ab915bd5d1186a25d51173f311ef33eb15992df52ed64d560073ef57feb87271b9f69638738b5decfb971c8098a5e03ee1c6d8a308c22ea7712fdabdea9c9fde64e9114e1d413e3e11e375773550ca6577c0233eb2df4238fd032e3d19c239cf1e8867b7913ee394eb9e176d19b84e4bc7a685fbc42a83752156089f0485558b22973cdcb46312bab48adb2bcdf4d5ca3e82bd455e2cf41a1216f492ea95a1a41364a4620c8d18c209f6e5864eabcc233cd4c0a3e19ed249c565ca833bc5c9774d4eefd29a7a4b2f261b87d31a998941773b5cab93a23c544633d9fd4cee7dce58005c442cee8e9b96d6eb8d67bf11aa11eeb47949865997284b71f868dae128a4b5bc67514c526dd6d00d5a343fe9465d5db526ed5763dbe2c65ebc7cc655e946ba6ff2c682ecf9394497c50ca62fc1e9f9552d4e6d093697b02fe04f055a9d4f16c46c76922a9ebee39ffaa25d9d352918ac5fdb7a5cc0ffcdee57c28b73cce8a463fc205fb7779a6a67c918d3fa7341be3636e24c29b845cf0fe05f715b5d6f8c4483abf37bf5f386976f1274e0e7884f011275dfafc874fbc7fc06b14bc5499d627ee49e5bc537786818bcf78848c05db2b6e2970af5f6b00e9bc4879a5534e8b94973ae56d91f242a77c2852be773045d572c45ec986d86f7cd3537ce3f56b5bcf15d735bf7e6553ce6dca4b9b726a535ed894b736e57b9bf2817f637ffee1153e1774101fea644f7799578c14da92b736c3d3c7addeee849013de8f4e3819d0a15adb5b1e5d71fc9923149f70abd48a3f724fa59647be09d2f7dcea72bee73dbb392e553bebcfdc9764fc6cbe6b7ee1ce86c909474bb591ace6aa96bed4349813defb8747af5f973cb2684b5d8501326abd4230220774d81bf325232c6a769cf332eb3e66bd46c86ee2c22e985e02d79b30545371e2f4cb77ba08e6f18ae39f38b812b602a16af7fbd2a03f5657a1db79b9fff279f7d55eb7157577a2c88bd31db9dbeda0dd88ed926e07ad3a087de71995f883173eecc13080555ae4f31c952c3f4aaddf2711d6ba2e5eb9c233f2800dc330523f6078bfd0a9867bf5170fc0d2da8fbf9a35fcd9fcfec92b32c2348dd0f24f4e7ee6c494f5bc04a70511f917f7d4f4321efdc2113600da9581d0da5726dfb891f7942ad3c2cea56fd4c6c2792597bd0638397c98a79acf7899cee81b896ad30b5911301c51fb2588b5d47e8b9c87d666f4d56a9061366ca96bed59a0f1bcad9a91ffca09c57a929d6cbff5eeec7344913b4bd6589d9e5bd07ea6a5267f00f2fc69027ad0e5d255996a9eba2df827d74227cdae7602d501ca677a136d5ae90a43b7c9f7b573c1e84f350c498a748425599af58f29e6d739157774fc2e95792c3153a97a1b9adbe967ee3b86feb50a33ee7714ccf8332712ffca4b134396e5d1c71dec8f38965858045053ded65a3ce36735e760628b38162d2def54ed2e362df18493546bfb6bedab5f177441c9f23ac9a926c8553c708345522864c97989a0e378a9ba9fb2899902ed58dcf6ce35b5308ba3b682d71c96a5c635e7456eef900b7b9dd1a9ba3ad327dad601d71b6a1c9ee76b6fc364a9ff58457463f629d64e4772aa35d5c1f7e624eee079f298f1646cb5bc3550a663c56e407a417c27ac69c92bb13d1ade6891bd2e34400d83406d33c33db3a1585f9ab58e231362f08399495747c57c44a4b70a795a463d8b2ba9b8181629b817b67b39629b9d2c261c1c22bb18b1fdc23680b6f6d033679996c99269b9b59edeb49aa79c7a6bbd20a999213741c5c42efc594e74c51949a0f59efe210bdd25fd43b2754216b85a65f922cbaa6eea8b8cac3443611865debc2c7ccbb1aa3bae2bdadb67ea6dec9c74ac37e1b1517871227ca682ccbda85392194fded1824c2b77277a6366f46e6367578b5637fab45d4e807d3f6dcb64e2f6fef4ffcfdd9b77b78d238ba3ffdf4f21e9e4f00263442d7949622a885e16673a33d9c64ed2d3edf1cf8796201b1d1a74b878694bdffd1d147690729c59eeefbed7a74f4c81209642a150a875a89fdc06381b9a476f1b18acbd98a239bda09764416738bda0170aec97a479562509aa68a352d699a4681749826cad78fc8e36ff07478e09cf5143e216f184a500d673cac80d3d3392f286d6e4920a72033698b73a73853c745a9662e89cde9841c85b043d57f2bd4b32230db62611337a1e78ccf6b6d2734dc83e65a7f4e1f668f771e2952c1f6d4f744e0d7bfca0a6c3522de87f1a749e9e636b113853ac9a3f26d5fe662a37e5686512c639f0a923dc0e886e6d5a4222f7aba6c2786a1fe9e1d951aaed03cfdc36911f9cd133587dbc5c9e5189f5dea18adabbdfb02e67b47b7f138f78d0b57b5dcd09f0754167a9c6bf39f1b6285d044d5d902c479524b92192d28a4427289d79b478ce3d2193249d1a20c43e05b4876117778cf971c76c7eaafa8814b4b42be1d18b4207dc35af54c3252d484145a7b029169cec8e4989f1441be81578a5a2375f70fad7e13e449c54acc60b17d6859c718a04bbea954388102098a8f1b0648bca13857aa45f680b5e24ef4225a969043c8ca775aaae0e04723886a015040c37a2350074f408b3b7885a4673cee92dafde150d8456692bf4c079860d4309d16b7ec24a9c24bf31c4b0ec764598f8263b3860b5e25542959b627c3a1ad1b2dd9f1b8449412fb8a5351354d09ca392fedaa09230526052606c36adbd1188244185b7b09800935160f2e7063282d891edb38b3c9bb1ffe8e8eaec948e49f12f8cf27551ce743eb7c874f6ae210a35c4321c62298728e4100581e428a51ee2a61e560d290eedb06a3dac520f4b04feac37dc37a62399d5f8b6a96b240657022bbb09d4eca6acbb1c95d078daf7ac7e974bffd790571f9b92a96d673e5e2e51ffb3b2ff5a2ee55341b81fb3ef9487a2d2fe9814b42a0837b1a995e879d21d96a2c7ed8d8d4f392d38e23845053d2f508da76745eac96e3945ca6eae2f1f82d62b8ca7a0fd28705a15f25605c1839020bc63439b58b200c924b1723e5d32d57fb5a182dee5253de7c4833ef0a21d684319f9573516c58f6a2c3c59c18947f8989911e93029af552009014e2479becf668c5f32109724c91d2f0113ba1bfcfcfee0f9ebbde33bdbfd5e1dd5bc1eb7ba6b9ff36107a541b5a945a2ebfa158fad117cf17d01ded015154467f7898f0352c05942cf38816bac8e461562f39d785c98aa069f79273ebb6a80ba1c63023716410a08bfb166781d64418eee94d5af58c92f75b5d76571ae645f4982f469c8e5f1b6a6d9354bbaaed5e5b2a37a0186d022bba8ce8a5a695715e9f16bf75ded2e5c80f3b233206d316c575c2e514d8bf548def54d927495a24e00dc39c63b5e224c6ac91e1912b306850bb31a0a85efb3fc6b866987f08acff5f04276795b3125d75c5b01f00afeba5368cfe71a9d1041c8cd803b17a42b45894ee9303c06bb6e1d773bf839eeeb0ce02dd9d5aec95d43bddce0ab4e75dbf66362dce20b3a186cb0282177ed45bb2fd9c21fbe87dcf006fe0c8f5504fe7db650214364618a501dc4bc5382dc52b19a35a5f48c83439c2aa1b72b2bdb605395d3bb571f164729644d652becf752901aae2426f4bf07c1280ee7936d9587a66fc11855d81d81f57e3b08c557271572b13ffa36d34204ff31191caae5d4ee4647034adb7e4226c2bcf6a8c1538d03bd2b5e9ff5beb29baa773bd8087d7786bf175ca001e90df0c66035486b95b1c60ef4138f93649bdb8be12aea619e55f51ee0b3112995539dea43155341fc5a54e0b456625d5d10bed50223f3132e44de15f8c9ca0f6a6842b6f6c3e0d9be40be9ce05a1d5e252d87954e1ed0193fbe74e27c669251db1cea136c31f72bbb5139a6545c3152e3d4fc84806304e24cd771671e0614911cf265ae3cb8d4f77424191af5b18280f72947fa08b54101d4372551f17b247928fd18fd788ae4cca1167e2aa6a8f6c0b949044ecbb45de6697a1a3f358d4dffedf500125ceffb80f1c9dda11f6af4eae5d23ab04244a18fb964db87e7c59c01e3aeaa530918d8f205525163bc724fd2dad98d2239f590296b51c92280712198cd2254aa3615e7012d2fa8a5b7a4743d95720425fd9023f52d819062e64b1de2da1ff9da763cd1ec1d80d93680592eeb75b90e557205bf24ac0cd65972d6703786da611100fdfd7d80ee2536393c5ab7020b7b5be21d337a1c2cf5b1dfabe4b07e6cb1e7de91d8ced1d2959a459307856583c1466d7a0ffbf03d277d8d91c12597ca74f8e0817aade57e8c99d06642a249add044d3870e34113e9aa80b0d26c20d4528b95b6d9b85a55a336c79605d73b0e8b964c87a822a40bb6f143713cc571f45ddf9342e627edd80610af34a8d90bab5045dd97102535ec983294739451e06830d938db6057e2f978805bf580bfe1eec4c6016d45695fb9d4d3572aa85b0e80ca10752473a526b66ec00ef3558851535d485827a681aed26e8b605405f415cac81f8991f12a10bb26507646dc60e586b65820aa302b41a0c36646b9da02d2d684b0bda723d686ddb6a579770108a14fe9aeeca00e83561a48c815e10f5453a53efe5e8229857fe4ceeea8d14582f43a996a1745183baa05192c2ad431dfbce3931252a48461a92bb40fb3375126b19ed8266e492667444ce95ae46c371912497ce35fd726303df2ed4d1fbec728acee9426b7a707a4e17964180a063f4021564419ac3cb2392fbd9766ff0ad7e5a24095ad0732d9b5fb12459d8f3f8c63f8f6bd9142619e5e88664e4d232c0d574466fd2ca721737a4a2376441cf25142f29a54d148450a89666de7816dae2219aa8613e16748e0a330d15dc89a3456b140b6f140b52d18535f998ad64f30b5a42d7ebba39a76768410a72e977c52c429ffbe0580c15db6f66700eb87499c25f05a6f3d600cfbd019e934a82dd31418beecca18627430561788531997936ab122a242733454d2b7ac9905ae78e3b5c15dfac7646d8c30994539d6920c72df3ce9d3176d9e9175463ec256dc8396de888dca882539a03a78d6c42a6cb24e99f0ee7856093f38d0daf02bebdd4487c3e4537f4925c6a24bea19701129f00125f9253154b8bcc7c3c3eb1787c9924e892de78787c69f1f824c6e34b4c1acad10969c8b95da0c5b4a227a9dd41f4842ce809b9a437128fd51c7c0cbec4a4f24672a93178cd6c0d8a9d0226bbb9480c9343396d0de5d41bca295950979aa90264be0464bec4dfeff10c5d92829c47bd3abc3ef5c17319e1f529e0f5797aaaf0fa47c70a2dde0faf4da6bd9e27b22f0997045311cbbb047149c2dd2961179e830be30c62f4f2e8cc502285eace56e5fa56589f62bce314d381582ad51399d1d220fe4c69d467faa4afec6138f334bb8f53be40dec0f1ad9cf4ccc01213b84ecc486bec1ec3c5a8cdffb40a3d49a0fbf09aa2fafa4e373e1b39233cb86df8bdada015b3e36af84166d4b6bbf2660637a3e31cc533318c644e0082d1c424df9e4bde57b5a4ea986106bc6fee0f5ab2ff1087c7b694db43b941ccb106368e8e421477bd57aa4eb57433f8b50dfc02c4482ad75d9f00c041495839bc2b41edb0482d4c192d4c49f8dadb92bf1ef0adbf1ca18062854ac9eff31064ae1d1f42ab2e469177308a36c602a783c106378ae632491e19804dd19a49b5175bcd4056f878c7403169b4b7e13547dc326797965ec85797cc7b751ebcaa920438668e893516e549d29f999dce02e30b6d0ca14e4493a58db8a37193a8145679062ea6cb251b0af83bb08ab58193d9a9292acdf701a79f38ea8f3079a99ec6987ce0f476458eb9334efdc057e463f4fb7df8db89769f73e3d54d29fdc0e373fcf1b6f3c9f004406f7910b87b56a0f75c7ba27ce4da85e298930f1c13e6857631a6e20a44e3710a41c85c24181b79ac0688405480cffb6fd257ea742183018e9cdf6afa8aa19a224621efe6b4f61234a6350e9ad1ec3753890b2174e82a97e334c3f5aff7fb5c79eac8b7b99c15fc79cffd347100bae71cbde7d6534447317cced1b12b240246a98d7af1a456366f288296f0c59e6fa0f18fb6116da5188c4889eddf794beb47897ec54d4a541da9c2132382b01dc25028cc35f17902758267cb21bc405902d2629dddcccbac86cc84267d2984da76794d556c75e7f96f82bc8e77a98d1ee7a9574dd7a0421a96ec9265f98772ae3503a33e04c5f2447c1d2d8b201128bed50f8616d4201085a28924ba5c34a04200d86a331e2bb585311ab6d2b701aa7573cba579f223fbc23dacb69556b60d3b08fde00b67bbef7f7f0486a2b7d6063765048eb3b45644e1736c0ef34a67206225797d97a9cc0b4e47e40bd7819cf4df07faef2fa1d1eecf1c191700ab14d81cfb08fb6b68661a46f172195e4713617d12924438ab22a163f5a8e85b107aab33ee96f323e0ad38432f38e5724635a93bf4fa91d9af2e8acca746e4b3db73c2062b334f61b3d39b2c3dcd0803dba102b75ba3f4851c191d4de6858ab6dfeaae8f36779ef1f802b5056eb97c838ee58a98c5e9988037da133712edd2d13d1e89f3de67e719a98d54ed9be365bf7165c80658a2c6f0c5c70d52b7863cea3c2bfece6d0eb3db007a3a6aae35b4b63f3d73ef6feed133ee0c25bb0ff8f40b8fd6fb01a72c7dc0e903aeeda1c903cf75f3af1cf988fa8d9b017ee19e75b2b50661d368ddd53080ec3003284df9d78f29d563f1c86a8d1f4864fdc629b3ee1206d35a2a3809dd160891fc167798ccabd7df78a7f1fa37dfa2f99b2982870ec7827bc1d7d0301fcc7f0b2858979a755a2386534f53f317df2b86237974d66a60ded5394e3fbb35969b45800a6f9f491ac9e6fb6cdecc584999561b7fe360a7e8a6cda9e8b0e0e6be8a5bfb6b355479394cb4b383de187ae6cdca6b95162adf986fda19b457e8b680cfb64b335186e20dd51b6c460b4930d47d73166d62e0489fbed038bb685929c7f5635be5596cab9c01e8d3d9503d10969db252c34fb6e6fd54ef146ee9370ab7da96d7f9143534a70bc225a79e6b39035d90ead917de36986c95d14a59b82afb6c23d0ce250f64dababf7df67f78ce60b35d91b817799b0adb021ed56f2465a824661478222fc3b2d9d0256f962433401f075b4ecb5443a121af4a54c6271e5e2e8d03537c16cabace2295eb5f0a7f73126e23fd85dedd8751535e92602fb8fb6fffa93dec7a2385dbbd604db88e712df06db81d752201b30fe15ca60c71d29845208db6e1d68bd028d0bf2a11ff01207362f9450b5dd0517b90c79dc0e606d89c941e5459e6a02a8fd4c95aaaaae2c83184dba3f2bb9757633001ffa63c9e7c8f2a6200ade35ab51725fd1b27adb1a76c85ed1ad1cb6c78c2c55c5dddbec045a785407e52803a6b69a319bdadb3d3949159c964fbb5ca1e5adca482ccd94595961de715aae539ee3bc64c514d6f9d8187ae1e5602a6d1330261fa60c3a9bbf8f815e425b5a37a8acac8eb8811fdae8c3ac0be4985c89c0fb8dc34219c3cfb902c568802327ce1be41172345bcf0191a2fe567eac6e5e4183ae7956f1450b4baf82be01b6d7da4cd1f55b9b7eb0c439549e6a8b53539cd867a193df1cfaf1c9544beb8a89c8446365c67606dc2498957f79e260fcc1c781638889719da193f22db24d4e86761ada2bb56d3aab54d36a33a79f65dc647ed5022f91fe2796d2b55235e619d56cd55b4fc3a0bea07779515d6e9bd3d9b942cf2b6169aab1553b0dc9865353a6447aa3fa26793fb3bb706bf3cdf68240bd2ba2e4280fcbd85bcf490397cab7582af231ff9e799ef2108d856d3d627f61408312ad4783b75720d385593f2707c84a7e5e1e82845a23d3239126f7217ff534351cbfafd019d65a10dfd8b026170f77ff2ac9cee3e49cbc0eb9f81433fc644d678fcb49cee3e8e6aa8565e7b2e0bde73c74cebf246b63ac6442097e6c9ffa65cad7c41c06534e00e3f8ea2c5baf93e1d11ef5618662de2d29430cf7152f125d19866474c3e5556d840918b1475f2f47095375c4341b8ef8049e42dfa0b572201ad4982122cafc52352c47cec0b4edacced0b6e2f7c6b3c88cc58974b1037c75e9616b7c0c0bbe380c6d80488c8a20aeae46d2847191120e02e42269593c263511583d9102bcbd3312118be5d19471ae5d494d1db9265c6f9202d38692a1b5a26fd59fdd42fd52f7d1eab1f6fce2f580919877ecec43c67baf86d7653347550f31d3b2ff4a3c106f36ba19f144ea8e757eca439057f745bcdc8d24c85052b4b36f7eb40bc4ac85898fecc57e4e6eec92d327f72853f399e754e2e7686ba0f792eef20cf2d50858e4ceee8b3c79585645853513e8fc5ec7510407227f95af92b134f545185aef6fb544e1bd538ad49195f5a3cceb5569c6bf94f72aeac8371adbfc7b8966dc6d5205c87929a39913c5b918e2351814833cd5984a4551622e91f1d48dab566704520251587a32379433a1cdb40693c43f121207ef0108040355df45fac5698c0ca6352aea2bdd3b69167993a4d687d383a7228501f8e8fc8e12243672dec3eac093bc29007839cdebd0fe7ebf761d6bd0f67596be73499dd1a17998fca7fb14446646efdda419cfec2d1dfb8da60ff866555ad75af6bf6bf675df530bbd775febd753df9bfb9aebfdd735d7ffbb7aeeb6fffdf58d7dffea575bd52a9a0c8b5febb97057aa5af01bbfd29473bca4a03fe19e18908ec5106aff6deee7dda7b05a98fe202dffbd23762f61d37ac5fbb77119f22ff57e834c222a71116388d846f3d97952c4c6bed5907eca47e00cee8c2806a0aa183acbe5ce5e3f2f259dab7eddc9b7ae9c1522b80457fa4ed571ea5adee063a07ac3a40b5f7de563086efb73bde4aef483c7f90690383bdcc60d4750609a5adda193c9834d074be909a5e0ba4042807da0c042f97b6928d36e4c5a5188f367712dfaf6d53211bdc3dd15546199e7ccdd095647a57f2a7c4c96b81b42310f8cd6a61f3fdda956d78137d99197dbb0b5765237225c98e72aeca4e9364cb3d8eedf3047b9f41d3b6e50f0684ac4fe955e694a212547be6b71a008c6d4474ec9ada201a5f203b80e57270c63215983f490627c5fc463ff74f8532d5f775f158c780b8ce26f504eb0d4b6a053a7f8164276a0c2a7185427b584eab4a436da74508586ecc0954b6b9966cf83186f82706b85eafa4a6a309531a7a3001f18c4dcc56835ce27c81063f3d00cb046cae5d35be5538c0c2891803a9fae1434088c183813282183ce8dba7293c2d97f5c6c62a1ad44a533b1d28eb3aa357d914ba71b65d7e87cae6bfade23ece108cf0ca279e2a5b6a1629f63f5c095692f721757dee49f2b4e583d5694f5f821717105b52e2f480c3d2432528f1ac7d32df254080dfa73ce9ec15bb640b1b91573653c853cdd3cf7359e294e9efb3c0016c49c7448f546bd195fd461ac5e48a6378d90612fa7067fcb8150ae5292d3a62bbd111267f56bd15bed8623f6b99135855acbe460b9f6877184c67cbe5418e32bc5cdafb4c16c41ab44203014eb959c9bcaa22a83a4588f9be5eca71405b0180951bd7168c007ec23c2b17bdd20c2008d13176887206a219f95dcd33d3f3b4766699095d4c8aa73c495041b3900e1024ec2e166e06782ad2cf2546052921026f096eb230283cd580e6388d175c391c66d655ed8e59781657d11a85e71983045811f56a8f4a47f61bcb79e269db46224618622781d37799e760e6196b65619a33b91f2cf638d721bbfc4c0f09fc8942cfc5251d6f3ef19a7e97b533949e1748440103ec3d8f5e16a8061b5cbd11c53fb511c5ffbd8df82a8b1c9060ba66eefdd1e4aa40b53ea8c148892f909dacb5dcb2d1351cc89127c533f634ad020f189b989c1a4f5772a59f146deb8f26bed1994f24bcbe4913dbb54d321d61a29998d8703ace0399694fcab5512466169166d3192d389ae174a6967bd68512c65e5dac0dd440165df924bbe33764ebe2374c169d111cb27b44fce8fc6c6dfde51254b1e5720930c0497222d74412b219262e5edfbca50ece74b884395980149e647215f3b81ed1cdcffb94e6cba58bffbd5c723eed08a8d6ab54fc0c891892d0b49bc4043594f3e5f246d56a4849e6e07f83a7e84700b73ef445d61dfaa27309bb9aec2aed0e7871e7c8ee7889f09ae6ba0253d461600a9c7e6726eb3f25d1dea32d1b099a63623664490c96e4c46e4a3a23256dfe953194b43fd6b42a220dca36aa4d22ec886ae30c11b88e4f9bf4ef8571ed6d24ca391212930c14d114fca31484a02e0a81eea229f8c7a807fedf433c3a088243099f70b4080cf19a9eff5384a3d52426a88a09474ee63f4e381498ef032e138ee71ea4c334da598c4a18e7fd29886b6dfd5bdde83d088969adb5157f042de3cf37771e85a4a80b88b67395ed3a624493a4c38078b9bc6398fdef0ef39fef484ee81e0472de4520e71181acfeff071920db86a7fe230bf867cf423fba8ee86b808e1adce1b2a0f2832449dfca6c8a24b9863013a43fc6eea6312983c3e263e652006903b6ac734b77d26510a3688b1d7d73f7746f21fbefb865b81aa82b58281a907c32b79703f5120a1bb822e90b44a3eac44a3c15d1ca9bf5c8b6e4e0fa39f3f3abbaf06c5627aff500d3d3028d485cda2a502e213a7f4d6a1f93447f6e8e4fb902cab129f4c9536e36af33f222235f32f22da3b791c08a94ac2e6f54ec74cf03e7416809410a6aaeeece2c419ff9f49d35c8278dbed4a0b20b87f072a95f6c2619768602ccdd2ee310a6a49ca286f647d155edd18eb132a2ce03b6b53b9cc7db70a1b531cb655f15d8ec2899acf5e98c57af6d15942de9185c9bde71324e3277ef844b9d157bb86693e420439225820a8df786200ee15ac044898ca21822351951090d055c25aef42239861e1bc62708fe4df52fe32fe97ca4d8045b59040797b13090121272400d295a114d6ac25ddca4d60ef896d98dc3894ddb5650e7b0b9ce75457de4847690efc799dcc58b2e41587809a9b01994062f0fc02b54f4a75013b016c2e082fe23f0c53040f528574707f3a18d017733c18de94c80016e04ee420eb0f05d406b222c9c0bd29d39627417fc0529ace35548e2bcc5106d2216ac8758f18503f23f81ba16f34820a830a887ff17e3b6088e4dd3cf8f2c81b705ee84b25a9d705dbc543d5afad6123b75a5f6a0fa7c5e97884074351217d21a13c1ed3205b69f3f474c816206a2ed690cf9b3d8b388def2ea4536fb7a9595f30a326fc8e3da1ab7d89f077556d63a59479e55755a923ae3792ae08f5b8374040590b6b5209e09345fa5281b7a9dd19a6443dbbe82bf57603ba4239281de133842d93815fac1750b954cc7b4d05f684da92f39fd3532168ccec502e2275a5750c2c1439c43c427a3320836ab3a1751e99da718e3928e9372b9198af71e6d073e576aebe90397f9072e4bd5ae33bea36e1b59375aa5ebea26c54902082af024f080559fc4af6c13da8595852eac8c585a13b8b08298c046d0f79d5859a7132bb34eaccc39b1ba06bc7c3b2c7660b548ef118e5599d0b11c873aedcb986a756d6e3565ad222f74bedf455102320e00e4c2809c1441802361e3204210523f37869e1ff83e8312436022a83d2926ce96bfc05354d80e7ced180499b69f78c70cbc243f6748f28a401e7960d28f836cc3666399b9a823a0b34733b1621245582dd64ece29f40a13c1861676cc854fa621e23e5ba9718f3451bf6be87571caea33560e5233576793a1fd07babeb53ef91dabedc87cc4ebffd91200effcabc3fc44511ea78921156dbfb89132bbce7254da7b45946c2a4ce71c6c7efd81b7ffe2a8465b2e0092ef68ae1658b25076792356cae33aac6d8a0d56eaed516f5381becdaee3ddfcd92444d2b5d0fe7bdb3245d168bdffcef87ccec42005bb0149679de3b68fa77e20523f02a7a051d451617207317d52c84b6838d6304173ae32ad0f52118fa05c430244308272cd862fa7b5e7c42d1b0e86a49e8371a5650852cf7bf8ce336b62a3333aab9f4d1df0e291febb6362849838183ab80ffc79a24bf5472658c6b66fbda30d6f4cd1b99108e324b92990ba6a99e42dbace3e4738ca230a04d68b431f5e9b556e3793f52cbe64c7059a3886f749b79396cbfe870c8243b6c43a6eac3be91b8e205c4647500dae05e2e196554ffe2c5e68190a2955c20ea566359adf96a6d5a5a92bc3280faec5389deb23e7e62eb4832f8b237ec064f16d28c6b15350229c583768821f1e7e1247b426e5e18138a28de4216173f045999d9bace15ad2af7eb0f313b9657eadd1202fb2f9c006f551bbea92cf59a1ab66cd9c1703cdd08c26ece95f999f20f2d71afd951db2a3a885aa68ca19533d300987b80b7e6ef2d0f3f3ecd4e64ae7e26bf4115937c845519eabba25ab586deb56cdc939afe3da7326f76ba53ea88bd3d39cb586242e9a7a907e65a8248d6a8b8bcb2ce7d035c9051264500895127c104e1732820fd272787c55661717c611e2f62aabde3579cd2f7296f6fbcdf05cff58fd50f336dc76fafc9e835b192298f7b8e8150271f995be2435585e39876759f5e14a484c62657d83726ca2a03587f9d1646098e401b80fb74235cda6e5508e0b7633249d9e8117e9a1fb90cc8e70da8ae7344b92f8cbc160a3fdb12c3cc2e9a7f638cd269e2509cc3bc72b1340cd60be5aca2b264ff5970033b03eec84a9aab52fffed5a53b57b2e406c9a867c4b8782a01916e265ce21c354392cc44c3ed399c02b085d1b86e3f0d265c6444ee518d3d3cae92ec4c7711696a91842f4f6573a0e12f818350280f80ee252e992e9a09a95fca21e801713428ce643e51aab4327a1c19c5f0e2088b760e5cf9fdebda583a7ea9b674ffff1937e1a10c5e19f17970cec1e11f38d2071da8ef93ae4d5b4dd1b27b7bc4ae5cb154e3b46c33131905731b3504e1929edc699e6f691f64770e4fe01618ee081aadf18e3b4d5f4fb0315908b696ac9805a96e4b5b14ff46c5519c96926374d89ff196aca30c4e9fb3e459dd1d164e651d499a5a8b323c2f0246aa583aab6bbba2765653e656db7d2a2ae2ca4aeed2f3a296cc7f02c9585406c33baa79f0292c6ee2688663bcee831f342d2851b97dd4d8c4b8f18eb0c7225b985f895c627f6c7061550693db9f73f3639435866b45c01d19e199b9c19b0b58da4e69524df554c161b6cc27b5487cdd16450d53739937ba8990a811859e07430979d954553e53707ac7e6336bcaea572212de862ba181e1f9fd5e7b986034e92cf4c37e19f0a4dfb54584cc3e4107cb91cc8bf0b9c24af4d1bf189b0d0ef06830df9ba6a2e2e4a5655fa7cd89b735019fc929542e5b6a04d92d85a3f835a8517227a9f3575f1ba9835952e40ad83a4c17ace0b7d8e3446bbb14892bf21461ab22039bee3706170b8305292fe78fde1c2e070619d08acfa2b55d8d42481840ccfebbae4274dcdd0008ae1283c6548d7c26b90dd91450fb5f5098384e9034f3fca118775e4f0ed50340e7e51236ad70e6b78c7ea1da7e2cc3b1559702ade282adb71008a20e54a87c563eb76f3285569bddb2cfe970c8d48cb4e5dd20dc3ccb732a7945ece88bb39fbf8f241ba38fb6978752265cb8a47e873491df3005c259be8b0704282a2efb104581f7f9fd83504374425c6ba0bffa8131d801cdb3b605ea077e071141bb074e8193b2c63052446b056c025a8c95d5a9bb5c1fc9c820f8097da546d14f1760e23612feacec91aea2949a8890aeae5c1955729cf2f0786eefbe970edd7ad7f3660d0ba36fb4b545bdd6bb9ef4584311149d22f95b8d8578b399bdf7e1720eed297caa6c68927b69e7e6828a55792d87d68e8b51cf587a6af4ae0e1ba592ee5abbd06e4def46d636fdd9fe457fb39fad490970d26bfc3d3db06632c6ffdcb65d716d531e90165b603a981874a23f3a2563775f7e6f13d8411e35db9a735161a516c0b1b712ca1e35d7a702fc36be9d414ca7f88e3bf674891712358d7a0f34db0bb64fd702cc792fe2616cbbee2f2805672bf48a7404ccfc447dd284b737871e0a46b25201aae434bf8cac759859701e6faf5619307b32827b8a182204e4becdb016cb6f19df056578407ce6e461e4c011e3cc8f4b34e11d80a82d058dda4ee2134478a0a3dbd206fc741e4a1c858cbf1bb87c2ba4adbc36b3902584daad5ac86038e0fa478ec71b63e7e87557d1349bdbb266819bd340ea7d1c4430f12fa3743ffa79fddbf19ba1fabce6c55c69ec311aae5a633e1f134f7caf709246b1c77ee1e150f33d83c104143582793ef6c1cd1da386af38dbc1d246f31496204dbb6e85d319744baf110b7e51cb9766fa991b4ce086183426efee97581f0c3b2437dfaac8c54a549327eda921818505862d23a8b3b951b543c1ce349e9ab75a7c8ae484bf5248f14076c35433c75e2f926b535897a4b9b80bfe81b704ec19dae3d3514175109988d9d915c225d9f94beda99945a2c6fd5203ee48335215df0850e229d1da97df32a85c17c3a4eeae5663a4ee431a693e9c4ea9e474449f13d85f5dfc036ad33eef77981987ff0590f4cbbb066136d8f761f25e0781ce755af978fb609f393006dc923b34378af4f2f1474d04ac4b1f964c70bcabaa63b237dd7d520f434b9837f84e1471ddf6f32e3dda829f7ea5e2c871957e86fdc8b14347f092252692100234ade92d6a4aab3d9d7f486a11aaf56af331a3ae73b955774800ac506ec509da472b97c641e311b6617923a2b699ae78cee38906d93dcd2398419fda108b5fc0234586d2dbfa7a40f74fca253c72fac8e5ff83a7ee3986cdfaf44ace2376f7c45da6a455e84903269d6620317a5cce00b94a99c4ea0ec203999f93726a3ec882e57fa3017e1dd3ca37b0ccd48260f24782a65cdc3a3ae2b78468f6ddde33575cd2d3b5372a2ac25272ad70990e2969c6420a3ef6dbfefdbfdb66fd39e0db3bd4d77dcb54befae3d0beeda568254a81c94449b18641046bb6ccb479224eb2a54c8981d364758dd9c8da4099861d038ccd4eb5997f05e5e279050094e0ff3233a1828945f2b9ed2121d2b7a8a2440ff037222b65c22b93620b26690216378d15467a8d1f66e4e3a579a4449e5617324917aa6afaed95482446306e98476a5b528ea03ebfc3bc3319c65b38aee2868e37e07a497cb2a495a724259deb502b6b10a777c9324b3c3fca84f6975981fb59750969ab0bb1254065c845930c92b30adee5e68604f5145ab69154a20c98ccea6b3a84c434985baad5408d360692adc1258ce2895706d497baa243162c9bee7d6d86a7230d8a8fe5d22ca4e4c437656b951da2d977ad40aa61d385861bc122d0068842102134e1989ef905d32b715f9d226d9f856740ba254c4bcdfb22e9fd05f58f6f580d553fd373d60b53373674de8fdacce59a275dfb3afd606c31d7c60a97103090b3dadd939d3eeeeca8844259f72f7f531b56133ce19b2c934ca9bdb5921aa2267435086c853dd46a8ab187085455307f174746e9615c61edb5037bedb41c91641a4f620479a97d453f66fa276aa6e6b7c7baa72e9aa3d14c5e874215f9bc018c73718892c438cc1c8e6a6e6788cfd075fa0cd9d47be5cc4195eb8f8179198b4658c5aab38c09e25c81aaf1a1467b155829ea9f07c120586a36f787c5cb26c56bf1170bfcabb9aa3f5ca9fce56aaf9502dfed56c61285e8a79f4475b3e775e3641120a758ff36f74415460ff32a1038f1824a6b50b0fbd4048f16d0c3b476f8846ad82d84eec130da2ebaa6d5622bc123a24b009eb0d08e5615ef13f3a6c2548f6467d9f21f2c6183dd9f4a7f7475715c8b768d01611d8c35de6677327db8967518efd3c22aced6b8bb4b0df4caa33bb72247f95582a4c52dc30c6cd847578abb5a3aadf0fafed1d19220f792b1a8933e61c09889885bdabdebaea3a499395bc79f707bb22ea16e1479b62a692c77a3bfeb537eeaab0b2e30ab6e78e4bc1eaaf9a9d23851042c12226c98d70d9aa438827091b2e24a786b08d4f15ecf888d66da53150619d23536bb09974b15abdf346c495e397cea7cb7bf3ae96671436431cef5a72a4305c63fee6f85ee4298b3751c789b29727c95e8ec08461fd0edb6eedb440c456479826bce84b9e1ccbd004158d68a262068be9eee354b46206335a9a9c14105349d33edf954b9878e12a009d40de417c9aabbc8d3654922634a015c3f2200ed0b26e24043a7ccf2393c5d055589c2b37fcf0420f27b4f6628d0f43dd584b345b77b68c3a8ef8152409f737d58e1abd5fb49d5666e93d9ada040c879778c65ec455c2424f461ebb8be8c296389cb5a5c5a415fe84b5a5fcac25e50f6d8ee35104859e1ad2a352759234121e5e78f4c60b95ba436d58b22df7b86d1ebd48e6f0958e02e6b8343fcc9ace6c9637a87667a28be6e5a5e58a76e9c8d905d4017513add87d25ed8ffda5dd3254aba691dfa88a1313d9c6471d8f315e8d1f853413bd66a8268301f63dac12fa70fc184f585a6b77023699e80cb2f79402e50d323f3044f1b2c6d73db6f2c441ca41ef1e22a1c98e93683d728fe327e6590d643338d68d3cab57fbc9408c91f0b615a879f5d64bc756105c2eec4005288b4ebb1e5badcaa9bbb1a020bd01105ac2a944c54249f50ad03be29af2a9476fd2da4fce29aa3a133346c4f40908bfadf2bef49210ca6aacd4ec01908ab4ec28435113208f77ade0f813487e494b1c881d6ba7742c6939548cca7e5180a607d0127b29f74a2f1a99962b2d9748f832a6507859b873c426d2d31e89264a526cfbaff664d7eb156204ec09fe638bd205e63282d77f7e7e5eda047bf85b970652104eb5c3b7da2cfd06df36941bbaa65ccf26c18e6e5a662b238cadf1386dfc203301f52a2ce5eab1887649740969576169578f815a4f538786f6472b2d05e74e0ace554f6abc2ab4152333ca49450559d0d9642219faac41395990cae2e942413949b6e1876c6311eef60559985ad6ba67014976bbbcdd169d34706169e0c249c2bd066c85d522a67be60d8cc22c6d3145392de5f43c58cb0d9cbb0d9cfb34c0b7b49de1348f0a30c46570255eb3d826b7dc7650f6d295190d42e98fa563298deedaf9fd72f3b15331d8be804fe5f22a1ff7739f66c062a35b53c13bd787dbf5e11d9a0a39717057d767973a655003919578bc60a61a0cccea2e5cb292fbcb5cda2cb67f992de565b6c6a123ce2488f1ebab3bec92795e4321275a74651b54d7d672c27ccf111eb2f7104bb7cd010a9bd00e0e746d1ead552aca46695066735e68a5f8cd85b5b52b216d6e927c624ab1904946ba90e42dd309970b3a9a144fb931742e36e8a6c995c70f8b2392cb3f1be396e1aa20f9f70c573f335d2b14f5bed6c57f438234249794d528614365d1811a74b796e66dfba5510649be2fb0301e7a06c6e48e779d169a2cb0d014a1cd25030bcdba4f834fada62034c9ecf8be6db3997655b246f68747e96020fbc4ab5570a57f94decfe369d3e990e1f6ed9fb8d6bc31c6681c39a0c19770b27af7377de50669b47ea6fd317957a338088bbd82b7e402a019ad5decc7302882e4d75354826189b580f8bd013b01277cb64ede62e2b4bc4abdcffd1834a49c765c4a81d64844c7c38ad5460130e5fe2f34d039bf0764200ac10664c0cf2f8ab2ce443dc0293729c1a97a9ba2b05f431e5011df6175cf4952c40a08db239e16a6f9545b4bc147b6cf5a78c32b3cbeef910503eb5cf3723a006be540f76bce69e71aefb90346021bd11976c64f307ddb61fce9fbc3f35047fe4f38d01b0f7ad17162fd80ffbcf817fce7bd93650ec283c85ca2f5e67ef2f0792061880e0dabdab86d0b106c8c0c778499bb1a88cb82cb3ebbeafd9661520f1745b997cdce3c554b6d8ebbabdccb120051b2844457e5122a86d97cae455e674ca092941864421079e9a259a7927a975d4cf5dff45d76e154526796d74682e61cd9402675764ab788185e64377991cde9ad961b7b39a34aa37ab24e9ec399b6d2a59e4cec5db35ca2771056e955434b4cb41a6c45bc4c0097778e6362a46f724a6b23774dba354fde45498dd64daa9db8428f8d94a8d0400da84b948780775a22f04042fe32ab6767ca45b803381d660ea5338ffea399fed100da1cb01a1dd667bc3ac2e91f8dc282335e59609a582d4693285fb687818caef0d6be3a00131f43dda7221d0c567885895099aa1a72d3d077597d369c319e93d3667d0af593f89d8ab47ed5d011b96ee816d96be836f92a7f7e525191c881fefb52167e68e855438e75d1c7867a596adf07bf9eeb3a6fe567fb92bf95e7d488bcd1e5efa0e895fef587fefb194a5feb5f2f1aba3b225ff4af6ff2f307fac72f0d1d7909dd1b871da33e45db4f92af0d9edae18c1f227942fe341e2d47381df529fda599fed2a4bf78430eea78315d2cd2ab30fb683381635fc5023176966ee2132fb19dfe623b71491e7677c17fdfd577797e3775cc07347e24476f1321341e791398d13f178891d1520c6ba50b7e572d973b6c8b6cee8c701087a4d47781dddd94794be3cbfb769fa4bac1f1ce888c47811f6a6f572b06761f995ab61fbfd64ecae8e69da2c1adcd4738b6b5fcd424893ca75e3649f2f021f33328fed9691077464fbf1919418000f68c009bc0405ff077bddd8cd014d6c2cd1f52cb4838039224092c914298dfe40993a2bfc93f644429fdda24c9cf92b74a6d19da965597cbdd274aa9b2bbaba2a11b7af0a5997e51f4e05d76810e2135cd114e910d3d8704fdd248028918c6cba57856e324f9d248f64a8ddbbbe1e9a9fccf4683b2945c9fed3a5e8d6318ca247171828a80f602fe59964319ea03ab414b4f9355760633a9c1c4b6cb12b8f60d2b3aa3a3e9b9dcf1315c0cd58cd4f04b755d2e4c204727605d95b66a84b44592a04f0d550f1928b6c0b165af4992fd1c15e46583c143a5900b490a2fce46c0bc805e420e93cdfd682f464ca0e4c9fdb7a095a15ab3f151692e2061a2ab67165cb6f8918b53dda07ebff90ca20a3db38946fe2a8a2ba15b7acb2e598ea72295fc760d97f551ea6d4340f95b3db4d69831b387650470ef1470753e96bc28797d437777bd5260b97e29d06f8dcf50614f1d5e53801c9173f4bf9ad8ac279ee6336ad8689cba8739ea1cdd2850c5cb8345f614518f92eeeea663f9b85c6e9a929db4a4a3671495743cfa13f2ce951a3f8c4a4a8ca7bbbbe9e6cee81985bca73be6f171babbe3ee719a296a8f538e69edc4404b553ca3a5358fed53ba5f24c9a70209bc5afb5ddd059092d4349a7dc77aa50f0a5492bf84a5e4569f50691b20f2a85de11813ea956ff8ec4e0179da13bb39dea86d21d7061345973d2e1fd0c56c28756cd711ee10c723c4c979361fabd3e432472a4c813ca6041c53cba5c821be99599f83c6dc07be3693afcd928e1fd9003f052d72842713b0a8cae5a3a22c56e35a6a8dab5c488eb0e4b94a72da58ebaa8248fcfa60cebe9a1e37c4f4bfafffaab9fbbaa783c6d84f14403604afced8fc97a2fc2a41a09af6b3bfda2ab1eb0529e987c6f2808693b86a52a3d20ec1b6bd63241a9b292ccfe65331dd4c4355f27503d6ff0688ca5d4ed1950348e736d79405767227b5a28b1c15189300233f3649321e3d4505fdbdd9d8198d00b99489c97e63526db428a4a61f7cb9e4cf249ec415a830f0d64bb7d23885b8c2319c24bcefeed92e6057a910afd56069629b19ce4d25f7a32702cdf370e714a6d3791e7a67f7f6fe7d40dc6f92046000c8120e162f978504cb3de062c05258b014ff14580232dba7f47d336d91d2f78d221d698400d3928ed236e5fdd8e08792651d3d43a51c2020c643f0172de9086246455f08fcb0c04f65edf1e6e859391d6f8ed2ed27f269fbc9281d8fe051fe49c7bbaac2eee628dd625bcfcae916db4ab7b7a054fe49c7bb8f467fba6950f9937c721d0b40e0a7a584c57731a15c8b093b690cb18fce67f679836f39fdd8e8e84ccfe112a14ea7d1b2199e34d5cd3b2e5e356acfbfabb0826061dfbe627976f3ae22a5c47770004311a8387e8864edf01a82317e4a8be9282d36ca87dc4cd4e0eb8f4c3898f1ba7bc52e0612aa2861749a78fc547432ad7cb6ce9d38bf7d8f47ab297069d3dac3bf1f3d4c6aff30a95b8789e8384c4aff3069ee779808ff3029c3c344d8c3a4d687496d0f52ef2a75102b67371f8d256bf62f9c2bb53d52607155a7dd8bc172df10db00056cb18c1c08ec70744e50a06372de58ddd87c53e8764b097db84964834ffe990635e86e23485833a4cea98f2cab1e6c0109ef8763cbbf86dbe3e1985c09dfaefc40f9b1087ad044d64262626d62adfa3c70e8d312f752abc7d455e9a5cba7521947bfc01ca8edab1792a0373c0c4dd5db864f02b34cad981fefa6ca4f2e78394a6bd9846fb3f3a9a18c1c341025d23a3a82a891bc6c681d09a1de37f4e377244f9e4975eedce22613654d6736cd67ebba45cf33f20bc7ce77ee0bef88781c025da5efb6b75eb8ca9aa4fb6aecd628992fd00b4e47e401a7df38fdc2b5448b7bf1270e1a1b37c2aeb4a1651f1a3a96b3af8d686ec252735120dcd527193d6848a33292d6f46543b220c6f568fb09c902a3b9acd32b5e7b8cc419bc9a4eb96a03326f05959c36132b34cbb4c44cc771cb3c09c56c8ab240663f0b9cc7b3c84a70d6ca6b1349306651014ea3f6850a07dd363e54c9112ada0a5f4116941b83d1b99cd49c823e48597940f1055d4448e228e9059e1b85f885a70d7237cd33ef63a5769abb34f2675ecc11d457257705dfe8571898d5b91ad8255d74294b28a597aac2b9915e4fce41689d63127c41cf952dc5a57eeb16756116952fd02272f9ce0273bfcddd2763388432a586b463f01001672abfe36307971b9a738fc7d1513d6ea0de26997194911bbc6a61402cec04ab1fedce90e9ac23a7b4185e7071fa329b9df940399da2e01500e7426e240d25720aa2ba9c3418a74eaad7d05310eae558a71468d7267d886c88328c6f957e2053c2b6137ae2734105c9498627b9d21f9d9013bc0aa0bb3dda7d44162dc19d9dab6703a41d20b481129e34541de6e89ca14c391d2d9783e73dd009f4acc661803706bdcadc277ad04acffaa793de4953f744d13378d9fbfca6779555bdea82cdf882b3f9f01fe21fe2f97cdecb7a4f0f74aa6e5b9b0e87c367aeafde193f3d63658f8b5e7dc67a75c958af2e7a176571c9e7ac97f5f2229364b4c7c59ccfb2ba287b45d9bbc8b3193b2bf2392b656dadef1d0e366e9884ef6aa72f191e156e66139386fe25430dc9ec4ed667e4c23b23b7d29c36e43e902615470b72d6a005186fe0d0106d2cdb8175bd9204e2e682916bba08ed67e4fe79b49d789d49ace920a8576b5569d6e2f1ba93125f776bb88cd26ab9ecffa1b0f11a43f4977b4ffbb235edd51d18b73a686895a383c6339faf2973fa6acdec3bf7a1dcdae83b0ed6c8333d9ef63c73c19ace335f6ec90d7bf6545e88369fb224411f1bcab067c4cd9ebeb7efde4b7ee379437dfbc62c07fbec676f250abd6d82c4ad9203bff565dc07cd041f3474a6a6e92cc3dbf592a4ffbbe4b1baaacf7277fb386ffcfc9e8491978d17f8200ed412641910d67b05d512f20c6372d2045e7ba4f60c39a1d783863273bed5928570a733981338a60208ff68fb4972d00476cac063fc3543922b81304d637dcf19c3c4bb24f37e748211296d2d5f75a0f89ab215bc86762a0a26c533a5d12f30e1fa9107915f56dd4351a94fac0d8195ae0b175fc9cc9b855bd6da50788c1470f23e6375d00421bd1c371fc644b2e61e41e9ba84fe71a381b743d03426e3a7fe727577355ddf511a4f27ee0ce355947e02d5f46f994470a7ab08e2348db61f131fbe11c4ba5c3722e6d54f188460c6c6a0c6ad9fc4eb90221db88d148424dbd1216f9c7165ee0b03a2e8fca68367684d00263cad7d9234f71a0375a46ee05b817677c9456c4e128fe5425334b9437384c319bd6e8cb8fb2e3184b97cfa3756f09eedbeaefafe0c7104b31fbbf6828cd2dee3626bbcc7900cffdfa0b621eb849deade5dd0458e0436c30fd569b420e5d32e21ea54d70d0abb2aaed3aed1510a2db75b71181f36543e1c63371a2726b584c0939c8ebc9a9ea4cad10c5726eb1a09143a68e827cfaa439207cfe9646a2eb73e6d40620d7100f5704088d2828a342a3414cf66fdd6f29cadcdd6d97429e8cf262fe08550eab73301316421d20458b8f2424090a40117bd06abcbe66d254bd2661856214cccfdc23d315f2935b5be36cf28cae5ff4d14a33249726b9acad9d57279c5c5bcb852fee4a63559c9ffadc63b83787c74362c3371ca5e168da8f16d4e67c34cccce8a1298401d3b57177d582c2a5693059d293f52a83233bfd45b105539ab7cb2b08f8eb5ca434f2895427a442ee8c3313993ff5cd21139a72372431ba27356d4d62fc39cc727931b95367aa4c2576cf529bdb1bd2d97e882ce372a4c64ad85aa35eba87546e71b334ce445d99527099a6fe8df6076a9edae9dbbcf09bdf103784ff029bd2137f464e2b98fdc80ef889a2608384e29a579926c6c5c521571e382ce3191a50b597a4e55f8923359ea772451f9c09c1b4a30754ad10d3dc59ecfc3ea869eac72fa50f23417cb25fc3dd3c1ea14d65d009a9d69af03b50aab5c825057184185515061722ee86d36abf9a50904fe8ad5f2cea91331c2dab3b97c9736c462f0be44aa345f919f6bda1f93370d2d24ef26b1e32cf7dd541d0d7f138b72b7b646184f4e73f4a6210ccb36de34deb65e8547cc9b064ffc6e546049467297f6e54da3b9b52bd9920b12c61768fc28b98230ca6f7c779ec10093f1e693e44a7d762d3f0bb84e73bb51eff7e83544b1d0a57bddb7a5bde99e8a5e91ee055405af8c81fd78b4057d6a65e5ac416f1a39ff405a11d8483d5a57892c64b9c7a64b3005b2cdcded34fa683cdadc89ea3ce9aaf3bdb6b7d3ef547892560d6a4845df3424c7a469508557ed65fecfe00a5fa03d7a2ec83550707245f7861e2e939cee0d436c26d77d4aaf12892757211976fecfcaa7ced8f9f551bf5e2efb0242c5506581254bb62052ad2136c0a12b731f2f1e3134e43b24a6036d9e5fc903a59e5a73fd0a099cf6fbca813a2b9919d5c7a2e28afcf7fb12bfd756500ef72b14cd6a38d70f7adf932b6c7346e5497226d0951cfa35cd87403e889333edd17cc8c45cbedea3d73625817f225e4dd155740ad26b72159c81ca60f49c0bb447ae94c5a921c438457b145dd368cccbe5dc1d8dd7f7391ad11edd8b4e4752d12b3fc386ee93346e3c66ca152639b5f386494f9bd4abc6c45c56eaef0dd975cdc43c499a677992a08ae624a70d696825fb9b0b74451a4c16ea29c7a44a924592207933ddf38ee8e572cf3ba0e5c90728e38ad5310c2f0a7894afec710d4e7fe603efd88672555f2e1abaa6d73a6a09a03ec2e06701ab84548fc4b48fc99ef6a57b9ee750bb429834cff229da1b66f3b96ae05a565320406a04c4768853742d9bdfeb78478236209cf2353d3c8263768f5e4de4eab94d32c1f2d4dbf3cef16b15cbc95a9def919c2dea746f58cdca22cfdfb2454deae2c2167c2a2e562a9857a79c0b4026f7bf0ea441aee86872f5f4daf8655d6d6c6089f2875747d84448f1baa27b43d9bd0445f0ee537141f7867571b192c765ff529073412f5d3802734a90f880bb724946ede1f6b575b86d3d4abe26096fd01589c9311c6f5ff1edb5c66260f93ec916c2704c9f54db07d43f1f8d12ef4de8f67a4d0f228df8353d5875c0f3d3f413bac6e9273bc1ebd5ff18f93736de6f0aa58be68ae9f1802d67ffb9c1d6dc9b91170dad9df528ac8507fc3aec9304bf74675ad30544b2d368324990b6338f0c88eaa9bc1a3d68a6df9a8d8d14193b63865378ec12aee649729dfba131496954e8ef0c0095893ba3af1a6be76e2507d6fe78b9fcd9841577f7fdb3587268119085080821db771e252a2c4a8b210069ddce78336178b9fcdc2c97e833f8783c28d0eee320288af1ccc9cd582435682fb5f3059123e40bb42b79ff178d19dceee3a72f9ae9eee3f4456366aa8cf8bf158891f3dcd7a29feb2634debd6eb49ca13f9ea8c65e83fad03803ac976f6c8db1094ffbb501faa2af96cc334ef02ea37ece53b9d9b568c4085124bc82180c3f1623aa413b446052a8bf2b67a4e1395caddb6160c421b43041a33a6b613aa3d62cf96b436b0208d41f39c8dee4c667610619e0a9f220a27fc99020b58ffcceb2c0d8cdfbef9244d967d886f510e5549c0138f4064e5076fb1a6153db44417fa961799323a13e752660eeadd1ac078a938ecd28ee76395a2e3b2391de533b52620c601484d1cb06fefc2543b5a4849d6014128ca20d466746e8593a38c89ee4611a46e6e9269d4d41399cb39cd50cd59880193a4b92970de4a4d466e8cb253c5c834964642309565cbf374f7746a32998b0bc6c70ba2f0942fa56d967258932e5abdbf68049523f85f8996d73404012df51ef2a30b889ddee8c15bf9b8a26d923c5cbffda2065dc4b9876308b71b476a879de4431219d477a3ba1aa0882091671ae4b900d06ba953e44ebb828acf4f27d46fb23eb125a3e75c1afe49b7110e56a2bfd9cc9d91d67a86db7f73b649cd8d6d93692445b00154315dbdd9399df2752bab21b0963a1f9992bae8a5608a7b71c05c9562207e5c846a7e5e1af7dd40aedca3f3cd6b935c9ac407f2d48313cd62003110f8e0b82bc5bc6edd924d509f367b8035365d7f0b2c24722f724299f51317d60329aa6a81ddfdfe1524d6db65e3cb5914e5408c249c787c18021f547d9bd1acfa8205dd9380063cc746caaf049142adf576a142d6024092ae2bce6854bfd8a753c787fbefdd297df9b83c3ce7d0588abc552f0ec72beb276f67b3f0dac06810a88e72b72a2c85c75bbc057e560c2da99d22f0b549385db78a4e470fb2705fd33578a929a948491421686099848cb56c905c3293a75e506a626a010a5b4183e78a0deeadc0e609ad2caffafe7d3b22e3a2fe4c9a185ddfdd10476a00e492261dcd58e1c9eda905e60235d32d57f95603093d443cbc8cbae834f11b42efbac24b994902c0930f3851e7949cf79907a09b670101bf2353f6125adc995fa1ccc796bfa47e616a33f82302b264eac04d8883cb715d44ad938f4564737d3d984592a012d71de0b7ff96f462c7756c0aa3e5451788fe5bc9b0adfda47ad3592e7e0f1ac2eca494d6b0481604b5635790d89aac03a27f00e1ff9cd25ca5154dfd3886b7becb7835798dcd986fb6e33fa0eaf56a8c0640c5862e6a038cbc2549c5877105b44d496a5854ae19b9dd2082a1d6863c9f0418e189e8ed3913b4fd547a008b55b86529adb6fc6e3898e49b07065db86126dc22418fd7b0131154d4ecbde28ade93b0f799cc781b3b3a9e9abbb6bc82a6fefaeb29dd674dfab22c7a1681ac39076d985dc0b99f6d1235290c1c039b66a54b6291e2c718c390df24e51df9244d80ebec145faf70295a4c05e78d9efb6f8eac75a840357b127651880c71ad55803d4b29585635399b5c7c9c25dd49f8e936b5a0cfde804a4e1caec7ca1c889b236c5a49d40cb7c2671aac0929922ded16d7931e8d27133dac41284a819bd16682dabe3ab9ac855466b52d03dc9e661526863eb9770f68023943a6d740ccb899860e1270ad9f22f8ecbf168733b08310884f1b95929a159434b12233cb2216a7fb7d9c914c77f60d7ad1b17f8fae04b0af4b4189a7844e45400664c1b9dcede064d8017ed48ece34798bcd16969d7b2af1de9f6d631aeb5c96ea5e1d204a70426b551c2784c8c0f06d191d9c57280513296eff0bca485d0d6c0cc2cf9418009a9bf96e65c3384e7bb5bf6ed8f6d599b924e771a0f351ac19328f070f7670e0f5a3318c903b96cf1f7ad69b452bf134e0b1dc54329e6a32640410eb7843cbe254405945b0374cc17a0a257d78e918aa2f6aa4439e1783a4a47cbcea822c3e35996cf9a3cab99ca663b7fc1eb6abaa61c1a4bfd9b3b9c6c8d0512b085e64792f4bd8be1ad4f93ac59a4158818ba985bc486bcd03a8a4e8dcdc5389f1803f93c8879ebdd5e67f8b6a1b95e2a236ca9e82c488366daab94c8a51a6ad82be77d793ba986c549c5ca4b35f584637c3b06358b0a4887aa568417b0b7ce4985e53a459104044c27ceb0e92e5b15cd3d3bef24a9ba1a880ba1016ec124513436ed87efe2426a652d15ad94cb855a89868e476e8eb962835cdc7f49ff0c601dbc1b6c6c1f69ee245c0dcda3848a0df89bdd369e01867f97cba9679f766b97deda55ca06d5475e7cca9c362bbd6f8b70abae39336c8825733157fe7be196c5ae2973ab2a692959448e0ac29d6f818f21b875cb5a4ffc2cc1e5c0d599a144a320fb7a6644555395b866ba8c5cd59c81867a75b4e47ff0f8fb74f73be4f65fb96f985b22dcfea688d1fe88c0cd0fa71009ce80fb54313d0536b729b81b457729e6666597d58a0deec8ee0654f73ad76152b4a58995cd7dcd5dee1408402447cc083c7e653754a8479b650f6214c1d9078f8662411d7b5b540d4960c2930f5d352359cac59c5dd311d1ed2cbc574150ee5a950521bfa124bc3143917fef0eea78a1bc55b91c66a99e1dc3a607e3a7e493bf836cbab22096c03ba8c4fe8dd07e4b6c224b43d471c2d24fde82181e875df9ebe4eac2edcb1940c09deba22cea423b72f4d990572abc93916e7b5fbf8cc4b2ceda26e4adc4142141e5b8206ab1bcba7e65378469679f60795978595748c04c920487212c0843ee60c1c240ee384522c606112c98682d8668077e17b1f53026ddb161ba93a7b662e2b492a78a2879aaf84ef254f19de4a9e28ee4a9759c3c5574264fadbb93a7c68c78983cb55e9b3cb5f693a77a29286d983f22f48e66ea2f11b0a921d7901f35ee83456449e94d60d54d7581645dca558601cfc18bca4b7adc4ae8cf7043778c2967183fb527982199c7b9890b240fbc82701be8b66169439f9062491ffbc2ddd21607a1f10bd32262726f8c3789203579b22ca21d514894aeed538449dc24a89c45cd6d4173b231f87606df7acdceee6aac8a1adbb58df94d546b9a30960412c6b1e4947929986c9e50271985deb904d87814ca553259b81b96e550310adbbd80c2edb0700e858f481998b3aa7717f2dde6e61ab1cc786ba4af6d6cca52330b5f4e836a09a3a61344cc08c7ca76925aeebbcd1cb7a8b602fd63c248496ad96c1c51c57307f868b57dfeb78fb4c2ebbb9fbf8f3f87196d5bdec5a2fbd43da687479a8e77b6eecb7e6f836b711a47e0d6e4f9a5691886cccf2f1418a1d1940dc382950fbbe776f89601d1677ee8a4a4c2237a5d1b3ec5f966fadc831990f7f55a9f84e0adf36250e3895df0834ef43dca0e4efe70df9aa8bf9a8b6abb3504c5befb8263443ca37d5be8e95b2d43d27636b0d5439702c7d3ac2bf77d213c3b82b711c3d06ec3faa4753945401e7f9124e299f2b8a31e0eec7fb769d219d666229ed6eb5c276a4c50f9ac5e2e47e0b562dd205ab5ea7bbb57d4f777af7073fb5dcfad7ed636427263f7615efbfe392d186b30a2fa1915ff0e8f94fa59d707ebc0b531c644cea4b3b53b820cd5be45c09b68b9e3d82a60b5254c30c40ef8fa7cec3b8ff61a45be0913c195e540432ff8b0d28ec7134e7f6d10270569f08481aa19dfd6a06dfa8d41b6ac0e4d1756511dc726fd4bcb7169a48d8e722a3c7fe23cf227ce236923bb366edab5973aeebc404a1a81f16df84d94a0ed9de61adfb1f294a9c41f2fc356572bd940972f6e8e27f11cc62a7a4e647333d319e7266a6433c842735220416624f7a45b82ea0cf18256457487a8cd6ca7b52393691d935141504d730ed944713b8e315b793960ac6ab6549c6ea964d336626f89c98c43e045f2e706495e93708734af72addd52b72623b7d3d238dfc3cdb239ed047451a66ed64a36e7fafb4363bcf09295c5ba7c7b5ebb901049025653e58d17e5d3fe0e76c167dd81ee88400fbe8c4dbf705fbc8e6c8ce435d39cc55a652092a40f5bd12a504821798b2dada091ffa880878f55fcc3e9563ac293d20b5b57789c4449320edabdc397e288962e988bf28f6a253753e4e12f0cd578f2b22b0237c3b767b51181604c3edca3d20a8dc82e28559d0340ca22672f75fe1e73bdcff68ba2a6a503dd8bf0e2cd1461609e31f46ef47b1c57404f8282e572d083adfd1092b13dbc28b8a81f1ad15b6f602b2bd1b8b78c5fbc0b95b130105df9915482219dd29c87935b634a5798fb593129682b67deab1c6578d2c096430caf56ef7254938c305238ffdf358389f2d2f305aa974b54d33eeaa39ab269bc42b187847141069aa7ac74d422d41e48fbf5f02cab9ed775c94f9a9aa1c13cabb3873098b228ea01c698f46b17d86762ce22687582c3e436c2bae9ca9d02bb6744eae9adde1a697fb4d2f13ff04ae71689c1dc75bd2d4c749c3b609c3b18d77990ecd707b9533dc3570e45be453b7deb69569e02342b6d4def5998d857875b4753ff07405983e0d6dcf9d29a91af4c655eb0a47830d82889bd6930125e20eaf876e01b3e3e083883cdfb0d74d31fe8a61ea8a4ed2f7254c7f6c19ba391cbf86120a3d4cdabd7b9939f691ba0c01a42b11a2dd2e0a8215e91a08d46e5566caf6b47231096d487d4e45d6e7cc0e14f90e41948a836cd5e91cb3ab6da70f9298ca3f99f0b04cc900dedade36a93cf26db23390f9bf1735c20a8bda56b6fc94e6feed12944cc551d8125a733e274bd1eb76c368dc95998fd862fd00143dad248401e1fe2d2fc8820cd8f0eea25a8ca1de0bc56247fe7fd5695205c5779a31c938af2799e23d5e9a1ec840e36fe72f0e1fd50099cf8e2060d061b35def8efa343100ee8311cfdb71cd768523f15c647a5ded8b0a7eb610d39f64ba54d28e54175ae224514e5b9e15cdf0b54823145bf88d0765762ed35432526070c7413abd56a5d1e201666edb47980146c200da44ae093241f65ed7e5fb8e43a35e98fe5b2fc4e594edeb472ac93d8697bdb8f99f7ad40bb4f08f30218988fdaa1f4b80da547def93b04a2aaefaa68ec3ece3bf5d917eb61f0a599988400acebec97b4e44dae0cb4ff06993a3126aa5384c9658e2422bfa25d7c879edee60f8404841bc02f39f93927bfe6f476ef5252a4f4f058908f82bc17e425f94a5e89c0ecac90acc93b8157e42dd9277fab495393cb9cdc6ade28ed8f5747abc9cf3945bfe4f476c1c51cee232f6e7e2eaafa8dce08987e10e4a411f31c0ebe74442e595949d23a183f1a8eb786e30151d48c951fb3d9d7ec94bdcfce593a501cc7bc381facf0704ddbb191dca01173b6e082cddd19767cbcbff7fce5a7e3577b5f3e7df8f0f6e0f8cf6f3fbc78fef6f8e70f1ffe7a7c1c3a72d4f4eeda2ae517af5ef14ab23e7338c6abe6e2a228eb4addc5747ba38973d7a8875cfcce66356278729d077449a5c82dc4cbe2fc9cd7d082a4b7e06aa083803ddaa6da40d7f8877886bace2b6ab5227bdf6ddba4d31584059ffacfa840b72bf24b4e6e8b4b56967cce7e2e8aaf07cea2d3147b663a15ab4de82c258b2a75f9ec8ccd9b5ca7e75665b338d3c73e5ba46bb380c885f757fcc50d4c24f5271a5ee710a302f215a8f3ded3e6acc83a14ed68ede77cfab3e46a54829ad638aad7851c78c9aab370aadd8545515b48e91a01a04e9999bb9a9e3e3c493d3c3e3ed87bb9bff7e9f8cdfb4f7bfbef9fbf3d387ef5e1f8fd874fc79f0ff68e3fec1ffffae1f3f12f6fdebe3d7eb177fcfacdfede2bfa6b4e6aedb6f9b128eb2ca70f64899cc2ab0fefe0b613ed1b2d858ea3a78c0346d7bc65cedeb42d8b7079a9958dc11a1b4dcdc0c4928a274f707cf3df7cf4847c0049fff02bbba994fb8615e5056b5e77ae793d5ce44d75767023666dc67eada7d6f8898b44d315d05545c309ce12ef1481a0b6faf870f9d5624ee25e5ce017cb67d5a43f928c20a9dbecdf3fdbe05837a87941ab8a7d5e77a1491fee9651e3dbaeed7e9f75dda7920445370333063d90fe38e01f3b1bd1e768c05aca2bd2488f5fdb819c00dd982b8253492ec17b19ec8910178c399ee2b9ff05de3e1c8e5aa883e6a42e197b23eaa2fb92a904841ac2a27bf9dc365d2eed0eebdc83b1cbde9360f15577fd312961a8fa34a6f6345e9118ad064dc57a92c19cd58309a8e5e47147051a8f76f177aaffd74f7ffa53efffc9f90cc22aaad08d97a3e1787738feafde9f7a864096f25e326fa09de13917c3dfabffeafd49d678595cdc94fcf4aceea119eebdce66eca428be92de1b311bf63231eff1baea658b05cfb95cf1a1feecd319af7a55d19433d69b1573d6e3554f8f62de935c4209111cdfbdf9648a7b8ba291cd416847d9c4db372ff7de1fecf5163c6726e2a3bc9af7e6bc0456fca6572c7ab5d7915c6439809f6c92619211f00ced624c542002dfe5cfe6ec7ac7aa2a3b05833fc172730957c7a7fa53d14ee633c786ed60d44343515c213cc9517f24794d1df2c5c5380474a958fd49a99350454698b0d58a2ce8abac962780fc3c6caf23d999abfb70b122e1edd48c6fea755312399c14e59491a877bc2245b44367d4aba312be717f10b39c65a5793fc32b92b587d81fafc008d44e64519433f6baccced97e40a125236423bbcea95aaae1052be5850838cf0b5328674dcecc2f37467269cafc9145c860577c5688aac89989726bbe945de5cf053f0769040c74d2812fba7ac9be35acaac3fa49a2db1e32200803d81a27657155b1b2372f5825febbee6926b6d7d9c4b0f72efbca7a5553b25e7d96d5bd9ba28150a7bdac7751e4370b9ee77287a810a7bae96ad83babeb8b2afde9a7c5c9f09cfda4187a53bf1a60d23193f31f1b6e1780fe43a35d75d91ccc3b7db4e67217e0efee97b9da2c2b3f86f0c57d379baef8f046a5153ca5fd313951b4e18a3e1c936bba43f6e868d2b10b7a31657846f7e4bef0b19fdc6393307c3b7ac696cbf1e6ce53368d962dfca857675f59050b50f19a5f4a825af74e587dc598e88d80908f3777484f7ec6c5696f21bf945c536562eed6679990757a8b8b4a527351d4bd46684460f3014eafe9e8299b42d495455e14251ab3ad9f184e77d4ddf7abca74169056f2897e1dca063627eaef7858887355a59bc29ee075e4758fb28d6be0114f14a19d7e1a5e1455ad7bd4c19e90b75238a6c11d1f10639b2dbf8ba9ea0965e474b9946d8e48c7c7311915f8f68a9e05ac1843f144205d634c5d2fd11506c4f2e4a10791a254c995980ab552632f89be16333d1c3f7bf66c4c0aca0e4b1038f591731e4c92d1d363958ccce5733d2c8f684dd8a138a20511b4f47a7fe95dd65cc82146d9e1e8c8dc033cd32e2f42e6e1e8c85d5354225633878be24285c5133a41ebe1e8888a894baf5fd21129dc64cba7c5c4889c36ff84ca8d317e3826196587fc8834946f8c494ed96113769825c9e8d931ca88c0d816e6aa3027199e2298b864779b234870d4e054956544360d65dc79147970b4cd88188e7e73361f75afee4e69711cb9c51765fd46ccd9f5c3da3d7b014220d5271bf2f9c37ac8e740913ed2c323f25efef39c8ec95b459af6e916f91d22c141b669da1f3b73df57c80bb35bd397e8bdf535a88324c04e918a3fc84a0e0ab58ac7040a49ca4c903c598978e36e39dc9303f4513214aa535f33aa2f3eef2001286298f4df60470b5ea28f18bf917baf449f834470c1e093a4407f106f6c0f99dfc967b5311544924475c611c61252239de1707f6262fdbc420293b7d0b7e9e16d92a03e7a1bcdea99c0cb254b927e86309e186dd95b0bbcc071e0d6959b957a3bbcd0463f6025a12d089a563f4fa9c013d1a2875dfaa47cea7593a76fa98261927c401f3179858c47aefc395173f41c13de62a5f237610d9437890fea4a81baf2402d309949caa9717566efe816234bc0486f415ecb558f8c348d93d4c3b1c91d667c427746910f9c17d13ff4e91ab3ed49a496df615beafc7e411bffcc7f33cf9935b9daf10fe337e7e76c2eaf3af6f5d87ffdb6b8b22fb6fd17ef25e39adb775bfebb8f6521ef4fc64bdf7bf3b962e58bbc987d052367fded6670a7060eec652b17318314e03e4a053c8589a9be77cd668dfcc03f6cde2c97bf2f97c8eeacf04eed64651f7dfcece073f6e3ef5e835ad6b7746b7f0448e77f27d875a84cd2a8b16f51c304685496348a026cc5d9a0e8fe4a51d3fdc93ead43c1bd931ced53b10a7abfc89aaa1b4a91a001f8f68f1917357d11bc69c42fbc3eb3ab17deaa5a681ece4523b046f070468c6e793362fe8ceabb6664eefc1d384304c90ca16af1575dfc77662d5332734bce8673966737939c0e44737ec24a8ffc481e239f361b79da90acfd3e33069553fb944a62a0885246e533c969e34c096ff93c7dbeb1410ca2a78204443365c492a2342791c17b46f38d8cd873297d385e91fc593345de814b737280de1366bd6a15c18474c4e83d96e7c594239cbe939b4512bffc6183b16417bc363238e11826ad9d25f9cb6071ce8a269fffca593eef500cc74b228f442d2485f3c8b012ea4c72a79370b1744cc0e699cd13238243bb23f76f7ce02c97190ab7e855995d749220b517f7cdc0a21975edc561767191df40367462857b1136af5644fd77a7e84b33bd680b93820af418134e05dac11381c663ecf89e2c9040b261c920610892b7957d76ba777d8106e8ff2cfff18f0a0f36ea8d019aa6fff847b57c800764702a6fd10fc6036cbffae91fd5c64fa764d0f3cbfecf3faa3f2dff51fde9817c3350a9831a2ad008844143811a794a0a34dec5a4828219260bc987cc65e9134c2e02b0dab1d7c8996e4c4a9dbb54014fbe582ee5a38a6a2e679f247d31e4d5bba291d4ff745a0f99a85999d612ea2c2bcd3a95faf7818a26a14f252ea67c8a0a3a60d75cdef848546d008d71713ac069a17fb1f9202da815707f107bd7bc5e2eeba1f9292b4d07fab5acedb50e5a0408d65d37555aac480906a42f0346a95c29f504e2c30c2b656ebd36ce49b7d4990db948126f10c0e4aa6ea7a67b33ae95520ed904fdd6a0c3eebe205ed8bbd8c6c373465370939755e5f6e50113af48d88e92a8776c2ea32c6292d505f373709934ba4feb7da7e7337175e482ba3553f4c1ae9a31240e56f5ceda60a3055082caab8e898e416ce84dec179ee79fdb7630daf45d7236efbd0547f0f1a915f1552d12a944f91e1ccc39e28e8c9a0a5a6a5bd13249cc21642560659220066944784d6af920e748844bb265d07e6a1ed21a935b593f65446f28a2dfc8b357045088ed09ac2a01faed8f5dea99295a0b07e256024c2bb5df018847614b2186d3a0f09ad7089b32804cb025e55a2afca6b48d3449a28a20f66ccd90dd136ecbac606dfc2174e02a1026e12f8f026e1938494cfd1f1eb94ac143d77d2b8a39db678be96179941e56c3ccd7b002e830298f08a7c5e1e88864b4381c1f914635e0e1109234b89c36662d1b35a6495f5eddc472b950c3a9b2053b68cddfe0ff2a34c0d2032c14796373c4f14af204dee0f53bc449a62d4aefe841aef39d5d7071aa5b1a16e253990915527a4fcc51641bf6af4e846458a9fe5618074b7ecdd798b2913a5870b9ad44d72a945d6babb647dab9ba933a49fa8b69045589e8e5dd20d5246a15693dfd2624404b4c580b9c42cd20fc727d3f2d9086ddb0392a3d78a6df19f57d5b9324b64535fcd53124c63808bd7459035b65ba29a461da3a81a13b7fcc1185d3cb5fb13aa061c690da1215a60f87a8e27a32d21fd9c860ad81d98f4a7cab923b41c8c536fbc05009f7db35b30e800612e0564d39e6084b620874cf7fe21dd121d6b78b8cf151f74ed0ce8f7088f4bd8fb3f97c4fccdff2aa66dac85bb2804ad5bdb69af594e9a0b4adc91fa587a20d9288ea4ed6f6a5e889c24696249e86b1d52631f7c03b2b8d008562fb8cc0b236e086943ad0e3fb42231c876f6af8927279213128925c3109b9591271bbc470d744b3dbe02f0ae59a39913502b00019378d3912ef7eb0b97a56cd5892659fe1bd5e356dbe830ac51f1f0eccf80764c0e53ffee00764100c7e40066af003cd72c8bfaa5c0f5ed608063f2083c236e606ef7e48e67e5098e6ede0ed33bcd7831f1c39e3897c9869b32a6de88fe6c36cf851257f2cc92d98ad6a7bb1aed8bf53b91d4b9c423b79216c33b2c0b8840e0b91df208189220b2bf5d2864870d7c633846f5717864d0197e0f93023178028902599deaec88509eaa7ae1fb75ca4fd31f1212e7f072097059a17e98f353fd91f11e02ffb23a281989e11075bf783cdd5b3ac6c1e6c05806d7a2647f5f9fdbb0f9fdf7fda7b453df42717c3bdbfbf81427309bb18eebdffb4b7ffe6fd9fbd8b8029858a6645d5b7aaa25ed089ca297b41ced7dcbb92a44e927a585de4bc4670656e9be9baea2555c92d101294e1e12ccfaa4a22dd54b867ed95814a9cb68200e86aefb37336f59e6986bc5f1241e00cf25c43e0e58004f592c4fb313cc92af625cb97cbc140228e26eda484c3f8ffa5ed58761bb781bf12eb208810b348d0430b690963b145af057ae845e041b5982e012fb9a0e505025bff5ecc0c5f7a3831b6ed259129521c7286c3797086afb774f7ccddc28d581e79e23eeccab91e09d28aa7d67e34adad6be63a2bb3835056b631bc9b6c00de8ca238b26c09647ae84130f236018615b41a3ec31880563dc95d264f72f000547441eba127af853333e44f76ea648fdfd5a700101dc4b7c2c11ea085c33d2004cc508795f58c8411f7c3e2ca72bd0f0ca7890c076617ebcda451a09cb92cadfc69bab4307e1cde1518ed1c4c5ed06d4c6bb8b4f97b051a88930be8d4f0df02b79c5dbd9c585e0cd66cc0ab8615b86ac8a19d49f62a5a16360065ddd31ad1266e218c6fbca301cc8035718f59631e75d5f9ef4a6590ce917e07b01bbd6e61963ebdec1af19af53e43ea8fccd47a4924b0d6e8c31e973001f2fc29d579af0b7a8b87519632deb6e4c9956c3ac58d9cc8bef63930bfd3e690e91b91439eb8136b860c54bd2f8aba726569f6a62e1e8ba62858ad1ad3a9c0d32e4004b1b7c672424f2a717b5b178f1e69d0b22e3ed10fc961ce9635711ea9deaff02881c3adac886f19f802726e2594f7ca6d9aa26a649da98b5850c860ca98570babe1c30cee362c20baac970841501acdb2ac5c2d8a87a2b62c522ebd5365a9d2cd36dc05e56ecef9bb5176460ac7e75bf4ffb137f70328a8cd0d1b6c6ab3db8d007a6a18afd81a59f3f8bc130200aa2bb5b5036785ac46b831e7d0ef2fd866c4228ac1bc5ed789826ec908d9337ca176b78484bb640446df58080a289d7afd25630b9b0148db88049101fbc19b368918b81606c9a9dd6e0352aa2bcbafd83bb7f46419d7f4a4df57a848331a458e8fd34ceb50a075c4576fcbf4df434b072d2f131ff925c8bcd85dd08c92c49b17ab21978bf337a01f79c9381483fa9464e4ac34d5cd3e8fbfa66db5e07521e7a7d1364531f1d7995600bb8e787de7e476705ffd4ceeab9f8854c885c57b51a1178b9bea89317e469f518fdea4eaf9974c4b39e444e3e33868bee9845a9b44f14c07fada7fab14af36c272d4c4b618816217d361ce2029365a8d65e991da7fd0a73ffba31e3cba59a5d81e76f0464db06d319627043bcd93173df8cc03dd28f7f0a7f1e6af6e94d965cc735e7ca8526223b63ad41c5b992aebe5816ef6eb8c6c5467e4a484ba5e8112c508ff5b7fbc7c6b3eb90ed7a2612c3d7c49b19e3ea8632c4365bb5e0a8d9559a3e9c45e1fd2f45fa6f8013c284ba132b63b4a0c4777e2a9751fe1673c051742490f028a3b27db73e79fa430d5814de7ee084f4736a54fe8bcfdb9d3be36fc8f74719eaa91bb740f76160964b70821666db39dc6437737f17e66e1c480c641f2033d38fe22c64e4b3e889b6d5f5859ee5ea217abdd1daed76359ee86fde17add1dafd7617f28cbe31b54f782f763745aa64e729300abcec8758801982ccce8ccb8364dea9b94a453750e629a625e81a232526190b29b77fa43dbc0f46eb537c00a66827bc09960ad597fedafc72b5a504ed7ebc6129ec7802187d8920314ac4560917738acb915d52d9f35fbf005e3f368a834d0453454f29cf9801b72d8bf28a7cc4151f44d81e1215f7a3cb4fe9752b0b4f5a8fba33ea9e1e1f1e174fea65cc56635001c351489354ea03627d7b8f74a7bc30fe6dc682e99976af734f11cf8c65222c53f700fc5d76b9ff5bf73277b038e089ee4e4a8bb0de5f334ddef8b8d1d3c4ff77bd7bd68835974a3cd548b7186da20e4c794103ecf24cdd61ec449ee84e6873c35e3d6ce7463c1a86cc1b8fceefcb060bcdd03b69a68ea3469d1a8b868a09016970a8bcbc03a628c35b0e9a0ca3dc3f4333a7ff3d16eca7287dc161ff7aa16b753e0887497d652e95bb97e8243c5e36ae9b39dadd65c1e20110d8fb3a5ce4388045ebcf510f6769ed064a6e000bc4b365489ceb80969077feb318c2beea424f2a1b0182a17bcc8ab161276d8cc8c9fd337efc550e5efc268905bad066583593efe26eb7cfa89aeca9032f5bc92548f1bd6673df19e3577d75d571cb9e5bd9731cf7319f31dd3729cb3a618f4f782e7f3b61561ad261244bf4d52b2f69f000000ffff82b01a8a1d6a0400", + "af9187dffe62ffcb604858b3adcfaa0b": "1f8b08000000000000ff94597b53dbb816ff2a5affb124b3da0468bb65c3cddc9195604c4ad39052ca1286318992181cdbb5151eedf2ddef9c23c99613d3ddfb4f48a4f3f89da78ec40fe741647998c44ee70d75f2649d4d45ee74ae9c47719b06d3fb4ebbddd65fdbb74922739905a9734d9d385855084ff2244e791045b7c1f4dea1ce2c9081439d55325b47c29f39d4992ed7f1bdfd2dc7fd4c9c220dfc124f62ba96d642e850271379123de0cf48c40bb974a833bcbd1353e95027cd1299c8e75438d45906f9f031fe9425a9c8e433e809a20884c4b90ca248cc38e80539e93a5f16e07021c8442cd186a3753c95e010eae4cb700e4a66622eb24ccc4a5c419a46a86129a6f7bdaded4ce4eb689bd3a1ce7c1dcd43c0e250e70e095274499e46e114086e6eb4436f32f16d1d66e2e606b66d334a3d7be8b334c9645e98036e821f800e14382a560e7516424a9139d44914b2301696b344bc5e892cb88d342998e15067fcbcba4d40a04cc6320be3c5e760e150e72188d64028955e855ce4859d31009a662290f0eb5e8086db30463480c08a9f0190824b20022ccb0258780ce359f208d4d16c2b34e8ae6beaac82340de345ee749c80f13e1d333666b4cfd83797538f8ddebbd4679f18f5d9a9cf61fd1c3e3f7ec1ef17c7f039a01ee34bd787efd39362257607f03d743f9825fff814be22a1a7040061ca7bb88cc2c6033a646c74447dc6bfbb27854636f6941a0ff6879c9ee386604c703a606cc095b2afd467ecf2027e2cf0074f8f10c77888643db3e33136a63eeb3ff10b6b09bef7df81cdccef01c3a547fb8cff357845eb19f006c774c078da9bc28fd10ce4201bbb3ca63e1b449cfaecc813b0fecd45e726eed2a51eeb4b3e446c9c8e189f21b6f139a8fafc857a6cd8a34376cc34be135438a0a78c9df694b1b720f21ed07a0f3d01d69ce900e2579ff5185a02bee1febc743e82f02f95e02f85c7d98072e6b511afe25cb84ad38922fd0b6270c743176d04a9677c53ea117c8a190a5db8462aff931750d808432dfa20cd83e537ee57a5e0128c9c1e29f11eebbfe180831f7d50db230c43aaa57a8cbf73053aed5479553b5761fa884ae880f9b28f7ce035ff0c618c606f05660c6288451ffdc819cfdc107f41b679ec2fbde1314fbae8dab1d2b0876befd00fde5bed24fcc96317955516d9f9814b47cc8b2d278c8f6d824b50fe9d63aa7a602d3f5e70948edf8fe848e5eb3944eb23539055ae9d5f606624b834ec21a57233b3564e0070bb870a86281982e69df40a9ac1fc44198739e9c720cf7b722fd5e2a8f0a9f7e41ea9b5b18a3df8e54319865390cedff0af8a08f9fb677adf673ce2ef948b7e73b1923e5bac9433d6f7e9a5ca2e10059186d41f2cfb5aa0ca49a51613f22b4d5cc6be0660e7aecb74a9068ceff1946f6b0a34c1256301eae35053437ac1faef7b590d030d189b22a5c04d3a60a3871efa87256e62c151ce84bcee3f80177ae7b080ed939da3d346866d0549ccdbf8eb531ffb1c0a072a9ebaa619c19ec7d8814b4397b12f5819b9cbb07d61784f3d7a01de025ec828bec44af6b12407df9539bbea0f3d65de03883e624faeedccfe10fc28ddef15ebcf9561e78004acff5cc605dbd0106b53f64a986f15cccf47babc00087e9c428a0eb12287c603983d7d6c9a7e5f9d11aa7979007568e84f2169d848f55bf838ed81da3f7ded2e8ff9670f5ae4be150b89d5b8e45a3f04f223968baa8ad0a5178cbf874ff6a8f2f1ce555d868e196f73d838501b4cf56a3a643df6c1068fb04798a34cb5238678ecd45768949f475cd53a086df357ce947dae497de67df7de6bd30eb46943d67f72cb2e12a0946f2ee4a8cff4f7a93994fb5c0502e371f14ec95f737d920060ceacad211c113c72f731a481daf2e06c7ab262f9d0db6cf909ae5c443deb24f9a4860825ea22c598bde9a300ccabdc7d0be0fc3df789531f46bb30124ec7d9dd176f0edeefef4ddfcdf6deeeedbff9e3cf833f5a77300ee9e99a27b114b184d9994c64bb4df460470272321e7efc44a67a8a26f32423382b9328096661bc98c46422e77a0a2275937703e6ee26f9819413f9106809fe2c275d029b57bbd787d6ae35801b82bd0a4175263734fb40a3a9da6d12cc6664620ff31387c884c8a5207ac8266ae4a3258f5c8a98cca36041c0f849712b983824c8d1623123413c23f3301385532ad0d5dd821a1329094997ec5262ae0ca44bae0a63e649d6380cc97f0a87b4d475e29084bffd56ba6c22f53ee916945761216522c379435d3f5ac5e5a355bd7ab4006c63e3da51a06c925f7f251b9b577aefdac63191c68e165c583605163c57bbd7cd12de4b09f4157af091a17fb19c63fc49c2d84e0b1bd2bfb5dd62a7459c9a55e374625c996dc065f195ebdbb699bfe1bc5173736b929a45551865d23e2ec348340a07ab54b001165b780b6c341b4dcb67d5cc17b1cc9e8b449f67c9caa4afaa5e991073112451984bcdbd71adc420b7f066d9d8d8a29b55f8f7dfe4eaba5929c16c1d975a0c9647a831282f0492934c04b367cd9309b9ce6252778535b6be1c563b4e3d6da5dba8abaf5d73b08a757948a0fa36ad7ea50881ab4a0aada7ca5b294b60286ed7a44b64b616e5ae017247ba64ef90dc6d012970dc557118242936842acfd59da51fb371b3e490ef9afcd2ed92dd6605de3c8872515bb5f346415705b2e939f566d0087fff9d92bde661b56fac2349baa4e635a151b3d6cab76dab6d2a65eaebecb1c36d36db6df2b968fc641a4c9702d73111361e314897fc78392c19d529011593cb2413f631a0cf409dca86611dab978ca25d9338919a8d92781d45c5469a09b5de4e33311772ba143323e65396acc25c14b45a1925bb9525cd50b144851a0cd1aed9eb90dda27c0afa8de899a3c9f6988e0731f5562dbeba5816ad159497bd80439d92706e6210e6d0d3cb48547375abe156db20c6f975e2967e80da3c510006beff9080c4e2d140694028d3b524a12461ac670444d6dc3ada49f7277a2d874f64d829a7816231eaa82a2b5734d40ef9512474a587f65597b5e6966a2c6a0e2d73de610fd1f2cd9167fe96eb3531ac76f12398872cf5c52454d1df8aca0657f29ea95001b7564892b925ac5ab9556856059b8c849d5cd4cc70c46a217ae7e64645afaeb7acf05c47b2c39f48b7d2b34ecab426192c71aa0910f5c459040d27e86590ad92f8d9f8e4550dd895cdb450442c0e56826ab9655d84f3c62f7532922a6365e2d18353f5e17553d10f52bec37630c4a8bc632c7b6956ebec65db07e53b2c49e27fb43aabb1ba6227cc78c99ca877603cc9768a9ebb03a3acda6959efc3ff87d5dbcce0037c5dee901d65c6ce96d5ff2876a774c28e2510fc5908b35d37359d6a1edc0b0c459e0653a113de50ad929920bf92bd8e92076d35285aec8c16fd3bdce4d8ef9095c816024731fde41d0a2c4f2dc974c238df607ddb21ba6015a59ee8709023715e8ff0e0efbd0eb915cbe0419028bc2f4e9657b340da59808ab077894a2618f39b1a4afd78817b45bc4ab68366c5108bc050bcc59b91ce37ad02d24d9988b9a656cd975619e57ae17094c470d4ea7451616ec0545020ac2d8a469c1704f5a9164396cdc43c584772a7be6e75d229cc2f352ed9dfb2f7972ed9c9b112769ac4ccacf7e2198e6fe5d83a9fb76608e75e3cd3328af7e2b9497e54dc72752f9eaf0fc94beb368c67e805646a16d034719c6f57c842c89eb2b68f4556edb1d364950632bc0da3503e93c7502e499cc4bf9bd6abdbffabe917dbe9b7d201b56f15bafb998304fca6cf2fabdbfdb79cf60db61275c3728662bd2ac2073e219d5a6e255a999c6fcb38242f3fcba3594301a76427d8294e910d6fabd56d8fff9b8bf6ab1e4d6c8feaa717d379ecbcf857b7f92d7e65b6015aea4fd7b75138bd4903b9bcb979155b4aba64e2b483349d38f6845cfef38f7489fae7dfd5a4f2ffe58973fdb32dbc151f16f236ff6d48ba960a75dbc6422817756836a84065cd53db266d553cfe83d2dca36baec11669e5065cfba857125f85e65a06f26ade394877cbee437baaab7d26c0278b442e4566dfae5e7d1970aecd63e6599248a7e3382fff0b0000ffffaff7b98648200000", + "cd6f8127a728e3217237b0f15d086205": "1f8b08000000000000ff8c54df8be33610fe57123f080d99539da30f25dea1ef857285eb9b1187e2c8bb6eb59218cbb75dbcfedf8bec38bedbbb858540c6d2fcf8e6fb46b36f07dfa42e7869615ced1d4b86b10d2cbf1ade79741889eb52a321ae8f1a5be2faa3c6864aeca9d655731795b3fe3e3d54cde1008e62dd68fc74fec73649450e29a4e768d583e93f3df9bf3844cbe95935c63919d08110a1765a885ec5a17f90f9a32e356036a8ac320ebfebfccec0bb521af42084b4b5d7646aaf61ced009d14986aa5f9142affa87ae4d1224546cd3c07e37cc089489d13dcb01db97975a032609d38d9a2437662c329515df0d6b4e3e1cb6db4443cd1a3ded4b8c74ace25d5afd62f6cb3e86521d7555ee89426db410d2d3fe089317420eaa8fae6bace40f1ff00868c949a77a4a991c98ae90ed346b44e38481c6e3a99c70c89adc00bbac65d74a5fb3866b50b695fd2f064e7db560cd473476274677da1ff17a791aa76925c7e6a099e1b4c662c2cd768049b9dceded6c72ea912c3ad59047a72eb44d1b3226189d0ad9849797abb417db76deae82ce6ea3f5c3a3657376f6b42ff1dea6539a6042a798be9dde62f04bf4a5d8539e8ed0ee3e3f3f9e831362f957297c4edcf9fbbfcdbd106f55fcd117c7afc60df654fc192e83b3c504f85670f1e58bedaf6e6bd8be5ce0a6efda9f45390acea34a4e5a00fc4df0aa90adba56fe9a6f8b30972a68edc90a917f6aabb4052d5a5ec1356c4db2d20fce414ee714cbf416f484c5c5b66670a978cdf8d2859d003fce80fa99978d640bb755919fa905a72e32a1c75bbb0ce3374334a973e72f332ef4707b7c2973e4bf9334e7647ad5edef378f2dabba629f4e3fb9bc4d70c6c5589802199073b9f04a92abe3bbf64c0ec8392215bf98188b99fc484f9dbf8427f564cfd134fffed107ffd3b3bc5ad0505c36ce4c48846af924c64851f5f3eb5fd657cedde665b8addaf6700096b16e35cca53b32555e55b2d650fd1f0000ffffec34951bd8050000", + "cdafeb8703e8d4201c7f208b7921b261": "1f8b08000000000000ff949acb8e1cb972865f255d2b1b381322e3423206a339801bf0d9d83b7be39dec91a58635dd03a9218ddfde60dcaa12308caa8dba3e31ff889f99249397fce5af7ffefee5f8fef1ebb7e7d797f7970eed727c7cf9cfd7df9e5f3ebdbffcdbbffed34feb727c7bfbf0f2db872faf2f1fdf5f5e5e2f7ffdf597bffbe9a7e36f1f5f3e7efdf0f6faf5e7e36f5f3f7c7f7e83e7d7e3a79f7efde5dbf74fc79fbf7f79f9f6fef2f9eded8f9fdfbdfbf1e307fc2078fdfae91db6d6de7dfbfee9e297fcfce797e797fffebf2eecaaface4ab781fff9f2f1fde5f9dbeb970f6fcfaf2f3ffbaf8f97e3fbf3c71ffff8fae7fb4b3bda31e5e075397e3cfff6f6f9fd65ca1f6f97e3f3c7e74f9fdfde5f78fdf176f9f5973f3ebc7d3e7e7b7f39fee52004c27ef406d4e7f1741081f4914c0cbce45020e9090bbaac7da5e3001d236523e38d7d41878eb2ffaf419799573a5414c7c8e08a4c7eb2f6efc7e5f8afe72f5fde5fbe7efa8fbf471e7f415e7f41c17fb8bc3bd788618a1cdc6035d91904b4900668d783141669d182c156f9e0092c12421ac06b65d420bf4fa30a11447be9822a6a70e43461da3979bdbf8a084a7a7481d9c9cd28637204ed0cdab088405bf7c7668cc6a944685a610decf9298d2cdb8f864a16544183236508c3cec9ecfd759c30e7d10770b3c6b4604e4a2605599641f6230a62a3a76202512e25c25c94611dec89cf516c4f9c4b18546183236928c3d0addb479ee36ee1d80055fd39f629c944b0760685d1aeb4604a3440e309da462afb04ecd50983ecf1b05f6ba50da65f6bcaa08a1b1c595d998e4e7e1f79945d4ca612cfb23549defd443dc590a4aec09dfd5ae3053230957dc29a987183ec61a2ce2a15184d4a1954719d33ab2bd3d1c9efddd5e40ead8f031158f6d3e40e6b683223c8e8077698631535501b76afdc86a4b22bd0948c1bf4b4478b3e30991478a6b0c0a306464a97a59d93d9fb1fa5c0dc2d806188f82de7b19269429bbca9492f2220efc2c15ed55476509915d7c94629ddd7462903f99d346550c50d8eaca10c4727bff757b3c1d22df3ce33685771377f64af908e228421dd8779e3eedd2a541d688f8811cfc9df7a7eed665410d2542665dce4c81a4abef1787fb51406f281235ebedc80664fe6063ae78102225cc4b0ec6d70e536b894043c2aac8175d9b5aff4b20538316557f2a0c99e32856ee76cf6fe3a12cca5074ee0a1314da1c4dd3858774c8da6e244fe1a0d1618935328d0655454271fa9b998100695cea182265ac690859b93d54786d3a178e002a51822892879df44b152eea368bf9e663c1be74e5aca01037bc575f2fe2ac53440884a59147183236b28c3d1c9efddd5dcd7abb58669c31eaaf728e79837e200dc034490c0e837b34a64d05542061e58619d9e369314e384e5d76e6140464df69c29743f67b7f73fcb0e63f0b648fef645e83b8c73b49d058ae30aa47c6d5713d67ebb856c0253afa04e3e3ba32a6c30a26e038b2a6ab1a574619839597da43f12daa4b8e502636a3131f459a3e5957af65de306d3e7aaa66c3609c9b84e763f968c2a45606f25a60caab8c5963594e1e8e4f7910789d3d62ce22fb07db77af29e114ff257c428da6f798a89b633af12bad70c5bcef7a04f55da4016a6b020a20647ce10969f1bb7f77749051ed68444d0bbe48ee9b8ef7cb7c23e290915668b86158c344288cb6e7c440d7af2ae548c0bc68db0c8c30647d25086a1b3dbfb2b396011ef58b391f77a1a3379f79bfd1bf7dbcf7e4f98a4313aec7fb0cdd2c4d810116b241b405526b0c65557143183239fe9c2c7c9e52395db7d083bb0dfeb09842b79e7f5396a432e6ac08a7eede6aea023855d417065d820ab21faa5562ab05053e8708d1a1c395d987e4e6eefafe404c43df1df530ef33d9626e382666b84b16ec0d749810326af920da07840986015dc8ba4281b40579943854cb474ae0a23b72e1f792b769e7b118a4bddb21026ef3ec3be0e9feb867c017b65ec584a5fc367dc5cd1dbc3ae15fe7e770896b228e2165bd65096a31bbf8fb453415b89ef90761b558b77e39bb14ed71bead95f37228c812544c08515d6c9c236df0cb1529fc0a53228c3165ace10869f93db471653bb7beca11963fddafc9dbc792f90d4a6f93edfda800acbe709c5842385fbf9aa64d8209fd6aa5429db7a3895452b37f5c42d90a630fd9cdcdeff2419086d87690d6b580ccb6ff966dced626d62d4a20e4ba7dff3601a52ca66f3c88cdb62168c7b32bdaa94806494b228e20647d65086a393df47aaa9d3460be5b02e1d935140d9c60be95224a02b9a56304b2fa540c30a6b60378ffd4a2f6b9d4a56144183236508c3cec9ecfd7524bb7fd86c23d3520815a340db63b64fc082bac2c83a06375bbe9ab22f101c1937c81ecf9e606729c2a459caa288eb9c595d998e4e7eefaf66833dcbaf5a76e8788dd96112dabe11495257e0b8d470c1644961df23608fa8014f5601a2e45d39bf740b93226a60a40c61dab9f57a770dfb005cec1b43bbeff4bda85bc97d2f73ec853c0b1aa00d518eb6f5d453d6178cd53368d093b54baa428649ab844ed7a8c191d28469e664f5fe1a7658cdda83da2a6f77e7c6c99d6c4587e4fb8741087d0f97897d63ea1a106945757ada83cdd495aca04b4217bf236450a40b51583919bdbb7e13ba4f2186556f2f4535517d4a3760a82408884d6603d926e3a12220968ce8f07408e8a83249855c234966882b3df7c9d7ddb5f1fbb3dbbb2d2bf618be34d9ee9075aab17b4ad0347a2a1eb01b4b087d4a19511df63dd28589cbd64fae8adf1931d0d385c89d9c6cdedf14d9363af78c50d8fb456ece8bb5ef1ca6c795f2602799ed6594cabd2aee15d729da2d572982229632a8e20647d65086a393dffbab49b0ac2ff942b5b3ed16046fe7f1c29daba8c3c0197744ecccd14e1e42d9a02dc9b00e6e7cbf1aa2106df73e85411536389286320cddbabdbf8e13b4d96911b23dca054338b92ba0d82031aed0621276e52ea953101e19d4c1c7e29145c3f64543541011833d9da9d2c8c9e6fdefbd0eec477c5e3b4468a318d1b6137a87b95f4645cd8e43931b306b2af7221f33acc3d31e2ce7aab206e8cfda644115b478fafb6f0b7b6db3df98bdbf8e086dd9bacdc6843d7bc09ebc670ff6fa597b9193d027c59cc4cf02894bc6b64714313936b8b633aeb206ea579a2ea882165b461786975ba3f737d095c3882f53f7fbb6f7e4bd00ef7e2eeb2d34a8f598661833e0e452128c59610d7c12d06796ed956e2f5950052dce99459f65e764f691f174fa2eac6f53efbb89b54d6d9307f6edf70201cd812658984b28804415d6c9063012be296d8ca52c8ab8c19e3484e1e7e4f69191c6b7def74db5dbe88b4ebbc7cbcf5e0496de12dbe439994165a59041e6caa00e16b4f9c2c10ac77e9a2973a89889963064231ff8d5e823536c997eb8e23beb1dba6f7f759f7ad98917c358e386babd3f930906622909ba565803eb5e3ee7ebeae7d933554919f3ca96d17561e664f591c1949aed1aa2efa774505ec9887eac1edb4245cde65ec9fe35412a05d6d28aeb64751ca3181b74df83326550c52db6aca10c4727bf0fb5d3382ff05eb3a01326470fc705e23338f1c9a12dc2afc8be1434e184d6468575f2a6bad7f1513a60f8b5ecfb6e411e3630728630fc9cdc3e32e250a7eb86caeed3ab780f237e30233e9c06358e21a7fb398dec1577282774d58aeb6433b8c5d75202be510655dc62cb1aca7074f2fb5035fd232cf14ec1b09624ef495a9ff5a54f50b34f9b9e6eb8c94a25aacdc4226e9057b3af2a25a025a52c8ab8c1f5bdd156a6a393df47de91e827214d62c0b4534acc0d0a163b60115faf1a35883764906d6ebb0e15a6af7377d4206bb1438a6da5cca52cd25c7c7365745dba39797d6496b314fdce884f5e0669323220db3d561ffe83d0ba5ab01d9ea4308f623cecf5a006a1b3546907e1d4d9ef6bcc444be8aa3473b27a7f0d0544edf8505bec0fb324ee0ec4f6e51bf62b11d088230f63f48d31177658c815d5c9eec57e7a591a1f9860eea8353fd18fb0f5f989250d65183ab9bdbfa5fa8c8c0468e6504f81d801fd838639c60d358cb70dfa070638470911c6c48aea64addace12a3d447e5502665dc2befaca9344327b38fec44cd665f5caaf7f769473dc17638621f26d09a457bd18e6ec6587cf73094623d26e33ad9f8a4fe159895fa82339541153738b286321c9dfc3ef224e34b2e5a31f147d4e458067083a145a4b018af8b045a369373212da0fa006cfff647e397d970b3fc2ad5828c171cd942164ece3e1f39ade1350e8e53425eba7fe3b2af9bb843f78320a366f4944c0a7dad546df7fe05d08e17649bc7bca84a19c6d0523a5de306475657fae43c3c3e328c8aa79dfea90801d348de93475cf649e2bcd204c438e6301ef9ad9a2905c6d48aebe4dbc6a855daa1d12c6550c50d8eaca10c4727bf0f9fea2fe8fefd5603f66fb5ba7fac80d32a4624450388e2e33863314e258320555c277be22cab4a270c96542665dc64cf9a4a7774f67b7f1f1468cb4ebcc68c99d9c4e23efc35b857045a44d6399e8a1196ef214eff208706575c279b36b15f4bbe668e8f774c19547183236b28c3d1c9efddd51ced58c73f1fa3e71f6efb6fabbf2bfffcff21df7dfbfee9d7ff0d0000ffffe0ee847e19310000", + "dd5c8eeb04afd962dd3f8390c15b6ac7": "1f8b08000000000000ffacbd5973db38da28fc5f5c7d994c26e99ee57daf8e2cdbb1a62ddb23c99d644e7dc5824888424c026c00b4a57c7ffe149e050065a523bae7c21600625f1e3c3bfeffb327699d32faec7f7f7e73e64c6f4be9cefef7ff9e3dcb7527cac7ff7df7eedd5ffef24e9b4a16ada9fa46ba77568ad2bf55a5d1ee5da3d6efa46bdf416c2eb4da48e7fff2d59dbd794d0d53a3bddcbdbefcb970f2b4c2ef94aee4ee8779ffcf5aac65f3cef6daab56bedbcaa693d6417b72e7a5aedc0fab684d2bb5a79f1372af7730a410f80ba6fe995e9af55759fa4fca6f4defefade9a4f54aba1b634e98a9b211ce69d14a77e274854ebfcde7f7c401e07aae8df1ce5bd141cf575bd9ca7b6b9e5425edab6a989ae655e56e94f31fade9bb9997ed9fabe155a517e6f987e53a6bbab77edf9dbc34472748d86ad6d6af2efbc3829569dfe6bbb114ad6cd4b7d76d88d24ae165d8cae7eedeca8d7ae5a08df642e993f75465da3f0f2c94de4aabfc89e70e1bb6a6f7d242fba18ac3c4570dfe5c54f529ed3bd33cc9b79df0db70fca9fd61e20f6b79124d2fdfcadf7bd1400559fc8765b7ca7963f7508ec2af1aef95b1edb84b65587ea6bbfec493ec95debf55fa495825b47f5729e70fd2fe22dd8f57adb3d2fbbd53dfe49f38d83c6cfb4a08b8948d2cbd5837f2d4c9ab84971b635be1e1f64ad113dbf75668a7bc32fa6d1da61b4fbcd11b752a783a5ac32a26c2228edb0a3fa8f187b534a6126efbaeb0c6fcb849caacdcc45af1e3cdfe7fac745e58ff6e6bcc23c298dec9a9695be5bdac1672f3ca2a2e9fa4f653d1346b513efef88cab27515bd16dbfba77ce96103f7176cbadb0feab7bfbe1dd9fbac36ec5d35ad85317b6d7251e8b266c6e1cb357cd8fb1b82305c3b49dd8e5466d64b92f1be9de96a6ed84ff5efa5fe40908a5d2ea2d5e866f692a71f40873f0ba397d3ab36be6bb5f5f5c407fe2029f6ec3ed5b5df5ba3ce9141de210a2aa608f061c4b9e728d1f5660656b9ee49faba381822743805afa5be1d5d38f2f4d0da7e92f32f4eed4630127e92f5f1daeff9462af3a4aafc6786fc5d38dd2a79e8717654f9d9756dafad48bf15958ad74cdbfa3d7d83c6b692f4cd99f44b81dbd46c5464e74b9353fde6011fc5f9e841f0d8e6e6a345cbd274e0e7e7ab7ee555329fdae6eccfa84767943af85931fa55f891f4f6b1cd91d90a237eaf1e45360853e1dfb3eb600957a0af4c234d0b1b7a7e0ac47912951bdaee079effd2b005c2dfdd4b45def65b5f4fb13a8e7a31bf793d2d50974e461d9edbedb4a2dfcf85663c9d7755a39c0ac02d2389eac743fbe35bf8f3b9c876df65a064323ba9309bae388cb9fae6265eafa953c16ace05545ef4d679ea45d29ffcab6a902c0dc5e095fa98a93a156b8eea7a2dcfeb8c35c423867ca59803f773f46a8b9d072dfae4f20bc38bb06cc600ac8d1188c622eba0be17f8c6e73116f7e953f262c0e31fa4f72fdf1265c17f5eb48c9a9b0d5a9d8f9718a641eeefc40d1bcfa90ff190ec0641dc2a5ff33c8d19594d549e4d45124a253fa35286aa25e2f4f006f2f3975fac1c98bbbf9abfaecadaa6b69cfad7976d22ee4a63985a569ba0ec699e8989834aef3bff7d2ee918761eca479ddc65d89f57f69dfbc72df5f195bca87ae3a052c1ca27327f2dd73746e7622eac965e6e2c73cb103dc6f4cdda3e0f4a3dcff1838c4cedc485dfbedc99d51ee14b8196b3f11fa138a0bff4fc4700f41333027c3e687c05c68519f7058be538b15b5aeacf9f19a3285baeb8c3b95143b7ea974c23a3935cd09e491536dd748f7549fd860e2c3ae1106bd96793f8e71df09bf7debcd5b2b6bb9eb460bcd98db02f0ef45f278188e928e1f9f8ce3f0e7936a9a07dd9afe04ecec780d08bcfe043372a55a69fa57230ea1ebf2c777df7778a9c4033da5f7b84c01176dc43ed6707fdaed75bcf0c2183f6d4e97160dcb7bd5b85731308e5413b68250fecad88bbbf92b67e30e23afba49ff0b6557888ffcb00a9496bf15cea95a9f787c3b6b4ae9dcc98086f4011a538a46be133f9ece8302a35bb06fab6fe3cb3cfe18617b51a6f9f122bd28d3fe98807951c6bda28cff3123e6a0ccd8495bfff8a81e14f831f3eca0c08fc98f83026307bd36630b8cdd8eeb933566a8403976b1cbd12dfc18433f2830769f5763c77002c7f1b0c0db1364ad2fca943f46830fca8c9d2bf96354f8a0807ebbfc38be8ce8c79719bdb5a47e5bafc797516357339479c5bce9b1204b8e3deea788270f0abcadc637f2b61fddced8cd2fc7ee97cdd8cdb251630b8c9da8cd58e0bbb1e3f77c2833164a6cc602c87a6cafea1fa3f50705c69ea7dab46f1b311a6da8c7eeab13b81c0705c6eeabedd86db21d3d86fd5b311637516357508d85096a2c4c507efc56ff3a76e77e1d7b833e8e6de1f1c78ce6830263d7ee71eca9781c0bda1ec76ec1c7b120a7197b913763c7d08cdd7fcdd8ad718244fba0c058d8d18edd4bed5838db8edd4bed5870d68e051cad7bdb8edd4eedd8c51edd821ebb61f5d8dda1c7ae9d6ede8ea67af5d8f5eec45b35baccd891746397aff36f47d3be762c04b163a1a01b7ba99ec05f3c28301682b8b110c48d5d3bf7fbd8026317ced9b7e5de8eeed758b8e3c6c27f3796497782bac04181b1fbc38fa6c4fc5836d809b2bb8302cddb6e7c99d125c6ee2aff6dec8ef2dfc6626afedbaba898be7e5b8e2e33f6a0f76327ac1fcbdfe8bfbd66f04f6341dcee6de7643f9acfb11f5be0db76fcaa7cdbbedd8e5d986fdbb7fec79025aa3bf953545b28b7fc31ac8e92f49355c4b9271b2be5c7718aacde2cc1e6f5e40260bf04361a23340e26b60621dc8822e7fd663342b54db9d949d2aa58ff6adfc9ea345b93a169ca490abca95b4b6f55090aadc28af5089d9456f8722b5f5f9e54944fce5f0ae7efc509774b32bd7c2b77de0ad0ba16276b19a971d62e4775bc6f947e3cdd8eb156da4bebe4c956cf7fa00308da22603bf1e3bd7c58cd0388932b1248ffa94a74df347faa0292d6cef4094cd7e3356c94ae2e1b1986726f4eb4083bae7b9326f6b53a3cd823afda5797ada5bf50add44e99131446480768636c291bb137fda93b8b0a76dbbd53a5fb8b536ddf086fec2b3726f6dd9ea25a767c4f7bb9f3bd3dc196f5fb2762e21b317e17661584c37c6f4d6d4f60a1fe4135b7a692ff856a6ed4096c833f28bffcbd17af98d0df947c7ee79eea8f214d9d20c24d9a7fe723ac25d9526e63ecb3b02769267d4737f4849ba8eeab13f7f5d628e7df6aa349e1cb79e155498ab0dff9f897f2eba90ad1e8286323a837a7982163c1adf16f1b232a69df9d64c4fa5d5be4ad2c1f01c2fdb92a6ec4fa0479f21f56f1ead2aff7e7104affb99eaf5eab85bc7c56fe0491c6f7da7d5541d05a3bd1f6e9a8e674234f35607c577ea5d05f3a6baa1ec985f6047661f2ed10ab00a70a23ab71e55686d0a91758ca1f9a8db1b1cdb2ed74d7f4b5d26f9db752b44ad70830bef7750466fb6e234a6fecfe93f2dbd5d69a67a5ebe5569dc049cfea0898ea22ccecbd355da037dc529676044a9ea9a55f4879b2ba79d1b09dcfb49127e8cbbd2876211b39c21627961b436ec442d727600f2f0a2d47b4e4027d3e6e26a0c8c85980326366000a8c193d14183372dc3f275a5e6796550bf13cc2b2b540add19509a4ea09a72cd1c673e11e4fd04f8e14aab1f25f6e94cd572dfd6fa2e9c750dddd2b4eceb570a7db536c85db8eab3e9418b91b4391319b31e41fb31743fe315b91e775e430c0f66424dba41b0d8bb8cc9809e03263266129479a5f3a2a30a94e3f255c66cc6084b562bf342788d313b7686413c0373cdf8f812b0f4afb7f8e62d18555599971459cf4638bc058d0a4ebf409a8a59f34cdaf232cb5988537b618ace67d3f0224d5d2a3d9d6c846ae54738a610e9571be5f8f9b68c10cd7d1d3b652ed09ba9ac38b7234973a0ce84a3427c890870d8de73d43c1072d4e700316cdaa4d251ffc096ab47913a3e659b97b6bbc09c8eee9bd0264645433e649da893d1d6cd4a3fc7214019ff84dc9d3e53df7d6b46ac49a8fb9213e49f138c2b014d66c02d63ae3d09c4a6e9496e40ff3f43d851e8c26756d652dfce96e5df020bfa21c8cef75c52ec509847f5ee0cad8bbe7d3856d5464e4dc9dbfbad4e8f1ccbcb4c2cb71c0698e52a791000d4a8d39a0506014269f756eecb6ad4711658186599993246111eb90ad51dfe45474dde9e40c153a35bb1f4b5ec12d38b6109cd31100682bdc6cdc91b91e55622bdc98955095d45e9dbe33bab100308c6034d4cc0b9dc4c7392a614563d4cc875c208b0226016cdd93ed6c8fca5341763e4ea87a60ea3df8a61ceca351725ee5324ea47263398247a74cb985fcbd57565657c64edebf1feffd859c83ffb01c0b04ad69bf3a73aae92c95f2664499c31e4e9ada58e5b7ad7b574aedad684ed9ffd4722a31aec759b9d0874ad6f6847be678e1b5f4cf526a2d4f50173c5e43d91827ff44795942822a4f99b93f98ff70c2853f49807c5c901bf51416a74874d98386d4a159634fd5ab7859eed8e751bee7bea36320cac767707fd476c2ab75234f5459f8ae943c1c6ad79d74a3511dbff7a2f256caf5a94e465e960b9f5fd59c93d69fa61c76a4b45b8a569eac58f18733b636fd298efaffb08eca8a1a1cf2fc3716efbf5091ec1b6967dacbda9e4419fc616584649bea64c0c9f57456b52a50b4230f5fae3972ecfb28ffa787a7ef06eb2d8d765e9ce0f9e28fd49d5a51cbff926605d435ba02508c80f227ab46246739b0b8a6edd4090ce461a90a14ee4ef16771b4b5c2cbb66b4ef15c25aaea2dacf6db869cf1be72d561a2acd495b4afd6827a06a799094aff7f6fcee0f98bb3fffdbf67177223fac6934fb0b33767a5698c3d7b73d66be42654676fce9cfa26c32776381a92fcbe09bfc2fb907b969e39397b735614e86be4eccd19f25343464e0991300c75f6e62cc405f3e7cede9c35e0c3eaeccd5917fe980d75f6e66c2bdcddb366743bf445344d28dc754d88faad72d0b0952e3410ca28747078f6e6ac963e2b4d3cd1b337671fa50e1d3f7b7356092fb0c9ced17002757ef6e66c65a5fc401a71a1212b436a2b420fc3dc8734519fbd397b94d0afad6ac294c946b6309b7a033fe4f91427d22b0f93e79eea7b6ad1796b1e43da46c1c030fe4955301d5ba9ea6d68fe9912766da31d37676518c2d468d7b732ac066e87d08b5d672ccc6c410fbb40776d2d6115404738546fcc233b0682f4965361a150431666b4eb43418e33f50a99e24a2bf790ed1de56efb760ddd52ee42f85033fd081b5237a1f3568696bade6d078b1d329dbd395bc35042ffcfde9cc1830bb0ac08e01f56d3500bb8e50f5b0894bd710615f407b3dd84f43b8bb97b5fe2b6b817d685abab1175e84058b2a20b75cbb6837dd6ebdec96a651e25cc374667340fe649da4d639e612184753772e3ef9e60acba6f1acea6f493685435371ad68ea257dce31e3436214d789a3313662340aa2accd5bdc0456ca55595828d6537e5877f7ef800e0403e56623f570e748ba1f86fa1b2309614dcd010b156ae51b95bf3cc5994bb15b7a1548593b352ad4cfdfd84ed84ef716ad7aabe363daeed9535df6023e27cd388cede9c61a59b5ee30187fd09faa5f1dd1e3821dd7e0a0f23c0be0a05ac69e948e2aae3782673281c775b11e0481196ac801cfe5b8b1971a50bb3d938d8ed45dc193d38f09a69b8fda40bcd63a57460a10f98e98e4b2b17b398f5d7b02fd7eeaa3106d79a36f85cc00297523530e3f8d99b199463407765ecd4485b2a803c6508ca2a1e12d8de38a14a2b3827e044df4a54cfc77323f6ef3910f640657400e14fd286865aa5232cbd509b0df63664539b0ddc20c2c232b83050d7775d98850bd9595902a5f3097d8be3ba686760d62afa8e40ca3ade1e552a772d74d5c02884adf13fc0b6460198f96aa06397d6c2bc80e203024e37ac278fca25dcc4677867e1c49005c5d99bb32c084ed4710bd13e973029b89c002863ec260209585cd128e1601b8aaa7ad0ca4f42021c770580726bacdf0a003f8d7996768a77833737594c8703dda86f32d4c0a55dfe01372d7f06681af771cc5411e04b090c473aab0251aaf29ede63da3e7d0ec16fd29a2bbc4810dadff0c50a28ea126f62b14eb03994702b2ed4014c6bc50ef6c7dac11d8f20d6032395c0211ca9ab97e998951727a540863c59540407e10b4c29fe76a2aa00161a5b290d87bf4c37d4a6d76584f5177877630bf194ca5d277402b282ae2c869156768d805dd9029831bdc7496ec5a3bc1a743f8140bab7a8ec8dd17548c906807392278704e13cb0e2c2f0103d815ebce7c0070efccc815f38f0f798d99b94cd9b98e16fdee4797ecec2bf64e198e74107340c6616e2cb412c823bfc16b6fd30e993b115cc402d77bc0d1721c2eb075fe2edbba0181bcca44b57c2a72b63b9e042d697bb8e6bb874a5e824b70a1decc27c756112ba30caee17de2dd40da8956b1315dc5783b4e2193f04b845ba0157d6b4f1b3003c70ef66fa8b1461c3eff147b91b293a4ee32b74f56c2e54ad3ca5431ac2f95afaa5e4f4b09d3e4202403ad911d474d2fff41e33c31e44d4a0c20d86bd607c6187181d470de777b03e31364ce699c7a4610c66255c5777b7abeb6531bb2daeee16f3c90aa02e9003081fe75cafeb1a808347be721fb600fa7195b97e688de80515aee9a629096a860a72d8590c7b568443341f2601101ea639e9e771e6f6771b8ee00ac44fd8ebf9cbc9197ce144c2d5872d956d7723f5423ef16d70af6429f9b8c748ab76b28a318753530cd7a038b24a9c36383479c6e117c4b0081a85b3118639871b1d477fd5370d6d4037884594990a2392544bffb09a0e0b0d13e0c20f272a82830aae88ca8403b179ae622d170066613942d970c2423947986a425811eba7faad74175c242f4ed963c44af729d5123b1322e9dca64fb7488fbaadda78c25fa12384d994c2a7feb83960271ce38dfd9c154b19792506b90f130fe3bc9906c728ebd6d174eec7d18fd8e517670f200bb54ae7af38ec049ea74f87a9add28769b856d4fea783b11d241f3b5e9f5e4e1b9db1c3965aa53b3e601d9dad0ed3e3a12a0e67b738ba06c591c54a3987e76c50c177becd951e7ed9c6fb7d6b7aeb18332c058fa4f70812c205364f845bc1445c0262a541c2fc9111bd42b9fb166e9efb795e04303387ffdfe34fb80ff1959b88d322f423ba6c2d9c4c48b068a4aef0848b56e251d572e753884e57c059303184283194b96ca0d337ab25fc0fffc21ffea3ff3703787c87081c0fd7ca069485e81edcf4beb7122e50c08c801a6bc348b700bb0360998749d8ef3302982b43043062a2f24ab4aa41fc38a2cf715e1a23aa18314d0a1762bdb671e23e0e6713e83102ab3111d91b314ae58b483c22f111bf6f8cbd14807622dfedcdd9579a6ea04c8c71a9ae722bcbc7bbc4582898c990c3c798c8a075903038b000ea22611bc031736fcade865ed24d20779d2cbdccc8fc80feaccc03d136cfbf1161aab15bbd93f9e5915dbde976a9d3255c4b6e286b967bf24ce08a46e765db250096cdc5c78f676fce3e051272c8d6e1838ab5d36ead6b60651cbb55f8529ae94dc0a68a7404a09bfb7803cee331ae0fe2c88e92d5cc1986086be15499c5fdb784fe9a305c64b8185062048e68772bfdbf9cc9c022afd16c7917762cd0a68d7966523b272bbc6ab3c8b71874cc92933b395c7864d64d32aaa8d7def6e11a9419cabb046acfac1ddea10ed08430fbf3f0fff202fe2fc3ff2984a7109e43780ee17b08df433835bfb89a12cb0a101b6ca6127b0c04288a21849d1846e088612b5ddff8c8c28a9b07b709e6c14f0c47e12ca50d1d87048d34ca0bbb8f09ba6f6378db22b02cfb26e701cd9677c53ffffed700791757d38206e31e55d7219b1ce63792dade78027bd8a1f861cb2c3300f20cd3086073f44aed3e59817c7019e04984e2184706846cbb98be962e91bfae3456aeccb98475a633b70c89fcf1f8d688c0014e176cc5d0f7ab447b1f168a2b16970ba7b75131968a447647b6d5994bea223cc998f5b704301f331ef325f16605dc0e514c80c890f15b6068a464e06274aa7c3cdf47dea343ce82a4015cf428e20f1b3205c36108197fef85f5320f32ca89079a000e6171d9d09909742ddc852c550b900ad6eeaa310207cd4d4796ed41f982aa2d22955790b0a258f7eb752307b5205767617a98774bbf9107eac2ce111e053cbe8c3b9b4433986fb0b4e5b6d78f431e008a1850690fc783974c6334bc639d729b4a36c476e40c085a099e3504bce972880589f7fccde89c01fb004c7b849a19643d208ad24458a453d466b3808eae1135434a1d38ecca9dcb0d1e850e64f24f120f90bb509b8db45297c800ef500cb2c1a5277dd9aa8258a5ac643e5127ad3261c63ddc60a2aa96fd1a1eccc10aaa8aa4259139eed2775860e2d73e6f0d51d8ccc0850717016b78bec9d95e74cd47903e88e39435024fa9a98030a8d493aa509612820eaa85a5587a61fddd862eeade97c30462aac00d3a60dad5d2e3cc2006c599aee1d50e3e2bab2876c21c13e034c63b998643c789f19cefa2918539881fcf7923b5921957e6e2089b80811746970cb4609fcc5d962f0769005e10184343f7c6f9c1d51c3992c809c0fb01663343c4137bd23144f05bf8097bff42363027525750ca0d568366aa4a92b978683be37c14883d2bbf35bd5ff69b8d02c2a56f854639e4c69af616302b6ff09736e6244ad212743e478d2ec85436bd534fc86b461e300a6b20bcc2a3b524c60f78007131e9cef231e2783a8343611cb3bbbfc1e50accf43b10bdf4c4464cdf99a5ee4d124dc6abc61b9a316f66cbbb38498f527609ba68d761ee6f08a49463ccb28347f9e1a8d20c7af3afe5dd2df629421e65f4700b33c780904c4e8d5c0ad85f6905192ca594d041e80441cb104f08284cf5a4fada03d954945ba1eba14c0b6afc0f0ec7d3ef56b849032cdf806e64c0f502903500b231354cc504499b10244e421531d98be56ab9551b94591607713820cce2845f453cf08d922022770c351ae58807376bbb0699f194cc1c02fa8054ded2586c03f83a30fa44d8162ff8ef78121e3a8445de4088f98e43ce7e91a40dca5d31695a1cd0ac81548d1f958b0d1543b66cced3bcdc218c073e5a4ec9a504c2228a8ce1540c5953c5216f6ac8d4e1368a4ddf3487ac95722becc4d3c67ec669173051026ff3ed64ed8657162c9a58bb298a33436d2b331ff29a57e682b01ef128278e656900d1e0df7c88cd08b7ccc269370b774d5c14e1a846e1f81409175b15eedf091913c03d7489cb8edbc96fad745bd3402320bd52bef7b07893dae098606c193c80f897800942fa95dac10603149e7f496ab66f29002b81c16dcb21dcf691c8710130d28002208e50b833ee56d6036c25ed31ee9d4bfa15a4b21c05d3915fe0db2e86f33a0007c4b2968299402bcfb9e2f9cae70ece5f0b5cff761fa98aebd5fce66fc51510821793d5e56a36bf2c6eeea6939b1709c5f2727a777bb17cf961ce69676fce4232fd6405200ad93e5d5efeca928a705ad07f43a4bf97e834068149345b83cbb22860298a02c2918b83ca3fe11c78c9987085b0b128ac14803683bc30344292eaa2701d7dbb9cdfafbe1493c562f2052e5029e126c5e4bbf37f5d4e5708f26ee5cecfaac89d0b3d4599c87af7b1478d0c01e7aa95ce899a152de07937265d03286414f4c93cc296d4c620367adf08a5e325571f8e5f54d5b5aa2ac97a34867376d6740cca07f6628069f4ad04877461bf5ae52988d45acf5f58c3c379a14b6936f756568a5403ca467cfb96b4866ed4a324d2cd49fb142a88da44ee72f9f73990b87e8b3b1563f00125664ba607b2d1fe8afa02a9afee05d578215d6955e749cf209c21b5d9ff0a1a5af1487973cf7a9e676fce7e0a2b73f6e66ce20db15e251c9a076db0e72c0a76e752e91a8783126a0c5ad6b0604659239c9f94a5744e56e77b62103b4f252def88d985b40aabe7a4dbbb55b15a4ca6bfce6e3fc21e3897a56965dee641123ff9efe8de0ce12c1b0f62503625e6a5adec8cf55953983005fc2262b1e72446377155c3ccae263797a8ba21752575a9a4e3213ddc17abbb824e3dbc8a5de22a84909ca322ddeddded25cc530da98439717f971ea15cd8c0a2467b19ea93d4d579547ea215242a0d2387f39534555ece46a6c54235a1fe0de0ac648a84dbaa2f7d6fe182a8a4ecc0a34ba2c0a02f80a4000b8fcefe85aa16bdbe11dff633adbc020eb575112a852cb4f12e646950937fb0d9d3d6067f000011f4e51f7cc679e09391b53a382425e556f13b1fefd07a017463dea147b977908a0108b2dd153cfa8c90356f22968f94604c99643aa0926ab3d2f7560f0610a7246b8c06d4ec2f73d8556539414774d6b6b252c2cb06c92578ff52568349febd17e5a30b106b92b7046babb7612e40412b5c0807200dba4b0c832cab96916b4edc09aef6cad82c9f4cc12ee37b0159fb8793e6d28a7143690161ec5927932a6e55a554ba1ee8bd3fe8cc53dac4f87e77564797f4b36497f21daccc0ed873ee8f4be765e890e449ea58d7f344be2c520ade16566ef27aacdc2ce1a8e689a6a978c26ae97929804319fb685228b6700508084a98d66687c4b0b15696bed93f38594d5cde4cea1ab7064e260e97cdc50df2f2963c1cefe16811111a6cc55afa8b836549bcd7343eda927b2d5a551e99ebc39af1c327e5b703cd4d2b37111aa2cedf07fc015d24e9b7a6a2cdcc5ad083554e50465460531472d0a62c33ad7452a07eb192fc05db7c8febe6401f1a3ff0cc4f455f6ffde5ae941d5de5a5e81d22272fbfb9ade91bee0f6c58bea4cfde9cdddf2d97b3f39b2f05df789d954f93b081e1ba5b488104ce3005986994f9410712eb91381b14e60c669d361d6b571f8ea6522eac09e8529e07fc5ed0ae8cb55d029feaa00f9888cc828bc36b7a65fe9ab50557503668a8f63011d0d4d9068acf4da5368a34382756c284c008b70c8610c5c025439689ec801597ba89973a022250569c446541e801342fab8c96d920a4bdcbe6abd7601d75213b37353d20d4b6d7b38a667f4543a1685e1271b4dbacba97e899fa2b2239b0f95bf3c45885cd612bc4d60a3a11a719f06329ecb0af692b88c848b6a06a245eec2992e4e0a4c080b4dce5d10d4d4c3873c31b1ef1216e41c45c242aecb38fcacdcd7a17a3ae34a08c17e69044a68005c60c1234f90ba9ab542664608689954f836d333c2f69c95f6c033e12da78b5d92fbb7decf9ac8a72f66cf4accc0c0efa94d1703e8ed67c783c2879a69daae4340195c2f5c8382ac8c6642bdc8346a45856580a484452960600954d387c4bc6179584ab261e6399ddfc20e6bb4d38c3c3edf47a72fbf1f202e9dbec0b18e87b6903bcc2f195dc11c5e9b16bc98426c7f37146f3945832aa14e1f559873c366b2fd13cc8c09243e48a4bdc243a24bfa4790c45d18a8eec0e22c481d8a2d75ae97ac90c1dc2bf9739c26dd1043c2e34f147270d52739146988bfd3a231494663a010edd446720fe80ae00b9aa6da1d8b3b07ab236bd8f707b81ec00ba7d784c1de9a609b7ec1d1cfb046e2b6e14b6297ca593c0a545ef8dedf97c3ca03cc9c12c32d13b37ebcfa8a0021cde23246a96ce73e3f259cd135d37d800c8a9181c1da2855c76d12e5ecebca5207f1a602309793a52922b9d0e190cad291f719888cec4309ab2c5bec2c16850a2a2e7d2d6f4504284d4ce34614145d3e0612e0281c5940d5f0d989aa6950494c8858ead739d56bac3244282530d15f8c3039242f6f2cad8432e82ed75be10816447c2f7eccdd9f9e272f22b246a497210ed2f64b742d3b38aaecc6a78af00d247297bca9a4db4d1c9c488395bd7d9213fb270ca5d28d719c7ecfd25f975a5285ca244ab620aed30b830302b4a79b272d9b8236b21a25d333db8242a6c9dc68611be54e92cc15002603ab7523cde1b85063a7ab087816cdf911a7329b3fdca3db3072b120597a2690687c8b32b00bcfa853a3c512adfdc4efac59196d6c2c93ceee056ab8c0eb9c14af24a49e45e6bd14aba52874873a4f18054c636a0549e4dd8fa17beb5b3ab3d0691fd07d8634c7b52f2399ba16c2d91146e4871970e7caf99d114ad7a383bf40cefc038da2181956d0dc8bc26750520d8572663402054943bb8db09e5d86c904c018f4d29258ec4f67ab9073391802125f298aeb16b631ec9c8117718b38dd6190bcd21cb3064ca0125b34333103304085224425da250ca74031ec980f1a0e5f30055b3b2ea91242acbc1872e27bc64f101b4409809f32106887fe28002cc8a4bfad4258eaf36955c9917904379d036ad656457d207cc7f9098654350443e280025bb6accf334ac63d388c19974dffb42da7eb11a184ca03d11adf23bfc982e3af2dd8623a3504ab3d299e649c65a003995dd0c79a1577db351743d04c0f115b420511482a2f12d5a354247632055bf0fc70e48564a885b8c71f630dd7719b40d9bad6a9556ce47f14f2c9471e3635ac4bd083217891e44c46e40220e22444917ea10b6bfe000d53271d6bd6523b316ce9d723ef2bc33e94076f7e50c326069307390f6622093e2544cd770d0eeec95b2094590c32ed124bcf896daccd9495e967eba2f1b52ce0cf7ca5c746e422a6308b0cbde3a79f924ed9e050edefc6b8906eb8d95a2da2f2559a1fd6b192f014b83f166525514ff40bf3fd3ef2ff4fb3710ed7509a2a0c22d30ea6eee3ee2b5a55d04ae81a69880ade4336eb32e13a584a4b4ad0acae11135c1ed94e2e9c2b44c650e90984945620d9a5a846c2815bab766b75f59d125dc255f81674d1b23401702930bb969589e048e0e2e0389e3683dee8905a80e36ae1a122d086659a80458f231418663fb3dee62180e089758a312be0e7ae00eb39867b4733be0b0bd388888247c527ecb1cb84638ffab36cf3ad6a5e5f36fc4443c20e948848ec47cf88dec073801550af1072d9f63bd44dce7edccbc04a31e94fa1e0ca9a962b8225d215c3dae1c070375ccb437b18b48fc416d4b468ab2b4e95635d54347b8227ee04d459703b29a5801236c01d233405a0d2ee44daf4b36ff3a94ffbd98f74280d47bc0ee9c0bfb28338487b4158a6c1fb20b8215f86028b6c2219b14ac812985401a9a383c5f52702be8762f706e235d2aaac865a34fd750eb65ac6317ed395bf1881e19093097c006c186e8d06cc09b2eca1beffe7507d7f0cff8bf787fc8d08d232e58f6448ab730a1664844bb416904742fe695e4d6745332840f107dc8d9e6039f2ca8e9fe3d00cb51dd18b705179b54958acc1d4cba7bd632e7d01e6be1a0bf601a9f72730ddc93fc5bec876986dcef7099d7a241c92b1dfce3f284177325f47e4517039053ebbe6606d9efe1f3922cd6d71ce8f533ea680fccf3a788a8ace9772b1ceb412d91582d8af9ddf9e7e2e2f2b7d5ddddcdb2f87873773eb929aeefee7e053e92d2a17b73144883e33bd0063291016ffacc7bc28d412a49eecaa647d0839e3d68b1d19d46eebfc57104e195ad57c8225284cd177edf49033d856c817e9e9242c274c0e30a05196d1bba9f4504823c9d4e432dac1d935c9e08af4a8e152f94110a92d2911a0fd701fc388e142ff53e5e6842149d714ead1b99757dc1c2c54514dbf128c2b458bfda2a9764a5552465a6a66d8dfeeae6ec620548a1992b9267c302fd2f6ca0bab097c2def9e9a738a7b16313b7d72589bea74613f44f095eee7ce6d58552eead7952a87a9cdcd25cc5979f42c48a9ad2efadd928c43aef8d456526b463a366c84108d5c4fbc0e55d0bc8e441e720e9a07b312deba072a98ba028973aa95cd64d404bb8a3cac5aeb2dd38355b14f2c5c48735bc9c4c57c5723559cda6cbccd743e80c3cd092444934c072f891f049de8a018f6aa2e56492a6f17748012904d07b01c5e3dd73e413976ad54e692607b8e55f6fef3edde65d170d4e0204800424970eab2ff79759467409956370c9579251cedf12138434a48a125c471dfb147d4404e86a34998f0000c953d68d281f894f15c5e77906ac24d3c8822a521cfc4f5db6cae74af4c75c9e2209c19c2a9030c57dc99e3fe95a81b6699d1a538aec06baea9b8685e80db92640555974d4244a8fea1a65e882aca6593b08423a8a85da22833725aba4b57128bbcd0693742140d480afb6500dad59efb2601a7e6765a99ccc7b9327e858c92518edc1b0e7518deca824f96e339c613f888519fa4073f3216eaa3b7b442aec60d0b30411abe44f4bcbe738276e3839030d97391f055077410f0f1701fc330a514b9ff2800839461b533ea664d0abb4a2634a4d34734847fd91df6081db1d65ca64861d4901c2c07fe6c3398f5586793848464c63d04b6355ad74d624f071b20cacf4912515282ec73e831433def701f71980a5303b4b6fd0379693a48d6e764a56332ac1c00505769c9a663d94ce526b2bd658e395ce8f50ec0363075999223fe407b72bd8bf85fa16f9a832c69d96cfdc454118a26852a701483688a751e1bcb52308451ac1f93ebaa2335672c781b9ca73a6f136226c8372c5b1e613c0f8047e19a8f5d14200b29861272048700fba0da416315d2ee49337a6719700d230edc1295d23145c00cc46fcf259582d2b902931eb0ce73c73c39477f07c7f6b2ab900d11a5021f4a640bc0a162891b46491886d218103376fa9748d241d26c215906ee4783e0bf681e7a41f28906e94ae2eeee6a11b3f7d88ccfb7c4c12f585811d10fb4522e0a2f8a9356bcc8da2d73c85c5bca0674d254044e1f261a18e10abd999f5d709fe9c336b827ecf89308b5b09b9f0c0800229ee87c8c27e920bbe48c3e5426349520d99a984d86ca8619ba5928827d2e6b2c6f83049b30b3cee014bd15e5a2d9aec6014c36c55a0358e94b852eb4843c1503e29124920621f59a6c6963252ec50457e9078b000450faba33d9c275fa86a7e242d3690b463e0536215c89d671eb8638d67f1285f301b8147786d9ab84703b99bc78bc10c17b99348046d09b1ccf42d48fc124fb33ba0044a261bc8c49ccf783e57703500c106d0ff466d64b92fd9cb31c3dacfd050d67400ec1fb22a670c633090b7c0a50034315d05641e8e7db03abc0e4ec6993dd80ca5544f92c15c67e5d3d17c718d428e48740d77db528bce6d8dbf6a909b72fc2b91b21443ebad587b517cdf9f1c30a464a948c64ce469462e94a6db47e06d74b367b8ed18275c66509c1b22e93e7c4a2dc509ff098d8f686764cbb031bdaee21453a531319fd7c36f385a4a7db85d4eae2e8ba38b76ecdbc1821dcb929da7e749a7a8a156ecd7325b0497829d69f6e43894d4d8c30fc389a39788845b041412e2a4b801ef818bafb6b295998358a28339de3b79cecf0edcb3ad5ca4a8288e4674b08e1797bfcda697c572f69fcb25ac5383f02b91866b17cb8553f59370f97ac22e12800bae6d94f98624b6e9e65b0c90f69fe88bd258e38d721e1ebd9da1882bde0ca451872e46d90c03ee326295eb69a3e0a8a2720cc788ff7d11b5be9d37dd3de992e0cd31593bb0a8ba154fd4ea16d1c0d819a0cdacfa66b417cd6fb179f0b2a103b56a0dc9a8b0bf2c97e42247f2e2b4a5386fb8ac33013a617f1620ead2e663efc9b80af100ac046cea23754c62cdea3c2dd354d86ad68225bd7a5afa7d23ab89bbfe1b5a187f527e3bcd5c07e759fe4e85cf4d95bc0e8402079587c506790deeb935aff39aca813ffab84385adaea5a8a43da82565c1ceaec80fefb25fb34b5eeac88dd2616d57981b2b03368b415c64d6d6774fd29234fc7adfa16c061d25965bbe107e1ab2122029dfc8e76e805c872b04671cd9d924b9acd220f8210f9092a2191110c817d34b00bec80af92e6331b2d49867786ecdb3937601cf87840c70e8077ddc2a473657d7c26d634eeadb0a9cb931b64af28b9412bdf00cf2a5d3bedcaab0fda634e513b672a71c9299455a070c17343dc593aad95a331e4939043ae140c26959c383cd482ed2ed2a1a3ad0a5b70d86408cc1b832aab1caeaf2295f959c54c25d7a8d47783816b86b5212446fc5136d2784665689294e14b277b2186680139e9f98efa52cc9097764ec12762577d1e300e4a3648e66cc12fa02debc29ecf395ead0a36df821f7ab123c3356f7e4ea36b41c9d1a19a5a779c2b9a88023d1e1d5a4dc64ed4c43ae4240ee74c756c92b2b541328a54638749ec22e8a37d6b4c95df1caa09d2af81b6e31dcf6ce5fea0a230dfa910290da215501c826930df2096f3ec12c9d7554bfabaa1b29aaac13ce5bd51d4b3b174ed27c6c85cb62f0f5702c64c08233e6a4b02579b9de0edc18d1948774162f61668e8141375513a070251f16b380422c664c07f0baba898d23c6165656687c76622eb4a8d9d8a4ed7cb49ec43011cd18295109321506e3fe5afa0717b066f818a5275d277595697d96423f3879713707f5a6b26fa327868392d40a7ebb46781391587cc501e1d4758445bd884a8029111b4c718215e8eec4493ba925c95c65e502349b0e64cee9d603726a213756bae834374529d3701652faa34c22da3cbc4edba496fee26e9e2ffa70d005ea39fe94f134711e1048e12b2eac4c70b0a8889ddc9b2e29415e06da424bd3bb7bd3015dc6c02d668ee1342d3cf0dbb021d086f491ce63d6736f787b0a7cd094b2702a585c837c982a216a39ab82e5fc2cb5c61bed6e9eeb02880a0172b65628483f4c55eebc31a44edff56ecbb310d034ee53d8e2d455f2e5cbb96a738e92bdda106f0458df86a47d1cc21e43520c86890b87736a2aec7238c86b74bd227538ad83a34b116d1c03961cc05c63b8b7a400cb95477fcc64d98dbdcfbed2dd24dc361d03da97a13faba80bcec162d86fcc15e6b1d6c6722fb1ff0cf4c35466cb279a267c70b9ab6320b7e1ad3a40647eefa5dd2f6513f990d24fbcb76a4d9ad73d3c53cd6300084435968d683b76ae784e0a827dd7a5088e782e5b63f72fc64c9bed326a34bd481866e41d72100d3d4a454aa13f1a14bab5f9c319806903671cbca630629f22938eb4be53d2bd952fd208eb5c884a8566804380c666b18254ac343a4ade9dfa46ea1dae43e558b46c874de2c8c91992d5ed9e1ef5405374f27710dd81f3d02cf20493b058b9e4d8bf6b84e2d15b292aaa9a737fc8c23f873aa5acc887186e05813259aaa1158f789811c67972009505a78d02d50ee1e084b6a1d4a322e738217549aa2c211c3a7b8d5b8d3c6bdc46ff7ed1d94607ba1115a875a9f7ff24af0ecc4baef0430bee28a3336387492df8a404af94d7d7d449feec816c0e7fe1df7fc280a3806cb5edadabd8c7e045ee4f3f7da998014b4e31ea147c96f2917c425d7e9eadc038e4f27675b9405b710862e2e7d90ad3d2ed9d76760078bda35b9bdc5c03d782f89e1ab17cfc1a332b8479c02fbcd3973bf40f41312ae238733834d9ab2205bb4c429d9a659e2d4650b9f27658b28efaf8a4bb125bc5ce669c69b499d818db7277388aa5703ca4fb97d5193227753927367299f86d06c7462aa25c3185b02ea3d324137bdb6f156c7bc3f38401ce1fc2b262cb9ee14c85a2bf00d224ddadf1d7021d7598dedfe55635e14e1c205c50f02766e083189ca9f6d43d0031e9d84dd30b32e0a02df1551f6ee7770fb7b8c33656ca68841122a4c9620df09fca48c1f40e0f71369cdfd49380bbe11baae855118399251f1c92b9abf01e140a7a3ac4976d32676e8ca802de4ffe978037b8626f4ce9fd3f3002cd54f56b893e1df821be3cbcc038bc45c5bf008a23bf975d6055e4ab30a15a29734a832797426e2b6a5d25d109cd2bbffd46fb8f7506548baa8b810e8677be18f9ba00ef7224f0c697bf604a414b3f5c14a8850e3d99f846b8d8ad8337be383d90a20749c773c56a97bff7223502f572841fef425f44ebba09a3674a654a2f49b9a73acbc76f59850139977d704f75e8c85574f1529ab6ed352e27ad927baa13d3824d11bfa31605fe242e2e8bcbdbdf609b0b3be0fe22b67b17390865c8900968d027a1700153616cb9969e96f1589a4b8946735a6450c463851300fd41557f2b9ed15582b766cfe9082439d6357d4de26f59e309429fb5a00f095440007221ce14fd5654e6394ba0878939c5d1a357e4e0d58927398d8e79391511f1140709271c72a5eb69efbc697f95fb8c814f350e136be96fc45a3613d2b76cfbc6ab0e1d1872f3204ffa84cfd250250032d69210e0979ddb827eb68be61873d2f82c5fe4e4a9e2510d33008e87e402f192d12ab18f220d00a81fd21ac53404ef12752b580d19515f83ba0fcc7db5995e51f436890a01071cb7d0ce85e9ebad4657e001a4ffed48bed0f6bd8a22cd7f20074d1ec9f90be7f91fe230fd7c24d3df805d132f91f7ef29ef2f47f2fe3de03c91f59c97fa994a1debf03f10a5cd72ff8d72fffd48ee7f82c65a93e5fe07e5fec791dc6164e7ec0d15b3f360ff7924fbfbbf0694ac14a48a8432611ef1ff244e22892251653129cd6f699b58e05d16433f422f39f6e0ef8e39c06409fc213592ab16b964e00bc6225ceaa0523ad2cf02b4f9912f1af20c44afd1e2c90db3bfec237b5b40b9ea504d6b9b0c400db9884d16ade7a89c193d254f07c905c3809f32853c542841a5c19f8e2ae5310f3376219cfe4ca36fa092f201bff3588d8ea233f6e6c39d01ecf303883a98d74d182f1a3492827446d7a27eeaf4d007c5c2187ce81eef39d13ae2b120cf1509d1d848141f43ef582e687412ba475e1b307fc9c8a34d5a4c8d445785e0a1875924ac11cd543fbe4f99428952f7747fa29bda4c1d9bc700cdd2cb7bd00630ad536b3fc5778aa8d2223946e1e04fcc718e09f189b89422b5e34392878b6197a1613c6764212dfc967d19e1b3e4c36162ff646b786dd356fa2999203e2c6ee292264b2cd2cbe1c5226e18ce050b1a80e3895f16f1d1288cdf30ef07a3e7c41dcad0f09f32a65f9e9c3c9b88aa3a3f9ae7c341f43b557dc8ea1a2467bcc3e5b31abc0c9870fc67e59348e750030b014bb47365b4e1d34b45adde0d05c2199fd6e5bceddec97b3e32bd93d032efc34daf010f1465999cef2cfbae636f9f4697328f03c9c0ae6544c79830f62ead7151900fbdf09392c36cce1cea6322578df435ac44c0f1c9d8ca65baa8cb98036995a537165161767840322397996d38f290403fb99f2bce42686c067db3aadbf42e61636cf4a3a3c91da44bb637bfcafd33f5b88c2f01da7a4dd05acbc6314605d8936be07f40e7b6cf90abdd87cdbbdb7fc37ce13f0a2a006a3f62fd6025e1d4fbbf53e0c3df42685bd664b72b9174032e75a5e0f155fc59e34fa5369b32f5ba4af8d8b4314e3aff6b6c67987ea1226a3ed3a050b947948a5343b73dd8e9859303f891a39710f167ab80cb1a9614139e812b0fde24c2063d7b7306caafbbf0ef1b3831f202d462ef67a1e4eff8d0152aaa00d6aa34cd0261b5785a78b5321feac860d15e128b1e5d826dad69c1fb2a38a2c1ed0b7e86e4f9d592d8e873f2a10ebed45d747902a24dd5544c2d839f0180265f45491b8cc3e84ae091cec6346e1e60de73fd656f073b0bdd86a273564b509595563585c1c528dab4010903691082f1a70729e3e6653b9845bd16c4d6728d8869b863d317dca71c875d5a4b3f69baadc0838974c02ecef456ee2e4c4f0ed9ea754c175424d49ebc644b1ba6e7309e326c5d9387b30fcfa96adac8ccfadbca1df7cf915756ddb7a8e762a26a3bb27da21117b2961a556fbd2665d8adf292c2e55e9037812571756dbd66e3c4ad6b52f029069f638670ac391c869f158c6127c15b8c4662cba20dec1a512a277c72529b224f6c12409d6c451de60e5e4d207787f0195b8d7ce5a66f950ec4cf1e23049d985442d92d6c970f98e13dfe404c3ec926cbb9a0435b09fbc8d307d41ea9074082d4944366fdc783964570bab9cfe8d3deca3daf20183e22d3af13bff7287d32d1f947983187fa82ac35c8abfd1c1f6e8627b93ea0a6123d162776ecb923ee04e6db9782de1409b3e350d90b05ccd1932d302cbe3a6ea9e7277cfba6b9b3f002737c2cd926e52448989090264b97f83e51634c4776746853cbeeea4420990468d2a135c553487802236f4c28c0e4126c0bf0b15e476ff662fa6cc356991042eb10c769c03cc007a06c992c4c1cbba1e3cb0ee600b822098759f6d69a3a533f9416955de213b2ec6847993ee31c14fc0a8a689a21b7f9b7c359e3b46313075e271cf96b41b7c101b5d0ffee41b8102277bdcf62337d189ff66b55a6bc7914320f13c003f6a0e618e5aab3847ff748adc6dc294ab9f38425b21028731683bc83f8e5ae33296b1683ac83f854d97c782986a3cbe3978d705ee1431f70bd72fd313d35719044925b2a90c520f7207e6e7af26c4a99f33866e714de2c32f4a7c62c4ad79771d917938be2fe72515c5c7e3c7b737671f7707e735900c6703db9b9c2d0bf1f268bd5e50223ab4f77c5ea7ab6b858629c1e69476285187e007188e969f19ae598a8548f9cc00daacc830d008199b5f16837dc9a27a45c044c6e199028a2b0880eacac7866ed49006608e277d1fd7f7a1ba934564bbbe0962d6c5d27007106e66343a0d08a67e60f5b09dc797897a8569ada0e6704bab5fcf762f51e1d982807dd98e98905bf29027fca4675931404c15396b6c134e7657c7d0942c4046b55c5ec3c1f59eb6bf94d493bed2dcd0db140a0f97b820f9f0fd26fe5ce1fa671de2f47f27ec9018cd04f828401cf8bb48c42d7c8a9a2a734c9d72a41f2f8828b3e96044fdced87694b14e5e629a419c6af462a2daff92a725bf37c43bea502082cb297e2b8e789c4f76650d89b7bc1afd814f89491418e0448872e52559bd4b10d66d970d737f9389abcfa4dd6776f702496dfcce97ad250468249945b4977151f21d84fe8241e5b6e4c0dccbe908168d59bbb8fefff7a898f5c4b7bb781ef3cee16b72945e148c6831f579332594fbce9856f2695e8582fb284fde2a4ffa42a7c084cee3cbcba81cf23c0efeebe89a7f8cad81bcf8e15b8509147cc93b45655722577fe227b6f882dd092cda2b47e9f79b6e5a4ec997027731f33e00ef3a0563aba87c9d109fc50928c135db0f129980c0113fd0944830579942af83528741d39505e22c0cb5e23e3c042a36175caf72cb1eb4cc36fb998c6ab2e13a76d45e49ec2ae4e1217de1d3f27a272e9c17da7eedb1042eee644ab969522f90d952c756ada8ebcba41fd823f000d98c207e5bf5bcce5e51c3961431355515593acc6467cdba7cc447540de98ebca321f4497b2c90b6f94ae588d252bc50560c22f54cd0d3f45c3bd1d4f122282ccd9608da7c920d5f97e7d86cfd004a4345c84285e9946094892ec7077283ab43d0f89c39462982f79fd29b2bc2935d0ba4b7e165454ccec224c7b2e814841e14ef4e281898e4b25d95f4cbd43a7c2bbc94e39b0d3da4d107bdfc794fd6477509a1aaba5870e5d91472ca8118dbd18b184eff0312441bf864929d78b3cec93f02cfa2bc9b4a2bc48232918bb280e16629819f5c4d3cc505a9aca89ae16d420b6977071604adcd9873c99f9e3700fb3b374b7d765f6bdc85daa1500daabd02e4d3bc2e0e8433b9523e129189ee3ad519062fac5f7364df6fdc5c74002d4806ff1cd8b96061cdb9a273634ae90474d3349fd2c41269aba9839db16f48c7d2890ce6340d3ae0dbc0681ddff89e9144e002da02c434df16107f9a2800e9ebf180526bf1ccaf9a07081fda1991bb45ab8b8a907e9504b1aa5ee5bdaf3ba6ff9392ced6424d710e760210808a391db4e11543385f0927c0b518cdd1461f421ba1e420ce608b0594d1e22165932a49b10e62575c5c14eed643317b6266e5eddc81803ce78c47bd10a816361eb9db31dca531b97826ffa80d7f0cc86f0bf0cba05e99b26503c08694225573105ab7369ff1482a86110a02f482bb735bd939f79f6b3ee710638e79f39f08545db0b7af427bb346b8953028e2a085f66ec748d0fbec17747b282d00635574b3f05bd292eb715cd86273584f39c8cc84bedade44c367437b43c85e4f05dd9b26fd3cb8b1bd534f120786b1ea3c9c390b101885a83983f9d58d171564cb8408dda1489d40d2685e589f614a23b0752018696af07b54158c46f73b23cfb887ec93ace5e9449ab0a11633c230195ce4e02bcb26dc5b36680007e223366055967b947a07542e35330f97612507a1a5343c138a283c9f9704063c06ced78b36c958f2b0503e059e031331d05dbee0b6cb4cf8be86dfa0b07bb4817c0aea3151fb4fb014550d27a151ffe3c17a8c90bb76be8d8fe3ded9f30ce67186ec006c3b03eb06ad1106eb562f7097fae43b7d1e6045775191fe7cdcaa5c430b19fe9f70b7b207584c5f339e079c8d32c11ff2c3a5bd3135b0b4adfa0a1679836843e7c4872f26fc09f3a58b39f93a4f64af9a9f0b23676bfb2029962961cb2faad8a2cd8b5b0ab2cea3c9876924a7d0f1eda01d6c1066dd82a01942b515015e88590e1cad8152945610fe64a2f454063899e2ba93bf7c431c709177610879763497201fc545531d589efcc7ecc52d6c20ed4650a4c004c89eed656e97361a335452b76e7c301173c298124a3601151a462cf21ba2c6e48b9a818e0301fa569257a587872e941fd73e124cc0dece0ebdceef2294e6ad48338171670957bfea28ee681531ff36cc9a338abde16e84d277a3b61f5a5900e32d3801129c0a8c29d1b979c1f698a6bbacc3702c7a379465af3e8f40e6e4a1e6d217515474e88b27aa2acd04c5c12e407703596e1026e8a6c3f3772f76243bbbc53807dd2b2e3b9c8c3f18cfc92cc10e9c53ca00959b58d8fdc8e577acf817c9fb1d650dc28699fb8239394de713ee8ccdf404e08fd883c40881117105f5304c24c2e587640716e1195fb325e7420b5f80e189a4ca0b115e8c524132fb9f3a4040d70e97a35bfc974456e58f65be66812b6498d94bd37bd1f1c639a54ca10e6f5c82c5649612d1c3ea5eb88e26661e50885a46d4ba03b41f1c806021ec3670e7c8920e3730c7d41d6a68b9de67be713d751504f62026cebcf1cf88258e067fc614e9e50dafd350bff4f1ef9f08fbf221cfa8c3f5fb0d79ff1e70b11986237bc9d90619b0e491dc74fb3811d5cd15393114070c2701cf18e8fac03263d006e7c8ea12f03c5ac03bc0a10c7d8c1979587655e26fa50ecf0e58b039dbf6c031c7e3a381c7fcf4eea0772f196b37c01d2927947b8fa8733e855f948a3f47455315a8145bca140d623c2d498d909702d85810f1df9c205437abc0a10f79b668c5d16ef4469394f2c7cfd425f337fc48ec82082c88b30bb1130e611d7b7f7a84cd0b7b7b2e60394e5807b00745e86db86817e79d0cf1264fc31294060c400d6aa9c451e9a329a9ceab90ef0cade3ec9b9d1c6d323ed29955d9e2204e065fc992985c84a0e7b0c153601638ce006f8ff13ff1f69cd708942472cef004f26be450c09263c8a14c2058af82a9092342d436e02dc344c68b44a13e6f2e2f0f1bdb89bf2bdbb8f2142149639e1884f1180ce09532ed26697277062128d98e0623e6e758482f9c7308f254d5998ca21c1769f27654dbba8d01a2fb57c86b155ae37ecb297e4a0667528bcc971a6d80571b8fc2ba4e9bf36fceefb8ced2838173c7d2aac7431857574e6d25b10d7b54a67da3cf777cbd96af6db6531bbbd9addce565f60bf0d6ac8261d2bb932768230892861a24c3a5000eafc07f688fc99035f18ada05d0f6c036029475fdc015125b51e5c6bea456e2dc214193af53ddf6773f7bc9540c33a63fdf93ede3ae85871adb4ace6025d06ef920805f7f3856a911c24cb0f2d9f19f669f97c9d55954aae4d560d5cf7515800777f5608d91928b908a12b63b9df2e53464f196080fedcecf89d3b7ee84d79fee58ff0d634350cca91fca177d2a60ec274e3f8882d7b6e90e0157b7e77b4354f125331234d3546126c154f423562dd44e64a4c8863c622dc93672b3a0e3772e327ba5a25a1e94457e72c347d4a942930326f06f5f0578e67771ee73837bb79c268b6183de89623fa1d22b4f2b80df022405dd279be4bc03d83db4ab89b27b7b3f96435bb03b7a18b5571f9dbe5ed6a79f6e60c02c5eacb3df8d5f1a62fb751d41222e4821fc2a45a6b606333bca36865c05b30c5d8713fc6d0ad02861b29f24fb875ad14d5839315c15b995b67a73574a8c6e9f0317587304754d50bebeedc9b4052908c908a63e468513d01c70f193658e3423af52daf266010ecdbad13ba42f374470666d3e5b2b85f5c5ecd3ec70c94ba9cfde7b298dfddce56770bc02b6cf4e9c1728200ba6f502a8f9115b13397108bfd5cc4e6cacc9f4b2b144426ae9365546e42753fc2eacb46818728c2dbc090885ded477c90ddd0497a4603f1e57b561b0483dc1bf4e3fa1cc8c82b63334f764e5a72e9c566a94c63e082bc98cf5ebfa8057372b9ae117e636c5b54a64556143a5a9a2e97e81a8d7030199d261652bbdeca1b2350bb30dc55e42d2ff3af77060664197a0e7c2b175d584d974b38a428d82ac16f6c52524e665be7fb5915bd52446be63094448e4094e79de49ec9a02702a2c1cad1c758492836651132a9f5e72d86391b18c583a74f477aa0b783fdcede10865e108042ef7054d1810bcd3ec3e064499607413a31ab325de66874064b9ca58202663378dbd781dc22d5a6f297a6a055c0af97d23e210f3f7b27cf656d02194c423fa40806bec62129533060b1da3017a76619c9e0f82095fd91521845862b13cd2f0ff0b37f46597f7c1824ed58f01e95eb5d40c2b2e347ae218ad770bc6c621996c840024b0fd6a6daa7f22196670d71ceb9019f5479e398924a631c9b479094ca708d98c275eed3dd935d43a5b03906025182f360d3f7abdc27d1533a01d004120201aeb0d3ad8cb1e058339db171b1017b6c4f7288508c1c73618459105408870091153825c704a885b34264504974e6b5e100e489c98c1791039227493af970a7e54833a2894908ca08ef390a502265e63bf275711788cb52903e0d0ac002c1e56fe533bffa464c47a63869b6a2189a178a03fe4059a3e02d13f56c5e24c42c4950328c17f9368b1f59df83b76facef654a71fc5cbca886db28d2bebc4aba422f928aef6df9bce2e18636e130a0d231f2d8c216196c56806baad612584261f661934c78db3099cbca24bf20f6ea7cf4a9059c741f39c6f9ae0d71da7aa6daf396e770dc91bc05a93bd98eada58ffb52e592ffa75c2f801f6ae24d5344e786a076c432fa386c6610d0e68adc7d8b9c36087c191c33f7e29c01c43f3c126cf27b656c64fe79d92e8df53973d6a5b6913d0c6412cc36b3cb607f84b967d080eb9aa73c87eb3781a556ec6e32d16b2b454026c8a7ca26d7280b0b36183989b0269ad157e4dd4d7495aa8773793881e80b61033ec2e13f84f71b5444447621f0182b19506aa571cb33bcb0e2791ae63ad76bc28a11e40e26767a90b4fb3934f533d0bd9fe1ff17aa9377a3cdeeac0027025c21f6d846350d4d0dcab361b7f90c8842e7e0b4109103b39b53768d01b663a82a7cbadbacd84923418f2b63a7c4302305338fbbe97314eb2e924e6adce7d0a1fc88fede8bca824d66d4e0dc0a474b08a854a689c85618484e7ddf5affca58620964f01edf2e0c984bda9e07f8c0ffb0ea3ae320f81a8d6bc87ed3d629918cf9e3cb39f239914288eb22f6712d9ee4ecc21dead1446d2678ea99a9dda41f2476513f692b1c3e8c4c63990d6555f43ad3871b32a568406e0e6e8bf535e9b64442e2a2cf1e11729dd144a7a5c8e44856765910713c467d79f4c5badf6ca495554e75c07d89b8a0575a44118c0c1823c85e18ad5e2b9dccec9070a316c24658915230fa40504d5cf5b9d8a9b68f0a952925e2e75a3ed3a9377ac1f546e52f265c4920495150074bd1fd308acb0e981069475699e1bf7299cbd817982f39aa867d04f2d954ed56b88758f360a34c07ee06b47c1e2690fb82a1725acac26d02419b71537118112f269655f2a730b804b3d5656dc6025f5f1d943b10601caa43c6d72650f12b7bb8c179d925195ce41e05589175a900f0178f6e62a11ff0ce918d97c451593587c0e233311c8b9695fa48aac60e397a3dd89ade0430fbf75f581fde1bd05b0233e4e2d0d948913f750797693254a527c872adab97730cb06a20d713e4e61755316552501e2849797a6a02361d7bd000e6ef597cbc29d33f464beb35bbddb0b21058af23adc248f1b1a026d09e827d0a8744e65637a6bea037eb4272bc941b5393f281eedb4b52db4672db9b615cf76db6154c2dacf2db5695d168f925d41643692eab20b05d1e232be1764ccac4204b007c66490ed6428f03b2e958b32f4f84a3e7bcac98f4785615aed256d55b0c01ce8252ff007e9252043261bfc2d5db2a8d246d990cb7207a83dc7761d722dc320dbdc408ec9aa4d2311736c9e6111fc035f1871f9966860e478018b5fb33fd3e1817dd359b8c7c84bc2b9a802cbfd149d906b6c4ca5cf17b7878f8505d21d2aa30767e0e0222e84ecbe39e08c3b8d3d34cc1e89bb426c7f738ce3de3f879ae05f632318a3e5d9c084675e3d66c955e24439956ecf298220faca2f76689fa5a1c4cc812d4179be25b8e7b93fcbc427e6225520c09778a2ce2124134f214e2b12b1803775101c2450d88448b476f196d141138d1768dd2757ac3c4e5aa3f45939f832220db2181a9a3c6e85a3a6c3a2a3f621a500ce4c7a1606d202685b0da481841e796995f2c629a0fe2402a1d66c2a201d4dea816554b22ce3d4885d28314e233840b954fca3a8f2007214f29c8d27e853b3b4eaeee5b1e8ad2a565be004e646c691a25fdaa7cccb652f99d7468ff7b8588a5a1100e441e0a261474f42e505bbac8f768c895def5c8357f32c51f32728eba4ac56102b376ca479a868199f977a6a977301e567621a6cff12a06db8e775da63a32045d61bc871f2f94a88de68b839710eacde6b1502ea103f11445b86f2ea2b56f0214040f794f5354b9782c0130c78a0865cae37843e42974550c0a292dd9023c0c308115e550a3a862a9f942544a90f9560a97c66523750368d60ce60fef220240185944215636f12cab62e0a1dc55260fb4e279a0c49043563669b83296375915ef7278450f22d9e78e7e893116bd763fd573b833e2152276ca65fc83f2d1c111c7adb0cae3702e9883192a99e94a95cc7e9b0f5374df1ea4b847d54112dc8682d9d9182244eea06f01a57c923a25c4c39e92d0f68e37a8452b2ac2423e1ec04dd4728d73810cac9b0c7bf1a053eb41a9d683670b0f4e2e9aec8ac4398a33d6d01c46b1c64eb96bd16c623cb412d5030731889c0ffa54e4f85364f666ec1b2f7749f148b9395ca4e8388b302cc0e6c3c8e351ca55ebc5300e99238829723e483ab19f07b12f8358ce151fa60e12d2e9db8a6633b0910cdb0f6d73bf8525ffc6fd1848430e8df5413f10be14ac5ecb4b931460d3b3c3bba8320e303bce36a089ac920d9169aa2db7f41c36fe21368e56ec6b34c7c3f30d574da8322176a05153131a44a1405701ceedfaba064491a2406b0fd2c52ea1a9878793883cc63768fbe439b15791db2d1af43b4687545a557e44e2cc6422677c53916de276b25aa64688961bd0a295f082e751ab52e2582004bdd77dbbcc3c39dc66518bee656c8b1955296fc1d3454110ee9edd318ba635ce7fda1a74b800b1e8718109cc1c6b771387ae341c69e6f2ba47357bbd51356e252fd07723bac4c0f9bec3f72825bf5f6ca30a90ca69fdb9d2b462d99640ce43d448bebdfc383954db8136a32f8bb8dba03f0784d8fa45a73f20bd702b6be852ee6381ba31a0f06617a0044d8e37f4ad6105337490710f8fcac12031e1ca587e6b53697a1852ec30803ec59caab5daa852448283beeaea1232485d2d077902ec216275b05aa88dacf2b9a8a5bf0227cf19098c8735c2be345f1f5ece57f93ddf1dd0162be5fdf262567f4e5ac6ac0d19a0d7b9281fc939ed9a8251b6487102705f5e267d4e8797eb89b02f22db11ad0e39d900faca5856a413d5d7debdd0653b40e3e48ee5391ab6fd9da54506c77b7167d880e2000d229871ac74cd7a6f0cbb37bdf5805371cf38215a3815497191313e04a14979fefe401f2f236e5821ae92bb680615db7a8aa1804b497a2a1a7950e0bbf67ea033e90e8dab1a61433bf7f49475ee8b41f52e564817cf41ea22aa550f92490b6a981891d6466efcdc3c45b7b5a18e2cee4d97c5d0ef449610a8636a3520e0d8ad00e2d119add8c576c2122a5d5f31d654bd50af443b1797a9608239465a84a8874a37655ac64c6df8c556053db94c11115ee01b94ce9a488903bf0cec43232e1c787a408d6fa565c615e222e994ff3c30011a9ce3bfbd040001decc67b7c5ec7675f9f1724131783b2e4b9a7c3e881d6408a1c56f939b2532b6dac85375e0f07b068a648e5fdcacf946aff90acf8cf011c8910306878f2a7bfc69d1171108170c7a157aec51517ba55ae93cbee920224fb24841e024d91c923c68e503e0e843693287513aa4a2b6334b76a16fe87308eecab081627391af46e51ce1f711e50040e2f1e9d18ca9493a0c57c0c674e4b59b0780def4265545fcadacad6828e1d882fe41abdf11ecf3a415831221c29424919dd334b8702a4035881c296ae55f223050698f033c9c3e1c01b90f28f2a98839e75922ea3fc2baadb8bb89434948d95d4c2031193682c39734997800427ac6c607d666cc0dbd89316432ae92d27fe4210f99b7e9e2ccc9746a71c01fe0339894c0079fe50e1833fcee2cc6a279583cafbf1c6e87cc128ee06876095ddd2de613384e059c06c1fe5e378a78ef1dbd1188d46747ceacc19250d87d7c28e60a1fcfa2293f4f9f4b30dddfa76f53d2c0cff2c0b61e805a8910188251251f2934e87a56989f7883772b0244528ede2c788a2c12721dc02f702b7761c5b348d21436fceded93fc2b07003048fd57fc790f8af234cc966b624bd890a9827fef2935ae3baa9c157142234b2f6ccac8d3fa297e4fbcc190e122ba0e883a5d00d2b431dd318c95af1eb34ba467ba617a874874d2a589d94a0532c51b52976d92e16e941da152ca7552ab2ec04247b25d16db1190a43ae3542686ee209678953129197a45be1721465be559c73b1aad3b7e8d395e974f03997fdfea980fa3d7519201e5e2e8c98ba739929234a3c39c44749f66237e846856dad17bfaa44191ac96b25714e0a5263aefcacb768053260d5a01ac80e5bf17ab0fb461714d500f3d50f619dc6034663f5755951884715e273499a4c41efd31c465c4c3722ba99189ae26de93e33d4861fc053776f4f59ff9b2c1a59fe9c4e28d1ad161df7e609599cf1cf8428c143613e32e0053043c16e7dd80221169f2c9a7315ccb73b14bd6f8fb263299504939f32a044767a693fdab43254da1b4ac32f7443175f00246655a52f06d53835d344accda6117eae462a8663d67d60f4e8d520a5a6380ffeb68ec9f32e5cf6b6e859b52a110cc3fa9e47fb644e11bb3151a3fe0686f94ae6ec37e23d310c0035666c94f0002eb263a61c163110d4c74c56ec6b8b8ec9c6ad8356bf4bc1ab9bbe04461e0c48123394afd39993765a95f622a5e632f6d9cf0c4093760c71e1ce98b97ea1adb8c7108bc3bee530b6728767793d13ad55fe14a780f4c29083b086fc0efdbfaeccdd9e5fd7276038fbe005e1e15d621969ed384e864c3bdefb6e257f46b01bf5ef4bf825fdf5e5859cd45ad95efab588d0b54d94ae89a5dcdc806cbb5bfc62c2888758de9e4059b1b6d9245d1b35c3f2abff88eafa6d67cfbde27f3dd32ee7b5fe493cf1c82315070b6cc9cf3644e0af832c394291816503a1a88b8686ff03986be1c9eda4c9d262546505b2433c9787520a8c84f7bf91ceb8f25cb6deeaa8b553c6d29a35944bec72042309a9ee0586d95ae93c41aa2895a4ffc84cd407a1913298eeafa1fc391c8bc7033fcc2aff780996ae6eda6574972d588c9315f61491f7e36b0433b5096670a25a9b3e0f59072dc43fc9c9f0908bdba8edd40a3a39419b13c90c5508947d2fb293735be564b20682936323ec81bba4b6a06f87074af5f3e2d5dc487681d3ad05f8bfc09e6afbdf36ab38f9f62209941dc1ec4f1cdb46be1663e398587052066de737cf0dd3c6b692fd233a3caadac7a52a2a1877a3d3ed761f4af727f81264e1619af5eac1908a357787e39f546e9c71cf043aec3c4e265eacf6805e125bcce01962709bb295e640d28a878c69712f131a395894a076edf720c73801fc4a5a4b7c3647a4d2b905791ab093b141ebe617fd8e89b6ac14f8736a6144d8cb96dbfd9204ab311958ca63483c895a89250809f4103a748bc01cef9b9e5cef5b232994abc2979893ec1d3a6a1d70f84eab7d921dac253dac0a2de37fcc47e4c4ca663b25af1ab472e7f02c9d1ca53341ac8644843e9dc2adf6de716b9b945b8cc45e7d280e793c5c7d9ed92eef9c1a7fcd1ae081028d3708e88e2060168382e2f8a65796135298e8fc679abea5a5a7ea79b8dba521ec2c8f151fe2da031199ded0f5ea5e3f3153b8a366e327d5b99baa6d74a62f0968fab0b94344892b2af3c37770944d00bf987cdb08621cf78ace2de74a47d0a36a4f1cd0356e915d69a67de64aedccaaa6f92f28ae9fddd86e856b4984acac08d72a875326d902e8f091792dc32c6948f7250e25ab83cba84af371c8d3688535692aba58fcf4928f7abdc33df04dc93814bead2747b709c784f2e9af99530e20db867d1e5dfeb6434981e687b92d6cbdd722b2a6997e05c6863451deac9d3ba943fe1fd98e1eccdd96f978bd5e5e762793db900bee006cef762f2717e79bb4ac902e88258aa19bc1d87ee454304def490f4e0cdecf6d762b99aac1e96a45906a5677a636e0cfae2c74701f0252476418f2a8d44acb9993ee7384fd1bdb4742f6141198b5e3546f89f3f70349064fc0a3672ca0220b8b3d1b68eefa74dd83179d6f82a6df662492dfd03d690bf0c04432220e2787630b004c7e667f1899a3879712af2d99adecdef67379769c2bcb9d2fceeca66823fe7ac08bc90b04eb7e229dd905a3ca12742c4acb243a8f36c75ee1d2f3778c41b7c56654fe295c337ebe8a65d7600eac35a390ac79b7db598dc2e676894fc707f7fb7c05723658baa4a0740a814f432163648eadb8cb256ca75c2975b8e13043cac04999199cc9d40647ad833534a07bc8f1ff8a48c88d3afd9cf3743958a9ea2410109bcbd9b399864e231bb4eb4a9181939a43fc3a7dbf8e23782ff68885b1cab93746d0394ff9c85bfb0c70672e1c2a6b032b974b107df949b5dc22b6ef325be50092f4aa50dc10fb2cfb3ec7fa500098b8786c35c205deada1c64816792f1f352ad9ba8f2b2c05742034d3b05a1c34139da68ef53f043325660942e13c6d0102feea60f00afd085c4dd6d7175777373f7095fbd255b6b12e1b31f0f0cd23e84be4c7409fe8e739c8e4d8a9968a541b14933f7975e3f8d6b0b4264e81abc50bdc4f0d6b74d340957ba4e13a874d9f4958c855b53a98d626841de2089b0718c79841626f47b4ead93e1d60167a3961e912d1666027a3e154dc3db9ad006ba960344c809417070809dc3eb1fcf1c137de11ecabfc62db380675551b360652676adbc15764fab06ca17f7b91d04f9a9629f89d43ac2337ef873787650ed69653aee0b26dcc88d4f6a7fc9dc15c3c4bd031730f2392091c7bbeb87fd95bbe122b1ce44d259d23a370ed799e1b87257f4b236c8ffb3811f9c001c6cda194c9b3342d319c295d731f580aee79c2942fd2f5e6c03e5881e8fcfb2b0bf9cde9bfb0c01b372c3f30f28f7c4cacc6c22c579e3e5659f8455d9251a41d75d2e447a090ac226ea7d383bacea39309ac6e822f936b9ebc0a446e64d83983ecc576acbbe6c1ea79437db417ef2f1476e19e8203b591a908d2cd914024c0b59bb97bfce07c901e881c3463da7d3edb293ee50adc4913d10d8e7a01a67c07823b521187771f4f201f9b464c509da64ccfdc92743394450f105b588ac2ac7dd498adedca9ecca62628bef3bfa04e08dee2b1f2fc967d5902a56f2f270993b0071911cbbd317f12dd5b83f1136f7dd8b32e4968bcc001116a4ed8f48eacae4f7ab3b8019ac900be68df87e5b1a37daf1bf68f5c0973a33da94bb452533be55d8eb84bb52566ecc6e30bb44fe57c9fb7a3877eca2031264358c13c13888c5ac3989e4d86ce53e4f291b533e3e2b6406c1fb96e1849f5f5e4f7e9bdd2d96cccb4fee6f851b9c9ede65cf311061e1280cebcaeffa82c5fa42d6c03841d28c5e1ab6b5049596f4e48e37f139525d49d043cd5c31802fe71c6000c5f45392374386ece85a58c23bc28e72fa9f36259ee7b8363ee3077456b528df94ae141df474912152f11cc3a377b25b995afa2dbdfe44271f4ee7613f7fe254f84dfb335cd453d1290f6f25c0e16e7c5e514499d00819ba8e3ad5940b93c8792dc1225525f10baf1e0343021277e49c7a2db7e249a1422bbaf4b7729366332099814e47b283514ed6618d7106ba316135405793b67b9692dd4b04b57ee3553edf637b213d261ecf98a8f961e6c32f79a9e1ed9027bb7e0d867151e179abaa0c7b62e4a991b528f71fbb7e5296b219a88786ba87e9076e76f8d28457ad1704b6b4e150bc8ca2e32c58df8842b8bcbbc9cbd4cacce20b82ec8b2a4f03441be442839382f856a25714da62c0e26198565a745db3e7e11b7d63447e2924cdd87bc645befede4b382698c22fdf6b29abb0994cd9d39ef2629d088f46399fa471b77247c6a38c5c3ba05f61b742fd4b8aa3d71931c88b0464a478a149864015b6dd3bb46bac8878d62f1ab46b00fd48453fcb7527cac77bd3ec37a891d009947267ace10b09a74839b453bd518f209557be15ee31b25ac9c7532bba01038ae391ffc409c87ee2d8353d35d365cca739c558ce111afe55eeb97714b472e6420f091486e87d2394be677d4f179a426632f86da9e911c91e34946e947e9c5544bd924e002a5d85bc9715295a878f916dd5bb4e66b6af1b632f45b9655fb43049a173338f5ad99865a6b338522237e8536b634d0b5df06656510f20d08ac7d43fe5e6dc2362fb60e9326a835b591a5b01bf9dd1124c0a3d8b4920dec4fb3a7278e44ef983249825e2cb898a05cae0b42c763adbd718f266986f6522e98eeecdf4638c0c0bbb4ce934647b11a745985569c2437a14751b1b4839997dbea3146ab589b9f33a6e8d3ec89755cede3c23eb55ea2a86b7c2519ead60e203ee6994f958299a3b7d6cbe1792b4b087734ec9878b38484e0b49c9add1ca1bbbecd7aeb48a2d952107316902f2c013888ea6377401cf34f310792d6913c620ec0155f2dcc70dbf56babab0a2bebdc033163e3eccd26242d868e640187d81c85448820215c61d1399a19308d6b84c4809a5381e4a44337910d9cef287873aa5cbed7f8c6993c37474e487586d7c2c9f6d2900598f4ec5c8aecb04e089c5b214129e457e104f4296e501fdde21288f6f3ae9d0678e65b93f6d255919fade46b1083c37802e113be376f8838cce1ad45bc22f3b5d4e79f9e515466fad6cb2afcfa129b63bafa417aac91c84015df134201f326d8e35f20de9bde6756437824ae2e16c6f94aea57d1f431f92354d58abf9ff23eedd9a5267bab6d1ff32eb39932ac5cd54d759a70931220202a256adb222440884049320e0af5f35ae313a69d079dff37dbfa7d677d290de6f478f7d5bbe182b5137aaa9f0922a3bf3abac88fede2cf6a36912874d3434902a83f5b4244ca1f6991bccbf7c154638d48370b9320ff8a5cb72fc5b820f89a13e1dde9f9f16f74a8a4fa87c105baf0e491608ce7278a4cb3fa7a5cf72e35edaf0c9d73961c7f27ab7ede51ce50ffce2ddf76d3ebd89607f35a5b0c866f4e3aa2c3d90bf130d970f527e6726ca0339ef74c70fd207f3ba7c912ec2241fa4b6204da21ec2291b8374d5e0e6f5c1f5dca76ea588d408e36819897a8df59f290d86202934a183bc08b32817d52a71689085ab30a804dd81a01f221ae54a3ca980bf4a3171988c09ce3cf8e5b3ec5df3f67f99242ed2753a6147029cf063612c85d940b77da8dae4688b8139d3dc25c2215c0c22a5ec29c0603907cdac35c3a209557e73dd56c4ebebc875ba4ab75edda781fb70afee5edb9dc6f0ce7d7d3d81286d994ed6c6dd635e40a2d02ea35e5f058f03151d65a15584719bfd5ce2d4cb3c1b6b1c1b8ab0294b82f8354bd3e2b59dbe6d5f996f35cf4f5f97f6277f05cb09ff81060861d40dbaa882229c34ec7aa9915fb55ffcf67e5f5eca4cc24d5f5e06c877c9f89502794a9fa6d664330f6bf2e13772a9129f1127d9f6b3fb496eeec366962eabd7f9cbe8ef994c6359b0b1255f3b18b2314ad75f65fc668555940ff4288ae36162349ed92611d8785b3dbd36dc3bf5fcdaee735611ca08d3642d18cbb2fc872bc87cf088b9aa491807bb76fecb3c5f1d25e1a4aa4c6440aa68e706c63020e7c2e2c3b3bbcf26104fb62508945c6a8f1797260f69caafd2339be6fd3f10980d584ec5ca4cf6a7702b700b954585d84e4c3dd675584143b9164a056c362cd554fd0f3775f9d50a77b88017e14ea7256d8b73ddc92af8cda0d56ef29bfb5d247e8b6d85bbf5ca8a5da66f511cf683f7208b6e82f1628f759787a30006088d4edb0cfa8115cb27958eb9106be0c6bfc3ef4f160b83800836fed701a36257becb85c8d285aefd2e6996aef2ff30555dfa9d3af87cfdb627e8841f721539e520ef69998c9d215d9f81f74348aca8e614aef9ff6ab7fd1fa1a8a5de929a2eb902551fb858f58dcd66f9c9a54f5b6182230e98c25ce880e589489b09cd4d1997443ca459902b6169098644c0a95d09a9ecee5b4cd4dc1c606bc1929ba8f4de6bf67cf9dfa09f76dcbe6be76e9ab107b334093befd0a2db95acab7247180d1189369f81ace2eb2633cfaad33f61083c84ef37693c11a5dff23451df3be2d29ab0a349a9db21dfd5bff27cca78aba35f94ff6469f6b6a0200d7dde39d8b48d90872305897690b560ff4ff01e2d2745ca2569b60467d194e5c7c7feb332939134852d92264ebc168cb5ecb36090334bad48968a3f4c61fe920a409ed845ca293b8859b3f64e1458bb46c696577fcb754bec7accd7ba90d9f17317f6dda257b3129ed6417411e69024d3efa9d0725ad01e893e037f4f2c8a984b37ccc37281f3ddf22d95d79ac6b370d20f8bea62e1283073aa48b392c8b8177590315b2756550cde7beb906db8b320125dc60f8a2a15c3e3304886abfb706b8c8d91d3145b06d98201c83a39682da98a04d9f493f98679f9dc2c30eb38b6c1f58a50d0c4f6c32e319d646c5f0444f08ae6d906a2f4d924629d72c005e183f144b68355a95bcbff57f13a836f8f65f99197ffc4234a182e26c12eef12c5e26ed99159be7e7f8fd8508556f8e257edd7d5afda2f3ccb734501adf725fdd2c70505b4d4e794ff84be7effaafdbac61725218602bcf263e4ba347d905ea037627e96b3b67e3209627e1f054ff74553e8e8d1ff537ce43fd4d35e574ea2e4afb1a8cbd3f7e28764a9b294ce2ed3a498edcf049804b109e372f2cadc44188c4be98cc4cdd2acd84f88d364daaeaae7e39015fb51ab2c1d8779fe600dacacf33e5d46e28bbf6adc0b09712aa3a04494963673af3f647afdb1b6711087c924c838cbde9735a2465a2974e7ddc052efce9b6bc1a43ec3ec2d880f6614a541b3a47267edc5a6eb42126833bad8f0f4459be59c55658c066b18bd87316124d33056ab551c119159b6563e91df8f92a93c9193afc2b121faf6f78b95c91404c5b049b3098bcdb32c1c175e162c970184009af5b8290333b1ed2adbd90f6b550d760d4c9ea36064513faba6ef3e5d27955e3c7d11785f2713166816b07ea066cb3c2a975cb2676ed235ad82e5be31182f0c279c5d54183638be98078ebf37d59376ccfd36fe1cded7c9d85290ee87c51e53bc9fca4bd825133dfc5807b1684747b4ab85dc0eb2ea39c1b4a8182f7988810559a9ea9f1633db1d60c0e34f8bd9bedeb8caa66b232e6512a99ba5458a66edb4bc58bf358318abf69e85a1bb35af61d01793b1d0a6363a9179f9370bfd7c182545d9e660b7aa5421296a98b0ec123cc802fc2df089f77346879fd5e8b37139d6202fbafcd87d91f2d68262ab45b04bb238fc670748411cd38d3e10df92655ae55212e41a0141ca03f501e690fd4332e3500cfdf8cfa941f5d1d06919cf347523151d553f2f9d93e6b3002ce02ddd083b0a022af64697c91b54ce2800d70edd81767ec64e35927469b46b44bcb7b42827c374471c54b92dc6212261fe7918d94837c961dc707518d34ef74a82bcb4be276fb13e88a2eba329d246fa5ff2e8e90399058847c967ba08f7552c2af3a07b708a58278cf9a763ab6cf22d350f96468a01362f230c5c9727ac73d1050c56d1de74ed4d933d3dd5b4d8d361ba620dff6045aa47360e886a760414962a70326b39361d0099c5049687650e59dde37516b3d074bcce9883cff25f23565dad8b833afcbdb849164ca7e5ae01d721096271fa9a97ae65967c7725133e58fcafd4ba25fc71608cec97e120a51d603942f0276621281743dc7465fe67a161c5cbeb9112bf9aedf2689cf72daeb1c44450e7b5c475760ced8636eb11d25f279db0dc3f5f6552cd1ba24a9921e26d438d28898c977cfa2bb2a434c1ce61ee164837382162048a6649b64354c59abff7e9a6dac7fb4ed47de6ec445fec6e9e09aa836cf99e9bf5ea511387ed7b450e671758558ee5d169cbd08ecb8828cd7e0b60c2c29a526bb71b2549c8e24df4c77c4ec3a26feacfad79974d5e8a15f125739784d174f6c67b67196cefadcfb498d98f0b98a472d9f082415edc87f0096ffb5a9960c6c040364063b29395e73e77440d2dde95bd37af7b4d8c74cd789a4fe54f309994c3e3cce5e792eb2ebfc3ed8af907bc097beb6032c8c2b05c80ea26c3a74ec3f77796dd7db2d16e316317ce74084d2a1da03e2bc770b5e5a3d40202b260da4c45b39f373f6a377174e6a6e282c3fcb74e4ab5e23cbd1f879d36f54cac76deded2ed7d184e2a5f06abf55b1c8d1560a7bcd5646a7c9742d59a986a82f178cd8af888c94516b82c9f12b2b6635d7e4fcb8e55cfa756b3198da352d312cf945a8e7faa8db3a7e3db8858fba4886238e71a845b81c7134a119a95e5ad92e58135bba2d2f72c5cfde151287fc2c40bfe2f8369e98e319c940d7103a2fd355e849361c6343d619f2657b49c0e3376af916613c28ec595731c0ed2875064a6707615877a2fcf385ded84fc36b589ab2b69160616768998356aa225ed62e3173c5a4e7d7ec237cd733e39807a92997a521112516c03281962955ccea9611c571129480dcc28dc7214ec223c8dd745b8e7ce6a1cc403bbcd727c0c4dc14d31af5815a92e000a63a3fbb396dfd832ab79cfd2a428b536f2e82b34f3e53c0fdcfe6bd77d78bdf3ef5b7b11ee9ddb76ef07bf6abf08dbadac7ba08cd2ec9b7f8fe5bff25e295279a707454ac4796c1e2b99c6952ed23ab7ecaa9883f908eb2a962f9a46d9e24a30203ecfa65a6a7b18c9c4708e22e5df3545bfed8ab00448c672a95ff6d1c4d8ef319ab8f279157e22c24dd2f5745615e5836e5fa049b8b13f8567cb67e72d4a2665a7d5c3837a7e7586cd26acbcd8f64a7c05369eef55dbd7af8d0735aacca7da419145dbf3f7cf2aeaf49d85e461681e57fdb4a6aecba2945fb55fcdbb8ec23adef77defde6dbcd22297de61b20022c43bff1eaf16be3155d1cc52034c9a7bbba7da20f79d866bf490b01ff00ffb417c5c981b111c7251806358d9edf8fc6462fe39b5cd3ef2cfa9a0a7fc585be59a785cac83d8f8eb0ee2f85e74a302bc79522ae3c0e34a68d021b3a87b0f7a278b2a536ce10f0799a031f21e65e143087bf049c97a946d88ffcd72d3f1f720b53769bf1c8ee02aa8f48d9bb7dac3041993a5700365e0c3e412a3e064a8e358aa11e1344acaf73cc2a47adb031a33ec41a242e1801fb7832498eef3471ed80f308114dc48328c47cf788620903a68032ad17edcc71ee191dad8cf97eee4440bdcbca7636ae40d6db4da56f1ce3c7c61163912ff62b3289e18f31f0131fc1ca0d902fc657681212746b330790803835f554b4124bacaf3685a2aba2cc29d538d564da759382d913baabb9918014210c7e9a669edcb83ef92b15864110b3ad830c6fa1b87e6910f79c4c558ffb4dd76077688beee577c0e63fb1614acf614e5ed70995276fe69067a167e6669a2a36c1c8746497886b136d36c093a0bc40f2c073554234b1206a87a015d7a08d94ac85c16357eb866c5326e6252ca24ac9279c8280c2766bf66e98a9b31f6382851563d0b7253a9f9a50c46b182fe574fdcc7eb2550fbac93c4bb32c6cc19e51533d0e59a6542c2d536c40245999ac5dc128fe470f721e92a8de6c7f475f8ba3ead2835a5c46c7612e5cb2837eeb7c4d05a046a8de81362ea89ca6fce7fd57edd848170e915c14e1c4d881680085a4a7c887c604869341024b6cfab4f314d9652e6e5dd42abe1112ec394cb9aa055302e6c2d92db5fb55f2d08dff23066295c6e347f5ee10fe057ed578760f2afdaafdeafdaaf073e11e50e79a4aba3d477a13d4fb7d4134e12a477d4a0b89f11cb51d4692738145b3dd1046d554c989da9239df1f37eba0c198085991a8b05068dce1e58bfaae5f5b5efea0777003f8b0ff7eaaeffdae8bcde7706afc3befbda79787dee0c5f47feddddabe3be36fd07d8c656ce51042e3a91bc5dcedda9fc675bdf607215b32c0c260618e1d517de820c4018f2550045849f020e5ff3222820d07bcdc29c3d5258d26dfe6a846feba9e9c03a0fddf777a664d779e82f57507aff0c6f8cf5ee3a97d781ec7c021fd67908d7a2465e5c2a659b4d35e147ba6807e165f100883e403c6c980919a66001d79c147c04504b01bf09cae5386ee00cfcaafdda52b0c3cb2014280a1c3c7404ec86023700e0a2cd4b814fc16dc0aa3f6feba9d908fc55eaa9bd47a53f0a82392582dc0a0048a09e0de36ce34a745cb17b207e37fcd00e46320bf270f280974fb3f2dd5e202741f9246a663fe8dbc3760fe09805a09e0e06058f148c702ae425fd12f979a688170af0f24df006aa124c33ea1505530a66144414cc2958bc31d918ae8adc49d3380c4a3dc0ca825e5e2258aef36298dbfe35f220898ae82be4b78e52aa6b45c107054b0a120ae237e8de53010ab66fa547e401e8b58c5930e5ebf645ba4282bca84ad9776fb8a143a2ee68c16da7d265ac48fd33b3e144a9a7caa0de2c708b18876234050d789b7a2b0d0f2a5d0c8f229b14dcbc95560bfcd897110697313e3a46a73c4bd779bceb87850f3b51367cbda5e41605776f46f1529cd6b429e29e820e055d0a7a6fb0ea562ba8016ec3f130c98377e87bc596a825318bc49a7f91d5e0c39b61058b090461ab66a2fb943878b33d15b1d666f9191595d94b19593e355edae973a921d5f448c18882270a9e2978a1e03f3cb5b42d2918533019b389549889cb971060850d16c231bf4195465f4447090c0967bb4926b7ed3be598c13aafb441078231a76041410c7cc3381ab0e5df65a46fbd4917e55d71d519b1c2f64a1874dd30cb51180800550a19132474845ed1e53bccad4d032f382b0a3ec6ec43192ff189663a3b3ba29631b16c960e646d6c60487f9717e1b21907535651b615a04431b9a0c835fc8553b0a1604bc18e822f0a14050e059a8206052e054d0a3c0a6ee0639d82d6d8b8530c27d0dfbf1b57aa7220cada14714f4177ccda8060bfbe66eb84cd00a33463ce9b2c136d62683f8ef10a12ed370a867ba58d4306fb6a3269f7d079b12a7ea4a2230a9e2978a1003ed3037e24efedcd90502cae299ff1adaa7843fac46e669887191c2046c9d4cac9db0c4c59282552d0c10edb3b26be3926e6aa66041c8c9fceba10ebcb2aae1fb3872e2baa326fdf36631634f23f8352bea5db0e384cb1891104559ae42f7061b8fc3b17dec85fa63ec1e4a2cfbe79d59e3e8c277ef934d684d32c9a885757facb5c3af9c77aeaf2d15f0589f525f0813eb541abab8faa247f5b852542cabfa74931b2fd86ea989d31a7d96a266fde046fd5bb3ae986a2be8ca0f62b951779e2b8533a577e8fd374527dd255637f65e9021e5b8db678159396af8621aa4d903196572a38aaaa6701611c945b0172f12f4cd691bc000cca79f986cdb508775316ae233a859080820f30d3c147037710db151e7927a2ef5339ded85214417c1fa6cbb6e23e54e54ba3ebdda48a74279111a33428da054d3391d7cc8c3298878bf5553c5bdce08ea3e09682d64434c4a2749d57ddb903a880a3291c180aba14f42878a0a04fc1606239812991f6e1843d675b10f291a246143c51f04cc10b05f0951ee02881f7191a177bef8cb2942f6f76593397c141583ded0d1aed3d344f669aa7e58d791665604b6c86ff65c1192b6230b8c94b631ba3980611036fd6281f646bb1e706370ffa0b500a9d334f002a6a5853da00a1e5fa954969a8f4ee79d5a922cc59b1a22a1102051fc0a8986707ab9888bdbf029b67f52bec46368f5905792e5a1e0568d32da5ee423c5d47d709941528d0d83714b8201829f04231b5a95cfadc6045c2528dd6c4df52542b846764b018f841ae4a745afa23a05d44a91db40f2a46de33edcf220866bba1310d62c543832bf498ee83e208ed360a86143c86253ff3a9fc87d72f409f0b277b591da3c2f26f67042a4fd67f2a3b1289739e331fbe607fa2115d5e556414174ff24b858a0d6f2ab963053b202cc458ae3f8596b67a629eabc7a711a03f87a55b91f2a0c387754078e51b54a7a146ff5e62af40b56898109741eb94827995c3da5b65842bc8e17896669509633facfce2725a6991052b5de30c86fe97290ba87ec367dc4404dbab3c5cdb8e0497ef2cfa5fbda5413631efdb40adfcddb26fa192f4ed0245c2cb3ceca4466c9da14d609855a266d0c0de1e41fed20e9335edac15f4524bdf2fedf4ab9b45092024ebc17c502bf5df145c527045c1f5afdaaf53fa3c2382fdec8c82730a2e28a0cc6748a5cc6794f99c12ce510b2b61410bab5e87e662fd0221a7a2116e05cdd4a1ea583fad2344d953943d4759547c7a4afff377b1bc62ae29735edf4bb47350797d657e4415b1a65c9fef7be6734f7b5fcfc63fee8bf9236ea53654aa0f1b301c6076554a0b53eed5fd786686ecc7f15eda8f732a60b89ff0452d2a0a1c0a34f39ca018e48b9a455bc88761b20cf24538011554f107ff90bbfd53de063619054d0abc7f688dadd00fcadf50019f825b0a5aef36fac9b78785ffdeed258b4f906ec0acedf65e6282037fbf17370d0dafcb20b3e61df0ce5e3e7fb90c27117c0e96386f9772f42878d8cb7b976eac5cfdfd7a26b15dc58012877b3958f7fa390a81173d52da8882270a9e297879870b7f8222d03686de3c08410ae0b176060a8f8239050b38fac53beb30b185edc7b464e56f571163e502603ea6c6c957b52ae161a60c7cc369c9379f88fa3a1e77af5e78372ad96f41c5dfa2ff269e5048411c8cfa340c2337365bb2325809762204ded2e78e822f7e3390b638fd7328d014342870296852704b8147c10d84cd14b4808551d086a35f0a3a606d4e993198c13734169a621ea6c22528d97af0ef663ed8319af9ea53e60130350a1e291851f044c133052f14fc0786a0a069f02c31d08ec078c409613a0b8fd2338bce37f60184ae05b12144a299bd1eb4fc14b140410a12e875c2bf06051fc80ebd10340a8f07d05d34cf080acf7752312cc3601a66079f6661ed12252342d0565a330a76786c980235e3d77e6818ce0c808e568d02978226051e053714f814dc52d0c2431114b429b897770b267b42ec076b16c0bf7d0fb3acf2b4bfce2d1f8cb4ea544997821e050f33e04db480b36a739a491f52dc2305230a9e2878a6e08582ffc0d61892ee0813006d686c0f5ac5a8aacf725989580a3e2236fbce7672d0e628fa03c51f7ca6d164308b724bdab5884002b2826c305e6c02d69066a95994b0adbcd190635c967e2a18201172592dd19b089c2356346bb37030ace484c0c64b0f994584c7504069d29a53b0a3e08b02458113010d0c448959d367930297022ffa7e61f4936095cf52f16a5f22ee3794d5a7e0968256046fb490fad0e6a0e09e820e055d0a7a91a5139b16b6a4fb21c2bd0cf7e2d0b1a035464f2978a2e09982170afe13d926848d68a2658f07733bc1e8673f50ec1b92289850b0a020a660494142414ac107051905390505056b0a3e29d8cc2b534e18726e296247c1d7dc40275acd125f54f3f2a101de76124f39bb11f01ad15e0db7452b493789e43357a111e07ebb284c8275a3992841661d6a5b53d0a0c0a5a0498147c10df72c89f2593819a5d9c2fafcd6187597254c93b2c73e55708bc95de7bb76941807a798198a6b9426b12dcad6a6e07ece0a8653a324dfc114839b4cff9e0841eed1bf7e3975872d6784931996d2e61b37bc01e24e3c8d8cd7790881b94d23182f9c032ceac4b63e7a30ce5a82c9a47cb7949a1852de470a46983e0838e6364c48dff230fb2c25672f730bd8882f49aa170a0a50f585ba303cdb62f229b81d97beda932036ea12102d8b2793d2d5007d52dc1cb087a153f9a8134b7defb02929a9f28513259366f41666ceee26cd0bc357c68ac19d03537799c81bbbc178114c8da029ca2dd348f17c9ea336361e4e97cba8c0b7f47c2faeb2c07e9e8b5564164dc29b345d980bcbc495beb5c3c208364519b9d226abc4abe2b92b4a26f6909c9de9d9614ade4ca94c16e2e6358cdd1f6278106c054c69551f2adcb56c245ee7b3fe2e19570b51ca6795f1bf53ee9537f45c9cd5e47b58f6be81a9855ed38af4d76f4516867e52a436fc6c87791e4c21ba4dc2bd62d0c304c3edc1305c323c60c68b4e2b782abf752cd892ab62ff2645bbfccad3ea6d98d501be5eb6d6cdd2f748186cd588d2a4889275e86ec371f5605c4504e02152bd0fbb2ac241900af3bd0ad6f9cf356db2c03655a8dc251a4f89fcfc89fed98de232fdfa434afaa712f91f12fa451606cb2899f2ab1746e99d17813792516e7fe738104e7ea38a28776291ae7e2a47bf463348e47baa7cb2506cd84be7705918c4d66b7ee69379c2dc53492abf8534cfc3f21525f1ad411d6a044570d09fccfac438a0d5ea572f204a062b0673f24355795858b99270b357cb32fd0c6203978b82d981ec6c204daa797b9db28d6c13efa363cfd27862f3f8d82a0b095607e50ca1a0b06f2a91a10c9a6f97eac193873088ed1558962f3796536c3ab28ccc158af7a4976576cbcd69b0358a9df25a0b9ecdda7b38851fb7e40edc0579519a10b1c5c1bab24f7fb78e7ab9114b6ec4b2cc6a19cfe2b12379c20b3a672f2c94901fa6251fac84f12cc8cc035e68cf766d1ee445230bd82553166cf48cf9737b8fddc95b77f6037912c5d94a6f1232fa339194b00b1e5afd76b0bd2bfdba505237b01ecb4ec28df560b462135d53aefc1b25551554825fc99624a9d608b0b16982c4fea464eb05f260dbe527c1400450bd136b5a9270637dad0e3a6b4ce5ff23e2a057e339b7ca552e8cb25c9c59275bb27d2f089da2d2fead1f8e3320fee17255ec2cf1fcde37fb20350eabf2b018f1b3360667cb6711e3535219de1240d47e6bc61b0e1c1d9746889d77a3266167b4ffc342b254c6c597b313813b7db0a3b1dcb80eb01eaa31fffd5c6599d8449abf6f73492e6656be0e4803e4e3bf51de0f96a1956354ba69402eebf36d3e4c3676aafd19e4793ae6c7b1dfb1e611983477eac1735f59e5b9efbfb8acc408661ece78a9e093857e4e588b160f85eb646ccc3729a9740fc026b49dc3877aa2bcb3e1fb71692a1fa759789b0b94a3d87e3666b6b1efbe761f3a830e10db9cbd7de53363184bff4bbb58faf0c455036144b9fceb9b9dd00e56d2442ea6b06a32b1beb8c8304a8a2b03f796c16a909a0f98ad951f30d937e3e6af477ea65cb4d94b6efd342c541c0bc84edfe6a51787b7796582b38856329fe9dbbc34a77d9b9bc86226ffc42d655523edf1d2110344afdd35666a11ee72b1e6154f0df2854c4df82617235b332a5e32cfae310b73db78170f05f3f307121b25b33013072e916c6998f19606b9a519ad0c1425b91688fe21522c4a33db012b6dbc6721a1db63a3870bff5446cba4480bae8f7b2c536126eb33ccb87d5a6f79f470227f294fb91797c16aef7b95a5cb280ff7e2687bd8df9b3058b40fca8ded0f4cef9e7a3274990f23fc6aeca5e55199e8f23393f4b799667c60c4a2e25bea5e127fbf67e9d2486d30c72c590d83f14cf600956d03d7cff7bf2c0535369c6e0b130327a818cfca638aecec264143095a5a595ab99254db3e5e75a7dd550fee6b573d0c7c75f7dabc539e68377fab6616e47e526df88acda90d20cb408e954ec15d68bed2bd0ec3b1549ec17aab569bcb57986866f14ea1f9c8b708f679babf9eec9083cf919546596fa4a3333c722730ca9ae68319359fe21cb7640bd138fac17b289ad9cd751c5b51fbafa19d4295f24b2cd2cd1f4bd5769e8b3da87978c5b20088a364617fc34ddaa4dc45a618fb40342f846215ef0f6ae2d8bb83fadec26213864912e6b90e93220b6231274c1fa3cfc033860e1c5f7abbb04a8176986661b8577cc10f04708ad10297ece118af7a46e50be70d2e2faac30c15d6c50fb151f273bc58c336cad698a896e958f1844d58fe9c475328e1c256b4cc01c865acbca3641a877c83c26f46583a0c2014338c8b609096af4cb3a525b5415588af80d238d17a9154a8a6f18cad7827610e2b43f3b4b0f566ff32d836b8b3939068087e2a3d338a97713099940f5cc87d6afe3a111c2f8a9026a60a274e948855e658ded2be33354cb3c86828c143466a2c3e364151d0394fa741f1651bdd8a0e52126e0669e5167bc3d07e1c471feb908d26aa4fa3b5852ff3a225bc66ea585e8ff7f8a9772ca6586251b782759e4701c315e68403e8146227300d4b5dcf8f7580f7b4e9b72ebfa7f27b66bce971561f26a686afcb78da9e49b49dcc1ea105d498c76c93f2adb470237ba6ad9e5e1fd5dd9010b1b67f5ffee7dac0f8a0ed646c85a1b4b6333e912ac46216bd176c06ba5ae733fe3789dee143cd98912f833c7f92df67ee843130cf5dc2bf8d831179592c8d8d2d6c16169965ac4e73238da52bfe63cd8dedb02de2678cf0e7d47a7395edbf5759f8c9165a53cb3e9ca0e793fc3e4327274ee5c4c3bc929f54a67f9fbbca1c1f2a2b74419f4265399decce26651cfeaef330b3ccf8e5d13d7e10d4ecded2f66bcf7b04e530f64d6c7d0817c895d17c49a6da76ee1c635bd157e561c1b757bed4222e67d91897d9dde918c0330adfa6b12ae28035d1f9570e40fdbd04daca7e29456cff0cb0b711778b87521ac9724fd1864432e107adb4075fdd7b7730529c0035b78c6bd97f42f92dec8bf2fb2d4a26d5d7c07d1a0c1fdcd7d3069bec42d1131f0f9ea338ae7c222eb20ab495f7daf4ef06b0d9bcf3ef5df560a7faf787a9af6dbfdb56dd57faeff6070003001e613b5a2d71f19b0984a4a8b0668220af1397626ae1df848d2cd8d06e2ead6a896229fd09971fe513dffb4e3f68437e5b613bfec0ac104694a57d2e3bd5deb79eb4bf0f0c62872570acecfa8c880d523b7e03ca189db2777663789a67e3d2e61447d8027beb282a1526b745b954c03769c60445ea3fe85775d7bda125eddc638186fd573b9667990eef9d7bdf001a79d77910bbdc57c71f08f653e9bcb1237ccb321d26f1c6b293ddc11fa456eec797ec53237f30e251cbeb4535c9e1a6fac8c5c5451951bea3c25e5f0629633dfbb6f3260fd20629673db09db79dc67c4e07e6b1dfca77433099945626b9c1dad82fad74bdd169c3415966b96959ae4c4c10c74e54baec127b1cb517390b725c7406d04dd2a525361adb49cb7412026b354483e3df37fc7befd57dea3e98f48337928c7b42ab45da2f7de377d040857dc7d5b9f1266f81b25227ab4dcd704fed442a672c93d271101bbfd7264bd9645e542ffd0b8a3c61e11d5f7ebe5b26e3ab4c2b75da0dd3b8343a1047f69179c1fad31666fd7461b02db0f52cd21a3ed5ed07b0a3bc1bac73569481c38b5298b6cac2cc5816afb2701564a175c15576df9067574f4ae0d36e1e02fb64926eca9ad384b5241fc25cba2bae54b43dd2ca6639cafd1f866c680cb0414b46490cd6efbdfd6080548efc6524e71ba456a7f8ac1a41073752da15081b632d69e5cc80510a2561fae78bcb1b9b94b1fc31897538aefcbd772986d1be7719abefe6b58a61642f7d69a9c6f0d6a891975bc5e0c3fb5e76e27d1f3a9ba0f28093c662ec6e111da5976b89b31ef7f87fc1f7586133fc3fbf4e6e95ead4fc5a476b5fd55ca522a7a695ae3bba3652aaa36baed25d5d1b2ad56ed0ff7bb7162a356ad2ff270f796e90c7479edb9aa75caf45158d6b91a3d4daa94d1da552a75bf3f4c3cced51524a958f0a5deba847855647f49f9aeb2935acf5951aea9aa7f44ad77ca55a14f8d415e521f4adbfe8db10c57b371243a98d9aafbc6babbc5f6ba9e6e00e593c146a52673bb768b92fd5844a85bad652aaf5806a5af4dfbfa7ff6ebbe629d5420d2ed5e95db8287b4fff3bc35a5ba936cab6bbb567e5d51d0c76aa319e2754f74ca33a46affc371e8aa7dc87aa976db48d363a37ffd2335fa97607bdc1bcf51ed03f8af67eeeb07b4d43567deae9dd1dfdfd68d4968e5273cd6d454e2d77943a453ba683ae526f54e9d4c17fffc1ce9a3b13aa8727dd4706b7218be12bd51fedf58ffedfa2dfe865537a594537a4af1cd3527a7587d6a8dfe3264d647fea506a0ffba370905a6d9877fee62d873e0d0be4efd3aebed04d2c8fcb31d4ef14a92d54a43f9db553f3d44b170d2157c0fb90db5154a4870ddbe22992965da5da99831e69bb071f8ee4a5f53db33b72ee20ee13856e25df85432bd3d9e12bf0104767ac5738f735ad54800ddeead7fab4bbd0c92eea6c502d9fa8d2ef63ef54539250b4f613ea65838e9eab5488ddd8aea3bd1ec7b5561a5fb5b672eb5ae2125d7b566a84213f2fcbb891d273cddd6c7f3992c5532ae08c1c96ebdcae728e947be1a29b98ddce9a533e1d5aeb376ea0f782b8e75a5be909624609b275da3c34ad149ff7da50b9fb138ef9cbaa89fed24bc91a2afdc08793fede635c01b5fa82b3d29a7322badee6d10fb1544e01108339d04f98a38e573630e922e29cc771817dd2cf79a2d0355d77e433e6b21bcebac58ecb9c1df78f3aa11f3ac8d10540ede17fedc851faaecbc756c6d8a3ffdc59af9cae9426d79bb934aeb5c32066e6e0249d1b18cceb72ca0009e04a4093a7f45913f3d8900ddb567ad030a368d57e3b3a761f97883150dac566a1a49b17ec456a33c4499a0854bff806d6cfbfc1f52f0ba4a394efee817464c45222fb09b2f7b7ba02e1bcf1b9b635ed24d559d224ebc76bfd07102a3b2dc1be3bd60bde5f319d4629ac3a3838746aa98a8503203fd77b507ea4deaf9dda52d722472b45407fe9f2dec198bdd8a51b32ac05ca4d1cb9855cf5db5394e7ccbb2da74d1b3047073fe146d0c67d6da4fa2bac58ff5c5790ef4d005240373646b964505ed7ab8635e8732e5ae7616fa8acb77211c79bf886622654628ad333c0a63a6dd4525496fc4b659173d6402416f099ee7f3d07448830e0475a52ef0959b019fb74efe80935b57180223ca2c5a9fb972d7a9fdc7d0606f754db8b3d1938438b466d81daeaff565bc2b53170f605c469eea3afd4788b3dffb8c30f5da8fa11bbedab71b86dd71cb3c27c0c8115d51d2ee7738b4dc14c28e6b381fb47d1b5bce53d86bc3257ae60458ce83018a73c73f70f3bfaa351e6f592866c2cd7ec294f6ec7f29c5c3650ea372375c833429b1e52f4e49cafe20b7493f329f792b0aae73975e5c13f6d58a56a63a5279c0903183de3ff4b6da8bcf7a19d3128337a000b8c04d02a784f37d504606647733e8a0b73e797fbffd340168fd63cfb4336d5a3a0edd6da6aedccdd6a56a60e25fb198de426907dcf984a5be96643fefb6ae568023e37680ef5ebd8d1b4d316b8bae9e3d9fe182ac5c02771746d6c97197dafa0c51fa19d4247a2fa6ad91f53c76ea96f57d1ffa10a5ff5dedfcb917c386f187f88d999390c453ce46c2b35e1f1478e54a581f59488778faf609e37bd7518468eaff9bc64bc071758cbf63d3ac0350d1302d1fa0bc7f01988a7aab594db3d052a3a6650c7ebe7e680bf1ecda8fe7280b7b6d1e91181c8991320664637a0be673cb0fd88eb1c3bacdda686f53d2ef4f60d41007d0f28d77ea22aef818cb607348ffa1e7852fb8180a6be03a6debea3d50b5ad5ff673af0fd331a73d7e71970774e6da87413bd0b0874e990a669ebf0e05fa83f1bccdcb58343d07ea7d50e3e5ddafa0d4095d849b95f3ddaf6c0c71327f3b0a57310271f4e517e0a7cf2942ff72990d69beecab1966c4415b6338612768ac7cb8eb1878f82cdd2bac60cf280410e535ac15e4cc5bb7c1e0845d48ae162a7572dbef2b105bd33c7de12ca1b563bd78bf5235d708d2e8a37948f553ee33b7b4d4de9c1f73877c65b664730c7279ae346a1a79f982c9f3114ea9d7efacdb3bd458adbe24de22a777273089673c6a30b8ff610907482ba0c8e09b4adb9f26b90062d17b7ee93c024ceeb8254a15327b8a6ab7c21343c95360055fd1daa593a75be284e1a988e25b5e7ce2c783c32646bb5107514f54e794b507a849379ecc82df3cc574bcba32b52c7ce2df2fbd2c28da42d1ce5d6a57d53822659c77c94bc16c67b2b09be725fcef632b738338e8f67d18e2dd08e2f177b99db9c19bbc7eb20f3bd2450e6cbbdcc8f4431c40e8e9c3700d81f4a425fb973e752dbb93b74be6387c9dc1ef0b9ae24b4953bb9deab9a88001d3b0364ee03fd7e90841eeda8e3bddc7deec823720fd19141cdd054eedc99b9766eacb78e9d88efe13930d07693777daaf9eafedc6b60c80d30b53f42038f92d0575eec80a68e9c150e779f7104dccadff62def4b931588b037d340c11b77828e50571af77ccfdf72f64fcaeead1cde8f1ef630ee42a2353bc2aef19eb0f19e291190dcfb742c94019bf30557c7e89849e62b8f31bb6b0fc7246d96bc06ffd3dc526da5de22a6ebea3867c189637d795a406a4be96de38ccfdb950bc87cedfea1dad615ad810f9a3173805312a6ed55b7ec162db64f5d40d9638ff665e29c7b92c753fe99536114369b000863785bdd815d9ffeaf71276d995af2dfe894795b3ec1e3832a1838d032ba4deeae41f47c814719dfe12d17d08e906dbf6e75a78dba9ee49e052e038c6cee60540476db84dddee60edf1b40c7d60ea33234857aa6f982c6aeef77689b806af62d4472ac0ff1a78476afe76fa917378a61649b89a71628771f1bb293f8d87d297adb59f9743433bdc667f086ec6364bfb3b2f7f7b25fea9d6f06e3be60b35ff87f86d244926fb010214e5aa7f00102b8cdce277de9444b9607b9f825635ba9de9467b663b2d37e689c13c0f31e64dda93754b99738152904368d9ee290177ace53b2f06abf1da5970ea89337205abf1d057ed60d553d6f78f2417351db384a9d307279acabba870ca48ba605f64fb0d90945a08b0fd736623ab591f2e9a2be9962275e388c05b77386fff785673e977cc5b480af78ca3d6616dda8a6f9883715783f2e2e613edb94ad99dd1eceff8f34b7fb490369a814d941fce44cb3cd9df8b624c09967ecc6fa800c6f0c7edff080685956d2664be91b6e8d39780b1cc0cee50db7d162068ea42bef836972420f2ef46fce64badce64e29da66ee4a1030ab63eecaf9e0eb4ea00da6dc9d7465b9d12023d5d74d1b1d896ef175ec3308f2858a68c9f0dacc9af151490760b3a3f475b37bb8a07526be668d3dae41a0f4a793d349f6ba355fe5aebfa0152d5c5ea290fa9838fbc40ae3919ed22dd912de3f6e896159c0bd66b4397041d6cd0c47d253face24f84c28752ead4647c780f833c7a6ada737343d7903acdfba4e5aff4c5ce78ed0ea11d62dd0028ba85e6c9654f3ed39d3315f682db34795bf44fb19df8e05c8d51e2e597dc7f8e0886fc8e01304ebca615ca97fc4b15c6228915374e099b3660d6ecd5f340c8da85f1805e9dc59099dbc61aaf2953e767ecac2d7be548c3d9439551ce8f6fdc6aac421211c55a2af7c6164013bede53c565ed911c3c77121639d350e66c0278ae9db0cb40923dc6fff5257535c8ea4a5bc8471dbd8e2419ca09ece05160ca70dac1aad040938bd655602a5178db953772d90a9ae703faf74bcb7353f08309c373e9d0e60d2354b5faec0ebdffb72c1841fce84db053c198be859ac9837c38ac1e106cba5c908dfe888f1b1fa0d938e7b7c983acedebce4ba782a6d32167fced01a50a23a0b7c7df25dfd6511c5cf38de2d303f3246b27b8015c1adfc071fbc65b0b31e90920053fce556584068a8813da6984bb30550d503ac199aff8cf9a5a0b1336ad5dbb2686473c785505d9df9fe90e0a9152d4d537d608540bff9056fb60c60adb774b1db124cf168c9e73501ccd83aa9cbb8250611ce682bb8170e5736659464e1f0be4e089ab484eb861cde533561014dec7c0fb4b1240272b13386e0a3476c5482a3631b2ded332baec74b39b618c9b21ac01deb0d0b2979e789605ed618830ad1eb21e44aee196dfac668876b6a881938e1713098f7f846d22b2d7becbc817a717a2e4a169a6fee52e07de34fbf36526a74e21b1a91892eaf60c90760dcd2a9adef08cca3eb1ba7f65b1331a1cbf57163fe8044aa7df6fd3ae858385d1f9371694d0618f93ac05e7a0316d095833f5222ecbbb8e3534c33e1cd1c1c14d5e41d04b2a1eff3fdc129379cc23081a767a4f4351fa2097a11f1e5727977c02457cfd376057514ff6d2b2f01634aab5bae1ad33aa25a2fe4fae41efebe036a7f033ccbfd5313479439d2758b3b1ccc7859eee526e9803c25d27eea1092d515d9a0a0b39f8ca6728ea31b3ad533fdc0537ec95b8411107cfaeaccb9c69d77ee28668ad1ac9ceb39333a69a21e12074cfbded6396108b0652c76c7dc8f094d304394d6c55d8593316b3e474fda45db126e2305189afed44772def9b6ff22ca5b9f39bbb6f9a49df7431eb7d0551e5f4dc647d4c7f198bbc8916f853e693382f5acf4dd19279ddf620d30df90273b17fb0982178d2f0e05b380d491738176df7ee3a75f81f0cb76ed0021b506ba727e632cc363c64c4e75d54fd5de1baed7616638e25a67d851c38d5fe570b7cc40478da313ad6b9a0ee325b6fadcb5d6d7c356f0d5fd8a2941da11b40dfbb5b1ea5f5bd257b36f2aa8abfcd835e3711f586a0de6c8b9336f818ee6cb56044d473ef8f83170cb2135e69fd1c168a82bd49c3b1f40880922ea3327be6722d9e3a3810c39536e31ddc87aab992ce58376e26369260c4c4011eb63cdbcbbbd9a636d6a7695376021bf05c097c2602078386710144186597df4fef811fc31e5993f988a983af6d7f08f1f21dd22e6a36da78cec948faabaa5533b71543be1afe7dae656b92f9ac1be75d91349b96240f961f14262cdfb21418e7ec2fb70c35092c9496c75be5b6286c6ac06b1e00671ab84c83a067bf3ab21d421e8f92d37567785362748c5fcb6d1ae65daf4941f3b4b6df5a4c32857e79385c22c4defdcd4faea86a9313f2758df7ba0dc0f574e1dc068e60cf9b4b64440ef333d5b5b6b703f682491b9574a8d1adf625cce6f8495e4095a54851de5cf99128082c9f34547448225e5ed9eb7b9b91d68e55a4f79a21193f3f4d282bc590b3267b1b3c7380272ae70c03d3ee7b8ebfa939aaf1e3e047b02dce8caca68a534e46c834b9ca7fe14e8e6402e441a6e71cb67e5961131d602e001ac18ab9d1305e99d39c7dfc4d51103a0ebbb9278d67527022dd8613cbd3d675085ee1a76d495eccbd81addb1c3b1e3395317e85b5cf60d326adcd0bd13ec947943360013da2d26a2e94bd017fd25a4429f49fecec6ceef737eaaac0d9843fd4ad1f4c65971bfe2b29c87dbbeadd460ebf20183786394639e7a3310212b3d6d98917b7bc501e9b8d9e39b6a0c270de18e832056236d519d988b911069a24de28930bc4a93dc3d55a2187cf3c977cb4801ed6f571debd865843264b60584937485100252088b86a9867917d0f5a843e08e25ef2e43ca9641f0782ba09344be7985ae4be5a8172a2bad925d619a916bf2f3aeaa5ff5091dfb72b6df8a77842532e4b89ed27506f476a6dedf64ea1be60a6f32c9e9d7e9f60296de61e8e067bcc4539e6002405b6789f5007e3dbcc375e3b43886e86d28a38c6e198c4d1d4ea09e43396d74cf09638eef81a8b1e2038eefefc5bb893e918acc10fbb5a1fa828ce4443fa9b23206c249db3acb09467fa669954e452e3777ea8cb5b0382d649592f6551b3a030b4252080c454d73f0dbcabd76976d6ea7549bd96b678e76aed1ce95ee085a645709b52a53093849df2a99a19279832a891a9d251f8c4bc19d3b2a8c75d3ae37657919faab678c5354bda605aabe04b09a3ddb064fc55791ebe32a99bb8a4156c007abf6cc04557bcbc70d93fcfcc9d56d9aa26f56e2781737a5524a506a9168c560a6fdd96519024fca8aaf54a7e0ca2ac63de5c9bb92d8a509531bf4c9df9615f8aa255c2a669fb632a6f3338bafcf37b79fdd10d2d0fd60c4f9580e77a76490f8f5269fb7b6012f1fcc33020deb5df2ec9f337b725536530d217176ae69e959a93158736d166f3ed1a006a9e6eb7d81be8e98f7e233a7ecd46115ad0b8eccd1dc1450e2bd60b8b36e4081cc6526d9df0ec1e30e82cc704ddd3d8802680de7fe41d2507917cde27fd384af3e1a324d1180da33eba20d657bd0d2153c2be7e015f52f98b19ab72a8aac734d492e21995fce73448078e73cf0cd4f73ffe5743dc411c8d93a0faa84b7270eb66083d553fbac91c6fda0ea0714fb06e0b770deecabc4a0cf0cba21d419995b7de55cb8f52eb3bdb5cd138654f2fe7b9c915a9f7621eae58be393ae187d2becbc038401ca7badfb4a4de88ca78ae3072ced4005acd884cabc770383c399c3e47468f8f47b774b5b2873a131e46ed975f96a6829afee30751232b556dd7bd49fe31b4bd0bd6dd8f4f702ba85cfc77c16370da2e08ff5117355b8733fd595fc54d792a9b059afaaab55d71fccb8340a8e7e515e3f3d865efe977dfdf45e5882f05cc2d49e75fdccedeb876f0666ee152d4b519791824d5b5456a0a3e9268cee5b77ca1f4beeda9814a8ec79d7ced0baa7b0382584dc03f44ca1c56d5ace45bbf3e5ee41e996f2e2f2a640556da9a57f50d53784f08c99512c85ed9df9420fd03836b7e8e92508d1cee2d6101c423ff4957b8c86068b16588660267fb5e93cedda2330dddc7766524c9d884fd2168a4ce18cf65f5b90f8ab7ba1b7a69a95a03ca2336b9ba6529b66a9d9385cdd20e5d4a92d1a4a2d1a8d32e5b329824bb01599d49aa3d73d8cb1ceed24cc66598241e37f325f88f14c16d10f5936c29286d6458ff75faf16d0d9f3d58dbab4a22075d12b47e2ae7a95fa86de3ad71c7bd433d72ef26e1f0e4f76a942ac63e79cc90216750ecb2dd19eb960de387dbbca0555e6410f01b15dac1553802c51db413f52178d8bbd1e46cea75d70dac38ebbfc56d0df821cf563281a87b4239e200c0b6b2dd5785fb0eec6276063efae5285311d5c3ab7dc6da9b9adbc014aaa3f15940e2e987d5898822de5bda175301bdc67aae4e5af9a6f431997da6cfc559bcd6bb4e91142e2bda09dbfe92c41a27f69666f4e9ac7a69996faad853a617ed5256fca2fd792faaee9e0b1b543ebdaad10159735803f443dc383a804b42ca0836644082779cac2cc19b030bee0983bd8061a0f0db3d63138fe77470c09e4b6bf07f0cd19907f41242ed7043274a064da54576cfa70796ba9032cdd0a2511e5ca67a651089fa1b88c49df86b4f537a804a30eccb55833edddb8762b09d4118040b0bd65a4f010bdcc819bf5670f387727b86edebfa1952225d6b1a37ec0296b7dd51399ce1227e9c4f98244c8a93b270d5e873a477c31e2790a19dc5dc5901f267c8beaaa97c2e96039489f25162e9420bd2dcb6558960520d1b849d167504595a044fe52ac9b01aeb7e2fe3788532a11cffe15e24c51fab9601ee9bcf113a86929fda93f580ef3b997f100b4b4e886cd91f179fb2f19e39f337e6bba03b6e78de2e9786629a3a894b342b45b45cd5814f1acaba897e3ef10d9cc8f9e99f1cf980e3a05f6f7cc7ad314e92bfda5a33edf377b79580e4c913e64463f6275764b0b6e29deab4524bf711fd48566807dfac0970fe49b2c3503feb7e1cc67ac81c0349b2fd399b8d71c7dfe20f7d1c5435599be76cef8f3f78311b9fa2cae2a6be7ae8cea3fd5be35b55f3d88368b51182f8bf37c1000f956dc8bf9f68e70349f593fd84b58017161ce49155eb04ee0ef3ef4d6756511f27c5beba8477f50deab6c7dd562245b8c9cd03136994b458240fdf8bbe6f44a6f5b0c66583be7041ad67a5267a5e65368763faf604998fdb1c9bf1ddcb1837109643b6702276b5857439f6f06da47df872ddc1b2d762419cbe132efcf6a2b77b591720bcd7c7b161730824d93a427dfc7c35ab1275dc46dfb9511ca6f94986b91dcca745d69e84e4f4407fc88ad11b6446b7adb1fa6eb8fd5dfd79e95f725ec8b5ea5bac69cc4a9c35aaaed73639b64d44758b8ad78e119ea43f16d45f44233901b8fb0e8cf4699d1bb628b062ceef8c670c0dcb8e19a3c4643cf6544967542db8c53b7992f7e5f7525c6fef059a20523bb8188a30d5460955b9a8b26e813eef6f0deb4adb7ce1f471a8247f5e40309a121b96fcc18cca8778d7716cd0f191906ab3d65c1bcbe1673afc215beaa4f71cbfdfc5035e43a42bd9fbd85cd6365d78f65468f102aadf40d6b0fb4597be01e6a5d20b2fdc49ac251cc1b66e355b3063999eb8366efd3fc3407d8e3c11bcf84a87c0b6a612ffdb566aae6c2606410e731ce113123c62bafd096393ce3998b79ec9a71bbddb6ac02ebb77baa3167d5e7e1b1dd36747443bb032be90096e439bbf9b1a3bed2677a78d0c21f736358ed9f1af795fb6916cd4ed293b55bee22af8bc5c001832ea4beff2c17c6238cb0c4499f85d6b49bbe609032b2e7ff8733b7d5385291f36e6761a8b7373f8c225e57fc7cd563ba2c109aaee6aaf4f6ba6189789807960c458e0ee128b3b0af997fc4e20b4629d36165aa68d2f13f23b47a767b2982f19ff923f8072d56f52f9946cacf0e59e23ae3631560abd75acadf1ef2c8b5a80e4f1dce030d648b6dd17e61985fb12dda16dbe2d8316c8b7fcbea1e3b578e4c68c57030323d8bf5b0127e011bb9c4f8127e41e66ef86c6e9980b837060eca43fbb20dc003cf75a6a3dbda81c404ed75947be9c874b6cc6a1c3282e63f3182a63e7325063f3295fe670caac8af8d951a5fdb75cd1bff3b06d502a6ddfd63bbae8bb25fd5f05d91e4d41df563d2986e13b387da8c40190163b987cc8e09a8e931cb19cda6128d0afdb9bfa9a0e9616202de2efef53f70c7fe26a6fdafecaeb5e13accbd3d4659c7f0a6ec929f7b2cb69ea8a6c62899592cb6e1b792db3d165b0fcb9a50396fa647f6966f95cab82577ec1f76fb8a15b076377ca97146e18edda3914b10103f72c7e6e0503d9d8081a218deb136ad0f0ad61dacbab53de698430851e4cc6863f9f346dafe76587d66a58840e91f7a7edda8ce2991bc73b73a970bd13cf2af40bf6e9cda6943a9d3c675c952eb7d358fd0a7df4eed0aaa99c7655a7bee4e5de1c4ade1b063e6966917c2dc470671a810cc3047cc8bbbfe775e1c9b8e129507e3a53d6edc6e580b991b77abbe8655948ad8998223912743a83bc23e509f39758e3d1d56ec3877e5ac1e6b87249921d4f4fc8fc431fafff1c048f52343e0be5dfd822aae386cbf070058ac8bfa336b4e7a9b3a895df06a801d76f6bd60bd614f870a63bbd8d1004b70f1add82147afffb71c3d6e65ea5cb3c0be62cce97b8b31d7fb975a64901fb495a07cfcd78c41995720d6364bb125a68a7fc919b4865172065ffec8b2b3bbdb860cf11f397cfb7dbc67165f27389ca4d6bff4f1a055f0c9ffa193fb43dafe2ffbf8efdc4ebb645bb5aeff65eefe67dddadf18f7735d4edd4753d4758195aab593dc80aff6e9a4806ae7ce8a232e9c8f1b66c565f4fbe188ba5d7e5371de58bde2ff94f506e38e92ac83326da3702a75629fb958ffc49973ffc499e3bfbe72dfff27b0e70450ac337ffc19dae84be7889598e2c79fc18a9eeb29eb9a268f3f43107de6301e374c446a0076c8bb988e0a7f30ea33e38d630d3370d167de9be41586de54f26ef7624d0d5f7bb1a8a107bb8e5b3678198ace36f0df779efcff0aefcfac807effafb0fef4a7fe7bc6dec7a3dc635057bbf93bce5e66786ff9a35c78c563559b9ee98c3fd78f72f37d5ac9eeb523c99bc7da07fbde822cfae6ef187f75d3f8eeb176e2c06d0c3835377fc5f8d3b3a6143f79b4f9865f5671362b1816edefc55b33e61bfe6ef311a732673c9af347461245a5edb7336319cb1ce8cef03773c23e1859750a60dfa1e8f6ed29750961b9ddd32a8f6fd8bedeb5daea5fc8d97a1486465b4d9dad5b713442562c176cf5dab131e47e2d545f3a76be5ab53f929746372bfe271a9432a538afb15efd43651ec17e1a9f6f0bfccf1fd926bead3a674ed6fa919ee239691b458814dc92dec5a3e8d6133970ca4e5bce5af68480486b7c4aa53d66925895d6ff579512c5d06066aa498a46657b735dffab4154c3a74d33bffb43f7b77fd9fdbfa98e00d21f3bde9feb021b95c102659ea8bd6f7fc27e334a1e8377a076e7132d613310963e636e89ffcf71fbdc83bf89f92333e22f13dc2a81a6f089d57c4625a9d77f64946ff86f795cf1c5b6a74cd1566747cea0e6a9f323c7a8fdfda3aa85e847543ef752f69776d6a9950a173a61db8ceb2307ca7b470ebcaaa827e841287633028f116ea1bf6ebef7e99b3a60d5ea359fefce07bc84f532e63e32c5b963a5d2eb01f320444376dd853e3ef80eeea7b3a705f237a3c456ca8e31948f63674fb544af9cb5b347a216acbac4636391cdf89f5b102f5c1b8ca43d63ab928b8a53fae5c06aa5ce3d38d9eb01188a7ec5614aef58631820bb4e64d73f94e0cc89feeafffb08feac2943e4238f60c76b31ff3682c2b91a71f66f49751edc7c0a35cf68aaff61701f32388099f954f7ffa9c407fbba613ce4af4ae4321d677f311dff8d05ddf29837ff38e6bd05ddf208fe58228505dea7bebcf9ff65d1ae7900577fbf68d73c803f96f8be68ff5622a7219f3a9f34989d03538a2f4781031e80d251239e064fb9739ddfb0cc472b0dbf03f353cd7e996247f4bca78ed28ff27fc9ff71e787705488e8d48ace1dc4f799e9785ed74ff5562d54abbadea0dead730a0643a7f60c7341b140282d07832a36c45fe4a55abb9a91b9df8e3a3ad1ddf8aef6ac2ebff487530bd5d597ce9c975a4f6dbf34ac87765f7aee1cddd5d60e454d756d485133ad6b814abe748ebe148eac600f861a2dde1c7a503c33154343bf5bb3c92775ecee98fdb8d0fd7d371d56f1976ca35b1b2a7d7725ee4528cfb1c4f728bfc7f194e7daca7f24f99f95be9b8918b5aff41d1f2c8a5feff45dcc2e3270b53fdcc3af640f262c3beaf7f5d449c59bd61da3b02edc4f0a367b3575ee977c6851c123742202368d7b20d22e84cb86f7ab466dac12fd1b4a416b7de994c64bb4be9eb0ccbccca9a42a5367fb64e9d9b2510b9346cb5b508d113b662d25079d15ede92be793f97e3be8218d92ae58595437e8b3b86bf285fc52bd59974d2129eae9f3869171dcd143be0335842e4c819fe0b03e1fb39718b8b970bfd04bc80fc6195abc74a00dae964e538641f84201cb43b6c2583c9bb63dd516912397499d0b5816b77e3f098a0e229b76cf87735beba895e313aee5fa0f965fd4e708d8dc1dcfed3515f51e8f300bc171599faf5a5f4ecc82ab8446e231cbe32df20fdd83b8977acf3d08dded051be9d44eb56a65faf4b19a036f6b5cc31044fc62905c18b3734fa4184f969fe6b98c8b2da38fb077c3257853502a6ea84b069953a09b9d3a7c8bc221c7dc9976abd9d30f0dc176d68ed20fb5d38ef21f18433eef54d954fb14fe2bd8a3cf2956e4d399b3b07fd187733f4c3f10fd997ee15be9c1a48f957edf76ed6aed34356ec0f59bae69e5969285c6a4004fa47f85633dfa2a4b846a040df06e0b4b147e9629041e3e9dc3d83106e82bb7ae7f481a1f33d547f39ae9258bb6c03dbe6719480fdc1c2208065db61909198a7472220f4e1d48a526eac99a2f9c2ddf481a2a2718506275e3c61ab44138ef824dc12618f44553fd1b478a25329958b330e809e68046ee963bc9827522df47aa73ec9c3ff0a929ba10d4dbcbecbfd7c6aad1d95f79d84dbfb3070136bbc1ce37271ee6b6f0ec7deb9f31fc6720f21b24fb88212c7dd146bf7a60c2f6ecc90237769a377790a659a108fb9f4d4c5b2b56e167cb81764d2bef1d7b980d7ecbf57f12457b14a724f7e94c3441d8d40f1576d4b60507abb9931298f062c778c4a91c6b52a133ecae1edb246f9d63885f60badbe0de9fb255c3f68581251d5b077a6abb173e626cff3bf519e8b2d3bf33783af28f7a4c21b409065df408e5793ce1620c162707858c8f9cc4f98d8fd6b55f6aca4078f8e5fc16ef491eab04b98fa8aebe7748e662f37c5349c773f06abd8c650d049c444097353187e0263038121fd7758c788861aa161f96f1096b3f88531c585e34ca195bc137c42d0ecaedc50b7e185253f5cb5b750e83ebe09356a423e06e03281e6e6de784ac832ef23576227e4417e4ce79ac75d4a7e3d7719be6b848e7ac69613c11b6982780a3eba38ad506bb22dd68dc922c145a6d74e170ec9a0aae36fa9376c4c7462b496f70f262afd0a714dae80dab546c697e8b8d5e51f67ca37f63df641b7d01d14883ebd47f57278d875d3abd48da31a111e9464f61d2053f9dc94683e9bfdce8c82b63e38d4e28cf62a377b0004d3007f38d9e53a69bee7e47343739ddeb48261dc965460a9991c6ff49a136278fec32332913c1cbea46cfa9ecc746dfe1e0edade7ceb03321e1bbdc6840a1df1b7d8506ce36faba4108ad0ced82e7f86aa3f5bd5dcdc92364d7ece06b928113c14a20752e717e58e2f41132eb059728987761da706b9e3ada88b7d16aebf5c517ba77068730a2ca768e63d5ff1c5570c75b8f6aa56b7976c9bf1de17656f02787185d45dcae2975ea3c55085ee45cf719d1328c5e486101c016ceb255dd3711cb34eafa0b6019f829bb56f237b6c7bea79a06fee21361b21bc21e0a40f4c4390659224d2d806d8f58f8fb04808298f6ef27b8c2c2a0fc04719d744057820270c65dd1dfde88ba3d4bb5fb1e105dfeefd7c6ca9dbbc88d5bae7f7183e4734e6fc1fb0473dbdab5911acf1a802991f335e07967c0ca46d03b879dab8a65340c902fbf186ffafda5779083af9c632bf9fa8bc9cddd99865ff32387f544c4f4fc6450ade1f08bd566f695022156aa123c36857e2654e685f5bfea83aa8bfa2e0214fd6017847cb1b71887450cbfdf00ba61ae1386eb4244c8dff63dfbad1841338bbd14baac907c3da806569cd3c2782a3f27d8c5aa7927404cc5389876f00c77d5992b8e1c4f3cabca52e547670e8b93863b3b5df47e7ca55982cd933ee45b0beaf96a413bc34d80bcde3017bd7d699ebba0ebf5831dd3673e0baa788cd73fe458c185a92cca07f3e32f6eec41adfc9a514a732ff50f5384abd267ac83a728bee0295a5ce88d66fdde5edc86af9ac64f33c2ce6181fef6e67451bb312f1a6f6c778b4e36d9c461b82e23e1508ba648520ea6086f8250355ca080dfa4c151dfaea56005d71d20c0cbefbd48549d077b5170dbb10ba4055ff985c3624528287a93caf59a58ceb3c622bb6e1b5edfd42c55c5e34ecde63a9df0d304188b7ee703c7ee39bbd7a3bd9ca77d913c8342d162fa7176c308ebc9cd9f0f95a7f4b621fb808fe96f4d38e9d56f1db21794d6d91dcc171cb170fd1812a408982f50dcd446ead8fb72a63e018bdc2968f1fd067b6c53a640a0b4b8557e8657833eab70738bd90993611f277aa9a7d46676a213ba9dd7275a1ff7ed5633a006a308584aca3e259df9c064192bbd6a144f7b73b3eb8be01ccec91a97ccff6245f131eb2cf1f55155f3ac745d67d6fe3d3b815ed5e9890eb1ecad5d8bdada3ad9602fd3ed5ea613cad42b9ccba0f683510303a699b3b660a4f20ab0afc740b2bef4b7348f35c2691d8fb5b51d9fb1977df612d83994d33efe7b3df99f7ae3194b877bc547ca54ddfa21abf8bf5fed55735187c5eeefba66c969b1772d5cd4f53da77efc632acb3dcf0e53a9bddf75fd28d1eb210b88602af869ade0fc148b139dea90f641d90a3b166a8b47dd949d2833bc9b3ad0a97f9e593af5c06875e16e9e1819980dec72ab8175e77b27605a8d676d3b7231aaf5951fe380bc6fb983f7743574f7b22d47209dbf8676643a12af9af5aa9c77d6689b918f94eeda63bee6315f9dc295ba1f9b31ffbe617e4a0d86f2957313f80515dbacf8ee209666e90a176be2cef7a1cfdc728d7fd488d956f67cc4c0a7b6bc2ded55a74eed0a2655c264db38ca7d14c7085ae92796c78425bf642e4a7d50c45c3a0404ad1c8bc31ca1989b5e4b24dc69854abff12736c698f54b74dd2e382e6b4691be72dff6aa35a978dbc6b472e958d50e95fff26d2002bcd7702ebe17955b516892c6f266f9e108e8aec727a168f0b83473ac88d48ae81b9ef593f584cfb3d2034ba2dd571ef3981768dc2b2c7ee678fe58f34a0b18c1767774117b37966ff5e72a6c26ec1cb9ffc95a3503666b9cb3c934333b222700fe8add3002153c7e96180f2fea0049e8f1f5a8d9676b533172516ead4c1bc567f7cb61936cbfea9ff2d952311e5baedc38c5fb1ab3cc01cd7c40d3a89f8d6bc63d8b77c4de4232d60a351a00fad881a98c0aee0f4a101e818f238769c0bbc30c10977b0fb5eaed8753ea8aab6acfaaa1588db2735c6aaf7b05bb275888875e281d68f30e4abdfd6dacaca29afcdb58731e6bf1af63758f9d059091715c253043e4bc7b5087bed487833bb706971d0ece17f7ebe04f084373e2e225819f0bfce36cf827cc581b1d0cc34f1cd496340f6a6bc6cec7534d48a976e230a7b3c326dd4c348e79ef63b8e2bc8c30e30666ecc4f97aacf5942beae765cd2e8c987db318c3dac99d5a386c0772cebccfbd1708d8468575de737cf459d90c745cfdbe66fce4e294e0ded65d7e7e8af23d94b7b90bee74eeb0cfb8531434222cd16ad1b7da68c9eb3bd6e00219f45ffbdb529133a8c0c6c2f91cd5ccfb685fee9173ca9c32e023c37d2f9a0688e8ba4b3f1b57d559db99c573bd13d0ba6b675bc1934bfda585bf69f037b676ab3c255adf7dd164f2edef96bad217584fbf61c08c663bb953da0a67ee9a1fdb38752367db331befcc9d7c3c2076e1640f566c6e620b2b76e6ac393a753eade8b9b3e1e80ff1676072ef4ceeaf32baeeaebc13f6334f3d1c244eb593de639c859db3ea6164cb09db7c24ac9a9f8262c066993b2b8efbe8941b2d76328ecb3b7c1a5aca5bb11f5bf15b5e6728bd609bf175958d2561470dbaf22ff503737cddea2208664f2241a6ad7c445bc1cd1d9894ab5327665778271350b52c659eb15ffb086f35b01aa8faf617aa717429ba5feed7d31fd00cda489a5de959871ec2870f7d3f7d012ff4faa18224a7f81f5c235b465df66e9585bdb68e60b3f7c26455e7bed6529f0e58f73b8751bd51e923166a49a815af752af061197a8d58931eb4307459ddae1182bbbcef58859f857afda38e0151facb593191f0c1a403c5bdd53aaab16608d4cac4ee0e3e1f4a6a72dccc090aa8a993f4abd1aa6f7f5bcadd36044a3232d95a8809a785dcb23b019a128251bac290ff4718a97bd638d37b0b170b8ed2516eac17fa00a24e1b6217ba792a412f349eaa01741810c662313a26147acbe99f4fdf332ca0f5b025f4c857db277b9d41d4cff6bdad5c6b63c4e489fd2b6b19786bf06f82821d44b3c3bf0eb8058d632766d8865a2d34c8cd9c25840e217bb3ec9cd17dad0be70895e1c946ff92452673809c3ebfd417b04e03df513ea345ac439937c5a9ad2f54acfbe9da5e6dc55d220b24af3b95bbc433877d28f6a6dc759186ad4380972f2679562c493972980aac3c66b6cc71ac75949fb93bcce39087dd491e2aed0e364fe9c4ecd7e71447feda5985cc8085a6f1d2dd9bf10b36019f3348cfdf98932433ca2bbe1da05b9bc141dd9e71f7f9bc0a6b3da567ee51c8dbe6a98af50a7d2efe795d068d397456d43cf8f3cadfec255d02f90f66dcc535bb6cd6074e1c512b20a1afdc4f514afb64d7af50a2d05be7a0c91fea6dc58db3fdc6eb9a65aa29ca42e956278d95b5a194e88bffe3c4a62ff0eda4657b3293366f8018cf1b53b89c654dea953e3813a00ff4d6c99daae83115f5d451de08f96ef95e2620e2d9033aa7a3e65eeacabcb3260f390adb60563912a93766fb451256aae1c7035985cfadebcf6e55be281a842dfd2e1a4fcc4d5fb1b778be63dac7ac85c9d7cf34603f00e5938c2f33c4748e5ee8676a84ee28da59be110da612eb4b054dabd62750f0fcd857e7b44fc06d226fa9c46f269256e18b6093eea2151635be97189edb353a262da506106b0d4a7f9bee2d041e109a5d381d8f013deb4b30cfb6efed4d450c4159d1386f186e48972ed2babb163bf86bd9351b80adf1b65feba9cbc6e37a54e2733d751b3bd16345162e5b422a4e599a387bb6f05b7e2348ac90990a7c67677c7d56690734f357ecfea657759cad1219be8d60cfa0867c5f77baec499b96e971ee52e62ba70ef4f8e99ced9c818e3ec6f20e422a962444eb660e3cc413fa32132f3fc7d08ce95a5d542d7ecac0749bb9dfe93346094acabbd027fc96313b0e8680d067c3f0ce8ee76ef6c4bc65ebb9ccc99ec8a705ff0dfa8edb0267b668b2dffd85865356a33db3809b68e063fc54895667eff8397f2f5d57ec903773a06a23b784778147a91e31bb0790e0d370493a4a6ff55adb3dabedbf03d556bef84a5f7987b78af0f1ace6e46eb976d0398838f43bab60cc59611917185824840ea85868a87400bf91ec046974edda1cb394e80a77a625b1ce0a683dab6d7e36a5ee4c270ced779a2fdb1820b2b72034b6f5e6f13e2fde782e96b0ba7fbe086a63981933971ebb286e1c643a0ecc73821de57e35cc744a2a3f81d4907716e8e4cb8b51acaf02d745055f0078d5424f58f71cef8f64ce1943849d6c06d60a8734557f39b03cd83990ddebd881cb48dd3d7ab6b0a16746a176ec113ffbf3e99397e7d874677f3fdaab6e0b15574ef6f4c74d6c1762bd29b8f8d72c687c8416c0b6cb20e2c4616fc622cb6407a143a655a70eab4794049e4fc4356da7972b825eaddbf37b03747ca541cbad2ae27be128ad8e1cf3d957add8c99f4ba8e52bddfeb712edd8116d96c50486341b67fb5c6babc43144fec190e15093af939aaf3ebad74efa200251ac143b10231a9790aa3d4fccad1898917fca0f4cade58ef3cdcbe617f69be662121f33531dbbcf39ed97009bae848ca111c0bcbbfd69b2ed113c01ef45b4d1216a3132c4de4831fb7aa5fb3ff41860549eb9dcb0272fd62b7317fc0a01b38adc0fe87475988de32ed9df64c269cb77fee237522331b798b3c6bfbb90ef58be97538799b234313cb3f262276ec9efd3e3cdf4def4fc6ebcfc7ee685b9e48561b369384a7767ce3f6d688090e6b75de1a94be7dab97ae61bf71a6a4eef3366694cf999cdfd2dd356de00028a13d12348e4f5969f5fd00510001b1ace8213d7bf1cd75cb574d5a9384cf554ea108a1d3b304e7a8aa11370c56aa090e9c813275012a2ee104e78090fbb0f6c1ade27387d113563ec97b573ea0a9717f26b361f3b9de201360d3275895bf64c9f4d1d3b51a53cafaa058b3777cbe8d407d6aff4c50a9b0b5c64f715dde6af6ec02e5f40afc5bcb55c7a5da57f8ba81940cf605c9f306bac519e2af1e53b17bff1179a2e904b47bcbcc07b9cff72c4e2d8cf819180ba0420d780706e477c61d3ff186f2ff453baa4f4a7c3ef27b9ab8175597717ac1255587882ee3227d1cdf6722e39e78a1fbbbca4f165cd071c073ee8bc08065d806be775f329215aae68ce9c13bca970cbd7b91f4d6ae5633770733cc7bb12fec7339d8dd1d7181a87f013b46c8a0f3f569ffd7afe6983b101c2dfbee4bced9d35f8c916730a4e1c7042f485535b3cd262d2e1c466d7f73f024b3076dc12baa876bf66c9c58cca796be55eb3fe22687835aa05ca9b3bf371ad22db29ee77571470cf9913567f620978ee29add8240f4c3c56bae1e7fd9e676ffbcfbb13dedf51ca67f3d82b3c191f7c306190bdf1c317fcd94ba68e705a614e899ded16ce5750eba8d6fb09d086f0e2ff622786a2847d8aae740ade1deb89a54eca71fcb2ad4f5bf5662d828a2386b4bd0b76f83b7558efb317f193d5b576f9b4c9505e76681196a3ca421da5f9dd928f3742ad9ff0860ad321ed7c5213c5273d3816a32e0b7fb4db2efd327f955d3a6685376fdd846c6df3b617bb690823ad55f6d0b4770c8563afb05e789f8239eef3ac400e6764616034f5f80900f3984ee9bc9883504db538c865d9a4f83dc7a33338ea0b475e6afa60aeb73c0f9a882874e3b29b1757e9993e0729335a49dac7a826ef28eb425f08d34748dd45b3b4a88975ca4cf142caf16b46bd2f1189adab6ace1a8cd06f4d0b62f50bff6432b79950e7cba1d533b195ff3494bbd8008392fa64e3f5baa42dec3436700bbfa4bde523bb578483b7fa3bdbc3bbb5beaaeb0123aa73a7c254194ac05f8bea8017a5a1c5bb162dd3332659c4a3362ffef00b937f0264fb9119582edec25091f3e1dacf9bcb0b19aeb9525aefd8a06874c9b5b10acd4b7df66d834ea130a9fa97f606e5576084e273772c509b895d464d2bd6b254fe09ea13163098bc10e78e5693c382b4c6f2802a9bedef27ea59e364667aeac18f8654b976fa2ea321171093cdf4279bc2a633f18343aba6e1ece0f118c21f20cf8f1808d4e41fd87cc1f03fbdad2376d81fd231783a412664f56f2fa7c299631fec23c83ba070ab9e4e7b5cb1a7146c1bdcdbbae45ecf1cde699e72df3e85c3750a3b8d61d427a0f27ec1429bcdcca90d956709939eb741cd7ecf8676d7fa857a2bcc61d6eb1d7e06b5c347823da5c1555567f226f03a2879933eaa85c281a4d0be41645b2a66d5ad1e9fd5ce87288ff211fc93b93b0c7690a37f21e3bc9ae1cda58994f0558b88ab5b768ad117c68eb1dad18ff2dc5b0b4c1eb06121017b8e9e4c7ef1b1c742f718723fb4c8e4351e966946c0012a5f012f8c32d7c45999ff361383601f8f24c390d9ab95f6c51233fd6610fc2fc6b0253ddf17f83077848ebfc711dfbcf14efe1c32129cdcd5daaac7be76fdd3776e6de140a9af0f1416d9196bbfe446c4f5123ff0708d1f16f009bf1a16456e62d44a8890d4d659946b4afb78f06bc83825df685f91637c00b295a190506b7e976d0a21f3d4762725cbaf8b06cf075b503fc93b72e821ab78b57f070601742f71f92c51f74b01cdd23b7e3bb0add49b553628b80a051f9bec8361dde6711d8386ea4c197f16878205225b6bf0887031b378b37df986b71418c0b473646bbb14f7224c21dcaffd3a7cab0c2bd69530dddbec05ed99edd39e418ca90e087e15407aedb7f1bcaac71ffc0c87f7310107edebdd8ebce6aa223c1519eb842fa5d27d74a394c6ccc1d370d5d15ea32970153fb61e250a2fa1b9c58add2936d385ce1bf6c1be64b89b0bfa3031dead7cf5711b1bbf88f083d153aa7319391656f62c6fa5ef00b00ce5f1c50e534e28f2d89f350afb55f4b016a8e5ad70638ede785f9f36546b22aa4039c13cdb70b0ced3d0d956ebe9f991dc222cd80407306a2e4545175227fde52434b4cfa6da6188a30477efd3e9ad41d8d68d1722171bfe06ccdb5182897f5a863579b85a770bd64265cbb5f655581b2bfdc4ced55a758e3c0a091b7c4a38f242383e3404f7e10c55f5efd815b3a9d853ba2bdcca536c80fe190e7867e3f083cd9cb1dfc184d543986739d2efdf2386fd3cc9b3809f20dfbd33a28583725d9154a1b9bbf55c6f86d5b858bece7a0facd3d86227216d70712fb7781dfdf7d65d36ae1e816835ae65d4ff926d8e265bf232aec9f6c8d9a232db973cd019f9ff9cef82f52e2fb8d5252e9e2be1eb7e3d72a149ad4585cef5d523bfcdcd13d0bbc254f5bfeca9faffa8fbb3aed671e70d18fd40f15a99a775ae24d9312631c68410c25d0810679ec74f7f96ea297908b0bb77ff7fef3ae7ed8b66c796648da51a9f8afee354790b22ccdde56b4c84bcc60b7c39b03bbcd9d3af258e8cb5eafd5a228f3656bfb781f96764f81f4b60eabdddd7af2578d6bdc654fe54a6cdbede6f7bc95e3566bf8e6592be5533985dba95399440df126d51524b9b42118baabb46ea9b028758684a535067391bd2eb9c64c98fdf5f87bad5ba33d3e7b4a21cecc7ede78de0d7175ed3087e33260e6c5a2578668342d9063a0e5976d4071101e1ef7063172091f8c4583b7b75fb76699bf608d260c946c508333bd6d44b9de39f84bfd68b1e925fee57a42f87372805a9bc80bf59f4641054ca6aaa2ea165dc185a4c6372f4289c2bfd8d3db22d778f60c9c61072e6cffa135739798e77ad7745a24252ed7f61189a90e9cb0a39f1d88636d4f25789a5cd3dc02ea123f5377ac2dca9dce99efa509510cb0393539b28afc7f6ab3c8ddd3fe053c116dcbbc973f59a0ae2f6cd851e72e6034e146901c444ff930cfc268ddee17685dcd80d8697c97245efc50ac4931066ca3557822823bf48de3e3d04c5b48b14e943d59b92712cd74f5067d1e96e931e4a6d25ff44d78ff820eb92f001a8e14fa497d12c1909ffcb5409f7c5ec814fec17bad77a90c0fea161676d53e51d6b41599683c3509f5cd4553a852d3250b64f1fb07ce846c959acafb99a67446513a7b09267fa159c3e35e12bcb335bd5395667c02ef322b40eb610179b8da833573855f704aeec0a0d09589dd347c212d2866bef1524913a59cfed8731d115fb8154b3266b08d264ad6412f4afded1fd3bce995824fb90876bbf06da342c22c87d07e46a00a4f5f2a31404c704a67e9c943e820be0820dc23f454a654da2d495ddd2ba85a7f4bba1bea68b7209bc4e4a9ed67e8697548ebdfb05ae1cf228bc22e85989314bc0f04d82033887be23ee8ef5c98d674497e4e13f86cc3a3e6770a32d705357efe00afba373b4501375eb0823e05c26cc4042e6320f99812cd03a7d52fe4e676a63ce4439cd860d91d7a25da15b2dcceb23bb6e9dd59814b69f530eaabc905ea85b252657d5e50a6bf3f96985e2f8f295207dd195f3b9fdb07c511bb2bbe78e2eebfe8943ce1c6460514582e3117d72ee1ae2f14014eef2106c42482f205404a6e8b0977503cf0ab4f847c9451c4a1a2ebaf0ee712a04c9389165fcdc507ed7de1e89b4773ee596b20bc07a8fa0da70365fe9133a612ba6d513a3325ccbf51678edf0078d7e8e3229dce5530f3d96485a5f7f6a1957b01eb33f57cd4cf5d6fdbfa9d813ce3359a0f512d65a5750cf22962ca48054a4b2f676b4cb1d64db3a83583ccd10c8f9915235840d4d185dca40bf952556669dc95bbbd77cd5947c2fd3157ab4319cb735f935afdd2f38a8f8938964648383d497d874c22af2893449ac2e521c5cce7283fb20ff8ea4428b7b2d8a92d6fc0e9670dd6da0f4667b4d78794ea7ceda2f44ef97f59cb47917e5da09761f17a39e77a19de9d6686323ae0b7a4b2093840025c47311cb986e55a5435d11df9ecab6a14926fc934d4ede4cba0ce7d9e24cc1ed5fd383b8e2f5dd1a88212038978fa9a2990f09b71858bd38b3f10e2ab0cff20f5d2afeb14bdc1b4e82c14917bf756a2b75af0ef2897b94299ef9dca1cdd0a89463449ce4169cc78e1d8a8ef43395fb15ac1b6e85662701bf5bcd2579d1462954fe8d615d0d24f5b7883c5695acbab0b0c5e9998ad063063910962d50d44bddb8a668d76d64cc236c69fb1e009d23d0eac11c2e369b902bf8c29973d605821a75ee21b82ee7908c91ec60a77eefac27bc082cea8666aa7f26e1e6d7584306b6de31bcd6922afd6384e2d4e16cce1cb557c1a8967d2b46c5873d6ed47cb2faa2ddd4a7e84eac9fa19886f1850ab41b8a5c03bece70ceba3c327e2207f57dea2b7c3934dba36df805c4f2a9a7b57e556dbd1e3ad65f6621be0c4904d0b4a92ee78f7f5b7d3137d42810410423eb814a0cac01f2f1e249f8ed0929bb3e9106372ea39f78918a480419c29fded7ac0523e68f0009e95563ccc43ee7ffacc6f8f8236895dbf93f242ffe8b74c67f9de7f86ff31f87b7f98f4b993c0fc4c42666a29e310efd013f7edafaf7791edcadca42d5738a877fce2651be41a95fff94057963177f4b23d1175e3d4e96f03dbfc68fd934da5336d93792d5f935b5f2b5d1d214e9d268c160bb9637a9377dd15f667bf773f690ef89416e413b6f7365ff5ba0cd184f32950fc1817136d891eee81e10b74129a28b5d9464190c4c5089f45e574555e507b5485a3325dcf73ac36ba6712b8fb996663c4fb996c1d2fc536aeb6baea52f9c4bae75836d5742d2a94f681203d166a84d80b32de4bc8f3721cf4a513539b5b98f4817b3a35db8708bd01a0aaf1ccfef808951319edf0150b8bd7a3cbfbe10e13354e4ddf8c8855ff03baaa4cd06ff904955ef243b8e06d774b0fa9c9c8c5153fe696f30a3e8cde3be73748f778cfbcef13f5ef16ff646ed0724d462e46a12d1885cb09d14d842786434db7d3e2bd778b6ff7fdee3fc847abc98528f73ca9beaf6f24a4ce0b7b0ce767d6c1334655589e69fd2f4776125a67bf08b6f9e50b84bb5ecfdababeba7fac1cff50d2830cfdba7391ab759fac3ec470086825db895c9b726523891fcfe19ce759c6a216f5af0fe5d0b26bf7fd20292c3fffb167ab1fdceb430fdcb16fa265e2a6e61fe972d0c0cd87edcc2f2f716fc48d65f7ee30846d83d5ee6fe0f49eaee3f81c44d92db835f3c5a9924d27efc82326e55e516a21fab62dd989f46daaa06013f208852c1d43442dc6b409a74979389ae8060b89eca14c5857be871e16a3ee1b07099e21e88d9851d37a004ff2e64d5f60c188cece2f687be1415dcae4774f644301bea79494b862bb9e7733896022a176f69a78e2083bcb0386df4bfe9bc4ffc6a60b05960b8860e3398de593db16bb19fd084fccdc50af178ea9a20556e5baf941156f865726b5fc1a5b8284b7455fb149a363d484aa3be91b347e6c85de11ef15d8085f8b50e3e4fc2e9c7040fcb1c68c010315398e5746f42aca9ba2a167ebaf032f51b5389ec2c40e7f2c7309986565f38555525f2d72d91bfc8a0889cf205fa131e11bbd23fa041faedc23130115e400483462755c599c2c19453539d2073c3a0d163519261ec73c86409f376880a3efcc8071f962f2e7bb96f95682afcb516bdf67bf990a89268c2d8f9bbae3fbadbcbbdaccc81c4b7d5cd1dd798eb4f76900d0039138c47bc721ec7122a8e0d980e934cc7dcd98663f58402f33984ef415bb4c4855bccf3aab03599fc8e9db5bcad1590c78228a0d68ac67a84d7477b4fb98d47cd94b7c350385b862384a6e1531f1a7729631f8210cac72e61858ade1400e0fe6ac1479c1d1990ea11fac22ec5e4fc562520bc3fbef9342dfd63694e4be653ea3ccfb0afd130b5cc415c942f5355577f5d548ff497a29c474b551354f3e07b51c7f869722a335fa8b39db43dfd5305f66853459ba60fd166dd4c5997bd8958eb8c13052c85ee4c1381cb521ed589d008fd9ee58bea1bedc8b15cd21e04e262e91ddb2e1462345f928afc035270bcfa6da14644de5ec8b45691cb766a7b22af5240667600537a078c6574c4d96f5f90d67a414cef4422dc02690fe11f746f6645d9259c2a240e310de402e34d67e825ab88f40af871fd9e5076aeff6bfd301f18e58026f6d7c7f42f2b76208bdb2e3aa9b643a1eccdbf6e3bdbd0d14e3514fc4d43dd6bacd2d21350c4afc933e9d0e3f6e7ad9b49a875ffbe7ddd6d6effb49026c77f92125495d35ff185ea24e379f96fc3899b9e3a3713042faca0c90aab155d62b01da8af135d0865571f86923b96089cf6e11e129a3abce92c47545d828fadb80dc57676d0b9b24b86b2923b7329adac9bea4457287becfc6327a23b4d37c677e94e3822badbeb2ae3bb1a91f6ad7dd3b0f8c776b7d4eee6a6dd2ddadda05d9f724cb7c44d3b6c75d9a4ec56ce1f12bc8f5f5fcdbdb5260faafc0417d7444ea02b78a2b804747a74e5d5ad4d240ed1f8567b3e677dfa64a21900274212c129319750fe0d9bc48afa1722a7cc6c0771cbb8a16ba4bceaeff50d569ac8b32164e52fab2dcedcc7cf1a9ca1524e865e7911bbff0c84e2b8f46e839831f843b5a348c2e36f024715824a153e3f8ee40c91d4c45747a485f722e85c26f85323e375b085cb5970b58d92bf27446f3125dd4bcf464877393baeaef529161339553b8c87e6311f613c3340777fc058c01527bc67298bdf67451fbb5c24d78023f0abfa4f95eb0f1ba9f9f8fa7f623af2905ea7980720c17b8dffdb741ca2643ac858b3e4e18ce51d2eaaf4748c19fb26351d8b48ce793ad67dcb13e7894bf55772db4ac08f3db8586def29211be03e53779cf3c6d7da42ff719e979ac8ad266e7c3c167a1ce75e8a0d9c4f393f481df92117fa423cf5a6ea12f189d2e269756f16771ec5ac6012ee5723ae7718b1c58e42537965c20bd17838cf29a0ccfb7b95aca718ce70dafafad40d85b7a553687f6c5a37fc1bf9c23b7b7375ef6c586131807e91d6c8a9caec0331d8332b8dd31e5e881b099be43ba039df8158ede5dcd98145f78f5a988e78bc0b991fa7c7bbffffc3f1de8caf817524fe88c6775b69204e3b19c5e3dde866d63bc9bb8d2da33eec540b0e1d1c41328e197e3160afc92e6d59f82a0400a21e347b002259a0a9de9a8bf286c281cda16cbec7a6173d4d916ba543511828531f49fd7bc7b2d41ed3463608bb2c57783c1238e0be5024b30fc1088af6698a7929c1e4185138538fe774c3f9ed1bf14b9fdcf509cf3247ab3cc8b4662ae4e07730cdb4663e55895fb6456d2bafad0b6d36ffa2bb5cdc9abb293f4b6fad35f2242c3e2839c1c3bfdb60ceff788369412abd57fa5a901aa39fc86acefb4e7dfcd3b1d24b36866b7c1f16debd5991df76ea508cb7f2ec9a9d5992d648543798ae939cced3d355069d36ebc8f17ba929fd615d52b4cb13958dacdabc30157dcd5ff94b1739cf7ca9fa175f32db2345353c71d9c8baf952937495c7971405c6aa361d2b108797652281d364c53a900d9e2e713fc58f173c57f9373de1f1e31c331a43e851162f787c8222a5fa81c7944b431565018f6b7ab75cd35d5bf320ad18f785ee89505c5ef6ca74743ab23cd18caf2b44c693bb1c30ce8d7fd2cb85a0911f93089883deebebe737403eaa9452e19c846ebd597198ce056e09e476fc8222fe9cd36ce88bbd861bbd416fdc39619ff568d3f757ba6a9b4055ee04bcadfc0321e5439e3ea6928aae5332a973001004327838bb3b6b209c25790d56ba9f850f4b097b2e8be82e51c68dd4f2b1b396f0a54d07f42c56c0998d5632412b5873f6c8c2122f972b8e3b43a23138e4d24c65de0d8487405eeff9cf2cc132b37d17c41761795c3e43453d0fb31497a025c5f9275ff874a2d5c7ffdb04ed38f1bb5afe2fc56b1736ffff2a5477f9b6fb5f8bd2fd9b4efd2f05684fa8e9ff546c0e855ade6a13fe85b04c283e7f16926d0a5ba8d8e31b21d926cc848afdf0f7d271faab8e889c07ab2d26e4befd77d270b69d2db5530257ff7f157f77eff1c985752bbe066081f2679a853fbf3e2491c11108bb475914d45362970523e44c3a50efc1bbaf04afa172ecfaa7df194740e8f9aa08752fbcc3b1ec1df5f00b4a66a7f2aee9c2e135efcc5c08239aeb5ba7bb35fdb95beaae0008a4a03a4abaa79e270cd7e027bd542f30fa55537d554f339ab200303e0ef2d53c3b50ead2d675c65dbd56afe475d705609db3c0b35c9bbccbe708e0997de8cbacd23f4b40fef82b7da7345f6f35ebc64fa9ae12deaaf17a9531dbadac81d82e8d3143b1f44f89a557f29bea5c5372d0cbb9b9533d21be7608cc79e08bda837dbe9a65cdaa64770fe9291bd4bccc3a4389c58b6d1eb5f545082fe82150fb5db46e4d94100b658d957022e782fb95e364a69097372bd2c1efe516fd0bb847e395c1f61d090757cafadb3cf5c827d8d51c38f3980860e41c29fec245eaa6f7c407fe3edd4b429e7611d17ad3f39c1462a2f49fcd42ce9d31afc58144dcb94c76627b79b306b41391928483b136ac1b0d845365f707a0e451febcd3c8304eea61cd6de9591908f570a577c6a659eda4c7b862a2bb9042e5d52e89c5c4e2230e916c7245fe82afa5d2856df825d166b29b03c044f697fe7788f5ed0aa76a9fa071e7f464647a01e3c75d66fb5303dbab4bbe8577efd6490a37274f9a356bcce4dc468e289fd02fca7d3d8d0e8ec2393d8d711cdb64651cc67c51e84fed2daaaf8979ae2ed356aab3ca6ce53c5ced8900a26bd64689ca5256d58a17b3a66b1c07a936b6917119d4d5f6776969daf2c5617054e654eee93bd5746dde83699aae777f5baf1dbf2bb8887ef7446530b567d0e2349435144dc34dc7946cbde09c762ad945ea8d0338d8eab7a387effc905551e457abde676f54bdfe95dc7dea2d1fc38ee8878796d5139797addcc092edd7c91971d886d7d4a98faba26ff5c571e16624112da6458f66c774c561e1962542e1fc654793eb2ecb48cb41e2cd1b5c264c94a629ef4c75953b980579ace367ddd94ef49c18005467fa9c56a52d1e53a940ceb2dcfde1e55acf66ee69cd4ef4feb33510d527ea5645d6a92726eff71ffb15af41831dcd9a1c2cce9c0fe2892c4f949eae36e4a988407f7b63c84bd396d515cb001e2927b9fd4c84075c57cfec8dd8c0b6076ed3f62ec353c6e68984d7f4890cb842bc2f1fe263dde5ce9a7a9e58046577c14bd3d7954617891e147ae85fdf1a886bb175bbc283f2e3cf6c5a4f5c8aadabe246ab34f91359e942c2d4c7e7ba6cd5256eace367726579700d0ca2ec6262a4d1331952556a5e760cc29aad36816f3f24dd4896215415e0506cf9e2b46ce56dee0d30da267a6af5cf9c6625b6a67327b95d482bc102e4cfd03c1bcf642bf62a1aeb07d9fe15c3ffd2bf55aa7febae9efba7146fb3224eb95f5dc96f7b9a3d6d02f8500ececfe9e5414eb8ee945096da1384f647341f4f659bcfc0c4b63e45f3294df45e7e68cbece8c6d351f1a99e8336d418679fd5e6e41d3f1c238ca6aeb76fb5ea5c19ddebfa99a842db89e6c9f02a3c87675e6314084a2d0aafe5400bb86e547b69069e597626b49ca1a2d94d3fa40c156a6f276ee71179a5519cdab4cd48d060c6b103aed419a38158228c99420d1e6a388f758ab0ea918a8cd3c2848bd8075e731af527440653352d663f79356052d7e14ca869c4fd97261b4a88e1996bf3ccd43ae4a029393c823791c7bb07dee66d847e50c2baaaf3c5f35eee5aa188aa0eec08aa1c2681f6ff6dda77e49add67925b89c15784c72bf18d0a1be496bc9dfac4964f07c16d88def4f9a781e165578b5d15276f0316cd1f587d71ad604435399fc944e7f377430ae68957c2f3965d959481c5a18f5fdb6fb8aaca616a43547fda10dfd6db4d59769da34a6f1564f127addda6fd7ac1a28fe5f5c75557e9c8980a502278aed3d35f868295b3d8b8c2d982b949568ab9f45ad9a94bde1e672d9eac3b0f3894cd30659f6884d033c105874147ca91fc49634b4d4f173fbfebc2c11720404b37b528656337e26fad33bba0cdbb805f5abe5874b60eb05d596517ccee406b08342344c0a19c210fea1a24610541b1893b8f322da8bc441aca25eb8950a48c22272e8287739768088b9b550023006bee8a884abfa9d9c0f34c3d0088ee0c37a40216f3d3a09501adc311b6801e308656319c9f239c3a065e74fff260febc8b536a53c2a0a0691959a1b03f40a20a5fd62d908917a7f7dc2bab279cfb152ee011b65d2bd9bc25726453912ac31b88166d218977994a73120137d13b4c50182028a323505aca247c3b911266220833d52120b24c03b4774899f9057e4c89f95a6668065cac87142b2ef7a451efef3587ab1e0a0bc61e8ab8ce620d04cda3dc23ba1d41b1c21f73d0240359840019614727932b646e9ba5d3edaca450efcb54c30bc21404ac457ef19bdae52a45ba2b82d4b96e51a22506d617196d26d04d3e53537798a8b56df43611cdf13652cc5d2336cbb0d766e88d086668bac6677a9a3691aa4b4a422a7c4adc34e7264a9284882e254b7ef24c0b1797b299a7b463e9f648a3942aca8be7bc1c78ddccbbf10c723c1c626940ec1de6ae95d052dd58c53aa9933e62c7b162e6044052be10ef6b6eed44b8829d73b653c69fef14cfbbd0322c92f589030ec71b5782308e04d906537bca5863777875a683323c3f980a1e317dfae4a1a812db9b793edc11bae6ed63b3995c04fe054d0297aae4653ce4826d6da4b8e6a1ddc9c988a02d5599886b3b6dac735f4017c2efb63d119cbe887ee9f37f55cd0c9a93189d013f415e0b962756799957bb295bcef45698e613415a79c775b67af3e636c877e369763794e4e9fb27ffb14e2e27a77603dbf1a2ac50ec9ba60fa1e64957293f0e314ca3daec9a72ae16909c2bb63510cb4ccdf3fa573c9c45534e4dcd3cade701eacfbacc81c6e75b780af48af871cdb6baa2e9a478e6eb3aab51f6a15f6a38f1071aba4e395da77853a726390d53c939db5c2b4786ceee92ede1d6cc166261e728335215893ffdea0bd53f73fecc852dc4ca2e901c5c7758a0231f39d19d0f5066620b31b32bb493cb0e8bf527da5cddea17ca545c319daa2bcb6c00160d40535948e6f04d3c4aee1ccf64fba1a86cf7dd6c5a3e03a98bd215ce57445787c3974183f0df4e13b595bc19c6b87bd766064aaed8e6655e260ab72629cf0645669fd6ba0535c701abf31ceba723c24f27452867ed76455b33447702713bfd0ab2b596dff4beff40266f6f4177c58892253b6f4d9a734ae2f400ce18c01f6700af321c2b023b7b304d384db241fa332480661c627aa88e763d4875508c653dbd5fd55e3690023ef7646ab9f147fdd29d89be74caaab994a909107495b9d7efd3309162929751ca8bdfb85904cd7bab27f4dc13895e405c0d8eb8cdc253eca36b3c75154b07ccc176172f84221c01b2874c3d83950b0d275fad2dae16240d0727f683dee277fb5e6f1b0e552e1936a3fcad172ea55f70c5a3b75f1aac08fd792e11429a524f4011ae3ab4192bd08302b54e6f4052d0721dc659c3c6fb79d856d7c45178c50dead436b8edf5c890e6ac8e27b7b93109be5a45922b78754c70fbc4167af3c52912b51436d27cd2d962c6f426eba7723acf0015326afe3039fa906a16634a92b9ba2bffd7496a0b772951de162ca2761bf4d77966df194aabff5f3fe0711446e0d1c81fc5cc496f27a4396233719d4778784dd47dc8a4d74c31c4046efc6d35354932dd0a7005ea797e302a6c8f23d4dd7fb19c7116d2af3fad26e198d060bc31389e9b4f3a4b3b5ed8b9fb8ad469f367ab2baee3bb27f8910101abbd41dedac643cad9a18eec6b1c3071da80c216a1bc0a3fd24fc97ea2eaf81cdf277ddc67901e833d5ad9f8c9774450d77f4ee3bbb35d2057d070ff617d8a6ade7d02bb59eca49cf90a70af645df46523392ca8bca62ba2292b207ea322e73dcb16215077a25e0e27e05a22eea23f83b47d3f276ec87dfde50b22e00f0cce9f498e35588e7a79223d4527f19cd1fdf511cbe07ed4bd1f9a6c8b49de8dd418ad87e70f6b20aa39f729a5e3c7a455369a7c57726e24314d94b1679fc334cde4d1493c5b9790adf4bed107b9cc5d6d4353ea895dce3daa129b7ef36d34d0e04c11848020c2b5ad29ff8c608c524f3527b56ee2a30779045ed509292d10081c5e02083320619fe9fd93db00b4be18248ec92172c162a7a82fec9469ebd786f70a6d069ce44e33f734aa49d36d4a33aa99bebe9b0d7474238105ec2f93cc7bc203a6afd94ba66b67e03ae00c761129cc5abd608ea0d27a2bb5a739fc098d05052fe994ee53ade11e1dded74b1228eb739cba11296c384f23b5eb97c94dfec54a90e1298d88d3a23424f63d039301b9fca8452ce7052a4840ac975c1288e6103b886ca55eb867c96f72039287a79a52785f4d3cdccda531417a06c54b6dd514cc8396f900f3bf84bf5a6fca3622e02b8cd6f4581d91f096cc57c2ea8adcecae296b4b768ad05ccf39329b07a671f781754381106dfdc473ae2c1cb1d5d580e94609b86e88a3c296f5ae5045c5260a2eddbd2d5dbaa73ed5c9e96c26d91a35bfc7fdd035296efda4cdfb6a6bfdf0cf1d5191baf91659527791bb55270f27eccd1a88fc18e3aec8696adce5dfc73ddb32bf3687b71d3dd0c2fe1ab7208f7c6df3c8cdebe61032e5bf19e2dec90ef1976faaadbae9c4458fb136768b8a0957598fb1d96cf118e923fd291a071803a3b881f3a8e00aa0f4d10ed9aff44d437a8b2d5428c0ed297382f862189bc884cfc079a9d60765bdef9edb3ce65aa819f4877a687e71b08d5a4b7ed6080d1611b1314d3ccd854665e209ffcc09287fe4b1c8a96f4017ee8bc0607cc6088f83cc7d0acd504bb9a0108d3e778e3f3d91474a70356517bbf4e338434021889d367c3e89e310fc3663857984629b00ee7971a2dab650d7d6dc4f0f6c26cf7f6e3cf748784bd57f6cdc174eb375a6f9e82793aeb7dffe0979ec7671864de1f3d27eef3ac2ed96fecf1f5773875f256ddff61e901e6599ed25651629da679330be2bc46b0bff3e7f5f054ad3882ee6208633b97f028e900b677334159aa656a6a99bc9cd36c5f0eaa629dd3734d5fb366ddfea5695a9eb8946bdb59407307e61551fb672b9c536a5252425467a4a8ed1420a25a62bf6b7460cae1eb59acb0d7d6e813d08ef03e72c7384681e7013b527dd82d3a9a34ce9c9fa14eeeb35c8343793f0f4e21243c2e2f3843395eb27d30ad08429665b3565a675b191e9e66ba5565921cd53587fd37d8daa186549ce8dd7eeff76948d274aa7de69a24c85baebbe16b3c33ca4865979622a41d998f672f9641a02fc09d29f2c55e603a220335f98555a913dc3489b7dab2dcebb16f32a753789b66243447f0e201b3e0ee3f79468d26647047eb80697e959be38ed5a651b00b8e14e33bdd56d2bc558ae99a4a72b56b6adbd44f2e9f0a0ab4c77e92adb6c1532c2cd76adbd5ca04afec5ea8af5bcc5ac3b1275e2a663f8f70368b74963cc372b12d00df7dcbcfeddd3977af681e89f995bd7ff7b004a4cd34e97e811f45ff7f899bafbfae6ee53454a1a41268707a2d92324ec1e017c2bfffc6d700a3c978fedd5c5809c060c539a359ecc5b6b95237b76483e0dc799b903f38f89226bc43d4e7db388af1d70a18e8e3f4cad022df47985b9e8f0ca0c0077836d7607babb77b3d6dcbe824c447ad04dee4f43462158f93ff7e7b465e5cef9a70e35331de2b29fc51f3ba4df8ea5a8cd5a6bbbc85cc28b3512ebb1e9114dfb307a4ab884fcbfe4122e5b1848c025cc5f4190afbd149700fce674ebbdbce6121e0d977021bbba7ae05a971ef242801de587a59ee10848242ee369a16710d289852bf2531023b83fba57b9dcfd2ed413ff3022dee9f557fe81a662033040729950e51b5ec27c72411f230fcaee0f2ffe78e5239b44f5eee72b9ffd79c04f4c5de62778025672f9f2c7c61bcfc47296ff4de347d338cff94caeffdc78ed99f885e23f36ee0b676e1ac72a7fce49f1b3fd894bf93e21192ee5fb9032afbf754a5ddde5eda7ff8289a9fe8989f9b6ca867fa0dc80ec18114c5ffe151b73b3a6d9a6f6ceef4d05a6a98569ea6605b34d2db34d7de78832f394ad8bc4c301253b5ce49c1447a409cbb6ee3cc1c56ae926ee6e8657d02463a37985e30dafb0a0bb7dfc82e1cc5f125ea178c32b9c5e740b4ee7cc79605e3401715fe1921db7b74af10a9b171015f2d259ca7acfb4b323619a801b55a432ed239f7ff28143cda9ab0b407aeb2fbabbf31a065ad3127d8c53f33f1ce8e5c52ae8815e516647fd755fd7d9815e5203ddbd3049a4919e65b3671a2a49dd513a106aab321f101599f9c2aaeacced1346daa4b1e72b0eb37f53f73bfbf73f1869e105ec5f11650e2f60ffb6dd5fd9bfc30b5f094f60fff23dd310a3dfdd65d83f7c401464e60bb38a13d9078c942edefdc161f6aff96cb9c245b6d4099d60cee115c27de88ee84f21928620ae0e4e53d5710e96941a26e2c62e7202e45268bb9101008a7e2fea5b268acd1ef771f3b4d99f9b9398f1035f9cae4ea4e6cf38e39811a5a9e794307ec50950bf67996794270a5a73ac24c91a32077b1c986ab90493687c3eef5774ddd5257474f79693ca32438e170c01ff8066fa80f58d19989f7e934d23202314e58c40ca12c00c8b9e7522b0f35948d6921600b4fdcb1afa9ded940d8163478889b3a284d35524339e3d8352013187bc571692c1a318b4fc734f6af4de125a4a806c332c113be31fe1115f437e1693dc84fc087db25cdd8b1cf01cfa201ff0491da09e4f00cbaaaa90f388b22f4ce4265384c2fc5555c13f738898de55a608814b395b65bc3f7a628809e89ec804d8adc3038e54ca26699423544bc5a749f89a2a3baf7882ffeb412c6c86136b20c67634efe83dbd64d6b32d04d24a8cac20461e5b745072c468df81c1ae84a3324df8ccae73610acb0d19e69ace0125d725b166c7110d7c25522a6156f93a508d914c05bc20c94e1ff71667803280ab13d9493df2f1e821f528c0a3c7d4a3108f9e528fba78f49c7ad4c3a397d4a33e1ebd9a477dc44a75493eec978113624e7c32d27b5c8d99f805ce26e62f215b9283beb784327e4371be9fb98e6510d554513681d4d888e10e55514ea9279fc893c5cf9678b6783532952aca88e6e5738c4c4c56a89f11d4bcf8a4b07cd127394e6e516ee39bba7e51ae018476046830652252ef1b7a38d4e4e51d7c88476195c781d1bfa97b24a6c5bf1741f26f3bf92797f084f784887856235639bfc64bdaba001c81de167e3051ca7c134c7a486e1d5a268f56fb0793c4c9d9028405c07a71f0df088a101007125fda04dcace04e214c271976800477f2b571979c0de3c36a8b10018dcbfdf7c02b5ef218ea634498559e70bd13a8a8a63d77cf906eb198fe9cdb89f3e0114ea9022ef3c2cf9441a23bbd7e748d7cce3e32afa110f79af24cb557b24aabd1cd05a09f9e5047c5afa04fe956d2af5cec0657a8d73bf3cf10b1443b4ddb3aedb9b1057be652f08f9220563af7704fd487c97fd820a306d285dd37398bb48d5fd0e28e010a8ecc8f1ef20573dececdab418315ee9aed050667949deaec0d6e92f0c8633feca435a0d5d58b0357083b76347bb512300a8e7e8ad71a764ace934fdbbd9d4f1910fab49264e6a597ddb8d2da26b371bf9cadb461b344ef974a902aabd94aabc8c009f57faae6b0e880111052216d288fb652b7931a4d9b9202d325e21d7097205d5afa3d5c0c51bb7f53fb2cd7ef381bc88183f4ecb164a5f61240ed5e019777f1fdb6fe12eb5d8365b65767436faa04daf4360746ed38a44b78c265f4901dd2cff4d648ee869417279798cebd2bc607b663ad28106b6fa734637c1473fa7456f676246b2b4655a4940be797a724da02a2a5be4d12823d24bdccab38a616882c318536beb94d1f5b3557ebd4f2fb94f5345b90cfee5c6db3d6a9b13c650be2143b73c5e82aedc298d44c63d940c1f336793ed22d32c3d22ebda0c1da4ba65ce9455f0e738574045aa8a152e37ea6d4894b21b3bd16006814b36ca9dd0b06b14729c4968f65e33ddb338adb9e2b64636bafc63c25ab4ea6d88a180aa74ce9e47c51eabd56f6ac977ab03c517f7e022812fcc3c18f99e4db1be664f2983503eecfdc9de589da735dcd18bfb07a6f75c5f599197ace9ecaed9dffa93dc64abc3c37e3f608aa62fd48ed0de750513de356687fbb1486fad601015a51560d91a7d4a30209a43ea3cc0ef3ce0c28db17ad8f691695b22d9c8135602f6f31a13be9c5a4c208444b5410189f1f67b662c818ffbe9682a07eeb46617a0ff64ab4b386c416aa3a52b426980570eb0f6a2d641cb762d8cae466ee426eb60cd863e65528da84506e0be4d3fad6c1698ae710fe813bb34bce434fa8ab228627c101e06ff098ad1853e353efd0ad6d34365ccccca19989ad9d6d87b8a3c74ca97652aa1b976adf96f27e2ae57f2fe5985223745104d5b78471a7913f5e8829413628b5071226fc5518528efe3d26550eb9c79e1e8ef6651a430610ff20a08160e003a8e1e3a7ac9e59679f32695c4ac4c9f153deecb063c54f714ec269b62c7b79e0ea8b9f72fa9b2f7d89c60fc9af3dfcc85487f8b0273d58f92121e36d13d4adcf93f7c0441d274585700ccfd05d757f435ee10cabb704ede4b2046ea87fbccb96f2c4c347f9dd6a8bc2c3d784e763ed5b21910dbe293c0ff9a61102dd05a969006d7ff16039e23e5288f2ba39d46a8d1c589fd98dafd68691cb1c47b536c05a9fe91be90452b554c1237609ddce48880a5e22340c982a2ac4fdfc5ec8136a6aa3d081f8a4a31a833a3b387db4243dcad012a7caa59c40790ed67245fb9d093cdf509f22deec4b45399cc54ae6c16836dee24355bdb9b03e9350a62612cdfdccb966eeaf4ca5d6ef3c6de63afb64bd0da50682801bd621921762c5b37b9593011802f640ede6b0e9357da44679126b1fe41fd424263d9ca4a78ff2aeba75c941b9e7b71bb6591565e290fac2d378c1ee2041447d30d2a4c16fc1c3ec8d4a0f9d475c9f8d30be3ed71dcb17533fc50e51873f23d2f24cfca28c4bead56a76f8a2057ae01b916a91b97a48dc4d5f6eb17ccb20427048d78f6a9db96d4e50d5d7fb223ee615cc54f93573f84bb05536b34f1b781a11d14b280adba249831f3fada1ddbcaf87dd490dbbcc20c138ecb9719c3179d2992bae55fdc8d0b70a9cc3e60f99efcee0a719dd595d5176d94d1351305f7049ff0b715078756c048ed6a702ea2320541a561496220e995bd389f89c43e70004686f0c68c7031456c0af1ccbfa9ca84a51e580be56009e3700caba15fa4598af7579440eeedaef259022bf9ffbbd04f46afdc1af05b680392f3dfd5a0228317d0654f856c2a9cb390b0f0da465421a8bfef205a2429c3f82225dd51c74aac7a58ad8e44192dea1d4470ed158bc451810256f5075d6b2c2dcde9faf6f6b8fbba8ddfa53ed156ae787b79fe6f4a58bce9f6a4fa09189de6f6ae702d4ce877faa3da6bddb6fde7e9b9cf6d552157eaa9dc9e3a3b7bb493b7584431fe451443d3d9ea18b25f58a5f811ff48463e0aa1b995420c95f9c30873339df430b461f59e9fb68a5cee416af345d3a2026acb1872fef96d8149f902aeebd0d19709560bebd5b866be761498146838839f615498e79c9af278448c880ba63b72e4f11cb162d5d6d22672d1ced2e08e1965997d246669eb7401d3812949f2e3759a6880327c23c140678ee5c658ebfd9a690a8eb9c15d9bb961087566946e33adea14d02658306deff8adeac9b9c26f4bf1017c74faffac22bca0d3249d0bb0e9cdde2fc55f3eb5d609da4585cefb6923349b5bf27434a32dd1cf9d62fa60cd647da2635a26267b9a174c0fd2a34eb56289cb282caea3f37dd2ec4d98302e1e771b5fb8dad34968c6bdd7b8bc8925faa7b83da0078b765bab17ddada27599bb0f7396f57bfd2d21350b053100bf0da254a039ff03c1c753a26b989c9aa54e1acba144c76d582dcb8603725c27ffc9a6ead7e4db7bc557fddb47e4e4d97ae763d6e5a3f385f6d4f378d1b65fd0aae92c4493ff9c5b79a68af5fc93c645f15f2129d68a54ec47eaaa6845f88bf21abd1726a00a596f0bb641b10e20a57c84c791d589e584ce59157a2a23b321d71c533d27b9d62fc04443650f2c39b0015ab2f26a3abaa7217886138d15e564d89e0261caa939cbc60f5d80e54028f4ea029541a890efdcd278ccb0764e4935586e6ae3878ce6d5739c7aabe58f3ef1cbb7de0347ba94e227a3b30d81f935f026daca1c8bd5f6d338ef1528b52c7691a87684b6b3f88de1392f74007a5b4d67cf2612a9b2ae2fa977bfde62473ac87843ed4df7ce1b1c0d32d60ae4b0fd6401c471cc57fcc4c7ef38f933f96e2909afdcb933510d5776ee8f2e36454ffcd648ca5a8a466e3d2d7ac4edc6df0107e8efca49ab3d603fc23190ed5df9ba0259341e7c564e453b1a51281ee6109774bbf8aaa9f0bcab24321cff6545e484f32a8bf803978d4acc312e6cbcf0a03d26e5facae6628c8cb5e74095f540c312c82cb576bb5b50d7f2ebc09c21fc942a8de675d1270dec0053e6278e3c7e427dd2b8e7023ec5eb190fb472b142e49f7d354d1b65005baed6eeafb9547e202dfd26dfe54e2012dc6e5fa423d25e53c0288d00b977eb69bb69632426ebf715f0bd9511ae96709a962a17b578a5a918431da2f3c5923b11e315cd2e9c76dd2fc37db6426c56a946c93c69df5993aa14d746cb223ef813c502a360a307794e8e9228b4786402b1c89dd08caa417dfc1e1865e2a782086253a4a9add2a74bee63bb638efa4b5930602638744a77dfa449d3ed190757ca22857d02bf74ffa68bb7615cf5f6afce56bfc96fc0dcef14f97371496e883183ec1afd931abd23762a6436c4ba1fdbae51e228150bd6c62f24f30145c7b5602a7bd036fb3a093df653fa63d9214199b89da733640043b10f7ac971a59fc92df6fb14c2f3cc22efc9bdf7da4de3b94d55a31bab77fa6bc602739a68de126b7ef610770757dac3f1487aa2ea43ee3ca382cecc86181929a8a85b40a52f32e9c934d6f7afe6748ff1c4241aa1be314a0ea3953d6c785e3de47c451aef3dec5996809cd9ad9ea6eddfaff64ff03c7169b88c61cb20268e0aaa6e64010bf13b31d8b65cb134ed9ea444e956a4e9cacc3a9d1c85230ddb3b8a9b9a0cb63d298684345e19c3e685ed63b3082746ff5f0ce948cbdcfbc24cb806354abced126d7ac967ee36d8044b985b50ae59cab8dc44178a95bf544b7ca41d17433f6adbe08350bf10899bfafd8d4645c4766009c2caaa42f344d2ee7304efe49a3ef218aec8e9f386cf277aaa9fa9a1fb29f617822d0f91eb18501e5080ebadccc276bbd459bf80397d40f1ec9b60e71996da050ea369d26ecc40ffadfed1e67c3d55be2d11a08378201777c6211e2cb8a718a233a4c4c485e2be0342f1241f14ee58b6743afebfa147b90b25dda3bc0588de58820f08f43b4ae84badbdd5b9cbbd4d11cadededc9b3a10d13761beed7ce9aec9be18ab8228fe32bf57e5a030d704567b9cd8b8ec8c1cd094253f3cb6a8b362766ce21d41e19b2dc7d182b28bc9df32f87a9a65054d761a5418ab131c973d4d2428e71e007552288a22ce9fae5a9c84c820826acc5e2e02a4f5f397de3ef7c3c71a8b7b038c39408773cc747fc756a6f44d84e845ae743d869b269a086d3e8ac0954c539d3651beca07cea368fbc5a7a221b47cc16a33d6842427809612b31f8d30a896e73cb3dc0d2ea79bd199bbe599db91deb97bdbec560a2a6a506d9289d54c62a1741dc1482d4494e42cbcc8ef0cea76ffec94ee640794295d509a5b017dc25a5320d26c0f75c9f241fa636419be857284f16708538e711a253f24cc1c66719474df391a0c17eb2e30f42cfa9d7a189421fe8e3c4186f5d249d56a4c9b47c610b7604704ca3af14199994ed41406a5909321c4101d989ad43730a3ece8d1816c813e4e3c3aab5847794fb73b6e3fa73634500ee5d64048f80888358ce0970567aa43f4d79ec78ec45e5deb3bed314bae3e401ed7ae70732427e3be75816e86259d982dd9d24f96c00380c5bdd4219a80c87843f4a34ce91d15b844a2f990dfeb18e11adf43f614a9c91cc1d5e1778513bc3f37f8fc6186e61465a829e29d4d5b38944da2f6344f35fb92f4448474097c11a5dd1d2561dc1234e2e92ef9aa40c107408a0458bd3ea4d198820f5a2c82d9226bdbe3667cf130bf9054f348cbe20d72b964957fc3d1a1e14986451cb13d388c4f9b6d870f1fa99617710c7429fdf72ba5652bab01f1a14f05d782dd33d2b2268509c0389183e5f0d74eb0e9a515a12de1223e723b0f940e81f3eab7466324fff70a620bc63ce06a992a86f01ddb7a2cb2f7554baad6f655ccb231d665c464f5312a4031a3a6282e1c5a706b7f819be942b3ae8ea8d89f31462cc52b71390e7f58360c96042ec96d8c9c6898d7903ba7e68f610769e57d5319fb22bd2485f2463242d1119b77ba2f49e6a98fe5acbf2853795e70f9ab70238960999221d409f7689b60cf767998a91a3fd6e22f409b5e01e0987f5af3e2789f46a47ce240f96ba4def4679f66c3cf29db4492d607c04a1a56c13a7191f2a06e70425859f57157e630cf010025437206fda2fc0b2ecf447db3c1664a759afe93a21d49367812b9279657d414c08a5459dd5f6c43641a3e8d3abc53e83970be2b92f1222d1f5c29871177418d0d84759e4e7a50bb3d4babb44dbb732e27715f3ced1f350e5a7b58bf12f73f4fea9f3e3c645b2a3b8c22c69eeba2123db0a44550a62bcda55b4d8db5c8d9712bb255e3908f92aad9214aa334f3d289097f574986cad19f28df2c60ff574bf66da3f5de3881dcabebce6e6f4776bbafd6dea4185fcd5d77f683f68deb45fb89a39e8c7a95a0067b22702db2ecad34566aa94ae067ebaaf19187d174ccaea098a13c5fbda350eb9fd570e24e0c9ec73d6cec0b843f65fb3b3dda760181bef3e80e5f1968c688ab8112658a5c8acd51b6a0f110bcee9dc9d1a436f994bd6d76b048c9408e4c945a22e672daf5c67823c76cec37422e38fc09ffecd74b1aba5d2a30a3523359173525fa8a95cd03f9cfb7276c62a0a8e107d83226070b957f7baf8f38a287f596936a4a6b6b202c25955b80f88d721bda8ca8332d7a0fa99822df367f87b915a42014b5aa5342a6207ad72419e6df81fe9874d79a19727bcacc82bf124679cf402a42908022a3ece2eb94804e2c19b01e8a4a2db2444d08582a60317be4f16d3231179d1e0b69b72a7a003e2cbcac63ed1ed7fa65c11fbfafe7cd5837cbf67951e180b57a5d4a94070d04f86effab6eb8bd77b2864cee9d24cdb4f208ebd6bfcce13fdb5bc9c358d7ab86708977445e6a2a6909f4a50c9bbe5547d7f2d4b54ff85eb577fa8fffdc3c412b7c5e0282b78b650fb1608ea4c69791218f82779e4a79a84e4e5a98575c27453333970482ab91f576a7e64c5ce56a6021591a4238c70cbd46c3465b25206649f27e0912311e5e705b7b244f6a190566403d405302f2dd2fb8358d723be77fbc2b1891d6980555cc87d914ec51b625266fa327022de7ab0834c69b6c8469faeb1947115dd01ba233c76ab4fca5e653a6617c014ed228096c8f36c425faab3ff09dddaae10af96120e341bc4190fcfa81a4ce20635ed02efa3c7fe06a16734c5bc84dcce8c281d92f97a791cc060cce84fcdd30d5bb1c21e1a6e4b78d1b88f5d743dc2e3f10c905b7216ba11c926dd3323835d20daf5713eb723923d76237c90f41d7ea3952d11f0facd09e4ce83e1dc83e5d276e0e01b11fbeb2ce5ae0d6a378dc17f18ed630c899c5376363835088c89832a9b3f6b5c6d22ebfca43125e5a55b870c0af05f983548fe3c121c5f906b81a027f227c982436106162409c1da15569f06b41996986e9721d871509db59348a12c4bc652a8776c593de1318f0f85f60a27aa467112064727118808f10676c501743fcb02e605085d7e81f92c2ddd7bd81017d6cc927023e85890f12999d39bba557edcc0262cebeb819818d12e97e42f2a2024f20cb171351fa7280a92dc2a2538b36d21b3b9a72aca6ee609be7b90797097a428f316a496e892d1fb5164dbd0650f09659803b39066573d5c8e661308b05a2a452a94d91ff44d35958dab418c25dbf054be64e9d818fa645029cf037f5a2f9157fb566e4a124faae484f981c5ecad4b326d631a6aca11173d02cfdc2f432a9bdc676d917da1aeaa408e4a1e8bf92e2ac26f8223d30b6999a93da77c5e638567b37bf3b027d41b4056f919ee633c42554d6fcbb78d754d6e93b89e1b475b9440fd862965a3bba5ae39b873bc1d78af211daa0738434d615d61a14df328ae508f795cb857562b9c36acdb221d1b5c777c01278912ced9e8d24ad764b0e41d9d50b70a9ea74ff54feda47a5e9d189a8032fea816576f5e381968f1b70f4f55896b5eb235392f01ebba7ea8d9942b9aa9997c4d56114a5be7286347dcde6b727d96a0d28dd41afb88b0b3595f025b1ac72293dd09d717d3811cfe8e38031dfa8caf796b3721e89fd427f50ebef840d96c1eb1d7f14b0cb665698e36ddf5159ccffefc40dcf6579314ad0f2764a65ac835a3166c8a92e39949b81f41ab45dce5d5695e298e8e341f6f3b5a7e5162a87ebd6dc33520929c07a2544b7cd36b4099d5a7d3fbd4a4a76df06a278c78a23409982a4690d33ddb1e88e5f5cf94d4fba151c10d38934d626ad55ce62aacb87145909aff82cc9b8b00f26f285450a2a3dd83804ad6442568b5af80c2f52f98eca0d2325d10be639af7f78a6051bf5e8b97ac7e6ca3858889846aaf0dca0ceebf24017aa50ecc679093d9bc7594e0f33adf4e1eb399de8a2460471c78696022f3eb0e742335380819f52ef816ffc23f89b4da518b44eeffd38125c5d1411abda1caaba2fb1f0fef6d5365bbdefafb837cdb4a5d155b7f7fa86f5b292a1204e96edf396f05b8046e790d8172a84e4cf6699d2256ce96780d2164f52262735da886bd13002a7b78e982e52632aaeeabba2f15fb3525811d249fd3c4b73f24a2af9e07c90f31916ffa3a20988ca944afc2774dfdefc95f5668429fe3ed38364a157d9b4b9570cbcd13eff513825eeb1599e8c2bb5098e62a3c035abece734689159fe725eb177b297d28db9e681346acc32d9d7870c7554a90778a6e72c60a40faad11aca4336d95770c614ee63a2ce12783eafcb99fdd7fd74f32fded249c6f1f7fe95e209cba73f592299b54523dd9ff434ffe66c6c892336afd536fae4e90eaccf1ffa1ce10d336bafbe7ce34102904454a99b7d304c776d0a0addca10d3b8d7b47f7b01c574dbf7affdc2f8f132288b7f38a650322590a322d548cf06ff5ae956c278a6499705974ad2c990883a66ed4121af8b3bd21763a405817e0d4bd758d46d7c7f53a7ba2eed835b411a28986cceb2a4e11c13708f8da28def8eb72b637b885cf36657bfdba707a41bac73a4bc4a2e448907e8668c49733a755a42bf5a9a819eebdc3da8c1c6e0e284e4983e1e4a96315c913dfacc6132f4a8a1f0a039ccf227bb0c2bc8d9a6599f5a872910cce9b94537ce07b4c9e38ea8a655e3fb74f337673f9ed72b8e9ac2acba8fcc3ddf4f2cbddd4e084c0c09ae17ba3f3cbbdd1608cb8e35dea7ae8fc723d98c24dfdda813d8b86e509119e20613c41d5463f9cd7d33ef6ac5cd800d09978d8d59fe0fca27b886b3925c4c41e73528d31c1c40bfc9849713ff5b6b58c14bf33799af75f899eb20e5f23da0a1b76d5dab24f2cab5856724926d8a0a899c495f24aa4075c49c2923edba294c0dfc4ac27482c5c197a6595663c59810aab51138c270371f92b08cefdf502bb18373939189126911411de51954cfc293686658274e708855eb01eafa7584790e947bdcc42a4bebb7780098220d8aab7e25fa23d39d189ed220109b0ef970a27b4009c0378603b1f384ad05438d650b4f3f6829dcdbb31f4b7ff9cec504acdace74a9f9c679b04a0c40d70268bd59b13e35c19333b10e279570375c2c103b077414198dfd71282ed1c710e7355f94bb3c195b35a1a4e012d42c435c610577875e4d426db70fb8cbca4fe01a8eaaf50bf6ee1b2ca8e0acfa5230bf768a4972aa3d6f6868de1559856885b30bf7d2142bedcdb65fecd3c379d2d30a723f24da94b24bc0196bf2ee6ce210f342979c7239b90e84f8eb48348c4677d0aaf68a7dfd64853047f0d6b288263e6ed84541afc7622855bcebc4637f97528a6726f5b4acc2430ca362844cebb4e196a763acde85ecf784fb6e326022dd0a65e9254e41956328e973006b2f4b7efce5adef1f0e51195a0c0738e6081c42820272878ac2c6b9c1ca786d9a66082adb16a220e80b69c8ac5d2a110c3313d1b9e8d0ec22513461cea8b6c27fdb24b2e63486519db3ffa71de0798c6f5cb772b3664298ecab1adc41cf3adfc2b5e9eeeac4fbaf03c71977206db812bddb0aa8a1dc4287779c40712c66a7871d7c92eef55f0675e67e606ba482bf1ecb82063e415befa9afd65e52e987bbfc472e9b60efe9748fea1ce1254fdca9239b1cdf46e83508bc1a54de6cab7263770f0c8118e54a247cf3cf285838cc97b4db9bd3b0a1f6e801e0c89677b0f40029f754d3ddffe57a264d4ab91b144e99975e73635b3bbfbb51557044bc92480e4f237dcb3bd3fd418b2728a618502a25181104b55a7333868b40917f598da682b05d04e264b0d62e03f9bf4a75de79c41b025ea8de06cd505aaf0c1a4930011237052ad55930fbb2bdc7b90f15987c74f3f73a4f9cbcb88627b068b0eb904e6ed69c7d49b494a6fdd9d75707932683d730e7999eaece076d7b979d5cdcc160ec42e4eb92ebc2d13e41c8bb6b4177bcb3a3b20b6859a3b955aac7ce11192a5995532b8a47a678ce0d4e14c939e703c024e6a89156de9cf6b2735e9e8794b34d32b21368488ef10577754513bb32fd7e455d91d536b4ebdce66e8aafe3eb2b5286f3afaad0cd92e69e316e997babba03d5c3f2396ed6823075b4037ad40e993def589efd82a70a97494bae451f188730f7dcf581693c934b33e7c4ce677f098ac83ca2bc4bbaaf97d429bbcadbd63e75cbdcc73e8f5bddd676a21d45cee1bf21fc983d3b2dac29ecb0acafae0657b7b22c7ea6d732505dbfd01b020c7fbd803e06d47de1341b941251f7775d4e49c15ccb3122a918017e7d96303f08e33eb0a8ccc316ff5c247f60cd987cc263b51c7d452427a8ab7675b7845f632f4d87170a4071c1025d60770c7c1424a38230c72c11ec5f4855134e69c7215322adf9f8867fab4cd61267d3036776ae0ed35b7ce0e988a0d6544d515c157d948d3194f26e2ccdef6f7bf4c65242ff4e941cb7cdad3f75b090c4b6ae587421ded826b28653c9b8ebe0af8886e5dbdfa5be76be3c1ae1e29d805fa86fe51ae67bd0f360ed430150a9dff2443a2c322827f7303a9ad4c6f51d6017bc2c6d6de63f5bd0dffe50baa73a769c45dad419be2f39cbe7b8497abc934e18947f4965cb4ce1a6e50589b9e4afc4ee1eb9727732b9c10214d48c062844279b8cc86646970995f4005328e79391658fd1b72af85da5bcaa36b15e50e5210b5548c5b27192ad38ad8705110832e4dadd848c8c2454cb19dfefa86f017ccd7b7e987620643d091e404fefa9515a417b6b7ae6f6ae8a2fe1c5f3fcb14998f54a2d3f876dd6ae222883774c4ed3e4b157123cdddb6b0f4e3bbdbad32957fde0ee629ef03f770bdf1151a5a038268a0e68d24437a6f042693cf30fdf322cbcdc49fac004fa7116b33545d95c860544050fc411e29227adec29e020619b08fa67cd03725c9e87cfae36bd8bcfc24526e5233ecfdf75a22585765ecd4199211f4411c805736ab49407438c27f9bd7521be9e72657f81b1cb1c1e0256f6c063d485ba4831db8e9724d959c0588a77ab1f41dbe6aa61b74a081080af875470eb6f0c15c3fc0619af033e15afa42e7893edabfd3a76999628a7eeac616dda8a0bb9aca7dbef1e23615207929798d12c40a5488c491dfe74b1b811c029451593b29ee4f605b48b86de7d5d2d6fbe53ecdccb4cb6a615b7d316e48dd917c5dde118185e1e515ca4302cf502f1346be269edc5dcbc44f7726011cd7b5bafaca794e16c9e5b16be249f8eeabb8684fa8aadc3ee03eaed9c2795ef9e9c6086f57ddcf2120cee5097447cf7328d4130eeee5c1f8e951a245a61774e642e092d6e595bd7f163059571581a296e59672578a1af57108f4c7b04dbce2147afa30b47ac27ddb3fdc7c2bf1d43db220c59260f598ec3a850c3ab6285459b3c7266cca4780bcceca3b4399e6573c7865eb0db3ba189d0e8685935aaca6367fa9966e8c334b7bb30c659e75340932b471de493d642d00f063e24677e9cfaaa2ccb423565c96fda5a13119abed25d9b90e86dc8a87cc2d808b5747090e3cc5d53ba4832461e8878928cc6ea400d458aad48430985ca16894277ac79ec80faccc74bc05fed1981856e0b17b45f0193e1387feb44501dd74389e8f30a1c5aea3b89d26145ecae15f1f70414678a518e8cad001be4e5b29fd409735489e3e1c9ce665470737e4ab2c27197988e2e6893fec92236a8f94a1cf6281adef6fef12a3e8546e7083e40b3271607d677bb07f86ef0a3dfc820f974f1b5fd00dabaad09ef957b82c843c29dd35eb02c8d82bfa0486d69e2b34bb68bd5a81384fd53d103718c21dc1510e5434dd095412c19687b5cbc10d724f85eda5da7d80eb4cc5733953c931586b72359951271e4ed4c721fbc2ad609e0d96f8803fc17de85e7370b04569e76c23e84bcff3855cd5164d9977c8a8d743aaca89a40d329165693647936d0eb51c33ca94b1ac649cd90694a2c30325e254a8851c59909c622efd5b74a332f336e459f23a3ecbec2772f7d06c925d66cf0a986a891bd1570ab8495bcc581a342f4b39e31e95d7c5d4d79e68d760076587a544ad2429de7d5992aacafdaa61010653cf6a8bf655366efbc3adce384ddb1d87d3b8c216a408172ba5790e5f73418d1ceb3c9a39b6baa93863580edb14d7db5846f9040c392f6767364d907fbc7a9a98b75da11eb6944bac47b71a5922db0b0f21287ac1af41324a759411b6e602c1974b5dd5dbcb0425279eae46090b424bdccbccb0088a778917acaa2b76fc2eb18340b992293c83967d9099ef41e4113fefdc4ea81e1a25ff25470d2fe62f8477624578ba759828928f855875f56e3aacf93c7d29d925705e733a07ea7d91e7a558a6267a2e33139b7fc84c7a0533421a46f572323fda7a02fdec202a8fd8a57d8a96d0937be61462f03a57ce9ebdbf2f39cebb918b4715eafbeddbc63fe5d913be6b6492aa8a4386c44aeeb9e79b3c7caf14657c4b3550cacb04417bed434af4c93d98dcc52872416931802d01aa3355ffb8eb321b437d154ec471f6ce55c844b531bb185fb9ee82a8bc336787d9d494ad58c1d337ae24c19969c5e99132aecbd9fa664e52eed9e86aca3dbb6d323af0e6e4fd61b58553fc3ebb050e80eb9bcc81c1981dfcf697b813a15ecd6f9d6830d1af28d0be7ebc32a6ea4e3389cef38a74304bf7222d2556ee5c0160df011ed34ace89881724c70d23cfb99c3a601672d2ea8b613e15ac3102a95cca3d9f88d2557e9766555145bcd76a35690469359575d67057eab17643ad65b5fee7608ddf823bfe3e88a351673b863eaecdfadf45760c31cd5533b27a5a11789646cd16ef79bd11f68fe896895d313b82688bf1e781ae706ee6268f043aac0dcaf3d7f2d9b9a99be7578cd3c42c90932070187a15e23708de95b4602ba2fc862ac0d03284d73e175245f39a77335f68e1fcc81387114f286f912a2b1845c33239dba8a732f6fd0c4824dd1ae95d87f946267087ae3ed330d76cdae5343d57768799fbae5077f8f7e98e793aa4ed0e09a732525563eeeb0bf5dc4a18b7a3ac17d89cd244dfebf06ddf91c8bc9555c8b0ed5cde04cd5cd1f0e50e7a4595e7391e8f899f18c1301d16eeac9e68dc13c1a8de8b3c7d74b46583dfa660025e06a2f155256a91230875a79c72b3b88d74a1cdc5912e77d60f912e645e51731b4af8ff18eb728d635dbe85a9a0fda53a1a378cff180cb392e23c960f6372dbdec9e9982ca04539819c9fcc5326166aa9feefb150b052c41fc806436dd5ff3d18eae603c985abf6e6d8e0f0aace1a8820d64409b150e76ce41afd8faf087d0c07429d89dd384b56f6571ec930c80fe76395a6776479f185f85c24dbb32fba9153042afd9e5eabd70deb5be080a05e1027b1182b3d2de30f38b8cd14d5729a7fd89bff2a0a4bfde7282cecbc6bbcf37e88a0225b6b31b575bf6d6da7a97e3c3643eb535c3f8aea44fbf122d7b41f5feb323d3ba1501f9cdf66ac280d4c87101295385f33749bf9bedd98a2738718d6d2b77cd1455a2bc00f75cb1f290685fd4d0a17b6fe5f39803c0934084e238484819fa09411af08d688775b099b20401c1d7dec084d971fd9df7a054f036fce7e0c6b23e1a4821b16a419331996a980f33a29674f695af44100ce1a7a559e09a6f4e4ddff7e82f2a8784aae2c38f1f33130779639068b3ba1a2161f84db0b8e740ca6067f26586f5292b721ecc115a11c530a68333d4bb5170aaf2c97e4624386d20028a53050c4433d8c9591aafa22dc83ffcfdffdc0ff47b201ffe4c1d99cccebcd96242ee86c57ec8c7c935ea1ba84eb3899485fd6bc501420afe672cc6a2a4a40a519182350b2b843e4a5470a6fe015dd7935b2518b2b7729259bb8c279a9ddd3fa9eb324ac305689f0ace51eb7ce99fa696b5166ac3bc1fb2bcb9890e19b343d0b299ca705fcad8bbc250b15564d15ebc62937c5740cf6b5e46a1e081759964b0a06cfba9f3178e6cbd95d8e26fae7daed5630f802ca5bd6fe659580b4637a0f4d9b3087b2ff1ab4736599b687fa7ba0841b7b2886aede8ef5ef8cdb5bb5f1cb811aab98ebbfca322f16380cf540f18fe2f3d8a0a3f925cc4af63587e6c1bcc356858430fc26639994e5f0ce0a97394854170f179beee502db69104d14d4d0d0fd23677648a847d4c414990e0e506031cf86c8ce761eead81c4c08848b697c8476fc65d2dbbe816f8394d7e87c137927a4877f3ade7d17784fa462fca892b3c0b0d182026a8b3d968c448b4e1165995bcb8d9d99a4cb18484917bd44c3a9bdbeb9ca538260fd6741f0b2c94e7b4a0eccdf86e9deca81660336cbe0b94920b42f375b23250f1a5bcf2ff2e06d5f7e10078b3f8a83255aa4b34fe25dc16f4ace23b3bf673110f4faa2e7bb5db709cb80979422f894d057b520fe58109b26889732ff9fd1ff2ff4ff50ff6f281c82335142b3285e147130da81f7ac23bcaff981cf4f2e1615bda934cab0555d26a649af28d77cda0e69f1cb3b4b730a53229e178b78076c247d397b913cf205353367d111c19761b2269162ee871ceee4d474395289678b7796737ebe8814917e5a12bf2897fcfc5437f16a9623da577936e2612375cf79475966e1e8528f6f4b47787b79e5f2ab489974dfde5aaeb9f54da48867252ae32dd5363239dd1531cbb4ceed48edf9f981cb13616ccfd5d1f4f2e6f9999f5f7816c8c1b35d95577e9eaba544f17653e699a4e69a32b1eb78735522423664280998d0c81eed933e5b4fd8abdea14a086b201c52fe9203a32295a0d3a522044aa69fb485738f0b8c83703ca316e7a007727850912c12b806c0cde0d2827c0d2dab2ddaef04874b5260e0998ca79e49d116c0925444242772a1ee81da19b4a120e8f08f9110a3a8473719fca3c87d66d4241b59d9a93d272d6c49a91c7a493beaadc33dd898095657799f6a7a6febcb602f2776f621eb3a5433793396c2fde8644744482ea9f6c68c56a657ea6ba91624d711e16a1126928dbcf06d6b7c2f1c820e050eeb29b43cf1a61772a3d854b092b11359d0d453edc310957b4abc0d98f186bb84e440fc046d85d9d813d9e715bcbaa70aeadacf2a4e64d8479a9d136b71cff84b951c213ecfb8e78bca1498759846cc630fb24f2d30c2a982f0580748473ba85ff860d7805461e41578406dbfb068e6a59126e60c6b91835248ed55ebd7f70b29bc262c59b86b3fcb994f472afbe90a5c8ecb9811623d9a37bd83c4e76c65091e163b990f08691acb920be2879e50e4d2b6876b6a3f22f419e7151e41fa67a2495bab25d0a84a21479e474c744fe4201c328004f1a01d32309068dad3f721bc4c3a58770a96d035cfb21e170b35d552fa423de835274f583be5191aacbba9afab8f629402c46319650aa7e6689a6078c1db931d1766b09e0d2790b7979051f6929f67c7dbc2d48e6f6736d0448a4df8fd2fb2c1be7ef28f4424a94b3cebe8de3aaf6d4d9577f2e46aae6ccf98c3fdd983d5d7547d1ba6279666d3852ea85b26d5eba79b7242aa51e56194f6c5613e04d0535f1ffaacb174ceae865b5855104116a901ff224275b933257de11c3962855dca86b0a2f60f46645993e5660d476a8c5fbdfd3efe27ca9dfaa63932841e3761ffcf6c5531320ea1d808148ed2b4772ab5511d82ec3ab12d9bb6f070e7e2a4b8b14ec2167360ed852bc0667b7c0df3f80d7c9375515a8448474fb0ae4515dd19cfc0d54de9b41a416c0f63af13a84281d891049b0ed71308050bfc0d1c76838fdd79fde554199daf437a335bf0d6f58d0297bcfebeb48c90791ac377bf201606825f30e57b955899357c200b9ee6baf3aa889fbb89162655678f5ed16fbdbc79f41daa9739d1be2ec20f70be8679fc0d1a91190e8dda176fc7966d2921862c8c96897a0d0fb0db119c1d248a23436d712e5cb66c244bd1b085183bb3dbc7c890fb6d854a8110b54097a613d581cc058943a4f9e67ee13e95cb2e66b2ad952dc4ce2eb10f53be9a9a3adde499fc5f8650d0ac6a1c380204a6c4b2d16dc205c2cfe12f36c988740a4bb8184c6b591703bd958c8301bd39ca31c0449480f44b6e19f6769a910c32c0557a9b98d42f6a2d97a668f6f19a1f6fa68a2f3a7a5194a6e97f30b3b86933cb3f996cfec674f25f6c203b60120fe1e9b6e7111ca6caf88da9b53cf2d3d35465b442677e7ec9b47135b3f0cd1852b923e1ac782716744374f5e7b26a7a12e0a66c2b2850bbcef353a670639a087b5b594cf5f853a887e38f23983e83fc851cd43be5ab756a439b7999e82bcd7dea66be94c3b8462941b49c69be1d810b8d6b8c67991a94cc836be889ee0398c69db3a3f96346ad99ee7224e7f7b146d410c62da3ebdcae035ca1f83b0b4c84bd4c2dda588ade3b22247027dfb5b04453c5caf63239e5b8573521d02af709c98a92491f2b6c388a3f857a86619cf399f13d5b4a781859ed4edf1fcbbb3b33c0ec3ea1ca4d4e9392fbc86aa87208ea5e3ab073af7e6ae0fae3b65cc6db125bdbe94027c27a1ce78b890ea97e49bdc7fae16432383168701a5981f0ab2aa220dcfb9b2999cc62a98fa206c9c719ca330f99638d96e78db5f9092d519d7596b60cd7088b8d08f4d4ae4b9a46aab73b656361007c42200dc0b8a04ddbb376ae1027f7cac1637a68d7bbb8ee03ea9e8bb8bda195b51a5288b15a7b1955c9ca16eed57ea772178e0ac5b9d023ec9791ae78900b8d9d6695bae20a130ed58ca3ea1da4c50916945263d9ca3999599ccd1215dc5a36534b3714ea619f594a2cfcfb3e457686c2799886748c725e465db72890aef9ed66d516df4ea837a5383caf7964da0af6218462329a2964760742167440ce0590484722c7eabe01bdeeebea39f3ad9456aac8a7587ffa4635d516ce563570cf251471963a6f74edd15db606b27743b2e328dd253631f9fe74066c573da39e709ec94093f7a8d0e49e41b826c6ff481f2c072907443eb85951a3ed6940ee5609a41256cf6f3e676bcc23ccd90cc13f7b3be740b7ef0af5785b786c5b711243cd6e851140b4e02c85d354f6d2dba84d2e40848ce9eaf9b297dd1b7656b4ab5081d742cd483be498eb22ccd48be13aa9a5ceb4972ac9aa22a2651dc843d0567ece7ba93b4395255caaf516f45ef0cfe62c460020d48baf072b2038921c2d816acd1b32738caccb9d5013fbd4434b9e5055079138770613c03da7021c88edda40ed618a20866b9692ce105ee31560b15bc8689e062d4f07dfa8b9bd983324eb12298e5dbdd3469abddf3f7f9b1687016c4f50202d9f5931a9efb1c213c1bc43a82fb081a11ea5630d98a71d039e6b8d4dfbc30257a13b7681a51d24dcf0687e6f05a221d7f09d5fd095e8959f2c57b81ddabad54d96a029a11eaca1e80197b7d4808ae4882da2b73cc2c74f3df4b75a67675dcc2d29ede1579042f902504c6c90d537b8ff9632d0ce4903efbcc6f7f49da07f6e38588381c3fc13476ccf09b64d6d55692d13b4612741e9b30d6680c7b7648921c8b68f56823f944f1883bb66eb4f0de99ba2d60201edeb290880bb93ee5c8d0d197a5bc02cd315ed2b4eea6cce9ee14dc44ef8dbfb5b2ce93df6c1255bd2f917137b65903403c9bc665f142e47d953d40d88613cd618c37028dc0e07aaa7f1090f0c4b3d85d4e3cf908ce8c091135b1e3cdd8a1b7379e7b09b29d5c15816b371eae464dd61ffe820c18b2bce4dbe00408a51bcf78634b9aaa8491ef96a80e6c501dc504997e89276a26fc1eaa9962a556ee9926ec9d747d6e9a05ebd9aad37c9f460c2b19ad30e0bfb5a865ae9abb91ddc31ef85ec78c76c3cfc588abba63a417c1c21e923cfc6e5c751cde0a689b96ad7cfd2388c92db063497d826836d271e45c85613d2553f1638e67e4e4d9ba07bf16df6d491e78763e34d64bdee9fffb4c78cf880c862fdd90598a7ddf33342917dd2082d80a3ec51f82b098f0c5cd4d12c06e72340e28219494969f4b008e12775353bf076e33d6c0a8c6195032a2415d72479c26afc68a2ff76cb989b1a5c84434e1d76ec509a10eb1b1c73f59e758e9e70bcd50b050eace14b1b56180a1b13c6f801dd05deb6970d9ec0be1043388fb9558aadfa2c01b7eed2418ab70e541d1dcb17de9295ac5025630e9b558edc260ec7f8594254f02704dcff06f6af5d01e07e15bf36f7d64912ffa190dc46782723e253d458b38390941c2b2020c63dfeb1075b594258a82d924a11829a079459c8499ebf42029d93a9f705d769b7e9989e77855b95bf755d3318acadd8219900a68dc0669e1357ea6e9304da16e6bd4be0cb457b2df774e08283a6a24b9bbc8b1a329a65371523836c08e6a14a84186012b8479578fd79332e33974c95b8d7476c4c0f97c5d6f9332d4df0608b2c29ede79cb8b1f4c3374497b7fd2d129e4368010ee49e1c05963a915c33dcfb8ab86fef81ba547cfef1feaa2e6542d26bb0e1bc36829f3bf5a8db2f522e320f60169bd63ba25b4abc490850bf7dc3593264fea29dda79c6075898e3d013ea818f037e75d28743d9f0fdbf4f9a3eb9f072408e0f46952ed061be2a4ada8b1c0f0483d4254725684a90a899edf9bf1ef983dac93151e111999fa62a52650a2078100cfa790b1f126bc828b7e8843ef959bfcf5c84a64ea56375c54e7d9d7597f6aaa0d6f7c951d8a9a9eaf273fded833a3a4642e02040e832f70b95e113faa445f60911d515ea6e86ad3b34021d4278f419acaa933d5bc0c5a90547262488fb8934a9a542146366058f8aa1f5b1ab66605df4be723e22686da0fb6c375ad0b2e33662e7d50dc2a23955631c8444392bf3081e870af3f91b1d5aca57b846c06de79db4f33eac64c8ea85dd0db2d073482bf1075aa3f6295ae374480d1f716e4c57a8973aed03e7f4ac77dc4302925c8f5397a88f3280802b846a44bd441a02c00e0f90b976db074b56a2c2bd081685115fe8c19423c010c4a2f6aac931850d92179da73cfc168707146c9f5a8c09005fcd6195639f572bf65bdfe2ac82877a1b03b3efa3d6faa9f49a4b2bc101634914e506f4c8a9e81950ed2ae663d2b3466208a48a6608df09b083012c32800be07038f8e08f9825abf66ecb3945f0004b06533a7e6f699b6d09d1623fb454454b5c0e2c65fd5b31659cde68b31d184128c7898f5648e1dc8cab119468fc508fcbc9d1cb0dd744aca861906c3274ab033dfca4af06d64084c4b03f7af32ef61f9dd3ce36f54b8caa0b164a9019ed28d7e9d76cdfaef7601d5242a88afeb7fba1bb613f73e1599738d779df0866ea395132ec88368de53edd8b2d49f2f04810a32382da364e6ca53d4ac6475e91eae8b104c00b5dbb2dfcaac9d741a8ee4112d1bf60349d2552332e6c44e9620f96648450c3f13da50d29c04df0209778bcb8e7550650e7455e41c22f26131cbc1a571269b9c2b1cfa11d79c6ad9ea29dc93d196f2a06ce1ae00be18c1e7b75cdf1dc2d683be4cdbb4260eda4b8eee453b19fd56d9f4917a3ea92b940f82fabb74441b2d1d40e14a16d551ca19e4f4f89dfc61b59980b4492d78a78ba810fa330e59d19209c732c59971ca982c97a49976d68f5c46a27d51a8e6b4b5903a16b6866cf6d627f9cc86da10dc4f7408890b05af0357ada31bc88b24f0c3ce3c065e57ba1d0b07ce932cc3798325d2ae3c40fa90ce135f4f1f4a48428a84907dbc1ca29e19c9d65ca83414ce4a903db6b1953ce8e0e80cc78bc74604ed554f851588170e672bba239a8cbc204bb37229798c1f889ad75c20a85f3529cf0e296b8d814c5264f564d0a9143b1b7b22956e16273149b25c51ca1ca8a1f6f7c639cf54db189d2bdaaa29dabac713bc88233583cb15b1e7a5547b1b25c408d9293f809f6f37cc9685e2a64eb9aad625df54502aad815ce511deea98e0f41f3013e1f8001011fbf257435487f2e781f03755860e90c192bc58125b3291bc6267027b8da3b6a029e97d388a160e097006dd24656c992d4df43f79097653b05889823fda9fa32d97434e9d217a9c7da2c38e60c8dbe224925b43cc51a0b82795c18b5179194852450fb8035b99adcae69ba870987d9bbc1a5df40325cc832a030bd0bfd15f395fa93ae6411a9dbdc84ec0017ee382ab2448308313fce1b446ef249e5946e8b3bdc941158d6f0047de120225a0ca8d1805132deac04e2d33e22715eefe5ffcbdd9b75278f336ba03f08d6620eb0ce95248ce31042082184dc9189799ef9f567e9794ab621e4edeeefebbdd73ea72ffa0db62ccb52a954e3534981140d547d41cca2814c84147e98b99a0a04c1461a1065786436591970bd95f855a0ef6e2aa8f56e146b112fcdecfae0087432f132e8d5015dd076b734af822d10c7fb45cc05a66ba409fbfb6edf3fd4e8f00b4ae8a01a4feffff3bb510e42f5120c80b10d967aa2276d073a21c15c3b4a9e8dfe424cb65b29127d514c825524261859584c224bb9484a45ec18bcd9da4bcdb6411713d8ef5eb439ab27a1820d4b8c9788ead09a406737dfa2c95d21f225d6b59ba1507eb21df728422670e9b1cb529d1f1949a84f83a45da249279316ed4d227b8866691e87f4cb2b380efcadce084548d5ba525a6478781586901a54e6976d20cf247054fa29132b5e41431301c869a82dbd262f8a57c07c28c52b06c8356a955ec385548ddc136dddacdf5998899b9b80147f2c5d717a4d3681ef6adf35b5027fc0be9c2ebb409f8d71271915bf164b2a61ad9da437b6b2803365498bc52c32ba17575e97c673f39441784b7ee5a92cea9a21d8fb7987608dfa81712bfbc00ee63bd950d5402e0d2517513061f0fb0c800dc17e4396c95f4e74f2438dd69eb192e470ed2d75594a0ff1b9c1da9b184117451cfc4b9a5137b5533c34a64f2f769392dc887bcb6a3096339710f261dedc6509d39fc0b6f132823131bbf2d2aedede124b63ca66b58c3182ed527c5fab4e6cb205003c203f3a5c99ec22275b5aec66ae4e1068ffe3af27f690d1007c5823d826ac13471ed4f9c45c7f24cf63b604ca6f99d1bbca118293ea65104762def9ce46ff85e576a9ddb33cdd22a3191cb1d6c4ccbd7c575b4d33baaf8f2fe8f1c0509a8618e0386bb3ca61a963c820cb506f7671a70c1edeccc50b2b1170000015841eec2db5d7bb2e936b92b1ea806bc078c5e571d8cd1828b9d283456447372f251ead099dcc565ce44fb0a0bad7589290daab54940eeb8a943a652208d668754738b87a0ea3360f79813f40b18fc725ec86aabd2585c2635c9fd5e3a691066277d20c046d226b16a5b955c77223bb027962e0d45260655ec11b22bb4d0df5686918be335e4aa949c6b7b522076f586df1140b7eb3278bf71ec5be7567538155431b56a3addce5273afe1ede36c1520ad3efdffef01d5da53ee6b02eb7a10a0607e616d7376f7486cb4715b0c9bc1c0bff941944c240b6b980a2cd09cca3c7100b6acc71a2bb6d2a10c6b4eaba62f8bd7f7ff48caddb2dccd9e037786d81635f486ed1df1e7cf12eba2411178a8626c8a5ac09122c91ff596391b860c50f0eb2485cf4e784544af1800a76ef96b8775a04c52125c42699dd79a3efbc3809a0a2f7ec281f166626dd2f25e974222e971b08b619bd0b61f33c3536afd095bbbba5a5d3a9465ed1482b21c626e6ac55fe13b5f7e839342954816f26b04d1494a08f5701af81d63f11079930ea42cb2e5183098fde48df2ce5835f621f3ca00c12a4612f3e19898cfca26271a0a0a278c2a5bb4907a8eb7d7e2743ac4c2b8958cac102cf499d7bae6deb0069c17fc9cf09068f45c541fd01a9ab83659c4955951666fd39e900b9fc410cc9f7ab0879a041b1e06b538b81a4ada2243d15f4b30e5c04e2160a82abb18674d8be79e0af22ab2c7845010fcacf24cf30f5ca2c6d3b01c1580c4ec81e6d4815949576769307ec8f1bfacb267a6a29cd30867df6167abd07fab0fdf912cf8941f50d8262f63ab5347431cc2939a611dc64d424acdf6ec2aee4a69ad30537d1d49da985aabede401b1fd134bc2a47cf7c584e80a4b440bc281268dbde3dfc9cde15b8abd8bf507da98925cceac3833ba5814705a4980325c36dedec2371d423e6a02dd8294f27b3afd94370ac07dd1f2f0d18d6d037f28afd43cc5218eb1b5e9c87b0d3db943ea2d3ad1e75a3d96dc52588ee4ae296977d274858825921d7c2a8189a7313b875d006dea70b3cc44261943dc6521072d0247dacf6a25c25cf6a2b13b7bd7ec363bc51a0cab714f96514afcd183e13ec188c368544df1ca5747cc4e2d31f3d90c201eae349c1c6b5cf8b0b687af62a24af2141fc76431a8cc8234741bc8886a7cc9b54f0659cc6f62d9c2e3fc443deb3a7af834ce271e1c233ea61395c3064718ffde82a7ac897748d3e6e7e9cce9725237cbc6f925fcaebc596c1ca14f1390f5027f1afe6b8963a5ba83a8339dd5381324f82bc98598b5e445b7a6744a5f0757ed2d1d406281a86d133e7a6c75a3801ced25b179310ceb013a5dc8c54b3d147fb61e9f3f450a07a32e7b35bfcd3ec9ae7ecf904caec8a576d4283508df698174caa8c64aacb24594e5fb02653b37ba60ddb99d893534cd81820b23dac76e3abea73c68b5766163c626ca4da46a7e7e2bccc50ea7ee55b363eb82ac4ae9294af38e1ec6b852e41ef64983d0f906c39008adceec869336fd73f846c8c1fab6af157a1bb06de3085561fcc7cabbd8c2a615e738a9d3cff934eb6b427641a4848aa4c73673364aecf50fac94ef04693f22f27288f8a634fd999be9c8112da3757641aefffe11448cc92624a542d9a0d9466f8e7b371bdbf68621acacbfdcd89592284d9dbe85cf7af4887e0ebe385440a9d0fa23101acb737ab30cae99c8e68c6091857549bb1a7bc9f0ccbe65fd9be6aa8b7f9b34fe8a608fd70b1000c983a49c6b764bd488880ec30f332c4e1b4a47d3228884c31bb73538610c3f48219a06cc4e9caf118e268fdef1b6ef960f22c15ec7659edeea3c68fdcf791a47412ac8ad6d9020b1b0c58aa232806ae83a6f21864b7dd9faf9d7ba2ff460ba7d5b13d00beb832186ee13a1253b45d84abf0d200177bcad0def028513e2c4aba82e287da8e079d179ccb82a43b825384f6718f0152665649330638c81051c4ed4c64ce9b5726e9db5f0d666c3a33c84e47946f1fc39499d7e3da52c9c2dcd9650c5e9ddd50055388279d2257e5fbc25058a2c6d3825bef732070cb4262592e3f036e5b30110b3ac7a9936ca8a97923fbeff0f41a8584c97ce1584da2709b8bb41cf2ec35a179520bdbaf270f5dee65b7706bd1d14f705421c9950028d75639deb8611b5f59e7c6cf757ef8d7d759966b2ed6b99d4c533280500e87aea0b1a486f11904a4cbe5047acfd9a1c8e1390a45239da0bb2598a01befe56cfaae1e809f9ca2f3076b2f17b363065a680c93c36f8aa8b4a1fc8d8e09078164db0d065c4596d9083fc607dbbbf2a1ded50f75873b9b3c5c92847c41c4ad818ef263fcb13efcbb184fad2de229b7cd0ca5f521b46d1a55dabb7b510ba238bff7ed7da8454ccde42dae45d05d2f901d19a9d87555993804d05ee3181f4fa3cafede1e03693d7bfb6528c1c2a3f692e36019132c2f14ed657eae61a41f7ebce976678ef7545f16176ff2d5ae3da99c24b733338739adfb7c86017b603a427d7697eca8fe8bb873d62b91ff883061a2382c42dfb2b2d14a53dfc331e6e4f201e6a49ea171bfe6c74f01baa17d185aab0c996edeb4921fca3c1d680f08fa7717ccdf170cf0b0580033ad6b2b1e404d429fb7c5ec30b4ea8a7f97acabd72db3e9de46cfd1b66fc3ec7fd3021e4c11f6eb13f228c423dccee3da67a1e5c636d6ca2cf56e2d6e52c1639651bb3cdb229b275a0844658efd49a7c24e7acafb2c86bfbe94790aa81863cca7b7644da59c1d348dd5ebec629f6779f5f039cab3aa8d9eddfb98299c639d99131d2b85c8b1054f975a535e87ec22060129230730fb86bb252a674dee0430d38e35ca2389f5f82dec343896656f9eca71fbf29603771f609562f858e6b1efa8211ee9362846e30e9479efb318e800d16353997199009971c494bd92bda9a95ef3251f829b9ba2455ecaebb99b2949eed95935d593da0fc23ac69ac782ead463fedf3b8a7206e86a3088cb6a2c48dce4105f1bb98a0e4987e66498f9d33cc9f7b3521345c5841f6917259e1a9db21cc9126f6727a8ae4c8175ddeb294612b5fa6bca6f8335d0395631e48658092697fe21a5b7d9f86af6c7ca8ca5c70973bf6b53f93d5b4bd52b4630e1aad003e2a4ed99c330874e99847673a0ef2d45bc986e42566341b77cc7ce6301f62e86400c4c3a2fd16224e004d8cc8e4717d3e536d7271a8e16764f034300f8bb5bb5ca8a1bf53532a5ef9ef8214386d3d633124cb05de9df66bea1bc890950be37b2bd37777fb5eaaefedb9f46311ec7dd0eaab69dffbafe28a457b3a36069aa82cc7b2af3c779bf91799ffc47f34ef674f87ddea5fbc6fe6fcc3b42547d3ad5124b21b4e1995c9f5efee9fb77a67eb90aa7ff7215e263eaaf643bf19c6bfc6130569b360d0022613065ae5b7d4921ff4fe3c9c97870f84df54042f1e3e39a75c93424896b723e1cc743a90cd6f7b9f8a84e6687a17ca9fddcd873edfa99e1ef687ed9dc5ac67e1f6594ad8a62dff795a9ee44840d213e6a053fb2c935b33eea129a2d9bb158435d9ae090f644d1bc71a7823d28be7002675c3916291c894c2e56efcae83dbf7c1cb6990252c441299e1869937e128b170d0e720ca6115c2ad8e6e5bb50bd7e2bc14f738e2a61181e7cf87ba0154badbc5525064fd166003e86ba60502c712a9a6570acf6b46bb5a99327c82cf1e1ae62f5feecd72385d305ae71f4f9b35a5e46f24fa3fb5b44943553b49dd758bfeaa24d82531f350af3d2ac7ed391421b6bca4fdd13fc42cdf4639851fa06ba586b8801eddd466025f388e270312b08b620885186c923f5394e0cefc0f88941378a6918c278c298890e433891e123d5d69d75e32c5d69e81040c5caf80cd16466b6ccf3acb8bed0cb1e17ebd5cb17806579197e31b6816b34f2931259efa26c54b087cd79ef8af71e186b7a046ad45b8592daaa16a233910fd6b6d82dad19a0da1a89a64be937453d27e42335998f88858e5cf2679fa1dc90580f619c7d53f900e2aa1790c3f3d0af457754b3f0622776a3e52a86e7bd9d38d8df0a85c21f2f91fee2339770ff1df64b2f65ce9ec7c1d1a74037ab10f5a55344e0241956aa4937c116c8a86a87aff3fa6d3b575e1a8e17e5c34b784b5d760273defda61eb95ad3ad2814e32eb6aa30f3fa528265fb481f1a2437fa0589fe98985c77974bc4078beaa2528e5b73c26eb7ca648f022b4293d98d68fa562d9080fb25a13dab827ddf51e67e5a2184273d61c9b5663847458dc461b99d524c03ad3e70b8124597a7acda282c4d682e66104683e62c57ee630d42fa90b02a528a48ee4ff0324fcdd51f9e0a0e38e583ec54c4624b85335d8e959d1f48559ef96d645c0c40a0ade9c271ecbedd6eacce8d9255f66e7e4555af72e117dabef0148c7f5c40a0dce086573f4e647f8fe2dc0e789a17e856794332507381221933bd7f88064b57db7f3bd681f8afd98de8873294f3719bf7233761af84bd7169070508ac2b5cb65c0a1ece482c7826ac1ac4c8fd56e9859c668cb2d0079decaa87af0238c06b0278814a8aeb9fcd8877bfb5cfd75fa11c4ba10ccca1d548afcee13d1369ed2706968e6275ea73b76e0e25ab95cebda63d6127d1f2d4ecdcc36412fc7822e05a7bafcb8961283c39c0324e4a65f6791c9df5f9bc1f9d4ff08dc4e99d98fb0227fd6b9ef00a2d52e84a7cf20d556de72fd6672875ec7244d57ac8bf8125525b1bb064524e4f574682ea295bad4c58f5a9a2242ab296ec5794b1fb45dcffe059aea4bce3914ccb27d33e12016ac440cd7a1691c4ae94478e619bb53922ea1bf3aa1408f694817bec2c94b6afb70d9107ba4aadcd692b41dcc7adcb78fcb043a9c80fcb450b9bd02beae5187e9a27c4d55c2798b2316888c108dc1dd2c897eb02b1eab1febe1033e8458989bdd5d2c4111e5e4fe2dfef284364a63d337cc7aca43edb44f00e81db56cfc078304ada8ceee2a80e75843bda812faa9c8525c7b811f702b93a351381a4b5cb1344a26a9631b82b143a6acf3fa3c96209cd4925b5e1f648c6d4e0b56c6a99c2480db6729a49b7d13fc7d2dae29f5e8ab9a4fe9e651aefc8a7998c964c54ecd96ebfe1766b0e68511f90d7ec53125d6825a01473a14bd56400905ffbe9cc09eb2d1bc28bb0fe39b7fe59ae7f873c7dc81cb68eabce5efe49020992c050974002dd09fbe554cef12d2ce6d931022915ef724c0a2615503a3e9c53c1d36f54b064a1bccd39157cc789409a2c2e89408a418e84086494874624d09f13c153a975f61d7dedc0172850de270db10b1d82e5f69c047c55196861ec5d5af70a633b06d39cddfd6617399931bb69dbee1c29206229beacbe84a6e5e12eee01657d92d0bf1f618db323ccb31a97a4d2510830f7404c9af16643f8baf8bb1af377b03d166f7bde8de98edb23d0dcaa197c739061ad83718c3f5ba93c2a82bfd623496bb64be5cf4cd88525fc2fa5be989d71d0e18dc39831cd3a3a6a7c757ffb17ef9e3e60ad53d5644d354e953f9f4b1f40267c47edcf679a30d5c504acdf313a097a7ce727b1e9633894d1580c0c7717d310bec9dbe9d8a328a8134d879998f8372201ce6afd4c3efdb5ffe853111380ad85a048eff538f93be7d1d69c9d47cb802b45e419aa726185bdf498095dc4bdcb7040d74beb511c7e39026e774ec095a6c83181ca65ab7b5da06a427a3f81f4b2d9eac688b396e236015f4a3a27f6abb41415eebf267ddbcdc2a09b7cb67abf7c8b494f856cb5b5eff24e05c6df42b6da29e214cd67ab777c49cebe6fb13a0fe2afc6860523acf1a29c70130199c4dc1245a99e6df7d83e5ba58c3a946c9cf8315e3471090fa9f228418554da99b8c15bd129fe34144ecb64c34921ca9f10c3595fe2d968f6dfd2166ef27532978a3071f018fc6ff1c2a8a27935f9b33625523c054d790e83176ab01b09f3c7207e590b33abd89302d1ae1b139343dcd56cd7411499cf5c979708e0d84cb16ec2bb80ab0db7e1410154b9d156e0d5d221a2980a24b67f4119bc19a3be9a3d911daaa0d48eeb600bcce1374352ab6a327c11575ae10d18bdf9798d644b1def20acecee5496174b7ab635bf16182c56fe9b0283cbe9c52bf65b2764d877b09c8529cb3b526f3fded1b6ba8844ed36466f6138dbc1d027d718b89a58d1136681278019c620a4d8fb7fd479133fa4495eaff3966e9c77f06b0d82dec46ea9b70846e2124a6c50f98b1270249eba32efebdb64583360f4c200184f99c7e5987b72b58dd35fa30c8bd34c5bee889a13e7b7316de6a06fb6a21cf8ca3c1b1670b04c920865578ac8e57be7df9ed888f89bec286f45188bdce68c906b1356e0bb7515f8a23134ed61b1dc5e1084dd18ecd34e286cb7140ba442daa772faa8541db6acbaee586966223f08b6979ed0c256898cdc7d9db9361ba27a26282fc2a0e9bde312d10e18259d34821c1407732644ca62cd378bd3a76b68069fed6222133debe39d897539038f333933e7e5d6628755a9bd32094468bfbf75b26a9b23b1fdd986fe0e42ee799b96087492181928ef5079399fe7fecec9ad9195a78341173df96e3b1145e95bf89571e63588836eb26faad86341d89216df1e734fbecf5f3c8f381f945229049ce0bf3d48470b64870507565776c08e4b3a1659e1d3d1583dcce228d31fdeaaff58dd2fa8e59f1f38a85fe6b461503903a8eb2dffdcd0e7febea61eea7edfbadff0a0b269612828b0a42cacc68e88166b84987a45cd2faa2cc504bbd999d0dc6f68346eb1673341dba602d087a7722ed92dd67991b173646e0972d1de4a48c676d352a66016f4bfbd2776b1f4fdce0928b8aff946f25fa886fa47a644f7f77ecc6a30e0519fbc5367cdfe80d881a141bd487bd70de8f96380f56e1c1f933dabc2d3348ae6aab17e4cd69527a53f132153b5a31ea1f4b0fa1a723a3a925448caa55bf82623612c48c1a5bcca0ac52d9460f10bf8a81a330882395dc35244c76e1501899ffc24561fb86d55561a1c68c8964709ecbf0bc7d754a6ac499943d979633d92eeb2ecae9d5b8999555e3ce7e1f8b1a0f9a5ec1c7db1cdb40b4b7660335d199fc970339553b1948912a3cc65ea8a77b6ffd21d22869b840bae151b6e1f5935342ddeea0da132eb251c83c19c85c95a08c7a4e11f2ff795fab8b387097374839cf306562ecea93a32a9396a6e2d3eee3c7ba93366dd724295fd653ee5796c90e980b1a68b0e3d353732a53f4ec6d81bf12ea8a429318dfd98e0f52eac9e0350719960ca9e6d2a96074ef09e187f85b20e25c4a63aec0d12e88e7b639632e7f060a2346e5d998d769b6f8eebf4a39a112ccc5ea6fecfb65e9eb04b173573917c5e53b50757cccb1dce2356eb7dc8bf431261d07c54a437817d169475fff17c5696e78787a3634923234afc80b3926b5e9995f281b39238fcafccca76ccb46dfc7aaec6eec08ff24134127bd435ecabf35b8a4d44fdcb414af216f65dfe43fdcafc797f317f3bcedfa0067bc7b85636b72205a208f2412a628712a814c35b0950fe56625d6fea727e20a4d48becba71a9d33fe96457557f973a33625773fd9abbfe65c41bfacf3ff290e8389792954b00c44e1c569431d8e9595e47033932ba925efc8540ea89d94bdef6cd4cf7ee15d5ed741e214de1be39c451565f555615ae6e47992a59d14a8e49cbe2bd81ce7e536fec288f863157c76a8d5cf0e6408f6ed9c28e1509918e5979ab180e2c3ddb76b00f9bf9df73daaf25fb2d6cef472de9bb17f39b0b51b9362bcdf23172d29acf98ebb92e3104af17ee68c9f08be671c0354efdf06d4bccfd59c3d8e70b50c3c1fbbd158f934079b3caababd6f49bfc46b4ce4ac87c1da51ddfffdc71862b8a42ded56841e6eb30f0c3dc0e167f6f49fa0b3971165722290464e4fa6a78743c5ed2e875f2c430b23b3a144dd9bb6cd3b432cb722d7ec28e5b90d4ea7c338dca67f2e4e8fe6ce74b8e53a4ee2a44b941d4f081b8ecdd2cf5c57edd49c1c870bfbac77c8aa743fa62ed5cc742562aff07663a191a729612fffecbbcdeec8cfb86062b30a5a4eedec1c9e7009113869a8585a09e58333ee5b0a32873644ddf466a6859a7b731c3963b4754bb04477d9dd90f83cd5ff75e6ee256eee95adf3333a7214e4293e8bd65b92e6712bc600daf3788cf7131e437154884c58818f12914d2b6b7b42bc0169e2e89e33d50e671313ea7b7100e1c39d6c177211db3acef7b6436704273397e322c24de76d98d914248c18ead9b8edf9c6d166f46b3ace35aa997b881a03a847d2a28dfc32957ba3feb60f984e3c69c06673848fd8a52e34a5ea439291070f5e5aa959c5755300a86b5e84397fd509a8bfcd7847ffeb10c052c6f2b7f8877ee32369604fa593104ceb106630fc8ac535ac78feeabeba12b518aa49ebe293e218e71c32e4b6dca1204ba822a26e12c87fbb8aeb6bd0fd7a0ac373f6b4b3a8b71cbbef62df7704d580c94071aac4d03776698bb19e3b5a682dd10308d8d1a25e728383167bfea64e13a82c02117c43f49b5202e9b8196e7b21e64eaadfe294e37012503f90136d0767c4eeb9b98f5614958ece4d228b535434703b491464f35d55dae7af5a0f442a608dc3c2b53367306a94048c3668a30fe6a87ff6bd8ff7dd8ffd5c3bb1f61e306ab3d4a39c86aee330aa3d96725bda22849198c8b0154aee4ae4eaa57b79ab0c7f3ed8270b260235004db99f9953b3874d5dc0ba780c1c8ed8c703fd6d3abed2ac92fe5832c6b015cedf7ea464af19a09d4f3b44ef68d5243b3851f6fe4d3e3fc91946c7be45989a828b23bcd0bed1b64b2f44d116ee57adbb29c85550cf72fc1dcde3bbc2849a1b022ec46976997970a35915dfe2381e8915e0a53029f8daf9a197b0a3cd239f09ede889380940a4b2803279f67bc153a73a282fe3565463fcce98a345bce9e956e3e2b6174c3324c09c68abc1644442ed1d4d33dbd630cabf479f167bbe2c6e137cb94595604537b5d992710f1d3e80bac3ba2f8d45cc87f0d77a1d8dbb603894303bb86916aa4cba21af5f761752e154cd0e12cbc39dc9304acc8366edbb378d05629cc30bc30d07ff7527b1b8ac6ce8581d9217fc65f5f3fce8588116de065749f91d0614f73a21d90e730bdc045262ccbe29576155c2c2f5a9fc76bbe93b2c4f237e6b06a6e447cf79206a0e64ceecad7370f7d29ed0c295a4a0549e38665d34f9135b72b12504024296cd54cfeda5b55fd86de84a9ce9dd308be53e0c67a9b839cc335c9e1cedc7e9e8d6e353d8bda5ef393367af0c950b33efe6d47f51a468cc2bc79c2e3a78730eca7aebc9c4075ee24141ea838de48af17e7ab11af6e7e960924c6d4ac68342bf9e48b0967e854d04fe8ffcca638945f73569ba2fbaaae4c46cfbe63babd79ca67c5f04248bd176ea5fa066591810f531b266231ca2992d06b9a4ef025e3b9edf1d5524d08200fc1112936ca7d9a25712b721c24429bf9b63b2dd5d4b77bda3c4ef1dbdec8deae2befb57441e6d9a18492c09fc54cfcdd2f648e733e3e852d65defed6bcc54f783755243e3b3535e53f3899dfa3a8f679958051ef412080e888f9931d06a94d46196fd2fc7d1079ae97b33439f6907a8a7620e6b06ee59568357dbb096beac3f6f6aae674ad13473e85408f7af609f3bbfb80c96aa0f3504ceacb9624c865f84dd862ef32d5f5c2c78fb7db6f2ad397d41df5859ab7a9b3f6fd818e6faa19dc54bf5b78fc99c42635a458e02b4da12151e4f7ae781d262713272573a0ce779cff1de675d24bee40daf6eb9b27f8ed6708e6f7337a7e3827c7f43e56e6de5138a1e65d9174bae47ba7d3ef2be69c5e82e1d0e1239df1bd8853a95b826c009e4475d78d303b66c1b2f4dbe6bf495c39a8839dd44ab03d2232f2947928652eec9ec549c5cadefd69c5c8c0e7c035ef8e02aa97dbeeaf8b5b53b589b958cd2c39027dc6a7f33915e19599e8bf7baeac84d0b1cc16a52084d079e640b4e931ba4202b92444651bf75bb497fc958a050c9c9d3981e4beaffc8bcd50788d1f37d9a36480139bd92dadcced461fa5b6e4d57d56d6aeef68774eb514773541fefd1faf7afd4f7cedeaeafad53f2c1facd7979bf1313afa1cfe023466399697f1046f53e5d52343217aa7c49ff85aba6155808c393c860f8db552bd624a7c82e39bf3ed7935c2c2fc0711169e8bb0b86400cb50e8246c50458deee2426afbf00185e26973b1ff375d6764b9901c24c6252ae93615a0f732d0d3cce391d545184c74a06ad2c8f8710c90914f0914993a0267742458568f87d226a72fecbd729677a5c7daeece4ef604788d5e3f80fc311718cdcd511252991cbd9f41d2fd2af64582660eaf7d50f142430519cde0da88772ea36a7992c742bcc9ffc92f8539e1da9732224a72c004db621a849f5753e63b2a5195224c2261520a9c84be8413b9b9c9c034b4d1a56d3829fe67f8546c6272f189e928d5193e92da199fdf281a8998e908729da407e424c76abd04d2cb4013d43922cdb7287266f3400b000f6439990a440b9fb6885c7e8ec2c114a9da443c9027422936e6c483ddd2e1e8ef72f44f0c1036e1ef6914ad1fa41a45bc999be2055d96920a584b8991e8c447fcb571f678157066eb259e0134ca4e244570bc082f9a4d45d0545b455a76973469b74e1287254bf4996c283fc71724e8b26ed1fc8725d9d17595a8262fc07473f4f7d0838a8f8ce1e972a2fc5c2f790d5077cfe0d34a04a8bb00d78e23eaeeaac9960a5686f5a8a2f5dbc7ca269609f32d7514fa5fb1f36faedf920d35d341dfa1ea1481b52250134d01c940daa037d1ddf044bc9b61281f0518a43f4b4fd4b6507e5f3526b717499e82d6e48ea4435ac70fbae5374fcf6fb068efa863d9e8a5cf6484b3528f777c64b4a1609b0bcd9585246e68b224294802d54d9c1646420bc3182d483c3b53e02e0709c1d85be9b178454fa8fbf72233f4c550b9034052367a23e1adc78a52d9caaae91a59d16692e1615ba5c5e4ec9be299ba7f9eb3bc00451dbbc0f15f4a15030657ad9a88c830b3bebeaa09ed77c655be72e93ba3a733b168bc8e89f9191ccb60b60f9c6c5a36cddfd8fc0ccaab4f5870b545fbd77fc30398d4ed80bbd75eb4f3cdbb9388e65e2cdfc65f91fdf4c9daff1604b61422f877762d2b555ce0607fa95af172d7aeeb11d73dd663792dfb495c3dedd83dfba2624b14585a2c17fcee0e13562af84f639c7fc582ff54b6bbabd2d70b58244b057fa8fb764f160a7e461fe8bf2a51f0d888d49d8fef404acf841061f15e06ee8c1b51e9d4565f024506fc9735da99fd92184a1801255f28fec49f66006ac6bd4e8ee50d8e89601d3052723b737b0985140424d4eeb365c1df5d3c3b26a10bb999fb9b99898a0ea4f651a411c3940e5a80959b1951e9f2f6a436b94ad98f3665c98f0294e65f71023b0cb1957715b95ca26b6983a807ef39d7c5ee7b3f8befa6f9c3ad7927a4eb5985d26facee98c8aa7f250e66300a6fa3f7c79f753403d598e8edd93bdbd383b9141445feb843e1908cb8049302f41bdfde59e61afd7fe270f7369502873b95545257f4955cdbe548894ed6a4798969118072f1054a4cd8c58013de180ef425c328aefe458651bbe41703183d3c86203706b0add75f45e58f84e29509add822ce5232a68bb40cbf9837d397a7417eae1d3938d870179f91803eed0d04c7357a24aae89c12df5cf1c282c6a4ffd0f46a80eca28abf4be0af308ffd84788caf92b3d6f6dca998db8612b3dd8856d9a871ee00b2d978eaef2f8c80bf0585fb935874f99508eb6cf5fc08fd199d6efe109d5ed6d077062f105aa62f65fd49e70c0be3a5b5046eac6fed8955acccbba1d3c56c3465a82b4e97d2ff82d3e59a77254bbb699322d8fb444a799f393c8ee2f0181cd9cf94e063cd3241fe63ae97ba65437fed75497d5e785d468b6b5e97ff30e7225066e0b128aa514571178d712237b3880658d771d8cdeaaa4c4fccec7fcc54b01453c1ec5f12d8463800fe9eba26129b3349017cb34324e4ff8abd33e830c361932d8bdcf67d21b715014fe2e4b6e5f6ff92b605b92d119cad4e5c5b9e92b97691e9e9d21b32dedf9697fff5f3f4ea84a705a76c231bf752e92547c8001551eac794fe4f89cf2d2b5916f7e725b3193dee96e5ef8856c293eac54f885677ff50b4f2267a7f7b4e0a7d1d993059f6433ca942e3b261bd3726605f5a9f299a999571a8cf65e649fd4ddfd3151b6ddc4d57533e02c91b70a011d3a9a6ce6cab9ba1f04a04c0eec73fbd3dc21824e4654cc95722f617c2bdc1f5ccc638e74dff99cc04c50fbdc1bf69838e7f9fd89d6737f02aac6f2a35daf3ae5ba07d150888692a413d39913f67bb671ec322c2429cc7f07c39ff7d8fa1f85332fbd8aa453e4371805e5b3449ce3ecefe55a761661fce6ec7b67852d748235ae6be56e64dfc80179e3b3b8ff0dcfd696dae79eea46cf8ec5ad40267c083bba0a2647afe6a77bbc0888184f5384f420a31035ec15c1ec357ccce0cfefbdb66e69d4eb3e0f6a273a54db66bf7bac8e009eac9574dd18850630ad611355050c2aec292b03d78634eac8d7216f9660667267998a025133bd16726ab3447549f6ae5aba151bef8d3283fbd3be77d7797ea87f833f059de40cffbe7d379e6af90fc918b35a3436c0f91e4ba6dbf4b8daebc355726d4ad34a41823d6f03f4d6cdc9b819e873a47965cbeeacd58554031f95652caf45dfa3246de5f4d5bdcea336cc7ac3e6796da212cb5031d0c9da5b6fc372db5b98539b7a7062a78ce33baa36097f9f6936faa0f9f50635faaf65f1a2643f04e27ad216849053bbb8af5a2f9dd12e94796c81f1cf637752cf80b752c5f3d1790ff993ab6329b7366f29beebc91f0e2a3e8ce97e33f5784a13a9bb37823fbbf1f4a2fd2b4424d55c15a5ba848c63efaee28d549d09ddb582036efa72f6777eecbe12e7be6265b3c406a5e3f848ae6e95cd1dc0235a958818756f52bb6c34125522d13c88ab4949585b2d3dc816fd5d7acaa9b0389bea66839594aba1f39e21b6ce0260c748ba1837d0ece72c6784d76fe353dd3325c66a42a26e36784550f3732f170cc236104c9f892399f7dc049707a5063c66e2474e62059e18758d8dc69cf88ae4a2c6c4ef2d1e26500c47dec0d0c6b0ac6babb59c63c2dae2e80441c3082202851d6ce1462f36142749630bae3ca7b0d81a482ec5160b7f6f45989d5a05376ce0f94dbaacc2c8baae10c08c6c18ff0af0608e5e1ef857ffd140698cd65978d515d1bbdd9ff12dd21128b4008c502955b2a80dc5895fcd7abd12adeafd12aea6ab48af70fa59a2b1ff21f05af1cc69edd13d9b1f7cf8357eaaa3631dbd6392d5d8bc35c91861851c22ca3fd4180190ec26bec85aeab3b9df92604c592a7870416058c8775552d24367e6722e46b1e20391440f5de495654e33aa783f98d426be07a55e5e23bcf8233132c255bee25ff7928e6c42740d13924ba44583d44836d287fa57fecca634ec7b32027d82eed23c3e13dcbc036d08edf55dc38e6e2892dd7b1c2474ec2bb24e0527817e33627920b50fa0fc32cafa56e238d3623343967ca640262b079283d441ad02af847d9012dbb43e2f164d7229840faedf21f9688d516917d37f3678733a6352032df9ebe9a3651b433bf052eed8233b5dd95ad9de2dfc41d59fbda2882c9609ab67d013bdcf5a19814f5d9155fd0476726886071aa91c65e1ce8e4799a9718005c1e57ff1b3f177dc1b73bcc62593737b4c3be1eb2e7699fe36e524a44426cb1b2f2a1164cdfadc477a30f84675b796eaef20723c915270ac2962081d49aee9d936fa2a0e3400c637cc4cacbc86300d483656f94b9dd0b38557340f0848121027a3f731b1488027946b966a22faa4c37c6bbe8b73dcbe4f0fd85088002f3e7f5e7b18713e803e2b539982d24a9b12e42815e646e3dbe769eb94de82c8596cced4e331f7d9eb95d9b2182c76799db8d77f492d7eb3133d0051f5f176b67410b067c67e559021b57e8eb5b92bd6fbc64574d33b7a9caec786e3f3a727ebf38cf37b511e4a139097120a9757dc1e7cd911073faec8a23c4910990bfcc2ca4eef429b9d476472c9a7f224a2910b73629d182b6c2791d5d56aed2e5f6fdfca923659233c2dcdc8ff41e9499d5450cdd9b54a7fce088f086ab98c123c513e8008c97da9970e46aba492d8295153c3ca6298eaf92dc3566591fd861dcff3b7c520ee969421eee32d01af9032638dd471584b257cc4ede460f8f02ca323afe7ada9981595339ecdcbc2563c858a7a19df11aa0cfeed4d11590e3cdcd1c0c2d48a1e6dccc389c29f2b956e60dd692cfddb91c985f4481cebe32df9ff1a3be47f31c46b61243d4fe4c18e80e86e79915e7c1c987a94070b495ff9abb8b09ea8d896476f294f8cf04ab6875b23a067b30d85d46954f9690a1964baff6a7406e9aea9aca04855ab2a9fca7e9e739e1ae8f71b02a9a6158b967ae375e617e969bd853ea2bc1383d78893a7d97a2b60e54a35c79bfd018e23aaab0d4f60dea10fa33ef9a969abd179fe1e4422ef9a9a6e6fe8c6935bc1011fbc733d08bf2fe4ce128d2e4bfedfe6321f9876135b696b9b8de92bbd8703fa4e2c683dd03c11f645fe491a5c401f6af1334bc6842d1b12d36d4f67ae2826c8e31839ec487b3e6792d03f3997916ac15d7133178297585397ed7e224d2f4a4d4e838875ba71662b6b42403ab36a22f64b3a577674be6e2a7fa325bfd1fcd9c4f23c7a5a63fa876a41fa8519214edd1e267b484844ae13ca26326d9b307d51a261533d219c6134859f9593c766af80f221ef3bd98efc77e89252289e6a8ddf0c3fd0c31f26733f960ce328bf29e797f6684783f77c25dc64278776be4c84c1ad0e7e78d192d19931ef3b416fc320787b9064bf5817752c5689f37837334c996c8120bbde69d12ef8cf5accd50c18598895a92776f0508711a5315126c5331db9c239efaef625966f912f32da89b82c1b92ee958a8a06a4aa5234862e29f2f574604b6afc888d9c479ef05d3a2978c90e37dc6106ce29a5a49ca9ac0f0d61b2c047074c065a8c2a67c8214f12156417c9647a01098225484d948a0e7bcde1da57e9798c4903e66b6cf94d7733fef7e14b8bbf6cf1464a03f8bf655e09ae5f94fe13b1956ceadf5bb96442ba317ea97371fc9b0d09a6d18a8a196f4c31bb84da6a640324cebe4d02835362514109c315f76f7968c2a4c1be6ef07f184d99af29e89b03fd5a70a5e265ac8d0487e7dbd8deae724bf3948b8498ec27a69a27a2f198ff43241362d0f5e8692f6013d53a4dd272c97cd92b65d753bd423466fa006af657fbba8c06f75e9c6605771083072a9ab7c744539fc68fe44e56f4b297d3413a59085f29a5195e560cfefeb1cf0aff9b6f4793e184f99c69a65217696639b815e21d4a3978729a255de9f25666c5940ac27cfacce73aab679caa85efcfb86f62b5ad435ece06f9f92beba55b4c5bb35f91ec32ad89b74922ea5d9cc3411fbb9060fae04f1c4551bb5d484c7bcca06abd52bc4a752503e441494a1adcc8fa1dd07a38abbd410230b81041a741bb687779ce011ba6a97e0e5ed945b312ba4429576a192a90661f8448496b6eeb33cc1b7780987ea0b16584a27a392e7a44529721b2fdee7c3fd59ad810a4d6525819625ad4cb370385f59e6c48f353f3046d38155ee72cf7feb2303e56d2a533f192f093ff76394599941d90a5ecfb7d97744a9c6b8af05be87fbd04079443c28b15c634f546c7e6813d04b0f433da319d17d5553e05bcf76e844c7c8c38ef04f03360b2ff19a8caa147a135d0a777da0cce309d23e21b37114fbacc9111d1d702118a9133da769a17de2f9e0336a239b7250485d558199ef05ba8c201bdbf9ad09ccfc1e667a7f21a191d1f302df4770615ff9520a6ec33543209481008803f101cbcc821078475d44030f4e5657ecf7bec26fc7dfe8e23df454b36c1a1ad455d83b255d5cf064526e8a20d18f3242084559ec5929fdb924900c707a10c67b480ccbfb225bcf2ab11742288398d34de3c5ad8cc4b75498138721ad203a7d9cb758a345215e01de8a5a1b0fe205e5bab126200ffff443f427555b7a9c2387cf2e159c5c3bcb5e2a2215599e1d45c7b0bf870acd26ac4b1a9b6d3f7c10bd8e2aecb50f3c74fc39d5768eed5063ed66d1db895195d6900f5ed704d849b3cc5163e1f0762a6e966a564459eb6b776586aaecfa2b1cc197f2854005afd69266edad409a0bb6e2c5da515c7fa5397a2d573772958c95449b26dbfb2c9e0c711ef09e9b9340ba1a89b6e8f30cbd3fb0ab1bf9896752e13afae24116a9477242bd691112566fdb3ebb3cc665c3c268c11a86ac369cceccb17cc11cdca336e450733179c34890bcdc0870d2d3d516a665f2a721287238408826dcd4dca7ae14a5a7bcaa4ac6e04d65861bef1243802bed98b69e3ada3755ef4ab465b80681f24c195297596871b2d5947f4ba30cdb36ca347b74c179e54c6cac0589212537d3f6661dd0bdb74a6071b1b296408033f2e61e39c85504623fc9d2dad5c38a54d488ebd922a7f74e95645b9920cd5f407a3ee3256ed4e696d4c0513b3ee79db899a3c7edafe548445d144588789f93c99375e57f268df2e8633948c1b9f25d3c27a25ce504d33286c27cf670ae2a5a445b5b86a72111d07b798c3f5a8434e5672a11684926ce60ce56a2a2ce33077728a3753f6705dbba24a6fbc4706e1e0fe7df4f8aad338ccf63218ffa70f8cbf79f42a6599fd17f4321e584e4ffc734d142333e51733c55be557b60f15c39577cd577a592b38ff19d0e9929d86f45703830569835e4bd741595d7c40ad33a318cbb7e9376696884a64fe93ce3535a056951722dcaf8a37260cc8573ae97657bcfec89e18ff40c2139526e2b2bd80a39f98895607cc18bfe9b36b7ac446d7dd12bf3eca897ea4bd46e5452a6e5ec396da5baf39164702f463a1a86bd5ab3ecb311eeacbc7e1581cfb2e997398b9e640db976c60ed1ec6260dab9a944984ceb6aaf057f7b62864b934c68e53d2a845f9434ce4db0cc9599b1100598d6fdbc115a12eede60a9568c674c7d0b0c552db9ac98422950fc628a53253d21e135a707232e6e70afba522fb38358504354449c825e20193cd0a4aaf7c29b70542cf9486f9236f18d33b81509c50e98d5dbe330dd25390a722757db26b02a2f29a5bee50b3a65ec1cf32e0747cb321c7b9c413b004b2d6ac19aa2c8d160c45403ccd4974846b4787b4e4e4db2af8d52ff8ffdcf671886b1ec5eccdeeb43f859ca3f9d2c0539d13b0de016ff097eef64986d03bdeb7e94fef1795e0cc98fdcce2e5346eadb80ddd4277768548d54ca1aefdc4796f8d21222e1509781b1e5ad64e7589a782bb1c8d41c14029dd9e45876a3b913c31bf728f674b0f06331446b08c20c390a4651067441e296f849ac30d3399c846e6b568b0f682d4ab0b4d56df5ec85472461794fb161e2307a89cc6a391e448d9b5bb0d0ec520e9b5308380a80644c5bf3862e64fc320393266184af8385ab2e3a94bbe9024c2c5bee6bc6cd3720a1e78c30dd4ee60bf6a9f417dc723026b295bd6a1b35550dbe8d2a6d25554b2b1ba7735b3921d9042c7503780c3d75b0a75af2469b47d297fd0f563a4b3e01c7059f6ae73bd950cf5e1a7cbe32a7a0f43a2288eebc0236b010e10e83a6d9b29d99135644c33b6ac7e03f84665b57bc1ad2c251fa3cd2647ed427b26864bec3c25e68e03b4f0c9e6c1ee712f2bb13d3361d97cb5b203cf878d748ce87b5308809ec52ed694f625c2c69cc20f1cf352f1e62707252f4646954706047e866ac53c28b608a7775516916d5979b4acc33ef17bb4aea264ad1d8de8a86c23a13bc76aefe7667e721ea6aebb95f3d71328f2a726d85a0f02f7a3d10b5b2849a41536b67e33192c58ef387dfd139c0f3f42d74ca02f958c2bfc144ac49b0a2f440913d7c5a978a9c41cd3c3062d68b1a6bfcd3b5bc0523494b28094faddb589b1e822d4ee6deca35d4a0ebb24692e8370b8bd8fbaa0babebab5563ed2644ecab792edf9e7dcd4c7212e441c21f227bdaa11b66173f83e93d653e2b5ce840f96f2b7612d010d540097dffe1391ae594c36bbbfffbae3e96680fdfa0e63cb828cc0766133b3f0989925c5794bfd12c8276e264759fcf8c930918623eb88819994f108e974ee8d073f15ac8f2d423899bc7d450ff28d55353fe67821575bab211aae1e87d31817abc91415da70087d0ad4abb3ac12b896a9cef354b712c240542ca6113f9f7a82724e05335b2f379e96fd0f0eafc89af093895b78336e39fb8c18e6319a02484f8b366d2471da986ba57f9b40c67111b4e14af701488493ee4ad586a6dda74a3b0b3cc345ef338b507b1cff965fb4e814328f125599da3c16b40046b2a4e81e3555179af25719c5031f7995ba66ffa7c88751a69e9072d542352c8b7300dc99b8af245082cd83736d50db0f3b7ba680ff5db951e409ceebec687b7d44532a160e2985043a9a1a16091d14cdc46479e20e2066155c2069973253c3d7c98269ef6ac6cd75ce8211d88475d11f1107e7939aa88d34744e768fb6d8499202e99f899556a2e4188de411b8987099b6b310a34796cccc50b376342a7b78311c85b8b51c0dd66b13e72e932f50cafd0b8de54b08311889d1645bb72bd29ab2fa0e9ec8defa7c7e867d32551bbea2e8bcfcb7125fed86951865afc65a8b1a629162df1721f7f3d0132c642f77ad33943d16cd3810cf2e57a4b06b5307a8382af97ff65aa62df3f93a6c7bf9e55a943e165d6bf4ceb87320be800f593f49af8a5d70f11fcebf4b511f3c23bb1c684e0590f2578173f225e04baa4f14fe643b691573a900fa27185cf59794c0ab64bde3d69927d958ae2244370f5489ad91f936ef477a112fd7d2344c8d09ab758bfb28ed80eb1e172fc2a1c20e41cbc21137b9db880f8e3d88aba6591f458af37509ee4cb06231335ed8be70e7370c089efad4e3a9abfe3389a66fb346782f18fcd3915a2c646d6a22cb811cb1365a819bd1a1ee5afe6fa44457723732fbd6c4fae58d1463e6fc458d27d786325639e490e8aa8560559a4229c0c4dabf858fd7390958d2901e5528c7d07fa329bafbc137f78fd95efa4dad6bc916fcac92b277c6549fa1ef5f8467e59337132028646c7ff5126baee129c436224ef732b8b245992db903c129e39b11ee665bd0a0e8f833918fe212fd8539538b5ef2b717277be2a528e1d7221c3de4a95b3cb336aa17e4e76a6bb3e6010b82f54e42e4fe892f759c730bc7c123d51e6daea625d093869e5dc6c20848bc226a80b096d17847583c4005f48659896f2ac7af74dfe41eed81ca75dc91cbca2187fc56597790012fb424dd3f327cb7f7ab2c4b0e52fa1b7795a7402149ffc7d8d43adc63f5f810ddd0abed0a9958f715a2213fbf48771e4b8b432b9ebb4d8575a625ef8f539212d21f46dfcb9c99f9e7384e736c33e2ddc11c1137f7af2a6c1e5930d1affc2c59f9eb3a4dd50efb9560aeec0be7e19a2b2eeb7c3c9f2f253469baf44f0f869322bd10705e998133f9c5811a3af57953e99e456d760d3d2f7fc554fb6edaf07fe6a24bfecaf47fe6ac2dfb1d34ffcd9929fcffcd9665add0b7f211367a75ff90b19493bfdc65f3d28c4fa9dbf3ef8fe4ffefae273dffcd5870e61767a2083458d00b39368d3ad1e13ea7b27f2dd564f116f6e767a2617e6eec2422e2c353f7125bfd756f1373b818adaeaade61076f27b2fbf0ff21b115f66a74ff23b6d9f5fe99de5565b1d307ebba82fe4445ff939a39291792201034aeb9b3e73461b0c74c83461fa175af194798f55193dfb33d640e420d40032c9b4860a0653f7e5afa614757b12f2f794799d754384bb8779373ea69164f4c17598b98b9ef6a2a7d3b9b35ec33fcbb9d82b1242a856b978040d7fc530c57a12fb37b24bfc5c1334ffb6534fc7b15edfaece408d6ff2559dd5750634230ef5e84ccd3707bd0105af11286c6f64fbb0f79aa2ce80f0f65a8c51439d5c6bd8c9b8fa593d389d053e9b09ab34a9a12e1ee2fa9c39e82cdf3fd6877cb441b70ee8a79fb733b0327791216509979478a6f04f68d84d683129e1a82ad995f1c53976c7c661cab10aeaec6cc4917d25a6c46733f08daeb5a45a3cd001e39dbd19a68239b49c60c2c8b614518f1b371dde63dea397d3b91c2be8d1d64709ad96253cd3e199339ccd592aafa354f02dcf609fb485063d849ca46162acb3ea74b172941d014ed2abc75a60cb7a87ca2cf7c3569b0ebd3f76c7dd26a56881ab46be3d73e96450f48d990625f6f5b1cb3266629ca37186b5ba270c7eea2c736791c42bb93c3fbfbce065e49ee402da7e793cf7581ae7a8f31347943917761a282f58d340f99576343bc8494069da25bbdb53358338b440a8338f36fe6b78bcd61eed6c797796617992421828f37810634681d6d9fa3c8fb8b28d5ee4c5e0bb1159da577b0d4fd44aab2d56aac7427f1fd4148c65209b9c58f86acadc8b41c9bead3b4e51f726199e683065daaceff2a263af0bebbd13d6c5bcdb71b3488d14859ec22b5c5f3fa2b9abf77e041a3c0b52a9d70284998ff3a652f75d2a5825ebf01819652a9385b8e41be763ff584891f487f311a675947bcbf09c542c66cb873c5f7b261115f473d25709ada22d9de52696aaf3314b597794e7b6ca73e5db6bd9ad313bdace8b0ca96c3c2b98984f625ae0559a12b2e4d2cbac5cf49cbccb3fc12bbcf037b74d83e5343c98247c4202cae3bed5f5e475cb828b5401fbb60a6f3bd951c137dccff7242e0685b05ade886ce54bd1837020840040d966ba20d1ba79c2c04dc1ba729209c75940ea06637b31da1bbc79014e1a7b54f04cac4830124faa7d64e18a4034c4d70887774d8232d45732a1955a9baa1c727b9c8d5261b8aefc0d692759531ebdc86055ad5d1e4719da35b11b9a7fb180ea2325b58486c89eaa2dfc88034ec901dbbb76d2a51fd7510c96c809fd17f28127d80a2bd79a9a8241abbd7e8ea88b4575673130b9ce81ce9d6d556acf37940a72d9782efa4d164f3d279bca674cc5528fe0670fe03a4b69d8dac67a4c789b7645ea56d5a5b2b17a4755140063a99496289ab15635569b793d2cc48bb1879f452d35afacf5aa925e20a39f006fe8da7c265bcaafda774de5e3404f53133f1925629fda9aa43794737fb9ab16d5732a96424dd8db1e68b99b8991595da9afb978c7373b43e782d087bff162f1322ca9d7acb89c3055b312f12d8f17c8179fc93aabb6216f486aea7e2023297eab1edd1a47b79a96a787d6d293142601f5eef58d946dc57167799d6dc38fc99ded19c940ac2df949dd87a4cb9462a414f65bcebcd9d9dceb478616c788a91a1299c72d1bae3f8461c15f66c019d6799545d88ea02959b62b00ce5913273453d68e17073cd0486b7d33d4c0c7f87a62b681e461dc53b492920126be3cfd08d8fde4475c61224c81e86af99df0023cf011ceb63a8aaed1d76013434394347419f0dd76e58b75f6dc51b5f768f74dcd0309b41123d0c33f27d090ed3bec909bbfe4fbdb5c146312a8e84f4c762cfc84b79ca93b50e6e05324a98dc55e6d39ff465eb8be31617cea8f3d93e5f40fe03d31cfd154971d71f694fa0a679a4be5b8eedc287f430015f16c369754d1c25d6e39c6a252411667a57ce5bc64e55e5fba40c4d76816129a6a0c31b93efccbe2f11ff31d97bbe2bd70f8e1a9cc729adb87421402e02d58e5e12870a537d25db9707938c8227572fcd71ff3dfaf980c00d88efaa220c22c825cdae179f1653fae2c825ffc73a4b69025bdd6923107532188963207d3e024165ece4f8b4965f9126f8b481615bfd2b64a42ec0a32cb76bff4778f1ca77ad0ef50ce798d3fd756437d206fec72fb78aafb1db191a184e3c4a4a21432466a106def6a25e6537d95112260263a7ec157ef333cba66e41fe7602d0ef3f51465e79e932e865b3536d080fc81685e2e42840af3612a953d099284efdb939d2ea71220820078116003651af604af8f3590787a231823fdd4c5183d09d81f4b68cd2dbb82410564b667edebb6dd559ea435d5487179b1321198570c835998485ae26368acf3943136f9e877202af5a20219e36bc37d9e03f4c8073bb0bfa49d5f465d6e2595e17a44d0a8c8df5248d3e40cafc06edeaecadf2df1a21f20478933186f6d521041ec9f9fd3d1de1bc0fee380d76ef3f96b422d71f4c94756fe7f2bd24e242f8f28cc57c5daa0a8a502d2b6926c5a992fb027ad7dbf5da6ba3dd5ef024445564938cca22fdf18f17949404d60bf767ca4df19c5ee729558bf882c1de95d78cd12a9fcda5788f0cce073413b66be698abaa53f28f27573260f3676f001d72510637e8c1119a7be8544e927a03a3d46270ae7f2e244b932e95baab6cd3f1d1d8baa849ad51885a65a17e74646d36a6de7aa06ddc2767d73231b10951778cb5de4d85573e7f2caee9335559f509b5df22beba3427c7ff8ab188dc92661b0e0c546f2363a2d46a65331fef9c762c48f83429ea3cce6ff70a07a97b302aa6b80ea06b76e0785c7694e5e972dba84b7703d52f481c54bc88a4bbb772ac6aac84a1eb6447691077c703396d3228f090372e474b8a1be3c6616d317b7ebc43b23b99cc024819b048798acd7d7b392891bbbd451cfe4dc930975c03ae4acce0c02e1606688811384313f43bd13c145f8da41f787226bc9a9708a2dac25869293c5d8f168c9f086de8936a2ce56d668ced28ab78b92b91ad0e3faeb038cd78578fcf252e276744be2b363df032f54dd3cc5c9876dbbd7e000176895c2ebc77a000a7825dc7783d130905714a3701b0bb18249bd2277a09b912f21633565ee0fb7571ab594ea0d184754a00110e8a0aad5378cc42bc447b7a1bfa271dc41c82e0298882696a5773ef545eec37de1ea2c9c184b9cf32e314398a41c3e6667b8a1bc83595d0c5e620f10977c71aba7d4c76ac96c9325e28d7cd1943144a755b0e23c2cebde67f1862b9d2d917eab8c740ed56bf7d0a4ca1031a3ccdb6a16d59866a8d41cc17cdef3e8689c56a67a25a2390cf4647b96ad9e6e28ef7bbad03f804dec78b24bcc076de69f9b749856601ef38b9f2148b1a703d594f8d43c63ade65c920fca8f5409b8cf56c45a834980b8b4ed05beef4b7ea58e3cc2136494ede227eede7cba5f67c9ac1d658ab77d5633ecadaae411f65c5f56a542b9e305de5d9828ef3361b8420868b7489e5a7ca1ddf12579666a5c964c4ceba4b85ff9fbc7be0fa6fafb099ff2e2273c7013cf0ef716ccf50f2a278e7611564f698ad55b42824d754a48f20611899d5d297e5eedd96a0c3385b1f7ecd5fcb33ba0eaca2bde8ad39c68d7e5a1086e844ba9afbf242c2b35245a016f24b4ed635251438cab3dc49ec334aff54223b35ff596bc1a1a60377a570cc935326276acc21f3b1c3aac1e1e4e7b811b5cc0d5900bfcfd18feadea2fd8cf28db6d0a3acf23b155e0d9117b4ad5ed2a052997332673437bfe44262e5fe0d619c261a760a20d186c9a8935119bb3578cabbcccb96f81b59b018d492d4a23bc68c9cb20b3d3d24ea10e8a5cea39330398c14ff3bd5d2bc48b7205f1db124709eeaa65fd64c6553bafdd67247f33007143fb757d2138717b3ce47fc3d4f201c343c7aa4f4111568859e53969d4bce2257b96341bea4e121036d8e01f0298878f3f0a41305e7c462b69ab293609bb754c410fcac2dacacea7474be103632beb91b8dd4e46d630f13e45b01b30d2309de24161cb7452a3987c391ebb60cd9aab27d283ec351210999a136e7b600dbdc8f834498b7ecf522073ca2bdde4d07e69b51212b17dd2bed7aa4e5e115ea5ceab98f302e53f3abb0c180c32d6a1c28df449d609382d4cea387209bf62b7cc8436957c99c82c3133d5ea8c9342fd6bc244fca8c456e492c2acd493d10cf5e890c8c0db5ea3169e1d040e85da732469c2d2d34352d5a9fcc31f75993b6016e6c8569d539969685e98391014f88d59f9c65e6c5d1908daaef10b910e78f96dd811a44bbb3235ba376a298a2c69ae0e11d85a562f296ad9b31b31d47ea95a416fb1f830c5988506838194859337500a6e406f6798e4c78c9837c32c4609aee9d9d325857d9bf3a629f18de166aeca18fdbc24b617e5d51fca647449a22acb7271aa9597d2095c2dd125fe6dcfcd1bb86385c752686350123eae3922f6759a7af18293d91c93051304a2ec30cfda3f7122c656846b6e9c808c9faa0981f7f1fb17a834e99c9ec6e9ea8fe1d4f6f82fb05202c2911a341c6679cc7d4c8cd8447c89feab5211c5aeb69fdd5562dab71d8c70ae068fce142d46d364cdf18679c270a609ee2c5078bba2c883e5f397eec8e69bc3b22c3ccc407b6de9095a0a68bbbe2d8a638a71575f8cf523648c71f65bf348494d02c3b70e399476c0f61ed1466652610c77aa280a0830ec9be3e1792bc3283f26edbdee4448b5d3f7856c946098889319c0555b123c9d46ec23f530549ef018aa154c286cfa43c169e011e72436316caf61d89ee8d53dd5001cae0970d96767244383051b2ccf1b785638715dfacf116f6a9653673956a50c453cfade9ba9f3bb898ce3eea11db7be4b51d4d8a7f8fbc0479ae1076462fae5ed25674aa7a25e42ee446c955a3dbe2b526ee2ecff33ac3ed0dc66cea6aee68577edf3473e538b9ea929730aa7c111697880b9de26d4327c64ee233524a0c5dd6a31061ff28038c01f89f0b68177d2b859c7f5da6bd225b60712c22eb2e15a9f6e936175f38005a05a0b8c92489bac4695d3596e0fa2ce37581cb551c8b9f4dabaf20ecc0559e2c3451096d21161658135392066cad55f478fdd5c1ff9546ff93e5c04dd027e0f35b205065ae569786c953d468c779479eea3ea4a95617ff57ddf016b96a30dd4503ec2568db79dc8915c72e1444cf897e48bc62ec53ce92517acbbc2bffecb1efb3f7ccbb6eff2098ad15bda56f259e3055e3559571505bbf2173de7d0f1cca79d7eff4994594f05cf913ef741ba50b5045d405fa96c08d51c433d5c2724cf692308556be679748fddb3a7dce54946bcc11fca946fb7b473f572f2ae7cca88a3b710bb4214488ea2f8375ae2c8ee96ddf853061e91ad4ec5ae30c6dc92477df740fafe5824c8b7fa89d0465b9f99e0ecde90f79020e6b9f856da65a99d3432cf8c531ea376c8495fd057f92de93c5581e54c2d0995a56058a2ebb6c7ec5cf121245642261f542bcd8e82b86565c1ad8a7a970cb732dd378d2ebe726adee4d75a2b8fe5700a0cf26bd09b98b5a2642090c1dc841d164fb044ca20b98fbeec1a1d7ebe5919a159a6c9f7b1c26d3b53302ef62b58f1455f001148cc23afe75e605e617ffdfd051b832aaaaa4dc8ea56c61eebcd9464f9d0db9bed31936786d7988c96cdf2e582fb0638e917e630913c4dc6b7b550fe440af57ded5211d76808e799f70505c89d9c4b2de78d54d1747c089818e62e573e7b41a384555aebc3cfeb08a8c8bc25db763eca2309ef290ba816504320574ad88570a572e95c2c58250cf19fbb31a9c0bc8850b0211e408ee85d2333e553d7a481b6328f2b9ee033e87de6b52b27785d056ff62c1a9343759479875667aa4442d79b045085177adbaf4894b86df559bcde6adfaf404cda82e72744b8ed40acada72c9fbd0f84bb2d32266ed899deabe07541075cba4fcc33ab03345fa54041995b94eaaf989c02c17921a0d354e7123cdda72cf22a7167c79d983e89fade46b4e24e3c4e5b9a6510c17aaa08566a5f67fed0b4af617405c08c957f6a8f7097e5a69276db87eef2743267ace506c78bfa029d75a09566764cae0e01646f4093fe67468aaf5e07058619c26cfe1addd7bb65b2196daacde234da05aabe3e316cf7cd1502c963dcdee72817b3c35da2fd0ef9357bdd3b5b943c37d3502f20d5d5675e7e76ce75f3fcfc3e5a04ea7e61fed802b192972d629cdbcc0c6b975d7cd5f6c4e0a799be59fef270437573241b00acb50e8c63ae3f4b9c051530e4d24985b050e71eb84cdcac51bee0b81ee2c9e069106b139062f7b51b621b30e612aa9bd999d539dddf3c2aff650cc7773d2849a5ea55399626de6774f24c2f611450470d91ba351adb89bc63585b3b4174056aa7ded987ad614b69149c8688bdb0c1cd1e78cf2bcba54dcc9a4f7cad24824c9f4e67832d05ca7f1d6684036fc4ac344474ee687666a8dd0728ca289acc3b0d2f70cff7c4046f941949f1166ad1b4497ee5aac98603fb0fa31b98cf9f8f2542a7723247f38af2a4fa8368a61d87932301beaab719c077388a8a597c6d0715ec1f1e41ecaa83a440db843ebc144a4100170428e243bbeb9b04492a7168334d67d99481e55fa73234920f3134e07764ed525d564efcbac1cb69986bd31e5daed07f03d0745a11996c06f79ff7241684149ab5992f0347a0553560f0f422d370498c3b0d55558787e479e4e900a163df3948ef34c4c27d9016c35ebe4e2beea01273ae3e26bb7845437dab2c5bb6fb0f54a6a0b44f9cad74ceaba1ad74a137fdca355ba9a07e6485a07665b793793845dcfe313456f654903244d61ee8e7a451438dfc73669637563590e45a3cef3e844af93592cf149a68ec887dbbe7dd03da7e6ce1036c0c6a103287f2a48fc3b3cf7b1b3ec7c8dcaf5df85ca0bc53832091772477c6434ff5c8a33c35f44235b436b27f9bdb889e37ce9e97206f018de31dad65d1c469ab4709e1835caca4573c8c0b348d432a5c6a08cb7bda6ad67af81ad91cf759db79aa75a81210e3441b41f3b81123c59e55ed9c83f72836842cdca81fb966325089d6c2949eecfb9abb54d4acaefc77e9aeb14f18fb72ffe190882e50a6879df123b043f4469551fe8cc7f41fd4dd375d73ae0f4469f091b556339d3290dad4521f52623b715334f79c1c67c571f3792e1700b9426713e6da65ca0a6571fbf2df461a49dd75c8ef772a93895f65b12622e61c6fa9dcae52711a3ea6180a6800a634d654c0f28493cb604f105d7c4affa6d87938a39d8428ff29981acc48f779424ac2747de3316b270396d22279d60708abfea68dbb7b400c80ea263072af2011a0f63d9f68e242c66a8e30f7551226c271aaa88f54383f05b6081387365110232683db1b847f78dc79cc151fc5315fc1746f6891936252c996e5dc3015b426dcb9566a113359a9960cd377f27a43776e03ee815a968176f188bd03cf92a9ec39bb2b9f067c682935503bcaa305c5c122b08a0f8636a678bb609e557d3ba88877172b22e108c9a9edcd4bef8c04eea0978984b1fdde0f65de583fd7e21f070c115e9c62bd35251c52beb7af937da3ee2656699d6aecdfd6fa8e41d24104169d713a9968e5f9ae440e4c72e607574dc3fc61669eb2445675cff687947021100534f2b7b6022a9102c31f9989706c36bebf2743f12247c0e12f06d467e99e7e95baa30bd56c2ab53712ee51b7fb27f3116add0dc4c003f56228d6f25135d232ccc644b143042ce92e8695c8df36d2595245772297ed0ca0c48d1b26a6a749478079771fc9663c72cdfb49da2e8795e40de0a5902e6656d2e97a58116eb7912b5b5e311303d554c1bf8b90623519c65f7c33e02b1667e38315dc570533e2be52ade21d7d77c68abb7546a5c245f134e957e85ec2b9dbafbc7964782d98a258e8675279e4623662174f957b4e692dba5872a1cc672a6bb91fb3a8bf933178cadcaff35414ec06b95d2f08488dc1002254c493390fb6d9909b7a59d031fb38b848e30ee81a97aeec341292bd8dde49a46cdc9b7c26c4a022bf6a176412c9901be1eb6acaa4bcd254bcf0be329fac53d059c898f252547b8b600a33d23b78a1c6609805e3dcc56b74c98feb85ee62960d8ebb8b0b833f894030158dc5bc578853437d6eb78c37423795f764086579de09589fb88b93beaabdc3880253442727fdc5fdc11da5bafd5b56893c6f45deb0c6de628944733fb8750f084820bfea36e53e2aabcf3379c6662f0e706e6d426dd4c8e23aeec49105aff56397d1c487fe5e0952e5333bfc302d4bc4309c3ee043fa7ac1d2249d33b8c16141da3efd688b6c8be02caa245026772b215fed9b6a32afe1e80a0df8234e4e634e9eb0a9d085f635607e7c734e96d25e0cd0ae35175ff7a24440d9e36dfc7563a3d4dc6c24f266ec2b6f27a130086b08ee7006178d956f4bc6cab7adaa044b417060e7f54ae49480b1dfc1b102b0a48af14e7198bfdc944c385cbb0dc698707f828f6023559be1b097b0ac3e792b9ef01d5e57333b10353fc785e779a49e14c4f199c9f37eab78cf12e0a0fc7e351e339486c1b595ba7725a990f5300edb40703e589a3fd47686192ffb9ad022128b46e4de73fedbb3bfdba8d54f40bfc02114b597a30a2b57c5b4c689048c26d74e8337539ed8193364f463af7c9f4c6b6504fc6b6336391180c9c01dd074cbaaec31933aaa509b15fdba7909e1c08fb5fdd1d7b0437fe7e94b1d99033fa06d8fb1294c16b4b72e359251a66c77301b69771c552c5d9a8cbe9566375a79e2ae8f9ad903298deec821f31a4f497729b39376e951253935617779640378cc109884adeca135476f8c125c3319577a3b851f911de11874bdadb53d3f7cecde9d060b2861d6ca74a81376e940f857656980fefc5c8dcc9b6a586fc4ec852111f90b05bab22a732c94491859b827b76c470d32b10351f6abbd0722c22079dadc25b3556520bde1ad2d6554a2c6bfb7153728c9bbe77019c2c2952d871fe029e387770dc25696b10f12ff239f45a10293aa24f781ea23dff769e908eece8ddbb2cf8d76742604814292083e9663d22dadca237db8de12fa5cc96da14fb50773263a43486d39d7a8efa82dda14079852cc537279ab82bbd95d7ce525bedf13dda420244ae759d89d3733175728749ba286f5ca20f8c530f2b21dc37dec6446911c95c7f25d4850e69e26f3bb894341efc74ff439bf8b39511dd4609c5633156405b460f8f2ea3b09de9a6bb5ae9c84ad77ed89134ec142aa45256f4ce888b5176a5113a95a9b37caf4f085056d17ce4ef75c8b513657d916b5b3a6e735b2a5ad5e786b5f77f0d07062d214b9e841f96045d15770d21296ae7c4b3db14997b851e6b9fce586740657fa40b852cbe6fccf2db02299b659ae321292d5ba741584c1880273d2431ff2775a8f00db9ed1633fd9d72ab3d492b64c0b1da24b46bea88c91e5cd592ad69e3229934d87d542683aada9ec52174ca626b8abfd27093c858edca924ebc91b6d0e454ba2634ff9412d1926e218574dde1ca8e5f656d02dccfb920bdddb59baea49da0a4390a79af8e7aa4988747332310aa3c1fd8e1f4aa7099d47ed049f42ac117052003bb9d065933c56548d6cfd8be24ecd996363ffab2b73609e545d068f420f34c6315863c32044a6d12ea99f7518c8514b04c0bad739527637cf73bd5640749519e93c6fb407ccab5fd1abf1bd062a89da8390df9c865b171052733233028aa1ba5a498b5858e777d86396487d0de56dbc8514c5b397a67a5a12ff42c3ea518c858042b1784a0a48eb517f261beaa055a9c9e559c5c2d9f204112e12e996af9d08eef414ff563f8be71991eb311464a04cdc36361cb95cf5515efa3d079d443077e0d4b6df6e5023028602c9432ce3df761ee5cd06040e87ad4b2da093a2781d7269161c534bea97b53788d0b327b00c96836cdfdc273bca9b08405de13e8a2249dccbb437947ac7f210019465793ab4f7d9d13fd10bc470d91c2daac84279a69a27f1d8b543491c9ea5580660eef2a27d03c2272600ed7ba658b7c3ea8450aef09df58795e8111cc0194360e291c424e545390f1f43f1aff863ab114c7abb4a7f246b39a900a97a4cc2c4f780794392f291705b4fe7199d9d2563b694052f78b0e0e282a11d2a377927b159b57173439c507ba943fd2496c74785b75362629ee48e35164fc9b6f2275e82392187075a90eab05e254bb766665ea7921a8091bd90e9ffdc9ea2e0feb23f11e1d9a251b776b47aa9f994c38bd7d2776cb899feb291b7bcd1ceb17d16d5efbf0b92d13c449c476df48d9e172c19bea4abcf6dfa97214fde4e815de4e5951262ce8b37ec7730f98beddf6202a963046d37294929fd8e1bde2e4804e10a4a2d288405ba92ec40aefa80a1997d02a9da106f3d204a69151e0829ba35bc85f0f84020e1faf8d69e94c11d8e054a4bcd946f372f93d14d9e4e58df1e079fa111b1bea311310bf62cee2c5299b14bb95b3bc2f295b92b12660a44f79418d32e128131b553c2719613bb35bd9dd915e8d78390d298b3c4f2841b10adc232a0342a36ac767b8f78674886cf9969252265b283ac30f2367d4d2e8c1f35e91923ac3a51e0489d55d20a739e527d579ccf1ef2ab3be45e7f2c1ac99e5a991a1167b60da269d69479aec631802448776adea4427c837ba4af95794f36cdc8bc96b043badcf03ada2123d9ad37796662d82dd20dd2b0acbf2909d9b7cdfbfa30893676c11c27f2fd3de53d4f58eeb63b9c89e97a348327aea8654e3a6b71cea3ecb429e8aecc142ebea0bc3aaf318e79a83d2ba2949d6675cb8b19b12091eb53753fe81b6e9aa1894ec7b2717904d81d77c928a980bb01e42fe3571fc986ea9eac72fea236fae76ef850c1c6203aa7e241946259be6f27faf742eb2eea9bac2cf504308dd647555031934608be141271ca0c3671224eb849625c473924514f99bbdd46ff466fddeb94d5a2615db81d6e405af733cc9a6ba72c758d4ceb277591629375d5379fd413ca42525d2bb29198da4d6e1260cb36ac4c5534df56a46a063169a9fc3bb1096c9fe3c713d9a3636c5f33d2dc8ddd01d96abd8f1d878017a0bac8e5d24a70be45606288f427dde9db98c49433192153ca93f593667f5957231ab4329986647e2648816b7ea0842c5bc064a7a69aa726a4a955048d523f557e9e8f2873b65bc5177db9896058de73b31f4c253f138508fcb367a5757fe5e15ab07b0ccfc289de3ef27c7c4cf6d44c7f71518f8f0ea96baabd6423d9d7e6e93d338ee077553b14049e9241b2e49be7ef9bb10487dbcf9841dc5dfc7be2eef55312511eff4322709b0cdc1b557f9183bba0c57fb2723f8419f7552991e5d051425e20179b07849c9981079434ef7ece879a0559c7b6321b9d67d19222d7b173be39eb6aaa8364d30cf4ebd66167349422a376b040756546c6c4ee567edc2580fbc5a370a705c273652acc6fc2d4c5e6fdbbab3f9f13fae800c9bab6bf87d8c3379e78ed08c9fe8db27b86d7d2f7913cd6c8f15a96ed3272c224e8a5aca50a2c2ea613c3ff49bdaa2669a25489f817ee369437b9fd85d09a566ea2fdf103c60564061ea232faf746c2ef4629e9a0a7bc320f2ee021dc4564ea24708636805b74cb1e87c3d38579ec8d3cdde794db37fe55e23e5db0a53381eaf4e3e8d93333a699476d5b423948710c663780b5b0849d84deb411be515366e7c7086cc5e124985489595d4c88ebaf90ca5459737d6b9326370934b831c5e75933d95365fd219ba4e910334afa898b4e0d0761aad09e6a2d7a822ce1bf9c133e33570b46622871c47bef305ad4da4e0854ea35fe94642dd9e3ba22cf1130ed9d85000885f52e592af64a9767a6ede93dde9343d5cfb8f75b31f59da0abb55ef4d0e7df7ee883b10bf6a1eff8435f2177a87d454d184f7fa50d8b92f4d06874d668aee931480e7d53a8bc8e1d8d27b3dab03e23b057e7b405cf4c32c4728373c03f9475f2abf238d49b46d2338d26c2a62b0f035366a87463062a6af6e9d66008852b12983d382e14f57a2aebe4589b5a42970762c8f22b8f2c7731d6fbe7a46fdae2e296222a539d21c64333419184d5e60204a749a2cb0b63b9a654e0996da2fbb7bcc6e0aa5acea36004b11414a0567a0d8a2b097f4c89318ae5ce469ea1a8576007c33b327f74c090e499e61ecdc798d3a07240a75f795253c1b3fc61a18f4f642996d853158e853c9b33b999ebc85bbfa168d4cd933fd60b4391ab9cac2e012909894749080807b5bb55468007e7b49d4f5933136dd6926bd6bda9b0e0db687ec64a0771c92a12c31bcadb797d11f145a662eee6aca4c5aff883eb1dd1be1632b09d59ed7e3d9d4594426eb71998d9dc7618dc436bed738cddd313e478290bc419ed1e9ea2c4d299de3fd1763833cf947399b84f39c9fbeda44cfdf1a49c12df620277446dfc60cfe777e6c5fde393abf0dba97bd47f3ed144f0a7807bf8cd5cd8b3a797e8c869a9e6bb0416825ac6cc6208b4dac596ac70fbb724e1bf38724a0ba1258066f1b5c49568597dc15f78329676e129a6abe469d32cdad55d68d1754a7417a3547e3dd94896b439e86f71be06ca03185b9e16ff9931c9bec14fb8038c025a59027927d583491aa295b5efec939e89dd65354273904420282afe632a4d07fd519c33eb87644d35067a4b45460d663fc573d8d227c48a6b8996fd95c14dc645a5881cf47b491757ccc56ad5e6481fb86bdd96ba2e1f6867460cca6915c74c1b2f81b5dfee74726aec38944aee0b5a7d05e9f6af8005c83896f4dd225467af762444e8ff0a1a41edc4227f8246505a8a6a3d5bd09649dfc69834259681d1a272013750b3d414c003e08d5d89f6ae25f794e43316e02f340bc34012ccfb4e2bdbe8eb866dbe10c639a279f963b180237ba14bb9cbe8426c96f59df38dd0f73332630431b42632728ec37cee5898afcdacf278184930d14b90c801b1b347ed51d4f2921d35d7ac44bdf7a2a5ab464be75d2cdd60f5ffb7a51b5f2edde8dad2f5c9acbb766a3e3ea50416576ef43fbb72fb2b2b77b02bf7c58563c42753ccb35ac2248225d0f6cd0ab32035b41f5723b15310d68a6dd454aff0c7ffcbde9b75278f336da33f08d6629ed63e9264e3388ee338841bc819210433cfe3afdf4b75956c4348bafb79fa7bf7bbd7fafaa0ef60cbb25c924a355e65efaced848f6ddd5955eeae3bbb98cec6a9ce60511bb218173bc96efa76a2e67ec2a640c05b0200c1486b8e709e1025d4e773632485edb051cda582bafa66c6ce3a22f84aa22ffa138431a58fd95190d24761b19f207e741ca4cce79d192e4eaf2e2e701136f548167c2c5c3a28abdfce4963345fd905689bad2a921fbd5a517f9bfd79494e5ab843b6e5b8175593791f672d4550e64cd17d57287f4dee2fa84cadcd1307ca519096fe61bf50fae70e41dbe3070a7911042ce43cf0d53d45db28b2bb4de401178f4ffacb9ea2a529a7d416a2ab678090fda974d5b16ef2d65bb1d276a628cf0e54723f4f96ef369471bf887b50c3fdf253b62df6b20667fc48d69e28c757a407fa3cb7b3a1e8e953f7c9de60e7fa700d598f73083473c49baab729854c925d02b8157ec98d779677a130c90e277d6df9acdc58a965019977e4b27b2e86469cca0a56cca1a9c52216d7517c7f25e70c7f4c6a59bf8f00b01562c7db1ce7e69f28ad47457206052fcfb25401c1f9dd22567d6782178d5d88d08d30bdacdc5b29b8cda0c9be96e64d2a3b5c59e6bb47728554f4765c7ea83d82ce3243ad9ef583965f09ac230220fa96f3c84c792cfd3bd482fe29843c1c823d70013dc34bb8245f581fd2c01ac3e4978a9a53125403c8ab9d236a6dac4949ecd43834c111f6c45a1850b71fb642c6e704105ba8e7916ddc550a6c6e46625b271ffe38b68e96e44f5b4e51c1a48751035293f93d9953d06f419dc92fdae96603f1ec56c378c1513a2fdba579450a7f7be4b2a11c4dbfe215bb5c25658d9df7f4d2ace188a8d4f41ccde54e8dd76cb605fb8bd231f2e07f88b4423cc4c44918e0448e9d84050ef5c21e4bc679875a60c112dc82093f61811c0f31e668890919125139fd24a72f69dd9406970a7e521b8b01c016786af942cf55b04700d87fc16353151341e5f0d86083a7d62f5ae85e48363eee7095d5908d9c6f21c21f707dff42ca0ea2e34fb8767ed13b66851e86055c8c2c5c8cb00b5b9cdbe34554ed417db201bf5742f312c557aa891c4347cce331af0080873ff126bd3e25ae37699af7036d8ce37d08959ab66d0819c09c0b2d58f88c26d517f6c54b4907cd7fb0978fc95e5e602f7376eb546678699e4ef14e68e9055e268f611ff5acbeed693e9fa71c1a64038725001df4deb3d9ad32a0f315a63c6f93e34a201c28ab391f5c0f2103620c902dcef33d57b1f5b16221069576d8f36b36a984a9a59f805ee10a45265cebbca0c603a83538fa277841b06c7040fa0ad0432b7b41aca7b7a6c554522b8960a63828f64094b89155475b2b1637dc054b8b7f475add3441d94ea57547567558c1326d68510019ea806ad113b3e73da19ef7885ace7a62a9d6b23a26c0e5219914879c504e043bd913de2acbed6d7c059bee1dc24572841852218a86d5585b297e4bd90258b8e535eca9940830d4e328a9c6c64a61bda8d4f48c51227f4b4658f570d12f6d3d10db2c126b0604b83ac8d9fabfe59a559894760b2bdb2605b7b55130acac37a90095d5c34fa695d2afa615f898affd4c30960728aae5cd437221e4b6ff466856cc4b0b7fed426097145a5090d6e527e754eb1f3ba7fe81fd7e8f3021c280b58159255a993a0271bef9b25ac29938c888f46b6d185942cd98aba808d2689391a50f234ba66dccf14b196483ecf2451562238b1ec433038bf97414f982b42f323cf0aeca3ac26580a125db763618b85fe825a9248c75c8e573cff8379890e9de3d019202b03cd4873b9df0f181bd19aeb90917337468bb0025f6c8715b944a631771b47a1c5ce5711c995702d4e0449a06ebc7ac2f467698f545c5fa82949d034e8c4b02e4e786823fdfa864b4d1d00294ffcfba622add0c2dbd9914acd1cc6954b0b0395b0e58f5b9a8fc423188609fdb31035f5fb7b32f8a4104db0beeafce36df06f67b49b24fb2c70dc22a37a8a141ce3400525d47f7d6a14085377775b74f7b21a7dc275985516f213c6c3557b027f288cdd75e50b954f5678e5940aa6f7bc7059dd6543ec7297028d4698b43048e339760f335db329dc5f795c1f970cbb815209e41a49bb560a5db6e5306f737ca8e3ea740a8f2a4aebf915b6a653db317c4a67c3c5758309840a4a028e808b0186ef1664c0fc9f212d99b52f76386117f06ebda1201e9f47cc32dd504422132ead000699cd440eb4f771a6ce46847c82aa852f4f6fa7313f791c684e213e477b213d32eea5cb42b0353d7d39959990145c410712692a1d75da15e85f99369dee1f86c4fd8275818e38e5c2a0a4f9e178835adfd9e536b38705c8f8ca0fb9aee14b20cc2937772c345b32e2df4e509d13bb7e073f484bdb344d651071b2858b4f40a9d0443019f55827d084c55ff6aeb1d6067935a7f79c679c668e67a0ea76aa7c5881cf3b423affa1d8e3d8750d036a640876be0bd9c18970b58fae4907c62e98cfee678668330b640a0dd470a7f62c089328150f67beafa9042e8e8f5f605876e1ebf0a6479fae262b9fb9505b02b3dee0b1c77fe64c8a07894e80c6cb8ce896fd62030da6542fcf72203043796423cd7e01be3c269cf26f240c5b597f72009a87f5a5970209dbf5fb5f17a7a401f56b82abc73ea37a548ac8ce46a7351687b635d76563a35acf1c890587c92189c05872d07691a5436c6e24548059bab99b451fdcd87aa69ef50acc7f49b0d55810be764f0dc48ee6462bec9d3ffb9f09e57494e36d12fe76436768453e418d482d69e65fd83a949f0b7faf136232bbee8ad2951c35b30820db5189c78aa27068f34108f4d40ba8e39f897efa1f65e99c8beb1f8a6b763348d064a13ce970c6432a499df13a740eeb5cf4d96a0493c60fc0c2a64c0744acded8e64e0de253d32d1362f349fb4fc8c1fd31bb54addd88c559f6785179e49402ea32c0a7b32e2b71b4ad53631df17fd2a0fb130b68cc0020fb597270f695eaef01ee419774e061095a2d221f837e89f56bd0545152d5b17c4149f29368c15ac005e9b56be4df1eb12c90901078aba9414a9b95cd194ddf2c95e476a230202ab746d2359c23b45c912ef1f2395886c2409566c1507fee8c3cb1562503365726845c11dec5dd2fd9c23955e9a94b64d236534414886434e9ead0132a3c29084fba5c56e2fe2e85ad4b6478cb5532539e4ada6e9754045c6b9a48ba6961d180f840fcdcf16fca1d4e68d87e508f502e8030ca1b5d98041677d61535cdad79cf2065413306a08116dedcc7a42c2e341e2f18eb8ba4b6c6249499f4e94b22b0f72372ff34440710d4ff07f4ee4925f4a075eab74fdd2355e7a91b91f5fbac64b2f48c8cd251659f5a768dced5810a6b40bfbbb1b92c2fb873ccb5cf013dac0547eb97a93b58158f85ef3d8691c0ab7d5a0e07eab20eb5c4527d134ab2d42e72595e528d34b9c74097b63f1352c70c45a36647ad5a796a73e9739c295ef619526cd43619fecaba75ba82573496f196c898a4cefa3d4ea4dbf06f7b08893e63ed9efdb572d42e13c9ef6c4edfed4239addbc6a20fd756148d31a913f672d23d7fcf4d990e154c85860f31d26d218a6825cdb5c6cc7e5257738715ef40fc0f9f68f3b327321f304850d292221fa7345f87153d891b523a6b5947fb28188a44b31081eaa548a56057a316d5c7b25f714e1603ba530e9c8061789d4d5b4269a9727d44c193a9a57d3e176f5407b91987e3aa279b0af57c9226d18f227a99775847abf59519e7027e89d85b5f11f1c83a7752251a90a06889379bd24e4a6fe0a311cf67209d16dc3bf476b4841393ec933ec088cd0a33d5ee31c30bf757b3da593757cf2eb9fc9c9cf01cfa283f8217bdfe0e984bdd9de36005d0178e4e9738258ca7cd91363465559b19e9375445946a91040ad8eb645c56a823902f90fa8d58080b11172dd11ca2234940e9dbb3ddccc86e26ced94935d4ab1411f55b9234ab62728f5793c717ae76e6caacf3a0823167fa6632b25be8123b3bb9651baba5ce0e7c84aeb22ee5b1fdc4beadb464eb6e8e251c5482c27b9c56f70a8a5dc1dd96c4f1bbd82dc42fdb7db356986ae10dd91fe2aa74bad886bcc55773fb6b24351033cca512e3626839d501f97ec0f22004c2a714e462af5003bab68f38a71222b49427ace76843be1a290ac7f98baa953805abf120e037702f8cb028926acaeaeadc40058330ea8c014c56f3534579bcb951c51958ecfe68de9f20c44cfff1137bb7361bce5ebcaabd37e2a851227d4ea92cad42248851ee38cee21e08f1129d33dc0939c87d3203802d7b977dacaf83715637fa6d25c003b581bd8323ec81b5324a2700cca18c75e90df2268a6d6d0f358d4032439847eaa9704bfbbc42fdb3250ddc98d35fc1c36d909f08b2fc676d0024efe76cf86bcc91e6e7a3a0c485f6e725c932b9cb73269d962ebc416fac943d6151b8b6a41af2dc12caf71350e7590e7263523845d2b0703bd57e356236477b4293e67260b7b1630465aac261ae7240fd0d9999b7a8715e9e6447dbb49c9d974b3f0fdc99eb977ff41b57b3cf379ba5d30aad24088e16e91fea6b55552e566d61335b5c54169cd76b79fa3ff5f485e5b573b35caf029d5002f38ee390aa102074c35ccf685aa6111ed69a19da8a0813823b3f304a7d3d1786cea2f148b9a637f2e7f34d82b03e74ec918ac4a36877de6f0e4e8551fc9053c38bef18d996254aac1e1f2b53d1bbcf756ea749b23bb682477dbe47687eb15ec9a89bd73a8521caa42569aa0fc06933984d113bfa05c653b749504b66e99c1d71032e18d9a14e75b45b5405962a2d73bd996700b5a9ab6c54367644346cc9154b1e030ceb1a44a1e6a21971c81ba50b16dc572e10c6f238c33b8d61aab24dace54ee27d9dfa18289a491edb9680d15515872fae812bae864877f890e7937117ec748076614ad0047046d709b6baf516eae681db86a1089aa67885c17cd6ded99c44fb22750a926947d1b441490a8727274e43896c35172c27a868de12746ce834ffb421cc76960b05328a8c3c56bd6152b1bec67ae04bb787a42ec09c4da1522923c5f3e0ae98f89c117d434b8b727da626d17acf381d4e0bc5ce9fe5543ae61a243b46f2d4cba735058a4b5249ef762a59a7d667dae024870d6e4eda1821af40022ec175d56b5a8302c61be378569aabe72cf9a59795925eca7fc330855900cb44d528445e6085554fb3fd918b8ad9d415030314ad58c50dd458b102f8719591982ac2fbc97f180151a57b490523497fb6e4af92b21ca070e454c88bb91476407f126e0726a73b6d29c486643188df8581e18b286ad8f548822f19df7acab3eea581dfdc5016102d4f26b7b88a10258403318c33b869d5fe2df3605d1cde48e406b54731cc98494745c3a07bab590ea48204ba25de96603b1972c5a55bba03140f9879f5aee9ea832bb7e9410ca0573b91cf426b2730c88c0f62f0ab850333e224940efccd872a7bf7d6f1e28d27b9cda91a4a43f53de153032f0e5cec214ed3422204158270c6c2a4bf481ce43d6134d54f823d342813ed286b4f687d12766cfe04a7bd2fc6b7e90ed88aa7f965f70587cc0bc6e4e8cb81915adaefa5beb5d93148acc4c9245f9adb2e77056a05644cfbacfd17399c32b76b79dc6eda8d3d1f39990b5dc1a60e30630b9d8626c40870a0f86eeea9d194878c340763283b08990b0547841d334aa3f9143f20e6d82f71d39b5572e9d00832de44dcd2e894de9ef71a12d768aed3b0cb54e025f7fe7989dd0162ab247dd7b7bb249d63afbee9e44b131321288a704826785b714edab75548102e95f2b92ea2b3e80528aafb16d8ff56627ec8127249a0de69c914cb850396c268eca2fe78caf99129218a5ca11f61341ffaae62a7d989106e551734a7124f588863f05bc44f76a376738db007cbc852212aaa6c660f9c8900df5bcf82ccd3a630efe27cd12192fadc60ee7d5b990108150ccd6580a6d1225fee4be31b99df4686f3fc56cae25bccf46e7ee070562ef9464a1a279facc61905686bde755b2f9f75749fb7fcf2ad9522d883ed70e3cfe37abe4b4459c4abec2b2cd3f5f28be3927be4647e6fe7886222dfaab5e7a29acac6964ddcefe4a7afa30ff75f6d3030dc5deaec833c19f728e772f1b889c05a5f01d66685764acc73edb03f4750a4f74b2ae285b0f5a65bf285a3bc39d85b2f52e9b8bf95827c5ba0b650dabb7c0ce05d484a360b280020c9e3cc24e570f0f6880c9764c489ff392ed08ff89c0fd532f001cfd037b435de17c76b2be38ca374534a1c18de42c93ca189e23e7aa53e1919c007f9fab12761c81e25b62db90c930baa4769bc4332acdd4cf06622ce1e359b906b245b928e187a4bc854c02925e13548ca59c392c18fc4d078ddeb229a78c2bec993d77521d2efe5187df3d35ae7036d6d241f8985e5340ca237148bd976de0e6d984ad97b1135b11101b2b68568d9bb9c2e54297005d448e08cb5840f1ed510680704ba7d896cdb635006b90fd9cf40b346407b009b4a7557886c0ce5eab73aad2dc0271d4d1f43b37570799e7dac908cfbbcc9211d4ee8e80c8c4ad973ee467dbf0ed808b3414b9c86ac18132555adde51106346172bc1d9a6fe28d8a9410c1cea5a2c3a20fd149757fb50acc13ab40c349b4985b6b807d9039bdef176de730f84d61ee8879bb26c98ef496c7fefd8fb4de29eb3c119d21c198a28a2ee96cc315d4deaa8c1377d5cc6284ea7faef7aa5973cca325ebd8b00fd80e54ca255eba95ef7a532f70e8f63bb8d6256468aca74daade13cad50573842c78594f383b68aca57fa4b13ac2e1bacb73cea3f85fa05f923bfa92521d607bec673de12346bf758a69f15496a5adb187dbc22bc9f992bf9dc2865fa8f7c1277401874a7ea6a06e5a94676977d9eae6eb417793e3b20614916287ec0e08db19ee1e93e13382bab7d61be1f3c8631914e596826b3f1bf24062d36044e292233e160ab8b2ffb291beaf4f227b41a66b774a76f0e10af080a4fa00f2e1a2caef8696de8435cecafbff7f75e0bdc97bec09d13b35cd39ea99526b1f65fb57fd777de7f98c4a9eff72fe0fabbe13f939efd2cf855e42679609aaad5fd730312b5ebefa208d976f92f913b18e0add6a26971c21498584f1a164f3dcdba5944184755ffbffb44a6c7f57894f4127db17c7e02cdfb331f0ad56759defaa6e81dae683b2fc208f8df57f52835d40675dcad8bc40a169a8297cc0b178e4a29ba1501315212724eb085f4ff1a39ba1200a38b8431b727e5b2fa5095a02eaf5ce191cc00b14871e54516b75c3195cb169c313e5878d75a11a2d97877fa2620742f82544e2712cec761d6b037a8cff9e8e7d817be6266ca4fa9e5adcfc613592a32860bc39954772f24c65c8d63b25dc2fd8a9a852c8c9052c26205bd5ea56d2619f36856b1cdd89dc3fe83dd0a79c66b81e61cbec7194ca152f886c438b8ed673d634e93d9ab55665f583e6dc505c4ab47160505744807c4d69397600c0019b7b9a232e64900dc452bea45426f77dfb986d8991f3d8a05cab52f31fe9c6ffcdf4fe43e5f81f4eafdaa526d615fe4ca5e6547de41dc3d2dcb830ccf53cedceacbd724a4032553db2416beebdec817df3235c54edd0847de3f0f87d065ad9b658cab7d40c6cedcf62f7462baddd6aa55568a5855bad34ff7fb5d25bad94fc944479ff84e257ce19fff6d2110d8d0df60ecda0fb8e4a71e0f3c8c2a4a75065d711011737e3749f0aad0d6cef6fda09aaf7961bd76eb7fc8edd6e0dca9a32fa444d0228fe2827e4d80fa67fb2c358cd40225801cac25cc5a0b9481ea9c031b795880908967fee7af280d517bbd756d68a1efbc75e394e5ffc2f25f823e34a5486b4bb2a6b85acf0ffd0519439cbffdaf5b5c041178e2003a29e05c56e38a82b56ba2471eb07ab0ca1ae9d4138e6b070a6b7ba18e441716e20a5ff4da18fcd90b77e00c6ea04a0bb7ff6f8b9b5d694723db236a84dbb396092f3a4973ab9079462e953eef359b18e026d21f6314068408fbd3d1223fc065489195cf1e109b91ac4fa9cfcbd8940dec2c41e71741ad39cdbcc1df8f581ad7a8fa7fb3ff0f49fc5f4272da6fbc991a4c5a20262db82333113ef6dff9a0d445d3ec3c47847e6e22931ab29ba2b73ade8dde16ec44c4da4d2b0b623d2c4197b7e0c14a62bcf42a1f9bfd1b3a05caa676cf5cebdd44c93174b9de4110b7ab0f3d2b378899409bcb557aa88f3bad7e0359e3972be59066ba8b73880612e4910e998cbd7ed45674cdbbd61d521c21c8e8955df11ce426ebf1d865fad6c2046a9b3f076eaf5c42c60a49b9216b0b73ff464846266ff7f6dc18f9a48a8044c93216d7918cf42407e79098097ef1fffac0581202d07e4adef72c042ddc80173457240a46ee480917a586a699103b48693bc95c89f862b5cad11c30d14479e8c491c2673122f32d33ec5204251961beb7cd2afbac858e6a0d2383df138bc2b783c566f850d57ace5421df5029a7d130ea8286cfdbb54e089b9e4ccbc4c4132325445be6942b8473dbb16a148730ac5e9051a93126aa5ce2fba9b4e2e4f758e6cc0a73e7e65c7b618baa3022443d280562f3f253f46bfc25933165450e59cc61a6a020356f17f10843e9de4e8cc9a2445dd439c1e1a19f65fca703476de0ad00443fe40e0e0ea8b0419c5a49e33ec180157ef140b557c6d2f853a288e96e16bf3b8aa4dc15abd186cede1c79864a94e6d80e4c8bed6faab7472771a844903d557cd9028d571b3be78a5c93dcb0b8977e9427afe79045a64c83a3292c82c2794b796d1bf91304a24da347311b76909f554c8e8a9f29fd690363b5eb625be687f9765012f5b58ffc6cb7af1cbfaf1cb081cb3f544021e84b70e6198b6e9d233567c81ce8c3f5fb082819f97908082580cb7488920a62a07854012c8cdf353762b75173e58cad6240cebd590cac2bf5fd0a15f5227e44219942d8227c6417ac69a8068ede11c574c2c54ccd0c2d2bba980a38ce9cc00eb055b1443e9720623e7576c9140ff851d72e0ab7b02b1565dc8e627be7a643b3c4e4d487717be77aeca6c5fd8b00810c018b5f3c82fc5b04d649cc3d04da2a1fe93d478bf9407fcd018dfe9a2cc34ccbf387b833da776d391fcf1a847282e7c0f5d4d64620ae08c057dd22105ca123beebb8e5a58c823025e5071c559a10d94d40d0972fa758b27c2c3187e9a1394df00a5f5477b44734e295a4d9de48613f2884c6764b9f9b38265f20ad4414db94720d1e436e9ec1e57d815c9893f2dd45146ca257233f5463d51dabc5f5265321bda160252e9de63aaad2f2c4eedf1117d4b033e6d52b6126a78c4dbf41a0c494a7c745d222ca61e7981a50bb1cdce91b03c9c93a95692b3bad971d3200e02e87117fe7432108ae558ba4b2dfa38f69e4cb62bd9dc85f74e8a13828f8233f129ef32a073628584eb6fe7471d54f52664e7f0c664bbfc53c3d5efe70a4a3fb6cb0c93542952faf3d714ca556f875eb6a8a2cfc8de075cdca72f764eb8787ce741877fffb88a3d5aa5bf795c059c47eaa7e0797a0c101e63563a3577ace5116bc0b5de3da12c916d0b8fd2b41ec4ece5fb293792c259a963a8c59056333e90fa3c338c34620bd1b02614d4b7a4d90ba8b694417d796bc05a02273733ca2919aeed800df7ae10830277dae6dc8d12f739b68b946fa02a56e2f951b74f53056032a408bf086a97c2eb23344e342f34b956f4c829d36273674e72b0acda7fa752483e23538040b5662a1ea45e4b2742bdb04cea08e1d3cbd49f5afe1b6e7a9e210e0b7b145ea0699b1e998a4ba985112439e73e71580f342d3388e60f4c92937ac549b5b1bea86814e57140ae83afd15fbd72297a846c0e619a9d8062e4a0381157a2f476f14e6ce62c2748b00cc61720034914e3d6fa6a1338edcf5fd9400c280fa89d9b70f6415fd824cd861bb2f0293122ae0c26f2f078a0c87ee562e6c3ecdc16ea154d4427bb8f0f9a6176209c7774cd455e460ca7df80abc3cb9c34a90694e9db4529e18d9c152d7653876499e9083191534c6c309b1397df03d58e6bc650152fb5b2b9fb0060feea0519020d78cf516488c27de082776b941f61db02f13c558665e35b641a2343e9e70108077b54440592de94e3cf4652f86c49cd905fe6e1910eed60c3a02c0b444c962bd03f29f31d276a78627b03df1b66dbc2d95893dd35570720e7e7887302c824f74913c415f2f8b4ac6de3c347cd2430ec480ea4f091cff1d9a42a3a90725c584f66705cbb352e58804549456c97643b705185dbcbcc19e4a22dd4c78a78a25bfabcbed512eaa3848edcf2d3f5bd8e501f2794bf775bd7b706427d6c791c9bb9f5fd392ed1ea9e6e86d217ea63810c4817f555aeefadbe30cc87eb5b53a9c7c9bf663ebedb8eeb3f79d337ae5498a3074d39d47047e013ea9d81f8916fd53fcd39d9bc008b8366357f50cfde208fd1e9eccf9194e02ea6b05e2da7c8d99f2114bf33af2a069f243bde0aa0ab72ba42cdb0cd8fcd18ee5a2dd481a14b183b51f3ad11c910fe9a5fbe395b71fbcffc1923d8dd74ed9280503ae3c35419c63efff463331b028fdaa8255e37efc338090fb8b372e2b5b99375043ffa2895a19e51eecfaf4fe27ed0329211eaabfb4b1efc63aa81ab857e91a23269f1fe1b37248981a56ddccf60e94fb9af09cf42a5956ab3ef210d9fdbd48a689327b1c59fe3fbdd066ed3ee6410c23a3f91db7389e63e7d308c502e159b94110eba7c319e01e1d52ad7240d4da11de195aa3fdc5227e45bfb5fff753f08bb8ae47fdd1156f8e4bfef88854c6646be1061eec442ad16bbcfecb3061c0e29f2c49b01ded08f9d05de6505eda1968354cff810541070e394205904f13e31ab4a4bdeebb9713d504e9499529b51303c02be277707c3ac6819a6e0deb9c159feead05c2eac9418f84d594441b49876c95f22199bb85afca9df2a6703ef9117f192454e01ccdd800ab453410c44bd8464d943022143fb102286a082c354524b3dc6d89a8eb001b3e2a75db36c103e6056b2a1582a13a2c7cb3b82f8ed3d23bf9a1447b0da2907aacdb624717c3cc7a345a59f6730e30b2aa3c2fe3e93cca6631c8bcf387bb003ff57153108cca56d20ba9e4db52868cf79cb1cec04da473522870cdd57f4100f89720c65fdcb39d9ac9b0ca131225849eb291d2106e65ead06b8c278eea866f9a909b1a0c6d97a088ce4116ca14e0e73530b687fcc4f9c8635c64a1860ae60cccef11b3375fe7df78d1bbc71c40a121d5ec3435e71f55546e41e5c704555ac3dae0cc98dd322ee3a242a10f292834de5c211fa9cb54d497e8142e6b30454c09d1cd39b644e32709bfd65801534e72483f07061007068affc946d09574ba30f2460bf966861431f260b01fd1972d2369e0a2e14fd05f329a955b4509597ed09c73910ecd5ebfe21bed426a3ca2b95ebf5801457b152d03675601b6543e1d051e194e0492b80a3ac69216e645e5d4378384b991d888a13c931803a589e0340b3e49aa7454980276dfa4191919ace67fda8ba30486e7698fa7b9d7ea09d7aa0ffed8130751d7f77e8ef1efd7d464743fa91c18fa534bfdc92ac5c736ad295a274583362817ff99f2a70eb165761e9a4d4582e9367af6c8e66d6f2d15f76f9f3bb6a36de905415e0b2452248a9d67171be54e39eb0a307171714a32078f85fc28c6faef5c4b949aec9a6a529cc09c055055da02e45f4fc9475b3e3407d12b8d143d65602d2ce68c935687d159ee4912413026f01c2881e14eb4a9a665ca148ff596dd241cad0e99520c14e473e66e750c20658570c7a0f8539006f1d4ef96f90e628721cc4cfe943ab82b03e4a9f71dc4c0986353d8ee66045c6567b2fd719946729e0a57eb104008312ff3e972c4a492968da6ca4a821bac11f55b96a9d27ec89ac70eb2a5593568f24a13539e48decb5913cdc3cf90aff16a7a7e98dec46d2a1127927eeae5eb2f4ca1ecb065fd01fd117a707f2cb171f2848d95dc55def0152437bf3bddaa5b542aff953e116eb64d8ea734306d19c7c2344f2229af46a01417395244f476544bb4c14695b4e1547b31f89a15734599afd1383396b01e1e0ea8571769f66a41cb6d754fbf18b0c25a4b4861481f744a5b880d54107448b3c769d59596bc8fbe0a4b9f02610d53256c3a2672ae1d3f6df7175eb7c998e187251fa8532a38b9535dd9c1c8ed560d64b2a6d8bb2ac22d78d91b568907d4c2371bd03f1e8c18acb6b0771ae4085431931a0d6815f961f81cd12bded9534d7814acf2be28da2423be4f5eb9179a8d325215fd1b7f71103d9edfddeea33eb086f216ba5efdf1e90b9b384acf860d52393da9e8855911b2656b96c65b752382f50ad5d986d3a94f0e3b26946f88050d01d591f07f8c6da97ad4a7dd49452013a648179136b809c04c80e0388069eb3df186b07ba3d59fd49b9af48f3d006ff866b2afeafbed0c905af0dcf1bdaa691a4724265b9aa30a04c157a7bb807ded95ef240cd053249eb235eafba5eca2cf69e0a11a04e097dc67d6f3111fbb1018a248fb6dec91e49968f10b33edcc419aa25148784c42f122fd632ab847d90a572426f7dd2c14018f14a2623c9b24c55cd7b111dd276451661e21fc2203791259ee471c5a2f0cf0d9ef6f5da76847d92397ec9b4829e76653d4afbcf7b6aa26206b2f9be58b584a577a22a59057ed768ccd1359a7fecf5be5d05c3ec509c838d44ac5e9822d0f5888c37b54433d85ae5f482b1dfa66814ceae7605b8ac5a48139150618255606c06eb8e7f87864b0f80b44d53d359f14355da062aa2704f31844d12b64bc475b6b88030b9e99d8d457ee13ea5bab656a47fa98b6c38105d99dc101308e230ec221ea9239475222d37a86520268d2a30e7e9090f84579269e2eb9923373bd3695f66f42af3b5f7def59ebceb70fd2e3dcf84117fd59ddd90396cd86d9f83ac1adce04c0db0c12f6a023631edc7af9cfda3cf33af1c087fa3109dd602ff20f4bb5d390d5996611e59a22fb5dfeabcf41b57ab604fbf8cf673339ff61775154664a7697df0fce0c97505d2b9de3da43fbdff48d03fc9d721042158b15cbce5af9b5027f641f2a803eb869047fe9a6788c61d2d11829a4fdf88f991bc0e217af1ebf69c6635a341ce64e19741ffbd5e02b19615596571c931875c47a0baef4e5698dc473a0fd5cb29f55bbf7242152bd44c1e6085333786d940b8ec360dfaa92d5fa3f5d169e4b584e86ea0c1744ae498f7321543b8d51e1c41f11dc357a02bd1e37458d51951768bf8c0290bfee6710ecf40806b2baa622dcd61ddd00c7bf0910dc4bb58ccacebd153916dca983ac9a2930e5eb1857a03d6b216308c24b493358ca4553d1398c7c729a3be51ca54acb9c8f247120a937ef940385c61737cfd4566255537cc9708b939676d72f286740548271b86dc85cb1a4a59f704e893a5bc3e8d8b153dbb76cddae1740cd7b4a0bdb749d5ba6946f5ac67df2e0f8518ea8771faa7be068535bb3914d66aee487dee2cc657c419e468b46f0df9c3fdac2bfa33c47f04b95142484e5c81bfee07798aaa14ce3a543660daf9125c2c1939a50ec447c4b10c16a9ef520bc9e5c079f3f6f4da6f118c50998383c883c97f93e1aa2fa6b2a679c257001d26221f6c178edc4e03151bbba62021b4d82e473dafb4d4abbacb38d1a22f5417a0af9d9d16d75517a24ea7b423d5b65be44ad94d0a9ae92245fc9d6e619b75c996df858fe583eac07489ef745ee95d7026bee00684f5e76c4bd83e71828f057da8fd96f811d739e86c6b3a31f6b2d48dd5e082658a9d6aea3de720c69561ee0a29c6c261e49d4d855dc06e8a1f15ba44fb49c43b9fa075ffeaa58beb972261e58c1d77aa182d502f07b72049e2dbb5deb24aec5be87af196ed88b107edb176d17b29f7489a68a73e4341b633299b0ab1109dc94466dba2fcf8a2d9d723538cb880d2bc62cb49406423e4fc1c9b0081872633eb29291b6f1b03917ae919dba17a46058bc21231e2c525dce225fc7e3f2f5167f482dfddfa1210650dfc7ecdf0fd1cdf1fad607b88c85f6223b930bf42893a4475626d72a82f050bd11536a1d90498840b262066737be1190ed3d354c2ae58e6f4491b6e7c6783a3804b16be5600f0bd44bc6d489655af3436554d08089a588073b2ab1c644636a701405ab5cc4562e68091c1ed8dba3c649360222d0138d9811a7242df0e5bb66dc7f62c7b255f530f0459279bb7d57333eb8b57868b5f37b331c0bd9be78456fa80a0405cc5254cc00741aa122ae77033f718a1dfd985fc8a1f49f960473771d427608f19e5150a3a25e8e2c82af2db48b5df140dac2ead97bd44c11335c1056e4cefd4043ca14f3386b056e55a1bd0cfbd5285ac6115e40e68adddd793673da75fdd323bd49ec8f553d60409bcc565b8d49fd8bc491b7924a31ade0303fe4bb627ec9adad72c0ea9884bb5a12c56b07fa24d31e1a7f26c9f8e8e169e1c1d1940be43ebcbb82302f8ad0b87bb8f6dd4b1c68f99b5c7817e9e1b5b36bad14ec12ac66dd4448e77cc47cc677fa5bf34551cbacf790021ce7dae1f65c3b2e65e243f665aac6e2ed82bc90e8e8e508fe98e4d8c083db6902a367c53c725793d3ef5057518ae5feab920572608b323d45b6a7a7ce14ce4fa7255e49a0b279beef4c0b9bc8e79a4665ea9847d353e17e35b425ab463e080f4083d1ae10db156323535be9e9a355f51423da7bf98400ad86a6a5ac79453c27ebc9e407b728fee5b5830cca59cbc25992adcbff46d2a7a2966a636f7de951eba7d302d14d92dd38ddddd4d77f6e6ea3b69c1c6a579553789ba3ce5d9c1546eea36e7fcd5c68a9b5d4cb30c35cb9bb81c5a1271ab8269557c10ee4a16e177f1e3417d2a18794d02d3477ad0be700e32574b476f6a45cfc9d6a5ca391399ddeb57e4c0733b15447aa4a23ccb5c8f3c291cc24efa384ed2b553e89b0f592ed120801ac5614527c498344d3821f785e09700eb7880638d2b085019a92144cb39cc3f0b6a1d62fe831919f0f8d90099c7e4390928ddcc3ebcc0cc8c4f3fcb0aa41b6fa492b81972107278d5d51792688a9863c8835e83c08cc377e3d21753ce5bbb335cf0b00205730ece10852fa881824eddc203faa1e2018a12579f69b8e513bbd866c81f9ef7b35c8648f80b52ce9612d7463259211cc1b356c28e80a54b5ba2284b880888c6c9477b23289961f278b90591a76a093182a05321a54f9c19871c25f350d21768b475c9fdbc44f4af3d232f6c6b8b196f9bff934d02e540f4c35fd413aa94907c2ff6a9ef78c5774c29928f4a170fa1a9fd58a7d7e172d3a8d6cbee106173855e12f5ed0aa0db832257bf8b2674b3c75ba2cdfbd967178727c43003f35f6fc1190bcba384696dc539d87c6158e73aeef8500c365d08d811e184d22adc23186a1dc196a7393d5144d847c8deaabeb02bd6716e82e72954b5ad15cf1ae3b712b0dbcb029c7c242b58aa7ea68112a50c9689f8a370cb8b40134fb71aafd8819cf85102b1970b76767046a75fcd51d5b611de7ffa4a812234f0b51d5455f5ebd4d29e48e08d0c22284b542ad627607fdc58ca1cd4b28c454a4e6452069093db1bd9e9cb6b2e67de1bdb84aecaa5f5a71265be7b539be24267ea01593d02774f50bf5ac7290ec7a92c7c71c8a596c7ece2d755f30b373fc7cd4b57cdcbf46b8be67359e0e6f92936c15c5652cd6b76f50b79ad021353fab9b92b9c8bbd811aece7a0da10a5a733546c930bb01c7f3e521c8cebe8d3c15cd6549f93f9604364555f7b9af0d18bde1d95508ce18a29ae7895d012cac882ac23a36a9181294cebde8997a5a48c97659f2187cacbeb55ebe2c84ad99c2a28b37218a5ad0be38c16e79c0faa477cca700659c6224dfae99249ba1f08f7e5c0bff3fcbaeed5ebca23f25e88232dc38c44b59e064e15c842ad4526b18cd89f79ca40b25a538a250ad6647b506f4cea60f6a5d7e4670911d6558ee2aecd28cd6022d7d8756d2e80151c477c031379e1cb67f41ac9159676ab880885a054e7d44530d73c5f2e50714507c793890b3d7355a92d6295df8df4e710bcad1b01e4a6c3d552db851ad601a07bccc31752a6d5c6ba79fa88bdda1a9388d39e0c2106a55a99832e2c32a3283048493ea26faedd6dbc03815a65e678153277a9c64d63778f769d1a4f6f1d9b5e4c6585fc5ea808c39dce1a98c14c8605a4a616bb10a3cdcea50b0fee1c498a2a055653bc4ece232be5fd6a28e3fdd2cb4eb389973f57cda7b978cd534568bd081da1765857464ad2dbcc622fa11f67305148864d99b096fb0c736e8632a3de22eaa6dd3d6355c4af5be680ec3e973024930c10e5d29b86fe26c817400eb9d09c9e6f88d7c8988702d13e6812be8a9734edc632e22549cb802bc468a9f6a08a192ea10d5463af88e1f5d2bff5f9b2cba452a147e4d7e6f55549494ae5876c28dc932ca1729026e9560adbae64c8f9fe764b847dce4a0e94bd244dbd61e271e0481b0af1416580449e046c0a45541b058de04c9c2e2199fe62cc390c22c323c59e140c5c358588b50e39cb98496c485f6e1e69012d12f6d6d0358f1201f5341e17f1eee49323f6d78ae6441a44619c4ddc8f39b543a1ba4d3ce30bf7830e83e60cf5b1c2f382459bedb3f05632032f664c96d1c8be66a84467fed0b199d44926b9a0c59345091372a2c08cf0f9a79b5e6a9aa9e286c3a0b9e6f5db9cc5c154faf535d8321ac43b8d3fef03c69e710e88531333b61c77eb08d53517cb39783fbba534c1260f30102e779c1e83f20235b068e379d2f38953720747bd2fc80a687189a878cc7a3b182f3697aaa6a2c489ef69cb60c0bb72ba5a7ca64498031b19b1810a641bf1ee1ccb644b06c4a0f4367d4993f68f5664dd12a13ba9a6e9ddd05d5f0f594bf2f70bc5e16e5ac86ce4ac7b4da9b29cc7516ee7054b38b91b621e1030322ce4aef72d2d4265483fc7fe1af49028968de1ab70de20cf6a1c779eeca1a5146ecedae57e5c615ec21b3a084ae08d080e71a6812cc03b8fc0f86caf9b90ea91a21dbbb2923946e283bd0116d93142ed09eca812ce9e560d8bd5aba2de65687e377ac6aae0ecac6d95a324d91590e13c85c926ddd87bd7bbb421f3efe98bc55eb248c70bc3f729441ce85771af55f08c20c7d1fcdc81be4c768eebeb13c456ccb9eae3b28b79b84cd331b32d0a16a4fa5edd84ad72ec4b6bd166143a6a4055545cb7d14b33ea15deb262e5773463367968a45fd3177649fdc62082b34c5e9f93bfb4f4f76407b01b76adacaeda51251b672337d7ccadf87da77285d6cdc84e1c375f19a43cb433d802618e368f9ac92d8b1b186248d1276a224b8c31ba84dd345c459467f795cfb108c3120de146ce648e9110dfe3d33a14ea3dc2b197e20247296c5241bb8f50cb4800a1f4fce16441bec37e1de51cc802aea226cb43a11e68c08930ce4256aef935c7cad23edc24b3a3166a7d95c055bafa352aa7e12cb4688a5f9e703faec59f6a86bda01dca4ad57ceb723d02cdb95ac21c237c5873900a8c3e0d1c94c1118268a997e2f26a16b399bfe00f241c15beb55e6b36e86ce4e17a7dd44b2af60c72cdb02a7c78edc3d50261513f83290b73a46218b13cacf3652d1df95afa9e5ee2285cc23e788acb01b157acf4062d3ff64aa90a58a6b7e2309425857ea93f9592996f9bf0709350a229908518e861f542b37360d7f02843878adbd503a985bdac12f510aff057efd98eb05f97ef89d462f4ecc3cef81462ebb95da4128d4e17be8061690ebb0230a01b45b6b06aa5603ab20d88b8809ab0434f217e30e67d794b15531a567e161768a7fb9415a36a727fb6d2d70fe6faf16c99247e7dfd84eb0db9f29297149ba8db87204abe5820695fcde47c179bb1f5f50b7a2849ae5443183fedd50312d8cec6e6af2fd6a5a97a2ada8703b1878ddaee529f3755882cb9444c9296108302cc1941198987eded427282805169fc29400b7a2b14fff0cb94098b428f9c3eb75ab20cb7a730e3931b3724d8ac295ddd2e58d3d6b37571a2121bd7f5d8f24dacd779f98a8205caf6b0233547ca91e13243c41e1a5e43b6f611b21188172813976cbf57a2c439f17c6948430fb356c95494a95b890f73c68c846214470bc5034a84e891143e4968ed3d8528360c762321156bad7eb1bb353d8d0866f96b077f77626daa83a853991bd937aea6a793cd09b0ed221e2304b370c5caf622b2bf3109cedbddc2a8d18a229b24d464638fb8d8666680014675ebdbe1968477ce6caec3eee92fec6fc706018b6087d938005ff6481e90a1c355a2f7634911182aca31a0c3488a48eabdb7964809f0f5feea081b45dfb603d48fbaa5e5ee9696d308b4bcdcd2721c312d67d12fb4ace3318f6809e004777787941c6e7266522efe65522ed3a43c43d29ff16178205b700bb910fb81a6632ea1635b44d223327ea5a8d8507a5423eb1119f748f6215422ae6a6525243ddd9274c9242ddd92746d48bafb46d2c1c926ac3f61083be21c2efdd23042148977ba435936c09699b2bb7f97b2f3a54a511622cc8609bbb55284dd593784ed08f7614e66fa956c118111fbe05f06d99e59a6d51f9669ed96a667a669b4bba1e9d1d0f4f2db325defbe2fd3dacfcb74046377bb00627efe4bc4dc7f2766786162e6d3c42c1031232b45cc7babd49ee31c1f7f921ca86ea938d9df50b1ca545cdd52b16ca858fb8d8a673c36242a5ec0380793f17732e6b8c61f93b1f1ef92b178878c3526633d4dc6c62d19979a690e898e972ba609888e35d1b1f46d356e6ee9381e838ea75b3a8ec64c474d951fe958c56301d191c54a7f73878e1c5b72643acec6ff2a1d3377e838b141c7a99da2e3ccbea1634f443220324eee90f1fc03192fb7645c33192bb7645c1a326e7e23e3787f878c979fc9586632eefe5d32ce57dfc9b861326ed364dcdd9291cef07b7444d657f5132537bf31c75b3a9e998ed1fe96391a3a5e7ea3e39a6320888ea60676ed0e1d19977fc4291b857f978efb3b74bc301df3693a166ee9d817910c898cb32b32f6c11d87296f669a3b1e6eb9239371754bc6f298d14f6bdfc97849b8231e6b111917ac2c4e26dfc9c8f9664b2663e3df2563f10e196b4cc67a9a8c8d5b320e44c427f5e28a8cc0329a6c54b693cd28758a640581aa04f2e71fd7ecc40eb2f5a6aa4b5eb07532de7566445465628bdaa60eab5b5d2755579c88d5d21aa41877e9f13d559306b51551e8c35d15b631a2618d4a25e0e4dbca236b5fa41e8810be57e0a656706d44b3f047c4aa93091a833500ea435063dd6cc9358cca1ca8140ad12f60f6def653ae4e91c49d2cf8b139fef5361318158076990cab036baa567829da7166b496643c5e129f503f1aac144b8839a9b963ca55795b62012f65ed88c5756460ae036534340f6dad0f2921fa17582d3d042bf86480a75713fd8c0bd9df9f308403452faed5c621caefc75cb7a5813f82bd9342c12b3dd03f7538661608fa38c28d0cb9b9c498bcc51972292c8e1fb1852d6a0b567b087253bd5491bd3d6ce03a05188d6519e9631b45f6dd7e8e6f96170ccb7a01670f10710d78043648c6cf3bb4f21c213a25947b74b7f4af7d6a52c0caa0825d161c4986b037949f755114fb5b35afe86cd71c0b3e85e79c93fca61cd0ba25e74a34a3377c6e29d1d55ec9229e429a60eb0901f8144dd587051b91a435f81d3b55f63f621c3612d016a94eb55ace29aa6d4419478f71c2dc1f314a5d13edf963d6117e84d2cd881ae9a01ac733cc3f27bcae754492e023510ea8bb351e78d97c00824b091b1709df352b89629a2292e8ef5547367591d9f99835a00dee6f2593674eba64b26d0a347dab9b7c794f385db8cba5aa2323a895e2388229a2a1a227eada5a7211f91d6572ab57342d69f6383ccbf29402629770d2a14ce56032e13d3fa1e1956ce6d5e118ffae193b6a3765f7fb54c597ed05e348c6705b8d353197206fa8ed52808f2344bfc2e1741c5bd6265481e186633ea65372cc179c6862679dacaf26d613eddd23e5b8d828d1c3198c0576576f11b0d42bf728fdf62c67a554d647005f549eea60a9854d79ff4df3ac49b82107aa3b03cbc7019897399b2432653ced68fc44230204824218f8e92f060468bace88dcb71344899dc83477540c9eee6bc5a74011545e3445697706bb1e732010a0b03bc8f9211845240eb88864eea51371d54416e154eacdc6e97411b5918574e04988200cf5613e92b34a08e3427d5cb8ed7a6c65ab9261d1d5426db8d3ed981c00224f15de29440557d44c11e482a06a7acd6c289498a53385c36a8457acaec62742b20ffa13c92cbd95ad4b2a1d4575a25e303341eae2c57a027d3c73d1c9ce1752e5e402739b075b98cb13763a9bc3ce58d91d4c632a62d8611f5d2f07def859e7d5398b70102e2910cd8ee468a61281259ab1c0c2cde1966b6d80c6c085da3332415a41a5763a9d2970b97660f1a723140ea306e1aebc8d536f19efd859b363ec5266f7e1944e51f5badff16037295ff2726e1002e2a3392c9558cc203367d105b8bd96769a88b05c8d64762826bc2bca724bf6a8c13095be48afda938c48c1c004ad9397ba35a2d03d61cfac881c118c63b072121c83a593d4dd02b897fb48322d463887e875a8ab1b69550c688d1f54716ad3d1f08609ce01cd9e83e8843f279bf8499d6987bc5090cd70cf41383490360bb17312515b398a786935c656b62d968ae4a6998a53ebe7be49564bb4b1d98a3fee5a086b8d562853549862d1f0505b13baeeec2c48c5c1a9630846659e89e7a8151cbc664f06e66bf4b71e0b1c6d5588c3d6311db65ba6b5d01433446b7656579efcf98326da4e4e3915660b172875148ac8fe9aba595bcc6de74886fb852d16f46d73bb5d24c163625322da730431a4c3a79e6370d3ba142e22098e06403e5e37fe7b64cfe4bac0e84b8eb03f110a0b433a1b61b6e0866bb9e0705312e04ef6c9ce76c4a8a909d95c492c7d31a478eddd3579c3a8c692cce59a4a9a34aec8d9a87b30950520ef387a80ebe644726d869bb43bcac0489f26fe9222a93e32845696536f592546969ded73709368e59e386180ad234008cd0331670817d025a978af85e8112120d915da766e656c27bb653cb193ed32c1e18cfd72a4e21aa800f2850dd33ac3f8de6b4c6ff53bde312765b8ac5e351f11206a823ccaab0679ca05732259602b7e71c635f9f55816a808c6acc7213414f2e9ece48cdb976714d5fafc0785b1e2cb2ace96ffd442c9ed3b07c2fbc02b5700ba189e1a6c1ba1efdfb3990b98b4ed0d849516651d4e15659c464aac11e41a461379674b6d7056d621731bc1bc5d27df91aa91ac4b87fc8caa480d4536148d07bdf0ea0f659b3cd42b07ca70692a53c19fbb1862c324e1d7d7a8526bb67efa3a4a8a11181edfcd4cb56aedac521c7568068335779eea21a9c6dd311e5c3dc6bd7b33c6ca54a662fb2e09b2c5df1c239cdc9bd4183bc23d2850f8018b224ecd721b777b51af3ff53e2b900baf2047642f76bb1caa70d825bbef2b1b88d3433f47eceef8e096e4f5366c89c3c345f6b20972d31f568e8c8d81e0dbf70f4ffca4c9978d285eecf48072d17399d3224af1e155bfa760e91d5da41ded00421efd8d0b0a5196e5eb6dadbe6deb704f11735aebd4f2442e4a23ca364616ff72b3535b2d1ef581f36c00578e0f0cfe4d1b9c9daf9ab37f262309e700912dd139afbed0ccd3c316e4e4263c40661f6b422bee817d8c71e094c826ca39c565d257f3c4454e52fc056890feca97ef7ce43d424cd302e9907e7109c7299598080af200d099d1224eae510b19216ac51f2f9409f3a4acb1da9403e411abaede66dc700ef74a2777b4aede3277532a3a45551554ea8d1da15ecdbbaa5c3f8698dfeed1cc8470def981643085ad3e03bd1306bf5380fec970e0ca6400200426a96bbea0a59744e39dcd03b14c69996803f5bc778c9aa99ece6ff03b3be4770ec99ce10bf111f5b3ae989a0a16a888760642cf6ea6994519196605f957a03ff3996d486e7f2e987b2c67c8197859197692463361b214385649375e4ae16d640923b842cc39c57c657b4270caee94fcee09a72091d173e75c251973fb68928745989771644949e578a3dcee7a0ae2f0849aa84c3321b0560fb570355b5d65ecd30a512bc95594cc37c58c80a06a378412a0bb1a7326b5cb918d3ba6cf557bd1aab7b26dbd4babef940db7b9e2d57ad94ea5f02ea4bfec6ccac2b691aa70a024b6a97ccd72ee34efd26dea8c3f0e4c696306d8dfd1dab5bd73ffef9b241c2182dfac0f393b6d7d708408af0d0f1e290a4d51eadfe7078cb30291694aa64365ca3597df8c2dc213a25d71895dd853aeb4aa57e352e6d649b28b56ca15d810a5281da4a0adb6c59e1d9c06040e2d8fb448fa35da00f642a62dd13f2c2842de5353f76a696024eaf3b0b8bfc07ac29dc93a491827a967ef2c317b0d9abdd1afb3771e2415b92e03106db6ba4d17d6c298271e5614e637cc436ce95cf487faac9c1e11878dcddf6ed0475341f040443fecfa4dbcebf95bb8ac74e96a7deaab942ccd576d0e9d0b8473b218f1e13e0ed8ccba42faf28f53b8047253fbe62ac9aa37fdc31d46e10691bdeefcc64a18b9664635c63b95abe1af677869e3fbf02bf1f0eff01a5f38cd11d9752e34a9799ed41c4daa8fd99bc250102cd6a9627d1c11db1e7364acfe1d0af5b5861ad65b612d7bbb17245853da36ec5f9f7902e61375c9256c9265da98ca649dae721c9ae49b7ca651993402ca95b714a952fb0714fc7685aa3d1c49be094f480c3e6f382f97d13e142a55bb94b2d4625d2adc1e20838d694bd652717d8b301e4b0745838a538e2c234b570d75524e5c677e3a45c43688bda3a2b8f6496ef309fae3544e263872b72839c6a556dba59364df89ab3b04903df5d816ea6936553fbcc1a3a3a4a04cfd1b31978d894af54ccf7484fd72289888cf40f419a501522b61d8968f3164c3544e52f575fb259619fa5947b40a9a11bc12fed51b1dc75ce530d0a23aa25d47a9cb2dbdaec9d9a15bdb249aeba506e8d335caa7426b76678c7980320a40ab0cae2fc63983e3c47edacf37307f153dc06043152bddbc7edb4b27eb8bf0a3824f331d87785a7d1e1b9ac539de8998ec486e65b1413cbb57a3b1be5729d7732a3f62aeb9b1062670307c4f68d4aaac4d8092cbae2f72a8b075ddd317069a131dd875946750dd02a5efa83f475cef35f8810b9dc837bb664f3a9fc860d71452bbe634fb1bbb46152cda30e787b842feca85a3e4c08e73fccb3b42cde49c1d94174462f3865227891d64fc45e3390717cc8951c5bfa30645561ed491ed2ec4d759ffafc345f57230deb129fee8b3bbccdde3df4124e3131256f4033217a86a4eeee138c37945331e3fed98cb99bee9a42d544e1d28f2de7922ed6c4d3f5413704e1bb2752b413c1167a6fbe3feef08f5e2c68fb9c27e5b6fe5cfdb9cc39101c23f2432ac509e62552736712015602a8f5bb604253e83f7ac1d43ec54c0c1bc3c40bffb859385a0f4310e4b1e8dd32d9c15871307a28f52066750869c4e00531d666d71968bd4666f2f68adb767649c55541ff63d55ccb4ad374cc7e0303a5addcb15644ad51c535eb4ca29118ffa757c81037a42c60a2eacb085d1a4b3a37f5577ccc586d63480d6e68322e2e5f603c202a3c17d9017840ba1d2ae583096d652a1fea949ec45a2df8c9c0aaa8427088448ace4121b69adb88a29bb6c908e46151c1a780018e707492e1ab8246c2a74679183d759a0e061502cd1367e9b4c5336ed0542ac5bcb06d45ecc1c516d4c0441d27b3f3e9d2698b21557898d0da736634203032f078fe55e168834445587028c89a5335949cdafe0475845e157bfc6bf2b79c80165ce6cc8efe9983958b4a27b943f4235a1c4e08dff76c06d150a46c185d7ae7d248cbafa915c32b5ac7663c6ab7484fd9207cf20fc953c555f6aa2f04e03dfc18d7da8e6ce4a6d0e267dc111e12b717564017ef6b3be187eb55363082bd0fa673243f55e1d2f4710ec1939281286a718e4f01ae2e2aa4c3aa4372374a6a7036ab07154fe16211d1d41db9a3cd4c0feeebb28debee2548f11feed47940761af242a35844b76e5e5d62c591f584ca0771e72ecd734d3ced955ec19f76bfc2f95d2c8936ed92a00dd7d959430d9c822fc1bed0860945baa618d3073b746ca747bdfcf9a3272ea4029894f937ed6a484d8ac730fe8783e38d8cefaf6eb1e7ef86c8c267f52f9b7387bc47e03b9761881b7cea456fd9833ca2f739c74d315903314596af658db1edf75b700e5d9a3fef1fa159542f6648c26d01ffb31eb8bb17cbad12d76c344b7d80f13dde230ccfeaa5bcc15adbc9d822e755c806b1e7477fedb9e9ef62b0b52a5deaf3529f2c5005c76418935f6fbf7889e1f0ee0eacc4e1dc0c7e4005ee000cec1b3da616b4beca62903a12283db6dddac25544d5d58749d9ee5d503a3390702ad96eace0dadaadcde40c9eb6089edcb11a55a95d7e3deecd2faa8684d41aff689309bec835d404a4c725a710b3a2e670a0336363e634e20cbd2d374ff03c0c34fb07b47c47df446344bbd68a879d649a2067cebcc22e185c0f70352d41fdd05bc1cb11dd435d5ac39ddb635d153a5765c3d5fcb8b0e50e40ce85cf69b05c620ce2dc828f98cd09afc132d641434c920b71bb54ff60f7813dc5e2df375fc31f4ae2a90e26a205da546e7406b0e4700621c82450957f56c15b97ff475f3826c5bb8a7f731cdc381fc3047c6d1ab515c515db252c7b8e1907a0eb41cf2f4ff056b0e955c12c1d52f73925ccc13da5cd002d6d80117c02e74509507520a4023e02d324872b48f503d2dc8a33acf48528530e65e474c90a227cc526c6d36b06a8e00b2bd947bea43ab74f1e24b648e8ae415dc68a53bd98d705e8f91f97821303fb7820f192db1b82354b2439a7e11522aa6f208c29018db112847010bf2818386f01d0619a123d4d131daa95b028a0e554269bddd30b43989e8ccd18ac31b5bd765f53f6feba210ea40cce4bf65edb24f767541b60bc46d2e0e3299f480595f7185ea8b2b5649a846ac315b97572a95ddc615071bbf3fdf4b3d5f5da938b171c14556685b396f6b5459a9af549c62caf96dd8784e935a9418eafecc55b44bfae0a8cbda95716afe02b160a98f912260fb2e89b37cfd12d36029cd38c9706e006bf30d5e4ed778a445f0d6bdccd1607b394ff3ae05b07a97b46b2eb24e4b7baab2a63c8e9a59f0214b145aef1d464887c573537aee24f7900dc7a90757d6c10890261d95400cb8dc577d986d899afd0e4d9ef73af63f8c28d8ffca4e3668a1f37d871a5d1945027bc9aeef886649d2fe2ddb56fe00cd3c7a37d32a8605aa0e78b21a005e9b224ad62f53ac42bbb18b87d911ce4c659035f41d3eb6080e36dc2c5339a22b9901b58f0cf03aa1aa971b108d7c84a220a7349a798a660b8b433f509effb2275aaf544a9db8c822c89a9ea4099e3b4209e99780ab7cf3ba3a160bbaf1798e4a87746ce4913951aa9e265986fac22ed98baf98fcef6b19971f59ca517a276d9309a168085a50edc5408b3c0dd5d87fafa2bf6ea78f80d4dc4cac0baac3f8134e7c2706a0baa51afb25504950d37a20d46701c5ceb70428fe58e8d09bf22802794115cd33fdeaee706fc35e15cdbbfb427dd43a389af9f2982ea743af278b94a52459980be46092926fadc354a2f47c4026c4cb46733bf77d44542990fba2c8ee8bc9e46fb82fbe1221f5f4f5bb903a8290ba6021f58c732924d42cffcf91712e88bbd81fff9e907a6d25da2742ea8c0a16b8798ef642893cebedcc469d1f8456de95c425863945851eb03fe1f86d6de09b0aa7b36b2116ce2c2005be335c0ca3a188b7e913ebcf542ebb0e5cddd28223af9566a17ba4c4b7015ca0606e3872e9e41397557e8da55f94bd4f5fcd37612b467462b86585edbe889caca14bba1372bfad6c16afc9ceaf9a258e872ced2858a6cb218e646ada03b438c399004aa88baaccd2e27375474b9702e45dd4bd749b47d2c15624e7ad59ce6bc4eb91c41ac6578ba61c4c8d609a67b009c28329c39b52019231ff3ad4b84c932bec82bd1cb1cd8d405b565cd291ba5a637d6ee5067ff8fa0215d0921c9e0dd6b45bb23842ace928c98cffadf4f9af8b134fb0e17febc62bb4003084256fee6f656ea753e66993838ae95bb069c37ac7837ed9a04b2b142531ed0b2a130814de399310696fbfd89dbda0ee42da6efd2aec8d359b331dc9ce87f719051a4171263dc57b493237c84ed3aa7d654342e7a03c88afa44d3369b321d032d3e84861161e229e2658f061bd9eeab351077a412af79fcb706f2b8c61e4081b88c12d4826830a9587d9a4f32678d16fe9c8195c3e69325076f8f879fdb6305b956ab79139bd3c4ff24b7fb69d8d63c71929f14678cdafec7813b8b5b9fdb7c5d7a8b9e5eabf3b24cedf88af0ea325c7adca69d3dc1f7848b25419cd17e28936e873f129699389d8448f80521236f55ad69ad733ce862489a372e694fea22d9c19f71b08f1ba85d1752d0bc640a5c9f2949005b19ce1a6fa1722fd1efa1f0ade85094d428333e30ab56a2eb804ecfc046d71c7dd2251c1294836f5bbbb553a12aeecc27b91813dc1aed4e4f55d5fd85fd9307b56aa22fd3c125de6087946a40f41d9d96484e4e0eb44d4d047bbcd6b1ecf21edad236c5c6625d0dc758557503044c3f47ce08a88752efc3f4e60840977e062a49220b347f1b6a5341124e482b21b50d92f47bd36cbd2cffa6223bf109602a0ce32b853670129a69573385825ae745d47701b99c3455e8e4f6c43572647c22d9539748f84b890c05ad557b5cca6753c10eab921ef0a73c70dc57ed9919c22086c2c753f54bfb55e4eb5a1b3689dc0e8b6d8cfbae16a54a6e244f168310daaa8024053d1276bc5c45a714f07ce3383a3f898a1c4b98d848848ef0938d7cd59c80688e3d50f06dc0a6a4687138768b9ce65842f6c63f53951b3f6d373292abb6aa768b9bd7d2113a780f8eb1f66640352cf4f0951afe62651d399d086f0aa6073cf5ee6704321f38a25a6e2a25657f4567f72fc213f3d69081636b3aef22e9a982ff43923c934b8ff39f6097651ccf2ef5f4e9aade298fe5f9a1298fb336761ed4fb1a7c7a06ae7d842c7578607c9492e04d1fcf4022f32279f85ab63ba865e1922d19251012b0826368dd8779ec198fa8bb14947a402056ed6cd0ed4c7418dd3c0d1b1e9c51555bbc0d54e4402bc0ff5e82161b506fa23bbb588d5ba9a7c94b61af16a4c1591e58287aa204f6b589c13cee91e7169b059536846fb81ddaa7ac7ef712f9cac6d1231a7dc5677e312a44e3ca0e323fe1e6995cee651504307651217cd8b735e53a6de88900a6df6136b6206cf58f57a7bfaa55434ef5ce6d6608f069a5873e14d12dbfe549d253919ed2564851a0bbfa3068c588aadfa642f8c9084973eb7f83bce4ad82c19b2f7a2936188b73f945c465e7560cb29d81baf1a90a86397d486dd6e9c1042339177632116e3c2acbac29ea87904f3cba59935991ced79f22554a62c1b0a8b18a2f8acd2d7b974705b4058be4b2655907b7259337ea99b8cd4a668036b0be49c8f1a59f0ec48ed3396691452d99a785dd14ee9594917ea2427df57531997da97f46a9a2973b982f5e02c7db2fe08082047bcb5dd98414e6b40c7d2fbdd877812ece941e78deb6fc65a91963e3d57eb5e4fa2f96d8813781b3bd83c01559ab285fba4d77a2c67b428e95216d726ff7381ad5582d0709e625087290e962798125c615fc05ce87fcdbf4308e1c4d918c2cda0c1f021451855937cb95f62e0d0ca13041f733962d737964c04dd414bc01bbbd542e69e9e6d9758ea0387ec160849d3abd22807b5262c8e79c0f161d5f965dcac345158f08c9b28764d631c38285ff09c75ff1ffc2794d85a9365c236d912dcc92f699adbd9be96d56198475e2624d812f3135a0431e1352724eb75bb00e1899d034aa82f4df47e8cc115d75e55a83e65b8ddd52d84ee857182ac13df21cdd05887ae9e410277ebce9dd56f77823440587267937e8646600ac24704cc3abd37ecdab761d3ffb40c753b6a87abc69fbe8d8d61f7d542fe42b8e44e82d20f1fe93dea38a6d2f0b7dedc7b23307756bf7e690bf37b7b07b1689d3b1fb4f96d5293deaee8b6f8762735410312a4bf8fbbf2dbe0122a24dd39e4d7f93bcfdcce430ff2b3488a4d387c2745b974210555f96d8a7e5e243734358b71f5db76f86577a54867ca5cbba81d72ff96fb0f6e5d4d53e1db000d8d0edf286e06b14bd3f5aab7ef84307776bfdd494670b55b4edf66d67cd0e1dbcca6be27b97335b197fb93042ef3f30afa79fa92cd72b54c7ee00bd8c9f79ec136bae166a6b7d9fd2fc5a4fedcdbdfdefca959f899d6090f76cc490cecc2ff88a3ff3cb6bb0cc3a33d798fa4ce5f9d51ffc9acfefccc5a32eef6377aab7ff94d7f9b9fa556fdedde4f91e1170afd727efc67b77e1ee0bdb30536de7b87a56b22067e58443f6fe51b81c170e2052c3bcb7be3cea5a7e9ea7cdb7ca75e8a15ff3dc25e4d47055537e7f71e6bc0c6b0bec7a71bd7cf5df559bbd3a71965ed6a945767c97fb8047fdebe7f7bee13a9eb676e746fea9d1f7935b8eb3d5911d112f7789b73c3dbae46f093f8f2333702757e79e8975bff0993b8c7fc2196fe7c2cfc7ce7e711dcdb4f78e6f683ccc2829121b8b309a3ff4c66be5958e664fa3eb8d4ecddfb203c932ce02b76f3ab8479f31e33825ff5937f76d2fe9524fbcf160226e86729ed675adfcc9cb933fb4d39f8f94b7fa6dbcf23f83b1adfed71f0f39dbfbdb053dce23e237380b3917b24e77b5d9610bfe1ce8c212c1062ace0982b48f89c695076820bcd71e681623797d1eeeb8f0bab7ee63071ba97a3f8fa700243487d6910be1c13e306ef4e6d4586b0a0486e2e058f2f993c86420c290c5c556475c57600b23cb44b2b320250192897d3dfeb68d2cea56c0e70af346466c96e364d93a496a0a362f36749aaa445f37e8b541f0ff75b38498bc7fb2ddcac6780b99ebeb508f5a77a491fcff7fbf093162ff75b04498bd7fb2dc2a4c5dbb716b47268302d4cbcbef0e77eb39e50916a2717baf79b11246a27e9edfd97de7ac9d83eee374b56b52fd44ef58dc557a8cffb0f70fd6311d067a941320b5ff71f680bb7915aa5178a9917ad2dc5cc2b4458229a32ccf15a3d335e35027b0d2ea318e01911ee9616e39cc7c6e5c33bfeae4b21466aff4eb0f99cf2dd11a277f3e8e5cea34b25c4961f3dc017977eca1122382fb9ecc586cc8d9de9c6beba7f5c52fcf0c24ab91022e34250421cb97bb6691ed17da779af930283893f7c1b0165773d7c7b662485fa6ade19afdac9ca0676ebf11965ff8e4027330d43534154a80a96c012302705abf4574fb60cefe427d7f4a45bb03042b014dace3e9b684d0689ef5650f45b641eb3b6781575ca007133885776e1d37085fa682086d7adf3bfc99d0b73de33ff9bdca921618c4bc4f7b229e011670c96ec944e1c435ba5c1fa358e1cc3f454a73fb4ce738a5a8d13af2648ff98010fc01da3b03d5d55ddb1678cd6caaf5218875fa38e552447041de7d51111eee205c243ffea710cb235280014cde36fac01e42e4fb035c21b7d513e4901993f7ef581e216ae9ea8520c853b46e1516fa23b7716b2869878b7e625842267f6e3984bb2fac2fea0883261bc4cce7386ea8c78111cda6386d1b445bb4b6b01ef0db29e78ed460f2972bc101d466df4e408d5ad9f114b9e22a623ecaffa9c63d0696cc93d5738e42a791cb5e1452e23b69f179a9b2cb4c754aa12b230495e31ffcf11d080125462d4168cf4f12f2dbe0d705cdd15f28afe62452de41c8176e3f6d553bf2eda82ac72b01eb25408a793c3c1c3ea00741b6048e42a410a61d6156749ced39d446a2d9c9ebb104bb065bec47e858b653c91c9d854778b6cd28054377f51a7b17c8cb95c20b6dcac247195d1cd3079357257d86f7ac912222c6511bd01734cb819067ea059b1224c9c4f49362a92dc2ade4bc2ab727b083b15c825fe929cc7771fa8c72f70843d93b58a156f4cb3b26da13c7cb5eee453980975853e8ac883f348e4a265f648c4e2bfa73460b7b9c4ccf372f492e5f8945a8e395e64a9c5a65eefac33f57a6789f9efe6907e52d62d8f751fe29db591e64b847f61f8d8eb155558a6d759064153b4be5ce162a8adac279a9c74eea6fe47319ef6bdb56d3ae5cbf555d26b20bc92e23c281e343c5f44a0678e93d2074383e21b9f45e6e55fdb949d495c929ca49d47749da36825eb2d879f5c3c0814c11b985831f38c7fe84ff205ea39ba45201b6b31fa35eb8b07c018b8231e5f044c0960b409d3d4d11d34918dea9606571d5d35b4dbbcf65c3158a9ea3a3def9da4d875374988711963d60053db7ccb31b7d855ab67d679a5a05b4de3afa33cd40d2a9b2d0625398797ff4c62bd534b89721f9a549d2f4466a592628cca51dcb07f52c5599a0d447f84191cceed214ac36a36b5935b59a0576f656b4c81013bf90ca8d2adec1c1e0899ecc205c1ca585d401540f44337fed3856a547bf8979bba04aebe6e18a90d3c8288435ce8622a32ea79f038d9a44381d91ce1d2a328e46ec2154c0a936ef9c524713549de53331c24ed5f7ee722ffd2eef0c4a3dead8f1fe615bcffb59e6cf67719d235179076a17733de24877fea075c8a3678a848de3ae9ae4a3b95ee2ab352bf76e5501e4db3a44aa76fa3625ec43d551e7ee928143e81b43f50f0f4631e390873fafe471e25ffc251ebbc69260802fd65734f78a71b1e1726d3f79a9a3e12e0fcd7db79765fb02427888d718ffc2f1d070bec4d775e4f5d0484a4bb88e77a2cdfb381e88a052a5800e86adbe01fa1b09f4a74e7510873c975c8747372bfef03275e283ed11291bda6e370636595786c6a823e75d3d3a2fbbbde57e3bfeccf130e45d42a92da03a05b1257ebd2053ddec7ee163b30fd2283abc56fda477ff9aa50b46a160494d0e5a3339e27279e27c73d7e971d6bb8542098b417517fc23e2c5b37bbad00fdd0cd6f6e05c4e880b6a3c3f53301146262f7cf78dc7e303bd37aa9a2fa331d06d53f7a10418d529028d7bfb5906b4e85a64e4f473dcb4faf67426bb39ccb3159354d918886850104b381f945631e24f7bc99dce313fc5bdbbd96f3922361b7f916abc47f921170bec3e818433e254b145ad958ecc2a2a692c6b6c310f6fa922049ec405f68616af7c9e7aa678e11d3dfd5456832adf8b6cd868678c950f30f0bc29b6d4260709562787cf3b81b8389db8444c030ab76a4f4cb9c97124738e3a4238c81678a5b74fe104bcf4f919763a596994a969995e6e6bc7a52ab48eb73ff7401a90fa0d8041ba2b57ad982e6c1697625ae6510d79df5449b0cad4fa230a038b4fc20eecae79515138064df932c1ea1fb234a3ca16b02c1ee9ee00d28718953cd402910fd39033879883ae807c1c508d8c632d063d7a44ed6a027ac9d955e92345d0e255117e496ed3058848f0981dd14812316f8479534c5f4fa2d31758bdfa87c613dee9cbf3d62cb0c9e13636011d89d6746666f649eeb4f1456570a76aaa55ac85d2bd903556006614fb20eb5900cdf8326a761dcc29bf1e25bd725fcdfbb7a4ae29f97e475d3b8e73521673b64a56e8a45d37c93ed20174201ac9d2c1089397003947d6781b73a840cf175af25837239270a04766a4053badb94568d53c58aa5ae7f6a494bd14975fd53c3647ca6ebdf5f5ee397af2979d09dc83264265e4b56b29654bc965ca0bd2b413b4c348e5056728fb7eb4bbdfe274b0bd31894ae37ec7e23cd8eedd18e7d11a7fe0d0f17de943edffedc62babcd38ee53dfad76bd29737925df910c92a1541b128ffa14950f1bca777d885de19ac98d8abf790dee8f0df38c2d11bb4799195a365ce71ffd9186660077d4a08e9a50809fa28015381121490abc48268309562cba72f042d2520fa95a4a8620ce3ca2dfb03f5bcc68de4fb89729a5eeef63a304450acdf538452344132bacbf92fae2992eed3589f2d3e221ce1bd1c58148d77ba239aaf7c98551f521b1eab808d09ae10746a3f16b47ead1e9766e7da9c00e2bc2df8d2918fcc0d69e52f6f8b2406d63dd37e0de818f1fe5c68bad40bc1fcc70bfec9fc259c3d9bb8f238ba8140e21e784ff1b1535ef142f529d2207e7806341577874e9c3db325a0a0382b5662ffeaf129ff3b01ffbc7d1cb3e9dc3ecd8955df9fbe1efbf222ef3e5e70ee0e7dccbd5478cc7ff1f835d96e1fa6913b95b416a585341e3959da8cb6801f30b3382569948580def89cec133f368808f774626d00ff7ac9faddb026b75ed8377766ac244cebb7cfac364cb0cdf59dd6ec460b24edc4cd5d598f880ac5d784f52c09ce87c2ecc926f0c0b2d6375b8a33b393a7c683f829e751b38fc24f4f8d1f92a7ea213fe50b6f111b4242569c62d20529f97d57537758c89338624fa6f42be62077942cbef34dd3a2eb79308c95149b224befbe104f0b1442407ad823a946ac27427f512bb5c0e2211df5f1488a09b46b6852cb747367a52e646d7d62346cea7636628812fdeb8952dad7f414eb7b1e45d822a725bc519258758725173e7d8fb2387d3673da0f374a7bdc534a73276172a5feaaa71b9d3dee697435a4cac3effdf86ebc34df591377afad98efe9331332c0541af38dfbaa97e726b64598cff8e9d1fa2a8e4900d47e439aef18d9bf3e597bc083be3e89cc0e0f7f93ff4fff57dfff1fd3f75b3fcb768e7ba9c131d4a5ffe3dd4fe2c0baf33ad1b7c277347d09cfc99c059a9759af2b9e8a0c980cdee409fb6bcffdeca8df177799cc2c8155d9efd89b2cad5c7fa62128054bce91cfe34573fbde24521b80d8096f32bf4f2e47b4c863f42a764ce329f74a54fe7fd9fbafe5d675657d1c7d20a94a395d022045d3344dcbb22cdb778e4a54ce7afa53e8af4182b23cc25c6beff3dfbf9a37c343240022363a7e8dbc2271cea68381097b5258ad7deb5b8543eb72058691f3dfcf2b7c7c2f1ece94de677715b3a723a140dfceb6774f04b79965bd78be7c7f4137f4356ccd997554f7312c69fe64eea60f39e4c61fa50fdf5f68aed014b9f138d72cd64d389e3c469c8d479fc6a74698fbe9d445c622b2a56e1a09ab1c502e30451d6b5fd77a547ace2bb6e2e82fec7d43433de1bed423bd5dbfca607e3abd9ff774e04f71e59d988b58db83aff0c3f22179d8d3e3bc16a8d59925024a7095da26e2493a2c4f0b4e34881d357275bd62ee9030c482f5d4e5de6971bb7572ec975b7ea9494a101bc41f68449f113a46699b90fc915179274cfd6293dbcf13ea610a0b96cf68cb787800c3bc6fa78f40fd49291c8c7dc642ee01df4104d395adbc85ce663562dd8f277c303124f17c704bb0496cc901221cbf9ad60d2e00a059a8db53c619f085ba3df012733db0c20029849e659079cfeca95dc0dc5f5c621a990221f9225c9329e9714139fbd5d564cad025bef048fde7dd233d19cbba9df3c9f618a5873311db6b12bde5cf142efe187364924e06c2db39d99aafa9a5aa35722d5bd57fb09a3e6527a716f4d634de0db09ce1b2564369780522e994973035f31207ea182e624b18a99d699461f118388490d35947a2df5895ecf967a39d2a651994f3754c8b9dada3d909fcc9e094701000707d490ff938732ac6f0d880e34684787a6c56bd0fc6c4e71fa928a52d8d6897dcfaa67c201417d22733b8ca2bd1beb3e03c3a20cebef10da0ebd9e31c5c931d7511b8b72475be8d19285837b661c9c215d7746fdce343af5cad031fcd78e7265a404825f6fbcaafde8722d8a931f63380b3dfcea7c92d1833251f03f28d3348dad0884e817f5de8989e8b67c2fa4d052395b320313cdd560088f329a5b30aae493713c749e2d8883826f6cf657500f663949253049c2565f432efa7ec4e11bb56e14414426cf82466bd7ceaec10ea1d13db26e25e3a13156c18be148f0f9a95062edb468e1fed5d580070a1feff2760ca50ea207f2ce53304d2cf855cb5402258ccd89cb0ca63762bd4cf9708a1e955d8cfa4426bd92b5372ff9adab2528954ed8077ce1c0466a6592e64f1d6fee49123e8ab92500e7c13f56f2906f3b675c3c3da3639d4be35740d4fe9128d61704f5a176fa7fba25e965b14a637cfa796e50e5821e52aa2d49750d88c1d0b03870c252f31b37d9a8802bd718a65eeb53860b9ca78c09a3c2c9238fd6b97ed101ea7ba1923516b1fd36ff2963dea9e070f2b7b8bbca753f9914c648489bc138bdc7fcfd4acde6a00553f73b7fbd9f9ce4b7ce3544156bfbbf5fde4e297a9c721dfbd98b3ac12a9382289cf879ab05549417e674f35f72a1ec33f1a42a44a0462e3aa675a25e062694ac3e945117e58602446e3aab7a4b9743fe8c78a27d6dc5b7306f2d6027f4b266e759ed03b33229e43e0a1275c60f53f500b457de056f2a484a9afc40c173e6e25f069ae96ab96f263675ba4fae9da3f5987e89f189f5687d4abea7a304a6edde7fb7c241e14b2503ade32f57b82e7a56d74741fcd2343ebc22265e4f9a01d5cfec2b47e259f0ed9eb918a0ab805c21491b2b4a0f7d7dc3fa8e00684ede695e408505dccce58d4f2d19a8ebf57e5bb6f1beec08a78421fda79753f4d94b8e13d61070f47094fa0ee06b06106acea6d9c3904796f34b6f5b7b16d7e3936ca8fe67fa4637bb7979ad5e8c56feaf4e19197fa78fea65666956f397bf25ddb848deaeaea4c2d3a6f589a5061ffd7131edf4d4b3a0ad7a0c71728b3fa00c45d58b3acc9a4f3fee2f4a23ea786a6870faba365741ee88de6116061c7b85be266dec6480e2d539bd15ea6fc467af5e37703c8c95ebda2ce0a21475bda8a5d091290573f393fb7fcbb462e96bfd0b3f326bef7f48f7af6abe1fc38073f0ca72394fa9b915067820d2c96d5130c30b4f6a722c4686c28f751f3739fba930bb968b0b9a3680d8524d010054e45e71f15203321ce1a9f2a8b0fe9d916e71fce8ef736631344e39d72c5660b049ab5d0831bc2a777262d42ca04c3988134bd606a6268489d582558faa6257546248626f78efe316b834618a7558ce6dc3dedb7a3a9d035d0f6cbbbb3615c5bc3c0f40149b6249920e65dd1d503ba33ee26a904e923e69d2f86a565ea0470d6a34885b354989b9d57b06b05fac4eb69b13bcaf7c2da4da705b74d29712dc7b43ca4d3d2fd836971b38bec7c5b649559e49d2560d82529c0e6c16a2ab1113c98d50e84b7526609c16676d3be3ed8649e958fc5fd795f4bc5c48ee988e2b77b6cc7970dfb950fdf91e6ba7ebe2dcd99a37da9cfa46e81c5d91feeb1edb77b6c67df63f306df6375b6cb0f10baf3958ef093f1c0ccfcb9b6da3764c63ffcb387a1f0e2367c779931fe84be457fe8ebe2876c254198ba19fee66147782517db0b195a82a1fc26cdd852a74d1f5931c0be39bf7d180a6fe61a550c7f0dc2f1b5fdc8522bac583da32e4945a9826721cf5a3d271df600f249ac68dac046c25668ea3fa6eee0bdb3c9b62fff6c2f76678ddca79de8fc3c8bbee98fb73aabff8309b604110c29036235ca48b893a5733eeb81f0c6ea40096edbfdb80f4edc183590e980bcf6dc85ac38ff0d9918fb9552b0f01c0e91d33a51bd38beb50fbfff978f2703f0e91918382b80c0822241a7cce06d0b4d8066f226df1781fef43520cc5853e409f77e4924aabbda419fd1bca6193b0e5de0d2992cb3658e336d6da95ce7ca1015e34248f96644b0a14cf50d5585b52544f3d17887d08fbc125e2c736b64d4a1a890a932f8e13efcf136ba4a106c8928deb37f07824c4995e88bb6a07189704e706e7d4ada41cdb92bb9e430a49d9bef68b1d3175718f4045deae550b736a2c880a1ac23b2ebf9f47d0a28059b16c7dd822c80c10819cdb017effe6026a0bc628cca35d4607d7463b543ba6d892080680b0e392cea3bcc252a3193636829022ddef5535f43faad873c23e37f489ace6ef1de4c832a2953b2bea16e761b0f94e38e07bf2a2047de9694bb01b25347a507041a50ce092a1818b44a6672a02ad7dbb6aa1821403f41bc21326a076576d2a266a6d08f7d224eb2a1d72b185a3bb1864c3fb4be55fa7f58a745ed12e271278262608cab3fe09407cfbbb3a21d2eea1e90bc2b6c3d9cb7a562b9c1c3263d0cee358b3b9631084b308642b20e17ae4ca18334b399e3bf8b4c37acb2a243ce0f61bc66e23c41cf4d8792a21145a247c211dcb6375d231946853aa41e0e14797a683f9b41d3d17aa1fdf64c9aa317e47d204bc50b75e5993ca15e68573c93dfd20b7df799f261be90d0fe4c88f92f64177ea6245e2f14c8f04c791a9fc868f0ac2743bd90cdeff953cfde0b89f2cf844da75e70fb3e93fcaa5e3083cf134ad8f3c2b9f5294f75dd25e0c1b9f4518692cd39a7d50562b37562793a1091c54dbea6dc62eaa029afa60165867df7f4295fec2e87bca2d0731a2bcb18d2d1002aa56772a413fd9343a960db3f85ce9a7692c8d91fdaa10ebbc4a30b9fcecaac1d25a08cc14aa65b1d34ab337db0a9741f5c9427dcb7c74b847802ce73283725e7ef0931c80f43bf1e417e7af70945f6844779d71e0cb5a6e3e2dedfe5bb227820057e9f9cea40b2d243ec0baf002c48a22713372434d39092bd398bb32140a915cbb86cad6e0eabcb9952ccf99ee36f7485db87c1c0b1187dcdd1d7d48a53858e71c23817de1a15b16027faa23a194b42271348753dbb3e83bcdc4806d8666c6dc6bb1c410d5d80ffc54dfe597833dcdf13e296bb351290bc7a9ba81a7d6d0ddca2a75c2fc935008555eb09e7ff09b3fff947b7e89cbe132de051ccbe8acccde07ad2ef7ce133acfbfc13b9f14271ed230b7fed151217cf4fef8a48cc6c9d929c67cd22eacf7eee2519b99f7798d992aacfbecdbfe86a6a13bb2d5a85913ca0ecf097ab10995580dfe47fb20035b976cca407a2f3640db5d1fee3a10e9caaf4f4583ba7b5be48fd1ad6b588c29f9479cbfd6ac24440e9b17f05e9f22feee6bfb89bffe26e8a7f713733c3fd1777f35fdccd7f7137adf9fe1777f35fdccd9f27f65fdccd9fb9ae7f7137ffc5ddfc177753fc8bbbf9f35c5b33faff5fdccd7027e1ea4f72f317d2ac71f24c95f97f24965757488a743839094a817f845f43c4f079275bf77c8463016c75c17896066eeaa9de5c35e464e6e62371342d97509d53bb72cb30a9ed322d97332dcfce5a2e5dd5e47c06951bf5ff5ee5bba28aaf4c64034db11f227fe5fe7bffe99d2f3c5873a2bba41fa1f0be4c3d7215886a54f2e6ad794a623782c7bc2762ff4633527bff0a899990a8b8427a1897f692e35386a53e6c2eb75b6467a3551aca326bda167b1acc40b21ddb3ca7be2242817cd27a7779e397f8f5eb078170dfd00d36b125a004ea6d8208d9de7861bbcb0323e3f09988d5057f48f8133d31bde6e1c1c0d165e136b28d57227c305d612b71e24aa01a48e3d67f4caabba042dd07ab6090bac2fff07b735d737aa44da6557f51f9773108a86f5bf994f6ad646364fea66f0b28ebc8dff6f325ed203bda9f38b5e6b9e3fa36b55e325423312e857a364eee37c54b58673f1bb770b1b43b66fba69eb6a149f8190ad1311e9688333c249040bba0a6d61b17fa384e96a937ebe086571333165d5ecdbb5fac26b2abbd24d5cd6adefd62f5129b7ef27b76d3709e33abd91339d3b70ae21596edbc277c226f57ef95039da1c732fd550e526b4b7efcc4aa466216a7d2f61ff028359749926dc74dd9bfcfbd0e7a42add4669d7ed3a30cdc2616008e269cbcd3acd22c5cb90537df11ebf00a3ad9279022326b1017f93a46d0dd706413b5502cc219f27d3661a533b4ea233dbe37790530c7d0df638f5c449729cd124c1975dd24d9b733877bfea2930fc5fd5dbe2845f7be0973721f3dd427a63561c779255c7aed0947f043131be80bc5b172c94de397c2fcb9ee9c7d3e672b6319f1f5ce318f19ff25a8128a7017bef761098e25c5d0faa5af5977a3f6bce635866718d927263a74e1e30d357c1fa86a79e3df0127827c4f7848456c86999994997ccb1f9598caa3660f3db294b5859922ae1162e0c29e0f4fa89bffd2f891729a68e5f526857db94e8f25cdc6d0f99bd9b8340f07e7c779a8c9b77cb52daab228194dd817a2fbdf5b60f69b700bd2c0f77c681ad01fe37220039e4dbeedbe8dd547bee9899142dfc6ff61df32269c1111ec8a7cb07b639a0e845b537fdfdf0d2157afb9bb2b938bf5d3e4c20c1118f593c34ede13de425f3b8ee0e88510f98c9f4fec92af3b46e1a8feed7f3615c7031a9c79f6e3446dd625fcd32bc0465cbbc899a6ffb921eca2ab3af661d8d8b899ee5fe93b22b82bda010da04eaa5da4c3e811b67737878db8fb99e4297fd1f936c1ce43beea09f7319d7f4abe88d0c135efeed5cec9ac982f82d44bea5ae5f8683786aebd55b39263439a62ad6fad59c50a7f5bacb1c225305fa5615a163494be1782317c9d88b524469478f33f9fa1e285197afcdd0c55fe0fcdd0c0e129a203647199feee178cc3d2300e2f9343c26d1bc6214818871dc0fc7fcd985abf558b0849d4cd335ff00ed351970e85c561fa668a3be28a702d7ec7017a2ff950b4df4af33f6016855efa93fc93b20a21c3b0275b7cb271ccebc59493a04b8eac16d3f787933bff0f27f73bdfa8164e64267722d9dd8ea69b51e8c6f0540808649b59db8883a52ec04f200432182d10b13c244bb9b7033336e730b2e794e5f15b73f64ac25fffb475bf792302cbb4b36754a5d39cd3ba27d37b04943d31d701e7de2ca3c14f165153f66a46cbd8591367a83e50ec153069cf1b8483136f1b21b0c76fb2b3007c6397ecdcc63cfeab109f230ac3524fc895eab6c757a48f1dc80931bafe46c6070e573fe0e620d171c60fcb1c67aeb4387974d0d5eface88bf7e31bf58fde041758de5451376f9b1315f449737ebfa145558f93053b68c0bb107a904e8930b0dd921c8313d07bb5c76834d118ee54c2ae5747bd0ad5532bf5a7f53857eb904eb95afc54cf13ae8b7ec70bbda5dcf64af31eced71687288a311cb73ea78e0c544cb970c51b17082600f3562b5ea7f32f748472762c2f993ab3a2a31b5bab05e96566d2bc984a2d03edd4e62f1aabd4e8484f540d1a55d3f5e034d7745ced54e9f2d82f3656e29ed5deb23d9b73cf767fd1b343991a1ba902f9c97f98e784fea376ea70de96def484613b33079f1c80421ca77776ea9dd09214e50d5e6e50fb196e2a9336d28ef4354f422984ed33e5be19bfb0be50d7a0524b14d0fc5897718ea2e1d1cd3f0bb74190a2d9f2c3d5afcaefbf951fffb2fcf15bf9f897e58b781b22f5b92e3f3b2faf2711e5bd961c1d917458977f80936b869e449a9404c25dc8a67756b0922db83405abe7056bd982eb8b05f5c2c58c49c2f059545e9117a8409828cb7951b5a2c532755583eb63b405bdf33715c421133d02034b653bc2ad48bb7020dcafaa0727ebbee6bd682764fbb93fea8fa09f6941f254fcb99f1c02cd04d81fffd0a1ae7063759467edae7edbee92db5dfcaa5d9178ddf7164be37ef62cc4f38ea04feeb7946adb9f79f668abd4a2bb90bbfdd9a1d3c765bc4298b79c79f94878f7cb036f4bfd91182f3fb0ddd0aade579a95345efbc26bd14e76639503fb880e1656aee527fdfbca8335ef6f0a0d8073ddd79f7e786675ba40b24ef041213f045a7425184292831c54025160626c0454c8bfffd208aecaf0f36347ccd59f0e71ba62ef7f5d79b6325e9c7f5679426e7ce2150b832f6ffeb4f2dcfef2e22fbf3c5ddbdd5eff5de5ad4cb7c44efed58e58aeac1db15afd624730cb94d49da9f9dac56d4003469fe3cb1ffe5e79b9662e8c3ebce603f28795d76beb106cd6bf3a046795bd991a2ddd33d205a8a2e725fc4217fb6f243c146e491ddb67d51056fdbc45b5cdf76afab8980bd022149a9e3a0a5bbc2fd413bd38a1b1233def1ffea6b19ae3e6df91e59dc908a2849e8b4a3f7f3ffd4d6305c73f1b668d594c8e40da7fbbb77463e6de3e1f667036cc06f39d1866ed6f1aab39e1f99583c69ae85923db18df6a41fc43cf0aee192bb3456b10e13a87d59f4f9a7772a6eaec366a703ea9e5856698a674eca02bcf0e621519dc6d5f780dd5bc323349d1b96d78fdb77ef59558e6f09afce657a74489fe2b5d1a9cfa390fe01a75a22142e68d720dd6e32537a81bd672e6fac4783791d15823f0f1b4ca646660b7ef286fa76670872ce9e88776646a7866e3b07efb7ade99ff3268672ea44ca0a445c3134fcbd1cdbf0af542b3ca06d06bfd04d4ca07f811c54cb49db473cafcd7e5f43756f7f47fbda1b2c8d095e5a94ed3359033fe7e136c62175119243af9341e44b8bce9b670738ea4a5d7f6857750ca30a42ee127fb3bffe7156703ed1ca020e9b4fde681aff7952f548de2a33ff63e06d517ea96b6c58a87313fe923e37d30e1ee0bf78ef0e26157f4d3adf6730e00dafbe7ba5adaf0dd0ba78d4b78147fe088ee77d1684782f2979e8d5078f7db937523ad3c2b541148ace1196501c1f168dada429c712cd8721385f436f1e68268b6c0f7872b7c7f7fb22eb58d6555fa5ffafef1649d879d97aa5dfe97be5f3c599cdbc163c6ed7feffb657bfe4ff6fc0ff1fdb3cb60fb07df1ffceafb31be1ff3f7abf6fe2bd9fbef7fe7fbf5937b760d0daf7f412e6289fc25a4a0130fc589fb33c9589e3d701b3894a6e54cb748b01a7334a3e07fc95d7ae651479bf644d5ec8962dcaeddfedb3d4b7498be7951c8a2c842dc0d9d95034aabe74c7f2e677faef13ffeb941d1da86cada85e3eb9f4f818ae504684fb175018e28cb629f62e2b04bd0069f0d365c7c93b45ca10a32defeeec444f793a225d58101e2dc82648041b86a77ce31a318d72739223ded4bb4be5b3216d237ddb1aad52c889d4602f1a15e086fe2a63bd34c40e06ef7b4203d4091440408e3d6641379334d62bed553dea45f09964f96d7cfea296192fce553e69171ea283953a3a8770977d415ee1bb8fd22292d6fea4b527a8abd9ed0973e1e3f2b2d9c93170ab4e848db159548a93654e4a7f2c6855fd5e48871cc955df82ddfd1db81c0533fb8ecbb9a1e112b3dcd947dd1231f03a16028fbd86b0399cc9066915d82a677cd54754df614b0cfdec2a903fd5bdfc98a229ba383c9c1b7d41ff5de5673c7dcea846ee0f92d5a9c684bee7457779b21c38e113a307985a9b731823abb6365a9543e2af4f56ef90d4c565b7f606127f8a58bba43265d4b6ffc29c4e7d283df1ff0943a27f06280666ce7e752386fb92a0323ea953c35610d2931d8b8e650dd932ca1de040c271a0ba79cd1d7d30cfd5c0af13047928ec7318c1699f2ee176191768e33ae56944294e586085f50837e7ba40f9eff80e94874a1bd32ce01590b0eb2746de9f7595d2fba7a0b6cec24d678f52ac4bbe63c3339b2ad57dd8baf4827f18a8cc0a9c580563c511ae47bc25ba95c3bd3d36a119b59f774272b764f339e98c34c4fcf5ea97ff82aeda9edfd4b4cbcb793673dad1759cf6c68a64f961f465728342ee8f63ef6ac93a4dd630e8ac5744e41a1c261c9f21518ab2a4a06403f080b9cd279c15949e764128c7280678e6625bd6b3a3b3ddf374691ca6520fea94722c9c1909d57f68fc9cb48f88fd784b39bd1a6f7f6076bb488398d80d840b1a2be8fd14c9498d318364a0c9b97a68063abbbbb221b46696baa0fc4991ff8e99eb6817ae3dc8b7957042f794fb493abcdb289b924c93e6e81dac666b76bdd683bb5b9072772f074bf4699c9ea825e041bdbbfb5be4a57a1a345cbfade346aad827efbaa65a18e104d49869b52621e395b29fd92022ddc02f6d62205f7fde5da37e4c5c515c12fb784b7518383dde521a15e509e1591937084ada4b61c106a0f9ad0a4ab43883468e72629c2126b302bfdd9f6fded108ea8b42ab9601ab25d276cd80f5a7ba3d107b3233ac6649f4962601b997527de17d78971dc15622dcf5b216570c1a13d04eb2e82e38110f59723c5e3ee6ef39b9eed1906c3b567c4bf305181500de78709cc06c00fc82fc52f58f71a7582dc56d41bb977f4a89f6f4c9ca20980eabb0ba26caf233a2fbc0f38130b7d3410fe8237b2a60c87ece55287a509441d4c48d48262b602adcc963528bb34df8b0b1bc5eb907afa80ade8fa333ede4710d71ed1962bb2c83ed0b655f0fc8c6a1bf7e7d0f8a60fc569cdcfb09319b2f5352382e0ddb3ef49329c2514b150a91fc1ee95c075470d3211ab0596b58cc3d76b1533dc319689634a9f5bb4add90ae39a3a9dd69258e89b0618ed8efd3c1061453699d1d70f906b5c222720eb8bcf06a5477cf3d12262da7b256ee2a93ad4ac979e31b2c3ed14ef774f78a4f619c970f79e77c558b6e703f83dd0c608be56e466decb2be1bf15b67c31be8ae8763271c854b21a48c3aaaa76a27889443e14bd87f54042bddbe5a390c44c4522df15ddfb553b116ebae45fac80bfe9cf48a91692bb4bdfe5ff6ba607a5a089d227d38583d996b375b7381d6d173c843a63c108bd41b756a435d948ae17144ed2b408779c3da9791732774a0b74e0e8f2bc724e7ea2ace88edaa9f56044ff02ddafead0e497d4ceff55977cd139392a6dce495b3b22e610cdad25798b8ce474431e56fd187fbb7afb742beedeb897d3434e9d1635b1050b34dc3dd0d35b38f47bd9c47f3e5b54a8b7718e1b37bf962418e9464edcc81ae08cd11ee94e1a987c469f593e127bbc7ac4b5dd72d2656221335c0313b6bbe176f4777dd16fb90d608761e035485e753057dbb162f832bd1d16c8657394f9a9341e9bded8e13825e277817e31045cf51cb0fbdd1df9a5be56e4de321f423bdadb1c593c816348778e1cf420548c34e931ee083908a917ea4bb5ec64863a20e5313c4f1d71001f11ee59fea8d0bda09eea647251d05373eb8c6a025e63e3e52df8500a3503d021c62982258f69c2fd6df15d21f21d92b0fd4cbacb4bb8298bbf69910337d60390a3458bb1bb8f6e02738bd1ea51cf99d8c35381f16de6e4afafee790a6e7f0deaf2bbce2d380e876596e2b5f91588e79aca9552f327d6d7570cba40da8b329c6127f81b9a122e01feeaf6a85552a48b10fd6894709b3571957b2d0c23253d488b1158c3e2e6a1a7a70652301bfd4ed3f798caf827fda92b31450d34e20dcb4422efe799a7637aea5eebb25ad29a4155d8d572b5febda0df0a8e6b01e71bea1c1fe9d6f1d3b9a831898bb4c0ea997c2b9199051e95ff60eef7cefdece4a4407ebb814ca313aaadec21b8b602c6702f6fd8270770e99d554bcf9b57e124eeb07f25bbea1efea44a84847b7403d109f2816ef961747561830daff0d5322b182abc4576c4f3bf2c07096bed3ad871f512ab6908344ac5b240485e119a0f9a00136f1654d2674a698186a241522a101e53416ac083194ed1a4d99ad46ea198388301e5904826127b725af93de6226af128084c5d7d8cb0ed92c7445fdc8f1cbccf93995b9ee07138ee671ec3a2a55a2ac6f31aa2e1c33a6bb3f1efa94596a792dc70de5d00b947e6236602b61472d769499508edddb87436328f929d11fcfdc9fd9f1fd1bc4f1bef8a87e309f554300d43634320976aac26bf1d5b205e5bb265a3568e6152cd2e181159d72f03aaaac457042851c8718221b6567b23a765c633ec7f3b29ec668b90538161edb9f370563e945d4e1aafcff4f48c083f587e25c288276d31da2aa2c615ea604f18fdabbaa9b7e0ddbb415f067aeedc86dc94bfc9335932e5ee70ab0153b73bc26eee5440a75ece2f077d8c031cfca0f991365d274c33e7850fe8f763ec0b15eca01632a7f6eca856d484956543a474d2c75093129ce0cc42f9639ccd0dfdeaddeb6e272772cc635029065764a8993925d9d5a7559ab0629c6770dacfbf8adecea94033da895da600264950173890dc93fa0f1f20efefba9745f3ea71120c3faf843a39c572aa92efaef8d4adf92f6bbca174dee0fe8eb62ca6eee802eac4725f4a8d6b5d1b061533a9375b20d4cd11db6120e97a4006907ea94c7ce52720298a28d21f5795be5ede35c7bff16099a9e23c9ccae0d7212cdc113a9c1c55a81eb9537c95ca1093d639624bdfa73457cfe434f4007fe25eab0c3553956fee1afd562759c783d70617a07134e9a16a60225e177c43ee9b7c176a92e596240dfdaac407b2094996d5d3a6c17e9936b77750788caf5cd99d585127b400eca54cc709ce26d10950cfd1945105093e5315e4101682c7261247bc32f5d2f3902b724e2f2d9515a91d02fa50424cd4989cfd7bf94f11d4d4847e7c8ef501efcf38f86df2446ee4319dfa4e5cd467b1579013e0b2764a0527dd9575a86f464d563ccf89b0e1e8458d8d638bd2a40dee2007ef24fc56cf17bdd83922527bfa44d023733943274828e82e144b05f3a7fc9174d40bbc5e3f6a312362a5408e113095506f2addeaad8aed1c85945fb94a6aa5ed162ab6af19c817157b19542d6e7058b5dcf03a229fc10cf66239aabaa9903aae5a426a60a1b49315293117711abb478a1114d66353c18bd5c4ee446c7722e96bd2e3a19c565da34617dd59d5f2dfeb70c6a7b4dfc9a7bc969c576db16f818a873fe8bef9d7a5fce23c2fdf3f424359da4359fd6228c98016726d0f68930ca86b26ecfb80d22f2ed43633acdddf0f8b578871277e185dfac59ddadb633cfc768cc9480ff2688ff4f4274b77be8c1b55cc8cb7f4cfc69b2ce9ee0f469d8ebda4ca55eb5855aad6b18210d69239502a930b7105ec84801f233d0f00cdc7aa18a41359cb4c2417374913373fb73254e5203d950dfb5452807774d6a1cdd4cdb4116f13071defa09af6f85af6f808d6ff16371d4d482e9304366fd44161e526cfe1a75e4be5ecbd52b08778de1e2c823b79d6ac01520a2a3794475b0d6a16111ad6ace1f69216154932aefddb63efe56fdbe377c3f035fba79f00e3fb74b1838196a96ec84eab46356b0ac7356b0a7d9158aec9a1ca55dc96c9024a5f9c41ade927bdf5c66a52b32964edc24e499ad095665bd73e4e4427a6f6bccd6a3f116f8f0351bfb57ba16b9e7021c7fcaa13e65499c134d4dceec922e949c265f99a0db80e0c53acaef789bb01bc38b1d0c8ae7d79a529e03f4dfee83a69260c7527d29639a16f605ebaf737fc204928724c8f9cde16331ee2fa60cdcb8e14d66e8bf11b46ee8f5b2a7185b30eb8febbe19955a9cf4333fbe11ad947bc96ab0f404a0037354300ff8fcf1f6da68bf36793008b08feddd499ed5771f5f91c49428da31b131358fa8f2690b4211fc926272bead92c06ff5bb33853adb4bb1dcec5fc3fb6257d212af0ecd85ffc92c19cfacfbf94e416d21bf2d09ed864f650b391bcd34584b6c961a2e527fa4c6acc493eea15e4dea6b0a784c25e68aee36469ebc536b9b35e4b1d6d6a57fa81da51c38193bd9fda22ed371cb086925beee8f36f7dab42da295207771c9beafebe2a9d8a8253ac59ac59a56647c550d93ac4d24e8eec54c80f54abb9b09c57ed31d6ecbb853d09cc1140c05dd762c0c6f25b894e2229e439af8de50eeeee4c721713097e6757088c033757080944c72a10b2f4680a74f58d54afb914483c024968d4b2b0e3e6cc3669265bd2cc4553c2cea47f5c63ce5cca473553d9e9825eed5acf8cd165f4f381f05baa894784eea716726ce0cd3cf10c8793d735c5770c24a9239915f12bd0e9cf32bc9c7a6c12dd786fdd9819523399bbe10fb842dc146ec83a33a043d61b26e964d5d788feff3a4e1fc512a22c928bdcc4f4a39b7745709253faf19c5722f8da2c2d6de096b276a92f98b3861c223e3a404ece27a1cf30876b592f24850834825a9aeb8af756568c8a810e1514c0227a24197b07404b40725f574d22230b424b09f50413d5320b87c59a10f699d8e0e3a44df41265933aa9759595a49c9b7d42fa36f5c44980c2023fafe3f9e3d4a4a3e5e73304fc2fb7f47a21e778df659f59ff4423e8aee9bd5b927542a8f2f707e818769c627e8e00c547188e8027810ef02edd317ad691679b169c51056298c2fd630b877dc0a98e6afb6c9dab7432d33a8bd4ac3056976bb0710223c3d2ea6a9496e1bc06fae5656a986f0c43208beec364946a2c373c323325d01fb796fcba882caa7f3408717914e77375d6271753465ecddd74ce877f3ce7867454646df2fbd9c0e75bba805bfba1c6e56f08648032558a07957f16eaba743681664f3de53bc2fd30f357e6848fa5e46de680f9c23f482dc825168d1a9fc81a2c8e510e083f9d38d3c0160e2d0df47e87a8b0708fbf303d761b0d9cfc26fd552ddc5211a9fe9f2146d0e960ebf6a64efbbf9898fb7de1dee67352386f9301fa12e36f7874f2af42ed957e2b1e8e44bbc30a39f8091822fcc951ff54d7315c56fce911642a5e996164b6d912706c5195bcab9fc65c6bceb5864d085d207d45788e50af4bdc23ce5641aa5f65958ad202af4235dc29f4f6fe925a0e6ef5e2f88d1294c5653873f75338a382be3c42418ee3335ef0f5516f00d78fa9532ee52052d54576431d32cb555f268e83c2bb0769a9ecb3fb291f0ac5b819fd9fb7977ff033da8bd12d2d2acc0f0d2ed3c8aa2526a68c3e2c0ee53f8c68e9d55d8b3bb13db2b162f57fea2b66492ecce1bbe85e1f7002a251831c04eec8637b8fd48f6f7aedbe483dd233015ad647087d0d99ff2b7402d54ed5d15c6fc3c5ad7e5f2adebcbc257cde0cdd03cfc2117f716adfb15d57b7d8a56879859864f79cc29a169bdce2895bdc738baedd22dcd397b0213ae684fd83ce418dc79daa38ff9d4ef1a0b564e09e535a6b553549a1ff113d276dfd478557798bddc4b12a3d6a5b6da4d9236794d82fd0690c818dc5485926b5a6f55fb80d86c275720d18b60865071e5f8409790d06f0d22e32db599500917969eb5865663f9cf94b8b42ac46e170f9605d9a7baad0faa1c27fff0b3f90b5e8fb1476fe3f3985bfad70fe85bf9ef31f2b9ced77f1efd42415bc74fba8bb7f37cdff0b9be6ace33fcc1418c684adfe8193b830ce6f9cc4b7717ac2af259cc46a06be75c97ce266a6f27dd1bbc96534c33142b7a69a89f0d8d97746cfc20debeaf8e20c369add68dfeb1ba4281b2f17cb10f67bfba4af19efad8032634eeacc39f790abf0aaad8b4c65eb7219727dbb220fa2f06b2e536f8b0a6efba07854d01f95f8fa3f67d3c1dbaaebcd317b697ea66311218245d02382cb4ac6203a40a23b2b0997bcee34a917087572573ce5d5a3ca778477a3529d6303fd5cb0d27f49a81ede8de582b2e3114de0c3d26bb043cd9135642ad502f64a50044565d243aa15e41d9aba6bcd411818d6be71ea5d93ca88bd36e9d27f2e60f78e19b8b40601ae7a9b589d4e8a03ef92bd492a991e04e7137701aca25f4533ddda0c32af73beafedbab5b4ac2e32be352d4526b9c6cb11a0d47b4992eb1a0f69585bd247aa85db3a66cfe52a3320af96b4ea09b725cffb1373ffab54cc1b65faef167e573e6dbda3055e1e42bda639b5e0253eb18c7852f977a1ae6eec614fdae40cbe9731f9b376a7edfc440a3576eeec5273530ab123dda529f59099fe41dd65179121c4ea489febb5d4cb779b2939494ac65c72543725c7756b70eace9ebac7bb3f9e8940bc572423ef8f244d417f25e1bff35a9a41c65d235f720f8ac06e411641975ed76d4ae5647ce44ff0ad65238f39c50891ed7988fca8b1908b0ef5f5289e8567d488241bf5f34af81fe591e5a61ec30d353a4ca465199dc27ff1b53185ffe2780f3a316dd1c1efcff0977e7b1c151be8260211161ce4e7e4cf20741a01960a7a72bd741fca589208854cd16a4c657ee9083593cae894498ba052a3935dd447c93ec77fbfa42461206714cae70ee51e16a291c4e97dadc9fca7d8ca96acd2e9a3fc47dd95e999e5fd1635fc7c9a22758d901172990b4ea4a98eb61cc4b74fa0a983499f752c7d21be58979a28f4c96c7fb7a1c81aca41dc1675327d748fafa6a8fbc0b57c039642e1a270653cbdc28c66b2c15c0b33f99cbcbbe1e3e0e9567b5feb92a57782db9e81bb58c18e7584b7a3570221f7aa9a65e8bfe523f1e0379111fb7555744d040ac50bac60ad5902cf647d74613820ad37abd6820503a66e39a41b4adc46199628f661dd736cb87eb992710e5537441ac3e5d1354a2077264b75662ad05f9ffbeb579f4d1d460af61644da6f75b7f42cb1b07e53ad435b3e236da1ba9b2fc92dafd3824bdf7d19ce82610186c9dbc32bbd66262187c00cc6efdd226abff990f745ff6dba712caf16422830b6b4ea84b71e4c0b4372e65605391ce3c82de164f8596b42155c9f205005f1320f7ad3ab9d432a0c6038c36f6de6676a0d627480f4729f8ff9a914aae47cd2b31312101c72c06c3a4e1cbdcd5f81bd94b430e216a89b9f7714fd3297ad16ec82578266862cdcb798c5e959c72731c533f689f67dded3f93e381b1fd77920d47d0188821d0a1727d0881cbc7a83c2406f914a9b60e3d7523f4ec8105c1f3a1b8ca201f3d994861fec72d85a23581acedeeaf1aa16a14d0828b557396ca865cecdfc4e6c610b655e0de9b47507d7f6af3c83eaab99e217ba076c33532f5baeab9768da8efcbc12e2f5c630399e78bf5f1455ea1f5c84af73a7052ce22e276247161c755240f7469b493c49812e13e7618273a4cfaac7346285a2d9009111a8c130f7738488dba04ebd3fe503e17c70ea8801d79fe5dc7c5ff8b004bd0c1a44018b8af6c7637c0401c695c49adbc9114ef8830927f0ee08570d0bc08b9e8331dbca2682085f4ff098ee2cdb84009e6909d15ceaa37abad01279b7fa579a19f647184f97a6ecc5e145e84305ee3ec5f4ba77c75b1666378b135d9453ebb7ebd3d16a0b247e464c487d07e3d182ed85c64fa71593732e33c93893b68bfb8843a5c75b8a4f1a4bec4c7d7ad93cabc692334c975ea1b9a2c57fc93e44fc98aee68b1e5995efa8edc01826ef288eebadc1fde46a5b32f478c9e331996f03f0d6084054e9cd1419a37620d44379aeef7ce52fc8faedddcf0738f51576a82e9799a89337d4d6b56ec93906ddaf71d12d3f2fd0be10018b7175c41db4241d82e75639035abea430618f00b5db13b9d8c28f81ebdace111304c50d21463ceb0bca2f48e0aedfc279b900da31baa2c34ecc634f0f07e97e8a2e3c479e37045afa4251b3a24baca87a9882d7a44b403d3470547b7ba2eaeaf1080fec6bba4f742b4f9caa5a33b915c992243624ced31814954d2139ca6f5d51d887991233655082d4ed94a345bbc610079cc02607f0e2cce87ae4211dc11728b7b55cf16713469e2c9042a093a393f1309f58dc8162de2084b73d12de28b819504829e2a001a3a257de5d29cb741dc30ddd8bfd7c8a7139c199a067eecbd276aa9e71f9f9ce8ed65de0a93fa7d0eba314779a8a4295cc53339315f9ab69215bdefdb7e1079a89b838e0b4d27f6138cbcc70563bfde1917a58ef48b238c832bb4d9521db8e11b27402875ee108a2f980761ff9c57f9c1083bf242afd21005e7e044bab1903e76941c545c718a8ca25d6ab140880e265396813f73c92f957ddb515ca87eb01e1c90842aff72a72c3cfb783368913e44350335f7a15aaa44cdea96a59b1ec749df7c5e749065a56792ab2074859f11ea6b8338cb57f28aba4ee560ad5ae0cf471156ffa7b7da17cbb80e61f9e6ae5ef030acf3b786508356bf5bbf9480c64ec7ed1514d5340a919fc767aaefd08e4a0153b495202b5904dc04bf528ee9dbcb2d558d2777a2986d4d46124c331a61d5b6d020f8e8d84dda357a82360670564c76381b7c7a90082572c0084b552f816ccd290655ce949231308f89d4a89e3e3949ee41c9a880ab47cee5d93a69311454bfc9daac1f2f484f7a52cf4421205c0cd203c27d0ccd975b0e77898f5b5e6a3ee909a48ffd244b4941d1c4dfe14e12ddef65ad38685daa1c69e79274fa89b03705e8ed7e9b95116b35cb2bba16e381abcc3f125bae148a827dca115ab75f574aa83428ca06f42373d027a0d0e2d3a3f1380b355e957f850a9abd4bd305b8f1842ef2348df67be467ce0a18db4e34b5c35510d1d08c7639c607c06a1b2caafe060255c5c858335478864eab026b2c3dc5e670430a6703e3497b22b9ca1b38257d45954dbf28552578009298ce47726f06087ab5e66025fc905ee51608375d7e493d37e380c390c072c35854487b70386e72ac576fce3411e61d40b4e13b821d0947b6f399ce2eee121791b0a5791b2411012bf7832e9ec3c211a9aba3f6b827c1f2ca1930b35654abf7492e6f9aa007b9d9e485f041fad17bd28efe39696bedb1f73cc27fbfbac8875246417f1aa77e0c3344791a1571462ce931d6c48067a5ddee8a57b1adfe9ed7f3b459abb1dde1548b4544fd39d9bdcd26fb55576f47bf4d15b901f9e0f9f2fff8a58bf9a3ee0c850ed818f6992e0d43b9521691fab7053002662f2b802b403f27673b7e3ec07d7988c1eefa2ae1ebdfedd86ee32df157ebb52ffb6449e684276514682fc6137bb27e0787d21ece057b460f4453a4f658eae39380188802f06f2611018054f9ff41c09bbc328555eed0ec6de021a9ed163f505778b71f6656bafe7cb1fcbfde13cddc08aa7b0c153a8beb5aa29fa9e91557e28a6db0f85df70d7d8fb9d98dd51d877a7d7bad254afc23c3071949f33fab4fb3567f06c56a6b478a28878afcbbc8502a1ee465770db732940ad0b0715f578e060354fa8fbca541991dabd9f2f145de04b89c4b3c9af487831386b681e7a2b7920103a118d8e948cec730ba9a0a76f0dba4b262635b76a38d5bb7c3627c4411f83dec3dbaf9be0f55442552e3641a2430d693086fb1455b10b0c8e374e1352861ab33326c592ffc5d047eff7595d624d1aa72aa52769c00bef0bf5a8372ccdd2a750f700d27e6eb19a75e320e7ef720f9547217d4e9a6be8fa60be9920899b4ca449f5c2127c203a0f96c2b0063dfefa0a9c0e141b3dd664c404bce38f47f62de05c55414c56c336e8f8505fdb7d8a6abe17d7e8d455920b49c512adf74e6352b53c57ea50c0ce9fb4ac56910368ec7b3c13842fed0e499da26f3246db3620d99ef03e62f4287b5ba05bfd0af6cbc5db428de13ed71c52fd7e6b4874c99bd7dd848dd267e15938a2786517098af43788257db4bf8002251810adf2283260c3ef740f3a427d84609486edfc510aff4ed9bec6433f9f826f54b01f3bf3228b69344fbd9a35c1cf86ef201c89939386dde9b946df43e151ea9927dd9e2fd4d57029ad1512fd618bed2b8087d42db564191f4fe6d717fe422a8372d327777042f9bdb1991cca38f36578ad6690ef09ffb615985fba43cc8b1e1de6e10b3c9ce6101a3dddf6c2a9429b642ae9b6dfb89df54d7e2a45e75680b8f485ba6a511bee6d6ea84f6e3b449b41db8c90175f736d37b1d40b10def00244378101852734801ba4a1233b6c7f836330c1462563a05343ced9b37deec6b2354c769fc7b019664361e9dd951cd581fb82ad0f9011da4bbe503773d2e8aa58e27b7d7adbd3eca7bf92b044f66b756c30d05c83d2fd44c7ca1c187da0fa42bc1e59bc3707683e48946caad646eb3714487ea8b9962bf480ef00e04c54d4896f1c8634e710fade6ec1a45b09a1468887d314c383f281f6e3d1bd58f5ca10765dd54b6bb8158789c20d856633fcca0f1d68dbadb8d6770b98fe64ef12b5412e52b3d75be0ed3ccdbacd24e5a36d1f59f099c301d348519d620750b52358bade2d28ce14fb932fe981b372124140cc65cc54684a936944c801abb066cc40cf891f620c2f448ddce415077bf8259c8567d6b006fa774f973e819fe91cf1b7b7d9284656224526307b67441aae4c99c5f5d959f756d2bc2b6c941108fc9ddc829a3e0f298f171bb167cf08e49fc0fd38d6ebe4ddf12f3d8cbef03fd86a054c690a7481dab6ecc3d0bd19b533c262a16d5efbc23bc8382b250ec0074ee469d436f763d850e5519bd5fafa382f52fb5a203a634922b9d84b18e948fc16647d10f977fdcfabfe674abff1ee53741d956e282dc34dd2e2fc8fe70c2dd348da6d72e9a651b732e4f0c150c2a9935e7c4f33309187351eae2923a97a42556f1aeace5dcd806e350fc9bebcc0af2958d419c4b76588fb604cd9de4fb23e76d230897bd81ccc540f2098d0c73c9206d3241d9adee9057282029556419d665a3dc6fa43eda042e4c10dc1c8a8a7257dbf0b313b5c92ccfa0523e075502a10dc6167346e13ba278cbf909ec3d5908f1419ab5c32f18da1c7087c984b0c68a5de1884fad5df58db5cef7bd714e910b14b5f6a2207ed8e6b70818577da4ae4bdc1b7e65bb87484f8da2dffd05fbbc97cad6cbe668ae8af55ac975dea200875f2b5ca566f40ffe0ace996b4f3a08cc76d9b1d0c574c74cb39508c71c14996aa23bc8daa579db37c258d51b689ea3531aebb71dbaeb953fb9a934660d94af1d3591f96a006fac487a5d428dd4f12f394b8027684e8692a10ee64f8bd64e5ac6488925df641ea9b2443352eb71fb7c9bc75e0dfc531f9078443e59d5769fc50a58c2a9eae9268805afc32376e836cf922fc3851423d4ce5f5c6a4aa27880c755fc6bd3897314fef96c5b71d15f0633598b48d3cd1670c18e517486bee04e302892bc1160489f3f16cc61c18e8a7616f448b06b1defa579df1447fccf3cca1da06f97771dd89e9b1dfd36bd9d53cd7b4ee586e5cb3ba9304f82a7ff498e9c17ed4d644907bb0fb2ff480d891791dd2c7a24e27fbb15a7512d6eb85a08b57635b14b8ba5adf5e24273bba51da14c2e0062010e2b5326a1bbbb82ac81c9ad2720309f6d484c11afffacede33b46cf0f233775f51cd09ec1ead09b876fbb72feebeb4fc13ede57402b54c8d8a7943678fce042b6c9fde722c93df5df1f8045ad73b4abd41f44e9ca9d05c4ae4a180d5aab1105664d12c87836e3ec76b1a2bc3989b23b41b99ad9c65d0890b2e2a585e4c6bdb090ec7189c627753844a04f1fefbba73cebb97a2a33c5453f6c415c5a826979c4ad6682d8bc0a1eb35c968ef1de9767aab803788e68c52b7282037acfd9b13da043bc56be58d910bb3371e22bfa8fd3c12ee6d72104b37c9737d0e4725369fc5301377d8cab18eb18366b46377774e9d2c58fbbbdb25edfdc39d03d7fefddd4de926ef89dddd9366c9bb423d2c32ac97e8568a88db392ca1299910e8a75f90c3a2cc6809163183d5f73945e6416de3240c567db05046de150b4b0d948b1325b7509bd77c28fc8f2692197f63b1d23d33023344fc657f1c1bc75499e8a6bca144446803a974fddc5582895f73d6d8314017d2dc9a27dcb1ac5c1e118b72484b7fdcff664c89b69d8d3c2bef6738e11b229b0aa30da70c7dbb184bcb4650d56c5487ba762b38d1446f089df062f17db1fac6eeb57b67c3973e788ced14d58b0af6e8060e1d3dd05b6738c5cd373de026dfcc7527fc83ace93357bebd673c39b3f93a7ab37a224836eb24d25741749d66736b5768ffa9dbdc33a80433b0b3ad4a18033faf847390703a736f121e80f9a1f254e5bba2fd001ec05dca3229eada2b592183877733a2bb4f397a75daad30ff0dd9ccc61324d645dc23a93f4c74f702769c758ba537629f3adf70162311ce547368e10b1371bac7b5aa6ecb137de69c1063766fab13ba730439cab55f6ab8536ee70330ef458209f59e4ae0123a83cf7caab5726339dd590c3585ed860b0bc992b3381446366fa15e206cf60be91d612e908364ed5ab424157777116bd15f0d6502376a302dcf6e89586ed95f731743fd5384e1a94fddf216b265137f756f5f067a2ab7f0c7ed93aadb2f49f648a4bcb2693ea0ffee58486571eddbf7d4a5ae2dc9e0ebdd1d30c2df0f7d1feb0dd0fbb0f095870d83b0ec0bcf1f933db02d0674937ebfea672c52667bf249847b2cbbb83803de4d4a8d63eae852b606a9678da63cf8ce5d87e4bac81bc5ed7c530ad194bb589ac07977e19420b27784f19a536389aa8fa8daf326713b5f263035c6413c192914cc458f4dae81f0282183f8420322c4311ed11dfc850c90fa59a4c924ff9c4fcd2958c0c5225c4ef5c8bc835c4df59486f79329ba9e036b50e16b3a3745a49c93f745e4b7e2cb96b53d4df3dd472bca5cceec18db618992a44cf5048de77b018cc289f033d5581e6136ebc633b643cec0d4407a8d37b8e797432723a9edd7904e36682d47ca37319515e6517205376dc56d52f747724c1bd61b8564195fc8d682af314ff80fa3a1055c972bc07a4ba2f1dd98e0fdba1966e38560fa18c680a5663596cb86c3153d8328ccb3976510071426f759887fa1ff5d39900ac33218c3cf98164dad640e4dc281b14323dda1cc9fdec222289027cec9ad03ffb4f1045315120875a091dfc3ef30a2cfde19fb8a27d4cb100bd3196c487b7b5ba2d4531ee7c2a6cb29bcdfae5ddadc556cae5a86073431d7fb7596b5dbf3a18f714ff445b22d22cd7ff06ec14ace23922c86084420b7df3e19e2206bb826386e24fd53137b17e6efb3ad3c965ff5ea5f6cdaedd79fecca41c899ff6b1776e5e17c574ec2fc9c766521dd95deaf76e50059482b0d286a8a25f527bb3412fe47196984901d0d1c03a1e98707490939e0e191046fbb5f0ba83f0b0df811cec7bc0f697fc7d37fb6bfdd15126038a2f1f46d9bfb42ddb1e6f36c2f9626d88d47947e3ee1f7cb1ed8ff9d03e9bcd46d137ee8b6c767474baed4e7c5b91ba7279c97c3453cdb7d932c3bc12f875251d9a1d8a67ce5fdd940e0ea5b21e14f55e43f189f273ae4cf7bcd8235052fdc63f1f8ac88893c6120d1008084d1e18920cf2448d66893419eda40435c92cdaf0cf708c010d13902d0b373c23eed6c67d2305e7da166ce6e9679ee0dc96b8f75400734ce48437065ef9558e1f493420a98a3d5584b09aaa2e23aa3abb0a36f93980a359468eea77b8513100dd8b11ac3504339204f9381ac60c797aff2efc26dc993358c4f637e3dc847d6ee3646a026f51161f45000c6b310af2d7ede1c51c0d44cc299aa84af87c5b1ab6fe385340fb8be98c85933d93242991dd3a55095b5dc4db93753c94f68abbc9fac66b6741fee7036fb7009562dbf74657548bc2f2e7da6c71be0c09fd94f253fb9ca7c4637a2afddcfc3d957aef82b7a7cfa2bc3d685aff4b9cd137fe5987ca5614dcf44ea5eced2f67d110eafe64d87206829fec318265b33b637b0eac1e82b66c4e4b92749b802eacabcafc6c6616f43c11ad141e666f25c1fe1faade965ee07673c5c4274791f52d2ca76ac784ffdd00f754ac212f4794332c12ab8f09bbc42dea26b31344107e71b740bafdbcd146c62ca7a56a61c21e4096fe31472ce9f12383d004de06ad35f12b829091a8ea835be7b2b2995834b5478a0bb58c5723fb41f8888aff5d703f1f25e45ee19443b3952334abf1396e460eed8ba56f2ed927fa9ba0bf4211c61e57a88ee4c58eb173d930bd9e4b77c7fd163f7cb3ca54bf5edaca651794d919f042e4f3d46ed165ccf13f72f3b5a9eeecd710a651a581ac5257c11ed54062011fe6d5b2f6f70e939d3d36c66ddad1010a733f2e7ece295aa4964235e4fdacc0373a6b41af97d46b19acfda19b30a476c76c6b336e7628af45e870380e9f0c9ecafcc9cb242b33b40b722b250d61c2bd76b6ddabea82c3c923376b892cdba4ad5b48d1f4a8f48cd1caee4b6e958886ff62c3564e987ca66919a00f1e1f2b132e5cd1079d24b83741ac8c81816d472d64e13d917ceead15a0c93c9eb0b7f46663fb2060ee1ca74e6b1c469688a04b5739400233c4912e105f44e8f8d828d93f6fa45432e53929ace2e07e1f0785029e3e5e700875680cf5b2e84d90382fb10f1b1835b2d797fc1428c68517f74abef22f65c7a77ec57537a355415f840fa7b8395b344f416329c4ead6cedaef05f4ca4e679ccf365081f539bbe255e012087e001507944f2ba31ba34a762ef5718f7853ecfb9cf8ddc9f7c35694e7fcf58e55ce3e0fceac16dd1176ea15df96583730e87421bc341db5a3ccefb537dc1fa14b260c6e451f00d9ba564057147a2296fe0e84cb25abfc5eb9fe32e6d6e2d656c09ce7265d2aecde4807d54085be9690c59ebaa00f0c2518114a1755ab031d8068f329aa9995c314ed7a4c0a95d7bc2fde2b05553f3f93755bac27b01669c5fbccdbf8a8d7ad02f727256f83604ba3ea61c704b647e467d77449d2f7c7b177fd225fde29710b47555c4b0f132294aa740ef24f28c54974ecf9bb0ebc1f89d7e48d74edbd27b85cf57f136ff2e54499592a2c82440506b8da4cc400aff9607fbe38910d6a9129e39653386f4caeed5d7c5b79189a0115a3d7c863c59fb7e57d4399c93fa2e3e7773ba3262c549b20894a12b821bca37b29efd279d3ee23c7870ae9cd97d7eb629941e812f54ec96fe697707f2ba386d6b5e722d17bfda55de18d958aef6a74b1bc1fb381dfe87474c9b44959c53ee3f5f7fecd75e666f3e03e7e990bb4c4b305fb3f6cdbef1836fe7d14f7e3c943829ae12ea3a67dc8637b43e1c522ba2639de0df36aae9e3168f847a7b4efd69cbd2a4081eb4397083505edfe1b39671cb5da97593dd7243e1deadfdf4a6e7e80eaa7f8f159db13f1e4570b81f5a96f3910230d830f1e588b50918f22e55f45ab8ca3c3b2c8e0b169bec024d490ebb0c2cd0c5087c11d45c2b90146cb89d85ece572c73c74cc8575a57397f71139287c464d9b1129eecd03126e26f2c39415ca7496b75667014daab724105bb57301c54807672dc93ede923302baed8fdef174aca7d01bab3a7dee15aaa83bb87f833780d70e71064fc0b6774cf8bfc724cd7d23432967c78658f7b18480414a22f7d12eb04181b555c047da7f04ef8d80a7d1dd00d98dcb41993e662de740ae08ebee794ef82f5e1b6950deec67faa8b96344d942dc19d198dc52a2f4f4ee555678103e0c89672ba51e731413f00aa99166c8cc16483b71d7aa882e4381ea91c9f1dd9cfb5770836ae5a40655669dbc26ffe5253d07d621c41bf14a118f43d5a86549ca097fcf917626a6922ffc5829cb0d87e28b2e0e139ad05235e541f4ba4d5f933d60f6c39d198ef06d8e853cbba6eea573c37ef40480993d82a6441b2502e1d5ae8657d948041ad0d5c595991053f8be312bf32cc46774a1c3cf6c092e38403d9e4a0075a067ef9eb58f685c69a7f4264a43212e2f5970b6646b9afd4f5ab29962dc93f3250bce966c692af9c25fa9386b7d7bf561fa7a137cc3859539ecfca30974741b5292ab58f205f76daa10483b51e0fdc077928055a61926b88885b303fc21917973eb6447ab6e9f2e0c47dd6e19e4389d3a359470b4316bcec9908ff6ae7887b04f61670e5ca289d17a83286a11a52f18f32c9af4d683928c9b871670cec15d7bb6688cf53c752983e98dd8f0fd071026370161da0fe0c38fa4afde8e9c31d54c1e9a7c1d0f6824ef08aef136c4328fe5f0c67021b47b5562fc2dd937f1658ed374e53fe3fc5836fa054f51f95fe62954ab6e69ccff8c5d0304987bd3646a7671dea2f365f584b770fe5f9dc68435e3b911f3692250bd0a758bf0fdcbf29eb79286615d120aafdf5e46207b63dab1bdf83aff29dc869c93bb3b48e619ebe61e141eff9215dc339d5242dd9c6e4d48ab7a585f1b85b70f8ea1789df27e2f5079d39bb7d12ddfc211f80e2bb287ad0b2e74107c277452f8a111d802b99a236b743e14c10328f09ca49fcf184a039b99dca4cc6424dcbb793b4368bb7e016682a80e6b636ff09077c5c358ae102e99f89541280962308f147ca7ee671550e7fa06a2f5f1d626ce4339851db08f7defcd293df707e231770fd8480fd00123da66239750227f83ac9923f76e59629b7e56af88fba4055133e799836c69f21a64f97946e8b8577ec8879462d2a3fcb7e4fcb4a45be4054efb5e92598f0b734825703538f7637abc3b3978cd512b7a67ac09a0ce23d9a92d7822fbb8807a8390d484349a4ea1a0af0477a54c13fa812744d484f752b80d88af40ac6a97bdb2b641b2e9560e60e7e135150fb111a6ac4a5ef4a1846553a3798d030a27be85b3446cd933a5b4532ff950f8eee98ec4c1222c662dd6ebb1c637cafba22e49b5769262c141c1b852bce44a29c3d4db43d0855737d62e02533acac7fca7f00e4e6d80dad521017cdfd586e96f4d1b1a1c468484895dd47dc83f0bafe234b86e7de8b05e9c195dd8ffbc9c319374500d28408b768beb19550cac7e039ca9a98c50fa8eaec09653e0d246ad73cc7e0449ee5f61be3a4ab253a9926bd43ddf2f4ee2d58197f4927f15decca99c5212fe2abceb2af500564e78278c09a8f26e4b7f3e4a3c4706af12abd4638c386fc40ad55a1dd17e6ad4e01344f02bf19fee5f755075bce0ae64f7a62ac93101bbe7887f5ac825edd1bd8409fdfb3ed7828cf9921632dd868b921d3daa078a1598cba47b9a276bd2f11023852f90f7d7c2d9fdcdf8bd58998c94a0810b04d99da139f2d18a72d78446a802cc584c1eadfe973e239442330335ecdd64f507ea7a6d61bdbf0bbf7dbcc3b5b30a33d7cefe117ba8717be1e299c81272e5e3ce8a00b4f7f5a388af48c48faa08e53622fe3b0295c00c5a123eb94f572e89f313cd02c672e7146e7f7fefd526966b6c15cedba4f8ce758c3fa07a29b5f9d2dab671096e20e6acdb08af75cd95e8be99d05957a8a7934aafca61720b86e293b5f96536062c826f97db2ebddc3ac2bd3bfaa95a029824755b2fb1727e379dd13fd598e418bd139f30320f950c1b579724c00938708457f2d210f243c39b46a4f08182fa034b42405e8f61be2bbec8da8fe4b5bc4d7e3fb0b37d52873fb8dd5d3d2623e37cdb287df1b971867fa83ff848774abcff5391ca17fe7db3e69e05d0548659ebc199bc3dbcb1be2bc2a1974c624b15bd3f95aaff517ff5d35113fd3d381766ada41977bf24c7c0a9a53d3927831be2ed4e17d7ecd170543fcabb1358585f53772c1adf8a087c1f7905bc98e4c50fca4adb4d714123a15e62830b9d1de21d2c586743bc630cb16fdcd811100d9fcfc9c5e6b6e41cce54657d9e83fe6945e6d88f2d1dff847163b21cd31dfeb986cc71a41b26760f23e717d7688b92a22d94b940cd154d875c8c2454dee68a6ee1d2653e910958d88c499e282437f67751186c010159aa8d422660ee758143ba39830aafc53380fe2f245089447072aa1d746f7749ec7865e29f23e2dfaf381954a88eee496b0e9ca2e61c12d178aad9ba2e42dabaf5054def6bcdb10ca0e0e9fd19b43b8073f357f8b3d67f0692925a7ef8d7e6b3be501f39664a1deb3ba0f3b16c02f73660a6da68ef90b142bda0f100010cdfde62af2f266d2b6cb958c8e88792d3b59bd049d8c901f2ea04052887ced52997ea7584bb93ebb96b0f239e723039012ee57818b38b7d699d29bc92be8cb82fc3e9c5befc586f89be04adccbde0ef9b98970d660d789e99b79ef06e892495e85e0ef7f7447276f09cc5af9bdd3d912eb279a9bb26a20c0a2194cc94d0eb93c82648ca10995f47fd0cea9e2f44176f8211fe388c664800617834d07fb6b2a518298ef633a3456384610ab9e5faa53576ea4570d7f60300563bccacb0c9f4890ecf06e6ddaa24402013a5cbde394032f6b66efe5da8c731563284ce3dd2bda4a3e03b5cee345414ee71840f112d4a2044b49da48b4652ea1cab18016a3b44ab7493f4843b961bf76275dc5a6a277397aa13e7d4115e430ed14f5ff7cee7e37433a4aebe10e0e4487a930599eda6f2a0e7f6b94519e27d805ef52a0d1bfe76f37f03fe96e17d072b8e74e8e84e762a96ae0c767768958a6be336438e27f44b1594d93fdb3a13102d3a88de6ce95c6c65807499dcca907ea9b16376df88551833f20bef0378f77b2be5b9dd970aebee1cdabbc25be2420c36c84358685dee4a13320837d22254bea28ce1a8395f232c8eae67dfd08e27cbe393f9ce773ddcdb1d88c53d88063f9cb5f070dea2e5ef81d58f8ec8304702d4487ea437835b831c44ce6baa0d20a75d93f93edec19b2eac1acbece385e6a8d5494d09e6ae3b6be1f51c9d8c56e467151596d9c7b36ebe234e572d05fcaddfe8d5ae52289d99b1878c3c88114382177f1dd0cfb757e326abbec678910fc5fa8a593cf2691273d960741b4b58a8a4c2c2f3774d98f0d9e5f3ef4d0d457de6378a749d5bd9722d1b2df658f7cbbaa237723c65c0c465dbcc2f2536e89a4508846ac91d6736ac73a959974ef2b46b265dd32e55831db17b9ca80c5536dfa0ad059f3cbd0b3696416eb46aa73f1a7c93595b2110eab165d218a66bed0bf578e0bb95f03cd5d51e9f3911b1b89e1c2df0d0d6587d6f574415c62e5d1036953a307398fd8e0879745181b85db593d3b7f4bba2538e1dab15e133d255b421658d6ac8c687e91831c25c1cad093f87bfd170a2afbca59cc935e8f03ba104a98d64403c876f382d2c141834af89bf61ab4a7872b16447a2df99560680d8867c1a9a69af7310c6a1c5ea75fc0dc74756721cf93d2939dc92dad7d3027aa62670350b63e4da0bec0afa3d5f82e189727efb0d552c8382ff697e0eecbb7fd861554abe57e5efd52e9ba2c8d4a466f2d4cc7ebe36e5e9e6fdd41cf378181886c1ff68fc24b4f27ce8f166bebf9aa14142685b5afa9b67e1dd1c6a9c00a42fd41d2831fbc05e341ec39be12267405689a911682f282448bc85f7cd626eb72da2b96f8a522c784bd9fe1f6923ad5f6b35f407b6379654f1d5b36e1d482cbae442dab711d1c4a5439981a5154e4819480d10adfbab6ee723dde99c55b76d55fd61c8f4d991a6c35eacb9c8332fe7612d95ac9c2be6f8cf86dcd343bef7d3216b89c60822dfa55d5bdf6118efac08429a047727770f192dda799349612250712f7f2e477b9a002b2114e28f443e951129bb7f2cb38a8f1f5d16dc4b8b8ae68cac56b6b53cfbc2af86a75ad26c582322552fd5be34de487833b56c39ffa32a9650043775ca1941492fd45393d12b89a2dcd6a6ec3f3f271f9bbb11e0330af4eb7e00979d3b78219ea866b7494ae7907cdfbe5a7856828286e212d5501601ead4cd19e83be2400a283bf08954115a73925e5cdfec1512ed7b872b4dbc7672de871ab886c7a4062e3a6396f49fe0eb3c46304734e1bfb5222d68419ffad03f31fd02bf797b3b8233f47303e0729d66910c280b5982e7d39efe841e3966e31604844fc0e0220c323fe47084393893deec9a6003269a8faf48526b8b267b4e455b0ad55fc005b501bb5158e5bf854d064ff0eb0439291c70f0fffe5dcb3f9c1d60bcbd100ad7e400cbcd2f423d1bea0839e7c512d711c4f5626dd6258228a2e1166ea0836dfa9bc99ab7420e30f1bd238010088fef80b7fa557f764e0ee38e36344761f19d631967d07a372477f89402f2fbf5ab5ff67ecebdafed217b978a12de53c52223a0d29c7b508a6ea8f4fb7539266665291f70f3bd231bf73b2f7b5720daf9fd3a1f89277f7677b6de144bb7e1799a62b3acd96d6d5d72081b67254bd8779d1a47916d4b74e883a11cee5075bde5703c0f1a96c34b9e33c9786d980b06b01d8cb9027c98d5c7e1c58ad91cc1ee3a255d65e7c4ddca7ba2e01ee4007c9811210c2d39c9c1754a588abe51b47a7785c040dda93bdf14118a7ecf264ec2f8dfae3e006248a2d4dac2f34c2cee81f067b2129c35b2328dbc8be0a1dafa41c2597ca412ce882192c98bf4d6a0ced099e4c0bf4834db31a84ac8bc3c919dadac8cdb468a7163675a30f9eed72a254b41492e821f01d106e7fffdd4ff2c2d40b581b4e0d2129c314e96bed4d294735ba303cb3e01dec360d646ff161cf3d13c43133fb2885d28bb5ae4da386b001f443b70fb4b485f0d065cddb3a6e50853e218f88a0d99c3ed1f4c6f30e7ae709fe8c9333ae42d6f79b5762b8a431eaa231153d127f910f9e37a7798e69122b7b0a3e6cadb1fdf4a0d25b8ad812243e45e0a356edf7c2b766f5670ad84d8aa7c530ad568bfa5e576b8ede7a66b9b1542a17325e7db0766de467efb8259e4fc54093157f9aa14dea11d6f658a2582cb0a57afeb73a07b02f09a2378fee0b0a6a0af301b0d14904decb67bab37f8ed76ab37d875b8db129654b8df1248e6231fd92cb5a47645d85aff4c266f178a309a6e0cca1112c184e30ded1890406f4b11bdfe5075d3c8d71c20da3623be226a693a9ac489ddf8a4e446e7bbc986b2384340c24eee4d20c37bc588d125e6e9073de1ee9c35bedc9b2a601f41ed33204fae77f8c4f89ab6961468666f8e82f18582210a8e5070e1c3950bce720619a121cd1763ca56d45d90b24bcd92e7bb102a3c45e05ec6c6da809b49a7be2682ac4e26b2969f37d70e5211d63d9add0a0c4e9df2c9d174602759795262bc82e286cb97e16e3ede198899504bc28208601d730a78c42400f9b864ebc880e486933408b8262c7ed9cac04c1184472854acb2438c262166281f6a31e0f48813f44c21bb5b091fa3ccd620787902587067ce80bf7a2228bba75c6430252990f05795d589cdbdace0394f0130585add54b16c125fd75d3d5b475cbd9ce0ca1015e10a176929467d34801bf15ac5dfc8d54f1712b1a29d122634f7447ba800723620027c801f4bef80af1c9f35a9107b797ab6b68fd130ae090678e354cb9883120a954da5caa54a59ced31dbbb00384e531b9a5bd728e8a0a8bda94d6272ab3c34685475bc7683b8d958b1c5648525a227581bf84f2efb50e309e6fb5e8ce8e201a7b7a721b4e81b5d37040f3073088be8e182a806cbc5d20e15f6c4e159c1637d11a205bcc1169d09236567b228594734855541114236c8051e9ec27a42b7d5d413ff4bcdeb7936aa1e80e9de3be9da2200dc7691289d02fac19729e6eba9babc23d11e1e1c105111e5368b57a2a02e67a4706a070ffa9efa3f6cb6147284d7b053c29d5504db06d27942b5581183badd03d77904300863589e7ea36760c3834408f29e499ddd8f6df828a40b2d5d71a0923f74445bbc3bdee424881192f933dd92c481f20860a3b78b723b4a94e15e43728d4c809aaa0f90f5da9bea7f77bd540edafe9242dd8d1058bec58765aa752a2291009f7c35cf805206af6d623950fc4134dae270692f119a67b7d9b44f72a0d49858e618766d73b84e8d6a8c3bd92d4c3496e1a5c26ef71cda444224b13675c2a594df4e19a4b6a9b4d95b6c6442e20ff3dec2935eb23d74be66644c1df1f9a55a19072ca15299eaac44dab9b2220c7223dd9c63c33946b8a2309aff7133b8900c137edecabbd7d4502cba55d757db6ecc3ef72d7cdd5a94489565ecfe3837f81c978708c44b5597230318b7bf5cf945316e186b6d9ed98aeff70ab18e27468a99db71ca642d4e57e718bac88b4cdc3e6a7be83de2a73f0ca754825b94f7db13f9534557aebac36ba03af517907f4ccafca27d3345f741e469f44f18e8cda447bfa7d5375325492220c0a8009f18e3819114883211d23febbdb333ed441ff7d59a81db82a60ecaa0463b74279db7845dcb06a56648a9486850f8ce44353ff956ce172ed175f41ea32481e6a23590ecb92871b260f81451ec61c0fb566a17bfa456e9431d0f2ba4b6833de8719ec2cb57196d0fc7c164ab899c195aa1d8383fc486f4eb4cf1f0202faeb263c253878b592d30a2dee5eee08245d0c2532fa854752e808361bb2462adc32eca416d919c03e34d64ce1dff2035f88f0d694f7359fbdbbd15f39ca8fcbdf30cd1fe14f189e60aef8a3cf6d5125799d7efc7b475a57ec069f25c0de02b04b391083bd64426828e3d450c647cad481343d22385dff44a1e11fd0794808b42fdcbbe312b82d6b7286baf20a448ea399e40d1d0e676d4e29e00b77264733a23539b93ae8cde014e4fa007494f8ebd2dec9610f86c329b8bbd242267b28106aa3a66507d39d83bb7501a736cc610f3dc7d0f162ba27b0aa3e8fe3763ae3a3387da86b9adfa8e9ae323b00668d7972b189087115d9651d304896eee2d06ddd41ef7797f7c554bee523f126f884477530be29012bdd2133f586ac3f8ed83261587c7e2b473a0a8291500782638f841bed90e3692c8f3b92729a723cb315aa2bf2b5e9ec7788f3750eac0fd9d35ff7567fc6f14aa84ca928c2257e0ce46a978e3b58d20f555235e63427f4d7bd8baddf9ef01f88de826898f4a9eb89b47e692a97fe02483e4825d3bd08f02f9a03b2c86a234b56cf34980de41b6956e8ed88548a27d9aad88acbf87e434d4dd5e2b21a9400f602bf4e2cd88d98c3ed1db8f5e416fde5a454dba8373f8a308e82f924f6d9df72bb3b0636a21924141455a3125115b6105390d591e05febacecfb5edb594e2114147860ac331b494a91f941e97b1fe20389445760b8abe456acef4a7a874887816cb2feb110f301825f6558a08c999dc29467a8e89241c8496afbc2e59627688b19fb1a7dc7db484e29d199926f4a87a306a619d727a818c30d217ff2b047a494f76aa4ecbadd6919f02a343021d8cd937b5ca9b86130d7804ff316128c33b4d10b396305a0ad437c17eaab749b200216efaea7848254949be9c50d715065e8747ed29cbb1b35a20d7913ec88870dfad51db40fc4eadd9c185d3f282afbde8ab4f8b764be0f477d0ce78e5107338344e9b0577e5ed9cf4840728d6273eb27f3aabe0680e61cc9126bec0765632e19238f5849e558f0e0d6d66cc2043d59591ed78505d48d13c6843c98d3e96a6e61bbc7095717deedc16132b775d81b5ae00b9f202e6d1708e52f6efe8ab9a9eae757ac61f2ce344c6a25012ffd3dc7c00112474691a4de129454ff9e6017ea9c7e10d7cf1066f30a5f4a7c670ee08919eeeff37de12e540dfe4667ecabf00030471bb70a4b497d99e1984eacf9362a0ab23b2e541511345082fb755a926e43d90fc9a7448dd516c9638c8e8b305923e13f019c8747d1021072231d4528c299da3695c183ec275e6fa533f05012e1bbc7b3741bc46994c7679ad8758a9e1ab72fe862d5c2cb619f3c4384bca0439d82bc3f8f51e04c93d9a17432b7a2f285b35872a1bb79c3ae8791a857816c163330ae2ef529d4c1350f8e45975c7baf33b51650919e8a69a177a136ae79302a015f6d295f32f56a8ab5b2e3525a702e858adbe649b96480e43632533736117715aba4dee535d73c2996d0d915d73c726f619f2f59a5de855b704a10b36e72f0cd9aca4d379f980355431e11c1bfc3d36cf69a58d54f3f18152ed93c7a7f6af3e80a755b1d26b679f51833dcf5ab706fca5bf9939923532fb2eabd0bff76d494a99de33495a91565b8700dfab80b62afefacfb7dce4953dd96f84857663684d312e2e6e70a7f1390c3214a07cb3aedacf7ca88130293166f02def599b9971f6b1979a8ccd8c2e34f3da80abbc8b16c84f48253b857d4e740cc274eb38158c4a0693f043a5a011a293fdf1561a98d9b72c830f9c3e09b39c75f7d37e790e93928c9d9cfe61cfa672bd3a438d3f4dd73922fe75984ce66f483bde04c9beedec033da89382e13da741fb4dc8b659381c819e2bd0c6712b083c0808862e4dddd2846aef5725086af26e97ba37c8d4434b6f5fe97caa46a993f52fc739ecf0d734feb38c5b5fcffb1f767dd89fbdaf630fc81600c1ad35e4ac2382e42082184903b42128c01630c98e6d3bf436b2e199b90aafaed7df6d9ef33fee7a652d8b22cab5dcd5c739de58944c7c1197bd977737e41e62062966e94e8a244e1271f82b7cc74404195b8470c093d7bb4ac941a4e34552b4e0166e1a530cfdaefe1048718b6bb3e9ca23d8769ec28540e99ce42843ccee1ad7c8e2188ac99547f43f3afb3e1aed52f73840aee4cdebd1ad70fe1ba172a8455b2a13a92e64040addd6298aec7aedbfe9141c67bf4f401a41db2c09ae3e1eabac7e58b94347bb4a3503ce5cb0a566177b6e060f7f9038417f382c542a65d235f8b32871d7f259e918f7fee1819dff67f7068daeec462fda9a56757c0a1da315fde9f5a106e235a03c3254241fa8b39997096f205fcf9040a84747c0452ab7ff05a606cde1328ba5b677d144ed0a539af3b305d7410b64259c1e2148448dd190891239c5f73c42075cb5f7ae3799c3b9795555da6b964abcc38ca3e6b74a1fa3843621f9aa1a021529e5cd1e9fe8df5b5ce6bacbc4cb1beeefe27585fe9f212f0fb2334abee81ac4fce97f97d218305146a2ec30a3bb776ad2cefebee321716e4a1ad679a20a6dbab1a2abb5696d27577993553a1a2b6f90643e15aec642ba82515d453336b22546c9bef3ce0a0191cbdf484b8fcaec5fa81ee59f9ad344bf8d52e63dd6609bfcd310f19eeca27baffdd86b9644cca558a9834fdbe6aca88b4c0c1666fff13f973249c82bdaafd53026fbaf95c99cbefd4dd3349f8c237d31dcebac709e2fd2dd9d09885f4b6f8bc7d41ee186c9b2b0f3113b5110c31843409e86dbdd23d45661fd9417188d99ebfe2f89e263bf9299d867a85b278cd826e62d12a6f5ad0b6e41221e7832a19a0ee232df2b9f7c50a8b8dfe733ec361416450bde5261d1aa9de6649426b5b88473a3c3f9064915403ad4bd8b13c0fd342a54989d34ca5b2b55f0e7dc3e6697f415c22aaf3a87b4beeb41f2be97c571e28f728178f1b7284b6e1075e4db536f8bce46c8ac508cf84386a01492ca12f7a9b2a7b01a18abe97119b36b2f0d798ca3dd9e0831dea1cfba25ddaf35a22c259d659d18a12c856004f7dd743468a0e72dd6c69a31ec4941889d264894ea290a67299d30222339c63318df14f6e1387ac44271036f24777d631880e4a8c06341f4f13a17150376f0e846a2a7f0eaffb2577c592d306506b162b6948f59700a2b50e6c0e3c46b4045eb82d033bf392b28f34ea1ef8bea87487ece3e463e32cdf5b4afc62bf876779513356ddcbff17602b36bcbd977920dc0863793da64831c3703883218822c4248df369f99d87c553e34ce17043e64b8a2319cc986b2044d6e31d6f8f8c380ae14ae20c7c90be8ef04bf667ec9f5c11d5d9888267c5e04cdd6847a960864a0075e840610f0f8710aa4e88080d3332ca97385c2611dfd8acda38d80ec8295567c3f53ca0ebbe0c11b97c860cc01241f2f599d9f645ca86c92063f89729c0c4d9ccc8fd706c553913d79972c2b9777a43799ead5a17347ac481e7f3533bf15edb6ef5d4ceac58720db79f0b7cb6ad10eb370ad664f3084cd6e1be651c586430727cce259066465a702eb0457a0ee01b8748582c5c0cf30f6b6969df1e4b8f504476203fd3ee89f71cda9c491ba3f7c10a27355bfdeeb6db543ecc44f15b7e243a4fb3932117218e09597da5819cbd1255f98e903d9f1b57fffa7afdb332ac7e52868b087899148eed1491edecc4a61afc4de6ff164b761cade9b809d58e012b344790de2099456b44588c0b8f191538072710d7312283e8b37b8de09993d3c98970448ec1e87d0e29371b6d965d6a8aedc9ca86e39169ee3b8f15a2dae9be5ed0d25b19df7fc735c6df1561826bdb25e9e3a4625a0fe4a2eaec64e5d8fa5302d82b2d792d85db6a3c5ec229967dd8c9c9de482d5c91ac3e2677caae9a9abfcc311ed29c9cc9801caeaa2083b77c3a29436e6cb4a62aa317b7548bfb8b43ba1de13c45a71f94f2895b03641c68a5e89c5e8eef47f9f917a21ec5068bf1f129cf86d1a15647022808bd3282e4592651ef1c5a4908846775f55f8a0c7d49fdd787c724ab77af7171d94f2d28f556e1c36659e583afd2e2c8fa245cf5a8c0573593e6745cc490b2e59c8ee3a9456066a732459ec7694ae273639a24ee02dbfe4c6ec05aa9e78287bd9f094302c8e19dc38c16c2283722f555065a726ffd22a7c29458a0a62b52ba88cc544cc38eb9e690a3c98124a4ce2d0a6e5547b982d0e0338cc5f0219ede10f0b202a266c9b70df3e1816fafe9762fb87abaf886e9c0b7c3aba74f7c7b038ef35dd7b44b7410f2403112f439636aba6ab6103b358d5176431f39c1e78dd7f48b3f164f88a9a21e6ae3b9cf2339603f2fcfe93fd9e716e824daa8cf6d92badad33339d767927b7599147585cdcce8468ac5febf81f51e7eaa016d5f7deae22e2473224139db2483f5c07846b5c4db742ddb4c2d34c3fadd542d80f2d863ae9297bb70a36d86b671bdfe8bc6ececc9a51a586d76d96a36ebbf688d65d38e38c4f68d4f23e7d21931bcb76fb8428c3fafae5bf2edd6750727496757bc01e83d1038a5139f7f13f760a9e29923e1cef06f6c02a4a9af204b53620ccb3da48b11bdda5c5238d6875873d4e20604e2473c7af820237d2c61581f1f616c5812bb411f8ec661483a0b07b56cc89ef65923e283d0a6253c39e3319fa22406733c16503c55f73efd58831e8bece00d720498efaf583bebadd4942a43901b22da871a0d2e7e1f55d4504598ada2885871f38232308bd842623cb89dc0e2b59ba44b561f4cad74d303fd50f183b0ebe085df39311e59bf31c8833a29f545ca535ccf265d244a15b13d7584a879e4ec99f3106749f9436fd6b6272d44d0e6fae986659bb99d50af9e51b2f24116988dac7ea4766b15b58d663e7bbad5577be691ccbe88abfec83367aa7db4abe77f7906cf39e48ccdd2c5ded5444d61d20b32659b062f752784a7c898a6839ba6e9ff89333957e7232d62de8379d0421aff0d85228e825fe925b17e32cbc540090b6a4becc32348ca6611ac9ecc0231ac0f0545a6d6eb33522d6585f6a85198bdeec9e62d43d29c7343818a66b02749605a25bd722d23500bc1114d4dd84834cc997d32b6bb59ccba5f21c58b11b2a5b15c8043de152af855001172a9957ea1a52e8cc6cbf7cb6453568bbe627afe53719a7dca6af99047860da69e3b3e4349217cd081be27b120e530073b5a888d6483e2ab3eb318ff6c4e6e5b384fb952eba23aff8f99ae99643e62ad6c13f3f5024ffc22145d763760eb50816c723af02d274fac4e2edb860a64fd9ec46fb2bebdc10548ff7f6990b9fe937e7c59324566ac52ffaf07f02a9e904ad6ff4589a4b612f0fe3ed46b0b09417bac50de0c2de809d787470d59b4fa8c3072cba4f5be82bf6478997d33296c4b06311ba317767e245a3d02de051491a066922718e6b77defa1a348b2bd0063d9f341e81f8787aeb7b9cb0fb4aedd648db601d4eec8fcc6fbc4a4cebf2b2b3bff291c4b2129a87bd2ca9373bf1d66839d1df74cf427776256612c3faf09464f7c4109bece4bbb632467de16d3b77c4fbc8a1a7bb68dc70e1b1567ac0521d90cd6349378d24a14487e77663d229f07db2ef7b4fb8d38dea0bff528936d5d4627acb100723e8385f4d6d47faf91c5cd799a07763a34a3b9658a682a5a8335ba1fefb2c9d57760a1b4524623228dec86eba445d4c21a78763e834d3bd302dd2ab4c05eeaa2eed36985346a2bb4e32b611c72dcd2f9862144742d10bd2070755c856a3328621d4e4e7a60dbbbd6d13013d9423d40086833a6c6664c8d43047a9ded1b10e22e9f43df0eb61bd6928b3dec87830e9ba26b64ad44230df8a0d31b555316cf4039426dbb6953511ed954d4936eecab3dc877c4a80744b77a5bc016340172bbb37ad4f2042df50e455977280100b45ec4aefef8917f777a33a976b7364e1ddbeab10c03167070a3f8412f91d788c98c2b18a191f7c0c2691347799d5831eca895abc8eb8d7e20ec899e7147090725f6d1a950af00114cb3dbaebb9305e2b8b813078cfb24685c5c412ba94f85659dc702df302dd4beff7684fa32351ce9247598f05450ce58fdfd894842e9f18d4f2f8156a6f743f5667c7a996f531f3fb8f42c70bb9fee2f0ebdf03f98c671c121ae857fd97337bfaae11f7bee36f7d90a6e7beea6a277b4d73d6e1c362cbd9938cd94d508d43d648eb73f82d2b7509b1c7177899904485b153837dd37ab915ea31d7d7f556a0334522a621b5b9f9164ad7e2601b5c4f9f64ac856bd4b1bdff7928def14f9bfcb6ab52b86250205fe7336d16209a103f18c6d55b475b8a217b51b5f2633f688584888cfd134b3d866f93f2cfefe057a0f1b09b7da5a31d9153ba538ea556909fb16d6a92fd443cdc1ff3bc279ac3efd53dcd34838afa7f98f58a7d135d6c92fa83f458977452794c1afdb8456f766ddbabe2cdb973275f5fd8b7ac27d4218e0efc3c92b25085f847df0ef6ec79377389c7c4e71e465691139d6677373c11f85adcdac6d4cdb23e394e995fc6c0a410aa98c65ff7b49ebaa645f0f6a288b4f705e5aa4282498b706392ac6555ccd60de5453ce29be4bcc641df75354a15b19c15dd520c8df7069402d6491370cbf309b86708582243d8961c9355a0952cc524df83f8635fc1dd4a9292a9031e51f107bada2109aff50862133dcd11a5ecb1530e10be66858a237f732ea661f0836fcc062937ae09c0a85f25e808b3ec0c4ba630e23026dab58ae10bed2a9e2e019c60cce20a61337c662dfc0de3ee608489c58cbfb84b843b8ab47bc1d27f51489754276c76f01531e32be7dc1e4652675f51cdbc51072711f41d2a5143239409c5901ee577b41c128eab1419466bd882fef41c7f39c230eb3be1f71e92308d4424cfec0943e900f1714966be2ce2654fe85ef187beb4d7ac9d13b1c181c597c833c91e2522fe489ae502f4b66144cd326ea86d54d2f317083d814d5cb9273c866a812ed97df902426a59d17ea36bc58744088a8ee2bf0fcf5406da81ed71b08782029544fe53202350a4d3df6d5d6536d96d934cd0e58923df261126e6241e99af45bed97b3fd6f3265f079f05748d1a4ec4c8a450b445a3530f22ce4b1f7ddf913b416059bf7b03d9c3fe0e5b1eb72edc9dbf8c8b063b40845a210dc3ff38b136872f1fca45c4327fa6f5f745b2ae33e3a252937f6123937885b503f6f12b9d1ff0d548210f0966d04838ad4d32ba12f3f4864f1c8fc9ca5eb2c72ee8f89506f853e46612ad4d3109bfc5c0ae7359cdcf613f5aec81e1eefb29ea1db00c913f2bac6f4a71321ebf2db069091817797d60ffbd807662c1f1bc8a389fcf778b73c72b058114a360360d41bb39c8ffc2fb4f28bec27af103d980ca857de23ff40c0f4005b621a3fc9a35e1b3b2942e4a99a8f7fcfc4102884793a8bf16f99189c825c0fb478bf96f5326dcd815cd03ed0cb15815e6ff994f259c4e6466ddf4672cb3ab7595fd0c2a3f9ad9f1c08b72e4f50afb7206b08bf2e2d52be64d2e1b07d8301c23eca2d7c589d21f592febfed83d5a713ff42bc3bec65a71ee7b426ae4dbba0009e386bc1c36ded663794ab2ded5126e3c94f244b57a6510e21396eae4da38ee8939e7eef96e9805fd31173944137d5dade52f789b2241c31cee64baf0e57edcaff72fb0e9b4c8b9ced4c4f1df7ad68ff1d8478e072b41511af3ddfed03fb2f16cc6f11c5cde52d9e1112dd3e53d83432fffdc1ac12c939da63f0c934e5d51b428e0c241993e90d8425e3c220b58a457f4362ba739646ebfb0348d90e5a8c32de788caa608403f6ac97007eab0d3cfe7dcebd6db0c4db0af56dd58e10bbf613967887b5b8ff626c12c3f97bccacc1f538911dceff4358627234aa9d342fc862899d9b58e28039eab2385bfdff75ddfe67985d3b5635d830fb59b8a7f224e7cef86b4871b9f33f64270e3a04045a70f44c8cb43fd62fba3aa769c1100f7f92ccf8924dbbd76445ae05be1f4cc8eca3e68fdf40d363d18ba4d536aa22056fad0045865cba18679660c3b979929c38e46d09ac4b7f115c16a12597bbd66fcfa7228e9669898f1803c144daa882b430d2df01ac9b659bb7dae54d00eb90a244efc582dc69bdd511c6dff97df6889bf938e28e477eff913c39d55670bcc430eacf3163e167cf9909d9abc6c1846680bde488c7993161bc1988aa5070a6f6ea483c56e75029bd2e89540aa3ba9be8d787ed02f3e054e6a02e9dd1a0f69eb28d381531db73f49a71f333751e0ff83cc6a13b2870f4d36667e73f851db7a31d315f124135cb55b449dfdc0030253a2ecc23c2c9194b56ce9010917985fe8cab08a86bea9eff756c9189f47bcce2fe95ccae4b3273d8bde2be0dc18476cf2bb88b4391582ee7eeaf827584490f684be89059f8972892023d651cda1ad1a55522feb30395a34f6e0990018caae4e0e856a6f9b912aa5527b39cfd9a429566a3fc0f08281c80d191e3fcd5559c7fdb461f7563c99dd4d9f0ce766d6099416decf95b1b98d681109e64628b9e67d15259c919aae9550748a6810d3c6e104553dcda1381aed8482ff3d15e013a97ae2605bba3841d2a961b509c0fef124cb25d00cfecb0cd971cd15992aa0dad9df2ff3c73cf26b127a0b52406597ba9aeefee7197a27fcf30885d1709287986e3a9d5be9d2fd241a837d912d87a582249ccfc0148b2389cfade93f5e9cdc9b5fe45930b3e18dbf8605ee6cf3f1fcdea2c798994f844232ff07bf893f43d2c61c5acd0c61966bf5be280b8395213e3ab19ac700bba5064069873441ddff5e9c00df5a0beb80d9832861ee978ef5810c0a5f855329b00965859829b5426b1c4c2b1906c6edbc90f447f4398fc4821cc6a38211dea3da62d62781893a2b596f56ebe2f6cf016778e9b7f591accb138750a18e0cc52e181f0af6a294f23745988069cf439a8ce4c9d954d5576fdac3ac335281af0c20f8ba0790241f975f1a6ccbd98837220ecd7180e87eea9da2237e7419e68e39d5a5f548b4f2d56510b4c05dd72526e9f295735e59065ad5bacb6389ee180722178ff3bc75fe812aeaf9294db66cb1186c12d003357e4d8e7ebc00464b7ec9098a158e20bff63c3f4b120d3ced40255782f57691183986cd61977e9e88d0586f0e9f23ea9c3dce38a449f026d95d7624b7eaaf741b03393018ec3e4ce5ed2b075e064ecc250d3a19c38ca6a5b1c6874199dc3553de5a41e243b8f583c463d815eb976dc36e92e8cf6c2fd05168ffddf7f986d3eec320d4e570d327756f2f5c70f0b920fbb4c93fd553d95a49ef7db1f3612bdb85deb648803fa2e4dc34741c2f65f6f97e08abe6d7860cfd8d56609e29181c58340e7da572197c074d5af9b337425c9105e92836ebe23866d3da7c6423d0400ef1dee6eecd7a207b6034b22d5d56f6908c882a4d614ce2f4083f301c5a573a481c04a7079383038bd7409e5b7e8055b7af8eb52b02bc44232cb501df92bfa150e3f0ac157972eac0a2ddafdc145f38e0cf21d380a99b080c71223db4d97504d6583b108bc4a97924461c679959a0d8e8fe256205bd5e05278209cd0aeb9d94ea5f82cfbfd8f6c086e55869c26f96a4359ca6b2bc00164429dd2afbc2b7abe3c75fedf087bac3c424e3f37fe55e769f9aa867fec3c45beb24b05ff20ec71fe7ef52842a226f5f8a21f8f846bb5e6847d1d83bbf24f04099c915c1564749f224e39b28fed53a8072d309b90b7d7b02c4d708dfdb2dea5e234e6bf60367784fdaa927adf76e9074ec5940fa421115ce68aced77274a9e81248a72e8174ce57cc8dd5d258a160a7a3f88e72bd90ff174ef77fe174ff174ef77fe174ffcd703a15a7c2e9fe326cae279cfa55d8dce1f017cc303f06c37d6786e9198ab364ce36e7290617666299c319d658ebbd412bbc1487e1b081afffddfd78fcdf893debb6e6f2670085c1c9582e4c98d3bc2bba6799dbdf78a6f49b671c223bf92bb7a1e852b6ffc7671f168b24d97f81916319d7c62d0f0960bb7d0beea98cf555f46b7b64712593905a2009571d52a8d3985decb83bd8360605be37f3d2f738955e26beace7c120670856e67012db77a521d63ac219f08cb3f0c8a96bbf06951bca6c014064e393b93e7f74372d61a2f35b0d0bbdd0b49067a4422e37f5b645ee23f423e5dad7274d5869c35734c37b7b5e058f2d423cb623756f404f3b2fb4ca97e17f234247955a7f1f1dd12bc8f2738a73592f2fdf93f9ffe93808768b0e99b58e0d5a2b6c5b37c383baeb24c4211b03d411f6ae8d20a0dbe13e6564a0a4d9e3206398cfbc9f37637b72ac3799b0c6351b974cf534323144e10d56b09bd4dd74cca7fe29fe6722c427b2c6771744026c477684aebe1993f379332687fd90cdd6550c0e07167d8bb9990ae7ac4a8fff931130370948fcf09f06c02000b55f067c87b63df581336750e9e5bf870ed8a1dcc3c43adc31db626345c0074f729047ccd7732b705563335a4b8f65e3d58efc726759a76f1835e87bdd438a2614899ebaf340b2d328ae7c8f677185aadb2b38a226563fbd0bf6773b23ffe3fe0851a9303a665e652267b045f68f3b46322f106c3645d765825b3887cf9f9be7395b841fff87e25ed45325822fb44a7e64e729d7fbaf85c1a8bb68998e7b5177852e14335ba877a8a49c33630dd6942a65655381aa4d4828885a57e14eb494e19458cb3a32c2d90092ee7e5b96986855649f7f8895412473bfc0da5c8eff72544ca1b5c6c2343125b557834a1a25847a1e2379fe2e9aa4960493f4df88e671472bee1fc492ec54122a52fb0e7ae80831de321dec96a6b2b254438bed6e0770f7b7ff18d85d953036622e17888f03b54e414238fa5fc3c06333fbac22d5e51fad38d6372bce325bc11f8c38c137234e33fbfc4f00f8eece2e3f5d86c3c25ec5e371cd3fc5b91dfa862dd8e0826b2d644467bdf88fb2a54dc61fb7d4b47f378946bfa3f9e809b56c9900141789153d283059d6a9cc51f5f2cfd9a71c4e6e9963af277110c898a5d92ba9d8385b4a1de8253dd044d0cc8bbc34a993e8ae28d8ff8337be41f551ab9f1f35a02cd2e9d0e0271f56eb78d706bd35ddbe532699d6eefdfa01b05ae55e8c6ee10a3760b21107e6b93ae9ebbe6cb481e4e6131c6bc557e5bb7495ec2757963c25a053f5d21cdfb0c46931fdb18654d88c9507ca40ffffde336999fb423dec6b9c17b3abc572623f98a231bba76f5a9c0aff3188d42ec9e56dfdae7c6cdd02975e543bc04cbf214cffbf002bedbeae7efd57d5d0ee951afaf09f42af1681eee903ce681622a4465f2e61e3bc421cad2585327a722f83c97f16240a21487d6c6186fb7b74a832e8508607dbc27e87bbee6fe1a27de188ff15b8688fe0a277024a0243411dfbbf0805fda6b01c3865c43f817942d1ff6162ed71c4cd641cb0f732905a771327798494de2bb2e1e44a000f6c16c0ff4c31db80357abcfbcaa72296832ce6c4570c654cb8649bc00940071243fa35b5c880aa4a0a91fab56cd91c9785e8ba23fb84d3548672b45892e9d9fc05a1e2cfc0ccacaa70960688f97f00cd04a07998f2518cb416bf07683a253bd7fb130a7394a40d3f67d9e57f405feebff2bf835782fcfd9fa3273b849ebcbb464feed9a9181fff217ad2749479d0a027a35bb04fd1393fe407c28e084ee908e769d1b4afb161ee1fb061779e3c3f13d801aa934a500dc45ed3ee443411ede46c84b1cb93ff35bc972b5e5c46557c833ae47ee90f8fe5bf0e00fb6afeff179c8bbe9d2b38fe25a62bfd4cc8cf88eebeaae78efbf81dda65c0456c714923bc8473c2fe7c138873fc0dc2285359952b5b6f79dcaed1387da1e276d5fa091d84ca3258b1dfb7ccfb0d44285b194c823fb76c205cbf5db9ff7f0390b178e650f2c2bf0ac8985fd5f0cfa3d907d90afe012063ff79f5e86d4046a195cb202e8c2faffe2fa5a438ef39467024d4af5249de8cd3b66fc4695b7f7e7028dcb75cfcefba1e29dc946f335bdb1fd2400c44376c2d3314cbb7a3b70f5599a8cc4f5e0b1a735774df493b6a16117aafeffa72bfc3d222b9ef7e8f2e2ddde95f4fab3baab34a6ea6972d02bfa9e0d711c9b28967413dace81da398beea15f8aece13d58848dd4722d370f27df17590e4323dc8330e240465af65154e2ce7848c99380bdc33ccfd76ad42fba68da86038b11ca44ab38b8f14e40a39ad4082874d002257ac58f32e4e18239c7d4bff0c54c5e60bc1a311b2cdec6a8a4f43572897593e86a52a1ead9054e16c1bbc61b37dbf4a84e3adaa9c23762805d09f29e1f00ee65937ceb14c7abfdbe7985d0014102fc7e3b9020504bcc1a45f42724eef80d3e6538bbdec6d3ce1215d5ed75828a087d58aa3d4cbe04a1f34a9807a28afd82ad68199dde3d402f3821ee03141fd07b59ae4885b745a739cf49970e7d09046ba8fbfc8c2bb18265dec986510bd13f48563c01a21a406566b06fe91410f47364f51b23375543520dd077536676dc82ce53e1f0861337ac2b41a22d6ff9cb48e7c75c0f7949be032685dc2faa7e705849fe242d1261a415cd19bd7421208d193e2e9a78fe0efae82c7b3a2fefa8b1c21e2565e69b5960834a0350f3830adbf85774ff97247f4a4a31c0ed4cf231bdc0fa0e308550162ce68469987d4878dd6eb8d6d5967ebc80c86c0a98732bfe89d133c61c7921e99c4e54bb7f684fbbea087fae856fabe93acdba98f6e9078de90b05a806ea3732e22552d30d7876a3b5da6f0ad8ccd7c22f49213565ae792f99807090497bddd29cdbd548454ee7a2c22cef9af0fb9ab03dd7385ab5c437cb3068b9facf0df6aaa86268bc677e02159414c09f96f0533a901e91879fc4afc8e8a71e9f2bd8e704bad4b670e2318727bbcd539eb8a4c9133ef018a1bcde9eab71dccdea988f54abd21e97363d7b8fcee82c68ad1f62ea0f073e9621403e65d4049b56cc5d810fa059288fb6b9f1050e353f3c65217e33d9a945e630efbb87b077cc4d989876623b049c3ee9c619be85ab15600dcd7399315619f1433b56b92ba06c35e23043e0c7d78c6b6323ce16f6296cf814a89287b9c5c5157ecd4c9b6e21a55b67ff0646a53ab4b4e79796b1371c49b1e9a8a7c0624e00556e1bc12f64ea61066ea62803ca606f122867236f39f064f2d1512f8eaee19e8ee79fccd3ee9ab8bf9eb2fb7169b289e5ae2d68ea90fe403d1a8b96db0c7fac07fc32c9a77c5a0241b40baf436b4d98f1fbd03849bd941b77ff4b8abc90b4a0d9683eb796cfdd53c567f318f3bffb579dcad3bf99ef8e57a20f2a0b94b22994b7699983d8d1bcc4286ba2d8ba949592b02b759f5b546ee14548e7c0883a73ce74a13037edc4c2140377b0dec9cdf7609dad80ff516f8383a6274543c36d842df5275d93bd435475dfcfdad97d5d7f7a1e88871ac4eb3d4b09e6fef4ffffbe3ba83b78da6deb7933d463bcc58d311ef8a51b575666191be258744d6d7df12fdddb72cd50e63440e80a75964f2adda622e093ff82522f92739a7c83c5fc1e6b2745dcad887a0c76eb855a955ea3cfdfd8aef68f1681d31079716f9bf0adc87ba5f089a9f2353f03911eab476d2167a353f853375e92a8ee2faaf765599bb2ae4aeaa9aae5aa3a5ff9daeea88ce83671c7d38bd18b662336bd2dce27a77c665c369872144ec0937355c4d69bb8df7edcbf71f287455edd4058c6a2f91e0b6bfdf509ed300ef2857a9fb26477ec59ece072d36102f9bcf160e32007680cb26d5c851e8611ac6ed89836cc0c53e0c9024d6257b56200f7c3be4db21df5608c385810e651c645c1e01b8e6d04d154be64e2a4558eb65f4a463d16ff551e4dfd8a00697878762d15a3205159dc85af1a4dc8ba4f38d3c80b2f1313e3686999d365b9e70c08f628c853b5b7330ea9ab381df2cbde3d239680ac3424001becb36a8ef70778460f85195c94437259980d86d48aa9462a1fdb263330af345f5c2396958ef8b39cbda54d170ff981f892119051e5d868dd6299efb65cbc8c113e2ef770b5874b78b7652ac2b6c5fe5ea970b7a9735bf2d786c27e71d30001e284e4df8b65b28535c57d02a867f7c5147d85559666efdfddc4ec25d82948c3e39e2dba8c0446f1810714a334484554f373b9e6f7766801f8e3c8fe2d6a25611c7cfc89a21accdbafd3cdfeecef979dfe308f3323f7f84317ad0bcfd3cdfee37b8787306d8508be3e647675e85f5dbcff3ed5e8e8b17a8be2eb1a5de890a5fdd21e0b0572c491a95a7ef33dbc894aa6e9791f93ee687ca25429e4d9f6f3c4407ff50d825bb48845813d84686164ecbce96d2c98ba985cb4bdad41136f24b2cb0c50f99aec2dd0076fc514a17166e8d5690f3989d5895a2ba7e21c522de7ae1427a58480b70798f965006c68ba562a30f1d2e8fdf16876d613320a96c25554a02619e052d0fc51edbebb035b8d0ddf47fbb80e9e8ff32dda44bbbc69d5861c20cc379fba27658f48292e47cff3d0f3c76bde5637aec1750d687f522f0346bac9551b8a0b55b5578dc79d27ba1a3ffdb7203fa6205c53c19eb67fc64bba15360d35809870c67ccec279b8e41c72ad75b5d456df19614621176e64ce9e1916ba2559773f82826fab8e4c88fa071c32665b2c437eb3f19a51cfd85f32a62b778831b00a5ec3728caa3adef7684fd5c21d643757780a1a917540139357b0e268d2a49367ff4c22a590686652e80e9a32c6926ce637a0ed2f471f51c393cfeb43f77c85d5d6b19d15e3d704f8cbc06c11a3f7275ce67e10ae79e93c0bb2b5fef72ea0945cf1546a4d039e0322e8b62edfa20a777b02a2f43e50ab1914da25e74229005ae485811a35f3786953004ce1f86f5ce971bb46fba2bf3de40a80215c91d47b7eff17718d35ff501dffb02c469c325fd75d0be0e96ee3f1d7ffbefc6df15ead91c7f7abcc642bd98c368ef4125881956a97b5b2b6ac01e34b19a4d0602c2e0ab63cb143e799029ce570f87e5ec1e4b4d1a57a1fe5fe5fbe0aa79fe15da33409a0f1e2df02e7827d50b63bcdd22a7d2648649d75cc7a1aa22993d55453f87b67c6b2b3e5c55657393ada94811e0f653295350f4405ea95e2beb6c854c81e99aeb7c9c87d2bcd97cca2a95b0448592c108c91765f39970615e75b1daaf6e0b0fe669d35abc4c356578d5ac1315745fb8f7639ea404aaf83053159312579dafca0e33fc9ba763ff7971fb941e2f8e8ee593d9f0d57db2e1ab4765404ceae90e8743579cc8b2b3f37a6b151337f6d6eb796adbe0a43f4a6bf57c1e0cf38ee8bf6ce6ed8bad87b9be7aa5a342aaa5e291bd8c801abfd471a4d06fb6c0b95f311cfc9de2193174a5d46f830b0f94b95a4156d65115665efa4d58f9aedec7ccd5d516760816dbe9b749be5197e66aee8ce0ba02d7ad7febba19ae71e5388b218313dce530be10313401e3ed341a50b93c865e2ca009768f6b95ff149db35c18267536b8c5bc69ce6893ee2fe5ac087711624fb933f7738923974ed625948abe49d8607af2aa67bb511d1664bd77bb1c2adaa483ff5557e1087577554537e03cec11ac5579570cab3237bdb4a8025e3c1a5e32f6e833a50b5e4241bb734869f4ee84c5165dea3c1a431288875afd5d301dcf127fbbef7a83784f82949d96b8b1a1aaa52c038788aabb1e75ca33f3c8f7cf1572447f6e1cb021e53c8c49012c4afdf5898f8993de39c747b9e00009682fb0092d2b681969a4b0887556b8767f71441ce68c323b1afe2706186fe776825f3b2a96fa9add7c26887e01a723fcea53ff49ef69610bab7f2ead1a3aee84d3bd7f0edb98d715dc58c83afe6304847e2924f75fa06674c37aa4a8dfa2142976e669de160579af6fac28af95a2e34db97e230bb5f10914d07a6ef0198a9c8bb47914ae4521ddab39c49e0f1020f09bf35085ad39b4a3ee8c9de03eed29ea2d878ac751158b0118eedc4a2691bf7aaf9a731e2dda17ef9773fc5a30bdc766ad4856ac629e258768b995ffd4b559c06b56eb50d22b7545720dcdf6c51aa697915ee562f88570a0339653ef34832d81ad1633a6cc1a183eeb56c4189afded8243ad40f24aee1e6e97e927c9a978ff1c6c6f171c09fb9862b18696799e33f46385f0a0b5613438cd39923d99a75c628b1275397fa2b5bd7accbe6622d4595130fad0baaa7cb3629e6aaf4822c43887e4966e98aadb15b91ee10794aed5f32f1b534f2b326b5e3e38d7bb0b4a60b2930ee67784ab7149cbaf3579945b40ddcc0b66c61d46a4cb8d0d3ae158455ce7a90afc193cd2ea5daf924b0cc1e2091d22406539a4808217ac3cfa0a202d974d5a527e6bd32464f0e70b9aa605e9a65c2294b219b06d8a802f1bab8dc8248baf3a5a2ba4222a9625464d563cc43b05f0a239eb0d7e23f18c70b638eefb1437a95e590272e638fdfb4bbaacbfc215d1332de7bd6c2011f819b80956136f0bc90a94e151fd8652c3d0d9feaef9b352a39a6a8367076c523e372905eccb82a48afeaa9a56805520cb30f4b371c7e80c626204d15a594f51559075beb0b7647e22ec97253fc7dad03a5531258f8781fb60c9fc54340655423f88299953a65e88d08479c836fd1df58d13b566656c57b0997e9ea9eb58bf700ad2dc86656e2e4b97fbaeb08fea778f371f770a1b6f659926c6ff8dc2cee4f355627a579c31e084d531b02c79cb96122e30bf18299ce8d7e4d16ac1a395baa5c70e35aa573de9eda735276859c235dd99ef39fc9688f20a1721944c23cc52a745b7330ccf43bd585ff8bf43b17d7c56bccc07d09b4ffd8b06d79d619388321d7d541586769bf7183197958db32c1fec4c2b13e58cc46efb2ccbacece23566a3dba5df635715c20781008539ce97d97865684e9e844524a3097c4152fe9d56b45445667af8514970841ba815b07a26886fbde2fdb80f171579a51e2135d06887b76da3be0cc0efde5b9558caf55ae60b477a0a590020bbb02a885e0e53d5989e9ca45fab5adfae485fad22bd82fd5d6fa6aa4ddda7956daf7dff6da7f55ac8bb4cfb52be2f7ead64fe604971def61ebc03358abe836208f7bbde59d6a836719290012f7133bdaa5229941547cd8c29c519bd622cd46b8227532f0a598327427db028394e129df17fe9b1213d4665475496eb1dbf5f100593121c49839896b281644738f9fa456c86c30afc3ca555a670a8d86a323c935d83d35cecd935bc91647a22910259348a27fc2c9dd8df33d0071b1d87b91611af2ea4bb2968b1876289464964b74287dac8bba01841b344eb027664cc4fd290c008d7a0ecec65abea4138229c5e112e143d70cefb0e99387a8dbd61e94441bd204238b19698f5fa972b9c674c849cde06decb925abcc788aa849329b42f1d3c3e36992a26c746927b787762c8df9d46dce2579f8f49090af3d8e839eec4a897dc9c9fe79b95054965b9b8c5e0b5d2cdca4aa80ce96fa3028375412bd72bc0e1e9001cb78ddb4c879b88573b84881000513de8c7baec78528f6b426cf40fac1677f4296fed715879b4093ccc9e2035409bd145cef2950a44943fed61d3cf14e88a8ae493611fc3b3ad520703d499dd21cba8d413b607204311785ea75aa0488071b99048227a2bb345d14ee19416b2c07dbb3f315a6ad502fb42de159eb390558e1b5813279c5acad309506e8f60f28db698032f3ff4738c9bd72b0e704db027b97a0cc2d602f787f0146a35bcc4dec0bd3c175a902709f97f62de8987bc23ac4ebfa7b78b4a67c9e878f2080c07f99c5e687cede572cd8e0194ee2d8990615cec82db0768853075d10e24f0e71e2e2e1e80a66aa72faef922120777006a18e9b38244a39e9b1f898f6ede159fefb05676f243f1a52fcc2494d99e96753ca92fcd2507da3af9a1f06537df116be411e6cc39b4653df1ab06423d3569f2756188cf21c3e2789c6c2343f031ee380261566737ec486b5a208d9e5e0abb99c28b4b61bbae74e36bea2407795b04cec791b4b195b3a5ed284646bb06a4bebe4a4c4a0c3da3be1d1b30b8d1835701a228f7b28ea1ef34725a3c56bbd6125e0397bd071c4be3246c35557564daf1554447ff186a0809dfca92c823880c97e6b9001e88ce8a1778596be1fda015c083fabda6ae28384d3947550898c5a4a6d5625348c60362312207016674c60ce704b7ee160869ddb907e35a11b6a42165fe1e05e476b73d59c991a1f797b8bc849150c393d9020b0c3a6a789ce74a77b99a352fa6f8973abadef198340d2f1bc4be1e9f86826bf9203df0729c7232e5c23ef072faed0255618b0da2fd05821efa9f180e3a02691789bbbeace5daf99a14876e6446d5d65bcca750f747722fbbed1c60ea46cc99838f93934d86b916436b0bad9b27c5ee2edf15fdb334ad006ff96859c0145a15da5a3338ca802facb1d10d0b04cd3d3f0c1a390a265af58f724167d467843db08be0319acaf3dc6fa772353b617dd9e6e9e61a4db14fb2ca4e614f231572c2a14554c5500b30aea5a0c7f63bf989e8bc02fa402dd8c863a19d1a246e506a9086fa48265dee7ae7fc14f6d765173db628605614e532d74ea91cbfabf1d650db9ef4d72460de9d3848fff723b8c6087e3b9e7777f989702279a97c221c4f7a5703161043c0b13758145b7ac0364f47b96563c199fac67e5fe420b688549783f1b73f26a1990247c647dda55bc968db9364c88a12fd502a4e8797b7452f92746c5624890baff51c6d540d048cbf1f084bd35bb6b62775099b09e7a9b099ce2e07dff661e65ca2cc5d961febacae9661eae86de67047b36d887e53e8657cd21bc95101e5ba92879381443894999f74775c429fae536b767d59b31e92584198edcf153316921300f0167d91c3df49a3c2d64841fac82c627cc44d8f0c2f44d672c5d51810572305cb9cdae09d248be9583fdc04c55e37776adfa4616cf474434b0a7b70b347850a27bd29ce5528677327af446b2e1940d3d9acc878de8bf0bb1733b989a7205dcd7af9ae708fb2d64ad37472685840565e055285e71575216ba9bd1567996d9cd0309f439221777562321dda5f0cdb62963b127e69eb46cc5d6753a6629e8ccae972fa721fe123c22d2db07a36bdd4838b2ab8d896682afd1e019730389338eec6819d9aecc5057c1011051c3bbef2d7702b14670e0dcd9932372c87d8fbd7728316f58f969df2fd1790aa790f40792f2e6835c5fdda2065f86793a7e639620ed5a11eef03d0c2d3c2f5dd8158cb9d6e8f2fc5095bdb82a7a322ef9e9f8aab69166043aad0c2574f5681fc213dfefdb89b3b1729bbe6816aa2ee19df88feadbe42d6ac4136db25554a6b75fa41c64917f590f43d5952a927c5305d133973fac27ed77579f2845c6807ea504f9a65a5f4ae46bd86d000883d93d217e4a4a916234b0811f16579eed05ee9f36237dcd00ddaba5c9f7779fd425f521a8622bdcec7b20336ad42d69da334c380e1e1cf743dd980c123a17c36bfebfc9b43f10f47c0f916a10dd6a99e50c716f5eb45b89cc973f67b3ef5a1f7e3f79857ce67fafae949abe84a88d1f96aad3568bb75b45ce23ce5023bb52c0b819da24d2d62590c7879d004279730496de23297627971b2ccd09a215b8f51c0c634d34a2a1915128070b44e21540a83fc250723078b546040ec8775a4bc968b0a2bd3449f358d77bc762a2680d63734b425f0b1c472cddea1fd33ad090b49b6ba0709f26c633ce0b373012b623f9e3b0610cd04afe050eb5589912e681d9a76660ae49847c7c977443f4a1a64a6592d351326c2fee2df440fe294647597d08590cc11b243164a2f6bd09c0768c5027286d53d8080adf7a8e708f470bff24a1f41fa910a8b9425b8f96f1f4f5dcf9eb3ccddc4948b28ffc1fd033fde9fc1d1eb25bfc86dd611ca534bce0499d01abb42744bb07bb1b38e5c34512ba27d68f744a17827b9c1b6d45bd5d39670fef0de8655a82664d46e0c520384d9eb5f847ab5f8e50d483097e0b81d57632a8761a78c7ca7df4c0b1143649050c629d21f37a21dd9d9c7ba2f564f81dafa7aa98a99dcf9ada4f69178f4d46c6900c05019faaccb9096ee8ac94e79a13472081d9337c7b9f42f8eb3edeeeef2ae680f8f6694871809e5cbe29e775557a8f7df0c96f2d44eef7eee7d119c4a9f85cb5c6069b12f5eabf2b4b6b16302d452944728e2432d4de937597ae44691f4587daaf890aee8bac39b4c8551d498289f68a35eb8d1678909818657828323ba64e1bc77fffaa0771e702aa70ff711231307f99ed87cee14d9e3464ddebf0c699fded90a72d3b00d49d0e06def19a6e9893ec586c98f8127fd6362329d88fe5226d446536107724b7662fb2e84e2fd1d0852fac069dc11fd176c830891f9cc2b41f69404bec1ffb545f725b59f5a7edaf4e4617abb1d58afe7141a4e5cf29d236c5ebddc06347b25d04b61a16e4352815f10d95685e461f7e9c45ae3d4793757b7b04d6c4954709ff5ae49e8f5b9d6f17b0f0eba4dd75af7d3c16fff4edb2ec4340128f4ba672402ceb69150a3cf01b49f3b53a4c8419190ea74a33d192e54a6d5bec9393c12ea218c55aa8d14d8a43c19663eb4ff60bda742a4c978cc746efcd8a03477f27dd1dfc91c0e16321a3c52d133d7a58b0ec5f8dd3fa7200e078ea1f159a06a362fa602db8dc050b0817a382ec308d3f79ad87efa795bb40bb2dcc07c2bf18b8ad468312eac79cb8585ba3787ff7decf9ba890eab503fe4df3210019762a4c5566a25a5b5938715927a1d1ac0d15968d3a481bfe3c0a7d1b99ff9ba43d4af3a0565da5f35684e80bdae2966ac57587212917b1c23648cb518b10803e8a8a8553345618fbe3aedd05b1ec7fb1e304da943dc24c57bde169d17fccf11fda75513fc979042d6e9a0901dcb3e5bfcedeafd7a24c4c46327b8fe6d76550f46b71d505edd6d81d1ddc5563253060929b7c7a5363b3b3f160e6c8a05e880044479c9e1c794425fab30270d6b0401322e8cfa8924e711e4a6034769738a5912320757bf89c364453bc638ef88b2aceace3f4b61e8ddcd74358b1030985ecd6a99ef14ee8d056953be6a4ae9d0baabb22a7b84ba4eeb1140a8444cac629c3a151eaf2a2929eacd62386d8961ae145e0ba1f859dfeb089724b26741b22f34c535eb6fd7647e5e1d4bbdd1c0877b7ab371a2d60ce4a0a5fa65ef72847a07d0f55c48c359b6ac12910af0e46fa0f31459aa190a3790567a20c5944a86324acd02bda95dcd82e70e85cad99779e71399bffa10a979e6bed26893a6e3c492bd648ee87c846102e5532f9bb0cd2988a8a6260375723e4b980a02abef63f537e60e09c2759fc1403e43953d2e504438fc1ec2417f555099ee3d110ede8e954a4b32fe82c129d4e53e267ff22efd6eadc4afd11dfdebfb75f012f52352f46ccbde2f9cb43cbc5c9844eae9dab9a1f5b74cdda6bdc15ec1c3e740dd15aa022becb48e8427ded1befede8eee5357d80567b5b0d39f1770de80353eb32423ea2cd5fede868ede05d144fbfe87be8478d1dec9484f0b7ba6b2e57afa351de1945a2a3db21619436d4b9e322acb9e67e02f18a3494e1a20770466537903a8a505b77292e17f43f862e5297323a0a747ab7ea6d81e28ad82e4ebccde012eeaa45483569baacb228ba8587c065a6ab9f9bee894e41ed6be950cd8294bfc98aa2eb7a029f964e168e8b2263c15b6afaa3f084cfb61f2e3b986e04ea44564446d47a8a77d42b0a21e963b79f15007ed4beaf75368f82e892ac197fb4f96eb7ac0194cd8d3f1918c880d7756a614493b3df28927ccc86c9bec913f6f08a953bd2666be1ebce9d34be29b8bfd4fdfc8161bc39aa76b1d185f43e6bfa9760ecdc7154279b93edb48e6fc24da267c015e7dfc42fdb314d7a6fe82fa7be2a67e29d670589ee164670650154b2b969760dd3228c6a7c78593b299133e15e193157871aff2e6a88f190e8089c7041eecce010bb61e5b1b1124ee7a496f98844bc7dca210e22b96815ead914487a850d61b0c51b60854fe74cc314b105b33f9fa1d67d260fa1af56501c79394e3eb77f3a1a95c749a5cb7ff09a07c8d6cf36755455ff4f993d31938fac2e540e63a891df653cd87c85ccd74afb393ab225490faf58d3527ac6d5e0f486daf2e035284b434291cdb292a860debf5ac0827195fd640078e0b44693fb5e600c9e71d312469edc935e7af03b659fb9e19b8d92eb3a678d0b1b541421835879e679a31a6af6e47323ccacc75fd4057b85f286f3f1d96eaa241805e7152bad0b2d86e4848b5766f5dcc44aa377a97f6ab407a8655e1c898d5b58d05d5283199e2c5b0b90512b15ee0912e5080c752b6782556f946a5403b817394f399510847427d61d75be228adac00b2583775117b27374056f9c1d5281e8aa0b35d666f44f2542413e134c8dc5047592c828431ccde58ca324f88287563a0b75e28dc409e4df34af4f4869204c5d709bbaafc0b5e570cc225212adf8dd4ec80131a06912d10f5b95ff92499e0ebe5bf27c845c4b58a74564190c22f6e91f6660e3337bfc8c017b75a4310bd9d932c6a847cb82b764955412f142f0d04cfe19b8eb16a39fe6712cbc9a686809378ae39d076f9495bfd7b95030ad9dc43c61ff5fc4ad73668507487ccc264a97753e45d4d4ea702c5a801ccf4e3d94a5fd54fb962f45c7cbe74f60e49501bb30bf180e3462b27d5379dd94cffbd7bf299fa7586bf53f8bcd512892bdd325fb6cce50d8cccd7f43fce99f99a6affdd6140d689c10639569ae4fb516f096c8521775a88d85e08e13ee31172f0474d0ec60c90ec99de32dd0508efac21a1cb5c067ac03aec3b5ed1e7c0cfc671bd38745075b4c4997f94558ef46446492740973ebef2e8e26ab3cc2190c92c18e5bf73ab76441779bc7265f8a2eb2069ee36e6faf790e28e9eb18faa3a2fd5421d6270c577487e93253f0364d840895832a8c0e4e79883795c35f18ace1291c39d19a9daee3dae839963909b238d6aa1a918c2d32361404bdb4f02fa8620af4413049ba306b431d75b439f33e7ad8aed1918dddcbac5b27657d8af354bef900b85f7cd728ac5c18b5abd0c19aacbc85f121ded200171d90fe5396d9c4384898cab0c3607093a6483719d2f3610e74c2d192b23d5f42882d1a6d8bb9e7042d9c4d8772a01d749bf952f7301b9793f699a8c9dfc5438968c2192418a1887fa97b2e4c1c8633edb2d61b71d777000c4f8aecf17a216afdb8b0d9f0c41b6788fea3e73e927642ba0d27ab100a81e905de3282b90e976d91a0674d1e21a9e69111ded6d00e10c36a371a48f2ee72cdb68c49e03acb5c4a7aa726ef80ee36cd523430699f998827dd81811f99c7da0c442f07195fe9ebabddfa05f4bd9e294c1e7b390697ac93e6dd074080e3b850c3277f499f0b68fcfba2754491a091c40ecf111db5b410eb87939165ea8b9aa2e1be6816ab62133e372596ed25feab76b1b73a7997d6269869f9332f0a716ec8a19e842f601939c92e93ef86bab7603f9bfa73c15c900a54af28eba06f2e1d8e73967de09b0ebd8a3df4e5d22eb42113594c87a104b23eab3b3770c4fb02ac983a15a663a81b1ef99fed9ccd9098c1cff48d36c9e276541050acb016eb9f151a269ac3030c3c1d8f3248866a13bac61f81f87641ddf77192559f4e07d61bf805b77d9e9d825456724042100d42f64c4759a384ddd069faafe8a29806da10821feb2a64341a93f3c3047a60da7318521ae39bd599c6e77c1274be04a71901e829e98ed6453c3964ea70bc4a9b8d666182c417910773966696ea24f2d03c90e54e24d1809f55ae284a6b902549c35b84126c1ea2241928e5e6562b65ae09884599d5026cc9f0acc5e3b18fb129a6ad6a77a8706c34c1f2910608fcd32387094252586b47d59acb1a5187f87aced8d9b0be7062bb56a2a4cbffe2c648b04a842bb48b47c5d7ca9f6acb5d5b9fe5a8d067ce42f6fd56f57d5da4f387788faf19700da6205e3d5246036800d7e4fe9805125e50182ff63b9c2c241c122703b3f1624a350d75239954ae0a6c7f2176686156425fd3de2041bfc614bfe30e4f278cc4f845bb0f76be7220a82d8cb68caecfee4f09e641857905dc79bee6514f95dea281b30f76bbde893a2b5de056fdec644548c992195e8af0629174a8d2451227afd489824d4d36ec9d45b8e508f7bf3c315f65388e31cee94011e81976a5a0019e330c7b3c66841ec62776b9473817450adc2b48b4b275d57c4afd982cb787804eb7cdd50fe7faf8532005cd5823a96d9162dea188ef8772db277ed728074db1e979bd3f039cf7a1b709fdc244c011ad1cb6fa7c0aa4e56b761fc6d0a749a766dedc0a63262479bdbbc5ab9bf1972fb28d7f8b0cf903f50ff9e083139de5c48ca6be5b0f206113fb0614bedf9f603a19a411b99eef8816d1d835ababd549bff78a9be620196feb0525f50ccfa43b1e77c47742c152d53148656e19243a521dd25963a949ef378214f940b49ed247c494a10fe4c2c0945a0c416b705a5835462334acaac47ca3bfdc546db79a9798ce5f151ded9ff82179fd9d2fb8b62eb723db5fd6f998f74858378b0c1f47016277d58db6fe11a61d526a1a74f960ce7650d2d9b34ae2f906ef521c44e43928d772c1bc392350d94ae2e90308d13005745d26366e01a38d0a675faab7ce89cce01b7a747a2dfb33f18a6c3a14161009cd80c8b69ead16f15498eb9e2cb7ee0e0d5b3829d7e376b61c9bb3b30d5d4b949e6dddd7c5f7458e7ac3210e3bc6c254c0a4b59e1f8d9c5b26d38046c4fa6e045f0ad990f2765e8bc66dcd202558f1931d3a9ada082159893cbec20d1915d553c3ec51312abfa889cc4b94851fcac7ec4588819fd7b0b9b52d2feeffab7b22e67a7a7bb337c1b6e282060fd360910065fa59c03c15b49158f6d7dcc13d40af379c0f37980f93cc07c36651e444c033bb038dc7e7520c0962f217a0faa7c7d0d4cf1283464bea009095515ddd43739ea1a4bb689e368faf4160ce85a92e848b850fd3155581afb65669e7901d613a755e591b48016ad3c3189e8cf28ea41db9165d439d9e1fa8eaedb114da38705b9e1fbd8f460455e8c19bf1f30b8720bab248c309e7dea7d7b64fe87472c665bafac39063b81c68d7efb64d5ae22d34aaf3173ae9f1cfdfec95da5958a68d23727c6eff85162eaba2204bcfec943b7061cf8c8eb7713676f3729cfc77efcce81879d06cd8da71936a74f6ad7c42bb62e092e2c786c2d48c4b572f21ce5c6825bd721bdbe13ca22fc379d750cee213847b9daf0fc03a35f157557ca9787c9d3c86632bc82588c3b75d968da7f1478ca3451c6053edc1954cfd2af18ce5848886e0b0975fae39c1e74d784f60c7eaa99f456b7ab9bd711e7b7fb537563d1a9db16a35f03e605d98065c3d91e19f99411138f6ac69b5b79de061b1e330dee8f48a5ec67ca2f5ba67c0e5897de8a59510c2a202b86ee92fa673ee2d29a5c7fed084123ce94f792fa173e47d371fd8d23a4a063babc534aea2f214b6b059bfe8c777f55924524538a287197bb3ff2fdf8c8f73774a3bb9ab791b937e548228537607b5b71d54e3be64b5002bb6524cbe7383ee7282dbe915ba1438967df092479889aa33b04ec50a3065e60d441f2a2705c307323f723decb7675f251443280400b5dc9970d935e96f878d45793412a6455ac60207a0588b33c5eea7d0148ff467212a54ee1ebb218d77c7e1c3cc302afdf7f845a4e3cd189acde3bafe1303bac592084d4dd0d902a27b98eaba5b503e63e0251d54207581f3f68a7671fc9d5fae14a76d60cab74dd46dc83db08a9eab95cf2e33cd9bbc40cacea3217329b04fb0acc6cea35a91e55907b080f33692db8050bca25b743c0df2727caebee176d50350ef0460f816bddd9b29dff14b6259bd01a86b335b789288f9525cfa91b4e12e78920a08e69f8c66b9b74c12ab683f9555da6d8d66b734e184a57db0ab9600e5fb101045e1564b4bcdca00e16b84f2f359d7df2da49c05dd38eb9aef9faaacf1a9e99d92070a95e17049cdd5f5f2e9343de20ba9d8bafa65bf338c79e9e9b258c2298078cb3da4e52c8195f461dcff6cb99fcdfc8a5d35b6029b8738f9c54e31d1853bafa21b2d1acb5d0539131e3920a5853ee0960fc9e09c58bb05557d10033198a0b9312b9c4570e0b1a0155b54beb8c46dc3cb5d253b077a06e70aad2f37efb46de87cd3c5b2fd8b81af285c5a2cd16cdf0f60bcd92898e98dac81b4f2b66a4d53dcab0756ee1e00dcd449ad338cce55c99cee73400ad73f635851d3a94c6a4366bc1fddecc9a031aa7d48ed03f30ee378e6e16326a7963c5694c7e2887527b82d57b881ffa24deb33f8c61cc1a9259a239f4a058c802f7696dd1262b64d32edcee53de26fad4c2ce0e12e072ade5e4bb163ba9e9e8e59d77413bafbb94403a8abe2e337fee6dd7c442fed90c1da47aa265ef046a4b8743d8bb4338dad263d3e59a971cf6ad91475287cd6e328e544f0c8b30341a77d2096109ce99feda8fa71214370f29e8671ff9a150081bfc2cc05299233a85a519cdcf1c4c03852e2e175955e4c05652fe92886bb80486115f44c7cd2582219024b32eb1b45732c2e1fdd9a0172dd44ee5bbc2539f7a4f7f25978cba3bc3afd5291028a853d145d4488fe86b6541d8a8172ed24d17817de9b5aad29738aaa3bbac50105149ae6851b84c6e4ed775b9cb5394a89e4b5d1c81fabfee409f8baf45f8eeee98d9a7d320b7a77ddf24db6d0bae96d70db192a9fb3336e44e1967e09eb64afb7d19652eebd9fc40cf3516a494112ee1b595e98f15bd48217cf3b544f4812fe99b8eb069c7d4f7ecd4bd75e6412bfbe09a1e7488d1ee21840bf7cae3e888cdfd4cceea6d3d8557d2c2d6d1dbd3d46d5729f2d51af00c26497870de3849cccdd8dde06bc185fd0b5dad987cd0161f8219aafb33dee0634e812631fbfb65cc1a967f942717f0a8ad3e3362d1e24ecf6c4b2e48001e101c5299ffdacf1e2f7a16fcc2fe6504d452a2e30973a254b66887f9ddbb4105a6744b994707429d55f2e8507461729b030019226763962a66f994b839ab6a0faa943eb2295dd1c5f84f897581a2bbc5eb7a4b3bea1da7da86c7bf0694691e2ce87a4ccb980ce02160f5275b8afcfb357d8e3a6ff7bfabebfb12b32d59c4817fb366fdccd5ea1a64d7a45e4a962aa30e1c2747d4f1916a5df6bd667f5d2387f9386419dc08e94dc6192e6984ec9d5d49577ffe77aba7bdd7c6e2c05747f56fbdbe671a717ce4508bfe48ac5ae5b3b6444930de4e70f70ff23de1dc0326e6362f45b44c9e14b94c611c750e2f153d333bc27e5e301b403df37c20930afac2b9e753b2f02fbdc3e5b80a56e07b5ba409eb97e634fb8314c0e9c4492923ce44b8d962b95cff86c2a42023ecf8e6966f5effd67d7beac5726563f7396f7082d648acb2733262fbe7e9213f11769ce8bb29e3dc5a529a6c5f8aa511055899cc9c686759f059985fe076e66c3b4bb32db06a39ab723c3d8c9adf54cbb2b96f99fbac5ad6991f7d8dc3610cbba62a49330f9b4cc0bee1025140711356a2e11d5668e0ce70e7b1765b304d387181d814807a6b6b4507a3cc7661988beda715c294ce58d98788f3ca1e112a461728fa64d9ced81c9694adc1f95ae0efd3a2282ff4a030043723279fca801542fdb43888798eae669d562d259346744a0173615018a47a696ccca76206746a1b87ed59ede43d24d4ad69f76bb60aa8c9dd33ed5211c7c8144934dc0d1837436254b2547ddeba59fa08de4ff70083e3f48c880f4b1d17b7aba7bddf459b1c4a04a0da69c8f9add63213ab8b00033700b77211af749159da8d70b5d2941c0a80c99195eb0abf17e12caac3297f3298986cb0b856c135b0c575e9549814203a049279febab4a34d4a75be7ca4dffdf406afde39b8505dce571b36efcfb4887317b0ed8e9d8cbd73c8c7a82d6c4238bdd6c8a663dff9cc9c8df3be73a278cf0eccd72f7c16c55f2485e1a5e8a9ce9ec0b6ea65832255bc882ebbc279010d60ba5a0afd2453846acdfd7fa7febe98c9d7bc23de21911161987dd79cd00b31bc1d0ca4e846b0797fc2a5940b65fabd25ae740b3ec711c970a8eee57675314b4d9caae0334768357544b8f9ad7a7567046fe9bab684a876d66069b6e93cffa149b64b623109ef360daaae679319aad849f753fc454216c1b1a2cfabe21475c743b0f0af9fd34380389f80777900f45ec4a584bac70f8b8a388f17d6e632781590174c2fb2cb8f22af726116dce547942e5749cab9c2895ace65b33b1262dbf540105fc85df22ed8ee16c7fc27f2bf4e435a01edba64aee23de34762c293a857b82e0638d860c3728254fbc80df50a8a13de042c2216983461fb5dfe021b2e82f89a067f9282adf4c484b69c57312f31fa108d701bd06b12140de096872f7dba9664cc02cbbc8c3c617b44b50fe32dacb10df7525cc5ca143fcd998f6020ec4006c6e48a8cf9fb2f80a9d13b9f3e74d2b9d649eda5443a06e11e38461c9de3aca6f94fca0cccb77f6fc7e1376dbfd88ac3b9fad75ff905b9d4e220e53bc348938f6c7807b614909e09b708f4e0608929d90579835bc1280c63ec92766375e953e2cbe2df67462acf2a8689471f8c367220d05d2d482677a943ec5062be90122aba08939d59edcc3346e95f4cd92e486c61812adf5d8278abb76628a1b73fdd3dc7f1236b1b9b4e260168637b3b78e06fe773fd8a5a653a063e03f4eaea8bad0938ff238ce7669a1f0be52373e638c6c5c51741db6336336f38ab563423dbf4cb6ac1d6048e9e76161f7aaa84b206d2928ba970c0f85ce0ea92c99b2850618b93cffe0b2bc52ea9c5860db010fee71c2a6bcd5a9969514871aeff341fc85c84fc199f8561665a54ac7672105876909d15e626a16bdd50d648072ecae7ccfadbd0493b974bade57f895d3dbb5c37e0fdf5a4b9915a982a90e7f9df98287998675f30507af8d9f8242f6968371f7fbb9f2cc812ecc4d2e40db95ad8db297603c3adc916b92d0271f61f64cc2c9260d0640c378d7983beb02a5d7ca02ef661711f552ec64df0a28964fa5084b263efd21b80e1400ee19aea5841eb070e64c6af0f682f7d12acd48eea98179d66805c6672067ffcb8cef378ef256c2221c3b34e21c3623cee070fb0181c86763dd9834c7fade73c96c1ee77365892cb2d793ca5d0f9261d725486bb7683386db2c8f684eab3cbe6563664fe62bb8068a9cdc9ec64170c3c45c18e5fb22b8066bc539585f9cd51cf7de5b744e3d8e4136306d6a3c101e13fe11653b081f366e46101a5d608ed4f582353ad343a5e7b690eab02663fbacbc766e39e662062aad0fc1d5789454235e519401bc34d3d7afd571bb04c1a603eb6f695cc829914aa2a8ffcae1fbe76cda76bb4853b8b331a8fa8ebbd64b3106eb6196eba2d10ee45b2b114eeae5b8589e4f8b474c467730dd1aa449abfb393f3a57d6b7eb1599e106c9e4adee57c45bb5b2bb7f241b2d286e3f6fc97cceed628d2fc789eb997b0ace8e5c67955854455c637cc6481166edb937378ef074da8438d0fd2669a8c4e6be02ffbfb9cf0bf2b4dd548e229c97a768b378778714a489fd773fdaf842dd416abea4d61abc9476815db7445efda7628addc4db1aa4caf56812cfd5eae32be15aeb5fcc51aae85dfa7affc4a0a3bb0abff50b0621b9abf72fe25c16a5361398070517635dbbfc95d6ef5893eb653d067e9850a66f76dda11b3cbcc06d66339bbb981c58a3bce2c69b3bd20c6c5d951b45f94ec2e664f42fb295d9dd93f37b3bfd5d54b1cc195952f12475090ee1cf5c8cafa95d5290415e095ad4945728bd938a8c08a499604db931e905beef6445ff46bc7bf0f47984162ce67b4c0df7e9d1c8f8a6cd9e4167184badb31b4a5b8210d6ae841345d813f5a9a3e36a6951d27910a7a38ae2a99aa0b0606e46e7d9b4d42116727c113bd03be61f4fd9a5b4325012cec872d889668705e5b1c92ffefb4d6bce74c7f06ba57e975c151fd4d9bf9b9febaf7530f7021a2c04a0c2cff4627a707ee52b72557c10f0d066376b6a1996be6a3a3eb3e1efcbb7dccafe1315cca1f3b9559bd47b7a666acccfc291ef59cb67f713e233722fe765bac57a9650a74672823e837ee8e02aadc87a2dfbea4800246b3f12fd93aed0fe026741d5f15c4c4360894f378213a8135f40a186b02511098a25e20b62ef8ea72d5cef785fdb428b12383b8194dec4ad697fc80fe4afb921de1deedb1830ec319466bcabcc276aa9143134423dce6d7e5ba5350302daee571c17b26e267ba67428a0d39ed2ccbf804fd495f865208693c7d1d82052182d2971b1f29808fbdbceb66a0f4b506f0a62772f25665cccac802bc92bf966657f3c1be42bde22ce59121f95aa0270cde6f0e0bc757c1207feb80af4df5d9fc1a7064bdcb84c3884b8dc133d6e1c9e1d43ef39fc2a9aa9857c822c20ab9657072626926db36727ed4fa9d5d522c1739408ddc10b6eca33c814b939b3893cca15bbfd546db5255481beee6a4f213317c581f530c48cbad93846adaee9e74fdb6c8e10d09de7d0ba3d870914be1dde78a3c384d09ccbc70364766d46574f406e8412de13a88547bb570a0d9b91ca5b4bcdfc322cd4077d0b1bc2fd97b642e2e2fde24ca9db496f9a2d42a64000d8e727b13c2b5846400e71292832149597ffeaa35e9d7799079573f20d2d7ce7b93986047656c1dc3a60bbef94c1b06a60dfa9b6652b80595fecaf457eb27889b2e3c701003f2668e02464d2f7614c9d394185702917f3225b20ae48ea1ef484d6617291ee11e4bbfd043efe9163b0fc66b148e000e74847a59233c79f34b6f7f7658d013aa775f8b38e93cf159da9eac9128f70932da402253d8a48e60b38a039732074fd3bec76a37085c2a927984f794004791f7bc1771912c158fa31b8860df34273b6216c256b16c5f423822c0603b0c1f07b87c533699451d64a7134f4732728b3249dc4f06b2a7983353b98c462d7242fa1c9d1cade7629d9d1a301cf560beed10b0a147fc67bf3a703ef628104cbda2213de6e9219b7ccc46ac8becbcda91f4dc0fe0fc88e509f0d57e015c3de63d31e09a929bd5db139da998cb23dad52d1c69f9532ebfa70081ad0b5090e587c22eb40073ee9c54aa551d4a16af42b9cd5c0551337160bdfbe9af4033d0395d2106394e13a85f4e4c26a9df942bb4f9d3d31de11ced6bfe257fafbe170721d3d6678c6597c500f03c895e8e98121dcb5e3ffc455dba77fbc25d2a2e1d9341b15f28fe3077ba626461b66e8af665b6c6ffe9d94a8730f6945ef36c9b2f711914b593734eb1686ed234b109724473dabecb4ebf32f96cc55c5ac09e7715079ae8e9e25365f64bf6912de3e4cd47d6c081dea5f1c8b1c8978c47081b41a759466c7ea34c90e6b0bd71ffb2a7f792bb7a0be291897f4e13ec2da0974d966776b2512e0a3b968d6586d2fe278e2b15a90660b2131cb7bb0bdf5457380559c34a9a206961939dbf601c501f3364169ce26544a8a767c2aa42344096acd082b45bd9e689e1c6cb3ec028fae19e3a42c5ca3cb03a138f857a08f8c21a179c87902f94639c3d406a88d11c8159239fa29443e5bf668a55e9d874109ebcdd316b35561cc360fb454376ab7bb8bc4154dbbec2e179268602649c17ac4d7187c4bc6414a399a7c01fd689387b058106d4c3bac8a4b688736402df21bd6e484c140021c4f446073410878a4253775bc594505d0246f785782764ce8ad48e7782e33739a1ce16619c10f28c23a46760efc1c64482807e24e1f5b417001ff47d94b0e7b06779923d42f68a2e88aef9bd40819720f35b74d315b8c2fbf575e4d0b16f546427f7c2c85747c722a3af56bf85d63684de95457e827fecd67a9342e52cd6d270bfaae7e3d785b22c3ac90b4d59e398d08f75b4bee58392034f2d6aa9dc092a923390f7eb1f6f2a5f9142d4281594497f00465cb0932e4df4894a78f65aa2c971ad3b2c2d2b53487d342936f6699dc38e622873b7dc75053c9623dac7a835dba7bcb0575571068c22404b2c63dacf0dddf7964d54876bca8cda61dbcb51bfe2d7af8389d5722028baad2335b9871bbda363e070033abb9e10926a78ae466c5da3df4304502b5f99abe024cb7294719e58bb2e7d3002264b7f43fb9bf2e44f7b4c813777de5c221940464d883af5cefa06b6ce5acbc9ad088b3c2ad052b519dfc556dde116eccb031f31465709158eea003d91c8dbb3390a7a94a41bece3c44fef50129c0b853c316cd84c597eb9092273bb2e73d8ec9dbac7b20763cbc35ffab396120bc4a9ef6843e89280aa9e2b1c17dbb8bb80cbde9ad09a4b710a71f6c6b3c0d1874ad7706fbe9ab77aa574d9194749cd2248dc1ea2e9006902230cad0d4b9992cb1c124a67595155288d22b3b51226765a453b50c13987a534a33f7c3f2ed9bd8d9ce50121795f61352ebe937c567ad71b992757904cbb2e82c1b9b63a0251d905e99c656461f598ec706b1c496eb28ff8ca0bec4b82382a3c63719f3b10f3dd5eca0d4ce1d8ea6946bc37f6df8a12daf52edf11eec702ac8ce3224d97812f796416bff47675b7844d3d1ce587e2be5db7c0037402aab09bdfda62e4c962dcbad05a80e6e7576a39afe473be273c295688479978a039ee6dd860959f6a4d1686946125865bed68a50df23c78fd72c9264440a4cedc9f452420554cdc97945c95ecfc58d81f3e5f2f13e8873423e7d5e28b15ca47eadcf9dddb0d9b08dba7edc7790a0d49d148cb657a939cc1c63e44b72e9189ae1bd25fe549417be466ef18a393734f8ff93bc6c9f5d8c368796d50d1e189d5deb9c8954e12c62edc265313fea488e3cbd5fb6cc5295cee2eeb4ebd2d20f97f2e43d644939c5f3e96312da50959d93ba2ebdb165ca5e773269a077318bc0c08146b701a85d5c1b84cfd03694cd5d6814004e3d29faa5800b93be557226ff8346446f6f5c1243f5c52c5f6d9417fdc25bb855e9eeb2a3c39116beb7abfd09beb96d254bb963a4ef3e9bc0c665f31bbcdda8040017d48d26a98fdc3ec3f5b94ab4aaecfa48128aa543548bce9a9385b06c651ae428cf5c72c55697a73e22f31ac34e55752efbf1d1cdb8a79f55cb85e487ef7763030f2db8711f2f0f6b7d429eaa83677b767f8c0d4304702c9820c309efd7599f8675ec3d46fb21261dab973ca3fe9eca48f0b4e0d21e177755e5ce128a1be79b60ae0aba9bda2ae929d9f29d189e49be1da1d250cf147ce87bb43ce958e9ee77da1be3665862545dca2e2a695a46f5faa0aa4d1cf9db94b6847db92ac1b1a7d821965e328254f3269d2b4be00c97cab06817ab2ac11d0c5970bf03ad105b8aa58aa2d5faaa3ed414b3a21916bbb67db08cc57ef8ed2ef3ef0bb9be6dd0d7e7760debde277073fbc3b4abf7b8777477665d1be50654f7c7e76ce75e9df2e24cd5eacd615f57d1ce2f2dfed374560920647205a0fdd645076d23ab3eee108f554640c5335a61daed740afe4aa88c628d5d525b09533bc768a447f66ef902ab9b4633ccfae85d6db42dd95e80799f46dc56c0c34370642bd9a06800ff95ca7a9f4565c5c4af528376492f1e50cc650647e59ec69033eab0b46312e830a7c8f693675cca920c64cbc3b1576bd65a5e6a87e43f7f2062bfd86d5f7371cf90d077e839d90b90ef90d13d1295dde404151ead502e14837dcaa84c7fc655392493a75b324942f67399e319f423dda172da365bec07daf1f3220810278753038e15dfe928bb70c0cdaa785bf1deb1162d506b90732338eb4b50353a4590a260c6650b062e2d7e8ce203be4287dbc1db5eaace91a1edb1d6714dff2225842a3e86891682254ddbe4fcae9edbf8a594bb7475abf84a61c9af96f0b050efe0de7dfec0845f938dd684aedd9809e9a85e108bfdc12d4d1c1e2c02e2ab6d1f56783a49c2bd473040afae1160ca19eac1a50f11a0da819c604929ad5d706ddd12dbb46c0ec0af574c91055c1f74ce22e0c361d4e7833ef523b685d20784b4b8a762be476d1c3eb1ce3532807fe197b820bd235fd45fa7b17885478a8f334e4963ffb2b08a1570d7e9ac158d80b5ac4127540de008f232dc801d5a5be7542441a53fac1b5149d760829b6330fb4aca69e4a7c921cdb2cff7785fb9eddbecb407482410b5cbf162656acca35624e74768061d018509a0f86fbe9adc96810f65bed0b1d3820bd7a2177c87d11a97dece44fe45300152151b47a502c197a7677f799d91a0fb1811f12916e0c76b5d11e96fa6519cc31503e4d768d12274249552b7a4784e7c5856b401b054f95590d50422d9990156ed721810c072524e70de4017132bd185b72ae0b5d71c159278dd5f9c469b4cf33c82ec603635485159dc04332b73fb90d9f41733e749ff46f74abab370553c9bc0abaf1955c1e402df19b66b9c22e99db5461c7f09cbc99d778d8b3fa6590895b93244caf49fb1951238021a57f264b88fd6c6a5c119fcc53f078f92546e123c95bb1cfc4d899c262143f5238f7cb65e9fdffa87bb3ee5481ae6bf407e918b6d85c5615888410638cdb247769455444546c7efd19acb90ac198ecfd3cef7bbe73be9b9dad425154b36ab5737276d75c5676084020314b8f884ae8fcdacbf4ec72848864678f4a0a184b24fb9776f6c19bb6acc2fb96ab52d8a1d22f8c7ebcc279fc01d567c181f000d19a9a9a615d7e261b3b8b50f3cdafc26940cfd87c946d3178b0734076848b6c140ef847edcfd1acf7f2dbea1deb5465a06134b1e0172658bcf584e6417cc4244af5127552db7410bd9bcddd992fa71b30a34b625372ce6d23c15b6c223bf379be0bfb63fb753689b686991945ca49fab9fd6316b6e54c3e966df1e176c8ea6cc288781240e600cc3545d8ebc4c0306ebc50a142b58563a8e203c822b51d1672b985e91a914bdf79ab830cef7504b8bb0d854c49e40b43e91fbf29dba97964c8b2122edc517687c38f150d82503373636e6fd955aea58b6f7032665396eb525369b92c9b8a92e4f38ae8f95db0a8d89c719241416008bb7e047241edaebc97c20e948f1c929521cb9fc2569151b4bdeb2b13d034eeb7af29303e05b2a559ef16d4e3554b22328979fe805407345294ae18e76d8b3ca1b541b3e9f4637eb21e4838c99d27f65b6c0c0e99d9c2f665e3eefab47c0a0bc53799af67b85d73191d12c1dfb557c5aa48a3cef9bf0d2489de693fd10e9d124b8633db26bdf3c212035a662a90cd2ea620c1580f76e4ff515f4bc4ab6b100a832ac144d91f3eb656b784ad6c1015e6e8a5b3b273988494cc92dbcd9eb0760a8bf147a7cb5c0ac7901be6e7ae312a600494334fd0eb1fa1269e608811349875f6a8e51c63eacdf8b8223ba68b9ca1e313609fdd66fefce5c64c0ffdfb7063669f5f85758b0caa6c262acd5e1efa9ac107f5cfa3834e520f48fb8bd4618152aee27c566639bec929fcb45ef009b7ef0c52a314d2ab0f7c22f01abf2d9bd6f5915b0184eca75d3e936278926be3cc0d607fa573b1a7233b326bf965d87b088966cc5aca746f413c208588c8f99cc7cbad7d777faaa51df566d2fbcbde3e67c1df85e688a2ffe979f12ec47b8dce647b219b85f5f1e706dd197fa62ad0f024f9fa4f0e1ed1519940f496a8cadd742b64cf2877171022ca6702017d9211d42ef200fc59b6f4c24a95cb4a0665e6087b4703d3308b037ecf2333584a462606954faa173b91b96c59f9d33a4c4f19cb97abcf5c136ffc36af9fe4eadae45ab07db3b3cb2146a6fbeaec6abb8847dcfc6f1c21486086a85ecada15914989200768749352dc837954e3cc687ec631a1ef571a9de894a40f518b5e09370ef202c4a5ca4e4788a9c947d3f46f4713a7afd54974bf72412c4de7dcffe1de4f422b87fbf674642854ca713c77b3b2933a762e141c7527226d5e2051b80abd7e45efc36e2d5d92bcc79b3dd307869749556085daa988470cb1956be23515522d380666b24d5c70564d3596b9f99f015f67b047cc3ed181329cbb471de82448bd3ecdd8cc603f6e1781849ac95cccbb847f4812ae58387260e8c47fb32bb609f283cc058d9eb7ba055718bbb210038503e79420dbdfd4ec54ab845fc84fc850d9aa3effe2a02c8033c0c1b355a1f9748ef467c28b6c9cae99a1b0b6269f32bb416a02f511539a9c293f3e69dafa9a6e48d88bbeb6f95c6133ea18ede587dd00feee6ce17c90b0d8a2b0df2ed10630fbdd82ee394935b507c11e0fcaba180a4b690f3b73cb34ef29a28325f54e65ed310e8be30d098126adf83ffc65a5cadc41762adc735124e6ae75ea34c927b33efde1887c4502a750eb0149285556a955ea0853736a8ff83df8a051f7a74eaec203075d896392c61e09904dfe5c21112cec29727f5ce8728490a822b37471d59e0bfb1927b13e2e4f844741d1be6860524a0610fa6a7432d98f3ce6850e8c746a7f43fecb13ec5072e3d396641665201d49322aae0c1aa513f2a079c24b94619d4b4648c2dbe460ec91181de94e66279c2d7a7cc259f3dc0937d602e0b763aed7a063ce36abc79ec6d23ca5d665df97e90fce8d3ea42e55db60a457902d6e22d59ea76331bcd386480cfac7f4774778896cc6b2bc93a9b1c7400a1a14d076c2835d3049ba0d8e46dac2264dcd8d3e2fdff8b68f3756a36f2fecdcfff6c2aaa69607bbec883b3b3dd1492bb87c777552ab4f1c0daf6557dc0b323707c3fc5038c22388fb9ee04b03afa8ff0e819f631924a06de13d349b56b92329cc3f216720657e30f65b7aceed71683b6218a91ef612651cc48cb84b72a1ea426ddc134813d9a56bf09c5b45cda4cfea80bd94f9c3bc459d17a14956150def968e14f3764a6dde8f9224edd3c0ddd57be59912ca69d77be58c39ac7fde7be9767da8d04219ddd6f7a04a65256694f6303da836d4badd2eaeff17d6349e3fb51f5d77ce13c38aeac4b9345b030140af73a600524ec02ce1bfe84a254615c267f5d26a5101cb2bc9dd92822c2bf42aaf42e5ba05156af14d85baa3a9eb8180a6d0504e916206b9ac9d61573543fb3cbd8dc2f41ec9d16eba5bc2555343ec27f55643b81eaf5b9dda99935a3d9ee6f27ff65a55b43d4ce674d03facfef14d065db5ab9979dac50014c2ec452919ac912946752765a085a28274cdda869a974cdd2ec5cad08071b581a485287a0330f75e56bb29d4becd34d5440539afa97ca350dd7f689414ce45d6a9ab2d76cdfa5e51da749d392e3977bab5058808e74c1b50bf985a773407fba97e52e8318298a73980c5930fbc4ba667ad2cac5c3756881712cd98fdd05c14082efddf46fad0e244b9df07ca305ba1ccd589050cab410bd1986121a20d352c9a4e6b5c5b93b84c0c97078a6dbd70bd0a7d666c2cbc8170ba5bf632073277c9dd9f36e4f052d6aba9d2fd49f3f4e1ae1010b811576e7ab8c74dc329df445999aa2db54f3eedf25da3c41f6ca1ee56955cfed7fec8cab52bd4cb76543e3360e62eb2ceffdd72f8e7bb2bf5202b5895843ded08a747e7d64367ac8fbb89b048133561278404853604604cd8bb3456c500079b70ffdd5655273ac485fbfd20934b62ffb27b19ac97fd30f5f2e03dd130034d100e423115e600d4e71dcdb58394e70e3180091f68b12e2a57f6121914fc716c54aebdc29add9c35e299377af3c33732c0eedece45b0c5706d98d4830621807a913a26767e67875b593e7334363805573308d709c249fd29e1c8e4dd70b557aa2d47dfd6593ac717ebd95b7428ed6fab787962e7ea13c13890c5ab1e5fbedde40a2791f55baca989500f5433c2809f3cf9bd8b28c906fee542628ae74385e5ef9043605bddddffc0a5995b4a49e6d2bc0c47d8a12c95c8edd9e767ef5ae904aa3e43e15fe4f5ac42449908a9c91662744f5319c6e7a437324e74788cd3dd684bf20374621cd135ecc14975d52f6705bf248fb9c26ec875e79295c63ff05a2ba1dff5236a9017871c0989fe75d82e11fb7860d6773634938950c82a318a69468fda28eb9ccb72843343e721a5b62b24bd5231a17aa8b67823804b48f91214156250746fab3f9b2573bda1f845fb4252d133162a94d12b850caa0d79915f56bb4885e223eab984e0a95d6f657e5f6548bfc40e8274b0d688aed84db667e2c3775693e77488ebd7a321da5f3353b98474a87235350327c9e870502cb93ac817741244c5bcee2d4e4d00388d0f546f34eca676bffba5fb96cf617b15ea63db3abfc01f7d51bd914eb07d83dcb52b8fa4a18d89af4e1df403ab5318c57e3b5dfb835836bbd685233969fdcbe0aa8f1ae12f38d6c5f77f2ac742e64083360ea7ff6ed18bce2df40b3d5ec9417118bbf57dbc86c239a979c9ca8bf9842bed67e4e7f7aa7f30fe74d487286c185590cdab0db19710c923a3651b138b037d246c502fb98bf9159903b6ca0b7eccbc90a17cfb528913e3513048c498e47b1b154f1ebc1c7161a49fa7038859a6442627c7b44ef8310b2a6b7c3ca250a85fd916cf3014ac906bc37ec9b74502266b702fc5a061755639f36b71b033fd5c389b0bbaa90d404ec6dd633eae6241e559916ae29be10fb964efda51b4c5f8188a8c327ec68ff9b5b9b8892b2ceed836610f558d918d50dafb8c1a45f7245711012df5db40c318b7f077b80536edd706598dc38ecadda72289b2c6f3f5b9df1d612fd4eca77849e60cc2db59ccf8b63a30b87ab755789da5245cb0857468aeacbefe5d47729a70938bf69e06eb59bfe9ecb6fc2cac930c6e7327a29365d5e9db29ad2e00b3deb8542b0a8ed206d192e50a0ca70de93342497a703fb0b7efdf26e42b217d64f4c053f0bd56d4e65ad1fe5f6b45d3fe8d808fa20e720aae924f9f394bd0eb0dac805089361c513a88b765575bfa99abbced054a498de47a29697cc8f8abad174dd4a3bfd49f5bb56f35a4a8b97e3df651429aae77d7b716287dd22eee3a64d070c689a628bb3a0f7e56d8912e9a1864ba56ab094192ccce9d19726752bb9bb6fd13e730d2fb7842cc8076504196037fab4e12f9b2c31971db5b4f9c594c9fd355705a14f9d374abd7fbe0463a794e8ff824228fa50a24e7f8daad964ec5651e3f7de9f301db2d1d32aea0734213dc427ac089e4881ca0e7e1f5d2b3902ffbde38df385c22b52dd7b81d9a5b10a3fe50abab6fcdbfd2b3b02b2abf8af2ab0a37582fb579ba84468f737865a1803da773c3211c026c1273708ab656728b13a965a29e304bf538110abd7a2cb76c223326064c502e3c8794f2a82259cc71156381a3d2168d4836e4ba863e94104ea7ec9e512801e23cb5b212978f042565e3ed27ed8c16e5c68d0e521736ee4f78592a735fae64227581aeaedd59edd0b3f6818a75d6a9e8f6026bb9c4f23c52346af448c47c83f4f41eddfb9ca83ea55bc70f09f1f20977474cf3e3db20811762460ec3f15d12f79039496d0d1f1731253d0ce6f47972ef9da91123146505ba4acd15ce63091424cf1e2448e676ad48a692fae95d26ab23c9f61388e315e7182840e47ba23f792c3b62fc30d62aadeb4ba5835583a713a752c3a7f0c051420294e5cc774ddebc26af05e75a9641eb648b896f1e935ca9e81c7589931838088335d5635b0b1c27094ccfe10e7fbd46edecab74ea0086f0ca1965d4cfffb51756b0ebe540209a4b85cc391ad81d68cade83d8ce25e297d600c4d5700bc31dfe3e7fbfcc110e87e790ebb600c9cdf8163e2d36d2ce8f76d29d7e4473af542bc815a7e9151fe4fd4dc5ac99f588ab05b850000d2dd94145ebacf87afa27511cb6d42683d7280780d63942cb897ee9f392de51858a84fe4cc6851198a3fe761215be9d0249796bdac57b8aaf8230c671cd7c3608f5a707a209b188f8a74bdaa009f29b730e1a73f8938a7cedd98142e036f9e5d1753cfa397bb26fdee49e5c99f7b09c09a0dbf6157e4cb7d047ceefe29e9581fb2b0b5ab17e84ccb511b9895ef5dc36b9128428fcae159360463655d24008f44eaf147212132808cdd3136d3444f29ec4e5ffabf4ff3fed15c0e0c865355e037b21bfb554a357e735e102daabec09f72ede33394f3bbfd155249b47c65058d2d82040a96ab205f4d9a5acf1ca228804d596b4f5f612e6ca38b8296fa4d85b48511e3166ed4a5670ce0dfc105450b3b995d9359e0398f63bb1c0b13dda005ac03bbed3619d9a0854c3b70146f8abc1838d4967daadc1769d990e6aab76b8f63940f8db03b29998725e905aa83613002277d2eba4278cfa68c01cf65ab0bf4a9fe5b170c8392150646af5d05d13b3843e2bafdacfaf4aa64d7a666b63e0bfe019b13ac7e0ff04118591c5148372ee22c9bb1de72f111a0a72c5aebf0c2f61928d966f81cb965a7cf523ce097738d19b80107764d37da42ac7fb4672f9e573374edbfe20b2d1b9c47ee8d0776bf9901d4a622e1966cbdde3ef04b077831265b505e45b75da187d0ddb5a42eea6974025195451bb300683d233d7c50ce6a0de7fee6255a2f079d8811df20aff5efaef8d6f77f180913e38b0e4d55789bf4ffb026e01942f67ffb53f10a9acfe820e472ef821e56ddc8b1553a05501a7e6756b88afae484d5181e49799f89f85dfd75554ea02257594fb7f6a9fab83b960d42b8d737784d6fdbaa74119f90d7aa3404de1a32c01e56090104bf3fbee467f72b4719a30c50f099ffd09387604f76471c5cb6ba7c6c1fd1a322b240fb5ae2bb584f5723c41146f895164b205b0ed70d335514645cde6bfcd3448f7b0cc657ef3a40f78d2bd000e9aebd09eca504b5d2b87f1f40ec4546e7d75daf4a8f775891e32930119fa623823c7a06aa8f681d95a106a1cef11947c0e40c8e06e417e50a922cc508208f38e258072c7109083161c08bed53d9ca5e3503cbee841fa1fb63f4728c8b74238554690becf7fe6989dc181bdea6431a99719ee1b9ef86ba04cbc2df9eb9af6c1b732d563c07cf47b34386c245cc07d2eca6fcc50d430e54ec509a601acc1c60c9943737ec636f7eb411e66303d4a07889544ff6a0b87aa467c8b3cd77b39d55c1d27c698ad167d8ed312d867805ddc65303dd262bbb4447b62871dea9e4a566e34d5131a46ce4dba8bf9a0b30e58989b2af79cff9e9523b77fb9e38f55daf3a353d546062b6f0f3d93ee9ec55842175a5bc99db24f5c47401feaf4a1aabe14316dbde5dedc4a648b251236c3f684b48b59e1b858dc6a1786f0aa5404aadaa01b1be37593bfde56a7dbc607d0290d698efb655da1f6750aa12b1e71d60ce3ea594ea28fe9c41276da902d0172b8a01265789f4af5108b6b8263a00d02c55a0e6f63d8695b60d6e40d932e70803e59c28ecdf329b2923e55e2eb88500770db5ee78ef05dd2265d03845ec3cd2a55269c37d4dc6a38d02e4cee617d8e386983cabc55a49ab86ddcf50ad755e748d1aee149c3f4b291b012d5a5c46b97b0c85e01273eac45a9827847d6d7e891ba5d3a322e0de7338ce6780190730fa27ad1522b61537eeb2610765c32c2f6350e3b435e4c161c0df051273f9c2e288fd830919e56bfb83c6617599bdfa8350777bee9926db8b9b8dc6f801f65c1adcf17698f54cd4489fbeee2f2803b13f0e5b385996a8227337d83be5142eddeb1527ccdea10b1038a60e37c9ba0b42fec7075768796c88483310c29210655207d380b60c72d9b5c1c176198db58273b5e58e3e25c60f5a53f0e883e37ab381419ad70aa4d78a2f767cb2d6cdacc114a3d1e7786d75adcb4115350e42683a7e39dcc238d4ae408e534401ce40548300a9119f23685eb6e42871809a0f61a7293a4062e135e0901c1f7450d7b70b366b51466c16089640f82a2321b1229dd833a9ef96eac297e7cbb6a116dced711c58d2383836653aa6eb4d9ae6fd25d6b0bfadc81c938a7e4341d8002033813cf8a6b371d613bdb1a442954a32a3e796d02c6ed07b2b4e4d3f1c82b084aea33a08c8c2d236d55f2865a67cdbb69ce303fa0df48b5b8e185563714aa626a7eb6b225262f0478be62374f6d8b174514f0b8655c017264f7295d4a44e8f16883bf13121466639b37320d7ab9d1aa460e9583aa311c305ece1215e623a01378b3a5f0aad882f479e07330e4959ada97d8d181515bed9870919640823e38ad82209fd7b2d685634c19939f6b088d10352c8a477e000c615634d523d97e5eeb853eb4d06fb7bd872bb84d25d7ea03e905ff419727c26a489cc0db5abaa3a2c7af3969fa1a27883dc0aa214f6fb49e28c909d5f0a9e6fa27a87024d112f6c36a837d4f795111bb16517e39e33ae0b914ea7e16f5709d25d453ff8cf673dc6a1f2a58fb3fceb5bd8ab31368e2df11ac013d03fd7729e9ff9c8d40ce49a5cb200916210e8b4d9f38add32690218e23d8e9f9d789b35c6feba95155fa25ecc76655c16b600bfb2db544f5e83c2c1ee08db084ba65679923dc3fcbb7b34ed641c036bde46df38976d2ff674da6ffe591540f27dd7a3a788db63a8fe4fa901bd6690d9cdd94b8af987d042fa8f423acb7708dccd93d60af27e41e9cc033a87c356fc39399f6e11ea1eeb22756c347789200b714436b7a8dbb960ee05815593fda7a2a865fc19b8e73930382dfdb27bbba37ac189414ab66753ba3203ec8a0430914439f72066d31afdb1957f0967ef5c4cd30a05f1d6b59b7335a5f55a39f07e276b8a09f5d7b55b7591371c4b02b1bc84b19a727e0235cf81c875cd7534dcb7b531781791fd81d833b2ed685d888a9e76a0bf17a57c889391e1112aaace17d2bed7ae8c2099ca4eeac8eb4e9004dbbe90ba6dad3823f67e04c8e788dedcd3ccb2b7b4dd7e2aa7f8e6ec71c8dd2019cc66da127cb92750ef29de8a913df5c4d73bedb5d5608904ac84e70c6f7b39db091cffb155ecdc5e1a879f9288fb47f90e1b418235b418a4f18393c0be17528cb732b7748407d6552efd19eb83356266922be2922e664994dd31d6ef703febca4782fe13fa98f10742e2bc2937ca6efbe22a67899021769db2cea66c8eda8c2294a75f2772c812c5ae597dbd516ea6edf41f1d582fbd0aac873164cbbc2f1b64f042e5ca19eda78e9f51445fdc0bb60ec077b436fc4fb31925bfe7a3755396eed4426fcfd7eaa386c79c87d33cf045a5be9ef8f59c36edaf089bfae9e7b6107b2c6dfd6a78a80fcfa0dfea23905947cdfd06f3925a5cceeb7f98bce9404a9ea77f98b926ea3c25f4c7dead9a8effb3c7b3edde2f423ce40e49199fb8a37ac27ec868c8bbf2e7dc52eae2ded59311669e7b936891483740d64e1bb74e42d3a634d91852954bf5bbb92b8f7999b2ced2bbd9e6455511dd644a263ef8c3d7164f6e89d956f89cf635fae61950eca8ea8abd496d92a11756561ddf8b4e69d176c1e31474dcb6bc2343eecce8a15bb74474704b657be62ac664a7f0b9f23923153c90e37b744fc341ed521dc229171d162bacd543f6027cbb3cf7a082a5c46cba60d56846d33f38ba91b048d3d662da14bad7b0cd48655031bbe4adc1ec910cd231f5f5bdc1b2ba76855fa88c3209e954e45f5a9a3562da2f81dd4d897bb4345d67b427f3dbfa797c5a0fc2aecbeaea4f455b9932ebe03afb5a3afcafbf48b137f51f555b92585d5aff117759fb803fa8c2962377d020ee91bfcb9e5a782dfeeb7f973c75774242d906e383a8065f2795f6599056ee3294d43240f4ca0109e48915dcb1d57e7947c9cc60b048780d46010d54eaaa81ab1ba3ecd51ae1f9fc2deaaaeee28640d9cdece13df389da59bca717ce8e044a33712de53f05838ce2ca783c8e2737a59ef65312b4aee7a934338e14c5d91ddc283bd67074ac34def9e51325ce568397baaed1d058f7d59677c0e7e927d244cd48f7da9783955922a5f562f2eafd2dafb3896d8c410703aeaee6d5e48bcd557ace0644f7fa1c9e2efbf746bab194b4993572d7f3f7da2f3628ecc47b213ec9334cf698451ebd773763eed9d8b840ecdf49c752b6ad9b00b104495df0feb56c9cae7fea787ef505889b96a5ca21c1885f3d6bad5f98c980beb2e79a68f1a064c178ad1f1991d9c3b466848b5c4c4d47343501366767b3a55976885ba569a4e5e5b9fb9fb337cd1e3c13ccf9d1871220fcad41c5feafb8f1599a975813cf1515aad709e23a559d6f8db7a45660ae24236f8db6645f24942a09233a975fd496aa207c6afc35d2a59f97a899886dbd99a9b86ad55ff49dab1c5efcd4c2b59161f655261d62273974d3e63528cb78449ab2ab2baec69ad7c4294e3bf3f615eb1f4e5b4bcd0d1d03c5e7434febd9965b1a327ddd16a833c60cfdb6237b7b275ee26e539021983e14ddbf93c688b3469670dab604a99ed8c2ea40fb4287304ebeeb51045ca24ccbaf89a21c49dd3fa4421443b7f780f0124fc9fb6257413a906916f509d2c947aee03a9c165274219f2f4fbbedf4d7bfaf2f4396ddaf956c5ec346d5dd135c9d8076a7492f4dca8469994a36c219268ed0532a61fecbb752db5bdfa1e7f76f15978b56a0f71f62acef57ac0cbbfc167d4296278865bc299b2a6865dae4baaf29ea4e6baf1fbdb54a73d7d3901f01924c7bae6b4691706c5f87da1552b567e507c3d28b3a6adabde279cad3970a6e7d3487c7279ef81392a8ef83be1cf137cbe6f58edd9df73f28642bd75401a39e976381b0f0648286770c14dba2cff674ff978f34996a024bdc77caaafa767f1b355a889def26f9b29954427b2c5f4605dd053072ca4a6019f39d1fcac49a40bb055a5fd8292e8cf2658244988ea6eed9ecb9f42557a2ccf4b33569ce9096e248f26b9b910f23de97709480f57930594d12e6583ab85aa36388703c6191495a17f4424e5a8c131f1b541f51c8e6f9540f33049e25ece8db7dfe58e1431e6230508b29a837f9836690ba78b183649e97ec4649c5df8ba863542541c35812aa82dbc3acf7863092857fdb9ec09c7b0a0c89e72bf11dd995f689112ca8835db9c22abe0392a588cac69229e81382ff9c517e60a2ec1850b10ce489e0317e410ef12b4d7c2c4aa5acae00887e26a097db71af342e6f7e6927b41087396c30a1672a6c69b368a1ab6c7736a833aa8176ca9035adcf2df67fa7776b0afcd6019949dec7b4eb529cbe746bfb743394cf04a3ff33e83dbd90b2eee6144ad9924491ff62ceeffb1908db34702ce6bbccb6768549122fa4a998476dbacf01acd5632154c4732960539d5fd5dc0342b565e4e2d9a2ca7525b66ac6b0a2abfb7d1aa645e49a14288a8b65a35edf2199598542dbfa86a31c3e1986b6899ae1ad80e3519d67b797f023b11ecdb25736785e6799fa8a70653d0ee3b05b1f5478bad087c78eeba6d027f77030932930d86c4dab52dc8529c7f9f067f3fad524428d29c07e3e69f4c16bd0af5467e1c14942c649b6f6a2d535b46f9720e0ffb278b1d92423349855c1f40d6ebb71cbc0fdef742c37caca042f1cfb4210b97558f4c9171ec21d768cbc01f14cb7016960190332fdc151b88b8bcb9fe6b03bdc46236dcec8682aeea0512287699083ee39df848edda817ce479c7412862e556816ae1842d08d9994c07cbc58c50ec774298b8ca902d6628fd8014db9828a4aaa25c632ec98f3f8166d49655065041dfb1ad5597bf3ed2f1d09615e472518987b7adf351dc0422e57b85cf169259160aad98d9ffbdac74b583c3281c337ad9581a417e3baa2f928f9f41874fd30e24533777d5677afee1e07b0f4f2c2880a2e8d4379ce3c458c7fcf38e7faed2cf5602cacf77f4ed01e39434e98c6aab4e13cc3d7718d55393f12560963ef7f175dc3ca74256ac7d93a1875315af0753809933b275d0bc7678e12098f049a42f9d19e8ff1df596c2490ef0385fa902f00d77bf2e10c1b2e74ff9e4ad0512bf61fd1e5413c2f33d9c67d66fcec2ca6ee5bb0a6a08097437b4aa2d50eb2128f44e15f3ea8d102cde29fde4336e22e1a884517aa7bdfeb9a041520babd944aa20bede36715a6c70315d36142a3177d02a3fe924561f14ecffa407bc277ccf8e1f10e29ec8ac63e8318defdb8b7e3c66178f8415586b3ce01dcb32eb35156aa82a56fb270001b2a6d221d82a2d5eb4c5d8de65670f853ac1d8f98e0cc6773d311a2ce512157b66d83abf0eee5edfd6b76833b3527cc01c0ff8246054f119fee501733ce01d0ff084eaf6ca4ad877e7d4e257c6dc1feda652e7b1d80bb5b6f2db410cab3c90c4c99e28bda8b538adffa291cd7a854b9760c6da9a11f75d9bd918ef6c555000264343cbec6b703667eb20d5ea8cecaaf59c3cb696ea0227a1ff83fb819d2c6de44c692551ffca3efb61a3431938037649e8af4f14f551a1753a7b13d2aeaceae7dd3b4a77beee957efab29e1f0915ca9fdc19c5ee85cde2afba1fb50eb4a443b17b07e2f61b6eadfa545d386be279d158d1ce9af4d6b150773ab07039008da39557b07671610fbc6a7f49fe364fa8ad793170bac3c6f5e6781d3cd72e9aab751049300fd7e6410cdbd79be30df4deb868ee44513975304fdfc72d1de6eef5e678017e1a17cd1de868720c7359ca85f382dfcddb52c53a63c3c774b238862aed7a17c5a227286bde7652b4f5291b4925f4fe9fe9570fc99a8c3640153c906bf224f7f37cf9315960ad8b9a795499c632ee9d81e88e146ab69805ac0b6ceaf70efdd5552311921428ae7c44e8fa6d55b3d10791bec64a2e96c0d9596c9175b542221ef259b805e7811eb2aa31966bfaa1c29d4cc7632a993c7729c33df91cbe961da45284240af9c58c7bbc579ddee3fdc84a487acd50585d8926fc87420b5db410e29582eb4d7429f5df8d1567235379fb43686a070215ccc22155412e0e27810f0fbc74b844f6e9123ed5111f1928173b93e0a8aa557318e69b2a73869f73dcdc646b9747c2ced847d6330a42b8fdeeb6e0c3dfcc3475d1096ad738ef6ab2ba8a3fee6714a2b0ad9371a54ab7794e8cf9314a656451aa626eb218ae90d973a0ba05fb84d7d8d327efa1ba5379588774cd07415148b11294e9bb88660ea810f5d6259c6f7553fc51bc33ea79a5071dbd063d526304b825b034aee5023efe426c61708e00420b7a868b4f073cd5a27ff8162c8564851e0d47c740d8a1da93dfc17be8ae72d59da755af7ca66a6356544ecf77430057bbb3f4cf275119bc3906e5ce0f9167f5740492e3289cf60a2bd6d865f53b6aa18e54d02606218037af5ee52b4a50f45e72a7f7f2dc1faa645e749893cdbc962de4bf004a77fa82a247f27ca8871dd5fff6c4099d18d5fadffa406500783c211bdca14ed54bc86725283903a54864e7ddceccdc87f4f13aab4eddfb2ffc932306f7ad93cac1d498194a8d7012503f38873a326b977b0a953c37d7da9dfc4cee840e59de2f4d587c563d229b9796bbd788ccdc9714671783eccb3d4350b844f57131f047f26a0c0d693cb0f7bbb2cefbb947862c954cfee9f490fb6560c8e5bac7bfb43bf99bbcd4f032f3cef11a55fdc339ae9cc821601e83b25cd440cb7df24ca94856c987d073b70695a68dd67578ea1a75a641af1a5ccd44f4b84547cb9a2b016b0d0eee5abaea88c8ce50e1bd82797e2e9f1b6e12e670b108e0c815771e1e3fe8af0e3d861161f0fae10a809caf077ec6be91b3b0d27b0e96bf927998970e39c90614ddbd1b2ddaf462bdd46c4bade4bb0d5761c0096f8bfe1d2ef15427e9417690657af7c5df37e57e9b2a74f656d5b78527a95cf230f572823e476d460b4fe83cffeca254d34ddb190ae563600e9cec93f64ce7610887bb27e81554b491398d80240b97e5b5128dded3e6d6d76d7a433b241abcb316a19c98e2f2a6eba703a69c29d5633c9280e9b941aa9958ce8c083ed267dc8ce82b472d1bbd2c2896c830c95547ceb055cb3a92a1621998d77fa6ef15a9e383de6e9f23ab43181a09ac4387b324b2049f758583db69dfef1772419e41934316ea2264a1b672be444c23c18c4ff468cb297c48af11c347ac97cc024cb9a30b851becb9596d9f93bb620b7180846fda7f9e33754fb144cac35146831c0a56f1150ad884d6756cc25f4fd71c76f8f6dbe98afc0ef512d40bc90e042dc6858494d8308be546cd4a94d93095c9529eab54adbd76b6a23232e8d8a887dc73d9c291faf28ab32a86323f58e32f39203827b17626ba1073991ef7169d5b492c296b7c2599ea7bb0c1dff7b60dd814f268703a2a27f5f6fa5c568d44439d2bba9bd9ba33ce0108596db8a1ae26df7ee91c576a1995169d4299563ad20eb9bcfeeb8c56eba3f59275ce11e67d404988aa293979352e24af1ed7f265d9a1fa8cc9e962402c3d7636d512210f923c7e2e5186f6046546d7b62875afca16ccf12db783c5cf29d335e20a71283f8529fb4e9d7cfa5c2f927ba2430de42d6a654232ca35f634db6d53f2349a7d50681552706c42fd7396b6dee89cc10862d274a957512971fa3a9f0a89793925040b2206a07306efb40335c0213540b8e74f2cf0c500ddd2687694f99aa9c6ce54d60d5aec9ff75c6189b13c15761902141d5a412e67458f34ab8b18b4ab8573ae1565752a0eb0cfdcc2f202caa8f9b259722239f2acc66884b25e26cb12186b928e9d47c7fcbed72ddf04042edb2808171e48275137bb5acee699f7cf2f6ffcd8e5fd467eacfbe990cce4c38f8bc63a982eef680bb587ac35b9dbce1593608557e5abf52517522b303b28dabfc8eec7da7d8d80fbedac3ae7cf16aa05dd0381928a529be15f0699b4116ec292a8499c38625cefe77ea41cc7dee170adaaa0c6f5310c78bc46ea3006c18950a8b462bf2e4898dabd7674ada5c38a4b850ed75b0c96b2b0dc9a40e11f4c6955abb8d7c8ed703b042dac7f7bf1245ba8dbbebece115e28d3a32b0b2bd1561de350ec5015e273f150b44f721aa2234129ef48bf79da9289edece5ceb05143dd46a4d0db2ef375fa1f45b73ad11ea883ac018cdb4bae5c9c39d9e962eb2049397e7003d2f18693a36173bc42e367cc318acf89ad81712ca14e2a86d0758e259c4fa0aac8595814d88d7a5a9f53b1191828679d8676ee968be064f57c8bdd48d7d9c7684111e57785f46875cf3caece11612f6f7162168513f3c1f2e7397f3eb599398dfeaa85aa15bef8f9866b0fb085b755adb898fc6d3b41ab9801bd49ada6de6374432ba08124700f49e1eaa9f24cca90418413d6502f8ccd8af0144f392a901784d1328c58874a6edd1875a5c56d0f6e5ece38ff479040524984b342319a577acea14e7a4265c4448308d5eecd9b1c6eb20a6533e895c7e2ad17129dcdeb2c03f1e4ea1bd74b7f36648cdfeb0abf2b66cb4e25fc1ffc2f35c4eb45c74d78383b6ee6d2596125befaddbc4a42e8cdc43875430962c8ba70bfff1be376870f4a287b3cd104cd3699a14c6112e7521f43b9b50272f59e731f8d6b41da18ece8df290291d6f65cc35fca1ea0906b8890eb24813b44fb0d43b9dab2e6870691716d4804ddf2b156b590c8b2d51e11e4a2aa27a462bc9fc2b3a023a2763817702e901918991d9e273831e6a40c92aed1600ecef4d3431d8adeb30fe0fd718262c82d1dd51bd9a24e8d235b17e6083b0b9a6c7b6b0ceb14eff30c0651c4c6ba2cf94a25ce8da1676a605cc6b8816b8f070bfea7c191e12288b9b324098ea5266760560f09d953f5ab4c42fd8a53c35866a9a2c3540cec192b61b1cca5908a518bbe560b095e0212f8ef63e4819eb086dca6665408b82a22a492a7c18cbaa712d5057cbf3ba58919070fe92387c4f51e93d6fae787ceed2920b8507bd206dc5bddba23d4579b8c3677b657c58753eb625c42c76b0a7015fd7cc7a91d2f5ae692688597de60a7dd1a09f10638d41ffb75243896f3a005cb42a0b28367071262e226ffec1a0f5aeb72d0a20784c1306807d5e6412b814f6791be96f5b5995dedd0ce44b6120fd48d6ed115eaab81819a5e0ed4e201b11a3cf0a4e856af97efec1d4e84652e3939556aa946f2e5d0fd66b7ecbaa4257f26f493ea5eb358187ac3feaa02d4ea7dca79b9db1aea4f98c6a360048d8493a83eddab715cf715b68d6b5d2e9e275b7db2de108c926f22fcf80c6891f13294e5f7d4f8aed252786ef389bed2df1b88f2bf425c8cd72130c5375c32c23f2f25fcd8e34d08b038da73d6c9ac414e3d9fae4a0186c4b161f36c3072cf3520626617c709126120d5a872646bce906fa4fb75b034e69d8a952a7429b17491cb303d07da445dd55f508145fa38cefa48203d9c2373e5b5f748c681a528ecea2eedc5606bee76fccae382b4d9187c308000c2504be291e85719ce1e8767c4eb3c44286145abd9da42d45d5c13e39a355d632732dcf2ef7906d3bd61e7bcaaea1ffe1f33c601682df31497d167ee8399fb7f2d86b37649c874ea3e88189aac440bfa3e067e1a0aa7b26a47918e1779f9fb2202a9a977dc62a204cb4a7ea579ee6beb6db1456c61bab30a49d865473c3bdd6e518bdac3cde46d81ad38a8b0ed0b8f7f1d1012933d6677e063763d4c7d09f74ed23b5f1a5665f98fa9a0d077debbf87bf6601daa3f1cd7756465bd46bc1b6ca4861acbefc9513f1ed840051c561c043eaab06f2496df3b974b2f986c47b220cdceec8bc4c48a3c3c92ebb7c91ac9f5fc9c502d9047901ef133f95276c4071fa07b285e7d03415d67c794fb851352b88682f73069b30f8faedad081fd942a39041cf0d6c08177d958ee103a37b6f8ded8306b6c746e2ce0c69a4beb7c3c89d10eaf4847854383e0197c2273bbcf4d2e2881a13f16d64219c83ecc1adbe14c3bfed4d8f67b6394da3714764506a5ff2e4867196a35255785d8f0722f1c214a2066673f6efe68f41d22d73ae2c01e1a977946bbf0bbb44bb5b2164cf9e7ad5d7e1656c34c0849c114d4ab418bf1a541ac3d6494abf64dfe937193aef1ade4f4b285e4cdf61cc0a1c3a03f0c92a0717d00c2a2d6143450fd10e984ce1e71de1b6cd02a5660ad43c6ec7dfd052778fa2fe5c54c3a33e057552a28d556157579093167580db9c529e12c37d913320439336b841d97765b2dd8702e08e1ba979df6aaff94fbff2e469a007dfad37ecd85bc8e646c3387c972aa7202b451829380801d11354812452271bdb3cefef7e478f6bf0b07444499f09a42917f3e3c95f3f15198169cd58778ce380220ea97a637731d8e610e801dca27af96b8070a51df2638002f199a1fa78ca15f347df4aefba6cd43eff8af8c86a489272db97cec9855b89e2e2b59f5179d85ae890b0f20f40767b0115f29f16455d86b24eab72d3957b435e090150338a0bc2e01fc2931a7d2c0378ce47013b15647c420d66307a0935dbaf665ba86e1393f1267f9cd0219a4ceac42757fcf21ce5f5fce1975f938a5bab2f7d31a000dba81a64f382bf7866f669f9fd3ed8cc08ebba3cf2a96ed292e68f926062ae12bf63e51bdd80dd9e54b364795ca025122d7e778b5a4097c3b3100d91e140a03eeb3bbaf62641996cd3d56695dd664e5841b7647dc1000a9cbadf20d35bea14e495776220ded650a81d6fc966cae3f72134069d93243f08e70e4d449b667e6d5472e9119a321d1ddf98228946af20039e96c433ac06f363cdeeb63ba4f1d62a874a638952665056626db61d3cf8176e7802bca213daeffb2d796c613ac205ada53795aa96b6b9dd776a630e9b5af163d32ddde1705d5c98e6465c1f6081751e2f473eb87a255ccdb12568bd70c188f4f64025285161374bb1d185b97f7c29e1bd403a5eb282d8d99b0b0a263417b5dd136b0fe540029e356af770707bd5bbfd29d8575e0ee94ae77071ac7b07aa53ba1151f0b0af792e4a8fd64f022d43b6b85c08f2fe3aa55d859c1f8aa2d42017a536f376c0d75b3e5fdaa17e68a8c4782d4555f978b10905174c8a8affc827b1683bb7de79277220ef3caa99dea1abdb9d4d947c5d25aebe5843332c8282b2d87fd811a4d71c35921c7801dcc582fde0afb795cc31e19d4f614663ea92a23f05dca7b8e356a215c9d723946ed0236407f6e2d4904db70febbddee155de85f242fc5383e2be9e0be890e65a699228aad2b42d86e7569d07c79aa5e97b0cb232aabdb2c4a180bc35ee3afeb1bcc46c6a3e0ac399dac02afbbbba306942fdb0716cd0cc83843cc4223314672038446673f4572dd9c11476b04f5a84e52afaae3cc42a1189910a719afd83a566ca38e07d7e9b315cb8034c1a1e6fea8362887f30df3279c29334a6e6a54e671bb28a861c027f91f402f5a86dae30c77aa33a44cd2495de3a8047018b9e5850baf1d81d0baab3927f3d58831dafe3278927443dc06caf56b04306e1dce33714ceda3c15daaf415d156b661d19eabc32cfbb682e361f99a99378307e535e89e6bb526c23ae554a749a34afbcecff699e72c71d413d2e8dd1bfd7f23c35bc8262cafc9c78fe865949ed6abfb7c5674a17c7e4380db903eaebaaa4923ba92958b0b3552ddaec96e89b54cd751c39c9fd8c3860cfd06344f2a916e2b048aafd8af2f654ef8b1bf681a5996c062bd63c6e8f7242cb8c49273edb74ece0fd50e96055905e22da4c1524ff53f39513e9acff9f5b9c42598d36eada85afeb4f056179785739ab8933ae341afe73c0164181ef0b4b739a6e89de2de4fed62afd7575a2528c543a1b07d79fdb2c09ce287f7435870a41e8ab9e6188c29c2049316ce2e3a6bbca08148f072c9c4a736791baddc977660b229f7a3249b057a1992dc8a91ee97c92d90e43d6969a5a50a8ab682fa6f12480bae4e95cfcc2db7ad455e0792feb3eddb0cb9bc294a86396876330429c1d9246d56ecd6749edab7a59b7246964bd400ea36a4409f65ee29ecd953070a4a7a77d5ae0d2a28b289ee6e70dde0aed3b5cbafe2de4b8f19570cef5a5d3b1532de4ddb9705762ee1701dc5d982420af8b792ba293c31ee169e412aa94ba7342e94d809afbb9299b112aa299f2c9cc3486575e9c6f351adca6576627cf2b3bbac0acd953ba3e1a2823b3a593b247807b464bc8a5ebd03ea04b3d34e57a97d316e53b20aed87fb001db0d111d53f18cc97979e067c5b6a578c2901e23bebd324b5d64a9aac2604c657e5ca85af9479ae84ea75309f76e9804726571eb90ec130d3bdd2d2bb086428cfaff02fed8160d9f517bd6fcd7d8a8ddcca52d2d3c06d6444d379a2985f809951b2355082155df4d03150177fc785cacdf7f25409f5c12c1ee0f49f1d356d7abad4bab04f861db64fba88708e040ca30ee4e5a78fc804983510a62066333a2b732153f1dc3eff38166e6cad7c13c2021860e3660931f69353f87a09faa5035e99a9c55f6b14ed7babb3c390e1a49019e119b21ab17a8d44c9a86d6730585b35af16d149a81cbf413af5bd886e8b430a8fa2ce70ef5095877ad9d041f61cadf29b2df3ad26326602832670cdc646dd06ca0be72ad6815d346e9cf8fbe6c9d687967ac2b15b619d368e59080f841d4a2aad7958dd10864e1312f9b94dde868101f4b421212d2263c3972d74611250558263fa01c56f1ed61e3551af5f6da2e3e69be0ce2d08dbde79c318d9eb95caa192c53c169bc2b75bfef6b0b3d8390a35ad73e2b5a66f4b625cd061674e09489c818cfa054549390d4a5a355d80cca9c18620f4d4cbcea11c847609b9c5ad12211c7fa417f7dd2e7d6b8f3af46dff119f3d469c488f5c4788b77dc495f1b4d85ebfcd00094c86a702c2ea62c68c0d3cd16c643bc236ecc69f3ccb197b07898bd3663a7ce5349c2bf91416314e22c351272830416513648e8741792d45ffa46a9486602f2d104af6430b0c938ea5f3c01b48a7bb4ca2d08c973e136a56691fdc24a6bf4ec5d4406158c5eb76432c9d07596f99172a2b30a9b2bdd264503b0d69a07785cefe3ec28c1d168a42be18656092ce5bbadf4b73907883b51b8447b6b07c6029a4426d268575cff26c350368da5c4639a4a354318f64424528ce2d3f2fd50f53d38ef5455abea95c0aba195818f8582b4abfc19e6f311a8574b7d53a8fd52ac6732671289f33d25de118e66c57e0b90b995363c3885fbc120e580975047d3e17b027860db22acd44ae8e7929bf968fc444e6564b36b26a181c6552ad726978840ab68a32900433d4753b2cfcff6d29b85d95b5e8d3fbab48ee1a8c92755aa9f319236632065aad3727c1e8805dcbdbf5cb236155643c4c7bb890eb2925fe54553ca540f09f0e0dd74e322f676b4e66a06f95e0c6bb14bb06a3b56ab29e05f646097ecacf84f2dc2cdfdccc1834abec0a3390ab57085df6796a19b7a3945c51c5c07bd12b52cfdb739975c6a5d45c0257274c3ebbafc7b2f9ca2487ba7460bf31b36596aaa17a99a56be85dd886b93dc89f0a27524d17ad00f94630f28d2e7f8be32caea5cb1aae119f1c88b614e8e8b994fd3da6264615128abe86d8e6c24dc5e444d8b16998f9b56a9735f3ae726a10ffc3bb337eaef9d04089c74c964a76f9391de50a89543557cbb6cd6515e46b8e4d5428a89935ad90a8865531d0bb0a85402ff91dc63997655bf41249d53c56476a34a0ec951d6127e62ae9fd50b4306f59a9a6f10780d08dbee6898a4b8cd83b16f5fe53a70b189a01a369da146f483b1151d990186c005ea0f1a102b9de71a15725af764c7b865cae3925f3e99bde7150b353aeea1135495c54b94649e31f024ae9515cb957aadb05b95865797ee0e267407956d3356c6fcd7ac33e933a33db8ad35ee52587c5e8a4e6a0804eaa3c682d2ee43012c84625a961ddf40a5dae38e504d6fe38eea042ebc8b2323de15da10c2d23c6e10f17a6273de121724e03d99148691b936f46562e7482746dab6b573bc20a55e542c54855149c4ffb060d7f551a103781dca37e61146d0972b9a422023ba9653facd724697c53e1ceeee59de19aef8cbde29dbb3539fcad8aac5c7b9a23d48bae54d73d5d6dcfbf8f849acb6bbdf9e434f1a720cabfa7bafba935bc82b590c51b8a65771737bbf99b575238be6c5f7bf3f42d7489b29e9de5fafc3bbdc5b591c9de228cf273abee7e6a6da7dfa278c36561e0c5ed6efef64fe10448389aa492cffdb3c80d486afaeb4148286344bd80ea42f5fd8b47ea87642bcc4a3b7639fef9d6781dba81ccdf9b5a3717cf3c5f802f2c4bbf418916e25b03982374ff50b877cd865da8b77228fdb32f4ee498fda560e908cfeda4c61edc2a7c6c91c4f3a732ce152cbd8b77aa007e72c8fe517de0f29c9ae7e297fb873895cb83a9a4622ee1b5aa5c9fd73ca3ccdf276a8bab4caa03135e07b9e844c258b3d2661f87ed4a7ac7c82b55c830531f5bee92e053dc1176971093541f4caf594f987f0d27d4e72a1d79bb2d416a6669f0688ae823f816234db73a27845efbebb8946c5f2f288a6fd56473d9bbd07317fe7f20473d5fee79a8635e47ab88904c3fc83352950063be49ed105314de861735140c1a4e672bdb0dbbb045599a7c70856a7efbd1d735c4e4ba3ccf9db5447aee0d1d7a8c0aab55a73963b995d6c01ba8e456c744588175e2eaf2bcd21e780169093b595a737ad9993ce1d3616505ee0f5404d1bf5f35c90ceb434a0fd02b92fc027379972ec7b6d4a8e3d33a2f142a9927ebf4f31657de833592eac0db386dbc55936b372242b252076d6a2f6bfc4358d33fe09b67ae824ae5b9ea4a72ab0f909e1aa38d40322aec80a25f636008a84072bdcb589778ec678acb7fc1ba616b7aa9cf06de82942e37013912505b3edecb03f13e59bb50b143ccf270d960b57e8142fcc83a537b1c393f9c2ce32fe4224446be1e6d83fad9419b3cf8935a81f061c53f1ae97e553555a722ccafc6edb77749050778ca6af8b17e7bf136b6b0b7969ea227f4f833dd3f1509c8a0912e11cad303ae60018e8f40a3fdacdc52edb29af77fbc655e638aeb88bbf9adfe8ea22154b802b6b793dab07560fcf0f6b6764f24eac8f9c8bf8da20046cd944a57ada7e27cadd814a9ced8338815e3759017073701914334ac3d1eb6a5d565dd15a69ae6fe546cabcdf3adcbabf26d71c7b780b578d9010c0324786390e91ed24bec4055d3bfa6cd06f2b83e2303e515448f7afd302d46abd4831047f3e4eb33f59817aeb19e8a4b0f403b7682504d36f87c4f1d55356310f122c5e8a438e9352c5edbe46b93c2b50d2e72d2b0e4f38e7d9e0952d331f234bc44484fe211ba2b42dbe57396f33aa4217f8da97447f96adeb10acd73046347697503ddfd10953e4ebd0dc7626edd3954dcd3133ff6131b5a0c989385a6ce1656ace04e68f667b21e93fff89d82a34779222fa6d5c52961ef2355ae4be1f40f17fa895e37e1c9cafc13645bb0d0ce34445eab1142d3ce9a40e4ac1051a1517b61a622f8a503fe2342bc1e0beb4e035ed79132d7b8c92b701f5a7f89efe919e0d86775c7ca54dee2bdacc27ee85f8bf74213723e5adb6f58b2c2d91611501f754ec171ad93a7d6ea7c5209efb0a1baecb6e48a0fca39a7c0c4a14061e02de0cc19521589da948ad6d7dcb019dac4e7c55aa541b47d733928a80b8e53211fe78d602f52e61f5b2319be80f6a19eb6e0df2a8eccd3126ed0fc9038c27e638ac3bf39cb027696e53c70c354ec9ece3e8391b0baf238055d5042347d62bce3999fbe50a257a569fde4f6ca8a4ab3f0cfc93c86b46107c98282de0fda8ba61d6f0665d3a940f2bb56d770c0559084fac5efaa9d6e6d4437d2ceb8c289e5d4e7749b547f8ae5766a9e7977f6d51cdf5f8dc1808b042f413bd5598e7281a37a064b7d1c215d6750fdc4340022e434eb65b4b79e43dbd15ea6f2e3aebf617ed32977afd64cc7d87adb52583946897395a0aecf2c93352fe37e154e30636c0325d4e30c1f28bc3216d6209ed2452fad3d2dc7bd6a6b1c220ec555c0c3b2912538ffdd4ad3d488712ab04ac891a6cb0642dd3087832b46f7e56771bf920b1289beecc02d3430c85ba2fe3477e7cf360fe5db1ed57914cc045134b5e5880632a3f86aafb79f72cdaf413f985f5c1de61e6b549c54977a084e4c1d8675ef6deec8a82c0145d58bf9f85c43037b6196804188a8adfb521e10b5d75572c38b52c0442e8106b241eab5b7fcc2b10a6c09f78b407265135e254e95f500f2a5f2df71fa7407552bee89fda4945c60afa754da7232b71107ef0840d02d4df427edc20865c7479fbb3e9d1b6efeb3362cbf8e88e4babb90aa431f0214c1e876d34e2bbc98e7694353b877baa7fa69895a4193ce5acfdd64f97233c8f78f7fa3ac0297590f7750ef5e39a36d507ac8ef8d05dcd6b9bd61f64b0c9ff07fc16c19f4fa9e1f7df78d4cb903fc1b0fad47d8f04aff58595c73479416855f5df831d1258743987b0ceb67cc21ca4ace4958bb169c1c3a3e7685cdb5ab3405b44b52ebe8e1abd52d1e34d77301ac3f70809bc31db2ac91ec7c110e505bb941f6e3a48210cbf425d53ad4c79c59936b70f5eb9d1da0c4115c2b0179da079d172814497a5078e458ec0b4d5ca3b591d6e66c8bcfa942bb82c048a6d73441d532e86cccf24e0acbaacc68257f74662857a2310e67bcb4082262463beb557f7991ff1cabf482811075d9256251b32159b00ef624fa473ec95ba58ea9c6e2308feae9e6f7d56b2592490ae92435ef3b81bcd2a89b9abce91bd522f29e1fe4cac79b5092eed8d029d52fdf0f23cb9073888d571f42d1d9e57f774eb283dc2fcd38bb21a04f905dcd8f5c791cb02d318bb8662226a9eed49069334584e5f99e7cb9aabdfe0f5c8817da657d08406f5e9dffeac0bbd065ab77a90c3965ad5ceab2a73a1321e47a4398299009ebc3f9ebbccb0fcd6c6d3ac477b62f2fbd77ba1f97ed271c0beef60aedc3a92d06c5d7e1f68fb69fb9f95a2b55ae4ae1dc8c8bde290ab4d00170531e88fe28261061bbc71801aa11f63263ebe6865c6fcef3516a5430ab2d9b0c8e0e5898cb2cbcbb48069457eacd55de373848a739d89d1bbfefc3af3761f099d6e19cf0f82e9c44a5c63ba7a49084f2a7fd3c7ea2f558d9e56358b02326c2796b16434cdf03e2e902dcb2b89eb66d14e633ba55917eeef7e0a52b9c83d55a7c0bbe927baf3c102600e2945a1d7aa9566f9ad18194a0a32c42c69989c2954bb354b2cbafc20c4d0e73ad2998f52eec8a55b91a3923d049ee3c6264e21df70ab7182113237d1de2637660fd47b1c299df4f970862854ed060ded0df6385bea2ccb45f628503e106aad5206df0fd0f1df992748dd7047a7b5d01f7b3ec70dab858ca5a90732faab66c014a903c9f8c50f350f6c4d44ce4745ed0e7177ea6cfdbffa2cf0fcbefc265657e755f066839402b06e04f57119654f3b5b09301e342ae6544ec3591732a60ec1ac4d2b1c4a4cd07f35b24ef74fd90e67df73ec20832a13f805e3ca849c8187f88d4e73f9cd7eacf1a053117c54935603b5411d4fe767a77922b659a4c3eba3c71713f4acdd8293ea563e4bfcbe4b2851b592d5ffe0f4e765c11c6ec640012c9eb765b68c34a0a51c84b2524268136976c2c1515840886fee7f9f4fe8c993746438934673d623b07adc8a8fc1d2004e87107d980a29ce18a4494da3093cdca7968d37950e1fcaadd461c57aa26abcdb37bfba5eca5fa71aabfe4df6b24c46406a58b3864bb18022a64a304070b3e11b7fbaf2f2828046e6d71b41e7cb6432d61fe613bf4fb5b13097c0cebf49dadd340ae502f4afd7cffc54cddc90dccd44fcaecb546e5abc6a9451bd869a140fef7d1b58547bceab74dc9637c90fb80b6d9e7d62771bd901bfffc850d6242672139e73fdb8bb6305fd85621cdcdba38503ca1ee5e7ec4c9433d65175afd0a2aef116a153f5719129a7b9682537ff966d45887ff0da366980a5dc66ffed12c7484eddbd53b4cf40b76f68bfea40dc7932c7e77360d3de16ea5568c58c99c6e553903f70146659203e87b6f40df666791ca68cd9b33e69a613aeccc27d962683844111871feecda2467af6a6800a97fd24c372d3e94bbf17f124bde34d253db05e4a6cb54acffe7a448babf11e23b04bdffcd75ab4eec3ff8ffcdaa747cfb32c69e9fcfbbf3fd6e7e6edd548db954dc8b737a36c0d39bf333eca20e527cf025e9fba9c7cc5fcdc7900607ffb923e995ef6260a8c6c58afccd42f96e8a50d696aa7c7b9ddfec90ef06876e2543a5d7afc16ad9652be9efa962dab8387d53d323b2c21934fb75c54e6d16fb4efc2dc7e82f0cc84eed322431a5ad29d6d240d50547b7bfcdf3f781e1fca8f39d08807f9be486fa4b0a06ddf594bfc8a5771c08f174d18bedb7a48f976f014bc3cc051d8fb4598597f40b3d20e5cbfc61e5fe6b63e83eacbf8559dc3f4fa972f87c69d53ea5f3fa4ef2f8a93828dfb389feb317cbfae2080b5af75331afe55ba20f288e9f8add568ffff5788692b2f636d2499f7ecece4957f4ab50bdcbdd497ad7e56e2f5e749606f944b4507edb5cadef61ebbf0dd6405881596ca82d5fcb8e98ab509edc5f1350fe4e33de5dc06ac951d57e0aeb630da73df17eaa843325847b750fba42858a534cae6e354f583e872e8bd92107ce0e395e648734104c61d81a2a38bc65962e0aba3dac99b2eb057e519853f3ac9bffb834185d6b0c9e0babd6abc3281c256dfb97cba31a15b446aaaec9020fed7c787b8a9c00ce01b9ba59eb94126023f0fc4216689fa9b47f7d748732bd0280e3bfc7856b995128bde6a7a5b6a7c75a6d93f1f7b2c8f3b182b239a40d9885d62f1b7085152368f84367eba8184ca479a5972b0647defedc7a80af50ccfa0cdc71407647576ee29905d067aabe3928c9b4c81c57eafaabdaa3b227cc8524406204cddf093899e278a6059aaed9d908704879b50d6647cbfacf89089da9fdeba0a58605d4df57915aa186c9ef053f05599f43faff18184c3623d567744893afe25a478e9270412069274829882fdeb6496f6bdd1ce8fba53b93c7ad04e436807696d2a0d401a7c6a903ff2f650a88732acdd3ff175902aeb01e37736023e6b31626c279d84556217ba0cb3976a5591f5b492b37eca544a280d596cddadf42ff1611849acbc8fe3fe5cfb40f5635b0fedd258897d42ec14af37fc925e88a51a4a6462f4f4bb005ba3a131374206c7f1022317226084bbb379777b94b6090dcfd28dde43531811fed50b5bbf2f7daa42573dd5da459005e82709cde5a9ddebfe45640effd53bfa17454916f75bf51ecd63d6c544ebf56814a204a46f3a98d1dbf8daf950e0a6ff14cbe4eb234b25afb664b63050508044e9fca236107b6cfa47b9c32e12345c25b311f21f7ebb841494aecdb8024cbd737a53f047c5f4e41a1d268f0caa5cdb98c68e4242593cac1ae1537e99211e1b061990dff9c0f88b225061fe581b8150764b28cb409daf9cafcee8eb03e3a17c612926400a1af9360422a47c4aaca3775ad02271d9d037f4e87e33d95c3279ea5e62b4f5b27e25ce31f6a6184635c709ae917ab691ebdb9ca79f6d903bda47b5f687935a1f7eaeb79219262a6c47715671f17df0955dbd9e3f02a622af5aba4ef3a95c2f5ad39903943f6f45af0b533820ce1b259dd82ebbe322fbaeee73bfaa12a7d60f58c839bf246a6efc4bf3c07fc4306e33004fbd5a665e53dfbb519441bc1c7d7cf1fd423ff322e3f0bebcfb2ce7b5809f514d5e5f9b260c649b07329d4fd2cea69802df5d4e47bec1c942340ce7719cdadfa33bba11d4d9521461659b0ee963bc9b395f62d94cc607794c2feca5ab384bd90b94fd642fa4dfb870ca3a1b00355fad2c533d6cbf6fc22f6e30e14856907ff1c0e4cca96fe3aad9a3987bc28bbc2fd8334a53969f21b6944b4bf78ca5658071744b95604798f435a53bd32beacdb5c2ab8ca773393330fa0578c82df640e70460c59a778c268b3a35a258b92d167f221db21622a23388507e191fd41249dbc254921979eaa8012e0ecbba4588c4f53641b1da7a0ce3f74391984223f9a77a98da48b011a1c00a471b3829bae0dcc98ec475b587f9a005d1fe69b276203345fbbdabc472da8b77cc3b670c00dd58af2d7aafb168340f1d3d37b6db1ebbd61d6167d184c715b9ed9d4489ba51a2f81c0ed1f684ea92a058f2209b8a7f240d8e986b231b84d14338e6a289d76f7a4aa79553abac655829105368ce397202d3425cc01f88f4e13781e238d58b9612657243693a0418cacd2e6f2efb979e60c738d3007b4a3518fb61c123a85bfa0b137d40ab9aa199ac6628e159bb6993e7703709611233ad94fc82d02d8ce8682f9f6dd25c60e37c26350b8d7091012ec20db76aeb6bc28774c3b1e12ae816ad399f6a749f2515473f3114a033893345ce9015342e9d9a87260f427daaa9c790a4e2e9e3e2f3deb2f6e77f3b7dba26a9d2011a6a07406e6498c9ddf65897a6ae34577085f8cb8794b5b9790d96b59b1bee710f966e9645f50711ad3fcb1656759b3974ca5a0b1fe6056fb4ba250a20d565fcc26af8954ab779050d1f6acd1e8fa8cc8d438451ba60bafed7b39ad6f9e14fb41089119ebed8eef6964f7100f09df73d9bb2a73e4d27e3035ad6773cbaa51d7be1221b8d6469e145413dda6127b61756adfc2bec2a94c8b1ac17530fd06f244be8546dfb6cc8f771111b502c9c0713ad0821e17ec85b13e3e28d4c08242c5d85857420c76ba2614d7e908e7c70085e5ab4521c85323c0a36154818e0ada4e68fae3cabec7721de9d9f29a5a078e4f559346cdd6018454dcafdbc5c8411545a88326853f9d5819082d7c0f070c3c94857095cf35afff60975a82ee495ec4160644b634bc980a81c8b2931c089d32b874cff25d17f3a4efaa51aea57df6e9fd94e7437477cdbc6729861dba9af769a13ef0791f3087216938b66feda7bdbf65c35b8fab0a9b1787ca6f79ebb6b063f60c54a79201efe479bd9e97d971cdf4a904b6219cf4d9bc7ca648511f1ec108a0b9675b404cc90c9b6609689e498c2c8e05e5104c4ad40dd540f3ed0974503e212d46d716c3d4d23ea87da4fe6a690fb5a5ad5378b65c28fd1f5bdaab1d0209e9bbde80d690ce55d3f55b94b6c77cb6d61f2068936695d7b4e65d0630ada797b5ef13fab92957e9166cc2513d714e9c3a7644f5d3f844b5714f6f9d98b5b26551bbd6686a01b2fe90778ef17d154e6432cbc68c749b486e019a8f8ad6ce23ce6e24947849423ef947ae23a14b1046b49b8cd4794820f9f690b6de7c4180aab15c0fca3affc08e650288142f5e6151644082f0060dfc15a16a1d884625bd707fd2a66c963ce4f78e1af1db6de2a47f363eca9698f6b6aa83a3fef5c40faa3b57d727129678695ec9355ea05a6eb1e867817b9f3c19a01d675e912a776e2643dc601f596eaf4e4a1f2e8bde569da8bbcb9eb35ee5df3fecdde20596bd7187d126bacbd43a087bb7f44acbde4cae91473d274c5af1dc408a956161212c7ab6c15a80d6c618f5f08314d170c113154044ef962816f351c004ff8e9e07eff4018891da96e147f13743b06e752d82f4a1a651b822ec25543b67e6139ceb73805a89c1a2643287ce10673a214a54ad7ee215e676260328c02e5ec966e710dc119f5c16eb354f646fbdc774b10ad59cb5f618e9629b3660de279c60e00865a83d7ef365d1e4e80067b6c11c0d2b56b90e51b60904a5ed05d6069506e3e07a0b5bf4c1bed0f9c01d46a136ab79444e478dd0923370bdcf74c71117ee6665675f105ef12a7f836a48c602fc4cf8823555d4d9bec4db0d6b482af1189df1f340102fca57fb6a2ffb82602df1976f485be63b4e7cc16ecd2d1fd172e3a2cf016d08b550332c78fa821610fef20db93e2ff88229f9fd722d5ff479415507ca57734ec55970b143d5efe76ec8f539e40b66e4fc7662a9174a89170ae331e9cd0852c829795a66b7b1392a2b7133f417fdf24478b7e90b7dea7c8ddc3f8e18b6650e8883bedec997735baa0b2da2b22d6a764bbcf946be1566d718433f6322b266fd3cb75491b38af8117ea9c8678b88523697d565018172401b88cfb0cbc64f5578db7a3b10746ee45761f64aac3cf06dadfa79eea84fb3651f66e8e27a9f165ca0c205bb3fe9da9460ee7677f6d5a785d48815f64b3e0fdc02e06d500643509fec244cb0d725c3dfd3b76b094df07505ff15beddcb18dfae911ea3ba3bf6e05dd1f2552c5f72a646b3cb74f10a7d2191b647eb3d3d351797dae88a6293dd112aece9471ec125fe69e96bb8550ab05285f6a2779ba38646740f2343ffc2f043a188b3482eac084ce424c4f767430d896e53e927f937572785a28d310ab52b85715186441ae108344641f1de9a841ef3bae5ef7fb08adef7f738fa1785fbad85656c7f32f252c56c03020954259317c9d5af05cea383c9e0ab570dbee10ef78f1069a3fb754f8b70a5558289b21756759003da69f532ae51e1d4f1a461432b83a41c7a6f1dda6ea313956fdc8ea855bef6aaae314e25db8c49e662a42e4f08d0a4b5031677ba02d27f2c404e0c371ce93e671cd34390871cfb5c75ac51542d9c3676cdacae65b92385286904c87365e2a59fdd224e0f6755e2201f6822932d346dd81ec43de700437435e5c594e426f455884f3d9fd700505ca116267c78bba2a6af43185d8e0eea88a06e051caba33595d65aa18c4bc5dc48edeb2fd1f6b31be966cf69fdb5163254a714a7d1007a54d1e4064bcafb1c37e77d841168d2c5d898c9cb714dede32cb5bca1ab4a9c8204db35b1d6d21ffb81f4a975fba83a0d2a260ecc36eb19ed7e413c6f72f7dde8fb9ca32a357ae5b17042739407f33cecd89306bbfd04bf2b73d757e77dd6a5f47b6bc4ae59b3470ba22313da26f6c1da97ec7c6c708111624e767f26ff1b3eee7d13c8a34799f69393e56f42856eb8b779beeee07fced7ed08af5765e812cd373a70422c117b8da0fd7046dc28f78cc0fc57acec06d92adff2ea37487cfe346047329aad8ae412f8d353196e18f7b66bc2da8e48f43defda0c2c077cbaf784c94fa690afaffe11ec4f16332f3e6fecc2f587b04f8b6f86b0d16b407ebba9a4cae93767cd59d579037224b6f70927d49001c94cb90e23677a451344bdf04b17eb93d55b07f0313319f1bbe1216a2b97488b5ecb932ac41a1a6ab3610389f9aabc592879ed05a50bfc6058a963e631cc0a2bf3f592ae508d1ee370fc68de2e017a50532754b33166b4956146ff60622e32e0e61c10b4c5f57b4855e4425a6dd3fd6a4a669cc95a1cdb425b8e561bcad23484629b7eb8f3f161dc212635b1ce924c94a1588d38f0207eb7324b4b16c4aacc717a3bb12c681470e7ed79057d361e68c12d98c57c8341fa86ca1ed90694e50c007b4334d196cfd876a8f9f86f4c31e5ab1a463003e29e2f5421de11ab0d36cad9fdceb1a06f26a2330bfbc0b909df0a610ebdac2fcc64ba9e74acf06c5f3f0bcbb77490604d98e2f5bb5e3556488a59ec29cde76dc528e3bea1001dbe072f237b3957191ec4404322d7b08d078d9a3a0781ff00892a22074386767af4f5d63871390c43527c068dd47aebde0516d8cfa7700d0f9a78c3772edf187641d71c99c46ab4a3d3e15618ac855c6ef30db8ca277588c6d706097f75907bf881fed16312ab253319ee6c2cb4c34d269a5251b53e433629df6ae2c07cde637eb3ab53c1472c01f89d96f001126006cc97d7b45f548262d0c4bf73bd54609695784dd5a0471130e9fb254cbce6373952fd925ac805139f6846145051e9db7f22145a43d0bd467ba95534d550df5885567c59b897dac54bb958456e2125a6945cd6df3269fc91ebbbd9a1de59328e36e3c194f873f099e981a4cbfea91dcf60f943a17c9342d3d3988fa2efbe295a5cc61a2b52850c8a9fd1b850fb9927a48ebfe4d720b17a9687b5fbf2af6e325591ffe021db51b03fd7114d19b3fef8a523b6a1295a9cea017c3435beff3a8d51fd56d4b19f3f4364eb39bc9ddf7d4e6f5a39e581700f6ad9c1939205d4f2291b989a0db9acc48836d983d0ebe8270e2b01ce00bdb02ed6e187befda705d721e20b3126f42e2821ef0da4723eaff6e7c548290c9e505debdb626c5d69a2d6d18af1727f5eaaac2abbc26ef416c8cb7534d1ea0f5efddf8e3a1598ac755d11713f9dfe5ae5bf8689989efe56b3c6520b141af3dde5725acfd8e02f3153fe4f74450df4894dced196856e6a428e52491d254506a3f8b59c8f15cf7221713ad3f472c4f2b36ff3cbef590cee5a33f52bc9d14f5aa8f5782464e01fe0022d66fc3fe76c0c85f8d0042db6e363e90d438acff41faa0b50c936e0825ded707023372421cff20f15e062b27c8633787f60d972ba4804597ffd46f562772dad547c13d07fe30fd2441f0cc2f4c3acb5b359d3cc1fcb474a613e9454f99f983fac50fa9c46fe6fa7ba933bd5c91fcc945294e33a114e5b36b63fed82eb07bd7530751bab1da1a9aa970afb3c3515de0f9ef54ac695a7b5b619f023d63b597e17d64976e17270a6c498a37a8bb8971d274efdc4e0a73b70cfc5b2e243d93e1e7abcbec8cf05e8971de3b3724a8f4a5480a2bc954ef9c9b5975e10c8ed30dfcc92afcb37b494c269c80a7753bfc69194cf74cae09bf8ce9694aa7695ae22b007a9f73ef69e77abd992382c3f4671b013ca12dc9fef09a74fbd228c481cfee2b9de0722e13963e2b386771b1ffae43593cb3d52d91aab2ba96caa2ba7250b4d1aab5c769cdd96a503b8372310b50ed6479352c900e5ac6a0a3f6ff9e7dd310b17cfa4b04ef89972ddbe1aa19d812dbf34431b306496500fa7153903a8eee4aeba82ed981aec0fdd90123e86c434d2ba7a8f93bfc711d643257f4fe7dfee69af6cfca284ba6daeaedde35eded338da5990eda67abc768f77794f52cd3d6753bd76cf207f8f9d8e41c33e7b725a8dbfde437d5bda20d251423d5497fff49c4333d7b75df3da3d23e1dcd45774820ee3551f19022c7f4a36ca2969bd3b281a40c8d756b9a43fc83d0a1eca17ba760374c141047ed92fb48af09fc66f35a0120c0f237a5897d27d5c46f0c93c723115f4d83040467524090ce27f6fb7fd4aed72854ed66e44f4e49b9e6e18508770720f701856a0d579d3e3192256380d3a61024560695379c48133a8c00e76a936dea538f90df800377055ba5da63e2dd1dfde234e6050858336d89de2af17aeb2ca633b907bcc8ec739f09437dc46ea5b59d1b36cd1170d266facc704ff710b380918a47c39b129f6b25acb44aef8b950fb01ed896e5a3767ecd6e9a6a74388e727afda9a71272b98b6c310b34e853f2a927b7e73f6af7942dda6ad3a3c1276d496fa7a5bd8913c3f32bd93e8cfe0c571eafbfc537b918cb8e74b1eb1b22d066fe7fb81568b7519e9b1f2c4f86103a6262465e7e6994a6962032ba77a82ddda69b0cbac8b49f612445e4b72c7648e7c85af2876e189e2ecd942186ac91489706b9e980662cac9417f7f047fe12bbd38fef210eb2439183ee013caadc23e1e4618777715b393d5005bfc300283d670c6d0783c1074a193ea4408d80fe0135a3089dac1c182e3d6636e7dcd37b5a9718b7dc39a5b744dcf16c37049594731640b67233f47f0fc0d6a3bedf80734191c5431fb05370d7682f828f018579b7987216f7d7590c7193bec70dd70b627dd2e901586ed2d310aaabea05b9584512be7c8842357d2eb4bd9134f1be45b3fcd966460fe6963710f5bf83b00e8bcf354bda89d36b1d568d6aa30759e28454dbdb4d08be16142222944787fb0b0905679e56747d884450fba051206ee4d0b9ba5c91d4cdf8d4288fc0ec8871b5000d3fed369ffdcbd617dfaed89ae70020625070ecb9a66ca6b4f0b3385e0a6a35be7f84de3988fdfa4721cd19b290336ff346f111c0d55bc58b62ab0f2370b42417df79159801cde771a152ae4704493cf90c624d5849e0252ad461a9c0fab478ce2198ec304f067859b6e0e8af0e05e1f91918b8e54192feec4728d299c8f14f4518478a09c10b039f60a7fc7044763be259c53c3ca97d70dd3fd6b077984c1190bfa38ec2379069fc78ba8808530a05b90a6ec1013594f1c3be0650543fa640bcb1b5315d051af1ea7d00c862b2e950502d70d5506710c7604349af18281b10099d0e4c41bf21d0fa79c5e82478dba117576dca24eeaac3884cbe9d1b670704eebd7e373353d8da6fd58c3fb306891c1731de3a1c3390814a902d776b63cb80402d1efd7b75975987aa855b3388ebaebc0bd31e8827d7710109ee3e29ff01cad44d2109982a37c33b24dff1ff6de6b3b7525e8167e2018839c2ebb5b42c8b22c638c31bec3092140e4f8f4ffe89ad592c078edb5f7f79d8bff8c73b3bc506c75a8ae306b164845b8c6c97bb3c4f9b19cd848c91a27c01f50787eba6160b32bfc67fd3fe48d3fc739ea9baf0519a4913a32213d93c606ab2984307f8f37a56e83fae1b811791f821a49a6cee38ad99d7f88c625551be9cdfb90633cd7170c89d3e79cca163596e721bf60cf9d955b64779a24cf4edf33d6dba813c315370551789726424058eade161e627f03907cefc40d5880ab8fed3294109c5091b6c86ee4d863bf64f01611c829388bb13c4d09a0a0ba6cc31220c26ed407d457ace44a9dcee0a06efdb127c5591dc909e6acf51ba6965b44a9d9d19608ed2f08b3666ad5b4d3fcbc52015ea8d51ee51eee41df9524de350b74f1a0c6d7510ec0562db8a2af7ec623e2d7949296f85f3688defd288d7b04d0f9d0cbb3464bb8c6e49787e9a5f66a879daecf75469de65199b8be70d703d66df562ae31c8bb78682309b2a64d9111b9d35e04486ac4880a758430c1bded44a2f9844cf8126a6f6da2cecfeb588547778d848aac66eec6e358233797f99195e4f6ba344b6324a678f3c8010a059c92db89931f08fba88ad5cb74c7c3987d8263fb472dcaa1f05baa5ecea0a600e87669f2745ca1df58967193e6e7f71c55737ba506575c2822dc4999c238ec08fb93c1caff50e12847d9dfced63a5ad7e0fb7e428cfa4b99f05a95c1f5d0ec067a585f6255395d39ee6e42f68bc0d05ccd06f56ef4a51fd30ca8c9e080bfc6740a3f90d9e00b55932db46b8eccfc87193aca1f37f11bdb9bde69d57bbc82a794fc5f4d528db5f4b09f3778ef88ab7f7371341be9085ea17ca34279156ebb4165d9f93d5727b238d93068c558785528a5fe1a313cb7ce05a1f56ee551e6909b004e93f769bd747a335701e87d439674b30d33d81c0b06d624c90bf199949212ac34e81aabdacfb7904ba94042d3f922fc4c428a5ae1941a76da721eb22bdac23028f18d1ef53266d4656d719e4e1ea8956e5616571595db239eb67ebde83cae03efd587403d4e0e5813f11c5a0220792a94d1eaa2397a6e5316d1dec1ee7b75de33a3664a51222f62439ab4bac35c419999630932795e412a9e5c80e5f023df156e2867ab1ffde0be99a7ebada327d40b2a9f5ee463d0c33d53d9135fd72adccacbc095a6c4a7c85f14d7f484735445e82683d2b2439948fc7b54e1529c795b543e008758c9e51c49b64452e7b618c464c8ae8ee4866f3fcf512999ecf6c7304a4c5d07dce68d95fcb960fea6a4bfbd577542535bf731bf2253c8df17f61b4e0b2f86ca443ea3f70685c5dc38069a674cabc87d451a843ed77c9fcb69a1ad37e12117e3e0427939b043f4a1f80f2e0fab827d2e38bf0c0e688681502b4846d5dc1c9c792e23aa6918cce02c2d1efbfaf2522c4ca18d939fcad31a00a9c16aa918e8539d5f5e3fe7ebd77c3de82d9ca5629010126db48c7485f882fa91285fcb08fdb67825b52ba6aca62edccb913dc93e618cede80baa7ab71022f5e87cf3096819f280ed3f9191a19b90ccba97d7f45b975d1aa5482787ee702ac91d39c4a58837fbad60ca5d9b3403a525c16c09f76293e6957ad05b42cf54447969ded3d4d4dfeabe9437ea820061e0c6bc359ae570a215f4fa5cbadafcc618d44bfe27c687a5c83fe6f178361c3dd79b5f133bef804d05434514cb05b0a583f8d84e774515cb0d980c46b58b2f57a18c8b29dee06905c2d201c7999c69127e2e41df2ec802620f738e55e89d82d0404546e7acf9c5ab633b3f122b64df44523dea954bf9d8afec724311a757720ea23b237e8a8a14aae5b460051283c82b2d43e5ccf1a2c13aa70774fd5421e934955026831016f3959d4babbeebd6e8a2276134cfbf74cea850cef1593ffa35c7d65c954c9c5ea580a2da5c2db62839a4cbf1b7db4678c1aed1a418804c1db167a06b7a1594112b93b7b3c7b5e85ca142bb02cd03b4202f55105dcc2537248ab4dea9b6aac80d9c91dda39e56a9f939d43bdd93bb241a45d59984ce2df36bc2852a2854198554ffa8a6fee1e22864020add19689bd352075cdc9a41906e09a3e471c1f3fa1a4f243f1cc5e1540dda7f8b6b8e21e4cd6b7ca78438a93aec7a1455a04c2d678f6cb202be3358708b96fcb70144731d64ed3c1112530fd84f7f8cbffdc80766fc087bced8cd750a9a075a2fb9a3b8b1e83546186fdd4bb14c1cf767a2cbadc8f1dd8d0738f73b326d778fdd0395a913bd35077c19ab7a39519c4f3c7dc98e3f3c5d6c64ae29b3bb784df1ce916c430e6146791bfa65cb7185bb55ff67b79c82449dabcbcdbfccda72e9576d5937df2a43354119b9418364b57a3821c263a8faa31caab819a6b4a4c7a1ee6de43b5573162c95931d8744fc0ffe39aa22f76c64f2e68c5c9efb64a5eb7edbc083dc3b50de818a55b5776be547972ff4ae5ec523dce823b4b3502576076c380e3a27819815206932033ad5d9515d2032d5bd3d20edc67b05c7dd05f0e44f7e3b57d87b90aad23345506c3919d7987a6e4282f7f77cfcd0a2e5dfdf96b3f254f40a37577a93d4b3de61cf6bd7d622100e773ae43e0306c10f47477202d9757bf5dc5ef46b6a43eba76c1224dd3a562cfb81ba394c9ebf190d5fa846a2911cceb4317dd4b04bf60e285e1577012dd4ffbe4758ec3c3f667d64275489a83f8907000276352ce65bca77894ee494d900b8f4b9fe62bf01eae79ae1480789221074a76287939d19c071ffb5b8a2024273c9b0456afd505807355beb57d9915dad6435a7c217575ae23a88e1c54e86fd4e1518978acd9c2463533e6656378b74c490699f5bcc493df45ba4a77b1b388a21b110567ba4f32cb757f7a637512bc4760b83ac34f10bbc735799280498b1f65a9e388a458aceb1ca6412fa0deb1878557af2d9fdcf128a7581a009294832ca15ea9165d40650a2608d823e4793e2e72f37c84c5f51f2a0ff4e567294bb3c39d60fb11f6e09d0bfb19e544dd54133cd98219fed37175d3d87ab2428f76e9c341f66daa4cf76852388faebb9d9a24595932db0e53c1f682fdcc8101e19aee9b77721d0b08e41e3513d20a3bcbdabb30769da319e69a1eac826f10f28f9ee8715ac56aecc9444163ce156188c49eb3af7e1af14ca6395ce178afed0a8f8c55bb3b766c57cb91ef09e6875efb1cc01300b8e5c8a6c8dee3077afb6326164b0dd2a172200894bfbb17e4e1291d453f8966703652a5ff281f8761bf07add2e19a72af20005a75b7cce84fa6994b9353ee2c481b05b6aa6753f6b41a310c9e94b46042ac4950f44d36277fef971a257ffca731a8a1ddbcc49136ca8d4c3cd3b7f7adea959352a54976d171c76a6619dea86ead7810ef3dfbea0cb3c53671b255bc7ed249a2182f02df59879f5a2324e78e1351a99f430baacf858521302478b2f86dd199bb13b2bfe61e0edb5c5d6d82f151d1db1aad908142d4fd9dd29601648bdc98c8453528db1fc33ef8216eb2d920069954338417eba4d713ce055720949d5060d7b7ea273d6b23486cd56d61957b02eb00abaa2e4f87e0188d96e09718f1fd8d6e1c5517db5c356f7d9de725a115efd47660847788486ecb80be0001387225da4b672c2c1b63ae4ff25a1dd5672126c6f98ff10ea1e5932ddc61458a12a42e8c31a63a0c187d16d2e2dbee74bd8314cdf9712b9e9403d685bc585f56f9ef444e81eda1083bdadb2448ee729d471386f0366880c1a47da1d420466114eb7bc350c61d27a52a778dbdb56b588b4bb60c850ef7b12dffd5d36dac22109b59758781f78f3dd736146b57b16b289bdf92cc98f7fef35e86d5e7fbc225acb6f7ada4769caf983132e115c7b86a4a35c680e76a9770663fe744dec10209fbc90a60e9cf5d7917e75b144d792189daca8c89896abcede60fef85b4425a77201a72ecf810feab335327926b2354027d06b597333bf4e5fd426ab49d70c6b9631bcd5599691f953c839baabbf733097be2a4ff99150df152e4270a62a39eaf984cc9d5e3992f92fe1bc605650f0750826e0700dd15929a964a41d86c51233ccbca60cd50c4d0c542d68219db085986dc231562215b2972a2c47f4f75504e23b2b2b7fd308ae031011bc69bb558769fa6625d61580fb74e62e7c787859b3d406372598572949dc7faa1794a1e0d15fd39a3a8916acdc3a4950cbab205ada9daf309f1ba828ef6f88b3ab6dd5623d03eda9dcb1ca45ff9c237604047a9650ddae16cd61874a4b2d6871ed58c81ccfc00a349608c2ae5aec9872f33de1b4ac7823af0935ed748e19a17b44daeb91a3cc794ff45ff35df1f43143aadbcb02e883835aae797f2b466dc09c71d35d176d74edc3b2036a9ed5a5dcdb1203a5035e9d6732ea98e934c811f2e849358ebabfbabda2d6281df2443e53e689d2ddf3c6af18dad555873a7f2a75bfbbc26dc96afc2f886c4fdb764a641b9c23db48efdb44b66aa6405f9bbe77cf53c6c4be1187554badf73bedddd9b94df5a9dc73e70f33a3ed6d0794397b5dcaebdc3183aa379f35686d8f1b1ab596b5468248d0246f55a78d69e5ccd369a5a77384c9e7699d36d4d3eaa1476ff315c4ade81d493beb861b3db27e4de6a64e1a9b9dadad24e35db94899b5bc1aea96f5b3c5df7c7dd5893aa8edb55634c5bfca4ce5f30b46bda2c6f1456ee0b429f37dd179df1237b9539428592726b28e44aafeec8e9cda53f239f5e33b2db7666df0d57cc4e74bf688dc088dcf0146f7b1e4f326c7bac9e7993dfdabc0390c48c7eb9f43f53b99a5ddb0536b2f42c0cadd1c98f07d4fdad798d96dbee8a75a5a86a4a55ee5ebb67cdd0ed71dbb795774b7d6a99b0ec13a19024a552970546085ec740c900862a2e9f7676ababf98853b99619c3d172ffdf5a77fd093e61137b39b6cf84e499e81feeb31adcb174e1a9fd11c81a3affdd22158bc7540aaec57a9c88ae7d9d0da92c7944c5f67ad2e954828bc458414b9d9a44b0e85181d11deac39153661d9985f1591c0e2c10485d632401da76b96402a63a0070aa5cd0c2706e32ccb44cbe28e211913128b0aa330b581e1c76d7291eea697cc0564eca8cfe69ca006d0eb4177ccfff584579084608e5f9302d41c8dc9f744efa5b9b0e00aef89dee7b625cd1e613f959bd290beaa97599481929f265928790ed1290af4d4110e2404d469e9181e1bf55d9b52aa00aa864d268c65ff10eab9cb5423aeb023593b67cae7edc6c8ddcddba2ffa2a559dab46306400f17929e44bbfedb06d0b341e3ce64a124ccd76ebc80a4a37485d502cb0dd59d5f8e310c940db2139f1a010dfeea9134b1d51df511127e3fd73912f1fe24a25eef009d4c3acf7bc47d769242bdd4569c1f319642bd033da0a7e913ffb727d4d3679a8bd0ba8347a62bd47d4da6c7f7ccfb3010ea71fe94f65ce309d77485f3388d9c0cca87646d9911a17b00070e34fa156b1c82ff35df13f6fd79c6233110ea8986ee30a38f7a2abde1a5b4a367a1a9fe560fd13dd245c40bd89a0f2a0b6ddd2b069f3639b4dee2bfc0b6ea7b467a39e8d3448ccde72fae7785fd0c3bb586d42976472d6d40327ce1d4946d3a52f4b22a2d29d5f439e398c1d0a023f619cc449c884e4d9e3e4c5f881e472cca3368c295b09341af16c797cf69506cc46571c3170bffe8e407c2d9abc9b749af10bd1f2e5b3021649fba67e0c2e6152e7668ebc171025f23b9799dad9a7f60b0f45311b00f89d1d49f138c93c87a2d51076aac08fe396eb1a2bcce67ba5eb994002cbc3ea1d5f6e4c1e8551ef37d6197e401fde86189c71f99efaac87124d369f1649a90d2c05e775317150a320f1944eab073d2ef08376d765106578df684fda667c15d0e76c4c7131c5a3d5e6b3559fa4c5362721b2bcd1102ad75de17de679a4285053adb58e9cbcfe0a78b18681e73bc1d7f033d18ea7bc50ece12cbff62853cdbdf0b520aae5848f764ffd835992363dfea635e74f9aa04165422a666b594a6eafd3a8272b381cbf70396eb16b197de6ac50ecf152a9369039a45b5c0960e1c3df77e8558d2153b31017342350ff3a0e30a66c86e4c664d3fef0baba487d69bc9dc5aa5fcdeb56587537d88c58bb7f01afe065584c96632021ecc9d34b3783973944a324b5a066ef5e28a5a7a851d82607b8e3d33e1103ca0059fd49c8ab100f185bcc8371be808db0d40f8c8e9c125dfe946b185239b60940ff4fed1867ddb7c0aa42f2534357b1d27ddfa9c84eb8abc2f82167abd8ee4a1019704724b0c3e2e36adc4fab4dd1295976c8b0de84abb0b68914ee5cb78ded45a9e9164188c919fe987a1de06029a1b7723a4c03f17159b35ae103d73657d6253a62b052c9e1b110d6f99bae799996cccce0c143ea13071aa6396b4fb44a12ad2947ad36f605961ffea576ee5cac12890f01b2cb284c894a80543dd6be95de86e4ca2e20d8437fa067055bfc1434159d550ca7a6306ba840b32413fe9d30663a4a5f44246ace79304a87e91ca67ba67855e7568ebeabe50d29b11e88a7398ba7a67a3637e72cc4f8e05c9b15ef6defb7427cedc1bb03fd4d69bb082829e7744d9469ec069458b7d2c5b34651d12f26df82e82138a74382df6b4926bad4a05a94362521713b52fc363a5884763ca9301ae6e6fba30641b4c4b408bfd7e2f9b5d482d2665cabc88e0245b105bfc0462d4803aee6dfe865546450a97078354367ef6f3971e1472ef734769b34f776847180efb469cf563fd64de29ccb840de8ca314c4c4a366d6dc60f2d8c5ffdb036e51f7b85a8e2e50dbb5b7462cf3104b6688823940d9e55b551b67aa551aa9e90ad1efa0ba287a5c9bff7d219e6bc4b826ea24b7b190ceb2c808fbf40d11882886744f8e5e3897750c6d377cd36f6e58756c0fd312d5c010635981d1b19639f47ab758026bf6e40eb44e058e3d356191791500178233c09c3369245b8e2fa8f1054bfa48359346a4ed16f0ee30cfcd25a18ef0ea9d4b1e3247d8336bcfee2e26299bd0364a2c5cb0b66d11a829e2a20719d1b2a8d8e0b7cf513a11a4a24bd9e0b6b81395887de4908ec924ce48c79a2c04bf4df4f49a2dc0feb766a9a76729953b03f49d5032eacd4cd689d4d2ef65440305b9d8d7e772922837c45616199c5d2763535465cc3979539af1bd1a981df8bc6a9089f6dc58d1f479a18755f96171f2b0e6d2014516e734fa63b202fc123f4c9fffd05f76dc926c5f2677e6960eb1f9c9f50adb1f6f2de684c92bf59b9ff92f7d5d0be994bd314fd2e6a79e6dce5b8b0a48899322ad8a5a3de176beb3265a7dd047c72a7cca1e9d3c00bb425d183d4012130cba799966460c48f63663db551fc83bb902cc61c405f7fc1c35c96e17b8a97afcce92de231c26061b51c033220dd32b25c9651b253698721bea114738bc416f20973fd678596fb641f3cb21dcef48ada9904ed31614f9eb558b9c3eb74139bc126d4dea73ba4690885c0647f2df3bdf24fbcaa85104e18721719ef4078f256fb5ae1075dac22b921fd35d6f805b008138a127b730cf78abc5247d4fb61e572bc1c916cd8dac15c95c0ab35bbc630a6e077a5bea0a057f7abc46c34c03f608e3228d58bd63afc27d2f7ac57c671e4905ebd780079d572ca0482f7cfdb1e6ca1c05d73605f904a06f548077a534a24efa899e50efc91d43e15865241d772bf8eb872d984018d022067470c6e0c4a9490788a9f0e72b50a2b35b6a02c33fe212df53fcedaaf45f9fcc7eae5171de328736f44a54bc736362e7b1bf01fa6951c37a74ea33af00ddb5c41a8f4ec85e8aa724db4d381108ab9c09fee2600dd0c586fcc96a74c092ef1ea93d6a6ff68d3e53db235cb0675c2c7f55b0dd72861b5529c10f3ae80a67491be641be42944c779db4216b224cfef8a43dbbc5c4418684a6ca597b767afd92bf66da72ae4f15980853f1379db81574fdd9b4cf449455e5cf1fc695d983fd1669e13b7eda3ef320bd07bcee2de81b1836ef236d1091897fe371a3f4f03b1dc6c00a176b5c788b3934a025ffe5b256cd30d359337cb4bb6826955584673017b76e68f00d63fe4be69f5de219f68f1d64aad118ae2e1e8f8ba9299c71eba2a79ce91241fc15f031698f99939ca1f851431ce53085c77ccb0b6501af7f77cedb73050e749feb0504871d68992d2a905ae3656300446736d61670ecba61818d44fe9b7ec143a81a786417a91c64e906daca060020d89319e2eda6c005e4e043a768f8f3f57fe17e4cfeebbd120cc8ac4cd032d9aad4b811ede35ccf18df7915e773d6aa8ee27c4d8a645af7ccaf40bd63dd17b8aec4991333e631a9f301a5d8a94e0b0c52c1ee1d1ef6265ee251dc76d0430e0d9e480938833df866df7239f297ece47e47f2e0bbbce3946f8ad0ef95c99a9d90fdf658e76cac7097cc23f7b389290139f74ccb32c064a9f1163087488fe55de664c39cbc27147d1968ec2e99a0efb3053904c58efeaaced38de7d9cfd97399c779e2f9fd80c7fdb3605e027513a4e3fbd9f931013c3144a9ba7f7c9ebd54663a5c93b819e29f23794a5428c72b9c589387d8217bd09d6ed8d4d33b762c1b5594aed146e45db39ae4fb51d8961380d6214812a16d9c30cf7dae90efcc910de09e692577de4f537c4901050afe9090a6966a0229325c9f39307b6e8316f68c40791f90672d4e2a65fb7a97d1d3d415a28749ef1c2503e6f3beb09ea1645ba242318a2b6f574866b89ac9f9d82678ce98ab0fb1da5efe22b779ed0d517af2f1a9868a0bec8751423d1d483b11bd1684fd75e69c0a558eb16bbce91b374b5ce09e8b190458f033e9d7b9a9a1267185fb80d67be51529b7fd33293fea7bc2fa537446ef129d09775449fda99fe885dc4fe629ba6b7de1457c9c1421114cd697ca270f80b3a019a48eaa74e14b13033beb43a08262363f26209fabd1be3ce1166471ddc92261c222d418b89ce0a1fc31c5e21aa6de617a29dcf7242edab1aa02153fa801f656fdc88f955091ac71098e3133e384b417392066f596bc438d7177afb16f5f23a5794323d7e401ad0a0ee011080f8c8bd875b4ca785fc1aaf38a4b95ef0b2f96b31813718ed67b6648dff50c143542a1bc4c00e9289302eb94c8bf3d42907e8aafecc5fce0f98a88e03ef1d5a25b35c5060ba6cccb96063f89c49eea2a3f1276645539deb38714ee2dd6a97396a8e08a17ca0c40cc3d93ba6b3aeff04486bc6a86ff6ecbcdf1b4dff701022edc67ded582e3bb414a9b5f9393591b31e62350a87d97dde11f9444b9e7c83f9fdc6e2da4e28ca1dcce6589cf10b7d2d8e10a757590850f11f16c5077a80294f03a17a45608785adc383db10b744a6da97e9312e64a7d3272ded6e8979f4efef367ead71fab7c525b939dd47ad8c75fc685a71e9b1ff0fddb42bd2e3799929df529a3165de13c3576328d02acb930cde4d44eb232851b2fb0ace70bce9378cc8f74e7d4995627de753244fcea85e3010b2e8f5b636a3d44049c46e2e90763c989ba2b94f3e4605777f88ecb1f34b69d8bd4e0a88459522d59495ae3de365717b6848ebc9b6f15becad3df3b96e687fdbc8e32d1917964a581dd30e27b1c317cce3999ba0fdb613ee5ec2e91d63c288e7e6c473da1b6b2c29cd82baed3a4373b0a67cc55e29c99a9153812c7b2022856f77462818cc541bfa9525e64e53f4c0182605b643f46d938d55a7b8a46bb304981029f41e90e79cb1ff37a9a3fd27c983d00f208213546b9d1f59e34947386577fb7b090b988104013be16af504553ca252e2a7358823678c9d9318b799ba2bc91dcb79118e15c6e6795c7cc83d45a6dc614dee8ed213dfcc3aa9dff12eabb39c5c4dea2a4b17f5a118e28946389b139f30dc515d5b9565b5943ccb9b5e000e60a4d09650b6d64ce7f7f12b7a9a6b35c503070b4e6b6afe6743c9627aa1b3d64822ebfb96ea3f6db9a22ac7dd48e12fe89f0a34e289b1ddadf7bc997f5a8c62c293ede43f9d8cecca6309d4db6bb449a7c6229cc3f28e179c6e5ef8a4c0bb37c0045a82f544b4ebe7e9f815e0909f17b3839bdf99e400d23eae1d910bb1590015e7e20ec482da18c5f6aff47f260f47e26fa53fa03602c0db53a617be4d67a8b3d38734b2c1e4dab295dad7950374ff6846aa968023f364f1e319533f047a629f4338c65435d9f01a988fa9e708114fbe235e508d2a775fa795757b815cce6082e176f43dd359708966e9a88bb702d8dd1ba651b42143b4c0951283a58a572cc4bb9a970d0aeaeafb5ac35ed2443d012bd516d1bf761b7eb6057c83be2ee754ff2b3f7a06d48e240f5c4f3f3910e0e1f4ebb0e30498e0862190e699e2da8c4eae7796ba551ff1d3eb08fbda819318b3b7dc8eca2c065513ee703b197c294109d8c751f399d0897a1842802934921512a1cca6ccaa67ce8740ca1a50f3aeffc12a73c565464ba53e103d53139f355874b983af5318153ed0e936739d3aa221a99ceacca2da8d2cedc89f9f7a24ae025a7b3e403e5908c954e25e47784248e3a35fe5d0fb50260771afc7b3ca182e16e38e107125badfd5a45edc4d1ea856aa895066cb014071c871cfcb10cab7d6ffa7037247fedc315b0e97655d69d65285cd50bd7cd3959883d58c9ed5d617f9adb6f967175cc3870091ddadc4d1d1dec8ea5144845fc10e6fe9329b44a953fce6cac9872b030f74c01d532919300bd3493155394b52051b61c65b76b7c78c1e57f08591497e174213bc44a748e977ac9615dfda0bbd95dca11c37bdf61777f5cd134f3344813dea1aa0e8f954b009dd94591dad004d0e4e3ccfa95296fb902456ebfd0e08d845cd8e7f73ce73404e09171993cb4651f2aacfcb58840e33dc7151bc82019165ab47f0109d270f3691d981cb2b3e83ee2864026ac515632e9137de1ae9549ab305f33a1b2d29f1ba46c0cb705322ddf0d41f7aa0aa2014191a8a4defdb7eed1992cbdd08e577c21f2993388324c394ce1f23a497bb4cecc375775568ad04f86215347e50e0acc813190a39795c9edefa8ca91a12b02edf91ccf29f1585cf35ae70ecc2ddac0058332b4e07e742078ed5a4e0f405cec5902e42a2a91a1764156984a6f196627a27a479f7ff1b224f82158e19e5db2bf3a75e07b79ae5e2dd8584ea0442dcbb0e116b0d8fbc68ab34335066365f284f9c5253671f0f325e62999653cd0cb3284ecbe87f7dc116dc1fd98b072178f660e3bf940d8912ca240fb475e0997513b1388a6d1917be8505558ce7a7a23d408cb0215f0b7189294903bf8b784dc7a069272412070681cc31a6c8718c926e46eb5061b78892e0da5cf14a4e91db9f287412c23063b08d780f195a85e955da055f9805225831314434e3ad76aa2c9e1f2729954ac1d7c42fdd604c2a1e827c3d513aad43ec01ff8d562e0aa31c770bd5aaa260cd0cc7bba1c0a176ee61f17996e6e6c1dd0b0de71cfd6be12eafd50b75322682ee1600b75bfaf66c9f2207dca0d2af0fb5c3f5ebf99d3ea85cf5f98fdb881708e167f9d9e690408d87688c706c9b1aef1350fc07663be712d275c1ab262f6570ced1724299b0a353e59a5dd590bceb406e0687df1c4bdc94425ee1735c3cc23cdcdde4bae33f1efa7d38964a135c8ed6e18de2fff6e3ef9c239db33766ee9611a43c2cc0d1a1af0e19cc13367d6704fa8c8ae63de7cf0676e2fbebfa4b84747b30d0cd8d586f163b4ea3e623e8c95a1623808ae7b8b36473e3303537552e711aca813b93d70c46e77b844730fd074a720ffc374dcd11ea71e8fd8bb684afac27d999e54f2d5ec7afeeb4fac6424a59ec8550a933833d9e08965b4a639d8e859a4aa585eeb418b722a9687a265c7896673fb11a95cbff504161be376c9aa972914db3fbc10bd542b2781091f0845b4ca90212559d871a56a4ec5d82d48888e69372bc9c6d8be71da3d5ad329c399070ca872f7c1ff6c239ef7300dc8fbc53e3a559027501a7fd1bef7f5961f69f13f8507fe830b717c55918a72a0576fd51c9bf95704383ef7959a490cd40f09a062899298b35a76fc5424393079b51599421921be859506f1624a65786e8e0af1dc8b2328a38627d4a2ffaac19fef1da6c004843057a147fbac42b3eec9d34b9d2daec4f0a3a65c13a09de1ea0d3e41586cfb37d298f698a45faf547f21b277e8abffaab9b867d9647fb0d9687728a8d1df6f18d54fbbcc8d8d57c5f2cc192ea69a0d6263d7c56c50e049cd648b13f7928a61381126277ed12718bd5047a5e4c18dcd7aa638d07aa580d5ad4f04f938f105d7a8540bee72b6a1579f92c3e73d0114022032df5f6cb74c4d9bc20ccb90a3d41ab59409deb06b2587c5b0950a5f66fbf462ab8ea4cbacea67af6595b424cb8121a7288fe389d3a29deadcce4caca05ee29d8fbe60f49237046c6bab80d0adb38b99d50336d8b878f135e492f298accea657956a375f35b9bc712f2386c55ebda06a9a440bec03ab9e283aadd64c9977b94f3378c3e1e6ee6b835c6c64c9cdac03e1a1cca0b7dbd8ba6b406bec1e90846d58bdaed5a1ad6af9ff65ef16eee9c0b1390e29ff716b560d847bba0c6118160ee99eec81c5522dd512dc356e0ea3116054d42b10d645a6242fd15ffb7b0a7040ffc859b19c737a2937bc92dc5046a952c77d3bd50e56d0266340efae95ca523f3b9837045257cb92c3c38f76e94737e9b70a39debc9e930c7fe49972f571c2fd9b493a489ed4d56a736199f99222a02878ab18ed59785f16e2356d6775e7682d829b8d11174d62b571d44d5e4fcc65d38b2954b34e8cc2305fbae65a33970326dcbf99fb41e64b9d1a120ccb0ca1684d59d236e8f36dbdc9141c62e0e8a154034d14671ac1714eebc70dc107ede7407a4385ed48f28a58e595f0c47ec6a0082e6b899c095a16c329115a8a89ac3063cbdea36da58abd68785cea1e1a51b5d037b146ddf4445e97a757778777705c536ed6de620e4db78ca842ff105d5ddf400c790abd7618cde17a2b58b5ebaa649beb5b2b1d7843c67c6f61863a940ddb54cd9b16205e27d7dfb84598aaccdfa80511151bb299d9e19f8ab115af3fbbe09207a885a4b5e4b3aba1951f09fb4791b6ddf5b74c39630faee2613827368c82c5b01e90a9f6157c7b4a385cd324e640f6027f072d26766d32633c78046b78491f0c01fdf586d09cfe8c531cb956f60041ed0a6a92f5b766ce00b3ab6f751a4ce8c531cb0280cd4cfbe01dc0f730d81255e1b00070fb0135d0d04e281683ca6bfe4b38b536f3751096b8077e0272896cc8ad3788330dd4f673c45b18a390fa05ecf444312f3e4f94ced93143358fc0e8fdfa1f1ee946f63153d97320caf6ddbc44743a1f8818876127b310eda3ac620b31368bc3e64ab038ca8b064c198d37bbbc9c229caa6231e82f397eaa03175f58e976576c6242ec0dae44819e32f596a9e8ac27069c489caf3b406a0c2bd3dd19dbd2bfcd039a726aaba065aef1a5ee9cfeda3379e6edd094d39abd25dba1decca740f00704d689549c63a9d2cbf784fd19c133f9a3c25ea22e5e2c3703c59c42d50cb8761107d61384e3e470f9413beee37b928324895acadcb48df59b26f6fd78e510dd6095c9e6b3439a76a85d9111b91e55a7ca95330ae010f76eeeac764b9acd22bb5b7ac2fdacb00a0b15672c89ef622543da446fe9381329fcc81aaf2e381a2ad86a9c57404fc9cb00aca63339021041fae26b54cf7a4c1dd469af12edbd97d991b5988857f6c5611410eb85a02ff032bb9a9ed285d5e56172dd3b158b50b43b0c95c76f67a55b75c2fdcfe20d68ae53389055470e2aa706f0cfaa9b7745fbae8a8fedb16979245a3e57afad8b66f32e7c2ec35638f17429ece07f3a3ca0bd0cea3cf265c977648e530149be3d24f795bd0581b5b1d7d98b3ddcd20af5ce8cdcf645f7a9bee1a4615a161b2781593bee8174c98e98d5ffce8d0d5ed329053d5e0b5843760e78aa15221697479d16360abd433cc3514cd30993d9db9d917bbb07b796b728928657d242c9f69055d617e21935d5bd977c802a58e90388e2433de70311b4e730ce3e6666906b8622770d9dd986cae66062dab900a995f48a317833d589487ec457a99cbea127ecbddcc333c7af14ddf30c54065ca0c7dde2af5daf82d8a54cbc2a4e439a27e98fd3db3e316088b134cd1c57692ece54584d0f7c08f5702cb633bd22ba5b0688fcf6c63d17c4c5fdf6f2e281da162611ea7c279f76068e664e414e3b96d913f4895be71f3f3110fe52b1c9ea087192a1c18e5654c2d222dcf0c4103dfda3b807eb8336e4f6b232032dec250a4cbdaebba4836d886a5e3d6b19ed9b44eba7393c1aa34211bb7d9561f105dad7bbe39385dda255c47510c94b6690298c90899d43ecbf403478a4ca32f8cc9dd003123ce6ac99e0317b77f326e02e440369bf9c541abf5e565406f133e1fc12de5e2e402c8196e1dccc8ef5b3eb5ce1ce543c32540aa2d76a9a34f47f7eb4aaa002532ffb81f6b779dd119d65ea6394ebaca9b25bcb00d4724d49668fc2c29db6feaecb79a8832d437536545ec38ee4cdafb4f752dfe00af5625e801a18db74acfac482927c4a4fb8df8b9395f63a734507e75ab6cc57918b1964fb407de35b80813c6c997a70a3e7b93793b90310785c5082016cf65ee6d6bf648ccfb23c2aa742061e56a548ff40bff475fe9562c8ce5d038f52cfeb954c4167a537e376500f936dc29b11bc002fb50139e3188a701644a10af27f0544e10a6f2d5baf34e58828527d360eff0f1af13f8246380934e234246844eb8da111cd376cc48db7ff078df83f088da09a21ee52ee0df51985bc542cb1f6471bfaf9be56accd125d8b3b932d4ab01d34c955fcda185e04feddafea7dde1677afa8acf1cf8ad38683d9976175202cf6f24670dd896401ec8ae4deef09ff651111f1f3b006c742c26750ae30460de990dd789bfed6d2ea1c5b2634a3f6ca6089affdef5104828d5d44bf1137ffde33c9c8f4a8afb66b363be87e0b0fc1e5977c0a2ff315599bea687177fd1a3ddaf1eda63ebdb99e02fc4f678b67e3ff2038d54f6353d521c5a6661395894d51b61e083a7c621abb0c3ef588c9cad773b52bc4d37ec57b9aeeb227416ca7f2b4b3ff1c9bba5d1d5d3dc3c6ba9a3bf6279c8d327f2bd4d375991cacbfe348b6bef789239f83f07c3bd882c15647b5c3f88eeab8b0d720526db595950636cf32fed216ea5ece0655902572a6605f03790b0b079217ea9953adac5424a9172e88951122ea8dd39c3272caf9de5ee5cf148094e1aabc332ed87aaadb7f2ad4aed242ed2664c3a1855ea14855844239af5b19f9aa1ee69c0a16578066076a1be9a324a1d4a2925e410c4284c456dfb9039c52a521dfe26aad7a8eabcab4d5cfe4acc2711c5ad66223a7207f8e01e7eead983c15150b55cdda818cddb4a74befe8b5a1419327ad4cef1b9c877c86223c189a2567a2ccc11977e04630173b35a22fc40e04eeda603b5b33c6cc5c57b63785eb173044bbf0c7c823c0c0499d7a14587c354eb4bfa9534f8b2462a69e4bf1652a024f30be89d06b52b636026e96800a828ddb2533ee67ee6b156411240e8d5dafc792a38a89df08cdf06a316bfc344d613716e1dfaec912e850bccd8e2af23dd48a371f82723758104411e79464883c2df2e07d081728f2559986b62e4d6d8172259b3e1cc37cedd28fdd1c821ad46b85af3fd94ee31a6ca7ca5fd94eccbc1ecc0f48c556c7d22de3e958652dfbc072b25a01406a49cd74c8f83928f7d062ea5647a897dc066cc330629e6b3bfc8499a59e4be4b6a8a82f2a92280f67eefc6ec6dc5a125ba8fdb25adabf195c6574dfb0726515c5152db4ed92e44feb583fbb9b8a6c347e35b8fefc6855920b0cd2887327b957ec58c2e69a9d2f6cae15e4d780c90113b9551a2b10862fb8a5e7d2edc1aa727be8e925808706510d70253deeb43a6e7ea75d91344b5eccb32f0d2efd64b2b8b25ff221e6569829977024c2bc927aaea2705a97e9b27a645f45b280f1eeaaec411c3ab6a088ea83414844c16469978ed0f5898cf838bb7fcc0fc46238837f71c1b6293eba81bef69b874ec6c7a0cf0deff2be78e5c2c8dfb45c5f68968ee571d2615e378442b5724d31a7866460d811dc09e45e93872383350c211639bcf162af99a3cc86c1f8445eaebd95891d3af4c2e0298de3cfe56c95e57e13fad49c663581adfac89fe9cdc1bbb1e3bac098302a938b72068b4550e7f4bc7a64a354d41ea6d9680bfdb2df3c03ae7f07939cb6cea9ac6d78ebd9b4d9318622ab0a39d73e5edefa7155e944f364b83ac1996f91a23278c1b705c044bae881571cec01d306d77da56531191b6dca368c5b3707a26940129ee27527a92da65e37e88a01959ef8a0c80263737ae41eddd0fea6ce3627005136f707a9291b59416f0c3768b7bed6114ea495c0d6e869c910813997a3d41d39c59e37e41803091fce124ab61cbd225dad7a1c288ae557b01d4e291aa09862a01c2297a3122217be1ad24a64065354bc1be41dd1fdce07e2419ccb1780d015dca5106da054530579425acdd779c5d9b1d50d7480dad1492ae7f9c27dd6c71d613f99a71ea039ad0b76b6c1e30925f38294ad5783bd1600e770386284314f63e8967eb5444a563fe25ae40764ddccf004beeafa09423f622af7399031b37eba917c79770ea380e30bb07c813fb9cca13933f7d2d6cfffca971d62bb5820f5b371cf9d897699af38fb9cc04b4aa6cfce0b2253a6ea54cf79ae4160bf18f6885dd1203493b5fcd5c684a34cfa86c5f2db5428afb61478c828d8fda1aff94ebf6f0b4a647783bfe08e350757f8fb313b9b4a262e830c2b58fc3bbe00a8c0f51945323157e738f7e5221495d097b82fcc5bdb2f176100b3e4e8fcf896c8fefd5b7463ada4755d729a275ff5cb37316c5bab5fe643380af85f3ec44f3ee48c620303cc3d8be34de48e66bcc13b89e61251dd8960ee1a908a2bec92aaf2d09627ca68a07a0a434b43ec3247c58899ed30a8b15cfa8053115ffb0a78345d689724eb7ffde2848b169212c80f5de07171ba49897e831fba1b51930b4fe9aaebad2244ee684e0f97a88cdcbd75d46e595c1ea91f9f1191a5377fe55346502e72df906972c59a93daf6a67645a07f003644de11e78ef0836d75ab2ce6dea21298728eaca9a0b9217602fb750f7c777f59ce34059c89bfb7650baf8ef7f06b537c6ac9cfba930f97cdd07b0b3523a60494feba090f586584b43efd47711a604cbb13e8698f6e7a5e78718f049b64680bd1ff0560d7b35e684d7b7a36aafed94369688aeebfa300455afe170021505499110239b8f158cf399380fb85188637f625339a2fec86ac931dd7d79d96dc7d78fb7133f5786b9d72ab79a2df32379f2626c783527f89c85f5165a5a4be56c2ac35a1b61f252174280712eee7c49e5277e97fadd3f534b671ade928e1171fb1baf9a0fe71ffa83bd94a85d4d38917e5c2cbcaa83232eb472a837e53d84400e938468c6fc2dfe19efeaac82ae2c00658ae413ce55d037f87b3295fb7c181b234186bc3d4534706f706b26f2395f9e5087bef34d0b0ee3a047a793ac7063b46f2f58a145dbfa68861bbb652c60cd256433b3342ea28a7c42087ca4ed993ae703e29a6307dcfa435c42459fa13ea0ce72d66368e622c099908ebbe37a36dd043163def705c6bef1726a23a2a30ba11340d77cc7f43fc05b08057cad52d35beb4cc7f2be6164ff4f6b6e15e5d943887c6040a39bd1f5cb22318b436ef185a520fd66acd5f97cbc954a81e21640266680c2a3507400a802ea992a698cb6d91e9df6a2a7f905ab4c270989dd892b613a1c425d6b914d609ec8add1d01d54625e4f82e300fe6b248bf9db0bde7c69d8669dbb8d6e3d0cc5afdff73510b6a1fa504dd030232831c5c7c83fd123ea9039c101f16ea6687a0a4e84fe8af7a39d701162ce2efe07c759b420d66586b95aba97c35d45578e3ba5cfac49d002ed18b18367163a8cd2dcc95eb56f9969ab9c5156adfce612df9b53fbf7fc1bed03b4cb4f5456b6ebd9d6f40a29c5b5e5fb445bfdb2ed86370f9fb708a619b6137bf9d39612527fc58a2b0448bc6a7f35cc5c6eeb77650ee9be0e20058931cbbe68e02df51e73b0a7c47eefa0e6f9fa1275cb75412357c367d7df5f5ee0e158bfc02c6d974527688482f819a72d515ee74767937f75876b45c611fd5dc4b89f7f1861f0d397043c2c67f69c87c7679f78d86f8c22d29231c266518fe47a4c90707845107795f9b07ec32ec1f86143863cc3121397d32fcfbee91654e0e43324a57455572b21eb89a40f7e4eb7f8b722d5b14ad096d91abb3a1d832c25acfbce5b29d9242ec0a605bca503bd45af0aa555beccfff26607ece5433d3562db4dabc2fbc360402e746c52542f14029f47e80904e256066cf2582b711fadd12e31294639f851c5da422999b00619643b1a0bd4c132027d8aa3e0ac54ca2dda6d4499f90aa2bbe50336b8243a3884f9d4aec2db18daa7f7d1bd2b47068303b39d9a6f819b5bf8aa67c3d5f5c58ea615d4ff9b5d9c34ec532c703e638718508c95e112b79f9a0f533be6d76f9a03521ccbcf11c368796de3342a9892fe41d87172d566b3565b503e5e89ef8f55da1967097205ff9ea4b55e9ea3e6acdb04bae01a9a50cd5a7874de2ed4e0e9fd63addf5d903cee2a5b1fd98792ab08e4f7c44eb57e97b44ef31b98df83cfd084519f7a59bf3cb66da2f0f934c85eac6fc2238b79913de8fe14f6f4a3a3c1773700edd71d14f81706b2a42e2031b60a3c3733ac0a8b36afa63552432f8bd65677a00254b03a34cbab1a264805efbc69805421d1589ae6e3b735b6648d7aa8d6f3a6e2f9816b9b40c1eb7be3c57647e2d3dea54f8cf3d42c640f4efb797fbdf0236ea1ade2b6e21da0c07c75ddada023e86db799f115ce6a23e15dffbc3a81aa941718abf11188170f7f2df8809efbf89094fa8b395a32a59c6a97ab1f688c4e6445642ff8430faa534106e91f5f7303d6c92c38fd6b50439d52c568a0f5575eb695310f2cdecebb795933b375777b28ca973150573a35e89f6ba4df59dbf7e4a87401b5bfc6545dcf217e2cf7cd9fec797156b169b49bb3f7e59cbbafeb26a72e7ea6fbfcc17eebe5de13db8384c5d2f65c0f7876714850ae654304651952eae7be0c62822d33be19a41e19416bb7673d0c507f9a484d9809f454eb8b52dfef95e71798a9c327c2a79962becd031a52ac77eeaf5592dd4ad2f58defa024cf285f3d76fcd7cc1c5bdb7be962af599161e38150ae60e30e4c17967677c482b14761ad4ca76a6604293bdb3f7f46bd5a30a0baa09d8f7a085bfdd104a8d1166a49e8ccffae93b49c4db4be9aee9f94aedce49097f322ed47d921a4e82eafa377daffdc0893eda60e58bfef49bb2891cbf7529649376b9c2592a14343b1137871a911ef81a8d093b80984e5426aff3b7c87bc2f126a85311340b2abf9342bdb7d80cde9ddbf9ba14ea717f867bfe706ee78bfac0910f9cce6d32181fcf7ca0786e53eda547c0dc41a208d791794d40fec6233bdd4178e209b7a14e2097e8174759d5f5c4eeb75a834c94063b4501dbaf2318d2606b7ac52234c37ea7ce92419f3d0681bafb33b814d8b1eadaf98150156c4a5f4b8efdad2a640adb5b1cef974a8c892e119bf71bfc48c8169c9593a9ad0af280087faf08bc0aed600e481d4861d6e7eaabcc392258594ae67bea85b8df2ee34dafe61efe48bb5ad283e883a3a6f1cd1b11026c532e365105b57789578c9e074bab0a50c0282cfdf1e2b1142ab6ea9c901cfdf9e2a9146a6d3571f158cefe7cf55c0ab5b51ac831ed4ed8fe383790b0774290775469c05e9f62e43f286651b02a2820dd9bf26d47c4807b07bead84a9e1f36d230a2bc619bce9714ed562ad0d02f1bdd6f8c297b143de44efb0fdd90c07703bd1673281407f836ef39483fab91a9512f10aed336d3f7756136c6dbd4a74f19605e23389b72edb6a0700c0049e13b49a4066cd336f294b51b62267cb1e95720505f698ed36ca541e82016fc2a3492534676d7131f17eb5a2b24b0de5c18eb76ea630ff440a6f9bdc5caf5c8448388a36d8724d19467068a9d316e19a91557e765a20ab4cdfe10afb2c0ba8aed435496fc2cd61d14d65610ec195e34e85c79c42cc5c4c3939e3096febf07b38aecb9edcbbcc9eb08e183e84bfdd2581d25caad2d371238aca89318900b185fa15441b3b3fd2ab78c201451cde9d082df1b2a7f0a9fd54269dbb3f3f48269583410cfcef12afdf72c875792b000d03d0c3359c8fbe393189c549e68709ec9e1af0814887931f6ad53ae68cbf39fdedf4f7fc06335a5369060a799728c160fde132945c2542f9bd7dc051af50b99c7e738999b7c5e4a96ce0e5191fe1dba8c0b7e12e9f33818903b869cb0d724b2d9579e6e22099021600840be4f47fee391abc8b8efbaaf11e542dcbfc48b867693cdf73fadbe97146c8ad5ef910e2ab8a6d34b6fe701d60b2b8d239dbc09145d5cbf5b790b3ecba35bd37e5de5b72b31a5ea6f7c0b5eb2ca61df45ef24c27553a8b8495732be54ce82a28a39c9ba3b7839150cf2c6cf8b718ed77207e96ab79163621868ec1379c39ee4c75a7be4dd210c032b1cd3545fad57dc611bde6c2f3d5a6e20f4dc213a306dcbbc6fb2c8ab28ec45a74ce6b05093d45c4c883d5864a6d092280500dea22d4eff8de8117e0cee03d13945b0f9e64bf0cd2c61676a044aec6551cc7a66c64fa8c4869ec99ace3f2441c235904d6a23a4b7e47b227402980774deda5f9bc9071375a8fd63d7740d064c8ce4ff3943dc30f402a3768f2bbcde12269126755bf3a7e5299a669ebb1206fdc9a362fdf156e4196b950cc692dd38043154c2103266419d074602e58509890e49de0f41028ea1a65f7b4146d60fddd3c13d90df112efc43cb21bdcf8b5a6fa2f76092a6c81528facbb1c664a978d015728a14fe99d984ff9055432ebc2dd72e0a2c75cbccdafe66c08fd5ae6004b6247d84bcb1ccfc506834530119e14176ff1c0c6a796f2d7b7c075907da6c76146e79321020998968ca4574a7f6cb498908396a893031588bfe67a994d2a51df8e59fba4b846cc35a027f8fb1156c8298a02d83f9da259e25497b6362a4842ccc79d3bcc823a2ae17fc4152d719c850580970174243500f728e46ee5707d9f1976fa87b544a9e71043bc66ac36f796db0448ae57983a44b302e0c90e0580ae1eef304a02706037db2d01778b1f83b7b97b826033bd5628d8a8d07968395adfc0d77db4d05abf44e0b58d9acc2e3f6b439e33558154fed71f4555376a98bd15aed50ecffab2e818e35b1db9dfa1bd768b1399193c304247bfb9b5714f702e3ada44f92615d4e36638fba283aa433b5ce69cf79ce344bbea9ec04d9f805581aff0e9ea0bb13cffe933f775d2118ef8d032ce0e4b4805f672ef794774496f7af4f449572874ffe525a2bf8158491858f65b80c46b2362dbb256f0e33a8d03605a0baa3e7a6f5e58a5477f834381c298f65dd5a142fde6b34ed50b5db893d969186e97b74577496d1525be89b1641b80a2e0ea68a0d4ff4cdd9aa9e41214d9e9d85b543a90210c7e8c50c396ce0f843b93fa0247384fe6a56788e4de82d6a8c7088af596ea793c51205ca046ef6adf81f926d7e8ceee1c10b40b62fc0fe1ec25ce8ff4535cf1b2be426558a063ee9e623833c9d47fdc5291c7c133e7acf6cb9d0c826b8294cd99a9633a426c9f6deb1190055f422d69012951bbfc3a7f5505a5d39e019b34cbb18fd07f67fa21c5c2ddd9aa124adb16150490c7b23a038063366301fb82e3753ebe242543d5e4eec0773467466b44084cc56a6eced50e2969a96a49ae203096b3bd6413a66c433bdfadf89646a5cdd9be362a00158b7c266c8205654e368d2ac9ba79cd1976d44000bc7adaf0f1dc0ccb6d0d768796dcbce2c4be4f4f9a71d9f6137fe4fa31fb18aa81ad3f826966c1bea24a72c1270e503b8a2eb043b3071c1ecf912656a286ab822c0638319963fb5ccfb816f21b8e4fe7c8b29ad156e196e4b87d0135eeee5ee073224a47204143143b2e1c812bb73627fbe2eda36351b24adc8a788b6462072ca1e94ecfdeeedada8f816da77dbfdbca1161ccd7744c690d257938b62fbaa15b66aaed0a5858bab59cde63dd8a4aae4437f68e13dd12de26ddf51da9d4d386fec693f392f7c5d1d948d634f744b5fb024533b746c7928f6d1802a4389635cb1c7544ef688ee63e481254f6192077303de989df3baafd37cf2a0444bb93d72cb6db2fefb579dbdb26d7cde79ccc17cf65f6b3fba1553df1e45dcca1b32de79713b33b63468dbc2b7a356bba63c0f8ca3c736d6e30e37afaca07a277b426673eb131976ecda534537ba1b5ebe3f76e6eacdbd2506f0033d578b8315914055715a5820addb5426f64ba7b95c80ff53f5dfccf8684284f68123c1dcd7b0ff80f0a452cc18ce5adf6ed8cad09a877d24f2817e15517f6657b6a7b13c4e15c208a342ba18e76a18a82f2cd2a88f7971bb0459077ae14725f34c1eae2cff6b0cef27de117d4816476e3f07db2c3d8ca2bbd30065c6ecf4fb66372f401f515ef49ad5c5b792f9feba8f6b29dabc082a75bce67c2a82fb9a600b89bb9a63a125e41bb476c45b4bbbac815aab0395185b9e1d59a94971049a4ab0f72d0babd424de186dcc4321b206dffd0f1be3755dad30eb45cde18a195180eeaac62ae5ba3455a53ceb9c825e87e29d18459b489dbd7d9b669efc9516307fadc1cbb649f6a21c0f975b608420bc3942ea23081bbe424271a26ab5e858248edb8dfd6515d411fe210439938265441b688d8df7ed894b165cec236f49dbe508ff96e7e2cd5e72b78fa48ff929b009c885acd2e0067efd6515b9e36d0f6716ba76334238690c18d1162eff42f4344b8fc4109fd5dbcc3c1edfc97716be244302343df9b524cf00d11cf1a9e51e567d4e1391f9c8da5d5b471a2856ff0567b991de497161af8fb18a60319f08c1ea643daf917436aa30f51b7371dd8593ab02d6b056e109f06f6e1b8c90ef3147b2aa5b4ab97a866ca4ad942dde5aad9733910adf3af75ad736b7ae8560e1050994ae1542c646f742bcfc904d9ca3245f7bab567da3fe9794ff9ae9ac9d70df215e07aacd152e579500727cb5c46050827a8cb532a17349582335e422af61cca5002663fa74e19cbcd896fc7545f9f90a7a937ae673ab301fddc4496a80bd49ea4a8a8535f1d651d3c0793d4c4572d053fcd007af74452f54e5593645ff5fb38f8823a1905f841831356dc449ea716432e593a9dd1c2893c9d6cdc03cf4ac91c2f9ec8895292951ae2ce93989f15c596eed88611450bf39225ca09d6e40a47867c5ce1f2f32c2b69d85f320571bec9194665e701a669df8c4646067d083bbcdbca9f733510367b64b8821893390d9459f6aa22d728cefd8133b639d3230cfda33b3d92ded8e6b181311d1569f515e4b86806d5a7d425478b55019d2b3e526d6cd4ce5b49432bba90c60ef6f70ead20448318f839e4b26d0555b85c097e66c954c1f00aba88d719757eb210f4d43fd412740fbb42870d00e247dc64e48d009a398156983d5e40e6ee0a0d0581e10811d385e4b45e7aa46db0d643ba04dea9c9f9ea02adecc6111737c3744b4fd2de9b3b9b345e4fa8ed4ba102943f95ceb6df4f10f3eeda88795fdb62ab90b9c2c2767e244a8a457d316ca7ac23b30aefe58e38a9a7263fa770b4133a88d71c6680bb3fa407dd7c90ff5067eb3b6419ad558c1ed4cd39ea2cf811174bdfc049cc5cb7c70a7893a6f4b3cfee3a37751390df5881e2475f4cc055dcf4928e57f75ca52a125f134e45265a137a43131df851c3c704b14a2f544ba5958d9e1045b91fc32171acb049ab6fa4e46673e78cdede837ae294ac467adc495a85073842d126b196393285ede7ab8b996fd7f40a1ff6b3cff0848f2a5981ee9c7c5daaf7677295f1b0f4f32351569f11be2f8031a4a78ba3af6d58ed34ebe82326cbd394c68649813c887995f95b2a2bbd4aadbdcacf957e8010f92281f8c905bac2b25f52a85fad0dfa9a56b09e3121a488b73a6ba137d8a3efbfb14aa97e787673b85412426c0d9bb5fc7bfdcb35dbe35ef56f69114d5e5347b815bd43cb861651a9767edde95311fa21ec82d5bc8354e811a15d27137459a0cbb9509b8ffd5abd23852de4a3e31915a00a258cfeea39ed424fcb78e0c0fc09f9339cbb7b9ae735384aa61dbd1dbb77f4d236a678c1c9bb6227dff2817823b638aaaa82cfa12610d3b16953b54a8088a0c617e8df9cafe854642d739b77f5257495279cb37cd20ba1dde06cf47ab593b019ce64839fc0b428798733b7857f1adfd05e95d605f76ba3c93842dd359034493acfd3181413345dd573f19c6cf77b49993e3b59aa232444d30d452bfc124168d5539121b4e84bf580dd23d45fbc905355ac5381b0a58518d9203672714465c8b5fabb46a29dbb41a5918f3c236ba6aa248f99157647426d22611905c4caa390901a4c3178c30a527ff5498f96a2acc935f92abbc5226863f457ae25e7a4750f15f632f19bbaa74a87223f2b59a91382776dd1caafd63319be3c2df2bef00bd03da6b46da6c7dd96f179d14dc71343cc1319009f83bbdb23bd62bf4f57835ddda25e5f8deab4d8fb76dc4eda06a7226fd515e3cb2e706431f91c763236a64ebe97ff50a164fd620a529e3bce781a08d501f52a8505acbbbc23dc3bfdc12ac70103e44ec1b2e5cc53fd8a77a0697c548275844d3179f15a0c1556ed1cb8b4f839df15c15a15902ec6b272725679470f7e2cb976cb9a094ccde8ab484e5618541cf2b4256ab4003e129ccd9118d7721c7c358603ee037536a632b626e9eef84c136921abed3455910ce267f2067cb58850f3a5a9fbf0b3abd52deb3e3f966222efe618c7a9147aed4e65a98eeedbb948d999004cd68fe83af532c5efafd9a993f7f21fca5d4b30316766f4861b42ce60adf9f9ccb8a85568fd15cf22efd218b29b290765365811df249be2d40f557cf6279d3fc11f443413aedeaa3ca14ad6bcc2d99e03d17dd72ffcca0f84f54d77e4688510fd93051f93056d2fa7f22361814e2e3d74716ddaf9faf817f63938e728cf9d62a03de8f17ac69b2b1cbea27071d4256933fc7959f2205fa8b7fc4038a132a81abf531943f0c20a22b65445df183438dd8da38f27e483eb2511ac1527380dc046298276de176b15c9b89adddeb5acfc2e73c1391862bbfbfc97a82adaed0f32e49285f39d610c48c6e58329094b2bd2b451be678c08c15a96b1c30fc3b0c3a98e3edb75eeba8bff1fa84a48821fea4cbb09d2b0bf7d408c1c990f602ee1505eeb0dca9a4b9f4e711c1491464ab629c86b5f54980f15ee76276127d32ee135701809af9c3b86c7cda9092ff143fa4b78fc8b92b75524f9cdc8e5f6f4edf6eb0669df5baa0ef05c4edad615ea6182731ec4a22782bd5ced8096d343855a3e2d48e5ff7f7caff30dd0839f0ff4de14b563992f2be18cc97fa93e1317a27f00272c343656029c538dcb0da5d7556369ca6262ddc1a5b10e39c54a690def54fbd55745a027fb9d4db4816ed5e31955c90f0dc29ddce537b6984897768f0f047b8103d75d344c3301c9aa1a24baa92ab4112ea57686e55f35d0126369005bfe7b97e1f277af11edf2236197ac5c8e4de69de40cdc7ea3d66187ed50ef52cc6f720f1da6c62576b92cb6fe4dfeda2a2999211176133318037a2e942efd6398a85c2d558bb3fdde241e45f49bfaaed452a7d313bfa63709493da54da13f43dd93ee7c62a79b035e188f8982695403df543f1df85c95b1fcc43d506b64fc4ee9480dd0a5bd25e4cc19f3e1d4000c3a247e2777d99ea0015e29d2366b4d7eb07b92050dd9fa9535171676857aaeaf7932da427d226442dc5af740d239e2205f0efcd073c46a60405da927de517de727b618ba553004035817ff3e736a7f7470c2b354816952bed322e5fbc826729d2759a3493c096f1b1cef9d71f5e98eca81af7ff386ae4ecc7af682cb5ff466f43e830a169c3ef0851ff4e81a2ae2fe6ba767ea484a7d48d4d3cc2d6a2f3bcb336b4ce4499a3719c41c50eadd53deb88807acea0eb8ae49b70e7827368f06d3cc5367731a6caf4944e7bdc682119754f117a58bbaa765e6061cb42b007d3358854db2a774c2d6eceb05a22f3f8fd33570b69aeb5f9d481722abc824704c45efd7a7a04ac97f0937b24272d8aa76c35461ac1a7b556f3005fd54d5e1cef78ba0bf0640063648115ae8705b6567462f3131e839e5a2fc9bf000afa92221a49cef39f4f7a066667d4feff23ccf834604a7d0100b6c1760a0fb423d330815e9884954209e73499dbed8a9201fe44f4a8516bc0573d4899ac8232c217f5cef70342050d6880dea3aa787c1e55867733210428079051c28ecb9e06ceb49bd93b15b6a2e39a4d787763eb0ac929cd6da7af60e67b8ca3f1c3b0cc6bb6888dd663e2468ebf981f2df5335892a305a59f6a51a9555a0424ad623b57e0e911daa94972288491bead6b97e3f9d691d3af90fe5b7e4e4d8d12deb3750a1a1cb1737779cc3d2554f9c834e6ddac87cd35639f99a7745457eeb577eedb987e631a726c3bb5565aa3847a8871da7dd802f999d33ba03ded76730b981972766c903d9bb1a1ba2265aaeeb0a39423e56abcc20526fe6ecebeb5ce1149cda02ddd00470a499c3ca6eedc8f884ec8887bcdf5126271c6dab312f22fa203b94845e61e8e28bc83bd667075345f0444134436bde27a42a2ce49949cdc376de555f05593e53470ff734059cb5cc1512aa43d12f981f7ac55593f499f65e154139f3b135f390341bbec213ed996a39d94edb353b667311fd231960dda5dad409f7d2de23213880199c0c8b279cad3ae20de641876627df335ee1525de6ddfcc6517b599265dcf601e5a5f2eb16c415a3fe6d1874c74489ff7a57e028985db26f45bcb412c966be9d483157af85755632b32843f6ef0f21fdbf11f8ec0967ad7288b70dcf53167a1f843754dfafc5693b6f5b5f83bc9b1f5beae19571854aa8b7593d81a219456e4c85ed132b4f30e7eb588afe110b714a432fa6d0d1e1ce5e9088ec53b7191a380f6e2d4e03361aecd5010332a789dff02b533078fd0f951f2dc1eb15cb4485d46bee3e3f95e29b4cc7b22c90fe3968ec3a09305fb98cd2a384150b758758c211f0c199cd1c4cf229205efd30ee18cbd18eecfa1647c7d8d2ba8dfb8cbf2c5eb0b70bb90c24fa8bc77622fbdd4601d1c5622959aa7002f9fbd8f957f7f8e283b63f949ae99fb716c1cfe0db3e1158f231c356d3a26bbdd30892bd867d0fb0af29ca83c13246f623f36f066c6c2480c5004d2173bb60cf503bcd9b026dd55df3635704156e4ae26faa485101217e73c561ca78091a25a0a4a7cb6cd42f027ec6af42b287445dd6afb9795fd847fb54ef24b0c6feb9c659bd70d44778dc021e317f9a4bb2333cbd7066e05bf3cbad769a31d26f61cfe6c80a4f846109fd4fcff812f656aec1fa6bde019a453132d7555b9413274eb2c0d2563f49ef2596b9a4de6aa7b8bb7e48a076d5fac7a6fbd9a6375bed04c3dd8f1a597fc87f6d79adc55b66a3c320ae8b4503072145408498c296a159b992b3067de15ecea1dcf8e35cf60be37ff1852d892f5c2a8ad17f155ba8a75723a8d94e31b0eb406937bd45c4a41b4d6d874d2d5a7ba125ea501c82aa858cd6019977be103b7884ce9229b0bc80dab2d9931d57968d7de7eab09e623f8f0e845f6a2f2b78cb26b269c8c1623c55d98177f45485838c86c5f2ff9d985105dd5bce5132d14c501803859a72e22343aeb72c68d5c67e66cae68fb89e7ea18ae5a466f0107a6ebc229e82940c8a310d5ff413d90b3324db6ef8a637d3a32407518f96fef09172d1993108e5e81e705501ef1dae30cb867ab6d109f62f1c3026c363d50255f8857fa15a632e6dda7ffa661f498af3b08146ff2ca4b02b9d1abb10368c997dd8ee39ec83f9cb84e531eb197ad69653d57b23974d0c2acb91511422a7c9da4c18e340f7f8376e6936b88edd1aae839ab59b185081bec7bd71cfb8497183af336e295945dc42981be1dcb863d24455367ec9f2ea25eac62d737ec916b7b452f8addf18d2eed91ce40dc020eb4959b0eb643e49500feabbd5e8247ac953b269df8abfe98d372132500b99385bb45a1e86e0245ed1b3d5db7e82f8d709bf5f9713947fe6f34f4b3eafc7c1d36a7d8f990d755bc60894c5ff5367cd1ffc34f526220a11554817539a8e252ebe1d4c3ea9279a24b4bc6de740d50b4aede7bc12e536d8fd6615fdc53679087a8d871458f49cefe6bbaad5793dccd8fea0eb5bbfebbf4b26b745e8fca793ae89a8cbb5623cfb27d8de48380deb5764d75cfe807655526cd747a18cf25f1052fa7fe32ab4753b1d96459ce86b664c945035b5782545f308ee534eaa2e4f1c889fb0d949e21aa9dfcf78e597572e3fa31d9729d744bdb4265ae6388f6548e0affd8c35e309797f75e7bfbd9e66ac7092e951fdb5eb67ffcdf4f8cd9d3a46c99d6e84e275de84363cf51e8193f1af8001495d989a223daadfc05d7578dfc2d95f8335bb0815093f3f14f6dab93509a632c14c1538819d70511333155cceb2526bc5a40b853aa3be2926ad22e6186cf0e13a1db6235928dba9545ebd248f634dac52b7807a5b21870861afee1aa31cc91d26495fe4031184ba1befa614dcfad42b49dba86c52250e283d2b9ee0810bffcabf746985cd373213c0a79d694e61eecfc6d8be659f39420c9a151bd8c32fbdabd4e0b64136ddaaa030b14d525049cd26563295190ae594640e7d3d3a9b89fc45b90698c1a3d2ac9d1f892d0a4c47b2bee0f8d54a8a8df269ba37e46b0e83037fe22c3bdf4d59817a358b672d6f2ec08ac70c7ab3a6c64d5efa23613fb598b2ef1a73b863b9ca3985133921be47420bc214bdc423c217e0c5fc983973cb1729dcd36d04385c274de62c73862badccfb74b5cc58c446eb5f6311775326b3bc065cf2025c28402e773f10976b6b85060c8ea62107e2095535684cc386395ec4f18604ae78b03428cac5896f30d8c196b9a559b69109a44a3884c2824dd46f36b04843f5dfc71cf4e074607f7266b5a7d89ff49f9514f6d2bf8595ec274e8e55d5a84208ef107506a635a3d996555252484bea3ee85d2f528b164df5055182a9adf4e00cf784fd4acd3e33f3077f178d72dfcbf784fb1ee6c8d170963b0ce1588ecf14515e5088f8f358a4f57d5407999ef6e08c72d836801af0b1ad32a69060e0849cd0f3d2d58234073b055e09f8a00a48d799818cb258e3e793b9d0d51f5e4a83c3f739545dd087e1844769da7b4ace967a59a4d8e466f22be9005e37fd26fff51813987a8a1af6cf5d37020b2db971222b048f4680a47b046bfd5205f76dfac96d5359ebddb86d51cadcd66adcf04c1139dd25a82967163a2a51ac2fc1a659d4f50e49dd7deee85109936680c2b30c12256e148e0224b9caeea984f995143c13dd02712a625a0f0429995e74a6aa4b0f396cf5418d6461c3621fff7461a57e212d75685974857a3e546c366ff38e285b4bacfca032cb460eca90b0816fe829d4374dd32048523d43493668f00e0f27e1c6e052a915794eeadded336fd474a4d97c41e15e2be3a9b2ed7c90cfb555833892bf296cee77fe4129f95770c24c3ac74d65f15fab327f880ca7928663c44ef87b4ec8f4a79af96f6075e78c6bd44cbc0a42632ddd765fd97aa4bee1efae4fac7f50b2ffefe8d4f1ff5ea7de4ab4518fed5d2393c254fa5d81fe737e4cb1cade6b20b7bd53d84607ad739ddb3d0725b4cc872b4d8247be577fe94f0eb7f74bfcfc6248f573bf99ef878f96c3767e209c996c914ed976b9e7bd6ad8d6cad65d8d2fac876deada3606a8617243ae94eb348c9c06990d9d8e16397ad78defc6e4585b480c1c73c3ebdd649db1d8cfd635f28444f2a505942bb44da4523d2ceb9d0c2136499b0575a6fad69d7a35ae5cf4c964ff9d883940c576ed77132c9d41465da50cca1d76ed0f2b9d16cba69d587f70fbfbeb020a7888bc2fecd8cca2ee724ec1593980e05ecddbe6c145f90e7be658b213391cca0352a2bbbee1f2541d86b9aaef34d29942180dc1f5343d5262feafe4c0fe9f0ef42a993a17fde3b90d4b04c89a31a72d6ae3600bcf3654f157e675c5ab19cd5f5b29aabeada83c978ff4f73dcd7177c9a1842d3293bba8024c6f39c1c3de05bab18b97aaa50c5760462ddfc1333a67c991a40fe837780d5946fdc0fe0c33a17f402981ee8ac8ca8dd26a4e4f5186a6d962fa53f7e2de2ad139fa73f262aa12526192b38b15c44f1571d91278a693d3396aa80f662fbb44267f06e3af679f1ecd82c1adeed758816628163292257406ddf3c218cf295d11ccee51033e2d7ec6788a4d06a8a6de488db847ee1fca46397bee3a02cb0111e92e24e3b2a9ca17217b5f61b5b9ba91917c212c172a647738fdd3158ea56d537b261bdb2c28b7ba95f8b8fb0845c6573bdd751d06e03ac2b9571c4aef9824277bad8a2af38c89e9a07bee1f6669e1de99c823b903cd0d8f0cc58571e539fc39fa46f24f0520a0deb5884ff63b6503ebc72dc03b9f584a6809f6d8e5e94c3a0f71d3d069cfcbfb48b4c45c65a16cba6321f7725f49bfe2891af50554ee3b8c0503c4a58842f1c8f9664795a14ad2d3d97e06a4829edd8f06a6e7142a7c528847bc4c060011d3b7455aea7d526f7d1cc0cd321910e0b76cb7008638a01efd470c347110821503f3615eeda4017ee0b41bb91ffc1d7508c189c439152bc62786cc250302773e88405e50d2075d461d37f1d08f353782837d200e5ffc974600a0c8c88415bac3afbdfe6881dacb1bed4a1a9bfd02d59037bf6b45fa74e82c65214ca7bc8d813ed09662bfa71694ca7f50098a5e423b37912a03a3809c05033bea17bf437dc0f67d873b40c01290870514ff1e3c23ccb28b3ee8e9a9e55320f24e1066dee993c7184cc30af0d3fb1f2718974a13dc21f56948d5395ed0ac21b379c1cd8b635c224f253a65abcc8930f8eb7c30cae4850894f494b544abc9fc9a2d14e90929e14d3dea2175605faecafad0523d6a3563073cf42acbdefea552a8a7c7a6338d0bef3f0c842a24c17fe78c068ec7862d05dd3e32bd6b2eeee50acccb075238a2f803e6ba004e65b74ac6a4fdea24a5a2027d20b41e97b0794821f9b633ffdfc9fc484c90c6b5919c99408e1fbb9111dd662b77847adb8fddebe9bec1a1838cc7c444df4f27fd9e4b71e05b3869f020b763e411c8798dcb89d9a68e26f202deb6c813a12506eaa937c42d71b91236a628491a6b2637b87e5085c9e89c0c0506d4de1e88a56d2edc438d020b6dbeaa84682a8f8a66d845b4f0ab84bfde6372b95fa77b39bcfb17adec463fdf7572c4033e93323cad4896afda5d94ccedb7bd68f7f1e7b38a4a882adaddb2fea1dd8ef0392f6f41540c47fb71367748432e12ef8ef34ab28f44ca08bad3300c1d46a091a887a0e9c125e31049f1a842602797883d3a6205b1e5d4414302ad11657c2513de35e1f6a5bab36ffca89cf96468a27c14f5d2d9cbb1c6348aaab797f14766196f73ffb88ceb950eb2a65af2954aae53a9643f34ca32c174ad988a63ba2ba66b434e561cb3f44d93133768fe130d3c82cffd129798b38a4839770f21d48619950db5cab248572c544b4fa7876f48e0458cd43c954f2b31a6aeaf77c26e3800075ae9852dd67fe1767517f88be2b76f4b3e3ae7a336e75004267da4801ded95b8ab7845dbe072bedf668f6db461b291ed710d38c336b7c0a34d5f1b60a64dbeeebf25a5ad28d28b2c021ac316f0cfa69b7da074f4c5edef7cd1167d17d062209bfc58fe66d2f274c8f1dafe4b38f3063eaa4189f3358b2dc3d8c079cf7fcbf05063d2e4cbb00f39d586d185d722927f82ba5db987d37f18146dc79de98c31e2fab26d83b9d4a6d94c4ab55593867110536808b99fd8a2d323475981c936a0956cbf961b646a3a2cd14dfa6695ba7d29b1c606e04c5bc86c9227bbd554c13247e9353bb9a247a9865cf333174584a4e7a06f1d60518f256b51e6326691dae1e7c0e6abeee0163a974ceabb2fc40b4925dd4afde364be1c8f6fd5c90df25145a8ab77a6e0b153202fe4776d9ae6ad06423d2571f32af091110a8d0d263b3bd9948e2ac942451bab5450dd61944fb364c000a3246e56c0e676be1d3723c9fc521cbb44b37876335efc137d7db784fb2bb24cff31a508beace46c20ec4606d1d8bc950dfbb7c1b46203f88078e25ebb2656a8904b45c79dc83a722dc646901f898a722e695c1c51560e56736c7de7e7b6f0dc106895bc12fe67ccf10f57887eedffa3edcdba13d795f7e10f84d7629ed67b25c9c6380e216e4293e48ea4138c31c6ccc3a77f97ea29d98624bdf739bff3df173b8d2dc91a4b353e05af8ee1b223358d38c804b05da4751db72aae3515fe6b7b530033685354dce667889eff566dd8fc4943b884eff04d9c43b5f40f0a42769571d282117edbfb9fb89cea1e6551f57431b8a9bdaa31a3f001c539cde7963426a3e82353dfab8d9ce3e1e1c39a8a58c21221dbcfe8f6482ce490e3b5d4a775b685ef2de6d028d018ea9dff52c3f85d804a8333331c624cfa3ee6494fe79c3ef82672a5f33f0654fa71d5cfff265ee506a48726f05db875b712f70850b5de71acef807aa0b03952f88911a7e9513453ff0b25f176ee811c1e902431d8e301dfa807fc1a1c91a07d422c09a960ea6e35027ed3b1cc0ac17511bf8936c6457e5a0d29dcc9167efb7b92f29139602d2f65cd784ddb10e52be005d73264e7c036e2e7c7e73541d9807b7f251cd81e4f902b5c20ecb3b32b547950416cca3d6cbf895ea515f19d6fe494d4911170b011fee7cde10f384812a0942f0044f862bd6b8183b3f47b8b01c816471bb81cdfb05109fa1bac22b029897e3e7e5cd12658cb4de420ab0e8f67724670f2efcdccce6eeae1d9842c71f313a19a6a1eb1fdcc13ea975e40bb7e743347660e239a08755f7a23feb9558162a64ef9ffdef53aff6646d1b41fc17b73d4fcc8f5337e830282bd098923cd99961f36ea28296dc15a2d65851205a4aaae9209b6f78b10de21e1288f3db9cde2069b8303ecd0cc1e641512a2171ab3de801d78349d5f6aba4351f7b1fa24c5fb648e0c9e43e4245ca805185bfb7cb1bf6e0ed784420f5b5d8ec7820010912ff07d59ce418ff26a1627e48b1934632fab34367562cbb512fad3046cf230b2d63dfd0f070144eb3df761c76ebb0a92db2cf4aca9e83f5a4b6575a412e2fffbe93f200b65f271479aac1f24587580a4fd760432d09c52d08a3fa44b3cf41617e34e30114e7a2b6a1fd9b1200758d2545d9de65f44ef231e6de566ee59c8c96cb2f26c00fcbb05259846c0bb18c321bcbac70a3642aeafdb36503ba70cd3165a56fdafc7a9e58ab566d83d31f1cef4d9e7357047a67ac8749ff7ad40d4655bc1db3f5cb252072af1523f3bd46fd966a761bb77223feff5722f6f4c8b31babf6401f6e91cc939292cb9f489d4d9fe0334188243480103d62faa16cc07c9c549f5f30c2fafdd026979ea207c076fe2b2e688952a95f4dfb3247a33623c94498b2427272e24b9ed505a261b698b57b25a46d84155c1bc404b318e0b915f67d9e6bd7ca8f199d3ed208ddc46ee71b9079d082099d0dcb9c27da2c88903a518b54787397450e71618c1aeab2f9b581af4f8ee8569d340ef73eaee81c1f239b8cbeb36c0ebe1f738852ef418b28a2932983c03eadc48770e6ced6c415deb870b3d0e8791415621d05f53341054e67a0ac60734bbc7d3998c1684987c28303ec0998801755a762d9f00018600f0341f1c33d7e76b3efe3efb17eaa227f96c54095a8a230a7c3d3328c7ed459a03f239d66d0979e2083d245687e29f12f8554fd6d0e86ec93e3ad217c1960da5ecc1447c440c35e84b0fcf74879d1da9703c025d39cab0065fe103249e7dd608c16b243404b7375fb078d1cb96c1cb6671bd60d94759c504d6ae01fd1a736678fbf6875b757293c528a2459dc9ec10872edd014759afe0066d54f455a82227f3d325644d7d2e932a86b1802172acb9a451820dbe866b911f42b9fdcaa81f3e2bc994dfa0c81f8742e55e9bf443f9253cecc1b750ff7b9cc0e8c753d15e38b9f5e49b3d33ab92f818c4746b5c2930a11b83b30d8f8d761845ebb94d5581c1e4e3c2bbf61c9ae4fabe7052c5ce915ba0df2e649937da2c76488d14da87888162b985b12816102ba90b4c85cbc0de7b9cdb893ebfb9a037d58f47c269e23a174c104642bcd1bf572afbf700b88d55bb2080f826b1b996e888c68315a3662742d4c80ffc60f7b1c353f4e19d7024dd55c42733a591b880d77e72aec7634ed6dae79891b0ea14e7be2177f88df8a83ad13d58b58eb44d530e42e9947a44935bf82c9534cf5f84fbd92de9ae4f40771b78c9868a3145749e4059ed7cd78f3674df4e2151f2b39d7ea69a30eb8795abce7a3103f3004321a8e0efc8e1930abae8707c54430a55b5ab26850de4185387600c555d1ee0eb3948d9fc5de3d774f82e728390ee209ce32057aa74be3692d3fc0c6a17bc683242240c6b73b2fa0d1a1750f0363e42f9ca69086575966d0fb2de8cb6664771b04545b64d18f985127e7829d2be92372e323ed6244927d3217e74191cb0c440e2e50edc7e35c71ad95ab0ecbd2ddba4cd5c4b90dc956dd728a94a62db75cdd9f8fd7cd7eee19685f34be1f9b1c35aa336e50858d8a9d332f4eedd72459f10b886b065d24efa20276de830a11ef588839deaddea0bf5eb88cdbc87d0c98fc5a042e7cba9aa5e7103c1824fdaa471957c4a5fd80eb9665f903252c4b08577866455c3f6c2cb63f546fa886d25dd46919c1a5d08497de6df9427bfee74161e384e5de5895d603390b0bac2119b98eb0b17ab7330e682afe71f8da92cb738d02087f1d2f9e694aab65cb347717253a072cf88ecc43273f40093cc1e6594c2dd1271bd39a5ff7f89647ec6dfd335b64bf85e8881dbb197d56121ff61c6bcab1973aa0e13ad97599c2f8583684c55961de866a6f3dbb78150a15aa39f93fa2ce3008969f629a3fb9dd842caf61f88f4af190a614b6da993dc6028fe1d20e7af5fd7b3d78ff0dbc0ebe91eafabd9eb7b1aebf2fa75caafa7a0685b94fd0039888e4575fee268ac6e03219e38b0f3031338d0a35c1e8d53cb4888dfc68988d1921c2612cd881c8327b588838846066c15897dbf7def98f76eb900f018a4f8e0e0b063833cf4e803cac1c7898eda5df0032dce8cceea156a76bf8334c8f5af1f360e8587cdc37ffa70bbcf0d7183f2056c37a726cc4b7a9a7b8f31a64e950159c7748a26423c6d30c01567bad1f3f3af4a8f203c102882db445acc2d2f5817590e7658d432928b94604a23de438592277298c2c7dc5c4c2a6497fc9984984fa9a886dd80b9fad5884018f274dff7610421f01841938c300e5ea6abe5daa95344c9a4867b53361062f4b5ac27bc62a83dabb82fc0b81e2fa7ac77d0543621b3fb4ae2e1a980eec5981e5b25bc546e4f0c7f3821b94c4fd66ec571585d108ce02273cb23bc2ce0cd50147d673027bdb1d84b2555069fb9c6c537dd54512c640f227e3e39101734658dffc181c780267f363fdbc050ae9feda068235033f6869eec38e204d2c199b143ce80884d01781034180eba5b01b7daa1bf5e6ce7f6376865a734b217e2b9281960cf03dfd162851eec4a2f51051ecbeb0a277fa0ed3f6d5c959a124f7022bfaa3ffa3adfca3f97b92cac5fb2e6580f388f102ac60ba98f9ebd2638624adca89ebafdab81dd54a4cb4736dc82bf632d45261f12a09d225600137af77583463cb2a5324886fbf0448e57b0774dc0fb0ef33cb3e306a49cc296004753dc124e21863edf119cdc9df1744ed88cbd82dc095e1c214a4b52cdfeeee2fb236ef0838834c576628326046f555670e6c91077f18b64499fedb7e4b0317e62be827afbcee66140dc0e9b270689d10c59c3fc50faaea93611eec0811041b3895e36f8377234abae3c3710bd79e6177506b4aef1efe4ec5a233101c0c9685931422c458caa363338ef16739bbe66ba94831eadec8cb4d27cbe36f1641802c2745db729212ddc3e773860ffc5c59d2a74e0ea5e56af658ed42bdeb7eaadcb4f8b97b4fa3465f3cb77289c3f5cf6a6bf0e04dfe1051e1670683bffc966ff7985e0f4c1903fef0bf58ced37e06e7a42fd3e3490eeb405476a9fbc33023faf7391075e9c0e17214cb591978dd5bbc83af88416ab569068905940b1952c97360b8c5b9608adebec18d2b501bcae41f38c246b2d4808c13a2487a28f908d2b31d9de373694422daed53e23c74e876b75ea3684df0b306a86c93be1b7db9d88a94d98303f98c0eadaa517eaa04a117b33c55c621b1181fd48c9c0ebd5217ce8864890762c033dc2a942493333aa1654647467cd1081b290bf0b6c13a29d27e0925faf5f382715277d33689a13f43194757e9ebcc3e195987397239a71d9571302f839e092eaa0c25a619862dcd972a87ad1ec3093d1f29fc4831b66b7ecf07d3dca7818f507ceb0d80fa98c19e3a075b161f7428eac8f28c0390e2b0c1dbd808c318df9458cd4fe895aa3858f03f7b249b665a72c17fc6d33d955f25051b1dad65944692fae79c405601c13c5fc67f7e63d9c54dd543d604d08e525610b7d1bbe1b83e6d929328a8c3a6c5efb70a36b6da074eb6e80e753ffbe12bf26330a8b424c20c7ec7f43be8055b9e1d61b6877dae4ce98ef98ce95e8b7baa8708b96b9c0b4cd1de9dc746c4eeba19aeab00057b5e47548e8b74a25e05457fc385d78d6488c48b67b144b64610bb66799a15fa792b3ae06fbb334cce5209411b105634675268607c41b2810e59bb55891eda9cbce20617cfd76adaf6a275187737e6b50d2c70d2fbd03b773d3954b130246ebea7d92bd6fe2ba0a301d7cb0559cb5afaf33f265dc14debbf9f7cd0488ef6780d401e4047ee701916a72368a643e20e72a24f806fb12ea0b4e975b031aa142f75f95f56c279b7c0adc3ac24ac7258433be97f1771413709cdb940bbaad5c5ce247f4aaa3da89537046ea24acbaa8ffe7e7bf846df1b3e43ee7f97e05054a38f6764182b82adb65a8c6825aaf783ef64d86015b0062aacc481495850bb503a518ece2e3a3c6b775d32171c6a70a8c32b5850b2c175738753b06cadbb404ae08fa8798a595315c9a558aabfe7d86c2d8b9d5bc90837059a7ab9af37ee1f6459a7ddf88e75cfd63b3c5195d3309bcb3c67a0d623ea9461e9f73f11d9e0fb75c5c1f0075b22f7c4ec1b3da99379ffb1b1e82cca85d224d57277c03349013388829cf15f33bd0b4ddaa6dd45fd536ea228d5dcd79221f42e28e63a393353621ca4aa50a4549a6869e685a9b5fd966ca74347dfdd615aed36146b54b36b809eb6a78a15a32a12138488ded8b5cae09562b4eb24a3a6a9399bc7bad3375e382c9b28a75f753f076d4c2bb50bfc3155df32b3a915d758ef886b944ccb8bfebe6a108a6ffbbb395b2de858335e0ea83dd51153ffd7ee2e4de882f664d2ad6a08ae08651adadac1cb52e91ffddc5ec959d75027a4d68f5dd2ddf4dbaab7ce310f33c03dfff518b991a7d6092a15a0498d65eae18782233da78c2258f6d5121efb19d04f24a0fcbfb0c229362c5de6b941152a58ea584730f11973611c975ca279dc08eec444e4753513b54fca5d3950d6908efc0073852981078dc07ed074376f4057e52a427b34b447dd1b60aec9b9233299c8d241ed265235a0ca977dcc1e5bb565b5e8130c907e30a3742d2405ade266b273f60a63e4a3e4e17debf366fdd6972d177ccf3d226d06718b2d617f61b459cf30727be6e3f581f7a8b1dc01f8f8e31b3a5a7d8d393c91169c1de3c3fc4846ad6946b3c9974997ad47e10ab7061a913704026cd2d18ef2a18fd91b9d8514d6d5467cb51aa5b4e68f8835c871b4f55d50bf8122e7e42bbc182dbc57d3be27cab8b1d3c1a084cdfbea872dbd86c5c282a862470de8b065e64bde08a0b99d72099f15716ee57b64bdc733323f3efebc4bf322f82b66d46dbe669997d5f27fa954573474e8bebe8a9d4ac4669fb6d9df097093b749a7683caf0f55c86f348b021c5a2f7690d45ff8521cf5ae4c17f378796c98f5bfa4cbd23efdfa812b37abe4c4a94c90c805b8f45020340a704bbaece3dba6c7affa93dc0114e4cf98696b4746559817bf638ecc2eb81e4615c12337ae582f8d7a0e0e9ff13ed730ef6a695f388bf4fa34c7cef1b89d56cf20ded7a15338f5ac3e320816033e85cadbc9328952b1c4f374db5af775410efc8433956171681b75c70177bfacedf50fcb1815f79b8fcbd67a6b23966bc0783684720043bd507515642ddedb8295ed520dd61df960a2790fcb80edff46ca42f8d061ebc472b52aa1aecd93da8d6b0bd217e09012f2e5f37a42a931913836837e3bb574104e5a0bae9592681d4dbbee5c04405941596c57591919e9e4600c717fd9103601f5501790b9ef9f306900e62900767d170ac40b8a19c6d59da83b3e3ae4638cbd03b3602b81a20b002ce6bc11c7f07faf7809476c466f2d378a64768be0d17bd2566691825d03124251adc78c5cf4f01f10b1b7b41015ab03189f77ae299432fbc1a6e59ca8de61e96c05ed82ea112a5873b7ae86c7a677e9a224cb6bd65883e1f32a3b301bb3243b2328ecd02da8f30ff9c360b0e382bd95d422bb2c0df0000740cd7df51ff9677f872c67de1a4bdd9ca1015f99fb1062ac4aec3215e2b26d9f06b5fe9e65c316e3353865b354d8d938e2794b72759c21e1d6e640af8067d165d83c87c530543e56d7f7d152049f814fead70d931de117abe9c2adca2bcf9e8ab8c89b5f56fe5cf9232c284dfd5c7f56e4aac7fb204736ef45746bfb4a39004d5969707e8d3f8bdd12e85948ce62501bf38477fd6b2ea17bc43cb07d85a88a3ab6d658ed6037a410db3e7dd80e055896e8ef51d08f718d8c5c7d189297545120747ba7cf66f041d005c971f1176e43b9b3a6a4d8638e210f325732e4dd8f16dec52f1edee7623d664736a1b2219ef7f108eb0365039040a73e229dce3bc4c0ecb2b4a7ae4c7ba5820bc4856961ef3ea9e1055e47f30602d222827f024997519b717c80913461a18008b5cb56591d31c67b6ca44c146cc7815266839511c3678676566f167e464a66cf1a01408c5e04853aff883e2c3e93c79e88e6f1e38491f79d5f431b35f23e297dfe794feece31eb57dc867b8eb0714f1a81ead3c9e752d879a430f1dddeb97a73c3ccebf80b4f92d64ad8ae08890ee61f0aac3be505b79a430e6c2de3926ff4abf59a758e3678e48f7667b50ac64c670deae582b463968d569dea638fac98a436a567a165672a385fa44766437258af9d44999d6d8853dd42cf31e7244554b02143c06dbba0fb233a054ea0ee7b64c7ac551cce68406c22e8e5db8b1789d1219cf6097a98ff28038c6cc2fafe83e1a1ff5e9f2d9fd73cf9a6004c5d324bae666831aa35b6ce3336fc1e1b8ff26be5e476e69caddf0beb56b5587c2d15a4b769dc701d6d57a17caf1cd76d0ca86e179e9034b4941fd14a41f90b9880ed9d9169ca58de10ed841968ab3983a6a861ef4d1fc72142317d8246dc17ab5732d5f78918285ca5f5fc823389843ec1f1d58cd04c5cbd5eb40b311bbe5cd8b03d46267f57dbd03bc88ed1db440430652608f9ff542df24dedb86aab125aa53a66c6fe4f1e3a533a8552b33203dcf57e410fb6929e141c4df60ef11d3f7b46a729023092dea776b01abb39e935f251bd111ae506f1c32e10af5caf9d428d0a89ac1897bcf9b8bfbed501b7ccf9d12afd8b561750638ddc612df6c2ef1bec1d14b4db831fbdb86449af5a36b7d083f712f2b3eb41d64182c31d18993eb0aad854b0db5799fde742cfbc0bfedc0f248ed8d43f09ffe6a63733ac3f6f2ef25cf8fd648b8ddfbe69a9173561ebbe954afc6e274a5e9ec79e5e1462eafbe4ec3bb706365a6e1764b2ed83adc4dae87f7c3569cf056a32e4c8413f5becc17abb8ca31d19c499bf7d8758ff47dc589aedc9dc39d1b2ef0777ae251e8618d9902bac22bcb87abedba5f6922e5fd89d29b416fb1eb2e0b2daff577df549bb0b6fd206f2b378e407f6f521f5eaa4c91571c4e4306a8c9c4ca139e92be66bcc3bd0bb2b66f5ec5e7e2580eb7f8ebebdfbe70c835dd7e374f4be43cabec4d8b388fd16ca6bf3f29cba2cff88e62203df28fe8e3846edf2d03f581cf647ea063f035bee669e730afbf1c38983b7db7b2a4fb26e7fe0a26d0b82c4d9a5ee762efe8b8146ded1dc4ae8dea0bfbc6decefe22a51504a1127c2447dd050c4b72b686fd2c0a59ddeb669475c699c9d03f2d51054234a8bd48ad97b2e0b2ebef5658c7e3dabbb9814cd4822f0250bb2845ecf2a335141b2976dfd03b76ff703792b15592f47af391263ea503543820c3303621add68766329ba17bf5be9d7880790f710ed055731a6e4bcddb802e86034dd8fabed4accdc876145c516e7e5f6ad166b826cd9dcbe887b6966d077c1a5d8df10fa5ce6bcf8801aa2c4fa9f76da92d16f6cc1b49b34f6d7b63e63125d777cfbedc9cb4d5896411f559bd6936a6087c31214caf97dd2c9fd840388902e5e515ae81f7196f36458fcd738be5df0bfec142906a16380d76ba865c24de29d18fe6ae2023ce562e2e226cccc98ed36faeb0b987cb941c4976769242b8d70f5e18d352a5cc0997014c199fb3ec3694722028d6808eb96a328f7ac2ed42cd54dbb00c0a60f51971ae3e519d26a05b464b76e78000f9bee3344c6dd094f1ba84b40c76ee0bbf6443180c49d3938d04503b04608fe6a073237e5d1ee4a2a3786f3d4125c876f061656ff3b0e2d1d5776944c773cf8cc829abce8648629f03234e3c240e411f56ba988b38b4bf1981d37618f99aaf4e4a403493892c259efed816acef074d6f7abd2253b342db9420e54ece8e1fac524e9320e0eb652a1ea9a0203f33e7f3444f47d86ee7b447818bc9fa8a3da12a94e230be7e112cd0e64a36d3bff20ba35d437ecbf06cbb84afbf50292ff9c0f2c4499256b023dbb42b273139789c65a24cb5db8ebdc1e77a2d53eea06e57bfa8ca1dbb6e5648cba305ca0535579341c6f450a7ebb217f39be9f5772ef262cfd3ab3d1f9d4de8032d4a94eff9a9702f767151dec9f45ae0d8a367dcaf8877aeeded1f5a9a49e1b5d5ed094422dd9b0fcc18d4f8cbda03c6e2bba557b4f49e384a436a30c036ee1d78114df52c3cd0553cad41842abd11f5aa86ec58e62128c3238322a84b876fc210e808a33d04a1aaacc6573ac7461b5880cd4d6176ca23cbe4d03168bb5a627588db1117a720c3e75c40fe5393de3a794f0525623566929d16c670d01cd629ea4d45ae697c209ca7630594f450c6c65aa267b5523faba37f5322c999c7ae77671cef972a4211695ebe8b1ceab83c31b5362331436d369931095405833bcc4129d826e0da625eb64492c901da465c34f15a43a1c43ad41bd9fd139d69c81fcb33692bdfd91bed8a7b3b226ae564e777c5e8d00618d39624403167493a130017b0cd8e9a65dcbd0de3ce486ec46e13daa4037c3528d12e4cba67768905e8ac4949a0368a75a0d973ba55d54e99d81e4e9e31e7720dca8900c589d5b085e8d80caeec0b27412ecf943eb6f26050d8e2d3d342c6a93cb0fd85f3450fc101913b6c60d0485098f6128ecac4e449d5a24678cfde4190caa3b967b8c9170e5f5b223075dc7e28dcd81dc0509f36ffa10fc5c5d943011694663c51cdf595d22a541b4e08c397db4cc6dca965c841ff9a0d4e2750f3d5fbd78588f55d525e2c55478804e7d11db366c6d30207398d6f15fc5ab0b824b5287da06d8a7375f4fcf50863cf05b4f57c901afeded5dc2fd2f6076bdceb1f9cee8b8047cc2dcea928c658378e83f6ff54eaa4c6a950a1eead1e2fde604ae61b12a476b010bf54f1bde1ee1746aa8f67fd31b76e3440e9d2c249f077236b2cfcdf7bbaf1114a334eb8f9150b9925959f4a959fa519cdcb8543c0d212471bbf0837924ba898c6c486ce69141b44ed8c113cbfe16f905ed15e154f8135eb091f078a1d6da79ad97b535696f2efcde4fbd0f382662fc5f5ad614f8e9a40bd411e3656b77207e2769f19670e2ef10d40c45f4b115220b76a1a349faee1f88ec1d4a36bae58abeebd3514b182d83560dd1aee6d2ccc6c838d570f893daae20cad91001231c4bf37f8f5b166d10a01a29912367648fa2376d6c4909235f5614339f7d95a94c0c723333e0d2892cf1722c5010763e65c6098d32f8eb4ca758e64f7387ac1c746a4955565f55d5d2d0dd225a362795c7979efde2e3849ce197f9f585f70535fd34ad44fbeadef0091dd39237fe689fc4489fc38bd8bca27f708d7c9376b284e2ec59773de1d7f3103cdbce3d3e90a2734a71227b70563ac177718b7ad25f57080b1356a30e891ab790bf8d61e5df3c8659b61d3cb235bcf333670c359c41362273725dc7c7c875bbec9b0c381cc259a0e02e6a584dbc189a09880354f2982fa7c978f6ba98374e203bdf3d823de8455133e6b2094534f7134cff4d7fb43d76b955592605cde4a6482e2a42e75804135395c7828c4135c7a2ab4cd9e806a642911d05d7d3fcd9e2a9f23e6d9196dc93188ec022466327cf8d12d6de724e5fedf6b5fa21f1ce2b48cc2fea9c4d078692e292e1d4733484a88a08a8cb65f36c258f8a1dddd1795ce0011e513aa4eb28663e856cf85525b941a0c61bf63f719823654afcd3afb9e10172ac67b6a4ad4e81026123a190e1af018eb59df9edec14e082da636d457fd62e2ade01539b194f0df9a4303f03c786edc9b448e83cfa534ff1e7efeca93b10691fc6571ca91f1ef64e1981fc3df95c8b1c622797db79418fd894baef10f70ee8f2d4ed7e009e7b152cab4c0ce5375a6c952b74fc9123f08f580538571e2a717a35184965345723ec48d1c21d1eaad754c6d54a5cdcc53fbfb226e158ee75cce18cb72767226eb9ba2c2536de41cdafa97352c4a1bf237acca193876e866df377a1b3a077920e70b51bbba7e476c0b1bc69b5ee1fa5507cef73ae4042dd3cc60d6963378b1bc875d7e65e2fa36aa35b3ad3c5367790339b1bce7a77a7c0b68d50755768226a6a5aa922e1cd8ca55f5b7b29a7fe75f608f3fb02187674adc18f7cac9f74ae4367b9252bb2dfc08b638223d7277c371ab6e3ccb13b3bbc72d703902bd571e9691faeb5e69ffa2bd32936cd758c1c98fd13ebaf09c1a75f0d7ef928e47fdd94334feba9b3ac39f169cb1758a4bab0e126e3657dbc0a9caa3f7d73de96cd43a720d21d63cec50a4922e2cdba9d4701c2f2ba20dfdfc2ed39ca8f37b9ff6afd8c1598cbfecf073d49bc86d13e31803f9a40757bf61f3c66d8de3c77919db37ce67e42e40fea7f24ceca37afa3fb4137cd3ce9792148a67daf9f2154f285f33a168c7fb3fb4e39ea4b1306da1551cc1e37747f6ee45709f6d4157ace4effdba9fa38e3a9f29aca13f6ec9185bf26cb624e75fe370aafd9e758707fc23d00f96a47da9b25eb2cd661436a98d163bbd09fdb263ec2ed98b1437d49c201b3987e72a6b87f8fd018336ef19a7afccd6026b2ad44531d5286fbe7e31d7e1aad460490e38f9ff7473b611bf0125c0961fefce36142c7b3c00fcc9d40674b02a5405a393c8f5554d68af5369dab3d95d1a40ae642f296048bf6f6ee703dd0ebe9ba771aea7a590a880bde248a170e00a9a87fc10dea1bfb5affa2ac038de7696d5b937bd25c49bae0c3983f171ef66710a0e87659491a122b86cd9d313d9b942b900411a7db1b01131757632aa71766125d4ef46dbcd743773993e72842df19c084d0e16006e1b5eeeb46c474e5a7def7c973f1353780f4eeaa455fa682ff08145c5b5b6b2100a103c14d9a75abbd0ae7829b6e154551991c0b84b4af831b918b0e5d2c2335c8658cadd63c11167c6083bfafd9f907e1c65760336d5edb0f6b2302cdcc9ffddb0208b354a8566c584a10beb9414a1814e09f489a730215f44111887b734f6c883c06da0333c0358b4f10566bb133c59d6b8c5075d68f7c1f42d16fd426438f46825e4395305f82f720e591455195a9c19433da31207ddfbfeeee52d34a8011d7e906871c26daa1f8cb5441b9d4fd0c6dac3fd0a8ab04267022c0f298486893ace7a78e488c1933e62b06c6b12fab291ad9e8161775eebff444967f20ea18e97e2ad5edb78ff8b5bfad2fb8607f88683dc29e0480608857128b34d090e9ffb2bd728a3141b1b9e8eb54c07059d4dced331e3a6ba720ba3c66887bf39bb57fe91dd1b9164f4e8ed41be86004b0842780b0fb69c5ca774478a5ab5d97ecb980dd9277383ad5bace60931e16403a42f70ba36dfa63fd421947395a8f01be795bf7caa42ace385aa79a2f1f9b8dd7ab998d0fe87dd919e64262714ee590e37d813f9756930fe86e97cbcbebe184a7b5c0cd8af33992976a1bc63f7ea2326f0e3c4147db654564060bf801cd6e250248f840fec3d59bee84399f071da7e7fad861584c02f5afae2f6427c53971e0affc93208565f2b5631090dd25810b8862d0e8b2b75d7dc11ea817682f7fc17c9e9db7d5e3312d0ffed601d10c97b7d36864ce146d767c339280e541e70dedd5c0bd5959590fdfcabe67418afc2839ae32c0dcf4c0cba738a1d3ac8122bceeab7272a545f0e9bf954a41a2183a51c30c4156c0011996682b22a75b2e3e112f42015c6d5a64fa02f5468ffb4ffc1838db6d979d5bf589aca1aa43cf41bdf2a085c35efea33a51ee54ffbf1445f37fc631b9e70eace0f6dfcdd0dcde5e029ce1733dae3e8ddc8876524a922e1c75b25c655ce115ee2a49883c1363461dce177ccae6aabad8b7ae196dd83cbf0f48349654beed06dc58d473f1502160e39ea22f12747828cca6088bf9b43325571c3ba7040d097f7d0a8bf846c666646a86d7fc33f00ec5b0c79f00b7876bf00c4a8cb33afc94a967d3a95a7db05813fc2529d20ac56e519ff0086d95101247010b385763f8553c6867c6ea661072c18575acb5c19e4c36c7e77d8ea5e76b6f27e5602436c4dc5fbf3f28fd15e3b77d5dadf5535cd1568f0fb150d76807ce1b5a0c05cc8f6ea07ba3b229ce82b8a9be5c6f28f2bace3a9e0d94629ff9992b1ef9b53450bd52b9a0d06fa7f242834c1e193ac066ee65a6270eafde6fdbfa5b24c4956f2c42ec57045bfa815766894787f69824527a7a9669c519734cd9057c32afa3dafba40c3f471f9b942f5571cf5a0a9714266f2c922c8307914989be4aa2cce02dbe2768562a5879f8a31f68d42d940286719e0d814ba3612679bac0a3b1bfedce34da5a0f8dc038864708ad846477b6279714993b9268b5c003b4d73872db2653b1f43dcd2764046b0a7ffe0fefb7e651cb657777cbe1cbf5574a9b66cc1313bd97de71de9560953f8968f5c611f3568fffd39d0d88eb20d3167508389fc3ddcc38c513f3312137bea5761ded84334590106e0fca57abc8786e47253fd44795ab5841508f16781eafb2fd5cb3b44dd356faa5f2ed4ec16e9bd97a85ef9523dda435aaede543f204b6c3466e0e799e463fa63bf19859c431455db6e5d38047e7753f376c24c4d041daab2ddb830f2c54dc5dbce9a8a88735375bb736196e47453f376964c4dc42c3a91c39d45c4f79f262ff591fe96b082a7000b780e380656afcb25c0b254e86f07b35d0d30d935bde5ddba7f99dbff5a1e710faa4519242bb2caa7b25675399345130db1b4bbe830f2f0ca85726397bd0ef2d77bb976617b3f7c5f7b4bafe7f2f47ded3d251b8a030f7e4b4dee54abea521c4d83b29b7ed3ec9a3ab5287cf5aad9157d7551e8f355ed3dbd5ec9cbf7b5b72edd64bf866004ee50c901edfd451a701f257d60ca74f9dcf3b5451e08cf0d874bfa4245b2095a089238de21e029009cc46ad127ef31baaf0f776457e94083db34e9f3025640285f93d659ae91505a5402ccf2fc6ed271014bdfd52374137573a3b0b597af9beb3038af6947ff46910f79e0b64c603cc64fc9df2fdcbf798ebf08a7d9676a9d797dc73f701026fec57a116e68eb813522793fdf79c6c0e2ffdecc6da38f1816f51113112472d5378eba8e0842e9586703743faecb4bab978ba3eb5f7fe58436c1ffd468f53f12c5c8eb491caf2c4f99246602b86079725245bed8028c6db3484374a9645f2c3d24b6ed5eb00e7ecb7e2743607a891127343d7a388226b73fae86ac786072899324d86fdeecd38a5f6490763f6aa85866d9738a3ac4852e82c7f9decb59d953fa777542f729e36409975a33ca8b358b013f2a0e6832979272da7d511cb4b0dbc7ed6f77bd3ac866077ae03d7218f8d137bb7c92a55781a7bccd68eb2b090b8ff1400b84faac7429f082c42f0f6861d10e37615c610ebd822c9b4b0e933621d065e6e0e715b85799606d13f01d72fd4585539d5e05738b20e2f7a58bcae6fcd4c7eaebffffb92052cbc7a2a8479aae688fe912d9ab010305bce295f0f72b0f73c0292886e4de68f02eb8f1034fdc7fddf8118d3b94fb97a0f0577a13ad9e1e177b2fd7585efe6113ed662ad758169452ec84538583b8575931f4117c505e294cc45b739af14d8aa7b5fadf8c01de4ec275ad23e37fbd7b4e0eef9e8faf9b671b7bd65a0a3557dd031ddb50b50e6493eec5cb6b1d9367e2e1d87eb6b0afaa688616feb91d99b0c162557309152475eb4065fdc850c5bfb777a9b68234bd9421211c6d65b34a792e2faa03c723600285ec7650026a2005178d85fbd92137f1ae4d5e3a3563f21b6cf79c65920650ffd1c2ffafc9acaa4a0e5a090ed35c14576f1bc2ff28b0fbcedb3e61a72eb2d86c1aee55908a2bdcfb2d70f5e632d9b163a2f127a4d86f15a92df88cf7d4148819b38edc839dba6c50f881005452f927fd9b6be5a15aaaa95abf725343a4aafb6b193443a0f085b7511dbcdd4b36d01cc0fabfd7e86fbfae8c439d4b99ff1c8ea2d92bee728099891c4c87da2826f40f682f42b1df0bfacbe939812dd1ad0063674146ce8749bff0252bcba9fa8edf9e18ecc83b587c60bda06b228bb16f14548c2dc2666415b9f04bc30734f7883ab023abae0430c4ece67595b87c1529385ef0eb95c4b61ad6e9f54aede402b0fc0bd9deb3323c04c1596f1d66c189de6e3bd0a438970c18573cc45533de019653456a5900217ee8568d0f0bbbc8fa915acef812834a9f4cbf93a6daf18d45966feac2c072c49ab2df869254307763fdd5df1d02a47621a3566519878f32078c85fac57946a6eb1a21167d30a82ce3c239a93a576cb3a5616d370838175271b91b750d50ea516eae1e7106bf6740dd331f0fe3ab8f3f9a8fdf91666836b6724439275115f3e578073b9dc1c80184aa9baa6b0c55e7ad86d4844b390664fe0189cbf73e9bd808046b5365dff7a189be1be8b5889d16a0bb8779a2aa902de44ee1092c2bc8b83025abc3678edfd4e220189af9037d16dc129d949d3afa387a343978bfcedf33983d77a0cbf0eb6beaafdac9935fe84c08bcbde11e6f0ff2e2173bc699fce9a0e8317a8ca1dc61d539f9a9bf6b11baa09e9b8860073875c3abf10d3bed2e0bd24387013b4c555de88552659807881e1e75e7c55a8c677758e485028272e2075b6a46bcb7977f9154183c77b7cdeb4c8513db3b44d0b7e5fd6aefe52e6e8348764dbeee9118f49fcd3f17f27e3bf3e0dfae84f3fbb4fe3b6b7049c11aac60cc4c25ac997b392bc128b15f53ba0444bc3f831b11e370fd77490a937091a104a6474b3e8668f0a64a5b3a74565a72509cf68968ca8baaa6d7a1259c25a979b80e2df1d89dd8eeb177f204593c9c8d5c3558457a419edf3ae3da140b7ac2d92953701b9918c96a5bcf5c459e64133af9e3962396ebbbab6ed58b4b26a6714aebbfb11b2662667da5597f3f5dadb1db9658e3da4add2f0ebae56e8235a9c82619742670e00b76f0cd192deb7c1997f7e4d0bb61643184d22de5a3f513584c212cd0849b5f1cd6119b28f3267b0099e8f2868f2b05d074b7adfc1c336e3c89be8d150fba77d6503c880a1b8bcb15e411a7a3bb25ddb097a825222c40d7020ad1e318edf1015adedbd8eca9702ef6e5a877f63651f79abd5b033be6a059f0bd1bc9ce117ef3d6448c90491a315bdd6caef33c60178454064989e8f0af2d521a8edb8d7f4a12f10562470b493d4678fa4880b031a81c789f560f7988db8749c3c70ebdcdb6b2b6527fe2c0794ee6948cc5db288386b09a2132b681d519851c04c7cf876907917ae142f7d83d29510ce41b73822d50a61af30e75f2441e5fc81fc36dab9b683ff2f579e670e429f9ac231a43fff3f90301389ef02219aeafc2085f8a699f4a03ea7799e61e33458aa3d0b9012f18512d20aa0d4b7884e49dc3ac969bdacdef810a5eb0a6bb6b7a12f77f1af56867438f73ccf7f08b102fa722e569c3b3a9570284dfa0ddbbc246d8805a059b7ffa0a95f44c9105c3f19b9e17bb506c56cb5aa997de1503bf5f6e0618dd7d990cbd420c9c0065d4199181d8279b1cd4f4cf1a0865a4eabbffcb1887c26dcaadf73df65794476908a71162e7b009dca9857a1a861b595ed8c5618cafa6f9582b62a1cc64b8bd0630615bc54c525cf0c956e6170d08310b833313b3cb827faf705ff101e771e59475c7f5f673499ef2ae091ed5276a64b8a24eca204226843643643869aaa4daa428757ae6f572ed597b29dcc7ef6271b3b0deb54da257570964b678d9fa19fd53043c2e9b7b0f110f23a1ee39a501a5e344880007411aec0087185e7220b7df2d8311f5b55e83efc053b1dee6aade5e7e579163fad672c3e3a29ab12ad63c7e5bb364723ad65353732c1ab22c2b24b0b7fb7a77aeef804a3bbc5c689bd6387be5a645bbeb2c05b3bcfa5c9476041a163980be6b3a999ba34a25f4de7cfc26b4387d6b64cd1db58b7acf113073c7270aca1e55ef6833ae1688ef88f9eff1aef8168878ba555753256b662be74450a4404758b715679057a348a5ecb0a4efa9c76d95f1be2986e3c704f2e4dcf0ee3512de9abaf13f91dc70aeff7f954d38730b3da9332790ff92293e8185e865877c005b9f534ba3fcf0c299e8cf5dca5088a65f4efcf4d87550bcde60ebc14f39a7f3604d0ebff4d2ded1b11cd57ba75b0e531040df6c01eb987467ae504769b9b638c8e581c30c89d5606c899011b19045fe8084dc6ca838028bce649877857b9248e75b271812a4220cf4103e130cf8a583d8e94937ed412d3a83b7f182ddf127dd21235eb3cc5dc2e3f2901069599333a35e4d8873a7a8e4180ec76b62821b32dd13754b10edb0dc8300275507c601c606215c96de411d2544c751ede4588eb3576dd9d46c7cefa05688fe70f6ead719ea6fb4d23ba8605d456965ad556fa7da325961958e3570518d93417bb02ddfd9ab18d196ef77c5de04a187ad3c11aaad9acc803188f5203e00eb6a46ec15ab1629b8ea3959b22ec08c86b9ab3300e55e2ef81b102e864b26f89ed782b7eb14dac7411d91b841e9c80e03e4c098198818e9e5a550da20851c54edc0511804f3f15c83c6e1031ad11d34837e05697d11d8f158256c7e25d60067e4a4f79b7abf58f624d773c00273d6fb72397fef8b96ac2ada70633d63a4c8f2f6b0e1d3946a12343739f923b3e22a03badc57ffb6081dbdf5d4beebe4dcd40b416996e5afbcc91142351d7664aea0490a7d86e3106dfcf704f79e5fab91ea2f2964fbd63286fee0768ce240001c196f5bb5b1c336346115843a52d0de203d701ef9b293d59b442527ab5755a61e69d0ce27c36e38c279482e4e9ebd5c60aef5f143bc8300771d1367a452353fbad76fa2a34b109c348f83c551fe734afbd4ae35fad65874159294ed65b5e514dc2c66147beedc914bf7ee997c4ac0c2a29c1b610f0caa5d6481b74c02d7fbecc6ede352130bf98bf536643f221b290a4db3e22f42f50353189e6aa0885438104adf84aea20094fb1081f18339e16ea8871ad4c353e38378c4d6291de9327c8928544a45f6fad4bbd92a9416ae3ab506e22845174a3f7f41bb43dd27cfbc4463e1fad6d0fa70eaee27fb4916d21f8d6c0a5021734022e1333a6cedc92b4a3db382715863c67caaf9196cbf6107c610841475b920215f8d1dfef70849e4d5c9a0bd9b6c4f07e69bb30d7650c74321bd533be4044a13a1002e5027e972b89c5abe7043d97effbe3d03d39bfccbf6c8ebd20d25bb55ea8123f1a81e55420a56fd44a592125a7aa53d6f0af33955951cf3c666f88aaccb105b87a6f9f7234df31e33ff520732cdf0fc82893de20e019d2c27c0ff2376d88303fff8ac49a64bace7d3e5052e1bf4835e88a5aca08d29034b4d96802c9a568f00d574500b70dda3f34b46239db23c1f0d1a012a7ddfaf2a69aca69b63df1ae8d938c90b791d7b1d323eddbd581c34e5fd596c5d4b89be32d3e10eada170aa32e91477de4c3307d6bb3aca4846488a416fee69b216921271ab90ddb0815af97ea07855c68c9c610e047c50f4eefcb5cfbca95f84f8252c5f77b52e9940972024ccf2953b61e5e6f913c66d7fcf1eecfee9c1a85ac04f1b95976ea1df3b206f029c70070d2b52003e37d62adf4670550c9a6b12f7eb8a1220c090bf3a908ada4b19d455b7e2b2387fe07b19776cd086de081f55a90cc149fab53b766664e62ef38dd45ff0db72c1886d9713c4b9234c254103486975e9175f2f8049ba3e91aab88c20e1ac6ee31141f22427a88bbc6e79b506895f1273ac2e0075cd5e23686070267b8e739187c22112e3fdc1b3f4c5a1ca32ba8aabbd5dce49f620916da445cc566ba1aab27dc8b7db1d6db7f715d871ca233d847b0dd1fcf10a901fef29f27d8ed7f83ddaccfa966fbd2b153a9bc35f76ef80b4ec9a5723500ef5cad9e8335cbac0a89b00e5dd956f1645b9289b5777c388b7267c3196a55a71989e7013b96a308fb4b485fa34f31288bd4c65b3308b6fd4bf0f941e1e53de29b425da485513aca9efbfadebd4205f8f60a049ebf5a91bd3a9c3bf27fc6f05b0bfa703d003e6b272c251a99ef436730fb294b2efdb02326548b6ce0963ce4ebbf9630a35d6adfd46d7c5429e52dae4a3033429a5930481ba484e5d70c48a4db309dcc8b72b725dbb21d7ffb886cf86bc26848ebb913d6b29c55abe30fae0843468ba13bf0faaddcb1a1e52c36b79a4e0dce127e552b80357c2891406faca291f646627570f56c3150ec954c25ade09afb738f23a351112b869728aa72685800eeec20b691b0ed298a574c9a92692a6a87ec050aa0eb218710a4e4541a4b1ac9e319dab328ba729fe611e0c33f8bf9db3bfb866233bbf38c60810ad8ed134e607d509e98c9edf87e57351f7355c188461fdfaf45e4506b069b9d0e389983f215d4e4562f383a045a4137338447581500ed06358760305b112a4806eb2497cf6886fa841a1d6847b30fcec404eefb3aa603913a5b95405dbcd848ef038cff4e8456b56c66941e688b8ea09e7af15b73d1a954de0356a0dc335f95476734ededb7266d633b8c3c260c983e6ac1739923b8509b92d0356f5af1312163e566524d8bf7e6c942a763cd00482a3a1cae459a012399b1b478b393f99cfd9133ac293542e4c9998fee146723967ff7325267f802724288bb1fef7111ce41c27f67a746d79a65e390029a53b8ad30f9357c9042cc92b6602b7c4080a3352fd8fb0859ec93eae2ec0371ceef1971bbada5fa93a9e301ded3d076f1022a4fb7c4642190621df2d1c50d563443aa50925cd78430fde59654765862758394b069dbf8c7f0c80f8b020b835671853e1f4f1b1b28040a02768fcaab27f8f5eefb2891b3ef9d0e54f802f2386e4ee3278aac99be7c04e1da467cf0ac4cbe7a2e25923d17ae881faa9021b135d9833c47608022b4f1361de317ccd89258281383cd4a5c702a123c66f0dd2fe1c7ff5e048c37e5fb0218e19c8aa8e1d9b7cf33d27c12da5bfe79296c97c6f48b90c35dd7a4b96cc94108b02aca835c0455a128e42c392ccbe4c79db4db229354ac9aa419f6420da3def7f3d475a4e610b6e9e0a78cf90ff335eb8c3d900f7b9f95b5f6f044a484dd7ed230f7ab460dfeff29c557511f2045c2293408b0174ebb2b78809746f2553cc8d99e9ebe10c012d3a53ec1d7f33d8f6ff93c1be552ac64af665b844ea16f9f07c1e9e2936142ef2fc4feacbeb49019c0fb549f17d662edec40a53b197bb9fa7c213f1af9d7d244bfe22e8e1de3d61937168272680d06d485b298ebc89e60362d7495a2cce12a3b3166609d8c4ba003981d38ca9b25a51a511af014d932fc22091ad0a0e0445840fdeb6f05aa65ffe733372ad813893fcac9c5a44978d7843c817599f4edcfd16ba3069e3af5fa2f80d2796eb929ee1cd506c01f849acdaf889e13f4980983cfd6652e16adaa7a90f12812361e4e089be0ec609cf4f6c424560ea41b680b6cf0f9cdfd6444bfb43f14b98374ba4e5d8b0b843c64ad5540c3dc411e678bbe4b717d5e5dfb4882a9157bfdd44368bdd10fefa480009bfa0ada8561897183b6272bae889dec844ad0917d201b1db4b48e2309fae65171b763007c454ac90432ca8b375974ca69ac81b4d977ad04541763d4a1cae9be3309f08c760b0ac783fb7b65185c674c9dbc64095035c4e870bd07c68013fa0a37d9e573de3abcf39d0bb6bc699ab51fa3ccd8666f76272fe4a4ba744bb5f7dd052bf0f5afa909b1d5e8f283d97f139f38cbf3f406506866116b1af6c50ece949564e1e6ddcf79bfa81185ce49c2fd01962bd707738a15cd14dae86e9d9cbb36d5ddd369f0879567975f7934a019f0133fef7db4a9f67bc63e833fad4b2c844c00dec25ad14098bda809a2f581fa9847abb2e016113defa886cc5a78bd4f55cc54db7abe6d4556dd41c0d4d70d8c697aa6e6072d177f5e3707b2e4c977a23ec17e7cbcc8e35afb02222e30cc91e89f943745e15dc482cb380f07cf42cda55a18a1870a0e55626c8eb339899e4c834feea8e81e41ca17ee51358a30818474460272e1c640ee7210ee3a40d73700b9cd561915f0201a98b8b0cda6151bc1157b2aaf76b2cbd29d98042b4f4b5bf5b541b310e0acdda13fcde463b40ce7fe99e57978b03d1da5efc53bb47b43ba4f4909a52e976596775faa9ddb63cef8ddf8f61ebc686ade3a5e29d0e49030ecd94a7df013691d3a44d633b6b79b5a35bac9ba425dd5568cf8d8a0c98b1e35b3e0711f8dfec484eb7cf5bf89b6b7f777dedc720ef5905befe77dff33a94535fbca7cb7c25c9e3450f52b198b3a1975e06a9dfe09d1b96147a4e30051145343d92bf1b54756ec269f574079d0fcb17f64e56cd7b4fa831c8677ce14c60a437d8832e8cdb4821e3d3e57b5c312cb2b8aee1d2bd5c20434b0ad583a5acc02c08babb0b094bc16476efae1ce1c078fcd97d5d840accc187bb9c2844386ecc45187ea8c9de76d53b2821cd01f4dfa897cc13bc5fa8939e4108d25251ffaed8e1926f7a2cfc32e16606a0ca8a8c245e7cc38745a0e7664379623393f0da6ff0656bb11ea531939ccc7684e353aff1713cdbb938caf60558931df273c8f5916d8283047169dde78f44b02cd99c2f5d9f8b7209267b44f70f96f8b3d37293cb7afefeed4ca3acbf732d4e93a84ef8f47900c245fad661899ae6fb06dfc106d5bd1dfca6f1add95334c29ef73680bf0c390b087bff82d8feaec3d7dcef14af8aee093cc120bb73dd3fd4f41c93fa5e379237f13bea20af4f9f7a8c4f5737d08d4cea843715d81d25248a3e8cb14e51f2370dc39a47a5cc08b6e702cc196d660a53c05f661c0ee7db81a9d7afb3f2fe4adfefc01ba1a893a8161c9086dd03a786d0fd2fb1e1b77cf0aca935932a896555913286b46b1ef17667b96ea2f2bc65323fe588de5606aa3eb49478b957d6bb707b6c3f64f66d8f4b8fb14e637d3ed51d18003aab64ac2273a1b762c33d543ad061372b39534e30dbd87723d818c6eb26b53ea5c3b89129b7b0a5f4592a9627783e0c8f2dd8007757051c9feaa5d23cde9fe8fa8ce585eb9d5bf00c3b5c1570065ccf3c3e9a7a55ae57e17aa7ab02ee05c11493cbd5a8c460ab6f3bf50abdd6aae57c2934142ae1a10f4b94f35789f5e16bb9406c324c3b56044153af57b877929b969dadf0885678298f1ddbca7264b708605b8933fccfc585b6bd1215feabb2ff7bf4ff9ea823e3398c32cafcd379aa218277c1faeddc3cb394fc0b78c511b050dc5ad518c80859b5f3a9ffc272ee57c1edb90079269f126fbe647725709941baa053e7b50acf3de14636ba77a462ea896313e8b72bdcb7f4c86e2dd499536c43d904e0e1636c93f57229f50bf36441e1cfe6c9a2e64113e40aa7e9d48f26cc867c01d15cc2cdedb9b9853c70e53d9a73bbb27134310604e25cf338d3db50d8e218732cbefea6a7856957b8cfab9a57e8795a638901e49914e07e8575928d776ba08958ad0eb5a49973744bcf3cc9b75801a751ed5b63bd59cfe022f90b1bf4e9843efdf819f57aaef77407c5e1d8fbd26d6f0f746f7cb9935214f09caa47325d49d34e063efeb6037a329775cbf61a890446098270b8fbead9ac6ccacf1bf4dc7d5e6014d32e3691d381d72f2462675fa5e8cc83dc81e301e3378880175cdc71ee1958c2d94e5b2f7af09e5fc031f9233d93340d63c0e2ccc9de9deb779a4d5ad30fb72dcbc529a27ba651e5558d2b60818fd812a3edaa67bd6b39f81935929bf77b4a05e784aafc6d4531a3c030152a6460244790f7078af1d713b2939a61a9c83bf69ac0fead314ffab74d356363597286a283463fc7e839b379fe4e8f7e45ef9cae6cffd4d357f4d429f4f415164ebe787ca19e5877c15908234af5ec26b262b0956804558ce022396647d3ede71ae6f899a8581d3fbe0e6e28d4ef3952aef48ae7752e85fb601ed46a9e494865d4bb655863051212555da4f66aa2238c96d7aab1f336e2bcf89f2f9a33fa2dbab51f7be4fc3e377af0fe46216756a708c437d83ddafcb45423b6e6892ffe42d9404b7c88d9a093a3858be2c19f106e6c28af9a630a318e18c4db2c18e7f72ad549793e3d3148b7795d00015fe8126ad36bd4d555971adc72fc7dcbb306e769f8b1e572a45b76a31e270000d3a58f72a3a7e8f8be447556fb2ceabcb9a336272d5c02c2509590c5f09d103c2f88077517f80bebf2c0e2104655968c6fe0b6be29e0092f513b5a7a5b3421843aabbae6bcd420e589c76fa1e56fe7d33c5cd3ea9069da3d4978c70e7977ba0db434dcaff4c4b81bc90052163236787ad500df3ea6200d876228049bf05ff47daf5e3788f60e9a0f26944a6fddc5b2c71735f2c7356e0bcde9caba2a56b561146a403efcf953f5079309487f6a5e6ca3997d2a2f844fe5c53ce19d9c4f9a648ad976df0ae3661f1195fbec05d077847390f8397ba24473284967fcfbfbf72a744c81728802c50a948a32fcdb7bb7e9708b7c63b6eb7c275b5992870db30215ecfb20ae91fa8836de49ce96f6cd7500477bec90a0cb3bc554066ddee37ecb2e752e3d4830cad172ce2eaa73a92f90ea556f9a7cf4bfe98fc33ebcfb069b92ef4157ab5f7b21bcea4d3b9417dbe1182c4280fab54c79edc810ab36324ddccc9da7577ceb09d5a4b7c60efe5a824cfae538d0a18f61d975ab8f5ffae5c204da044fe896875f4b90e776dd5e195ea7c40cebe17c7535ab50ee6386278ab500e71de4ace11598bdb0c164a684e44986f31d7ebd1d2b17be1d1990367b3911e2a57561c6a17af3527399fc3256f13fdc847b99c879a37815468dc255f8b7dd48ce2a3bc99b38c836151db3dd5fa7c515cee712fcd7a8060d2fef43f569f8b30a3f8fe9b9f3f9ff983f73235543121342a2b959962b96ad66669e97257ba997a5736101b87af3522f4b87dcf7065549b6b4a38c1b4506fbea50f0c4df1e183df523e144b734e09b099e19c6bf22ff93133910630a20e98b5dddbe21f17af4adb807bd52f4e506d0b4fb9c207d0a85b5f4abb9c3ebb89b7a19dc9d2d8e15d43ed15f65d7efad81709f2b55560552d42a6a7c528539dc7c8611fd55822bd48a15c275a1c2b18d0d74a2bf4a5185c1f3b6ccfeb194ebfad2cb327edba2b5e183d0463e8757fec66ce9589cd4d6796014ebfc32d293d2c0a45cb249b9bed08e9894aaaacbafa7fc9f7960d5e53488ff53eae0c4ea7776eecb0193f19051a0acdc3773c11138b92fe6018c1123a05b03eb5dad658cb0e90542668214db8fef5a42955465e8fe10c9304c15f902190408c54a7e5103ff1df287875417fbc6e9159fb16a00481c3bd83fbba497ffdd01f80968cc105e0cc306ccce555a8c9e32af7c7152a924cf34d278cc60b0acc8638dad473c94ce5eb1f7822bec964dbdacab3afb588fe08a8959e07437b313d52873be24b252c111efca07008f86e949e50ae94475401da020bcea8443ba265d987392a1e93d62988e74ced51ffb9bdab12407ca930c553e60e711c1ed895d30e8359ad0896a7283d95e83f1fadd6c7a109374ef3d5ad3fe5a22b01764f7c31a09f58b1832b88c0cf60fa02e8c1cea701cf0e181cb0f85fad5c278dfd31499154f4808b91f182f04417209466c3e88d47bd482fb0937f496234489d8c1dea6c7c3f8f85ba3064fc4b702e1b579948701e8b099078cda0d59f7d0cc1cd49faa2ca581d6b588dc383c15de31e3d6e9f0388c0ebf3eb33ea90d359ed76a39c603de140d6d8ee2e1076e0ade796c95a49e411280b83ad90346eb9653901e1569d138d1d50eaf343f1e787baaf54b704a04fae5c07d867d2e49c9a89eb61c1216d6af45f0ca9a9274d6e5465a2d296ab2a14ea43b5565955b1682738b03dea832b4a50bf9640dc59be0a6276e216737a32e360bbaedd82cc0a4a0064f250cd0ddd42996e448d3c9e5d4cb35fcb13c238063a2af9a3c765af20d343954108428e01ab7e7c77e9ef921229e16a7640497b73ac5dbbae413dff3f73546cb1220a8f7b89ac98653b5d9dbbd8ccefaa72d14a9db5a3f3746e21a146ec897d6117c8db73d1394618a0bea8996bf9cf4f8c65dac80837f623ce1eb5aaaaa1ef22f1cf0052ffafe0b9be217ba498fafaff9dfbfd02e7e01a7a0f9465637785123f820680078c43b97edec0cf5c4f10d8bb8b42960a47c04e74093c84db23326e00e072493701c82e14c23935792a37dc46f2429eb2d60aa990c91fd4a5386320f82da7176ca140948574bd9b9c420441a9eae3c12ec80db4354d6286f2642890b287d85fdafba5b277366f7287c807bf5ba68167b42333c22b680b54e55d5a87dfdd433cabd0bb7890f1db08d7da43855af7ad256b2da027897acb4a8318144f6e33c67754cb0400e5c9e27636b2a42b71f511abfa0dc34400e01a1792057da6ba9c9ce2e430320f3941b5bcbc4464f6f604700d2a0529936bf985bb7f0329e24e9adb1bbca71632dd6b854e13eb14be19828610e655ba90828a0912cdd004053bde7221df0d384cd7066659994f87b7ce0a34dde5c1e87eee9529ed5926a259fca0522de9423281a011d3d691e7195d2b176e938bb7ba2b82ea28bdc2e859fb9e736f998c35ce39f818341be2b380f29c12f29f21bfd4891eee5993846d53b1a6e8abc692823a3fa6dad3de1d24c21961eea3b9266c0dafc736fd441b690968ce09d3f4f69ffeb77102a3cac702ace21c2cf117e3c045aa0df38527e94ba4a8f7c656ea5f03ead81b045032cdde09c02e69bf88f4b8a688d9dfa9decf3688d07a2a347b9e754e0ec150dfbcba5024dded395df7b099bba5a21f560579d0158684a8f2b25307f542ef3fc6e2fa08ee92c24eeea3e3b8daf00ba975dcafe4eb6eb57773838a848768b8f83d28122f389a5510719c263855fae17fafedbc2416a214362affc36425c3618c736640cb032bcd406d5d42e1413637dc2766e595d6ab2d0b496aa012f8603adcad7ddaa7b8043214fe450e5a6578a9af7b434c3b94fddba9e92a1b02a9a542480b703d7e48b119c1a4a407b185ef72d20c79747dd41dfdb9154712f8ef7162b36d55315ac1cb9d82d180d91143afb909530ae508fc73dc3ef5c90f410e1a14125ec1b4da74b4e00a162edf3a08383f97262acfc169cf9285b5e1363dd4055e0fd01e17185fa3547ed7154f7b2877f1ab426a326fdf166b4f79172fe4eec01551e60d0deaeac8a998487292b45a0d24510b61875e98b4e4a2eb59f2032aa5725c0211154f6acd61a0a3bd6f4d607016d736efc1238792f29d11e79aeb2cf1462cee0e5cb6b01ad173d7a3ec3b9677c593af9d058671dc485f1bed6801b31a987f9c3cf659d89715ed2fddcaf48f5d12b7758b8b887efc1cae6f029f64034e0a87b4e7e4f5141dd533f8f8efc153f9a606f4f4b838f80752f21fc724b65deaabfc96b88a6986c7caa2d6b74c68f2850ff52a02cd754e02534fdd63c5b893687da49a032778f481b7e869fea455619c38fc7437afba59b41b68860473cda9f23fcea0361e24b542c2b27c24fa41daa9e619e817389cd65f5eeb6b31800f56467b101ead5cb9e6b0a877c6aae102f605c413ff5ff487c9952ea84a93512efb166b49fbc1071a0c112eed5de6545c02d7f5a1bbbb84d23f6e9ea308a1076f10febe83ee2f18af3de2f00b155211d26a2fa89c73ff7802f835c917ed40199c9f148cf48f06d1bcc34c6a076e62123b252daed06042eda304b28ed97b20b5e667ea0e12d64ba61a9963c92fc481fe83efbd04e40a4f5bf9b9f741ac9495c0cbb432b10ee4e7ef1369a3f9af77012f78442c6d33ffc267aa4642fb2c10a8e26940f109f2b4390492d660c4d713d94599b8538bd6f0ed03f0eb61749889a9cec9a4cdff0daf64b04423d2031ec1e83d99f644e042346ef231c017ae6fc69902baf3d6ecf18b9c813ca5e6f81d0b006ef5e939eb5945a303cb4bf30595fc78efdcefe8498ba00490331300eee30623d4a3c5b4a2fa72794b72776d9169b0b133de0362ce02296721c2176ee4088275635218d29498160fb079dbd6702ce9d3f1cb13e68ec3d82a06c33b52c23bbe1a0f3ae1797fcb21d917b5b1f3700132398ca1d6035741fe8202da5f0523a18de16093c8390fc24c5abee0dc9773e77a6b5274be853def461e9fedcf44209b1520df61c03bb01b76bca8aed765d9ec382fa83d05e61ac613fcdce7d6122d4af9bb19dfed68135c69629794a8fb72b7ff955f86a707e354bef12425c4f3440fec7ac0bc36a0ecebf2c5f38b19cdd154f82bb84dfd87a6fa236b25e4609f712acc86d3f8903e167a53d1f981521b28d0a73d743c8a52fdc83773a10a203e19f3ca4cc0e0220406f03029124b5e3e0b88725f483d2ad5e6c4b8906e158f4e06132e6a0e5418d66b8e9bc05d658349cbd82b77dd33949c6770051cac95859fdc764ace64c16c77e369b9e7036f679fa9f4ee3778bfd9749c40da7272ee9eb89bb393343729aed5b81d8d81b795de06823c4ba44ca9931f0fc169c2c6b07e2bfc9f3620b2f23f92d49592b02314a00c6b6c5e99d3eb09e29ab33081963dea45b0dc418eaccd10c6bf3026e27465cdf01fa060e9374e3a23f631f4f47b8a61296ccb6649242ee73401119e671af0c7c1d9d91a3d356ec9ecbb8311bbe6530e4c11a4c79a8568cfd7c2189463dafa14a5f28004589000f5455997073cb13e3a79cacd334f7ee1a30b19878624f38a24939d15524cfe4d9a8391f12d3db60fa82d69eccf17f1817555fcffd367bb6fecfa9ba7a6aa017a335109fa6d10188d432972d3b74d4464ba42ea712193d564db9041edd1888f18029cdf7283938edd83b36845706ed7de74164645793be26b368d44cc239dd0a6d4f4faaa627f5c12327b43b613ec5b4b35fbc3f02e1aaee89238009e2c034e48bde455e7de3fafd40f889fafe952f860c67b387d3df0b79564f13c4cce6b20ae5735b71bc55b8e5f0bc251882e5896d072d800e6e493858c8ba4d4140bb1a319efdca06eb32db3a5fdb1918dc8862637aba2b07c62426c08835c3154d84d7ed35d7fa95ed50a090d2fbd513086d14e30a58e715f33cba3204b5177d95d7ed05eb2b884c317c2bcf0dfc55d3b593f13e9e10131c938f366843e5c8fa7b480783dddc2e1cb780d8cb47ffbf3a73ee131733478c8c7673e0d5cee48ed8e0f88e4250c4596e393d2bb2c738eceaca4184a32ec880bf4be12d34f331d353f265a0288003ebbfb25bb7fb95e1eae0d1b0def6727633521c5bc067401faf5f2c71b4c9abf9a1b4e204d5be50bf8c90415331c0c500112330f2332697058cac8067a0cf7c38cd13b33ca91f7a8581cfbccff5d9b394101f65bc80774c682f59344d88f93af5ff402523be593737d687a1077a174f0cb572faedb9bc9d92d9965506c8e3852929cb16bb96249f501582a04f799ff8e116ac1b668e3f2b469b9abe44fc188b3427b5626f70bd39297fef18bd7ecd9419b469fdae5dd8ab4ec2fb6bd68fe41693827bb6c3ce3d94b06ce36e7ad8429c43e066320ce8d71e9bf823e4bb7a076bfc2082dbc498b72ed7dabb75b588fa94d8a7f8cd38eac3e5fa344d69afcdede8cef2c4882fced5b69f2bbc67c6892b77f8612c000ed1c85c9d561446eec2cfcb654763a7103d5e7824c6e526d15158d53c10c44ed32b1479d19bf8a2761d2cf596feaa7e1b18ab6453edc753ec474f8c7f1366315b6d02171f69837f2e15d45a1c75260a4f3ab0b195ed326a0f975358e81ce1de25d3ac64c5d69b7e630beee8ca28eabc06fd754f92c96984fbd59bcdf939cf5033e5f34c691588b71a6d9193a1f286a0f84e8d7114bae01e9c70688a7942c52af2afa0b0765872d30ae130cf5719169618182caced6fcb177ee814daefe77d0911aefe0cf0cec68e34f31580770ed733cafd5e55cda3faf6e30d0e51d2055f80f42e9ccd4a194051a76d3364cb6d4d93274538f01c1d5abe080ef6a2c2137ce814268c5d31d6e480e71cc81e4ea790f48362bc6187aeac764ce1720ae69cc7f592d175108ed683490f84ddbc47ba34626136f8b905701d7bf674f64062a036bac45429c2aa11de8a231dea1def163d05f26a4facbbeed5dc3bb32de7ee3695ccfc54d6bc386368f2857359f7f345ada7086c2189198a72d37dce2efcc49301983844aa36e942803f821866b3c49bd2610c1e2fc40d4380c18076868602f5064d8a7f0f1691cad5b831695054178398b5c9dcf18bb575e9d51a1a3412e22311473a8a22a38726fd04f4ed6df211452ef761bd62606546243b4d689d0c4beeec90d8b8d4bc1dd2c83246079fe1460575edf694a1732bf6a06c4d408008e17b55f4b380ef0846be3a65a53de15edcd6855737ea643a4e2f92f30e774ae0cf2e7f9bf4daca5262db7ba07c534469f7068d84a219f2801831ae1199f29ee1b1dd2c7869300573226528186a6474caf2845f0625e712c102b6a9b5ec335ac4d404b4e4db734edbd325e701d7ab03d43968d0df3ee07f1af6bd6598bb51da43587bc2495ccbf030092e8c8c96f135e1d73b1c37d7dbb5c021183d1f7689e906ba9e41087e891f4f0ec011de3be617fbbc8b213fda380882713879d8644dedbec036b9633c4bca6c7f9657e73065a4c106eee549b7026adaa1bf5e9b2d76f0e0acc818931a94e000393ed0fe7b81203a738c9c26bcfd9c6d6aae10cb257db31ccbb07b65dcac216fef4bfdddca10b7139237876b3ea39b36d206772a79ff06428ccdfbeeba4f127f07f4847e93bf20ff6eae19d3be5178f0ce1990c5a4b1865a10814e614c853f660067f7dbeb7e3673418bc18dea988b491db8144165090d4c44ac2334962da4451f84cb3ef478993c3f4e30906c065715223723c1ffd733789893d32042703692e792baf7ae57c1f4ef02a488e0cc945917a09c2f71bff8fb655307765e87d2cf70906bb1554d50df0f80d6d89aaf76bdebaf868defb74e7124991f2cf19094c7d96f6f0d5be58aa53d46da21bd5512fba94b474dcbd613b6408f666d82467b2440a8994a6f765c32327bcd117359b571022849c2407c862ca93058d8188c0efc0b92a9de292b8967b382ee080b68ad9598cba64bb10c33d9e4ac6d2bf2794be4183d59cbfb50bfd8c86989ac8d6bf9684dc446b664428005f2ae49f95436f257838ef35adeaf967dc2565bdbed9b7bf0761289265427b487f3f33e217c5d7dead7d9819f12fe92de6d5bc71c73229c7c752e601b9eec61c33d147f7ddd119ed8cbe61352fe087f81c83042effd8c5344ccce394314e9f8101a3ea6a4deaa2b0f2c8a94d63814d19241f5f3729e70cbd220d92f06b903eb715b6c2b52b76d855d68cd0ae53c2d3e99b6d647c4e2c2e9ffc8ce76b5d2752b38896e9b123fba890c30a6135201eaedf7da3d5f572951205e28a31377fa6443213611eab37c537846f95442199fae662b2afef24b3395a5c21820ad406136e241e157d0a9cb62d988d36698d16e8e57a37737dbabe2076eda0cd08c817f0fa3dd55f1b2e9090f31be1ef238be2a5e57d0e46c650b39fda6b926f26c531acc8bbd2277ad8e7adc53a2dcae5ac984ccae1df5986513b8c8e4c29e968b22463f1de25a8577d7a6c3190be0053aa945ae3514917db411ea2316408c7b89e0b8305957183f81fe4cfb853253df72c5d9aefb0baa1ada4f9627e676cb3e7598199d9894e06b30325b471f192ddaaaf65d15d7073c317a3922afca5508ad1e648489163786c815ea3c96167c8582e489e129449a0f937bb5f0457279105e9769c5ec223907eb9c553759dd2579931da163a3c79a51d0bf5de1a74304c63f80b38c77b4563e9817bf81f4c5246da577cc3a73a047b77f45a41246d7e09a10675c66d089a34d0b02996326480c58b1423e7c1bcec985b01366b667f289124c820eaf61034462b38ee450d2d1fac2998620a26c2e942f0390bf2cb26f5174cf35bb11b9d11dec56e4729f4cbc1ae5ff4de50cb938cef2849a0132bd0c971bfdad856cea4d1c49308c6bb9e352a7c01a8b8fb63c0228e87ce95963f1162094fb94f6d9deeb89a177865d6f2f2f86e9c1e2c2e9bdeae8d55542b49c152edaa1f5221eeb0498c5aec203cb11b1fc8d88fe36f9a16132c1635ebe383c3b795ea02f2c26e48b33dd0da13c15ac465327ff3761b70667ec94717ba78aec1a5c4bd670d08e0ceec95c52a6d0a36a307d86f5206db277ead894421aa116b491adbdcad9a5d9d6cda5b07af776d7c78c11dac214f8974d9fe3c26b80522c5fe45706f2c2025502035800f70f9f9de4a1b2016346fad9850cdf4b2d5a124a95e8c1fad78e5c4a1bac0ea83faa6059a775de1117ca4b370821a0ed8097bf4221aa4d575c90950d84aaca2559a3bda72a37d2b9f43820d811eaf344fbdd5da8ca99254c23ee950cae28bc26335732caa5bd717efd549a1648e6e5f5b46f8617efd22a4a53fb5de65e44a0057b5ba9140a306668479c796b1492168c61d0bd1943b36ed72e7b4573822e7e30da45ec91694a9652973a3553e594f8df971049e896749b9dbe143ccaf29c64584d83ac9554de14e2360ed5470c37cd8db23cd55b29026b51a13a6a8a622bb1ab3b96ab7a3315976ccbb19d07fa6d57e51233c039324e8458a5de1617f03f31e5a757afba19d7168fc58c0ac3ab5c32fa039411e59e52e749cb73faf72c092140bb5ce59c5280a8a5634b5600cb11efd0b08f183a6c97e921d5fd081897995e729ca71d89203dbff09349666dc486afce3531199297f8bdf8b6eb15f48d8a9a6c0de490a6bc335e8d2ff39e15d8f7768db24d38afec3bbf9424e40e455f3c82c5cea038774702e89d32f2d4b839a7d0f80bc24f827c3ca70defb7894168bea82f35c76229c342ae06cdc868c9803a3c05a0ae5721038e224ee215b955206d917bce9de670ee23407b796b4aad2f26faac396f7ef621bdde17403d4f5268d43c38ffc6aaae723530f311133e3b5e033bef048d0f260de1ccdd1627427b0603b707ca5cf6b5161278504fc447d876bff9b698ecda2eb2f34c848aa043dcb7dd9f7ae20b75a0741f33e50e9155f5ba502fef92088e91ae3108edcdde5ce7be707e599e55729c5021a3c291262e4369d28b38b206d68b3ac93f34235b89f8d9b0cb891cf47a2e5fcd4da5ee919f56fff3e10ccd2ba1583d6d6b0a7a8b403880555e4bcbb51a52f53626e3edd09a8a8aa3e5dcc4261fd0ade414868d0553e24e2f4764f2ea3445849c257ed78c8a308b4f284bd83d2755d8932a774840d46a30a93d70def1e35cef6275818a1850ef3b1cb892ccf98f93cd2e44f9b18c81f63c269c9d8f9886a12e728ff1ac2565ed7ec15d5502faaf6ebd2ad7724b681b1519c94e99033de3986ef220039f65770aef18826a9fe09bd626b7b1f102a2ff8735bfd31fede3d23f4408ceabd006faffd9bbb2eeb479a7ff81e01c02613def95241bc71087504209bda394b0ef3b9ffe3d9a19d9c20b98244fdbe7f9a717a9b1166f9ad1acbfc9f1b7124c9fe57d63931000caba33120bac4c75c2a09a3bc0aa6aa6f157e611b10af057f631d9668f0b13f3b9728f9467edd67e52113b7bc91c137c686eef40ab1ef25502230cfb883ad59883f7a1b748903d1352c173e0d31173048e63f38957c287dd639a29984b28f5f73e4f905c439c453dafc8f13d25a54e12720559dfb6d803a7ca454d752f40f7ca5284a6b94f808fbcf2a4cff543e7a8004d3da13ab950c4678071e703a00d96b4c5c668254d636d3c1f0756d2121ba3063f3b272c5880df53ac0c88e0606c8aeb144be4806d2895c2848ecca49cac1a476381eb0ceb90b1dda6ecf6afed3163a7ba44fb7317381e967cb937eb44b372d4e1d228072cd986a3f53f85f50782ce8e707ae1249543b40e7cfbc9265c81099587a0622c0792deb2e84f9b6410fa2b451e2d2ce46e1f4e9882909ea02e31003d14e3de1225cc0e35ddf842b642c915ef6fb9210959924e6e23bbd939b0343d1637e06d62e2ec2fea6713db1326b307ac552fc882d762d6774c130059abdac7afdc2c22fbe892811cfeeb8864d5cc9903aafe05a980abc903b93b11c56ece19fbd987a21ba82cb670f1a429fc011e8a6a468186dee76928582fb77ac989bf8d10d287acef0e60eb8f04f32c71b0b09a8c350e0438ea9d05fc47e41faa737f4122dc6041552d923586202a8dec84c2ec73645fcce3d350b8f8a2400113734e16959d0becc75aa7a540c09a2251f30abb379177ac0b04afe79d252cfaeab2406f50b8202f68f0823f6862151bde470b4fd32b37dd83ebffd0449f0a74e9121c386e04426e793fe0a3a238252851dc47de5e6e436b049732577c08763dd6865bc0cdb066e2162ae71ba1a9b85a041e0e328958708cf54651007861092d0618043ca2ba50fd141a3ff0dd9608d17d82efc21917a010decf3bd4fcdb39cc0873b2509c5e4cf87248d9e9232c54ea0c5340870ac467cd27d4304dd972a3cbe14607e1538cfc3200d2451be7cab8c712bf9d1de6af3b772933d992f2e25d8a8ad02178c484f7314b8232e9d186836ba3ec9e32a982c19443208498f11230a65eff25a9ead78b81a0243fc33d674ec4e1391956476c8dd5ee9e500fa018bef63e45539c12ea45808e3d1387129a17fa25fbbcc711901106223fd016747343b8a7c71480fbe438e15d15bd653ce34bfcd55e7967cd0d5fe3af3d183b5867f42abfd14ac00b47737b9adf41cad5d47be3e6c21049b332c3a4a9a9827083ff7aa31486969bf1649e31559d2ba0d5a39a984169fe057ef30cedd9c5225acd20cf47dcab775fa241c701d422dce0a0040c9a71da2cd0668341fd338364b9148d5c6eca887da22db19d7c62c904f16a0735663021f96b1b36660fbe982d8ed9a914d0118d49acc3ee70dcf6b6197cb30541e10a92858a0507a36c7701fd9a689f69cc4cf54bee4a9b2d401a8e8c7e4a2d4594e25a4cdcf3f588d04b0653903b16bc3f2d7b67c04b343421c61c441a539c72a4baa1340de58fd639434b8cb0a48a8fb5fdc4800baffaba18f13598e7ea7d40e5fa36fa0e1bdcf4bb9cf97555227b16de13255d14d021d9428041389b3180b7af0c5d353ce6a4182904b0af5c91567c111d88603a5b698cb172f6e04d662ef87a47b1a177adf317b0dd99f0ca8efce86bc96fcd648633b3842052a01a547cb50bab27a40cf0f2b005cfe252cd83623842a2c8c9bbb609b91628adee7d4430f2bbc5f7ce3e2ee895f786fcc400d8b30c7cf926cbf27bf9b24e9cad87e75fb6e9861f348e93b24ea3a01499b311d7be6af611141ef8f1f6e49619c4bb426f2dc4f90bba35e8f89c11ca282dbe97565446df62e6ebb22480392d3996e65d958417d5964eb821d8e27980789020dab4017d58fcba53719a828967b901eb2b6e8b6b0cef4e30f1361853f1f33e4989270b3edff084bb7c6a0249e905ae3a60197ef12d01626b674398bf6ba86320267cf54831cda3126e9343407d151bbef8066fa6502431a3f820254607bd8428ef96f8f17ced85121d34a4f9baefff664d005890cb2d3f275c1c3438b5b2a0e1f4d6affaa784773832677d2b69da2bb3b9ec03f44d33853b463d8b5b48c7fb96280e828bc3dc0dd512a06c2471e0f91142989c304f007695aa7c88ddeb85557167a83070f5590e7c34c05ca93542d2a2949fe3294cf3b903c43cf1b3814be10205ccc46c41de13807814af07a288fdd644d67220455e5dfc671feb1fb40678d5ef7d0cd591575d7366fd4495b7b1c58cf4ddcf644d3e226a36dd3d26191f5ee57238f101a19742eddefd8fa4a9dc306853e84b0e61144868a1d755c1e44204e0476819ea208593b69426fa04d8e2f6b17e246dd6b02158a297d65ebf03e5363075620af9f90ef8511ee10b74605d7456347fa65f41fa80a0f152a18c2b96c095b2fd0a185b73347dbe5f019d672126067cf67b2ab35cc4066b04c80be643f20ce8dc9e501609daa2e76824f43ee2704251ee0242a62152d3399dbfa21f277c34b49e21c07bad0803c5f36905264828b26931f379f4e2319a4de201fae617d8f7b0c3be99a93c6f436a9d3d221c032f171b63301bab1cc577e6003e17abb8b5377416b73a31414487e6884e0f7320960c08677242a7c73903243672f20de8741f27d9f003950e07617ad837c0ff546cb9378690ff8e925bd58b19cccb5e3470966bc98742e3d872f9dd0b306f8ef81c43d040ac7b524b6d8bf7f16d47f7257f03c8420eebab83585bfb956cb3bdc8f1444e4f6d145a6a63d96512e2bb7c248b5954e13c412f596e32c501aca0ce0e970634025ba93333651451daadefe616268cc30bdaa297b43e9953dd53c1ec09cfce2d659763cd4dcac4caa1c722b9166d283fee4549344e9229390b519a636036f4d8a7e4dee74cb8dc60dc717d80fcaaadb8dc14dc6ba43ac92a5bf3014f25307001ce0eab68165fcb77e19c787f6691c100631eb3f26ad51cdf6609eb539e3dc0f6543df0e1fec1bbeca95f4e565975c533fd326e66709a22fe8197d411fca19a160fcaf12abba46164a3c0f7fd323e5c430ebfef57080309a07b00ef9faeb58352abe64a6e638ae4db4c7c1be0bbc61c9a86e46d185e464e3bf4b7cc724273d5211437562259811dd659665c5852da01f0306929ed177ea3df0f038f1d13942f6b820534abe3bd9b1fceaa2bbae0124ac359054e6e23d06072b00a1dc54a98a8a3f904c102068fc92aaba5c4f21ee350f0a30de4a65eddf0f4cc54f65cd6cc6de406519df1fcc6f0fa16f0ec866736da12b9c7b32bdedf1ade721a6ce1ec840fb75adfd196fa8eb7dac2996c257d991b7e4789948739381e40f05af1bbb9bb8e2c663e26ebc9bab87f7e4de3f7a174cae90229709b2745521262668a5e00a07f95636632f154a08d3c59637dfe53495aac7e1a94932e867782501052a494a4006744bcad1368c6d88d058947027dbd476521829d6f40f8ffb85ce125f6983531c1bd28c76008accdd81b7cfc35d7ee9dd576792c5501662084371fa5b8eb91d72494bbbee572c894711aa852405526bea3a097a032a210c98abd7b23fcdf990d0cb442158b648527cb44a66022b3cea005a2b641eee5ac13653059d0fea48af40fdc32d88a3a3b888e65815d2fc72b08fc40494535793dcbad163b420dd329202688934748d41f7bac315fdb51ee8dec67cbb572de5119c38e730c9c3be130f8dd5446fad4012d4c1838b3ae2021aea5fab7a9241d669df816abc9d065984397af0a98d5a063ff8c059cb1889956559cb27490dbeb981f78ff08667004e4ef6e601d0b061ae38f393e57822a7d785f7532a8b8546fcff10766cc96319e88aa35dd23422d7c6f13cbdc96861054d619a39da71163d29d296fcbdbc276098f1bb73243145ee468a82a833da7402cac9b4861cabddcf137e6083b6912ea9d6f38892ed096c5b64e6e584976581509a89eb807f7216a57df92755100b46e8a3b9eca692d289fd7286629c610a2dcb394b83159e0868d717fcff0eda430d68084a61f0c04cac48030b2a0a2aaf3932cbfcdd9b02235e0012fde0b37a40c932ad3f718f50531910e88ccd6cf39ecdf3f5f92827511286b512a275bac8377b82c9119e71ec3341b33825995d7f7bc5d2394021a04d7394fd8c9ae5433510c1fe06b3287c30a06c18ee8c43281a14b772303cbcc0bcafbb4196b4f60d363ed31e6783426944b39ee57a0f8b951a08cbd19a47535b0fcc518a7eea5a796b66566909b35efa754e37f6a011ae98f33162959a63c5b42d6d04ae484ce3a073c838f39e7399aa73f0ef3cee1fe9cd04c5f648aea16685c7e2ae522312309b344a7072dc9cc267c8651988a371584c68a615d7b0162285e80f7b2c9cc924518b904d82c3fb538f041061f3fb30717eaf7b5b27f02dc002f24c8c0b8e48cb5ee12541d6547108a9a6571c48bd8b7594a7896c5059f4194e3bd7852896696eba8056df38e723d288c89b9eac2c458e751fcdbe4c1d0ff942771b000e17a7b618f4ba0e4f62a7857275cf828652b19370d55f9ab235094448e8fb153af84ff3bdf7093d8e2e240db7c07e0bb76643f459bb264f55292c755df5ce3ff9d4da98c7d8f2512815dab5bdaade1c31a83252ee7e382cc9c3330f1020a96104bd4513abac5ee801fa69e817bf9b6c6cc866e6946f6811a33677c42d1f8f8a6aaaf3baa0d5c1a0a7442b598409d2ccd1304b22867004f4f6286a9e272cf2b881126c6c0540e7b7ace08d5587b415781d601e0304eb0627e1cf146cf6efe74cbcde367adbe96061fbe793995bcf97933e2e6d51292d792377f97a17ae59ec77b3422f695c025d14a0de1c47316fea734a4ba64ec600e81f9a96f1bbc283f1cfd85c8392738e74af44738e7004f3ce7714eca852be09c139c93fad29cbb52d97fa79b0979958f340b9c6da2eb8894c52a339f4ae0855437be02746a75e34b2cbdc11225324069f32ff026d3a288b432e52830b553f8b420bd8a9170df809cc849eac6670047c1694ede34281ab407239aa6e7ced28734480b6721093895bac56488c19654556b83ff57e739344c8ca16c9cd8f11c39f7fb03b86b88f6a90e0ca455329925a99a2f8014c1b4f92cca6c4770b3d752271447c0af20b75a70c256ecc409f59f1142efe6c116b6e354d6ae3ad93dc8275e700cb6a9e577659c06436513180749a3adb458dd4140f8f3145f172229bd2ec8b6e8c6445aa72d86251eb754627b49b02c161b7288267c9bc236944267556333aa287c1f31e35b9cbe334b209142759c26f61fa2841c31e207f4af22361a687d1df01437a44269b5708aaa7f02d39b008550283f72cf6d62b72db0685960cf970c7d37b45049801f8f2a1a0c357767fbe86a1060892c99392ad8b7c498d70aacc84e9a04c50c2c57d2bf9db49afb5caa3cf55dd15f6ccae886645d9fe113c54c31f25b4587603ceca8f360004b4082479749997cc2c95889e2ee1829161c93e29b1429e127aecf275026ac27b018f5362b295a0c6c1be9e3b8c2683639f0671935144f5769b2c4c353b2f67ff29f294e55540149ccda734268c5e05791e2cf48bedf7d09776222fa63a2def4b8a2b58ec7e00931297339554061300709620a0e88c96de0c14b67c96c281afd68c0f755f98510552b3f5742bc6d90880096513ccb15879b257c5494606bf2af0a6137e55e0e938f3d31c04e1f1e54ec850929a006bb3b50a2ae85b993023206d849e4e8c1327dae4050c798db45819baa06e0370f1393a4318b8987d398142f2fdc991ede0601019b71b9ded36d650f901cd691ef54297bd59d8abde8b18757ff2d8de996245775e34c666852a71a2874a1c358aa25e6c31a63a3e55dbca947b0f155cd0b2e0889fd23e9b0070654b2e5b993ad7d2d2ddc648c00e913ac9ae5084a1aad32eb2d79e4cc300793b35a8c5499d1ad27cdec223e6a7d4199e1499b392564eafb3bb0847c539ded7a114326e67c34d12642149fac97a659dd485e59c14f02ce1d93cd818d1b6c85ecbc4ab5391a29c0b4b65ed281e0744bb378555470ba95d670b6f752412dbfa017a756426864046f78c0a41dac1a80da14d949006c511438561db000309ed5708eeaac8cf86df06a00e76e0b9eb2341f52fdbbd198d87ebeece5ede2eda42dff231469eddfe35256380c6b3c3de4295c35ead6e6b4d59560a9889d38c2796ba99d97cb1263ababe7dd9d097ed5a395b4935db12b7f83ac823574c260a56f8c62249ba7b40600204594668a00a5516e78f496dba9406b6f2a00ff187a156c5fafb4eab5146ccda95b06d773ab84518b94a47a87117d4b3e1b42ad0817f1a8c5586b87ee00b9855a5884b0eaf637f1bff2d9e8011abaa6a8624ee9b4f811988e3ce9b829df252884234dcb117d3ef008004b2f2a5ee7b9fa5c9284dd0cef62d91d9816de40b3123e06cdda591ae4b09d98819302cc4c75bc1f832a5ebdd143b4e543986c09cf66228e4e6d3306f9ed71ae3600a02fd8914c00f937a8d8e988e7ee41e9edb2648799ac782f978d7c0d0e18ba709a254eb30488891107a8da3d148436c16e5c66032c645a473ccf0ce5ec9acc7c25cba109f1eb18ef2c654ef42f80943441371a58469f519943d6217e0ed1f15fefe3f49dd41edf7602222acd1c1fe3a560fe5f13ece58c76806efeb49cc8d76a7fa3947cfb0c98b7221905811762da507388ffb7083eb4aceecad2aad79273d629cebd6bd510a8d222eef30c102c45ecd8c33723de484bae3221c6f434038cc6fa55c4a58fc6d60ec278dc27a45a648d442661a92714bf06a9b0ab9b033e9ca08a2ce77f735fe7cc7cc3a4379b50c324698113704bdfdddc29c2925bda12d2b72cc43aae5247a0a83d5294370c292a7b4f157e6815fdd2e731611eb3f5824bb081ca3c2cac122d2c8f7e966aa59e74fa194fd04e20b451e4bf0a0c40e2e9c337ef1b050c37e9f3435652cf50b19b2c1889aa242656c12c21de06982409063c92ee5e7318d4de775c18e1f608e72802fa788ebf6046413dbbc19a6ba8e1a554491ed8d8481ad5bc3025cd4bd3a0207f0bd05cb4d3a65b8fdd5bb19792b2c4442c31f67c5571c598aa9783650dc41c69c949af4cb589337b8e650eddf7d13730500642b712139d9ed890abcf41d1ff728ac68ca751d3a89ea6f8086b54591cf46e4ea6427bb776818af257954954bee03a334b7c4d891bb30c628141f92e3e45b482fab2ff80ea0380a4affaaa20ae8d52a12aa091df3c603eb1fcaa05dcc8ea8b8adac1c484cf71b72daa6f66317bc64bd4b3b8c650b90de479899ff4818b53f0fb773720e08a0da7f369cc6f4402a773098cbd737638c52f757a6aa2b57487739cd41c89cd0370e225dfdd3da0e24a2dc3199608394106957b81fef6818a4f1c7040da1db07d20fcc113b49825d5326d797e82d598cc44a4939b054159ddf5f1f6c1cba05e1455a53377037f74b76f6bc1b73468ba7d509f9b7571d22a047e60b5dafa7cfb80df532122898d3665ae782639a849d76a909b5d96b493432e068f6816682d0a888884f9d1688bb93fa0171b554c2137eb02151c2a96192b961db5f644c1424b7c726c3036366a6ec3c63c62c242326b3096354e8637c6dc1b58cb325904a8c583d7b630b6064e88c2f8ce6bba17f90734e93698784b712fdfbdf402b0d1f8cea48a3d47aff542129679e04be1b19521446bd4309eb9f8dd8300b6072ecc9730fa04c34b88c5aab0099d70241b58bce13a84509b6c1577ad3ae4d328a27d2264c38e8a85a926bb4c3c12b1cd39134f048199e1cc7cfd817729a0ec659d4047c5773aeec121f4e841e483de034e4b2df6958eabcc7cabbbfed6575775102f74c53613cf9b36dedf943351d9b6bd3b4cbd2429345f54fa4d3cdf66e2b180c5c320dda24829a90dd95f3bdfb7bcf3253adf62a292287bf30c88b73699a8a0fdae2a85af9717f8ea7b4e2908a9478f8a76a667db43eb390257bcc271463bee7317d09ae19e23b7f692997fc427174c60f21fba8de96b5459c1d8f323a041b93996432eac092ee36941b874427bd25285d443956e53e553fd334755b85575b9d7a49bbef5cf1cb997ebe0db9f563ce74547767922825071f2177edb6410a8aa7807ffefd04e6af715696b3ff5caa1bfa4a7b478c0cea3397a3c3f10b880bca33613b3f2de8c35cafbd36662519ed6b451d05f218651e05be07a22651ada18e8ee6216a0592a3050a44d33f618fa234ee628d685f4c71239a8736bba5b58e24183c18553278442aaefa190556f03dfa17eac69a92479a00f7bbea4ca452875bff50784354d31ce8b04827a4c135e3f9bd9908bfd806b647f873964540684fcfd940ad32794265baa517b3ce781f44a5e0f5151668a63f224043d7e932c9849e6c3a43ac1f0a777e4fd699cff6932abbaa70af0d1fb9f82bc6f439e8a144b12b4cbad0dc6d6fa2eb7f376b9bd606c2fb45daee4ee72087ca0ed720b914ddb2a6c184a81a673f627ee347772a769e15a762eeda30e5506306767fb6702389d8385f1e60ea9f272ff9ca06700e3206c66a265acf4e0dbd51ac93d876d088eb7780c2b75ebee760dd8cb7ce7550af4af8bfb5ac3dbd7328a6d5499f8b5d8a2283fdfdaeec9b7199a82ede950eb39a39e53bde7e08e2015efbc93bf26d473acf71c51cfa1de73443d877acf144646d98993d673403dfb675727a047225eec99da60cfc4864e3ae0599c11ec3c54f816679b26f8adeb483f94b1d000bf2f66b9ca4e79c4676b1672363add89dcaab8979a2bbeef203701fe51f5a03a7df3bb0cc5d01044091f13e0e3c2672f5a97366987dd3fc4dda47ff96459f20d888550b2ecd164ec687ab2eca14cb22c3678b26ca17cfc189523468246e5b9df41e57e79f29cf24228ec1d94570fa53cc9705d81b2a50994754da06c6902654d13285b9a40e96802655313281d4da06c6a02a5a309946d66be4cca9765be94f8bce5b43719db6bcb69a796133678cb29f7d1e5f467368dafe574653939372ca73fa542985f32fd974cff3f24d3d702327d80717fc9f45f32fd7f43a65762f440fc5921bd647d49555f52d5ff9054f55b0db39649302c97c8266f3296d7c826a7c8061b3cb21959ff4ab2f97b76bbff0912cd5bff5da35295e5ca9fb55fd5034625daaf3a01a392daaf9a41c2db10e1f582745720baeb04e96e1645777da0bb1f4877b876a8b4a25c2258825fd2dd03c64f48baab50a49da4bb47ccb802bafbfe2349352de5ebfb3c5a8040e2ef188601691374cd06134f480b10bcfe10a405c84d7a405a404723d202f6475ac0f3293aefc8fe169e6f32512969e71365effca0e29d475ab0252d7cc3ed0afc026562caa6e25455b0291d6fdbae320542cc427ee03e54d4a1fb15cf0edd673e3bb41457383b0c9fd7565c3938d9a50bfb0f1bcc1285a26f870a4612244cc6121aa194ca5723099626634b532794f23b2309fed91d2ac29b3fd6bcf963cd6f9fe09e3fbf13387dc19ddff2368d96b6690c75777e5bdb353a11eefc96b66b34b55da319e1ce6f68bb465ddb351adaaed160e60b9957eef8a55d7a0a79fe67111b3371db7e6d2a7b0073f7ef673008e8bfa1fa6c83596fa3071565b0179151061655687d656a76da8be4566d2e907031b31583ae2104cd1a69f109cd3e06193606238c24c6a4a6f28153f42196601c007ccb9e63abb11318cd48e873f8a7ceac89b81abf107717ab9d28fc0e8974cb67046442f6a1c204abbec9a5ff38e65330b3895f6b88b66c43be6f5bfef97602655cd4f288bedde7181cd5642646267d2b408330031dac1c3fbce13ba8b2052f1717f2c5cf799e9700b672c6ef05e6e0dab0bf029e8993c31af27d841ecfc07f029264c9cc74630b50ca131e6ebdc331678d22c7b730e33bbe7f7639c78067f06bc387d12c9f108807c80cd53545cfc2649b8cd7ddd1bbbb1f37e2b7aae8e7e8d37983d73c67a7ae3359409571705bdd5a8c6dada2c771570fe37b1be5aea5c5d8d29adc530c99c3ccfb0762c7770663771a3b2eb9ec58b2b65d1d27c75edae407d39d1cdbdcc9a5ec6366d0069d4c0866fe9abd1213474ead8b3be202132f19efe1d943ee31edbdc6b413e1da78cf936efa528a31bdd38632c68a27979599afa67656be9a1126e1669b5880bbaae4858b4754655e72ced7381d339c5933bebea86234bddda2a9ed167227aa90257d0f3c48540e3b3443edb124e8e30a4b3f50090851d951fb96da37d48e7a09ee186b6a5be86db46b2cd5bc593ba06fcc616ef365b6b371fb385edc3e50e538db3e469fb17d347cbf1db97d34cfb68fa916a4d650db07f0d12e8160d4480315956885de0957f71176e5d075370a8dd978bfd59e5455a9dffa6f2a1fa84e9cbc6391b2ce2fa4e6712039b6ce844d6721b1e7dace7388ed948f11613a2f3336d7224c67d7234c8f0663475d814abf37c23494a5d43c96d2f4584a3b540c9c5eb3ef3565efef6787d0a1ebc9805aa4678b60306ee122c412f2577947604851e322513267335ce61ceb32674793391b1132a71321733a1132673d22845497393b7a0869313a8414d2a451e6696f08a3037d665bfcd5dda9b33613802da94b831ab1c0163da06182b9c31c265ed45c1e5d025b9808bd17640ffc5ad3f8cd8d2d80070bbf104f836bddcc17bacd1ab30e5749b8647e2209176dc68ab616245e21121e1a8c0d35125eb9249c108c258446c2834f25e1ab524146970a8447c345114ac33d8f86f508ec250f8fcc3e5e55e534b2eac421ab5e04597522c8aa136100ec441800db1a59356304d294fe721bbd5446d5e5befd061b3d0bd8e88364725766ec4edbe94e6aa7c3fd4c8b3f8b954bb1158c6dc36c85dde4583036161a996c8c5032e978642285ddcb168f3b6dab1b869349d323933e3fdbd542ec1dfd5bd2177423792f82465a1146f25684913c2a7b4137773422b69ee6a71ac96b924c8e9f641387c9c60e0ad392cfbd1d0989af01496d523a4efd485acc869dee0196ea4be2074471b822b00999353fa1235bf304fc5f4741bce936ec398adb35045c572d261396d7603e4b99d87a4bfdb8594a777c52f935a34f5d4aed3566bda5afec7ff7b15dd65ffc4bf1af6585b165c5e35f8b2af12f6cf0f8d7a9aaf857bfcc58bfacf1af91e5f2afb9c1d8dc38e852bce25fd8a4f1af8319cabf1a1eff6a5f635f6b8d7de56f91d4f7da26dff64e67afb2af7ab8e85c8f61add5d95757635f6d8d7db522b6f876c416dff4596bff0dec4b8a66ef655f2d974b1d75f6350088226ab9d3f9d7ca6df934fee5b72a34affe26abc3a7f2af06638d6909a8e3c80f61c65f678566012a2898b4d99c12bfc7bc8f29cecea00f9f6ce1538faa0013b0866e965b2df3d8a78aa25427e622ab93af7d2d060bb09a4c447f818ad409e7a81e0a2eba9c98f17d81038c245d21ac1773b013abe6ab88bd63b19ff7229f869a069d34500de5781e782f03f8f18f2f9ee119ad79944fa88e9accccf2c10c28c859ca29d6622796a3ab7c5332c1a126f70d94dc37053657d3b89ce29b79c15851578f52461cf5e8dd79072d8f91764319e95ad397121a275d870b827dcdf5b5e4a199acfda01e758197b6c345c17d94ebabeb31d33c191fd3ca301995cddaf6186a86c69cf431c454efd47cca98d9528cf564022d0c450a380d2cc816e09d36b24875ad1c625823a7b54963379928eb1d8804cd03acd03721db04b501b2513c2b8f6eefd16c7e0dbfcd8f80c0c6e681afeb5732724d2d23d71873970bc88559c5746ceb74d57535b8957bada15ff3fe64067997425fcda3edf4d0722d3918ea5e5f599a49b6caeaf26d3cc9ee163300b1ed15c608d05feac9d024e38cf7a8f2bb2a3e3de13ebb2ade599f138df554c0b57661808cf55db811f7c2caab197d6160045d264e71aeebc4bd6e8d046b75dd2a730c0000841a408159fd9de916c23ac77e74ff3bff9c591b38ab33e23138f9b2ccd852e3e40bc5c98b0663458d934fca77f760cd6180ff28267c74675f57e99782b1a5aed2df7f3ca821dc9aadb1f6de0d410d1a075787e776eb542bd46e4d06e7fd998d9a4e6ec34eae6fb766cfc19a3dbf7073578dea97ee2873fb1d1d63d8d75d2501c33b70636b48027ec17dad318475295e0658d4b8d1bfa7df2340f268f4a9bd80d8468dfc1c7fa786d89e18e2ef12b583b11af7b94691da72aaadc1c40bee738d3cb515565a1be1c266616ef3e76a64aa0da3adef170e13dfd70f574458fb134dd08289c7bd7240a34b4977406fac1279c5970f8ced1f34c7f5c656bee92967e6afc9cf6b140d35cbc5cca368ecaa0b6befb5657f12454fa5b096d9db9e892cbdb7c9cc279878caa85fe0bd926df0a19692cc33ead75ed2ffee6007643bcfffdd66ac0f9f73c40b44f7df11f00861381c8cee3307e6985f185bba3c76ca3532f68f4d5d1e3bbf74ddc1ebc5b1cbc075a5789da5c1a34b8373e69ac79466eb9a34db8910665b31e2b8a20c9bcd08c3662bc2b07906cbb20c13023d8f37e29dd93b407f5de2be3a52a0ea360114bbe2a1b2375d3a01b12e36a0e83df4e4eb7c852bb13c02010316dd84e3051b00f88cd76b603df405cf5e0bfd8dedf722bbdf214f65d9c2fcd466889fdadc985420d94be20bfb73e400089fe5f074613d1accda55b03a57725f717100c7a877d472f30a560451a59210bcace61d227cf20f3a6133f384c0b554de354c9c062cb325150f8617307b8a2356bb110c7990c9d9904fc95e0a6b5f2a7b0743c96dd8d59e995a4ff17d067a76f3b8c4c71b81bc8a19931063b613fb96d25514d49e27ffa2dad48757d49e52806d83f22c0befbc34997bcc8d7be9d65f75e93af984dd974de847546ce6f6ab2af4a4997b5527c65595ef67f691676deacfda88fbacf5f73f6b0d9de5e6c2bd6a9d393b9e5fdf020a03c7bf2ced184afc5185586bc6a759941ae63cb9ad6279532cbc995c1b4c9cf82c6b6b83e7599b30ea1640e562c297599b66c4e82931e359b2124d0dc6a6bae0b1d0bc831f0dadc3d8f1f7680e47cec4b3cad5ee32f3dba21c08b3eb7a61763d2f57c00da2bbac468c2344f1d066c38dd50b9e9c879d1c46f474958bf05b8e502e42359f781ac77bc6dcc5080cac870606ee6153109511aa1555523b1e49edb049eda890da5125b5e391d40e9bd48e0aa91d55523b1e49edb08bd45ea276523d1e49f5b0b3d45ea076523f1e49fdb0f32b6ccf513ba9202f4a053972ac5c798b0a32a87ea20ad2979b8096e09032af06b2cd4dc6e67a82c3ca4b70c88360a011f0ecf3a360d6c2a3e0bc16053337426363d7fed41f533ba6e8d82c67e2bba91d5f49fa66cddda3fc8e6f9e59116df663c8e8aa4eeadace5467ac1e7ede1a94f764746c47a5467422900e75675b3b42a48e4a8d68c570b6357591ba7b2e515f5fa3b3d8308557d7683d792c3376d484d89d45d96a4b83b165882ba249793bba765b56d96a09ce58224cb9ed049768fa5cb935af66ab696b364eb65a263c5b6dc87df1dcb41c7b5eb29ac6ccf75773d59a5eae5a4bcb5593bb0b25abe11aba96ace668c96a0d2d59ada925ab752292d51a5ab25a4b4b56935badbbcea682998160652a8b28ec211595b358f767b2c6deeaa04639903dcba0d1905fed59aa5716ab016ef3f30480366b45f851c21f77f2653ca705fc58cbcffdbc31e432ac37d00cecb0ef1098d806f7dd2bccfd8af61abceb2a653f386e126f4d3be76b7098e474de495f9fb09f35563919a372d2663d83dda42b2e3e3346725d666cad51deea7a9833d264489ee86f8a91d4c4bbe575979f8e5d3bd77c7bd38818c9eb3ebf88f8896e0478ad6e25e96a2cbd79a3954467e91d8da5d77df1132fefb67c0e6e419e950afb10cbcccdf9661070de6b1afb0a3ea7bd9961f50ff4678397ddc33e924c70c5af9e0584a28e2a6a8345f732865293a8be1684b162913e1a06bcbf07a160ee30b7ab2ac30bb04cfa2830da762176c03faa0125576894b91367beae19169dafa569c1827756f84e592971b778bf67276f3096d7c873f4b7d881c313bbe31070363cf309a4b86a922afa8aef9520bacf52cbf1de6be7fb8299bf1a71410ee611f0d358cc4854ee75cb3551f13e83994869bd8d28f9486d276a3beed141bfcba0837e4bed076adf53fb01a38eec7d8eb29ca87dbbc78ca4c1c17e3f89df6267fc22f10f92782148e24188942f12ff22f12f12ff22f10f90f86d46d52f12ff9f22f1336f21106d4b1240c785a7849f5517cbd23bd773fbc19f2e134602e6812ffb1d3bd5dceeb5f369dbccaa1e33ef46b2c7a24db4c2a165c0cb14d70fe148da9a3ee96944e6154db27513b257fd52d2373e0028edef40f6aaa21d2204d92b2ae4bfe9a9acdd5b34d66e78bd956154bd9528c7be9ed5d78d08f96f4738f6752b64cb972c1b33e4ff665c496fc035a8c85d6cd0920b3695fccea6d24f10ceb37c5864bd509f41c5f39851f34a6b2ed94f9ee9399b2580910516e8c2d5539d435138738fe5da5fb1916d91c4a96a1ad68dabedb758bb0bac71872d52e1cac0d702a8c0c062aaf97985c201a14b6f96b3d1bb7b7a86f6e2bc42454fcb5a7be5a0b72f39ab2d788a1c86942413163dfe79f9f1f78fc9cfafa474f81e4ae658137724a8e01f20653da832c8e64e8c6bf40852cc19f0fbc70f26040536d3edc1c6b25992794f8e76d0aed50f0f65bf21819fdc747d808e84186cf44e0a7fa4e093f7e24b502bb5ba7c24f86e9b1d8c7641aebfbdf1ad88e1e20bb07b56fb8b0ad4de9f606c489a176165d64f152d34e42865027bc793755630da1bc98bee0cab584976d8c9a86299bdb52125099616b36ad22b809cc5f8913416a0db8ba4c3ee8c7b83ee01e97585e2d7dc0164278e825cd9e513b53baf62310173539133336714794c67e5b9f431e6313c3bcd884c699da7b62232a5f560a96e1400414b4707719878b9265d1c3e0d86b091dc9719db071d3b97cccb1983b18cce2572bfd7bc7c1b989a9e51320d27c3f94db5d122c4da7e94c750dfab3b31cccbf508f3723306b0455b5f57dbcbc0162944904f90e069b1aa064a56194205d01df770640075aa0321adf0f69f52246a56291c0f51ffc37e832466ddf3ecf3e585bd8b6ddffe372eec0fed315f0bfb6b61ff6b1776efa66ceaaf85fd572cec069b18b5e19aff5757ed979cf15f5cb55fecf873cb4c7c2decaf85fd6f5fd87f03c7de9b5f8b59972d46ff69d9e24bd5fb2faeda4f66c131823ff365c6f2dacace7d2cf8b32f18ebeb30019b7f203540037cc96a4b7b2f3c9f5dd7f5d9399a31ff87bcf611bed9048df9ce7241d83c1663567ac0933d66def34df9bdce05951cb752ce05f2da590b31f87e313275184e76ef06efd403535b115ebe4604d54515efa94558a41b1181a9b528aa6bdd9c927f4b602ac03c6148cb9053d8c4bde6695b953f96207bf94f8389c90325c74e1f99f9b2be5acc3d99293396d1c830adc850aec0917c17cc7af2a0bcabf28ce980eb226b2baf9fc5c4cf2df46de31033f328d7e22f0c4060bd19ba06f17465c4e5798bd5de5267997e7a9aa0384b134c94cfd204efca1f4d13dc1a8c6d755672f8c388237b8db7e435de320f8f2cf792f73b0aff380838a017cf300b46107040beaf7904e2c0d9e030c4812e63e308c481b3b125238838a08df5230ef8c6061107eea40c1381387036387d057120c28dd68f8a4c6847f0ac7f1672e0083cebc61cbed85eb4bf8e673d0778565028fe2b785607d8ce4fe45963e4591397674d9167cd8867ed91671d14cfa2c18a670d15cf1ab93c6bac78d6e48ff1acab92fefe3600bc2f9ef5c5b3be78d617cffae2595f3ceb7f90677d42ba032610508638981ba492be81cb9c673284e524d06848dfee4056449c4c0647cb7fa03f62240243b5748626605807868a05d74e3671b1b1b67ceba5e0adb8004ec06e4781f980c37600ae324e66850d2f5ad4622556849c3227461f380f6bd157b9929b91be9e61d9e70123d80c2bcec9165f76c68c4ae5f6797228773d1d7d60e7216460455cdd0c46d9186e9b5e0123cc0e5693baeab35f57c5922c023bf4e0d0566831cf97d1313b1e3a66d7b322796562540f44ff888f7a8c87040e39057c6cf192c34c87461633215eeec718874919182f9481d1c850fb0133291a9485f14259188d3b6a3f513b6562bc502606025322a3695016c60b656134f66aee1ccd8d59182f9485d1a02c8c9f1fc9c2f8d43cfc4499b184b60a4bd7215c0329426b93b175c4a2fc237569efb48dbe2fce367a0f89099201d6947833e7e1855dfa2202f5711ce1bbe86be9fd7a91dbbb4fa966dbf94035dba8fa083d6dabec46244bb43e94dfbfb9d58cfa9b8b8bc85b55977b4dfe1dc545f62663fb601df52e3504eba8a38b240a3d09dbf4e22265458681ad61f13bca4393cb64cfa37d26207777ce4a5b16de93efd461264b76c3f39dc611be906104196fdfeb836c6b54dc8a51a4292a3cff3715696aaa3e0621cafb6b9c3852d313e7e94e2b1e333fea6ad193f0d9b78feff4e438ac74ab85e10ea575456f39cdc0902be7559e143228dd3a40afedec8f481b0632184b1539383bb499b9801b692cb6b7239162c29094990bdd1004d29a925d81a2d758c9c003e1d76b21b430dda7059f24a43e6ab05d8ea7db983e695d504f70823743f300fdd4a153d43c44e592a2fff9798011b640ed899a07bab4c1c3fe19f763836e623068b5a028c69a23a86c3d03f9e9228da4733fe2ea3b3327833f5acb04dab20648dbcd04d27b3b85689ea0c95576e6700895323aa361459b19961c73e0d2b57b711de13399b118cb589a054b55c7de9a8c6db5dde8dedb8d4cc696fa6eb4297f1e18678ccd677ab30ca86d57197f6dbf301170aeed1deb081150170daf57c86a87e6cbfedb9128df23328e62574489a1e344c22044879b644dc6b2faea2dbc57a5f9d490bf8840aa28acb12865647f8b14d38e9062ba11e558bb31cc76ed88908e6e444887bf56dbefc01a8bb1b0b665c6b6dac2daa88585661aadd0ef05e5d9606cad5bc977ffac95fc93c3a89711e9c0dd50c880eb217ccdf0851785ae71a6057722804bdb11c0a5ad8810be6604cadd197069ef5a290055fcdef6cb0a0780f05f6ac5a27af8c036b3ee05d4f08c561f9d40917c080a0c9bae0ad34594d68f1c5563d6ccb856b06a17db04753dccf58b88fe7789a87fb5a086a222b37285302e924824c9bd8f461aac608cf878fe4981de5f14f04501ff320a88b54b4c6e858bcaa3d165ad5c6029cdea722af7d14074e424b70f726eab9933c7d7e35d871663434d8b1d3cbc330ea388a1165b7ed0632ecc13271bd69cefce823136d060b1dadb8a8793efde606caf93efe99fad99f5a9e4eb42895f82151ff22bb8e2714add4f3f2b6e208a7e3b110a88ee0ce9eaf41b511754687541e57a0e2dbdd807cc7028c78b10dd506ba6645ea3ab545c1da6cfaf29313f29c0003e4513ad57140ca0b9fd6b8848031f144a95e3fa223f7e6765cbe5f89d02ab6a64e1bdf14f9db576d6301b5625f27b4b8f7da0c0010057643ded2ebbac55284ba27901c32c13491d283df8a7c69af786bcf36f74e73e98f500ea7a6366ac1e2e61f46b90851fc0e8d789691c4e4c3a8d65ae82f4d73c90feb606d2dfd741fa3b1a487f5303e9ef6820fd92845d947ed84a154c7f5583e9af6b30fd550da6bfaec1f4373498fece194c3fd75183bc32bb5a398ce1d96e2449c24b84220425b5458d889460c597696f331567ab26ab6c641ee391522f2e25617c1c7e03c21b85981bd6d56377e00ffed69afa9c7526d51b89492102fa8869e312d3f966a38809eea089794267c40ea4d563adddefa1a57f3619368e8d56f7fbe56fb1d1ca49c243daf46a854d6d6b929d42f39d3a115986fade548bc832d4f7a69e1ed32689e974a566f53ba8e933f0416318d7fcb5590eef282e7ca922d8bf2bd5a72965c0f0105412e3a178a6990b0941d5c6fa23507d638311a8da587f04aa6f6c3002551b1b1a81aac6de8744a02e39244d8646a09e5d78772502552efbfd5e60ad971ad498b419dbe0fab30773c2a6542a93d39f4b3dc2fc0ef218e85d33bedb87c8a2bd1b45d1a8524a7f2e8475f46710bb898c24dbbd0f01e2961b13f1a01613071d525b85af2e82819f2a481d476d02f0ddcd50f86eb9d77991ababdb47d57da3d4962e36c161d71eac7dedc1dacc4cbf072b3c241eb545e14e69d708851e2f47f3e412bbc502ed1ebb1d441ba196bfd908259790e2b7200c5c1417747e9bd76a3b3b501cea7bd0c5ab62f2b40a8d20656f35c0f0560047fc82565b0d8d86a7f8d50ac5af56297ef591e2570308e21985f44d48e07e14718a5f7da4f8d57f1c49fc0855dc02824694112b6097a2dac572f1dfe0fb083b52362b9b59337e5958b198f97d5b4629b8c899783b5af8b9e4dd030776523f9216145faeb10710505e123fe455188a2e720a8859fb99fa01f1e5188e86421376713b8a1f72a55347061d45475eefec14020254fd637fca8dd4dfb1ce8c57797bafa91fb704c4990a30dd9bfe59aec5b3df2ddfef3a3359b2c94ad69467eaef0ce3fc96fcc7c338cd17a15dee9f0fe3ac5c0de3bc5060f06832763c0be38c10629b41dba0caa3ea49c6c5a63a533db8150797c03d35a67aa050049ff102f416b25e40cccc45f3455e335f489935c47cd1f47866fbac2eecf720279d5eb55dd4c30b0cb634d3454b335db422ea0b3635cb4533a2be6053335cb434c3454b335c3435c3458b99df6286530ed128e0863c16820195354936c74f8a9facb1ea898f1d5c244b8fbd7503ec2d7d99bdd5e3b2b74690bd9d9fb210b424c8de7e05c606d95b338abd9542d89be3635f7e7617fc6d4a9e68bda5af188b060f318d4571d4db3b93b13b4dde3a45cb5b2a28692b18db0a9d11187142ea4202bcdf179434d494d7ed39e06944485dc71b303daf881d1e52a7959fe88407636bd8f2895bbc807af661272216dbd134b7a6a6b9399ae626d7610ed0775ee5357aaef544488a342b6e1e9ab9e0f9aa36afe58d2fc41c9fa8060d3f10231f31bee98d6fc9f1c507effa5ef4146ba622af4f8441d61f7051c8d7871d56dccdcf337fba5a9375e0fd6f546fc9bc54b404dd5867e1fc25715b38bfa92abd9c4b2767bfc7d09720907af2aeb56400b795d692b9e0c9265b94a7fc68fcbdf929bf5bb089939f5234192b6aecab50be5a5a2a609dbb94203e168c8dc3249b6e50b23985f3b38ec7cffa5795c33b7fc46fd018d7f49853f3acc2c56bf0ecf42a6f6a84f3a66e046f6a46f0a65bf3445a1156a5a6cfaaf42f136c6ed6db3e22d834e30a36f5cfd5dbae09363e4e8805a73dc1e682ddfee14643e01afa85a5a960b6100473a0668f390d7247111bb403ac2c2d4da5caea526b7f92dd2d66b4603f82310208aa1eee3acf786e0b51903c1c34546bc27db600652823f6d0d3535fe8c29031e1bb7023ee851bf2c28d4b170696d5954c2ac6759db8d75532abba6e953972d68abd6f85cdeaef4cb710d639f6a3fbdff9e7ccdac0599d115f8eae6e428289c783838ae2dc626c6e15bd1d69f230beb791ebf4a524634dee295ec861e64685fe240cc61267b9f691db150ae67a4ec01f7626f56e70856af08eead0f3b8c817a8bc3be1059a2063c07f721b76727d76f2f1e2110d997366cdf8fcc2cd45548f0acc147a4799dbefe8c8fdf5a72ea448a01198c008c0ba811b788312755e2851a741893a2f94a8d3a0449d174ad46950a2ce0b25ea342851e7851275b08a126eea0d4ad279c9a936294fe0c6dea0049d174ad0c136dcdc1b949cf3f323c93925fbc6b8be844aa6ec4b9e688ebcc03d7100d0d3c67e7943e2e3740aae22a7045e0df13db8ab28365cc781ac3d53785154274fd24bc9489e2741ae9752ec60b5d9d450832c15cc01e8ae6a84ed2e14b912a6a676893e7765c1748cf9cf471c62cdaf54db53ecf9d588dd5f317f03e34dc47decf9d58853acf91db21b1e62cf4f23cc34cd6a31f31596e53dfa2d8b5264a37546999e2428b30e10c511d331dbbb45c563540052630dcc6cfa6a642a6e5e012c982ec11ed7b4b050650cba14f07d011039aef214bef974bdcda7cf2f607d53767fe3770222db4c80ccf1035191a764877098f90b4eb3f3b3d6290c1bb91f9149a776a21a226b5727b80999f81a6d79b7fdd70bc35096091b367ebdb4c968a020d5ffed8cd049ec8cd0eb0917badc98b518cbea72633a96dc189d3a8a7b9c4698232f7534c1194be856da954b98d8a411e6ccf8b89576af1166223c74bb73eeae31bd43c3f5dc3cb9a29df96afacf16e5d98b6eef08336c6430772d961dd6b37554355b473d2260ae190110de02eb1a70abb9b884458262fc99f972e7375f5a505abee6da11506dbfe65e0545aacdacb7d1830bbe181606eb39d4779e435d493c977de335da02d1dc0b3e7751634aa874adb98e72c2dbf11de955368b8dadf191a8bf6882cb0bc6f2ba5ba464fca95c6dbd32c054f8606e3e29c2e01603148db50082528e02357bc72f5aa3e2d51ef0ac4ff0fb9b677da2df35328dbc29014edb66d711e85963cdd3b3bc097647db287b51e85951f6541d77a71ec163a2a2f49a31eca96d66be4cca978968736b2c5eb684e6911c9636fee1b11d086a92f290f948bf2996b79a26eb5de17694992b663cd7ee95071b201bf2a9898232295cf22be77c02b9bd2e81d85c1b812d4c30b01cb166bf723e0541ca983b85a522dfeec26f71eb57746da1a1ec90dae58e033bcee59a844c39314041100cbf2938e57e7ab8940bee9f7e196b7a2c542057a699731fa81b7c201b1e4840906b450da6242151f25fdcf72a1f08f352dd7a1d6e5dde8ec2a1514e8812f73d65b0abab50f950816c1c898e47758714022606feb77fe50e9b81cb2a097a207c7718eceaaadc7edc22a5c2abbb23e15f94aedc5dd4c75351c723f9e52e74b077c65d4a5c55fbca8ccd7508d0eb9bddb4ccd8b4ac47b45b9fb9d9dd62738ce1328b034c327c2f4ae2907f9e46049a2df1fd7f83367488edb1892173a19ae32dc3d41f2f34f6c9e9a9432da36eaaa5ce0d79787e2a283717ecce642682642114971dd2b05cab7174622b6baeda6e36421ddecbfc09b58a277c3887d2bac063e240d86cda58b7156f89810dda8ec0066d4448373a1e4f3b463abbdf5b1c968310afe8ffe9134b3b7eade3af75fcf7afe3180c792f18db0b2d6ad8a0857c148c1d85b7900b865ac8b858b5859c12d781c13f3136b0ed2de4b1b690b77a6860470f0d8c18b0972b7fb0b7fd06e44040d910b490efb0aa5edf810a5b95eaa9138e0a1b1ee923271f1b7e238f3d7a808f3640b2eabf48127b4d76e5f42da9fd9aa113f5f589461d6f2c6b0c1fbc79f599c6a62718d54293be2e655e689a5a5862c57936861d6a08da06d980e389638e46d0558d9e1d8d9eab1a3d3b1196bd5a8465cfd1e8d9d1e8b9a6d173f52cd271503ef2e9eb9f334c25046309dd3035f8639b4b94612aff01c3542b68986ac5354cb55cc3d45a334c9d3ec530d5f019a282bfa30d5399887c71dd30b5bf09d393a01a3c6ea868641c659a828630db14a46a846d7bad18dbdea514d2cf334ec52024c1c4e35e79589616634bcfc322f7ba87127966d67275b89e19879987ebce17f9298f27e5be014f8c3ef9a4ac2647682dcded9332331d579a327fcd5effdab2c981faada686f049ef01e27568bfb85e574317e654fc0bcb705d9c133374d59a59e70c965b0c78ce514cd9fca1a43b39e3a6ed6ed6b67c16563c9f31c7cf67240c1af31e030aea5ad7e7f39e4ad035a0788c5d517770264736637894ea1139d94e44f4ac1381b2eef728b97826c58bf0407af4bdfc6bdabe13e89e79f382f2eb841854f54ae4a8507df5bb8a542a3626a5b09bccfce14db6b8eacf29dc0adb952990f14b2ea92538c82df9aa1e16da71d53bb4bd43e11dbe78872deff0c93bac8476a01c35f9659ebdc3ba77b8d67a144468979fdea1d6a1e31d3e29379ac576c5ab6189efc01bbe3318bbd3f5d0fbbf420f8d405599c670dfe878c3637103aa4a64f193768462d88a01b2d08c5136a11ea1183663e07d593ade57b39fc2ea3f831410740b7f970b7c400df22d4c059e3672429e069ad26bab5913718d52ef6fa5d4fff9c22a754abc85adab60caef500964e40a9087ccca912220860663439d38476e02ee1c6a541ff4702a95808b4d1a6deedcb8df39c4fd2e54dcef67c2895d2f453f04e0b633c5396e7a2528ce75253ea3e27c96fb3b8f802ed30d544bed7cf196fcdfba96ff3bd4b1cbda11d865cd0f2400d72390cb5a5a0270db452e3b8209df53c46b4c7c5fbefca51934d68927accb99ae132b6ea6eb57469cdaf5fdf5fc726ad7cf988c65b454ff54748ac12531e0428ac11ef6268dd5e43eae88accf137cc3c480b62705b44313e234c8deeb4a48335c0438c35583a0d330ccde281920aa005a23a2e8808eabd6feb7a4c4595e4a5c5f7c9e3d273225ce8f5b128032f950aeff4d29718d2bb175fedf354a5ad262edc280fc7ddf16529eaf2b4e93cf74caa2a95fb337fe711f4038f7880809df9edb313c2740577702448dc8470104d43d9653f7984bd36339753f76f8058e53f3384e4de338ce8dc6ebda078cd78ec66ff434fd9aee8c1a86e1387e96913fa48e95bf2908b074c14980600090d422065c77dee4aae1ce9b821541f6e3a5edd17d6db0b2932e4692f221ae4cfbdd9044ff3d05c87c29a549c114f2740fe5f5e09f96e29d90530c11cad819fef439b3abfbab78ea60a67a412602e5e47f25943503b04d7431c60b81478ffb410f8fff2b2a518e2f56a26c32d63c8bfd4ebfa7126553b9f2427c8e7a48ec960704a740486c1cab6e58ee48b4dfa11be16cef45e0d446c953ed08677beb7da52863c8537fa21865d1ba240c38ec3e76beca97153554001a97191b6bfad4c8ba9a13f79746f3445851f5dab3e318b567f7bfcd8a1a5542fad3aca8fb7fad15f5f360703bb4e54921ca073bdb03d859ef24e1c88b917e9270dac524d0b327f913bcc8298e8809140bf8610d484487e7caf2037c3d7324bb18840dd507a9bc81b1f4754c08184036a7d3072efe842cd564e66bd2ad72db90bf5f548ba8e82d2e24b94d4aa37cdfe4e83201a24eeb6ce3b3ca27946f778d61ffed4dbfa2261327399968eda1e8a95193fd7e4de4c31a6ba1f5b3077c0de1db6280fcca6db371b9983b945e995a5602c3cec7f2864c4c83a8e155dc7765d30642177fc6b37248955563805ad403d5a0560a32d20f55115991bf999c9a8c4d75016c565616eb001f9cb99091013e988e92bf7c16ebae67b11e864348f63c93754633598fc321247b4cbc2054997ce9df2bded960298ce959bca37931de3180f370e78b7ccc7266ef78519c73d653f99b9c3fc3ef20701bb3efecf506f84e63b341bd64f64dad6e664d315265d25522863941be3cee225d2870f165f9f564420e1d5ce2c88f7089d53b2f21d9295e022c2d2d798984f92bd50d11fdb48c4b3fc2b05ec3d38f2eac8b807e64613d33ca8f2aac07a0f81185cf7de66d3df7d18bbd8cb656e73e1397316f3296d780cd722eb0193468c066969b8a2f185beb715e3b2f01712e189beb56dbb42b764c8172431d44ff8cba938fa9ee0ca1c8cefb432b5bcac876a5e0fe34589236a0e65c0fb06a840b3dd328a1a711110bd28e518ea31123b8aa1655ab36dad0a8eaa8d459b2cad2462f666541521c567db406a133c45211ddcff0ad30053c09a8f290b0836733ded9ac7776e99d5d7b67b7a17da7ded939670d8052681c51321bf3d3f09264347393b34038c9f66194739a565ce9c45165eb8f886279d6583d4e2bfe93e60491641228bbd4d343acd5766eb142f39156e3c4f16490130a3ff3be3e37c264d696786e8597db3f27ddc2732812de845f139552a98703edb171b8bef842817dda347b5acb57944b648c63e94db0e6f98345bd499b9969035fbea8d19d6617810f642e3820b6bdff32f6c80c9425783fc4d7580a596781848b0715d0973098f96bf2334eece08e0a2861669e7e29cbbd54a6cc58a6ac5faa60a94b7563860ea25143e3fdabcfe2fd7a8599b556f73e2ba222f12f8c0837c2eb20299d502bbc7676794bad7197812f4c9087ee78fee1023d4dced350c79c994c25628e31ce62cad9d0dc88d14b322c2d100b398a4ae980efc29f1698b94741a540edfed4c02cb5e7a8dd9f1a7847edf7d4ee4f0dcce449b8a2f690d4c06e1cf7543d8e7b2a7dab452ab0b138e4849e5a9e14847838c9a1606c08f664e581c601fef305f1befe79ce589e7be70fd4df7ffef4cef9d185ee9d9f51ffb3f30eab1e6029374a10715a4b8c80add5167d973b5b50d546a58798b5c3dbf9de53d5c334e56fc52fbd467968e78cc5993a1a7fa8750f81bf0df8325b3eeb07760e6f0b5e5ade4e788f06ff8ca56d750e76c0073357b8434e475488f53eb829a1dd434e4de685e8e99c02cf8fae42636d2dc6b65a525f0c049e4bee070cbbd071855d3f2836ed7417e94778b2e618dd6a1cb6a809e4cbf0ace96d44d6f4529391cf8ad95d350c86c9c8254e2aa7c7622dc21625bed207d7239bc25b2bf28d28e1323ceea8400cae7ebb3f452e3a385201196a5fa133cace13174c1197db52fb86da8bd4aeb8f09ada17d49ef571e1a59a3f4bf3e7cfb9f07c87056a0a3bfbdd09d6abd8a036c42cb729f8ee1d5819542e514e3ec39762a37dceabb3da6222cd55d49a579171c899987115c106e75d0c208008e42aa2edcc5c38e22ab8cd2bd6a8e2e7165cc46bf2dd5ca049d9580a3c7170df2ce88ec4071228736f60d58d11d835856dbd04f5013690225951b3f7c197d43b552967470aa4e5c5cec43b6b44c20e233a853d876a4aac098bba8576c9c9a2e2e9aa53b82f8ca9b701774e58c319d949b7233b700392f1097a0ce49459fcd132c964a63f7f955567663a75d5cc87400e01f746879c181e5f2b999166be00226dce0d4c0d448ba53f6ee6ab29339f060e1165e58b51e7b6775633da0c242dff3588b45d1d91b62975bf9729bc993750b499142a0403e558fd2dc2df8c3a63f6b96792ac4b0a7a17b62cd83a095c767c8495da1a016588055728b34354b5b406829b1dfa4728dc59e4bf5a8302a0edfb478421d14a5e70d6290c92b6e8ef14864d9bd73ab59879e01f41c858c49676af1a05ebc9a2cd58d1d68c822a681cd3c83c625d942b144d2eb781a9578157fe9ef14516bc719237ca1313beccba8c549e38f09da26d146f34da9eb8b48d326948ad974e3012f43ebcead32d31e67b8d9413e1a4bcd7e2be35337d371c96e07ac5ea6e78d5a76954d4775b8bfa6e6b51df2d2deabba5457dd723ea55b7b5a8ef7644bdeaa65eafba156eabbeb02c3f1327c0ef2ada5c4f340a14133b7daa8b3c1c3fa81d6a9a9e5e03bc38b734f4c26362fa2170abd7fd3f018e9fbd7d9328c600096f85435f8ea3002f1a1131384e8447de8980a5ab47c434eb99bf9d98898a516ed615dfe2afeeced35449f9f567362275802b7640c304738749c25173794659086e9c08bd57157cb96b1abfb9b1c592aa3ffc62284869ddcc1737d2d73a5c35a5947e4ba16b7f8dc04274e5d5bdc9d85e57794f5ac49d602ca38b8223f3d6c481cf2ea5d3f9d4cc814e8ccc011d5fb6a711593722d0ad1b812ad38aa8a51315e8a6e1cbf68df7c6e6d734bc8423f702ecc50835746c125213242405cb2b286a3e4b05cb7afb84e87affef9eef7707916c17e60d85422f979339779e48d63ec05f61b893a61be93ec644cd820fe5af7678834bbbc55900eab10356cc40306dc41085453f883f44ed0425117b88aaa49e8a3f4425d1dc7015edc6dc306ee8637f8f517d25f1c858e2d1e35b2527d2531ec9b73e0fbbf793dc27737e81910560ed7f2b2a512f54168a288e78dded122e9afc07a0e5c3fcec1fcf96a8fbb31d1c765fbed153ff1fcf928484d7067ac27b83d1996f600391cbf523ec48338c8c4cf75c59126387b79d2415a866f54df5ec0bb1eaa88ebd41577400fa872eec3af1c13deb78d8b3b6e733514d291e18058ab336a136aa41d6864270946a2af1c0a82682e66a20bdee28d5940a8eba7087179eebc2b5fa9cd9b4da87f58897d9a3fa2762167c9bea454f8257bdf00d2e8c7adf13aacf33085eebc2970346addd86364a35cd6ebc9695d3d307ca18772735c114c42e1fe2542cdb9719db87d503ef9719eb97b53a64d17be63f5c36b3e76d91e3abb27e0057ec62d9cc4ea8acdff2ac417a4458d8ae5597b3855886f2109f231e36e46c591fd123b4425ba8b5440fd5c38ada97d43e410f923586ffc5c382dae7d43ea3f629b52b67ce94da47d43ea4f609b58fd5fc059abf80ed236a1fc2ffe6b7c5cafeac1c987f2ea738f18918719139c5cd604e716c30397f3ef207eb87fbb51c7f59cd60ce31853b5e2bb3b9a87ca2d5e01dd8e1ff824219c50fd4aa0f2994d1fd1bf008fd8532da37e011ae237284c611a100fb5bc4fe3e8fb29634ff139532ae23467f11d117117d11d187e1aac385da4b54847e53ddbb59fe8b333503889b21652c6e4b5ad0625e1bdafae9dde8166a44e42c34230061eb312aa2353f84833e88eddffc9f40648805498701e51efd9c94523835189b86d04f33e8c63db8d10119c06ed5c867e046fe6093473e66e9e3d1017aa0cf5d7874c0588b0e586b71007d1e9ec697bf1a1f20472a35109454152130f62204740ac248001521d08a810bd7d022041a5a84404d8b10a86911024d2d42a0c5cc6f7f3358d435f4b751f913f3e922c1508b0663c538e9ac2dcaf8d756fbe6bd410b9fe425d0aa2065ae793bcfcb76cc23d6bf1e1f7317b6feafa64c5cf27876223c9ecd08b8d4460c8f672722aca01191cb19b3cceb5fbe7ffc8dc8839161405b93b1ade688bbbf104070212ee84e3076a71b15076e0041963396d5496c60c423b18f5919b70f7f2f775566b3e327d6fcfc47cc669f0cc557bbd16c06507cf5ab0558dae1f90fed5b02446ae1ecb21d216db762c0a24471cb4604b78c52d6e2945f48dd9ab895478092354fe60dc6f2462a6b6b8141fd1ca5ef907e36c8b9ade6a80c71f35d2df3406d4f6cccb554044219663dad93f7a7c1c4c13670a6a5649aebab6862c9bb3263774129182d1823c8b7b2a01800e22f54e519130b0264a1e469758219bf98d4c7b6fc800766e6516e4a274ea43ae73bbda1b281068bd5df66391b0465b05bfc34e8a901db6cc2b560de6c59f24ea136b9699999073ecbc2e02e0cfe35cfda1489b240df00c6fa623e0d26ae98339e554625f84cba51e90f0b38b7d525d3057c5d908980e9088dff8dc282ed68043b8f23df7422e49b46847edc8a802eeb5c88e8ba06072f7420a33526c2c071463bee73ca7c814443aaec6a96cc4f477dffebd8c173801d044db35fece08b1d7cb1834f65071fd1d6a34db99fa79cbfcf947b4b45e2f30a055b6d114e355dfc4c4717efd4c57b11f0339d08536e947079ebdafc3c55fc6f37e5fe6e55dc0ca8e2b46b99deaeb596fbac861eb552e851d8e0d14fbaace8e7683076d4e927edd10fa2151c7464291741049a740411e3b784ee87d7c6d45d69dae9e97b51ffdb1118b5cd08f0a65b112bdb3154b3cfc5a8fd644343d533346c3f6068a8c73534f88d057fd0d0e0040c09310c0db518f13983d8f8fdc4f0b298e63de5c9a9c5d8d42a79a2b3c83d24f0834d3955394c69ad1304d1a4ccdb5a6e5ec1d75c5375dc089bc752af927e3b00ea07bf15caa9bc577382901feb42240c15e6e5833a8011cd01f8a9facad2a244dda40182793a2ef15647842e85b9134d00e1394fc5384f9568a8eb6a53d2148129d58051f89458b9a8232f7a8a3ba5ff2edd01fb56f88096bc421b0052e20d2021c02e8918f19f7299673168b0cf17130d96a03a072dc41c4262c1eb027ed90c3e731ec31887fc04492e3da998c0bb928d8821c486fc10681413605f8d94d014a25fe1b39903113ed30b3658acfdb6cadb57c3632ea82e01cfe4e8cf3af61bb27748da724c0482a59cd37f721a76721876720c273dec511d73e05d65dcb361e007a13009471fec692646c1f77a7826ab26e67e76aa48e4e6ad05c1f8d343f4221a21a921b7bba33eb3a48bdfcf9f8e112753666c58d6e364ac3f6b09d8df02657486f1116109e8872cf42d42b4e8cb9d15f15caea9ce615ac61e20368e9c99df62afdfbab67e5b112684768409218e0fa019018d7ea9047318a2404ca4a2d86adaf578c8ffda0a9d6a708677ffd2151a05dafc972cd13ab8ec33a3b8797020f662f5870bd87436abdb893e47fdde6636685d0f76ba93540878802550f3ca21d77470bc2a1327e3ae83c3ebcc7ca18170eac703a08aa29dade9a2d836dc23c73daa851e394b9eeacb3bb54a3c068429c2966a41c60ac10eeb93ebe031918501036830b3df00db112e565d85ed3813abfae134a5495bdbabe6df56b8f9572f6be187a4d37db87e383a3de8d60f458795c29148fc30743aa1f821e8604e2216053fb7b9b3aff875e372eeda0d74f338e653807915bfd619f97fbb22bf7e5bfef976c23c282d5b9e542eeb9e2ba0ca2a1bf172712165a721cff3122cf001bf1788366953210b490bb93e693254301e04cb9191742196fb3cb9469eb1e690668e189c1e7474df3bdc9e9d758a1c9f6ac077dcc35b16039e415452d07d35584c27e9c262e273232ca6b3c978ddcf8032dd2a2111bf158f71f4e9bcc163be024dd95ea00e1ff091797f5ac885820dba87ac3a78585e77929fc1215fc028c6e2392e46b1c34c17554430f3fb8ea6400ea44d5132dd29b04d9f6253d6a1928fa7f08e10ca578abe80824a1e1b3a563272aa104cab5026f6709b6bcd9a711501eb30cbf5e4c1af099f7b9ebcfd83eceb7af2f265b9d3950a6172c85596398ca86d588ce9343335066a7856c8b1415648b7268a3dc2009a016a84fd97648d75173ad621b5a048624a21cb64928f0f38a09bd73d91254cafcc5f8546bab56382b3e68eebb5a7fbbffda932716f3676c73c3cd56519af75bd58817f2bdb8f105df5b00b4757d5b1a16edaceea17b63327b89dcd76b60b3f17897f512353f859adbc91b80d0923349cccffdb0956729d721d8d2d80fcb07b27f24335ba4ea613a74e6635b44ee655b4eeea8dc6e803ee1eb43dd7ddba8e35b7eaa3e3fe69b80d4df7671d8f4c96a8e36b16f89acfa6a8b97f1c3c67558f8b77178aeccb0f2e5e474fb8090ce1e7804f9ea0eb187efeda35ffa18a8fcd4bcbb84e25a8ccd57b0a3d3accac246bcc7cbd1cdba8e5c31f79287afe4de54fea311c687a265123223422aa687654247894d27883034dd5551c8898551bbd01970b3156d9263692730c13deb4c2d8b4a2895c55857904766f0df3c89595100d49b7887ba96e53c1d854f7ef9e8c5bab32df8468d4d7ec21dbf7da4334dd6d7f55778b2849a86d786843be86cdd68dc874eb6aebb3abadcf4ec4faecf812257f4378841d635d61f9120d0d5ad908302edf5b5739d7f086a2f5492fa4eb55fb168cf5f575b5b9040312cff0165efe3b9ce5ae3596bbbe0a01a881fd75422100d7ef2d02d58be082ed8855e6440488d5223c11356d9535224a7937e3d580d204860633175e1d6db9059c17d23ec71b6b10de182bca454cd863a9b35d2b5e8e751f8e9b2a2ec39ce1b26daaef95368ca3f11e81242ccbde0cb32aa7cd385e71e510379979cfafb9bde3575f3a777f2b21ae9e072b041bf2290537c1d2935ad9c1e721b667a6d6537c9f3d5d74499b3b41459e926d661dfc12265a78d042d356456d549d9dc23b2f4d2bc2dcb8976efd5597ae134aabfbb2290cd28d08b8f5aa2a8c72e65eb51ee3aa0aa168f1912fdcd6bf70ec67adbfff596b8a77b8576d3067c7f3eb5be473b4a9f44d62bc06636bddecbcf3ccceb7596c426497f0820251b19d31e28e23ccce31ddf9e3083d3fb4f9d2c9f92d3d35977f5804c2658ffff6f22d87564378cf98e3bbe303fe037092b70b86b1619ede554ffab6fdabe6dbbf5a4486e3b30dac29fb7eb381b3181056f40af30b1f546e53d93b5ec15b202c281aa44d0ebd5a92e0ef4754f65abe9b886e2654d3b226fe0d481586c445d661222d7c770a3c2fe24e5514d9ece29d2a1e9fbe7ca7d4cddc89332ecc5a0abbce3af883d5dcbb57af6c77cbdd3b882a48c0eb5177aff68adde5bba76ee62270f76430b05621771f7c016d3d80ae2e3b3e452c96e0e56b4ce4f059f056231ea619769774ffd6e6da5db6a80ed222de920e7ec8a682d08cbccb5b164c236cc13451b4b0d2b11ea6f3be8751bcb870f96194d274b8fc30943d6baea2be8cb332ee52e29a761b0910148d0111f0805f124502c58eee3f1e6772d5bf13219b84461aea5041706cbefa4b56bca3dad1fa96fdfd82e3627956ed68c8f57247970b6a78fe9ce08de4c34e166fbfbb6c8c321b0daf5e52d3ab9734855260e2258765c61bd93d78395eeec758f681ca9ebf50d9f34686da0f50ba9c35a8f4f90b953e6fdc51fb89daa9fcf90b953f6f1ca97d47ed5402fd854aa037f66afe1ccd9fa3fed4be85ffcd9f83c3fbebd68d62bb0d6258a51094d6a3db54f96a3858a024592156a04a8c5ae8a98dad324c232b976760ff5ce093394b7417d69236330f7c30e3312c2235cf2282f8bff221cd145f54fe7998b1ae6712d3abdaf4426d62d741eaeae16133511863518969514993ad8870b2a8aa187ed483f75b5e0fb726a6c5abcdd8a44d1ad8de7d486dc6fe1faccde8bbd0576dc6e4df559bd127af5c4468fb77d566bc3d3122d486b0fcdda519b110635f2bcd78f7c9a5191bffded28cf53f599a71762b9ecd17fffee2dfc4bf5346807f37498c3a88cfe4df017d73f33fc3bf43f5cadfcebf914327f817fffef7f2ef3811350f8c4d1fb4881afbaa8e89580aba29e8bde0d19f1ff9b0d4d4bc6cb89a378d8023d7d1a47594e9e22dd10f431d8e7c19953ad488481d8a8327dd8d8023ef46e87a3daf02e25412f6e1e5d6c0040852d4c1deebbedf5077b0c5acb77ee55d2808ed20e87d332eb841cf05bdbf03910141ef77b011bee06cb5a4c9cc0a0daab3ca6bd262b5572f6eb5a91360350601e6fe307afbdc606caeef8dabdf0bf913815822f78ae7bbbd1dcc53da4b4adc1dec80cbb87dbe4f9ade59c38b7b33f170780b2c6f2f2251e98c0c5b3132f8daff042c6f74189214f352060a8c14be63b1eac8c3afaa0c41eedb71e6c96cf24f07f006e0ab3ca5209a1f4e3fc96ee0b2c0c2860b9e7dbebcb84f9f59217b5d666cad2deed5f5c58d3e096d71a76295d7faede06b1146c45e78a982623876ea58bcb3b86e27c28ad88db02276229252db11950aba11f19bdd1b0b5da4c4df0d62f5f7d523b800bd880d9afa64b9445366aca86781a7bc2c70ac62a00739bbf0d16bced8fa5c5dfaf08e104302bba5fcf4f116e9ab19854ed88b201129f3b93402f0ed8a487a11a6f64e048a553722c8b9a7f3fd4e9cf0d31a33173cfb1a2b6efff7035fd91ef0d5de2f4ede5ed6da0c038cf22357b7aefcaeab5424f35dd267f346b06f8b310ceefd89658649eab4ce44d5f23706f84134de66d6865fc3bf5a7d26d849a4583935199b6a59efbb6850fa776ec5712b5dbe37a23d1fce55dad7b84a27a0ebc5f3deb5a364c94e8c90f6460c5cc9760c34087de31df2881a41683f38127d0ec56f281c19024c17bb60d9f5c2911f2a97ef4f596cbfb7706421b6bef7e6a34b652a1f5dc7558e96882f814f5c40a83cc2f2d8e901c2bf03d3abcfc3c380fb1108af89ab6a5d8ce4925b115e9b11227014c2ab4e89eda814a66d34faf007d4baaaaed651ec200a94a0db85fe063788757f55d7dbddeac9cf1428fe4c7e9e25dc8f2579cec3423bae7a87b67728bcc317efb0e51d3e798795d00e64897798a8cc0def583b9dd34ed7bdc3b5d6a52042bbfc0c9dafe31d3ea1085f6316db15af8af04793b1a386437bb81eb9730987f6ef2bc9a71b51e1d8d48e0d4db9a54c86f95545b7155d926f6f06f7d8a81099668cc2208d88b4317ff22c994d971fa8e7f91180d77adc7dd45f85e6830598af01bcfadbeb0ae0d533a98ec3a0002c66bdb90c8f35fb290cc31ba4c062d8c2dfe5021f50835c285381a78d9c90a7811db94831c93ab326e25a26ffe133dd259160525851d323ec557428edd0606ca853fa44a374c15851dfcf17e685fdfc93426935d2df6ba43fd76ada6aa01381a8bf219717c5c4c7d77764eb83fba01b5e8948e7337a894fbd16d15e3b9fbfc55cd08e214d342210afdb11ae9afa75d0cc3369a2761696b7338e7cfafa396082ef9034dfb907ed81e8b59599bb650f6a87c6742faf297ce7b504fac1fa7d7eef7bf6aaa04993609db3c8bac2bad6d78b616ed577a44e44d06694b9b51315b4d9bc5ae8c27cbdc6186faef5d7efc3edf688834df22ee4d41da7dce1fd32341578033261fd08145fc268964cea2169b221ff2607aef9665421bb14841c21fa4e539ead32563541957a7085e33a8a3a08cec39c5d44b71a7a45e61b104f9dc5c615bec5db11c7ca5b6aca4deec586a793fb8b1467e47e0b1d3a70dc428c669062e5ee43ef710a2cf185e17b7177261c081f5a8ae2e6c95864caded065a67c75f008fa982b588f2fcb0cbd7a95309ae26f427eba4e1adf1b6ee4f5f1f7300cf1f91676d48ee4362a0fb67a0693f37b9bea6cc9377c84cbe992b63c76181b3b5a24d19332853f3076f7a099c2ed482b16061d694c2da74162439b0e895d564c0d9b76baf1eb374362773ddee5781c2d70368aa1cdca405947be7b84f44524ac3b1410d3f2bffa6bb2c69ed91d089753b8c77b9ec60e23479984c58e67281372f40bdf86c514207e8d893a8edb1afe71837f601c203e0d7f2921376b3e4c6a52c633e159b7fc00cf3afb2f3eebd07c38c0e226692202f65bafd1e14fe7d535a54b70dffe34de8b90dfcdcf85fc2e858aeb66705732c36c126465a87b0687c0a15b62fbecd0ad2e7d76e8c6069e1d86cf6b2b6e109cecd285fd870d6689c2750b03c21a799c3177ddc270a9c6ecdf6761184784696534c9bf758b9fb015ee273c93ed3e62478c82cbd7ad0df50bb56e0ecec780f3aafa9106a1a74a0d582464bcb22421fcb92ec73a3331afdc1e102e80a9e4244b33526a3afb086ec4e9830c553e783abb3c3b30a5e4b2e7d86aecc254f706b3d35755f7592876981de40545e35db9fc9b1925df02661f8404404838c91152073841fabe03e733243db6e4daa757d786ec786f28641977418e75c7b9b842ac47874d88e9f68deafd9e510ae86974d328e5571b0447d5a84623c29fa4d16b9cc1e9f31cd3f1277c8689ceb53471038bb1adb813be7307f3de0c607a07e5c277c4155d4a60fe1ddc2faa72c39d6665e95c8144c4da434ee621d963668e6fcab786722a8c2907239d3d8c29073fa4351183ef0156dc0dc50aeb7a7cb8774bb4ac064957f3f830250b572859b84ac9c28f942c6c53b270859285ab942cfc48c9c236250b572859b84ac9c28f942c6c53b270859285ab942cfc48c9c236250b572859b8ba57f3e7687e4c16ae50b2709592855f3e922c5c88ad805ff72b22e27420e7a24b0d1a455871fc8ad8a6bbf75d3b2436edf4cc8ccb1481268dd8f2c07574214d05ea869a7abab7587a746f434d93059a9a2c508f28495ed36481ae260b38113e450df317640a250b68f0f552b2bd1256e7b052ecb0ba57dfca6951b05b5a5c8d14c1060dfbf0b7af9ccfa987dbbbb67274e3e1d5a533fc9f593ad74ccc756d1b16697959b342895ed820978e4861c39102ba3513b34819d0a4f2ba028866397121af0b578e2f8dabaed2b8349e7396c675c7bd3caea1f0f2b8f68299df69175e1aeff4f7598e978e40390c0c0f879c32134c37c3014e61385916d621662ea4b872e159cc7c66116e3f9b596971ddb52765dc13b85adaf2f8199c8f1d500a10b4ca5ea1582c9fc394ef091f86d48abaf71b948b9eefb713682747e0ee21e9cf889b6ac6fa310f58e5fd1c3c1f66ac97ab569e85b5d762e21b7d3cc924900c2d39c78302b66dbbc0b6963c7e50a9a7528353a9a6f2bcca2f95e75374be29fb5b4a25179592763e51f6ce0f2ade792443a9d959df5c4b7dfe9f4145afc7813e6f84429fc78c2dfd3026b45412cc32dd9aa958b65c2bf7d6f18f575e5130a01bc02cf9860aa2302f976659a8d22c73b734cbecdda5596e2adaa2556ad97b8763ce1aaa52cbec2fadd472275615f88868fd5cf2fb2120e5a5091da6c5c483b79a60ba3de840233e9b1b985afa5daeb0213f73fddb2b237b17ab628b3c6a268f65c68e67fe50b9aabbc9a1c5d8d062495566e5a45cfab855d534281dd8c446021e27cf47b0782df9290862cddec2293445e2ec77066377e70539f506a69f6fc82589083eeeed589332debecdd8d301f6f2dab08e2f524e644e1eb12b70218b312b5185b76945f5b1993928431277c384991eeb10b2bbe52bd057a84ee94ec8fd4024d782b1bd1857b4a6b480186c29b68c39cc6a16ebc91afb36e23fe9aa6db6e503f16958a5316442bddecbfe3c2b2d44281cded974a75db9530eee6c38dd774fb7e5e9d2094f174fb6fb364589a74e98a49e386993a478814e5f850fbd96a82d3fdf38a3e69e73c6e67cb0f23c9ce264c498a1b8acd00c1890edcd5067d6c41cbf5e927223ca8d8e3f5228a5f10fd4fd0a144ab1420ba5046256feb94229feec85904229c3cf1209c2728d6e2c9e726b5d9492fdf1ba28f5eb7551ea57eaa278036ba1a3bfeaa2dc5a17454b5cd4cc7943cddbb2e6ef4ccb6ac4288cd28c288cd28e514db31e1167d5b8e06df98f15467947c0f1d6606c1b8690f557ba03b7fe80e31077a0be40a757038e751be05c8ff66afc250ec16bb9b5f12d393f7cebc70fd973c19d8c5803356d91a8f59330184be8eb67508e931df647d252e2ad9fad76fe7ac0fa585b3fcbfff6fa89c1809616634b2d307af17015633810a97529fcf436152212bcb4716573ad9f0984870f9471814b549939522e360233b50662f1f6d142523aec465fae723d4562b8b6936ea46a48d5e063141a876ea3d353b48e9a8d6e1a3c7f7bea562bc256de8a08b6be1503352a75cb4f219f1a4e3b8b9d2578dd2793b718cb6bd4947b0f358148a05353390e6277963396d5a96960c407d2101fe4d27ad0cf3a1c835767d2dbf782034ca3c001741edd8b1043e340c2444103347dde9a7f71f2607c18e018db4764b242b0487b1cf9752d185bebeb3be7aeef0c585df5b8de8f67a7c7c0bce8f350fd4ac785e9bd338da5158e7a41fe8c10d48b4e8cc27eb7c24b8767c51e393cb8979fdefcccca7e319260f660bdd49cdb8632ee0ac68e4233ee1a2e960ae83e3aea818823857c5ac1c8b6b7aec67a1d3fae6df32d7d9b8f18b0950b71b027c167fe8124c69aeba91cc3eafb49a6a99a725a5acaa919d213760ccfa769c5f1695e326adce8d3acfa7c9a559fcff2fa6f04ce229fe6194d373c926e78b4dbf6283a70d625e85a982db019b4051edee91eb4a3ed7e761ccfa11d6a1cdc06f990e3f12147e343556d7fad69fb6b4d6343f58868887a4434442da2f2633da2f263fd4c0732c373a06227877ef19af7f09a9b81474279cd193799091fb7b99e207d8d2ddd803af2c57ebed84f3cf6d364f7e5cfcbe6fd622e5fcce5773217ad4c7e33b43e74e0ec1773f9d3cca5cf4505abdbd9c7ad85cb88ea0c88051f6e60ed74a8b75ca260aee9ba273678a2e59e985d3bd1d8617c16a64597fa0f684d854ca225e6763c813d759ca025269b30b5fb7092cf284e62b384975c9da15df6884bfc247fd933be5d638af761554936196bee7760eca8670af209c58157f5e63192c97c05b108396e9f8dcd3e037739166c2429ebac75be44e6331e3c60b379d69cc094a73d7c0e73c337588da186f4b05e549256b22b9a23bed31a2acf10d593c54ce7631b8cc668b939018d37e11c6b9ef03f60488da3fa61cb6f3a12f451b78707ed0bdaf20b8e76b6f6416c36153bfec3bdfa77b8fa9c67cb5e6a7d7504f7d21896dde2de92cdd82f708902be92fc1ea71d2c6dca1d76588eb7934bceb2fcb12017ed3db7e50e93e15d79cf05fe2379c7599ee7b9fc99e6050081b9e37d433ec5503e45ca000836b84e3607f6a8223009f63d97856ca13567f4e090153444a6c2e005df0de57a3217e5415f68ef3d9335e45b12a23c928f67d9d9bd7cbe87766a80516769f9f52c3b2be75af2027f7507ff80b733e6c50a19da2c152dc8fe9fba3fdb4e1ed7c246e10b8231e81b8fff48928d310e21841042cef2920430c6f460b8fa7f683e53b621a4aa567d6bedfded3aa8bcd8b2daa9d937b8178ad56fcaa15d3a23c6ede3c88e344d8a35be90ff60afa4918d7a495af78b0f098df8362d7ce1bcc1d44097752fb1e980d69fd76c9c3c58dfdcbb69eb282b19306bd8b4968d5cd06de82da9e648af7c422a04f45624c0195d50c9247068ec22d5f70824e976e7f2a5a61ba9f73ab51d57b0e4ee5ed34e15ca052ee3f8b2c5f3cb54c3b2b3a7bdf3e63bc24e1f749dbf08837d209b2fe5133dda06d85cac3b6c12100c2f4bd0f0930b8f119ba983eef31c503fa39b36e57eea29d3db1d91a2614fe4c58432d6517a819c3cb6ddf4df0b4a8660c9835e71537e1768a92b24a53811e11f95689ddd82be771db1028a01f262b4b61ce22a476f997728fcdd8b86795fb8cfd32f3aaef28cd81ba2ae254c8d2ed9c8e2cd9d7ea1abdc0c97aec69b4b0b70b6d887dc929012e58df0e6e46637829b4a05c73aa56743eca885ae7a8d8e9990fe33a38d5ddbb90803e5e8cb212d6858e04f665f59088a34ebe2946cf85f92554cfc59eda9db93e425b99cd14ab5f203e1b4b6072fdd6dcd5fc05d7a418fb1029f989ce17a4b2dc91437a862d9438773cfea66445907d87e22bcdf6d526c13873946277e6611c19f0cbc17224f5fc7026e6f1d856cfcda0ab777baeee4bbc20968118ffbab398f85432eaaf6f2e0f1789e506fff603cda5f723a2d0f331df684dfc9f7444b5486402d3d219ca90dbc33b3d3674bbddfea255640fd050737e580041e944a0a18a124b734f697c1fcee51eee8c964b627d55c6fa0111f13f9b9dcf1d5ddef3af92fe136e41c9175078942f6e32d15ac58c948ede8c1842edc54a21e2e51ac1d5142dcaf9d3aa3c70558807801b4e252d3e51ab8325ad3060e1b8488be40e8ab6da0c6b1507b7bd56447c719fb989ab723e1ee1578284363379ac6cea58a340d5dc80cdd53dfd718d3658c5955f186e8f698707a7f37f5c8f37b4ffed96ecd39c34bf2831cb0a70ae4e8b2e91872e499a8cbde813f3dd2a7dd63ab4c9fb6a792be9dc080a23fd5ad4ef4d2adc94a4c4bf0eb714bcb57831a5d9e9d3caafabe436edb7309ab8ee0a54e841835f67ad64bf97da6e64e40ebc8903dbdaafc52a9b562bac70462a98ff0bb91690c26602e9907216ca4c50954f6a2c39b1c2b1ab2dc50ff6a0960822511b6573dabefb1de97af93147a6b438a3c7ed6dfba420de907d1ed953cef417066539ce5ac45164405b62615a0b8be67fa7be601e0b73200af33078e59a6105ff93ba2e832d95ce24070e20327ff21963246b0f2978d06ad04d388956c13d170acab0d9e6f35ac4da52ac9007b55829f6b967f2e079d2bee2b278f32dade727f1be6bf22a256a831fe423b3297bb10b5b7f6f8db9d01c6cae8b722c12834e40cd41abc5b32de24cbec61b02a0f56ca86ed13180f53c6cfcf4f54ffea723190687e4703eb9228b95a23969bee77a1d14ee4dd094386275c1750bb86cbfe407f3810ea697ba05bf76773a09b5496d18e20a257c1bc72b1ccf7f5d2be6738ef69b37d9707ea9bb5eee45aee337bfbce60bd3a024436750d8e5daafcd20693799c255da8e73d45feb73bf52dfc42cb33a2c2830afe76b775ba479d98c45287d41faf2770210b19d2ecfae84415a47e91ded93926dfada12f5f0fdc134e231570754bfdff3df159627882f03bd89f25007f2d0be040cea0e009620b656ed3b9da0935c3d67c257b75947ce193ed9bcb6386d37d624e9751c0692d53eec96b1c7803096eda14a5d62a323c96f0973fa1902ea162fc1894f1f283071f2c5af96ebeaecfd43942b69e9f2937e0d7fec889164c145745555b79531cf8a546f3eae7ce5a2cef3fe7479a8966d95d7839ce1c10d508f10c1100560582f8286c28cca7bb29135300f71c529c3068826fd4fda9a0752a82f78a8b2478f7b7dce7a6a6bf76810e07e7a2e632d5533a87cb85beeb6febd9398082f6b62ecde050a119f453b8c50cfa361f843eba56c4691596b10244708fbb3acd8039c4c23a417c1f5a467b133b0b17640bff8e3ee9530e45c2e6153a0f0a0b7f89d1ae93579a29d37d6d07b4f775888ac3cbbea3497a17b92f46539fd18586f71c653f6b6d0658ec20df13de03fd725f0cf32ebc3386a8cb5a95a4fa41b1aad9b219e2b0bca9da53b455a726cfa8d8d64c16e3ec9546ce4e55c6f4aa55a4369e701e10a225bcc35111cb713c72b235258453dd4b528ad648d468ca636b9de50c04789cfc4083df5ecd949d7989b10932ed0a5c11fac522179884430bf250f44f953695c29eca529da8021298794b384fd4800e55aacfaab20a378513f680490edf7332f0d24643bd20085fd47a10030238aa30e9eb007d0848e0c4520953a7bbfb4ab8a925e60eed491f2c620f2941f8db1ef2618d1158a2df38d153197058a53427e22d58d006af6ce280d652f052074925ccd20a7d6afe64c2047d605416bd94da9cb9c7f38a7a3ccbcb0a59ab361509ed730d7eecfab927445f37d45f5b478eca9b52d6d48da6374ed82f2eb93ca5a9581900fd0da322f57b908ba29e991728bafb93353d6fd906e6bcaddca0a9e19f3de158b8e95bd3477c6edfac03eac27f028ede9112710cca3b6a32952104ab25e58ffe227797e843e3be95c4333001e4a4e3e1f0f31b259c19ae1361f1b2ac0cc012cc81560830a673c62ec9e7d501c142be6e0b3185a8532b2a3e087d966035368a4e05c9069b92fb799ad15f2fec01e290d21b1cfd59361eb8a6c8c05cb1eef981543217526e748b50ed96f0ab8c7715fcaa3e680e7ee62ca0f39dcab8d24e2ed9c444580e671625065e93cd6230b59c04f17a4115b83c24fcefbc9d5fd151ed82b8df5d8d20642fd32b53e29482d7a4e21a4dff13425171c213d0f4e2a4ee118a0b81ec17c4b2016628fa3b3eb94b9167d804871a37715551b2f5d04c6a0e09b56fe26115f875464e86737928518fdd4d246195a1bd220eccea4003c2c21e706bb7664944f4e0b28d4e553aca715cd53bab8eb21a80b1a8123e1cd786f9be1891f0feecd5f06eb006584ec942a50279e7795f887e41d34e772b732424b780510b9a64ba0f0093c30359700842037904449c1ec8a9cac72902b8be3533e0e0a3799b2a5b3c02ace7b48eaf10fa16b3bead2c3fe06e4177f41135f59cd4518660bd3673d42ade522a3a15ca05af7bf98df6dff9be9695671685fcb4a6162e94feadd716ea353933f3593f5822d62ea74fd07d3d1f148e784f471da905e539ca519069e0121e58ca193405043913fdbf2270e2375dc52a412552ba1c3288e0198860e108b172484282b832d0e0a411234064556016fa352376968aca78f50ba79893206efa47ad0c052523a7e12ca0976326904326905d923b27a4b9cb21d2761c712ea71595ac1373a9b9fccc83af26102a2f14936d2c80c59b44687a85cf969ec67011228129ee7b535da4beeb1a824bb536cda2594913b5b12dac0869725dd09befbc2c73a097510ed789cc329fe5150eb800d567cecff78517c863a4198df6f884dbd6bbb4c81e7e068208cffada29b538e3ed22a220ce3f21b8a29ebeb143e18472a3a76b0f9755b40bce1a4cd4fb9cbf8baac4d6bdcf43808b45e1b0bd26e5c4f8d673d0133ed7790e7585a48fab88116d05edcb5df6939bed706d37057cb12de879a848cef16252c30755f24adc9af6fd15b7d75ba5479e1e3b687ea46bd19b3eead56f658d307c03e932170adcb03f4d298c1770f6dc6b5e0428d7c7818ca081f72d8a8eedbfe74dc4f842767e6352e843bf44ae7f13debc0b0cc5e8d42bb5d10fa9da7583ba1375eb0d5b83cf5996be41f7d252e3e4356df2b768e66f84887e38b16692e919f768ba126443ee431471a2ee19ca26de45844b33dd7c3a2e0c35d4f7e804b3fd300e6de60e34ed712054f7ebd085f50bd536edc93954b03e20023820d5abc98d36bf69bcdc11633469ee5ce0c6fdb295a4782ad901ddca8543b36a9094f8740c39989ea843790f2456d9d3db15985c97a73c8aa9b1aab434947699b3514f1a3a219f6af918a2cf1082628ea89c51574341399ad21f7f46c461262f4028fd331823ff428639e7cf826eab9854e7b41a20a8b1052b66ef8c621ce30bfd750ab0099467d73b520c153942c43013f5a632054a48deb4370dfb2213b4070dcf088c4df799f02abfdee07c470f7c9e5d62ab38889ac0f3d4d617b3d20aeb6ddaa1157fb15edbe9c8339ecc8e20e00b774f6ded3a6804e543508f08eb8d70ef56ae46fcdd4036292176a5b5547925aaad926296b4375bbb94dabb5c043a0ce72d70c14aa858369fa9b7f202e6dc598d21a6d606dda01c605a04d6e357218727ad82b5844675a78054f73b4471f076ffd63054b967ba4dbbc0fdb5dd87506b25287b030ab42e4bd78d2bfa689525831004a87a3328de57e4b2883a1ba755ebcefb481d61631e1adb93797f5e83625b2185e5ef550e777eb7ba3769d590ddbb6baf53866dd590a53aaac7d4a3eb06e52d53490d639bfdf5246312aafa27d4f7cece5ddffe5d4453abb5ce036cc1dcbd377645ce2c5cc5e5e6eee46ab236233972943b747e8eaf0a52f3254083b99b31d062abf6945fb8d73cdc3f857a0d08b239bf778a819ad7710ac5f9cfdda570d72254bf9378de4a1c292ab286002a98417239659408c03e7da39cd3f490b1f85038919ce1da914668c01c8a37afb5811ea39054e9e3f2c9ce7bf9892a7542fb02e98284f3a2a4a282ce193a02a8c6bd35e9cb3cbab3ef654b665e31b3e7116bff0e4902c28757e6bf2af3ffc29eb3a41e1c380aa81f4d88b97c879aae448c8efade5fd248f8a702973b72846abfe53979c7523ee55df128ce942ff54984351ac88765ccdf7c698e4a9c89b57d7c05ed6e80e1f523fdb23b6c4e5b79573cac650d93f44324365dd1ea7da0f0b56e3b7ac9fbe2e96d37837d22e0b176903cfc1df6c4dff2dfcb4613831e99ef9e560787593e97497f9ff3d43842cdd8ceeb8bb97ca1f5b468350f99194494f1a6272a96a4b5cc7916471e6d49efbb43cb2c67c90dd049c8cdf0ff1535e6f51017e8b3ad8ff7a6c97f1b99dfc95afed14aba2fe0e57d617f421318f17ed501203ea6a7d864cb9f4da5e6d9ff0c7a79e7ca818cb4835ef24f156848e9be0052447789bfbe935924804e6d65058be815280790bf9971d21dd3e393160c7b55e2019e6ac4845755917a74b6b61962c14334184c2cec5bb36a46810748af84cc41d3f9cd28af7a94214679a55186c928969ac56ccf09d8d45f87556f9e2a021bb282642b74657ba4a12eca55236bfc871fc696f8318783f1a040e7872ea9fbfbcebc4ed3164d2dd6bc3874ef5632e3d3c4697feffc20ad96b12591cca2c23b6fa612c65ab630e53d716a6f25cc3b97622b93757e0bb69168f32368e2cd35771e90304a8cf50c81254813f947c12a040c441613672bcf1763fcd598745df6e076b2038bdf7be41969f204e57674ec68a164af5624a47a9884577ad27f9c7249636ef57a2ce0f116ec778160d4a996daf98170dfcb5393076b24d427ade82b3a436d4984627e467c1a946ee93b4da556f4c39da9e93bcf7ca4f78e3416e3a088ab326dd8f9b314ee56162eb005340f325bd1369783db12b90cb9c2e2ef02df34fa20473e323e9f6c645b21cd08485c27af84eb5134dc176e3419c949b32fd891ca15ce37b9ec94e81bdb39953851b623dc485a85f6af1b2886b92aa4df46915c312d79099c5f7654376f72f31a35772cb9060631247929d7358fe268735592bc2617329ea9ad3ce31f3678ca17064e7de05de832c1635fa823f57e42e69c2f0155e30a36c2d7cc673d8ab1236afc8251c49c4631c37a42c5ea7e3fb7c3ab8a8de1f35de1be0694fcb0553ab1f780963d7ac2dbcb33f2c0fcddf12987b082ed9cf6c9493891dcc09937e26cbcffa303895927a897d65c664e4583cf7a44bb420e614f9c9ee98bf7e4999b2ec965e7a2aa7bbc5ed325a13483e263811b53805f61fa8e2414fae1b07bda428645f8519c76d8a1ddaa959f082754d6dd17622a356174cc8d1bb33105698d8c1946a31be7ee0975ef9fd0e82f4f28b784bb175d3a8bb095bb95e797ffcd0941674faac192834d6a650f486dd501d031b221043fc19188b702a73a8d68ce9ad1ca60ca06918aa7e24cdddf5bbda7ae25a99e88ed8001ee307af485e811b36049bd7247e84d6c2de49176c7abc8f2929beac939ef60539f400db764fb5225d96caaec7d59f74ab27ad418cc1ed5a0b29ad4cf2d2d4b9abc4a8935423d6ba16de1b4e0ebb9871f0e85fc73a4decb3260586eb0eb22990d1df611d8d0175be7c9c98f44d1e67e8e77fa59997eacdffb69d84f1aa41736eb42d92fa897ed6713b0e750e1aa9fcbd57cec274ff3f2e45426e6f2827e06d97e76016fed6c97ede778351ff5e4ebf9289e4fe9ce7c0e663ec1eef7f9a8a76ebe2b8a92faf9aaa09b51b61bae463509af7ad95ecd463ef5f203825d52b4d4d04d3fdb0d17a69a1b9f09ee27be9a8d7ceae73fc40775b393b523fc35e41cb4642503c2ea7fd6b27eece45752f45b6455af49c6de3dd1a6908296600725e6a8c4522e89d03a25a22a6578960e4804fb888884f72b212c9c6f1cb7a079b5ddd2cbfaee96bd24ca9b01f60c4fc939686aaf5474281b47150c5dafc9f9baf0a5e1f6f091c12675947ae9351a4eca4b7b45f7b60d6183a874855a4e5c53256e66bfddb47fb671d72ae3a84a552516ce15aa6180afc22e3c39e166f27b9248ea948bae00e177b675d3cb4d8c220d4e2a452a3f02051d1e2ca4705ae68126331310416f9b71b55fc988d84087dc696c71427b8ce0a19805cfddb0894be6e70a5127931d187ef288bec08ee453d3f52aa64fbf82b8c3e66b1719061dca98652fa469b18e09adbafd1f9e054e6464282d0e5cbc6f78fbacae7da9be38cf6bbc439a5da88246d1468101ca1d18232b264dc4e89b06ee11fb3c0d217c2fafbede275f1f142753ac67bf0e6549c550079028e23cc1ffa42fc449863695423f1d49e90903cc895420ee4ba2a27dd0d34e9c6039bdb4becb2ffdd3ae452a8a7e8029140aedbc2f5e5f82633aa0eb50273b12eb85b7271f02d5395cd0d111bf1f0e964357ea6839d4e5e36bb613336b725ba465be35a1d22db32dbf3083425ef35d253b9d7cb3e2c1a1c115eaf5b206e5cdfbc2fb844d9895fd8d1d807eba97acddd7ffaf2decfc4474d78a5a75a818a7d7ddf4a1553deb15b4dff31b253c119d55f6e9a386f4dba7ea159aebfd8195431396bc3a91cc4f95f0e66a39c9b62f90c09d6acb1f16eb16a9f94aec446d6c136a2be77318ed0348a15d13031ccbe7f3d6a33d7503d92879d94da54cafcb167bfa93280bbf7b8d10d52b0c5224bbd1e15978e935ab2d0a85d3df7939629ec4a8c12fcf947a567db3257a683ecaad3b840fe0385193053c479e5deaf24bb8b1348b154a770cff63ba5d6f5b191e530f39ef09c7bf6125ba1692d39b5f87fd98c55eeb0f84b91c9e6a76e8d388ba84b1acba67180ea118d5320d7050b16c8318b54889295cadc79ffaee70e017e6d57d85443707de981c4f847f3e8bafbf328d7f25a8f685f3ba6cd0698e5fc8603062ba4d660be86a4773fc9dcbf804a63877d148d2df6a34dff14e4f196fd15decc050b6872c400f34241e0116ee4a4b016e400ce373b396f1c58a418303b9c130e367c63643b2282b91eeec3f999e47d36b5f4fef44b3515b19f3f4f483a1701e693ac58f74c32fd90dbf707c46cc585725415ab77360a781662bef891ef93b3d5ecfe0606670e419e807149dc71b4400527cfa799062680e9295226f3f8f530ce3f4b03de146cee67709fcaf5518aaada59ae7bc12e3f6e93be3715282daa97b081c646efee50044f7a447534729f243a1ba779bf544c98649ce3b345bcc5bb1bfd95caac799ca8f45b925a0ba996ad6e6d87ab987b83de138644953a24ad4a8ed2c8a894facfa03eb3dec9f9c64927398e57de1872aa2c6f68a91ff599f8ab2457e2c14a9ab04d5c65314dbe408524e75c9c8b37d46c4cf1f72ce6c6844e071a8d83196b73c410e30d4afc5145e353a8372760f0b9bea009f65346f194050119442d333d80428f50bc42ca88aac66be45ca7336b9765758f917a5188bec357e76e77b9772ed7482bdfba39d284bd32e799c93c25d3be631cf51bd986178e0ba7a8622af5072328abc3a65bbe698c5ca81dc4c7b27b2c7efe50ad6a88f2d6c6f7e1d6ecc794eb12dba07887da3360978aa04e8f0e30ad63c2513c6489f7d2ce332ec9b7538d48e141ca0c9c4dc26060fcf5d7eeb08f56dd11d0dec8ee9516fce41afce6c0eefd6d27e061db860751769be383d11ce9c92a634b04950e912a87ecdd6761aca99a369b98860d1c0ee68f2e33dec03d83d0fa48d77a8d4c317c9193df2546aab7c577c220c4f90da043e3bc7cc79e873dfc9f9c981bff96ca9b753b5e724187bd96f2fd74020367217490092005af38565b73c4d0b95ea043238756e28f94e16ad6c28a440b66c23a8b40a0787b335d9c2e74ac433f62fcf213c774825234219e5e04d3fc5df61b52cf31f247a1a56a4bd6d72f0b04361d549f2916395ca14b3dd9dd8e38100050f648078569af4074fda10f06ab9c5debe7af2352a09acdaa903d1facc41fb0745b11c9e50de9c78083bf57cd453511a19b6883b279571f1b5038fbfed173b86930f32bea97056ff73d561010473e809e1175034219f5833baeb33272c7084ade946e535909b335da4834d52524372990362826a6cb66f9b6743e136321a8e8fd9a573e5f694ef92b9f2d2063e740d1336d120f8c9eccc233075e91d72c1074bb63145b6cc1f03e78018177c1456e0fa972b3bfa4220c7ef3e6651af0c8c37a8c459eaa03e014ae4dee906d2f431ad39649b245bdd568572cb2f10b9cddabe83feb4e1efcd425d386439efa544add37b8ee732a96fd241a88a6e3e93759ce6521a31d568c6c83c337a633245b1d0de4c9dc0ef7a65134eeb08f7bb0251a9860439489693f744b9b39130c4973af0b3b5fb00f44768833c0ee178f0c83168e22220814e63ac61e9d0e96968dd77a8f8e9a1b3968d9ba1f4eeea313cb1eebceab5775f8cf19ade05dfccb390bbf237961a7e936dee6869f969b856c5a697fd26face70e82c45f68a90bbf96365497ee157b7a4911d8717c40eece08ed5b516b84015083773bc2d902ac37f80a789a7a9dae1cc2a9a05c5a1f52379b5820aac453c9d2a7baf20b6a65ffbe6906a3779a732024cb48733c772cfb19bf8ed6f381a644f66448f63307beb3de06ad7cf77c5702d734d0f41162313dc8d941173b993f991e896a4e64872d0ce6d6465d706c5bb44507a3431da624ddd8ec30c873b389056431d556d47e7ed1ec0788d3692435c343b74912af5bd6a60a3ba4d4201eafd0d07129dafee5243e6722df2b2d624afbb952acd5356c097c87fd15b9e3bf77a109eee6028ba5b553bb631fc48a8a70d53ba4527639ca2cba7b6f27203971fa2f7a65992be5182ce657dabe0a54a61c664421fedbf88ee8632f79d1f8aaa64bde29e8f57654e1e82bc9ece47ed42369d973219f35ca15fb55650b9bd91be8d5273b89cafa46269fecdf99357c279400cc2075e907abdbbac412ce108271a3480be8055ea14b1fd56c48f4129602f818fbc2b5ca35c0349d310e989587d6f6670972289ca7f6b945b89b798ff74aab4c06dbac27f274e20a2fd189cfe9008ae5b9d149485f0effb6a7ca7a1867023dc5ebc5b86728347fd90ab67b413e6f1c821d905668e4c08ce85a050a32cb197fcb6372dbb288b5686912cca91bff08bc1de3108063df713b871225983bf432f47ee6beaa5c8617217fe403fef098744abbd2cc0d98d86fb10eafd76b8c505b25fa1d8ce3c7702b9cc5d0f330fd991a8941dc6bbc803c69f188272a83a1ab54cf65020d5b1e9a5af7c9a1cd4e0bbe6c635109aee3bbfeca2fe02f972426dd93bc0ded35d54014bfd1472fd804e25cb5c2c3dfcbb69780be11d88cc764b24bcfbf32914ba901c1049e0937d02bebc96eef160bf82195d5f3a19517dc5db962eca5fe391bf8829f3c933a8019132f229b045ca247c3558533e061fd4ce7c99b024b4bcbd6adf0260b148c8612a4bc54e027b5b96e98e1c827070aeba3c9e3db091657c335ee338fd53404cd2a804873002332a8682ab36da06693bcd69d6bfaf1e9f03aaef326b95918e02757587358b82df2f129b28868513d63b2751ca4364290530ec9d0f12c117f2483bac4205e54ab748594fc45cae14a77fea9091deaec0edb45706f8cce506e4af607940ce9b1c1c75175435c8794d11a1ab25760230b59573c81d5f17a27ef35644103b55012eac65a2213d1337e96baa3014e2c36264fe487c7197ffad17a801632866adb54ddeec0759b974b0156740b1bfd9b98630fb7c47e08b1762fd2ccccd816606006c7330ea73ff78e7ea84c4297842b5ae9ea302f26776f94e28975fd8b513c5098da2bd6689bc1954d24bb0208312a5b1503379623ff838cc02825acb29073c9817000593cc02802f4670f4bd012355912bbc1f1ed53d782ac93af3206b6606ca26e42cc965d0aff1c0eba3eed329d8d5335bd762f4d6dd2d5a08b86152b7e75122320177cf240ab96ca720d7937110665d637407194ee8ea7b934802bd90a7b77aa5af22667516a56b7c758455c66c4249ee91b8c05ffed290b734a686ae10dd0dac655f5bfcf58b071b33a91ce00bbae3067bfc75cb073b3fd254c390ceab25386bb9b158495465076649a1cbec0d0ebe9d2f8889c1bf8bbd9152c51686633ded514d046cfb60cb2943669cdca2c4e9da16733b698efa3e09feb6b6e066f35325a692cdfad30db353e0904b7f31239f38b08ecf37a3bd3090fd858c153fbff184f307adb7a337b6682178b29f8b9125216fbcc190efc3db021d9ac7cb37ce2f550adaf99e1690a3b75be519b98d9de014c5e19a274e1466c2a33960901f78fa81b540305a3e8da93ec0c73a09ae3fa9489ee8a4f6aa539ae05ec1b7b8bbc1df615e09ef28cb13b0abaef03f39acd417dd3f9c19df13fd5705fede15dd2795602b9333ad2bbcaf470e7a4ce6bcb64999f9157cd2d4e79facc134ef67368bba211a2c3e59c64d5aec6d632a448be52789df9b4c0e11b418afd160f38950b324e1828204bec7ebddf56ba7a67857f5f15f386a5d8be328ca37a6afbe4a13a80b0238d40f1628eefe4148be7ffc04653853e3c92396147dc21851a4a7e36760a1503f756ab2fc89501324ac4842e97a9f0f493483f39cc62cf65f91bd86488eff62bd276f7aaf960f017b2c8a9d677db1a1ae8cc880a88405b1d0db9559142b53f52492443d0d3f6e8b189103de0f7cbaf224287fefcb1daad0d5441fbd1312b2f5f4734fb89d65b143254cb720be7eee80e8c4fd99b0efdbf40cc6bdc7f918674717ec59191d0d6b2538cd1534cfe31fa5996c1d58bb5f3aebc9aa775a619b92d69d30cf71853f9dc2b3a4af85344fcc1e2a325726ae2cc35a8d9056c835c7453aafcffc50b814ccd2120157eb0fc869c6114b52520d5f32426084b90719a55b86b1dce71001995f49523ceb4e9bd0aef66a67f039ab05c5cf3c08ea7aba67923f602e25a1303f3a3f3ee2df75a949358810a2c87a8703632a72b676d91be280a44cbf8cbcdcbb6915284de9c9e922f52778d0f21a762f404c68f71cb3bf438904c1fe82e2d214a5b74b5b69d4f0aaf1ab30ede3185531998f768522bd72284d030d8d7d2de130e63d7a947d29ef89c14bfde4a43bd434f89262aee03e8be09309c98d0d544ca6f02be205500f051b58d933d9a82be10e09c7049406cc13ea851d03f5f6f1e636385087387e8c5bbe337c99f60ca8c813e9bf5dbd37ded6cdf7445b70b2c8e8d8e1181d0d9bee23a9085ece085437aea5f99e38b6c1777aa10c32fa83d8d0daab43e23474b32374cad303c84170c621cdc13bc2cf835ab99ccbedc5342decafcec7d3bbd6172d2d9a745bd35352ec4fcf0109e6a060a944b82fe78dc34e2396a67ddd48bd1abd85ff4486c93259b85bb5ab0ba69eeaa516234057387fccdb06d5847467b2586f7361ec91509fe0dca9adbb969fe99dbcecd95a49489d387df1da4486ae2a7cbf07f509e2f489ff52915c1d5896b610fb41c6a87a13fa960b652c526b596a53cdc35d35e96420bcb554a9c1aa84b1bfff62e826a598e9973074707fe86613c15a250c1dde0eddd4f31f826f41f441ef42f46b58fd4422811238d14191c42da725c80be0f8f4b22da6b6039f988caf5fa249485f1eedc937c33f6c5b0c674908813c6ea15f3add7917f3bbd5def9f16ecd7d2eafdfe909beace57eebdc4c702e290c427d2fa1e1d8e588371c949ad75e8deb4744fa0e85aaa9d90c517065e4bfeb56562afb71af8eb84acda4a850453317ca9372c784e5a8ef42b973f549a309f3c6e56a1a3dab89e95438b5d94b052c5fddca26bcf135e7dba8a7bce29053582e4a9dc470e391837f076efe138bf1c36a89fd3aad5b70f1347608b587e3f488427fde381d01369913e9b8c2f94eac08ecf930d2e3bdf1538a09d7d8e5612167550d1bc143eb54d1ff583c0c10e61e572045b01f952b82876ff0175525a60faf696866cd18974e305175f34af8cf39d7844af92fc3fc48e4642bc984e38534a8d32186e37c628711373986171e3dabd9985671691a954ea25a5381328ff53a5c21dc13bfcebbc292b10c771ab1b1bfe454d6779cf7296109c0a67df8f92469b1af4076d91cd17dc90f45a7679a115678e4c8065fb83e71b6e3428952ddced44d56c829bb56b3fb492b69dc1743728e7d12f0be6e2d24a7f37ac16da6ec208a5c043e8c93aea7e718976094cac147c10cbda63a61c67061061143f39478214b51911c8dfcd7f69366ef0f369f4b8fbce15d61a9a761fe4bcca1353ec1f19815d60fc926d4d45a6a00cf616727cf2023db4eca44784524b8fad087f925c457bdc2ce7a05bc189806941918b90ba11e46ae10f03c659cc4a9acd16192480b59345e39f118d02a90980bc69eec9a508f794924fedb73ded33c2dc1020d324608568c14611ca9cf0cdbd73b0e64046b2e3b1329a1deb1e5a25f2549cd7d8668a19057000e830ca7af4735afb18b153152b09cf74ff556cab3c40a287e5f6417d9923eea16d2b592c3d4472785d8b984118405701ad6a970e44a706a430779864e64c5915124a17c1075ea42473cdcc9e4344517a605f8bb52121cb577c9763b263e444c689f3c6bd682effa14116c94ce1b8fb5408ff03b154b56ff34928047e722d77cead31d7c871f107681508e5e2b39074fb85b79c211f080a2bba1114af6273404fa600f2de8e729b991584a38779590e336c99d477fc8b0e0c52a354c15657e221e9728f84d0d5cf676e995eca6eee30145c717122ec18463bb1755c63b2ff36ed060fd03b1384fe10f74f6d94bb1f1038e1019fee8b389ded1f627b147db12a03d07e96b476983d45afa267a447d9b0ebac2fdf60d3e573359d51373446060847bea11c5cb9511cf4a098410ce0be599df8049a16ba79e04de12daea0ff8570ff66c2b3e9f718fd77572c7a9a9661d4c2df3c947b4738bdcae70247791481510f9e0e122b8f573278543f52784fbac074771b7c96f09229d6f8e80dfe6907a6a95430ede9015ead56c5f6218f254ebd94e52b026a52222a2e1b0e52e303840bee47a77175c49c0581d55ffee5a4d13727cb01ee0edea719692bcc9d3b43764d5703a23a1f49d3c4baf4a59f714f9c62846692257c35f452635026251a8a0898d1841ca77aac492f2a16fd1547fcececdc22bd4241c63eac832ba229ba91893ff823a3a4e9e753fea91ea870aaa6920a83481e027be502da3a5d74ce9d334ee643e6b52a3a2d4d2629dfe5da57fefe8ffdc9173dddd2c4ebaeb3d25be7c8e708c6f18f0dd187614bd57849fb7281a37660d2cf492c896a81a884582bc46e5adc71a3def6423e3c76265ea65522e2af5a701f8f5ebf4573d202c00ee5dcc2c5dd06458ad43c22dd491e4e2c0a00fce591df1d36d36c068961a34b1cf3a3e1b43935be2130959bc242f38ae964de50135b2994ae1442d0059ae21c91ded24496531fcd270b3559c2de9c7eb5a9d343b5b559db29900ede64dead69dc952ad95e4c718963961211460a9f1557916891e1787f47027e7a55ae544ccc82bb49545a46b1b5e6ac4d50feb68d0470e455593e76d2b6960324ff8a6550c7ffd999a7326cc3d8b3ad42a19ac41a98d6bb2d8bcd35713adbac877aaacfb239a56972db7fadb117bc29da9e2c543be60bd4d3b7258a928d299b3cb15310823e23b192d431338365530ddb59d12ee05b0ebbb864ca0b52d08547facd995124838fc62bca80120590084b678c9d1b4c8a335a66beef02b0a5b2033df894d450dbe2be702d204d06c07149bfb42aae9e147de1553f549a72902107aa252c4764ea07f75674b1744b99e73d2fd58c25fedfb1d37d74409b078a1c6c9a77a6b5704319c3ee503be5ab0fdeb75ea9b94a3ab53a04477b9d66090f9bcd07aa78765b5a2bc588516495b4bb72217d2a89a079cb949c5f2228d0b927a8f5027625c3d48f80aa8740515c42dbb474e221c43819ea32f9f67d8ae3385b4bf9c106a37462785593be1291faa88d0f871e9999c35f1d43297b549e73ab11a9c7c952fe7d442bb9975dd8e79bd126396b9a5b7cb39c2f15d0991592a37595826f018bcc030d8b3d8eb70a61f35b367c815b7b410ff805893e19276671cd4713b34ecba16692674e38d25d9097cad180f0db95bd7e0a29d95f871717ecda0794d7fc0a6addd2d4ff747af1a7d754d32bb72819d732c24e9ca2771fbe1bd7e9d63d2ef893794a361dcb325936e617af8435c9f5341f8e4a46760d32dc8b94a4bf284fb16944bc50d78f6d2266be98b24e7b3e9060cca33daf78892732cbdf1118c36bc55228fce7be94ded3a7d1679944d69e3711cd584dcf104f83d4f78477966b94203db1fa42e57f92e395876d814d9fe7b36c3f90b36635a97094be18bc65f3018911267c361e84338367f632e1652a8d039258edeea3de52e9c1fdc85d85e127640b577974ee6b384bb5019eee2a6a322711707fbbad37dda69afbd883b77190b300105d9983aff2967a12e72060f798d54bb81cc44ee90de6ac7d231c678ff3f6034ead615a3d1b0fe3fc0685cd43b188daae200d122d242f583423b63e16c0247779731ac4a354a93e204cc5e145ab4a85c2b9241852cd90b65e1134452a8990daa3f73a9e5d4454b87c8ac16034c73f2f0535b7b45568600cde757cd5dca668c8970f4e6d1de50e98908ed97ee5e5a7074ba695f2b7bf99e08ecb5bd6b52f0d30a4a94b354d0acfe4e99d6f6bbc6bd0713b07c4d9bb6ff9436c5f6fb6ca941a26c3a6ac0b9e77d051f1e4259df09a176dfd737be3d1bcbb9a1d447b5834ae38656c76d2d609cdaeebed6c97411b79fe9f1416d48f710b7c9f5ed6437e48652d2ad9c567e2c1ab64833636f37d20c27fcc5c6a4295737cc54e59f3353b57fc94c45ff27cc942796f63b99d1c46c2dcd1eaf9dcfdd86d0e3c169e53fc4d6716a0bcd3fe89f7a0bfedf64205aff7b06a2f66f1908cb23f1b7e935edfb4c44a5fdaf998882473aa19c3777ee30129e70acf66f8cc43c07df2fdccf8d842fc7cc9f41e6af01c72575ad9c8b3c36521340ff091eb6309ca624c37f10f4cf33e06c74c9d920f233c9ae35fce6b78e075c9e01c9a4ba26c893bbf71ec89eb04bb2283b4966c55ede157ecc5edb3f86ffdecbc59501835516c22bd63b8972825d804565ede4afc34949f9f75ac6f3fb06090a7334b609e2b89a468d4cba3024c7f5f27da1ec4ace362efe287ef729523f7cc66d3e6ad0897e7e2cdc8acc59048c089b1ec6c0654c829cad3221fc4704f9933ad4df5d45ea433556ebff78cfa17a1aca1b3207cf2e5e02fcb27909d1b35981e8272b6001dcddab792e3b4360bd4b461cb714f8a85e98eb24691ebb67d44322619b50949960f665bce59741e665112f49682620acdd79a965657d7be582ddc6e0a01041e6e4eafcb3ad63dccddd504e2fb06fa0aec23e63c249b245a9a3b17e4e9174e772bf5945b23bdb0431ba775b3917394dcaf68c84225f1a0f152048510f3b4f7802a52527adcd895f0f4d14e88458849a815c8fd207f33fd5da3db18f4f6cf1de8f85f8d8ed35b07815b5a4ee4ecf22bd1750335ab9a400623784d1b68e475f0df3ca17ea3d01870dc58e9172419d01b2fdca06f137454adc8bb0c9c2b34dbc22bb1372866caaf4e8a56e125444c114e7cba1d1a040e4d05dcbf25aa64d67db6cdb0d48f1604b19f2c66b598bbd546356c7cda4f0f01cd240af0914ba6fe470424733d118dd79ba581a058fdf9a0727eda08c7bf1b303ff8d420349293021432777d07f2b5aec5f67647c2744a28877dc9a31ac9f156aeebe55ff59f30635efbe35ad0e2c461fe4f0465f7e08ff5d190733ddcdfa6094c664c06ac2517218d15ff5bae2df05fe3d250fee6e674a1570bf42cab1e07c2fe7994aaf26b5621a6071011af09a4d9c7e154547df67053c5f022a3e9a1209cd43e8c2071b2403e1f6622e1d76b30af1a1b32c74345cc57603233873a4ec3b20c5d663cc8f7708745e52ecb7f368e683fc1ed55ce74eb763a1f6b286a45b7ed0cff67e3a718e92134cfe47bc6d227daf8c6d33a67eb97fba9a01e7ae8a627c5ae348690d174e856b09381fac184ec6542f3cc6ae0905383315e896ab8f6d50ef03d820406a2bc79018fd0c267c0c86acd1dd64c0e4c99f641c7ea46a4e1d52d04f4ce1093752fb0679b522bcfe8cf0eb0f137e48118af78f7f264bd7a766929e5a38bd50f2b6f3de9d112b3f46ccbc134a6ced8f5344a80980490c9cfc48736a0c87886b29a298597fa1882f5ac84640d97c871132d7f084dc747c57f39d33f298e89ef7a89958095a70254f3fd2583afb918a5bb5a79f202e065dfa7f23874448aa8a094df668c5a03493d523ae5f09f4c741d5c7261c0287157e8ac352c8885a3eb9ff0b28f06a0e797bfd0a0aae700ab20e1af411110a528f65c2aaeedb82959323a15ec2c483c3fb24d4dabeedd06e9199652697808fa43bcd48f6de9ae0158076f7054440833695a0c22883aaec25c9e10e174f09e499e8c1132440cdc2f7b7f2526ea585624e942253bdcf2da40209e8af7a43ef13ea7cd9d45f0e2db95fcbd4516bbbe032b4559be30629a6908ba2807b60d609b2b2bf3ae8a783877c4f3c7338d9b649b2ed0861392a94fc7d6f7d80199afc263f73b86383c2fecab1ffb082ce4092ddf9e3a05871057792237b093751bb7c0a30e8a3edb669e7c7c229a80dd76b28317d5e6d1db8b96be168f01675d232171c33c0910f588d5ece8f99a9a3d453f38412182da4d1c4b8dab4f343bdcc1f1f75c5b0210f39273d99fd19868ee26bc6279f39dcc101acef98d96bdee0326590a00d7ee40d4636abcc061b1eb952f4321b3c6db2eb4df32a7ab15ba5ba25ce5ace3160b24d67f2e97242dea6c357ba4d1cdfc2db843989c1867d29ae475047a987d03b6546307b352f29ecd5bd2fbbc26bc8cd861d44461c9181583ee6ac7b4de27ed57b9ab1755068c2c40ba32a859e7184f2f9669a5683a33b7718756878e072e86537761010f153963ca1c130024ea7bc63d98635d3b089861b69e4973ae7a56a708d077d347de157ec4dae736f81112f30f7738133ebb705aef88419f2ccf20e783c31bcfb8e635af8620e6a75f6c3ebc0647e66c988b9288ff3bafd683fe5f6ccfa8f4bbff4df407273b70a574e55c4fbf1f697fe4dfb39b79f1e7833216a21d00b173f45247dd1af39f3592b6b605a6a6a35a0a4454f7330887b2aaba9dac86bc5daf185bc30e309973c2abbe3cef0b4f756cce079f8b368c2dbff860b3a33eb63f6e174c5ecf50d74b992a62da6308fcf3ab219a485432379a9723e493c237f84573ece4de05ebd133959a2195ad2845a78a2292353659536afc2d50c02a87f6a249e45f62ec752dc85df37c815c8afba9a092fc8ab5aa707ab9377f375a90215c8230b37f7ab96a16c5ef719dacb22cab90e4354e7a9611d15f2f887faeeb5cc89331397685590015c9776f07dda3b1a2704c8a3f0c519ae6b0e52b616576dc082855a217e2e68e72742959068ec402cd11145384f94de41c57654e1587c543cf12b1abfa9189f2ce993addc91d0df940b341e44144421fa4b0eb088576dbaa8d4ce59b72af02c81735a84d8a85ebd8a24cef02b5c023d0c5822a0b79ea9dfd40bea92eb9cf52822006d2cae42513e929aeb6bdee0fc7dd6f38ff7a467ec22389082022a308e70195c9e93991b791d92d79e7d2ae32c697ffef8245cd2bfdf1e490929f2bed84bb29a3b53d5202adbaac92252cc566509f5f33c0398cee01fd62bf334543d1d5bf9b32d7cef0c6750aafdd20d1b2eb2d2e895585cfa7b0ec52118dd0d74a3a302abc03dd402a920ba6b5c451a53bf46e5735420eb53944b0e106fe5cf1794b909ceb6a3909f2e166df4038c12f1e3e5a24de52864cc5e5315a82afdf29a82a8ffc45003f7ea3c6c8332aea8f713624387ec908b4089ef150a057d142047f9b9d846f7210257fb7aed4db96ca41b07dd2cee5c5a7486620b88412395195b869ca33725acbf22edf8d2a88249f2b483e7bcd1958cf8e28eaa113bdb2119c4087a0428e0bbac848e97748ffa75b4e5970d4e58d1a41c8b6214d45c7eab27b8208c23c661f2542f6089a79328793a11e2ab9c43ee864ace0c3e14aa305822ab3cc0a2b174e0324e6b1e9b722817148421eb5dc5546229d2dad4dbdaf837f8c22529c7db14d95a98689936672eb0b3ce4ca95bd267db294232ffce2d91d032692bf28929a3bb3ddb54890c26abcbcec6348d4971a6c2b94db39acec85bf935a0828dee0357f9f385d3cdf7f24da9f6148de0222aa4806a45ddfc410ae7f52b8395296d1f14449c77a0402e8ca29f439ac4e437bcc9fc7c4ea90e0b89e552d6b7cd17dd30492daf90747e6922f8c869f723cd0a3f4915c1997f661a70c26607c18e454925c71c8d936f7f253537943150a8b7688c181f57389dd5383ba7e0c0c1598e508f1cc1445f3be9d7c5ca55afc93fad4a66885c85fdbc5d317838ac383f972225dad0985332b542c275fbee52fdfbb33e8df3ecc8efb18fe809638c3491320a2de195e0b8755ec3d5b3402fd56b952899d7dae3a38fa2935ea72e09c3af339b00e1836397297066267d94e94997b0c86cc0fb5fadc015e33f7eb6c7e29aa259fa1a678d390552e5c031fbc159660aeaaa58ee099fec64658a17e529997354832b659d246b27e792bc130b3287646e653963e237bd48caaf162a30c473d9e01cc3f598472983c959c8b89a961fdda98684fd906ec596937ee400de1bc30a257f5ca120f5e6241717b541e6f34a3847b2077b1d669f54122bde456701e6f69583b3cadaa438a59b7aa0b0025580053219999109c592593080160ecc1c8cf06e4e4c825391950aa2ac90de12353ffdb28f94862fd8e3724593952eb5e4d2d2cc10e4220059b46a432dc5c50d9bfc3c5c7189ca18f5e3aef24e80381d3b37694fd69c7a822dfc20b414fde2503889df04333139528098182e507798734584a0d4a34d858b4970110d7ebcba7ebcc66354d38232be89b8bd0f84f49e653564e8082a70fea1c429ce0e1a99afe2925fcf302dbf59648b3162b32886ce07d2ac52f04f5daac87dc9d79568d69dd10e578e2d398d0202ef18598c93926f1ea73cec424343cf08239375b29bb44b1b730916d39876ffdc17e242050997237d904e6d542fb064b35d83b9cc9fa496008e3527500160ba7fc8c1391a82b795cd4824f25e3ee7aa503eb1260e4c76d7fa9d97620f47f684f58377b0469497ff35ecdf63b09a0dcecdd160dea8be68eb2bba9797997f9ff59a224eb85ae6e765aa5cf8bd40ced8f11ea3eeded1fa8470fe1107c6fb4dc3925918790899c5df1ee1c3b8abd2f24fb4d877538cced462561515c1067a97a9e2ac66626c623853066b0c298f8a153ba1975bb017fe46ea4d41b0b4802e06a1df5c346f6c511e10af06c345f8a499e38f69132f8306a5537a006396ab9b18b01348233d350b25347a4412c70b388a322cbc29ebb35ea4ac4f6c43a66051eae1d030c56b5c21ba84dcd56ba3689bb87fb0f962540e9949a51cc6cc5b2e902a988a054ff49990abc1590ab7e1c2147634603a276c7f40b29baf78ddce7f888af440531b6f26b2bd2c7bf9beaac9b7f3cccb8067d8fc3bf0fc85d5ff1790589fb11010b210104208584338f89defce42c7583871ebff0e70f80b3e787f0b0c91c7c907f411cf48d0506bf90b380c342f3bc724bf2ad983feccf7d5d35b7dcd86183d99f5ef275850ff450443847810f1d92d43aa94f87941fb510968a1d841377becc53fc53a4dc63a6bee7d1532d699cd7f8125e0e3323fae342108ae184da3ceaa7face37193d3ba9fa168b950f6e5f7e29403e2a0d5f1e7541152fd99b12347ae865e0a3585c9ac40223eb63ccb26150850a1b4d0d32d6e14a9aee57d83409e2c6e5cff67b87100b9c3d4364d1124fd8b4031954539829c4db91ac883c7e6dab87f8d84783942a02ccb26e10315ab3d006ec422cce0f656b0b2fffa564c841393eadd5be8bb65f395b4930b695301dd586ef6acf821e9a6af25a84c70c9c396733920668ed16520ebb1c916e50be78576a601fe7554c7df7e83688f8ae46e67a4c7ae102ffb19ddd532545d0241b7385a35b313bd9fe816738930a55779f73a87544bd9d72cc628f501e24c85a4786db432b77d5f9449aa11f5a2613ed5ea6864ae7f9178f3d668b8491e12f55aa81a92e10be7119c8b9e62b908efc1e200db4a09e39e71b44a5ff359035cd6ae462c0995ceeecea6ed6b39b8268379b6f0ebafa4288742c04312678e50a274ab3314f6583398e4c742555ad6dc066da250c3026fa5fe717ce0b82e21ba117c727ae55c276d1d4cdbd98d5742596ea3a078827a19a71c9120a3851ee99df44cffb3217dbd19267b429b1138eb32f2a546f0e81d2612fb454e9b1a3f390f306f360c66250d2423d5a14514d4b207d7147424d4a3de8244aad3986f681cb634be4b64563dcd443a6d5cb8c68227cef6cb192864682d5c30ab64246ac20d7ed84d9eb5f3fd7c5f6dd9b70bfb55f95b44ff1f6be5d47d44378592651c8c8118c7681e3cfd730e30496c7cf94b2c9722b0f45f3de1442e0ce923601b61708d8ab1d0c6868f36c125eb0c2ec9d5245f385f38ef5c13d813aa93dea8cae09f5da8052cbab850ab48fe3d1bb8bea1fcfbbabc77cd7c2d8aebcbd313cee389a162bd4901f225dfcf7fa940be6d3619625ffbb73050c5ad1d54987695997e03d5d7f869959fc6bf91dd7fcdc2253173868b734badf9f82f28464d864f7f05024d2c086c9167f2a77a1af8e03099f15043ae6f245068ec39e423ab813588afde7413c437229c3374f2ae70894f6437a8e1150f17c822a73b84269271dac14e00cb079c28a1223b6404aff7ac73dc5fab4a97fb76c223aa67bda39e7060173e4f7f709ca421a845f740edf70e7bc27d32aaf8ed268bfd18ca86fb8dc67e9162ec77d8b47fe8f45cb1507ebeaf8e9c436304746cb928457f07343fff1576aaf2a1fca712670e90d12f308ce642ca7ff0279cfd0d8c72c636d1cd0f853b6bd191dfc3431f26c7eebf920b7f4108bae7a945e037d0b2861bdbc8947631e73412ea39df57a17c2bc61c9642641492115042c003b3f1aba152945765ec7533d52c9b733bd57a0bdbf125dcd713b8c75e2996c6f7406d25cfa4574948973e862e2528eb82e7aeb66e5ebd126d73dffa1897a450eb57b456fa4bb4b662b4762b96147e954119b3054b4660cb361337eb3fd06ff40c7357fa7bea96457a44dddcc0fd15b4faff6dd0d2eb254502d2927f5eb370730d67ad3996ee570ca4f528360f18c1af0123c80930426edd366860295fc9a3cb5f37dc44d7268606916b5e7f2c94258b75f4ef24eccd1f38e2b8746d13f1dd11eabbca79f0bcb42d0e24a8b592443e9f73045efbcf69ab3e265b73935a0b6ebe97cf792a546fa57e3eb1381d56d2f06362b80f50956c4991222a965c3b9e5e566a9a07f003c96667666b7f07d580f579cbfb72e5fa035c27e7598031929330ff04d4b3fc15ac688674ce13e16c9df48aef5ab8e106e40889d76ea884b9d403a11ea3a94a0126a51505caaa9b928e5908e3e3352dea7176d62d47c6f535a2f70d5a12d78df6890d8ebc6bea53685e56a68cfc96418ffc07a6880e186b8034cee62a3610390eb61a22f7b20788ac9b131d889dec127259a37e2a1b9636d3566abc2a1488391fb38e80ba7e3f457c59bf84f37a658c0bd2e20b4e67314f7c3d44b7940584fa852b03060562366280421901ac7411c454eecedcaaba46493a3bc6d51bed58794e998b554d1ed80924a8731ed9391d9b8a4d7ee08fa0c98a9a79930a68583264df8d398cc2731944e4fed6307cfe6ac12f340ea1618a0879190ef1fc1549847355c847db2a0fbea9b6f80d22a6266b33f88af85155905be47bfd283ce3c5a22e31ab52c1c9003217285cc80c822410f9002762040102140671f1a58fe5d2b970202710e6b2c922c0400357d9626e5063a063c408c54b2b319004a92a6a411eb12047bd30a7d18cf3675968a7e7bacd3919b1d9dc224b2dab4e72711eb6b08b7f1c2b8440fa9534962050a7fadf20e51332c8f47370b61e159a197a9ee31f4df0a25f8d1a275aa0b860b75ef34c84b3e846b35484a6725ea18dd235833a9d907ab9cc49d0ec6de6a4a579d892a70044217f49d40591845d8bf67ad244c2e6ccc27bb0ad683eceaaa4c4e7b98e9052af1a214736aa5d3cac24d70cef554c9edabee86dd53430174b9f51dc4874b648c9a3b6ea846793bd410653a98174096cd08dcc63ca936d9eae091920c3cf56aef8e9b6ce74408ff5274b913e38c0a5a6f1963e9703ae2e9981fe4c3740b45c0a517fbdcfcc74294d790fda6beea168b9640acbf7fe7ffc9fabf6360923de160eb6a917c55cc6133c59923e6d7122e6b58fe28c2bce2314c1e0e4d06a1cdd26fbd698f93552836b78cced7fb484c73ab59cc180e7ec61b1fbd916aeead4f6c2fdb9f75ba2ee12b50c118cebac577fdfeb9e4ce7ceacf20f9a4279e3ccfefced0e8470f876d6fdbf9d6c839b5e9efe7602679e6401ae703fdb1a1cd13d43a2740a602defb55431d926bb456eca676f9dbdccd9b3d70325e642fe28670b25ad8b7e92085e277fb685384340704ea304c21c842a841f5c9a930cff28cc7d44b215524c152b1efb986c1be4b33f5ca011c8e499eab7c5dced884b8d09273f6f0b554071fd3934300eaa699fda508591d6ab07670ce1e90d6057960f8ad8409c29ff60c8d4dbd888f892d00cf50634f9c9850366308103d650a164c67e8f660b83ba13c10fb65ac36de24a6ace1a8f3517acff16b85beb0316f4394543f62354b9718b2fa497a72c778362893cb6eb702381b82f9c1a5463ff4f4ec8deb907642274660139080e37816d6e804b51baeed5ebd5dc4e61a9813cc78ec2eed2ff605260d8022c0afce89a3aa3084581f0463c1f3dd3938c790d66b26d3eca0aaf6999dd213a6cd66f25f3db4de1734ef32b3431b3e8bad707069dcb75af4413a2cf2af718718f53f03e66841d90ef8a9f72253c272adb80534ad5c62f31cfd2c283a3bdb9f6d0893a533ea074011ac657c9b7bb2495ba9bbd9ffa56ec572e24a56e123b219cd9c24f1c68f40dd5a4f5f4967e741c513e68ea50cb9ec98fe9867005c2b289ee50c6f5190e39428a0e874b5f5e4127cdeb42ba2ba7f99c5eb4dc5ca5873a2bc9f4470a0a15a655e4e84f9b473ef1037092ceb40c64b945efdc5a3f4d5ace18f0f770209b17553a834aaccc3b4a118b5f393edb6d809347c67827047c2cb159f11b6d1d5af0aaac67ea7591b44fb0e61916500a584f316306e7104ae390b7ca9a912faa5d4dc7c6614de008990377121f138c51e2cf4a4fb4d0550d77b3c1009541cf757ed4e0f0b5256612618c2dd2f56d9c747a8b5e7642bb7efac6c237e8b77c61f7320aa62f6353cdd2631820a9912673c4400eac85325bf77323cda717f6420375a082c34510ab3db309bb0292fc5afc0597cd31875d41fd488692f81b380563ed5054bc8733d7776620544cbae241992fcd7a9a0149465e8caf7a6c2c327bd08ce16cc8332be268eb7c5f99ce5ed31afc3e4efdebab432b7f4f91e681fb2804b8c1e9f1ef10dd76e63b58aa90035f932483d82e302d2fc3db34fe000ce048cb28803134a357f178cdf9951fb17d601aaa114849893be4c32a161d23dd8a41a9e8a4c89b66783dec69ea5f8d77f2b203cda7d7239c962de35aa96a7f68b3e223e347243de15d3f7d246e56fecd4878c6c39dbd245ade47011ee75cc69878c6c8e2102412bb415688d4a5dda7ca217c1aba679f744bae70ca085a39f36897db234d20863a8f13bec90e29d66f5085af9b53bbd8bfc302191f9e415ae9b47ca419620c31267d85a7af772f390a04125563a2744ede4908b19e4c8db160f29a0462724b9dab644c1f143df9576e9eedcce4e9e756d96ef58d480ec25c589412e41f363a7291afc19c2975b236280057779e6103544a19cc8697f82ff5a2128c4936347194659e11803acecc44a47da5ffeca1fc00454f5292a72c1f5c9ddc62d51a9e5ca0d1db4c19672996bbbc2a248923e3419ef337677135a755a581be8052a6a845e41a8c5f60d25266543f9b27bbc32a513ed2b99de5b3f88e54530a3b57bccc4c2154a7bec4f66f99fe6d0a48a4637e6b82b753d96eba09ef966c9f41f3a659a301ccbce1b82f72435e537136aff0985df99c1480fdd348ef7a5d2ec3abb597a4593c06dbfb4ccee5bd5d75ccaee6a87cd764edfedc278da50d3ba2bb2ab753d8e1ab79cb7dd27710221008231c96eee28f6cd54a546475cb2d93c38c3362d7fb29c8414403786fd49444faf4e6330467f106156eda74ae005dfd204bf62d59ca70d44415db968738a54d7ab7b35c23a0d6a44b619a6b1c5e410631468e7d1192b29c052f1ddb5cecae7073aa3cf5295d748567bdbd62b7de13c442131b6cc658e25b668576167b5b0f06a2b2f8db08387682c0351d7f439748a5edd6ee22e40c7bcaf885c949e5210b9f86a0185a22fedd9cc4205ab47e2096ba815bfe1b7047ef408d44f946d9a3f5cdd9c00f7cc5dfad991ce9c975f6288d2e7e800ad5cb88ff9a856af2c58d725cae86e511383479012f6dcebf1b5599953e6be0b67373c079c4d35b4e35f5f496ce764fd5011d8bc5d97a0fbdf46e00242507ccbf433f66183cfc4f374a9f530d8607dadb5da59392127ad15877b2e79d534cbc13e8bb3d885b12cc8c4f0238891093ecee9ab9d515fc6f4168d7fce3f2787f620be95db10c55fc0da4b9333bfebbe7bf86963598c56d5275cb8f05f4db8e75c9286ea6595dc969af52a91061a21941c562fc63d42b49eb04f42e153bc599b708b26b1cdeb7242eab18b2401393a62357a6eaa385fa0a4eaeec716a427e4de8a04bb97ca00f43e885b3924695467985d62e508f661be206a82ea8a71b22d3d6a9ca6a08ddbe52b3d3533ea93b78203941c398f54c2006e0234851338a7acc6433b87b6d09a8985ca1f721736fb971823407d6eb7f34898dbce52b8b84228ff2f2760522298b6b80e540cafff1c1520970d095365cae9ecd3168a5879c1dc9354a38006bcf1c717921d3b55416f20735713561d34d4355bd7babc0990e38376616b58d70f34f059524dc1a5c0a198295c577c996fd25347a42595f5b8ec087297038cf812fb0d87b48cba6b41ad654cf10fcd2aff2734e46e95878df3fcfc17bc728e1e5042839d76f5e20041ee17dec20b4bc5f9c6325c7122b8f1e31eadccf2f6d2196f63319111e222872fbe72a5259d047ebca1dc55fb2f61ec06572771f6007c8dc7206d3e69f147535c6066fd3f93f6729df8d346d187b83fa59ac66fe7739f533fa0ad28f1bb85442acc83a14d19c10289ce870ca988de1cba7d7bd2f8354409f30bf3088794f98362c32caa55acfbcf185e8337568c2e3b77b4be3ea6fa9de22c2340c1f7baf496301b0e4edf9455f5407c55921850deb8b5603a85d31d3dcb3de0d826896e5f457033ea64191d97cec5369cd0a9d5e966266649678f0bb6ee90015018f7b96f7354ba5764a27cce0eb1af6acf8742301453c463ac3548f44cc6e46cbf48b5ea9665f4d874d2e298fb27bff072c8a8abf0d8fc200b0e2d03d86a8b808f00037b762f5c931002710904da8bf9adb89efc2a0303577cd15a2490e74159f41362323f6a8f846b2634de6a82ebc0ecdacef2835dc7ec67878c6f8827f9f673e410547ac38c5996fe2338513cddba05eb464e3dfab65f3e63443d72eb0165c60dada1d3c4efd40781185331cae5e7ae08300f25ab0b3b475c89aaffaf3c04f37a236f36fd17a1387dc8c654a671af0d726707a41b37ae3eaac06c0dd7b1e9ab5e6a6a4171ff77ac30a6baad355b51969b233b39ecf7666dfb0b166d3b76c596b4680ff63912bb932065f3a286444fe0caa62b6bc5f2c382989d9e69c5fbadfb1e18c41c9e203cbcd7ce376ada12599fc36600c1e667a5f2383d2af9cf88e2fcc9ed5d106ccebcd8e860ad2220c6acd4e4ae4018dbca9bbc04f8d1ac1fc4a40a4605aa6facb03944469934c27f3c84977bb163abf75d27ca666698b4c1f0703411a948fbc132773e42401fd3ebbcd015eedd1bdd99d03dfd8f06843e7bfe9d776166b460f465effd1d6136a3f69bc010802df9803090c7e9fdee1e072cbedbd0996593b08b4f57b37a703207d7faf932a1b79c02bfced1acf07e8327eb424528505d68dce9804c9b99ff6d2e419150ff8ad5f66ee8d6670134bdee5de87e5839bbccc7cb8da3177384a7d12de6388f975581339d985ab57b9f01362c25e0a1cd7cb8f7cc306852c2765f9cdff2b0cd3628ef25d6523eb90cb4303554beb5f86b269918854124888e75af7e44c56b85b4cad190facc009592c71361fd31d2860c1977718cda0709d63ec0234140fb87ec92770ec74b628d85d45df9b0c6e0ac7b0f0b01d39047ab36619c93b67c8032957721c3b4ec2cfbe95be6159d54dd5b69004a369aa421a5c58d75c9cdfe9d30a54464407a0bb8d5b80ff4fb7ae19767e99fe149926dd7001eddd748921f74bba9a4bb00e277e9a5dd7d53fd5ec23b5f0b841f09bf68927cd9c9de15219d11832b06cc0e783d387b9287c67d729cc69cc40f96ff7027101173987bb901b2c7d16c17d81321462b25a66a4783d6f6866a64c129bb7a02ed875ba06c66b0ecce05673edfbbbde941a6a926a34d7b06391e246592f9b4d474fc0e5caa84e8d4452241dcd9a84cc76a5aacc293c845c686edd210b5de0d6dccb12bc58be2af5769c79b16ba3ae80497d9de1508a081a4dbfac4b21eac99791baa3d6e809b547fadf2543899e63e108ac66dc72dc3b1e5945945b7667a84ceb58eeaf0e49656e1afcd234e39355e5a6e12f4d330e49e57774ca82d16dcb8c97539d3b8dfebed326375dff7dd31c37ddfefd064ccf68baffa529f0380c08dcf4f84bd3ccb216dc34fefbb92eb9e9e597a60729d4112e592b6e5afaa569e2e6b5e18695bf6bb8e386b55f1a9a4c15dd033764b0ab547ef1062b5740aba2454affaf4c0c193313892b27a4108ad8cab4c0775ec8545effd6d7dcfcd6332a1a8b942fd405d6cdd582afa019f6d64128d1eae6affc889c6bdd5d95bd126a17565bb837e60c9e3e32ec5d69fd324ba4aaca4186b48345d38fedccc3446073eeb50cab6ee6f10787fbf887abc7496b9579c81eb0c964adac4341ea7990d859cdbdc6d7ec04773bd9cc639e001123ee9ad59745629696f4ff9adcb30ee8dae1a3c25b3b758db95e0c793bf5ee2768d8b4a32789665545df6993a6d963bdb0f4fcafe822b9e1acbcb49d7bd54e4f39b1e89f8fbc117af36606e052215eb330ba3107ec385376ffcad8e8d43514a650477c1c03e976f143524ef52a4401ecdb0363310fff4b64babff957028ce9429ae3cc7059d571df989ed9d983f98bdd0282e23142276cf43a2ca07c286c8136aaf8fb63fbf761c653abc24c2f7b88ecb9f40d2b38e79c9b2660bd69f94aa10583087325863ba149270f2356fd3690f16b83e22419ae7fbb64cd49c43213a9740ee0cf124729103c632dcf5afc097adba9006066780443e43227c53bca76f2335c481b67796bf08440b6f8c916ba4285dfcc0b7ae61c5b378b292d000ce5c50da3456f6899fca6c2d0c6120ed779704b1180779ad592b024943ca8f5aff8343a042ec9036031107d60ee3899c511a3e90609b1090b9ddfba2b673ba52b5390538432259d7397bccdfcabb9a0c32cca74e8d9ca4fd8bc91811573a07c80c6146734c80cf519833a0752b9fb956fb4b1a9b8f3731d15706a0bfe2a2cb3532cc308985be818d9b9e3bc4b6c59a4695b75d2fb0f791ca9b3eadf19780aa7927d09892f5cb1a8c1df36be612066c46bb1985478ce27be3a663fca3bc38400cb97765ef21cdcd1f1d2bedb4b9227c8494132e3855bf77eec4dedd5a0949e5001b4858b10530fc37b820eb97f30a0aec39f661bd33b9967192057dca3698f1ecdd3edd553869ad191416bb396a9ca7e1a7a291970d37f669eaaf49f19a16d1fa6787d80ebf6008d0192d1422b04826df06ec6686dd3c936df6f6ed2b5c077ca88824bdea18041b4f97ef5383a740cde4d018b64d952dae0b7ab4eb8b1f7a33f0275f457ebddc0835b665e8dbe1ae19f2be289ada597a82537c89fdb3bed0894877816ef64f294f4758fb4a472d4fe811fafc5662b2b3657c20cfbc7449b350005a32b48b68199c05398e1d46a851f9229dc71e245d63da31a4243a9c74be13fab6c2082c03dc70ce3e6ab5a9852495289f35ff8f5f1470d5eca997f63813490ab3b308e84c22d86191250baf9ecc263215281bfa3160f3774c3b43cdfcc9a7faf084d05e0995d3b3d0a27bbf3dd0c6d63649a222ff65e87f9fdcc2a411ead141a4e32d9891c2fa510fed08ddad907d9b6b3e55fea79920ee6779c266f9a11965a673cb2e239dc4776fc972ea1cb8793fc139ac7126c8900e922f24532edd72dc11452a8bf05bb1531c2eefa76fa0930978f9d74f6d1bd66ba453a0bcf0c58e2d95e827b7e0c48099df9302ca974c5ab126f71f35588e62bdb65363fa302eaebccbd4b82379c02d475d19488aeb35dfee5ae1bd68e700c5f89ea3ad1b6d3112c339cb3c8fed349e3550e3508b8c78803512065e939428aa9acb17d70b96b2643442790510e91c995250b83b8fa1cf4312fa4b736336a6e0d4e797df0d22bd0408a282ac011bfe70f9e10072ff653d1a4eca53e71d62bcef18d3ea9bca5cbdb20b42ad9c094faa684d74f8d44f81f6f1b6b1ae85162f2c1cf21870df6326f898ebcfe98544654c9f0483cd55266aa2b9eeafac754b37e9137f35d2439f3c6a913c39d59fc8bad69ba09ff495567adcfa43eea84d57718174ccff4e9bf7c1ea747214e8fcbc7fff691dfaeebf29e39d31147c85320f3f8bfbea67420ddfd7fe79c6ebb37fe43fc3fbd98ffcd4089a1f17f026f8c487305c6de19cb21d0a4b5cca80a32b2ee8932a0780538a51ed85fb6f00b794ba6c768b44a45b39ce00fdde70344bce2f56ded1a37ad30e3fac33c538ec4773f4069999ee1f7987c274e77c5cc97f9eb68bcabdfb7effbe229227fd3f17d8270a5c1eb11a369af5affe803f2366bdf52865d2813254d379fe8d21b8dd43298ea04d2b8846e424bfd0459ba55e28a279991d839697e42d1ad25392144eab2cc3aff3260ac652a69e751aa53f75c6a01908cc180c258a2976944ded0ee2cfa8b734f27ea5e0544641e9ac93ad75a25bd2da97e33796928dbf5e36ede4b7521d71f005cba05decddf5e7a1c1fe85ccfb1b7b56fd7f9c3879610673b81ae6e66ed3d82f9e7192954c7269aa1af1935be5b9ade1b0e40ffd65c842fc4d7edfb2abf3ff2fb0dbfb7d8551f2cd8f0b44cbbf1cc0e1f96e9b7e6e120ef89fea2b5e0c505919f6a0aaf9545e75c8b51439c833114705e3cb488205e50500aa881cdf5bc39298754595e3996d6cb32496bd25b7fa637d1f833e360e0aebbe7080ad6aa304ad8dc70528c5dca092705fcc16cd3ddb578427cf05af5e2df78f014cff438598d57806316aedbf93dc32da4607d2d0b4fcb3050443c3dc650ccdbf2746eb7f030d2e4b2f6096bc50978398a180b43d9ec5edffa3b114db7ff1ab347532fc170c66b3a3145af788c75f443fbcb2e968d1449f58c25970d948536d013b9bb200388c6284c4e48c3c8377dc859df1c76f632c36ef92fdffcc840cd9eaf9c7e3211f691d0fb78ff7392cbdbf90f395f659f358b1cd7c229fac559ce8ec61a0d1eab9403b23b717c4fc6f1b06162819341d95bd33614cc783a6ea4915db2361c73b5f08c2fc20c1aed8c880b4065e08a5889b6bbd610e2ab39852236fc18c7811a06e22b8097af930982591ee89e91239e5b98319a4b9ca0b9e46587656542c49d142a621c5bfde75edc464501e92ee1833173fe6e5af303971987c377917c52971004ceeca39cced23a338f50eda4b6bc239ff4cde4c09eb0f72195ccbe0221157fd369ef139ad515e2609f180b5e78db6984228f508afc5b927d4d7faf2e0ac661b4b18dfc7bedafb5c4c519b9e07c9910123dd886f410a1dde865ed1e876ae70acad978c5caf29419ad184a4577bd77849e03aaeb8f32593a0c32ddb165e218a5a481633879905ae4df82ffcdfcb3e3efb77e7a1ed58c53a9ee6e25915f46f4e2c825c18a00b36735882b419ebb95713dd3a064c2f145168937798ba94a8bba8c331ceb6cf5db64a93b9ef16a0a83093673ea5c3d8ce38cd73d636db3c452e4dffdad17a7417dcbd335a81b0a790381e872ef647fcd07597a6056c69e16bacbb0862e172150e911c4f21c777041f433b3eaba312c6a44661825e3c04a6fccc3e4ccf4c3523ac1c4b7ae1ce0f4c3ec867ee9f7ef227322ba9fa1964ddfaf4400d6be18ed42002166b1429fd1d521cd577746ba3a3ab39be1f53c777e96b026cb4cf69ded7be09dc193758d912f610579e30fe8926f0aff9a936ec6499b189bb08b53eba56f92d0a2393c03ef7f731db369d8c4a1716f6e1225aa48c6b129af8238c71835bb9d23c80e70d496e9de2acb839bbdb8619ccc87d026fcf5a79bad77b5e7fa7624fe16e6ca1419795c4191be0b18a1c14feac9935aa60de51f817e119bb25dfda65fbc99bfde30e4854d1ef13e25c47439b80b1bbe01072d3c66363f095ee00fcc4d208ce6fcf628c30b9b8b5bb878e696f2c4537681c1248531c606692f1b4641bcbfe451fe72cd8ccf497a98b053c2dc4dbdc2f851fdc7f6a7e892b68a8485b8930553eee6d0a7eaf8af40ff71e70e78e054e0dbc1fea66c742821815af16c947bfb15cd0bcb3c5d2d6293c5bf5b06a6db2d2cb0667363208f283cd7d2b8d711bf3b213835c7f33f66d14a9dc86a89dd6a2b19f2b45488c67185e89f51d183ee64e8b164effef48938506f6bdb78ca5e10c947cefde462fa9a4f825eaf62983daebaae37af2bc498ba9cdb8715b81033e50b61fc21fb0fc7d0ccc0563fa0a8c4004775660c7ab93d2a2711c469f7de19b130db5e22c7e65158ca045566943ca9cd3bfc612c61263500530d4e7691d1b7a422729276071e05efb73df14172b201f66466396c717dc7f59b5de210ada7180cb2589b1f2ecea08c952deec5dcbe7d4b71255bc342e9ff23e8d4bb36632ecf1dba4948b447e590960419a18cce993c5b863c554e57ae007ae9839f5bc7d3e1056785002212781b00de4ec8103b1f003ef41796e21de326e5ad8f14463d7d036a9dec3ab84975eb9b757886a52eadfccce5e5868b10112a339e45f232b1d72cec0c13acc16e082153adc184b149fd9a9267009f30c5ca37ae05fa6110f85746cd44c83479f07e70923b2765169b0d3bc3473666b86cd83cf903ad246433570475b37ee5390c7b9c21e0865f331341a1478b853cfee092dcd2f4c899b3644f558da69c2b9377963585876aebe79610aa64951802ee77ac2b35554eb23241f091b2779bce8fde822c22c802ed0db3ec5de511b9d99b6bca47d330b87b75f1922be1095500741cceb820857fc9e9edaa9d1f3c49e2bfd380a9cbcbac892270bbd74cda35f59d0f7e1c80e9d49025437e7ea13ce6b151fc65aedf1571d252856b2cb0cb3a16325bffa26d599691442d2c7b1906220bca899fa175c9386ffdffc97bb3aeb699666df80799b53c4f87926c8c3184104208394b48f06ccbb63cfefa6fa9eaaaeeea960ce47eee677f7baff724c11a5a3d5457d77855e08a1b46c0f855fc72519a4441509a44d3b7dd3d99be001ea3c545da4ef38825ac051b1cffcebf661d0f956e1054baefb89edeee0b3cdbffac2743dec0b71a62fcc96a541ff132fe7b9dd94754e5d9ebcc196fe7bfe08f5bbc3448e426cc3083e3571fb3279ced8536868a687868181e4eab5b531290382e5962f7d17fa1b74f05cc2207ae3c5c1442aa1cd42351af110651fbbbb2002c62c76765ada5b706ff85d31bf8ea9d80585dac224af3b7c6d174c843b6452dd1681c67a23de85941298a2c22d11cafcca43f69b70b026bc34e65889272a71b44555e8a552c0161866724b1866ee3c8a56d3cc03039c505c72ad973e2812705766df8c87e234931477ec398da0eb12742de05c123b33cb64314ae21ce7a073c12a063b68310b4e93d2de32cd68ea652cc66eb536cdd9c8c2e54be9449662616177a126b25053b1e1beb2b6bd83da1613636fc3699863f398a585a5bb3b8f0346ab3f63c6c5f1281cbef397e2fbcfb9cdedee28b8596fb5265cbbfcb5b7b3fd567278ced56d920ee32ce0842813afbd5c1875325fd388ad906bdc3fc52cd872039c52a3e38169bf19232acf7643ff87de202a0ddd58937779d67e2317bb474453b11e7533b3e6b3eeb05c1940a07143d635c8f8f47689fbc774b9f6ddb0705fb1465848c830ae8a5bb0f72973e7e52a1bb1ca28f743c5a2256347bf0f75ca93b9caece12dfb5bacefb8e8fd11bbe4eec8dafdfda75324b16956f157749562a9668891ff14ab19ccc4572b1637e8b71d6a1de0f8267568fbf48d8b0fb34ab317b0ecddc654233771d1d5f19b033f1a402b23a4e7fb2f9b7bc90edef5b8e171cb4b8f5b8e86e408a7fe7b2679271d1188bb2bf81b988d768b6b9840d62bce1f5eae28d45e60e934fbc01e17392f3bac8c60a6996e59d7572493576d8267e4cc419d9b3c10bdc75d0081301afd595e6bbdc28a688bb8375d97c0a82cda743fbdaca25479cef7c5eb00f6702cd8c2c47f7a38d0a919cb6b8f5e62a23db55706957001e1dd1db96829bb8483107d56b91bbb4659fcd18cdc61cc6da3ff4b051050c3f8a3976b9818fb4b3df779289b331be8595029a4c5f277e73e4f4e7baa3d1a4579f18a63f889a47c7bfd343110d4e615b433da2557a18aec933330d0f487a0439cb57dca66a79f9096a3c3b14b07a566a12295f255eb1c95ae75bd9648924f25c6f5b3d3fd335b10766e10756d3276c4b60a0a0df1abe2f9db49f1445bc1a788d0cad177ab2ce6439a54f583022d3776633b1ee794bada8caf8c88938bf0dbac071a8cd790ad6dc10f18e2fe98b9d843cafcfc119997665ddca7d19523a515094ee83e03be28955affa6218cef40732e20161f00a554a47df80bf29b26c98b01e77a566064e8e4e38e64a9638da658dbcd25780c5928933dc0e54fe38598f8e7d33ca6733cadf025e8cb082165bcbe0a35cbf68a9cadac07946f80dd6c06bc050a937b4b291f64cee48cf7ef20c36427be2a9e3dfe4fca45dae81c0d75b5e83b10a5fdcd750e93e562f6c5bee0b02e955d39bba05107db6e6cf06fe52f23cc374b0626e3342e4f970ca848e897141b22bb13f7616e87f58c95f92b88b5fd45c4cbfe44e4549a50c009b8e1bf13056d5d72d4da4cd9463871a09875983c016d11909fbe5e64c12164d8f9300b66f5ddb1cb572fdca93f16470926f23b4903bbea8fefaee00a52b1e8dda1116be7c688039f0aba69dc297770748befe4de4d0c99db8b84027dbd2358b9b02f74236bf4c1ec39d654778b1fd6ced2ad37e3e5bc1a3cb1d0bba0b40ae4c461dcd4b68acf3b0b4a799ee55f7ecea518cb7ef626f743ca3ac7be49837b6ce29c4fb2cf20fd5b58ff64866a732ef16f750352f3c72f54c7c7d15e9b5345a2c37b85a0f54cc340915ebfc83bb06702a3962edf023ef60d73d4bdb2765abd677aefbcf056e6fd076547f5187da6efd9659f8ace1f34e9e3b4d0581a91b04830ca6f1dd0f7585bc05d07838927ec692eb526767d042a3ef97481f664d291556dcf6cc4e6579f3c8e10e877b7da3ebe67d6c718a1fd6398ecdf8bb3f00317f7c6351e89b7e1a6a12b790a0f4c50fa17243a4c7b549ac8d90dfc0fd29af33b9479664b40050594bf8dca2ec44ced5cc0dee104c08cef4987d54cb40aab901ba0296ba1e009462d46691785942d69803315263f68018cb2ac389718a570f052bf24149d0773b28ce39932de25eaee3726b2de1676d5c9118b1d282ed43cdb1025a2d606a8bfcff9e267c1d297bacac8aa842e9bfa7b54ece3a3ade28cace39adadf045d2cad7bd474e256ee24ee5c8366739ce94f4ee76a332f3479c53dfad2025ac7ab010e32ec64d956c6e519bedf7c30df298f8ff069903ca979a7b01597fce5c6173a44253cfcd1391c9c33ee95f94c2202885938db60a8d3703b2440d991ee5e6b8c82b3d414ce1b6c54ae20e5619d6b7d0a9d946e93b92dc66e2aef830410ee42f470c1d04c1cff19ae872452fd42f476bed4b18f24d6d897a68ec59d3150390c650d2a17fc4619e54de9974f742d944881d6cb4fb66b51958548535a663d95496a998ebda75379b81055a48f0e476c342ee680f03a739946a3b0475ed98afcbeff41b92b417d539c7658f2e1d366fc477a7ff6ca021a78dde39051dee713e43ef9dd0395ea1b367dd6dae8186b8e3c1ca3811225cda99a891f6b51673560558ec3005d009b63b9e8936f3ad072dccb0dfd0fbce71e37f60bb715b5e6d9c26bb85b23197476d360bf10c94376794ed8dd7c24e2179658c807441dc5558c21316a6a4ec642cdf630f2bb0777d7dc112e05c4b71850a77bfd07312af48ddc70c0c81852b727d60aea60b2b5715e7c27738fcf38bff19130829eda7fd27bfd5171b0f0d69ef56ac9a5b0d957e661ee05845227bb1cd56e96c6e851a8437b1b2371072203583ecd2c983c5b2b5ff1878f59de584b23529ec67c384231e40d9c6e415449d0e016495ed7c803f58d0682d5932334440eeb2e903c539ba05670b7ef2073d5e5aa0803baf9a03d31e10d7861b49d7c6946a4fbf70e96b5ad049e55a1fe9a2448a1edb106849ea5914bf1ea17c9ea002c0fa35858d72d25611c705b092a6cf73bc755ded81d63e8f940ee5bb7c28730a5b535a94824f0285470f8a6ec393d4f05f31f0dc993bf7505d640b4b54b7f10c0def9debd6bb74eb161a31dd28cdec7946d62def93bac6886d232f15c00547a7c6c402594d0cbe0609289c01a68ac4f52c6408ba7e30a84202fc55d8682795fcabd28e7b9e319d958d37fe242f6401401b85bebdd8c4c5965c54ad96ee83a074bf1baac4d5bd80690faf82607875b0f7a22afb0a8f78a29ebc9f926d0e90d69e27ba8997647bc7589a3d762e8bc897d82783da9437fa1af19b9be225d75f2003b6f817c6c8c26b273909e596a45d4a5d261a48c792c333241efe2b7ae799278353ee3f23fc7b8052833d425a60f25e141160930c14fcadc15558c2c1cab8638cb91ce7bc6ad27e11c0bd7d7341ba2a0dfbc2a0771d00721318c69a76bc3ea66df2200cb79658e2ff50e3773bb6a511d4fd171c85b0a0a5fd4c2547d904456c57ad52a69c9c0f5a08180f94a0d01d0165044dcdb6594f015aad83b22056db9e2dc37c116203cb6053fba9744ed7450f4bf5c58df8e103f8996fa7c385296308a5e354222ebd24997f67ccb40940231246b529215d653fba469acd02ebb9bd62c64be0a46071a70a45ea690454c494a25362d8d913e36c51adc375274693f271367ba01005cc46f0094803051b52f0b3baf15e37b67784216ffda90bdce7dd5c0ee1202bbc966c5de69095364fb8b26a311f58439d1121c27e58e4d0cc321fabd7860a7b4130a6a3af1dca42a7b7f6908d0ef27f76c5a47cb35193a23287c76d30969dbf19d38b8daab5252bc37d6d199abd6d2d20db81b59725a13d1c148babefc1d5cc20611d98277a21eca424defa715ce67d10cc42e1cc630c60a24885bc34bfcd6675a5e9e8df5e43bd7c9dcccca7bfa78920885cdbf499211059518f7412c242667b6b703afa0cdfd01bbdf50c1b665efd2778e64f55fef2b1c61f6580a6b2775505769eb6fa6cb2c34a79783a2c6ba77436d77768da66f577434882a36bd8038a23e81fe36b44b110fec889e9910ffdba6c4c1b49a06a17ee71f7b0557212c84653537daf94d4e9110bae2adc2c9281276867e1972bd854f51c25426b619b0242832b0e3ad1b0c846f126e60cdeaef4b27018ce4e3d10bbbdfb4a4fad0cea3d9da5890a2558a1a125eee149fdc8068fc07eb7e0ff123cb2c5ff4212cd6fcee5b273d99c254a370053981dcc840cec34d4300d932a91d460557d7bfc6edab76df99eb4a2f4741aff743e4ba734e5353edb0e7bfc3bfd687afa807bcdd31145c5efcc7116d719b932bdbe1842f91a2a1d30c6c5d550e3cadd737df6e0fe0465fc4f10fc41532c03e107743b1a28fd830bb9ffd9a79e514bfed97e49fd03890bff59680ae245f48fdbae6d0db8b0f8cf7ecfc6433e529d3b7bc7fbc77c02e3432a8e6d840e029e94c92e135fe4184032dabacd0b301bf91df031af009a8a72701c78a2add29de38ab3d14f281655b1aa55bf7554a29682c5a3345664012294aa5241cd0a09ad4a87bfbae2194a9f1f1d00c63864d17a0133424bce5b4e99e9af4cca381db8722ab9772bd8e5ab0a62d90ffc184bb0d1e9db11372e1ae9a237c6617ba474a4f499ea246c09f2f9f24b102cbff88f043d7940f353b36e7877751904abcbd958bd3b57e8e760d3dc42fbc81ca27064d1e0b333f2c65274ca3e17448bda5cf2f68490e916670cd7c6d717ad30085ad855cdf1b527786eb4b441ae6a0e7975755c5fa1d7dab5b61eb4cfda23408453289465540f88114bf68c909507d725d20b341405044c34d1dcaae2aef56164dfd36898e66530cf16de6e7fe8ed946ca5722e5029aafbf0cd17dd008d6d2285d3930419600a720f5bf2ed87385c49e66d77dec8bce263a3dfb1b2a444951e4bdcb9110aed9612a9bceaa28db1eb6582b7ce00ac19e16285d3a39ca0ea754dd5172b159874aa6ff4b882515541b515946677e6b8398c721be89b582e591a49493e6b81af0d079eb89358e1fa41eabaccc121ca7b075d159e5f6d4a386716491f109926952e2c6c80e5ca30df6f0fae2cfd362a0eb4efc21e449c18da3661077c011f7f7308cdfdbbcb9c1d04bef3b57d83f8a8bc57bb1e52df34639a49af8aa8c9d1443f8cb8f6468b0eb52ac48e0d268419ce77d3e77fd0d4164d71e8d33723fe7dbc2963cdcf04551d48da9f72a1ee8827a83847b5021ca0fb326fcdaf2cce8d2cc085712088a5e64c7706a94861bba3849d331d7ae4c365b4c8ef09f773f1cf7a6251bb53cdf9a179dd3872f666f3f83e9321e1c133f8a1eeb548339ef34d602e6877aa689939a07d369e23ea9e4ad72014997cf5d1ecde51eedfd898d01128da0f0e26b85abec530feefe11559b4093c64ab72af652f631724a56b6fb34344936450377e45a43459ca279104c09a5a0d2b8fa9a044096192d8cfd9166189441e1ad7c72b1f63a4421370631c199cdf08ebd3bd8d3e5d1f06aa6bdf9d87c5d294767581b9620716c7671f7f282f860abf3eb7e098feddd3df2fb999ef8b4110c5ac4336207122a01ee91f6cae9fb34f907f4c594fc8f9f12056a3c822cb449260da9518f0e7ecd3b790587a119b02336d3ca7da42e6ea93ec7ae735d5ae7a4d7d38bfdd3fe9daf09f430123f17baf1e37df5e542fedf5f12ab4df3f715e2e5b046bbb2bdd33f5e73ddcf0ee9f6a4ad0f5a8fceaf45d8dc8e9e4f9f531432c9e06fc7a2a6c0d4b6ae179cb595bff20081a57ca08bf3ee649bbc6a725c438255f87126655eea5bcc4551e768e03afa702111627ce18da741cfa6cee0676df43542f5f51179a52dc7160f0695762c6392af5f2a7a35e0e8260163ae8f7312982f350d771f4332aec8c29519f3d69fcf7e18775b3c1e35fc6089a8ec71ff3a1313f18884758417a4ebb0aedbc85aba84d87cabb6e3e3b5dec7c7da5a901145c21e6c92bd6af33f9784b99aa96ba076b8f76f6e223624ce8b1a1916a3ea28a7163dbb1ac7438e281d5b17e35b58e0f41b446580e3e3eabd8d8a6685e19289f2c15276a5cda9d31ab75ec8fe351a101175fec393cfc6d3761bc54e0c7a5d5a57daa59beb68fed4f03bb15478b9efdcaf8d1fe3d1f45f695c9f8cabe72647c38beb32af7f933fd209a7d555ba9797c33058cf8386665078d5885779e426b1093c8cbe54097fdf1d3e7fb009def3ae15faa49957eef26a0d72dea8489675f5e65c3c9e81fded6823baefa44c514d1d23b5d1d3889f5d2d61afa047f019b73ad025f876e2b68209ab1a169051cf8f631dfd2c4740d800ec502f973d85ba5837202560f1a87d3466668ec67ed4dd557f5df88343cd78af52a69984da94f071269d2e078d322aa62745203dd76b4396dc5b250b9d394440ecb6fc6c52b6ba097003b3fe00e6a55f98a0a1b8555705ebf98819dddb7e23e499de1308421b42f716fd65cd157250c1ea9189b44a4f162ce4e1c68d961d89e41101c3ac2baa8279c1c8b98be87c094599e467ecc37e7e68071a3504102ea9d4e3b963e265355d9bb63ee1ba3c07877658e33751cdaedeea79ddaab2609486e71c6311a8a4f3e1def439ee538c419540125e0db24a35edbf0a767994f379e5d303cae8cfc5d42e9bc78efdb55e92b458ee5acd769da1e81c9c72d6201b1d83662e2c0d16505f6c68e79c20f7f70c2d8d971ebfad8b0b44cd7f1788bfd079c7ed6d21071e656da8735266fafcffdc28ce7bc3823e70a17dc0b9c99acb608b6a2fa99371a8e554be609dac51170772830ef1a9f983d4e58f2fa094bc8c96c7e3701a6283911464892c729ccaac04b33fd64c9b07ee269a820535f94619e17f059b49376a61f04c5707672a43916b886d16e796541d647b409a23a8762ec417ca7534e58a35d86397888607ecec13ed6b52b9b32da047b60a02de350b4a8a2b78227a5ab611b23e5c72ea693ad2f1adf870151b6df2c9d34ff9d47f91149fa083fbd1991e3055c79d70cda39e0d54e6e1041d4d4d80545f74b6668f8dc13a57ad29fe955a7669d2b2ff035480cb917d5d94c791cf947b6becc42c3fc466761520790125beea383e9814624783785a1058f94577d74dc42f6b09d73c5cf2d4a7e38931649e1c63b0decde6753fb49675eca1966097754cc86851a373991fd8ccdad4b7c3e2e0d32f2f0aae4d47ae00f9706f6b8eb9c67b2a64b16eb1529fa50489a06bfe772989e77dd667f95caf59714b5d9ad5f07f4e39a7e70a377de9724b0f84e1520b90f2e4b29bd762750c7ee1d3cbaccc0dcc311aae09e59da6ac9a7e924e9d870c2952d9367bc54179530082ac0b98078c6a423f9de3deb12bd22c0399697cb574626c8f01c625c25a51226a54c426dc69b289e8a96e5f7ee12b91150e302b3f94901c10912971a013eed77b1eda8742dce95e5580fc9955dabea00b567cb31200d3d5bc7e21235a03ca2d341aca6a79eefa5a4c417e914eee536475fba651ab8167b1323f9c969e8a521970e70d8f2aa7254f8abde1069270890a0249e98010777137de362a2d2e536917329fdc7bbe43e656cb1b8c4fdc2b0ca25edf0b05bed8da648fe840e845a479c0d33cc514be8e0155c37776568f230f88b4110cd7ee91815dd2f3d5d995a7bd93ea3833d1e7754e78dd6408bcdd239680e49d09aa970b878776df7879d121818c6c8b24a362aaca17ae5bd61d3adbad619ad8a3f46ea10b4f1c7e71424141ff6c24a1176f0c655ab5869058a5b86d889b0cf1399ee56617cc28a3f07c12f07f210a2c1960fc4b6c8069973d59aa91a4aa215e994811facfcd5730a1ba842aefb1c2c703e56fd7266d16448caf403e39f187a0d2ce58bc7aa5df26c737d2bf2d53c5a01dbd816ae49b3697f06271ecd88da8480e6e56b4c2e62ff01ce60af4bfaa0c4659a1b37ce0bf67a7d0d3869ca1b83496c547636879db74269e076d013944733e7842f33559c0a0a84d10d1c2d3fd96c4e41c9c6dc98dd6c37205e029a250b8948b1c4c349c1707e4331594850c51c9d164bb06d9e69ec91324efb4194b0f43dc534cdcaf9198d8ab402677deb9f31fb52b7f01d7aa87fc64eab6efd05ffb7098185fe3946b6280fced240fd3362a60b9f9d599055e733baac420197f811e37f3f4f32253f3f62e55c2a427478843c6e767127732c93bcc5dd9a86cc21462174df153ad12e38b202db3f1e381984567c53d373d0def321d482937656e418ad6a9bddf9e293fa62a5ef63065a144461b29868a6b067446f3347410de94682297050b04b8d4cac0ae0037a5292d4ba0b297bcc2dcc5f8d43fd35da025296a4c66b8208abf2a5fd90fbd13b6cec7bc099d8ea24b092a955125d6aa62dddddba09f4e9fafecddaa52508f6e64e7a9cff3dad311516b16350566d5963e21b8118a5981b3211ebd34b3d87786953e035dc3748fb3d8655bc8dba11bce2d31cacd54b938b69a13a14e781ff949f1ab2c02979460fea55b83dd9f338a413a57ec56f156ac67f9e7622c65c2df7110ef0781f992b537ba4cbe5699bc3da0a239dfdd3acf1320d77728673fccb23dfe8ad199a7958075bf2195cd70b0dc168c675163076f5fcfcd24be7a959c259a674d4afc3e29aa9841feacb6e38f3dd4781d230db8cdf3b531cb06714f829aa2514cb8e01309da345c71aaf0b59240bb1d60f2b031bfebfa80f32434fe58e5be7eaa8a24b6db221b282c8f78ad6615b65857ad3c6b44fd9f1f278e32c4663cc12cef494aec1d5eca65c4706075704e82e2636ee3e6acc00ce4c7439936a831ded92a469ac630617eece899b97ea20de8cb9b5040b94fe863cc9be46b95102026a19399525c69d655767b3d237342ec870840071ba1289d420e8edc61fe8d676dcc18bf2787a0529b4dc31b93106caf0041d1b73476951fb313a66b7478d554e0634a45e25b2f0485646f667f59a7e0100f75645e7f68328fe5da4c5ebec7f77ce33a0e8c410dae5327fc17974d9b154eb31b75de1d2e1813136b9b04a9edbccce1fed06de2a5c3a3ca2b095eb452489b4cc152e644f74d92d7cb3d4d6acabd8c6495b592c362d40e25a5d9680569aa1cd8e57c5f4237dd514d9db55328adeb6c226bc2676daf23b3b5a77c227e96a6d7725fa64d47eae7355e572f19a3b92367d69776864b56c2dea43cd9a3cc057c7b1b18650b70f9abf03c5e4c01ed825df8b1facfe776b0f733e40e6e43c9f5cd5f9cd473eb0f98028fea0ef14ccafb4995bef89f45a0904559dbaf59f386c3f01a360218cfbd49aa3167179a00d1909af51858ffc2a9b4b0a78e6c481518f2c792037b5b72652df4140e1d3b0e9cd3441502b6d7a8b83a6fdce73fbba0e8e3063d0023e75e10b2be72b53369a52f16a2a3a29c123887a6df0815d5bc3b6b5664360add4bd7809a219e7d18eab3047e1dd948ed3c649b645e38709f7667aa4cd78bbfa827ef56dd93a23d2f09f2889b4e031d70e5736157d5a5120639135a78e1e72a2dbc1fa1034c2f7935ddf46b5cb4e205aa5b6d2155f5581b79e3e32c96d98373b1a66b3a16978db09826da70c3b343b7e57c6ba90b632cb6d73150651f30fda64a05fd3e6b1130447b7cdf16aa0b11016b96d328e24dae4a873d366a9130425db260585ae06127f108d1e357868f5fdd45e237754c08caa38f9e5486cf69577c116c94dbf9e34fbe619eb8bb09523ad29454c94f91e67e28588ab66fa7bb14e7214d91668fb123d3ee5c9894bba84625359fad8e2d93013d32ddf6b17423adb274e0e0524fb8c21a559a09fbe2127aa8843b6d8602f57758c4966aead2da92fa5ccf605a99c0d224b873cab5acfb950dfd67b4115c699388fb380ed3fde17824b5f58e085f4a13bc89dcf053cd971a80600b012af68bf0e998650d6aa2ade03bcb63065e75b717ce58d731a06d1ece6e22ee82c6fabb8da68287369b3c54487d88a71157145c8c6f767acea5d97ae31091c1a3014d788fe9e2f8df5e30ba2dce7b0354b0dcb734af1720498817496d3ce90a4858f7ee692a5edf46a747add61f65daaf114d635ea039112f4a4b2bdc74db0df11c9ed2f32f9f68574c3aca0cad781d12acabae4929b5c23e238f07cd2f6beda7261d076e54dce0082243d0f0742b1da570f88d4a3c3f0f6559a3d82521cd8b0a9c74f76ee6c7078b1a2b7589b44a5875a7d0061c29c6febaa05beb817ced31b3d97aa1cfc5cb6c4da0b2edb64ba7c36387ce650dd683ac566dc81ba6a15feffd1e399d671b53712acdd254a7e9d2a108a5d557b147d7c103b08e151032d18d2ee99b319be08fda535476d1ffc6ecc59066be277def3778ebb4edeacade0864c7fd411e8945e243962abca4d953ace3da635bc8055e69367b7740ffb26f26cd3876c4ea01daba2ab78dab3fb3e3e71e303fbc28d10c6c09db8dba03bf9ba6ff0ea57edeadf5aacea234eb22f34512fb0179039a5ea2331a4dd2a7345dd060c10ca66a81cb803a15ca03f4d9563821f9929f4cb409e21bf4655497b714b19950af736f0afd6e8d97863adce96f62ae077b756af277d1b1dd83a0decebcdd5a50a229ca810e0427265c3138ba72bfbfdf54885070f37917dac5dc01d7358cf913537aafd67f11ab7a6762037213355c73a39f1165c4a30aa737edeb0a62675ddea5ba25fc5793993001d215186f7bf11a95a9d2068b92215630301d36256cbdac55bb426d58ef8c20068b3e1a2b405e443a35bf5a697dc91529da9c24d9f8a79aad75ccda32709cc30313f2a8ff3bc966f52d6e1d478c4430a647550ecc009ffcf09fb283dfa75f8897e96d9e1fbecfb84b6787757cb0499c245d1b5ce3ad3e3f42d914fdbcf4a27fda4a2d6eef86c10113d7defb366b426f28d4133aa35ed8f35150dbbb513070d97a63c8197d6851fa3d353bcda75ae6aac4152592013342ecd14da2cfef9e0c24df74392d78333fd6cd6d2cf4eca9125afca828756cf212f1e127c2f47b660c06e56e7fcd82f9591a5ce94446a309718e387210a992bb4c31721f138d3b884df50cd29fdf96cf2d3d8678c972eada3853b5acc218b47038beabc6be688a81f3f46f573eff7acdbf44c539d6277837a0263cef84a6c46ecf364a41561ce57e8d64b5d73f14fd02d7328c1b2ae748419a7944fb9c57108af3287af97bffebdca8063e30847d909ffef11d83771bd2fcb318bd2f1b86f7e3b0cd4cc8b892056cb963e292d150aa1d58b5a0cf55a99f72dca0f6fb64953d1c3113fea737c7da1b86c8c32e3d38582cd1a2128a51533d38d210fe8f198caddd5390fb67c0875e96e78060a05555ab658b0a3a012483c80f9a26fb7f762d157e735c25f0e9112e6a8f363617f1894b8a3b0563aeab36daada61e57a36b0cf7e696281ec01e28a6a61e32536643ae2197c8332accd867b2de8c9881c2661464815bc9651cb1d5bd274ac54dde1b127c256b47e1dce14f94676875651a02d9dce1ae37ca2682ecdb2878a75a8670e76cf4a4b9f14c0997d5d64bb03b6b0bd72aa93c088d95aa2e1985d2bb74a6840b673dd7adeee08af6cc1e14b2ad738d27f2afc370f0a8ed35726da89d38271c3b7cfee169ddceb7380dde0baf9b3b8b9d4cf9bf4a64b2bc0aa062bc72b4c86e4685cd9e756a72bfbe4ac195a9e322af6ad7a86f8ed621f5496dea43dd000b403b4ddcd918be32747c4ce37789d63dc97e7bbd60cbd6ee843808bfe7bb2edaaa1637dd05489d79203f97e31d3a962fd870d9ae83f57b6d166dd0a75e4c495dc597ef4bea8cdb95005d511fb603b9cbcdfe10d7538aabed2bb6bf4b892d3e33a3e3bcef6b87da6c778f47ed4503d6e383d4e29e5015a082db9a64207ace8b45328161d4b17f3d6c0d255a471a3a35c9274fe34810b9135d929be30d9aa722aab67d1cbc81536d396567a289d8a697265df587ee48d79535d6e7e73f160dc77b8e01b91f552bfd5d66f459351de6bfcc00a761336aab2a76a889aad4fef9fd25d9566df57f9e69c7f06b03ff41072264e16ea445df0acd3e9503989fb9a8dbda3c8b1cb1353d23ddc1cfb25dbac0f4b40ac4cd8c5b55b22e0f787a56b52c1b87129c350db7104577d27ee91f46b5264419e2accafb8e411d23d3615860c4b2aa82d36665f5f99b595c73965ee22121af11743e266ed4807d060fafc31d4266cd338b02a5155d9c2ad903c055fa5944b930dd73fd5699a5fefe0cefe4aff7eaa1c14082dba445ecb43a426ccdcd431ed2f4174e235e2a5aeb12c38671cd8bbd9084a02e06446bc53fec49b6bc34e89aa703dd92326ec99d84a3a11fb8e4b2efd7452f82b15a0cd96bdaf3019256027f20da6f043014ce629088624d226377b559cc1c4d5a086316c82ed31b41e854a6d6c93f85f9e3db1bad7ab71da4c0196ff3abbd9d608f82de02d253191b49da0f63b30368933ae78bc238e47033a7b839b9fcfd9e5749873528964d22f7bce6711f0d4fde6edd5b3df1c324457953da695ba5b6a2425d3f4ab38376f8170c259459f904756189310f11c97794ef7d6a44344fa05f1366cad5a966d1cde2d44cd5188a52e1234f23474e24145a693a8dd74edfa709c5c8bb04acdf19f8f6a06f2a30a513a6420e03c420dc292d09b211cf923fc3f2c87de8bf2f51a5e9ce0f7181f9ae0ffeff6bd1ab2adaca971846627ac998c5fe4174dd74a054117495388aaaf673a8877fcaf8ff9b252f8d31e9073ea5a5ea1ff6e151b2e7e522c6246deae15e91193708c514a819a2967736dc3459d93a52758217cb8cd400b051d075c405662719609f46411ff417d7edecdfbbcd0db763bc8fffc94a9a8c84c2dd146b625149ab896fd7c5795848623016917ac19948c2d88b7783c545ae4eac5b687324b2b76b2270f36709549401a5acf9195f06055d3a102185527e10f96f9492aff650f6fee2ec750add87e549b62641cd71c175994aa94b9b35514b7c1ef3aa968cfd583d8dc7ad6c3a15cd86cdd377a041d6cfd8baeb2fcf74c507664ff5e7696d08ad7e8c603d4a83f41d4e4c8fc5a01b3dacc9833e678396efafe177846e927274e65e34025f3ca530a2e5c805889d267de8b5cc2369bb124eff141df6b5eda0eda4062b215baebed7e07373573ba929755ee2d7be82005940b48c4e8785c3de509db8d3b397bcdf3fb2e7e3f0241559724283366476f49ec794f175e8084d1630263fda1c0a7a6a3381b61fdf0f477d6e4f165108c2f1d6bf276fb4e1470faa75848cb5f941ede6e9e4bc280af635f6011503242dd0a226c9441bef110d6f791936c5d29dbdcc9de78ae8a8b0b5a04f95259502873be2ab1f0471af80d3c1d335ad76338e10727107414f4c07e8e02ac7354449f21f2b5cae33a00b16d3f2305757b79982987fa71469cb1da3dcd749ce1b288729ec59ef94d9a1bcb7ceb3dabe9c736abcd85b0432bc72b5ec5072a33811b27b85c89659f898184904371b53103b02fc3dbf0c9c28646939d4e4006f8818bdd7c3f014a9232b5a1846f53f91f078da6721288fab9607ed76881cdf0ce8dcb56128ecabf798bb6949364f79dc67e64b5a8fc71b5a86b5dcb732962d30f827557fb9dfbaa0460562fa1b569459628e39684fb32514a0e388ed4391b4c4abce9ea6555a00ef6b616d09edaf85f54b6c6069e94bdfa1a7f7272e9332c08c79316cfe8aaac0e8766897bd88a51e70cb5df184f89b5da92aa71a79ded938ebd9e71caebde1a4565433d9884f2d4db76e297534163443ca4a72c4ee04953e53f087830c79f0cc321efce2a540a39a8caa0b94ad352b046e5b74750c6f77de1e2fbf73c13c885976865d3b68c5922f0cd7609b69ab29e9b98a9f442c98269478757bf5de329becb6dcc78a5a7359c88355e2bc7beba6f5d5a54ad46b1abed2926d11cb6bc97bcd7077673955b3af480c7a16dd4a596a4dfc3405de83bc6c203cfb66bc62cf46d3ff8146bf3e4d45b391e59dad51ca3552026bc6306b8e3f8ad21f1985f4ef6608b94f8210a95b534d436cdb3862b84e5aaef14127ebab0496d2a48c408a6d101c0f99a45297bb5dabdd03254650965b866c6ad1e502d184d050fa453e6fc792769fb5256dac41e9a2e1d04fe2d6d5dd5115f611370aabdf9735f0933d7b9b78606d4d3bb86ca08dc371474805308d2bfaaea67a806958d2f33553db182ccc424953e32af65bf9899b937ff8c46af1f7f38ef4feeff1b7f72ffe94f5ea8be94b539d59897ce8fddec0ed929425865b090d67e4166e4e9ca91da6e99e4ea5ba798a6f136618b6e94bd4967fa5b300ed88e29d6e18b9ce0b5d6c0ecd67ecabac853bc0b9d609a36c37df795fbd5c443483aa9fac2a03142fa707b60763cf1458a16244970deb326e5e397bff0602cf7ea7abdd257666ae3e8e159463812fdd37458dfcf206aff099c2eb780686eb816a920124d4a61a162d8355eaa0fcc84fc362da52d4c5ba10d223855dd9e053fdfe9d83ffd324dd114b96c4848d0747a2c0e6cfd06c041f6b2e4bc3d2a27d132e9d8d329b23911c5da55eee27573177aaf9c52e4874235023601b8075ae914daf28095e575ee7908bb2702c7dd51562eed5155ad5caab9b74e7d1156f0e8300ca2d9ab3c8cf0c8e10d7f9a14f058355a7fb3d19a6a34188675a7d1a9349a4ee46c78a36ecd4bf057f7101375676bd8e6f955925ff438507d8ad77f1f1f50008af109b0deeb5bfbc8a4e3ca8ca87ca003374d67d97002ea8de72acf4485e3b952135494e14295cab5f29f7d6eb4605dabe2ec6e2b7c99cf2f600c5aeda3dc68401b289e17326effb2ddcc7b8e5c8b14e2182dc661a19ee994edbd6dc8ad45f5916b14b40a7f60a998f9881571f35e26f74a1142b7f332c5b87e7bc33a7042484561def35eab4cf8dc2bcb13d95e516028be3bcfce4cba5c0b71d882f07327ce7d6534e4e0cc639600b285b82e32c00c76aadc6a5ffe354ab9a783383a8dc26d437f8c85a781d6a95933fab4a7c9dc858bb24ee197d44319edd4b73ff5892fdcd903fec81b96bfd72e640a88df8e87c0b44009dc2ab384313f598469bd741504a5abbdaac1776470f93f6d8eee6cb0dbb14edbffeb9416e1cf8426b857e27bf167ee49ca6186bfa04208de0de78aac99a16d2e7117e870fb2bfc5e30a92cbb08609a2984b1f55e651fedebc0b5e94a504a3161374dfda8cca595e10d35501552a8f27953da454e33877ad76d963581db204a7e335fc471d374aa2494d0bcffbaffb953b5e3fc3e54ad8ad2af0845d37184ef309b5eb2f83d8f615ad437774b1292b8fee232bed21aef83a94cd4464fcea2a3884450fb6ed3a0666da5f52f574a532b02e119de2203ad42c74845dbd2a6c7c1452b0a8256245d60a11110aec7c145290a821289aa0f07aec679a36d0fbce84774cfabc42fc60aed29ec05c112c97cd598deeabb4ead1931bde7f9af8b5a140435d331981d4737e8d284a9fb510594ce0961be3ba3911e6d2199a6a322ef4f14ff20550a8e09d3d17acb94b94cd8ec10b325ac3bc76ffec28847341bddb807b0953763b6c9a554914efa1c6bce603dcd4166e72f5926edd27476dbc81714d31ef7e1105f5b92912a988bdc3ef4339565b0fc4322ae24148ba4e0e97182fc2a843fa43a85e7eed8d1c05a8099dc2bfcb0d38f74deda614b17e94d5fa368731603cb53d6e7c72aeeb67679e143be56d88dda5b4c07564f9bc17a9c7efe9b3576cd7fdabf75d50b41e78d4744171cc69638201d96c208f60013b11add5c54a220a8441c97095b3976b1eceee5b2a796a988656a38cbc4b03a3b5ef93fe43e601f4e034490fcdd92b163a158b1c5876f27d9a363c2b629708a390fdfa38edaf0867536e0caeecdce5ee3b91a33e4b3e47fe98d9e2442ef9dab0cc946077e5282dfeb25bfd0cd8a27bd59f26baa15d8e9d7961b2529ad26ce61be3e2e5f9b0c47da99650bfa62cb3ac5b8ba2a5f5f8ca3943c611dc4f56df91a299c3093e1ba2dd4d3e0ee9cca7ea5b7120fa08c1b95f2b55330ab8eeb0daf9f8ad48ad266c5be7a0fc2789808188931ba48c1c9733e1f6976c13c79a910bb3a72a327861fd81a48b10c2945f905e7925109162a68b1ab247ff3e5dc8bd1872f665e3790e4d596cb2eef448fdfa04a637192756bda381dd267c6377997bb7917a30f5fec7eb4a325645e2c26ea80a749ff82405f8c002379dc62fbee468e444067cf846fc5932c13e126c102fc36f768f390cb7d883fc108bee64fb448c3aab29ed518df68e32b792a30a92dfc8ffa83bc43564c76bc2b8ae31bbbc68f47590cb264af06deac0a9350b538c6dc63f9905a62d4113c616c9b49faa1a8f8079e0a238f7eb687880250ec5eb8e1a0457cc81e49cae45dc3d7adf2dcb379760b673500147dec7816c1bde36655c5c80cb66f0f428cb831ee82e076b5d1e97f0409ec94fe242f132acb076a8216ed81834f443dc044213f9963e5fa3b609ca494bcdd20e4d4287bac7def72e80d2efce720d8d0000f1c016a5225bb30e4972375c8716eeead12d88670b71d260eb55b1919569c1305af1d953f6dd126325b48d17b0043b0ec247e2565078298c315911fca27339881cdf4b318655d8e173094b353e8527b6c43861cd85c592e30de5ce572e672ada7969144b81affa8e24ea9a6074db08c4cc85037e4939626a517d281269fcc8d3deb20274ca8b1e6ced878cddef9dd48a50934d052db5d03c3fe3bde9e74c13c0b2bad5b88ed607203dd5d1aed9cb9ce010d0e1a5c3250cf284dc8bd718749efbdd702ebf2b7a91290db50d7d8d62dd2a5b117cf0f88239beab93962c6ca18c478dd7556111e588ac9aae219345ea4a0ce2dcbd44dc41b8ea7378cba83af4ca73710bdd32be9144cf97f6abebfc063e96b3f39435a2080e1bb9f6676d370cd07fa64ddb57bdc47fa659b50f31291413ea664778871a68da86dfe6c13a9c85d59e1093c55e0421f21ac79c46f0d9f0c3b632e524a34db37a781d218daedacda3485042e8b208bd29c5cdba0eed594a1024183e97559cae5f4c6c2107d53ccb38c9a6aa30c24f17ea48a88b5c67e8546c0a04cb5c9773fbdb1f8246cd239c92aafb9b5fd0f1bbdaf028522cb579a7b236a44272e19d3da8333384bade958bebcc313dbe90dc7c982a42273f54cff8ed31bb8cb089100574be66adad32aae56a68cab5d474f8bc8c02e9c546248017d6eeb3e7345f6c9a5ca769e623bccf05c01bfe5bd9d828dd92c6eac3be2a0731c8e9f0c0bfbc3e2c0e4c932bdf18c576932537d5175c316a13f973f25688b1dcd285dfeead4e449a7e19eeae69ab801a9f68e1304c43fd2fc0ad758f3fb9cf91bcf22899ebf705f252a8be2676734b3d93b6624c3ade95043ad31291bbe4657394f744c83f8cda08c23b7f610e66318d2e65f863e710809d9d1da77ed35ebe1ffc80c44b36b46aac35817334f2ae9e6bb40a4de1008fdd213fcda6b37a7b0b2e021b48f4c6012b7535bdc401db05e89f4f70848691ef3923879736a9611cc54c2ff3b606f6dc7eeef8a84c337f37f2fae9c66963fdeeae540d0c87e0b681e9210533af819042b7a6e144e9c1a14a5f2800fa9325eaa017e2f9d13ebb2f687796e846ce061436ff3951fc124d7d70a817ef66ca4c60142e2d974746fffb65f66273a111163496d1abcd049c3cadeec3b58842dc463efabf0af36389f6219aecb036fa1b61558ea2961977330da8d9e792ffdfd93fead3661bd6ef2d5f582396b09c76399cfdabef0a83a9eaf3599490abbaa0df9f9fa9079d35155cca0b1420899f044d07c448bd70aa747f764b38d39c07a71af372a1be6e75cebb57700b116590cc6ee2bd4427becb0c63f8bd47da7290e5bdd0e2c6ce2ffcc64908d1b55b94e18862c67fa4d96978a980bbb9c53d4c49ee1ff363c384997e9e72e08be1ed08ee4fbcc99b550c5fe6e103c246c71d4c56fd30b08689f8741f0badf203f640b0a5b521dd671c4d9cda843b1f9c43b03f926c7257fe7b014a4dfd0ca3c2683e245bfcaa84e2b5d208b86832bad211589df7208561bf9d2e9d547b2e45ac9be4bd596643bd5a3b88ea0c87438bfcb8bdce10ca376e3fa434328b38da9143a1dc658764315bbb8c58fdcc1db116eb4044cd4300305a594f21444f53f07a68ae1da3aaeffa4b4f543c6265c725825da1a87a36ad75c2086992e1662398428da484bd9c444c03f8d88f043ef8e05577a9f86f313b39fa4617d47ac0b583694e5d60f82d8f574905101a9f62fcf85e217e7149b499ed99bc7c4adc45c2c80b8d0361c85c676af19005c3b770e2317750e5ab87c7e82f61a88263d49b97266f522e849d6ba5c86609c6cd982ccd13f1580c4ecfc73bf17042d229d6ae8981f5a275ed4366451f99d8e8265339152953cac969487820afe25dfa053734a3ec1f48c182d5e8335a2a3cc9175b2bc89ab281c42ef5104ce746da0347785f33b07e2a1b9b2acc0730790fbf19be2dd336eb46f4fe274c792b4073ca045043bf6711a5ad5b0894aaa71914d5dd382b25e0c212897cf8b602da9ee958efcbbde29dcfb4400c73b66c9530ede8a26a005cf9ed3cd9867844acaf00fb083f8c910160723890e21e21f2b335c1624aa72f0f55c17953dad15a2eaacd137f6ca3bc785d48ac898bf0aa75b40b2ad9419ee765fbc16e719a553f858de6a1cb6411bedd02f2680ef026e6b73099d0c8bb79b520d8855384320506141377e4f00843604171388aaa6019fe84921abc178c947b139346f0da6eb8b38706f78c1d9307f84a2204a13cccc0574aa8dcb0d8e7b28edaf6548147af7bf720e9eac2ac98590ffcb9372dc4b6501861e70e2143ae727239e23c101b0c4027827309b3c19d1ee4f7c845b8c6ffc9632d92b10f97a6794bcaea9da8dc9587c51c11a346ee2752fe075e0523bde13434f8346fdef31265dc60dd847f6d0ee24b5319f6f74dd04111c5c3d836649331787221c38f1021b2a0887f095363fb06a47b87240ba77c5aa4d7d550ee0d02123d6de81255e4db868d826dcff82ddc204ff93e883c36c87f4074e5b899a6c39dc27b01ccedff0f89aac0e8c1aa6d8bb7809294bb037b9364c8b70e9664fb0cf4d7ed9b3c5614e6b449baed9f72aaa2da223266cabad219ec5f3731fc3097c6b927e436e74045080691f4f1427ba8f9609d2c3870ef13760b995001b752061b58763fe8814aa176e8e5803c87c6d1a36ed9c87048b9a5e24b458ef37ad895c2c15af39891b27551514277e75c9d582d9c6ecb53af2881a771f084c114be2d88f4c392c39af8d974faa3c0fe7d8303e45d853b367c40967647ceccbd81a8508aeea66c15e619f7982aa5c6207e137b16ad361e7621a05c1349a0d3be60a7bc3abb1f322ded83092e6fdae8dba8dd8f3f13cc48409030bdc1edf0651f133c436a690d91ba3ce31d7c84235a157b036bc34152168570cb932c10e132334b400cbab8c01d53e43cc4ee81868d99901faf376daf3d92d269ba954672b772571371b3f95b08ffe9dbd765f8692208dad56d7ce76da434fafa0d0d5c23255350f2d8eebc3049e99950a63be34c3320c5b32e2d629baa8a5b252a72269992e7bae59e4831e57ec3ef7193209a09c22b670da3a93266e8caae0cde38e546ae41b6bacfc7cd20179e3c60281ca8d5187e0b1933f55d03de46de90a9e3f0cedf34ca4cd91d3828d75921bf69bf2b1f44a8dfc8593218bfeea63648b005ddbad70186b9e623a45114f4035fba7eba72656887b3994d12df0a0d67b99b8e74cbdc5f90db57879711f4455ae56385dc84ece8b251015f7bb758512db7f4ddb19cbec4d243969acb2d03245ff2ab18dfca748fbefd558f30cdc7ff60a42ca436d36b7b3cb275b7d44349eaecd175feeae3f163bd547ad71e3539e289d636ca3e39d3810cb098615d88340d895d0b9ac7fa78d2ff7ec974a629af107c40ca7b76f83a02f8f0310aee77a7b218135440747fcd57e86c05639dedcc7acffba5cbc868b0afba6674bf3e0d798c87cb09ab35b4c75b32773629004cc8c7aa17c66452677eeda134137ce4effc04c6b3462bff706876532cfb832b3d9507c38cc7826ddcaeabc454e4bb67032b8428dd356cab0eb60b299314cd8dfe74219942e9541968cf988ab1804513c70fabb9bab08172da6ea1051a955658c09c051104c022c017bd8aa3a41bd56e53d3ed93b5e25796304a471412e9eb3d27bc224eac76ccfc67b851a2d0def4bd7d6adcf3a6c49ef5a7d724b61419b8f612cb60da7b0b67bea6b91f5d8baf6d1ac29af0a7e09c7ca8240364343956da8087d1bfafb1405349175b747fdb39ebeb7d1fa97fb446d8e52c2f330d3ebd55a2508271a7ad1962d33fde6749f45040b19e8a46ae83bdd06f2311e34708e366b0b32f8ec7cc5175e9cf9a51cb06f987969784416369482ac2144c1a5bed68aa2631be1cc710a0d09a2f17e7daf098cdd89d18cbd3a07f813a1d8d4efd43301610f3df0239de94fdeeb0c0bb26c5af37b8f82cdef826017a9c8be48f7ec596ad5ead09347093de19016fe74fbce3ddbba6ee636b78dc2a04a78db9110fb242a23562ade3b8a736dc54ca1d8e40ce6e114311d47018a1998b97331be01d8bc7ad1cf3f20f59f4466e0c9be7cbcf7c8256c23bc07c6e0cd8cfaf43c4960cafee2f5a3cba005f7e99441d49ca36a6c9e60d0838eee8f95b5252114c1eec17c09307532e3879b7ca003bd2bfe6195b75a943bb3cbc53feed903f31fc49a3946e67f4014e4ae0551403d2988e3690139635ee18093f266e03cd89e5399fc28f9932c819bb7e4389b4dd82cf095869c79ff22a5a5ff8d9e4d80c9edaa149e233b4607fb9e3b3b5dd84edc59dad532c580ddbdd39253f1fc88a4e57464d5cb7f6b0b9dc0ca3b594ad1928c94307504587b72c8d6773875c719425ceae674a5abab3039c1542ab3db785b111a76886c1cd0f64073cecf37e1c459ed0540191637483f4df0cfc4493e6f4667779674faf89abbb154f82228c01b1d247b7aaec59de39eae270387929bff70cea6787f36bfa190f4d729d2e766d3813f8f4263edb3df9255bdcffde02a5fd27405913d1fc9a7dbf3bc43d930e8e5a9b6e6ea7ae09a2a1acf6708901d463fec3c17be648f34bd44baee249aab5cbd47739b66f80ecd35b9e23b0cdf3ff4b1727764ccee5e1d8a6f0eeb007b870b60752fc71019095fdf3de68c30792c292a6be7f5adf5eb5dee6e265fcab75477084e49b8f52a6c39f92b002fd47906897ccc81434e5244dba5a71aaadfc671f76c738220ab561496029f5ca2fa1fecf9943a3ae3574a5f9e09b8ec8a9596f9c0d0a07366bef19df394339e9ce356c2039c6fd31d78b4675fb400804eccbe586e35852530c927b36f6a9b43d03b7dd164768261eb8bb44c51444c6dd597ecdb32013494f9c00ca5129d564c6975ea6b1275feb3913d61647ac69731d80fca076dcac8032e5b5adc87b33b3b7437343167715d4f0a7d7d8baface7c65090439512fab486a7ad81708136e2165a9f2cab63eb4ac76e0fcc2c6f57a66ac1a36ccff0fe4c39d9f7c9957d81371b7265d04798f1761c24bcfd6c1df00b04d042a929724cc6e68448be82d65b785316dc5b95d5c05498eb9f101d12a377e5cf3c453004f2cc8f581b69ddabbd42e945e5d0db1fb3838e9d3a624cd48d984296a3e455f18429e6685a67446c516e20f0209561eca2f2ae7e282a6ecfd49155e7ce43851802b5b65ab6de430acdc690e57a05ffcff099a32e4d9f9cd8d8e4ae078f9e03a3c025d1d7e9b37d9767e4594d1185a39d5fe029872b628511060845f28bb71254d10cf38f896922684753de99b941af1002223353c5f4e3f2510d43c645c66044aadce99d86f1bf313a0e049a8542aa2360669f96087a439ac49d6ec11d70fdc5f66809e74b85cd3a31fa7e2cd8cce7bbe190cdfda7117308d0b3d92c23d4eb2d39045643398b0336e91bf3b89d734b33f07d99c9d9ad7379cae5976bb4494e518ce87de4ac7ee31cf90753fe5cebfd33634cb90d82677057162878e217d06f7d7e257b8f1250a1392c98bdae85bdf6ac9baca542ec46df3dc366b4fb23fdea94fe54bf09434cff9b00d86cfe904aab55aea538cb26ea5ac6d99e804e15d32c2310ae54fe28d7dce187c00dcfafecba1739b64576760c2dbccab019fd021af55fa5d2b23fc02473d9ebcc39dfd92e8f4b3e0970e4c20894f65b73d75f0edf49125656368f1e7bc5025bee3adaeac8551095e6ae41afad0c4743c42f36382ed2e7aeec1f910907ed2712da1666497fe104c64938271ce572aac888e5fa3676832965ba58354eae9c056207b8e31f422f75d024db3a87faec49a7e0ef567b0ffb5f4dca48e26dd8014b99b549f98f816d7fef2472a74ace49396164aee42492ebd3836a6222872bd9dc31daca83e6b9bffe0195b3dd736dc6bdc5a131e398e0ee4fcd84a5096f1a9acfd2cd68f4daf0cef0e656789e422a3a72bf678ca5217c589a4f2fe7f0e1ffd2f40a176e62b611145dfbf171368c505e1e1f4166f18586787eb843e558998884c1b29251737cebd68ab9e918b1dfc4fa1657c8c668f0c28ed97251fba558510c24b56568dd7fab9ffa8b95d78c5a437ad0ab1d4a85ffdefcc86a37a2d8a4db8d9024bfe028c23be8db3d348de227db6a0182b37171f2d727afcc3e7f794c0e67d5ecd58d37e7deb68020a9a6c9a42b14a1198b9d8d97a4b4255f8ef1a648b011f71373a866ef29089e3d3ba1a42fde59a6df547fdb9c18a97f3182257ad693ce9ae40131045327a3f5ebdff6f22d6b35da02694904936f31cd1d4ccfbaacedf4c9e1f2e4e88db8e1c0ae6ed9812569436a758879c17926c50277db6b7fd6c9cc84307918afdab08f4a464d4a61b7a9245a3e339e81711817aa92d375ad1700a0d8b28d1aa025e9469eb1b00db3f3fc8c195e6df8f4b264011526797d6c29bd53a2e14db91bf2c6f226eb25133f2fc72ead1e014be65f72b717346fec4713dbdcc7ce5cb061600ea4bccab567d14731f079890bd2b4a56e091e84453f18870920c837f3ae2d192f667e1b67d9859f3387c861aa10a6396a84672df66777e29d4bbcf0bc12f13aa1d60deb318a16afd6fd9a727ee996a96a07ea91283d9f26f217b9a1fcc1057f919595c9d4333a637e574bc9aef038e36ec01ab69effd15ce7f81ccc0848acb8f29aeddb2a1dd85ff13f9da1f4e5dcc9998b67581b236bb0b2c7b3cca6734ed9f49f152c48d5b54ad483502b8938f9ef135bfb0eade99878864c169b488959711da27efd975d1d9cff49e41f5af62f929f745084c46ff8a11b121a4233cad80f3feb806c1803fbe225dd69a45adf675789b9aed4b6fd7a61328758c1f8662f28a79042de2cef1855e1b8633885aebd55f56ef5ecadba732b9abc728184122b24b39332d1f3fc49141607b48e6eb21a23d9c5a62a34688357928572571c496e4822010ddb03e127c6c3727deb5d17f4aa0dae23d26da11dac43aeba8c62716a49d31746c56c2cc7702888e323d81ef63143326a241e13d495ced8b4bb88012b1953c3eb68c17fec4215e911a86e6d5a971ca7d4a2189ddbf41b06c5f6146b1d75bba080fd69582d7164c2b6c44b97f0b0cdf0670b15bc93be95b655f75edae1f71ebf0ff87dc46f7a1985b0d0de142b3f0725a47462e0c80564708c87c678a8cc0ffd9c2046b176440c68ac9128053eb8899a09ec19edafe28f2d7875afe0fda7008b2de3e125fe4f299eb2baab4c1f82fa953723666d5191970ff0d2b223226214335263138870f5c70bd7a61ca9d15ddcb980b8967e8cb7d9cdcac24180f094b104955b95b944b64c4e8a7ed5545b295d5ffc0c4eddd5f5c55d70ec8efa55886ceb1f17b7c1a9bbe9d3f5ea155432ba8c18ad16d4bc6cef1e311d0f7088971637c08aff695209fb1452d90b821f556cbcc28a22b25ea0fa0c54ebf674049838c35c44fad218e261dd3973dcb74c66da2ad2f1544608547adf6a0d540537c35d92f66ac04b91afa5bf69818f0a9d122ee5ae820974fb28a154a75adfb9ee3f971378a5fc17bcd2cd85e3c935b3d4906445dcaff35c34d2e7a21d639ab740f375c97f8b00713ac68e91c4389336573ea9fab18706c225499605829ef5a7c391b8f09143aa0cd5c60cb1dcc8580e59c33ec2da355b666322efce956f12aed075931bb143cabc2f61c7c7118a94c7f14fdb80d4cc52b5947a360c6c6b9192bcea4945d4260767592c3f94f8d30b822971d0e255abc42198ed12a2661a00783d6a2798d9e814c208c234d026642a55983906108617ab97ecaf2c35a54cce9b51c92b98fe566282f8c8f6393edb5bf8fec7260db15e51284a3216f50f6315f48260114a309fe9a9d438eb95d7ca97543f861969a1f0d5526283cd275d458f8b61cec46cdd3968ec0154796e780f3674d91d5e3f3dc6d377db9da337b12daf519adbf9106863c6fed35dac38ec765555d5990bc7480d24d17b6a5ebe321be976b4b4097bb7959cb8642b4a4946ce7e79630facc35241074c35416d1d801ef3e7acaed0b377e58e8911e6e3e0c087c292533aba3b747c5943f9623e1ed75893d5907ff344c49808b6033fc84d8e965c862a8c8438f152e10db3cd1dadb670528f6b8c456b8224efbc9431335e4a1a5f4b8ac1c059166a5aa322c90367c626a3b03dc5cbf29e7473ae7e1b6e9de16bf9f1e68f463a9675fb13049fdbb6c11e65e9627c58ca35d273569c420a882349dad9e0aa2c708d7950b75ee2afebb5befdb7169967949f9020f815a03bcbcbec81c62e2bbd861d70a76e10cdb86a462d66bda589ff957c25a43f39ba81e46b6c16bb6465251ad4ef33db6a6291a239d6beba54397fd033b78c60d215132a74f006706504a5c0946edd0e3c941da997eb518601a2b691f4b09f0bd2c1f407efd51ffa978fb9730e8347dc06d24f91cf243935d35f97da450e51852803dd8d58d728138c1d1a4515a83462228b551812746e20e978c347149494dc5d2075880e2cecea634969acfcb58daa87b69df0b1932c064e1b8cf2b2403ade7cc9574f6b4ef028c386cb22eb66c7a92e2304c10e3752118f72177075bce1bc83fa71e06da7051f17327a71e72e90dd22682d307a68b172ce1a48c2ee5978ecc70d3e4196072a5112b5ffc4872b73450350484aef6903919704709dd8e77ce61c16ce7f7596ee1410ce010f61bdd3efb1f17286f4f0c227d374da91fad231934bdb92598fdd8a974a2f9ca3f8a2065e55a0c1156dc9682ad70a02354a5ee1f0484f9d6cb17dccaaf20e2381a93215e858b418ffb0b61a017310716f0dcb1e5eda037d6cb271b3a705c8ae8e5d554274fc51eac04d1aca40c5969c3be74362bedf1e29dfe1f04be1fd8de22c36e7ff2873859532ed1b999b3660523f1cde147b9392d58d25b3904becfcc8e16c74fe9f5c5c3487a35163c24dc5242a592a48de4d9ea9c5cdb326ab26c3c75660c54025c4de0a1505ebe36ce7df270fc974a5d16962a09c28050c224443cb89de5bea3035d90d75048aff448b6f2c964925f72c396c991c380bb32df982a9bca9f98ad590a5ffa2c8ec5d54bde525c90fb34b6d0e33b495f66f59efa972515d8b2d23801c2c2af431c036f7e4aec0204f00115d2fafad2577cc8035dd360b940f808bd4bd4da546633c9b631616f1d9acef29b9c58b9fc48f484e1327827dd964dd7f21452cdbacad56e76211e3ce49e596e595394738d06a1442e06c400e2e1dc82db909771a27cce4db91f6cd66387a54c367c29488470f308a8f9f4484eb19ab920bf5bce51cbc65b8f392f0729be8b97b3a0b8538d1802978157284973d78603f0221b3464d36baade21b7b88f096ddfdb655a5962c2924e717cd09733faeb9b57299a76c5ae3d36104ba9554ea2d13c8f88f55ea66f8c4968e12d888fa41f05055e14d81a5a71276d7ee835d2ba16b752e1b46fc12e54b95818e9d3c71c88f741d231b52b6956c75d872dff6a813c285364b6cba135e0326b75d132df0419940c75ea164d21a55830a0695900c3ff33025941f7016d809ea022e43c93c4f63a4e5feb329cf6911954530cd8738930bb1d27c8d19b9fb1029d478e8947d7f93797f977dff8887ca6fbcdf15a957bf1f2d98824b78aa1afb1a53cf684c3d4ab0e65da40dcef424d7c2a46fdca332351b275661f69dbd573748bd2db7d225e5b0a21a4ad41c81b0e153728ff0d1ef82a01c59859775df17be50bcb4317aa77b13effdbccd4c0d40593407af0ff538f70afb7f751a589b30e281f4f449b0108eb141028e41f8986bb5bf226feb3e625608fb177d2cc6e7106ac7e0e6e9b9f8ce96ad394cb254bab625c7d920d252ae53a4f28d81c734593aa9f2697b4fb6e99edfa60cd2f4f9319dc0a8c8fc74b80208fbea7ff7a80c8e4ddfe2b7bf3344c149c60827ab37608cd24babd2c0dab95982484a2a6c09050e48dd4052664a7452d3e2cd17949c2465e78a00d02a202d3bfdfd0297dac36834c89d610b65d017707f2ab27b70db8c8fd717b74134610cb81578e22c67c33a33f0164ed983c629a3199f2f48cf7e1500da37c1cab6e170c96ab95839b7a831de1613c471604b6a46369fdf55ae8930c76ed23830ab1b342febae636e31e5c38d15a5672b877dcc9682776032c6c7ee9b9e25457405a474ff2ca23c458b0b692086a1112a8d533c01da08dc9badb95dccee1fb1bb8b5f4614fef4bae1a576251304e35afc40d6dbd72a901cf15eeb6b2e294f004987b0bc763594d2f28610255a0a5ea458e1834f50c71acb1b48e02348b01eaa738c2af9d4c3518470e0c69a61ffe3bdbb48ad350b7e282b39d8c098916cac31c9f00f0e722f53ef7e4e638dd916cd86214551443cd1a5ba8247ac849c82cf5e99c5987f5651e4b5c13ef952830da60863e251745b0294c3b5c5bb05298fcd7863dd21634d8dd858338619847f4d915bc3bfe60ce0b1e05f35daf92f756ea511736dd9668cafc62196b28d2b85985f28720450af25e590a8147aeef81a122030e500df7d014575c73cc29571b3871af2301e0ffead333e2bfe0c3e70c6939560ed4051aec783b3a29d69db8a76144c301ed88a1889fbbe3aea86c46aa2767a6475e6bf776f9e789d0f1d48d104c5d3f948ea6dc7802a211cc29cd9751872a54ed3b225116536703ab4d57ad44ea3f1e3085db5ae1d1b93d8670fac0fce2fa947934b27e4add2eafc85162ec69c96e1034d68e2adbfd4c41b6e9fd3c9a3891d0f6c7cf661cc0938c4d27eabac4e5dfd92a0fe61beaa8590f444b33f8e910ced9eb92f15503f57be4e90391e0907a59d7056403a1e5dbb89ab00b336e1641fa7e257fb39a5b1f18fe1093e4423258c4eb0991cfe0339c146ba536f0948108739b717b5ff9cd87bc3b12706773895bb905bb96f0eac66bd5e65ac42c358015a9f5c4b21917cba4e9fb5d559ad37260be55ee2b33c40d9693ab2d7d2a71a07c5d31bb93c4fd8e2e20ccf9310a2b5e1791275b65b0867d77c91eab9e2f769c1f6be728dbf59a931db6b6095ea58356b6caee3c90670880fff06edad4e1dd328991da198bf497ca6b0e438437c93ff11e20b1efe43da8b0ec3505c8332f4d9df11600b04d8fda704d8d20458fbff8d008f5899949cde26c02dee7cfaf7c86f0fd6f7e9ff25e20bba828cfce95f25bca8fefa41ca3ba99a7af9e5339525e47476f5a6a581929a6ccc33c9895064b70b362213bd6a54a681d48f976418012d1460da3781570c385b576ca762ffdb03f14d8ccb7b18832307354e501d3dd4385c2ea18db2d706a3c64565c6759d63f8d555c654873a2c99407015a0e956b53ec2007c1f04d5aea0d928650b21c88fa725cf60f933b6376a254c8b1c4fbbae5dd9a89d262deb3c74f164d3f91523c09deadb5d10708c6a3352b2aa60c9dcd8b25f32de21be49cf8d8ae47a787ef75bbd941824d6ec96c00038a4aa867dd25c297bc87ea52a0d72a82dbebed18f252be5ccd024aaab1696f086b75e11a1a10e8220462c89907515e92e8d16ab0fab70f33ddb400185428165c908a4a83e2234995ee5ea23444daf46a1e792c2d4fd747f1fd143e0e9639bca7695416ef154fce4ecb442eb5282cedb977fdd99aedf1966012dfc686b26a6f95243d518a74dea3d257b4039b5f4b6702f399911d2f2b17aad861fd519bdb5800e153519c02c2297dc305095367ceb8c29a5b1be092335cf0ba179389b667c6d8b3965c36f95259f3b238bd73ee998f5cac24636f6cb0b97a213d5af2c03766954167f7922e3171f749f8edff5006fd51197d870f121857035c38d35f6c7a11f11f727088ea19846e702af7b2baec2dd2c5b955047a37181c091d3ecea441886c330c694f827964f4263e13366730b17040f6d46b234edcb385de1d6e5b6c741eabe796ba7704737ee3e5a602a57a781d4940c6ed727d1b0ef83f665f3fae236685d6e06a46ab72f8b7dfed875c03faff927dbfeef774f1736aedc19fbf394178866937d7c284bed7645d8e8f193b56c9ac0e211e7d654bed3e5afaa15bae097f74529714ee9ef4d22e8dbe3891f895de772dbddddd0332e7433e0e8124a4f0139f085237a7cb450486aeecb92935474e0ca626eabf6ac1f65f3730bb4be7e33743a7d04622212d4daa1f1aaf68b1c1626c6494012b309b91c1690695644111f000223486f537f3f765bf2c84e6ceae3396121b23fe7c24db59e29e7b8c246a2370639d35dd3b84c8f301dafc93cb8161c5709623e78055e76ea2bcfa65823f6b02dacba40793220b44a25221ae998a77fe1ccf82c1522a3043e812d36cfdb8bd2b5f1ec2a4c5f6cdd2ab555d07dc0548d84a8fc962dcac7ef1feb482daa53ce4e5f59d70aa1ada0b06823ad627e6d85fe35905ae66daa6ab7e954915227707d3e6427471c005c85953b5867045d8fcdf303e4e1f890d713a900eb26713c38a9284b7ab78c303ec9e8811ed55530872d0eea5bd6f92c1badafd4dc570e2ed2839afd7e106cc9bcf00d6675a91fc29beee1977ed214cb9040d24299d27f4be1e2303047c56f87a5cf2979761ecafcb6a6039e95828976ed5b98e431721d3dbcf0e72910695cb2db72a27b6fa71c2402f2de15b2169cca225296d349d0c8a9ff745d7a41b4e050b7e1fa2a67d2df267823181d90e7bb69429443124905c950eddae0bd09229884edb565d6b17220d1d1e6654dcc5429e5f477ee9ec6e4f65b48ad4bded8ce151d2751c00bbbf539ed50cabdf2e2f23c18bcfc3bced6b61c41db9f65f827427fe82aa46571ea71b6de06e5fcdeeab400cda51d13579b897247881d6aee7ba529d8e91f471394a8de7049935e139529b658d3fd3af7ecc051f491bc9f7ff9ecd81ae89cff6d674795b7d21167c7e103eb4602c377bd5cf6d040051dae1f54c3f22c46ec5fc5f2a0c6652f08bee42f14cfb6386767aa38707d365052a881da4e19b18028b5f22e6a06d51ba200c5ecc61b24511e3cde520f27770a188992e15bed86d13183ce092aae5503bb5c7100e425fdb25806bc5989795d0930537d0b5223c0728b5f9cddf85b0889f6683bd45562ea8d0ce83cc205e139d9f1ff7ba802639432c4663a8522f775dfdb9974ceb00256019c039f8adb7688722a3b145881dc3087e6c7bf04176fff09d98b7531f5f1fd258094b67717d3288892dfb8be4305a14f288a32da4736a2a25760535e91ed6c4b000748e52bff681ec29bb41e78427a13a10f07468e93c0d2041846154e8f6f036cb304417ae6d6be28a81a9b3d8b320bfc1669336e5dabfec78064620a5b4e90ccc3f3fdd0d820b11bd51751dbaa8032422797b89b483db89399f1bece2c248657715f46514626a0b6db5699076e5484f4bf39a31d14390569fd92b77a9b3bb7820ec01f869fdcea37a34f7279e9fdce7bcc348ad63677178d30081af45874fa83cbdb1bb43643591a7d7249ecb314643dff305b3706ceae6dd7323902b64c68d0931d2b9bfaf8c52108904f1546e2fcfd3d92a3442db8a4a1bcddd90547679178f820dff4d9d198b324dca2fd8dbb8fb0a886158689034ad0479b2dcc939d848d81e380cd8bf03c4a98c272b9db9e4324466196cbbd500d633a101ae17f93b33d06c1b83369762cef1a45c0d5512c2ea5c07987286ef2676178995361eaf049b1b0601afd0fb1b03212a63c4ee3712f21bfedf243dcabf4398f23badc0b5d5f30f7da9efe3dee0596a3becedc6b878d5941631fe05e60842825bcbc7d837bedefb042b29e3c35cb4fa8e5283ce4935c666e657fa32c169d13d1e915a358deea8f098ca1f918beb2172eb7b34a22de56b368debec1c717792cc16376864e1745ef61d294bc8785d9245c83b30fe077b19d4a801c5077a6666d2469e49d9eb0ac90ecffc3c6d355fc209b36e8ce403c7c9b4dcb292f4fe7b2e91945a9cd5e7de1e6ffcedc9953c3201dd660ef3bbda38b768dca14d539c0a704c5e2ad373d1dfd0d3d5658de858227393874cbfeb0057891ac1f9f4e605f5b7099f5c8700633da0a4eaaac4ade53d07d6270c201ba420dc7c3899105043c87ba8083d4c43962e1c4a8662464366b81b04a330a26acd0eccffa49c9db9b5ded624d9bad01ac4b6643cc2512e09e67d7a52fd6a02588a9e2cc8b1c9f036120068e2992515c55573da4dbf5b3234b5bfed061d8796f519e606dd02831ad356b10e56c1279d6ddd9455a50ba13a0fbcf467a7de5a61069fa9bfd7672655f41cd6c987fe4f711b531ddf67097cebe7e03d08489036055a2e4d728fe73d10fee96df872483ddf222a6ff7e3e7d4f0a3a1aa57d6d376865184a8da98829058101457f97c9dc14223ef8c429ea994c9b09bb2745e75e219817659b4f085215c4a4e6cc2af22b3ae88bb7920fadb666d3d6da7aa1b2e72d5b149d6e5da65432f02d721ec889d54d7a48bf360606bdf78d69c4d9175e5b2907260fdf83e4958e7714474019ee83c90ef6b9dd0dd488d3492172af40f06d5e5112852f8f3c37f7192b3a23d35569af98d26b3b4e9a44804e1dde40c3d6220ac5ed05411d0e7f4968c58b0fd243c9f1e068f69af2da915142b045614325e64f322f0258d275bf152cecfaead23294fc644f6cbd80fe75719dd850fd53acb3a6210d9e2b26dd3604fcb176c07125b9a8fa9322747fb525ab19f11f8bb2351f77552492299d134d5e05870981425be4074b531ef056b58d0df929338e0736112e49b99845def9842defa52a0f5245c79d27895d763c6e3693c6f3bc3c19f29440632e17f803b935df9c82cf31f5edb194d0189fca750b93c0acb418b959d0423a07e474cc31b1523a0a01c62b6281c3b058bd7e9774ee83e07154578b2d1bf18374f310048f4bedee608720d4b23a57d01996ce5053911116d72ccb489d3e6440d4e9086e916b25b91494cd96d47f8731a74dce8f41cbc3248358d22a316caebc2db9ec8924bc731b939b0f90158f0919a44bcaef9875d0e07eff86d7f597a6b921037bfb087219d28b16affc417afedbe1c9259cdbb4a992e5352d3a3c9bdd7f93d7c826cce308d674ab39420f49404c65e608fadfc6a18225e1b4d77b7fcda13273e33328feccbe746da5bb09cea7e1e2e6ef894ef3b22d0d6c1dbe4b3be7a4451c5d9a12a3f27716eecb90a6365a52771d1013f696f4b3577defd44197ef84c17f87ea9dd8ddc9c069132feacb3d14faa7dd2ee626e551ec89b76cba0118c0e6e3de72b2c2b8ee5ac3b629170ccc38739350a0466c9e970f2e5b0ab66bb8672d1ed5556713aeca96c0c0766cb3dbbb0d1e5e280f2c601c0b8027ecd6638cc048764c4a7ff78dbef37511398eca5b82c09a63c3e9cba9c1e4bdfdee744954ab52a3ef744df871a5d1b75daca28d5aa3ef7456fcd9b552df74ba174427764a8db1f8277f897a5e4e8d9166596c6d26486181125f63e930def16e132d0e93ba42225b719d176483537b7daff8309787266b5412a20b5d23203f06c12aac2f89de59440ccc9fbafcac35b2b8f0514674b58234024e39d6eb457c7f8a9d3afc4e627f7ac11980528938a30c764ba9e96a0d47a1b3a3f74f0af38a62cc9f74137b68f7b98f2be12656b0a0cec16f60419b39b0a0b10f0bca5119d0f3e89e2af5a544fd4d3e38a894296e001cd4548a056f132ead5ace8bab94d7361e3aa86e2e3b24f3b4244c7731aacf43e09041ade85e7a27a2d2d56ea918d4a5e2e4d1e8d572cb54a911d2215a5911a57e83e3dbd1a31f7f79537724e7f4984b5d493036e0424ad70c17c25fa9f008eacc35e47cd069b8fc2fe4288a2dbe96b3ee44d838cfd0c93a9a70575932fe256dabf6ccb129bfd91531b4946b14c45947bf3ff4928c8182f26cd29051633afd73124a3d72668d3fb2fd7df4fa6b66f297d97a40baa0823663e7381d6ee963dbcc94f6dc2c014786e11de3b423a2c40ef242be6871d241786860beb9c94ed8561551fdc074113cd265b619934a409dba0b72dea74ecf5d69c64ea12bd51639ae729bdce419e7dc9815cb206a4524dd225aa4510c6dc4fce8e098f210a1c316082edfb3867073acc0f6c9ffdf4a45f2890866bb44e157aa8864154463d6321db5cb0059d7e96791416d1b53c73447b605628493081a1354ba1f55a708353fff139f937c01899477f4935b048db9d2aaca9b108e2a2cd4e1b31eb1c9b65cfdfa0b3dd3d7bd2c29ac35290c106bdec2c153de9c49f4d86f6e0c7221777db7d152ed66a35056d9645e1e781c71f7e4db90a4d8fbce5a167ca6e7a040cbc4809d9a8f6a81c91db1c38a9ecfbd6f3a7d6afb9dced6d705f77e9e5975f60ca706d8b005b0f32655be9f602a9df1f81747a3d08e4bda3cb60ccb8e8a9c31bd82c851fd4b298f0d0fa0e65d7e810723b6a8bff2eeda6b6fdf35f3e17fcd06cf75279c01253ef1f94ca5217a6f6cf90302e6bf4c68bcbd1880adf384eef776b163c7aacc88f13eb76602223003298d873ce51364924ca126c87df96dcfd7f2fac6279798b9d43cb169265674d44ea8076f4825769c4a7d0151ce5a8818cb2b33506e3815d41b4d1f45b82daad72d59c7bbcaeb3294ac483faaadabeaa930a963fb9c8be194df66706e6ac3a2950bf3ea3981b8a5a19f7c111d86a1a1980df578124a3ec634bfbac2f306d7db3ad50a9a88f7d926503dfd194c3b8eba4a06fd835da11c603f0ac5235a424c9de0dcd4ec07e8a06c91e6f270524af0c0aca0fe8b5259c7c82ea319da2b6870fb8cfb9704d82a6e545949191b48a61cff70449988a9e48cf153aaa6d0aded526d6f235fee733a92d725f274e6bd672e9e19d5fb2f927a917d315dc1f79ea1cd584724651d2c1cdeb5b1e0c1119228de9d0316ff2074eb096d0f16d16e5cbf4e75882a57876a4d59408a71eaac90d11927e1df7f25dd481b7872278d7fd8ed8a02aa593269efc2f1084862e06a629e31ce9781d471ea064ebda69499a4ec6f5af6c356c579a5a06ee881f49c41e6250755ca830265dc67a7260aaab57504683a012dd4fd915a52d63c26afd2a5b3efd35d34b2e1a8d15e19f8bde928fa529ea10df7f2d49bc4a58e7b1707b8a5ab0df6d0a1c66bb0079d1d5c3a432480bbb88d6ddf7977de008d363224ec710b23ffc3192e9103b538bc780ca2f2eb4eaa2a15b89b4d2e1b2b4284c9efeeaab0e9d1561dac6c6af6a3d4c5d8b27d26efc0b3444fd0c3e2913f2ef97c9284365efe6591b1d3eb8cebd42f00c1aa8844715408eac59b814461cb633dc92a1b5538300bfa9744078f6f9910a882e09a738a2980671b969d8a41f3f6259bf02497b47dc9821053d762cb975b63c853d070bcefb451c099cf941282a4a0eaa5ef5240d8f9777b3649aeafa0cdc5e409f7ffb0c06b3d69b2dd6bdcec934f812878841494c5570ef4aee0e8aea010f757b94b24da757a52984829bc2accee131423873e5c724f336803b82ad1002dc4b354758809324de464ade359f9f2146ca758360934bd207854d90c1f3a16a3f6eb0935815bba02dedb8764e49f918de6b573466e59a0aaec9d33b289a7da776f7e307360bed7c30f9d9ed2889cdbac5cbcd3f2fbadd0e67ca795ccb9fa912997437604910a82054f7d0b5caebe706e9a8f1012003e323cbd7f00230ef1886feedc6f7a0f43446a2d943b410eeb2234c074c751350dfc3e3dd8e36fff60b77c42cc901a7f9836ff41eff5c1dea66e470961b3a9c9c2a8eacbff68b208e85dc76b0e71ba193788ca24420c71fb9365e9882e91e2044a12980d59126835434f1240d95d60d74b35e0b4c3d09491ea9880f137507299e335b9e82e1bf5e2106d3918fd4dd2c5e9441f86b03025b16eab4f4c1de57bc1dbabaf561e69a34f947dc8a6aa1644a86aec764a8b1dfe332c3be3c1791404f3482a1173e80b808e5f08058edcf39bbe2380b4b46e861e8a1020ab897c20e7992942e38b73c083405293a9afa922aae74596f582ff5f216679edd01a01722d5e3db2dd6313cbbb439cda23fcef8b2ca4caf1de4b601242eddb2d8e5ee3ed38d6784693dab53c6f4cd3ca0685d8f10d7c7485813e2d19eee7db1a651220a3f3975f44b23b2d073aae500eda7565e0496a787d7fe8d01a2e97bdb7de97aee0f19f4ae25392daee00e9f5c4becb18a76e6b73a30535a6aa76c51c942a4bd70d63bd432db9ee5beab8b16df936145abbb55a3b2fb1011682a66321b0700f1217ec39e1f4aef91b4d7ff78aca08e74c1ec726441557dd7fd0ea7e365b533e5bac38752524b05932800bed6b47f03168626cfc1b35f9b6bf0ab7413038943248a2e7a560c27b5d441c565ce47ab2be09c115a4e29d8208763189b88af02e5cb638aaaf396164d54b3d52780718b8021e511db7fc1c04ab508848526dcb894170eadbd9609ba10cc9ba2b90bee78146cb14aff8c49a847a9536a1c01a134a07420524fb52703aca2535764effe42a00b3d071c6c01950e2d3791e71a100a9db6dca44cc6fb852c00936f5235c2a822c8e300984004c1002a05fa72a130ee87f94bc9e725fa71e09e8f9786b2b01dd1fb860655f61dc675c950668bebebabc902ad7037762375d49aae82352e0db0c45b24a4baa16f5c455adfac33a975118d551d7744207e0f389ffa7fb64ade2e7fab8df4bef13706bfdca74a2afdcdf6b3cbfa9a3181cda6f6dd8147bdc208c19d7571c5f760f6750af4aaf67dcfa3d9c1e191331b9b89edc4dc0c4810a7ff589ae47eb3e3226efe0070ccc3da900b00bd7a80b809db527e25b87990df6473623ed503e75d791a9be62771e0c8d186a2164e7e601942ab115fb244a490db39720b7a4b2835a8245269d97658259c759473e18362648286affb9e8059df9ab0e8588268494d43f78db443b9025be3de5effca9f4a3df4d656c76b8d62620c128088e44db87eb3c70835e09ce0a33821eb9c579b73a2c60cf8c686baa7a88a1e284a0507722d57928f6e64a95516f76de66e7447caf704715918de94b4f41f0477ee7c0c28c496abe3375dd79613fc147cc6aedfdbc95138c6638434a65c2192ab12adc288ce8a89e9c23a4003d761de0cb70941fe926b1b3029a2d58d60285f1d33add59bc378068246cc02f24352738af055f3a2e548f65395ae3c8ba95c4cc67fb2419ea0576fb46d53f7e077d708705ee3b81874e70a771c9e2499149fcce0bd8938493f9e3f01103461bb7fc7b038e70199533d4b5aa6dc26591d7d7ce84cbef0ebd73c2d5e39aeb8471dc5613571bb82ab1c61026d8e95721feb2084f1c288070173a38be05172abf80f6e4a364d188a3dac9f46c1d594d5220745b2b145214d217b1b3d92d3e90f2c6b97b7bb21d1891608e3d8dc811098739b7a785867d8be33996d157feb6631bf694f40df1e756dadcc2c8d4f8ea4b984fb4f873711f744a7f18dc208a8761709615705d210f33913f67b01a0f9cb51d4378dba318d43c3ca033a5b66461d0cf22d2c3f306abe7b09761f73d2b808e552068373f9c02e72b0dad3d40b9fd6bb3fce931bcf6e2ee239f62fa50d2be4a052d34b869d0332fd523b6848416e51f25427c72bca5af13bbdbfbb0323ab8d0543738a989648f6d595da1c286ea0c3f6d1cfd4f623fa591f46825cf1f72c5bcc7fcb082933a4dd265f22b3e09b5d865077ca974c3894f90096fdde90d7b0fe5d284b08dc8e0c4d18f531b0929e1903d0620b372ce6db6d25c3f88d6c350625f764813a0a86390559c647cd719784ff8e4674ce92d5f64229171a4e34200c548f174e4e0be2cb2c1e1de419324e0b72b281d6c01e8f8725b97c4a35e1034c3bd57b63fcfd3dfa7a3af0fe3d0216c17afbd7e3d93fc964e529c05f96b409512dff2d98e3eea9849239996e0b59732fb79f2a794d8872c39a7be8cc2f65db69fd350635b7e70c2ce7da897173b71ac0d72c45e47966e3ab2b42dcd6e824a57a0a075e244119950d50d9b8861b5998178203972d9dd7d81bd7231c16b4dc2ddefd25a817556b339ac392abe23b03e5ff48233b08bed674bb6c0ac6d73d21bc2782b5bb8886adce5e5ce9459304d4918b434967eb4e564deb06bc8b92461ba6b5d7733705e3251bab5677d3c78b1912acc2b274257e29d565ce5135f5bbdb8e1b9aa1d276e0d8f1bce87b85cdb4a66042df2704723835bc51ffa4bf02a91b3447ea327163be8c8b107acb741312e3658c74f827ae1c1720c29cf2b09cb5c693c633432e5bd5235786fa3a598d0257673b96373f5084929313bb6a553051844e576116e6489c9c8318a8ab5b68096abf92d97e002a8fe7dcb8b96f2dccf5b6afa26a5d03a2f703c1d3ee0e7c006f63fca26614cd41e1355cd9f28f10d55df1b8eb2964adbb518b8ed30a2c2bbbd8511f5c0f013d3665fd95011f9b098126fab868509ccdc38ced9f4f254b1d2fb8bacb943768b07922f960fc623d2559110b8ccb627dc2bc71a1bf231888a7f14167b8ba1e6856851031aef0c049566566603e174c81e98587331f5276cd23c696c0a6a7fbae8d9d00be59dc08f33ce093f3a620970d53bfd611bc716d85dcc19d0c3cf96b7e09581c1da56f8664c740691a747a9fb94082263e7035a075ca7b3738f907f9cbeeeb2148056209e8fb485624d794e0a35774d8247936edd5335a96d3f47e5d0ac53cfbabdd4b20058c6de5cbcfcd59299a38c27aaa8f325545334692016e9149e2d74723f14c5afce97ecd354b8809f3e3ce5f7ce59ccd295bab3c219cb5406e763e13a739c190f5d3708eee2713ff3c072dcb70f509b0b78d965fd8af8bff9fc26ad61d589d221ebb51823b36f16dff145c88f0fb42da353fb0743361be8ccae31045870c37a2615c7e78a8882da21ca1b3272313f30fa7524eb99fb30474ff0e906031563c30ddce89f130bd819a3da2088ea2f0d7db837cf1cee3daeb308b3769eaba41fbc20e46a235e4d66e81c301bb0bf5a569580a0318787e41d44ce054b57059e1a7c181226dd192a3782ed6597c0da78099bc9b5b59cf23cd612be55e7ff0941376db1e9a44c43c815f7a6277242a32ab1af96c4dc2e3429a3de962b1c767c5cf0c5fa46b12e606f8ec764107eb20688c99876e486c599d21e383149a63407a0132416d0cc83f809f552641882cdb180c239452a78397152d6b010a642ea2088665c4e738a20e26a924935e04ffc45ec79cf758349ef0992e2c7d60179f96392015dcebe7792652b1ebc11e411580a6b84efd30b82df1d45f3881f7f39ccaf80b728d84fad3697aa68b799b6249a58ea810c937c1cb7040038d846e8442db9b9584641b08c64eafca17fe02f3b63e91a562e7da76b93b1af97f0e037f5220d6dc1989114d050aeb7c070909f8e4d4f59c9c6a13a52f78e8d0f8e8827d561f32890c28d6a66e50efb8c5b52ac3277ab88a7bf7f1a85359561a55e3333ee8a76cb7ea6fede89d665d84f4342f8ff8f4e4a4d900560d290494aa7e2fd498812ae81dfc22c1493735963ae72fdb16dfc9472b32fcbbd2a5298306779342df0b1e3e552a2a60eebb23f441947f19c67db297168ff7fccbd5777e24ad036fa83602d725ae74a6ab08c31c3e0ecb9f3786c32881c7efd595dcf53524be009fb7dcf77be7db13d2875aaaeaef81493f51a867b359eaccd368137b09d63f3a62bfa28b78f020618374133eba5c7ac28a04e8945c3d02eb8637b290835f54ed8edbe345237e7d5f3421ad075eb6b39c62d6dd2c88ccc25ede6b2acf1fc4dfc8854e7be497fe64d6743ac49dfd50962dfee6b3e4ecbb14fd0b8e25cba4a2d388d28c9f7060b27ea237e56a3432f3fcc48aab3e171754df8199b08852b2a068743241f9ad5cb8a3dc2f37e6ce3624bcf9ef756c579b86adc24165319f6eca0967b5dcec94678c347d4fe7dfa5fa9332a10e08b57cf1b5f2363c829058d4f1712d97f5b2d03a5f00ded54791ab78674af70e181a2e260c8e01940b1a0a5222c4bdae0db1fced80b6747cabedcf54c09b9845b8d02db9e3308c08c3614def15852fc697d21882203ff550cd07fcd5c2a2709c6c2edbbe71d45befc540227a1c019bc74f8412959a479042e3ce1998d037aedf856d2b5acc9a7aa4e3e4efcf162a2bccbac4131a94f51ed5e0faef80d05822839987d56ec8d148c02a4853261ce1a0c156f8c1210869e0e46225a9ef598e84661c8d17ceb870e60f8232cdaaff368aa67cf1b98c2e23abbf6bddb83a805af0a9f7b6673add103445e4b261a15086ae0f6ae9144fcd0f8a451c364b712cb8f21cfcc574268dbeb4cfc7c497cb0c1787b9b38a592031d9512034ddf9e3037769ea6e7b667e66f08f62e6986d517d2b682b0e82914d59492a382865817477091423cb1d7f46450bfb45c543256a734be98f313cdc24ca0109e33e7f574fd377c9317cb9a1aea860044565971d871dd141e30364c93cb063367f622a571c11fabade3723ad7925c53fce54b6dcf14ee196fcfd252fc645a143a5b924459af08ca26b29f6b17a325fdaaee5a0c6ee1a28495f5eba29a6dfcb47b69890abdea8fdb268499919f762ac44cd0f66046bcfcd619b1667ce74875377c7edda12a72937e378aab1ddfa47b396374602f3a245f3def03c02e8166d3b893c247924515ccd9633437614e2392d9ff8b2f634f2391e2c9f3b2bc449f44ec0b4d8a8cae9303ccb1e0ff8dafe3f9ccd711e59368e72e7b94a2254c5dd2014214e1cd4874b573803d6b769ff13c6c2309a997027aa32ea065da5a8987ffd2ebd411466fbb537e4d4846a8049a104db49c25c48169943edaf24c482b440e668edd055120918bce339630382f31c1d4efd207080eb7446cd8b8e9fe2aa7138ef87bb5c3d46c8afe1941a6e373335314b9efc39a58bf720e33beb29d5da56ea6bd91f6a3b6e161eedadde4f6dbaf9ef796fc360ab977c8553045ed5919f91ba5ad80820002f3e027e87850ee089a751dc898c3b223a8f16b558237d40809508dc3cb097baabe4c04c5cb56ba0493480374717ffbf5b22640f2d62e7ac386a1e5dbedbfbdde3cdc8dc6229845afec231e1c78ad1ad66ecfcf9efe6f24b62f89c6a12877b563d8270a687fb12cd5fd6f26e0cfcb72fcddfc5d78fd6a7535e3b29c2e2c4bc019f8527c4ab83dde220fab58a55f14fc8f8718ac9e08268f4f62e78c274fc64a298462cdf570a78e93b193b3563d838b0134d3af0c5227a37261504747bea2043ca74ee749dea44e57cde38c9e1919279aa6ec1a8e6779a430e7aad75f7c64ec3a85146c93908f7c3c9a544ec5fc2e3e9066d1a5e8f05d3b67335ea3598926471c1439d6938882c35a711581d17b6c465e281a748e09a9b49e3a6698294e959c894faf4c34b8765c6f299784339b5e8033cb11ef2f5ad70ca862f41eaf6cc59504ec87a8b52c2f029a9528214f0868a6ad4e0868367e3efbb2bb2d26c764676d2bae30e17eee7c50fa7481a1f3f0489ad5a73a929976c7c5c8146fa20482b656409aedc10ae77b06b16d708cbd026567006829e6f42d19dc622f8b1481ef1727e0421be63fdb86d2312f9a3ba3d415cd20496c7ce704bea462fdb4e399e09cda75d7f37d5dfde1e47cf5b589a82897da0ed5ec504de2033b992a6eef4677ffda60149733ba73dd5aa9b81c26b31ceb1765590d22b48ccaaeb9b6677fa743732622d2bf945db6cff7dee6052816a81e262203f7bd020329edb92d9c8f10dd3421b4d90533730adbff250f4dd2c83b738dbc15e8dc8fa968b494c27339832b56d6555d728c37098ca37c2a121c71fb2e37fdc2f1c324fcdfa0c0d0638ac8c4f95924736c3ed528724196961d976b6914ed805e4ecda787b4c6dc65fb6f12f3888a64a455ca18717a8d46b4811cdc889660a439be4cb0657abfe2db1c93772168f428f1b814c223700cb89b5e3f5e42c7dd40f002466b28c44d065fcb3b052d5a919f5146c7f7f2032291d430045ab41863a05119798eac714c3e65e52a7d26c367e6a7c433235a3d77fb18cea3451b19573d22f566c4ee98cecec4d852727eb35dc18c8c02a026f4efef8ee9c7dcd82cd225e97a7d8009b73e01a46dc8d800f77a3a373dce6f8da47a37b336ca6f1d1f6fdc0da1f9a93585170cc42c2226b9388335722abb69ac767e35ebf58baf5ecc7afdcb77f47734ed014294cfddbbcc2255e4dddfa7917a6571946f8c9a5aa26c56c2e5d08a413fcd3236a0d465c895a6da26e32ccc67cf7bdd2381407347665b40f7c93186cd51d22c9f35a2d4b769302efd694e3fb381d72cff9c1713c0640ec72538e9ee63e5d69271522e694f4e06c066c8690b526ee71e478fc6f93dc7ec35f295c44699e8a84f02d4d6abc910cd723299f64d4cc44f9a0a45d3025846d9df0e20709428c716c74df0c8c8bf2134a6b747531319c5efb5924baae18951513c2b55ae1349a0cad3732b5177eb3e438d59c9d312395768d08a43f2b525db6d21a5216e96f34eb8d8a6902256955b394f94abcb495a1b92afc1701597149af85af131485855378e712c052c0c013295c864a214335362e285ce9793107bef798f698c5d3b6f66fe19813cdd6bd8ad3c95fac87f841d7e4cc10eef2f06342b34e37f831c5e39b27f4265f5a2c77aff53c8e1774bb4dfd614924a5b57809144557bbb48adf7ecf6efa22f989031232443e52b6f42e400880d3deaadb5d3957a28925c34ab8a1353762bc1863bd771987ec2dec9b3ceb406f7579fc0f0e434798a3baac7c840c5712715a73670bd429a52bfc7872b3390bb1e8aac17faee98f3277c6453d275e97b26070d74c406e95a9ce7db4e18d970edc7b6d1052bfbe5ce1d3adad09ac8cf1b0705abaff6557b418db584079679af85d749908af6669d280f84d0b0b554ad18364788ae1e62d1113d3d5370c8a8e220a62ae4e08a8e4faea546c7679931b3ba85cd554ba6eefefbe85c738182e550061ebc6a812d67b295673a08707899622663e238e268d29e5586b963b47822b0ef9194d4b88bcd13e9140152685dc48410c242b869bb7de3b15dbc613e5c8912be3bef7c74497b9498d907ea478a287b37e8c427e4902c627ba4dfe9889be3018e8d22cfdec44a5d4a566158e210db647dc47130f175fd349e50408a96b731f7af95dda45011fa848d4bc07bc6cf3cd48512727ee90144b45981bab087d6ccab59ad652a83503dabf92db3cc79636ca4475b53a5e3c75e7ddd15e21fadbdf3a3b7010c0f4ef16573422c0a6974c4042df9112bfeadd21ad707347e141d907dfed3aed3f93fc53369e29e544dbc75e671a7ee0b934edc7066d2496f30b91ec4ff7cbef800ff195cbc1a33b6f455b8163ad1217710c3d7e8bb7de26aba95ce7c08b3deaedcdcab88f216df1c5a24458aa2f02df1b469a08e4899c914d3738beb6bf4d11e1556f7942c2eaf687290432a0a65c8d5b04ccbbcdbbda8ecd81889610ea88c62793c4721aa81d7cc19c423059e399a6a1b3f241a378c855a9a09970968c22d33cf18282987fc0f751756981027fb2b3ad04ec3db9419a2e6f629163ae2d325d50aada29d646444f29bfff822b76a2cf644c745f94c1628b3d00cec6a3bd075e5042b691e7a4ea7009bac40ed992956bf3e6598e23461be89fe37d93b610ede45da3d2c6fd3dd19c461353f352772cb2fedf60e8ffb38f3945b0548a6c04af76399a3aba98132dcf25a03737cc976bc2b095d6fcd44efbe9213f0a3ceb3ecb007924ffd043f4043fe5e9dec4cb7caadfc8bd022663b5333ee33a52bfbcc48867895979a2b10c618631b9fb7e0fbf94ae78cef0f1dbe2fff2b6d7d0e184758c7f37eea60f97e8d657357b2fc033f768d88b0a29a5988a70eba041dcf9c2053adcf2637f8bfa118902be37147a58b3da5645dd7ab76c9f5e678d23ea2483a09d96415073be51939171ad7d473694398d4614b5628f649414b8a3538fdec69f246e0f8d29d5dbc49bfac4ebb4deae5ae6be2551b2e446cee0cd7c782516af19ca2e33357337a6cd4ed795e5ec4c379339a52b1ac1581e7522b62ff6f173cbcb9d7edc6b0f789cbd3062b9d93748a63d9806d45df09f711648a151f05e3dbac90159a3f317160ff85f291dfdf9ef9034e7bc7ae2aa3d9a2df9a8650c20315dffd52790f5907a9d6bdd2dee19e49b2adee85b267cdc86b34f66bfbc8e718d82f27d4bdfafe56a499b2bfa9464a8fe528c6d92fd1f3660ed139c95edc03d84b0dbdc0c6336c672b8994cf395e1e1cb4e02974a003419f0e88a7aae0389fe14f6997d2902285c299fbfd3eb92cc9b405fd70dc616d52c9dc31e5440f8bb5e3703610fbf3c24092bd9a8ff85e11459f647b0eaf61c049963b8f3ba51510e219751ec99b38d9e4e0fc1b8828eeab72a1dc536122518bc93dd9e2df811a128bd7293d254e82facdbad9c981d2d3e0f4330b879b3aeba4118d88584c9412268ca8ff9cd36ce61f8d7d0226216a582756dd4a3164f6829ceb2bb21141512511828f2c47e413fbd4c3ca57cd9af509e2995d85b83d18dfc2533e4e52af9d95b667a650a6ed55999183734c8901f4d68de6ef840e8b789ff0a5395e7ad2441a913ade1a87ebe4368c2c18a4fa51b593e4511169a84dc968b4fbd88f82c5e3317cff996d7b3dccc2d5ae42f9db124de32e2df72031b9e41729c484071e2c90c482b081999f2cc58012140961b23ab8ec0927c672493937cef7a0970071e72d2b877cdfd9f1f4f6424e2fb098bfe11ccacb822882712c5f0a8015573acfbf07b60f6491898c62e3d729c04fd7508718235ca4b29b2bc182813a12df7776667ae5ce000010b05ad955b1ef1c091b52bc34de204f40b7e9267179dd3089a575926e71a60e9c7a078d71c7dd9c47d2df892d1d995bb63e0589d8dafc4159d9b496407e99308a847aa7c4c44e1c129b6422f1fe7be321dbf27a6b9cd3f3f999386ca5baefab27fb50f5298fd954726ee9889d432648846a0e8652976f2776fffccf3cd5e7c46499cd8797ed78cde347326ca978b8cd2e7dcfac3e4abac4fbdbecdaf7bcb50f5b592d7f0bddccce56f9283f5063ef67e548d62c1bf04e68b69f6bc341f01c1b5babdd9843c092554a6160ed6f63d73b04ddf28d2338ab671361838953fc63c523b9ca6d9c221dbbf61fd1aabc686090faeeeca6ef78dedb9e29b2514bdda8ca533bc6524ca4775deacc90fc16999c98e26568c49e5e5ec29254fec5e3e00213a53f555eafe709d0744807920fe0e6de0ba9af50dd30b5378ebe647e47151093cbede5fd3f2d77e62813b3177564eee7b8d4dc3d76bc2379ab41098f15e6fecb0a7523f7805d219ea1aee4681788013d84fcfa4fcb630e89f51988c5a400c2ce28cf1adca664057b47dae8c66a671e6d37f461471b8fdeabf33dfbbfadaceeb7061aa92918e164263b25e38760a4fdf81ba1295ea73e88ad800a7d33ff4274613b4efa6f25ec060ec0c2d9efbf793ecfc9290c128279dc63482b10aa4acef4ff871de062ac0fc69777c043c5f6e37e410a1044eedd6dac75b762525c91d3cc4a0e8a6eaec1ba0719e90f40382b124571f08938057365e86b25d5c9e046ecba475f25189080ac24b0d77e69e4c16c2071ebf5e614031836d587795cdec4f67c60cae1a4c7177eb01e6c3ed38615aaef79cfbbd36d52c1880b2885accf1c38602832ec65e6e281c9ed80f530b98f7f591031ad5d5c90df989dc44078bbdc25ce690ad3567a129ee92a172a009e8998d1e2663b9e19425a5435e6f027ed12556457fec9550a5d575ef6d97b1125f359c4e1abe3cbff448a2bd1ae768489ff4c8a33b110178928d1d9b8a2b11212a708712f634b6ccf93ab5888a3a8751c3942dc634a881b17c89af349210e878c0a71557a895488d36c725a9e548843cddc97b1e530cfeb36a59f5e32bf8aef142f0c3718311f6a9ac8d4afa69464957322928ba45c1951ed2ca9a4abe6c37f17e8f4c922fb009f42e63a41e2675abcd2e0093915237a6cc6c7af50249c85540b7e44cc8517f7a5bef7236fcfdbd7a97f7cd1c5687bde3d13d4e0cfe5293afd73831df5c0d9b67f9cec3cbd66fcdfb41e366debe5e685d64d0e7b6e5de95c58dca44c2d13a9b31bcf773c7615a513fcc843591ed872dbb5a3ef9a19ec2351c1ea2ad95601a8eabd24a1b89b482f0eb7ed383d6bf59e1247796439a5e135b8534352358a07c6a5924f6f2619d906ceccfc8b18f6f6e6b839b3d78bc6f5e782826def2c61b048c753addc498981b8ad487b09dfc07b6c35d5e622b8bea413c1ea70c2fb59ee2291b64f54b60c8e825685ca5a954cabaec812b3e496837b36c4b04e0cf4d68d74c929d7221105ea8f6bc5f72efbe3cc9c06463fc1dae2e08e98a36e194c591c83d1cd580b620fc656df4b7fbadfe27d045b0ea1fbd7f4382eca413233fa7734342834b3515e7ba9de740e9c4cc1293e116e5dafeb77dbbf2211ab96a5201e7806387348526f6d5cbfe7ac701d7116b417ce19fd1381cd24e97f32b41ffb95bbcab6bcf74550ac6141b4ec7b7424e1e84d234524335634c667b968271aca60a78e7620be1cc31c2110ee65189b268341d95e638bb95b54aee3e451ad0256cfb7597395b5ea59933e8e882d306b3689cae47aed9725c6ccc5b0c48ab8f6cd397522bc7c0dff1c5424e6c8b157e60e90c6321cfdac82dcace931c69a12daa900f56145c3ccf28810cc0d47b53ea20cbf02b72e578a08b061c4957e2116d677cb2894d91c00cbbf88f15eef3def795ca31950d1f9920b985bf9675a8b186ffb7a7ac4ee29b1baaff085ca5acbab74622045985686a0524be811072df2476618301432fae2482c50416501829bad1059674f85a8c84311f10841398852403b15b8d0ab80c9aafb9b95c85d8803abdfa6c679fc25170a0c6c1e2cd2614e9b6a3ace7be81e52459e4025866d95991885b4877090fcec6601fbe6809f08bf390fa7084bdf5d6caf22c25ac8069f9b908912fbad03dcacbbc06e8d380edc7e5fef4cf31491a3d14d5419216dced34fc6694c62ebed25c43e2768b7027a0b592d514e32e2d0ae4e44059882f1d619b9a3741d7f45f1d7ebace3d1f2bc9eeeaf0406c18c606bab119a5d146e050454cc0b2ba2af1c5ddcbce4938c2f5be13019baea7c060509b67b74ba524690dae25979c0bde8611dcf7b61641303bb738c35def6e1bb76cb58fdf1a39da8765da6040252c3a09dfb08cb1eb35bcffb694d664b74b19dab9c35c6cc25f8e4714317037da65bd6d6ca6bacb12c56c124294b7cf3db44c07284f8ed24a21fdccc8665d177d0e929e8af11893545cd7005dd3d1c09cafa04525bfac205f6b79eb7bfdd2e50aeea74b4a7d7d03f3c65dbdec02f3fcd463ea72cf0867e6805d1819f7f19b374f09693b7639c779d509f21077781e749ba042f4ffc6c2ac7ce4ea039446bbab9ffeb399af823fa4b0b60643f357a6b47d17cc17d5e9298c267674ee30e3029ce25a92d48a9063bfd3a873e6f8906582bf0e36127996fcb12202143d0f740e119283a4ae9a445befd6cde8f0a8a6c610369bb2765306d6ab107fb88a241c9d016a0effd4aa8118164daa5bf99b5d9d9ace5396b858bb3f6ca591329ef8f94b86460d6f180dfa7831f0bbd795c6c6fd8d01a7f0122013bb1e4e5b9e9396aaadc255c1a6b2674d2eea83a324549c643f07453e73a7e9b0270eb96d3d8e5de4aa951912d4b66813f14aebfb473220edcb7caee5b15fe28f3e90a65bbaaf33bd0a16b5f365317ecc2eaebf1ba8f37ce0b83a353595e3a32e73c43da2c1ee222a76d7d29bff7532f1570a55d1d12f9105ececbafebc5c3f1ccd6b3e460361c641a1e250f33cc5ae492798b514e51407f843a922e5d1fcbeccb282c1357d55b352c5f47a1feaf288961422088b8af88a183526e245027250f46f8f3a1890c6029237e89505e789322f623f77cc7f37e0c50edb735037c8e885ae2beff11cd01abf514d649215f74872e871ad560827a3119fbca0692c02751118856ec0e1b40f46d8dc79d58f319dda5b4241abe69bf5cb2e2bd16335113661c5fa3655c8e3f9cd540a5ae40a37787a83dc69b5ad3b014a653122534bf931a59a29e45d6413970d26552095c9c7336b7122eab7990ab1814478088a8182b484e0d0a73ab3a7578975e2cba170f0e928ed46c4921eb2039a392fa5e1a7fa7e47cfa95d2674b2fce3ab8d6f3ccfc537bae6ffebe3d25e2f4b8f4badbfe3d055ca7be53858fcdc854766b99520422ebcd44814125632e851344c31efc167988550ee4007660eb3ef5abba198e9225c2534f75b2b2b3712394832a580a96fdb3b18eeb9c75a23a68a13fb6bb72e1d7690d12d4c7068e8ccae10b9335c3eeb6905b182797f3dd932f3386132f231164f1ab68e09032d1c70d8c60004102d5c9772239d7dfd9a98bd9156d62f58e7fc0ea4e8e763a9e4584ce0eb731385c1841c2ae7c811359fae0e1579bf26f8324c08e081344fb9f9a162b74e0d1b3e41817a30dacc6c5287e78217b3767529ffa8d95b263bfe1581f1386addaa1f9a511fa3f4643054e7850ec908d25c21c5d40555af2c39a64fa4dede43697dacbf25e3f58e3f374123ace5f6403a8f3d78a5e808f54e1ebfc99547fc68c08d10538de52b0d72ff09b66fe511b27dca3ce5bd5b8a79c8c4404c030d5c65efba48172a9a8c1c23ef6bf48dc22ed6363d74e566752403632aa6958f8de05455450a2c11eec513154edef98118e7995ce6a7aa5277bb887a33a6b3fbe78e855999d3ee9582d34897810bb0d36be4478acfdf54d86562e57f2e84c58d274ea44c7d588129c1fb663632f1eabb156ba930d072270fcc00d17b47eb2256e3ec13a664ba8f7b912817e6821592cdbfcd2b01e9b0deb1858590c46e366e39b23644626b6c91517b431a33c3140f8df6a2ff0351fc706f04c421ed80b461243c8ca9dd548cd14c8f345412125b20cf53277136723848c0b6251e96dee26fbe699c6c7816c840020fb1c88e49073a36c8f3907a14c6509c5cdd86468e5cb5cc7158be96c6a2beb8e8df7444901df71624a474e767cb1de8c7f0ceab0878198351b544422b29a3cb5e2c6d4c18da939eed6946047e34b673a06fb2b3b29a919678a4b9893cc084658d5f469415cc23408fdad7d748872f41effbb40354f3f522b30bb8d66c6851b129c7ef8340209633d8b1b08fc1bd4750666789566a129d7b73e0820a94d0facaff9dd59c8c9b8939e15d9519c089d485928daab32f248cd54c17c062898b02eca1b9d1d2337c3ae4e0d0f5a7b9105a7b63c2237b015eed7f10c04ea582fa7863163dd49db93c71d4a65df70286539c6bbc73d705a56832031b6cdde59c295b3ec6aaa8dade3e5073876f7588b6d0932d70250529baaf3bcbad1238ea2dc029408c11d0038b2c2660378ddfac431838d3ef58c41b293dd53d32143378637899c81e2c0c9b73a4ca1764c372e0c84d05af136de5b37b07144324269411f87bdb99a9c012a7647849d3da1b24bab8817dafa2214dd7dfd464ea61144c643fdc6d182cfbb24ffd320118561aa27b21f60435e52f18d7667794e740e38035b998170230096ee2055cde158ebd6699528e4a014166bedc82e2a1524ae7227d9af5d07b77ec3c23a05bc531fdc38c62551d6d307d570c183927fc3b01ddb952b1ff8b7eb7ef1e2d96508f2a0e9d4fd8a4aba51c9e8c736b2639d40caccb4f3a23988949a945754f3a97ff3469e8f9c6832d221370637d9949f343283c45f48b95c454781a196cf981ac8fc1f9a91a16a21f9bf7abcabb81cbbbad87dbee7b46092087ef7f39fe03a393e451f2fee3a341c15ae9d75ff4f6e940905f30a8caedb3a2ddda80738423ccb6948ec0182451c6b14cc141b07b7f3359107267ee1c4c081cdb52378aae67495fdf086b787efb0d134848f05e3534293b9571d3310cb2780cf1922dd4ccb19a31c5c32c3dc75fad62087737f904f3723245a077e05aa0813c18fdd1c20d6a23110d98d06befda02dd835f09ed6fcc3a01d5d07fafc6ed0ce76bdc1edec6a70ba1528bd903cd40e5c8aa5ab7f31dc5e3932a0385568492f92a42a141c953528ca8d65efcff448de95a6382076e8caa420393523bfc4a3cc320747c08cd7449ea61859803471604356ba1454c312f615842b560fdb930a361be0400cc1dbea4856515ea49fc27a7b1fa525123517f9806331ae70796f85cb0fcf8c3f6b13d71f5f9d40c65cf1001d54e8d69dc02959a980db2d291d9408b1811e8f3ad17c49d8f7042741ee2676727ad1acb962f4e5cff0a1f90a7f0f4c0d7b41111e1e260acfcdd249095955656de2dd955d1fda567186b8d940e6637ef5485c27bdaba4429170fa1a9f6e79c22d70936e28449727905a54d80e7f22609055ad39cf1bde2d43cc08b988137cebc46f4d9beebb8329bcd105deadffb22bfd581eb8432f64a4a2dac037c0c1651186f0a7ccf3e2e78556abb50e95ce0df75083a326c3a9d760d1699ca8bf93f6e62f4213f7da5751d09adab747a76f870c91fbb891cf1e76bae3b6d68b2385238ea3adebfe38240a324fa657b19a329d82d794e7700c2f68e8d9e56e62017059c3d9dc18ab5a84ceed58f0ab3cb132a6397d8653b25bdea84ea4a99950e9ce5002582d717759bb8271ad7615fdee7bdeabfe76faac7ca73122644d4176455b47e6ee752b70af51d4a25f1fd05639b9bad8f3fa1823cb0c58a997cfed73d858e5322a4f70bbaa8b25d078a4d28927356d42e32183df1e7e27f5d529f5d5d4d72de6f133396f01fca120e4e949390ff1abb09e5d2f2103f6368cfbafb713a2614a621089ef9adf856633040dc1090f76710238c31c87796bd0cd268309662861e1f454f64cb0613f23195364861a84489a751d6f6b91a5f9266c2f8e1f9e9efce41dd00d0245e094cc71a369674b359840ca7398355476fdff5dac119143ab8814cbd855d3950a747c96925a9a8cc062a2b4f1146ec4900630cdf8b6bf3589b53d80c32826410903d980c6864b6e1b3e64bb2eba3b21c0f4370ce7bcc89766327315a1ff15a5f938e9762151f107a7aa98b0faf94e6dd342d8ec70f3324e40c8db093447d2c044edfd62bba26149d1c235ab7b344d84e97607bb042c41348d43f66ab44b00b288b9761719462a7e89f07a2dafece7bbc8f45ffb42cab7f837a27f6b9d945333b7e8a4f6f498333f5a267437d1c764e1ae862b79a75fa43fa430fe42f88fde188373f433bb33889f529c1713d01bd8f3bcdb8198c22566b93f9fa789f8d5330d0454165d4c0efbafb95bcb40c6b377ccba23376952be279ef46f5e74f5b1810ecd69f05a9f6e637788e734262159719075177c400e37b598a3318989ba8b56aee6976cc7aafe1a600f7fe55d50fc3e443a4b2cd5373b89353f670756f58f578c8ef612db74b4bb56af99d72bccd2d51c20aa26b2a9b38edfb01d038d1009ff236174feb72a57c9ddb2a26578ad71902d56bd6a6b4917058f8c66bbe680cd9ee76e443c50eba0301324596ce64887db4963805d079c5ec498c52df4c0e8f413810c5e902bd8f24c85eea51a85cd84b6046c858939126c6a8cb889032100ea04372308d727ae2eb89f6a44c0dc11b4e64dfc6b52d287d24d0a1d0355b0ce42ff258c41f7e8e6ccfb25339d00eeab320343c7e2f1953845ba7d8e4ee056124984aaa7d44b85d8b2f7b4a15c3d11581f974c7700d2d99cfb3a8cbf4c2aba4e30d8587d5b447544b490d5e055238992c05debc1ed9fe28786e538cc746016ccef3d2166e8a0f00b1372e90282413f3519806b106ef488492f2b375946935818c38875d5b4e14de30c8b380a7bef7be6f013b52fe85b088fe7f478a910c0ec781b8b429bb11b52b3dd6342e639f0d422fd551512587e00640d754c6d1b10791587630cff72fb38a66469cfd91967b2d0d590bfc0cb017c2ce3e7ae80211fa56b30162658ecfcf8c880f25c8a21309cc4cf44c27b9cf659e1c349308874c6a79ba01dbbc0b9576bdbaf1258be82148c67b2bc48cca49c6d37712cf388424a19114d0f15465915a772f6bcea6f182ba41082779111c8fcbf259394cce161ed864f6dd2d07869c2d0927c1337c95914bf49daa84a6d8b2a6071e90071b8159360c3b157e40ca6b8b05ba056777e7d9d8d116f23d6b12974dc0d6e6f0893f956dcc406f547edd3192af7005e89e014b27ef1f2366d056d11abe1db8ef17a08131621fe7b8c09d68d8297f3fc24b31e73ad98f31deaadc4ac69606a7d1cf19656c27d16f7b4b6c37c8c6147acd6402b6bb80a82f9309d4f8d4daf31cd6700bdc497ff5099223e801bacec9702060fc7c8f03f5cbbaba9b8df55625d34701096151f5d0f501a434e93d8222c616acc2148a38745d494a8fc68c6bfec452b2c34abbfb42e3d1f21a0ef6c269e7d33fc9826927feeb7fc994b5763b654b224bc5a03de2431a63f4192640242dd071346409cd79a101b707ee173336530cb559c16d341eef76f9a4841aed5650a4b3e9214a371d6c71a9c40d76c271bc7c992c93036e83dde27734e16f2331b3c99d61736f92e86c1d250fdaa50f4a189aaad63c6c09202ecd28c445b52a0e7b5969db023d9b0d0ef76e7ecac135096742e5af1343c7ade9b0e388a75a1ada4deb93ce3b2c8baddfb2280ebce474cebdc570610b12b4b11e3cb5cc10c058a6ff24cd981f31e21dc4b7248cd0dcf4bd4906b30feaa7ee9a23bab41b2f897f245ad279cd1b46446fbd77164b7360b70e8ed9a71bae35b7722c87616ab08dbcf4c3fa70cdb4d8292912f13e420bdee4259483b1a6f3bae4c11a47390f62583d2c16dcfbb3f94882f9f37113c310aa80f9b6a28da51b1907e1b67873327486b19264a046cf6e080abab947ec28c71a07c97173143b45b6f5b766e6a4582a831396e49b6fb411355f6651483667451b85eea3744c539ac2f1b17f8adc8316aa18ec9d4281c2c6177995672c2cba7241494a6e6570e117886dc1d81930c58bbb3101dfea032c5f8a68d3f6714cab5cee9a556379e5da2847d62ebef570e2ee46115bd104da326fe0f8979c5f7dc55ad8e9c7cbbcd2032729f139ce7726f781edc7a4041e42aca1acf48946c33ff232952d41b8efe9a6b5c9f6d4db55bfdcff6e6e6fb425c6caf2aa3c4da0e1b1b3a50c7399a05a38bad280c8977d8f9618781e2ba82b1c635e0aae786eeea4e663259103ca73393d6d36c8b626149bc753c60b10a74b224faa50db80d76150cdafbaa818b43bcf4a99eb7fe3efcb9a5ffee542444a0e3559c3af9a34396f818e1e252dc6f35339ebac3e1cd686a943de732ea51c55fddf2429cfd931cb4af6b57c14d94f117fa53d8df956bb76b790e741a9c5caf76381210f4d3d5b4ea0789f518f875c84a4caf8f5aac30fe2603cf907bbb07bcd8bbf1557e87ba618522e561f21f9e0a6a8400677ddc971da8cec4b897ee665e71334f93e9ae4ec957b5ef44dfe129eb7e65f76f5f092210ab91fb95f17ffdcaccfdca3cf995e32c393d1956fb6cb0ce4aaae291dbca057b9168a0f35826077b9aa4b39db20ed4654a58506a4cea3e45030bc42621c9e00b2b93c405b7bc4df24877f41cdd25065a228a5d43a21fde15b028d9b7a4caf6a7be2199f4f0ff4ddfdc3ae47b26854f682950252c3995940168539c38894255c7d2775e98750138d4a0f2e47e8da3ccf82a6659261272f73b12ed872bd02e32cd382e351f124b63e26afa13a6194d53c08ee22d81e69a529c2982e47662d0fe0819aa39da424ece5133fe52cfd098be190b2551f0d3d5a45cb097d0c2fe0c26b710bb6bca8571f44051c676286bb6de40c25a2d937b6b730bb9daf2eed3c6c9416510f071cf30deb913055a4eecb864f115d64f758359684146a8e74f352133981911e8c90aabf5fc0d022b682e1874cec8561bdf13d94fa7f60f9247b47df654a2a9f9bbb58faa94045422f8172ef0161e1d9dec90287488342e5301d46faec0e449fa5b59c94335dae9d4dd6781c6e2c5da4a08aeb0850b337abec8845a3d2a220148ac568c54ddad1c3217dbc35f1a3dec86f94b7b4714362c6adee0d24aaa541d9291a785c7af57ef37abe5a87dd1bad6b9dfcecc0417f86a9d04ff5beb4aca9c527413f2d4fc655c4a5c84ecc1eccb6d94a1b9e277d49edc6aa9518e2eaab65f9d08f0754dff0f9d569707e725b70e015e2e0db2e599f03d35dee2e81251a5beb906c4f1e0f5b7f3b7707208aa17b7bbdac22a93cea56d3fac30099624ad06b6391d115afc6d7f1d7bf67810d52e360419f06052b6379decfc11a1c605b29b3cf13a86a1f4032c82186df2a2a649686cd50a61697959a83018e5091d3182a6bd61b9ac7c181793d8cb09b2bad2346d2a8cb6698444bb9dc195935ed1cfbc6bb268c0ce852704c130aae20840e9fd3069280644e29fac74aef8a78e2b140f4e862eafc48831f227c4261fc3ec1a15c3a71c923448302383e9ef99bdef204f4b62e278ecc0da0d0ac90a7bd33b074d4f82e510ca45016139efc40c245c39f1e6ce315a465056651ea71b7448fa831075ea14c338ee7681ab14de89ab7a866647446efdb2128ee266cce99064a14686e92d341d1606ba76e1faec72a0fe8a5fe4e07c75846897853f55a49955f25b7cdcbd6c3bb2dec4e84feea2d1efb88042b79e273f76e17244244b975f544085c59a63acd7b50b055aabbd6091e50d6b646971e45a1c3bf43664408b2e77444e837c22a411826f8e63007d8d4c826270188dcc192988bfe6e030ac62a2d6722a7334bdeff3956ba68eca96aadf2466936048ec1f7f453d12acd7d11703b11cfa53ef1681549962cd2a73fa1758f2dfca6dd384918893bff6c71bc25eab194be51fcba0df2d2dea49b0a7509f34b1ce4cc981139bea099876b5a8016252bb9148e6ba7f3ac5a9fc6a626d9dfe2cb7feee241ff85a3c78b01276fca2aa6f72d8af4a831c64d547ee4e98608c98b18daf7de737cfd46944b4bc2b5b57753a79e6ee590d70b8ba3e3b737527b8bd1229bed6f9cd17ff458f8dece8ff4532a190d4fc9fdbf8351bdbb58dc2c6d15aa1a674cd31ac2ee8c59b0fb56849746b30b9448bc17e47af5652efe43066e145abaf8e1de2d7a81085e098e9e7257b6fd24a9c16258bbf712609c556fa6756158d54da89e40e1da25870a4f2f02aead3f00a312ab8524a47d0b4e20ab243c9b5e9a0ce11ab41cee1a447da5e9560013fe4da9145d64e5b28017084c23e312812fca00822cb2c68f25ce0d911016cc6fc3b19b6e31c9a29b30c064bdf491a63ddd44585412232cc0a3fbf01d196a81084e8f5608c90fee1182eaa2551ca56ecb15513a55c2873efead8dcefa4c75b7e1bb1bf5aa18ab334db92766596f48321310e42bc5b0d8985c0dfe5d00984aaf0e264aedadc94fd58ce63375b6bc58b93adb3591096f729cb56587ebda4cea1c70df035019802825bf67414d27e3bf26db3bf5c0bed4e44a0adbf256fc849fd365381c7aa8ad0d00801f2cb580e3a17caf6b8694e71e8ecf21a2e2bcc877a8a0e9121545b171c81498b3cc3caa82fd69f9d90309863ca73863e8e1dc3fc355ca9410eaac5073784bad550a70a957d8d3bd170a72df3c3954125b91c4741deb7c87712d4b98da3fd220a52abcc68ef205c684639d3c3b93b52c9e7b0f9f3625c4848195d26b215682ab2d65b52a7ae16752af07e05f1d1c9f2abb435cd0e9d043e8ee2e5cc098c99cf43394ad78d2d6806fd162339b06d2d21aad54579e8e67ccad834c2870e0a4a25e7467948a268ca3c82dfe6f409495d93c2ec11607f235b38e4d5057b50e3e8eb79a0c2681d582de0dae00896047c60a5dfea0c3c6a05efcd11c86fe3221da5456156cf274114ab105a89668fdaecf24e748f989a93efac3a668be2ee4d2eae292e8a6802d7d271c208e751c9b5cf781cc5c4d494d3b29b8450717f38e1d05bd7e5b2a7a2bc23ed0d017e7c3a772045efe7f97e8e5130e87ede2d6418c9685b7097a0f0e38f8f1e674eb70e4c18ca2f9d286435d942161439e26a2af2496fc0a3e78840c540df578e909fb713d7a3edb24ad6ab00c37727a8f6e79eb4d0898e4a861936a6af2adb22886274fdb79da8bb9d68fc7d277426326cacf1a7c6d2b4e4c5678ee7d24f8b5ebde8f82ad2b35793bf26fc74a41d57c5527a69b8f472fe58998f0d8939f0c5d7d46138fffd638309f36ddcc774afc5413835c74531e22babafbffc857f2c8114e3d15facdf1da0e67893666bae60a30c3938d41d767111f5e023262489794cad39157ec895bddf39d5b9efebb3a421f5827cb110f973ac351d221ab33ff4cc8e8d7c6d99a9c46173afee43292aca062be90603c53e0a15afe7624b3242f3753366f59c1858e3523b62cf0b3b9cd4a3db0ee2fbd9d801aaf5de777f41a7c0a55554a7fd428774d1d4d82de798fa9168102cae71768ee6be02db88c49247fe6a23831cb57a0630295bbf26574c03da7799c5526a1762e6038af06fae3845a1b95c75bc75952a2ed6779d44dfa816ac09afba2950562edeba5dcd116ea19a4f801dd5f23c93f20e30528517f76b07d4fdb086e05edd62f66af4ee952bbed3472a01db034eea0acb7b708c0bb79590adccf2099ca5392f574fdaff1a3352067916a4e013a3bc221f8d79a59e5724a2867ea5a0084a359d9753d45ccb33bb37592038554afb3f48c98ac774941db0893095687d2736137189e7354d12a3e5238812154dbcd12e975df84ddb335fd172ce60a3e6b588a0e30897f8bd13d011bbb167cf6daa1337157fb1009432fa359341e65f804355a24cb2d69fb1a1ccf441668101c9f3c424a413d9300a8d6c8fd1b44a6e7991af264d6e4eebc4e8c6627cf5ec5f836dd51263b58f3354ed90fe40e1e02465b903b35f043a80d6088cdba811374ba6285545ef3784c289d131573b4ea33b2c74bab8276aeb99ca13b446b2abc66f0c1408ff4a78ccf69a2a49ad60b1416ae55031e11926b89b80439f8031dc5a6e609a5b6d925ea32a25cce8dc0e9c0224c6eeb35dfc83e54a9632d886bf4978d61733943b9f9870f6659e8e3dfd27edcbe96825445ee45dd1274266a01f204cd5a2682ddc22147596829defda7178d8a1e8ea4fd118471253d30a71a80c3634bd486ef0c6bff0d1e3cf6cde785e1efa6148d31b4f7b85d670f4b6dcd8c9069d9ec59b388c81287f67c94813005b87f4345083c77231d139efa098f1b9229627285153a7a38290638ab2e52c73e15afacb795fc8eba6f49ced79cd3ae2464a8c29de17710ce994eaeff12021991d5760558ca8d7cb555a64366bba7a0416a9b338b563475c2d443ef3bc265926e147b6ef35b71fd59ee24598e9a703d72fa9936f1af9833dbc84c8afe9541acbccb28455b5d12f62b37be0798f5e7c5a6c6bd82a39ec5089a9f8e19a838e25090b7caf559c021771f844d29070952458ce184217120f0e16b46fd83e2c08e638cc3b8c68e923a2dec5c19cb05a02b3aad40e315bc1ee30e7effa0a824b6de596b776af069aca3320bee2d86d3ac8905dc51d8a3f13db826c93a3f0bceb2604d31bf1dbd3fcb98c56f5dd7c21f9f7607a41a43b99ad13821703f61284ab5cbab14d95fd154d349a50ec30818e425b9f54928e9af49cdf411ca1535e349d329e915b42adbcac3a9da7695c237fb4cc661ead45b6b5459cee1e3101392e87bd8af4feb5f9c5f1b364cd950a37f9916ec70a468d3ae78d27903a3db1b5752739d95d2b10b2165ceddf5e1cf446ad6243cc502244a6e66d44b49f71ceada0532e5c032ab10c68d86d0946b49d3821cce95bc27bb6ca3bc4e8a50f12db4254e0409b892ec2c41e5f8cc293ce9e1c19cf1b19bd5c0d2ded6a49b523e30836692a6d250c5651cf5c1066394cca6a94c44628a64b6c688002fe946b374e2d11628594d25971191c7439f7bc8bc7474ad35d3a67ac85fa57e7b0e12fe1a1aaa73425f5f2aa0c306ec6d18242a1d3e617436c3644ca783db8698ca8b5b4bb96ad596c7a96de764d571efb0dc58c066d8a4b6322c20c1a57119e2ef4b71c81a2065ce121df5dabe6b31486b871e9d3dd446859132c43b0dd0a4b06cc1a808929cdaeb2498f429e6950cabc1cda90659a6d3bd84a7dc06c985d67314354f690951a28d769d246920046fe978bcf1217b5cf7f597c2d8431a676cad59f1c19972935bffd3f5142578fb54129f97948b1fc71bac0d013f99f900fee65f339d93fcd38bfda7352ad23a3934cc1be0047cb9e56b4d2d449e867a44d2c1ad1dddf77cd156a5a2890a35533b0296c16769183f00ed23feb6a14f25f49fff2bfe9dbbf8c42f62ea72ecc3b5997c573b001cc33cde5c92905e3b4f37a1b4694782ae1fcae97202443cdcb6bc25052c1a00943996f2caf5c25be352923112a26af52fee20794fd3713333c9b3be66f6d1a4404e460911b792066efbda0f05ab88ee929b776333a3bd1a94e4758bc2368c35933bf6169e2d9967f31342d5159e25cb2115b853669db1f6e3a179a16f7104b58e82771c0a7be0893c9c6f9e078f36f036276f6c24f0c604a8807e672079abb1d273ebea7bb6207670ab7db296de3b6338769e7c22eed01f05f695d8c4a47c6bc4c164ca264be5832f38bbb622776a9be90cf167e21abac74b506a7466d38834d28d30a544080aedc3481033815f6bf96e887522b79735bbc563b9325be7a8726d1680fd64aedf858ddfa8e74e7b923184365cb37538b1207d6b422e88c40e5c2381a43b5c0cc14484415ae419906b2f88335b2f632014a1ad3ce99a60fb690549285aec614d958b67b5d614065e5464592986fb675c70d48deb9e40a3a4fdd8b19a3e7794fc9651ddf0be8b4c26b9e00eaa3c82ecb229cf21514d540c24b9dc39948c2ae69fc18af7d6773cd3aff244fb9f0df6755438f2b676329ae4e75e0e4e656065f34d406186fa969c5d162f3b928b196824a65b9f989e854932d0fba67afd41cdaf52b365107f16ab7b5fafcb099bf43de74b48ff66537c0524c43b4384df667604b7aabfe9410c19d552ad2ae542296c4e199ac9d35101bc8ec93e2a48366e9a98e5086ce09125c69e31cd52796cbfa9f15672d354f98b551fbac406acff3ea6d29c9f794937b529ba7b97c52c87e9915130997a6c1ecd4235691281d82e30c54eb60d18f071052bbda73e50faaeb16b0de1bbc48a00746936dabf8bb9c3a104e25442af6a5a0c3db01c0cedf654e8f3f1964ab16c39052fc72e1c75178d325f30f255774b68ce4fd77af69aeec9b737f20d684d761c1f143ca634bbf386d663352bc2205f254600c623e7e4004120d4d2c40c09d12887856b88df2929daf40d9cc241c2f832a8b6954313fcb93a365ad4e8e7197b04105b5aad63211edc580791d41bc09e25c28c586da9e02a45f4996d516dc48cdaa3811b7678d2d0b8a51d0c824081d5f69c64749ddf2b8991fbee467480e9d569ce3b8c80038088d3a009e0991d063d45a6d7fec6a4d98d5c517536bb21f07c09006a1a123a79af74910e07a05a270092df73def53c31034964898251b51201670e4c52ef1a988407a5acc8af806cd780aaa855b81bd2deb601ca79389bd3d2639623ed4f7cceec706074fbf38ea64674dabd8ed0925382fe2ce3e072c9d2d8bd2e64064fd49a989601cdbd95aa1e950730c63ed98c02e28ec5a5baca75a9eb3f6743dd43503dd4ea6bc7fafb9e8a9120d0bc5abca939308acd7d69c4bd3227b7c9cb9a04fc4cda9c372de100b1d3e5651092146c3d1150db1a220a1a6b3a066f73c9e0bd5f6b794a191695d4c681181d768eeed91506fa250e41feaab270ac0fc8e43ffdd41d85600fa986bcb24fa9af165fb7fdc91ad09bbdd5e1216451ba5faf157ea4c75e748d41b57b342b028c1936a72cef4cb859426f37faa0766fec02eec4b91f3d676625e74d8d5329fb2515d8872e85084ee6994c37e0b5fd3d2cf3763cd7be1947e8e7a16d766b18f78d1ebdc1a1d292948c3b5ea50afc437ed3790bfd03f96f4ec9ab3ca33d4b07ebe1439d684eb2709546889e32a24754f119f9a7fa9f5f63cb37b427462bf58bacd2e50d85550a28a7ff075a90db0d670b22952f1c071f6838692441cc34bf31209152c99f3f571e9e2cccc17514609d01053d169fa8b356df7cfd9aa6f86f7b9db155c943d015c93b8c67eb6fbfff0bfc0747f815889984dab5f943681741f41e435e4c5940fca53b6047e572f2123cb295f5c71f44d45de961f25fd118594cb58bb0ed39089662ca9f4ac3f1bc361c3e28718fc3e516f32562d8eceb994c940288af238ec9d0c0273f624ff1ccfa385a01c76e7af5193726ec5a5b246b7ee7345f8ab320ff8b0a8af65278b8afdda8f905e737060170e4483d347088e914bf55502ae0a4e98805abdb0213440b0764f23a3cf9bb2a6bd7896f35578fd9698da31cd6ed1c880bb4be4e5a90081f5abd11e55fd355adb798e7ebb3978f3a00c10df217d15036223e62484cecc3f1758dc22aff7c05e181f5c5a82a1663a4e5219a82c9c98d8f1067f0b8b419706385af68b402bd682120f0b66bde6542e9a571016779c53e12fb63dafa8452fb647a8dfc3ea4df2a97cdbf3d477399242598727f788c74e66a198af28e6440fe7f7b8c811d41aa26257340facf37bca5b31f18bcf6d174e8998612588b7c4bceeb89277ac0b247b79ee141e72287138be49d2426ffc117502e2d9942139b9191f1501ff8c4a84fe8b8e27ebcc33c2ba34d1142fae3d6f715d660d75f9df4933e55ab4914572064f8af89be5a363aa2f8e59a4807edff186c31ec34ad118a3910c7f1bab17cd3f533c488daf8e6e4c54e0141b9ad2c95061778ffc0b3f1911ae6541a6f4d454f9c4a0e4c7c83e877dfbc2d24592e178e9f8e7cbe90fc8c1531453e8fd62d68c4ee6766de39f73a40907a2035ace1cbc66b2d34a906c413c80d39bafd84f1e8a778d1c5938d76d7ab680bb5d63fa8fcb94d674549e0e4dd7ec1069610bee911c07fe65a40b4d09240778b3f11d17752df654242c66d928898999fe7455680aeca39edc6afe916718863b1e47f9d06d5137bb5a3aba46fec0cfd0ff9f408449d69b838c31c0365ac282381579e511185e9d54c6876d71192b6f0a0c9d414bb95e5a837570cb6371c4a4c83d85ecb930b12c13329ecd0db671be9942538e8e715df1561c42cf19e6b2b12a79235d83b6ec7c7cd2733a2fcde0a5229ec17ce65997a3c0bfa065866895f87779f25353302cc549dead2217b4a465bcdee20767cff1734b56d4d7cafa9b3d26a798209efaaf8b6dd7de75c5851a267875c5287dbe7b6984d527f7c5690f9966cfdac1c1daffba87f3678744b14a291afd97ded2fe189e1c08fb6c940595e18e1d4629a05fecdc7a91d11d94baab450794579edf0cdcd04ab5c69363ec283e6d0f4e94c2da29ecb0e629900de268cb56d261e55c3dac9d83f43afe673dbe6ec61a282a143c706c09ce561b218168b2be898f96f9209dd7ee44e2332e68cba53bdc6065bbf654e01c2eaa900d5755591680f6350cb7bb7d25709eaea62656639de793e4f15883a8fceea5fb1dc51b16c8850ba2948b74f69427a089cc4e3c156dcfeb954f2e9f91339570996514e20bdee357355c7eb968a778b45617fedd4caa2778ca74614295db89b2435f49b48ed9a08654951fac254892551ee3654e9d885a6957cb16642303e6ae81c633617cf08b8e7b4b5a42277b4bb61732a24c6701c2ebc6355095c77e943385c8a536ea71761335e07250ca8e07ba54101d731f7f7519c40cfaec297127321a9ba13f4578a6204b5669efbf4b3462bbc69087898b94bd494a45948c735af28b4c541b3fc5976d5bee94c8c00881981963371749a3075674268c85dedef3f6d9cc26a6373a8c4a041bcd761384b6c172555fcee92c07bce6605b48d2d90a2812830ce82cc4860c1e1d0a71d26d6ccf8b2a1dc60c2717c6d8e114dc4c0864fd46c8c886a5eff289d8141373dc96770e0e14f9979d6b51fa62fab9b8ae5fe49bae73078f6b1c3605fd7132e41956bcfe767c9b2dfa1234682fef78b91841faf238c5e5c1bea3da829c0f4853eb2fcbb7aec17b55c6d3e57d275b179c0179bac2a733a384ca5118ba14b96fc7355c516ab5bf2e475d14063a8652877d7c7d991b753c73789f8ed8bdf12d83b11cc56e88c5a90c69572ddf6a5fa36786b4742a81cf5160aebf2fd32722c6bb92635bdf0e3ae975bef42f1c8c9df8e4028be84705a7d603e74925356555dcbaee23d95e54af1d2e12deb4af3aa6cf63399a79ab029eb84ea388341a2c06352f70a4bb8e22c5ca58b709792086b1fac3782ffd2b35e2782ceaaa4f8c7677365ac7debc4e8cd60c3f38dcccaea3851384d0beb436ab40d64f7243351d78137fb3eaa4cffc9807251581cc8a329a16034e24f2c543228ba64c5d4f548588de915b4798ea1a948bf5f7ea336233f627e7edf890603ee4c9f8fc51acd5e328cf4e9c5894bdaa5b16b426b367a9412be10928200591254fe74d039d9921af7ed7d42cacc4642ca446450c3d51894ea7200671502152ef0e78ecf0e01d38333f794c6cc8c691f166b19461090cc62a7bf6cb017cb8897944637b9d380b4a6fda2127ff503ba4b2eb96a4a8425783f6c9325122ffc089bcd7da0001ef6fd4ab079388bbc62150a333d55b4a3c0c291cb9a26a424a4d482435cec872708e8f2d76a8c1191d6f51528ceb9d1253152695e267852851b13cb199c3b540a353be9cb4ff97ce1cb1116b8b0fb67f63722de4d5c108649ba66d4eca064d624ea05672cffc1cf61bc211c48a1e3424b4feb1ba92d5eccdc704127cf35a73334308431f3596a417ddc68655099e3defad0e22f890104c51dc37ad395e422831e2fc7ba5652b7ea9b814c2104f29de6a1528d648871feb1bc3a66c175b43bf5c15429dd9d53080075afb62557da995ad7a619eb8866a455dfb9ef919594fcb37d9b2ef99ef0d79d8eb65ca3796939bef395e18546eb25b7b6158c18551455081cc7782384b7ce91d2429da7d69e11d2cac647ef7900dbcb7a93f9b09e54cfcacb1d40bab2dcff6394ed7fba1e41a9813123707485aec2f861d948bcc1acf1083c460729f3d33f5573b2b481b2ff5fcc89fd7aeb18f466adbce0d6136aa0f01dfb2acd8cddf1ab6563cdffff1dd8ed71eb78c90329d741b01753339747381cf8efc30f1fdd6c9f76c97afbf63b94bd5dbc4a717959beca35d4ff7b589ef757f555064fe75bbf31d4230533f03dcb8817fa8c8dc3cda9d630afe083f3f2a0074e89605d0c1acfcf25868edb582bf6fabbc1ffbbd5be3e6126079d1756ed5b11462ec8827eb5a94e4070c05e49c7df55a4d8596a98fa4c6fbdb788c8db14079987efa7e6d0cf97935b05bac5de2015fbfc5dc598209fd5d7805995e0806ca4f6f6a3bd3958ca9db2516ea099522f7467ebd48455cb333131965bf3e42d848837fe503c6bef3669bb2b7db9ea9f9bc9f78beedb51eb0d32b12d7f75ac6660c5bf22bdbf3f2a606f7e2162a7eb786c0af5e612bedac64fced3af06c1ee7372c2522374bbe4ae80102c30610b61ff36ca7508697e4702f72ab1f5a5e5a329273bcf4d761cb6daa0402cc4c858c1f57a86dd05d97d0f5fa51e6a5e23720fc7ed9c8712423b91fefc556d91fedaf2c618dfddc04d549321339d11ef58146de8ec3947cceb8a4b5bdfdc876bd97359c372fa3d9b59de5a7da007bac8abf3dfbbbe3b551bc011546f6be8795996d00803ec5dffba6740ffc3fefbb6bfda38a9ef50f006849d08a59f9176eb7bd40989bb469a43656e7c6f62a904017e9b41d6fdb32e591ef5daf747453929125e860e12faefedcdb7e7170a103edb1887e8f9dfce0da0a5caf21560ca76f773d85f63ecc5f498880d85425daea4902c7db5e19ca56bf648f38f3321613ce3da942d65d4eda11b02677720ef7122fdd1cccd8ca398f48d22d428f7f5f2db13ad3bd4c20eb87ec6141f8d8e06e4437a371277b6f9f326447bc5f843f66354470d67286c7ebf56bcbe986b011af1aac7a042ff36226efbe1daa80ddcfa3cdf742d532fc600a3e51c6d5b51c0f275f4e2bcfae59f4ff77fbbf81fcf3cdfe6f24ff2ccbfff7cefff1f424fd8efcf38bafbedaffdde35fd516165b46bef44bcb6b67beb69887e71de7c3febeb7fb8807848ce15e0e87020f07048a35edfc7cd7dbf6f47ec08f9e1d477beac76daefd1cda6cfca1cd8aec7eef398fbfd112679fbd5668f8da3d4f4289c57ab5472d7115a4adf71fc9375fbdc2d5c98015a1e0aaedc33d9385baa79170872ea27b903c511ec8b51e78656f5fb07f1f566637c2fe28b563ca31bf868813ea2cc54edd15484cf3324560ce731961a96e7fccd06c560cfe28dc24ef0a85ce00efd7fd95bc27cc6b817bfdcf0bef2d71ef1522777cf3cd3363930347e866f83727546a58f7a33bbfd2c8829ee7dd371e916f09f1b7c7a2d9cf230cb57f946aaa41d8948d8713f6b130b24bdc7e015f585588d49e6932b0b91947f01e67d2e87d591cbbad9ac4c07ae270e8417eee96b1d32441d81cfc12cad3f61610a53a6265793e6c93574521bfcf1aaf9db39fbcf67258ddde02a105fd508a3c9b4f59ed7b7176777e647b5eeb298f43bd67cff42791f26ab802f01d19543bb09d79581fc8ba561a599fc3a34166740527da4a4485e6ce97c0c54ec12749f52bf86b7581d60fbd986d79c183b4a9b79502f5b734fcf3f70d4bc9aa4d551a0e7dc971ef34fcd91c6dcce7ee97cdddb0d68a96b8e3b51e4e42e45e7f93236a11f4b0232402312cc87154f3c3997ca99319236ca20e3b9ddd2d8167e6fe005f5af8a7d16dbce4f3577b7768cac0dcedd772082a45b5d3feba01c9235783c4b56ce0b14a4616acd2d4f7ec854060a7ce5aefdade6d64bd1e87d0a40b4f38c7ebd74e7ca60470999dc917536dca09c6c2c5dd62ddbfd00084b71f3a07424ce51a4e1ccbe67fe56aa8a7279ad5f7adfee87b9def968fd8ed4236126d91e3923032330ca90af3f89b7e2a530b70da14ac6e14949a39311074773fd469617e2cead76a445ffbbf8c1cd4a795f0dc3b659b3df1852ffc0034da28a2fa5c5d1059cca6f92d713cacfc0cde03f3ee5adda858924ce5eb32d8f37d4f94e8893f3fd9df0155a08cfc329eedd85558170d22f61fc0007bf4b34bdf326ebb33b9693dc9c7792a87c6b9c2248d9b9f8b939df2eeffea57db63aaf9d0419e4be09cf72b980fbbd58330b8a97d2168efb0178289d0cdf53500b3fa35bcd4cf0f7dc4b80556bd3955413619c027f5f74321a77bb0b303c97b80f8ddfe317e37c019d93928a7889bf47a87b5fcedece0a093f569db9b760f4d8bb4fe1bcf34e84e876e050db753b891a389cca5bb195ce91614897a99037b59e5f0bd8114a96bbdece07fe814a6c6ddb2c789b4715fae1a496830150cb973c20d7dffe9004f7af734f2ddf7ed8cb43def7134163f59c110c2bb7bc00d79bfed75b84619446bf46aa24699cf6cdbebb737e088fd2d0e8d22c397863ceaa0a6ec900fc549bc3ba9ca953cc6cbc32f6492064ef0ff7492afde2f88064588068f25aacac59d04a00ffda590b83d3ef08ffe0fa92feb9fb658b0f0258efe0b5e3270cd7733bf441c7c58ede4a97b3d25763bcbe1cde71e1d3a9eac6cdafa3e44884cf4d861270af9e7317e2cf05a771cf53d63af1eb76f387a86787bbe16ded42f6ded575a1bb3450861246e67ea307135a62227eee4048775c90a09fb7ad3e5d3dbd699d0100589dfbba2c2aaf9bf2d2a04394bad571e8cd3cf0861ec58b1b00b28bbd6dcff3cdf894bb190dc87d3ab2f77a2c9993cb6da7315fcd252a2d5b3010ad3298975b5bb16574e3034a4dbce4a48dedc6d8119f20c2621976da74f58f8ceb10826d768d873a3bb31992a91dfe5047b17f461534150556ab216b88ab4ac533910704cb3dbfdddd4dd7b666342e9c5f33224cf1c04a0f5012a4616e6f6386d8766b1036540e08c05d06d9971ecd285b1f8607a384abb47b1229b9359637b7587215e1e84bf7979b24ab6b4b7a77f2b67eaa4654bb4f6b979418e2be13b4bd32ec2723df0114cf2d828dd46076b6896758916133de305217958bd43b12592d30c7d7edcd598699c437859290709eb088a69e78aadecabb47aef79a19f21b79e66b0618ab2a116fe16ea75306b7ea997be79ed4a730c034a909948f2c833cd1ef25bac3e56b0f6fb38c177d3eb6cc70b767ef8ac313b0691a38b676730e6768bc124be76ef054855ddb3eb7af33f74fdd96b1f9ae094357cc5d29859f96bfc1af86ddadf3b965b6dcc03ae6a2c6d1fa6ee67ab9933e5abb7cad9f65a77191a7e7499776b47a7093e27c3e43aed01a5d85b0d2eadd38fd0e46bfff2c247c38cca419a54862631bd6b48038f938c716630000cd252a677ecd3182386f0bf9ad447cf1c60a7f896a4c41292244aa5e0acc3cfe25a6b7befed72c1f2a85fde0276d5e7f901870f0c6d733f53a4256037a1ff9bac7dfb61cf979c3fc769151d90d1c2be8ac1729f3c20dd652ff86b58521eb1f5e29bcf9ea9f80837bbcf2120a09f91803d33f6d7f0dd7dacd8d3e5e1caeab83b3f37874d302f44dd2f3ce3f919d4d7c7cd096cf83414339f5555b8c2bc71c804bc01e4b50fe9f24758b9b20771c33f9471106f572d77ef4514570899a950400fbb88340423323f8ea8ba8f30ec319ae85681a3765f9304c0b5c95939716ebc25635beca85f6da737a2b88dfd3c7225386aefc34ee4ced7b9283ce3609347ab9c0f3be00e4cb866e81f21e970b482976b3ecbe8868cf51e991aad93bf991091fe08d16d812dd7d620163334c3794bc5690347cce15a2408e01c778e7968599b8d5dbdd6d02f1dfc7fff661e887cf7a563277befb5c67e6570e9f3c1d0dfaa417d1afcf56698f85eab6094231fb6767b98ebfd96256e5762627fd255b7f7db8c9a320fc9a7f4aabb7a3d3ae2ccd85752d6b593cb89c5731e76574f0e4e49c2319f9b04b57addcc01d7af1d62f51ef7952bd0e26946560eb4486a40f67f3c37bb0d313475d68063150905aef5ef72bbf68683fd16b7db5eab6232192b8507771908f35c29899cfb2b96d71afb551af823f65a869b75553e5fa0572ff809e658a53ef50f67ceabd75e35e7e324f33a21a8e2790328b2fe1af957cf65e139c1f6558cb1d3e64e548ae0989390f477accc095262500428f987bd3af54bbcba9c489269fbb651f0a1a54a34b928ff48772a3d26a6a85801c9ce9bf150824f781970e2f24efac0cd43e3fae250f04ecdacf13aa859c35ab88fe53a51a3055dc3fc2c1e61a76cb474dc1f7684761f9ae193741ff8818f822b68863eb5e796676e253abb07789947a9ba63c63e3c85221e77e7e59618fdede7aeb76596fc6c79e61bbe827ae08ff33bdb974f7c4eceb0eeb42cdacbcf6319e591505eed717c97ed7bedd0cf23fcf17d53370cc28245312f78616668aab9e4f69f4d210c0ca75717ce423337b3b26c93f7b08e28ab8acce9ca3ff8db61e7af3ff5eaedfd95a90e5ae0c2af5e5b22eaaf3f37033bf8e0ca6e876809afbfc1e318547d4b03bf95f75e1cf1e8fbf769ed36dbf17a03b3954e9993b1eac9dd7da9769bed7bef4febfa2d6370e0fc3dca107aebb24ccf18068d8aa825575e5e0e8466270ced31619ef7e1b528b77e610cdd618dbfcff3258cb94b082cef1bf9dc6bcd2ef9437b81f032f51ece7762ba2bc11df8ad5fb01fef06d140530662fde67084d945d1b2d6b829ea423358c38af058aa11b0f64acc003371a2dd79b583e565fd4741d66a3de1f2132f3f3e2e4268f7ab0cf486dcc076aeddf0a7b617ed87e38136b6bcaf09e25692ab0a132d7d93cac166eee76ad7381def3df3545f48318177fbe3d7a6e143b2ee79e6ae58f7f158e099a729b9acfdc2ed916e2eb1c15a393afab126de88dd1cd5170daf34df8f61a0e0c7e6b3320960c8b4e2c408dfbacfbe7bc1433f8e44f8dc85f2d49bd8057e36d1af57cfdcf19f56b7fc853e753cf3ad719325a68db9adf8f1f55d1347b2d5156677da9479a8dd29570beef6a8ebc491ce82e810ff66955796b2304fa553e0cccec1796cded778c9eaad805db6f332e7deeb01f68c3892600bf8f20992db1f6b19fbcd813f040798c271b8a934d53cd46aefe923de33364144286f262ec0ab8369e0648cf8301dfb1f05c00d3010262f8812c1d0c0f93585b4fbc868b600d16ce627da78db403a0bd615897c19fa6c74e1e768d439d993c454fcd5814f967cddaa81176c7c989f729be08f4ac7b3d5f032750932b91ef298773ed7b28ad5a68466b6155fe1783b9ed9f8bb4447bd37113a863ef6013ae9bdef4537684dfd1abf3eb2dca6f56d8228dcaedda4f0440c8b609be1a2151bfd070bb1d5350c3c441b21f7c7b9acd00e7a4ed0c8f891b6fd302ec9c6390aa1368c1dbc7d5122fa9e61d9978cae6ecd008b2e9816ffdacf640aa641774937b61879ef6504608defb5764a3b6cd2aad1ff6137cb0bcc8a539890ad94140cfd09a871e437746aa6c04dacca94b46ad18d32935f2702d07468cefd12497b9c4721a699c22dd47df7fc7e15c7b119d63ad8636dcf3c8da08a8337544b82bbfb2c66c507ecd0b6671e1e70b5e3999766cc4964623abb8625ee62eb1b7cd499dbac063f99955f5bb421febd7aad9b45bd097556a00e60fa0f61e2af4385786de06fd7fe7e4cfd7e46b6861937e7f09edfcfe845b7bfad245a822da72806c8a999e1c85efa90201f0740215932be2727015d43f8d6a710dbba55e0f53fae260183843634bccf04b5d6e40cfb6ad7e583513ba6e0af3237e062af9ef966e5a8d869b3f8145eb5930f99bb0a60c782bcf4ae2dde2df3fd05a21ed4d59544603c2c77b00d563651cab265c399b5f47c65e618a07bdfae93bddff682d0182c9b80bc8dafe14d83330aae1e510c5a2f5bf15e7607133bc7e66188f896ee687f95003599222ea4e65baa7ad370ef465da60536d2f60cfaf6eb7c72ed089266ea9797b273deca552c59a36a97ec514281eeda8edbf7196c095664afb7c6143c23d871b57498c1ac20afcd051e81037b9ce390c90b0f9ffbb35d33badcf35a0d53cd880afe3864a19c3d767b47595ccf6b6f8c6822d52d661b3e3e98fe7b2b8883744ccda003a4a8d64c7d89ee1537ec0f39451e73f36bd72ebdbc89313f86f790a018fe5396b537a12f21c1f7787dbc009a2b2d9dc91014effe4d888da554faf5b1d59e828d04e1986b288eb11dac67e5998da1f8a7763049f678cebe7ab5d6aa0978323baac08ee6373bd44c7d2433bc56c6d7bf531d1eeb96364dc5f4d1aea0d795b476037cc36b58309e6144685b6d698ecc9bde1226d5c72d82ba9a304b4b96a86169ea8437c3bc2cc70caa43e831766babe44f91efd37fb307fab73cfcf85db1247aef0d86f0ecc03637a11cc51b83c8d8eee2d612d1f5b60cbf6b89433e96627e1c78ad509b4467df2a1c437142b3303bdc93b49b9ee569f566a1399808bad2e366729ded799d9fdbc9b5488e33b0ab1d76542fb78f5d885e7b0647406f8ebf1dfbbbe3991f40a07f3d2026657f87a5aa7dcfd25c647eedfcb4eee4686097552657057bfe14117d3b84df1a867dd8b16738fe0a3d91da1f781f9954c78a18c40aad0d6d46e8462fa11216fc2d5d007234f5637db0e7b50e7e1dce47d1829fbf7dd96457f110d24d82557513aae2c98700721fc2abea6a87ad9a3f19d3986ca9dfae0664a0eef080a9b34aaf445382738cae5d5de93041e53bffa85fa9e0347baec55fe97ac1d41c0b3731cb3971c1e73877c872468df6856d782f81a1df67123af739c633dddda7f813f6a80a1b9d578d8cbd6dc460f4e9e9936fc92707bed77a91d10c1bd7100444a9fa21ccea0f2ce1f2f96ce6fee513b9353725739149f143bdd2260ad9b5f353c70178880e40e7be3df170bfb531dffe03f315a1a4c288a9825583badf32600caf85bdab420453ff98014d959267666fecfca6dbaf77805ef1ac8c977f64202224092bfa1067cf9bbcfe1188dd9ac3b0dab425ef2d54cf0f1c60d77c49e8c678a6e1007d3d5f7af0d9f25588b108d8bae2bf032f809a682fb401cf1ba09737f8d3713a7b7bd6d92e3afb70b1b3b0597dbbdc5921576ce5d483d2591093ecb01f4dfe3beaacbd30bab2ace11478c2a17a56abf406fe037f7cb0048fc9a16fbd47b1b13df1dfef2cd9526dd6cc53fcfefbc11e8373b3924d5cf4e9c6ef6560bae8161004d02fef027c3bdbf63a98f657fbffdb1f35ace7ff4edc6845a476f18a34603d9a87d789d8d15a15527d865e935c552a5f9e5a1a64572cdf5c7cb152904219bd3a1d2a8d82a453cc5b79809cbe9780d12c4a4b7b2d68f8edb199492a643398228348c3063ab95fa07cf9687f81293d2104a4bb602405ef02aaa59b91f0b59cc9816f4dc4447f3fc3abe1e00a5669becabb709a760756ea0e72cd99782f9b4188044d5150fafb90b28f9847df02b830ef9498a36bc326c267740e9ff30289680e3ed650a708a979fd3d4060df4f004e94a7dbdec8df357fc6f4f576b2f4f32b14f2c947e4331d31fa6b7f83a03124fbfc2f924aab6224b2a5d947f8cb5fad77df52b0fac6474b437562be961483fbc9287dc72a188dd612e108fc64f309a9f5627f7a3ceec835deb92702af55f19f70ed9ed7daded1cc9b0878ea3d58029a22dfe628ea462055cfc4ad5c43006388bfddf2f43a763e183d6edb5eeb6470aabe0ea9820c263c957660e2f754774405329f4bc0234ae69939f8a098c771f887238311c2f92d4d4885edc5a51b9a450b0f5440989de35275b5035f5909be618f313dc5edb51cbea5a6158a8d41801c535ec639d0e7047855033f84edb221746bc2e6486f0caba0d851f526f164ad702391d766a037ec37edc61dfa89979fbd4ec1cf232bb00763b3d7a95688456aec844e2b481ccb76bcf68f49a5e94c377cd6635f1781fa2626db7c4a489af15277bd6cdbeb8efd6d22f5cbeb976bf8e28b6489f973d8bfbac31d7d17639cab939a48df435104e725ff2815930d634d053e0f89dfd94eb6ee9bd60a40735b246133a3ca0a4c73c340f38e671e9c7f7a78ce30ea510c59253384c143f1e89e3df389eee07ae794c37d26203caee7f035430082d3613d17661002ed48fc2bcff2d667d6f0777b03ef16a0a376027b627e6467b75ec74a184d6f0b6f7b7b9a87442d01f4b7933c4452e9527964f994f91e1df2571853e730bf91737c2f905a5d6a7c72ce8d68a89ee725b8b33780cff0fb26778d5823ace83716bdeb2e70ff5bad2c312ffdaaa4549bbb068a1ef6eb92736cee4a63dc2f8e71bf3245046259f87aebee808cd6ce5ebc7ce6769783147a447b0f95a1a43adfe78722cc3e34324d888612d66b7e4a01de57f158fed8e4d8b71cfa8673f21a86e40c349e22daf95e40b192e73cda79991ee9933ae2feb800bff2a860db6d7d6fc34c7e0763a7a1c66629b1b3b2aac41540823f24a7f455c616fa5eb69dadfa66de7cd838d473b5f0b3836676e09b07e634adc3889f023879e82f103bf91e5ddae070788b2eac7ca60cea851d2edc4717c63e9b7dd49d61a6fe62296d3d474fcdfd6ee23bfd9d5f3d41be118be98fdcc03e70fd8ebccbfbeca317f44df6c3ab36c786d96076583565e80b8427f673329e5e11718448e878cdcb009e4f52dbc26c20175601a0fb7c4077fb55644dcefdf20e27ef8937eabf781d09caf776dd0bbee4bfe4fdb58fa3e324d8936663ea785b9e2ae1a9a2bf869dbc77184884fdc6d4e51fd737f6a986ff6af753dd878d6a81675f03586eaf6118ef468fe7f078267a5ca6f6b58dc76ff0b8a456bf8a24216ca05540ce9c4453bf1510d379bfab496e963de7e065f33adb1af55868413fd420db7ac80f88906c29b7adff6cfd94efca94be0bd792d0e1a6372e8b071e6e0914f85f60fe7f1d0b22e5bf36b0e26fb51a537cd698bbd70dfefecd62969a47aee32ef91257ab3fde37bf7ab975b007cfaa29be916573eed7e732ae9111fb32cb9fe2fd0f99a9d770d82583156bd0818cfdc333bbe60ccc9e4fae124f2e07941cedf12806a6f608481c54d6de114be264e542ef61b1f4de2144cc35a44e93334bb6c6c7102ed63d090cdde3d18ad3c1b4292b317ff962213e21eb57b9ebf1ff5362be7273a1ab8d78883b3359d3e076fee5da7eaef1b1b7c35f2e6137fb6ee6ad550b55ed654fdf7eb7075dab81ecd649061183624ef7a719884e739e436de1688853288e5c9ed2f6ba3b7fdeb0fbe1faad3104349ba46d06e63831d99e57f60ffe6114f392b14f5e2211ae06d1a56d11e87bdf9cbe981f5358d7fb7be493bf4db1d65d09c0cd21ed7c1246877efbcecb065ef3b5804b1d082476af547c64f51c57b67fad5b1445eced26a01a993b715b11a3bd75f28744b1135448e365ad7c6572fec3c52998f825bf948b4f81ef32c2354718fef7110a3c848eb0e779ed10480aaf1014e80fb77db6ddfbac81b0f9b5a87b1fc9dedda47b27b1547210786f8761d7a587c7b02122561f24f0832df0e9a885636a027ec64dd86ec2d67ac23cc098f00f13d19789f8e62eb5b973d6a7e399eff0bb768a44efb60ac5dc68db1dcb2dd16c3c6381e77536627e6efd285c677b76781bae6f9da6221ddefbc11fd7ffb873ec9b722e847ea391de3fefa6fb6bd08c3e71f71dc987431e865f52c80ee9b7f7ab5f90107a9ed7b2931254c0ff7fb9ed70164e32274ff50f69b7f9d0f8995afb09db45fa49ef973b8e7bab05d9de142c55bd9ba0e47ffccbeb53c9f9f5dad3d0802a9f28080d52936a427fb8861d26baf46b0b63e0b35ec9f83bff00140fe9c0d08f7b1053d6ea6bca022252bbd2b8b60afdc0dfa317623f67b26b71cc482bd05ca7dc6092879cd42170f6fa4570da6e6e287833f7839115e383020444e84d56c6b9407f6dfbb1424411f6edc44afd10f77beba17bd67d52d54c6c5ef70b81966e6f8c34a9dd5d120da9ed4cc8afc2f5d77431f341ed0d523b844657f85c976fb32939729abb4d2c8c1882934fddcf556aadfb5ef08933e8504695f1826044acfc2d80d1de879b9b58e45cf9471496ff3816a1535971ffde0b4e3e8cca237f8df75e376babfb06357f021efcd638dd2a7498d9f80b98cddf76ab1b161c90b37fd9958367ec5b916ee46f257864d7f4601138363d2fdfc47477bc993fbc42851467a7aefdf215b9e5bde775c6b0b722c1f271849ceefb71d5ea57c1dc2f32734c68ef7e89db6f5708429bb3d6f70471c6f753fb965d8f92e2700c16f063e85c0763ff08f6939eb68b93d3abf9334cced6af414e782d8537763ee7665962840281068006d3b382d3c8f7bcf7b9e01756fd79731473ab10bb6ec649a0eb608b71f5c3912b822162ae373bc2576d8615d807e033eee27a4bb2b94c6b8e0423b9dab7db7a2c72b1a1c1683dee46b2f0a7a86c43d9752d10ee5178e2fd123eb9a53f1d75b50b81d7dfd96df25d52ff6d53a2525eedd06776c3f2112969d31afb4effda5ef034ad07c23d4fc6b6d56ba391efefb551375a80de7bd964efbdb79d794971c83d676a030eb9ae9ef75078e3d49fdb03b5dd5d0be4dfcdd50c5865d16694350e3cd30a710396f5421925e55894174099cfd3ca2d5c6d809c92df223e576e61cdb17a648bf13eab0d53d202efbd6090ab99e4f1f51bf278aba2ef01a1fd218583df0fc55bc80343ff80a8c1ad20695df7229215e89ed6c6df4052a0696539e86683ecbbe98d1337b449d52ec33dd3b6ecec8dc481f8b4d8f3d706dcec758dbf3dfbb04ce6838a3f608cbd887b7d1e10fefdbba367e24ffd31cc3bd2a587c419afe7784b99b5c3a08d67e404a4803e01ac87244721671375097b833573a1ed305087753f69a1eb437fea2005bd463d0fbf300c3c4617a67fba70bf81071396aca1d44043f7da1bd40993bc80870d6c9b28fef052060c3e80590194deaf08247e50b2b3dcf440c88b9d6096b743fa27364068ebdb59a1647f64ae078cbe7d346a5780125c11e7d77e068b21cd672d041c766afe0c68f49dc2a88be0b79d2819fdd9e90681f24df7b6847f78edb2f0245382d9207ab72cf94ddd91808598154c00d1ddc55208a89b2f53bd4f369cb941b6996cafd6ca6f24487b2fa42d4a02f9e30e541709c9ef257ffa4729129e360fab4eafa3099bb90b0265c71528bfc9165a5032233555c5c4745f828436589a48327bf6bc8fa4dc6605fd408a5526c44adb85fa47741c89a16e2ec6af816f7e820f2f20a34603bddf890279c9aeb4f01376a507e9f588bdfefc4a0aa61087235034780a7c09e1b8d3e7d0bbdeca1ff9560a59fa4f55c19d29fb39e9de6bc6fed14abdc871f870b540c925ebddf17b7dcfeb4d0d065bf037087199e592c3ed7e3ddc4172b8b77f3d5cfb19718ed4fd794ee4f15f54f9fa404d1bfb17ba2ebc64eed3233b6a24fbb9f69304f83dee4d2c39865f8ad2c110a2ae631b906de89f115740e62bc432367771bffb230422e475544f1208f2f9942dfbdec7a409ccf8a6ea63734aa865ca7a3a92917ff273ceeefbc64377e886b191f84728f9f95cc1d1db95ec56e8511e7146fe92e0df8de7aa52df2fca4488557ddf49700988d143d0f3dd16f26019bfbc0bff7e967f5bd6d3ccbe7bde13bff248b42721c317a4684e9087184dc94772466ed2faa54492e2604c4e4527df8bd53dabe2cf0d0343baff4b0d4c4293d408bf6a62995ad687b88d98400f09025d8ffe5ff6deac3b755dd91ffd403006989e719f24611ce338841042c85b5a8c319d319d3ffd1daa5fb923c99c6befb3ffe79cdbac8735832dc96a4bd5feeafb17d55902bab020f7d8bc7df9d95fa426bd0bb2daa9d938dbd65d9988514122469de10251ce24a413a0e0bf29fad3071383dd8b20e68ceb179b992e6af1e1dbf5bc0233b420f3e722773b0ffd177d39c7f9cbf95a86b4857a0ea101e48b5a7da1e4028173363385bb87b22d9caddc9361468c8d905c8a273b147377e1d5736247870dd866d6bd230f27799f5cac1dba58cd58fa5ee1eadc0e882b7cf0650c6b498e5aee70c0cc35f41dbc44c9ad75ac4259410bfea6ca2d29dea1ce7957fdc796fcb65f715a79bf5e3596a82ea28522d5c7ac2ed962ad5b78e1f38e80d7e10ef07fb41d91b2dd0e17dff9a9252dd8e39ec63bcf2d981b695edeeccafd4e165684aebada1e5c5c88dbc39d13702f6f42ef93e375d868c05e3444a2ee1fd74ef99aaf3e20927678ac262a57c275ae32d4c4a4783c1f591dd53814c550e5cb5dec5cf3a3e713b8a4f4d1db02c01bf95d7ffa998d4d1fec243f793fe30b2c96768fe4ef06f02a65a8c392e711e78a0acd9a154a4c34a100fe4dff9c975c7d93f9a22bc35544e80dcee2848dfc8bfd6a28c4886c15eaae6c8b58be97375254e50b91b51d4b0bd52de5927b8f5bf07cb9b428c8b92e8d2df456cb8b43057cf6715df8b79af3ebcacce8135cf2a3de1dc8d5ce935b68c3b0eceea6622158b66c8b402d083b6ea5bec86410322cd94f9d79d59d59935b15567a8fe3396d9f1dec57ba2ecf0e53522d353a67cdebac7b93f24a8a4def897fcc931f7e8f0c88fa871ec40679afed109cdab8420a6cba88cfbda916392fbd47a0ad62febb4c634b442eddca14f7ee3a7122a1284cb0357bcd8699dd1eb5455fbdf4b4fc72c48f5a2f61ba2c21a615b6b3929f8aeea7392e7f8a2567c4bac0817db221250566b25822a2a9699a445a1be66d536f098b46d517c18a18ab19bcd477a466300359c1cc0dc30bc6b4c77de5468ceed322ed8cf2b2f38a0bc367b89318b851ee09a1ae552f117ef58c1e600bef6798c7d388dce9cdadac9d740fa23e9dd34bff28bb6bac3a28fe619d6ef94c24407a8a710bbed8b3264c2123a3496cdbb80a00d651bceb41ebf9bb4dd034fa449119574433544bcaf9ab1e8f8fb4abf5a6e9639ff4294b19e529cc8d86b0717c3735f2d9424c1717a7f07c47f2a2d5ed25346e2e559366d0b21b8b6bad83284ff5be0b0af7cbc283d661e6175e3c316958e745a6dd3647c3432a3cdebe21ad15a87757afb24334f486b300d8fb5916d27004474ff9cf94215b94c362bc731313b050c13665685c7db12da644baad3c779974ae95f7dfdfcd7feddc0641275d27df39079dbb2f748eaebfc534dfab88d09ecc37eac85caa0f6cd06a705ba0d2e3509efd9ffd054a6641d0f14cd69afe0bfe0208efb7ab0b7d5a2249b7e25e3ed209542f2724d29ae2ffeb0bdc00e40ebb6506636ad377cb4361234790dd22ede1cd144014814f086fbd98626f4d778e53d9968553d9c34d6e80f1191d9af0a83f3609107c0c650f6e4b1cf21318d071d47498b1d06c283c5ac4acb91bc02fecab9ce83ebe1babc32ff26d4f83b26cc084d400f0f477f2a069c255a1da2877cfef8f66916e248420d94a6f083dff856cac9f732f81c7afa9b8c558393c637b2cc4b44bea2175979f410b6a32d3c097110c74a40abdafede9fb44dac27c2ea1816913bca61b7e11d413868d7b5b815d5bd0a921d763f50cecfbe99c9e4daa7546d55ab0ade42be93ec5ee815cad7b25d0cd69159b6c6270351f560967732aece23539d5c70447b5925bca50f2b689683f59179a00f16ad4e17d01bfef39008bb396dfca45ebbf2554db9cfb74127a14151c1eececb06b42d16f05e40f4051999ab1fc14e2de58b8448b79cb13b199b602760dcab47088993c73c8f7e64eb328bedc05f04d38336bb2fa2ccff475b709b06aa47b7ea2d8b1858ce9d08909ffac10271733e0f0818e97b80001790554551fc17acfeaea9523d4b1e7ad6e313e4b386f249a611b16ae124f063086e0e9ea99ee9733ab64c23e08d56295806f270c66fc5d71da6c3198275f16af6bb609e75865f08920b86415c77c7d1af877e4a3336ea375cba26ca47ed6dbc6b86852efaca58ce0b49c136d4e29796ca1fd49124940d2040635def0bfed84e651cfdaecec08772a3139c244b8e2d0c735fe1dedf0efac7b71c807c40accf0984945cf4599a6a6f7924317f140fc26828e217c42e0549e5c62dac7cda77226d63c5d4b3510805c20698c11513a0e3123f41193e519ef33312df0dac216f94d864e27dbddca2d29426fdeebcb9c75ec7db91c9477928c5e5094aea417c07ab32043e0d89017bacfc43bfdbfc441a531622418b5dae594e6cac930d5c715c6ab299dc1f194f81e32b10f751376126fb3dc42e30d025fdd26e133cb41c1bb6949ae47770f1d128127a10a177926a6c44cccad2fbddc8b2f966b0b52a94b94f6f6df944a8742ad55159216dcd062de829a4918ecdcf22f9afe39483ee02821b2aa8f1db6c7a4be047bb0c76fbdce142656c31eb8acc858f56e746e89b8321c10382375e5c230158a5366397935e101f3923f867ee39bab2527e5f88bdf64abfecdaec25a8dd499d23dca8088fe777668a70aec501df6d3830454d4b045832c648718add1f9d10e66620ae1b7088c5dff7f8b71cc8c25dd105d39ef028e001668dce51e0a8d2b2814a90517bae14269d1491d63790d032a1af69688827f275fc6b1cafe4f7e8dca50de1a7b60817fdf214fd6818ee07a363c812f19dc69dcab5f9860c081c4ffd4e2eb96b181c870006b06b46f8fad0eae3763f9833d19018047d5f1c9003cd277ef7d97383c5335e8a1ded5fa691356e32a7ee943607665ab50a49d1679a72216e5c87a4f8a47bd13e8c208fcae70b6c42007928762bc425148314cacaed7776ff95d19f23b1bbf927087b77681feaebdcd298dda2de7379ebea267c07c3a31293d33295da10fccbbb718c710ed989c9721748b54b414e7edca8468fc56ce1b07e6b22ebd9ca3cd809df4a02f634e72058dc6eb7a6b976df1f4a089e86429e73bb04fdece66972195d39b25e73513df58bc68e073f93eeddfca572ad4f57ba19b1d79940b40ca201e0cc8cc2f0b59be483123d1fcf985fe0666def3bbeee4945e3c3d970f524c295ef2e953ff3da1e78f2ff4373d7fdc93e1684c2f1e02593e4931463cc2c39c3e329a2117857ee42b6a7ea1a8b8a79eb5b0bb50d4d2568b30272936925fae29be71a13ef07649b8c4e95b8f1c30f8ada73e754b73b45b916fbae81cef2a92305c4aa8d8958f9ac72a49f4b12be7c49075f0b62d5ff00b6fdba8dac2cb26aab6f865532ea8470d72967c6f4bdf77af18962a6f87f34fdb4105728f80ae71c4815d1e79f0bf6e021ce82d80ce689f6866a4ae8c5e6ea3dcf15981e381cf82192966295cfa03ee9008920eccb25b5e48f5e849cee65cce5c261a4bfa7e439da1e687c666b49fc3833fa28bca6a9a17767d82971022909ee2dd002636c470402577e0aa47aaea1efb4b08c273796ea89c0f86aeaccb9da8112b926da0b84dd73e459b1aea60b01bdc14a2a4c9d81540141f355af9e62e0d0090c5a0ecf49b5c9628014ddcd762419d8e16250875ac4ddc673f0dfd8d6305d50fc8764abfb9baf27183eaa57204399abf7fd5649ee1d07357de29d54e0cda9bef976991cb764319063f2b08f6454be85bcee32335783825287f6715706004b9319c03527bea551d44e6c3b80e7e57177bcb2e9436c2b0ea05e6cc4f5075aedcc9b7488ffc497294c08d09a3e19fe87bcc14f574a0cd5ff0c89acb58e63c9defaf6d0ea483c4453b8c71377336ae464d6ac9cbc0a79a357dddf47790ad1e2e28ba073c86730c5c023a38ec072c84547aa40e2bd1fadca49c8d754bd9f046fe0a5c6f07e826dd417924cc4855556eb5373ed8cbb12f43ffdab2ba90082a77ab739bfd2dd3b359a7cc957c38a17977aae00427fa1dd9c89e58f4e7840a7946eb18734c54ea03ba78bee6bc2ad35c1147a88f0edca0f3651a4052cadf264bf8d8a75f9bad25ae8e9d0496fb9872dea9aee44466c84a35ee22c8249655f46d231117376ec37ba62dab1d0ebc6bb3e2e95b8d2e374512fdb82d5b0b9046ffd8a3602e24f95dcb574d7257b26770501ecd12a01c61e70c5592585f79bd35094e861c69325e95bd16b23fa25afbe0800c2fb4941ccb99be6e2eb2d740ea806113ff8e7483ca901e4a515317d9abe59baa274d7548e192b5c5c3e00f5204b08ad3c1417c6adee66c980b9afd31f31f44fac9cb00c7a02247b8bd7ae735e7c5f1a7e98120874483001495df2bad602d86bc004c98f1016a6a4d1862c4b48f520533a5bb537061b82d27be4d15f9a5c732574fe534f1ed67d91591fa2a7f8a83bacd1e93b135545fba8b7bf5582c1f52f9fd6fe54fea0d98726bcdd4dacf399e504c5aa55bf80ac53d22ad36967cc0928b25ecc770adcfeecd203dcbb3f24c9815b9ce397088c9c167a7a33b6e27a28d996be86961f47543376943d3f25433c4c586169ad4e51ba223976be763beb7743b2a6d67a8b979e3aa9de54916dbc149cd776839ff271d9a770a1d12b601708fec9e3fc9b63ce674196f57216aac58cc820f5eb56c608192eee9a53a83a422ba27ad0130280615a098c014e6f3435f9ae38605a51c7955dac2fae020f5211c1749a2214e779bf8f5ed6b45e777732b9bf040245041b8dd28b00267f8d20d37708e9db44b37c0c95b128218195d2e104b80cb6521d1bbba035415ddebe4647cab05b151280bf7fafec84bf4c4337bc205bbccb46746e2585cbed2a7e5031263bfa8e15a15345c8fcc306ea0311b2deee0fd9c5d1c7bb07eb30d12caf10de1c3797588c0f3d1864c5ce27d157308b642581632413541b3de895323db88c9b9b98eb8209c16e2e567c70d2ca90d0030bc72583d4ddd52423556e905cbece67be6edc48a9525865e83b435215c3edbeb65725ca5edfc978dff7fd5a604b8a9862d1e46c8a1a72bcedfb006a730a2907fb38bd92e35d95b37f15451855b71238f729d1bf83deb26d956934e5d71e8a4cdba111ce0189b00972094b25d2ab153480e213fabb3e276fedaf71212cb1cd53e36d16f9ffb6d96f3cce634242f80a76497da62f241fcce678f062fb7cbbcfe6cb96452f9e6e742a3f31c44d02d2a88df7f5510d3748047658ead1e4337be305851ccffd6c00f4c9aed44614c4ecaaf36f42d6ff3b4f3af1f84aef0712cf47ab74cd9b228f7c24f144a07fdbec890adaf3efd51b6844b218fac10ac34733b75cff0e3ebb59be7990359679b076b4212f5b32fcf609fc7c8fdf14649abc82d9ccc0d5f896247bf04d85407e2dfacbe2215cc740f3d06603310225e57891a83554667529400385b3827faa52afa3821f7e1706b3898d0ad84b98c4c33a9685292866ce72e8750f2aebe601627fd6b72d40485c991232b39c01f5be49fccccd60840702a486f312bcdad4c5ee9301277b7d0a0dbcd69d5d798917109147e5ab9680aafb62939d8615568ca2cc64bedca0638a074adf6f18dbe4a3e1afca5b0e3e8eeb2b41b917fb57ad55faca8157f92e737ea38398722bd091c611f311ded98bdd2eb3cb5c8ddf45deedb67f74337f182c8b3f6e14596af34add5a0487caaf22883d5b7e0500eb7b1b61298d6240791ea5df569fe29801f0f9c39a1e399e466221e3dfaa5fa21a701a0857e2e959803ace08f829bb92dd456754a6c292951ae9be71da4d5713857c96cf05d3eaffc6c91f816ad5f4de767252355595ebb1eeca495130c1b783f831863e060c33c0dae622bb9c8446f8091109fabb59b5e63160c6ec4169f9218007ece23e5dfb630cfc045ad1b4e26bb41dde11f614fe273323b27048dc99eee820ba2dc843b74cc9a8b74f49eac9c656e866cd1e819f25ccf686953f1f813629a6f9dacc806043346d6c1253e6a759c74f843bd9b608bc1a1518f1dece9b9ac907467c29303069c367952b15c000a663d91f5fac4e4ecdaa243c951f2167f0e2b1e1e700a276dfa1c67c975d28f9f57296b96f4d081969bfdc59a0997e9ea9d9315701bb4cce65a16fdfac6c1cd358b60328b4036d2dee0e15bbf6c3d54bdef2f4d9cca231b7e39b226902b848c4debfb41d25d9e30fb04a2931b8a4d4cc948738460d3de5a4bf2ce69c83a1c6f871b341c3245758539202b36945b9bf49a4308bb99faf487af99217f0b2171bc61613131c79f392870bd2f9ae3935d532200a83525365eb03dfe991cfd9559459ebc5983f3f89cb8ad3d355d521ef2262536f87abfa64f897957e64442f65b4e716df4d8d577cbf15ce99e6fcbca15f7b09705f6e12de71073650160559601fcff050cdf1fc9355b309ebcfd72d1b2daca2726f18d39c7a25062ae65be143522d4269591e81e00655bc9a84279c190b87798b8056d990fe3394d8fb78a647bcbe169a98a86f122f264a1ddcc530a5b3f6ae05161260745daa902155f55accaad8cc2cc5318aeb92d7941fa29b7ea599987accdc9ad3d728d195fe0f2bd92157279536d5943eb27c99f719b545d0cd18c7904965005f0192006077677f1abc8075ae57c7fbb16ad5e9d24c69dacef7be971217b13adf82b36b4aaab39e76aa83095e5ea1f9dc8fc6dd712f16d4a76122832b17315b10236afb57f4da8ec0efed0ee6256cec2f1db01dbc6894e1e1eaf82ec365852af56e8a041403dcb647c386ce2205b68ec53374a5ba62d2b1c94b765e0d4a4afd639511eaf2c61bdf10d3a15e32f0f93f2d9814f224314ef6e73be110cf459b6c4509fcfbb161912631931892e019b13a17e3ee26012a52eb14c1bf830aca1495fb66f33f9658dc88a21925f8c56694002f90434318ea4b11d2eac117b6b53a20531e2ec5f74f58c833978b88ea9a96260561ff4e81f0b0aa1433880706224baf655ab687fbec848d6734bfbc202008c251c008ff4c5e316fa386a62588819ed6a126f07fa487cd162cfbe1207f0738d402e1e4ed013b8a597f24898bde8a0744f6fb9d8c840946b95b079130ffa67ac73829c5065d29d9cd445ef08a78a55ad97f6892816f58d6fcf152bbadbe8f08a02fc5e50441ce044f442cc5e1d895aa0a48c07e589f07aa3f2418a658f0d038d986df953b60cd85d1634d714827ebf63af7766a6c143186b971a56b889ed8c39865b5fefc2cc2e3b1c8ec38b83f4a7394632e7489f62fa2473dc66e6d118f21d9f0b51aa2042aa7d7bdd05b30b6d0ff3a6fcd1c41fdce055e71816f6fdaa3e13048532c849ed91ea97b6c5fa24bcacd8a709b0eb518d73a4ec68a1ecc73ebfd4e5237a667a05280631a9062c529f4ddeb57639cf07d7645d5682ef61be0d7671d01f9ecb9493870647384b8622d1078738efb3844fddb7c078e5cb55e39bd8710e8a8a2915c8524d15b6a5bb9670b3f95bc0c1724b6d2d2440f338e2c098bbe57721a66416a84a231f71c0081563967a5f71fc99b7da40a90dc1e5312f4e122f9413594c18d098fa8cd74c859673e6cd721aef33e22dc606b9742a04836ce6dc712838bd4d2e349e08a779ece514f4139fe7061e662e89be8e104f8b29cbc1fa96f33545ad8344d5e489766ae2a3f3d6ede548da332f356bcf5a0d02e43ae664e082dfc33f764b0237943848b4e12071ed6bb6f8d941028e643f84d2244ac3da4351dfb4d941242c9bc570ecc27dbb5e5d6ff0cffc7d9b2a67388c3d6cb162a1c3376a3777b3921f6c074e1481f47bc1b7b657d731f2f1758c3c354e31f1454328427b623e489d9beb5383bcf265f34f7e528b855bbe529a45f5e2c9526b0975617a03a822af164936295e7325d58e2679c3766e8ff8a5ab3d62899b410b093d87350f001675fcebea99b58535389320a73e169f4970cb9f7cd69881de41b420d68f6caca430d34ba78931dc72321689e69853208e2afc2fccc9aa4210537d965198ac300b0eaf524df61d216689f3fd8e8d0c8b4f4281f13f731f63e9b410e9a7073826778b88dd2d22f27298b2f45c745a527e0fc48f5c4575b125b0e76641fb8614df5f5b95f709fd894a0f45f1649ce6455cc144e3b1cab8f6baacb4beb1fbbdc283c6151b9f7c59b3f1d9a75b5ec6c053480ab0e35fb9795a324a398de70bd9e413f4b535917b316fcabe82bd2252cdb2eb47ee2489dfb12688017f64b676b32a9e88cf22037ec756101ed139f7d1b0957d7438e73d9467b3dd728b5024b77b96c238356274e44bf09583e1ebaad14f2070cc47244a1a95c8136f46a0a11b75411ee42041454d614b67ec20f92bb4a9459821e4b80093cc46d68fe420b320807915aa065eaca481177379a646b4e064112aab2bc45ab2de83d51cea818ec28e4a2a786fc4407670c9da563b3261d174ac967ca25c939a3fec951373ae155112dbc7cc07e48cb2c3759352374c907a0e1e41c31009b5763812c3dca9a23fcb566266a0df165e21b48280d6bbfd00b18ccef2c44d689625e46fed4864b138a804dcf8b141700b2e2616793ed920974cfa02a8679841fda086995ccab80a74238f1001eb88eed89cf8b001a6fd38815ce342ad6935810f357fc27178201facde4f45cda69a3fe97f1fd7f5bc3388609a33d65bf0ac02a46a1a55ab0aa8ef048ec1e896a34bfd86f2ecef64bd4561750cab85344bd32634420cad3b16620287a949b662c0a7b4b319b7cddccadda0a012820384a0973d63c6fb89f593db3ae0e203217a670bd8989bfb4c7d8056ec748b1c26606f86018cb7a83b048f3e83d319296dd6f78d90e1d789abeff7124a66fb72574d5898e499214f2d46516913067552de15761b5211c3119f814634cc82fc101c671f8eb4775e8f470647d1b3d08880c9d3a4e4e9e611e9a23862782e0332cc4c56afe40846f7d7fa55138b8dc433b0dc2e9b02291ddb4e0993b362d04d5e937562b25d6fa17063ea099e2f543200aede18230d5dab2704e7246b5639da23e1742d21762a53e08b8ee476ee3dfad70de04d72693288770c4d316dac2cd7d324a2a4295617aaebfd49ef06eb1e812301e7c86fc6909e0e4d8acdfcea2efb184e5cc58bc5967d47836d2f276ddd97676248d98a7cd96758876a46029112bd0a29f50b680db4b3be7801b31979c0842e357d22a03ef1094f15dd8389103370fd1b06772c3de5bcfd8c2a277bd2ab5c2dc924c582309b3524f84ac2c23d5f2629fff4d1e2947a7a34efc8f12e3e3909eb6c6de00ce84b8eb2286c01a4943cf8ec60cbf240d9d1097ed2b30e6d7ca7f2d1a7b436ab80d3d6612d465da997814851bdc92982ea9c5076aa85501c9e1a38c24a03990d577bf2ad20c46ca4588f1de4acbfa46a1d6157802b324cb2020ab3baeb25ca65abdedfd3917a6ba9b212efdb1e1fbff4239da32c4f8515c8f6a2975e889cc358d88b26677159077d9ac8c6a947524c53053da39e774419d3daf601a430a60794354e3fee002bfaa8eabd1c9d6970f651509a79afecfc5ffc9fa5460c86482c82c9d96df67ba42a125817d614ac81816f1ee9449aba50fe7582e1af7bd7c581329bc39f8b22f7178258b1adcd65efe7a29ce752175dbfe0fb48aefbbde80e6713a74897a823b8f88f8db6b9abed5fba9a2b5ac1929af5f7bf4f00f7b139fbb928e7957139518f2ef3f473c98b24daa54b46c0ce331bbf4c556efc6b2e7af9fbac9ae828f5426dbfbe15452a2f74158e4026bb3e7d6ff69d758c6eccdf2ffdf2fdb460442cbbb98d7f69f113ce6dc28d209599dbe7bf0e3e804dd73cbb3f175dc9449c71db5c144ac05f3faf024ed558e74e0055dfc2ff902742e0471a486e228535dd24a06866ccff76386b0f2223e8d614947ed5f1b10be9c519e70c8d75da88e54729780b217d4230cbfe865b28a755e083453fb62fd9df5e47661f39710df2c2cefa8ec188b4b70cd7279cc0c87dfa38cffdb8c9febc9c72cfdb1fd9d7bac3abaf5d96b9c123600f251b4f5800e224801d616e2b836c8e375b335d0a5d1993851450a35d8c3b688d1079132cc8681f83e58af8c871e9439c64238c7874107947a7f44508001f730d59f112c36fbdc924b1fd0c7e34467a51afc67407edd7622cf73139bfb8192e2ba8c002a8f4cc0bf71d391f9d105020a6970456c6b8bdead415e57d05e84b835bc7b9f0c1bb8e3adc15ff151de474fcd50592fbb5a1073399ed9c57d9a9978cf017959be6ca209d7b62f5afa6bd35a3b23cc18b6a92cae5b4c77e88e71020975595101dfa7ee11b576d3688bbb1781156c59add3fd5ec90f463f12a6daacc8990b52ca9479cd10f47b6b8e1f5dc456d6c4e5edd5d95924222919a17ffa11b757202b678f9f75534c7b19c7fa8e7a31eef8f2a7bc9433a87ffd1cff5ba24ccc71fbc8336a54156b1d2f9c3a1a9ed31c2648f9daa4c98c8eef4a7aeb630d3bc070ff921067faad74098bf95ecd34b7e52b77faa796af06af056aeaddcec9bd19fa6e78ce919f2662fc52ab902882dfa7d63801b4ab6062900b1420ba8aa49156dc127291958932d824977cf0d863740cd136ab6b8347faf7d56f9ad68274a80742b36913ac102424bfa780d09d1aaef65e1b9e7a338d3dbe471002732abf95e781c73e3b562e33134c356f85c781c06281dbbc54faef893b7c5463e6165626e78c3446c5797654b0bf32febc916c046ff963e49913ea9266b644760e5f3105a3b1fdac83f6992fcff739a24c8905b66f24804f9458354d55b20d520354c611d6ffe376a8faa80c49fc4d1e06ffaa3ef532dde2b4b95688e5c6145166759bc56f0bcab5006aa977b579e94e752f57c993db4498df99ef81f2afe18454ca51ec56ac042b8c09a7a55c67f5cd01fd90b9f7e9b15b9a43f7a07a80a3e08f9591811b08dd75b28035b3532873d0b3844d942d96bbac17ba281e89b512da2ec192fbafb3b19ec4812f7e5025aff61a546de0a2715c476f18d47e66495a81dc958bc415eb6724b69e99136c67950bed24fedb7f90684bbbe10eb44f98884a50f51429650f015b646b35029ba90d77e939324a1e454b327091bdcce29169603fcbde9e97e6d2069b8a53ab8bb16029aa6db2a76e106733e8d37ae5e7e03dff8fa6d1c7a8a74ebdbdfc671e02cd61d08ce486292563b622411e7b64159c73f9a18c94c88f7c5f5c3915071effbf056667e78f306861772d4e7c90728db1990fdcec5a72bc78df9f7f960eae1b6b1f55b2d7d09848a93764408d82bb37eeea4187c718db9b22a4bba339cd4e0f1ae0c759695bbf41c00d5e87d07be7fd8428b3b82e83679a6a290b1129450cfcbea0df4179650f74842457179ad1a278373ca96d848a0ca2fd47693f8399337c77bd6d01c6832760521b44e8932135ac38a4117dc079c559dbbf250a8fbdd07a815619a0e5d7ee30a8bddc4771f654b34e5ed22bccd7a514a7bb106e614f7620d0c4b74a356bd29cc3fd643bda9c22ae855990acba9e3bc7d2c4fd9ea7cefdfe95058bb7c1fb76423bf11a72ed49fa59a597ed563a10b273adb08cfc4440d79b2dde6c1260a528521e6bd42eea2f7813ab47857357533136e26a4e862cb933cd2e18adb69733b356ea7dbd4837faecbe5dee4a02f4db5a32e83b97f313469a35b8c8a9dc5d867bc01f7724de9374da6f39baa260ebd6913afa77a5769e120ac6a11c0ae8345dc5329b19011feb00e68a49e60059ba2e7264dcc0f48b57ece95b585bd455374821b521746ea75f2a7ef4085851851674f919162d62635a959c1d6905dba67ace71c44ce1e9e94d3688fd393fcae87bae6cdd8bf2f3b64a9a7e809ab9c403423012142121cf287b8253c34316c719878dcd25deaca732e0189795f9e0ad3ccea6fd62ea51b3e90a3833aca4c3f408bf210c9f33a175131bac0793ecba4e629a35060bf7693702f860e52c74281eada85809e1acf55bd50a0b676293b2d0ab8e577b5d2b43135bdad641391a6c392643f45a21cece69ce2c73b074e1f4d138de4e1ec3a046685e5883c453f5c0097a52939ac2716a7050fd59cb1820e49ca46429b15d63ca6b2e37de6ae4f37349b6ed02f0b6914371d0e706d178610fc0f0fa1848b6b7ab81a42f787217070c55e764970641f7bda8326d43ffce9be5ed47a2f94b9008557ba02e632b90356073be78047190244b0c71570fe2ce8fa496f4ddd7f2d4f44efadb44b6230ac34a4bf724bac30c19b3cee2ab7b9347373a98f837a2e27f8d58f8478f6c82f6f28633eb997eaa61e0718707ac11ee7f0702b1f7aa2efc9ce9c9d6c34d3360c808d7c464c3bd359fb0e5eb5a0b38a35d74bc01c8fea3504a65d1a264be8767a33d9fa54796c52acbce79e0b7769e01aaef0fe09ce59bda1181ca99ebe7bbb05201597c3af92796f34ccd489756a9788fd7916e18a4d8996507747045892235dbf854d356ceedceb45314379e1842fed1fdf564376d5f9e16d240f90c9eb1c3d935fed48ce41315f13f29aaf5a918d8ecccdf7e7f57cd75a4c4a5bbdc214961df17596272b57772973956d519530302e155ca23c95a47645f1952cdca169b036d670ece7d692e8f5068be604e425087c9f2f76e974d635ead6145e2c1b3c75b749514744329049617d1927114d5f737817bbde267be8c9930765d979ee40814a66ce7b300bfcaee23bd06aa69ef01dc844f60277a019346dcd633eb1c9ccf4ab902b0e840ea9ee6bc0a3726b0d93f55d1112d55b25b8b7bb245d5a9c49167e384eadaec7faf981f015e3486ef214bdf0763a22c5c6f9785b7684799fffad0958fa1ba1820e328525dd4d067b782606b1d898187eab6c0bf32c2f8c9d10533f847b39727ac298c34f0e28e01cd107ebf89cce812d42f9558bc9b03e63ef00ca8b1aabb3bc187659899e20d6f79d35a6bcff9c902296cddcfed3eccaaac17b85fabb8e7958f55eb24ef65716f2d021e6c8ae7658cd1b9203f2dda13448fcbd847d6ec3252baa32704632381a8b6acb121ebc3fe486a83e1a0ccc995d28ee6a85683a7dbab57453c5d2539cb70f055193466a270024eb950327218446bbd10cf39bcc37af42877e9ba1ecf202ece95ff57004219d56e638b17bf6028e28b1ef475dce4f5a2c5f4b2ba66362dd34abf64ffc57b4d07cbe03496527d733048c5d5a198b64830bb961c619afe68abd50d191cf78ebc2b57379c0b60ff06f8ea694df55a517caee2593fb87ec7378457489cf7598e8dee689ae3538f05df90325b5c23f9143a702d0da224d74fe059a787b4513470592b8f90b491cff6b1471c71431257e8e78fa85cafd67e959e3f41bdde280df5750de9101c2c5f478d6cb851a1a478e5ac1bf74f06da110ab928cecbf4cc75c11a9e7c6f1f6574a32fceae05bb328cc23d438257839bbe1964c36304b91f50fc5d82b9b4c3994d0fa448c3703d2ec542ac6235fc1a3a0149016a3c7efa1d99a54688b9a9e5a84395e484cd6580b8ea606ad30b3368754db26d7e36e6f05ebf0f4407c60eff1b59c38b2ab490f5fa39a8a3da34cf14491c0a64b597c29805effdf118154dba34daccf5a3e1acdde15efb3bf3e8675206ce0180ef2c7d0fcdf7b0ce7ffff31fc6f3f86c19f8fa1fbb5a801af89104ee29fcf62e544891cc9303fc13dc442df0e1aee969f1d4a4ba8e70e3e32899724803849e4bdfeed0aab223746fee8884f2d27dc1326a672f5897d53219f8797c271800ec04e7400d39bd2c6cdbc0b0d84a8b8b5a35dce9201f9a83f32586a39344c12b4a0c4a0c899273a9d6a18ecf52a980f889857a33a37786a24b9f3ba00544dd3329b3034db49e3bf951c21742f8415645dcb27a573343fd72e8e9202bc160d348aeb3a1144c940fac08448ff7f4bda069bb6177b23c5f47eb2fbccd5c751b3fe50df166adb2b5645f1de5f3f6d0bb54eaa1e3e73c5511567f2f05b55ffaa6a2fd761f587aa50f3301f576b7392305e9a21eb7863c4418f2e4d46964b15480b5878487bf4a0cfeaa5d707093a872e416748565159ac244002a0974cb43eb0ee7adf639381b2c964a044e3a56c8abe68c06fc12ec5a4877ba0068f381f79cd07f4e73da49ca2bfa90161375fb2a2fca80efd4aed05a59bf4d36dbc90458c3f686e4a7d384ec4695d2bc9413b6c90bdbd6bde2f6b03c2adecd3c01b32c67d68118acc08eebc0ed2f9bbf48c7e25162f676fa69352cf192c167dfcdde817678547d0bb29ce8af5afcf4afd050437ffcbde533f9ddd13d4817f9c09dbcfcf4468ddaf6a034d163ab77d80ff18d802c75c941f8df3eefbe23714c577d8c2b4573bf2f615eb527e806ab05d70247f858df3d8b3d49f33c11e5370f11de196f50fecbeb2e29eebf758736f8ed0d46c8e4627b2718ccfe4114e1b9b2d7347f8881e08b4f4b195056edf6fbf082d6a4f46213a4cf7c88a33854cd30c8a33776642b4f9c2c5ecb12fd7f5fbbd7e6fb1763820ebf5f1eefea4afe68345f3fa5e09359d725ffee9c1aac9e216ea8913935c4cada3f74e5f5410fa999f31f3b68e05ff7543714bd71b24296f098b8fcb89ccf6f1cdfda636287f8a8dea0351a68e3db2fd994c3cfd3c1a0e569d433961cf6b30301fa92dfb8bb47187ab9e518fd2e11016cf75117e0bbd97480b7e1ca8ef7eef7157d3b77ae306ebd0cc1ff421324ffd72b2bfbe1fec4bb2e3ff4ceeac87d4ddff2e22de40c035f98e9a37df28447571feb6dbd5cdbad44fd3e53867e35b98c0af942157267ccae8014c9acc12f0c90050989d2729eaab97cdc1f5fe38b2763accf4d6b9ca0481c10489aa5fd39f5c752bd75ffd3755b72b502362c5c2c1fdbea6b7cd69402bf6d9ce564cff73d910895e833e55f63fac9dfe5b174b16f29c23d16780c0bae5ead55226b78c45c010bdbbb9f18f5734fb81af9a67c4309fd997f3f705f68c6fa68013f0059cf33ebfc8e7f9b782ffa59d5062e6700dc393cd7e96364da1f224400d7eda29c2ae1236925acb7a6cfebb9b2669c7122a569566efdfdd3db976ea2a190cbde4f5fbad3ff9fd2b9c4332bd56e6736ad3ca3a6d0e4523ffa9e8f6fe501b9447627fd767f32048e1d7df6fcb65ea5d7190d87129254eaecb7fc60f9cae6e494d01e9a2cc48f676787faa0dcaefa231ea83a7aef029e2915a5bfe774396ef09b876db6b59f929b0be8f62630a8b041633198575d107a61f255024a9999122b1c95eba33cb1c5163fa3d0f1115ff89313b2f59369e451242bd054e8f83737e61dfe5e45e68caa675fda5dd8554990b195e90cd119f6e7e3b4e852e5da09d5911ffa1d9d544e7a1beaeefa88403a32a430007385cf10ffd803bc2dffa410bc7b8bfc3cbce243becb195f9b3b0150ba6a1a141a850cfbff6defcca4fe7c84388e930ac21b6834aaaad5ce2fd2711ab0963d78d3a50b19a870a061eb2758dd1ec8807d2ddd7b26f1d0c80d92a219aab4ec679e11e2d326bf693419b3ef97df4496ba13f6b0975dbfb8f77ce5c8335ad33266b851dbbaf4b43dc94256eec52ea9317a2b12422f496544b963e88f21f7138958d511b942db19edc376a83f2abd80ffb5077c18b42cfcf08fe95360df4fdea30b6176cd85cf4087f4a17ece41206e78a7693a2f31e794368a6915eb0bf117b9299373f9cc0dd9edaf80c693a95af0e98574456ce22fcb2f7b426662c9307648a644fb5d49f296132f72854a84dfdd6525a8fb840037ee96955ea92d728a831c412e1e5ea48cfa13a18d750f3d58f6065dbdc6438ab30be1bdf4e3f5d912352041932e975e26496f09e558bb1f9b4c8f19736b28ffd2eca46845138dabf02e670bef879b2e00fe92e714a83c7b22bfc11fbb474185c0f0cb4f3f19f922cfe24959a49e0690fa2e62f928495f2e1a6ffad4c32a534624b657fdbd845bfb59994b4284e957ca47e69b9fc5d1eb00209f6b2ad9e83381ff87b88385682d424562cfd8263cb0191a7134198a40efb356d18d77f47379bf991b9e32e0837b3b763074f9f7e5222308b956eb65fbf29bbc2ae20aa9315fb130f209cbeac3491a2b7847f295c66a33ed820600b85b49d0995ca171e73c2671a7689022e2ab23c133d8fbecf892b5baafc2a7a6d957b745d368371d0cf3f45727dd36ff54514645c7688b59e66052c44b2ab76e129a0f466df8b7d703bb65067f57dd8965016e7b3018ecc44747b5d1934f2b18ab548ef1dcb97cd28e7d13bd28f873c0875be7ab96cf6ca9f62677e419af58e895fcb0dfbc624febde21d6932a4b1236766f8a5cfe1dc1fcada0eea4ccfbb41beb5ecb0851c317c22dfce4cf5b61c9547622399798ceeca69527c6c834408e9be4092b68991d19b18f0d74085018f65dd64e791c61928a62e0bef26d731e1b453a659c5b0f8d83534b7a21e3cadefb25fc2e15fb18b0dc95fa69fc2211bce3388f638a2e8fbfb5adab791500f9cd590731c38849eb33bdc9447fa129f2690df5de650fe1f31600b9088353d9cd87c2e5538e5dc9edce226a797b2232e0adea4efadf94d0686d5bedce4b8d188b36fb76e884bd31cc7569d55e76c16dadbb708cc8db21e3abe6a5dbddeeca1fcefd273b32baf0be88b7b4c004c5361b1ea1d1e6056304ffc1969ba2da14c8a6b835bfd5636eff33d245c00d5947e78932fe4ff5868bb03d10df23046f633ff3d12eab1c57057658b53b493de2f81ff4cea9de183ba59b1a4ae9f6d57d01f1ef874b6c71c3243aaf066e2b3bd0a8194504ecc14a1dc7e33302cd52246961345398ecf7b90854d2b891dd6fcc48620786ed288c5e1637924061db9aed1a71e571c81b723b437f5740e68a29f92e7fba326586a1ce3f9735adea0d4fc37194da8ace0e1adcf064038ab246c9a8f3bd6c232568d89dfea6eb183f771c4d198fa5b8eb05fb2363d4fb7e9e4ce5b0b8e473be9c3fb6c18ac801eaf4857b1aa73b0c8b96db325e794c0467601141af43af4c7fd3d1efcb37e0dcbef2a502fe785592e1a77e7b27601b4042c269e01fcfb06472a04359063b5ad62ed17163b4f93e6ed25aec25a3787c85ac5e327831fdf65f4ff0302e17ee7a65072e65bb4e324cc559a7dcebd41311749da993110805a63c60e2e214a7e7c842ced9e7c554ed35392bbcc03d55bca3382399d53a83f090affe06d9ce2db4bfead7ffdb69a7f1b5cbfade12de11db19327b67e33d7395d304427d1cc0e0fa7c5fe89514895e04bf9add0850b452804e3d0b752552e75fc56cace95aa7129189aba8f6bf59ebbcc6918a71a31a79ca762221262a1de5a1d023ad82102742bdb9d0424999e1f0a0fc6ec9e573793a79d0e1dba05aa07b25b7cbebb7e40e6872d4e4f3db00a8425d56de845a8ab55358b8122ffe8afd6e66700f12cc184794cd22b4e8a03515b79022cc43b69b2e701ffd01de9d3bd2743d41c15bb6c7af2c4590e4918cdbea87c19b03be88a2257ccc78c58d46b9a232cd92c84de3158942d6c3322217d60cef7748b3a460db47ad9b03575fb38e2e275eac5e72ff50a9e1f0126b3e2c76d7e1ce51f9b2f15648e751b3b8e44ab0dca43617de1be27bc5985acd20672cfe86e237c7b370203b042cda88658d4d23493f654207109357e2e44779b0ae4147c42db4c138b08a7de2606ff8675b394923f7977a6a058f3068d1f3af97ac74ebedeb294af1750026b07213a4b04df3995132698321daa97d6856387904bcd21b3b47aa8f1635233dd175e0a072fcda74253c24153d6cbe5906c07eb7a3b3842f52b605486a707ea4002d9bd272bc8a84d87fa2d1e9739a7b4ad490c157d6e73d10325031857481bf0d164ab4a95c1e7d9cb43dd57c16e3bd12393732b5d14bab099fb7784baad428c1f6ed9af3a22534efdd693f3a54df829fa7ebba7bdd424bb80f9586df7cb73294eb055cd65aba6120c63651a0436a6448db25f2b7245522222d5cec06c9538569d5484f6fd0907cf613b79f2e7ad4a4eb6fae0704b3d0d38ca7a055e9a258686d6179347cfc80b755885effeabdebf0c001183951e96305f6ead44d7de97cf9b3506a8947359f534d1f898af68f3d27ef842beed34f4c0e65cbceb1585d28f5b94945019b24d394fc5684595eda71071a24e1738354ee5a4f2da913d426ca7cdda6dee18f90a57af702a57d5c01dda8b52b11a3db68837e93fb598bb33900195d83b0a35e2dd2ad28dadff76855d97247cb9066f9044b5093194c278964b9a00b7fe7b918429fd679fb58553914da446b76b58c54937c2684f1118901d67260c1b14de36aa2c515ef0ff49d1b923f061e1d6016f67f38e7b5a20aed76df2f30678abde867283d88fc9ca1cbb98ead61e17661bdbc4595407854e1497a89d2ed199eb77b87ef72ff5b1566bf56fad95f33fb1568eb00d990c73d734c1c800b4d659f16f7f07d5d23eb0c9f941f1d14c17f78878b16ff3f21f5b5c5b3877492f35bb3512ea3e063cb7dba0b32ea6755e1c66172389fcd538e32618204ddb9272176ec7f8a59d4bd2cefccfed54b99dfa2fed5493763effd84c8d9b69fed24c2d69e6fd5b338e70d71254a35b434cf21904ce39101152115c57d3d7eb355eaf2869c9d68e64b70a2c2de21e0f553303d2c47a7196d32318cae97ed3d3bcc896f9cb68d34b1f8f8539a6b2a14c1e1f363db064703a39e61e0f85f5b135066557587de2a356c6803a02a863c4beea7deabc51d7aa04e96c427d1730d99fef9300734b7c9224f161fb3072f44539cfa3eb1bf1ed1ce657981fb2f352ca82d34323cc4f3e3fac27d5e9321143fdf025b9619223e0577f263d0929a155510941d1278dc21ff8e45d9fc44d135e545bfebd6f9a50e8d8c20c7a5133970472eed3317a9e035d83e6442ca59e0e47586d099b94727cfaf730e0d8369ec909e5eca3800b642698b537c44ebfb436d00e19f0ad76aa75d6b653b0aef9c5c51712681faaa8039c810b9835e794bfc4906b2819860b7027133f720974565e3091c313aeee89dec90ea937f4862d5ee435755356c206f1bd708520ca2f8f4515fba2589116cd7cd821dff027a71939d7a925a7c4600b152055bb65252c0640e6ec149f6c354cac83b07aad397eaf85acdd4c9d9527174cb68f7f21b46b720a579e3a7560c64b685eb2de516e3fe8516ca982b9554b7c3a1942c28378f785edb5215843d5940c71911667de231c16761b17af537100408e8409344622660efc00fe347fae3089c3173bda0dbed43348a914ff5ed7110e05f7d9835dedb6b0f9b079dc25a94ed5516229ae5febb51e8abaf95856c244fe8d184cb07da9679fc96efe3748219cafb8c899295ff2f45c1ff1e4f7b9c0e2a8b6fc8d0624bfb7ab418127f2c169468a97ed9aed487e8757f59a54cf66cf3d4e594576b417bf0a3dff3ab7d334b9a29b631c5e919b3e4c0b644dc3146e0b04483d53bd49744586a8de10910a5be8f3ed1db4fd77a5f8862d0fe4689e7488bc5fee711fe4bb3114e6b317a2894588263ac5263c344188782c0e8ef33d1a51ea653a90783ada707efc44e7b48938aa0926ced79b065ea41b082e8ac33d118ba7b38c560c0619ba05398f2ea9370f9f71177c6e04a69e9f2e7972a1450bf8e98aa78e9e7e7147dd3d532768d7569c16bd99eb364533442e21b0d4474151f33315d657176cdf6e9dd239f725c40f67b3cf5d63db3dc6bacb3f0cf9e13eff30e28787eca1f576e4872ddefd241eb7596f7889b25bee2d8ef8c6c81e5a6f063f2c3169a229abe087336f6122e922f35a262bcacdc488a13e027eb8686172c9dd3f945f507e5d6ef4beb98db98bf341a289526f1e3ab838a41691960c643ec63e62b3b7a61e94e43999bd59b6e42f2f8549d6cfceca93e7200f8853231deccc07d7336bef39fc5fe94d3c3fb8a9ec4d50cd0059f76493276641054c4f7ab4e7908d6592a36c562afd9247ae18fa1b951bae9b1be948ef758f62139d1e18a270ad72c3d9ad41f1365fa9d9f026dd353fb5072f3efb872923a29d54e5413c070b0706fda9be2bc9e73054d70bc198e6fe215db59110a3dc67c7c2f2d57ac75affa950375dbf5f6c853220a8486ef76eb9a8123d49e6714648df0462e927d74d0d9f817e70c1f9138e20a5f68933c19c4b48519d0a885efda76a012c5bf6aac209642a941a70cb9850acaca23dc90a114a763ee8ca636770d5ed4909cec9a3e3470ef2a1bd2161ee074daa2d54ac1a25446f12fc6d7741d433b1ffa77f6e3fb3bfb1269cfb35536956e123d5a22c53e6ad4ff0200b953388b4e1526eef6b79a5a3faca1c3d3961c430f189fa4509faf21f51827ac8bb90501ccdb84143d859335799539451c22c3c77767b8b92fc84fb1f753909bbb05863531ab4219421aff90866a4120e22291f222f9a21af5f18bcc37ee647b2f6f30dfdc2a258c23ccbebe7dc7fd6c77eb1ee74f9ad9025cc971ffb90ea6bb96e85d5797fa9cbf3c0fa5caebb5efed4e9971fd9ad54dfcb75bb57dfa5ba762037154ebf895d0e93b62f3b089998f99e9d7fbcf01037da2e966e71e9202d6d89ade9cbda1417c754a8bb03d213a71f4abe903405537aebeabbc9079396c91aa26adb3e8316d211ef2a3855c2c308d8ef94ced37cc972a2c0756744a8763068c69cea2baa0e60fa546c7160c72936f467ae4417f0a3542141eb52915a1c9150e4ccedc5d51fd4ff86a4e4f3428ce39f8b41f7d59487ca6da135f44ead65e9e016eaeb17332dd875f805a26b3d1ff339f7a15b5a7b76ca0b9cd50ef33846c46d85e7be84599f6cb3b20c5d6677d654f41360d0e3dabb96c89a3967923060c7759cc451a55474876cb56dc83e2cf6e829eb79e0c0ad1376dfc8abfcb9d210117cddde36fe46e04f3559ced2ead59ecbf95427434f9680c0a7a550f5d03cf671d1e99a9519ac103821a5835550fd5459b22a7508617de681f439bbf50008ada061412f39bb4903897268b7fd73033111b5213909799261ab2cf11eca4e30282bf1226218d62618945b7f2e27886047c9adea1336b590c1ca0114f3bb30bfb2bc31ebc3bf3663ca93a7af5f2fc751ac0ef3743eede27ccee33e26144631b0fc9c35681d0dc8247939e13a665fa86d44f7c81744bf719597d78807a9c38ddd60a0d85a070e2bf0cde732aadebb94c01020059ebb9d0ff2e4b785ade6aef38f555b262c8851acc5c4f3b42ed68208db96ff9a52da4a32c6de45070a31163bc4dcfe37db132c667bb6c8b664770808cede92cd4c3d3480dc380dd8c2b5e45c02f9df2c7808c7e3f4758dce0dc17521a43dad1321db57f289bd8f83ed5548343d5bbb05a2966f8b67ad053ab0a6b82c154b5e95dbe281027cf928a052665aeaeecf6dc5f9523fb5650b87b0a842951ec28d0a65a80f61a0fe780a79165e49ceeb01cad5117325fce289149fe585d4c210f00d6355389726e37d24bcea7d7a3c4dbb421e297dd1e05d0eba79ca2c816fc7ec47e18df956f77f32699b9494887d450e44c41877360d09326eafefbe2aa997867801844af947ceb0c4b9bf3cf8c74efd435ebb633665a2eec9d3d3fcfaf9fee01b5da6fb36a1b7793a9a5fd2eb8aeb3557a4fe362a1cbfbf1efc44ced772c905e2ab0271850b1ca02db3b7c7e2e9db8157f94e03da3242b644a201772d365517bf2cec057f38a4c2ea28af0bc6ccbcb6b8a06e95bc8561fa110e7ca5d2a9be1a5a37a579dd9fcba17db3fb13174cc61078377d5c1b6c4370112b12cccc8fc389b5b56b372fdcc1dfc1b9f0db73e1ed92de5a48633d3a9cd48f33296cbda3e966ab27eaf18e5fcc0466469235d8057f9e493e0f1869a21b4c26d61041a3b322e9d7e6c8f53d02231d0f7301ecc52f763adc4fc127e986aa6868bcc5aaa0603d714fdce7c5fdc9f78295a4e0a6c65a16daa4f451e54befc8ba1f12dfe1af48494cd4367d97d3208de0a1cd496c8b5ffa4a324a2e64e2f3f8c18e960dd297aef0ea21498d90a5b134335ffe58719d45a10ed2123ca34eee07d93662e5e7bfb348bb907d81da0e8b6dff5cced23c088d72ceb939c3749414a10994f8ad3c325a687ead1abc56d14f55ba5995fca2cd7eaf11a8a44661f53ac9ea053fadde08ab177c5fbd31566fc7abf7f32765bdd3fb1f5948aac30b79d89bf94a75c66bafe1df85bc7ac0bb2099acffc436a072c5defcb65f8c5eac8c9d9927094aa8af4e403a36689bef36a08184d0ad9eaeb129e001387d89f84ef0c87c2b26bb7800cc52d22de2dec1693bab2201483515cd3c0549985401fadc2c5649941505a29370a8ba43ef9e622ff0f1f608afebe5b29fcadcb14cf47b9871bb30af7a6aa65b999e226ee09721e5b6605b5d9d93ff0363a32a573358c1fd6a170fb6bd00c20f4dc85c7aaab6006651f4afcf48713f0103a7d26bcbabdd43c46763966dd132715b20b486739b422b7293c56154e6e6155009878bce3d6a772ec1263a8cb335d2728d21cfbb347a3c8dcbc6a3f77067661a08a435b00f7837f27740fa5e72d9330c4979b0f5134761cd4d219626f7820a928ec511eb7e6c69b943019dcb22cda0cd79ef870c2ca56f7db79e4b40bd92959df91dc733a7116d05ac40d59d870e76daee427131ef26a0bc1639f9afa4106f1e89172a87a7da54572808c2de205e6e4a41ed62219f083e469fe15b27ecebc1c305b25040bc6aa25457109dc78167262a4fa1aa764a0bd02f9b0529d3572b72d8b71ee33e3445bae02a1b096911cb23d16b106ff4d1a2d1d94d04e34f7e9d2665c80319272ce4a4b6b39ec276dfdbf730256dcac4677aea50ea258546c23ae7f615d1ed592f6b429da5ff7d3735f06812e77753a092c74dec076be3721c0829d94ef8eaa41b0030a10ba5a4e610dd268673a08ad663ceeef292b83f3af62b8117f6bf7511322a2538e288074d21ec5bbdd7d38c10636407e6a0a7b9ecae71b4eac004bf70f285e3127aa45ba848f4edc3982f89fbf25f27a200c35f4281cf9bdcc4a8b6e4c7aff5127cf39b90570fc9630f43aa62cb70b6ebfbb22d4273ac0548b1917ab5edb3a2504258730db2063b2deae57bbb0f76b28a7420d8756e032f9bb4b99bf2829734df4300315970f7be03b77cffe86f3212f6cef97e135cbb7995b194a16d0b900bc95de25fca4d529161db4abd75ee55f6e77cc53f5a4ad8c811b333f0ad3a6bf5aaf8f7756b98e4a92e4f5586e02213c829155e32bb8598068d9f7faff8f73af77b2a54d0dfb147ac6687e84fd60e1ba41e55464e673927729f681f1daf0687ee12a4db573d543a916da4b1b4381bfcb782dbb6551e89a9a74e80ae3d20282f90db5301feef24b77cd273271e383986b938936c78426f9be86d57d60e30a9d70f79cc38e17296b0a5c4b89eeaa8b78021695205ba7c571a1143f7015ddfaeb15b83e793e9dd4df4c389bed84032772a4ffe850b4e4070ddc0daa3d0287785eb987e135c83fb73fd26d7df73bc5a65810e244ae744095de70e3493061abf34b0e50e6cb8035bee005bf7517f18f74e7337b9c07e9848a7d1a4ec258642ded93da1ebd29634e411a92928ce7b2985f9d46a15b5eb57d6b7487246987430bfbc4f27ab608d8b24e3a7a7432958e522d946b8540afaab393147581172bef3d669cf01dda80e73184d8e730669a4386f97b2d05ab1acf97c0d12cd6a7f65707db07b84df919b7678340ae2eb3c2521e75ba960f15a312c2e61cc4849fc62b82e5176f815053247720588aee1bc6691f73c03ebee657c72d2f2af7ae8c93938e75e38bc8c8ebe909bc058199608085c2df80b15b868a55f68245f687243ba3c7d2199ae28f7c2c1b40dc584e00006e20a753995c642de29f3265e9cdafce2cc2f169c974cd3acdd8178a9b7b212c39be3fe06822941236f091fefa5c952e129b2cb23e112822ad9eaad1b0aaa5e2e349b620ef50e7f0e3b0a9ae1a950cfd86e6d7dd3b8cff1ce493c5ad4dd0e0840ee12aa6cf05e077d75b867b994505a923de43228e752b45b62f4dcba0c52b7d6491ba1726ee7a245d6512c5f080401a296e34b877f52e1fa3c6f643090a26498cc759b8458cd302744f9e6b8a7633d6ced393dad07ea4bc94e46fa9a8bf6381d9deb12172a31f4d4652ef37d58932163e4c37d9ad36730782694c28b263bc625cb76ec92ef0beee28208f3001c844c46b1c54a7af27218c02d8518414ab2c68936aab80d2a900deeef71270d21fed35786c6d12dbbc219ec413c9752dfa98e0ffd460528dd73e97fe17a465826985deab123bc84016ffa99a9f38f661c15a805f9e1719c18a5d5b718197583789c34858a0a655c4b634a10cd1ac9733d535d8f889728c9a591e456216c5c6840444831c14a00a60c4160a2d49469dc8b25ba75bc24cf4dd1d92126664580081f82927b5e6e89d4dc966b522851ded3ff3bf4ffb9fae1ffa6286fe8ed929e947afaff977ff0f782feefe88ec7d00a965dd1746ff6a4979fdf71373a527f624f155bf4a106fd7fa5b86369070e263da1e70dfabba4b2924bfadcbc47ade55a68fdf2f734fbd3d675f8db2a1b46cb4c06106503888737cb2dc5cc0a8ee2e3cc7f2b4d4987673aa76feb40a63bc50ec6c856688b613bc7371d1abac601409def94a25cbdb4618f735ac071bda5dc11801e1dbd43746c182a6b9b3de9291bbd799411ac7b930612dfba9516b254b760581a834ea836a7c0e900d6616a1074a4fa68a11a2409d76812397b0d38b55e667dd949bae23f49daa62744f6aefeb797c20c1de83caa67c81dc90138aa94da51d629031db74a6d4979f84f924c5e1322c7a1e2f4b3df5e576b94e7d30c9581f44c6364b9b5161da25dddde8bd1d413bc30190fb55a65c1be7253b632bb0b9d9076ffa2e7a1d55fcbd5190698e69cadb0cb2e9c22e388d4f7c36e24f344ad16803b376a147bd794735cf2549ea3e5849b5462aab75f152af9ea5b25f24dd67ffa698fda077d999967b90abf1776fedc2deffb17feb3dda2183a3352ffefef9b93db033ff72df87140873ff4edf8bd6ff929f8b96f3f4cc1ffa7fa668963ffa86ac6a03c155580ff6ea4817c4eb2cb6e271758195daf45b035b3035de443ddd4f9467372979b7602e86326eef9358ed266039edbad23133472645bd1b24f6a01b5f72832a13f07fe915f252e6fb20098deac62d0818d65a961170a905579079418b75d079f7cc9370e8dd8587f8084ee3f7c6126d6565bb6ce37e5a938593c0d1d907584e7beb2039b8559b35e0ebd1c8913ceae4b1aaa7791160e1517092a9a3d528f55244e7483004904aa709de0f75624179086dc751bf74ef5b16c0a7fa0d9dfc54054f31ff407f7f474af76445afd41a4caae58a8b6dcefa4a6ea1b00bcd66403f04eef5bbebea0dad9ae60574ab2539eb79afb5fdf54e4a14a00c8fb1b064056e08e6399c5d6aeb105670d4ac515ddbca8f2545c6e78deea73dc5a4756e59cc10996a8ee83475034e30bd99e1e4ff08198952d61dcbc543c2d5ab46ee095da802ef3db3d8bd63b1d3ced26975b07e24317a52a92efb27917e5bc6eb1dc192e51c3e323aebcae9e733354a462557d911b2db80a6bd9959c6a1be00d133fe2082933c167f27a1ef2beaeba926e6c441f4c56949a77e6b7c0ad6aa9df6aaa0ebc39ac5d576a264d6ce416c53fa12b2498371edebe2b13c7084e35eb6320aff316adb720f812b5b542eeeeb756f5758fc478f4be0e909c7fdaf2f6a66dc15998928b821371bda68250a6d8d94a9960c97be6bc41839d9e980054eae40f8634694edcf89651952b8cdbf5c4a791349bc963af01f1f584d7b351e169e3e496df353da18f7db6f1d1e43559646c4f9d4e0ca2d4d07d69580f0df07ea2c29371e2dd72e6dd32bf98e95ac0dfea2d2ae9e36ad82c1a6da084fee470a4f1b17a0335e901b12da3138d5b3db5f9138b8b49a7bbc99015786fb1f004bd67527679418e824806403ab0565c7bcdbf49e00b5a7d245c5b42556b6d2e50016cb9d4ee62d2067c80422e697e8fc7d3e8aa18fd08f9e1e18204abc7df7e77c1c506ec64d782886cce99de9eb8c7e7ab8f24ed5f2e267bd0c6fca47aa1268c9ec10ffed6442d6da2ce4f1a17b37c90c2347a4d7ed2bac016d5ceb531d3e42969a483a59eb419848466766d9012cd25463b56f9357d250037a7fcaeda665d4687ccd1c3e144753e248153dd64bd164b2ff6cdbc9d02b238cff59d9bdc68ce539b34929c0f19f1791bc9d0739618c64ab7662390568bcba1fc3a57337dfa4672ce0876ac5c7354ef7787b150ce9ba996845c04949e31605aa9b324043c104095004c2aa13eea5eea90a5068b40663fea7053c10f36b6130a1329393a74cd8b25a1e32ab10568b200d40b64eeb158d1f94ce4f18064b517c1fa60c2867c2bad733f62be88c8a1b69cc01ca6ff538fffee334bd86f079832f4343ea8e44feba183de4cf5f36795fdd904c978df2ec8c8f9314fb21c56c9e720f93d873e2838bb1956d270d32116e0b954cd97f17d3b57a682d418e55761857281c62ea4290e65057b783687e026e6b24e57b36aca438057cd9acabdb285e5a91a5eeda8115fd6b92444d5ef93f4f4ef4ea62dac58b60ebc6e53a16eeba4e312af7a37d842bdf9a0cba305fe7dd5bf5d214635f0714871661f60799a9402054f477d3ff42af0eb1c2fb96e0083c7b8f163ddcd4241bed693d38b7a7cba8966c4486399f53c4693c31e388a4b9788c12782c096cc80184d784a96117d43e74bf39bbdddc9cd15376aead7e28e181926f7ffb37b047b78da432bbebd23da579e0893239d36180b45663f6f0808524c69c77821a3d9500b3b36638414b06b6d35079c16ade74b96c0e98f2b1b5d72b6957e0c0d28156d754819fba6475382351cf1ffee3369827755d60e86f487f91877076557cc9e3b07336ba5461ae71f5a719ec920bd4f5a89e80fc5ad8c9fabdd9c5a93aeeb0026ec396a9ca457652fa73a55b19e1bbf5529c55ca51273953655719f17a50191747fa1d7def9ea78169c4f5ec5e843a1b5a950037828004faacb1a9fe35ab3bee6cb1ed72f5eb62ad08eae5bba2ff6565e5a034692c3e926670968a595bd34a0a634282abd2f3a885d783ff227e6603eedae644676c68cec2b807f4389544aef2c261c371694a6972e87ad40f1452fc890efc3b76bb8018a9b5b5d43fb66b0b487dfe233f9bd9f73cab108f6bda4c06b7b099fccd6d2c2d551ac215e3126b596c9a7f8c534ee727282ae2691c3aedcb2a27a8729da1e726e4c5db9039ec604eee724388383b6d7c332eb9755a05a3b3b2d063b1b950951db8eefd8ebfea4e5e9f1a05dea657605ce32ef1efc7c4e5f9e39f2a350f7c41e391bb009ef20d2a3a3de5ff7a2051f0ecb5b614e6a34fbeaa18ed25608cb875b220761f311d7a0986d1e8938ec3712aac8360ea47bc24c8d505f7dc0c3615c89606d6073da7c859877cda58c9fe3b5cc022c2286f9bfa4f74d3620bd907a40357ccc59f19070374d68480fa20482f5eb90baa42214d3131906d587c1cf2bcd411600fdb438b3edcc6032c803651d837bb91ae882f9f70e3b50b3c9393f52ebf9d083d1699c8026da7ca4bac8d53ad11d00201ad820ec534ee46aa0ed71ba5fe83a11bf57ec70c5262a4e3ab98add5e35d0c4ce1a789e0d93baeed5050b4510e626b3f8c6257392b7abf831eb62abf34e26e1d8572798869cacf8858bc71c794a9bf99d12b8bf085ddca2e3259303a03c1902f4c6dd654f4dc634a6610e232e907e804ef9fa924de130cc17395d7834691132e9d20fe5fdf4d4f4e4815037b6b7b87c9ab0b9b19bc7d80bd9e3692636b71fa54b5fb320af6ba2cce6dd7e9f9e672b9407e279888f983c9687e2516ca869d3aec7b49d45ab43961fd1a2082ed3f22e9a99183eafda03921ae8e67aa9f5b2ab691df0059773cca593f84e168917db6f21d264d174ca2729d4c39c8d179e4c98664b585d55817e6dd60e10f377f228a783e81048aa123171bf6262dc1177dda858d0fc30197036f8f7f578b2a05980ad60732636c95030fa905904310d6ef9a24f57d9153d71609fa74b17d979bc3a49a284cce03e952d31b017b0fd8f34ebbfd0e3f0621634ab107e822a8b99f83d5df3ef4dd5d47d519a44b3fc049cd061c8bff7552db4996f114fd5b2e940964c4319ed3680844735e40418ad2080a8ad5c27dd882190724977851367adf1afcb6a076bcbea0716dd50db3d91af574571c47aa7cbeea353a1bece30fe5bc11193b33c82501faa243ada5bd96452bc68c2aadf6c328734fd07ec9e5957bb137bc93455b1fe811bfe1307482de81bc9165603cc912f23700880d6789d5318e428944668e702e8f09597251258cc65407fa8e484bfd346c3061a75e546a65302bcc87593233e36f237ae332244dc71b85669a0ad304feb3eb574465026fda61d7b906252518d4b2f73ddf5833ebab408993f4aa1f9890fdf325831e6e2f6fa869b520a8b8df5fde63343b967ccf1c3843e5fddca2cd4cd6e81e759c87681f9514d44dd6e4aecdae835415519ea08f6485b882f465a2757c6cf399552446cad41768fbe061e838610cd5047e9f3a5b6f04cf8c72b304670fd0c4be07af4e76d31394bbfa2b2c90ae201266b73b6ff3059d02d8f7760b50af724cdd782e7ab78819aa15c323fb82df568c63af909ab76d90dd2e8e6b5cdc984ed9309f33df31f4cd8c2337f9eb09027ccc2a7c1146e7e9cac234f163eed7872cb2cb7a138e96a65c53199e4886477555065f1700a50d1013c518d0d5c4648bccda7ace0a0022df21bf7e5eb406b428715eff185d328a814b961d3e610265eed88c02cd55709c0a9fc891202de1236897dd8d456167d38aa61b1183ccd9427ab0b62dc0403317b8c7aa419497de5c80342cd66de1939923bcd7e5ac011b6af6a9b41321d0a080a7e0506f955ec12ed7bccb2a0c40dd674e849eaee063fcc92daca133a3ba152ed9f4bf9f2fb649e5ab40bdecfd083ff349909e37bc4643e6332dddd1235987fb6c31120c64e88831f259de0494564ad275b783c3a871c6a7993cdb9f2257bde5c371e015fa68ab6ddee4f6d7f74f0d48d7f6afab9565c359f570d0edee4827b543114f57412f32b971472c4d050752751be9153cfbde6f0297fdbfd02a25244874ddd9c2e1020cfe0109792d9b44072d8e3e709aebffc62f45c251f04f64f52b9a0810a61060ab74457bb758fcbf7fd446e73cfe524b397ba875375b527261f2ad756ef0f6d31fbf00e98f19f5b7bfd30cb4b25c40af12e4d4a3cf01e6b32f28c193517239c6532578c728f9c9c28d8941095cd7db6135125bacf3d07136d1d25675a5b50460ea7d0ac5de5c8db54a401db7f567570a7ba2d7297ccb76ca7126ba19695d5e2d6b36f59e91046e0908b43c89ad7dc35751cdc8327890e4f9e5bb19b9fbcf6af93f75fff6861caccdfa72c55b14d10fd919b32f3f7292bd4b28ef929d3af8adfca0de1dbd25bdf57dd4a561d76e40893673d978e833c9a47091afc696501718518a0943d23dd15c09649796b9c40560fbc024bb295594795f9b306d56f49848a178ce2c4732b18a75fdb9fb9ab45d84bd49fb411696a71c2edc97909576d841c34107694d4b276048a9f449c0ec510c9451b9c517da6f70f193cbda584db3c63c5b1fd1f3e39e489b7ca9ed4a5faf6e41bc63b5460e983adbcd48165594e9c03d7f2b8ccfb0b9255e38325863d925ca529f4942f9b0073709306cc4076dbd7292d16b2017dc7972e6192ea8f92560c601d39ee07997a071cad4b7875a48b0bdab80497f8d7d1bf5db8c7aa7c1e60f244c3955a5d33eadc9ac5323def47dda68a592a637822bfa35273ab75d9b888ffe99032ff0c6fd2b40c5e9b67331773b473d3a0234fdeb576c4cfbcb39f55056601bb81491aeec33e2bfd91a9818481e844b9c9d5b14706a900aaae7b6a16062df504cf8993447ea5f4ebf19a73fad42cf112c8e0263fef8971f802bbf3c7fce296271c3005a7bd1edb9b429f521d87b918e8bd7f5b9e88075b51a49bf06570c90c6a364789cc4f37e08d11a8bde0b894aa7b1dd06051c8d53b58a92a615e89955ca3c25857b438ada165c774a66e440ba7661a6123ee47e531e3f3f496748449e92416c9df26fbc19a5b6c09aeb759f413ab5a966b107ab510df1fed17e4e0c099d1dadf6942038f66ba6b6934d45655f17825d9a253a5cd635fe85f1baabdb7e6d924d0883b786f74e1ed3cae1a366737210e87f1d31a08581c550f163080a9475100ef733d3858ef6a28bf900c61ec1eb025771b37172f456dcd694e5871ca5404b83d944859699ebf3f076158ca6d150195c8ffa0ef2e3d32c23e036ea575c331b4c733bba3d3c1ee336959c907ae015c52cd90529ad223782a0811ebcb2d3c9ae6f063e6f18a99c14cdc82324d463d435a88d36816b60a1be79d8017b034856a63284c762aef00e772d4ce9748e773fb2d8a6163601e7d23b7c25db933789e41e3b60656f870b9c9f5664b5e0eeafb8ed6b3ae8f5910d869b8dbf8bca744db805c3e5c202cd477b739ebf0b0a98fd5dde39aad411ddc63a51d8853a575ab2b934273bc9e413db8e4a50a90242a90ab192d64a3ad0b3fb13c798f859f89865a43afc0e3e330cf9a9ddb9caa52dc9c8c91f9ba25b04905072410ebdb32b956ffb3ad69255b33578b7cc8a7f0ec32f5d63fcbc7ebbd4ab117fd0dfa5ad8aa648b37fd5c186bc3e6fc663d0207245487d0bddea1bfed694d29694f3ffeb6a7350f54d8d37359c7a63ea69bbad5828703ad3d276e9cc45871dae1c3f2bb5a9b7eaf8d50ea85549a502fa42f11455b02d8b11d208c651ab2bb7129d0fb63b8ed9587e24ecc2b50cd93d871dfdd42ecdc936f917aa4dec640e37016084e03703574f321c6b3368011bce1f03572a2b3491bfa4c4a6c2bae59bf76c61647d954e70d070f0936ab090028b70f79e8ce06fd321909ea047892b1a6373812e735eb34e6873f8edeff6f1a7d68300676c9fc43775edb0c3c015483c9f90fb365096528c670b3bc836227b6ceec8792561ded2eb95de39fb65b89147b9bb57e6cb78b7657687756ff73bb4d9a33a295aa979db2f5898f59877276d60ce870f75d783bd1c93c43c54e2dd28583ef2e40f89a7ffb6e329e55becd30d726f1a7915aab0862316db392ba8a635d75c1fbeb5d3732e10babc49ed4009fe45db1956693b24bf707d52edc4844828564f60c62e5d5569ed09fe912fabe409300b5954dc8f4b30efbb9751b4a53b1502e6a1641d0aa768de62c96d526b6fcaa4bd6b2865c43b7470f66c26af654eaf64d59992cf617368f12820f277499fb09da07a50752c91bf3f9b8cdd4814fc7c42510a0ffe99fde821da02c613d761007f51979cce0dbc2cac26227b7d1c14a63dac78848fb7c290fc59bd3e9971d71b21e89dd0cb09c339ab9d766b757d061937545c5ea102767d612621296d84f07cb4749e055a7d94fdd423e587d3814e657f72bb73215c82e3386944650f66e49ce015302377b48d6236ed8a0c59a2cd4e505cecbe3da4a269fb1625987ec34be74c92f6316f3c2e8df537671aaab6e9d11db5935366e6dc8e16e2e8305e9fc17925c6a878b9649deb8ed5e838ca927e70ef90ef5a225391f8ce237aa32ffd1097b7cf96626b29e6bdfd85376c54eaa4c75910437b3ae766d3a95c3c6456fe1a6737fa04c44bbfb417dcebce8161696a84220051f21acda694463c94716d93a770db3a69ebb082c4b031c4ba4313ede7b5213dcddd31ded09a8983d967d11914c3f4c83ca29e6c6f579f1e4172ed3088764b2275656bd2c6bb47387b822205559558f5d8b4fc0711b773670c18838efb607dfa139fce3eba49839aac39ab23d09f29f7a3542a47324748df3465337db9035a4857a2fcf847afeca7022ae7b6636e51c7bfe5deffd4992e6635b61731656ebb5429b467595017b897b416c013267570821cfaecba35f8c253d51d66e33c0448973fbb7c0d1eed493ab252d9f0824d30f4b6cec261dbdaaecf6394048df6cb57e82ec660b667dd64d5b4be59434cc16622be7e420a0c8190de28316d9adc4af995dc9148964434a286c0afb088695c2b82df2bd0fdcbbb22d163d5f128bbc9044d8cda72685375a8f1dbf9f624edfee39acfbb2a50df6b8af63dc6dd0b349d4ee6589efe426cce0aa6f2f2f19612445d267b0b6ca2361f9b2bab1b2fc95989c7c39c3d727cff2e58a883945c69a0fa4a278a0484c7d9c74571775f72aa797bf0264a326355fcb957d952633c85ebb5fab950d52334d53af125684fbb8bef450516f9ce3ffcddebbb0b76d2b09c37f65926d2ba9a66eb67373eaf8717c49dcc6714eec6c36957cbcb008498c295287a02c2b55dedffe3d185c08902025a769cf7eefbe3e3d91440283c16030180c6606e2fc4c06a4be9c886892f3ed5858b9262fbbd295428af50f910852d0d63d49a3332615ce54966bcb72ca9ec7cb9ded1fdcbe9ae3eee4f4f8933e951001c3e340a01704d2e51acf2bf89b2f4f31a5c7c5b3cd434590cdf38bedbbdfcc752b405bc5fe1bfc571c33b6ef4eb230e3913850d87a897b12f2e58eab1207d737e2940d478f0b7c791936ca18223dc8ce93f048686f73c1185a22c9db91c85dcca19d7c7eb975a1e793ae9ddec98b7737376568edd6a6dc346dcbe9fa480cf970241cc8ce784f3fec7f3979c78443c1f9f4565c843ec7d4c2e3379f5f4ec5b99bd03f632beb4b2a7cdd26c2458074ef8428b40a1d4c5f6ebd4136fbd7cd51b6d4dae9636e6d405f243dad4207090774b67ff65f6287297a3440af347905b4bc4b74fc728c4714e21e9f4f6957eca7d8162a2ae24a88211eea61c957fb07e8ff3c7b292053d4b8a75261e8e022f8eacd9d8caf5423f2642a17c929c673e8dfdbf8fbe0e291fcbd8927e1af04e8a7e8d975f20e539f7c16aad6c7f1f6a15ec7cef7f73fc698b6e4e0c94bae131efde311da86672f85a9ece90d66b87e2d828e7ffdfcd9d09b36c565f672e293cf32a99fa8216e3f1291419fb6bec83cabdb871ee5d46337d2a6920a494c269fa5efcd9c098f9c99b000e86c0e2a15c6f8f36be5ff76901c744622d32193a555720795b7a21d64a5bf1c3c159efb7aca6fdfbc962bcea91287fbbfc924dabf296723252b474fc425b047fa8584b229a1449b32c13f7afe4928ffca41090494dba3891abf3281743e1387f7d8cef9fed197c34d91f80275d8575f0cb30349d09ea2dc51465bc2e176fc4c50fd66fb501a4bc38579687ed03e588c646a267133b272aae3105ee9367ed553591c9276a47183e2d22acef55fddcad1ef4adb46746260b4110b61f4596234d318253786db8381d0678190725be4003284de69d9844db089145e0221e195a110da56dbe067824662e5fe6d53e039e0ad447cf37a22ec27331d0df66afcf2891801b22514d34157e69b10d97a1e778cab29ff1548155af670631b372544e67b181f2809f8781b65fd3f9ee00b34a81f242f47c220a6b6204fb91e7974cc570ebda0e5943599976b226e1d3a8f568df597836022fd627591a951042309e3cf3289adb843fa442a7c42fdcbad8c07e3830d19a2f94c16dfd4fa6171813c0a0fb66f4e74278f42216e8e9f8c8c4bb1dbd275d72412a6d5d892740ae55561dee9fe6f776280375f5a6bcf9797ff1217521547ed94ab6732b8694bae589f1ffde665293422993245a54e1189508efe514ca8f269ffe0e246ba4ccbd977fd54193925ab5d6f74c4fd6e68057e8c6e56e9cbe9d66f2694f1cb797054b17abec2742b98316726d2aba88c3907ef03d42cc4b52c47a702bcbc9210c19375c01f5d4be3acbb1f27fb278920f4bf14cd428b661b32098c4a062352bb1c08fdb0e3ce14f366666f8002799931971affd83ffa4f59f5a3a3eaefb9aaa6a6b2a2aabc79c36387fb276275eb60be006ae6e751a9795e89ac3a621dfb4d7ad995e5ebe10c2caf58c0f31757aa9e93fd83b77860797091e73e110e8594e3f3eae5647a6252fa247db9b9cd37ad2280f73c11a757181a270e918fa558e42bb52fc33cd10e7d2b6e6f9edfaaf09bd3fd93a918ce8980a2b6422a730dd750e3992941bf8cc54eeb91bc9e8e895466a171c688f7dccad3abe0d1816b693ff87c7023020730d9d9efd22ff8d5863858ccd660cc273e7f2b649d102ce6d2faea996c46ccf24122afb7d9ce92cf9dc778b7cb99de33a089f3cdfe4d6069f6ff88c5e2723ebd119675cba7f9d9c153b969ca6d6fff81c71247a6687bf6526f129e70c1f584c863a2f9e7c2a1f0e76d958f521dfddebd1c78b9d3656988a0fad1edcb44e524d3b0ba2f8543aa2e341607d7662da17e79d901f450a6b6e874a4c7a22c4be5d27ac764a0a55085a37f49f3ee4c1cdc3e9dbdb4adaca2c0ab445a6d85054929d2b276aa6a6fcc5edab65451207c797720e352f347ae4c54f8afa778042ab74da3dbd72289a33e7fe5586b7f9b5f0fb467e1c53fe6ecf8a1f7701884f4e1cec35b1af971d27ada258f371f0d9f0c9f6e3d1d749f3d7bb2fdf469eb337be83d64f12c1950761047298dd2873bbd87f46e1a2729dc92044e0671c44e49140c294b61177a7ff42380fec3c0ef3fdc81fec321e93ff4c4a3884ca878781c4729eccf298bf913f97a9ac49fe920fd9084a2d0384da76ca7dd1ec6514a44d9d6209eb475853018d08849900707f0f2136cb73af0463db68b15e00e124ad2e0960ee2c9248e582b4e466d5996b5af17eded56a7dd7fd88fbe7a90eb53103bfa74124701a7c5cafe04b26045674e4f2e56a23f0ad2f1ec1a8120c4664ac944036f5f87f1757b42584a93f69b9383a3b7e747eece4c7c47674e494a938084704859308a6075cf3846713c0a694b2216c4ed8984d2f4114a5360e6eef2fe940cc6540d1efc274d581047b0d9eadc871202859286d726491a384872b198ae4505d60ca29118dc5456a962d9e6f93e6cadd1c915dcda64a4bd55cab02317c3be42b2c1d9204524d718638e472c8bb70caa7f17269e26c184261afefaa335748dd63125e99826ab858b28f79d27a40955fd58bf432357875e910915c276659f46644205cbb7229a56cacbefc079156c377775e4a320c79a7da14970330ce3394d982158e60246a540393f790367c76fa0dbea5676914fd941124c53d6624188bd3b3b7ee3ee90efead021bd5d6feadcc6491086e48bd1115fd6fd136c174f692456687b64b0aeab13c4d589fd2855b27e4d26cbb89d44a914b4c6d7a64d93bfbe5bd7ccd1ad97719cb23421d3fbf72a9d5fb3f6dfdd89c43536efe924b8c30edc077facd514632a7e5810bec7e2bbd36ecfe7f316c1da760f4b44f5c025aa4392c2411cc6ebca0453f3e1159eb68721499b030ee26f67bb51e212d6493c99d0b479effe8c4445f559d59bbf68cc2e9f3ff41e0613d4ef7f06c2e03d25831486493c815ac2bfd79ef72363037048876416a6b83bb8e33b0024100ec60ecc229f0e8388fa88110bbed0fcb34148187b4b2685172c5d848587244d4da8fde8ab8d0c27788609a2dec2f58baaa73ffde47a5cb77bd1e044e0f0aeae0843a1b80be93860bc36ff6ce9e7cb250c67d120e5a4af3744df8d4a67d77cc45baec2a92c0d308c13a8f3d6980701ec42d7035e9724a3d98446296b85341aa5e3e710c02f103d87606343d7056066d15e70f9bc1fa9571af014820858038221d4254ad3244ee37431a5ad316167f3e85d124f69922e5a03128675e6c1b4d180b437bd845d60bd2907cb417e55d0139ace9208527cfe55362a1f2a02b4c8741a2eea9c625e8663e3b918b67e24289c888d638ebef8d42218f380ca7ef38ac86aaae13fd953de2e6d05914fefce86f569037e814ebef7bc190e95c1835d88666188c82ea6341eaa611ed1d4807fbe985cc72183dddd5d2efa643ffa0f1b19b67cb43b1e4c334e7182a8b38618fc69c60a9c07383a06dabde032c3bc175c4ae4f9b7e7c6e8a49afe2ba7b92cf08739afbcfc8cff2a6bb5501acba7356c400fde4542e9e651483903d4d384aa81542825942239134a5b1332ad67a31ec53ef520d00c2f6b987358c1e5455b2919799a01eb7a96dcd0c50e0492873dc0a25c98343c1b377c311807a1df6808d64676e59d916246a3f68a469c2c759fa4c4ee4e86fd3489a76c1ddc39a497845117ee42e865cfbf7ac0db14f8eb2e89a672ddc1725677446ff27d51cd5b08730ea5219dc0aed1a3411c0d75877889413c99ce52ea9f075f28ec0a345a5cd2f3d9cb4beb1ffd875d3ae93f7c6ed455c25f3ee30c8d55f48b46560676c17e675412ad96d4aa673ff68c171b50831aec40add6800dc841d05294a3c909adbbc67f786a6800d2200db37ee32fe32dbb1df1b9cc65b4106902530f7afd871c50ffa187f68634a4fd87978de739e9eae294fe43763be2f58a8cc2d224bea17ca51fcc928446296a55521dc0052108c38ad7a2fec7c04fc7bc54872b0492bb90f2d87510ffaa9e79d94a642ce5faab011b97f322d25a579023808aa0621dfca54a2a341094a7388dff68e866c634188dd31d8b2bf5cbb9e899f3dddd248c584e499a6fa182b4d9e974da4874498e8627873da74c64432447d4c38542966e2894713e26346ab8d64e538379b0bb9be93ab0572a3864f9d6411cb1d98426aad992592b5be2535bbc90820e76c4b3bc2ed48fbe3ef41ed6668c720e090652b8cb7937a08cb56874db7a7b76787475f4f63f71c1ab4d93d89f61eb35d9f024f667216d09d1c3674442ff350b125aafb5da83cfac8dab4e2babd79a0451eb33ab2102404346ef03c7a7b7348ca79c461a483f7ae829dbb52f3a99d1e88adea534f299d6e2e4ef155a1c4946d4a1caa11e27166d871e672970a8f9e196630d4dee862e50c3c1f20610b887c683753d0eaa61410010bde9ddd005ea0e58107f3dcf4a7dd5d3b1442344184eb55052b4422d7ce83d6cb71fc02496e3c6eb3f37b48151185f13ced96490c6c942a32ff530cd139c03632446cd50d304e7e0b4aae9795583bd224b49f8f506ec580d883a02bec20a5b102f5a64c2e7a9f851d7484a1802f996e89cd9483ffa2aa951b736135098738a5fc6717c7340c2f09a0c6ef40b5d97bf657a3b22fee4189815e5380859618d8335aeed365c70dd3c60e0c711853486848e0296d204d23185094dc7b10f9cb7a80ff3201dcbf1ab373400fe349ea5206c89d108064132988524019f4e69e4d3681050d6caf583d1f4b5812fd407f29bd533b34b5c47c8c8627543430dd87e9290453d88a6b3d445237c0141c452120df8a863793eef0bf32b8dcfd324884662664988c81d3dc17ea2ee65ad021b01d4814ebb0d27474f611e8421d78c496a2c0624f2c5268430902d05430852981316d5522e302c40a24f72e752d263635ff30d1d1555d6e8e9d1649a2eeaf1f5e732f165ef81b816c172724a235e51055b90221731ed344c29662c28d91f4ad8e7f63314bd375ce8e65136518faf3fe7846dfd262f5d0bd80f49c8e8f36291aff6a3afceaea7c98c16c5b28bec1f14d7ac62794ea5db38f0a15331886f67936b9a948392923283588bb046ed1b279068af92af0e494aef319d79f16f448657ad40856f5d499278308c2c4c385f25942f2cbd4b0f0263d890bbd00ca0948544ab091b1b8183ef596b3a63e3fa30e22df5020eafd170adcf9a000965a518673c5b271e5cbbe8b7965281954b5b110b7fb105435d0aa2dc3b35b30c0cafb1afae49457a01d758ae85d6543279be66fa940b744d0d7fadd806d1bcc15bd13f9eaf0ffc9684337a3674c296ef10b4fc5e06598e092925b5d81d7cb83800c1c01e27f284a41e84f180f07d93d0275c232deabee1e5ce920f1707d5103c14418dd62c1dd4cb875eead9ef48c28268741c9211abe757b98f14224a7dae59f8944e6110a29ec1950e31ef5a05547334a47c4d317eef08d9ead9a566d18c51ff22bea11113a57a97ce222728324a8ac4b7341986f13c6babb9992b32189384bda1c3f4ec962658a4932bc117daac95328483e89684817f1a47e958944265cd59e81807a9bcef8c2627a22449a95fd6208bcd9f25a5a62461d4e7b2f01de1fab28348139a047e4027192007e6c970b0f9747373456b734a6f7cb2380dd884a483b12a654c9052e61b519bf126059563d2ba9a0e6157683e85a929dfba99b852e662cd3c5e62a76719ae503d34642b7f6da1c11fc02eb8ca29f0055546d6c9f612c35954e89bb2a14bf593cfb6c6f3629190e2e18752a45ebc7881da814347d2066db19285b4705491fdf1aea3ccc70399e12c12ab88d804a56255f3205da941e59420c778405e8242b9fe55ce4801fb4f3e73dc0c245f96721127cc90f30cec3a38d2417331bfc4dcda05e1f8c6c983405ab9d9679a798afa82d1db4029f8f915d28542c0dec673d92d7810b0b7e42defaacf35ed8b6042eb8d06fcf453b12d81a21691bf40c759ec812827c47645014b00ae2ef751888aaa92796952513493d1ab5b96d2b7a2605e00bb8ad665592d3d974ba8e71efdf493c91f8d4661324aae742cf3ba8439b8c60f174aa007d55ed47047b5a286b9de5a3bb115f5ae83d1eb7826dad05bdea25e57ecb6545503769cc45fb8e0923bdae5121ee4ded5276ee162ce678336e55a25ff73ed25c198796b80712e21129315ca9ee42ac929858dc7047633adb0fe96bc35e73ba79a904d0f4aa497d4dd8b82cb13a355b20eba485284519815bb8e7d6d91320e13d5bb70360a2206e998a4407c1f6ded344903ca808de359e80309598cafd2314543ea982614d0fe05a876ab6384761b580c730a03124938e1426aa5f12c6134bcd5c62aa4309abbde650dee0a135ccbf1a27759b4d70de2e9e2208e86c1a89ec61e1ea716463110a7071ec7f4797eaff1c0dce4f3ea9c75f64fb175c1f745664fe34221ae33b82abb47b8ace192a632e0f7023774831b6a70c37b810bdde0420d2ebc173829649d30c53b0d58fcbc17f4f48b434871d0e99789869b7e99dc6f7cd8878b833276e0fbc68c093e5c1cdc0b743c1c325a420df14e03173fef057d5ac20aa8a1e7450bcea1fb71066e6e4bd803df653c823fab36fff989afd567e8141ac89b804aea962bd35c2ec06ea15ed11602284b14aff7783d579102816e8963da64f4118060578aa67c81726ba64bb6a7b16bd7349bfab8d0bd4be251429938a211cabb16d9426281de2349db414ed68a5278ee198cac4e995218f721b28cd125e19bc457a988ced1182801f187ca7cbe07fa59a62dc30e3856de0708506d2e1cbc576c2f07c5a0265f04137acb691044c3200a520a611ca347d480302a89782626a2d0081802169c634112b4632d1bdfe230ecca8128a0ee1831c7664d2c932662ce8d68c5f0e708e1daba49c6281c39488e8baf3f9bd661599a6bdefc8d7128125f7f2e2e994a6d2ad5d1c8353b0e633ec7851dbcb083148f85e3568e88ed36343bd07c011de7fef594a4e3d68006a106bd5c6adb3d949e7298b5871c35557d1d72a6f14994d6d569e1719c1cc434190471d1e03de02fa82fecf7b00b1b8e4a5e7ee719ce284ac2bc40b5813d909b0808d83132bafdbe389114603518b9f22bf44dacedd03907f1644a120ae93c06922464c13c2dc6c614e4c0c643f083e19026341a505650fd10049a77581d81743d016cd3033f8ed28338baa5495a20af30cce0204e824856956b8582207f367264164f0f83e1504120d7cc8600cd6a10bc470cbd1773bbb08ab38d528b101fe0bad1573eb2029b5e7089832d704107c7e5d2b56fced5565c2a61341088f11041b9d734ecd9c6c67d766a82181b065d4ba5c19c24517dc24605292024219b4da75cc01dd26942078457f9489228884686ac759b0ee4b9db208e582c9d1c4c2f07f471952f5b1c8b42e7cd97f59a8101221d44a31da8c10670e4d71114be044079779d2762c32061b83c666b4381b472f759f0b1b6994710cfcf507e4d223f4441e1ded4825e7b8a95a44344ae9f50d46470efacfae06c029d079391def795bc77bc715954573912d97f2419c12ed46a0ee00a79c932a6cf91e53a530a5bc1dfd8855abf1ff5385f04b001b54b286b0f1c5e4c59c39dcbcab68cf678d50da8095e340108afa50da87995387cadee117a60b558180c68bde34173b3f19c4bfaf77412df5248131284e8be124f26049d30d8940ca81ba67bf575b668fa7cdd036bce5be2389824056e2da9a724102755bf1fedabc605450be70c9c12f2883719b146eb731c4475e132cbabf33a75ae431e25499cd41b8d164bc9e0c6858b39dd5d9e0f6e378761451481ae89e2c5b56f30663733e3055c72ea3c984c435a8fc8848ad9ef16d1f79032e51246b751b1453571eff11ac539a257931c298b559d86358b5c6b2c40d6b09552431f321414f163f9f51ebe1aaaca37fa6ba8ea153e1b7c33e4da0ee2410c5adc1c3a0ddf5215ab40b619176f8b131a0fbe3242f0d26e3584b3bb706ae065f253a554b260b5da150ae4b2ca4e96135b4d81b6c6ffb9b5277c43a3806f8de2c40f2212e2310417866430a0d394c1e7194b8128b597cb77df0fe4a6c102244b6c407d1a33165c878b06b07436e4dacb8443c480922b9f2cce8678f473265a7c4712465b16a88bb3c3b31d259efb0f63a360ff21e757e116184410d1bb1426e4739c4042434a2c4872a3ed6c50755b6cc2dfd3d1d1ddb46e93b45e55bf259d7b974bd94c5c7cd9808de258d696285ddbfdbeff47d7dbfcda6ea8d2e50e4834195161c46075beb140ad78188c3c40aff303379f0bdf24a96bfdf1d503b3aaf45bcf4f0264743e0f4ae042d10fc6282a60ba595fcc11792e6d62220c4d0db1f193ef0d98f275c59931d3a6aa3fbe96acb49208baac4d0bd9c4da758bd8b91669319b719b9b2f5fa9c1e63b55a85dde5809349f8634a519d0fb9af3d4578b432c665ac12236cf228f941e163ea864add26a55ace52473bb0d13724381cd120a8331894694411a9b274c7e1cd55298c47e305cc8fe4a115a04678e9831e5f4e38a5dc7fd7cfbd0918bbad6361567158c4af90b4515a3da525aa139488d9ee925df388ae5cf2dd8fc41165221ab81933165d16cefe772c095676309756eb2b2e5baca79d7e0a3f8fa73a9932198fe97c11aeab65ba3cd860c5c3e27426d15113824a4914f1215542dfe1899d043b2801da8f52e629f2c80a497f0e6a2669862f862979599c44912cf4b8a7da4f48697f37ddf875eb14c489806f589b29426ee26793905abf786b0f412ca40f21e1cf1c1de81da9b9aecbfe3585475bf7e43171e4ce28907513c2fac5ef12c455f63a5c3c86a6243a8575dfdb8a69aaf99dca28feab56e26c036604f3620b4cc0c8b1df9bc6200dfc4d1e890a4547a8758c3f8e6e21c3801c63b93c90e63b06f52e8cd05e897b93720de9c9eb60f0fdb9f3e7dfa64bd7da3de9e9ec2a107c5f76f0aefc1d1082f2779c20357e1d2410bed2ef3a12b1a7e1439c4c8d85570d8bcc2349e90f4c3748adb8bb25aad34c6220784d17ae3b2604396cd2e97f0c00058165a208a9459864b31e7022b03de4ae83424035a6f73222e4f4f9787874b4ed5f6c8f4dbba2545019cd99ea539a26bc9e086cb5a568a55058f4aef0b748adf859a7226f1494a6b8e4d9c51da19602450308a55342db564deec8f7eed79e1fda1539f865dc854e222866a77e23a6eb1709405f510711c3cb08f425c58bfa721e64392a60cd39d7d96721561076a41043f3273464d0913beb9b51f1990516c89437c4e6048e7c0e8208e7cab2a6358cd77bd9bc8aa93209aa5d47a3391b5c42babd658d48a601ccf12ebc55856e22fac2abe6cc8270bebb12f2bf86461953f5588f1d1b35e9c2abcf81babce42d659506261b558c82afc052b173d89393072f83d157a763e1b0e833be1bb1e8d3c14f47cb456ad2626d09ea8ec5836eac575a3017bf68416cfd7c76bc7553d13283ffaeda0945d354d38df098050f783e1d003b5ac55cb64abdbbc22bc800eec414df038c6cd73d82bd6500195afa1e29b5e5477e403a33f8cf747be774d3f120684d132331ef1fd0f5190eef342509f4541ea011bc7493a26915f3c3c8be7629d805de0655b69fc463db23cbb65a33d5d810bf8c243d8801aab99af74d397b285d2118a381dc2e00be5e833c49c55c455e17b61e4122c53833ddd2abe449dc77a62f7ee12760a5e951568094d5d20872636e9509627a9ae20a327f830e5831e7411ae6be7830a848da1640f59d632145578a3689595c1460676f30381354bbc63ecbaa59b851c497a7635ce1906aedfb6e12eb049ae4dd7449a26419c04d21fb1622ebd13e5167236c96ab63a97c1425613264751ae322a4356fb427d83edcf727b34f4fc11fc6e6fedf441d28cf386b32e60300f677edcaefdc1bfefc02cebc68e85fbe5d71253bc80c1e224350e210b816cc60090966a019a70ddca5103f20ef7b21636534ab12f34898f8330d48b8708b27f230ffb877132a0e7c1a878c44aae99f6bfa8d560233bed970b476e12f286d805b6c59702a3156866c09497815d57a6bc92c6dd17bb96278a5a27b1d01eeae20265bea66ca8342c3b506bd60ab650c4791acfebdd8e271d1ec85dbde399d8361afa34a0de68b1d9354b937ab7011b19d6aea92016a1348846322a6c17daf57ebfd7fb67bfdfbbfcb9dfbf6c2cebfd7ebfdfd8abf75e8f2f27933a638dbde569bc3c3ddde3ff5b1ec6cbc343fc678fff8f6bf77bfeded28ff796f35ebc9c5fee2d3ff6e2e5c7cbbde53fe2bde527fc5b66ff2e3f7d5a8e46f5d168b4d7d85bbe7a557ff5ea15ff4697474bb2dc5f8ec77bcbd7aff79637377bcbc9646fc9d8def2fc8faef7ecebf26ef95fcb2f5ff696bfffbeb76c35da232b45003a291edfa37f6f2ece976f2e966fdeecf1ff2dc33fbadef6d73c544130b5bee7044856005b2b29d56e43ca5feff01fb5d39a7e3a25be4f7dfeb8573b3dad79b079a9df49657d87d788b32a2ad87fc7cec2269418d430eb9c07ba6a469b22ee38c314ea88912751f054731e38330e603f67d1a0986d00ec93f5814e4b60acd745075001aac2c701ecbd4b4fc1bdac178c85e5078ad84597f76961bc7a58f452e2540e51506b3d90a26caf7379b97657b5d4e3c54b4e81d590f5ba97faeb66d1845ade0739d2eb7542165ebf0bc887c25df890a4a4de684910d57d1243b5ba13c59522c193b0fcb4771cb8e2210b7fdac238a87a9b4b857e9ff5fbe797eda2c6649ecf663a3b9722cb7efff287f6c8e302bc32243257974b1dbb9a2b9efe46f6a5b0a3c82f7498a243d95e649ff2d2bd815185d279a6a06aca647c2a4e4980b4722f56b9dd6406a61ccf20985e70e9f670516f35ea65b5d73e0136209630832a517dd05018bf8ce327b9f814c86f9d6b35fbd41cdcde80953e4c12d8c6aeb99fd4a8f34d8ffc6ed8651573ece8976bf99858765c7019e5db6db541f6494a6186e7de11ee90c513a7afb9a8223dce0df472d3f0c1a4c2055c07835952c4b0afe503912dae165b7a7a3725915cefea2a98df86d8789eaf97f1a0f89db168f1cd725931555d86ca12405938ac2b8784a3133268a3102c05bbf0c89ee1998044f9635be64ba5a481b268aa651b575595e55288b7b2a1702a63ad90b0f424f2e91dd8caf27c1c84944f9617d2cdd95d3da54c51a2c8377af07376162728af8a2c793171bfbe2093437317ba2b9cac2d7bbba5a4a330ef6a68c2fcdb7e6eb6d06ecb2f1d68c2b35cd5cd5cd55c6d55b78375f395b77295ffd8fa6a5496753bb26ebef276bef276b1724757ced77e6cd6ee6d342ff73888c71244bb0dcd67f8276b17ea77d37833d7efbd22ee9266857ea7f176aeb20d4256cfdacf017894c68f9d00323008625517b62c02763d83feb91e382a6fe72a6f975776d47e5ca47ed713f477523f07e143c477bbd457ed6f583c6bb51f44c35ce57359d56a5e4310959b4134549573d565948fa8fefb92031074dfd993336014e0006c743a3b9c01c5c786e046fc374ee0f73c52e33849cf54249f05b7beb7a34037f60ce01cd8ca4672cd5c0413ca5232995a7daff7fb2dc5020dc93eddcdaded478f9f3c7d967d6b7537b78c659b440b98c789cf357d48e7710393b390414a13c65b17e60a06413408673e5fd6d379dc4ec709a5a21eee2285b732b90e062d0d59d4a00cd8204ed3808d614468180c301c04ab92c887f1623aa611c6368b138f5c5f3ff282bc9b9de6b3cb3f3adee6a3c75f7b35d2fcd2efcf3a9dfd4e937f3e3a3ee61f4f3af8f3f009fe3c7e267e1e1f1ee0cfc363f1f3b8f3043fbaf2e7d1f1e51f5d84bbec71288f45b5ce630ea5added5fb7df6f35ebe807adb10a76d81b5d54fe888de551911dff302f6061beba80c42f83e67eb4690d906d4d0fd12517a4f140273cb1fb073999228d3694a53c6a9c27c61b5f0d8337fc28e68a74a2bcce799a158f3384eec3e9738e098ee4bb2df6ae75786bbe180388b281b90a9d24364bd156bac4d5e1dbba8f239a9df52ab7228c107b14f8577a6ba3a2525831b95ee03af30f8d78c3254eada5b8f1e77b79f6db503d64cc734a14dd24404a64d817a53d1af1944cdcfe496887b5872b4cd75d4793682608fb0589d6507ba7c8b59c31da6bdedacf7fbbdc6527ebbe4df7af5de3ffbfd4b348a35fafd4bf1b2d5b08fe971c252df8369d783e9a607d32d0fa6db65a335ed72bd70ba89ff6ee1bfdb9619b85cd9b53ae4ea71d6cb76afd9ef63b7fef9c3cf1b7bad7a834ff3cb3fbe5ee2ee9abff8e1a7e21e1bd3ff289b60c9fc459ecef172993d2cf0d63389219c6a7b982c02924dcb6d373a19a1c66ab56d4da634c3fd61c58e5c5bd840c58d094d7f3dc3527eaf8b1da98cda1143217a2c53f7bb6d6f8e00531ff3deac3b58d6b8aa926efa2889a0c49223620ce5c55c3b8cf3efcb65d1bb5661a2c0ebd2f9265cc724ce2e731de122c67095e3249e58bdb11a715bbdccb85e430ea7723b542286cd51baccf78554f5c531fb3e1dedbf37364bfcd1e9d9db8bd790ed95f07e95fd8b23d8854de3d1ebb30fbce69659f3e4ed072cb76d3c3c3f3a387b7b28f7c259c9376f4ef49bc7c69b8f4747bfc12e3cc93d3adcff04bbf0d4b4df1f9fbd3fddbfb83879fb4a3db4ede9f5daa79a071dfcafc450caa12f94bbc18292a4ee38155bc02fbba85dc39e38be424f900dfca69823b32fe470e878d0ab7dfa84e708559898a65a8108fc08dd4e67dd06b00980ed4b4f02ec7850431f16d5a3b27a58f1d137d4e3151f8bfc8ba26b593d3d46fb6f4ef6cf8fce0ddcb57f445d14e7d5ec3aefde9f9cbd3fb9382954d347c1aa66d7aeb7fffedc66864cf513bc807fc6c6c6e8a2555495d51b584feee14b2bc82a7ac7272b6c5754c01a7a93272b3caeaac06b382be82a864ccd065755bef470b61b2d18c5551fd658a3c4dac44169e70133afd626ecc9b02ccc1076318f0f8351907ee24c2d0d553baed5ec6b2962df82563506ab9afc9616b12ddd2b0fba9d4671f2b6dbf0fae8cdbba3f7e7c51040b260271122c9d9db1998c6de5032358aecc1d6e3c7b0035b8f1f952e53854a45b8f8027e846d9d180de4936ea723f21ca0755115eb744441876efefaececb7733b9aaf30084555c8290a0d16810dae4e18bf5fc0e3a7b007dd679d0eecc066a79311dbcac672767af4f6e2dc5cf046343da70a8d09b9a1aff041bd763c0bc34f42ae604ad9a2323aa2e98926a65b7e1bc4364479f5d9924040b98bdd503a2d8472170e3f44a630d7f18f48325115b0c368fa43579ef78936053487d74f496614034b472563295bfbbc48d619e906386255474355bb6010e73008c241c5496c1c75e4fd23f9cb2bbf571bd114e3de263a09155ffd3f5c1c6497f5a0ab914aaa5315d9f943d7c048513baf10da58fdf493ca77294a3b879a83139b18cdbb222a4df320072a5990bfe13f953f02afd7550f7d3cc211e2fb993b23a1a40b5b972e88b76736e9491187bed48ef78d15990eca78e7db505b1de0f4b55c9064a38bbbc7576afadabb64e535e674ae7c9edf456a13133a570827ca521b8c5166450e60631a62879c1dd0f28795b167d1f1b32c3d43a1d7a6ef66a1ef907307fc82e9174b9df3f2555d192a0c502b7354201d8d0abde0b22598049b73beaae21c2793aecb07f7e585127e5893bd2b78c4e29049ecd7230ff22652a138d423f891bfdae0fffc08772e038fbc1ad00acccb677890656cb613cf1c79a733886ea267358db03d575eab13b889e279911b57b90d088f9a8a1b12543f7500fdee2e1431c85133df2aac1bccd7ecae652036c52f5f153c711850b44de0c22394c5e51264de652c5a268fb2153087a5c84c2a7327ef223321240fba9b268fa26ab9b10be22d3475a506b4a1bb59dc9567407121dbe36817b4e3cd675c3b7ccad7e8fa56d7800a3fc213f811365de6e5d57685d39a9779077ae80cb8d6c6def0055cb9afaf9d22fcbcf9c2e1bd51eae5258e7af0b84c6a559933c4eac6bf4febab1a5e652390a13b503b751a093e959a0854c5a7f7b0119c8a7dbfdef6976cc64f4fadcdfe2aeb802065c541918b9ed2d1c3184204a9ebbab6b0b9464fed5dec7d1bad68cf6d6f38c5613aad5dde63f38cb6c6bc791b9a25f3c36eee543658d56495f15888262197ec432749016c4e81b38ed174ce5d432eb5db5c78ce29f8818f975f05910f32f60c64ae1d92dc60523ef4d6224c0532b6f25b015ea56c0b97231c167ebe4a05c967a69556693bb5fdaecb7da8385fdf9c1decbf39b236d588cdf9d5c9db2b213c6117da87bdf8f0724ffb79f7fb97e8eabdecf75963838fda5ebb186c29b205203a5c63aafd4aa219491657c7f43ac12fa724198caff6a749105e9d92c5d5afb3885efd3a0b1757fbb3d18ca557e7749ad2c9354daece0669cc3fdfc6b7e2c1211de0975a8b4dc320add7aeb491d3881c3610a874972bf54e9537bb891036c1497c2d327fe7c3ea4007f38af7bd1a4b49e493308eec00718743eb1acdf5f41eeb32dfb255cc02d20ad8b18e55ce0f70c3f2fbc2903cfc8a5b2d1377a369976ee81876147672ecf9b8f321e703ae869b8f361f6c3ed27c8cf9f8f2a15d775405fcef36b4082e4f70d1c68a41c6427f72a4cb5b5f73cc45d9fcf07e87d1352ef78afc908a55444854ac82f7f2ea4b9d1cf744c8f3dc20904917c270a0c41daf8be1847c54dd21935962e32b4398bbf600a9bc56328a539831ea97d34a057e17127c6411efa7eb14c4b0cc1525f33b8eee66f9466312dbb72bf4363b9d8e0745dfea721484ab76a6a44aad11095fab355610bb920e05d0f7815a75715ac9dd22469205b45370fdc0bd3f0b70c5c3ad6276f34f9136c87a1586ce20401379936f4282405e32b5b6e5b30c8b1c15bf0b12abb484bf8f74b8cd5428afdc17afb131febb49f9978de7df4a99bf84d58beaa3233f4bb61e0b1178bf45012588f28cb3a54241601fdd118794503711e71727f30ab07294ca3cdcd65c75fe1d8b8a85a7ce59487c1f589ca44134b2de9e8b67783ec544ceb160087144e57ea61e2740aeaf93065f39094c133a0cee201e0289e2744ced6b7f19a5aa1191b3126fbe3770cd4abb963d97ed566543e39b29e18929f75e98026d4c6e2904299030a1c45fd855d75e2db335068f63ca16b752bb72c94a68b84fd6fe59830df7d2a8dd075bc2771036a0f603ff1ad4eebbaa5735985be6efd1aa230df58302b526ab2925466f17ca69c1915856235e4a91490531b0e54297d7e92cd71a294b33eeab629cdc827a2aee822fe10fa1786bc15369f3cfcb7e23836369eb46e30e66f94ead1b7ce01a853fd54af9e252754a474547e5316cf1840bb7a23acf53f1662beb70d6258cdec6104f9d2bcc249e54ad16f25c4d5e0d51e590ca4bb7ffd9effb1b3fb405094b8e86c1b86a4298d5dc2742a52a8caacc7bed30e98a4d5ca9cf805e5bf6c552002c086994c29004e12ca17b6e95e78176a3ade85529590df296fcb4089f0db579794576106e9f546787e88a75cc6edfe3f4b986f06afa6c3c43c3e1759875d0e9e370ae59da7d5e5bed06a2268454749c6359eafba1bc631ca392f3f9a8bcf925f3f5907459eb4287114d0fb3b1719fb598836778e178d6214c5572b5d39cd51d3d8564984cdeb494b7d06796f6e219fa7aaa693e2c4312e9ca30cb3b2ef0067485ce6b56993abbc6faed44dc31c296ede83c8b56b9afb74f019613ca3a9bd6727265704b68e64622bb6e39cf0bd5645c834ac2454746ff38a46165dd9dd5447379795b7d5993a5ffd771f3f761e4bf8087d7655f27e77e23d37e23bf96b2ea2a2eb5eea2b2473d27e4b39293e91b1abda7b79599b0ae8dbba45a3aeb868186ad05a256fc2ea00399cad9c35cb2d6834970477df3496e2cbd9c72f23f694f6b744fa4242bdd521503ee15190a154beb1894fa3e95ca51fcfa5dcd1710d81711ce833014f2124787d3822630e5481a67b7267131579be65013538390e5854c2294975a97b30cc4544e1623b2cf7a593eecc59ad6bb92c1c8a3b8b9ed46d1e870b121fb65a9f5cd250b2de3471daf0e33482bee115a0aedbc513474942a0755a2ad4c20ba903198e1deb8ac826db26315f0b21bbd457ae58507130f7c0fc61e9c7ac03c98d85eae98008d4b2871f30a26936a401a4b2840d0db61c7aa304ed3297307eeb6bb4fbb5bdb4ff37bf394daae16da8b6210472c4d668314af5499902913197aa1d37cf68ca3d17dd6e934bb3ab502c8e576c1e74b47c43a608a13973c9e2694d1e4964248c954c2156977080c676188a110e8ba36580c42ca77181473ebd3d486e58bc4d6fa02d5056cf0ba2edaba1d42c505931c4c6b4453e5ef5d2fbb3e90976346b9c5bd9d560b18afc0d515e9ed3b326fe798ecc3c581e4338741c635e8bc748befaecd6c63df71d48ddbf2aaaf212bde00f6bd9986a3d1eb706128d9e579f51029d2c88c6ee20641bc306d2da6fa7071b02e5f9945ff3c6b95e12d29fc2d5cd66e034b499236e36113af7c6bce29bd8166f6940f408e23b1e0474a6fa4b943f8c8faf19cff53e4cf761b0cd03e5940b309f3713018c367e1b684da4538270b0681b88d152b0056a86fe3e218b0d8832e7e45d5a361d36a38f761179ec006c7039a1c11afc0713934d066878d5848d98f03c661171a0be7b00b75de9e353f252d3a1e2fd390dc7248b8a4e738cd1bf02386ec1606a729606e60470cbf3e63a0d46240a3d63cb809a6d40f482b4e466dfeab7d727e76c571bee2c3fc1f07241ccc42c295bb2b828fae46c12d8daed231bde238b6360f44719152e58a44fe95ec726eb4d1fac639f83889277cd499ec242fee293a558c3fd2f3a324a7249a26ba264a6eb4e69abd607715c3e56fbb5508c32e7461039ec0cf50976c8d49662d84368ca6bcfcce887dc29612ca0e15d082d13b6bee17979c9440b870e21f4d2bb5962c7068606c8437caaa1c65df683e27346c1c5e14e2235761b4b10646f27bb3007c0d23a6d9d89a0dad1064b92638e01d3d5825bcb0633566c02f5d77055ba8f0b00afeae6455d3285ec6b0c89bbbe615dfd2c62eb145e161b4826cdc8627e8205fe4d98f382f253d0aec8a8dfd024597896ca4329cddecfa51e08b90c4f4c971acd15537bf62d517565527a15c489aad37578328a25feca53d0556317256b19234f763625e63478f5e0583afcbbae634fd56e6ad96b359d5b7f4aeac3ab2a87334546854219edbe2f58d5c33c8f8df148c32c76094f95c05a3cc63bebde3d0cb5238d43e62958f1f55958f582560f147554bb75f199c818df0c6cc968cf70a226fe2de391e24f04739d059810cfaa37bc478cccdb40b65211b48cd75e33b3eae031189ed84a88bdbf973ea3d4455a0826d7018ae4007a1af94c739f0f7225b8c4a49dff1a0db28492a5499aca0e8fd9f73e942395148cd2ba7447ee511160dfeb48513c9fabd68b40c6953ee342e2593d11a579477b8aada6ec3f92c92ca6ea67df307f1101f605b66cd05ecc06371862d5f433a26788d624a8288c1af2482c7e9d88688e52448544225d2ae8bc938cec7bc162eda825ea501559a38a522310fb03c35814d5d87a829f39e10a7cd02d362b606256c9551cc7218e02f0ae735d62dcbbb3203d29e00220f0d88efd7658a2421351bf0333cf1a0e65758ad049e27e7676ba06ab0a2386be97ab06d71dc5f80e95ae2dc176177351f65b24fcce43885b2fe9f8cd193db15761a44f78d10f4bf5be3df14a0e87fbff6efdb34d5edd62488d285f6282b2a572b7b40572db078d199c94bc5f55716a1d54bb02c75541644e95c6045a56eb77405cedaaf286461d0bd4fca267fbd704cba5eb1a3f58af9a2d56f0a9c34a6d3fda235fdefd1ea374489fadfa5e17522450bca0d362c3b2ef0f816dd4689746182c945712afcfe5c1ce788a6407423d5819cc52d29af53e68525d662b91af964b172afb6228a33b345ad8ee3740e8910242827fe9ca2f92dbaa5715b60c2a8ec8b6adac18b86f7a44aa658e13d692ee595defb22db8140bb34a76a69aaaf224c790d5d394be6a3d6ac3ea147a830657e5b9f54cede2c4ec3753d23ef8e16d3f7a179a5c7aa5b5a985dc7340ccba5def94249e0633624b027b4b01dabdb5f5d1b14ab8f6c1c0c53d94106f539f32072ee5198bce836f2e049a33588a30149ebfa698757ab721dcc3625d8d02ed4c416e4ea34c68f8b1965fcf323f523f1ed623c4bf0cb7112f08f7392ce12be5aae8c67cdbae30e66358423c32cd666fca87a91058feaa2ce7051f5b6579f60d6289c6e6932a3999bb72aa2238773974394c7913acc2713e42df435853d7bf8946065f92d64eeec6407ea9386d4d71175b43d8abb27d5b3b5875287259fcf223e987c24f928f2f1e343c7c76dfd215341c8cea43a555db7298d60d6a482a3a64910c7ebb569731a44823257a7f1d5c5ecea23bdba185f1d2757e7647d9270207f9a20a741f44de4380da272629c0651a9ec2c0490fdd055ecf98d11ce46edf5639c2de15a126f6695591148f671bdb293207296b4cbe67d809edc3b94b97bd9c0c1092a227d72a81861c7e62ef79b229a8b247140ff1311d3f315a0ffe68869d4c6ef15f76b75e03bc6d73a30fb8680e48f7f1176f7c023cf9dff9670eebf6a5cfffe90e5f568f9b7e2f5978cf0df3f0bfe569afd0f64afbf7018ff0a71f1bf7db8fe22f95eb49c549c7765dacf7d35bf95690c2c8adf2f91c10f5d339541156295e690efae5e96a98cc592f7514487b330ac2c9abf9332af907e87800cbbf27d355967b68142b7aaf30db88a972600282a9776287cbfdfefb7f6ee9379e0de4d57661fb857fb6eedbfba756b3b70efb65df90fdcdafcba690f0a03924b7ce0a65a4921b373f7d977fc7bf323a0869a19945cfc2c6c4a863cfbbe39126c049c6cfd97636020e0e0ebefd67c214d439e1dfe644be58be84a6703c337c27d69b8986a2b2f2cb66f5912461f2b5f7f0e5199074207f8a8387ef1cbb7fc9e77cca7f828679ab11a2f6ebae5c180ebb4a370565d116e8f1e08ca01011d968de3625815849f3b752a5376c4a8bc9118fdfbc6263bea130a121aecd015bae938e0cf4c80d23bdd8981edd7c1a1ef1409abbdc1d7f340f9bb6994fd68b7e19a72d544f8273132c1f3c9095efffd1fbc77f46e40a7767823614038f22945a770de34832710442ca5c48778081da8779b4f2021d1885acf9b8f1b45504c8262c2fb8a8de359e8c3350de36804698c984d137a1bc433a67cb0ee33776c562839bebad724f2d5b988e0a81fe189c50f995bff93b5a79601ce7dc2e5b2ab7f348fd4ab62f4adb3f79551fa6bec23ca42d0ad86aa23f5ad95ea2f8ad5d74ad09f8dd6b7faf52d96b56f2596a3f92c66ffe37a58ad4396f5e2f65d15f3e71ff7c830f1b1e08bb20e13df237bcaff859cfc5db2a81449f9bd797acd4c2a8e312d70f737655329a3d73df9bc2ca34a2501d7e078e5f3b50ebfebb2fffbb8fd3488be1baf2b327e6f4e5770d7e27363dc4b38e21b78dca6d2fd383c57d771985dc5dd398e7571c8df9a8f65124456f295ef959f85178ba612de5440993effab4d8466d5fb1a0839be5527dab9e2a263d587d4b92a4883d2b3e7223a6692168eddca643302a7559965108d9559615c0d160ab91b2c142bb4b86e3619b52ff86bf2c964242e4f01f36fcf39533231feee9433f05d73c8e4b5f3ef9145c6a918552bdaa52b8dbb5a698bdf3b094da932f567d2d0383bbc0a783645d6ca70e38cc0c97cb984d76279f4d4389e254cdcccbdc937f5fa5eb2a229e8665d58cb256c6ee7c1e4e3485e63c0e6ebd7d935e2355ebf34ee648ce5c7e3acbcec5b59851bac70739355b8c92a94b43199acba5e5df6172f4d9708c81c1fa85fc2067ca1497c1ca8e3dc4910cd52caea0dcfb899ad1203c6fe521c60c396307651460771e4af8deeebfb11cce2923f49a9d7f7a5d4fa8dff29126529276912f8019d405dc66784f19c2603923b6dcef54b96adec557eded9098d65b375b3bf2a4f6cd6cb0c1973d92848170dad466a769adceccd7ecd832109195d3f080c673a9ff1f70ade92b5ba5b550157c63dd4e9607caa07e11e414057aa6fb83770083233de88e85069d5564960d2feba055faf137c3d5ea7d0cd3a855004af1b188ef277ddc2287bab03c42dd8284cb0d0561a6f976120e73d967b94c68fcbbab516b4d72e68baa4154ac4c9c48975e9c1ebb30fef0d8056314c0d7073b3fafebe82f7cccd893c3f73841981be258fb7cd1541557a771736b7610f3ab0239f9932c98521e7d8dafe3d1154c165017b372986a505ecdd69116155484b423b8aab1441bc1c733cbe278636794a6858166e761d8c5ec7b304844b7e35829251ef39bad398a9fe67e682cdd2e135f037521c4c633b7798bc38f1e4ed878ba3925af92adf8b02386dee4f836e9108dbcf0ba536bf0ba9badf40ab2e5fd58bd5ce8f0ecede1e9657dbfcfe347efdff572eabe8d0ff631a37d354de469af3cf3c61ef4e5d67f0ed369c1c3d857fcc82e486c169ec53f8094e8e9ec03946a525be7ce8c7782f2009c3780e6430a00c13398a88470661704305fecc82fd014b0dc624d94fb3e36f98c40945932a4983ebd034f5e8fbd4c5c1f7860ef6d0611e2d01adde690837a16971775bbc50d354cd6017da3d32bdecf75b7b933dfe6f3bc81f50845635a8a3468ca652ae0a7b1030c4a8705a81e5e005745de9b7640c27d6843da84d2718fff7eeb4b6ee51ba519988cafb766583109a31721e46ed369cd314ed78e99802c7588dcc0da5537c980613eac1351d90191336dd19a309d0bb69180c82345c68506c4a07c130a0beccad88e0d2315dc09c44690bce6348934520dc1d2624c0ec3199470616af07196a046d1bbcfd2f71441bcad44823465bb0effb41346ab3d9759a9001764110dc8fa9b8b772187306d5d0d04d2499690ee38c217c53a444e5e05fe1837a8d3f62c67e25ab724d183d40396327d8e13cc227c98ee2b603f9c0b32d8e8724a562bbb693f1a5f9d8282f43d8f93b5df8247b66948c133f8848a84b9d89df4689ec5e15f90ef95f573874bef6ccc9189234b8a517c124abf5de78e899b636919179c77595ad972f850633675111c969c29d63e6b442bc65a18c4f16f9d6d5718d572c791a4425854f83c851de85b1758c6bd3c21438f97e9aefe48435057910a5348948082c8d1332a26869160249ae76300c42ca32fe142ff91afe87ca19973d3e2693200c8a6f47617c4d428152d10e1171be0c832f5414a8dfd0856bef7b4317b0c7ffcdc968ed2c7bc5b5f266adc1f719d4956c691a0c6ea4ed1f7b384ce209fec6d5249bc9c9027a351a35c90c933344cdd175ed120883fc43fc52f344320a98c4b75c8025f16c248f1802962a9144c9609c49325c61f963446112b35449b701175e21252cf5e07a964aa0c27d2ba277a9c01582944ef82a10a43586179e273483704b92804429a46322e4df609624344a2189e33447fcc1388e99a27c44269415832660173a1e7cf61001659ef000838c2d13f87c1c8414ea01fc82393b98d4738a0715bc26ec16461e2bf582cb860a606e168ec03ec3aea85e3cc7e47f91c81e58021836a05b38c15055f8c71e7e18adbb6355643f3fc30b47925640498c0cb60b614c7c8983c05aa734f8dc90e6f366f13a06904bbcc31064fe5946210708574ccf10ead8d39f7e125d959ae88b5df8cc9fa1a294504c5ac004ca6ad8452838166c3a527eaabf76dbc9aa0caed141513025013646fd8e26c664c06c6e018338a26ed8d7092537eb75f473b3b9c2956263c37df8a8aecab26516940424e9e1e52c56983a71285fc36e9e8ff4956dc741e40351e49993059fee091d058cff26918fad7075d8905d2870dec63eb575c207f26d8f6373c90754a50e99c4fe2ca4225fcb2cf2e93088a85f6bc04f3f156927cbfef493fcd6a277d338495931082959b8d8c0ecb549c6d615b9becee7ed55a422614018f5dfd37fcd8284e241227e7314b78bd66badb6e876bb061b28785cf349e862af0c74ea1acf82d70d0cf09cb8ce47b4e8530ff9b927e9ed58722e383f67be4841188ad19402828f2e66a26754446e0872293b2fc0c950838ae22c3f3b9084c29430467d08220f8254c066c1641a2e32db7b26fa05600d4cb6cf57d31c4b17e9047c459617d61557079fa4e4b9cd85f9051cb4e7d207c5797509ad2ce33de1aca3bcdf1160f56c2ef36192a044ab1934dd9b22d422da1c8613cf765bfa78b7fc594238f594bd5164f6e56fb2073942a93f7382b84badd9558eaa9aed833862b19ceef9f9ae5eb6e624892ac4387f2df662c1d0cd795c3f31d4a9016eecf8d6e89a42e16205f567b65eafc97ef389cbf5bb0d809adc5ccd22bf0587810f8b78c6d5d2119f21b1983d41bae78cb05af32a4a8784b7445351ce9bfc0375918fcc610de24320d5e607bb157ef44a83e24b6d94eaed5eb6f7cbf54ddaa9398a7c212193bc54cc940525facbdcf8f99f4fa7091d90949e737141eb35b37b67b73449029fd63cf7f8f1bf1adfaa4b06179755caa92570786bd1278d6130c618865afedcd2824922a07701c3adb6927f6a7a99d3d76ca31aa2c2409a1ce2285c70d69c71dee51b1df4031377844474aed8b81ae639a57879c24ebb2d90fbccf00e9dd12cf0296bff074e9b201ab1b640ba2997266c10d5f4201ac62d27fbe6d8c11ad0d6d5c0c51946689964120144b26a1517983ce3a85bcd4215e8ba6095600f95fea750a2483b1a7051d3eee3cade94f6a802f7d5f883ad98a90db2934895a865c4a884e18ad6b6b02d7fb50674e1b9b7024bceae3b2267637541d1c28efcacc0b96c74c1996baf50fd3eeb04684228412a3ca024eb4d683292229ad54d6ed1e2ae51c8c494f1a0a62d42aed838da055bc338392283713d3b97b82be5154b54deb5c45275d792d8b9e6df4a1da8dd866b32b899a3855e58d2519a45f17c0748c862adbd0aec0bb5d15b175d38e7345716f68f2f8edee3e666300e425f6f6fd08df79ad2222ec27bd7f780c51cde1cbd7e69e4c36c0af32015a61713186fb26583716c06d4be21dffb0a451f4aa77fbbcd5799e12c4442a5145735bb884f439ad252b850cadba501a3d64abc9e8eb25a454927d337f7d456da6d383d7affea28b75754806c61eedaae612c862e5e25b87328e94a65aba54bade2bafaca695d7097559bfa4c365495b457e5ddca51cf8b9fd0369b1a54fe13b3b262026862957136d7fe45702c2a518288690cb34870a097e77df66794d542e9f5359c726aba4095eb26f74318d69bdcb06abfa2beae69695021c49235f93eb2b8b33736f4858dbc83cfe4669e6f1a6fe842ef65ed9f62eb542005afb75b2c57e6038e4a92cb70506e8e73c3501957392c47e8087a4637074132980529d05b9a2cd2311ae843464b26b921ae1c96881586da2a23ed5717c97a3774519a454742b3acf6064e0e0b65c0e4a833a7e7e90d5d30c5dce55006633ab839937786e63386a2a153becb393d102e5c5b57a4c055843351de0b65d268293878dededc2c50347b5fa434e99d9ebdbd787d297ffe021d582ef34f5f40b70bb007f8309f75574039dcbf3852c5e117e80a28d65375331a9e23d649efd3d1fefb4b4fb7d5803de0e5ddf08587471e4bebe90bd8dce68febeab9f4a2fbe927fe48797b3cd8dd55b5952787f1e8f4e4cd9b13eb39a603e6f0dc7829b039ea994f5fc0a367483d7ce806a39ab4c1584f1518f1b00c1b03fd5f9c9d7a01cf9e3d436cf44317ac66d7a9933bb8ef4ab15776ad0ba7b866ba5f800f34c7443f7a8103edb66366cc8a85569c47ac40096f4be4e8d853c47d1063b4fcf1e8e8b73fdfb24f16dfd8f6e1fea7551b8c4a39e0122d2e913871ac89efd481afbc84485841f19c691e03d74ec609a59971336f0b9767e90c832b3d1814146952aa0948ac88fb8c89d7bd5e55f7baf27c6a502eac85c9ff90a4e21cafeed805b4db308ee31b86b173837446c270819412473dd497a63788af3fd3416a4bf5289eff270967d67db208ad15c5733be7876198ba9a31fae1e2a0acb73d05b5702dae07b95742ea169f23228dcb4ab259cd94b5e16cc0866eb2d9208e6e69920289e491671acb1bb85bba8c763350d6c8499024c88194ef62c884a6346198af25f3298ae294eee0e6581c5770d53bd5375ea1293e9ef23127211e25e11990645ae53410c673ca5298c68c05d721159032bc7ae25e3e7495f1300f93878e4eca01cd03114ec27f8761207e5ce6390e47f8388927c870e0e238997e516c105422a6dea567b2abc7d98f0e52aaaed5f0b0a317f10756544c155bf9251c55262f8cf660b774b23cb713fcc8986cf31e331c02f4df98a368c601905e3a6e4ce7f2f4057f288d42a542b25e4995a5ec0ca1708dee49348c1d1bd05c96a26028ef4fb1fb1030be55f460188c669ca36629ccc724852085a0a427d935ae65324c8f5b16a3cfea5907a5c264505f3c729bcf8acd16aea6c5b630b2af587877d775992e54f8413b1401cb25da4960c8aed92edee38cf861cc5401bffc86a2c806605c172e6553691dc955661521b9caf9020e3391a1ce8b0de9250bfdcc87228aa12030d0bb204ac7288ff06668cf1242b1be07da8464d50c58bea28418f9b0b02e2a55d5cbeae1218fbb8a627655030d87aa1e89c43e30ab960fbadeb2a768a0a7a73bb3be5d52483cf1d564faa074a7d76ec3ef3489f574e45b559813e17b2ab1a63e17a58370e6a3d76b30a139f42bc3c5cb31acbbbac9370f9c1e7c27027bd0851d3ea9762c30159d39e05b48c46a737ba7d3d9e9745a9d4ec72d5e0abb9ee2cc352689f27dc7ad4f7559edf0be46596babe11621aa7044efd24391c2b028230a9d824ee9d2a444833906426d823d5ba870c2e36ffea361dde25f8829ca2daa467454065bb59c4bb7683d570917ad71dde72d6b2f6a88c555bbb82e8a7002bcd553e898304b07f22ede0189e09aca9361df8288467c4c30f77b1c9942c86491f4cba474edc990664264caa8d27c27d5f30634c1805b999c3937e415934a8df6e676c5ac18e859310918c6f8f1992c6523d7262a3489ccd7433c6bf979f72e5362a9d739662874a06c4994aacda944b3c8eba5e71295da4a5e459c8bbcd9e2e66f71f999ce03a96e7ef620a593a97e71966d1033587383cbe7b90dc9bcf5ea954ef0b85cc2bcf5d1fe7954ca5a3e6e49f3f798fb319f54db2e1bbdf0f1fb4821a2d4c7e550a5ae512badbcab51f458b8d4102ee1a734f219c44590e3780e732a7cb7a7094df92e459a203d3ec3b8267787db5c3ed31a18182164450114c1bab734617ca0383349a4a455bf8ed822e8f62c1db4d5ece69ce1f1d5b9005134c4c13672676e6a584d85908f840705b5709edd142be0a105936fc8c495b10b87d6341797cc1aa03f7ad075951222d02878e42868de25286d80eae70b78e2542673ec58aa31eaafce0316c161b9f0d5fc9dc436e395145e14f8914fb0c12cf958b88f374765f38af575067134720ca26c480f5681551c5ae7dcbe1bda3daef30c367fe9de320871577e4ac3d7199560b4c937c92874c5ad7fc2c96d10472cf069427de1cd6c4be32243cd5b7e891b77c6471d9b8f1e971e20adc54be03842ca4eace6adead331e5056ad26110cfa25404db9124656219bfa6a3208aa483f66a2a50d88022a766e342351d5af4afa481bbcbc6c6e45efd2af6c87d5aa7c6db141af0429808e476355bdff43c5b7b15ce99838b8bb031fe39f295f1c25a4df92eedd64d68be36e3fe33b7eab3faca85bd7c578b328563402753942825257d73bfcecbea07159a4abbcd176178fab8d33553e7b7dbd0e9743a4dfc4f7cfdd8e9409ce8efcd0e6cc0056c807abc637cc97de7bb1dd8800dfd628343915f643e672e9fe95d4a239ffa272c562998daffecf7d9cff5fade4e6fa379d9effb7f3cfebae41fdb5f1bcdfade4ebfeff7fb7e537c2c3f663fd5f7a5f8c8be351af5bd9dfac5121a75f1a0beb7b3e3f8d66b79bcbd8dc61efeafdeebf737fa7dc44116dd9300f7961cc7df79b11fda46e8d73561c160cdbee8aed83db96f478a5fbebd1b5947d22fba0bbf2f25eef9ca768d80c57c7386091133e6ebd53ee15ff3f4b4797858f3a09d11a2698d64dbcca228aa659504c92a2bbc7af5ea55b3f7f1f2e3c7e69151c5e08fd20ac5e26d9942c781d3611ea33fb6beba712f205e0ef5d3a7d3539b3cdd8e0baa2ac54b3cb50bb4db204a40c0e0edd9858828a73e5c8ba30e26c3cef324400a1814fbe8ec922e992bb8f9b5bc5306a59e7c6d4b2bfae5f39c1ce27b69793b85b02aa34c32833003165f04932267bd7ebd3399ec30d63a3f3f3f972df5fbfe8ef5d1efb7f85cc8754755f5aaaa7a1515cbeab88a17ca160a4d26855ed8ffb9fbc0ab79e5d5dcf8cbac0f8ef28ea2f98285225981e200a34b049bbea5e9af2c8e4c91d8dee3a2a2dfafd7fbfde61eca2acc14a019030dcbc2aac262c91db97d76760a73727e56710413e6fc7265f45db68f087205d4863fbf34b5e81d1dd4457534bd5bc2de7a9b83883311a3bab16332321d395f7fff22be15ce7d109bb5b5184e2dadb8d8553203af0721ded52ce4b58a2c45db69e8b69d820e6912757ac165af7b29ba8c08f6ba976ea70090a704c7f2fa19304174ca7cb735c1721536856b07ca9b92aa6b064d3a9c024c342b361259e625bc5903cad1291ccc95342c28b8e57691760c1b0ac375870db2a1c37ac5a1dbaa183a502ecdbce0e6a59168a47651e3da1c9b924149f82affcb581c765547372ff9e4a901e6d134d12a6507a81857074d4b1ea19fad81cf0aa7c6f5c719cac6da8188eb4eaf8cdb7ffac9a458d576f6afe2c26d371722edbe18824e972ea59f9268b00bb5df6bf70e85f95bc8af1a19ca134489f186c5289c599157ebba4be2917353c617a4735c05f6239949d27554edecfbea3e3bf672ef8f0f60f3e9e6a6d09b76e0384ec0a7290942064c866fb19d763b8de390b5029a0e5b71326a8fd349d84e86035ef53f18c535b5b9d5daca966ef912976cbeed388da3e5c58c2e3f527f79319e2d8f9360794ed2e5f92c6a787bfd3e6becd55173f536bf36fa7d56ff9544cb637abd3c25c9727f9a2c4fc962f9eb2c5afe3a0b97fbb3d1f29c4e97678374f936be5d1ed201d6419dd2dbfeaa7ef08dc68efac2771fea7b83b7c8d1fa70b17c757ab1ec1d1d9cbebbec9d1f5e5e3496f5deef5f2ef98754a6b7bf361ac60647eb10f40ed3ddf0317b7f7cc07b2b868ee121f679aa4e7ef19b4f16f8398e67f2151ea8e057e128729e26050d24a16c16a6b6eacaff66519acca20149a93ed4e7d5739a43591a9796bca8b4aed0cb5714371645695d61dded9416d11daa2863f4b5db31ee63ba2c282c6e52004e524e0a1155a501ebe208b8f4304afa330910a5be602544cd8fc942584c340e7ab0bb9dbc371716fd6517b69f9579726d0a4b47ce4a6358a6148867cf4a61749f396114ba6f1428767e9ad069120f28639297eb2cef04f79e628295413c91d1cd910fc338c4f3f4f93848292ee7721786796660320bd3601ad226be62e2b89200573d439a5ffe259a4c67a969f7fbf5de3f1b973ff7fb8d65afdf8ffafdf4b23df270f9cf4ad5fb7dd6efb38d46f1d53fc5ab9fdbf6259a6df9f887b6797340892bb7bab64b5ae070a871f0fd1391f1ae2470282befba95419c75bd9774e25bec5b12056148e0d773f41294de849264115e2e3ca5512a1c4e16cd78d8447b29e2983b0730ee1f7b97c4b7814ffdec58c09123490b0403674740a27cbb2fcea70d8746831cbdcea5459e5e37f77bf3b2e1ba903047358d36d7d8ad76efe59bb4f22056fddd572372beae8c493193449a7bdcf89a89637e662731fb70b1031d63105e9de61e1c1d5eec40731b7e86c7d6e373fef851fef1c1a1fb31967e9c7f7c7ae87e8ca59fe41fbf3b743fc6d24ff1b1ec7871111d9070300b494a0511ea9a1ce84419a42459a8dfd16c22be16a69aae5426223322f7f4574764226ab256abaea9cb272bba4e291b99aa02e9170818fcee44a1b35281e3dc309e984b8bee717e7151c579e9f1047e846ea7e301e7effa78024d9834a0cd9fb98324c73824b0a1fdc0c1ad1ca21d05d3aea0952d892790d0a1d017575855d42252625951b3516a896257505c82f4ac2cf849bb0d1b983b14658df0adddadd0d1d41e44a68bee6de96f9bfadb23fdedb1fef6a490140bb761d652a1ac1a9e894d16f65c1efab4ca65521ff2282e11a04b0e78d22f98dd3937c304724f75879ee96fdd8ec3a7d4f4b3b2bcaa2c3f2a8d58d9b1d49ff02f5acf78956d38d63a79fba6dd92cbb00871c2ab86d76470533a1d04d355ce065ca273064f312fb259e0b6efc955b2dabdcb5cae3764b55e31c1db0a777097d5b4248241135699dc8afe4122f0335761e5c8ad8b624e04fdcf42b3dd86e3004311d2944ea629c60183c8027f6c7113ff13012362f621f57939552cd741dd4c6525540765669b7ad6500d231e60aab4af40b8d006111048e8201e45c117ea83242d67fd93f333391154061a740649939998037c6a308cbe863486cf4c706023978ea626b2d4cae6121a06e43aa4400649cc1806755c27f19ca1bb49e42b272cd682b771a4b0697354c40c55e741492e434dcd0fd8209e256444fd2c08e49a42825b1b1f3b1ac16c3a8827e242adcf31df84879430da8277f8c9d7409af0ded8b0d7cb74f39935398e851c3786de94a5ae70c80b289bd49a3f61c3e10f5b830f17079899b896df26f30f2b63358e9fcc89998ade321521c3696c9f050a363b393fbb429f805dfb9e93afeb02d686283e7826e4f7c7075752b09743ce04b33ca0117b5394cfe2c90ad15c30b7e5f6be62bb762ab2960688b5ba3a6d4a9254c588882c499cedc378ce0b4d137a8b732248f8229cf0595712273244196493b364e8cb257099e459d5a0a2724583e5f27455a3a6d66265dc295bcbb9445cb88ea2549640992d9389fc5498c2fa860201191815e0c0e0cef9bfd504f96f2eadfe1b15970f1707ff6dafc0fa580f2f172a3bdb0b721b7fbcde87c94f0fd84d309d52df7962f846a40edd953fe5f94bae681aa732d9b3684157ead897a761b3a8dc4e498e6f5b57432fe7e3d868e1725f17d3210da211a6f067780ad9b34d70f9380ed154765ae43826c22298159f17b5e31a4019017d751b8a3ce39428c9f1a7a8ec1cc789756b92d69611cd46f180474a9438a4ad301ed56b58afa687a366b45cb347ae0047fdd5d00c5ef3602dcc1cfb00a315a79a2f79246384ecba02f94099624c4865396f25349d98b624720b2aa6da2c9aa966e4959402e61a2903c13c0f57ddc194bd155d810d732454d263476325936163d751bffa7c8aaf0f18bf8415752668bc37016ea2781e0996298ee630bbcbeb58ae1cac8765cb0fba567140d56028b957667b720c40d52958f5980b2920061dfbb4e69013dfbf0826f422c6ad275f19acc9e1328d568f4f3e2bdf15133709fff4133c5845cd3fd9c5b2ac97ed36ef26570b49805eafb3486022a371e58493ba8ba961542135189384bda1c3f4ec96267acebc51f79bb8393eb76fb1d60fe78c5f7fa60b7793aa889b909204aeba9b630c63e008e0cd1001835f76a1bbe9d62b54380f1629048eadbc4e6757acfb858a79f0f7e97b76578f0ef829eb76190831fe5c7f7887eede990b105189cad7b935c8b83e4bd5578f9e5bb41f93c80fa9beb1c0a14de9a82955e638b8fb989069dd5effbd7c0dafd0b26d58c854be7c94b72e61a6b871ed3f73da760e4195034847cf2b340a0e58ecdda468f3d0142cb1798864006379b9891fbb6da0f1ace4b42ccb51a4070b796745060a47957aae7b6e83b371eb5a691bedb6c32a80c88a1bdccc9bdb5ccd81f6e37937e1721567f12fd02deafb801baf59c217daeee66ac78f0716483e79ab80daf19c0e9025a353965e0df762d26ac066d3692cb70363329de617f4ca81775bf98ccda4d871c4437b57c9566f2b4bd38aa0a3349d4c65f63c1bd96bcad253b424787903281bc409bd885f52925764f3fb15192974ce2b94a68418aab5c41db65bea2b28eebed15e3a15c1bc9699e22d797b3f9b637e4b92c7bb245edbe8ba83eb32baa31c9e2ec48ffa1f5fcb74966272964a0fabac015d3c1f495c3d114c0043a3eeb0b8c32ab7656440dc815f0fa431d32c58e6309606d1ea940eed3688c41909c56c39d1422a4c68f15111f95295e21a1681298d48982e4402c4b148cca84f969cc3b9b15be04a037f5bcb72c4d2f176502ffcf6262ced524e9f9fa1db59795861026192374b67a91a2563c2eb0c28cba58df02fa65870ef3c4d28f946f38533f12363839cc94bcbb467e1fb2ca78b67025b2ec1e64970fb5d688e3e43270897f8fc33696dd44d3dfaea1bd1cc87283012af04aedb4f31491f99d67b414be4f6085a32bb47d0f2c98277907fc1bc3d2db1fc072d951d2868a9fc40fc599621c8bc4531befe5c7e888dd7cee8d3e1f8fa73fe5cf8eb7d343907ddf56181148e65eb5682f1145ca88b81addb1ae134a15392c82cb10a46e10c37a1ac3c3740bb2daf95c3943b1392a44023bc2d8a24f12cf2e1f0fc224f25d622be5fef7a50f30bfe956663eb6c033297b14a9729ddcbf23c4ed2f25566541caa15544b78c7101a5763e41e2c97c6dd1ffa5df1a430d0170c2bf951572def1ae4e00c9615add58acb814aa986ac226fc0abffc181e2d672073581af957921643206a31da14dd54a4f3a029573a518c12d4681d1e2f5c085760326b955142deb5a295b0705639ca1c6070cf59b12d0a62e645e9b5c002226aa189a3230e5faa51baa84b606b00a97e38a53747dbab82aad96a573947943586a63219d7761860ecc95a96a29b1305c394b9fe75927bb8e678d215e95eaef9bf8460315b962f0a8f66c580af8beb3ace8a750cda32b30562ba5bc27575a48562d75c6c056ad73008e64fcabed16562fa46a51d98da20a5206ed2d66432883d66ecbdb0bb3553faf7e960ef46acffffbb8074055f61923b5c559c2f72cea52e7a10c34d3d719a285d68380e5b35462da0c75a7a5cba89219f8964b301eb99d2fa42978d79d135a2f8a2b9773bcf02937e6b8d6c9474793699ab1f47259e4ca1cdfeb85d2de3e173aa0044b09860683487f5fcb7b6232637843941f47f2e0794e1676aa3915a1310ad2f1ec1abd0e840b82fa08189b51d6ee6e6f6e196a45eb2a60fb6295131428eee107e6d69597175ff1d32e16ba0668602cdbf663be9f1daa8045e3b91e6cf1e5b94bdae734d4fa6095368bdcbc82915dc9bef37361d55410fcebf2f09d26711a73697c1a44657e3762acea0dbe57e01aaf2ee40bcf2079b9d384dc4110b19412bfb5e6d54a93206a4ec85ddbed61e274a1147e0dbb26092c673f9d03d87919c538602db5c6e3344170d9a32a992f5afe45b0fa9ef8d8114ff3d2bff4e4cba9a0561ffc80e502638f19b95b3d667c54cac78c8fe8fff563f6e2df3b662a8135514e6813755db0885561b1302e4d7ac3e8b28ec835f898e142348c13206176e1a3e8bcf03449285ed21c8b1b22f5200c23911507d284442c4883db2c4fb086a31b1771afd22de59a66c98f31a9a7913b9a014745bef5603e8ed5450b5c83c0c4dc34a413910aad024c3e39f73418dcbc5cd48791a790726de93dc8abbdb2b0b9c675c5b229d642f9bed7718472aadeabeb1d99edc1913b7179603755bded94c9b7caa29d4adbd4b6e4aeb025db6dba73939ac8f5824b639a2c97903d47be4aca6ee9b4712a58702b03471c2608ed90f68151e85db6589ca44ac6ece5869e8b9f7a61b44932c28c189742336f0d4818d6b58cf0a0d370adbe928d6a017b498771426b28572aeec2e092f1fb37be3f4c6952d6b64cba9e77172c80434f305e704f7fc52c9e1b75ad7eeb9dd5576b6d88139f4aaf975e6d410947a5f6af19490456353408f22f734a6ff8a74f16fc631ccfc47b3407f26f6227209ee98d41edb2182513b043796baa603efba814d99a6376431778b9ba9b89ebd21f47d05bf5c203bc49e6015e528057384cf05615d3d4fc20606fc95bf9a2d1a85c0e560746d9cc308b82f435618774104c30aa2c0f40f7ce380452c8af9cb9939e2ada0b2ecb9d766c244afd76ac2ee24aa1c380208aa36610a57444138638b3090943ca52ec61115e498e01dcf51e8731490bb8f3214a638ca7b5df94e25ba0ed9a49e1aa2d2eae4836835391437fe83a271d2a1a3917fa32c55daa01259064425f392bcc63c5223c550aeaeaeee18248d22701da53d17936a0ebe78cb85c0a30b392f4b3c1e8dde5d28adbe37f525ab8aac857ae5a28585c7544826f478db9cc7c97af8091a3cb65e1b9ccafea02e593850b923cf4c897e6b2ce551cbd005c5d13e13faebee11b571d694771d4116fdced6406186763fa35d6b6fd6e4de6c58db02d9473c00ad99f13be3f60344aa58b788c1782d37ddf1791d5f99672b86e58bf37dcb4f819ba740b3678735d2b65b849e49fe131ddce0a19019af6f0fd9cbdc67fb8c89b31bef2d9cf95eac1f5d0adc7f4117ac7dfc6810f432ec87885691c4429e0c90d5e20962471c2d6b65d6c3e7bf2d422e54b3a207c8b150f6d1242cac50283cd6dd905c2c00f86438a19537147402c409c7de7631ac13c4e6ed0d7439f2e7930cf3211b3344e304c7b028c4e4942521a2ef20326a7c8067e6eb866e2cff0c4f6f23a41453e98e82b47d2586c2942925235e183288dc5fc9b07e9389ea5e8b56ab91cb6db2042686495453cc3f017feff9484a26bd7f12c555781e29da1aa63169c2035bad82a30a592411bf2db468964fb19b6f2ef8494fc59f815158987b7cfe7ec86e29db6f365475d0d47b1ebd9f57598dddee05a9cb2a5206f7d360e59030c5319d078a8978e5290e49abd478ea98b7cb885336af1187e71f8d6c8264f493a6e21dbd59b5df81914a09fc56d5caa74559899094356aff6713a3e7b7fba7f7171f2f655a147326fb5f2e795bc10db3d23be3c2bb27c7f3bf8df2a4b8580bf2b064d67b92f6cf7312e231845b00bb58d7c0a208cfa16805c94e57fba9da6f8e6d07b14f8661ebcdb2b0d8b6fc0179ac4c74118d6ffcfff5138b4e171a7e1c16603363282398b36e04778dce145f3c7f6d61089c2f5daef7c73b0a34fb3f5637c5eb3ed1ffbefcf8df1245c268ee89d18200424024d31e3838c6e7fee2ecb0b5794451f6551b62730fcfdf79ae5c5206da5c48a7b36076990f78dcadb9ee57b11c22cba6d1c50e591cb5de4f0d522cceba337ef8ede9f1b4ff40d0c83f12cbaa1897e51dbe876763a9d1abc805eaddbe134ab753ab5cbac40b3fb68ab53032cd0ec3ee29ddfd205f0f083833c53bcd7d6f9535512d6f62828eeefdc1da4898a0a2909196659448dcc2a25036b64f5b28061a61d014acfc02b0e5e752f01f08c0f21f6e4a7321535a17ba9038ccc9a53f49e06bcb503816c18781bc413713fb5664d88953c984c61dca823c85ef71295113e05c52e493cdebc745a13747dbcdd64cf2442c7be185180e9887b4d6a1b35d8d39577a029bf3a2c34efe5ad76ca34975df3e1095b64c08cdb02901de9bf66c12d0979e9348649ecd3306fc91b8471443f06e9584a4d0910cbba6d7a5cff2998f538e4abe2e91d18b62a5e045b2b48660e918f5fce9f029d9fccd36cd883dc51b5be894558f04431e3241b9ae8a8a31f1423be3e30bca6ad19d25b1a0299061e5c4b65102dcfc348d0d528d12af44fa623b80826b42e7f66286e60fff24d8b33567169b3243d52d73af6c9f15866b98355ebb7832a619991b3a884c81bf7a4d4c95987da6d388be03848e830be6b6d6ea36deb3f46a2fb9ced6435752932c969edf73c6e9ccec2b0dd7dfaa45b98724d434999c8cc0f360e754c5bf288ab3edd478e29f5faecec37538ea3855e534105730f4818521fd57abc084acfc080c164969294fad99d7e52018f44b6563eed6e289d8a1c2f822e41046c110db2fbf2d5ea21811439a33254f9f4ecf4e8ed85d90bde208ebccc598a6712134a2226ec4be2de1fab694fed043410321cd2010e9abec61cb74078a3c9a39dadeecee663d8e86c753ad06cf632ad6bd3c3f61a97cde60b0d2c2bbfd9e94812653b142ebbfe3ff6fe86bd8d1b5714c7bf0a93ed46922d4bb693a65bb96ad68d9dd66763271b3bdb4d63ffdd918692a6190d7586a3386a9df3d9ff0f01be9333929374eff9dde7e639676b7140f00d044100041444ca282f5a15a11f322e6355e1b4695c8043dd3a92f4b7a5ccca083165120e372c9a76a53905543ea125e51f942ed4d8b0a2cac399a429eff3e508c2bc70d2166c548cbba3eb02dfad4c5e257d0da718d8a6472e2437be99ad442705fd107b3dcd24cb7bb6ac77529071c2a9b831dd2445c5c9121e865beb25492899269959ef6b0438295e966c5a522e0e215c74814d1c0ee23e6aae6838699acf192946b959178cf0e578863393a1a50a12b7f9a46a338c735a297e21cf10870ef1a78cca121c2cae0c7f2d7f46f42d4088873000ef0cbae71a1deb0411f49f501987b479f12c39abb7253975a26ae1cd7da388e5c3715731d46fd5f5c15ca7651623dd40576b9c9080bd2623ae4edfefc8de63784459b792fef8f0bfa0e969bc0e99e5934e2190e4de229e682b1629e04dde1c5960805ef34ad4a1b4d0ad84580abae88d82d85e48b21b8d2f3804b2244ded0a5dd29a079ec591c991bdbc3794fdacb53bdc7379ffedad1c83cf216a692549d373c9fc6012bbbe621cd77447d22e0e005243450517e252d4bd3bf6260e5e6f772071c10a0702c7524da5da86bc7b4bcd1ac5aff7de866b94d76c527ba2d8e1600d5537c96fe7b4fa459c5d51661c2895eec8e1ee6dcae17662db2a78e5e3296ea23d0e5eb27cc224ef3468886ae792ab73ed82810763fd44da4b691ad98d8c646d4bd2c9ac79d12c9a09a3686cd609075c733a65310da9603d57064c4a7e6a47e8771dcf8b44ba344bdc3869f8d45d092135d3d594bbd29b345d4132b7908584ded172229b650078a909bbb34e0650c7bf4417f5b102046b4f1c6b38a2c226a113d6a3da8d73d34f5fc559c20ff36c5ad0f427b62c1d393258c70d05bd9af07b24904f9ec42ecb16932003cf6e271b68fbdc84eca8d3f9afe4f12e6a829a4c07c92acfa6b3ea3c799f155338afa396e976239176a4a79c52ada0edb6bdeb0ec17740de0cc9d70e1283a1d120128cea7c964dc4dd28dc91f7ec57108a051d9d5fc81ab54b1b8236aa16432b90f542778c9bcc799b4786c47b71162a3ec7bdeba4d971d21ce73acca5ace52aadc6912897e108d5ddc8f6aa0cf7e998cd45b7c1998e03e6aef43eac30bc8ad82fdf6f103b36da81c8968a9f7eb1b589118b3ce66a4f5133d827c4b9200c9cbec450bfd6d98e37437f67ec9f80f7c103efd601bae29ad6fa7d7278feb277767c417ee390c9574722b413e599b44626a551fbf272e7f6f272bbf3a4fd0452146c75def6c8156644d8ee5c5e0ef00f48d3a6fec6b44e5b5ef635a5ef907ec6291b0393e0cb92eee4d9a84cca556fcad834a7639652743fceaabe04b9169fae45cfe17f7abff11e67cb724c7bb36a6efc63399bd31bf0a6c5f88524cf0a8aca9f47bd47bd87bd7db2bfbbfb88f0051d639a5e7091e224958e4849b1ba99d1d2a832205cdfb284ad38676936c9501787ae55e04d85f116e025ba8cc93362d50c73468aea3a71be4cfa654daf9cdc976276dfee6c5f3d79bbbbf36db777b5d5798353ee169ec60a7f8e151e41e145f8e1a78df19e7b0be83941197bb596b2578136467925a923328c6fa6b36583268a4b8a5c908c438eeb8267ef6997a48c641511b44be741be6215b219dcc9dd4f3c9b16dd80f3fbfe43d964f20a14e2de5586bb77d5f014b186171175e69c0ca499c1f19889c4af4f89014d93550ce4d4024107074f64fab4f75ff6103e4684437f55fd7ad22333aaf5a8f7aa57b57b9e2751cd252f32ae7bf7da6add2da6856189e550c3275b6854d741b051b6de6909eebab347066146f0c6f55d8915f1d58a44ada6f48784a68e0e2f8eaf3a3e98feb715a353f16fe6238228499f8068ee233a3d397bddd0a75a44dc47747efcf4c5d9d1dd11c1e64044ca514577edf9f31389563a7a753a12910a726f7bc329d68d8e5c603219e7cb1463e602b040bbd166b1882a73f2dffdc7286a201f9772d63621df452bb1ac17a721f8c306f09b10fc5103781a827fdd003e0bc11f3780cf43f06f1ac07908fe3705bed1d29a89d7f7dc7e1fc385a1533468f159699e436ec627c38bbbd5d290b4f0d94b0bdcd75b42006a09b2d430b7b7a45531a72cc2a3f18032ef348ea4e3e0983a39df355715ed74ba24faad629d5005d6740a185e2d7a20fbe230eeba0aa7363c1c590d22bf7a5dac8e5c3d1debcf6508f295f01737c5cb922d943cd292ce79f1481196eb9e3c548367a2f1a81b419626571cea4dc424ea5ffab5de411458c6aad2afe3b46779287529ea07794b52be674cff99b652e9389cafe0a1dffffc4f562c6400a38ca3c4bb2c26acac960578510ab12ac93973f08c59f19e42e2f89c2515580eb3423fdd924002f13c599111355b068ca9e3a4a493650ec64a21d8a98c4be2ba639bec4db416814a858fc1070659b1d029915add5697b47a6e747021992f16f90a39f0cd2ccb29b9a1ad9292a422f6a306a5fac0772225e582358bab12fc89a74aedf56cc1f001dd69b0ed46600f95aff5a221683c4541a9f70019ca8b34aa463a6487086cfaa7e79a8a4f02c15fdfc0e2af8ef258b577077c57da97244ddba6e52e699db63a3df94c49be350c36c7ce4eb9c17ee5bee8b68dea8a1db2bdbe0b51bfa7a6803621df5bb300be4917fbd4f890b44e47f4873d5021f0494fe601d9fd58373f5a75e3f944417917d6d08f39243b88cfd7ead606496b33b2dcc096d18caca6b335ebbfe397c5aaa80db01189ad7d6388b91148ab48e6b44592724a1241d8fab9336a58540a85e82df6304d69d94eb31233457689c01553c718b799f749de250b5a662c0cee25efbc5d52cd17818758065c151d3ecc9342c192c76cbec893ac404778e23fca82d757d0a04ea702d673e469dbb22ff16b9a7af97d9ecd17396d8be175ad07e22db20d4326649bb464235dede7ed3c1dd75926cc0b721b81a88ff5f4ecf4dc3c14ea5feb5ca6ef5cffdc3c49d31d9c369aee2c92329907e929a211bae70b3224ef93fc40fc8f2072e8d081fc2f1946d627b025624d29d4c10fcb12439e906d5136805602f9471fe85a52b1a9c6830f2de540429a286b7cf87c7b65fd4300831fde4d77b584d62519c758665dc7ad2874ea75f7ba96f09af41af2cd89bedd994ae28b2fe46bd61081c76fa120786fcee60de69b7e9f9c31c216b1d9abe33a9eb39cfbd3b8fa944b4a06ced7d09f193b1ddc186905f94e7121a6b4c23f5a5008e978e54c6ce9b5a9794d8eb9bd57d126beda93688f1278cf6bda8102702515cbb35123f61ac7ded2db3eabf2a7edb3ead0ce460dd69222897b65204d8bf1c0c377452c1e76e71d7692a6f871e81c047b5dd24a5213a30f5e7aa8bde382ee0858f5cd7aef60bb4e3c4d725aa449298397cd5732702e29d84da82b45df6505d413bfdb05bbc167dabc155a4a2523808adf919dc7e40969f1644e8f734e5baeab38fe53907b02324f78f533a5ef9a207715e051b26a82db534daf81db177032d66113dc370a4e76d01a57fddb5c39d95fed619a6b151027c816fb3305a7487088442b978c95afd2e5b0345975c97b8e3616a7ee8f14f29420f00e9bec00308104a82904e3b89951ccf102b711e3462f2d35ac2405f3af411815a0928e564e24095fa10da7972f56029580f1b1071d7b3169c3d37ebfb68ee828e372b9e489670f1762cdedad3be36e77d9b242b3b74a67f5e081b860a9441432aa1f7f8bffbd12372eaf081ffa6383b017063e44f48a00eb81006dd909e59886b7f7a3a44ada1d3db0b60a89643ba0e1c48a563b0d119a7270798a4982561046dbde1b33eec13d4b1b48964516896e021d574fbbfd770bf29942f4714270c50963e518dc1bdc731adc1ca0e7f6a3647c732e072488c58e12e1754c5616c2930dd5689237e7c7f7f62062af2f1afdb462756510277d41553b0647136fa37e89f1bef6ffd6f873d6f8bbcf5a636731699146967283169a56b8baa1b420ed4929e48c8ac955eea2a18167efb32ab47c427bcf4a36b7571cf4b2821b8a7277bd5165eb0e10705c301b43c5c0158079b52bb631a9883e458a2fd8e7918f3517a0d133bf04e9b43bad506e695b50fa155bbba55c1d949a4af75aefae01519e5b525b1280843e2d4e63ca50d3b11ab3515db0485b566fccf726ee7f2eaec57f1263f0f32b88c2d350ebf57f25bb10f53e8961c859226babfb6daf3b2ac877438d5c45df3c854c441b30a7cdb89020a617e53a81c2f51d12753c58252e297276beaea1e517e5dac3ee0eedcbfdb65907e05ae0c07649c2c15610eca96a16a41ff99d15f488e655e295a30c19ea1536f30b0d5efa981ff0122d94d3f51bdb2ca6cd10953eab553d4c32246dc0e6fa94fabe9a1d8cb7e2f4a4715f3b90fc26abc633d20ea940fc83e76718836c602e0c70393f12175bf992622616b04ff6f60fc8a8a4c9bb8318160c5bb60e4d130615036d83ae3c6cc223199585066ac3dcca91508d201eea460e0923ad3520120be3218a84c3416c10bfad01d7c3c7f4eb28b25a8ce2f6588390ec184213c8fff6f8511376b245f61f754941a7494549cafdfc29d01cc4a3dbb0bdc7bb8ffeb6b641b245bea96f34a5936499575683567b6b0c1292ed9027aaf280242351c64a79276d083aa8688eb4932e19f98a8954db5e20569ee7e42578dbcd8ce5f454631992767b644c83896317ec906dd21e5956c644fded4b0ffd3e19a1e30c6927c578c64ab243f6884c1f224bb65589e76f213f0f49e298fcdc9eaad8833c504960f5fdae7c4b1a70c591e83836110ba722abaf695e0cc7ea42f8763fcf0a9a942aab37380d0958af2df542d0ea9420483367b237eb25910dbbbdfd1fe8f6be29aca3fc7e1ffc64d04d466ca9ec3d8500325db529c40fb15cced760ebec84e3c3ce75544833a7695452c9bdaad379b5debc79f366e7f474e7e8e8e2a79f06f3f980f35f948019a9f2ba1ad7d47afbcb552b54db560c9fcf347865ab15439d53bb458b5647a9a55a699a92d3d353727444449b44b546defe787a71f5cb2fad7af650b193f317f2f1ce3b4a17110df81dc49330508afa13825bc2b498563086a3fb18122c3f6408b04fdca12fab31bc67f18c50602e500ce93bb20b0a79f5fb7bf2edb7df7e5b7bd780f99337207191834661ddd4cabdbdb852b3d93b3f3f17eb47068d20bfb41acc0c96c612e2ac6a5f9d9eb51051b35281440e26d5b90e9b9771f23f5fef7e20938457b4c448db592583b851324e22cfe096d5b8296429cc79c530e6abddad3004f5ba08d63a76ac779bda0e9ff0c853143c2fdd468d53ce2fad6eb064ad5f5a4142e8c6975c0d6bbe76c5d7acb7f116d8da92ed6e99c037b3e53c294849933419e5d48f7fc826263207482066e9b6c05b8a8c28a1620a930a5f034c6945129862590d43de65c89479325781ec4c5ffe9e67c53b1db4a46029fd8df75839eda719affa7952515ec12b897eb2c8facb2acbe1a9c35fc45fd7e325afd8fc3a2bf8828eab6bc541aec5ff619c6dd54edfbfca6195d81baacdd88af41d50ae6bedfe16692922bacec8366991adbea3eef1388fe88ae0c888a7e5f19bdff13163cb5719a8de49b348d03b8935a065194549777b598d8184e44ff039fb8515d48fb3a6faf14bc34816259d641f04d45b3105d0856dd26a5fdebff28705e15687a4bdab95029229aa973c8a670e259394dbc062703eca34a9688571595ad1cde057e0cb097617c6b64d5a6f2fef77ae5aeb0c2d7294db38866dd3eeb6c4587fa0497b13de7bcfc37861f874afe623511a9b7395c95d92c06b387b9ed41df683d887fa45f48c599665a76b371fb1bb8676a705e395639e6a989a92cd959d5246cc39c7d98cbe366e7eacd73601af2a784e2da82a9b537b37c732c7b83a64517303a5a0e7d8f247c506d2be26c63480863f6ae1c89aa476a7d303c69bfd4edbf7dc41df49d9efccb9e44378446ea24b13bd3c6337a45d3fedce2e28d9bced9a6449b4ef3179eeff8e1596eb8a6a12f6bf7f852b7687f5add8dd56b7df272713b24838248a55899eded1551784bd2ccf8910a775ac2baaddaf757d15c5b547c88b6a46cb9b8c53535b774e23c0909372393496f7499909e985eb060c626f42249ee03117f81ed09be77ab683ebf73bba72d33036bfa496990faf93d1687d966ca7652784aee867e42d9a5b616dc002e3e1ef8fd106dd2ce28a470460bb49e0506a4ec02380da8123e50946a5eebaae9436d12ba112a82029a6cb64ead1410f020e7a95b1a20cf3a5eaf15e3c5b4fec69df666beeafbbddf3bbde4b6cf61159f7a6d43a1e7d03553404f7771e78384b797a7efdf2f8d5353e3a2343b8f91c049ff1cd1c19e2edc8a91302fff4e2f52b0f14eb87a08f7677afdf1c1fbe3a1702e2c3c75f932df26877976c936fbfe92865a685d57e512d03c7cd59bacc19d921b3a4480547d07a18f4c8e590691324374e4668c4d9fbf69bddce205050a65fedb5d3ec7d96d222ed12f117f7022c2bebad82227f556010a05256d085b5a7232cc7395ad480b7afba64de25a9af15155b009eacebfc73ac24259d270b2ee376efee7cfbada0fbbd6f777777f6befdf65b9787adc8776245c591b922dfc752c9f7fb042e80e57b4a729a2c245e8c289f90c932cf614940021eafc6b98a85272a5571ed8bba6eafc8b6a8abc6b613acfaa607a3c12871ddcd84b8acc61b4c3628425e5f3cfddf3fc1aaa75f6e820d46896b93699526e198190c8c91d9dcd6a8adb3aed9b36a8ce42607f2ed2da9b19d43329ccd6ef0e1d9e6dd130d99e8388a2a00894b456410ece24f3411468e70bcda5a9d695b176508bdbc17f3fddfc00878f7c6e087b1a4383fff4a1edeb92bd2a2f9791db973ab6865fbdc46e1570ac2b89a0a813885903077ea8fcce9f2a5bba4ee53801cba4576c8de1dfb0606d0f8878a7ed11edfad5f68eaad6d1e776b5aebd5a2417786f2b097aa9cb6bbcf77a56edfd30b3b924ca76b8b2577dc00d2fefd8507d2f57a78a73e29e3fe9fd527141537e9d3c7481212fdc4a2f2a2ee6d1ca67293f069e0a2f4ff0eb3ffec6186765e38d004a7fa5f72a8916d3cd8eedca52f72b8e19c7c42eb7ffe2147b6c93777efd77ff6b0fbb43efee70e3db1bc77efdf973afcb687ce357de74b1f8577df325fec38344393ea8a9d86e3f1cefdfc7247a4e9a7d4ba44fb298fcc0dfbf97feed894c36dd23ed98f2277485b1299159f1eedeebbbbbbf506856591f9596bed2c5b137042f3ecfbe81ed764a480c3aff6a953c467a00919c4868c64d69d4be20827f6ed5cb38bb9e11573c928c45f62dbcbcfb04ff06fa44555ae858776e7aaa17b9832f34efdf30e7ad05c0cb4574bf419f3c01a89fb5d0c6a6006e77e84c4800339601ee2c640f9033d0f21888e52a1a62786c58e66e14c1db743b3d6bf27afd87f9dbf38f3e6b0df37d472969c757a08252df0c5522531f7f74510e1d2f1372103db8da93ea7eb7e9c7e15f2aaf19dde222979564c9fe5c994c7f1d00f152dd2f61f1fe125f54b0b1e513778cea3edeab0267868145b8fbda7e5246737b558c16095b142da0a42bc3133fa4049bfd147a1eaeb24f606890e1c15bafff8441c94035bb6f6a9b22ab3b16e017f35105a3409a097d66fb74bdeb6a6d35697ec5f35a5f6b3494d08706f50e0feab608aaa5d63508835f2e38f776a444a62cdedd8a11914b4d5b0ce7038a555451bd31b8a2e4a60f88f4c7286dd95d5fdf98d37da6e4da730a1e25f4bcd55cb4aae575b49d6dabcd28f3fc2ac6aa178e34aa256504953cde1f393c3f3e3736b9ce2467a9867096f9bce7589201cab350bc846dd2562eddd4486af4e5ebc3ab978e3b5f0b2cc5899552ba7913daf0503e436b2872d98361a9325fe28174826418440e735b912a79b83fea8d002e85ec5f66596c5fd3adcd33b56502bae2b3c92151ed5b620dbd8b482220f5de1b1acf0b8a185696d0587169db492b29aaeafc6267b10cb3629c842259b941bd5d9d4e23b6ee31e5f8e7855b6210fe7155169d5eb7248c6fb2749f7f37a72a5c304808fdcc50d3bcaa659058cad21a5a59744cc4b24a2e83e1691df1c8916e04f345fd0d20a1710de0262818589ba0088f1042290f315eecc75008e1fcab500efa5ece64ed0ab7ae100877a72fee2cf9b16e750d277705b5d0029771e357652f6909f14d8c958ff6e0c80ab02588bbd1e35bc78a1f4dd493161ea6e19ce7128b1d7f645218345b47fad5d2477e2dddd24a9a84b00ab40161b04bf48ca29f5738da9c45b8d294f45f517133d1cab2118d95afba6d53c193ab323c7a1f1459c6e208cf9f7368ea83b08800d6b464a6afd6c384eed619edb2141d64cef4676598db8ad0ee5cdd72b4d5638dfd23349ff7e56b239d0eb064823373f1d42e8f5c553b829390dc16282e0e616eb5f9d30b338503644c49fd2eaf5c5d367cb3c47d9d39e254b0d67c19ecad7603e608a3dd370478199aa4125b289f0defa27a6ce6dfd9389a34aa9b03797e5540d81e28e129aa9fa4d67f31cd5ff5469a76da9ce3a7501209e64da95de45c9dbd31767173f5dc13347eb7447bded1679f809e7ea3f71540de787c368c81354188d69964b4d94a5768717a3ea718ffca0b3b5611795c3bf652e88394aaea784a396b8631d1dc93b56eb082802d4cd9b93438a41ce5a4775b410a50459ebdb3b90c1912d2ed689ba30984de56218af4538fc1c6ec75d79eff6552c18f7f215c6bdbcbccfca342b921c08f1f23e9924793e4ac6ef485690827ea8c83cf90d7ca5206e632fa21ec1d6dc24d36de5c4097c0798c40bab1d727b4b1484dd7ec70de7d58ce4392d325a545181d611668f605d8f842c7b74680cbadeeef367b179fb41347e57b4b69393c3d2beddbdda48be15a7056ec1233d50483dfe8efe08c56d15824fa995efb2398ed4f6803f1ec20639525b441e0a77da27aa0e22bae37631951fdd65cf1c39bbe661edae31fbe6617c99df4a5c08fb6959fdf528d65eada2e9f99bb9f091461ee1c38e5c4186c44a39ddae62414630829bb23e065fc1d4dcd10ff081738747b4cff64d0f247b4fd2d430772369080a8bbca5db846ae740b3f3b9519b29f3d6e6942a2be80c7f9b9fefbae6de5d8874be096387213531768756e7d0fbb9a053e38cb29e8d60365c8f85c814b92d2b37ea1d1684c382706e2d880ab8b3f182c80aa2ea1d1744d7dcfbfa0e0bc237591018d2c60bc2a1f75c2c88f1c459bf20e79865c45d102cfcd4053947f177ad42f97ffe47ca66b6750b0d7a715d50a0bc3e3fdf54795ddfd6c64d9dcb330a77bc15d6e9a0b196a8f66863fdbadbbf2db2e7a8d79b9a11ed7cfd19ed6cde9068e9f1e7b47487a6445bdf7c565b77694cb4f6b7cf6bed4ecd89f6befdccf63cfbcba60790a15f41ce77e57a6efdbdc777607de7a85ad70253e4e6e9809f3b6af2876b2e1c38a701f843d341f0f413c012c18495d22045860437ec81636c8247cbb2886c0b98966fb2b27a20ad55d0eaeb823b6689b86d969ef2b5376a3b679492ecdaad5d084f2f65b1ad1a47087778771f9b75c8c8b1c94e5b4dad3ff54d3e2bffe837e6f94f3c6e7e170b8ee74deb7756d0c3d1a8ac63caaddf7fd78713009f25734f706b90817f91d89bfc60945b55ebf5c55378dd5e1fd159623c4bea12da7a189f32bc90563425af8bec3d2d7992938b6c4ee30de11b7e5631218ecb780056be1e0482929e8e17aeff0dc5d41dd8302aeab00d638252bba0105ed84507650e1444bdf3a0449903841ebb2e10943950f225be0335b15fc64bb092cdfd1645590074c66e02a033edb180701523c19c55cc03711121888f684aab0011e661f891bafd37ee16065297b9903238b38d5396797032e8a10387650120068a7501a1cc8384c8a05ed3a22c02a6623eda60b22c0a6d7a3bf4c2367ae0e019e3f5413ad33890f0ccd59b7c51e602e14b5b17c87e6e69838152dd03b31ee622e83cf910acb9de9ca7c90717382b1a803377fa1d771f056c9539c0bc96f4ce3dd2530fc15c482873e1543a011b4e96797b037de96c4059e6c149a736070ecb3c40f0f4f3104a3f771b4c3b605960baccdb6f184dc64629cb3c9ce032e6352dca3c30a75d091669171c21bd6511650e9072cab4816499cb8c2d6f2a05679739c0f0425141e1e1fdc6d8e0d4e67a4e9385d4f34c6975a27f3b60ca8464e35276460f9f7618d18096d5d88195f60db501d46fae2b4a5381bb7f406de98e0a5499ee7194acf849a1549c53d077a9826060ceac9b624ebc667e36165c67b07e6559cc9dca721282c6953959815a26e6585b0a7c181abbbd09d0db6718687dfda9f20700f9495c8ab550448721b1284015c220066e2cfaf6e4c4618d0ed0ed4330de195b1a42029f545de127b62c7d168c7a2bfba781470d96c75aa5b86bff343550c5e2b5614bc94199dd9a2e74d9864ee51e59079dc7c78127c1bf21e10af882bdbe781a9e708d3560158303096250d5d6812b461ae9e02ce187395ca1c482e8b445b1628f5c8ece2fc26e66fc2859e5d974569d27efb3627a910532c9f3708043957fdf037d1dcef6d0cea71f82c77af4ba1afb80174f370154571d5c6075350940e07631b4ef1ac19ee7c489f3d1c2b2643ca69cb3d20feef19acb78051946f9e861fe2587597442f6cbdd3664595323c8b5652bba91087e7c6cefe2c7b226f470d2f9d8951b823b8784f89d975149e0a383db8b796276a49aad0d33c309cc7ddd2db1749d90c2cf67d9445c069dce395fbc716f9e992ee5d50e47245e4a3a71a9ca58d1ea46b7936c38e20b2c3d43e08947ad193fc80450abd670d19e14bfd426b4b170f620a96a1b32e99b24851dc3a2da0daa9a92029f7ac9b88ad6dae6615837e5f8630b75e18dfcab3d322478e0d5ddc9bfda0b6edce6be7de002e6ac980a4157f60bae1d7689076e459c52ecc59478b0d2066eb12259e2c12d4a0ab368e0c209f3abe870721b5729690e815f04a96115bbc4c79ff0ead9b25aaadbadb807a9120fd4bf07c1f114ac87645a0e9cfc87d7bc533be5a75beb7cc6caaaa9160044abbeb4e6355a1500a2554131a9ab5a65f57d945514b429f3aa488f38ec872f847db5d79b6425b74cc60af299535c5be7671bfb33a7385816294bf2f81449b9d15f1555e914efd63595bccbb5554fae674dbdd862aa9a72396b6aaab58cd775d753fe733e3675572fad57b1718de534e89683daea63d0e98cbf3cd56b78c25f9efa4447cb2ccde85cc39cca8268b2c1aff688ce77961529fdd025938ce669576c55ff19894e3e439dc06bb6939f8912ad7d16db1dc108da884fb612f10b44c46fa1f5abf6b21aab50c1f587479e71945cf8c97c91c70712c44dccf81984b792d0618c00a8ed6b3ad53f9d0c4f4724b0009ca7a41a52fe717b8bca64af37d0585d543ae3c6fdd55ecd32c987f39dba6e8805c9bc056210baf4edd581d35bd2cec890ec1e908c7c07b935b2ededa0476c59bdcdae70f9ed3eade98f3720b60c12e2f7fb443d24147f7e6dfd3d99575de21558bfc047cafde9826349804517772264a518071216d2e6392b4116dd88cc640a60bb2686ac183196d3a408f3166d449c6b09742d910614d244acba42d4455cd7b247797087dde4ce8ece1cf5ffa179f1b75a8c3dfa0f1b8530ef4d1a79a27d1fd57b113280e4069fcd2e649d6d6cb743fe4abe319b15bcc5be30ebf8e64e9ca39d6dde356f9c112e12391abc632176ad70cf119fd1faa9349a1a43f9e50bb508c8d634abf854238faaeb81cde49a795c4b89251b7647cec37fa64f7799272198fe87ba759a1561a750f3f063ce4649fedc6402e9dacdc6bd9f07a47f7999feb1d7ddffd8ae66b7bcba2dd2db32edf42df6a2ae9503cbf145a5e5f7b6a3d8cc233294b13ee1cd71e43d98955b09bc232ce85df4f382436d0f42cf57b36876e6f6c882e15513cc3ec0146913cc43802953b0ce57333f04bfce63021ddd36d9da3c3ee23aed9e6729257432a1e38a64f3052b2baebee273c6206eafca05001fa27a36fc8ce741a0d5b3294011896949bd208ab6061fd7b588404eaba631a3369927d5ec70c495677132e291e7e6233fc0814c249058d3ae83b8f8f1a0b1d853b8cb66dbe1c7e05dd1b56302f1ab422afba08aa351085ad3a9deed1d5725ae51c0aa167cb41b848fba92d7a0fd31a8a48c1dd14af2635009ed29e16c988f613b8e7ac56f27c87b9faa3765b5cdc0c74e5d02885a2e9ca4e9b9b4588b4b672a2352eb777b6064ed92342b295408288e4186f4a11f68deaeeeadaa0a7aed92dff6d03442b610ad0b7210c3e1d0611c87a510f1dab7d7a0a67da5e40a66d5a0192d47a33ca24dedf7095f2e806b1156e42bb2dfdbdde1d52aa762d6db7be8804d58093f153effda93a4a95818673e23a7a1b38eeed34bb9847b77e9a0f262b07ba9cbeabaca2d42fafcfeee841db699df539ae5d16314a2cbe33913cb321706599238d6deabec9af0da2e52b1aec34823b158452e0b0e59ef81cfe01dbe6bf8ad07e7315b9bc90618ad23c33b306c38d99fae8a5dd4c518475d8ca2d4952d3e2bd9fc08bb63aaf7fb62556e289925ef2949c83cfb40d8842c18cf20b27952a426cc392c3fefaa294bd94d414057eae0832c76039d73699a55b3e508ec3b78e0aaff649c2f29efefef3d7eec92c8bd76db99fbef8704a25ec304ab1f7216310e762c27878be33b1bc7772e0ef13392a6c3e78192b2db58eb8289b9943f3a90b067c53b644b26ea745141ab439d7b4fb7a02c92bb7537ca7e9f5ccc2899b03c673759312563965239ff9c2c177a4938a510c2bda2bc8254150e0efa21992f440d362137b344e6db9ad3a4e0bda6437de84ec25f95d7bca9e39ee448a73a51a753d98d9046a2a2c09098a61ebb0db9a7bfd79069e371d8825373a811052db8a2423014ac156dc1a9399488fe4af61f7932d34ad111e244b83ed97fd4f1f7e49815ef6959619d8a05594add1d6d7754d4b8607855861fce93724971dbc3902738dddc69247755ab13f47b6f5f35b1f33dd903fe63bea390644f2a828a6a914efe7548f6f643a953b2590817c06b643735bc1a316d885db9b34466cf2dc1c9f55e0eabe8fa1cf9e9dea3c7bbdf7e8353daae927762076745c548321eb365519928fda45ce694771a91e9b915b7ba477fb3531e2bc94734b405dfc4ac42ebb5a3b11796684616668528e97b5a722a78873d0141e3b2735b6ad47de847bda0c063417e3f2731b8fa531dc6d173d72fdce0903735364fdbede7df071dbf178b590549f08af1c9a93f6879845857bc6de2f1d7d8c9a3378473d1db26219bf02a36c7612641d6708f0c22ca643f47b84b367d1d9121ac23f39b07a4d647066157f8b84e54ecf765fa1677f6385d246552d17c4546749c2c91de27394b2ab169172c2b2ab8d5115a96ace4a40de20bf9cbdedf1e7fd359bf54d63b6487a13a57ec4f5d0308c64c0819387ca04fbe0198804e646aef3a6c69b212c83c6ceadf465447dc58c2013248b713430629d46b490d1f1d07b8f61e3dda8d0d1372eec751a908e83eaabf3dc69c4011c92582abdfb72e2b6421186521a4af7aaa99d192d60fcf3c661b442e43a68bf80ebde62aa2a950655faf6625bb81b0a1c7a213edd6ebe25d214477415690553488254fa229a1ecdb2986c878cda97cdfcedbf07aef89c7e4a523b8b8767e7136af3224b9b522eab3ed18843d9b3e84b32b85d4bb0f19a2befe769f3e0eb0819ad7a9d097151eee7dfdf031b52e37f5b7e679f28e1e72d24ef22ce1b14b79cdbb4ce2bdd24ab844614f59ccfd2be1a7be8651f4a0adde601ab873574057703ed8a927652b741ed84faea8acc0661ed891afc344b0d403fbd9f5755760377edf7cf526829d7a60ff544efc2ed83f3db037b6aecf80ad5a316fc39c1534a0fe7802c8e6f0b9535a7db51f3b0a36cd0fd1140ef82d22d9262ddeba8278c066d7c589f547704e6917c93caa43da905c83b0c4a0dd782bb05e399da8a5e3404faebb66f35397587948d1aa4e0cdcbf3f3a4d60c4081b7c1652b802874f0e70a0ab37c08ef130a23772fae11a5c552ae49a6ec0a718b5e2d39128adea3b9b8c5db6e210b7e09b806045db20e738c157ac8e55b392f219cb61bdac86381f90478fba7a36fa7d929009bdd1cb5531f5a755890cc8a3af9d4a16382e8f75b10ca1d5e2560c16ced2069001d9df776071652b2656cdba580ac0c70ea0736b3790a76440f6f688d33cae69c5acabf247dbce368348884eae6765b79a14f046b4ebfd3e63375d50dbc962ad0d9f143a6bacb7ee100d35ab9615b8af1e4e99f428ee4aaba097acb54b328eeeabd1005a8e7b9ae32aab94bfb7b764af4beeddf3b0aa4615f67a66682315dc75c1f8199d1e690b898738d249d87c123e3491b8f83abd64c403a73dcbf08572bd9ee8048f47bf82e623d10af3b082e624d10ab3b082e626d10a69a44b8aa5442b9c86153457895658b53c8d101c9896560fb2b2abeddfe39c3c784030648c84b822515daeaeef542744d67710c4eaaba9ff6e48f69c0f507fdebab28a1aebdbedcf757d88588420f1f6d54ac6db9fad6d5fd7b7db9fe9fab396d4f85fd5d45784116f3f5ddbbeae6fb79feafa690b826942f3f1f99374166fff74fdfcabfa76fba7bafe694bd9386ae847916dbcfd95d7be285ab5a4f5e4ca21e8e4edfe1519bafce5c0fefc507cde76f907f9de51f0276f1f5df90fb789f564c367c6ee6b9198a9f06296714bb196e7ec8693155be29189e98d61bb8a4ba9739428468ad9629001f350f23ca7d52b8be5be52b8da0aeb33091c5cf27c80cdd25cdb3203716f7dc65534d238e8cf54c7431d9a924bfc8a718f98aa5cd2c69ba7f2bebceb7224868a3f63112e348eb646d7257936cfaa48ea7bb56bdeea3faf365b0a7b9091a580f636cd5d1ee9441c734d7f7174073563c3d5e7e1b2bb478ec4e2253b0a57d75afe5000518214a6bf8fe4bebf8382230cb8dd908adf3d5bb5f36c8023f44245b734577292d6fd7b66105a580ab4d9350325b6d39b94f9ccfba6f636b68010b563714546f320abedd6733518230ecfd7eafdb078362dda5107c576fb8360ca9022ea03f8227404dfdffe50bbe0566886aff6829c3c62179f9cbf507b97dc50923252b00a9e610af68bb773b4dc0ace09e69e8183846cb9b75969655f2ec8b2a8b25ca001e5349b533cedfdda704acb7665e5a412fc2768068fd3a606e0ec73ea0157cbb8568f57335ac2abd38291312b2afaa1da9994944adb2507df0a19ab05e5177129117d74d00a122cde113621e39c8ddfc9acfa9e254cd44c722e872691c270f1a28306b9fdbfed3cdcc362716782e2ce7f7a4b1a5d041068cc632f5428475401766ddf3e13d106388d053e6ad6f5c3f50df1edb70f1fefeeea21ec7c4f1eef6ad9170cbaee1df9936cf29f6466d76e0143b4dafb3d50e5ce603630467f8a35da69232bf8222b694a46ab98c74bcaca34cb732a7d5e7632ced48da93fcad9a83f4f78454bf9b9677deefdc6ddf57b6399adedf2d398b55b7c380a6de470ab541e0a3e7d18df08ffa66bdde09ea8bf7a157b967da069fb61a757d2459e8c69bb7f79d97bb2bbfd55bf4b5aad8e1d0c8ce888775592abf34aeb96dbe169730f206319ee2bc9870457e5c99c928493a77f6971d23e6369d2018eb05855330cf4cdd2a4a29d5eaf17e0192d2b6027e825f95fe7a43d656c0a91083a51a6d07ab97bd4f89405ba7c9e4d0b88a72306fa1dd9254f486ba7159b8bd55cc2c239e56c5d726fa88a711a6a91803b7f80065d133646329b4770b82cab1157283be999d826ad97adc0bef2863c51c3df266f04d01b44d609404f6dd053017a5a077a849197b9043e12c04775c0ed9938f1e7e27f380ce7a20e72469ee819da263381f5a73ad8b9033b6fec2e776041fb7e2e6163f20e3e57dd2743a2ee95b54ff6f7fdc06326ea981320efab7d2138d99d0276e883b841f986e8f7ea0179f1b68696c7a98f2e60fe4183be6dca2d08a03d0b952e88a07534f9ba2000f4ac54b22000f3ac5458104079462a591076ce3bd079e415bf80f3ac54a62080f40c55b2c003f3c2770d8dc9d60394ced406107f7b505ec8c5a1b2807960d34870203722de57fbdefb02cf19d1a73fd70f511f58014a4762f14f3c05e6c928ee81a980bc5053ce61ab609c605c4465eef13be5c673f08e7305e53e31f08401dd71752fd51d97051e9c177d6ee8de6f02e0fa3875116027065d33b017d03016cd5043e9b8715e30c360605c75d7790f647d6877fcd7402f2175075ed69cc4a8f241106917accac678951b278bac4a72de6975ddc175fc7ee3132819c651ab871a9e4e6d1468f6df2674ecb2c83ed4c698fd60e0e49e6edd213ef20715f4bd31a5e1bf15d44536a7bc4ae68b785c7800fc944412646812de42609767394b2a85606f3708385cd3fe872fd0be9dc92212aebd7e69f13bbe565357e32169edf7f61ff5768d00c569f51363ef9ecafc326d2b62906905b14c1c51c2ec1f20bd031b320cda4914e373e18248a0124e070145b8c28b24abe00a1d4d56a6fc8e0575b3a35cb8d041a44907dac49c949d0d22e020b87925ec8067dc0fc9497420361d69483e260c42ac122b789dfd08d16d01d50335fd3fc1af4e0d6d7c8cd650229e370c0c9f1c0e03cb1d602f1a8d33455e2c1a2bffa41f1fcf1ac22f266eb23d5547eeb346fb21bfbf069111c31ac4c61a462bf257d88e6de30ef9d421f9a1ff9cd95d06d0593ff7565d9c1ca6dca55448651f56b0cb23d3e4132bf60ac1797414eed887e16b716f5bdade3fa6965bee542963161d4dea317b4f6d75638b8855d75f9dfa2a86d833276636d47fea7c72a9545d79bcd9548c4fb3e2f1b22c6951e52bf2d3c5e9f3af658a1ea8090feaf4f3bafd473b10811335cedc6e0c6a5e3f3bbd703d558e0e2f8e2f4e4e8faf9fbf787af87c405a6fdebc79b3737aba737474f1d34f033007dbfffa7df29d697e78795f504a95cde90ed0c6e57dd2ffbe0efb3586db3f8fb43200bbf706d8794517c3cbfb7bcd0d9dd6b4d193b90c366f68b7b7bb1b6bccc1efcd91ff2fda988753747e405ab129df0ca7e87c04a735e7f644df0967cd9c03fa531bb39ede4f411f9be99f8f8fff31c034c93b6f7fbefaf9e7bbceb460401e4e48a56896af75e799464f2883d4f838498d116c3828fcd801e1ea7ef77e7f6b8b9cb2d1bfc90e698f3be4341bcf684e7ea6bce255290ef4fdddbdafc90ed9dfdddf253be4f4e4823ccfc6b4e034255bfdcba2bf758f6c7dc97f97e565f1942d5665369d55aa4f25e36c5291a7ac5c30a9972187794e00889392725abea7694f54d6dd5b16292de13671b848c633aa3ade25ff92f2e17e6f97b405c0e57df9edf27ee700ccc8f364a56c4b0229284427594e09fd30a68b8a640519b3f922cf92624cc157015a92687ae48dc4c146559215242163b65811361150562f4952a9289d373737bd043ada63e5b49f2300ef3f3f797a7c767ebcb3dfdb1515c5ff5ffc74724e9ebe383a2627e7e4e5ab17ff3a393a3e222fcec8e119d93a3c2727e75be487c3f393f32ef9f9e4e2a717af2fc8cf87af5e1d9e5d9c1c9f9317af88d87a2717272fcecec98b67e4f0ec8dc0fa8f93b3a32e393eb9f8e9f81539fef7cb57c7e7007c72faf2f9c9f151979c9c3d7dfefae8e4ec478df5f9c9e9c9c5a1402490284881aca9bd8b938be7c75df2ece4e24c34f1ecc52b72286e4a17274f5f3f3f7c455ebe7ef5f2c5f97157e0393d7ef5f4a7c3b38bc31f9e9f5cbc11b8ce5e9ced9c9c3d7b7572f6e3f1e9f1d9454fcdcab97c9e2957db5e6435db135612bea0e36c928de1ceb84ca6944cd97b0ab150c98296f38c8b6a5c604c8a140dd94072dca228b5ce02ea8b92bfd854a5d856640a7230794527391d575df2b264f38c530920feff7d5212faa1a2457a2e7a38e664a8ef5fedb44b46e2ba25cd313e1c06d5ef715abd54a7fd8b09b9bdbdb4cc37ed3fc8f5351cfad7d703f2f68a7c84bbbaa078362118d2ffc103ebca27db24694fd72343323a201f3b1eeab00e046c021dacd85ba30e582846bd59c25fdc142f4bb6a065b56a2f3a1d92be5d5c09b46f17570782c9950e9373068ad8010401c5ffebb6afaf1198374e9685c3e9f9f5755bf41b531ab28257e5725cb152c8b507e4a3024f2d696a4830588c4c6028970065fff6a84306a47d7dedc29b5f5db8238b46e5786c2ab8be4e3847eb8226006b3cd667d9a8fc7d7b6b8f070bdb955593a8505a60a3ea928c0cc95e97084c3aa6aecc2f8471b60a1d67ab7455f1dcaef236bb3af0015c02e04800b2bb7a163c7ac04cdbbc4b045d5448175cd0858dfca3fd43194f344440406a1ea44b18fa569800c2f5c484cfc4dbcc1abcb2f9c9b87be7abf988e5400397f755cdcbfb6213b1b7f8b19755b44c2a565ee164efeaee89e99877f4eb3c1c3aebf8dd7726bea01faa81f750c09b768196891e64e4fb216172313b84912179cfb2d4ea8137877fa01a7b40180e20dbdebeea9294157440ee316b629d45f8e852af357f254dd236eb92e20b4da03373f7ccd4b1031bbb98643d995d528ab58660725d42356055aedc99bb990959a0dd465f3b9c27b19b8a9d1d747a79f080dc6b0b44594f2c42bbd3e98999e990a4ec2d967cd62e7b2a388c9a18f5c738810789f09a4d7018c108fec0c76d03fc0ff968719849562479eef52fe8b09a87127a564267c49f6d31bbd9dbcbfb383997f7af3a1d351f59a77e1fe956012bedc81770b4071db4baf7d1a3cfa4ac2500be0012b0965ff304bd265648bf0803dadeeed89d845a4929d8f338a9da92c46c2ed409f68fee5f81acf5c50fcf5e9f3f3dbc383eba3e7ef5eac52b2248efb08030da659614159924594ed32e99b11bfa5eca07b84c19276c345972d0805b4e3d685c4fc4853a5daa0829599ef62eef1f28967e7cfaf2e2cdb590a2dec8d886e56521d9e1a4a4f477dab6403a5ebd173ffcd7f153b8527facad883058d3f6813ca31faa136719e4d46c6fa34c220e46da9bb3d1871f97596a96d378bd2659de9e53ce9329b5d0e8296b83c363972810b3cf80882eeffffbf2fe81b8e02c8b9226e35932ca69d88a4107d1500c3aab45b1f3e1ab4317fe6bcdcbfb6fc568aec8e57db24d54cfc57ef657df3e7cfb7859215be465991595585065ef80175c88a50b4e10a00e115b4edc2d7bb2da2b98568eee9fa2af82728cc9446120370927492e68774516a22920a6092b2922eaabb537754fb12a37a463022c68a0f69c4fbb821c31aebd35678b928d29e73d5abcef9dbd383abe3e3efb97e4ba86662fef772227abf465b590f90d58c0565f2eefb760f6e77c4ab6c9e5fd16a657c0424081c53a7e9cb8aa054c46b417ce420fa220be988801a39bc5cedefabe47f000e71648349090fc582ed99e21a4235d7740d4b0025683deaf21399d26ef28277c59528c2123c86251b2f7594a5373980b2652bc67ef682a2e9173c605958d1571f59d35171fdae29777b42a04436fe8d11786d67c61d457a8db894b07cec9619ad143f6677e598c9b042e4f72107d2f185b58f22ef451c2e8b26591fdf792b6f38c57dec84b7b6f884201d39bb0f23819cfda9615aba2f3c8e04b8ba810641852158e4f520d4099b104c450521ee1a41947ceddd691c4dc5a500c140d978a070f94a4841f70cb324021cf161fffcb3cc98a9a46c4480d2268e1f6d66de19ed3c2fa4d6527aa9487d2d4b983b63db14862917586ba96b926ddde5a5f452723e34cd2f4a72c4d29dc1cdad8ddaea8b6384be6d40ad4265b958da08542df3ec37a0e61d06239a7a538ac0638eaae2332965985df20c6b7fd092da1cbb2e6b314b3e13f1e01d58cf2190468fd5f30d4f0db971a6bc6555f9f5a189d7e7b5b3ea57c5c660bbca31bdab3ae93471ac2c5e313e33d0bd5edad3871d4cf9e3d3cd81c78b83f786035df53f36300a2abc9392dabbb8cb2f6e8be171cdd700dd8640e9d2d0d82dde5fda74951b00ade3b0390c0204f6af1533bb3b43bf2cc66234ecbf702799764153ab4570e29804ba99e97acc0406b4939a515d1dc253249ca72aad4522f4b9a66e08d5200d58ef3e4f7df3d4250340da27cc64fd9e8dfd0f7023266a9835d54345ce6adaa74e59f62c159f9212eeb6856fe016e871f6c8c430fe7c79858a0c4c59b1905775a3143ea9884fb44a19c2dd28c97749a94606d54739fe559b58a4a0719075ddef3ec1d753a2f3b0e1f7b124800dcdec260d492aaf2e8263d3e7f7c9a2c0219d0bc0180685d5aa9789a2cead09cd36a633490d1b47e062b3bdcdf80b09b82bca32bde25e65011bfc903f8c451e9801028a5af4852528b0946a7559c6be670fd075d71b9b33c723468b8f4841143b5348eea12fc8eaec4ce9048e2ec98f792346dbfa3ab0e5ca0b6923cdfb23f7b5cdfe57fa841d1dd8c8843ef22b2d0a6acf45da7673a12084ac1101c6109c6c26e8a2db91a7a1cfd3e3963953849e0563d5fe454ec874489c8a0ce2fa616fa2ec98a192d3308938ed8b2b161638209f07be44208de376c99a7fa5ebf286955ad08fdb0a00587a7844c9cb85dab2b09779eecd0c9241b67b03da5520a05fa52d221ae8e6c3a338be36cbc49c9e66d6b7662fb0cdf446593d53fe80a16df3d1304e13c7820e847b3e698a4667fb7e88fe69c46a081501156b4e8d7fce8ef85d36421380cec8379e21f5bae202abec77a2849ed9dc2e1dc335d3e5587629e2c7af36461d1f47512518b82567d44864a2f799d74c95ea70b7b7048ae476f77430db69946576fe67653f34498048f97aaf258cf2d721083804908f557ee112d8e4f6065900e5ddeb093051ecbf113b5622fcb6c0e91699b6f1d962903fe3368ba7b9027e4f23e348f5fa588e7eadabe12976732946adef6e57df89da4f3acc8c01c8d5a07adeb3aacd89c0c497f6b8bfc7d9c279c93ad3e69476fadea1010ffb6c853901a4802449c546cde23cf98901047cbe9140c81cb72c138e5525a29e998cde7b41017f08a91a9d8fd5925ea274a9d83882f6694b0e20778df87ab2aaee745aa0b5f174c158fa50f2227e3a42023708d558f95395b96634ae649914c81a1598df4f5c1a0062ae6418709f2b87301828e56528b4b72a1641f51efefb02896daefc055f4827d4bd6700424fd31e32f29b82ea9b1a9801f78f3536f37d16553ccdc52c265c5b4477e483885759c09e689d98f18d835cb84b04595cdb3df65c411ce4806b1ba83a92c80414f69c56156056757dad6ac6aa1b459509ad234d2fb1f68564cf562f9aa100d281b2be387b4064bb3c9e45fb8013cd3093e784c787508a94a69fac3aa0686dd505ec91e95a06d2543727244cb0ce71615b0672f2eae2f5e1d3efdc7c9d98fa1264ccca965370b8872d8acddc1217b959e67bca2052d7984613657888812b9fc2628d2ca69228a80086b8c0fc6ac5433428b2cee3246536de35146aafc19e37459d709e8d250dc99d36ac6802315acca262b02fc12448c155b96c0d9605f8d282d90bd7036a7337663f32c2d15974ba5854609c6b8f725a4a4096e5ef90c39c68fbc0529e98295d52604a75560760515abedeef3719d4c2a5a5e3b656216f0d933cc17cfa645925bf395e4393217bdcbf90ca43fe9752c36dca6437e2adb691831af92b2fa21a9c6338f870861309926159548bc59202029a77ecdda4d5199771aeb665f33fa7ad3b8408e27b6123c4089cce5395c7f17c7a3e6f27e1750782627aca6cfb06e7080fe04b164cb6e84f3cb4f9e305983c03b066ba140b57ce01a156a9bae411a81f3d1825d13674e9c27e6103fb06e1432c228f95554fe55730e7293e5391c6b59915519781fc3b576c6d83b71346d321da036668e0649fcf3c1dba293b5ab526384a99f8735ad9a0a5ebbe1a2872d2b1baea65321591a35424a8b2aab564fd97c9194b46c27aedb8faa0d4b3a8a5fb396e36a5926f91a1429a58be3ff5e26397e8fa19a41cc9a3be1c12426012a49226b50c9ab53c6fd2e09321ccbbae083ad5651ced62098377de335f33188cc8d06d35172bd9e1a3c3819037f562ed1d546de0e04b33ecad257cbe279f2fbea44d37dc9955b88777148b39494cb82e4c9ef2b6b9f94dcbe43084829bf1ed131835b3a0f502d1082a41ac4c6616ee746edf1149c10b5011e2d56c5f17a488f2f2a858a355e4bb7228e8baed5bea75a1a4bd406803c69e8eda0b18bfe69d006eca0c6bcf23d07ed4fc3508c5a6304209e85c152def86053bacec10968594f9e3a9d22e76ae43cc41104501f836e70b71bfebdf993fb623aa15e0d879d71750d51356ca44950adfb9ac8ebbd2eb94e5ceb3d00be5db7f98c123ba2ba70ac7fa9bdcb2cecc126741db84c356f5e5dd31e22ecae65165decab339bfd3ef96199e5a95106be034d6f99ac507f3262d54cc71f12b77a4f19a986081a97a1f1686a54b65a03eb3a0a2eeb8377cf8c3977d95a627ebd07cd4b8f445182aa2b7ebd079ff04fe9997640eea94fe01676500b5943d14a373dd4157b7152d524008fbfd4e8debea3ab708f11e53c8bf629c10b59a99717bf88ff1ab31afe92582f34a02e3a0c5d0ae27bc8fea19cf1c4a8c0190f66c5b8e3c1347d3ca8718e0bae8fb19523464b8bb3fee081b722e0a8779d98e5c06dd5e990eb045df5b07ccdc048e8b72706253df7aef702df3d07c3c790af98134aefdaf6c23daff2d5b1a579f7963394522ca146227c968c2b56ae7cceee7012bdb207b520f6054816524d4d92962c4a02579493f99ca61924acf0d8c48576e183d704494e164999cc69454beb7609ee5c90540ff065d2318c4dc0534c76ac8bc10ba5cfb9d104039e77d902dd098b2a2b29beac933505a64552565daf6b6882d0c630305288c148e732351d1523540896dc32b4da986a3c85fd79315c3f4ed775fb379c71bdb337d8aec44ea92afd3d1aa9feae86f1ff5e26e377fc79f68e1e1aca362e4981f18a18dbb81b9832e3ee5a8f9615c92a7293f0a25569bfa83c7b476d38dbb5cd1ec2bd8ddce1ed233038549b78b8b68b1dddfd88b6ffd59fc80182ae7976f0c7c76eac079d0d985a6317eba55045a00324c70de877e017442b19b21ed8241e0775ceab81da068db07a670c2265c164d599a936bf5e34b0744f7979e0ab58d76da47051fa7df277b311bc8fe170c9d0f694ae1babaee7c6f98d731887bc647aa3a64e8af1f0802544bb8a263cb37d799e8d29eeda9acec406b1f66185663f75d3cfc393b7dd860fd2971e135f93db5be2173eec90070f9cbb9eb4fa09c0b77b57d2ee8752f2e57dcb61d00300f1f7f27ec77f1a1674e39160c950f9a175cbe844143ca02e2966e2dc2bdbefbbe4ba4b3cab58bf2f2d7a4961392529ef6a7cbd62df3a6cdb6cfb7dd42cfbde56d77136a7e88d025a6569d8939906a52970beac928aa64fec765cdb75bc21d3df5e82605d69cc1ba0492f30343bbe9deb703209d7355186d7e19786ecb5a8e702680364e774837e725a3521735625aa736ba610f07975832d0b1a7eafcdddcd34e0138d9efdb8d754588e13ea97d6cfccfb061f884fa3a32eec23e9bbf96713d59ac63e83c2d663fe5472abc56cbb606c2e6edaed0bf9912a4225739666938c96a46f49ee82a7c07312b0e7e13bf45156e08d001ea2c3aaf2ae7414e35d324f16525f412b1ef7fa28e98496b41853bd3b0a7af32f4f8dd5ef4b4b3b3a3442924d7bb2bc795018e2cd9d83c2d8de8c2c4fff85c9af237bf20ee27b13d3562f8cec15868e287b1f463fc6c985d9b48e09d4a748477aa215534a476f0d214e55f2631daf2a82abb53eb49fb152cf14957f445f56e98f719d9bb6d2b99776e977a1f597f6354d487e6792eacd75ed3ad4b458028fafa3bbc302c62e9e7a749ee3b5f5b3077db8bcff776bb9c6e803a55613ddd0c4155d2b29c8e5a5f44a723ce8ec61a30bb380ebe08ba4bf8fd97cb1ac60ef852f91882f40e2c50a0467e516627aed8ff489ed256e592c62d7813a58fb1218bda8da97929ee3686f2034b776069684079b6ca797a496ee02ee7d2eedd853d02521957e7409169fe7587ce718fc81240d61fa73de456547c6c92c592c68c149ba0463f79ca54bf0229793828e6312999446152aa4403d5ee42016ad7a3f9b48d79eaa276637198a341b2e7ef101ddc14d2906533a3a84df96bc82a458b482b077794ea7496e6debac78cf50bdc4bbe6e11a81c82305fd501119122fd2289c0bd97c91af8ce5834a2e81aa70527b1f039590f70c977c47f6a374e73a289e146356826e2c368a1eb137b281481905cd09fdb000b55ab132b7b898d6e4b3ef7f83c8b5aba482149082c1b8867fd6bfe82a2e8b7e9fbc2ca9122847c914f2c4e32cdb470c5bc84514672bb8150851608cb94e2b3a5fb03229b37c2501d5192fda8148e9b078f3e437566615c49b19271c1d8bf11c40032c346bed656cd4d691a084e358e6500032729c0105a49ab863308b927d5821be4b1d3fc17d94dcdc37cf6704dfc640b8650488783ddfebffffe070be151dbf456de7addfd95be859e7ab7eafa2bc022cb1172f2af6a09c7530b6a0c6b663164f3ef504e7fb50e44978cdd082570dfad1acfbec4e97982c301121a3791a5dd31e724283d85cdb639895080cf05d9b42ece5b594409f7eea07bd6b786618b216640e54ad16f71e10a94ab6ad0d97407bef05e455ef6b02355d6f0a31334781c41595e56c8d85f12790f2ff8638bc6bad4153d2c9862802e9df418292fae6a85cc93e0c30a0be3c2bd95ced01b954a15e4a7ee8f91bd73d6ceba0349f7679ba01a70ba07cb8ca85d258302fa1a464af60eccdd105f856268a53cb80b884d9073c5ca48c8ba572a5d18102fe0ed625f21e983bfacfdfccb2f14cdd59643e19eb4e8315ddf748638f2588fb4a524ef7e17f1fbad73cfbf4e56c0e125d8c7798581a6b347f019452ffd5c405b076d0ba33fbe3ff66e59e11667dcd8947c0319d89b53a2efdfa6a9e9072634a1e812e001d104bcb12bf67847a9628260b1b6a5662000146a95fa9c588589d7500911fb7c158d2bfb50ab0970a7a6393409a5489d9565dfd24d3719314cb24ce99f7314250c29cec022434b9c938eda26c3e621f2c6c9fad00d2d11eec51cabbac1969a880e9919309842fbc498a0a7b26454c774b68be26664b3015a4398cb861a11bb10fd297c97d2c04e9ce34189ae833ea089023f621f088ea9290cd93ba6bc4f7916b44a62e0df9ea35a7e9213737aacbfb23f6c13fe2a19f9096a14ef662b678e9adb920225303aeae6a1c75a758a74b580f75842819b11e0a9e16bbd242316ccc811332dd5c92f99f3b59d0f6979d2eff7c41e6e48d69edc4c5266a9e2cfe0f4dd33c59fc993425b8ee979820cffdf03f38419c0672f5979c2071907c890942fe66cfd1a2640b6e692d1be769bdb473b7598b5f483e71e2c0ddbe07573023cb46144c4e804c4bf2f9e3232a7afdd9b8b355dcd230d8978529ad8ebc5258389803b37c81ee46a01b251cfc97637db62c4ad69f3588e4f4a89bcbaa48e6d938d0668ae6c2fa7eeb08fc7356cd5eeaa7db6d68203a91fe94d46aa900458d71bf6bae45938173b3abf5a20f21f0caee08d79e2fff2072df330a1bf7d8d7b36966e640eaa16e6856a6a42ab3f13b2161bc13d72cb62cc57d007c678b6c4cf395b4af2cf12ac431a33eafb23c97532e4513dda08ef8689447ef30ac42208ac4821748ab92f67830d5de1632b24704137e332ff5ac6b5bed0ec7476767ae150bb5134686bcbb807879ff58ab360a2aee90d50d335c494cb57d0784c7deba2760c7e891a32c050931198fe15d07788356e54a5416e2df1a0424e186b89f18a1b0300f4996b6ff568dc1490600b48f2cf4576cb2396d6c72123d99d2ca31b5a08188fba59c56079863d232d1c8cc8796b169c210631f30c026b756f285f54c794026906e92d84eac3a924da91d339f9043ce9773b84d3ade9721beac48095b5682d1a7749c2760e30002943e9e19e8c441dcc7c67ba40da95ce710494ec68f438b973528d0fad3b2d3233f2cc141afa4644ee7ac5c91254fa6b4d7b3faf48c95633bca0a29d84d974cb20f949319ab48497396a4d994649c2f2917fd7b45937145ce2047c5c05e1ba6f5cdce0abeddbd22b7b7ea1d0c891b9c54fb60727a2ac90d0c4e7524643c0cf1b588ef5f07c21317d421dfb60ecc203f1aa94052bad18c295a8fa8c7fc5dd0fe437adb0ef453ab9e7930a5388b511a196482f030b481091332b06c9082aae04ed2b6381bfdb0280fc847a53e7ac64a92d369325e99b806401ee07f8a3a124e8ecfbfb679ad34000dc8afaaad76bb4386df03f2ceaf079686c99e0cdbcf5a574ccae95e8daec995aef67da9ca1532fa7d33f2d805c49ff68d35475216de8b45d283722f98053aa4b9a2b300d96be870fb0f4df71f631a864fef7dbf6fa65aac8ea6d9279d2fa08ad7c6f7703e4c04e62eb9bcff2c2b7965225255cc90ceaf46534912a44f0a61f603dbb9692e62577c289a517b9e54c0dca207613641937f625cb1a3e1422533e226c2b4458456e812281dd89c49d4eae1192326c42dc75326c46845acd638550517830cb861fe464fcc3dfde3f23e84c8dd922753414b30d7c267f33cddba53a969433586406c8732570ba59c618675dc4dbfc6f4c351001a4bd8f2bfbbfa650c5f4b4614f3b4176209db6c59f12ca564046f6e8430882a2f13c5cc3279f5fb0442a3669c2c58565424d5eda9f8723396c3a3cda458a1063019896334a50b5aa4b4180bb9876a8db0dfe1b741c1e57d3be4c6e57d2130ee889b20f1bfd8aac282697f2eab65158b8067e298c9135ec919777c158428cdc4d95ed271928f977952516ba0be4e34e3e4669654f2d88787ab421eb8cb085fbfbcbe78717d7478718ce3dbc5e1d9c5be4a1c2e1491b1e16b8714faffae60376257d6cf843d64710328e97f2fe1cd0b436f0f3201f6924d88e98ba09a972fcecf4f7e78fee6fafce2f0f9b1cd1275f40af09673e81f9bd0b1166a9158e866c97bd4fc679c7008c922fe8004a864944d9d503503ab1e8e7f9660bc30082424fa21e423fa9e96ab702aac88d137335ac808364ef49a4d56d21b13aca62456ff93bda287b135b2a367c42916b62b0acd11eac4680514b5f3660efce181ab4aef2e83b4c6b68f63b387f4b113b02188d719140ec91f1fad8816176532a6a72c0d989afe6071335df6d6fc25f8c199bb83b0e0a0b9d6f3173f3a0b05bfd7d4f9e1d5f1e13f9c2990256a0a34308cddfcf206fd34594e67d531a437c2f84d9bc4d5d2855ef536445ff26409cc950261998604feebbfbf3d9e2faa55704ccb63cc6b02c7a7229158ee527e572211cca81d2d328ad715c89f6545cae112a6a26fc2a16276089b78d40f7b2619574bb860cbcda324f29389a99b517eaef8c99e4052c00b31e48136d737f05d89269bf8dd509b5461302c2eabc8487ec740067ef31523fbb27f12fd0f2b19b7100e6095dac0aea91c8eb8103b5889d9913062f98adcd092ca983e681c956879c5160b798585489cc0d815ef4b727c3869c60e227352ca9c8218df0bc41e87a573891dda87b18f28a9ca64fc8ea662e466657a18dc31e33a46d88db800f1e55cc65b9791f8b15f1f245e67d8e16a2bc7341c062ea30722456021ede839bb495612ff7241964595e52481e860627e3eec54336b71a3467d442a67a26d5ab3489edf64f086d99a8160f5bd8d3a4e380d038e99837750a3c10c43a7c531d9d2d2603d38f0f4ba368390f2711cee993788fa5fe2b9aef60c5c619382b0f1785912259c0a891ea6beef87c4227fd9dffbf6ebb8f299be3f14672a74e5154d30e3be5b725e2565d50ea312d8485e178aa287825af06fac8831520b86c7ec04428d324eb51c0fdac191d9905db949e54e5964807609c99700314c204d9f494aebc5fac446a8c4d184a503fb75498eea54959cc5afaee31558195df2bae451a6bddf106b2c8114d16e1dde5d67f45bddab5755c5ce6b92663c19e5143283fcc096459a803eb91e0141fb92b80db6e36f9549ecd1aafa17b7a5d8ff6aa306dcad078dbd2056ac8335632552a6a3c094310655454bcad127c17252da62e5964c980822a2bcafcd2193b27c0c6dc59b6305edaa4876499eafeb83de00c745da767647f31c887fdede5318bc4dba1e4f1d0ff2ffd5ce7bed877e5fcc8d7b6bf9958d7efb35102af4613f32bb1dc4717df883d8ed44b70b76b3d5aca8faabd9d3bf3a1e55b4141c103ad2d473a5c539af3b9e9a7663d341059a94f801b1866c3f955cbe04a96c4226514a080a83022482237f9e2ed8ae3ddd41ab77998d4f9d815aa1201253a4df276162a73aea19d8142097bddfc7e96005af48416f8ee842ddedac9a4408e5c5aa1312968543d0a0f593a0fffa260991a4adceaad876ba12a35d5730918fa12d0c04f2f8ad41620b541d0b41c743a61e5fe80724fae600b28ff463e8f7891f801f1701222ba8962319c2ec7314c8c9a9a0b5eb181338cbc14cb6aca440256e132062596a057e19069d99d1f1bb930934720a0f24e5c397c3920249cac8819e3d70a66c4918c117823e1b76c8b3df29f9de0ac6dbef9373f920105e3c0a1189719ec9c82c52cc376c3175ecd4259bbb838158f39492bf7cf3eddf6c9dbc3d61d6b08fe8029c7176c983074ecfc3b7099fe66648c09aac55e9f8b0519fe7094e230c142e4830120ce0cc9d6ba419349771544bed70eb696e7be4a2cc1029bc6b5dc9e712b01241dccb73e7356664eaf5bca3d0aec4735e95d9b8122dd0aecad52c5f85b9cfc1e47a7cfdf8a1bd1ef7ec05317c0f83b17288c3e410d2edad43f3b498b0724c0f253d1b631638fb7cc9c56bd7371b3b479e90cbfbe7a0b8c3deec880912073b2dc4e2a55d7f495d8296f4a12659ef576e934b8fbccca9b87bdd9409862d1a432385d826bf629d5f51e0cb943a11b3985510593d4a20b1c10c6030164542fc1c3d0024089f961d63418f1c9614dc20aa72056a5dd5a6ac2d76b00a449ecc1739ed4aa5046480364ffb262491666eb17b59418bea496c181db21d1b8947fbf58c0e4e588bc199b5f9e467d2767f6ac81e6faa2ea80d697af10ab5f51ce6c2553f102b4bde4d521626499e15ec0a3881e57a52687f136922a2496ac82f88461d18f73cf5ddf1073a5e56c615c24ba5f7ebe457d45f97108e1fdf56d8ac2dd1b6aa44c66e579abc8b99d432218799b072ae6d50bc6225be3b16cd3a22b5f4b70e95e6986d609a7171a3521ab3843bd27752687da3ea8edddba89e2876a5b7e4a22e9968f787205bd2272a2fc0c589aaf78b543e7c51cf195941b649c9d81c7619087c52f8135289ed5d83f58c4a2f9bcf51a537ca8ad4167c559d3b8ac4d675a3a0372f9406438565062fe6988a43d9a5b7c9deee6e14ddb218b125f4913f65cba272c2fd5b70e5b23849c9d04bb00aa507fe525c28621bae91b674cd354299adbff1df602ff3eaa04e5c89eb49ea02c221323224137c9fae682db4c987fa90a8fe632d425217ca31ea1a2b9181a53c301f345c5e369a607bdd342e9f7aa3b42918e6e1882d2b83efe7ac9a41c19aaa77bdb599872e6ad5dde3e8ee5df9523965bd701bf53b519c73bbeb10385b4c1e57eaf8b24ea4db5b678706001b9d701615c00967b31a7dc20961089dadfacb450aea9a1b9c5838f69407832f8ead3bf3d26c32e1c4e168563c13316bdaf2909a47e852181ad1484dcca66a1f351283d4d999dc097015705e258ac1e900eeb103aa693bb8f1bbb48750a39ee8deba6b72975cde3f39bb387e7576f89c606a6fbf0f32cc00276b5bdad9b39743f16afb2c89d1ad538159c0512a7791d8cbe3b68ce963ceacefa1b9bbc1b6639fdf3f320898b39ccec02ee7beaac39042e89ca1b3de0c30ad0a242a00eb89e0cb8938d497180195f28eed1e41c8ee405adac0ce02afd2bada8cc6c81eb4021ee459e554dc1ba82c4156c5b4643620181876c5b98b068986c3598f7b63cb844cb9adddc6b362eadb25643e6a3b2b10f0a8f008f2a0c85ea04e03dbc62e905b16d59f5abd00a783942e4224bbdbdbf54764bf4f5e2fc60907eb688b2713da22335a522b9d1258aec5e713c30bbb42b8f5b6c5af5a620ba34110e5195591595661680bb82e16695679514af40c06fbeefbf5941e99e74d7647b4bd35424070180d491615f67c1953e9c39c7234eb16ad0a393138c7a8eb8fbe6eb4e1ae0ace9673266eec29bb29c49eb961e53b929482bcc9b36764b49c4a6dc7e3bd479dfaedcdf27483ed8d4face559009976d019c8679e1d7f97eb4c5c59e17392aece094623bb3cab60ff734fa1d495be55f0d6d5e440caaa9ec53e7615b25cca612fbc7532a2d62ccb2969e73b3bb5dbdca9ff36ffd4ad5e52b15c4a89242a75499daeded99e3e8fd88dfa027f12d306ffbcca72d3c5058e2c22b94938bc8210b32bd612563f676cd1930ba21cbd522604177831df8baca90c826c9633a782420c1df4a09951828f8876bd85ca761b56ca61851b2c93efb8dd3cdbea9f0e7ab5f12adaeb742ea423b33a62ffeaea9ccc939592a07895e4546931e174b5f40571af51ced0bc0f7e87b32425052a4ef1c5b7f10a02d405e59cb4fff2edde63c75f7c3da78cca584692f0e6b4d9acb79e311fd420530982cec558da31a1d8a8d4729a941aff0622a67d59c80a48bb45be17c244203bbaa8ad8d241d96c07949da04c0c1d91718eb7d2962a7882d15bebd72106571c70bb56d7676bc1b92c38cd0b7224ec96b16707d82427731b409b21de80c95001d73735130815640a56f42dd5644b3104dcb1018421b09c8ef4db4cb5f4a2fe3c4b6d76f44692cb46d380ad3b38dd413119c51159f57b87e02bc0ad1d1fb1ae740bdb8e12cd4a83c6ae6226cd5456baed25200532f597f8d24e8fc95c8c7a03df46ad6d608b005b6f7092bc521a3cfb1add81d7833c5a5ab56b9bbb384c5a01b542577ddec910be4865cedee3c0b99d4a67952bd9ea9707c37548a2be25a63d185f49da31c4c57d2a95505e3d38648f9ca11f422f3655e658b5cb910c0bb0b196f5147de93af11d04407cade5ded795dd00ff6873dfd4111c65932b7927191613c7bbb15b7df71d5261fc5715524736ae72ccbf8330bfb532b2197f584cf6bf8c1839a2f3d3ba197eb8e2db33b22534e74dd2e99145d52d2c9a7d9afd63d529b14d1276ada0aa983288fa8cec2c14cfa992096a4fd4c518f41f6cb0e7875cf7c0daee8d2f742194fa58400121a061784d4f35d3265d540a6eab6da72327613ff111b86985a97e293a219ac7e31649c411e7f6f687161decbf8291b7d405464e8ba367d5ee0bf7aca8c08e97227a08641ed847629e651d17c97fc811ad3813d9fb579772f037d78e4a4699e493e660b0a73e81f90e5b23829268c0cc935a4808d20b02baf157626857c251aada5c7a24c1f65e91306f607333f9121a1a59b5d42e686b24a9ba5a96b5aa4724c1275a338b5d124b83388b7fcf3c50a42aa9d2f56c7e8c1d0ee40e61e6b033a070c347491cddd8b1c2448d708378ff41bcbe62b911f8923a76037ed30b64b4e8698dd4225b490c71d44fbdf0dc027795255623e450ddb189987bc2917b79290e3d46b327d5000b71a7c9b5de1d3d6c0d59a2f56afc0871c05c230c7d96a01915013c5777d008c226aadb60fa082f5201104976e93fdc6eeb0b3996bb8a490ef1cc9b7f67211cdcf1c5ac3955f902db0cab29845fcb3cce92efb70a6dd1dd7c0fbddf54183fe0fe2c50d15a1977e3528742ae9bd35307f76a33b6760fe74001229170d1c29697bdbed5b62cb56035fd80a0fb0501a538c50b5179845f17be42888b03c57a4f11b13ecc46fce63285ed4e144bef5a992f1bb1ea4b55db1a5d8dd5354c34db222e33392a8cbef93a89c503f6877fe1ceee81e10f79ce8c36e9fedab155f2ee085bf7207022701ee8b09ba67c1e6113737ddb91869369ab9e3353d7377248bba7389b6911c459421f6e47c8923447155d1f61fa4822d61ce12b2a317cb1c363136b7d12a188fecbafbb39ce6765082317be2d7fe1a1e181407a1fe9bc41c25d76eacd089125344b143d6c9781b0fe70e3a1059658d16a4e158b9b326c49f8475ba10d3f6a6a84f40a9a97c89dbf5f4d1e4ec1c9d91c023da96ddfe0cda59d3b89e916622921132bcd0a14d0faaaff972e12474b9bec60868bced61e912096bccd50a4b4da8521501bb2b7317998358c6248a5cc130fcc8704840e9b1db91b1dfe175b9d7ccdfe1a23aa5d519fd509da4ed8e973fd615b13d9c962c0f27435855262975eba942134c49c6d83b0873af5c83c16428a74d2647812b2e868393375e47c4853a8d291e0c949c97c2be705838544ff18f08c42ce1af0bf528137794c3a15de8f79292a84e9b848b6c0540745de9c325800449febde9d393f3f4fba84891d657be5869176f4c905b2545ba93e410a747938e8f451f7fe2ec931708d41c89fb3bde18cc7c77756a2970111704684f4fddd5dedaacd7ce9a6b088fb6ad4c8d298509573bb939d5bb4ce0c0552d5f70f2476f659cd75524e28348e7dde4da46aaadef3d0624b2222186b9bdd47e5149aac496d453eaf4425556108b928a4d78268b0df29008554d311d36af7d7df6f4a7c3b31f8f8f2204d67ce98f7ac97c01792c20cc9adbaefaa788169de922b75e3d7b2a878624e55a384de1eaaf5a50b56403fd570cf2e326897445b7b8e0e58d6bf959f3dc38cb424ca953cc6d40e71e296e42f39b3c2713d31252f32ce1274545cb315d54ace4085543c063c5d833550359bd3c8aa264a5d420001203d888e6423a0aa820beb8f7b0cf4da99ca25b384066f10b44d9731203060b4da4db3f642d5729109b1810f55316762dd6d5357b2dca4cad63ba6dd732e4f2243e4e3220c13836e4c577a1cfcd78b2231c44a7172050ce40d2f3379a24e9e719af68411be81977bd0b5743c21b51e85a3adf9015ae6783b53aff0d966dea1da1b1d04638bdd220e9cf6fe490471e6bd62e666ba9ef9166254ebf664991e634d0f3ab3b0abe2cb2f8965c3e55ed4e3d50ae5a76fbb9a48b2e9964253d99cf699a2515cd571119c987f0d74be18a1fbb5f9a3f5abbbf99bc4cb2c066faf2265ded1839e36a70779bf28afdd7f98bb30d6c7d301a3720c866f8cfc19cb9690bfa19c35b10c32d3e240aaface8659bb40e355f4c36699cbd2cb3795665efe50682a1de69ac6fcf210751cf4275b5e9b06547a3932be1bc765137d03eacd8bc635be1432d01de7b4e747cb297254dc173be1d5cbec5e5c82bea40844ee3bb72480af90a17824e554e2cb1152919abf0b986dccc1c73db402d19925d263ad26e8a59c5693e71638545c22b96744ee72319354cbeb092cf16edc081d2dd82a4cb120b240c38c97589ccf4b5257d41bc37e54e1f8e2c0fc92a9b533b8e9a8ebaa8a22ac27d74025151d24ce6a1b45e7ea8189612b51f9111a387d90f42d115e457671e90287f757b79325fe4e0b42d038749270a1d36728becf508c6d2958368056da981a9618955d2d38d532d711142a6d97b8a5eb40a84a66a3d30e4d87e4f655095b5f69d1e608cb9588ccf6e6d0c4d7099c973f326a84b6e92ac82d57ea85e1e3dec919f75084877885d6bd16498bbfad8a13d33d86ca28626bf0dac2ed6f50c63c6d1321804386f0962041f675ed185d5d4940954a250cc17cd60dbe8806e6ab52724c13ca518a516861a06ba058ab2bda1076218b4c218a198744cc0619b7bf6135f88dde8ecbecd22372a1621fe6d91a7324d149899c74e5c0848c201ee3109b11c204c08678dc5c27731a3e4577138fc6a42cf671c963fa5a3e5d4442217dbaa01078ae61616bea0637125e09a9324a5fd265fe63190d972cb795620058991e52b827751ebecde92a34cb3c98496dcacf9a2a4ef33b694a9c67ae4e286e9e6f049b87e492eb96b9e8dcaa45c1d905f55164e09feabd59a44c1cdb4421e86ac5ac94f19172b351c0e3bc87e7f9591e2935ca383ed98af0c2ee4ed4eda406ceddc4499b7b0dba9eb8a8c1610870bb242e437c98aab4992e4904ca725c53852e6ddbad546f41986790c984d24c33411eff3950e81d873161cb5864b4e27cb1c88e58695eff403c4f7748c2955e66c09a1ed5899664552514e6835b630e9c0bd263ca91ffe3a92e9478ae69fe2d9eca0f07cb3f1a9534ab90a99963306634aaa1e79b12c15fd41c35c860be014eb04c8eb9e0fa9e7013a1681603449a15fcf5733f7ad815e9fa0858cff2058b1bac644b5d112f0252dd2ac98be968f77945b450d3cb3e2ef88be9c07e1ea70056adf5ce0256b69fb4f3a9f04973e9407c80fab1a984f721a7550343eebd750d7d7f36491a56033f94b602469babc072fd0c52247aa585199f4a4432c701d329b9564bc1ae71132caf8ab655164c5f41c53e2372cf245998cb1091d3bb877f6e2cc9d18e381a972abca84fcf30c83995a9993d5f102a9387c4f4bb9092d271d0b61086902e5038c098fef6cf8d048e55f4515021e499aafb4a2384f8e43ab7b07da41202195dbf8c25e2bb390df92aa25bf632c30e2fdd37d95dcdf62f1b7b7a66128ad53193f89e521a9031e0476b6c890c059cb5a09198f21a6837243c59021b9774fd5f23f86d5df51ba38cc33d03a987aba34b4e9b812b9a5bcb09f0d35ddfbb4fc789aac465429cf5c9db0b9fdad6bce66ab752d6afb915f492bdd226ab9e60a9174585a016112c768858b4977a5d0479465eb86fa5a3ff8bfd3604db58d871ba9f2670cd815995f010a2986a26f953cca998a71e5c8d1b6a4f333243913c5189b9bbb576295ea001f9ec4049bbab95fa3a6d4936d9d1d758eea4fc5c90142f4584676b5fb68d43d9afd0dacc2ba97907e040ef5a80edeca42d61d4752c0c07cfae33d970544c842e0776362d7a9b13511e9c0263a04e62b9ac44c8bc4770c85579c9492052d27a4a2bc222dbde4733a6732d45cabb6e9f7b6565f56450915933846bb10f15c0b6836f8118f32ec29ac433b57d394c6faa6e90b66f2b0d055e2e0c466afc859c1dfbf9c477b133877e8b83d356611190eda13a7b056d8237476c7afbd303d411820876cc40e1794be6bda93e6fdc64664503ba68601358ee60e43f1fd081a9d1f50188aed512d2bde8bc9a25d99045b4a5c6ce2eb235a11ded382a47d3a989f8c692335953ae921861ab40092825c1baf946b228d7f59c12b883867ab2b69aa95104f7ca995d4cbd5d1a0bfb521bdad9933be4a3df91c22e212126c0b52e7dbb6a69ba1f81fa00e184afdc2cafc8e9f1edf924080d2b7ae622bbaf057e4a4529128ed38a198f44faa3090702035bc7f28dfbf8b14e7b1b57547ed9774b4b25ca46293655bc37af19713c4b289c959a8338ab94e2a0155ac61cbebedd502ea26e1e74b0eda16b8255b9ffb5b18af646f7ff76f64ab5fab995917e32968d3771d70986d987bc1b86e881e3a1d0eef66215356f3d0d908da380084d0f76c370585d67252084e08d9eb3ac1b9d15520e63027f1dd61abd853ebec13d84331d59babcf08f8669373ae17d4c8f70d56b3126b9a6857e1688c4c34d67a326dd7da66774e93fd798114bd2ebbfdf28f8c0dce8afaf4138d69273eb1f96817c866b927b0c90d2234d636547f9a35d1d6cece66aab7cf97ae90b9ac3b54d65f82bc302771b1dee103daa5e1c0ca5907f1a0c0a0e29e99f73e552ff019ee22b62b77e0af0daf25c59d59bec10c58877a84f0af60b891454b96152b9745dc6a6663b40e93eb88bb85b366a67bb7b76b86ea77fa75d34345fb5fb3bb0cb98b97aa9226ae6b9d6bc8a7faa8ea75886ed9f8c8c26c151b49c18622e2d2ad4d12f193f02eb2615c8fb06e377f4a58541286eb20f6cd2b54b1d69f2552d9230396ba1901624a1e0c50bd7134ee60652c0d94322c08f1d7352dc4789a0cb09ab3a9ea2e48e3f4aafe3eb851ecf01e3962608d2393a5ed2bb27614e1992156bc310e3aa98d14bbd9c4ff3903dae0daf345bcceeab17fbecf9925842874ed4e830f5a5d5ffe0c0fb49ab6fe64ff33a755e97de6789ef94e234d7e670eece5fdae8bddf739bb00fbb54c1a81792869c933d469e3b6313974c1cf052b6a7f16094e8bea1f74258efcb76a7097f7c57ef97199a5d6e975799f2f8c43b2f3c14b8d617faadbb30e507d846807ac3e138203e63d5676bec5af016e6796c5893b6eed8d8e9932aef4f29eb2d1bf7f8499e677cde46a55f549d03680103064d8edc89847bd08085a10ab6c946795f446403743152789e42c919e34733a67e58a24a24cb0318ec6140949e6e2a640b9dfca4945b202e995eb24a42eb1f14a90226465e08467f32c17fbc0e46c70317af8cf7a3f0cdc8e4014d492e62ac11af80c25e377c9946a183681e1a3234f86ce4e9820cf005433eab5059edd85d56f560aa40e32e9c2a3338926e392714ee6e0ac07ae4cb4a8fcfeb8b9618c3589e8fb80ecd6907c7dd0bcf038b3f94a4582add83b0a77059e4d45d7978597d8bbae49f3a0626827d88fb7fa5427f52e517f19c9375dd7d0fa187bf1360f4bc810ab1a4c1c3398ce32fe049e43e9e3d84f7117e94fe3ebe678578e93f14cfa647a3943a4c4d995ae56a8fca42949d4fa94cb62275bbb1871e79ab023ade9324b5be0cd31154c37c995435f0f6d9b23aa99784a92ff3f7bffdedec66df401c35f0552efcba2628ab494435b398aebd84ae3243ebc91d3dcf72be992412e486eb45cb08ba52436f6f3d99f0b330016c7e55292d3a44ff5872ded6271180c0683c1cc6fe6bc9c8a1a45bdbf72c34e6809dfa11f6a6ef29250e54d392af8f8f209e9c93532e3d7b8207095cdd74e89b98d5cdbf06b3ff19595e7bdf173a2e56ace2b862b165263c9f30102ec7b150a6d59ec936559302120b7fe88672b34d128c75801136c6510462cd136c9f537a96c905f2dbceed3f30feb28b188787609176b344e18b90d4b7a8bf18c654b482d25d7c58ad51a340b7c7b150ada5a5e50fdd0bb69a72e28a6304b531bdd95ee8c153d59cb0bfa8ac46e3b3c4786cdbf8039b273a8d919cb1408b39d8dea895f41a917551f374f9d5c1afd9fd15b79c64a2392ec8479c06ad0e50166abf237cab79cb0522c2ba677492e58037c27b79c955ccb6cedd4c4302302cb4b07f2e071a62b717e12f81558a79a900605d12905d2bbb432f6aefb9834325397114decb4734e5635ecdc58d107d248ad8872a2b2d393adeb979f58ae13239e2c305dfa888e2fd7eefcb606dd6591fd5defffb4aea95ceb042182542099928ab0dcb4cbf6181d7f399684e4f16639aeeb1eaa1b0e92cdb7baa50ebdfd9956a53c7c8c23190f9b1c5a698b46a7ad3c3c4a749ca8def1cd825539048514bb89aeab6c752050d0591f5cdc8d12300c7a6dd2c83429e5dd44326b97784b7e9c7b1c999f69ed1e26242d023a761c42bf05e157acbaae72b0f3db8e08ca112087d405e8ad2e3765266a01b14270195df14c9e5e729508852e85bfe9aba34ec1e8a518802bd1acae17e270389ce6f56c39928c3594ead02f02fe1b22ecec70ff2f5ffcb92b4ffad0ae91c17bbd7a0eaaccd804a7544cc140ea0b173188b9eae7a55ce7269b87cacb39f12a57afc697b885d1d24a100e895c848af4823091a99d3b2035d2d4055a97b1be988084ef6bdf7c9dbb14c418ae18ab8398cb121969409e96ab9828b3b0df350297dc0aa80829b132692ac1cd44720864ea38eccc079f7eb156b0af470123113823eb601f1a8fe67c7c892f9b439bb11f4c598def7a1e109e02d0bdcecb8c5f2ba7872696d6f77950fdc0d26137ad0ad521bf638558bab542c18a49d7ea64d924111b3a210d35fdc6b47cc9aa29fbbb053b6da91a689fe38554ad307b803d5bf2edd4f9306ed069ca91237b521edb23c602838b0bc956daf687510d2afdf0965344b18423cae3a371d92b684b1b8d1e3c20b1e7c6120139a3d9b56b95d26f6fd58dad48411f8d8fc1c5115fd6edb780509d335389bb3c75cbf276c62a94331a33bc6f196b8c2d4c197a08ee7903f2925e4a5952317c9c1b6b199893783966845710f5f64e0371b3deaf9a85ac611e028f910fbbef620e6ceef5789fec47c3d983c908b91f0eaca9198fc2464619f0a19f05cbcad0ec714b0320e40faabd388a2f321c92b9a4f15cb205c4ca5ed32a6b8c962c2947dc8a13a4e83a607fbcaaa5f8c2892c0b1f6b79574d8e95c7dde7085f46db975afed95b67b672dd9362dedc2d258253759815fb6c3bec67985065c426dc5a11c63c57aeac5385c5e5be400d10cbd78b05596a6fcf12a5f1590cb250021182af9a898cbb23b8327ecdb2fb10df8283390e917b9a9da9b9c0f98657a0cc4a823a81ba8ff1648ea9dd2a462f4171f1ecd57c42d84d8e5fdb49be54e5523f56d6eba53acc4f759e275a23649cd455551e6fc830060aa8ac0ff52dacc94d9e01c6c5c4a83131149cba5b968fa1a8c1cdbe642b4c486c7fbaebb3847b5b35c8cb8cddbc9ef42ed96a1798616f3f2195a09fa7976c85d9faec46e0a9e9d03aa8cead74367835bda545293b837d3c93b8e212eba4d8d8341f3c883ec7488daf94e13460c7db3768f1e7b0b9a432aec6b18a0fede484aa15483c86b7ef3566a73c8a3617949dd345a2e80b39d12cfc42ea5bb205252fadf7c05805ab93a92555b9a62eb082cbca4ef3731d52ea150447e3f07be23864cfe9e234cfce811ff348faaa395d38694e75f46acd09f033247acb452dd560390f1c2e69e1eaac1c33afe90fd6b697ecd1562fc7eb3ebad88d74a849785eaa1e3c72b322ce58a1bf1f74eb95f5b7fd7bd325ef036b0e5508d2fbf73ae1c4255b0949d45dbb80fdc11ed9ef7bf50563ac411d04df75f2cbb2bc54c3c1bb5cf5e1aefadd03e1b532cf712b0f67c93396ca6526df25d3d78633d007214d33a56576c97beb3467ad988b464a68e1881d3d4ab40dcdeaa338cda4aa2b3f48b515152ea664545ad12cc33e382a8055341627fe1589d3d04f4ed456c751a28e5b0c6c6372a7a69a6439ac2a49759bce1fbc0dd6cf14d789ed3aa7d0ebab1636cc9d777f5450cd6bbec33fef9df33256b09ab5335f2cfed177c51812a8492a45804ea3bfb10bfd73c996ec1b5e39d778d1ae7ef80dd82fb9da5b087f10e7c5b503734f3556ef52a01547ca54109279dd20ed1d22c6d58a9d8189a1dfb04f2d9de69bdce84e7a75ef90de6118ed6113d15bddc162296669a6f08e06b880210c56104aea8a96024f5b7da9bd174cf2226cc4e6dc3051c1b092551dbf318136e09223c011280d19d7be3d06d04b5fedbf0bc3bd9b2cd34a54d09accb95c0de5183c1082db8e4fc8d32b9e67822ccb928d9910b4921c37a6c5785950eb52da3b5ed881bf710c7d25dc54288a972fcac4ecba8cb9b7970c860e33359923b3e7ff3d1c368069e0fc016041c5aaf136c004217dc0bdd2ac66652945f02fc8f4ed18db216911aaca6bb9c8e95134f150a31cc592a913270dbebaac508a6f60a9eab210e22edf9b0bdac4971e4a4e4bdc8a14210a10c01adc8c66cdad968d4556e5d3a902cd9b71ee5ddca668b01eb127f169b8a412c105d1a81d972610368bbea39e7f682b71a277b2cb9acf69adaf8c19ad747a7390180692cd9c120a46af589256c3a1f2284047108d7627d7fdb212f9152b567d0fb2619e4f67b5f6b0b3daa2233070d012fc17fb003c35e84068e5dfd395badd42953a78e944ac435ed47f74d7b461b1c115c282c38e6d156861b11ceb3a26c1755398a2b57f59146bfd4e4ff2f9a26080363357300b7d443a64743cb3bb522de1d24eb9c1e519a6edc9fccbe8678098944f70aec1c7ce5fb2d7543477d3c6010b5de6f02ad4f3e3b03321e0059f003c6a46c06d54b9ee69b5e7b2e4d76d4e8c5eb6576c5712cc3e713808589175972ceb666985ca034e1d0ec9db2a671978a4cafdc30623eb135e3579d7e1af11af67840a72c2ea3e98fdacc3b93e734086f371c1051b84ebc8ea91ddd4a9f5dc07e37af8f0dc31d7c4c3b13616e4add2361ae24fe28236810eddbee6b5eb7f347b96b96d59b3af35576dc161cc1bf42d8e0d3a1fa59b592a6ab1fbe1f549ca56d72773313d249851d53569c95db4de1184dd48c92d17bae06484e80525af6199a36b24864de5352f07c074359b2f7845abbc5891192b16da5f4119b843835f5ee28569f4f833a858b61cb35e8ff6c968971c7d455ed27a3698e7253c891807fae460d736374d484f36f1d5d11a53c1ae26ea7048bedc03b10167082ac4728efe08a8e045f3515b2da2f746c9ae09dcfdfb66aeb3ed989d2217e4bae2e5144875b64d1e468c7973318d3e3fdb262306de0cc92ff332f5e597a96fdaa995329935279757afdf1e9bdc80067606420ad87846cb5cccf134919720a989f604a858b5c4bb258c0c1564c4c0d177594a6e1cd72c2b14ea2b79a190791bd059edfc5773cb311840460dc068b52ccde73b523ba932293ee7743562249f1b548b1e044e548c0a0e0e86204f77f5054a5e930a941628a5c749178b8a53e522fc09f9962fd8642995aac4d068c5c01444268cd6cb4ab6c1e54eab8e0ac8de84eb0e3f2d04c713d7888a7c0c97d09278b6170cbfb40e54c321515770a315795af3b986545638ab9a5e8ec6e26104257416fbacee0a19792cd7380e7090732e06d71bfea240130011dc96427dad25305ea56d60799131d080afe1ae4caec5c1804fe0a4863b2a2067f3eb52eaadb9a4aa159d52e1b7a2e0d7d6de1add2542b0347f2304ede31629e6e34e13d9a6e19ff2a7e05328f7a29cf05ed627b10d29ba7dca9fcc05fc4b6599c1a29d4060ddc9fa10378ca5f990959963db72168607a7ae40c71b330553a8d1eea2c9da164d03ac759bc5a33ffe032d9fdf82d15dbcf0e09af7569c446c9dee164bce9c76f5295741038f0d62059f9077d9bb3ef965296a72c9d882c408bc5c8087b1acdcee5a30c8cde72902aedb7df9184e8c2c20080e18ad9a53bcd95b42d078949fd7ac81afde015b59de003334b1d383f8ca7210416fb1ac7087bfcd92da5a2376ef755db95cfe9b2eb0d69da4e3f24a74ff0fb11f755e17c84afe9a30b3e0f6d502328a5b7fd6812dd80773077241a5ac8698d8cc40ae6100545e1eaacf2dce693ef75780d5860542ed4cced73f1e3ffd3e821453e4258bc4852caabcac9fb3c5db8ab1de94c95f955080271666691fab087c208743a9b5d775ceaabd7c5af2caf10c94472c031c75b68d1eecac7a7c268f216767a51e440b0dcfcecab3b3f2fff812cca0acac5993d3041dae308f843e5f5986ae353383d811308b19680f2d53813e09d752df1c23987c839938383b2bbf5bc2258f0a47530efd503584a928d55fd62098c93d93b1ab9af3024e42f2f1a262e35c3048aa426bb2c8d918ce5c2bbeacc8584552c9511a0228d89ab3f2ad6e7352c93eaf14b934b03e442388e63aeafff962ef2f587e0f3e90350d90d24003db0299b26193273669a37013838a2d0a3a66bde1e927e76767c3e1542ecce1d9f62ec13ca50848810dbf9d3137e30ce6c1c96d2f1c39a843ab9fc093835f782eb90b1e9a1a3f199e211f9e6defb6fb063a8ba0ae1833bc9eb1453df32ea8b04975c5f9d511d97ff4c8b7166111b8443cdb86b85b88b99df38aedfa3798de5664c49c53078c55aea5a75545573dec5633ec1a872dbbaed2fac965f9f2e7e343134931a1a266a26e8e488c8a9c09b9cbafc8e1ae3d40a8c69e0867eb0cde46f6b7f12c2f320b53da2130bc74294c1e4aa9a225bb49176d05286d04d7a0bfeb61665c5ebe3022b88fee922a50ae4faa208c6bc3dccfbaad2e499fc3c6bc5a6305741603a7b6ba2dcfb2c2016f064d8e1c1a84856d9a9023874461e16827c387912e994bd68f9f04c4dbe6ee2b8fc9ed13717c940c19b9789e8b05176d29492e7271a203cf5b4bc9adf852dd1cb71654eeea774a9061b859af9fdba42150b08a38b828f04fa4765dbe1ba6a04dbd1472a847e1e8d5476b100108f93824618b8f4304ac2a325c6ff6bb2029d9e389d0d485fcd78eee10f4499ac9d0f1b90dbef4653ebe247c32b100419a7a862d43b068d06dd29a6511030db6e1eabbcc67da6b624354fd708d256fc95a814603f99eb8412736b69cdf781c5fda7ce6a334b715be5b3a71fd0359f3ad3d4b5d861ae78f0ad2f581359f5ed355dac380ac4786b67fba661fd73f1a30d2a079ec196ede6efb3681e348528e24b7c584557b34a40ed751ba2fca669bbb1d342c496759e8268770feece53bf1a1002d1cc496f51b417924da6bc681113432437b1364aa52e51aff8ad7ec50fe4b28919fc8553154900d7949e4099f7ca69218260de34969d2e4e86f4fd02fcb41256ff37998a941d5703794745d3b3922cfe5fe53f2eb88c4e892d6bfcb5ad1eb23bd2adab0d2431d238a5cdb64b94803544fca7e134616519eba68325dd4a26e6c3b1c1afed3d66770aba996e5803c2b182dc97261e7b6444c1b2a08e88d26e88be96ac0bd3310826b718e8343c926c940d648163b4f4888bf7e2fbcac99f4b8cce22c5ae792451b3e277bcd02d8841123c2ae55beb5d0c5917a205f36417236ec659fca52aaa85d069b4227be8862198ad15638d738a24422bf0ab41c2cda3913824ef1d8ac305e8fcbb13c0c41fe5df0481b032f5af812661940cd2519ad2cfdb1f1af6298438f97acacfb965915a8aa6ca90159edf1c531213a83d5f6ccbe61fa16c7e0b5f12f26f98dda6ff8c498f5d4d72356f06b3016adb1b07680d7d75d86b67a6a1a942524e48ce127800162c046c8a8e23029529dc76bf645c1c06f0f70aaa44ca2237ec5cc041feeed0ec8dbf266cb73d78bc81e7b5fdc3cc387de6b6024dd127744cba88e1fea5fa285a011b45a9287f8d72602c566b616e8a688356d6259d2267a555fe0b28ee37147e493de35ee7e800a2d0fd1638c7386561b6d426d457770b33d22d88d8a5eefc396069b63416b560d08dc30825d135c5de5d173b4ac49452bf4b389b5d07ae8235df30390dba41a6b9d9529ab151dabb5f9b04c7209fc6030cacb5846b0eaf47f502445f6129d83a11bcb6c0042dd68dba711a917c79b4e1c125c1685eb9eaf2b462fdff0bcac231ceb95f02caac1dbb83955b6abd446bfc548cfd5a09d8c9c060cc8f49d97ce02efcd82adbbab4800fb90fedcef452bd3e4d98de778ded68e8e4d0b9ad2b496d57d158572e8d8825814f998c97a9c7bc40f96cb82714e7c49a7f998944bc8e04f0b56d55beacd73d0e90578f5e56583692a753f61ab07e04a6ea12aee696b02664153d561c67f8312bb9c832fbb865ccc0599f2b2a46484c9bfa5aaa14e0305e70bed46d62075bf7cfabf173f1e3f7df6f6c5eb57172fde1efff854fe7642e0a6e8b12ea5fba82d4deefa7745be14f32e6fb96641c7b7e26d45e70b5ee4283cf38953d601f43212b664d71656970e1f5be4e34b9691e542579e4a54f91586816f8069e2299f012d7a769fbf65c54233e3872415b05432102d865cea6c5b724e6851d8efdb6cb6ce7779cd2a1368f2c8f64ef8d9deca1a1afb246f226b903fad04a7c321f9969563806fbde6d525bab2d6d79c80df03220496994a6f7d3d63b6b9623804d4575e5e018a0fa4a227159bd3dced8f3a5d52dc7a4ddbb811f76cb2987bcfc0435e72c7c38736298e8e526ba145ad461dd5b2de68a4577b14514014d878528b0fd34598ce0db443b5bfbdf7ceb6c99b8a8fe80851c9118c8062ce707d6d6f82d43427aa34af36a14e1f9def862a82434a250c1fa18a0f1a481cfd3392e4534da1cdae89baed6fdd20c43ec07284753521890d1647787cf4bf3acdcf6d4b7d0c046bed8af4622510f4cdb2fdb7e563b0b20b989dd9db9105ab7f0c448d6386942d8ea860b6540ea4535a6ea565b8973b493f77daea4d509f37db61e9e0543916791f26a67b5a49b2e540e3d820b77ae24349db9cc3d81573d4b0db26ec515b0006edd30cbd5b5891cff352c1c853b9f6d57a13b5dddeba01b4ed353a8057a3faa6aa321fc4d64ce1532cb5544cc1d3fc5c91ae8dba687abd6712db23576e6747e4e202f1f07be6975f3ff409b6dc27bf7a5d322079a6b28621b0ca5d77d51ebf7a7e71fc8fe3576fc9915dd97199e9aa1ec729705c66bac67b27409304d229d50c254e14f5493f31104bcafb09609b9a0d3d12d36f2762bfcda8ddfd3466a292cc7d4e5ec8bdace47b7cd18485a1b96999175980ae103b6258e7a0b5907e91150a671933da586bbc1cb3768cc954e52dcb7930c98b5a8ad826cd9e9df31e44a5ee5598f73ef01eb32573c64bb9ad00c37c93b32273347280efdb403a9f6dff4d6d7713a8cbc0e156aa094cb413e32379dece10e3ec391bf38ad6bc02dfa570bbb0528fd26aca6ac84bbce8938c8971952feac0448ddea78997addc1a1f665317e4e797859abb9a547a4f154f0978889a4a635a4aea68e43cd08ea71003197033895d6a0e87644447ac2043b02662af2285747b7356cf78860b2146036b60b154e0568de9e6acd126af79af3075206a444f6d77b7a007c92b6d562ee7acc290534c4f9d2a39b610b351f0258b5e5779dd14d31864cd6015aac07c2960d674f13e663fbace0553f0e0725af372c6aabc268743d243bf59f81b747fad36d64cd4d154fa1f36987d5e16ab436f92c991943e475f915f83ef401f28f33aa745fe2f565dec43acb8a1bbf52a71f1129fd86e13d27132dc898816b1fa79983624790483b44ff25809e121766c485e5ef14b66d7aac13175dc23c4cfa6ead6799543967648dda4d48d1cb0a2b3fc216d95970c00f7abdac959cdbd886c4cc81c20e23df93aa08b45b15206445a4d977356d6226adf6af0ea92b539e61c85eaa0d3ecabfbb02aaf017e14337a02e1c7a836abac5b3ad6550febaef25f61fca1847ea33ae37d1c3bd3af63d4f51c3f657507de54e38ac3c6c21404150bb7e236694db3ecdb3ccb582947aea619c7ec381a6315eb2e06dad902b8d1dfc46d3a4bc2bff2047d9f0003bee5fa68eca991dedb54f253a4ddd74d0fd636ac7698981ae7a4117320e5934c86f740e116ea95796bf61232245f4bf16d24f70017736a931e0e092d043f54423ff65142e8a7a4f66fc8e291d9318c989e1bf2fe7d62675a2b472d9fd053bb91107c2ab1b842cdd859082177486541962399667d7bb23b4e576caadae760cd24fa82221676d7696eaebc6385d3ca7a266895711f7ca1a2622842bf5925b26835dd87cdea00fefd14fefdccdd7c54d14929bbf3c1091231bb9c0df6b72f557b953142d6af8eaabae9e8f1dcddefe5577871f8fe3d39dbfe7259c2a946f5e4abb36de8e6be1302a87a79b62d8bca129dfb7be0f6f7e076fd452a3a5dfa9bd7a75ddda7db9210f15fe21d8a9efb022a996365b4239fa5f604495fb97b20ecb1da3f2ca5cf2eeb6e933683a5e7b861409457ca5f2995422176f99c1aff81d6cbe45614d7cb60a9c09f8e6c398a6ec3c115dc8b32e402d7968cb5bec2409df4ac9227f8f490ace57fc79c3729a3d536fceb547cf078ad6969ad135e83fca99a9d9461a30f1e9049198080beb328f68e204c8c8094dc8aa22637979e28ff006fe5a3b108bbe592f2fd7bb2d5bc0d0e86ca7ce0252602ec1a703d076e127d32e5b5f621b3da0aa272fd5d472574d47c61be447754dc143ca75457ffcb45b381380e337a37c6f1a38f688cf2f066908b977c74f35409ff23ebb2d36daeabcae7dc9278ea70f40367c5fb7529df15f87077d78afa6b6eff9fc1f760ae840560eedcae72760d379e978c2d54e2c4fc8af589e04d92632804b7ffd774a57223a858d90cf2ab954c654075234e15d20e5ac21b60455d5dc96b32595690a679a9801504979a88066bd588aa7f5bd08acef1c3b7f695a17ca2cbe0940aedf95499a5d027d7b37c3cf37342889a2f9afe00601286309b91617727cbda64abf4305b15a8514fd6d0277c510b1f1778510bcf87061f91e3976fdefedfc5ebafbf3b7ef6f6b1abd1df932c8161f93c2d45c753ec754c6850a1cec05a6a0442c3b46296966c67b7c137b65bc838c369a6e3315bd4c6c82472b9efd95e14cb127ccf6d73ac2310200000053f12f5c103a02406e84a3125bb61c97ad5853090d4aeb15a9627ab724c8ec8165426ccd5e38307ea51c60aba723fb21d95f49ca99ac2edbee4d59c169a53dcfdd6689325bbf6c36c5b75d726dd74cf64505c96c115c007e4c981f21b527f458274bba807105aa1e903263a144ae6c2f59b8acf5f63fa3e98a200d82063520f007480901a783b6d22c5a081303ae00e3453a9b4ac165238bc5e2f9261651635da6f585235b783e84287f5806d27d2d40736813a7087e192f589ba6ecb451622acdd8fc0b72e67d7a6ab516d400d2a129daa9d307511cb07b4e75da34a89b4895bd83afe0eb3cb3832c41ee193967787a41134fe443c4974d7ce1fd7b7bef7e3e4b1fe6a59c6fcbdf4e26137e0430f3b259b4cd8b8fedded654d17a33bda37ce9ea5723eabeb608312d86c73e94d4d3567867ab6cdc1548bcdbc9de555d634c327d19c9cb424faa3f68dccec5fb863a5b10fec6f7182b42aea5a4ced654a9e90eb8a2e6c87d19ebb8cb1a65d72a87fbbfbd6282cd79dcebb031cbde404aaa8bac091b02d8058be8793ae4ba47f2e310517f413b2ec55eca4ae96e37a59d1c25d99ea753510d1026a79aa2adfbf6fcaab845a2ed936dc99e41a6906fffe3d892b12b614d432b425da4a83bb6db5c7db7788b4178d13699ba261d87ce3bda2e31611e301a953fcff0e09a4f6c84b7bd15750c7139fd055db2e1a09e16a7c7ce291eb95da655b377f58f0eca6d640178d28eb453664ab399b2bb690fd7acaa863ea0b2bb852cd982229df8b90fbb44a3dc92bf6a2b1490594b24590ee51c4bd7dcba9d90c4c1bc66e59aba934b445583224957ab84d8348a90e8d45c597a72ef8cd880af64dd9e61de2036ec460092c57c66fca7537a1c45ff92d11ed76679bcb8a3e61adf1e7ae734e80310e4775dbee1d0e1f202de4e9ef5bce2f7b67db7e1d726b0dab89903f9249e20ecd37b574ee805bd58cf3cbd8879ec9b2e673c7aaf869ccaa3865f5d39acfedf1c87dd979ec6e98e3d1fa5ae1b967ab741c36bf672b72044940c01467dcbb2cbb2818b46b3e3fb53f3af7d82b2c00e9cfc6a34e07cbf06bb5879eb0ba773a1e9d27b4285ee553a901c9cfe518ce9d4e6b4d4e16daea700fb1b96719601d9438c3602a53f6a5deb2dc6d786bb30823390edb012fa44d20109d4f22ebde79af9383d95393ac6c7dca1aac6d5d2f0329d52a639a04d31cd5456f45b9d94751c7033f7bf745df60b4fea8b40fcbf35d7f922ad27cfcccbacc8c7c68bfee937854b7f559bc403feafaaebf09de35c57f8c6187f9df85856c4cce16e2a40b3df68e85503c9252397109164b121df76df0e6bacdafd15af33e87c0fa1d715e305ae29546b484a8ab1c0e6d3eef666c51b131ad59d63bdb7e6efe50aad6845764c7ad7007e19b76400bd921475f919db3b3b36d887693bfecf4c98ea44bf3cac80bf556feaffa239fc872f00b5ae0e135dc1f329af98759582394e863baf34e5ce7a81f38dd8dc50f51c160ea0ea36fac0e6f0725e40f74206938039cd150f5953503c9528d22015b5a4c1bd45a9a6c663ed5aebaf76869b8a96383d6d5f9315aabba5853084e2daca6afd53c9686abb53ed1e923c80ed04eb296622122ebd2b3b8e3335132d63e90be8c3e4e958d259296d45252011622f5161f798293480e13c96820ec2025d9db0484ddb396ad616b2bf532de971659dcb537ade27c6b2bfd3adea316e1deb547adfbc3d656879d21cd0b90eccb4f29dea1c6280738dbf3a6b3efededcdccdb2f124e77f19d7edd069552105267622ff4e4e7a73fbe7af1eaef87e4391b2da726810a2f8bd50032cd63b4f1abd76f0158fe8a5578ad8939edf102f65dbc0fef482e08c380b8812f0dd623d700f9e2afda978dd16a3c6a45830bc38f5a2349d0d384e95395f182b337bcee1aff59d4609c8b3705cd4b74e8ed594df489d415f49f8e19fa92ad9440875cdceec10eaff19bc35dc235e189f24c30680fe4109f38955d149c2ff0aac99c3a16155f444e1edaa9c0eaf391453270590c0f1f5b80a03cc80522298795c46068a24d9d864fcfd35bd2eda6cd9dbab0c1010086d99905f42bebea45cd4be353e9cfcd63f2c19e7d76d8ecc2d4faacb16b54844aea11a756fd1a71bb718f973d0e9d6688c98ea8fd52c991f6309fb2faf575f9c68c549770dc4c22507becfab95d5b84542a4b59432b3a1e3fb75ca863a4cba22ed87de27cbafb987c705ce703a6737a17c8cc2ebef56e0d9e0739b1c35481e47919171ef2472db19e4b48df91a9599aae8c6237352bb36647f7dd7f7204f5d66df7497826be8f5bb6c077f22be5cd19bcf8f2887c26997bc7eff94ec3e5077b9fb5789df9776d5ae005b76dc9264473c5b689c3ca566ea94e2fa976b5da4db465720c34e170bc94125be0e96e4e1783394028440e6266fed57c912342053a61356d58d76130a78ee8568783e78d98219050c27d0ab76a408964658d8fba0e58d003870b946ff21b26c89ff6fffcd923fd05b5e8a43636cd96fab0af63e3dcde0c5839930d5458f59c5e32224043c1c972b29d6aaf30e5a6a8ba098c2f3cde562bc159eafe8461477fceebd91bf3c1dad5e40f2030d66105115bf04673117314407b903fc9efdf3706958cb145e356459e908a4d9a928744bef77aeee504ff2824f2ac7117fb7d7241fb845d1cf4c9c5e85e9d629d156b33825cb2c7303ac0f833d200e25555e6643bb16e0fdfef6aaf43b15c2c7855b36c40de00f81e66e6ac966330e9b29b45918ff3daec7b73ba908b5e36f6aee6df9dbc93c32b99fcfe8431920bb164e44f9f7ff628e6639bdc3a340d2fd94ae0f2b674c9efd94ad89f06d68324a8b5d9bb64bda0fc5d5c60e6eb9e7cb2db572fe015fe3a28d94ddddb7d4cb6f4ab41c64bf63859b2c5c949b56cbeb8d81f5c05f790f60fe891b26b2a885e4f72ab9f93b28fbcad5680eeca25cf1600c764eb50bc22cb522cd8389fe42c6bc2fe509d4227e77cb2fa9ead64fbbb71dd4affac8774d6b76f72d000970684fb55631dc273f221e2a233c94bc8a41887656c432f97c43393f4e0813781f249ef8236b387f26777975c50bc03c4e71d07ec74150db472a00aa5f4621fe18622e34b58fff52f513cc160d8ed4bc5621c673051eab94be420b5440e1ac63ff096c881bb442225134bc45b1e07adcb6363b5de96e292a3a3b5de5e34fbb56cb9c7df0d17afa774b11d957e187c850559c89a95641752d1136ccccb2ca9e9f99dcb85ceaf14c64076e9de1b2a104296ec68c3d08eec86ada98034c1b33c6c2da4e0e59455cd064346ab601f1e909f84145408ac20cf7f8dc84a18f5f54f74492297347a62b36bc8f5af046bf33035f427f671ff92adce53050f3dbc89365a3e3137694683682b7e18e81b77e5602b00aca151eb85b0fda3580161edd114ef6e2fad3b898a7b5169d3021dd39f4304fc760edee189f992addc5865301c26a914d4391c36d0107d05d068300ce96251e42cebebcc7aefbc50e777b16692c46b3f89c340fcee75858125f66e7ba077db0377b73d88ecb6c99d36b9cb9a1df6c0de610f9c1d76d408ff66871d593bec4107ec147f673d6876d683e8ce1a6ea4d1d1c5b0d7434b4498ad50994db5980b4f3125cfd85bee7de5b9b298afa3103bb10ae443ef9061f21338e342286a591c8ea3a1110761f23366a5ca7af080b84f6c0446bb7205beef84331d916599ff73c9bc4a770773bae8c5c612f15217da6134384eea24a99bd0def96673ca3b9fdf2fdd67da88c02a8155c7c8dbe4ab3fc25c7c8349c5e73d8b1afa638bc676afdb29ac82b6a7ac642044ad6c628612df14fcfa99946d4501901f882e6c1102626d6cb0fd6f7e78fdf3c5b3a7af9e1dfff0c3f17375e30be48dd66599e88dfe86bed13defbd87af988b78dffc9c073a565241e69bec92d1af23bc3029f875cfd0c8c7baf00d8072ebdc77e612f6c8adade87e0c8e52b223c674b7dff8cf03d0aa0b384545b3e5f93723ca6bdef43416d82bc76287f50e87e4c57c5130d91e22ba8ca8b2e4cdea7a210e87c3695ecf96a3c198cf87f52fc3311f8e0a3e1acea9a85935040ce7c12fc2a375ab0fd7b8be89a185833760350553a0266a5040a7bc7bf8d062daa0d49479aeff08c8ba273fcf33a5706055ea85d459cfb6fb0df17430f7b8be017f43115e02544cf26a24f38442ef7d53f1790e18f8710c05653e57654a764dd417d6a541c5042fae20f7011a68a2061251b3452413204e0876129045e5af4109cb7ff49b6531c98b8265b2ddc4d1a6e3e05c4285ad927507f70a2ef93699c3156079287d5312e4e1439850386feea2b231652528551b9c1e3a24c132b2154e795d335e1148587c53f72a5677517f6ca4f75fe026418abaff9c690265ce9e2739ba3ff03c996fd27ab3a45e73feaa583da8672c0ce16a4748a325a162558e15e074fa00a9ebefc99e199192b41124529f2569a406046a7ff2ccd3a82152ae41f908a893fe09b858fd36e8f8bd862b76aa411a58d2ae6f2da90e136ccb490b5c414e85493a59cf98be83774e246ef54afa0fc6a0856cb88ef02300a0690d856e3bb7b984494e1a36a57727efa328e1e1e20ccf5aa3828f2fc1f75bcd468f5728047689a89793493cb7a2d2af51a151a7c65e22c19ad52aa3526fb2939ae92d16510133de2779bd23d4980a966da55a873eb2ac8df9441bf3b9dfab95c7e17a9dfb4e05714abb35e84bc3d54863564ab5d08cc34aabedd104173ae14b8c0990f3a2a9125f34a832f4209b7e5cfdefb04cd6c863d38a1a17a2df8f1b2f20d80e2099bccd48ede68f28349c1aaae7c5e0eaf81e872b82bbaabe92d2fea26d3395b9657bbb110f071334037e7ff6e1f475133a152673695ca19c636570858fb02eefdf13fb0d3a23c5df414c9c7ae7c76369d72b7992cee679998b1a331cf811386e348bdf317d671e6bc3257443030f7727119db869944a8c31cfb65f3853020b0d0cef0eea2f25eade6c6c2c097db83b5577ace64ebf54878ac2b759af23a7c7059b6054dd910c67dbc7da57c5ba24864b5e352ae39365f99754741575f1802985b10e3286fe0f9e23e8dd4740ceb69f5a6b0952c5b10a32f969db2d83241eb998b951477ecf8c63a1cb7e110743b7c0a15ea49de399c296431d3d9a9b418fb2b3b0b016d52c319ed81c98861adb746b838f6dbe6cabcf2c3074e94a327b22bc30fa79386ad56a4a580d1a3ace3a341aa3012efa4d5bb64c8fe93ed8137e61ddd4a9c0df88e1534eb20a6e3e3a023c5440fd314fd62c373b30c4722b5aadf5d98e4876056e6b7c73d2d23a96dd760b3e5779e550c11283193557d8abf07632599f1562aacdbf3e05632a434370dc0e651569e745bfb4a513fa686bee3caeb3257ee55912ef4bba37fd306647d8e01adb235ec1da532bf95fa132ca2fe084a33787bcc86b70cfa586ac91c0ce808ddb4904686fd664bd72c1aa3d452182cdf7db900ebc96cd6281935bfb557c8a1ad628e332c072f5fafd4981dbd334d059d5d288eaacca3ba155fd939364d10a3516173030747483cb6ad06130c1d99c2e042e82395d48e963541ebd38952742100cd22a13d338bb6b855edad93f3a7b36caf1375c21c860deb63e118c913ffdf9d1bec7932db2fcfd7bbbc52d47467b2f73d1c859ffc326bf56ea7d4c94c60585bf1e6e793373376960c5a2fdb6a23418fd1a1afd1ec42939dbbeb3d08c4bc194d8bc642b21258037d2089fcb42f16cb37cf48b5e975386ce7489538e2fc9d2755a97b97cf4cb00ba194321f66b3d616d3dbd6dad285b5b2900f7cbcd51e6a24fe0eacf0a5e81bf1f07d98b6ecf2d7647ceb67770343be1719c97f62955f9c3f5953097b2ae6e447a3c9591726dbc239f185ef36805fe4ebfdadc74c956e7714a6dc6459d5b948c0b4fbbb5ba119729e2dd179f09c824f9b1984877f6a3b0112beb2affadf8e814fcc33437fd86ec641a364cd5b1f18db84ad3f2e3882f18822fc04ee10138de2546742f2c6846b6290faee13e81e4558e839d3422939460abc33c2593da1b8841a19dbc377330bfd82779696a885e62d863bbd8ef9bc2a7f0f7798b6e9cf4674c64d68f28d6eb1930bda4c1fe90cdc991a54504c46337b9a8f372eae01ad06cae8f014678fbc78cf0c3c8f9425604199c7a1663a4c71cda94752534cb3c75b2a9b00f25946ff2b189728bb6d27e39901051b035201d8231b4579860675921cd3297b0ed3525e58ca53c5fb2959202984a3e725581d10d0b5a09f6a25423da7f948aca94a5bf52390d6c376b10561adc44168ac6e62417adf2da95554b4a4432d96a226959a11ad97fec5111f61f7244c2288d94636d9ccdeecb42b323d9e4eec295346ec02e28f09c5f31238c6eb5cf5b070a55dd064cd8b23e1476d90695b5ac8dcd2bfb032e0f902a98bb1cdbf96d3955cdfe4763d6191577e354701ef07443a0eceb096a8592f4f1fd2ebcfc905fc78ced72e7903dbdfb22b0f4bd0d2b6cd74d6f51e13a9d54f3ad8e40fad292b5bf290fca717d34069c5a7a9bc7805b0e73c68c4be16de8ad4c379736dce25dd92a50c5eec6056bfaf771667c7adffba383808bc107eea5eeb3519f8c47afab6ff28af5890f9f1c3542eae29d2eaa55a3ae761a5e58b77763dded75d048baf2d8f12cf9b9c6056d23ccbaab6c4df5745d5d7a94bee2be7b1fed4befcebd55f129ea58f1da408598363356b371fd6c352e98f05229b29b05afea9774219e0a94137e898a8d979560c757ac427f4195acf1cc6469b3dcc3c633d6030718fbcc13079b69f0299ace395c3ba78be459c6be0d8acc59cdbf3bf996150b56f5045f56e3a6137d7271a15c5d4e182b7d69dba09e7a830e8effaae2a848c6578f23eb15df281964d23bacaf623824cff38a8deb6265a7729555ab2a73014fec36d51b7dc319cd5268e7838d3452cf18794eeb067aa516ac98c8dac7bcaca9dc76747eab462846fa60c513c9ea3a122d74b86b217a30e7b00bed2667de1e76033173cd0880f1c3900026406524539395e85db463a00caa17a6355ca90dcbdbb0becee3230ff9143140ac120f1ed8ec04ecf0e0813b4850c774d7a2fba45b5c52cceff01a7ba22a4edebf272e885bbc59e5af8c899f405c383de813bd5e4fcf1bc11198826afe34cbc8912aec592db54d2fc218ae400a3822f48c1517fbcdc91e5af5954f629be9720267acc22f4c72f225291e93fce1c3c89dbcb8d83fcdcff537a7f9794cfd8762ddacc7d69434400f6f7478e0eb89292079ec84d556e860782235b0d8e14661792ec503ae649f0fd64db48668df4dccb7fc51f33ce1d5311dcf2273ed7fa0097b00c6abce1c10f1d70e1f591372b0a9815053e5d35bb3ff9dc8f1e960b114b38f478f4fd798326327898db8f5255d7c546efdac0bb7ca5edf9e5bfd539e3f479f354acf479ba7cf6ecbb79fafa3cfaf1f3e1a613ed726d4ee027d33aa7cbe867b8743f20d2d8a11a8071cb40291d74b0c0886209a4617a325f10fe0e01ae5c0d1d83a0106f16c4edb0886915a30113a8704ae988890156b8017eb89fb21163d9f50ca7d75dceacd70482465af6995616eac3a47379f881a6de0105d4c7e676f6d20137ff50e40fa8d0b35a075ff4425eee9ca7c19d7dd225584da9d31dcf82cf984a48f215a2df4bf39eca845029caf3d8f8f373a93399faa706c10873e0b743f8145dc91a406ce7a7e0a1c0c7a3f6db423a3765d80def558feff6580352a1f3f7ce8a79aa9a6e2f402942e535efe1d2a58982ba466d5d715a3976f785ed64186003b05b6ac58fea3d5c63db27fdecaa761e5f0f9822f7afea9a1caaf50d81837ed6f2a3e7f5a4d45cf8dbd077e6ecac755ffbb9bc8709e202bc19398a92c2f459e41909a3c52b1cc8038294f5b1088dad371409e71285f918582cc5227cbf02b93a14d432c16e9989a860c835cbcade8582f23f93b7bc9333678f5fad5b147230d995ef069ef6cfb74ce473790a58d9dabcb12ab5a1387ba030385acd308811eed54bc43011f3cb13af8f58fc74fbf2787d6931f5eff3d2262a35cd10c4ce7edb0f8d31f36158c3c0a524968a39505e00e539a97d3e766348f838af69315a92003582d8f3cc704f8f4a0e3a7883a71baef6777f212973f5f5688c15657b41454a3d740ca5895395a65eb5e96755e00dbb132d3877feb2b9d4bfcadfb1821f3470cb2c38a55399e55bce44b51ac48c94b56cf582197197eacaa50e9c8550556fa6cd025b0430252993799ca8524befe5ea72aa7a5468f832fafa950d442e03839821d6c6587409bac66553413b935a29ece6154cfe4917eea1ba0f1a997c9d53cb5ae25360568d4f75d48ee26759dec43b89aee8055753d63656f51b12c1fd39a0127edebac69eb3d82f60165577e636113c09f2e0675d458259b6ec2689d1e84debce97eca2efcfa2166b50e3e4a64e4056b0aa600c698b2d8a606e91c5529353a732fed05ebd955912327c1f0daacda3ae3bebef5b7b26cc64f05999b66d17f0d5b37c019a1a28241d967db3f7f7bfceae2ed8b97c7af7f7a9b4248d4998a750ad264d0bf5d48612a452bf4af4bec1f85cf668095ec776ee476df998bc8726892010789817f9eb1cd920223bc944aa5d9542677ba3d2c7ab6dd8f66fdd513239519ccd16e83f544e36214a346014fab81aa3032d1c0a636d745676a5c305a694e748b07353a194453ce596a21f96b550f3cb222134b3e92217b834801c830ad13aec658d58df80143b63ad2eca8e23b7067b9a362f0772c28ad319f8fe07ce221686198fee3f0f47a1b70268f5d02b965bebeb8905ae1b4ec995f7ed5b3d027bf12359a430de3f061d7d72a147848ab1c6a91280a0e47890f0bb8cd6391f8b95834e8251ef98233b307a7f8349b6ba4fde016119fdb0e937e648bbeacfc9e415458a40a14f157b4b0526895534c7017bcd4623ffa52ace6235ed84876c3219107e679fe2fd0100fc93523192f776a403d07c504427bd5956683d25b660ae36246afe401421e010a56b36245c64b51f339a1ceed299c059faf4a3acfc7caded7571d907589cb7c41580e78eea6d19216ca4356c5ece3bb91543f6d20f8bc164d104e03992a001105328842e13715bf59bdade8c2b97a9d517168b19c462d2dddb022bdf251701f1d1198514964f3e46cdb60cb733501e69d2cfc3ccf7e5c963fd07fad5e984c0d9538812949c5010699f57cbf2493e2c12e341c92973f1f1feacc16eff2f21d91d40130db51a3ab3e212f26a4e4759f8c58c1afc998678c2c683d33baf204d0f1c890cc79c5c89ccd79b592e2371fe7acacbd36dfbe7efefa1023f3c88255135ecde542028d586c7985416b735d834df814f0f7eeae4d047f1edc75039395a2a176cb2a4d68955700dacd4b1f86e443dfb2e0fd8e5904258cac27f4c85ecb2ab83ad2eeda21d1dccc73f6bdb13cf5a52df70830da7c8997bf516d41976e09d5b5d96e960b32d1d94dfefa85e4e6315d0a86596bf15409e97de0ec35a3527a25ea32cda9d3da3588c28ad5553e9db28a50ed6c52911e1c4e450e1193a861f513b54aa1a5b42c446f92958ae5480aaa11e02f4f9690e0ed92ad54fe74417a8231420bc1017f4dca5779c089ea4e690e273140a31041355ad4bf7587b3a1f2a051b9189a6e0befcb92d7faac8b79eb48c6e1ec49001e496e06dcda776eb3bcd7aeebe8ca6856b548afea30ec845840f85d054f88e220581d6d27da7b272b66bfb14dc95d56f76103b174b79e7712267246942b707a52e2c3e2d7e5f76c15d9899371286bfa2179520aa441c516bcaa4d22fb68a77e6493828deb81ea455069d3cf45c5ae5859434e1a21b5f4b53d568abd527d229e89963e3fa9f8bf58e92bace9b078dfbb0b8e8346c9f2bc4ba5dae4d9151652236a8e05372b28d40ff4a5a63ff2bd3efdebafe17f5f5b6e1ebafaf28c0a037bc32bd1cb6d0c9c50f9755e372833bcf27270ca2356baac05fe1dd1c12b369542adb2fae5762b855be674e7a8adafefdf935ecbeb23726a99479d9e833b40004ca45d394b27335f64ade4d98ddd3359a3f67b0f2a35c237bb01e2ee85316c4e452ae020cf6edc80836804bffe103304fbf4c54d2fe04e76f513182ad5edc489dc81da0c93c321b12611ae3be63ccb2768610507e03e19f3c58ae4b5dcbf28d845c7bc1c2fab8a95359696e75ab0ab02bac4fe5f3f0f2203bcc9bbb8108b8ad1acd736c7efdfcb49de5deb9614e15bc73b29d4839078dea7a7f9794f5135d4b19ac45beadbf7ef552d037966ecdbd8719af74d6a53034c8ff79d7045a4aa3116d5a85aa71a8baa3061e2ec18320856d0d1c46cd8e6b8cc7ac04badb6e619153f283f5ea13c7ae322a97937c0fe98cf4291942edb4d24e9e2568752c2a830bd386aeba294442daf5d4964eabc1f31d454771719d4d4b289002a799d4f56b119beadf4e94e74f7d6d77c133103869477c8e6630ac4e447e171588bf0304563c2c22caed43a326eed2f9ffeefc5c99b1f5e3c3bbe3879f1ff3f264764ffd1a3478f000df58431c206d3410c855f6a11bf08f86f0899f5c4f02f9fff55db6c405a07d69abb1cc5d79ca02341cd4e1d67db48d03468a753913cdf829fed0ff055246c5599e7ac061277365613409546fb948d20d0b84389b4208db76b2c8ae843ff8abe52e783dbf7c3c43d6245ed3df26b9b5161a53ddbb02f1153486c2ff918a7c318af84dd76d944b86cb22eac7d63c6f1692b621cb33e9c3ec138caa08c20676d7c63933b1a64ddc1c7713824e572ceaa7cac6c841b8fd5e5caf5a36e3fb4defa30680124a8a8b47b3e03fa31002a951d8468883ed1e97bf5e4f36bd7c2e6f072e33ba06e2dedfe43f5e19da5ebe003d57b75a9676a44ae37171ef0e5a1d46bc80bc8c2ce3783c16118f2d02cfb36cf325602823b003d34d6cd3eee0980f7e0eee9e1a1d8feaad996ec86e689c330a83236edf19c6a3d887bf96805841c115a14fc1a3c7af0e824500f09b3c1c95ea046f4735ecf70de1ff5a55ae034e87de4d7ae37f9346a8c7db2577b75eb34912332fce413f2b7714185209f0c495c55340f6f33e79e8fc32c1703cd60f0ffe3e0b5ba5772dc15cd4b3d99f15c2350a4a0a2febee4d7e50f3af8e451584821b64a4e0297a8e6aa7fdd0ada0d2bd363766e484b76fd8f3ee145f60f2b9e4697b4dee24a07cf80d3c1e05c8a17fb2254ffd24afbc6af5f633dff03e138497b7c837646ea829a6d0b5dfb93d8be18841812e776f7366311e160fcfc416b462317f895bdb2838c737ed70544473955a6c729ee30d00655dc1e64789a24f61d41681a933d8d60656fde1f7595e2f4a64b80ae9e05af84b7c1046f83ad26514f4479d1bdea45efa0d0ea7168898ee845901cf3a1d49940469f6d470b29b88f47d19734cb587668cb2f7d224c177fc69765ed7e837c19fd04adf7d921393d6f7baf2a7de417f9b05e950a2c1bc84e9ac277e127f7c0d5e648628473a7db81907677e8a44877b264d73fc494015bf5d6453cf019b84936efbe8c481cf460b39decd0651af49973f27a59133e2195d40154929ea63bc14d9032979a31b450480fa0e99d5ca64e0509e9f8383810b8f57ce5d512bf792ed9f58b9acdb5f313aa454d257b5e2581e1d235b1a03125f9793c7e9440de2dec0686915aaeb7c32179c53568605e14845db16a753d63151b84098580d0be92e77401143edd5acb728c793b466b3783ed7bd3be17e390cd17047a51a7d6042f32dd7ac68a9ac6220a7511581331e5aceb6238272f2dfb3f613772c703af28c725091d389615037863076c0473895c53a16c8a21aa7654797c7884a3bb8b5c71a7cd21a2c283c4ab6390dd168b84078f0bb8a78f64b604d79e1713382ed894124f2bf6541e2458d633a235941ac506e202badc02f44ef45e1928de0d7e0dbcfe8a2420e1f4d7910e7855c4c4a9fefa25ad678339bd91272d35be870a90331853dc493da8da9a26d33dc8ec99b19b78379d2f1c65f4fd7be2bf0c8026c2364382b697b78980bfe765cfe1367714bb216d1a31dd3ae596343f7ef9e6edff5d3cfdf1c7a7ff17d4e65f324b868b19a5602f0b6ecfd415252a26bf95c6876b74bdce6593b54547d4845aa3a1910e57734a0b4ad19b04eca06e12ed7e075f5813a98a43c7d3fb95bb8fc3aff6327a449e34459ae1fbc013d621f9c23954f7aefac4ce81f82164d18e4edf0936c3be3e97523e32843d9b8401b1a0a7c13ed9537abc5d35a6a003392d64a7cd9e6536a67247df72bb61ad1f7c698d0ee3964a001d7e51d61c4fcaedbb4a403d9b45b660c2506575c8002f22bb752e06787f07c33f51d77ed8beae23920e376248507d778ade76b3f50872a72d972625a2a6cd97fe3d5bfa42a47741dd5d7657f558c56a5dd07ee3b3701a76f5dceaeb1a1532e9eee96df3c29e32dc3c1fda4d8662c9b5d2597fc56494aaff9106c38e9619f3724ceb5ec330890e7a3d6b43248813677386b2b8fbd92c2fb29f60b1c738aa64d7ff50900a05e61689b0135677b2906ae096650d7df080e4e264b13ac6e0d708fe357e498e5c7708d83fc353a0de39d5477241eb867d923db9978d1465e06d37524dbac38688d13e29ba1e9adf824dd47f70e8c27411ed980caef602428b56e8fd9a0bc24b52e5d3193ad61088bf069fd89efcb3e435a1237ec576fbb22c7c734dd17f69392da4d8aed03b3fabf882e4759f8c9635c96b7455f67a806ed0b45c916a59d6f99c117ec5aa19a3800996b12b56f0c55c393e3108a6e0cb9a98dd4db05a6e8b05138288c50a22be85099df6059661ba070f48d7cdd2a7a458ac7e04930cde72c4438a94b2d257575287963d07acdc7e64916fee4105cf67ff660ca1dae9398fa06a1873afba7f421c977647ef245a70e38c491550befa5ad5fcff9044b917d5fc50ffd2a6912389d72bf8eaaf362bad6dd885df55e1dbc8a9ff84952b251d2f27bc9a1f1a3f2325dc583598f37fe5454107bc9a0e59b9f7d3c930e36331fc998d86dfd12b7a02d162c31fd98455ac1cb3e1df0143e14205a90d61e50cd55dc51f585e28a5a5556ce0adaebe7d345e588d8383ed8a65cecb875d6f9324194ce8783c612871a30290ea87ffc60ba2c61fc1ea7dec9441b379574058779010f97c98beacb04f31cae3f151ac9e8a2d0a3a7688d572e2e83ca6884b811523a6cfa0e1c1afe99806f9903f9f9067bcbc6255ad741b3c976ac02e4a7a62062e09bbe4177a453192b331b80eac7abe01c7e38cb1051917bc04401b822830fcbb93a6e050ff2a1f7725b39fbba96f57f2fa554b35c321f94920aa872c394047a57cb24ab505a05b71b259a3d5ed090caaca38a145edc7ca3a8669cbe31da23a0017bbc8470326be186483da723ffd8488bc1c33f989605653761325ab92f5cb5f210c1894590c8613f65c7dad02f2a205e1fb95f62e575e500a9da84116d2bdea5bd54a85790241c1b4d69ab66c22e350cd984a35992d5899b172bc42541c14b6fac22fc226c8ef87ad67f99882d4d8a73c8f121704eb6013102c62df1c5de4648f1ca401b148cc8ad3becc2db821a733b1208338ee90c5cddeb0491a63688d848998cf491a75a84b65fdb4a9217647ddad9e76a1e77ddfce4fadb6a15b4bea4dbbbc588a598b64834bd02e2cbe11ce9bfcc9157fdf2b6fc72812d9b81ef5b1f9a8e530281fa31a5f6cb6799bdb125b1d725d86f6c87e9f3cdaed93fdddd34751efe4593ea937d419d2b52dcb75f5fd07ccfda37b98eb8a5db14ab0f6ed5f15921a8082a424f3650d486179494047232336e115534d433035d88ac4b2f04d38d7b37c3c83406c41f29a8c783d2394ec341075880e43c90e34221f0cbc2a0407540f7605081e938acf7197549d939fffb21435467be7f201c9587595d7d1d0ecdb5f8368c4be6b5a95cd95fb3bee9e48068a7ebddd7768e8925b391afe1a9dc35012931207752805ceaeabe69024bb62c298d590f472fc0aae0271e4012903124b94006cb25801f448a4a3d085dedac6b175cd170ff468f41802809ac02c02faed515c37b55818cae96695ad1f9ef59ba515ddab78e52c7e0077add8373e2c25f05255df2b674f3913844e695e8a9a48856dca794616151dd7f9988901f981d53b98e35c59874226d8facd795492e15e185457f4db7327b6ac9a96b3fab1f95236b20153a21dec708d6ff1fabda0093fc4cc8ef6356023f39b74601147631d90f815d9db8f85b658bbac1f8be85122c0f3e990ff3e0543a3d3be6e460e85bb9340f8d30e2fc16698805f81749a6bfd28bdf1f9f3604d035e469e770031892d54edccf8b4aed97c51a3d0a599dcd0f4a294c3eb817ba3beea9362000e90b9201cbd20477c596642950b4881df0cc89b82c91309e21da95793bc12f5407b53423db22129c91a593162066e77b4222ff9e87f5b575a328b583258cdbb2abcd5923137afcdf8134e5a5f92759c321c6ad122c90c1fe525fa9a06d3dac1c54c335dc8258066a42eed749099e6a9a8df8bef2824574682d55b7d8568364fb80a91aed797c4babc300145c9926baf2648f4c2335632e212443ab80591b8a3aedf76e3e0a39fac5fdbd6b792124e388b77f71d6501e57b897e365893dcfcf547514e50df2427dfe224abdee8d0659fe317fa2d97f8ed5409fd2e5c27c90e2b9066f29450b26b3803f9055aec078ffae45477b82d43753266d391aae1e6d9ea97fe0286e8d4d0279efc9692bba0d5146c95b4c4d72e45127e1a67267ef2543f0388b631adad557ab60d3ed9ce93495ed4ac721f613207e799522a9c67bff0bc741e1454d42f2205e774e1fc5db16ce9dc55ea473fe6d399db61e1dd6a9e6d0b3e771fd4fc44457d3b0f7fe0635a30fd4abe398fa4a990bfbd7263eefd286c5de4bc2d10a3db517ebd86d1381db52a7931e5b462565f957e5a61a467a89de20559733d1664db0a421f311ef78541c97b637074832040f7dbb3ed7efb651df6c24212f5837e31a76208a9a4f2ede8f77085df1e740925d5ec78e00fca73cd8d027d49172f697509b18abf22d18643343230c921197949174f001c0210ee1a7008510f2c848892897a46aba518ee7f3afa2cfbf367930336f98c1e4c3efbf4f33f67a3ecd3c9f8e0d3f13efbfc33d5c4d7cbfab023d4c4fee79f7f11edf9ede3555fd2858ef67d4e6beac759476e289b984ee76ad20af5cc185be83cf491d8b56e51da2fe9a22d469b44424cf5afe175bcaa5ffe17bc3cbda072bd473821ace74243b43540d6359ff79a36a46c071cb7de6e2c8ae2147131075a90bda5d37318f74b29370365554550c909def253b1c6ce74feb604bbd29c2e48c5feb9cca5b091552d78b182b09d8902a7d54852a38a5f0b560dc833381f8ce888157ba634afc898576cef173164e28be19c2e06bf88d65300922ca3da7dd84bead2149951814cdc5268ce2ac0e032ac1a89f676e6d0f227920d38223d96b2a8b13e43972349a7237e4c6e3beb9b698d5501f5b53d1d466be0f145d065d2e49aa956daeaa1c81de653367d80e27195ace6193fd4f7f608650c11e398b0252fa724a17fab0bc763d5939eee920b9980876b77347d5269479763239cbc250792c2dc5b7fcf56487bf9ee89dc9530455bc2635713c4a448d3fd0ccbf3f26b36e673f653c9f5aeae0bf75d95c1f5d9d74dd899fdbb849e02953cd8d9f57c2858edf3611c00464eca8c8aef99c31c71aef8d8012a78e254bd79621d3d893c87d22c4b1c426defb9353eb45749075af4ecba6481cbdeed834f82e54df4a16ccdf932d8309126292bde05d209574e2cad715067fcd48395d12cdba0a6d850d7b3272e82bb4acadf861fcfb6b1b7b766befb67ac10e936443d7296722accd8f28f6d7188251b3ac50634efe0184bd2ceb19da7a2d37410c759dedaedf5663848cb08d2369dc134e89f88ff2ab94f274a72373f56c4a6b9642b1855e0cc0ad4b7d237b5e6b9903f17ae9edcea03eb7d8372ec5bd82861474519845b77f4c30009fe2232a3d12f2d4c7721cf1728867b56385d4b47a17a7b27efb8b6139eb76423efdb8fc73cae17aefeb9c32dd0da8d209cf2ee6acb662a6d4aa345fdca6681b62daff388429021ad57a66e371c365ec7c596b1d962e445c516b4626624a6b5d07bdb3631db078e9f5e3dfbf6e9abbf1f3fff8fd9323adf5f74dc322c7a77dc29ee7ad5f19fb9a92404709c67c91f55806e2239b4e6bd91d8b83bee85d9aa3d9b4bd74d3f105eb1037d7379e486b0ebbfd71de4935a80bd239be37bd39df083b8e8443c36321caa03da5c053b5e3132624c8378073995db159710ee906ca8207d4885a6ad95c0ff8628362d71ef72526f9599ebe5e51f25786c8d7cfc834569a524da34b442a57009cd4935a57dfa7008bdd8d10dcc64dde014629a7e17c3c53d424826a110ea75209231d57b3da2a43b14297fd6c2cdf952aa03e61c4e09de806cd09dab108e22b2db09564c629b1dda966ff0463a0003926fd570156659a5ef6cb09fd1d1cce9257b51b34af635c45094adb5b8547b75357dfb127a92887dd53f4fc8af389f873062cde0e2d4d4f3f0e1f96e9f64bc6487b833c6d5440222f0575550ee47d65444b9e9c32693260f4ff97fe0ace111293a65892fac0e932312cc55d49860f53a5927d126e343720a3a85cd0fbb71bc4bfd637147aa58c80c2475e2d03dfd48bc748af82f0adf5add92e635e67fdc6df5c7b0a58fe2c88d448ff214719a18d3a218d1f1652c4f39d106888bfd3eb918795af32a9ccc26da640c897750d6a122d62717997c381e487ee9ed3e265b17d940d2f8b1f7a6c5c5ef024c5f17008d7391a9732939d8ed2b7ebc6090d35edf3d5cb0d3fd384bea612b007a1cbafa102a437a6ce2f835a610adc72ef62ff6c14de0629f1cc9ff31af2e3c271fbc8bfd686e9c247d895ab21700eda0e9277fef5d8c9084c823bbbbe4628463bb1877f0d735dd4013921c804aaa7db13fc0c4da8991375c37fce413f29255534668c92155acca029b97b5ca2e880ffa4427de074eb6a23b538c0b37e22ef2a46c60d37b14db91e6255da84a22ec86dd3fc2fffd18e080809d0f902a776241f35239f9a81ec4e679ca6aab2424bec3d211872fd437dd7bd8e68c28bf9232f53cbc8825b6c3226e3e72255474d5d635244bd88d8bd19a4d4389055cbe2367e18edd853b4e2d5c6225f677c719511fcd74b58c3a17c7275fb472839e3a1cb6952316d4dc977491f4c05509259e61fa88dc648dc5302f7061622a663c2f67acca6b7cf3922e14cc6fd0e60053c8c803fca262759db36a2f9f96bc8a6e7da9996ae45c9a6f143d63c40be487a126ae9c2d856409a9d5cd933470642bade67481546908d26a3bb8dd4d2de03cacd3ef92d2a5b30830e99ad6df2fe1ce7b10ecbc4d9b891d82a477e20b5babbcf38e6cf7542d63b52727972e3176a1b65b2533b39d9536b3f91ee8cdf7c0dd7c0f229baf21566a13d63fada426f7b429b78e8f4436e98366933e886ed2c91a7d779c4d9448ed10b53615c3fd2c98e1904c2b3a82e0c37a86d98c5162d28a4911285859437ef0190383ac1417a3650db13cde6b9347922e22cdd03253d1f8b2f0bc09c585ecf6f58c9504f510aba54835181f981785c277c374eebc149868991b132b8903262aefb1eff1403865f54bbaf821bf64a001c43ca549135af37d708abc481e23f567f35c88bc9caa4f552503f4a0b7550c6ba350dd33417997bbe0e4bab71fdd2cac0662aa4bb00169c110df7a2e2c17c9183536dc0ca46e35c06dc924344b707e9f9c6d8bfc5fec6cdb73a3f122ff92de4bdd4c4c246a66920dbbe3744ec40c326fc92ee381d57939e6e5249f2eadd78612bbb6f66ebef984fca814744a165207d59abc827251cb4ac5c2cee9c246937965728b3b4b76c4f2726aae3b7296d9dfbc00c09a8ac19ace968b02ae70ca297e4a2735abe428ae5855aba0e53904c6426da24f466c46af72beac482e40cda85935979a86d5c8da4346cddfbcfeeef53a15805d7c1aecc84d7cc3af1ffe930ec9c321f999912267848ef8b226984f0e6a911413245b427efc884bffcb7c5c71c127f5f0ed6ac1148a9bf6edffcb179fc60d2fe254f9814347dd1c764fe0e1617863164f5847ba9dd53fd5eac2a7aebaf0e91fe7acfe69a3067cda7e56277174dc0f6b858082fd22252fc314e92ad01c40a7dac4811405caf83dcfa7f58c885aee9223665f4fae010edb6c3d7f77d2c19aa61df15d73cf7a3d08b1c6da1ab805d89894401b99f47478c5ad4f2e1a94daba9cf619ee6cfbf457387cf92f12d6ead84af0a0dedd8367dc9b5d9d807b67dbf03f6efcda200cca41b4a15f785ef6e41e7db6bd1b1b0bf9706e8772a4985fedcec2365c0dc8db2a9f4e59254c4009a49814648766d94e9fece0fd3882beeca022b363af8613c63e020826fe1fa0607e02bdd4964e92b19ae685d86005dd250558c73b58f2e041602533f9cf7d0c48c82023b51b72b6ad1035d83b927106b8f962b9906a95dfaf2330e02358dd282f31f20fa239e67421820c30f79108cba5e26f95d82d80107d4917f0d240860e3f213b57b4da2193fc860922e6b428f646cbbcc8086ccd8a25fcd0490c58ea162a09d15d7db713bb8f9b70c4ffd97f7c1684f59dc8438e1b901814b87ddcdf09ab7f9f717f27acee14f7b726a4ef7ff6dda03e43cda0b013a176e244da3445683ae66f8328bf1356a7a3fce474de3eca4fb0ba89f29355dd4f949f6075a728bf7b48f4e964f7246e225a88f74b9c2035685034349004b1f3ae503a61f57f8a7f873b94dfabe536bc336ddabcade5168d01ead13d5b70cd7970631b6ecbcd4b30c9ad0f6f75856a08f7c7b4e2aebd6a4dd6b89915d75d346dae00df94edce00e195c4bfc7ced189619b41c5affad57fb7beecdfe4bee1776a40587b8f10f5ed6eb79c3adc7667cb693710b37f83d534b5bc6896addd55efc9a93dc4dafa2d4346ef2f58798d7423770c471e0ec9dbd7cf5f1f923c6392fbfb7e8032fe790d30e72306ce5f90f9a74f04470396325e8d694946417721b11bdeeb8c560d2579352027527fa78b459133341ce095b8545d2982ad10bac877c420296d60e0c67d189929b6586e11be08eb846659cfcfb88772b151f25ae304d7260149cce81f33d22acdf4a46b98d51ae627bfa370a8f591457fc43025b281a7887f740a62fa3716ef7f9ca8fe261ef09ea574d7d8fe5689f7c7941ff71ddcffbb17219b460cdd5b707ea77d89c4e3dd13a7daff46bc934e62d247888ac9c8aeda7d1cb22a0c75527262835e760cecb8b7e00d07bcd7ffc0d8756283bf97780f30edab71983145174433e28747643f5a442316c670865342cb0af83985e011046dedbb18aee7ff8e881f9731d6458dd92ca9e76d83ead74781755d1b778b3be26ef8728c2b3d9be347e3cd480499dfbb0da3c91cd9e0d7f5ef0f31733922e65779e728871356ff5ba21ca2a1046d3b3518f1137b73ab137be03e28cfb2b7725d8740805682fdaebadbcdd33e3e88a4afbd6075bbaf7dd0a75b3adfbbbc7f17470365d8213b5eb11d65a88195fac4fee20fe09a2058fd715c135cbaff56ae09a9f63770d1920b73bd8b965ffd7ae7287b1f37d81ca7c8ffde4eb8ebf916c942e7d62df7da0e9df62ee8ffecdf43f0678bc21178819cb0daf502f1dd3bd0b9a29b7b075cebf7ddda1bf78ee6315e0f0470dbb7f4e088d5d6ab693565b5561cf162bdaf331f69df8cc845b6d6bc1cef0ca38e35b0bc91ab7f6c52eebbf04be83c61aa89a4e458ebca31f0fa0e6e26ce93f0130ba459f61cdc355c7466c7d72de4cf18691da584661bc009ab23800b53d1ba3ed6b47f5de5217c662b4c50ae3858638b45a62a0e42e6f53d50abac2f72b34ac833950135d61d12803fb5803e4592757cf0b63923adff5d96c45684b130b53b79ffde90eae380e0dcd6f8187cd6311f8a33237781a61b0eb539512c56e4814ea55d097f6aef885fd7ddccb9a115f5df8d5fd791c3c87f11edfe8b68f73110edd6ec5bdde0f1e7e0588becccca4c47e1bd7fafae3eec87966a12da7f3442e87c3d30687cdf89a2af93248036b479938b5af66b6b6bedfe4950e4bde142e41038b2a8f379fe2fa0da2179cee5190920e82811527cd25a857df30a624ea02d1d0f16acc9e110023e45cd2b15baa9e23d75b4095d80946034eb93a580bc8d442cd838a7858e69aa39c958c96b46ceb6e59958b7884976ecd6dad0fc9126f787e21f10716e63f7b338707f644631f12dcd3091e5488cabdcf560b80bafd32c6bcabea9f8c2e1fc45c517af40a434c8882cad9daf77bd8ea9ca8fc3ec978dae9ed002a910acaab5ebd233cbdbc71c2d74df7f7bf79af856a7fa9556a50cb1dbb4b8b4f7c2ef5de3da108093755f7c66a6a32bcf966f72f5353c9dc2df5c87bde919a36d144eed45943b6a7edcdfce67d43e99ca1d94d6cc5d91c8ddcd2823c3c31d55d7fc34cb72386587cbf74ee7399a65fac4149514b2edd7d760f5831cc4ac62241720ccf56b92b171412b96199b9e351d0bf0918b6cb56bc581fa549fd09d3fe5d2ebcc411d3947b2ae7378ece9ce87d2c6a10c4846351ca9fe8aa808f388d9ccbcbf0ee38c95f8bce12f7b16d3dc750b0ec1c4c21dd0341dad630daa66a030ad6587dfb1904f1d4bb47c470a868acbfdc86eef4e28e2b72ce491e36b5a8f67f7e481b3e1d19417963ed2c5ba43c2dcb46e1d0f1eb80f227a32c18366db4772fdb7645d684c02f2d845cb0c945d561bc37e2439a765015cebe56293a10d7bc7385e59a78fb638173b3981f5497b528af47944ff987405bd842a1c9cad87430bbe0544965fc2bc366b1e60d17e2b03875e981b1a385a040271cd1beab7ffa6748976f58f687a206d5123accc6262f62e67b9bc28d894164fc77254ae2b82a7487897b056ec3c81d0f3b7b35c90195d2c582924dd68a3c0e582506880651078b29ccef492c56e48fae7651f4ef58eea774d85d78c56064996576c5c172b4205e1d765f30d2fddca076e0d5e7dc783e9e0d07b8617564fbd09f8c45b319fa8e4a90dad7b4fed10985fc9cd21d9f7510bfcf6a1adafb1aa2e6dea44fb059fca930ff9bab73bb8696fe2458d28391837793d63e036e0d059cc741884ac3fcf98a4f08ea8699d8f7708af345aa10db0a3e897436d4bc1c83bbb6f4f0737bbefbcb2bc3a94f3c7a53ed97baa28649defd690eae7192b953947d7d2f7d8252f0a428b6b0af843a462865b124c42c7f59216c6a4ec3638b4ffd463bba655d93bdbd68a33d98193815e257058d8217ca29ec322520faf69b76530203f094676f41077b4290b4d56301e336a39355827c96b82f305b243d79fd73b027bf15f0c0c92c0c058232263be2a0d88f2ef151443ce93fc92e4d6a786fd2128c9c7f5d9d4014513e14ec7bfdfde23654d87e276918daea437c94eb241d293df3c9189a592361af47fb39bfcc1b39b90ee67bedb9df7dacf7acd392f4c22147ae0ac3dedde62854f59fdfd1a67ef06d081a67d70daddb4e10606e4d58f6c52c88d945f9780e9691dcc77a56242cb95df36820b9eba27d53541f7233fe85eb7d15701f9232bf67eac63ef9d376d1883998531388e600c662ec66096c218342e59b6578d67d34f1a092a26068ba5982572532679e9b784ea1f63f4fed88adea748e4267a9faae8fdd12da2f7bb43f59375f07f81ef606ce5b8ce8466c950e17f666e27d679e6ad434c3adbb646240b078e72ce773137ba285a93ac4a99bf9d9bfbd7d7a5deef1566841a08b86dba3666edfd86d62428d0f0f9edd4bd46d5539dcbc5311c07f3e66e72576a7bca7d7b4e2ff1049031b95dd19a651a99b1d1e91ecb03412e08de6debda6c050f6cc16e7602d5963360352bea5d804c2fb503db61146bd2eeb221dc95d33a6023451a0b2b4c57248513cde6c1e560ab0fa971ade8bb973a255e09faac6b1aa359f66d9e650cf8c56593beecc5aebfb46836c7f573a61c71b9734fd75ce30880f482e947cfdc9e54801a07deb175ffd2ed2bb352bb5d1136cb53234426bb7aaa3f3a27efdfdbd3d7e993a3507686d01b811ed90add413a418b10d779552d5e70794ddce691004144fe08b7a5ab4453761be0d66a5d065ead0db2d86dd8c69a488f9fbfe1957d2f07977768b8b3fad42c1078e3cb2c5888927583288b11434073cd7a707c1408d9aced2a1c6c2ab5abf703287a83ca663c74f1d25b4aa426fd64138b929115733d5dcd2beda5aec6163ba346c7f6a16d3506eba3ed8a335c1d8905995e1beb3f58bb326c7f505d9d7d0bdcba6ae05ae56ecba61b0362e8c4c75a569bf4e14ecbce0f9b488438748ba3887dec0656c44a78823cec8d1c6739f5542b59cc7a192eec176661558254cb9214f45f79b122d7335662d8df222f00779d23862240e280da2196687d5c8118a896e5603058b366b117b135bb8ebaf8a95ad491a8862050fdc359e9894b0567594efbc6f8e5514b415442210541ce950e2395777caea3ee226e09f62030fa314a76e2b976744d90737b0ba2fe39db7e6134c18576c8acb9248f0ae5a6359f0b0c03a4720401282671764e332503f961fa001f8b4d4dd226527df79a159c77bc66d8ffcad55b9c606c216ab3305373b4766af47ea2aa6d523dc4fd0c6cef84e61b93e1b5e1ccf7efadf756e27f5322eed16179a57d544602e33fd8839a6b0fa018de70649ce903472e4c12166bf473ba505f4e59fd9c8d96532997b510834a5a58cf3adc2439e3f720dd1c5e7af0806c39622c3026c04b5dfe1cbc054f18237fda7ff4e78336a66f13f286330ce3b470f186ec219f148c0a862ed5939575d51b9bbd58f45523422c3f9ddf099397dceeee22bce8b3387ec29765a62f13c344091f97d791219a2d6e17dd035d2743fbcd8f2a335137299cf031d0bf98b8f4c8069a4479c62ebbfdd00b239e0b2acbc5820b5619cdf0d61b47a8366ccaf6cafec24735cd4bd835add8794b10ac39b5ad5148505c383caec2f78f6f166c0c611182cf3593f9269d0e0a464a9befa53426b7853bf15ccc96e6705b7a6fc70aa3fac4da5a3fdebeb07e4f50972df12da08d7defcca1ee59a51baf7aa22acaa6707149e72cdb94f3e023cc721665b4c78174499f793c6ed8984fecbe44d6a7db97b583c0989b2b5ae419dcc9a0224da820d7ac283cd103350c4c50f8071d4f6fe11704766afdce3d1282a5fb9f4b5af4689f8cfa24630b2793375acf17f52cb099c3334ce1e6f58efdd3a9ac6193e1903ce38b9c65c84a912c50bf5031bb6425154339ff9518f38a0d47051f0d3f1f1f7cfa67fae7f1177f39988cbef8cb24fbfcd33fffe5e0d1a79347a3c9c1413666fb5f1c7cf697cf3fb33e1cfc22fef4c3fefe5fbed8fb61ffe02f7f553d805bff9216a462e36525f22b3450d12a1792c73561e41cbccb05d0e6ddc0a1993bbe3ea12735b8728ce07f8b78b2b58c95e053a37d2440023059eb80bc7b8469f01ebd33ae6b2021ca9d9ae4fac381559bd4eba4a670fa2dade6bc5c91776c4a8b77c0ff5cd0e2bc27697a381c5ee797f9808de75480170cf8c864fc723958cc164ff2ec6886df1fcacf7707f66453e8d2282663282ccc477279ec9321c192f2b7912d26dfc973ee3b22c967d6f03b4c6508c396e231af0180aa27ea2a1fd716fdc3be2058cdfbf764a4ff8875cdc59a93bd78455fbd33c4ceaf68c1cabaaff23c967b159b14ec26bf625e7b728034d6c0085e39033dbe99d1a5a8c9a2cae7790d7c3463e34b610b39f0ca3a224ac5a18f7dc34190d5024c06cd0bc7928095c89e586f3a51e31910989177a7a7cf0a2ac4f9f93b90210d82305c11c857aff006454b0bbccfa2ee66d414045f22a7e828ba99ba3d12d7395ca79a7a4213d389ced4572ee723564188e474594018e9a26242e4bc147d92d19a893e788e8d382f182d71ce91a3105a194e08ce316c2c0f1f67dba74acbfe914d8f6f16e767db875e27f085ae91556396595904d151ac111dbd57bc66876467873c24433acc6179ecc8df76765b5ac791faadab1ebcd1bc25608cf58ce59084a46262c1c195421f15ae2bba5848cdc465f9c7a49e2d459fbc3bdbfefc6cfb1dc983a080e1d02a2e87f70ed073a0573df86af7dd20a134ab4c5b54a9edf0870bf4ef0df615cc6662b01baf59eb5bb5b5bfa2af76492ebc11bda2af826f241f3fc405ff90b69d6e1fe2d27f1866e6180ec9d3528b608b11724116ac9af04a6ef30d7c3798d2f3b1863d4c90f42112f3117902a2f5a12565c9a1fef3612b919fd39af924f68a7c8d8b253111cf80d77171b96babe666188dd853038276c3e5073c1b69649e17452ed898975993211421eb075612c0bc449d083b8369b8d25f46dae113642ce81818970c6fac9983762a2316538c8226439e4a5e8401e328d0cd9688325d013a01055f4fb4b085d663af469ebf98d7a5973490627ea7599d98f3977481737dc29492b22c51a680cc53ea289fa0fd6e6f417329946906328896242fc7a0b2d08214ec8a15b145fa6d9e61300d61377545b120a2df8f2b46854ad58a7a5574c5a2daf9d51128a1b1450b051e3e5cef1533aa18bd0caf048643f2138c9bd0724534018c7fab2a45c991228fbd358e9aa723cfbfa042d3be2047f62e0b1ca1a7060ad8e86078b1aabf8c6558525a85ab1080bbe57a5581b4016b1b81aa565c964fc08bba2696fb8688ac2894d6eff0e37702b440e8ff3be1d50f2780a6de4925d51159a333ef40bc6735afc811a1b6ef489f8cd4e391fd38b0a3e2c7a0bbc16fa1e16ecbd0112b0c15b2189f6161cb038d26aa27ca6b564ec7260d8cfc06e0c16ea474ef6cdba2c0d9369127773cce07cf472d46bb167cf50ff1e3a0bf08e3c0cfc1911c2bf832f8dc3a53c6d6e5532196737576ca950ffa78352ef231c1412e2bb90bbd9d31428b29aff27a36874219ab95d90b8b5b75361f4290514617b53e9d1e9f90cf07fb44303cf4ed7f3ed83f187cda277424cff9e39af00553869177dfbd7e3788598a3083351d5f42b2db8a5eb14a44c489fca4de114d0a1122f272ccc835c37353c920e283cd95dfbd3a48969916cb8df2d18828388cca6583bfbc7f6fbb838ef4db51ecad5c75089c6bbe5740baa6c8f52c2f18e9e1d3bdbd5081ff212f19000dd36a3c1b9037a810811b472ee4ae2e49a1420a7825c9884743c8950f5a22e113afce6599ff73c948c9849c256bd283550f7d3ec5de9d03af863a9e3ed985654771fecb321d15216a93e01c7bdc6192151dc1fbd4de34acc7d6ae01a70f659f28565aa18accbd7b804dec16d61110be52b32b302448e53ec7a03b4ca4ec28b3251b332168b572e8dc3088cf1bba37aa04085f5566a32de879d315347b8c7959b3b2167d924f4b0e862e7930683452b002e61e43b4b3aaeeec16fb678f6a2ee89351f32b8aa53db21f587a6e99adc29588fe4439a3f69988b800f2cac807b8f1340cf840cf6a34da3d8ece9dfc32367dc321392e95d59ad664c4eb99e13d390b54ddcd0aa9c798e56acd0019b1093727010cb9630b23bc83156b8f64b43bb0586753c6593fdd3e91191dcfc89cc941f8459182803baff8217eb7d89b51f13ffbbd1178b3cb4d1a8c84102c2e7909ff6f61a4bb7212880bc0c10824146c661bca28bee88512ca79e8278270af018c6e1c3a16b9ae2e346a2da20351e463d6f3af8d8e4fbe7889d5466cf7f1aa2c445eaa7337f482fb2885e31d568c4f6f53b11e4a843ac82b54f18aef18d8c9c15c7d1c715a7290f50d50b0350fead1a987257c8e171227ac98f863d045e2f73df28b5e380c03e80ddd1b4294a854cd40a191873d656387e3e024479722e5f721c8428a9e1987e80af9e5cf793de3cb9ae435a978512c1780d56d1cd947cb3283abb709cd0b426b38bc2d785ea213493e678ff19a4e7d2fc872a1564a21553f1466d7152fa7845719ca81bcc6786074623507778cf910a4277bcf6ee87c5130e3ea2a960ba60ca90c4e3f051fd382807ffea850de2d2326bb3ae3b95463d0e22dc76793420a5d685cd4f25f0c8b078f4779bea2352918d51e32faa36ba688325531bc1583b1c0d8f2b9d4b2d471aeae725a800e016321cbb2ce0b45c8bcc888588ec78c6582d029cd51a5fc6488d388d1be9f90de7897bcccc73356909f99a8e1ea8b918347fb9f933df9df5f54b9972fde921ff2312b05cbf0917af1332bc67cceb40235e7a31b22f8b21a33b145dea277192d95c72ae157acbacad9b5145f337e4d5ef2d1ff22720ec6b65cf3ea52e1fc7d822491ea3c99729e11cc9200765b5ad587aa90be7c9ab32c5fcee1f2e96ff36b3394e1888df93c2fa77b936551acf62ab886be627bb4dccbcb3d10e57bec6651504461dfe393bd79e374b1f7f9e77ffdebe7075f1cd083cf3ffbd3e0e66a34fbe29fd99f3f73487002c325135e64ac12ba6347ee8ff3c51ea18b7c0862e82597227e8291dccb119e82689d8fc99cd5339e09c26e165c181b1c99f36c59308d718f8e27f2ac313075c3659bacfb85e4e9b936aae95680e6e664f518bdfee4ae56e557687deb934addd6c3f3052b33568e57a4ae18137d07c4510cc833ce257f2f2793b64e49112864af9e16c8a2c0dfca3628d4d188a343781891dc37f7a865a6d11d73d1ac1b20fd80bc28c7c532d3e6a739a4cf649520457ec9c83b2abe2968fdaee9d3b2ce0be8d34f750e475118c5c09e2a0813b78c346f2012f628b00136c61a65260c8a58a235cc6f7e0a17fe38359f3f6cb29c637360cec36af54e4f5e4cc88a2f2bc2caabbce2a59ce520f65b7f53a97a0c3195df56c6afcb6945335855d0f66703f20daf08386b905714ccc24fcbace279d637901064b9905f49327f77f28ccb59deb66e879da838c0e69114b063a2e46e2d275c891205723d310b5e0a57f025535e0d4a9c29f18e5a114803ebf35e5e4a95713c43532978289a1b26326205bf6e727c8ae548d4790dc10c2049779ac69a4b9e98c745334c1d4ae8b9434c71ff4590024ff3511ca2ea8db088ad9f4c07a61cf9b509d5338f8190e61574690dae7ecd44fd8c67ec655e9ab4b2b2a06b168a95c2082fb47cc7de07d6afdbf9df79f491e5770c7976fc10e8177f7ff5fac7e38b97afbffedf8b972f5ebdf8e6ff2e7e7efae3ab17affeae7b5a2d59e079361cca6d737c4904975a845e32729b52897832fff875452b759b7a0add973dc05c10acbcc25ff418cfb6cf75ae880044c1430e514b7ec597da99a84480da3910560a7cc9f56889450742dd91064744ae14c1c07c61b3b05c2a201d40a192921150792a2696450d62934ae55e1b04f262450a5a4d19481a21970a7e18e410f8b0ab58da62e70b9c82e7c7ff78fbfaf50f27177fffe1f5d74f7fb8f8f6f5ebef2f2e3c4f7ad7a9c20104b1bc476899ad2ef9742829b497b1ab9af34218c08ed6f60679295b7ac947376e3e2ab1581dca7fdc3cd0377545c56178b4b4fd9f0e9dbf9cf39b5319386d1de27f8668966a2ff7f1aa26bfea30c16f0a7efd8c96635614b088602fe89317cfcd460c013e766cc84bbaf07270f48976aceb135a14fc1abec1f078f03aba089e460abe00c1ae9df7e29fb965ec4a7e643413c7a5ff9d7e1c1405b885586178d12717accc9eaa31054e59f05df0b4dfc85ca84e97b21ef51b8446680c8ab88ffac683312fa7cd3460c9d81ba92889b061ff619f5c80ceaa0765266c59f36a59f6b505a3ea9b18bbbe89f8627d155af4b4e6f3be8578a40eabfd007eaa4f2605bf0692f4b5735adf6162f59756ecde560c1f2908830a1fcca8b0882689a307a0f27bfd905f4ab20a2f6a5fd220175ff31be674aaf10eb57f97e761f9776235d895bb7f410ffabef9a01f0926729fe906bd650400e396e6a97f97bf945fcb4304d3000fcd939f4a6e3dd32b5175bd320b13f1fffa52c6bf28350d856c550a2452f3ef4efaa4aee898f5ed6c6b7d79a0abe8f85256afb3ddc0f1f7c3e3b372bbbfad248a8a526e36fa0b14b7eab0fdc618f37ee05cb01e9ece24db486519538595b8f7e32be3a0a56d0052c7283dfc54eb197ef57d68cac417bba620e0e5e49035480156e4909b90e4e44bab166dc824f9c387aa73da82d7143acdcf1f374a8b1ecb0002995e4f103a16ef97c7bcacf372c954710bffd154a8d0204bb9cb41e79ce8fec767e587edfef6f0932df9ea195fac2a08609567e78347fb7f26dfb18cfc4c6bb8b62989392783ad018fedd6f199f45ebe78bb2be79fc9c2cad1ef17965d630d6a1fccff5ff6deb7bb8ddb581cfe2ab092239231455a4ae2db52615c5b761a9fd8918e2d37b78fa82b2f49905c6bb9cbee2e25b196befb7330330006582c49d94e6f6f7fc98b585c00036030180c06f327eb82fa01ccbbf0dedefd465fa349a4c6cbbc27f5a583b2012a0cb0c96b00b607a5423f2aa060ed3c6514553280ccdb7661602208ad11c19824291698d0236c35a37cba547792ea62aa16082cca95b06c6ae28a6231bd994f9dd5f3da9eba3679f99455c14714aaa2c448b4f56a806315ff8e3aef061bd9a0a449d2134f3e6d9961ddd9c74f37d1210c757757c1d62f241c22e6278218ce0cb79d68b14856e0a9afeeb7ac1f9c00b470e07863c30aacd55d60a0ce749131b8d335cba7b698120df3a9d729c5443ebe4e496b994fad823ccaa7b07dbc36de5051cbc9caef42a3c63feef43ad22ed48040b06e880602a25a4c1025cd48e0da80251de4978519295b0acd43f9fad078ddc6d51a77151718da9e8071bda71accf413cb3bd17cecac8aaa618bcc28218010463a53276bc3b28506ddc98b52ddfee1229b2ee662118d2ea3a904cb500481509b6ed3b3f3b6a8b00e1fed1c11772d3e5faa7e1da7e3ecbac3384615413a6c4c0a5cf41bf19784582108f8704e8aabef3bdf75be03c50cf0f00ea1fd4301ca18f5bdc279bfafaa2e3ba636dc78e8401b656378ae4ec29c590f07f556a8660018af5e1ebdf8f5ed0bd4cb92fa21cfb292828e66f90a956ab6a732973886ee20455dadf8b8496c09492920cab0e39f8b8056e20f09f774bb00c982c9905cfc1377f89ad45055d509412305c01717b417dae223bc3667291804e1085ea042b12d4e96b964a5932cbf8ef2f11b39698ba3599c8c7325a65037b0c2ac9f8f6212a7e3e7c7af7fcdc6524db328d59c2f8651399ac9f1bb051a093acdf7c6d91c0f332be6e0766a66c30f4c8609a9e1aa76d9a6867938a1aa9816066faa78dda4ea4e4c5cd3237f29c17ad9f003491a2821d9ed722f68d9f04365acc1d964c30fdc728ad91c522930449aac0d31fa84cd55f46a07ef88431ce187fe83d505ecfaa328498e667274d934e9b9c4911d1d5ba707a6869b56cfd63548b1fa527592699d29f938a913494414ab372a442498d7a19e84375427e9412c0b279f4641fd86c41a280fcaa7aae258a29b06d8b341552ba5dab28e0dc60121aa42df6f6ff573b1df980702117d7ab83572f06007ee096824665bb53884eb3c2eabadd7e71961cd418867a06b508cec02bc149a47dcde0f48507550b4e9a5e384219dfcc7a8462bb0540c188fb2cc1a1d9aeb0c07bf16923b944346f347dc28712d1dadd4be68e32547a77cd62321d18aeff430c22d08c31028b13925aea38fd53048a9d13256422851915e78fc6c15541526950d3fe8fb1166aea9b20264141e3a283874d12c964358f9363ea4c2df55166dcb82ee335eb10ebbb18623bc85575ba6f69f2f8b52488c4c3d94e88294e56116a1fed1e3667cd28fabc546e58cd189f88d83645cb957594e83a2f0eaac594fad8e4dcdea01ad33445f1452ddfa7138c793f07254976feab6ca08dbde778b11b717f1447ff7eab3603e755d58b2ea5c5c00222f2e140f0c026c66b4667c9b562157e7e761256b8b859e62b1dd14155bde029c70e6d1178b43779266f87c022170d53960f23225db5a37e671b390c984ab71643271fd3cfd5d63a269ebad5362d47e780b71e2712969790fe9a6d9726aa883175ead02eca100f3137ff03aea0ce3a96fa03e8c180349b369c0c9bebb6bf805fcf622f3d8775756ca76b74f60aa5648b25983573d8f6e579ccea4ba2610f842bf7717e57238946301962d2985c38847fc6db670308176552fe846d9bca1cb170de6464dfaa67371218bd778a5ddddddce9ce8a62d1a24bd375ae289b831f7da9eb8a9ac071dd1d97c9ea51fa8abe6246dd375d91d145dae21582a8ebb273ede89bbb698a44d2c6cfbf76cffc321737106a1fe6571615fad2ee6b18da3e58fca08cbba2b7e970f1fa554a33dd8b1981cecb43f22037ef00898a71acab0cf49a6dfef3b42f7ee2ec9ce932c6f8ffac327f66773b003d3e848bc150d765abdc78ff61f7ddb1e87eba9014589aef6b82dc3d5267934e5f0feab3d0957441ddfc53c1b4b5df74fed694ddf79a6aeb13955dcffae3dabad78158f4dc5477f6e5f862b8219ef8d1ee5fea37612ae1715ab74c407b9bfdf9ed782a468815efdb4065378edbcc8e544d73d682f6a90b52c16ea9aaf2b7edbcec315e7729ea94a835455fbbe5d86ab25d13f571ad6e343bbb79b51eb633c695a2665292adadd5532c8837e3f6a7d54a4f78f7ed4f9fa6b2c3d4477dae63f5a1fc18461d4a30f513fea8060115149d2837fe6f88fc47fa6f8cfa4672c1669ef3330bbbbb63b03ed121ba6f8cfacda9e3efce3ee0e6a8cd9873b33ed2b356d2a5028e8f7fbf33bda821d3cd3facb43fde1a92289d7d958f613f3edc8ac3d14cc7981a233756a28a1b77fe9979c10c5f667a684f414fd91f9f293d150f453fb91765a5fc9b8fae309ed94fed4d43b818ddb1f9b0f6f61e7c14027e6635cfc2d4ae231f5ad24d3bec60fc3ce600795d10e61dcde867950747b1bf5fb7d89ffccf19f29fe33c17f16aaed5a5adbdd6dda7557356e6f9ddfb9f77be6fdbef47ea7ad3b3667bb9681c92ab2b8bd25824878336fb9afdc2267c1037009e2e55db599a186fa66b33bb6dc71a18925b8581b30eb2066c487c308ae7e24a9d34253637d7dc9eb1b42adaf3f75ea2315d7d71ef3da9cc46b5b4c142651319c3a524d337cc0eb33375c0ad1d8c345c443d6373fa86f6ea8743d846feb21b804bb1ecc776bc170e25e0fe7fb8d7034b5af87f3b81e0e11fffaf6ff55dfde92f97a107f5a0382e87e3d803fd703d01b6103713d5a0301b6c686f66ba8d36e960d30d69068f5f8d8006b0db132b6bc01c81a52f599f406486b88b5c2d337805a43af153ebf01d41ad2359c7f038835a4cbd9fc06286be8d7b2fe0dfc6d0d05dbe360038c3554ac8f880d10d6d2b0b3131c38db5eeef0e299c2c5bdf2f81aee176f96740e75bff1df0b0f1eed7fdf167f8f6659f640bc4c471db73cf830f8abbc16cfde3ed7661b1d13b4291a81b956ba8ad3a9fb42087e30329f17fa0510a7ffe6c5d3a3d38bb7a74f4f5f1ebd85e0dea81e9cc5c99868596df6c2d1fc8d6c41dd77b70149eba0c1760be26291442b346564dfe145b0a60d94e5f1951cc3e3e24f79367f812952d657aa429ac73771ea7e5ae4d9a23afed2cc7490de19d2f9e5d7e3df7eade22ef527834f327e37a82a71f1172589ccab9fdc5ac628c5fb1a97abea187f3a7ef3dbd337cf2fdebcf8a93ad286160f1b0ea85c2a42fbbc05f4f0c88774faf793177c2caa847f3ba36dc44eef73d10fcdc48074b52b5645ea7e27ce319525534e69bb00abcef50b83cdf0ce5ddb908a834d9ff397b8606b5bc30208aa80ddef873a7b872a3ba9be1218a2739faac149ec5732117c0b4f4dfad1913da2a30d01fb304ca2d1651217a55163f2e713b736dabd909d137b4f461f8c2c6d94380af0c1a2d857a2392be7490bac4e0148815a51fc4ff5e54dd481ab9f3d4d4e503b96be87cea637d8d6e1a0e27c1b00b3bb1b02ae26ba695ceabfed905eed80e3dd1be71d33fee6a862bedc01ea0ecdde457390b22b93a21ec0d97b94a5a3a80c37acf4c7a75119376284f023fa0eef38f3d07566d9d9f9b9b8bd75cfb64317308ea206b037c48d802de8d0bb3cf77f170f1fc6413a654ee0e6599e2fc203e7b0c117d0dd5df1a069c841fd343fc8ea0d6ab853dddd75e7ce6bbad8dedd75d18f3583d45c3130a8e367feea6b17e30a4474d4aa7c161426031e8f26519c40581530c5c96534de03cf5f1b21200c206847e00ea96a45e0fe7727988bd5dd76fbd0b1db35dd1d9a2753e72da85acbbc4e8458c7c5e883a2e2509139245f5cc9b47c318fcb52e6a2af44d1af2e2e4edebd797171a1e441cfdc8ef966f1864d6b7be4d9d460b2485ed7b212c8f497e8bc92da42d7ccda31c8e010dae2cc9a58f7c46007129268a31678ab36a3ccd2e668d8e26fd9b9b880a7c33e398a9bb570878346a0a3a15d671d14c1c788058c3929fad80103a54dbc119acb47b18d3a20f6f65b9596c502c21140a5b6d8b783b93be48fea6de12244cee3b21625aab0398eca888ddfeb7692e52fa2d18cdd7326a9335b8d8b1401d961b59c719db7dc2763be8a87606379187adf9b4531a49255a2229091cc9b108b2f2aa54f8610f9545584e8ece0843a26ab289b02be6de505fc996423728751557e5a26890e068a0e8826356522536ef14d1c1bbc684a4adc86f6d450f347f1583cc1467be2b1e88947adb6b8402efef810fffa01caf107b3c6820c91e51954d9138fcf1d3bf30b63ed5fe509c6e4d2b7aa47a8cec4d57dd6f90d29f07ef8214ab37435cf96c58f3f0e76cc6272d4907998f9797b6b90cb485ac7d27652437986308205d3c7e5f20e0f3096c7ece6da268d43a3b8bc4fc46047fd01b6808e4faac39875d86ae6b97c3a93184b5c130178278af7264b8299a4fafe5ec4859847f9257a99919ff318210c76e2941aba788596e808199705e5168d0baa4bb3834a1d6d8e507f36603e61bdc31cbb27564b6f10b2d147438ab638fbb4ad70aec53545954c1abb738db070b494e259a1ff486f47456afaefce304ec7e435004682d8da6fd2b12451d79a12ef5a8ee2c3505c4578d1bee1dceb9ce8bb2758e1f3d454288336f5e51411f137660fd7ed6acf727a541d58bbbf8571550858e23ab16ac068addb15fb7fee7cd7f9b6f37dc5c2f5ec2f7fd1118d4fa329d27a032b3570d0b65718ded960c76932d839a791bcdd6a243fe95cf38adfa559ba572ce408e82389a3547be317e4a51ee5522cb264358993448e3b7c449b6d7ecd98b9e92cd6af1fa3737668ebd27b2e2fdeeaa0a8e9afaba25bbb84c658d8563bb45374bd676c157ff4831d88fb406ce82eb06a1c0318e7d9c0e876c5713216d77278a9d846d3845bc1382914d7407cd779643cdd98bb461e81d960398b5203ce786a80a64f87edc46e3be237d948129166f91ccc87d02f00c3006618e8a23b4ca2ae81b6405f2a83eb0e42ef7818d00f903e0ad66eb52a22f5760a108306a0e9e1148dc1d271220b31cf7289d13b0017e23da381f71d71ac6e03cb822224631c9ab92c8a682a8b4e2555c016d425477121b721b0302d1eba34c2f809f7414ff9f95aa1a3e756327250a80e04732232b79f6d889181c9e554de2c2ca0f50b1210e9ac9b0893e98e54519637c12504192c12c53c1bde9c5a1d8966f5f5c2a1957c3e53f0db4ea602273577d015f1c65f6b26c46094653dc94e99bdcaae657e1415b2d96a850f7d2b152892524d69ea4cf8d2b1ed3dec911888d1989f226fea7111894113fdaae78f234e51ece2b40258274fde123256df0ef4eb68b135dcd7d16203506d22c46b55a3dbbc4b25642c9263b34e4acad442914171ab6e89ec06abc8b09ebcfc80cd2674ae588886cf685612623c9e462b35148a299880f85f23b753570c978a41aa16592e3e445794c08344d630b5a2084b22b8237907e4ee97144f5d8db55edace2698854257b093c6f262b9582431845e22117c9d006e56f1bd9a40c7128a3329338d87ebf1a5aa39f23a5bf4eab6d53272d526dae789b0cf8e279ca3557862690bfff56cd1b90f1f6c7f213e103f8aefe9467c20f6c4f7ec4aacc07c7f487fe2a5f8807e86afc500a07a2f3ef8c48b314f00677156f1eb08a93d38559be7a575146db05d4fab621615f652893b451f2022cd9010eb884f2d0d0a32fd4f3a70cdc1d0da4029b6778861005d32090290628e30283ebc3f57ac73638396415736f59f9e3f5bccd0551880b445bce51680f538837589e1eff3c14eddddf81390723f06e2e6a38425db6ec13181365be6c320307844dccc9c82d77917dceb6871cf91c1295f058482c23d611ddbf48229865e5053c88f3f0575f07a5dc55c18e42720506b34ec1b2d877a9fe9eb91f2d9235cf3ec2efac2d1efd313f02497f29fb2099bc923899effa11da8743ca9543b9e78155f478b9efbd3ab8063e955be40b530ba7b35dfd7345143ad2ba10185d7a0575b62ac78b84aa98c4a99c8a2681a2e637549ef8d716a4b7cbc43cecf7cf1208f45b325fa3f4229c57bd36d6dc1551c8967d150262e0051665987c9070fec109893e0eeae087ceea09107311c7811853bf8cb3170e280104317fad44a0b9bf541fe6d8bc3f0d58a058110839d8b8baf59f4052b8ca7c0be073ba239d869e98f7adcaaa0a54f4dfdf1e143ae42c4af9cc7e2d4c6d69a03ac51cccc53791d9ef603b7e1598ab73d6d3d1528343bbb0e078e90e7b6b58ba4d0f21aac9650022360839d45548e6658625997aa7d82710b9ecb0978cd6569a8212fd7ec846b3e10b0f1b8c6e8af4c6e84cef4b02888911dea79f8e3ed2d0fd48430cddc10da99ede93cfcd102e1003a4936ba0430d58fb7b740df5e031dd0b61ffe4cb92bec32f15a15a99ff2a435731925afa1629bc6cef015789bdcfc1815e5d322f41875601fa30edcc7a883f58f510aa07e8a3aa87b8a220aed7605a210323715181457b210fe4402aa384eafb24b39c650dc593a92622173f8aa652f79255391a53c45669424f0643f67eb053b587d64160168b759fe0d8c41adbecca2dbcdeeaa58a057e6bd532130b4e0a46a2451e2abb6c252abe6f2610622c49d98c4182b9a20f389eced39839d3b84aa13ddd078e60ef5051e69e7378e443cbfa1e15e54c75b79aa0d51eb4ffa9c5a4bb29394c70699a4cdfb5c1b83a47bc0ae888fb6b8221a720dd06af57a48fb10fc4f0941f4a92dce1053d5f91a991f90d80af9434fd2ca960736ba25835ccb5043ace0db204201de6bc3b75cc47ecb98c2b71e57f8d6b2856f09d9dfd24f866c0efe0ceb0659c4b70e8fb0e3a62bdd85bad37158e65a77e1872861b534b337fdc7e7a1dda3378836bb606d5a3af953784b81cd07af1e507883a09eb847e7067bcd352b0a168b0eb4dd5d17fc59f0bc3ee76f465192cb68bc12746aa329538c0c759c41c8dd5c4221e751bea895e5f154312a836b7d3adb83d59ccba9bc761080f289fd149871dbc3da13f7378f25d3b35c5aefbfb6373c5c99f5216078dfce80eb34721bc66f47583b2a7690e7e05ea17f523e3fc55145df65ae2e08c3609d5811b99c8018daae44705145edb04c4797cbba36839da92c073b2ca4da54964d5f386703276d443dbcc28357c8b2c9e3ca9884f278b6218ed96e5c83248c25e3e0a66a0bd1ed9a5c1b7181a921295e934e57a02f3add089d19d8b509f6074a2c8b282fe311e4fc8537084846210ab9887275ad5bb1fe4cba349d0ea028b35c9aba3af23fa62480a4b9a9b896f04e8ba344ff0cb007b1f1a79cb1b6852c47ac4bd99976305b006e54c55c31fbc71c5c4730d1874d9214157e6d073cbdee63db21a655d46d59af61287ac85cc9b79937c019bb69675db9cf19355bbd02aab2d12dff5e43b93c668d22e10d1bc78e5755b6bf5413dcf7e62e89d1bdb39cbbcd685f0bb56bdf2a7a29d66a170e4dbc88424649330451dfed16797613cbf14baa029e19ba37d70f8736cd5496bd1a0660b3f0043ad488251bc3c201a3f6fd856383e6c4917f9d0d6f841e62cfc4932f73f04f2a33119565349a89f77cc4efd5ce8952a64ad771a52921c27b1ce67bd1cc72f19ea21ce7ef5be2e7e3a38e38c1fc1118e8646573bae915c974221e4cbb6a7b51142ea37147bc44a6321a490c0903af86cbe90cdabda786c634f7bdd5d4df593fa8709c2b1e190b749840ad5018170a591657462e02934e0623188b69ab1e758026d823e88826c43702e8925649ddffe12b3888dd05f540aaba1e67739a474324ec9f52a6686f1329818b013b2b99bb10687ab0d61e68dd99f68a57bbbd65faabb4f285871774545dacc0341becbc4b2fd3ecdac4d642bb5c3652def34335c23d4572384056919df71a15a28f68758caa99f96af3e2c853100a16954c43698b8b802b860162f0ee1b3abb2e2d0787ee8bd18567001db6ddd6c05ba1179afba924acfee1d126635876a9ab378575de4fb4e6644dcc269c50d3478b6ae439ff9849b7f835d16f48f745ef6ec81185f6dc2013bc916e0c4d7d743a93c6fac44c5e6ae9a56fce59c7fedb63d37a391dbc3846f4969cce4c9f64318e8a5f63335eb51ac70a4ddf4deb986556ea2991c6c8116085252793781453327c4022655252d76d0bfc9b6c5916f1587e83f16aa12b3ad59dde9af184b78f79eccc561b85b711a4cc89e0d14fde2c645ac457b2f9a42572b98790410c9b90fc42dbd47008a73f74a055529a2cca9e682c0b4c78325a166536b7ad290350996542a7eb828c26580123020b47423227f35dd85388c22f0239f0109ffa3f2d4863a1175a0b6257575c7274af3a50a26d7ee6ec29b1c16b2c1a8f41b88a123d09ceee715474b676ac84833ad9b619455bf08a2da3b20de002f53f71eaf7eccdd0cccf6a82dcfaae3ea83237d0e0879f6e6a7aeae0b5ccd9e31b6cb99d98c44d76326a985553eb73cb500888dec778216bb2a301881693b14d62998cc90bca8a33c54c6794ba8a518c21c9672a5389d29486ae0d7cf5ef8e7b4cb35f308e3a0724c67546ae33a501ec0b4fdc4da1f69e1f4b0e3a24f83a57688633f7ea6f89f7194ca6092bc945948ae3cf302a50e029d4badd942e35daf60115ad29f42c51cc7745e70626d8dce67222f10db7d09eb0aa6bddbac5d539868e5d8076c0ad56c0da8d721a6a2113453f4ce064c1600a279debec2a8a13253f3e10afa34b2940db8f175a0ac606d9ff8a6c2ec5898dce66c6686678663a501bd68e937d77ad2198110e8130bad83b1b4861164fd5151bb3505aeac7dc7d2966134634c2c184ca008cb1504697b2d0215823c5f140960167ca6c426ec890d6441bc513a05c46639bf396185b1b603a115ce955244a97f028308f16a405d038d5007d586aa840063d008ab54e318470d3725ae3fd64786bff47c35e4c9807fe5c0d0869b6205fc72445d271493bcb45a7d3b1940d408cfccef9ff61c52bc0ca6e8fceebdf82390c47e07b74eeaebbdd4b665d79b45e617cf13ea0e55fff3e3714136896b61201e9b8f73025c781370268809610bc57a8cb6d9c4e99ca641ee597b07ea65d54e81c3d795bad26a4918d4b141a300dad8e040c39cfdef361be6f73bd9394e2abfdfd7d664b6a27acfb68ea6fdbcc08dc2e04a46e401d969950501d20c76b62c6c3cbbd2516937b45d45877d5e75ec19e2dacb3f8bc9a81c5396c3d425ac7deef4d58ce21be3d41b5f99940c9f6f6063bc674ecce8948aedfe8215f188b5e01d60f785fc58c6d3bec41ff65f12e9d67cb1409803fe5c7b60439b0e6916379a524d64427df7422c0c4c573ca62f702cc4ac786e675f93b250be339ffc688d56e25454172fc74982d4d9e2ec4d773b9c82539dff1bdf49b8c2e5f478b1f30cb029efa3f1a332683d4672b55e10da418c95736a30e35271b4e9eecf4099c7754de6cf11706133948cde18d549800b37238201d1f67aa595cc60b9cf12f7097e5c8b665d6de02022e8de2748a5922aa8dbc0aaaa54206201859c31e78b78cf13c8d8b62290bd18cd2b150c4019927b254504857c5b8b312c43ad00cb691573c7ef427d155fffcd904f951906d34156daca39169f363041dba6c31936e2ee8e4b9c8e5a4253edeb5ce063b3a4ac260e79c11dfcf325137b832836490ef55bbf7ead77b254cbf17902832dd636f42cd593c1e4b7434690188bf2ca23c9ad32b02ffa2aaf0df9860405337d752fe0c30d51e73f22954a3e13f20093414c298b76c6d0896eff662f84a450378ffe0f8fec55d4fba2e623e3deea98154a2e6bb0232cb7cf2f541c59e4d6187d5b091bb79a806cd616dbde6c80face2044f60271d6b8489c9517e8d53da1aea6a4e177b75aa1652f6586b75830fe4eb542cf343d1b5f6645ddc55dd83fdc7acf54b90cc72292231941021612697795c94f1e8c9a0de6e7750b1dfa25217b139301bc33c2ba80555819a76bf760d8cba12ea714da7cb235b75059d4296d0b8723b73196207a206d0ba48c516035a23fc791acf658fa95cd16e0fa7f9221d43baef5019e6d224eac9ca284140cfa35276d2ecbad9daaaa5a9c18640456a9a3df8ff20ec9701fe02e6165a34ab168dfa8409e4caae49918de4758eb01543b7918bf4658ace5f3936d9c18779765dc8bcc315d20f2a47722b784a93fbec1d0fde5e48efa06e563fe9c9d61decd516ee950b665d1051cbdc9126c0e8bdd874b86a4898db1c03b5783c1b1e69bfde377c5415b0dbb46b6fa30bdb462907063667fafb7995028a19f846bcf8c7324a9ad9f0c3d3b6c8861f9e19dbdd9ff26c1e4c003c894672986597ddc9f043d11d26d9b03b7afce73f3ffa2efa7e7f7ff8e7478f0e1e3ffef3b7dfef3ffed3c1c1b78f1e7f3b1effe9bffeeb603c197df7a84bd9cf0a6c5be4a32ee4c3e7632115223ad1f281b53caf695d8b253e7ada228188a72050df6d3085db5b9e29e9594d8367a6816f246033ff307b924bb92a9e7af935613887bcc6b36a8d6796e801065d0a6050d0c4242cf4ba1fd4e440e250dcab056cacd0a1ae868129569f9ec5e7a09e7c40983fd35fcf710decef56f5aac0732205ce05bb591df3f1e64d5bacacc1f8bf01d5ddc0daaffc85c7c8358f147af64557602df5d72a2072386d2065c40afe5c85e50e753936ccf80dede02659a87b16b307aec92cee933023eb238b6c594b4d5544a2dc2c2e8cad9d3da6b1eb37de0b486d28a1b830dd9d90d547df210460893723b9a00b10bf8b0863c9ca58af57aef3f476e050a9776f0b9c1895b7a6ca392afaecc80d3db47941b8f840abd9fdb453ce302a08810c6648e2130e666468009f32352578d44dccc8c89627983130b0ee21860291ad6700a21c600a6aed83ed214ad138fe4a1a7831c963998e9315c40c05863696c3e5744aca184df894ef86d4f13063ef851cbea5fc87f72edef43f0621f86fe62d0a1b6424191d3408e836cb4a2560be7cae077581913bd352e669949847cddddd75c59d0b06480fe4132101f66ac1fc140f655e0303ca0c0098a3b590783921a53ce880916d262b31cfc6f1249663923af0ce424f9a51baba26f724f18d28321195d9bc8322136e9871b3a5df68d06cb3582690a267254b11a51968a5cd4be6c05a6508ff3e0b6fdd8eaec209be63e731c9f29144d5831eec5e5414f1943f3f76c46f9262725e475a935e6662142d0b753d4ab26cc1e63596a51c811d5921c50859c1c6c156152566c460da17e7522c17861f0b8d034d7a96c780cd3eb075f0b4d36c9df6cd7af66cc23f1baf1893beb439d8b16e476cfbb5c560e72be67c6449579574f4d3f960a755c95f2becc3a33f2af71afc6be75947fc5596a51a2fdc49bf19ca49964b01cabd389d7e23e6324a0b5c9a88bd7af04d3f8b0a51c4637899875790664141a27399c82b585a5900c5cde362d4f950b4d82020ccca328dc77136874746c08c588277fc7049f958918a46599ecb5199ac400d28a261b62c75e259712d4d9a6c111562592ca3c4bbb57ff5a7ef45579c28f1f4abefbe33bc3fb4782c29a4735b43d1a06330f15b9c2438c2ea33446ddd2652dfe9f1f3e31ed887c14b34b47be29e4908e2cc53c79e838c8322876b3bf172a2f0006e3346771b118e16590c296c03c3014d60c457117621d8cec1639179edca2c60a7639c0be6f8c7ee20d8d613713a9329675b1833d35f422926f05c31d383650c6b162d16327d822bf85fdf3addfe9c5d4b78f958c86c914811254526464914cf110c9a8e2004315e824cb14c63a4c8a2d319386608b3a878a15dbeeddd2728a2f8ec06172acc706c8431fd1f6c4f5a5b879f9eb76cb661e643c9f8294a95d8d605ca46cf2543148b3c7fa1fb4e8171793e07dd65cbca8feab4cf0ad9f422d0b992d1c0a66d340de10ffe5e6f6c8f5c69f9acf29071ae23e26bd908ce98dcb26dde9c3fe0bb25aebcced4106ff8559fbd765ab64e65d62c966d31dab5ccee2954ecb2ee2d2f1a846236dd1072b41c525ba3b266aa7a95e7789b6293c85cab6ae437220d68a3ae91c71daa513b8e65224b09a06ac2a9d46a1f05d7408e6551e6d98a19ae392a40102c6c89ab0114552fb8b64311cfe3f1eb3a72d0653e2dd4e3d857f75aa9a4b677dcd435dd63e117ef1f99b9d9db952104cb9bc65600cd06e00ab8c52ea937127794a72f4b51483937b28d6fca1791e0c1ccb60b51e6f1742a733916d733ca868f299395cc935fc97c4f1da12d25b04b63203e37d62c4c4fab8e687a61e0beab0c0a0bcc0277b9258ad360b2be826e8d182c9a51a11d3f2818554b5feb985d1fb601afd40a3eaba112dd6ee3f0cd449dcff21fcb28698b382d16106773b882bcf8b8209a67922b8d245b4aeaecc3b22845030e970648a06d11a5dad2128ce0ede9f81e258ac2baae74bb62a6cf7f34144ae391ccd55893782247ab5122715b17e40da0572f892f254a88095d9dc0000284488607148a6ba6ae2f651d8b691d1ec151f9da0b0f377f31faa9c38a82caba6b545e113d474f7861fb394b82efc640e70ac285bd60d8103c839d0bd6da180e80316699cd3f19a86d4c301dbdd754964fcb6ceedd53e0b8717a3de7861a816b9d53b94dc613009986a8ee7226781260adceab3ad039d73a6f7e73c5a9eb800cdbba47d8ec31f5be32842d2697d0bd9e2c1fc6cd4a2471988d4b16e71bfd6aae3c1d1f2e48550cc4440015e2f6fb6b8b2bd7ba35b4826e1bd5e4707d034fede0cbd4b5b8323a90fbc1f704de6a88e47b4eaa22f932f9521bb2d855e96a4fa42c0f59d71963ac289fee8363c441f55d5195e920c2946ad3bea4571e16d1403305db2a6bd06b0c2fa34244365a911381d58d62ab7a6d714762e7624886a8621e7dc87253c51eb1a994e3c23146057adcc6e887fb7c6e6723e45cf11d51a101ee641acb3d329bd1bfd525180dd6b455650cde98005a8ec97ff3bbcea38e785748f1fe2f640ca9d621cbe5fe60071c5bd5df076a4dfe62001f39265eef45966b17b4bac64d430a9e8159ebbd763353c2cc7bd347f32c0c895f3cb1f7468563c25a3062a3e5d31138a2c2a15ace96b6b083b389e15de2aeb3a3bcab71d8752c0ac9c906c36201693639f883569d37bedb2b9a07eeb39720b7bc62f9e86b6742de8a96bcfe5ef1565c165234748506c87cbec9b176d09f458568e06c1b46e444b7180681f47af05df5a15b04f6b3373596c2bfdf07c1aeea5db6ddf4509fe44e8b422173a81d4a305f5e67221acd6279857f678b4556c4a514d32c4a0a90139992686802c54cc115da4c0cccde2027abb62f13b99c14224ecb4cbcff4133881fdfbbfe3a28ac6a0f6c4ceaca3c89da6228514f6d5daee33495fa910dd708d9599981ef34068e6c1370ed126d8de5c4cfd9d18005400fdbd2f13b322c906b0e078b146ce9be313a7a6d6fc573ab2771559fac5135a465f548214c2cb4b96936e1b3bd8ec8ec5f30284c2d3acef80260d2ae82120681153b1b4d99a10ad1aeef134fca0b9916eaa5b783aa383b1aa3606e20eccb5c80ee8b0bba78755c779c63639b4dc10dc3a95eb4bf9d9d14b12e16b5c28e2614718791bb71370a5cf27b447f2f2744b9a6ca7059eac070703326ba8d48790b8e9c5cefaf2919f5d7e88de7d48d9625aaf4d52d6b500dedeff3d8804568f381479b36c4c0edada82dd431e7405eadb06a582fec53955bc603c9438dbfa67fa03afb678436d817a59c2f8c2acb8699943957649a23a709f5459fdaa3236fc0957783332f77e7352309e6553360b09a4b7361df5cfcea2615d2d4b9c90dd6777925587e842b22e2a092ce712ed5933b63a3ae732eddcebdd4dadbbb5461ae0d6dc1efeb8e3f6150a17dde0a78cdc2b0f5c664be741abb9edb9b37963a9f742cc5d0840467e44680f027c54a4d131eb8b3ba7f166e659e8d333050564a7bc12c6aadeb5e6583d489789e38e8e63163f2ca831a91b27a209170b400e684c96ddca72d2b9b787291cd1018c49a65496e1946ff8b6fe2f495d6478185a28ec745396b02b2e47f03deccc5905d56d66888063b40b67aec6b6b822e50d7acbc74633d2b09a84ace37c7eddcb7e00a5a59f12de65bee7851cf2a48f48cb8d62014477236d8a928d5f1ba137a7af14a8c1a7cb0731eca5ae69a878a7afbd14373d737a44a380ceabb5bae197db8127bce02cd6ab856c0500ecedd75809544b70568f7ea87a21a28b88d09bd7fc1af5c0fe0521c04fe1edec153166a054885ef52c8be80f2f650cea2ab38cbe1826b5ba88b013efb26eaf60bd2bb89d98fc62f4547bcd6be92f17c81a29aba9cbc2f8edebdf7ae154a040585bf4ce90a639f11b88e7ee0f95bb1cd6b040076ace77272c054b9e02d9a43e40b28eae80fe680cb1c5586a98717b9f6c079e432a54c9677aeb5900c8b7abcbd15ce460f896821eb7477d31b6705ce9add31fb4d0cf426135ed7e98b10b2474ee60a4777fe7ea7d3e9fe8886f022c9d2a9ccad39bcb921c3d50d3149deea321d2559e198d36b150ae79338152ede9186c69babef51b1cd65c1838d77065016b620601376d0f163dbe802309973890fce6610ef38c7ae96ea18fd9091f43e891cd0eeb4cca35f745e5922154d5ee02967e53548eb61cbaa24b760f124023702a796ee788d0ff086a4216d8a65b8049b32da108a83d03e8a531bf4ac8cc1f33d906ea1a243d9622eb7b79f3817ded7174a89c2b394e93cbd9f971a458f5ee722c413de50301742291e026682af52263e60d3d2842a68e05a9b7e942d5639f0ffe6a8250e1eed7fbbb7c86501fbe927326e6f8b97e9087cf3a1c9299a902df39114a36c0c69159378245375f62c499f23c5eb97a7fab39864cb949c6bc00f50bc7a79f4e2d7b72fc484de8541579465a518c7396805571820c6f654e65276aafe288e88e2d80374bb42ddd6aa16b4d3e76f7f3a01c747e473a2580ef7408287f463da791ae5876a6b593e97797c25c7a038f829cfe6e8ff5fb9090108eb49c1de939709a8a6ec17735230795c41c024cfb2c94055acf43d0bb5918caf248ec88f8cf1e9180167588a68a8c7d4a2c7ee9c859bc619c5a81529235cdb91cccb284e851c4f2584734498d6390ac13417b9bc729fd93f6d2198258405e95e93b65a0bf184bef69ce31ab0f12c46d3c7c18e1ad76047ed8178ae7017a5250684c4873f6db6604e5598bbbbba8400662a1b888fea88e21b4d3ebca8dc0a0ffa5a6ae9f4d0adf096631a66ce2da616d4dc8dfa21586dc12c2578e1856bd2fd368d16c52c2b7f4a22cf74745d6d3daea92cf5a767a0a5275c6889ceccb4cdbfc098f083169e3c133f678e0648688e069eb31dbb5db28099478eb1e6e8b7d7ddd16f6f4ebaa3dfde091db67e2815edd847304c7af8743c16919828b4d05684b01668c24db1200a0afca9f8e2428ee228811dd519a45546d8b9b8d040d853de6f08c862be967f7c4a7bb2badcae25772ba4b4a656fdf3f5d7fb4c68b26a83bee055ac3e815f1c5dbda755746a6d664547e86b3f1a47518a76467a6046a3ab6d921a15318640a198e20cb28e5501bf61f94377771d1876e03554efb5578d7d518e8f830f1895da6ac6567e7f7af212cd768c125ddd618a6822073bd646a810d7e08530c4cc0040bd000fcd69e309585c6178b742f27690bf96840bcd47e95da89cc995b8868be475965f8a713c99c85ca665b21243595e4b990ab01400713395d73217cdfdc79d6f1fb6c495cc315e0b64d08c281b2a04c6576287d90f740330bcdca9c1097f6d45c4bc5fc5156369d5aa5b12330a9b056371fa03036d54db37b8ae22d8e7bb5fdf3efde9c5c5e7765d0ba6618fc1cd73e648ddd87f60051ab5d03e0d119f3d9e4d40ef851dada3da300e87e01a01089f868b4feabd1e9037f35ada7a603d9e37e1bbbe2a1b94aee4f03e477943637718b2f768e094a53a9e9e0915f9741123102d52dc8bc7f72b3c1aff7b221ab5226c8bd5eb41bda0d0d36a98e7143cc1e85a4b6d1bef80798b444ea3d1cae1e031649d664c1ce40a66718bbabbeaf9d0190cd2c1206d88877684deedd61634c4b29085702a337c3a3587cb92fc51b2545d170a7aa45642b41a4a65123d076c731dad3d118d81aada100f4334d9138d462b0cac962807ec912c08de6fc91bace93040da61f8ac62055c0317e9742695147ae51cc2d65c0db586e38e782595bc0ae162999318499c60d5dbf397bca17de127c3ce5c7631104c54acd2d19ea1863dd3ebde2ccb2e8b8623801b3104c5e61ffa62ff71e700ded4794c0e6d315eb755b4f0f1b41011880e51ae30d4461dd56faf415e500238daa15d6597788d55944da0cd3035ac5f41bca88815b86be2690ad9cd7de1269e08bc46cb9bb828715c8c197f0aafb08f266b458a800ee4706d3bf718ac5720dc6fa16a98d486057a1758974f5c90a86486ec6a39de3e7b57b31a9b25eb9a95587faa9bc7304f3067cf40957756bba58ea254e1d3dc386ab9becfab61eaa49a45d13deca642aa7b337073c8546c1737482c216d8463d711c0487f2dc20ed7f4cc61acf1c339d157c82d5401e6cb3c5a0da5c632f127e7cd0eee18f6bc943772b42ca5c896397cdc23870fbcd91fb2862fb50727be9f175a8f0176178ae8c7f158b72e67d9723aebb0d6c770d731144f5ee1ff58c639f6ad8904722fd86100700ee737661416a5e3448a6156ce500b87892e4791bacc816b09788cb0fc24eaa686a95b063b2ea27678244c7d87530d1577f8be736347cefc4ac13c6ab0a3168112590c7628eb8637649403fc810d766a7443e1e14c65b967b08e23a03b7104f6eaab2ab6de661e0ee4cd2289477129d6e9b0b4c6662c4b99cfd5eed36fad063628323d4dd61a905c485c57970b89ce02312b9bea46e1b605768fb0cd61865a098fc95e513cc58279c825b51430e85fe4ca263f318f12c6a1038c93ccaf5c4e742e8c3bf332a743172bd9db33fc5a63f4650dbe74fb90c99701a02b35fdb0bd7e9c99431bd43f640ca6e15823a7ad5322f8b6600694bb58cef0f4ea5c38eac98fdad47b942d56180f55cfebc27f9608642ea045760ccb2c12b56959d8ac6cb34999a61da2854e9692a51bc5b8d044e279450ab7dba92c0182e12235fd7bf57c7b5572470094a1653e108d71a8b03bc820b226b43e85972dd022371a8f45769d6e8443aba29b7a386266783c4b911b7afccec1d3796581ea04cd7528bbc7a38ae708c5de9baa31198d6ad634ae841157c87badd8987b01890bc8eb104da71099f94a7a511f78f0323b84ce244e4a9937e17df7ad09face4399f186765ceb1bb602e6fbff6d767e4f9ce21399400111dd8188d06651412ea8d6b0027d37e1ab9a2ad5a4545f589925155314134d4162c8449424c29a06b40ec34bd1d18a78f2ec82099126be55c976518da5af21bad880fc166277d7d202bedb6b6fd913f634be1e5f270e9228e6bd1a0d46bbafc7592e174934fa5248bbf3769fffca451bace59adee969a8f3afe99d2fbaccb73a05bc6e9f77cc82619cecdeb0e0e503a4c771357d94654b933c9bb74599f1b8bbea1b8ba03048ab3952b00abb210588a525ca4ce73d51f5cf781663f7a933446a1f19d61ff82206c2dddd85f1a0afc51aaa07331a663c750997c8aae9947992728f75737254dd7d2930c4716a4c25bd94ddf9327d8e75f2e2380dc4b3a8896867dd4c75cf4ef65130b6f33b576c135eb014372a338a5c4d21b90af4d967a65b745b294abcb360264676571cd4d8d4b8a30a5880aaedf78b5c1de73a9364cb7d98ce1636e275a5aee791299e2076ce2a15cf45afdada09be013d55f24f9baf5ee669cf2c29e0c1c3f8e386c0b395958165b9cef24b881aae8116a2588e66e017a86984f08d510274cc96a20dbe22f93285bc941d8f8dd9bb6eb6687ae9170fab2ba65303b85bd01fb2e3c22df372155ad1aa7b6bb8b6ff4419acd599470b6e479c56a5c8da414e52dfcfa762546c760257cdad3186bfcf82e24b319ae27a51318a4ec08590d159050d9a9de90de0daf4d5550fd0e9674c89527e41287775c5559cc5646731fe6a8af73a59563a8e53a1128a9dba5d2b745e4b0c69972f53d1a4918c5bda4f0d4895875db4caa7a8788a7e9daf29ba84e88b07b4c296c4cd1b2e8a1826adb2dd03b7b7dadcdbdb183801f886a9a9c3140d926b792da34b2f00986734c038bec22ae8ebb2546aefd4909746758eae293d7352a8b3d6af3d75d8f2988008d2701f815152e20977598e44aad883755cfe2432de8a0338c20120856dd42a395b6ad68ab282761f79e6e9e43e489600b058acb60505a93f6a21d1dc978aa90c137931c44cd0a86fa93aebb54ce40bd924c90679fb5bd56a9928c1b80616593783f35c6a0298995007f8c9b24b42b01739354b9bc82351145433306eab17af8f9ffdf7c5f3177f3b3d3e7ef5f6e2afaf8e9f3d7d75f1f3f1f12fe4d4ece7f5707ff78c79ec5a48ad16c1d211ae990004a8ee6b122916ab9efa9f8e0c7253e691cd9e2bf0c63a5c4e95acd8737ef1a3ef9003a70884960879a4ab9ef7db8f6aef86d1ead515ac6b2637b7f302e1f7fc0f03e607b416d1e4f1f05a4fbb69108039cb8da5a1bc81579c8f82f9b559c3e3a850971dfd9dc8accd722959cf5d0f7db54963a2a2163bb58dda3e1eda81a8f85611a7d3ddb6abe79b42de4e7b076d36c585bc2965aa93f50d76fe328c8632e9e6cbb48ce7b23b835c29455716f32ed5845b04b566895aa07de32fb92cca282fbb74f7ebda1a0ddb8c56e1a39a025dec603aafe53c1377040a38438376fce94cce7555419eebe414a1755c1f0d7b38cad2623907ef16deaea3bf13a5590dab5b8ddd6d996008558cbe94b2cc0c8c919e9cc437703355251dfddbe65271dd768cba8f79dc2c62393eb170081da108db5a75490bd2fc78d73623a093ad2dcef497f3aa5f89e74e6289e6a3a31b73c74470b9a2926f1f9ef1e15996954599470b6cdbc4a1b4857104553fc3e8b314d1e48be2cc01ab2bd945373c73208358e37ca91a150302cc38cdb66a32a79a6c5116d57039ea2bbe91e299de68d127fb64ad7aecc1579703c705689557dc2687b985eeee06637afaa69b87c62dbfc173d0460993be6c28b96b1d3a191ce2f0b65bcec0037f6205cb0b9a82fa87bf192a34f7b19468da94c2c7afedf67e5a989afca3a91faae935eff70528b81e892716574f14279834444f342070c61bfc516dcf29249c212a979303c5a527958b388c886f2774bbe36fb38be28cf786b14427b018b248e2b4dc1bc785125bf6527953ee25712a51b8e9aac67b90108b3f140f8b138ddfe08ec9164547d7d1dbdb7bbb08ed6546bf1e7f000db6111e34e89ef94bdf1b0d07a1bacc62ac27063b66a44dcc916e49b6ceb48c02b73f14839dd66067e0e4bf31676fdd866c5b6e1e15864fe307b5b30800ed76974b1f7ea963ee0265b5dfe272962d4b9b04f6559615720b90eb9af37ee0d284790bf10c840f106ccb3f3dfd4392ca3e0688c99ca89dae831e7db63e7ff1b797472f2edebefcff5ebc5577bfc64dd2688b463255ff9f8fd5ff8bb9faff4dd13837476c628e61b6d9d064055fddc91e83c59a14839da818ece8f8caa05e8220aacb51899ff09aa1f85854428660605645b94ae4788fd97db03c24688035d453aefca6e45adf7effe7ef9d97d35c4e382ff0b6241cd266fb99535caf8f39c6f507cb167339f93a328240641920770535b538cb6b8ce32b606d58d8e6fa2c64996bc888267436d831fb19ddd5f508f1a7c2bfd1e5dba337cc842cfb698cb2a4617d5b8b45949ad49a24bfa0cf94fdc8a92aa01c1de69727599c961556fc37b012e913cbd5d57470428cdd5b53a887d616d96452487584e7d65dd92a43b18b07d6058a5de0a97b75be23ba1b7eac1f53eb6bd5178d143e74d407a391a4d24a7dbee4103cb4e7d73120701a4e17f8c9d6c851806515721b94c98f79e60fd8377ec2d41e480f1ab968d0755334e0c2bb074cdf94f544a3c1024001fc075aa50c5482ca23337398b002440ea7407c0fa9d35ecdf787a66305a7c53ac4e99b1eb5e31ef439d8815268e7c38112071062ba16121487414151288803ce5f3f9e9a4bbd418a3ed321d37612c5296eb341c5e0e4d3cf79b02c518c81eee49a19f4d8514351779026dbe2cc949cebc0ad30e6b6c649ab855335fee64759e2b99a378eb2a4513d9c8fb2e43ff948d617da284986d1e8b27a91a5ca4f878ac98eca5fa3ab97a59c9bc3d9fbee9cea4aa0870826bfc8153bcfdfca448e405946f7a4cf1405bc383efa648ca3b444575020240cfec1d38592e83ba66fa85e53005fc545f9d73c5b2e60a60189e1334f640ae1ab4f5bf8650af5a874b1fe7d9ff39c66af2bd04fa7ff2ce5fd67361247500c907a15a948ffb6f13bd2a32486380c504e3fbf8c348008c2bf3536827202cdd3b6ca522b40a87ff5b0f1170d92c916ebaf374cb248e2a2dc9b2a12d98b15d55b2903cd363532d8ce624403c3705ee0f5b478f6ac2bbc51c3bfcf91c4599c5f2c2eca6c71420613719656422687829cd2b45b7acd6838460563084e57d8ac8bf19800e7ee2e4ba73e5c7eaf57a5e7308ca6a131acde99c12e5b73734568447351d153a47c7b2b9a44ee4f181c25b846703d1f2ecb324be14f25c9b6a8394dbdc7d773dd79d4b49b50583aa18dbebb2b1af867a36df7b7faaa7f34da66cfeeee5a32b407b6dec27aef566a6972f7cf398797f921cff8cf6a5df774740a03e7a453fe9f7c62d61c90dafc0d4be9977fb2bd4b47595ae6195882eb636d693e2a5af88cc3b07a54878e6956d33de874ddca4a6f7fc8ceb23cfe67969651d223b7abca99bafe3c25cee01ea8173ee6fa3e2e9b2e47c1cd062ca591a5286fa088da0a1fa31eb8c091ca0f75bf76e58067e7af5fd73f8b2dc642b56da9bdab7b75e8deeeb7648777b042fd45be5a912757a7af27db1de81e2c38dcbd43db3deb9d23dcce3ea007f884b39a1fd306f4dfb0477607b265e638ae54177d67e5ec25b1613f37e06e687f2327b7bf0381ec42fdf8b1c71679369245d191e955e7d7e3e72f2e5efcfa377ab05fe4d978a963303dd12ca9f9804d499d1c863cc1eb295916b346ab2d1aefe97b7fb0031f073b186feebd6ded878f73a252771a2dd12382ba87c4b0515af0a8ceee7238e2ef7f2a6f79d256d722dca052aff608def6f8ad3d7a1b4e2dba9db8076ffdb9fcffe099fca56e9369f6d76559cabca85c15df64d79f70a031dee5bd99684e6b7a3455cc177b124001f27fac53a7b8b515831c5f1707cf46f2f4a81c88905975bb63807050b9d89929b9b7347640385a5f326392e367dbb2fe3cbb6e6cbcbc049552414664a76c53e26c623b9541b7d9daaa2b409aed4df167c3671c6fb26b9f15bcc9ae1bba642d33f1b8c09bec5aedffffe361e448171e3efe1af6f46bb0bd064bfeb280974f300e6b229bd88b3126d08022dbac8cf760b2a2700aefed23e87bb1a2440fd90282a9428685545e8bb1bc9249b69843fc56ee48d8ed42067ae3746f81edc5e99e1aac1e2298b41da7cf01094f476a7a4e50e46cbc4c640757d49948a73b89006d6ae39dae1612dcdb80949a34ef4e5c10a1b743fd00ad3111e4733061f1ff2988d876966a0e713a7d3b8be76a9af428fbc7d9f64534a5f6603b8af2f1cbf9f48ff7d24fd0af7ece736a3c9ffedecfa9ae9af453df56a37cbca706fb25ced7b532bc46f613fbc2e6c9eae04c82e332ed5a5cd5c89e7d90ac2b4f3ff8b9c16bdce778a546ffc922363d1485ad1d3f4f6185f4a2466b243bdda45ac4da8de32b55726436ac6ee517b0366aa5b449a6aecebe79351507e4b58846c00025be7a0b2ceb69f1f3f78a40bc3e9b8dd9f78d56a0f2e370e5c7a6b2eae859365e897e00334ddc79c36cbc320d426c5d55a8dc5614e4dfe13d6b0b8e399c9ad653f391ec62e13398d39adada42005bc02f56385ed9a2f16aa3b9eaff153397e114ff252779f5858c01f0ef31bd5b5987d8cf65e04c213662fb621b3b5ef34ea51afe2ca3b1cc9f19eb3ccea86750862674263485b1f4ddfcb6c43667a7d6e6d7d621f09f77d15bdcef8ea70f9fe154dde8d44292c5c9b48d340e5fd55ff81d4dc789c8b105fc4dadd0ce83d4d548ee4f6a51a318854ebf65ac9c45cffeed1c7da173af61cad69e78500525427ddad1c7d3b84ce43a6655aa0a0dc2a759859ecb42f928df2e87e526a005d5d900f731874b5c55e34d7f7e15a797ebba4ae2f432d04d236a70e0a7b875eab1a08e970094850305b7d23a38b8a11aa6c54f5956ae6f31811ab6c5cbf9f4f84ae649b4f68889e7d3bd0cab41d380c8a3e41dc53cf29f578b1930deee5eb3d3ea4eabd5ad117b349749fc4fd9444b74d7f109bf753058806c125c9e58ee4291795e49b631cb3b65f66eb190f9516472fda3c5ee7fa64ca6d14875c6d97c4f77a68b7ea78b248a128ba818458942367768b35fd5f256d6f6ecd1b9bb4ce2a1430fad4e91c423d9dcb7ce6eb56454255bcd863157177b3ecce5441dd1989e8e9fea1fefc0014ece17ae8ce072496d86a33f71531daf9adb9277c5304326745a9a084186025f28e9d803ac566e397272da84c5972a188ff3e3845df6af91f9ace07d067503f7f02c707201863d1d7ce1f220205d0a5f463da80aa988d4032bff1d70015088d3488ba80715e9cf4eb9676ab0a6db0b81079b5f401d790e5190cb224baeb453d326c96e6baf8bd3685a95842a97f22de41f777c2d92f4f8dddbb8f633f2d9206f78759dadc67e71f19135f8cf65fcff0a9de02459c655b3c8238cf40bb2c697be42428fba147efc9eb7b62d2eac9f75b183096cf7a8b5b52b03e19e3b342c27d8943c010887cccb8f59bf63614f34f6e0afc6977b15bbe765090752b5a6a7d9e8cb63d55e9b1050b5dad698716bdd4b7da79b2981b6b12c2408a2b8b5b8ffe54c8e2e9f1fbd30298bbe11d3241b4689b8b878f3e2e9d1699d1f3e26bead249dd8d00a56d238eb374c5cf5ad5a77f46037279d7043c1dfe77d0dd324cee2420cf3281dcd445c8865aab8d24c1dfd268d38bce81934ea484718c9dcc08953f68284c14e313a473a8e753b30b281c671ca5fde3a6c3432c774f01407c58e0c8325a9f2b618cb688ccf983289e7711a616493a8481ba58185712e921564968f297306943c07ef548a5da67a99cba288a6b243ecf9b9bc3acdb2a410b94c62096166e2b2239e264566dd5c0d340cba8a104c96ea6c345ae6f03277ad868ccfa50c8d6d91e5260e14a0d9c0c380a952404af9f84ac74cad644df99f8bffb169519c2444ddaef89bcce3c90a8315e33a8c7578f2595488a19469008b722c9acf8f5e34c62dea744b2a6dea3f74909311c4b46aca3ce7b466f08a6648b0087954ccb48a3a55e82dd575f87a1631aaf84d6ac32524821cc21d40b62b7583b996e4690c185613a2a63a181e04e480c154c29c04f74b3fbc5fd40c8e5e50d05a1ad02c5a2c642a8648b4308fe7c7afc57009e17f298071218a0c964243d1781845a99ecc301a8b799cc69318f3f7e817388ca900117e20aeabe6611bdf96471f0a7a681b67f38e9d4d671ea79d0ff87acedf8eb787c577ae06046fb875b73d1321168fdd62393cc2e4d9c552dd25596a645dd4e1298828aa1e9e704ddbc656a2c84195c63c8599e89b0a6eed8b0ba8af58361b902b827e146fb22504d8b8b8c0bf4c0c89b922f593a89cb9ef2a7b395463a6d6dfd4146b39d541928e6d512f973ad5b79630c9e739cfae0b99ff1c1765060140e0ebcf5131f33ebda2fc9a666e332c67304da412aa612f88b5e6d5659caef6aa36d6ae9cbf6eee54b1712f297f1dc075ad592f71aadf2cd944ccc78693ebf17426c562394ce291787af212c23846e207249e1f913143be8e9f4f5fbffa5e105eadb10cdcd67199b0cdfaa0ccb0ea5fd78666c68de7c06b8b4a233f54b353bfb92642b389517991801ed124d227574448ad8ff9ecae0546ab53355b6d71015959c5a343fceb0780803f1e3e64fe34aafdd90585b434e0f18bef2663e2407bf383e8cee47ae897b5c5996a65fc0f557fad166442d5c19a75ec675a2aa37c753753f3c2861bde14f759fbf69699e8bbc8ae645ac36a810ce77ed8e7359702bdee06a934939ee0f3aa3cc8f544206634a13c9823dd9909446bc5d17884b6565c75ada169761514b9895a0584014ce1f662b852072f53da46c1ccc95648b3b1be384eb27c24dfc8492e8b19af32cc326dc23f95e5bb02d8ff24cee7c01c794db52e54f352ae5e01f53b9d2de7439973a4d5ac7ba792253e9cd7fe13ecc9d972ea3517839d1f9c81fc48993e30ccaf2679d5a8234e3348271289d1b228b3b96040e0d15015bef70e4e71f75e67ac869ce8a6d8e5715161eb77d4ba3b16e9773a84c77d79ec759c8eb3eb8ece16dd9945c5cc65b5eaecfb627cd602db82c9daca7f70d81a0ecb04934f66af16cdffa779ab9dc69764ac2e72be3457dd9e65aa7da93ef2e22c95c793e6d96047150ea374aaadcf8b242a66f883fe3c6f718c8556fc5fcf55ed28fe652c95f1b22df9297ba638cd8cccefec04afb059666d315ae6b94c4bfdcd7d30243d97da7c7e7ef927a2cc9a95c63d516687565f9d66f93c4ae27fd68c28507cff31b150d7ee7d0740a159061967ac192d8ed76ad3dfcee2391faa5bd23c72c774540325a0a637bb5bab8c59653f562875e2c0730752095017173aea2d78713b8eee3a1afc03fcda99cb32fa45ae14fbc60f51523abf47659e381f8a593c51555a9ce85ec5e9e5d37434c3c0aaf5ef11542455217b98d0d1d9f44380fe6d1d71a2ab788aa95aa082fecd42caad0f7d90cba2dcfe1d41f74f2c8a3aab8b5700ce031820bb0f1d75f097f3be100814a7aa9a93c6b8bab3b0b43c30004b866615848282095c98680217817002700a1955de8d13857d437c03adae9437a168e910aa0621d89089ea27fad577bb2620c5c27ca78a1a04b646f77f20fe47aa253c60538a3a7925f355398bd32928a3133929c5480135f95c7474722582d032c02eba286432513b08c792c8520c514ad569bd063bd8a07f314ca2f472b083b1e135dc9a8d64c786e340cbf9395685fc0e66680eaeb7c0b6a574e7f39d91db409eb07905f7bf270b7e1e53dae360eab8b39ff8d1b8283a396728b02d151a35fd077c637933b7dac6b843839d486d2123f3dd7daa9863b98df70c35d8b14598b162ed1d23d7c16f45a44feabde83acaa5f821fad1de2b2c8b5bc7dc0e6ab91bda2a8cbc67d2032bc330cf6eaf0e6fc59f5419bfedf93519cf03fb2dd31ffdb686bf99292a33f3d5e3c5075566bc352f253b0b3d30e49f340a32b2cdf05fcb70fd6c312142f274b736382f1df27661fca4640fe8038621d95234348ac126462d12839dbf674bee83adc4ba1fd49afc28b26559c463c9eeaf28ae79403c098edce1ed7d8966465f589dc4ca5021d1a946c02370ba712bf0898f03b7b7e9ea89516bd23d2e979366c244a8c10eec360b61f37927a0971efcbf72ccb353d0f243ce4a3d4c6c39eb431700a69f84e6b851ec3cf5979ef9b2581633d61edb36aba0efccad6f0d97be0f9fbe07a7ae46edc3a66c4bfbf5f578d6ec36cb5804bbaedf7d16070791293bc57721ef8ea8fe6c9e55aea8bcda10e393bb77cf736b9391cbc9a7c2865b2cbf20cfa285d43617747be0d7da285d213aa87bc50582a712ec102a0f5ccef5c2f4f4e0fd1048c18b36d1698d8e13859bdaeb7e99f568119c4c57de7dd2a5d2aff73fff460430b6bf13a9ea1b6f45382e6fa8959bd1872c4e8f8c3957d342d9a093b326609fae99b330d66ae75c31ca36d209f6ecd916fbfaac983666474db339d811986a83c9404ff529759d478b05f88a47a5b84cb36b4c5952360a16e94d64eaf65efa82d0afd1554516fa7a7fdbab1e1a81e57174847b89c48cb3c18efab8473b6cb0736e03e7542abbedb95c34d8594453891935bc8a9e251bccf1c8b740f33e7bb102fdea5528ee580c227bc1ea1e7470967007029faaf6722798ffabc6664ede60a20e0c11a87e58d9ae780a703900fdcd54d2671aafa4bf994a6899a58bf1172b5c254e1f85330f2377ae113b3f43ea04a1d325261bbff0c88b696cd11c740603f491884a78c25f1a21a4b784f9ebbf0db0ff24e99676fde709b89ef68dc998402db7b715998d352eb9fef01eb2afa7f1ab7e617d2ca27226faacab8efaa218308973537923cae85262fec61e8454287add2ef3925fc44912e51f8aae6aba57667bb96ab5e80e936cd89d474529f36e9c8ee54de743f1d5ab8347075c7096c5285ac8f1098e0386b3bb0bff1a779c6ef3acf3f09b27fdff79d0fbfae35db37536189cdf760783c1e0bcd59daaf5537f7fbd6f53dc81b00bea9fbed3c1136bf4e2ab71cdbc99c0ae3ef5380097e5f484cb6c7053f4e85f2d168b1ecf6f8ba92d9eea48ac0f1e341d16f5c4e1584d186d50870b257cbadcb6d874f0c417001c8edaf6b93c38f0f11a3c5638316b06dbb9eb1816d816ea27e3330aaa29dd7069d2a8f4f959cff6bbbbeb1c90b7b7360ca0a8310476f9348d8671e71ea37f5a36bcbcddfb4ef3f5be77abf97affdfe75ea3d8d917bcd21083acc8fef49dc47fb5ce6cbdc2b794e6999663f040918bd0a133362ae932d6e7156482dfa1ab881e11bf6d3844ea969a9d5ea5366fc43ab8abbb5d6aef198cf87bd55b1c938ed742211e13bce8e8dd50734bd278abed5db3aa20f0223cf041381989679bc54d0890e0b4f8ac6e46ddee571462e975b458c4e9f4dd9b577d6e5708769a1f8ace3c5afc115de7d33d69d4915c71a479168da7f27770a2d91096468dc5e4fa8a43acfaf7c910522ca2f48bc74e7082d8a8d97cd1cc2143b5425f3274dc2746148025c3bced26a0829e2c0b63591718c777a201c2f31d68e063c396dec771069a1ceeb477d813f0d3619125cb5236b520e7ea66f4d7ce6816e54fcbe6234c2dd9e8368c6d56573c1d66cb52ec77bebf1113905b45398b305e5c799ded45f9545cc9bc80c7ca09ea44be2a16e03bdc625a17fc749cca661217655b80f0ebeb5e6238c4c7f2a62d2ed59fe2a1d86f0bb822c445499a984371297e10e9a12aeeabf24bf8d7c814aaea597c4e8dce2e1d950ac059507e673d45709b89e70b24a5487bb8601ee2998caee26425c04c612c1b8558e6496711e58a8df83615278451b874b0e4ee20152986d5e769b45bc8c4fa9804c5aa444f2234da6f96196497c93a0a7b65b3d16da09115cb9ba32098fa006e77173e06db0c4c26b9d3ece91042db41178c54caacc512cefd946773aca861b3aa30419b1f7459942fd231d6d61d28294e0361717d43bd72e79232530b1051297ee633251cf1a749040b9ffd9c2906602e9308d41c62ac6e168a86277102f6505e1f8646fc9e6d0d327da33eabe9b26d4d3d1cda76b8bf06264b41719a477112a7d3b74944ef0b9a5e82d381778f081421a6ce995f5bec897d6deae777a1b606b4579bbdd3508bc47efb1f1aa1e0c8558870b0fa167b10631c2fffce26f747ab36f38fa03d8df7f6dc944e51ee4e343e77f33141394ea4c533156976635ab645dc726f125efb7b001062b978f8b00a6db9b81788bd3d27cb3c231ebb995a88b943ac2e540f167bcb142c719a3078b6bf102adb91bbbb1e299f3d3a4757c286296324ab4a6f6fc5036fb3eb324ce1d3f2f78c194d839ff3b92cd4f9c4171d74d38a33f150df3e49edee52d34eb11c1665dedcdb6fe190bb8d9686fab0cfb613ed2f2cf284727d4c7a8c1a73d91a360e418c8e27cd6cf8c13d2ab3e1870e158a27fc57535de5c9a9c95a26522198d002b0ca2b04d478f18f659434a3b6185aafb45359405e5cad5d95aa4e5caec424ce0bf4a353e88a80688786a950885202725cce647e1d17b2ad2a53ca7988e72ad5198489cbca995c41f4d034a36e1ce858e9f6560cf50fd399deebba3a9cfa9db8c01791a8e53f4a3435c9bb15872d437b42449a71c1bcf40f5e0e464046306fc690de84cb115a470c7d320463cde119d43d67cfb444c115de4dcf4f9193c70d4c8bb060184ef006f77a9d7f4ed347c4355243bf74d872b859a453cbf54504a8b7bfed5273d281f236d5b3b0a826d1e5a55c154dfa3b2a8a789ac2cd1fe8aee5a3f552ae183a035d9e5dcad5b942a7fad770d456e0e14a9349681f5a886bd249dfcf6dccdbdae63a095ff7b4b0cb1ad831505df8b0075be1befe6edb789399cd1f8dc7af6434d6ac0ec4f3aa685e15cb21784d39133df8f1107e207ead9c5de6f1e273806b6ebbaf185ba08359543c231b72006da29c54bb28b357d9b58e2fd481dd773ca1983b6e61cb9afd35ba4fbe6ad8ca6ca8d490a4213c0bf6f643f3df6280f5d370d1e0761a4609f4e91c5e1b900e7f5b39adba04707d7ad4167b75ab00f70fd0d9b39ef4e3454ae1e215a9dcded201492a6b19e5f004d068b03c5945e0cb4bb50204052e897a491a5ff9e736d5c5f568311971c6db13424d7dcd3abc11f3ba8fdac2abce644b9c4afd309f38c3e4b5bd811a9cf8ddb336db0db6d2c0e5871f5d183df3579b0fa46706a488e289228a4643e8afccb9a2472856d5be32d5d4b781b5dff0a27401c924ae3dbd473649e5f5c708b41a51a68a3326b3e48e6bd621ef82a18d53a65d20c501e8af0738fd16367cd8a7ef3ee3020451939e18ec3cc1449ff0e19013a9020dff3e408459c0e041e6810584427505f42b4c2fa2a7c3b6744d6678f3fa88bca528a352b6c5a55cd539357063b6c38a2482b87392c6b3a81fa4869964f9bc273035a8edb5e5aabf61051cde71e856e8402bd1c7d681bb9f122f53e9f76868aad29d9b5e94f5a8e65721365f4312a860d5251e0c5c7426bd044ad93a1b02f3aa08a4aa87fef79a67a840eb4628d99fb32bea06e991a22155a78240fa7c18d8686b86e7b2796f70b8e80f38eed57ef189a2666d022483c0999b426821c772948de5bb372fab74e0071f7172344af0958ad291da1befdebc84202adc3bc28457d185cd86110b073b0eeacc701e8ac660478c784e251cdfb823548b06aa090b91c4971262e640caa5e14a4429887f493c160b998f645aeec974942911acd368d5ac0bf954d42800400a376344dbb24bb9629c21cc46043ece82c82be27494cd17892c65576bbe2cfb355fca4cb324dba145f583eaca04688bad699d0d4155595269ed137eb7b1a12f5feb5a3dba6a87d37210ef33b8df661254dc39e4564933b1c8e38c591b47e9d862322e849c2fca953aff4b11970aa3ddcfc0a03e155daaa033879d11fc74d79f8ba77955ab404d2397c90eedcfdd5d117598d431ecd8d338ea182963d8d1e768842409dfd45f90c9cc5e113b74de0df18faaf6030fc9d33c4a0b0828f53a4aa3a9f5ce254388f982255d1b703feb42962750de4ce50dfdf919fe9ebaaf3e5957359e1a33fc62b9c0183a10ea2a4ba51e58548a48a85ba99f6a4db0a19bc1b9decd01275513f10b07c2dbb62ab810367cb7879811fae55acc9e666657e88ca5ed90136f1b62800da3d1a5235a1c3f3fee89971311a59071499406b062f60a2fd7b33891e25a367249119d680c713a3570ca9904f7af385b2a4ccab6b896621ead844cc762b910712a22712de37c8c674847fc144f97b91419861e338086b25017f295da63e4bf05beba76bb11ae4c2676835f47176933f66b7cdbb86c6839a788cbc71c5cc6f47af27523701a7c4850f3aa0696c01b86e7361668d0c4fed8d2717731efbcf9b49d41e6806c43a4528e0b110527609f1e534c91af96097da109d3145aadba67f03f3d9166992f65c0f92d342d38f0acbe09f52f11a7d459965dc231a72486049f2e4d69c74232bdd33a82d912d831563c3bbc5104c77de75d5893b828658a89e4cc6b9cd5092d16321dbfa23acd49eaa815997d1cd3f4b2e61ab8cf5174c39698a45ea67e6379def2254233d20ecaf6f4b3b50d17b303b52f420e4c7a9845f85583f652ce43ea5cf51d1644b7655adcb51c31cdca78b2d2782dec58ffbda270309464f98b6834633831f8afe865754975658bb59a59a3f9a023a667ffd4b658d583a417faa8cdbb1ceaed79bfa992b7143dffc3c0773b1945e9bb423e3f7e8d66a1c43a31000c8a882c26e7eeae0e0d33ce4680eac027d76a44a1c6a0792a4b87b912abaa1c8c66af1368428aaedf4203492ff23604dd4eb3bd289179e9b86320efa2789a1428d30923069eaa71a12511751d3935c6c7e2753696791aff33b7e90103e6c8a616fb8b9b225336c04f6d3e9151b9cce5de58967254165ded2ff7a10088189c1392944540a2c8a85339851b48015bf137c066214e66592a8ba05135588699e885681ca7f38d7dffa7c7c645c58a8924bce978334cbc5c46a2af8983dc0bb3bcb32c64fe748a41ab917f36979155293e4dc7b91aff41a7a1d5cfe2f65684aa7cd77964ea80f339aff43a1b2aa1e96d3489f2d882f26a1dcdf20cc4cb7eb0d84198a95579a3337b9e26aba96a77573414777fabe4ad863ab1dd0a876ba954fbd04fe25c1662912d500580ef03335a712049f1f2c5fe23b830bd7cb1bf2fc699eb4e5459ab936c01433a4e7f8e8ad911006aba1799fa65b3d839cde3b14c4b8397f0749010e309e5569c66cdb4859efc300d8d2bb8ea2ba167b24c12b188a6707dcea2f19a79fc35232bba3750f39dea40cde813e6f2539ccb4976b3612e7a6922318daf646a1705020d803d4d2ae48d927ca412c37f93c35fe292c211a067d868942dd312f72318c744a312ddc390162178eef15b5af55c4689d70bed778ce1ac306ab54958eb5a5dac17b92c00df1014381a5d0a8cfd10c0665cbc30233ea1ae6a039a506c92aaaa4a11fb5a0c1fe5f1f15b0fbf78046972844ed5e55c4f589b9a5a2a355514ede00ef0defda6b2245604303529302d5970afd2946e6fc5c7bb3ab558b72b5ebe10fbfba2c8e6525d4b0bd4301588f208528c2a9c87401b106fa50c315e30b83ccd714d3577ef2e9649d23df8d39f9d917fbc6361794d8e5b38740b1b6141e0d3398bea5673eca5a36439c69be437c2b0abb6f679a55f8abbc015d32146eeb3e8691ebc308f68ff6f4df5c81cd698cebaf132449fcd52fdf3c0ca299fe574d578a623937877ade7c7af1b9bddab14356210f49f4d0c810a4fd729c6d4806db5ca41696ac2102c8d6b594d0964eb39b68170a1918686b75a82a554d73c4aa3c98fdde15f6d628250550f00b77646e6de0b55f447e15e66ed38428a12dd347883af03c8c7e5099a76846e237f8c2604a51d9ef964ea562bf1767c148f6dbfa68659331d25ce6645d71f9e845ebb2bf60c4e9b96a253f366c399e1f3e3d7e6a16cc618a31b3b119d837839b24296f6052f64600f7f2957ac40bf4c90072a3e4f30d8b83fbe66cf555e78499e5bc6aa68fd76d5b752f65a5aa9ecbd9a9a77d34a45f6ac137a41d5cf9cfc69f293c2dd99d5bdbd0d184698756c8bc6df29e1745496728e49a78d8ac740c95211a194743dcb0a29debd7985631f67b2a0b795699ce2ab0a485b280860f38e7871b390a352a28a9dde6bf0ad169e682069f1140456536cfa862a9daa7e49b17533118dc990b188a9e42a3b363cebb6c2da5868f48b5c55c24ebe0667ce281d67f366ab53666f415bd8fcf6714b9b131cb4ed66aed83e94bee6dc84d70ce8d403ca73143f527953bafbcdbcd59a9885b68ed9385a74d0f67aeea1a32d7ab16e65a01d5f1f63a0195dabfe423ad7206651f7ab4f1e2f3c9a9285286e9815773d41555d78500266bae34dd2668ba7e91076104d8f973141b4b56efcd51bce1aa015e1b155210b38e27e9537e509b8dd7333cd2ae67c3310e3bb6940307d530d64cde988a0eade3ac13072440cb671727cd2306dab04f2194f185665965d5614efde27366ce7aba02e7aba2bb7d0ba11268e77aca78b0c6101b7ff95cc4b07fb412d774887cc9c4d3490499ecd2b2fc0153f797f8b1ddaa79ddf24bd782ff26c180d9315e644c134286a07e532893181ccca6cae4b291718302d898b526413087727ae65e34a8a424ad0ff17eabe91a56fcb2c8fa6d2e6ff7889514ee105e8c3b2b016a165261ec1cd938089316476b94cb3eb0e3fb3cb4cdb7c4549f28b5c15e61ac73cf60d4bd6fe26d486742416068f4ca0b059079b63da87ceda117c0e89f73096491981ff0a96eed99a8e490bd4abdf7ef4048065d38caad73c3bc4695cc651c2e8612363b15eca8805d117671e980e28b1d5829e603cbd382d653e89463278067ad1c2dcc3901dde212bb52003ad98397d46b4dfaa959536f9d661176acc63029fb59044a13350dfb900f754dc3207a9d685e8170145f96a3a785357a2d07e51a27064aac4ea1aa831b297c497d2b94247492ea3f10ad201a1942b626884312ac75579c863c9efdefedc0807985b27f830f9a65de132ad5a11e0cb7378b0b3505f9cf3d9096417a243a71ede21b8cd8dc3faf54dc2357af2de819d7bb573dcb83292d164b867cfa55cf544b0e39e608a1a81d118d056414dafc586c18e71baec7ac75e257e3eddaf721338a1eef022afddab3a1ee95300e7931682922889a96800c6ded9427f28f6bd98a8d4ace3981b56bbb02c4bb738fc971efa83da87eafb73a6802a33a0251a45a9ba53010bc11671aa15f405f207d4ba6b358fab680bbfc56f432536cc61584ac15035ff394c5a0784fcdfe3d36f5e9cbc7a7af4e20f56fdaf63d55cd3fc6fc0adf5aed2804c0fbf0bbf4665b886a05f3309ce992939f756e3ff118eabf9c1efc674c38bbd9eede21b2621c1256528aa69f42c1a5d5a25c4346beeedd755fd09a3a438b5f72bba086d9a724489391ef98a084c7f78fcdaaa82dc5b8f0be0611f2f4faee5bfdb47bf2fe0959c6e597d1e15c220371a6320776369e5bcf0b53dcd92c5baeaafe631a4550bdb7b1c6c57f43e018ff4eaa41e556791cb7976257fb78984c06f3f17ff025a3c4bb2d1a51cd7a9a486aa980c371d651433cff41ee298912dd745dd7145c13205c0705ff6cf356b404cdd3a74f5c00c997558a55726a1f239b2dbb91f82acd6f037d4a108624e975587b3b7eff008fd27754dd868aeb79643e2ab5a9c213ef17310a19ef9a26f32b80679eb50b37e927a40e139b9c1d43553a1246e2195358b54a60e1ed053568287796a106d2d6724961efb9b0a95608e5e527ec0663718ff34eb8969667e288edca37fcd47e2bd3dfb2715c1e2f6f09f3667a03dfa77906afc680f586ee713b4658078ca9e3583ae761295b3a36c8cf69c805c9dd2a9a7710d3e30a0cb61a1dced47eeb9cae820e49cfc807b3e3f00d7e71a3f674d08840274e0f186603f7eca1042fed196eb41bf94ce2a8888cab80323f59e532de07ab05e932d81ead0dcae273358292df38459cb7187e0659ef8bec0dcab7ac635a1e289aa2e7ad0c8dcf21d9fdebb8a850c5157d3c6c4f84d2a91ab81516843f9ff2095b8c9710e21acd34c67681e6569015ba014d128cf8ac2ca697b826cab3077f7026c18218b765c3e3093c75b49e8461cf4989e61e8e2ad31846ebbf0400da4a5e4505b8d14212e9a1433317862441cc44d3feca84acc671b305a0eb5e41142464bdd84bfd28fb5754e3f3cffdfbf8bddcdcfdcd8eff734baf18c0299e54dbdb9e0968634ff174c58744a403b3afdc5712177aab0466e2843c5c51ab6675dedf7b661a1b570cf40ec9d3253dacf677a503690bd65da6a8621281d5bc5b4b28cbcb695adb2c1d0c60baf0520d991e870e0d61f3625ff5a9b923f2c3d369b33d0ad1234a6b425423ea21597d8afbfdee75eb15fda2ff69e761e6cf7395b8ea9769111e838f0bee4ec85c12b31b0056bc304db6e57bc488b652ec5b51451721dad0a318baec8316f21f364b5472d85cea72cd855c50c8f835f63ec91d43e36bb8adc452eafd6192af02bf203871c587002678139c4b6a9622d77142a9e0a7ba701fea1444bc24a9fa5bc325e0cce4d9dd15dbf1f7cb0763a234b24b0a8408087b808f812a0b7a88851aaeb12c679af014ad78765c596679dddc81fa63ffabf3f4c7fbe98e98fe23c5fcef64743dbcaf8476d89a2934445f9926e5b6c375a34b43edb12686d47ce42fcbb9b05b193001257ab232c2ef4a9610e033194134502e30c163ba5dcab8aa83b3ad7c3da036cabe36bddd1b5f1e0d9cab4c9b1648255147d71c616cf83d0fa6c93267df3388da64aaed66ea7ff58ca7cf5562672546679b3a16a34f8514f3a062fb29106b4bbab61aaebdcd3b2cce3e1b294cd866ad668318a20381b2eea35da6968aceff06cbd36d867fdee065ae147b99f5d0f3dcf06e27736806203617ffebbbeabd336ad35ae139b044e46015ccd6a755f47e4e2ebf1027f5f7b6ff0ac65cb0be9802a3fb5a6a54c12f46b6452db7554f0004c42ad5f5b14993a88c60ea03c82c02546ce024d61948e75fa66cd0649d88314c1a3e84a4625547560c5f4b28bb150988b682cc1a01c7cd0e08e4a71508a782c7345899138393e61a1261c998e699105bd17ac13b845f8697fed2155a14c1f18849b210669806db6cb32cd3a66bff362c6754d4d561c16c3d60861eb443026807d094b80a06e904852511b2c76a1f6042c9f88204e844ccb7c85cb4f31c4a2f1185ddf81d07454a1321a5d866d002a12f5bfd6ce6a7b5eeb583ffcfe764c7f70dc7f2f8e4b4bf89fc274b7507438afeab50c38be17f3ad35b00260ae859533e210ebac659cf56cf32e1c26266c4d747f6e527df2f0990976501b60011738364f7655c6f28789d36613a7cabbfeef6b88749fee067fd80afd612bf487add0ff2d5b21cbe09268be6882a2fd5ae6cfb265aac4b3c582fe76c3b380cff33c4e9bf84774e3366c392d0fef1140447d91857d0f5087c65cced56ad58700790d15be9025c29ae7f9756fec6b1fe7e95d9b88e8455a82c0639abadf590aed60f50a18fe967ed6e836ceed4b7a0d64b754cb3dee68e0ab3f16b7aa07808fe351650c2ebcff854018ff5ecfaffa83c4a5f9d7b8daff6e410c62a20b6422ce8a8b476d8f9279ba0ca661d654ee559e470b163f112ee5fee0c99d082fec3c62ab78e25f40a18e73ed64388104d19beac31788947c7beb34469cb4d6689dc172c81c13ce9dd2a7b73f7c62fff089dd523dc16eae7a8c313d37d95a8a2599fc2a5c0358a9658f1b9f45910ab1e5e9215823bdb37fb4fd39822daf4a89454dc5b60800da13acbcaa76a92a07390c3799454846fecc9b372b048cf7d8686d11a1afc7c7b6ed9dfd0fc7cb3f1c2fefc10fbc1d7be6f003eed9f7bfaa7bf2f9110a0dce58c5439182e4101693ace8b0c62ac55b581f376604e7ffe285f32c58bec0c38953ec73a2c176af2addae781dcfe311da5aca597415679067f2f9f16ba6a4d5f623d4641461b4d548e4321dcb5c449352fd9fe2b32772ece96deffd24f285757d56148ed2bfae23ca0a39ba6a0b5bf5474a7667bffcb04eb8f7c7f13b28c14c1ad16db45fdbeb826ac1aed5016da39571d1b4953e46ef62e46c544ca41fb303d81cbed2b902ffef2b6e80fe7af8cf97d2e5505ece8fc1c8a8edaad3463ba43f697b4760bb6a9cd9b679c7daec0e0363b3f93f21d2acc9dc198d4aed73f65396cf8fb2b494378a84a11ac572a7afc80a47595ae659f272dcb3420765dcf7129032808775f947073b9b13900e766c12d00b1439e8c1e3048ca9ca5816afb24c27a6580b725d73decf28898ae2d7682e759e54f890aa0f2c256910971a02a04ef5f4ac3881149754b1d3ad16b1761fc5b290cfb2ac2cca3c5a50cb3bd3f67426e7f204e43999a32d13a9f0408df717b42f2b57e2e3cb74b12cff9a67cbc553e0047702ffadaf77924bac487fd4d73c9537e59d50ffafaff3261ac7d99d807fea6b1dcde4e87298dddc09fd1729141549da6a862227b85ddfc809533f5c282e21c041ca38d40d35d62934a9fe6d732dc6ffb4714be37f5a0719b3f6bad47cb07ab25c4ebe8e0a5d21b23abca36cbec8520c536d6a396e35e3f80a9c6ab0b0cd0e0fd06daea5709ae9d960474f67b0d316831d357efccb8c157f46c560e75c5f0d194aaa34d63408128d58e17d6faa10effad671ae40191e9a66c66d96885073e889e2ce13e0906d52dbea63c68cb4c7765bd3e25ad801c152edeeda093c14839d3d4c4319ff131330de81aa07f8904b3a48f5e60ec1b75d93cf740f0fcc4615026d872d402cb06600c629b2d54d0014b36c108a0c627ba2512ca2b441d3f341eb8da3040fbd25aaa58e027ecd72ba43d651554235073b30724568fec2ab0b6d4f51a3ded33b9c0430aee65d602ac02cc2f380a2ff9549e4c0c16a6760fbea8ce36291442be21d0d5ba21835ab47c4e08ed2ada231e121c0adc456bebae06e55b30bfc8de156b3a45e21ffea016faba8f31d1f974f8c8e03df69aaba105070585588163f169a35355eda44df519cc87183e790b1bea2a32c1dc7280ae9c4305c5037c5815c47fc695cbff8da813b0d6ca24bcc724939ac5d08e14ac0a51401898742e7ae819cbc8d56ab2667bb991d8a6c8d6521c1d218258bee3783f4285bacf2783a2b4573d412078ff6bf6d8bbf47b32c7b205ea6a38e789a2402ca0b91cb42e65772dc51adc65224f148a6851c83dc86e9279ebd7d2e5ee1e7de209d95e5a2d7edae9671120ff3285f416a026ad61da4f8ce0799a1e37f822ef20ce7df78b62a65d1688bc6e533f5ffd7f0ffbfc2ff4fe1ff27f0ff17cf1a83f4dc0a2d27b92ccb9558e4715a8a08d93c083a43056f90fe652ecb593656b45196ab41fa9745944773f1f1d7e57c28f33b6c703a9322850fa0d266206d83675996c828bd136769562ca291ecc315ed5c3c0727083380053c0a545b65a969719c267ac4592ac56816e5d1a89479757467702b29fafbe7023fa97bfb588ee27994082c43d59b2249af5718ea72ae3a3bd7c9d7203fa25ab551965ec9bc94633def28c584aa800f7c64d1ab35cfc6cb447690ce0ace5a9b20f40842481b9306e2b014c384be9d1d455a4a6ae0282a9d2da308245b406754979bb3ead650a553ada0904a8559ca0b08635446bf6e6f99ae5ce8611be8f8b3c6718a81ac42736c57e62b852b9b124ee7358bc798a42c1e8b1f704f689d8278f8301e57b0b24ce3ff9fbd77f16f23c70d80ff15c6dd465256962c3b4f799d34eb646fd3cbeb1727ddb6966bd3339434ebd150371cd9d1c5fefef6ef47800f9033929564efaebdefdbf6620d09be4010044110d07c1f208fb3f4a4e6a64c16227a47c56c21fdc79b0b0fa2974d613b7a487075389757edc1ceeefd2ecbd2d81e799c7d16e97ed83e10d0d303a66abd006876c0cc0d2442f699eaf42af98bce6b230e3ba17b33f34e470378870d10b849930fa63be5e16ead55da3202fbc0fdbb714b37e1274e9a2da879b0a53de310a2c55a1df62320b6fe4ccce1b4df677f15a5898549236e9ae78cc00ac020e267645a76d077b0033522383513aa279b3d33c4b07342e7960d5d321da41b516ba7b57a3ca764404104ea784d07552287ea8106e1975cf2aa6dbabf428de59644a85df8a73bdd77f1406e1523372b4efbe62ec7e49a2f92ff8b1029c461b2e7789b40618802c681f9b4efd01150f54e29f3bfc161ba320e25746645bd4dac3c6503ef84e42cfd9aa377a6fe03e280dbc2f849b25f9940e10ec024f89376ce33abe6021097e0404ac153b3910084fdfe43140070e0f8c355001aebb132204b1b95020667f6c3e0073f1d2ef0d30ebc419b80bccc2f8d03b24eda846e3b7e76adea508fd103f75cfad7ea29c6b29c6d9bd22d6fb402c3158a847277a30ae3de8480cc16d4ccf9d4fffe72d375a0c7a10a8260ebc4d89a7a58a369f7e6be95f5b1d21a67b96835f665775d6776a3deec46ddd1d536f56437e84a43ab7beb5add8b5add73add65bda3b5ea1a33931720f010d6e22bec1f2dd53133edad7e2db9d2cedb2d699cb3b2337d04c16ecec27c2079f9ee17df75986706a2e926c9c89b4e689e46bd55f356517ea120867b4aa31f789eb6cc8225693a543cd2aafaffdeae96ea83f3378ee3a9679f72eacf76db7dc3db3b45999e505b14e8da02d567390ac5604e9b6bd03b703aebe272865bebfc13d05bef1e5e7b9587f5b416e244086e717682cff67706decf63b9a8e6165fe2c96c68db0b756b5193eeab92109230fdbfcd0135929c67ae68c47899bfad06b63d108e8a32aff05af04e086576cd0dbeded412a9efa771e6defeeec3c6147956e98bd16975935e505fb4941426ebef5f9fd29147bf3eaa33dffbbbb825710fa4f28268a292f122067c5ce97ec289155c53e96a24839fb49e9af5e055fbd425458a13e72feb9cc14fbb3bce239fb29c93ef312f405ffcf4599a9de854eee3f758d3d4f12a1cf849ca5185090cdb8bae832599a24a811537b41d44daecf5b335ee9f3eea528959e3489517c310ca72e8d453e4e05d665f0abecabc06451967a4bd6997d2d367a78dd6000af6110ed3d9da77a26d35b3a3b61a98d86eb864e226d8ddd8d7c7d9aa9baa29dd08347252fc096bf9f7e1974efdf5ccff0cf72d97e365c2e3bcfaedbc7bf4edfa88fd54967341a3cbb3e7e9dcba3fffeededc9f568ebf87f465b27f7465bd7ade3ff699ddc6bf52781f9981eef5ff158dd1f8dcedbcf86c7efdf1cbe7c7e727cf4e2fdc9c7ebf6b3e17bae195f72fd462e20b0e8f5a128aa92e7d72f21fc7071fdbcca7951654987b59f0d8f2a5ea4bc4caf5ff0659e4da6d5f5fb525ca2abaf0efb98cd84aef34f6f3e5e7ffa78d8d1ed6dff78321aa55feedf749e7546a3f3151d3cccb3b9eee4f1ff6cff381aa5cfb7fffbc4405a6888443f119f85027231aedd40f0367855e0e82ae1c954a4a0975b4ca62cc9a55af8476fb5370e489248908b2ae9b2c9cc4a0a236a57f15f7261dc24a24595d0d09a3f2ce582a98b6c6e9ed04158f3b626074d7cad4f1f0f872d2434a33e0c4fdd715c74ff08e9222bd27763e85f2734a1bd7b97dde98f4669bf5709552144747c86060f80fe8293728abedbdded6d7cf8f59f06323501010b71055c693f84cac6ed3bd0019615aad29c448e012eee90a9ce56839d5edd3aea65dff2b78da3439debc7e55ca0ceb565b7320ddc5a53ad418b61dcf16a3fd6ff9ee8d102dcf5758d1f1cb70c436899c3794022cff35c5e3125aaca86df5d54497f32abbcb9dd65c62143d716aa0674ca9166d3ec0019a1d309dcef449a1a02aac90249ccf49aa4ffe9cdc761ab992e4803f743558a26eac8d7c98a669baa677af53495bf593925208a6a92ac127d409a88ead3c74350694c44d58af456a9a1c8e353f6236b69426a9db463e5d68b0868d900330b60dec8a29a36402d03a85f1679fe5f82970d80bf0680bfca45a91aa0de848d66c5a2124d702a803b12892cd226b8d7517d799ea995c0d2e178870d71df9c88eaa361bfefc66325aa5aa1dff001f46f425cd456acce7f6b9cc2f0e5bbf14aa071ce27ca9b18e17fe910fe0dece452489cf3b49d76a20c9d43166336785cf4521443d5f18b93183a1dae81663fb2476189197466c67e6483307d663b04799d2873d6d0a99926256c687612c3cfeadda2f0ba8dddb0d072a97b60f8d5b263d6ec6e2702d26061a48c290ce957f6af6cb00bbaeddd307b6a474641c26a7fc52ac2b45f5db910f80d00bf09d3de58e03721b0026015a6290bac42e01c8075c6eb2edb0bf35ebb3c7c2d231745da7ecdfa6cb0d309212b838f9ff4609fd5a6418b21380b3b27ac3e4b3e7b10ce4f05f56e50edeefa6af7c26a3f6edadbfbebab7d1055fb71c3de3e5c5f6db47cfe1b7aab39ff33d81634f736ecdcf0f236d9713bbd19af9269db4a7e1d4d7bc7add649a73797f376c7f943a6a26197b55ae1844a68b42dd953d4ac6dc39ef123a8c11d418c73294bfcc9cf555b76589f3ddce9b07b6cb0b3c37e6434e75fd943d86c83568ea095e356356d75b500a6ff2d52fd6f99b64e8e53bd7876d853b667f86a1b5376d8363379770e3431b27be63bc4dc6f50fd6f41da5b487b4b36cc48d2b05a78bd873b5ce92304b571061c47bb336ee255326559815cb9b67d5bf158671e03ecc9aa7d9c74a44aa686330dbae6b36e15ce227b67679eee9ef6c5d296df339cd83564e17fad344d356765690a6c5033a8376f864a59fbd4969acab20249212cdb9af5d3fe72e9e06622cd16b33a600b6aef42ed0e3897c5a4a14e00ae438f1779de08ad77aa2e6b2c03ddd6bb73dcede9f0cd1bf6f163d4ef3a24000e95a2b0badb0d755258f6df0e3a53b2a9d7aca53bba3d9b6da729856daa98b56af3616aad41935a47a3d6c7d1c81595b4eca72aa91707117865f9d1a8f5dfa351cbd5223ecfb352a85f054f4589f40655b560360c3d05c4c4febb353286bea3c2f85ad44763b0c1e579f6577cd180e7331591b2e69d9e92ad1832b4f6138cb58e1605584e48f8f37121f49fdf04b0998fd385fef34b99e93f47bc6a7569b9942f4d51f3ebe34228f3f3379116eee3e37451dadfbf9499f975c4ab45a97f639d963979a18476f3df39f4ef17710e4df252ff793e2ff10beafb771cc9bf2f72c85b4ca01131d77fde25c03ddfca4bfde78548c848fe9d170b5e2e4df5a5fdfd8697c9d4b492e5613bc234b4342d2d90391f89792566e7a2344d4af3f3adbc74c92f4482bfc351bbfd8d0e9aeb02d07f3e839ff0ef73b06b815f6fe0e71b5b97a713ff7094a7ed4b9e77592e0a77af96fb63e825cf912de6a005d2ff5e5fb35d48ba9a66b9601ac472d49f4835b622bc13bee4b9d5aa3bde8c6937c45498fd495470047d75f48e3d7eb8336057425c186b1200f8992b54982772867ac17129679065ac842a914ccf7339e9cd4b992cca4caa5e91f72ffac5c3c1e37e21ae54ff321357fdbdbd474f1ef607f71f3fdceb1ff23c59e4bc12dbaf8ede6deb76b775bbdbbc48b7978297db59b1fd3bbfe42a29b379d59b56b39c183683750cfbf20eeec66ed8995e5e679867066a2d6f8ca28eba67f7071317f2e203f8558119d7a34425be021b1d13590e7453bcd44724b37262ed853e3ed92361bbd375472a384cd284172eecaf69fdd0f846e695609564ae01f077a6b1a2e1c2c67bcad41325bbead9366b37662edb5a227aa8e59b47fad71ee9c8477e2198597bec7e35655c99877bc6c0212b903a06acad8427998ec5d0382b552382ea3da1a8b24a8dafc147d0944347981a62a3216f1d32c07652cb48a9d16c6e2b7e9915936d4d25dbea2ad382934c409d9c820a32916529920a6c82b2cae224d5724b7dfcf1499b6db35a071b4fe3754200fd42038a315dd79c2a32306f80a671a9d8b9a8ae84284cc51edd7a48d025976487a4cbbdc8c66376c0a266e3516801bbfdf8e1fd1dfddfbd47c195c8c00adc2895db4a3b4d0cca3209cd97449925ac14f352285154b8d59a4b00dd03f3d3d0c93d4dab7a42704bec383df0234cc63db303907f047389541fde6c229557463de3480f90918ddb9015387c42e04735f69dcaab183b1759916ecb310301315954e120eedd68961f761eb7995ae78d7ef9d2dd61e8e301ec2707f69e2b7c66d6d2892d7a714b4bf857c8713197532b6bac0a7515779a2c0a436712647fb3153c2f4bbeec650afec2506aad739d15b46cf172e39c6af4129ee7501ccb9ac3cce32edb1e747a957c2daf4479c815be91c4edbd360a1ca4b9e337486ea137319dd1e3338f1a4c6a377a5ab253ef24c8e81d6f685320c7ccd97736a1b066031ad51bda05e09d562fb8b68a0b8c8a9b4ebb9a66c062b6ba5bd1b526d494668a9fe7221de273488db35b6e77a35a9a2e758126e96bb2bf93c5d869564c4599551b571cc0d39a74231f9773677a362fe57c5bcfe2a60fcb20efc5bb37347b3b9533faf64c16e36ce2df9bc167603fa6fb2b17953a9af2b920a6638b2acb55dff59194f1cfadf1954164a8d69cdd0aefe03fbd7df3eed3db8f2f5f68797551cce4a2a8902510a097fff9ca4088cf5943f6db8f2f3fbc7afb2700d0273063681783982a34446313b68acf59656ab0dcf5e35490d17ad990e5a25270d5970a2da29e0bc6c9bb5b4405d884db12501d3a5ba824e305de0e9eca4b81979ea7180c873395cde6b960a948725ef22abb14ecf9fb573df646aa0a447059e44ba80d22af818f50a8319b41e553c10099e84b3e6506b7fa538e19f73deab2f345c5125e309e2b7c96772e5c7d6e5c59b18dfe20c8f0601c4a8b875722cf7b4e32dfdede76bfefdd7b2b2b71efde909d790c9ea1eb8879ce2b30d8e29342aa2a4bc0e3baef5a8fbd828bd456a93b8496b6f7480740123d3c3aea0210c492335115ae383ab158a071033b3e3b3c3a22ed9fb4f599450dfb7d582c1a9f8b22ab963d594e3069db37830fb1fa8952241165850c832bf4d8ab8ad9f5cd789e03fec7429fa3051c20e8e00dc625dcab2bb49d48f1650acf7da9422442292d835752a36ac98a2c11481f874747011eda53512430eb501d466f1a9ba701069b9de609fa79e923424c45384b9ed05dc4279e57e6a508f53d601bf605b2ca781a505dfd1b5f2a943cb9506cb4056b70b4058439dad20b6eb465a9498b63b5ea94c6b026f3b946865e7095045b0f3613bcb0342ec663703e225905f1aab0c61efb45e211567ce6b0a8ae04d27b9a32552d737c74419604da806515837e2a264ba6fba8860e69676767bfabcf48029681120611d804d72809c48e7b668085aa58ba28adf38bbd9d9d5a2ecece91eea9d118dd0bbc600cd9999cf324ab96ec872fb6ae9b9962822ba14fd072519d754d310339643b987213b5e6ab3d42d4f8162d6f1db22fbe9a0186c974f97a775f958f8c35ccdf09f3e3e22efb2646cb2f3cd5e8687f6119b87dd43b14bbe9b083a7ac6d2afc894c49561c7c41a01bbbd51d78643d352518fb629c71fb5af47f3fa5d925d2cac1972f249db15eaf4727a81b67c6f83c86fa4f08d80d695dfff7aa35639c8df5f07cffefd0cef4d3ecd297e9dcd8e1922d17b34136046a75c8fb886ea14bc1eeb319cf3c130f36385e30e0f943ac7a9b9df99df52c4a1369906476cf28c902611fa22d04dc4dcbc92417a9338538cb8a33b098ecb1dfc022b32a17e22ce46866b39a6485828cd1d64bc35854c527a2c75e2c4ab4b9c8142675c30ad07db59a66e3ca6bb3340bb7d661f166d7d59c82e2c2b22bbf86093724a5357baac093129a9f11dc61cf98d40c1cf672ddbd5c54a2c75e0bfd5df10b539fde54649ecb2b080c63b859fb4ae8bdcfd816e176b75002bcb744fbdcef0a36b85426aa3f95f2426d97622c4abd77806eed5f164a18df553abbd3c8f0dcf1e4f97c6e4e28f7d0945b55ec18d758972951bd829f2768b38dce64309ae7be2962ce347ea1fd1410f6060bf8c1ce4eb47a9ad72f43539c5eaf1724baa5c31a978f493f5f54959ed8e230cf928b832f6d60326e806d4d999da81b00aa271b2992b682d579f060391bdcdcd4d6ed6fd60d97e94da658a2db009bb615241dd21ad22ba0c7d96baa8ac303c25200213fd8d99929d6d6852e79be0019e2cc20fbac63031465151b6705cff32543fd974021c62f0d4dd6bdb0ebb09e33c5ce8004ce7c24078c723485a7f68a89cf8998a324821339939782a89a098331ed19e6e26d31b5384fe8e6408bf1ff727afafed38797a7a781aea37d0a27a71f9cc1b6391f8747bbb6afaccb6a25627f901eb86decbd13d9f0ce40b32467610f5feca056392a2074a6331e77955d5f33530773e10f34cbb2be310c2086c32bec235138a081fc1f9dce406835e20e87386430bf7a5678a9e8cb474c02d7f8bebdbb77d91df2ddcbd41b7bda786622c142e56c68beb016d27be34c54b389851d15e0c5806246187692b80dee6545e4bd0b8b85eeba691becc09c2bc945746383f678b9c62757ad623c6ed63c6745057defcde9ec5df1f27356e9b9c5649ba851b77624ee18fd359d0c471fbf72445c186eeaeb51507c18d6668a06d35688cfd521cf7363ec4f62281ab67feae8d7b4e9491274a3a2cc2e450afbc62fa59cbd374fa102356b138c790e352fc565e8ffd77b0e732fc18a80924ce6ddbbbe704f19741d1024d7d572d44d9c4110a2b766d7103d9a7468b981953a11d551c1e76a2aab9f81d97e9aa77adfd4fd794f1c5df4fbe095ab721e8cddd270b936ca05e2edcec101f08bde3caec5eedc5f4ccfd90d33a076abb070a05c7475f81567b2cd7b61ac44b7e7f432c62f254d764874855938165b3880b9215f94c09b7a70407b707dcde2e4db7b802aa1d51d70bffd2f4b0eb4269b7b4383f89dce4b59497640891e922a0ca70ddb1024f4dcd6fe224bdf98a817de3b5e9ce975c630550ba01fec491b1f66d5789cd120af6e15897055b32b48d4afb775ac7b2d7dda4aecd411b234eb32f270db449ddf4e9a6be9b2fe3ebc91e77e033dae23c6c65623ce529f771356cb57b87ec67fcbf2fc136e488d734ef2236a4367926f09e76f3736652e35e5a28a39ba4d0e63361b1194511ae9994422436859b08b524c97051286ce81584f15789377328cafc313a56dccbcebd22462ae547cce016ba169043575378d18a89efe74f3655b7699fa9b0486c5902e6c6c374c2d8debf96233febb2c3d95c73d370b397204fc2cce1e6207566c42c1088688c6a0e3a67837ecc5d0fca5bb7f34d1940ce94c07e46915d301855237234e73dde863d3e7367bd9b43bfb915fe7c13d2630670200072863e9702efc9a95ee96c0b9495d4ff48e074ad054d95b9ade382bd217efdebc95a9703766948bd1854f9846e48448af03518e653903f1b0ad5be93a64acf3201b94fd9c5550b4eee695dc28fa45170aaa7a69c42c19fb0cc20fe931823578d0b5e29213ae5c37c27045215dd19153ba5a8791daf96bd7f0937d7abc710bd58f992e1d7f02428a430a3007ab67c1273d040d5d37f66b5ccd6d6c01fbdb8fbaf4d1b140dfbc5be6caaf7397e2394c21cda8f07208945917d91c9d42818e02f71f6cb1dfd7737e853ac2e00aa95c148553a76515a8de95e548a7b385aa4ef58251a20a6235b93af421113b826f97c7d9a467af846ba4c2c7e2680db9045d062f6c8db7e6e630b26b6652e2514aa431c9fb9fb13b30b2bb057518ea7293e1bc8aafee7dd0772359aeee7a53c7b362d2d46e5444165ea87c59a4a604a5a2dbb0b50afb2bf1bf6e06d6ce410306a309a9792c6fe604b8f7d61881636fb5d5bfd7b8facd164e16bfdfc56f5fb376b5e95a562e36732e242b449843fff7ae89f0c4b97e92f7fc748006edfb5644bc8b6cb20afcf1ea96451076d5ae811ae1efad207ccf11413c5c8f940d283fc0f206847f0ba6bf86d8eba24620a037082281b7b69a5aa64116aa019946894c738b7aa769bfa668a55d0ed0eda2317559626a761dd38232dce240108ba205617edd0d39dea857ee6aeb4a6465ca4a9e80d2333597e457593575b5b930a9b629159b496405ab8442c154492b11cef8856026963faf5c75e64a1971c578b1647351407c8da686c0f7fe95b0ad197932f1e8b4e25230990e29c1225b87bd261a8a6a0d6663558335e679bf8979f204cc54dc3b5fd2cb62458be82523d6dc423dc1527255c75116b1376ba89122d6b456937457f7d5107fd065d2b1c66ef9eaaca1625c6bd3b444bc8bb6b896add9309f6578128fa7d20291ad2c9542bd95d5affc52982dec5d696303f803a673a5a3a537c2f4799abef4b104c2e89c70e0b9be5edb02c1a2727b689d4575d9ce6d3b517442093b1673b626188bd0b8ed9aa3bb06edc0c6c330e5d61d6a4c648e031a5548a784ba900d946191d6698dde3a64dbd122ffc17a1ff398234f12936996a725bc4d21d03d9b1c43bedfcc9399af091c9ad9dac0c998e6b3e30cec8fb06763696efaaa0c63dcd821a422179ae3ba8651d3df9c452f59560205e7de955081cea99e2dd63621d6d51c2abb1a5a8e97633398bc6598fe9c711b887312d208b16e284e8cbb0542a4a15a0e75709eec028bea509bc3f35c5e29a344539548899a5d454ba0c98357b3e96acf3a50ec860e3cf38518babb172312da6e9a75d825c3ebd4f80a78a8d3f9ce6fd5a129de9345be6cdbcaa288bced4d47fab719a2a9359785ab143a1a8e150b849288e9bfefc2fea8b8699b918737ebe47ac4a8553ea25fc9e6feef0725e6ceb07a85e3f1466f7278290496bf8cdd63cfd999a5b233334bc63c0a6c648d05285eaaa391b6406cf45062f57eca95a9518b232245434eea8a2a32365a28d6a6a61b5d6a5dd13575117b882eb186e874d9d5344ba641572ba90fdbf9d21a02982a8c8fbbc430d5d0141245538b0b6705a43f62e31cb21f6505b1d1193c401b1d06062ea17d0eb336306f96de4ba6735877f0e50ccce0f43fdb3f60c99bb31bd6f7d5756e6c6f22eb1de6ec6718d885f80d6be80dee7bf0aa4aff6c1ffb443d63bd4c7d107f5964a548bb04de4eadcf3de95050f3baca11cfd1545e85f639fbac2ab3c9449468b286fa3063606a6cf1489fb3a0b7e752e6b52622fb5d43a1de0e57316354cfb2d94ca419af44be643c97c5c49f88d0b60c2d385698005b636c675b3ddacaf95f9758fb682bb24292853146d375e3f3b133209272216ecea01e4d9a4a54ec8c6ec0673df67c6c2d8cb11ca2882c8e267ba70a9fa5b17b76b45d067ef064610c8c05b8375c14b95068b1cf73250ded2fd959b0bf9ff5c814d0de7def64e86efaf9c06320184af3642a9435d6326b18a9a1672949632aeca57133d6026ff86374766f20221cb996c6599129dd94e11a74a041e5b78ef4ad2c67682214125b212923d35437368f47d5545e152e9ca45da2848b3ca506e7d01755233a420686128048e8dc2351a128864662603adab5369831ed54948d31ae9892265ee23dfd059312f6d2f42d608d4fc94b07af88280c89f1dceac98db92d04cb3c73bacfb3bef92dd2333c890037767583f93c4f53c5d06edd3e1688d7468ffd2aafc4a5debf338ae6a7ececa7e00544806b88d6b962b181e17f2914c6a270d5913e9c19b177fbde9977300a555ef1a55be9c9149e495512cda8cdcb58a82bcdc660845ae54b4a8ff692f116427c59f0f35c68166af4a6b531285aabd8681d3754aaf9f3aa3a3759301feb46c2a43e98af19f1d565d7bddd5a2ceb3a0b257db0a934ae07d39022ff4b2ed88c2f1d8fe34c65c52417ee64af85461e2c0078e1b062bb0f6c6ee30dd67c4b08309e5d66e942f3864d6afb62b7723bdd0f7676ac7063276b8f2601ae09d0cdaace6c7b26103bfff4c6add0c2992f81df4181b31d9a0f8cb731db00fd1bf874fe62e2705cb32f388a6743e34ca10b43209fd84997e00604a465f034f462a44969cf6bb63673627d80cff8f68952a6593b0265e654a0a9c7b438450f14b14fca2e3ab5c4e7fdf8d416209fb2017b8685b6d9800dd94ea7cb4e2fc0c7ee601f7ffd04f9f8f1e38f54a3564ed431806cb3c1096d15524f565830ccc1d2215fb6d13aa0cb8e61b827fad090f0aaadabb581df6b2bf3799aea5d6ca12a39a3ac4fe8fd0285b51e3b8c84760f672340dc8308aca0fb42c7b567a92cc499d33ef6d013241ed666b2d45b5721d8a4e460b311366c6acce5244b7a666b19debbc79cd98cde5d5495a1e17faa372aeead47b2f10a9e10acc190160ebe183d580adeb70e9e32b734f591daba2e4d94a2fb7b91829c057bf38c9717664bd652061e893cacab4d370384a80b3a255c2ba8b585fde832ff62a079b1e356118c84b262bd6c6a13ee34c563e0acc6ac1d5f90d8f3967990b650f054713ecf3391f6d8f38289cf55c919bcac1768da0ffdc9d473b79983b4b3c0321a319a2726f0ce654c847e7cf69129e33d025e66a248636c6b8d685d672ebf588fc11a9343f66b35cbcd09bccb483f864c6f441db6fd148c6608be645d9cdd0451dc49e6ff8c78aae307f2be1345fadcf1cf82a1d59424d2ef5b74781a69c4d457f57a451723f9ecab27f26fdfbdef253573c2fddb75b03ec3e044065ff008728728cd712fc9f571a634e71096ca04f6716e35f5376cc8be443eb10a29e149d94da4fa33f296bd43f862552368d85a3fa5fbf4e850eb33acb8e9538cb00946d25eaa779f8e67ea4e76632e11276a74d134a82b4aa8153468d649e84f84a0803a4ad809b39c7b844194eefd22ec36e44091bd7a5558e27eddfb06d1d79ae08ee352883f81731076c04a1420dbad5effd467b43a36b81f7b212af08b540a2d8197199cabce94c8c7673d17e057e71e897cac4559d4f82bf8f24e4cc0665ba799bf3d74d1031702e6a7c9712d7f7222927bef688f02e8db8461ddbe1ba594604fe407787dedfb767dedd7508bdcf2b6acd7ca9a7f155d1f3a46b13e25c0b194d28cfc0c8e2367b868b852107004ba5bb03310accf6cffbcf333bdd0b3047fcfc06fddbb313b3579991ee04e6fd0dbc104bd654c64b964afb971a260430ba267a005c64cc45f956410a4b547fd0529f6e5dcc63eb46118cc93dc7004bc60e05ba78be6a3e6b99fa9cb3c5975a338754e7a8e075db6db657b27e60164bfaf2550dd4003b0e525bd73992e7bc1ed882d691cccd48ab6f879d2da08f2b4a7d76133a8211203ca0e58e071a899027ca6f7550351bb5e82d782aefef9418cebf1c41cc1c0fd8d26e2b30f627cc6aec0c701ce59a68c49750a3aacc2b842e8325128fb065ab09954152b45629f4ebbb23a5316c2dc379b634e8ffd494bd3a0e403fd53695511fa0073280b7b6f31d3479e85e2137c577a05daaf79292e33b950ec4a9617ba5367f632fb0cb412e782a5994a78995a61809d0bdd517d9ce991e7ea19ec668a8fd1634a9208a5ec20e1e4614c1bc8da40daf6748df8826ff74ad49ba22b712867b3acaa04843d0330e2b1ab14637cc1ec33e134e266aec95f13042a33e839c096cde1931dc3d749e003ad14e315e15fa3deed47b4e344825551e8a2f2deab4f98dee06b8922084e6ace96645c34a12740e2b808c6477ada8c2d8b0587b4bb77e9a739dcc3bb3ea710e8388c96620cf8bc31ecb50c4847134a51954b369759815a2fc3f421bcdf9c27a2a66686b82d42d351254c75b8a055a0e062db78950096d2681256b02b91277206d49a4aa6640f2be8eb3ffa7f80355ea4724637cd6252f2f9b487199a4311e8ffc82e39883d7046c8f95f972f21ac94d70a012ecb089b61cd33514e44ab6350898f8a292e4ba31c81bfd88d5795287925cbf5ed00682f2c61270c126f6d67f3fa37ad1738831ad69080e9ad8e86ba7138d6f8edfd4903782c9bb842432ad698b4deefaad5310d41b5f576e05f0384804a9419cfb3bf8af5d874df8ce592a7bf9472f6ef47efded65bd00bf977250bd7133041aa64293ecae6129544f8917fb0437086bf130cf203ae57c8c09fe7135966d574a6fa1e82a241ce056ab6d5aa721ec297332814b75000c149062fd445529166262e31c0854bfd1082f7fa9fc0a359900f7d5a87982b713ec9835a7e13e77f7add87748a09488030e82f631a0cca10903a428a4dd65d4c72b6946a751a0600ed0d7d2d7ab1eaa437bce0134d94a49b90d18f20e820e930575750832158a65d83f9205d738fe2d01bafc4bebb8e977c52a4a59c3775d9e6859d1d67456a0eb8efa5f59954238806a8b09a2a9b45e3c482901e824e44f5229b89a2c642b004cd5661c91ae7b265f4e679c5cbf450cee6bccace7341a8a78ed4d77c2983091fcb32112fb2522470c8acf1139d9d4321d21b781ace8b70fd60d57d9bb7a203ff9189aba6497da327f50c68e33ffff33fcf985cc08e0b097e47b6c53e8acfd5a2140daba8c29c107bae15622c0e57d2e702ed0150c8116940c7cfab9caf5ca890d944fc333e116f652ade977252f2d9ca851ec13554f53a2b2e6ea985803454b041376eed41138e5d5e4391a3bf2c78e3c490dc55685b8bab8642b037674938479ac0fa41f60a5a7821e6a548d02b62a68636ff14caeac535a45b0cc4bb3e94b92c1b7ae933c31d83d07d03ff5297933a65abcbc9ea6191cc787760f69456d68bd99c7a997e9fa5160d8ef813a57c179ab61a1b53ad1057ccc4542365b470ed2bedb1f7b9e00a6ccd98cc5351d2d88c97d9250746c3da3fb19ddea38e8d9157087d66addc9e1523535d4e34e9fec2934a96cb8dbb1916fbbbf4d43991dc1c97b6c49afef9ee406fa2ce40b4cc33ebe36b9255d3c53984dce4c525bfe07dc3dc553ee767e60443fb5fe7da2b84a5d2ca4854a2bd9c1048f457aa2e27018c5b0a86159f0b96f099c80fb9320be1e7525e2951be2ac6b269d3f3b96ec179b9bda663d1823ce41afda48b3d6f35833dae543681480afe1c8abecb3bec8bbff2cef0ae3a633fd5aebdf7590637d6688c2f1725c4e6f3d7d4d9c9beafe7422c595618305d281bb3b6e98a73f7d19b72f5eeaa30b6f04bf4fa8445baba868e2e889d3cbe104b889b0cb9f0b5cf6ee0ffac1a12e0f6e36813abcceedbf2fc776844d92119ffef07eccbcd3e4548563079febb1d832ed1cb8a547c7e376e671df614fc9627b2a8b26221f6d1e460a3814207b20e2d6cc69ae991caf3df01a5f50186e303cde921cf73d0abb66ddcc92e3bd4624ab9d07cc076fe8ecba6f129292060dc2d571f5272b475c80b2d4fe8ae338efa5a73f96eba32daeac09484dd9b4ba5320cea6b1b41356a5b897c8c4fb65cf77452d8830f566d6dbb01266253aef0259c28ec4d5fa644cab6995acce1dd088540b363d33d834c18c6ddbbdeba5e7f1f80553412cc680b3c8dd572c968d933cc18a2ce3d1eb9f5a5d6568bf3438dae2ef60e7edb215b55bfcb30a6d9be19d0e987d9e6fdcd8a893ad2c05ade2b8502de3e5ba88a890c1c2e9f0b7cd404b1866d235d9014213e79ad3f80343b024fd19eb1a0757d9b7431e8b02fd2655f50ac462a18c2b203fb7a8f2001f10df8792eec0515bb2ab30a13d08b0fbe155e943e4d135d07571e45b0e99f127ad56317de8dd9b3e6f41593e4fbd63bc5c74aa7a79a0b391033eb1bf82adfc8d9f9e19497b68244ffd6ccdf6767eae55f163c3700b94cb99af64d2201bb10cb9f972110246128660854691f02b8cb26f34c005dbcf81005e813ccbd20883edd830257310cc05bb4d3e783b7f91c6c87653770391816f06ad59827a2ce2f84eeecd79e7db18375ec0a2b59eda9b0d309dd1af6503dff0e9d67ae7dfb896e000d6336afca7a30fdaf4c2a79f25d7fa576daf84c0dcfe2bce24a54cf51e112bd58abe5c7a58d526065e9307f4569755b71d5545e1636d7a28f168e72f7fd03b8a651dfbd5b4f741b611d0b667ad08e9e3c9aad23042b0e13838aa3ac5b2b568d35ab3555ab5bea8ef178f76e9cf435b56ab1f667a38e01336a5e65e7599e554ba7400c9600de9110c2b7c616a19f03fbba841dd82744b517c50d6ba2216ef72a078be1d22772d977b998c34327d41d79fbdaa8bd8d9ccbd5fd18e00a28455af2abf8916f2a5455ca25edd29adeb2f53e2ef05ef5ab8687871d97531f612300bce0af7bd03b5dfb0a1711002c9b2084001829c5648300e233e51c3d23b87c934040e6f902fc6b3b10934040723111f062dd40e03701980a707ee200f09b005c656935f5f9f049b899758af59e0c11e450f0bc5c7bd44cc28c074fb74d37407474b599c4eb6bd3893017d2366f01901dd6a09336afe08e9162da0687a4224ce97c435d765249652669c3daac2347bd415842046bddb12c673a11dc607bf2dd6fec06be0f9cf2545ed9325d57ed863d3159ae4e4b8c646826e96b39d1b73b3d6ce036b7365bc31e6db38edabaad7f8a5381eb457f34bd9546a015cfa489673abaf9442c11ea083cd6c4fee4085c936f030ce407123c4be1f6215fb2d9025f4161b0b68ac30894a88c999362e7f0da292b26ec74262a0ee32c45891b6cbf8f2fa466fc422888bf81c22a582ee9ddd8d8955a5b025ea4e84b11f091405841e52a12255aa25e0936133399fd55b86e41b326d8a632ee5c381bf30b68ca0d0becf91768d9d833f52a2158835a0e76eedf55df96ed9fe7f2bc3fe3aa12655f95493f91a5807fe0b97329f31cb4b9fff2fae1e0c1f6eb878347962bae242d33084b3b81dbc5382fdc57a97b0f3dfcda926ce20be95a9e405cba864e56423ea059bf51d5b5bfdc408c4c4e5ea01bea50c38058e0841d24f4667c4eec4b94a8022732562ca22d6918e27dc90c30ee2cbf1487484c4646b6cebe2a693d775a9ad154ac4916f002674fa0559878f7f8d17c82d617988748230ee796d3ed1c4c9fed6cb702d64533da16470117c9d40b71c90e58f020bee5dfc3c3b9b79ed9225e64202ed321bc9df9b3585af701a10f35d336cdd77545439a88ea353f17f973f567b1242dcc167995cd7341c6e826dc44bf7d0aa6af9e92715c77efd6cbdebdcbee347739f6390c22da6fbc2c6a5e875ceb6359bee4c994909cc9aab91ebe63327ab91e61e4252c688aec7a2cf0f21b7b09f5a582ea125928998b9ec02b86630c4164f8cef6ee09d325c0f25877dd916c2144aa18678b22fbcb42b00bb1ec91c7cc5d63660ebd1f6d015fd4dc98c982095a4d8691c87aec796e22615f8a7c09f1b9c0eacfbc4a629c8db6ea5431da42552ab05d78416a8d4f838eb5ea1e9c365a29135145ab38723e5c5be371c4c9fae1cb7a400d527bd6919fe601b742787e767dcd8e4f363c62d45952e857ad8163ddee0015e5195f5ff87d7d8d06fbb68ea4d6be7589586796e68a2c4c6f5a40750f98b6fde3c08d649d7ada69e744f386660f7a2b3149ce77750fc546a8dbcc79a43f4d51e78898484e33f1ae59db949b364dbf3f0774d4f13bb387b3c27d742a0e09d07716651113a9d210e61b514ed0397173b1ae1d6ccd974dbfcfde6773b7172a342787ddceae1997250a7e9edbe7932835f119bc72ae622736df466ff4e042b68ea615e7904437cda8c550591a65be2a52f159e863302899e3b2ddf51ba2afbadf67bfa13341c5c702ccae4de045226118137bae18f8f180088c9a14b8796de3a5662b3443c511bbee0503bf953d1d04b88c84ad8286b80910c40e56a0ea38708fd9b0a0a1ce9368df2316c2d63a18751ce6d88d5f77efe24724c702167e16ac94e70b057647854492601f442e2eb93110c6b09cc803d84ce83343a66670d39715cceea678d4dc565529f8cc79d3b0cd7cb4a708982cbc7e3a174ca49931d38769edb1e7463ad4470970f1909b77acb076b28ad46a070c3d56730847ec86698421ea59d4e7d5392d584377d93c4b23718436723ccfd21333f13e21f65dea3f81411ae6e6ca041a6d86b8bdcd1d1c0cabcb8e5bba82d6091d54bfcf803d59f2ce84eab1b7b2ca122d575c097e516816a20f7660d7edd781164f505c4f83ea404cc70633e314e4dc2e2791eac3687894bc14e81702832385b3fe9b2c2f782917458a51edc01b897b58632f1dbdabfeac404451dd7df351c5f4a14b10b8cecbbbf5f0875eb14271296464e90aee18a81955b56eb6f0c086b3a58be28c6dc25ee2a3df7ae82ef4646ddd0ba331de6cf727eae0bae3c5a6dd1f98d5ee2a756cac50dd6dd0a846ead2ddbabe34d0d9eec64adb5823bb6b555ec1a4ae56eddc2a7f749a7449a6d70df7a24e191721993edab46364752da64150cfa1057f34eae2e38b8f425ce1d41ad7055ee059cec5900588d343460542376a7ac8e24932081dda1f5f275152852025aa505158d7bc4492dd2dca172d682d2a70e062bcc978914b1f9da6fc12bcd628b3db78b5033c189224c5cb5f12cbc26331abc4e04ac92483b765c6fb85d3674c44e535183d570d18df1acf8461c724f19be7a25fe3ee87a5b4dc83b100bbaeba31b847839783e02687b38a9f9f8b947d7a651e9bf9b14d7433688b91a2ac536533e13c2181ce869f2398095e98daa7a05803788156463909110a4186e8ddaa0f6a64a8c6ca02360023d9a7449abc9d3ff6d2bada631dfb33d3f175fcef369fb3c868f65671bde87e67efb60b9e3dbc5721f9594a32b3949c96d678e96c25bcb8e4aad5a54b653cb4f77c63573f7667c8a26e4127862cec4b960e59e699b109fa692a0d6c191a9982e96e88efd5ee2dd7a9c0822b632ba459f5202a92f6f19978ad1eeaf8128a21f3bbc5ef216eeedde8997fece0b0c1b4a0c17341839dc02d506a1d989d419f65bc27e94cdc3082e1e1484645ede6bfb176b70f34d6e036039f0b12fdbb713b86ef74718ed2925f353804b3fb92bfe9d13360bc1deb3f6ff90c4cbbcc3ceacf709fc0b3babf1a50e8e7e8d8163e3969f0f1ec0d8e5f15973ccf52c3e940cc386bb11f595409fb91b5cea8df110dd342d0a07300e8f571a88683819ab5d5385ff5935e3c2b48d66be4094bd776eacd98d34ccd73be245e1b189bbb173fad73595572d6f2bdc4e968a5723199168baa15d0dae0c10e1d8a75426667d73b8e70e4f3e566e5f8d62d74bb886b4f706b5cc44168a6fcc2f47aad75d96ecdbccc16ab1b71edd62ccb2cec6d366516ae13bbbeff6a43b2dd15ef533bd48ec536f7f5fb98aef641acbb5bb3c5d46cf16a4715b37ac31d8874620ce1481befa1a033359956836bb11a0294c6d66fe618d70de55c4fc0764f6adc942cda566f4784bade67622d61edd508eb7d26eaf3b957a3a9f799b88d9cde67e2fb29696f134a7a9f896f23a247ff0022da5d49458f1aa968d792d1eea67434cfc47a127a9f898da8e77556ac279ffb35f2d145eab378bf463f1aee3602d230df4f41f737a120781df74d24f4e41f40427b2b49e8492309ed5912dadb9484f2acb8858634c63622a29f79b996861ed468e8675ed6a7f1418d847ee6e56d14f4332fbf9f801e6c42403ff3f2dbe86730f80710d0fd950434183452d07d4b41f737a5a0735eae27a09f21c4c6edf4f3ab2cb3bfcaa2e2f96d94f4b0464941d9facc3eacd15450e036ea0a80bf9fce1e6e4267419bdf4871b56bcfbf03c53d584d717b8d14f7c052dc834d296e4a51b39ef6022c6e44851f787a0bf53daa511f94a9cff3a31ad501e06dd40640df4f658f36a13268eb1ba9eb1f21983f5c4d5dcda2f9434b5d0f37a5ae52a3643d5501d63613cb657e0b353dae0be6ba4c7d3e1fd745730d78ab70ae81be9f9a1e6f249eebb6be919afe1112faa3d5d4d42ca23fb2d4f46863115da3e47929f82d82ba06db4cca5a9c9fe7eb85f52775410b0ad567f5495dd602c85bc52d80fa7eaa7ab291c4058d7d2359fd23a4f6c7abc9aa596c7f6cc9eaf1c64217e0e416b90b603622aaa384575168ee1a550d766a64658ad5e775b053232c037b1b6519b0ef27adc1ce26b4659afb36e2dafd4748f44f5612d76eb344ffc412d7934d894b2152d65397c1dc46e4e5e22f58eb359be0dd187e318f886f88cbc4c677c991ce95a2da04156bc34373524f5680fbdac2d6e5befdcbe242866f3a9c67e3d02d432978faaec89756fd6de37476c15f4c78e7434c77c21b83e08a2056e5df3920ef03a340ab1813e2d8b479d24408fef260b4f55f7281b7ca36b600e3ec0c9ecbdbe6d88f6cb47566ec77a5c92c7c067cb7475b576840020e6e21cd74c180d92f5d8fb91706a31cb39438a06d1b7c928e3391a73d36daea60cdafc6260281c853e27464b680c7f3e051055b34f3fd67b16c7b3c42f3a4b677d554945799125d0c2a54ef6b6fb4d5596d8e4c3d7a7acbd2c2dddfa4eedaa3edd3fe03ee8abbf63283cc3004f9a0577b688d6bee982fc4b25e4da7c9f2ab94731a5899a7a9237f5ffd58966c2cf30b634ea031572e0ab84d0723496314e10a1c471805635c4df68135c9ca307cf4d541644768117ec0e2d1019d7b73b43bd658c595d015ab0ae2e769ae655dc55665366b77acc11c7bf615d101dd5a6f1bc70cad4f6e3e81c4b6d9f1bfaa93210654d30be1ec5fd599b3afc7fb37dbbf0bb1c4e591154c962986f08208d35945e844d7db0a0802177f870de3fee8248c81e2b0e26708b0054e4757711d4a73c1a55ee0ced5d588241e1378a6fca335dbd12f5171db99803d355747e8ea422cc3aa5a26b3c57e84a7017a437a5eb5773abd4a7e9acf4579c895163e31572dce5555b6071d6cc8395696f32586e76f271db6bb33d8db9e9742c1aefa0b4fc4b994175df6aa48d08bf573cd893438c4c512e565cd5fb1f10a94c814bc2be759220a05219c52e3b1ffe7a317db1807cb64b2319a0cdaa05df7d8eb57872fdf1ebd64e32c17d67e07bc92e32b3a592ed1eec7b7579542406009129c6b5272e3ec598ed99c57a2a86ce74d6848da307bfffce3cbb71f8f8246d106c636da731e94e3794a78f13c49c4bcfa20c6ed24726f611f6edef151c7a8db1997782778aec8aeaf490042ef75e5eedda664b053e049e8dce2c66fdbce1b14ecdaa3ad7f3be7e722ef1baed63716f07da1667d0339daf2de44d6062edea0ca75c5a11dea34a792d64992267b5e4eac77260ca304f9d92cabb24ba173bb6cb4856c0edcfbd8e72a885c2802ac4c2d67e7320736a61387ec08cac0b2aaf9eda14d64c51c228d67309fd42c10720ca7a41e8330fdc079e9315d82e47db3916533768029c747d0b31e69f364dfec17d9ac26c318c7d318d6359ba1f311d247dd81d196610d8011d2635d2eec6fc7bb5455fb2bbc09fddbbf91bea12db729c4a10f980e665ebdd0c5521b7a6426c0cc117b6650cf86ec2d184674b0ff9dd0914ee0e3db7a8887bf10e97fa5d76f085c081ed4bcc36ffdd50ac96ca1c4a7481801ae0d9b6bd7325ef3158699d73370c581d17fa00ed25df168d28c1000471dd7fd033792366dabe3ce0f102c11ab3bf0e58e774e3c84a86c5d3e7f70429ac3ddc8bc956ee8da7e341c764006661d9003503d19dcfaeb34c8f7915a9cd5b9b53134f3e071ad377a8a7b53506f2815cb2ae54dc6c18092600721fb3840f3c01efa7df7ae1bc2ddbb14757ab8017ead78659117629f1e670d0d1f9b269e11240e4913dd151ede2f83e6fe4f049403471196d4adbc18c596430ffe0db1e5084a49a4809b2ef367ac93e858f0a56915c2e1618d3f7e0a6fe52cb4190db7dbe864a0f37ba5481789209384c13dbb78660ace93d485e26ee8280a5dda98a2fed44809c9a80b8e810ff58814e71b3aa166ed7a1841410777b2f94b04d84e41afd165eb5a26c33d81974ce196db095f4898d98323ee81c134e95e889aa6f93c58c96b5523b30d0ee6d04687e0e09270c4b852ca1c19393a35c20e4e6a6a31aa45d2b8eeb2b6230138727a4dd32e41818d72417369f7d90173870c07e1223232f7daf18646c8f92ab9fc6bc4ef37af3efee182773db248e03b24f09cd4ef43302f63bfed1590bdc98ba35fdec3aba1c51c56bf5a9c6f9ba0ba3dbb519908ea0da545f54294d9a5488107fd52ca59fca2d4a806a10ac43ebc25871aad4f45b77dac501e610d96d191aa6e0c6b6bc6c0079188ec52608f625f47df8e917e9f7d32b1295d9f3ae6e91e9ca721048e3023cac01fa6aa38ce6d224a783329d2896009b77546af80cbf6bc14975075c01bbf7e22dcb0bbcc57197aedda682ed833933a04288b7d7cde98a1a71274123adad26b00e542fbba514de1718673246d710b630f67d720a0779e15a9f7efb76696635f56e89a87e2ae2a9741d4da525cbeafb9b8da0f018e28a661e4f4f184f590e51aa59976925c3768e6e92988ceaf0af056901f157caea6b2fa25e793d017c33a68f210d926fd0c3e650c2ebc22c68cb44b53a04f986056111b67054497f9d230465749d3185d7dc172ecf78de67bc697ec8aeb33cbb95c542cf9ed4d3ff9edc3fb7ef2db273613d554a6ca046122cea8a13c86c81d6bb498a558c233eda95002aacc8a09aa0c912f9a98e77a45f546459d11f64e4f6d25d63b7b260be39ac2637e25fff896f2381b1b9624e43d97f9729ce5793b76d969d4b1ce136cc3fb9a7d22a67bd0eb6b76678dd6c2cf7be42ffc90171889cb76c9f81f76c354ad407ad7cd9aaaf0ec1b18a03772a8580173f76e5041e04ca389d8a3f2ba70ec45831ab4bbaef6fbfad0a4c7ea7541cfdfbfc238c786e975d9686b51283e16a32d966763912c935c287625d1c7b1f1706c7705409ac6012fcc8ead899594e318a64c59a79bf0343ce126d2f1925dc1ed01c42f2321ead9b9a8ae84288ce7787c117c254ad61e3cecedfdd8b1bee4956e136f932cb180a8e1d68091261dff0e2028b1af0544b4c72044dfb1c2d79971f3d8ec1dacb1a3ad7af9966158f0f6b8b1cd4f6f8f9efff2f2f47b9b5e594dcb6f7db78f9922f5d6f61b66a0b5b2b66f43c477f7e7b64abf0a3bd64de52dfd0808aed550c3b7e1e29b5a5f5d5134f295b4e5e4acebebdbf0bd1a9474ca02058c0f9c6104efa6e86641ee5cf4cee0330a3e13812393abe7f30c8bd30bf6cdf8fa418d2fe37fcf586ba5b4da217043806b946f3a2df220556f5946696acab63e01cf66b998f06419306ebd8599e83cc8bb4184f0db197a176bd8167aa351311a152df6a3ef61f432cd67b4f03d6f004c9019409ec3936a254155c7b3029f018fa5969775576a831806d5b6d791d833d61a69d016fbb1891487acd5ea3457b692163d306bae3e2e490bac69b081a29beb2780b5ea5a38491fa7420b9c97c1deebafe68d438e1e7b2db4680a7114513e0551d20897e0ce63184f79cbba581c9ff766a28fbeceb85a16c9b6a3866dd7eaf654ca0bd50a646d277da084fcd3011b3cecedb2540a0594e94e9d106e97ad5a2a56e678ae180789015d80805e54cbd9202668591b83b85fca0b3cb16aca3655bb6edabade825451932670d56493c2844f0f659a6cccf0c40c2fffb15f84077f35a3703c6cbd18d1a0ebd85f5b2edcfa562b0abe6e965670a85b66e753c3a47ce36cf0ca9784b938faf9d38aa9b85d945e3113eb7772ef51fbce2acfaff1b982ac2713ddc49d2f56b2fc9851c3d05309b381e27ab31b6fe376c275dced30354762b748294d5a87d03d57938ff17508db5fd3f2867ecadfdba3e206477e9732e3cb7361b16c98939fac7e9fc1b9c26f96e2b348169560725142e2b67353a54ff0fba4e02b439e730852c394d557b8bba5344b6de96a2a1793698f947e472363390b2cf003006d5b2201bf20be1be60ed4d7f39bc0685595342a60762eab296adbbab0e1265c1fe07e5fa80a4d8b8c22c19ece12a197db682b44d45697b461cf6dbaa0e60e0f7a9f7dcf611f998122f91c5d4fea4930c67da32d125b9d74198580b863a3ad153aa0e6ee4c44b5edb08e3d70b7c6639eab651d5b4732c281f83ccfb324abd83a5d95d5cca4a212e54cafbe7331e597992c5ddda0b08c34566baaa412e23a582a21061344fc82d5178a8f17d2256b842c0ed7d50e8981105f4b060e36823b35c7c06e8278ebc0b2bbec8b2fb9f20add192513fb8ed60af38e00f46b63dd4c16a9c99e2c52926e051fccabb262b96d92bc95e99be7ff797af4ea4f6f5fbe38dd1b9cfefceae3e9abb71fd9011bec3cda7b747ff078772f546521a5bf52edcf5d662da9f476f219f69a65aca9f90c7bc88e3e950c589f2194feb5a447bca6329fd9ddbb6c093f972bae06d098f95214d54b881b5ed622af9b0b232d1f18278d2e2030b4280b62ce2c8b7668a1c0fcf597eacd176aeaf22d4599152bc7d42c5a8ec76b2af2d758aa37ce72dd6b7f913a6d32a0c58802a610f1341d756222aa61e08bb65d77e4e1c3c8fb722a28a744d52ec495b944444fe7e9cf59a5028b4abc3cb470fb3564d52d46eb08f1e3c3acf665bdcd86d18ea8612c99bb7c7938cdf2b49de87f4b5184d7d8600bd0cb14da04789867ccfe3ede396143f755bfa10062336a56b4e90eef5b139e278b1c1dbe4638833b5debc8e3076802ebe8b2d34359a8c54c2763ad1fbdca174510483537c0add353ecc7b6f1c98cb9dbfa3c3559a460a5d83a3d6d910abc3b6d9042effdcbe9e9fb4f1f5e9e9edeeb8fe83555fbb4ae3d0e1958db5605bd0eecea35b07f02667d6f4636b8a7c1b304e62345f91345f3eb08081f67e3d0301fea06d7bc96e3ea8c804472ea113b0ad614da2672478fd1c9d8811b484d17cf0c0cf88df5b359c5bea049560d19a518135cd83ea14d04dc9097627c4c66ffc479e2c311766d152c8cee831d5b7750fa86ab55560f9b73e9ec827cdc8cd056c70e55e6a9b5c988cbef8790969fb05aa51120611181ef50705d6c3728db6ed7d5db89dd94fa6ad80131776ef2851943fb7886b5551f9dba30b8610daaa97f6cd8bc1f0783fc362b78fccf6cffed361dccdde6463b300e02d865ada6810cd9cbcf7308098e760e64a731defa38287c5a7b83edf3ac82a8fa1351f6d8ab425582a7ac44d24b8700d6c8fe83455a9f8e6b9cbd18471404c4901a3ee88aeae1d617d0dd8add8851b7fad4c3fe8ae578fb03aed0413c2e11b21785b5da079a863fa174d4aef164c7bfc88e53d9871fedc60dc9329fa6bc981bc59ecba88fb7e61aa809a7ddf7be625fda5db531d9bae8c6b4dbb03359b8c69d6937de9a7683bd699557a9e6cd69d7dda707cc1062741a808940c9a1dd71d453eb414f16759dc1ade29961bbe7f8b0c0f02b5b214dbd8e568d5e33ed00e26ed844d322b2e3b5e61ed10abb6dd08c0a77e1626ad81fed44b1e64d7b176e45709257eedabb7f8bddb101e3245416c9d8f72ab42ccc8148c5f433b0d6b9beaee71a9d7af3116ec81a9a8d39d3ee37c7ed230281e10b017f08886425544fe2535947e7c13bb835b8255cf2ff0472bf2934d81f84e2f1780d8e9bfb6d976924d09aa5fb2dfd0bc29f347513ceabb7fb22a767aedbc7f115fbae3f4036ecc09db6b7910a8f13b54dd9b29f559bb2634f49bc1f379d04ed7edc9477db7ebca258a7410d1238d1c4331e66d80a86ee5770fcc670bb29c80d0daf9ee1ed55eddcbcdfe0a6122a09f46c5fa33c136ab65281f6dd81a4bf9821bc1133592e7fcd5425cb65d724be9668fcd565b9f9a59e97027c995b90f7bc9a3a15e1148b6faca33340215611749615d97693368046b98e5e9943f5c153f3c6776debf06c0049d939afa61fe50731119fe71691bc9a6e5772bb84c4009999fa0f9e67a9714100341ee84fb7335af7062fe6d675765d69d2ca54660aa4972cb11880a4ed421606b778c36a5e3ff5fbece3bb17ef86ec8389ab024ecd9b16802c12080b98f08271a5179021c8c1c31fed02c2126ff94c34e911eab9ed227cce9db842a1cb015ce8263730113960ce2ec406f1774bf3c669865dbda32212cf1bfa34dafa20179528475bc8e8ac01fec7a960f3c5799e25ecf9fb577023315f54155cc7e35a60d235ef0de0c1eb1554d8d0fce681d0f1788015ad8e828ef9b0592f2af141caea0daf9269bc51d3bcb6a6f0823e7409192a83553164a3ad3eb9d65994799c34e7259f79bfbfb0a9aa979f79520d996dc3bcfceb8fb646f41ea3e6c80b86d110e83354bc39b5dbcaf8ebf62d4574b4390dec84dd402de31b9a48a2665a7b36ddf6d979f5cf14e3ec3cab981c33cea63cb9e8b1df04ba85a82453152f2b13c00618a32c595857bf6f23708249878b4ce0ade7c12e9fa3116629c04a93174bf6d307810f309e2a5793b94dce8aaccab8f50f01415f5cd9aeb1e5c4db4b58f1fdf9424d2116a3ab086050c2e345ca54a6977ef2e20d1b67a530317f509a60e7182e74ce4b7d84ec42dc50ee432c4d44c5389a109871db12baa73fe13c3fd57884e6c05c954ed169a6de60461477d064cf310ea9ddbbbcd1274279b71e3de47a668dc761d57a8b0267c9059175530fc944f96fc7510b6a1877b8e96cb9f268e9292fa40f2314766ed1e7adc486adadf1505a33325815293d50251b16131f49636dedb7c44e0f66db999e07d2793cc638ac5b13823d721bab68c287e7494d5ae8af3efeb8ee5b3aebb0e0338a4fb1b1aa6d8d4324bb0ff99b0e8711bb78874d1a3acd29f51aea8ee80dd990d29b591b417193d65d89753c70d8440237d39bd070d5ced56e28dc733b16a92658df41d7829cf89cd5ec8010fab2daf7d25aa575e823c54c955f3461240a3a19243a804cad418cc3f53a1525824618880bd071c66bf816d39eb6334aa006701bba88b17a7a5787a5158c595f272186be951234bec2edd16e15161f4f356603df2eee20b7465ce37ec7010b2d5d95507e6bca30263475eb01760590f687c970b4bad5929cab9582377849f3aae16f7b4fee1f8fef6cfc787c8387e36b4533a37f8ef3baec58978a9e92378a6e8e849a4eb4f4c6347a4eb87e6ba3a85eb5c17d1753b693ee2d2902561a33d1b58c7a1d03a303f923d9588ca0989919d1f365519599a8c788e9065010f7724550143001f9a44479288b7156cecc4ed210ad86b10bb17c0d14beb2ae553c9662ae79eed7cb33edef6087779a39df4fb41f4f8d292d9add5b9a377ee024d8eb729640e86e46ea005f6ce0dbcda92a0cf3ba3983b8b382a7fac4e2b3030ec79507efade6b318d8c05af77e3f5b74756dc0131d6c6dd5d5f8cd06575d4dacc0b5f0470bba91ed812c20bfc3ea69f4140b6f8d9b64c4afb5c96dd8ca6b3d32ba75d69018f789d82baeefdef789cdae130811770d5337c2d7c6ecdb3f248fe33518c258cd57d7298c4a399b83ca48afe88512a53d0f17fc329b70c8e2577c89ba3bce54520a5134b853780f35d1703a9a7e6742293eb13e437ae6d36d283af1077dd4b700fab78f00e7330cd0c18159faec199cc7d8d0e7529ddbba0388bfd1866305e19e497418bf63d574dfe58110a547f3a2464b909a13fe84e87acae4a2521872df8a82c8e16e731c089a04400a3861c3a1453a859872ec945453991a778dba94552d9ce732b9d8bf5566207cd1890d864304069fc86794c8c3f04a3aa1578a5c70a5c9027bd33684d169f0526b977a50b9611eba32bae4631d8897f12d21ea39b38d853a0bdab176688fb2619fa92e83761fd941d87fc35ad6a2a7dd840ed3ead0fe08c52ee7fee1eb6529b25ccdf5d82d010941e42140e83ecd048346fa6e92c934d13646dfab8feda37d808fe7cada769ff0642aaca75597f03a9b65159859efececd08c43c3ed77f66b0e32b21c2e9340f74c2cafa1d8b14e3c71cb89a4b9f7de13518892575233727a67d3337563bdc4dd00e9cf4fa4d78e144823ecc057bf4f72a1f48f3f3618de5370e248f37dc8fa0d143078f6e9c36baf1337ac5e7f83be1514e9a212184c1bf93ec19fa9c823b06b54ef0491509767df5e4e8574d4c0c7be11b092e65298635dec86c3776d41ad9a79eb84617d9e4d0b5d2f348baa32e109c3d5b4660725fbe4bc949392cff4e120010f217077c58933ccfab669d5e6f1c669f44ea9bd2ec1787334d1bbf19636bf92e1ce0a9a7493a77ffbab119f6180e8ce0a3b8edd5a75f6ffadadd5dd447cf3e60acf1bfc893edc2757e9f8086490deb4f502ce9fd936606ed8d07d9a8b105230f71af4f072bc1dd2c9336b3bab6922f66919acd34a76431aebd9353b8c7cd5cb6e78f3a659c430aecca94057d46a7729366495ecc085d56f5a784161572f1e881c6d1edb1a3cfa18d34a54feeda7d38ecd6622cd7825f2658feae557ddac986ddb5d98c456eb444e8a6f20be5f0e0a36f9953df97ea9c7ba647abd9262bc4ca46722b651bc5333b668d3eaa240064e7d1e8a521762390c7ad1bb104b222575626bf195086914a92aa9a9e80f137c2cbf681256f4ca5c21ace85d7258137f4ca6eee22de29381afe9c58388cecd22cf0f8366a107d29bc51ec85a2df8fc30303bb789964b77225d0706bc1e6d8132c7c0f44491922f3d9ea4a209a250e078d78949ba894323b399811cdbea4ff441a65d4fd503f5aef05c0d915016a5bb162fc4923c5043c7c4604c13ca6966f01adaa38014518bbcf24481550ccd5faff55343f8971ed24359ef874120edfd3008e4a0c340e6c3466b02df0f834691cf41af96f7e05eab41daaba491f51a853b28e54426e4f0218dc0c3104c6992d55c5624ac9177f2b434d9b1aeafa3a765b6dda6bae90e35b4198645d4946abe9cf9d5a5c5c17fa9a161a00b275399d41fc4679e54140c121c5c9c6de11b65ac00a6de945955a42d4c214e98230057646d73512d3edd2edaa0499b481c3bd7c168d9f56d3732065ca7f6aec51e9802a95ed5dde3027d8ab4cbc8c9cdda59e8b9bc7b17e714b93ff1264e767b0d6dea71d9e63bf41d4b18a6717110b34f478710f73c9c5344f990c51368b131f43fedde1678d6357c8bf6a217b020cb8662209d160c64660e1558ba273e8bc45b5d51051300ae52242dca9c1d605da15b5bb8a15736afa7f22c1118d6c116357658860b3b43ac4549a70457cdddbbec8e016fea48b36d58b06cd18008c960a1d0d501f4cc0280ed58746abc7b17c767c8863d33e9439d1c576d8885cd65695e2943f2a70faf2da0333c333f680d5753514d45c9f461525668b184f50106f2a51f1b1ab4e9f96c58096226610beba2c96f2471cee4f1855882d72ae70e581d03e4c93e2533247f3193442ad57b70c04cf1845777369aa997b37985d6dea52856bc18365a6a93d74b4042f6a01ae93bb5aac525cf6d9117e2d2c11b93ba8003681ab32fa92d5c9bdcbf7efdf5d865dd35bd3d7fe2a044cace5cd619ea5034119cd9f6cfe82b76176b090fa6f80524a8090d8672301a19790bd27fd474882943c3c974d253f4d1b1940b6693cc79188cfe5cdfb8318e15787ad1c476a6a7f0ac76a1163c3234c637a160d1a00521c285ca8a492ebcf6c81df1a87ce18c50ff281bd40d2ee900ee6f764107b57ffb25bdb39ff88a18731bab5d88a0e9552f3f0cfe26ca178d866fd7bcd4d41df4b1b94bf6571e3f0c7a359342bac3d1e2b1aa64755ebfcf7e3a82d0104f19cf4bc1d3a5536b78860f84bf50b6d96150a159cb5e7cae198b75297c07f4937648506a3f7ca5653d0c07e76f57243880d78d37ebe66dc10678d3891a839efde09a240ecae9a9dd99e81dd002ce202484752e5d2260676c43a1dd7aa1a09808baa3f7f072001d07f28209bde73030e9605c1163e025d966cd7b982e5368a9008fd0b231585eb5d0a2c13844769bf698b55739b7b87bd73563ec9970db0a765d822022b2040ff0becd62d259410266c83e8d989a190a77ed3bbda0ef11ac71cb29504dbe312fb8752b8e574287b8ff687b82b79d1912f278b60217ce26cb153744f2ccf2529701333bfc5f39642b35b1f5b69e7fb8a9e7a6969e1b5df41532f5112fdccc0c1bac2856c6c26c8e8689b27efc882906ebdc1609f3558171fc20c48ff781db0247847986278016e0a545220166e8add046014479c995c6d7376efd32a2911428da376a093d2faebd21f49a9f6fd01502b37b376ec7301d3731b82a56d8a891436763b7ed5935cc1cc526bb7f17c3b4a657a3f658181c369a5e976ac0689fc7d5b45680f1d3fe1464589b6a6a7d1a04df2b61c5369484572de7c218cda53549fb1f8e0d24915b5081405f8d075bec6f8f041ab2f06b07d73ccfb6efdf3fba4d56cbdfc8be3d4092139d35a5f81b2077e1d2652d2bba9b13a2a2183346ef70a8a501723523255f6d59b2cb2c11e0dc91777a4c23de58d7e64b54be14928db6dca3a22d64bd1af7d554143e76b12c04937025b83857e22f0b888c890fc85a7f0805dd59819def434e889a00558dc821b19aeb58f198d3477c09ae745296559b22a6eeca8da7e96bc1d3ac981ce55c05e62e44cdeae3b4369951e0276a259a1af8992ba1cf37ed73f3c35f13921b833b36d729f582735c53bcabda65a3bf8d8ec7e52bff91d50e5ee17da1f7ce5795d9fc0fe9bc3e419da3a9d8ca8eb91bad5af77aa0937b370658e717e60f4052bd251371573764a32daf400e4ae39f3ebc8edf1b86c14cfdc13d363e703943f2763fb8f08d67835759f2ab715f88f7c36fd7045df732e177ab34cc439f7f5568bff313be5e776a8c2ea3bd695069ac587b2ec67ca322ad92f3ed5c5c8a9c3c0ed208d44d8fb69c16459f5eb78d33fe73e3c636c308c2e80d9727d5025886e14a70ac35e1301d0158f7605dcd4c7ec768a9892c530515b9a9b22f81c134c31aec98d75eec9312e345ce663c2bf225ec9442a13159914235e0c3a5dcf6161e2a11052f33a962452045f01fa00fa4d56da016a4e0ff1f7fcf44aaeea1e7d0f76828b6f6b9317dcad433e670e2a36c7b5634da7affe9e8577f82ba696ccb7a7cf8039afbf0f2fdebe7872f6f6bf1b57d63ddc447dcc9529a00b2ab6af93997c9c5b754b2d11b304a9eabd4cb1e0bb41b8db8e14980cebab2af51d747407eb05b58a49d731ba62fd50c492aa0b7c4e666a309704547bc738e50a1486dc75043d100e74bd34e7cb989ba9004367c56238748d48b34219a679b4bb4d7cde2506490e568bc13558417ac7eeb8d1bf8c60725d19cef6e30e9bb2b667d77f369dfdd78de776f99f8dde699dfdd74ea77379b7b07b6aa17f12d85ed4683d27d05e80f81bc4450d2afe3a4a1d6cd82ed924abaec78b46591ab2599d15662fdec778303c8491461d719c3fa47fb4096bf9682bae7f689edc01e8370bb551231fb91503a146e328bc405a70f21efdfbd27be5ebc9a6d9518bf72d10546d1f6e1abdbfcba9e91c3ee1400981dcbc14ce430125c475b1339daea10889f7972d104a5d343c85f6479c5cbb409d864517874dc10740fb7370701ef7b0200d8b9e8bdfe468f851b8210d7df0fc7c6d2913380847a3fb8e9346ac2e9cef7472ac4e31d35d68b5b9a5969dc99ac7269b04ee7fb7526a0141dcd12c0dfff2570700efa7bbd040ece061bbe045e63a7e04f2310382c2b55e5eeacc105039adea8d0e102de05ff114713a86893430900fecd8c15b0faffa5d60a0db60a7f0b4b057bc1fff73255683654300ac52e12debe096fa33b18194999b00f7495441095c45367a737ce8ad4bb01eef7d19797d5171838bd132bb417ac24e3798e6a7dafe2e445caae840d1b75c58b8ad458495695d964023156d9029f33f64b812faa213ace95b44bcb04a032746555eaa436afc3e7958fe6ca3e7d78adc87d7c3346827804fe5a9690954eab3d0d3516223e8e37d61e5e3f9ab2d16b056b43656ccb82a7a2d69ad5665273104d0b246d5cca5950d61aad6c643b129881f85aa39718d42092a6df7488c589b33771b9236a1812886fd6b4c0acf05c166e813b52ded4142530baa999a4d0e0e9ab2ecb710dffa1c281e38c5fe91869f5456fb097478cf77fe54590e58cffff4dd0f760e77fe75590958d9e5bc9689a4da6a2dc96a566cd9e0feb2d21494c147996cde6f056f8526849aafe8af52aaba64683da14863d74903ada22e068f9ba61b85db46fedc053615bf7215d2f870d2e3aaf4a3e9f8bd4d5f401e2c0e07437e405e7eb19cf34915807f6eb4fda86ff1e8fb61aaa0d8ed4ff87a424981f3a297a0658ff7bc4a635a327aaeae8944967c2d93d7643fdc278d834d97e47596178751839f0255ffb98ff5b542b0d104d1e7a7ddd4ea32b6ed86658d318bee124191b6dd1936573bc3eeaaab97dd865c15eea1e202e94f00f9e710e7dd23ee1090b25acff33ea08e02b7174c73e12a3ed46867c9d3f82f0670b5579b99b3d8520b68f595630648d159e6ae9a83621f810c57e106e19db2336e29862cfe9aafeb9d0e787f5c7e08f1cab2204be87f732ff64e8b383fa0ae45183f8260c7af13f12f267e4093f1be203ce08c7c0fbbddfee7f2e5c93c17d03b1d68e7101f193b39c35175e3737dff8b69dbcb2bdca8a545e1950f752894c0038b2c9e539cfd98181264ff62ecc0b701368f614ece1cad3f34596a7a7a7c67b8bb17dd1697afb0cb6b5e4773564a3ad43399bc9e2df8f88f25ea899ce7979c466325de44251bfeeb354e77d7af382ba68c75f7a70d8e163b834bf7b97d14f1ca950333246f3fc10a5e99f6d3fd901e9f331a9e324d0d52891c822e5e5724541d3d809fa63872806cfd394e5597101f2745965496ee2908bcff39c67051857a4a2e259cea6f20ac0344111dd482ee1b684ed12c508344a5523b5a0e140e9bc14aeb816e341986b1805c87450a78f9c6e14adf69d1a9c33e67c62ba9f29f730a65c1445d0400dbb50bd7d9d06cdc0238c6a9a1513c5ae64d1aa20ee3b2bb3c9b4ea915b7b3b403aad6e52ed920b630b87de6cd10d55d7f978e832f35acc0284c622563f6b056aaed8e929661e5a91937a3ee9fad5dd25a24197ee735dcfb5bb2153e99273139075bfff2f4cc9459988377c3ecf8ac9a70faf0f3048062eb7deefaa37e37308e6624f72477c2cf4c113a22d39565930ccfd2dcb7308c0632ec08cf77bff60730ce1bfd169f33d26aba928af32254868f2739e5c60947c8819604a2a78afbac8f39e6bebdf60a7605f2cc80d01ae24f6110191432a0f7aad6bba3107cbe83af110c7f68b49b5fbf9edf638ba9eef30c881e26bed71427e0ff0f5b8c3e358893f6677c87ba09b4efd292f4f922e1b876e2791898f310ea50b8019b89b0f5940cb3e83786e7acef441a08bdb1f5084d138f859ead2c7ad767a5bb5d5a8fbc393c485f272d689e3f012d1cf63f30cb2d8aa6a7773b3aa5d338dbb7e1e77cd44ee9acfc0b68a5857edd6a773f7a4e96d164f92f8828504aa1cafcc6b7e231d85656aa4ed7d58d74ca83c2baaed3453fc3c17ac90db88d16dae5436c14562c317f1e293122fdebd31c1757a7d97d2da778d429837f4be70b498eba4208005852a12d104322aaa72e9353a35cf1b135101b7c82e455304b07adb269c0233d7fbbe16dd035a45bf1fe163bb109fabed3c2b0033b3455e65063171abd1586ee9057622f4dc6250e9ba8362518fa7298444c61b7651b65b955055cbb946899cc8b872a598c94b714b51dda78edbdc5802c278db5abef6efc1f487cabc829dc55d3a6373594094fd2ebc7b926585babc338d9633d35ccc716b03030d37133aed2d08ab26a2f83a2f3077efb2c8b30b30ad732973c18b16a89e83b909445088ebe426aba73fe99d019f578b92029894fd9ac6cf184c301adfdd33b0b007ba4f3aa15353c3d46ae99d9e4217afafa96bae4458fb0cc0553d8060d3d413b4921aba7690d40d966d9cf814c6863ce3226f78a3ae1e44838919ba9ee43a4d93de85c5bbf595f4cc4df530ecbd69e3d6166a64b5826dc675688e49aea9eb38de9480d1d555445cb792f2b3980c99733eb4efc67dcbd44f1ba6dd2ea970221d557d45b5a668b7362d4dd86da872dfc70d8c71efb69c3883c47f6ba8d1156bc86b851eca4c349a4de7f01bb8d7fe68ed6b826fa3a8f0ca25c2318e49a3d5be1379a5de72e34ba944bf6fed56af7f4ab35a1d1f86c0860fa5b036b9157afcfe93304cbfc0063c9fafd8d985589e81b10daa86cfa8205f6697bc128154ff0ea06ecc030030ae313f2bc9feb210264a89834795f40d280e34b0fe6b1ce3183f9895d4c3e94547827b37ec83f90d363ae4a492552d6586d2c5a853c4e54a2fdecb26a242e4b56dd0ce0bb16c7010e3a2af52304a177422da2610ff33537ce845663bdfa8c4e8e1b42b6c000b6314ce5abeed715b2da007ae8f7996f24a1c61aacb25975f4084eaa892253a5937b72934951663cc7cf4c0602528dd3386290e623cae838cc701cc3803661902e9448a3d03ece21f46a7bbe6ce1a59a7cf748600eb1468c5ac1e51c289122c90a65c4d7beccf62c932658050ad86139429740c61ea9363a6b75038d39a472f3dcc3200cfe37c087e97a94a0565fd4a2a5296e94c58fb3c77d681a6be2face558458b1d3c65c75f6c25de70b6cb92eaf3d0aca79b1334c030de0af5804b818c4d530bae437371d6b6478c512df0ac2c88612edd186cf3d068f422dffa4cb0c35c79da6c386fba427a1e3ecf4552e1d5f7b9609cf93ae257f4c6c21879a842af64c1988f5ddffd290d24385b26e8d66615799f90414f6c61f0c8db261315e06ca8ff097ca6d4483d3cd6c8f1f896b988149457bca83eca0fb0f93ccf7376e066c69585d377cb311f82578d9ba8820043fd3efb7396e7593161324fcdea85d8539a89980be073c144211793293e82ce143847198ec875eb8694e90b34e028386feb8eaf99b39a9fdb54e4a2d2c33b345854bfc8128a1184ad2265d233ddeeeaba22e32f04dc88489b6323a2a0691ad990dc19d59464a8f2c8c097a8a9c7284bf6d98f3f669dd8040c8fb206f2383be9399c681a6a2041fb9faf5ecdc1895fd66583303402593cd1c74dc30cdfb24ef4d6d1b850a2e5f1b5e8036ee10a35bd4a584395ba41dd31ab465341b5b1ba8a3d6583a081a0283b302e4dbd01186216cf75aeb200cd374457f6f50440f1f5aa184be6675cd3c23e3d5a7b28472246c915e6559fbbe1b83a6b5c1b45933d6a7c1cbb4ad6216faec3a486fd07e63f1b2fed03de8512a0be5a5a39952bc7ecb0ae963b0c3947bfa2bc14e96f5a2cd05b444b16ad2e6be9b1eabf723c6e21c69a166350ba713ec03bb9919da65cbdbb2a8c0dd1b21d143ece022737f5cb1d83263b52cdac71f09948bb263e6e56b92b9a295760f0a45b622db8a489db83bb995670f5624f89a093bc0352fae1949755ef77c52e777b4f7a7b9036adaab91af6fb575757e038a0fa5df5643981bc76d261bb3b8327bee0a12caa323b5f54b2c4d7c61f30d6490a72341a07bf79f591bdce12512861647aa21bc7aba02e1bf3a49225caf3766fb412b5e6f438e72d728247b91bf701bf6fb267ac2e9063ddae557d1e64a0fff4fe96cdd96b26f5026875f699d1d481a28eddb09b76a7c386ae6fd81c76cd6d42ba7398d1e3b3943d331fede396a9bf75e22dbfda26ade37bf147f5731fcc6d4745db5dff9a1fd7d70c9dcde3770fa69120c82463e5605f75639453d43129e66a49582f49742d84077dcc6207ccfcb87bd7fc8a9747cb9c9e5b1d982f0d72ecd24ed8d0a4351d30f0c2f977f50666b93d2eba66c281744695b57940ea38605f2c1d0dd9971b76d365e3a28d99dd88523a71428dad4d4475f8bb7a09b9bf947206f7c4739e08d62ec2e6c1e2b4a063babe6645e0f95de6b23497ce5f46a52e3bdae27af338cf1762b43564c7bbf777ba6cf7fee32edb7df0e0a4eb808a2afbcb425c4db3cac03dd0707b0fba6c7740e1feb2e090bf0315c4b5fc65c167bccc0aac63b0fbc8420d7609d45f1725ed4cad9a73914d2c80ce837f76770840a6fe62c703a5771f77d9e0c9430291c35b39eca8feff20ab48a622e5f94c1629a90406bb43fb61918675847dcc17e23293b9a870a87b8fbbecfe9eee0aed4529af0acc7ff8a0cbeeefeaff91ec45992fafa4349dd8ddedb2c1e3fb5d36d8230d253c1595ebc993075d3678a047fb900c09786a29162ac67b00231399733bbd839d2e1bec3ce8b23d0a234b9e7b8c403d8fc3fc629ccb2b51ba0e0d767445f79f68fc3d0a2155965f10f402cdd1594cca6ca6646106af11bcd365c1b096bc584d6c292f2fa2191aec3d09f3690d83bd270d101399a7a228cd1c18f4eb7f06115cc99766267535e69f184608dfdc4e487606e0d64a2ea6fc22339dd1f98ff7745d8f42a0199f88a2e286f49e340f5ee6d9a5f07d7afc002aeab2fb5165b2e4c584aca6c1fd7acf65994c3383a3077b5d06dc61e77e0804dead488fa23a14ac386c674f8f4a5732d8dd8da004f77d1ee8253578ace9fdfe5e04a769d9cdffa3dd2e7b3868400280b9c9bbffa8cb1e3dd1ff6b8412eba1aa45f99785cc9423b9dd9d87fa9f088cb2054df41a30202721e6f3aca06b03d6d0a310445d2c29790f9e0ce20590cd3c55ee3c30eb79b0138388f520329d90f5bc075db91f35a5a5dbf332332c75f0e87197e945b24708609c6be641371058b0b0db104218cb52a8cacf30ac354d2f415d8b64aa32eeeb89b9ef8467853a97a524ccc3fc4380a65255a443c0806a3b9f6600a4c383906b86ec6177009c57734d42b57e12601b32ffd07cca1674f64e94b914792eaf0c6ef70cb3a3f4e027b1b989a92cc4321557f1ae4a313f95554875480b94bf67459af1c22ee35d9dff6457ff2f049920da1f3d307c87d67029cb259dffb8179ebd613791de0840ce2fe17d8ae1131666f74103cc79be5053bac500b53da0805705e126bb40d7bbc104e462268b649a8dc7963779c2a5eb24cf2653bf0fe3340d1e42ef2220b28bdedf699a2d84b25bd32ef62adede00c8911fa110ec1afc33889b76a4b83b1800d789588f01f2ec5537bd07ecf57e1deaf6aa22827aac2598277b1110e5fb00f630e6fb084619ff9eae49b399c1a3788c942f0e50667b18d307c0059c7f3080ddffa1de766a1d0cb8ff5ac84a889c10c143103b35df8947134c985b09bb01966722906e76c23c8f0c438b7ad7a5208528084198d5e401a88cd0c84467bc94b2f06c25dcb16722cd16b358a2dfd9355d09e60561637199ae1e84a052c4e3875df6f841445408365f94f3dc34a8f7e2c140b73a7812c305140344a577edc160af0618c80a835d10a990f46ba0f3322b2601cb06fc0e1edc8f414371e01160e649241621244a044e3c7aa2a14058a13dcdd2226031bb4035307a0a5554facc3a23c723c3af2890aa96a554f109697797ce884c12aeb2223e453d26d351f04bfebb8cf77438a73cda0bc096540aa7bc4ee669ce135b7ccf9ee628a1829c1aed6eff2f7b6fc3dec68d2408ff1564666236257ecbf20715c5e738ce8cef3289d7f6eccc3e92d6069b20d9a36637d3dd2445c7bedffe3ea8c247018da628c799ddbdd73b7731d528140a8542a10014aafce269c1274a02a540c89d14dd24d54cd807ee7cc272b3b04910697c3b104634719547992343b9e2a9f0cc01a93947a8aa061ea0d5b172bd199dcae13e1db940ae000d1f9e2a65ec88a50474e567040a4ad2e7d88c2bbee23bbe5d242bbaa705512363b5123c5eacd6b319b57960dc4f2950b1b626c0501aeb0f280e57eb3f06c9a7e5e95ac92748f90330cc8858adf2ed946e211f8206bdef8905d5024a3d399255888988634ec1a476424e9f50b8a9a3034913455eeec81e5ded33bccd4691efb8d5f90fb4e1e44ca6924fa7a920a824df617bf798029175d0180654c44a9e4d094123b93c0f1fdcef307ab4e168bdfb0f94f9fce8a103512e449a52cbe8d413ab321159a636907280e4d24d2da7324937ca088301d6ff2110e175984e4b4fefcaf2c7fecae02fd323cd186a91f82b74182873175cdf6a0caa763ce62040ce0aff10ed5bcf4caeb4e536c412cf82ad8432ff82c65fb548ca2ad5a7300ff4c66e4846b8ca97bcca6d57e47af190cc1f576f48f9c0d93320cd904d281a7868491388ed42f08a2c23a8d61f53006f2fe79ba800502ef3ebda611d95a4a02534f0cba9c2bc6fcd1d09843e2178be996d44512ab7e2f0d92d39533627b8fd23b83048f1c2c00416edf7d94f3fbf793e76f0aacb6df07ed7afb48a648949eb54dab228e9891efa8c941d9617804adfa50104bc8099cb2a715e1422aed83b3ce57fa7f23096ed1ea9a502a8ac4bc126f98d4102cf7eb1b19fd6cb8928a27687bd06a729f94b5471afad795308d905f17fc46eabaea6e02d9eb985ba161082d51c11abb365b8f8d5dffc23f56bb16b2bb8cbca6be0c2d4c26750ec5c362187aafae81c494bd6e2f9bd77858267dbf3c998fd1a2f789689b41cb3930e4bf9047eb68af9a40537bfd5a24c1ba116656aa0367ba0361a6adbdce262ab5b8c97bb6b07ec3e0193850aee66f7be11dbcdeebd824a79739b29d76da6f1a2192a5e68fac58d0335b45017ad85b8695d21dc350e5433ac02d0f03c2b93e18366702ca7d0a3d35bc047a7067e11cf9bfa76d15ab43aac15cbffcc0dfed52a15cd358ae10300c77f26962eb9923413254b5b571fb54ee9f7d922990ad6d3e0e0aad543787d1d9a88924ca3653e15294e24106c671ac1177f12410d3b8de0a23a6ae9165b04d705805e59d8cbaa7683bd4cca32c9e6cc50ac2f6dc7acc58e913c703baa601e3a6d62bf7e638bcce5ceadedba2d29de6a4f88afcecf3d52cc50ec23499322470b1032c80f58b26552aae455cd448156d2dc6b6cfecc02ab0ed740f1bb02543e3ffbb185811c3cca410a6f798d0cb935e464d1e2d361bfaa3c4ffad3c7f6dd5029a9b088f08342a375b916ee623ee92dcad4894054cc276ab4602162e7ac984f2e0657ac2f17fb335d30570543bf60a20a467ec132c9d839fb2baf16bd6592454587cd3b6cd2b6e5fcc694f39b7af954a4158724a337ac2bb1999285f9559a5fe9198a0886feba818bf8659219415ce8f4d895f2d902673404e3370e5834675d3669b33e92e0579a072b8dd8318b26accb8ac68a9360c5fbb262c1ba6cee55c4fe2c280f17ec88497bffe4c1a04dfabb60dfa8c46488f4f85c42502ce0612807e418dbefb3d12dfc2a43fc4ad937e76cd03b75a0709cfa88e61890d07a21c8911c503dac6d4aa832da2e161d56b223bc874bf1c795f13076c579b34f9ca7c9cc8a30fd6342fff004eaf3cf85cd7e494fc0177bc3ba7ba68b048a9daec6c4ba03ae4512432c47f781142589f5980df560571fc990639326a19d16c6daa8d3d19355fa6ca3149464adfa1a4785565b73fa75aebf4ee8d789165da404e7e086ac189210a8d1b5431698817e9548f6f4a4cd8e61d4e5140e569e842b8f74e539562e48654bac3bd3d45c1bd61bb16e821aae4be002f2ae87e048cedc8e663a4e00b598e15ff28f8699b09d1ca4d803621c10603b37ecdaa9d70f404d316dd939cad9e9293b7264d8fc0661d6233f01f86ead0e4e0ef3dba94334c3566b86c93ecd20edfc7fcd4a17db35cdfcda995fd7aa03d75493cbde171d60c21cff51533d4649ee32b9245ccbb90c7f5d43cc579c9a4b0d326f04d96990491308e168acd9b9d43f76fac7b5cf6013944008e31828b2deb2b74dae93959826bc9717f3befcabff7c1da7c954f0eced34292b9ec5e28faf7f59f3424cdfd68b00ab1b1c205fae3806a5fb5e0145371db673fdaa229c1dc0d855be8d6ee48076d9ee6270d561a3363bae950fb17cd8543ec2f21194cb52f354914a97da7fed1330dc724fc187d9dd7d17f3094e1ef48847385f9bebef74790469c36c2fcfd2bc1465a559c3ced98b6c9664496525cf8554adabc1a7470bd091c0f1c2ed070cb226dd7f3879b9e9118304bc327affb2eaf721fc984ed1a6c6995969b0f8a6b687219128e613f514a8ede15f88f81a5f95952c1565d9917f94392b05b80ac7c8165d035745d5d4370d5c265dbdac1a0742a3396b82fd3f4678aeeda05464ad092c114d83e92a3e854f8aa8239a7aac9cb9131ca1ba22bdd9bdffddf5680643c6cb72bd14ac7cf5e7ef804c09c8be6583dee0fee0fe297bc2cc348da2821dcb82d353a9dd86f0a3c346bdfb6d369646459f0d47bdc72354aa92947913a2f93e44731791247dd28468b20fd1c441a43821374051c18ed8a0777f38ba2fcd8f680e7f9e9c3e7cd0c62d85fc73f868706a4dc19dad361a8e1e906a0f87a723526df07034b2d5dedb6a83e1e313526d387c4cab3d3e55ad9145e2a6b636bcdfb7f8a67c9f318212e5c918c09c51d6dcecde532b63a73e117be5bdfa44ec95d4fce256e254676e58ff9c3d3eed0dee3f54cb64ff5cf601fe788f7f3cea3d7a7462e0cfd90d0ef7e0d1a3d30774bc6f3a4c199c63163dec3d7cf4901db11be0e2509adfc3e183b6598b770d48762124bb0012d9d1f70d48de8790bcaf23d1fbc0e1f001b6d265c307805d6eb34f070376c422b929db59611fe1d71debb2f7be48a41dc63b6c5217804599d614d0a24c890048a37251a6a834f45e15f65faa0094861e1918565530f20baaa1fd39b23f4fcccf623eb1fb304ecf094a6f07b401d778b9ddd4eaca7676c3535866e03f57744d561b63675f5c8d14a268c88e5919da102b906356b22e80961469358433852396b2aeea179eb7b373eb157de62ce4e4a5cac9194b54741c68ea44324fed054fd811eb46891c7cbd3d8387a127ded6a63a393eae6f80aa136f67539d74bba1934329628073e8980792c195e449548d64cf866d76c410b6be8b1aedc131aa839f68f0d1ed4de27e4ffe790214b8d86ab5fd1ecae52bb9927b764ec5c55db151f0ea53c33fb2689a1abf61529478f8468ec7e8691cbf89d20eac0256df961b3b498cb2383a574707a5fc89c73fc3367bc25236669299a86ca1b5a3736c44824808f95b0199b33b0648e484308712c08b1427227b82635ec241549f45291e59e1df63558825665a7987461bbd3c6d9a96a745b90968a74d6d0836a89d6aca69531f878d2aa88dc322d14c9fa5795e448b36fb1a854d01cc6066765d18537d259500ec8f37a84bba5a97c8d25feaa551c98ed8ac6d61aa0618f8356b6b481869638995980e255a246622c5bc146c30d6f3c268c50eab3a6c757546a08635a85f3a6ce3438d6a502b80aa1ca893109444e740ddaf4149a27ca8d310f5129dd1e67539f10fcb9be4e43788c8c69b991b7f66a6f4e8bb4c5d4347afe923100d39cc50aea63bf9ac9140874aef4bff5ccd3533bf03b3176ba6f69001ea8d0273306d3cb9edf7e1d460dcef4fc5a6b73d81c382b82cb7f0df2e6c48fa7f5c6c27dd2aef16f309198deda43e6bb7137f34b693ba4db1d525b54199a4aaa4362a729399b37359f7984d2cd313574be21c36bf32bb95511559cc3378bff92d1b6a630171d36574bb90ac84ef4a6227a9fb45db1aae3a910ba75617ea484dd12af50a94b22ed2acda8e12768f0d6e0643937858913053f567b4b94c73602655c68675d976d186e8a769920908b45a896295a798cbc09e9cdb4da06b831bd562358b7a10372633f5c1d8513ab0c5dc9cc186323b83ede37671c62685e0d7aee201c80c21377b20470829cb086816803c712155f39b00e47da77568b601f2d4e99186745af74e870bb4313a6cae7f4cf0477d758b97bbebda44911fc94c89e5e66bb9bbc6a942c57ea94b6a5365a74b6a53e55a979cd426519318a8bdfd905e780c3b2cd60bd3b5dcbc5cdbbdbb0fb80c014e0280bb00e0a7f1f566f7bec6d69bdd7bbaa9353bd600eb70dfea15d8ddeb1d1917c9ddf8496f747f809b7fd9cdeeb0777af210b7f1726bde1df4ee3f7ef4c032112a7507bdc70f1e3d36b586bd470f4f1f994a83dee0fef0d4f213eac099c643dbd0a0371adc1f983ac3dee0f4a1b98fdc7b8a3338199e0c1ee15478c2a2080e49f4e9bfdcca161d894e1a87bdfb6db941c5f314ac21a7cd111ea2a8c6c8b9ceada8e7fb51cf3dd4e4a4e756d493fda8271eea825e0498757fd06145bba33765f32698b9859934c14c0ccca7cbba7f80d324eb01290fc8b76bb47c399df9af3c9d4979fd4837e5d492825310eedc1572f5c9bb2b949fc8e8de5869b042a0e8dae9cddff0411bbb7da60791b33e74f058557b0f63d2651339a50603b25d8270c0747c4ec889a15376e394bd77cade9b3218fd913b72bb911ca91df05f8d0feb33183943f18d57e706eadc34d60101f1eabc873aef9bea404b47de8438a213e2c89f10e6acb6c3761df63e3cf469bcf83d867e61d72ceb4d112bc21646e5f18a6723a930390e0098e6055e7bcbd1667d847bf9e2ec2efe2db1c65ffe52541167478c4bf39b1db149605ec41db60830275ed4b45e1a2f7ce6c40bca9c587d1aba17e6f213618ea7eb08c3347316b867911a59af2cc80298fdb1fe16e765b428ac0230056592e982437440319ff4d025d4e92e04b976af7620aab6e73400df3c71806fa4cbfa1670c892cc06e3664f4860eee1151b7bae051b24412282b496e58675bf658ad27c5525cbe4bdb3d7c046800545becea618be11f409f5905280ce8e4731e9c4112418adac94fbac9301c21db328220d4cf0d2aacdbef946dd0f5f561f1885981388a181200085020853684f2f8190e373e6cabaceb39d9549f06c6bffb8f6fb0e1f2173e819db0a134be83acbb710a50729e2d9944d21834326840ee9a91025951e3e318588496b485961af177d618bbc333824aca385a7dd28a7a3d3df4350d54e1dd3b1ca2e634a323165f342ecca98a782c153af4a009f309f83828cc50a4343cf141e885a8249551749257a2ccb8b254f0d067894b0e025bb4fd0970b3e15c835eb0c35874c27f073e25cc517ec1bf6881c6e2b460fcdf1b5eb58f52d1bdd0f808f4eeae7d958426434029fc44770507bff615b2a26b89f1c9d8c1ae6cbf081992f270fb45e72049e1db1d376db407940f310507de241f9d9ed530125aeb667f324074e9c9454b0afd97060e5026345dab1baa40f2ed4813564ffd57f3e74c60a307e2bf5901d008495cb57efd41f024d09fe2bf783bd537bb5e0dc45014887d17faefc4159ae538892f87fff2fa5e498c1edc7a0676fe3613fa93a750f8b65dd36b9d6d0d329d270dfc2e1d51ee889073d6a82a61b14f478ac2f564a01ec1bca3dc385bd3f97824b2efa70e5c6c22e961db1a134411f9d79cc067b2176188cd5ced5c433fe3e4b87a9e49c0ee0e5022fa7d36980b304362ac4d20a245609d6031e4be0af6be5877015165c71b36f72245925e60205844c44a569db7092f8c30fb8ce3d6807574ba5811dd84716d4871c5948c2598c34cdce3541bd2a57efa8860fdabd2affdb6a258a67bc14115a46aaefad01fc5fab57ae278822c27fd40306391df0437d1d1537b7690e9d704d7e76098292a87fc1bbb341f7f1d5af0f3e7e30bf4f3ef61324129e7500a86f91b8f7bbd4f34b4ea7d79a195057ad78c6911b3fe9171a522b9dd83b1ca73af90b62545651ab25695f4534b3362feaeb87fcca8ee11fadc4dabd7fe6492631f8345b195af1a2142f2005aa69b9c3f416daa8225d41ea98075a1a5c3544401ed52026564e48d1c133229eff8b5e47b8af1f1ce7f0b6fb4ec27d47e17888bb90f1a2c8971c5cfd5de77a20b1e0a818ed0e642d88eca8caf4b2dd5461f036407b912264c8a78156706c56da80e373be169ec7f9a5f726a1f06023fb3a43d1a16f541b10cc3d04ee430dc411e80a02bb8f33540f8ed97dda3709d93f5734c83fbe56aedef4566c2d946bb746a26ec82cc71a6fabd39a50ba0e0377f70e904b9ff59a99e91168f06591d0a39edc9a96ec481de0b9bc7221a2616fc0ba2c6dd704400a57cfbd728a52382e956b578c6eca50390e3f0a01b708bc2700eecdf6ddf1d7b9b6a971edc08b5ac2b7d2dcb1867817eca2799581b3a7a16b9b43bb16cfeb17a1f1dcbf088de7f58bd05815d4fa3c57055e9fb14760e9f66afbe68b79ed40796e0f949d3560853957dc75cdb847440b69785b2f1c330889fc6e3e6dd5f58e65fe724eb8af2f16a92345d26ef25f901449fec87900e4499ec0951cfc0119c406c12bc63a862dc530bc0dc3288061d08821747d78721b862dc5300c5e55d6316c2886c11e0cee7d6d232b1d145b2a11306c669eb323bce3aabd8589e454d0c88fd972ae760d1dbf78b8bf78e4145f069fcfc83955f3ca72e6d45da78e16e2981dc3b470f55a48756cf074d8511db1796fe5ab0b98de464becf37682aea59fb96b104298760b5c9f418b9f510debae2bd04176ef1ef3979852f5151cbcd27660354fe5164eb6a06a5325ebd4061d9bb6c34a5671edf69785c0b5ed3e257b27aedd220e3e7d7ac55054429736ed465ab775b3d5f58cd936fabf34b9bf186f1267ed000710a7a3b5b5cfda8e07af7ce0b24356be79534721aa407d5b26bfbaef1a2ef0a3f2df3b3d3d39d5ca41812327822523bfa4e1f05c0237ec140c1574ab00eb9b44db0150b353f0bf8ffceff5f6a5cdb86f77aadb57fb741c5addcd433f36348baac4fbb4b98d125cf8552b4d98bde9263fd6d118a3b91951eddd5f1813febffda8fceba0002685c05a36a1ae79c72c048dba2a71ef30144e3a1cb56d2e399b91f5f10846ee56d45fe0d361ddddff6b8e51e44c919dd9b3a5c6ceeba972ac77d1c76ad72c95c789a32465057d104cd404443cd8b86186de0e8dacc2df3df4c8f6a1461ed4029c2c7da8931ad4260075df87da865a3cf5a0a4c806c01e786037bbf701a8871e54ca434d3ef2a120ebbc0ff5d8275fdc84d83af0c0ec2bb61aa83f04782c1f82f487411dfb86406b6311cf4360fe6080d20e01fae321651604b97f24450fd223d92494f9ba1225e32a9a4c9543f63248ac8d9f306ffb65253f9304d90b5e41c276a83f650bbe118cdbb41def7a9682778c57158f17620acde770e58413404c59b9cbaa85a892d860efb1379244832b2919cf745ab4cb2a9fa9095a7698e0f1c25e63959558418afa89a8b64264f0b1352bf2650b6eb25a55de9218f0201f7bc7a2248bd375996c445bf59486e032fdccf28aadf2b24c26a96065b25ca53bf31d304cc5b47799613c2fc35d481fffe782af1611d11273f94147c5c2e37ef5f8f89fe54a14b35e9c2ffb9811a47b2d76657753766779d14db2aeec6b374ef3725d88fe89d93b62574c4e2b592922ddd0c7cfe6750de62057e3ab335793273790609c3eba019231504b799140882d73906adda009f9434974a2def012c865121779375f551d36595798ab2b2991a3a2a701f59bd331eb0e3b666fc60b915563c8538ddf3e064c30a054bf7126ac1559e855f77785e0d36ad19d254559bd2d052fe20519bfa928928df8ee87d79194a2bf42109ffa38d251364bda2f6b01876e17a6267a01acb37291cc2ad6fd568174bf65ab7ca55c0081cdb6468f3c17d6d6e97691a4824550d92c5af42a089fd6b273c4df5be5ab48bf8d820bcee93f79ece640f3e5e542e1b8b28f903dd131480e921eb7615a1d733a59982c9f42924be08386a24fada56d0ef9642d67cecf5977e8bc65f600143add295b726ca258985a286452832234294776aaf18b34716d03d1fcdad99149922e36bb06b9eab02a770db1a0fd694aab1caa6199da86d4b06f0bbe7a668634aa7290a80ed2428478c5c16de90279a4c0ae141f24654a76cd4e3f73979770c5ab0b5a3133926906c3833f23926d464b179afe4b5acd00d4c1d4480085c0dc3a9904fc0afee8b059a62b52fa08205532b38c2c6c700d542da841377392e0c0e2e8988bfbd44848d9d81d2b6df5d78f84ab41e58fa37cf6db94beaca4c6c954b413b6365dbd112773554faaf37350de6d67edc872bbb0da5e76585ee0ea006d24985eb7ccd7452c9014b358c4795625d95a0728203e081a99214de5166f9e178105c5a239ab0700adec681cbe103b73f415df46b38c9e6f60f6f21fb2a67d28f104901c35c9c1d8870fcc7cf5f8ac7d4b8a79e9b3696f5e40ac8d58ebc90003b9006b31eeccc4c02e186da52c9f954aedc6e8bcb2a61f64602e60fcf3cc9c9fb52c2c84109cd9485f867bee3c75e66d60904db5a01e7d2537b262fafff438a1d347898e3674b432354fb7a255087c0e2137de68c4033c31d0c1b3ac67ea94022ce4241636d2236e4afe599e294f3c1d691642cc9a9a0eb8dd78f42c2f54aa3a4d33c9a24738e2293f043ed06691a321c1f16d347500d39f836b3f957a84fc9f22f36a6998e5c5731e2fa2e6554b076eb4862a5d94f6077bb4751a624792359b18c25e48c93bb4510b2ad9d0028d35a93d2470737c8e3f42cb3214fc35a4f5b1aef1edb37001feaa45c85978c18a4124f595b5de517f89232aebecd63abd826f753d5c8e505cdafa288ae4f47b66d63d85d02dfe892fc59f865f92fe7d49faf725e9df97a47f5f92fe7d49faf725e9df97a47f975f92fe7d49faf725e9df97a47f5f92fe7d49faa780be24fdfb92f4ef4bd2bf2f49ffbe24fdfb92f4ef7f40d2bf86c47df5978cbf5e668cb1b9a85ecd277cac7f74f4d7bf94297e953f3a04568352480d68bf6d11ee2f5b0bf7345d2d1025fcea48b218630b7183348ded4fac53cc27bac4fc34259c14715ab612452cb24a173b7f3a10dc0371b02ccad450a57f9a124e8adc5a5b43b1f9892526b59cfaa187cb1cae2bfe2b2fcfb61a1e78afea7e92dd878b9133f8f323fc17fc562693829d33d6ffcf3f4617bc3b7bdafd015fbf76ee7f6cffa99f74747586aeb135c0071f9d3f471fdb4fdc7a92d5ec9cf5ff53fe787279195d5e9647d1c571f7eac9e5e5f4b82dffec1cf82d7a32269f2f2e2fa79797bd2b2c6b3fb9bc745b5e81d36da8615af36bafb13b95dd8d209b89a21f5d5e6e8fdbfd3325cf1b8c7e4d9f5ed96a927d43fba77eceac5c7bf10db31cc7b63358305fd839bbfcc3e51fce8c5cd867cc2e327c8f0c01386a18b0ecc496850259432879b87ab4578d8c5919c08b46f3b2187126f0e247fdd42f8cb1ca47fd03c20a29625cacdcbdb98c0c7243fbb1e9464705b352fefac3c1a06d1e52d006f1bf26507590d70b71d32694d43835b29c6a64efe76221de7f47093b62a30e837fd8311bb53f3f333f2707e58ca42cfc7c02c58ed9f02ad071ae617f4873aea1ef6bc843685e89e2f3904cb85ca348d12f87b1777afabbf4c3c90563a5424b283b972aa32a7856a267d3e51fbc7ef80f33065775325197914bd30b8ddf02c332a59f1878e8eb3205ffde8de986e3f06c3bc23ff5518dc3312085b37bf718675fe957ef96e1c31a779d6244cf7117e5e0954d9e480a387e75c3cdfb4bb9349a7ec3528e0f7efaff29ed8bc03a1b3d194fc55c2e4a0d4b5af36277d852d73f33a484d56699b69b17223046941a6d1670dd55c3756ffe0fafda300c270f066435640c9e38921a14f948d5911acda99336d73969aa63e521297fe23f451c35ed13366463ec9f2326643e2d3aacecb0b4c3f89519d9ba886c27bf4542e0e156ff3f17dbc97f47f9d84e1ae5e377968eed2748c7e45f2d1ddb0e9bec978e57735f3a945d29dbf5f60abe4202ed27ff5516c54045de0c6929b711a57b541b5489411baa0980b8770ffebdad09b037023dd970f0440af64445e62b6b93006a19ebd55b212d464af727e3b0b3f37614fa0dc75c64a2e0555e94840966530ba6528771ca06881bc3212abcf5bbd4a3e7c6137ac238c3ddae695a9173f9873f5efe010de4eff3f504d7470ec1a2a8c4caffab010dafdab7c28c423091ff8931d9936fcfd900175f0cc358837942b0d34054eac565a8ca18363e7e415ddccc2181e634358dc12d15d4ce376cc83e7c609162a566b7fc2969ae0fb73d6170103bd6811e89623e896030d410b06376f9870eb39f86f54f23fcd486cd5dad4ba1a66b7d721c77a9c9a314ade9ac2b694f4ccfc7beb9433ac43fa147ce689162ae3673e1ee3a87359f7914dd539ec6917402c9293f5aec78df3c7f252bc13c003a0c834e02a0230aaa4f1002c2041cfb5af170eefc35c1bff6b0738f04fdd7f6b641ce6eefacfa4b89c2870f66e83f7c60c376a37899933c69c0de2e5a12488996fe19162d7b0ce8200ecea74599623701a53b9de0939a4e5fd36f4a430407b9a1f1bbab08dd475f45e8ef8d2a42027c7a9fe4374f5b049544bf0f466f5232ce26490579ad05bcd7a9161c3465c4db0c864afe28932c16d6433dcb15d67225e26496c4f0a097df005e69afaaa7c100934390599eb27b6c282babe83b2ae129e5bd3ee495187e03e7b79320e3f17333dfb74a3da8043c94ebdb498de91872043ed538ae28add921f6f3903df1b538aecbcdd34d1d4f44f660c04db2fb135f0a48cb4b8dc82b3ade225d09c798428b3b5b2f3b6c99641d93d7dfb2a59e9b0100b3f5b28de0f50964ec1109640de112724664ebe5fe900da665692f6a9b0dd2e149860d805f12d558fe57372ebb171782578271962665c5e08908b04505a3cd2477d4fb3cc22ffd82c19c9f4838278ff09f86962584cff40447d681c7d1f2876178f8e6084978a602e5dac700f9e49fea218094f47cf24f9664f85e359f21b8ff1e349ffcd33cefc0489c11beabf6ebf91533b1c51268943e1191f57b1b9e2690139aa725beaed39fd7c82f856c3e71fcdce1e3a24c431f37818fdb40f578b9bb1e3b0768aa80e36517a49fa24f6ae4fe52f5a56da2b25fdab01cf89c8abc1b928c854743b81b6991c717b057a11145f56eca70c944392fc97b21604e29aa7f07fe44ad623e6941824dfbd8aab623f25a811d966c650fda4599de19ed76722bd66d8dd8cbcc41edf3cd7f6ca59ad6c26859d42b3cfdf7e103c3ef62ea96fc1666f6d28656c01d2e136579705bb772b8b769680ba3cc1fdecee69676b60dedc0cdf7ddfa541f5fafadb8a1ad78c7b3839b91f3362847fa5e16a6a87d9ba8b54852febb543663a2076bafde8d4a4245050a0174cf2d754a51bd5ef1586821f2de402222d057072342096940b4b913a24d23a2ed5dba86e31b4484baf4604c6a0843a890e1f0bcf490915a0b1da48870f94eb5172a43a461ed1d6b6f5c7e36d7dee8241f5285111cae2a934889e5567fb7ab1bde4e7a719ec5bc8a2e68b52b674e046a79a376a7deaab04b6466f04feeaf4b98b424f774c70cede76a6f51a6b7b7a70c01dbd686a7cec36b88c5d5a0b602ec037ceef0f8ca0d4050bbb5cf6ae3e04e13316da2cd9b75cff061ab564e03821e3b0a9e499f866c5843368117b09f826b54c3b56846a5f8ef048049d9d736d3d1a549470d11de205bf2c98301467963631debad36556ac4a126ae73ade4d51a128ede997588b1ce3a63477c1ac23aff2c899bbba3dc04693476c19d116e9be485c7d79f8eb0de69f506fb53ba5b47264d93bbe252cb5b5d62d47b854fc457671dfa157e22ba7a5f61243e11db898f4dce5eeb1ed8bcbed07d84bd6ff1d6f7b6bbeadc0dabbd5bf0b076eadad96b88dfb925fe494d798e8f87b5e69eb8dfad41e22379e0d098f357cf78babda13b32911c8adeb1a9ed1d05c31e013a0d6d6f639e71083dac197d9676a71142f9fb69bd9c88a2d1dc41ff9e902d6c08d1814255bcd30f26982e863cfda0c2863a0da7eb6592e56552850d2d1b8c6fbbddea9ce46f5ef5fffeece99f4783fe1f0b91f22ad90840c3b3584cc5ec309a218aca7ac9ced9850e0175a8afd1a589ef162f78a6928824348988fc5fba5ea22f520450df40a0fe93c7a3476df6042bf631f32c1bdbec9711021fab2cb512047e74207d6dd08618f446c3d10376247b83c7bb83dec3e1e9487d19e297c1c391fee28d409c6755c1cb8af21f446a74f02868145d58ff9d2148d7cba11e033bd64e04bf74bd1ce9439e510808628c4b3cdf026cddf0c552641a44b40694eaef20d31c085563e8d430022a3622ddc31b153c0bfaff4a25a687deea8fba02e98c0bffed397bd80becbe5a4f9f3e6d35c49faaa3b8df3b9582d57afab4c5c6acd5723a31e54578cfdcefb3ff78f16f4cfcb2c68c83b3225feab11edddff25d09633d1a0c07fd98a7f15a4eb76cde853e75351187cfb85df20b89287cc4468f1fdbb8c247ecf4d143135d981db1e1f0bef2381db89a46a2f9860d478fdca19226ed3e4df91510269911b9839c8939afc42dba6faf9e38f1d58371451c9d9eb2aecf121b77ae617386bb14638e346fcda0d3ee8e0a66a1d30174140c1d45c0aa09173e261fcd1103046761c2d0fc579e7dfb08936cfe0c74753f375d6a9f227e1b6543c3b1e1e7e398f86cb4753f376db815bb85aead3ff9f51910184c9a67dbc90174c17e4bf907eea30bf611bf95b09121ec76313b943093ebf0932c2abbe28603fdfe59a7a6faa30a609564f3b7a094df56f95b93b8ea929e56d9fc68476cd03ba17a77d03b7d4c15efa0371c36300015d3c586a7b00b83ff5cddc68c3815bc708dcbfa28e97beea663aca6f32bacd7d597d36afcdab7d194aff82febdf97a6e3bbd254e49537fba7f0f6b93c78fe6f30779c72d4407bd0e0f89a1c58a9d27380a62756f2efb1ce3ff75b5446ff0802b4b323f632c72cc4d2b828795932088fbd145985564792b1670a54c7b79e27d5623d81d8dbb2463f4d26f0ef24cd27fd817830b9cf478f4e0783c7a393d3079c9f88580c1ec60f26a3fb8f6783d16818f3584cfb36d062bc5afdf1c7d1e03136d397ff2c931bcae9657293e07d4e876d855c553d1b2fcd0b6dca9e79df4790844fd727a52b76ae907941339f40c29cb12a3ca3612bb79008ef88ad58d70474d64ea048058a60d4665d6d35ab0f2e9e21267add42c6751d57fa09dbb2318bb6ec987195fde59801485ba5a0edb3516f40dadd8e54c299edf0cc3343252fb4c10339a3f51f97d576c88e34b985984612f976a4bf8df05b270c0f67c4b51aea6b439d49ba16b52af85157303f14bb3c664a8e1f7b0cd5498b566dd760acf2fffdfae79f6ebdcb902c697b9a30cfc24b42bfcf7efaf9cdf3e8f577ed315b9749368758c15da8c1d00ba4649c4dc54a645391c53b56e5ecbbf56c260ab65d884c559a14f9b6144532db750ce225bfd6414e6749c6538cf1ceb61c704c92b9fc472c27620a7371c18baaf7cfb2c75ee72c1555ab64d39c25155bf26ccdd3942026f15379a5af44aa9c21d1bc106cc8a6c9526410c41362aa96b05de24926ab41deed0c4e1e4a8b15137833a54dd97691c40bf4e842d01e5944758c57ebfc41f7962ac272e89206c241f3622e2a1b49b506001f3a10ccf5ac163b7e55e42bc92f6c84d8fe728f871f7b0b5efebccd4c484f59a5ed0465d569f211fe4202d818f29795ba558e7efdd836fe4518fb16bdcc08a8f66a407f860b7468c0e8b9572da7cdcb0a3b8eade1adc55a68f72a8ad373987051e389d141b8eb289d2a719e95792a7aa228f2226aad3371b312b15c33d0c9098fd9f1aecaedf447fdf38090b50d97f6bd72c563eb0184fe3fad424c5b1dd602a5237f4855d2bab297eb17adc55ac8027bef21ff32d72a0676d3080b9dd170e036a4e1ccc507b6ac2e2d14a872266ac53b0e68d449bffc8987f4a652ebaaa9cb4b7ee3f7d88f4a603a0a99513130e560407b152a806e040a14d1fa23296e2271ae4d0ec79d0cc64a09dcde5b58f27ac484f20d6ddc0161f0880f9e6f6071bce0c5d32a4ada46a055c995dec89354aa7b6ed6c103851b1cc494fc687cbf7e2dc62a63a7fa77a2fee56336e8dd0739270f4cce1aa5ba997fcaa3e5402e9ae9819620fc650ab5204119fc618ab4ed6cd38426670177bcaa70521d037ed433a8fe0df3343ee3fe56739972b387f4fb52dea490c9ff7f6546c00e9e4266fd4aa930682d439bbda0005721225c8119b4af1a7c8dd4404bdae6f8cf44fef3912c310709a9d7233c720a4aae7f9248fbd5e3cd7d31a807577b3b23a6aa3b78c10f5d82cb51d32b7d620e2f33296a7769fd8dfd86162e92ab5b3aeccf3c67d692e4df838ef5151e7682bedaec89339ff5c3be76bb7d905ceb9402c62d9566958798e6674639c47ca5276b3ec31c1280775524b949e2200d2b9ea60ad028be83f88a0d36310026b86579a7a60bdbd6f8aa8d0e79e681adb43dcda77350a8ac5db27798b90b8d001419478f97daab19cb1c870d2c93024bd70c4a1bb837eb4d953a47d1146361e474c37701249a5829b1464dfc1a47bfae88498205b262a96c8c67cea25236f8ff00e7648bb0dba86f42cc42aa16cf1ad7755dab2cdb97ae77b169bd850678cd4d767f8e86b2ee8c5dba44511f4bf73ca191a5ca2b20c4d4249b8a1b7412b0ac2d438b1c5140b77859594ec98dabc36585f9029a0dad0a80d2850ae3252dd407323c6e621a0d0738606e0ba8e9ce9a39aec04d4cff00db89086c936c9aa3036fcb7047cb0116f6b4f7bf3e0531998320a2fa3f4bbffc3283332276c4fe173c63804982bb4ff3a6030e6be0540bbf68a3d59e2e3dcd9858aeaa9d9503d88cc63c6313c1d6a59876208c84b8e1cb552af00ff37647cae884c7d7bd4b7b3294e5f9caeed1e516bd7ea6f50ad825f7a4eb2cf9652d5832edb052fcb2165995c84db27ee6ab0fbe389ba7f9844bb55c247ca2d2c3c9be170ad5af38b93eeaef9a0042d93a998e594429b34b2b5853de45591dd21425d3e363add050b4a276bbb19b52c149717e0742f30ede4a8904b473b64e5396e5859d341d947edd2f58d94c6f57bce04bf6ebd1475c3c5897bd5908f5bbca5925caaace99499ea782678635f86c6bd47bd81b10ee24e54feb34fdb9f89b24840c20ee1abdf5566dbc55d21af6e103b3ca4e1510416f38d9dcc31e93430653324ee194642717573c0669fffe5c0a0850527a5ead1e73e48c4765ae20d9bd7bccf9a02a04dc4f0b2769953e62c1030c954bc46af03d87195aeba8a4b6d20279d8768e1e5a922a0ad27da000eac71d8dd4d5edae3b0eaf3a0689c48d1e5f487ff45f27fdc8e4c304ff2b2df8f7ee1d3638eed90f56b9fa9479c1208ba6506779216e3531eb53b8a558f303b4791b6ba2ba0a50068f7a3f227b639fa1e101585bb250b74025b9992d861d33165699efd45b5258b1df1d2a3d5ab31bac818a1471737d325e4607d6397d44790c357e2ebe47fc3ea73b4ec3b5c3f23d9a973d71691e9313c5660e232a5ec12e629e6c44c6de815df44e6e1750317f22f741c5b82380f8aa9ca5797ebd5e8185612850edfa68d4628fc6aac283bf93ccf03f80f2378ea9b20eef3eb44fab17b2e69e115666f7be8156465ccf1596487f769718bdafd606ed988544a941109ef1342dd9bb59f6ce665456722077242006b07f8ef395d072c0263bf64e5ac04f8bf93b48b2ac19522db45642cee277556396bdebb117336c0d5e915752cd29f6a0f3255b8a6a915b8475deabf1d4d53eb259a606d31ab639d8ab4189fc60307e907afd2326e5d3f2a95e3f212ff04205a82d17f93a9d4a435922ae5383eafe23bb505cb972e42b9f21bbdeb155916f92a9b47521d125a293f40273f68b9736c18944cd32dc1a23ef9e1673c74099657afdcf6790174eb6056a4323081800b30c728cef228551edbd9d3d7d4d8a7eca2b11bdfeae0ddd5a896296174bc8b55bf26be10eace224dc68a97d075ecba579be92f63e10acf0c2e4bbcef26dc6f2428a6296670272ff6765b2112ccea78245528e7058583eab440612592e656f35d2768f3db72b6652b54ab62ac44c14d8620ef908392bc47c9df24276236a4365c4c53782899baab0d20a0d966131f8a0549fe911ca823209f2c2eac189604985bb9f4f906fdcaef17821912c7f5f915448b5d1c02ed46b7889f5c50c0c988eee4bc9a4986e79218719506a4ed0dda3249c88b206e9b05966c4b9a31fddbb3bb80e4b45d661d762479feaf9dad18c3d11724c0869c851477b97e442d26fd0396f95d5bb6c78c61208cd74c6926ed7bbd653f3cc4e1fdd181c0426e14bb9da5d9f7f12194c54f9898da9996c8f5e2ce3d05c0d724e32db4b7668c0ce5cf6ca429fb50775a8b93b12e54572758583de9484f3000b5b4ae33b3ec055eb1d1fbed3b7ed10b004563abe8494c41564c2deb3472985307e3865c5e3eb7c238a599a6fc11d87f787f71f9d9e3c7e783f6c17f1816f14c5f972c50bdfaad7e0c35bc0f7d9f550e7f92f6b9e92175d111f74181ffa332b81a9b51974d8c6fab16018d081b4eebfe210ce870f74700eb943e243ff5629b06f24770c561ab041766e11a27c242020c7c7093d901e009c933d7e283f0dd527328d3703ba03315bf4cdb0f6d99140e8a89e0f846d1132a4edcdbf401f43135b112439b57173d62b6f9631abb63989c1a3960a4daab447d294655235c93543489ac6ecd79bf168f0917d75ae7e59b441ba1aaefecd8e7fdfe1dd5488158bf3d50e160e74c2408b315f57ec5a8895dcd7c38a2a80e05ceffb4b986938c90236b9f23cf1ac71f08bb9cd1c725d8422cfbd24b4222890ba902a2f94255f993a80be962f39a82eeb681da719bc5737df038a542170c19a752914eb434caa5fcfd835fb066acaa973ed489a723701f5790dd16a9c9e2a1a4cb9ab5fbd332240e5b3c661658340c941d6e19f96a2986b972ce730bb0725d2f653469d16335503cfa47b9ee939663c2d73b427273b847d9667b3640e02087fbf8e796a3e823aa767daec7fad8a64c32b4184ec2db649c4ec5aec3a8a031dd5d98e22c9753f552f9d2ddf690afd120b2dd3ddfcf93511abe092e6de3d56173e594246da6122d4c32b0c4be4996300d8a01e96d0ba7090c7ef0d0bed5f657b25ed116c1d095230f9e5124cbe0577d78dc3f062b67f20fedbf1ffc58c8c402004cb57489deffe762d764ed49edf3632af44bc2ee47629dd193d9e88d2aa7195845c7e4b3269f86383f5130125416657f0e2af2f7f7ef5e6e94f6fc6b68edad7037553987ab076c9adde6a0ad73c8035d078d3064629525c22d41f6681549b74b965418c25b85302f7a7d09d863d1afe73714596203da26db904292544f9d1b8c3527c917b21390dc063133f8d1b7775ba120a4aa17767d8acda2bef5736b5e551d323f198f1c08f74e3054d9089748832d3bc3d670d6b2a7ba2f9386617f88bce3765e42934ee8206fe5192a68eb43fe502d48135acc3ae5d03b43e2b81f2d01d4b7085521d63e7ba8bd29035ab3372de94a9719120ba5da5851add704236abf1ac555da7c66bb853756b021f9f26d95a8416e503ec0920f41acded805db1c76ac055441905cda278ab8d69c7e373eaa723b9a41c494d2a558e3e9c34cbceffdfd5d4272906678d6d585ebd536a656a78b2f1ab369dbce9f362f6b1e930fae96a95ca51865328dc81a303d7366779c1967921ccaea2cae702eed5a1efe8b25f9495dbad4f1e24b377396490e00c796846863aeef3e934511e14448ac9b879a21a40fc13ebb2a7168da68c347218e6bb4a83b8a944361d6bc5c2cb329967521d7ad27198545c5c79ce4e78d0de61c376c72a9cb0b53d2da55815b1a399a6a5b188ca22a6f69dd5424d72f61d2f9398fd936f781917c94a8efd421409ecb5d984cb2d843ab85ce65391aa5725a059bee3f1f5446e4eff59125ea9faf47405d857d616d2a5a8bf8d82ddcf737ce9c5ce19a92a2d4efb976f26b6e23c2bab621d5779d16acb2598c0923236dee7e0b214e4c0bf1601cec6db445a5faf8b229ff38a7ae951a4fa4dbf69fbdce95e0da7c1e744075c923f55158ac581cdc4d652655eb538e028cad47851e3e5d8178111b3e63ca288c2547408e36b47064e95b76fcbf54a146fdf863ba986a4c6312dc26fa7625588580a233df988f395e8e85bbf55213649be2e3b2c5e1785c82a3f3ed79e5895fa81c996170a2d3b66ad31bbfc438b1d1bccecd84ec3d6e51f30a6b3a6abc75ea6829770b3a3ea293a242a099d9595e0d35638522471617b1b4b7d6f06ed4c8531fefef9cb57cf9f3d7df3e2e79f5e53dfb897f41ec35c40c02969954c9234a9761d20ca3d6cd0b76a9aae1e3ada99bb963af4335503016dcf5590ec8d28e015d7a8f7a03740982a9fe6ac10cb7c0337dd1ae2044bcd76179449a825baeb539fce3ea9ebbeff29dc18ff3c73fbde04e4e01bb3678b225f8a0efb79250ade61aff98c174987fdf0c3b0777adc612f9e3f3edecb4a85f6562e3efc2d5cd4b413650547917057b5ec80cb21dcd7ab49a02660030bf4e2154470667386fe268174effc0f134bedbb6caafdbe5cad354704d425ffb331c477abb81b5ffcdaff1af6d468f6b8e4973bcc7acee199aa799acdf894af8c97ecab7c228a8abd1459268a56c90442eb0035656fafbb700fc19fcf66d29444507d9ba5a21715d0c00af0c37d1656e9134f6381d5b5a7719a648253dbad6619ba6b995c245e64ffb6e6d3bd75d851a0decfebeab68a5d593392a6fea81d68771f06b94e4615eb9fb341efb40d592a6a56d3a0772a2933d4f9ee925d0488a26eb76a5b4a5817d30ff8e43c5b4f92f8563e34f1e2d6da9194bd0a1ad778d8b17a7156e34b33b63b32a691399a3715eb9e4ba658928263f56f6b5e540731678fb0ecc7d08d422c3a521f1ae5a701e927f0e97641f29985c435302cc90e675833d36ec1d2c4b2bdd2d58cf513b9766729bb45da5e27ceb5625d54e081569c97116818f8ebe50bd667238c0c1162e56d38014999640194612ede4aa4eabca155e33c6255a3127a7eb3ca6f1bef734802fa840d6838be51870d075ac90d0334ffbcae0e443ed449ffba147b17d05761fe02431ad18397bca6bb264eaee058d880e80debb08749eb7e3635486da0fbb0923408edb3a46856d915fb36d8a3068583b252fe525410d3a3da233372b5686ad9116d8dcc53190dd2bdb737b731dd11fdc65e34b0bd46ad511d18f525346b525e560d0b265c9db07336ec3d1c0c4f1f91339f157984a4a3d60ccf7e7f91fd6a45c08088de491d8a7baca5d45d82c9b7627d76bfe126599747232dfd2f5fb4f54f69464643d6673c3c105d485e189c33e7902eecc86a4b98482598574e53fd5a201aad84be8cd5e71c2b7fa48c9a3e708cf6a8f3fff281226a46560a84533d6cc4ee9ffef71832ecff5e8df93927de61a27267e41884cf951b2535dfb9aef1b7c98b670947518961bdd0ac2e83eae3d39aa89bc94e63c7b2af8d13e18e4d1e6e9544b6e751c98ece5934ec9d8e4e757433cd86bdaba5675a3763527d0c9a2edfe5eb2cde6bcccaa5581d36f4f44840255cd9c343d58c55cf049826a3dec3d38003c1c3dee98351c30edfd41f1d501f5924396281912383dec3806a40c414fa36d4a3de2880fbf1898fbdb1fa8360fd47f73586ba4cdece5b903e9f723a867adc410c476a5e07090e8f3c54d3730a55824610bc4b500764eaac4ae11c6be4e6e8f6b35f2f60bb3d7d5676d0a965e074ee773aaa842b16b73d76ae996278f8f2850e4bf2f2c5197e7af5f4fbb72f9fbf7afbfdf33fb373067bd5e1a3812afcfee7bf7df7e3f3b7500db69c2355f097a73ffe603ef7cde77ffbdbd3576f9ebf2225f755c99bbffffcf6cd5f5ebcfafe35c5c6faece4ec90b008bd98671b4ea323889b555e54e59f86f5f808cf52c10bf43d1059951482616dc6cb328f13e0bdf23450ee7010aea1e61506147cc4580ecad1007f4bc1410f03f070165c3fb791add09b772823d30baadbd033d0c3b8bae901dc2b115711a64bc4926d32ad16fa8f0546e86cb8077f66a2255efe61c5abc5e51f8048ce0a11573c9ba702bd60201a0d44992b32519452ba5679996030919b0edbb5118e2bbcc89f32792f58a4c8518480a78d7965f1aee0d3645dbec356d35437506329b0e895c8a6a248b2f9b33cabc44d35fafe238b2bfd26540dd6e87ba68a9b1e92ea0a378cdf24263e509ce7c534c97825cc3b28cb84b2e2182e6895275923e29d42bcfbdc8881850ab9a9db2af17b53256478a016163455c311d1d5d4b8f365bece2a1625195b2537222ddba62fb37c5dd4860d34d18267d3948c312f5995afbaa998551df855483a3a6c925755bef4fe9250f868a08f9e294fc8fc5064bd721ff1c7d54d874961ec3047e63aaa4fce1ae57d5241324d3ca72453101a89d4560a2f1ccb39bef840ec39bb61c7ac700aaa5cee0176b5ef0546ba851a7a705d086483aa6c86d2ba1e5e5652014855ff269733b0ca576dc7af1068fa46b574ef1e90f28d42ebba1656373d5ec49119970e2b3aacfbf245877595bea6cfc834b81a2e03af403b6cb0071a9b870a830edb831d8921e0063d85278ed4b4bbb5ee293621d2dd9d7a732b8dba0a21901dd7abd100a19f301241a6d6983408b2e7b0169c8a54c6e2342fc54b5e2d220be0cadeaee9458104939a270acccaa0cffab4e0db97b97b3f00d3baac76a9d01359cf7288029ee499ebf50fee38373fcf66a590a3ad7fc8c5a8a314d52b4043ce090a3e85741b0a21fbf0810da45d49ac1cc75308c8216fabf1ef607e5c139a16606cee6b77b6d683c6fee5cd5f7f7cb1e473a1dc80ae5a3af44e1d0e9747035813aa926f44e44b5055f0ac4c79259c2134c30611d6a512f44be4180161911a942ef6cce846f3856a4e02a3ff70e5c0ca4b59e5854b2e6e046ade7d744492f227fe93d1ea1f3ee875ec9bd0718fefa125db9d887992593187efe536a9e2851a6e1a89ccfa20c4e97a2a4a162745acd308a8f74d633a0be4a45342ab4478d0b166b23bb142136e52087eadfe8a792958ab2a125cd0c7a149c98eed718a1c4388ac8f0d4b2bc5dc0a3965b639391f8ecf5debdba1314db2ff49ed1cce56a9ae5ea17961396b1f69129ba8009f6137407fbce0d91cb7097227f88e17f13bbde563f98ce07bf7cb9a4f0b5e25f1b37521c7ec9ddad72595098856b289a82aa1837797f8540edb2d092e9e2ef3b2625c49614f6e84870fa4b5a61bc6edf8aac8a7eb5894169fb4d9374909c1ca09426015c6edce0b1d7040f6dd3800ca7e83299f485a6417e3225161d15508108d0b6852cef4ca14ecb11fb437f754543c49cb0e2b8550f6649ae65b6912bf7c55d21108643c50e1f2fa3a107b3f29cbb528fba7a78f1f7e62cd47a78f8cd090b5829d6b857284dcb587b57293736ecde6c00a7359a9e5489b974a52d931d9f94ab195b84c9d9d5b4749fefe3a46d5b02e590259d72e83943c5046accbe4f28fbf6a668b45786c71ec28f61042630b39cb07c545883bde431c220c9853b4a33b8a6b0f5dc70e5dec987d9ae295f3cfaa0638f4af1922443060f05effdbab37c3b723a3996a6b9eb491585719293bf36ba406d8fea2cb22a58d186d4aa95a313120fd2378f25ab26a51e4ebf9426da75cdd473a1716db76bd1b61590d003a6b545846db4d0b4048fe1a814302d6001c96a04f118db8c8cbd2e1e0278f05a0faef3a12b73397d8217718b6db46a2cef1b2e2c5172eb9c0cd32f7853f61299255ff674a51bd2f535e2ec27b0267971732ae6b3dc546c39d0bd3e06ca966499a1a7d09fbd0aac8af45745bd4471aaa07ce459589994c857b7c7a197e338775f004137fab18980df0bc10dc3f27bdbc2db66820464152c2d9c58bec69214842f10868e84033ce51855895499a67ec9c0d45f7c119ebf7e187eced9217f304127ee1792b1e90c7f17ab94ee1220232c0f4bc57b678887cc3be85b67a7026d635cddcbb6700be41003c1c3c26107a4c1170a73155f92a8468a711a9d34a83c919e0384d561e47e04cc7e147ed9822b027a7d692e960c750d8a19dea321f42d1d835f014a7a4d193cb751626dc21d93dadb0b946e5c4f2fb6bdf65e93791b33459b9f7f995506905d4db4df5e1c7241367f4f809be1273937cc5e3a165329da6c23d0a82e787c914a7c4398b34413da9015483376e5e334f55e8da483a7ba26bedd8d874af573b4b6aaa6c6bb0b1c1143c3275fbc667952820b4f157c8c10f1f6cefbf722100a07620a628b20ce834b71faeaad9d509f6fb6340cdda1af5a6c2c7523440887a5dd8760f573f1935ceaef78928d4f183c948e78f0de42ece53d06c2fd5c77fd0e1a6003f899bea1f9dbba0fa8f7da8fec347a5ba576bd2ca4f90dc03d1fcc77e34961ac36fefc3aeddec7fa0ae27cfed0df4efe470a0ae93f17ed9753768bc2597b0ff023f03a489b000bf9c7dbe5e939bc103fb3e2df8f695ada516ffdf9d15a166e92345bbd0841642cb40d261f58adb94794fb9ad48aa03ea408a889055538aaae1a971d9f0f21f7ba89eff2f92f2022a5d819aa67f9fb35f3fb60d2e77eaf4fbeccdcfdfff1c6d4eda63cde016268668e10b3833a03d06ae033aac182f84ce20c1b32960aa16a2102d6943c67956266505592139f04e7964e88030b2b6e468615abbcc34bf7a921791feaea216a84248d53166ad623ee1d1a003ffeb0ddbad0e81f921cf0cdc1f1f3c78502bfc812f937407afadff22d28da89298b39f04e6ba335fe41f4f8b044828795676218be5e51f7c6caf93f762cc86a3daf76a978a316b6579b1944848b1b433fe22303dfcb08735cb45be95dfcb3118e697194655c07c257921de1271d23f0dc0a6e195288ac89ea7a22acd5049dc6d66390d8c58e58cb367af5fe3e712c3f0ab69e79af700d0654f290205a9e4f657ac8e11317c9cec3509f339151b91e62b51f496f9fb244d31d5b4c8ba7f7bdd9fe671d9ffbb98f49fbd7edd9718424a8084f0c5b180cb4009ad26132cfad0be0d3c84dc72b27640951e9c081e023803c96afb13365ba7a99e7797f6f5b3420e979a4f18f9e398b5588b8d59aba5d2ee1c2b5895bb5701abbf02d0866a59b8ba612da700a9d409718c73174f135e7a6a5bcd574fb7d7d3e0bcb5319f7c77afba8449734a3b5b98c8feee168c952b1127b32446197927fbd210b2fe83962a1a013f35334c6e4a57bc28058bc4bcc786bd071dd61ade5fddc8f9fdf0f46bf9cfb0f7402c5bed265f1d60a40a0d0d120b0e57c4490782214270fb324f37727b9bf22ad908ddbbc6d43a8013dd002538658c654804ed1d494d21ad7495f641aa59c859d80e06ca3d7806c936bbd8e6e5de7c1e554ed5961f6c1fa7080dc0c2ab780191cca2568b1dab54a93df81cf5ff3342b5f821babc9c1e474fc697973df9abfda41dad6e3e88e587afdb4fda7fead31c2c5f69941f3e68ec17c32b951603956c20e2a8e19d6f9beb4cb7c71ad7e8aa7623ad8b4e6c822c3cfe59dd90c36792c7c43923fadac26063fd73361c0cf69fe8b874efcb2d1198593a250868ed159f421618a5cbe16a705588ae34f2d618796b5a2dfafbfcd43e68e5aee7d68b99c97adc61a5c07c16269cacb40fdebcfaee47b023f34c645547a1853d5e478a2fcfa68a22b42f753431125c0942c18b8a84ac647986419706fbc32ce92eabdc6a11badeb84e517856e13ac9dc26f92f116f63be16f08801279f4987a5678110977ac95041c56a498be4a27d8c0935aa7c059e31766f69cbf0d4c5299dd85275f6e214a7b6180eaa48612d32293b07df3c89d156736a78526aabe6ab31abcc46ad402551980f48d9984dcc1749cc98a5e6ef85522c723db350304c6396b2635628121a66c34ba9e34b657c682bd3cd98e15926c1434a5d551a326ae260fa360c03e63580a9056079f19396b882196a193635afd72bb98fc085f9c8a35c2eb8e80c0d564cd4de17ba15a89060444a432126d1aefede5a938e75d9c362e2b4a52e58bd14293a7ae34c59c01d0f6fcfb390db042330e3dc0acf4cd9e37b9a40937d5f230861d3f1a764b172e6a0464bd7b3a8a1698ba4a9698ba3ad16414341091b03b857369f704fb08f97e8ecb58799e024652788eaa2343149330568ab568bcc19f8a58ccc02df68d48de333677acb4f0dd3edb9ec0338cf38198d56ebaa7ce7e61dac4d42081fa8157b3087908ac58fe8e454d429927452a6b203b7bab21710b749f9cda4bcacc2184d08d9189dd6553a0d4d85f696d711b48c8de5a6cd514bdda5499a420267b3770a3578606327f5c180c18f1e416c22e27ca95897892d76b4c9fad4e9860e2458b1aa4eae4dfda4dadfdfbce15892cd72d9bad68636875306e967609bc527f9ba42fb770d1f92ecb229a389acd78b79bc107c92426293bfab90a06050e4ec1dc4d387746438354c14515da9b77fc15676385184284a1da6c6c8248792b438dad134415281d7923668a34c4da95a8e056cedf63c0bca0245703f62adcd3e168a20d710abd6d4561d7523d011575a92db2c94a4c81207ff6a74ce9503e154300182f218851c6235323cb3a82195a347064d697b2722f647e3d384ce72b8ec3038bd2414aedcd61a244d06f7045e06153f8a5970fbbde4d5a279efad8f2047f55db7c9284134e78cc7555e94accc0b13df6a28e71bc46140deefb12fb03aac697bac60a5e1ced9851306fe97c2dedfdbd6e8e4aacfa7a14a0efe4b51f9296cec987ecd92da63735000ebb4eaadd6e5224a5c17675ba0f664347d0f1d2175db07949f9fab5f1fd840ca27ebf79dad3867e52f6b5ee824927667685b93d56b312b15801c119b459777d8a4be91e5accb26ba7ebbb7ca5791b75a2332f786349f0f072a800cfc76e2cadeb8d7e437b865d3e394e67309a11e86fff8f39f8783e770794efe96a3c4f4979f86b83b0367d0670b115faba778792ad82adf8a021e6b0d071d038587c253dc3dced29cdb475ae8000cc1d68a222f6866b8bc2844ac5379a9880412fdcfb3e1c04decaefbe4485af99200dfc0e09a17f3c341c7e2b21eea7ac523559f9036c78679cd1753722a933b99d1ef742db5b4437dd8c50cc0de7a13f3f837dfc4204d8401f8c5f0692eaa5755fa1482ef15f48a468ef53fd486dd8d1ea984f7661c1269322de2ea1f72ffa8fed50fc16ef46452e2588aeaefb8db34d8b6041b563b675baf9a5c169fa6c93ca3199fe4df9eba826fb8e0c622ab68d27a3acb2554c0d79494220ed861b7d813d6921b6938fec54f1e79372fd3350d977ca3cc973a9f6e58d759af340689ff87bcf8b12a5c344925967f2783e2a132c50eba8fce0dd95c543f564560cc3f659c0f1c4fa9c144992659d59d26a55cc9bb70ec9ae5dd75b62ec5b4bbe14579f7310e0ce0a78cc1f19dc6e02d1d84bbf4ac816bb5e109cdc72aedb0e6495954297be2ce666f0a8fdd718fdc5bd37c238a22998a37e2a6fa3e913513f0dd729d7ca6ba44358e5e3db075ce8b649e64ea0843cebca9c522674e5a61fa64ef735191e363f5d08c81cf125e79c327c52cdd8434739cad7d6f2e2a1d361c4293462dd34cabdd69847d5924799154bb10383995866aa5ad46c1094f3aac952ca596e559d5a2ee57ab426c7cbe3aec72562ee574b56f2008f7094f824d99e1308061737c2a5251893d3894271919956696e8b62e0657e48fe1d51e0792024e4c81184788c7643ac0c80405751c96df8eda95d6f8390e72b913200c4229d01555856e300137dc081caad4b8c3b8fe31aad45eda79d778aa5cd92cd4845125c825c2b333b3dcff69d83334195a6c99a1c85062cb6a89639c52458da2c27e475a900672f39bc8457695c3d34b78ffdf619b446c3b986ba0236913447e03e95d001045c5d9ff43b2041e576bc8f60552659d0df1616c3ce8b058e7750c9c10386961c2e703d762a70069d64593ed0e8873336ae1a684936dc9746a8369608a0570d963ab649357519b2d78c9264264ea204b1d1a25626b104e7351662d73fecd12c83cc2525181a34752253c4dde0b5351b7a6e8b48771ea0e4fc2dc92864b82e89413e10443c87b76ce0ca873e5a28bcf757da9eeafc5ee62a06e0bdfb6dc58fcf41cc5750b04c1b9855e80d10463db3e2e1412789dac61ed88e2bb65752e633b6c88308f91150822f3cc4bfb62194f77bdd7c9d2f2568ff1c035466961ba358653a3410fef94dd938f78e857572949ce9cf31189601844e00e6a3cec2d939b48ce119884bd623ea93dd70e0ecea57fce12ca006a354352fe204554e8de9283275a5a4f6fe5d2ab46ef984526ad8d4678043da007520da772f6da392cdd1f95378654343645895d6b2199e2baa0efdf88bec5a4199858c40505e4902cc44ed6e63c24b8ead41007127100056fe5efb15dc4d5a9836d29941005885924d32928427b86a6cf2c4037852a86d2baa05f80e8bd956c2503a83fd945caf6e6d78f1d26cb897a37c324bfc31ca5f9444d0217874e78d89fe0226eb3d1702f8776280f0d6ae2734b043d29538d1b424899ea90ee1bd5fb3fe58c67893a8cef7e2bff7e63e8a3ac82a63f7c00b1ad85c8bc956b94632eb38c8b539d61be4ef586caeb15657c4017fb7a97b22a5cf51033c03fe8f1873acfd32a59bdcc6be3ed7b7a19e26ec630ea6a80890ff3ce2d50efc1dd5bed052f61f7b0a721aac67e8243c7c869afa6eb0240c48f1a39d094c74722a0997c8c4fa2309a8a64d171cea64ff405b3707047e873bb80c8ee7077c9d08194883189078681bd749a66a88a175faf2bb11a4bbb4ad5d6f761164b598995ac90ad9712b81cb30708ae1d59f1c896417811b182fd319aad63d66a19c4caa4551107302a135cb7a976d0c0cfa672a360fa831fcc209aa4b96e3f4b516c12e895dc55644f75c1cb229f17a22c09c275290aed1a27d9a2f3d654399b25856079c6048f17d0131d18cb2191a07f962f5772ab7507f41018c1257e966449b91065dd5fd5c2d843bf93cf7cea693aa30f3bf53164bef221fe68e84113fff36415ea5f2a743d5c028d8d687a4c17cd964783766e9e8be082a743a7ead5c34ed4dfcaae3fda09b59f6900f7c2ccbbff029639141cceb01ed4b35ab572fdebddf3375b41df347afc765d6442fee96664c7e62043996063361c0cf49d87d12c3461464b15d2296f356f96e72b036027ad0be0925b9f83c631d77e19b38b2b752ef1cb5a94c487c47bab704bb8c54a9b1e35a70b4f983e52130510d8bfc1c76a2b303968033aed10a1195b43620a928c2d6bc10d8d0342cadfef58175ebe166b817b5e351fd0cd60c98b6b3165dca87754fc22837b5f88a7528872956765b21178cec063e5276dee4bf974fad4ca841b63b26389ee18aa3b4098633c3ac307426abfd41d138c1163808c4cdbc9404bc11c7a938089fabd6478966fcd0ecc8219b69e1b5a9dfde9570edd3a70a6659de348f1718fdb84eddcadae13b0cd37e017c995eeeab9eaacb39973206943cecdf0dee0578436b8ce357fb7a919fe62868f60e07d4b96d301fc652dd662da614b9e411c20769dc4d768b672364de6a2ac3aa0c653b9e2e633c67558a26d5e4cc9e186cfa49a150f82a226b511c11f0abeb4af7e9d6870b1d4ac69a3b03a1289de1cd4309c25d914d26b459e8076c85d896156fdbec497d573575a3fb61d59b3de24dd5a970967ca559ac422524e3e43f21ebf269bd489c3614b908377d9972e851e05e895d4ae84e47e9fbdbe4e56d494920d3055a564ebac4a52b4b6f075409ec1a19eb811f1dade7e03a6370b7046cbd882af562243436d55e4b128c16c5de6d208101b4c052b7af31e6bc137b942b708229e4d5549beae5aaa066ae5aa48e67351b0e55aee8552a1acdbb247b683a6bf4440081f818598dc6f9b64d37cdb09e636f550395b4b288369f33dcc197262f43128dd7b5fdd1144078dac3e23e0d38d9c349133f9bfcfe50ab6e01bb54694d57a3623cbe3134734eaf3f85bc789c5b2e09039bcb7978adaa61e1eb8ca90254b2d627a4bd56199b881ad185d94748e08cd9e2111f59528349212b826f5659ae72b29ac505032a947b1f27691a4422e16dfd497089add816c381c8defce7e5adaa3aac6ee111d10fdf1ccc6840527986bc1ca7521947bb8dd8ee2110e046f1e920a77888ef66038b86f48529cd57e2db334cf8b28b2cb35ebb2c08ade667d1658c18fcc98d954089ec5403a42a2f46a32eca0b7093fe8ed0e6e19adcaefa19ae8b00bdff4b952826467f05e3c819d71875d84b185ac04a76bdf9e134e10c5732805da0e6fa4a03a64bdf10c0bbd6a392b563d3cc2f171b2dfa5505ddec25334aa89b59fb92a33b0e021f81c55fd39bb684903a7d561ad55be92ff948b6456c10fa04ffe5a67f8f1cad98dfe25cfafd1a9197d0e97a25ae4d31267089f4e595ee84da17ea0a3db6a6a0af09ae630ac799657c90c0f515278642c0af6f48737cf5f91a6cdc5164f2b5188698ffda840e1ed31a055cedb2a03792bcfbee7153f6a99638f9245b05262c1cb75b9e83051c53d15841d22ab9bd3f39efff014497b6a59abf3d96a9ac9435428e9bd55fac008a4fbb9a72b2a0bd4e0714ea9f5c655fe13de662b325a1a6fcbe4853737079354e02b64bd6bcdd64ba13e83fc76b49e87434a239b86c231bbd0bfafa884eac94924ae37cb8be73c5e443417bdb7024b3162e77a885aec985d8b1de8eea7553468f7aafc6fab95289ef152446d550a59f0a321f5fc9bc099374a887b07b7975370dd4baf0bc34c6a66936154d8d8c129389773cfcf871c4ae54fd58b9ae9ec1cfae6dfeb383adab92f92fc6e922e6293a1cbbfef06ad6e1bf3997a1270810374b5cf9b5cfecf8556c4eaa78086dce02d9fdb11ebef5ad383ea44bbed3f6e7e056a873e56413d0106ae552352bdc4a9e0d97ac5c44d5570c6ab8ac70bf77d6254aee305c37c17805133519a7c137ce1885e205391692dd886bb796854dfa983a9c8b31d9a8b767afbaa649d1daa4cf006693dd1526e86d778df7c258bbd0333aa3320cebe5195e780cdca86f58550fb404bb44addeda9a5c63d9bad18dcab296a20e4bc810cd8c9f50e1cac5a94a391ab0daca8d162cac68fea04fb3ba94ce29497a5c9aa31e5152f05fa4a14799a4a0e466992890e9bf002168fb6cadc8290cf0ca073d78b7692c246b3a67bf7b841c8e65bdc5aa3fe7daefbc04b5ded8063817ee0ae4326332ec59a9b1ee3428976acbee8f931c9847db00868d4892026c341b08f649fa2b0a996dfc0dd72f04cf260da828441b4a1bb53763b598ac14cdf8aa9c74be059842f4595e505f19bdfaa3fbe777afdb3b2d114caa76c2a8a640339618cac2cf9ceb899e13514893d60e1ba268642ee227db31048947e8f638eac9aaf11f0684acc45364547cb72df5bd469a84f63ed2cd9924dccc1431fbc49f4f9776b921753b98cafe091a3ff3900fa3d97d663ed13866ff40afe779e6421bce03e0b672057c111fd84e1fc7f6e2c3f712003df90dbfa1bbcf4c041a10310742069568be123b8a5081e7f2f454f2f5e14952d4d93ecfa75cc53519aa31638f1992a26389fdf2aefad25b8f3fe55543c6af7e437e73e7fbd9af24a403ba443c19e2815df4020897ca8683cf4405219d2dca395946a6669be51a714684a33b2877f9272bd0c68dc4aa539e8b1d2cfabcae2d1a26cf19103b28af76e9ede24e58befcde929fbf0817de5162599420ce179141dbad4394da3f87c4059d7d227bf8af26270d54ba6ae7790a16cd74cd96e2f65bb3065bb1a65bb2065bb30655a2c2ceb0fba1dedc9c67aaac5f2c28aded59987550acb61282d0920601667dbc709f2fb435ebc983a71cf782a087fea0d20372e14a04be9fe086b735181570d34ecb41a6ccece673516776b0a26ed9d9bbaf994a66caf0e68c8b25df902796c89da4d71836fede827b64e39e5b75e880661c6daa85823b90bbf03d553515645be0ba185cd2da096d3824cd3d01ecc0276a083e1db35c8fd278777cfd46cd2d87675a9dbc6ae732240debb07eff9e5efc850fe56795969bd6e0e25ded2e505ca61a25e3a3be9602f9c87f5b7adc3f57efc0b3a61cb132c68ee1a59d93fdf620a9b8fda7208bd972add791cbd545c0578a590f7dcee072ece418fdf7665ae9bc12b70fad7870fc0576788edb3e98ff6decbae1694d6121dec6b28ac055067f5d36cfaca9bda7549b2de85a8ff3d02edaaa2d48155a3c010f76061d0d1f89c3aa8411455918230e121ea8a65b24ed2e9cfc5df68b53bc9cd21b692921e6d0b68a9899c0fe7ece2ca753ec81898d890f614df48a73b9d1e12aaf0e9141c58fb70b8013e96e6ce2ce2524baf4b562618fcdce02d044fbb55b2545e3265bbc3b6826502b7ddcb3c4b2a4c5259aa6696f9546e55d49d2244f3da65f1a2c8b3e4bd455b2d94ef4cc653b263e7710c893ce7e9ae47ad2e54b4708ce4a9665aee1c3ada8bf152a89bf1d2fa3082b3632156298f050653c1f6e1884ebb9af62cb6d00aa09bedb0a570a30810da00edbd7bfa6951523ebf8130d393544099fbf0a0de48b801e3814d84c59fb1fd3e7b25ba92f984c149860cb9950779c192991cea655296626a50f26cc770daa8c1cdd9d2bd0d856b70103beb5c2b11c376afc4f45d1847f452df744b22bd0dd69ecc050bc120eeed147ad02dd7ab559aa8b038daaf574d966e2a362265269065a329a30ff60ff6f190ccc74ace2d1b06e4fdf563c7be0dd5ab96d9f1189b5b6f21af3a04966a05fd08b44315793117f421305c50e8f76765be2e62518b6e722d7618b3fdad940488d96e3e496afce37adb9fb7d85eb0157260fff1327c14af0651996a63faaebf14d5810c5e934c85f015cee42593d48692f8882c8552eaaa85c04e3ce45eb9e7454792cdffbd16e844adffeec273565bbc4aba52d6967eb57e6b58bd861300c78b0296fee6155ea3b948ae7ab62f4e0f7c0d6176b44a22fd8da95e716e47e724176d9e42ff7aa61dda4549775463d01d585e43b0478371887595cfd8aa10fae40e1f9d937b26d0a536ee898d32bb92929d5546619742c76e55d9a251d1cfd41a3b15372c29ad63ff65d8af1601bb7a9550f6328d68f8028eea5ec8457bc663f151919c2b877aa34be5460f23dddd719f70bb515db73de919937ea3bf477de8155922ba774f5f64354486d2710024aa7dc7f511b1837fb57e689eeb863ed6c37f9d289d0d0d79ad986eeb9870d09cb25683731bdfc7cf92149fc3c2ad349c29b9df3ddf442cf50e774d6e5d72b8eb37a983d79a5809879d22ec632d55c5da3a5fe41b73e5d92c4c7b0e34d570a9c5c30a0aadbd2e3133b8be36521f80e504cebe59779778a319829b7772c78feb7f0daf70b8a0a80cdeab904acaade6dc45e53e5c2f049ffe1fb1a33b87d77191ac2af06e277692e2830a2477ee39788f99bb119fead38db00163009a36ea30a6631c5a2555fbb6bc2e7b6eddfce2637ab712f50c544c91869c24803d612df871375f1336967f1aa4381afab1af12f2e8c2da4c285217aa716b031a6649010d15ab513245bae4ca44380c841ab311e9ca4f9b9bb74fccc3b4bc3fb5a41e7667190546f70b354b1dbb8f68740505e1fb0043ddd31c41dc03fddfae260e9dfe9f67ee1f3af13ff7c47e410ed17eeb8cf72777bfcfde29217b8761bf6d8c453718a8dc78da80a0804c80536109ddd45b54f44f99e5b26706d5580b866d5847fde8380ad2141b29f515bf113afabc160358ba034737f6bf5d85ddaec40ed03846e75cbb0ac5d538b542ad6fae89aea1dac68da75af3caf2eca040a8158f71677bd87640e894cb50f894cfcb226f1424ecbf8e9fee8b181a95d47bcc5fdb272b9ecf0a21de8b88a6043a68a940efddbfc895d137f0f5e1aa26c03f10d10afead7e77affefe934e4b06085d035af96085411dc24a511d4495bb8d68bc0a35c45215e6ec4195296f0013e2447017f351c78270d94300e6aa67da06b77c754a8c626ae02bd1f29e5d3f461a7c739f84ee37e6be01b59f3c3015718f82c1275fe9079ba4f311d9d50323ec3b8f3273301e2e75f812055b6a5f7548d41277ff54eb622359840b1e49b424488e05389494bfabf8937b48f93be6b40890a24a6af81adb3ed43694ea402dfcc1f9b7ef3ec7bdae29bda847fecc35ef1a5d0d1479973a87bf8a7a5b1a9be5f390ae43d11662b37f078646070c8f5a3fd4d0380cf8aace817092c9bd2a84b6a2a9df7f94618c7973f995352cda14b7e6ffa72ed8e1e55af2522fd56ec0b3caf45c97536a28d8c75b35a3fcfb70a977ef2afe2557c6042a5b2fff2adcbbe2fa0168b65e7e6f6f8548b9112e0df18d46183a15d537a80ab8631aefea16bc932e8af9db20e65e9295a2a8cc4d8f82e91892bba6da9d27b48b9a3a1561d89f385f93d904826a4f8b413001c2974c7c1159bbb946acec982577a7d4be286a121fa004bcf8f5fb226790955b95c34aad985cd1d14ef35d44a9b970b8b82b5af355a3178e77ed6e2393df01ffeb45326bf6f3f12ff625f027b401d27c9b5cecf12470e0f78c8482f3c78e75d9e8ce44ff0d9fbe35b2c66b7a506fd60ff2547f067070b8a769e0d9420d9da9f2e6e9dff413d2972fd811c390e7b787521166069b7770f1788ff91aca5fd4a3f942c3a66ceb8fb3d9ac15b65f47de6715fc5947eea6f3ddf0d53cd7c17ce6b1cebe1e3b6f7378513d5549687911f7ec87330d23b22985d07f9a72c80af8574c5c8f20e48b81824cb7068ad6e9439d7c5d89e2159f266bfba8e746e1bb315f76ea8b3e15e9f7d9f705df329eb124cb44c1903d6cb2835e43a014788319e3557cc1b7f21b67d37c3d49451783a8632585ef7996f2628eee081207209108263b36e89d9ce82c8855ce449a2c938c5782cdd30453014e44b515225328e1742b94c8577ee3451cdd74d8aee3f7bf4387a54b39d7b183714cbfdbb74d1215700251b16f29abed43ce5b068360506aa54e306da54b713411b9af5bc4afc9399b719b6d6a444fe93e1b798d9012fb8e4b65fecf4be18d881ceec83cd533f3474acd0feb347d9614712a700353e26cda2c81191d943e32b16e9b343abd089e9864e4f68882d726253b965a4c8f893fafcf82189cb6ad945888f35a2bf7eec19799e9347d94ee543e3e27046119a9d5ed9eb9aae9b6f900b31de5ab2e669d2033fcaf5498acf18ff694479e6b59491acaaac8aff5ddec9de9dd2cdd69ec131622ff33115a97589453474c897ca2b63c97249315055fcc4259ab514065f36992097d006050e007b5ae12c0ff9d839a69c11ad96a98e5cd181bb04dc446a42d3a505ab243627bf81cf6317a9d0fceb9df4552f41cbbf30cd115f7cd8c261548e4ca84ff55f6cf5bb908ee099ea982efb67811b7ccbba91ff944a4af7836a7762ec4f3f987b3bfd82ccd6180134a16122b052ecf2293210791b1aee4e94d878ddaec1b9b3e67b3ec15b8441dcb72d8926b568dda5eac5d9d64b0160138c9fc1ec019ed3f547c8dfff8b49e80ed942759f54a6567d6e15cfd435518bc1f8a7c090f452329afbfdea85bb17f74d84efdfc8f8fed338a9b2bfd1f6ca3c7c992a0f6fb09ba983656d100674ee099d73c4baaa414aabd42728aa2754ccccdd2b730cd81965db036cb9eb76699903b06ea1b82d7b966695a993e7a9890da6f4dbb5e7c36301f0ec1d048086fa2c2b20e7352253388df91a01730f04f874acd5722ebc33445ee5286294b131a86acd6aa47e7cc5bc8914c6b07b852824d2b3bee9c45460abe8581a056debd7b5646be39f774188d88a0e7a84be2bd7b4e63874ebeb9a89ec12e07a4bfe97c2230eb54c982a7332d5991237fa813ac00f4cdcaa5eb59b678ac38f67b4f2a07222f4bd5a4edd4382f2343539b1d9186684ce6cdb2b7d355ca246baa7269ef3128c79e1622f83eae99558a6abb3b8e22c21c54af54d2fb2c1ae95c6c2f5fb425551155bbcef2366a6b5b5c953a6bd6c87b63754074ebfd432e77c58508ea1c767c7bc746f41414e6a354becf00a99205d23bc4403a04285042bc7dd42de21119f9201d908cf5686807e4243282724bdd90c0ecf3908dab1bc366bc998c2b7aafd83c0aeeb940d46c69b6d913dc598f8d032286a089e92da1e293df77f337e1f5d8e3bd8121c3a692102ef94d7d3c9d7de6c0b29b7c1f3b401ac0cad1d8152b1292676acb8da1a64b89e53aa6e1d536cb5e9c14f17a39138590eab70f5b073a96975ed64a30e6f8868604949f66499aea6b063922eed9d599bfc1a0a0ae97a5b3973c60a3b877271b369de90140ddecbda3fdbc1fd927d9d01aa56f475f5677dcd0d1c18902af6a6e63644d3cbe26bcfd4887bfcee2cfc8e0cfcede30735d4e11db9a6e1a096f9b36c321fea8e457917f466d5cda4c92749afeea4f906486149a3af4d4b721b3bd7332fca927d272634c8ea4e139975c3907bdfbf6e4d83fa7de7324ad8e9d4fc227d5fbceb255ac94316b4dd655e51f677fcfcb8589f3ed7ec6182992e481576a02a58c596b9954a2b05863befa4ebc4f9471587af1cfa494a84f906001227b828fb932b67921b839b2c5f87d998093e2a42a313c1bbf49cacbd0f13add1943b503b6c612ae75d0b394fa652d2cb434d58ab34083735560792e573cfb338708a27241527fd1551a9fc0690c493a2d44a61c88db905e374ef34cc59db2d5501e95b8970da27de6c3e36df88f49665eaab2730f55cf3ea349329aed3ce565f57dc1b7d90be5ead41d522e6835a17a92e6b913fc15bdd7f4457b47c747fdf7bfba2e0ec88d7a28d7b0a3837ee8291babb9562a2aa5fe879fdf300739ac008e77f2a5f22f90043aba457f7c51896584483cbf9c4b1aed1b857801d1e26107c956bc5a7418dcdb0100e6332623eaf55fbde64051eb95d7c94a6ede3419e4b3f746cfc892ea6969df3bb77b719ec5bc8a9ca281ee871b698f0ea627b24a2f14825f932ffe5bbf303750481437f814df97ce92a2ac3447e63c715eca1a42dc41c22e40d04bc5b0c155b35364c012ebf7d96bb0af989c0bec67ea0aadcf399ff195637829c5ca3e7c689c4c1e286deec573f61814db7020f5609657ac5caf5679512183a6bc5c58a106924525714bd54c63e9bb2576d5957f1d401ba00badbca9c288cb804e7b41965bb72904eb1cd21c82b6c3c7c806a959640ee88481f5709af3eb46d295dfdb2df8d18239d018b7f41a155ab328ea32d768126ad81fc8bc50a12a739654ad128f97302dba3aafcc72b6e4981a60c12b855a2b58a30e2e0657cee2050ac780f9fa449226db7d934716e686286e9d2d0acc1f7f6d18f822e6e8e4e11d7472a01f543b1a1288e6f6a9814093ecc9611a9d8d75332e9aff8fbd77616fe3461245ff0a3233c724238a949478925051bc7e2413dde3d8be9633898fe56b37d910d971b39bd3684a6462fdf7fba1aa0014d06892929dccec9ecc7e1b8b0da0f02a140af57c7dec3bf1b7af1c967783517c72726216605f1c4236ae4f0c6d858850d15107041e0218c84a8a2ba0a7d364013405c2c465aa494f21b72784384d161e81bfc9e6c6424ec3508076d625047bc71e798530c32b9c50dd61cd1801dc44d671d4833c8260dcbc3a6e071fbb3be20f1affa6e08abd1b3f4a8e6efa288167cceff62c59a0c8d6b151247a71ef0a17706f243a13781c77767bb1fced70fbe3a45187de35eef37028be771e7ee7f52cab8d7ce8d07705349f3ff73f3ff0e0465f0a562dbb023592affe6a93a1199f87b9b847c2bd64ac7c65574f7c2d42059719bea6234696eeeb86d76c102f6f3f88973888f58d06c1df4c482276783441c54eab2a0e97a42fbc09ed20e9c6496dd223ee09bfd04c1924d68196d1ce1997a072a26db6065ca3c815a388177d2cf839f6f1257d5cdb8f1fa81969914287d2d5732661dc41bdd05022d8257203606bf3f1a4fe3b4ec7919d244d21ef5980ba710f913641393cb8f55aecaa97d8224b77c410b93cf79b2b24cada2415d183a75f9ec6829456766eac7085df79af6bfcb46ebcd6777fdd0762ae4deca8180e85547956d4fb69a692712ef7e1015294fb6a96a4e55520d30b989bf8437c38140f8da99ee6f4501ac4c235d99df2232b68bea7c127bcc914b43f2d740350b7bb8d0e9f425b18f3f012ad77782e1cb53c179a1212c08fd89b6117597febf01a0ba2b11e4d0f9077b258d917e62ca37d9e4146df00dde357bcdbf9e8f7e43d2a39411dfc26535d7f383b3014619db377d96221d391e88ccbba2ee72df6bb079b19834cfd5356753649726722e2aea93b77f4f6a1a9ea271c7dc3a402dfc3ceb9f4ae10841c453e633d6965ec0ac690a6619a54692e95fd5a56992c6a4acdeae2b1e8ca148edce4e37d6ed6f6da80c306860c3f80deae9bbd9acc9e645beea71598cafa4152615bb70e40b50efb6275d417ebc3be581ff541ffcdedd3bce5731e9f497e81a88f6be754f4ab43228362dfc2d29f8fcce73dfe797dc8330f210700e749594dc5fac85641856258c57fc2b891cd64369dd5e1d07867ab4667abb0b36695354d70ed4f707d643eb3095e1b575a7e85e6f2a21ee975c79f75b918e9d5a7a3a5c73cd23b82bf11f547627d04f01a2ca7ba4a1690f2be2f2e0ffbe2f2c847715d0274f952bf922f8fc4887d3ad29f0ee95303f222a91459f3d149f41147a6538f3053a563535ef9310ad0cd2d9dca90a331a93d985d20989355d9af655127b917af95f6427c435cba0bce84a381e5d07ff74547af73a72f3ab0a41d9f703a1f2603f16b62b90962049ea142a253978b4ecfdf60f54ad77acd13607af36b5d5ba0627013ce93d54ff0dfeff9d3415f6071bb4dd041bccb16e2a465af6cadba2faabe18f745ce36834734404f3fca94eb9c4ec489d8836f83ba5cf02046952b81d5e5656357862bc60b7357a8b7c715f98758f7acfbd0b05c13563b76aeea112c87196bb7165f8b0330801023518b6f6069c53dfc67244cd48b8a9ad989742bdeb0c2863f61c39ff4177334a9a19b6577cc5b8e1b5d8ea9654e2dcd127473de2e6ff498c7cf3e5c015931d5574640d5e9763869107e8b1357c421614d9afdbef9a94766ab1221b57569c2b6724dfa20ec189c444ee2286e2f8bbe70d4d9c846fddd0415f9c87b76b0b1f1d7871b85fd7a35c2ae9c3c61441d1211a002509eb77622f6683a833cde9fab5037ba86e5c1c6eecfaa392057c8fe1c735ad5d8777aa8c38a6aee903b1dbdcb163f8b13b1b2a1be3c52f1529ce837495864b1e5934bc4630473e70e36d28889d1c446517c727b878070f077ee1838efdf8b95f8e6c45bda3b77c44a7ceda35fcf6ff852375cb3867ac5efdc116bd60e51316a526d99d45d0421b6f22e2ae4dbdb6de96e943948fce4b23a80f8e0fc3fa9155a8a78dad68295c2afdb1921e98abafb2ef4a0f91cfc636dfeb8327fcc7c63102a052c82fe07577a57a82efbbc5dc9ebabef36dad15437186a1db81cb5ad4d23b69ded0827b022bf05dd11cdb46fe7165acc74e4a52cca34ed6c102f136ee1c1bf9514c6702bfb4eacd06e49df22be2350868ab8aea8a66bb141aef6c13242ff6161f0e49e47dc0c6c085968aa8cbc2a909ca965bc3f6f718ed86121a0e700eccb28d89dd6b77db41f6a8aadef01a6fc6b79b69dd78190eabc5e9301e99aa474faa5c3de4ca17e6845d557f1ea088f89bcc24043bfad4630d691587fa865f52ed8641fa8242f4dc6aa4b6f37337a8757eecde8d75eb1da7fb85cf59ccb4a631652f695a5bfdd07c35ee65544df1fa3151537aaa29267a42bf0740754f69c5da18d6bf5f8bcb0d232ecf63e74673f529f8fb12ffbd974f88c3ab205bcb7e7ac1723dd5a547292d4d2775e7fe3be1f47d5769f6d53dbc5e45fe3a432c22f8a5549db342f533036d394b0c35141518626aa07698546e295331b443e430f745a566b27cb2ac936cfb3ae9b5659aad74d8db86616abfec395e936a6d8e8494d5eadf37add3206bdf989756c7fed23d67669a0099c6587364e380b6d66f84c561359d489a69407832f99e2b1f28bbe3a8fc9ef8cdced61395f2c6bcae679fe97725167f3243fff8b50c97c914ba1b25f41513d4fb2a24eb2428c934a09f9af6592e76b284d053a152d2a48009a155348c296278bc14691d9047bfe212bcea0abb3ec5789398bc85b5a31be7b0e162f503a78c3c277982041a806ef07093eac25f3a10da08390b784d0c1deac246b9e157d47b010c2abecb5b1b657af32b12f0e5ff73c914524780f0e7f2aeb17d9e49deaf6b68c42cf88b77aa63bfbaeac746b975204c79a896fc481b8d7366600b50f2b055abd796678458ab0a42b445efe58ef3a8a304921ceff92a512b0c56025189eda3cd0c95895f9b246a16d3dcb26ef0a90d9ea8dba60aa8cb2324920c5a762a9081bd53cc973a96acc6c7199e4a2aba48ce24d0fe37b130a2ae88f90709115d301e4ae00e89ac01893897c2d92fc2a592b9bef52c5d0bbbb2cea2c17579062a32ad3e54452944c1e0cf45e6f2774ff2eab1fd25abda892ac5626a74ab5cc65d537d018eabb753bb1090bc749f5c27cb6e7c0c4b9014803552793770f21088fad800885e506755d343e77ceb8e8eac932cf9f563feabdeadaa1d0a57e2f7e8869007894796fd46c64ec5fe1d99cfd0aca983a2b5b8467f111d8630214ea0446fea95da02695345c81eec85fc9a08ecf910d87e2a7992c020cce9490c545594d64da77b89f1429d45b588090205d64d3a2ac643ab0109f94b5ec9e3de88d34524d20267d92a6d6aaf10272bba3076bd031e660e5db3f129dbb07ffabd3b3c0316f075ddac29b9f505931a1d49828f1cb94199d49e6c2a6688eefc05b6857e5530af2e4afec61bb0471325b16ef4678a70c2988126b3c4234a04f60ab371244babad4e8a8e7c96ce254c9dd62766f803ee045ab8f7d05be6574dc55964a315ee3bfdda204e330bd1c00daeda60d50ac37f5b0d7f7899db5a2d31b7051e67909f15a680499544885800201e080e84022fc34bb0047981a855c94628712c948b07dd5244ed3a64532019cda81e6e4727543a24381627c621112923809a11b05edf5f056e215e1aa14235f405660f0646bd9c82f69dd2084b1178141fbc4ce760b11b09edd7dc044467570e8610cffe1902c035348d796d50a313853148ac7c70367d227ac8bc970a82f3c30414d7255a2717742202105d492b20801d504f883c605ad8f01ae944995798ff64716a9d87784bfaaf5e2e89afbd0b01118c283c2276a07e5cf13061d9bac457ad4e7231cda4d18f29e60bc071f060ed34d8cfeb50c0c72751a540fbd52ed490428448c2c8743b3050ea7597d0b250a6f4c9f2845af0a9f48c13f1e61baa4a8e018c7eb8da6e2272d81bfb8c034961fbbf980db2924e7c7cd354c6aaf8d1988bd05e25fed65653f368fa62d9a27ab07b126f3ac7890548f81266ccf70bc5300c93e1e3713ff1e3123be472ecebceb6e902c16f9ba3b972c509c93e5b647a884a090806d911895f09d5744d4315a4fc43a336af218f2127f767b26703e41712f787878a3455087cd3dc06cd1c1c7f6e0d56ab87ead1fb983606731cd95927550d0bb498f76875b3a6418e0f5e7beefde5d13dd629dc690d2751d29dd3600da1b9712d6edcd80a3736c301ebab36178df775f81e054457b0c0f1eeb3428f2c574b74847c695355ebeef2d093b21a7cf12a32562bbe7fa17f3ff88bcbb5197b33da76790c0129abdca5e835481e53f0ba2937a8dbc4530d4dab8f0edb62cbbe76d6a4b79597ab92eda53208523ec31a92f950cde2051b1fdb1a4c33c0f78efb8d170bdb9e1bab5218f138fcdb9c702ab98451c1a58b189e5dc6e42e76ef61dc2b5dbcaad01dbad419d5f953ec7adebfcaa3f794a755a08500b8d6c2872908dda3a3916daac8818a7567f348cf9b913705bf54533db064f874a0d7b9e7ed15f567f6a7ed2c06b7e58bdd3f10f59ce655daddbce867b89443071915d96378a541bef7bfb090ddf431b8e2a6158b83a5c57addc2908ef02560d948e27547b0046004a82c0cfabe6acb65ce54c7d6fbf7a95199d249a8999857da269c6695f7c1a95927c02796b1f24150c184602295a6d2e0df8a7f4039603c56e0304e7b90d50f01075f41e90cd9bb6fb71ccebd00ac20e8a7bb8a023332d28f5aaaf3c48fa21156f3893492a466656030c5aeb415a8790fcba62b409b407c9da0145c1c15b65e459d0baa6c6dac86be904ac230f4acb11e21961810b55eeada7a9e3425909d765a6b271966735e6158e24400417c0d7625fbc70791563891095f84dd555564c5fbdbe86ba79a6209923f2c7a78f36a59985dc887aa0ec50eb7eb71edce05072e639b889218992d53ce81b39a927b3ac98fe3383acc3fa82c6dcc5fa71c05bc3048036626343e9e93b3f32c8a698ee9a31e869374e82dc9d7d6812e17c36272e675df1fc00c3a11db210ef857ba4b00aee7fefc585be2fc57b904999bf2dc6b13668d9846d8458d1bff897fd9bd5d72f1dc1ca82faac26f38588d5f421630647da123f7da35e5ca4474f2fba6ede3de3fefade767a5e7b30dc00eedc11fc55e7a5c0f41c51a93770c0675dd95db8e6e3850a2eaba687dae78d5802a127a74d20a97bdce1cccb8b0b390199b3cb347d0b3ad038a6e69482686583eb156af0ed9976fab11dc915890f2f286feb34bb24d1a9263d1f40c9bcbc459b281a35447a762d5e15c95c9a063842fd45d4a5b8c88ab441074d872ffc096d5f584a0a6717960fb80f7d7a04d1529370c1793bef4a273ebb0bc3f7dc38982948708ea05b530a1a1f311c0a2a1566d2fb8722bbb019613205d48452f20678dccdb87377a35f272c769dba87c14e0ca3618c6e2246daed26b13c5148c0bdc76de4e9da781b6f7dc6d23d0f04a6a13a0666ae8b5652707d0cfc18260d6b221f2a458e537ed0b891b91de11774c563c6d96259a47ea16254811e89f60b4b7d08cd090a7bcc44f6f449594b1aa3c9e268b426933c992f30e7b313b327954c3610ae1636b8f5a4054cf136d4d9902c73b74703e7fc2d9bd1fa1c30762536bda697a6eda3b13dc6a1829a82993aa29dcd08e71154efc5c947c1e45c4ca7c33fdf8ad9f2e5ae74b2b8d0d5aa878c7b236954fc0b1f5d09b07c9e80f9f50178bbe197acc02ff7d807569d75959b196eea0bcb6491dea8cf040ceb9afd6785fbee8d652b23aa29160ace33688f2ad0bed04f993ea9f2612d1f37d324992d02fbf736260a77e79336fe691716f7bccee25cae2bbf10dd2ce0adbcbbcf0fd7118bd81481e5583fe21e3d206c55361f0e36b0e8d9a06eed3173705b7087d7400ce25f2cd698c537df0d7edd6b7c6e00f0169742b83854fb1a81d388c10f47a340138da9c637e2a0172c9ed116ee9d50256f2daefdad89f2c2241d68b91001ba596078f16fae2af604cf0764b591d0745f186183457d8f967d12e2bcd5612ab064fada237d3c93bc3574092920f64294c42ce727def5f0febda134663f58a9b7dc347f32838ff6d60c6ac31bedb534dac2622850e0010d39b7025b25474862cc27ddd108e98df9847216fc28f68c4ef76833abb0e5ba67c2aa6dd77dd4866283d60382a4c74db930b2f0452e571dc7dfded488c3b1bf373439b3286baf492682f7de1ac14234af527e919318ec04673e3007a88b3f41112f3e65fdf5c2c220aa35d7fccfb3a26be61bda25772dcb10aabe4e8b8bacc8eab56331fdb1e02fd0fef74243f8df7cdca4c9ed5bac0b1095caf79ae5066bf1df7ef314c4f0f7a681373f98c5dc4547b78b4a2aa68963a526ec1911e0208803262e9149d73a8351588b810b6ee13fa2dab903625137ddc174ebb21b177cab33f52479a2af2d8d753da2b0f653b2f22f2da33c840814cdc0c8d7ad935d16cde9de44e9d1aaeebb51c0569302df0dcf18a95cf7dbcc58582afed641444d261ab2869d4d1b9c3f82d722a67067d44dcfcdb75c684632f9ac6b47129a47c400b829983246d4b7c0669429d23c80dcb442d80c3f66f9d00a2ae82b209c9b3b6a50d93890b00bff95d7806f3737b09788346f906a9e735d17b5879efb7cb30f0b455bd0181d84ce36570c951eb7fabb2cc7e35c6e74795119b8c79edfdce785fc4d204e347624d40c8c8a1755394ec6f91aac0b13811589f28fd7263a8c95f15837ab4640982c1d89ce6a3f59656affa0a33b2aa44c455288d34742954eb630490a514913cbdd4a5a88e899d8d95b3c67fa911161b0096f3c6b331e03fdbce93ae6566f92e4f9187545aedbac8ea7a93ea78091ba5ca4a55445a716f3e49d144a164a828c594d306e28da545fc1c77982216bd0605789248ced48a8d9e9b80b2154e5dbd164b59c6306726f5cecca05cb009399d8bd206b391ff8321600addf00ac6307c9788c6d058317a3fe9ef124fe6c62dec0f6446724ba1db127a0cdca7eed0bfb711d7cb4e31968aea9d3ebc46ecec0518fdb5922feef626ae9dfa3652d27b54cd94dda6e8709e3fb37d860fad696b184fd4161045218f8d12fc03880ee9b890c68bfb8005af693899ce5d9646e59db5b5a8c6d368d62e1e0098f8f5990b51fa14b0aaf16f25e3299cc6c305b3b28f86083dbb61b8af17aa1a5d806d6ad6d599aa664b10e3e6cad264b559773131778403fdfbff753eddfccf60b02f2ddc8e8eb26c66ade6604af8f9654efaf3c2a059555ccaacccd971990e0dcb900e8919c64f324ef1e0ceef6c42852015f11fa2e2b2f685cfa3d5f42f09f8eb887df46e249f2c46e268dc85b43368af559c420488cd877bf73f42788c02ece4dc45a66d2877f1c7b857607d79142b7593e1f4ec581e51ef5efd78919ed51d11f6eb0b7830d1e0baa6baad94fd148c0a6160b3568a50c44295d25f3850922b02fb3ff078255f63b55efb2c5880e32263a78ff5ee08b74d5737f3329078406303fd62361628a5e0708b2d5d2ae49b994ac2116312d824fb97c5a459bccf73c4a0e7c946355a6d49709d9e9259c7425c1a4fe665c554c8492762c3306653be0183786dc8061bc9a8f5f66c3b1461526c6b32f84c6789aafa5cfadc42bc61af4fd75ebb61c25fb186fcc6c7b876c15da3a7355a21db584158d764401462387d7876c63cafae748ec090f284b19fef1042d510ee216c2ba5d446cbb5de9745d46cc7d1b55ad10e863cb7b385b76d670a466332a8b1a5dc95cf483193a85ea7f3c3b69b281c19b8f1740f007fa232ca046861708cfdd70284e0b314994346b71252b2926c9642653d1c5f4014b252eaaf25759f4c08f0fdec575499987f45b109b224493750741e8e542c1d509a1bcf224959b6470543db4db180ec543dc78c272d89925c6457550dda1b0728dee2bbbc678a504d70d3c0e1d79835994c545360d2ba2d4d29cad20e02f2770affb668723fe0711094ebbfce6ee2ea9039e9dfecdc6277d764a629d474f7f7cf0f8db375406ff6012705df8fdfdc7df79451487272ae249cbe574562c6b23e4498a6c4eb7bd73af7c5096b94c0ab12f7e9ac97a262b8d32581391c546c8a6b8b38f082a42a09acf7525e98534d9065b4d923c2ba61e4c8db773f8827937bd3eced0e806ac242d4ddc4d7255e7722a8bf421095cc2a0e31e1d046bdf13919613a00d834925d9c3aab3cc3b115edf99afc4cd5bda0c5bd02dc254c05f4d73ac3e0cea14842fe6afb345e2b4dcfae340c9fa7e5d57d97859cb6e679227e0308523cb52b1273afbb80c7602faec9b4135b374456cbfac24e6e0f56ea65f38343d5e710243d7d457efc42ccbd36edb1ae759c7cb61c5e74c70f4cf9d60a94552b4431b28cd7a4518193ed3a0945b28939a9b9c5b5e074602bb0cf4855cd54fca543220d1ac292dba6a58538884f7fd8b1f1e1f8718ef521a0274266834aefe8fa9a0e5446cc3738e4684bfc6eef1ce1d1fed9b1876ee4be94cfb79b2e832e3f9b1ccfb226bd85f3089028eca3121205b38f0cd538c0e794db2803a1938211dea92d7b9a420365ebb50cd6afe4f5f1323e1fb3e99ffb3710747228a618d062cf4bd6d1261e11d6651c07bbfb2cfc89bff9b65692a8b11bdbe7c91eac16bab5b445f1c2a7c95bd1e60bb7eb81e40dabf5dd5558258b154324513e7723ab5247d5256959cd420520ddb67c419f9dfaf7d139a96dc41b41baf5e37a4b076a065f130cf3c2a2ffb02cf833e8d81ead5bcfe5d85819f8e8833c2609fcc59e1804e7bde0f5112da8d583aea957ff57a5bf0a573e72c1145f88cafd87088db219939b9bec171b6d98590ab4c19a9e33937eee7065e3ed287c58420e2447cd252d446c83cbe0c458cdda8272ba6c8f2029e2017821b022154aea4982c6b512e6b5338cfd234c7681593655d2e6b1e7eecee810f3be46f909117579099cbe5e0a280271301c14a311b86939eec5bc6cc075e9775920b3f9d30ef07c7c88b479c0174c09e1013afb99d2a4b61640a0cf7a7d9a5148928b289e4eab30fd736dd443144bd9d6ed60f79ca21baef58cba60a875bef7646561be3c8176f1d510cc5817b381ff73b859186367fc3a150b3f28a46541684199070a5bc10f3655e67f003a616b4f45f61633949960a74744905b8504c0de504f0bc75b874f0b74d2a1badf9eae0b5d8a3171c3f8491d46f0e7aac015f2e765543839be9c1cc6be4c3838edcaf267430f2ac7877462a69b791458971c1ffadba30969dff77d18fbd76b4e11fc6ebc79016e70a4441bb307b0920171acb5bfe96224025795e5e2991ca5a56f3ac30a888a1a79322a510d5f446a7bb3d8748a553593fcf8ae9268f1fef7d5599ca9e8515dc94baf81734a5fe457ced1940ebabf017761ef5d17597f120537413923340f717fff0eeedd96eb7597ffa153f30a0c406011a4ba2149a8ef9c267e71ed1143c8345e0cf36c419fbf832f88891447f66d93cddd797c1d7cd8abaa49a34549a56e0a76f5b146caa4178f78aa1383c38e0b921a08d77399aa6fc63b8683f19a764b2add2e887dfac17b7e7b691ac48303b4f56df43bd302a27cf708c814a5430ae0cec2d1271b1ccf13ecf655f58f35cb4a504eb0a8c394707117ca087e4444ddf926ae25edf7e275ff3bb3f60535d567fb3469671f95fbc99456fd660ef8437ff864447f7c43e97358d789dafc53ed5f1ab1c786caf2c523322de9b88ed1e9bc5cf46e6352955d735ec356bbe34355556b4d69445ea4134a36ad4f2a0c56be9fb2ac90a75a03975be1e64c16e67fccd09790df02fb16de050bf8a807512bd00bc2dd8d48dd873f5a25d1e7e79e0ef0e382b42d3006a2b88a32f22c3de6f1df77efbc0378e789e153f036fe0067e4fec6ba4b376d5883d7d83459f12bde9030ae07fedc75e08fc2503aea71405feb26f10cf03fe12ffdb063c59f1916bd00e72b2fa9061272b3eecafe2a06f3c687b6b7461e8e052f1b31fd3ddde215d18035479e9577137ca3ec2d98bc07117cc3e42da6b40badee06caaef9aadcf625de955f69adb026c36dca0067d9135b41578d1faaa3fba079315cf6d63357a74bbd8a7bdbec06d6e1df70552a0d0074f332886748b3b80df9b0b8e41b41978dca7ba5c6c84f8f298cf0938b8e746c96231c885676e5e933dccdb632569c46b69a6b009a8d98bc3c60002b291d6c436d2d44c8bf5a507d335d6d4c8e511cf8777ff8b12dc4b35cd39f4bb73886afefa5434ba8cb478695bbc6c6b813ba639217ce9fb21666848ac62b00bed13f796e8d326a78369f81bfc0efc8e6e4fd0774b3f8cbf32bbf64147b36198e68ede6d029825d5e4863667bf37036e756a64ee0f9c99fdc87b03a79a9ffd434d29a702bac189a36bfad26f8ab9a842fa10366de71a21f641511664d7032ae55952a4b94c85c6ddca01616cde6d41ec642d103c0410ea9d3bfe1a0f3c8d23d92325d5c40823f1033f850f39dc685431f1a9e8369f1d62e8b1e35c2de71db1cde344db353b2ad694239947156e04b049c27c9b25bd34f662b4f61450b1a1c587e365cfee70287eac41706cbebc891b2958a9e09b2c307970901e49955532159799bc128baa5cc8aacea4953fa3d19597fae2c6967637b0b5bb81b59da90a929cb02a7c645557237bcef78477f9b04aeb913dd17ea597ac923bb8fc5dc62a984339b2c79315061265ef27abc67067c471905561f83ae278cfaa902c38b076b88f58628d1eba7eb04043c5db4204f642298def0b6a4cf600bbadc19e79c99f696a44fa270882a74476013137e068d55931754ff04ff0b8bd7f2f3ed9406802d193f3d23ff0f53360dfb581eada693524b191a60d174716afdc443d34bbef89b50a0e9291ef461f7bf429f662b780f422c70c307d3ea7cd99cf917e90d7b5107f1239992a0da19361af0e426bb018354b2633a7cb62d6f324416edacf1b1d43e47238e6dbeedc2b9712fd2d4d8641bc7d3c5cc021efb188e0d8ae218064d6679f42825a9a6c805d66099e244fcc0e811c9b0b2fa14e7c931efa34c12e0a4de6b7e65afb9b3170b049fc0ad5beb1aefd6e651a59003d91c5a7a21bac8818629f1e2f68db1ef8169043319535c6d89a272b937db4ac04c8c92913675dd22593afc9b96c9191680fee9cc67bce67327788b399ac026cdcc0697aeae1be806bd66946acc1685f7879ea613e36f7afa357def86041becbc0ee4f6a1a3e2f551d4af94dd508171fd146efa08606d1655cf09e855ab39d55d6f8908f489619d9855015f6d113da64b8356d9a78f8c605fc472c984a5441105b7d0f473f8e2c83aa723323586f3b156fdecc8885ac1f9795af1674bc20afbb513ac22423b1ab2ace5d86748d7287361926d8c40e30131d3f78a027768970656c56ee74b0aaa1aaccd3f6e291e57d40d26571cffb36122e00916bc57a338dd827bfcd758c88990a1fe8bc905493a8eb82cf076d7c04b00a37755bd060fe239d166eec9870f78f764c083bfcdd1c13a21d6d734c6862e53f646db4bd64ce876f945ba898c515c8933e82aab93de66e2818db5511cddbc4f5d12cb457a88fce6ea08f0eaec546df7b2cf625d36766ed613a98ba9a436aa7329bd72d58b1b370c5a83b2b4f6ca01d9bbd6fa3c3c1bd1e5c9170f1b067c5c25b02a92ee71ae9923c37a66ce4ccae97cda216e216f2f193a41063290e36c451dc2844de25206c4312db36fd010fcbb539e9a68b94fd604b3252607f8c8148b2cad44874d61f12a8c17c6e065c20acdb9e63b499e7b43556c2474f80ca676ecc84466eeb28143e031c6447c0f1b17bbb3566c3f60df890bcaa1e067cfc0cab814596d79bc71ebe19271b0213440f938d6f739a6e3b3fee4949eeda37a3592ef8ce4dba5af3ae3679eefc7df7c82b475b22afc0fda1c0bfffb4204d4323bad21baf462be6e8936af046cdca2b761c000dd42229fe91684c0507195accdf3b95b11f8585d38a1bc454d9103ac56e944d2008437d98670b93987796e4170fb8f613ba0339463679476a199401dcb913c462d53598549ce28b5dca0a42339af603fa64ab604a525b0c3f831097c1a8ace98c931db8e6c96ae7e6be2f02c53a3623be273016e63c333269f00061c51072759e805ba1cd0b679796300e16170f589f5cee3dc9045be17098fef3caa8a24c1c03b775067ab877b6fadaabbede50bdb12875b91889f54016261c6385eccd8a7dc2bb4d57c3ac8bf8555f02ba5e33759e5da2ba8401719919605a5f547d31ee0b23860e2d8b9f42c085503ce6e2f9d6e582183dfb76405d207d1ddbaf3874fa9cdbcf7aec48dbbcd73a24dfd5db224e84ad6c6860cbdad5feba55c19a8dbdd5cabd756a5c31392684dfd9e057c93a6ef3abc95d7f9b61f0cda2e0b8be6e6afc9b2cfc7833ed36c18f12159a04eb4fc8330605ff4f991531b8be5df16439ce26a7452dab4589efae1fcad435b9c8f2bc3deccd4e16d0840b8de73c46da69315ff65ef354b3b92ade639ed7f2e6c8025c609defc3a03fb147bbadbcc1c83a7c7bfb6d9ae30d9fd091fafec89ddbbe57d51f3d8fcd11095f5479edfda6cee3844a79a4a30fb455de6cf54b27d9ca66cd53b32dd011fa3445a551363358532285124c32e0c21fdc9a81f81e2a673f431eae4b8ee0a68a937d58dea9d714d073439d1b66999bdf2cbd1cb47121a0f480cead8cd90cd117f23f2ce78ba42657ae91b15676aa747024311c04646e2e8b7c8d6a813c859c1b7dcae95b2a3f06801530eb25ab65a1f455d7080a4de51a115e501d3fab4c20966e54167e0f318d65d3e6404318bce1a161bd2840a642ba31431f9a202475e2379accb23cad40388f08ccab6bb29afbf58db435b02e6c5c245d5d9d3b924273ae42f5e32344028145f40738c49b9b5c61bb56a3ab06dae9bd66f3f510e220d6d103f96ba60927dceb3889e8349f9457021601311742fce9795ab5fb874eddce34b2d65b6dcbfe5d11cd76318dda8cdddc4bae5d831d464f7be385da0a23a5f9a7cc5c003fd803e06e81a6de61d5176bcf5ae3d601d5f0356ac382b54636a3d9fba1cdf06310db2c924f6897e066dc9e0c30fc6597b24db4012e62e4ec8f8e76c605d65ec546c83333dc8d765a6d41d1daa278dd2622d87028ee2f1632a9926262057d5510efacfabd829dfd07847723723b8af034b88c54a1cf4ee43df7b725d72371c01216d572b19020431db5b46355041322994d79819250f36553103a22ba3790ea6dba4c470dfb9ded46bf1bb9484b968ded4e0b61de8961d5ebf7343c942ec4902e0ea9f48de3573596646b082bc807877823c672965c6625e4ced3c3512253a22e05983d88a4863cb934b2be482693b24aad811c841110b3ba5ea8d17038cdead9723c9894f321acc72f6af810d6e51735cc945a4a353cfafcb3bb7f85bf27e55c0f6cffe8f0ef5f1c7e7978f74b36ba4cd15281f7baa27181771c852aa84ba1164921a6c9c286df82305146ceb989e9a72a8ce9a72f41a8efda72a66da018ffdae77b6d9a0600f9197281ac8ebaaf0c0574e57dc30d7bdf781754f03a0cb79e670b8df24c121519b8aed5f7247aeecaefb30bde05786772b5dec6b057a16119de87a14559fc66fc0073fdcddc895ace9f952a30c952cbf913390d3e667d912afdff3f803116e57d7a9e4d67a8c4e88b8afd6d1236050f44cd2f13af10e4f5e2b641168e38117b8eb5707d8516812ccf19121c48855856b54c7d6d25263b63e9205ad3645185ddd254e1a2b46463a5403f50e523a4a94a5bd2bebde23db4f4ae4924b27ba01681504358428f6c28a415cfd258e22bbee5addb93aa0df9ae5c023106e9ebc02018fa4334dc3b69221b77863e6fb1b622101abd7704e1af78b8f47ae055fb88e9c4b785f3359361a724922a763b10984e04886f36d506809d1bff5d17798b7ea4ec34dbc563bbbd8e926d1e473bc8d29c41a9066e8d499f592186b96a9f16f95a97aa2c95163244cd016951955c1522a38092606c616e57ba9e3305e19d1cd163fca2b953c3f7b77baf5f64792d2b17cb6b51c730ed93855925782138646ac810ac1a66922cf8167717751fb45e629eac9ac6994d5f47a89fac7ad02a2a0c71f38c0bdc91facccba2accb42723346a7f6510b0de5e1b2ba943f504512c6d82e83c37e7bd107d986d906e00fcb51efdcd98a3e33db141d6a97931257c398fd9dd6726ee3d2673deac48b39d6fcc262b3c855bd0388c673c615722a4cce0b6c5acf68983f3b7b069cae9dc060b5138097ed00d61b013c91abbad9bb9ef7969e75c366afd070dd6a05e62cb1a36f8fc12459204944709bc33b7e4c5c03736d6ed9d0255aa5e95f68238eb6dddf983480bc95e9823bbdc4816c458780686ca88d1d805295fe44c7cce35dfb7b79a3fe5e522775b9a0bfc89bb3ed5a372bf6b5bf657a8d36ace0de6d56d0a2f3d6d940cd5baf9cc5fe9dfab9f18ac58cfa7f8f1c7637cd07d2b8dab7b2076836e4aac04fce1b84ef9dd8d966e072bc722d35e19a35861ff4ec8cf036030fc48ec9f27884583024d095d01f5adfac207eb2cebd2c7c82a9c56e0bb25380228cbbc021d018aec88cc6a1a4d8634d1838b0818092ba5cc407438117a88ee72a8a36125044111b2283a18040238eb96638f8cbe781d8ebd0aebd4be2d7b6eced69fb7cb5cca32ab9721a19ae7fda45d302e3484cbec346fcc63f733478f2dfffc01c0d7fffa35d21c20e7f375788684737ced1b019287943079a09f7326576a6461cf8d9adf2f5e9c747a50fb33502c570e8c6720b4d2b75f749fed833b004dbe7d0b23acdd4224fd62c9cba0bef19b3c40607e13ca9b801f635b767791c0698ded403d85d72736c39cd8afbf5ff9155e97570ee3b7e36e3c9d7e5c658f540f7cea3a1efdb03d7fbe1e6cd68aca92c73ccdf3f18dc159f9af8fd7f069aff33d0fc9f81e6ff0c34ff67a0f93f03cdffdf1368fe0382c2df3412fc7f780cf496e4b84dbac3f3d56246da20f76c4cdad7eec66539c33f236b7fdcc8da1fd3110d115c9142f206a63137f4addbd0cf2dcdc277b14fdc2cf50296396246c303110541a1a1c4180cda1fbea00c033b6115fb2390a5b546aab6843431c193f0ed27076f709df061e7056f849b7c5998a9e83f492b4fa8ceabb733b56d0c6db6b7c708074efa55f6da84efb5442171d1a1de4ccaf962594b58434e97713db075e28587c2cdd8f33fff278460bd75b0c8cde787efe64792f17e94c091f3ac38cb7e95364467566c0d1fdb6f847b0cc3c13af4db18f3d5f47d83e8aef180eef762b15b21ca3b8ba91834ea899138fc7821612d87e21bc83cd4a7f3a6a157bb6db15737c758dd21b46a8410ffced14d7721db1f2bb6a9f1ce60974f4cf4d088f577cc8dc45d8054bcbd560fe1c37158e3a5adb176350a7a2de86a859c7e9fe417cf4ec54920a1692ecf5923529fbb9378ed4cd50946256d841a55c642e51155faae2ae738322f0776187434bced58d0bf3786f887f6fb6d01f7bbb100a86fcc25e0fab38000bd2c026f8d33fa11e6f81f129114bf92ec143dc8ffaf8e531a8d4bda16fff3a02d76a8719fe06835b2a786b5e2d2d31de3fb364fead688a81f0039124c75c7f8a648d22c01df359a696b70cd087bf9fb86d834bced41ec38de38a4260b97190db9bc2578260c666faff1126e582643c5f6f7d47f83d06adc37c0a2d3b6f4c1e7ff93c2b1fdc11ac83f48fff87102b1c5de34fcd5c70550bb99d8d3310fe2e3b873f4c1cffee2dcda7fb51e7f5f04ccc5833b04d7bc759276c3275b744e7fa73ced26389b51f9ba54e60d218815bee9e39c78774ff7c8f1aef0d6d17b8485f14ce55ba24f2d32d9e9f308447959c8ae5fd3a4e903446f07022bdb4cae7960fb1f0ec5331b7217ac8d6d926f7cb5808b7a9a5d4044e2da886d5553bc99493f369519e1714b00a72fb6d1ced8acaa247531d722b1947650b7dbf3db0c419683df9d537866793e121de0623a4dc7bf03ccab20c660b8092116f5e8ce77900543c59de4c01f39dcca479017df3a1e4b4c3c7c83b82d1f16a3e5cf802b7f065cf95353f0470490613140e282a6cd6ebf918c8fbf6348958f1c5065f7702ad76db107fc402a7ced7689a0e2c54fd91c3d054bf3b20437d5cae613f663aa7c504495309e8a9df0bf3d908a1b04ddde74397bc6b5db23a71858fff342a67cbca0285be901f4f08c82d05aa9f154d6cf78811560fafecadbe598378c651275140cf2bbc4c3a9b0f8249e685c8cfc290e78409875a3d5baa5d5fa784bb89218cdb8553c9280a6fc7eb14804a802f2a584a43f6037941516a92870e878598b2b29ae92a216093a49aa5a3f45ee3f3b1563595f4949e146adf8f7cfd826bf4f6c932f6e19dbc4adeb7f4278920f8c4bb253bc913f2482c8d6501b5f7cbc501b5f44436dc49d1979d00dcecf46a2537c146ff06d79d065c237ebbf9d2f77cc97eb7fae57f7073082dbbc5d6fea57bdcdabba0f6c73c4313afcbdc9af7a3390d0af9a5b230f87e259252ff555a8f18818d969991553512e6b8d7fc6c162ac6f0d657e4dab6431f3566d6767dc365fedadfea437f3c16df3e8deea4ebabb636ccceffb16b368f3878d79876f19bdc7cbffe972f7ef77b9fbe28f76b90b3bfcdd5ceea21d7da8cbdd173770b9dba8ff5093a4aee5e6d42a2a2ba6b9bc5176049e04e1b0d3174280005fca542485387d2454e95cb42649212a69520cc33dadc15b0ed94f9140b068e042cdca659e9a478d7eb5504606a13b7717f6a6242eb1c40c3c03c321d3486c4d12c3f3a67859583ea6e9bda055484ba98a4e2de6c93b29942c940459885d9c4caf28f0589a21ba28abb92e4845a2448244ca32211b8df8a3c3e85a1bfd15d8e88b3dd1e98786fbfa63afd3305ad88e995bf2c2d014d9d2190f7ddfbdd2ef08d4a4b836a486d348037258a7326a2adccc7a9e8481fc0dd0274f5f7c2be46a5156fae13c4f169aedbc9a659319e0f33bb916955c5452c9821275b2c48c1aa7fa1a83011414e689527d48fda54a315faa5a8ca57898cc65fe50f3b2592130c7675dea029b114c54b2ae3279a959dae1508cd761579a192e2bc9ddaf7e51a2fb964dfed5dc84137bfdb637682ad494b97ec649350a12e4000e8d97e3b1c6615e049fa0d4a82a4731fd651f699097f1a72d3b0f7adac17e079b0225d6056414750cc13a99df7891615b50198e1a4a44a3f444bc6ba2c77981d71ebc9cc5a7e27bb8db05cb94a16f164a0e772985211a24be14c05f42cbff5a24553217bf7dabbfbc3f857faeb15cec43284be24511220a421d300f0684a3bc260d3336261f605da9a2b462bf6190e06b8085c00d445d71c8127e4c65fd9ca66004665d4986d84427f4534a0e0aa8136a5ab8584a0ebc20b972b0f624115e3e0e8f536a1f80c9bbb16113ea2ac1f42f499e1b3edd64e833af6b7d526a7fa9e2eb19af64babba6ecff95a949245f0f43aee4645923c196c96466c7806e7bfea22f924a49b27dd38f1a8586d97d039f655eb955c444d3106dd9b2bef8c5bcc17f81ffd2ba105b1779388671165b9e8ea60f3fa022774501d8bf20ec5f1c6ccf43e417f1359469d8bfb0bb8946c99abcfa2548576d0cecde5c66f20adee1dedd46cb69e3eab65e5c3b1c74c8e1a8f70a451259516bac9bd42d67ccc730124ebd7a7d4d30f61d6ed6a5408983d7cc9c604b09f69986042f0acdb448a57ff1d3dfec51b73375a1f7080d3835d3f1d0d174cef0d10edbb82269cadb86cead818d81a4d0de65c5f3a498caeec24af95dc78375af89106ab058aa59b8a9b89741ca24d362073ae2efb15bdbc8fe5a2155564c5ddec6dcb4d5c446ce6e406c742f795942b062bbbe175539ff508ca096630c2b71cd90765f641718130255be56ecd68ae251e47694d1d842ffa0799689d8f7d676519597e4cfea5c0d8c06c2280e3f14859f60791481fb6e32fd60a89cd666c523e708f164391fcb6af0ece9d9e98bd37f7efbe6f4c977a74f4e5fbcb414b6601d7ef87170abcd2d87773f1cb874a150d0b995b078e05359a3aa0c252ebdb82388bf4c5db79408cf0b7d615a7dcdd7900d2e5c2a1a89a3e6fed21b7866361845d2ebe9e4e4a4a5afe1503c4c0a314b2ea5982ff523cd9ecc0451592573868796b707c1f295144af3fde3b550d9af323681ddc90f6f1592a07f48fdb8b0a398e3b9b1080d6100ae4a23061f274aa6a20436069aeba72c886a8492750df1ccd9b9549080f71a6b219db00d0662f57efd7eb58e1ca147de967f5756f75799eaea96ec942c95fc599c003cd4763ebde876569d1ed87fec1f1eb37a2f1bf5d65e3db7524cd87ed8178bfac8b7ff97799de84ea1ef7b281a4fc64ad71eacc4be6e3058f56c1641d6ea25b67a19b65a53ab356fc525efea5f558da2f74579d5c511f4c5514fec09ffeb4bfd95a4338d7c7a30f11fca541a1ae03235b1255d381dfe36769814c768430f7baa310555cc800e99129d554753dd79524f6660c84321f297606269c44ad0d885f4879fefdfebc6760b03a27ed28e231c8ae341333aefa6d4d1b87bbb301da3ed641ded5743927ebc895b41c70d38c8411c153f2206d1d09db8eec145597d9b4c664e69a459560f877d6e96ac2ff4285e1dbc261b81d75c1b969645a726637676292795140ad3fa8a2e643680800c0db6cabb45a2ecf1c7e3a6fe0bf6f5229948710a7b9a4cc82709edd681ce98caa737e63b32f38e2e34ddc61e746704ffafc4de601d889cfec07d19f2813e2c8b3ac90a855de028f1052f534b8294eb4c2df49c3005049b18c145494a25df7068244e190e1b3ca63ea7ce1c5c9f551068c21f4e1096053e0f866c04b1566e44310214f44e03c83b6fccb0dc9e87df8a799e5492619c2971719cb84a2fa83f50793691dd83be38b4186ded29c81602ad21ecf6347679003b839ebcae7e2a17959c00c2a03cf65256a0f83f1a7c3e3870f5ea322d4525e7e5a5d46c87a9f599abc1ec30ac258695d7da7b233a6a933ebec9d540bb81b1f46cd25de00fa466073345e7f04ae251a425a437cc85feeedaa9722eeb994d9b42e738da85b98588345f497191156983850779a8b5d78d716878a925862ad8f0473b6d1bf35ad1f569af824ddaf62ebb92406f7194fab18783c4a75900c488f50800be1809002d40564cf50c1b4d2344f3daaa1ff7ed5f7509f2ed7409efce8cd32303d07b3f0dd803ea7e55256b515e30b183b94d9605c89e0da905e429ca82465e2e8bb40ff2ccf9a25e8b04e0648ad6c4585b58f4e5eec83ba22fc9e6902927638d7f2b02df16776122496d267103646db4f813313f36625a7fb7c6cd1a32e4b7be62b732d6eb8e771d7f08776d60fc3b396c2688e5ecb4f82648b862c6188fb56659602fcf8e1f19f1ba71d167f4a4fe909b1d35dabb5eed03f1a392fca1a569805bee931316d7f543180052b47736f380661922cfcbdfeca048777abd99050221104ec9e88f923c0fcee32cab45adc91f174434c4de0491b430a401bbc1954de3fecfa183ff76b205207e87e7004d6c3b89d8883ae64ef4900716971ea193bc544c8cce6c14febb62c46d6ec6ff207ca21dfb9f740d3a54de7c9135aec8b8d8a80dd757ad58ee48e43e90487ac34c9615bcf457625242ca4946eb77b99dfec4f98f84f3abdf13db3913c642e9623c5c42344561bbe136fec872979f43c14b23f550abcae23ccc58787b894e63aacc2df2bc5568331cea7d352e4a60cb914da7b2d2ec455230e64ab35a579244a2a0d8498ab551045a581b94967df35a2b4af608c4193759e73b77c427fe8ca2fc6c3372f20dd8d3f56dc9c9fa76e464fd2739f948e464fd3f999cbc0c4e7df3a4ff494efecde4e49c6c968e8d3527063df1dc0ff0d3b1a78a4423a3076b8b7d80e80d239f8681ded54c56d25476399043add9e560512a50cb1b80a845eb3574a2aaacea07eb9f204794815b4930e2f3c70065035ddde9d592be187b7ab5cb037004461bc07b622c46823ba85d1e7ac5891889b1afedbd3c185c499b56ebf2d0fcba670fdf016503ded7a5f8e7881552fd7dd7b66de65755b27850aea4ea8ef57f9906384fd6e5b28632870a9ef7dcb85cb5dbeb21bcdda2df8fcb953811d0c025e060fde3e176a6f324d165ee24ab916ececde5e1c3c01e0f53e24c7cb142a6beb75fbace6d18170dabe0df84ead6e7c165e970e36ce295ac1f43f1a36caeba5853f55162ccd7dae582812ac72d6b4a00b6ac26d672d5dd920e8742d5652505a66623276d55cb24d5b7948b6b7c25327d3a71561c2a257533b0076e39cdcadd33457ae92e96798e6e2b77eed0ac07c96592e5c938c71c17a6d9c8145f3e28573f242b280c874d49dcdac73d6b1d37358d0c9c0d6d867d7fcf4e4cb8a3e36596a78fdd966f3936e1f1b28708d3eef984a7410e19ac3e397ef4c8c7d002a2f47b3782046d4ce21c0d04d2eedd08445d2e9a6331e9f76e0489fc657a8166df20b3bca8ef17e98b723182351b4cca6292d4ddba5c98d30ab3b95fa40f281320fc36f5c82d8faa5a4c1935ef1e7f54b666c7b4bd94559d4d34dde0e340a7421b1ac91197ba5c0463388f9ae34c65fdb09c8fb342a63f24abee3c593d4bd2342ba62cf4785fb03b26f4c5752d5e25af59a357c96b6b1914d41b7bf5c6af9bd702fa7203d562a3c06362a814437a24e0eee03b936fdba991b6c339759f99e9e21539ad15f2ca9dc0c2646102d02afbd5c9198121ca14752bae122592bc9249ba461b15cc5cd317b9ac95b8c82a558b4aa6cb09461272a6746e25a89745a95e8b7d3b1f5dd3517df6314a4deec19d61d34dc205626959bcabbd4657346bdd782a6b5a2a8fc718976c61fd7ad67ad2ad32e6d58ce1027ab03a6836a4bddf9ec8550c007ad83208fa430484250e312058e881f11d6a595d43f1627030b32807c3bc7ee92960304d9c18ba0f8195f1dbfe8e0712a9b1a3a5c704f97b73cf70d0df1b766c47d89ab832cac830c28efd939313efbe7effde9d9ba0d05993f10627f6c41d8785332cf40e211c37a35fae9660fa8a6f7388c93099e9b714847c4154ee28916695643a578f5df24f4cebac46ed938a5fcfe85ef1835d5747bdb851f52e44a9605112901a3e2b957e2c7ac710e71d47c657484718a5d51fc2340cb640930104e73f06d8b76b8f860cd6ba891b1bdec93e9d19ac823ac8444025f6952331fbcc10b07169fd9054d3ac505db7910c873f64b1e700f8bbb23237b3b24f747fedb1a23811bf613ae383be8044c2077d41f9890ffac2a4073e30a1ae2caca68124df5c4d713478dc1ab6bfe16e06fb6d25f63d7f17115acced2ce0a0efc516e055406e4c74f351bcb24f3f22d7bb6191912bf5884fe36d524953bbe51988271a886e1f6bf70d3d687f1e42c7bb3e648297618cdb300526a199d945efd9f2fe3da72efda00eddd95e25178b80a17c838471ccc7fadc1561275eaae7054e065a1ac8983428b717b1848bc3a17894cd31c888b22439416b21fdead3ff29f4f62ff39cde80f84a1fcb0bfdbed2ec94076eff1b7125511e5597b8b71878d1d5c28fc158b9331b99377bcfc19ef84d0c87c23d0f711828fe2a28e7dc588a4aee5f64e0509e1520119b24ae6fb618201fa0950c8452eca8e150ef39ec7710a2470031011671c430da3f4a8b3c99c89d0fd352c9ca9143e21116012bbcf228a563a6d7def7f5c693f8c79dbcdae3d0dda160a8a9f79e38485f2a708f2f0856190519988e3910c3fa8550627c1c875c1137ee83167b9c1c781d21bfbcf6be5906762df61893efd531e21137d87d61666f2baea90202f43d8a626bb68aaec18a4671c578383e782f4b557c225e156f357c805678c25ae3bc38e8159f77e41472a6c44c8a3333b8ded7bbc56b4074b346ea748478a00b64052cb1301c819b173106ee1a402ec21fb889eb10f12b4029d029395343e68b85f373623e912fb8fb3c592281cd26f70137a74a3c2b15ba6e52dcb9a442f72acb02d0ed8e9c80bbe6319c03135cf05115e039782dac60588fe98a89d3ea129dccccd806e2fb6c3a931555c2b8bc17cb0a52802757c91a946f6cf8fa19c07bb41e9eee9c320f4fba94681994e077693d9385d0145d18918bbd1eae0ade8573f5e4525cb1ef5498f450d13d11496b7628ba991c8004ac3412ac5ebc17bcc8f5e225efa4425f3863fbab4674a1ea99e1791958ab6210169417d6f1be09dabddec5beb0ed9242a08b2d46422624b7a66ee954aae826d36ae3aa53bf03f10385f9b84cf22c15c9452d2b61d2bfc6c0cc0caed003ecd680808ced8bc7fa1f3d687e0606e24c826b23ed8f5a2b63cd3c498aa2848e4c3451ec24d685debe7df1a25cfc5e1d1862fe1cfefd9d3ab1a41545991fab9b21059179e18e8192d5653601a7884b59ad8592f98590ab459e14495d56eb8110a7fa0d5f49b5280ba447e0ffe9406894d45c1919d19ad837b966811e43be6505237b962f35d70c169c95ccd7067d8391d024844c540696f3d34cd536020d70599a975d83ee4f035803a308dd9e82853c0803091c1f3a44d7053d4152556b8aa887ba54a2b9cc718a7426c669cadc4123f15b336ee97333c60404a075c916032adc87ef7a54d97c91af45c2c35095ec78c3602af9af655649656f02391d042bda172fb23a9706fe2e5efc64a9c0ad1cdcc585b11fa809fca987951af63b4fd632d5ab75ee22b32669faa08cd82f79519c80e3c7a5e0fa112bf4c0af5cc3cca3796745566749ae89268c09d3969083a917f15d9f0977bf9c88e0c3fbf7ce22c15467f60ffeeff7eff16ae5958d1656f05f2c6f2e7cd63883618bbc9fbaf348942de3d1c9de6dbffa69ded22ab96a8bd0455dea2a144f165360fb11651b36097695ed53996d03be9e60ff503e114174b41927cc040b08b8fe13135262677424f3730c64b9b2163c6de8c93af49194e05826042b323cc50a515475403d7992098acd31f41eff657dc639809171303731133410f4278f633d04289dd8d8e7875b12ec9ec95a896e696e58d5b366484447a7d9a52cc45bbd306f77260c5ef43058d33cbb94d8d15596e7faf427690a8c61ef86f403830b2f41cd5ccfd81859d6a8481011676785be4d5708d018afb0adb51dc4a950d3f209ec9eaa12c22abfea58faa0996773fcf5df78be3b5ea4608a5aab1b9b37332b35a9fb581fc75ef0db0d59002a78a50164f7c0f60d7666897a7a553cc330ecebaeaedb6b18eabcd29f5f3bb366fc1d15c534b1ebbbac56c45d9b80b2b055064bc84a1e3f021b3b5e8b5972a96f518829a50ff15c264a6f77566b36822003175f2d0b30d74bc44506212144924fcb2aab67e1a96f8f7ae5550b595c5d0fff86984538e49636969fd58de847a315205823190b61d7152a28b16de4b2db29f609128fa736942b9206b3e5c41585c919165666e4aca04c93ba34ca0e0fb4112bf959687deb0b716257926a7be204af81d56cd975344d3c39082927e1766f184b7096805b44d13bcf4899914e9aafac220bd0e75575dfb9baea5ba564a139897c2daea428ca2b675a8748a1919eb0bf407ca653f0b950592a91ea6024f065a5d9d3cb44415c2425f2ec1d5e6317659e97577a1d6c65cd68ebf7b0128f0f81b17d7c04ef67b8a8f42b28d18316cf0f916d95f4ba485699ea8b17f6ab7ed4808f4252a416f6035b4caf05e731863d5768439ae4aa149f8b7f2d93b44a8a7a1fc69b979304f1ae0be3d0172974cdad69f272f2ee2a53b207c92caa4bd4a3d3d12c2f6595276baf47c5014334080819b0af69832b288b7cdd17579a2cd4c886c3356e59682bb8b06dc8ded1a9f5ebe49d34a65cc321d8c75615bbb1ea59555e15761f6cc5f7fbb7f8df7bd75c34fef7e25074bf5be6b9207176f37fef3f6aefee3ffe308e221d07bdc34f00b95bc7edbd3f3c8c2d05ebf8e151bc7737844dcd6d85dde61e1f42d0fcb11ef2e323aff9438b68dd87073dbff9f3c38fd9fb479bfbc3cfb6adfce7bfe3be87ff7b70b87dee1f01e7834e8ffea813c7af4b542c8813f114b8d4c14525e5afd299a23a8d03c9fffa5ec9f764468a37a4334f35d26afac316f8b7f328b8ad6d356e2319561243712486fe954a9cab3382e5768ea3c6153f1447e7be129b4c1de8d89c089ed4f2dcb3ce19d9b2ebbe991e33ab6d9dd2ac310c5bb4b2eb84b646e6fbda7daf4b4a43c33ab59c806f84eb2f0c59e8057c45cf6aee383bf11d98906976d1974b13bb6f948a5e07316d2087f9425f871a24934733a09ab5b4808341c640fb31e748f2cd0d74faa4528d4ee1a693e09ced06c31b7f0d0b60c7409e67a40052e1b311824c335f2293762ad0b00e9c4de8b6e5fda144cd75b980779e142691867d5b346c659a1ac1c0e0265092c587e8dba46e1c26f2c4fc74d93d448d94afb47491e2cbc5c8d7e085caae4ddace861e6c832e30941db17d2495086e62563022d1c544bd94320e6210af92f9229764211124bac76563cb64df5e9eb1297b61c414d1e735511fb0450956b6e7e9344961c197c4b399f3ed78aec3d8dbcff244bff0e7e2c2445ccef4e4e6b2c01460a23bcf8a6c9ee4bd014afa95946256d70b351a0ea7593d5b8e0793723e842e7f5143f41dfb450d17cb3c1f7e7ef7abc3bf664a2de5a49c6b98fb9f1d7e75f78bbb5f7df69515e8c3f544a378334e14382ac322251310243fc464d56d91f64d900c71e70e0a2ef179e39390b3e50262ce6304f1b59157274a95930ce252a0d41b5f46ddac98e4cb145ffc942bfb28ed59d1067a4eb1ce422ac29c8becb0a6986c4baeea6ee728ed805946b1cc737f5fbcd54841bb7dfe97e1a7e7b0f88f9efe60fdff2b595098dc54d6649f0895cce6a4c965965e25b99a0d8a642e87586dbf2853b99f154a13466a323c3f2ffeeb9d5c5f54c95c2a415bb98f3decdb7c91e2b7f3f3e2fcbc0659e56fa25c2413c87d7a30f8eaab63718d8575c98b0ef13b96158300f2bc2cb2baac0c5cdbd1a87d08078383834375ec60c6974665bf6e581986b6f3a49afc329c28b54f8df7ffb5945526955d183b6895fd2acd90fb6d05fb72b5488ab4bd5ccdaaac7867a6ecd261246355e6cb5a1e6381b5391d89bcaee82329f68fcd4a2fdc0f6316403fad5100fdd6afdd8bbcbc1a094c947f6cba0733807df02d552370dca42288bb4cc96dbd36bfee93dbd2fee171646b238b21be116976b975ca57c8051e1ec0ff162bfa3c23e62efcdeb6181b0744ab7fa3011d1d1cfcaf602cecd3c661fc257aa4ff76284ec4f0d3bfbe79f3ecc7e7dfbe79f3e9b0c194bf7903c9f8debc190189e89f171dd21b75461e2c2f99bbaad7b9543309c94f35b9f9457d0ba936beabcaf9131374b1eb8fc535fff6e767f79f3c7afae67f7ffb529c88cedf68053bc758fcf0ececcdb3e7df7e77fab32e35cbcb4bcf4effcfb76f7e78fae4f4c5d3e7e28437d8131dbe0fbcd1f36f9f3cfaf6796b339f54441ade7f72fac3fd17a74f9fb435b5c4c334b62dde9cbdb8fffcc59b6ffff9ed9317672052b77529bfbee85cc9f1bbacbe6fbe9fc1f7d7de150aa407d34cac175289fd6f84b905f977bc3f9f94b51c6150353c75a415b4d12b11465249314f160b9946aedd545ecabc5cc86a302f7fcdf23c1994d574288bfd1fcf86693951c39fe47808eee38ac5d38469be79f1f2d9b767e682adcbe56406531d89cebc5c2a9996570566eb81b27979294d91fe9b15c9223525cb4587528900398118d6a60c7e78c5ba8b66775418ef900a978b961e7399b866e5b2f60ac1bcca15850cd08b9914e77f81ec867f41cd0089252f346b48a960cb0b08284d36a926a1ec9a6c46923c1793249f2c731211ce924bb48b1843147659e9e326d3817831cb9498cb7a56a662a9a4c970335f2c213416242d2b2fc45bba8cde42a259630564937b03687a14058d3305199ee46a51494506148b6c2573a53b4f6a304d9869c482848faa9c4bb0455502ec1100b2eb7d06e98f60516c3296ba1459ad34f7afb115ed9fc07949d5a22cec08d6b21669a616a07aef035cc63b8bb19c244b8593a56a78fdbc059772035e332bb73d000fcfce867a5bdfc01606595c8c2ee50c36dcac91282b96663dbb10cbe25d8192583fa0772593f4472553dddc38e2f72d5a303b59449f207d1d24a78b3463de66f564266d3a33cd42c21f0328e80effbfeef979bad7eb9e9f0fe08f7b8bd5df86d8dc9ae923847b146bbf4b1f5e1dbeee89919b64186ff8d49a2c106e22438cc885a11921e003e084a65ce512625465172809774d6857a126ee3f467e33e62c97b2904a81091b3cb9d36616a6013072b2dba32333c0a43c9809d7a624159f6a9cd4ac5e35cf0a7c8c276aa1d9fb4a9f47e0ec178b7c6d339c162598086593ac364a208de9705875c3ec2223ba3bf4e28d67f543985b17a7d8a7a1b0ed569476102b0ce0273d3729f955f7ec41cf144f657dbfaeab6cbcac65b703ec06c570a70ac481907925bafec10cb29a401a848670d565253a1d8db67c8288416e7ed2860ca38d4acc1006e7d65342efb1d59345478bebd661febbd0c868e336cdd02d88bd26018332a90c41828191dd28284f58e8894aa21375598854aaba2a21fe0ab679c57898d74e02418638ccaad670727caa4eba87cbce66e4127763ea4ba6bab6d40b8a06f4d34bb48a5d61792041b59d61e9157725f734de6ed1be2bab895d238df974d0f40ee725a64c4a2ecb2c1572555789c048db406ee18c65459e15928099802e7d32a3b8822481681c2cb9e5833bb6f8bc929a6c4da442d5e270b8934c0024016a7874f7b32f752b6fc5c489bf8260c70413ea30bf410fcb4e4e10efdfbf17e1f74ec7cf7280300d767ae4db1c668e9e2ef9866ba6cfa5a59bdc24869d554cb061db448cc7dd24be779131fc59b002360ddd9093156bccee5733b15a3809209a4d0d20591ed029c24591cbbaa3884686d49327a04714d197bce622c6d2114b43bb974a56c0b380d676bc36c903f57d40766fa8ed6750bbd9400e5c2c3be8fbb9eeba47c1846ad74f1fa2e11ac2c5897c79218e06c196cc020a76457a0593363cd2a7de85a35e8b2b03c3244b1ce3a8e451c71b615373f05e8f717318cf3bc84aa4bc8bfd11884294504c10660db0481846b677e0a394a6f080789ca95a16b21af8a2a55df8affbcf4ef111f222a9a6b21e8620ff7a965cc87cfd868434c594b200bfa1211ac3628ae46adf3154ac3c60ce0ca51b1a1cf2363cb4535d576b4e235c52627a8ee3e658aba5dfaefba2b34894a681c67b835058aa3c2beafd3453c93897fb855cd5fb902b732aeb5a56fbb833a6c1d48b95eced3d1b67d40fcd20d45556a4e5d5205cd26e478f0c2406d6760cc58b6202194bba5ed401cd6965c55253f46952a5b9e6c7ca0bb445380fa2c3989169bceaf66c9250932e85d60543432d3509d1e4474e6aa40d0f6795bed835d275dca3b3839e1ee639d9a117319a60dfe03ef9fce8cb2f285e531c2736a2cc3df11b8d7e0463bf162316ffcbb27f499ada65d6cf923ea523cde9232d2cbc581afbe257ed47c7d9f46e45d3cf9d7bc5ea1fa3e34925931a211104321c5bf5c5ba2f305f2514fbb13c08b530f72f3464aa2192ead2278431e2b08c409c6aac4662e59349714facc488d7598fc4ba5167cdeb3403955c8030ccf6da8525f1d372422899f54273f24c6af20a6a62c6573d56f7d332c110a76b5b064ede1f7fb3b5aefaa25414d46db0a62d6cee593dabcabace65dabd28faf026bf5ff1a7499d4ddea1e59da3806017574dbdac2561d6284b30a822c4021c8078520f12d3810c26499e771bc6db340a4dcde8aff7efe14fab82039b431a5a8f67773683f5c8a05bd84afe6b2915c8e5beab92390d00c962bf85b8c65680d4c50519a1d330c10e9d99a05ffbb6cd2de7e55176d99de4cacbe8a8efef7202ab32a0fd458ebbdb49b34b6210643e8044c64f92393c1e738ce6dbe1c801f9f3af89ea9efa2a3a1b38fc460a8e70f8cf81adafba9144a9c9ea0cc3c490103ef2a47d042ecf4b88e35ec8eafb173f3cb6429e0c922d41b22c9b9548a66259a8e442dee2fd70f7ab8323f7ec8451eb65b39b10caa259d22a54486caa2cf644871417ec754b8a83ad0db19e7de3229c01c8dbd287b32c4fbb0e00c5adc2261beb001ac03cbd6a08ddd090663942f6cbdf5452817ea0794668b06a529579fe185d7669eb8f23355e80ddb75f81e6b2018457a309c2bc7381212bcea05674b0fe7c6ca8209396b6e741e3773729e8440787d0e9db7e06e3ac485db9c10104c541e01cda41b872c2862024188d9d1de89be96c59d443cdd57d5756cfe185471c42f300e3544a710202555f48f2febde836bf9e88dfae1df62faa72b50673298033c007e533faea62a0fa496807569b8284ede424aab76134dadfbd40f411185ac4b5388cf6ebdbc95d5e2ddc1bcc8c908509a6fefaf9179f7d31326ceb1c5e62ea5db68047eec3b333e134d268088c9f43651650750209516f358396a24b017aa590c5c55ca65952cb7c2dba90acc781079dfcbdde40dc9f4ca452246425986fcb8b0b25eb67202c7febd41260477c01722270d5cbcb2b12deeecbcb245f26b56ccea44988553d60d478912cf3accad46c7837bd7b74313ef8f270fcd9dd2f0e265f1ecacf92bf8ecbd53e66da5437a7e87ab91dbdd40806633e119f7c02ac2d9f27ed127c8705d61bab59ee6e73072201e18ac899d9fda89033c39643c104568860060d3f08878d2fd83644f662f7a63297b56c1ba40d25e62f26f6b3d37a26698a8c43302af7e40819eb0f204688578f415cf54eca85a82b7d7ec0d7215374a40c4780aaa9a52261e8a3a73f08cdfaacf1c4c2143102f7a0c94bb8e5f2b90bc3233166bb713301edf3db07465f13cc9588703daf99799241d17d2691ba7307d560a8127b52a68e73d5c0f4297100efb9bf07933c93458de2269788f5bc365bd3e50f8e0e0eb563f6cb175db90eeedc69e9e16b71058568ab169a6019b1a451f020309023ab599514ef4c8a2bf4cec0c158c9a452cbb9f440e1cd3bd6ef97c54226954c07e2ac1457563a9d4c93ac70e26b57df2414dff7e0c98b0b39d1cfb47c2de6c93b3712354ff2dc621307845631d8d1c003f680f85e0ad69e01c72bde5aa4798b712328ec7cbe166fe969f2b64ff0fdb1a19d00809a16a5669d69b100ebaf66652ec5514c2ccf575e0f06d631155755594c510e6c52b7a1a41315c332edbb40f56849e501abaf32cced9ce0ed24ba8bb2460725a3ebc6eccf9ab6f75cd31be29d27e1ecb1f3ff6226ed512da44c15797927759d4c6668ca07ae97652a4991dc17aac4947395e28199082278fd819ee9ad6ef4167c7502689a7e5078a9acf80525964633024331f1d835cc285ff6a1a4a28d0ab41f50108d184ed9b5f4c5cdf6342383f900e6d8a5567d76da61f1e065e16f929383be689eee39a9572fa533ddc6538d0f11be82aa4e480bb981c377e97363c2b2c85d74abcbbdf52a20346c5cabb6b08e73189e0e0b61dfb9b3696f9a45742de3dbcea08bb51ef5b5f8bf80b05ff3776814465a3f6335421f1388a3565bbfb4855e6a4061e676aa9ff28f4886f1fe6c96a4e5d5f3b2acaf455596302ee3e9acff44b7698d00f0ed6be8e89b413483fa441927693d4e3cc378b4a2da775df0f0ecac6bbaed6b003d9b13d8709baa4e26ef8cbd23309dff1a7ef6d5d1d1e1675f35d1c0c06a7221f112f72c02c195d97e9ab202c30e153ca8c3625fa8a517e14474869f3a6538989d76c49e9e1ff35b31b6056df22428b72a27d4112a4fffae394508bc2457f570a25450998b0e824e5ec815ac46572fb98d08494be4cb1c34281f2b1bf68f473695b3f5dffe49f3646ff5babcd5bc2c5d79a08c5cd6a57ea04c0cd975b1a798bd23c51cd1d49a20921b46be262b60f750239f7065030358fa4e97bc79a193c116015457593d99394b0adb3ac9f55b45ae6a591549ce47d57d9b66aac6d74e7730cf8adebdc12feaad094480283f4f8a25f82064f305a441c704f3ef24195665e32aa9d660e895d4c0ba005793146bf1f0ec99899470b6a359be11a11d1d7c79ee1cc54973f5f0ececd42c3229411a9ef660c2665f9ab3324fc1760ce269c180cd56eb159685069bda903b26d38e2c2eb3aa2cec7d293e150f2d37640c150c207d26ea522899db6421d07de0a9e06246b8e48f34bd37340e544a94170205c5703d76aceaa0a329325530f81f56692c073798aaa42a97d5c4d8aca4521f0b81b1157149fc20101e8945d3223acdd746c78d01ceb0cce3305a27aa7999c76592ead93abf7f9f1f47a9fb2c5383c8c6374c0998ad50a690ef53700de8334361ced8a5325f2aa3ff07de576a9c66106d3006907438480356e72698fcc5df3fe31c93a64a9e01d273734ddd8b7cecf6c4c86eb6f7aeaa416b0d0df19e18cc4a558b7bd8816b3498c92475bc98bda65cfb3e2309d120291bfd5c022b33dc3cc2527444d1188a772a37032127153bcca9ac09b91eac4f531626c7da3918479a6648d6d08106d238a1d681b409a2ab9693994894f8e5ffd58fec98afccab834690a4ff44df1dcdc796e60e32502fb2622aab459515354439073bb5244df74b66988b2146ac9b8f0587d68b7d6e003b8aa1f8bb77c94215b21ae2797f90979377b2b2606e6261f5e5c1178e73a055a069471c925a7d94b8abdcdbacc0948ee58568102c1af273e39444508e1ebd151749962b77fb52e0420b965ec74921327c4d9615496828e60a109c4555d6684dc0af0ef19324cdd27429953292517ca5821dbd89ab9455a22ecfe090747b6413395ed6f414415912a653bbc8e50a6e59cd0ce08b596475c70d38116a7971914d32408fb24831ec56c6e261a2ddb441be476438a5bf628a7325de225ebd1ddc66773ffbf2cb2f6ed3eef3c383a3dbb5bb7be4ceebc4e10cfd4907092851e6e7e01a0e85be8cdc0de8ee4808df0d16adc08f01a30909c00cfb9341fe6394d6205b67500618258c4242dc11bdcc95c4e83cd10bf79c34d203ef96f428219a8a9295af477d8fddb31495f538f516c73fe7d7d7379a9f5c262a42e2098e1f8c9f9633585f6698f849c4dc75a7a03d64096b2f480fc2804aa9e12b63c6666d235f4762cd57e5229059189b778216c471d2c37762f04c3d59e6f9d3ea474d42bbd0b217b386c3a7af7bcb40b74e0a1118ead966defb47b7e9e3e89a522647ea02193dcd028d2e514ac073b569687df14eae9b16a1d0e2d53bb97e6d0cf99be2792334c11de7c6f54c7002cf0d13c1bb6be5dac8732535fc77f24ea4999a24552ad39e0b2d7305b04933af924bcdf0a026088ca8bb3d6e510df48b10046531e28ccea2939025ee5ed3285d73f6d09086cc4a7790d333b69f38daf1da9e53d61630ac490eafaeae06579f817de18be7c3a383c3c3e14f8ff667f53cbfbbaf7f1ddc3dba3bac67721fc1182b8781ae6181b5dae715e5be92f9c57ea25436357eecbe3d2fff196a552267c83bf5a11d58331257d49a2ba4024ca47eecf380c8fc9108d527bbe868e6c46be48a46ee396411876623499e8b71555e2959394ad954ec18ebd650b573bc9dec38898b69dc94b8c44b9cc4c569dd3210a218e98af9a26184df62add718ad4e97bfc2a5cd52b1273a6f3a624fa07117d7695ffa593dad107ba31999e5ac2dc67005b459c8a60adade160d4bbeff4ea81315c51267ff7190c58f29b709251a35b76f3fbf677df56ddba803bd6cfbfe5ae7c3a178f4edb3e7df3e04edef991790a12a2fb3946426e364f2ee2aa9522bfd018f6cb48267b6d50d835313070d05af1b6b7a908dc9435f3c5dc82a115ff4c559729154595f7cf7dde1e0ee5e5f9c7efbd5de2d3df2b6598423d820df325dc776e05829958b4a4ee0f1876e6597b202d7cca3c1178303ac5397a98daf9ad4b6c66731c37277e99b7ec40937f93dfee02d8a9ce9f65d8a55fe376e5464381bf78ad5ffbdb78b7505de18fc209aa3f65f2f9e3e7a2a7ed07c0c7b50188162529420bcb46f86a4c6808fa2cee692626a0741514e0281f6c04818c5bd50d43d0a829b7898f45f85f1caa71534759b1b478fb3c134abc765f94e0db272a839da5225b91a02e755d44313ce85f81f00020b7e34f81c177ae80be423b98dbb816cde4280adb2b24617dddaf7666806677d98e47a6912fbd42b0b55574bb25bce34161b3f4626b21146dee0169f34d1189555bcfae9b38746347af4481859c6fd67a79ad12cd2a44a5ffff65f7956bc6be32653ea6c781d4a643fb51181357b8e46eaf805240a1473b81424bab39caf0dae607c962661d4e16698e0175627110416b6deca6dc295ebc86ab11d6a952beeb44be05c196c123c621548e1dc43de17c4190b0f1280894f419496954b05d1f031efbbf117f347e81c7d8335db3a7fb38a2dabc196d2a6f3e03935c8235f2d2713295399f6f13d090a90731e8abbe5111f5d4f13559f1e6ad655ce30357edc6b2fde7e4b3061f81920204243d122d25b0f82d1b502c7878bd4a533710a44f3ba87651ea800884bef61c7be2f9ecb898450db89e60a35a653bca8201b803dbc8a1d5d7f08c226a3e9a1e82f2988e5348a3ebb7830d6723259565e24ed0d0fad96bdd1f744ebce78188bbb285352bb351de36eba652c747c6e6fd35bef1a42db65c75eb00e85f31b69c6a0a7a025c88a9c87a1e8372db45ee7eb7e705ba2b4637b2aa40526d818019c205f11a41e82729b680383f3d665d176930234ff0e3cf4ee401812d56baaa4ff0183f351802a6fd2c0d959bc7a1dd79d66a9bec92e32cdff299bb4282b200b8db1cc4da59a54d9a22e2b2526c964e65b374184671e561c4f8dc0f5340b0552183b74086de17e0fc46981fada49a2649f2431baa3d347c2eabcb36252c14652fe3d3e2cb40f9b6a2c00da4f3669368c345cc49324cf372e17f4799a52e6880d0414c9244eadab7a18e6c099aeb0990567e11413b7bc7afd9efeba36db68178a2e8baeeaf9e88e20198e53433f203fb9370dccd6d3ebb0fbea75cfc4e534ed22f25328e17abb0bd15dd80c0da6f8244cc4705e2f30df05d5d820d0c4c1d142efed799206b7da3f5ae488af37842cca2e7e8f857678f9c72e3530f6e94a73f3e1827be26a5da79109436f80c98091f2fc17b7df02939e04120cb5d21c47cbeeb2359ce432a9626ec5de7af14c35bb8e8952906936d8c69a6f0eef5e83d3a2103b5b865d2e8ba837b449d1cc47cf1357b48f34ba7c16f5dc3ada815abcbd26cd7679615a2123b36deda7b2be9fe7bbcea265f89afd76063366bf345ff71628fd5bc32f3a7e655696ef802c07f949926a6a87cc234e713f13fbe05242956521406349b33681235835608521fe0ec1b59c3c6a7b282084becd50cf6dd6bb8f975b2dab6ab9a83d23a064e29bed4419a8172cd50b3d072f4043ac9929b34a6a66dd0be11113c234fc142c9879d2cd6d4a329a36ad525d0214d19583e9407450b3f8234459edf442c8e00d7b2d5ee9257f2df6c5b71072c53ac2bad843f432821168f04d3474890613b2c60063073e44653297a36916be527892404e55812b5f37e5c67a08e4e0ea854861573b5159f6a9eb89fa59461956279257a6cfcafb340997321817fcd84b3483a9685ab3cd38707edf3cf30c6d272f276ed056a1ad3ea121bdd26be2ab28c9c2c6543c39111db3901dff163091d5519afcdadc43e02efdfebd78f59aa7b2329972f5cdcd86e7056b7083a0d730fa26fbab872c01e04190588ba30883771dde4e81cadadaa4b653568e22e5459456b53d682d962345d5b4f6d56f16218c2ce4fa753ba7c83a0f713ad07d6826d6a83efe6606f7febde8069fb87208a3eb4c667290e16e7bb76333ed19d665638a293222976ef3a4794514dbec84c6ca1c6ac8062cd468b8a02541501b32cfe0616e2c47658134190483bdd494ad9e66b16ec45211c05b30569e92c5f33140f016fa204b3d9bbd7201a1534c02a92c6da4a3522dc7a6bd4bafa13e245e3bead18950277959c8aeffd8c56799594c3daca8038559b1285bcfe92c54e02408ea8ecc71f246a71762840b03db6efb8df80a3690daa7b1c7bc16ec8277488e3d7212b66b529553fbe2354fdc08011979a76556e6a9977cb22c2ca70653ed13ecf1b2f6c35b62440cd69218166355c1e357c1631ac2aa438e4ddf64f72696a9878761f0f3bb77bffaecf3c3bf7fb1e141ec0401ad64ce581f78e4cc57305af10684ad3f2391c989f59680749cc4265728b843ca3cd02c8c4dbd9f142eb35121af28083e9ad6598bcfbc9c8ab2128f1e60b1ea593b7aea6ca9a4cd85e709ba355734ad9231098d316f0200c1b701a90980e4a3144f83fb51a15b331bbb9566a9d2c60bd4839f53de84a410df9efd5dcc9305ee2e64d11279594cc9870cf44126ee14f4a251cd68b6adeb192e1b516973becf23f955adf0005abc8080389e576f1fe7f9d0cd91be504425e53fe0f85abc32460a2104feb03303b2954312e577e6cea87ecd9c0580472d1ec9fc79c3471826fcc346f79a1569747e40d270208fecdac647311c1287420e9a7a8bccf4c55c5653c95f482822230324c51126c9af92b5b2d89a6bca04316d5573b696b6b7ccd4ad360c008287bdf26f0518685f44760b42b4d2358f4b81491e36ad465f24295aa2fa6c3d44943121772c5bb979fcec866355239844fac246253e9886c17b9da42966037e513ea6ecf72d846e3814f7d354a1bc93684fe97c7828b7293edad19906dc7644329940ee9569be3e8fd9f4616b4529896de7f021b03d97354f90cff2a47bca7fe56be70d0000e825f6c52fe64eb125c77e0b96dbd76f600a82fa36bdaf5ffbca0f19c8f3420f30fdb17913e2cc3d8ec0bf4be095ffb422e4fbdb971e1af88514657d2aebe775fe3d54f26a57753ec0c2fb69b2a8494dbf5d3d5097655e670b65a3af3aa79e6a69238d2d15243e6031c2e6652a47a253c8a4928a4283f3a8ff9de45256c9549a1210562839a93dc07aa7a755b92cd28765ae2962a79a8e93ee411ffe6ff065cf34afb33a97df950546791e89ceb8cc53aff06c914c20c3d411fffa43524db3e201256ef87b08cdf4fad78b8b0b0fdafd3c9bea59e4f2c24e6e5ca6eb462ffa631b245d1603745196b5acda6683a58d8ef033cee745b9709371d06263c0d2d828d636279781b46a7c992495acedd723fef50c4c14ee9a4f6555c8ea7992664be59acf97799dfd6fb97e60b739181d45e184812b1f33ca2a95550c2b7a1daf0aa5393bb063c3843b6ae4519cfbd514742b23d1258cd78447f5459ad489756341a91424511fb1b355942c7b528da5ee9a6882e34f190c1257838f69a773ec17e4c958e6f01e48ea6480bf62551e964b30c4a1faf7e80f120d9930149e90830fcbd4fb461c04520d78f9a1ef0e6fe07c8ad8ab127c9874bf010c5a12e3fe0355bcd6a123d4eaf1762858a70d0c5b946fc481f5b3c1ecda5fb3356bed0417f0956be64ff8fadc93f0040f5adc50f7d87409fa2e6a59b5a2cfedb0f14199ae6f032d0a0c56b515b5732c8da1760b66430b83bffa3f4a6a6ec5b5331f4f618d11395c183e0f6363b885f5f74e4467243a31b11b1994b6b93ef09144dc2058078d9abcb78623444bc37588b5d70dd4f18fc7b5bff644eee21b10e690369c689d58b9dc54d68f70bd7f9075d26ddb875e40631288d1423e67e2046042036f271bc70438984c5e89131fc2e08dfe7adc98bab77e1e7dd7f507ec4bdfab19f20858dbffca96bc6d715fc8551d2e70445a45e217c3ed79f77bdb916f3d56373df200edb6273e4e3fbe0306a0f5cc5f6c2e8601c541f017889730c93081b28ad87fdc47b650cc218c4c9e4ca4c9660df310096ab3887bb4b08cc6c644d6176a565e1546e01318ccbe405803369001013cf7144d161aeac7087f5fbdbef6fb1a4b487b66f2ae98cc1134e4f3b830feda4ec90ce39c5956e16818269ace7c6f72f3b5e93c1cd147f82e697d91cb82c9b457a00272bfd7c1ef09f1180711cd11c0122722180e2a9422fa241ba5d534e08a2408cf93eb4b5be6faa1fc4f4d6dbbbd0665c3a8bf321fd03ada50bf9c7c41524e88e4cb3eaecdc735fbb8b707336c9813040a1b3b0808943cc465e14965d7e623b56f91c3fe43d63e625b4ca62793c16860bfcc377a87a3a9988f373b6139c1d988e58300cdcd00a56f50681aeba198a567b83d8b9ccd4b0a736ffdd6bc54adf133125921764e683e9173d2f747e6496734aa7ba5163b0ce2fba56b563acf8a4719a9c44f28cdcfe0d9d3b3d317a7fffcf6cde993ef4e9f9cbe78791c1eb4bed9425adcff944334814c61788ea6b27e083f9f95595177432e20f5e409292dc203595f49594013d5f5d6ad4fd07b0d562e155ff3850c782e7f89538ff1f65711c6bd8bb65577ea370d16b25e8893608b36d0158d40f582d194357e58375d949a44c323161e91607e4a24c1a94bb158aa9928414939496a17759a8ca88f8ad489c720bc4e61ec692a5194350be6a4213dad1ea2aa718cf687e5b3a532d7063e0bd987a6db30185e984abecc4e031427f08f5167523dbb4a6110733d2052b37bc331ab18b0d5001ab47041bdf346360e5d35ccc5612d958cb511daa728a11679568bf15a14f20a93f4448c58d0e006ad58f0efba6cb41c04f9ceb0b126a4d824bb30354dd02f30e9269b1eb004c6680908d95ae6fb6e3f61902ea8fb04e1aaaeaa2bb69fc6a242d59517b244bfb1f437165d027bee699aa1eaca6a903be7e745a727bee1ea62939da2ae063850ac64b0985730bbc0fdb840fb46b4040c7f20da95482ca5873b4f738039df0b9368769fc59332dfba9076b02f926ad217e3a4ea31b8fc0e416792b2e21b051a325e215c608ac6e5386973cbb020772b5452596a3c78835f8e4d8575a3027d79ffde7d0289f0b1180e299cb4a89234a97495459927d57dcac55ee12d8ca10552b9e250e183ed953feb782dfedd567639e078d5e8d3d17b2e0e5cc3636f5c66ca2cb9dc9b29b582b2ae8b760d27a4a5c13f6d593708ea4d08b9a21716f5788ffed0a38692efca0a3aedc2b0fadeb2f4c44874acd09300ad0da0f52d0191ac842dc33dd1e9883df6e5e640618d467ca908a8fb7273a0945818abe1275e77e4b57459422c7ec0391dac5c6e90a004eeb8eb901abb0b6eeae251ca1a4fbdb549b04f284705e8d3d345ddc2265a772eff104f65fd2051f2070dbfcb80b0338c9a0fa3ea03346c1a9444f16f3814864db0715b9db49cf536305f1b42765e69ed575a9178de8303df0c944885b5ad6046f8a84aaef0a14a59aed16240ae6af789e87b9dfbc0aadae87574f5472e4d36afe415f18e1f9429313a813684b7f68aa8b337e6e377c93ccbd7a38642ac1b838095fbc1761a65a9abd10b7b216dcb4e9d40dd4d7d4005af8bc826d9cf81b6089527bb0d0442366f1847f6ab1d86a7a10a815101df381055d3be072a316fe3bd323365fb75a7cd0b6adf60f742d5df6edddc6cff5cb3ed1be3d5dd7567de70ad62031a47115f99d9a8ca7631aee36cb4e0c57cf351aa675ea9810e9143090acd8cdce79d1020ac7e030c68e84b77ece86638c0da6d4702bff2ce58e069639bf0381e046ae066651f131aeae166035bc8b1e03e047a374ebd9e6e9743b09fa3fa5eaf262b69d3f27ba4c92fa426ff3f7b6fa3dcc68d2c8cbe0a9cf37d266951a4246f76f750567c1cff6c5c9bd82edbbb49aea4b2471c90823d9ce1ce809298c80f749fe3bed82d743780060643518af7dc73abbe4a552c0e80c65fa3d1e8dfca4cce301b56af5bc8b9a42a5c9bcc21b5b5cd1d5a66d626284aa99e432a1a6b28021574bbeacf36f16c8b3dfa1b3145100886e4678c198a181b7a9a40364caa35444e8a713753145b905490d8faa9be3af4b97f5cf64be2dc880d110fc4013c4aa81f41df6d331bb48965a842e56b3503bf2078985aa9f8193103a6a1f9dbf5667eb0a7c8e24c953237acc38fa89d3e82eaa35ae6aba9ecb3506e2bf3f033652f79143c1731ce0c64c7958f50eb6155deac004699f80e2a8ed0094aece1bb2531ca1d371da79df530b1c4297118d0925902fca84a6935fad8023ef32198ba7868db95f17b5c3bb89542c0f6eb21df965655fe311a43ab6ef8f9d0661202e4da398a67f9201c1c621ae8e14d9d6663dbc7a21f7dd915fb03f180cf8f0821984184b00515ddd00583c52fcb1060af1167f819eb84301398f220586700644a53934eb47e2cfa89afc1e41953e786ea7a484f3dc6a9c7c186ba0bc281431e2139e318d403d10fd162c0212426dd1e4b3ffe144c37b8f5e21146532e3d7b2b5cf66f47ca2cd9b30a30cac66760588b42477e0cd57034c712c29f327d3e5a64577df83034a477b49059b3aa21a63b36a258773b419f610635d36e56c1d9f652d81930261053356235711d3ec43c6efc99b8a7c393767a2f86e9c360ca2c1108a0905bb49b86183e536828d1232afa7ae3f818692549734458079b078ff7d1225b0b8c5a2cd1650113b7e3aee42b6ff46aee7371565d1910117e60bf019360f03420a03be260e0320145f3311599296ceb124b5467975862961bdac0ac6fd7041634d58427867a0b721b48a9a62bb1975825c617d071dc1a7d623e9a50a5c5c3b7bedf884458b513519ee4b9587a3687ceea913870f4c64a729202a14b64f9f0fcdb4536946d424cd69642b1cc70fc0b0acae205e4e8ab6319c49823cca596f54295f86e843c158e2b34f579925110b731b6103e78360c84ec31d718168350bacd58da2257192556e248f4502dd8f3a2f1540929308813158f60e4949fdd9d0fdf52574b04c8cc006ddbefac13225d2ebb01ac0430bcc87b874cb104d66cb3a1a86770add8b506671ab7dea290333d143566fcb78b6f9b57a67db519809a018c710442406aabc6edbfc1904a542b0d51bc5d4c1258cc103e47a63503a88237859857b271f0e8bd610622aa9aa623f3b9745a8785ca7f71fe926697475079c763c4a8c68d1a8b8343d6ead7b095ae9641235c78d78a70c06ecc91c710b769c58cdfc6576d0b982bf1e808c66bb585d663eee686dfb5db853ac9ed3aef03b62105198b83c11d0662178da0ecb66086400967abaef139c03b82c1b1ef13f7960fbf587afe9d6043f1ec8aaeba26e27adbe5bdedb67adb4df5f6882e4eec631d74b18ebb58d35eff2a1e23451093e83033ac2a664420ae3c09f0340a2ce10f9920e4253f7d95a1ec18ac1e4fce854485059e157e8a70b11e9f387d7a95ea9877cdc9634097d6b6e13a547d7b8a576f9c130cee169322720047db1c7f3325b4dde1d349f5f987a6c37211a39fafbb5a48b573d8be6fad8aa4f2ba11f138f83511499549e57525b6c1da36c03fb6bca98b8a42b1f95b9aa7c903534688f3e7ef6e1bf5db194af52f540625178b81cf7d088915cb9c5f2809d5969569a1f1cec502affaa16f155a081b5ed8b571ca2b77578b2371b11879d5f01a3fac99acc21f5c28723f0f830a9e0bb47518db44a21e2f10a46aec4b9b7d7013a29d6db311bec63aac410cdd9332a7717352971c5c0d837852e67e1ec178dbcd88ba5cb13b0bcf9d3f9062f78851c2986bb9da70db41d38efb04da86143d20d5fc703a8b704b8ba3e1380b2a04fa28700ce196a2fcc4c657b521c09eb9029bcb60fde389f3b644b45973bb665640b001186fd3e78ddc6a758c385eee783be0520856223da9cefd8c308136340d61035a84e3001831a26ec2aa163eee74b54fda5a781b366bc1f6a59517128233a97929f35f8016c191a41e095cd65a7704fa18288fd831ff3824c7a2096f84b3b00bd96eb50b5f98a81a21f86aec01d741db312031653901126c1ec428b62e5062d5a6c450fb8915458060ab6fbdcec215080cf28e4f879125976be4d26e529cf6aad6cdfffa93b54fb0e6163c8c705794605c06f460b04fbfd030823b3758ca821f8bacd14fc08fc3c74f7176cd63a7b1d05667bc8de7d15ceaf791bfdc463f6ac6142c64c80fd83b87dcfb30204933721f0eb9f53b73e4835b80ea8cd877324c5cc8a10f2cc52331e95663bd4d33ef0216b4f59f3b01381028be62316cec87009f48dc13a2149b9f7b326cdf5adfb19d9fdcc0cfc4fa3b991a312e6d8337df33efb7ce10705de731f4e189f71f248bb80da622df88c19d861a0e7283476817ce73b466881f62b7f6da1b80ed502425e30b07911a5b64216dc15a979d13e64364c3ae5adf37b3c6d137c001f3cd7ef27e58a15d722ce24cd344bb5560ea06cb0027a6bd052cb575ba1fc2580fb8b811e40d10496ada3570ef1176f3b8a91fb7a568feecc4c49655689d2ad7e02ee8fac43b997db583e5759e5b9e2b7b9da098162e5feeafe66f63fa5d5805d29693b43e6bdbdf3b5b9dc1e886a1c1b5af182cb8e9b298b59bcfb66ac857a675cddcd0f7d7bb67b0a33b5c18b3bb3664f3dbe6aac1002f612094722ef33bf22056aaf28a421bf938cd18ef1e18ae3309b25ca174236619c478d2e75929568d795e221307d8ad30f78f9ccaa6c9ea355749993e17ea37943728ebf0e5fc56eaacf4cf794ccb0899712bd9880fe4914bec9f9a09098e1b4747621f132f3b593379975869062e16a6f0d03617b142c38eb38a02fd0074337a044fde9a907356ab85cf13899144cf6a997dc6c40659a9169966590391d7558d56e5fc276255cd7a7b0545a8c17065314b6bf62a381b9687352df04780f6864a50a9f9331097512a6bb36297e7d23c0aa0bdb5f030abb80761ae080328c5a56c20b98a9d0e9a8e612c9b7955e56cf26c984e547f144bd526e1c284b6c05eb41556f2c22c7ff702a10a2547416fad8eb8ef5204be0d597bab240e9554636173ae28f3aab2b08e579c25fb79e3c3f774cf00a435bf744f03ca7f657db85ebcc3ac130d049bcfc33701283251134762ff308ca5e87df903f2ca0a9d2f7a54a13d55e6dd790c0f1efbe1d4731738ce21a074e815190d8c338561c76d37c560f29d4e8a6ec88c7d69bbd320ac63753a488668f409b12152e0d22682cac44c159aa555c0fc4f0afc641755ae66eb96f34f6381da08932384d139e628f40955f7f667593a102c03ddcf88f538f4f5bedc72a24d5503e5f84333355fdf555190884d7335bdb2990ec5d986c95ae850ef16337ee6949f53c4f8199a5bc8c69383bb3f5d78e40cc2bf502e30f2e51dfcb839366182c19356cc880da05d9d5b80b71cbd5fa5ef3137d6b914069eb797f2f4c60a2416e00304cfedd453f3306ce55fbcaea97f596fd33e68b95d1bf718700ddd2b628bd68e29c6a6c8ed75b563072b52b640aaf23227a40bbb6086b22d17715b679da8b38eea441a90ca594a7321abaf1ede0bec57aa5e7045445fc299034303fe91d1344d013a6e47073f6cffb3e767bca14260981245bb6064852effd846195e7f68a0ece6c6199e94050bb461607dcbf158bc50655688775655c6f559278185b96572123a33184fd045a03df3e73494f1775efb5c475232e4daa8c872e8b55199c511359a9b43548fa6718d7550c31a2db279079aa00563bea26ae72ed4a1e590717991374656b996dae650f0811c1446e9e71d2067b6e1e0b16abf769d3dacc85e02eeb5e098361b7bf8fe7d3a8f10bb90dd18ecaba7d801aec6eefd8b30847b5e67974fcd30db32bf37e8a5cc8cb002db7c0ceccc0df36d18a5852b66b193bc92d5f38350692ef553fe3dd1fd505c2c580c6a7d0582b0f7553f0038bada1f865d8cd62ee54a77a38356a3839b1b3d6c357a1805c80de6b47171617641c88ffda130c332bdacf787627d3014eb87f13a7669b3b7565447aaea8b4578b4032df5c5223cd1a0a00e4f003fce58fc6b5ccc6393d893dc52e606be1d4de2e4dea4083dd1eb03f3d8d0bf8a1dd18fb4a98ccddca42c3dd157fb00e317c6455d19b057fb6257c42b0ea50fa1f490c70f591b20eb03ab798f5aac1f62690a5e3b4c9b1d9035c24e0c2cddcda681a5a762079682f7257d9f6cb1a0076efc915542dff51244433243bcea1a224eaa63885beab38331593d6c30b68ebeffe8c8e211d833fccbd7e984ef49a78d83c382a5fe956fbd19cfba0bc71131f637ccc782143be23c8c2dec616f3a0dfbeccb782c5479216b2d72f2060747345f01c4008ba5598a876984e78ba917cb16160757e3ef57fb1322be1322c01322c21322c41322c613b17ef8a57591c6eae1a536b41d5c2a02026f5f3f178b118fbe091215eb3fd672a34ab8460d45e0462b5440235ba21eb01162019779fce5fec5021ce7e11a183ac3044e33971a58b8d85ae26231620ec1bc81b93eb5bcd2f612717dfbaffd44eba0edf759232106cd91e82d549e179207db8c1dc5ec8206be5f27912332ab475fa231cf545180a97e04310c9b784b7f173751e608107c634e002d3996135981f82a965ad93183bb0ec03b56a743b6dc577db37783a158ead15aec44fe75cc2c8bb679ed3ccb986348b060623c4637a51ff07a35ef98867b2c790aa4c48ed80702d44248de9d5de8c0696db7ddebcb99f8316b34c48f170ba83cb4e949fd0874440af979e72736d21c761dd8c8c9f062d1f630f4150334631fa26a8cb5f21117a23a1e062b00961d7c8721b63d5409bc7a38776736297611b31c6251d586838be03d6e9d707b99f3d0cc7f889680ba50158519dceb19c888babcd422ec36656dcc163bc1443da207fb16e0b945bbc8fba9bd5da160ddeaaa87108a04bda7b9f0632848d5a786e2d310f2930dc5a73078a5dbec1755fd342ba6abc2668c4f1148573b7c0071ba1a63cf0db4730bda153ac2590c8d2857c205aedc704f744c7bc05fe428cd0b6cd63a88722a946d247abd583081e1304238df6d7444a2d370ff7ee77edd4b19f6b193cdde262d3fbbb130bcdbbe39536d073c0b8d9f370a89c3964694d52596717d07e5dc3b631edb9d99f298958cf993876474d88dab1d89ec78cd500e68eb06f53aae56d7878375930761d7167aad7b6829136a843ee10a7dc215e21ef487e2937884c754ecec7c0a6e28bbf03f42cc86dd427d9628f0c7007932977978df85089488515f6b5c9e5f82137fd547821c06a024796151884c5c9e2b2d052640a29434a6c9aaa61436a2545389197851ef8eb23dd58847629f834c1ca764448ac354a3b772aafb7ed8e66a7851d53feabaefe6350ca82a51e3f06354a53de7ef2356df0b63ac57f37e6b788daeabcfd2ce8aab5258b08b8e56ff4dd37a5996b216cdbf56592d376d4930f830a8c8ed77c562d89b62d5f0e9ec0fc2f18a5d71e0efcefd7661a27a7234dd273c4a41101e68349339fe94ce7d7783df6f8236f0f66ddf5f50dd791be9e46510d0df272d7beaf4a5e334465d838205de3d0a980d0103042eb6c81a8ddd307e9633ad2d73b02eb6d5699f2e16a4894abd34db313852f132fe3f7c5db278426d06ce4dcd057cb8c30b34d9c3764fd056541137a028a44807e58d02526dfdbc8c77c74f2362d3926ee67fe48589006f786246cbd2f1c68c6aedf8050999f00d0f38163f29751e422d9c9d538aa14c52d9f6b502bc677c9bc47793abf47324d8bebbb41d12a6ea56f0ef655aaadea51f0b84eb69ed98e6ce6469d5819bf3999cabf24da6cffb5c6562a8d8fb0afcbb10ca50acb9e3d7069924a6bab33a29d8c88416f54bb8ead49795e0b6fa34f5feb5caf23ad36afa74555f042d86623d14fc971b76d7982d537fffbed8285ffec393c1c1b84000e1a86e9c956bcaa6c797c79577cd33f66bfb6333eaee373d9368061bd762cb1d8a9512779e4e0a4b3a6781cb9fc4ca695135d29f9f8036b14f667a214989d25f7932d56f6753244ad9653e7e07752e1f943321383a0a8614a44b0eb2796c36b5b4bc41cbbef262d16954b98c2d4181cdb0bfd7f07b1d8b730c37fe7c7f7ffc3c9f4b34372e2b2de07d7721ebb568165951d02b4a81f576259a325bbac031d6bada9a504020a5ecace1abf248eccbdd8703f158ec09180615f051bcaf57fa7c3d86ec276b0abe6e2e66b958ea7568aa02e43b6bc83ce569556a3441b1c2536bdb7b7d2d02e947f4bdf5258ef2469f5b9ca1dbf8d075c2a679bf7fbf3dba184bb30bd90f792c0c37f9a4589e676077142e907f81fbabbe757e7d51f7dd9f80f81e634721af9e95791046346031d7a1d374c8f8d7ba185517b2ae550e21b35c5ce13e0cc26c0eff1a8d0406d1b4a68436719cb30f9bf938c57c1daa7cbda14d383dd78aacd23ada85f3ac65a3abfab6d334db4c2dd304cae79af90163c96725e6353949a5c176090f5e3e3775be50b6164c78807feb8aa2d29fc4d95aceaaaa9059f9051234c6a165c8e0e6c4676d4128d00fcfdcb28dd705a5ddef70fe24d39e239ff608ca4cedc07b35fa0079f639f978a1ca5c50e1739b1d076292e39c1a7f6ae548af97e83fd15b54ab4656abe03ef44e06dca0ba653ac66b3943b3d15cda6424cd130debf5a2aa7faa72d9974397227d51e5fe97270364f50b556a7921eb28f7beefd216f707a9a7817fea2fe4e24cd6a02aa2c5b1b264b7ee2cd11ea4d978feaf5556347ddfd7305afb4054fdba2cd636f181ceeab9d4847910c68863935fffd863a763b7233f8f70792cadbdbe768bdab20a43b861b6a3a3501079351192dd91744fcad1da7ff91288af1672844e357d736ef8636e21474b7551e90d5b62e39be2fc516feed2ac5957f6ff2ab3856c96d954762785221ff68b3033db87fdd0b9e0f084e7b7b7bb71e4ddd10f299bb06ef71042fab0ef60452194ff73737ee36dd215db5c482e233cec583311c7b86a7846cd6bcaa63ff0a7d67e98166afad9fdd2d56a7adee8acd6e12780613ea097ebb9b9ad5c4ed9aafc017fdf9811399df7d839043d5b61aefd89f8d3de9ea3eeba2a9f9a4132f88b4c953a53e5936629a7faad69c420d6b2595665a32e64f2e39376777b2d5c7a2ba7abdad42ed6241c87ccee10cd8672f3633a8646d492d2dba8720eb53e62d6ef8f74be00de19845facea6565fa2ce7710e79558a8f574fae4c2bc3477c5cd3df90be47a19db73e9708cc5e4599c8a55c8a69b55c5bc3e45a36abc23c43ce570d30a5654f8b0cfc4654b95ce96614477180d9d96cfc3335ef8f1fc4331c8d46e2c1380ce790cc3e7f3a6a0a35956849ea1d2d871653a02a173c7e96eb21513fc31fafea29a3eea171d867896f841e2c13e4f4719f60b57aad7c5f0d6a6a10eef167b93e0d859427dedb09f3db3736898d2b86c48338400010a9635849e84214cba923395993f41ea25cebe190b9ae0cba841bb8454d30b3fc08e711afd563d19b665aceab7a0d51c2cc3334ab7bb17e01ad2dbe3b126c5a6d87afd6ccd11be4f72fa12cff4b1b365fc863758accc4f5b5606387844cfed7bda36030b6519cb8162ed4525e8e57a529cee974191ec640a16b63220aa97b8d005f60382da5bc7447b005cf1c373afbb81d045557e65a304c6ab186586897b522a75747ad4360f15909673414c740ea01fa3b595f981334971acea40da20fa9ad0684a1a7d14a2732f2c20c900ee11a6464a3de640b79bbd10589fb83eb39f8b33d0a0ff8031efccdc73d2daa1db4339b6d4d9933f4ebadab4a3b76fa8c982e508b880776cb2cc6502d9b92c7917220caf0e323f306469a6ce931c0fb7a34f97f2e390621cc4506a1541901bcbe16bffb40174080b112a3661153ea0815ae732fd69ce3aed0fccd70cdd5a91a31ad16cb425e8d20726db5aa457559fa28a0e090815b98690f2f24d6ad7bcfcc68084366a8e82d81c3a1b646ba6a30172ea42e33a72d13f729a119e630138d2aa780acb53453a80cff5f954455ba46d93a9c30c86d088699c8c8528d8bac386dcdeadf7654dd46a852695a5ddc435a35dad023bbb30e7330a4c5b34abc7afd1e9c3ed9497087125cbcf030b80003e6f14cf903b10da53eb45132c0beb01297d5aac8e93e10b59cc95a969074b9a224f850d1e66e1f8a650d2c35249232bde20b06e93b739fc7698c12bffc9908b2c2c759e2fdab1cebd160a816fde22f77ea830b093cc9a0876a229fd73051744cb00cae9cba0a01789885e5165cae0953a5b5e5b84276d3590c46b35ca5bc7ced468caffe30a244a40cc72a481b98f32bde484e1767265364ebca505234e4fcbebac2b6c1ede566100ce38f2c1c4abbdbcbe73bb05d069375936feda26f78e85bc9b259d548aa9a1fb20bf9f259434f652c87c06dafeb7fc0ca63b53e0beefdde0b80b17e1c6134e8d796f201d8063ed05abf7dd64b79a59f5c64aac8ce0a1cc5cbbc9f5dc9e6f5924ed24c5d0d31f31e430985af79124cbfccb9216775f6290ec5539d7d1aa91c0831b5b47423af5c20430304fbb329087776b0aeb83c5785e4695e67aacc3175a01f2b0c646018e1bd08e9a1cf70def6b1ffb2f9a1aad56f55a9b3a2bf0c3331db10784e9662359798ec927ff5017cc36ecc8d97d5f2e04779218b7eb13f14c541083dedba6ee30f1e17fba7d0c399f9cbd2efc7a6e0e054ec9acf07eef384eaef626db7ce2e2edf530a95eefa5460d31a1079100f4fabb2d1f56aaac31a876cdc24f7c47d64040023fca124c7a5d11d8af18307e2bf0a59e60d8de2c19882bc3a117028ec1d13bdc4714c368e39218e65f4501c256eb443ae9a9a56a5466be465919957df62944dffb552b57c8a258965b02e799026fcc881b87fdffe39c2b294069e5a99baf0575b0d6f15faad9a4eab6fa5c62acc79bd52b913c82de408b57c3422f6d90d9b8f712147d115ef0bec8002af5be95d6e83192ce428f3321e572a1e0b1b2c933ea070c8b7629436a0b1bec687b3d5ccdcfff95b59e66070e4e4e84eaeba967514588e900cd0ec8d8d5801311cb2e9e7cbaccef1a06a75a60aa5d743c251c35520263ff56967cfb30b29cea47d65da045de201703927dfd874c527df8846aba2708ee967f0d254a579e80253a9b458c0329c49887f65f32b2f8bd55cb920437832aa258ee43f5c207d2cc9e5b296d34c3ba017b26e0ce53918fd79b4e7ebe92aafacbf44a65dad87bc0f77fadcf9439c20aab190019ef834bc0bcc0cc4922af0f2ff30c32291da8915a39b0780cf906c97ccc68ec2cb5b38c13036c39db0759b6340fe5337300bfa19acb1c80a95353e3f0aa0b561cb26e2230e11d9bea3e852375f3f22acd7c0ab8e70cfdee0eb118391f54cadded0b3e2f3c0913a786438ff6bde83e7c49d28be0940809c2816ed87fc2a5469b1f4a1f5c03d4b96aeafc53d3ceb6146f4f7ee110e59a7156ac333771cf01967401ce43669ee900432368e1f1aefcf5469780ce68783c218b7c5c484a011fdd94a931166233530ea6759a3a65479ccd33cb3285efc6168102ec317b4d9e5999aaf6a29aa95461369d633cee9222b542efa7234b71b8e34f0ded11110a12054c3b9d6cb66321ecf953e5f9d8da6d5620c8d3e3563c4c24fcd5835cd4a36e383bfeefdc5b634d75555c891acebaaee9f7cf32253059e7d4af30d402666e03d2de88a7157079c7d1d6cc8c9377e5869cb0a730842feee24d0da44410b375db69b03f2a66f58efbc615a13e532ebad660a63cd330edcd23528a69384d8f3b2549ac93599ee596a556698567b819a39abfecaa57941bf5157b2806b66c06fc53355e6a08c6c227b1a06c0eb16c23361a3b0d412c2da137e2332e57576d988fe62d500d56e54415a675026d4173e60be8f97367072c5851c21d0409916efa5e1fcdfab653fd03ba215f21d17194e5ab4c6e9b810d34266c988937e4b8811819a601062e71132861e66a3ab650ae4782cdee96a89b1f5a6abba364be9964d1455b514d5d41438a202336461f8a6e626289c6a68abe1e00eb001e126de4eb39f8aea4c2c9563af5861c80d39a56e42216658bd907d1a18e26dd9a4921356ecb1464608392bc3b1106f7569780fe02c1a8d4448955ace0d6fd45462917d96c23c5019510de1926fa168c002d6855b84388904c90609d495c82e2a958bb302774bc8d9ccdc9d6cc4efa446fb7b7381cb2cf7893a4674ccac4888d24938259baec4c3bdbdabfd6ff7acd9065d4428522c8a6cd9586f1c1257fc1c27b9db1be2dfb3a2aa6af68e9c4bfd5376a516ab0534e9d31d39e03c7e292f7fb06c6e0740bebf8ffd00c6c1c64f44aa5f041d76cca91531de47471e2ca28865bdb1e48730e954d775c15f1188abf64f0bfd30a8e8b3ad325edf7517d6054469c1133ba2b7bceaa5aab601b2ca375c0437df02c0ff44671b439f026504aa43c4526467c8384822fa274c1a5eca4b6bb348b68a766a43618d14dd04bc20bd9318630fbda13826c8a791b9168daf9a4583e1e62055f95606117a4e302a505008fd512749df9a851c19e2cc2c383ce3c0e0e64ee3debe3a5b6a79d74dd2e02b2114eb62363cbd0591449be2a280d18b04ede0487fc6f51aae7a47ed04c2812433e862046a5926d0bc7a72a56c61282273f8c7ab8c541e462109cbe01c248471c931f4ae76b32bd5ecf66cbf1b1e021be7b48ee6b4be794eeb0d735adf654e3486de7afb399981f00d6583e09f7108f197eb6bab0eda6c9308f10c1b918945b634c711d55a2f9f417c61543ca23a6356d562b6d2e6362daaeaf36a39626c7542ce7bcb54129bd80e427628ed407c15874a351ff1949bd5a167ee67b96e685f06ad04d6d5d9a7a108b6ba3afb748caf6f2e7fe1025fbbb643a684088918f5c6d08b460affdabca91eb9a286781650bf32182db2653f7932d3e1407f275813119ee25caf9772c20c2f86225fba705e56cefb855b8c0c86dd435c770e717d8b21ae93432473907080e0eb100ecffedd7a6fb4f622de0a321169dd3093907ab2f9dbb1d559ae32f0813423f4e5aa214d67604a062dd9245cb2c55ef23649513515455a55edec10d105606a4407caea36da34e3b005e8fd26831ea79501d937f4042b13c7224b6a2102085e2571efe828adb540f0ae62804c495876f2ae4d8a3720024187dc6c567b0dc41197df922512e8d3891459b3a0c680f156c86e01db63b54b0f2d0ea342261fe6136b5543a9378abfdb85b13833a55977537c5a644d63d3182555f74fad8ea2aafb7e62ac5b64441db0e4618f2cd0a21529e5251b4d3f68aff289507960d18b67d08d25287327982f605063aaaf26b476e177945d713ba4c0768cb60d1719b1c6f15631726125909fbf57d3cf96b6f5631f89d7cf5ef7df7d3f988897e65a2c3f8b4b299a73b0063893c2701498c300c4da604c8046d118fe3e226e0c3006d52d1b655ece4a8bccdcf2b59caf0a87da4b8325640a74f20d4eeee49b936f9019288bf53dcc4400b6090c343cac31d9e25c4d85cc1a45a9406cb4a26a01cfe94236cd6337de2a97a3e0189903eaa8652c090e8e4a9a4d22116921e1b237aff96956e7d6c82eedc54e679e91d1f3acf987fd18dcff80d4be3418602e0ba965ea1cb71939cfb6d883cfb477f191cbf21c19a8f7d58f6039c0043e967d0bd82dafb6b915cf55ca4bd632669d9835c8428e028310ce75615016379b44b416db2a11b145edec44b7175566cdb88929cec42685984bfd0c2bfd2475d65783a01e99a2121867cee9150ce64b745119d8ced2d3ff0043cf988e9b45918daeab75c7204c959b87fac5bf496d77d8d9615000ce916c3af8fbfada05bda27af0a430375f6a665edd10cd2428a3a731da1db4e6c32b16aafccc4d3a36dc321ed1fc55e350efd8cdfd34ba505acd8e8ec4aa24fd626cee7c5e579770893c07c544efe49b9ed861dbb8237a27df30e50fdc90a664d41b443753d794e9968a8605128860a5c2a3850c66bc052d7211c9ac43181d0a0e0cfbc1a4850da4a72f0a777e4e3a3521b569fbdcb9696c4738e20cfe11696044953e0ded485e46afecf6b1082a724483917adfbaa158c8a4c687d6a3617a311b1145e95e231a9d69a7eae0797f9db01da0f8d5e9ccd918ac9d1b19147518246dca757483954707adb5aa4f325234985ccdac1218e277e1c3bd170a06ad3140135a03d81ace3622291ac3529e612efb6d3df179ab8ef75b69e51c5e07d6778bd0e1cc8a282debcbcc1fd17800ec11d036d26a665509da4e9bd4699a4dcf7d5aa35be836bfdddfdfff0ff87b5a2dcc2c761f7efbed7f3efcd3fe9fffc2ae682be4fce0bb0d26012e709bf57f785bf70640c640a070a3241b531d019f0787bcd4aa0e8d4c9953279c296740e7b327c5c9937e725a117bdd32620cc6f8566e62183a43f0e27240ff0d9cc4428eba389450e1e787c26856d01d6e3cfa34e0e50f139b562b974521c174c474e946e62375497312144ca775f0b97213d78e38b760b24fb3122dab6b47b55b8b3bd394bf9ef8456f87437be2b18d2979bd3e11b526adef237b84d99423521e6ee230204f29b6a1933ea7e4186e5d68852334f079da60616cee1cc27cccbf469a3a998b4ba5cffd7d0786108894e6e5913ba0b896d8eda8753e62f26c5b81532d79009b2966862ca1c80e7aba94b504d36b55ad9a626d06c97cac470ececfe7b2340f39bfd75465c8d392e1cb456937bc446e5f0bf159858f3fbabf48236aa3e571450f7c802ec05e85de7a641f0e062598b32841de5a0a754bb40e431feeb5e16b202b5168fcd9fbad3714bd0f2abfeab5b57c91595be42aec0bffb5928dde7c0539846677917985967357037fb6ee2a2a353f5a5755db191c57b91fda447648d2ff410becb90fb4fc16abd23c8345668d1aac8fe447b8043e5afbad8f3693aa69f491809e57d5e7a1c1324cd4670ec4d06d3468bf0d3beb6debaa527ca4c4a60066d4cd00724ab5bd31cc16171d82bcd5451718ca5b5f6c4c3463982a0afb037fb3f83a1142f2376c9b5185c0968cae9d55572167f4017779853e30b49efa528177099832962021c3b73c8d12ee48283d97b5976e8cc7e2079b7a05236a1a12355b15c53ab85dd1884bd57452adacb209c42467d5d5c80f2ea0c26151db4b3d38afe61de2b28ddaaf430130f0477fd0e6b2e3533fabeae76649235be596164dcbc5c81002b04ccea5955132b1c8ad0d560dd90ab0dbda59302b5272b479f906d0f33fa036bc52f178fa8a1b8c4abffd1a46a59be92a1b927b7e6e6e614f55c753d0521ffef8bb25e5b1973382fac3142802772325b2f5bf2a2d0a07712b9a047c25bcbc6ecb5b86ced331f3e3a52a21f9ebdcf9780e37608065a3338d07ef6e58f07591e09638c03d2102bad2f538ee96b571253b58a9d5f386f316a6e504da3b5601da4c70f168a3ee8072b45b43716cba3cbd0de6c592b60fdcce757b8489471059081acee6166288ff5f0a1d60c7ed2be875c2cac0bf91b8f09bfa4ea93e63feb30dfefefdd637fffe62bd9869782710f3eb3658863cf4ad081a585a944fc13f594bee22e5c6cb239a6d4431dbfd61fb3969d36ef6b75a193f2083a7b6f4d40bf9e2d397829a78de063b4f82dbd0b296ab18cbd5e29d96cb66e2f77e2cf6ff3cfaf39f87623c167fde13b36573c353c31c88d6f4fc2bc4356e9f3c7407f56de10825a2ab23b017d6ef8ebb4461d1084d529be308161587d13ac0a0172d92cddcc5513c82112b6db56cb45c3e9353b500377a0e67dc826357f7308cbb412e2a7576d90f67d667c00743ded590f71488ed8325ae4a67b2f7a6aee6b56c9a490af56ce130d9d422e6849d9a50c6c18f0ab3d8cef2dc9b6b43e267fb6b283ce130277ed0fdf484758974c5efa4bc8d68f3e15ffeea82e3fb29f45347c11f80bda1705af02f8316abd29d6a91879083edfc67e0dfb341ae8d2f0bfed840c3fb5082e0915d35af5645f1bafe4799cb59d0193b34ec338ba8cf45523e3f7f0023165ba0b1efa323b1471a4432e97db44d50d06df8853abb3497341bc3adb805704f41bbf26a66793cc3b035a28f3d8c0336d2f43718fa470238ea385074be8ab5e1e6ac7d003dfdc44b7c6e810ccb6cb96b450f705824ecb34fa6edc3f83537c0709464874c1e5208c83de3fd73f390f1e23c98370e88227adebf4f1f8ed5e9e8371845cc84fb723857d6e3ef492db394b4d25472b2ca247260d07db63a6ca08931fec1f17c80b09928414c8fe7068e3085631def880473ee4fca6d0ff9a697544b7d686d086f7a51d1c1540d6dd13f55a3ce0ad957835847bf51a8bfe1fc2735b34c7cbca9e9562bfa612ef5bbaad63267e3e34f5f4c594f33bb91886e30d760f13b28fa39c4fc890d3efe9829477b7fee051320ca79d38ee1d0acc2bcbd7b9bb4e6d0322592066389de50f4e041c7e5d2749761dbbbec1d4da3630be34007185838b9f1cc57ae3d8467e08ff715043b06d05713eb00b00d0f7a4e42efc81a9877309a15a8bbc87cfee8c56abba70b69d3ae3bc9ab3b36b6b1bda376c5be3930dfc1ddb4bb1b0988d862f56d4b887096204cb7941add86f423a67d1d01d2d744b65be01a433510ea88db20dcf6c2216f6e354c309c13de6bea11bb1d06dbadfbc30224f6c6ba1ddb901ac746dcb1cadbdba10c71365f056538ac0d28c339aa3b92271f7cd773061b9049dbceac26f8df80386cf277421ccbdf448fcfcd5892ecb4034bfe46da7033c9c23bb9a26e3d6b04c4fc85ed3c09829b8b27a5337941b5bc0d696ba915922af3b4709eb3f085cc9b17999e9e83d72e968ec493a2a9bc8e1fdf23539dc1b8dc78ec2b87b0c60702a738e0c9b8e92e0c592d3f405ce10c6a4084f066845327f56674e9b7038ddfa10388c966e10fc5ef5168e32f1bbafce5c9956a6edfe531b9eaf54eefd62d0fa9ce7b1f8a30a87a782241d177d43524f37fcbe0425a079455db664747a2673beab5ce0555f3b389c20bc6e21062a5d9e48874de7d1709af6fb3a08c2399b42c315f6ea548f116d8f13be298c3e10b7bcf5a257f30d70e5bcae0bba18449f13c15069529ec0def2482bda155a847403f1116fedb8e6c228e4fa34fc03e4455fd2dda2a3a57792e4bfb99cbe85aef9c8120e342df1a5cf25e3e6b415d777c8767cc246102ce3dcf9039e13be51e4c9d823c8ad4c3f02864709f56abb2d340040cf158f6e58ea73ee6e3b895dad4a562b9e9d10843a0287a275df9efa15230cf18ec762706b00e86b5c97a994b8980174354110a382259db402b74d8a8745664736193ada099db43345a6e261015a25e41e068b8ca87ae037609da7e30d18e6a849a97552df3a18b150b4815dc9bd4048da3958d7824ad4d857dbb3aeae92643310121e3484f3c16f778e144dc6bef794842a86a847ca5ac332d3123ed4d6f69abc3a30caf56efd4f697d9f89c6ffb716c830ae04089f89927e9e74dd36f6baf437a79ff7e44dd882032d1748b22063c3f4e8bd90491cb52126a2bab16b6be8d43d1c6e030b1782988ca6031396500cc4d25cbd552644d534d1598ed98ea275dc2aabb98696cf2e80925fa7194b1851cadca381e534b2fca620a2d989cd1c563ac6521b3c6c56344ffc4206e855be3c025d5c540645f6f9612d06c996d2721483a065d70a074f57dd6c83fffe9e5229b272369f1634a13d79559d87fbcfd916cd058d9d06bf3c383cb42456d8b8afe2dc6b5bef4c9eb7c3f3825d730fcf492e60d45c260a533146be932223b860fc85710ea79b8ce1f95d91d84198cba9d5ad234cba3da6d4e68a11a2d4ba66261bf83680ab680db0884d80eb1a7319f55ed6c0a5bdbc85faf6d8b4c97f60726c24c33236f3b1faf34c749ff48c3832ed1fddc8ed89f1637b963702d83b4e8f825618938f6e9a5205abaae442e35a42357bf59cf13eb954b8207559ae728992c9615c89129600cc555f7e6e0b754dc1e1cecef7142bf399cdb0dbbc543b231013ad32c6f5e601fcc67c32253078955de1aa73901fd2a58cd9f0feee38d221022822948110abb6286baf6db30761965447e515dc86df1f84bca790c721a41d25efeae2404b66f664aa6152c1f459e3eb285e2b1e8355243e2151c578f2dac0b85b9856ec8f67ee3356b8533be0977f1854c6ef83dc0e014c76d05391fba1c078f5da0ed9e5fb1dea9eba053990487aeca299b1c816f25574d0fa739de3bdd30a4de879ed8f111c07b042118df0d7e0689a3c3a9f1ad32f9758930b79537021a8376e1d6260be0ee017e2b64493fcd8aa2710e2d6825d588bc027a0b3112dd05df0e90cc6277a49d4982e0826192c2851cb14c887dc9420b184c6f1655a5cfdd52793b1f01d45afcc79ffef3afff19bcc66c551fc501449e98a9a79a05b9f3c663e16c85c4f45c4e3f8bcbaafe9c61de6f0fd6faf541063417f7d0cc4a5c9e4b9f974f610a170469434ac25b1a2b700b3fb70221747fec1ebb9270817c8d895bc7eb8ebab7d35a71840ab6abbda3897d66143f2a89a29fcec4a544e7baccbad67999afaed57c2ee1d9cc7cb5f24a64a2acea05444d3568c7d821f2138a3b0dadbb589a44f3babbb79023b74fadf141966755ce87a290d905fc5111d2322976636dcba4753b327cca85ca04a42d64238c5e5be8a426d121b174fe77709ac02945356259a9528fd0aedcf40948878646367d5325ce2403584bc317af0c53442f79d36e0632fd5adc172bb0935c54b5b95f1755bd368b5e8a524e65d364f57ad45ed2a44930e38820dfdfa895a7af652e6c0884a3f749139b1b83aedf4054d296715f25fbabbe29f76b47ea57143399ed6d707f773de67ecd1cb0413216560936a71d8e103e1fa648712b5f6c9c40f44ed962a13fb43abb4bded8add2c6f2acb11bd3c5f235a19cb1fc530b35c107fca2fa6cce2ab009a01a7565d677d6dc9e28332c331809e20ba474d278879ed532fbbcd9163f61c5ed036e62ef2c392b9e3d2a30347b847d43086b5c90d3d08f2cb9e22b4c36c2bf63eacf481aec470249370306713c16ff68a4b023f079b66e703de00145012a66243317526236dd2c2326e685d0477a5d00d5ab6a51306fe2be8480e733c888002187e90e27d0c17bcfa3793bc9a1f327f24c63d8248963c89825193155680126a3667b69f8c168323e12c8841ec3bf797859f7d09271c2b7c965cc5219776432de902c39415ca2e4c45b65f67df5fafdf3febbef07e632cda67a9515c55ae49561c25cf22f523223bb0bb7dfd94a73dee2b3944b70c8160f3638408ec4fbf36a353f1f1a149a66a547a1552367ab029a722770808779c56c4f86b7145529162b43070b2ba9787c8ff2fc45b23f2718f22987837038501dd7632c9e3d7ff3f6f9d327ef5fbe7ef58e2fd1d6be9d4f5da20cf4e934f7db1422ffc4094ab06c535e10acd1edbc195cbd6cea4f3ba6779bb94084211b0ed6eef9289908fac689fcf5ae1331c494eddfbf6b02233a9d1457eb2759cfe5cd931aeddd7e5aec6ef25d8559d2fe7b660accef7fcb447d4f89ac90e1b1a4466d1920665adbdd15df43f2914f8d5869983cd9383458c7777a0977e711f70c2c0a3945a715b4eab5aa3647f663ff8c278650b38603736bc0479f2f6b84b0dab617be1955e947bd72f90872905801ae0bc613c629fbf83c3a62a89a8984bd618d80d9b0bda1a13294b718839695b16d84f7c861b8e62ed59b384a2c932d7b4ce237e7b6676a0e8565d586a29956cbb6f405d34db274727103c7d54e6edb01fc86a88615b16e2e3e9b784c29c22758ea56a8c34400077993f8d0eadf7040c8ac01f8210200a359453fe25ccc3653dea1fff825da375769779f6b30a2ad7a25aff4cff131812edf57ef64564fcfe3933214205a09f5c898c80972fcea0a2b58733500963e5bdcf78901e5bbe2be8a23361126bcb5cbcf6aeea081f22311ccc36f482b5823790abdd47261b7cfb68a45bad189622d63fb7f2400be3c69d591da92371493e7ab6f8b2cf3afbf29c935de6a9b023b72b5bbfb3f6b53dc65f353a6cfd905a3c3b502969ced5119eb8defa9e655f6aabfccea46be28aa4cf7cb01dc21aa79a14aa5659f5ca96354c88a45d5687c22f01eae86623d1472d9a8a26af506494eb2b3a66f96773d108f6cc50d5dfc7c5e1532ea21060fde3695a188b94dab023ffb5751fe9e7edf56dbf5401e1d892b98b32fddf1a5df99d2e4f816d9550bffe31923b18d23e02fb2aba188b3b281fa0cb7e322f6b10c5770915d71103196780959e682c10c0522c3e8d5f3bf3d79fff29fcf3fbc7cf5e2e5ab97ef7fed989b2aef3a3755fea1b9a90044f7dc54d99adb9bd7ef5e6e31b746cd4b8b26f0777cdd5fb56f7657d9a354fb16e7ed0c6aec5c612ac3aabc9035d0b84c943054be2e57709d83cf2baed0557275ae3a97e24a7c27f6c463b12f26ddb7a9aede66b9cacae0b0e6725e4b96348100d267f140f461de6f5e8ab1d8ffeb5e7a3975f58cea33c835761643a6cf06f2fe5ff7c458107c06398abb8ade0c10c30fa959351339b9c32f8b6c2a6de4553592a3b89e9a2bcd83fdb986952af5d0de3668c4073f546371e924141323d02fc210ae27d485ab637d2e5cadf71b86bbc155826560a7366fa04940fd82a7c03d4eee896007e8d3520b5a953373d5068535332da5fcc89c8c8a07420ec4586090668ee7523c3812fb3e3cf2d219888676a1cbc3e8eefa9b0d208b8e0090afd01c1335cd0ab15ad6e0fa4dde2bb05f9457291353596a0a0116e4c07a6200bda8abc51ba8ce1f56d0e20dee3af4077f07f747ae50146300fcf214b44210a9c1561e99ad6780465787e9c6bfa61aafa3c66bd618d35b3c63201c04243bffaa753f35bc07c941ef2447f320f535d4fce14650a799ceca837ea2cd30d569287846408f447f776ff4ad78e00e39431bacb273240e467bbe06904b9e4c4e3a2b591a9d6a6c24c81a3470d54cf477dfbc1c1f0cc543f3cf6924ddb45a9ba0df090273aa2b3ba149e756709a1ad33fdbfa7ba92fa52c617f8323bbd4fb43b1d407496e083617fe5a5697fda53e003c5beafdd1d5501c0cc48e080ad754b836855d54f3ee02194b9b5ccaf15020036970213d9aad789348e6e6d06e2ddae73b0916d17c804469f132b222f1bfc501dea603f158ec8989d81b7dbbc5d592156a6e700c20d17de0d21066a556bb3028c82c5baceae86e8035fa423ac05d20fe6126e2aecb04bb33170aebb8ab3246c740f0f87715e42fdc7c1b2566b8dd45040d5bbb41917400da10871312d328919e708991f171f32c2ae7aaccac98fdccf3838bb138386c1f1cbc99fa760d5db3812175711e3f316e0f69c7b7095084318acb4295f2e9aabe081e203355379a2e9385caf3c2dd2c86d1a0bf357fe5bea9ab252886df5667e2dd529653d4fe83d83117aa2cab0b344c012d2a9804345a54a5802100de2175c1abb07190cfb55e4ec66304e4e180d1635666c55aab6933c6893463b841dfe18fd1b95e144c8303f947dcb9879cb459d140ace0a59c6a71f24df3592d97323ff9c60fc2f30f241530ebe49667645a88c77c91c4849573cd34656c3de29559798919f5fd0aa761fbf2e066cbf7f683cbd49154ea16692e4da14d786dad35afc5283075b27f90eec48c1db907db5bdc01d458b31a1eb803dfc01ccc4cc6a26ffed9313df201343000338c560da7e0c6a405b87f102ad566611d4207f745b377e08c9e5439c396d837be4e9abd7d4b5c9b3dcb4262d75461ffc055d83f08e63003a71ef1005a9abbdee02de870b3a9ae6ac07e5d2bbceadf67ace1996dc820c677bbdd9a097f3d5d4d04dfe45966de1e6e47fc9ef3bc6b6bdf661db60931c09967f9c4eba65677ff3b6622b7ec3f68d3d5ff26fee4f99b772f7f7cfd4a1cd9a78dfd707d2df6e5eefe9fe2e7b1a77a3f5565a5ab32a07e883b9cba8594639a15d355010132bfff7ffeefdf94acad9b89453b558a4c346aa18aac169719d9265db37eafbdd3d5d94abb74d88d58e080d454e9b5bdff9696db8180f5e0970c79411b5156a2a8cc73425ee95a2e560b44f92ccf59f8724b58b9ab56ae9a692db5b423ce911fc054165ad6cbaa4032eba0bc93524c9ce5b92c4797eab35aca5c65a3aa9e8fcdafb15dcd0fd3d5999a7e082005b4143afd59e9f3f786c7456e92d63d99fd6f193c66da07e3442faa5c16133234fb00bfb84ba62c74f6f749e0e1b830bf1d7e0546d276ce4fed4e8ba6a896b2117d0434804df081df85b6d3e82ffe3e88e7f9232825da730e85b5e4da04d530473cfd788a07857e4162736a1287b272ddc5aa0e0e27399458a0cb1b80694501b7512b6cbf2a57c984656c16866a92f826d5afd815fba762127a21f999426b363353bd0bd24e02929b0c42bb7f5fdcf33fbb6606578dd9f06766b77f71b8c91b016d6bafd215b78bb4593730a9080655d397953d73186d7fb99419194a52b6f02bcb75f231a8c6236bb8a123c4497114d4bf0712b7c78991afd3235f1b16924398b094506c6b4128c3f7f7fa9a236dd79a863dfedd62613807df9f377365fbe5badab87b1d3dd1f0ba3b024b7c1080b6eb633ac9a84638f6c10d83d88bfbdc583b3106b1935ab2017b3c246dc99ee49f0ca7eb2814e8a140f8e0ae1a73c12c65ad953568025949b13ccffe3e34b787f94767abbf0f45f3af5556cbfca76c5e2abdcae54d8408754c7f80180594a0f3d46f43bbb6439e4d442d54d471f5500a1f86628fd20c1037721382f0c18508b37958b851f1815afc5d8c371e31d8d756b79bdbc4db6f5f0386c3b7f812f2fd843d0783608b5a701e1d89ffdc7a1f0c2a8a23f1d00ad7e12d12831c1ca6f00d579656ec0120b578b071caf1aee0b26dd1949fc1a768ca1eb1895c986028eeffb9d56f7dabd360dcb5bef90ecac3eb3cbab9edb518c0b832f4f5e161d7b9853ab4abf028b7b603bfb4cea3eb24d8ec5b80fc350d72ed40c6e8b8f87b5ba176277e28bf031b74bb657b25af74e792eddc7ac90cb8cee5dad97ab9921622e6954a361149b3368ce4268aaa5a068aace0833720024b8cef8eb8a59a0ff3271eb3efc77be61cb0dfca1adb9c26f551b7019dacb2b9bb785deca3fd6bafcd23e463ef34d8ddcd6bd3069d5ee2dd70ce86a95f2c51268d324d7aa7976aeab4a25931af6aa5cf17e805ae4af002af1728eb44c3c8ec4a3502426c511cba7915e19a9aca57ab45a87686c485201b0e04d2f26a59957813c0ad382baaaa66fc4a51cdf7f7b07920d49b51ac2871440aa7b1bfbdf7f7860e2e6f63c6f582da057ab17058641c643b7824f647df068485c361eada802d67cd1f6e6a7c7043e3bf6c6afced06e63c1ee45e8b4ca4fa3b12fb231ed3bb63aa1d6d0fba5b1e6c6ef96d77cb6fc3969d43db8b39189b4796d77bb0094bdc39b1fe6d3e7dc2b22ad63383ebbb4e96747979395a66ab42d5aa3907b9fec1defefeb8c6b6aee9acce16727756d5bbcd22abf5ae73788c143ad4ee49a9162f4c13736fb54300b0386e97aaccab4bf4167236a789406e9ea4c536cbc03859ebb72830428bf660777c98303d1cebf5b56d4cd52ee5d967a5df6e577951fdb665cd6a5b88cd4d1537af4a38e746eaf76a21ab956686c3fb7b7b7b622cfebc172fdc179b430ced009fbdfe296d063897faad2cc0c1ea0d653de314535e68ca43107a2256ab46fe32c47f7f65c4cd208cbcd0a3aa567355660578dd8157d945a0cfb1f1734c5d9dd573692b8d9a7a4a4e7bacfe99218daa9cbf955343a32992cd5ceaefa9e069a164a94d713fd48be86a353d071b1939a2bf0f191253e9fdfbb6a2bd15bf0b920ae07cc1431b6a1def9d8ea6d0a567ac702d52757e75236a392c5ab8b21b9ce450a2b711b821e02e886955d5b92a41b4ae4a7045844566df5dbbb3b5985545515ddae89dcb4c6b5997a2c8542eaa9536357a9f645daf3ff5ac490585ce6b4435738038193ad78be25bec54af7455abac6850d3985f64e554e663a8b18b557661d4bb6c7463bf6bcb2c37bbfaa39cc1e3cc9b9f06888b4e6d3674518f1aed1672a67bc1354d25efabe5eda1e96a9904f6162c906e0d0e0c979200bfafb4ae16b7877806ed429097a421e7e766843653bbe147b358e619c2167c379822d7bd4b9a730001fb8fe1ea6ae901bde73f709e5c53f0b314b9ba50b93458079846ef7254ca93550238940fc519e5d840b93060b86aacaa7cb544109916d9024222aa52c86c7a2e725513db2b7ea82ee58535daa15011869aca3287982d059911ad4a82ca707424de811dcba5045dd1bc820354895c66e4f65bad6a82c29a410483798579d00dfb8a9dbbe3cf4d16e8e38dfb645e89fd4b6bd34024d19a446c34a7b098e2484cabfb5f6fda4ee89c5280fade0941b6e99e5feade2a76626f16fb654d5f7e25da474d99a1e01b344fa11c4c5ed1a82b6759bbc8ae766161c6e62f1a2418b9901e6191619a15594fcdb3646e2928b7c77580e178fe945de1716cccff214cf45094e046bbcccca4dfa054781d5c9bd0e74bb49709ae21e4a53c2ce4a71a5dab72de0b5c0b18004b2a5e963a18c6fe1ed7a380c8d09562acf4d7b37eef7ff7502ebfbb1f3b70fb65100f30ee967980a9852c1bcacd9f1e4cf87b6c7813f1001665846bf2aacae571b83ca71def81ce19fba97430daed35fed265db45d119e6eac2c5ea7471a8b35260122fca40dde83a53cc8caa6d15e51044354f6d7d99c350fba1c13b1f29ec8177d6ba7f9f7d86a832c1975e5995141baa73561865fbca5a8139b25df1d91a7ed0ec0c6adba775d534bb677575d9803e1e2d010b29665973ae7c0c70b239fbe1fd4f3f128ff645e4d5c2ecabd8c557bcf9d31c3d88a0835c835d3bd1028408fec50c174e1301813dc69389ebe226a516ab059a819c4b4fd22d35c6b026fd9e3bef3d31163d7fe67b838efe3dc65bbc04430afab39ad199361333570f04fab1860c1891c52c754651650994edab9152fcfe5f852a3f07dc5299e9f3accc64f1a92a25f24967453537cfb787e35a6670b7bb99ec065bf425857673a91ddee967f6b8f6697f866e918789e986544ac94b7124f26a0a3104479441ea9f4a5e065c8b3dd24102bc0f73a9dfb822db3be74da6fe70506bd3e108868f416b90b2daa6c776e0a769204f9d577f17243fd434b0f3ac794a43499cdd68bc83a821ef7e736b57938350e54c954aafbdfd4dcb4d251012b9b15e5f87dd7738a52c54d9f724dbb57e1c5d63d12487c2a14d0a59266ed8c310b65f8c0d1db84a4386443775d415f13da28818fd080921f9b75535a3af6a26ca8ad1a4d663d81f216b65eadd61082123327ed3b963e46808115524c1ee45f29eaf34ee1f2c97fe55064e94d38dfc07a2a47ce889907822652cec6cbfde201f194aba195240a9c50e373237fea56b9e7a1fb500b5f84dfa1ef242df89dd7dc45adea778e0792c37aefdbd01b1379374e90d8b935a9b806c6eda3c4f7b81464321e3af185749b5eedfa7fa235dbd830baf8f31027bc794c9e3dd799657976fab4a9f7266d3f542cdcf2b17d92d72de81f2a462632ef54f786ddf789c88ac3b62baed9d627321779141bb46ece4c5b404baf6c5980d18e1259ab505141b709ce36328a118f22e3708186e0bbca6031b43f7c201333f36db2d5fffd3cbf8c045b432de18ab2e02b3dfe9e5403c169762e2afa5cba1985ea69d063ddadc4ccdfe7bf006c7d18d386e9c31e6040d5bc2a8db6eaeae966e6b11f22649d26da1932829d18167791cf2d08c6f12f2b8d872ddd8839036a3cfb9419f738e3ee743313def441f7c4f70497631742c7d7c13cac2e75836cd1e5b54880a8e2d8053ebdc7ba2536c729b0535bd9be7dcc01459fe06394437a8e4546aa95599a19cb7ed6133abeaa9241f167e3f6ced5963603a1886a78cf43af742bd8eb94c481dd176a2b9be769a39b87e5827474762ffc668b4816280461de72f7022c829799e4587cb0a3eb1f8d2526d280f85544716d603b65c8741cdcbc0cf28550f07a9af3042109bf290558e5d2cca8a5eb8e75923cea42c4523c19bc78b3487e4dc08113051044311d1b346e4aa5916d91abe7b4bf845f6d90af3d1bdec42351805ed0cc2a80e45538942ea5e2364097b2e94f3a03df9665ad5e6357df20d09c6ee1c33fde1b77ff99613585c4a98b05dfafbf745f83df41073eb1f3472fbb5237acbabde61b26eb86341cd2f01afbdbb2b9e22aa25b562b3ca9cf83ae251614bdf99551758015ed3e6cf17d942152db2e22a99910808386d21e0d8e09b6f9f24004555ce65a3dfa387932700fa0abba6183baf67efcf55396f86629a4dcffded08bf406566fe8d0383824f04158eda3fe2eaf3a92b9f67f55936974fd1dca3eb73181b144306996a66e0405bcc1f6ce353e3712338d19bfa3f3e6528e1fac01e624a634e6cbb1882d8e36a330b5278a4b3d04876a1930e089f86e253214bb05d356f8152365ae6d0a0c34011832b85517da071dc1fd923964e4cfb0ff738443156037e15d0a68952242c64d6ac6aebd5e2723a95f3b6f4d17fb6d2c7763c31a84356dd7510c8e344fb0564d142b07b83c288b7909643cca743bbdeb4608394194a57ffb1d81a437a2a10dd62c4ab42eac6ce1db540e40c1bb4c398d28b6c7d2645a316cb42cdd618ebc189d63271a6b4a19f9740a04d7da80031246b395dd58dba90c5fab1070cfbfc09236b7d72c9b7cab90be4f4493c828243f129d8fc137013736863db1d7f3a3de455fe18025824e01db550212eb40871afbd23ac6a1cecebee28c1810673ffe27fc471c30266623e45efa1f9d46af5bdb9bf993d967f973cd76c16f1918566f1990dd23a1dcfa7c7eab4a5db30040cfce7a6b2bf37443883e48b9ad6207921b0a56b5d08895544dc08d8432dafdc4317868b75823c7fae0ea74b1ded0c51d657c19e52af9e03b3d387507d541a4e1d8892ebe13b3b039e60c52192abb7ddea8572181f9420298a4195dfebd98fd9992c7e04ed431ceac8e24ab0aaae1d35b1bc7014fd30baad7db29df330fcfcd6a4cf11736fba120c25a62dd13003aab4e16045cfb2004cb0d23c3e68519917f93de2159fc2ef389c521c0c6a5a954d55c891acebaaeef7a0d1e85303a46c56adcafc5ecf9303ae4a73167a71e0a5b887f103312faab3ac201ef06f75969b172da1825d54cade47511aaa59543bf27a03ad2dc600a5976033c25eeccb106612d08470127c95fa417cabf6d2ce2957c9535a626e315cd561dee478ba6fc8d6c7ced606caf04ddb93b66daeafc5a66a7e6d1efbed74d5dd9b3942113ee85193e9559d69d9df1b7d3b18e559fd5996fdbdd1fe6054cfcfacfcd2211cae8cbfa8cf1a5d67536d4d15f5795d5d42f6b1e7804d38801eb82453065a8598a5ac51b2cc27422a7d2e6bf350cbf26ca925bc4b0db34eedcf2462a2a86ac36da8725a99e61afd7fe798fa00725858efe351cf3435e3fec263e33ecbb4747dd84002f8d0235318ad1694e661908e86fb819a3790ed8642e162b46db32d619d54985b3f1a32e62fd6a2592d9790635fac4ac3f9e053c8bd0c2168cb7a29733913bff77b0b5514aa91d3aacc7bd73df7c742952b2d7bd7bdf36a55f7ae7b79b6ee5df72ea5fc6c0aab529ff7ae7bff5a65b596a6782db3ba37f8b279027c926625c43f4a8cd71d4c04a355d367871c66b19f209c7e98c99867b1f4f911dcf307b68c91f12b2dcbbccfc0f928b143317ef040fc5721cbbce11d8a0763ecaaadafcfc4225b8276de6cf5acaa1719e54b005db8db092c017db3d9948674e374890955c25a88ac1197b228ccbf3db356066a4fd412bce44b689e895cea4c15e8142fc78863b0c7ed3031a4249f50852f81ee19073b71e7ae956ce34d5637a4be47c3838f80441f815575c909254f276946d3e86cb18c43dd64e5fa0bd942ecb2c86cba42258ce8af48e031ad16b2c19061d66dbf4bf37f8c53382588f26a89b9e4e0ed8965ad15e9e3dd770df2bc2f27514c24b63c30ac0d8bc32d366877694bacc965b39453355332171fb1c247408ccc2ea65bab8f5d71815c0d9aa1ffadab6882d1d2602135f378a2abcf324e0a6fdb6c580b84b661319ee47913cf196df83e9ac3f1d1e0fc472bafbaf3f455b95c69ffb5a315d90e6213faa1cd6590470dcc89fb8234122bafe808e282c4cb44f0372c5396e75b228c0f20484bc32355e0fab869365dcbb3c8aed20b23fab59cc95a9653191f1dd75695299c6a5634fa7ff752e56a36db62ad5c38675a264b58ff4d28b4e534a33e8ecdad98676b4b875ebe7b2df2ccc53031a5685dba2fcea421e13f55658e3190c503a0a57fa182772b5320fa2ea1141a0f607f0fcc601e1896e7a36aaa9fa5fcfc7130dab0c4b076afb759658acefc3f6a8d131392659e9a4e3b67c62de3e561823ac3a519ce1c38d917550dca913e86ee110f4864845ca74f494789c67359621230e2fb1615a46724be67d47ebbde3da05eca12e1c3b49699e6792cbb4d16adb10d857be17c90cb9ace5e24c8ca59566b5b36cab6723cbe796203f3278e38637518645fb06ca238c2dea0c14410d31866e078e518695d89f3aac821f7ba9a0aada69f5ddeb4cabb2e356906fcbd9a7eb6bca61b8881e146e151a9dda7bdf76b64f90c5193686b087943802d04f8b873c9ce471e48ebc6351f27fe25f800ff100fc40b5b0cfd222b85ee94aeca7f11b2a6bb1ae173c0d7c6d3494c1967cf4861e56b866cc335fe737cfa059ac12012cd9c7b88e9b513511daab6652754f1310d6c227a3db1138a0e864e53d7b952852a254a7b644dc8b2f58a61db78c50c087c207b7ac897ef8c7187715bf4b10dda2dad1b175d1e1e3c34916622c45e2296b270fae1a05c9048b735aad10e25e9c221237b3eb4882bb4cf47f706c96e185eb4e3b86a6cc75d13e7140d03eacc2d5954da9fa46190154a8aaab438ccc2498823acec456a0fc563fc747c009734fc098ed3ee4ffb752f52d4f02c97966d2bd467290e46df9a5b0b434f173a1b8a999aaf6a090e58e7d5a55864e53a8a0f6dd3557141958b9b0f5006e23bb1df9610ba65be77143839bb8258703f1e6310d812851a3e2af9898d6a40abf44f7a922581768914d98a17d5fc19818b3daea399796820c656d3cf4e49dbeb453e0fe184f75a31aa16d995399fd6fb65915df9deec3e0e8622fa1660c5aed83f1df019429e3682fb48eccbdd3f0dc4ef623c86a88af6b049d12ccc6fc484e65060224f651ee73335358b6e63be693ee0a29ad3803b5789ede561dcbc5c2d9e939fb1ca8ad0d19d400fc24db4fb12c24ac371cbb750653fac3214077b83a1d80bc1049be7c63dd2156b19010a70a9e569ee66f98ccecb91d8ddb79ed6374cc837494e868afd4404a80d5fa82b99831147060fa96a260ef612d1e76f9c3200621da50f4d6bc621feeff56058a584ec81867a4484c35c5e7b892368a5300e5aeb322caa7906e118d4f4565418a297cb4506c922fc791c8b7ee0febe21e20243e841ecd4e4011eb50eb8350edfeba534ca764c4747625f5c5f0bf6fb20fafd2de45dc06c312e0d83fb195383d418ba70bb3b77452f3459e10c30b132010da06f87b6064b8113d56325541b788cd735a5d9f95f21090e0b798b279804c795b59bc5356006a172e4432375bf078fa6de10178e383ecc120ccf26cbcc4c440f8d66cdc76a366ba49e602e4dff869bd72a07f64c3412e4a470facc575052392eb8dd0b692926a257cfcfb2fede10fe1bed0f7a43cf8280be7122f6e9535e6797df57752eeb0090f9fc1a53ff3da965d62a039e30f86a10e4a7acfefc23a0d144ecdb389bbfc9bafab1ddb1fdfc3435e4836fdd986d3d1ce4b3ac399f88e3d3cec2d7b4a87b23db3f2ef3dffcfab9f5d627fa2c05f52c05ed846761c698bec4e48388c1fc0455eb84c58cb5266ed63632da38bef1501f337e7aa8271afe7c47a2eb5e8f57d6d5724c4ecb64ad8a45f483c5e7d5d57222fee47c5cb0d144fc891f4f3f337cb870dcd3b8d904ef4cce55f944ff5fb2aec2b55ca8f22d5dfa3ecaea22bbf21fbf755f555d9b5de7cdddb86da5dadc018d0c6ba5b03e5be9eadd67b54c7e7c138385f9b98df596873f1bd6bd317c6c5dade6e7d602055f2e68c388868b90ec140e283e34c12bda3ae9bed6e7e6110c09d8d09ae55c521a0f1f1f64c25ed7eda7a85f4eb344bf7f712bf9097f9fc49963990ea6949764354486d1e65a2d578b975a2e489790d575a8506ab2c5b290fdacae87ae2a5d0178f535481bc9340dddbda635a819d1bccbdba5d8f6bea6b34103e6cf1aa0314d7d49a629689582766462e7c8f7c1a4376624687b91d5f531bb71d5e074e0bda76c1e1ea86f355fdcc310445a2faada52853e9c5fc7014424832d064df4c84bc98012f607dcf4802e18e572303a2ecc06bff257ad5f1a555aa7690fdc8ed374d2f7207d2b140bdb161fe0273472356499fb7259e651292600134786cdff33b05ee60fa11ab1c8eab932af2634f744ce2b9b4e570b30c0cf0558368c2c245c33da50c8af9d5c440af645cb1819546313cebffa55d9c5b90e6142bb7eb97ca22ac71831462705bc9f5edefd4100961959c53cab87140cef864d83ed0ec0fa4b1961ec1c71b479441cda635a5a3111bbc12253742540f5c0c50ec427106c4235f008271905c4f6629be03a7e4478e4d2c519fed0177f076bbed34a48974abcc4cf9f83d03e8281d92b5ad336f65cb445ac906e95eab05843dc4038b6eb9d06f6bedd067440a312c674db9acfc5f944c97cce9bfeded588ee4bcbcac252f9dfc11a6d4886e4965a7d11e806e775ee9082620859e3217b09d8d19dabf9b96c34f0f300d5c69e8368748469aaccd51422f060eaaae9794581cc6d0da795d6d5d29388516cab3045ef11608cdea9df6483f67da6f31755a99ba11566e1eea6082d7f9c38b2052bd08477122e47f411871b7de416ce307d3f226b125f83dd338c6a0878fc032d76b4f668dcf9230289d6985f6e0c71ace52cc71ce4b968b2c7ea74041f0e3d67fd02cdbc5d39300324cb8395a42f13fec53010d6c52334150fdeefa6f6a8e16fe6c0dabe39f62d4ed31fafafc5ef06d7815b11f3a9e1a5adb9bb5f3cde9dff4ad5accb837393b086eb81853021eb9606c2361f234ba60a00200de63d2b4fc74fec10fba1749af9fae33d7404c7e106027407decda835677e65750da6cb22bcb7d9243c61b70da01376db3b3b9fc2b0881ea56dabd06afb0fec48c7aeb02ec3bde105915cf78fee12071d08d2ac7f4e62c34e3a4cb5ed701ae44d2fb92b2c91252c390f7c1d893861113b27631b2b1b606fbe2b89c820e9b12e438df309b78cd4285b2e8b75bf5c1536935543c2557b21d8a377435baae4c4588ed493bca4aff2ab58dd1a9eac09f57facf22b201d3e2107029fd84e1235accc8496ced7a0cd70cb56c6bdc36d3871c3dc1bb8e720ffcc38f3a1db58c96be06f5b4aabe78be903589b7c493d3dde077292c8828f864c1f474ed2629840fa16ca59284343ab97774e1e415ea9613f10f415ae3b7a7533befd9eeb1d9fdaf16eeef135a63bc51f42dbf803867fab4adf35b44b053d7053abac57affd12853e600e69ec06113b2e148273a40c17c48de535c2b5f02d1578bdd4d10eb4f4fb1b676851ccb9c04d5a22c9beef69e4eb0dddb632f7bba1876678a69b61a12f1f8764be0470f4bad80610ba020690cca7c130becb37c3e20c9305e6bfe1d9180c9d6f1f4a00db2b5ccba62a2e64ff381a26880cc361d2a74d76eb2f6cb5d341c85f8768f29e58940855d8c101beca05384c61951d19d4f48f7564d18e7cb1f93d92657656c8dc869ad90cd0b418888970bc1da3732430827f8682c445f04f9b109555f90e13dda146f07df502f2b773fa001f20d738e79db55cf820de12df7ec8e292b0636f48629e00b0cffc4f8f5be23d54902b5f61e0f0a02506e0e65e3de4db6d2a8f3e20bc7b9d817bed34f096356d065def555b3545509f5fc8f2dd329b1aea94d575f85269c9b4ec332357b31923ada6ea23d14a910af2cd90aad6a26fda22e0e3bdd32108d2f6998c8c3f1f201d6d5d1fab53b10b0d28f9825915032611c7d8759958071a75b8062ef2825d05c0ac97e6a528fd3b2ebb520dde4cf4e947b5509aad96bc90e54fa6258131cff27075395c26e872d5fb6d75d598f5e55a60b6bd66487f0ccd7e28c2d8d25a34604036732cbd5edb0cb158438f3217d91293801660ee64aac3f1770633e3b1682a8cf2a6cfe5da86008d0143204603594ccf57253685db365e9064fedc4576d5a715185aa1a1c5159c66c8099b361fb044fd26fbad3e0ec387e9d0ba061330b6b85deebd94cbd035f17946201a39967e67b72d8580a6461706764cba752a7f62b8d2e77adb4ec1b5c781d4fc036143c7ccadd2d6bfc383d97911b5ea24341d82e9e6b35ac28c682e44c4dd190b17138df456a50e24ec94429437244b1e3b7f039ace803f54b0e053a90abbe2318ae06a44ebc35645a34d875d18860b0a24b1665cdc07534d3f5bda7de4047086175895da2557c74c93f17470d20fec729c7648694912073d71718ad39fb4d6deaeba433ae8f61d8a9de1efe72eb30117beb75821de6e6f1089e29d3220ddec79990f83751e443f0fbb37bf20ca4bbb3c8455df76afd1ea2798e4897662385b2276d9aad08a7ad04ebccacd55ecb7a037a25eb4bf8d8556bac4fc50f28849f043d4a0862ce42feec68e88d063d0ba58155730346e9700c16599ff77e2f5b6c3bf23761b9cb031778035b659b4e951f33bae8ad5a283de8174a281bdefdfa4a6f0eaf87823837ce7dc65baa0aad67414625639ad74cb5a9bf921513534cd2ce554364d56afb94e9b4c283d4866be13c6f397e809dc1ca6e50f859ce98958c8118f1416c8174055ee2bbcaf9661798d8f1f5f03c39b0575ac7edd57a248562d39c546cf18b43000fcb392fdfeef24ae46aedeb9b4a00dfdc1e82fe16a9191467bad9cc79a6a46a8854e8d27dc3332b09f4b0d6285245c168b0560636021f3e5b0ddb17b18a20411823699efaaf9c1702d55a9b3a23f108f01e2e80a7b1513fcb9c69f10ad093e782874db338b86f7e7b29136420eb07860e081dea9859ac9e9ba9023f10fad0aa5156a3d4aca2c3022184fcab50fa461859fa0338128ebe7b2561a01664561f76ebda40844318069568a3329f0187a2f59dfec0ece1b43b473bdc854611e94222bd78baa76e7cdf58d46dd4016460b59cfe1c5dbd093f3e42b3a6800c2b47a48e10dd8e8564bbe6d679081ed1fcb3c74e7704d98efb54dba1260156f3f14c7a6cc5a08b44e5dc29dcc86140ca3503b45577743174eceb624717257533cda5f48dbded8d0d1e01bc15de1643e97568f5b815b37200b4ade79219c39ea4460d66a84c6dd492f2bd154ab7a2a9b89ab2a7cd83bb14b6dccb3a6d7885afe6ba5cc79d115da643a0787c666ad354368ec18f8858080f5b99a7e2e65035568e4956158e6e062ac4a919538adaa56d6b69ea1d12a4604bb4743bfe843bb881bef046b72fd7a096ac1851c71c92aaf85763110e6eac83519f9af5c838c2f88a1b308b29ca4a9accaf97394f170c53da2a6f811c8cf148286bfa9abb3ecac589369ff6586fe9a600a8ba4c2ac597521eb4b436da2e83e8794747a2103e4ef0771db9e9c35557d46c8d968595b050da4447100dc09387287e190173a859efb9b1723261fb585a8d145dcba56a37bb87da5daebd36fb59bdc428e9cbb124b14b990a3f4d70f85534ab7cb16d955103765cf9751541628b66bd42e7e2faff453d2a2a6bef29064a6436bde89765ae9b1c665764f5d94df26428077d247006e9ca5ee428e9aae826ca6659d68e6ba3297fb4295e345761575668a40001300b409ef3a8aa1bfb8c876869a8f5df111083bece2478c7371e91c1d9f3fbbe7eabf2cb5accb8cbb2898aa8daec870cfb251e436f4e6edcb7f3e79ff9ce07fa00ed063cf0135e475b16ab4d5676653c3a0ca9cc2f6176ba4a8d54a3728f6518d80b00da370dce065e4a102cf8f8e585539c79809a62bd3cb22ab3fe38089fd1a52c0ae9e36d4bd9c4ba1347889aea67a6593b08cc7e05a5badb458952e00c0592d31a022366c46e2e54cacab15b0f0e00c0ef38918cec65b45a2574768eb06015364968fd8d94324f87ea58a9c6af1ad7c252f7d68920cc352909e985842a7dbae666e9fce561a96e8fb274ffffef393b7cfc4d3d73fbd79f2de0fee528a462bc36f6178095156165e3fc41a428d620d412acfd6c2700d1868d279b30e46fec94757c3199b4f1405d01053c3208a4595ab999a7a6f3092f709cb98b4c102dab3b522c9d5f5b5707790ede339e6e9c6c62ead87eba39497f844f03110f075dabf8775aeafc5bd407c20eedf179628460fd7268c3f98908fd9860911596c0885f5401016b9b7142b3971908ed5e9901793da02e4d3fefb97969bc19714dd6fad9e4dba0c4b54931d321cb499d2946823a38b3e079f7f09d672dc83144d83d191b67097b33d3f53db8339408655a8667061af0ddf3cb726e2e814cb927fe259330d488412320ae288731f8fda4650643244f8f481ac8fdfa3de04df46fd18e6636be9cb9913e86160fdff82436ba092279f216a596180e84b3595435199378179fed09f4004a7552d6d0ede42d62364da7eccd6d54afb40ac3f98471379129a9584d0b1d64142e6622df5108ebecbd583b49c42bb7a40ffcc6a6566d608b459e30306e2efa5144e796156c8daa30f0d223868ca30bad56794e4f32474788f68dbbfd9699cb6c1053f44b4e11e79a4748369df6ae26de01ce7c8e7d3d430f97d999c47eb42dd0026ecef85d2bcf12cfc09b05c1547f456bada6d3eab6574fcde57cfeaec9273cad6fbe1fe7d1498c3476b966f891df2d4f016c168fea642cf3cfb0d645bdb52c84974c4212b5488e6a1edd4dfd0ffddbd56e8c8178528ab12a6b184583dcefb799b8315cdb995d383f19c08ec5008311ec7f7d8cbef5ffef8f2fdaf3caaf24f6f5ebf7dffe4d5fb8980c5c7db090c2fad9381e1326a44d2e08683dcc1af9efff3f95bbaeaefb1d100b0d473e0fdeb67affb170f0713fb8a5fa812480e26015a9d156aea3308b16047e8d58dfe0445210a38e3e2acba021603acd556e5aa91fe7c2db2cfd2bfac81ad72ef082666723222f392c0c174beda13e11fec99db5642887a22f03371b9b9e227e1882af0a7a1b3b3077b746753ef907221233916434bdf981e0772e60dcc2c342caadbd6829d6074b5ec8072c6a3d8dbc4996415210c7aab69563879424dfb4abe45ba12ba5a42d86df203c8205a2c2c8933eb8bd7f05ef081cba6916404838fbc16b0069b42e0b580a5717fa9eee0e164f5170edc6edc9dc52c7648ee227062cd3be44d632ed90a1e59771770056012fdeae6a67e52a702c2a56b8a49c3521ef9fb4e60f7c4ddd4c1757613fe83d782b9b25d880702c67391d591fbf8c2474567f28943565c6012933dfeadb6620a1984706de5af65e1d9b980e330088070a7416bc88f110ceacce6b570ddc61788ef8c3bf6457a8b40ec1064e3687f7f1b1955b75413b60891a62d06b8f389b809414b2f57284006e08f88970bdcfd7c7818a9c391904e703bb4b2aa967e3dfed87022101b48848e9fd2779fbd87919afd19eba16bd2c951846fc70e02424fd446c8c592224b55450e06422d51804f25cb6de1a99bfbf743fdf78610396e2dd8151e4d63288e1792e4b3a751e86643f6489060861a8fb28f4956e1b92ff390fd72d220550abfae83163f7897b1dae6a72021b0bf228d5a4b89871860e010dffa1458d9061c71ef8a50497029dc4af1cdb7b87d9e92372d2e9b77a6f58d6e16e1b35577628b45b6f44f9155034f25986cf01cf179e9cda8063161fc6a6bda0d6d1b0e22f9cabbfbd626c125b776db7ebbf86d1fa1d6ef5c5a39d3a59929578bf77e6bd34eb8ce56d70e913f4df9e7ebeb20490673580f5af8cfac32b03fac3a831bd7024d0368abbceac0fff41a2cabd6323da7345c58ff99cae65599858f8e7b86e355cd3f55a3ce0a8912cb7bade7b8a1216cfadf1d0553bebef6abfb88028bdcdbc4cd19ceebc655e8ca9514e860400f42e605e82ce884117cd1ecab1aaa8cd01d23e0eec2350dab937b8665f77653656d27dbe78d568b8ca47c949078867e5710ade32c6b641ea63eb26e462ce3af03874cf3a57b0887715041560902eb8bccca20993ece998f313618ee08962b0a8cb4d892d9757438c5ce1639743ee66c353af223124c04fbda779fadef7a280b7f68df8857074e974c51c8413d020a0f7c32c82ccfd07081bd1a827dde117f16dff9731009ab63fd6434ba7e6b7e7ba36fc544ecb39852812293eb3577bb1d75462e10cbe0c489a7773d9df01af40d5e38231f2e24184d70b4ed5e37ffaa75b4320f44bc5211ce3f883ef85ee2b3ea2f075d3d93f35acaa69fc8b88bb1b91a55fac27ef7b1da117fb646d9849ffb83c1702334bff8e3169183e636a817348ba6db6ee23667d03d756703c8e8d550f011f9af41db414ae217430f7ec72cc457bbbbbba16dc342bc50faee0cc30ba553ecc12c0db383d183676e705d93bd8517ffd9f0a327de81b0ed31c8edea1c344c2077e48863c8836cc98024ec42dce1e5b5fc5756d5120b5ed1111056cfdecd7809b22b9cdb9834eead0e709c2002c4e694f332a8ef6f6c041cdee19c7ac329e52f305f915ff5b8211b0431cca339f61e6c376fd358be5c03b19324a1e1eab74ee2784c16578c2dba613a69d18f188fc54c1505063d3c9701d8ade6e9e0febb26fa0c349167683735539854c107445510b0d3aaaf9af3ead29673f5a67567885536ed79d9b301d105acff5bec2e674185312eb7e4f3ace359ddf8d2907f83b2087467655314d44566b1a3361606f5e95aeb68c0c23cf8d1a8121ca4240b76407e80dc63f581d81bfde9305e589f4f3c66270ec398811d088d8c9838f7c71ea52d94e18d0b72c9e0145174e40120e1803b04b4d0ad8b0da2901e860db2725ec8b759aeb2c8ec4b57f4b51fc3194420a65513dfccd3aae973c871932678da21aba4ca7693a051113c0c3888073176209df2cd4ff44e30cc07a21fe3877f56f4fd223e6ea1d1c805f4d91b0cc20e82767b62e2110ac3757a81b06bd62237d10bc13d1dc37a3bc15aec70046c2f1b0e98c4ce8b7694a33dc39ec5aa2cdef4ad27b1352d51024cea31efa36479984c0c3e6ce5f9e687c15acf9c675a542beee4971597d9ba11aa6cacb71e6560153f9fcb1225f9d27ae2a0ca0bc69d156a5ef27016e3b1b83c57d373b1901958ee93412c56b7cf01d588bc5a8045813b7ce03bcf6f157fbc0907a29017a1f4dff1038f799d131de268484c4736a36c88f951258b9e21dcb0493f6ae3303f092b8cb0112925ba26127518107afe804f74178f3d5c93b0497a495260d92452817bc3ed492ebc8f3b955c89d4c0c2265f22047f927f5a351ecd341afb81b36936455722b2fc13aab45133020810b925cfcdd3fd4ae84aa031ff6546868d24cd00f36e46736255947b4bf5c324fc9e700ccca3d44faaeffe0e2a0dc59ee1871e1ea6fa7a1b1038d6d95bc205466b6eec0e6bb5fa6b6f2cdca94e4b7ed38d0a9d8c0479ab64407c64000ce940a9c90596aca89aca3081483e88f00106e1fed056ceaa3a540906d79a95883029675d4394a8bdf03c9059a7e755c044aa2a1bd568594ed798a325622322009c5f69e79e03881e006f9bbc65c3fbc7dc4d766c87a9abee72b32c2ca8b5c31627bcd862b5699aa285e72fa1384dd225de2a61b1789e9579217f421b76f614dbf4f80ade5ddeb02112fb39fb7bd487075fea209451a0f40e78836e2db91b015fe234c4f6181dc96643d2d532fc10d8aa84a1699de5cf0fb07ace65c69c1077cf965ad6d934f0656adb0905cbbfadb482cc1a621f13eef3606d10bc6429a093c3787b0687091868319000f1be5a0ea3b54b02a863321951d0610b2792609c9942020e22ffb0bd7183d4ce5943c23b0bb8d2a226341d78779ed532173ff9fcf7fc00756deeb26aac93a28b3544f29450b10a158f8e444f57cb9eb8bef61fb8c405455faa79b12a0a8a73bdd9ebd2c5aeb10de26959975b6b750a067723f12a7b25ceb21c334b35431bc28292acac9760aa8bf6f3749f487125aa5aacbd92e2f25c82c48084038cce57b521e427e83d0ab8f24fb4d67693a9b3cb282beb58bc5a15051c421f841403192345e5948d077d73a0da1afd57d9ab96665e35afb2577d9cda4058ef6108f86c2e4f302f0466df2c916ac4f45c4e8119c24c83a85f3914cf5433cdea5cbc2c67aa549a968ec9426c74193b3cdc6c6c0e08e00a58dad857506c63d7bd00c8db4fd04ef1a50df4a7303e86c84adacba1c8d505a453ac4a89bc47212f6c90704806106f8ccba81c7bd4b672aad8a6a3ab30797af4fae0e81ba00703b029e543d0d57a43575b74b4eef60700c370d89e46ccab2a1f5a9355a58363686105072f69ef7b2bcb17c78d3571c099c022c19b2304b0db98020efe4172a7841d77d286e0b61e3861fa4ed042922974ec87e380923fce9dfc70f05992335f1c07966798337405a036d6df025c60d0fc3e48e86bdd77b8fd76d27cdb7bdb705b1abba2dd4619e18246c6dc13d1accbe9795d95ea37293e7e7066d9fadc2e63bfa9c4b2d29838a3580706442406ba45489ad0df460781639de1b98f58e1ce878dcd8c86e969062b655a1d486c6f63eed192fdfa0fa1f582ff1e3257a1a766f0a31d5fd86cbabe1aa685d3b1a5d06018da8f0c53be9a017394f2fedc6c8d905c7837fb2d171f6613dfc561c63867960e16e9f00a027391e86dc173c8c536e9e248ec24a82e543ede3bf50b81816cbaebeeb3ba0b55f2979a1f62a0f94e84646155e297884d53df39020fdb4ecc5d35d1243869b5838dbec1e802121c6d29d7fc40fcbd216b0bf613c3603813da28369289992e414fe145572c8e772cef4837930609092cbfcb90c9d7646f9c8b11ae59d7056dd3fb1c43dac1918d5bd31b0afc80b1e27ba7bd8ed54a6d5a388ef699f807517fcbd2c639195d26c0aa2ab45abac834108c8404b298c51542f39c94ade483e127d3ae9198fce72488a9026bfd028251c9ab94dd6c673c97a29a061903713c3042f0f01911df32cd4a6b337326316f5d2e8187cf6cbac6acc015a05edec33bc17aac89fe1e48b5948bcdb05a2e65bd0b6fd36955976466e444dee1d439e0bb2c9015e813b5ba6181e28d85e5e0ce45b44c605634c27016aaa1e4bae0f261e61277fbef5817184138d52041ee1fc205e0b63af1f4abcc23de1f73e5319a11c6e1ec34ddb4992fd84d1ac8c6dbd6991f12beab56e1696fd07d1b31cc90ffc088cb196f81e9d6901b9dfdbfecbd0d7f1b379227fc55e0bd3993b42892529ccc848aac73ec78e2e7f1dbd99ac9e42cfdec1609896d37bb39dd4d89ccd8dffdf9a15e80021a4d5276b2b7fbec5e6ec7620328bc170a85aa7fb1584f78a222a6d90325cdd4986f9d007002ff1a07ef4f14b38e504cef89e6ed8966b8af437588ef776d1cab761195afb47b9ac7b81c72fe13b5d0e5c448e508e222c153fe9099a7ae8ac9a7107bedd32f1560beef554f429271f8c103b5cf61fb5a0e81c0076ccf46f9bb273487ded05ee99a1aee769ced008caa0f43651b8389884153c95ac1440dbe798bd303c7f2fdcc4e64cfd4d8ebe366302f6c031f4bf3344fe7cb391928fdeeac9c27fcc7845abe4d1b15f2cf2e7f3514f04bb0d065da6d2e032860a171976f746ded6fc20d0eb75c1b72cc7fcd30e4ccd6bf7b1748983f4fe02f2fc70397e301e648739763b465fa12810b60fd112eb45a6405de940b955c17e9148079b264b1305b1daf57830d22bd0b5a764bedc26ee0450e88d753c60774103237b0733f75099f3e494243cbcfcdfda5db537beac09b4407d2e993f461ae5b705bc70e7b824e91e73e4149bf799ee06b591cf9d4590a8519c25af6d5812c62719d2c2468727d2591748f7cf51d6003e0ab5f5160dc6309022c04d67aa6c175dab1d6b0290f9a00ca7083d802121b9291d8c8bdc01cbf0103deb03273d09e5f85ffec9d21cd8e8ea27196ac0a2432496de0bc3c427128579ef5f43cfc6096f27924966930dd91c63c5007ea04ad13d8faa147b6e861a3cd1a17c04e2d2d6d0975da0d9ad223a908d7fd7eb830fbd494cd75616ca85bd428853935c62db517d67dab65166f5acf3f8ce30476d39d30bfbabd8b9290621b6cd6aa40795b10621e818e5cacc9cf21cdd164001d04d3221fb85acaa2bea5b91c99cab1b624b92063fd495175cbc219bb937d5c235f95e62e5fbb862e6e9d292cafacff080cd12088b519ba54ddf86abb93368d990be441614d98c06c038186eb414062cb44197673c03e37f1a9727288ff90e22e1633750fa6e581ba51f760e04fd48d1ac2b7b102ece33477378f1965fa01b29b4c279009b3df60f65bac706b2f7e9b25bec138deb3460fa2c1c40ec7b9468057cbe199c01d01e812ea8feedcf129ca071c30c1c3827d014d9656ea1a3baad24b05863286ff14b9564955159314aceb48352172d33c464e1607503ba062db55eda683582ead1e632136d74ffdc735332eb612737fc1dccf759d38707877b3aa93c1eae12aad9e3e863747b3dea6f84a5127837598d2f23a570acd653c58955cd322f2c48ef82aa06fffab442b148b6ec2f1a2bf66f56d710fb5ee13c2872de652e1dc2354cb0bbf5368fc55d0b4b406419a5cf93bb85648295b6a421033a82187c7c21d3ad5836ba0b9828e0954de91c8367a19549e1b09a1487ac2b6e17bac8c7103e06283ab9378c47457c5c0c616ef2bbcb4fa2cdcd4f073925d722dae463f1627d8d732f08b3b1adfb9ef61666c2187ce6d5109d815efe8e06aede3d5bcef1a64851351d185ab43a0ebdbf8a67d360b7e26229edac9591df455bd36ffb33a347f1df695f964be980fe6b718bc8c63a2f7958b432eff7ee9bba71adee1bb02d5c542f2db0b6f7cc221eb5a4012c790eaf581040e52fbaace44e2a13a960362644f39b936275069d4677904d82f19e1315ef8903927e4f5cdc29c4141d409ea569df7aca8a0c95e0bfd066de80d0d62eb68206dd99eb6ae6355841db3e7c6beb5db99beac6fd7e9c0eaab5e1df8b6f972be57bbcef76acb7c83c55b6baf57fe846f42bedade3fdfb86ee5cfaae7a4b0da32ad3852edb3bada795657870eeecb9b56dec9d1602bcf22d1621b51291c9c30a50f87ca484f886f572a8b73374b113b5475ffc7fdefbef9b627651affee57dbc01260d514067ff1a48f4991d7692e048fcf81bb124b2d5ea009433670d236d9dac28653b70064d0463726857fb5d013b0a970592d47f54e346e803f35981b986e3437a488dc8e1747b3ffe8925d3882b0e44b7e49d9549e3299ebd4c0395d354dd465676f714ea77ddfb5468ec23632133ca2d2beea9457174977d487ff0607bd4e6ffb505d7ce1103512c3a1710b4fc6d38f45fc6714208ed6f2e993e94cb8fafc3d05c095bb05580f43ac1fb79abb6dda3da158c1bcca13608418622757367ca3c7203230644ef0a763884d7126b6f6f05cc3330bfe5c6f2620da6524d1064270bd3a1883cce4553106094ae63a1c833c2573994f6bf9c990f22819421e1d43c6a362887834c8e5dc6d1b397310b8d2496cb1553c96625cfb321f37243c9bf973432b8b2317b9383c935a71cce51f96e257e321d564bffd5df09985a6ff1d31807cfd5bdb1bc76e57bcb47a0e7e30e0cf2ab556e81ef3475deb2e3779498b6684545f45356cc20f78f39daf095322ca94ce5f76ffb66ac7e8bdd1aa80e842944074a2555fadfbaad6abfaa16103f68a851187657058dc3a4bf3d964bfedd566ddb8a6a87d39884ef8e2b60034298fc289ea4c745eebb2a3c62445dffe86b1f66575df93e9560d0051736b0b42617fe54bee5db1dcf181a0ce7a3b8c8a570c2b696b53583509b4f19ab70f875f3356d8988fa68cfc0506b2cd386e642d4c092e90daef264637e2f96f3eef170eb437f48d0e651533b49243404d2f7d3f558ace0d45f11df204f912fd1af32f8e266c2527eb221fc4daf6323da200846c554ad70552cfbb57a2835d8511b3a01642c7c34bc54a824d6ee0329ed527aadb959b8b119fd4be63343d754f7020597aac2285477efe0d72d07a5bdbbb07eded68f80b6e14915663b59222cb58adc5cfd2c209f15f223143535164d4eeb399655c0cfd58ebc7823b071960178f1db36f175abe50cc9896c98d91c7bf48cd2c95c5e22dc3d317dba3e68ed07c36c04fe2f875a0ca663e38a957bb69b86fa7e3fcc355b37cb237e3107dfa84165f61742244c66f3e05889991a20341e1b92b23ca0ca6dea30d8c1d17ffd6e7180c190e9925636757558812eefba94ee88e0b4913bedc0b068565efdec526fbdcbb5e0daae45a77e52dd77c9477f09b40bd0085eab2f8a8219c3e382ef82a05785432b974fd0cf088ab59f0c013a4422473711ff61116b841de353a28f1b28169209da30d0530bb7a95d4b3aeef386d1aeb2fc5d3209a0c539817d7fab4c0b6821e1cff5a1fc49bebb21edaac87a14fd98666bccc1f355843bc31b62ddb9a625bb2a1216e7a1baba2d4107eaadbeeaf06b1dbeddb8387926e755da64132d01eeb1ba45fbe434e120bd1123e92d9c063fd0b55468d9be7be3af0d448c17389ddc7c1cdd3e65df133c8415fad0f838db80978542a9c3d7d0889a4fd60387a169cc476ddf7ed779a8f905c49b795c423b7170ca44fcde942623d8fc80fad9d81f00bb7eccbbab52f17e4ba7dabce38cd50b4336ed2424ed85c804d5eb8a3aa71d4f36804cc29dce5f8c2e627d1bec647b75ea445dda8fbfa76f9e476f8d6b7303002b1444af9bf8360228f7b115790cf7a2fd4a038e89d9ea7eb1dee695f7de013fd833dd7fb16fdcc6a05d67fdc59cf75f121670459ff1af7dcba87df683505beaa5735bb0db1933d0a06101eacc86b6f7df847bef95497495e6549ade9a0e073c2cf85405298a56c809f991ce29266fa3040a7563f4b9a65bc5b6c3e5f848016e9155865c37171ac3af3743acd74a791c7debce184e50f62c0f8520c19647471bce6d8728108213d0c23175f98f60f38ed1f70dae545f1487d503f408299f60fc1018e51d800ecc8b9fa832dfd32ab53e8310537076b79760d9ee9520f06e1016fc6f354afea6ea7c3f8306f3f9c8374bcf6c581b5da13431eb90836fddc0361d1d645dbc0afe3b3b7560261e1965ce834ad6f69021667105b74b30e9752e85d7df453c7bbdcf75bb12e57cc8cbbf726654f883f250222137611994d40a47b0a6f540daeb2e222c906f4db92eb457b444cc4ddc9b87fe8346992bb4dec669f8653e036c9d405a5caa62f04ea1e1b3c26d9e533a986f19b38886a0e7657890b3df028da877ff4c58f5f8f768e6ce50878aac1b9043353c3a19aa753f0796441d6835a143537543ea47f755becc4530007e3b6df9c16caeb088c9df63628bd1729ed2c429a3ec9a54a2b82438ba86c8fe283844582fed0b0edd69ea02bac08de6128a4798b3fe87648e651442bb17ea8cb276a7f34f856dd437be3574fd55879bfc34dde3853fd13b56d25cadc74b286876a78c8b1863d486e3f27c30337c28b600d973a9fea1202bd0af161590a2ac84d82bdeb9defde092178021a38434e52dac89e7be7041f10e608b89d92ccb1e900757a2b8f36f95931276a3af253e140ea865f0985e33626fc59b2d6e56de5eb767cefdf3c646fb243e1607fbf85d6eb57bf3590bb6d1161bc618bb58e2ac498f90d58c2d56f043f02a2e81db48e81d1f1350017c9e4e34d524e01e822a9530c98304609769654183cb5b8d665994ea73a073495656598a1752375b3a8de0ad9e4b7b1aa7f13cadc60f904e2173575902c16d91a6c2792f26a0941e3e3983f6db823ae09bf8dd5956bc0a6eae56adbd6026fed6dcecc9a98be926daa6fd7265ccdbb55747e8b250f4e72f56496e657b4809eeb3af1b088d60bbd751fecf8a4ed5c1cd0581da0258ab2d653aa5c98ae57cef3c1b0ae5a970ec368aeeb2486e5d4bd03d8646ccc0e3fcc3e803ec87576f7aeff3c047149a286f1e336bb7837ecc462ce72c24c02b08cc1a22ceac2548c13a88e55f87d4a2ff939badb94fa1dfa1f504e9be43df5fde9c093f8bc345b82a4d04710a694031bb0b03016e2cd675b04aa7e37496a7d55946b501d7383067a55eb7c8a4f43d15876b744e909fd7faaa6cdc376cf5374f1b599a39ebe223559f965d136f0388cc9c49fc9b1d661438b6c97693e857cbec09ae6ad582688845aa20121447533b9ad43b6f9cf127595c323eccb4b43b9e75d7e5dde07c79e5323f8213315af99ad3a613350b76876b2dabdd9c96af766bb91dfde6c74ebe6fcfca73bfe0531fef3489674b0555cf6dc2b2cd2a9b8cf512f36864cfc8a952f7be5fa185fa0a29f47be7330e12d5ea71a023154c55c3742cef75595a513d46c14657a95e649a692b24cd67620d8f4a8eb5a757c6c3ddcdd97c64eb12ff3951a732ad46629f51d853dd6e90b8fff00fbc6c70ee97b98305fe40064d77ed463ca232fc3ccbf632816e0ce4fa7dd5ed44bca9d713ef650c407ecadaceb1c3ebf854e9eb7bd6a076b87727b03f865c1a977425c09e31cdac114678538f66c430073b53bd7bd86dcba2978ef93a26c114cfb0e27db1e587874128e06825b9a4c7a6ab572b178ce771a1fc3818796d6c1bb63fb6d05603ff8454a322a0f65866c3ec48d0598eaeb24bfd212a2ccf3d26ac7a99180ae12e948a01c31124c35505f86ffd4845cf201e2faea4bb627147d4473d877889653ff6cbd1388400c238438a87e92577faf09e66685cf1db76238cbc864af19fb33c15166fcd47ac6a04a0e3f0a7ee40228ccf0d9bea59617b5c8489a2adc4cea17742006444a00b204e4f6c186916940ee79431c93cdd9b263b05263fa4b3acb325c9b47c69318e04d0707c4ff7ef72ec1e9e274c9566d390ddd743951d757cb7683a513e0f1a5d3884412e6a1a3d4e4350ddf3f5027f0638c73113c38888e78d0b644e5baf156e9fef1ce84100a8ab0a0f695cf3f7a8483e23843e3a0dc1963cbc2c15a2450ff421605b70a984f2bc0550bb40f5a40c21622dea0f6302ff3c4467f02a0b30db04badbc84b967592cf36937e0c87b340301c013d3bf171d6f3b48165bd2b267627ca39e0b9edc8826132019ed849324bc10ddadd2f09d17a73fbd7ef1f019003bd6e984ef79ac83efab525fa555ad4b3d351ca72a274318f9c1870a6f79f6bd421dfb97c4a3b3dcbf010e6456fbb7bd2ee605c0c7fb587447b1fbeae196fb2ae827d43df5579deb32a9b54a148baa69ae79f1421682c8bbc29c6991939d3b8ab1f4f7d21e8044cf462a93340c237e4d0c951c6a98f59a24cccae8dfff4258eeb7e79f9177dbf0a90cea0dda149e535b33a2bd365adb7795d3eccb2d4a76efc3a13ac5433c5167ff96a7137df66f0c5848e85ed0020bb172a3d54d9a651071036c76168bb258946952eb6cadf2648ec1848643224748e567ffa692ecaa28d37a361fa8375aab595d2faaf17058d5c9e46371adcbcbacb8194c8af9f09f4b5d410f867ff976f4dd5ffe72303484f681c9ee5b2afb9745b90f276cb57f93d6b37d4221dba7398036983e4c759da4085e4563f0fce98b776f5e3d7cf4f4c55fd5b13ad0fb0718bc0cf413b55e506cb4c6880e38d1e65ee60037650b7dfa443778ba45bd58ce21ec471525c7e054f6deeff40d91cca477705a8728419b6751ea495ae1ab4633a74db5f94bacd8ae19afc2126b1489a22607aa24b6693ad12f96f36e174aee03f51e063675633284f1330cd1fc6be9612099be32349ea739fd91ac000c0a8b1e5939f447bd2ef2a937a5975991004021bec9e102acd48506d0c2426545a5ddf0109d6a399961b89a1b90593bb59a1614eeb89ea95c4f745525e5dadff2bcd4ccc9cdc3f083d718944d249f023d4bf47b228e7cd62f97007c6c46f19c19b5f927170b0b2173749ae1600f2de810c798bdcc8aa2ecc2040f7d4422c2af22520fbce99131119e322a1f81ce4ccda802ba2396d4ab89d6d3ca2b6f4e095bc0c2d56f5a2cae25f7eca2dabe646844600ac43e0c47d74e782fe85822b60a85feb18aa8beeb32c737b27127a885488a12693216c54df7602491a8de11b6e2abcc7483d70aa3107a6faf6eb803a59868685f81e0611623ac59176e9bd11c1750d1a6c6b901390aa7c6ad28fe768fba6ff630fee5ad46dca95c32badedc9c1ed9220e283bba7cbd12398f0c238123963ecf785ac1714ef1c7d7685563ae9ed71aa0f5cdf299d2eddd9c5d29de6ee4aa09d6c5b52ed76a02cca22e20dcdecdacc8f840eb4b2ad13b92dbe86e1924d9bca8ea5f0c9dae373c7db1e00f46a39194fddde83addf3e74dd526ab4dd5ca31de5a6d42da4dcf84a7c982ba9c799fb976cf5572e4e6ae39a6b08e39c44a3f9c9ab00b3ffd7399649563147d2985dbafbdf66e35f8665834b221e3bc362c12dd09449d3eb66ca2602b8832c9aaad0c5e02c09326baea4e781e1420b8631bc162cd9cb01f8cd883066aee48f5acd4047dd128db933df5c1edce5ea4916e503636d5acd4133edf31363f2bef44c01073dc7ff61f90506637bcb8fd09a92de88f1f6800c2ca608c9c6b172007ad1a22385f7b2172be4b8a6a27bd46a082d2dcbd3c4502dfdd308e17443d374216c96abf9b9d405b1cf0a64effb22861f7a43582c35ea5b94a6a35ea43ec9411de0092acd4c974ad2e34d98ee0b10872c2ccc503801081e6549dc12b419a4f2880e90d446b013e6dcba81b9d96d3817700961ac28bdc24795da90473606e5b41b232230a7c7f92e46a9ee44b284396044efaf0a2430b18de202c34c48303731bc780aaf40a03f3c9573212c6db33bbf57ce6deef20bbc3f9e59f21360884aec430000bb55c98a9189dc9177b14ca1b481ab296077e2d0f36d4425667d3e2268f5495e67e5581b61276a6ae9fdbc7527e2b6daaf06c6ab5bcbad255ada7cfc36c473e51fbc6ca4fac3b110db3799adef6260691f01a1de2adefc67a870e05787b4cf8f818745ca1254650a9241bce75aca0174632256ff606a5cd2e3ceda31d460a0ce766a7f1d940d4c6255cb58f8f5fa924bb657cfcc82cf8253a3ef24d39363eb4d64d277085fa6f4abf689046091c5d314e7ab202066aae1817453d1b88126f0aa583e8cea82da2b85f22eb537a713264471c5d15331bee374b160b0d61f1a4c70045e84a739294fb202ae705bfa354f4980be63191b5fa809f821bf1d670289a06560e041d04860369571509376c972f15ddf74b6c9a0cb19d1a6dc40f7b7b0117beb3e514e0f6ecef4755ed42db6a8e6bb04fb9cd39bd1be8b9d045b9252a5550f6003add0e7e1e29e071c4c62d08ac25d8a5c7c9bd343d43e50a786a069a0c99ee26bf1183d5d5207c73ec9076bda04a5e271bc0ee0707b127552fdb86ae01bb9479fbb686d63772318af255dcefc2061d3c46591cbc7af9e6e9e9d3bffff4eee98b274f5f3c3dfd3522133e660cdf247b84f1afc74a4465f9324b91af12169fc08b3ba045dd708c78b32e9c260235cda84db391f43020a4d5a1c013a459e1c5a5a5cc9ea086212503789ecf8b1b8cca0748f349ed459d90fa6995526c9d4acd97556d64d3fb234bf917ad92ac2a54066b865a0c34c256d7853a38a040f857e9b536822768b30f46aafae7322975a58adc6bf255992c6603df338ba2f2cf926bedf07d0f9ddad0df8e1628a3b9fe1bcb3559750f83256ae9d1ab3a3d7414e54beb00d358fe634bc2c5f84af3b127f0f8d1bf2473b129569524d29dae8a73314318b73fb6dad297e94a4fdf50817e93fd9195e5e70d56234eef4d2f242de3d257d262c446b36e6e393f60e2c31a815340c90cab935fd0978b69526b38c2594d6538220642b22f2a1453162f44371a17895e2d125087d828ebc3a1ff6a24eca0ed19eb86d31a73f4424b349127cd459ea6c447662a613446feee39cfcff58023d2b968279c8211e9bce0289118dcb2bc906fbdf281fe89b8de96e0a61bf91f2f9287d50b7a1e700b87acc8c410fa408f2227bff80b00e3a81620d654cf5ae92bcdaaea06fff02dfea2836c122263ecccb4beceeeaa61e1652ea22da09bd62cac6b1ab48fededc9305ae1ab775f1df43c271eece2feb12a7c2f4e88df177cfd6c67d637a4821fc25a4ae7534ed2f9b4cd8c4a3439784b6fd84883557568250dfe54c0256be4c9342c1c417c8c9a251c010e695b228e4152728db6c2c73f3d79f8b767a7ef9e3f7d415776efebc37f80f2cfe4162fc9f5cbf251a9935abfa993c9c72e3cca567d05ffea2962e28b57e48f7aad8ed55b1e10b281771a1fe66789aaf42281b73220050fb2f0d7b1bbbedb1b88b9b2f01bbb61f550b791176c5eac80538e432b20680956e4a791d93d9a878c55a7d3174d8702e6f7f9e04391e6ddcea0c32b19056333166f3feaf5790beca597c32dea45518dd5db737bfee5facafc9627d7674fd729e8b0c6d34e11a43d4e6af212a5a9a97066f0a95fcc0f8976b865a57447cc0087cf1b673f19c1f8765914eec119027940e26051b8ea727d65bfe7faca7e275779308f13e18fc809ff5a603a8648c24d5f7ab6c9c10ecb90a06861772e2382a289155aa081b21c5f0bdd37738164df0e2a3f98814392605901ee99bd1d2c0a803006a749c23266b559aeaf3089fe68b8581578fe66499d5eeb5746b090d6a096f2c168d4d4b2d8feb07d95ed4ca05ba4caf78e952dd2723a53852e67e31dc85fa328f83c4ff3e7c98a97697479feff74eab109618460fed877e36d5f5c312d8817cc1ffb6ed89deb4fec19847b2f5e457e4f5f9a4df7c44d615798ad47e392487584b619c94a33e62ad6f51dca2be049558c89093606971e7949a095c75536e3aea572c9d20c7801d5717a37dedd85684ef95efcf4d7878d7c76558adeb42845e536b8e3b21392790c5bc4866be1ae4a8091b35a0ea03835635af8a6ce6dfba6dc583b18271fdbf5f1d61dcd68106d337a63e3c744b3a7e13c7e146ed0037b5c6aae5b8a055d76d7279d4c66f628b49b083e00dba9429b687b2a62b2391bcd7d6092d4b294391a7bf2f6d3a2cbf7ef715841cf2f185772fb97c4a0e0e75e73894b63ca27699ed69a9fbfd81e3e7961bf9cb0a2772ce5cf7037b4904c5621497c17a6726329bcca2bf8a3623e2f72d026a974be40bc14f4e4af0b85d778a7f8eef39facf2f774bfc1ed3f7c840dfdbb875e38d4363592afe702db93693ad739db9deda42ddc74e77b229181b6c15948fb6256e5328ec5fd5110c44e60106d840f09d5d7316366aecc422f4410681ae3fb28c9323d55c965ad9d1d2abe525c2cd3acb64e0b671bb5a4cdf144f5ff2cad367a05fd822fe169ae12e705549429afb001c4b6ad8b8573d1308de4f06dea4d619d8440a1e97cdece6a671eef2b5522af0b5fe2a3e645fcf582ea6320dc2ff010938e3f759a55673b78ea6c5cc09b3d15f61a5e6d44f10b9c177633f6f7c6cc33e567b78356637e2ce35a1036e02bbc27ac764a8ab0bbf8503477bd08d4f9b9d9e58d6e15a1dff9efeb21002a91404962bd0450a08dfb08fce9c0aa3c0224a58b0dfe3ca40ec98aab8351a03aad6703f87cb4c55da0b84ac0023d9dfc27f719f8d3c197790d888f7f071c8670fc9b64f100f6ec4fc59b210c7bd7333deff56c544fd253feb45af806a68d52c9aae7d4113a9fbe49aff2f4329d24a0e47447915784958cdc2cac49125a2dfaaa72a4846ac88ec0b17434d75b1b9ae62f0a7c71b637c16653b16cac54a3c9dc5e7b7293bd1db58f2b711326abbbd724861bde939c5b3ac5356ced07d7ddd674e44aa1e382a915a3a037974e725175a1b880649f16110346390a90b6b7174c273f81cbc61f1fab03a936f17be66c13f6f6f4cae14e858d7f700cad3f5063e5bb5c88bb859b16616ab96586d43d61bfad8601f1cfea6696665a7571fc68f37cfa841f4cd7e8d3ddbbde52f821d835de16cc920a5e1676dcef2c65dbf5276684496db3f5f48f85c34dba73144e10e9b1d2759de657d5d9ed55ea8eb79f49bdfa70a84e5f3e7ed9bdfea637761eb2293c14636baedd7808769b17f90b7d9578c9ecce479dfbbb9095681c22d724927feede257193d615fe187bb422c6b2e2c4faa30057fe6825d18ec83f76e49f3e062592ae42101f7645fd2a541e5f92121d61dc096d9547ac49229c78effe6a7d4b5ebb485bbfab8ac9d2e3936333d95df56bb7505ac971418d91f7e507d508542cd38350f89b22107b5721a1e9da10dfd8bf3dddbddb583477ef3a3af2b1a8d5783154ad05f18bcfea8b52271fc5978d766dde33d8a74f2aa60bb3e26ff54a976fe8e9c60b9ef81f631a1aaf86624cc5dba1bd7fffb12f88f85fd71fe19d9f137beac41fbeb1ea747afdf85a715f9bcf8b5fbd4283a567df81ec62d8f46ce9a62652c28f6218440868ea709bfa03af7404225b3efe082d721aac357f8db3ece1b7f628d21f7a4c687f0e126b2dcdaf932c9df615bef4a0652c1ddb5c312883aef2a2f497d0573f2b8997baed4f77fc5f23e652c04ce4bce293a1fb5bbc473633469efa1aa43d96457f06ea717f8efa8162a87a5294a712edcf5fba94cada8cd065c17a68a0c81cd38733fda346a964d5286595e1d152ed8a786c4133775cfb8e35c7b1251d37081f2bfe63b0eedf8f3ffd3b738dffc26cc0fbd05cc4b6aabe0a5d9ada56b26d4c5f351d9b823d6cbd6a62ad0e05d2f646b19264139b6b634c4d20bfcd4f5ae2014ba84a7779b912ef544149d9cbd6aab993b6055cc691fbeaf72ed233ccd26ab7e7adaf7744dccdc1c137553b88a5a0b9daa8f93c19bd5a7b76cbc1d2b673b9a5646c856ff33211e9772c7aa1fbddeee4b559234a1de839989fd8eedc581c3025f664f10d9e63cda75bafb6e01936dc6b5b9ddb6ed16b68b6e875403fee1c163a1dc154b87ec49488d1d136c3e58a359e9f63ddb51bbdd92ae94415c291064c22b08196fe9c7c0e1c6c24b0dbc06e5f0b8e626c49c43ca1becc05653736c10fa988a3d8d4fbd88ccdd717e9f390e6e3ed5ca3e7bb3b6ce5155fe088107f7691e6d3ffb5dc0bc4f4d29fd29ce5dfdfbf001bbc931bc497ba24d827debff3b556d80408f703c87c4b8f0243a9f16aff57f246e5d80e75516475ba4085f9d97f485b83af7a3affbbb5dbfbbffd6cde80c79786437847a1bd0711f030baf11923e9c38330bdf17ea6ecfb607ac2ee6f7951abdf0caf46f1994b52336dd153af8220731cb0ff89c97eca83b9d1bca3e575904042056f6c7d1fc4ae6d7cd8642bf95dde2ebfca9ba6d55bc6baa98c366fce6dae315441704112d53687bfdb7225b24d6abcc985072ac46f4177ba6d21a5d06d174d6b3c0bd9760c629c70f4db7187039ac5d890ad9e134ec38fc69752d4be47d33407424e238d5656717b53247c6844d42c39b3ac3f683346f266945ee558f274ef74de0cbb6abc0db2835913628acae18c72a5b83d1555fb3be3a0bace6c423bf5edbd6c99e092742c25f513f7e7d8dfdf0d9c55ee1a8da0189e3698d53fcc8ce9b061c674e8cc98dc036c8b2dd3619b2dd364bb2d5334e06810bf239a87ca97ba2ab26bfda7fb515b4f4a3d8abfc97fc3123685c31bc39397933b7e2c8a4c27b9da57bfcc348080d7854af2740e0f3a9324034c460bff73591673fca9f3ba840389323bc2f2f9dfc66a621b8024bfca348430b26ffe8d9671c8ecb1ea9457174977d487ff06073d760bb3215fc7ea803eb940d3c2a72b8c3e3d56a3c1c8db641c50c95920a4e5649925e5585d2659a503316d9bfd8237a26f66c58d4a00bb7e5a160b0403643b632bd89dd5d5acc0b83e3f524e6f92107d04c34ba2648171bf582ac1267125d46ffaf5480ee3e1b7dff6f9ff46833f7fdbebc81af0d9996ab04da658812ab928aeb5baab2e7456dc886aad3bbf5f2f457cfb75ac0e77af8387279d6abf6f9b2bf987ace4162e995406ee6f7c1188cd627a89b3a1cc34116429e289b72cdf466f5fb93210e8151115825ef1e13f56072349e5091b4cec5b487fba5a44dae2ba6fcf0a0c8cda909b659455eb2c76143a9d1ae98617259a81c38b6c6078d88643e15d2b69986c28b3303c27b52be4ae0271e096d2d19e03250897a5ba477ec9d073aa79d470e99ceba45a96785b3234bb937ad557ce249ee21450177c38c496b8b42cf5f36cdc48ac85acc8af7455436c3ea88a83fa714556f5311b7ba16cd53dd12aa9eff0dd57a9d69b3110a6deb958b13d7436a04a4c151ecdcf8df1b11649688dd405dede578ba2eac312ef5b28503144900995b429bcaa880f49e3deeacbde63f061dd575dd8404375e84644e7534cdd13a9de50385d1dd6f883df8007bb570f7d0b2bde3aec8e0495154d3614bd3166ebe69f6171d8dd6c76ff655aab4495c9344d328646c723e526ad670153f08d8b2fd3fa97b49ebd722c0f9d19b1dbe436832b1b745b69c5e07ee6beb4ace0244000d792825e6405d85ccf937a56a9abc2e4287208834cf40cab37221ab3f445595c647a6e4a9b5c638b336e320daed27ab6bc0094f13ccfd3c9c7e177df7f37997c3ff9f6dbcbfb17a30b7df1974bfd3d92e606eb6482d206539a6603b3db2f8ad5b2d2e5a4c86b0df1abe7c3e5f09bfbdf8d0ebef9ee9b615d14f3e564564d529d4ff4e02abdf4a8be29b22550f5befea2555255cb395b7e4fd365653b5664eb2b84289e25d9a584ce216ce6fc3aa95452e3359f2826b5d2c964461a8f1b2367e9c9473874661a838617d7bacc920500a48ba6e01cd46a5ae80ac177ea82d1c97049e354253512f78b3f04b79dcb349fb2809725a5e13ed4125316a9dc085869658e40336c52df59ea7971cdd36d05c46a962cec10d5858331c4059ae6374939add405010605cd33037dadcb846cec2140ad6912469b9da6559de4135d71801be9e3e5576c684f1258fa1c7be5a258f1e01b8e8bdb862284788d782955b386529fd192ccb8093198fac480fc88ae095d4b3ef2f0ae7032176551974b816b5ee4b8008cd8d3c7b1c4228990b6919bce92ec9a503f617aa66eeeccf8ac04718c70ec77e7d46c6940069d1bc9461870c1885da675ada72c85e16aedaba4c28561fe4871282f88d358018dc1fc4da36c246237def3a2aa11df59e9cbcbd46cb85acd933cd7a5d7be5b6ddfb54e82bdcbd6e9bb07d51eb890d59621b2d68054b2bca8a25b7da07ec2b84976bf93035d779ee6cbcaed60988c9e2a444e393f46b0b3d6ca6eaf81991c6a66f6c8a67900506e0c60f56cf85a4e795a390cab912155d5c542a555b5d415ce985cad150fd8e5b2ac67baaaf110770f32d9588de8a42ac7e4bd2f0584daa55f70facc0bfecc91c64ff15af2f928acf2a16130c2059cfcbbcd98a1a4072d7d25028ae7ec932fe21d2f1a718e196ac04eaba1d6708fc1c041c5d2054d96da702f9c1d500dbdaa5d79dfbec56bb4257da5eb5732a19b52a46908ff99e657e696acf6d4b7d619844601f43781206ac7a0cfbd9752290dbe5bd4c29c263e346883c6357acf5cd3a9fae73229cd6961aec61900830328f0545f955aab11b213b3d68a4bcae394507086bc36c24a5ec9b1004507cc7f3795fa679206c5eead8bc75011c99744aba7fea7fae63b19b473661770ab5c2a867fb072eb6c700331af0ffe32922db9be1dbdb5a037ebabef477d75f8e791af84a426d293d70fc1d61bc86b5a98648644963e0a33e25e828c729c42bdb06c86cea7ea41d888b2bd11a56884835b6a34a1dca109d79b47a26e6f04a8d2771989fa16cd888ec4457b232e4423368cc4457b13b81db8212a5dbfd6d3e5046d7d1a6ca11f34ad1f70d05ee36a66eeee1c94fe4951e24683a644af6223ff226676427013f2c2da47ee52b122e0fb13b91075408aeb341a6d03d3036333bba96fe50979ef16ea8735e2f8d016547b2297051fa353453877c4afeaa64277538fd8369a0c11db461f57c38bb06f4abc4dcf5d370cdb59bbc7a1b5da3b164df6d687f752dea01a25d900fc49a61f96957fee3c294ae0fba4ce215e268f5ccc175d27df070bc5703877ecd969d83f565dc70ce12a1e5f370f0c0547f207f57d1b3d472ede53b35b5aeeb5e8e254afdc295fbbd8481b81b8dc2929555ce2603d926a305f5186005d6d0a3457ffb2d6e563bacfc80392bf3d298bf923d87bf611db29dad8d8419d28876dc4c2988525da5d2cf63bcc8797597c5572ed4c1e360a5f26d1ccd68f49a5cdd256c7aa334fa7d34c778e046614eccaad8217a04cab14dce98e54babf2f63c0fcb4aacb84e1648b255ec020cc31a9e96500207c0537058e615f1fa3835e64e286ea504665f517c24e729d3fa97b542fcb76dcfcff57eb05e959729515c5c21903cd93b545e445aff145592c7459a7bab2ca95b069662240e1cf8fcdcd27a760826112a108b8bf6dd3ab424e1e16e6486fea35086c917678a65f7f982028da53f391479bafe504a4123b33c75699b91f5918d6d1d13bcc622279ac74449e17ded7a68fa5063d4fb779e61b16f81aeea9cfd25c33be1bbf7099f9eed33d96e270eec01ef935cc0ca82034e0ef475f7a990287e534d7db16ac5f2b2d558a937ad0f348c183e0aea46c8128b9d8bdd39c5add3b7640eede55775ca7c16de08eeb10fffa056ffe9e602425229fb5e2cfba2c3e6ade5696a44d975db57f1f710b8182ae9f819f70e5aa0ebefb83e19e494dc3df9ecb3d9551096b23d25292d23f7d52a3c128ec22e038bd4aea19f5135a4a232939fae332b9716b2e292795bad0f58d26c349a7b840b249392161798547246fb435ffe4f5ced6b6af9eaa7b813412d45ed56502c780e978a526459eeb09442b747ada5bddf347dc0a39aaf3e25a9f16ddc69534b853baf3c23b330f362b206ea382f09be6a67cd7c6c9eb0c1486e06162aadd92161fda99189ac3bd2cff8f2e8b2e58d7b5bbdee3032be73a51688c37762f79cec31e9f4b9eed84c65819e18b40c0763396b6aff4a48a5ee69322878504ceaf4c4c5de8cba264e9a42cd035e48c8dad6e6853a37d95dbd6887ac64225a67af785b9d4b4b5ca9dcedc4ce232cfeddef1cdfd04f4d8a1b0175bc7f20ae83030f3718de905c5a5aacb77d98b97078b22d29e729bf9e1fe2bf11036601eece4de7f6dc3bc6e85900c9c2f2326b7c203933eb598f3eeeeece7b921308ae7ce9e85b664d076ca3840c804dbe832b9f97be282ff47fc41db8df5b8acef4516b8eb856e79689adc007e3dab8363f62cee7217f3b6ebab869b5dccc3ae6f63e031e926286504acb1cb56746dcb4a9da8918c0528ecfbbbec4ed3b6d2b8acf488fa2f03bfd8003204cb6fc969862d1c1132324ff43bf0c5a10b9c925d1e2fb70834c093f7aa61dc33f72e1082757932f63c59749bed64842073f0c83b151b0c49636451894defaba4bc5a9af5e33c611ae644668f521574bbc65f63d5e91cc9adf13b0128eeb18dbfe0265febd470793b8ccf28aa8e552f1731c32739bca11114d41f9a68b8e18e79cfe81a8f642861844dfaff51f717e7e46044157ad42cade6195e70edb9aa727dc3794c026a80510a3c6b754cf054d99e1d1a9817bc2a2a38ac5e9360be45b1bd6dfcb179b6c267fad29ce98dc713725ba8d2bc1bbe97f4daa9bd2691cb1e008df7907d2b9f9811df504db9a11a14daf61bef1c446d525421b57a03b51f314ae4b1da6f6bf685da571b4436d99348dd17c2df233af89e041fc9622dcee383bda9f86ba70f6994c751dc54da742e5ed68ed9a6e298c93bda5bc459de9ed2dd26b6facd3cc4c6702fba107bbec1db17103743d4a04ddd02e242f208f84aa499fd682b1b5f418a6f1f4acb9afc0a25e3d097f5f3e21a84973e1a00b99f75b1703f30402affdeca3be6c9eab5bb54e16d67dfaf0037879866bf38ad78d942f403692d81ab54b47a4b7ebb3237ddb1f6839e475bbdf1b6d7ed726ff6ecb0e092c0f66562dfb6de02bbd4bf3dd77049a3c624afe9a130e094c11bbd09f9eee60efb5071fc7c99d5e9224ba191df7c375243b5511d694f73724ac6ccfcfbd3273f4801bc3b3f2405358b4de2a3173704acf73ddf0930cbc9ab5a2753230b9764b5c196742ab116176c3a1833aa80770c505dde6bf4794f3451584a48e1c9bedc1a390dffde83911a2b7a27be2755666a68cd2dc47cb53f52edeee1e5cc123cd58e0d43ce4e8a0d13f617c98bf04d7f3854a7c947add2bc2e543299803e1a6cae9cddfd1e0ce99a6cc179882d50b89865f47e7902f1d29149f8b78aae8d84ea035904c1b5bc97ba66371c151aa87b7ecd528e7385d8d394e1516285a4f79d54dd45a4ecc63c6e470698a5156f8179e32507b7ecbeeaf212127aa0d0b67a3576c286a56a7ad46c15321056f63281f5d8c95d3b1120fe4503bb71ac22eb99c6cc5fd6a1d7b1af67c51216a9bcfd69573ae48a26fd9854ba6df6b69f73366aafe72beb9038d0bb5e7663de5416db2622cf312cae2fee21425580da089b96ca50eac46f008d47e67061d0e1cf1368b4cd316a73d58e39469b3dfad7329dde4a1958d358f0dbd776cc54f90cc29601d69b2c3c8ec28cce0b4ee46cbc614937188f8c7cbd8abf6af502bade335b3b5d7a606b3eba497a699fcc529db148f3d6bbf9961b5a6b882baea4e4b5a34925d04d329c473f707e8a29251de2400c05cbfa6ccfb7996234c2547a4a05fe2f78999d379e65793cd310da2d00a10b07c89f3da169706b897ee0dbbd6fa6241e1ecfea6d8f8bb6d086e7496e56db23e459e421d23ab776dffabd714f8bfdb637c7be7a7b7ede93e3157db1dca18a9734011b1f37fb6a34189dfbea5e56dbb0b5585427b7cd96e5766b2e6afe63c1d1043216515eb877c0085fefdaed1c8e63f868eb52e8f5521cc5e2548d4d07bc26ca87c4f00dd15f5ddde818870f8767eddaadb673e1763168bff064d81c9adb0f6edf646adee3c5676941e3dd3a1a229767afb46b70206e47ac6ceb91e1796492f5d0ad4c871c52471ffd20ece034b892b034b3318984ad1999fd94495e650922f66d5891b0808ada6414d7234948d80f7906afbb58b57dc579e44e238bbb7067031e53e3854b6c92dfe9e8120d73a1bd433775af49fc7abdc9b534d8ecd27cace1abeb5b90c922aff5a4eecae375dfbe54abfd56a7df7f78f0cffb344efb625991d7e8061abf7a34b0d67637e37f987bb357c2af6b8b83b22bd8ca0dc301f42cef9ad6c8b4fa467db5ef737cf160d964b2bb73d7d3b4cebce0f179512cfe28388f6f1a701edf58380f69edd182e7f1cd91c3cb58947a92d47a1a4072bc73290110c7b75b8038223021d3cd3021383c79adaf74a9c07824c96b44b3b56aa39fde7ca7aa859e0cb082e74f5fbc3303fad79f5e3b2304f3f1cdc3273fd9944f9fd4fef7a3d19f0fbefffef0dbfb7fbe3ffafefb036ae1f387ff881078f88f06814879a400f3f9f787cfdeb0d7d83ccdb2b4d293229f3a400d7885f6d03d2ac439e05fb55e546375301a39688e7a6722a3d1c8a7f39da0324ff365adb753f96eb491ccac5896db897c0354023287f71d9969b2de4ee52fdfdd8f90f946b4e646eb8f0d3a005612f4e9fe5f2294447be6455ecfb6b7e870f0dde15ff4f7c16c1d3a3aa4addca14d7f1efce52ff74352a2456b9dec32d083836fefeb031c121959fd6f2f9e9e9ab5f8f2e2839ed4838f7a5d75ed1a452ee4e27517a6cddda4af2e7c0bb344edab8b865d1a5861ff2d4fffb9d4ddb4d6738981314baa99efc4582c6b87d02ffc4ffaca943d1266f0be870950dee26262f2705617b515c44ad390b726e15cde92edc730de45b1ac31dc8f496d58f3b911299675ccc1e8799a77ad4559dc46cfe7735da7116590765f474a3ad4664dc9eaab6a4a568d9af08ae4612db0c54a92bb486dff3204e0c2f25915b0aa5c90b8d488538b22a3e0730b3d492fd3897a6f8abc574569af3940bdfb7e5154ef7b9eb50bf888573a292198b2d2795da6ba623341f0f1b6d1354bfdcfa5ae6a3d25684005f4548a91e9128bdcc5f6b223287f30562375a1d94f1cdded2494a882f735d3dada087450063d8feb992e81b65ed5a59ea7f59af2eea1d04e65d41e793df706ea45511300415aab9b62994dd5855673d31933fcf3f4371cb929c401cdd6401e610b16a5de276b9f29b974f4d5c5b28e9906e1b99817b5ba5a266592d75a4f555213b6ea5c33380190af0b358118f9e8af5e141f970b55271799a608a1e64ff5f0d92f0f7f7d634ede3a4973e1485ddf14b8d5c0340bc15c93d5c09096210145943fd382aa4ee68b0a2449fb0318ce148ff3acb8d1867861e3917ac4f086f319f4d7657ab124fc9fa797aa8346459dbea40c3efd175a558b522753c204c9d6046f502316252e136c3e42cac293d34552a59324cbd67d1c3e180d2068c7a2c8b3b51c877fc1ce1d7d066aff82cd75f0193b605a5869b388e32de41de1e6ab4ae6daeae97170c0ce1a96df403d45953a109f2495ee536b1c69586e10b5c7cd3f8e8059b166a13899b20faeca165e01f10980f685990eac20c93249df50407a7284fcc1095786c45c01dce567b0ec4e4dd1aea3edf071fade540bd73b6f0598cb212f00f03070a4e8cc089f236c281fe06363ac6f51546335fadc0fd39215a51d90d611cf96cfce631efbee1f6c664d984ff3348f1c778b525ff7d56459967d95eb55dd7ef435fad276fe19625e7eff1084e4078a401ee1d70f2a00838753164e3e931e3bf944166155f98527b6e9b83bb1d59e3ae0069be11129fb2e857a294f79f80e8821666f4fa7e40e21764025f1e5780fb8a1c1dabc204a9f3e296c5df855443aec428e3d984b7ad0bf737c0c432bc19781a5c288d182c259871595aaa1eac288edab83dee70db20690b127f350fdaf4a6b954c9385e59d0c137273733348f2e587abe4e32c29011fe47074707f38fa66383a185ea47952aef7f170dd4ff3fd0fc975524dca7451cbdd89e741176aedab8f7aedbfebc1f349c1a8a328ec99f9c7ce0ab52ea7ced3695fa5667970c44b0af498151812f0ee5d43f087633573eb639e4e1171d49ca5694f3d7860432da423aeedadc9651608cc99433d4e0f648e735fcf988efca0d988416e036217cb1ad0f6705f7749ee4014629009cf3ca5a4fa575660d08bbe9aa563951e7cf60d13418f758001aa7e081e48cf6a1848d38b3ddb3d596e84e51e34cac18853ef5b0c2165fbcce807ad13cb6ceb20a0c4952572083cf20748de0c4303aeeb191fbd4236c44d899556c5b29c68f51e2a7faf1051cb9d2ac84cdf571ff5fabd0d6893a31c530a7beaa4aa8a499a982df1be769907ea49512abd4ae68b0c4cf16d1b788177ccceecf4d5fdc3beea2c8aaad36bd0b6af0586d9258ecd2afdcf65921991e5fee1c01cf472008d4879619845d5b7edae8134aa35df8efa66e516a57a0b2ca0aff2733859419666dc24d7e0b4c81b07a9e8ce9f0eb843156cd9ea3ac9faca8c84d8b725a116fb5bdc1510483f466e1d37e4c376a1f09066aa2b0efede990b8f7b0d50f900d89315ea84b6e7e85c8df9f32cb59f035e7268727159cb57e80869123dd889e881233a4b8fdc815e2d1208d5a257f5db0ab6df3eb41f7f1cb9a1ac53b37921fb89ea9ae1f3729a630112c782535a55341c206f6b49bfc652f790f4917704b80c6acf2152fb97c2ba38e585c98eae69be584a68083c34acb7d7e01d7d70edb3d65e3e1a9459f23613bc9594c2cc0b3fd874c41655c79cf1d3279b13936c4ef68081761e0984ccf5421797b62223e371373be2790a0b632e01702df8da4b23174006c350d3ba822b92dcc249662e086baef94e6b1cdb46bdd448eead69245e523acc824f78c07184d859064bd883641ccbe575c481753702f3b0d9ff3545d1959d27a70808ff65f6a44a73739d4cead4ec646a37040c2bd47b1cc5f76a9698cbb6364baeb84ea77aca805ce662b834d331078bcbaa36f79765857748a71656ef91f07b9a73e06486789a5f0dec28d3ccdebd1b1bc5f6a9c65c5d5cd652feb3954ee086cda8fbc55cd7a846c8a0a1492ee7be6fd64455f47981d4526db47519b856b54e5f549ae399f2372f968d6cdb4d5680982f5c0b561012b7949df6b55dd84d46629d65855b09d57ee4afd04630a1a0dbdea2b6cf04e69c6cccf69ecfa4d09af4e5256f23bff0d196916671e4098438c013fac6dc1296795aab5257f01c82fb24592cca62511a6942f86725cbbad8e7a0385374d70a0f64eb28f2b73cad9f14e5c3a519ccc9c7ca1c8be69bbcdf4e924532496b7940d30d0a94b62134404ae20b1cec97d6a451dec1b01cc8172f2fb9ca9ebb83a1b985a739258aead8bd5cbc05326fd373be785db2b927e71e809a5a9d841fc6f201c513bb6d46d4609b9defbcd3ba64319a4258f82e55774f504f7f333bef87e370ccc402e346b7ef3cca41e370bedbcaa80bcb299539baada3de4d5acfb64dff1344d94ef32bde48f9727e8a0fe08d052197411f2a8f4f6fc372a675d685390df4e5381c2433336eda4d9e733141c1f69ba697975d8c34675a6c72f74cf5dca578301aeec7a629a126ab9396ae1811eabc1d6af979f2a1284dc62eb6e95f6721a08e4f1673ed19913bb6dfdade18bcb1b25b84c66be7f5e82db9bf1237a954621d428b4bf59e57f97ba975632db610b0fb0a989f852805a2efe7695e94ef71f9baeb14ddb64011021ac1f7c440df939e72be28ca3ac9eb3102f098a3b39802ba29eb216096eddd1075a8a1fe34ad3b956d4aa9ab459157e9459aa5f5daa1fe66104261524c0139719219418cee48e925e8a941eef03717b35ede4a1b19e9974aba36dd0c91b3586a1e9630c8a473037b0518ee4f9f361c0136eba6b3c05660382a615dda37f6ee5b4b8393fb7e0bded8cf07e78ed68dd61fa7c91a7406d06c2366998f1d807ba2f26955fc4219e9a1d289f4a0ff80e26284307e95d07cf208a1c4686ede54cb12bacbeed536acd3145f944c1e1a65960ca8c50e7a8e1ab0170a0390d0571d6a7ca7cf9d0daf0268c4e4c24955aa40ee04dc620b791ec013d59926eb0e3aa593f516927f55ea6b9dd7eaa22c6e8c680b7ab9cb52ebdf009e38074d3a0ad0bcf4e8f94a818580f9505c2a612d50f158b430606c817a00effda3113c1be1e48b906d657103bb744f7560a776d015097f9766fb15ead2ec974552d688886b175e7109d9ed6f5306ca9b8ae5e802af059e728c037c841c0694ccf4b718db643aede21ba25bc4d819d770789104cda9c9d9b80d2149c4c797f74b54b8e0fa061a9d9d484a06d7f604eade0acd38ea7c4af7f08a5e68a657ba6278672331c0532914e89bdc9f81d80d2094c36b8ed51525aad419066cc647442f260a207c1bd65a85cf98c8b64f671a35df08a8364fca2b7c83215cef1a61b401559c63d74c8b1b4c2ecaf42acd938c7820107c49bd32ab23999ab3e566465843efb1c7f66a9756f078dee0d4f468499458cd545bb987789eff7c7d2d8298398509c63b1cf98ca80fbac8a3e63d82d42be65a29a2e4359848546dc67a400c87373a676da01095bcd07b000a1a898476a0f66913c4f5b29cafbb432b0e6c2b98a8c4a9a12729d0cbeed4a93074e0adfb88b3c1831fe91c66e84293f6bfa04987b6498d8e060124287484db6063f33f7c311aab037393c0b1de53076acfa4f69af13a2a5d83f88827344916bc529385f91f122e6f235cb41e27bcb806163785a9dbb2349d2d333670f7687458fa60d1dfe46d01be3b6e8c3f7fa0a9539cea71642275201b25ae8918c87f9e2cde42b2bc4150644adf674446951c7085c2d4c62164c598af536a9aaf4fca626e5512769650608ccf50443699278b00551d657f2413b96cdb918ee09c37af07acb440724eee372306dfcecd1eb57762711af9faa4315210117d3f1432f096c30bb1a2c72f1a6ea6882a63061a7b5fe94562e4e56cedec25316615006b5ee849b2ac9c344e4b14f475fa5a976b204355a495d2ab85ce2b38a5e83cb0f14e20184200642366165f392da6f21d316127d4d6f16d36a28432f3cd5defb3d1a508b7867ee09d86c5eee3a44e7c6b12671b02d58f29e3be35301803f40a9c8c6457924c2645292275a52803a3910286e33017a8eba45c234c01d2237b9008bd5d2c40880e3c03bb483136480cf8da7ca8868fc0e7e643355c2cb36c78ffdbd19f6d41c0543d1cfc1903bf91bdb21c8bb1b3aa69a0a4805802825652ae011bb0d6576bd5bd582f92aad2532369ccd37c684433180c3ee76dffdf9b6ebf1f23643e846db0e370b9ccb2b5ba46f4ae7e70e544cb957971ada78e1664f18861a10835a84512abcb650e5aeb2f1cd26fbfdb3ca4288e8ecda5a176e1fe90e95663f52f343841d300867806cd381b8aaae110ff52c7c72a510b08d9962b7c67f0dffee7c55ce7f5870a1a3c2d26d5f07f0c49ef3ec4fcfba8c81a2a78c59c2cabba982b4633a2b03008c554c15309c31b41f84385f49d3629dec4655dccc18cbd2821484f69861aae15e60ad557605fdb576bb01dd2f564404a62335092625ee4ba7f4b22e438844a3749ecf14faf5efff4e8e1e94f8fe9d0b2175d99cbd564aea3283a983bdfbe92ab2236cc57badeaf743d4cab629f6e8a43e2fe78d31fab8eb8d871c446afbdb01cceacd5af1f42d10ceb9b8fe942d80fe3cb07ee4a5882a8837341daf11581cea3b1cdb6af3a865a676cf529953afb3730454cb2b37f0b51c8f01202be19103a49ece781a4090b5cd2443ab04261db75d37c922d8155a207a048fb57fd69f5696dad497b1e65ccdd461b2ed4a8da7a2fdc0bada9c0cb17cf7e75e4be8c654677b8dde367355a308c6960ede4d0c92d646323004ffdb3fc2cb4d7466f0dba328b40cd128d33cdd33a4d3230fc6e89d33ed7e51546eef7d1e85a823f3b8a6df1d83182ff2d71c048c3d6e21238d78172cd48079e9932086c1e02b695bce74eec86d7fa1b1c2c66ae8377a6b99698fd6cbe7a2f87cc1b9ebe7cf1666c0e07b3691235d755955c69342c2b7252992e74a9702068070b3f992e5c6c70fec8d2939ebbe9ce43bf3afc1339bdbd7c6da305f7e60eff8954c8407c771ae6dadde13f058d64d5f146e5c764f2f12629a78a1f8c41813b6633ec34afcb62ba9c40f03b1cdabe7aeff3b3f7ea26a92c41406e77b13aeb24cdd5bd24cbee810a8e0e28b548d2b22213e71444a74ead2e342b40a7961c88a05991d8685f64b8cdf38c26aa4532d5642f6e3ad303ebde4cd79d4a2d8a054494b214e76905aa729c24540e8a99764fb0b0b39e5e821269e077b96f9f82894ab719093ebafdb0a641b258646b7085b7c8826dfe660fb3acb8a9907dd6058ed1a52e753ed153759d26aa53775452a34027bdd2bc37dc7113aed47befe08feaee5dc57f0f6ab042b09691f2e583b31f8bdcbeb262d328784d737ca8af7c38d43f1eec36ca6576e76cf4d6e6f95bf0eb00a88f455e425df55f4d3d3412e1d316704f7a17b2b75c4c6174c7f07bc61099ded7b4af3eb061f207f85f84b115461258f0e174aaa741351275f31de35656dd00a1db370e76e5b6868d21a400b824a37dc49c847817c2ab010111a932862e4ca0ee5bdbb0015a38f5f184612b1eab18ce668ae09a47d273773854cf80134d8adcdc474a8a529965b8a929c022dd05919f0c5cf1d02c04ddbb008bf8ede8bc1780778896c8886ffc1f8cd9071cb30f6e9aece07c503fc07733381f1ad0c2ce968a6cb1ec34bdfd10807e88cc42150fbfc38ca2c96f3f9c4be3762fe367f723d445363b4e0baacad289000770037a472cf5f66e56be65fea43057487424aec25e0882a1a759d87afeb3d98dd8ecc9321efc8907af213a11c03b83348179df4afc8e00de190406cad600ee388fe2afb43b60046308bbf3813a50279e27a1cbd31b54455977d12bb1a7c672d465cad1a63e0a9f886dfd14591b9d88f7172b748b3ef00044846e8b308575fab985171fe616c053e0fe8cef8656db9617e666934e59c3d207d55f8661f9ecad0d2d57dc5d4db69641b7a5abf3495353fdd808247971d3edb1a9c7b8d115c6e0966ed78294cea751427bea0091b9654f5d084fe08386745a81a26352676bf4092bd184cff4a05bea7f2ed312b54da1953299565aa0717f450828180b27ee1602bc951ef41bc0e1af5e3ffdfbc3d39f6cb97781e30f7d940bdc413b257522576f5f26989d3db6a776df3ffcc61edab50fcb065e54a7a827d85decd911f96cd73b9c847571bea481a0d26647111165fc410caa6a482f6c3561b13d403078445fbb027f10aed6e869208035f08b946a3cdf32db62f9d9179e5072f2ce26cb09b9bee363d28fc0fd567e05858111ae9b3e6da422eeb5714fc1a158b6f09d47643da443d98156e662b8358f22af9035c799c76d71626743fb333dbed9b69f1cb86c3d661ef0f2addc3b6cd070a87eca2f0b3348c43f41c54836cea8bfa606ff3b71fbd788751ab5b31a5a1bab5639776777415f668b790d0647b97a70ccde83eedb0fc7810f61c3c62210ec4271c5f2673168cc908391f1b8ef70b8c1d052953a4bb5358008c32b5485bad16a5ae49d1a8cd7d31a740996306b5ae1c50b1576f6a5cc165ceb5a7dcc8b1b34134573a63cc91a95918baf3b1ee866d8b0197380425c3f8fd9c9edecc9484dc4aa1ebb1999dc789389ea9c1f5c68f908d3b2961a243af63bfb40a78e0554137c1df05042c4121e07b3fbd7e0b87be2d40991963afb4e2e2babe573b8e154ec1f25149ea5c5bb58d063ab9ee3d08cc556b6c194e5c897845be1aa3ca8ba6e8357ca27f1e0f17b2eaa9783febb049168131ab62944e8eeeb01fdc5658079c4f7c00fc421b4f886dfa071c10f2a821d78223f92a9810cac217d1a760c7c71d406be4cf7eb860f08b7ba11c2a7e906e2782a2c8aba28b23a5de0fe6b9a0ffb9ac4aef4c9304b0021c4c40ef5c945ea453f1b178b849d959a55439ea8daeeb68df2d5a3a07c17b6770da5e613e7cae6dc93cc0a48afd329785aa6938f6a9e941fcf5a51b710f3cb94656a62eda3d521430f13109d3f015fba05b648caac560ed482fe00f9623af366ebf754bd65fe77ee49ee8eed7a1c21ccd3a4c639cf0339db9a1fb94db1bbc0cfb63eae5d0062ec1a40d679fc2f9e101146102e36983b5a1627fcc798ea3bf1aa18cbf19357801ce0624e5d2fb8b47f5e81ae813f586b573993b814846136ef21bf06172ca825dd489b8fc23c756be93a560e13cf1b4f0daea527ee6f0f6f913681b9dbbb4dbf63bc272af9af60e2621a661166bc45707542c76eea6078e36c6e75b2af4bad7d5dca3d6c3b62c57d672750bf2b5dbf4a5770b0a25c107097edafa256bc10c286485f1455c39853481ece7ad2ec06cf7ad3c729a7463e4608a46e976a1ab049e4a2a87aea1e37678066930d2182c944e317d845742b5982de75d94bd11e500e7ada816e989bb1a0ddfaf0443423125ff3b8f7995a4375d97460b4e4dd5dae71b8fb241a5eba2d93832b4898a307e0bd22abd9851b51ee593fc280fa784508d686b3d494a29567647a623bcdb0fd6163855d27c15258507ae77aea7a004be74951021dd10500b4fa9db60b01bbe25ae7bab88661b0c8d5befda0f3697365b6ef3db3db00bd85f7619b2541dfdc15ab99f44506e20ee4cb5f13d6c7ee1de2727537494931a85196f7dff8362128906ddf916826d290cf434ddee42354f28b0bcaba03b2ed754be0728a556e0638ad7e2ecaf4b722af93ac6b8d42e9385ebda6a0b07428577c2af37779be4f8aca663f762134bc18e7a00a74c5395f95e6cd7c8c204b8e58218069d735e892726dc77d060f9df0acb68ce2668c174731d2f764b77a6a0f33d866dd93bd71c1b066314232678490ace72ca272768bf051b99c6a74945ea5731cc8e2d229445088437f16040cb8d01b4f55d7ccd6f52be389782bde2ebb5b9de39eae58544a6031a7bb9ce63bdd6c7d215fea7f9ae23f3393453af948ef1af995ae6a9677bbd241ac07c6da574b5dd53407a1986a6ebe5e1d6f3ddd1300270597345181e8030dca3377dd8d485f62e40052b94d7ff156643c0ff518f646e66dd7df74606600f32e5bd58bbf0bf8f19b1b9c46c47436950c6e305c008515a38f335faf23669a30a3450c09aa797fbf45e0b44dc3982ef6e798809c3eff51e0d0f71be0d0f72d3834dc45e3a0d0f78f3ccb44fbae35496a7d5594eb31592cf26fe03f683b3ef6628a6342719594693d9ba7139bea3e411609543d8e842a1726d3aef1d282f2c9cbd7cf1f9e5afc65563a8c55e7f9f3e7ea715ffdfaebafbff6d56c3c9f8fab4aa15db60fd3dca1c4c19b376f384398e60a229e327ce78f888edc993dec389463acbe23f08a3b59d691a8c390c3b4aee3630877defeeff3ffadf64512820277e003f73d62ff38609b6656ffa0f57200b3a24e70a4dea5a67b98a54386d33ffeedaf60436bdd60d054b935e4300dbec788416e6e5e1e02c58b50523924115652b520c5345558acefc35e0455351fc9ee106a499aa3af851da218ce8ba4d98beac710722cadfe9e64e914f80b7e41b9e1b26b2eda0d19f992edd57d2d55303c2c2c621b403e64cd88ecdd67eb64306d504ce6c532aff9157e03dd643aed7a995d07bc4aa6e9e5a5a825c48688d6304f563df264a60f69ce96011e71324468f4025dc943ff70be018a6e1cb975e5de1bd84dbc7935031ee83c03ac077ad0f770caa1181b4d6c1a2cb08688f666e35ca011c526c281117328fcbc221c2790152ea276bde4f7cd183fde8daddbb3fe4602e4098de1af755919c1ef70f017767b51ffab2ea62e6a636df37cb3e1f682979e364d4a64546cff3fab315b88e7bedcfdce5c563b287d77fae415962dafd2dcb9555ca659a6a589fea22c16c915b4a52e97a18d7ecf1e31f36461ee31e288497c55103ebe7be223bb50621244a090120b59a3526a68913ad7c2b8d05c75b1c6e7ba4eba5e802c78f34003451098ea04205f5b2c18c392849e7aacba4ce3ee5d20c2ba94c1bbc92ccda6a5ce7b684129f5b6e4334c5458a1e005fea4b9bc635f700c3754522b60caf6551a890999aa1fb88ebb77a992b7e9f9e0dd75aa6f7a010468602a43de6a9b67c8fab4d969e02fa297660a6dc613fbe76025593b665db7645d8bacd1c7a6876599acbb9c3f12e673d370d94c5c5ebeea7f6e914a7d82cd0a05f5d558adac924c9de04440f75722b0cb7a6cba1fe6323d5ff71b8db1822fcbbdc844ccb0986df276748eccfb7f747a1efecfa498ea2769967585421be29b0a4fe07931851b8bce06eff06f17b9165db533b8d09824b729e16e9794575aa20c60d6a80a92a8dcb983740c9bbd029f36177ae6738410facd7dfaa4ec9718749a836289d1308c2a2cd14160878e2c84dd6135e693ac3092439a657d753072206e16ed0eb3f72c50175ea1f82b544c7f0bf9cd9badfd0ef7cc7edaf34c90b841c819f7c48037b4aa94f598337ffa44b92178a6fbf5e0d85b00d1418cbcb3bb8a29a9ba49ebc90c3b44b48643ffd0c44b50a5ad87f1d89f0290097006305b5d2cc23c3a9fca1cbfe9b208b3c899643f1a00cda7ed9deaca11a0cc63f7055b213e982afd2aeca21f0e559aa37529ac2e74a183030e4fd571fbb2f4bdf6c972022f6c3f121ff259aedc9bc46ddbb628faf678d9f053742787e7abdbcae2d50161abad2a406c72bb0160eab7612b6e70955ae6759aa9eb6f50170c6899b94607289a44773890b322e0cb315db0fb82d1406f78081a0f7f5100f4249fe2efffa3cba267ad94aa62ae955ed5bacc934c91c88390c9b488f3ba2c8ce05335a03cd35a75f5e06a0095bf991ba9104407900143c6436bcb89e03cc8c80365537d28f513123571dfa871b3000eb1bba6b93acdf2dd582344938f5657170bbfaed36211562452216c6ffcc12956afc91e52b31235c42af6de3b2c89669e6e13ed083337dec6c477efdc7065069117354a59b7bb7135b862c08e23e0a87418488872bbbb6c2f7deddbd1461943143fe18e12d0ba276578f9489ac4ec3199274091a1ed1c655e8fd272b2cc36b1af36be6419cc368c392b3163f2c668fcbb72388178e2b071fa6a421120d33e8a6282e3dd89c7c908591de3164543b8db4d0651acf96f32eb4450a02de52050aba58187228627177b241e7d7bd4c7aee28a0aa15ad8ac401a13c010003c8ecfcb3c510c780d2fa2936d8d48fb4d6a27842200d044c206d3dff336e8acd458f068d9f0d98309ad47b1c550a89e982b098ed5607514a4ad5dda3a48e34739db1a19acbea7f6958853efab3e8883a0631e5c18ec4269308fe8debafd9e72673daddacdd3112ee62d7bbad1fc8d024ca3576406740a7da65c95bd9158a582ec26bb2250666994b065a79b9b790dee6461a1c685e54e587553e6a3cd4d1139a0da3bf66272f72ed766b1535120368b7cffc03b6feeb4084ecd2ac561e24e411a0693c90bdf165c32368bf3e2dc23fdc56ecde04ec28286e61f79d73aa2190e5ad09460a5834eeb39288a9acb7c13275f2f20922e695c3ab10b2854b98d616f9a15ae8425d04ea45fa4e47a6bf29eb7aefdb47a5c263760702d75071cb70018edddbbea0ef29cea63ba6802f996c9cdc35227dd49bd82c048d77a44ff1ef40dff1ec1ff1ef800c9139377dd5765709421c694c8ef850676723bd88b83c73f80b525a54eb04ed5cd8b729e64c0b045686f6cd8dbd1f9c0b6d2fc5807c7ce813d7646fea1e3a4a649925f2715470117bda67847eee7794316c461311523ff8e0b717826d8ac133e17f03c70dff94c28ad15c43fcbba0b7f2d8a1b51d94aedc3881ff6d49e8aa4af4dfadaa4dbbdc30362a6c2a2559b53797f5feaabcc0827e5a46be793a7fe6d4a7d741f10028f3e82e223a6930f26fa4391e636a6cc4d2166bae219e699c06ab8c16ea2e5b7b5007db56ba85800e298f696119bfd7bcb63e3686c5f22665482f19023d1b8894f0b509001015499f66963f7d575aa6ffa6a82d1cab3c206af46439a2548489e2ed749961823c5101898bfff9a2c9c548b6bd71745b1c1fe37d8ab12db1386467e701142e9241df5d5e2a0afa6a3be9a1e609b5f7230149ecb20447f3c441974af15e99b34f5a9fa9f9491a4c6911d10368003dd33271f2040a261f8a6a5d468d04e5396a9a12039a675429f1e042907becd0140f641a02cee7270cbbd7b574d25fea2cca852115feaac9663a0f682510ccfd329980a4e250a284d1cce334981c29b9ea611a79c920f226faf40c67449b26ae2e36651f9e80abb9e1147ae0cb5d35b56c47382252abe1e042ef60d6f7c1c94001ea06d2c3c177f2879102bd91826afe4e7e6fdf556c3411b63921595761ba3112d7d6255d59cd2f5a0165195f40e1fcdf8e90b4c06f093c5b7bbac75492f4dd5df42d828b8e486d8bf3ecfd901afc315b222ae8c47c4df443e923043ebf4b9ae13b815ebacaf9c3bb07f82d14d9298866f95bef165ce4d27594db91ed9147b15f09e8470b5e8cc6c10a717851fd25841671a608206e6a6e2ad2c4bd65b6d24168f5b5f047b5e707e33b1e3c6430b3fb278598120d1f5127436563a13cbfa48ae6b318a833fd9a5e5f965735fc8f45f5ed9a2b82f1b26ab79edf21d5eef04af82d0b122afd35c007788660bf9dd798334ae81f20a18f46920de1c5beec661093c614cfec80dc35375f1e3276076f18634274cb81d0333478b1f848be4dd95aedfc09b03ad12b1c49d85396ce07a654b4dea55db3643b92394462cfbf1a7939bd30c7bd29024692b7209233fd2920ab6d51dc80950b466dd35ef8a9b67dded65eb26677696bea16746211390aea5a2147e3cf7dece01237841ae657542136c13615c58d80a1e160d9d4de6c68fbc3125eb45acecee5d1c71f796de74ba8f08a4932c5d888307a7dafcaff9284faf9d054f332e207c1e6da87699cb8aa32ee53e8ce295ae5fd7d9cf40e74f079ee9795967034c7e68bdf8c037ac28164156f3895203d36fdf9add4f3cdacd1a25d357005b4ec34d66b85e6c7f01635c170bc60d4db2f4ca7c42bd1e7fbd5c666c3f2d28d01d440087d667f50d58b78e2170445f181d27011a2cf8af63d00ecc53e48f32df11451b39c3f4e369ade79ecd9cb378711906d213e748e69da4ecbb224d5f7ce397b4ddf285720f87ea8dd6e289ab71c2192eeb706ce9e099a5d3a9ce79fff12f67bc70679286885e28fe53d67178762328f72c9daa841d98d4603050a52e753ea5e8f5d051bbcb53020174666676668afce7e25a97deeb47913fd3c9b576dfe02b83c6d869b82856b426ee8feca9bc48a6e6d26ae6bf2f5aec821191235f352b6e720e69819328b2838d239c6cbaac535da9ba205f97b1c855eb55adc6f80f44b987452e323809748c5ab1e21238c312b07d8a95c85ad565f15143e631fdd890dbce4d7a896892d80308538a608915021b5346f35d143737ef47c9428dd52459a80a5a680e25f33dc8f638a966914f74fb1a0749ff4f91e68d8fe89f61bf32b64ac3e9d23faecf9a907f11d1f9c8cfec1ea5302f0bcd343cee4ddd1559561ab4ec7c53b045ac97beff65e01538926073ac5f0f240b5fa4304760d79995ea3a092e4df8bab5b6366e03b1e30d4d93d4f55b7da2466a2c3465473e045ef30dd2fc6796adc3667a0b55d1d647375a3fbb5dcb636c5d785c07d971e18dd59d1661dc55d70b4ad2e2b4d514e554978f9205541ec96b96a39fd97c69c9c87ead6176fc1e296456b49fdd7c696b0bf123991d3e055983cd2eba1919c9859d67ceebbe04594bf26fe28cfcbbefaf0734edd0597183b10fea1239b988ce5c5c5d65ac57e425e29390a7dd58b9e994b9e45efbdc570e78f92c146fa885b84fd9f77ba3289fa5104a645a4c004c768037869ff0ced8ed2cb38e94de77e2229e5aced037c7bafbebcd22719edee6e3a0d2f54386a1ed76265952551d161c21ee79671f7bd4d90a1b2aae01527597eeed49e514b5c4c81da67e2372e6d34746f0eeb60d4496767a427f25fa42544076d98552b548f2365a83284f107d33179698e5e019eb8e443edf334e56b5a99da77a55bf28a63a42aa1da6893de5cd6816cb5a973f9f3e7f66b5cde4ab44c1b250e0562226b591c42914d58afc012d4c618d2185059766b84230144fca64aefe85a0f09f5128291675a5f68587219f66852fa588f208caf459b183a657dc7c041f2f2cc2a70097c1f672d842982ed38da4d449333a61fd23095be88ef8725103ba08397c7acf6236837f528236d426b1eca61eb8b69ff006a1df6321f77985c228664f9fbf7af9faf4e18b538aee081b91c2ba002ef7627991a5936cad924a210cfe3318cb7e9bcf000330dea191309c018b30703d29a724747d1b78fd043cd236ba5bbadb16d19b83af2d943b129798471c9a7e96d666b67485216d92c9cccae2dd34b77fc3a1e210237105fd9c9ad914ea42a40e837956078e0cf4656869bc9b19795d4f890f799783e1503d2c014bccb4a1585ecdf2650d8664ea66964e6610803b51d3f412e0bc6b82f85e2f1c8c18977a6e0a1d4b3b4ce711723ad395a6189e88860efd44bccc2cbdd493f524d303f5b7dacc2688ef339dabcb22cb8a1b0ef9fd305f2b616e8d0f0d8c449ae6335d8225c2c51a608b4980344dada2142649ae2ed0361162963272a72b271556ac39c66b399ce28d1804f304573ba070fd0cb7da3e87c06b5f4c3c0f58837ac6a3a1f6d5abb2b8482eb23501bddd2418fdc45ca2a9dd1c93e4c6f41df792ede0915b46b20f5d6f7d3ebca88af282a23555b5368d03077a50e45a02dc35c4c2fb4538d46322f61653f16f998c41008f792c64fd8fd3b9ce2b816ac88d7da36b97d6159068555b0268fae3c56cf8f9a0921f01a54de0845362fc3354d028c2153ce188ed96fa93b496c52ffd9f404d66190efdb4c674398486799a1b86ebb6592d4ac8459a1359bb8ebdf1f19673e5a7ec86e10a2a0e3c5197f9a4c8abba4c605f4e99140769c0138ee55b2c4deecbbe21a610230084d27045d63c31b149924d965982088b1e4918be1b070911ac5662aa97b5f70437d78392d7aff6e022c20737e78ccdd4dd6affca46d7c5226c1499241f3b1ff0f09dc155865a14bb82e8f733bfab2ee1d4abcd7d7f4d9d6ba6b0f1b4f09fb2b5d37a745b1e7fcbf79e1bbc68391dcf8cd47e14bfe673b8985b576a634d8b2de9ade80bf97d774c622bbef8300aa45e901a093413607562e529615977e9c4af81af47e9abb78c5008a803c285cd6e0e57f632cd00765c3c7bcb7ac52fcaea3416a9af0b8d887d542285cb93079b28e4f028c090189f26aca46c542bb8a41572225d099744cb443716c493b4f616c2655adf3254502b729e5c1c269f0f512cf035389d7eda69752f530858e32564889209efce6e29f108bf435fa922afddc29057e64b070d63090d2a3a27fc0d6ba551577a96d61724646e113c0911f08d85c190c7115dca054bc73c4d6b7bbb8864920fb2fc06403022dc5c91ae16443d73fa40a6b0a465d53c2727ea60a4c696b935b87b50634bb14805de59d0681c666bb2eea7b9b9085718d1ac0259d68dca1daadd7b527483d11c1cd798b075aee1c224cd5eadc1be02d79c58368065b0cb3449d9ca7dfa85efaa70d3c9d21c94e3245cc33a1b50317553260b55e475a1e6cbac4e179986fc958cecc9c1c1e749be063cceb43697ecc269bf51c3440a3d5ec4f2b7c4e806cbd6a24eb29fbd21a2543320b55ed518a3fd58758cc0d0390a937f4c2a0d1d3b569d793a9d66ba2388880b623299757d36d717a042f66be8388b4ec056eede76a50fb4e4bc302c853dd5b50c628896930dbc2cf734663a2890b32c6958082e7aaa1be1b7ee4f0973aef6a8257bea50dd13670e4915ea81bf9403d5ba9ca4bd63c7e1f69a948e64b92dedeaa6047863b6f541ef3c30c8fa2c7b6c44dcba2811fa1c99247529c9a7b4b561eb0ed413c0ddb6721f016e53e42e80c4793f2d939bf78e38335d0ca6e275dd2c3a292fe1702cc24f2457dd3494d62c5ff19889ee7933bac3141edb396c1ff5cff20d23e0407bc772b7d97c21fb8587ed57b42e8e37d485e659d9729ecbdd1e7c797b1ec98f2df00ab84f6f230c8277df96c62ccb52e7f5a3c2e61fb5a44719ceff6d5e6104bf5ffe187e614eb94b60dd7592657d755518f68d0112cde8879ce501824136066c4fee7dc349ec4279109c77310e423d3a6e4cd4363e22d7141a7c05147a70da2f4a7d9d16cb8a3ae54b238e0e2db590107ef683356d5a517efacfcd53bec9c1feaa31884dd0b0662d36f44c90d4778b4436b4394f1e93e6490a97c47f02866abb7b1ba6dae4841b979fb4aadab6ccfcac3bae245f4a64362ceb96f7b0a86ce9f4002df26578490b2e5fa8797d334b4a3d55cf51036c3e4a697203821718e1584b5a5e0818aaa558808be4862c848510aaa31f4eea6592656bf0f5915a5f7ab74133af33b26cfef7bb3aa245d663077c17b3a693574d615767b8be57bc6175278464cad32c632d784dae8696e36771ddf1f451bb1cb00d6a02b83544686d17e4bd1bc91d79c36e38d7852bdc102ed90a0f0f496194d7055a659df515a908fbe26a4bc2e951fb1d5edcc1793e42233da9cee16cfd96597bc2197ae10afa63d4034e50a9848de670a81ec15e5095ae970b775f94d7233ba6ee6b17af4c5cfb961b53eddc9eec6137f856a408eb0b75ec86182fda450971d93eea7a5616cbab99d297977a528bbbadf02af0cb92f95b0a11604b3da9c97a6bf77bf197c95ddbd42d72fc89b9db4350ecfe32b9c127ce1f0bb3162d975af5d5bac51012eff12f92175d6e35a81d6d177e3856a388aed07b8d77977c56fd9bbd004628f8b02e2fca55722d9f3082ed1ddd244ea8b4f9fa926b49339d9e772b9733bd89aecdd7f758a84f8c4deeb637f151b28835902da09a64853dde76eac2d82952894b6d5603b67ddb2b30d962a4add95493b2bd15f1df5e0e7fbb6eaa5ee48c4c8558b34056d7cf683cbc256aae183fa9ef417a3c18a969a1f2a2b6a836c06fa6c22692dae88875779981b6b10f2c554493dd71efd951782616613f5e6b7e24d26a051d5ac3c6325b1d4a751db24e5a83b9849ed4f6dd87a870498cc44db815c5a5ba4caf96a556dd34af6a9d4cc192a45828c3aa7bfe85b04ca6e9b292b7c17b783378f3bf5f9f1e0a08067b6e4025fff04e83d5ab6c5919666489986b64b4e0afea58ade51d8f6a90bd7a6c64356748a7126b435bade71785f0e969d8ebbbe103070031bdc2308f3acde024ffe03f7ef50a9401cc7bcc278f1b0bc639adad6486f55a4feaae1b35331b4f8af2595dcaa1eb014be75ff19b3c2c3abb39ef1c87ac5c6ecedfadd2cf91d56faa297565ee78eebdc73b324dbf4ff5aade746af5c14cfb974029084767925d0a18fc70d1d87c2b7afddcb424f73c6a3daffcfa39c828b43665be4059ccdd0915227d6c429f29855c4d6447ebdb901fbcf1041b701937a3965e9299b8bf9a025fe33aceb30f8334c21388b43420705a741b238985dc44b512c065d76ddaf579eb027c49cc05c49e8e7679588382bebac88ac94761c666fe63883c90e2818c07831e80cf49d9668306a88151274a3903877dd7205b9221ea8c94896ca441a01ba510d348f5bc95dd18b8e150b9abb41bcb5d9ee036bfece065c057a380e5305a50ec85d3d515f7babe7c1a189df77c982c327788f455e43304ac798000ce0af8edd6566eaa43b625de1bb6e3f2eeb2418fda5aca33e47b7b310abae1188f21040bfa150ce07082055ccba49eb745d25acfed3d7c87f790afd52d83269cf7b73abe850ed816dfe529ca56e17370f4dcaf0a8925c560b694b0164cd5f1a74a23b96ef40eefae307fabb4eabab5d2c80da254d7ae11914eda66414bc855d6a2c81477963c2cbb59651b25cb076220354fd66a965c6b75a135f8a7e45716e75ad8d7dc2495352b72c14a376ce940cdbe12cf73d1a7b90d03e34916723ed4deb158a5a1d6da6431fb656fcf4b9133cd57e25bf11841fa3c2ea038ac07db7f73ae8b0df5406d98688fbff8ad5d6101a9c5f5dab3e599a16d54bc413dfe3246151f96cffe7dbcd44916c8ee5dcf93d1533574217ba86390cf594e07cfb676515193e8c8ec37fea55e26a17ddcdadfbe4f5232b14840a58bc3cce9562c8b35584a2d8158d6ba77ec94eff622dab8186cd9217cb2bbf6f80707c9d4b73a376e11b1cb0ecd43692d65c4f2ad6aef1466f1c7c25cae669e8a16e2bbf16e068ef3c3b1e38eb0051fd8a50d3f311d19a66f66f246c3f6bd617390e564066847685b221c9fa469d3599dcdda746cb84a4284c6d92006d248cb11556dd98cb01a3cb60a7dc53c7e7fe5b73dfe850b8847803eca51109f6ca1e813e770a84e7930929c5138640e67392c0e7f093711c777c9cf62786e8d05f533f86443d5d754716399590798a73f993c9f31abda57a7334d7fd785f0eea685891fa08874f3feaa7718429bd303fce3f85875e6c5b2d2cb45479da8ce244b271f3b6a4c19a4cad6f951786b3ca0632e549d104208b627b94e03021d7d00bfe96d1a57fff472d561535baa02dff8dd296f793c190ed10f87e62ac94a9d4cd7e01e52ea2ca9d36bedde69d35cb131bcef7bc221b304abe9eac1aaafb403320bc734da4949161d7ee35d1e0e01495a0f726ca28c3a523511d4f13f490dec78c1b98769f4e53a68de6783d124f4543bd5a6b5b2f1778e715424cd505cdb946e5b0bd463ad0d4bc7f67ccc4f2858eda1dc203a6617755b23bf661680f8ad67e1ccf3070c60305f6812661ee6d387756dae45840385dc111ece1cf85cc66e64b9be219fb22e031b9a9ba64598613004e43863418d52242a11b4d0026215a57e9725eb62595703f4225b96da6f95d7baa346a9640ab2995784b241fb6c2ff08f089496cde1a0b4c817b6c1f1db50e6f182723838187cdb97efea692543c3814b1956da57f3e423e9afd53dcfd54f15175591e95a0fd469a192eb02f02b2e4a0d05e84e0470f67a059a7e531f154d2ab530ccaab824c2268d6b44c7362335b03d49a9f7d9f190f02570cc3e54ea32cd34871c9ad5f5a21a0f8757693d5b5e0c26c57c08f93e54c347947fb85866d9f0f0bbfba30dc2161dd0636aad078cf434f76cd5235ed47611b46026786cb4b1a06119eebe0b8ee47eeac71ce2beb6a975b0c9e46addde152720cf7579a59f5e8a6c2db14fc5d668a86203d0a52fd9942473c2d78143b770d936dd0f6e3d3131f9a0d115af23180bab85559c81ead26cbac63c84ab006c7d42c18c48eac832884c6ddbd0d3e009d9af1b6089496c2530353a8c0125ed027b54a775a69ba847129f08545588e6d0b928b2e96688a3269c4d1c3609c13c3a9d0004e970341a29fe7fc3a1ba58db289b57b03a4a6584621ed4eec16834ead14b5f72515cebb3a827fcbf8fc3f5a919cc0dfed6ff49bdad7f574fe6b847f1e17f7b14ffb747f17f108fe20d3ec5873bfb141ffeb74ff17ffb14ffa7f0298eafe9a6abe961d3a7587c6ff14f8d137726d287bfb77f6acc2fd30c997459def165982df51e61e85d23b078b60f9b2c70ff004f45f8c3b6c793f73846a5d581f7d4895388b32fd3d8828e7357c8820d09dedb6c526bc8f5e01dc57aa414f2b1ec9eb058dad07b6fec4f2437215c426146b071a40242b64be3060f891be71f7e8d713e680d8a8a413243e3fb23ef74818cd260df7ed8d93c1fa4743492f87a1bfd16cbede8aedabad0db4dcdcdb581eebedb1756b0e5bc077e785c725f6593d94a469419aac360698a027c44889d869e6e0bfbbee8ddc92f6bf7162b12e41972e142e4511dee282b83f63a711626f41ff4efaf76a44323de364c5bdce9c2887e13ecb030a5bf95d1b71dfbc0e63b626fb34de8c0ee821a009e80ba5d1ca57d34be44c348d3b8793ac52035f4a0e5f96be16099050d4f42858c9270560b815a126f113a6c8b70a5785e3360bbaf4eb8b1b4cac6966c5071d0ac6e9796c7bef9d0f38d3e4523652ec7f5dd02e5785ff748cf1c6fe3fe68f0ad1aabd1e0db06b2846f7ece6e08659257999182fd2528f34023743734f56cb88513e27190bcc92d9c8d6978dccddf4213d23cd1e0300bac71d6de3909cf9770aabb274c71ea351f313d8345931362b88ce0799ca7a7e75921ec4906b3edc1a3411e688f9ab4bd79f2cd453769ee41c7f0a339091aea3198c940795f934a22d737a89ed84d756f497d9de61ec8c8866dd3db434ea9b6af6d77cd06333f229a7beea453dcc397afd0db23c5dba9ed51fbf3255a7b2cf99f44690f8dbd9dcedece7f430fce33ea7840b888cfa45e78a7c5ff553afb1d9a2a73f2ca0c17ebd62e3515f76ecbc54f73b7358884250d35de4275ef0a4586cd9e68904168f06dce5d14f8b799a8e81b7fac5f9bf5f8a2485c97efcf4e5497cef199e9c2c8a6fae02ee905dca144abdaf79e102991b9926452476739d531b0842d454e693e55720a9374db8615dcff2b4fe6ba5a24138ddc88b4d2f611404072d3d293e22592e248ff46ca4fea0918dc579a73a934af0b952c1665b12853f03fa79421fd3bb8079c078c3a517dbaccd35ad5baaaab3bd40eca4a3ab8b069ef128c01617d7ff9f75133efc33c9db3ac8479f94324b34d7ba3cbeb74a21b656235c8d8dcc7325277242f81853fb25facf7729810293c6df1788e64256ce3e0912192913d9921d609fe19c9f5d44870c9440e63ea3e450ad0f6e3ccf4339271912546369bc306c03fa3b978c3410afd8c647c439168e13bc7750e33c1f76086e5b74891d374f2d1560fc19063998a22abd385cd863f79d3bc261101e20fd6fb698e6173ab0d7b0f6dd1319bb041870f7d30d022b6b7a98703964d606c4ed70b0d564314969efe19d8c504d1c37adce8674532c5181161e3ed16ec2695aad2a92687e2aa87ec840a1b69c696a179038995e5f18fca25506f0c676756364baa9737f92b0c58b1ee7e74527ecb1ab1dd65126f3fba789c9f6383cdeb6ee09edd88ef40c48272c2133a919b93adaf8a4b7593e6d3e2066c943a3656019b6261e200adc262843ed3683dfee9d5eb9f1e3d3c7dfaf2ff63ef5dd8dbb88d85e1bf02fbf48864cc8be434e9291dc5956d39d65b5bd2272949fb4a7a4d9004c98d960b76b194c4c6feefdf8399c175414ab29df4dc9ce789b8bbc000180c0683c15c0e4f7d967d5ccaeb6c4cf1ebd3b78c6d70e5e4d73ccbf91038eb6a2e4b91e4f85dcbf7d95fc662518a11f068146daf450917074fbbffd1ddc632c0ea711765bcb225bea670dd369cb2de4662ccae1ff46f37bcb75e30f10de3dbe97ef3f9e37b1beeeb664bee7afcf6b71b28c84ebfcf38cf021185e48bcf18e552994118c64e3e21e99162216267bfcf888326eb14dc753bd003874e01b821857129e734c26300377dc1b51cc5152b2440448edab61e332a9b2ff2151df27b96271b245e67fae0c9b382fd1f7ecd4f4765b6a81846e2575d1c35ecda13875a6c58b77b275ebff9121cc1b59740ea7e640a1119673c90b4cc1e8a1a7083c36e9ac4b010fa5ea83b51f1ed974045d064021b61ff3f07134618db8c022c75df55f6a7eed79f8f82a0c9040a9cd8f825d8e89a71bfcd0ac15138bad73af88f2fb06f844db25d14c2dee7f07ec895f814c6823ce246303593cb7c4c6c827150eab95d7fb8624a54954daebd5a08ab190215006b0e6c8d66366eb35f75993e6bfc0a07e48e7efad8f8386875bf8c1491405020ff6a29ea1c65bec60b6e53e7355e2c8743d2dee9c7579460c1bed058b60fc732e7e55e29b87d73c2c71eb0d311af2a5136f4e325de361b71fb2ae74aad133bcfe1eba5ef828d491627d3daf517c5f30bea53e935e307a54f733499623cedb6af44c14981e62112f55ed5dc6e752bf956de88f22557a2d9624fe8bbcab39168ee582fcc8fad20e080168d91d75247553982c78f2d28f8b8fd389b831af23df266859bd7c5e3bf0cf950e4bd725954d95c98137e4fa8798f4a5e3cd6c232d5c6cde8e7ac9ac965756cb3d0bd9552897b80dc54dd6f07ccf60ef53a47a098c108167ec3953a117c54518152fff6befdaad9e70b292b55957c715c8a4976cb3e52e16eef6c26e6829625dc6ce893c221bf269f0080dc9dc8522fd4133169b25e8f1d0a0147293c1fa01f16992c5e3ce6eae2311b2f4bbd2a17a55cb0b15055b91c55f88a4294d08acf05bbc9aa19e6c21a77f46b59c021ded3dec2883a433384da73a6d452a8ded7dffcf91beffea0f9be1493362bc504a89731b8c75484805da63f77cd735b17d0ff2cbe4d09fbc2153149544d097ab605f4db3f7065be7365bfbc34e3a36f506a779781d27c9b3d678d7176dd607df3d156d48804809be886467c7ef1d80cebe2719b5d3cb643a047ea2f3ee9e9c25365c17cf4d489a66991c51a05bfee64959843c02f4679178958c2945476c86dbbe29a7af9c388da38331ac0a4afff4703b63dee7b0ba0e9a6c276b4a5cb7f6cb5eda4d8333f91b0b9c0a7296dd06b4de8741d612897be3cfb9fc7214ef944ec15a3992c2d5770afbc727b434d0da3ca700753387aff99bc87e6e398281e08649c292dfe8c9d9936635cf5bd9ea34e9b78d7dbacb84af1aecfe40da617a680797e08f398956262bece1cc133f4b2fbab58998fe6d91690c5a9c8c5c8b08eae79b605921ce7b318871960928de8dee32fd3557c32fdfa5cf69267c5d5ddec25a2bd8d4c66065cc6c37ac475cc38fa2c42be26358b53478bd1fc9b81f7593435f7e6666d47625b5b7a2fc0870671399fb769124ff036fdbae197081793ff98e480bad27f530ec8f39c3e6baa00d15f7520b1662fcf863d9ee731bb6c23ff7a290bb0e0f8b849c0fab1b032efd8965cda977a1e3f832f52b5437e3de4a5e98f291dbcf54abfe4e5382eebbd4b33f614530f7b10b0fe3acb37ecd72b6188721d77ff65a9aa6cb2f299fb24cb737a0e38fb66aebef426e118977ec8e2df3b522196046fe3f9db8d67340599980a1f55d9b500aed130ebbe41528915082370241c466f7db69d2cb05e5aac17b490fc5d2d6eb0b6c35df332e3289dc665e9932d0ae94e12e5f47b5b886636558e3ed9a2055071aa247e496fb271d9cdd27aad742cb9dbc94c4e8ff9f8d0cd3502041badde17f5fe186eb884647cd098c45f842b7c4074dc47b237fdfdc41d98365ff0b883365fd8cf235e8edf083e16f65d54d4f09d5d8f81360346e5808f3c3e1594f79895e97f3661cda0859659876117d96ed8114beacffcd2b61473b9f6ab7229589fde4369cf48c3ebaa6db88e0bb6eb8fa9bb06591f7144f7936d7cb926219344828cc79362a2bd5316697a3c12ac42da3ed73c3778bc64bbec11adcca040340f4fd8c5e34ec1af2f1e5f5a6c871512f8834a178fd913c390a0b547f592e9beadab6f58d8864ab8e62ec9466553495c9399168e7571c3cefc1a2d94db480c5d73484d08710df365a3f0a64b9092c61c5df1259d7e8c349712f3b4883797e3652ebaf811ede0cb69a8addd5b4ed1a26250f1722aaa012a6b1696c1413e0632981a74d92b291428ac4dc03b8082751b2aa807c6ce2b70a734895d21321aaf463361c2dc8ab1d5e902246a49fff6f3252bf6eb11256986318ce9a6284e918c2a48ec4edb00f3a4832bb17a6698cc232cd662bf52ffd1424aaf5a2c105667a0d06e5e8995ee6cfc2da851b30310ab965712bb826dbee1ea40378c4fa98a6d570d8e20d8c44f3c5f827984ae8b17fbf4e5fc4aac2ea34aa8633f118b9cc3d5c523bff10f1fac6d00be0608602010376678b41b71003918230ba0ed06dd7be68a79acb73eb4dd5dd6c0896e44b07b3d36956c2cc4a24d6eaf234d687c289715cba55e4e3351a251aafe00979182ed1d1f3ceaafefa34f3e88c7a0db2dbfdfe627fdf85867f808078d261eb71f9b25f7522e566875df1cb5d8d3ed9d3f7616a550a03f7bcd476228e5559b1d14a3ae5d0567b34c312597e548b0911c83116f9e8d44a1c4982dc1f5a19a09f6eee0ccbc6613b92c8c112dc0787bf072fff0741fadd9e80aa594b26263882d26cb15fa27b896aa52e03514d8dc35964a40507e3c193916729acdb31c1c4e585618f172b8ac982cf215cbe55431ce6e785964c594b8021bc9624c6185909dcc45d57543a534ce4b854ae85c4e196a8021a3b5b816b95c80c59828aeb35216c8c2b2828dcaacca463c07500b5ecd54979d88b9bc361748b99c4ec1665963512fe84529c74b641e0130b048be12626111a834fbcee5341b011f43ef6f000a5f002236697106478ff7aff67f7aff9eedeaa64642a9ae28aebb8747aff6dfef1ffe847638ae130d6bca6330b61b7841a159a75e2d04d7636e8b322baa9f6bd582f7cd892ce7bc6a335e4e1df742b34f2d40f372baa46421e86a40e246395564708f3e0cbaf4f76c071c4a0ad6613baccfb6cdfa70e6522066ef3c831fdfe9a2f0f3c9136f356bd07a75615a32af073ea7f8e8fac9cbe9413116b7e430615ecf85527c0afb2b0db5cf1aec893dcbc0b0bb2532aa66efdf556fda8efccbccd2a6e50b1d33ad3d79e298d647334ecfaa6a240b25739134aba2530a96e88ab2946593badb0ac757952b57a1d7639d4e87fd2cf2919c0bbc8c192e917c51d7dbe974bcc2b072003a8410ad66a5bc29d0c07f248b6b5164a21809a624ab66bc622bb98475a69735aefa8a8fae3c789091b11893635e9e2b8c1dc035abc595a96b193285d2786d8d8c55370f04b39f1c301b81356ef35613b5c73b13646f99459b7d51ea7d6aa9f7e906ea7d7a5fea7d7a17f56a72c101c0ce66a9c4031763cddfaa1a03c24d0a21dd6e17703230313c7ca6ebad030064d68ae96cc37c6dd53bfcc836e675d3e7285dbe58e4aba63e5bb5d939f6e7b23b92c588574de85300f5a33122ac09a7d45bbcc18d045acbcbe44d21ca577204fd6e16726c840e7369adb9f0d616fced0685b59c33a6dfba0fffd554a09bae77f050f9720621155e1b5c19fd5cf26b2374c5cad459995d673c7f538a4973e6746a84d74770abf1e103e8d6bb5599cd9b2d94cffead81336ac481339bdb5565d512edd0d978090c6c58ca1b254aa629f44a315932ab9f602f4f4fd90d66cb655f315e308ef755159f829020c4588cdb983f5689392f60a3cf578c6b61a392852969f6eba1a82a51b2d14c6623d1f5afc044a196254471e1150274cd650ac58e3cbb128c2320049f558af191dec1b3612ebaeca0623c57928939446ad6f2c76259b181d1e90fd850ccf875264bbd4a01529e1557caf83d414be4132d545682f58f663e2fa03dd536873ed566af4ab918cb9b821e4535ea7ace109a5979c37bf0b5d8e7dc66f3d45df69dd768b2f8ab58bdd2fb93bdeaa2179f7aad65b46de1859605eb29c830db4431ce050483f42525ef75132e88823d862ef6a063e1cd9e1e9001869fe9d99e97342bb558f9f021b5de3cfe0a6d771725fc35eed11e1badc3ac5556955c6864f1294709c78a2fd6bbbd06cc0fb6190c8b9011f3f1109b6e46237cd28708a3ba41ec2aecb39a95b0c67d71c0125395ea1d467ef651ed66cf211cdf9512cd86ddc3870fac818bbf018edc37c206579af32bc13417a15cd699de6f8140785595d970590913d4406f45d84eafc7a42e7e9329812e9994e7202bc86d3d5f919d0c6b8adb915854a88ed1bdd9355d699929734309a812ba0d5cd94e6f9252b046c587469ceeec3cf3be9c37f451ae636f28b57453954b714fcd66d228245465faaa337bd94214d7f727d8debe1225f5d31b5e3320b7b62b1f5fae3a5e19abe642a3884808711f9f3d6e3f067b02aec481daffc71262ae90e4d56c747befbd2f8dc83058945a48d2f432d6c74bb0932a3305f17faa1b210a56dd48ccb0a550eaaf4439cf0ae1abd4d0e2fa1fcbec9ae77a9d5855c1575f1dca4af4bfa2933406353389b39469ad9832ae2561d5c6bf6cb89c4c44a9da6c28652e7801bcfc2b06b1c6c828bb4d870bfb38e77ade8ae57c083507a8a11bb802a5988a5b41a094d0af30ec82fe01999374fb05aa00c7d4a36e0d100813d871313656a1d54c642583792e64652cd5b584208ae55ce06eead4915d66a844418baf8ede0124bd38c306c0e414d41c1abf9cec55bba2cb06bbbbbb0387e9bfa88a57d9087fcf85c6c2d184bda76f605bbadddd3136a5235e89a92c57ec2d2fa664768bc1b3bffa88930d51b3f157254d77ba7151602050147fada960d5a6349f1fd909bd19e8453c308a1822338d00474d6dd4c90de072764010c52d9f2fd087035e40ac129820b6cb7ed582409fed00e3351fa17fb56ff0fd7d37c3c5d144106d2cddc2dabd1edbfd1e988dad605adaddc5927e41ba430e35c1063e0cd0800f445a6f8986a5d69e5008269e506afa302ad77dff5ea87750d5714cf3ed6d565c513c43c08d790f2c38fe680f885627f4be5eee69c878ea051aad4dd5bfd61216f859c8c50982317b6daa310fd6a65eacedc0bddb4e356be7764d2539fca5c57e35d32b87bf4014f1e12ffe8c3c87f77df62bb3d99cf40b54fbbb794ace470a7de60667c31cbf5f5383f690a9f15e047e7d23f5c128d307d9a2436c680e02c494edb2661c10c94ba80c9b1bb902921e89825b3ab01326ae790ec24a9ecb1b2d662821d8cbd36330b6d64d80f176216e2cbf6c5e3cf65ab9788c6d58fd8d71eaacb584916ec0d7b014135182f249b76c3c1d8cf364e897a857f8c563badd79dc62ba4ff8c9f33e9c82e64a552675b859286dd03b17b29a914a6a2ce94a20abbadd2ed4fd59180af1aa79597e4c6dbc3e5092655543414dc155264a97d280a2ae7225ba2c9b341f614c034d82dd6e37cd4148bb010736d80023b1015f36cca5cf545427fce68c4fa362f6bd2d89083b93a7b0bf46c5c38f4e1e313bedbf55f469c04aa1b4a863674c756d20d86299e7d895c639b1e3c3659e5f36a80b169d51a11fcdfb4b7b6fc05e18275bdcbe52cda9d5dcf4180112c29ed38f6ee57ded47ccd25346009f6770fda30553f4ae971336988aea8c4ff1c25393c884e7f9908fae30bcec70399dae822b016fe7f71c66eed8c6ffb114e52ade935108725bb25e2a036f38836ebc9be931fc00fdc5ad8a7632bd7cb029b26e68396b6b2071f3d1db4cd8f370a6fa66628d606f2b37a329d8da8a27252b185210f5aa858d3f77844b1ff07d3f2253fab876bf75a37e16dea0cdc40899cc00200c345f41d09d3cbb125db647230fdfeb1a7a3583c438d0c31e90b2690c8e8c9c0d9019d97520271e337a90e8f7c7eef6278b7e7a780f90e3d248b89710a7e5309cc1b7d9952027c6b40416153ddf69b3a76df6f5e5bd6bbc8710deada4e4962a0ff47c0f39cfabe2af8d60053c22e39fad2d735b6e978db960de20f5b916900e6b45b0415e8ce5bc4f7fdbeed541254a5ec9b21f3d9b202d96ace150ab980255273b3e39fc018ffffa3c48d1a9fb5092b142dc564d4c64a77fbe92cb612e9aad183bd860133493a7c21efe81bf0ad0cf113a6c09d4c4e0a1aec19e7b1ffaacf904248357106fd8597761235a5e882e2bbdcba413391465c5fe8f28aeb24235d8d74fd930d3c7b64a4c45a957dfcc56b57748d4c566137e3c61dbb77f12e36fbe19ef7cdb624f18befdee3bb6f3b4d5626c8b6ddf4ee8dfb33484ffc7b66f477ffa7667f4f4eb518bfd3f82f0fdf7dfb39d3fb75af781a0fbb0f3ed37df7efba7e14ed0876f7417ee0b61fc357ffaed1fbff5faf0dd77eccf0f813019ff69fb8fdf8ebe09faf0f57d21683c0cbff986ff71b2fde7080fdfaec383dd137451af448bf5344eb6f1df335ff946551c19009de3bfafd80fa2d0cb4028a21f4b0b487bd644811753ba46d966cdac18e54b955d8b162ae16ec158049465f4deb5e0b545fcd6963fc4264ef6ffbf1f0f4ef65f75d9d17c9e192fd34c992e800d00ed0459c10ef9a1392f437ff402edba567ae6a75e90cc05e4624dd36e64c342f8819888935ccab2e95652b3c5beb2fd755a4f0cfd752f748e81253c009b3b6934a258eff15b67f2c015769eb84ccb2a2de16225abd8085c7b8782585a6b0db2907b05284ba3cac7cfb3c000c75e2bf6425e9a11af057b35d43099fb17b3b56695982bbdd3a3262c33cd6012001423b3392a8872719b552b8d84e99297bca8c84d7228d851b3c0ddaace7f0dc36f52fba3a5aae4fc04be85b7d872c4737c0f69225d317d2a3368ae5b1f78f5ba407d6086607ad1d870c1dc081a191beb3e30d273267a7bc7077db3e5f89430cf9432278ae036215efa70abbecf47b3609247247147938db8c8daec9736ab9e855f6c623f40a58902dd613bcf1824007dc63a9dac064ffffb85edd6f0d4ccd813b683515a33669743bd72655a3cffe5f259fdb3f9644b65eb4b65a0480f0ce9cc3f838f66d58aaa7f8c8bebc9f751901cb285872d6f5f26c0da9f6dbf099fb7681e703a5b4e2639280af51a414accc1919f81454dd72fde730f0a2b6e5adbff43a63bc27bf8c29a1c957c553732fc686d08bf88c5c2464b82cd8e56d18d8877af6c2b86e2f7869be8857f0dbdf12ee9e2f138bbbe781c7bfeb5ddbc47d6f1eb8ce0179ef7887b4fdbd24712693fd23dd17f190311d2ad4ef858408c6d747c7a90e71c4450062b9ffd624c05c772de31fd08beaf73a2236eb3d68beecc02d135f60fcff64ff65fb5f1c7c1e10f61bd8e6bb2332de572d173d5838e67d3a9285fa061c98998e4f2c61abea43e6ef252cb0adf414d4f845c567df6f5f636bc98cb65511d15fb45254abfe0b2305f6e2166acf35f5e2c042f6b4e6e6ea2b448fe3e7804670cf7e6dc20477391869ac99b46e2fbfeab359f5bd4e26b3e160f370bf91281121e68c5b1d6db2961bd01f340ee4466a37303f24cc358924ab084274b19c30d80db62c1a357f8639b9dc3b7cb3b3d977d825f77096efc79c6e3fd62fc36539596e3fbe1825c73514e84e861e38242253834a88a574ba5f7e9429440ec6b186e2e0bdb6f3b8b21c375303cce9b66b40d4d830d8fc73acf982e22d6fbe2913376f7720d47be283421dfe1348345c26b7dfd2eb17de9d7ff75d8fcbf2c5ccc7d6348ac63abe413d0678d4599cd79b9c21b03f45bf3f9652a0604457322db17c744d148ee370801e139c8eaefb153acc21433f04dff8e1c4bad0d1d3c3d246cc490a26e63af2090b53db4a19f0f7c8168a8b6cd2f1e0f22704fd5e3f31d4d931ea9d055fca9fb96880981be09f7f2491d5685e7930a2dc1b69876645c503542fdd6166be0cf86f956f7136c13a2b7b68222761430bfd147a8af3ff83eaa9e21d93d4458b75236c6af889c3eef2dd812a6085c77438c098fabbab1f88320fb37302a2bc5242efa88abd882cc79a1f985f504fae6a35c05f674776c9df78b29142343a88bd0d20bb944bc1dbcb07d30df1f124303eb78fb069899ff8cd7d786337aef121b8f65515351e9912e2b31861d10e48c365ba8a5184bc24578a0f200a350d2bd178cd0e23d348c0ffa6cde6eea75ad0f8ebd8ee588eda6acf4fd09d785b6b6f41f83f99f3271a3c9c3ddf4d32d79f9e36201525eaf79bed7f9bf97adde7443c766abc54c14bc124dbc620d5187efac0f10826eb346e70f3b8d28161df5a0eeb2f7747be7ebced3ed9d3fa67cf5d85e9e63421dc54aa144792d287e652261c584aa63acb3de3097c3de532e86ffc19ff26f8762b8bdfdedce9ff81f9feefc69f2a7c97f3cfd8f3ffef9e91f27fc291fffc7ce9f7baa1cf5ae453196656f244bd1b303070ad074defd45913292e6dc16b1f36ddf98cd7bae8e21aea0de567bff6fae3abdfbe0da3699447a6d4a2cfe6d6b7a0ae6aad36879f34e068b620c32341a4cea4e359b36d9cf074ce9f301a251b69a7ffbf0f70ffff7c3d7e3d6f30f735e95d96d137e6bf96a216057f8a0aec48d2ed77adefa432fdb30b64cd96653778a8f1ed1adfbd656aaa3dd4a287b231e2ebc78addab9883f7872d786898b8b7afdb685bd7791cf87f2b905b91cfbc73fa551de68d8edb8f2a7a2d1f0f64252431b207887a8c8da24da1dc133079ad69ccbb83ac33d47d3118bed4f4bb385248b6bddafbebf27e1456ef74aac942bd125d5b427385e8955a097a7cb623b40e3dce50e8f8f2c41980be75db6ed2926bd51636051ebe3edfa0c6ee2d63fceba45fbc41879927b33f26417dcd4b4bcd2247947f7433fb7189c1f3cb0eef4a6a066d807a8d4671194670e883d93d9f9b7fd70313310f2c563fb8d20fa7df6c0d20c79781a2975266e2b84f20cea8e9432f73cd1d2852aff7b96bb6fe8cf212f5f941ca2c17fe9f3d33d8e3a5ffed8129d493e3924dd90979da1468c770aa90bb19eec6f5da01a6ac18bff24b132fde02366a6134148cca774a44cf3f5bfdca27a4fbe00f7061c94f735ea2399e77ca13e59abae79605d973e525f4cf3fe698af636dbffdbc119bcf9dbc1d9a76ade3fd1e7f473f5f6eff64e7e38383c35ba25931cfabc8159e3cfe4a2d166f48099a81b180d85f24a9b826fc5a47225219b75e3d25864f9e7339b5b1a450c9bafbc0d29883cce6813b75e3cc69fb065d9f2e7db97dd4ac299c3c6bbb61f6dcc6bcb758cc8a11b39477897f6a3cb954fe838b7902e7d0e64766f484c7b5054cd91524d0db16d409c6f5fb6da6c67bbb5b9d40e95f2f31486ab03ae326aaf30b654f0f61c890f6e2ccc9746ba94b9f7a04f5a9a4c14f46f48ee2e19b5cccca54958b6f5afba25223d284d669f3590c051635aa3c67efd959ff9eda519e4ee45d1fbeadfdebf3ffef164fffdfbc042a5f91e38c91fecc644141d72d1a601d566b5f2b4cd5a88a6683310a1df9b84cdf0c6c658789f0edcd0aec76cd0255b6df61ea3326c3fc35fdf01047ca80766784f717d5c5486f7615806fc017dd3a24734b4ee88e739c53788bfb5d9b9ae15453ad0d241305000dd0d2fac1cee3d0ea2ffe947147ecfb19e3fbbcd1610ee76e399330a58d34614ff256e0608db80d5c34eb4e5d9a778bd725cc6567b3f15d5e9a894791e314a6420b646ebee6e8389e2e720a758e6f9e6666eb3ea77c30c0a89f7d841f43168716b8f576bae2ba1ec9da3bb63ea3f1589b49f98451c2879df2f4a5949b66b177e175e903e187809bc08daf23b19f621521798c8640ea3de0405566eec79b254b3c5fac90fcedfa1f715eb74d8feed82179002aed3211b26ea7faf070cab12aa82fcb87644eb88df1fddbd1788cf2d15540059027f7eb22c611109820402bb0c49ee63384d944bdd1b02be49f0f3a75e22fef0cb1fcc71ce613e88966078a157d8dcb5d7cb2151278a66c5b45e1ac34ed40b7be127a02cf282a8e06d56d54a259bc7f75ed9e0dceb95ad1f7f43b309bf686c3d71ef53b1030287631ab189816170153cbb10197a2cfe6f5bf26e6b0cc6281b6d6a6d451f6b9cd08bde156e9069effe78bb689b096fa501e1b4dd0f969e4a8fdad64004caba1f40316e3b7a4c8043e2bb1b96a64722c33494fb8e92e8d59174c41e1e6abf720f939584d10a63178f21ac840066ab69b0ef47dc784e0f59417e695ec498bab94bfc1182be45b31a1511e37e38a37e0110cc3dc4879f7ce8b44ae83e3536b811497b9b2f6571730f7dd07a5b9be84804bdbd6c13378fa401dc5fe1dcdc809b64fc69adf83f3a6d752be5f861e4017d686ce2a0a3538395181e74016be1fe57d34c6dd2d9d8b39a8de36fcec6bf574e01a71a76e7c6079b0cde650f78a7faf8a10683413c74a714fe64edaf5549dca9ca0d10d87d290bb59ceb5d0923e17996d15134f18dda617bcaaeb1dbace8b3478f0c34bd1ee967d7f0d256c8745bedcdc6d4f7329eb61835a06d80ebd8342f249db4bad9a7e9a4c6f9bfecd27ec04dce3d738e2c95d8bf164565cdaab1d85f4aa12a5e56bd999457aa1797fa5db9454a3b966b54f659e34c4ea7b96005bfce30025923c8f231e42595f897dc40ddc9a76018e62b3c7c91dc6f64fd940899e702c8513c3c3ff2d56f991d0e06e7aecdf018008d7f0617ad606e4de8171765f0e9a674119436d261c4520854ed9a172ea116313e5bc2bc581be92f5e2e1ea98920329d0d856723e0f9a6e2a6272ddbc9a6c70ecdadb8470e5a9032e1db92d673815ddc274657bbeb1a7143683592ca8916facca7f807e4b67a6467448b8b662bb5d9addceea1a73abd39a9052fbcdd29b115a14d663692c5c5e3e47d27ce487a07c26f8d5ad90726d1b235ff076c54efc45cb6efe5e0f30969b270fa75b76d6a90f00ad1ff54dba5d08621dca3ec9576b49f45e2755d2009ca13eb094b3be2f93d937c61c2298db7b846edcba68d1997661f4274b42f02b3fcdc5d3199357b6433ddd53374615a9d4d9e7dc9c45c77a7e00ab997e12590758b507f1166dd7a50e62b84972a8a5f3e2545d6709a6c7aeae5d0ba15c936e183f32aa8b2d1553225157ef95d52633d3c875920f0dc99caace077a632f377f4f42c79487bef4b0871e99ab0e027d7ac178e126dc6cb2089bfa88c5739c823f769d9c342090ec79e70d1184e4d26b15ba3d0458ab9675e6007dce9831171a9549ff1903f5d42f4ecab481a713a87b4435f249e61075a765ae99a16a9aded6e7c5b8199666d5eb7b62ccd798a3a4b594de07e6168e1363bb7f4522394b605d776502ed1e53c0a27a2e45c2077650ba9b22abb160ae2d741f40c25c45c510c73ba83aa66bca00a85d087aa6ba1ba2656e9c006f51a6000290cf1077996f26c945504e4e271b1cc7350f163be1701d1854dc4bea512252b0546259742158d0a631ecb4238c936a2700a9d1c4419dbdaf2b80384a3807c7356ae4b428042e6bc18df3322625f6a8a66bb913468d6874dee44d78686e707f6c82120ffc979fbe0db4d29efb4589422cf38f48521022f02823b3424d28e38dab3d27418ff25dcfa9c5c5c63a27dfbebc25ee722fdbae598a6d60769be8c80d376d783609a12e08c5a4eba46c552cc5a8821a7d800f2fec1a7d7e5fc7cc0a18768cc721220a5b69522b6b6d8faac756d2d416c6d0123c70fc369db4803f01e7f930b1aca022454c067f8895fe1673d5b7a7c3aba3be71c144a1d9edcb1a96bac877d4351fbd1eecac149c97ef6587da4f573107099d58f004dab61d0e22e4d979d6e63864b034e9edbfe3b9fd8bea091f8b15cc86b519e65d5a7e8e83e47476632de460ab2df45edf7894927eea96e7bb8b0b4c059e8cc2027e6279a972719df66474a6477ae2361ac948fa94497d162f3e9e77f97dc43961cec82b03efe77d1fd4b17dd508e57bff7925befd471ef2547f4f33f70d1658a22c28f5fcb726f676745e534e23bfa44a03ae2b62a792fcf86bd5ae1cfd7eb057ba629ecbfac97358b3d2a4daf37e9f3c089768e420ff81c7b176c04e537b85bb3ad9a12f6c543580258a0da281afae1fedc6264d9237ec747e75b5696f2c6ea5d800fda374e7364db1ecdc478998b1f17635eb94ebcdfb1f770cbea68f2422e8b312f33f185bcd52cce92ac0bf091d2d7d0504979634745b5829190f226ec7c1492632c46b2e49518bf782063bc9b272602b6256fa4f4a9bfcf2e1e5752e655b6b8784cef01057de653c6c5e3db8e87b73e8b09ef4e7e5a1b2f6e221dc3eee11065a1c689bd1f344caf2f34537455d5f6e8b3d56a5b627e9e841f3203635962b701d6af6f0954e58e439e2965a4fb4058739f9d24126d2debb61e93d322cf54f5928f66e2652ee0b2c0cf46107eb4190ceceb576834baa6127eadd7fa015caf92557e1055bdfc1b109492e5df70552f7fba1efea9869f8ce4cd0b00c046ba1805675f974660240b5595cb5145b9024d8c78f07ef9c8ce4551e9457c09b1e2afc4aa83ce5d0b9e9590260adaa8250e786b3ad9a4fa1eb3cf6cde2f67f6800136771995367905d873b6cdfae6adcbaeaaeb8195e948cf255d82dfccb25cb0e69327d8c0772c0a510aca3cc85162db3987a2c63107202a51419f57e7db976d2c7fbe7369ddf94d2a90bdf1d8c446d75818d8010fba17857d702e09d853b61bd1e8b364e1f3065a3043f2b38804d335ba9847dea7bd35056740803ed1ad29a84288a70283c7d682d0dbba2ec788f84748b3e21f11a1fe202a8ce78c5305e930b3d10c33525c89152415b0a9c407109f74c0e42426c03b7263100d63f0584dbff80b328643748e5a9aab2bb13284ae8b29c1cbd18c4d6419e745c0f8d6612e0d1c0c69b72194b118334af18449113a3bf51c1b5c293982143f471313a9d90582a024c3b83afc68b43ec9e39b4e274c72f80f8abf8b5f2f819ea3400eb49706598b4d5664fb15f2f3a57314f87d77d30fe9dd43a6a55f790960ee9187c5e5a991b2eae2539a00ed3793d94854879c82a245d96bf0bded88eb07e5ab731dc1db105e0a762dca6c92d978db0580f0d2d3c033725eb6eb1a6f1e5186b1066eaed468adf77e7d37864cfd55ac20975c3806fb7edd821af38a83d7d060ce17833bd60776f1239bf30550bdfe1b258fa19226758c591f2eb5d295a8e599f92a5c161aaaee568df2a7a27ac717af78c59b73be88a91e46b2ab6b77dfbfd70fefdffbf29fc504c40e41d27d0e95cee91206f37bda0b18f6dcfdecb3c68cab59e312ebf5b17f73be584be9aeaffe24a5922999b71eb9ffa8c49871e593979ea26b5e6672a9d800f3020c20577bc58bca5b060787af0f0e0fcefece76d90eeb41ea796fbf97c5b5d0fd33a9582ac938c59b82e1fb8967ec07595216c44fca2c1472ce28b7d007041ccebfa1107fea2bf957b1aae514aae54831f305996b11ad26c0512ae39073ad033684579ebb2657d113d6088f104d5302fc5bd9d6166b6a1c53af767759c760bfa589a7b3ad0907ebaca51318589836e82f932c1747d7a2bccec40dfbb1caf2ac5ad95b3924851b319ce6e4f09615536f66f8b29ac992ed15e35264ecaf5ccd4633ce9afc8a335e5cf32bde62bd549c2ffc68b335d7d39eeb16c3a803f0aa39c56c4e17b54c1ac8c78e4b392df9bc1f3eb68ded8c3e8fc0b6dbf71fcc59492e56f07ccccbaa1f3e9a23d80d5f78458247979decad1c6186ef7ef0d47697bce2b6eab3697ee1b987d87162cf4f677c2ccaa6823f67e2b66a83d367e80f091ff5f2cfbb412d28491be634ef62b953b92c478220b69983ec951cc9f922cbc3c6435b8147d35c4b7358e2582f4551d9a26d0de3e5d1bbe383b7fbef4fcff6ce7e3c6d458ec47335c50e5b2007c544be9553af352c8d51efba3c1765d59caba9fb82e91ae66aba26c10242f26fca23e4125934357b12b7d88dd372d46693924ff521d3be0af0bdc06a3ec20d24df0ded5ad94b3a4264ad9d69defd69ffe46cff6fef4fdfecbdda3ff1ab4f6ad56bbd0200af4ff67e78b77f78e681b0f3c8ab8a8f66549dbadd66d7ca9bea7491895f24cf8a2b33402a9124062ae3a8c1829be6ddb707877f7d302d78ad7d2e3110a82435783ca089b97edb98f8e4a078418f02b50eea58940795e735ae87df0cca421605f6555c837d4f6984eb39297a3db67f2dca1584cb60378295cb82c9252458530b3e12440610ef810e0737d948b02178c2773d386747af8efa2cb31632d82308db9a299667f3ac12e3aede9255a679c652e9bd76beccab6c91d3c90379fd6c39156c5af2c54cf97385a812882c0a41f13a97bcfafaa98f3f938ca28e86afd8533769013438d462753f8e80f1d0f68bae9963ac9c9c629f013bba5c16d94496f3a372cfe42507c558b0dae18067eb42d8166adec6e9c830e646c6be5b07d11c87d893275944fd052a83d754f4b367982438158608b019c9910a359cf3ed4b34e7e12028c0ab1d7af5be1118d4788070e561bb66a00e471a889f1a45b7e52a6bf96327ca3112a7d1b9784c9cc11a4dcdf8b530d2e8d82585a72078718b414290703ace7559f2e97f0a111a4cd79c55900b1618a068f97014fd8873f409380ad24f7e1a9688407e4b1c79fdabf7eea55ce663ddad49365d960218d44a2e4b484d56545d88ef4a9d544ccd20bb157863619ebec6f27dc305a52ebc69575480bf6f5c3c8e5257d5177938b840e3e5b6775f6633ea8a4ab6e126c931f397726943faa41673502e5cbba8b4a8247bc23297ea062eaaf49b74b70239d1740bbba43bf705ba059148e78b351d62f15b5b8e06f22c3db86abef006e4ae4e93d78d91f2db57dd1bcf264c5ee9e0584f8abaf3049e2f2bf9ba3881a0dbded90c5e79d1b94dfcd9524c20d2101ed32056771c0a45bff4932e5d0709e8e0e66c5996a8ddf7ce6ccf4cfc281aa3053017e5549c8889d2ddd9837bc3179e9280c391cbf677cf99f70ec32f2f8293dfbafe417aab16e32e43ac793b6cb1a1ff967223859a77587ce648cc9996007261d361016eb4fc2f9520ef91ea4652be7a3d4477ea1b0c0695ba859fa013d8907620f07ad8fd1e46f2151e8254c5ce89a2db0ca5d11331b90c4d9d4fc4e4bb3767efde620b7405f47d9332a01a38300d632414a0287a8469f1806335aa4ac8fe0e7dcc740f777fb5803eb25fbb5d0c14f0b1f73dd4f8d83283f71413a08bd053cbf698f50492259b2fc17653232e2af9e2ae9236316e2926ca9e902d4dd4c617929dc9e27da7296e9274ad2dac7b77d95a135c36e8c8b33b980339c9385be1f5ec2165a14825fe3b5b6ffc5e0ed0de2c783e56f770b0d21d9cf32b04fc57b1f24c3f1ee47215e53371f6197b4355957c541df26b38313cd84ee373938d547c7840b77f9855849e9d0db9193a1530cf49771a74588ebc60ee70688e4dd23e2314f086e424665ce4e8428348b9b6589fe764fa92825f23327cb2685aa4302f1988ddf8165c6faf9e0791e7f85c23a396ef6a10f81978bed2b5b299da33848048f0bc8f1d9c60577de445db81c38129e59c381aba6399aa1a2d3f340fbe37d107e1c37963cc2bde29871dc044e74aace0a614b1e597ec66637c6f1a8388ee647a5f1e8c9b58a51542079f64b2d05706720ac2b806a186197b938d83d6b3f9c8de6d7b60b1344cf6ae1909eb3bf406c95016a1f70b2028f6ef762bcdf6e9b95b7f7d77c6f507ad803ec418066deac50e31e80e71548cbeac73bba17573a4c35d34f07e8f9dafa84e9b8509d58205d08a16445ce7e36f133b3b727a276cddd766c84e99975b280eb21d31f387f9924795ff3b6ffb6bb6790dfc6cb5b0009cb1a6d95a17b604edab263bed57ec742146d964c56e6602a4f76a26d8448831c80b99b9ddcbb3b1963fb3027f4e32918f51e567e0fc05c230fcda6c4089c68706956db4f0888ee120311799ed709712ca384b528ce7abfc3224f7eb07b7ffa784054a7486cdbaa2afcd68123202ebf5d82165a046bf3bbc7a26dac27d8c8d9770dba8b1c8c6026d8cf0155ea4eb9310af322d99839202aceec69d91596d8a79b75918217c686c046bcf99524ba17a5f7ff3e76f8220c3bf8fb9fa7d249f75b9d43ed10a3d163820059a951d7ef74c0030bcad2dfc0bee6666395c3c8e199721ad5ab6447adff0cbf88bd0fe0e803c84ed995aff03f9dda778869c2e2012e0ef9fed9017d9dc288871959a17772744bcd392fb5fc300be5c7a448b8b385b62dacddee3140ff7495148019edbfc5011555808093753dbc57fa1174bd04d976031ee7f986931f09fbd78ac45f3c07176bd530c418d991abd4ea86fe98bc78a46bcf851895747ef5c2c1af32699dda31be5f4c82126aafd888f5ecb7aface4ef60e4f0fce0e8e0edf9ffe787c7c7472b6ff8aed7a4d6b89539f6f4c5055518c1b2c2b5c8abc58430be91b5e2d4bbcb889f2f2a90a02eb2a45f9be1a0eb0a9d280005c5ebeaf395aeda8aaec666416d998ab468baec4d873b6b3bdbdcdfa6cc7a72ee806dc97365555b6d85700e7597c514031cecffca0b14d11643c84cbd86bdd8531a5123444ab4f39cdc69bb3776fe1a7a26521aeab6e5664157d0f71d7c6c837f07f2a8ead01a5f06a34c36ae2ba8af580ee167dbecc7925929d6e6b410b59235bf0f1d865c2c3b310bcf1b8983b279a4fec9bf88437e2142907f44751c40c3d35a23ac3fc13eb02653c4210adcdf836ca50330248068243b08d62da32b24416851b760dcf89aed88168ec9bd66c22eb91c0b044f563600a542e7869468d9870a18c75179bc1c5404072c9694318a51bbd376d8f52cb34d62f6fa68aed36db6ec58a038b687bca766fa2856cd7c4870f6075c8ee4985011eef9c3342c23a0d78803acd29a3ef8f1e199b41644f18f1c34603817b68326c316b39f12adc93e0faacd763a5e0b03eb8979a010e33104f65c4970a8f3d434c97a04f35a518f17c04586a8397005ab543855c544c2e4bb7352a7623cbabf5c920d7278f473a80947598a1e70d246b81602f42e55951754805dcc9f5e1ac909d65b15462dc11b78b52283d1465338d3e4a1829fe351b5d71a5589e0d4b5e8229fcc8dd7081b3125bc88516635921381c80b3d2b30a3617a964267a2d4ac0df4e77e7dbee0ebecbb391289488129d36472df6747be75bf65a8c45998d24fbbfd9b5cc25340c3ab96cb8ac64a9ec15d1b128e7198c499fbc67a214c3159b96bca8c4b8cd26a5104c4ed868c6cba966c31ad28ae99ecb82c961c5b302677924172b0048691f989293ea86973866b074cf7825c67657c075a3f1a6585353c2c5e353aa72f1b8d5c6d331cf01665600ad98ef70e295cb8a9502e3e800fbce8a51be049a339fc1ac08db81883990e3150056524b6e6de8759bcde5389be8bf0206b9580ef34ccdda6c9c29b2046833a55f02cac148a0274ba6449ed325e32213cab82e985ea231412535b6e6594548037f979b999c8723cab05f936559646a46ca01c9948496b5c8abdf80a244e6b9bcd1c31cc9629ca11da79d4e70d3186a963fb24451c82a1be13cc0cc2cdc94d32735e379ce86827028c06f8447a32b754fc0c03ae339d3ab0e9661346a770b7bf6669f9d1ebd3efb79ef649f1d9cb2e393a39f0e5eedbf62178ff74ed9c1a996af7f3e387b73f4e319fb79efe464eff0ecefece835db3bfc3bfbebc121243a3b3ed93f3d65472700f0e0ddf1db83fd576d7670f8f2ed8faf0e0e7f602f7e3c63874767ecedc1bb032d8a9d1d41b304ee60ff54037cb77ff2f2cddee1d9de8b83b707677f6f03b0d70767871af6eba313b6c78ef74ece0e5efef876ef841dff78727c74bacff60e5fb1c3a3c383c3d72707873fecbfdb3f3cebb283437678c4f67fda3f3c63a76ff6debed5cd6112e11fcfde1c9de8beb29747c77f3f39f8e1cd197b73f4f6d5fec9297bb1cfde1eecbd78bb8fcd1dfe9dbd7cbb77f0aecd5eedbddbfb611f6a1d9dbdd9c771eaa2d853f6f39b7dfd5ab7bb77c8f65eea2d4d0fe9e5d1e1d9c9decbb3363b3b3a39b3d57f3e38dd6fb3bd9383538d9cd72747ef70b01ac547af75b183435df7701f2169f487f3747402cf3f9eee5ba0ecd5fededb83c31f4e7565335c53c198a6e3bd06715bca2bbe715fa102765f595f84824bc9322ee3ac3050ae78e536e39a0482266a8596a5b03075559f29cf1bfbe3a968b459e3acccc6a2800c73afb3524ce46d034d4f52d62e4970d69e2e634f76d94e20d539fce06d068eaabb54a2dc9bea8dd4c8eb49c8e7d9658b7d1fe6a7253961679defd13604f16f8576eaf36c54ca8aabab57622897c5483427851f0cbe2ebdae17eb20ac18c9aa51affc3ea544496b337b5cca79a644b7144ae65a10ec563351a4446396ea1cd89515cd445283488e5c3b62e384fd90413fb295bcdef980bc71b23b24feb86a38b66074208147e41ec6b9f373fd51966bf54ecff81957570aeea53c2a0ca7c079c738931c36269c8d991143e4847172f96a83a3574331ae56c56856ca422e55bed2e298284b31d69086cbcacc1bede3f3acc8e6cb399a152fa452d930d71b0734fc17844c3fe74351ca093b0669a9fb6395e50abe984881ec579337e5239b14f0c93ad5d82f178561516630fa145647cef3fada60fd807042ff2108d84721f8a6d9b52850cf31ccc1a8995bda4189cd8c8bad1f180b46b657ac3e5a1867129bebb836b458a9df45be442fa4cc052f3e325ea81b90acfb61779ec7ee4499b2c967a2e6bc553215701de2ec8ca305623ab8b5658a762b798a772d7afaeba0e1f2f51c157accf4e0b26128d873ce632f4f4fe1c663a925489bb05cfaa82799f91371bd0f953f8650dce75372e0334d277cf120378bc9776ef384dbb35b94aa1d5c4c4993a18f22805abdbfedc4e7d4f34b2fe5594f4b3bfb7db6c35e1dbd637c34120a8576334bb4e1ee5a3589bc2944f9ca1cd5e898f453266eac8a0033c61327a8e56cb70330c64fbee3024ec3730de2dc3c5eb2be9ff1dbcca2efd28657ca87722cb454a9dfcca4aacc747ee644e6a999b48bc37ec63e24e6f1d8762e526cc553863a4a4dc36fcedebdad65cca7a2cfe23dd980f090f0e1837dab11b10975980a0e6e06a1fe175d03f7441da5b95b8b41cc9b87788c70d8ebd168d8508e576d36b0c50778ceaff89560237d22aaa48605831bc9b2d43c62802d9fc9c500d5b4181f15f6e3b01d8b6daba4d0edf9fa1c759355a3597d463de5971234b57dffcd8ba3577f376f6a931aae36dba6a9fb6fa63b6b01c4ddecf51849a218d075a92cdb6783ceed004e7583ce6a80db021ec9b862377036b597b629fe846eb91bd9968bd92daf4509d99e77d3c0baa640adc6dfeeacf2b75a9dbfdf59e7ef9ecd54afc99795fc80c4f14197c8f9aad5eb5642554ddbf1271e74f7fb6f3557d868dd7a2b3726ed34b3686d5abe4ec55300f79b446f2579bd135b8c3fb0ac52229f741fb4c0c91f9996ef07e3b5ee6077a2b66824a895413d152ecea12e95637000d04664aaf560fe7a62da01acd95643f360d799ad2df7d02dfdba682e9ffcd2775f7c79385307fb3b3bb10cfce8519336bf77a707c56259bd03bcbe74299b2c13313fdec9b130c9a601e8760cb4f7eef4609fed6c1315264e7b61048257a212e53c2b843202a5518c668a1d1495280b51b1fddb452e4b517ecafc1f52c80d23c5df253dea71d505c583fd2601f0764503526f863b350106b1eef6c15a8ded648deddace49d307deec5460ed42a3b4eeffba4d32e84062191cc1f7e42679affdccfcd8afb32bb047957e03409d07fb4d8deae7e19e48191b5dcedc3b044c1982b51b9ffffac307978fb8d763a757d982cdb2f1d8215f916e7f2cad3f192f02d8172e3e4bd8e4ee6e3cb8ad2ddb8d42dc1a8c9c66c3dcdde6b1b8e306e7de1812958371d5716c84c010f8d656f06c450b6fcb7a64eb6a5c05c224c817f5d79b644cf67c9db81f1209ebdf8b7e7a3d16ce2785c0c7ccce5a1ecba512aa62676fdaecec95deacce40b9991520e7108c428668c9145b9442c161e280cd7825501dfd8b1c76bb5d8399f3c6d91b50c5bd82ff6bb88d4bab194be2b50507a7ce0e1d3dd3128d5f1382e2e1c518dd8b3754c5ab6c544370bc507d28ad848810914ba881ca14c2d23b0bcf0a51266ece3d9a8a2553df4abc4e3171cf9d12c967a1099ad2a4b6861f752759a90c85bc9c65f918b1e544a480ffbece8a318939525628e1340d9d61400779a3d98afedcfa4d98b26e731d47b69d4a09255256feeda041b27f4a7b14bbcb3a1ab1d5bdf229f2d045d6632ddcb346723ec76d5a7fab6ea43e705f6763310630ea0bed5f3b771578ba0e9fd4c18d1bdd242bc62fa15c8abe76ac6be953773e3cd33c010f389962851063bc0de3608021ca5296ca701a260b11a90d14cbc047d964b498c812ae2c4bc1952ce2ed15a409fbe03431dedba7c1832df2291b73afc7de88122229ccf539572de99cab056aae208a282fab8bc7fe803094d64882f1a25e8f468bfaeae89ddd944b8cb3620702d6c1a5301bc13171bba643f716d344da7d75f4f24708d2717c440613af8fdebe3dfaf9e0f007ab20425fe95d6ac5ee353bac6fa7cf9615905f202af9d495dc7182c60fc212392f464255b2842b6a608dd67e85175351b7253ad1af492b0e45ba4a337e5e564de8adb5deb01fc1daa218db0fa0f982d6f7a871cb96d92e555bf3dd0de185ac66b81a21d65906c12b983de53b866d51a699c8ba669d1cf37463b90f1f704aba842da507d68aae9ae2ad660db04438bbf5a36609aff778eb58d74eb40ebc858bf8cb94419fdd27dac03e4852844c364463844c0a9467f8af79dd7a16631d62e0cda4aa49d377b0275bcfe353388e202cc1fd80b5e38e3e6d619fc2d89871443a52b6610caed49669d801be040c362bb900c5502e2655eb8b1e74ea2a71687150c9c5400b8203dde4604db4473e974b3c8de1a8c4982db25b91abb54ac4848404ededba545126a2cbf70c0440fbfe7ce71256914b6ef43cfcd8678d4a2e1a9ebfe05263e314e16333e01e261718fdce281f21001e3ebd1593ca995e7eb2f07697b80fe683d53c5fafd74f6c3ae6729314c6fbb5f34e08a256f0c30768f35940e471a9738bb3cb84bc23528588ced18c603927c312f0a70af63d9ff2156b6ac2228b9a450bd5bf9c881e94c3a821fb14cd88d3888d2ad661270e1a5bc925ea5d415ba23785a026d8b246eb8475c008c73c61a082997017c9a5e0e3fada0ebb64b53016331da6a52c2d0d964b081ae3772dc05f02aa8944178d148256ca7136c9207d5880c440ed835641b4244b4c98565f98a613c9c5f9345c9c4f372dcea77a719a038cbba5a7e5477aeb803fb47199baaddd2dcf35c5353979e52d1a76dd389eeb33a5b3931e555dcd579fec7a5df9ca56748586b2aae4fcee7240d0b6147435550c6db8ee28474ad35115adaf37e02c83b674959ee02188660aeff03ffde84564faf2f4144edbafc428e7688df0113dd11469e42042a49ce0454fea603e60b258770ea456cc4ec36f33c53a6c708b3bcd6a1012b7d965cc1091becd13383004fba706570f5f3115d50bac729afd533471306d281c6d427b9ad075978061dfc21e01fb018344ea0bb72fe8d22f684fd9c3e258f0396b9c4012085de505d04d23f4410becf27557ce1b38a206b85c68784f58e3e76c5ccd1a972db000bfa3c20bbf424d47a1a7498f5b0fac4d97747a1768dbeb7798c5505bff8e57b3ee9cdf3675f9f3069e08757b1aca258239a71dd37bade19e374679268aaaf6ba06045fd780787a4d18fa41513593102c720e504a7583396fcc7939cd0a5db4e96614cd826192cca60fb3d6fa2c5034cb1a1a4ebd06d7c753496d2a7e867b093d21ca2a527c3f31395ef967237b79e8c90b1bcfa5740872fdf715c5a84d0bad0134d0c84b924494190cb16f09c88c791311d1bddf8d2646af2612e7a68a354b27705d7ac9f31c6d507c03c00c82028f441b820b52ac7e5fd36e4b30f3434e82b2560c73b1c7ce560b61e38ff1a29068e2c438f6441fe63df39fc74ec6b7368b145986d259d6acc2ec0bdc1f9da35bb3e2e5545426c585e95aca401143195883c4274fa2007f63a14665b6d0e7ee5d8a63e005f5735fbba258ce4549f1b4d3ef3f7c88ccd6bc622359406836021058c6e919b8780cb2cac5637d9471f55a3e8c9b32ab52f551a2e906585a591c7900aec4ca7f6e45269317298b3f8f0800df95a47493a82d3e0e6680224b5099567de23c682e4f800fd78fc210b4b00954d8995058f78a39a348320735ff9163bb87bd801ce5f017882cde6671b46908905d6889d1a2203d190e84477d90191483fb9b978e9abc74e70c636859fa893e19b2709e48ce023438a3cbe12fe757627519c64d0b75f7c35f9ef92bd4ba36ef9a8171a5b26901b46e1184a4960a8ab783ab309685c39508e201043ef6c5665c87d1ca268463696f29ebc9a00e06792a8e6e0a3307688087356b590c18c33118fc6031784a843c8cb186752de2acfe225051e056acda6c2a0a51a2230c93cb6ab1ac98cae6590ea1f450f65a16e3ac98be04a9e0e4a1273aa79e30471d6a3ad24898afae1996675782fa945047b8827407a4421128080660876b1444b835d26b12fced236c7f44d178767045e1c0619f708fbd30fe76352bc921218fa14c4547bac9e7cbf9a9736efa64e9b59cc0627d76130a9e12e32efdfad1e959c1c262679bbd3ef85b9f1de7822bd1a6bb63aeaeda81da00d4ff546f44e184d1f4f8d5d13b9bc17b9495a3e51cb77b45d78fe6f2012f104ab128e5783982101b59817d3051373008fd9c6c780ef677763480aa5c854a5894a40215ebc8d7c0a451d20a02ebdeffdc1bd6b8dfd9d774aa76b40dbfd6cfaae1f7c499372c9038c59a1d380af1fa2014214362238eb67c2df6ab773f6f3318106c3d88be1b0f2db94a2efa1605a144eaf5bc53ab67045e7ffc1d0be8c28b9cdfeb399d020e7fc829f6356887f42fe5ce8aff84681d1b2c4dd9f3f86c90d4e8e96305996aa365f018b2e04003c8747cc3535cb83f9bd7883b2ce68e1430640b831e6b40ded8f704050b7aba9c992cb37f9e5a54c46624d88b0e0b5bbf1665b5be0e35da614163bd9e5e89bc60b3d54256335165239e7b939029528c88711baee596aa6243ba99f3727f0cf00c3d2098e602af727795d6198fe7b0652f443991e51cce1578f7a88ce4148dfec3877068a16c0067f8fb986ad28a88807776d769341ab796058498dd5065d57001d07d0ad175c2869f058588523abb6153691b4b6f9963f5e4d118ef5874a91332493c937be530ab4a5eaec0b4d0462ea1bb696f8b81a4ebe652f437d2577a7681b80d78f1fff4324697f1354bdc9dce691027c815d3dcd08fa6e14731dc5869e119b1b85dc3da47c5c6ae7e1bb6ca9dc4193782cbe84c2e7e266e54535775c3227155bd71dc55d796697912041a0c28763313a5f0bc1020de982607b7feb369214bc10a3145535752a867d6d661c4f39159cc21296d6dd1ec7a7122cc4cc016bbeb9465e1177b311d54c971134fd581adc80b52e09be7d19c78b3fdabb7d9f934059deac4bdec4413d5f637d0a03a74b053eb72279eae70630d40f8f2afd954830291d8cbac3c8cba36148db6135f4804da7664706af6612c007af0d848ced89600fb1f0a2d4f2f2903953572a14d608c46d04c16f98ac982c1ba1e0a8c6e00f5c1ae477f0dac398662c6af71cfeff5d8389b80b172954348bcc2760ebce7178b9cd2a7655597f28cb9cf9ec3364103db616913e945a36b9beb628c9b8d6ba29095b5bf7b447cab4ec9704de261bcbefcec573f5d4c3015ebeae8cf6e6bf14f3f9ddd9869745c2f9e85e58d14f6802a48adbb35eed2f1fa1d5529cd5e76471dacd5ebb13d08efede18e17631f2d96605267139435566008a5276e1e76c69f9075630c66201a9617ddc44dfca390a93d371b95b537f1f70a2d662e9c6d6eb08d6c6d05cf6ea77b54b75b749c2bbc6eb487e9c51d56972a2526fc94899b852cd7880b952f2f24c218dd7a1df9423607b198f0e06b7d3cd9e0187054c8ecef16885cec1cd2e2870703bbc9e8cffe79a06d9c0321e2963d2278128d3d18a460a0641e02714784edd69a3bde4721f69f7b2759e83feb13cfaf1d79efa8690fc00421dc3add7111f64ad7a34e8475d2cd442fed1a0cb64caf7b3530a40d4ac279eb8e9bb473a6364b6f7f7cb64198c6f1d51447092f66a74a41d108c2b05afb2c4e2f9dc5e76f605de4ac4c97aa92f3979e5de0665f6776f13853af75079f43f6eed8d1597f79b0ddf5271beea48db135b0bb3d866b36ea80f61a6c179b2b14fec16679778d47ab1dd323cf60f95e16e40685a1a1f31a8b66b457754e38bc08e5a019dc9341982a7d58f67dbb8981fec65e3ad8c1a003d4d932969c92a602affd8d72834bcfef6dd7ecdb2c934dba67d60527d29ae3e35d16ccc6f8d25b22016428472e3b22dfe88c217213cc4c63ddd077210be1c89b1a4ab4117a53eb016de87ac8eb4c0801149297c59843be740814a5bcfc3346d2fa3c4d39fa4eaeff6e9d148322c68e8562f9adafee06b06f4dcfcc2f38b18401a65df1b4a95928f475d8019023f17af37a5e77b0b077295296e3ac8014fa44bb6193a9cb00f8d84444b51d426c30c6767d940fd3e3fc3114d0feb84940fb632ca06d7287737a094b46bbec57941ab6dbb4f16f33a7808d1cd062197b233741046989658d95b1c1e006075b4f1bf20643515e93706cbdb62055538daa60719ab26e8106037f98a81d3a630598485ddeba1efba7d621d7342ef15e47f874cf5548792c9e29da1b31a4a777ebbe66ecfe19c6cfc45703b8d9433c9c0a77791b82e96e72ee4ab68a737f2f8b607793eb920fae19348aeb1b87fb8086e35b9e1aac5a2f627f839a76ebee034fd8489bdd417696d80ecc2e3c018d0e6806e1fccd9dae862c9238c5f7b9cf54e2e58d3e5f1b212a70278cac73de87773c3866ffd227857d17b0c11d102896825795346a4159730a8c8b9a3b98fac4992bc3405b53574c3c4bd42445cdaee9e1131f48aa82b97f0cd536090d47aa724958c0213e0980ac21cf5e0f05ac3cf794651e9f516da3f883504f53091202abb145a7996091f944afc7f6c663b3cd0197722185cd2f1b3c16af0d8ef1357af2bb207b7e94e2064a0f78819040600ce4b9addd37bfb0ac6dba3ee1f781a18ba64058e5d97d809456491083719abefbc0a1d204c8931e1dc494ee68af141c42ca7b12875d26a598049a6b7fb5e96fc13524358795bf72579481706a52db1bd1cdcac7408203beace40083c7e2010a1d43dd0b4803329725ca67fc9a673958cc41a6e687850ca99bd18c79c5c9a21a7e927f84b1e719b3e18a2d17635e09e6b791b0c759608c9a0e7b4726ecca197801e6b5144ea5d6489a512f4c70ad7c65cce2c7b1b849e6a37bcb4a1e1b84352dea40f03c41487549749300ea966c42f4fc26143dbfd9247a7e73e969a3c094d074ce4571d71460e3b8c7a7375b3e8e52108b699f2c763ff32d2b46958a3465967792a6ca5bada975d23738b7174e3e9b217e4975c87e6a430bce48036196c1fe665af42a389d996bc6185f3d782409c6647b822fc286f06c1037636ad80bb48079df7b30be1e10ad0bcb4a8c352ff32c19afc44a81238f6a75e77ce145a5bc12ab98b4e2d4128c5d89555fffcf0c0b09024c063d2b4f5e0adeb78cd415695d04769aadaeeea2d705de66c3b80fc3ae86c63a8cc30faae90d7392e59528dd40bd6177f15b9474e56970b1e5f3f5a7d13447acfda9e3ed5e0711c0f75628f6ed69b6b60c84f8fb1b0729188d3177b7cc0a0e8cde081d97d966cfc34fe7db977a7e59dfc701bdf49ab0f1c2b4bc61998d5ae459d56c741aadf39dcb70f7aaf7e90918a61294e7acd16998541ff0a6cf1a8da49da211e3690bab459efa1c273e55f14aa4025f19750c85bba28794bf515d3ff3254264c5c063754bf64075cb5e613661ba9683dc60368c84f2a3e70f837b64d7e74de1b9f078a5c0125d2436c687a961be0ef7c2af37ed855f5f8641899cabfed17f02154addf37dd311d4db5aeb43489c416b6b05667459096319987401a78324da143e3106025fd6f3bb468075ea431ea8e53762770bebb2908a80a54715d82f0672f683e3985a6ba43b4299ba6bcbdbcd560c783d99f2a9a3322fdcb9c2015ddd61e67027d493e06a346dca4a2243ca6cf2095b45f7834943c927ecd6480a9e03a9f292fed4a870016cc93f7204c488111a3e85e06c745d0338a238f37d92678b851887e562aaa25e26c47c8fbc665ccd405d8ba258a3245f359234f182b86d254230b26ea39cdb1892075f803ab78396027e377b1ac60700f801ab7ca8e4a237f533edcc79359a7921c40998eedd397dbb74c2c15dfba87fddf0699be7c26d472f4f4fdda3867eeced725351990de5aedb8fbbb7db5a404ada796a9bae19eec337dd1a81b18e7fc58609463db2de78fac4965d277fa38df8d86fa67e543bb2663111792f3c913129d76d5f863178089310ae2b3045c70fce88d463d8b4993e0b7559442eedfa465049c8de633062c30c78ed1c59dd6ec8e35c2f929682dee7ba1d44afc7c66221d02966b8f229d1d39b080c40584923e2b24cf791faa3720d355ff9667a4e25f74696d93f2187846121c83b5cc83a6f7e304c9d8b39c0b382a28d1840cf29dc8861416e731323a98f7bab7a85dcf89c57becff95c70b52c0d2178c567c27a9c033e136dbc0bea3ebaa332109d3f85e76660976cb746b0dec727898faee54bd6634f59c79be0dad7673565099aa0f9b87286b841178332c97e4625828ea4307599b8b87a689bc9fd2b1c4e2acc4ad04cbc51bccbe6d908cd31065af21d90824e33bfbdb2e4ab4fdcb4a1ee47c6cb32faa285bee815faf706ec1496079325ebeca482c6357959b6d15cc299502c956005b279880c954d4c1607d8878014a05b9e23a42e18efafbc2ce17d13e147a1a9742b033c510f807141962b0cadc2e7028d77335942580bc0a83715081ad40d081cd96d224e2d00242ce036043bbee6549f10cae6f79a17c87f8f93a3e1856ec1f529c274f9f79d2728bd6eb2b065273b8d96652276d9b28444049798b2d17afa3a6d533ccd7a413c6103e2d603ddb7816d6e40463741ef917557a3199c400da9062ed3f118e4f09764b7c2b4897aa466d780066a42df5b2917ac2ae5723a038ac9334c9b30b7aa74306159a2fd0a782c946351621228c1473322b53905db9fe933e43843f9ded3a87f5280715ddfbf2e083e1255da8e26c533f0b6eeb0a305f951d9a03c855e77e66a5f559e9c6ba533aff5986ecb6561ef1a9ab6076de8641b1af54e06f6fb993c5916fa000a2ee091b2c221bcef7e77559e8d4473bbedad14afb9861e45831a34a253d85c7722cb7d3e9a79646e0a047106cccbf38629d8b86c05b797a944866359750ae95f59836fbd92b9e8def0b26836060670d7c01da08bdca214230e4e72b06c5cb162f0a8113863924648632ed54b7daef56aaf4dba58efab3feeae2874d1317a29b8e435452bc40248a5560701ccdc1d99c8834fcc217be17c918b4a90fff249100bcb40f31c3e8662224b814bca52a98189613db5a8598aeb4c2ef19a782c85f14c267873a114deda5533a1848bd805ff347576cd553509adb1574fa28c332d093eba53d446184ed5e55df90363d86593a2892bc6926470ad1d8585d1456b379c7041483960ccd992363f73c04111dc1ca10a7163a70cf2482e16f9ca18c59902a03de97e372c59ef7bf8700cc3600393540bdb1d40d2073658d29371bb909394b3e6dd2c30663308b7e9f6c26c620e1bb0865455ca955e42e8b84e6d8211e7645982850182305ba4a6b42ea85fbb997a65ea477b4b7cdd479365980545b4e903d9d2d109b54d7df6abb98fe265296f4e6b6f2b4a7ee9bf24150c99c9d14b9aa13e785f07a72f73a0aa6bce5d5c868d845a53473ba4a00946d7100e3c78ea5678a6937cd7501ba8875bf5fef1652599771fac2abdbcddb1824cdfa36db24d50dc6e600ff9949f0b36d7818503e2059afe525534399d20f7906536cd0a9e1ffb97fc5785bc4175027db5521b22ce3fef27afb94344b831a6d1fe10acba9d4f9345b77665bcb9b897ab9a908158c78c3f26d7573c05831a92068e866af8db8d70446de14b9f26d8ee0682a9d38ba7485847c83ecb0e75390182d7cd42d8ef96dff1b005dbd58d43d08777f41fd067773e54325f56a2e14646426320a11966120850d04624457973e8ccfe2da3a58ccf79ce06b2c0bc8203781e72483f62aaa195952c840aab18f6ed570163f7804122e0b117acabfe318c1e1560cbf4ac69c6139fe5a3d2d829bf74b4d951e84563cd03cb38f0b2b17243a618c9330f93bb6b5e30757717336dfb08df1747cd4f2fe9156ddd9e402be722ba360f6ecd0bf498018327fddbbb3237121a7da5c7f0cedc93e20a6325e9776b83ea9bc42bbc2eb5c733e73ea2e17dee6d8481d51cf1b9c85f7225e26c47ae28f52451479fa58fb91a71786a7b0a4952ac5f8b622c4b82d14a68824fcdf08cff84c64d334a28088a54ec06e4b4c5fd9935e6aad1668d9fc5f02a03ede43bf94ffde78812dbdab0c794116c612346cd78b95735b75bdd4afea80be8de37e1deca14c1e3ce8e59fce91074d8a3b5b1afb000348c255d083ac8ec2b4d403f2af89c351ad007787ae2f5bd6f3be6197447598621426217e49f73027d196715ae2b15a86464c4e9923ae04df5c7309d13486bcadb281e2e5092c86824cab438e8589ae1a472399a81ad2af89d67133600a919e4bb418aeb5c5807e0985dc4bcbee120355a21a7a54196622eafc59e111d9b8ddb8eddc4ec41d1af80c2bbb787351a6b4b6100850d05285cc28612c6167843116b9cbca18cde9f5ece2837c1fa72e76b57afeffd74e96090200f80e83cbc7f2d8aea6da62a51e8edd7db6a11d7be2c924df47e533271bbc8b35156e52bc6d515798b81f02a7281a72e4b5ee69e4442a81b38de2360774282b45b747e35ccd6cbbd18ec8c58f7a820024d1289f31da4e2905bc6978b5a35472ffd71dd4640c6025c2939ca609f37a7ea3bdd4bd3260e68005fdb4fad697cc26021b04f5867b7e06bfbc20acfd95a0307d6a701d66c943904163893becf49e89cdf66e21afe18d9a91d38e4fb8aaf4cbdc070b2698f7de78c62f70d0cfd8799ef74d5e761d54d03f20b023c84d5e5e37140efcd5af77f650bae54764d211f9dde818257e89e58a24b2328f6d2a1b63d8fd63bd1e6c83378df5d2cd5cc84848ca9f55454cb8571fc04f8a0bf85656dc544b2a1f62f2a89353e4c255b66d76407e713b0d25d88188a77e6a0358c2145459b3a0306c37efe56b0320a07a0f9091229e0043629af36dbf56101f2dc5a723aa7faf4374a68add1aec3dc400abd1e23dfff7a2f83e4b52eea1abc752912621209f462ebe82a00d2366e63e9bee3ab0451f91f5c7f8267af1c8c4fed5b59db13054cc2065d2e26c503cae9c6c7638618ee290f61a86bc3b43fa518f17cb4cc7965d46e69cd9d55ec40049b6a2656109fa62ab3e95494f739dac4c48ad249bcfd79819b3d8128c043e208a85198a0fd4dda8d36aba99a427d62fad877829bf2bf667de36eba7e81c360fca50c7d2def5ed1c9d59a686dd382f5562735aceebf4813eb2571591204e3b59b4ab29feb17672b34c74696272a6b599c646f36df65a2a3fa3876b961714775e335ede230dc674997fe9c2656f58dc4e0a66655a7e970dd22d6cdf05c4902431f524a1ac68bd55c9602ef1e97452e94829c25a8d531ba21b24598f362c9f37cf50987a4b494ecd8c49d5c62c48b91c8f78a6c0eb74daf4b2d9faf5def115749aeb8245bc1b597e4196722cf21efaf49c991158b25845fe10cfdf93ee53ef6ab8f042795e97793d2e870391765366a16a15aa8c093b2f1603de4874dcf84b568b5e8362e2bb24a34ebd6cca724adc3c9c898bfe1783fc17271bd2cef4541a824de1805edaef34cf3f296e02b3c45707bcbeedd24ea95448989365af7893c69a7aa28308672d15eb075c2b8efa5431f12dc4ef72750a62c8b2c38dbf67ab0c3c3ebcc9a3a2ec165b5c049869190232bede71399e7f206777b6692b2de504e066301d63636b1ceee8dec62131670d04f97a3d55118652801d308ffead60c6471db08ef96cda90a4fd76452c17c30ec09d45ea33a3434e8eeb6fe05841834fe9f831aadc2c6a348d7cd04557a1fef43994876bb1e4c9c2d4f5587453495c086e751839d74af9f4db43e8ae1b5d6f8731b10b17a0a3a5abbc60e48e62f368d474809ef4253964f73998df6c14da0bae4dfd0616f890290a17974d03154e0c84d262dafd7b4e011a66bc5befc422d7d290760b0c5f3101b53b55355e2258d957a79b1727a7aca48cdb2820d3c2c0f369b6b9b8bdf0cf552ec86afd88dd09284b52a615f97104caa5af9d659e331053433de2a10d693a0bd108cdff052b4bd1a23b9ccc760b8509a0b686f1a8c411299271a7b13829767857118ca9485f908244dbb01c1a08d9940782b493b8f93833763ce51cf3db107f2a529a9256cae3082aa478761102ceabac7ad3674df63516134f0b29437fb2ec49d4122d897384b08084e06f138032f26e05508df87b3b515b04757e094b66fbc00b15c2d9a001f96e9be573b61f39bb2af31bb9ba773f796afb159ba16e5aa023b53e0912e5c2d11db104dedd0c44602cd9a88b3c134dab7851063f83614cc1e2bc694d04357005023594268fff0dafc1e379e699bc174202de2b775731373fe0e5c5aee8acf653d58344ca0cc38cc5002429dcfd1387e513e574bb3aaa3e2ade463ffc86e48da6a250c3a8e02659d636ff732b9419fb2c8df266d70b3ceffd376e9bfa9710ddc4ede655b9330ab4978e8ac47dddd1634f7339e31974ebe84145cbdf97e429ed70e6cdd033381036f17276ec18b04afa0da5a2095cb2a34e7331c1fb7c346c5a64b5ef2a212c272002f72920a372383a95f2dbc7e9acad698b3d4ac10a9f27d65ba2f1509e50eb1ce65779d698e7b023aa40e3b98046e63f8119cdb7401cd702ac6f37c834c84f86b285f478bc00884ae8b2a87996015cfd1fa31bb15796721ca09f267ac9a15d32e3ba81a8aa94a2fbc42566c677bfbdf19156cb3e1526fd9006e2a25f043bd89f042f75913475690352572f957991a2d95d2dd9a8952f4d9acaa16aadfeb4db36ab61c764772de7b2dfef953c955c57b0bc3357b8b659ef7feb4f38dedfc5b79c35e1d1f30352a852814c30d8c1bd2c59d68982fcb12eebff15e5313f16499e794729a354ff984971900e48add883c8710eed974e6036f756db3afb3524ce42d181f687e5448442b4096a58f39603d6389b1d5d1bd0cfaa325327dd80678b3a829d7d25191af30a1862c2a9e7b7cc864f5eee1453649e1181c1c37609bf2a89bb8be3c413230bc1ded793d2af4ee03dfeb8f7f7011d77cd3336be7638ddc82d25d4fce433b0a67d31916b45f9ca73329542192343c5830935c42aa42f8040f5e8080429e504d3b5e7ad5bc8edd31ae519e0a02da503f4c6e0968d9edc3e87ae8e5d78001868589606ffccc1378b1fa93961e473c073f41722d26bd89d39244067fb1b360a67ef2027684855d88a04ea356519f93a0a3c7bccc20bb5f34d87f674fe176d71fd3bf93731d0610aa6647e3b11d6cba3668762210f821cefb03247d260f8a4a4c81761ef96cf0b99dc9be8f39885aeb30f0e1436d5ccf8974facc90864b1ba441dcabc592ee272f6af94dd1513c318066801fd48dba8e6e6db1b02da2120af2b3c3fafe9b969f93aad6714361955cb4a290456bcb628156184829350a63bfa34bd4f3ab66ca303fb8ed2fe58d12a51e5c8fdef7b26e2554d52cf87536e5952cbb4b25cabda99537fe33a953fea531c89c4ac20a771ed7d5083612cfade57c2befed2a6242116b26de5bbb6b031d402ea67cb472263c857736b97eead62996fb61b1dc1b8d442e102978e0304e6fe1c1dbb311dbe0ba14d99776add1a76f576682424dc3d6adafefa6be053165dc054fe0e3f4f3dec9e1c1e10f7d36885a18108a99c6176ca7037fca3cd339b847333211640b33f6a759c126cb6a590abd22151099132b7f51c657ca46d38ebac07637a23e0e99b3a9ac139ceb88bc484724b6016dc8e821a55b6925c3196f4c34150439f52c348c823b0cde623da78dfc1f59b9c73b7710123629de503898b1b8ce46e2580b7f271a11ec3bf614c2a45bde1664a2a004efb7489f26e687e79f3fb4e9dac324ef2bac51da8cdfd63f1f5f05baa878fe33058a304d7b55b9140320351708527f36b466cec7faa405567b502ce795f87a3c082f1c9cd223d0dfdc98839c3ea0cf396c2039c49fc4fb32cfaa9acc9b89a8c383b667793cf67208dfcbf4d121a390376d960b7dde00152a67aa120b4657c963964b79a50f4098724f8e051be552897cc59a37d5e4798bc0d0196a248bca0b5043039eea7d8b4948f58dc99de0ca079123c66da78a9df3159bf1c5026ec1791500d1d436cf14485f63df8bccf8a351e3044a5e8b7282176a10572215ed0cf20398540030c2452987b99843e8e14529af41417223edd6d5bc05acac5a6dbaf2e1798ea61ae44ca199de728ea7212f083c058a427547d721edc63fc25b1d9da698055c02d4bbdd361a6f25cc1006b703245db918f81e963efe59256f783956800b0d5d3318c1c74c4eccb2a814c9355db71f815d2fc6ebb6bb229a037b41bc2171362e5c6fd1b6bc30e260d710b0bd4cb1ef66d53cff3e582930592a8a2a23a85b66aef1d8c69a986ec6b82cdae4922d77095b8c61aba88380ec3f1e1de018fc0ea662487b776388834e5023c8c2f924ca8eb5e6822c01c78ba9b216ca45dd4d0600c5e19c3ffad3f3c2e790815ff303064e24911af9cf519ce7d28bd6188f3b05c6c59a5907a43e6c82530b2dedf2bd449c5e9f9622a6e92e07cc7d76f81decc43d2edf6cb0278cd2073516b76da69f312b113c6eb7cced390184b5716993e505ef5fd4df4756ee8e6da743f4cb6a7623ca4c89b6d992d0ea8217635e8e912bb4d9407758ff4542c21d6e00d81d44372d74f02df4e1067342d517377bce3afa10b5f32cae41c9a06a0417d78871a311f8956b750da600ed5f794d6dc01cf6fa096be00c018c281885bbd1322ccfbb03b34251a0d1ed474a808bd0f3166d96f06a6ee041339626f175d785f12e0c1a0ed29afb4012376c2cb8a68eea9a14b2d1c522abdd75c51583b30d944bdf8fdd7135767f6f3cf4cf52989a9917d629d177303fa8d0a24a191864d5ed3bd7803d23de2a7e9277df9ac019ac538ffa910ca6518a7f2c85aab2620a4cb4832e7672e27db010360110e3747d6fb80f76473c11ff586665e88f18f6b71d361fa487b7dda7a368f2f079a7af62e88a688fa26137ea917933653acf76d9a3475e6fb6b6d67b4edeff281c62dd83e9c7bcb0ef20bc0bfbceeb35be0afb4dae11a6e3015ade07f86c0c1a10962b209d27fab5c75f1d014415a8d37ef9e0eced2a3e618d60b19406a7c315f048bf5761590a69a317f18d2cafda365b77254de2489655e6fa2a012b3883dba4660637bfabf5cf7fe280f9c05dd76aa90225fe1fa0ac6725a21f2d1b9505bb12627126a70238693c811e7dd6b8c35a1d5303dad0fba90fbb514f69863b4110202330db706a3591fb0102d29622fa4c5a42747c381b9b1cbf1c82652a918b51254b3320723d0d9b836c4200c3c9b25187525a97ee3f96a25c9d520b4dbf4690b826d1677dee98a0cf09c61d891dfd9df4fd28805b7383b5c84c0ac0d83a9837863dd06d720603b038b2a9b6311f9e39625b4874e21d831b2b04a684dc79590e51ebf401d10b5ae90d20893b9bb536189e37be75fa41286f0863801d1e8a643fa8908b85b41e6b8e12176bc354d4c275fe8baee41e788595babd7247f802ee0e2ca0cda128b3b178c91759c5f3ec9fb0d18435cf4809f7360c9289b131a3cadd4abe9537c681dd16e679656369faa0d3e134e52259d89c427ced5e9dcd9c66ff14b510aa01359ee7a2706159890391181cf24f1b7d70ceaff48ee6824de1bc833d77654c00dd34c31db42820741cdd80678526fd5fdc06074d1b1d925c400463c0a6e16916dc39e2e39275ea03fd8eba02872517962c7149812558679785cff76bc8dbc67b3dd2abd0b578bacf8aa28ed67afcbd699f1abb479f9f7817a1eb017722c0aec79f11ddeb22b4ae1a89a2027bbad0a40da3e6e3b7545fdd1b4d7a146bb536000cb24a2dbef482df68303f81c5365a56e87728ce8c138171343df1abc87050d31f1f8de4b27029d021c49ade313022ef0c92224ca4cb666447a648e59f4e30baf9ea029fdf412f68597b9e2c23a5ce1bd845735cf7b8c9650ce60588336bc0608af804182d89829eaae1017448dd3553d7d9b46eea03e9d43ae5a66f51a2a35db03fc3297728f41492425b0b0c7acbcca64bb95468d9ed763a0dcbefa64df88d3fb2822e9291aaea14d576b55b6d97fcbb6e50bb1b547d565b332865eeb266421665bb0c5407a0f6b634912888bd697bc6264dd7bdd6fd20d03ed2668d46ab9d928cefa19dd81062dfa553f9ad82edbb26d644b7a985dd0f6bac09c06f6d205c8e18cf2bcfcb3ea3656251d4135b37c001395036266a62a15a5d0db076ccb3556b71558dafc368241641d831b06b06eb32658cad681e7cc3533c44f81aa29fc290f28af152f4e14b8752b999874a2eec6f54839a27d2909a47509c5a13b17d3e9a793332e205f24cee510c2c6ebcf8cf54659bef00ce2cdc8ec010c65f51c7a9367499659a0b2d4aa19122b8ca30a2cc4a2e35dce2cac693e518ea0624864aa2a1097a929659558982e5bc982ef954a82e7b63cd4ff2156be26d11688169c0ad361b6017418fa641c267d34f5018e8060284935406200155be66390459c98583a85fb8eb2632a49773931540dcf2f902f4a5de0456720158634d7745e659f7a210c2f36c5a88712b985cc23d54c4626155e85a54d168ca751dfcdda6edc12ba469caeb136dd12e2920a601741b691b9b01e23167f5e1cab312b6c8f88baa78958df0b73ed51aa524be11c5d2290d0d07e16359e44164716f2d6cf2eb0dce45e0390d69ef106dfacc0149f0e8af1e2f7922ba02e4964853648f29ae807558c4f75408111b3e79ef6d6d4d5aa6943907c13b2c81423c65562833382752eac6811b08d1a69d331c3710dcb13f7887090ab6f575684cf503ec055c8b525995f986a26d66d8b8c961aa964325feb18448e0e1548c7239babac994604d593210c844d9b16f3d0bd82fb1db74d85e2de14633ab88f72ac7be4c0e8f84dd34f59175d0e54562fc8f4ab21b9e5f85693195296cc713ed72a460f72aa01a91a4dacccb945673dcb0309349664c2f9309b176c284583b9b1262edc479c9f1966b2c6ed96e4c3589c3b87f264d5440ca42704fd84eab3b92c58857cd74b9ed36b61ce6c232437d0e41ccb5a05942b4b8be7ef60d095fecbfd9fbe9e0ff67ef5db71bb98dc7c157c128ce909428521adb494c5956c633b2a35fe6b67389e31515096483645bcd6ea6d194c48cb467bfeec73d67bfefbbed13ec23ec4155e1da688a1acf2ff17f777d7232540328008542a150a8cbebb7eff4abd60f2f4ede0c584bc9182dd04e3c7bf1fad95f7f3a79773c602d835f2a7afde1d5fbe3b75e8d60715bc3fceedf676ff81b56e02a8446f5b7a8a8bb48f35c94d170705debbba11f712f14b40b4f65180f18d7acb185feeed7d01aef3a2d743e7e5c0b737b78d810eed5b5f49042cc95dc7329001570ec972bd8d405cb8a6201381cf111da4895a285ba525291e069096bb3328ef16a489852374df413f51a4df39accab6bdc16cdd798a795ceceaa3f441c86eab16ddde7ab07eb1c4db996eb4991b526cd9635bd6eb658f7f24cb2db5b0c5aa01b2a4cbf8657020a9d02d7ceebb41acf98f1b9d29a302790871496c1f480b30c8def8003d139256bd33b330adc5129b80efa1880b61c28063f762a6c0435646f1b02efc2f117ef82c2ae4541858874e9d7d48b78f7cb4a2cf429e05aef58da52471998efddde3a90e8ec53fbd79e36f73c33e08f07512dfb449ab50f9c6142aab87db57d0e9d34540d55e9947704fc85c09745abbde279cee67ca5538ab1448cd339cfa4e2cdea5ea658d5b42076a67d7ec0adca0e2cea2fa30b8b2b51667c21df8a892b68e2a51a75e08f1f2388b6870f721160df51a19d3eba30a8350fc091e14d033c6cf56d1d1c7554870726b80dd0c8e12136bcaa58c4a0691d7e03406815191d75e4118eb6f594647c74ff74832ccf9d8308b0b714b37483c508536247e1a12dd5bd73f5337247217daf43a56eb212b52cd90db8fbde3d369b08d3c7f43a920bd0d84c4d1e7ed69249307f777783ac818176f4d9974e8c79839d6df0a2469756eae3fe1735d3970c3baa397debb13ae288cb2240ca324a9fef57c80f1e3dd28783aae1e8841e3f56629f19fbe3c72caa8f8b2ed1da76ea4a1d5fae470fed8fd66f7dbb5a7fdf0734194730bd6018fbf20762f719b56bc6b0adf329a836487bd8dcf50a3d18d53603ee03b1fd1e394a33ae80a9c48893448a285e0d443026764eb8dbdb287f89c0f2130861b21f543ba0257da52e8190b345ed747591d0d5bd6b8b178a73f31139bdfb528f91a24e8de86425d53bbf9b3553629e4c7e8fb63e06bf967264f1d06cf02176fddca9d289460017d16b8e911a20dc4c7905c65d3c2b20db74357380a93551d7a30a7387993835d70204299e983039e8a1e5cda8f612db6c83eaa409f7d37aacb9d3dd9fdf23926fc9cbbad178b1c62b3eea4fea91acd6be3afd7f5535e2da53b8b1a1fea326360fbe983748f7bf52b8f00c697c5b97d218eb84ae6f0dc6319b25a6755ba015906a42a6418e01abf7f4edc8e3be9d4867aded863626396c6c6e4d36e6b5d4aec14834b0ef6ac0e4af190936de30e2d3b3021c10ac69a29b831a23eaed50fcc7bc2a18678b1bfaecc6156de0031f0d9bf95f70f4f4bce3041f8ea9fa6555b25df637b7731c5b5303972276d9052efd052b4a76010471d1c43ebcfb4653a5301e4fc0465e011e6eddf72b1c7a9a939d54578dc4c40722344358111374519482899baae4e3aace6eaa0200b6655576ddb976fdf1d723075985ad140bae382bad1dbceb2ac49afdaa380404c22c7b9039b4dd6fb78f06c3e1eeed70b8d3391a0e93ede1b007ff76dabded4edf55d2a125c70e0039dd77f2c260144efcfec4c91a7e3241c3d7bca84c845a3285cd9962bebc2aca2e3b61d3a5902668da233755ac13ccb80cf5bfaa5f1bd2e2f7ad0ec8907b9ed9ba3066228eff9fd5112a10ae85279782b57ebf680dac20642184e993750d578f66605810f4a1b45f42659bdb49b8b8a18a0b3549da8ddab1021399a74124b495917cd8fb7b7b6cdbcd2e6b8d26702995247e356b29d9d3f970ed7948a613b474be9a29b2bfbaa6d7001d2c1a1f96ff25d8884b91981446a9b85e146565a722d1e4d15b9cda409c15a2fac69cc864ecd13f48bfed39371adf6e785c2087c7db5b342b62116fbf07f602065a7e27e85be8f5e193335acd352c450dcdb949d582cc06d605503eb5efc7605ba7f0a6842125bcd848be7578e99ce02124d8958b9b2ec62c107a98bf2c65154231463266d0c161f3869752a83e2ef038b8d0ccb02a90fb2d0aa0918b1b7adf5e5d9830c37eb8bfcf7be060ddff8643a2de95a2fa378ec75de42199839ff618427a73f5096d30c85fdb2877d39c1867ed51196c08711ce4107bef49d1f507e6a6a53192ece95e97ed394cfc83148cbc7bd3891b8d8f4c6e8a52dbb1e409e9eb53c9f6304b1f580b80c1a6da0fc37a34549b06903cce215ec612e987dfa4e87f08dc04d2db93411b8695a39a5e4e40732849411b5d89b6c6962308391da0c3d39df5fbec1d9c978e3fbc2564caf66ee32cd3198f171151f23cd126ad1869722a6ed4e5b214520a632366f20f2db2a554a89ca7f95232994ec1ec75521679c5da3bfb7b5db6fb64afcb4435ee18c1bee4536d0082c3a31b40bf3d1ceedc0e87bb9d7ea737e70be74946b5094f56f5ad5795e9bc5dcf68f01cf518e92482047313e76cc1d3d2c141512a3933cda79970d60bc2b89ad0a15a54814be0b898cfb96a06cfa97a82497a95e20b9499aa593870e8339f5d87bec6294ac14b25f1746f8743d9f7ee32771dd705ce803da5119c81cebff6d5ca1e5d923d76f71b82c9e8871f6fd6d7b3b4227babb6ecc0734d98419b136adadd8e0e80d06b8519ea4f260655a9d44e3cd7823e7a09e023440aea2aa869d769ae8657c062ff1d2affdcf344c8b740cd87ac3f1ccaedaefa3f85d39dbe73d3834b318d8a42ba1fb153bb90c64a842a197392d308a291ae6dd7ea827bd6e9b2cdeaee9f9d69e061ff7a843b6cbfd339630307e2996bd00eb7277b10d2c655472786b6a6c092da63427dcab2e29a15cbb216c61271532c64b0378bda6369bfcf5e16b272cf768835b1d2f254512af1c333fbb5e6d7b16b3499ef6020b623f6c872c981e5989d669f1b0db39c8a9fd26af646272e77b38f384135cd34de2b7ecfa7d3524c21b337cf57ec6207ef6ebb17c8efc0bb8b97226f554e7442734f900698e84d7b03b6bfc776d8ced7ecf03b76aaf8e34e97ed7c7d86957aa5489663d7b19677d9c81123d536e7a75c3f35efb2fd33943641fb7cdada5167c5ae7b50687ee129496b20d8c8b917c4d0e4a4957530c5ad0ad5cae2b5e66bbbdeb9bf6f7789d675feb15e45ef9f91a7ec857fbaecf4cc8630f98bbae25e435819b365e8bca09d030a06ba0bd2a7b6ba43df10906057c8aa8c65dafcd4abb216c6eb47dd8ba258b0aa04ab1e37bc2ac866c832c58d186bc716244b674f470c20ea3bba5844aa299643159f04346a5360c0b1e651000d1015fd4000aa0edb56fde2c7270e61efda8016f53574b06177afb97ffe8faf0cb6407c358e316dc1c91eee9998b724eaa0d283435afe71998e6c0c7d270e842a5944fc223e5df38cbd93599e13a1c04aea3a4201fe55b7c2aa69878dbaf93fa6b9f6646df745a8a6b8ae5f4a82e04d765bec601dbb339c8bcc8ebe159136dc676fb662f345ca8bc5eddf15426554303b6384d0b191ea74504eb555f5e6b5b6486ebc4f5bbe7f16aa68221d0511921ed0d3ce037baa8a45ad9f1050d8911ac743671486e47a4057912979c9fc89b01df3acffd4d3d76f3a0a297901bea6b7e7c6100f35cb52d760b056767bbb71f4487bb909e3b055b1cc0d5dd45a81630fbd051384690159abc0ce70890e3d5a6b908b9bca07cfddc07b060405dc3391ea9c342920de67a212181111d2d799388460563c2a8b4be11b2dd76d7781ec6bf832f41fc37288c87aebe09ef8eaf5fbe301844ae0e3b11aa736030407706086553438bc2c6c7443ad01450d26057177b279982077f6368955e35940d34a8a6ca289c9840ea32cf39bc68674cd314d78a8689007082975006b2aa5f66baa0a3613d982cdd33c9da463edb14899e517865b2068c565cc1148f1dcbc72f5cd061f344139fd5aa7de5ccfbcfc0cb61f9ba5add643bc2800ab2bd577eb6737357f9089f9fdd45815a5907eca8d5a1e2b3ea944e909eb18415f0813453969c0aa0e381843ab09cab71eb1e603cda9cef598bba55db92630ac5e946951a6d583223683e3104445b1b170cb74cecbd580394c1cbed4bc8e58906e8d1e9b4d356b32e4bc63db52f6ad332ff7fbe3c7cc98ab0939e60bb8829a5431818151e0195eeba61befa5767db127b8ef86fdf1aeeb3abae1b3a2be00d20645adb28f35f3ad116f736e030244ed49a3560d0d58d7c0ee43fa779f1de9d60bdf8ca101e76cd735dbf767eae633b061ea517fd479d062e951846b35744216160dce06f5a5720c546c281ab5186b2c5bd4c2d1a681b533a4d0f204cdd0f04b734bd8906899d1f66db61c5d43dc90ccdbdcffbf441a9148e52c9d54a11d56f385f7e0e1f74ea219d58f6bfed8e08de48500834661d35432b91063984d371a500b42dd7a8dfca07b9bdcd537ba873bb5d7deed3d5bdbc03ecc3a3bfbbba8e9112dd884f7197d7dbad997b36ed6c3c63ee657bcac06317e83413d42932a832a91279b37f342e5780617514b315276de99196c605eaab98c3bd1539f7a363608fb1f528df71998c82c4dbc3c9f0f0f29a820a83d105c90370b2a588a09e5406874007304f5ff9e1c1ae1c0e974ead544558a8a0561ae291c39097e2044dfdeeae9a0e04cf2093a14b9a5aab22e1c1947005d8ad53560f47ab2ef5f4fe1e6bdcc73a1ee08bc5cb9378674c2ae52998ed22cad566cc62186e018c229930b8db971cf80071de203cc66ce844e3bf7d92688687cdabad92d96d56e31d9b5086c9dd9db59cda4e7b34f29cc83bce19cdce7a08d27651bfd8779cc6f5a540113b07f83a8f21f0cf408c179d646795c675b03e7f5720496b02fc8ddd75aa0af37d2397401d1d1aac7130a16675e4c3b0f10dc6982311c45e0d5848e3336080292b92bbb89cffb2641fd7c45e89a5da6e9da1c065d26f878e628286dc827e78109b59810a607356136936f5a497631c94d98fd951b3fe9fd4c486100d964ab639e6568e809bde3eeec92ae54f05ca20a71552c21402ac0026daa0e4cb90203988528274539e7b989b050e97c27a6688cd93132918bf1a5930dd1f01b83931ff2902f280cfec6d88c3ba48d594d7dfd310ed7225b42ae651dc09e675a456602821610974b2b99a4bbb836cbd7520a701610607df28d13571e7cac30d18c0e1934e2321d1b9ae0594a9919b675bcfbd18aac9046252f5776c53ec82528ec1555603c47edc6e56532bf804bff4517a9124c460b48808c244ad6a24f6934680ae8aa094be12f06d1a2b145abae05bf3471f795a484613dbcc0f91474ca2282ae18b80eccdd891af9782974b4de3ae296ba91b0a254370c1d20d8702902460a72bb3a0cf309c07e2b054f02efe148b4b9faf62518a4b52f72c1440ad8c2e06e688e8391a77a54dd1edb2e36a0044e39fc0342d1c2740746d2d9068bdc62c13ea2b5c71dea6e0ef7f7f6d82e3b0143248d2937f31028478b09595ba8b92178d2fd0cd8fe9eceede3f461623e51749a4308f5b4cb7e9a613c5cefcdde06b15153ce8bca74419f0720f1d57bb18ce5ce3499e4039c3a48455dd20a18aa780f044c86d01e5346f270f622c3c06d3320087e934a5a04bb723af81598cd1619a58b02c3b001d5da65178b1b584af57937135276bdf07c5c92999a6df07b5cfadfab3db610e558e4159f8a5a5a23b23722528b26a822788b8700f29f842c94abeb8b2e844cd76e0368456c3c5aa8d62cac45d6cab61a55fea12875cf102f56ddac05eea339d8f2de445239d9b3dd1badbfa7de07a71cd9cb7ac6d218bf50a199e2f4755d54e863544737dfd63e4d3d7692a30b4931a1d88e0004e31576595ab96d8d57944f393f174ba038c3b8b5752eea83db5cb20bb48c41e0681e73d1e9a229af6fde4b30551baa47369cc0e7b935e655fca55d941056b0e35abbca107b8265bcaa706372c708964e5d13ff24ad582638daac2a8ebe94fa68251c10c452606ec63467574ffcce9e1ad7df6c05d8d35b4afb04e3f3ad160ce1c34854d742e42c492740f2485b7a77b25705d884f18acd9759952e327a4244480a3752c7c954479cc997e7afd1dfa2612481122e2ee8d7fe1efd68edeffdbe657f77d9fe9ef3e7ef83bfd90ef3ebb35df6f5d58cedb02fedd7ddfdbdc50ddb51055df6f5e286edb23f98523b84efd8f6f6abefb7b707ec04e37b2642a69856031309eadb4855786206447126937f8529be3269dfe63ac88ce9429bc5a765eca17f994f8ab25ae6bc126a0dd52060f9311674c1925462eaff7a44b29ee9426f09384a21f065416e093a79e0692ae5529cb537cc3e0eb565ffcb3f7ed9f117f6012728e2eefe23f4c9af3d429ffcf68e50b2bcaad50f2df6aca51e33dce353adf598c1bcc5fd5efc18af09773a4cb67382b941b24db648562c2ba92559d2a6ac7c0a79cae458e4bc4c0b266e525949763d136518ee094d2574ae0eca9bef004d43befa13e55de42bc5e7665cb2e1163e102641bbe116fbbffed7ff432d24387c996ac3ad4076a42d02e7d1b530f9e413318620b20ea1104a30a9358999036fd6bb2c1195ba2b52f86177ae8a7196024ee5e15655f2050c86d526ac0e28032e5592b4ee319de645e9231da0eab9218ff125ef2d6f7c3fcd44ce2e222faa1736fdaa937dd55928e9180511304d0498b4d20edf4db3aa78988ef54121568d695126f895e810301f075eaa1c421aaf14667171546d914c454d6efb6436156890efe7575ffe5a7ef5e56f8f5f0548b00d0d672200e4ef77aaad3c0eb5ca4c7ba5a1dacbc45d383300de388451952b97eb183ab1b7800a3433d48ba28bd14a7b1a770dc86a2672107bf0f26bc0d0cdd404d1b6f1aae114ad19f75c04dc534f6e505308da50cb7a82cda8d254434645875f9b0a4fe790ffa19868ff579f8a38d86ecd977375f857a82222a12de0741aa0762ba4039c44787e29643d554a76cd5712182867595a5599d02334e0dcded46693fa5e4f5e72da25c7220c010cd8d7cde8c033eff62fef5fbe20b4dfd5cdac0e5b984916ad005b068613be0890453a182309b167a805b8709b5f74d5bd234f8aeb0b4b3317fa660597039ee38385565004f3aa8d6fc0ea03dce078f57483c1c9e0245492155fb15cf012d58ea0fb21908ac1174bb8315ca9fda1063ee50b6fa9aaeba2c78ee1915ee7b49e2c334cff6b7254b1547342cd41c04557899da4ad12398d54ddfd2ab62852ca08104de4dc733531a522953c5b313e5283b5feb070ff3762aaac8c84ab056a0cd90e393d08a03b333fcd4ff3201ec0f6dd7838f7f3fcaf7e2dcfffeab7c7f35d0c34697b5cdbe0d42a62d5851479a99bafe422d08110e1133020aa14b4078e3ce9ae723d8e5fb03fea24e72b108ba5ba76bb06bac1f820ab9a8d68362baed99ce75aac217fc762e26688c2c0a3a0f9ad29b01413cd0b262613f22bce8bb047cc6a0e0a854f205280753f757efd6ba9f3ebdf1e7562a2995af5d82922f4d9717ab30bcdce5a10249fd2ee1598310f31c325b141333cc3d86deb0db9ba097b698dcc8d8e0c982e0401e225724f520be83c65a0d889b3312a26f30d49aa705f4273b4af94f513c21df969267d78dbdb60a5bcbd1dd8fcc31e029d6ab95c20d31e2f4bd40ca1edcb7835ce84d14c99d1a3e63fade8ae829b4a9ad4c03e8acce3efc377810272ff26f8c3afdd047ff8ed6d0235f37b252a12c9f593d82186c5f3540ae6b94c23068d301a88b7173cab14132b3d8106aacb2e4c446ef823c84740a2951b09c40b2d912606a09381a20d15f1599167414a0c4f2aa3d97819141e2882bf0faeaa182e1fe8789612111bd177c35bc3e71382b58ceaafa23e15af67e99894ec0e813b7768ff18d6a76daf71f2b9b8023ea2b3a1e9fb3dc1d1d93922178fb6b8198b0570800b579eb870f6426df92242b5997033eacc4ef443c71e82114fe3d42836562cb598163d2ebcf434f876a8d8b77bcd6c88319cf1850cb42006cbbe4e4fbb7dd881906a878c1950e347430baf21fe8c292bca83316502c6fe9b5016384779f8b2e8fc7762ce608050f890db9bab19cd8a6b5615d7bc44b113ceabc687447de07d6f1518fa4a1648d7a4ea4fea8ab4dad67474679fe332047fdf7fc4fef1d71eb17fdce88885b5f915676cb03dee3b640d3236208599d67debd541312f72255503f5f9a8be65604b87eecd4546913267171173c50b66ec1989fd8fb9bd28fbc3a3f3d64dcf7dcf908d4a405dda8b496d4f7e7689f421b4a9e6743f69fee9d792e69f7e7bd2df8c367a9d2e29f5ab24039c5546ea1acd2cf86291a556611e70e2aa6053616e21c628cbdecafd55b72fc2917b839a66552cc71866e4f9eb97a08f858797452916bc7407a9bbd42eb817f0c80a2e89813509bebea615a93229d214b9a1a05e8b60a56450b02a96e6d6510ae0963e7cda16e3a5ac8a39440c046c38c7465ceda12ef9177ffa7aef028c04d0788b1ee7e06c483157c9888f2fe1441817f305afc8e87968b577a0ed86e03557a2c437749b46ee17d963c7370b31ae3c9a92489d693eb5267b0ced1a49824f738aeccde6fc97a2f46007566a9ff43a429ea780c30d76e1d7bf76177efd9bdb852e063690b9a68be5d3f15864145007c66a2a9f4cb073b547c028510d5d31ea2f9f5b0f5c4e0174adcbbaa3da37a05eeb8884d66ac6242eb3c945d1c4c69a0f06e25130d81035e124253d5b9fde1c9af70f53e7277ce52d18cfc7333a72fe8e66486d93cdb32871749d1e7bfad7a7eceffab11ba53c3bbb67fa7e9a4a4abd5a068fb053d065e78cb3242d05aaeaac490bbcc23ab964dd49dfd860de9b4d152db8d74ef4673dd1d0a68926faf37fef444d0a5d779e2b939f3f7e883c85430269503b98139f8e1f1cc13b3f59a83e7ffd92cd799e2e96999342374be769a54f20879d1243375c5cf36f02eabe43a47925a61000da5af2a610498d713629f95c28890202f6a6e25a733afd9ca1392f014b4406d1da8c996f7dd8f0c2d174f451fe5f6b8de3cca96b0cc183879ea82da03a4f50a7ad03526036cf0b1d77ef42cb4f76daea484cf00146cdf99137c8ff521d470786265bc87f81b28a6b602c7c3c4b0569f0d1e2292125f6279f13f6a4bdff94f8e6d7ca6adffcf664353bff7a9b1fe829c1b640836fb7d56bf812e3478e01a14c95b44e473cdbefedeff5f6e8b2a8137fa0a9a02227f7dcf2b358febff0dc3229648714c2d94b870a56cbd633e182a246fb4958e0559598439adb09e9f7662ba9114c9bc625956cc1a5791b332e0cb991c02f8afc5929c0f7822cfe3f902bc6986799921da563b0cfec58752c685a5ecfabcc7851c2043d26099fc3b6daea2c70f3b13e5aceb5c144de6c8650cb44ea40d265d9ca680f0b4cd81c823404e865127aaff6aecd3ca578260442d1e5234a45e490f51aa8702dd620e3da3cbcadfb97dfae3ea3aa825de6c535a96d6a5a80b0734fbb8bce88ce9b207b557f8c1aade847d37cbc65a733fa69be823d686a694c837cb2f62a082a0701f70ddccbffc5aff83bb02564793117f938e370a9688b698f5de0bbfcf794a87eedd8601aef7ef500111dff7dc37494e5dac9de579a7bbaee6638da3e586d40c7231ea0d5a2eec1d6c77526b2db08b876aa03f6d825ded8d526f55d9b3bc458b4df0fd28ee97342c5e7d33a1fd74e9c681b824f4a682bad89201068f76a8e61cf51756a7cd3f4a3ba221b474e2a725995cb71559475373ffda285ce5889c8292b29f267847b611290fb97731798e3cf05993fd04d51a6f345b68273c0395b4c4874c9e7c88f717c8a68f5c392e95abbc97124f62fcbc48ca607fe1e644f3f004068c5becd72714d036d9762028115ba20826d33660fa381f914b3780c74a7ec8eeae2bf771dafc33f839fa5a600fc242b5ea5e3688a7cc7dd8c1631e26df6a6fe08a9254d94536829ec73a193bcde5c461d79d4147a973dbf5348a30f8ea3944b9f847cb833581b1623cea41543a3e59cb526e98d485a0abfc21fa83979bc5061ce930b8dcf2db52a6b7f805a7485e592ac5d0a99fe4b74199aa061907575a6a2b917ad61af613c08e4d8118e9de1788546f68da02b822975a15856851297c6301074580975cece0d6face5ac8b44c8aa2c56da23b569ec08f175fe1cabd7b0199437e1f319c95adabfd758c6d13053c9c620a525bea5b8fb7483164c7467cb8bdd6211b8e460e883ba3486bce0c213dc2e82096b29f1ce999bfee6c4f4d29fda1df631a21cbe7f9668d791d0655c8ba0da1a1fdbe927819c246220b3f45f2014f7014db540ed5d36523214327926972329feb9b4375fec55fec7708b22b78f5bfce6e1163fc571fb828c18ac90bf74c57eb44ad542015de38d3b785c14334a67b1322e6d7327507ee089ec9f4bfe14cda8dc393a4780738bf72f487f3624a0498bce7b5ef279ddcfbc763abbed117d1bb6efb30f559a49f8f5125880c4a3e28d0e2460a3c274c24303472a1977ce40972a0c76c61937646330864323a1fcd6c6560f93e390537dfdca607c67ead7dd78273a2d0f4154d704d6677f7ff9c207c96533a4ba8bfecf9095011f35f4d7d0e5bcc88534c2779ab3537d109fb57f479b4f6a770c72e5b75d993d86a3b60105a2174e63b3a597cd8a263ad8260583f04283c1317c08a7b19f1f9b6674682421a913057cc79eb0c78fedf7d327671096c3a802d8915f38601fef28420c1084e293cf66627cd956dd7669a43627a9fada93e39948969940aa8ed12373f393fd732964f5344f5177f043c9e7a20d93eb21f3335100dd8ccba0345c6aae930875f7188ba46bdec95262aae532078f3e640ff958ec2e44b95ba5e34b67c44b3d520da8ed7cee8dd23c810f1d2fe933f0cf8f7790ec0076156daa508cd5eb417a58f249c68eed5a7981be884c34c9d9b0cb6eff29264c44c661705fe1446c120149077cf8caaf8a901bd40a5c737d3960a767910580b463de2dcdd7dc4ad6c60c28bffc4f4b51aed835f87095da300d06eb869cb1bf1f3f763c947ef927b43e7282b8ec29b2f4036611bc2096a282a4dd3335180aef023082807790ed482c307386fb9c68827604abd6f34241e87d823ca0772956b2bd6e51dd305e35809d4e24c265cee76e94a7f3f8584e55b5b37b28aa56fdf6561dddf581b0a3fa376aa27883974ec3a0f1ad9870759f843758ddaa85d68c6dc40f3bfc8e8111a64b0f2e3e5d34c6271aa6b60ad043fcc562411730a66a0ee0fff5b7bbee7a74da799a49caa20c1f9e472bd4b6639d9eaad19c81c6645641ddfd2e1be1af28466d1fe8e33c138c538830c8a987694978394a2b78d01917e88d993b278edab18a67e838626a0ecbf10ceba65243312eb3eafa6d1f16d24a060a713fa3174f12e07e4ed81594d9527b227931580c90ef8fd9d39f9ebe3d1e50041805c939952f6a4b02a1ec2e406e56e5fafb6bd2093c8a5154643b05ed82c42b41694f3f7d3c7ecc52a95f276ab5f091c24fd312af43479c73c69f3b3c2c20c76e08449703bb8fa77331f89da4f4b4866e4574d6c58530bdf618930f1402b563b2ede7e3f7aec1248f986de4153ad93dbdef7e267d29aae502a102c750b213fac9aec811521dfd638eda203d1b9881d639e43aeaea98c9b45a72877fd34c70358f55272f741fed4e182ccfa2b817ceb23e311b661fddae5b209aa2d8e4ee0a1dca02268414af76264c55ef3d0264da5605c6e9ca13cc35cb64b59c4c30bbc0bb345717c76a39926a04aa298a23cf54ebf61ba2a753c2f1a5580d580bd1a6dff2415de9dce7b0f48b2ff623f21ac944eaf282329117a3b9cbbc6e4855d1d40f15c73ba2c20d7b8a2d6853b7b1baf131c46a6e3a757c5cde6c44d1ca0d6889558d8e69587b177d478239685b6921ad47d832d78a0bc88af1e1446f2e7ec5d34c756a5f24ff4c71597c51df2d0ef599fa293236ae6745960913976e59a5746d779d31afcbb482a493786db38cddceaee225540175b87df1fda3094207434ea59d105e11503167e0a4f9385b26825d204bdc55e391bd5fa4b131b830313f2eeaf6d7dbdbcf8fdfbc3d7ef6f4fdc9eb57dbdb03541741d89342c7f844a4c02d1e6c98cd6bb581e244b4f163d93c8274ac9579bb4420f3422d0219bba81951a64803eff9d2c4339aa5d319de3e4980209d09a2c7fa2b4387009e323be7adcac09b2e79c9f34a50f896aa20377426c5fc4a943d3dca39e39535a32853497618cc538033ad90d1d97be943a83467f7beeeff292441ad2bd9843019bb3bf332a0bdd117843b3af3bcc7f140fd11bc90c325947453986f39af4439e16361ac1d33d2c119110d6043ee185149d0fa52cc23484ae305a2e290ea062c72f22211ee638bf618c643c612be7be2737ddeeb685719d2a78ef7372e8a3249735ed12b966b318a67167912e801a8d690af54fae125b6d7bcbbb8d8d32a8e574582f28c6904bf5f7d4f1b6922f0f532955e242535c01385e05c54ecf8669115a528d9fe9e6b2010f418bece598b135089eadc28693eb5413931cca0e5dbb0c83a8e630c79b5b506f68af1c52ea25db86a7d6f7cda1e0846e7a41dc731e5ecf8dd1f942081d11eb971f3c57489334ac0ac37fb555a564b9ec51d21eeeb1693846eda2f0563dba8633a1f6843206f3b646dc5078a09a557078555cb68ac5aec48170cd8342b463cebf41cde7860c0396e734e605da782f3d4a67fc2ae173710558eb47e962bf4fbbf63b2589663f1922f16693efdf0f6c5a1391bd4ed74986f75b73089105c76d921d364d633621de897f0048f14aaef5d767a86f96ad5d608866388f19f92b74d882cedc5400284499b09c3d0d57aa015d14ebf4fb3ac6d9aa98eeeb6ba5be91c3a7b2bf898de995ba5fadd3a409df37b3e02ffa09b8a1d62ad1e499ff8b59d2fb32c326adbeec0f6a2efead8d170ebcf233e1259bf5ce6553a17fd99c816a2947d21e77daa39dc3a18e6ba3572de9f30eac31b2371bf280a293600b9aeb9dbcf3f25274c24c57c57430851d9b20d002d5df65131489a3498c91c83f920fc7c2b26ec2ec42f355f4af143518eb53a152bfd995c89fbb3a2b8947dbf8edff8a528a722792b26b2b1adade2347dc5aff4d262bb5edf7e72eae1a495386526f711f4b320a3fe55accccc7afd5a5d078e434ababafd84991e14c5e505e46f3264affe86872753e3e94842e8be57fcca10e5a428af79a9a6e86800cee1f1dfcfaea9be7dc1a54eafc96d18ed67c57c51e418e4d9d43ad4a929d9116b2db3161be832d3aec871d6266327fd6d2af0b13a0f14a274a7fa830dce5d644297aadf0ef0bf8ad573255c19e8f4c186ff2e31e1f4dafd41b8381d6e7139dceab2e1961e26fe6586847faa31e86ad4df70ebcc49eef554a1156499894bbb05c4f32bc64bd965a3fe5809962082eb47f1aa4ca753ed70851124082098e57a118221631d6aaa40b385fec7b0a7f462ba7d1f061ba96df3c6a98ee45b1c97da8987b425db1858df66e5028df86bbb9e7643b76b946d9b552e8f749a58eab675a7a252df4a75234a4e92aef7a13c499ccc0c16accdf9806402ffdcdeb2961a4f2a2b9d5ec52534dbda921b550bc6e0570e0a234dca754dca93244c89a14608f67d06edfacc7090f24adc544f619ccf666996b80ca05e4a495c0d5a20c787eea647811a3afa5054bd39f967d24accd57651c769d8a6cb5aa74a10da2d47bba001dabd14abb3415e54ed9ef644edb43a0e34ee8d3984e71fc0ed162d85078112b6e3b84c487c076ec7d1abd9eceebbfb4d1354b7fb130d14fedd614e166104642b7da7bbc637c48ed77e2fdae45bb6e7577301b05db6efa78987d253539f72b63aeb3fe3799209b3eb6c2e17e77bfb52acbaa896f3d6fd5251fb21e04023c419b366721dc3a55d384e457feb770256506b541fbd65d3c1f0a9a05d1fba61ad1dcbe6dbdec8f4723ab46f74b3e4928e0d7a9762e5e892e02ed77a5a96c5f50b31a95a8348c18785fdccc25e305b41b8ed769dcce20c359566381eecb7e06213eb55cdf1c1fdaeed96244e07a647054651064c22e82ea01844259902d215c1688d3d620ce0f414d390a2ea95232d140534161c419a41f8996726b5d34bd3999126db91b77635b390f3b0c78f9bfa0c521d3e8c8345d863c8d470402e0373fbe8c170eabaf86604391969ec393ad7122d9e2a56c045834f3d0d4fdde35e5fc8fca47eacf7dea04ea7ec5a630c50e6baeb4f0ae118402b423742fae84a7d03e6c97bfdbe71ae78c5af5ea4f9a58ecd55ced35cb0b46a496851132e079e4cde36df6dbab3e0681fd40481db5b90b6a30dcab041691bf86af218568c6cdd0d329e29d9d5e0c770c181cf3bbbfa38990cecc277ad48343018b9eb74f06a1bb9923ad706e74efa11859264391665fd8aa615826f8d0ec8d70d913c2b312a3a5d1fb4e61db4234571c9c43f97e915cf844e5abdcd2ee0e9c9dbef17e8d0886f420618448707db16c54425996773b40b21976bad16464d9e640b50be80fe7bb4c448dca066c6cc67f07c56cc05e3c915cfc722614bc929a84f0997c8a2446566b1c0e0bbdb28ae63373527410631f511b6a711244b7eb03fdf4052df766a23065fe7cfb214f2df2aa19aace9daed0e3bfc4e5b6e7b1844c3ec2e3b75be421e3e044d5ce0dbd1b2aad4faad16e270b8857f0db75881bd1d7ef43abffbee2fa95ac8527cdbc7aadfb9cacb7e447f649fd9825992ad5e1fd4cb55319d666a2ddd9584c702ccd5430e80826be54cb1a8d239d99ae222c9cb14d45204954c498d6d2b1a58caaa4cc7f06c22feb9e49949d0c065e5766daec7ce6e3874b68673eee09b749086ee117c3d201680f72ac34792542eb812560e5df836c3a67dfa826aa49ac2478f1e62573a82551b4b6008c30ace75aa7b2d460b3ebe7c5364ab49aa0442a831aca8d83c2cb8c0b46ac1565bf06aa6fa3b3da3ef68a081457428598b3a1b84172bbbe319ab13af147987051f5ce8640913e4a1c406ea069e155c5d93b7ba7a36c34ae4cb39ee706b970e0553510dbca9e9826165f305aa816407bae40e7fa04dc106c3493ff750d2c6a1c457951dc20583aa7bb00ed0889794b2232ec5893c56640f865f879a4fb55bbdfe7950dad2e49a4ac4c08bf452f84ddc9256fdc148010c6268404a8ff35e8add5c50981a7ad590ea9251a53cc3478432953a75143849967c7c29d53f57a25412016a77dc6c58f63dcd1ac36edf112b793f1336220776207a6155cca4f4dee4545adf60a45d0f466935e7f212674dbf27199f92bf26db67bbec430ea64522716687a54fd82e7b539bb9d7937dab39c5f7e0f45fa23c83feecf95b3053e662d01fb3b6d83d95151f5f9eb1f7215a2f60ceda0515e3b4b9a876f27899f96b698082c39303253a8501d3b5077e1793435e0047bce88579041d226c43fb2eae4457e3b56b275976194cc2496c4ad9be0f0fb155c894cdd5e22e6c00f76525bee1ba3b1fda8f5c32c7061d4841ee7dc7fe6a295111fea3c343faf5f831f5f0488fd18e879a04fb701334384d344e74d2bcdaa1e1d4b59c41dd31f191cee709e6bbe1066551544125f5c96c7ff6fd32cdaadd34d7afb0e6e18b32052972b81225a47653343bd2ef833de302f6922fe8de0b056dd54197b55ef20575539bd44bbec0c968fe0336db102d43d3732ac9d0689b9d663c9f2ef95480cc83f94e06fdfef5f5754f8ce77c1784bd9ca34345af28a77df8fce40f4ffa7fecedf57f27c578577dc1c41abb1adaae822651ea527c8e9ec97bac2d7ad31e06ba7452d8caaede575d568aa9b811b2cb2e7271cd3001487baf73d1c56da83ea25b75bbd5ea5c58112ee253f77ac2cea90c6c05f67afbbd3ded8051896951aed80b0e42d2bd5c5221f1019bde41b5b10b88ec77f667f25134d350270262ab4d26b6db4a803bfc8e910b5aaddae97e973de9b22fcf36aa7dde53b7b28daa6a55aca9a8ddc8fc74a7ba3ab103f39a02161c878c1e70a1d4bd716b7680dce5f1637cea55eca685e86a299663bee9fe5acddb598fc4eee5395f3ce3e3997896095e065bd52b337b5a7f7d2e3251852cc02facb5f95184ecc029a9d5fe0b3c34c56aff85cb5aed778db0df892a1038ac9fcf9c2fd85855329629059355510a762956bbb8020b9e968d9283e320ec6d129dd642e455990a89c76f0013b68deabc76b2bda4a1b7a9b943345ae3bdbb6f6e08994e114bb5cd8974c4f6d8407f250d33dd1ae00a3d562b4bdaa4eb599a09d6ded949494bad35da8e578d82b4b2fd9ca65623aded414505635e9dee9d75b1fee9be4dbb7e473e5a4f93c498545505bbd0f3557b5eff769ff9893a3d8a3c88553d6d25487a674e75a4c668fdde14c8c621c378b519d0a2437ff16ad283f60ea0c54f20a860f721f07b251bfc55ac42aaf7ca0cddaba33952597f7624f2a7ba7d28909b82a6eda1032e93794a719d337b63b151182025289c62059d6266b36c6fbf2a2a31d8de66af8a7c97f69823eb8d0b518ef16cd772237b27843d7d8fdf81b9b23977373e730beb2281a7ec8472ed415ea5347377b47b30d60ec2f0a43407a367291578d3e144df7b7c0594c1e109497c429f8f94550371ee23b8e138343ce387a2202dc9b6de8d9c6e7bf6cb881db227f8e5ce80f8a128dccdc60ed99707ce71075e264aaaf8a128bcd3eeb4c521714deb8cb5d38a42e790530479fe1a53c8a413426ccdd256006e4f81db87c8681e3b84fa8848df64c7a161537ee46f26f37d60b68cfed4784eaafe8c88c83e900fa5239c2a5abae225045f34a921e128e0b92261239c3efdfbf9bba73f1c9f9fbc7a7ffce3f15b76c8bed9dbfbe3fe37df3cf9faab3f7eb5f7cd37fbfece8b49a21c239ce3b476c1ac1d79736c9bbdf78d79b3a290225bc1d4134617c5d38bf705a6f4be78f8beaa0a3a181af64f5cb0fcaab7f79f102c097338e28da54bc44dfbcbf53220d5c2d5efbd3c7975feb7a72f3e1cc7e5c1b0d5493e49f3b45a6d56bbf5656b1331936abb62a6becb3a2226088b68b8d8628f1f3b8f2bec3bb6bbaf044dfcebf76c5fd5ddb35fbe3dac51f41a59f3859637e88ca3cd1a3d859ce3eadd6a3e2ab2b0167eb50715ee4a88970ab1c5fdb388d2ff99afa094b4dbb21427525d97df94602dd51f0e7bb7c3e169fb6870fa8fd3e1f0ec6cfbb67d3adc6a9d75da4783f6d1a3e170bf73fa8fe170383cbb55ffdfeb6c1fa96fc3e159df3caf9cc837194f730df31fc3e1f5f617fd4db6b73778b8c429d6c9fde17f9aeacad93ba14e0799e059ec900206c8308aeda7ec3a6f42f7287152f957b1327a0b97c783c9069207d174a830711e37efbb53814d90be2a69ea77af4f1209ccfb46f3551feda36fa003d2a4d930445f8b64dcba1d62e955429abbe1ed2d7be452675088a0e9fc72af86f402929350a24fb8755741346972b4bd3f8aea3d9f46e4492cf8641daf566efcae2a7446e452c865e6b8483b7b13d70107d222226588e2b3d6fdbb095e00515f0409e92eb0e9055b94e93c05ad5551129dfd0f7182213e363ebb8818f19f1e4a6545b9fe24a3362d3e1a6f74ce7804bffe9cb1bb8a48b7413f6ac94c7f3c3cb4a4b08e8c7130be42efcf933413afaf4409715c9fa1cf0e05ac48dd283363751f98967c31734942471279fffaf9eb8189014ef1b16555947c2a58c65790b2b5df67fb3df6bd60182d1522a143d8c7bc488464afdbfb1da8f4a45609b9901a4a96e697baaa1303c5595f32f583913a5b2e872f3df8ff56879e8219d6ebf124795524a2bddf39d0d61108405d668b5ca06f4cd0e2459a5fb69f74d997aa51bfcff2e29a5a8d351aab5929044d0f93610a9881d94efdc842a145c38f0a923145062b9874b28acc083d481bd536ea36021543e274ba69179eeb72bfcfe0b3132f0d525aa6daa18b4b96a41818a784eb17ccd031b035f73258ae1e3be6e319baf72884b6e06bcb9e7df05c45cd6745960051e04a835f918edbc32b5c08f6344f28180ad5d37d43bf4eb23cb95024b95c3810e95a0eee112620729a8bc9241da7143009a262b04a9473b8accfc5bc285718610962cd29ae29d9b848d27c0ace7136fe86fe058110cc79da5ae6e93f974291cc49d282d40c81b7b8ba121599e85df3326feb23d4a3da418367e25e6fff2b76e17670e17b03f686c3bcc5760cd00f8a3d428679807b4163d1de7eaab65198b5fcbfe0ee84760ac07333e946c3d796093649d40f6aa06a638042445101d2e2306fd9f1a4183c30c5673c7abb00b1ce0ed279fe666d00049988d552c3c43b3dcad7649dca8dbfbf056296a7e7a22b70bb7e2e40eee56051057e5645be6b81489614fe855d276820a41439266beef7cd7e875b3067d3f44ae4a0d0d49ba687c9a1c1bd4eaf8289c26522adf5fbe439c924bf126855833409bbedd99b0facbdffa7dfb3099795006bf560cc1d438831a4b8817b3a71b469f151cb8ec8d28cf0486ff914bee6d0d3b1b323bf189f0220ea07d115eecb43766a12faf6d95fb804273318c52e6403eb998b0cbc59b33481cd8999c2747624083661d811c3f6c750e5d0f608159e4122e043a6e359cba55c883c39be22d7aebdaea6248af940c6e5380df5c709c90c6d2def611158d31dc6107944353e18ea6303faf42ecda7197cea3a31175e2ff551f6f4cd8975039d0b8e412d30b0011c9378f2c05e44549518bb5c2e4798c3de00353b8c843fc8174b2db5ff83d97468087651e4c6a190fda5b816574ef40e6de88596634e3c02f43aedb1f705e3e0ddb2cc73311652aa63830858edfce57ce145f2b81636c14929c64599f8d363cbbc4a33550dbd4721352f84651276ba3aee75bfcf9ea9851b09f02bd6361166cb695b2753dd347b3a1e2fe7cb0c0fd22c33bdcf792258b284b034382e1d5dcf3485038f18a30e30a6a58281a94535deab4bd4ae139b9561060439602d9e2490011b7cb75b4a20d731170e2c183859216dbde6c5dec1897eb5b354da13d732196c41086e49a8ec8006eed50c1a8a3705ad2aeb2060844a67d3e342ab0d4079190e5d23512c559b2e562af24a94181e7e8caa55bff826ad22a5d6cba822310032402c47593a56fb6da0b91d4ce00d2f2b1b10cb0d3bf03449a4715e369ba7c74e90c7a3c32ef2fe54c936ea6c59a941c9cadf6f06625a497094c5703a95c813912098eb19af2063e0b898e36e6da98a2d1bad76184612a01b971aca4942075a225a92a50908959019e229d11c84e44769db587896c2890040d0c03efb8cf1244951078ae39d504e8e1c771cd8902689482c3268fa061e3388d073b681ddf972aaa6a4e78e2125aed54689cc52c7ce53bddcc1ad3217d7d90afbc7be75365a7f4130f3a4bf2c612e3bba200cf48f6e2cfc04d001a73de1518267504459e0dd586f0604b4357999af71ef4ac09ec31ef0f44d0a812f073864030365fe9ca231e9a0aa4d64a144c993043bc6a4b2d8527b64d99a55a1eb893c69acd5401878e680637b6e16d26108b19554c5ee4ad254a0597d7d14e718e81fd1f5790b4c549244a624537fb3c2771fabe6cf9996f46338242649848bc3478b4d7d4dec28da9b8a4afd21db1dfda2db48c6d284fa05d8d7f0a602e13b0e284c74a1733984a48af5101bf6f75a84443645043d502b404f947b6d843362473556e46473d0b7f28ed93b1be00be7f2607ce1eeb6bfa3f8fa51543164592eda80256bc46bccaf3591dc871f0a6b29cc86d39dadd937c801d31c47692138482e4a6750983c1d62b84127711638151522897eacc190d1d620a34ae98283a4d438ee683311b4f2078332fc606d60502beb6b57a0e6915745c5b39ab6e99e81c09ede6020a80b31a625f70cc52a2cda690e19115083b4ace08f8edda17582b4a7755c04a117e7094005bdf8e7a0c8e6957deaa98370e494a0258436a9d1e181232a984ddc3cea605d06e65714d527f95571299c30dc05a929505e9844163e448b31226eab369d3b0beb07c7847824580a7d25be34e04cce66b25147bd96e706ec2a95a946502dc7aebd990edc3f369fec952857b02e22616d9efcc2c7e0bae789b3403771a9cb238d1387c1e8642feef2d6a4481f775d18c71a0c52507590a1323d6894901c3c7ac296931ee8ba60d0aba82020b79e2b89a539c9365afaaca4c826b50117658a02698a5999e8fe579164c2a5a9d1b0522f60d0de7ad94fd1553b267da5707942ecdc6d46ee83d1dac0f39a91ab28d62077e0ddf89ce7027f982f1c741b8db9b9cb43a0498805060acf546489be398343168aadbb9a09b16b50bf5931d6e51b20b946ab8a3c310136b6198aaabb35e1d58a24bef2bfe3a54e88aeb5b7cad1f57d876a277a08a9cc2555926226a2f9306d459e90af1ba512a8d3dd484c531369bf764f6e100be5724ee476ff882036475a3a89e9b1bc45d7ff16c5e0d4a1bf504f0a31f9f315535387707ca4b80a466f2638a85de2d74ab4f655496f6c198ab4414f603839c07fa2a09f8b0a72215ddb9c76a4046fbab599a6af17dae26b5ccc17999a09e8495eb7f30e5163aee833903b203c9bcf375fbd7e7f3c4069cadd85729517793a87eb379d77ed4eb3ac0ce3456f12adb2163d3c521bc5e4199748cf04ffa138aa8b21a6d50678daef3c1005787168468196365c141cb01f78265724a4afc3c4868230cff195e2df411a35eeafb3a8d62ff856646b6ce4dff5eb0d3e0f4d1129199a1a3a9108b4560e14c13c81bc7ded0ef94f297ea3fe70afd1fa89b46db475fa29685ee4695594ef8c66589ad0c324a09a26f4d91056aca96be65d0a9ebdced9a185d02b723768b24e870d5116418b0e7ba05896ac12f3450151b68bbc4b2e7b1898988217214f34a0e6ae06930696e6533a14dd01b043e68cc249afd2f64324e7c5353afa57e95ca03dbfa20f785e4197e1e56462025ed81e9c33054ddc6bcad7dab7b78267077548f6003b8c6969c34f1e9488c238fc14a9efa990c34f54df4191a541bd923a6084f324a22fda3c638be5a82f9723ca0dac69d2c4770d9709e9e7c0e9d024cb85cb91261a0c53500e822b2536ef412a534bf75d9b7bc30f2d1c10770c5b202b769d8709fb404d27f462296736087e06fb37c303013fd9b603e7378da373d03c127f1de84ab0f14872e0c93932e44f1e89d639e18da60bf29f170085ae3ac1a3a91945352b8b6b506e1e976551b65b27391ad60697e5562d30496dcb04f1d1737c7dd4671b8ec30d2df408ee9fcc43083b84b1d4a774e0d642edc5ce4ee356a1b580d7283370b4b3f2ba83f834ec10bab81718bd63d523b4a8119de268cfe0a926110613214730015e1c6d4f746103bc05b6875e9f0d24aa558321884f5a9c9a59e6032861510a88d82209393d9009dc2053ba42400d3dfdd2ee44f282db4a1b8c8e210e174bd9b7b607adae623b3ba9978cc06a966d6fa7e9593d85801e383a1b4510ed92e0eeae996813d5d04b68673d45788beb1a96d6b73bcc0185a42ec83dc1a6bf6f3554d357fef223343051d5fc843e39f1b6aa2268a5faf6dac007afaf0c2d0bac99416ce0a6052a1c814b8206c0954bd0604fbf7b42e6b9a2c87aec75ce325e4ee99224d9a2a814cb82dc82d790a0031fec053a08e1233e9d6e84ccf78599f12babd571c89324d24787870ce7ecca24368bfb35de12d5d892e52203ece7537d992b4a4808b99b15c5c2e464f0478018f6fbbff3e9cb1e7e74f01916b729719937ac906184661deb684caf2d443c541840c324af49c8e8c4356b00db2558f1132eb44059372e43283f8a8a9569826a3de336d37bf8e8d1bbe1a5b6ca510d8c854e6fc6e5ebebdcc4027167a16ddc6dcbdb5b73d5f53a0af2af3c72daf8e9544cbfa7d8d1991387d0f02f1cb15c4e26e90d3b64ad3fb7d80e6befecd45b5bd6d78c0bb643a070ace6cf0875feba45364f8d0f3dab9cf3901db987c6c01e1af1a311c6095b2d0897e97c693af70c65242698e4eb09c5f43ac9d1af01f7270cc6238984e244feeaa315d9a5549c4628b05db67f2fa70763de0d783bd4f3f9b9e684af7cc1e07e14e8463d0f17161bdf1d7ae8604183fa0ce30736b881140f1e1d36d9786c6ef54d47d6c4ba7fb56850df40668570f3bdf27793618f1fa4803c5e42eb1a8de93170cbe5a271f759f8368c551aca8de0eb62f762e48dd3ca73778ed1226b3b329d6ddf20d4390286ad7b9a9e798be8103cdc81ecf8d9e3c7cc903994d5f0153b36e30b6c67857a0a63355f3fced0317fbdb4c6fca7321364ac5d93ca3d21bf97265e62ba469aaa0fcbd1fab7f5bb8bc785d32ef39e82b5d75531b1ef34be21ad334ebbb65d1bd2c05fdbd4c425a80befba8376b6466c5f3b27e1df9235c0ae79fedaecc4197ad76a88256a4f9cc78fd9c60801d3e6b06bf730c0a1bfa62ab02cb6ab2e0b27e22024b8e686205f15f9a740bd1fcd21e026982ea2ffb94cab1fb8ac0e1c16105ced36e400b5cdafcb70e54f12aae3f202528d1c396c60e05672346b7aa0ea32a38911af866e1f67beec8ecbac9bc69619d83958fc4282116b87039e49706331def7b2c7be871c687971dd7bc0bafc961625c691f33acf5d8f6d58a91aaad720fbf3a1db11b323980f2cc121ff20cf5760574626e04b3073d7b7922c1d813e5ddc284122adb215a6bbc7a70302e95c5deab91f4cc7c7ea1ce9b2e39bb4f215ef908c56b2d132bbf48dbf41095c2c619c100613fc08fc7ea26a717b78f91e083b1491a2468831ad781390dd4313255dad67e0e3a07dd6b546d5a477768534abb2866717f3aeab75b38e9817c0b1f7a9e8868a395238a29593b99569ef4c964ab6dffbf246bbba54339eb30b8c247bc1b2a258581bfc7742b08b59552de4a0df9fa6d56c39ea8d8b799fe757fc92f75dd7aa7e550ad11f897c3cdb9d14e56e9aef5ec9dd62f4cbaeeafdc2801c953c1fcf600b2f44396195909527b2b8633e22e386bf8a95d41364600f7092ebbfa3eb5b6f56172162e2c2a3a6d3311ea85c31964b0c8be326c905c6d059c3ac54ad065ea54615701855fb343d3bebace5d763cb40dcd41c8bb2180b91f4c8f37753366df1fb9911e70a34079ea08dea7d5224afc788faffff5674e8d051b9b980a8211659c2466571ad38668fbd9b81320f4a4702728e2d78c92b41114e8f5c37e6e875cfa48802a74b2710c123fa4093dadd77728d40914e3e112ae1bd420ddf13afe12c84a8b65897a295d0caeac7dbe0e293895cfd50ecd4a30200719a9e011bd4bdd5ae56698483b933bb73dd6e31751ccf1ccf5978c65b94426a53b383d0111764e2d457bd4104a254095964620f1f6aea7bf8eabfb9c07842fd3629441d233bbb5c917ba57355f4b4c7a134ecbd29802c71e6872fdb102de6fdc2c34ba3e22b4d5c2c69d1871921930af01e0a2d9b905543b48fbd1997b3670a71b22a9db872ea33debd527506967007331e96b22acdf907da0ea216d5eac0a7cf2e11b36de252ecce8ef3e259324615c7335eaa413daddaa9cd192167aabcdd865fdf7ecbbeeeb05df8dc613baab95bf116b606f8c5e557a204d6f2e593515a4138f6295a79b8413868e83e729a14bd5e94032ce9e970166d359ad6fffd7ffeefff1b6bb11da8ef9461176e7002beac6645c99ee6492952f6572e67e319676d7ec9199ee21dd6678d47bc09505073b14f8af949be58562f79cea794ba5fad6c52f2699e60581a275887f9dcfb453bdadb94bb3e287c85efa2d0948edd70846ab718e752f20dd726fb2461b8b96cd12873b462a5c813512a61c7f5f75463dacd7761b0286aa2cd01ec4976dc9bf680d0defded4703528f4949d573be72803d7ffd928074d1e888e399f19318fdf8c2dacca5636be427f1002197549d4e170d1ef2299b0b250ba672bed66698ed92092a99b3441ccdc8f2415aff1a30b6a014991860411fb0ae81282b72709777638377bde2e7259f3aa5a24bd98b826aefaa62e102d185dabe32cd1305e9d5f352d5f3fe1c3af64c3614b35b8358b29ea41f42f28ad24aea03ab56cbd2d587136d83948e658f142d1f4e422d16d3a4726849bd8dedfd4b364948bac71e21b35901a321eb9aedb0694df7d1d491c2cd46fda88aeda0e1c6bda855dd7036c5a21d34f47ad13fedf63e25ac9f99fceebec9841a51db2c44a49d2b1cd2404a91092e45db76ed3ca807cd0f6ae2e0bf85a76a82b2dcb418831592617a96a5f6fa9054b5ef57d1ec15c22ca1a87a924f8a684ba7dc6d3649f38404d5373a4971ac79a49e65ee46afffb2b8025125551c1e03a62df858b83528342bb1c39160e206b2bf40021472a0b0112331e008445e0220bec60402e2e3ebba2cd87c399e692f79c58cd155038cf344a20556f724323b3a1466e109536dc2ae257055dbf953e489f3971c974596391f16a5b8c29444ef0238aa44ed3cfddd01a2befcdd09b0603efe1c7c5463a1f4cdf663552cc7b393fc4d594c4b21a50e42e1769de6e3d9ff5c14f31746dde00d602aaa97c5528a37859bd583b545a0cd22ab9a42de04e3321d157245ca0cbf10cc16d9ed2d650ec6583cb55a6abf8bde824fc5df555dfcf9736d10d4931a04d53e681c0ac1082a38fc45508e65ea11ffb8a74fdd62474f47efcedea848563d248a176252456a988d4c19816de57593a061adeff17db1d8b8c3f7c07e3c9c84ab4122d7a99a76178672e634b9f328685e5c099f74ba7437ffbbfe51c7a942bfa2e828b2558182f2f1860d3428b64b7ba5cb56e6ebcffaebcff6eda9714e66ab11c48348f1cfa6f8e7c6f9caaa80587a7caa2d70d7ed1aa4b3a04d877d64b58fedce81b93aaa65e7f95864df2f472348338a6a8f3b7f508656bc2c791b8dc86f8203aa25db0bfbb37fe161ff9cd270c2c9744fb7e16c45b860119384a67e8163bdacd15dadcfcd588f2260456e6673771d66b0c948c25c930f1849b83001438f6e0f347317656e5455a8ff07ddff5c0d2851038230130a9c9667aba28802bb163a5a13ead066a9ec328c5288ed5349b34d8c062c5bf5eab0ee5de235cbcc5c71d40c4dcde1e4b8cb32c550c79880ec90ed47ebfd90966252dc8495f7eaa7582a15cffd1e538f1d2a39b34779c894b00b216bdd6502d52706648273c2a9bbd7891e646e07d12534bcc8d05c04538623196aac75c65c038bd172be60ff82b4ae4771a68af20340ac783915154e4896633a21a21da0c2465d4fd8471c1432e781c79171b477c83422ddfb426c91b75b40aa608dd20df7758c709a202c177efb0f0b5c944fa44f83ce9f66bc5273471ad0a14fc075e788bd2a2a365a6699a894e05a4c069103dc1707d961ed782e7209e580ba9808e08a8dd1f66a5175eb7afbb5fdb1c318138fe1dd108edb6163f32846e9646190971b07818cf2662c16153b39ee7c2aa36864ca1f169fe57008a96e327910e136366fa2da87ac5f406161d74debe6915563a3d0021eff03e1214f405ec813b583365a8c9f6642641bc825a4834039b5f9c9292492fb44bf4d4fdf885854ef322227ddd77d0f87f9378c631b2569d00588ace291abd5dc5ed09ceb5adb49eae8f4858cfc3568e9545ff53bbcb9fa469a972273ae8391d9abff6e066648a77b676cd7eff474ef2c0258fdb772daedd7dbed9fd59bdd355c14af15413d57f88adf2054099c73b622ebb32fff403afd5959cc45ff1d9ff0328d5e0fd7c2c48c1faccf76bf01702f8b7fa559c6efbb7f0051aba313d7d9c575b398898613efa0add11139f93fa1e059f880eb22eb11eda6c78fd93db519326b7a588588af9528292e4e4eadd37cdac320aba41b4ff329ab0a123223e7a01a83ab88a2dfa858bc16a3cbb48aef6d66c9b9c7133c605e4097a2242e0aabeb335260353aebe97dabbd7ec5d70fe0f9eb97d021aecd7d8378ad040719e9bd513b6197edd106ebf659b08ca69dff594447c7f0df83ebf80e6587c13e69dc9b5351bda9a9d7cc23c824cda7a2dcef32fcf1a4867d127074c59ed574500bfda5c3b637aab513c56cd0f2e75acb9f23f063b5eeb90abf5777c50d2ee5c8c0e166e958411dba9607dea2c484f67a35f42858425e6303fd74ef2c22d0eafb3e54b2777ef7cf9f6b67baab358c8cbdbeba8ce2be562dc938fb5751cc23bc518d9a7ca581920c15d549abedceaaebcc71ff2c768d31f284e7b0e3af42a4e76f43857123cfd0c077f723d01d74453af9eec19d44fb88d04a78c4aa4baa8b37bbdaab68c1cf3535228bead0eb938adedf37b86e06b264adce3dd2356cbae33cb967cf35bc136c70598196de5dc7ecf34dee3a88e13cf15b1fe7c9c68d510f7a7ffbcf7e7179974ef34cfc004cf03d71164fc90dc37bb89e33b6e22108d20e791caa495fedf1adfafdf593d43e9fa0f2719b1b1dca98e7ec042d7aed4b1f66bac7ccf85abf88d99580386ba046cb0ad9a8ac20ce0993e02f4ae713c2388ac8bd9be852eb1bc3783bf9ff45b44f0fd81aeb206cb23bd6b5df70836cc248b4a2e9331edfc63a2abaa550ed6ed9f0673b7683f5687750453e86905a10a00b983a9ccb9faac9be7f23b3e8e1f1e0b3fd3e2d39069277e686510565e5fa10383ad17b2e5549719dfb22f6f3e23a37be5d8d8d61d0c0137c6234a62d08c037e762d60a89b9a1416b36c976699046c775e9dc815ecd52d928af92fdcc46dd256069f3eb7a033b9a8d7a137092ff8aceac751cc3d059e3f1b294c86c617119dce448a93de38b85c865cf711ef36cbd509e7a8eb214fef1a648f3cadb0ddac88be68a77a88d665bd76db4eb5e609bcf9dcc7f584384594290399ab42dca32977c227aec27c1e6e97406af603937d01cbb0b26aa71c02ceebf39afdf4d1bc1d970631992fdb7aaacef6bfa5b1620ef254793915d131cfebc3356b8350b2ff54b0a0acf900ae9659c7a8ab1fa25bb4039ecc233d79c8aaa12655fc23f6eaa7e0c7b061e562ba68ad37c2a6db2b95a5e2f12f2b401ed36ab8daafd91f1a918b0af9edc75a9ba4ef6857ff5f854b4519ba283d77df5a456e1c9575805e291f0a9604fbe3a30e3c270006956895224ef1f30a42e18910d58ebbf8a59debaeb0640baecb4a52ab474fefda0bca70a83b123a8686d356c2f501534d449ed5c5bfbda88f5526814ea91baf6cc4224f207f86a5d88aca99bb6ebee29bed7d6ad4167a773158223c959cb98ce3b100d738b792021b0061f244a1ad13803c7dd192d243dd59de9ee52ac40314c5036eae052acc2806b813b866e5a2ccbb1f01b5a8f0c2c0da3a1a83a312f2684717a295667cd06ad3a921d1f8f8594e847a79f7d89367aec649aa3cba66e15737ff2ba734e2337c5a11e2106d27cd4102a8d319ca886653390babd538775bb5e2a766044ed5e6b5c6cc14b299e155951fa86fcf67b7bacfedfa174284aa04c11e1cddede3742fc6932711c9bb44b19d6817c8e40fd2d70af74e0917a4a7d71a5fdafd46db4df67bf2ba7233d430286fff628fe60bbdf3efdc7efce3afd6997b5bed8ff62bf85ec4087481218bf3c434e4b8fd093b49415fb5dcf5bc9e838be31e328a7d3d1889b971f1f07f0d7495e1100b91cc9aa6cef77ba6cff0f9dbab573ad9b3f523745a97beac53b6aafed897dfb2dfb5387ddb2bd1b580d1651c56344be160214370b41b6b96c266ed4769f733aa316a5180b08463cdcfadd708b9c287eb7b73799ecedf5d88f05a5e31f80efca982828e4237162a034ba8606fc495a58be839953abf954965753a0437935ed8d8bf922cd8254b3593aea5301d937836a16bfbc17f34586f1371d00ced738a0f38a6a381093625eb7f4e649b20b02f96e46329fd3425e4d2167e2708b52ab5f5f5ff7aebf8474ea4ff6f6f6faf26a3adc22cbee9b2ccd2f1babef7ff3cd377da8020d9c7d2dafa68eaf625595df1bd34c1a03698ad8a1e1cf9eef21f80a62bb86b08f9a151950a1cfa26a9e8e9695089d6df578ac635870d4d996d1e3ce03fe8acfd58ad926365480aa47a966350e4ebd76678e9f490050d1af42ac7b9ed8a982ff1f71ff861de85456a07df85de6b7adef020fadf1f3d43778af2dabf05481ce0ed5a9d9d41c875bc8b1875bd695de05125aaca0f73a95bf7ad70662ee32df6dd5d1f1683be55409b4f26a1a528f88930e6db8446d499e55daedd8c1a981684c699d8c6690a8b228126df54841f5e645ae049c05afc6104d416db4bcb652442c0761d162819779fc11163bc12ac222b0913a0453291be6992709135cae8cf358d0c8c633f63f4f26eabb3985d519c82b0efe553a2cb2535d95bd035981dc3ff18f8366521bba5e5bb6457b5e2422f3839c858bd4a92d1b70798fb7b66d679af8c346b8b7b0bf830d588d1be919f3c98f475db694e2195f54cbd28a678655d7555d16729745613c6c2093c9a62389a9073eef60905cdbe322af42ef98f12ccd123c034df941c80488f09fa9ba6d6851d3fcc1d778e78af3e50ec3f35dd1295e739302d897a6d160d715a41d6e20aaa786bfbe835bbec69dc76863360b0e185c8d38a4a8fb5b7c09ea41bd9c3ea64d438d87d482cd4017fa75c88b1f53015e489ae8b2e116fc1ccc4a31196e791a83cf34af86aee29354acb1adfeef5940a5706ad9efeb6e553ebfd50d90edd25ff56b566c82f1e985606a2e86cf8ac5aa0475637bdc614ff6f6bfdc254fff2efb818fc5a8282ebbec241f9b34e8e81687573936a6cc85593a16b914094c13d34abe3c79af3f53f62acc5303305e9c3c3b7ef5ee585df385ce5f531645c592b414e3aac054e595d353550a61d3d8b7961233af8eab96a7dafa202179132f539e57ed0ea4a69352949579ee4bc733b682e4a165312df95c95430a15f46e56a7b29deb1b7299968b32cdabc9aeac5699d037917691672bf67b38bb2957ad5a5e4caa4e740e50301c08004a736c0c6c061e49ae67bc62a3b2b8c4c446f0e7aa58b26b5122aef01e44f9f9f41238b3647321259f52f4a511e265b1c08bd3a22c9225902ba644afdc96008b02e6cf790aeee5228780be59314dc7d6e531492713783b7500dad50039d80cc7d1dd8f8b1cb3f37409675dc6bb6cd465e32e4bba4c74d9c4d1a540c814297b22bfeabd7afdfcf8fcf8d5dfd0f8d676daf236192dc4c601deed20e9d283793f54a1c1a25eba564ccc25098266e5bb802b28071b8f0d3b3d744667b779eb659a63be67d409c0e93c06638fe40032359b54e7ba6222ae98c8afd2b2c841066eb956582d9dea75b2ccb270ba8a5a6d0ea599c8169365c6ae7999a7f954ea54ed98ac3d7614c1b5a69c4258917071fd9074bc9c825788670ab40e0f8842ab4df9bdec4fbb8e7b3ffb68c3d14ce5a986bfb37376c0ee3ae1c0a92fd0cbb24306d1fe9118fe9616196cc9567860608b49c9e742be2fde40b089fd03e3ad14bc771af26a4948a20fed481507a468694431e283a86fb60172008cda9c36e7693e13655ac9174521455b2e47cf322e6557b11e51c26f222f5d6415bcf6264b79dd6d1b5b09f1546fdc1b173906838185d215fcdae7e750fffc1c6a68e0fa12589ba43f9983adee163a44419c1f5727419f5a1d97c91f83069c5d2c78357b5fbc155371b3b8d0ec28a244b4b5c2e21ea86db492ac566a7534f4ab56a32a2e452edf17264ddb210b3f35b6792ba6c7370ba7057e7067aa183d7066350936d757c01226c396559aa5d5ca9e0b7f86c5fe8870ee08210ab36f9ebeffcbf9dbe31f8ffffe86f61ad6699fd275eca502cd841c7375708c671cfce24bc92a751e6134799bd15109d7c0f3d9640921826064942ba9df471181a2ef29beb394181205e133b910e39467916ed486aa4a9e4bb5f5015aab3da4ff7a9d56d71bedf18d1255241dca365f20f0b465beab367ae27e07d521874cd9e98dbed1e60965ffe71945f816b2873da8e30167cad1a21c13cef7fb6cb8d51f54425630b864a77334dc6287dfb1d3e1565f09a6c32d883607bf54b9fa650e01f5f1c8fb7266a196c5b2121aea708b0154a769fc67b49718f86d05d2fee70cf9de3ebceeb6875b67b83aa76aacfdde59e7a87d34681f0dd49f0398c0f54e87fe6eb7e9072ce3ede93ff4ef76e7acb3d351bf3a9da3db8dabb64f77b68fce3a47b7d0cf76a7d31ae667bd5f8a346fb76e5b9d2e6b4d7d86f1067639d779d3f57158f26bda7bce16c2503636bd966ae497202b3dbc23ba4119cf64f47d042f6577e1ab1d329ab6accaae6ee7a8c0701490625f7fba1410c740ff99ea9373681e3ac08aa7d5d21f1234007a2eb2749ee2431f75c41e3fd63f7b8929bebd65adbe690d4901d51fd733c5f1daed1214a00ee3e8891b3186f05a1df628b8d82a0873e0dbf274efcc118a88a160c9be535268cfa052488c23a7b5edd58ced60f82c8921c655a109f84302166183a0ecb0395d2887366d063d919964f1341429feb914f9d8247603851f9639e2991e0695384e41e322afd27c290249015f59416526abf21406e84c17790ee1e1895340d288fafca5f3798c4a132af9ca299996c57241dfbf76be63e453587655f407a708e26fa6f2928afe78e660e9cd5262b67e9d2b0b665e682349bb3d74be1aeedddaa91c42cf419187404d9e019e16bcac14ff3fd468217282a0d20a87f5bf0f1daead097621947ced4c5c5d15765a8ab0fd6fdb2d87ee34af0f1b1eddd33071f6152ea2aa1f6e3a77925525ca1ceca8702d6f6f71f1342a5cdc1984a2cd0150c5edad62023b3bc68d0d5130d058531bb8650acdf806f6a729d4b31e985f5dab3451781cd0bfb62f5ca381fe610a34310dd8a347fab7d30a263d30b33fa21df4a39a789bbe76d880b50d511eb1566fbbc506ac75fa8f16dba1061468ce4c05a2d19ded1cb588c250beb741805124e0f9ca952ad052172fb73ac13d38c603fbf8d609e6e7bcf639fc071f30a176d0dd09e64c86da98fbbacbd442b2b4b29b47e489e9d2db37d15de3bfa460952038e3339247cd4956158c33fdbee7c55535c35b77b439ff359f72ce7ff103cf5cc8a849972e1b879dda29a805ead839e84ddc8acff8aaec37b0bf0204bd294555a9ed2bf27101efc3c5847d787b820b2505da3d35a3c49f99f3d133c051b0c587b7276a398a5ce41574bb624eec49fd50a4ab4291bdc99e0e87fda3df9db9d75950c0f9cf4caddfc3ebb51b4672af638330eeff41fdf161a16e5b106f0ca82844c9310c01c8c16c392313f7d8bb749e662081b08b054ce302354524becb8c4b92ec7f35ca9eeafe1f80a87f1796f04ac9759648d841fa22823b0d24341b274c11941e552f9c6fed5ad8c62f21cd43604fdad359e69cb8d811def3f0f885339e6e257885c3d8bec44b888d1906158225d62bd9484c9458843b91ebd1471fb43dd07e9453d7a8096ae9e0bc2db417731fa069d450c3bd7bb6fed13e1a606c5182d0d3c7c60e6b75be6875d924e353d9d638ebd415723a3a83c17331fa0590ecc7670ca41138cf31ba6c31fa451da41fef421141a2fc2cc352a4542b5cf770d7a893ae892f0c22455e44eacdf1ee5c178ce2e0343db36f3be1c278064ededb833ee9a09a6b84ea4bb8decb916b9ba010780a8d41a576e6d6214eeb0f8b1a46dec430e49082a4c593c0605a09aa4a40c913233c5217240cd93ccd0140aa5e33c0f666df7385cbdaa4633889bb115b85f3fbd54290d2f958db310db70cb1a3127287b5865bf4ee4097eb961381e42eb20018d607746264c85143e423ec01e5b9cee719605e545a4084c3a11463915e89845da816fff5eef5ab1e92583ad1e3528d2f82e9f803857aee2bea5e30da7bc922b62e4d0edebf66ea23c1c47c51ad5a9d8044a273335bfa17dcd2bfb06f993bd703f68bb7a3d57f9a9a0f895520724e7f39ebf874080b6c196a0f9450d4b853f7b75c3b67753434cf1b3af1ca1de63cdcda800ef4b06a9450db5d7a33b67fa13c1747debe6403fad3bb0d181e1305ba8689595c2354e726e2cb299a9207dea274fcddb8d96a7c2af53d6c15b09e9e1fd4b078773010637e2146c34773d5661809187f8c3a5dae8495a5922405aa65c19e0fadca9b6f20e6d6719ffce8dc0923d2a3baac3936b7bd9deda3c37f3c1a7cf1f1aedd391d0ecf6e87c3fe70381c9229aefaf9c57eab2603e24c4019025776d519aa5b46a43f02fbabbaf69ae7099b0b9eaf9f2c5dfe379e2edc99591b9af9f3854fee8c0f1f0dbe180efbedcefa193ead2a3e46750f6413e112d4e168b58e2fee8284cec83c1ed1bb02a3876953801a4fc600687039f4df225c131b3e9efd550da25d0ab0aab7f7c01ea53a217036837a309d1f053e688394086c97eba71188afaecab494569f0e5e521bb4b80d0b833db5a317d788b2558a5ca6557a25d8116b818a236d8537d66596b16259e182c0b0f9064b40bbd12dd2abb0f9226037fa6d0c7514de52f4fb6050c1592ea61ce69115c5259f099e58e6045610c186b15716fc939ee17ae42e010ddbfde1b0dd3e7a341c1e75fad38e7d60c7266bbd4aa893b8840c496f7cad9ad6aba57eb452d0a6812d93fdece8d18212ab440ba31b6b1d5a2deab156a285055689566f421a34d5b961ddcd371fbb91dce50b88ecbdbec9324ea95bf07eb98ed23439d5292db2dd4dabb59baa9119288031328c3d95289cea9792a68b2bd05a8c38a0b1d5bbe93ee18fd3f42cec95e8d555cfa1ea1906ea5f66e92e8b3d98b728b8c9c62eb2f12544c8f1457c064ff78a61abd3dbe573a40c84c8e7ebd47d1b318d5fb794d8d7266b19a8fb088da8ecc35656dbe7b76f52ddf8ea4f7ee9a86dd4018d1daa8f9c166d1dd91bc18df4b06ea53654ba4504750eef22d8ab694f1f84c5c042c0288f6278a4c4d9782504ba31d46e1519fd6d631c60d675bbcfa03ebbbd7550ab19a8798b24baf79422f08bf4227a53a0359ea317c10fba18add07599faebd121857f31dbaa5882f175ab65d5ec901b4cb0e28aac0a9df5445316562ccd86b4e2e643d52a6b952a9baa5470fce6d190f48fd044f3ef88ed947919acb722c9bce356b70f832d577be669ce5a56d2b767a11e87a7286ad214e85e766c37e69660ca58abb3dd6ad051acb9b63b3a8ab872a63e45d377abdd0a46d0396aadd7c958686ba07840cc946ad03682154389210daa583fcec327468f1a9a1eef3bceee923fa5d5cc7dfc873ee90d7dd7b434ef5d8a8813fb6ca9375c0e7685b499e745826e2859565c338e8f018c57fa754b5d194096eb790f625541d05040342ff079626c70005257c146eb759656b067c7452ec1a360bcea81f513542470a964573c4b936004dcb18eea82be862c8ae76992643a9187fadf7c5194151abe023c9cac002714982ca55462c3adbebacbf7875b942d246f55e62e8e4568aa33dc322f7c8f1069f67982d859bbbe3847dee2ec7559647d0658072408da0676f9e1dbe1179afa1deb540c2ee58e40ede12fb09a47d076b57d04089d8cb0760d9656e8e712739e7069802d0a29d35126d4657929f19c5d1474fff1ee0d66edc864c27d9ceb0543274a7cfc3842e3fa52d53e3aaca1e7f68b4e6badb4ec3d44a8e6d0654d528bcb62af8a72ceb3f45fa82d98a657824cf4f054e87ac2465d3162058fa7396a16492a1ff39c8dd42e9212edb7f54b2e9efc68bd0e16dbb3025242e24d1cf400ea8b40bba144c8719912d3603f80332d0467e8d2ca5cf4975294fd419a5c74d905244e05b0006d5ce4154f737671fa518740489356d7bd19b5faad6eed3ee45f83d8ddd94544c06a23866e11f5b720497562f7d99a90650fb4fb1faa1f2a70b997817542eb6f41d8d2d6042ccd65c5f3b1924b705ae1cba87fbfa769b9a32361570faed30998899e29d82884d0bd5b5bbb012cb45cdf69d74348e04fea5d27dc4ef4a5e6133a410f98b659fc6b315af0f1e5873cbd12a5e4d94b30d77d2e26698e81aacba2a8ba6cc2c13105d030acd289714cd596c6ceeba793101f8d7ffdb751056058d52c95a987b6b67e1e6ecd8bd1cd70ab03be6b15f9a7ea7ef1c5288823a13ac6821e9f27d4117e680fb75e16a39bb7828fabb78ad795c3ad2e3bd59d9cd919c67a8bcd92c053d16904fed966b342380acdf702b175865b101ce4aed3c65421c60ce5fcfca7e3efdf3c7df6d7f3e3bfbf3f7efbeae98bf397af9f7f78717c7ebe777e0eeb47e4d5df86fffacc10431b174552cc03228def8ba29255c91770026093610586ce3a092f1bf3b1e2c64e399a6dca0ab2432251997492ba5a0c2021ca4cc8ab63fd01ce6970e754fffc9c064f893da35d4027cf66627ca936380d1d031fd62700541ecee0547772e6f502d58795cec4dbd84893fb41d0f42e324cadf05047350db5ad6e7e0b88c4686d3160e49d0000d944c2de5b331e0c2f1fcc221d305da15b2b74d47941094d6d00acda9f5dd392c3448f6fc458893b95a5a6e8da6b96e1a21322f6f89ca44b40f4bff67b84663a6b47f643c6a7eeb0b86459c1139144c7d5cb6ce0ca66986f750c3561980abd3c2094a00551943f159f7aee62dd853b0bc32639fd481df5aa6dd14225e7e73e3545f0d69ba305a9aabe663fd77a8d6cb318f4718468d7744367c1d48fd905d2e38c97f3225f695cdfdb73e205dfd394835ec908bfbeefd349fb510c56e103e8c438063926e10c4c04a5a0e38f4ce4cbb928f9281303203118cc40cff8aeb39e9fac63b984bbf3732111d18c826c6d82ad3282ad287ee8187db79a8f0a4a29623c2ae0d4c61263b7f69e229f3c0c5b75200a773a140e4eaf752fb6eeeda66591d5723a50eb5203be0ef563cde127fc52d89c9db431c3daa08d78ccf6076482944ac6cd119674cdb99936b57c326073514ed1286e6102a829f64310f58992cb06105f0db4688a2d20a2a55670e472fdc8ff74bb3f602331e3ea429c5e9a93fe5e2af39c6aa163e0ed224a691a4d1d63a91513154c808186e67fea78138d54d435bfea38d2aeb6f1f24561fcaa7ff42cf5acef04fc2364cd79514743f4ea4637673b97b58a71d2ce155593317f2bce6f88c8712ef52d6451f7a4868f47aebe7852946ed43ab23189b2e23629fd1de116c3cf7968c3806aecae374af38442334004ba7088d4280f8fcf353b742a7460e163d8fcfed9322ee60b5ea523704344d55e5ee4bbfac8a1e3f15ef276b316922c53a76c784c466eaf0f5e8567920b1cee7d54639a66cc7636aef330823835cbaf70c9066ba160578812598775c0ee36a1cfa48d13eab2166f99d3b561d5b074f395ab0579f4631482e078efca14eeca14147e561b8c38d3dea4b37a7b1f4de104ec7816cb51968ecfd535fffcfcde312f20ec188416bb5f2a7c51f08489bc2a5746c4354f855121808a622c353618c5bdf6bd25bdb3a2e5afffcf9d4ffb54fdc1f698fe5abfd676992ba2c4fcb2d75e9d75a40d98055c7fd8fe26bdc52f1e8d43a863f6894ea5e877fe646de71610013f3f5f3790e1968d2902c4133f5122504d22728d3386381b3071538932e719fb38dc2a8ba21a6e0db4eea23bdc1a17f37991ff229fc0e779f8d9ffcae789f3e10eddba35fc7305fc5c013e3740cfe7ee9ff8179f27f8a301cf7b662acf5ebf7af6f4fdf1aba7ef8f9f9be9f4fab21cf7655594a2f78bc4219c8f310ac1b9d63917659741c8413fb4df3928d340675e3ef7cf5e1d5955f3852e73614188a71bc80001da575ba6858703163fd3eb70fd63dd42ead9cfd0e1249d2eeb95dc822ebb2ed3aa56457f34d28253e620801d351420a334531eb0ab224dd81e33f94c2d3e01efcf78968136a7ad95c15df6cc866b304833c5aed2d8ada86ac66c54875bcf789e17158466671cd3e1a3dda051516c41c6e86078de5aa4427aab01eab5a8e18e2a0c5ee8e96954a30b1e5f8b05044c8c2f213b6cf87e7b4bf9669a56d544e553481b6ec11a0eb79494e6525d64bd4dc3f594e8b404a9ce811a41218abb1048a3edac15a0b02a1470d985b046e9f88d462ac5d1a1e24e641d1c48f6bc7661760e74de150b782d187f1007faf4746ad488972f16d9eab9181725af44f2dca021ca0ba05651ca46bea0090495ab5ed04e07c3bd49511ef3f1cc2afeb530ad2ae9c8c6b68116ab3b482e3e813d7a147ca34a01355135f72b62b705b4d5d2a485aec472ecf2023db23a91dde9d95adcd05372a7578a2b514afc952cc7c299ad6ae4e0d311dfccb7065edcd1e33b6077f4e5808205c322e0ab833f7cd07120fb323331ae4361dda3daa7064e78506febc54cbfc394feb53ade58363d2e68a2846cc8e6c4ee2cce001d8d87dc4f1841e92f225b88b2dd40b9b50855b427d27c4aacd658674f789a89a4c7de603e088ad30571535a6c0762642d0ac9b35d68b7eba83752c9440ec99141b895a262550161a4b2a290a098143d04f21ebfaf819583fd3b5986a80b9fbb3faf399971003050a428ea98f35f8a9229bac438934e1b005841ccfe5e4b1f722859e0f3cf3b256db043d6c6030f7e29e9821d2ac9ef77e7e76f3ebc3d3e3ff75e7375ba0df3c101d5f66cbece21c4dca14ee88105e1d18acf4b0e0c1b4a729d5403ad865b5931e6784c064292aa6021a9bf7ab35442ec3b933acc2903ef72378abb068cecd78de77eee0243ebafb0b20e74e5f7411e059fd48df646f87fd87bd7f7388a6371f85f69f8057605eb9565ee32c6c758dc59cc8b9cf0e627e98c67777ab563cdce6c666625d6c8bfc7176ee11a7e2721f1216f1262223be6662e3e8091e083930ffe22ef1ebe485ff6d19ff23e55dd3dd33dd3b33bb2853139e279b076baabababef55d5d555f96a9af5944adc4cb4b35ed1cdc4f1a01a2b4689b3924403b0c54c4c0f7bfe82e95b799171f02c7c7caca2df4c3323065cd3ddf2670630f618ff9509c23b44faca048d5bac26240bf00b79851b91d642894c3d1f19328c93e99b0d16bfe4c978da8be5860c71bc57aa7045972e4c2626181226e61333b74610d5ebe5a80835741b7994af1ff6885b8470634e0a09391a45b1e25bb8d48cddd3eed1e208975c464aa468281c6736c3c2360b99935297fcd455cb6853d3377bd580faf3b0754fdf3c3353623da3ca27a89b84e494c212126321254a92762c6934a4d462d2d0230a637874da3d0a7db4a9ce48cf876beb13930b1dd01ffc209fa5a1a46cda2c3dd0a204dc4894063366f75089b8e3d650208e2737d3754db67c6a5ab1235c55e619e36ee3133e7115b927106eb023a8297b26f28fb3574d1e47f6179fb02fb84f30bb229919e6af1976cb16cdda2e64d748413a46898498ff02deb66686c5417844c56516d5456249834e33ad45cc1c4e118a054a29acf7d111949f0449998cbe91c1f2a13026452719616cffd1445c9381326e87b91e4054c26b347634d7f37bd5c3d9bc675cf479e59ea1a4b987d0acffc43ae7c433634fa8580ddb12b7cbab1e56582e98c806fcc337d267edb02118b0f8898726bfc88f4638f4bdc865385a98b27d05556b1e337c660aa498d7e1bfd0ade6a3181c8bc7c062af5b04a0b85a1336cf2c8e9658c7fb1ba63babd0a9cb8fb893386e0012933c8c2230b6efed8e6b6dbb41bb0a33b24a1ff6bde6a3c9569459ec8ca2ae76864d4b57545aaa387a59212a544641241645b00e85b1c5687f3e4df78a92514cf895f0cd8527e3e356ddc49e3fca07374523fc2788284a284a519fb03d3b669660a499e378768d84c4a0757174da3377cd281de0b491fd8725c640cc50b6b48ad77ee0c2693b520c187b531024154a6ae789e6444d577b27abf57ce9e9daa04c36515a1efde8f76e19424285c2b06e82ee96d89e46947474e0d1867eaff05c1b45a3e01a9cf6913d894f99025c91d36e1bd5df736975f1d3374b45812fd079f695793471eb3a8018ede6b549aa7438b2c8cbdc3139b1eab585745bc36d1777a32f764203c776c31d961da0a2c7f57654ed70c10e68097ed73cd7da6106813dcbcc96619f3c5879924c1ca8a0443ff98b47f077d3ec10342e60eebaa91b0abfe4c4a1f3d4094a5836f062237f8fd4d018107d73315d8eed062135f9cb0a1142857967178151a65ddeddfcca94480ebed0763c109a1ba0dfa292f5344f2f0bc0c802209951c482bbd3e59a2dd3a7139caea7f18101ece72a1a645d0003595c2437dd34ac38ab8cdcca43621dbdb974337b2c4230c0249c0dd633b4ce0ea4427954492dec9e7639f4f300ff50bd4e6b2139caa17d6a322ff58957f8661cee14b53875f447ce0c4af0661dfd0491b6dbf4dadc93bc6cf85e77f96189bebbfcb6cb435937684661f26fb06666e1b4a24861103970cf1acd76409fb51de7e70c4bb1ee4aef703d9727c39e23770780e1b0455d51d4c8d429c74df2433ace9d881acadc37a5226e1372b444a66612c38503002395d9fbcff0588c26f1699df53c3e0d6a52cb3643ea7438f36131f51653622d30d62939064c9f79b04109541981483dedd37aae6e96ba4f0e3912f95b02fc7b78dbe4084e22537491129b4f36127986d6353d55a14daf94d965f112a8c030504b9eff3c498593668b0c2b25b3a1c05e7ad0f716028a3ac09ad3c627488fb97076d3903cf45ccbf17cea97c8fe86ef3569894c9a75d3b74bb8e13d6cfbb4ee3dc77883e8158c451db3c3eea6eed8051b28811d13dfd1847496857e47cec0e9f0376135b31db0180002c49ba77eddf1165868045850ecc10ce20e880382800fb3c625bb4a6377de53baf3de3b4a77df790f6906a4c8bcc0efbab37c2fb1cc4e3052422c3e0dda4ec81e68b337ac7693026095422265c6bf963c05e37733f3b6394e1a61d80ac647472dd8c441622837bd23b6e398184e8dba3b7e3e396a79b560f4595a1dddf7f463a3cf62fcab03feb39e3f47fd471caf6a3a9335af4547031a1e64d52bd11b2afbfe5f63e2a127f7fdd2a84c923da462868d72cb5b28ee2a913bc646c80e329608d446c3fd0dd376a9c5b1717ef7195a2f91ba5b126ddc1756e4b7fbd88b1554b8c6f964079930435a76bd85a2cc21abb35a14bd7f8f4aec5e1237a9083573c01132aee464ee409b6a8ad8776412469897fbf4fe02678eef39b043734b6360767928526246f340ec414ccdee7448cda126cc5bee2dc6736b34635f2f93a7e8824004f3d9ad51879bb030dd223a274547982ef7e238ca7892019b91e80869e4ec406c017ba4fd8087b70d3b2d5845e855d0adb7036a912a0d172875d9118c714d6895e0d3cac7269e48ca70cae6169d1dcac993397cd0577e6ae4c4c4e10336226f877cdbd3e1c407d6805096983041733ce5a959d60ccb8b479da94ae8a8688dc85756d3b27b12be8476ea423bf1076ad1f88ca881618968cd6eb548c6ea526a1e1dc5978418c2ceaed961a70445e50dcd0e48d0f0fcb0440eb783102f9a4ce2e25349012379e9d3adf28cb53c280ed6b0e51bef2dec896802e1b4d6d9551c958a86b88f9494fe1b677ff23223a53c5ce1411f38c185060d1bd457384038a8780f35d9b896c9232071c249461c8ab784b4ceefa6e16c628f42d97682ce79605bc0c386317e2002840ddae1214c807934eb61ba5abecd508b9d64d576180588c10743016358c53da41d00b63a35f11d708904ec853031c9a1a77daf6907f4109c869ed30e9547b0ffe6477b66ec0203108a74d93f79bc133115017f3b528b1d6b72ac870e1de28c2f0630215396199a2518cc09333467d88e83f709cca25802cddaed22dc316b5b1c217b1ec0f9721bac711ad61a504f71a41c36a85b2cba7401aa53a0223f8ed23295f288a0312abc3bce3cca7f1e65f4f23f870e1dcac36546f5c51b7b536e28ecbfa11ff396a97d1fd9fbccbd58cc4e3e54f2de7bd5b2400227e13e43f48240842a225ba225b93071e80748693017e6a96b53387e1b9e37474c1fe3981d12850f118b72169339f16c99b6cf0507c4a11eda5391bce7d3fa4c51707558f3e1007939e4e24066d861bad68eb04177585eb3dc089bceff12857740f608315b7699b9059290b243b81d5058a1e833e59038550f316eb6e3b523c9dfa741cb73a317f9200e319634a02c3498a40970cc23b6d3e131c99197452f0ba6cbb79472f6b29303fa9ab5c633b4ced79ea0fc195abfffd183952727ec791eb7ee811c4b0d4fba28982c1bf7a810e195d74c87ba9629024c3ddc769cfd3ca92c7e441169a5d27c1a1513cb56a02b5b34087dafc3c88c5625cc438e6c26c6c671dd6fd9f3d0c77b9e8ffae128197d405ebe57293b4afd58549d2ba91b9cba060cfa5c881e3970fe4fdffc6f55b34a9d51bfedc2513dda40bb95609406cd510e8956b1bcf4d35eab45fdc727f9ea69e167f97090d48508daa423b0249f8a198b903d9dc5ab0356d364d8e1af67a1792daeb6192705b38ae70965811042af354e0a3bd98743eb61fce5b54c605ae2849687f2200b693a4e0aaee7d202d3894ad5eff37d6f21aefda8b44308e511ae021e7bd8a70e739417784d5c52d4c7fd43e43369f269d15d4985c2f3b00ef822381a1717918d0f36224cd9a5d8583ca40113ce08f03fc53fc20080b2088911c464476132d4e20f7a1e482e4795e2c2f428f466671d26c7300aa3396ce2eb11cf1df5ea7505dfa41ca72072b70d624dd41b1c95e8de38331a88787753876238e562963d6c3f07c25840491d7f897416fe7858f3717a3dc43b01b5b3ac1bf9bd01f15c1eae1af663fb0865a19503b6418baad86bd998f0615b02aba2989c40257572087387981b307c14c5b88555248190bde4f9a3649ca547ac3000ff4c0cef1efc14a31dc1a8d931b48c1aaf2cc71500b58e7854792d51421c782401229791eb2a54bd30f49a05515f1a134b56865ed42a27c6356b4093e5650a987394710d5ca263958923ba574e8c3b59039a2c9fd9e15a8c98152f7c5e7b94508ab93315442e939e3d0a8074c1c926e563dc325da30d60aa8200f762b4aa2d4668ca2626b2976072525989ee8ef7a8b506b5da0ed7b5aa3c888e2d455bea2469917c2fc58aca8229ab3516d588a282698dd65e741c4a9289f05b29a6e93849ce58b58ef1c43707f2dae181fa83c0bd9abe4d03d5ed28c6cf0bc675072e8730e343705c7330323e3f9a14016f44d4a0a99d332549a09e4ce58fcda01e699fb48cc515568d5f0243912635dd406cf9160da9df04c19f7b8888ca72d303b365fa61ec08181f0df007a8e4c14ea4b8904f24718cd801f1a96b5189996781fad95d40b42bf39dbc01322e7f03dca466d086727618e94798268edd7293d0b76767d9c9895412dcf479a61d8a78bc016ce9c06193a61d980e9332389b4526f1064f8c34f01fdc608289214040595c990f94bcb41314662676b8b4cf2620b9b4357adb6de4203bd7191b15d9da0dac35efc21a1d4d5c8cee70e973e10ec776f18ab4edb6036aed88dd6a05fa0d71ef8015cace1b25927d501c21e3038a705a9265926b5ba161268714cc041a4ef3e2629afbe39133204f39c635213522230361189f5073b170bc6c37d56ca5423640a38f447e498a61ecf03d2963ebe595c6cac6cc4ee5f299902a86332ecfa70efef4ce98389bc789feb48d881fcf687749d6376203c7d91fd9a173abe57470371c57dd4ff2011d8f5d9d723d8e54982d5edc0a2bbcd22c2c9119a7f8cff32d80be6fe74e25b9ee4ac69d75b768a10e2a111e42ecc5c5447ace434502e74743dc7f49085966035aca2c722330d9b8a589dc64b9a32506ce6a1849d5ac9c4c0829a5a4a053c7209668d856ba49d2bc4220e57491e81bd92d27a821410488b40ec81075d7c0ad119fd4a482e70cd8a9849662770ee8f8d181423f33d60249d965b29ad3214f1d38487cbac36fbb2ebb59121e9a229970c8e68d72fe8e86e7cd05a3f4b986d90e4054db61d156106d9f9c2395567562fda636c8d4262158465537187013724917226c4eb81ac2f29a3b84fe4364498a0d2eb8a56159c626542083aedcf17c89947b0cecdf7c1a84a61f8eb2ae4b42490878fc765e8e7f49f9de824b7d6105135fd587b6138c2a79421bc3fcd13e413bfb59f4ab5df7ec1697c7ae8771d1a3f90cdf30a78faa77c676f024ad87fb1dbb36875417f1844c848183a472b51d861e73b3bc53841097d0f03dd2cac472d34d2cb5dca4a1f904edc089c9124c2754be6ba1ef280941c3ae0348e252f760833255aae785fb1d2fa0879846d8a7b330e67e403a5edb8f0d7ab8c42eaca7626b02c15696c9d3de020b7c4dc9a1fb0fcc53df313ba30f1c8af5c5b1df5abc51356b0d9bcee36b2d93f9e96471afd19f8cedf9fc2246a5c30e04bf099cacb00f62e1b8610764ae7a6f639611662d8c6d5e60a689bb95c808ccf349c30e39d134a81d2273b49372f2f9bc50e80a6dee6252ab45644d16a9b20db9a3e010e37d94786ed4eb0a842794553a4d5655e86222d7c96c13b214a8c833be80aac1ec3cc87a0c699c385061338385642d2200f0063026de825b2234ac8d601c4e66d525ac4103828799b86d979533517380cd29c9edbb46858c68a390d7c5b72ad62b6de490729a74d599024c1456342b98152956644059d4f7b1372b9edc0f8ac48f7c522cb47b2e82903d723fc17a855d46520eb8964311ebfec847b75ebca7ea6d3f3bfc0ea2813f46f6ad03035c2cf00c7ca10b897b892f9d95e3f0258e55bebb166fba49c15622859860eef7dbc227f490c02655b51d12cba3017aad46e520374bf308b754049130f4f8f34c65f28c94b86f6ac963b064d48617adf3ccaadac479ec7a162d08a2b306426207d4e6409fa7f65e7c187c537a67c7f4d81654ed165ae60f622269d3a7f59911dd60b251540e39ed50a2ec34ac4912d7c4675591aa625b92862768e7e7adcdd080a18bd809b9678f7a66e6ad7da88c18ad722623c6d25f86d08786575e8d3dd9890ff6a22f1bab88503fc2913df33b6d07d17e46020f7db4a3912a8f218a5e5a0b314c897b7e678a0ddc1998b653b8010f84095c343546b8fd71953ade42644fc226dcc4814acc4aca9a99a637cfbc63870d4e04db90a373af2ccbb90c5ede1b84d44ef670d28b96572b29fb5d49b3a594487c379e42bd599c69344fd04ebb9581a630079985923c2f650c4daf6a3b9499483e6ad6e622bd047a96de2d47b228786ee8b56b0d6424990302af561647fc43e24255ba801f849af91d608ff5014fd5b33ae55ac3762c9fba23e5a6d992d78a2ab8f0f9cadb499d1229e0304267144ab8c14b863a23491dc6600be2ac31978421cde8a57295419172337b45f3f88c61d2359de51475ad94f7c65274b2e799a4529a325f6646042f9db83892b7cbddb150840b0bce0d4944d96179cd2152842c10a52489ac2bab62c4f51ef0d529286cc195ad4b9056aedbae3571a0f29467511d8ac495f7a6c94d998b0cb4e462d2103f77194f23855a13a9b0ef4aef2184336f41d51ed53368c6ae0e25757bbfda4d23b81c7727aa62e5d4879d8ccbf4a30b1781ffd65b65b64782536c7c12d0c0671cecb462e78e3eda9e27df1333f170d0d303d30e1ff6fc890315de6dc82bb38eb4641e597771926d6694188add89db0b9e6db101ccbac348e68e894d1639110987c26d52d3773acff03e4c53c179080e34c2eb8913e4f7f843d984b8abd8b8a429225277166580a42a3b062bc988f228b5513f409f0bb31a1dd32ba06edab327835ade1d1c3045254e903479eaa85ba97710d76607c3df483e6b870daf1dc6fe919e44cf2ac3510e2abe497b1b287d102db1398cefb576a069b604843b6769a0015cfeed5fb53dcad4514930895725d49fc5110932cbc6206a517ef326bd3161292a542c7f49805162e2e98abcdb243462c96cd94ef0c1b6ed84a8f0f15ac4ab93439195cca1128b40ca743b8a652d969cf5a9c9a31eb583d06b92d0f39cd06e891292b93e2c23ae23227bd8d000a3b160fa966a92d9625ec1f0d164bc7aa078ddb15bc2775a193eb4b6132c3b7d93c21976ea3f6d5af85247802633625d03e6ff8ccdd4fdf8663dc62f254a97350aa4b67c5a0192868a1062d44b9b3f666615875152e2e25d9ec749e3c4a27438785e18ddba250bca474464e3a7018bce0a4de5bb06d58e571b99d5ef4ad78fda6f2d11bb542a9a62997183e768d515a38648932a9292a3c167c5d4033b313fe252a150b6641489b503034ff89b1874d0f016e22ea2cfd9cc5839ebe07e280da08e873c9584b50acc1f297998218c1e8566ee6ae012ade6fbdc1ec9a84b38ad90e66249bdb95456031960428261e4b845146f8a74211e8c93b88b79f6662e4bb93ee6007f52a7bf1e6cb16d633cbdc32c2e92bb22b948be864ee04dac8f2cc252b7d7d2adea4d37c94b4bba0b8c6eb8e5fc58588b20613fd5b74faa0380723548dc1732ce5436ace166a8f1cce017a36a174c6ae074d7a22d31b9067231c5180b860b62354edf5c22d3374b5879381ec1034b8b535190e1f21b8957a2acefe5af7bb8324fddaf8189bd499416d62b119258317334f9b8ec51dbb2a89b760cc2d28b0390c55433623cf721b57e42d48c325a0188333872cda372aaa86a9bc077376d7707bb0f52f8848586ed5062878580c4cdc77b567c3e256dda5e9b4d1ac615c43d0e4be7a0aee704bf2edd40c89b8868cda3b645a38522540fe3848f892f6be1134913ea8d83acac184fc2e21e13293e23d9496ed58814ab907559d5c3e751d04a7c44e976c2063e47a89305ca9f33a11e3df4ca8ad4273bb18a8eaf86ed583127c3b55645cd5e1af50654acd9163141b2d9089825486271fab43e1e1fb57c52c826764febd1e8d62ee2524f7945972cf7693c17123e6260da46ed679f72bc734c9099bd284585729953fe0806bed31009443c290d47ad2458a4ca1603c61860e6918ecf5ea991d21e3f7db3ed4edfac1930b4d8c1977c8a450d6be03849f445d4ee7192ee02b1fac7958d45ce76316662b263e23e18279afe88da3e1eff1453867584b2e149ee2f1847b63792e078473dedf9a1e914b16829061c21e391460630f2a557b6eca0e5989da7cc2646e2e5c90509a215099cfc5906138908b98d4c5216a175de0e4474087e97cc0b33b851f8c3965424bd96ab9ee7947840dadb6e23932d5ab3eb9de89d61bc514a7702c232845d0b30db7f14c9e4fb0401cfaa95f8a1b86ecfa507ea45216cc772105a1ea94ddc87776ad1def90cbbb58b9f829488e7673c67a4366c622cbeed2146dc21b935d8545e8ddc60b5a1d20b87b2d49d0c9fdc28d3edfc60d447d3e8100f4b8a7b6f831236db88d85479b5b0e85c8b3d3fb34399ec08d130ca994565c02b110f520e01737528e2a94a2c643146808f279db89eba8d98edd06b9aa15d437b26d3c2f7ca78e4c6bc317fe10a13970d402bb68e98b7e9025329fbfc610b6f0bf424f3c802605328745b5e2d889ffb45aa1b7cf0c7be7608f52f4e5bf6de2f660f515a172f2b307e0c697a3e25b65bf7a41e643c68d63a8ac69d731cb078d571955e31855e34e730de1e9f74653249e57939c59442c2205b6e43dcde593b6cb4abe59ad71c7d981ef9856f06a1392a17fc5fd17591da34dea3bc3e1ed8f3e148d3f13ccf101b08b7f82845c9f20257f519b7e94c01f7a610248d20d96b4090e1a44ae413fbb6f8642eee956c5e34e5a2b3fd7932c5ac5066c679b453b248dc76b34a7dc11bdcc6397bdbdce19855ea38d4aa76c6c95e061e8148d06966e207242dfa791491b1b35958fbc82b9c0fb33c47618729dbc133cc2997959aaefb990b0d024c2dc69b66f1c1423c0bec20723381cfa3acd9e835b830298a66344c633ea5cbd152901ff8a2e3825a1be7be70d1712829f46bc5b53217610fe976b3a785781bb799f5a0666506142daef87212917f7101e2db056ee361d93ead854e87bd108bd751413cd0934cc82492e4b628471e8bca9324473a7691e396cf216e76c22dcbc82126311c4a189821f31fc0420b6c4b39b925aa226960e8ce250862863375b1f1a260948d16858cf4093fc5ad95c495b3e52db88599f4212f2a8d6c2ea05ee1a52d92a29ef5e15cf375f54f44d2d3d08d39b6f5c447e4d58e727461dfe2f390a0c18c7aaa943490d554374a43b8b8b30c83953ae4c7568b76400e01c77b48b7bbc26a941ac186755cf61d09094511c1239624042748f624d6b6468a8e884988d1bcbcf829ed0ac98bffc889aee1a0609f74a08ba277c09f146020e822423e40c6c85e5668071923e364e748891873b4c37cf1e2affb319f7da017de58b1321b4c21c80e3236a338e4353050448248ce8f47cd61aa01a6002c9129ec8b19e13c17908f0873a8f4cc38c49679ac0dd881e1f8ff6d57796779e72172e8fe58f6512c483902341f45eece6e9aa1ca439b014c2ae1803366d7158e32c22ecf62beb3c2477adb4e4c65662ea4706211ce80d8ae32e9b8b8a44ea46155988182be4a676d175789a441d2d593d89b7355859e52e4daeab6cb57a5a2afd1d5a7ee0479aaf3edd94638ac0b993f2fa92e9462b7be0b75f5fc905da8ab2fdd85cc9620125c992901b23f42324d9fc777b14209f3038e63f74fed7a9819c1e92f729f2792958c7add9bb8cf458fe720f08bfb584cc0b0ac12d4836640a3619370895bcb514955c08b3c6c5af1152c7c885705bab192b71b802d25f884f8e92a63fce36f89e32f845eab206c4ce248ffbed9c25bad48452bf864e9a294d9b8f0c38a5baee07b39763d1697e1b958b3f8e6d63186b1803c011a6916d51439c4849f364ea91765a3267f447261063fd4ea819e6752f525920656683e33a846f5e9051fd8a2e12b37cb5ea48266b6e49ccf8f3459a17c0f8b20714aacee6a87d417f360c87d045a7a4c4ddf1c2917f02e22462a5d452875cb1f7b583025b2974dce713973713156170b37c41a8da3b4101217707163225da43cab254a99ed913440d0b85daa9a965511f50d0094d9049e8e74a7f1b48840e224090eaf070484a20fe5933857efefc2ee4778e91ee8e9f81b304ba340e29527b746598092051437548be655ca588dd9ba89d9a8a8eb79a7c3202835c53a75dc345455b0242e4b2de1b77089677b7c26389e1b4d044f3b098693a2af577a7fc1b7e3716967169595f9a585c828919bd4cb321ce95b6f2505f851485c22262e49559c0891269ca58fa8dd12ef1219c7affcf9af73de1ab6dba0be1de646acc0cb9836f7f43032df92e75f29f5ca708877a5d8e889fb4ccc34bfe2f99b330b1bf6f650651eca32bfc0237fd1faa39e63517f60902f0349f9d97e21edf04d531d9a6284ab445205f8ee14870913b0299bd164512eceb1185ff1452f9c1c3c949872d168606419bcb8e235c4b16638110ca4ccb5b38ae5b0aba388c596522e2e95f001d16ec52bc400476cef4a7480f46ed36f6208a0090afb2afaca54adb09987e538ba39fb56a2bdefe589e3ea8d2926f23da8815a054c11141f25a3a364d26eb61c4af0df48914cbc3a7bdcc16e194dd7629f4f52739e96d19fbd788652454b3c1166ce0e48d5f7e6a81bfb4f9654d175b346ab9e37c734d1a37610b469307ae7aebbc610251ae509f796dc6b33d776d941ac0d8aa839d00e711a939ae932afd2a4eed8b539ea23baa6371f2d08cfa5fc1e53d2b69b2ede6b97138f0525537ec07e20f26eea97082db11b206a3d85d7401243161958d1b2f2f46a77cce2624184e0bfe3475eb4ec2242549d4d2975c846cec59b04167c87c47ede046c158f7674ebade4a6e89d4f64b4c40047a2e9ccdb538ccd378e8a6d40271cf0b4c904e71f0a1b83a94203ceac428914ea5ead1d1466524200df6eb8594292990dd5879161e24d6482d715277f7464f3a598c90b73af4faaa523732e95c324325d58ef64498b4ceabae881689c54927571c104951a29afddcd7089c824f20e646ca150d4e287cabdcb24b314893891806515a7491c3d482eca2b52e1f09043f1636e8fe2dd3a7eec0774e15999f23d353dd002f126894689c3e23d9ce5fe2899add81ff22d35b919c7a322595f2ad610fb7977963dd7e914a33bb508dac0a49f89e1c3af8418e1b90fc39a01e224e0324f96c01e74da7e1a0a5225207c0f9a86c2e488aa591abfbd1de28e4be6bf936f7fd46990f0fe1d7b878dadc2f8200ca95238ad8e9d66e396254f17e9bd2ce3b41595f74d389caa195c34098af27342a23aea8ef4c88204741a9ee5312483a23d82a6116d9547b9836d465ed457715ae4fb3ed57d8fda560e076a9bec3ee00bb4dd07199aee932c077fb8fe43a246f475461d8804263a10bdca6476a05868c3dea8c7b3357e2dcc5ef7208611b1668b52fd719992c84ed5cf5770beeaf1d627513d2018e15b41ba726641c87253758b8d6158e5519f4baf1be8fca4ba9684cb0f91258646a516ab1c119b924c2f4fd23f3f47962e6f2f69d8343606149811df6b7271ada01ba98cfadbd9fb628eead92840f5a1975539c0ccb0f7dfcf52625a16333460d14fabd4aa76a237db66403556583686d2f11cba67fa66fe8065fae669e6dc0ed86866b0c99869052b3a8b375b702ef8369cac455a9e2d1313b81ef45d8dd636b6db6a8364c5825631034fa0d20ecbf1a109240bcf598253d43bcd4ab9cb1ae2282b764f49f630475036779dc439b6dd3264c47847c79af4b6173734619e7b93e09285646586a6820a7a347a76509ea5e1be30f4ed6a3ba4c502e41550d82c1412811c38bccd1efd790e2d87de93de02f5f79b012d8eb03d8d0f53417992cc08827d52aa2939170ac220b66c5b23baf813e9e61c15329ec2b0610c98c88d8888663a3543c6c954742dca014692852389e0a8248f08c4650c5b77a05ee457fc232894ec188b4f250949396653a4bd4916dff5a8996c310cb5d8e4a52d7fb71690efc6f1d63c9c0226e6a42868f95e8d064199baf3e5a70e4c3c643cf4d42f1006d5b5569b07cf257b23af25116a76794e1e20632552e0a65d55cf0b83d0375b33c2148239fc729871c2a1e99b918ee99b0f45a3e9d84de122286dfde94586782c440873dbd00ea07eb2df7303db0221df093c292814af09fb5cae09835898203f639c09d72273b453f54cdf6214225a94c8039abaf55ea08e532e8c90712e3fe907463e0512dbeca002b86dabfbb8c6565777a7c0d21ef6cd59a6d9838551ca808c145b11835c1f4f08447caf57b4d5dc0058267c64445f87fe76a3a5a8b155bba2e1ef90b2df10653cb152bd2fc61bfdb8f215ed459182ba24eb9f247dbf306b91ce483e94dc7236dabca7f9ed0c9f3623495d3757215c95ca5bb846c2f88fd32e13a67990c769b7581b2193b66bf9944c7a7ea31d4cbbffe6d835ea0694541e3b38edb267a18536c6d5f56d11ba421348927b499d377de69d954b5dba68cf038341f31bdb861948797199489f595621783198338f050f45c18c75055bbc880ca7aa6e428fc7789d37992b91e91076c779d361f11eb97754f11df94ce0b0d361d8f0bd05b40b3ad869d1877cdff38b054e080fb059335dd70b4995799311610011b5e713c933039016b2e0c9a112c01aa94b5d9e32a3b99f0794a9d28a9ca6d0ef08e29041508889e88e6a10c14f2089d73d1d8e8e92091ad25a48aaedd9d90e111d298247333d2a703e18881a35ebbfb857684a83b28447a84aabedd9a05c6bf85ed36e3799a5f2e8fcbd424f6ad1d0b49dbdb6b5e7ceb1b17b59613c9f69108e71c32be6bcbf5830abb5c2c86e9d3f48e1c7d7a50b3bd85db51ff061023c5377cd8054c86542de3fda19ca2ec6b0d0c8d4ce19c6e4dc55c8df7b9b6df51d3befba5b6df5ae881d09a74325cafb4e16e57d6ca788eb2e68c2625305a3406ee79d550629617fc3f4f77b162dda23d07e5b2297d78723b92b6bb9c69db12be97f47339f1811ee8ca86544ea6b564ff9b067bbc50267350a3bc776dd71e75d77df73ef7dd7b57fef90fb17e69445ebb30dfbf09cd374bdd6affc202c948396638740a9c6078f43c39087c88e7bff8e29960cfdcc7ee9ba418ea0afac4e3cb410cfc888d24ba28e2c4a73769c1822bfcdb28e929a19d61aa448fdb8254c6e6372117dae059b80e946fc9659f544080c7cfc5ac5b09361c89e28542909cc3aba0ad7912274f14dcf6a3bb4cc6324933d9aad6c2f51375149a68a54ff2cbe3e271c3d12f85e73b7f8c0ebb1687f979e80872c30bd388320255a5f01b3dc0cc8fd2923d0dd2490561bdebc4411c263d3cd802b939555cb03f6431969a4504fa41c6dcceb158061ecfe1109783a0c3d11741f00a6b88928cb3b9a186840ad3d73258c4174486b21918c91a806dd0ec43144fda3ee468c8ae4312d3791979fb267d496625be3cca8c952d2ee18faa8a61312a768e871ef40c01b8d92a061375193c062e770090746a8ca02c8461c06a6a3437375be7239717494d4cc5a4384b15d68982105d67e16e3a3b2089c34c0a8d942b2a00146c77399a756332441d8ae123b44646cd1557d6ace117c851a940979b01dcad1b5e15c13b1b2089cf56c098bb745367306323a4a84b116063b00860e9a41490dfe5968d8b506fa89840a190382ab9c510ed53e1616a04bd0d2de64579862015629bb900cfdce28d68e8a18af15da4dfb084657a8513f346d975077d66651425997b2de9a8c6232ee9693f74be12f552e4d5c8a6039298e282131fbc559af38de230651608c177589cc641d4da396eb2603d0cb213a0756a0d55e33ce4c881e9261924475d23629e1f83cd9834a884bc92b773aae6546e964dfca38b8e0139d120a35f9711d1dd67ca557737580325e7b1404393b218141330f36d913b911c229488a2323d22cf4dbae145758f16f90eee63df2902702aaf2d8a8d49db77d0f4f245cffa64b4960876d3394835ac8118ba5ea4b64e7883a72a3a3408a3449174ca66b9d376d0785af2a4b248e89ac005f0c712bf4cd48ce17d4632621f1de3fa3c1795743ce762666286ca20dcac3e0075e93563dab83ab3ea8f97441487252bf4037b81e79acfc5099344dcb726990eeed24d1495ad8242bd2115997aa52c6a97b16a9a318a3d17659b5d5367b281dd47cbbc5f628dc9fe8bc09b267c0a9137b7fe8b70356801f5a3cb034b699cbab6c52391db5fe8cd6b0039e6999d48665368eb726309b1483bb228b89338a3d512a04c48cac70bc3a6b001e9e4d203e7a21acb6000ef842d8b083428934bc56bded381d82becc3d37a4cf85a4e6f93e00e27dc2821dc4c172d8b66f0a8414f6fe4d349e1971691a2fdd24aaa790df76e58da2d834fd39ea6bf681fdc99d52def9b6642fa869e8d0ed06ca9e7db5fb41aa39bae338de14f62b8dbdf5d6ecd66fe694c8ddf0ebb93de8a6c3eed429743d7688adda22e416c99b84dab8ec06fe247689728ade49af4923c5584417522322928144e0d080d908ca53763e9066cfa6ba966d419aae55b620dc848001ff559bb6a9f0ec8c4643be69bbccbf8a10df25e7f6ff0f80ef968a3ee65af439b287ec18531977688dfbf3d653f4b9f0a05d9b4b84a68a2ac1152ea1d678365657a286bc689f94f070c95441279aaac0f1eb41cc8b975992794c37552209eafe5556a5482f562587f552d5b9328ce29d9db77568a7a87669124b9918054181d489422314e161ef60e5f688d0040ddba14587baea762b75a628b73bdde753335222f34a55bcfd76a95bef2749ccba614d012449988a51ce94fdb65b54632ae9a32a658d2ffc97d91dbc74a2fd52d8a38c999a3cf0f9b8454a7e71ebeaf231539e5cc922023356483c4e4eaaaec80e32269bafa4f21f20634aa72ada9e31a6ed49ebc36ce53d33fb0f5f35dbe927cdf68c76178ababddc6a078d2234e1b19036194b2c3d624eaf2f6417c6d02658bf42e2f91faf2c79f1090dcefcbdc4b1e728ea6a2cbb16dac0bfb0d3219096a74c962f391243b3f97a9bfb83db2d25221c7bdf6776d8c00212e97eca6f2b6ee48a29a4fc55003b2863a4235c9d2566496887780156e0faab8294c793e2452e5de80b4d964832fdd979b14c459a3851f79042018d7a68b3157684fb8ed0e361197c3a4b9f6b11a6784f95967466e9a04ef27cc78a782096882acb92821824323db74635a9f57a3a91f9c6cf46c5f2f7398e1c902001439be8df2c91daf2698bba03a8e40007dc9aa6fe18cc912a962e59cc266c79e2c89f9a214a97556d97fbcf4d15c95062254bda4c8d15b45b2dcf0f850e4ba1acb6602567aaa0a7305a20f224aa352c5b796f52b46c7f3831ac58262902acdd340379379429d9b99b444ade9b4813659ef2e180385ecd74304448dd9e6db3db4b68dc6e4949c798b812a99bb5d0f3a3e5cd155491e6577e9812bf5a61fa61769d15dfe7467b510cc81d6924745c18c319ab2d728062a15c1e650d288c8c90719916aead4da0b8f5569e51369b16be99818fe2948468466a1dc3286a658d2f33b89169f728e71fa5fee179e479923011500280d65159de64a102818027b1eb8b05b35e50cc2e9a9e1b3602324e0a8f9b6edbf46d6a3c4cab3efb55314d3f34f6b57cdb312ad4361e6fbb36351e6f3b3635f6b567db41d80e8c49da0a69b34a7de3c05ce8c1dfa7bc7996304103fc115de0190539ce23ab7bb2e1f9212700ea362aac4e5123d407b541455005a007cc194817289db3cc0e3669d2732d73169a817f276c3780bfcf7a94fd98f05c8bfaf0eb177e07fe4c9a217e0fc11d913ce9b9801d3003564008a800cf101415db65088c0a14379ef58c09cff8856f4c9a59bd457ddbb269f369d30fe838199d6f2ebacd515b82b083a72bcafd1c5a58a63803be4847ffdd6dfe6cd42e87340839a4cc19686a567037bcb60f928dedb6431a94881da031a296674458723f19dba5e51839411c03d94b0af318c6bdf08b4a21c92f6a15c97a242e43f2541a89be998ee7ce4e98217d1844e8908c276b79f220a07bf4d1f166e45239ce9a8cf2c68320950d991313a395cae82f7ff9cb5fa6b2593ea9542a15a2074842103d191cd0b22cab44d2e0fa76c3c6e05aa69f6e3188f813f8e2af30f50b5c43c46bce90270f262b06ee5800562e7de1d30170cf523a278824537a38c70c227c8f6018c60c840028104e3d699ac10c1984171af4100bd25f7832a33b84f345605ad35d526f6310ad7152f03c9fdc921aea9619e0ce704b4066a9432d9a220172a7a70b2e6999a64f023a079b500a4f8070b7589900cd080f2cc17698ca6f72046c8526b31b51f176db4f653678d9b69f2a684505619f4c665abca065a60a566282613f4e655704bd909b2add894a1f36cd14c19d0e2f8c99fa71b5ccce817a058e9c03be65bba62336d2e969ebf9b1d2aea3c520a48b161d19951dd7325065e7635edeb2b655ee45ef7652e4805c3e5a8c1cecc1f7bdd2f7037bc8ae9d23b0630521c52d0b83f9018b7fb061ba73e8a9e771cfb703f2cca5ff42b768da87af870fb75b76487d7df317d82a49106d790b649c8c95a0327e4cb267b09450ea0721855126f3a68b4980a39c44005d7f27f3e3cc41c8821922fc9d162582ad20553a6f8609e4082db0c3d895d3b269ec6942f83561ae598e8ea048bacd64fe584c26b302a998adf85d06fc57182b8c93c2fa7bf21a2decc2b4bf2a697760da6925ed4e4c7b5f49bb0bd3fea6a4dd8d694b4ada3d98764649bb17d3ce2a69f761dadf95b49d98f6173e8a474b7c6da61bb7fe1e408e2985d7ff0a69bbd4b4d39076879af63ea4dda9a6fd0dd2ee52d39620ed6e35ed0ca4dda3a69d85b47bd5b4bf43da7d6ada5f206d67dcb896d3f64d07f81c5558d505b2e3c19ac95eb2938cf3af31b217bdecb1af5d642fd9855fb790b19d3b613fbb0366a8f8be7f0f1983f277a8306380e54e324eeeda9d202c50fb1c4ec2a9c2dae9f513eb2f90f517d75f226b1fac9d597f69fdd5b5bf174aa4107f91f557d6ceac7db4f609664cc539e7e0af027b6efdd5f5976091c0a9b1f601146410f829a357136664be384dd827eb27d65f5d3fc1098bbe5284899c98b0284521ec93f5136b67d696d64f14e284b802354126ad9126edf3b5336b5f73c2f8ef14592c3d268a7f2b24b1b4336be70a4ac2df939f3239568a9cf557d75f597f11cab05f112948084b1364b02f8588d3ebafae9d61e56fb138b2f5d7d6ce28090a0995748f7cb1fef2daa7d84efca592c0d2a29ec02f9584b83c7c7270e55321a09326e06bd106f62b4100a64504e0578280af71da8a5ee020712f70fc3389e5651fa1cab26feb967d92dd29e11daad70e27dbf5bafd5c89eb1d41ee7b1859e2143f8476a0648fb4d908cea99496de82d08f4083a9f6cc54bad4cceeb460c9c21deaa54a863208fd298572be918d25d11dd5727341e8977d8adee78aa3b758a3b63819145939dec0b83a650f9992f7df57d75f5a3bb3fe2a4c1639f9f8da599c61a98c17d7ceac7dbaf6b992b8761aa0d75f5d7f21050bb35d4d84e9ff923ef98554f2dae9b58b6b9faf7d99acf0f3b5b36be7d65f846a13f0eb27d7ceadbf92ca587f69fd95f5e3ba129facbfbaf639cf60e933ca2d97e967eaabfc0c7d15fb91a94d4a65cb7aa1b533eb2fac9d869566e0cfbfad7d80ddf512fbfc60fd85b533b0e7afbd6770d04fd7cee2a6c7133e86a5b8f639fbf870fd45d8f0d807765a5ef591a041aa5fa95ba937aa33aa2f4f5d5ccfb4f69181d88db54f8db58f8db50f8db5cf879444f1e8a1e7cc5a4812a1347e7855c9e8f4747bd7ce9d0f57c48feba636c9ad3549aae3d62e2caebf387ad5dab8c2fa8b05dccc106ab38a38a1871bae861baa852bac5dd8b4d20d88cfa7631baa6b1a27852958489c2b58fb7afda5b54f085f5ac8580cd03f61e18b6b9fc019b899a2cf523a1769a47296e32a2aacf2f4fa8b6b9fe7ad50a8ac365ba1d05d6d81ea0a37954f0668af803d593baf0180ed33e2228a85a0903ccc83a1104d15a09906180ad150011a6980a110960a60a50186425454804a1a6028444705e8a401d210faa16ff9b4c576a27867602c5ad68ec37263ee666afdbdf5bfae9f5e7f7ffd6feb4beb67d6cfaeff7dfd2f33a3b3b20bd3a619d61a83768f486c9e42d014933512d7b7f63ae02e940a59d70e2d2f08eb78c05c7da3a6a7ad4db620d26a0c6f41091bb0f67a660b06e9dcee469ddba419b67d8bf9da081b94d46d3f080924f0675e992ab7b15d846908b9160d0dec2297938f9b2e19db153654bc08c81177684e6d9bbfad6dbb11b46da63f71249b49de611dc9bad75dfb109517c7d75f35e09ff5e320451842c630d64eb394f5170c264b008389da10fc0119ebaf02b7797afd95b573862c1518b22460c8dcbfa170fcb96e7f6f54326f48b9e10ca721436e38b37572c3e9b58f503ee135a04c8238111fe2ba81e588eb7be5ba7537ae692ef885f55f6f960b663c70de824996344f392d0f9cb7e0d554b8853c306c3257cb01176285b186fb4daa90d3ec6f4156e36a98dfa4ea37cdfd1662adab86f34dea69d3ac6f41e85f354cafaa604df3bc05a1f8d470bbaa6634cdec16d63e5f7f294d75747f0bd9a8053d9731bc8358aa9d8ca56abb57c550dd398c9fba736bd8a98923db0cd58dc1503db13080a19a5bc862a86275ae21ab70655e45a86a05af122b648d5809bbf699b17671ed0be056be583bb7fe5206afc2d33f59fb90fdccc74edd98440e66a6cefdc8ccd4b91f9a99fa692961b799a76de6699b79da669e6e2c6dd4130bdbecd38dc03e0db4fe1a4b1b7fed4adb7edd9136fdba336df97557daf0ebeeb4ddd73d69b3af7bd3565ff7a58dbeb6cda2b6cda2b6cda2b6cda2b6cda2b6cda26e3cb3a8273b0354144e67db36ea7f9e58be6d1b35b0ce6ddba86ddb285def6edb4609806ddba84d9b116ddb2afd446c959eec6c6b876e04ed90e957cc019c6bd3dcbe5cdbbe5cdbbe5cbbe138f7edcbb5edcbb5edcb35396b4b2ed77e3a0c54c5dc66a06e04066adbb98248fb69395748e86f270771c1c11672c182af4cb29846acc6fee16cf76f7472b7f5dbdb9cb10ab7add3be6175dadbf204d99627d87fffa3e589ed17bd3f312df9b55950de3d4cc2bb7b6b04bcc96d01ef8610f04cffa03b4036085d9d6c7003bf939544821b984ac1e0de2082c07593037e68314023050c100206c900434480a112405e01e06a35e3db8cec0fcac866f0b183d9d8815cec3532b14378d8a12cec400e7628033b807f1dc2be0ee05e8730af0378d74da8c2754c52e469d8bb0a1e699cdc797d1ee81e74b739a41b81430ad03099269e3d8c8d93c20edbadd9f2ecbc4b9778af2ef19e9d5a506dea2e484c96d7a4eddaa949bc4b977807a45d5a766b9796e5e43bf5c9633b77ea33ee66a8ffa1acddfb20b1edd6da2a0a5dea1ddad4bb31f51f9fa610cbe97cd9a86aee6cc734995e693aa63b6ffa469dcefba663344d3f34cc964fe167c7b03b6d17fe710c73fe57ed203402ea861db3ea1bde1cfbeb7af8c7a27366356778918ee94275501754c52b827ab01aa803d0036ac09b4395fca079c4f40dfc97503fbc7c2ab08d4b2f5f3ee5fff3cf974fb9d5cba788f9dc3fff6c36fff1a99a6cecbfb4dc9473d9b7f1cf3fb1fcbc2ae407cd23c683471e322ebdbcef395683b17fdf73888de1caa71f7ef088f12022411cc6fe7d800111dcc85ae272a552fec906d3a8b6672f2dbb2430cd7058388dc0ac9a8d819051fc8bd9cba79ccba75cd2b87caa1e5e3e254261649595836c589796ddcba7dca12136e6e8a5339ba8622be36ddc1290c0737d334b8f794b402e9f9a9fbf7ccad12a32abb6ef22f124305dbb73f95426339891dfe4588875f9d4afec5f69008442330ba02130407765aa337599962809d3265395a9cbac88926627538d99ceea885276aa332305a6ede4bc2999a5b5cba71683cba71a974ff98b40a47569f9c822dbfdaefe0665f4df8b095c233f1bbd9668469bba54b973e09d0a3639e35a25ffcd0cefb21c78ee194c0defa6cddff3b07ecd79d73334c0ca8e2263221681d15a84ff196bb38889c08e5c6dec15e80b29baca4ee02c3146718bd66cd3213533a0184bf308f5bdcce646a15b226e67f06338e47d30ca2896bb858ced2ca5915755889d6407313560b518ec813d08b717ff1d97839866115c14bcf2943943161723d679aaaa7ed666ae46b17d0d421b1927f70c536cdfb32562dbb657a51f5d688b40d9a38ce282e75b68eca3ac577c00ebf94d90eb0042e231d3b1e0dd7613574d1c6456a4ecc4bec6d7f2886d6ae70c19c75d801578600fd925c393fbf7903b21a11863b81fd25920a6f8013e8bc5c4708e014ef673d74c22087dd45a998179d60e1b4fb3d6673c109ea31d6d7798a12ae7c27f8520288c93e43bdd42ef78f742f762ef6477a5fb45f7bc217ff65e533e319a94927f722078625f2a349bdafa5fec7ed67ba7fb4def9dee0ad42f7d0242e993d52fe79f1c089eacbfd1d0d5dffdbc7bbefb45f74b5ebffcd97b4df9c4fa95fc9303c193f55b5601107cd1fdb27ba1bbd27bdde87ed15de9bd636081b735052a152cb0dcbdd03bde7babf79211ff84baa28feef9de9f52853b9d0223f7dbee179cae98c06f7b7f92f92d69a9c0e137473b6c3b6816b2f8a521c3a819aa423a5234fc17711f51a58dfc95aa63a7199f41950e89b856200572bbd87cd89a9a9aa39d9912b95df33a3d5accb122a34ab31419559aa1c8488a2bfc36a4d03bde3bd13b19cd9cb78cee37bd377b27bae7a1b5b0e8ce772f76cf636f5f84397cb177ac7b1e934552ef0426fd094bf75eeebdd13bd6fd2c46f64ef73bf1f15f30273920807054f879117e02aade6bbd97018e55f74def1d48ee9eef7e879d8f24ad742f20aeb732e47e82ee034cd7321dcfa5e946bece1bc97615a981a9e6f1c6f1f6bcae36ef75b979aff3e6c57971037982a689a906c6cd3b0f85e406664809aaf248b494b790b72f6a57d49ea825bc0d11f59cee88da88c288b2e10aa7acb90643c607e19bde9b06b6584a62949eeffda977a2fb2d927911777dfc8927c2cbddf3bd970481dff5deea9dc019f5129e16bd93dd4fbbdf42f3f34e0b859eb736490f4cc52c7a709a0a7abae707d06307e25e72747a7a8aec9dea9eee9decfd6986ec2dee1def2eb3ada6fb4def64efcd45d888f8f87e07c9bd3747f692bdd3d33364af6559d66836c3ac68e3e00085b6ae40db60587bc76036bc042dc0511e7627cdd571578de7c651b991eee7e51c6ab7eee7e5d266756f5299ab54c08d93c254f73d38bd615212981403ef65bbbf677315a66706b474a9da3ddd7b99cdea0198d93daa12c43d5b069fea9e166a368e31299566ded40ea92158b0c35a8320a75fb6cc4e71440bc67a35a064e7f880cc3b0665de3528f3ee8ccc44271075d90eee13a582b141b5ef1a9479e7e6497b6d386147078fdf169a7e76bfc34df5cbc1818af1985cee9dd4ea4df1708293fc9bdeebdd8bbd77c82081a149c633c4219dae3417642337606e48d497c65c8b569f9a0b112a5063a65eab60cd85a84322c65fab6fd523c9a77eedae74bfedbddc7b6d11a7023bd75f5b4441e6ad453c64e1b83dd63d7f4daa580dbe1b471d2bbae09a35b272175eb35a9675d9e695b2721f6f9d6ab6f7ce224c8bcfbbe7754ad8b40eb6445ad4b73d2bd54471aa646413b1b7162a05cdeecab2acecac898989eccc85ecac67755952b716251d2df7df1887e88e12ef18112aa4589f8b7a28a16b4a24df3142f6ca7ae5de3b05d4e8c609a97924357508c9121a18371d228bd6cdb613e6c1936f26fdd4f5c455baad27feb1f5c4a86a99cd54b5cc66d98cf4de421e0b36beaf8cde0bdd0bddcf7ac7a284ee32fc00c9fa3cb23d5f75bfc1b4eed746efcdee0a1479b3fb0d009eef7ed6fdbc775248df1740b0ea5ee82e033ac8ffb67b1144d33861a5fbad9cff05724451423ef31324fe18279b13cb491d4426279013c549e124e4305141eeed8b5810ff364e80ba4010ff8c8be1ec13c44d14d5510cbfd03bd1fdacf72a746bef5500fe0e92f067ef78efd52182b84e44bec084db6f41bcc59a798dbc365e03c7be6981f93349603eb15502f300797990b8bca5062a9bb34fb956f394ee6f61a47ac749f7b361e629ddd328195f18002a8c479858a487936d51baff17e70288d0d9c01ce90d23e1e61362ff2fe97ed5fdb2bbdcfdaabb022255f73c2c1f2131f2d65e5f5176a07c3e84faaf7a6f0da73da7b4bb152642bde3dd6f60871920eee2d1003be057592f1e515579b1fb6df71bf8571177bb5f651a0d0d066b7241f12bd42fc28e99653b2401a5b0a0851072fec733ad875876ba0221f35e485f5a45f6432090a46b9584dcee850c219753ce41d2b54bf22d9b3c99564512d05719b32187300367ec22b47511fa11a4d2af40fcfd6a11baf76a8d4c806dc17dca9eb5c3a1661f00b90b4183840188c66173c2762553f69339fe0bddcf0688a04af59b43bb9213ed032014dd7aabd2d2fbf1fa3c574d38c307d7c47b1a04a9bce47fb609a403657d99d2639b407a0f888d6ad2bd79895fceace7ea7bf45f548c9bdd16e36e0831ae9929c635b3c4b8ff6dba0bed0e9d331dcf78982eb47df151317d3bb0f1e7be05dbb71df6bb72f95dfcfbbfdb0b97df75f94f4714fa79c8a0262fbf1b9a6eb5edb7f1f3f26fe7dae1e5df46df4f790b52ee040de2af7cf2dbff365da0168804ea802aa00848011ab07eac15aa820a7248674f98be6d3c155e7ed7bdfcae6b1c347d33348d7dbe59358d7d8ed9b403d378bcdd348d49bb6afb765e29eb09d347a48010b0012ec00368f249544f98c653a171106831f639c6e36d6332abf61fd91b0c0a3d53a1edd0193241a602d39d19245365819329e7f2bbfee5776772388cc98be35a04b0076d22900d16bf266d7718a82a7e599e3b005e16c39e68bbed21a02aeaf0f2bbcdcbefba7450055bfc2060eef26fddcbbfcde2f54d52bdfc2eb92520d5340caebfc074674d62994df68f9eb90fe89ce75a36b9c5d272f54ddbb5439bcc5187a68cef9b3244ba3cf2ecacaff4e51b3244ba3cf2ed3011f5a5ad383f5d16b976d8fdf4652b717eba6c87f79dbe6827cabec5ba0a5789d7c67d5c9f20aed5e636f77123701f039d246e9c51bd15ee6289aabbc23b58a2eaaff04e96a8bcc6668e1237ce7ca024decd123f5412ef61891f2989f7b2c48f95c4fb58e2274ae24e96b814b94b647fb37c264233534e13a19929af89d0cc94db446866ca6f223433e538119a99f29c08cd4cb94e8466a67c27423353ce13a19999de13ab99fe51aa5ae728b0ed6c2cfd7163e9db8da5b31b678e6f9cf933fe3ebf71e698b1b1f4c1c6999737963edc38f3062649d94bdf191b4b1f0bd8373696fed3d8587a6b63e91c875dfa6e63e9330439f3b201359c39beb17436faf51996849c9736967ebfb1f41516fbb381bf5e1668fe8cbf3fc6df1f6e2c9d3736965edc58fa9dc87b2d4a3dbbb1f4511af63da4e2ab44463ed655ee94b82306b679406b793b93cd4bb6276e89427d0eae18bbfc432cf1212390d5f51a121c277dbcb1740aabfb3d8e419cf121127a2691747263e96b3138e73696de4f54f05f58e87762c8e50c68480c9b970d8f9a11539f243aa63593c424653141f958f96154e84938b9e96af3c901fb4863bcd924400accaf3f6788040c6c3c080640e6910e3675c9522243a9cbba71d114bd16ee1f17d81f87b1fe62bbf9166b3c064305bf735dc39486f0fe88f8fd81289567c10c9edd05e8706f31db8fabe33cec26d9466dbc7bd2307c8ff91decffb07ffd8e889dec77f8ef599cf1ef656afa73413759256f31f41fe3fec17691d4ac8a54ff43e01a0aca3f88aae110cbbc0d18026729289758ed99d7039910956463bfdd584a5f2354e466ea203a0a9a0f3796de85dd36eba22086d04fa72d709fb871e6ccc699b31b67febe71e6dcc6990f36ce7cb871e6a38d331f6f9cf964e3ccd2963b52fc69394d1c62ce27ee64f0fcf97663e9fd45dc1bf986b20873098e9773f8eff94571e0c7f9bcd8a806f7a35edbd7990bf2ec6c3b41bc49d06bfd593e495ece1c4d632a46168b28124594a24c84681ed843ee1c218b8be95ae0bf5479a527622cf793bbb291247128bd977e8d250d2ce2be9d8ceddaec450314cc77b9703d4c3ae36e1f6e8639f046aa20cfcb6bb6e94c8ee6507c83afcb5223bb6963d1ec7edabc6ae6a7e0e0b4baedbceb27a09a59d604b0d858d644b0d858d684b0d858d6c4b0d858d604b1d858d644b1d858d684b1d858d6c4b1d858d604b2d858fe4b5ed5ccb2269e053433ad9a59d644b48066a65533cb9a9816d0ccb46a665913d5029a9956cd2c6be25a4033b355335ea66ac6cb54cdacfc79e3dbcf37965fdb587907ff7d7b63e505fcf1db8d956523957d6263e5d71b2b9f6dac2c31202dc4d2c6ca171b2b7fc882786763e54f802323fbf4c6b7bfcdca7b7be3dbcf10f98901c8df4688ff1800f1d78d6fffefc6b79f02686645d0902f06e0783167f609fcfdd960926568a57f73ea92b647f1a7388a8a7e0d0afd7963e52f58e2d7a267a1fb0d354fa93791f70789c6b7f1f3af69a0d31bdf7e1935249dfd3becf8bf8a467d91c866a3ba04130c9b97c85edaf8f6fd8d958bd1c86d2cbf965b37976a76b2a999cdd33449d30c0de99b2757a8f06e686237a3f81ba6eebb7e4abe4dabf6ae4da107a3c246f0af38542f0c55eeb1e18816e8ca7f0cf5fe97daca7e877bdf095eedb7bfc7f164dbc41f66866a00578e47b362b8fa6f50d57fd858f94db4695c3f15e1ca6998b303f48330c77f2b083eadd712ae9c16c712f443b64a1070fd46acaa973696dfd0eb0315b03f2476fb6cbda05a4caf175c79499c08ffb9b1b22c0eaa6cecb18a305552af2514f37008de585b2815d02b0c358c4006d258772895d1ab0f61c49687a08b758808fd032a1097dfdb58feebc6f2e98de5f73796ffb6b1bcb4b17c6663f9ecc6f2df3796b73e12cbbfa602113690ff1413ef0f1b2bcb8bc80e2e73ce11528f6dac2c2da666e8171b2b2f2c0ace6c596ca7f0b998467ae3eb1953245fadc251d74f57a776d4f5edff08e5637a2cae590ba99bd3d7ae8ed48ef5352b25b5e3be79d5e4f05efc17d5517adb3aca1f5b4799e9bdb1d20eb1c7b7c47f23fa4f2c34dbb0efb8294b49ee2db0691f49e530c783169da7471a196efff4deef9a827cc5ff9deafe2ee9c0927bc9152d7fd8f37f494d3fd0bd83120f2a81fd7f0ab305546ac7d0be57d43ea4d4be4fd4be4bc4c4fb348f15d39d51753c33e5f138db1d421ac17c12c1517defa5bb42ee09e975d703e4be2c762b85035f8a69dc15a648cd18d2681a84f4b9301aff0cc2f46fa1041fe7d5c38a8c6d3055009135cd529892eb48507dd0ac3a54b79c6051cca7164b559f8c4be8c800a7994a75534051b9d630fd7d6171e7c80cf64ab43b66f58ed45c7d7f0caee37644500eda55c67017c7a4352aa9dbfd4c75bb9fa56e7f84baf3d437f64f4f171a0b74dea7be51a16dff48c378a8ea53c7a898d4a8d0230d3a4f5de311af4d7d6a3ce405a1f1c80275673dc7331e85a489b6f104f58fb4f369871fa1aea8116a83aab0a287e629d40115007e40cd31e7d0574eb61de3c9b62bc8af50bf065550dff8a5e9b5915eea1b93a6e5f9c3225e44844a3801216042c2264d2b9f526eb26d3c09457969e3910563d2fcc1e36534a6e84cb349f66528d258f678106820f2a9d2a64c326f1f99c9a1524b41924ce212bab50125af45c9f6a87dc49e2796394cb5f6acc9e68f671e690c004f3c9bd1c2c90ab3098a583330a65fcbb4cc808619d05ba90b337754a9eb0e7600373d5d38e26935606d97b8b44adb1609e8ace75ad475bd4b5f672ac2a8ed68f81c5464b57d329fc107699dc1899342a7ed6abb84b6fd4c959626cfe2c53847a5535ae524a0c21ba3e1dab4fede32d074381ac6a6e81454195c997e360c7d135f342f7dba384fc36b79fceeb5c3561bd85c9971181b217b49c1bcf429fa729ea76192e74a72560ccb750f43709d5e06f9dba2dd0d23da85bee9068e19d2cdc8723e0dda8ee4de0105abdd6909285996446edb8240e7b72dc16feb1d1ab0998404dcbe079f1eb65dcbd47a5589953632172ff9ac437775896fbd5a4b5b2b1d506b5e1c760e7f30245e3cacfc6e5d9f36755d9ae563fe30b55c9369fb4cdc95208172f55f92248e5f5bc1d58c19aff6fa0e99be696433233680eeab19b0c62607cc74496086d16879b3f0992287e3d622bfaa0566a68e2bf2032f2e4dabc8a65696196eddb2b2b48e36afa6272dd3bda66659a6bb7593afa2752d7a55abf9300d68ed7aaf66acf4daa609c3b17533a5d3d9aa2e9df580e9bcce5d8a955edb063980eefc1daa8d3a12646a77822cedce61d36d63f8d4aa0f7f45fc54db319ae661e370dbb58dc36dc736ccf62c8b9fda0a69b36a6200550ffebade3c4bb0680d7fe453f01c36dd32d45a862acb5025fc3a5c862ae11fa70c5596a1c232d455868aca5049796005b16a24a5199155412eb50e53e7b069b43cf173ce68879e6fce19816fc33962fce30d1acefba13967b428fc1bb4ab5e384c351335d0a55619b097016d199096116319b09501595643120a22971a2dcf688746e00302a3458d204b8bb6850155afd259e5306f95e5e11aa1f2e6fc55a6c0af56f783da17383e02d21ea4fb41b8a01dfa6636dcf5f52a4964ef8aed1932c5e734fc6c0f750599e58e3285952d8c7c4873b9b144a4b0aaf2e1fc317d56b6857fca4c3287b8a7142a3e9c3d87dbff7883fafae973833925557aa1e57bff7ccf19de176453d38061a56232d01b7e323082ed6b9d125ba99d3d6266696671c6b560e96a1d95e27f0061fa4408db69ad2c038af42029bdec3080e61080c6300c8dc610002b6a09481069bdece0d295a83467d4d31ad9c1083a110264efda1a4d6c02817ebc87ea5fa7a7cb7acd6be1164b8995f493f7cc186c6b407f6c0d28481535334baaa899f962192a31dd66f19215e40d8ae2c6a533865965f2863d0bdc7f07050ecf31cc590f250e10387c6a78b5b00d7f99c0e153c3a201fe1810bd2d8a6c6751c22ab628e1755b94b0eaade9e902230193ec59f88b84e05fa40561901e8b92882448156459944894911cc449a1e526a6bc8999bdc5e9e960e476e0663342c52564a859ca6428149d784796d57e2c1b260a516119fa2f12a282bc42545a7c90a528cb6e37a93b4b0dcb769cb61b18960d0224fea5359fc28fc35e1bfecc53d76209416056c3ac7e498951d66cd9b09cb2618565c3aa950deb70d9b0a00d994d48884fd6ac613986151a56cdb00e1bd6bc610df3a8f9234a4fb95ea84c5954ef9cd27122a81ccf58223464ca240e0d66b4d29693445a1a2a9491cd56e0f0922455cbd5ca72f983e299f36d9b9868f256649c74c36bfb417184c5ddc14b498706a85076ccc208b99d14f204cf8b2d05f25262d1e6a5bffc50a4e49328042d8caffd0148890d1d728f4fc3f67f884ec92f6645a4504770fc2d3308ccf087206b2b65023cb47ed5bef4d100a38dba4e6ee0161b01b3d548670b2b0d7d76939b48e04550e66324cc4d95e556192669787eca8d6a6497d1f07c9a2a1a5966d8a982d15b22cb4e97ab08723559e2b95093065e2ab7c30b9a6e27f36190e97682ab8d3e50f417ddc570f1d2d94533a7b1456628b52146177e8168c4de8455e75e527087c2dd9113df9d08c7aee92e9d4d2e0abb2ea2be318e78a1401617899cf2acfe7548d4c6424abf9e90c5ff471993d4cc6d51ea4610a5b880b4078e068bbac6a58baee71bd57f9ea247a86b58ed2a758db9f97fbc1b52d7f8c71bd49f8fffd29a11f82dea1a472ebdf7cf53973e32e09fc3d4351c3b08bd9669192ddf0b6c97d672dcbf3002b07aac1daac68a8d7fbc310f55ce636dac2e5613d40355c8d877a7db867b18d943a646ffdda1d6a85d22a3ff0ed5b05f5017fb65b5abec07d4ca7e15a1ee45dedc9fb11fae391267d616a3be10bf6a94e7077e8bfd4092d94fa49bfd74ec80fd68f9dea82d9e108e8e92a70e1c7c689c1438ba022cb5c8861a565921aab2b01b969c4feb9e4fe564d26c072169f9b4462d2a63727189fa74963e47428f5429a9b71da743f01523b5ca110d0700ef821d5082cf447d0e1190c258994815994a0a701e0518ede4103c8335ee814ec359b688b36c91cfb2459c658b7c96e97a54fc1223b088f36e91cfbb453eef16c5bc5b14f36ed1a116d68555413d58cb221fd6f91a20626818124001a54746eddd2993ab1606a62dbaca361f45d8240fc0c9850134d93b43f8f97ffe4fd125a3f83e8ef16019cf07f2587395403a4746ea87b0eb2a8ce3c09ba44e1748406b9e6b056414a64c3249fd3667bd4cf6b4a81ac32c2e4a2dd84b0aad4bef09fd2e1ebad2b7d94cddeec7f66740e77d2a8df2e77d836983837c005d9977e5d29d3730d86232708bd2bdc22cac834de1ad1ab98a3b79b59e42667f10fde57cd5a7e65c9699191f626651254637fa8a7e0e1ad3947d536c8a5614bd1825b7b133f0a7d74ef5466c9dc64694d51e8d68fc19ffbebe238ab576e2366cc578b2eeda82e16c88e1e42f8fd968461fe2d7a6c6b2c1cc409263d960d707f80a037e668e65a321c612254f3192e243fcbabea388247762eab7621459476dc1285ad1a204d69caf48f693fdbd86fdd5821319646e9736f5bb29bec4c4f142f5291f2efe9bffb8be8365f191b2dc4b1f6dc54001be6b1da34abc71023713ed9bfc43fcba86916afee3dde0d24735b6d3b0df594386cf6ad976c93877b15b8aafe8e775de2b39d9721bfef9c996ec980cd9b5afb54e348e20a48a61e4bff98f6b1844df9bc3c6fbde5cd6e0753a62f0a0b268ecc487f8757d47cef7e6d89a73e8969c700e0daf76cde92c086b991684b52c0b42f623f3924afa4ac13049655cfed2e3190c78238871640b4539a9f1a84510ad8f043a875aaec9c43a3321dde15fd7e4529ed5aeba6624ebe15fd7dc84cc17f82dd74c497ef8d7352309b0ad9105d90f269e6b8754d7b4ab951ef5f797d17cc1afc4155e25075c0074e6014c1896fee35d871a2dcf851f973e322e5d0ca97f69c508c27f9e6266a5e1bc1fd239a375e93df813789b332b355a1ee034821050011623c80a3da83525cd5b78f855e74fc74e5463269abc0f1238cbac52bd2678e8cd23da90ba3420f3034c4801e8c8a58f42dfcc067b96d2b91fc780749eb0496c73e2b6dc0a4fad4ddca90daf2c9789e23c256ca5b573909f650a98c428d66c0e94b90c08e7095bfc39f0e5b2a09c27b88b0c68723eeb549898f37006644c4c7169fae34c4c10e71daf7d5da727d679e9ef5b3c49454bae7da6e69f73ac252bf95b926be6452db9b6f927aebd7f504bd8715268417f67dc786799760683329b83ad5e0759bc0e34761d64e83a206f50666550dea0cccea0bcced5dab4921bcba8f53addc46e1bb5de1037b1b5f94c41773eeba95cf7e2f76ff78e75bfe99eefbd6c7457bae77bc7be7fbb77dce87ed73bd97bc5e89eef5eec9e37bacbddf3ddaf8dfffee0fbdff78ef54e7497bb178cdec9de89efdf36fefb83de498600803ffbfeedee8ad17bb3fb5df7bcd17bf9fbcfbb178ddeb1eef9de2bbd13909def1d1d238a9333881495082420a3fa1c9e94ba9ff55eeb1deb1d874abb2bddafba177b2701db09f8d33b1127bcd63b811d762c4e7ab3bbc27f762f7efffbfffea0bbd2bda06279033f2f88cf57be7f1b5ad23bc112f24a4a8c464e13a7046be7f5f27a38fe7c0254f733c4c8f1096c1c97d17b2513cf0f1edd7c47a5b2235b9c62469830f4dd6f7a2f76bfe23e93a67a27bb5f7fff76efc5ef7fdf5d992113533bbacbdfffbef7caf7bf9fc910ba368fa8343c127a895c3dda6b10d3ba7fee9eefbd05889f3c48a67ac7bb177a2f762ff44ef48e752fa4da2f496edd0f609de42c2731d6dfbfc3a67aeefa18a75d98faef73ddaf7a27ba177ac739f396b35e51befb07dc8956beff7dfef25bc790c53b33b3b1d20a02b0279ba868dd434663d27e366a97e973b41615dd4b0a406e77a500ec039b305a20d84211a8c0064bc793f233991b8dddce0818629f2939bb823db6f756f71bd8e0b41694ddef60e3dd011b1bf9ef0f6043633b582fe5483cb2a81c0cd68cb192ee72f7abee0a6cea992696d9200d0951dcdb99f696d920964c11db9eb36c2ff5d9159912beda33cd30b3003a12123627320d3279f6661855894fe5fb4f26afcaf3ff959e61d5e6b739d61b8263ed6472ac1d1dc73a4e0a8f79aeb9e01bfb1b0bb4ee7bbe513117fc10dd76da8e63544cdba8d006a0321ef1fc7a9dbaae5937f62d04a151a1966d3cdab17c5a370e9ab5c602b52ce39986395befe4f0efc0aac67aa14eeebc136b839aa00aa8012a40ec88790803064c4ec7b2c864db31f0c7934edb65bf78b3d86fead71ad4671f8f996df6837bf664084c6b219f7b4fe1dd132a826654a86f00cadcee3db9774fe86aa3428dc7aeddb9e7e82809e1b465efda0262fa1417339cd6c40c087577cc56b3b8ce0c05fed5f09c43de2a0d0da6a302647388ba403ab918bf417cdfa3d4b2ec0562368768e87f59f7fcce0030ce5ef1b7325a3089fb9bb03c9a814ce2d5b893507b81860db39e01bf49de2c83351b2785265dc872e8c9589c8e4b2e7de1a4ea1f27854eadd1b1ec59426dc7362d33f5de390822479eb669a55814eecc3c9dd1e40f2e74998d7152301734ee3af95b8b7496858f14177cd74b21b32cf124449b5d413b34cd8b10f17a25fd1c649c14aace42c7b23aa9f7e79d0e2b56773a2eb5acab7e1152a7d6a269bb8b667dd176163b96b548ad453aab3c0f813dc2372d1bce16d389f81366841010b3eacd5372c718ee1dae072c43b3e9b94e87b4036a11db2535cf71bc5fb56dd321cf522768a4789d9c5e3eab918d6c29cd7bc72f35927d4570e3f2e6da2db2874ca5f3e0bf42a1440a661dfeb51df8b76359d21f9afab7aef9333a4ac6cc3a093d32b6b34ead8c9ae8ac54907de44b820fac638cce4225bbf49524e3d9d87552ac9207b24267b06c7c42b3932c2e12f6fb2ee9f7ddd2ef7ba5df633bf518d5d100aa7703d93035eed869da6e89dc037f88e793fbe0471ac3609b15e94d8ead77ed9690b862e75dd00f7aa223a46ca64c55536181d4cfff59cf7d3adb2cfb8dc0b25b999e13ac2ccf093a7f6c410e876c943b64a3c2211b150ed9323de3a71db241ad5023d4276a83caa02ea808aa00f48039879238b8f4956b99b346d3c43fa1ed07f0d773f14fe8b1cfba4fe18f73e92bdf1a2a0544d4026e400c580123a0035488279f2e37b8f495d1348dd0363cd7083da3ee43e11f4b7fbbc5e63043ed61a6acf28c6a143335e79467ae4dab8abead6c6299b304910df69f6f93a6e7cf527710ac7075dfbaf4377e6f9d012c7bd0b7c9eca5bff95968958093dc87d3549005bd95efb1bde660eff9816dd114eb884ba97ee96ffcb10e4df1b8d26b6c3d00aa036998e73d76982e8d3a40eaa2dc99a920844cbdab7ceac274c87e906dcea6b05678b9e6a5bfc1b991a50c64d9e96a3bbcb997fe96ce125a40c8bb4a1efc7fcc55b5b5fd68f847e722e2e790be57a341f08cb4d35cddebc5ec086385713255a0d00b15e6041c2419dba5bef89e49ac267c15c58b4c86e8e93d2ac2bf53452c51841c34670578133fd2b0082cbdb23c889b0549a4b8e99295a8968ae79a615c0ffb4cc3571235215ca22e96a6a9ad13d5f6b8d9f0e3caf02b0ddd49d4056089aa30c92dcc48ab341daf2df9a04c8ad336b573868c2b096333ba705016cd6450691683fa3863501fe60c6ae5d2fbfe11631f32a815d3361e0706f5716050f73106753262500f7006f529c1a04ed0239b60501f37dd32545b8eeb2ca7ab2c438565a8ab0c1595a192ad717635e9b96e68ce1a703898b3c6844ddd00bfed305cf06a0d63c2735dea63dac33eb5e1efa4d984efdcc1a4bcb251f1cac6845d362a76d998f0cac6c37ed99834733abb9af48c8a674cd846c536263ce361ff878e253580e9bde178dea4afe06bb51f68d0764849bbc9eef37fdef0075fa2672b9a391b3c08534adf3c0858d23acfd220a4fe60dcb2a98043c323217523cfa672b16b637eed41a1a3e63d3fcb0d11ecab2dd3f4c924636fd30cb2e07fb30080c3d59c9f598c303bed52581ab9b0441c313b00d38e487361b1f28155f241e503ebe483ca00db66a659e3339969bacd4c6f33d3dbccf4bf3433bd2fcc66a77760cfe939ea4bef03e3f863b0d497dedfe6a9b7796a01b1cd536ff3d41c6a9ba7dee6a96f7c9e7a5fb8cd556f73d5db5cf5bf3457bdbf3180abae35b6f5d43f064fbd6996789b99de66a6a3ffb699e96d665a82da66a66f04667a7f639b99feb19969c549bc64fb5ee8bfd3ffb07fa27faeff727fa97fb2ff7779ea15faaff63fecbfd03fdf3f9905f0ebfe99fec9fed9feeffbe7d48c97fb1ff57f8725ffde7f2399f9ebfe476ac23bfd0ffa27fae79389e7fa6ff497fa2ff7cf26717fd27fb3bfd4ff4dff7cff3f92b87fd3ff102bfe8ffe87fd5ff7cff75f40b253d47ddc7f09813ed1039ce87fdc7f651086b7fb67b12a1980e5cf9462ae29d1d72ff7cff45feb9fedbfdc3fdf7fbdbfa4623cd6ffa4ffeb642274fa89fef9fe9bd8cf89cc17fae7faafe9124ff6cf60e7bcda5feabf9eecbd63fd73fd9710e85c32e3e3fe89fed9feb1fe59b9398a337e2bd3bd8595e5de22971f473dcb297e0e6019078070ce50f4ba217ad810bd6a881e3444af19a2770cd11b9b30db4df281d766b83b9a235ed7f0505c398d76f3be826b52dfb66cda14a759ffd7fd9716fbbfeebf2a9f6576f07445799e6fbbbad7f9c2d313142fe0868970194f2744cd0ae286d7f64bdcad38c8fd4f7a0b9a2743769d4192fbc9d8ae818198a039a9f02e996f50940664bf12d9bca173ffd7b8472cf55feb9f1b66eb8c3bf06bfd25f83bccd699bb681864e10c9b2d6e4fbfed7f38d4c6b9ff6aff0c1678bd7faeff4aff6ce404e287b475eebfdeffb07fb2ff119e002ff7cf0ee0adf9367716d67a1693ddff4dff2cc29dc03d1916ffc7fd17fb1f4227e8f96deb16922ca4358cc65184fdf43ff4d89a49a873e496f4cb448481a6be8d03033bb3165b4307a9c38806d230b3faaff497fac7f4d82c15ea37d07f6983694e7f26964a0ca1c7d0e1fb336058ca6a59270985add24fa2964f5b6c6b8a3709e6ac376bfb61b9659fb61cb3468ba36baf8fce9648a1a4f85056aaf0825044ffbcda4a4a58c7daeb99950c62faef2921df3ed9be3aae7f6cd730b67f6cd796f0fddbee1d7e44ae9fc80a743b7898ffd41cc57cb83083d86e109a6e0d9a248a90c54572007bb7dcf2bdd0831697436f924de99ae9380229b67e8a8d44547ca6202b5f6346923a598c2475748ce4535ed376f1807808a5e4d553ab9faeaeac7e77e5c5d50faf1c5ffd7af5bb2b278cd5a5d50bab9f5d399e4cfe237c5c79417cbe7de5d895e3ab9fac7e23e58b9fa756bfbbf2c6ea8afaf94d5cf28dd5cf01fb9593575e6049a7572f5c3976e585d58f5697b16a0ef9e7d58b575eb8f2a69cf4ffad7e9784faedea85d58b6ae24055ed23d4b5b57df02936e8bb2b2faa7d2025ff113eaebc203e591f7cbdfa8d94bffa1bf6f314965d1139ecf39bb8e48bd8076ff03e7831ee830bbc211c92f5c1afe524e8830414eb032571601f281c209b41073dc68797b8de5fcb02dea4c20e6204d1b9ac919e787ad61090f37d40dc30c14a609b3eee02a313a3e590066191e5972317f2c59d82e4b2ed5af4b903f5620138f1c2c8c808acebd151c08e7ee5614766c144f8654995bb9a47f85c4d8967cf94da1765cc2f8ea4de3a0fe37db33a2a2ffe0c5e5fbdf760d39c4f6c3e91f904665faf4653369aac7c9af2a9c9a7229f7e7ccae57868bafa9f575ec455f2e9eac5d58fb1dc951761ad5f39befaa9b1fa3eccd72b2fac7e69acbebf7ae1ca0b7c97f9d258fd0bac695c12f801cbf0d32b27619a5f7911109d5efd70f5b3d5cf563f851594f7728451c3a960b57fcd6b864a2eac2ef3ba00ffa7ab597e1e13e23160459c8811f12136c48598b2566396441608912c182e9305e401323636682d720c642f29ac2eaf2ea3e7b5d53faefe71d3729a84e8ca3181e82f1a44fa49b939a9b6c8b2c9eda4501829871e56bddf0c6871646ae70cdb20569733f93f45ce26e364740a289d999e2eef5dfde35ef8a30427c8f788b831de6c927d19ca8806d34568f249fef8e139f5111984a8175669f8c122351e890384ead5d3ab1faf2eaf5e80a5489e3f3a4cae86a39e1dc9038015c17a4a0f274bd7ab6756bf5abd70e54406cafc91a337eb053d97c76dd88b08b205dfad7ec98e78e830e030c4ad18a73bc3b9b745eb66db0973d6f5e5ea8abeb62f87d796d3e9f7207d83a48a893b1bed479a5e73709c6376eac5130fcd0c4a692ad906876c2e70014daf2962796b5cb3484c3a773739d83f09fb51365b2da7036c5012a7de4f092f2524d1c2f3470b25b113df02b2213a74c13d12b8bb2f7197c49f5f5f395118c9daaff22a6fae9c5cbd30f8a93a674b53ee1cd9790c4ce8e7ab9f92d52ff8497ce1caf12bafaf7ec3f9cf4f336f48f316409dccea47ab2b500987baf27ae6dbf608d1875ac5cdeaf2ea27ab9f922b6fc2a693f9c61db32f5cd1bbc0e428569719d391f9de9d0368d054e2265d3901701fb39f99efdf39880655474175e565eccb15945ab44a1b689c00fa7af5d3ab7d19bffaa5e6aa14d1af7e79a35c9506e1b5ab4ca8b3ad32b9112e4aa93bf948a676c2dd31f9c860d3b08eb00deb1815d3af3522e3b08ef178dba5c6e36da7a3310eaba58cc336e365e771d3856aa146a84fd40695415d50115401e801730ee18729180db6648c836d1ac0df67a9e5b25f071b6d1f7f3cecdbf067d20cdbbe657672db7ab55d400e98012be003548027a7c957dba878c6c1b6f12c350e36069a7cfde05e76b6923dce63ceb555d65cc8961ef4304669388c273ee8353ddff7160680aa1cf1ffcfdebf3f47719c0be3f8bfd2957a7d168e6124611bdb248ebfc48ae35c36f1d7f87c5229a14cb534cdee68e7b2672ec2cb51aab8d8408e4de20b18b031205b18217111ba602c0caecac2ef2ba76449e697d5fb39c95be78dcffff0a9a77b66762eddb3b3d202b2b354a1ede97efab9f4ccf43ccfd34f3fcd870b6bc4bfa3515a62f291f5a65f61dbf175433e783b179a52c3b61ea3e73b729594c8c9da428544d0ae330cba17852c503b3cf39aab737847060bb50daaeb71550dea5d122a18f0e271550befe454a13ac1262aae2ac18eeb14ea0ef41ccd35a7b4b49d114319b19411a7b8991f6ad562b2495090bb396a7ea092d383e21ba0ddde99f154a5a6c9e39d620e71ac232fef2283b19d34986d14861eb52e8479821d08ca8e63778a71fbe99f2a63217cca3b4ad5c650aa76ba294a15763b4ad5f752a9fa7e7b1d3b8a5547b1ea2856ec5f47b1faa752ac76ba1dc56a6328562f08d3411363eba030237447b1fa6755ac40bfd99acf6fedede52b565409eadd92a659854132a956bc0e1ddd0a7574ab8e6ed5d1addaa05b891595173af9a63788a2f2b3811445a530d05154be978a4a6759ada3a17434948e8612fcfb27d550be57de9f9f0d7494aa8da154fd5c78d60231b6aa4d8e5be828551da52a687ea4a9053a3a55724c3a3a5547a7eae854ff343ad5cf3b67396c149d4abc3bddd8aa7237a87774aa8e4ed571547594aa74a5aaa3347594a647ae34a568209d1d681b4403f9f5be140dc4d8d7d140be971a482758baa385a08e6ba7a3a58439f927d552be57ae9d5fefeb28561b42b132856a9529d2a986a84e65ca7b984e65ca3ab61c53c6a053c1c590290fb9860a7f35d594f1bd2ba05899b2cd342bcb94cd9263c2af41352bcb9415aa59596636cd6a081b401ce80255200914811ea506948006e007d419542b45d5b171f78fa6acb986422582bfc42a594431e5bb73f8de15c5948789a1d00a1b0f6047c46d42af52541df052ac14294308e8005336dd4a5165cd95752ceb04bacbc344b61f917ba759b8746fdf568c14d24ff5a1d4a8690e6416774f9f86fb91b82f7fd28ce7eaeec3e5feddbb2567f76e498f640f53ed97f399139bd14669b088ad9dcea6ee586a33f6ca9773ade6f07e6019e3ca9223e912fd04bd2cbd2ae5a5f5648dc30d643bf9c8d6a3febe642a2abe77050d91660a70deb40ae99051fd970f17d67f5f528925c618d17ecbd8560d07fb0a30bf473b15e0b2693b292a30361ce05c90dddba607e39843290a301f80eab8f4994ca8d751fd37d995aab845d34a740c29bf56b21bd5701daace777519042640d732e0a374f78ff0e1b21d6c23779fea6054362d54b6cc92adeaae6e0a346540952042b561dd347052acb0a68c396255d897282956a02843e3d05a15652c3c0d07e71e8a26f874334df0e9b6688266470fdc087a6048c3ea35c16aca118348a06549a0b648321eb0a0549140d3823f9a24e3822981ae25c9e6a02381b625c98a3a987eba1ed38a1881861637005a5ca5a1c5154ca6c40d7a4a9c1a51e27e98649d65067d0ef575fd9e18a44bdd82ba7ebf870cb0828e2d56c003965f53618521d7f00b9a07533059c126655630071d5630cc615650d4c12ed5cfdedb60e2155220afa1e750d7ef37118358e608a8c8f0ab636b9f3982072c551bd171c51ca10af20855904770c1b41d7304d46315b46032620e3a2efc1ae6b057a3a8835e891864f76ee979404d7f756cd15f3c6079d715fa3be41adeafc6da0b26fdb54999fe9a830efd35cc61faaba883f0bbb94b8d8c2eb18506822d3210a8ecb227bb4c6597a9ec708f63c601955d6ec82e7bb2cb81ec72207b26eb20f4e037497f9da63345df07719eebaeadf97c7e6b249b353f4f65126f9fbee634d351ee521009f4ced0c3ba237cc51fd44c807456f1211fe0f3bf39a2aa87b8e471f0805f9404237e7ae2d055cc2acb6780b3419c2c801103d6d455a340ed5762538b1c7ed4ea256bd0d4882d0fb96498d8f2b04a2c00b0aba30358c96ec19aba04a8bd8f01e0856f009100a144b1653ce45f317d335695875c795885ce0ff460526acea658baeb8a63e8f30d50564a5d4de0c0a22ca10dc27e6b37af9aa4530ed21217cd0ac248c339f438dac4b22b7b197ba9cae4f946a90998db8c1e47395e82e27836e286ed96950d1d57af63033f1856b26598f679f1d639dacd48c3facc3a26b842acf60f48f694db012344f38ddf32b6b162b69fa9769acf246dfda8880789c874760dd346362980799cb680c407d0190a94c984e62f21b906064b19a799d198bf86e41a48a95e49f46cac2255af247be67d96934b5a0ddb98d8c9d68ad71157af8b8d63686c6d150985ace3bfcc0bcde3bfcc3f1cfbf821ad94d81dfbb8631f77ece30d6c1ff78a97d0ecad8a7015ad63247f678ce4ac36726613f9915bc88fd440ce681f67358f3bd6f17aade3071a65b75e0b395be45d4acf8e95dcb1923b56b2cf4ec74aee58c9df432bb9b7b38edcb1933b76f246b693ff2d652579abdb594ceed8c91d3bb963277f4fede47cbeabb7b7632777ece4282f1d3b39ce48c74eeed8c9df493bb99bdac96c8b76eb76f2f66676f2f6f6d8c9ffd6594f7ee47672005ab6cc4162dbaf84261b6fa7ea16b457758aa6ebec72f7ec515fdb82e841ecaafd229d792233281857cc5640cfc59f4c3637f6e5f4ea9c41bcbd1d6a6e0ba215aa5701d7658c2dbf1dc48fa3b1733b505fb03735d7c094a8e3f4d61913d52f8a844d499485ea17259b5d727ae8517a8d6e893a4eef62889ee31a0625e7b886823029e08036d4703a1763a47d0cd12a454d76554274cbd53132dca0452f933df2ac47c975111ea2d0b418e6b2e4ba9c7ef91893001561b1e4ba1ce12a210e31b61d4a2628507aec2ad9b312a3e8f78a5739b9fed04414fa1483811b79a8453bead8c3dc572295febe6dfdf0c6472b76442a7afa93995c5078bb1a7b656268ba8568fe10715a38429785c3f55778ffe8ce20ba4b561e266c97acac57c72cc766bb643559c760b8b806fdaba93266c947ec20f98859724c9a7dc4f0b38f28c4b1b3a61f095860f443c4799429d9d08659c76eb663d697b25cfda288e9c32d135bc7362b3a44b555562c999aee0118441bf28a16210a9135ecb2f722a3f9f8b2fc53f955f997f2afe557e45f65b01351d64e19ac3fb4d62862d6b3b757cae72581f9c720a4f47c2471982c91c309f0b59a7874a7e3abd531036f49db8ce9eddbd47522040bf64dfea23a661574d5209eba2fde9049c17faa6a7ca491cd983f255a2aca76aafe8fd159ddc2b6c3d5ff9107e3e002b6d5a40d40ffede0a9004963202ba89e1dabae67062d66c75a2c660655b26355140f14347dffc31ab72e3263cbe7338356b263ad54c4a0ad982521ab64f76e49689648dfabd53ba763933c6a9b846a3be2f3a8858751bb96832d4bd5b06c3a36865f1d5bce6b26967159b5d8b58a9d7d582625ac1a5876f739140c0fb8fb1c17cbaa452f5dcb52b18cf7610bba0e10437145c92d62c9405ccb9180b8bfbe5856a1a44a4050027212d0928090046424a00275247d7d31cd5d1c7699ab056c2804cbd87688468ac460456c395e25de57824ad37648c16505d5c21a96356cb9c600764482261420b520c95893642ae73e49360b926c6a92ac5919dde66a41c69a8c2d19ef93cd826c6ab226d226dbb8f7ea41a51981f6be92c9fcd97d1631fa516f1fee1778cd05d059d28db4d4556bb0be35c1b8a6c559e1b2ac09e004143df004afe13e6b55fd40ad2a60d702ddab8f38d848301b4ec531a0167113d0482e0e116038190776f699629411fd0fbb964540f854e46dd60207b065b9221fb0e2120d8bb37150f72e1ac0ce3eb7d4cc0b2c4ec9e10286742f708241eae6352d85db3770020300d7070c2cf17a064e6000e0fa808baa8607884378bd034fb00fc477065bfcde81371800d69a776303685d0f29f346e7b8ea0da175d9157dc0d4f2b81c75dfe67a723b50eefef5f02397db46eba623754fd0ba9948dd93b46e3652f714ad9b8bd46da7753722754fd3bacf2275cfd0ba9b91ba6769dde791ba6e5a37e5ddc53ff8dec1a470f7af03644fa4f3fd69a8db16ad9b81ba27a275b350f764b46e0eea9e8ad6dd80baedd1bacfa0eee968dd4da87b265af739d43d1bad9b82ba6e5fb84874d31ee189e37b84c78d7f736af9e2cae195a3f7df5a3922af1c5839ba7c9d15df58beb87c7d79465efed8ab7b5d5e7963e588fccda995a3cb9fae1cf60a1478f9e2cad1e509797966e5cef2c4f2c5953796c797afcbcb17bfb9b43c418b40a1517f6d79c6bfc8a65d6f4c26c3faf7fdb7beb9b47bb7bbadbb7b707976e5f0f23810bcb672b47131b372240ef0cde195235400bf62e5cecae1e5cb093c9757de58fe1c0a5e4d564d7d2331e5e9fef7df9297afc9cb33f23787e5953bf2f265797976e3eafe1bf604897816c19583cbe32bafa3e58bcbd368f9e6ca91e5eb23cbe3cb9f2f5f0b5785358a96b20b767170b1f040d6add5c4827e5ec1e66905d18f50cfb6d4508da4e42d2713cc25c56b6b0e413a8d5c5f390ad867962f2e7fbe3cd12c99e0ca81e5ebcbd7962f36ed10cd2998061d366696afdd7f2b034761ab861158b973ffade5d9fe744aedb46c96af2d5f4f4fb5cd58e25a36df1c5e390cf77512be1ef00de01b378d76a43cc6b56f602245cbd7560ede7f6be560124d60e488418a0d34dec809ad1d1180d240416f9dd0e8e137e783eef0d54c7218583dfce64a448095d785668fd7ccbfed658b94d994d598114021350aa2b987b54a16296b78906ceaeabb3fb5f5fee7fd5d852de1b068ec0c16d3a6894003eca3a089a0e2cd0d02cb6f01eedc969c685a2b9bb6c3166dd72ec5eedd4a8b12040a7a7309b6500196df124ad0d4fc5c7943687daebc91d5fcdcce4291bcd31f5a37407bb63531407bb6b5c302dd833b16e846b040d92b6abf0c33fb732867989a8651a564aba884e95f53d309328836541d43c3aa0a55ae6babc826aa6313bd3a66a0122e2aa46463035568a13a6604ca258a28971e352f2ce339d4177d0219f9dc16940344068d89c1410938a125c60d2d0eabaadfecbab414fb5837c4eb7bba7f4be4fa99d8f5b3a1e015ff450f46d3b1b0616bd859639096456c57a3231cd671ecbdaa3358449b4aa492988406b14d50cece710e154886b7e474d775b08e0d16c765a8068d8bf56a59a5a3c6d52b8f44561a11d41e4accc7a967655b355cd7f1b9a517223675014e6f5c9b624d700aff062c824b5c72c58c12388d2171c4635c14a0e3301f47d822df4a46becbd53175185e2216c9432ff8bc2b02941cde79489368d305c86714a0e4ba254c5f7920c6ae6cc1f0e705483922f0d03a4e8b37a192518661d7f4290dbba688fb8a001d87fb28c28c7c4702e73ca4c3c41ac0daafe95417cc788dd9ed71944339f4b807ffc330022a64a4fe0fb1a9b409eeff4860f3c20c7f847abad1f3685348e0c8f7c48b50ec473b22d3ba57bb39a8e605fbed51853e3c55e4c373b0aeab25d7958b4463051d634db569955b74689563ba25130a256257c718b46ab012d1688b5da9d03e9a59c20c8b65615a3364ba9a5b72dd6cee3aca0f63c6e384b1c178600c78d48134a54b897a1419b90c5e37db350c1734422063605a7254d586df12b14beab0aa964aa6ec9816ad2b136b884169d8a585acae349beef37200adec987299c85ab30573cfe3d542cfacde2c29c59b25e9ba24f466a584ff41bbc996961d9cbef12b06b605f59534b31ff1f98abab75ae9aab160433ec76cad99e1e332ab2520d2898557af859dd6e30572aa63067c848c7e0f65ba07a8e8c21c60e074e8a877460018f6fc105523291c44d6b1875555f7a218fbd218697f3c6375cc76aa63294e1f5b759ca48e6d5307b1a71ef35c3da2463dad2dadb198d696d6a8a4b5a535e6d3dad21a2b696d91c6353a0d36c09af5c38914dca3763c061bc163b04798f2704f9353c3fc43c340dfa0fb11aa57fccd10744782682b446c2744e68d10dcd3c2d4467e10377e5858d3ad0fbef2a3e0826bc97a75d4c0ace8546fdb5ea55af29a8bd519af6e8f55bd52280c79b01aa914b045cbd9f5208352a3748004454ef102baec2a51751450c8a0275667e43dc0cc3fc529f1fe7e880c478565d32baac790820ba8a449cd548aea31a49b564135d280e31a051730ac51548fa1c25075d412218da81476f54a75ca765c7f7775497bd00a85aba72f1f518eb0c1d91bb103e5f6544783ed891c75a27154959a38a8942e0911d5db1ded240f5d8d46c639490c451f8353bda227f80b968ba035794eaae277666fb768a948c18564df7cc03a4c2bd5a964ffc65e69069164bec270380eaa8e8a0f7185b68eb6c184176a1b9d9c621b43dbb084da8695a26d0cabc492f7542f0d5b5060fac630cb1b050a800a1a80aa69c491b159bd15281c2c6b94e9658df29246552f0d664f1a45894b8cb4141096a274a510d548deb3eaa52689cfb26e4ca0479a0e16093dd254a5878faab24eac418b28aa3c445c45f50f34556598f895cc3e19458d26f22196040825c02701aeac697c42679a0e91d4234dfff9629232872465d35676ba43a66b29ff7bffe9a2aba2eaf9663a4b2fd1b16aa40046f5153e5cfc504d01ba64b88b422c430cdf4e3545c1869da2a8a81aaa206104ffbfbb44fb7797d8dec1f1c9ec25b193e593005e2a17b29ec3e5a17b91b856a27723990bb40ab3b90c714ea60f149521dec9f4413617534d49e7c2690cb2b9245c488d5c2ec6da4f9727d648c653e5b7a032b15453492cbafa0bb28266f807bac76f7a7fb303bde285b1911cda5b2486afbbd0791afd18f548286f0e13049f3db690a31ab6aa102ec601cd1c2ca13da685746c0fba1a7c8df79a9662a301a2997b256ea75d84a0a2e394ed1d5d5d05d529ba03d2a0a97b9f66ff47b56d97d85d4f3cf1f45349246c7da997b7bc8438c7d2fb27e9d393f1d1f328472c2ffd52a03dc558fc2d9561afea144382152cacebd85107b1860ac45088b5833e2e5b9063a93ab11d8b6ca14f5e12a542f660577338fca62c1eb2a6ffbfb8a9b7973b04290baaad8c0ec9343c7b88ae1aa2d1b1e974cc7974188b7bc5dcff76cddc5b24c47db8a72028f33baff05b1d857f6328fc2f88f753585b07855b2a3a5a7f47eb7fd8bb903b5a7f47ebef68fd8f5aeb270f47edff8e28b31d3db725ee33e9b962a5f1854e1cfb46511b8b696a63b1a33676d4c687a536360df9eba88d1db5b1a33676d4c68edaf8bd561bbf57eed1178a1d4d772368ba2115f2b7aa53ec3561c8a82ae91fb56639928ccb811e199cb4e616fc93d64a811249ec0c27adfd966d750c9162419596d36a506534714e45a8b15752d47583ecc5966ab363c15851c798f1429576ac12e0a7020c55bc9052d7664783c5834a553fa854cd1c54daf673c1fcdbf8400e070bddbbf69c13e673bbc6c3c2b21a25b6415443d64d6c28846d2f82dfbd263668c1318d02b168718f458822db06318dccf1b4aa24eba6243baa24ef855f5392f758926c9b19ed915daa9c37e55755f9b7a6fcaa29bf68c9bb9a9d84f548ed91adf9fcd6efa03d42b7e40c994441a69e628600986e62cb480103ab21301af8609e0d02d8865cdb2196009d6f84d038dcd93d56f55690765c80d93743da608598c44a0fadd52adc1d3a39d54065c24efa00fb2209148aade5025003432534b6b63adf24e764b27bd1ef6e9214fb031a135d15bfab421211b9e1a0da64cf7cc0b3091f8e140b049a93a686df7d4825e2785a6804aed76a8bd80e1951b25a23a25c270d5535aaab8e8ca0d0f533a1eb1f3f87b675b353b41ca6cd2a4498bce43bafbf563adaeba3d45ee3fa6b34f947eea7d8a88eaa566e0bcabd48f040d1a25940f2d5518b1d4fb3531db048759466faf809c11a3c1d84815c529d22c17a11ae7e5e9d573528fcaa3a6f609b21817ee8c5ea8c5ec48c422fc1aa45b0528cd4eec250a4147e6d6a1a560bdeede9e79c14ec1f40dcc738f7f90e98f679f6f90d584d7219f0e8b3e633e373928b3210284940bdb77a09f59a7ad1c06a8176808a5fb99e1c7091877175fcab17aa97b082cda0195be12b54dc697ae30a57bbb053c49621a0df18825e53a7d2b8fe4da32200299f0afc16779a4c32478010542b868e61f390515c3e4f0c11c313435310868d14b83123fe91a87c3d7f47f822458915eab03b82924811dd11bde42b9b3bc217428d91a330a6e88b69ea629350e7a6ca62565db1e5dc8bbeae98a62afedc305417e142135571a75e1db5f060310532a22df2c142dae2cf0da37a0961550817416713130d62d521fd22d42daa8b026d11541781aac834c5ea0cb28b6a5211dc817283d5f9b286916daa832a6f1b96a729f29bf51d28675467541d269ba49ac8fa0a018a3b50cec5aa85b081068b9aa91692caa297ea3b154ad981721a4c1f717d9175e634e577a09c5ebd925412fd5d578926b8fb039a8a938358a9b04e5eeb5a554365c4c0237a91a71b66500d615a345da7ecc23c1df760d213ebbccac7504f376dd9062d066699938af1ec31715593e14ed118790ae3baf4c587a52e163acbfa1bc8d919531677eae8456caa9a46305dd7cfed34d0cf08b62c4c15999d3aca57cf7b3a98817ea60e68c46b31d00bd571d5695c3a5babef16f4a26ada41c5cfddc122b6bccb5f553f37b0ed30058e36ef72a9f2e95df756cf070a246b6e6891b4f9f381a286078b4a265d12a4829e200cd37e3c314006a6538d331592724d7549970d01304ad52257f394bdf30cc0d724292ba9aaa4aa54a7a926c930f6aa5aa047aa7af5bcaf45aa832a568286b002a91671a03eaa36288faa6590e6eaa3aa78f43c5a1e198f8087dac3da4c77ac4e8795c7f374d0e898eea423fa12e6eb8e8a507754049ee834e51165d51e535da0cdf44794498144d934c8effa86b9d615c9264110c65645750b459156170e80d8b995be1e84aa9462f068dc428ab618e6a13ade4caf4451c5b28855a5d82fc4dfce80086c18a07e89bd9103456048350d1e1075370e105cc0065254b3905ce80f3c92fc66ef0c1cd3c02a47cb0c9c91b49d24bbb38008ccc900e0fb225dea26e07b233598de84be486e2bf535ead5cbc943d9431bfb2f9b3627e201797aa65234126803376400d08ab289326a9b593c918f5cddfc2e3b280b4a47e3dc081a674113aa029a6851fa356c10d532d98a3414746ced33653ce005919af26b6ef53afcd53453c605d3764cd9263488d4944dd771e1d70b22356585d01852d182622c86f4b5c6c23f3d1b70c0f2ce40049af0579380a404042520162cfd670e1f4d8f1e3575d52898b2e61a363d0092d8b25ebd640d9a16b1e5d7cc6162cbc3c4800bbb3a3a8095660ba58de051331a3c5abd644980d08f1ead8e0e640d1f35fdf0d1ea25f93593c68f56471ffc82ed1ace8ccea43af529841d48c84aa94a140736cbf9d1e27e6b57ab1aaf62eae1227d45f33542f3cb6ea22fb154345dcbdeb4994e4e3d74c5aa3a6ad38f46753447b3d15255271e862054d9b2f2a1e3eaf5eae883e1c453dd32b2c214bc4c8ce0ec7c3494cdac23621a4ed33bb3162e5a1b8d3eff94c7be32b6b16266bb432db0d4462d39725605572a750f6d93544321affd66cfa69c6be436d36f6337173e3c1206486e3b1627cdf31fc4e3470cc4ef171f075f912f629e27991d026cd8fe21956931cd7c00dd8f0e560dd7491e7219892848f6f6429a8b18154d2ba11737429a4d0b0b239a95ea15b11a0f8de288e6649874438f2776b2b511d19c903414d26cb616d31cd6dfff322fcccdf597f9dcf74957d63abaf2a3d6950350cea1f76b3b2383c535460f8b847f393bb703f5e59ca2a928c4db1e810de6268c54e6fab7c47bd2ae8101998bf64ed42711e89434296198831ce63626257f0b46125c8fd163bde2d468ad9eec5e0ca80d9b56406cd8b438a0c51825da234e082a397494808ea2da011d45b539a04a8c0eed11a7c3ed9a6f8c5dd1540dd2183db834391df2f1d1f3fa25c68fd6271154c2e3678707d0e4f057a9248790231badd573a1c361fe903cf020f2a0c3fb4d9fe5be12a9f4f775f7831a10aae8e9e71d415030f55f61c7105a9fa6be55c38e21b2417f810d62c92f82056ac9796cd9f24e6a7ee6b12affc235e45fb81a56e59d607bcabb98e929ff060c4ff9d7ccee947bc93ef8cd6675fe02acce17c1eaf469496152125092809004542420220185f6ec58dca93ad89277993ab6e4bc6914340d5bf24f5c65187e2c62d356b764512063f7eedc30ce9c6b77a7ea48805a02cc12609500a70408a1c1c86873ee54e55dba9c37e59fb8f24f801d7957b3f8e4f55b9c3b517187aea3be61bccfe19c86cf6c4f06b4c3b68570ed0f1a6ec258c4f6a48715e0c122c1fda8d7dce29d08908e41d3342d384820748e40acd71a6d57ea8d57f735892b79116b04370b40eefb397130723c0ba66f4b93d0925f626eaede7008f28bd8d152d1b531fa3835f2182b6ac2ab00af2b4743e0190acdc1f46c50d9c08ad9a0b28129d9a0b281e5b3416503ab64831280add514d944ac87b3bb12cc061f39dd52681a5a05e1725953898d1c336cb5d06f4c124b8b59f0800ac7dcde28a9e9dab4e7f1fbb5ab31ac68c4ce7006f370c4364b58d3d411c534cad8c2fa888d8d21d2c5e9f692e95abc9395bd66f191ca74218c7fa8326b47dde231f73105673b536b1058cfa539cabcb39c9f44cfb3e20ef6f338ead926de6b16a5e18d4c533259f1f923dc9cef1fa39e6deb611cee60732a3c94e90fcefaced57e32d5b149efa858c26c6773fbb7ac399eede93e67ff563545b48defa80c18a2b7a2e5f3c1b98391c53bc40ca98e8be851bb88c0aa0d0e50e6f8757a723b50ae3e7931ae33e6b6b186f144c313ace152a2e149d69038bd3bf7146b984c346c670d97130d4fb38644ac6fee19d67035d1f02c6bb89668e8660d9f0a94eee0786cced8c0b0ec80218ae38461d90143946cb8040d4f701a26a0e1494ec324343cc569b80c0ddb390d57a0e1694ec355687886d3700d1a9ee5347c0a0dddb9a85f25e40f7185ae1097bf9f23579f38539fb8539f18af4f1eab4f5cab4f1ea84f1cae4f4cd527f7cbf589c9fae491fac465da36156bbb4afb4dd1b60fe4fac49feb13131ee0c497f589690a327944060a9307eb13e3ac74a03e314d7b1e95eb13efd4274ed6276ed26ee764287938ce51c25769f9727d628ac19ef0db1ab5e3f589b924ec2865e166aca1b99b863b20126720a4660320a58b2f79c24b71a1a5b8a45243482922d9ba2311a8b053801a50ce3169283f936f52e91a5557eb1307e9ad9a09d75ea6e25ca4ac366a4fd25af6b4346a6fd0eb13fef8841b40bc0603597c4e61ce1b0c47f88cb017e12ace4c8387e64e2a46d823e9d1f32879343cecf093e99428fe3624cf05e30fca49ff593cc2df9ad4f04e65e8d1deed4a81bb280365c11ea63414e9cea734df139daace34713fc1430014a7eb934732ec6bda92ee78a24fde916638c37e2878f301f643362b308f148f4adbb6373d06cf08cc5ce23d4e743a3a529ff89c31c5dbeb549f78834e6ff01651f88999fae49ba23d4ffe4c7c82be9d893d443a45f86786ea2a9d0bd88c704eb411aa0958318cf084ffbd3921da139506a384517deacf5337453ba4d260f231313ff744488e9bbf7baa0958258c70ceff127d26da561581e13f42658b94998d1f09c1508d82680b3d6b952c52d6f020d9d4d5579fbc589f1caf4f5eaa4f4ed42727eb9397eb9357ea9357eb93d7ea939ff67715b68493c16067b098660705ea5e1f054d644d116dbd2f9bb6b3c79b5fd72acaeedd4a8bdc068a7b8bdc7675a19fb943184c2a64980eb5acd8c9169efd6c236c11f4efaeea10b4c7ddb7af825403952d3ce8a8834442bf2daa1a414e91580491d754dbb123b831b2d482aa006a406cee4118e55ec6456ce590ea20d58616e4da4441d866b01aa5a09b0ab18c803749ec11a25fe33bf589b111aa694dd00ff2d408d56dbcef3abbb843a780332237d106f11205e23c6857517880dae62f0adf820c3ea3e7d819f1eb12c1bbad0fc277f4005d478ddbdcdcef93eeae89dcc7e6c89e6e822c74ffd6eb488adc9e96fd49e211e2df34f106d66eeadadee5ae6903ebf6268eeded6d8990723beeaf8de0fe2a129113a34844911c4ba797ce2f9d587a7b695c5e1a5b7a6769dcbf38bb34be74415e7a7b696c697ce9f4d219a8797be9b4bc747ae9c4d279bf70060a6f2f9d587a77e9c4d2e8d229796974696ce9d4d25940c55a2e2e9d5a3ac12ecfd382d7f6ded2a7ac982d06c46374c6677326c6e24c5306677ce6667cc6667c96667c7666321ccabc34bef4f6d2a5a5134be7e4a54b8cd225a0b374098ae34bef2c9d5efa188a2797cefab5971a85779626b246872cbd0d9c51f6de653ccec84bc7e10f1d884b4dd9f5a24396de9697de9197de9597de93978ecb4b27e4a54b1bf524e6bea577fa9bc77a44a0b26dd8ccd085c6aff676f119d4b420cc84cb9b160710d0f0e062c1236dd845ba749c3ef11fa1a577bebed39fbe8b74e9ecd2c9a5f134c8e86ecfa577962e2d7dbc74bcd92ed2a5b7972696cec27b27c21d392b9abe2b27963ef223ec978e2fbd0d8cc1cb85d268b67367e9d23b4b1f2f9d587a2f656fe9d299a53178d34571e94b67e9d4328ed884b0746229b1381084a78b416804fad27b4b17978e0ba3d36933a72f8d3f67e3c58d4d6fba9f1279fa5f682b25df3440212d87129c583abd747ae9235e9c82785b4028e6912201919aec0f50bccfc089a58fb841f40f4844207876bd229ea6281208e222d290fea593f0342e25d69d680cce0312d223b95e311b689a8a5af11ed8f3c907b65279900fecf9d407b66125c4b70f778392e755d2fd3e4d37cc449f7110741dafc879eea0a65b80be93814eaac777ff60e9d3116f26f32ed8647b1a2d1d5ffa74e93855f44e2f7d34124c77fcfa134b1330398306353eb2f44eb8f831e83f5d6a8817d57e39fadcaa46d94de630f664eefafda630b322fe3c429bff9797a598e1143889da134bf154aab1c81999759bc68d915d6f9486271e7a3e60948e6f2ef2698b8e710692cf642519dcd09ca7d4f26e6aeb26b6ff14ac256ca3483a26eb46305905111b5eb4c68548b48617a9712112a9e145695c887c2dbd088d0b112dc98bceb81089cef022332e442233bca88c0b91a80c2f22e3422422c38bc6b81089c6f022312ef89118fe5c2488c0a062c6a32fa898f1c80b2a663cea828a198fb8a062c6a32da898f1480b2a663cca828a198fb0a062c6a32ba898a1c88a68544551153a24549143a23e76a63e365e1f9bab8f4dd52fec97eb6393f5b12fe0225475b53e76875e1cab8f7d20d7c7dea88f4dd08ba9fa85a3f5b1690672540664170ed6c7c659e9407d6c9af63ccafa9cac8fdda4ddc664288d7d591f1b839e5075b93e36c5a04ed0eb73149157cbf88b007e4abbdf0cd766736c3081a586a0523301a514f1244f32a92191141743f224901a6cb72539837f93bea47fefb071b959bff02665b75175b53e76900efe74b8f63215e062b8ea24ad9aa232366a6fd0da13de70441a40ac06f5ac6e9680ef06bb112e1bcc45788ab3d2e0209b57a6313e1e358f8e47c4430f3febf2d5f82102f0489ea95fe0054244f7e98821db9e6aab11c020a4294abbc5e9ba1ee7497dec707d2c2de8c1833a511f9bce92732b25e0a109a68883045e7b78a23f8497e5c291e6610eed70883c06cfc0d5fa8523f5b183293b70286f9f33c6b85e11fa661ca88f7d8800eec27ee4bf2a9fd5c73e11fa47e82b71848ecfc1fa5832e68161fe737dec04e5124667bc3ec6897808f089818a1164a728c573f5b144e446b0bdbf01949459892063136b22aa34d8ee2f84c8c70584a103f693148314004de02a119473fe878513f010e00b01f11fa676443c5cb858bf305ebf70a97e61a27e61b27ee172fdc295fa85abf50bd7ea173a110f5c6ebbbad04baaa16cc87007ca585aac037c67efd4c7c646e83b7e80cedc9f8fc09b001f5d369b4c8dd0cfe89dfad8d58dbe252690e781073b8486ab7dc10ed1617f08f10efe7dfdae6d9469dce775473b846fe4baa31d623770dd010fc1fd693dda413842fcbb96b6956f1df10e6807dade6c2b5f5b221e8a6ac77df4a8dd4701a86361c3d6b09396092691ffc522b6ab8552873e8e7228fcf0fa1b82e37d51b0b5d5b6797b5b632b123d296b049481c79f43399b94e069cfb61ec13299460f5a7a2276cd9fceb854135be550ea0bcfc591d8388752d73558ff1ff2c654e70da920eb496e88280666b33c4bea0a15c189c57cfc5c026bb9671ed9877bcbf8a2a156ee580adf6bb961c5166f1836908d9de06e9905b84cb0e3e1e6225fd30b869d87fd7271a4422dbd599cfda868ad7749e16ede5fcb482ad85897580a36daf7f0e5b9690ed6f4360f119b0c3eecb799125ddf63c270b4ef49a954da35a405535105f7fac10d2925babe093285efec03ea2b8e91c5104bb81862091643e21e3acf4b91b3d52172f7983184e561a20de1bbc7886cdebbe30e95b0ec5878181aec6175007e35b54c2f2dfa53323573d8dc8765cb1d32a0d176cc3256b06c3bae420cb380e5b265daaa3188053e67f8673bd850b0661a24e0051b433e2f98f1824b941768005ee05753cbf4d2a23f1e2fc00a3602563c4e548f0f3c18e643600246d7536c7548a2bc48941109d890800709189080bc04c425a00c75b6044425a0d8966510832843301472d9f48b25d9754c0b9764db52e12b28df3d469c61cbc125b94ce0afed0e988e68cc130b16065124c02e015a904895284609b049802c63da3083c86553761dd9b600815c26b2ed6edc4cd5523e2fa5ac3c48cd971ea4f0b91dcd834613e0fc27b0f9120375e6c3c7cf466eda220385b35dc7c262b86ce98b7d0386e62956706513ff0c6fe44ffddd82443d289c0ad9ed477dde330d459797de3882f589ac58d98b910de9f6cc48e1adca86b3478093366e4b6b7c32adf1a98cacb2f057219bb14f8f28b53662a749df3d462cfee3933dfb75bb1e9fec4f41d932ef8d6acdc702b5f41830acc47f18c8867f1818c3ea7a1f8976ae07eec3a2d068fac495e1d5e54646d37f00c14e02a7ae82e4b21f030abc3889f5be66007a138062330cc5621300259044e19cd0a334e99d0f7a7b664672152f1d41254040955397b36c1743c0bfdf4d4f80dcbd5b1226f5967219fdb7eb4bc5f67433ffedd36df1df5a1dffeda3f6dffa27eafdd45054a360a3e7506e18dbd551cbc06554ac5e72f6dc7bc74025a228c440f63e6229d551030ddad52f9cea0dcba9de28556f18a85cbd6438a444414c7d003b6623ef2d0a0e986fc9579c9235dc70f5c065dc9ab338c54fb6c92707166f841d7aa28451bd54ac8e1a15a457476d5329136b90facf38f502af27df53dd5836478f37e3214ebb39cd344f6e8e142ab954a29466831aa3b3b905976e46e15aa093e6e9cc285075c6628e6a28554787b088541aad4c2265a5c4f50bb6269481cb8c9281cb623a6984324994890cd71fd89a38c5ea4c408a95c5d4d2c86512aa05625cbf5c8b8fdfa561ef99b8342c7acaf9febf961e3d21953f84354fc678ae919b1e85a769f82e6ce2cec28939f37994a3f4faf4eabce6f42376ee0e3dbd28f475e96bd831fdfeb93c7d5b4ba6d59fe3a5c72f0ad3c115b9e9e0e87a0636dceaa845cf65a305bd3a6a0daaae2d5747cb96aaa936d40cb9b63c549d3754f6abc12f760baebdcf716dd9de47ca0e81af8b6c969cea0c14d8496dc4f24e6a231973e60f610358615c501628794a9c5206b28c20d002324021c3fee7e02b2d7b5f69193ed232fd446339fc8196bdafb3ec7d9bb3fab786b14d71078819568a0e7065736e0dcb45b9e4f596cb29fd1ea8d7ea77bffbddefa47c5eeaed95f86e2b0ac0fc4c3c90244caae32a02b9851991299eab78889642461437b17f2bf3f62dda280d16b1b5d3d9d4b359724c1a7af302b6c92676ca54cecdb5ba4dcbf64379ece6b13c76e6bd50c08c63b9740251089d427a7fda72e40b179bcbb0fd5bc660986c01ca3a0ecd592921ca45533370391db6a503d0a8a9368835cdd3f141ccf8c7437cd65baecf218554865a3e912dced01eacd94d396a737c347c6c861367793582a379f1d022f3de4e6bd4d33d1f695e8f5487479ab323a52dad319fd696d658496bab7c3ffc1a0fe7acb2622713cf86f06b142b3b75a10659d98af516177c17a7166f7e7d70f1c6e29dc5d1aff72f4eca5f1f5abcb0f8e5d7fb838ac5595af8128aa38bf350b778d9ab5f9c5b9c5cbc0d173e9ac8e565eff2eb37163f59bcb9787bf14bfa77525ebcbd7861717ef1cbc50b8bb38b1f2f5e6084a6166f2e5e8b57de58bcb93817ad1a5bbc1087cbbaa61c1537266c206a48d0909811212322c604e488c7112e211a47b09697a817a7403690eb4b2a4f481a90648e317e83fd5cf639a71ccf03e414d007ce66173f067eae2d36db7246a95e5b9cfc7affe228fccaf4865ca383f3d9e2e8e2c78b97fcca0b5fbf1eaefa7cf166b2726a7172f1c6e227e1aa9b5f1ffc7affe2c78ba38b9764af7e7451946528a1f12f5e03763caee8cfd7afcb8b9fb31f188a4f020a80fde3a6983d1ba06d781f785ea4266bdba185e8c54b22332106b5255b62246e9f35aaaaa0f0d137f1f6d76f7cbdbf490e61789f17a717c79b9c4ac59ecac56be969865b3adb18985b1c478b138ba38bb31e03190f0ece7e6ef0e2e8e28daf0f2c8e2e5ef517f3d640b6adc769a1c52998491713197643bbfa164717bf581c5dbcc5ddd1b738bb3889be7e1d245b9c44f4fecdd179640eaa845bfa9a01d2ad7a5fef5fbcb938bf7841b8914f0440f7e6b13115eedbe337d3bd78705384bbf4788d74d31dbd83938bb7855bf24400d4285afc927db6851bf002806c66fbe2278b938b9fd117e5cee2e888770fef2cde5cfc92567c7dc07f8958bb7f7193dd8faeb5dafb5dbfdfd404f53a53b4ac7dd34e7448d67dce4d7c48d7bd7b273a6ead6fb9890f74466743535b69c42f6cdd041ff991aff72f8ef14e576befe16a190e206bf594b100a5293a832c73582be22565da0ac3230a23e1c48af291c0f0b676c25b02cfa33e3ded212dd95776ea1de3762318b7aa22326d5525e5c060175b2a3d329816f2d8228ebcb34c4f0d26f4285ff8a3a9f2ce826b3bae2def0a96427e53724cf8fdb5bf12d24bec1656427e810da00b2481a04f0ea8c93b0b0e100212801e3067b0a4f2aa5128b8f22e62a886bc8b68d8c6f22b78c0957f8975d5967fe1ead89177e101a7592c6dc0639e22a2c8001320023480249ba1932fc8bb0c799726bf3220ff52977fa1cbbb443db39a32528a2923e9bab4e614afad1ce5db57764baed68ff8ec082d9968b76c4a541917d4115bc54661c4362d32a2630deb1b7d0f3a30ddb62de154f86c1bc17bd675cca3457268640445abe9783f94bde12daf28f155035f15a3f7205d1fa458d25308b2c1cf80e6d92607325a6b38fe908d7d3bd7ab5ec2968a544345de9b989e58e727c4364be9a0d184c442d0f0d2d32f898e2dd510e30de7da617835acb962f876ae222930e42939871fb351051b05041c718df10132402c5cc648218e5a121adfdc566a53db442786ea080d6e6e6b91f51cc289d93830b6396d0aeb55c456220238b0b5798d79d66fc0d59281b781a9cd6dadb09e0e2ebac936dfcc66addf4f8559553aeaf2a3569703d0b2e65a58db6444a66e6a7fd204c32cc330e733e3dd4bc77249d87512da41d948502cec4d17c85303b142f8e3a158eb8c986d439e85cc5bcc474650382ccc304b258bed3ca8ce1b8a6bb1b059a875f5a036f1d56b96ddc1bf952c2b75b31cd0fece52b42995d7288f0ddee2610d28c33e5418630f8360677d4b6916f4ea15a33aefa558f02edc56d32b3c9041f399b122ac0906adf1cac4c29b33b2d2188735de92f4a113273b78204357d2dc5209ec6c4351d9f0856ad6f1dc85b0f0e514662268e9aee4145c70add6ee44587c0517a8d00a496aeecd522664bc1fd965e20ea4820b982ba040481e924d3191d92bac546f141ed84bb286fb2264b771875a88f66efd51d2aba3865b9d5acfe3e4a1f0a6215a163c56e294150fe7b1f2b96beba315881c92ff014ec36bba5da99c476f5ceb01f8a9536d75944db0d5514bf05088936e3c90b93fc4d0da67facc2454de1e8048b0bd6a0bfdc9764ab07d751eb3607b5ad0b165cbb86c55af68b28eab57689c3bfbd1aa57e4ea68a13a6f3bb2cd89afafce0401f6adb89583007b6c01e10655165d4f29023d165d5f9d1906fc199ccbb66b182e9d4765fa48b262f58ea556a786fc06b53a35ac96bcab3daaae3b7eb97ac3f6cb1a760bd8625372463fb4ed1a942aa547c900768a15d065f345ef72e57c7554ae9eb5e4bc2abfa8ca2f566fc8bf1265b7f84ee58ce82b69527fab9923429dd6e351ab5e410a2e208a2cdd9b561d45ba69155c230d38eaf7120086bd69d52ba850fdd412e18ce4adb6ab57aa53d876b01ffa22e8d44e871ad9e3a8568a436d4fc5a2ed883197f00a3d9a18ed88cadc89d3fee788d356ed8e6fee51fbe6a8eae108550f47a47a14886160d5846fff8005051d5bfb4c5001548dc83a2e1454532ea86ec13065cd2d68aa29e382693ba66c1307940f8bc8a6e398f0cbf6f6594456d4415ac8a67a14485cf52800452007b4801090607bfad42c7bfa1418037510cb9a6b10a57a19503bac40ac4153a3c5826a0ed3c230318805051b0f60a7d976bc806dc5d4013f655b2716e0035480259b62a1c088ca3a96752217547998c8f63ab58a07778e692b8bdc4dc37451127a8d9a047c9c7f5328a8086b1a69129fdb6bead848876411b19e0e21020cc5f2fe9c58628499436c1f486e2b0d237bd0b4ec406509d81498cae9215a51dc26c36d66c19d31b3cffa35a6d06907694bca9b3675fdbeaf7bebb3fdd2e3ffab6b338be6b4695a08c7cb32a01a6cd735caa1c791dd24a239b4beb927b1838e4e46581b740d15d964d0e4670c628b778276ba7ae91a6c85df142f6e4273a2739175debd3b675a09e682054ed322dc054ed74005d5b48c04d5608d9336f35739816562271007ab9c3ab1131d2b5e476c2469068b9cd83054c183c2d7c8504825fbcb3c37f633f798f297f9ef9546e67434b28da191bd5014eb645b078b1db5aca396b5631b55472deba8651db5acf1afa39675d4b28da896bd50ec28661b41311bc222b56c088b74b2ffbab9ffef678ecaff35ff16fdb9f947f8f9db871fb2cae3f4ea8d2baced10bb9aa4579f7f44af8e1df07e3c4450a2b8b2e9633dd0671bfc7902fe3c097f9e823fdbe1cfd3f0e719f8f32cfce9e9a67f699f9e6d621a61f5ecef272ffcfdc3337f3f7941fefb99a35ee9ff1c98f4eba66683d671aff4df47def14a7f3b738e95b2aa691e192000a80129a00344d9d4b4d6113c606d0dd4a6ae7cbeabb7579c19eb6f9fcfe6ff7ee6682f0c145f638b41a56b6d7160961f8bd7434be750d33270a871a104f4f8c09b1445d99caa5bc6b7b1fcedd8d1bffdf1d808fcdc792b91ca0bb596cb8b4d450c57cb89bb5a3a82afc9fe5b2655eb1b1b92aca3f5ee6cf8af5bfff9f793179aadc1fefdd49f52a01209af0c732f577e1ae36bee956846c4cde847882ad7ecaa696853dfdf3fbaf0dffbaff7d3a75ca0d5363917259435615da9e9d9908c0b86849b032c6d4842a3807e841a03d47c48fef6c6d1473c2459d6bc9b6b807f3f7981bf56dafe6dd9dc50486f7b75eace6bd1c6ebc43668983b1fc626e8eca93260d2105a483013f12ca4bf9f98fa3f17df1559469c266af5f4fcede861913dc4692a32d5e6f4c1ff7eff3d9129c46f5558cfe477cab783384dd4cce9f97f0fdd008d486003f15b2b4cb6cf1359377c0b089a32980043b863006c0803605868000c3fe06ddfe5f66ffbb643dbbecb2d6ffb663bb54ddb945f2103aefc4b42b77d13dddd8b8b5482b56dfc2603800a100192356ffc16f5ec6cfcf61e9498c64c8c21d5288cd86a85edfd361c628c180ad6dc8dbefb9b71dec6fddf9587b4011c8698b3059c0efa77710bb87723dab009bcd2a65de074845b3697d80d68a7b5d4ab0227a8ec1a6ac9ccb6193c3f408c216c14dabf1f1c6b18ed558d42caaef4e496f0122913a35022d6c3d917be97de3aa41a85f4cde1aa5128c12005ec7155521bef250edeabdaebd825eeb846a18035fe7ef04cbbc57d0c6bdb35aed04748e8bce7377b3bc7f7a6ee1ce7b6063bc753378e7f6ff78d0f0d77f4ed8da06f97840ef792c8e11e9f86c33975570f9d5a3df4f6eaa133ab874ed0c2f9d543a7e4d54327570f1d5f3df40efd7bde6ffb80b57de8037eccaedf5e3d7496758c819c5a3d34caae4f51146792551f84abde5e3df42ead65551faf1efa48a6a5e3ab872ed0ebe31475c01674fac86ffb28d97686d6723abd472f4e27db5272110769977963369a3266a3b1311be58c59188a493f9a1cb6d1e4b08d72876d347dd84653866d54346ca329c336da72aee3600c1be3d618a5c6f834c6a4311a8d4168c8de90b7215a439006e7cdcdb9f497e5b43fcee7570fbdcd489d5f3d344ef97887fe3dc9781da5171f72db3ea2a5abdcb6abab873ea1179cb6b3fe33f436c5cf6ec309d61607cff61c47c4099e8ba444a329128da648349a22d1688a44a3498946532452ed173d99ba36ad1eba4c253ab37ae8ed118a853dabec0178777397f8f31cb1c083c1698c4963101a2237046c88d3603e9badce4879743c221e050fbd87db43bc2e3bbeb843d7d14e81215f64cb729cf6f65bf202468426bc07bf1ea3833e059fd20761949d3cb27ae8fdd543c7534f4ea177c09bcb533b854d0a3a2b7d426f173c8b4d89053be4924fac1784d484700841e3f90fba7a3d1fa07d92353ac97b41d94c726a845eb0e9012ed8ebf576707d990e017cec3687639992e8a9349245ca1a1e249bba560f9dfa5f5d5be0cd821b90f375b16417f47800942d10aa999c608cb728a4f74c8ed08a13ab878e87646db67015927913c3767cb32739280328781ab26ee866fc87477e4dcc841178fc5c0eb496d6b84aac93b129f3bc3fbeec35613ad287ab878ea3f0d80b0ddb34209d5168dc34a1719b0654645822775b68e5368153182eef49119abc42883cebef3d5f42bb5708510946c4bba7420b3802c49f5184fb3dbb477ab6b29e23ec566e4d669f5e3d743cdbfa26d76d174aebdc9d364d355b3ce4e04b750486323b7b43d31cb78ffc47685bf76634321250fbd1733435d8bffc4b50f318dad6ed0915816ce410ebe6bfbcbe7fcf1bee1c7a3c93e83ca98e8be240d21d1f5c8746067744a9b3fcb721dc11364df4416cf45cf80e77ef40b9ad0b4717de0fcf133dbcca6dbcca2778954ff22a9fe2556ef72adf0c573ecd837c8657f92caf7b4f37af761bb7f6096eed93dcdaa7b843b59d0bfb3417f6196eedb35c0c3ddd0d60efcdfa61c4b954123a974aa2c5dcaf3eac4d7df5c9c2c1dad4c27eb936f5d587b52f6b53b5db72ed766d6ae1d0c2fe85376b9fc90b07fe7a7ae1d0c2fb00f2456daaf6c5c29b5e71e1d0c28185376b5fc8c054ed566db63627033200a97d267ff52140d6e6bfba56fbbc36579b97815ced334a018a0bfb6b530b476b5372ed466dae766be160edce571f2e1c80f66cebc18c7d8f718f698f5d8f558f4d8f418f398f318f1d8f158f890c6bc614707ee1406dae76bb767de17db9360b12862a68315af1d7d30bfbc35daec7206a37beba0ebcca8dbaacebcd8c1f8f0b8fb647d1a3e361f77067336c6b37284e8611fe306c808b6112e1f97eed07dad2be0d41d4c4abbdf3d5b5daccc2fbb5db089ef4afdeab4d2d1c6cb67a563bb1b07fe1606deeab4f32748aae74a5c387cddeda07b5b985a3b5b926242206eb5fc7170ed6e6e1a142b5a9da97f4f5babdf0e6579ff8bb6fd271b5f904cf85f7e96b7e1be6a19455b6daf5afaed3a92d71900f7bbdafc35457bbdd180d78db0f015aa1459206a43790a2da17b59bb5db0b87160e0acd1231483184a831ae42b3440ca2843982d93931108155c26fce87114cd53e171a25bcc64ab8f38d85376b8973a90283c46b6ed114699c76038fc3087c4779a7dd64b13be0bb8a1b996e4127df92d4c4071a103f66fafdf3f4ef0e64b89af6c374fd7b93af85f5b1aa7e3002823a1cbd1ce8171db7f45d5fa22c953a36c186b0092afa80a9e571396a14e47a723b506ef5dc68f85dcd6d63951f472a9f60959f442a9f64956391caa75865244035b79d557e1aa97c9a555e8c543ec32ac72395cfb2ca4b91ca6e5679ded79bb778af5f524c90700748bb2552f931546e8b557e02954fc42ac7a0f2c958e505a87c2a56f929546e8f555e84caa76395e350f94cacf212543e1bab3c0f95dd7cf340787a6d897b742d8cd8d953ab67f7af9efd60f5ec0d99966e41d5b97757cf9e5c3d7754a6ed3757cfbec7da4fad9e3bb07af61cbbb8484b27fd96b39fad9e7d9bf67f2f40b69f62dabf7af63f59d5398aec7cd0fe47dafe4776fd67daf943767186e27b83b61fa6e5fdace15d5af5deead92f7ce5343aa3e5e4d0c7446058fc7309ee6bfd54ea8f57cfde583dfb0e45fc678af1b44cc9bd0db8e1fa1d9942bd4e2f0e52f00fe4d5b3ef5326dfa52568f9808a738e968f53193e5b3d778c897acb1f800fe8f5b93700fcdcb12cd64ec02470059c00c106510f3ffc34b771da868baa1d3f7d0d0f3a3b68d27da129c4b184520ca1343ba8c97a5e532b28ab11d4b20d140fc30d3d0f9faf9edd3f020f325cbf4e9f9c37d67c486568235b0c65b31d6d0f72435b4cdad64335536441cd8336d31251c024c4309f3b44dfe503abe78e203a75fd71f5dcebab675f6f92a1c27f9b3f5e3d7770f5ecfe4c5d23292b9a7508a5aef0e7da737422fad09f46ffd8946823ad4540f41c4c4080eccf744ccfaf9e3b46f1c184dcdf9cab16534008ec536a77c2c47a6effead93ff34c530fc2632cc1059dac8e03a7ec4b02029da202bde77f14def3e7eec449c0b6ed2def3485d4fd6fdfedd5b3a75301751fa518a61845d618e7a4c5ea2313c32851648d873969b9fac8c430f928b203abe71226723eefa3e1b556a2080efb1fdf1babe7127bbb2a151f5314ac15a316d1a91406d9b76d05395519d06391acb3658b94d9741c5aff762cd528886657d6da5810ee5b3d37ba7aeee3d5739fac9e1b5b3d7761f5dca7abe72eae9e1b5f3d7769f5dcf9feaec296106e1d3b83c5e60b6a795ceea3a0fdf1594e64e2964ddbf1e39fd62acaeedd4a8bdc0606518bdceea5f350d21e5f9739be033df9305274943ac7b26e7c63bc3e7331698cd767c693c6787de652d218afcf4c248df1facc64d218afcf5c4e1ae3f5992b4963bc3e7335698cd767ae258df1facca78131ce7e4516398899b0c841cc84450e62262c72103361918398098b1cc44c58e42066c22207311316398899b0c8414cb1456e082d7243b460579f3e539f1eaf4fcfd5a7a7ead35fcaf5e9c9facce1faf4e5facc315ad568b85a9fbe0317d0f0417de6985c9ffe737d7ac207fcb23e3dcd6aaf0286991332e09e3908e869f599facc010a73b83ef3be5c9f3e5c9f3e599fbe49fb9f63203729ed09bfea707dfa20b04289caf5e937ead3271a6d3307eb3327c2cd548c44a751cadacd5843b6f540363af141796463c11f8288e4718153e54cb134c3eb93f5e92b54dc71caf41c13dde7d0bb0b57c30d57e9489fac4fcf846b2fd3ee17c3552769d5540cef0d7a7d22f404060d20e9974155d605cdb00071be23ec36b88c3017e7a9c14ab6a54f463f42d923eb11f4a87974e0675d6ba13b697cac603194353e94a4d55b908013d17a68d021dd304d5f11ad4f1fa137f4d3facc81660ba1f42ede810775e67096f5cf2d4dd63cfd07749c3e28e302ac91254ffa541df62787c3f5e96b6cad9347aacdeb9b94db83f5e9317897c4eb9bf5e9cfa9506c4c13068937475029a6a7e94c7400f9efca67f5e94fbca960e68070b9d39fae4ef8b3f4287ddd04dd7446f0dde02e237fd8afd2bf9f09d7429bc01539884fd28b731cb98385d134208583f253f68808d7488510790eb231ffd608062b583a6d0e5ae1a09ff3bf7289c10a16552340024b6bfd26637de6627d66bc3e73a93e33519f99accf5caecf5ca9cf5cadcf5cabcf7cda311979dcc6bda7f4737a071e045f4f19a1df9fc3f44bfd25fd081da37f0f8fd097e422bdbe463b7dcea6b4117857e10139539f39bcd1731f24056e9e38e047e8c975a42d108d67dbf22f88ee4bb68c0cddeb12ad71e31f4afe85965ce94fa67ad2390f427afe04f423d4931a152ebed3cd113fdd04b1e00e3745bcad19c7a11bd8f25a4286216cc505198aabd9e4693e3327d61a569388410f30ae2510bd9bfad376b96b0b6fd9de2cbc657b5b3c6a46c7a3b6113c6a2553e87331453e979e6f3f3c2e6f833f4fc09f27e1cf53f0673bfc791afe3c037f9e853f3dddf42fedd3039d32e6b57d1034c24e816f3ffae2db0f8e7ffbd117f2b71f1ef74aff73da2f7d7bf49457fac7c425aff47f6f1ef5e10e9f67a5ac06bc470608006a400ae80051360bbc75040fdcd2067b57cae7a5de5e896f6a03c03fde789d59c7bd305a7c833b01d7c4ea4ec2d3b54d7e27ad09ab8d84b4a9ac6a02381155217c98d5753809be3d35f68fff3c95ee1cf8c7c159a09821283ad527f0edfbb3df9e3fd3c40bf0edc5fdff3878e6db4fbe4002846db6fcffe7c3c48a68c8e0fff67ca295bef3ff983882be9d4d6471f4cd784e134b5ef98f1b097cbe49ce69a266f5ff9c3883be7df3ccff9de2acee7ad4b8ad0aeb7cea1f9f08ed6bcee399f749fee3cdcb22039ad354f1a616f48f37128cf8e63134b5a21785f3b76efaf6a32f46befdf0f8c8b79f7c915135fa2e6472851bc0d9ea9b72623b1fcd87c7c568f68a59fd6d760a9f70196d7bcad9889d0e0fc0b7a7c6be3dfffac8b7a7c6fee7c3d7e3414d91bbee98256288f461dac8d426866a5de9b9ffad5c16abde4140137a9e128329c49b68e374852aadd9516937824a9bba48bcc209d85ee1c46baf70c2b55738d1da2b9c60ed154eacf60a27547b8513a9bdc209d45ec910a7bdc209d35ee14469af7082b4573831da2b9c10ed154e84f60a27407b85139fbdc209cf5e8946677b4d9e9df11cea0b817e7369f9e2cae195a32b87efbf8596afad1c5d397affc4ca1b1174cbb32b4797c7972f2e47d7f1973f5dbeb83cbd7c71f97a94f8e1fb6f2dcf00d604f4fdb712d0cb57568e2e4fdf3f71ffade5ebc93e13c0cbca1b0092243d1eab02242baf83042bafc7d02ccf2e5fbfff1695f1fe5bf74fac1c4aca1886118cc3caa1d058019e6f2e511806d21f37005da101e80a0c405610da6e89e6b0d975ffad9523ff7bff5b2b8796675901c60d0a329326593d73ff4f89ca6f0eaf1c857b946858b973ff4f2b87972f271b8ed05f367272bc39ab1d97e43ece7694df24a3490ed7c79a671f42c76bf2f28cfccd6179e58ebc72445e9ecd1ca68d9ac4697fd74f165e7bb8f6f2a7f7ffc46e20bd1723cbe3dead8237ecfe5b6b0ed78e23ee625969589f477904494cc0d6bdac31c1da9a6677f953efd558be7eff3082696e79e29b532b6fdcffd3f2f5660be531c132f68e6e1d6ede27bc940e1303bceaf7ff94815832236ff33eed34a9575ea7c3939a8d976b527f7398dd93c3cbd7d0378797afaf1cf227333651f26ded10248a06e722dfe80e30a0e5abf0a914e00b96c653a18a518cd1b115ae8ba78329519cdf9cb87ff89b64ae237f4d9cdf9c8ff1f5063c9ddf5c13ae818b002ab1119b59bef84d62c777b0e0ed35f39f98362c75af8cae7cbcf2c9cad8ca85954f572eae8caf5c5a697f4c7483def25b803bb725f71d5bf46e20df4205587e4b2841da6acf76b6da831dd75ad37a4fcfb626eb3d3ddbdab2e0e376ace30d611da7e4383af255646661398e8ed4223b59b6f12a9fe0757f9257f914af3bcb71748497e32806f90caff259af7b64daf7721cc56ab775f3483dc1857d920bfb1477a8b67361bd1c477119b8b5cf7279f0731c0139efcd8a864c5784d65b45b47cb7f0e7daedda746d6a61ffc25bf2c2ebb5b9daf4c2feda54edd6c25b2c3bd0fe858332cd5eb29f662162b5b5cfe5dacd853fd56ec3351468c3546dba3643b31e1df492e92c1c5cf873ed3ac55dbb539b0f5fdeaedd695cccd6e66af3b52976996d4d9031eeb11c67b519931e7b1e531e331e1b59721cbd4f139a1cadcdd5bea85dafdd946bc7698ea3a37fbd04155f5d936be334835108629c3218aa78270ef1fec2219ae3a876aa519b39cbd1fb2ccb11e5c3a3eed1f42879f83dec19b31cbd4f713254f08761035c1ea64e96a3356739faea9a97e528538ea32b911c47ad6538ca9cdfe8c8c2b18563a90438f98dfe7a2996dfa876dbcf6fc4f2e37c75ad3f9d8f362f07d66ec274da3cd1d1173487db2161a2a3da4d2fd1d19136263a02a4a8f6058ccb5f2fa5263a1281144388fc51155a2d220025cccd3a921c31046b4c72c43a3fe02447476a3747e0533c029f4d281deaa43bdaf0e98e2a1df3e0519b070168d93207896dbf129a8083e5f9bdaa53345d67177d24b7a012a96c41aafd229d8d23ef0fbc3bccea8e9a1af02fa7e776a0be1c310a28af1aaee3e4b620b822967fdd1f7bcf72c5a0c72ec7348c460776998057183c31502f2ef8d03abd48c0e63d5894375dc36900b3cb0478c507ff8549ac0634bdea0f3deb3f0c7fcbe8531e193c7866e8f8f49548a5bfafbb1f66a450458fef32f803fff6b031a73787e3cb80e1f7333afbde0cdb1db01d6b53f716bf423514f2da6ff66ccaa1dce6f0cca2ee419b88ba8768c47a851488b6b35cd65462bf6afe9a62f4a74b91f32487510e3dee11492e9d47208d24a840de97b1ed6c48698755cbcd2c30008b65eefad77ff5bafc2b7a85f6b0e9da0cf0486769d352d000d9635a845e17d461127c4c34d3266c1ece6d357288180a481de0235241a203ded38d7a0929e4d080ebc0bd7a8a5dfa804187ff5f195b58f7b1ff876a38a440ac3f34da2d8fc3ff18304d8d602368ea8addc10ca31b1edce04e524fe4cf0d27987d7abae3374eb57f8d7fddec16edc19a4df8f72594f9fc479c3cea5d5de8d7a440a741c418465bb7fe18616d2f1886706bb804a1214caf11ea1ed0e284e77775a1df185a05f520452da84eb4113a3f897e14a81afff22fa891433d35223fc60c12e6404f0c13976d2edfdb18cb76527fa22607b4c5f428a62cc45aba504f7c930c500fe16896ed3eed516b508c1fd5c01f8f345c014b9b9b0f187fc89e40a6859ef4c68d3e551619742d5b1d265a050d16c960c957d3924fc3dea2aa91800a553bb9a312bc4ae2016e5d76ef6d4b0a9e1472a751718aaa51401ab6e06bed14b11108bd4328b1b1f509ee03c513a73b2ed0da2408e6e186774d1b1079d7b401418a40761ab47f18b49caf8e116b9fbc73c0aa4e6a9a9c27247c1cb45b706d877b1af4b07f1af4be8ca74133d212252cc9796b9f0444259fa2041425a028517a12d09280900444a48cdbec939102a17479bb4cc3504841ce572fa9b4d05b9d34ecc122ab9b749cbde66051ee350d8378b52f5a4485df5d5867351973deed3225a0220105284d4a72af29c92f5a92bc0b8b6489a6badb6502064000fde55e537ed19277e1b6c54c0872dbedd075d4b7d32556e2dc232fc39d77669500a689230c9aa5a689eea4b0672b85a148be3b51a774a7585a06b697b0eb20576f9a648cef22a367e8bac4126048645be3838572acfdac3a690f161d21c6462ab58645c59d71bbba50afba670fb1880106b6433c450f747b946bbc1339b4e95597d80aae6c46d850502ef466405bd1b558a3e212e498a85c340d53330bea20d690e56a2449da8f9106d34f52706593f894231a4abc4d10024c1b9f1434a29032dbf72b4207cdf0dd7fded871828e51d3c0631ee2e678e3072cf11fc88cbec48465c5f725c60c129e2f91a0323c9dbb4809ee6ae290ddc07f2802d01b64c266b8c877c8ace6249a62263481ef90dad29c6388336109dc87d49ae0380f9ba3085c88f41b923869b9920949e048a40639ff7968ea46dcbd5be2f80c29dec81ea20796d5ec61a435d3063a4eb747ed74a37aa67013a626dc84599f1fadcf5fafcf1fa9cf1fa8cf5fa9cf9f9669e9266d385b9f9f966969ae3e7f9a5edcda4faf2758cbd9fafc8dfafc717a3d15869fadcfbf4fb1b05ef307eab78ed5e72f50a803f5f95bf5f9e332ed354b694ffa50c0cbe9fafc31767d82a2b810d09aaacf1fa55d0ec8f5f9933ef0c5fafc74c64456df6f6923d9aa40bc69da6f96913fca30c8b4850dc2eb14e4342377938131c29314c4e3fa266501c662820ad38c7e68bc1f05793fddd4fc4920cb08be0ea819fa4986150675a213dc4c07ea22bb3754495a6b90337d7ee195a277ea3fe14eddfa637d7e7a24d470803ede47da919f3a89755dbbbad61bf12c927e0d0926520543eb8d7ea6f3d56794b9d330d1ddfa23e5f8229b789a260a6bf4be420b477d919b2068e4f9f21fb67e78dafaeab7ceb0816a8624925eacc1c54536856416269a732cce0b1d700f6d4684ed0c41a0833a579f3f901a405d9f3f43c79dc93d0a0f19cf74a8cf7f005fa15b47a90427e913497bdd3a44bf6117e9cc7cdaff4824021e1a59c992a08817a2d083d2d035928fa500157d3cffe9b37bb17eeb2015f28830522113b4e263f69e1c61d0821022ef6180d13c0e20f42515462f3481abf8fc7cc81986464e31d6dca2f1b1890d6efdd6d1cde979adb32694c90508b9a7a18a0d83ce56d60d6118b886eac4227573b64d3726dba4e41acadd93322bdcbba3de9bf1ca243207e5740a4fbf98774fcadeafed154e4741f55c039481dc3d0688d9f7368ab748f10e630d1b0a96d9af697b85bbd13d89c5622e800d60eecd78051c45ac50c48a4a0c2cc35fd3a63f31948a92f3a0bcf67b33f427862ccfa4bf7bd2704d197e88adfa85bbd144ccf97cce0325b68a551f1ac46725378abac250130760890370c489c354725c18efcdf35ec6e0b1702c6cd81a76c82e32681a8add7ad805683e1160e1dc50229a6adac87f90ec5cd3f51c5f99f3e8a2e719927b3328f410d241816aece326366fffbc5072d528b81ab65a173d25c8c2de542295cd2cc6625388ff505b8f1f7fe15d6f0b62ade2acda6532a8628d37f746a3bb1e433dde89d5e183ac7f0cb5a1d55bb4ad5b44a9c10e87089d1c68a848c81612200a46776d713c16b15d2db44cfb38caa15c6c213ef5f8708f650fcfe32dddedbeeefe106bfcd5d64c4f7c407d53fc0ea63e08ddfdcd573a59240267f4442c44e8b56a6aac51906dfd29cbded1d7927aa51ca157ca1178a5e20ab2b71496b3b10bb3ee30b6b1a59a72c91c36e501f60db8a39a728114dc7b77e08b33a05af7eec0bc246b2a299bb66cb985f2d0bdc9bbc75413caf6dd9343a66c973105c1e592a5d2a682e59a1497c02f00ff6c073e359a69109f23dbe3c8068eb0edb1a4da0143013f36e507fbec38aaed73a3da8c1ddb63079a2837aa9dc28b6afbcb845dbd7d666ffff39b76efeeebfbfdeedd7dbb77f7f7ffebeeddfd23bb77db9b1f078bfef911fa5700c1ba77092ce8a817cdc62e480cd282ac20264808b2c956a12c5b052a0c4822172ca5b9b34a78bf4949c7f49b7d4d2eab5650c68663f965c722778fa9fe558938c3aae5049d88510a2eee8d927ba3fe55e61becb3a0da0d1654bbc1826a8759806720c402740a5850ed300b59ef2bf5c9503f8ce0e6249c6ebb48497e59b5e49d8623bf6a11f997c4915f26867cef3cb9379acd75b64b7e59de29bf2aff527e19fa6d5c2fd9ef7ef7bbdf6dcde7b7f6f6f2bd64d48bd5a74bfd5eee34d4a748bc256a21ec1636f6a86f186bdc9e695dd9a2771a022d5d8846fab7a6426829b04d7848ef9a94613deea77be755981b89d1ccd3f44ac5318732ed5449f715fd3fb884ada69ea0972d7cf7e4906bdff5b2ce3f60474fd94cf1f0942d95dc1be500d8f4f58a6af63ca74d00c3f1d22434269e9b4684a0980141b1988240c98040515210e43320c8e75310543220a844805a74be041b48cc21b55d697c01d75a32f8ae6fc7c6435a3c763a3ea20dec230a5c44c4f6dc4277dfd37d0751c351c4571072be1fe8dea443a81fe8dea403fdbd2aff57dc7fbd08a8bfc8765c43c1b64c7fef1ed059017b3fe2beebe91c7895b0e7753aa0cb0d57544abfb576f49c4eef19e4de2896bd824a74560423c5af1362583f0aeaa52a6005cb05507275f8b16959d8235b97a89f2bbcbdc1db5d10f5d6781b09d89e87e710461a310a4e91ce4daa4e7ec842d4d173de1e882ebcc72116c25ed2501f2cd8f310df87c00c944dd426f673e9c55c0e2d3ad3babad04fa5828476ff605b0ff21eeadd3fd88276ffe009ffd2defd0329ed3b1178897a425ea1c7e80e4298dc7a7a7cabbe6f5b60d0f73dd19f25fa3ac19abdfb0708db4835d0ee1f94efbe3788224d9208812fcbddf7f4388248539be4ec6ec819718e085c8761e5edb7aa537c5973adc027c2f328a5b8eca867cbf3cf606753c3c7267a5c040eb7384f19fc5c3caedac546aa3b398b1335a7e07b77c21e5daac5e37b77ee1ed051f07dc935d808f99186857ea4615174d3103686ef1eb0545bde43062c9715756c39b68ccbd6dd498d5eaa43b63c746fd2f07e35f8c534a81ebe7934aa1efa9925c7a40583c6d543492183ac942dfc68081bc0087000f48134254ca90249200774800420cf10e7630fdf7dcf611f88b26ae9ac643a162b3816b937ca8a837047024852f28a36b159296b4ccfae61f965f937f2abf20bf2cb2579574687424b9d1e69d88d1f179f928e5e427df0c5eaf7e3d9531c0a71d02de9a138fc2e213fc23a8d6f136e352abb5ac97632d8e077279da6c0d1ac1169d009b33c1577d43ec785bb0786dc7ba3770ff8b1dc697ddb6aabc3e729c55a572ddd1618ebb1699367abf33f3a1cc35df425e0d9ef999016b3232df260b94895ec48151e2c17693e3bd23c0f968bb4921d698507cb90aed139c00f0b47fcb8f0efb4753fdcb1ee378275ef7bb34c2b6ae2ef352dc5de81fe03757535761b152cacebd8a13b8406b14decf8bcb503f5795e81dc16df3f801b453591eb40871e4344c1060bb904d821a21866815de3640fda2500f6a01aa5387cb141c1c661fc36e64153700f9042b0df24e78a02900aa69922146ce0e0370e99cf538e87884d0629a3b4841bc524f24a05ba144c78fb018e964850c2913410e1afbd695964d0f959e33ebd80a3a9360305ddb4945fc66c0294b0569835f5bc0fedc5373436056f8bee127f32044a1787fd8b6dc2bc32813795cb64ba0de33fc31e15f45ce86996e8034c4d1ace7eef12a9489ee5cf8f2740624b2532160d695b5d638fd98321cef9373171e79a2fb54732f9e9446425e944b0d77888ed35dee3ed3506f308ac135593753c240fb9863ce46a321ea6bb8c3d7b085bcc1cc296670d61cb338670b65dc643d89080a404f424a027c5c949404c023a12109180405b76181b441922da1096cba65f2cc9ae635ab824db960ab3887cf71871862d0797e43281bfb63b603a996c24464002e412609500a744114a804c025cd976171b442e9bb2ebc8b605fde532916df721ec2d16194e02bbe9816c276e6d1ff13a3610c3646e2337c51602287bc8752cdc00e3db414d77f5b6bab5b63bcb2657b71ff5790f3214ddb4bdb314eb1359b1b2b7211bd2ed9991c2ab940d674fdacee2356d3ba68d4f6564d5db349c75cfb0c0dca506ec907bf718e13f652143b7c9d3e3e74101e85e5c899d6e12fe97eb2b5be6bd518d341e0d128cf896f43e66a11ff505536309b7d40fa6d1ec5d48f08cb5c69d373bb7c85b99b4d083f84f6a83b36487b83a8042964fe83ef5355ef78402f1003d17fbb0c86f81bc388321c2f55cd07ff4fb533235b564225faf4f7a30186448ad11071fb400ab67872db680b758cc0eab04a34095ff84ef2233a27c80c8b70d122e8bccb82a012e6a20b89c8d23625cdf5d5fc5c3c91da9938eaf6223f82a745568c2a80213e6976651ddeadc3de010f92557ddea60a3e05aaefcb2e93af726b73a64ab858d822abf8c8951c05bf716ef1e80fff24bd8c28e8be597d5b26aa9f24bf78e19055385fff24bc4225b1dd752b796ee1d2bdd3d20e7711150feb6a85a2a20b97b60abe196a2158cca4bb8a41689c856889a41c038b00cac027b9425ca8fcf0de5845207525b0df663614a2695c62ba4405edb81ba363dbfa32f87b7eedbbddbedeee9eea13f4ff6d29fed3fe97f7cf7eeadcf6ffe8f9e2d4ffca14b4df249ef505b3081c46d43b426beb645d1852cc257ee1e7070d995f3d820f2abf7262da2cabf250681df57ef1e501d22bf8c2dac5a447e09402d221afab829f82a96f31850cabf251495fc32061c99ecbf163b6732ef04f65ddaba5893dde84d37a3c7f6a2f7a9fde245306ee2f4468fb59b792a72884a908e8bd8c05b90dac4dec365b36c8aa12249a1b850a19c50aa810d5c54f9d81a09a13c6c7b8bb88475d7718d02e67789e4b56aae220a34c41d28a722cb744ca40ad44496ed5c45ba8b132cec403987a0e2ddf74aa68191e5628b0364b35dac1e546247f00e942b12a413833809d552d7595f7e6bd1238f4d2b81b658f4a8f21a154693d3a0b05ec996bcc726b6b09e6ccc7b6c725b2bacab83398a1aeb074d6bd4cbfe322fca2cf497f9efd31292ae76d4b20da19695846a59497846cc297ab0c3a1dad4c2fedacde09498a0227e4ecccdda2d56774a5e38454f43b8c90ab70038714acc970b07e97127d30c193d92a576a75171bb7627dccece8a092a329e164345889e16133e2b2660d56334724ecc97e173626a732d9c1373bb3647816fd5a6e4da97b53ba18adbb59bb579b9360db2d27326e072e1003d6667b636252f1ca9cd2d1ca4e30ca3310ffde7bc223dd5e17aedcec2c1da54e6136228698f0b8fae47cfa3e551f0b0673c21e636916b5f9a141fc54671514cf2c20191f69c31faa7751f368dfd69ebd930ad1d0db3ee93618ed7e6e8912307506dba76a7e9a9309f2c1c841b980a1c44dfd4de0520ef64164187c89130efd2e7627f6d4a883fbbd3b35d2ef354cf77760f76ed54edb3da17f4949829788be07f626c36aa4f3bc6fc4d9808b230dfc4d3dd4ea7254c330b076ab76a73294157dea162b382b82b3665cdd7eed46ed5e6170e454ed7891e97864487f024c1d8313c74f0160ed1f993177ac54ee00980125868d29a8523b5a98503c28436ac3949801dbd031f819433776873b26fdee37e0e845c382c4c5bd30049f2ce0edf99a9dd81e1e111699cbdd300bab9f61378e08b3b02e28cc0488ed4a66b3747e0c33d0203bc9eb37844b9e4930f3e406eeb65a9d523b0bcf4f2a1688ad4dcf2a18d5d20a22045989fb03e20df1adadb19d1fa6924c275349744364af4194fa7d4c8b89f1a8011667fba05a4a979d9c29cee6f01e9d368640445ab9ec9cafc17423a6b1f51fe3bf49df7b8973aa6dd8630ed34a169a70913c7ce9ea9cf8ed7e70ed467e7eab353f5d92fe5faec647dee707df6727dee185445dbaed667efd4e7bea8cf7e409be1af5c9ffd737d76c2039ffdb23e779b02ce1da9cf5e63ed67ea7307eb73f37e6976ba3e7754aecfbe579f3d599fbd497b5e0ffecab4eab08fd26f983d4879fa42aecfbe5b9f3d416bcfd5e7de0c6ac7299f0da851e065f666509531b9ac3f22126724a4c6084871b1a52c424b9ed4125f48292e9cd4904b8a88b4fe102a26ec599066f61a1de03bff1f7bfffa1cc5912d8ae2ff4a9efd3b3e2d8e450b611bdb8c198219ec310c6d7306ef3d277e423b23a52eba4bdd5da55d0f699aabd92181419887f1788c6d6c663cd8c24880f50004e225224610714fec2fd59e2f127c29f9ec3de7deffe246aeac776556554b2d90bd45d8eaaacc956bad7cd6ca956badb46fde64bd8aed9b6340ea3cbc9fb36fde88647f61cf9ea47cd1f7d948de3518339781f35006039f72526379c72919fa7e03684f45206e01c26846e620b65e55617084ab373b1fad52a01ab3f7e2ac1fe170ecb39831b22d70e4f0e2d077c886083aa428fa55eda777a1f2f65a0d6d66c35bb0b36640db755d08d7f2b0b6ed288533d17e3b5670355b6ffbe6286039c3fea686507506f70d7bf678169f9af6b460a841f274a9e0620dc73da5f3f2268ce33f43c13f772311a9165fb11a276dcf9e11c73a45b0328ed8b3f7d87ac78f747af3983dfbc0be7905b9f37c12fede76a7e9797b765e1cded4594ecfb933fa1e5d2de3a46a8cd4c76c3d472e1146d0ff06097785590b943974be81321e8747e83749b47bcc5aa018a5f32d9499655f09e1063305aec0e17e5e005a08722c00aa47f1cd820c719b07ea454d0d02f1476c2c7835fd10cfd305d5fd280fb949b3505d3aaf86ec9b1f78e20b7f240f01ed13d0e82381556114b01d198ad3099f703b6cbdad9a1a2f5cb5932d8e530dbb2cfe8e88e5a3946bbb28a6362f62368bb41de319c456c0f7f31de8e54d686888af7b8ae2496bbd5c664c498d9c4bdaa801d72fa2ceadcdeed068c16cbbb2d6c41b7f3939dc78bc4fc45bdb8c11cc63e33d03cac40b03b3f4782a89644d44da50683efa7a7ac366d9d8563736b6cf7b63db8aa0a5eed903cf2509b4ee393dc7d1bb8b821f348e35ce5837e1ef83f095efa01516e5364ec5b5790ef524f2fedde03146e2c4e304a39e478c622d4ad0498ea56764c4d7953336fcf70426ca7c26cab1f4acad71dc9ab66e38ed00cfd69c754748bec8275f8ca56724ffb709ebe6df261ac38c01fa0647e162060a7c060ab1f4eca361da25cf9e131abfce275e8fa5671d01b7ac39eb9ed3fbf02ca8bbf8dab7109594cb386b8a50d7a588745dd69f1a67ac1bd6cdefa7ac1b8d338d338d61a799b075c99a6ffca1316cdd6c1cb56e58d334d1cbfb63e3686318cc0178b99fd02effdb04cde5e0fd5a58ee33c04a53b958e1d08b97f3276bdaba63dde7e69d6b8c70b9f828817f9a77dd9ab61e20eb81b0797ca0c631614b6553af75ba48b7ba0f2fb90f2fbb0fafb80fdbdc8757dd87d7dc87d7dd87ce2dde9387bb736b169eb22ac9ac3f35ce5af769a74c432b4c63eb42e3ac75c3b522f9b2710c169beb34e7abefa71ac38d33d6756cfd019a67040c4fac3f501cd64c13f61a41aa0e45879643c5a1e0e0ce68aff1a7c659c00918011f60035c8069fd0675c91425d69ab71e344e818e88ae7e88039b009c1cd6852957124b66dba77e3ff9b7f1a1ef27ad4ba16da3acef2fa0955ca244313dd76b93687d9a17d2a36ca3d55e8af4b771ebc1df26dcef70aaf1cc05305f638bd88974eb99cfe9bc6e1c1346960d6af3fe36de18b5e6e86a2ae224a4c9a38c5b37286863e46f13d6836712bdf6051d5937a109a6e3360001dddddf26acfbb45d13e3d8f2d4729902d8f2f46c9902d7f214679902d6f254629902d5f2145f9902d4f2345cabf5e7f2c4cd6c0614ed4e50c4d83476f746826c241697fdacdd0959bbb999881b5ac193a039b64bc9b7058b44479475a7af6cecf49ff74e9f8af57abdd6a3560ba43f12c2b633b71de5ec4b97836b506e2b4b1c0f25bec41243ab55ee6596782594f80a4bbc1a4adcc612af85125f6589df85125f638993a1c4d75962f826a12d2cf15bf79a1f278f0dd6785d6935a9a01cc241abb99d56399c3841135f8a245ea1892f4712afd2c4572289d768e2b648e27734f1d548e2244d7c2d923845135f8f247e4b13b704ae348ae871829fa782300226bb253da0cf61582237d1a8a6014210ca45ef9f498ed3ea2e7a8c4ac2a2a7e7b60788d863e7ecb1797bec8e7d6918d96373f6a551483a628f7d9bfb19ead12452e12c5dbe922780eb8562d3186a1166ceda63e7903d36698f3db4c7c6e1ef57e9486a71364218ec4ba3a948ca7c4ec6a075e6d28b97e33c642d5be493fe16989fcd84a118a7de44f182b017eeb8cd389f8ea4c0ed051743862ea8f3d998b5c7a6ed4b67ecb1dbe918ea711efce2621ee2df53fa8f27ecafc134838c23ab9f6c19f1f0a69c3d361f9b3319ba3c7de265638937f7184bce14cac24cc20cccc8066f1e3236fcb9948593e4d9989119de9cf4bac99b5467ecb1a9564c4e074f16c678b3943116986919584a99ab49ccf0a7ab23f73294794deaaf925ea9ade3856287ec0695dec40bdf5cd3847a574d6863387601381c8709380bcfd3f6a5616c8f5d85a46b508d69fbd248247bd27d39638f7d81a1f9ae38b0b42fae03c8a5514c295c3a628f8db3a7117becba7de904b6c7fe608f7d0633ff8c3df6158601c5107c05848f50da63d30cf09c9b71ca4b1d879759c8b81329711158980ba6668a15106c8d3ca709f2d17ae7a315cf3bd5cefbf5ce872a9e776a9ee7d4381fad6c9e5fcf7cb48a2d3238a4359875e7f73c6bca39203f194c9a8446fdcc1ebb114cbd0655bc1c4cfa0c92a6a119fcd45b907ace6db26086b3dc3a4999ad075dbe7d76435cfacc85788ab2e27390d144d06b1f879a43c721e2a0a73fadb00c745be502fb18a45a08a6c1af9da5601ae5548bc12882d5a81dedb1e3f6d8855483c1b10fe897cdfd7ab4c466d0119412af4867806c45f9ccbe340ce06b6d26c86e38a7542f3b35be14bbcbdb8b4d002bd41177bd9bb52f0d73e21484b78d3175630a402d2d3f0da09c969f06504ccb4f0328a4e5a701d4d3f26300fcfeefd7a47ea68cf4953b0209df913258ae2f6574d9972edb97c6ed4b13f6a52bf6a5abf6a56bf6a5efec4b93f6a529fbd2b7dd1da5f600ee1a317acbe95e3b05d2df05a0b1d86ca268b6fdaa6eb89754aeb42a070f169be4d6537135c96dccd6917e91e6e9f2e5480ec343f0b5674bc20df6fe2d7c7cae7832d5902b534fc197cb87ed5877e68b115bc1586dd3ed03df8010c765568b148b411ec55063a692cb8e37da29e935f9f90ed4b965b575e1f4faca6c2c93c7e75a9a4bc60741ba6d638ae161a497576d2b19efdd55db468a3aaf79abc8f4f6e3f76d9287e216f0503c60aecc43715b9a87e2b69678286a1bc73bebe178a7a60bb507ba487bb017e29acbf82d16d85cc605d28b774160f38224e3bda682f79a5522e3774baa8e0fb0c0e69286dfad182afd7d07029b4b1ade2debf090cd4e692f512849975a90167eb7048428098a9e62ce100c66579914f11e5d91157c40aa129de0df901e13ffba4c6ab28ef79a35420c7c80f41869b1c13d1e779501214547715154140f45926d7bb9ab8cf7e8f84015ffa607ffba86f7d6f00151c9acb63df904db9e7cad96175ed8d4c26d22eaea372b66b51bf1d911866f0917cb2686f593923c64484a899489260ff54b06514a4335522535914cb54e442aca79cba41aaf05b209339dab10665813e7d0d050c49f041a7d2d449a9810acbb428d9e2ed5e85468480c99c07a22594c002caf2462f1bb2003aad79319624ddcb480c17aa095265d6f134d46b22223676a26eb58ded4d54a3264f49a33016850cbf26ba95a239aac8811076db918e2aad44f747181569a7115699b2704d979414775a29410b0c475bcec917a248df413a41362081d2c7999e014a94b355991e379aec72437b7cc4af691d8f2ec794072f28aac140c729e19170b1819cf2cb0723d66351e04dcf35fe4e6d659498394cd789eeba9c8729b179d7f14c13df40dd1797d88ce85ba5878de5cab6fc8cf1bf2f386fcbc213fa792da909ff95836e4e70df939f06f437ef6ff6dc8cfab909f0bf50d097a5d48d086507e361284678568f82d8d68b840b4c3a62739f7f599f8d15f4ca5cfc4fbcc6a9f89770d0ecaba6ee20392412568cdc4ef1a86497f9904ad9978b7fce8143c3521426b84127644e83e2049095272941425e2c8d08f4e6510a2f754373ffa96148b788fb1f93d45ea53e0a12a4b06c1fb36bfa9f5941e5d26984151b19a3efd45aeb1547df301b9c7c82a5d533af83d45c2ef5565fca6d683294a4cb1e103724601fbd1b704bfa7e0f7aaf84d8d96a7c5f101d1ad2d6bec7fda5a193b83a7691c7c35a2c09e6ad5aca14372757377b214f0ab479749912441863fd602c0a00cb0a7bab9479634f2e8b2082d470690111d76c522e916d268a52070e887e1f3c972805c8ddd000293ea90211b48972a2aff723de7fbcfcf87afbc7b2fb658023039b7a7c0a755966823098500273f263fc0d7fed1455353489cb0270b3cbaa811458a15862ffeefa8ac2c14067e573663998e2c10bf42c6130474456e2ace34facf78918ab1214eac077122d15571796424eeaab83c7224eeaab83c7234eeaab83cf27edc557179e458dc557179e478dc5571796434eeaab83c7222eeaab83cf241dc55717964d87355147a29d21ac6bc14690d635e8ab486312f455ac3989722ad61cc4b91d630e6a5486b18f352a4358c7929d21ac6bc14690db95e8a20278af5ac5c252b6db1e1d1e5e14f9687efc2df3f2d0f5f5d1efe727978122f0f7fba3c3ce3febd0610a1ecf3cbc31f2d0fdfc5cbc3979787cf2d0fdff7926730607dc010b397e9e5e10bcbc3df2d0f4f2d0fbfcf52ff0c658e409283e9d8f2f03050fa88412d0f7fbe3c7c0d2f0f5f74b9f0b2192a27fb13f7fd4f91721f2f0f4f027d3f3593ab83d72c4e3b84ea9b5c595e35fdaa45ebe233ef709b225d026f1f412156a53bd0849f0007949748de05affd82e057f1f2f067c0e4c790f4c7e5e1afa08fe630b0751ff8fb3354f52360778ed5c463fc3ec37b0ca8a5ddb8e3b7aacfa7c398c34c8cba4f0e6722c1ee2b6c2101916cbe6e6f354cbbd1b069993ce932c3e5e12f58abe5bbe9dea40ba6c2fcf2f0b56e8178ce0a9d87426c0e7f0afd40274d1614c11b0a93a103f71eba0467f2cbc3c36954825e07de1c5f1e9e5b1e1e591ebebe3c7cdb1b305e8c9324742dbb23918d642074121aee367a41471e61816f02947ae02eedd11a300c3c67859cbb52dd81bfb4781e968f4f5cf273b0947cb13c7c57b86188e1b8cd81aeb94bd931407b1e56c14fd86b7c3fe1224e042b87517e02ed463f57f14d868b4f0c530c23fb928ddbf886c3c524002884d15c88ef3b5c04b1ac7aac3af3fc7abb97398660f863ae052e10cb2323cb234796478e2e8fbcbf3c726c79e4f8f2c8e8f2c889e5910f964786375c2078dc0ec2c212dfb9ad6ae346f76dcf62dbb6a1055e17db36a54724dd2b3d222d701f9850e043cc8202d788a663027ae01a91719fa9d03f551913b364ea06d63d1b0ad5b1a1505c1b8aa2d48c0d451f51f2946a3e91649e12cc535a794a284f89b4c659575f98538aa4846b047e0c59d3e9afaac08fa1b2d7439a447faa0b735a9194b26a87f585395aad3c36e43c56953c36d43c3ea4e5291e11f711e5b0be30876b041b3256156ca8f890460bafdff885bbd36ea6cca72b90f341738b4a359f7007b7a74915164a965c85da64760f77919410e04abc805b4635552b494a1268e8de6c015cf01e6e545ab8a489100605d043aaa6c925c9bd1a5150a24919334985aca61c24eb72518a1d83c25453544941ba54a14b734c711ad421730140512c1906d314271e259b86112f0fda624941865c9384aa649a192b59744ad2992fd2221749295eb0e014ac2d5ca21f22911e9965c78bd7dd1a2f5c8ae7b9ea649ac7efd0d4f07a070fe6f981f5722f14f33f2575b2d2b32197ac07b96423f2dd4f35f21d489d9250ea9412c3e68cbb717e84d17204a1728ef142e58c9df0e2c40443e5d092275899cf20f497172d87d20b868f9984672702ceb1849839dfc5c183d164fc8c8c97f2415b640a9713ad7b3eb5e679a7eaf96895f3d14ae643f50b87c869557c9ce3f6d8280425b9168f8f732d181fe73cb0f51954e35a3c444e3089f2c8c2575d1385c8b9160f9173add910390eeb799fe57c94d5bccf623ec45a3eca52de6725e37ec01e3bee9276e81e71c9b9b45c2af09b8676f55b855d509b536ec8996b30f0628150dcb83a0160165d4704df726394769491d384b83a7c046ba63fdb0821d2ca1022630f87029371de1e1b1f72c3f07d608f8db049e5050f19b1c7fef4e3091832f670ed4385849aaea5a142c25df0ec4285d03e7e26be004dc5077929637c90b1165ca416e9d4747cdb522383443ab3559141a0af56110d84d35a2b540da166e2a17d0732c2757bec61eae50b8092b5dcb7f6a5534ca3d3d59ee67ae04a3d17a04cda75aa544039cb3e6349045a7b0703935e137446ae583ecf844daef608981ef522e69e73c3827e23d424f9e170e9df6fa0c045ae5a2916679a16f84aa8624a812b87507eee92fe8ad306fe55a8c970c5104a36c9c685ca282144215ad940386791762a05ae1e4279cd0fcd2c52588580f823ebc71e8a479136f44deb41df14d860ff5636cabb55da64a12327cdc863d2afe5714d8213a73cee33ab79c189536ff2f6d7a3a39a468014a54409513a2e194a8512a13428094a811208e2ff59bc26cc1e7807eaeaf8e73ea274c8eda8e39f0f493deca14688660cd11aedfcaf2c85f46b4e96243b497da6d225e7bb777aafd5e02b314bec4197fad9835a31d883a20eb087a2d4db21bbd2b8cfda6fa492f43bb40375fc731b3b4994879ca34479887106277b4335491eea33bb946ab73cc48e124d7dc83b4c1c720e1387dcc3c4a1a2d4cb1efa8872f0607e27c50abf35cd805fd2afc12f43ca92cc12fcea523ffcaa1506aaa803f05b947ae9efa60e39acbfaa0af557d5e45353d93d369531d4d53dc594e207a7a69e7c74da9bfde8343019da11dba071c5caff12df9404d62ace1c118b6c1d9b0b85c2e68ebc21e9469b43b209e4cec4e8aae521a36d536c579726d071b84dc016feba44db1186ecf6e00bbfa9b3c0c1f2e300aed514d814be7fdb6790433d71aaf80c34395d388de8ba2804de221aa44206389d56230990af483cac3a47f7ececbe28b343fb4155620f4555294a1a7d1ad0e43efa7b9818523327f8875576805f94f37850cde3a29ac7035a1e1f2619f57587555c23b828e3411517553ca0e1c3643d9fde6f2e14363f33efafd6397fd1bdcd001d05a484d45aca79bd735a2f860b1dd6f3c10267f5255937244d883078584f0e95a4aada2f29ee713dbf482b4feb07242df9bcbe245525d189bd2429a89f100de9522f9d4b7128ffd49e0f005ba68589850905542066cab97d1c41d94760c6ddadbcfd1327afe8974c3bb98f3b7c07d8a6ab8bf8ec9ee6c6cbd7fdf27d24ee42e66d862093dfc3a9c7f76dba210d15a54dd92ec713696afdfb8e1d40a6a844434328f0fe5ae0fde73b4067b313e5744382cb908b522ec99cf1476d3ab0713dfec6566e632bf7a3dbcafd426c8c50dddc23b447d8d8cf6dece736f6731bfbb99fcc7eee9946f3d8d8cf6dece736f6731bfbb975bd9ffbc5c6e1dcbad8d1298a504257d6a1931adbfb118dedfd48d2de2f4ba05fdd64a2cec225e676564ff23a2366535e67a6027829528a91a2a3a8289e8c4e672645808d7a16a7b31fa743d9f3f027dbe3f893a9950a491169f6804b99aaa44047bcca44a001e1668feb589604eb8a376f2dcc695269e112fd24fa0e66a292cfd6c72c1e86d3f131ab6892e34396e262c6773093333a98f1ddcbe474ffb2b8f450748ba688359c50646e493adf49b28719117a98c91b1e66ab162b940da1623d0815c91e66133c0fb3099e87d904cfc36c82e76136c1f3309be079984df03ccc26781e66133c0fb389cc1e66133c0fb3099e87d904cfc36c82e76136c1f3309be079984df03ccc26781e66133c0fb389040fb37eb2472834f693cd72446e64f35e9310d124578854484d424447fd9286de210aa9e8655296d12fddef778f69d0895f87328a6a2053978ab4802697e462b58ee862ab16254d41fb4da58ff4c8799ea06a8f5fb0c7c7edf1597b7cda9e18c6f6f8557bfc3e7d09244ddae3f390f405b6c78fd9e357ec89339079c21ebfcef24f608a69e2883d3ece9e46ecf1eb50ec042bf3993d3e678f8f61f6634f4cdbe3d7ecf16996790e928e7849c05000e45b5aca7dcfe8a4f693a958c8236dfc238a9156619e6198b3274e01a37ed22460fc0cf8f453af01eb978349b3f6c4b0db221ebaf1fb14706206988fe78d8f43a12f8279999dd2807b9fe910af3e8b3e670186809b101319fdd09e05cde62e76a7cd76c19e10ba9ef94e6742c8b5703a4be32efd1a77afe80af71eccf29fce9b748705da37dcabd6c3ae0ace0ca533567cd17ac84b418838ec9f307ec51e7f688f7f49714f8caefd25eeae03026de387303dbf48f25308b3c7f753183f0783fc4f0846f839c03b6d8fc7dc047c3f856438e6a1303e6a8f9f43b02489e03cf78404a0b28b0c5622648f7fcee0ecf104df040f285ee56214dfb7d04009be0922884214d3a43d7e07d68e710e73be7b42102ece5f3d8a750ed6d6eb62f7040f823fa85ae1d63971d99e18b72726ec892bf6c4557be29a3df19d3d31694f4cd9131b6e9d5c6e3b3a5c798b4a65b081428754cd73b9d34160fb1753362474c83c7c1804b57e8df41a72af9447bf2dcb55890a769a84a4dfc9baa187501326de51d414b17a081194db0fc1bf916cd0ed61d3a260d40d957ed7e7edf1b1211860b3f6c4a83d3e3d4467035d2caed0314ca7c5f490fb5d9cb7c727d7bd03aa5bab35f73e0d345aeb5c4f638dff0c5c4f03bdbbfe5c4f53aea6f77a7bd537d207bb73d5d7d1c7bb71d54ea7c15e6adee954d84efcbefbb1bbbbd16df986fa6b3da8bfd866fd1db5262b20f9a21d28a71bf5dec3d2e3f771d534eab846b4c3522fae0cca52af4c536ba40ff71e96349a80ab723ffdd16549eb87dc41edb0a4c3533f797cb77858963445aee0aaac1b6a3f29e29266d2c4c7ef276b0f4ce8b120438a4c28435249a52cf512e0c8a0a935d2471847bd8432d44b183f348fb2f3f84bfa14648778fc1060489149c4fa1281bcef34657fd5d448b54d09ad00ce506e53d00b74817f03bdb28976a9fbfe73d4c9dedbfef55fdb14d4010bdc0bf0970eba4e97c8ef23b40c8d287a9518927318df8e0699dddc01f3d021f977eda822d5437cd05ed424ddac1a68877f969f43c1a5441f948dde326a8b9645b019d42594d3f5dc76e1fae4a07f11b5b92de11814ec4439763252072b00e79464d3cf78146a09044255a4589dab5f907b0bcca3f3d195d1419a8435896dc05af70908982e67669a222da9c5c3b2427288a2652f22c6cb49989318676819e7ec59c07aa1b0e2a69174f9d1b15ec9691dfa76beb72e2053afaf904c95381d5c25e1d6ffbd3731027a5ca1a765bfc8d332ba10bea732a5508aa56c0836ddb2d55f39c51204a3c7967fbe04d7d181de26bd95ed14dc81966afd461d0d4aa8a2a883882eeef4b30b1b0a43452549913462485c54bf914a6ffeae1ff5d4dd1643bfa20ba9519614d4437a2ba84735ca688054e52250d3117c106975b8f864c545a949a4587738cc8bc599b61c7a31b69077859bd633d9a58bd5905fc06fd0a4029b1204b60ea6126bda463995d395992aa75728a3bc1e56abeb469d7e0ec1c0a43228bb5f65fafda35f3ffae1834f1efdd2d16f5c069db6224bf4035925b85f65cfe4f111a982070d55932af8f1979a5aa41fda41a2195205f7cb8f8ed15f5ded518d3493568f6fa57898a2c783064548b1e17e83e2c8a6457ea788f72bf8b7067efc85867f7918ef37f001759dda99acdb8befb6a35cd7eec3f2e32f919a6255b2d73434550cc5cc3efc95963bcb5ce183ae61f922a9b7f12723723f295b38df13f79fbbc274fd16b9a3f5d17987bf9f058dc46358b766c22a2136d833a17c291ba3306f3272b92d1b4a9872e9288bd22162568d4c383d7b6417651434a2daf9bdd862e8b7bd87558df4f1878d6f2df47c86cd61493ffcf8c8a363dcf123449eb1ab3de4b13e1762ced8e31ee658d7f30a36d3f10eeafa6a07400b8db90e9364632e43aaf1af9cacc8d50a49b2e5f276579c1313615e526639292f29134e373a91b31716da7029fc5ba75d199d7bc821220907169a5ae19e647885f85db761b8e5e9ae36fc7bd785e6aa5f7871757fd2c5d592aca9f82d6940d2e0a940b485cb2aded503f7571359c57b4da54cff56cb2ade55527543c50724b8bb5ac5ef9a86497f9dbbab55bc5b3a0c0f4d5c5d2d0db0abab7b344a8f92a3c428297673b5e9dc5c2d1dce20b2efa69b0b2859329522d97c48923582df93b485cbeecbff308966f82fb2e2bd1c907ee73f2f5cec2145513d6252fc6eb54669524a9400c54bd1019a6c82fc6e156ffdeb15fcd25fafe097ff7a05bff2d72b78db5faf50043f66e7b8aea2d4cda474784a94fd39b0d97601e282abd80fbcadf64968e12f7aca8660578d28e5856f92204326e602b880b4f8ae62483511beccd2a2ab8df5a54558b4b6a0a1211449dbb609ede40b46b9ae852faa865c535d59c8e50a6d87331562981afd10bde81caf246321512c3f0b7cdc36a3b7343986620d652a29c940bebc709193cbdc4e606551e399be693c1f006c4bcc1a3b4c54936de3e3a5cbac3441655513dfe34d3363458b0ee1a22cbec2bb28c7cb155c8617aec4f33cbb78499762b975a7245162f5f4ac4488a2ea2b358ae75ee28d7e82b778f76fdce2bd4e64ab5f6862e96a738fb621606d08583f4a018b7d8c572c66058b6f085b1bc2568b85ad7ed5ec5575a148b52173f9ff9eafcc2516607ea16d8830cf5b84f14083f3f5b7b251de1fb442c86459e39eddf39641309aa13ba45edad0d1510810b55aceb530e10394cb1440d5f8b9c522cd3d2c57f9d98502cdae9a71253164d7eb349b28722e65e193fa89460c958a7c61bb21f9901b3c044c97b6b0c81f74996ff34381d0f4fff6df50080e3e07f1039b30a5a21422f6fbe03a1b8e4ce2977bd1e991ae8a54eff64da87cd155534582aba68aa4569905eb92bc206e12ae11cd9025162a025e652c9b8a2c61d9a4efe17011b480da6ba8ec495165278dc5edd264299bf42a3ba10935b8d9d80b4ec848e729653f38a191a714b34627f445bac46bd68a664d56e4de4747311d539489fffb4b19d76449eb353519f7a9321e90154993b1bef075ade7d151e3d1d1cc02ad59c3fb4c0544f3822ce1bdaa8cff4956f08185af6b19055a13ef337181e0828cf7aaf89f645a767547ff0962eab33bf86feedc7f959227392ca36a5a2c89dac2d7745917c385a44e3e58f06a624913110ddf4bac1b9e18c7076fa188d62fe986947cccb830a92053ab3d3aca95d57a17be36a4018204cb3fc86afcef0f576863d1b1f8312432a101f94c45aa16e71764b74c488a0cc9e1d80705a4b84c280a0c45d554e28c804897094bdd699478d00e90eef838f82362ed9462afa629c55e6d85524c533724ca7523513a76ac83aa566ca7f2095760d4d10e4421e226e52824dc304b71166d8d49508ef80416e29db4e528b6ae2ddd683b485c8e69f90eb435088fded8815e66b6e71e8637683a8bd81614dd3679383b294ef6b8b55b648cbe76f233939d6376df8d116bd6badb386a3db06e5ad338f8da38157a05d3e150fed144f0c82ac224f3187debbe35673d681c6d1cb1a6b1ffd238157801ca81bca342c0284d26ec3746ade9c608663fb492ec61de8ab9983af2bf75d39ab51e344e63eba6f5a071167eac59eb4e0c9ced07acfbd66c63a471b6711cfb8fac3aeecb2c8716db2d5837ac79eb26663fb4d03d6bb67124f8ad8d6c0f2a529dcdd65adcb45964dd1f6ce5586b0ab6043c5bdbe836218772e845778a06f609ede845c7f09c6b668e4471b61b67ad07d67516fabaf13e6d35f66cddb7a61bc3cef3b4f5d07bbe6f4d7759771a67bb9df7b9c687d683c0f33dafcc75eb8683970e521766debadb38e23c3fb0e61b679d673a00eeb2c8db8cdd8e0e54368cfeed1d1d8a34982f69a4a61a24af991d7abf46062aa44333ab92ded1f9d2eb9bfb35b51f6d477fbd8c3ab7bce495b62e02b1616bbaf10165c09a6b9c45e111b23d85448fa9a91dba44b4def266a2e88392b653dfb1f5e5addb5e7ad523f3cb7dbb7f838ac420dbfd5e73b00e0e0ee64d45ee558b525ed54a1dbdd5a2d6d15b269aa1776c7dad43376b35a2d53b34335f366ad5ff5fe7abafbc14d8e599c25d9e29d8e5452541c79139c73a997668e32c66bd4c9bc5ba47671a74345b0ca09fad593ffd2c66fdeb3e4006f46ce36863040ab1ce6d1c699cb566003feb61ff153ad97d815eb6a6d9ab606343ffe906518aa4aa2a5298fdd361f64f7bec079967a9d61d97f9d32ef3a743cc47593f1d66fd7490f5d361d64f0759e78b64e18d6fa467e8e87c68cdb3b163cdd141693da0e4d0c17f60bce60ffe03b2e6dcd707f983ffd08e000078b86bcd5b775063c4badf38d518b1ee2186a171b671a4711a59338da3d65deb7ae3282d328d1a47acf9c628fd4c4415d5911192f75a37ef346cde69d77cda78c87bad99779a31efb55fde693cd1065ed0e1716ebc6ecea7f570d3ec88e56a477310dd6f06f9b5ae5bf38d11586b661dbaa7ad594cbb183e6337d9b0a44b9075175bd7a143869dd7c6080cdb9bec3339db38625db7661bc3d60d6c3da41d0a0bd77198698da3d68c3563cdc34745dc965eafb6842f2a7488f90291c4e7ab215296d07fb2fe96c359c7c1835d686797f5b175bd1bed6cdbb91de6ee7ce38475af71b4f1e1101dd38c76e3c3c6072ce90cc5be6927da79f06037da49b7d01dc99de6e965aceb8d115ae9075045a8186e8cd2c1f490ad0233d9b4332bc6f39ca2c83bab8c75cf7ad03865cdc26260dda62ba9f3316c8c5080691807b7ac692aa2b4b385a971a4316ccdf92bc9a97664dda4d31dc1c0b90b6370be31dc38d538e6147939040dd25ef4e3db18f1d62258c08082356bddf693e7a2ade647fcf73f035d8dd38db3dd432c01c2f707bf0a6eae93b41300fccf9cfbcc92bdaf86538a25784598a833c4961917045e1808ac3ac1f47b2edac037d27d679c863e3a2eaf4ea2c36be033e4e2862496eb7d95dc3c27c1291cf84eb90090c4bbde808e10da150f996cf4d099f1a760e6d17ebb61cd733f691bbdb2c6bdd2ecbc8df552e4ba8c60379d6d9cee8ef40d24857a23d0055e6657e3ac75c76f7796ee34367b89b470b4591950a8215952a0f55842a8bd6812af913e6e9c820adc622b8c35db8efca5c99ab766d93234ef7cbb2853d71b47e9b70c161cf8f6dda5ab5d60b16afc814a628d53d67dd4781ff05049e33e7716f01bf9e0c17c68983beddad538920f8c645e839e6e9ccd7707876fbedb1fa4a1e1e80fbdd040f30755f81e95f5725680ac1bf90ce705d68d7c7b9387067e91559c1c5817d992c79410edc812067d730b7c46bb073e96d322f0c02981f531485209c03c8f43451de49aa8c0c9a53a98a7524a1b0bb9009629ec5de849d684d319cae2788682ae56d6c7282cbb59b3d6ac1bb0aecba9b3c0a3cba3d699402dd5d111005e5e39bf73d69d66f94df29c038057d200923ce492f9a57f33f2fbfb78b2d8bf1b39032c62ebc48f94c561d39acfca55220b11acaba8693889e7daf9239f77fe168a7ef9d6f79c0b6cf74eadf7f916de9a6eccb50c354d9e6b2d3ce1763ea774079978cced48d0d3f1431238e7a67bdac608ec840222a1f060a5b973ef6c80cd9d81b3f394559e81bb672eab3c07f735eaab3c0a6792d7aacfc2a34126413e1eb5e686e0ec65d89a1e62e2dd10ec091c792c242dcbfafe4228ba8eacf49bf14039ce5ce9f8e7360ec24dffd509cec2ca0a02783e8b00856efd338414e4af382e22b7fd561d9b903557f3210483ed9b318a60aa0dece636ebce101d79438db3bc4bc6e2778cb5a37e4993d562dcf2cff9c00bb2911fb68a174e8a6515c559bb77efe66522de21e166eb0e6fbd76103581e686352f46342866f6b7d969c447024a0def10c2b2fa78923f06bf31cddc309179de2632fe093ada81bafc4ecb2d5e5b3abe74627166e964e8de8ea591a5938be38b33bcac638b9717679e84be99b9c5cb4bf31472e9fd28ecb791e28bd7964e2c1d8f27bdbf7879f1e2d247e18caf9f4c2dde587a104ebcb17472697ee9c1d231ca6014fecad283a513b10c5a470efc93938b379c64961abc3d1b4ecf228df5f593e3519237007324f1f29319da484b2722c98b338be38b77c289934bc7964e2ede88b6c8b108dc93d1a5e34f46439cfabcea45d189bb5e149cb8b307e1b16f2c3b70a0487f124ead04d9ec282a92f9dc5dd65a1a056cf174e6306051596f7176717cf1bba1c59b8b97978e75ac58a4cb310439588000724de5b714b98b552a41e0e1702ee037dbad188b979fbc9f7627c6e28d27c38b979fdc5b3a99762f0633765ebcfc84ae38c7d1d2e8d2c8e295a59388fe49d09702952757162f2fbdbf34ba349a7a49c693a9c5eb6cedf448b886d6224a2dbe2e63697ee9c4e2c5845d286d03eefef3c9f1a5e38b5388aec94fae2c1d7f7252e81527060113eba5d12757d0d2b1a5e3e1d51e053de3f8d965aff8932bf42bf2e48ad03b4e0450f4519ca55dbd34ba14db127a9e72629042b022a3007542e837e7822c5ee63acf019ac51b7410093de89c6c7ef7affe628bc5d31da576946b175e1edc8a2b27da81c6e2e99fec0dc57a7143fa5d0fd22f988df2452449e47aa63efac3a33f903e52926a0b1715c5c425531d1820ce8bd267561e9d71df7a4df5f129d579a9c992ae7b8524e2bfe8a62a1715f7ad47d53cdc8fce9000ba925a2d9554c32d5559b8d85373f3fa4c75a0eabc64735e838af401fbc036e5169804e68029e0c56102a833a2402ccb05c8aaa1901e89c803321e30555d5fb8a89508ae91c7a71e9f927ad85b89e8153240ca958a898ba6aa11dd2006ee9188d6478ac4c0d5858b0303442b1223f3e5c8aaa1003da00404003320057c19af48c603b8864bb8887bf0bef519b116e4cadd79d4d5934f0cad1083435d869ccf145621b9e80a05332ae2a8862221434e399396cb860137ee66f26ce383053ddb2a868868d0b34d1d281665c395b8f8f02d54fcbfa0a392441ecfc79de65d798b8e64d9104521a8a9a45874af44a633252670052f45e6008034a5560c02827ed988c504084522281b710c650f4351966bf1689f9ebcc5b263e58b5e79b66008452dc81e9063080a7e15d8222812b268769c7edd2bde47ca9518794fbeea2325d9d8b82bd9a9bc50c09136049ce72de074fcf73ebd2c2b06dafcdbce2d5bfe7b4740ec9185628f2c127bec5b5fdbb766ecdbc3f6edb3f6ad7bf6ed8fb17deba67dfbbc7deb16bc8732e6dc9793f6adefecdb9f60fbd631003ff9c3f019c8f8c2bef5c0be7d92c17e64dfbacb0a7e6ddffe14e8f82f0fd8cb31fbd605fbf69fecdb470358e9cb470c31247d04e84eba3c51f49fd8b7be70b3ff14cc98b16f5f00b63985a668c51ce4a1bc8c37e84263f90d146a11bf2d9aae7ca8c27edd429509719fe55edc5b1fb06e83726781c4ad1bf6ed4fdc774afc2bfbf6fb00f589dbd14ede2df61478f7bbf87db7af6e42e37f0c5c9e0c90a1495f00a57b011c34e33cc01e8de465be2cd7ad925f19a71a3ec7515e430cf94c64bc29f7d607b40825825977fbb81dc40eca358fe445e0425981ac49dcfb71b9c22615ee3a0a858eddbbf9c226087f4c1c14889901887624e0240e8abadc694887be6ba8e1f3ba1ae51f74fb1415dfbaec5b97bb9374803060cf53a824e8901e500017ba14f7d64998df5f08b1862fc7a5539b8dfb0b301cef3a42a8a0706b957e30fa9d792ad6fc51a85b9791bbbadde38aa474cad359cfa6ff3de4a0a66dfc3124dde56b05a3e55e8885856777e5d2959371fab10bff1d5b9ef8a2aba8008700bb3f97d6ee230e9be57036a73cbb2f97ae32402f8ea21886e0a028782c9f85252c86a21086e0a060b7e2d2897594d347f570362dbf42991605272f5fba8dda1c88f48001b7e0205291fa3f745c82b6a30e6f444271f85c0db913ea6434ed7cdebe3d4c1fe96f7ee5a72b90e95cfce920cba1a1a1487a9487b43ac58e6074f70c464f3f84d1d1cf516767d2298c8301ed0c32bd3d955394c5b0258cdb69e800fa70072559be087717f2c6eee279ef2e42c603b93ea2980b1735168e8b3ed48826f562d2af2d7c57c5b5858b7db86fe1ae42ff5423a1b8240dab1563e1067d502088aca43971b8242d83b8cda853ca70b316e9d738f428314a8652a0c8577177a4774da4023748aee252483a91df82afef5a5c0f99dbee5c7b7d481a44bad4ab2a451dc1d570d1a4f03b29a9c2a9dd160e0c415739af063b51ae7fe1a28674a9b2705729c27c77134ca5486a32ff5e45082bd2d1815e0f33197c7d3d9939baec253026b00f6efea64ca856f44e45946a881c2594133608e21b20f76812a9886ee8743a997d1bdcfef5debcc7a45ee5dde5b97097ddf5d8e6b6a39f6eba77702edc355453747768cded55e7abe5f6aaffea3f3fdb5e659cd703b56845a73a6dd6824e2dbb9dea5c10cefad47b719f9aead1b25a846b4e231d0ac9ac3fe151d89d100707ba93c9174e67ba2feed3b3ed4860b9ee72bff05dfc5ed515f4236ba9167463d19b9b45527727267b64bfab58688bd2e31350efe2e3136a8dbfae422422e832d0f4383de63c3b0fcfb6bf8a8acc985616be6b4557151f9f68454715fc45948a15de1aeabcb84fabe8ae9aa4cba4972d38f028ea330807c5564d265ab98ba6fbe63d3ee32513b89682351868c9a209b85ad08775af0feb1271974cf7d9795845076a6a05eaaea91551d741302ee83a4acceb39f7c57d7ab6fda6a995bac7784b7a4c532b2bee2ede35d17a45781451598d912abc0934de8a54941ecdc39db945a9aa56b069a89a5ac1baa14945821f5f34063443ade07e99d09f266fcb9570bf8a4d03eb06c584fb65aca7dd21e168919b299aae0c5e430ff87cba856cbe8978b9280ebd4295ef7694eb2a2a929e7a4bee61d26768643d5e933b80d8f03433dc442af272cd7e7dee40ea1da2a8a90b5507104ca22ccc2739d8faf854e44ec70c28931c65032cb279ddaa9b5e07d805af0955ce7e0fefc0a3339268583edf6b78e956adba70f7990e4e46f3418b87a85b93550fd4ec43aee98a641a785e455637fc9ed52dc0fd9a5414d82f89aebf5d8717000bf3923293aef84dbdff5798b7710770330649958d2383e77d64e06bd835b557d2f5df049695e7a826cfa8450b6cc9e8d64a912aa4cfbdb89c49ef7e42a2b29bbfff736a00a1c513b67c6c1fb623aee163845557576d2a45fe36cdf76e0f5014c7e610518cb4864bd1a74ecad9c8bf815e690d71292bf154620e928cbbdcd01659a4a5cf38c676a29ca4383a7bd0d6e6244575ef0613ead9d766400598e03380d66e380141d9a74d6ae4998d26e7eaa700eda489d4025ae9a45632e8cacd0e3a53f3479ca909865b998bb615c3cd25cf218dd66ea0999aec507d9643ccd4248feada0d2e534b21b29261c58de891e57b2929a848146784c9355454a484838b351863117e5c66787ca0b51b70fe198834a0260eb9d6d1695def7343bd64ecfd9aa44bbd7effc3ab680814b8845a3d047c8e04cca035fcc2518a2448fc197ee180a04f7b0dbf6f4069208dd44a86627de543514555c950fda148df124e75d67e207aec7039416b370aab92236501e1673702ab92235902036b35faaa92914c24fbb8e31e5d558547575591174d1fdc5be9de5ae95bc9c9555c237db8cf5464fab72af7613210b79253576a24c748c35d957055a57753655f9e12a57faa794a12aeaacc535a2dbea952918a52b50f0edde049aa6043d5a40ad6e1d0edd119c9d00ca982fb25fab7d933b7629e22ce5394798a310f08f3145b9e221355817b0267a858d72802dc2fa51fdeb5e0f2f51fc7315d7bebcee910f83a14091cd5f524056701c03ed3d0e400601cd4f19f782e0776dda88b0d69b51b75394caefe20ad1b75d199911167b6932a8a934eac8c48577482d3a22313ff6052c867b663353682d8c15a9f60b0053c709ec708ead7a4bec71715183fad1f4941ecad1e5121dc3f9291e5f22caf7a84b5d2f7ead119e9b0e8f00c251e9fc1bfed3c9d7afc342d2b682d3bd65a2d3368393bd672393368313bd662313368213bd6422133683d3bd67a5d0cca1f6a3f86c3be6773ffae5edd38ec7bde877db043fa17e10ee95f443ba4bd44211a3e50ae989a810b44d3f17e4dae567181f4e1ff21697a59d5f0af554d932bf857a65e36f081b2410c55c3ef49f4ef3b0b5715fabbbbdc47dfb36d8df6128552849beef76bb24b8bd2a14428098a1e9053cc19bceadf44bb65a98adf446f2f5c5516aee237518168067b58b8aa554c0d9edf54fa0c09bf89f66b520d1e0e940d5359b89af98e7e59c29402bba47fe1aa86df54faf07e4da23c67bca41fbf0d57f4537ef07e7ca0bc8afd4e3480e5fedd4385dd51d7cae63c2bf3bd65a2ed32dab6b05b04728535f19c7428322f863750e756b413e5f6ef06f54161b788e44f2b50697be638a5d95cef0fa8065216aea685de7c47d217ae6a4990e1d09b02c0a0cffdee3e49842fe86ccff049a842aa261172d04a294f59b89a7cb3436de12aea27dac255ae4f7d51d609d2a50afdf80a636a0af2c1095ee95bb8ca26439c4228c2533c0054d92baf72d8f3a23bf1328b5ed1a2cc21ec4576e2e6167cbe4dd2270eeac4c9ac7b4539e1a2bc804e03b2216dc473722a2f94a8fe6543a25a0f12956befa76ae10bfa0755ada86f47ff17eae8d82d1f3a24699262a092466a3562c8bda40afb633dba626c475daec14caeddb7a369f7ed79baa38b042dd2271589c296090adb271515c9f9c4c60b40090fd6816af7cc4ba2f0659f804e3cf46a89be71a001dc010408f61b67bc58a49045a25088225188f71b852c148063381b6cf70eeadabd03ac287cbd4ee14bccc1b21db127c97b22b96ec14754d534a9d7f895df49bf24e1c8bc9e499caa157fcdb1600b47cd809328b4d385eedad28db67b67363fdf81b6d211ec1ee1ec402f07403b29a8fbb2b55b1475d73336e53219b3db8bf14b07b04305ed080ce53c8c5eb8f73fa284910f81ed5ebe2a2925a39c70d826306c09b5855fdb66235a04ad0bd18b41cef99d18ebb9f41817e1c8fd9a70dfa4f1f64ddc8325237cae84fbcc6ae44c8938674ac43d5322ee9912c9b071121f2905c9adc97912e73889302f2e123c4f1ad00c02074a34d5cc7aa0143a4f320d95739e6466394f0a3974f9c749a2e0bccd1f27b5cce72be52c29fd2829eb49d28a0f9212fdbd88427464a6387ce9a6a11131d4f373ac313da53f7d325ba3f3371d5d7f36949954fd80924ea26c389fa786df7435fb42369b393aea331f9d91f82327fbb9115dd55de8ddb13b6482ff725dfd9afaf86255f2c685e435787b7211b5d48dbadc05b1429a2a4617cfec4524677c35c79ab32637c959bfd44409c91da53e67f102d1ef3ff2074fb08fbafc791e9318d650472076a272cf81928e81728a5451ab724545ae082f3a050a48316217ab26606bd961cb4de0f54e8232c07a47414cd08fa9193223f24e7fdc7d404ceb90199577e4c3b603b1b0d4de390f0fd78f572df18c0e7ab40db5c44f532d11bcb0d69aa6bbe950ca6c2c658eafab687c6ecd520cd60364ddb7e6ac078da38d235098653cb0660319d6ac4081112e1b2a107e9fe66b34026c3446ace9080bf3d60d279957beecb4875bca05f49fe37567ea0e461138842756c87be66b3ed805b8d66ce3b85335e7cd29ecbfc7a9325508bbf896b68853c47f9f8dbc4f6f2847dc7f1bca119760aa72e497754d6c7aab6deead6b5cfbdbed30e3a6e944b5a61bc3b8f1be356bcd34869d57eb3efd691cc1d634dc913e67dd63699fe3c6e77491613ff768fe75eb46e36863a47104c31af4902e04d67d6b86219ab7ee368e58f3ee2b9ddfd783f93761fa780999542d8cf3bcc374dee136ef309b4fe234ef30997738cb3b2ce51d4e5aa18ea1731bb09db7a6b1f5d09a0f26587731ac8df38d61f63202979cdfb4a631dc7f7cc4ba4e1b1ef2ac8790e0801db566ac7958ecb2296e18d5bcc341de219b7728e61d7279874ade21914d9943710362c00a28011f20034c1b9a9dd66a76dc0f556304358ea6e87768fbb3fbbc13609f9f9687f2d4e5cf097875f85cb5b2872173e65456cc99743e2e66671a66c5fd3c753f943da6fc1133da8cf687aea474960b46d5da6880e0fb33df3861ddb36643e3065ef99c704bcf5b3768f9f07a7cd79a5e09166f096fbafc6c607caeac06a1cfc40af977be2c2be5defd1405f8ffb16996acdbd674a26e096a3d9ba85e827174d79ab7ee5973f417453661ff29b54dee3eab150aa7e0f6ab155a277fb7d538baa17b6aa9ee89ee4336f44feb41ffa4ebc2fda02e30343ef80fbf28cbb51eb93830481409ef518a55758028c479ca5525a55236ab262e901ea2d3e44a7950a2ff1b32dea394aba487e05f97d5aa53bcd44b93ebaa22e33db5fe32a912bccf812da9f43ff9e03f643246fe459996a1048136254ce9515a784fa99712a1142876bca794e69d08df0d595715e3908affb1a6abb51eb36a5654bc4fd2e51eb92ac383a113e390098f8a043fe52a514cfc8fb552afdc2355d3a878ccef9375fc8fb51ebc4fefa168f03e5dc6fbf4324594cd1a799f8cff51c7fb7af03e03efd3f1be32fec7b492ab77c02c6fafd5d02ec1decab9858a93df7a1b5d012342235d073e798b956ca5fb0ea999e52a414a89a459eafedad4899e0819b1d4e503062d75f7186a5515618cdbea56a5aadc5f96aa323b1ee5176ba9c16e2929a4e1a0a41852055a447433ab54930f9b870789425055adf51245121aeed61c40aee5ae49736387479ecd2e2313bf7415dcdfe5b2aac5ed79cb5e51c2cb2fb2a255a294e27945bf2c1700ac7265a5cecd734d760d01409dd557a9934a3ccfb5da956b3203e0f76fd41141aa98baa4c843524da67f154327b51e522343528fa99b15b3835376955730bd91720553cee14970bf5208113fe0828788562a0b9ad793d178add2f4954f39a719932e73e2b4f0dbaaa9c55ab9ddcb16362ed375f3a35fb07cb445cc898bc9eb679068dcde486a228a5bdccc117cd02969d8d0cf77a0ce4eb493bd6c673f2fa2cead99c9f89d8686865024d3e9152e17a1c6dc9216653eda9e9c368d568d578d156e2a843b8a9f948dbdbeb19958179b8901e166622039ae8becdadfcab846343d12d805e2ba38979fc92d8deb12befc2c68809b7cf39960bfa02fdc528aa4846b0b97e0d79075faa32af063a81afc1ed224fa535db8a515499a8cee714b7103628a95a2a4f8282e40946d8fa02fdca228b0216355c1868a0f69b4f48a6f4a5895931e95c337170a9b4597e636b701e8aa54f3dde9ae7a2863996ab5ea5148f002ac3a701ee616b80082745f24a594739b3d35552ba94ac23e01a04a0b97b4e4539d5cd7fe854bde5db9e2e0f9b9ae3d0caa4b4fda3cb460efa0d612b60e87166e69e8051de912c7548d054c5ab854d28863c6276949fe7e5c801a8b6fe6fae908360e4ca08d152e3b850db9568bed58bcad03cd25b1b245a72c5d15441b872229c50b165c8e172e29247e25aee7ea07d9719e616b2019065ab814cf73f70d346f8542489b344436adf0825bfa5de9f1e354bf803ab770ce1e54d3803b6351dbbffe6b5b00740bea409d8e0374275cec23e510e734acad2700429240b6a683bce411a27f23825cd4f683712e308df9d10b66031b82d9ba10cc068582d96042380990c7de7205b302e92dcb781795cc645c9064bc978a667bcd2a91f1ae924a45b3038e7b147e17bca3f03bcc390aef9674fa9b3da6c45b520fa547a9b9a428254a8712a1f829728a388358b6d7ac917eca357d308861c283a2484e82a2e25dd532a9c9ba8cf7f499354220a3a6ea7256e96c6f7f15ef358881f7025a83281425ded357c37b6b6a1a938e78b6772bdefb12defb32defb0ade55c57bfaf0deceb58fa1b7f2200b2951f4d6779085aaa4229da4aa6e2b925e4e0474f5ac5d83724546721fa9abae21854e8891a6c7ed234aaa0ad7415d95eb6abf6c9034f4ad54e3bea0a31e428aa41e93655c79cc502b9250895b960764d4cf7ca37952982382712ee1af3167848a5c21a8a6f6c575bb4180787110b474425055e6956682588d5088786190b574b96272293351ac4600205e1884addaa0745846355e71268dd5640a102f5d67a509ad35af3413c76a3261b57ed662c3333a201edc101bd685d850aff5a8d502e90ffb26e43a73db51ce9eba1c1c9cb9ad2c713c94f8124b9c0825becc12af84125f6189a12826b96d2cf15a28f15596f85d28f1359638194a7c9d254e8512b7b0c46f9dfefc7dbb238bc7ab496bb89dd6b63d94384e13b746122768e24b91c42b34f1e548e2559af84a24f11a4ddc1649fc8e26be1a499ca489af4512a768e2eb91c46f69e216b79a214b708388e4410804c19507edc90bf6e4843d396b4f4edb930fb13d79c59e7c48ff4e9d81243f63d29e9ca72f34e30b7bea0cb627cf0600afb3a4497b6a1453ac5347286248632fd7eda913d89e3c6e4f9eb327e7a0d8572cff0b7beab88be92b789e84e72b8c1cb6278fd1424ef628f0e1e78d0393d1125f4135be8864649355371a0545646d7bf2cf40600a10cc40e9197b6ac4e5e01ca4df04c4b43e63f07edecdfb8a0bc46a380b79b30e7a1edc152034c65a2e9e3d0bef5380e0a688a159a07503f26e401e1fee0be8787e76d65d43acb146e22d7223d8c9d12688d6395e492f355c2bbf02d9b6268c53873b871d87b843d32142f39e8f3eb9a50625ed4d6e48da5bb023b12747dd914b8742dace04a6ee3c74ea892c6625ed293b118a8fae0e33891c84f625ce94a505cfd89363c81d9ad36cdd601b151edd166f51a0e5e80a2adaa400cc24cc94090e98b3727d0cabdc0882b9f1d09ebc8edce9c45afa2b67bec33c12aa959b28538bd21d07e849f8fb156b44a1023a061d5a32b81ba220a9497bf21b7bf22172bb7d9a4fce5359672e51e4546a9ecf94a7d5f65b2ba10a054e15e66145e2b1e169bd0370892d548fa29f654fc29ef054e3f055fec6fdc08ef814f8033b555f0ea4c7eca99115eacc63fe851e42513cce7e4dea674cf8c8e99e40298990b3dcbc26f55749afd4d6d1654f5db6a7c6eda9097bea8a3d75d59eba664f7d674f4dda5353f6d4b7dd1da5f600ee1a317acb49261e9e4cde05a031637f913369bfaa1b871c57b09556e5e0c16293dc7a1ba526b9ede8409a7448d250d930fab7777418243f2857e47ea92893bcaa953af48e4e49eb0c889f11eb2cf7433fc946e8107c834fc0009cb1a74e0cc1d33c131e8760927de3ca73e7d88a39644f7ee8aef957dc393832e44e1a5a309389976be1956ee085de105cbfe39a44a148ad520cb4d01b685b1abe50abe47e062d1f494da3d1c9b7f40910f19b3af73346c04f49c5fe721a764edfb9643859a9f45e4ba3c719152e3d4e561abdada95d3e196bbdc9e4d65bcd08e24fc7f5685d17ad49aa5ddc1b68eb2aace2a253256e1a171ae7adb2f9e30fef4c36805b32d736055976abbb24fdea16d0af1e3057a65fdd96a65fddd60afdaa4136f4abeb41bf6a4842359c2454c34d5fb0a7c7ede9597b7ada9e7e88ede9abf6f4437bfa9a3d730692fc8c497b7a9ebed08c2f58d2597bfa8a0bf8d09ebe6ecf9c01c099514c11cf1ca1b821ed823d33020027b03d7ddc9efecc9e9e83925fd93323185e8ebbc8be82e72394092087ede963f6f43937ef543083b11e82bd08bccc45906454c04173e4a3cd90cf50fd7cd69ae743d5cd476b97776a950f55256b6c88f8b16d489b4619f81690ce3ad5993ec2d83905350ca54e42fb7d664fdf88645c832a5d8ea47e06a9d3f03794710b92ce054654308f5636c44f666d975b19bf0221a67d4643cc4519f299c8a8ba9a3eee1074a839741c220e7afab32abdd52ef0291228ae58e633d25c093811abae9c02abd25dd1d9334a27c04cbae28a76eb28cc26216c538a2b67448ec3f8184fd75ad1d136f6ec9453742d3995a499f2a7da437b7a8cce28ae7e8a829df4aa694f3ff44adeb6a7bf81e978dd9e19112ba69c55ec9c8b8307cd5452d31fdbd3e790dbb093f0f73687315f1915051530530ea1ff0ce6fe57629d930bc147560c219b8625e5020fce53330580f8280b91ead3f6ba2e562db9107c64f510b239a8ca2ced61daf873cee229542af10bb8edda8c6a0905754bd3b3429f107b7a36c7d90e79ca0687fe98375a87ece90f60499fb2a78f0c41ef5f86cc2900bce38e549a3707495350270fc3119e6e615d6dbf6275ceb2037b79353bb04093b66e7f25ee9a56efb278c4f97d9f4e39fb96ac357aa964250c672ca46aa652b446a1ce4e47f66a0a327127a7e2de9ac6a8a00f9b7678ccd08a3fd15db7b4b1eb5e1fbb6e43bced3612cca1255933f15bd280a4c1538168ba8977f568721517886ce2bde6c20cfd5bad9a7857c9d40d131f900ca9d6a399f85dd330e92fb388d64cbc5b3a0c0fcdd8440fc06575bb7a344a2f62136d50128e4df4e10c761abbd59aac942887253a6bf07b92a613fc6b936806c1bf961583e003924eff921e524cbb7bc1bf564fad5194808e620354808922ca78af9eeaa0c0bf36f1af655a1a1f10198fff988c0a9ea99133dde9bc5b96152497938c9c29d8ae1e9208e6f87f31ab63015cc0e7ec6d55937549ae8850065cca1c4366a94614822aaa6156ba85145ae8602697938253bca0a3aa6cf6c42f8a63a6b78a6998a88754cdb8f759104260d2ece4ca9c7be66a89a5614fa46a44e7952dfbb90273e6aaaaa90aaf6831902db0663e645609b76c21902db0653664855fb61ec8165a32a7bb96e9c690521cd28a434679bdb89819e5741f33dd487732538ae95e665a11dccc8cf27f6a3f3343323664abf5205be910225bd2c396d45bb6a3dce6c651eb7e700de8e4256e85c40fc3892ff1125fe6157f8597b88d97f82a2ff1355ee2eb5ce6f955daca4d7d895b532e8697b670ebca857d859bba8d9bfa2a37f5356eeaebfcba6df1939d691836292f0985ea9248a66e9cb51e58d7fd90e2d721ccf5bd5840f15927cdba83adb9c687d603f6c30b28fea071a471d69af18289bb2f0fac79f7f126c4e19ca62fd9846fc6a6c3a2c39cc35a125b0e430e230e0b0ef90c027ae3ac75b77102e238cf58b3d8bad9381a7885409781d7516bbe311c047f481fbfbf1d48fafe36edbcc6496b1afba959e5fac6d9c6096b8672417f1a23ec6794253e841f869fe27e60cd6493f42956c00918011f60c3dfdf6698447836a4fea4c318eb73eb7e63f86f53d66dd418b1e6d94d1769a732d657d6b475c39afffe464aa1e0d18bf58935979952f04ca78b82757d7fc39a6ebc0f51ebe710cc50b8b424030369b86e348e5ab7ade9c6099a9082afa5918267ace9c649eba63597bcc18098ca27b83b0c98f8a330416f32ce1f58738db3dcdd048545b4c9beffd29afbfe4b6b5a7840930454f650b90d253c911101147d14301c844730fcec825f99fb74080a4f5cf8d9f57005ee090f559c6c7e1f47cf3b60959c196221acbfbf31c4581fa2cb269b28a2c38b757276c1f85febf30ab7795a7656e18c90350f00e7f7e35a1c44ace13984d3afe9c705c95114bd8e4b47946c5feb74583a9ae4288a81fe68fa5041d0242b542a6c6ea392cc1015c3793a858c2a0592aa5208281de08c6d0bda097fb723c5ac565336f46dee5eab8b2575a3a1216fffd545c2af3dc2db979ea3af78674bb6fea58d9dff7ad8f91b65e1feaf2cb4659cbb68cf8dd873dfd873d7edb9f7edb98b18dee720e32f90fa677b6ec69e3b6fcf7d6edf398d216316debd12778621750292beb6e7ce63283506497f09a2be68cfddb4e73e0502e783e08c87117beec320f815001fb5e7ae46f8630c7d1dc4700e905e0a02321ec6edb91380672408feb98be4b25722a3bde3dcc5bc3df77e9e3292b7e7fe9c779ac44984b6c8db735fd3f43fbb90b4de6ee2889b78258807b2ceb9297f76533e8794d5de72c5f8fe0e6afa19b4c539da10d09d27dc86f88c7601247d0749a3d02ad7edb96f5853ced9739f7b8d7a1540aed8735fd8739fd873b318da79cee9488a8536c41556debe733ab385e25a70d9147374c9ac4b7a3b32ca9a24a1de32d148af21693a2a3ad740f64ac2ed34639f76dc09fae73bd6970e3ff4779c75fcdac7146afec2add66fbba1992fb34929bc7e8b35db65d6bf7433097d3c6bdf3981927165db42d04ebf7302fae53ce07090c342303a0463e492339262d941d143d6f717827287acf49b86c8a10d321ddb9b440a2277c0d658d308b6339e214862dbacc0b0247355915836cc68edea8e18f86fd6bef3416884a41ac0d209f90d5d132877a3cd2109693ea0cee7ed3b1fd07199563a6433eb7c356fbb5dc03e444d54286c52eb3648b7c396dbf677462806cadfe5548cadd4c3409d66edb99144350c974fbef1ed1dfa8d86c61a7187d565f84a9c77bf18b362c3db5450d0d274a24410cfd43601a8ece23949bb833179e708f4f4a8d8ca360b74d1c5ec74b4d8c65604517030d051f0091d7930f3c5b6b5c97075979f2f39cde01bd1b2ec2cfb88f2c63e625dec23aafbc53b89eae67ee166e24d45d254bc5fead1e86f8168baea1967d555fcb6a9c0df6a5d65d12ac168aa2ed57a3409bf5b314cfafb8edae3a4ec9675f6944d2c7f539128e9807d569d52a4f47cfb2c8859d9435167ba7a48299554bccf54249da235e88f5c97b48a599574fcb63928f5483afe054d52c040aa87149bb86d48a1a881df824c791da4a8b2db68ed93f13e1317082ec8f86d13ff424e28bac687358542c7ee04a11184b8dded4952631024cb690d830f1758a138419bf23db890a7ae2a25443432d89d60a9f50bb34274a40863833b665514a54e906eeaa6a21691e2848c14db6cd102155226fdaa12231f30d7025655caa8422a44238472c2c3dc425b2d9da0aaaaf620a5947ca2421caeaa723fe107a3842b79900e068faaf0632dc887afafac530c2002c7014281c163d965bfbcaac519f43ec6bccca25f960e10e1a7979759f0cbf69883f188e9def7969b5bf74b1b448d67bbdf59c85ca1b6b515414e7eaa764dd5fd1b62c9ba104bd830d3df514d45473b50ae9f94ca7890fc307c1ef796e16750eac355f5001ea0397d64001f507bcbb8b7ac6aa5327edb34821f47af9f3d2ebccb43df8285af8d99eb85063d484774b1dc1137e673d29d627959294abf7bf7505bae8ff4e53641ef6deedc8476860be4f5aadc2bb56d69479b5fda845e44b9aa74206471c841a735816e90fc8f6474bbf71c68029d22d542e8a0ce2fa21ceadff32fc1ddbd3b77e49ae4a4fe5edcdcfb896e3c9fc67edbfc61f87c4b9b5b525ad9dc3d11745e736b92b1e2e67616f37634281b65d5340ec00155bb1382a91dc93a1bffb1be60e5e8f4f3cecc76c16c743f0f018edc7be805519fe04af49caee738b6b5a18f0a50a335ae9afd51f5114352ab654762889094cbd99168920049b1981d091da75c2485423348343e927a3d3b123a227f16ff0ec6c60fafc3a323a46c2a454d2aa21da8408c72fe505555b5b690a1f6964d60aabd25b837312425a1042b108457e9f74970ac3ba86a947c2e582550873a9cfd9c73591c94797147e8fbd2e514e8a66d34408c6a99d3482e725a8124c46d6df0041ff01c988c23b018cfd1491ea26a480a50ac91b713e8d106680d3d5591baf9749cc1c230edf031d18f2e4546d3a36b0dd31d24a80e848a0343d2e8079c8e68c4bee8c114e7eb1e0292fa42eff4ab1f7c0709209840a581e03b4806612220250493de360d1ce3ac46dee62672f8f6b25805b2de88e63641a0ea6e95ddaa7a5574abe655295015b70a21d6392c37cb6ad6c02955b5afb6c7e8237d783739407ffad501fa532aef31aa65fa54554bf0db63fe8b93a1d08531a302658df03bda951663dfb80824c1476e3779bb8ff4a578c8c110ad4a07d2f42efbf625f8c5011210fb52bce238685aa75089ec34f80a95907cccd3a5f49b07402ce26951bcc23c150a340208433cfd89a868d92f4a45209ef24454b4e817a53384a73b11152d048bc62f5d2b2414adfb45a990c3d39b784557a8373978302f8ce491cffda4b4205125c88682a3450a0e94e8b7d5b91de50e1eccc94aaf1cf5b2e224bfc64f06d7231eb8207d2b4b8e62e1a66eddc24d7e859ffc124b5db8aff42ec47cc9b819cce9899bb5cd25f16826ea2d76f060ce547acd98bf1827fd2541fa3627fdd14c8c4038c7993361572c4d28056b2221f8dd5e52c18fff6cf610034e9bf03bb24e145c20f547333a7e9b1c9635a2e0f7a45acd3c8c773dfacad40d55c76fd6ab0bf7abf8cd8a5cc3bf26faa3991adea591eaa3994a3679f3dd5e0244e11cea1d5967e766e43025045428058a9e62a7a8331c9ced27878986e1af21e9323e40f9c10ba3447bfc15a9f510bc5fd21e7f25d57a24fc4bb346e00f406615fdf693c378bfa153c4809622a458f02f8d8cf7bceda708f001428be3fd940ffc4b6343765b81214e8f595ab8af20d14d6841a39b3ad11ecd24837ae62c25a92af54a9566ee712b2edc17dec51bc0bb7099eeb29fe9fd6dbaaa6831effbc0c1d9c22da5377e3d1bcdec91b50a59b88c74a2c8f10be0fc13336e76cdc180d81d6dc2e3327e76d92d4d1b497858c6cb2cba25e9c8101e95f1320b6e4952179e92c5b3ea6ea9faa399aaf0800c32f95d29f42a6847fd9226abc598aec555700ab291af15e4a9e258d6ee842c35218f5b0e259cc7b9ff8ad22162560d4169f9905b6b908eb6506985ca967abfd42b932aa37e48d5d0614953f928624ca017835f4a0e4b28ee45e5fecbe6c0e1fe8b448fd88236239200dedb8cdf87a86a6d625f8fd06b6fc8f503ad2cbed68fe1d64043db382a7dde47a51d1d68d72143d2bc8ea30f9a84f4b26a568ba8474204e955a29711518a00446aaaa918b4af29b88e7459e995d06ea9578271be755b3bea7cfdd5d791aca0dfa835021340d24855cf7b14df2bcb3a1d3ebda6a6498a51ad234355c15e5eee35ab066aab917a8f84a401494172ad5fd575b9a72a6d42868a48b1980f08ce87ab42c9f97035f9a264fc9634a09152b54c65d985cb78d780b6306542a0ae5f2ddc87485d32c1bf32f5deb2c1c2820d100def937543ed5f183374fc8eca92feffb4ea03445b4160b0012d448f5203cbb37d32a0a7a83308d00716ee564951c6fb16ee2ad2c26599e2340ecbb8b07051eb353519ffcff2c25d0af04ff2c284226914e4c0c245c3d4328bd09404e0077e2962400a1801573639fac0c25d8a05ccd0162ee2ff59c6ff04acac5294ce2788d2f95a2dbf52513acf44dfae22a95689de9d2854f360119fb59078dd5595bb515269feda1ff55b281e3c985387e85fd22107e0647d7f0165f643c8019a1cac5200983754f01af825d1a5369147a2d0f94077bd0ff474f7031dfd3cc5ffd5c180767a6cd2763f7830f76ed3ae071154c443b5aba55e07eaefca325af84bda46a728d516fe9200177420405d7cb8e0ce4696644d4437b4bbd117ee6b48aabadb1b9a27998282addce3a87abf26c909d6817d847f3d75bfa6f64abafe9b001dde1e271dac960d2a1b58391b5436b06236a86c60856c50d9c0ead9a00460fc11b3a133f7974c4ea389ac6f2a523dc1f4865da716d60cd37f393db71d75e5066449d1898e74a9d7548a7aae9d6975c389ddedd1b250d8dfa7058be73c4b81504e0c470de81f3c9853506de13bd308907612e2456a11b200c7a3ea64c430947da20bf3aa4682f57552e265ca11aa00c7a3ea64c430147daa8765334c1412e2258a119a148c4792a5c7ca17028d2be9a1a69578e08568c34abaa4f0da15d263e5eb3e39a205a9118d035c8f10231aaf6634b53b3057e2466bee98a77b2f18e55d15a9deddb5a51b6d476da149c2830826747abbecdf47b7a587ab1bfbd2e7bd2f65bbbb9a78775713edee7e98fde087d9b3f4bf9bd33fcc7efdc3ec27f8879b333fcc9e73dfcfe11f663f8497733fcc7e81293ccdff040a7ee2657e0dfffd11b31f40197a3fe33e7c837f98fd149ebefc61f602869f3ffe307b01b09c05dc0cf1cd073fcc7e45f3801d0c28fff8c3ecc538e06dc838194ccdb6bbfccf55f9e02618f09c87bfac0ae7b15b93b3c1f7f34e13f94994b34f22ef17e3453ee4a5debc4329c06bd6adf47a67d4d9aaaf57365777bcb6cee208b6d630caedb2db3fcc1e433fdcbc996222e5823ff8e1e674127828f2b7002e60340568bf70a6f5ec0511e6584c71015c0b1dd368cbd0f1c8da67f63c72c7dad984ad68128cffbdf91006ef03e1895b12508d61f9d05dbbfff8c3cdbbc2c3b714b832c3c5e6edfb3fdc8c470e2c7b882eb8d3ce8506bcdcd3390f52783ca70630c570143c1c5fabb0b87f223cae0326d8d7e703f82cc590d583abd30d67ad109de201161f8ea26bfe2c651bbbab8418a6b6a20d64e7d6d4c05a5b5b729e72b8b621b8ae13c1751f319404e1757395188a4882951585d435dca3fddb18a96bff36866b44fbb731fddfc6b0dca3c91aae917a7d10d70715f85bad0f1ec6ffeb9bc1c7170dfcf8e2a041941e59c315e3dfc6062906ac0c0eb2a4e2601ffdcd26483e171e82f21cd1498de898d415fa5797e1a7a2c1df419654737e97e7ced4499a258f57b3562376e4a556a1fd69054a6ead8043f462a58c84bef41e54858881423207172a20cb105d278ac147161360b8502d145f8a84d65e4775a224c82bfc5cb6aed4e48a5042e1657af79b2ccf9d49f49ee7e497592880fff5a5e0ea13f041d729801c37fa61132aee56ef491bb45fb85206a9ab837cc36fa864bd2e6b7c9f79a297e27efc9e1c21d35c91c3fc4f4476a09fac64f98128259394362488b59720ccd22f85e28359dadccb951db6a3dcd2c9c5cb4bc79f9e5abcbc388397469e7ef4f4d4e2cce2e5a5f7f1d2319ab678052f7ebb7879697e71e6e9474eead249bcf8edd2074b279f8e2e1df71fdf07c8a7a716ef3e1d5dbc410bde78fad1d2f1c52b4fcf2d8e2f7db0388317bf7d7a7ce9682061e9f8d209ca819b3ff5f4a3a5a3eeabfbbd8ba88671605209e4919f54bd5cb1012af5f4dcd2d1c59b4fcf2d1d5f1c7f7a8e223e117cbdf1f4dcd2c940c293e350573f61693e02b178ede989a563f4c14b5b217f7ecb3b8c013bc00290055240265d3e5a0d9ab03cc4118756a8edd98e725428d95c286cdebd3b2ec2b8d94b27973e587a7fe983c266185f27978e2f7df0e4bbdd9b978e3e3d419f39c24fd6a28ba7c5f29323542c9e46cda1e27fa0a2c6224b279f7eb438b3f4c1d231b474f4e9474f8e3f3d3744bbe5c9fcd3738b33434f8ed361b87865e983a5e36871fce9e8e20c9d424e7a389b9607ee8e0f2d1d7d7aeec9f17517623f5e361c559ed3183934349456cc6faf2cd08226cd85cbb52a20bfa08728a3d1ca439fad2c9c7e9a914d5331ff93076ef3514d21c0400ded6014ff3b58ebbee894fa1967b8d5d01b68db96e42b7579232521863e45f97a0acac0284ac1d4d9f952322ad1104bc3bb3513de5434afa5d45434269b8e1aeb0cd9e6ecb49276958be34f4f3c99a20b295abcb17879f1dba7e716afa4ec3119d0d373194a387bc42ea8f3fbb4ab978e2e7de0da5c25970f6c4517af3c3dbe74dce5346543da059f89f717a768132f1dc94aaec9cdaa60afca9c54025dccd9a93298c0288d72424586e3b4a3e92c4320a21d5d3a41c5b4f80e966dd192606adb518e496b68e918e5e9e92807a8c6108921ca3e1abf21e3db5b971f114431c00d7cc0e3fb5c87136e6e21c0054803f1edaec30137b71ea00e62457cd3eb5067b9e171e0bfa5dff4e98927438ed832b499ae754bf374e664bba7e3b979d464749b412fa29c2f0b721c4118ba4131a5df66a7e3371e8f52b2bb4e92b38f60edecd7a47ed6a57eaf08223439d8596e5e93faaba4576aeb583cdd516a47b9f69cc872b85fd58d438e60bf5222ed4063f1b490c820ac8911641d1de857bfe8780fbdfaf296d73677befefacbff7bf8e4dfcf4dfffdcce47f1c3bfa1f1f9ffef7bb637f3ff3f5dfff72ff3fee9ffdebed7f7f78f1ef23532cedafb7fffed9a5bf5ff8ea3f3e3efdf7cf6efdbf9fddfc7f2e8eff9fb1bb7fbf71ee7f0f9ffaf7b90ff71c7817bdb66d4be7f6ced75f7bedff7cf7c1dfcf9d882986566592b81dbd9aa612d28dd56b84ccd22f53d4411bc7496baf0cf2ad43aba646aa1061a99d4e63aed5a78e7640aca570e4c2f81a004e6f6c7b45abe8a66c81b606791db03976755e819fef405b83f0e88d1de8659ad0e6637883a60f0d0570d2525b3679383b5d4b3cbd6b6bd0062f54dba098f15bd928ef67b5179bc3366104abe7b6a3a8a9600eaefebcdb38caee33c4a1d7b9d02bf80a04131a4713c1b916ad71fac7acebd69c75cf9ab31e50fac1d7b9d02ba31f48a0f413c0b9b6ad31fad60d6b9ef20ed4032f738117a0ecbf368e0a01b9b6ad39b849f541e334b66e5a0f1a9f3a3fd6f51838d8a6e6acfb8d4f1b238db38de3b488fff269e885531cac4d738de1c6a7d65ddc18b6e6adbbb451e0010a0456bf48e4b78a54674b402dbe2776a64f4ad771ba47109ccddb407944cbd98906fb2bd62f49049382f282116e0ebde82e36017bd976f4623c6ee3eff993d7d5fcfd92e8d26f9ccf74addd9991b189ea1dfac6a7aaa2d66405d601180f0fac59eb66e353eb5ee32cb61ec2359b4e02ed596c5da79ddb3862cdb3ae6657ee0e53183aa346add9c611eb3a4dc2d6c31f86cf37ce368ec04d9dc71b6731bb5bcf9a6f1cb1a6059a486089f4f69a3a8fa50f9b6489ceda24963e0cb0d4389ac4524952640e439f4619ba4b677690a1bbce42e7b4d15c8821eb06058f30f569b09de6824c85a7547852315d93a1999270783b63a02bd8e5dd4e84d3ce76f4eaa67cafaaf412a32d11724b3beadcc419a02e23ff25ae6b4c64208c293c6c15d554e800473b505b47dbc1835d5dd6c7d675eb9bc6d1ee8307bb37a19d74c3ddb1296f48bad1e60efd9de2d18422827b5b5bc7c1835d3bdb766eb7eeb3594dc754e3b3213ae31b237450580fe18aeacf36ed443b0f1eecce44323c62a244a3b38e233d782de5364077572d5f24f5b64ddd826fb9e3d7f2b66a6afa5b4e2295f1437de160f725a304f19f2e53d63c5da740a0ca83fb60db2626cf74c2ea38e387b0cc81a6e367f1353f1489d2ac088fdb2a023b9de86ac55a1c3e3d238d4f1ba3d603ba4edd6b7c48a71b5d9eb135e34cb6db2cef2e9d8e7472d105e808dca57e9dbd8c02e07507853547bb1a562948672fce3c9d6d8cb0d75bd63c4c6db70c1d24d63cdc2b7e133eea8de1c651f8e69e4d5a4e74832845525515295015e7bbcd2a3367dd0956c5c9732bc35ebdea38af6e855c44502527cfad9493e757cb49702be6970d56cdaf18e40b1625b1a513aba15337a75e5e6dbc7a78357078f7b8c6eefaed70e9f1e7f1956eecc4f96026593051b1922eee0f30106c8c3486716394527cc86ed5cf7899fb8af1ac9f1047a8319ccf60a7d418ceb7371beb28502659b79c60b2c45dfa725dd6c5c669b624301118c566a1a76a1661f88c0e4a3638e3a53db5b1a8f4c78d51900038657d95b5a8f037ae32994b97954d58c751407b07cb377c3cb860c8d5926d1168b520f3a5a4cc579232b7093291ffb91135c285e037d96f907c2fa956a15ad1182e21c29d495c6d4dca7cb9252cd3a19795e9c891eaefd7cec0cdba6d4d275f1903abfefdc651ae791b7c01ee82ec7b9acab628691b0e766f7c2d03c7082e1b6066c8726cc3c63391cb84aa88021b6baebd5c26346020f7ffb1f7bedf711cc7a1e8bfd2646262975ccc0220fd430bc1bce02f19097f3d0294a30720cbde9dc66e0bb333abe959002b9138a41d3b4ee2dc3cdfe4dc24d7c94974efcd9394171f4b91f38e443df97dc03df7133f40df28fb93ceb1744ffe8b77baaabba77ba667b1fc2159f6a31283b333d5d5d5ddd5d555d5d5d5b6c1ed0da19b0a155eed0fc6b7379cce8fc4cf39cd26b912908b418b64fd443092ed2684a68cecf0341bd1281a93513c122c249d5146281909969201eff533b24be38c6409e18361c4a45647b23e1b4042aa3e17cd3e93866747f00c93548964c048caa8482c35bf183601daf61f7ff49f6f834af0a164addba84fdd062540c9d4c7be05b4f987350fbafaef3651a3c7b29feb05a093afb1d7ed9fe2e2f8c91789e6fd3705aaaf4fa609f5d947de45b67bf8e9dd427ff8fe6d39adbfa8bd2defed0f476f7bf9f7b69ee64ed5e1fbd57b618fb0b126fbf20bd9eafa4dcfa436da7eb653f3ebdea9d9a1a9f60d2c91f57cd0661efecbc7dffff8070fdff9a5b3a8ce7c7cefe13bbed710cffa0b67d77f4645b6fed0ddac97b0ff67a1f8c37ff9b8103280affe0882110ab06ffce2a70fdf75e31366e48b8fbff7f0cd87ef1461df7af8cf1fffa0f40162633df03f7df8ae7a8d6fb57748769372f73a9df406607fa388fde7bffc61f1d5f73efefe2f7e5ae889876f3efce92f7e5e6cf6f71ebefff01d89d9f3e197f79c97bfbcf7f1bd87fffccb7b16b59673a8323ff3a82a3f333e547a1d4a9f2d6f80fc6782f95ff1196dfac2c7dfaec3440f7f38f571a2a2eaf6f0df1ebef9f027b71ffeece11b1f7fafa8a03d427e3444602548fb75dec78e8d9aa0bd7828afa077ba7c660fffebc37f210fdffcf8071f7f6762841c00ffe2ad8fffe8486037b5d924683bc1d92f7efaf0ed873f93d395800cfdd789f53829cff2a226246e42d1a79cd8f9e19b0fdf7ff8d309f6edc7df79f86639200bacdb5f7cffe3ef3ffc2979f8ee2f7ff88bb73efefe2f7e507992ab1a048e6c3d7c437e26528c7efc7ee5a92effe7be85e0173ffdc5cf258c2b48897dc0cb80fc27ef092f85e8e14f7d1170ba319e8f579c663c7ca34c8139f0e5ff3cb66b7ff7e11bbe18389247f19582e0ccc8fd164548fd46e64ed3eaefb344c25f0af577f46aa59ef46ad561f78ffee2f0c3c37f3d7cfba3bbed8ffee8f0df0eff159c031fb40fff1ff9eea3efb40fdf3efc7f61a709df1dbedf3e7cefa3ff78f821fef3411b7699defde8bbb0e7a2368dbef3d15f1cbef3d1dd36447c981f1f1efe5c3f82abf0f06df963baf3f048a6225111a7489b4496224811a24850d54f7108fef0a787f73ffa01384bde397cbb7df8571f7dd7fef9fae1bfd93fdf38fcf94777ed17ff20e9b25ffce78fbe2b896d1fbea9df4d7b6a1e295114a89a558daa1e855de19e7207eaa787f7012760047c800d7001a6dffa53f2166003359227bf64e3f0471f7d574e89c30fc947f70e7f7ef8f647df91da0d593ffcd9e1db55b7d563c99fc83977f8f6e1bb876f1f51c455dd949ffdbd692ab455b9c3ff027eb8b7a72d6714b9c3fff6d1772495871f6a45ee5148789a8a9d64e2c3f70e3f245f11e4f0bd8ffef8f03d5965959677f8a3c3f73eba4b0e3f54ed96857e7ef8813f700e25e41f7df4dd8fee7e744f36a952e99b04043adde13b58efcf0edf0672ef974934cadf24a0be854c7774a502580510da14c1b0552a80fecf576c043f3f2c29aa4601f47d1cdb85df3f7ceff0834af54f7dfea2d5a623bd864f476d7af599daf4e5509b26650b1abd3a3159d04b34ded19719447813d8f2306511dcccb5321ec5f24fd45edee98d44d65e6571463b69fbda36fc733519cb7f2eb06dda993231d04bf6fd05c3b45c8dac43e297c825e629d49c97e8b6e8d3b843db1746ea6195a987f3fd24558fd7e9583dfdde6840dbabf03cad02f312dd06ec8019b04a7c1213209a4e5f794952d85e65b27cfbbaa443167ea6a33c868e726ed41bc5442478a316590fe944c5e4629ad11e9d08ea2a24dba3984f466fab21bfcfba7d7a34b8d13eae6d6ccc643d6a6e063bbab6a7a971bc445fe1b1d41c78b7cfc3caabc2cef194c4d0b0af0892446139d10ecc3e91c47c5c42925f16e6fd6c5d16f60a7f65d26561becff96561c9a4cbc23c1fcd6561dba3eabbc23cdfcc556149f55561e54ff955617cc24d61bceaa2b0dff86dc5578fce09f44c49f86294841d5ea520ecf0ca8bf2fb07afc73d32df560f0bfae1b47e38a31fbeaa1fbea61fbeae1fbea11f9ed30ff373e6c9e09e5f984e7f58ebcfcdb7d7fa730bf2cf69f9e78cfcf355f9e76bf2cfd7e59f6fc83fcfb5d7faf373f28f2c714405d3de33dfed7ff2c11b24ee7f72ff27593beb7ff2c15ba44fb97aea50f590fdcfb7d553fc3fbe3b508fe2e0f59106fce4fe7f1b4fab7a9cbfda5e5b68af9d6eaf9d69af7db5bdf6b5f6dad7a7d3371ea3e4a47e28ee8a097abbdb7f82eb829a7fd8edff6e933f4978d2a35d1174d4969875af8fc04b7d56cb37fa3cc2e540dd3e2039ffad294384be1c2adfbae4d9c9b75595001f213afac85291a6d54b6a14190abc244645808a4a145c4ed9534a32f9ad839f0d484cc7243ab8df3d220dc8d5dec13f8ec980f289c04e96c86cf4c9fd3762927df2c18fab4b59793f809c57467422acaf86f4930ffeb2ba86a718b6fb1581ad99b0af99a5fff3ed4f3ef871d7ab7fee1cfc23273d7ef05f4bea97d141f12bf1e9a0834f3ef8db8c0cfb07f74bbaa25142bd5ffb79e91effe483bfaf5443bd5fc3bc742c99a05217f57ebd9297c6e5b35227f57f1e5bb5ff8fef96e686514de1a37f748f8c66f45fbb540c62ac5a1a4ad177bf4dfb8d3bfc994efc65d089f7ae0b360a932ac5786f7608df2bef01dd3f78fde09d83fb07afefa7071fb62fed1fbcd5490feeef1fbc2e7feec3f599fbfdf6c1bde17e7af09308dec80fbf7770ffe09d83b7f6dbbf77703fda3ff8b07d70efe0fe7eefe0bec8f6dbab076f0df7b383b7069dfd83b7d2f6c15fee77b38377d58f1fed1fbcbb73f0d660bf237fee5f3878ab7bf0d6fe40fe9af2f65020b9bd7fe9e0ad0e52d8de3fb8374c5ddae09f487e39b8df6bef4b92dafb077fd9cddafb073f3a7877076b7e2aeaf4eabeac303c785df6c3958377f7e1c7c187fbedb583fb076fed0bf5ebdb076f85fbb2d744b80f94aeedf70feea7623f44ba2fa5073f515f56f70f5ecf0eeea7f869ea1b4af7b1e5570ede95ff40eded7d596d7b7fad7f701fab909d31f565a5fb07f7a149b229804a12ddbe94ee4fb8b2741a35fc49b4c45f43d85de3e925f106dfd9dafec1bbc830e4e0f5caabfd6de8c1c1bbfb697af0eefeeea412856b32fd80b6d3efe0eff70fde12999c9a93e9715c7f97f70f5e179976fc5594789adebe839fec1fbc33f95cd4c1ebfbbd8377bddad5c1eb647febe0ad5db22fa4b481095a4e0f6e9c7dfb0074f0ce7e1968a0d10d0e7e72f0cefec1fdece0ad4a956bb02f810eee4b5158c2d4474cb2597d49d1fd52c66ea37cf5f70fde9572c2ab7f4962504854695f28524aa5afe44d916dcdfa95fad740d6ff4eb6df2fe706d7380e3e3c78ebe0f552138c1276f0e13e0088c7d5c46a59ffb6c86ec7e1ed34f41d2d99462d93cb65e7c8ebf19351361c656489d4f6f76bcefdf84d323fa74ed8d7a5659cf5bdc9036a1d0b466493601600260e27c19c0698349c416f56d10a2f9e1841f27f4b954ea5ec3cd33cbf0c9ae7b852e91c57aa9bab9fdc7fffc1bd14feb62f3eb89bb2077723f6e06efb93fbefc1dbbb317d70b7bdf2e06eafc310a4c33bbc7dedc1ddedd183bbe1a8bddcfbe4fefb8344bee98d1edc8bdbd776d92e6b7ff2c10f1fdcdda50feea6b2fc39f6e05e347a700f5f0f01f18329a3dc1489405d0474c5480f12a34941423419928a9c06ac7faaca6d3d72f9c15d0ec8efb5975f96ad5f7970570035bd512cb1bdfcc9077ffee05eaa1a86bf3a9f7cf0e792ca8c4b9a1edcedd007f70650289b7a5f58555cac152a49e16fa758c574ea23226e2fbf0c4825264087d800d513ed1bf75b830159aef022f6d189e8f9fef4f5c70a422a154805ff241ae4b5077763fee02e89f951da23b061442740ba5ae3271ffc10c6ff2ec99207f7e28d8d19c9639b64dd8fc0d62697e5fcada8c856207d1545c0ce95d53c4d6d32e60fee4d5626b73ff9e0cf5f966cee5327394e9097470fee114ac7f4c13d1272e6d32767d4e7af845e45d246b45dbecc6550022ae3011d71973eb8b74d33ee43d27721ca18404d94cd85fef7a1080b20651ca0292662f4e0aeaffc15eb73b9ec58210fa534f7151fbb105f091f4987242dd234a46f6c88c9aebdca567e9e9ad317a0388d9fe94c5f0a9de9d57ef59d36aff62beeb4917cf9abf7ee7ef6773f68ffeafe0fe19ff7fe44fef3e98f7f8c2fff0a7e7def27f8edbbf8ebff825fefff3dfcfaf37bea1f85483e01aee994a279596641fe392dff9c917fbe2aff7c4dfef9bafcf30df9e739f9677e0efe4299f985ea3a6cdde7b3bff987cffeee1f3efbeb7f6ae3d3afdebbab9feeffd0bcfb13f5f4e98f7f6cbefe957ef7bd9f4cabef7cfaa337654d9ffee84d598dfce7fe0ff1d79fc87f247678f957f0eb48bc4ad99128253e890c30fdf8c76dc05189e073de2a95aa86d4727c77bbe8ef9fbeffb32b9ffddd0f2e7cf6d7ff54a1e714a096fbffeb3bef0f069ffea07424edb2bf805cebab0b4539a1cd12995134059991176af286a987c4473a4afbe91ffff0b3bf7df3f6677ffdd6afdefbd3dbbf7aef4f3ffdf31fdcfed57b3fc17ffe4cfef3d9dffe975fbdf7a75fba9b60dcab4fb01d9e3b51b065fe5b5d48e96617ec80236f5099f6ea16ec411f55d0a74ff9a6966653d628876e6632d6a7738dcb639c86fe3cee715123ff8457b7283679d26b5b14ff3ce92d2d6a149ff49616c57e8f9c4e4771e7a35dca32d9c8fbd5077ffae97f7f6b73b27df7d9dffcc76a20e3b2ffd57b7fb629e5dc6403eeb3bf79d38fcb71ffffeabd3fadc0358d9576b4aff7b3bffea7db9ffddd0f6e7ffaa337a7f4f5fe26dc9121d7aeca8c40de34467e347f57e24df27453177dfaa39260209f47c6a1e9836b3efdfef7aa8df54fffa474f12aa8949ffef13ffeaf374aa7eecd368fe71bd8dbf3e4d31f7cffdfffd33f546eebf83ff755d9b7ffe2b3bffebf2bb772fc9f4355f6bf97f692cc268ee7db152cf5abf7fe59b244d5e68dfff358d5f87e2929a0d9b291dffce3e6b7857fbdb789fc866c6048fbef9925fee5b0c4bf5599eefad5fe6cbf2ae3f5334bfc695ae2ff7ef71d59d3bfdf7d475623ffb9ff43fcf527f21f891d5efe15fc7a66891f6de24eb0c227442affffcf02f7d9615f5213fcf3b6b67f320dbaa9cddf2fd4aa7f666b3fb3b5ad72cf6cedc7b6b5fffdee3b5fa0aded8b77d2c6f6846f17fc5fc96398dbd3e3996c6f5753fbede9ebf8f7bba5bb8f496e714f85e6a99bdcdf7be3314ceef77ffef826f7fff137134deef267cbe4fedbeafc2bfecf4f64727f7af7cf2699dcfecf8f6e72571b91df7a96ebf84b6244aeed4e3022b3dd6746e43323d2fcf7cc887c66443e33229f199125ae7866444e44f39b67441e1191abacc823a2718d197944d0adb2238f3ab3a50dc9c78cad7d6649fa313db3249f5992bfc196e4da6ec192946bd7652eb2f3b4db676489e4065ab36dde1bb55764b4bb7d3e62342d80e61f5cd80b2c625911aff5c5857e81653ed01758e6c27d8b0a1fdcb7a870e156fdf856253ee887e6c9931b313949cea78c664c108ae548177a030d619225446449cac8361bcfeed068c4c890f25404b22814ff0fc394efd08ce18f6e128b2c1d49d3537da5291d90d796d3948eef9075166729676213769f0b3865655039206f6ec44686ae4ac26aaaac129178b14c46c912816b25db6df9abdd264b2466bbf9b89a6230d70154f057e5b04878785edc88e172e066932c872119b0ac9f8440ce2da8f956b011c343304c932c91b67ad0558c900ffe6209687d26c481ded48038f065c8a007a3a547dc03d08761d743ed0110398655c0b011a3eb22300e0eec47e54551a37f9da55b493a1084c2cff55bab74c05e9483f2bfb334b9b559eb67d9b0d56cb2ee80cef23863690c3e161a0549dac3d70b5f5b687e3d986bfe8e60dd59b9c0c2a0becad2a40e48bbc96048532e92987458b6cb580c37fb01147473c832960e780c9a50d66763b8f54fb2ee8e5445328bdb444633dec5e7019332fcda1669ab6f3cee327226980be61437d28cf592744c2ed3b8e7f0e3c93b583df0213e49ee034291ff6cd024ebb31440f1a9a2004a1a415eeb2449c4687c87dc506f6e65e988dd52add30d77dbd8401deed6168d04bba530b23d3a1846cc345f32bd9a994be4353243675a641e6fb8561f81bed237f8de0ed82b352cdd5058ea58b2d9244bdf84b40515c012ab030b54bac03374a6216b3d0227805d03c4f2b97e14daabf46a835ca557bd686d21c15ea941c76a72514ce8142e3062d27cc21eba7d9b203438f6f0e9c409f5f19806ab6bc9509a49ec957c09e950c15e60d91aed15046efec188662eaee9e1b320f5db5c32935bf8e677b26415aef7b8455226a45a93b22d96b2b8cb4400ed971450318ebb58ffccbae28f65f94edf076bd293cade2a0096607a2c2e80bcc06296d22c494bb0c334d91b17a0afcb779b33ee22d367dd6d2127c02de8ec5b840bd28da8107c8bb39050b9fedcd2e86f29f67ca4793f17cc3ff6bc97d43dc224b6da408da63fd5046e073cbfa4b73d69aa58704ddae936fdf3c49e005609a04fcd00695c1ed31ca6be183343dfc32ff1c10209fa938a0e1b0946922d0f2bd29d8487827021a41cdbe5591fe4da2df462df22c910d945e1e23159a55b34e5e439b2dbe7dd3ed19d6cfced5b490a3ef09050a9290842e350cd464ba500b503e45c062c974f30d5ae456bca03c892e1f8dbb7f51bc5dff90b337df2579aaf2b0540ded9663d25175826f97f2b6592b7524e3b1123b7d0017f8b6ca5c9805c4d4216bc6c4d5d09fc024048450677017aeab7bb1fa1de9aa7404b92a525254ff36ffee53faf2ba7f9a66021f47e67c4a36c96c74afdf1ca19d997d7a5c641968cd8c8551023bb006796488995443b0c78236472ade4110b8948466917384bb36ea18a35c5686429af31d0dce78a9524de61b271b724e02db8013813ba86aeecec0a4555c903dd8a3b501370bd994fb0be03fea268c01b9772c9201b58acd39e9959b20a5f61cfc59a9650e7b125128fa2c84cc92c1de726a69e9f56afe0f5dd804999af774897820f414ef93bd558b0be536466a6bae41d6b06cdcc54b2bf6e51be0aae32af1da55f9b1510e6f76a3228029af706126c81b2b9a35f5b8ba56638c9628960a4c3b30115db02181ba57cae835acc76feda95ebcb372eb6af2fdf585b59bedcbe7479f905b244e61501faf3cdabd76e5cb878e3e2050db0e030e1321143d6e534e2afb290ecb054c831978253caa71571f195118d2e3036bc05f428010752538c86b247e57b4035a469c6694442c6860ec993b9585957801978189faa345a055ed46a27174287c91dddb7504e3f6f45b42702b2ca98d3666cef409a8f21cb288f445031f9ba23912503feaaa2c79982fa53a93f3c7898acf6926f26e72646ae720b3948a88cbb08519cde5106f15a4aa5ee92a5548e2d0bc92de8a95bb046dd82bed30a8b78444b402f76475902ae9e3ba2110ca1a84179a5f036f47034acee6ce45dd2c0e658e63317d715bf2d99a13ce19d14c6f742d3f4328b7b599f2c21f141043f0d4092f50d0090a500943b464abd1cc7b1250bfec40972ac969384dab8faf6cdbce22974976521460346bae36ec4bb056b8b46468780ee60a1b69aa50d8e1d8ad25192aa414e9cb060d034289261b0a976e7144157c721db234b6476be910b65d0e797dc7471425ac74ba4561e0f570ad5c959f07318b1db22263a41f535522c74ab6c33cefaa678c7345cf5e14a2f96f3364ee259a47d984aad2ee33857a41e1731523b750abf3e6f0d90ee18b04cd2f44534bdb0867500dfb45de6595f4300290ac2b8efe430e4fc6cf9c7257a25a94250c814e7e4a8cf5a13a1a6eb69189a1a382a66faa85ec259926369d958f2b2393e85c59d8b88452fb3565334c5d2c834236635cb06727603ba499cf17894efaadd2971523e15e47f9d94d16d97826693dc60dd512af80e8bc6bafbb418aa8991e8b261c6a5de0aceb828523230e2039e897a903744326a81ec63660dd75ca58596d5fb49d65f911de6dd343ea61777406f039f385176e7d772eec259873f6edfce859e77c0bc721207aceed980d1139cb138188e44bf66a89ab4777dc745553146ee28e5eeeb7c5ff058cdc65ad5629790c76e7e8ec6a67e5afeba63244beef9b4256af193258f541f634d13bc2e66e973dd2f2b6239ed8d06b0a6977d30d6d79223e632df667e678cfc52d431a73594501bd0a612e29b602881ff41ab105049b21bdb12d720ee53716d37be8e5fc65266e63505ee4753cb394d306ac23e7a5555e31571311e0d580a96ab8bdc0772b48b27e2db52d0d0582a4d6a0c7e93bc3b3eba1b806a5a6f8f613d137057ab93d734c31be48be44ead3ed91f94635a9f6f90850639bd59e91442f5ce9e148589300d35e46c6972e51bdb8e8fc95ca5904f1dfdfdc48902d3a2fdaa5cb533f2076333b9803fe663347f192927fc9e0eabe9b9a04893a4b825265f59db66a3ce25d9872e90796d0903bfa747d57fcbf5ee5ccc8de662c0a9e3dfd1afa51eac9e833809d9da78c8acef47d0805d5120e10ac6b02e39f494425c0bf4a8b7921cd5bf3635f8aa488cb46986c9701449e33a190c92f8f75609dbcb580c36f12d77a02c2af1c345c75575c51090ff0aec685dab358f22ecce8db6b66093c4adf42c3048a0be16d5e9a685ba24f8d17dd94f04cb9da1820e1889e51f2a94817d2b4a422afab7f40e634e520cf1052bc290a61eceaa87808b4aba26485f4a3a58fcd1f6cf4eff5afce848ead45e74ec8f9ab481d4e3c211f2d32a7193c7d937409128962a0b5133268541ba7d3b9718555208410bde562a8aac23a76f3212e4d65570b2dc429f378d338b45ae2cff417b75f9d2c5f6cad5b58b2f5cbc4196c87373735f9f7feeb985af9ef9fa99b9e79e9b2fe91521ceca512c782f6621e171c67a7affd2c29db21521bb842c91e61fd6ceb6e66eafcfcf3eb7b9b1119eacff6e731a3edba11157befb59b9e6a3517484dbea68262af89ed6d197b054ec0b0c27180d872c259d641487e0d9d154e5a43c06575a288ef0cb700146815ea522db18862d0b2939cd220050a0fa46da5da21fd01f4cce9687bc451c678a5a758f1d8bb4070517b21a56b54466b0e3ecdc46f8edd8129911e341278940d4ebf1c79b9dd416916b73a9ddd26f92d97959027f7d85cccb6ae6f237cfeb764fd838816e2aeaef725d0961467a15f8fcb359aee5879b314d7d05e0bd8194ebd6cd8c470540fddaaceb7a7786f4592459c9b778c842056a0dfa1327cc73c02d9847df09b5b6c21e49769f7e82d8872791dd16bd530bf0bc7f0a2279b214b78aad1fa5ff9686c919b9b3390bd58a1feba45562cc2a21ef4028a6ceb7078bc6a57e6f59a2c661ea00e2db62b09657fc1ab11b906535a292a99258f090a5cc15cc5b84673302b0c549666d60833fbb8f3bf18044b96e6f41869019b086f40ad283a031a9f4d098a8cd0bb0ce216a6a0e7de311134243585f71910b8ad2edd61716e5f3049c6efa716a3607c60083c86fb579cc3c5d204cba60c3049d241c07dd3e8fc294c5d3969ea19deec4601c1bb81dc449329c26c6202fe3310075480dae60274e18e6aed90c0546e1b152b8c28425c3546acfb0e92269aaa78d18f10c8c26a982e1a137e4529e8dedcda606e1010bc8ada5a5a55b4facd13c12c36df96854de072fa1472828ab80e03c949058ab8770c98e8a2a468f4c18a8620d6eb061f54ee98066dd3e13da47803b876a4b5d6de0e8ae004c4f6fc8f45efe361beba0549de9487b22e418f658560a0b1469f7c5f26843538aa39d6f51da310372dd933d62447069cc54bf94066e9b8d1ba67e7700739f3b86f8693f2edf22351d3b580839f0eca51957b4fa8225d7b7d9781398c3b43d57126be69db3b701b176b25779ace3fe146568794188a29f9f2a5a9f0b812e15d9755a5c3bdbfab55963b3e4f759514f84770539019bda5430c2a51c97b217825d8145db418f65b7c0c04f4699bd756f8e1c587bc9d50ca73797d558ac39c1d6af8c583af6ecd6dfd66c3a94ad9565e06122a31ae63be9729d0acb0991dc12cba9a02a13fc292b529c32c4aed6dd5b93bfed50d2e26e677ee78c31726411774b58ed24aa3eb0d70eb5b318b9db8a26fe55b1248c2390825b87a74e6dd637178bb12c35c466d02e2d19bc67354ad7b7e26749d53bf63ae4b15ad44b4bc72bf31fbcb39c8f727cd7120f37db9f2c8e36315216ac7e5b5cfea8c8845956b284501c4a8cf8501a216883497c54c4947f89e3b19463993f8c4205866efa785dca5b4194e4b37856c5a8d87c2bd92e67f5bc01250e36fca9e3816d4128c5a01a9e8a60c8dc34bfe3f8b6259b15309e25ebf06693b49c11ace981d05554f293a61519aa74fe5e6d1d2157ead5b1a68a37c8c6f1769b09748d6e1c6f68674334622da5edc14118ed4ed6726a89d00863042507b7bba0cc9fef531e4bf12aed19509858e1a4cb28e3916856432bae3b02e70259226d3849900c6f20f20b48576d4229446d86b80241d279d9dace483a2f431849e7e520ef269ceea4455e33593ee1c59d4572c7a98246514db18694f135685604d119669f4447bfa09b8866492ac714994bc2d61ba4bd0d337f6e119f9e071cf8e3d4292b5642975f6fe31a9b57826f3443023d168d9229643f899a41e690bbe0a597a63d97d20545ea424eeb82227641fdb4c8258000085b28d3bab099ab107928084bd304dca823c57b6ebb83ad24bd48bb7d2b2f85f9588833404cc5b8c97c06dbbbe976b488d9c73688033a1c46e39a11fbd831f9bebeac4d95f255a79b64b6addd4dfcd2193480b707522f4e738d8933464fdc7acd1e702554cabbe4f8b43ea34acd6c2efa448b6cdb304dba4c8880c53bc1d56b172eb62f5e7d110f990fd3241c29470536b9548f2519ba2f8b66ca68379be522c88b06031e072f63a4a67d46796a5421db61513254c95e66548b7dadd122ce9ae818596589bfcb3cde3e8f794e41b4b93b29306160af2a14f9a63d1582f762a9c3e67c99d1b4c7205f8a99699c2c91f945c22110ca9d6c8b84c3ccc198333469ec19c33717733c4a4f463059488e52317e20f06da8629186c420573482442a855d21845f8be40efc9f099397708be44ede09ca456d7cd5abe02906bed838aebb61e3b8b583881001cf30ee5f81a28779e338396b759e2ba255f9a4f3b224ab5509a744f9d10449616f9d180018058e5fc13851f49a1e25676d725b2e5979c7005fdaec0a2fec650f5e4c5ae100c02a30d4b3d9462b5fce4a1ac48c0f7412fea12d1d6ca26e24a38ca517924189fed9143ecd86c960e68b5f66dba84b7d1bcdaaeb26e6455602dc2cf4dc414e254be4b53b8bf6cce340829e2cb244003afeb5ad1aaf936f2e91b97a1e3c87315553cd282080d7edc26a52f14d343f60ee966792db3ef0ed9fa75104d2bcc661674fced4f3399b6ae28f99cf443f245b0e204ced7e9aec82f3408ef445b9a8d4368e9fa7b1d4e021688fe28e026e26e413a40e73df256f9808c13b11b32a41a5bb2658b4d5007c863cf9caa5e086de23d164647d2e489f8a7826231dc662c2639e711a71c142322bcd6696d6ea0e04c473848a3cd599d08c132770bf2ad9c2df38e19161368ec3719dd257abb5e42c7e68114977696078dc6729cf444d8c3ae7657735903a78d64d5615e41f407e14a54ee1b352142a066a5502cb553a65021c608391c808e31023d06168ff26a973b44c8eecc671728a94e8814ed32db0249a59c150afa859243a04e7451ae435fbb0550ba61d98127907311392d342675183eca6e89753f75ee7a9d8cc3bc974759c7976072bfa04c3083349c2b52d72d6ffbe629072da82761b5a0227c0731035ea68a95f4942d864bbb8c360b3db728d3a9f6a6c0713a239bbacf83618b08c4a6bfef66d822f689439bfbb591a392f449f6f49903c6009330fb8da489596922f89edf3c96098c43969390b3b851ac4825c2c980c0e64cd09d66e676c306c903626886ba7ea18b9fc5c946208e2e0cab5dda3cda592f931b5a164591e554692a5f7abb1934d214ba4060dc40729a59626493fd509a623614d50f642feb641d625e0a6d439ba34ab81f950afab4ed4ff067d1a87113b1ff1eeb633a2369fe5a3d0e7e277e53a0e144279f8e524c0d0bb411a040b984d2207368975cd36a87a6ba5f953c1e70a45e080b9a1e85e10d51a9ff505be670fa2e94a1ec369a4f488eb29fcc45319cda669ddd0bc57801a0596ee8cb22c896191985325399e714879af9f91ae44227499631512212f85f018ef35405050df0d8a42243952a188d48a543e67bce3bf30810190bd87110573c22e14a8d7257008467620b3a404d4e7224b20a8c28154af1d6ec92d64a8af143aafca687a6a59e246ccfbd356e952106a5f2ab251caf4d240b925e75af56cb6645add36c01d0966e983298b4357fae29ba2c0ec731824f9efa2edec68ebf9eb1d3dab8f7106a91716483b4aba54c50f2820fdc686821d921c047edadf71235db690ed65399cf3ba519ed839a447a0585c8730657e434ec3af0e8fb13db4a0d437f8697d565b7a169df2b70540bb19df61b0b25fa5038b86c207bb4d65e0ae070c11ac66e3a884155e3a543a40a2f0b9c7b215b10c257320aede587046c457594058b441d667147fcc34c88ce602f90cc32d1f9cf1942ff4b0c967353cf2314be45fe8752c060e94069929741fa0b07f581d8105d5836ed6cc66dde1ff7ecab6c89299cba8837e2b655b5aa1961cb2b48424c4bd197296bc062efd980ea4d698803700677f8e155a257b0ccd6cbd2204e7f57a94c4d1b866074a14d500a71852751137fa6a05333980272ba7ada4ae458af4e72981c959e7574bfb51a40cabbbd985cf922c09746ba19d862d606c5ac49d18384e2d52980ebaa196db44bf92add97204b2ec3f5ba6a46ccb2751e47f46a84818f8e12c536ad74b33f8b163359be3cfdafc5f4381642a960a3bbc7217beaaf18992d80c0fb4ac613c74b5d7ee34889a1fce0262d8b645d6f3798e1d1314a77fde8eb325d1d202436c337839e1716d86ccd4832ce5835adde92c98082d1b8d43208a065bb680c952101804a64b0bfefa14b7965a686c35d25a07eb75afe79928cf95e95e67ad93a68862f9a0602c94d644e3a0828e5673ba653ba4cc90893e1db29a1a10b982fbc124bf065c28b752d8d0d31404d5a314c905cb54a5a057ea45349a3bfd28f2433fc8ba474239c2f848e87c12fb0019727f91e29c312adadcc0719fd09f9d2489002a4b2a688cd9b52df9aeb6ee1d6910dc8d09cddb2c75b4126e13c9d1b26e229035c927d026210bb3fa487835a18f18346b421f09ab6543f560a157c09d76c6d8411de135673cd1f362f568fe42775ffea6d4036a319fc16acb7bc3b01b55580ca59983bfeab582d57fbc71bc1c0816672c15ac9b396108d752de83f4a87494f59354b4c895d136137d723da582860db23c1c32381ccd63f2424a877dde15e40536202b2ba49324db804525a4dbdddd0d92218b7167030c7316749341135f347bb2fc0e7fd53ccc9e79ee1bf9db701c53f8d1ecc239a5e65ec46326020c3aa5714868980c333c47f132dda1a29bf2616682d63a63b21c8729e3e4f7a9e877fb340f9b58eb7361adc8c96038ca9820bb7d061ebe6c3721b22e22580f5c17789e306510418107b3e59ac3e31e843df07838cac830e17126486d6fbe319eaf93d95952db5b688c17ea865e0fece9c6f8b4823dd3189fa9e7e382e1162b183e042dcfbf35e06532ca242e7db24c90bd0681bc7c5052b00c338560c65bd93e1d8b242b973f0c3e1dd7e6c4865c55473af6e6c925b862d0ee121bafb7d4f8b14aed2d7c6ea5fc254f9355d64de2f0111bf778c5f6ce7c8ec5ece89c3cb00758a2c003f6b06b6648411c8d7568fa16891340e8c06e25a3380cca51ab1a06cec1efcd37c878be41f6161a64bc00b7606e950607004f37c8f87483ec9d6990315e7829cacddcc014061b2a6e8dce37085d6890ce7c8374161aa43bdf205d59cb49723e615b5bbccb75da980853c9e86c42a0becc3748bad020e9e90649cf40a99955de8b677404ab060c599c0c1a24d9da122c6b90783400e015d9d2010b39cd58b188095d30baee5ecb0aaf1bb7c89c52fd740a0f4932481e68956c916ccd6e9fa538e18d8c51d2621e84c802603949b8201bc7e93cd923e414219d79328687ee3c214b84cc6d1cc74c10481e9d274b64bc4066c9781e14cf8e7cb1374f66c91e66a0efc28b057252cedc59f9e924192f94494d4f0315e9191b7d7a9a2cc93a4eca09754a223f29e7c829d2c5dad233e6fb19f3fd8cfeae6b8023f682f76218bebc2222a56027c9fa8a59f1033e9f211167248955a7c0914ec143661860be6104a811e7244c60bbc691b5d8960d157f969e866d22f043a667f2e79afc821b96d25eaca567e4af33f552881ac4d09066334e4a62567bb66c065850ecbca0076c410ed8193960a771c0e48bbdd37268cee080c18b33d8d3b3f293ec53cf8021dba40ba67da91c6a2a877a6f5e8e861af453a48bac00f15ff87dc17c5fd0df2b464bd7521aad796bb416e468a9a14a6277b43c73df3f74aa7cc500aae19bb7866fc119be7967f816f057e5f091c2f859598c4e4a73cda2cc80b5b446e191b42ea78198d153a323a727747b67dea43752104b40720589cbdd6c4423481613c9cea26960b3190a31b2a46a7b9ecc91b364167f34c9026911f3bce8c0cf0573f978af4186c038193417e0e261086326a95c11a488e2b1c8180d41c54847b1b4d6e29ee4852c1757340c5928971a31ea6429ed2ad50dc2ec61cf324bd20609d99021ced13089e5573db7792fd62a8c81b7073e1ec9be04e1d2957d098cab251048e7604f2acf120e7b413ecdea06b7e0e729f5b34e9ad85ed505889c224a3950588d8d7cfcd8c83db95554ecb23e60045b1c6e1c56d0bc09d19e2e880ec2f2449dedb24e2f5a91fa27823a9aff9524e6101c092af72c24d46721192423a195561e230a04918abf9cd97192f12d0ea73f3a5203ef3037f738ea322ff21d1a80c110bcc8d96e0088b4017187383f8bfa4591ee9a036d050d3bef836231337f9a4d72218967a4462232c874cdbbac2131ec32484246a394d1704c6896d16e5f732917a6e12d67224eaed6decbc03c0a23c1ced361364a59783509990ab8549a027cbe28e5c6791a451d0a9b82eb9bf6d7cb8ceeb0caaf1792ddb8f2e3cd61e5a72b891f29eca2f93e849de87cd5b761ca765659c4bad96a4653ed0f8583df37b4cda9223e31e587db873d96e9e71b49829b70e0b549b3cb30663559cc3ecf40873c57bdf23e6c59cfa52e6c59cfc51e6ce58f6effb5f443b1ef5af9a3dd732dfca7d0672df364a3515cd1727e19cf5bc4a8446fc3795eda5ec56693ac5dbb708dac9010f83d65785293ecf6c7c8d05c9098b19085c0d19319598abf21772556fec2da852bd1946fc95531bf3774da0686e3bf93d12421f3a2d13d5deb2a4675ce5b59e149c8c4cec57e967fbec8eeb8fb69707a8f6461f79449ea3e057aba4f8b18c3b64f4850498a3c315137874f83a45ce63d3141521c3c0d926c19fdc44481fc7a1a5439ebca13930532f76990e52c864f42d630655d2e30641fe4c9cd950638481ce2f083c914b102f78f1402808689d059255682612278618bae4fa3ad1c405d60a23f2b2a878908f6c82cc23e4fe0e0db1e795ebd3f85efedfc1ef2c3382f309605c6aac05815a888ae5251f6e52ee9b14c8acfe5ec7cc4599c5d4f446d9888a2a5515a9c3d651a4ef7d6bdb5892c195e4f9321edc1664e8d391dcf82c277abd34bdf6a797e6c374285055d1a7759746ed4e9d8270c889502d1210a77ec2e70413b910925325597495e74bac6496debe0e5f14eb29dcf4b01c746d4e9153b4285378a95a81a20468f63bc1d27cf1317537e74819c5a22f3565f15b0c10936bbe43adf9ce6504df56094d9caded8f40f7c4173b33b00279385ddf19bd99e33fbceaf888aec92d4275df5193fdc1c8614ee759a775ec3fa0d57842d915331db251768c660bb584321335cd12b99155d547383a7d4e896d6bc065937943508dbb463a370662f49168599f3078bc5c99d7f7b69d16eb287bc9b439b3887b68241986c6dd56680d041b2c3661ac546da2456161d0ddd823787752f8523e8f9735ad1afa4b163414052b71ecbce296702ca15f9b166556224e82e8fc36437a0214e56642b96d666522625ed4ca348844652786d85f6359bcad0953d4438246581330518e12b58bac30449e208ce6f67a95cb4b000938b5333922b27c60f0a9580171a55a6d11a07ddb22a0edb22b5929e5b08e02b1ca67382ef64f97c2e9c3a45be42be5e7024e17fcd26c1842d19789ea5499090ce288a189ce54db67436bd3c5d19f674010934bf216de861cad860a836cab0d7c16bd3d1dea29475331af72207856f78f2afeeb4f63719f30d38d23fdf64d5ff293b61c2b424b3397b0611dbca26cd5307384b860eea184d938a55d601d5aa875cd573d9064715cae3ceb76a06a6fe1ab13fb9a2c951e96cd9b45919b45910addaaad2ff15fad7f979fbb653b9a3b855566e2552c6ee5acaf30b1cd9118f40cdb45d515c585c567307ccaeaf4059a5e2e074b77d007582c00893ddf848813115f7cb75de2264d29cfb1ce7853a5cb05e3131e4c2b9e8f6341c2998db9c3cfcf670db265651bd2128b0765588380b4912130afc15904b491425bb524a8529ed11d14f4651483a4cad7e00ab974925f29d7b4c8b4b683cf5e25b5dd6bffada250b0e37b2a4974993a12a89057c075dac507a222c59f2e9c8050cf6ac5163559ee3af4d3fcf7e1db34cf6f23473ac528b2c4db32f6432e99c87d62c9ab8e6d8e5041d30cb7fe6a0585acac768b13c778bf0b76f1347f39d6a021fc57805b65e2c9f6cc84763b6a0e33f4fceccc1a69f6e64f93e03941745cf9e4f5cf80f42681befc8d245c6b72d11d3024feb6c8996fbb15415e58baa27cd06dfc98c3c0ed5de7392b3d1b3dfd4ccdf4fd864c270cf0b8e20ab15ce2cfb61f27d1ce51f325276c97b1187b50d5ade69d17130089ac42d621c34c9d6564bfed9b0135b19da64b7496c187c8c824f67b7306c5a12209e2265cc5b5b53a04e61a19812bb2fb00f3bf7aae9157fe7dbdf9d4394568fc54932b4fbccfa2d390d5ff87b517e81b4f5154476d26457b07425de4a247de9462cff9727b8b23f93d736d20267a0d850c7890d67e079e3634aa6b8e7c56b1bc763bac37b70e7e1f1ba416ab53bd57342d54e5a64e3f8c6f146fe414716ca0f731bc7f5873b8bf87447b70365eb88e6abb0a93b1809962ef7e44867c9e564572ac802560f7d15e34dc1522a01c80dd6bbb837c40fe92eeb6c7348ff5cc3c7fa3ad9d8686ed6d637367683cd53f5a642010da600084ff5dad9567052915e3f5b556a20388342f2a14e3c00c9ab3c8a10b17a46d46749bad332f0f5b3ba843ea3a0480fd81eebd646b44e6edf367d0f147abf48327c1f6a236a72076c1c878482701bcec6f13aecbb9f38614835c5edf2eb9b8bf93015c75e8dbc3a01b13ebf2919ca6102d58f1a624141186e405e004eb0b22a5ee2718819b2684724d12863447b8d210d764c5414392aa243dad3693dcb3744f23854072eae2b14eefcf600a86c101bc6e5d61da552e570f2bf11f9364b86e070c4972a1f6180410bd769ea1e859552abb80469cca720fb822a79d9556facba1cb035506cf21557a59d9324101b4e1362cef15778bdd715310d55dba6119a7a5cfe03863917e284498d6e5342e31dba4deba409e1cca2d56cf678d61f752082193faa319a186a7185c6b4078739f04c398a5f775bd58ee9f836ebbc70b959dc7bcd175c4f5484aaa206d1090d13a4e07a999d0a4b44d44c218b1fa4fdd3f3c528a0ea03178d47dfc205095cb8771a8e0e2b5fed9116996b90b1fc2777e159d404f9c65a7ee85aea960de22a6c056a5cbfc4a3ba56ed761448d11bce567df592beddcf5b5dec08508c031e1615605304ae5bc1e7208941af2d9fcb2d00d4588314d4f73b9ee359f65e473dd07ba86ebf16dcd879eb7d1bf7959d50e68dc5cfaf8792e1e40e92ba86df7cacee17d8f09ecc71107f6775409186a39a69952db4f688165f4869cf73cb1929c248ae8019665b95301570c6d9f623ce823b9e0bd1dc1793661299b85151d5e36452be35ab912894f57f27c979c839433a6375b09ba5244b4ccc56022c381bcf866932547e18bcc019dd3817835e005b68ab2fbee0a035c16bbb8c0ce8d84278e1da158548456153bcfb0344b204efe5016a393ee5201aa6c90eec1ac08d6d8887c73d3260dd3e8db91804762907838a9103efe7ac24a4c3c800c3f15818f8400ddfccea649d78572dcb304032652cdff46b3918a46a0f22c5ba27caf15d2088642f0b82e958780fe82ad80239321ba099ffe8f0389458af5e900366e711c3b9a7dbe4b1d22bc487714ca5c233b78e55222410e01f311da07b846822fea4068e32913e157522458542a9a71596dd1a1fb0d46734399fb54e0b678aa9c894af61ce5264e3107361aecf0c041c554f5e95ffa0b62e9f92994d03cecd93e8264366e9d065b3ec987beadab2b5a0acb18ab4d9946f00b8b7ab1f8d475fa56ee3290159969d5432f98025a34c5bb3e653376234753e4e30ef8a5bf3aa338328bf27176a0fa466c744b61cf301b8642ea574c016c9a953dc6a8d1c23c4703d655b5c4a5f85709d6f2e3acdf123244bf875ddc1728accdcf041cf1471a27fb588d2ea352feef39e5233600e4d829f4cd11d97ad267562911b2a7b26a55bd79368bcc5a368622dbe5e2855e2ef2ab50f7163524d7a5d94d3d39a3d5a7848610a53176ef2205b3c65220f9002e9dee33b4c1db6daa111a9f1980c449d8ce28c47068729a2d334e342ac3e3715fb9a5bb74158d8315aa96d32604d2b61ce2f72e1d00208368ec14fcb3395a187eed2719037cee75cc91b8c2b885c3d049196fa489bc398491a69b2619b164bc29a23ff02350dbb4e88c7c7154e3db83359ff72a3530a72d32c3cd0017a82f999ac9623a82f5ac5f1b65c6c47adeea02639ed35bbcc1d436a05a5a69023d62a79b396b7c121cd6ed9dce2e44a552716fa4636ce425e6c9cc52755ad7325aaa92d9f44558cd91da5a95acff2ed97a087b2ddaa103252f2015b4bce43f241728566fd6040f76a730d32ff35324b6a06d5ac5925eb2e029e0f7ebe7a3857735a6b881e6c83f69445408ef74ec3fbda5aa7bd08160bb38a879e9529cfb05e1049351e96c599b5e8c9ef36be3b2505433b75b577aba4a0f45876810ff026c9b27e627fad99e01a8b269c309e0ff23f4cd4e8bc92ff0d9810b4c7480b169838c9e05852a8eb81b369f93d1706f98c8de78e7f02a8e8f916b99e645299a711e9a68910c63fdc19f5029b55767988972f98140168227d5bbe7798aacf405c9641bf051f16278b5042c0c5d6b2b439e82150abdd7748520bff75be28125aeac1159195238c3ae6653a4e46d96251450d041f8c22cc2e9cfbb462b09a82617f2c78d782b1f2e6a2b1b435f614437bac7859025001c659176f0309490434816646d55289184a47911466f87b0781c86e9f77fb70144228032ca23c24c928738a26ea54b56acc2acba48d07b7168d931194d706a050dfcc5d38aa0cc93b4916e9d2980ca910f207de29ad0b1269810664c5bafa410242869493849a1b4d9298915d1e4592681c9eb07cdd82356cda4d586883b5fd760c208cd994a748c5f4a83310094c307ddb28956b354cbc0e2396b25e3cf68424ac3e3287a8185145ac55bc80b0566c8f7538481a755764272fe95ebbaadee8261707344f645df812e4b8fc41eb565d55450b3d235f9f4b42ce4429236ceedd86cdfa610ac4417a65fdb20325cf272348973a67b51ac1d7521a8bad241d5804e93e0b34af0545d8dbb741dae7e78856548ae057996164504a77a5b6bacb489f42e024e86e309ce075e031cfae23b8f2d0a1b7652d71f62695f8a46235a356e052d5f1aedc5174925c67a92458c03410191b4282034872ce7798960a34ea2529cffa035dce94f7dcf605f97039aaa1622c3236b08280ac1bfb0410bb482e455430bc3f78970b1618dc6b39022e1438a656205ba314328d40f2e32c21b724e9b5fa2d90077c304c931d0c99c406189c4dad8733c7e5e25ebee0b004067cda5eb97c61833428203b62b6c352b03a20535d276233eec50c52375111d1652e02da2df770b34956a96ac020d9c19d2d0eb7be40078864c0406cd13813f93d333cd31c24315ac8b45e657c6174c8038b22fde892b01c45c9ae623896423d43e4161225bbb311db6111a4de916a02ddca184e4501474031302e746adc026925699bb15b0ba718a5ca6d51d2b4c660d106e48ac7af26bb609bca62cfc351eb796760e0887387a5c039c980c13ca3698767294dc74110b8f957f3b9736c69c9aec4717ed933cc82b17c5de01bec44ec7c9fc63d16d66c4cbedcafe6e69d22b23c26dc9ead97acd5f9165ce819de3296aade112df0ba0a64d27b9945c7e14a58be23adc7b25c5e85e79270ac418361222652b8ca32e1eecda25f166e6442c2ddbc2bc4f6cb9aabeab03a2cca43d06e384b4be0fad6e43d4f9595c0e3e98197ee90571d6820a80681ec7c8bd0e130e25d6008a9f424e1b85e14348fd0f96a351aa3215031008689e0c24cc1cc1eb53a92225f3730ebb495eb5544bccb30e5bf4927dd20f3565abd9250e2b1ba42869d3b97ece5c785bca39eaf023a6fce651e6fe73dd7199348bee0616591602b4d0677c86b7b0d32be53ccb80385d11551593e4b26966671589e18924adfd8c812a5b1c1355e5ab3a847ac23d4a67bea07bef90efb384e74d9d89642042d9713cb8980cc12f33d4be457c7deca25c9a30c0a4d19d56a231c47d8ca970cd42195fea4edaa7c82deda9bbfd520b7c6f3b7608b658826946f2adfda5b00c8855b10759949655ee59f2e43e743014af10dc8fe918f43593495f8b4c7b229187405341ac90e729d66b4dbc7a9a61aafd49cdcb480942b5a35a2b96302a7979a8b8546a8db9de46c6dd93f2c820c3dca8d2b4a0a16acb23c6e8ee2218f8de8e499009786d4038a629e5ce7b1b4cd71ed559a96b227e8d6168334217202166b820c70d12e1de76397b201e531a199ec159e562d29431e4ba956de83e202897924a916704baca15cd37820f7aafe317180d5f5b73a039d65c082ed17e275d1d885d158b620664581c005c86af8546cdbd48ba46c4d3015c98a07e4f8aad00122b5d994617abfe21c09b9182682f9d5569cbd70dcac8baac74c8324314c2aa58be47d9ceb620aa73637ab287d011675987934c2d1b4fd046a95065b5b77b56440487796dbb4069db9be1b7b32d7122d7180b3483d5413a564b24d0d0b7bb90d51a960a0ecd6ab1228182c851664bb497ee702e8b2e8369053229f7490fd418341421f741d10dcf31e5c05115151fdd21d92252ba1e4d69868df1a6004302655e990c58914587d9d150833396d1b9472fa626238970c4d45467964172435b9ce94c5568f65abd08badfcd1dbe1eb378094381a6f62e71b8954f4cc149520fdbe5512dfd5236bd624dcd0d9a5828ce428c8a14651566c0758cdf84f355a3a00b32ed9ca0d2b25e75948c21170933442942d3c6434f508406da6a893b53a304bfbe16a74c8eb4726fab096885ab76326b35267b6d958d472d746bd747920ac458e92d2ed5805d6f1f36683283813bf5375901d875e71490338d40981c329638536020ffb63cb9d6d6dc488dbd12a3fb8a320359b840a311a300d09773a617556f0859ab24b0a2a57824a470b4a08d125893855c44735e280872505ab5045b38913980b624e80ab95b797d20e606c39e6bfac784989e93e1552f1747bdad1228f49f87af178aaa1533ee45416c3367deaa967b86daba2782420e72204f02329faa23416b518c547ad45457c55c6b3416c3b11c0c7d23096731546bbd61a9223cab788da590210c6a40750a106d658220459d2a01064600d1ebe0ef09f35b8a84a723e0dc39952789c82f51d518d390e9105e26a4aa5635e0888ac53c2051c6783780f7ae5a12415adc0e3158fd210a5dbc805d1817a9c86285cd3b5c5cc0e826aa5e5e6553b18689ce3db9a9f831c0fac26c6ef33d68caf043534b8528934c35b1a571bf9a9fca8b615fae754037da107b8ba0dbed96ea9e615335e4923f06cb893409fccb63bb2e4a380c2259628ed8718faeab0cce35d79e81e1fc5db71b26b54cc19af13cdcd2863f2c9b864d869594c2318eff53b18c525dba07e6247d48a5c8a55780d5026b2ab6c57b6c11c1930b8bd24ab6e2f21a3215812cb997bd8108d227d9e7c25b4bca7e591234b006f0aeb33cae1f80a15c21a24bb7fd0f6d1e9cba331da2fd80785c413ae7d36750e135b0e383ca1d96945b72f5fdaa6e5d002837afbc489b156e18b5ea41aa6343828fb8053a1c24959718cc875a4586128601d575af9623584d60ff23e9165ce95fac542b7e9dc5404a01e5889d886341e2e1f5f5aea21d8640a6f03b5115c2e732a0b1b62d090867a5b8452d460442abef2ca315bfa3bdd5ae99db32251bdce39dd972549668f4cc12de78775c708ab93e5ebc51105671f2f08c92c29c16589822ab0aca7794730ac1ab8bcef2b99b642065a793f717be5bc8ed8eed04e3496aa7598c48c7458262dd72426033648d2b135bd2d41bbee2c2d30df655b44d9c3624a2d3a4b392401a57b572d9c1898c4e35a8ece5cc4b8505facd6f66c3c3e5d4fe9ed395a5bd99300b06da9a6a2c53426df8694da67ab262969f9a7a4c31b790d274ee4d505c5f5cc741666783380e59b730ae682dbcb4596f02f1e8fa241c08231c01d7dbd835fd014643331597fc0c5557ab566cad86b4f496f80c3338039df5fa66adf6fa65ee673ed0c287b0bc1cf003a469f0ac26370b89a40127416129a6529ef8c329510e4a40a7a19301a7bfcb82aa803132265010162bb3496440e53a6af90556eb193d2e6c57a20912ecf80928de37aa5dd386ed54f92147d47c06121cd28d2adb3632b94dae9a4ddffd0406ab7364b485776852ea0b72ace15f7f2013aef65cbd985442f62c44171171ffd25d61db4d54a46c10435b97c9482ac158edbb7d51b68b54a32083f0c4cbd5ee9e2a8d8547b5285b8a8602f16d4bc4a646ede45a3b595f995465d29d399407e877d4bdc8b4026ec2669cac4308931fe0a3acf0e7a0efd9cb10aeec8dbfaa20ca585e51baef9066903c4275606ad023aec80afaea63174b949e4177148b61f0c581cb2d0b403f35a6975b5c030856823df788154b6d764a91ef804cc31b5caa8ced67695fe494e117bdd204d723a98b3723b541fce3719c0e118a920543b3cd59eb1719c43b89d809089b827974934f5c093ab96f5a0ead872716d77cfb216bfd6841b95263b6a552b4856468a88779a58b3152b262b15cc174b081f2cc8014b7b3e40786f639c323e91e4327709919b865857e0d9e7dc4e929590d188a84103e73030444d077bf1381f804112b2a89e9f08cb8f5721f465c0d222a7e7ac8c7c6e75df4a92ed1929ee774937bf2f2520f364968824e27a24ab2b816b565a642e989b9bfb46653d52c54a061d5f552bd98cf285c3ced190456aef2feb8feca530663d08e2b2b0aa38cb01dd968b92dadedb617aef100e23c865867633dc2405794e5ade3eeba5748767e316999d0f162a1bb2d66719b51b800af7399ac64c906fe5bbae3c890372031c755293dc652c867bbae6edca21b2a71b2582a518d69925645ec549a5ba1df9220cb159105a9725a497800a31eaf56d842aba5076479640149cec1de12790c40909f9d6164b75432c4c9d7494b1598ca955535dcb44bc095b76a8d98a347170debecd64af4926a9e6900b29eda9085e873d6e2ace1051b24b4288888518ba46913f222624cfd098cc57f6b0baaa620e7791a0006ce5abb03c1537eb6b4198528bd5abf943dd130d61fab8e9520bb33acc64d5893cce580f22bd625f4ff1015b95c55a64019331184f59b349be0d7baac92ec1f070684cb2c3d2948710f8ccbb648b76e1a6624cd288a73df380dbff6d44c3b594c111311dec59f872fb7649aabd32a2619632d6e95b52108b41ae385146a7dedbc8503e43e22a51c22387ff128c7e0955fea98c2dd4df4a08717da840697f2c2315f9570bad1e37079d7e99a41e3c6c14b174c54078fa0ed4a952cf85630fb2fce38c1d25dbd191c2eb9b70b7968a1c8640102e6c61e48a6dabc86abeb454957925679b0223e54b7323d712154bd89ca0a2501ba40c2f9c912a0d90a786d06296028fe4d076277592bdab52b73319438d9b0f0e0525198daee8fd5330a69b4dd24f76c960242d22fd054e88874caa3a664f35af6438ea44bcbb5c15990c316c527fd21d91b21e1719840e836aabb79f4bdbce06c5d524632db296101a866038a2ca3c128c28476badaee67d80c1bc4395ee48cabd248ec60615ea3eb8fd9c31217baca9368e69dc6564384a258028863220f12ddd082d05357fb4cc9377cbdaf481e2c1a7d20988cb7483720f7dde1da15ad0324df187c4a0c560d44015230f264eb1a5b059c0738bae58a1c2d1324fde2abd01f0b8ac96e7f55471ef79c8ba2fd8dd67265705a63b0170b4db1d013d0ce6ada81563a807f98434a2b7244502bd5eda46aa9437017a7a1cacca36d28827c6082d87a140cb505d4985dd50ee38f714913eb4324cf900745111c87979075139314713c6e028647873968d44f5b712037697176d7b8fbdeff145c12204214d185d3953f2bb695980fe39bd8150e86a6be3e691ba99d04c99fac590bd52c76b6fd03029066a7fce9dbcec8476bafe4bef169dbf930dcd47f4b6e5ccc95581d2b6da130fc80df0b1ab3101d3e669313f587712f984312939ea5470de280ef13e41401006ea76522377160b43946f6d4d3915746c4a711f96877bb8ff283b56e799eb387e68d86e0cf7c8f39049dd87481517c3887799849556a0535e4128b3bf9c955dc9b49409e624c12f8cae9dd7a87aba51bdb9a4af319b6e61d0136d9650956745c5292a0f0159416b7c97c6607b4ad19e16865cd70c471c7996f34471d52e4f391dd4e70ee73cc6832d341c9787fef56d38cbdab03d156856fab8601eb24502b6c9d3561d2c06fd631445566f3aebac51f889bb576e4592d934633c99f6f6db0438504b64164f06a98830951b45fbdf1db3b2c0cb664b51b64575f8d17d68f51adc8d49ce7a3eb4c8ecbcdbe979d3b52b10c45271c7d4da85eb82213fa0e9b61db82e48c8d36c1c1438ddda56ad9664c8b81343246d55be5687588d02ebf558b666db0793e3f91d53622a41ab437ea714b57a16e64c871328d00e512e088d751a281d914c3ae37c0e3d8afc3501c98f2781cb93b6b4678d2957f45b5b7c16a5b066242d86dd1de05c107f93ccce7b2650a5009e7c7f8d193c7f608c13586f62644a7ca104788ea33ab06632379b3b333ac99ed92cd961a980607b5c47ca1c7cee5cb257c1b8b0fcb8f6b16fe9b1d469f3a56455e7b71ff9562785a993ec955aea9eceaaa0748215ef8c93f6e3e6482042bfd0668cda3f5611ee9bdb5b81c2479630d0dfea006deb06c9104e8dd65e337503e81d1f8ff5b99810eaabc55ba1f26aae549ed5a7d456c036554b55bd4fab9d80ce1f77957b3fd1f5698ce94112f22dde4577f40ea7ca034396afaf80d7134d7b6bcbc57868eac500f7d2177d3c4bbf2f06bb97ad572baa64d97cacda2353cb99d6e9ed3caab9baa94276cd1c91e2adee046dc3c14da987282f209e524ff1a43505678b3abbc206c36c6c42b8cd70f258b03453c13188041339592e9016b9568bc94912253d129b6c7e2a192f9f9d2d85d39916d8c12598354029f4dc0421d8770ce19de02068700743e8ee9b95ba227afa1d7c784c5d2e3456f8bb51e802cff12d4d6300982d85da0630dd93478ba06fd155fc89ed89d402b208e289df55c369ad6866a44dcf163ad67291ea8a74e014df2cc640c919e34bd6626edad53bbc2fb2744c7a2c6629efe6773095b285c0b55cb5bdf90691aae2de4283581ab29ce7c1de3c59227ba040eb5cd1f07e2cdf8fcbeff7e0aefa85323cdc726fde57248b5f637bd928654e5356b9249d64f8499f83849cc8cb594445a9510a49cdbacd1148e8d278870acf7d296874ab4cdab58de308b8711c7b1fcb66524db1d0c8f5fe7c124baa6a1bc71742079a8b0b52b375964dbbac4e1f64bf338982d41d92f9250daa3dee7eb8ea8ea3ee00871e726fff1e9398f21d46f860882d36dbff0aa72014fa95ac64289785bd27152514f3d20c4651c687914404c1043cce122c09da648f6544f578ca867236629654a9cb6030c5a094b027e31113d759aa5b3c4b781cca658009f4d9d378acab53014a921cdc454c62c8a49e4f60cd312a7443376a4be75b48b674698592ed75314aa4cf858b2a3fec46c1c4520d3b2a194f3e04b542d3ac6807fde506e48980f840f14a9a154bc899333fb770a64e9e7fdee4729730abfc5550987234eaa3b47e2e43035740c9d6372462a357b0cd562e6fb0c6548ab095505fffb0cd872cd4ec6cead59c625d040e77e5b1f0661a99d8c90d9d66888bebc92e4baf6d2d943aa2907c68e3f89a0490ab9419c07c237828b1c080ee26c1c6712704a969eeb996a3ad56793496368eca2d93b3990eb44346ee53a1cece84b600e2199ebf94969473d6522403c36fa68f20e04d4984ad88f62079afe41e1645456f88826b99fbbccab49e8f189536413c2682f730ef1952ab0f04157042ea3785367f9e68b9a28376944668bc769328625d23266080941ca65a04939285d852ff4e38e2184579374d42282d7505d7b27f54a32e245680339a186026f9dead8c9cb7806d23bb6570be863991494b8a397287cc62da68952a5915f2def820abb1eb3428dd869ad7cb1a09466bf2cc483a9af63069685c1294463e3540f6424d34cf4001d978b40cd7a7ff584662b697d97c6df56cad6e8dba6738ac2e6b157efbdd93621c77fb69122723118d89944bc2ea1bb545a0c7234d84980d1338e22f587794f22cdfd78bf880ab450bd29a94395e4ab8965ea98c99517dbe359f1535f72a05a5c1d021f7aee9e5f4c09a9b2b0ee5e9cfeb7cb30261c58114398f6a7cd0bb9946eef51e16e72e39927d1da19d60500bbaecc728516102f927a075d798593c04669b3585456869c92659ddf2e1f1b5e9ec552bbd384919c619438499c8dc19bcdb4f2226256a5050c2f5d2ba96a050c383537271b158b5e621c6b94758c2afc4ab2cf317775a97db1add6438ae39c51b0e2dee1199940d23da65e13594258561b496d575a7bacd4d13176a9757cd20be8e5e2cadd4eb65a04df0be54556a281fd0745b4d19373e75d20de496747183a8f5c4c04197384446c6c908d25f7951d9c35098180a6725db964e07273454381ac47b8dbd8daa78dd94aadc3eddae73b0f82830265dc17102f266a07df8ca4481a24ed27e3ee8e1c16a7b542c23d79d6fa7ec0b74f9a017405a530c6b274b64e3388d93783c48464229531a2e8925ed95773a97079fa0c5bcbb9cd580c4864463f566ee00b28f1e0d7a8148bb648960e74c92812ae7bdb2ed1c2198190349769d06b1f5ea934653d68418410d7b17ea973f1a5f354b62c0f0f062db1c5a78647268f965468e271f57578c5b1d8d53b245f242e57e845d27abda40b506e1c937978aab92cdaa6eaf968f2fa95896dc06354b587595b990704b4b2b3a90bd896c0d9de860e926913554858fa9338e0dcf53dd23dff28edb4436930c67e82b4e50f971d3159d8bde96e48bb712770acaa485b656da4a6158600cad3eea16fb785c8de91229419366512b742c45d9d62e8dd64c7778717ca584c3144fc13cad15b1346dc3b350a31c4e4f91af38452aaf89715adc727fda54b5e41fbbce96fca318d9dbf7467a5d4d766b4eca86d2b092b209bce8b396ed53bb95d5399ee49045748c26abe49a86ba999dc395eba3284383484dbb94696556dd55e4546ecd67b56e38d9be0bc0f9eeadd52e67a1a86e9aede4dc22351bc337c9bc1dd8e0f671c59a57aa48916fa55fb7f134c899b9b989c74241f192266b836489337fe4cbf3da016864181c71756597f2c71986ca92f3e8fb33722f2995c8f60c3880264549a6bf8ef1ab2bcacc0c80aa2c0199d3dc00fa4bf2115e1e2d171b64af41c61325e6a40ef14e8a09dde1812f1d4cb21c425ace99e374e484fc334be6eb758c97295fe6b7c523766d87a53b9ced920bb0ed2508558e4dc8fbaa9229e2b54ee0877b41df06d58da840af31069002bc7274c23143489ad24da2243568001c6f0094dcd48b6e663c2a5c9a0bb51ce590853c8e69d24be9c071cbea46dc5cb18e0671e54234d762f93d8c164e57315a5e5bbbb172eee6dac5d5f6f58b37dad76fac5c59595b79f12259225f83f87013ce45b8209779ac8ee265bb6acb4604e422edf6c185b5d7188373013b66899c2627c9427ed45358d7579d7b49577979e5eaef9325b2404e929afc73294a68767a01b37ee660172f5fbc72f1ea1a39456ef2b8fa7b1d8896d4e1f19993a406f79f9d42a2acfba8a0ff2ead9225b29ebf94ffcd0c53d6e570b7eb80857c3418922d49d3e24ca300b843d3318f7b648775cf207e0f4cc24332a03caec9a73a79ad044108e945ed4b70c404fbad02d59d99fcc566f072c2e3daccc6463c536fd83b58d0ae177ded320321095e20b4bdc3d28ced5d4f44b92e07f60ca1ed9ca602e428e6303d00e7a82dba29633108ad12520d3aa0d919326a673aa1820f6d45df3e66ef5afab6552f3909e86b564f34ed1634c85c30d720f3c15cbddc18d42460bc54ef04b4d37bec611be2ecb40af7ec1b363ba3ad2d4ba9216424a58bf55baa50b03bdf28b082c9ec637dd84a9318ce964a2bacd93407f0402d26afce42908d23d9d47f224b52dad37614ccc17340596dfe6be4646156d7dd1b403926d7c6a2f62caf29ac363c74a806b666bc0f56dd67617ee33e999d34440fb89d1e84bfca5c2fb7fc8fc56294b28b7132eaf5574d5bbd0129f89f0960d33b0b94842348a49c819b1fa42f64e2c4f1255dbc90700fcf256214a45e165cd4527daae543786abe7eb22035bfa9c723e88c3376b968b939545edc61e9180fa6ed32928e62928c323c8d41bb7a7f0a7a1b4307b25dde65a4c37b3d5c53ca18b1dd3c2382b181501c0afd2afb015cb02c0cc879756e808c045c81a8f704a11a5c7cfba39eca8f28ca35e129de0c0e5aaf56b25fb923e4da536f94f1c1302b7cd7277165a1d2a3709dafe2d8229ec5a2142b6391ea6d0da780ba5acbec6f31e04dd04292e198bc3c1278eb87d4733ce364cfbb52ab17cbf066deb9047920735150686001d6be2d71c2859fe04cb243997a91da3c2f71742f82dbfed4e7427523a57529fdcb4253ea772572e59a2041d526bf5693d43adad08a42f1b2d45e148c848156b88a40462a9b4a7a2cbbac5fea520db23e63ad41330d32a39614f968af48f8dbc8b399cd72ab7a51c062da89d88b806f191672e444434d60eaf2b4eae8d2a84a956a561240f6bd3ecd8893d309897157bd8a7ce537399a2ed71321edb4eb49f9e2ce3c8be79e4a577393073cf4cc52e3eed6e0272bd5de426f98d9b39e3bbe1559c1de11b0e41499b7e1c705789c6939f0c266de0cd4774afc5aaee134b8e29329e93993431f45cd573dd4f887505d27c4e36d67fa8e7869c43c8b6b29faca515a1c9703fe67692e724a713bbf699132dc139b863270e0e7f57e130f73586f60dbca166504d740b14b873a2a1af32ba1750469d845865994acab557ad2901a0972ad365fb7c3ec2c8b0eb0d1a855a6105a4b9eb7e93a718294e8f62ed6b8f82ae90e2969c130ce12b5dcabb9cb0549b6e918af9b2a23527232198e41245ca7a95ea61a381613a656c3a6741258d517cf6dd5fe71c718b9fcfe22374a7bd77c28f595d1098ba900f1bfccba3dc9c653c980480844dfd834ec3648594dd3015fbb854a4dd0577f716a628bd32096ea57455c35fe37d562d68b820e8f4325d47b51b07ce3c6f24bed73372f5dba78a3a158c857083e5ca0192d17525a4443c25d78e9eaf29595f3ed0b3796bf5d960be04dd46df6b2b9dd236e30badb50b442afd02ce57b67b676ac852d371454744d3ee6c576b9c816b62c2cb60189b6891ac523ef5bef456a65c675f77a02976afad6ed0659803ebb74f9daf29aa1f6f491fe930699f38cd0e44a618637c819a8f0e6d5d59517ae5ebcd096a81bc079d3d5bb404e92335e750576cfc01a90fc7179e5eac5d506992bc88b857251772db0a5b5b36cb8b3a103a91c934bb22c29aa1dde85c1aee69b3a5db59701513cca3521178f66196ee8a213859f5dd9531692fef6f8570c1b66b6bc0a578ade1ecb2e594527ca1c1d5492c39723a7ef3ca663179d7f4fecd8857c6c64b54f872cc70a4775215c7a14d1d48a507dc20bdfd16ffba4de63cbd7e0f51e0b08ead54e64d5a29213197dba3abf8f7a0d29f2c42b239a3269d647ea6a19b0f855049a8a84f43ba12dd26a5674eb0417f419307eafdb2e68703aebed0a013216866b03033cf1fdab64167db6a2619c74231e630490ac33974f57af5db8a85cd54fe679360945a04f6dc7f2910ee5c9cece6a27e791ae63e57b74bc8e2e9db6a3d875fa9ef63a88273986c974eee0c96ee0a7d01f533b7b83bd71d1df0b67034bf8789ca9186abbf4abe4a45dc1fadce6fadca65378a283b86270f4f00ccd24c6dfbdc83ca242657e9a95dabc8185c8fc9ada692be742ce1f53b96c0df4910e5b97efec7cf3d685c9e6575fdd7dac23e01d5d1b1aa5953d377453ad317978a737d414cf108af26d782a645059435ae457dec0c3c33d3c8180de729dd505968d22ec301164167aa718fbeb80eb5ba98c63443f998614cc9b56f1450150326ecb7a6ee43e3869b6e2dd57f9b3f98c763d7ece9fadd21052a862dc202d50e995052c179096fa77c38ab8352b84d7396007d8d52cbe3945e6eb25ce25df5c9aec0f7f5a5ef0cfdbf7fdb43cde4feae57e12cff6d3f5674fe7c53eca777d94c7da1b2f02919f655fb4d7073d85ef79b2cf592dc90dad43686d7ea279fe05fa981fcfb7fc383ee5237cc9c5511a9a03f549c86eae34889d7e274f22805fd167e8ca59b1ce273a8637c99284355ed669cb692ff0ecd072ba3e4261f00a2bb2851d09a41cb64722386d21c81db9fecce8f90d075e375985c769a25bcc5f916433d70d56747f95dc5edecafda720cab772e00a622d2045bbd7fae498bb85cc2d3a09fef3760195b7bb0273b329571a691e8d04731cb03352c4cda84391b0dad8ae58cbfb3ac9ebaa299ae42bb0a87b3297827b8ab910770dbd6e9a5ee5eb2f74b6f1f09747b2a04bd49a27cd3106504424af411efa93cd3a79ad5c5e6a1ad6355e9324e82339369fd8a159e5c8ac765f3e05a7e5e3ba2aef58a27f6ad7e4698f6bb252443d82c7f229782a9f808cd3ae03b3e4b8bc7e6de5ea1a7a2e730eaf5bc18deab0f690a682697bdd72efe4efa78810645ee70e557e9c88c74c6d3b81c70ba2f3e244cd0ab81632e9f12ea1707cbb0138e0f414a85ffa8ad0c4cac42fcb883e95ba2c8d43cc55843f4d668693042f810095ba9fec627a22d87bc0cb1c4e5685263214676e94a7e70c2e1cdb4c5222f0f8a672d2a93b4199c9412658a62e20d5793fa5be97c22d0d0617a40d1770aa31533707936e326084aa24cd68ffcdedddb8f1c20be7ce2d2f83af90162fea042a5ad698d6f238c33b8b4f77d857c1f5e60cfc7974bb41fc16b52f7776922068f727dc5557ab1b29d92059026894dd43497724b26440a224d99623ae2d53e7083e5839b3f88f65c142727abec722e55f55d0384cb3ee7069f899df49d35eafd3a174468eebccefa4bdce8cea68bf0f11fba06639fe1e8d6b6caad19549a485564a5d0a46b34ed406ae1f2b411b398bef5a647eaefa7cb1975195fbf4b1b848d6904e7482e36d28da8b8b97cd8e041364f5c51748874a2e91320b2f6700541ae113faae531cac742396ff2bb1afd8e9691e5cd440e0c4d971ee7040dfb4d8810b1c14c854d72d28d83019acc4c351869757b8f32c68c2a7660146cd394553dec32693aed8e9cd62cfd99d0b290f41be625b499830ccb5a336f5151abc4947aa1019e6ebd9e16204197e85ceef1f8770cb737e061dda66f5a89900562f826293e6e68dd8e99dc75bee59dad84873dd51ecf46e2449e6bcc3208f3fc098d0d2fb974aef79ccb3f34aae381f68371bd168b54b2386c923ec6f11f8fb75fa08f7cb6575cf89fad23cf9b2e843fa9f584a3295da4035df56d1cf8d7814c2c096efa2b4408995636aa757db389eb26eb671bc5e8431ff0534cbd2dac6715081368e37c8fcdcd1c0a8284d0bbdc5a348c26e1cff9db939bac0be01e960ac52d815c5166b2f87eeff52d32d63b740827153a9d3cd032a97fcaf42d296dcffd2a7d196663d34c212ed7d75fd9305eccaa454addb934d03fb98cc92af56f486061e6be031001fd10b118fb77de3aef76b278dbb540b368ed775c5224b936da646e1b9e79e3b7a08642513870042a4567cc16a05ba10d0f4d7bca4c284921dd5610ef4f808e8bd0509ad82c28ec26cc18e8fea8c2d9eb21b4cc8e91e3a9dd053526912130ee8b8034e57d1a75184ce3e958de46cb190c687f723cbe98b951e3d5e5ddaed836b500a973dd292caf8b845e65c09845097b03fa7805c4baae06cd862d851316ebcd04830032db1ed0121a4b0fb0107b2076003d6368e93538e043e45e458cec9fff77f83b75af817dfbc046fea1bc7177d54d8846ade3154010b592667a1fc1d67c816ed6e53ab537ef103feaed51d28d8fdd23bf84b6e37a97b2b6faeb40a7211cf3cfa85835e9bf20bcc263295ba87cbad03634927d601ab5c7e73f9c43ab4e6a1ff83bb7c30fd8951e9419dc38e42ed214f9ba5f2373b180af8943ede41516a8499653298c64145b4db65c34c5837ec151082bd61a5bd8a433290e6a3ee809830cc1ee666f702cbacbca494c8d5696957b68a345f4bafaac0044a207368b9090dc263914164252c625c856d6042dcc5425dd7741edb3c4326e6b6b40bb9654aaa8913eb5220b862f62bf3a23822c796e42cd7c8368e5708069d2b17aeef0f931666c73a8b5aa94afcd84d06439af14ea44eed25514876582a78120bef34f5adf2f9e25ba074d157c2c900fa74591ee26b5d96ff1c395ed6f614391e82bf1e97e3bf685e0f26307b548ca7fead617657d3f431fbd362f465137166eeef52b743e6c101022f2086ab69b4cb04da05f9050b08750706f2dbf5887699a6db3612308e80a0c5c4453e86904aba8092ab7bf93a63a5d95cb5cc915a7d128b8097fe6a51281629f30c7585c5532cf9046301a4958e04e80ae48709e4555803bed24f955d2452161206c10b1db69540be07e5e4818b0e85e5979830301dd6e3f10d6f3cf823d38141147d16e7a46cf1988b3e73af1f9a8a3016878f4f162e1b520185accbc990e14d0828d5adeb9421151c38b6a50992fb5fd429d76af2604538cfe28ca5e755ae479bcebd06197bd825f7b3ec95d821f7b58c4bdf8a9bb147193de51ed1f710f27838cac840b9c3222e321683d8b970ed0a7ad6e0d7304dba4c688f5498d2de6c3c1ba6c970429770dbd1d62abade4a349ae1b9c122a7efc2bd06097dbd073e73f41d4a9b40dfddf7e20bb0ed53ab377ceb448605725ba5c7b2f36b572aa0139de5aaaa8e006dad7c28b280c7724d61b57addabfe0c833db244c2f2800f83b1fc30f697224b64787465e58a6a43f0b8604382bd3a3949b28056545e1b82c745018f1138f41294058c9c9234951b92055bf8c9df94c9f66a16d0929d9a05a1658d42cdd6afad4abbf4716dd2f20402ef82c395f0e6125ca6d920a29b2651042cf1187c5a317216524f27e380d9308fc238de19603313e85146606609ec0f5809a97c55359be47c32188e547c1cf619d64c786c621f07c948e4e94d7d9db5edeb2cdcd8aed503439664ed86ec887a0075d9636283cd02dcac047c349110a870bc716ddb3f975df7b66f5ee5123e0bd804199f055ba5af5fde89522c6ffbfd6a528129f3b4b680f21e3b62ca41eefdd5d2bcf3ccafc226c3f4fd38affa8ea887a729431ead5b8e56fa0a4bb851b53a63f222dfa101ecfb042f72b61be4bb7b098998347be26eca32a65d64241965c351e6a21ba6c90e04a20e5336a429cbf7e61db5a7b8c473f788547782afb29b77e370c8e2f07c9f47614dcdf372cf4cd67108ca9bab09ecfcc1d644924621dc49940c98542f7729cfd4cd9d882b508e66a5ef09067716a19633c120b537b76093770a6bd42e53ddc43b5f8e114f59c4a86024e9764743a9fea64c24a3b4cbc484a1d785a61d7de5cc0667ee89136412a8cb2c18b17704b34ceec96a43e5e9f4e5c4e9a352868353c4dec09dece941c714149ac58bfcf1d2cab2cfc919151a86d2c62cbaa1ab36007586849b2bea78a4726ee0d659a99721ff33c2bb777179ace09b2bc1303f65334c44099b82823662ed2510c7451ef0d0a41c58f1d2e6c8eaaee418751f871378e9e136a7a0baf4068c68b37be7406cf15464c0911e4ed4e9098faac61682aa4f27b335b1b21297fbe0d7293e60f318c61132fde7316462946ed1aeebc72f506571facd1515fc5070e15a215cdbfa9a0cd90cf9bb56276c8f7547a5dd8d935e71f5ff31f72e4c6e1dd7b9e85fe9b052a29cb09bbdfaddf2d5cd912772e8ba43db65ea3275ca4a29e02628cc31c0a16786b00947fffdd4f7adde0066882175e4a80e55e2c69efdecdd8ff55edf7acfae738f8ff8d6c2786f169e9c7cfb75f1d1913fa668f78dbc3920a77ffcf59f081fb98ff4d130f97eecca07e783da243f3c1ff8dca3f93062d77ed47c58bc7cf9bef99141c3f753cad1a62f8f7d1e1a5c729a52eaf51fb6577f74c58f288a8fd0d271157b44db778a961e5c9a8396ea6d2745fa7b69d5f8aa0fb9768e1efb7f7f560ef2c4aef9c9e48977f3750fafdff3749e263527a7d7c766d67b837472667d7062dd4b6a8e07eeee4d0752f391d77f44d0d2bed5b0ae8f686dac7a416d7ff9ce5c1c5ceef749d4afcce7f32577d1f3ffb47cf78b7b6ebbbf87ffb47cf7fee7cdffeda344dc5152d0bc064f5863debfefdd89fbde37e4ceff9d726becfd32fb873e3a5ee7a707f23dfaf1a3064ca3edfecf078cf77d78c078c94f18b0f7b9ef8f18b05fcfe1527b39f1d0f94425fed8c8cd0f7877df03ee1fc2a340a093efbfb9fce8dbf5e653efbeb9fcc09b4f399df682ebadef7a74fca247c712f87fcf6c7a5fcf9aebd25e41ef9b7ddf5a977675793dbbd22fa60f3b57963773582bf5c75b3ae7f8e07f5f2d5fff61b938e928d8fb8487e6ffeae26ab9d7fcd539be5cbc8458b15a6cf7fef8493333df8b6b3c320dbcf7f21f6d1f3868c31f5807ef3dfe7e05d87c44f530778c12e6cbf79ffe13a680b9154f89a69de0fafb61f8f0ec78f6fcdfe619f2e13088df5ede2cbfd83bf699e1f37ab11ea5e1cdf59be574f1ea62da97af9fc5870f4fb01158f63122f8a18f9dff3844b0cd471e3f36e7cb9b43881a27e0f0ae0d6fed5ff6e5e614f1750e7239b2bfedcbd1eea3296f0961e3f6efef86d1e3dc9d4cbc7d14dded0f1c71e223e04e0364afb7dfcf4195c7971e4b19fb6bbf3f19413d5b4d35276ef9d2ee05308db37df9eef5627331ddf3163a01ee180c0f1191bfbccdcb4e8e0dc7859b9167f36271bdfceafafae2fbd7cf19d6722bd9e6bb3b671fcef9eeda735f7dfffdd5f27bd69ebf7ddbddd3234f679f863322940eb5d7a7cbcd9bcbeb25c9ce9f96efaeb5d22a75997db1f7b98ac3e52b73f5f6f56b2dcefe4f66b998567b627af9cafce7a1cada7f9a9bd5d55bf39f17377cd6f23f9df90633e9569a9646f35cbe3a3c8c2cfdfa804a788852c24dd70c9901ff1f6d541ab9c46d7cfe480fd357eaa2dc5efe69f97284d9bc5e9ac5d5f76fb53cfea8407d9434740db56ed2fdcd72f36279f5bb57e6bb718e052d92f3ceeb816971b3fcfef2ea9d39db7ff37132d1df986df75f7319fca3a283da0dfb3f6f2ee70633c2e65646d2df7e3d96cb0fe68ff3577df99dbb7889f577f3ee3ff8acfde72a2af6f02e6024c7b3f655f3e7c6ccd48e4b7b1efdc59831cb312fc6cdcbbf2e366fd6cb7d27b1f224937f158ce79f8c317f330f5f5e5c3dfcc23c5c2f5fdd3c7c641e4e972f970fbf30bd1274ebce455717dfaf8eaf12ef99affb4f8615adf43ddfb93f2ddffdeadde77cd7a343e5a65108e39f0ecbecd90d4336585f62b5b83a83f27de926954c71e50fe3f7f163f3e5ff8b762c1e7ef191369b872f6f5d73b2c9dae853ade56d77dfcaf77cfcc5faaa1ff9f2c79a4dc497ef43930f6bfff37db7e9027ea42bee116e18c96877a8ccfec23f2ddf8dabf11d3fdc93ecc7176b19e76f1fbcbd5e9aeb9bab8be986f5b7be7d3dae73df7db7bc7eaac947fb8cf8f9dc1c4cf62596f55f16572fffb07cf5cb195becbbabe562c2b9efc85c2fdffc4109dd081af97ca67bdf3ee085df3ef885b673cf65eeb9eff2c5ff3ad88d31dfcd679fe1e7b8a5ffc2e31887d1c42f78e0875f9adbc53f0ecdfe5cf9c9af5f3f32dfdd2c376f8e80c3bebb5abec267e0304533024379f32fe66f3f982ff4f81ecee4cdd5e59b6fdebd6142126e74fb03fb4b4693a0c7ecaf3a3eb6bf1067fe91a871bf3e085cbcfcd6c1fdf5a72ebd7bff71f335fde98b13d7dd6ec2cb8beb37ebc5bbdf2e36cb7d7b0f870edff5de65b7ef3c7ef5dcdbee354efdd77f1d0e1cdff2c57b4f3902ae1ad6c12fdf4bc67fc34e3457cb5777ebf0cd2f39be4413a76fa33b29ad750b2eadcf7522cf43e40e7306edfe87dbfdfb2fe6deabc70cfbc52de1900d39ddccb991afdfaed7a3958fe60b8f7ae40bf3fe58ece7dc17e6eef43b9e685fdcfa8b6f20bd78f0e8c1c5062bdc7ca70836d72a4c7cfbe07fbc58bc58ae1f5fbd7d7d73b1593e5e2dd76f9657d78f97d79bc7e34a528ff96e6546ff7e71b3ba7c7b73c05838bfbcbc5efe88477ee8f6e3f730f71c9f3fdaf9900730b3ae1f1eaefa03c9915ec0313a3af737f3f67af9abcbcb9beb9babc59bdf5f2d5f5dfcd5fc302e768fbf592d37cbdf0f5b206e6331f4c50bd2443ef7789c0fa38bd97b3c1129375e8fc78f9534ff7da81b367fcd7cc5fec0fe1210ea374c8ee205e3cffde91797578aa338bf62fc7de782f5f2fafaf62538b2bf680589663ecf3f0eef57903a7df97155a9ede2ea6241c0359e1b7f1e6aa40d4170bbbffb70e4160565bb3e34fca36bfff8ed83b9ff540dd8f795fe397a46ff98bbe1f82f7cb1fecd2f1c775decc6fde303f48f435bbf7df01fc7107a2f97d32565ee5f1dc6f6fdf9f4f97ea4cdc31bcc9d238c44369b3ce330973f3f8cfbfb6f78b4efeacf3e3bf1fe7f36df3eb00cd8998740c7ec23176bbafb3cbbeebff8a85bf773edfeab8ffbfd68e67dec867968741ede7ff518b84367dedc5a982a560d17eee7df3ee0593c77a66d9fffed874766d0da415ef73dffc53c328f6602fdea0b6c9456fee2a8b0fc6172dcc2833a1c3e2340c697f77dc5f1e4ba5d4f538d44c74be7cb2fcdc36b0ace0f6f152cbefbaabb470e037d3873177f65b0a0d37df7f2628b9efbdb7ba4ea8bbbef1a4f7da483710b4c6b0e56c289593a5581729f9c40d2facb078f1e3c7e6cfec7abf5e55fbe7dfdf020a03edc8b985038bf340fbffbeefbf5e58bc5fabbb7af2ffefc76f9ddc5cbefbe7b785ae6bd5b44763677f07e1a87cd97e6f3e33fffebbf8cff85f967e207fda0d2f2c9b690a5fce616942e0fd98bebbb5afce59b77540b4cf0921f99ffb9585d5efe83f9cdebc9dd3e7f6dd617d3f23514bcb79475a0f3fd76f917f3ab67ff6acef59433cf964bad583e3133e535114dcf7f73f6f56f9f7d6d5e5d0c9dfb6679b5b976476ac71fbefeeaec9bef9e7df3d537bf397b36977a65b8c300931b0204f16c78ee70f8f4d1e38b6f8b1987c3c772cbfee8f7cb9b7f3d7d3dcf5c5d6c972f9fdd2c6e96bfbebadc7c7d757579f5e14bee3e6573f1d78bd7c7078ee4a3fdb19bfd77e938a38ffebfdffeeedf7f7bb78f5edf6ebc16b2bdfdf09bcb9b3bbd441bdcdd03c757cca68deb5bc72e6ededd6dd3af7ff7877fffea0ffffadd1fbefef5dd963dfcc77f546af1f0e8213326e64f1b9a3b3d7568c6d3af9ffeee47bd9f93f26af9dfd4807b87ea9bfff9fbaf8fdb83e3c7c7fe38d6a7fbf55e50c3523fd19bf7ddf874b9b9c42dc75f7e5b61fd7e79f38c56a8ebcf699979bd7c3d23393e7e3ce4cfad1427c27490174b52b6997fe85b2eaef19ea3fbef2a07775e6fcc0f771e1ef8f0c58bcbed722e803f6ebdf559fb37fcf1306cff4172778b32fc72d4cb5439e7d5c5eb192b0d9477e849b78f8f01f97e7973e4ac53e97c7fc78993276f7bf66ef3e2727def8de3f4c95bff75793d5d5dbc511bebc9bb0f571c1ef0fb79f1feeed5addb8e8e8f8b553add1f3f5cbd5fffbf3c9a1aabcb8beb9bdf5ebee638cd93e46671c5f2f163201e190d983c3af062bd98feb4beb89ea7d1914070e75a6638be27153c7e6c5e5ebe7e78a3efa78dd2e835e6f3d5cd66fd0bb39f06d70791e3cea7fde24e69f8d7abe5d5c5cdf2e5e1dd5fdee9bacfef34ee18b1152f38f188cf3e3bf5607cd4fdad313fb25bdf7ff071cfde033b38920896efaef5f3eeced7fbbf115f78729e1e357d3c9786dee9f2f5b4b8397dcb7b6f790f304f25deab03edd1e6ded319f3ed74d2f0d127efbaf7dbf6eefb0b826a9b0bf3ffe847281bfca5f9e77fbeb8335f5448c3457fbcf88f3b13e11f6e715815b83efbccfcc3e7fbe1c19ffb3f78c12ff48adbadffecb3db9f737ce5eddef9ecb3dbdda557de9a554aeb8ec8c77d74e36e3fa96df65601919bab77b70b523c7e6cbea219ecd5e262fdf66ab6595c2d172f2da19bdeec35dde3db6ed3d8f7e7384dbe8746df2a8566a6c5cdb4329f2f15c0f2ee6c7f5f32bff5ec9903bc274b9f5a7c2a203f7e6cbe79f29b67e6d7bf39ffdafce699f9eaffffe677e6dfbefeedd77ff8ea9baffff5c8eaf26fcbd7bf992e5f1f4c2deef1fae2c5c3834640896791bdfffd5f6f019d1cdbcd46b3c7b33eff1b74bcefbf7df0c5703b3efaf6c1e2e6e6eadb075ffceddb07db8be55f7e75f9579ef5c69b949ac912be7df0c3a36f1f50fafdf6c1177f3c7ac49b05919a8e9ff192279e8a8f2e9a98928b932d2e5b492ed8e2ba95e6a2a92ed9109d98905db1cd34d35d302962d35d58b9b8b53dba3e890b367b1c4eb607174cafaeea5e8eae1bcf03b833eb5e2fae196f4a74c916ef9a11892e58090d574417ad78972d5a139cd828ae9ae6b20dcd1593a3f1a675977091e85e492e196f8bd85a9dd8d65db122f892945cc15764130a6ea9ae988487724f32b6d9bb6aa218e1678760a4787c3b1e1f926b161b13d1823c7e7b34dec68c4647d76c692ed8d85cb36cfdfe269bab6b76dce122f7ae717533bcafa361383859c7cf2e463010415c3021babeb62ebb32590c5472d516174d77a26d2b4e74b45cc5d0459b5dd31d11d79e073f799b4dc415de65c33ec5661592b838e163bdc156c415ddc94e8c373a68f8c3ce479f48f42e6e2506d7572e4ee2313ae2bb6b26b480af2cba63c437bdbf36b434a1f342f0f87c8e5809aeed36851d85d19faccb2661fab882fece46b8e75d398bbe985c5c31b12523092763f71839ec4f89f328e0f592d1527c3cffec9850addb101386adda109b0e40d83d8d3d9a24c9d5b3d0a2c901afebc9a49a5d36450cda99276f2560583117b816f0591888908cd4e89209a998900b0e3774a10471d1604830ec1230f59acea48a4dda3d0d12f135beb83279934ce2428b066fc6ec8f060f108309ddd82fc944fd4a5730290286b7a3933aded8f1d5dd89e1319cd5bd8c0561a4e990270c7ec5b20ee7a164f46e4b6bfcc9635371d11634d963c4047b05e7b2abe72175574d286dc2b5059b864d62337075d6bd6cbc15ac65bc29e09dd5c5f310135ec69b05873a7b02ad0cba17822bbb6f1ffcf0c37ffcf08b411687a562d04d77db2ff3ed83719c76a65b64f6ab695a5ed34d4fa2fc89d1db84156d42ceae9d271193243a196b1bc353703a62d515ef8a4daeaf05933080160a8811171e7640b124bb06a2da75af60ba7893408da14599da5cb58933c21797d73676ac80eee294310c25e22111b4b054176c4d632764ac5f9b308f3a2eac9878e5bc62ea4717a6c091ab209c022a28a6894b367917d635bb685bd657974105b13812c89807196eb67a9d4819f7649bb24bebd2f0d975eaae5910c890d032b095985db65836e87fc10798e6f1d9112d6ce8194c5773e89a58b8887270e53ca03126047426286606c7e2ba706262242dc1220bf833b8badb809d742b394da1911e668f590bdac63d6cce92ef18cc40ce50956ce66efc64f5265ea5a4897bdc78c393fb471d36bba752b1a0532ee0060d340e630fc20382675bc0b2cac50907b27273160b1650aba0491134963bb9b834a1ab749a601bbce0ca8c2d67d4d15326f21d7c592411ad602545576bbc6f65de5e6a2796e8ed0b4eaed5b7d797af6e7e96555a92ffa9ab34864099276cadac3175832dd9b56b2bc108667426439c6c379dbc9e974772e5a45c015d598d785c6f20eb80901a7195845c042c2982ab1d765db6ae5827d6e11df83f595002081224c53640a872c5662c4695d34cb5cdf575c7428bd1b509f735d330bb1b84a6eec105a38bbb0d641a3102c16112901cd20825241403218761695112c36a928c354d3149c0cf12f85fb3942f30178bab96e402621c442ad0a9e0333b022263f03c9dc078bb328530e49380c9461e1294ed04cc765f1c172664201088ee28fee162e57a10cd5c3f0bd99b9a4daa051cb3a0475283b8196b70b2db480eecef3259b04b95c84050ab8d0d6d0625b122194b2f597c5e3620525808957209da07e65f54b62a6b8872626b9a2cba055411b742d02c99df176d74982cdd1515c39241c313a80028594233b38a2af8de8ce6807606886be0f2905941b795d1839d83e9532ca200cbf9133d4846a994229a29e4fd9997448a9294f3207817cc387d373a2e40e0ac85eb1f8262c5d338c4104294fd3b4ca8f08125cf157b7ab1f3d4a965fee7b717a38ac76f5e4f97576fd479f4b32c7b48893f75d9e7ea523609a2fc841eb3586fe2a2adae709cf9db1d852608d83670ee802e63014a180b2390b979ca4654a02c87a0583c9393cc4ae87a38e93cb518964cb9311bc13a0221c7240353aaba7e8cae3cc887cdba601a270d44448e7934e49a148ea1a345b2484e8caa02a505754a549c2c852fb480e2ad936da82b91822fc7acce36a8bc283681f2645bb162a21be22c6e01472cfc30e84d160f6ec94a86900819315098a4a4c1650c1ad720f5b109f8de0c5123414aed5872c5a88009065ec9a029fc071bf85916adc7c0b8640afa1f8b9f8c37a1d5ec1e88d3ba089be117404248368092344beea68383859128279d87e86a06e3a688312ec2d014837dd015aaa70efd8b814a380ce5d57853c5812c8ac72fc72e5a12220e4dac143d1cb92e7a96b20a2655c4ca6ee0ee19e23d260405854a121d217381440b7b0392506473302bf517841233b192bc654769c9750a386054f8da3c8839540b9067924fd0a9c0d9b502fb895b8c5199c84f3cd808680204011b209b28b5860c8991075503332361e4d34c3251c08a208c2ab3c0f839d03d522e6e3965059a37e855cb8eb43c346588e05259551a104a50cc48dd96448f027224afa00c43ce08fdbb9278d6f178d1eeef6c3644584bd5ba81236623d4b12a4794ccb84547b6892ef726468a706461923943030d0b601b9142a1d444dd2553608a9c6c81d3d652fb87a48ca5bb80661a8d6e29b1522f0f103bc10f53a2d10543085930633608a5cfcaef4d064b86cc1813acd324816fc3d564e2a11a2ada5c311c87084196fd47a1bc2f6276b519dd6a1ba2f221365d68140885efca683aa7675d602614a35bbd0d8a9ef1f77384d3c4fd2487387de9098ef1f267d2dc7af9a9cc21a466a01be5355403d39b6b4f3083847f5bfcbd7b8ae7875c2878d32c436e1e52830884df67dec41e540dc8582838cf33a65df315f31df8b7db90db60a8a184370a64d9f0588ccdd51548f71a1a0ca4d4ba92d25ce1df867f47ff0156fef2a4c8fef2949cfef2f2c5f26719902ce127736bf645492ba9def56d6ce97c3e84a52addf82721bbc233d28b9e798a6e0fd002cf6321eb4c6d656b5c930c4038c29f0dfd3d5f787f075ebe589eecc2cb17cb539db85d5e5d2fd69f5a3f426c86dafb243457cf32a61684e358394b0bfb164ac49937a9260a29cda4463db66267957274692263f02680085241c14ee8ae3e2fc185c9ab004ece0262cfd39c9f4fa536da80bc8b934a1a01574090b70df26852536852de0ecedc6904cd9662fb5eb9d00381623b4d26592dc64dc56b481699fc9c72151e9644ad5dc934aa3064902193b23793283f417b8b90b0323816f7d44c0d0d8372349e941b9b14a17a3523647d695072aa229e92753245556e4a1536154a95900a70193875039f07adb6859fa2fb54492876a249d0449289346727aafc942c5205a7a21682fe8d6086895a8b89145f05ec300ce3a18ce781ac70503a851eb262511b9d584a2aa1427d0cad509409d3300c935491e755f2aafe240797267c0fed80b4e7369ea5bc8526d25605c1b8ab7141742752684a261468c3f8b6d941a0e20199305814185e777db7812a139377791bba4c1e1cddaa22db2dcd8c519971821a8d4965aa4aa0e0c585fcb8517b6d36e975f461507b574db5911f431aa15c9ba9700bc4a3645d8578262a088987460f068fafcb34fed276c2b745b4d156c10ac088626ca8dd15fd55f915fa7f329d92084db0ea1f28b4feca3051454bf5d289eee5dd06643f9b80ee9b86a40b1da582c5702a744f5191e315e95fc09a8086432580121305c2044184e620c8464de87c19ca0485340a652dd14d20947665b7b1a1d33192f17e15d8a38d9881f88126840e9e07beb28f20a334c8ab34f04192eb2675aee16e6a546dbb1a6a04a6aabe62748641884b26523b677383a51a9cc17def25d34a774f526a3d758258bf7a75b1be58dc2c6f56cbcd27c7fa24d31e1fab4b67e2a9047a909f44b92e61e149329182a9642a826a836826446f32e8299e211345cfcaa5cf3526425f5cc2b486a286b520a02e14eac5742e444f35a26202465ac77275f12c51808e9e5a8f74134be510179a562364e690d91e9bf05a2a72a9dbcaa58c295e402e7a18dec066a5242ea3e16f6c187110b5a42de926f8aa3b92d1a541756bf558723f4062271bc9b41f514bb021df3b596e8dfba92973eb821313e7e2eac5eb179f9adb218464628d4e02c6c08564a3b8523192bed9dc5d8a36650b71b6917366db1a394411ec75efbc2ac62963d10665d1dde4605336bc6fb791d89c642ce110279b02ee91e6a2e0c10574d235b062acf5ec5d025324958edef96a5271223678b28e96b99793ebc178505f29b8220be64b6846bc8744e77ae41ca5be17a229c1c58e199e22e4e40c2d3b47b04a9f6df12e67ba043a9f980d9f6fb3079d8998f12298971ebc1214499cefcaec62470b209ed7604314272a8eb76a431207613ebb9aad7e4bc82e17e5d298b36d30ece0226424b51167d713e4ab58714da3cba27a578269ddc56ca45647993fb996685e465ba2930a55cfd332554d1517ba8dd57931ad3808bfa95ab29e70169a77a1823ca39b300122a43b4e8730d9945d46ef62dd55a3530214be981a5ced6711e36aa2d4e1b0e826a6cabe861cd45d834e198249d0da9349cdd544d110dd542276a720ae8a0a9205fa3ce6840417ab2d50747373a59912a1a582a78462785cafd1fd82573b9fb52b388cada0938a70ee48771e9252eb5ce074c3ef77bbcbf7b3062ed653ab9c274eaceef5f797eb8bc5a7b7bc49175b7065b260a558311456219d718f1b4f3ecba3e670149b6b5ae5f62778cf44ff5fb4491f76d8ec3605126d2eb489d325ee1ded868d367332fc4883477c1e3c241fca191461ab19d65243e9470c7d0af48e145153a7d0224a03a67ae85cdd3d8d589c5053f0c2b3a04c056cb4a98dc4bbfe3c054882713c1c4bcfb079b93f89ad4f3cc13b86e5837bd83ceff4e76104f0b844861783995f0a41c7d35c975cc5e7804bb6d9b848d73736ab94d53d4b99959e497cca7ccd56b23ae5d4ce6e282619da9b02a5f604e22c74fa80947247c04e293a56de484b4da6a445c30d84d1a6f742ce0445da6db08a41f1d79d86d03055355ea3199d3b9488fdbaba6aaaab138d92f867a2852001ddc3246d1964fc11360319104c804e030d2aa0ed0a32a050be1fa30c5522db645c5cd3888e77586d44e62f64407c567569b79140f7724aae4db6d23143d925d3f5a2620cb6d78703e6e8f05469a8e2e1bc3f37b6de14da55d97f877b74ff5ec2a0ebfc1465d033a748c3c51be6a47f529421d60a9a1cc393ea5d2867515c125d38256217da4670a16ca307b739e3db5cee46af0431e79d54f4f59a2936b20d746c2d90247cd38b6c819699b2eb0533b904ca93998eb288290491ac359712d8b2673c5827cb91641a34ad46f62710497337def6e82a4413f0e2ea7c826215abe56d60888229d99a85be427e1f74170a091661554eea5d80d25ec1ffa0fc6b8c5524b3eea41559db78bcbfb2529b0b5bba39573d38dfb6f8da909eb4e642db62127b5989ef2ea5e71dcc7d95bdeb610be9268c135b5ef524e0dbe296f7af5a73b55e5316164835853c2b6692b1308124c661d7f51e5f09f92599d13f39b89a9eebb89da5545da32f225793a440f001e59a077ef73455c84b3104d7f3e43aa466c810da29191d8c91ec71ec678e8c373db84c72539a7a7f2bd54a86d345c601359299663955ac7eedf8a3d093e6adf63fc495626b739191761f60c85c4427971d4e9c58759bc5eef2f5ef7fa685f777841050ff023708ea25a0164ec331b91fe724c86819ee3aeab5a2ee99bac83dbb0675873f5e0df181ba7071d114e86a32ffe8e912e9b077cd141f5d8cf38f9eed190d9848a3f126da65a050d12de7da02579762c6cf782303f452706d0a8c310c745006861fe2afc1934c37dda461735954508ce13ae8ae40b29ed4c712c40964cda096abce6097eafa22d5e8a298f1a3b7d6ac06a262124eed8fe7a86625c3403b6ef83674aa8b4fa26f8b1367ac8b74eed101eb82d5f8d26a5d5aa4401716b7e3155efd4b5f811426a35b9e3252201df8454aecdcf133fc248c78689582109da2915290da38eaeea9d4604a76b2b6c94557160d8bdde8565b1adb082ca108ecaa1d8e7ffab9321a0ba58b1b7d27cd5669a28d0b9f43971f8d300d5fc907d868cbf05d17575656c4e5d9d74753815e6d40eb82ef2e424481366d20fb180c97419777fecba6e2b824276a19e0a5b415274c6d936d36981fd8e011366e413812640cca05d5a80f2fd04a2a159bc4004a95939a2934ac25432f33676b0111cee017cdc6c4b0175a9468636e6a5e8d204dc306ccf969e33006428e6db4010818149dd6912175b820ce911e0caecd16d396be441be8b264976a1cac75b27b2a0c16155f1711fa19376376a8a77292e8aa653066d338906c3837e894e7b7b2ef30a834de30b42333b494d6d1ca9e0e585aec98a84641487aea064f94b86d19cb005f44b36562c41d5e9bad24ebd4c4680bf443b5c12dc827b819b376b459ddae74806af05a0a2e5c630c9bfe21bb0d3d9fd08ffbb41f5f4a7b2e2d04aaeae809af81b209339986504a5d26aa31b89bac466ebae9b346b7d29f5b19a610d9cf4685b74e6f31d7bb863bd3229c666322e35eecf00f644bb76e609bc8e887e3b8d2a29d0ca690e082c2194bcbbe865054be822487a1331a1c95185111952a97e1385854a8e3dc8c3588898c35c859c265a506da85344fc380fe8c254e3630a9615d27e36c9b35c364dd297987a806fc4837b4fa2c92ab86d2ac2e8e4097aed25623c974c6aad3196018314f6f41d198ea465b6ad4fe4f6ad4603731540c3d802524cda54505a3e6669ed7058ad84462d48c462825a3ae03c3a3c268a5ac64ca30cec925edceaec199d1f8052d1969ee3a4ff7406268310de26ed0414e2d0701cb834a9ae647e78dfe99e89fa0a77f642860656b1c0b3484c4a96c8bc631570d9db024a3c1aa33a2a9a59ac6c1caad307462b7892a296275470cc981be43aee4c0050da6a0bf1def8eec0dd58daac670250d2d21975d040f1159b7e35941d72364350ca11250ce2601914a53e0a860fee142ce46c88b655184dc5df60d1b090a2e4ccd250dc9c0fc8e266410278c1e83c9a0dd31509151864603e73b238625b9788d89dc19d643eabedb84dcb14a30fd262b960e01661ba845352e20ca07a3dbb1ee35ca40527531cc3f63e277a5f813e3ffd40a50b98ea34df4289585300e47b7e32ea76134d989e866cc846cd2c48fcbfa69a49e20296da191c087d914e83399aa0682c8509e4131a28a6273584e503187eebe68b1d4c59564743b968206f5d589b4828e099dee548f3d5d7e8dc4466364e89da108a83ccd8ac782a51fa6812bc84235ebea660a219865fc2cf009157612074c16a204e5404f8c8e7da6cdbecbfc338b8c8e7c324d1a6359946c440df2257dcc99b18ada75c9568e0c9d807d6b19fcfb34f5c8e482fe67cccc982182e50c85a55af1d585c9828c5706c390ac1535b5a32fb19095bbeae449fcad1ae84a5f80fa6abbd5e8d131e4f4e1820c2ee8d348ea24e33791a2c99f49146bc04cc9a43029bb3c8d502913f64194a21e55a658d0d524d98e809a68a36144da980159c3bce202dc2e1add8ef54a92a9921983aeb2e567405aa00926589d1091beefe4da9f2dedcbcac226d2c56c82512adc5c5f886fb421ebcf2c7183ef434c2709f72a919838b22cd242220dabe367c8f69ac291fe1c330df7dd55a3d1f5b5bbb208502f8d6ee72e2c9069260a8dcd92af24743b7fcb189b4833a28004f845759981428370dbca38aac079ba5f3d74c117f4ff1a421a6df4ec3053e7fe4924c20c880b2abc8ad5783f4b0778ba57339c15bd53cae17cee3efdf053b3ca845c49a140476c6ac3b2278586429227dd657403443ffe15354f2b31702d6b165e514d92091264ee59431353716d9d0b0d5fcf6212131aedb4d82be2d273c6fd9de1efd64da4704dc7001a43caed75a727d32ab6128b8beb1ae97469139dc64c0fc9896ebc5b7bcc658128c749dfd5439c19a9bcdb78d3f004b0750ded504342000d0c9035f1933dc439289838c524ba6df2aeec36120b35d33c712689b7d59b52199c974da9cf2213c93c13091947da278636f36a1228da4f9b8b678df9555cf8c14793f8776c4c55f4e018d9c6393a3e70054bd86da2869606664c32f3c64ad1ac1666ed45aa0c14e2fa885f2c7c52bba6ef2b158d5304f5d5ac4be6a555c6d5a7466aa97e5870fe40499e222de5dbc0c8fbaca1a5230246c310c0271838900a031c231729f5b33a622941483fbcc4ee5d5fa716d7c5a7e80c499e36fbc91651613c8e28876e85f32c67cdac80d8caf093ae5601289fa4f2438ea58a96c6faea4ad9f42f499a6bc4a864cdd6a33ec9e4bb8e114d9c6d99d61f124b0da7a23b22b4e17b30353ad942ef3dc3f40b81e678e8e221d32e5819104326164c687e446b9898eb1c7b1b6bb956cee5135de3d020d394e64493a8e1e868ccb0e6c836a81f82ac1e6a3f3fa06b8718d164d86028fd85eb42c38a29cc4fa913838c0d33d4b493d083cfa5b4893a32a40ba696492c567ac0ef6ec36c8798daa4b1568ca526dd630048ed9a659b6c0ef40ad02f13a9d0d1dec8c0732662a2fd954e655c4b7d27aa5a5db3063d25238c2fc1edf7cff48b7bacfb3c7162a6bf7e797579f1f3242ce4fa93635253f02ee747d18beb7111d2a3901ef947f2481e8564f54f1ef18f44ffdcd850b29347fe475d1c46304e72a93d4ad5f5645b5c887f24bcea9167b41d84c0955f633c737ad492f3758116056d58c87ca6b70164af3cf2e722c5497b54924bf9fda73de2d3f8b6472d9e95e4727c147c70213c6a0e0d6b10731ef947b1a527b996c9e2b0ed8d86fbe472b2d2c4d566055c108bb2b89cef9b0a3ab2a7e6829e393519be5fae09ebf089513e3ae74da0979129b87478266a1d0192a5eee611e73ea2832ab3ba18e23ef612932018ea05da596d67a85b894ece4202f54b46bada67840e373fd9286a35d24c4b3c86b1f6a2b1f57904bcd3edd6e8f280fc434d21e81216b2bfe0f587a915688f8677e85e56076e1ba6488ddbd470bdc828206f331dc64903a205aa5b3d4bc5a49847ae1db3834c10cf18e93089a8b316526c6b74910a135c8266c0c69161df028351e891da3d8d4c7110dfa6a4b911b36d9bd6a6b1d7b487bceb461344687352d7303dbc8504bb588e9ba406b1d91613c997f81e61f22e3e7ef223f63369b66c5557006e5d473548327e9606b111b4592d55bda422ba575b6963d807c370ead84d0c5e97e44d4869623001442a3005666eb0799e619da4f86432e399eabb008b4177d511fc38369d163d95bca8f08b261c26eeed36e0c7d1482b8cfc555fbb2d453fb9d0a5547537770d2af56564ce3040b363c8a21a7c1954339018a29a49cb403660bbf1a6026ecdbd3ad2866842aa0c211699778a2e90a04a61e654c2861921d5e806ccb861d631f2977b8c4a64780f4828585eb329500e23ca82b6a65a2adbc300dc359091794d0c81a8b47331ab45735bf8dd75f4f6f876ec654f0d2d349d7ed4e5e952adb6f2532ccd0a958963940099f7c1d5c20fb08d028e55bb849ac05493e76ca6c4c43dca2560c118eea4bf4c1b36de16b77fb20c233385a138d25ca3694375e1f82a044051861f07ea47c4bd892936bda9877ea2e8aea006d5684cae61a8b4c61e40d6b114beb898c2b0ef17cd7c6fb68f608a7b458099889fa4fce3dc49da7ff58e88928afffa49f91c716b88cd85b5e6773127295103893668d7130b23cc1960e30a7a63d418ecf59ac460f3c8190d62a65615b52761c8ce73a89a76bbb6ccfd620e70631e6d530357d0b0e5da8731dab6e092e94a4fc3ee69222788555c5e072e3bd7ce536926a4eeca9ab01966d8799b91e0774fa5604935276bda486d2c76a4d8119a238c6cd74a523259c174b331a8394f413ab26b670cd38e9d090826d66a40b599054fb8025a878a63805a03f1cbb60cedbad231c71cb7800ecca206f4b626fc89578c986e83cb9386cf6b46aeea6229a835b0ae837a6646c4ab82dc708dd21ba5096e6430d01ae82c0d73f0d4d135e8b2ce901e5c13c73524b0cde4ccc1a06384dec8f3583d9306fa9a8433abf3210e6f5c1fd6d80cea8e91277c8d264b62ed7561ac94513351543ec360a4a026341afd68c3af5cc929696871586bb0153831658ae8d1accae1f0d194cc98e13659a1bd535d2142dd9b97336a9db1ff844989411d6b75f8cb839a7583ba31e9fc227a515f43343d4c88b6dbe4a2cc887045c37d40af1c4743adf26bede6e6f2442c24cc6da6a4a0639b5a5165b72127abdeb535d4ffe2273b7c018c5d9fa926594259134e2046863a45e65be7b5e5405685ad69463342a266b130d5d033d71c2b21298b63965ea1f9be29250d63ed818554e646326db2d30ca7c80f3e68868667b3d44880b79ac2806bccedb2f718426a637eed3428791ea21c6ec60d905468dda16f14f2182933434768af8c6b46fe535fe6849d4833b413c104a2c217d5b5a6008b3a3f8266a68eac05cc591571225356c1da0bf4e2a45939141007755017d29890cda638899a760954457012c68e977560207c234cd1bcc4bae6f7379b0cb181f64fe5570c3f7925c803f910072f77821169f686a81045961c2d2d0bb163ce27f5a785cc1514e97d8f6a1b872e1d408fb89a769b508ba27bc8c4e41b5df863ca09fd9b515d822e996a356793d9e66ac9a51fb18d2840fa8939a3d58c5fc81b398c58896a7e68bba7914c3d489a32d3893ba93b0187183a51d9b7d50eb429d17c147564108cc5f0e16da402251769f40dea7952af5cc7a4917d46b670be06cd41d584664dc02903f7407df503834099bae8e40085615e2ebda4205cc368530d1d6341e562193601354877756a10c3c40c521819ca2994cec37aa68dc300a70a11ededf7a74d1e4b00a78587c3f99302c4dbf5e2ea53531d4511724a73b2aa855c1d23d03977416db0b77b1ad061268673a2c51497d6111323543ade6b319dd11cb558ee4426455506bfc4ac29086d055daeac47644276e98966adea7ae201e83ee7faae261f30e3685f9e1e049c39d1fd6fde3cbbb9bc5afee6f2fa531b82e4bd89e1496a6741d41aef4156335407bf8d394c444ee2f2cc2635fd7f85133cec4da2fd19e76c6acf9bd78cb381cfc5833641cf83e8d612881bb389e929a288c5d11aaeb2ae4ea281ce52693fd74cc0b542ac2510f732b4c1401239f20ca9729def5fa38921dde6e8fa13c28051bbf2b66313fc357e0d775759d685f23df502e8585460d9523689e44018cca0ad31a3a10c97211b993f613d02cbe96ea392338da71819e06c5480a21d8f19067e8d65e61b787a0d59a969f0e5aa80780582d59828439e03c7a926f9dda633766665435f139c2d46d7a7d1cb0c791a1109fa643b5eaa5fc44f1bcd51c41ba61266b0820eadad26cd4a54dc9dd0e94acd8d498accb5a2eec5b6c411a05fd5ce2c3eac7298e83d0fde74c30ea7868655ae9d6fc2fd49fe8765736ab51dcedebfe23eb51cba9095e779d7d75d7dd115ac90b821443dd1deac039285e9670aac32b458623554d7d7b6a90f465c5e81c74fb40d783ad4e88ca60bdbbbf684696d1afbc32540a015d11d02e1793d371f34fb33ab1cd645f964d643946364b2a3cd2afd078adf59654f8d142aea6c0d3ae73a4ecf2b03627aa5195e1a55aa6222d75ae1bd32f268650ed4c8763c52ed75eca5f96da00a8cfa0e136355e83ed1403a0a624c1528bb0d887db7455c5de5088947e334f9b57d588774e335b9a0ef4d46f3192c2f97d7aaf8808e8d06abe8112817e8d0d8316ada31414906c773b8179865a1810c607595b427aaf35cfd09aa0f31c4a0826169ba325a42c48d64e88a51642d3ff005da994837cd34a3bf21976b913dacc3fccf8e6336a4f62cf6a8579a06eda2e0c4e409485a6da7c1448ae509c12c68b4be601f27ed7cd28f53f3c1fd5de30efc6de6c7e1dfc796fc07d6fbc9c5befc79649bbfc32c7240679b380dbc099a0bab8029c995956b5b8ac86a6465f2ffb08ad5c13ae6353be27f288ad220d29e24d72635616bd60bb138b3c2bfa6338d6fed748367233d2859961e260670d1f69b152557e81d2420685244af44feb2adc5c527d8ac45551159592efda80190b4b47091a8c7dd2bca021a9c464ebfe85eac4a7ab2ea5bb40f3785c38d4c1d62b25f6a0a11272326c5c6e13f55b37c1fc67a11cde429638f37688867d41fe82856bda61a66a9123acdc6c1f5dda68213f7e4fa0a0ad89a417638bd726dea8ad1cbc0a9ae16e638d021ba066279063199a8ac585db9cda8615d636593ee2545718cde6a96b4e635e54094051526181dc58e62beb1e2a02a4d0e5dd18988b0471fffcabab6addec52712ebd64ae9bb0d0129895fe915c54255616d70d53dd1b06b85ced49f30d66553b8a8a8a24c18b3b3e8572a3c52d19dd041b915c0d3bbfa69f55cfcb13db7626ee6ffa5be631cb96b9357f8b1a8ea5fd3259132bba2d901d4a9516d0cd61b7b74539b3cc28d9bee61b38540b5021f891354e7a0d974d4dfdb1ce095b4999a88a37b32f096abae3575a063515497b78121f97d0ef46ba3eb19bfa7a26b53e64d4b16c1a5d4a6c5f021acfbc2fecc7ec6a8d390df3cd03d4497322f68bb4d2d4aeeca64d52a6b9d023af0a7a92f5e8f90e72b0148ba19ce0a3171880fcc77a0d61e3951779b9c35492cee276ea31173e5ea347013759232c75cdd7bdc3b24568a823047ca0cd1e481a05c14a62219856c61a81b04b16c18da8a299727fd26fd000c361a4c914a6dcab4e388027f91e0d3a83b5c946a09c2b729121fe7cbb6b415d3b79e4b0f1f404b056f3ccd4d97a735d5f5f2534c6c12c55b681a809555b91a916bdd6aac0dc173a93c126c90d1e707ccbb3ae05f142591c09532bbdd864937a98b2ad1dfa0c6d3b651072a034ed5d564e967eaae1343983b4dc98ed001c434a7410bbb829c68e2955a14a91c4ba345834cbf9be635d88b7e46f5da0e346d6a9571a0c80f5b98aec64cb3331d2b4de1d854cd1af49491904d03c4b3d5690b5e3922868ad24b4da14d1aed3f0225099134c04bdbde7fcb18181e0f23ffa393920e53ad57b4beac48dd31281625ed9e419c6cc45338282e6c45f9ae77714b2bf08a991d5141e14b56a09aa87b8511e204d02f04dbc7a115b118761b8a1a21bbbc8ac9f569a45225211cbbfec6e6cab59581c79718deda1c164e72edb9940ccd8046e0ea5d9f04d4301685dd348ae08fc6bab2c5aa5f85b6b59dcca2290a65b6a968e891e81ee1f4bc552daf4121298a955d56184ae6e5097d5449835c43535ac6cbb3e23477337b14884abf0531582ba720e20e81af21e2e4a46ecdac7b495cd6aa09613830836144560abb4d53c05c99f68ee6c2c8eba63ba4e44a63d5744f1fcb40d3cc0af6169c6c4526af4e00b559d275c2a514761bf10cbb4dae4c4143fc539c85d89c07def639c880749045fd2e8d91c8e060ae9c674d6be079c1dfb99a88015ed3f8df0836a049e16a8cd6d8f23024d04873b5b744a704910027632cba6b4ab73541a5b8fa0192491a789a6af2d43d84f3938396a5f6154a7375b2035458733a58b72233dca629b03e91875355981c664757ad614110f4e09aad495db5d53260957b9215af9d13884076ba775648cf12d570238d1e146281e43f7b753b91653681e64eb58866a3ce509dcab80fc5440b9ccf9619992addd73c6774d10cec19a8a24e4b4519a61301eb4a81a8936d9afaca1806c6c296acf5152a4d02b6fbf12b500eb0660b5180c21486552c69ba0b633b43b2954434693286cd61746a55d3401fe1b15d2d9bb3ef08f3bcca1cb041ff505788b8d2d5edf8212ebebe47275e9f5288af6e58d3ff678a41ff7bec5f4c114feb144126e257595c240276cc735e81e7e8f95568d9a5b525dc16c76ef7347b3a12b33f8fa41ab98f4734a3db9179d319f81956ccfa5f870c269ae83f678878f5ccd9e81a8d2023bc86d696ddd3503381abf29a462f02029da7a4c7ee1d9f7d879f1aa4fdc9132375fd6eb359de5c5dfce9538bf2cc9cc3d1771726e59e8c2316dbf8ab60e910d30b63954802942f14eec77c166ad504db443b9098aab514847213568de00cd4f2ce90800aedaa81c7d5a44a18e43b45193621cca01f6799f5583ad98a021ff66c5287ec137aa7a4364bee3604f58bc7ccecd573052513cf1c35bacd636bae4ff88ea2d8bb151c9508f68a0b9c4543ae9b1af4082b9f083ddc8735cf040d15362c6d10206e9699c0e49945096de4d461a5887e74d728274a01144f549410ed876e15544254e9e0a34a236ce45ac54ac55ff542773f836ad4da249a90e1713918775d6b1989589dac0424fd3c266f1204ce89325b5637392912932a28cbd575822853c5b5273985f35454b89c2b5930c4202bf765186764c8839586d5d6203ad8c0621b8c21ab264706dd69d41cc5a7aa61ddf49cbbb4c6c7742bc45ca3955842a4e44d54be512822aa63872837f7fb4cf76bebd4a2dc9f3cb1286fd68bebeb8bc527473d25d3a01c8be25d12337f305e4c3bcd576ee74c87c2fc65788827b47310cd28d1bd95d43c65475599685a2a91b691aaab10fdea62ef14708588d39504326989204892a3ec8fde9b0902584cc15aa43836727335d431e9eb9b4b4f52af13930bbc0ac932fcfc0cd0ac9ad249cd2631a32c242a4f4d7351a2c617683520af988e1fc2cb9d07f3d42498cf9d98036f5f5ebcf89924babf33d84e7a777d9bd3da46bacffcb93721a7adcd693d8e9848df9a27582614ae6c6a58a7e15c489365727aa620e5bdd64c2b566a98772bcb62d0acab95286a50829556d46218cd37a272330698112b4dfd859c6420a44a1a951b170d82a0f1096337c920360c23536203ea97742faab99025360805deca88815b339e3c347c46f08af6dbad9a77408f3b63732851358d0e8e5af529e15432a9ef58800e3ab3d0e0cc3438cf286a72304a9189fcaf04276bac1c5037c6daa5b3ac364ed2bec445c7ef8cd4e2b22e0caff8591aaf9e230b0e909b45f51a8dca68815162b4222648a4907236a9a827f5de19ad53f3d47cd633a766f3cde51b964cfff41c2591c32b650dae48c9af5697d7e0f9b6894b2b88ecf93c799095c293e7f33dbb0d4d0f26821dafb50215c668252eaf1547997f120a72c7d5933c243b4fc4a0f3549481b535f5dd5c5c3e1f17e1d12c1f91eab97806918032e1769aa18892afb3bc7c2081f4a8e34f0ed8e1f48951db5e2c5e2f7f9eea8d7f0f7477d6606b28e861daaf32a20acb28fb4394ae736a7fe25d3c53b8ddd486d195085f8c1120c09750c4ecc643811be15a8d616bddd535e1d7a26f2e4f95f90b4afb1560ad8e3da86d8de95e8c9d8861c4450e2f9a9f344452d439a0e07914b34275a2a1928599e4c37f54556629627320f3d9c32e1369a2e15365eaa362e45e3a2c58b90a1673aec975cdf5350b2f2aa8beeada6ae36128c57928b8bdbab656b09b3ca945b8a9afb0a9fa79d8ab233d3b2856cc40e2a0e7ddcce5168bfa598286ab4635760f1866cd9cd05cfc0c724a021e4dd7fc8ad9065d5dbf7752ebbc3c359ff5cce9a97c73f9a9911eb5328416a9ed754c88f624168df436fccbaf0b5d3151141234303989286d2e804664dbe7d07016f8cc2b8dc4a47f027fef362cd543fb435adbc3e356e023e066627a513f4f2f2ba9bc46f43df4513114f3b980ce3c0955b684945b7130779be0154624bbb2e5964d8bcfa554d757843bde52a65ff5ce4b5ce651517218c88b473abf8680363bac880ced344de19a46bce5d0a68a198e5795c0448dc7c136ad9742ae0761232bbecdf5806307b7cbfa82c98ec8512df61946f6070bc1da32c052a21e50050efc40c12989d2381e7fcdc4642d29a547265e69868d72348c4d2cb618891473c3c83ce946bf727ea699db77add169036c1f0f9f9a029b689a6e53142ac5ba31450194b44be65ee2e503df67f4081f06990c0bd14f9e5157aad712707f58308bd5c298f401d6d119cc7de76440f7a8ec5f34695b51fb83963a23b43c8863ba5617fdf0de379326aba02cf46f1433103382d6e04b5af24b877bb8a04423fcf5d2a82ec351d2858e7e528e6171df1f1dd79b018451cdfe5166bc035a499be152e86019ed1ade5f05e44ad774288a1be0ed691a5f49032ea9d4be03cce8191d766ff65d66466f2accd1be048da7384a18f95e5cdde29275a357c9b3b41e3f354d1afcb7afcba468259ad9a28582f9749667a1e796251c0938e3ad16ab2226c1c024695a292264455aaa87bdb55e515c5c85e8208f90fe90469cab5e253928f93047e463502ddc54ce63ca2694766d6969286e28e68a823ee3f713224140b2b4da243a5f9d453269a94f8e93164fd23a5465543202f309e75a37a383ca350df3db32932ebbbd5c5b46e15f0d7c2973105b50f7fed88c220b5a5649cf6af956cfd99c34c0639464c6a3b636bbb66e98627d3be233abd1c21c9c41b68fe08fe397fae1dbd3bda397c6d190b90a6019d125761454922d2ba106c5ea0a5b74e30a5ff93c16bfcaae6f896c97b7dc12b98681c6bc22c4355d5a89f58e45f301a58fa20afabb56c03116e3235810dbbe4a5039c4e65576610d5ac323760441687146167428ae5eab7f8e196b5cec7c2b3e04cd0d3fb2b95b9d822c198c2f2554d8cfddb7d9258ea5c558b6ffbee9639d26f80e2f6e52c8450923081f74a1418ddc33687360dd14ffd6e453ead21c00657ae243f2d0cde53de2d0cde50969e82f3f4f1cf8df230a35ef9298e0a3f332595759f1b90c69128a69234d65ce90cf8be6a4d00a3463543145a3b8004aa68eba5e16b899d3645fd62b1348c8f5305997a2753e806a8262b6c8f01db5e7c8a236577c33e3476f2ec115c677a64c376668aeedeb6106b53730e52e10378d953e0371b57cc1cd9e50f73de216cfd22cce9355171799d9dc39d52b01ad4b9808d91f8a4b0c32a99657d8945c63e26f07494fce2b769a55ff66d3a024b144b28b2e3602aa05d7c8a86ad6dd4a1864ac0ae2c525d6694b9abf9bd17e428d67d7b4c8613625e3bc34276d518b6bb99af1a3106139bba2710a0a8bdcf2fc3320c4aa2bb43e47d01d2fd0d042df3ded91e0bc8c77877e11ad4b5a1541fdd29535f715e68eb50bb9383d3ec3333a0ab306bb5a31d8956a838bf435672a384c20cb20008dda93b0003231231bbeb5d0984ed46017c0ed03a5b1ca646fa14ec974afcee4b2c46041829786e83ca3415a7195925226de17ddc285c6c158d78ac22925b99227eb3a9a57997ec3c9c8fc3316356c8b84d99566705b080a8d556ff384c9e53c8bcd46adfb1e9821812739d6ac700514c9133b316b59ccba8e19eb4892778d511ce852fe311106da05c83c9df64fafa20fe9a5b2f632052760d67cbc88558aa8eb100f8f8ea808c195789e8277bd99e6c1c439998475283588ac9aa31e594977354c18187c4dc180b8069136b0127cc3c2c47a248e9f66731568c1351b295df1d5b2c92e63cd378a78bedba3a6ad1805d2e985e984b621ffce44e63d1a9d9acf6368989682bfd6f410342d62d721b040dec2a35d650afbd14b6ae64be28e7021890c8222486b588f316250353223f28da12fd0bf5e53377d98f17eb194f168d96a8b2608d62993e3156ae92de2b1d4ad7d3289a5240a5e599d688884e67cc50272595d266244ad6a21e5d44caca811d10f7821810e3be95c63b7d35ea0f5f2591f4a837f1944c4e250126da0fcc97251033503dc9e64a876cb656df17768583f216345e6825950884f9eb3eb3a7f2a577f226477c20cc8d96516752f44e5e5caeed8100a2f935a9bea7cda92b04d1ed2215a52c0f28bae6cddabae8ac5aa09e222adbb52b100454b9f665b40b0d1d6d85deba0a0b1918224ac4c4e3c300e26b00ab67e063e282c04025a4c8541011a14d04a13fe18b397994523692cd1110940312c138189aa91a7232c755b082219f93da0878c9b4a61b7d162431ed464b2d5636167d660219a3c3d7f01d2757369fcf1552a182e904efd1d28995cfaa08dac749a753259cc0f89f8d28a2eea2ed5458995c547f4475dd9510ae84b4bf8be123d48c6f819beee444697bacb99f02bcdd234542b8b5761c4b4f86adb6d58b18671c67db2e8e6413373778150b844b46fe06a051a65ed682611783266a260aa75b207ef7c651414943bac3aab867de84c0a1911b1146825c54a00b7cda026e4050c74eba0bf15ea60a3a016aad120d1aab20401fb83601843c56c2aec6c69ac99e39dbfdff1f79793f9427f399127f4abc5eb97d362f3e653acfbd9ce44c4289ed628ddf9f17c8e96e7c29ebb0d4b72c550682c6a724ec79191da56d264cd101f22e9dceb3b9b7be7446fcea74e75e9cdcd7af9dbe5cf0354f4f7d8ad4131c484a0b25d71adb2d010c81fe431860b76a6e82bc74cac351f21ac7926a1930db6cc2a4d8c38aa2c7f9f893d21624b04458fc54556ee8b2afe0964dbc1c9ba7149ab58110d96c68f4c3b55a3033d15ab85d4bca74cc560e9c0b4ed1cb436628f642e91f6864e635bd7a0d38606b44281b859e8e6f12c648a024a13a3823e82a662ed3617c2ca5288822a087527134d0e822231ac188a27ea7d9706ea151211e81b2b506543e02d5b211fa1db14059daee8c2bc765a207a5c418ca1bbae14e8868d91cb4ce00c8c1f6c5a4f8ab51a049d562190d46c3b397fd0327d019d07b91ffc28d0ec578be9ec47eb623304cfc133590b2a17ddcfdc100a06328c17482da110150404ad4605c98de49d85bc345517c5f44aedbc31d7b2b1e4264b84178a4089bdaadc738847e065105e832275a08b8b0990962a45f448d05b02f728de4db2941820948c7285e835484abe304e2e19b6043a6a36290d12588ad18a269db5d13c2732479aa499c07f4913042a78c72276f049dd2ae768687175be4fd9d17a1784e21f266d3dec29ce596191317411f4a89c6c07ab21970d5668bd2e74b84212a8583960a7e8174af91ab009c6c30c5efcc1021e85f1c985158d1acdab14d912cb87c680b95efa6ec378844cae11c284a9cf94a22a047f60e05dadaa17da1e304103b402e219540e13197e6ed065bc166e64ad759a127ad4940b4a5b15bdcf88ebddd3c0a0f3d82a8459569d294e0b49660dcca7c8c165990878ae01da9a0731a2fca83d43c3a53f8989b844886a7c752d433d217849809c0cda923580a983272b6895223db0804d649298cf8b8ad99ebb997f8740105c65a4759f223f96618a8ce2c92cacd6d1eb595cc717d6cebee9b4bf644d3401cd19e8e604102d2e25026440140c5a1d8dd8bf95056002793f8bfa502860487e499c279cd8212f2aae6e66fc8cf99741555bfab3b04e8b644c73c881c4c010992827a21704138e966ab430b0e8b4295e410059dcae375632c712940c1a1e580008f26743c7375688816c8485688b40f80b4407efc1466f5b80841105ac40a40c750c2a3ec34f219a4865ec38b4a2a6916094479939122182324fadd28d188db7e80c48f5985704ee128278e4ba285d8b06eacf00d44ed483c05fd2843e003913d712d5cbc61a7914398b8b91311695a54e8b65fdc36a59e9080b68c4a22506aa4953cb7f1396cfa1f691125605a97c2b24b854fd84bc8ede44f933453866eb96c29a004c1c48f52c16b5e0e440f02245c06e8975ecb3915426454b676109492cb7042113ab308445954ad1507f06f2b8709a4796ec2ba9d0e033ffee51dc21009255395fc906a848914b41510cdec57816bd37d23d8d3e99732d08b5acd83abe34c438b9caf4c60c65a43382aed06f9484f17ccabc402ea280ed62682b1810c4a58a599ba8753206a54e16bd59a00c155b290ab0a6634fe83eac7e46960eacbe28ac2445b8a6c06233a19d0535cb4836d167027367ec16ea32c2009ee841fca3eaf634c2e2d333d3034a50d21d2b56a24063b3ec95063a00f1d9a65167b8586a3e34667019f17e2a68b9af941354d5b98d8af0543e84652d25ba5c771b3c971a709882c7d504644b5161ee7265c44e3635e06313cd38a4f820e19973b3b1b866c25a260ebb56748e8ab2223420d5e21ad18e5800b426d7ee155087ac7952421de74e88a8cbd5e2f5b47cf6e7b78b9f0922e0ef0245a177bfb3200e030ca8cfa78162935d5ad99469410faeaf5261fca6535e68662034c24781732a041a811cab5a0d287830a987407b9d2991659b926b4f24c749067a73568c1cdd09cc9b65c56c8a3613cd2f589a7e1f522003a570c5d2ebb4a2cb21df8f08805e138cea0ed2f86d849123141193da13c2f6164d256c476022078411330eea3db721498ee04ac0e5e8846c790539624b98ae15658ae7d218e81369818a5a2e5ed46d9088484618464a12818e51e2c7481dd5432c1475ca8d2aec26c2b6f1eeeaf293d2b6d2c30a72e6c4bc0017404c8a2695722f67d7774f230bdb7b97a7913acd6610178057712f8dcc167a9609e82187986aae40c5200179e509c39462825056cd6f6452552acc80a2537064c310baac280045f42ab88ad6f7f12cd2add00bdc8bd9c515f49330692d17cd5c2782c8bd2af9ad15776ab11e9fbf77c17e6a31f22106d6c30e93c610668d0e574d42f72a87ccabea586c631804d3f8b0fb040b20d1972bae4d45831e89a73d4ae373576658d8a4cb44307999c4c37ad975f79491f612b3eb4f24cba4c594141fadaae4476430e283782df64264c030b0d5820b2b5bfb16b4a2ee364d135da3ab4ff0e4e7a18615e8366631d876d6c2f0f8cd9ef32f668dc4ed265508efc5a4badb44660a84e45d7d126b79ded30a6a40dd6235ec9ea2eba3cf2cfa5ab342be410b62308a7e39f7094eae90ea91c2fbd815c208b0de623704269548a3c6389b14db540b59114fa4107b452c049f27d977455ad36cc634522d15d1947b49e1170af5de80dfc2d9df3278711cfeffe606a05fd83d8d9d78213531d52feef349f38813cdba477c5c0e5018c089c5052cd4f6844ff8c83aba7f059d583b179bcb17ff6b397d72c0d1498a89e1490c674c0523f454d2ecf992b6b1b168eda8ffcad3fc7f8513a36e4d0c769cb3313c2f49999c66845b1eb4aca25bc0412bd1e735578d10ce0a694bb8afc0b029e84cace68621a7cc44a05eaf0bbaad2c7de9ed492fcf25965549db9a5c5d89938989725e41dc18a448bbbbeeada4ba38f5a06b9b2f8c1a3a35de9db731b395e4c95b85045170ddb80ffd1b25db1a997f9c3486902481351674276657b756fae4155094a56e22017ae7d35a2d3866abb8845043cdfcf07b438ef773e8d4c49bcf9d9a7a372fde4e7ffaf44c81cc9189e12b290a8d4de73973651750b0986dbdcf486364525b33bb2f41f85ea87d5db743eb26c1692eac62c8ae2e8e1f2ca40de93cfbcc2207c727493554940a0912bf6ee70a92cdba703e1abbdb8496097a56310bc4a7b5e6214baa2bc90c7bd5d4dff481711c0372721cc7b993e3385d5e7c72e930d9635d179089585c2f50ddc5f9186773387e9f35137bc0d9017424d279cd803dba0eac76bfbf0fffa073257125abb413a7e47a241e48ef8c1d93ce7a9d35769073a892c1e51ad7d06412c130aa27ac5a90080ed3e8466d9935a57260f68e64624e36c6386696924f85d69ee6a3cd4ee25abcebeaee6be45ed2dbfc34719223ad06ad307626042b2e261a3d6a84565c1a25d558ab4dceb7b4763e8a75922c74f568bb8b34ddaa1dd69770ad5f66a05432b5aa966c92eb1227f40fbdd5351388ca4b5287689a7dd2d9b59019fb513aa5821ef2e46a71421770056baf1a07d15da76d049b404378abc5e234a63c76abc435a5ecce94d918dba45f67a28b89d5fb0a51d319d893aa9882ce7390f463271852c55518b5a3fd35d165293d4b525c5549a6b916ea047dbb190e3a3f30659a3fbb9667c9cefbb2a631be0493320696a1e38df5681b03bc24b318688d71211e2220f5e8b1b3a713a55593d1c37c9c08adba39f071810ef9f1b8500215bdd026b0459f186f206a2bef2673e47a76bd156676078af22dd22751bb75b9314b2e34da37bc4f905e7a672c08bbc4778d63af0cc3ad9daed09a58e4baa70e9e149cd46a5a7552e9344c348ed64e41c86b5dbb106d8bae6ad8434f846aec89d6aed699299812c33e7d34b52a624c956a4a734db4147f2ebb0d1e5e199b55b46c3b34182c326a493e2aac4b00438ec32dd0c31a239a1a96610c15ba6b2cd144d7426358631cee62bae25b622d221fef4de41d94ee3479c49993c4f1672ac0fed3dd870cd12cd58533a951936063a0f2904ca26a5c65a204af252b35ef6f687c54ab090cd088a84b886346ea85de46593d46d632743bce95a4140993155b3b333ba0524ea2483955b13a032195a9dc9cd5c8a67426d2444f0b064b36f4e4da3417cd4d6aa950b5548b6a32da51cb52b39e41665e4521145f6f2cf090a8be4ec4a6b6eacbef9a774b1899427898cee435cd9fd4ac7d0a5a9e1a53d05a4bac66a1f54d888ea438d179a42a06c3d8ec64620115310af38445d36ded6b345808f7d4184d42c1b41d6d865a0385a0a88a4e6b5b5b4338d35b47a1240ac1edb0b99634ac33fba7ed36556c287d42ff6816fd508508bb9e8d10faa5b394608506d415c2ba1170356a19448ea2025ff551afd8f86d1507365bba9af9aa3e5fa461470c840f62edd015a03b38b1b57ae3e15987e79b7b613fb1a04e2fc013b81bbf5a2fa63f7d73f1c959f1a09c6c536aab94daf3189ef8dd66ae779729d3259352767dad03d29aa3e7205b6954ec3306a8aca43193280783851cd6855842ed7efd7074c7a9fe1ba7eee9c317cbabab9f878efd3d09cfa5d02f417d68649624e87042080eee3dc1897510f4615b95eada94c26cfe6844dfd6bdc8d5296ab7ebaeae085f7bcef2d2464a5955ef64e2a5de10083f642d6ac952dea338898294f1014c41e7deee296108826f688f9c7b137a717d3c51a1991433246afdd0cc2762f197510366ffc46647439b57545fb472ad59b1fcc4f79bc987cecd3cf9d0ba7f28c870a61ef97ff85cfdfc78f2f337363423911947ecd4985842b7c9ed2ef8606bdfefd490088396ca13a9f1fda61e3ff4c4489d7ee887160ed7c07d4b87274f2d9ecbefbf5f5efdea53234089d5ae4260b54f10ddc672949a0f3990ba287a5bb11215e13a3385880632b0dd30729342430f2a9c671ea551148d8fd52c08574b1846e5a0256af87cb77d641e691d033d16a32286b09c43d6cac77654d3495aac80288f8ca866894eadc94453853f53477657b837059c350a3534172e962c4eeb1466478b7d2aae4dac7ee415204b4845081514472dcdc26a0d5a7cb051b6f1c925d38788d43437a9578de9218aad02b8654b24a5a6903f8df28628605c1c7e82a652128d7e4173fb064650617d0521b0a3a2bb0a17538418c568a24921d059640c1f93db101b92423726ad779e898b337009d38cf4206a055591ae6bd96d62296ad6d4704a6ada949625892c4e494b6a54a8b7ac26e26a5d2250a31595fe0af32b42d06cd6ac980c89488ed2155bb193bc248ddba1ff8f302b8da8310dfde312c4846e8760a76e863672ded240216362541d895c2caad0b478735208f2917d42610803342311b0dc78eb8a04db2b054f759e9a81763de0cb12ebf27cc0e63a56f849c2a0a7ee250b9f1a5590c2fc995e262d01a4a93dac4aba87cfae8a568c71624d2dad6bcd8c4706444743d55ba35cbcc95a4299257155b76381671617a6b4a2f88c8a58879537235c6ba6771ea5f175d9531d114d7126ae77dc6d8ae84acc13c1fc155e8f12b527668c68392612a7ca5af259d1b2e9e3e03f0d8435ccfc0e46017244e1bb0858cf4a212cff6809cf10acb83c757d90d77ab7c98c026b89202434ea73cbfc13d6110be46d12c19db4087b6349129371094b0312579fe1740489ac5a6baa2af16a2c9348ac5368ea4cf9aa41a9f7288e45e0e53c8abe5af1c445e7a2890aa7014aa4724a1ca8e923119657877046d40a22258e14ce901539b1abb7b069abd42a6e9ab6999574aa89dd6405209f3471b5981839ae443ef356498a824947adca81f7558d8f67f2baa1a39f1587347bb4f951323d0fb05a225656c241e5dd06fa49b2d2b2fa9485bd1e5896a16a8a579e0b7a373b27b9abf399d9604589ca5c4f62540263b19a3a6a31b5d9994d08eba6358f58c98dd944d94a182561328b45ba816814a80033455546dfebbd3a668a98996d0e6e7872992165033362994ea49d69e99f539703d56546d76be2f2c8cf04b1344511802b59886969ae35cdaad944f4e67340cfb3a21d6a71321940f45815d155c52b1066d2c6ac49778da669f5e069c2dc803d4d0a1ca57a1b417ee68cdba0851069ddb33dde9f1f3768e1fdf4f314f97cbbbcb9bcbc59fd3c72550c3f3d51ae33f92314ef7c88eb1e5c09ea478a319e4b8a4e0254e6e08b8b710d354e44e69f282e79c265a611ece38bf03776e8798c798a4c4b08ebdb17df7ad0f908bbca12d6929acb39b0a066498945703061b549cc6568457dc8bd301faa576675f5daac8b51318042a77722caf8a9bba702265da289b487ae6fdf787c6d397aca07d8e83ca42727c27cf20373e15363a601836fa48a93f390ba16b65a1378b4684531cc868d55a391401e2296b96e889b1b3428a4951ddda1217797ceb0974a3631a96c174c60304096f02c063d15f45a524de28d07adfb8a7bc925f78f23da00b165d7b58f72b3e781905b907eb7528bebe712a1c0690944c6b674d3411f7ab4e3570f72439b628da3f68554aff6382b04516f5109c30774ad31a01f9a0827e6c1e5e5cdf5cdd5e2674ad6f8fbe601568938066da530125d6a30495c8acc151dfb2bdbbc6b7d6b9bb8d257fc634ac1e511c4d399f0d8c76ef22e94dd068b4d327a5ce2e40a6b1b37979211fd857a114521c533589b3aae1afdcf29e9fe8a75fdca16dca3adb8af5158e28b2b751b7a73a57c55936bdde876a441d6a831fffe09eeaa272e212e928bf1b93eebc415bcd3c4b0baf73587a6ec9ec6d89c87785e5d2b13ad92992221e11603f39d7c06478d796b5d8d5308ae0b042a467a47adcc99c77eceae300ec70406cd34682345775798b5db50c4c53809ee62b848ecae410c2a8d25a821735585f610687c81397e0af1ddc63ef8fbfd0150f3e43d35e7e77327e6fccdf4e9810a7b177c328199a76d8260481fa634824ed6aae1ba2ce9c88c32a2f6658235c5ac804ab9116513370a7384a13987fedcb34e5b0e6d5bab0b3e4e7428faacc54332e42fc93aab932bf1f8faee92ef448a6c584f91e92405928f16868bd5f86d16576a23dab84036ac0cca49522117265322983a4b7c635240fc097d8266120813903a9df55953944bcbf4af65667ef82ae7515da629bad226c8460d6b832f27b7dcef3dcf1256a3e59838be4c125d88899785e224ebeef8d4f76e69cefb3ca92b101392a0e298e68a03d9132d228d59a5e212337aca087d4f1ad21d68312dac2e1443213e55df3d95ec2985484c2ee788f14d92998506d906fa44f675fecb688b34ca304b86b45ee9d30b90410e1705095bdb8bab69b781ce21aed6f23cd4ee5a902906572bf12023eea8b63be548fccb682f5be7bdb0e811e519ef62ce7a2ada5b57de8ba3fcab9be9d4fabb994eacbcb7af5e7d7afa7b0a95d1f6d099ea9af8829c552d2ce608ce1969818935c69f43d42fe38ec9261b2c14580c19f4d07e5eaa0bc1c4ecf904d616287bd00086b1fb3543e98a2915d76402386699c35bf43de31aabd71486909670f49c663c346ccf22c6294e09145e5c2f867bd985443ca180096269998b6bcb3b68338eef3d97ae333ed7ee1be87ce3759a34d1eef405a88c9810bcabf2dee7eae3f0b9f6b89d36996013dad715ef48d6ec761a95da9d6e3fea8e4e1461ba2398caa7f9d43e136997c04fb27baa834390c2b01ea309297a11bcf32c8833e740dc7eb0109fb84f5014216c5a65a416ebeb3c44e62742b35c6862956e0f1f59d967fbd7b5c98ed16859f7925ecfe57adf5ae20239b59c78e2d48ababadc5cbe58ae977f7db3bcbaf9345d7612da4ac2ecb29300d1d63f69cf935f8984ad0893c3ad047f7ca994a38ba57cecf2188e2e8fe1d6e54fbd917e6887f43b0d09fefe47e3e2f79af2b11bde6bccf10de8947cd42bf94e6b62f9c087e613adf9d80df1fe729077e7cfc9a977fb925393f07fb3f76f3b921d597636fa2af60266b0f3e1b295da40a09129482a202ff65dee556c39010fb25451edd8f2a7ff31bf61cb23928c24d955cdfe09a841a6bb85fbf275b0c33cd99c63fc9ffff6f1cb5fffd71f2f977c4e57f207d363d90c6537804029399ceddcfa9ff6d7957a8169ef2f79468a684c1f66b7ffcab9fea9d61c46c155e4dc0aa595e54a1b21ad8fbdc29c1a436b57b3b69acf2b86512f76915a8f5e027a7fd6b0e09befcd8de9460eb37ee9915ad928a98d8c0dcdf5309b1bc32ea2d72d728610799649d34c66a5997f7d91d13a777b3449e2a262655efb743ddbe547a5e88b0a5d3ba0836ed1ed0ecc264b5483f6145abe7f2a6d82a899d2a56480cf53373957d2055ed7a4ccab05f548f10388066b5e205929d7dced73fdc26469bd26e120b7fb33811793f839c4f954620f637d2cd96c6157f2fc326600b5e821b653a8765273f22087e26161261bbbbd1f1cf8dfe67322a2dc89b050e411fb359b44a790a75d560eed6a86676c2e9bdbd52fa4128ffba70cdc5e36836e3da5a9843792cbebb83cb8732b11b000f2b72a6357f519f892169af8f9931f61b1b73733d52855edfba74ce97bbc80f1513fe618498e19e9621f8c234d950314d2527a85d79afc9d543fe44ecd63ead3c6cbacc048a0d7edb37e7bedef65fbeea2dfdfbdbbda5fbebb5ebffcf90fc7bb9ccd8568318cab362ea1d483f2f7e3e3abffc822a96712fac84e2957bf440435c3784a6d85f9912ff1f19f52ebd794365d4a57a294b52e2b86f90be3b707e2fd01dc5ffe7c043f7cf9e1cb9fbffff2c3a72f7fb97ef7f1bb2ffff2474b512993dc12f367362e7a031225fba55db1b349426bf32350dd0dbfeb503649f37b83897d527106124e28afad1776615d8a1ee6d7944f223481ec4156cfb6fe08edc59b8fcc17fbbde5bdb9ed1b1c12d048a5e8363be3e6cf34a70aee3913bedda70c7df4a3f9c21ad69e408d2229acba09aedd5dd359da87bc4a5011a813e3713cdf5f483ee62b81ef9903289e02c1766a5fbcb1b5c565d8ea7d6dfd29519c94a67902b4563ed4e9dc0a9dacb211f54a56450fe871e5b5f52748b3531f6e011f38f28b17995be2b642fb304c2481ff5a39f06cbce81609f85a3f74317b55d71d8044cd731b668813822d2ff0d7b809fc8a4d0890f40f80649d8641e0b0fc16a469b22de0fe786dbdac26b481c459205eeec70cc38b3eacb8cdd42814b23fe5baa3c77abf94f8e205f99f056be113507d8bfc3f7bb6b993430e5823f6440608f04df3c56bd280a2decec96393c0eeff5b12e0670bf91d41f0b363de9107c73f3d7fb9fff8c3efc551f80f58704998db318579ecfd40882c10cfa6106fbc1ed1a7c0263968b21bceb6796a3f36d12915a55010da6884257a75e59288caa36ca2c02a3a05f6c1b5470bb287f64fc1eca57ab80bce7388ed6bd7a4511894f7bef1f0d22ecb3776a9f6678b8d536d482a1988148fb6d932fb2154dc49e6493e37d59b107a93809017171710398fe34f50628107b34437ac7024db259ebd0782aec83fed25542fce4c91ee7b6e909defac95b1c82218ecfa56afcddac91e3b757e1b50995dd8543660337bad8f3dd728561476a437393f0b5640c524d564552efebb2ae63ae3b714b399b280f8ae439bad6109887a434a93565a374ce77213ae5832a444f22aaa1da7e7465bd34dd3f59dfc9260fc1038fd00edb98546872d691566a81d2b20e4c9d994fd25f459af6f3d791bc5333ad3bff94915212d78689e6c92ce4485a39ed9d05dd7c0200d6b18cc293d65aae74676059d3837e417356b8ac1b3196dcf022f7514e98cb0fa818e6ec8501ec7fc242756b11603c7f33cc96b32d6d05996d5537fd7bd10af07b9145ad73b6b91da6ff13d32912bc9487baf9e9484e5760e9d0dd855249b93c26b0807e8982cbaea2ed1dd418d5e4c6065c0a5bd412f9e1312b6d0e428f6b936ac3aeb1986d3268e1c86636d0d3888f955cf1d6e2461c6272d410983b4eb51a7205e4f579480494140ec47d224186edb27365940e973d4de6e3e40b74920860615a071eb8472669715a520dabd04b23204a99d9c120b3610b8c8a133d64d774a982b101843e002da01699e5492987101b4b5e3eca13bb0d4adffa756b7ead46fc4bb8fc8a0524cc084155278d890f3fd645412877513bab068874deac807257191fcb56ea75802f8bef8148fd78b22d740b4cbca5cd61cc1602ea7a2272d473915d45ad924246daab07a2a18dcdf5836e09f209da8f06446359f4eb156046d6c7343c09c7eb33f0fbf89211212ba857d00c6a444b82998e4acaf33950d55f44da23b5ee28b5ab24fcddd635299bab0b1cb1ed800e531917ee721bd3833bba012ed648725e6ab92514901956ccb27fff1dc1cbfa487d53df3363a601120fb3855dcbc7f5ae09bc51ed62d41861d9d528a02251c010b668bc2babb5080bb4b598153f6ada614b2d8ef63eda2af338a5a99d06e30a11f41195355e9a788dcee924c41506d37fcffd6e74a8ad26dcfadbfc4b2043589ec3252af8a38262745288e54511b45c88fc8e685aa733c12d3a7f8e40ae5600008b0f677c69832473d6ce8e404a33343c54ae8c2e9189aa2227702a26b6a19cb58e14ec5e522950db7b09d5908336867fb6008be1db986302b5b1649b3b0a82e7e9924dc896e14e6f0da6d28eb2a2497b1fb66e68c97a58961cf86baacd5491a275c7d678ead5070c84a42e0c288403a3a2466a12b1f3cdb6d8f153634394cb82246b1bbb443002b07016d79a8b1b2c818fa2eec665a835820e863126693a81c34dfbb3209851c12d2cd9cc4b42d0baa7ad1cdca502c5d736530575007393b3203d1e3941f9feb109fc38966b49285011bfd04c90149599cc90328c85da84ce984f6cf218572b1597e9c5c0050c5a3c68b58b485b83ce18d8104961462c0e1496f0030adef844d6abb4499dc869282ab69b9d34b940e331945f23132162d09519800feeb2961d7fd99644933654d966256549c158050189a2493b59f8c0aa77c56d6baa7f81fb3cf3c57ac3ef12792a44e2594449f869cc44b88217c60b60a8814195c4f7a0b564677d69210def475c8e52b74421942a08e33b65348c5a08cfc4c18ec27d5b8cb3b49322927d0d59d913eb78c1d88666e34eb844d029dac3bd9400006926739b7361dccfa9d4d4eef366762bc3c6c4086da344172c059bb2289ec1e79a951bc0b79a701922fce4aead21d552b8894592ff2743420fa6a28333300ccf06d5ff0d5897bcf0b7cfdf67dffeff7a2c4fafb5dbf9265880fec0b09639cb9a9a98c6cae575fb04acaadaf509ef2683752482f695224ab4d3ea9bb5d75c0b73d74c81ada11fd9e58a2cd49ba8288319d1250e336d4f0f3cc7b58bb1240d74b2d944b4e87309e74b4de869037361528d58e0916a84f792c48a4fb0518f0abcf842a440d4e7ae8c5f71e9af82c562897de28c9a2e2d3664d75b95c4cba5d550004e728f50beb2485d9e5a145d184a2fa12f1e30d15a3d8d30833a3d5302ea4e06e128bd2cdbcb32ebff8ddcea15d4c3d5ee51ec490efcfbd414c90af3b917792b8677e73bf3fb38c4a22ae9d6f88958bf961c75eef11d959d498bbb32a4688288a65b4de9f01b6441d0deec9baad85c6a05f68a1c72f30a79d0f20602a3d80da3934f999b981f9c5a9d3029c4efc325fcd33fa492d00bdeaeb68d804baaa480ac1df0f20fa34c3764d69a1ea1423a83d7e609f52bdbaab74be9e73e4cc3c66dd7ce04855cd3a80e1f3c526c92654f8e579b7f0e814f8b0377bda91293dbe91a27201c0e7bab18bb636aee369165b518d8909034f0be3a9c4303e26e8adda05568f2eb2a9722935b46b179353794a31de7cab215f73b589952f3664d75cf9f0662ff74f40af25731fae78c2421242c00f281b0748b98d01ad8af08ab50493892a9fd651f43b95296b21acfd97172f0fb5d558c538cbe0df2cb1c460ff3382c0b51d803c62c2b750545201f15157be36050075933031d6e8fa29472917f2a66079a16c0223abe86cdb9e29db4d2144a8ea82bec3bf173ff30da4d5cb2c211d0dc7445e2355fac43f01263c9556de11c626b6ae7c69f35832ce89cfb80c9e94ade816fad1843345e23bbc434d3cc1f66dba8c692313f291e474a31fa16a70701a35fbfac06b209fbdef2fedacbebdc660de04667c9dd625f14dd8e64d84e696e20a76c3947dafed56912192284ab914b365abc44392a91086c3744b3730bb2eb51f0f07977a184cb9e54a94cd5f147edaf382a04c899714cb11cf95a9fdc49d2a6a3ddcf065813aa88e10a3cde9d2cb6d857290e4a8315b669f5229608d8b4d5bf38ec8c0c1f82ba13cd5d60f0588a648bc54d58e9cb5d74b35d15d214d4b22154c9b9f1554bd6addb06e2bc330072e49f5cba7b376a588886ddd043bd8729887df426ce24e1495c933cdd33a141e898427289edbabf6820379a8862daa1666430cda1204dfcf34d2616764eeaa74673ede31dc088f7a4c96e943be99ba7d82ee1bcabc7a785118c3a04da153db544e174a980e5f118e142caaee88dfddece5a94deb822add408885c8cc29879e4af9e6f33dc5cfb59ca1c537d140a7486148afb1c23781c79b5fd16e9a889dadf4221a3076909a35eecf0562b91ada531bed544f259b2860a113b09e98013488ea44578ad9fd273d5b166f2608663bb8d7377d74b7be2959baa49a66cbc7366dd8480a53bb1c484ad8fa36bfd72e7c56c5a91a8a9c37cc6758d650b49da2a0365c59e0189a55f1e66a26152a8225abb4adab9109701155c9721f762b53fdc48155e3b82f532f2532b1d54702bdccaf41fddd47ed9d3e6aaf7da4b00d0562bb9310cef7672ff83d6012640fb4b61fe5b4143097f0f9a13dc5ae29613ed5dade31169e81aba55416f064b44a55d01b85dd41b9c29584dacbacbb90c506b7bd9d761de2045cd45a014295fc2ece445574f2a8093b1497eecf944cd9105ebcd8a6bbcacdf2f1d8faa82e657b2da2a417413da4d0d53aadd48bf94b5f29e87205db82bf8ad90f2d8575450d5b0bba3bb30a84da76ab50709ab70f53eb0553e786152af3b1634265b035b8ad56ed8e07cb655b9d9d4055520396dabd18505a39ee68f3dae64cbe3fd7bc39dbb00ab0052ea85f2c559473be9d26d89215f34b3ed1bb9caafae25d4fe82f7fb97ef707dc082b917233530882f0dbd67116ffb8137da9297c595e975c433d3d2070ed5040535587c9cc2b517177f050cc39c98a82a4296f7e082310d05a93e642ed96aef103cb50eeafa80e3603a4626d34ece7b2b6c7fa3b7675c6fa37eeea7c4a990d973502f2917a75453b1cc5dfec359d2a810a78d1acc31a3908da1154ac1bc417178f486f9374e591d84cd384ec3100a56c3a31efd07f27a6c20649895e4074aacf24fee252a78cc20b71531bf19c56ae46558d2551f42cd24fc07aeab6e697b24d772d6f3d751f715885c18955c673e70376ce8cdd0319377b8a439111334a76b83f31be45bf1a7610fb2dc52b19c577d5776f67ba9f96e55299b8a2b14d93246b3f3473c374f9d28ca09c39a7fb732a6dd7676a84bb70132ae5d355103af3e2b119cce5ab17b98fb59bbf6346581651616dfa6d55abb6fbf38aa2e68c8f1d07513cfb1af59e85c9239c75d35565977b369398e94854f7566a9ec51d11f52e96323819f5668bf036cc45cf5d9b6a8702ea14ac0ecd9fae1641d3a838381d4e08a1140505315a55368c521e2aa2c72d08f57349d1eecd84f3bc7f6aa9bb9ca2996336f9afe039b969a6a447365b0fda9f4fd43bda20adb5372afa810bc2a04de13d9cf4dc7593152b8b8645924d3b9a437ca490f7b6497313c576eae7b81744992a499f1f1ff7f70b52790bd9f725f3fef23de9fc5fbfffe1bbbfbe7cb8feebffef8f269f33d3682c53f2ab6b998ea6b4c5be9b7a8d8eef07f2e4cde77a5d420ae00fff7acc3e43f4f6bd7f3de7dbd7fb3318732e8f85919cce1db79136a3be5ac47b5e64d8dbd0ed0f6b48b71c4758f7e7b1c2841ddbe6348ceeecdddb81b0afa9c54f5ef010dc1cfb3afaf4fea9e5e94a7eaaf303121a20da86edf2f51effcf0df177cdf06ff997f74f85eb57733557540a561704d882ce87c2f5a56daf18f287da4ede142a61ccbb753678d5f57ae10c2936567ad480e6dde424c4594cfc2e723fec8cfefc3a7e1baafbedcc7d77d2bf7efdfeb47f397ebcfd4e9533ffc0a46f92eaab8704edf6622b8aad773015a0de35797233a174215756f808c8e52acf0cdc9bf91f37659e85479c4c641de8d8e89a721d120dd36ec20c471aef18bd727c4ac857c8cb4b85b15ed5bda6b00b31db1cf24dad449129dba0e003df527daab5de40b4cdb6be721a7c623f47af7dcead3cd54ce6a85d2d5e3143dace128371305f123aa7208bcdd2f3d3eea1802f98f7357d39b236a8aab678f5ce4b54a6d2fecc3fbef0fa85577bbfeb177ea761bd39d85eac2b81af0be996d6a10c365eaa0c2f7636cc2443b7c19fe0003cd81f9b82b7dfad9d8722ac22730d681481f9e1a2148585dcfee2fe8c2874bd07905455afbdbd1db6ae401549da1dcd51594a552d32bf7044e066e92467b9ba049153ae5ec048db91dee864b99e94f082df61c2e10b9a134a70a9ec6d86135f1068465c575a59516f805a80b32e438259d6d595e09a699042083739e536a21bb48561aba4b1355f9e4abef999cd6bab47166c97e6b580a905e4189d20a9d8648c32ad12adfb33018c68139513a57effd460252a8248f48c51332b39b5a794e79180002a0dfe2512518ac9c79aba4f3dde3f0daebf76988a4428bf69e5bbf2e0ba99259308f0a586fc1007c3efacb68e893e082dce8d8b45c3d6e08b7032b735ce56c92f495c09cd6fc85b7df99eb4fde7e30f675dd482cd552b52239b4ece2a586f821c6f32fcdd46a72afa83dc2365b74c4fca5793672ea91bc42abe571ab84082cd8a441ad8fc642905f86ea60755fd284bd15250bcf7e76c7526398ecd4fbd255b64d316f3c68fd187ff91997e9fc86926aaeedb38a20330465b2571295f73ee2669315159084cc1a12dd779cbf328f292fb7cfbb6c8ab7453705ef69e4c56dd9fd340c89963d805b1e8536f1b7fab37d716d37ee8664c5c4039b2bfca9ff31c1f0a692d45d527adb81217efb9f59746fe9de8e2ade70bfe519e5ac17976f635b5f4e11b8b881c6f3223cc636fade3f608db47ad12b7e50474b1f9af65f8a2a25472108b4f39d2b8814b714960e199370804d24e6054cbacab6f2fcf7f3edeb784fef978d704faf4e5e56fdffdf5f8f2d73fffe1d6e6e489c575e3a4f7fade2e4eda971888d2a80069932ada59b391186cddb9c1eef58bae1d52259365f738157ba17123ba8179be4fecce132ba7d06ea529a1ed3cb1db276eda2d5472278db4b7cabab0f7365adcf9cdfd395101106083ae5ad46e6746ba19863c67afa4644e30d91381c6e3fe6c7374da8f772f80bb72221ebd7bb38f2fe4e7a71352ee27fdf6e65ecf2fec6a4d982ae988ce845b683b27c4fef4f6b7d7071ed1a70f9af23d4cd609fb8aa3f437a91d1ce9a24746e8c7e70767ba961a88cbfdff3cff2cbbadf82fe780dee7fc9b03f6851ff7c8391fadc72ddbf0ed14bca4a70b53df86f61272e84abdbd3fb30592423df493c7897485725ed6c59f3ec8eb5fbae4c5a7d06f25b44b989f6bee17335694e574019090d49fb2057bfa7b047bfab70a7673db72247c39ba4299b2e9db57af1b79af819fa34c30106301bb5dde04b1b52a249119a370276098d2f2670a052473edd152be2f17e8d9bf5e2fdf9fa9348b33cc6380c6d9dcc0f8ec4a07ce2a5822506add3f88d47579217c095182d992a353d80050a82cd3bae38355b9802eb200930280934c55425d7b250b654ddb3ba489ed543f6d2e909fffb92c1c887c2b3d8ccb843648398f521bd9adcd5e1585647736a76ce77c19ca9b98bbe6e09bbf79fdc5445999b5b111c2c7c59cc75bd5eea06c8e4ecae05ede4db7cc96c2d4c5d54852a448b7a14de46d7f6f9074bbfef23b98cb896e3574bb697b7480bc1a86b93d03e3ce3c5103f2a9a8320f504895cfcf32bdee9b3c482ce8279a7ad793cf3343a098572284471a54fff673276ec7ca010dd6f617ce4c6663a968bbb8a892a0dd9f21385a7092c83a3fbcf0a2c83dcfd2226c80b1ff05d6750949636c2d766035defa70847e1ba15c46e89f6bea0f72a0a164a97a962989a74e775d2fa6f9952a93fd06b3eb3ebdb660afd2f80ca5af3c062ad3dd59be914a95093d5e49efec07251344b4497d0c536e432587916c66f61bf050fdae873949c2de9bcd9f6b247b2c9151b42bc048d49fa15e776da0e90c014e141d5b77a94d13dbece0606e90cd8e446626a8f983c5c69eb0f05c963663a1c304ccd6bed84fa7c992b54e232991ddeff3f7fb73ef8a3294a71aa716c3540a26550a75972b28c1814be57da99d2faaaf98df7b84efcfb065c5c36fba4ace76ceec478fd9e2a3c76c599c3de69696dccf7bab4615432cfdd286f6501a741474317bfa3fbd592653734a39ffea66ed245e30bd9b982ff179989f4bcc17369c20690afd16e68584569ce6ac5caab72a39b1a77baa5d41549eca7a2b69e59cbfffab57bd5c5f15e4d6cbf3f137e9a7a7367ed5cc4e69244cf4ad92abdb36c8d42fb63d82820ef3b44c74e856eddb6de78ea4a9b9d79d297f1a07530f16c8af3d0d9414eafdb96ca2b7615abb5e0528ca237493317c7a6b68ee9bcddeeb3ee092689b47d86e35a44b526a50bd3f63d1894971f48db78cd62bd27dbb2d5d2b40599b0ee865539942d7c4e919045e87f26ed0b55bc634d557e9f0fea675c6ea20815ceef582df445179eb2dbceb63bc7efd9eabf1dfbffc9fbf7cb9fed1dc8c0484766ea868657f091d116b45ef4bee5b978fc1fe66946a588fa386bd6fadd9378fc8c93cd2ee9f26231281f2af8239c72976e4d1395255d16a2042b345b4331fd78e0070274959f152187ee72e2f556b27a4799ed5c5a7d22348ea3fbf44de97e0024a71f0a6437d22e18894eaa5b46ab2275544f61f1b5bc8a8f5d4b49199a411f3f485f8aa49aca874a7e89bc3f373358c8f25bbbc6ac887577da77dec88d05dd23a884de21f65558199fd71053ca0877e24bf77ea490d778930ab3b912a49b3187aafec09cd5d6ea4dc2f598110ecfbba0d29a868f69851f65e70fe7c5662e546dab41f708fb2a954432416b5b33e8dd6dabba4f86b7997c02c49b0e693c380dd1994444ccf677fca319e0fffd5a30b89bc86726817133d5636694eb1b98411b74848b57b5f39f4434e5da30c6e6f6ce2282ae77fffb611c117af2eb57a6d578ae5bdaddb5c311f9802fbc3ef0ad942f144f3f5c2a6c0ebaff32e7b20c973d733d051ad0bee37e3a628f4b273bd193ab54ada5510d32977289fff48e6395418b1857922033663bde0c55043f38d794826a557d49bcd04bb7f1b8aab57556eb4c998998ce53119eda60ee28c7b6993c0aaa9b8be3d11ab76e617131106d25f9d88654fc4b627e2bfc3347c989b3f9d88e55727629df5ef9d8804e38a588fdf996b13fbf194a87cbc05de1e064a38dbf176123cfe5d925990da78386fcc3a6d7c6cb51276cf371fcafdd9af087bc121d90fd4e7706b175bb98c4f44ed7b6abb2adb3ad16d7ecc154e4501b503899c5d36637ba4a2fd42e05dfaf35dc5abafde53ba7ffadb5fbfffcb1f0e40aa823792335b412207651bb03ff603731897a28597baead5d81899aaaef85486193845c6bc0877490d66758c6b00f4741e1a62d3a88d9aedd4c55f45b5920686bab0b279750b6138327c963230cfcfff23f7de3706fa4cc4da485e01ffbe6ed298e5e42aec59a8a4df7ad6f9a59bddef3a52a64a2b8f9345a2cc9d7be5145f4f54b72a55899022c915be298c61ef753db2fe5527063f99dd6554d893dc55a5ab4de54cf6d06e80eeab461957b32a870948091a236c0b2a29e533ab081edb89cc778a5668002ef4dcd93ce8e42c8ecf79d852ce5109636dbbd464b3f65ba656a06e37906981b8ae621923bfdde4c463e9d12a3db46b100ae8825ad05cf05b89613ea595eecf03c89b43346caa02dee5c1839bafb7c9ce7569a17d4e66865c4a0ce3ba1348db31b5250079ead2d8518b483e2a99836691af44a2700be33c49b3e78fc4aed65538188324f719d6d5fe94f3a83dc2da90842243cf14fb0bf97f91ac6bc3a61deef17a976c91b21b380fb2c4b4ddb4841e90c5024e0d80caa0e6e972d2eae54c194bdaf815638ed94dbda145fb26946817df57680715c75df41bdbf0a346851615dd3b37b2b822e4a1f5b9a47c60976f2819e53d935e4243513b186710b1b4ba345ce922ae6ef6c15261052df9f026d2818c1b6a7595fd9c1e68548969cabf94782529fbae68d657ef89e6cfdfbf7cf9c309e64119accd8917626563ebfcda9e6aed0764f094a998b9d0ce771ff2a6e159a4902b8c71ddd538f53fd67b6894b29714f247f321864ba35f0070a2a8d1c65475d4dba322bfeaa0167c517b42b46f083cc1f4c453c194c0b84c07d41f55a196755631a711d2557b9ea55d2a29eeab866af78093ae7b88bb9e2fb944a19c09f4fb732a84764c192a6d70480093ac5860a8caead2e437f3e590d1a5d60a79730a8ded19aad847554c4531147233b2881fcdc2595776465952d856040917c9f35a2c76074a3120072ffabe57698637cd564bdd672e2e478426bc51bb4b24664e048efc6891042b841a4171a59d639bd44a3b31a62bee3d88e395ab6419266347301c4b08268eacd569e2ad066d20db0da8366108556744dfcad6e02585fab16e24ad7e81f0e7a0249cd8eba20a3c2b8bf5ea9b726872684f35f7972ea627aa2aa9017daab31fda26048a56247e67e3a9e56fe2cc4902bc2b34ec8b7744c6773ffcedbbbf1e3ffef977b2e7fe0160396a28a9bb950b5236993bb09bdd8f289c80e9f58509e7a894171275a68e28fb00d88ebdb2c0b144365a02a8299c9123e4fed911820bb52e6f217d58542f2ed8845ce94d393ec9e55cf73e00849526e927b58e0b0cfde4d3ca2ef5e4c91f28b06414c8941ae6c44e6237356beb0f3dd8a9d8efdaed80d9340d80d94c3ea930797a5381cde7084c8b89549f4b351f63c8872da61813459b10224fe8342aa4c3e49440199b940f9d47f229fd5252e4639abc37b71e5fbe3fbf7efce3a14fce25b6b476c5912fe088746de4b5cf6b6fed411666df5dbffeee02cdf5fdb9a23e52e817fb9b348b755512d8f982c5fa798e7dccc72cf89b7c7fce38739dca9dc7914faa8f36a1f3519881e3dac0e0a2349464fb9467e8d7c74f480106e86b5c52243e5fa9f3a10cbb689f7d1481d58c8f65294936ddeca8a7dc49a2fbfaa679792a2b730c374006cbfd5307516af490af90ffe1c42ff3231659f99460266168922177c64a38f2a913a22ec97cb241a5f6985f8dc1e3549f73d1e9ae5f9f87c3ee9f72344ba19a49f9b9c4668ffb18a2d7e3e8f27dd39c2fcef348ed1143c4ab2ee2a61c1c3eeabad71be2ea171eebf6b825eef2f5c08b3d88d9d466253ee55143be7e7d477b284c040905f1ed9ddca85adbf74baa5269a62a1e07d0750cc7fd39cd2419b59e72699ff38247f731215e07533352b3f5751a31b3fb9eb9afdd7b3bcb4e1fa3b71ff11ce71b23367e8129508bfd1b12e2c7f7d04d2f7ffdf1f9770242fffbd9c39332f8d208ed6313055e0ce9a843d063e6a4c2ed697607d8a63b9dca5cccad189a4b19509bcd82044213190dd589cf8f82f9583ee65e496eaf874d1d60917018ab18c3c54b3d2bb5ab59c51be6a85690c6869066faebcbcb2caa63d117fef1a77ffdf3f1023d8c7ffcd6160105292be48f85d4c134ea5136f24e513ab072e0549e38cc162de46247b3f66a573cd62d155f0d4871a9ea59a4bf55df33e0be4b8a918f4a2c61dd3fc1cde6ec8ffeb192ac9e63481f60d04c4d4539e83b71f6b1b3526d8e4e97d97fc871edcccb1d5c660c0e53897d0b639560d3040d6ffc12622793f3bdd9cc17df9acdc79797bffdd16ca90a04b7ebf5a9d72f35c3ccc4abf0c9df7c72eb25acfcd4ebcdd3ba80ef5b60476afd09f6a2fab99a7b55e7cf4fa5b64e0819d2c8fff4ce4175ba5eef9fccee9fceaed0a62e7cb1d7f48557a757dd226ddd9249d9d9429e9f4b4d5fa04c2a6ebf6dba0dfba3eaaddf42a917aefe25d515d272fbeda48358f62f947ef1a194f3e4e3c64f0ef3eb4894ceb6b6472341354e42b8a3dd42d3a90f1faa6082ed2d361898cc1e1bbc4d5efbb705e763e67c73bad997ef4cb9eb8ffffae797e3cbf50fc7265112684fad5ecdfb35a7eda09e4f7cc82d6d07d1a40fe9a7fd43827b3be5e95617d88835cc0e56b266df9ea7a0e6c0a2f0adbb0a93a809bc9543570b236b0bc925e248ea20c75571c71ccf8c0dc17a88ad955dec7377d2a5fd9e37524f74fb637d92927da4fc20d3f34b54bf5321ab741de69400b8d877865451b06e81f9b7e460f0c4893c99b6714753dd8d1c7746537ffc4bbbc22386fc626d95f72b734bb552c2ee334b1e88f5923f98f2da81652913a4e78b3eb663defcf38f4f615028141e97ec74aafb33c459873d9636afa31fe4f474fef853225a61836682b9bfa41edd404ff6e8cea3dd3edadebfb91e1ed3fabdf5f0f8f25bebe1f9fbdf892cb194bfdf9da5ef6b5a90f957f0694c2f996af71336d3f4e267ddc189ea27f414d0b3dab77a75fb376e569b3ed5e75ac232bd5bd931d8e78c7ed697bdbeaae74f3fe73edbb4b3816736ba1fbcce6acb48579afb1a91cbd82b27e216c000e8f66ee7fc95e1b351f8e6f0d997df18bedb777f7df9fe5f7e9faafe9efe7eab90f87389f5c0fe61f7676c06cae652ed2ce4e25a92c9579c10192bbef6dca08fae8b94d604c92ea4ee0e83d3afcdea3e7ddffcf459e61f26a64f40b79762ab2f51bc500159b0234dbccc06c19c60af27db1c66ec2c452717317d78dc15fa9c6cf6bafc48e4a6d08f421e35d20aed86a0145e159b39ca1c5942566d805be543a06b547137dff566ded4e75ce3d39a617e5876a168738bba181a2d8575ab3abf2a8904e1f6c8819f973ac93e016a65eecb401accdee830efbcd9cf660ff343e1512a999899085ba9d3659346731e6cbc89ee1d33730063b504454fb2cb125f722b67157a33db74000eb08b75adb385c424c2df0f790d2c81ea4a274d0e04d61aa3cbd56e18e0d4a9730e41c69bbc1cb8066604435ddcabc8e5edf9817b04e0726d507155be4e9286451f8d3c6f42d4ada41c030b4cb272570482f1e94712de8c0614166a747166dfb82c20e48808d9730e77fac409ad3645299e7075707c48a37139ce27d3008f5d56e59696bddfdc43be9d105d13b095b277cccfafa94f935655ad32a54ffb889b7ecafc3cbf78fdfdfd93b242fbfcc096521763f64ee168443fb25008056873a691c64d24700158b39d75156466b8c72137fd16c8a3f38bd7133cd9cbfd935d3499d507ae55e552e0e80231b508f9970b5f69db47187fdaf358a1dcf4ab0d1d94cf5f3841bcb16f20acd705a205a7b57ff74fad138d6cb7dc0e591e1b8fa93d3261db9359461f042531b29b2e7742d91852002e1ed12b990c0307a87ad1705c720be9902ae19b5dccc221df7693dec8ec6f89fbfdf53b02ffc73f7ff797ef7ef8a3f94b2de69067c3ed1cb15ecd7cf7a9693b630e5fc34a2ad74a36868b8ad336928b1cea52eb1f4a18a932374754dd640cb32267879d65dd4ca2af65e6c008a916b77f51439eb6504702e123cf7edde70c31e7833b70dc81d31dd81f98b7ba837daf1c0cfede5a3a1bf66c2de71f9cfaf3be990372496f37927dd101dc88b7a3bb8e6ef74f794cf3cb5249d73432772a065358ac6663c3b3e6f5d10e4cbdd9c37fd60f28e676f196620e6de4ab5fcd8eb4d3d9e5f4737ffebcd47d9dfba75a618f4e255f4d075a4f71ec47fb62e5306bbff941efdd9fd38a2e671ef1634ff46829c51ef1faf32b14f310463b6fc9748d4f35dae35cfd18dc57cbeea72dd7b27fb4ec476effe8f33ee1558fe6f568eee73d53ebb4c9c0ed6ab062ba7a3d9d3f9faecff3b96ffbe9beb504b58ade5b7dfae6dd85f7fd777ff9fe77721bc7df1fa950e279cc611de5c4150bd09cb2e568ef17229cb75a37105ebfe1f55dcc72be7fb28b979643ff50d996ac1538e806a010bcbd93f79412efd195253c97fe27fb6c72c43cd6d8b06da6791b3830aa8e2840d9269bf97186f9f171c1fbb357848c6de1beab34c7a1740ebb5d3302ea06f120e380e654da69aae0ae91af44d32c4e53b07cfffab93bbfa59e5b397c738a66c0443518e225d46ba378bd023062065c57c507c97431fa340499197dcabb9e0acb6e911f4e93d73f253643eb80e5a0eed63194c69a6a57c9717249001e29fe4284784fbbf7a72a5fbd37577ff897ebbf7ef7c3f187dba3cca6d953365ba86a675ab94f2234225d3e5f55e4d85b30d96d927b085b48e96ab805d43250352032114a9f6127ca6e46f300a8939c51f0dc935d4b70f4d930140afe00a24e950ed9dbf80b0fa1867428190b083b7008a7ca738ae030d836ef666809cb884d4533483f5039ecd25882a328b5092c534f7d7f6e0ae0a61cd25141d0ee6e131d6c34871cf2c7b2a6d25d267459be9da0e549b85915144a70ac42871343ec5f09548f69ded222216d4610ca15275f02ad1726e9001d4c8f4fa5450ef5a390f66a0ae500e37b8a3363a869fd561e687c15780a27a4dbd81df2c2667b02f90ede0528578622f4bf94bbf398afef4ef3f3cb7727fa0fdf1d7ffbf377b7efae3ffe3e34ffff08820c8e47aea6a8628873f9d9c32053218e6413bf92543d9a87397bb747c82553871c95fab188638d52f4468aeaa9fe6a05ae67ae728456ba4fa1c7e1748112b29947b46b983971d236604de8a089e43e7ff2f67ae02ccba66605667fcc6e467e6e4fd9dcee343fe4d539244d2c0cec8a6c9e06eca1a9bffcf4142dcd7d0ab3ec6a4a1f521fa1f67a9ec24cbf5a879d22b56947bad4893a468a23b941b73b447fec374a8ae2b01e7025d49979eaec7818fa694d100d72a1ccbb9863106af22ba438c077502b95d03bc5d4adec2b58f7ed568f031ecd12899da65a8e3d5a29942222b825b4085a54cde98066e30f68c5a2ea2c36335031cfc6b2c55ada3c3c0fc0757c98a67ac3aa5dcd3d2ebf743a26c7b5a5d0d77073d95f5f9d924751ffecb65d5604606609332bdcd73dbbdfceab33a4cc5c620f2d4d7a735c52ec36793fe4b142eac9d55530e1f2d498568515ecfde5174e825d7f6478f679780df7be7e8a61cd3daafb9ee3be43fff6e6cfd911fdeecbdc877ff4253ee26cbba3e0c5eef3d84bc2c67177a8d801d554dfbe3de1d4f26270b468aecd7c8ce4f760fee48425e7f384d64c90d3674d1fdf425ca4b995b557dbdc97bc7f4aadd86474b545c6d7579ba37e347b940b7fdcf4075b31c53af7a2830edda82400378accd14de9feafb59abfe3eb0835dd5a0c5d74eadd968704974d114dfa63ff12496383b4ec037bfc98a6bae663d57813506a26939a7e448bdfd0e2272fd1b30a7777d6c9ec5dbdf9150f9d9f716476782de911469f3ad15552d5e937b7c50893a61be9e42bc51936def67087ee5dd34e424913496d3bef30abc2ee452fd6618f0eccd75ac2caccad19eb6dd8c450975ba7b53d2e4e5fbbc720b5d26f8db5787f2ed9dccfe58a099b79e540eeea63ade094e415929dcadca0662addd6fa92222074690675e7dffd536647cd159321715cb78495ac7e32cddf40996d5b7cdf9ff7c3d86757b69162f1d3544877362a4d51d0d1dc2c76453747687379b37a677733dbdddc9f25335039577de5f5950373697049fb3ac33e98db53493863d48198824bacf2fba79a500318faab482b22ae4ecd68e37d8af352af6d2052528c76ba9b1d7a4489091b66944bd570324dc6c7323a1232b7ce13c7d2bc9eeae3d717bf3f4b01687a7ccc73b0de53cfd6a957df0662a0470945b37ccaf23d5e4c94c03391ed468b8b0fe165af304e57454622929e3f5e042884a6e66349a4cb68a43b99ae359d6e126f14eb6872291baccd0b0435735a725dd2a7d737f6c497620200f4cd59eade3ede4b69c66aebcbc4732b614258b052a2ae3ba7cf75d8e8dc9fa3d3b05e7b64f5e48468d5243647c9c49e260c9b307198b7b426bbd8b1959be69689117618c7fc98d674b90d29d0d2436517db0ebaf9d16d9cede0398823e82cbe566c83996dc1bbd9b882a60e16e9984fa9a7d046bef9b6425afdfebc9540e70c873fd59ebd4aed713bccceb205ce968e1c74f3d29a97b5c24a57f88ae3700b3971911cbb3f27f3925352e1b9752c328c87d238e21ed4a13f5eb664916da76f340b2e7ed98fd65597f1fb32ea97eb57d7268da012fec871af67ea48273c3c5b2eb3bced6618b6c7c229eb6acf955627303ddac55c9c323a04c335e5bddeede4618ace3b977ce52f72444dd168165ccd3d9e393b7d7a7fd69fbe4fa99d8cbab862ce52e401de0243366dde608f4828cb02b11b3ab5e496dfdd564df2a4baa48795eb965902e3f8a93679d8b7115e8839ea15ea81dcce895bec6eaa4fe442687b29963dc7d190639b6f7cae1942530b37ba47e76233a66d658e6f0778bff24ade7769de1cf0ae5bf3b72f3ffed17c777973b11d54fa8035266ce0bc5c27d033da53312341554c451e86bd97fab9f7233ee0a285ee6e9f5fda08e3c3d819532a570126ccb51a2614ff87fcc8117d1e444fa617e0c20af5fea98ee94a061f351f39c9bb1787bc8aee1be40695acd1c24d03e940e2565ee0e163d39b16a3906209e8b885e26b52a67c9d813a980e1a3f5547a00e96257e20c299ecb229f72dabac2511b610b5aafce4ace2af2474e4345c9bdac503d7b0f1600d9ca9c8ae59a87e9490af898cb4bc423f8ac06adbee4c8a741afbaabd84fe5407dc50c4013500eeeb01986f46c5975f083cd91c7c7ff2feedcb8fef4ddabffdedc71ffecbbffef5bb2ffffa879bbaa38692884ad404cf40ef54793593bab9b864bdbf7c8ea030d870b7cf356b4faec25b5a93b7932cc7eb6e77aa4d297ea2466769ff1807baa75006256dc5af1932393765daf7b1fb42bab9f9f284037b0ddd0ca3117275f1434a31b4ccfe9c99bcd541e354aca544be9e4382c82d0fbb6a4dbcee6635877898d483c9a2ec36b7fcb98e75f8546aa8c59b88849fb705337d68e78caf6d4a24430ddcec23d0584805a46d0a64b033335798958d7397530d5dbd37d3538bf14335eb65325b932b7386ccfe5a5b9cdba5d8ec353ba80f162c77cdec1e6b55f65ec8fb4dcbb55843a9e74f5bac47cad31e3eba9c4a9860aace04d8711fdecca6b6ee9fcc524d3387528e6ac361d664731d0086a5f751421fbb2ab4872afc78c6baee669ea1db80d6154af1cbe689d91d62ce2c28cfced6563371d5968d7067c3dcfca31c4d533cfb99420701bb74006ba8392ca2792d7e0ed76ca8fc82741abb304244d4b2d9452979fbbebb35ee9f722733e9d837e6ea725cb1a7502935eddc7401046b72df243d9d374e7eadd0b388674eb6f873f165da0108c18aa75a15fda44a2f4318569ac3e852fbfeec6d703305a2f91825246ebd21d85622d120d9a3d93d0ec0c8a8b9aebe110d5b8de76ade9e2b819f722ed20aa417e401a07bd7fd9284e26b8fc4ad0f589fccbbb691f41d9f0874cb5026298dadd860f4e6341854ba566c48186f267d56ecd1939af7679bd0141f95f54f339a90176f2dd6748faec415723b86ad02538702e78264b1c9f84605b4f665c690f979debf875172ca403fbcb8477d5aac40a6807daf0a946f737fbc91b5ef8ae8d7afdf11d47ff9f2c377bf0f044caff1efde19008f292b3fa609929825b97c055932f17ef1e51518320b8754b5e32986f57140cb99e3358bbfecd8188b99cc8093138092e066764413bee33c29873a356482cbda7c77ca6a103d8520c036de59675bad1c7ebcde4b7fdccbbc02f79b8b288dca86ea9b22db859566f80e2e2dfb99cde5794933f4a32bd143607755d0d17607d72e5e526a183f14493e28c3440d0294aa75da70794e3d44b3ce702ddbdbc54e791d2a614a87602745b43537d5c60ce5c95cc3e384cba64c9ae47832e5eafd390b0602120b33db84ed968aaa37ab4922a5889c140cb4cccc6b0738d667bda06a54af7eaa20641e2241af9ecac8e245a45f2e9e32c3bde703aae0c9fa6f3e49ff7a84fb6384e7b56c6c6898ebeae18b10846a313373b39fdafbd5ee4ddc7059b9a01df48f5cc46c37af89d2e97954f14b034ec4a6b389596ad7e7fd532fa4da8e051406d5ef8b9c947c12545737c2fad8b0954b8ec74933b144e60673eef2b00d529d6b56c31ea6e2cf416af67e7ff6b974d9a4e3060e3dd5999448ad0957f3c6efcec2f48514a65cb833b15d61b5a80094671ce07f3c95d58eb4b35e778a0c162f0c2af52a00bc1acf4b14b8f8de5ce2a966eba8ce1536176d64d4e6d58c4feba543600e4aeeed6d277379153bad291297ae2da8e8617721afaa87719dbec48312d90515ad39c0d3f70b9464429a04840d025b9b49e92a825ef3f5bacbc02516fd9ceca1fe58c0fd5cc0792f60cdec0b642ee488313b8adff0e78423fa55986454eda705a448794c0eb52ebe0e7c0e4d5d01036638ba801fd8e564d6ab4d5b9df81b5d90336a5d7a0fe3dbe20cc6a9f44d7d81c87f4f53f0c53b3ae2afdf7df9dbf7b7ef3efcf8fcfce30f2fffe5f7492efd074a8e8aaa5c560df566e663bdd0dd3753f10dc99454e7a5cf8159a866cc8bcc86aad42a84ade2447ecf0688e07e448d349ef2b2d5a26d97299676811389ee9e5a25b04c16eff6bbcde4d588e11e5114b5649c954628c297f652aa72c4069fb802928636c9f63175b75e687a9de0fce6fe29939b383f9469663fdb2ae4c7266db4a8d8a76a4f7c2a0bc1678146d4f921411d79e672d433c59d9985108bf684d3edabdc9f259bc68704fe271e75ad3bb5b2abb9af19c9c284dc2c0a6e9d4410da29962d61415da456208a16388b271f52bfcd3b02cdc1febafc020dda4f67ea7bb3fca7c7fcea84ff6fc7ffe7f77162ff81299f85c3fec1bab13bc9814d5ca8be47232461aa578d1ead0f85f88a8db75dbec6f23a4ff6cc19b867d59dbfb231efda723a7c4ae4bad865fdca145a80b912df324d84e181adc256eafdda9b703be14819b7bc42bb40e41c1de44be0517915a63491e0ed8386282f3a9cf5720e0b8fda773b0b3ebc4951e3c7695bc6e4a8af66dc907b0d7ac1c6f49d8860b5b2aa31a81ed4ed9af9df62c870e45c057dd744184a7d9ebc2fd645f1691004b2b6e80b07ec3bfd0a2a670d0bf2e57a7f1e43ac69ed0223214fe74744514f31c8f443600acd6d14e0069d818cc88d653acd3c4a025c698f16566814dc4f339b0aded67805c075ab9b8d1f3194a8dd37827df505036ae3434ce5ca509029ec203cb47d79918499129da4825be776ebd825028d11c8ecee646b9ecdcd26463d6ca66133a68ab0638845fe2c03a26a17f2ebe4fb2f715efc7c81fefa4ab7a37ec35affe7df2775e4775eeb64e485f9ab6b3dff74adc3aa615ae1ef5aed442ff1c5dc2267ef9a32d18b06dff6ba995973b1c575ddd8d2f326927133b63f971e2fd6b8b57ee909a6ce7e3107fe06acd2753237d2b9f2886d26a5d8a5d1306f6ddd4d8808cb10f705bcee13a0a7a5ba3054122b14aced042feb00d669867eeda66cfb5389897ddbea56f719370b40a3ee67e38e4da8e441918a2d0041541dc031811445cc7851b8374067a429d2d7bd02be9aff59f888f5145d8d3a74e02cbf6dbcfd7cbafe9699ffcfef6d2cfcf4a03fe2bc975d33ded835c8a7afec9afc4dbbe64d8eaa8c8d5fb06b3e35951a41f04019e42644a23e7da8d5b73f0e6f03b5ebb614ea1bcba63ae5a62a513dab66c5419322eab9abc9c5ba29ae87004d14ce70ad78fcc1d642b59593b0576d994cd260212a681b793cfb01fece0ae35ac0e6aea11d404a40b438bbe037262d2f643aa206272dc726cb4ec24315c038998d944c9883ff49ddd932398053507c6099b1eb01a4ff2ad75585bad48e048715b87815826439d715b6569ec81e88673bc03f4a6785ff0c44d073f99857736981e349c703b33d61dbf163d791b6a23ad5643f9e02235f85323c93408130e330739d6d4dac0ce06a60750669d0b721f2d2149bd81112fb3db04783ff346dfc20a0b16f402ff83674d04f17d36f5995bfbe267f1f0e987f9735f97f8daff1bc2a5b42e506e654ea39a4cf698d4b9ad1be264562bef9f206b4d9fefa37ce9777e1bb7f7accafce97fffee77fbafe3ef009ff0e53e61cdc73b05fcd17a2834c8dd37ce90ff3a5fda2ab422ef79e8a5f4d9a264e3b05af1848b3477743b32292aa5d411dd150bbf3eb72a64fef49b3dc5cbbb042338b922461c82e8ac81fb349edfba78d8833fbc5e44dbe9979922fd6d4c67404012d247beb53b12df4823903f681df5ff03c29ce0de1bc6e541b5e29e127377d62f9cb906e8e5a4b880f0564c9073b84b0c212f8cfbe31533637d94da586fe398f651e575394c36c2de0a0d5aa02032c802e4ffe3437a9d1ba3f13e1ec986079c1619c4287fdf12851b7649e927d0a8954e8bf716930a77f7d7570d86f58207fbcd5316d6d503a63ca6d7db5320685365a15fc7b3181ba3f33c1fa41eb60b10eda597e6342a9d625c2f2b5d97ec0562b9b1dd6e73ec2bae2bd9a623c547a1185b4a0625d6b803d13dd5a6e5033914500298099ae5d90b55177e1731e4bb909ed635e0352b774e0d342de3084344ac0bcecd6602d365b79825d2c62d85db02654972245c9c9e6dfea1b5b685913dcefe23a941f11669388fb3f844625bca7455cb4c5abdf180d07890f0538db5d443c28eb4957d92d22b81e02a328be4d195f83ba0f6b556d82cc2887b871754ad4fad58fba718b0ffc58bb88f92954020bb3aced664a1b96c7dc9b45c94414e5b4582312195c1b7b2f4cd732dc1dc953f1e143f7bf502bf4d389ff5b96d0afae9ffff9ddf3f7ffff3fde12fabfcf26491d433f0e18139639c7b711a9407066abf622a0e9a65aa03c45cb2312a154365fad9c66e25957df3715451725adfd1818a379c53a161a5418fc5f5db3493862a8570266e6867c2c3dc9d3b9755b09758955a8dc9f55ba3713f07cc53c6f7c70a2743ca72991cf79b56bd2e657870aa75e432578168067e857044402fea32bced77c21358265b2c4edf1dcb2f0b6cc142b1f8b6885d7bc99a771a594307dbbfee89d19ffeb6b87c37e75f9fce9f78117fecfb5f36f593b9f6cd20f97733a12380deb51253830b4969a6bedfd353381a822ddf57c45f848ddd6594de0022d9f846b44bba8f274b1e76966a6e9c4352e1d17591ca4241376b13b34eb395a59a6659be2126bd34f99aa767d6f0b8a0a035bb143adb29dd92462e9ee0963b0c6ec14575f77f263f675f1c725fd1208e14f27ecaf4ffd3fbd078cfbd3439eff72fdfe87fff5dfaffffa3ba199fee70af837698f380003ec82e58f5e10cb40c40c268d38e4925f591b1fe4b82e9fb3788eecd942154112a8d32d28effb1045665571ec0e2db12914b5854e5a03385e35149854c979ca1b4fbb3e0e36df68a2a842f1909fef83eb2ebbfdfae0425a1524756d7c7517fb9d1da67c25e43609ea888f3fefc74b4af000a4bbdbcf0ad0ae24338e309ea6e9433bcba5a5500e11e78339ada42033d1ea555d58423a608c0124ddc482f0bfc3805c8fac136803cc3d224f7853101665c9e866d3b50aa999823f3b6b39c8487d736c7d73ec82ba8c849b91c2dcc7929ec415601acbf0da74df26290e6c98d5f31e0a7037fb0e52485753b2b3c0fc6e573c5e934086e44dd29d9490ae8907ab9706006d9b57bb86f6c5c6742d64322cd6cd5e8ee80859c27cd1a885c3ae46968d0df7b6bf012866e9c7c7fb87b8c8e725d4c7a946689429e8d7c7bb07bc00d0a67b700c6f5222d1eb46ff57dfbbf3aeebdbbbfecda2f45506fe16a1fa7af46f16afff295affdf17addc33519e4d650c02d02b10d0b56f2ef3eceaa6e53da2ef2269920b7b328b0aac553956e28ad6b724ce41bb0c9a9675829db88960231fa0f25341e3055fb6c195ca4ef55a62818a14f22f6a05e55837ed094ff8b72aa8626231101f143b79b646cac5b7c84e2d9933550801cb2d653d35257b4518c2d2d5575f1278548d1230c8e08a17d813c4b944dc498f3387f7417947ee7938e951c1c922c7d084fdd8823b996884ae769fadd3c83bdd6efafcd3b3413b242a38739e3ca08b15e0aa6ef701dde6491c2c5033e1354660adf6dda57c7d9ce3d039b4795fdc1426c58418ec5b37f88dc7c5b71257a729967ee5b1e70cfd639ad9958a0be6fa0eb67c75ca86a1b8dedee50ceb6302353f8f7cf80caf59436b117b98a19a5ecb08c9f2944abee21be68108ac1e5836182e8569b7e0f02af2eb2a275aa245a62cfb2733f8c409eb9b5d42fd89bf0abc7ed7ae32b52866116fdeda3ddf3843df67783bffaf5bdb777673b83eb4dcc9ebba4513f19750b7de979fbf5d2cffba48be7cf9eb1f0e9afbff46799ca23cb47a0cb973c0038a620b8887714be65c812336fcf98d7f7cfd9413026e08a5913453ff38e4e65bbdf856c5e7fcf3ef3f27c84ca2dfb0df10d96c0153c2b890bb716ca62d6eedcd8db57a69f5fe29355b7825c6502e35c24335597303113d37674bd619cdffbbf91a6d3ddb0f014aabf767780780bf7cca7984aecf41f56f9f338034bf71b5d8d4fe0d4bc50efbd575f2fffdeeafbf4f6de37f2e937fd332f122866907992d4eb009cd0df027a328dd94c8027b4b4616575df8f1ed9f8ad03545c627c01bbb73df37227387346dea8c6adf9fd93c5887221f3d54ec0791c536256dbba914b444a2add9e757df8430191ffe1b391ae6a292d1a03d2f38d7ecc74c7caa4a132d985409339aa146d8b062e997b41b55bc9879da294108db493e539970ec8589b01e462371c15c3be0fcb1fde6d5640be0d717931df5ab6be98fb78e5a30e731d530c795b23278b9f23cfc0ab5602b4e30c5a1c15f049d6b3fdb9435c6f37735f4b4dbb5845937cfa1194139ed8fde7e6dcef1d83ba1e6ab4513a114aba590fbd5da8d70f161427f087c06ea466822d6f4f0cea909d056f4a384251323eff6182136e58ff6e56ae1836ee6693fdb2586917d88496b3ba5b09aada2b55c6961f6fb73aa85b35ce1d79faf7d442dd818765723bf76d17ad343f5577b88e554bed143ede73d54cf1e4abb7bb4f00635f4e54de7c4f5a677d6a37b5698e39dde19b6a4d6f84607a5b383da7ceda1d6770f21929bb92bb1298fa0d23e85eade320db1ed7c82ba7e9250d0fa8623b38ee39967a8da359ce3fc2b57a9f0614f00ff41f60fe1ced726ad87b20bd24e2fa86ff20b42ac6f530cd2996300fd4155fa411e92dbf9fc8bb394537467675aa79f7f704ca773524ea1aba0746719645da6eebf7ea3c4f97569f39ea4f9fe6fdf1f5faefff3c73f1e5742ce9409c723e41e52d34ef12047b625368b53e6af915d7129a409016db15e9631d8fafff6368992e90e64468ba1f42f2dcce9788119c39750ecef310f96825dc3e738c2947d9097cf6986a504f5362fbe7c4835bbda7b28a655e2746576e6a21d65ed3abf949097e3455749618227558fe86db6456f4fb8aa0fb1f9dc4a485f9a6b9bacc34ee46b58e5431e944d9b9a4c54036607954088c3c5fb27c8dbf1daf2d5879c7d48fd7fd85ddb626c94879be56bcbe1882ea41ce20cb6b64a28cda4250f193a96ee48ce9ccb929d1cbd665aba784273b98604b532059ba6eb6fece397c39e2b859a5cb79b02ea72f1472aa43424d61bd5b2a6c0b35b21c12d6dc640a5043ad419b26464a8d9574ac5470a85daaaea7af17d045be8a9d36533a98cb0db7b828abad1ba80fb7e50250d62dcf2d4fe6345f47af333cc698e29a5e6a1743b17e59ec3278f9ae2216a489085c34b5ca6ec10d5f6872ece09247705026536b26392cfd63f36233ce5d7999ff630fa6e86d1c4e32ee0b2d15d0a33db24c93de4c43c6f480f675608a5e1d5a664de28436ea190ac034a483564c8fca6ab36ae1cbce8db11ca8288cbb45fa16a3aa42fd964162f9a662a812a874d536f77d343a29abbdb4356ebc424a6cb6e776a13c0defc589c8392b6ec4311181e106f3849adf9c464cc4426aacd4a5f198c66bd6233c6675f5157a6096b980d1a8521869228402e67c29f10443737aebaca8803c08dd84714c450ad0b12f00e9d8f32f764366b68eb4b3299c04b7ca025e54c2561b189d31c3c392c80856d8366a1609e74d4240deaaab8794a883dccc5c4f3d6138429dacd277309ad5b6d0caa4dbb6a5fe5fe65641b45bdee5b28d66304dfe3f436f229505cc3938562aa2324931aecde2f149aad3c5390b67a02a0361d78c9458bc93fd2ff401ad93d0b9eb4bb5c6a28e5c8e89cde3d9b1c76528feab7215c2e9b20b2758ce665058d50a890ef1597c124895a83edd2d83fa7a27d240c7f32e8cac4a889cde65331ad6643390398740dded1b092b73960b68268e88bcd13564924b9dfee28fb3096b70f6c61839d118af2a8560bad783322cc5928deae49a57505a5a399931e43eb7e98a9d5d1e8fd3a3bb813a6044c2a4ceb12b3c6063b50111355e582b67c57f540462d337a6c82dbf4f033e3df4095cede4a1f243177506b32381b451036c5a4de2ab66a4cd9d828af905b88f37f579b767ec8e0e9214d9feaba3fb7242db3c2ca5fca308340af9a318d953421765e10c2068172c02fbbf29e3011468a68920d4888da5e503e8e2569be4d48ebf0d0ed2cd7ed43645a915cb66e77cce25cec75692282c46e0a973ab0423a3c069a2d8426bf2e01a8105afa328bdd8f5e256a54ac15dbc13cb2e94829a538f9aa80280058d8538f51c861c0743b8699d019ea9754ed6314539e26ff583f05819de9d78a845ef69d1d80f54d2e39a51dd5a460735946322bd13aa51f103bf4625a2a0ed9c60914e8d26c6568999ad4b7d10734c516bd9dbdb4d0b29d7b340f56620405c53e44d832c215400a9b1525ac1672f9df008c988d504c031d8486b5f28add11fb5ab64080656da0ac9a64b651507d013a6ff12799ab6198740022cb6e73365b7ce67bc921135e29597ced0bb6bd0c7c517ed9626457582cf72bf91940aa6dcd6fe7780ec97ad44f1a18bbc9c4504633e26ab96ec389d1a2c20b3b937abc86d4bed4509ae345d7cd382ea154334fda3283cd03e483ccc517084bb23431c3ac13cf0cbbe2f156cc25f4a18cfba70e604caa298c23814182b568ba747a5ba52de344e8e1470731c856a1ad0d574c9a566f138dc1057ea4d81064313dd36d36777a7b58751dec6708eb233ccfbe98c3664e98af7e98662d4cd66ca339e8c5823501dc4f6e903b537a6f43090e672fae994677e6914cebde5c7d7669119258d695d35c9250c71728e41e3c72c9410fde4d284fd54236b34580685834a1414990eb57b3c50690c5f6a87199b353402e8f3609069eb3900d2b343085c2a63c7c8f21b5fbf304d2af0f9298ebfa92cd46e745fd93598b61ac0303c8fc4d7025ed59cd073427dd4c60e205a399042d13d1532376a7ddbb37698f375b6cfd5493cdc3dbf43355651f9a7597b6256f92c32c0ef03bcc209e9a49d64513301744a4694a749b29fe55f6d1d69526425cb5ebdacdd98ab315ebb0ce3a480873073c48f60108d26c7f814136576cca2d1b381bf82f082e5e1eb687adb4c48e9e3d9e092a33c39831d15c65885a244bba2d5d907b7a98601a341621a53fa6cd17cf7f35918fb63c02b46695555f6c4258a744877687f21bfc296629d231acea124f6cbd9587abc5d456d44817d0a6cc7cc718a938ba6617b5205855c78a8a66869a39857d53b4d15606031b6d8151418476c2b5d841f73a54bb54319ea3e41678f1d31c119b3f85427e5bdee8b01e365d8875b7107e808fb787a317adfb21763433f4fe9c85c8980050ccc924d389605430589d309aba19271eef6360d4e6ec9b423c257d81833a0940462e632fde2c676f3a1874f650cdd03191c4793b16a0e6a64d0ddfedc56c496ec78c52eb777bd982d04befd90c2ef341c418dab4a1a0cb7979886bd05359e86d22ba3c8386c441ea256c4f7389b3cd71f3f46c6e982bb9e45014672bb5da3c31ed6ed3d894fb53c9392c7b3653df765a6458f361e014a52f9d22e2f2304c965dbc8e83fc72928e20f04e7ee1df4d14e009c9143b8b7bd0a1787b3d7d91b8b297538cc543eeb4796a747dadb6643352baa1f8107ce6ba57675ab6748710c72564bfd5a644020c7ac9909c430ad26e63509e57c932a95d53cd948137bfd9c353694bd37454eb18ab72ec22869ecdc9b9584c548ce0bb69ed357bcbc05061b4846a8a83f840eb0fbd87cc98e5f088234e9f08bdcd650ea1dd5bfa5288a4d98bba5a2e89b9ddc96c1d14a3f97c4c1d505470b8cde4b4f581e231f3cc86d5ce0f740531936e7ea569adb307488d5a9e68236e40c34e07ec3dc85633f3cb8e3061680a957954267d206b841e410ed87108cfe9c514d5bd1d82edbcad5611fb32b1b41601b86dd29dc98c31dfe40a9aa72498d7aac95f71813e9708139bf431d81d5a1715f08ecc156d7de3eedb19178107ec85c46da29c5cd1180ceb660677b0272d1b4fa01f40629b9db04e6bbad9edb6296f2f0d2f624aa6c848c018253c12b1a86106b5a6a6d3c691a91a2ed5f131f1e33a264e0fbde208d613b4aa5a670c745b16cc9ddddce041271d54c15b30d7caf414a6632e6ed1678e504702340703d9060ed8271b1719d0f8e9cbdc2a3b098361e28fc7ccbeb840f65c451332f6d5e114db29f6f43623018fc246ab6dbf6e259ada8e4ae4cd36f3be6b97914bfc66103d035fcba643216bc5468d9801610fafdbce0561643389296b06db6006995d6aebd3acd60914fbf0983ab9873cfdb0355008e0dac0746a41861907392b1e681fa7cd0d276ceba98ddb2919673635479a5a365b20d945f0acacb78b8c8744445ee62a1e522270c9e2205702c18010318707e1bdbc6c54164e16cb2a29f126719bf4e4846dc31c27c0ea23ee35b7103bd80e66b0d47187c97fc28c92ea51844a4708a738cdfaed60d82fa4f3c0a62003498b7a056ae86a0ab51178348994b6710360b73da199c2a7d757cd301102df34bf9dd8a8c9739b3c55c6f6d43b1e9b790009ad5585c1e79bf02143bd5252bcdd547389bd2ca6d87df15b4e4dbbd36a126e29a30941371d80539391af369570c786cd0b9b24855d17dcfb6c22b2efb52a8150a6cfc4fc346d79b4da7c88587b6bf81049f8c4cecaf767e26bc5b761e62df692e9962c3ba876676f0deb906d5b69d99a90f78c410ff54c2e10ea42b72f4d3c4e596858cca5a93db0e9a40300384a3a5d6ddaadd8a287c76cb6c88799caf45cdba649928a8bcb7e57147322408d5b41f027a31b737a315d8964f50a1a4e33351c8eaed9ed01246c96210699044fde8a2c62454eeb235b250eee7ff355ccd05648616bb3eee2416079989d900922d96a59838811213e8f8f202609b379d3f4699a1c675071dde20e7ada9f8869142dbcc899ece496e4e335b3fbbe10fc717a3d1db9428c311dc81b9bb9d6fdc297239098b1f84c54652f83de67446765a9624582019b311bedce872fe94b2e8212eba74b4442f63a243655afd3252d5a1224263b656612669f2f3ecd7268070d52ef41845eec6c2e91c460abeafeec17bbd4d3fc7640f385a0693dcbb253d622fef370793bbeb9856e6eaa82fe953d2aa241e0a2da729cb61c4deb78f3cfb9e901c200f66b4be6a4cf102b9b59362d6dc19851d7eecf8401d1e551b784acb7f93f838857c4948091b7ccafcbcd9eb4eded51cdde851be104b63b706643f2459bcd3598515f118935e3b324537fd5d519e6178a0a05ca26ef0b5963d6df51253c097b8bfdb79a5030ab1d475601b63d6aa1d818c10260639c163bb953097f032bcc7c9048faf41c2f62c9ac04fed84f58e9feec4d2413b234c3cf2c96c99a03c52fe1384f4945476056b39f2d2c824e2588fe8734b89d023f851a614df41ee35143435ad9b926026c86b6eecf196a12eb9eab39b7084b401dd309240b9c3b1beac00a73c0b777205fb70fdfdd7e7cfdfa9dbdc79797f27b95b59759ffde6dc7e84abe961a6c5eb6303fa6955d9df19aa8966e3077997acf4ff1fe5c002399f14a26681da17c4c26e1e2042aaa847481c8fc4afe2d5161a064302d4092996c1c01cc394a58b0fb5e01db9a024ec2fe201c34fc4e671942f085a1c28776f3e01f6652d8bbaf5d7701236cbef6d06cc13e8d1ec6c711c126cf975c7f29314c23f3de88ea9bf707f30f07083e194bdfab2b7d826a5ddc8c1fa3ab315ed3b2a1a8615e66befa095ccfc79ca22b2b02c60e4d7195db0fae777aca2bb46bea7ee64b29250c48856d4e8ca7d643b9261882f353fd0516f09797f28d8e7da757fff56f7fbb7ef72fdfbffc3ec4edf5ef47f22d159a002ad1a9a6b00909427d03e2beebbd91e96b1e27b5d53452ac2fe71f6e7f7014f1268e297ec0e5f61994b4d9a2b005c8c5286e0e9fd208f343992d0cf4872b3986479dbc7b53777f32fb7f5d6f7f0cc19f52334864caa5594c3c037147596cb315498dd2f2e725bf39ac8f917a6f701f5ffe7c88ffeb3ffdf0e7fffa5fbefb3f3ffef0fb4018fc0368cd8592dd5c536847529141dec4cf59e5f8666d90a04db4c40f8aa5306a5cb595a0f470d598ed5654d23d487895587986ad145c3da1e0a6303d341c66f63ad8b681e703e7cea604cccff0cc89e1790413a14de89de690d9cabe12a0c92f7e5201a14c7cbbe4813e279970d332061305a0dcb2d5c5669ac9d3ae73aa1a2339a2adda21a4ec41be34c7024915a61b21e9f81112e5ca245da5237ab3c71758cc278db679510b2a7010cf54fb518511486d047b17664281fe9761a8ae844b55d45694563f1cdbc582b42e617a9157a327f60eb75fda641582756278cca15705401588e27e9629fc289519e863b011ed62fa8a1abba2c4fc66ce00e1019c3f0f2f3c590553bba79e73ec144e0da0178cb6dd61258858a95da09cc63a13263a57dd069726fad29d2df2294eca3443a278460ce29d641f9b06ba555d6a01cd1d5580e13403c93f05074348b095a94a4283cd96056e30157042ddad7b8b97ee305f665927cd508fec34dbf6a5372d3a81eca67020d30012b88d7197a8a4310f6d6a9c00c1e21e06056f8c2c12874b0fa74c70b0bb99f474bc3035cbebbb59ac0c71a70226ed04db3d3ea4c99079aef7bd9ad626574f5a91a93007da796b4be05bc3e3d734252c36679fe4a23531efcf66443422b18717ceb5af30e988b73f877405e12de4db18aad1e4af2391b101d9bf30c2f7527430e646d776a1d1506b33fee675d67bda07be47c1ea10d20471a7857e638fea287157219a77e536f20079142235b6494957525bca57e3fea9442288a4002a32698699325e964d140775d09e6c8dc8142388f401b6dbab6816739e2a9bbeab6d04303785fda9ba2f61770b6158e8a038a0c0106b6c4dee34bfc49b2bf8702a0eb41a9b301306bc143e471fd81ecc040f7d0688736dc27ad536ceb3ea7127861f9a20d30fa4055361e31cfbe46c4d6c4ce4b92792cee4f7cd4a144e370082494933d86b57cb531e659396e906fee28968ad08cc406ed0c7833e46f9ebbca1b8e2f61a070e35a45d6ea519cf4e9b5dd8090ed0eed4a656c0b616e4ba6ae9f6093622381d21681b6412225048e6e6754be275d31bdc6bd1ab3948e57c8c2dfcd854389fb67984ba693101c10b74a7d23d80f2050ad0ec46b439c68dd093537788183b1767421134f80876fd55e549b6d2aabb12501418d52b42bb652c7bd04b28e7823ac749b6a5b37c524297a94fbf1556266b92bd51b70bb27038952b6213586882493abb33c9fc0eb673c12195e0925cd9b42562d9a2bc07dddfe32c5de5d884c53388edf4903315d019bca8b9314d30f3406844ebb5c6295bc8f7e7dc10d7f8af9051b11c9397e866e708cd58378afd7ebf3f03e460f6bb8d5fdf55e57e77bcc7d3da5d1cb7594149b2e6fedc6258f929f6c4fd66c2fe287bfa8e0d895f545d171a97ee7bab4aeb7d33f6b192bce08799b2eb54e460d1e9d678aaec842a9a42bd7f1a2a1c6a611d40fa57c12f659fe67e5f9298511c1bc9e7e6cbf0b93d95abcdb7193a40cc4f60099332de3f97da3f16575a0dfd008626ba81b0b749da59760b1543a4061db1c437dd5ddc7aa56ff629d0a218245fd3469d39324f8db13579370574230e82de66671d022c6b5041b242fe5c126c05d669453a13fc2a5beff35643bb986da455867d431d263ec42e145387942bc5eff9e6cdbdabe2fa866bc43e4b35ac4b23f8bcbfbb0956a0609ebdd163e9a1c72e33bd3d152911cc4b2c5bfbebc0a937458ebe586c69f0ee864252c37e6d1f9851bb54b2c397ed7870729803d21a04e6f6e64a0f02c8b385c03609d8a2105c26ecee72a524a6779831521857c425354241d439170f467512ab15f1070eae61f163d71bc294a1145d41be546a57076c2236b69992538013240f90923b9e6593a5dfec2e8105b0e5cca64e96d1245ef2b1e95d20870bfd0268598adae1af020896256af689c3d0516d1c890c12b032a29caa77807b11042a4c253cb2dfb924c3640a1add913ce2122c232745c642bbe6ee0be9526ccae4dd8ae275c8a19f40a2d505a9c6a9bc5c36416cf8a5b03743462edb165199d8900982334452c19055a3afeecf19c099b142bf4211f1b924c6eaf0db6702801570e6061a3bdef185bd886d6eb5dbe861314e108214da04a76ff8e1173391ced2db0a4a8d0d57c5556aa15f720ae5e6670bf9aa1f8af2c016ff02b8b90877b6a070dff4c6d80aedec0d55763119ea9e1c6bdb1c604ccb7940431469cd203997f10d857a818fe9449ebf0d726d7eda48c87eef529cca0a0baf3fb0c7a8c07a8cd7a1a83f1d0a78f69a86c2cc5e7dd5c858ac4a63232fc8846ba1f384f45cba8aaac5dee18b366d78345f321c20e45e7f2b6af0c6f97f276cf0e6db6fc40dfe6864f8a02951c48aa70cc1cec984627ac30cb4822c255b948907a99c5011bc7098cccba84bb57a4535868982c125f79ff4dc934265208ca574864a2e0192c1be66afcf34cdf059be05521315e17a728219b4011f9901d722b5718782c7f5be710254d99b5de6f4e69998a0f2b2b980170e50cecabb37fbb6c6b02b25606f84dbb18c8d02804a928943d0d64d65d9efa7db8406beeae8b54de93455ff5ed8cfdea4624dd208b6f156c2232892548a69eb42c1b600271c14074156b0ac64d9e6c28e332b6560d435417a9af5c2a2e4952db5e23149823661b290e77ce9a2c2a968a9cd376583340549501a1e2e513db61d44ef4f7505708f3ea3ddf2fdb976a487797a874f3b23bb9b09037477dd4599d45c4f108a3240eb1243d4ef4617c800eed0bee4b57dfd064651da612292aac0374dc441482bc0faebdb03237d1e8b30bbd46cfcc166e478fc1a52da2f76668887cc85d886b8240936a8a028c1b4c393c5024ac25948f2ea101af9d55d079ec66f8fc01e87f22197e55ae1dad817729f841f6eaaadc19eca30d86f2b281743c845fa0fa04ec7ed05e106caea1ddb5dc94a9b9c8cab49b56ef6d8145804eaa20c89cbe2da54892c46b5dfe0e1aab34f9e493e25c4e9f5ed86c9c723a7c11ce896368d98a74a9a9062db0a0924f4e4867c1f7ba96179b47b91f060c14a8542288067cfa2c228e227d78423330e7934609b0e0f92a075921f68982e753c5d61bd023e6af38d5265b93638355cccf49506437e5a229f6912b3994c9722eb85820d6a6614ea8497b631e5608245cb32779af041b2623cf81f27d67059039e2cb3c38ab81c89c60845bd34cc696c9370125f110382a72a43390fcd6d75759c401a5d237c0a53e25c499fd92c2e53769689e1ea61424862395180aa9af562c7f4d3fb43c813750194b18076bc6596523c8b8ab06a97b0d97c689805a234d3ad0cc5de856363f6cd7219ea54c0ef96df802844471520e966b30ed9951889b648b07732cac5ba1e1ba7d9059a4d9359b96d7934900433bcb9b0abb66597a0cb80a9b12e27101205fcd21d2579d6d7cc04ebbfb64304ff0f79ffb21bd9716d8dc2af120f90118839675c9bfaf97f3e6c14f13574c0867bd4726da5e0a4cb16e5fcb6f3e90fe618b1922c39597b6fd529a08003a97205d77dc5755ec758b9870643caa45d901865ecc6b074fb28a7f903da03543c21dc6720d3ce0c040a1a445771fd0e3e43cce6de92eacdda82a20d81d626b46d42b1189c695d4beb61662ebe2d88c0fd38389f30ce3fc22ead9767e9b0851566281b496810421295942e80020a8500618dec83247755ca7b85065a2b30349650d672d431d569a1a45d89a438d7420889cf279068b405c038145ae455a04d83e1b5ed0daf3016753426347e6afd88658e1d307454fd235d07f81d9035601b83f6a4ec2160def1e66d916b30d772b807c7327c223e03f9312ef14aac8373b9e15185860c9718849001836b6984edcf200b192b1aafe602f588badb7506f8109769c917491ad4e9d55fb7a56d989077cb345d2206215c308c63ac382515f21f740a42d07f0c4e011a8f14a640f3a9685ecd34d04813e20568b00a5cfbc6d27c7be81c2a88c34d1d97408e5f68713b12d020b21078af156b6d5b5ebc60c8ab33726517a1043e83545ae70d1e720bb5c51d7f1a5a3f5413330e60f5d5ab045f88c3d5a2563979a3cae0b3f589c6c72303f2e88da22dd63b12e02202f8c6818d3b6aa830f3369a6d16c2121e8caa0c543329210904d1c69e41b3b9552071546244249ff2f7ee67746900791be1cda485f145bc767258ec1dac11a4179f8bd5a32117778150f8c4614a010b0139f3f2003a68e993caa1c549078252bc024e231f0bbd1744d18d84e608f38e9df637efcc9825312e3b565521bc216048480b89d7a357209017bd32abaa611d85293dd842d968e84e423530c3a9b35c330528560a6292ba30b7b04ab4d559179631166dbf08292bb12c60408c3323180841c61b3c847507ba9c248b6d89aa25727c21c7c13509e33d5dc2d434fce59124c35914830333b1ad2ed9c3a4236a2c60735ecaba584231676d5bf64eaf4759a394b63738dbe856811b92e631194454576468e1ebf0a69138668bb64c765a515af3b05c7a55fb4752000f5441a82c733d464635dd66a0b7bd027b019e1dba5583b291311ed091e11c73f909befc50de4e0a332ca2b7e6a21506344df688ba5f098879ad789d88937db91f3933228039be6a7cc4ae1344e3f9f72ba4493674a891b4ac706b10bd69ecee4b16609151267cc465bd51209321cd8a94b6f0686152f18917ca21262898a881538f1c5c88da0aecb5423d75cf5b8334d59675560af1d8d8a77dd99a4b049cbcc392f020c22eec99c990d481996841e255ba54e82436a28c0acd9e951cd5989914ee6432552a7d33c65be2016d19c1d0d44c760c305efaa433378a9b25ec620b27062461c2218d402188ba549a7c655b1a3415d61988edcfb904422f742e64d22dbacabafcf580d2f11bb3f31a2d34507ed6833580568238c6f06cc187c7d7e8e48f83297f75dc359e816b1a16d22c6aa3d03ad0167c3ee77f323877f8c98ceba3d1c78e21a73bf6abc09756b86662804d3acf40371cb9b72d76004edf1451fa8e3c482a3df8a40d1e4424eb21bfbe067af581ac9a00750063a02800a45a1a40429225cd7112617c0527282af6cb109e30040624e12f1a8fde331bdd30183dfd72fad7f327d88abe37a48f39d2b483b6fe54462a07fc64ff0f15e09d4ae51f588aed00589c520edeadfa6f685939f82efd473e78df6e38340e5652fbcd0f98ef28e51f9a533d64df2fe8117dfcdfa67ab0dc53e93f949ec40efcc5b30fe6c3eda0a31c5c60b0f5cb63afaffce7877c307d2c23df97321e4dfffc60bda42e87926b52f2c4c8a30d49d68f31b5fe0f482cf300234eada90f16013a70c83e3206d26de5698ca4f3c05f7f2ce4cf09edb9fb7d642d9bccbd9d2e828ce9d5865bb9e0ddc079a94f63a679c00fee7330208cf87dc63fbcd6a08de5e915d0753d3ca7d10ffce5453a532f87eaadc13af6e241eb41faa3543bf9c74016cef3cfeff5dad76e78abefbe1ebdd5835f8edb3f7ffaee806a4c89a55aeec517a22d4217cb24032970ec8048d1527d2cda37b09ad680fcd65109fc36ea517d19dc782d7692dd07a5511ff387eb732e0f52a13afb0a8900bc4e5bfcf2d4a2e4e2f4a3969c8076d27783a82983d971423d8aabf21bef104c196f630adc8cb3f8f278c21bb9347d8fa7be3b1dadd6b9d9aa3c74a3493f9e7ed97ef9f4add0e3ff789b16d0223510d663e170196b89aff803e621843911af5a96cbb844063fd18c3897768a9436ec6f58bce922c0618d4c19872810b9eac0f10e6bc90acb1a916b252c188ca0c271dad77015e3c63a95572c685008a142de977147f03e5d9c3e218791cf569588ddcb87058b900645184aa56ed7e0d587f441896f697bb61cec8c8e5b2680b9ce846727c85ad1715349f5e8cf53c2c79665802a2396f138f216b19203eb7530bc208a5e1e8ab450cc5f7340a7750d3efa2adaee55cba3d6766fead76757aae1e2c4d128ed28bd9d65ea51e6bba1ced70e78abdbeec76ef5dbbf9f3efdeb2f9fbe0d34f757c43cdb80266eed5825f5b3baae77048bc4196e8b6d29b4de15211b4343a19b1ffe92155e089319705584a52e083ea2311857773a14cc05b8f146a2d71df1ba97c530fc28d62ecfb141986d027f3020a601e506e1c9a0511a9532a4ab418f05ff0b62a1188cb103f9f7c8bdd71fa87244cca3aac11b6a6a9707010feeff27eba4bf57273e35ceb609d1ef39f1174efce7854ada29b1fbde8803f7adac686f5f6ce88ac6b147d1b5c82060b3f0f4687ab4519efde4fb56ee00d88954d4a98b8165ac67596546048ee37fbf72c3ee1c5a89eb586c653dcb2aad9223626f6cefe6a85c87eacd11be8edd1ae12f7ffdfbb7c2b01d7f38265b337433d113f8c26da4b28932044417e8806bf9f4b519549dc112200e905f6ea07f8a88db26227c041eaaf554eeade98680928ce80c0b8d14b74943afd0b26028efb1c0a4a6e416d7d0a85a31928fb63cc62660cfe559331c4cada7be47fbc38c8afe0e5e6523f67caf7468c13866f4bd4c98892fcfa0d84026c73c4b1bc98e08d021c066a835d57bad79a37b67b1bf57301ac2583b76838aed9e474ad00878632009543cc6686657db0a58128f71ca46674a06c0dd1504af4791f2282dcdbb1c68ff80a21e921c876ee8c0c9961f75f9c950b54aeb07204e174ab405866f1a11fd9441897bbca7e962c087e3e3380a02690769bb04cb6a9fd7a2f80d2ecf5120f0d5766a25e84c800d808901fe23f539acfb00f263ef0f218c859b0308476e0d9ff3f726d2798db870935d9bda5c4e1a707f74e2cf594567a828de4f49d9ce924b2afde83db16e46c0489c2ec882bf9e1ef69bb9d00450fdca92eb54ed1cdb4cad6e3165418c802cb45941c4b5f1accb43c9e032d17b1f597798bd4d43ca2d5457eefcd9358db3b59cca1d52bebd2434c9fa9c821159463efa29ba01542564a2c2c2a830e943f31d8f7eaf0dd9c6045f61d8c5a2b1e139ae67c05a3725c9e4023510c2d904c96e08cdb60677543dc279f4285dd31c473f3c7c06070ea3ff05ff55c1c9d671c938a50cffee449c5e763d768cd4dabd6661e858d1a377e08e68c5fe66bf80737572ff31364d0262d8240d809dc02b1aa9da9e8d3b539b8f32cdd77b640d239b7da48af1bfaa11fe9b368fcd92cc13e059fd01eaaf67009d908ade430b784ebd82b10ee056cd105c5500f88b474b2969f0034eae3b0bd06bbbe2a69d847dfcc0814b4a0323f1bb5946ffff8fe79b83f07c7300fef2f4b7df9e7efd460996fac7d38a34bb2eac2726424a9f4ce00d33d57bd37c06d21e40eee5c4a018b09cf934390a58465cd66f61c0caa87ef43e9f23ee3921f874c62c9688438f48953e4a6d27e4cc4caae53d8eb221026c30d7058ff12bfc25a6bd4fd6ff5ab7b75b631dbcd128c7d3f796e4a5368265497aac23f50f2633689763c45fd78397871c74689ae796ca71481a272ab8e53e5f1e30e4fdb20d02408e8d89a8b0f6d6e5d075dd6c85bd30d4846e43fa7a19c80373b96f5d3a3f0105d6d7f471f4b9413652e2613204969dafccea528391f2f8f26cc23c9a7902db7bb5543035e809f4efa0973ffadf978789d8912ef7199f34736afb275d9e451861b4c17e6f503c171918edf08571f741974310b025be3d969ada0bd1f50333b45c445bcc2c30c0102a365abd272a25a69fa0ddbfd3cfd92a8523a60dada8f1e92dc076ea0656b055fb67bcb0a985cc162cb9bcb6e0b6b07b7537c65f4b976755752165d6b3dfe918674e7682c301b744f883bddd77df4a7ec4adbba60ed96239c6fcc8ba0b288b5eef12a5213310f9d06834cbae7db94e755265dc4fe3cbbe69a4fb923f6b433f7c79a6993d277b2141ddcaf1c277c2939ae19411c22d30aef0384bb2d3f563ee8b7e69601f4fb746f4f1746328fff2f4f2f74fbf7e1be2cfaf300068053892d5922a20cf40683c20434f5f5d3b8b3f7600b41429a1b7500026f532185507ea29167b2a1b733104eebf5280a3de227932907f0e72852859184bd1410381d4bf8ee5ac84e2058c921e10389b26d23a22221123f073199fe2579799682153906a54dc27c3e36bb42621d25b10ca03621794c8be2e86e08b1e04dda7c011ec6a0f1cda19962bdc2323fd02090c05316cf8a0021feb581c5fdeb9a0c9806a6f71856a9a2f71c03de6e37bb4e54ddd2202f2c6440dd605c6e1c577bbdbea43b7fadc3a74abe3fdfcdd599d06dcc15d93dde7b3f492cad1f58efe386168397b5fbb3c7be3f8d8ae39cd739c9aec68398db3972ecf3a61bbf333d62d7c99392b08f2bdf858a4dd57d1473ec83a52ff06f436c32c81bbfddb8d4191ee5dfc3834c97e434de2373cfaa5b66ea95a93f0e1c0e2e5ebbcb9d9db47d0086f61c2ac64e72ab029d9e36cfea9fec93cc08fe1313ce7fdeef0f34d23c52f3fdfb24ffcf2f32fbf3d9dfef7f6f1e9dbf8f3bea63bb83a2269f852d5cfaea1b7fbd12f0f0af88ad2520391f4fde86720595c9e4b838dad4d9fcad562f74563904d092edd8ae9c87fef7c4599b4300c172441ba535d6a9895ce0ecc4492250a88335de3f3a12dc40ad8e313607d46342034fe2b9280ebf4380d1400b8ced5f171f6f64ff65873d904818f2e1321f0bc220a10a198a648fd46a7b3a026e7e8a2c6d17fdbd97feeb5b673fc6237b8b6ecedee703d7cab5bbc6c9f7efd3650025fe5e1ed49a5052dc664ad9a9ac0e55d61f82bd25c2410b9fee56d64c05ec46e867eac324f79c1d5eb8ff0d9a10d50f0a04de24d81bef2d9035c347195f87a872dee17c537177dfe56fec8de5bf8ec99e1f633e39b67ae4724ad887abf7e7afcecd3d75f34ce564dddda6315dd622ba94c00ebcd89b0d7d11002263a4055d55dbdcfdd5f0d1a4e23144dbbaf9acab803598c86e28233d8638a8e94e10ab239d228e3914fbb5bc432ba6f32e09247c8472b9672b92b5a92bf1d3bc37ee3ebeb5e9e5d349cdece9a1a78167c101bb0b1472b58dbb58c77fed49e5a19b14b9a864a199fff01a6e151424979b6ad00894e2c99a82fc0bd14b82d7fff576c390d419086e984414c0b8ce16635ca94a4061804757db17484b35704be4806aa8096cffe7851c15b6b4eaa25b49e4c11015dcd85dc5401b1d6f5255af56d4cbded1f824890b165a6f58d56426b6948dbff5a35c2fc50493517606e6ae8833423690ab347f1aa6b04494f5261d1446df2b367ea3a62818b3227cd9f9583a50e30c566aef74e6060e58a28a53299e2ee6315501f320725b131bc4e455b70eddcab78786bfb0f9099193605c38b4c5839cab5ea60cb24bb599a1391c63ec02da7d2bc62db0878e3202d8d09e0fa6eed777fd5966a279e34aac4acc555279ffdf5fedc8ae9f1e6b48a23efcca8fffcf5e5bb0b3b007b4c30bd5bb40b0ae9372f623a26146b6d21098c83dc9cc0aa13936ea28b098d7cde19e1eb8c19554bf3cedf4c90206510cd4dc3fec4cb83f77b1b059e3324bd75c4db59ac6565917c80d3cd26b4bc197b055a9a6bc342f4175b61582536303f03ed018ab3f7019fd974bc78b9c2a0be76ee7fec677db1a1bdd5de6b6a3f76a3b13f6dc77ffef46d5a5afe705a9d4df8d15b76d1e151666a1faebb2e0f964b90a967b1bc654c273e9990448ff480c6f2fd6c8fa3a4e12a71df308d20db0d8426c0a73cc751ee7445154ad0bc74aa3193867c9fcf55f488bfee4c5d44f2c9b664efc6c84ac83998b7f0a34c3dc6f97ede23aaf956d3e0c0cd76f9ebc75fbf37db991530e75a8305aa2539c73a5339a2e8a5cb738e9acbf570cba9e3e8a3e9e5b9c3fce993f2bd353dbf5e1a792de44af315555eaf97758a17710b09f9bda3da11a59cf346672d2cfc9dd90820ba13e41e20f6a4104a0434fe0519b5c447600603b19336662c231f488128823052a8e786b84720b18332208810b905e6be7eafa9d03a5833b23848e5340260ab8182d2e90b9b6122411c29410d41fa28025c2c07edc8f160141322a8f34a212d096bb14bf4c8822f24d321dc505b5f1de072eccbb28cd8d5cb73ac7859ed697a55fe7b4b7c56cdffc3a3d10f7fa911df1f237ffdf8ebed31f2d78fbfde1823bf3efdc76fbad483efcd6f0d2cbe3950ef2e1f68d2732ba91f8158b01948c56b70add135a5190441d182587538fb1b93a07c4a637438dda14468290c9c579e37a3b4066c776f0361f22e485f0b890990f6db99ee83e0a61905dadf58d4e73d11d3c610178f7e252e7c74968ce81858ae602d43893d14a0d2f4a655a42521e76c10668789818cc1061a11122f900c1391c508a06910e718433f46b2c0b013e453645f2fa1c3bab07c37ca1a07c204059b0da115456a9a2703e4f76319be4a346086743995ce9c60101db07479f0955e11885208c7e1d514184b8f9c084de585b1f592e3ebfef5c7efce2484ccf5cf0b13c3cdb5f18de04bf0f774d80a774edc01fd7f32b1ba78c3940c3845bf0b0de844ca2a714ff766d628828411ca1a4a25ee5468d04e60be5b509ae8c0c8051ac05b1af0c579bd82b493b475e0ffad2e5c2029b4a5feeef07c3bda6e8dd2b7c76f0dd65f7efae9a7d3c71ffff1cf6f4628fec745cb89907c1d493710e422dc1e09ad4826461808ec2548149941c702237121aecfe88a4c8fc25840d8721149e12bcce5c1185458cb066c04844fc53e0969e1a31b190679a59f01566645b0cc50250c9f87883383dc7d61926897d490ae7a791044d65a2b5bc90b9a320037d2806e6418852382ea4a72acb683b0c2c71b6be5681a71e20590b892070d45edf20cd056dfa11b52933ae31201f416b99058d23bd7905ad06afeec02895cc3e82c02fa971c3508c441520ce2a0561227a799cab50ca3081002130722523c05f93153d2b83c03af565ab20d29756532175ac2989c68aa8f36e09df505aca60978012d54f8516539ec84812146c2c35101fd372ecfcc22f4f57c636ad0087b823f4246b19613b28a09a7c80543641052158dd96b98d59b2c3c15de9f49b393620322d77aa31f68d216728d54d5c644d915361acab82f638b0c298d2ba4345e434a338fac9dbce6f318d4b06e16ca40305e90deb61cc760648c4f4979fff7a31f6e9d416a5adb0bc2ffa4e5b7ffe2bed3af787fee783bf86f4e1e6f4f787ff6f8de0cbfae6e8e3b846b550d0462ddcb0b84157fbd016205cbfa9bfd51cbf8d15c0404902bee7879966669f6205292b5b6e94c35633ce71550d2a6cb0eb322b064805ac0ff8433789428a97452140b62a81a68fc7aaa59634b438677db8a98c65c48be30e002b6c9e444e9a4a929b033a844bf7def5843fcf2de53194abad851c008a87679f0f5b8a8f8e01b1d3147126a2acabcfdd9b1188d860ac82aa1b7540514e75d1422786f10d4874f2d2d49c354995dfc2929e781f9a0236b5da661729ba0ead41e64e69419a953c6844d3a03cddd92d6ada63a6ae8a9312aa8d8082e8e4a03082f487035d50c62e24cea4943a62669766a9a56a2cc9a86315b2dcfbba6e0df2a3d697605b4a5d687cbf3b51b84f94996d8a63eb00178ee2a8e1a7c8cbedee602c03dd5247980cdc2c24cda06497017db5d15030170cf5829a4c07ad5481ad8c800563b18d504b03ed2912f36cbf4b9a54e78896baf518a575c0968b04e87810968ef2db73b1751670908b9caa0117039d1151a0b9f7d001d51a015eb49c436ff020596b09ab918227d708151c549b5d316d96b03420d78357500f526dbc42be46a3ea90a6861726a36a2d784c0b496bd356a4e19dcc87e6e54100180f26f0cbd3c6b19de20c3db1f20ef20344c6340192aa5c55ed298e8db0293a7a46c80bd21ac7cd3468ae5d0fcc61c55a587997245325d41e2e62c90d8d45b39cf344a89be04cc0a26bed9df37d3ac89ec0b73e0add9efd3df7ffaf49fdf66f2d33f6e8f6bc03ff055d8954b0d033016ab70ddf321071d25c949b020ae5dc2845423b61d8e01a6c25c347701c65ce0f2fdf1f66de37ee8f22c8c141549ed7a010f1b2c47958185fea9af6f9b8c6fe77bfdfdc6dbbdd1dfc1e278df93cd26b9d98c3872ab15fff9f76fa5a77e452e17706e0538d184bf10785c160e442b0cb34786b7cb81a817cb11f9ad408450664a43d401cc814655601eac64fceed3fba0485717b588dd89f88c0b332ea84d606f9d99059b54f990603e320cb12c1920b310fc292d94dcb0d559b60c7dc9e2b0e8c37e2201b7036190c6938af8a64c05587cc00a59090469ee049900e62aa44124482fdf83f4454a20c476b0a0e46d06aa1290dfc19b08508e40c808c26f0e60cf121b5e53db8810e46f8c1031a3a6ece712b243da12c699678ea8bd055f2d94b9919f51170804519365a1defa115fa2630f0d7095c89856d8a81ad1c91174a62bf33f6a7545398792ebc6fc6659a1d2c834001e4ea5e40aa88702f2072411e3a5154c290b9c8ab8d1002b852499210b4fa0d2fa7a334299c1f5884ae03d5d80110d48b72e468e6ba98c1dbf8e332c98c586afb0ef8f481f5e3707a41fb8311efff574fa46f94c5f61faf61e7e8610796ce571b6a3e49ef44e81e0335b3078bf806ae1f2638583a26a300c1f60ec4a0bd2918a29ed3e9f5b39e2cf3b4348d03e74ac019ac4078fdf6443f2402788860b792536e82fb524bbb30c65b4052d6b32e513400af25e83a07e6f35080efc7b83fcafa75f4ffffae9975ffff28d9223ffb831cf98d2dfc1b3af51886ee243de88aed381630b54274c5c00434082f384fda63662f621fdb9c5864941b38496e666049792d03468f6e120710f3693050650887b579860d540b90e9022c20b014d60b7362027a2e50df981ae97bd2609be309ff0faff6b7e2135fac6ff618a4732d557ddc40832d9806b07cf01c0ec3043357b4d4da9346b5458f588ba0ce07217c434415386e50080e404c12901193d96a06a94380801042c77dcc1fac211b4c150b948381f901e3264529805da08a24b8bdb42695766e910e295c84f309ab604f265b0d7c605a64dacfe2b3472f4690ad9c7828451da3710de01f80c55223bd31889cc1ad873c016316809c6477422618c1349a63623b286d0130113a076e0bb281f093849f0998d85537b2270b96d88281c4c7b2aebdc41a0a6ce15ad4618551b677364129c16c070d9c0f49d66449fb024b1111e48d8f180d43201c84ad6db46328ba07d81d735f25fc21222cb709401ceef6a1ef1c80044bbb0d26b5f9033887326d04d8d08a7d265b069f4fc754b0c0d5ee8ec8440eaab3b1462432d40456bde10be4ab7bcc36b61152463c4021d828bd060ba56325acdb032cdcb425607c20890687481beb408137905d6917f2c822191cf0ecb38d005015e5bd0ebfca84b4f770a5fb6ba7e56292e04159f47c6867c67586c88e68d31a104cf578c4b201f12fc72412c22f76c21f60b81f7e0c32e199db186ae0b220e8433305b3196b4065872605a842d0e80991c266d019a0660012f7c989116f87925403e10bf50a59575da76f8595d98bf583900390cab45e7e5401f2534087146607bc55d42cf44456514b4b7f8bc3c6846ec739d696e5e8d6579e375c55d4798d1015622045e133f5cf77724f45d26c2aa2beb93b50ae06c18fa0a112441b41206f15224102390f53a1786786c3df5cb738556681b514bbdb7504f5f68a5e82531d5080205113004ed004e908c05fe984e090d2e6822ef40a7ef2814d8f41b5bdc568b13c7ce2a923b5c845f30a10061225e0e45757c79c90b34bf03c438c18c63743bec904f155f42c42b18ff8484bba1377686811ad9995f0024c704cc0eac4fd44096f7c3fd5e97f91bb2c1ebc11bf2c14f4ffffade3ce22d37440bd493cbf803b22a003d27585f27d0d6eb09ae16cd80de074a01486767d4e60ba101809bb9d58d60863d325cd3921ccd52df16010e8194165869e5561b444ee034155f21cfe673b690234047f0c5460836a5801425de6c8e1d3866d0e2e3ee3c46d6b610520cfcbe4a24c0ee6703a1b4b004e52ec762246e005463497a8e03090eaed09fa5cd54b70c48c8482cbe491c6c7c98a4ba61f25e58a92b0e83fa0c576064f5562e7833ec4f010ee544d3792d82c5c6188da37165e010d12102d02c13b2125ec882c9a4f916f822d9e765d84303ecf44c7af5359fc3c0566848d2a34ea410120a54e89083d5749c6373f53213ed2c01e98eeaa44f6ca746e851602d0173bcf8e7d7343f78df4307ba3c2832be4042b591142003cb86467e942a19514c398335ee783da4cc9baf794508b0c4aba07633f7061ea0eb21a62a4f17486ccbc190d80e70f41241548312bc2b391aa69282ac9e4ad1705263c59443a44e22ca1216b7126019161d5f281a181284385e47d1e19537bc9700a1c0574f59bdcc1f8b12fcc9390e64f20cdff6ce9683e4e60feb85e90a1d29d43e831223a8870e6f794b72c4bd7d60788f1a7174ae7e1d70358082bd3c4f0caa726f966c030f81f79109104cac9aa0a77e776efbe9e95fb766b59f9efe75633efbcbcfdf9d43a30c49530fe293c2b82b055848de5bc7c1aa266d877180be28877110eb29d7c338f81c278729a90d404ff5838b35ad6d0a76c6320f031cd97d262907f1d5b3ad3ffa4cda0ff9202a406302ca94a826ad879afdb9aa071f430733df61d30bc392f8451990b6260765f6714d22071bc8354db51fd4e7967928691496c42fab29b783259d87e91fbb5eeaa03d8d76f085172050d60f2e218a97abb0fc83f882eeb7c186d058a59434cbc1549f5c8af5eae38687eb005174d654ca5dcd05d7f70680ad31f0978f9976f8aceefffc00db763f945e53eb4fae878f71581b426395965a89a56e0b24ab8041d84ad282e87b22698ab51fa4d6540ffc5dc856d90e2e72f6ba5508477a98a8a69a5a3dcc99728bf234f261e4854c5600d20586ed381343842702a95c6423ec0026a48ad0e3ae204a99b167b0e80efff5615b56d946ea720053c83c8821a0bbda017ea23bff1d071996bc37783d681ea9eb61a476d0625b9494871f226b7b3d344de3a086bad7fea4651cfcdf422f7359fb20f068dda92f86e35066f35a5729de898baf69e5f059a5fff9592b72a9e748664f3df576c00f2ba4a7a931f92387a4d6f60ddb0629d6deb5f420b3a75af60d0ffbba58fdf5ababc6925a3ff8b48b18f966a87cfe21a5fce04a931ef8bbb75e4e4d0eaae3200df5b236fc5ce0abd483f68140b8a9079da012b6c318def17c59b38354bc70f3ee3d7c48ab1d2c1f6a3b94ee6fa4e66348d47b44993e329a1cbaa4be8a567de4648c86623b4c5d33040b8cfe43f776c1cf1a28cd7c2e30173acb7b78693e2bde9a42fff2f30dcfc8ff3a7d7cfef8b7df3e7d9b48c9af81d322b0a8deaba6722799d1ca051906259573c996f42e87d25d385a366ec4eae4238e6db254e8df47263dfaf508562e1a8a01bc6c7fda8334c42ffb383fbad036ce51e63ca224735e9e5d6bb290ef359724679c72445ac8d98b97e7ecd372fbf2e1fedee1f75a746fa45bcdba1fbbd5b6a76f844633ffb0751664ab77705edbceb7eac52be52a08f36f38fbb99bbefe51d2ec3b73ebe55900571174d4a477d67d390b5647aa120cb889a1c0a8eea7a3f4823455c3fcaf33ca82bb80912802a203a00c2032f71bb86630311b83f01d1c1bad061e42ba0b0f4df89a7d360c55d3843d72e624c2c89bc63f5e002eb058947800ae14d95e1fcde7e922fb691177c6113e5913cf598ff473deef3ca75b382cbefb469779fee9fb0b9a6e06d32758c6c885b2786117ccef2abc2ce059e8ee93f0b97d23ce150960013ec5cd0b8cbf608a8d9619692c84ce1b40d9e5e6653582112fdc5c34d6137884eacb8a49020abcf5d57788ae07ec2cb0abb99af902334328e45c09ad23a32d2f0e2724491b1d4ae3252a2167b9f1b90e7d10c4deb01f02490c96f116cb8c5ab6453a029480422ba58137c5754e28a525023bb8aecd0bf27e8849601604d945c18cb675ff7a98d716f1de20ee119195352cc5a431fab48060d6bf0e9c63705901b106b4373218db4acc6aa391a691127451685c4b2f51810106136c07c23941a22b15db6b315f9953f3ce165c69987d2de0630b381ba87f0b89041b796d4bd2ed0a422c63b762afc2cbe2c018a46aeac16f748aa42adbc91cdb8b00fbadbb22b8acbf954180af25f2c92029706169d7d3f5fa41342e32a9956bff99848ca82078dd0b2f0beb773934c8d66a04b032ef533d93a6984440fa4a529a19fc5a69b8ed0ca7bb965eda207631683bda64bdaca03b063ed5688b9c16c1cf7dc122a0c68a30e8d8e242801fb45f1a40a49135bf92b856d591c560bef8829cd70fbb62dc039297155dae05f0c475624b071a361027c9845b1afc402d4346c9bd7082a776a4f1428c39ce0c046407229ed0e8567a9a1bf1b431b1365a5eafa5139dac2f80e5f33a75011f63eb4ea800c35fa4d92787b16f5f063f39485d836d32da74be968ede0b70b7027a09242192e2b612738305e1a81c4130d929e9a8d1c92af9abf0ba30eeac2082be985ce66be94560c329e451d096fa66440ce96b96590c202cbd448ef3baaa6dd08303ffe6782d9d50aa3de951fc194ccbb0152549a71f7beabe6d8baea82e9fcee53956c4b0db964634a5fb85342e33da049e7c271d26b1116d99f27a988cb298048a5985cbb37658865de97d01a74d5976e086911d4b0e138cc9dc6ebbad0ed336d2caae25a09a0c6044d022d87c9ec474fd3a717be98513bf20eea0202b8623035df4b5c407213c1a26b4542fcf63b1aefa4d38bf0d2e4b6d135997910840ae8597c9a079e5bc0488d7469bbabe96de150a7c9dbf2515f8fe5b62c1df7ff95631e75f214b8ece1eab5b24c01ee16a84cc08060288f6689acad6c74e3982047e17a410108088c313632366920d44b300795f4b039376b12a9d40965a53dda22208bdc506f2668a23e00c18a99c96d1725e1e2ad82d5ce938614e847b01d3a0b73349938471032f8b25a980329be036caec85be197d5308a0be1274b468c237f7fe7067fe49b29b69e1fe43d1c5ea1c3aac88b2be77bf88242092f1c508d75ef74d727950a4ba14730103a433b157c6bdcbebd7f6bd52c686056bb02797c8a4955575e514c5c5e3b2814baf29a433a69a21366d90e7a7a57646ed6c5cefe8eded51f6182a5b984b0aac3984e88be6344f7bcbac8609d786096f1a26ee976e7b77097b77099f75973b440fd3518ddca2be601d5d149ca76b6f69915156141e26c3a2901ef36c19ab42cf901709c3e8fd265cfb4d78ed3730cbfb87c18bc7de0c9f9b92ed9bbdd9678c336aa75358656fc664b3ea30eefd99ddb86c0cae677f6e61efcf64f8bb3cf8e05bd8ade60281ec3a966f7fccc1e6d2cc821f5b0ad78bffae73fddfe599315279cb51e8b3cb70b1c046fce6f7479c26589650e48d997e20bb823619bd84d8ae81b18ab256d2e9c7df8fd8badc7c92af58982df8c840b6b28f9e153ac2d36cac10130c3a449215a274b111143c245b3446140c127b910fc26fbb3ff7ae349fd625940e1aae09a212966b7b819cd9eb4aedf257f66a1a16a4fbed4121615ce481f385b7a0347c02695129de4d85725e63b80cb41adcd1e59013e46e74914d2926222942c8de3e71b317b23b818c6aed3ab54238b435db913517829eedd432bcffeb8b2c6a2974c9c56759e3fec6e384008dd6a84635384839fed3ae0060be290427ad6b6fd07569e0a508685dec87706b4f06bbe0117899b85e66510d35ce8564f9473ab1bfb67f5ee0e7c19f8171bde2898cae6ad7dd0a2305f73dac4d5e57190e02cfbc125419ef8bdbbfbe07106ef12e90abc86bb85eb8325bd4bfac6f0ba78a512d109fd6d7834b87b21c9c7a7b5dad54d32f65937149beb984fb811b6bf8dfcebf7c23f0b1af30f3e560ba95e58cb20667e52267440c456bc93ec05637f2316a3b45903b76412ed5645827aa1f0c334a30e97e575c90ce509b8332c83320831a81006d834888e100bfed84d68a2d824ca0e7874698e130d9d093a060f07e6ae8138061042c63807e0fad22b3ad50c6ab8184703ae81d5304e3c4d1e3144c954addaae5d804013c0d00a01aa58ef7f37cd992b79a1e076e34fdafa7a7bf7d9b40cdaf30eb8c4ef769bdcfe7922b201bcb6a98ea4b6a8726a72ea274d210296942e175d712a520ef1bc1505341a4bd4fef1b348824c817e3e20e488261aea9b499264d49781abace40723b62c80c6087882a9ca91d939d221e7c794e16f206f7281e8d20dbd9090ba5484b87a21a48d1d497dbfcdeef458c6cc96b11723d10420f90ad05e092c0cd86223d62952055d68a2ea7d9561eeab650ae111dd50869b960e4474e83b88a25bf1b77cfbe70abf3e0c08dcef3dbf1e3af1ffff9fcdd81c272e66d398d0fd27230a4260eee41725d3ea106b9e7f2809386a5f261204ebee1a42a7a02128e62a1ac0aacf9776b6f55c6adfa5b876ed5e0cbb709bbb151fe38eb83cf98be96a60e735a4758829725431a08628a20cad1c1f63967549969ccea6274b168de5d433e43a7de4a4da5825db2202daca9ff91658626c0de0703dc043885a90b28554bd45292144344866bb2591157591882059ad7deaacf8ed6d683baa5315ad06475a1b89985916af5d542d39c331a409669c253178cfcb310f3ff5abc37d33b73dda1746034b756113aa285b9e01d98dc6d1ca358a700042877af2a585b599aa9d7472d92ea56878ffb311680c4b5a033f51ed3ac58e02bd6844c51a1c6e65523478523399654325516ab90d804c1fd3a573bf9ca53efb5f6cdd5b70a192c0f574332aa29e5027eb69a11624af31ba25f348e11f52c3691150bebc0aa2017f1f6f2bd36db9a01e409d030b5911b6fb63047ea55e2f44fbeb7f12e7f82f7f79b03e4e5560cc7f9e3af7ffbf4dbb7312e7cc50071b57228f2ab94264885abdc356b2608236caac92ab7915c5902746189827ccee1d26c89a922762375977f9375fff741d4e0996aa9d42dd9f09da9c5e44f197e1250e26742773698faf22a8e9a6cba28132cd33fdd40839c4710f3c571c25b509115dde01e2a939e50c2dc82658720acea2ac0a2232cbe535267a812426235a68c74c84cbb650f5a291b694963fe506a6ae4ec055c9757b9a8ab8da9d4734c19e08a921a8c1f0890528048d4126bf5ba217798ffedfd3759f58a34046b5517d73bc4f4b9b81de0fe06d2838436bd4206ce4813c6eb06c468c23e4c20c8f5be33225498b0156e1f05f2c6043f283d7c80f81e8cd213495262535c17f8976b248893cae0c3d23040b9957d1a42dc6b24bfed001c7801c135265114b2a63e824095443d58465aafa582982f292e320cf0684e0925c900780222e95b718d4611392a75d39c8a6b499d30f825745ff79b8b011359ffad05860285e1375382c47798e5bd78e7b3a4d450464dd582b60e628091df1401db336b444df9e400af44eb49017439ecf23cfce180d201a897b781c224e15f52032033b3cbe7d300a1099e43749531029eecad1831f1a40cb62ba3c7b5a586d91b96ae81296e1853b60075176b7a9f9d699f4e6ecd3febd08d39e83ffffef12fbffcf6f12f2f2fdf28bdf0eb1ce6c552b913005c14238f65598223233b6bfb711d6eb0d3fb35289546027ea435a1acb5050348526116046f7f798e93e62d652a134cf6e612f0025e2928bde04fc4595e0f9c017c9e03f5ec01af0bb6475801b65801bf3f61815887cf444b07daa3b806772d84fcc7ef7779b041f93a6f19662fa6922c363b900428a2af3a69907a1cf17ac2a30f1043086a0fe3f51a948e5ac636c9bbd281207b3dfe68235f9e232215ac273baf4a0ce45c9b8168432500d577a449c344060a11ac1c3cfea8ae5420b1bd86b57fbff6e897293128904581bb06e00e13a7d6751118f2904da4bb0d1616a6b3c91fa851633c440640be5ceb69d9768d14c36477ae00635a5d13a5173897602d43c9f75d5ec33ff6d88fd7c08f5b511f6f423eea6bbc470ea58f6477a2120a42e9f9a16315301c1470269d7703d04f4754bece55c240e875dd01e3c04bef4e2c6fe6885b93cb9bc3ff3ec1fce969fbf8d3a74f7ffdd3f7a644296248838e71728150e3f405e41887af1d441b03d2428508a22e2fd40c7e19c54cece563c9a9e8634bda7e7455abc066ec97b490371788146ba92f4af056fa9acb3f0014a0e7eeeac2bd6a1af351c7380e4936cfaa85340edd77bed72ed7aabdd128d763efb7c8c3c797978f7ffbf91b05bd7c1d308a0b9a3e585aba42a3e464850321551fed5d69ffec02e4cd3e80fada61659e25b828157aaa48c0a383be8581f82497827e10860fe197e29ba8869a5dd2dd10c2c4e8806a1077211536c0d5aaa67e67d67dadaf48a2a8b984825c1b2ff10d515c6f6db3a53a09d0822ff3890bc2928c9ac44eb11b14b1da9f0c843ffcc55bf97a34118665a75847cae01c2afd497c8ee1bbbbb4964fd107770f75a652307941f841986d920558d441e75b53eba76ef1cd335be02f9e0938218978a63f928b6f7bfbc88047f681e8dd990c36e1e252ed2427a0cfd0b5ec02744ded5dc1e5df3ae417faf3f59cf7fbf5f7891206b84fbd2fe3074cb7ab127762d1a7b73b513efa7aaaf5d1b4a7368fb1d9a3d6766c7676b1b4952d470ab3d6e36c2e304f4b6d2f6bf706c82079d3e082ea9be2b9c9d15738eddb12c733dc9c180ea2ab6c23f5f5cc91fa384511e086cda36b107d90c439e7dfbd3ad1a4deee24c4d47fd5f8efc23b7d7ec2fbcdfebdcd62980a6abbe33c30e1505c104d3f02ea897f0140d07cfa9a39b519545bb211344fd70fb47cdb1e30d803560790371d40feeb0e50b3dc15408a873200664404eee95fb33effbf6af62f34f8ada6fedb6f4f2ffffad3e9979f8fbffd5f4fcf1fbf4db2ff57627a99a6d13ee017cdedff0a858db5d9f7e29ccbc31809a850350ddb407747df9a327accdb73420319a1482a150979358c960416814e969a8ea08d36c9ae8660485fb13240eb403e2935d419525b96830c8f5c5bc61a643c2952cf47214f3abc796539e04b6a484a5610569a782fa9c0f0d0127dc903aad104606ca7d31de0b808e91303203f100a01ad1460e394d467b0542c09a22b6b50a8f26956c6c0e9480648d30ca8cb8e979c641344881ad3021742185e12f6d38cbaabb0dfb91ced5a377c0680d21681f714b856192fd92662c3989c0e2fd79c4f456b9b294bb816b820fb990858e9f0951418cb32340617f5f1a6058e9b0c065129f0644c044914048f65c00dc05e69c0a0cf036400707c8ee2f2664614a8318997be67e49e59472e3a3c3b5997ddc460beb086b72dde7445b1ee0e8468176ff0a28b02a04146308d4cc46f60e5f676f0064ecdd76e57a4188b89b49d0e8384c0ec570a3c77300609c20d118755a2a56c11660c00e134c212f07a980a17e4205875d98b74266d3129ec1e404373b1033d93df2e9a069336c1d83a1579ce0c5025901782c4ba013b0808116d8426492bf2f4f9bd63b184f624c884af2394ecc3b364bc734687f43d71889f3e3475892e8157b46cbd6064e70f50d94efbf85597066bfb80639707c0a1f02f69272d3968c9716d3ff0e8fbf3e1efa7b69b33e3ef4fba31477efccbc76f83f6f515feceea53e128a99e00415c91dcdc34951353ed916f0e82332fdd1729e728ed5881fb5c46927b9391e6a35a3bc60474fc16398a41bb4c0d9c25a054e458c0333d53210a3ea0ba6500661a73a9ef6e50c666f4c769497a5f684cd163cb670cf3fbfc68a51e7d7fefa91ecba0f7b40684f9ec91bf280ca0927604b667f0bb23d2c2f2c2623ac6a21b5197007951c89dcb024cd9c75153dd56242ca2d64af0691358832c81083007ed3b9c08298b8fa9e2455594547112159120aeecdfb7924fb1161f11f5f21c4b410c744b6d43527103960fa1c85b00977f063f69bd3c0be2f8f8d98809cbd180ee837c7310fe91dc077015dc8fcde599f09f2e511ce32ca93c4a9ba91c673d7b95dc975ccf66691e5d2c39fb6c7f8c68f0525267d3eb64c66f4d732524f92cb8778b72aaa441886b7bf6331bef72795ede6570f22982aa27b8fde7c9cf5a31357be96833f51352ba19695489b56b471ba0e8abde14120ae865cb118b1fee8bd0a4775dce188db746b2efbf3978bf154bded7716790394398054260078002406a291f32b2c8fa1321722db5a50eec7fcf93f49c14f4db88a30f0aac0720b5799134d5e5474358811163ac226cc57bcd00a2bd7e3033b830dba64032efa09b9c08fac210b27394d44eb526f5f1224f927d34ae959b0148c0d83693304bb2275f99338361f355fb1de4ab1b0066801fa03d29c56afc2ebd860ca8970711c82aa5277d2ad38512fef2b485e7534e088819a93e0d9764027ff9440128429a9787d9837a173b219e1a91606986f16458c3f9cbca4588bda21b2259439fe00dc1cfba2b5072c86cedb3534fe58428111ba97863490ffc5d56840270e5fea1751f08ad3d095cb27dbf9f8f99cefb3164689cc0dc6535d5a746af317ed7fd18cf5d3f00b94ffb786ac5e539feae7b66866b9221d3b0ee9f80d06cf5a94218e2efef2bd396e1756e3b656a45c8b032a185539d08f8cb4e048669a93d959114f8043ad72d91f25017ed2944b2f134a7abc5fce57b62caf42f1f04dab31332408aa4f1d42c951ef8cbb641944e4bfa8130cdda80c14134a019e702819282974414a89d4038df34e9936b668022d0f2f61dbd7b4b9253acc035f00137868becfca570aa0bd3e2f2bc1229faa982ff137d7820b96f90671ad3c28afcf2fe6fd7cd323c797f6d007940b0b475f43044dbb4791d5212a59f000dd435d527eba9cec05fbefc242ac9e559b9fa8b0fac02b82b8958d8101fd466b2b86041eb0a7fea584a274279617087db93055fb19fe08ba547767fa14231c217b7057a432c2edc2db527201004feae69ca9741df7102b4d6e643bbe21f5d02f344f0f524c896c77b9bd2295718496527ffa024a0d07f42bad6086bb377f48a7e09c5cdf6dff5ce9011926dcc08e2b239196029043f0be081ab0b52aa939b0a904e9371ab2078ad14114a6cc80e9827c0a5f7a74193e8dc9bdd15c279f28f4ab2f9a7008fcf577a402e2261afb87283a8ac271fdf7466ec869e4e5cac7262e2587d92ecbd67ef3a882f65589af83cf9c132bc73239fd084f2eff31933107d3ed30e9e8527c0ed86fedab62bef0bb0ad2322b6de00d256b6b2b0615c30bca62d96d47de4436d22897d60b4f00c9591b498cc50af3e97f974026e84fad4c49703fe2e7b67e6ec7d9d9cc47b1a117f6bdb5fd005b5e9c207e1cfec1421a359f5494246e0ef5e879d7568cb55349f202d8eb036bce712635c1803a298dfb3ad44c77f9fce0212267c3af3d90c341d4fa3a70e38fdbeb70f32c180feb4203a9f40e66a616d96a2bbe81f3f58417ae9cc4f15d8d2fcdd676488907eb358533b81bb0d142e4fa6c176ebfac4bca7272499b792fad3cc695ae0ef3e778101e17d2509e2d16d71ea26fdeb9f7ef9f9f9db88535f115ea3bd071787fa0fa3ee312dbb51dd8fe57bccc22e25180e5e6dc57e550bff7e158ff4df1df1d96dbf872b381554abf9b3fbbe3d873fb27ed9b85ec6cfbb4de2357cab457cffad06f9f5e37f7cfacfffdfaf9ffecfcbf7e7789201fc16a99a46fbf333927c0ad4808e18843e0f2ebfd603fe90377f34c31f65fef9d95c7ad343f1568017a60953ef68e5a9e085982536491d601a5d0fdad29807059447b534c6414bea875e16f84542663d42667aaa0036ec35f692acc2dcdb11f7532bc9552d4a9a16115b6269b4d892f8d8eca0a7b2284cf4173f84282d98ea6acaf587028498f28a137330b3e4abe97c4a888d5bf825feb0d45a9a69ee7b4a3b645f6f34e51e938bc458decb86381a3bd06ad41b90587ab211877af5a9a63e7ce6f39adcf162063046d47f5bd2ca1f1eb3942791418083831f5ed7bd852cf5794a5563527942106739ac0dbfa8287c6072420c5892cd7ff45062d203a2d07e00ab8a1cd666a1a64c3948c95b7201f720c9574b3de8014d9fc64cb5fba3db41921e6a6a7ecee87e624bf5a0e82e07a0c548aae32029cf54ca41bda2c638987f9f24abffd054fd5ab1835f66754bbda257266fc183f244b17f682afeb07628dc8f17a9782a5e090bd4f02e8bcdf5e35bf30616dba2184229614f04f7be205b0c740f4987b7522f0750a81e1a709c10b80d8bca3c80daee49f248c50e6b43801a43245d4ba25b84e33c4d019e9957942f18be464fe4748f981ad01d5b94a4be648b46bd935e523d5869007c9a07930678a3e2ddfba043529d1b1e06535f9134ebc1c5525de50eb0221d707fe61dc5c65c554a794675f9b3322bbbc78a783a7361cdc57b5fe63b840dda6027e4990e93496e4f6d7a03f2973db2c11c9e7aff4170d1616d58e5d20d48517df37920377fe70228835afdad0a01f00453463f4654db4c0d36747519b4aa8f57af60c4b90e3f25a68a70173dc0823b92d44349264fd2071083b8e10baa79f747fcdc0f2ae5a0b2cf2c5500a064c9da291ff253ca23e57dec03fd28575e5bf7110408b96e07ffac2da6dcbcdd3052252717f70eae628f7f440c10afdfd4c7c13bef16394ada8ce283d527a202f8ac7c488adf32a2cf74ddc7e4c0b089c9ca01731fb0c08863948abf5d1a5e165e8a208083e499540eea9d7662e34dcfbf44736a7eaa22c0350e9f4b0f5abc5aa2664d4dfd31e65318faaffa6816a8a73e76073adab0e83dc7b577249cf968519f7cdf0325fa7ccdbbb956be3de1dd45f37b5b2d6b369faab4482a63439f94547d062da843144a6ae3ecc74e31597bfdf3494bf569656d76502c53b26b6c197372664fe7bd4e80ed8a65db7770eb3dc6cb0d0f90a4d17b0f628071beb133bdb982af9846f9dd1565bfa0ac1166edb35bffee741df8c34f3fad43d9eb6195f0803767597b7235fd3088598725d34fddf009bfbfc278c9eb8bbfbe075ebcf0b6b29f5f0a5ee4f31abb7e859066790099a5c4ee3346a5eec15b765daf81bb4b5aafa0a9ad477b955c5fb3ef2dbdbf0daea9ac1c4dac57e036ae9794345ed659401062f56dd7f370435b0d2669eabf9d2ded4946cafdc05fd61f0e6dfb17ac4b8c6407d75bec7f7ffe27dcab6f9e61fb432ad6d1fa2ae9f0ecf1a134f3855fe6fbe7b00ef935f890baaa1e8d84d7fcfcf83ae914e944a8fbc7f859ac5a59afbcbf394fe382e93dfb49cb70a9636daed37d8552d6ca0f329a4f936bb3b0d4440f3ed7b52db2dbf8f2e1626227f2d2706db83c899f330f6bb36e5da85eaea59daf55f6d7eae8e9fe56b51cf4bafc54f84365a60aa097c94e697bd7a9085c4fba963e5953096b0c5f9aca7802736c3daccd5a88462cf75a6b92f2a4565cea5a9b2546561f1315dc79d585c63ca237a31dc0feed02e89483cd05081889a1e8a3c3852bef10277f762ae35e7c02f29501ff630a63f12aa2eb9ae6b0f7291508885c48d758dca4f8a7a2a5acc0c1df0e85bcdf5e39a79a0607f3b6c63eaa48fc9d30a0f96ec9dac156a73f546f397ffdb580bebdec4e6b4e130bff2c0793e94b69c949cac15a3f8c9a9acb0b8256e66609bb0d32a9d7fd66d99f5766d28376af4e1101522604ebd201c7587c1daf062031ab870e594eaaafc0de934649320ffc5d108715808ff3d02113f3970f6f5840907802bb6e712529c389df30fe913c05cf34f7632c7448535ebdb5b830a59066a5facb2b7222a4f8725541a4701896d4950e4dc335386cf8666c5f9b49897ac26e52abcbc12651aa1d66613a4cc630eb706c97a588ad5499d221f15774e1098d4ee1693257f004f4ab550e1395cb1e97fdac999a8b7b790095340e438f7091f9e07a42b479b00ee726402bc9cf76b00e11460e43f1d58df89625f5c9ce8260d343e3c3321e7340ec23542381ae73d0dc92b940545c60e35f776097eb075fec8b1e6a2e07df231345ad1547fcf36ac658cbc6e9a8facd3f1311fe0bf9e87dc1e8a644f4f2dbfffef52f1f7ffde1f4dbf798b6f0ff36ce5f0e658ca47207f0d812803f2ac8a80936466a8d65c47ff314c2ff01b0824080b80182cdfc06fc0b5148ae37b5fd9604a2f0e2e5d92750ef2477f0b921be446750181b05b136eb0f869de39cd2090de8b761b1341f0b81c89dfb5fccc598888ee55dcb60091f6b92d4970200e7228fcf55db381184b4fee0e6473149324329a9f02e2cf99b57419eba5cffe2538bdfd3dfa3aef744f1f2ec6ba45af4f56e8e2799929a58d8b7cb449993183855e7297657a3e18842cc4919c090d22799be00d7b06f7929400ffd6712ef1d598a3df0f25e92f627993e5397b06f971976a466f011d8098e3e60f017d087cfe06b98017c4282202207c92ce4e2300b90bd04c966ae1e63a7afaea7e2f3e6703100901415f1d386efb656c3be7d7d0750c5e8c900dddb4b32ccb503d0e7ade0ab073f7abcfd6670b12a71cc17bc7d4756176ec47ab611f6ed6b3d23acaccd53ef108c11ba3c34a9f987130f1109a500c9c1774344eaf872f56e33436ac89f1ba8117c7d951383154b22cbe5e4bd1bdea46b0bfbf6d537039b5deb277f6f7a1314ada7a88076ebd3d1d2831570f22509de84caee82ea938e279619d686d75d6b5aece4eb7007d521328f05e149b2795bfbd7137c734602f92f01f1c5db5a5253ee0af4b625629c4b0bda53aee0266e9bf4a4de8deaa2c6f1c53b5cbb9b747a59d57ba7eb89be8800bfa7e38b3138b079fd62501f7b3ff5d38055df3b2fc7ad58c91c1bf23a361680887ff9c95f6d100f0484d4ae43f6ba619063a213c4db817ac64bda5877581e31083a1a3d75548acc13f2ab14b7f1baec8034c9f37d93f69bc5e5f6aaf47afc4b6bd3f716c701a03cd599748365d6654a4b1601c482b022ff03e12d492f0faa25cc96da060213440734e2cef860ea2723c17b89aab1958d2c45b60347ce5462c970e79c00ce0958aa028ae48c202abfcfa0b7ba234c68f158e7344f95240ba990f447016bd1c94e6fe47ad0ba829842c9f42a810bbbd142300359b016d30a69a15fe8452707943ff6e48b512cb1317d14a157f80c0258110d0f618270cff3453e4ca45c55d07d13eb02340688b60272213e011167fea90810c2e76f88e765d80cc8b541db8e2cdf935f1d9bbf6b096d6cf8d624fbeb82758af4539db83985bc082ac4083bf9570ca66ab7d06a1257362cf233004054b257d7fca09d007d8a570c680dff0a24c6a9929301e0aef88e085e226f38b08b056fccad139814e11a93acfe5e5360cf39c5564813d89030b92d4e3280b1a276bde02ffe1209843881d4a47a02234e2861dd608bc6280923c312d03baf0f012dcadc8993bcb310d814df82fee44bcfeb77e013eaba8a1d0b02be81658dddc992c46b3d21b7505a3b21ff971d90aa7e59441d7bed5f1e0a524a45c71921a00aef20901b6d9447d1817df9a464585340872d122fc331900ab1956d243babd5243852a62439692625784ffd116770845a4f72221aa7e499ca5965f8cbfb757d919d18d35e1fa5b4c497f3ab5cd0e2509c0a361669cdc70d90665194e6cbf1f41ed5d10f1b87048f6194abf745df113be8d851e4b1ecf7c55aef7b46dc8fbd9f0a729d39bf38ebbe33e5fee5d7a7fff836bac057628dc8d4636ce52c3aee652ab6840e6947af93728ea2e3e87dc70bf7e830532fcf8cc7b49170edd10fe2e2561eabe851a63eda287ee123c8aa8fb8e0f2ac74d6eb318e999a9f7b6f9acfb195632b7cf0e521877cbe5e5d41a6f2b85ee331bf4fccf85ad5efb5110ede68a3d32fdb5fbfbb25f19a9575a78b4616418bf59a98b578f4df50df87dfd3e2bfe1d87fe5d17f43ae1fcbb83c48819425133902be9cb6859c5c58f29f97eb9fe1ba0f25846c85d703d73f5f4f013c7fc8dfecf6eff50734ebadbe800337fbc1df7ffaf4f4eb5fbeb7ae00f2d452c6b194f1086ed267ab643c9c698da5b3ffbc29de6380894a6a476d230decfd425df1d36f57178fddaab1ef0e4249664f2314ed696c24def275cb8c3f46dc404465e79006f0ad61985cb000086f1b0b215e481126c1246a8dfc0b362c847621b56730a40ce8de7057234698d0e124c6c4bd3b68022b90e85b30084a0676d546f441c4fda6e98289117491ebbe2de6bfc5a85635c99d16886718fb05f865bed86db120021f307c20ba739d0c4a87dd31d3a026e59c0194371d41ea486ddbf599307b90de82d40a6012f0b23134114f2b0beebb26395932205c0a3838bd2689bfe49f5b11028dd84da0510af209fcae2e52bb4406c01205d5665712bd0e068a5c1ee00f085605900c23566f8606126780bf211853c68cc66a46ca5501b5f98ad4146f86b379fd5d1e8c74b2804f69cc5a58fc80e2521b1062a5e764776a68b33920617be576443d7925b9a8d818ee3f170934265001ecdcd8592b992a1de64808d1f56bdf8f4f3addc263fad3e9061cd39f3efdedb71ffecfc7974fcf1fbf9955f12bb8d60dbc0e447f6c21bb563119125a95e1ad3516b0ee0d50a52196923e1a10f0f970220e39a91450d24c1e3e62773792b42eda88b1c691908ccefbdf19ec6e9bdf0bb8eb2b1c954faa3bb2c8a4800ccab8ebcf0b7ec3f50882fcc9ee879cd4200b4f185843fd0cc4431e1f61aea3d79f09b1d3bbec4210356091d40dba1ede3c78574ae3d1ac6d82d41c78265b70d15dc9ac0a7674b203b8ced459f229c91bcb0893da66b22bb57a055627c8215aa8baf0dde9fe0b747f91edb8a7f1287d24db80e98eb4475081c68ed690cb83611635bdaf39e99d92e294243f3e71fa6471369fe2ee7228955913403b59247d65e4238e6fe0b5e75e62ff92d52f277df4bbb84cd2097cdbe3f5107e2ecf54db5da7dd32309bda8a355fba5a498617dc80f394d9b68bb39de7eccfe8ab135daf4389af788e4936dc800af6fe10fcbc3b783f1b91b7c6f167277c7148ffe9f4f48df8dabf42fa2c2559b76075a6a205f5ef9a524b5288700fb07f13ac3426ea9259eb0058d58164369b482eab15f825d2f63f4a4b795182d651d67508541963ffcbd759f3a904dc7168096bc084e8a200eb9e2d6acac5c77e86212ecfb6ca7c471c3df79e065e5f25950c4601510d56d210501af779fdcbf5dfca3432fe0d17d97e2a368fe0bbbb83efad067e96a5acd04d7bdffff01151cafa033a8f7f17e2a05b46bde697750e8eae32371ba0878b691c495edf4e355505d972aeed8c38b6b295240a4f772f00ca6ee3da0e00a0bbfee9eba78fdcd953ebb0b436af3b6d69befe69234df1613e881bc6bdf8cafd0fbe1202fead85d51b50663738abcb2aef8210feaed77f79dcf8195f1c381f3efdfce94fff3c7d1b74309bf38fd34d56e423ded79eca1d90d51141cd82ef3cfbac663e79024c1d4710ef84bc4ad1238e6f8bf2b32e2bd064c97f1e716bbf843cd8b88dcfc578f00501c2339816405e15cef3a1bd624c796f57325a2caca84e6c4a944a0614567321b7203c72519dd773953440a7ea325e6542a8b204d341dee28c3d4a5deb6d6536488e0a5174b1eb806401251508fc64d396703d0ad81bd216011e91ebb93fecacb219cd7c841926d56f219c7a21fd2d6cb8787f0a9c208bae90c12b53262c9465e4f2fa384bcba95c9e0ba8bca51757acc4fab9e724f743eb6624a1051b4403b43e36f76d4a6a67e4d06c20ddad642b2957de92fc284a0c33d52000341c487f585473cd95159ba47ecd4c567539da37976799b06d92fc182b7ec6d6bbcd22d3c316f8c9103e9082c463dc5e9e7390d9926c70d3841de08d9fb4b683406683392afc58213f9e7525bd6e01d071251d7e21fb364afe738e229dd01fc5c57a840bd43821d2b554ce627e871c8a507f678e1a4bf951814b59321251807c8052c8e07d2e2b3fab01cf1909c38545af493b0bc05e77ec7e0082ef2f06b1a95c9e0530e3ea6a05b819d0bfc16531596a358d47b59af45eca183058603d68a0f4c725be39ba447b8e066261d22d35f3218646032bf1d97aaa470c3f23f3b9d5450c45e4133b02daf32c1924c158d30293811bf9040a4bfb1ce092746deb7d51ba3c88cf51a2ae30ce9d4b7942eeced1170042e3423cf3f5c99ba2a2b7ecc595155d7c037e74900b74a579bf9c988453d3bcd79cdb498cf94a60bbb2eee34a0990cf8b4032c2ec4a014992eb5a687f65e235283427ec1672022fb2147c0e346f2f1ea364d88cea142678b413710fa537a8c64ab6248d5d4391384ac8c8d973bdaf9230df8230af8a276764fdf0a2815a399152fbf59648ae448ed9409236d0e497b15dfdb38b9e0ac9b666aa9b00e81be2ec4c100e7a80da9d7116c60d329c0c1f583630851ba0461785d520f7bf3fe2f2eccd5360dff60ee5fddb48e90fba31342ecbdd1261db0a55595b458153b803bc1d2f40b221929ea16c443e9f8b8b6a5adc47ffa2af41703c713fc0c8891442a48a46016e698100065c977194020582898c4aaddb4fc7d523cdcb83d62e006ceedbe49b97209831e00d02b07ec8f77edae5d9c8005646f261872e8fa98a4087b391ff66a24123305a980e4b5e2a94d6bb586326f584439525a5678a9422c2eda2f9c6348c9e075f0b4bc81624ef0ff2ee3af85a5c7743690dc95e90d537c3a0dd80d44fc03441a81c824610e2cf92d0fca98d888d0054217f25c774f61965309bcf080d4b8273a64e7a576e6beb630409aa000335ffbc4e4e137fa70e178a36b004fafcff5f2c1cbec4ad85a37d69e10059b9fef7978dd21bfc768fda00830932f7b87b5b0702d5d1c067b1b52e18b27a7d421296f2ebc5202b9f24872bd78b05cb4afb83cbca221e2cbc0424691d3a7a67eeb851fc5ae474ad117f15a82d700f0fb2ec63df50528f114ed13bc8a21d292c754dfd2c059c6a806fc698795da7263b96a5cab108867e14f0e35ab9ab5413a8a16b96c07058b344bfce18d759c2d7ea354b74ce04d75962bcce128665f5b35942489b5659fa1fcc142bb17e7fab3557cc34decc15f2fbb9e239cac8b495cc0d26a13dd79a2b33e8a424e46344e1bfa15decaac197358cfdac2f6a19df9b6afe7dd866883ba2a3c054569679898c887d9159d2ea04f72c6c7b6be0749f0227e7de42d6cb2ecbc24564cbec437ca01bb57e1d2b499941fd6afc835d2d232b9dd9c530548f332c918a200e4045e9b2f94cca355802a192f8aa3cb9f19f4721e7116c4d74b933b3dd76301aa296074406107ccc48d154af26385bc7c3f538f58d0153e5cee74639efec17c10c07af00921202e852c98e55519f30ffd336b55085569b62496ba101152cec063fd4078cd8cc36071bf2f582d53800d25ca582fa03cc5698de7a6729f9bf65fbfaf2f0ba3dac7ed93efdede54fbf7c778e232c03aae53881fe04181100f0c4de52792ce61d7d44124429019ff3c9e5bf50537b2cc3eef319a41a2732eba6b1f900e0f9d116a191f78447edc33521b011939378f8ef7d7ef417805fdd67465fb9daa055770209c637a090cdcbe9e01d06a58eb7f625dcdb7ea384d322e4a6c6699aa58ab541dbe2ea02ba6a3b9bba52bfece9cd5f1ab8dd25f87769b1a467e8d927f5376dfb9749de3b2be9da1e7560adf695304ea2d0e0934fe4311bab365cb63a8ae43396e7807b063f884a55e170f04abd3c47cbd1272c3d519c27584510ac8100e782ea05a96f4401832de4449c69d0df0a6c20928f363e58c60228f7a6781441678e364e85139446c3387e1f16f6b51bbf3302d6d12f8c80ef6d59f99d93f9f22ca3c37f37c13b40547160250805eab34fd51b7d1706ef60e1fc5b8e8de4923befecbdb47106fdc3960378e6e0f534e0fed8a9f06a396b4d723fcaa38d7922b5de56bd9b35b253d3591a7b9a8f8aa8a71ce9609dd856a29df90d54c751c7392ad4a9a559d7d821fb986f8d6065cdd74cb03d7ba182e40dce611779e1660456478908bef687d9e5b963fe2d703af92b9f9483a0ed6f0b04122c7fe0ed7ed40e9bd972b5ccd8408d8e2f39012b2642b8f46f9ca91e474e7a16d78ef7ea420d007c1215063b96a6860a03e983cbf935d513161d8d106329362a03d3e01c450915902ccc452c28a40507f70f88b5b4a77ec2b2a7e338f9b81abc463b422b6bf85220c1debdbf342e6e8d8a5fbfb583f36ba053b3eb621d614c4ad142807c04d738b696fa79b59832a620acddfeefde67395c14e8c0c451bff01c7955241d3a6eb6ffbb3c0b91fbee2d97fff9438f78d72f3d3512f19444ae9f3dd7141847206b34ae52be96a40237e12428cd72e3a2f74115195821804e6470944bc450a029039ec8b6524e351226cd27fe7a675d3922ad00392807cbbe3ec165af240e06d652ac39d617184782402a0d15e87f86a0da86a8538da0a02d882980a02891d66b3c111d9d5bf0ba87a5884d82885980e5922cdf58afc64b5c8663786507095c89b32899a85fcc760a82f43cc435601da55f35cc54efb0ee4ab5009a830c2e2a121e78f30517c3fca785248921a990dcc26b31f9b28580e8819d153b8195b24e20c7684fb2ce405c4a2a0cd8650d2010babedee4ed298b109e2cd8b889e231860bf91ea81e729a265ecdbd92e60975d6b7eb7eaab008b548465273acf049d320f4157642640d280a9785a46932941b41348d2714af8d1e2ce03062ec310fe20181ec1cc0519ac9ae270cd6dbfa9bc7493ebf1fdc7879c3e1e9875146bf09fc3417abf14201a36f12af8fd7f5a03c33245b978225dd274e6f8e2d193e63dfadbccfc46516ec84bd0293c0bebbf06ebc0c5ca8f83c629a05d8b613d4217c87304c67bdb1ec94daa84a9e877647056b20905ee1aae7572a4e28a9a23afdf4be6e64b840711b4b350153c55feffa28c30b29daecf333f67b149e81aa7c7dcef8ec397c3125cfec7add9a60698301c33f6516c6d9806e2dcc99bc4564752faf09d4aaa20f6100824e16809909e13b3818fc19e17aedc40533d9cb9b326e81d8a464db3a715cc79f57b7acf160de7569f04a7d0d40d64ac62bc91a252bc29cf5b00feaeb687f29d14bd1fb00886c52613c9ac4b77763c0584cb23f700f5a639bf32f8b7cad9894be2086b8b902efef7ebd2f43aff8dd911f1ef1b5bcdb9b7d2f1abdce22e96d22eb337a85f21cc161dfd4fdeaceb39a5fd320ac4b000e856bf51d747902faad82d4617f699f5b1334537688b83a44448788de6b6202f16822f33843f657d78ab6dfa5c53419b38f9506d5c7b36e9ed3df9ca338e7edd37ae49c59a26b0f2d0e7850b1ecb112af592af5fab445008e8514f76a2411c6abc34c0730317e24ba987fb75f0d8362d8cfc0e7f9dc103937449f1bb0dba285d7ab1052e79a91af5c2eb1a6f166bff7049fa270a1447bc1374dbcc260401283a8d634177d60985f02ba68dcc3274b042e219d79f36f9a6450c29ef1b2e29ad6615cfd7a78be9e3f1804e962809fe173b97f0a8e17d44e8b98ebd7f1c45a442d839a1f75e9bd06f03c38dbbb8c0fa4c8eb509f92fa89b88cdbeb01c301981e51c6dc19313cfdee408dc06e632205ca602d8607d02700bc0040245026f8034413186c7f7f0ae7840495a0bfde8228f3b65e44578df01bfadaebedbfffe088bf4205bb25f214b2edc0ccc6048f11ac0bc1a70bc3ed34d3250129bf057835b80f192988f85e86370d8863c4e28d781185533cc2312750fc7b85fe52bd6f0dffb996423ee320c0a3a98a4da818f4a3e00b1bc1048de93a4084ec88dcf3c7faff5081b01f58967ee9d94f31cac56fe5ddb8045b79156cdfcabd8fa6eda8887c1efa3fbedaf5a9e997d7f72fff5c94ffe2d594002bae9edc3e8ee14235344af89ba80616dada91dd0362acf25a5a58a82322f52b7692b0d7c7a91b0cfb84da5d88dfb43bd92b8339dc09cb910ce2c315bca350d901424ec1e0d6071518a910b5ec8a303e46ff1ff2de76c79123d9127c157f00bac3cdfcfb67237771f32eaa068315900be85f7674cda5b6c99650297167f9f40b3bc782999298d57da5ad410d0652919e118c2f0f7773fb3c076128a8c29d376cdd831c4b9c2a8e1dad5718fc82c27529398dad006cb1391a66fb57bbfc3786cc7ff68d7de9854bad381a86fcfc4f5ffe7d2bf8f33fcb0efcfc4fb2033f7fd5f0c39f30862b18bb758eb48e98b41bfc1336dc7b809d688be5a5e81130a0a8ece29be99166a4fffb578ebec4f2678fed71925f8aeb9b6d9e1b02599e8ee4358f684886da84986ddd932f2a52853a30305d6540635e62cff7ee2e32d08b786f05876b60a1e060cc61454f35ee6820b44633154c5d107f35ad8d81801ec0988e594d94559e6530f306f6b747a473e0d044cdc31eecb888c0d82f4c82665d2024cef8ffa1af1f511c76ffc8c7d5ef1f86ece3c756d3fb87aa6928f70e6681d94427adbe65641a91c1fd4d33e4cbeafcd9932e4d6dc3badb9dd9b13b8c72bf9ea39a4cb6bfe146e911b591fbd57ef7f0afb77989203ad2b73787fec211d4d871e7617fec0e5a483355f2ff886bfd73e1f465c974572cfd72feeba76f2e240a90627bed0f1aec6d83e27f30d34f11e9ce414a036a7a282da8c27c6b1b6aa8332b83802c5d424bed412a923a607aae20b387db15aee782da51404c3e94d982e4124ac70176f2cc4255f069004d1d12a003ebbbc358c1f844e6b4326c284101b2dc59a15357a80c3dc281d2b1900ee6b1c1269206271d32239b69dd58d0b53193b4325dca96b538cd581bc86cc24d5730c9633d1f844d46c61c384d1bb24201b65be9312ed65708200e540023293ea390aa4733144aa7aa59e3a81e068d36fde6f5accb0b7fdac679b7086fcdc229a0a8b79ee6832ef08930fd676a284c54286633d7de3774cf005d2efbab7507c57fd09a43e9481a7552122472d46aeb9349e82fcc000ce3fbc31fbbee8dfd5f3ebf7c3dfebed2ff78420047f3635d693d2044863c287a0eea4a72a9a52069173535e2297b83bc3025c3ac45722f22682c0d6742943cc8cca134389a5022565a7d6d6dc517d002e58fe67149729c25d58de59e8c5ec3fb89a9003a936af683d6f25046a19e3b43415a4e09fe38d733222e6180ec02e9bc0d580b28f38207ba315827dd0d954719caca79ae903d4c06f661f6948ba0aa072c0ce1660ce1e3b872aa9b0b8a8e25173903a8ea62050d66870d33c6cd85336646680a2b76860edbed6eda318e62a31f393ea83ed21dfb06acad9d30d6f43bd738f13cd9eed8fd13b4e4674ce56934f03f0f28e1c41a6034c73e8e2a6b9bbb660fb825dc009048de9f03fb70be3b0bf69d77e6c1e74f9f1e7efcdba787e7f34f5f47371d7f18df6a0175161051c8b844fa606f0721bda85a4325ad43de717d97c6969a0de209b005fd8bbd7539f093f87992e5d06bca6d8b93409684ed9d208d27066d4b7d3d68497d1ea48c0310d46c9a4c3994641b5a4ea5bec848751c44c6a155e0ed7649733c8c6ef75d0143735839753dd43a0f92735ad67ab6d7d90efce44d4db0ada5593710932980fbd204d07d616ba662376b1b08b68d7c7adae439b5166b05659fa652620744d11ad630c3bcb7874240e739d33cb46acf956639bce9e3ef3f6a59f6405573ca634bb6d48eb42481c222b5f6fd79953496fd2d2326290f04edc6115d01e12d3cbe0f027a77dff7fdb98087afcd249381a01a6b9276683955c02d4d6487e516650c3b0d5e564bad1e2ac8ebbada0d4b5ba921a54cc74172255463aad6fb338d7228f520b66217b3c64b047439520c4b4be3b0005eae33f57a10410edcc149fb6a9ae35061f46a92be5f7f096086db61a47e18624f6de6d238945e0fa5d543a904776ced506a49ab6eaa69b48376078b1a7a1804ca0422f7e8f6de5baa20c16b00c61b12c73c9412edfdc84301c5f341cb4c760d05de64efa9ad43293d9575d0aea9d6ef3f36019adf5c3662ebea87a169ac439dc0c3ebf550473bf4fafcbb7960e3691dd4869c4d1c3960e0d9c43980db10ad4164c94a5c65004aab75f401d3ae02e0b24aea72e8ed607af9b2a935f5209810d1bab1cfa88510e785c3f120dde47da936ec998e35edd61687f301c3f9900fe845bb1050ce6d12d801f32f52009a5e76ccf46c0f99c4a696c9099d766c4d1dbe5d2907b018e3f5af83e9380b45300df88835ae6a138bf7cb09fc5d6b9a8a62eabfeddf777105dfc8d07be2f7cdeefb02f8af2fdf1c4841c9f07399b12f66ca22fb03e5d0710c6404ab29a6249cc307eb256c6a09f7f0477e202b93b0b4c2230adfa22dbd38b4543b48bd78a324b97e34c573856eb361c0e739a0d080733440b926accebe7686c10a5ae0102d90e00ce6dc15a5b2c232c63010f79e70b566e8a9c3341f10ec95a024cd6381bf82b58e316cb3ec913e39a013973810f7982c3cc60382c10eb9842017a317a20747fe31fd9c8e0b02753217b1c3f3ed14658d2d41666346717db777d0bcc94fe03c627378bb199fdf55142c94696a20dbda65cbe0ae417e35757bba3e50f65eccc2e1fdc1ad8edcc399de07cfe1807d67a0fff5e51eb0c42fa7edf32fe76f8d987fb5345a10f0909292679aa9d6da07bd6dc6d688adc456d112f2092b6e0db26c35fb602257c1d7d924b491a67ef05f36d1a792739aeb0372fc1b7e55092f5ed35cd7f358a98f5f5d8df710de5c39bebd8b73044e70a8e383d9593c65ac3bf1ff5c4f4df483ac1e8a14e0d6d5c1df34897e77a3a5aae17dec1dbeaf7baf987b7eff8affedf9f4bcfdfcc3f67f7efae997bf9e7ed8be45acd4962bd052b581343a0740ced2abd0bff33d8e84fa023c536e7a0b9dca3fa36f0272a919e4e3414c448060b4a10ca8019102d4b2f883c8a5f84d9da6371211944d9e239459522ffb5fc0101d0d1889382b2f9a5ab99e75007751d2948b49447d96d9d22a25ecdf843b3435608032b39e1cc271a4d2b7a8207651b5550f5024a59b02061db503a6e17a4675dc30553096917a35cba85239725c151bdae08a9ecd4eafc489ecc794e7a635e5e190980d9c3125a7dc714bcc231f4fb5a72ad733e82742cb49c6c514c1013a9b8caa6fe479570dcde1333b69f9f484a895823b8e447425f0d3b60f7e6eb1594f4ed30657aab4a190bd5441fdd5f50868ee4b91a37d6f9ac02e669fa03896950a962ffebe555e96a75fe1b79755ded4f318698e12fc6b675cdaef1d0fb98e452eb8b8e92cb9457b565c6f443044e2f610496aa7df5d930fcc7bc127dccb3dda9386059e9e011266a1b06ff5888ebdc4227864eb63b257dbc3da15d1d124e7c6215d4fafa71ff17797dd7b78266d11daac5d12088023bedefc932d54f3180b706f0b803b731a7ae248e4807996d953b1b9e2df8ef36983c4064c1f478cf22dd6b4504ed551f26c569e2605b3f6b2b54b52468a71693052cac6211e6cb8ab8df185924ee510370b3da7253879dbaa23f841a118c028a9e0236f2b62d4f29e3987d6f563219d3aee6fabce19dd2b103f1a2a2839377815ccbfce6351773b25728ee882e1aad67b7635e1d51e71feebb92c9482d8b377e0252e821605544fbdf6d1e94d876ea4fe5610b0db63138e1ee4e3e8287b4cd4ac76bd7e944244650071ffeac56c76069427e41550828593f1893acf06b2dc5e41f0bfe08e07f17223dc09ba0e3595bd5dcfaa9a5a81f16dcfbe02e4039e7ddaa36520915364f561a2ad8dcd7a15c90c284b5501cecc0a6f6455e34d0b7bf718537e577df9ed42756791fbed4fde5fedbefbf48fe79fbfb9989ed695660fa5a43a2fda531e0f5aba49e7490272b5113e93d4a0da404f3faa637356643e02b5464a2c05c0ce68d799146cd969ce2d9abc68a9d8fa093f1af2ace070ee0db0c27676b1c9524d3151c846e0e902f9da264849b5c4626fb213801f14fd20a06c36f134e5865d01bbecc0800325ad013a799c36f8696b0d2d89064dca9407de129c68edc2db0626cc92304043afb70705af6105439464cc7d53836da05550d257136fa66097f6846e3dc2fb626ba47660a0d791c6d8e232a1ab491a43ec0d54f623d51e967503dc83ddee72a501b76c475e24218d5784b79659dcc05862a920dced93e2d4ce3158ab0824a302e451d31404d3c9ee372c28070ac25205e2ca4c05bee18e50590523a4665b7186d9c0c596c968b30954c166859b853e400dde60fdf516403461279f4084c62200806bb393a62d98d5e6f39891a84b03e94940b5ad360ed4de556be8b2663663568caa122a30a5019d8efeb69f057b44a4fbdbcbaed3247d1ed773af76cebc496a783cd31246039bb80630e3e28740996012304aae06021dd279ad409876623427059aed40829ff276036e77d099d8b122d82a371b1fd616cc1a49e96e03a5a509ab4e06fb0af59ca811ae95b01c609f9cf0ac58674372c19105094db8e3dcf8a622dfd4840b036476324d8403ba17af3be2754722cf376840c584b68dd4ca41133868e05133e11b0706a3407b4b8390e9ebd9466e5dc1bf9c2075a46aef3fdb002f9a8014d3b75860fde061c3b4f5ab63ccadb48ac9dcd75956c1785797a950ab5957ad62a767bbb19a95b2c3ae24ad4377b6febb686ab241e5839317487c13ef8e6fd02c9fb4c603d14a66b6b73781fe5d88225191efd9f3569bc90831656e801841211556b6b957739a2399c220115f48c5ce2d0c0e6b41ead53431a550c0b3bd261560e6404bb47b8e82a1667bad77f6b3f9bf1a72c44b8560a5cd581ba89f969d1a77127127a1f5548b89a5d5c02f80e7923ced521570e9a2ac1b4425f980aa42292f33a24b2e117d87b42b625c2b4ac8cbd88726fad9ffa81504e37c33b115fb35db784b2ee9f15eb708a12da0cc83ebd95e39de3e9bd77386436299de6196252b190582024dfb7889af1b5abc6d6613c4e1854d6c05be0a86c1c413ee3f47cb2e38a074081962515100a4af31bc8dcfefb400e5bdf4eca40cf9053b90e236f8a3f8664b7cbb059f76ad9ea46ef09e06e0b44e847bb3781b9f2ff1cda6f86607dbdc1bdfee7db3e5ed2f41278e74b30e0d5b32861c74f00e10ab8c4cf16e432654f4110401f0f4471260670f649a888d09bc0910212d372bac65f3044ccd038c12a5da201bd3c6dda8a98e939da8a661f609d285c56c0f01b378b58e5361938c2299e668c47cc3de687bed2cd1ce026f78cd36a5a9908e626a032e880af111564245bb4c3c0d946bd8b9cc6684ef4c0ab50505f508981af0ac04e4f6c25fe47f82b7da044c67be5b3791541a483a30fe4164b1d31fb66a133a174c0e60c367805e52f4649039da7a9564d85c4f243748b961a65b0fd498ec0cb64aa875574639494761040a73175a58da80a9b25a7425d914a7d423cf88d3453f1fb7d99fb874f46b63b3663c91dda859e9a09fc895371d79d352ec2730ced474c2b840f0005a077bf27fa62453bffd828acc1fdc51903ffdfc5f7fdcfefee99b43b7ac79a41e7a3dc6d2c7038abc7b659d3d0bbb91d0545ad2870c069746e4cf0ae4fe9ad45a9b404b5538b009bd435fb6fde009e770e985f0cf4da855975d51409a31114f56a6807ad6171cc90005c90f733f730f13c545003e61332fe4d3eee1690c7680770db66438706540997e6e49c35c09ab5f8fd30e43ea2fb6d9eee64dd4f2079ea3204dc6cf0bf267668113558c324af40b95b5b761706f08edfbee8c9eff78f8e1f376faf60cab36c27c10cd0148a1b2c2daa996eef12cbd922cad1a66c0d1d733266828a3a6f901282cda80ac4f5e00809b96462af9ca524e2454dfa23011801fbff95010660058b52094c2041f9ca0befe2e8e866ca6eb79b1d00005eef8b09f0b7f7e0bd9f831bffe204a7967ea04d081170fc3f56ebf0ba3c5d13e54445fb4b550320acd667ebfdc747feff7468befba3758beb561021cef00a4fc130a63023ee39bf6076a23fce5e8699e6a25d20ce9e7002409503fff509b69afff9a98392288c6d990601c809939fdfab1144d13e7fd80dbe085dedeccebafdf9ce176d6fd3af1f67dbb93dbdd85db1d7f2070a1e9a2fb65df7fc377dfed9db7fac3cfdf2036722dcb966f2db6d07fd00a34b2da9e759a0acf4f9a50a6d40ba0ccc879064dc0ba56f9b9990261ebb1c03bde0178350047549030d8e7c96cdf1ef0b995ea2a3808c06486229010301cfa8a2427c2671c99cad71cb111fba87ed09ae11759eb22702f6c4a6031d37c1426303da2f053b4f66cea600dfcbc317399eab2b99f570635b23c62855f950cd9ad5f2230ec90c93c91f6e08ed5011aec5e636d1fa46a6a23483683aa5a97925b739a4dc3cfecffa12b4fb21a3897ecebcecfec47219f84c46dfcba7736be9877872746ddbd218a1d7787e9775f2f8bf0cf5030e59cda0ac5c64dddecd5a17e5490178a0a91bd29623a7c0e9a638772aa194121f7c134d828cd0cfd9274a126a9b30cbc7604a256037d1e3cc09a14c658814ba6c2abb4b7cc2868c25cc6015af23ad260de92d73d910ae399f417fba80b753ed6f99b8de4c078bb91c418c7df1c4f1e8deb39aa0e006c0b9d80758509d795a6c9cfee6d01855936235b0ab264bc89dddf29223c41d4ccfe820374a0600ad634cf411eb9fdd44580ed08a7d96a4728006d8bda624fadc509e65eb07ea3196a67545208af62b6166c2b5b3d93c8c3406c5917be3ae0f5b378c34c8ecdecd5895a6a6652220e24d3c31a848cad5190ac60aa0a5683a50fbd86328a9981762325201f5a11482ab36d153eb16cdd3881efd4c4dbb5a55108add9078ace403f57342edad42b95799a082f9554cb26e014ac00dd5ba1db83a009d5b7b0b0a12feb94e2cecfe51038e3a405e749635ecf13f20949caf584fab334e6168b1d61a28731487ed9187e92a5a9e91150f6a7881ed29c1a92ae470b1cf47673d356e760a6f778d2355938a5d1a65035034b90bb392e982dc7a1a92a11768ab453b45d70d78dcd24ce2a805506b6df04d57f95bdddd32897d8731a7ac426542f553992126f8320b7911548c80c0e09e28d0a6a2ac6f24a1681af9cecad953eb88b6aeaba99a908051e5d490641381d52ab97deedf93363640850026d61899da20f6fdb5069b40c2a001780cb672f227f41ffdfc5e37d91fadd3b49a9fff6c3b7071a22200f956602e151ca7858034e531bbd70c26285475be19323aa72b663003c85f4fb2e9ed86f367b28c5464019b6c60338190e970a0e36812f7d624d9ff2309314e60740822eccd21c2abccd762948749d2923903ed59656e81cf86364172922081f74388df8c7805395f5a0e45febb111605990b3574e98b4485f6ca6b8e80823b509d04f9b236cc48efbcd84d91969207a31244a437aca389561e35ed3acd773ecc5ee41ab0047a82013c14ce789c88cec6d9707885635923d035313deb006db66109d765504395219de949544aee7685d20518acddbcd663e9e36a7dae37077b87acb447325889ef59a90f3da5bd7b3a0b4046bab5c6cb5934d4d583346603d53a3fab7c893667b5f9bdd3de2fb2d0e9b31bebf27ed272c9145d3d2c7a2f5821c5681006f423013e5a0b20e3869463436cd7ab18b5fcf4d6d366aadb6b04585931c6298a4d5b578db04b3bcd01d541a9de5d86eed4d8bbdcdec45195dad813d2ff420051c8e116b8deb479b48053d086d108b692b114436782e80a14e6f57acb439c29dc9d211367b4bb53f21c8d60033064f26e215b9fbe0b1e693b49ada66b73421cb4303f87643efd9a5c61152d13a0eaca7701e7681e7d7745b341f5b960b7ccb4793b7ad5fd648d2d0db4b1960b65e075c7043fadf7cb7eeeadf7e78474fbc2bce8ebffcf5ab9933f30f27c00970e641a9c37292c5f4bf06c8d24e846b79216276012aa4636703697db1f5ba8d7c49409fda0fbe7eb4fbd3311310e9242d80f7900365a41698ceb1cc6aecc0eb15d30466640d119aa3395e29eb5a6c6185dd0a0c3814d6a11a5e3db594b0d9249b5984769d204e230a6a81135659b464eb265057e1a69bb80e59d688085dc87fd91c1ab61027b88485d0cc0ca5075db15b9f01cf02387ec3bec1cfd02a9137c234231c1c491515f4a1177a5d24832fa7014e1011dd462a4ec0eca3d51c23a47bfd68518a5704ad11a0054755282b0ca0ae2cd045a8c958bbd79693cdae0a480a7b5740b61d850565708e13ad18753fad874e707ea026a0c48e8c00984a0452cc66ce494c8b3cabd84e4008b337a3ad1fb147221be24a017562684dd6caa0be0edd620b55c102eaeda33dd83632eb7700330084596fda4fae67de7b23aa95833fefc3efcdd8bd8de7d721196ec3f975e8c6db707e1de25f98f99ccef7e73ff7bd2705be4d6bf17f183ba182aaab9ab28df29bb023139380d51a589c0126538027e248fdd27cde6ae321c55dde035c1803b10dfb1a85e5da13407c486543684462598e8a026adca8e0f08e9540c5a8dd464c19c8cbaf2d2248926db8110a93719c4e60844c164354228be7a667522a20624f360dd267387bef22c2627660c18a141a905c0c028f91400da49c609901cb9cf55c5f943f63c72473ca5a3f369397b7a09a0ee57985a8a2106ec44503901b841f7bd27ae6b505843682af8017e8d620187a230a05dcd2afadc50255f8a284bc59afad0c11ccc986b2c1ecf5cd0518180e4c3d6307aca980370ec0fecb9bc292dfb8c07c45207ff828bbb7be2b6685777298d29f5e371b13a09403785501b806e1ddec74d7735c33c9cecd9b889c3122be16c60551641c046806e0e6ed604a04f3226cdd22205a14948017943ada6341ad25824dbba16a2a64b8fa88c240189108ed84576b8e38c7ef37975b816002a63a3b6f9a6cc4712ab7df56c73fc27144a215c2fe007a07dc4281df8882f2de029ec5c1bf20ef7111a27092e3da7bc1a7093189e27e252023e1e2e83a21a61420170879e6ff2600c17061f491d83f3b3da182088768677e893bc89f6d5ae07526969bf7869f9068633bb05bf613b39a746cd1218faa439910d5c9efba44025f01ee67f1ec353a5efb2b1e9aec8863012c163bc08b753c87c9ad67d0b7d1210988cad0804b041855c18070b02da0c039f21cb0d36c5cbc1f1479b36ebcbbe27cc1923efef2d76f2d19dfe6ea02151cb8bc22b1e220def10d843a4a58ff266ed30e2266429608e525a2c69fa3ac1166f87a8ee0fa3493213aa05f71d80ffbb780bf262ea881f0f4820b55ffd7080adaa329020092a2e259aee74a063e244f2f226c05bd613e006e0efa5ec1edf04a405e03e62046f90e8bb14f1e4c1f027cadeb474554653e4836010abd4f38b815abb040a1e9403ecce0e1ec8812838053009b0cf646f69b43ad136b1492bd300e6dcfe4202371989265027750ddcb74bf55a442d8aa37613e32334c892a40d452d9018d14fd604a5e67f5b782ffc0fe6cd8664aea405032bb66294821b3d39bc9088f7104a5287907d449fdf6a690c28a27e21a5c82168257a16331ef5968e6b896b10fbfa2edb3b5133e60fb5414d2d22498a46842b0e285c8d3d6c58a2a71b30e4dbbe1697be82b2a892b0368626cc876e222f680eb097a7d7815bc3030073e1e5bca51cd85b66486751144c7e34181019f0e794e84ac5344b4000cdf68787748f7c6d86d28ef07d6b90c470378a840fdaa0df09cab87d2ed6cd6d2a6f8e6982a13fa78f0317745c175280d9c4a907e1192d51f531c48b3f00d729b2f7d025457cc971d1716e9460ee5ac51c016844e968d24b37c4bcb912217cf0facd201ed20119ec7a6f80d151aa78c140891d315201e4a6e97be39069edd5375f9ed93f776cfc45f6efbbda7429d109722de9bde6efb36ae909305a739410b7a1087e0edc857e6edab0b99e2d24893a7fff87781a5450cbb4accdcb88bba2f39518fbffcf55dd17f57e8fffdf3f3df3ffde3eb3851ff38915eeb901c327728e20e1da01056be39dd27e1b02be6e5c4dc754318a24f1773543a72e0acb58a23c200172aa35c132ab7968cd4084de3090cdb1bf479b2e2c167175025ae17c97543e23779f95043850c55f1b616dab2a683c29f1865000552a1480b5fe2a0c6552285e40acd79a25b641da8864a763ea1ac0045b1385a71de5b0b9a0f9e2b360a8472e37733a95f2f7169521077451047431b81d4b9515964f25c74028257321315f2b994386021540aa3ced62c693dc9c828178d139dd5f994d622246033c5181f76eff9419be94a40cfedacfad5bd35f2c5a4db06ae44548ef8126cb73c0bbd4da09d8c145ec36f33e036817f014e826e6f5d01f25c52bbe0d9c1258a80233bc6160a6fa18b42b6e791506d996aa095c615d1b940b78311084c1f9a5d44736fbc2d89936372c516c7ee3c8224177d6dab2fce26c64760de0759a326967f1b369768c38bd8c72d388c980dbd80a1a7258d07124fd70e0d48426980cf96a0b2e0bc416245a73f07a8918bd2134515cec16ce66ea143ac13a4a784548901d4537f00839c54b3c9ecfec071b45f0074dec475ed41c12aa803cc7573a4f9546c89db3a146169007706e939f88fe643c50ad8b28d84362b929b3a5ab7fb0721656ab13b1f3b8bb5eaf563812e0878a74d0ae3ae88bbb5d7d272da90e2f66d21af8c579d0bf0d38a534fc5d7bd1cff183e6f7eae582f7c2e55b2b3d3d0d8cf315ecff1723be5ebc11bcefa7a9bfd37b7196fb7fe7ae017243b05f57de1ce7d77e5fbe9f9eb28f57f26eb297b16d9da62c1fca1a6c806b49f0f4a1fe74ae32845b708bdb4c1f30b6fee6bf3fad146c51c54b57b98614f4e0434b39e14b137419c1dabf6aad7b374a818f3b440eab02a2241dc57406b35e709542c714e1cc85fe16451a68df105bc3fe25d81f248f5fab1222fef8b0f778ac4b2b2bbb7a7fbc24b3f3dbfb39c9f9eef2fe73f7ffafcad11ec74f08ba9a6f628fd291f5b4ef582bfaf1fa5777af4e588381b40fed0b06dd7b32dd23de4bb3b3f963ec3e8dc77d13a1e4b9f4fe34be6f1cf9f3edfefce9f3f7dbed39da71ffef6e9dfbe3d0f2cc6b580eb0ac053047504100b0c2d3400a4064e5614a04c5b0758a27a8a70636c23d641d3a899b6b2d812b3fa1e0a015ce1857437bc0ab903d720dde2c23a39d0589351059d9d89c32594d2820c38bf4adbc02e2d662508f28c3d1d596d522cac82c5260b9aabd2c303b2a55deb00028644daa81abd70d84d3a6b15623a83c4b04952b6c64ae5a168a8a3876e6a81892d30d4596b1be487948274d419a451736f84539648dd5118312a64e8ef83a115009081bab999a5b790d70d57f064f603806e69ce4d6771c9ce68b3f0cd600452f0416c8bfa16c09ac0ad3640445153dd4cf5356508e55d3dcc453ce50955b610023813e3a980850d156993c4a33956389ca77dbbcfbb8e2093f024818a5b015d21fd821594fbb02d7b24401f87005657f074e82410bdf0fa48696cb49435bd1f0ac58cba3705b1e39d29f8adcd40456280d48904aab9b38d0cc792d59e2ad9ab0701e37a6840ed1e6e8f03bbb98364045ea6e8046ec4b961c8ac4565f54eac8dfe8c45e0198d7d922ebbb9da8a17d0c8ae45f43a61836e1bd144ee11717fcf7a9b41e7e19a37211926d16dccdeced1c335f137e19ae01b5f73e95ee33b6f623f882c06716e3071d0da41f3094c9280fc8f001da4314d1f6f418a42001c0d953c9bebc86e3301d6626a1b176c22e974b37f94ad89591d6b75c25d138298b68d2d406ae628194182898629d76d27532c1a660b9065b3059225da720f13c49d52308fb2d95d9da1cac516bd379ee70e7f58b3b951cc50a22914c99a3bf620395a2a7c5ab03a16a71866fc03c165cd26d7e04782cba0ee51dd6c430ab53c4c6631513e80184e9e66f21bc3358690b93a4b736994c2f03739ec3832f97310f7b4f49b3b67629c09635070b8bf8b2f8819fbde0cbf33c17ffc6f3f7ead2867fec3e90e456b28b2d23c42e7bf14f872b4525f177bd3853d389719e7481070eed5e22ce5ea4d29e4c6066b7083ff82bcf56ff63ae12cf991ab2d253dd87b3b7525336e79b0f514014e059b79d1a09ad9589371583b6327460df02e21154c8a57ffadb57a718a7d803b8161670054af45e54a2a85d5199832032d067918716b8f6635f7cb5c8f45ebe63c975c281be2ab8114690509a6d12c55ba924d99d308d46534df1d421813f7c61076dc1b443ffeedf3a7e7bfbd7c1d65ed4fe8be157efc5c52396a9a9b384431118acb4c3b7d5726950aeabb115d03ba2dc84421937a8067b6c3a34adba60798fe488eb845cd0a32556a68dd6c9712fa2461bec7dc61b492c75862ef20a56820d9a8086392088f9c30910127cc793a5549f5075f17708a3b7ca670c5c08fd2112fce2554d04dd788dc7fb2ad6bdced632822a82ab3a1bdd27840d496143126a7807f864ed93a9cba4cf660664810285d2383d7e8958ca8048f6c3e99a57daca4a75593d0c00906750bbf4d6d1993a37f047069e0aea5c333b2dc5b18a52d92472e2e2e1129c9881c002f051416b5c28c999364df0d5983b63a81f11ea1fb11451a14dc1929031c615695f9828dba044a584d527be45e7658587becea3aae062c616bd8db3775bfc6c5254d22295e4dc03b7edcfa8243e13665eeceb37de717e6da37a7952d50502db38b9a135046fada2299d4335c36d0824cf9702d2e491c485820a13a3d8cc8bc27db4985f1040a361bb06008302d7d0e027e13ed2fd4ce08fc10067326ea95eda3b8be352fa574e6fa2ee6f6b61e5b0fad3fb64e4c1cf838b02f62dfd39c5be61edfc8638e76261e101a026976b2d050d09501e7a62fd116ea0aae3f7ba463d475a999339bb4ca9155cf6842ed425128a8fec160670f1f1b731e26223e20f3834d3e40c14387fb8a8449873469206a050dd9b02e423e98c02a122f6185fb677a0a40abc828091da9344a2224e81a4cc2019750028d56ea892120c7af7621d9a283364725fa395e5671126515be735bc39d00673187658258ab30183c014589ae806adb99e0d5a2c078125a50a4237a931980ef23aaf1b7dd050db0cb0cadbbd90db12ed3460d1445286e289c4bc081aaa102f759294d4b6c26f75daef6f7e9986f33f14b33f8ee04fe8fd3a7ffedf30f976fae6ab694158a8d27e20e86a247a0e09f04794d6a5af66329e08d07439c96d43f08593b663e16d3ca516358cc3e7a545b36ae1f050ba575e887cc3da6b977e4c36a194191a0f9faab2f74f8de73f7bb7cdffb5ea7ffd7d3f3fffbcdf539222e5a6a2a1f508f1ea49c6cdd9cce40d081139f91a03b427e283538451179873c64d352b9d40aee2656934f770a98c98624f17252786db5f50f76a6ebb9021d1e39ba27ba7200ef8ad81f0aeadfb432a459924d26b950046a448b7e8ff3fa91b75fd7e2fdc7d7fbc7c787dbfe2fbf607b4befbe5fdbf9feebfde52b69a0bdfe715366f694bb04d599eaea9ba4596a58a92f7001562209ceea7f1449abf5873257d25c431939696ea1003a68617dd6cc72deb9413ee5498a688db3a5250d4d59fa823fbb35836fda9aa4091085d5529e05756b8d7ec02e6206af2e3dd9ca2cdaedcf5c5030274cbdec0a6ce0ac1384c96b81a17db6fdafde52e5ddc8448a7e4daab2ff252a4987e9df7da46ccb6549b5f4dbf6dffc6cb4b4504263c3a609c4f2a8d4c9564746f418e511bd7131653ae7759429493b000c5baa19f4cd653ca1a8fa686663ce72692d8d528e91df176e3dee7f71a7ffd47ff3d87524bdf809f623ffd930fee53de56edffba581fcbf78fab174b3cafb764b2ace70280d3424e797fd8fe01b36a4f103b161a5193a8a42f4c4b425ed4936f0bd0dc7897647fdbab9ec9920dce1874742b2d0deb3278421087f2f36bcee2a8b4925b0cb26495280fe2b8fd22b89fb8fab8206b5316d26bbc5e90c380de9ce2099320b63757c5fcfaa394e49135aa32efbb201c8d693d676d4657f3e96d66c3f7ef52593fed7e3ea8be3f2dd14c5db2fbeb534450001033178cfc45b0cfd12f223dd05fd486f603fa6bd610714be9ecd2019a10cdd6267a58968b591d8d010ad2f0da9525a836fd89cf605abb54898c0d52b27e6a21545c213145c249543813573bd828373114ac6ec8fc1cc2ee245c07e911754408ce9301f686dee6beaf05f2f520501d8bc1c01787eb113f6a399eb6b6372d50c5e6603ca6580a7874c172c30db217921ad993aa1d7331273b0cce8c56eeab10cbd98cade50f4dad87eb3151bf7168fc12fff8591f9c531f9de68fcbf9e4fa76f0fbb481a199ecd2a41e65047fa0ca302c50669755aaa8620047c13e8f70ee24a7b5fcbcb00e0152a1492a8a831d35460c2e0b71da1ad1207b36ce1c221287f099af3a340f6319800af39fcf0a4c2190f2859d23ee8c3229f13cb7c6ace47c964d2e974cc0c27914292235c96b2cccc2bb1c6c9ecbb625fd7335c21736e7d925c2748c950725b9002bbabcfc79ad716910b346d9ed5a8bd815b55a3ed16938dd7b3da2d46876042606c32e307ceb1e6ad639cd34c6bae162bd0f61494661560419165a998eae3a838523b7df82857835b170479405e0a0aaf04ca2fe05c35351b8fee4dcd852553dd7db32cb04296b97c294bfccdb87d77c873f77b83fe2b5527fe71ad60da1892341fac05776b280bce855c8303ba237576def0dcb9b212ce3d33c1c984ef0670841c84508e2d0818dc4ccc9d104242f3411b565b9034622a913caade88fd27f3884d183b71197c9f682fe76c2acd24650d521985ea693d6a9d1753a4cb514b077d29027783b9b470081390ef9f58a9efbed93beff4f3f3cf3ffcf4952cd36f6751156486aaf6544f51a40469a01407892eda5b9c2c2de38a16596768136cc05f05122038ac3a02ac142e42943300542f9be7ddd34ee556d204e43e0000c582280ff0b950bd0e9476946299902690da787fb1f25775efedfaaebbeff7f2cd791d9001a8a21ba8fbfc1f3a05ee8372026b2a8a73b8972f860da8ae27a6f1d9078995e1df632ecc7286e293ad197612eee715d8e03984eb0d380ca86ad8af4b2ca1408067cf154c33da065b6af6fa02121ce37b382220323e581935b89b1b33d09f43b305823cfae5f5186525153614fffdedcca071dc974e8d0577316e77713d0fac8205d9898b20c360d38615a01ccc481850217dccf2908429726da5c9b0ef724e1b2cda958359b13801f292a941acecb5d3f6c69a3dc14a4bb7eac60c37a44796c0000a43291246aa81600d0cd334f2e5c9f5230434e39565bc85c2b3efefa6096a00e27580e8b175a3dc0837720d94f607d33837f573b3bc5bba931046a2e639898e90d7a6d8620e0734b1cfac8f261fb6037b830da49bc3af50882ee372187d9380f753fd8bcf8668ce9e4f8d342abc0e962c418c806208c0c7a42b6345a3dd7bb585c26eae7135617a28dcc766b955e7e4b46b4daf33a8c8012b2c82b101eece3266c9332111e93f4e67782be8a9cc548933b2e60499b093e90b18af9c3074d843d5a90484f3568eac5a431978746cea1ec1632eccbdd8ed0ddc4292088a7d54daa5169b9fdfa46a4b9eaf3f990962f66a45c52ad2be6d6ae0ec48b86cf6babba75f786b67b09fb45c5a4e0038ebd0ac4c2340ef354cb3c149ed79d12d500d9ede81c4c974b7a6863d5d9e38cf882ea8874b50ab5a387a32ca915bc4f02b9032186426690aab6fabad0f8a8742f0214cbca6fd2bef6cfa8a51e25187e67cb1caeb0acafa834e28f5915495c5dfd1ebf722c046e7c0ebcdde02ebe6599fc5b455a6b0abd7d38263de0638b455aafd9586035456a22613d0c0f4dd0e134301c680004b27f17bb30180e4c26eb3a4838eab166038107e854abe84f6be2ff6f3f3e5fe3277b9b7c4fdf0d37ffbe16b31b4fef1f03ff225822d767583ae4e8055894cce609b8a7c1d0cd74d407e231512992188877754114b7e90c1126e64f02075036a04122f4d88628a0348131506bdefdca20122bb022903863c2489b5261d41a86440587ae08b71d2c242efc18a8b225c195a64b559e434104e4804c3354ed861dd21e851f2887267e4122e33ce3437f0c16e345c4ce38ec3248549858515bee4b44e48aade90d089c25da7692f2c6103c56ca59c2442917a5eb530c75283234e307d0c0d645c0685286d5c31c415b77d71cac0498c368643338935c9be5a5fd9d5d5c9d9419c016c2513e566c9aecee27eb6a0b426302eac00a6bbd28886aa019a2ccbbb809681ba34f024af3d0e381bbfc54b8a66a4f2e38567f50b369ecf87bb1388bbee4da25ffef1753c197f26791ca92d7341c141910653d2acf7f7062aad1b7b133cc658f5395c4a70eac1c69a57f859f7041a847ed5f3e956001041204f0481a23c848be4813dcfb5bd69bc20491883117a7ed1d4362c41744157205728c2d90b8a5d660d8064d28cdaba33298b8569522b564562276021589a083610a531d2424d728c4936d82040ae08c0650da2d733f352d2dc880f230c304305a8d05a06aae64a0248d7f01b99d14121403f1817d98aeddc888f97eb99783bb5a5492266ea768546cc9bd60b8bb151ce06e8f5cd717c34f65050a927cbeb8e4365497b63be3120d61ddfc21340275e1a9de3440500e600e6deaec32337938a42a3022fa69134d468498ee8da891eab245646aa2c2bd04c94d1f759b8100e64f002f91a8943c22cc9815027de18127e6f0d4a17bed08057abc26159ae67a4eaa0cf0ac5c5ae120c623683e71a321022dbf18d0414958d54d3e0755794ddad58c6f5a37493373335b8e4eb16991e3c59760b380f3cb8dd49f43ac2886c2bbb7e0b0e0182de6b2c4f4676370d17c0b571d0eda30f7a1e5523a45fa1827d60e4aaab6f1cff805f24e04360917c8b24c886df0c795fa4cbc4a05770d94f24446661217ddd8154e89184f281fc2c67021dd18bbf8902d31d0fa3422e372668a23e40a1be233adcbc860f596ea09a60299f0d7ce893845bf74230aa67187c24656159bb97cee1841229b7ed5190128b7bd94101606762063999157f5a46b25585ce0130ea2cc77207543262439da9e0a8cc33a9125dd4b852cfc1ddd8af1291bd5350ca8152c4e4a57c48c24161e94c42b3d8440cc5a340cbad2c14407593a0dc102fb19f38ef20b6c486d2064601654ad4bef07b6bb8954d5811542112df9ba507082730811dc0a40b35d91285b5874097e978baea105b6145e466f0eb85b61a80695008eb480b1d230fd65dc3982a23e983cc7a0b6e39cc799081f4bbba41a63574306c2961aeb96d1dc0f4608e0ef04f26cdde1235b07b033b94b948dd05b6baab950f8725dbfa8303a3a32a470bc17b22606e6ba79e51d081d0a13e00be75a1cf4db86f7448223105a678c0ab21620092b043477228665da1df20d2a2f1091e7720186636810b63c59106c71469e885883fcc9242eea3eea21762764440f7e02a006a689405c48d70fd0b0b20d20d11a8f2914dc89aa00e9d04236fb042c9d14fd4bb1185ad4485d8b18c2a239c3920c114f62de4bebd420801187066954e082b164f74dc8aec45d3946c4a9c7b794ddb2f8bd33474ddaba500f9a2740c2c224f23333653af5556bfe07d787e20b3cb82ba3f5f421d4cc49fc46303990a787b06143700723f482da165c65b0aeb8f16a4bde8d1d45b3a35ebc2b01c4070e23ba23648c0b8c67aeceea989d05a261343850bad860a55181c96207e454d8159c0ebb575fd5840775c461a5bf3e59044c354f249672c2c03b0976d86efb0a589de0738420a84e408cda505bc08668aa23c1fbe6cfac8dc23067641781ebc186544620c038d0f7546d5852a970dc5f01447f9c1990b31887c09d140400078a1162b528a43f49916048a1b650e7324de8238788c2dfdc56161169fdd4131a0b57578530436b7ef3009453c0a8c5e210ccf70980930ef472f2ac69ca1d49d61f77251cf80c50750302efa1a5dade8715c3f2267b2d243885e55f86e98dddb30d46784c662f35361f7040e71d140b36c047f893338a248e760452508a1525327f6c0ed26f5e66c51c7a841d787e2207d0dab412192947a062d3735060d158e3f96ca62c422872b015c29a405281c60034365055f1abd2d1c26507c8b8d2213555c1ac82c9ac6436f01dc26dd81006ae8358cb14538e694304d84d50120004d241f2a3b3c47c192c45c5522fad8294730814afdcb456d618cae5e3f36b84cdb4a6be30aec386eace8ad80e581f764badbd8bd40e4d8232c0e4bb31075f0da5f3d99a8ae9b696414970271a958c860946874ff138d0cc02b66567109006d1bddad2578d927359242342289b504e87c409041c22a305f6c8a528dd9d357892ca6b1329f1d4b3a7c9bf6e6083b871cff4020abc9aa4dac3337661761431d75c891c710d5f0a464fa8290f26cef10e6c8489ae030b57f2766df72a9847541ec21a8f1c59e1169b90c9fe27283ea091ddaa83881a185b1c484401bfca3d2273649f29ec13e029bce73eb99fbadb0056d12faaa819504abbb5780e23878ed1a4122523ba17700d543a49617141500706703bc31964b622475d44bb1144b9918dc2329c7d0b9c4848095c787412f82d330c06a43ade0f08002f477faa6156b5825a14b82fc5d3b4e0dc614f5dd88f7da2287628d152f10f2121c1e28e660d9c962c7c0527cd37a1d35444155f71cd22745d1b1ab28a7d452dd804a4a898f429649a278043d5ddb0395045635a5968891841b1ac1671974049063fa7231986902a53aa18aa203aec89592412c161c381d3c95da1910d8a346d6aeadc85ad546dc137ba40839dca0a4d8319deea386ea66204939424363f16d618dc72094115498348e51c4e3556690157a93b1a813e44526a38a9d91059cc9ebee189f7047b6adb19d6281286030dca29bdc02dc18182600795f3ee250c2d559a500d52dd5380859170998925930694f0bcbe4fab1209513345474c6694610b4555f7ddb7204df8042b58ab050e53482aa5321a72afce80ac0ad11249f5ce783f24d836092e60f0677d8212f871918b0294c58b5097806247060f495d43687d853d73e61ac3af26198882cb16f95b5ecc261ee3a5d853aee0517edfa519686baa01ad07b2e714cc2794e224902bce60612627d682397b5b9989d501ff62a03a88d23e911594b1b6630e9edf680bdd9ca2690ed9f19d4646764b53d964924c1dabd22cba0e32eac35aee79919adea5b65812c8b8d89bfb297c82202b3733ec259066dae628e2faa208d7ac65e48d2ae67802877b86059d54e5f9819325cfb4065e6b145ea70ac2ba65f2a327e63238bf8036e8c29d646aa060e6ecca20ad36b4d3dc2b88928b06fa105e20660accdd096bd20bee4918669c7c221e2a71914e76c99021f3ab39626037a34f227918730e4d14bc34bad33e54fe36aaf83a19d793d2354af25db14a653a5a29673e0c5d3f9e6d2db513a1b25103438a814c40d82cb9c0e2e65d91c6cb64a575c4ded655299a0ed5fe1de365b13bea7955cc193e9e89cc01c889daad1ba959d54f8b66079beef01fee51f77d37b6cfb1ddfef2fa79fbe8aeb57db1fcfffc808662c4972a26daa8e8818660648b8eb9d807b11607aa3f54278efb1e37cdbb61387e462c014e2a06ee07f75343c3a661c1c365fcf28fbd35612380d4c3d68a96d102b99a8bbd594dad880ebb7ab6bba1b501340ac006932db3a903c8fbeb789151349c758ceab2feb64cce5aa8d9808da42ad78f7cdd26ac212be020842a02e567ae1a0a043f1c204a994b8a2cc2916b740d417cf485d78610c83e3038a00a3db3d34470fa0946ab4eb308c2323785ce0189f8cd24f0e96de36f5856dc137654fef5a6c269e2db36a24b328ab399c3970c29421566f78e41aab3b547e866e85384cf078b8d74b5d12e18ad0597a2aeee7ed0ccedb3a543c19001a12dc0b6ed3124f0ea1267784409e89bb3f700b9966ee7235a89e06a3cb7dd3d0dc41027d67eead4aeb7e76072ec12ebcaa1370c41756dec6427b5ac7b048a99102e8c8d32b119c2dd4d42b8ec89158f042aa5f2c7bbc5f0864f0e6c07355e17105feb42d70d13d81031a4371874df77e9a4cbb8195daf9e605069b63e175d6dab1f3267450534663a3d1e2c01313f726953a291c63802aae5c536cab8d21b88781ea4207e68e134cd9678f08501741c1221d3dcccc18343d4d6766e89cf83723089074a763066a203f3b0db0ca905023380761cf9c299961008e27fb9cd16b01658f17a83bc5075524bac13d3fa6b30892f91fd5d195333c188c0175825f6061a4735c6809778f72a0c35ba858d476746d7fa8eada55259ca9a9fad8470d0b382d50c467a0ba082307231f9949d1bdf3ccc7a59d09f33240e10ecba39e8813cc40f1525dedacfb8a4aba515ac89142024e00b2ed6a2a5e294e38e6c22a6fdc12b25a025d090cd134afdace7665c81c753b62b81d51f0189537e34e1362a841ecd114805e42dcc4e95e2b64dc154c94e1e89dd3cd137a75aae755a14ce2d5eb01ad6e12b9a53394c2c597889f03de26dc029db4890aa87a01fa8e320d708c20400a266c73748c5197978dd34261dfece0ed8585b5cba1b63bdc8032a1790c82b4d3ef1b095d3c81486cd661a597ae10bf8ecaef0830fde068c0f509341d6497bc842a8690c0334338287c79f02bcfe86e2efa56fd7b6284283a00caac5d1ac6132526145175d1c31054795d29089ccf64262f1e1ce8491af3f45e31f748b196b14400ee223331e096c3158b4361ef2e71f5f01fac81b8bb2a3db6b23856e8d93e419c2296be392f3626da1a04efd1a8a64bc07d68da6f24a4af4ad48221b43732ac3b306b4eb7eb8441cfb4c272f25b16fd94544f744fcd343ed8f925f58d9d644b0de287345fdb4b87ad4027c54ae5149324f94078c8514fb65cd69cc65696c34503886ab2681522a85fcfb12f4ede2d438a2df784d93f39c5a440d944167f70573842de2f4e1bbb53c72a325620c612d6d972c2a0460e3cd0eb318082fb7efcf5fbd23e82e7b0ed7171a1770d20f6ef6aacbf9c7ebaa7b0fe72fae9f7faeae3f3f6f74f9fffcba7ffe77ff53a35449b6dbceaa3ca86358cf31fb8193940fdb03f24d5eb5965da6daca732eb11eeb5279d92ca07676f3d9691cad6e0679a0c60901e0cb9a2054af01e9d1f18bf488b83298d7d8f45f329b27af84bcc28bf7d7f775efc6f7ff2a541f0adbd7e7bf9975ae7b1d6f954f4315bd7232d60fc4ffba2bef88ade7b399f9ffff1f76f2df7bc0e169bcd87dacd282b29b7a0b32582cab69ea487fc9d75690305f280f36b563be6259212544b66b0b275c4f30ad99655057c723abfb393d70c925cbb625da1ccfa62ba26169290b244056287d9a72554d3aa758b95d4b34b48b9160b60fcc89e99a6a9220a04b909c724dc2e00b6ed494b6ac8f66e2bad1acde880991453b505b216345a9aed6896f02a5b86ae996a0f85ab77196168322305ab3716f31980b46debd582139140ba39e988490469a512539eaef636707ea6069c6b33ae44d252801cd650e2340dbbb146695c624932b6b8521f3115a6cece889c2a3ce684af039e7f05d647656f8432535d6cbf5449421e3ab05aea00a1c0daacbfec669855535187318040542f254947ca09329b87d9e26359ff69eae4b92feb3873525b496b6af6b7991a03419b384bea30154ab2f5188e74b841852a1ed88eedddabdad326a6b468892977d350496cd3a08f291c442d95f9504a01a473afa1941e4a95a48bcd51ec91a63d52415afd04a8feb0ceb0270a2491c5c029a0e6b33e8805fc8b687f798edb547d778edbce3b73fc879fbe8ee8fd137807da18c219508184ee6f2fa7b07f474c2e02f367b729e9c3d6342f9ac51524642c04e68863df11c7b142c5696bfc9457d45bda3b991b4b0fe831f0549915e1d5175aac44e561808419f962d29d1e2d8f0332798e39528fea4a17ef963bed9e2e3a16bc6092a810beb953b97b9f4faa25152a864ab052f8bdd5116932fe64e6045be3029cef2d07b34ae167c307b2c7ca516d1122e79c32cbcc6ffc762568f366a1548266a19cfe7aae03f8e092591a3a89902c485a00e11a91404eb10d1630940d567481bf41992ca9f486a1ba84b843d589abc2ac6ef98d20013c18f68aeb0525fce8e6c27c2971d6a30e4c7c84dc0b330b9ce3ed965d902358fd1ac3147086d4981a0bef6b50309e009d71304379b9d3cc690e1d93a89f5af1f8cf4668d03d15198ef63d08495b6dd1e456bacb8a27ec75fa221c8fc0ec4422388283c55d0e35d14503dfd1a554d0e72047d18b7b9c2841c973e50e6c640c780694a2f10a5837e1742b7da7d288408884f15661a0332fa7b98f809164a48d209ffdfab10cba8e16ecaf1d82b332242ade44c1ef456681ed95a6e7f7f8bf77a7e0782a756eb257150390d1738407932cc8d40917e424c759f3263e091153222b9e32d2185f3faf6733ea283606b9a6c45d5795f121a212f36332ffd07323aaade7283c46c219028b049a834fac123d51c9cfd8c36d3fe39c8c5ebc39c03eae1f61a9da4add369a9da09643b62c3ce2c09058e445e8ec92d7adf6f142f82db80ddc8bbe364f7f1494d2acd78f77d78d1f7ebaab15fef0d33d7df087cf9ffef2f8e9f4d3570228ff330a21d868f3e390b41e76b68dc2cce9ce9cb421695cca90d4362276a5157a279b266a30fa4ca6946bd2adb026be98d1dd1bb0406cb0ac349f0608a14af700656fc8ae36956d0195f67a06c773267a7c674910c2839446c84026f36840b503bef0fe918c82b1b958bde15e74f5121f064fc46b126bf449bfe204ff142a62197e400694d23385faadf9a8d9f328eb5e223638d399a00db86b8631003e099748717fde9ecac03be0efaba739f7401aa9c5946aa15e59229f2deadb3e08ec83a09e79eaf108afd19c7b6c8149f2a4d093dda93498e6688bd832b159d1101d693e49132e55b7198c1c7a9d2c5aa99eacbc67ca04aeee007bdcf33501022e415999850256d3272bfcc6ce38478e1aa4792078c41e40166a70ce48a429162ec33d9a2947671f31406e40977c87fbc751b2a9015e37caf7e63199e9af1b733a08cb086587142988042973931d4edd1359778751f19ee5d79b870b7cb8a06fbb21b21be26bfad142e8cb4329501b2a9301bbd7534c6293d40b33c089658cd84be5cb0a7847c12bfbf6fccecca28ac17269d6f438dcc2649469be2fb36e62e8aee8baedbd23c17efcf1f4c3b7a6ee0a110d9b9eca4c05d519c897b2d7d1bd6818e97b3dcdebb90d66135e5a2a27d3186a9a5be97b89615f0c0c6a5800ce64c6f92231e9849a34884201252e630d416a3617210775545f64b078bcb0029470c3d35b6f57ad85281257a69adacbedf0d78feb39aa0d859cda63aff9492b1037dac02ea4e6e4a3fdf5648af8f8d032d44b90c7a39012317daed3f6d1b2c74b5f5b2fe07066f67cf602331e12785c27bcee72cc6c4dfd85b55b4eb4836d60d4f7eab4d716d9a17d13aeb6ddee85dc0c245f4531b232bb9f2038a9407588fb2e30169ac81cce85bf67f02a2be111816e2f24a7613936255fbb00821904f323784079110fd85a2f385899eb83480b40167327dffdfa577a4f7fd77b1efca34a8cb86ce8361c958583a85d67ca5e56a758bd20c7f414bd3e12d1d11d75384e6651c63512a975b2976223a4234e8f379f4a530c870b240cc06758655088f0b0580181b8c0746362783988dd1f2a1deb251621870f0a4c48e800bf7d0187512a2746affa05a97e5b66708a968c97225bebc5c9ab16e141a53d15199b4c6afbd03590f30e5dd57ae61257a13e46b81b82b9d7081e60b4108d4fb2b374292b2754ec995b4d65abb25328cec204c6160090dba6973a310360b10e44c830e1d4444c52f9edd87ef923637bdcc6f6c0d8e662de10c865718cef29d78fe0b492592f1d7806d513d19a3ddc8aa303c729b202b6ec055205a548a1d3d691eb5989ada3e032ffba33e4bd35c6168a7bab8b6dbfb7ae7cfec75f7f389dbe35b578f454261020cb73410630756170386acae4c3d72d8e9994e02ba585666b464eadbcb64c55eba1dae4d31a9624e96f9b7da42280b4596921092e43139a025fe478969ae15fe557662689d9aaddceb0aa598480c94b63c4a4e06bb5c63c254121c0ec5b5c2b293c9c0b34d160301533de665a353631d92a79c6a2238dbfd8a84295441bfb0527138d9bf5c5627506342e5a83328836b9417201f677010e6d1664b0638c570db2f249e1d64cd2b68cbc0741bac64043539f7f01078f06ffc2d583e60180ff211b19340408c8a00505cbf744f935f36cea4c48752f137d0c05ca295c875d5bec7dcd91dab20996fbf55c724db2c02723038fc872e4ea8f684f0257c778a819f9527069d69ae60a6b056d92740263bb9413aeae4804b2c7827373c55425d88d59832f7504ffe2334ac9a9ae30671a7d2b36cf173cb11925d47463d60ebb974fa3a9543c2cc6967040f9f828a9b638b1a1ae28aba62ef66015efaeb6fdbdae544868f1b10c0cbd5a7ad2bad9cb46017b45a15655e4eb12cfda24dd4abd43876a9aa46ef0f5a64ce6c20ca33d49e36312e2a9900157e2b25188115c819a32016dbf80bb5681d0903a56c731c00241640e7b4cd433543b81c0dae3e0180bb8a54570252450363c2a9e747fd092badd07de6af14fbc5bd45a6220e817441a65d45da9c65df704dbcffff7f3d7b1f6ff4c6816b605e8e01f4a8565bc0037c85a1a7c7fa7ca6a325be75641dc6e3c1022a7c1e5642b1ff2896aa819b03358261717dce6007bd52cde55c890ec363cf2119489b212c5d67b9a8f937e550815e80ea6048401f720b05e3ab0eb90b96ab2a811c7ba454231033a193c045291264c187620922c4f65316b0afecc12657e7105b33777f765db8e7baffa97ebf55b7bd33a50926262f25186a4f254677e94f154145673bb00daf7543232265beaf8010e7bbf677eb95eef76cc2fd7eb9d7ef9f97c6adf1aa6420e454f2417592dcd0f26325aa8339f1036b1954a3f00121a91eb92e9091e693d02a3e35499d9588f3200ddcd0459d41c2e10698f4b2ac788c4dd35e95c2811c6e33cd691c60731cd42f3093911c8c96e8565252dd049fa6833e803d9314c4f3e9ad127a7e85508efa691a0c7efbd20db7ee705fdf2d7979f7efc3ab0177f42f7d20ed80611335f5049059ed08a42d4416ef69d298f853ba8c7044b650f637ed08c6aa552898dc68257024c41cb68bbef8ce0f9f47a79aa2bb25a41200238189a48d3cc84fee2fe7a265801df7df39f07a77800503f4fd5778f0c98d50badf94e4a34565f7b22fc7ee8e45d64586b28fe51e6836a9253cb665ceaa64a9ca8ead54f0b2c7fde7204b992235865ac212832da8988e00a14069150b9673acd9348dfbcaabd32571a7999683930ae3aa6d88aa000ada04f5cdf15947cd611d81825c996197180a100a40896956b5a970ea4038234d9f916d17dec229e150d471cae039ec238111aebf4ac54f7e7c1da892b80f26f3e084acd941039ac29736ac3eacc7d448572f02e33e790813459875281f584ad6cd12b2be4cb5f8432033e00e99a85d52964ca2936440bf38bfb62b14db7ff5fbc19ba7f7a19203678933bde9dcb9c9cf76633f7fc7e3efffbdf3e3d7f254b6afce14a0664dcc841804fff5c57cae3c0cf7c904346bbf3f32ff6390ffcccf8ef57477fff719a5e79a8dad2acc761d6cb93ce968a3e62cff7679058f648e161131ca07c6a869859f6956d02d7eb939a8a78949a727b509b9e7ac0267c763968a9a9afdb5f5293d6efcf9ac5b6d6fe8491598eaa69343f5929a9af873a7b6a0791624f52e6b4c3ed0ed741d74a7df00fde467d92be8e52377b54eb10b143472a8dcdda92da769d690a4a0cf4507be4be7e8c529fd021f3b86a9a6583e2653d6b6affaa66624a3fc8ea6968448947fdfe0cfacbd10eb6e29754700bada65a2ef630e55157bf484e6d1e4b7e526db6e1f5099b7c7f1e35f57e00b32102c87d3c966ef6c4c936cd836f32336e7c287d1ed0597a2c9a4a3be948ad1ccc18a8df83bda8b743d1c7a2d442b06103ad7ab3476f12c74aa3a0a55a53d387d6b2bd30197a68320f450fb7f37c7fce876a32511f5b49793ce1f376daaac9fa47cd4e3d74f416db9a35557968ba526b8702dbf550ebb4bf6ab3dbdfafc1bfbe3fcf92668fda6b9aed4319fda0b2d29c8f6569aaa738524371e394efdf99e698b3772639b6df99e2e7bf7d1d4aebff49f23dcbbbf99ed78f6b90b7f0b1d727b19156ae67216df911d6fb254e07c04d1d16c71110172746be664ded621f40f9b713544d7373eadb19e09759a0763153e7046d71a575acb88ead38380a358ba8b2738c365426b84312cc508e6cc284125b961c66682f350893d106fb6ea4eb264e0b18e8597ee34c5aca12e2158147036007ae9f2bcd9397ac0b0afb26fb44d2b8544963eb8e438eca3b3f04e917953024ca30db7e05b97e5460192e3867178147a274566749bf4cd0be6b72425e56d370e74cf57a9e8efd2da04325288a78f58d3718ca45c14a6559eb083910d8877c0fa86300aa4f1007846139c2c4379d74c0310add813adf5b606d2add9b78e7bfdd6117fff77fbcfcfcfc1f9f9fcfdf66cab56a85f0eafd2fada4520ffce40aab63a4d20fda3a364fffe402fb7ae4f76753b186c42acfad1e5ae52f3cc5119f5b5431bd74c561b67c2d711168b596177080a2bc895be5609b7f7fa6839f69269d07e5690e43526e6cdab1e5bb25876223be1fd64a450fa5e5547e75b6c3dbb3a91cecb60e83573dbcdec08bdd563dd86d1d6e37fbfbf3f8f3cd544ceae0c8889b3adc1eb37c57da487290a969d443a9d316505ba3faf81e6fa094f93cf530151d2f87a971ea5fa6a475c007149a83fff27b9b1065824da03c9bce5c0ffce4c1d6261444fd8b7d62839fa2e495aa1e64ae34eaf726800f10c07fa9f350f7379b0f333fd5a2cf6f37a2fd5873fecd56cadd5f1dcfb37effb14c4dd3d65705fadd3a989e52e2b05bb57baf58e0daa18f17534aeac10460897d1cb01d64ca550ecc41cd2db5e5eda2871c79323b2ff28fcc2e9216fbe0495f224f66e7e5426afbec3e2a5c3955e3edbca6f3e0a43819ce7b182923dfa9d4c37ef08b9d6b2012db0fbcce981bee11e73af01ebd6df7c807c669f1c0765ab1e7e5395f708b07dce261ef0ad3288b59f1e3a0d253ad87fdafd5ecc2af9dfaae62f06b89734f52fdfa175f105adfa0b8426451b60872bb1c99f4d0501d481fa57dbe34d496bd6ee0e777e4ca034e545941019fac802a952ae17676a4aecd65365a25c5f4a80cca35b6ece3e5f667b86d432b806ee27507c8647efd93eb592a32861629578929ac0e7fdd994f3a59ef983d2fcef3e3ece3c5fff8cdef839f011f402b2006c04630bd86a57a91a0b860ad2b746c2a3f1a40232b37e307c5e1fa2a536825cae42d315770e7f5b7b3c2ef5a50480ed08b865c5e0d08ca4664e6e164012783a15c5daf01d1e8227de308b7a35eda247ec67e6add8a0713710ab4783f38054a29f17048a2d91f22dc1e10678b0d69487c78b81378523c24f2a2664df3fab1ac996628736e2425594cfc594e89a924ed072f796389eb028d1508ac25ac17c4e78797ccda05d646c09441704e60422de2fce28375b22bb5b870aee8e77a61aa2dcee69bb6414c3a4f552bc08ada4f443a4fe2eee234c1afff82734414bef226379c6330df166593c0f4e5a3b13414cfb7021f8ec7bdc0ed8273f9967755a55d907c490add933f3f7ffabcfdf8cd899fb2d40c96d61fe05da4c14250e55f11d5bee1960dbfe59d7d4362fb4a54fb86bd36b68e2412807d29945e5811bac8b0c156c817b15742af1998fdd69b567e327927d7b3891c0036be7b1a5b65be709adc913f43c9f585d3fc2b77f3b141fbaff5fdb3149787f7cf52ebf55ce890d3916c662287a544ad98fbc02c157ad5a439aeb1630613a31de9e6dde40d69e1910adf200906d3085d1473a2d3a9278bc84be37a6e141c5f78d27ff674ef4f158ef9bb3385bbde9928fff8f4f3fffedf7f3afdf8f91b4c129e25e5ba82d89bcf1d28cf8d90b38358cf0adaff5ae6fe178a8fb0e46a1a8acc955e25ae99ca90a879a53e0a3277c6889247ea454df79b02e79daa845192e96765a4bc661033d81b529166539395b3838e4d49e1af8bc4690be793246d3e88b65473058fd16c61acc43ab599724645c25a1a74491a4a68cbda83991dbd2134bc3273006ae969d4b1e5b0269e78699aad92e748664edac4446d66acbe2a00c46a01047d035a5c1b05258a7db5fdcf35922031c1562aad1e84ae18cc536a34d522ab3e9631d2d24172f58c0c81b6cc32b09f2d60bbadbeff19eb48b5f4c796cd4eefa96670deb709f8c3d6e26a6908e8df67b3c5529274bd7eec15775a6a4f738c4d461a22a68f09a35319dc5df64625e7a4bd07d1924aae71ce34aa848a5412316bab63b5c97653fc6df4df5ecf22cd5fd04c73948d61e146f6d3d1cdcee2354a5a73ffab955485b9ad92d6842760a8ff48027ff568efa1957e3d5b77b6d291e3d191c9a008f8e864a94f071e4aceac216873ff0b6f4ec928a98349b69ed93290f736d4416a7336f3a7ea0875a59c19baebd07ba68dd89e1418c0bac016b3668f53529b15844bda0bf482f92e82fd6fc5c17bb2e4cd4feec994cb0f2f2640beb1c5b76680b9e863cda93f20558e0b70262882a67e29365f1f72a8cc6b64550e10003ab9ae6dffa68edd81bade4996988e3cc1a7a174ffab4398c5db2e7c5c3f0ab46aa4096cb62a142e2ac0e105081d320dea4d75075a82f25b47482850551b1512775e83012f6441426619638b845322aff330331949a59dbcfb301c2a204116fc88c8fc843e9e4b2a8f32c669121dbda166a811740171cfea6c11005425080ed2732b5850724df238258dd30e6e761c3dd58d260c1904416129da09dcbf9c1990d14a70fc1311b42135b4243d61751c2bd523b2855f4fdd679a27d642e5d436fb88032bb53256884742d9c0241233a0065182d5b2e32986e679fe8dd8148d3c133b04fdfa50a689e6b611ebb274ead8353460536a68eff286ed13e1ee2ce2ae3bb3e7c7ff7efcf1e5eb84c6ff44c67b971ea4e723f2061f1aa3ae19568382efad680e36634a98c164a42cfb7292a94ed01cb216c0d6988f5a37c2dce5a89569bb5a03d7a5424fee08dca2f56897dd905735f74afb19a429d6d4819620a3cd19e96e845628af6228bea82319d7f9d8a56fbc7ad0caa8bc56bb81ec60f0c0dcadfcff7a06452f1e05783208c26ace5173c6f7203494ad6a6643451900baccf5b16afdd72ff488e7da62d9098a9b997ae20d3e0d86e104f0be5fdcbe7903013710aa06e144c8f551a5ff673a5a81d358488259774863362a09dbec4e8f9ae7eb73bd3d07ceaad1b7f052bfb989370fcd6ed0e05b78c4bb138a73e3de7ce29e3bd3e9e7edf8ef3f7e6b6aed102fac1fe301cb4f1da90f12b6f5346b30f378a5512e2aa9d40d888e19e86cba4c764d24606af3b67aca6ccba9613999cddb0d7080a6f021db7d8606d4f36112f0a52effade98079bbfdb0a4665781b8b41f1e53db6e9740f6b05f02edb7979054072fc1f3a7d16f97b0f6afae824bd85d5a430bf3261420fe637a1bcf7789ec86c81ab94596bd8e6ce85ed3d238da4331a5ca8b038b367bc40201148a7eb724490da5908369effbeb596c4551a4f195b54545fd7e8d03e588330d31856936c4174a1280d10a782b0490cb79c48605bb779bb404dc266bbefd762401edc02841fb32957622c1a39b35a12943c5100d65e09564d4023794758c00508ba8855468a639af44a374a959a5d534bd395175d498c1d2fd099a22e51819aefe083169252899c285edf81b9e863d3adbcf6de07d0ccff50d82bd2c2232395891116c3ac7d84cb00ede745e44d357e29ace67b35c9604ff62a2f19c3600f38359d86ae3b104e82c8dcdba52116b6e4d5301ad76b3df8d915a0913dd2ba67f609d5654ed0a10858173dae1285dcddaa358df08884886694315ca864c6f774d039c4f0a8cab02bb6d01237f45692d35e6ef969c3a2af84a0ddd6c431e1f78bcce5435a60c0863e03ca2a668d5885be08b8ef6ae2581bd19f76e0f32fd8feb476de41c1eeb0500e3136853accd68a1b5a4725270f58d8bb654083dd060fb9a7a4726a5620db1b163efcdb68053c9be63927e01fce23c297835c616a10ed5c9ab004cb3be6dbf2b7f214cef895fecb8277d7ff9c7a797fff2e3cfdf1c475c9920d5980425a6fa4d7067b3a7278b5ea142386f47252a5a3781d39cbeaf904a0128bdd006016911871318004d10e45284beefe4309981616587538059de9102678a0a718beb0d2593c95f99f552502a80b780ea99e20444666a00c11bc5c66f9a7907ba47b6d9de00e42a89b907f136f82460d920d7cd5e7f071879218ba186e2c0c633005c62102301c39df5a114ccc0db9ef094a3de2382ecee8f7408e8f158588b9f76544f9b3594410e01a4d74817b4d0e956518fdc7638ccc63b440640068a0d5546ac21364594778dab37e77594d0f92523d1ed4fd4420985f038a198907d7f9aeca3feee54d977be375dbe35bbd94607c07fcb83e842835597d2061bda24b5ef6ca7590333f008b45f64d85b1d643384981c283aa61139802939107dbbed2dd7f380c7b4e62dde8038c48bcb95e00c3bcda9904b439d990783b539bb42f6a09733b576d434d73803cadd6dd814afd62ed1417a61d7386b0d816c0902c9793499bddb9c4369382f052029421a713955a3bc6961e044070cc5f774fa819e98679d1de643001b8cb80a9374db1ec243d8c7a97780ee02e05cd7cb35828aa1dea02386730ec030fb4f3c2f680058a1ef51a79208e70dc601208b929bb70627e122c819a03a1d82394b14001190ebae02a651d86cf05484154a403a53c414cb640dec906341fa48fdfab154cc6d7d94ac693ed446c64d64d832d7b8a679d1aaa93ee450c95904d85dd3b0321cf7331ff1830d8a2b3646fc864d7c3ee1440f363d70e69a958199fd06ae3efe6b357b353b32c232537222d1074d7c7e27807869cb27405b2fd81e263058d0e40f0b1cfab5d6703bf99785c9bb82e4f742e4ff78be3c7f6babad8e9186ad249ad606f265f23ad41bcf355b2f26a04718e412b6e56b03452b0a99d7707465d1e248edddd60793c6b63ec9fefd423421a048a0f477d1850d5abf2025873210ab4701be5ccf7122f0a3289f464475900c7232875d6a4bf341572789a80daa8964356f6cc8219c95fea74e882558ea234857ced9c5303562a2c3610139e7d569f2a38c9e7463f469344217cd883a11a98e26024c19d20cb4fdeb059487b47caca78622640e171b58e1466a6469edac7e828c25a1c9c8a93d5b3720eb4d1c311cf2ae6f02500e70c14d8294ce3d5cb5462acf36dec92a499c7f3222022f3c9baecb4f2f339458b62264cefcffd87bb7dd4a8e2c4bf057ec038e196c5fecf6588897986ec60c0609f021dfd82e5551a843a94acce464f1eb077b2d73329479a84e48d02006dd90c28ff3b81fbfd865dbbeae05e02860a446072d81ffd267721b85707d6f1cd8e4763c803b401a5c451906c05674915b0964cc38a187f8615a03533836cb2b59b6f607f14ea849999cc5d80d5819b5e8a7500b62b457c0ba56813f384c94fd84af5f5092e3c9564725ee00d7f2600a82a32a07c0f9ed21d4b1b9d2fed88d3ba98acd0368526912b3c6093d550127cd641123200cc9c0dff75e9f64ac50c3909c81fbb3a87ec02d06e2082392724f0094dd88da001a04584b4fe443432d82016add68b166ef9b967c438eb50c10295d65bc7ed15e8193d7ec00993ac04110d23cc1aa3b39f3ce1768f9c4561f5fedcdce420fdaf9a9332d757192ae878efad4fe5ea54a32b558bb3e129421f76e88c9f8fa8690fcfebb1ffeaf9fbffb83029ebf2b4360a280d44a3f169975365396a24b7fb10b428f09d720da6f80f8f16d37496d50a85a08ca96f5ef76c9963c94b5f69264d55fece2d249a0ca7794408674fd6af739934e95148c61771c64206c84d8b27e826dc5de9566920ff2ecb034eadc09154537c7a890e306593f0a2268a6bc80b71bf47cb50366225e340348f980a7229e4b40da9170ca95be53acf9a08dc7f5fbc9237dee903e13cf05dc0f640a41cdef1b8528cdb6a94862e7390bd03106f29780a312ad718067b80e4849a0f748663be240d8e60083400f24f6004466270b0e7b31b3eb50358e792decf2c42eaf1b74948887e0c18cb595930460171313591522673c7a91436b4363a9ea360fdff632f48fbe4935572841e37defc3b9764e9f5b13ee3c766bd6fdf8ef3ffcf8c71838bf2bc900a41188f1109c1b5c4dba3914751b15b14264dddf5b657931d23541d810528d44104690a5458cf64aaa4a78354156b323602004eb277b88b40e6c3b6512c276305422a3f4ec0bab538cdd961d4fc482ba4e2cb31834a02fd87ca2349221f2677612b41640940af3587a581308889cc4f49dd300d608827e008fb4b0f6c62821a437d07e3b312f41424956eb93858a7cd293850e4ac20e4bdd777501e9c9b01a2d16659071140500ade8a61b48bbf401ac9a299a3a91736912144636f3f3be011d260a7c9249eb300cf74f33d4f9c1f2c0915cc079adc9951cf83dc12968c43003f9a8117d14d83342e618a033e2aea104c66ba372c2f789fdd15541142544901f2cb2833ee76313829d005abb53c2f431aea695c5d2651c42264c2bb817a9c70147b669281a8ccd051205b23410a406edad95eb423f41e2fcad7940cc5037ef8280d9924a0548eaa21d6182832f8d00876f809740ae0939d31c6137387a905c16a6e08a358a90301b0e8874556416d7376577c3fa7bea60cc05f23fcb1d17e1c5c8b6bd09d3397780c034c951d685046ae4c263654ecc47e427c624029b94c1a4a83019c898a51b7e8e906aa4bf20b39d6c6f51a82c19ac9e9897c4fddc9876bad9688c94764ab04d4c3707981d5c5c6953cccbe04c857b4b76762be94168042f6aef8d7992ab28c77ecbbb9a3693cd978c9093539095b88eec624e441c6d034420335646df20a531e41ac81c6314c2761935565d2428585abe11a1e4e41b9c9c609897489205d09c835ca412aea931fc48de60a5f0d0ba016937970a4a8675fb833a21fe78f941f6e230f53b6172576a502fe81380ff5d80194c0e5ed914406a1b5f0ae8769d9e48a8c7487a5d6b17d512895542758edd89a86c88b3b9a9a0085407d700b29a9df0b704f30b45132c8e48ea41d8286f22ee056819e8ded06006ebb4c1e841340950e7a3c4de29abfb662d87ba218461c5c8f5d727acc5319c0ef0b8a5cdf40063c601aebbf9fcb21839f0d6660ac59d34635ae71d545512b2e0cd1ad1dd105c43f5b2811bcd900d8db7d32dc4460a4141f7264401ac27ac411cd3c42646cf8fb451563147586b555a4c7b344405da3256343240d9c6b69a6021863b7a434d61e4cf8498060d8c86faaa3ccec5d19925dce9c08b7919f7810bc6a8847532ae814f8bf8c9141958ec4898a77393a5c4a1d72faa3db901820c9726f06cdc0c597f5c88172428e0611ba4ad0b449fed8c4f7d9303c4d1f2d72f000af335c8a86bac1c5be490241b540c178cdbc942f6de086e4b8f1378d11abc944268018a3ef613902889a54b76efa412c217eb1f1960e6c96f58f107abdc219b6caf4964f219453fc7c3be3e291297420dcc651e21e22872b0d4bc809190e49fc78630068f25a97a9c94c924a0def56e13f43b5eec312f403735cafc7130b301d2bb52bb81dfc0b0ace74eee2392050193fe040edd2cd3a40f6b80ad267cf1a2024dd710860fd7adc11841f668adec27f913195c754332b8918346d2761e6dfd0306026747deccda841bcf7cad4c36ddbd981b979b898b2c5023c946452615edcab83aa0aee1d98ca9f9fa04a4ba6895c72c7e10ae9e63b7c1f51596ca7cc6bd74eb4cadcc47708c1d388f5c9a03e8db1bdcb16d326d4d4e6e24c0de91fb1763cfa95281373ba4f049b5cb35989cefd74c2cd8fefa14e3a71eb1be24449d3644c45bf0855cf8d10a8dcb44fb6cd35e9f2671f18eaca777a531a56511c1573205d7a6f4eab9c867d779ec5a4aba637423145ade0d901731022bdb9e8eb99d6c5d5a26984fc8c20171876a3ae3a39218bcb29e814c90d00d2b0502190098c302cf44d29df782853994f94d1abeb5f24d4ad550784ab1641524843b290f5c98ac9868d9e03ec7f4947982776f371398a90752ed4814da9c1e3a41880c1c5824c33d8531734825752b72cc33fcb0f56ca840642ad4cd415db7931d60ef2079dee06831b4df35e68d28ae6f75b64e3eaa41443f3712ff9d81309031319a17d218d6a7879020683ce377cca622891b2026b7cb8e93ece4764f900170ceb36116da08c6fe06aea742dc77bdc90e5ea08b7d9023ac532fa2d910ef3100538b329c99a3d5a0f38f8ab4a57e16394fc20eca460baed4c501074fcebf8655015612fd6b5c5d8850087a6418545a63dd98d4316cb29401e82185f8fc03846d9a68b08c3dea00fb8e80670cd54e6aef957c1729272a239842b024e6d6f3cf05da58863e48e14466000453859a3222a4b973d6ec6170ea2eaf4f59ab20e6a3c7d61e1642552acc87d36de9c6c8221ca5820bd5a8550c408f08973732c5b6b0238d60fd38b5a51d969374f21ddac6289a24017725fb9dbd3e01bd000ebfe3f43051c986c7d5c3c270888b377e79a6b0be954e90ccb0f38e2335e286c6f804e8a668f103dee9455538f40a42d450698205d5d3d6fef610816a41dabca180e09e95f99dfdf509fe51ef2482187b79004958de0412549092b37f3aecba8ed9baf3fa1a4dab96652b1ea11866726b6e52515828ac4347e6ab50116fd1dbc87c876ffa63470c3c2a37dd303872c309f3c3cf7f4c7cc8d76f866af155134a703e39277a8fc53ca6ed8009b5893266981e4e9e7b16ecf0f3c863a38c0faa4783a8c8e393185ccc287deb9447703de0824df43090d3da98c437406a843232813b4c5c927281c8c931e670465af59a4767eee7fb275231f3fefcb0df7ef8f9a6b3fa879f6f39ab7ffab7efff9884e0dfd16506bf91b74f66e324b4d515338bfda56902566f22e169d3c5c341a970ed02334a20604982dd63ae4e21fbce33ffc4117c1113731d03312168fe0452efd17b5332ce797d6ac8cd50980e215642036f99808252b1644edd7b9dc59a50413d63bd83d6690c512ca8af990060baf531d998f1caf96ef1601dd0bc72d2e40b531a605bd4498db5e730be26d1bad66665645d9cd6d05c662f76d0fb0dea52129e6ed21394a73f2375dd63140294aa49d18357a33779c7e9e0cf0d01363e4d72c710de042b3c8b68613681da65665f2483dfa5a6a02df655e493e88c9532569a459d31a46f08ee1196ec00ad3a2a19b080093c100b0b09e9984183d980d86990766aa0fa282b949c50ad9bc76200d9de73dbbed1d9b9c063d9194c8130d9cbe3b9f3ec9526b9d057c11083b00e41b6aed80f9acc8c36e71de5d886362b75318b81bbdc01dbd998540175121139d4e6d8fbde15212ae2aaf42dd19f498fd3480513caeb87933ee6f1ad591fdfdf9af63f3d5dff2051fddb03540c1ccaa7b02b2799e13d99a60e2fad1e5659c8445cec841021529c4d37f65c4c98b84a4c11ab57a43d8245e8c868776c7cf30c59cc8a6dff13dc73076e81a51ab7d2a25716172375cdf7a510369a98aa8b210db88e666cc65b257ccbd6727732f5cdbc66599f14d2c2bd40930cc1bfdff9f54976b1762f7e7d7f6ca9596a9a70732e164df35ebf7cdacebdb6c1f2def924c29047ce5abceaf57c030817509fc26b813a7922fd837010d0a64ed1438c1eeeb505283fb3930f0739126d9d7bf02382409d60c1fc4113066cc1decac056c848b01cd2bd31e9929738887841cb50e9d68a19ad9df69816a5dd42662ad0e2d11786727aa66521ee9cb62f0f97195f8d02341f36c75b8fa7b7366406faca6fcd97ad25196fa3e4fa360248ed1123af03c278a653c8817509e3163206b1fa8632a209c753dc639db8086f2d972a0d3a365a037875341ef247a01c1a9032e197c40004d213a1f981d37ebed8fc6a28db2691b5cc71417b90d4f2c8dfa02302a151ffeaeaccc724d104f2a48923b0e6e9b0eed977d07e71afcda29f6a72a6b0d01fca178d9d430959d898cd142f8eb853a76f949118f466f439bc929d2e7fa3c91b3de2e9ad433f968121d46e0ac13870430afe2fcf35ebf0f586d977545aafa019edc658f6e29e91b9bd1999ee91944b82822b19ad6a19473f41196002a9bcc31a932a7812818b9cfcd8892702fcde78742df2226e65bc3e61eac77d0f7af16b0851543cee9c4e37de3686d2b11840a34b269e1d0b2fc9520998a9738766b0a39b60c84f1b15c10800afebbc42e3c9e0334114161654c3cab14894d1e86905443c9c1112d30761eece3d8cff9abc8739c749100d78673decae1a06054d32c000cc5d8639e937007c2bd9f0b1c31261dd401808a521fa152f78857a160fcb9810d8ece065147ef68eea47e469e9dbbceb00960d63e3a379f43185ef7ffb90baf7bf7d73b9c5b7287b39de7dfdeff1febfc7fb57e3fde648bf35c6fff587efbebbfe31ebc5ef40a36d524b37478a9df7b04fcb5060e980bcb67758981ec68a4da68d8c9eb55843ae8fcf19ea8dc12cedb2f22a7541adad0b7c767361e15d6d64695656d842566cf6acdecbf4959794eea8133318560acb720d01bf645fac6d82ab72d5b0d9648289b822dfa021cf5bf2285311b59c083b4be5caafd031ab336ca392672b66925611429d350329c8304047b96a6869cd27b261464fa317afb3586bc94a259e1f4a22a37dbc34f1b44af386c409a162b3c058574dd298a576e4beadca686b1764314c439a5ceb0b456de269ac325607c345af33c5ba6a70d7ea9224b85a8fae1aa5c574a96585866c2b4d2f1594cb2a49fa2c75e1a560566b2e4e7eaaee19fdbc7a01b1492f13081cb3a820994d17e226cda3f5ebc08c170786bbc5eb4c5324fd75032379911abdd5cb9ca48382abd60d08d9e6f091680366a02224dc91ea3b879711e348ac8c3e8a3247a887861e0a2e7c14d1d0b3485bd81fd847106076c9c58c751b86729dd17b5eadc880c5b0167c9aab6ab4b97ac8a75a3daf5aa633e63e3b3c355291633735f7520743ef1539a1ad03a9bc2ea4478b410a9327a1a3f6a93104d020be1c059f6b0a40a6e60079ad1ad2f694e9702429a916c3b34e3a7ea3df5131e8a557c6b13a44bdac18d04d113d5385b1640ba03dad0d28be8a0cd43ec091a5cbc1b388288ef58e2a2203a651c8d0183f0e2cab0e78154dd198498b0bf46357e4623944e25c2cb1a45cd6857cf00693387e69ad088868bcf81a615e8c32e6cab3165febc88d6d2c451a7c1f5d91d9180dd97be9bdf32f842f56b35c6a2577500be91273c8bdd4b190f5531b2a4717f1080503495cf27000a1b4b26c84f166132ea9dac8df3591adb860889921135f87262b63c2e25e0b581195441ab391ec638c16e67fedc8299339d3960165613141f8d7314886930fd33d5a72a284abd2b9db7b2e73c2d3231d61faae5002ac01ba4ea7c723c4ac9e45d6404e483720f657a4f4cd3562f5ad988313f84eab87ba5dbaf63c6a91b19214d5066c8e8978a475cc8d0adfa38bc7caba3ad37806ea72bbc12916b2349ecd7bac766b214375f8275dadc4589940a8d75abc0f782bd748165264b6646ec5c7a1310a3156ea5a485b6b9e46b16ec849c56c2ead32a262f1b65a01e3d6960293b24ae76b4f246df568e28968b17bee65495874cb10487444a106d24b56f4509982c05874ac1711e43acc0ad96e0d219d5191a7d51a6ddb0e9ab4e82b032c9286b87322db300d4c3cf90a9108ebbc03212ec47e74eeafacfa5ccc6faefd3cf48f1ac07f7ff8b77ffb83d67fd3df0ca061605a6e554abb434a3546400c4ab21db6435955462abb8abc0c8491da63a8477a64ea7860d2a7d7b715bb9b15ca9595763f4afbcf9ac9a7807f9fc394fcbf05980c317cda8baff19f15197efbdf6393b2fe9371e3fdab972c755d99c582f819ee255e4b3f2cc54374de3b9d0ff118c3fc3f631d4a35f5fc2144197be64667f2c08daefcfebffec7c3f33767fbebec454672590f32b73a0c38adf7ff590d03f6f9d7271129312f7d947ed0571c521bc4afa4286bd00c3a5835e53f9119efa532796f86723e1ec62c6e895b5edd072ac9ab173164b4fa4e7cb41212190541a15b8e01daf52c65ae2ca19385c4bb93350bd894afb1f0226fb483f01dd1d4caf824d12080b86648c09beba1496af25eefb3b2146d403a6d96f13286a44ba0e7d6cedd564b07a5592da325ea4cdcf756e6bcc6591d01de89b42f490a0af101240b154064c07b3adb35445769fe103246c5cff6e8455165d5fc53089feaf17e20df226594ae32c64b28d07e8d4682d36c3e08c223b2493b2a31fc5a078d573f5a195863041ebb89d43180017648644b5e54a26d471270516215841b5be44146b450da1f2c6509cda5c35d68d7d0cd15ee59643d7600bd8a1c2d34bd9dded4460c824e9406eba1b8879dbbc8711f2a1456556fd175d34136612576349f19374c466dd98aea43a89375a5fdb199ee1869763b2a800342c527c69b71c1071716486c34f5e271bdd1c9223459ac3aa2414271290d0686c188402e18326ca57d8ad5c0dd929b278f2e89413515b80678a9994305819e158b32abe896be7e915077c3908f93ae68c38c672bc6bc2746cf4301795896d69e2409f01eab34b29bda8c1ff8832878f3b0dd9d12af839cbe7507955bd6c1f83ef348f1068a7d45b28ae95517a80ecbb08750d6aca5fdc1f1480a7c60f54eb4cb8835fe21a42692cbf724228856c39b5cf32a1de9f38ee5dc35e978085b23cdb7be425bc69bd7dd10481eeafe10e3248d93ae112592489e33bf866a80d0a5c0fb2c702f0f708756b49cb78711930d9b7d9b0a38eae71cb6418e87414eac9766b76ec54414bfc3a4d456643d23ef41328a4d98e429feb0626e6173fe748018d631966deeed3ec824441bd7099491d58b695c22d4e9f6d67931f6e212fefa45e60845e49f15ce1f2d555c796ead553c7273b13abefb6350ef7e47714b47f4bdae6257547eb57500bad79584c6923ae1d83a4b17ad22a7b4d76279473050a301d0d902501348bf46c03645ac4759c4d21783e2029845617cc26d333c4f67486f20a56c2089be583e13e741290ba63d44f67087c54a05946a7966229516ff846c8c56093fe55390f0e1cdc11001d85564d9b1e4d558f6dd5f9f2ccec861b0fb81603d6b3fd7f9ee8412ab9e37d9c3ccb2d21c0cc1472b492ab6b10736b91392cb51d9850447db99fe7488ad5d429004439b544cbc38d3cd773dd0a6bc5d4c34d870017920f359360b14a36808ab4767b104c111df3cf7a0523307ab47a38fc58a5f078515a2f2a0f42d9adb206c00014cafe0795679fd2215809372f43212b3a4853525b055edba6bec99033dd2ae4f65ce6526f8036a261a9b13ee1a3cc464f28254e43b0db26075f22fc7f04913bc358a0cc5f669286c24472a2420d6575c251ab69690cc2079449af1443d04b2ac146475da1804f32393b9036e59cdc8d45e50aed0ee428b67b77fa85c31b64668b87856268085a866a3bc7e71641fcd4341b1024fb292190f38a4f6275fec4b4f3c55aa1fb96fa4c433af2d86c0bcd297dd561907c3a57075c399dc59f8d989b5aecc458cef99e18f7c11e0794583a19a403f3171743852f92494744fda6b34da3adc762af7746699c7fa8674762ffdeaa87660c2fc46c8633260c7672cf19f9c192d4cae067dfc7ec3090c235cd08a1f8d19a8b5eca103b6155879444246eef74426b012646e21cd70e29ccc2386f0675be759a851cb1406c6fc18c93c2248305831da41c3823238c55b3a0b80bcccd7a7dcc20a5dc50f26d40e66b438f38548c5a6d74ce4d9f1186a78fc8522a303103f9cbf648f63b5484389067003086313b3aa81018f9b389bdf5a427a412875a00227ee93f4faf1ea737c770b3792076eac3d3f1cfffefc97879ffff2fdcffffd5b037f08b3875c0a7ed490c9cadce198f061f038f63e11605fc38224202806d48bced0487109ddb54d1ec37c71cf489a179dcf3011f6e2d04bcca57615a4688acd62073a1e184f43b93c0d609e027e14da516726155683513c2f0c8b85ecf2d0827167a046fb81a813101990e2d98da3c4f35cbb7032ebe25ba2984b48d8a965deed2699ed258ffa71d0e3eb5ebd3518be3afcab43e25bb39fbdc6aa5d3ffb24470b789691cf9b7f190c0716727cc920f9193d27c522a37838f61e6f675a304f4f3e5fbf084277617f3562e58f9d91d742e8213508452c8d19611b96ddc1a0d55e04496a607204ae02aa403bf066b9a7ace236505bb29215cac64bd8be33542e26821e88a4b150726d76ff46e05967f598a4b3846826668d5cb3ef1279545041b48c034a8141e300997f031c11ce24d2692c1e4e38915d8396985f03befef1826cf67f62c8fdfa88bb31e07efaf9e5af7f94afe6b7e7a9022bdd001e3c3e210e0a4af04e8ed465a5bd58d8453773631a519fe3f8712606b5b7c420264fbde0caf188b8a64303845dcb3bbf7e99c45dac653eaefe22d2af1d3e3ce98f306fafb1a26912d3cf71ea4b16d3d7279010260d51750d95605082bc60fb9857bfd7ae451e41247c9dd050ad96f9597d7e4ca5cc5ebad5b738f08fdd7af7f0f3c3cbf77f10bbe76fb76b5af5e2179156a63db432f4820df9be8ace5cfabcccd2949bfd7d03e353bbf44b7ffbca73197259c53a37fbfba1b92c3f7251cb45359786d59edeb48759a65fb0d9a7afb8e19de3a90020f9302f9bd02acf4bbdb35a8be845441e6b18f4e33249458a5f47efadcb8867c6e67c8659fa6516356ede9eac2c3b729151d473b155bcc57b94210fab8c4bfc3b5f0ea454edc8a54ebe8814f7689fd2673c46b4519defcd76d152e7bdaa159957e01fe9c57b9175dfc3bc7e18259ef0ab1f642d751d40c1c4d34423b5b3031e66b176c1e6ed81a20350151727f75c6ce4e263f74398f637fbe1b28a776ededa2697f866e2df5b3bc66d1feb5d0c8c2e172975fc5d4784eaef97d68bafc7fad0a389fa5723e4ec8929dc9c775be80969dc9cdfcaee0960d5162fde73693110a3a1d0526f8fd6e269d42f3ddea17ff5224a5ed622939baffb425e2c74eef757b8c40556bb0247ec02ec388fc1182364dac95d5bcc4af3237abbcee252b4742bda1f46597ac1665fadc8055580a536f444a8f9d17dfac0a1d7df2ee9b9b473807bada5aeaf9f2ac753dd879d36e735b4268783537e71ceb80fab63e9bfccd2e381fbf9c05f4fe63f7f1191d22f31bae763bdce5a64610c368c47ecce3b93e272c1a0fcf3d39c98d4f55e63c65cb3f7d2eca21d28af161d1abaff7d980ced8a8348925ca06b152d63dea9151b60cc6df76314d3bb364aed97d5cbc04f34ae37efcd30757a8c496cf80645b4accbfbcb82f9b6c87cac0f2d9abbbdb77909fbe9d28b4d6ef6b7ae177909d1d042b0bc9104965e06848272737edbcbf46b45e759512d4de3ba639416b36e45f3aeb379cbeca5f7ebc9ceb7345a1401c73f3f4d80dac988b6ad508b4c2fd34b052d9e4b9cadf456cb25fac2d0013071e625c659ff33992ff4e2a58d3b8d5e9c97b08445ee6d8d32efcc7be91714665c1d0109256b72058889d89db568d68bb6ba7b8f1d742f2665aceb7b27ded9d2e82919fbe15bc89a094f53bcc7e56db7e3712787ce9f9fe685e7decb9877deda459a14e1a5513bea2f4b8aadc7fa1131de5e096fac9dfbc8adc5f3f92ffffa8d5277fe7f95c1fa042b6a83ff112bb612710fc96f6b848eeb545f2d37e1cf9152dd8d9f24dc80a69e087c147b5d984ad6587c0b47123c1d7429319ce3f09d49b1f7bd2b2beca5ac67a63a1311072ad82a7e6490ffd53c169d43c2bd49130138747c72054f6e7c8eb3dda000a2daa86ef68985ba7dd2ea392b0a958fce04edcd3f0700bab211bb853986284352a09e30a9822d862cc0d0ed5d598322dcf36dc198463b2acb9f947bc6bc4324b2c30eed16f7efd70ce094b0cde1fc21e6a890c044b7d31e5e4801f2144bfc3b8989c3464fce1cc0befdc1425ca181a27954ef89f2b38d02d2b3ced2e8915aa5c30b553c1f1ac15f4fa19b53effdf047f3ef5bd35d15e6a4f5119a3d40389a3cc3cb97cc09b6678e0ab6067affa2207de11ee020c16e85b644e21850dc847b9d7313155a8dae5992aac01f1963b1f5b25273f8627b129482707f90f75814650e861d2418e07ec44d07a666168971bf0de7dc582ee7b440b167be07f05b0dd74860c7c09ed2c5e31b09a2a3be3c66f2bc221f74c0bd1c4317794648476a60755adc8d23805b73d6f1aebd3b8dd369d3aa610a48ea1360d3c9e9938d37a537b24cee39e933809fa042df50cb7d7fc2c758f3b4131a66a1d6147f6a5e3d1e9205bd96057045d2ed93b7ed15c544e944fdd52e076a8584f71403d2294adab9bf1364710b14bcbdedfdfa0cf9706edc9815df3ffcf81f7ffd63e8dc7f478a2c0c665b2829f4d9aec87eeaa8265dad313b69e5a2a31d00e631cd48461d52baa759c6341432f6468c8035a2d92a20418b8ae7dec110b78fed53cf3f91258aa5494b050ed9a80d5ee626c43253bb5ba1061145a91f1a6a1a62c1b31a202c2752c24540d4a6dacfbf62088fe8fe61651a52cf65b4743e6c486ff77d0fe44e0d496d952a48a1182ae07f3304889afbeb97d6573ca4c383d64ad3ce7c109f2db7a2d2f2a8a53910dcbbc34f6472fed157598bb1a431e1cc9c43ce3f43391d838cb5cb80dab0aabcb5abd7d2e319f7a3f2a34385da87ce66dd7f5a5c3da66a2c915dd24256d9be69e24d3fb556d45672d7a286baa26102dd6616ab167b9f7b5976e7abf84099d36cebd39c652852877b2c49210d6707dadcdcb9869e34441e20e834e4de7460ddcd967402c2acae0646df2afd3c02b6ed113fb1e54535ae7378e88e8b1e233012eabea90218369ee7eebd575e9f10f7ec408d182ed7e8816a3d6ba8a7de91ca3f9c90ae8b611e6a532e28f0ab75edbf6c2279141d62cc44ace36df482a5a42a070d9258bba2a251157d19c7ce1ed97f9a9581549c514199378acbdb4d810f2277ad82d6d0ab156debf05154a096f81ca1f4cc45313fa3055aa9dece3f6d945e43d518b54c1969955efbdb488f79e3c80b9ca8b9aeac5eab0da93871e86d56f2cfb05290271196a521c8bfd63a6f9a78d30f0523e5dc2dc9c823b744e3f31f5324f3bbb8b710b79075a012a311981e2c65a1def9c9f5864cfc4e6a37f88b63ef113f7909d5f3b1173b000703b4404b3b76818c722180a8e5cdd3d5b1d3e8ded68d2994c0e306c8501bc55e04314328332794e8061fde6720f102d1d5beb395de2f8aea752390249dd5d87b41c263b17b5bf618cf7e0033b1d2051e0ae7f96a093c7b842331f23ebc358700fc06c737b39e95fe82e2875d66cc4a7edba06ffb1400de54d4f62bdf2c1e6583c1547e2ad532e85afcfd59d7afa53f2b114146b2b335ae2a996cb3acedacd9848fd01a413e51c0816aa645fc0ae6d8a7907609c187b159e92691ca1a6d07414204156e641ab024f3ecce011c37db5d5209eb284ca8a8cc27009cd046bab16b562a3c879c30d254a470bdf6b6e708d2f94ee8e15e28b0a88c75c98ebc7d7085a1acb6c1a862bdd64499aee2336e700ffbff73182a07087550969f4462cb4edeaf5e94961e38f7d0c971562712787f2385e82fe8e378dd8d8bb04180f6718c7342ca854d8a0fc0c5d43d4095daa8be057914a3f005f8531899c7d98408b0107e95466a7fde3c73c49a8c811e7316c05554913b011a307b62861dd48e8929b6d174dece409212d205fa9edffba2cf46f66fc0bae2cef279d98bb48a68d51e0e485a48c074c29ed473d6c99ec51971ee46b84d64180b12bc50375e1434e603fddee4a07d8ee9f0f528fe702a7040d6f4ffef190179fb5be7442282f0ba3135a4b5dc0187641cf5838ce0b475049e05d4637358e24fc019610f4295660ea600a2ead1f2570aadddbaf1fe6f6250b848c4a7a29a1dd28f281838f259573d00bf371203d669e3b5fb49318fa906809b8e14a55606280161b51cc01c90d3e0a3edc4b2af05d367b73cf74c1e51a8f4f1e2fd7cabe62fbebeb16cfff0e337e75f43e42e69f5a22f43800f8ea81fd08c95f227244a583b07b2c26a5662e671f9b52b56f9ecfe128af1ffecf7a12312f18422d68abe64de1847e5147a3cf639148a98140a1a9a8d8975855ee1fe9279cb5bbf7cc41d81572c846ac62359328221f0a4bf7faeafaff2557bec1febf9efede231bcf936e91fdf667cfd96f1eff52903cab3add21f612dbf00319b6ff0f767ff530f5750fc503a70eab400e0aed8fe6b3d0211ef83e7c4d5fffe39b1d690a63786853c6682ea217bf1e3161affd042ffd49dffe19d3f5b95972cfa188d73fbe7f76abffdc7fbde99c44070267edd3f5f6226a11af1ded68ad3986149562661eed748533e4f3988b5b7f3c180aa9a274fb817b1a308d319f681909671cb299fad8f230ef12b38c8e2ea38fefa943beabe951ccdc3c2260d134c37cf9aecfdb908c581dcc3b6cea330f69cbc849eda44485f697722f40eb7a81025bd9fa0a3580a8954080075e0e04a3f41c627dda770e82680a400c259003cbffc540c14faf3024b1ff7a67c8c3414e2f096ecfce1c75b3ed21f7efcf7efbffbe1c7ffe39b63ec068bfb84f53f8adf8bcfb21e9796395fbf3443ca7f9d453ea923891d39c7354dfae29b95f9c0b3b8dd09e575206ffca804263f11cb81df32506b6731584106e5f3312f2d7dde5b05cb04703fc3741848f441f5cbfb2e71753a7050c7de1dbd8cfbf34263ee9798abd4f9e2b5cc4709a34c4976dd52acb288bc192cdec9dd85122e41896f27701af651141157ff9581b0fbf6f670d8073f1e14dfda9070098deeb349599f080a043f327ddedd8bbdd8347282817003e7f80449e962d299f4438824644c6e8d4f8b868cdf1f50eb4990896ff33efafa45ac013bb57feeeb5eab8645dd4bbb77e9a10441fbf1302f193e026c13f473ecc5e64f70a62ffa4334ad7ee88e614d82c81bf78c78874a5ebc1302eaedd0eb934e2c226e8f706ade9b280d8d9949f534766ad8de838700caeae067f3b2e2c1f7eff7db58192fba8a3e9675c0f040ba54a5f9d15207be28f60639f31773888d7b0877a139fe27c3f15706e3cda1f8d377df9c76071ea8a40a7bb018128048060220d66b1e75e7542335282b0a1d42405d33ac62c321287a9eb6a6105ad835a3a013b9a559de7fbf4b25e20a77eaa14e23730c0b75835a74de8848b0a13d82d303c51083e8d202fd72df8ea5a61a5721b8a162f8f34d34f360bf93780dbce502b0690840e3f3d89d6c230cb9e3cee74c9a51037767133ce47e0055db93f9868b9b84e65a579094254686e3f70bc463b849fce24a30f15a8b21711b64555c126523b9c04a934d16fadea4239dca09f1cb07994b1cb4365c9dc72a726578681539ca060e263b455c0630ca92a1058e5cfa751a0d9f75a0a97194bd276c70cdde934e3c64b43571c943f0a47a8d1f8224f6835f2b211c7d732cf8db05002a1f4ae2b5c1108b8b97cee7928daa2d5909dbdf503e954725df571e0a735341d9e1655e3d2d702e5502c48408ccabef66eea80c797dca03a46af58ad8a07624890057c0efa40209615c43fd01b8588f0533c9b022773293cf2b05c3da18bb509cd6dd79ceeb1375a5b084ef1a4c79abd751911acf2c5b007ea36aa457003ca30c4c06d2f28d808d480040a5d202f4720f2daac58377808176082a2fed4a8686112782f3a89f236380644943b0d9ebd3d40cb2ca58e63916c11e027c7f90575956b833487e719c035510bae7e7bcea462c46edd1a46f11f1f4f5fab47cd7c65c331edb27593f40a985144f8f41e20c032e005b1398e1bae125313eb2f9b1458e65c225c744b53a01d739ae4812801302011b40b477008e6204d92af34acdc240f8c19a13143f08f1b663a901dbcbc792fca7ef3ed0317ffaeeb696f9d7bf7d6b425c81bc246aa18325d20cc3e4b26d78d13e9e606981786fdbc096cd2b4364ff45a93800b38d3c0e42e003531cb223aec54ac64dd700e28044b30448990291017f275859dfc716bc9f7139b0af8645ca4c54dd129f52a06742d767f437301b0b5d7c9eb63106612428b98cd704174502f7a26b45b0671ec06a757a3505889dbab9fbca046cbd6dbd801805cc0ed9157e443090ecbb492c931d769715858c5a277f6f231e3ebc4da1420b91af906e03d055f05d016575a0846d949d1984d5cce54c3918fac9c8ee40b2ea56b02e9833ee6e9b4649c25eab680ce43f8432a734be81cbdd098b0f5f19c40648251731323d54c93659c22369a1488b9ece493b5472a723d9c8c9490e2c70538c4d5582bcb4cd330104785479810ef8398b27448ba1b1b6032cc024e59e699221003032b0bb4978bdc83ac0be04de4cdae4d983d407e4c71692492c80f213459dab2bea77d3494d857a4e58abb615510a0f727db575b2e63061aab2f466d1866d24d525bb0ebc5749c935055e8145ce1651b26e6c37aba3620ed46982a29a7832d0e612320c76f4a68a223349c7fbf5325ec08e602c64633126d47ce069e06bd6621ab2ca589a97778a056b503d193cf1c0a65d2c611da03cd984e1b213a51620188a938a89e3106c52405f1b64071e61ab19886d4118015f3d9843dcf3269a41dccdb6de93f7e33ae72d136894bc041dbc029cd39ac80e014e9fec9bf70928aa9847a86544ec2afe857030f6044f4a6a9c76ef1c3ac697c87d2b736c556699bd7e916969b4320fbc7e25821d092416397908542b7970b4919108e57608ea6c528fcacecf9bb71a50af2c0d050a0520ed93248c5ca0df37100221fd0cf8427d23a0901801b576600642e61a91fd14edc10e45150d0bd6812beb24c602ce06a87516f706c33f6d0f2b14e9b20e95241528d6f5bd7e032a6f52ea6ead84fc748d94547ad2ce0be718cb0a272599a48d233e93ec0267210717de7764d9f59592e7663722bf9367ad591aa85f9cd5b5fb7b8a1208668cd4956a26dfbd407d8107d6c02083542ac9a0c1315055b2747b331636d257f5bcb95d91b1b94098cce24f402f91f44c7bf1975cf440b55ec1d482cea2c6490bae08b80c5bc254df1ce1a4b55d675d13eba02b96cc41767ea37ad8411dd3484484aa267221404e4ef044c192af7953f20f50df4c529524944e758eae95a45f656d78f863515e2dc6c040ffe502fcf4184bac185c07a648c763f40dffeec460ece780f193b5a6931d04364adfdcd028a976966673d0cd93150b758eef7b384a160e422ac3fd44a2bde7cc0074cc4a2c4d8d58c3c8d963509fb8e84846dbaa270999f2261d99d0da901f0b628db60976505a4d98c9817646d92bc812810e2f589291236a48fb016f5b16211a11e4d88ec082cf04a2b927dd648efdc4d7c4a286454a8070d962b54fc430e16ff3a6098e4183956a651076e44d6c3b01924f0d1b5014a45141b86f6c08684d0b00059caee079216909f3123a1fd562a501eb99b0badbf9c2c63aaad039d0a971e6048107c406842f060389895a3a239944dc8629cd38745b549f64f3552ac8f2375d52df6c43a4fc26216dfcd0c927bb39a152cdccc6d8737c2b578381360050cb29437b58f39360095c8a4ff211dde0dccedc45dff90e7cb64d21740a45040c81fc3470402623e82b9f61d28512f464d0e0e03d8341a86d109cb485898d024620ff31f7b21bd39931c495541ab4839cac42d003da33d3c3e1f63f89ee98e8b939f1e004a5396b8811920e68ab8d1326ed4266192966941e0c724229c9e3958b87a54d1ba489ac0d50c0336010a2b572d9f15c851a04000c64c712e25d77afa26074d0ef86f4564b2b937a6a64aa871dd8180b22a991706c73350a325e99702ae411257406569398faaf5fc22236800f8d03b45889fc9f2d91770c6637db9450773ba7a1fe22c0dec85cb691c1262869f6945cf92407afc59fdb8e80db9679d0d562a8c74b1c1c23a8fd475e18f58905040ae7505bf43028d94163ef99926c83e8af4c4403f427447a6e79cbecbc4901613d71b21949b0c816264c2482edd57f35baf1d7bfdd363dfffab71b96e77ffdeb1fc39ef23b32c02bc2538f6394f9a235fabe2692f3021b6bb24abd0bd761cc8e268459592c76d1323f91d00636819ca437eb7e8200ca27458f2175451f434d4649fc7c845c210d131956db265819c8b036ee023ca56e6610ef7b07db7b6be310ea50e04325adc100fd06542227e001c435a10fd64be8048f36df1f83fb30be2b9dd4805478db4bf5650c4441f12cded357cfc02d8bfc0fbaf1eb1698428207e4a6c74aaf70bbacf5226207d43f02647db5575fb2887d5ef21206e32006d64c33354f0e4fc84a06ba59e0e8c3a1f4be970931401dad6df82c2722b26d3e3bf2dc90f2d041b0f5326ab1431ba0951bb3e20084417ed7015811285003d236d49741c3bb96792f61233de668a1975f992bfff5afb72847e2eb7f9c295f1efeedfb1ffff2d3b7e6a57166ca871a7f6fd3afac21b25edabd84a17ea7e8ac01a020c8caf8f60ac5a1957587613afd5ec2ecb8532433d62b515270d5d72f0a946cd75a5a9c408c13d0c7035b4b5fb2b68e1b1b30ea80fa03881fdfc194d04a24c7defbb90e5fda0bcefca883769bdfe8a37de45637fd703d1e7f78fa8f6fada3cc00f2a76ea5e983f52260fe970d280683aa1e523af86bc3ac5f64a0b6e2089575305cc23dd247064475c813a2a24f5421d973eec541b417d68ad2c3ac8714ed29d66c67dcdd137935f4f58b8e516a4bdaf4f0f82918526399eb69169d4981ed0770c4b2c24ef699573164b10952b4eb7a30294c5cf6136e902f6b002cb4b808f83dc1bd0e26bf98d6b597d980ba8ab4ab3224ed94559fa00cf5cd015306e27f1a6f30c2d40541ae1d1919e55290ca9f501819820676a894550cf183b1ef2bb94c7930d0c7ee70f7040a6059edd0b234cef762525ae8f1cb339aab38907ee2a947d8a3616422afacc1612c64cc3e0c308480c2ab9bc68aec36793c03a50f2a36596f42dd5f030cb11d968783a5adf75cc4f228ab314d2cde38ec007b1e659136508a6267811f2b5e60a5311921322d2619711a5852e09747c94326231fd2fa6c261851830e121938719489ce6c0898d5f855f3b09d2451c51e04bbf4dc62cdaaa145e9282db4b13a39ea80c4186a973d44bf41119f76b6f520c2e2d02314e515621d1caa68bf11eba5c2f7d143d1230c489fd145ceccc58152cb99d683c6edb1e158c3826f76946a6512221096b4b55c6c915e712003b042f932206c8f30031a488a35565fe0f7b7b01e3d9eb313067e6500ba57205069dbce86e8cfd0d2e1ec6dce2a2c99b10b2d0e2fe0401b9f54af9be6496c60b8931ab2f3074d5772dc8349ab378005d82ad241ccdc721342eaa07ec1c7157cb74096b58d2c50e1691e88a32832cdf94d1b9f362517cc91112dd8633228603b755899ed1aa61190779a3c0c8d21cfed860ddd9ead18df1d1505c9e065724d7d946600c343fde2308053d59eb4d39d68405d8fa75a0c1a8450f2d014482d8f8a174181a6cde70cbcf3d04b941c71c6fdd7a76cd281abd641893635873074006186e9d250ff89c2d7169abb208a6540fc52a464ea489314e606546dd65a849a0d6605e24986c61ac2e2f5cb045298afd2daa7be425e2a48dc1b1bae036dd1898804236dceec3148421aa3aea8912cc24ac59b4efa383d0f049c0d6a8aca2701fa795ab5b4b0b07a11f817fa4c1a53156fbde468d1e3400e552b0b1eb8b9bede7fc6f333f5d56320a16acfda81cc54e4f94ec40ae64a13c895cb09aa52fcf58b01d12259ab653c4336788caf1c834732a64d0ff9a9b5a0da0bfe85d569024dd913c5215a809420a1f2026aae3d842a3a59ce35cfb56e445b87aa310f83d803142d60221abcf6ee74161af061d746188dc603e1c9020ffff47f91584342f5c5072f6e1d13c4551ef07e2ded0fc26146bb7a58a3f3c8cd80363ab07ed649bf517461cf6e0fbdc770e196bf05daef2ac3435c3723db61aca704a9858d0c9a5403eb31005801700e06f9c63d2f633dcc78a0793e55cdc0408e917964ac2062c8d35c703e21f91a30f21318d359e93c80b5bf8458f2485d916b4b45d7310b483c01a79f206e6398c4523ae99559a4b9c7d3c30ddae9c0e8f41510ff7a00117fa3ba8e1010d154588bcfe664bdb416f5436ad8e34ec7530824c44f163cfebea2237bac22a4770f190f43ae5be9b4d891d4c082048a08a013c7e309407c31be0ba90b5ae816151e6e15680549635879cc4ec469e421160dd0d3bfe1a57a0cec7892036f2ac0659d65926a1e5e15418d39b9bd488533f332ac440e3dacd6b889a0a82fe64323f387c5b297889b2c0be34fc071a0d124213705b9950e86ed863bab146ba5af2c09aa544ccb5807e494d680fc5d03a8fa1340ca3a8b877c8d4184a823bcf8b1761427ba15fc301d2cef689e90e792003f8c8f672d3556beb17269a1d9347b7dca1dea0213d641622e7394766c18dc55acc101daa38d84e85c06282f7b282316af73342441ae0afc26f194bad22ce6b9a11fb5f4f650463b61749143d2cb5807417d0706f8a9ceaa2687c72f6e32a2457813c888e8559798f5dc6e54e1e8b55186ffe226d4346401670cb23bc47f4730031096f8410f555be166928c811c5a43cc9476b66c2cadd049a069c29ced65c6e3f5584437de6ecc29fdd8a4d9f6c94da3661fbb65d6fcf8ddc3f5a79f7f78f8e6b20ed542ed484dc24a383284360ae4184c210a752c826deea60c990470406675eb8cf6eb8ea081167269802f4351f56960404f05c5c973004ac92c4464e8bb1a93a47444e4578ebbc6af0daab474a22731ea166ae24069efe83b246f4827086531d4035852f61096c04cdc6e0dd318f4912387969c411aa1f4132b82eeebb978a8eea035a908978c038a98c790ecb1904a2c3b1d7e751d09c8312b86ae01a97ec4c4f29001f1fcfe207541f8f2e31460ac5aae61b0688867c5a2b2689560e98579c2f228c8bf506f35c44f3cff7386b6e708262818da016b6fb1a6d779f2ccd3bceb540b43334b20c989d53f74f5a39887dc95b804645a21d6c57c00e5068937ced93ae09f45469f219363e4b0c77c5050cca21677e8d1a6122f348beac38af572bda90c193a73a8734716fc291ef354a3894bb307c2cf737bfec211b26b4786e60e5116036584ce69fb7517d2543673bf15124a85ea96437fa00d8ded29af3a42217284c50a28ffb00c4df3280e18d695a35f04d11a18737083a96d585d2c1630726b278d816fb32136238c338657e31993ea3517169acb4a313b345471ae79ac76463c855e7380b5404570449e60ce32ef20cc1147f55cebcf6160c602dd12b4b02147b15e7a8732146b120ce7a6cf1c3675b1a7c3e27b88e511498ae26fe0f8b5a79596c4ff672b0d88551b0728950068ae21c1c569bc190ad7007316f31c93341eb48e0cc561706a1aa20498aeb3a53633d161244381e48092985bccaa885f5b3f4b750dd100846c8978d342ac87089830e880a0afd1e50b16401961f8cd91316c905e627995d5629e73be0a660d28244c4bd75812bd8c59e60eb0d3292dfc25b4405af8862222418afc8c85779225c028a4f6621396b03dc7185a54dc04e8cc22d7902eb152027d18b101a4e728076f8cfadcb144c5120621e0b983550ac90eb47d103b469edc6c57f83de21d25de5b001c1df69734745e91b03fdb2e33acfd9ae3b126451e70ee15644bf12620419bb1f8b61049308d15d4d99d5d8299d628a5211eb92cccb858d8aad148b09ef1e78cab86a014612a996d3da7c5e5a565a482184d2df49a1854e5e80585a58cee8382b34ab76b0cea0c7b1ccb923dc49205d665d52de23524afc343c05e8951d598c4315746f0dbd70344c19b3c90c4775818e6f10070b26550196d7d318633483e04aaf600030529262ac3db8a4c1684fc07828f6021918492aab8dbd88e9255c62267440bbb0a11c6cab438d81074f21c35798a5b794cfb901821e6396a4320e01e066483c430612d4d1f64c2e781ed9bba8cf5b885762644fd509c018f8ca0b87821a81e93b3204248d6aa24352412e4bd85b4ef2df9763d368c7c21db412cb46feb2c2756a80b07d665cabb2c6c42459adc845117560c3f76efa12ec10f202662ce9531295e43c28721fa0ca701875274d03aa2cfe1ac9110c71daa89f74cb42d2c38396cb28ac521f616e2150ba5c6a4a6938cb086be4dad68e97f710b3d80dbad17f716636680be05ab0b2ac834777ae86a8f95d961611aa27f56467f2026337187384843bd396292c1bfab190627e93762565c63fc7b064861282afc483d9ead97166bc782170ec6674c5943c4b2c5d4f658390ce9926b8f5e48211a2b095a2fd4f8d0a55073031521561409b1db914c8848ef432c27099bd3beb550134c8f50c7c31c068ddd8aae704debc12ac628b6e7cb422b997a28d8b3389eb6f3ec5c4b46d27527cb9112ac8745974cdedb91d60f3f769798727044e5412914dd0c61e771fedc3c3c6521fa0bcfadccd089888f9398ba671eefa440f70fbb312ed2ca9c3055621845730e8e419d0fde8ac10ff3e6f66890408ca38fbde5d087eeb30e8e43aa53d88926b0968b3fe8da8eab762a232d4c5734bdcc02f68e22a7addb61c7c0fe1c7bbb7f14da5aaccb0d4f62299e6184dc0ddde60ab6152d7ea77d16d3d40ea985997a210925c3bfde62b869e9f34e67d8cba95e950b9adb41ee9b68c7e8f2114267b6848868a89e2d5406839c98946b68b198cc18bc05546cc851e9c5d683b5b81eb77c055497c7db89c13186ed1bd58a243fb0a5df067c07548816c87e103118396ebb2443ddf5d0f438a2c6bbfa5847b223b7ad61c0c28b5b21054a7b12f88edf72cc4200c21facc25dd6cd7ba2e06ac8f3e921660d8ea237a712eaf3e0c2108368c5f674bfa2a1c64cb09ab0d96eacb0ec43e6c41499dc9cf326d441581d23aec42d7f35a23990c76c58951c218b8490eb48fd5f465826d86cdd4e81d6f780c67fef81bca342bd1d54d260e2091f49a89dc7f2f360d04db93d5543d7788f79480c2f449ae1aaa5111fb2683c630cf4583462e50ef5711db1187484923088e09f09e9f7605636d8cdbb33adc6ac5f580af7f4ec2809a4c161f359e0f5298e1cb12d9934834014ba6345ae24398e94f12ba9e8a54ca716a84311538861bba0c1c303d533c259adb83f136335c4296cb390770f5ee13cae27631162ee0aaec13e8e410186eacded0311f86ecd8a61f00c7246bd3353f58cf55ceb56aa4f011ac742dc991c21650d4b795ef1c00d5c527862263f85accbf46ac3595261673b6cd3ce2a9acab5d9610fd9bcc6720afb114b4572fe78ef85009bc5f5889ef0d28d6eff6668bad0a8aebb03426f7543f71cd001a37fc8a90837dba2de4b826a544fc34f08751d954bc24912125ca237817b12a228d4fcc1d4f21eeb22cc5dd51c12d5d7c128ab9536f28c0348c744d21eb5528c898c99de1062c09caf0f60a74bdc9e431ae12cedc9955817db2c8a069961fd80df54e7fbf9039d73b0c209dea9459d0a113380d6e6ad43865ed82d09571df809c782680079ac8e501f90e2383c43290bdd39d161956619615c0b5660a86a35ece1418e0fe57a3ee16d44e1583b8dc7bee06683c6215847a65fb3a3ede37e21e2622c4f600ecd77cb0f5e8e390e8477305707b2ce1792fb67b201cf8d93b816314eaf059ee0e4b19e3e3076c3ed29d5eb4ce388fed114ab7b8310c5b761ba3add29b0802545fb84d2e42f42cb4510f42add0e46990daa5a838b1931cd5003e09e54840ba183c561a057a380d18cc15d8c4dcc1164b7c2948193be392d3383e2543ccc8f297921130e72a267687e426236e4c4c238edf4efcf1c6a2b6c58d4b5f69eedac960d0d3309f2d074c638b5678f89695b9f9eb90c3d28e150d217ea7857e256a028024979022d05d4338ac02de06b316c1298d20a7445b1cd1936e08d0ee560501511b83c845c78f86245177666765a06694c587e03ee26443df87c70ed7b717b7dca43b2018a596a8c4c79e729437203641f6c696c4f91fe76d01076e4f6f4b87246174016c9ca58d8e94fb230c47d86c64d616c8d0eed78241422d4b071d10a164a7505fa159cdda5c3c52619806c23fe84378dac85f05961451a8c25c0a6b26bf4516ac43c6fd043e1804a501d9876a8963156433c3c23cd00212e1860f01031341a8fb0d05d4363d2225bd6611423db4291c7d892e943e9fabeca4b2ee2a4469699b577ac9f785370f821180f392e0d7d896f4297076123915001526b5b288489373e017b3c29e3ba93cec7d6d2087b3429523d2435cd1d66695ba9c3c9340762175865c2dcb53c18e9b7bca07b2321d363cf169c120a4704327743e6cf78b8d727dd8363aca36dfb62ce0482c41850c391650b840ad07823e56d22d9d65030a93387c68be91e5a8533b35701c63372b35893e2d7a923301832d941b7b9a8ddfae27a6769d498b763969196503b4024bf47f77decfb7f73e2dff4febf1dbde5fffff9dfbffbe9fff9639cffbf037eaf2d23dd877cf65e7493cf2d024a6d18e4689917abc0fb221f1cce0226d5dbe6b1f928e3507264c537f93c0b8998728feb1c1525a23896cf6384347ffd620401e8b5f4cf3ac64b16ad57a6f10ff085094b3ad68b68fdbcb4d8bd3429fe1807ae6fe7a5b7f370e045eb2afafa24d6981b7c6713f581ad7f76fffa12f7f155eb1f56f89f9d78b3f379e856cf3fffe5a7ef7efae6c23e1e2bf0587038e5358ae64ef5585131fbf53e7cac8a4c1885f35351e7b1104aa57c07c53e49f1b88b9fc2c9804b20491ed5d2b541e81225f8640b1d693490991aea186d97eeb54a9720808c0db500f2d5ee1595a9d6516082e02fca2c07d213a422e7bb52e07a9eac0e9b2be45673e4356c9ce8333e9377e2d731f98c28ae68334434fc76212e50a3975aa87aa803928a9213236a0998da9854ee317b1668fbdaf9198b2796f1681d7d4479b9bda01421668687b6d13d87659fbb87c5fb128d8f13cdee658da3e6864676e4306744ddd60baef079d5021c4d01e521aa7901f522138d30da2e589c04089820df63e5e884e2706522ff62210b5c27ed50472c636caa3be4309f3fca9d907e636310c69d52db9f323eccdc3d27c5cd99c443b766d2dfbe410e52ef24d4d4321e631ef99db306af5616d1d782729385e21094658d0c47388bfd5129e7a4247c04b5ff15cc4b49c7e405afe4658a3fa7157f3ffcb9be1d2229d66ac53fdb1c87114a909571a8eb88b51808e18a7a9e4932d3b9b941916c505b595740f82555fd18b49efd70b3ebfe7693c0efcb77df1c1cb70c58e23dc4c3dd48d6f4d10df937a501f568dadd74b854e390972157454ee5185485c74ad8fdacb55dc9ad9cc156b53e8bf732eea4f6a4037a4d673e22eef6faa4616d3d4643af7b5c7d94f5bc5a0a798181d0ca086d784c6479496c65e2ebf9f53eeafc42c5097bf95eab97319f1d1940587767c8cf8665764ca4e0fbd7fbaf4f6ac478f2a2fe1022ad276e690b0263d9e4c888461989bd5ba91388dbfaf5fe63c8acf582f79f9f7deaf31c6ca389b564b6106f61ee64439076fff67dfff50997c816caf1b3c0aea769dde93f12ba193afc338acd63167d413ae6787dca7072ace2fdca1ac1a5f7dac763a9f3d9e3b1322c59471447b538a06d5027db29c2db36c2bfdaff700a7c770b78f9cb77374097bf7cffddc37ffcc71f83bb6cfa9b153f6ae73102fcd825bab1b411c7157959dc43f51d6ad380aa8abc3e52d92767a12c7259f3dc247f92672c8ba0c115209780654563b234149239cb55e1207cdf91b248bfe1090c86350da2b5b2beabb1f46f10780001cc81e25096ce65b054fa2afd9a3731423b76a5f42e68d7b31218f59f7450e7aebb4c1dfc29a3ccab496eaf5f94c86c2782156abb4d53cda69f9702050b08cd72d27a9a3e8a21a7db53f75bbf7bcc73defee19caf4f44c08d710aa051a033a0a2a6137800b06933ed62efb10b61018b100316f576507692c7123f80f14ba6dd56daa7182820b056dffca3bda6faa7fd65054f861e35048692e604fd0942645c81900ca8d825597252d61b338da12554272ed6652e76ab815e074512282924f236a829495633c8ee58cfd2ef50b53e71bc00f42c66274aab431f6cc04706729ca5150d8797307d161d69e30a0ee09d28abaa04f225ec3bcb9d0f21a8841e4976aa8c0d924a5a0233c70628ea4917bc5b78e2d43e66a7d893fb962ce0919bf2e087bf3e7df9d6d498818221578051e5b6515f50cadec9ec3cef80dd34b4c87df747f15af42a75427f1865dc1938ace39059192f50d037e7392216c05480fe0c8808a965be283d23042880b0390f5d0d25d2b8ce67abc0948e4bda2ad046d78192675455cedcc8d68ddab12145ef94b8c93e8a3c62cadc21f533e1e88b4c67cd050217808b81d2862205bd86dd1156648f9bc7cffd25cfbbde928d51ec684c11e06c34c84dc816bd4703feca60899ebf3d58e2c84783e55b331d63d6bdb8cf47f7796ffab9be3ed9008440ed44934a6a8479910deb469081018013e9288d2622dcae00dec7ae584fd45e50fe2732efad8f2bd1a9ac74e0343061cd715905b8cdb89705d4a73e80d12da0102d7227da120ebd88b43dce266ab5c00a8565ee6a429437dcf433864708297c0f0de830028ca0f018380bd4ddf5258bd98183230b604a6214ae32ef46032db3dc8bd96388ac2b146df179a793b515f238e31a1fdb48e8fb0f47cbcdc1f2f31f540cecbf9d209be5e0ad1f35096063c062a4a0d39785ee3ecb6f501a4e3c11c0c9ed1df82d3d35306fd802d350eb7fe2b793143a6982c99cb0e11d498def3f5fa87147f13e9e4608157e3ed993aeb159cdecc8c0d06b0d6838eb24df57df2025315a1b818164136e43660c22ea038377021065122b62a1fe1e038e483aa17318f15cb3a05005d8023a005c873c1438b889c9469871c0eb80b67bb2507e90f439f70177ee622dd9ccea007ef644601de055010cae3bd13627b0a156725c60a50e08f8c6c773acef00c303c6863480afa35c9a71e81c024e0862a11504f03577a45981a479102b66fb0ee6175d3da93a55b10a34989e679e2fd96b5804983bf826cfc7ecf3ed4420cccc345fe2bcb4cf4b33be7a8cdffee37993e7018668c67f8f5e0f9c95e6f9e5dbd5be3e6b9e679db7787fb8f3eaf9eb8b7d75dabcf10ef557e6f3cfb7ca95f1fdadd9fcfd5ffefac754c1fe0e3561ade4e2c50e61cc09909828e1078417b1af847045049113cd331345d0199ce7aa3bceac0bcf1bea4b0887159bf9fa24c0b51980dd268451748550168fa415382d7d57494075003c0f126e60384c220a1a61876205da201e92512ab4900c8992899e3da6e5c1c453df3093c8125a280adb881283d583fd74dd081917f8ade1ad080a0450960e1de1c4c820da84bc7e317f0757950aec08352a45a8bb4d1d184082f491d0b31bb162e2ab34b6c38da835c43f1c1097c028730a0e6036862dadaf4f8ac454e48756e0bed8060da9444aa99bf882ef05343ccf865a8ce74c1959019111773b4e241c225f52e9079cc6eb13dc1f92da3c80105d3c115d3cede53b2ed7d042be891d216f81dbe330dba4f3950ddf6dddac219dba1117d501063530505a3ff05c728ea5c571d737403990511d1858447eeb27b6c820922d47ecdcb4797943ab35f4f224d18791182446f3eb1318f55b2fcc02ccdbb1cd32dc18e5274ee642ead3e294003a62bc2186c33a61e8e61ef9702da3bff79400dee880f6b00e4006f5fd52036364d1fc6a189cf876b30c6a3434ca75323b09e9c8b4d2894a3790ff2b7b102fba221d30121c15abf881ab3be13ae05221770868e16483d1021c729c8055841c04348612d7a1c30627d2d966fe4016ca09dcc289076cb650e781769bd746e773d0e60272cc3287e30673c3ec40e09f50a2bd9d6fb26a5e67192f7a49a319e2243cc3206094c3d3be3ec10e4ca302485188d8abab8298e400d22a092201d3a36b03e02f444591d0be81ef0166d23bd918475a8de8b2e0a7b40d135369e16e481823a49d9031018cae23efcbd62c8a403bb091d1028b362cf6901bee99237225251c125189519691e99359c408d993ba137d085fe19ad42f94d8aa505ec0ab96280c371228124700778627c0401d4cb604662b310b3835e26d1cc2383b1ab212e20c704b465a0456c4c1932044c1ea1bbf0728b1e03ac0c8e15242b4220a71a52616af4a9c1e3c491dc4e6ee00f2ea4933d700cc39a797816293533161406244c3e8e31049a3be8543c6f9feca19b6f88c181b0eaca6b1692d019a0ffcdfbcb6c18ae943a981d5704031015e3f48350613b0906207a168906e4af8f4157ae1e0dbd6bda6816717f4b96d83217119e8270a664218480087036839e572b21f6477413edd2ee723200fcb37d58f26ae4d94a2189b9a3a7959de563af86900ee06c0f88fa302d0576eea3771e09682f36f0ff8f30fb16ed76f0e0d28716eea2afda5f730108de64363e9776c5e802c7fdd6cb056fcf58bfa4c334c9544eee04533e539be89635ffdcbfbbbac3eff64b3d188a1d203b79b78f13beb31c4a5f46b566631bf40d5feeaae84d48ecd4b1cb98babbcfd84f06ab77fd4de7fc4534382e9d73f9a83b1a5d8dccb9c5ffdd5b4acebdba9773ac064b85e462b1da7a5d8bcccc13f914f30e2cf5f71a37128dc1c3d3c746bfcfcf8ddf7d7efffeb5b4ba9e80ad54c09c1bbcb7620c2218241a70191a6a0d1ccc2b82f784f2c8ccd35c9fb36731b84f95c590cbce1842dab65220c055a98d0033473819ab8b8a49a9bc721e3f7792a298e015519ebdc0034e0d82b1bf4142510542b33ad41782b7291c2b3453c682097e566446593cd434cacbbb400c2ce9435a5e18c34ef34850c5b8b90ec138e7df273c11a9ff03656b2c674a0486a2e5808002768aca0c7c591299d60af3740e601ad1036e94649ce4d095f852819d00863ab4c03cc31fed7492c2dcb785ae39dd33c91572b82fbe0a8800835e856a143a43e09d818f2147892a8c1d9b41a80c717408184793a41ba68d568d4cb632efdc84e9af8aebb99b9d7c9fa6cbe29a4f9c5dba1c7d20f1cabf88e30b36fa740d8b0d4e1fd62b1f978ca71f6dc9c723c7463cafd70fcfcd3ffb8fef46fdf9a47d2d62ad62fd6b5a81dba3622485f17e8a3631673ee222f657d72044d2fa2567c5dcc7b99fd627a51f58be99fa4343f0f625fad17f70b5435bfb8d732074ee6ee83da2a3a2ffba3e2bfb150d46ff1c35164721347e4328be8454beb87ccd2e6455ba978d82e17d7323c7e3dd7c55759fae0c5f5820daf8c84732b6e172f36b8c1914c909eae9739e27fdecc98045c4b5f7ffe62ba4ad38b8650ba8684b14b8cc775a7cb2ea65e467be8a55de21f7e9e5759f102aa77f1c2a1282fbd48f7f8da4ce36cb960f3767ed850aa57e2e57414043690faa308ef1797bf180174fbbc0e4125755c49812bd247bcfd2f4f0f51352ff58a332e38e3821f4647c93f5e7b5e70f13f7f340fce217d6b229cc73e9809cf3ffd41e08bbfd337ff182a4c7fc1f673bd377d7d52680af5b3fbdcdfe39b38f6a5260d4b8abfbaf7593fd77b7cf38b9fe1007fc483bfd6a0d1321f35681cbbd5a0df1c814268012fe66187239ea869022151e2b3de0bacbc41deb295e6ccad8611124b547b91d18ac5ef064991da8c6dbd57af07629da8419b19b844738615f1a2068653106fce496048dcaafbe78fdd8a3fdc820bfdf2c30db0d02f3ffcedb8fef4d7efbe358dc91599361aba84ae4f8e420a879b7ee848e65ec45aea9334e7b2529f476834da81e269bd00d7306450cfd256d1da92a0bed041c400b09eaa0b6430969a97a9baff1091d2a6725dd585ac99dec370d5b27a8701ab6ee7df8f3a57e9e247d3620ad2742fab83bedeba9e7fad587d90fbdf8a98205159669e566a0710b5cf3024c1ed588bcf95c4bd34fb0c5c621d47a829d5c9643e27106a5af7f3af514baffe0caef1f3aff48b63b1b04c1482592fcd679885a385dd3a0d0c0aa323d56f753b3f5a2d62cc5853781c65666e43320ca8a2b6260cc4a1085074e0d8d766ccd2863eb8ac65f06675a4ec0f2b4b3bbaa3eb3cffecb14623f5405b5963c5687760cef14facd315a90a561a0a3c5588d7025c23eb40da6a0bae3a0756401318bb62a07e5986322d81338d4817a3af30d151d3b4261c1813956ad6e10df301cc679ba8041b004c6b55e171ab76fe15fa3b6a177496b11a72600cd0b666d03eebe01f213f5ba99dcc86210ddc4b556291d848b3179b604396aaa46e6ca8e66a967aa9449e186ba29c1c26c3d073bf1793912abc490a3a8fa9a8677307b6c1625fd894b3677495552d772b7deaf9d75a455481ddd6148ebb31d0973838cbf406aaf0de9042330d96a211be4d513722ddd80470585847ade75a28f188f70ae5abf5f4d55bda58f093a1e6f1007d5deba8df327838aaa2de77b69090c55838bedb44dedb44acbfb5c9ded72a6c93aa4ca219eb176d820042dda80c9508fd8d60dfad9d7f752f4d8c04ec6bc2f1efa049f13af3d7e700a8617412204dcca65a61dbd4d57ed134c0dc1a02a752d5be87f139e6dfdfb5faf815390fe17d5bd8e3d04d89fffdcfdf5a0c2924411b97d14b1d0fdeca900bb75461fb60b9aecb81b4ae79015841967501f62a30612e5dcb18d72565cc50d4ef003372b1b1000c879afe4b98430cf8c825168775f1d0acf1d37ff9871b5f2434fb18bb7ea7616aae8bc6a90fa2a1f3735bf743e2067ffee2a396b01870db8b8d51965cb4b5e28dcf9645ed1094fae3692ea81004f50f60f961fb8d0f9be112cd70cda2f322438be8ad87b9e061ee6ccdfdf8ff78b5cbfbd53ef9b462ede2da8b8c8b4f2f3e2e1673dd2ebf789f8f55e6bf7dfff3ed61f8fdcfb7c6e0eb5f7ffce19bf3f2fdbdbb8e9c30cc53b091fece6df7fc776ebb4f716bfeea170ebc3c6bb226651db160333293e1a90071c1acb17ae8bd583fea1bc9fd8203bd66afcf4e12fb842f5e54adacd727d11a46d541e73ddc749b737921058a9030147c4ae8974a7a9d7ffa46e2b80d70408fedf1a904e6c602e579d6ecf39fbede90f22b922c06c4cd0114076e8ca09fbefbe68c8358d2d4a5ccab6da2a61116d235870635adccbbb7335ebfb8d734da6725a1a362699c491ad2137b69773c2186cf42121ea8033599c2586b57ef49d79d35492a23aeb846d2e545ef66721b8f2a06cec296b5d6d2eecec31f76c14fdfddb41a7efaee96d9f0d38fdffffc0701a7fff6096c4d934d7f4406e22797911ca0e56661a1b5ea9892adfa9fc63a0f354474fcb3b8df8729a1f0985b97ab54cf52db8be87cfd326732ebf7a2f32a2c5a8aed9dd79944c169f038bccc639606fe44a64b37e5e7aca770f85a34fce9ab98c011aa2302f80057074fc7ac9fe7c7ce3af4c0cd0e8b03ffd865ffe7c37f3cffe50f5af97f8fd045c0cc8681529508b6215f80f585ac85ca3c839665850a90c3b443c0330e311dea516a2de3f5c93dcb5aa51f5a191275db784cc86ac64fef7585f1ae087d9a4e4c9f8ebd62f762bb64712146e88bc54f304e887a111ada0c2127643b82c77bceb23228bbb46edabc76742f9e7b053c3fa05e25a9ce4d8805c6ac4d6036c8218698dec697e60bc793c72ec13b776e49264d0913dd2b596afcf58b87bc5f56f485b9946d6ed200ee09086104c56bc64c664564c9102f5090c979456e4a6957e2da1d7c96ce646856ac011fb7c58a1537833e8648a0278b0e11063d352f418a7d2b8dbb5607591a998b43bcc73ce23740a27dfda2a07ab2a6cf06b6d74e743dc0d56846e63892d770cd4ea44ea4f2cb067b0553146a474130bf804f16f60c79c84440b487b41403ff562b76807050335312d032c85870f2a231b4aa89843e60b6d3b6092d3b192edbdb0ec9cb40a00fbe9f467a0ecbbcab74a67a58f103449a0064069dd6fba73a890a3318413a13f7dff19300fd9b49b7d45106498afd014cf7fd19961c16e39efa38f716f9bb8ae07f035a15325d3e92305b60dc1031fbc80d19f3fd4f7f4c55cbef29c6935698abfa98572b22774a04186ba3787f59c2ace0d2579cf459e7bdae32f50e00bae9ffe5eedd76e448ae74cd57b107a019ec7cb81412181003666ff52e8017fb2edb553359d3915525a694338aa71facef37cf64a9832c40b509100da9329ce1111eee7658e7f5ff116d12dbc5e60d04851e52f9d84ba8ed4399ddbe161fd7087dbdd49e6c1d17c0374a0b797cacab5f86298230e7c7b4ea25438f629ba1d7c759c3589706a6bfe9a8f1083feff8d04d055c9f268da8b5f7d0d365d2e739e68b4f315d6c798f4ef54a7dc9399a8b52976b3185b91e470ea55eef67dc48cc635c0aa9fe5a7368e3719ac7fd91138f5ca9bd1473acfa07cac2d4803baef72599739f426f979105f89d3ec25f70f123bb565ecc791f5f342a6c41dc5a403ffe72a30de2df7e7afa8fcbb7515065fecbd5cab952fcba0432dd04ef9581854d82451644ec782665915d867b81b788939c21194a33da3ee9f3784ec2a31bee7ce77a6f22aa98086a4724c642f94b9f9f7feaf9d68fa304c67ff9ed5a3ffff1925e7ffcde6675743363ee521bf6eae6121238cbd7647173398f0fa9baf8524a0b75dea5ea2a38bda6697a625fee2bb5949fd318b628c7044350ffb00dd3f20f1453157ee7eda7af4fd1953843ca871f40e84668d95bf2d2373a26d3bd9eed96eafe87fbcda9fd2f52bcfdfc07a7ea0fb93757fb0029433fac7f7d71c9b20a6f2d5a4edc58b6bffce5c7fff3db88bd3f44f55c5d8bf320691d37516398aaf86a2103a2806e6f875f2823c2281ea6fcb374b78a684fccbae215154962f59b8b911e881eea059d99674807755dbb7d87e57f4913d2bbd8433fa81d82641af82adf3e82c101f82e95589b4eb9c15d04a9200e28df33db87ec7bfc50c4a4bb615327e5ed0ba85da8645eccff4966e8a1aba9627335ac4b533357c8471e27355dad4294d3419a617c4c7d04db84858692b6cb925b288fe8ef8c4edef5cbbcb6503e96310f82ebddcb71ee4aea7024ca32afb082af59b55afda2e20f1bdcbb893db6028ca6a307c8177b0ef5758c92788c77f5433a4d8d0f399aef00e8fa865600be41e56af39c022af9c791302c76c1eedad781b1e475d4208f6446fb2e1374fa1d0a159a2982431c7caa2ca365479fa3e451b5ff19c4858891ec33b65e334f78f846250b0cabb0290a4d96a32caa57aabfab4a52a904147da9ad06863e51d80abfc7b07b9bf07b034fe8cc8d6802f27bccf548009050edd29d685cc733e629d66ef535a4838e9d8a35553c85aa2bdb10523a085ea79f558d0e5947d43545788d1dfe0a35a4d31623793a1a29f024362ff5d451eee2ae3b0b8ca927351bb1e988e615307a858aab616155d1eb24b2ce0adba06dd1f60839ede18b7d2b7cbe620b5c79b6130141b1f15ac3ee83919bd010ba25fc727bfd1a05bee4dc2dc1c889db82f17bcb2b162abe6bcbea45530f0025f080a47ec82bb95a00925d74016b99989cf3e60c5099b05b0f986d5b346e53ae7b2175857461b267984790b35076cb74fc50467335da091f20475efa21ca07c711bd0a75e1eee4040519f4c597c3f32d588879b18dcd69b74f77be066c894b2a561c4774a18b9356eec3056ecd05a9b8a08ff027450f6a82775220b8ec66c4843f54501fc6e3308f69090f7c3357a6305ef471f9af9d5627d0ef1d10c8b62c9594a51bae5fa032f553bc99c05ffbcd28af7988a1bd0e07c5ff382ae6f2e8e4e51c917ae8fb09eee5ac22ece4e2e51c133ee0e44925d87cbb8a5edb393492fc105ffbf3dcdb98d6633f3d30c32aa9b6bfd7a70a277e0b137095cd730cc5171e289cc8698a5b5a2159f53ff9a1922e38129b289e85dd9fd4271dd5949055f1ac0add90c314aaa6038d259447d34e881fe209d091db5af3c1e442e066f64a49bb0d9618c3ee8de728f59344b2b8b12bfaa77abf7310f96312f3df6e35808b88b6fc1c4f86fab81b6da2ea0037772dd5d91c34f11608657c6a08d2e63f0d93f2c3b3963cd4473f36e12ef0706f6bcf451a34116e4934b55d47694ab89bf79cedc57e011ab74638e2882c9be6cea27715943fab08bebdd6c29b9a5213457efb948ebadfff54abe87912ac0db295db76ca7ed19e50796d889725a6755ea1033cf512e5e77a179589204615f1965de6fa043f7f0ff9d124fec190750f27fdd40bb1249318ea47d29427fb787e31b510ea0babf351fd59a82b5ad6d4c946c65a41166cb11cd41a68639f105890b0524ab929ec01c71359f0f5c967562e7b80c9cafb75222c7c7e29a13d2670e8595788b4b45fe7f53e15208296b81758031b0d0010518c54a8edccc88385dd9e77a9ff4095931b3d21a80bacbaf44115a435f43bf1652b7e92e6e4c9d34a171beb66f22a483cc04204e1770a49efd02860766635853d4311724f50e1bf7accb9c717331a2af72f6382a0dabe7f702626cf6ff38466d659007619fe4dfcec129f7613e87994066fef9f72f653fa25b77fc9ed5fb2531742935990ff7a847e3e823b1b289896e5c4459f2fe0ca5cefeba0de6884f262bedafe01bf7fc09f3fc054407f7bf87d7f3c6aa2e1a3baf83659fac4a6ecd3be7f1dac11592eb706ebedebfbdb4ebd19b42f9809db90d3733b18acfec28b2d77bf3409d3a94ba4b141b20d0cc82d758f6a7e1dd142e930dbacbb94a734dede4c6fea1792a6900ff6ded6cc85818c76d29d27f90a1a1dd59b2bc55e41ed6845ef5ef4f97484fe5bbbe0a25fb113ff6c17641adc7234c919c6ebd8fcd332fc9856d6b8ded84410a1fc665ef6c87e3e73ff34b77b84cef97fd1c4b9edfefd66edd9f55da9dc1ce8e5e23980683cda048888f1c8a2c3dea00f266feb87d6222931ed648f0c58afffd1516f16371246cabeb97de642e93cb29b152e2ef473d55f04f2becf72d7ebf53fbbaee9281e488d395a33d0fe93bf03a8f57adfda7239adc3146bf1e824ae955f52091de87b1b30a7372f29a91efd08556fd30aeae28736abcba51df46b711109cc17afeb9ca69d46205f4e9c8d69bfbccf48fec40ffb9e4cfe36532515d2eb114f3184e1da36bdfeb977137cccc7f6b2b31733f9dbfc27779e3fe77fed35b6cef93f872b0989c655b7b76dd677696f973a736fdbb6ef5f46fc3811a50fdaa8aba919335be0ac93f2b83ef981136e6ee0c52c195320e942a17ebb3e0dcccb126d886c60c64b5817ecefaff92d5ff05a6ef82cbf7e1b688d3f804b96e77479ce475ff28beff5b1e4975eaf4f794e9ff27c492bbfcf73be94fc3ef5f8e24b7e1f3fa61e1fdbe826da527725bf2ff925e5f9d8eb8b5fdd2ec15f131ad727807fdea7955fec6bf691921f7bd5c99cab8bef4bbbf9fdff7ab12fcdc1afb7502bfeedd71b9015fff63cbf37a7314dcca1b6e0c87e058aa08cd473f8beae0f606f3dd61ad607b0cd31f1d53198e363eb617dc825eb328f6634aceb536d260bc3e96f4e1c79409c7cb58d5a6c27d2d4483349447e99a69966f6b619e60b909690b787c1d6a1764c64a0d5bc103349e97bdfedcc457c828f7e0e93ba4b067a3e7bf377b7b3930c91b0ed5bcfd0139471d52a605c43996e5a3ec1f86997a52ef376a8ed16506d7c92e61339d074b22b24f58037b8cbb0e853e3a79620ad2825a4864f9d430212103cf5862bdc5d2f1d3c9503d7ca51594303fa706adf86650dd38006faa67ed014c48c59d5acfe1a5a7b9f6d8489a80d9bba2391e38d2e551cac0e6a1fa3c5f5410f91f3390174248b19060859b23852146836796c976955226ed885b4dbd4f38aff97221dd97de372242fca6442b559706a43c53e942784f618d29197109adcc0cfcbae03291943bfdeb7124d35f662feb67d262f338dba46757a004aaaadbba2a66440fec86c53de9b7caf7205b36eab36a274aee37413580a6303a044b32344386e17bf3e6513fbb3b04acdbfd76294bbdee474763a6933d62b44a9c05082029084cf5bd54d9d9a62b84091289e0ae69940e992b6e6fa324ae5bf3dcf5b52e879de90427fffdba79f4c007dab1e84f82f4ba3695b3dfd90b3bc6897e3a210dd1c1a736f84b9620ba9f81af1bba2faba47f5f41008dab62a3add5dc741eefb93c46a0917cc2c58bea92b2c49950679aa5f6b5318812b47e07708d862282c9188f757373c853472cb4bcaaea486e1546d11ec26f9e28ba88b8bc93dd0bbed266c5ff8d4a7bdf4acb0406ec2f64b76c2d77907900e7534429c32392cbf270bec9496f64c1d9a19c9f6032c75b78628d1d8d13ae885d23f6ab1864e686fd2fe5f865d64164a2548308deb7dcad1d53c95b0136aa2cf53ff7ff6994c8abde3f6a1d321fff7fb0d9fe7f529fade65e97e17d7b94f2bfff77cb0dceb7fcf072ba5ffb77cb0a74c754f87975d2820439560cba7ee1ba06c0417975fc06365b33a7cc93fd0829ca669952604663f95f122f697dde6fcb7b348069ab3a630462682c10e9e2513489b7584e7172bf33e531db7b4cddbd9ffaa75fec75f7efee53f2f0fcfcf3ffff49f3ffdf0d7bf3f7cfa3609943f90574e13fb770c22a6bfa9faa5f4b8c6e7b2243de9c6990e80ad4c4c58ef50a3ccd1b3ca95b9c0eb99ebbdddde8c2fa565fbe646524417545305efeb3ccc7268ce8436e73ce73ece78449dd96fea3b8f76257dc1d5e9f6c55c9d3462b790d004eac5e92af29b515dea89a3e789ff4cbf1fc056915851c556ea81c6faf4f6e799bf8e42455d8370711a667bae6876583d418286d05b004d060555855e5988a46d11e27ee6c0ef377c9a87be43bd19e65c13265cc2af1ef212d2266657d77a35ed95c6c6e682d545a56d687ebbdc451021f6e7208141faa6090daef90ac0ca105c50dfea113e87262b9cf47fbff0913ac23af635141e1827a69cfe2c775e25bbba93e3f675cf35fc7991e19388180f49109b9f852b407bd8b64855065904cd537c4e9afff2c5228f1b1bedc65ebdf1a9dfd9b3df1ba4b35940c995520f8fd7019652a762b286e217db6b5da035a00275900ceaa11cd9e6881949b832e6e5d5a6e9a62220a99604cf4c059760fff4d03fccea5a247b96a70a479a1f65fb72b44de952821f32dbf1f52aeebc4ab99020b73f07543244b6cc0a64e3ac2810ab256c9abcf19f04c762cf0681d7066804261a4fa5d50d8f16d50509eefda24393a3e7554ffc9fd7a3839fc9ec9a015a91ae43714ba2e6a0296ee90afb18b49374bd2f7183648d3b0edb747327d87a74f19953f6ae0ef87b4400ee3c65ba49204faf67ebb3fee1dbdc07bc7b7dea5d5d73ccacec58738ece3fcfbd08004b27e0e338222161de85338213f599034dbcbeffc58280dfacfcdfdb3e3736cee52ffff3c75ffffe1f979f8eefae285dd494d03a1d83c86c72a9f990a7704ec4efd8a1461b41b09e612c31632ec8f397387e2305541ddae8ec7258d066b5304b58c46c9a280c9188b09c34fb347c4c197ad42678b50c6ce1a028de96f6ca9b4033411e6eeaadefcfb51816b4a219b4c45e68f1454c46384cecee7b188a1c137c98cbf505731c0c51a1c1027f86f945625c5d0e1356774a4ba429ec4cc39eea65539165f166a9f97301b40556e92ca10d7188a610abdb3889767e8801d60605b077ee835c6beb61163743a9f05bf530208a05362cc461c33d609c5b6155cf70d63097d77895e9430392bc7b1b6f786ee118cf61644fe3b748c560374cc3ab7aac29f11c29998485be859a7c3d833c8a7374c85f279587050eda46e52ffd7c05c2fc9eeda21dfa99d942ca0fe098db34ec57d1ccd0c4eeec213b5cc090db6103d72ee6b193c04b8cc2e876d3f451d4abd445d8e096e53b6c86e06614719b77d89562755066431dbcc4083f80d18bd40c51e5d7a0ac83ab0da892a6653caa8740b08b351bfef11c21374cbe8799432cc4189bb7113685dcbcd8d9b24d46f13db4e1f1f867f1e2291f4c8567066cf898005130334d03347f9b8b2238474a7148b5371f68f3ae2492294becf663318ba49f6187cad3b710139ddc26b913bdec75e917044632618987fd2b71e91c84ef0943246de64baccea2a04862796e989eb32b4656125cb410b01688cf32143b3df1d7360d5acdd68e8a2122bf5c4d1b610776285b81dea328029475d37a8d7869cdf6f3c4cefa2e042b0d026cf8ef05b01297a70d6075db0a6608b2b6b969db1ed3db66f3fce20c6bd9eee046173c1ca125bb7f5b55d46bf26f9009a1deeba198dcf12bb46c4f05d37c37e3135ad704057e55cea8eec430f4b164e966364982b5dbb29b761f052e61510f57f11d539e6cc20df6f66642aa8892be2d37e1348627563e4336a1276c9f3a42046a303718763724649f8eca62781d1056748e83fb07d13d28a2e2d42fecf369933ba76de32a6a5820120a88f7653a1b2578fd468800d522fc9b0df46cb66d3384caf03a864d490caf2544e0a1996c4c5081a6286ae8087a79f722a25fc987d29de80a5b7a9aa123496ba250b70818bb169b3eb3aca86fb2a1167d265c96d40f81d3073e2a0d436a38323370224fe186804ba3822a004d8c5d336ebed821a4076cf42c46599b194ab108c2c19ebd6ce7373ddf1a7e49ad25fce72eb77ef92c8a6828cea7186aeda20e0ecd0c9b2fc809d4c2c2d5617281fadc586148b741b273b648b163a3dd52ad9bac052f0b41009ded80133e54f4e234e13e021cb7f6b8706a66915a40a42c7230c47c0d891430bd46f639544cb7798d54f06491ee6b403b181285eb9a7b59372c6f1c04e09b63ee4c4d2a863fd18878296ba2bea1edc853ebcede8914819aa86e36ba65699832cb4724b5b024c2008e99810e8b08734c96d8a1c0150731a8160e2e797b2c60dac650a2bb9a1ed4ae092bd9a334363414b3595d88b091475a954775b88dadfacdfc69e2c74d5b12a6e6938838ed295186da22d964596e9b7f98883264b1ac124e2ec1df9ad88a43ee3ec64383a1272d5bc303d1a70c089c479227368e1dcc5a82372903db40254ff73544cafd869f66bead204f124303ad136d201baa3337faa7ccc71493004bab9a789e9ae845779758585137916732f55037c5b7699121c2ec46083db2d21b8ad2b43819163179839f59294aa0f69bb4d8225e6f66a6a9323362baed13fb30a5e2943f0154114d390cc001975abde14c32656737da7856e44d86dc2e671445d963604f4019e0b42d591a8c9dcdb62f583036a2d16edbb78a98ae66e84cb12265fbf1c11c407bdba4780b00ce9dd63e2ad3928736cb36a2dd5dd243dbef0d1b7e3469857d7ea03773f6a15112b660f8b7bb3f927ad426ce99c936c9f6a26246aa4b217f1f54ba6c8b6f99fc6b3688b6eea174559488edc324147662556673a095c4f90ae76d9259851d8905d5412b632f9bf56ddfa2fc70246fdbb94ada987c9869d3eadac4d3f0526cc34a52c12c9ed869661dc2e84c7230abeb15d49dc21e2daae0ef22daaff66ffb9cc9c0b8788c26c0e16c1fca66b9dbf3d89fec36fdf6c288446051ba484bab6d72dbac402f3b33982450f2a6344fb66b2ac6b5fd1862cfb6a759ed102bdbf9b1f9c04d8115d1a597a92f8e6e3b0369cb9a1f081833e4c53a3bec52491227421b0ff1bc5942fc945d3015fc1f6f6f481fae8411c187cd201bc5b4778af62850274d7bb717ccb0e6bbadccae8ac26473d2500dd8472c7013ce9ea94c4986d8eab27501343293b6994a15acf1d2c25be4cd29965f4db4ce98bd5baf450018b0daa867e99b08dabed2645eb19d671625f1b26589559c968cd9481abc242f03d5cc6fdd1c107854f216a88c59a666829784ff6617ae5df4ebc9147482eb9e347242db932585d191d0b8e46891e8996aa42dd356518752576dd8897280495d61c370ebe3fa048cd990f57f649bb701633565a37b819af3028692c3194c59cce713ae3093e761e1b826dc4994785121346548f620e6d8b1e6cdb36b7cafc2188fef57515f14b593edc7f0e23620b83715966d599757cc72d8955989b9c0e061ae94aba1b13797ade84a3b50aff48a25fc01c47909e00d15fbcd46e91f9a0d787efccd8aa0eb321a58052674709928aad75a9da4b133f49cd88c9599a4c1dc74a39e1b632bc1a33a583f3c58c2b529c4024c06ca56eff6bb716ebb2fc2f70c317398a6de7c313d9ea8e3e8423d85539fc039eb2c8a59df769a7d1836be11b09d4d420cdb21666ad98f9b9fd8ecead04e6be11736a9d7b6a70aa49ac26db637b08e23efe047d2bd9d713a188358cd90b69d27cd865e9c6620da14c6fd68d56e6f6c22d74843cc52f01957082aff32659d6a48695f4c8d5bb64de2f8ecc4baafdb2d9cdb1e43030e15244a92cbd94aae6ddf1e18501b2d5333d13c86899d2dba1f7bcaec4f6b53a8585efe7691333beccac386484d9a69ca4d4b5d7a720e49ab89155b7033f0df286e4430d8d2210532da16158570283970fd34b2675624a4292adae0c6f5c9a748e9c90cb51dc83159b58bf215a88fed9b30d56f16fb6c0f8a1a5b4d410880c14d06611d214c06b2ba882c9f68953d2b7bbe43ecee52243c83f76af3684b225019d286824c4311a3a20e43e8e24854a4ecf2d9c565e65686cbc2be598aa268dc649197134da199a16c6a0781b2ef034b3d9b4e8eb0499898e843df307bc6be8615eb703c4ce30f3839a34bd50c50deca193545a978f35275e6f7b96aeb3711c09a12bcac8b0a6f59a30d55db1173981b4c007c64db9b03cb4f95b4d28bb891c16c3fbb4f68eeed792a7532db8f6f7a389b10143f9b050e4ed3a1a62f4cfd9b92eea851b452f10a8ac4ce3eb4e797c73679c52e63638dd0fb5653599b5934bfb6fcba82215fbed83a2fb626cef4086bbc5d2cfff3c5ecc42ae7e6d1c56ca86e5cac9f1723aec1acd877e656de33c36e1f0084c43f95d7236d468cb6e24095ed1ecdaaa55191fbdd86618a1c23db262f21296298b36d002ca266931a4d489b5ab149680ac92ec56e973cf849374a32d9114518b0c3a9550bc4b44c4f0e2392186b25ea4b8c43515f028e66feb1c84791523321213fae03af916dfd876c12ca94c0348d1aa0ee4f12ea6ad7b2656306ea24aa427e42c42859922e126f325f1df346d16399f1455d1c2529089815ba6e36031d356f328770e3e42c46253d4ef4f462ad60dd7a2cd325658165da4cd4c8ba48446b17bf6c02a084be42c31e7732a2d3de61949a57618b10b2c1b0271c3f4d4e63467749b50553d5b23d90c5439a7788a69a1c9fc49b10614b94e2a65e9431ac544836b9f0d846319d63576d04880dd2f3da151a543b416610601902abd15644dd7eafea2aa7992684eab2ada18a45d871deb14049932ec28083024130ed226e8ce9c8068a43948640608278092178a44a4f268bd965d9ac7ff33f4c59651bbac286c40930cdd095bdc0c934bba0a192e87f146510913dccece5cd29c4f645d94f190a787c15881861219af6497ee99f1292f6c391927ae20ab44abac90690f81ebc657ba0a4d3fd8926b1c98ce400406b5e62e5db438804ac36ce36b05d31ab4a95a8d67fc20d30298f88314b749947d86d4b3785c13125a6a863489457bcc9b9bb39e55212ccea8da807963281f34c6f17d10afbc4b403db99de64db22159188a8afec51e8ea69e838b80bc705dc1bb890084513d31eb0c2b426df01faa5c4bf6d6b7be29f668b117a5383342c9383e0370d1d747bd8326c26405986f1d4c689d80c1357607e5f7405984ee62b127fbcd97181f7a21c8ad86de7329b4bd2cc41904da825600e07e035247f488c74dbf918721508feee51c165073d26f2111a124073141a38731143022655c5ea7734030b2cb3b66532dad54bb6cd681f241c5fa531b0b4a3fde66210cdf4062909a346e98dc288962d24cc276b0a00a81d50b88ce6c3c546e0119b594edbe9e199986373dbc3363330161b9b0625934a6bd91f5a269b2899c8c825f1e89990c3715b5bf22f627395cf9234947c94c366560549b269bf3b88069ac00e5989310280c4b3ec8189272bbcad602639992e8f85198e0a94e2a799a19eed4e52f2b669a58bd525356dfc4d419807ce8dcda20d3cb6c89eca11760889cb7404ebb27e9670003136744187b20b5d04192329a72e4670b290843b142576591e6c4551a336b272a82629c33e7faaa526cb5ca9d4911452c43c2aca6c25bfc3ba95ec1005e76ca0485c97640ecd2eca984134461c3c22f46d6767534fcac28d8cd748957e91520429d334ca920ab68538ccb4b7ed5029a147696b43c1678ec766a64f86bccec497d9d70862732beddfd31462c68dc1f24aa7c745cea7bb680e973dc576b8b2fc2dcf779a34a46deaa4840f300b412db2637adb6f6da3eb37995f1e7f2081b69a6520e0bfb465d78bea24c83819457e651c0a442e2e44b8827ca267f99c991b140c83aba41de683572ad366ae36648b97ef8d93085ddca27c1ea78b7669133c2816056494d7cdea253c3566b1cbcaae2a22becab2a349908fd0b398f9a9dce872f1ae4f653b3ee3909ddf319d480bd8c8a69d1b1f4bba13c87793b32f666796c3cb521855b1abbabc2d50381948e3d8f4d90523ce5ae7c0645b912935cc0c6e4db12201f590d355c2682a59c89d304c5877ac9b5abc9409c509c4b4591e09b01dca2ed3f25bb9eb54318112d7565bacab421ad6069a405b3fbdc46cb65adba97200e9e39b6342a73106343185beb3e54556a35d0f976b796d18aedacc6bf226b92221b2b247848467b6676d5261b6778abc50b6b12955bbcfcef23529bff6eaa169cc564e567c8d2e91b4dfe4c9cc471fac761c10798cd166882c57466ed2d99188959ad8646911d9346d62571abb7080511a039b8aa7b6855da9b708850d52945f20027c7d6aaa4f3842314b8d788c522a81ac50d1ca1e104576d94d2999d7526890558253363cd150452b70267794c5ace26ebacac456e7f23198918157514df952fec00a6d592251e174f361599e83294e3b90644ed52420c42a20c14b546011247249f946e6577b2c67724ef81ccae193b04ea113c3328fd8cc742578f3de58dd3c2abb8a7e50bacd2539e83c71cb8e9a1ad58c54050c3abe9ddd9cb6ac79be2b547c22b389e44e9b5383438bd99314a55aa46c5b48636f9222b16ab7b7374992f0b28d4b8671a200c81dd8f2dad2242bcadfa41aab1e9efb1d32999a2a82a667de11c05aabb1b34759c62c491302757260f2e2c54ba2ec956d7344b00f2d6c12e77adfc912a63e43817435fbad0e598955067f5759cb24e202212091d03c70c99d6d36334270109b168a27f945d084e544acc911f429ac6b40a55d237c965f53099d2068e203d48d0c85755306319f0cf07648887412c5d51c0312b5ec2283b5d6f6b891c1a3640ac8457c9845858f23a9dc54f612f9c5ede6f30ce43bebae24eafbaa84a6991cb6179a4406955d2dc93896f14676b6d9532acfa2a47054196b1fdba14015d9c363ebc0086b3310061957369902344b3095a76161de50a4a491d874226cc9249ba383518f4d74867373633129506c7bb850bed414b41b84a74d73545c4c74b882b10ad1ec90a09967b07c66293c22aa24f2cd7632138076702056e4e02d19ed73339d664a583222b5604e6625501be544698735f17ecd0bdf2527287b5ca5b11369304fae44690aa63b95344a599ac4572a99bb332ba62f59f95bf2db26996d3b4e38df5111cbc27d9adf66de6752c950de115b78109adaffbaed60b974b6dd66e8a6039b58b1ebae0029d84a783452bbac4293535e21a15d6a64837b7d2add2422c9c743c81604fd28b6403e0e5bad4ad1e1aa9a0817016dc79835e1e5e4f54c76087d461303a55007b0b0ed0908753952b6be12194e90f8247b32e5b4b86549e5d8cd4b766231106c4af4cfabf0c40637225587d98d40a74c5222e78a242faff454a48ebc350fbb882bac88f676795b1b4a7924e233662ed9f9496a92f3f6f871138e374d157580ccd54adb155c022ac298b6b580a137ccc230bbb0982cded9569533152da36ab628b12893e864405adae19a650645d5bec2661d448b71170b294aa23e28330c2c82ffdb53586c19206f081348cd627b512791764c49a559b47cb25917e11854c12c841f099610fa636b0064939a57d08f8d84c41d6ca742c54527decf8d33873d11d2f63b943ca8a61992f7c453b05a87a49be401d54695bd1211c51357b811f718a29245d34eaf56cbbcf9922b47d82c641326bba96a52d31e9fa9f4455cfb0eb3e49f5233a6c7703f487e26b33b3d8ef6aed494c3a49d9f9a890db69ee9f02ff6d67c56337cabe0f8edec8d72e35f7ffcf978f846dca27f88e98876c21aa9fdce4da50dc511d5b23f1c3ddb21301a45479c119570534f2eefcd233701fcecf3cd9dd798e04594b0f439eae44446f476217df0f9f5067efb67bede997e9fa0d5ebede8cff5292f82cc23dea526a2edaa5e1ab5a98a53218c03cef396c2700d181460efca007fa8563ab34a28beb954a29b84bee1a59c5c74824bd801b9113372296a2ac93afce212daebe0d6fad9a76e2f9e9fbe0d49d61fc1f81c7432957cf17dba92ef4005a84dddaf65653a9e8a69c4237a3e3cc1602942f51db4e697975a0e9da51d2fe5ea888755d8adc1ac025ab5b9c544d1c7936279f1a5c64b07892dbf9459d5b99557ba80cb5a7c9e024d67e18cc39f5d77cd576a11a31f11c4eb175fcb513bb08d6011a1ccec8628b45ea15c0ac2707ed83ff1b5e9fde916238e4edc9cda4f0fdf5b03420117be64066d44415cc1629a33d18f3a68cb6a6a3363935735970c2a0a38cf214d2e51c000747e2d404363a8828d2880e8802cd1cd9022ae22f897e8a78038970fe58e4a4c57e7a283a5d0d81661328850a3d87ffbdf8f611ebd04f0d9329d5d54ce77dbf11d0498a5e621fec1bdac252cff7a7db29bb1fb02f6b546f5fb0fbfa24835ba4fc5acc6a90630649c7dd6af14ba8ed2e8225bb5ef554a67a88e5b74048dcda63dc50cb092fac10b0de8cb044e6cbb0994c30619e25054f42bed30b6906e2fbc4f0fb7d6dddf7efaf9fe979fbf1929c31f809c6903b65e33fc8f46a722f544c26d6ca21ce81e8fda0fbf37f5a69c5183d6f0eaa0252439011886ad5f6fd00d80d2b7333b4ea58beacf509716d928628520608422d8db168498dfa86c76019b62a81e0e3cd6ec13c4ec6b978c82ed388134010d514ecdf265e32257bd41e1234982e1554b093e2da745b9dcc27ac64913abfe09797178500845b69b15234d404ada60bd0e8ff8f105c29677c718c405c0bed50d5b5619134194a4d7e6b214fac7dcfa810845eaab07b2084e035b5df9157d55c07a59c0b24938940378c261e7ba5aeaeaa49fadf2acd9c647fdd56640d26c21f20b567ef430df33448293b4dfd665aae89c87eff1ae980f010b0104cfe0da9aa2ae6ea4300ea6aa6a07da1875b8c0a99f063a53e8b5f4bf2675026682121eb09734bc1229cb37d3fd95deab2a0c383af88094ab422e9b5ea891b8254ad9eff660da04ecd33c44d3caca200c0b49319eeb22e13cdab32df5d04177b744993e9620b1b3e9c3a02a673167d38a47bbad085d06cb4e507cc549a40a4c2d025d8cbacb1295a45aba13cb84dcd361be8653f362dd0bcaed057502a2d99660819b278dc34ec7cb46031bda73360434acec6d3805c6a895cc2a076685541b8ba0c05b820e6fea80ecc2e1ac40a4d2e5cc5ee3e8c5a6f7e046f6f80dcd2b7e366dcaf4f18aeb7b37403b9dda9b420862da6c4e455044583784913e929c448ada1b54c7d0f7a86cbc5362249e5ad32ce8a0b4d180caee24d60e4440993605070740944ac1b9ebe71cda591b7b5b44758316c1012a341a009d69be86642b3257afbc24b4dada42457b51de4ff8d08173a665647764bfb66f5aed117e37e18089c65e6b04193626390dd767876bf4a2ac9927a26cf29f6195d2e501f525158e66702a29b6c7b4984226ed6cb61db8a33893481b6073e91d3597d4d18c5ae746f2b41913347a85c846cdb57bfacc80d49e664b9c52d65c98210efce109e90a7c58a04aaab1f6ba0fec861ee621c126e8594c16e10df5a27e1e21e96ed66849584978b87aaa5662a7bbdf74874d901ae16728d77b8ca51c0192d7d66760cbdac3e51bd3a5161bdd9cc618689cad6134cefbfebbd675df70c0020dc7c6d000db18e621d0434497d7832ca9d40d8e2980db28509cc1c80b1cbca8ecc4f68072c85582c2c3b0800164e2b50badbf1729e1bcad25df3746315cb3eac5af02d7486634891f86d961e79124ebc2639c5b65b5f212ca25696ba5a30aafd1ad0d4a99ce47a1af3f2d810654bb2994f564e6ae4f09c6553373abb08f11f7a5ea7533df08b0a7aa313d4b23d89fe70d8455fdebfb4734736f521c2ce21c9d6a70e6a9d8168e662f60a0e9f75a26ae4d9096a20935a1d06b067f9250ce84add6e5919064b83ef966064a3f08662f30452ba6b6349ce287489c2ab0e9964e9a03dbc9b28a1aa355ecded34b28479a1bdb5473e1da70f17a9f075459711d9e2c63b3cf778af5db0634e3c6f3c65cad4807d3884945c6b0351450df1b617c1f263f8722266f6592210b7bb50415903204c06802be4be784e0618bb65ad7aec592a1a31859d0f216736cc1bd19a4fbb7f5453279e8f9d50262cfb1ae4faa73360ff200f64ed254d23a173d2140d87da3b92218c60949e16cf5d70d37615b75b80d9d8608dc0a5a6a997feadae43ea60e78b0ba2d2820d24bdce90abbb24c13014fa03bb2b4c3da1a3b096854b323700dfd94c0abc76e7caee07e0846bebf224e056a073106bcb063bd90e904a88a16abc2c4f3cb9e7132481df8e2383689424418665b1bd8e70d996c93b999a2541207188eb0764cdcb250460eedd0361eb26597640f787ed8585a4c13d2529f86fd060c057bf1a5d3040357b677cdeca98502cccc53438afe6bd53c4abf2d0131725d9f485af40eea3d763aed8b7057c5d01e8164a6ec986f698ce8a8008a9c47d910c50d046eb2bb7ec03a363044aa6c795d4612d49606e8f25b53eb4fc34eedf2348b1ba0f1cd6da17209317c88aa42cd1a132496a1dd9dba9938c95677291073217153d446ce112b0a677811bf8b0eb71db0e1505e7c28f6c00002324b03a128885b2ce6a8fbe92c3fea9e315a3697600e402506318615e1bf15247e9edbe540cea2b62bc1a014861bb63e0acdf048cf56cc3f9721598ffd6c0b788ffd0fc205ac4fa45706cf82778a8c6413d4c2e44f27883c6892eabb8c2e4c19c85b0beb0334ce381692b62d496c27dc4bca3a64704d45eab198dbde8b5342c86d56132d3ff37450471786583898691b2ecd2995d5884fda13cbbacac7e6bf5992e705c39595c5925b4037d77852c17154861656511671f9bac458d27cabf4637a3014971c9dca7e31f1d4aef7853ecc01302f8c2ca0f746dbdc43f01f7d436856b974c5ad28a7c5fce18eb8bcde0f72ad7184b419a990214b6476554755a32f6bb19d01b8924fc99964a564f8440401c484670c9d1d1108eae9d6e2b7fd7d7dca1a54b47316fa49dbe659d7510598dd7654d28899c285cb5f9cf1dc871a6c75771be0c92e958b6ce8e24a461aed3da9669d2460c26606470381057ca93e5d1d35a46333fac981cbc249a24c4d969b502d4f38848dd4945d8123c996362e6152de147c6f9fb72f3b145b3297e9fa548b2d863e8e1d45b0a7afa74a8653616b170c2805cbf8836fc500abbd5890a77b1ab627b784ee481416da72cdacb7f934d3d63670adeb1041856c4295eb11d649db8d10988da260fb69694d766bdb9a797b1efb8b1050d64d2981085b0a9d7c2532fb16f0ba19267b3b7d235af6e9f846f1f73f402d9857a5e8906684473a68f3c752f3631da18ea3d35c0e5e64ca1e68857d3c68cec456ed5039356cd8e527ad7c7678bdcfad4347bddc74d3e935b7fefc4f34d4ee9f68a87f28abe8939b7c9a02cb1ec3e88f3649b3bef81c47688ffcc34c3cca95b3edebfa60bb5e7b9f4e189774ec5fdfef75ff1570c9679fbfde97185de9ebd1cff431f514727f9c31f4c324be80352305a32ac3d73f4c27cc7657933215c56e7682b3d06d5f70c12f2e295b15b7d692bd7f63113d7f1b80ae3fb084a6cbbd875aeff6d653bd68c4fead741fd1a956ea910471a8105c53a07fba3ccc08c51397473b71785d2ed127ecfe3ca85957d124b5f4c82c334dfeea61f7ea2bd4e61b80c2651db0871337923fb4c188735558b580b0066617e9b916e6c3a0f1497fc554daabb9e4302314d1750c7b946c1a620c21640de862ca06a4036c0a2f708c4d635a25a8da56f18c44e5a667337db93ca92ef0990f2825d843a25a911ec779c94a5516d21cd5777b30d9c708623432b1bfece7460a9b8269b93e099438ac4394ab3262c5ce01f8217869e9952ab8223c4b7269aa6d8e7a207b12e2d6e62a95bf66a05b9a4a919b4f266c0fd9f982c5176f509729dd856b49c804cc5c52afb3bb6d09ae6d10cb7d69b8a711358c9d0a1863da41b7feb04ce438fd650703e76c5603a4b41d6a1d2c1977e68a878df53c9d2e59c627feb53d0bfd858285063a771caa1f4f4e7c323c383c79e0084279d69bcca3e2a6943dd847f67cd9411da78c5405929c092396874fae742fac49b613ccee9ab836e6a5fbb400fd8da432d780b1ad7d19adf37f3cdf842e7bbe0158f6e787fffbc7fabd650a37a3f99d698016f1a35611a7f80ff6dee61a3f80f88b58bcf0c798427023b40f958959f97daef325a57c7d8ade9671ff98cc3ffdb0005aef3154fbc4f5697522a52f8ba8cdc602cc6e568509cc51b04d66a7df975aaf4f4de0ea33e40b55f00e8b4307e505cf08de6c85cadbc958490fa77828d7cb08e3d1ac91179fc4b7b4c1ea236e3739a57ebdb7611497bab9d876c2dc2433bd8191a9763f1fcd9cbaab988ce09a43ccde6000d1d7aff73c2d7bb93f7698aefb23c5eb2f25877df871adfd5e5ebc97c378fb9cf93fd7a74ee068b650ded768f79e84845b3d92a0c94f5f3ac2f18a24caa9cfd2516ef60b2d146ee4c5a7c6fcc472f170f899bdf931f77939ffd518d17e41d6fb16c60bf6c565ff73717a11e29d7689f608fec7c734ebbec91cf26312371c44719b1aa648f770447220fa3c953293acf5658471d9093c501bb11fb567a1602be69c0dc9fa65fa0dc45579c842eeec2d942fed54b6df8dbdcafbb777ebe5a79f7ffc36ccac7f8050b85040476a9ffc7d826d461c13adbe1d20d32741ed484b6401f57ee23994aab235b3226175c855cb87147b853286dc7b53ec3835120aa45cea0ea899b3bec3facb84aced25a5b216f4145055903fc8b00253f9d36067e067120c030ba709775438f18a1229ab648ec812b5dd12c0a75d350b6874fce650f41454b3a1b17550140c41bc173f7030b14dc4a9891b55a18aaf2e75d3376f878468fb568c3667fb622230988b91afc04c7910314af5a92a25d4c36f8fab623c5598d1d84a39ba21ac7b33f1fdc2541bb6a5bfb68259925f58c59cbbb5922fffd78fdfc8f9f9d76b04ca6489ac2228e4a14c332e7bf68ba4e9da649905856dab19503116c3240634a58b04472282c6a250cdb421aef689690b6175228269d9ac0eb32b8956f433189c4c964273a1b04014ab6f92c9cb11b0cfd1a414006a4947951a38825fcb6ebbbb14a3222bb67ee42d43a941d80b3c5b7e8d286d3fe384e21754542eb3890a0b74bf0ebbd961fb6c28ce044b53850ec534a30f18d6e4d0ea0e5fa5185ff49c25b0e785525144f1b084be4c33237936d67216697382930ef5d2779e384338cc18246ccf46444447a305552e10fc730a5b5fefcde006cedaeece445099c04887fa58e22513674b23e467e478419873f498e70ceb19e1aee1875ab7f01dcf771e4b7ce672d88a3354b0b3a0b0d0d454fffaee2349e8c30fa91b224b79d344610cdae1a3cff3a33dd2b3cf67548698851d3dfad9c27c565d46d48bbdff6263f94856ff597c13e4c54cf2ee6bae1fa64b95c5abd1f8f2e6b65d7a7367db895bdbfa6f9f7efce5e7efcd2315a57b85ec8dfa3f530a157fc6dc4fd2023a8e49f43ed3d4cdcc5b39d5fda1c807ba9b9a0d9ca6796ab07257f35ec18d9b5de629bdfef4f53eba1653688f2bbef8bad2fbf852bf5cf3b747f2e6d873e6d6e0ffe3d787cbf7661a2415fcac069bb3aa423699aa5043b57f8bb43b7c6ab6ab0193789f722807b963a87693aa41b292fceb837c3431b0b7537ca8d3c1e5a8d7042b5174a65dc5fc98232e7875503751aadc093e10323623392a9dd75c3799262e493107d9378846571360c4199a1f7eecea917cbd2f4dc45af9d89ca1c5e7cd53bfe9a1f87192385924bb648c3a2c3594604c9f1ae1d9087356acafc7db38824f48be0250c4bb5fb4c67002ef750a7bde0e018b74a2ef52b201e1bb1e7b09edd800de2aa82942544f35289c5177c693f2806a3681a8a27356be85e2272c5d8e46826cb70b865b826691b62ba8b6a21ea9ee8104c7bf5ff9cbfc465ad437b7819db8b10b7efcf9e77ffce9d3f1f0fd1175d72c64c85e43862fa18ab05e0c9234d1c9646821af8bd99c7207d3b14178eba23569807301146f06fea2d5d029858f342eb414927d873eb25dda58921a44cadaa0146d5e6820a93da47564e04d0718d951e86e6d10bfc88255266a01fe77a12fabf55009f9989554ae4f250bd9d7ae76010e7ff8b5423efc092e59c4b94fe5c5ac40dc8b4bb9f81169f5116831dde860d77833349a8ab0ca431ea127f590a4b94372091c455bafe98e02fbae1a26e2bcad84018fb21935e388cacb9608ac090d7d3062ac16cab808af618439ed87e64a6ebfc457ae2921c88fcb360bea3c12e01375837dd462ae6dd63739742da4b93b94d54c6dbe3fddc025edcea8367c01fb43280db44599b206c7cb8e139dfcb829350273d5e8b25d2b4ca2ebb3d0463f8119a637a9f7d0ba5fea458935d471bdcf0d88b9bc6628042d5672b4ca0b9e560d4bb4ead115b5f1f18027a17fa8026d96009ab141040d0322bfc60d037f5154c5679fab1ba1dbb47628d482343e7d98df955838a0de8279596d39d10191c979f5068707b56d04355273833ead2a74047baaf230cdbbe2cf861c8f36e5a58491af4f692dba737be8f922f051b347d746cc0c6b0a4800505f7399049659558397747b4bd540e03e346a642ac26c3681e2d28585690a0a3db3634bb6d0ef6862903221a01f1a901f5e6b67d1962d34f9ae4e5dd0fbb4e629f2ad97dee952663b39217b836af4ba0409e9da6ccdb0be2c43df44e22d41fa76f69634fdf4d3f3f1cbafdf1d674f19d1f512fa5d29d817f411cc185e37bc2af8374db6b9f8e2f027cd2aca69784460c54f6453a7d2e0398cbb5406d15fea7c4d3d61c7e9ba2de5a36eee6f2826a1a54cf9a477a36ea694901c10b133140eb84a34b9d9b60d8fadb22b59a21988ba7ec5fdf435eff26bb363c8d3aee8f3a09262474f26344f0b956d1fd311e87811c37438938e1c7092a005d613b4245ccdeb3cc7d7fb52a6332d629672839406b7226243a8b248c731ca286b3896d1fcbd25becf14e68b6875ab58aa911d784c5347b9b261a11a4a66f4705415ed01d986da7292bff0945402bb5d417c333b94b2e18052912faffcbd7c6faefb7deec6aa7f7cf88f4f3f1d0f7ffbe5dbb431fc912e9a5c5cee19f660b3829f7352b87a2a9b9d215aa6d23d42ef9d14b550a5915e2f27a1ffb3b9d3703f8873295d90d81ebd0d15e319b24de7eb457678c8cfaabbccbba8136c9969df771366fb5043dbe5ebfbc57e16ccea670a09bc7d678511eac5ef0af479f84d030f7899fe7f5123c0c2d3252dbb7b1178540a3ee2717e6d85b68317d0b656674fe955e121e6ff9245c34379e0910843d8b3a9e6e4f5e8628f19f2733eb3502eef649f7ddb2ca5630f90caf8d3f97a5124233ddb339e5566a15da6c885e611ce4a0b8dd9783bba3e11a3f4338c2350fa47ac86622535ca03e04f1daeb91359e71b6d04a0627b15a53260bb0ccfbe661f28aaf6089000a80d7a73cdaed0ae4f3952a83d98a6e141fd223e615e1344498900d8e0a7fadaad27044b5bf2327986e24d9bfe127a49a2371cb5c9ae9f8934a7fda15ad0feb865e2688d8b0d633a10cc83be3cfb4d47c110bfa9cab8b463b443a53a32e13c39b2b79fe348bfe967badee31db9d28badb206b72c2463c248ef44509a92b87ad7a5a6cfb84c995814abedf987f3a66ceca4beb0653907d5ebc457822b6f42e696747a3b7b4b3efdf2e3cf3ffd7fffc7a787a71fffdf5f3efde7f7e6e8649ccc526b2807e569b8babb0e5519e34c3ad8dceb4ab9beef13f706a3526586caeefa2ea7b62b41dbb46c972fd1352a8d9a2b5d454edd96cc52cd8039fa8b86c26196979b2a60775255d07505e1074f40a638548bc1a66edf3558e8cba59aade1779202923c3a8eecb19a49445b6aa62da71f443625a558874b85726761a1f8295cd9a4bf2a91a50a5d7c660ad8da273661c1308faeec4a26f505e19b55714eab4e8f0e1af60fb106faa39ac0b2b2df2552fee4294e61dc99c69f4ed167348aab4ac930a4436c61e4b0b17b93edd3acf4e33a6c98403f728a52c3356102d3062ee4d0648330c4943c52845ebc048f57ddc3b0e129bb7a1312bd6c264adb35ee205daaecdd86c08c8fa9a6e944414572e64c47ea2433edb5b19b0d4330a657ee72d9cc2ebf0bc07dd674622cd6dd6c53faae4f480a710c05bb290a2b42e49ae64c745bd22d867628864fc03cabdc24512ed6936a3b7d534f1c8564940de6122a8cfef5e82a6fa7050e04164a875ca6462e3b6af75f4b30ba2f5a42837a979ad426c798aebdf8f5439b0f1cf855b58bed3a5395bc8a94f0ec5ba94ef807b643f26ee8b1ff282b1d2aec4ea24ba17f87fe167ab4344e3c5f658bd29948f90c2367be1b4c5aaa8821c39186ca1af2c1b7cc2a50cfc42e0c6d3c24893f325bdb501f5254451d2ec056a80c7ded3ad84cff6476d16338862e25cc30dba4b3ce8b37a7d8d35da7f2eda192c6654a44183894ce54ed6f4ad6ea3445aad61dbf7163bd2deb242ce3b3934de0b8f8feb681a9245cae4735556451a377529f925f6aae6b8c4a54926750989e496d94a2a2cee4532c2aa8ae62addc4942ba0c95c8ac21bfd87a925c6d7be5ee662615a4909b5109705164097195112b32113517550cd5937698a55d98641a143795c05237269bdb2cbbc100dbb0c3fcb35cf443498aaaa21f30f5ece0fa8498a2efe9d8eb09d3298b19135a001b72bb64a7dbdf0435fd88280cda7bb208d2b3c298702d4ab0c0f44dfbabe49c8d98c737d17c61ade295a993052ad426310352902c053456b5a1c7091bcc7872592a2949029bcd34a29848d7f53ef7a9eeec82a5ad4e3cd9d20819f0c0cd4458bbd39ad4ef3ca9dfa72a917372ac44497b326e928b18af9bba7537057288b92e0b2f99f9ecc3767383b8fc59b3c8872da5f8b632d17da79be06bca02fdc48a031acd0cbdaa6a8eb488f7add71c1c2d3724b0faf5de6c83525a180ae9d3febe73966a9a450430ede5aca657d42529af6f2b9c46648cdf21564ada76a96297c87612db749f4d353bc4b3f0a2ee766919b2555dbd5985beec66a4e9f658e550ac702eed18a0da4baacdafa1d227025c7f1987b419a02f4e1aaeb97ceacdea215786f3b36b3309885502b00a274415e02a9d460b9b46aeea9485f820a901d5647351f7db0227c5d96c17d5b0d3ee46718a535ba61a6644a2b9396fbf6c5cfed642bc6961fef6235f34337ff8ebdf1ffef2e9fbcbea2d597cf32ed50ca7c5009c3a2621afdaeeed313448b4d2616e8e8989495c434897664d0843ae483ed1bb563c243aa5e2f750b7d8ee28251e0e44aa04bba42a323251e4398e0652e346c803741f60a6d9d111a62ce720cfbc4edc342128a96e7809b6385158d0c546d59668bd1635f180750f5c66a2916df84a1fc1f285e823f0c6be432e5080329da68b3b1c32ea355d1b8ca8d3bb3bd530af6078f140de751b4820df0ac4250990bc5a1f9a4064776c9d9ce008cd8cba510f9318cd133c5650148e3019f63da81ab6414147db68474b3433e4ed0ec0a115ad22f97a50db36eb5cd2330ba8d20c1a204441da2aa13c64b83f4fc249b1acd86c8ec3e728a2ac0a70dd84ebcf343721f84d00899a8e30aa9421dec28ac2c9e43a54b8410700cd2b15f137c643cb40aaef17959c4efaf45b28e9c8a23fccae810897414c9bc9a62cd71de5ef34250cc50c307a1ac6d350078f28efcc1e85dd0ead8eb125100818595a76bb45cf8c8c051e9580d0527f2030e7f457290cf34d304ee0dc2b2cbaaedf01394478b990eb427db810547d39d86df2991b5a74602924e330116273134eb922006ea21413ce152a97c0cc99cbcd446535035c79ae26899e6d66b2a0a4fd8250d2dec403a44ebf09ea35b3cd59c7957edc996dbb8c448cbfd9b3cde2b2f8f0009d9f61d043ba6b61947e4bc2fecc29b404eb175195f290ecb17b3b97f7b20537c10c4fb350c3ae979d11129a58aca1d723475d86e85275c2fc37fd2807a54ed20e703c55047d4b64d5432e7fca5564b77ad9f5cbf66466835458e193f45df57dbab9b1cc87b05ea71f20ca9323f3666a77e2456cada9dcc69f729da2aee5453f61daa6bbd2bbcb4567cb6767a3cb60c5be98c62ef50e74b73432cda6829099d99d12f829e76c62b09487017e9ffe6a208193abf3c0eb04159ca2cd7ae6f8004c9c616daac634c29aa6ab71ad8ac8f17e47cd9d1aeacb5aeefcc42d25f7ebf7163e293992e06a471a89fabe128b3cefbc0f534ba1fd50958c8fc43972d4d1e1f7b73c1f55d3990ef5ad54850254f7b7387aa25cc274a93963a055d9d4edb2eb67bd0d3eabbe63473f6006d6c5b3e6d65d5d5dbdbb830fd9c1f53ee3c050ab750062ad0ec2265b9ce42f4e78b950103f62e847018480e62fb3bd318a6a28d77b0285e68597c7d2c3b84c5561cda30abaa9775cb385e7bdb691656e313123a0d57050a8d05752436d1245edac6afeed613cda8d8c0f6fbf777d4a939e47138af6e3ede2a76ac3e651a8c3a3005d767f95ddc9af41970570ab2b89568e6416e0a32f03cde949eaa469b7d58579b304490423e9b0db527f341efd85acb75b3df447fa932f6a4fec58e68d0c14638d2649f691f1b59156d1e18db12e93f88f3dfcfb9ad36763adb6ca4e238279e67f78b4dfd7342e1b0da7cfafedf75f6feef15f6feceb9f7efccb9f7ffaf5c74f7fba7c1b7cc43f50679acdcaa8fd003bcaec22b8ad041ec3c829b7a68ae1acce9512285270a00924cacbd31a611d3e2d352725b06dc692773f2f3d5036900e500336d8a079cfdd25d824a6c23951cd8e602a15ba9fd2f5be0855600c0256598dd88dce493c3d1a85e49da9ef1c50664f25915032a87e2aa2f8cbf42b2472e9340064df1d0154506355fd4c675457a9f472746a787b63dcb54a7085069e56152a6a8aa95c3ce452078ccfae455f8a032d602a641aa12650f08076644169c5aec05bbf30faa1bce0c41d3b3eab4ca3f87eb7cf4aafc010aaa4607562981e3448c15f88de6bee2b00c6b494342a55ddf255b86cf8a88bceb778bd6f2499e345992f02162472faf569b761cf6c261b6e67ebe67bb27f28064d2d5292d12ededce10df652ced4ce8e3a275f929a27dc20b3b7046c899dee5b559342d35122394b5893b6bafad6d1be14afcc0a080d959f9978b8d057ddd03d94bb4363e2f6ba768b60704e381d5c8783529444a724b687896d0a5c868ea619ad26a85a54279fbd7ba118b89b690df65f3b5221ec9576e607aa051d801909f98d9095960022bab765b8edcb0d183437e339e1c42e8f5b10715e55c49d68907abc95d5fe90d4e231edb19bb053b49cc9600869dbc424f88f8c155b882375ee6f3cc90ab6212551fcd476f7bba2c01b0e80182f73a862851d24af3aa2b53aba4640a22a7c55c5869a3752c9f243e112c81a69b878cd112af86816bc5043809a82b6d2fc2ec19ab122e088809640a5df59e0173e8b3855bf69cbab97bd28975605047f343551baa63a40fa05fd091e433c7077dc5797cfd88f9d758267190e34d0e8e808c41ca7c8a3b99c4dec1588c429a66fca0c0a9da182a0ba54684d9d3aab9f462a939754e18356d1437ac923e44b52f4b2fa9dbe99d7276f9a898a877a118853227ce7cf812ce425af4f93ac8e2de48bc2ed0768d5501622db39488226da59e4a284388595740bd8962062a91c64ff4a13d1679aee9676fcecf457d4e4fb87ef0e4618b3923cce84f1b198be20a96ff3bb5018b1aaab54580e243bfa06f22b6e1601a86d8ccd564f44908e06893a37c41abda18958c15d6b957f0348b73b05a6cfc8e4551468af42ff29dba0f9ec68b1a53a8dbcc56337e7094412614a766b621be6400530201fd4ca394d3c3b6a5e4cf491e19e87cf1bb372100a449350994ba1d9dce085b90b9baff892e696d977acd73a279d4265a3299bc28be43ab5b994e950bc80744664ffc02551eed2a0c951f9420c18211a090eaeed4687a10bac68e20bcd4b25c246d9297afcb72312f798d87e8c90dd3c9b94c495ee7ba58d775b350a4aa72f77be7ebe9abfb615de3f7c6d2bfcf9db78847f041539d22463defd1155e803e1312bb6ec2872f243124599018aecc1de7bf17d1e644fd48799d41a36500dea66045359301f4b476598cca36bad8fe3b34b43e9493ab186fca22be306ecb2f49d6bdc07755fd9bf5ed9535b17fdf9146269f63a35cdf6b4819af1a5b46c0fdbcf1e9f3a7d9daecef7751e82bc8cbe8a05dd73eee38c47dc60987a53df79b42be90bae52c8631773755eefd36c400fa4a3da8e1cec5af223763496cc5982fefaa77f3de1535673222df1f0d7ba19269819e36349e9d2d4e818d28b29864e997d51970ee4e50e2ce94a7ab94dd54694e39f7fafa8c3aabf1a2734a385be0d1ce15bef4e86a902b922dc032a1bb755b121ffc03c981f6bea5fb83b32a2909e133de3a0aaa270d47368b89fdfdd837fbee9abbd9dfdca0efce1af7f7ff8f4fdd59c6657d3fa105d1d2be40b2558f34ec65871cddc5e977274253f968ca5bdcac6169b6bd75308ae1e2fb7df25b95233bb89d9578821d6b4d80225ff50224006a6207217e2dd3267807a12f46196a5c9ee4f2e6150e55d4b323d755a45dde4dc63976ab4fbf4e0d7128ca1edb1f7c762c6e8d155dabad4ab5af661123e9a49010acaa68a4c38f8dda5a0f9fcda72d027beb224becd6298ff7a33476b6195773698347ee5f2aec477658e30d63b78ccdf959a4269ef4c17f63fe5d8dfd97f91ffe51adff57a97720ba9bcebf55dc9ef521b21653bca233faf6267729c9fffe75fdff539ce871c47c8eddd7ee1cad4213540f0677a975ab33bd82ffa401aeff208f54f69f490fabbfd62e7d2bb9a4648f6f3477cb746e8f440d7fa2e8d4155ff1821aefdaf87341abfa1172ee0e7805aa3847a4cd1e1c4114a79472262d14e3fded12d97b0547a7bd7389143cfeff2a498babf337bc63c6ef3f8e65d1de99d89b4f6ae761e24c730df7d3601ffeb3ee5f6aec6be1fabebb1faf9583d87654f75c7016899f55da27fe5ddaa76ae460e1ed2b087adfb7b768df20e02dbbb6c42929361f477b6a1c77897cd6fceef5e7ffd7ffdde46f8da16b8b5f87ffedb8f9f7e7cfedb9fbfb7aebe1cabeba1dd813ee3a45a47ddd5f6aa96ccad93cc745969020e8ea5cf3491bd8b9a55d898516544453863224df15db6c28cea8237939722355add740c2245440682043af6618a8a3b509d2724a19685b97f1e66418d559063a75eab1a3d3152e86253f3327629853ed103feb888c7d47d64aa1b9f1e58a180eb0c37b653813c853d8b421b9cfd6507392eddba10feb0b9e813d951d88d34a3904ac52d48ea71aebe2f4785c1a42605d4ec918503ba8b47aa8adb5c571509d57179f7452dbfb1bddbd94230ef6c350caa5cd6a45aafb93dcb5f16efe7f2bcb9accf935f59d7dfa79eff3dfbd35cfb7a508edcd57b52bdb9aae00530da5e919ea612e4fad911d0acc5a9b2c9c69950064743319cc47584b322780690e3a3c77d64ed25981e120539fb381231268f3a30acbb500ed5da5904cc47a982abb62f966a04055a49c538e03519bc26221faea9aeb00bd216c3820aa31d8bf163a39d67e1a814af38a71d514f2d773bed606b4a71a3b57655c845008d3666be0e97a48319260211170e289ea10e15e722a92f0829ca93681de9ea27a019ad78b080389a84e17c033cb9edc80f5d02f40a2902a02adad703559e25f2d8aa7d2b55fd135dfd40176047ff377a22bfb7c5be6241fde6135fd96cdf5b2bcb1bb4512ae373b83fbd36f54b09f47eedd234ad15a50b9a120975977c4ddf9b769edaf87c5bafaf1bbcbecab5c5ed6afd74c048d6d9be039b979ee5ac481fa8b29eb2c8de017f511635bf1d47e00200ff196963162fea2ec8f07715fb5537936a988b5bfd373b2fef9d57fe79e729669b67489fedbca19d2748f7ddfda1bdd7ce5dd8943d6a55d87332c16cffe57dd4059ba51253c1e2c6b24142d6ceeb79314f01a53fe63ec81a8fbab1e7945a2425e8d0d96dd76aa244a2c0f2104b6b7317ec0ac0aaa353fb56a9cfa1a32eba810cd3a69053ce83679fcf56f8e9f372c96cbfc3b3c7aa07e7bb7b4d44beeb54d0353d52e99bd9a76ddfc67d8623f66c7f3f43a0fcddbdf8b55d7863ff5d1efef1fcb707b6dd7796876c14b39601ca424a6a2fc8be4cc509cadbd1879287ab2386fc429ae8622b1cacc279d0a7d4770717056dae291241104241edb248afb03cb3cb61714518975e68263f2044a1ed726c120737369121f8f370f5bb1577ee220a6007986053748e7862a9c4c200c0bf3ef94cde6f6520c4ca3aa2d83f8ba2f5e7c6518cd82b7c42656ca252b4be94aa86282db8303f967c00d340bfd254557142eb98c17757d14f8badd792e40847d91cf9031bb9f9dad177d3ab0663004c4352bdda3e39d49e92d45a0265030d5c9e4601907208feb5749ab0af4717e9a93ac27c69954ebfae04643fd418d6a538559840f9b3f8290b899cae4e8fa2500159bc4beda264592f75d23b750234caf6a735759b945fdc396f5be0d6de793b7b63f77cfae52f7f3ffef6feef3f7fa32cfebf5e7f5a32a65b9a74cb22f084f635d4499739a290a4bce0463cdae191d5a5cc275ebfc09feb7d8bf5cb3af187e9de80705fc1736f08b0279ff24683ca02b212cd859fb0a99c7fdea7be427ec9753ed615fae7f708aa191485530419af5ffae21cbf4dd4ad397e3b7b638efffefcf88dc0c06af997a7b746e13edafe9fa1f9e51256693d2019a066020e12c1ae4c22db1f80111c9dba8cb6c9647257754fde0413fd922265927586726c2311c3733701d10b352ee8744cf62c3a09e823d2de8fb44d79d5350e19c1f37a9f17644625f4831a77003109cfab44a37ec8f354f5299a7730abddd034cd7cbd57157f1c6163e6d270e313b5b47e8574c9148fa92309989d12034fbdbf76bd4fa5bb8a44272f5fa9f92a7c9dc6840fc2931d2b8ccbeedb5ad0c60ca2d5dc26cae23cba3ee5a176d61ada87ac344319a15ce6da0559bbf7cbad308efa4a31d5362ee8fc4ab09aa5776bc172e2c65afdc7df1ebf9122ff231e2b90b83946d5d80d5fa28a208a4214944fd8d12335c42f55b86465937564b3f9a6d9b893a3f76980e598c56447c2300b4ed999f67f81ced084de12ce49edeef5a4a38b8916dfae2e05cd0e35202a43981b6d109e8c7d6be58536fff7390b13b584fe98cc183c8a6c37999d9b5b554fa392a2b259ca287ec71c8f94c2e5494a3fd6236deb2faaff5c07793ba180bf5393eccff7cdd1106e29bdf03ab0f7c5e857dcd2bf31737574bd4fc4aa6c7fa4479ef7c8c28fd4b3d6cf9ff5e34a400c66c14e825bb22769c7c336555f0582a9e337938db6d19e7b46eafe92b32fbdd8e8f1c3eb85c1f3a98e43bc25448569561b9a64c5ad6457e1c667474a3c6e9940476a1233dee0d3f297ece87d8ae9c5630b443548d2954336c12eced1f509a8e754a9cd4a1ba24ee3995ec7b3bc8e27a3fb3a9ad5a5cfe62bbfce577dd64c95d799fa725104fbf4d6c6e6c47fddd8fffed7ef6f5397305a75957af9c63036d325a12c807726c52ca3a6dffc4309d752b1464c188f1c72a537399a4d1a531853043e1584a24573c3ac4261ec100ccd48e76dcdc98f5092caab6af149b5eb23cc997c6a2bf402344e19e6d3a50c7d4955ccaad0775140b5e2835e1f5c21569832b3706b92484bcd846f614ce248355121b4e8dc6c65e9ee97d952b5b6f35f3ccbcad4e397124a4102a52265d8206c1ab0ba97e1a11ecfa166f0307aa5bd4e285523aae4a9e3f7c60c96f35acdf718ea6097247ba8d8c218ebaec7d067716b860896d60c6be61063773957170fbacfcbe09dd44b48ade3f597e29068bd8241b3bafa479370c633158e2b51e73ddbfe51a71f255634fa7423864803f948c4cb620319bef28f11bf8884f2ef7fbdb117fefdaf37f6c1df7ffaf9f978f846883f7fc4dcc625ace62d3dfaf4904461d614fda767c197d4433ed6ce43001f0d647d6ac36d8adccd9e9389cd0b06b88920a48acc4ed1c32c6954fc1a61dcb528d241eaeca1e4c5f20ecdcd1f52de275276d0193fa7b854224397793d8f1fb2d92cdded1735470c940d3d396d33e661a7cb032e278915dd8a17d33fd7a741f1589f613d2c6a9196c2fa2ebab77f0bfa4a7fd5afb2a09d5c217f71859c137f6ba19ce76ead975fbe15d7f41f89e047924114f2e725401a880f9b986f88171651a0896e39ee105a55a5e8ee5000f9b75445e7879f43fefa3097f7ae2a879244258ba36dbaaa510740bebde4cd6f764699b3f9097877608c152144a069eb7269aebb3c3aa559766f990475690a13c743a16cb7e04ab2ebcfe55731e323afe18a49d1bb4ce37d89d165b2f7790ca20fcd8e0e5ff4ac186a29faae022d580f09f41cd00fba547c553c07d2b926336688d4873aea4e0425ba2264a02af81b1d8cb631aacc66dc07a9f530ee96760a61bc12dd2032e2463ac64e4ec52903afedc3d446182189db1a309876a26a9b13f3c5dc14cbf2e64afee51673f5fffcf3a75ffe9f1f8f6f146398e95f8ed0cd24d8b13b3b02717c07356da92d9672fe21ee331bfaec2eba4219708a85fea0ec72016ec7d4cdc73ae3a3498617df536807813e666e00bb42fb9a227710d3dbc753ca17dfc7ce818ea3556d10f8d9abea47380229fdfae42b66a6396c47f46317bc2f6f2a308bc7af94e70c3e5b15b014b8e4a51c5100082449662378b2f1caf3267baabbc69b2cd1365f919e94bc08d2fa3c7a9ea2beac8e83b513c0dd76f27a3b7af469ad8fa5a7c34c6ee16a63eb64df85c2049d41a25638431a5c607a30cbfb00432e8ab3d01e7b6e30a4a20c009896bbe851a726a8086151a8fcbef476a413b44d55e2c3e58d3d980476bd4c5811108c2ac57f01eaf14babff5cce3736c079eac61e7878fef53f7efcf4e91f7ffe369442358e7f1dedcf96700eedc28cf7d00e7386bab0c72a1c0bea2602b31f6081cdde09fba338a4810748421b813a5fe03bd4b74ea762efa2c028a2a7ec361077a2e5a78dbd3b37dcfa6b55fd548e7fbc06be49e800d843b6b4ede60efa67bb0a95f326d0db5c0709a89eb30928c94fa63d5a07bb46bcfb2e0657d087597069f362c8df07ae487471a2b0481b1f38ccbb3c12743fb92f9a127287a919174ddfed5a7080c303d966b704c5de142a9172c1eaf0152766dd817d1c69c19141609704d99eb8860c1ca04bcf46307059446ede3d20155e08b194dd6f3e567fe283ec4402f7485caab9c42cc1be28de7bd2bb1bfdeb95ef1c9dfe462b5e77875e145ff70626811ff30e0297b42942f27499f6e22c8c0b1af5042931883009b60dee60516d2671df2ba20ef8c6044585853177dda7702d486266d5c762d62a24bff11faa307a04e4d6c47109835f8a277385da37b2f8cb99fe4ae763d9fbc0115ea340d436cb86621e222d1da29049f5243772828f0e42891672c62e61696a22cbe0bf2aa243e395f2a455e22acb2ea0d9a9ed56ee7c97cc018b5c4c0a9056fd96f2633a681f33134f1c9855408455d9f22144fee2932ea73814629e0af8a99da3062e656c8b3ace20e2d9c53e490aaa46b57b6c6c278c069f2a1dd490f4d80fcc6d1fda95515480854f5b457d68048636fa9e2c2a3693b393a6ed8a5b85baccaab20f9a36448e35a65042e6b3bac9ec5901b799d1546f93f0b18f7b8a6ba71069e673126d3b819ae566bcde67818499394bf417d02dd7774f9548ec691aa50327ed7aee29deee28c47016c454db26f545c39bf89a224e6c62f904ec88bb27165448512ff1b09e8270be2ef42d399cf0d9b353e2a83a8d4091bc8da861c085e992f2ea4fd31ea6e98f580f8464cc72da0425d0fd2214d4cca42416b83276df02b2512645c057821ea7b3cf75208786966ad2cf2f92ecdd35b6f3dad05a543d270726f2e611a691514044e92cad527b5ceabb1f0e0a204121b20f10852a45490a6391c0dcd493f6068d1ecaa009a9cbc619e8852a360e9a7b5313ba1472670a8546706a02f161d514d1d61401e464278a0d82f25449380d1d35dca26262ac347f5495e55d5956740eb25e75f2ed2a619a9f4cabf5b3426d53d8f553d7b550ed318096ecb66dea069b1465fbc629f654b62d74379a8c3106250266b714296726e683205f4aad000567bf33121d5845f47935f403cd28690458f3a4001b760e939a5e38dc8914b5e2ce42e9acea294c4d6171307a6076d824d5b8313b545bf4ab29a3d8e6615fe4c12be2626cc6731633eda1be499f543c2375a43b5c15f4b2fa8976f3f39014ab92c355c5d5c2c8343b43b6b8afda911d48579810136b0295a2ce4690cae86cdbecf8ac3d9f36617fdd0b89162445cc5143cbabc969076a4fd0b01a9448b1b5ba77816ebda91d1de61a25cf3372461a6313d72e1fe6c58c94900e10c644f8507609e5d9dd286c42803828ee81b11b4377d7e964750ed976aca8f822442dbf45856cb74c6aabece9dfd2c5cddd375742c7a61a780e14bdedb50edde1509f74dd604adb2e40950adb8f06cc7192b14f012f3585110a7b05b8b5d0bc4a1a1a37c56e11bf848a00370b7a5177ef7419119105222551422729dc122cf8ae52a2bc9464ec10282a50cf9a6dae9ac8cacd0d4287689f21b20ac03fcc4d7022e86dc2912cc85adaaa1819807b98d0aac53b049d963111207a8b9bb1f7d835add34ff33d6657618f949f57759b10069aeaea5ed5e6f51ec7a7d47ca89a97f54be9c5d8ad2bddd46d5191e5708b1ce254e7fbc24b5ac90ef2c1c203d1ae1297d9a55ac2da426fa9567277b2676cd9ce647756ec54a95311ef0779abee365388167013c9a299394da6818a7e17a9b053550bb28e522369f1e7b62b65a4bcd1f5c4b5ddae9430e57d6c7c84a90410cd84b20d50f6d7fb1c6d56fb211a523ae5a768888749d7a90a10a9dbe148108179de289ace622165fd7432be6dc34b8ac649f61f00a46dec6295eb53c325a7c372d3ee79600b5b516bae89542af3ed6e96ee06cb06195a5fbc390e32cf864427c2d6bee9e986011d191c2be17c36301cedabb6c22066ab4a346ea4cf0da4cb8d8eac85515e23a1150f88e807f4f7236f239cfd58340bb4d92ea1f889e43a0a5d726c124e99bfc5fc789515daea14b641f565a953c6bfadcdba815a05a2e1e8097b5ba05f72c0df7ce95b3ef8dbd95b6ef8cb8f974ffff8dec2ef15c8f99e420372bf6f0408621f70c3d2f1df771dd9667f6c32fc923029e4109f610d4a5eaacea91a3f098cb47b6134c29d4e1bef923dd05d9a72a1ebe68e496e03e444bfdd7ed4f2522c179619acd171be92fe05f28a2a4524e3a0df5f052fb28b162e09a4b7f2d58b7a29598842753d8f7e583588d7d93c0b5bf455e8ddc26334bdb0fbef969b63c7e484df539d406575bce39f1b63344d4f8d96c00707947fa0531602084b262f78a6ca54d05a4f7a28536ba7120f3f33559242fcdf964b277e51c47b383d0e9bd92e13b846e6ab8bf052b0df2bb4eb3d54cd64b3f2f3893f092eafc4a3545afb4d78645737b114368048d90eebdc95db66d2e962292c5a54e91d950b82c05cb202d3ebdcd4299f78c5902ea053f82eaae44caebec84e82fe90ead9ebd3d8881307b589806254dca50d0d9114ac1b68ea287c45c5c73f3b76203c8c6d3583899e363128f83bbdee92e104487435e5d75dada09e0a642d0c683df0513b0265f34baea47e97e45326561ec7eedbb3f1dbf0c9c00a2e110f9a701f6b9391a6e605b1a70039dc0949d8f7b26e7dde3dc11ba724296856f7afcfec84c330972a33866cd992376bb4c23eaf87da7d94e7cc22d5d0c9b6555b4b159b0b7ec1b1b3f94c831eb4c8d7b1f5d8c5c793553667462df5fbc2b584a965e352b0ae21b46e5454967d48c54f74698157953800ce9ad1eaeae44955682f66837d3139ba45ee4d49cd991b52fac7876f952df803325abb6e0cf12e55bf5b7ca7764517970de437eaf61fe7b64dc2f72d9a4c3906b612f7a244daf58d220c8e0e45b359c0e5e032124a980a277a61a9263159628a096c37fb4968729815d75439c7e217a132503095af6dfeccec4b3d011d40071abbba4be4dbdc7791473e587649e6e310373cf0da61dd816620888f087776a518bcd14e8f04a2c7b96711c514d01a5ddde0afcb1545e9f0dd4c77f82dcf96f90aca34084fd86e6a2d51462c79aa60866296b1910572a482e8d3b3719b772de2430c3c6c10e705165c6471d40d9bd3d5710c26f138d38f44248622cd58873d9fb047a2cc3de3a8785b844b85dc9bfd86ac4927979ce9e3215291c4c39837c1eb143b628912cf743b0d55478f69222f6305ac1ccaa12ad80d46b314818389be6cb37b0996a352abeda4214c857a052536279abc32f39f4dc0c32025d82271e2a0adca0659e717bbd0ac3ba8fcc4050ba6c150f436c93d1eaad7caae0099d7b6eb2d0365a3f0c3e18573a17e2745b44356de41ad7a55b04aeb5576f5cd89e5361c0018ceaa0fa8b26793293d98fb730ce520785b4efbbb8974be13f36f42fbd5f25224af0925c076dc020a7a6dbc05451172c7414e1b80ab8bf1258964e1fa9477bfe43aba3222533604ea4f3a2186fe2c37a7878db95dec0b607042fca520626568c2782e096e55f0c8c238a63086b6630b5d03fab3cc309e89178323441d5f85a0bf2bd542684114083ebfe26bed40378267fb1884a7cd4e27f86caa82489b0099931d3cabfc51cd5ea4110e4f86266f1c0a4fbb89889ad6b3e81c84a0922495faf529e1edb6143285b49a4a4a6da99def42c8ea8a26a8fa63ed30247cb1327f8b7ac91414adc34d4cb0f91aec1b8ab9665c6e96c2205eaf553e15f541a2d62d15bd1862cc48d0b3d05b481526a91ba86e9a701bfe7ff6fe653992e3d81a855f251ea0222cdce33e94e1ffed6000d8b1efd0ac079c41a9debb682a48da0485ef533dfd315fcbb350dd5d684aa47a9f1e6c23bb325099951919170f0fbfac659d32c90240a437d4912e9e5a30611b550870e1640a6d02b4726eeadae5098201800fef06a785a88045790b538aa7f4005cdf7e43d2150d6dc086804d38cc7595103a35941568c3d1c01963fd3d7ce7d099098cf405507e2fcfe585d92556208ec5ee4e994ab07f5865105253b8e835da65407387fd23399eb1bd03ee77754758df6810f3454a89340ec3333c0ab02461d982e7a8c3c5a5f4d7f9b092c14507016d8b645685ec3d15fb4e585768a81f240235f94ffb107c5a9d6e141b16a1165268759aff3a37bbe2da6cb39a739f727ec69212d6dca84a61950656074da00415a78f4e76eb2e0dab08e094dde8ba48f54ca23e1a5316d08aa2afb874b214ce23c481572099d406fb1d9c258b62c5491c10e18de5a9969d661c2a38bc05d503cb4d56aef333ac2c0843a1575f7605b250112c117bf0953cafae1186c919530a6346a12d17ae24406fe3bc5fb46791282970f7212523a8658b1c1370c1122c0a0d59f696d901e426ac6540292a241001189acd68e2c9a93b379d74a1733e54a73d55373a93154676cf52a3585697f4e007110878e56e039612a7a547683b92bbd53d7226ac768dcd3642ee54852e04c23b5b4f08528fc5ac6216359a1627b709990e47c7fb433f743a37d5dd0fec330c4cab00ec2b20cd0566f964a9218a016835958290149500823e3f833edfe6f7068b0f68eb3dfe0aa54a46eb4cd13ddf3edc449469fdbb5c805fbd5c7efff6f1aea66f6afb2d3ddfbe7f47cbfff8f79fbf1501e2efc1106524882934f5d476f456984605167bc46b033bb62061f462409f915cbcb6baaaa74a541b451dfbd17fe266fa4fdc8c44c12da7768cc556e04a5c05bb29659ebb805dc5a3577fdaf1859e0607c0ed495e6ddaf78dfe383e17d5b3e30b1d64306cc3df97018d4665aed17a6f95b03ab87788ce013a0984c1000bf144c3f120bbe3411e232ccf99d8574cb95116ecf4071dc8d4caee108307fd72f69874e34fa9bba126fb9df1c8c9a0102969f4e81ad0e8e7e738b383671de198790502ecbd94b52953c7482ced2f325fad8bb6ec3cd325fad7f6ef08cfe22b16a27ba9fa1b6e60cbd18645d5f9b379057658af6da1c5b1dde3fdf67f479874fed5c79d9f6325d7c6061d0be9859d49868a1761e20456dd2f3bec7e0ce61d351f6a7efb5fab6b0191ceedaa6a5ac796fa6950276a4fd4609c193870ebabc792caa608e262ec07813761e142e5b60c745825235024db911c6d88bfc2a8796cf030f69049b6cd3961ffce8f326cc9e84f0590f7f6c1a05e2e3ff568cbd65301f4bb7df849db469da2082cf01b587012b40772e8d8f1589e4a1a8803a89717b26e6e27a1c5a81c6df539891bf06e5d6e5aeeb1a4b629c126b0b455d2f460bb439ab295caa952a723ae982256702e465debab2d8d7a1cb8d1bf3c4a2f00895f76bcbedbef2395577be8d78745caf5b3bad82cd53a2326d84af583b67934b5fa09240bf860f368d4d798e6e7df478d7a8422fe8aaa1f4d3df9ca8f07ec35e3f26349eb882df113d80df0e1e7ec06afbdd8cdc0e2b40f543bb1ee5b962fcfd8edf65ac28452af1f641269415db3a9108192ec22b1c1113a58b812898b2e009788fbc9639a178948fbfc7435a95a3bd48cee5da974988aa43a237a61f1fc0c25a4a94d71dbb047b715ee1b177961cc57b9047fc9d5da8134c40b82044fbef81aa1e1720f04af3aa1de86e03a38f1143376b9e9ffd5f6dda86bddab2a979aca1182fcf36646cfac777be628e8cc61ed7f995c422df11534b847dbd19fc86634923e692aa61e16dd6f4347ff51c84dca8e0d34c21524646133735f5a7b05edeb11d9e6447ff48690b78678ed644906593bd865eaa5a5733d3fcf86a8d4abd7fd5706e2afbeae58edfad7c68b55e6dd3ef0c1a28a3c45b8843e1b2c476c315e115c766989b8b7c05553d82e7921a67e9e6e683df2a6f544255e4ef81515eafcacca98541319a583ddc70f6cbc1d95a06c50a601c1811f383fa1e7dcdf955569d8e83d14723448d0056ce255ff8b203fcbd577bce434f1391931de194d40eeeaa674462320c2b66ca135363868b1d27c6a73a4693a3e0eac287935cb1dc06d41f953830ad90465202a304845a7eb085a08da01d15f3706d116cea9302b344801eff3c88413a1990c3988428b59582d5c2858e14c4350b5c01fb974df4f00b5853c86dc09332a09362677218167b683f1521134f05f91016eabf9f613680c80d89a9991000c53428b99249a71678febd1c45663b46f0336d9a2d556e9b09c08e19cb0c680dc7177194a856b13fcf76880eaf1943980b15085a1f9cc959e04b487516c5627fc2cc4fab4aad0eb01f406826400385e46478e2a78034a4fd31636c6cb89933717e2d4b3c4745d004f16ba77c885da933e0da9c1fee5dda5030f6e057fbe1f9cc506db5d4df57fe90073590f3a4834f8d4d64c6abd88833314594777269baed4d77eb88c34d8da187320cca92dd63b34da8896f373c9d86717705073ff0a2fdde458c2a654dd8e30acf67074218cb133cac0deb0af96ca0c7ea06c02dedbed17257ba2bd28261c121b2f13eea9cd99ea087ee0cd90ef6b6fba81c70e4ced39b94d7eba59b9936961d21b6092689097ce5e14a10c6526904840542c4694719e1052bf3ed9c064a08df354c1f81d5b1a27103c3f991400724b77176b64c455df9ab377c0851f1ca6dee49c691d0d76237ef2674383940de137b4782b4dc8451974ac4fca84b8b4b71a02da37864ed38c127688f8402fa287abc1200f932e50896ca63e0d0199931ffcd518360d9619a71a11da5f0155341148f3445e71670c8b42787ac4645e624c77e68de009ec8e914c6351a115b33fb53a6d51f3c3de0a8e42fe5f2d4d04216259aa4a400564d3c3458a649927bb2dac7f6dee8d6255d960de474ea2b3aa34776aad54ef08f8ac0b72df5ea66362da8eb1a55e37a2e2232278901800ed422caa4c9f29f899d9a3b6732e4f62e36aa786c24a0617e2f4c8c0ece06a8c9bc44233b8cd51b7670f8523c6c9080acde3b530ee7222b8ea496a52d273ed8f42660e4ccdea9ffc1ee21760b4d4d4b01d5e147d640eb01d8ff5fed0e007ff2506bf9092873998332db2ea56ecbe6a6a4f2a78a27cf2c41a071d12001aab34bc1761502a683ac0210ee87f04e44298c1a5c4968c1e9fad9cbe15a33e9b7ec3cffd9d01dd71e2fc53ab3a3f9d488ed6bb0d3e1cb280aa873339947a7b2a0db4677ee0ef0a65c42619191c4029aab63622cda813475d16e3c0244e0f37243430a2079b6dd5f01e22f5186f68683e53d66b5d17bd4a39dcc417db5d0d975d0d1757c3ed27a62462aaadb7fbd9bffb92d73bfa72b3199a197d7ed94f88ef27ea957e28747434e6c3c86bb45f3e69b8e8a35827d6f9b1c0c0feefd4e69809336cb7fd6fba63a35fcbb7975088c7ff671bcc7f691ba39adae7f7fb748769bb948bfea851b1b543b0f35a3b3ecdd2d36f6b3a37757ed5fe4b83ee7b56609ebd690bfed3f37767066e60aeb01deb7d99a0a281a4cb713a214a89d432a95f20196644688afe8d8985098eaf6b30cb2bdcca5785059e50a8579895a1cee3b47db06465f01a12809960501151d5020cb63330126e06c0ef01b724d36b8c64615c1d47bb6f3adfe031af50573f2c301f302217ce3862e8c26101ce0035a599c641df46baf395c7fbc1206278e50a8925a39fffa0132645c2ebeebfb0230068ea467ae5e2d1207efe5535adf3738e3dff9687d2b0f8af3ff68336f9ef7faabfac02dd566011befdec52c6ae50fdbb1ffed577feda733fa8cefffea7e26d7fc3733fc87a17478f22e8b6e0fad3f34d99f5c78fa7ef2d4a8dc8192dd73b41b467cb35ac50b88b8771a0225eb8c380300886bdb0f9a5e978a5b611bbc9b66470a238962153a9903aa56b77b528324f807a8cc0c1959db51007905121e51c716b0db7f48280df63113318e1b797d2493d97616e9e5165b2aa909365bc95dcdfcc8cde2e145f2c3d807824cc53adf494c946d3056eade02172cc2b963c580721e9cd14c1abd20950b6a80f3221a04692a1677d52f2e456264c48982b416d420810c2b5a03323524b99cbce8209f911975b555a546d6f054fc9a57b9c9f7821a22a330c8efb7784acaaedd2ef1a40e86a8691622157345cc6c6fb53e08f1f4f3767c01f3f9e6e4d803ffd3f3fbd7e2bf688df4125d23040f47e594b54eccf9418fadc9ff5345fb5cd54ef72a805c1cae89c990322ceebcc479cdf9ae227f66dc43528d9c707dc66cbb0c1e05cbc9cc3c7f95188be6b3df1da7a2ab6ca0f8eb83ac962cfd20769ee79736bf9600c0972beece328b6c97ff7f7c788db335b9458c29d364dad41ebf91916aa30f4572efc955aaae905bfbd96ef8f3a0ea39b038fa76e8ebd3ffdf4cb1f4e3f7dfceea8f36b25d451c1f2651a9f4e0f52a3ddb231840bf6a4116721cc65875913e68cf2a0ab8085f1341174cc0d210254909e5e008a7bf9c08e1fb163b4f92edaddc68befb2f7bff1b131d011b51ac09a85a149f514d71e1fb8916514b95d836c81485f7fd00aabcd181b8944712a67a6770b6ceea4bf27104166e87d7564e0b9971af1c747491308bd505e60b115183e2e5bdfeee9cfca78fa89901a3200c24ec398528fd565c8ba22261bc1522cf274865588315e1a3d48476cd122752122fb8057c64c2c2b9d1f051963254f220a121d808c6b970665bf6476c527dd3388818f5c517e1b2f9d66376328fef8b497f4fcac300d2e0c20589610782b8c6a4611b9803956284424cacb04c9d85528dc8df99488cb1e3b22bb28a025a5ba7e74eb6a78e1192995dd6f80a43de49e794e9775205e64afbdbfdc97cda4de4cfb28bd34923722ec6c0cfdbbbebe7c054feb6afadf161bfbd9f724c7f7498ea19309340d6e7a66c3a8a30a64daaa08796643b5103ebc33b41f461866e32a515c1006633b43a0fb20b15da9bb100c6738d6022dd4447c82a7b3ba81a533e23e640f38222279be44402f8febed8c9e9d8c1acee4d8bc9c0fa4dc847721ec89e02deca71a4f3817c8e53cee7a7e5e99799373a3d5cf791ff69bb7f76fde2e375fbcf9bcdc7cee3bf12f5f841fff9d2c79cf9034f453bdf9fe69a4578fbddc3d0f482bee7b3a2e883a750260d8d691ca74504ce2bafdb36d8204bafdc5d926fd569b44cf57075f76f77c55dcea0468d848ef5131c56261f8ed682335cd1375ef659b362c7d38d9e95a4c0acd97646e1d19df93d9c002216d5d448c830c3b27397ae03aed080b05cc03038384eb07e267c1648b08df0105bb04a9740c22319164b7023f1a421b59e4d91ced95d8121d66308177a233878e8042c3c3bd51fabaa47a9761e4faf47bb2ea7b537034634b9dc9494d4a27f5a9242cd113e55910fbb7412fcc14c258ac5dff74940375704977baf1db78716dfd1b11dc91f05d0534821cd6587b9c8ed8536238c8c8698c88ded9099ed64f00051f139ce90e96b0654f26ba7e1dff602385bd91ca5b4bbc7cda68fcd8f6059d1659f515789ea2d37461a645c66806cfd20c150169a6234c008417a8e976b2d07750e26c2e3223c3e4eac503a52e62762a113277c1f8b99886d3c97c2aa191cf163efcc41c0b1b4f9e30af612138a9786110a9c35b9c1b6d2be26406a607d2617173df413332bc1323b12b0386164ae7c792c96f4edc2c526ac6d1095402c8c6ee0e09869c03c126827137aae7443250d0b4c5494f3091026c435e581271aa145cad8e4401db2f04c28dbb9f9f9108c539d13927fa65f47f32baff994122e1f3990479f8c940f9bad07957dcdc1434c76fc451fd7b5069aba4a6416dd8f6cdc4af8db4a9a960c4572fd61192028c0448cd922650c5e78cab2705dc99626234eb3c82ac61cb5e00a2d6a16c6438044b8d53d3024f6d217c71f1b2b4d43b81b6099a0d46dd39bc2c08c016bba7b4943b4ce7ea655b252a9597de819e55d320493f90155b182335e6206147a4d07a446d99d2c15131c31aa957e4e69a3453c43cf0afc70ab4f89a66ddec8d4cd9e6b1a6d2bc38180d52c03d69af5f429ba9f5b8a617449b35629e514b4b0b89d8d63cfc43d47ef354576a4049696d8f45c13bae34f40ef781cd6342c0dbce09a9233da75eb68c189d810b80d0bce067253c2b8ddfa430d4d4c4b68979ee7fac09473e524304b9770098c8004c59857dfdfe7c38de24ade6895bf3e12f3f7f7f9605951aa433d25ae053ef64bfa9802030393252bd2bd6c788dd0a05eb1a01957b9888ff5a368e2490ba58b878bd8a5d707ed40603e1c68cb01c27c107b1c5684806bc13e0e15428640a4f784162aafdb4c8daa898014a41def8221d79aba6715768c45d24432c6e9aa461f25976d8d07657da0a6560bfb366d041bacbc916f8802557900384d031cd1de3a7a2a49541e41dd2573d2dd8e902d7d704a7f5fbcd8162276e0d94bf9dfef18de8557e0f9932e877ef45e71d52e2eac41d95e6ccd2f483f47c97c384eb1fdb710da233143dcad26deca12c9367ad203a5fed9c036befdf473f777e14a41d2a515fb034527d2edcbb541406967da163068c862b105f8b807956a11d13aec1470f280a9088a6728c568932d33a16b8dfe92345605445caf00298d4a09112e04144cb63389e67e9076e39914cc7fcf192e454d38cc5c6a04083c9c8ac29be851e7095338d04e0649eb247a8bdc6242f862fd20882c0286e8e1975d200d039a9cd8c880d563dda0cdb903f0ea43ba8a3cac49505a00dcfc966242ab19f818949894bc05e20b001bf4f894dea60a104a544b204a3b37976c03e47f82ee13bb5e8c19d9d05924a6092032a6651d32a302936b25208b1906c87bcbba181378c066ddc7631c55eb84f879d81b75abeb36556a17bff32b149c3f2cc7d273f8372861d819ea260e7d9cfcfccb903a112a2c6186bc5a755872b3bc626696c48bee4f09201224ea4b956744967a62872f900c5860b3c0a86e09d23ad30cfcf63c1e2d936a66520a39f10829e321506c3bf3afd928e02f6e2f43ea4072320ab106e107f237d4b906d81a861cfff44818194a29c2b7ccc88d5f3ac3a01d9b80b68a9be30602af8dffdfc9c69d6f96e6b8c7c9c1e3eaff7bbd2d984ed4de96c276e49e7978f4f3f6fc7ff7cfae5bbb3f5e550f4b5d679ac757e287a9fcfcf0a5ed9522a23e57a28dcc4f5d832c1f3176338b11f2dc40286d5a2334f76d18033287f6a4cfdb532d30074403dec3050080b5caf33c94614e2423412262df748a120545921c34bea69be46fb05b3ea01221889b10ff7cf07d506233941c1a369697e4656d9f054619679eab686c0bf8c78cb4c6c3e064c3a2a6ea7f19c662f863bc3be5c074d5c9d58ba25f36286094f446602713810eda8324d9aa5d771c12693d236829be588305a806aa2641f1fa48f2d5398c3190df10e1a8bfa523ca177854be904b16ccf7e81a8a7f85d2eb511354be3d960bedd7274a7577a1161b30b8ee15a786f96a8c7d03e9e99a54c6beb11d9eac8d41847ab87f3e4318318300170cc2f041e76066c8e8bbdc3060c60b6a2756bb765b463c40469919b621e0bf16d0773bdd509f56a72825fdbb22305dd8df6fd6bd3f76d36de9cc46fa76f4ee5bf9e5e7ffacb7f7e6f4cbb3a31a71018543bb32d2aa212002659632da93e1453b4172c66ddb1ca231079c025381c3c6a3e00415a4b4ff3a49338781d1c6e04173c3f6ac51275276051c61e52c39c1c7bb8b29d94611025adad109b222969a9c895b1528993c036cc830409b602b70d13504f18cd65a4b939bc3ee07bf3fe5ac3e1db31f82b513898d78ee4c492f4417301bbc63ca97a5a150055093c85403a02bd9107119697122648c9b8e623ac8eaca3023a48160bf7c3d3c351aa97edb3dcd535907d534381b18ba4612d4ce0659650e64cfd0164b5987738b9bbdb801c59804cf79524771f87b74730cfdd1abeafdfdb02a4a6fc9b70ac69aea7de521b819f08d98e56eefcb4ef7bf54f0fb4debf6ffdfc2c65a566ca546ec798a43c69aea9afe00746a38e9a8a89d9728a15b91f4807913652261549f6340a20b492c065d6bb3289c1040dd1866501f1a46a4d2256fca10f3fbdbfcddc402c3d67e805a8083a82d4029a945a5ecb4a62237ca601c8e4b11e54b01c5bf72329bd733e990897b03a0ef6326c1c531897ed9d00bbae4919e561fbcedc5e93c811448afd83f695e657c26d5e6f0ea2d71bc3e7afdb9f3ffeb27d331bdd6f8f91adb3a72ac0966d638ba3a75562cb69da3e63258101b746ed3589c66abd7c27b6207704760378650ce7a42b496c7f994dbe64408621d94e85de7d70ac36883bf86cca0a32ddeb5f348d71c7df55ed0c8fae1316babd00765864ecec691dcc7d334dc67a311664040d008c6809320123d8c35bed05ae05abfd804d0f997e2d9a88eb5097d648d2ce8fba6a92196aae49f5a9d8fc28c10f4c4699330919fa06ccf6030a415e4f60efacc10f9e4bd36dc4e94865fd416ac19379e08c5933d45653ee1b4058c18d00603adba50ed3ccb5fe97da7c8fad0501fa6a5f1be0b80170d42536c0e2966a05ab7d217c2162d36a943a53355d6fa52afed70fcd16831564d4e0456d1d9c7ae058432eca272d717e9459316d16f2dd4d24047efa8b62135ed2d02d1212a82cd066827aa1ccd0676aa676e6f59a9a3c15d3caf6dfdacf78b7f3f328f6de973badb75b0df03954deaa4449b25e5397cd4ed7963282470608f31a80905b496d9e9fadc10b16dca1a83916a452ae6a2e9707f6ab07ce7a55f77255f79226c2c83d65e0d337784f685c24c12dd97139795b84fcfcfcf2dda94f759a3603c678b2c763717eb972d8edffae1d7e3f94d9768ef9f3b3ad1e355459a91de3caa708427e30fa424b26d0513125aad318d1513a8e96ca8979b66b31e913dc83cb6ef320abd0c9ac4492439c4575c45aa0e3b7904f60d10a329b6d8d967b93421b244deac4da65bc534db6bfe0e12470a38a7c2d348e7df64e4ffffcfcf26537fff0f41f4f3f7f1b8ea1df63b91ea6081c783841dba3ce371fa4f743a9fdc7476dfd6023611de6611e78d4d67fb052cbd5ca38dabfb2cae53b2be3cac3fcf1b18aa4d90e326d593fd99e0f4687f207bb673ee4831c6a1929cf834c39e6a7cbd7d1a6f24172aafda1ca3c40931e57e7ed54c355c77c7db7eb07fef8586ca094c3aaa70ef78f55e0eaea52e4306a5a7afde8c3e5d1ed84ca1ef0b3cf9f7df8e2d99787b1f17afee4aef3303fcc7a759779989fbcf18cf343bfae1d6ff2e3a34cafe5d5ddd032a8c2039be6b0f67bcb41f8a2077b67bec2176f7eb9e78fcfb63369f35035d5f5498d6d3194437e909a0fa0f7d7eb1bd897f593578cfe83130bfcbcfe896d4ef6c38f8f3ddb1b7eda4671de5fb7d1e18b363accfb4fda8837f9f1b9e624ed304ad2ab97bf1e667859ebf02fba3a7294adea1df8592bdfe8684446b6034808e5c767dea4f44fae59d5c7ec295e86bd7e519fcf46fde16d549f6ebe85e49aaacd8692b4fef8e85d5f65a29bf5cb915a6dadc538f8621888fd77b9c18f8fdaeba1d65f1ba155e7a71df6f920fff1b98fd83f9b536c63bcd8834f932af35647b42fdb03274f6f33f1b3094c01f2e3338671fc6218efa3f2a10c3d9459927e7203fb72e8ad717fe2f1f3515c564d6df9e147326fb7831f44722af550b3a4de0faa2d8db61ffc4b5ef2e3a3cbbdcf46e4956cb91a38e533c1b8b7d427826ffaf87d1b39faa5982d457e7cacb51eb4d7fb4ffa327ed197711ea57f3e19af6fc9dbfcf8ce6ac9a5efc662c913b7d6cad3c797fff8ebcfdbb7310ef79a7f8756645aa156db711f010fdd36532a9bed400a36d2d0a3a5a45ebddc6de70216b3350864259a061d196a9bf49e3a9169e7168197801f62c740b02fdbe4bed82d4b500410e29b4d4af0bfe02aaa5ed64c3bf3c04d7b8fbadf5033c03f4b72f28cfe34ed9ef8700c16db348fa40bd05d6306c5862f652006d9a94c4b66a143298fa0dc6ea755d26aaf807fac5b6c688b94e98200d23210175709927a3b3f5a2f68b16de51c365f67861fbaac28bda5d283b54b05cc7119a194386063b0cf8640313595af235c4cc0359d5b9431ac7f96da0657ad49c5ba66dccdb424545bbb402769fa60c79eb515f013e7064888894fedb6331a74bef691fa08459f446bd21afcb0efef6c2b5767c21e16e91530ee12fb52c2944452ef89447c6c89064cc84d8934d2666ae3aed98ea4587b5bb3d8dbf515bc85cecfb109a23a90e904d6a6c10848c4650902d5273e055bca11d5c74405acd95e9c6955441fd71ec46473075ab1e07adfe92519189b367c531d49814dada9f4d8530389da8a36409ec4b6a2f8c84e4611255561164b89037d9309902e911e484deed8aaa40b42d64585b572c23320404903fc2612e36410871cfe41580cec858a8dc31e977d6da5a7624d12f8e9b818b6da9586091593da00ac1ad300b6554b434e88ba1ea90e5c9356856921c9e4b15a238c169ca4ac046ef5d5e62f8aac552686f4809549b81911393f17b515a8396e58212e6e8743db87494b329f24ec29e6185ba9cac95a986f7539c96a8d8d81561d0cc5028b4e0d18522977eb35505f5b5f81b38c2ef0dcc3b4998b92642c8da60bd0db21206f033b7c05aa7c7fb21b13d3794711183670a5a656b71c087add6487806cf00f1520606b0d138210f152480694bd29db8c302ad8569b0d813df79cafb6bd9e734b195e6631c1a1187faa365d513e3fcaa2354fab8d3cd066c9055041100239ef65ce5b6701a03f5fc7fafc64b89c3caef4e56fc3e5cee7e7666b3782a181b2032c50c031820d155bcfde58b429e742bcdbd00398934d3e0cc9809981c984b1e2f30acd0402354d02dbb7f6b00f2b015d256095ac97d9a70c89141625132151ba0d7845874c6b74eb53ce816aa33f0db1396d0d0fe00684759727b1a7e1636fb46ad7025d705d6a6e831f6828cb8b035822c0a264f844a5fc87d03f169bcf766b902996ab268f5823ec3ed95618e76243b49f89d7727eb6451168537d6dd7334ddea61af968255c49c4712510a70bc49a041ccafd2210cbfc5420c29668cb1bdf725a7359e9a9e0fefc74c4944ebaeff2c2290949d94c806cd6d31495ed222ae7af88ca919630a7abc3fe654da7d9ee84a228031b6bc79aec451934f7bf89d1792546878b510623ee3214ddfbb918d51b62945c6a9f0ad1f026a5ae84274672d3af494fbd48cf37f139168ae7c7d246caf655dd320433c7a54f387c1cd9b3765ed020e8b06afd632f6f3d21b69910a49ed8104020a6fad1d6b23a82cfac7d493b699ae0e3181b50ddabcb087f7e358dc1c6218c4988bf419e470552538dcd9adb3e2220fc974604d0343d461b3836dc67c0c767e2e78425280cbc50488302df4fa274b4c6dbb05e06603d4c13392d632f9badc15b732b2b404f95ea1a4940e7c4ada3b529e04011b78448901a5d63b1b7c58268afe94d6e072c391df1b969dae2daca4b46bbededb7b57d3811e2840bb6ad453aa3dadbae34c0da0c72dc8640a705764e138a434c60485cd6fdecaab6d2a8c05985f4b14545d70db15be04ee85b4420acbd5173266aa60a0e2f0b20c832385332ce7497af124c245b1bd323919aa6bcc87b488262c45ef8f5884858f0a22b0294ba84b7e7d802a6c26f2565788c1b66a9ddf6fc5cc9366592b361b28060125030c81700b9a3bcc6caa1727b1d1b47d3d16e9ec638796d2d29162be0d4eb55abed6b59af374fe31eaf40d51b40955d02b5594cc7b6318ec068d3f017e1b86c884117a7e434a504ae1a7adc785b5b29560d03fff34bbb32a2329d1f2ef77ce89d9f6b278c5882281184c8adcd2f403db1fec85bc105cc24fb4003a20f62cf08ee63aa83278c08ee51f6e2825218bbffbef9375c28517e3205bd057eee885ad6add6812f26db2a67a95564838c86da63330be75c296e056bc0658e994cc12b08f1f1974d4b4259e216a08b42e5eca42f9e0a3eece5451d185ea0ceb435a564cc43c841949f6a4d153124b5ed3d0221a1041de23f9ef0e657ccaa89ac56c8ef194b642c3dd5152c612c4bdfc7b689714e3913ad33b565cb630365579b57cb4370998d7826f0314e706ae0634e16afd595fe2fa82bfd5ba82be54d5db1f1ad36b8b45d4f1b57576a4c59ecf6033a0b5490961a28352efa0334fe028dbf04642f74eeccf5be55936393298f36e63bed0590968320aeefd22bbe59456e9a52f693b7cc292fdfc6bdf43b0c29250371b98c99960dc142de6dac6c39e4f3b3d665ed32c793d01fed0747cdc4e6b0915f1f5991a28e4a0a3a3f50ce9b62133d4b094c3e88ce7b198ccc953076fe24666a816f868c274a8630c5d069693d89723af1e07520afa36cd159b906287696933a2f5b8807217c2bc28b9189df4904aebfb582ba3eab6121891c42fa810acc5a45fa2fc76028629e617980a822617930dab4337f14d9f0a9263230225714c47f252644cd85d422204ef6d8ed069a2a3fbe82ee0f4621425a2234d9439499260565a672cfb9c87f50c97636631706950f64c445fb1f56a5b7b0e98c0074a8eed1e1659591e44a6ac60ab435e0ef66623500f6af2c14b7e899d8d569235bdf055724367c89cae0c5584b2001f1ce9550c1a3852d1c1ad85a02cc62589b887e64dd1e0bf948c4246b6fd6bb0b5282ec34a01734cd6a4fafa508016ccd9ab1220f6398fc20853f88092be3a01769d05aacc4b22376412d485a2a0070187c8b86c80ed99156a7c33ae0dff2e442c5406c6c4e72c72565c031d06b82836120551ac0b98349c04c4e073e3f420748b3bb7c7503dd896dd799a8b9ac1996dd70359a315bea778581223201e3bd4a84c182013c45922af02b3a1f15ed2e7d00c6324acbf6ba60a1a9d32e01cf5543c4c06ccc8237cd3b23625a4c6b44d8e952bbf90219b5361841c0842589d1f9d8a860b43a2ba32e90798ec9f008a6f4f71146252404e0936620f52bc1307421f7225471fd16c83f6d92651f213860237bc1e81be098a36bbb6d18ef05ffdb3e323ae106f097538bcd29e319ffee5a59b791bd9caf8a0972916beacee533814f5a19418ea0bde1cc24900ecc016aceb0434b1ce97b70f48cc74c8a7eeda65f29eb43eeee1e01aaecc717d4059caa563594369b7d0e68b01cb495c6dcd7242f49231228242922639a43b6d7fdf81a993fc08cf59dbe13b18c2b56367adcb7ab7dc5c130b4bdf8a4d9f486e007aee4dd63ac4159015c6a06fb1275361492283487bd9f6fc7a78404c25d8b427a720915544e13602c40bd265eed2285237276528f85897d7837d2c74d9a1395c85fe0fd433a03822311674f8230a43f787606a4aa1268b83e81447a127f3033538344c37d1352b233133212d99c1ccf26db6be4bda00353b60203471cf21f64b8207ca8b1dd55f037d94a3d3454405be9c86fa55f6b6418030336f9327c4a72ea4da8cf8ef79997b754b562ad10fc58920a2a553212244a284c2159c1f1bb8511d930713f0d58b5f9e9ad028d5b24c955ab60fc90c5b940682fc65b13d9c6d9ce1bd9b7aa2f4a64ceca8bf1badd368f48976a2df5193a09a91a28628b89c60ae4dff9c2347be6c80096b821c7a938aa7f4bb291a80a2c060a3ad80e0eac8a507fd3946551b6968c38388c58b4950dfe8cc15ee3c4112c0ebab8d14548b9cdb6c59150194e674b19368f68debb566d1f5b1bd8528a844a70e0a9a1e6bc394121107830ffabedc5c96fa994a04023a95c187bc21883f24c35c20e3b5add428e3a19c0865ba47302081c341c134a03ecf752aae9f94b1c9798bd20cb96be0678a66903a515307ced8c2de48a473dac35d193cc5a015f0343e26b26744eded3fd050d5c2933c7a232549c98970c64c449774af7f3b3d8161e1660184622413e8bf3b0f6887d1a2614a5198e2f52d24edeb888e5343690e5c078e32c9c73910e328784ba07323b46180f0721928a9a9cd2064b444d1394140d4c856d8bea2ac9205914b51632d15a9bb7e5a425b0b2b6a7023f173f7ddb0b1c8e34c135a2fb82481c729bd500a27e3770d6361a37f7262fb702a2b6e3e9a7fff3bd055f172e916da47102a61209360718fc16462820aee31a84c65ee747594a268653f5e1a90c8927b93fe84badf9a0d89d9f4d39149b38a7b25b851e649826d74e84e8d70b0fa34ed04321d963cea4271064422e036151e69e5a573cf168c134c7343c8db3a47102101c10c800d55d09536e3f65ce434d7a7e6c26287ab22ad86a65da83536e508f370d703cec5791ce9584a727cd04ac99a1504a57c70de326c784fbf9918ac43c89a74a29a3fa35aa556b3ef8f9f3b3a9b01047a70898dfc965c0fa01e4b444f32701a3cdc8c7b54065a92722524b6166654ef301faa7aa9c26f923f5fc482a8e320678d4c1940c7db8038ab4ed9cf2a4cb9fd65fc08d94b2d23a214dab010dae93b21d4e8511c1f0592613ee3a26e5085ab2b52732aa90515189af3109413ec1f70af5709c9f41d11975ac344e48aac2daad93a4b32d932313fba76ad27c9e9fab8455d33a757c3f499b3e4d45eea6633af93c80dc076457c362d1523f755ffa273205eca3c609cc0db0ad828940df4fb6e0dcbd35d571e2d664fff9a73f7e9b74ec32eb6f8e91c7badb146b25722817b1ffd0e6e0cd1cce690a38e981e1018e6521ca10ca0b44f2c8d002ccbded5e6c611b39f553844019a6c196c1418056c662de8123d7a2567b50e51fa280b6409cc240c61fb283680860a21039bd89152654f646405e12727c415d0e9a2a494824278c5200262c98893109bae9a56904e09b82c817ccc9134b1af6dd60d0c5242060414b6b73aa17c8a1c91f02ca46817965df4954e823419dd2a6efe4841d68d8a50446ecd63d910ecb5e29440c689d5f7b0e53a3ec41bafad53b82842efa26499cc0c77312f34ed5db49050e566d2b366b0f624955a6be0bf4cd3a523995b2d3a220d5d276e60f39d4dc53392127d6f4a1ad999e065924489f1a50d517920c91ea283b32e9ce1c05782ae01e4072e002267d5557d46df6aef7f3f338796ece363b7163b6215fefe35ffef3a76f039551fb6f0fa0522c1b259b7c078db12d971f6a49fab0409d5b4a6aa7b65b885e79294690e605e28169836d755ba1e58d8b0d6434eb0e0cd64c146a1a0408625658a45468ca7cb5121688a2a1e5e796daabe993770ddbfb4a7e051d8465b0dff62dc79949c13481eaa12088aa51dab4e981c01ffb7a235d30a9580a8948206b197d111d120d48c4b086c59e29d22b138749d16d830660a4b5c4d661ffaa4c4f643a3eb4ba4118ac7a22ac27947e40728299b9150a9a0955779a2600035027d42920a5eb05dd6f62d6541e2557c240d5d41c1f34db8f5707e3ae7c306dfb4e9bcdd202a61acd68f5c9125bcc91d940054e124410729c8460027db3450af987c581f780ebdb46aa2f08f0727130432d1b0427b22aab921b0b9bc5167a4ee585e8954e1b6f2bf6f9393a75f902876a2565b1fdf712e13d8d33e01826ffc31e7bc6f717bdb759756b2ebe9dbd35214fa7ede9e5db2489fd4e44e6ea88cce30e28603b22737744e60e44e6e188cc3429ed88cce382c83c4c2e0ae5de209c184aaba60e44e60e44660edb55f9c1d3e7e7d87228026c341d042556523974f2c14c4f6fa65a095306badf56854aa37fd213b689b64a6e8431a7215c9d627fb9ad577c224ed8dde0fe6d44bc405208b87c3a93be0bcc09a05ee08cc1151d3ce83b2503ae20057ab645ae478680758703a86eb58fc5971f9ada01e0f17e55eaa4ee879dc242b62d050e06360036344fa06f0ebe1aec6ec0509745c85cd825f633932e858671bf576f26a127bdd1624c7abec61465b8d0f07ad03b5f2272928bff89964146e05ee97e799d1d360d2800369d8564f2dd5ea2bdfb74f4ba5a4ba2d757a6c644c62fa42903b35ac384cc245ae12478b39e5c51d9e0c201a25b539ab2069180dbfbd39a73f3e69ce6a9db13fae51fdf9b53ad155023a9299a796e25e55e61c5688859a24aabc232b27cea5dab155b903235d43e531713e1a18c9e322260b73806b8aba02bf552432b29dbdeae9794417198c6240ba562b6c920137ac182d5002b2d6df81fb6731a420cabd531b1fbdaffc04110d1586c8ac34394a521a0a06147da1741b03427d586a8e04934d132f7bf4c4dd652ef7a52e9a1da6bd712baa40e10791025d42c105f654a9235b73e4847651b4499d52b7df9d38f29670158fbac507fa5232b396b33619647016362cb805d82bbbb66490d919333e980eb98f15a45bdd1c4ffbab7ed44972de242a79a55e12fe227bff8a02ba7aed04a920ec4c35eaef9f4e6c792d3aa6bf39bfac9705d0d3fbc8ae4b474829eb88e11f2572aadfed731fafdffa95a8f9cf2da6b5dffd55aeb75adf552eb22a9b6f76a3d6e36f53bb5d6eb5aeba5d665a659bf5269fd0d4ddd350da9e7e73952d67fb6a975a6bac63fd5d4327a5a5550eb3610505c0996a8d777ef3a8f7ed75f69eaaef3554db27f25420152f11d41faf28f5b62f4e7d79fb68f2fbf3c6d7ffede1260e70c2a7d9b3ba82a00d476c4e2926bd0a2f7795b8b9e7decf941811ae68c08db07aa826e053f00160e40ff4c1da930179b7a7ca7155ce00544db7844c10a5b3354bbe3ea77b535bf8419f1d3965f22c6f7f78db1576d7bb34bde4edfe898e34f3ffff2f2d35ffef8f7d337ea98dfaeb48a358ca977279a20cb05610e7b2386f99e9f8ba3a0b4af5f2630cd483d55e0d1c12bc173d1af3e3f023021d48a5b157aedae6e5578abc70ee7c1d2341f96c070607a89fbdcfcaec3d437a1edb37de599cfa4ba41fd3fbf6af855fdfc0c8879db02aa5fd56fd7dff6eca91f6d5bd95e6d8f742f239f9f23f6b1f97e2edb69e7d48e7601bf2f21df9b727df9be9c9fa5da3e2de33efcc1bdca383f2f645cdfeb98d777e14dae1ebadf7d617b71af452e5feba737bf7eea23ac9aa54992fbaaafa590c47b9e9f478e6afaea97f51f0866e8479b2c24cdfeeca7d2610bb76df9d608b00f28fd9ad3646909f1c6b31b93e3e55b07dd0710312faba6caa2c45fd1d16edf86b76fedc39a76ba1d0fb4fe740e90b075129fa838523a62e31740d4a7dbca68ffc7c9634c8bb49d6bb7559aeae524da5602e43fccc0e4639a178079d3c5872bde4ac47530a020640f9e45f8d23536e15148af57c841000e3a10c6ea896849c7b4b64e530712cb3a1f551c3c6c79d079a1d750bd5089fddc93988ac99dd50041c5f44e973153bdaffa4145bde30ae87ed426d77dcd1dc9230db4e6fb8f4a1e697ddadd8f3994345e6beec0601a30d93e980caa79a5f101f3b2020bb54cf0a9a8863a80cc4f62900c6621407a4dc0838d9cc049a76ba5726f577d289a969f6e131bdbd269ebfa7ce082e45a3faba3cd52292de917d35415c097bdd88d3e7be7e71c79afcfdb42655cddee6ab63e16607cab7cf9a367aac6cd4e7c2879ee5f472912adcdcbe793d605c567337f169206f7eb27bc89019b95681d9abcfa1722e2bd25ed6a55bab5a45d9dbeb5a4fdf56f3ffdc7b7d9b3fd1e13cc9ca928f2b9e5a9a6de0ff8c8f61f2478dda21e00f9a98096df0b2fd85323007d2af8d660819fe543cb25e943ad9a463fd4a13fd833863da3a776b87ee08f8f3a67eaed3032e2d1a5a73e0e7e601506920f46ea72a7430e45d36c076d2d553da81eb48c83ea93b483b4bdd2875437463291a31cff7ad43bd592ea4124f5725029878142cea9cdc3dca2d6439ab1ce8300ea45dba14ee015d9aee8606fab768d7d091fe654ab7786a9beebc156c2dad344727885515f51b6cd693d38c178950364653f20cadc1a229679d085d0f24be9c1a4c804b0c587de521f4f1549dbfcbcf44eaa3fe8c28548133d5c37e78f8f5a8a3d6f0e60fa483f38884e27aa04bc7af560bab5576ada3bb1f6858d637a776c19b5afd678d94e2efb85b06b344db9d3a249e5d0aa55c51e4b54873a0fd775f8f1d11b5b6baaf50f3a525d077e3ad084b4834e2c2b07e7049f620d0b43cd14af9b347b98f454d5fba12218abeba1f75411cf5af5806b31240ff6e358f5c0da0201a61c90827f30b1366c4825ad87ebfafdf828ad26ab51b55dc726a9a33de4d0970d0ec40b02e9a11d16d3ecd33cd481ccc166e7264687755f3b4c4d1546a659f06aa3011f0aed7b553e098df12f7c2fcd7891996a3da07736b1717d909514cd5305df631a5a6b4462c73724cea24962b75e8eb3a709f277801c556b76d5b84ad2714082415c23f57950b8120f65d9e0b5b17b557cb0c5ab0246a02c20feaac4c9a1627d76b73798f54e63b39665d5bd6ec81f1f6dcb51d59a04906ce2f313ef847b568ed16957156b76abec412bdabc1c9098fdbfb4ab5d3526aa7d75cb77710028816f4a6e9cb92db4fff7b72284fa3d5c721920922606e50f5a3b123479703af9d69ded937cf9199890171a9419fcc4151fca93da62ba821ff67c43f0943b4feae00793f3344d445acf3f98e6d235f8c13370ba262961d42dda925e90c7819882569021cad840db59029c20336bbed065c658e459a0810d047574dbb02252c0b4c4d2c31ca6e1b6f554104c7da1f3b7964d43cf8f2d17b8f3b25dd26b283b4a6136c10b4eacba0109bac75a10658bd952274c8d75fa1f73073dcb495b689a64ece542e402381c9aa6dc4357b0e1970aee4dd8c233bce40d767d61f2fdb097ed13eca0e5e9d396cd605299fa07add6197b4edadbdbbcaf9e70b0be33c0fff74d2aa11f7e7afedbe91f7ffcfb4fa7ef8ee6a34e7aee4c0bec20fa6ace9561ed3959d29e80dcd8ef4d90970f2ba7422eb2869c0c300582b3aca7823bdd0943c803622448695ee0e5782d45768a2cc4bf028b125e4c3ee8585ba6917f9228abc7fd2a3e808f8f70ae7f5a01f83fcaf9514055555a03e555477642072cf24a83a50ee8423b09bf11beed613f8560501b1428839c773f0fb6413ccabfad6f3fb57d3fdcc91b6f8ca7f6cb533bafccacd2a52e613f05aec1cea7d6cb532b3ff0d4c53ddedb0ffa57207faf46ddadd1fa76f6d6807df9e5e7ef2f700f9bb9ba1e4ac60633e7a49b663a141167470c6f2b2dd2212ed01e207aa04fa460d35d36d3ba1b08df833bc0f440c458e7b45e069deb4886e8084db7f2668b6cc861d85883df4b7203a9e849aaed85c1fe99b1cb3f3ff287a520cc7264e6c7006eb821d60d4593d9eb07c4280cf1670d79c1c9d010f547f05fbb2e02668fc5abafdfef7cf4e0cd8ec7995b9dfecbf17bebf11c8a9e3a3c5eb6988e66ed3721119a0620bc8625299727a93d8d2a613fe65da40ba1ddde2e0d57b7780057c7c9ef8d07f9bd71117fc01f6f3252d65052ae08901d2c36a4e6e7136f8d2b7907d6940688994f979bcf34a6df9dd7f137f8fd56ec71f620c1dda33dc8e414dfe2eaca7875073ca3e889376f616f2fafc4c22f3aea06bf02e8dc912909062d44fd0e165de1448e4f6346b7ae136f808a8e70699ef560bd737e56ad61ad34e6e6a8021dc621c0cdcc81a4db8ed4e389f80f7ed405a7a222697f34f0e5022adece7590ac8e682d120130bd7fd415f79ff11a00d1578411b5d0800f644fab7c32cbe76708cfde37045c2a92c44cf1019c6997b490ced081232a33e01365000df7e91ec3395eeccfc60bf89509fbb7ebf9db15fd5791bf42872eff2c8b297d5df86496df9fc6bf1c6fce619b305f4c60e08f7e6f1a0628b6c424f3c30a324792e3caa99d406e57721a7140d4e696e6f9b12c30dfb5341eb48317504f42d6caca54418902fbd1a3d01229331580106a54bd5f693d2862a7e12ec496558f3aeb294e508dccd41e14e187a59c9f1539632bc983c23c59db3c290cadda258d635c88feae880deceba166608ad61363b089e02e5252b59732d503ec3aaba476029dca6ca93fd89e0c4b8d402db2b73b3feb1cee6a1ac7a82b9f60f49c6a2f80fa413055440ccff295385df4faad418213b786c93f9e7e393d7d77e9c2f6d362db982ddb1664c5a6ceb16f1275bc95ed24081da05c55f0273790475786c87527e318c80941c4a6295cccf5503a023203c7263205913e8bd41cb0a520b28ed136205eeca9bc8000025130c89e585b0e6367ea402e2e227541e45833ede21d21c58849d008fe2d166749e07b6c35225b8311aaeb858caa7521a7050fb6f226b3c1df60bbb90658ba05ccf5e5e585f065b2e30b89209cb1da5319732c8d4cf3681994982b8b4020063993ffb11368a7874656928102b80a5c996d68385257b29d506e642c99aea64e98d93bf25195f7d4d87840ac6046d6abd35e163665f56da707ad23ca6c77c74e1611ab9403e9b8492986a2146a70e45381f72e7ad034797819598cdeb106426ca4f507699004d191157933c2fc98afd0caee13e8e69ce3a99bb3ee6fdf1d0f4e4520a9ae855cbe15a5326d7b7afe7625c12c845a64087946075d7deec4d36055d97f53d3b8934e173779237601a876805f0daab767384aad0493207691bbcb6dee20620c2e267418888a1195c8fc5597b7980d191ef4abcfdd178699e0bfc18f6591a1193685cb73bc247e63a5fb0f70d602c2785baac1415a17037f35f6899c3c81bb13f1c7b04562edb7cd80223a11c50e02b11ee89a768f60260d0fe8d9c1fc0e4fdadc4b6811d83e0af3745152ce47e64f77f80862d5a83b616b738939814180c224f71b48629bbdc2441e4d36c985626be48a15cf42595e6c648af2a96e7b5421254f61499ddd15d4f1364c46e391558f55c3b00fa5dc158403fb33a6e9a4120a9cab15f99f08b2076119c3ed0736c4cdaad906e9751bbac30a5f99a07fbb69a1b1ef6f4ccdd3d3f6e7fba797ef6ef7539181a423334b5291bbe2560089b52356168c1ef592695be2022b13089465c3d2d499f621ce095f98fbf2cfdc10f1b675bcff74267582937c39d55c5428700bc1baa18e487617d9799e7eefed28a6dbf6956b4373f3124e8014c723563b6907610d0f6d309d6432e663e5873143691541b7eb935bafdf7c6baff6c65c7a32719bcc0d15444f2bbcdf45a7bdc14ca144d00082947fffedaec747ec972b07e1b0a89f4645c29b69dda77d6025856acb9a789b257838104cf07ed0d83ec36e4dcafddc3b13f37b9b940b78bf05ad87250b81cf82c8afdcc1b2e2e51f4ca603ef911783501ff9c89f5cc6f2119faff83c3f2bc828f2affce6a55eb023fd7b7ebe42e6d75fa9de0bff885737e7e707d4177effdca3cc99d6dc5891fcde6f7e90b208a58ba0107db76af8bcc765b62fc78b6ebc7778e7372fefbdc13d3eef78566b49abbb9e8c157cf5b45ede69babd067c3b9ef995d60ebfb196476f55d48789beecdbaff6ceafb4f787b17e778dbd468fb6bd147076cdf92b5d117e57a55faf873a026bc8d8f2f55f855f99383ed87f57c5efd1065f155fef89ae5b62eba73f7d7c397e872e4da1cda19534b6586c07088c180076102d663088cb9351fd8bcba9970e04ac8e6f4c211b5b8e05291dfc335e4e90b387be907ffd414cdfcbe18be7999283e7d52f9f079eed954fd13696e5435da81eae05b92eac0395c7fbd153df189b9723d7ce62473bf941ebdc8116906b026da990c9d7b3d331d62554d3e86578ae3d804040b3695b9c826cb91248cd5e42c32fb469688da64becb3da480de8a8095980f6a0d5b105073264202b71d98164b0a0ac04bb95a649f63c72f682d21b2cdee05a0a40d988a295cc9f888a9bd3de9f4cf6250e0d8b84c733c2d0948a67491360a03898906e110e11664342e72fe407cdbb2bcbe6b2dda310e786844aa69d304f2b0e82c274e616332376384815d411fbbda74cdab5181af68c49e24e5358d095f3c350f81f0ba30ea9b0d846b3a374441ef306f52423513888294628d905af68a2f727fb3e7b6fcef8fde48d69ff97a7bf6dc7a75ffeafe35fbf5116e0ef98f9cd3673b52374b98fb2c5965410cc89ac9d91b440c2e6b9621f80cb1fa9c88c9a3230a907225bc680fadb2790e2f300952d315bb585965aefb1a5ae25cc343b31a174f28f534cba464c39b72dae5456232bab66cc2c05c6d96cea7f684f0d76fed252ef1a7aca4c93d50684b736011b3e0b32176a011bc81804b1e8358e8aa40bf0b62d84e95480f0941adb44328fa9cf79c6a1690e819cc89014431045d66b81bb55c1cddd2620e5b4cafe97d85bc1899cd3281d98f6fe0a2ccf944771e39700edd9e38954e34af6ac3472892b09a04df174494ae070458a9b0058bc0f508c67760d494e6ab51959d7b40927edc94492228bc10e0cd298690ee0b6e5beb6be529bb422b4066aeaa5354e4d2b0b4c6caa23ce9656a9298f1a938c9ea4b568cf4a5a464c0d495a430a705047a8a9554cdc5957d0543b212a5a011b25dcf60b3efb391462a503fe203792f02e109a0e69361a3a42fcb24034884efa4520ea5bb601580b00a167c1ea3e94c837a5d90e2c67ec2d6bb371b764859a64c28e8b9c301b770809a9c3ff68292bcc4f49896092117edfa326812bccc65ab1c6e87124c902030ad8f2a7b5684babaf3b6933892ab225ad8e26073320d6aa066d394dedfc6b4bab023220499568b3cca156516c9aa44265b56e68007118932c8936956cec16801f0c4240b430d2a82b0c6b4558b7578373216700f74f1bd28071048eefaa0a6420eb24d3d37b2a3611752265625a9ba73281dc9d3b0c03cd1a2a4f2063c3bb9d6a06be59179b7b75a6dce629655d29cbb65205b87a997cf982b753c15f6d12ae662499d6c8a3822d428110288cc99b03b02f19f2065153a5c59afa02de526b71a45a8086a90df8d2580833736fc348333764df732d56f620e01257aed6bd0d56609378c4539f69d83b58a5bad5a2a752d56420c6b875271cb005a865d2c2003638baa7044e92d053b509672d6137970e33f6b0b56a285e7db6f7fdf3d78bc5ad85e6fafcfb6bcd0ffff5f76fa566fe1ebb55cea1e87d9db6356b34f4b602fbdfccafa5e986c01e804f021200ff1fed04becea142b6dbb958e787898d304054047e60fe7f7e460274919ad6069cd2e9a8e1b016d704f20582860ab1dfc28205d873bd05486d23d2cf018c203b1e23f41d3a2e1490a844c642416092a473a446e4cbd3dd5099245d08ac04330cc03fc4119084c829044ba0479bd523973fe1cfa80651cd2ace60eefc00a1d0043d51a0e23aa0f995089c27404e00ed894064428595b443a0b3a8953093a62735a7a9279a2be1cd66a043a8860aed908aa4204f36f449136c8ec8ea069d2231ed620b05d07bc02c55d4a94647335b9e788e175282efc1fc47828648d0753006452784ae8eaa277b8e3fb67f043b32a9a66e0543f239527188a2885831406f00db0f8e8288b8c519c7487227009e929c915c32c232bd3fa3b031f28a59fadd545921c0570e1dac353300f0a755a4dabb01109024d83da719ec11a6b1a2391730b91b11e4886343505e61e6cc004aafd57501275498bfc64a142afc64a49964611149b4773620bd012f9334fbfeda0e9f23e87740fb627a2869fc2b402f85c8fd9812366eacd680b243c046b38e4d623d9b00a88095d6b644cd1a01bd5f838481376fc469cc5f714d7f22a5be22e578c1fb62ee7bcb1bfdf710a79a46164a99ff23bdfe477afd53d20b763a48af925d7a21b2e47fa4d7b7945e5f915b3724d65ffffe973f6da7bffefddb00e1fd8ef01a21ce73eba99c1a4001230e13c1d49c09c47e4716921d5f2220cc30146d5b5e4fb6b9b77d6741ac4c6fe017d1e097045e06c47680b749c0fdec7b40da549bba7d8b30d0d39f9f34b6d04eb12102ac87c61a3978326277f01fddc7884ec083466c274cc6091cbc19f173d40718f6b171fe9c9f15d2a226d92283541020605730cee584d7959251d53ed2dc008f2c0ed78b770dcd6b94191a83982200f09dec68bf0204bb14d3558b63feb70b307b393f1208ad003d0ce24f1d9559894b8e704a49e5c408950d5205f0b2c1afb07f2f80c5e777f6cb13d06f5be4c11ad72172fdcefb3ff894605d5f6fcf6fd7cf3f01df16e868287438b8dc0ae7bd01be8d172593416053b7d320dc7e452811cc996f95a85e81e995681ec9403281ec93be3a247579a88e8de063949dc14ad0fa59bc73840664a05a737529491055d829a4178233361213f82322af2b5e116567904ca97b3d40ac77c2e4181989d9181339b0bf46f04becdf4ba1f40a052146fd847c00001c5973643404903e014de6579d9fb5a2751048869e42fb4cb738abb71b2255936268edf8ca148d44c926fa11c819e68948ffa3ef4dc5de05e4fed808a1873567a60e8cd899fa0b211709b235533f15a22e292a2a833d5963898a295681afa5e76747976de0786716e85bedd1eb2f564584d381f170f3c1beb7ef720a89718aec5e8804e939cd971cbc877b4bfd15e18092067ec69150fd15c15c807f8211cb294bc9c339028c47b603a923a87070d54ffd442a106a246c0bd33814d8c8c55f696006a365e0167739aad636bb3c99819d648bb8b83ca919016e951cf61cdd9845edeadfae00607660fd6e699ec01f817839bbc9462dc7ea339cde01ffcecf05bdcdfa22580794b068044616f14a1b8836222125158898855908dd81cd18225888785002d03efd3e03d15c15c795f455e956092df8c0c1bf95f48848dcadf295069ab3f13866b226ae8e77a888f88d4027b0928da7654a4b47620f510901d2082dce16f97d7817761772d43a47b5622edae5c3f501dc20b872892310422819380971237472751d74b86e49bf0781c7913ec4d0471731c8b9b1510b106644a21472442c7671bf8cc6fddfae15550c71bc66021249b45f71bed4c645d885042827f77fe767e54bd70d4fcd4e5b2238f6b41e547799e975a99bd78b7559fbbf979d0d838199eb040ce0becb9c2af4e7d945d12fb17fef2a48175de7968a7439795349fa79fbf8cbcf1fbf3fcb1572103423bd0d4a2a02853597fddf1dbf46e4b9e9c4f07f49d0aca9ffc13e670f7e706ea90e1bd8eaaf92258d277144dc0b55e6fef771f5546f9e068cc687b27a923f682ee453293ba27b0e975adb4c1aa60e9b12b280710d40e2b722f63f84d7e3df4bbc90bfd2cdde5bb7bbd94fdee8e6bf7d7cfaf3d3dfbeb73eee35942569cc3bf80c24945c525b7102f0b96a9839752490f4fac264800134a844682fad6168b013a5030abce2a490826880b5770e243f16b05d00b5567b9c485e2d769fa8ada425a1b4582a48d8fa20ec634945a28ad86a8ca4979c66df800610679a0beeef0e76cb0e9ae1917a6c60634e4b003dde03fcb8265247983912a9b68047d2e41e42c3ac56488229306d3b2904987b14d4bfb37bb55301b8a22219b492f9436201bf0722624b44da0d284d41fc3f80595153d753acccdc954dc11aac233472810008b02eb86f607a00f85eb049606f13d6404abd04501ce19960912d20a154e470b50ec23df404e98449fd575b9c35d502577f03444149da4221fbd6004a650182404fb5789ea9bd6d28cbaa262395f1ee84e0b8be351b78e69da9f0f1e7ffdfc76f14cff67bf273a460c8ac7e2f393f49ce3031789a77d49c8f5234cdfa645d79391166be475858279bbd1d1bcfd77c14bba97e7eb3a039dfd7fce98de2cc471956874d41f484ceb061944dfdcde7475d3354e94fa2195390874b7a9f88dda2d7d4da932c24b4af0b831b98757ad4fc4156fff274dc4fdf2b06de53cf3669f8e92984a860e96941b9811b6fc007575a9aeae5995fa5e72d83db6642cb119b7bfbd9af8e250e8cf7c613cfde1a537ffde59b81ddfc1b6ca3e9621d25d236eda3e9a685345ddb4811d671b192e66cda4f878f87aa61875eee9471a631754db065f62805ac7c0a2023a08b37aa6a71812305c91dc027c6e613e6bc416c710a19f00030af8b80e3e47fe86986293bc586408f04e79b1684ab2b12c10aac610856c1d1ae7889831c35d5ef077e10f57d6a4720868d316c81c07c57a25333b458ac66cdb620b000c3fe0a2c7e5887a1b5d64fdf0bd0c2990c12935659b0e4d51718d00659f8e83bdf944aefb4bd3e2cb91d5297a5cee409216432f2dc06228761a8063707f87544fcb8687604d8b19b18298c513a3f17b1254bdfdeb8b217154a29e88dc8a71f654d829e8fa8802a47801176e8b0722b0db5fec62539376f61a0114a0028cb7c937901781e6e5abd908014c0607bcfc860f2848651a079018011385ab9a51aaaef4542255fd92290336ba244d326187ad8ebc09c92f7273f66f0cd898f3337263d3c252f7f7bdabec3e0c24ec6a2924a85c6d2827db0449e4d64b92c8018f2a47fbfa7d5ae1af243191394632a4c6050a405e802e2def0725f50b15faeced836cbbe7dd055d26aa156cf805050c0f96518a94570a9a65c4f29d7987285a0d2066c5fad1bf41bd7725836f55d90354715e4ea0a9e6bfb1f381ff209116b405685d5446b0569764682c1a5694841ca2220952fbfc40f05c90897778857ef10fd1dda091a58626055affcb0db8eb7db6a4c594e20b7cdf2d63db81891c23a2312dcad0aa7943565ddded87f47f0f7f73ff67714527bd9e7f6d6db6fef95b2f0ad603592b49669d6a59cf86ed15f71af89d7c9470b7e596fbd1352e39784fc20a550a5cdb642a3a9e65553815a9329fc6d6f808816781b59a0d62a82eb6d2c78c6ffc94a2997079589e4fe9ee6dade7ee14f8090f327580bda23acf11e745a67625ad8defdd294cbcbfb80da1bd3c43b2fe0a9b2ff61a74bca727e8e683bf041a0c9d05ae8bcc1a2b70abb45d8ba6bbbaa7278abb2a3155895bdbbdf9d9605b14b5ff6ae7751f9723294cf26c3c3b42d48b035acd5cf865fbb0c3fe1d38ef6b2ef09cd3709784b70be9dbd213c7f79dafefcffff3fdbf1e92ffff9dd991e10445c8aa672aca269bcaa6ee09504d44c091d163c3b1ea3ac076df665137d4580ecfd2c5b04005487b9d2164294fa7c8daa1e6cdffdd671b67b7bdeeb6c7646f24af5c6a9c7d25bc8f7b3dc5564c9a286990be94088f18795f9bb0ff6d75d655e6046de270295ed06eff6e47577dceacbebf3eff4e6fffdfaf1e7ff38fdf57f7f6fb4538af4c522f2b05ad06edae004734a5e2759f0ffcaf9b9499ce341e64c0a0add93cdaa660d3811a5df800063a21339a236951e0468a532d6894c48a5a78615cffac6764b5d010652342817b502c37a0945a39aee991193358fb6b77bb57b1e356780290fdbd555ebcea2f9182b3635c7d2566afb375fedccbd37deebccfdfc3b9d69cdf9bd4d4be0e9052d9a08efdf4c3bef0882443649a92c1fb19594d75825d571c41f9b0ca09a055e67ba7d0f97dfac797e2472cb6badf33e7f287a7e9446221fe66f211eb8328ada046d03fae5007bdb8412df86ed01242a54ffc5c24cbdbc20a6c3c33585e54d40bf0a32d9b14c2f6e5e94994a3b969cc629c98aa98d8dca7bc3de287710e935db87887ad9345bdb6b344d8d9c26cdcb6552d783f2bf6878f1a56790120c4c3e0a070529a825ec1ce50b780a0c876dce1a0a8ba892186f78194125480dc2b2245eb23b00f97f9e6292995adf2250e00474d43315d0eda9daa6a7172feb4a6bba39013ba1d6bc8c77393f032562c6d6522fccba42ac73456665edb1955495e523e0eee6ab9499641e8b2619c87c2add874501b01d62222bb1175ab8dca0f4f3a3ae61aa70d1f650ec85674f631e4907fba0f636da6c6bdc81e36355d4fd6c51ab835d70b4977a1f3a7e9f70efcd554e891bf3f41fa79ffef2e78fdf26bea1fef6f886321589b09ada0925c05fe4287da482002bfce34e7278ca4b7b10a26e0fa17501e09dd8330e78100180dd27f9d0cb46074f23543b4069426a2784dd6c15ae65b0d3d758fcd4acc1149fcb0fed82159992a227608302bfd1a381c86d05a776057ff643c726b2cf9b6f6033f501b7cd9aeaf51b0c7f03c5831e5424349ba22f036ea94926ad344fb226585ed65651fb4ac30183b7f4fc0c76b059527d506608a7b64506e1689cb1edec4392e4013bf4ded2b8aec9fca42627f03156b86f073ebb6dd298dad49c9d1e0d9b4aaa2720b397695d55229c7923f68d1e6a0585f204fd305b93dc7b959e32e7c0ced1c3db3426db27d99ef252bb2f5a5bb2c9c24cc75ff7269708802220b6253d2db84525b5eb1e2f11095a2bb593802340daba7aabfd9d24b5536d0906c279f9fd676dfefe8cf5a9777bcafac95b73f6e3d3f3f719292e20a22cada7b67982588b128b0714c297504f91f4579a7413cfc903c52518fd4b4f6e8f51a4cca987a8014d72f0633f4d7f850d313c0c3c72c04d002ffb88dd7f86dc951e81039519d0877c3f028d9d743a74e5063eac9108326ad3bac20ab9523dff4a14bc8d9271020c77a813fce51118249d98cc02e414a4fa9c1aa85b73d2d7484a01706415db75ce911a5c5528bd4cc44998ca87d2446a213874894a346d2ecee5a74e712c50716ee23b4fe21df4c97081c11261dd62c37904215437cf3de4506c57f9a1967f5f4cff5a002260800583601a4c789d611ac8df2a2f6828e655eedf111108e6589480b5b8ff09c83c7e777ee694ef9b3256a016424f74961cf6462bd58f1e091cb39f8afc15be08fbf9b523d2e024484e8984b39f7a7f5a5f66e7cd797d39fbdec4fec7f31fff7afade267659b691610811382291d9d90260efecb3b08d3b12ef4ac4f72f5ee4555be164311d76240df8fefc6c2a66b2d1d64b6c045f9b40281a2c3fa8e99b43104a122ae83e5a183d0164d84bf82e1319148c7ab3c48ee1dce607353df561c1a7bef2868cdf45460be8862534a058b5d310183ba02c93925e084f03e37865e9ae2c7a83ab7dd9781c238df3a3e6124af75cd6e1cc78ca9bf90701795700ef104299da494933ba61b3087e8f62128889d4989c2433b2c5b9a0e620dc433224cf45d2b621f21a187c908fe2d9be83904420e26c6d2fedf1c488e7339977a9a4ed2949fbd790985bd519a96d8abe7d60e9cf11941ba5f2dbb6131d57e5230abf783b5519398c3b80fbfc72c3afcf284c8b776714cebe33a3be378f9afd545bdf729032e02dd3dd5b06ae670e7f48ac6cd20810b55a56344da69ec004626bc2867024656838047f0dc8ea460903258721cce1ae61d83819054aac75744e4a065021b3eee4928212106000530a242a64a42f53bcacf48262e0f7c0b269af92f441067090c7ce374da625c2d7551a3f923ce4a0a527b9c390968cec0401141450d47b98a14ca89968639115bcc16c376d8b989d2ec0b08112d19f6ce942d6e5d881bf1940633a993a441e38e02702dbfb625204b3d411ae6f828a487fc593d73daddd39b2998e48df56e3da3540590f3aedd44fe0df91b2010f6b12ad4743c9243de45639329ddf9a45707ea7883f3fc3614e00e10d20b1264ac1dc33793469f4c23f4ab87c83124847edd8812536d262e9f21d97c766cba3636a00ff4878042f362139a282247fc6cb8917420cf27b50a0cd0d98074c8810b26a5fce7d7506bf37776fcdda9fb63f7ffcf9f1efa76fe4141bbf79ee36405ac85aa9dbb6a9a4b24776217b51e318b65d819557319884808c8554f10bb40d1dfb904ec073c0529137662211a33329065eede6f1ed10ea44ca5aec1e00ea7617f4e0820036a28db28e80d9199ae7ab443833f18b82c73504000fe6213546ef5e0acc3382463ec1550b5e7b84fb727821de3b0ee05920af1b5b258d136189362be608345633ba372a23fd0bd63710ab577b2381a5ba233e55e07b5d3832c73c0a0385344af3441100cd218b07094fcec38f05d1331660456ac41d462835f6f901f45c8b31b7b4760f324a412c21b3213b4007f47904364fa6b590ec3e42d525d63217d61c04994a98ee3bdd310a042cb5958e94f901fccb8b61e5b67b14267f499011443d0cbe39333e40c792351543616d7f6f7b9de5a1b13a82f5cef21c326439d9e5dc3d994e1d1cfb0f34c59ec3c4dc072607d83eb507a1eed09cf60706881291f585bc798c118905e3173b04848c3bfc070311bcc4d1faf65525ba8ac40ef160e70617ad160159531677389375816a09150cf80e710484c7a3cb822a192c204ceb7066b205df3f7823342ad319184e5fec9d6d4078e451dc73e290bfc266234d3998916137b046e1e4ac48ca833d4821b2d5b4fdca6e098a015212f38da0bda1cb409e0c06dc40b0ec48abd2e4b8f59874c529fcc8f4468c0778603aaa62c31919199d830c3b56246f202e44b823b51d646406168025909961355632d36394677b965b97d879b89c69148299670b98262470616446f1f87ac016db6c05d988104a17ddda3243471ab274b09a4e464233912d01606385052c18a46bf12e0090ac7889e984e0952b8ae3a5233e67044f401c761912cd2672d6487e072200cc98ca04b1495d592625e074bc3c1be88158cc1cfc56a146339edaf0c0fb149f13d64e981a23daaf34ee098dfc6be113a14119529d71df04206afa9560eab735ece6c277397b6bf9fbf9e9f5e97bf38009b6dbf90136d9e35c494f1d1b28e920dfcb985d7a9ce03b1760adead21337d3d3bab6c2c037931e631fa99f1cf15b09d8dba2ea57dc51d626375bd24edc6cc49ffef6f187efaf1589765999db86c4ca49ae5190e8572f016acb16280cd512a4223ba6a7f1414d7b56604351cb15c6e365da2b00366b2d1a68b71444ac83a1a50de872301783e19665cd70bd5058faec3405a312b76b39e36834655d29eea5d984adcd347f538f9fcaea29afe0070fd56c3dc0cf2630ab918f039b7c16409d0de0ff8c9c6487bb46c9dee62b730b7d7b7b34d899f786c37797c3d94d40d534304b0a32724d98557a27810b8c1d05ce5680cd73342447c0a34643e2cfb440db3837e876a67d96e2621025c0857e5095a3fdf51acb4813348e033cdc126cbb77425a929424f72ae5d5fa488fb5a6f2414b4965c3dd98104d525400fe72dd794574fb165d7d40c28b3dc5f4a724e7e7a58028438a26f095537b2d60dc7565f7fc4894649db03b6081c0dad6835b6d46105a91b0b374846588ff0a57ed04e7d180aea20c9a44a239020d3da022db949b76241f2ceca9a10fd2bf7a09bb27000a31e093f8f27eac4c752c9ec0552775797dad79c35a31d82a4a07084832e80a711a2225f2dc64a93265ab01976ed02a5959ea6429ae3618043283c9f21aa729e148ee9bc8cfebc3d95b599ab02cd3408d008e311108991a4bea20d5031aeea44dd9a430c61018c8905864fd489c028493624b00b34f81b528211aac01f9f7389136a55113c32653672ce662a01330f8a7893d68c00e4da058896106c8d4d9144a1573f26c945564e92973196ddb35e82966b21a6c5313ce9a13436ee5bef4f2aab9a66923abc6057c7eeb6c984c2a731ddd2c5084ca144ac09ccfff2f79efda1b49726669fe15fb016906bb5f3e0a0416fcc0046657dbd9d8fe46b97286b51d2c9594127b86bf7ef13ec73c98350aa6a6bb267712185425c323dcc3c3dddc2eefe5bce7403c6c1dc1b6c60a04aab7dc5eb10f286d6b6cd9b5611629c09d94c5a60abec84e587e867af166adf5c33a3a7e06d51f3c85531e382b6e5165d0b05553c0682db2da162e853f7721f2aa62b212860dd2fe294d1baf0caf6fcf9eef4e9eb7e6cebffdf1a73fbdfcf4f3e35f7efad140aa75825f32a7e282ff375ff2bc6c2ec7aa54d0b41e5f7d43c26ce8b99132a22fc369d83c066366aaa95f48a64af686dac912fa91f72a1ba041e4e5d26d8a03c5bde8ab5dec142cd418ba364bfaae526468d2fd50a1ecc2c2cc57bcf19c01e801308669bd0dd3957af8ea9334a78ba842f266ea1836729a7d38373745f3a9776f5d7181a3b459673a255d2eb9611ea3bb56ccdc2af3a10ceb7ac56582c1bd5e50bd28c8b2c20331437a48e462e245a4f829e787921035cb173bfd4217dfba3101a4a42196595e1e6aa33a2d5d8887c16d9de449670f799b3cde2ce18db11d486b981dbecedfb403de3ae6cdfefcb6fb66af7efec3e5f3df7ef9d3cf773ffde5f84ea1a6df5278d13a8517cb4db427b7e8e43f26a57953ac441c5a65df4bb5103087ecba8111e64b8a1ded936af394c2f160f7ebb955c52d601f6c3d80baf7bf9807d79eda08e5a5362aea53749b9de4fae74b52518248e3f8e54f66fe91f68c3b6f60638bdccd3813a52ebaade7264cff702387fe920bc5ba552b72da1cf3d1ac19f3c80e6c847e92bd10764034a5bf3ea74ee143b6b14c6c061d6ba8e0cefbadbadffcd5fde6ebfde64fb9974bbe9609942d76925eea60a925f2eb20e439efbefffdddf7175f278d767869072daf386a3d5fbfd1dd7fdd636ff7f95f1ff3cd8effa3cde62d527bd1fb4b57557acf5ab80b811e25e0eade96b0873eb2d96afaf39864a6a83915171250a983fd2296f8a99429b14a226fca706f5c41fb7d4dc395964173daaa3a5ffcc84f53164cce22f0b979da3430586d0ad68771ed8263dbeaf17aa95883796fe251bda49e4f05cde57551c35fc10ebf9fdd154a576ca3d8229f7bbf8f34d15d746541b70c46978c6426e6388f9e54c272b64fbbb621c2f88381ef774bbcfd1e5b5f440891df30172fe697fe0ff4cc6ff7c91bbdf16fbf7cfecb2f7ffab7cf7ff93e0256bf519eb2e4c34fd6dd84d8e47439fbdca22bc52f20500db85571b3a31001de08968146b47b22cad2c83ea12ab9350a8f093c6ceb44fa6c8be3426adcad44f09b5839745a38ec1dd8d54009d57a1948ad4904bd893b5b67d755bf3e639d0274dd1c0c63317b537e903d8a54304a630f895d27815119093e05f35092dbfbb3cd8e0507dd6c10db22f9be36134952563e41e9905c6aefe3fddf1ef8adbef2b6f7665ff9e53badd3bf51e72cf70c30a26b51585286f35969cfbd2d92247c455b1412a1fa1186c4599aa48b30b168db88044233bb75edcd94457996771560124d4f4b7070b81e95945b2481dbb9b5f0212ba66e1e61d9c2c3f4c8fc33396be1178a5779e050a9600b7d57bc0929d44e2d74c88fad9fd4b0ee388959818572419cdd883a9badc7664c1687a89779fe6e2d319c1773208bc0424d8821738d12f422afcf3d2a5fb0be288a5b945255a6e948bac08c6d9cb69728a3dffc425f092835657433f033f25f1592a7251c282863d7b66018642e5d1b3df49712d6132ebdadde08ae6baaaf38b1028fb1b563c379fbf84a17234db6cbd0cd9e21195db555a4ef86f89a62d84909376d89be284701dad2dbd6458e6244e6e2ea4bbc808fd41d2852719a597b6b17908ac3a8f973f778f1ad86f64418e2a559e74dc022b7b80f85fc3be64e6c17d40f09735e6dc78b6f3ac1787d26693d5ba84f9c10889f6db623f59d90bf267868a3f4658b3c0eb9b4da7ab287955e506034fb74e4d7678a796be19ce9c9dca563eaa9892a716803bdb908813c1eb626345e9fc009bc3eb7e16af92e1738fe9d17f8cee509cb61168a4888ea35b938437e2a23f4a329ca4b9885dd7e02242c4fd08abc084c054312c90d24d1427fa28ce064e922c7e4f7ee1733a5f2a10471266696cf7ff735ee9bb5f38aa38b71e2f6795fecbbafcf5dda1037affbbea575689cfd472edb2cc1db976d5ef853a62fdb25ded7497194f5c1f5ced536bb9c5ced0bd71b6e5fdf3068fffef67cbbf99fcfc8ee0efbfa7ab2ddde3628af4af695f1822aa98d832670f4cbb09e109a1d392e59e48b4f29948b5001e345ef9bcd2fe9c91314cdcc4789e869d3a7ef3b03ac85b757d05f6e9afd7ffbf2c32d9d75a410273cdcbd7ff14a86000ccf50472de59fab80ba6696b42d0aaf0a7a194a592caa3ee7626656d945ead69347113225f94510399acd3c5c1ec353db1c87333bbf85d81f1395efe94af31360841807e1c64c82b89bdfd8ddd87a7e557ff09a217bed6ec51d91d1020424b29c0197b9a95bbb84bb9a16dc40dd2f549cd4009005404d2f17c169810093afb1693d9bf381d261259292437faccbd5b7b40bf463e360ba5768b428c75edef41db59e2505aee75eca0ac9f1b5b104790bf55beb23cf9f01cfa7ec53fd54523f846cdee88f34055044c44cd9a58010d39043cfb2d85bd804abc88b083066df5e247e48d1f64d544b1e82c0ec1c7e4da59133d3e9a4fc4268491cc2584379325f9adc877cff29c640da6a6c92cb2ec8239401b60c634edbaefbdae3217e5dbaa072d75357bbccda9e64c781b90ace3e25ef5b158f362b9e2b21f5315c8a64fce7a6f415552a21ffa1a863dae8a0a229f1fa3a5932f2966a6942892d8c31b036668f77f5aeea2751e909f7ad27562c4556d51dce13208dd83ada9d0d963351a986e9810a2188e30af6c82ea4a953c11560664321febeecfe87e429536ec2b826294536f073f6ffe252888c93801c39ccc73242ab4e7fc5130362c7bc8cc3cc099704d99908625a17af421281ee3941ea1528093e5186674e041a2d94c7dc431673c738b96908990e41f0d3da7fc50023e83f45fcd41e4cf246edd4d0ad57e9dc16fa97b4d5137bdd36f137e6e42fb767e42fb7e6e37ffbe93f7f2722ecdfe6f2a6d6433493b78686a0855f5eb88c961f93d9f9c9ed97dd9aa129d996cdbaefe75fed5cc11ce6f9bb556da6d75fcd5365d5306d0a7d5c2ba4e1f4779f12404b766935feed4f57a8c037a08eb18b4bd92e2e0d5d9d0ff93e655177d97e01ade3d45e8daf16e230b7057e8711ca08793ca69102bcca49eaf0fc18ec5e3994cc588efd7cd9bb53c8e4c7feec0b5a12a136dfc34cae84941f570dbd3bfdddcc443314cac40a1ca573ba84447de836f6f234f7a4b8f6bb057d93feee093d9b619d86b5536d4e7fdf5ad7c18f70f3b15498c1ccdf332f9d069bce9e2619d9965fd25a619623b29707e4ce9d89671d75eeeb43b367edaecf7abb73dab5afc59e74494e7f37a953b1275bfbe40e78d2f5a463cad050a65f3f697e015acf75d4d06ca95ececeb11fe47dc925ac74e821db1dc5e9ce2ec075b7e5f6cbdb0901fca0afddc6fe7b5e833564b22bcfd9e9ef66e22bddd5dcc3a493fedded7a9abe5271ab976b2b2d8d8883fa5abb85617d51c3287d4a23d34b43344baf3436e03f62a387d85e9f4146d97a9f0e9f2350e3e2dba0587685ccf259928a68cd40ceceba539d2efb4691eec5879a436e87f92ccde5449a0a55b32696cad97c28f377b9547827f4a209ba363838527ecc25067244bc9c83d71e0725c347ebd44193064a9abc6dbd2ae6724b3fba4192d27db29bab29c4859a7bb6673542b4d61b276e44caeb78d8eb4024bc2a88391027cdf01eda3415abb56dcba10d5b9feb3223612e9fac6f54e8f2cc3e4961b04e8f05415d768846587789f4925fbdcb1a976dc2503d9beb6114571f531ea156b75f76df0809f86d1d87194090e89762669cdd68b149d196c584ec7bbe2b79859e00f28ce6ca68e80b954ab55c85b4b0e6c3f33361d812da24fc6e9f34c03533b4ec80d1e51962756bee87908aadf5df50a7b1b5e6d6ca649fdf589afedbf37ffed3cfdf8789ecb730dbfdcf4888412f636e7781b724a55029b857a2d726717338a5f53bbcd8691264fe5208a866c8512b6e6327635883a34ddda67f2ce2397c0f5dd486d69df2426061b946fe602e5536515b57e146a6ecb1376f83b8b690ec52acab673fc280d0169b64c0248d55d4baaba467c158c10083123bee933250827453713393477a1bffc9e699eedaa2d87c86d25c4a8dc40650b1917d5ea29154895d59765f83615163c8926962f2a80a5d256fae0846c0ac3eb4ee05d3ac00433282ca05445043956e2ecf20b0e9851a4e8e9ed315c81122b46b2948d0ae9bf71ea91e112f41cde72d96ea9b2d01398734fd72b9fa4c9c2a57dfaaada095d935e93667488bbc3638f921418ee22700cf852f36a80589e8a0b7465a49862e75fd3d797115d892e4432fd4522637e0efb4b64ed1c3a393114d00dc3b2e7613c5a57a24ae368db00a5ad329cc21f5f41643b7693ba2beb8a8721b108d2e731ba72a52ab2fe06a84ca1d663f37643cca049c9bddb055de4c201c431d3d28c4ea9bfb4e3321d8e2057b3802182c9f58464d8210836ea3c8aa6bc927b35e2a2b4db58ed3b693849b90a94b9b54c954493d9a23e8bb4dcb2e87450ea18fbb1cadfdc816d84a614e7cb5c9dfe52e56b6bc8e3230e86c558851045bed54ebaa7a676b58b311678d5fab19f689f9bb42818aa49aad8023f4e52b93244b725af0a1da84f9ee54a9b9efd664a93d7f3f5dfedf9f1f9fbffcf2f9f1c7a302051b576a0f631d78aaa224f405f856b5596908a2949654600896276067be76090c989367037c106fa95dbaa8c33795e6c2b251a5a23e54e0205ec4b67db0acdad92afe9a8016aaa0d75942b0300e2e9581ef1838606e8a3bcaeb738e4065e6a3783eaee61905551025107b406567602b348f85e512f9055b80371c1cb81050b684687adf1728279e6aefa2508f9f8dda0145e16b40ddbe2fc54c4a0ee9f5b967a24f55f20813a41721024531e4712c58111bb04ac9f4d7dfe59cb1b7f4729a9a84df63918040daec100a0b644f9d81573581fd98870db3fe9f05198ea2c9726cfd9f680e52549aa3280856083b45d08dd54b0306c9ac9020b708cd15579dd21fd927b742b96bd281a1bec61607ec672a0ed3ea870781a9e841a725c92d906b245de428ffcf2888d787e872af21af17eb7047142b524659d766183088104210afa05ea3800c22286feb572340b29a0a274045cdbb95776a6961bf16d75ca150aa37a62ce8fdedc62bb2b28959621077328bfdd84856ebc6aa6b9f02d70ee943a85287ee9d95d5691b2b89d64ef6452c1a004e92131cd28117041bd8883b9614da512480336de92d4a1351ea0e6a200b4f0d7fbb0a0ea88ff1647920bab1fdaed111f30627be37895d67a41bd3d875dfad89ecf2f9bffce5f1f93f5d1e7ffee1a8256aed2ad9ea17aa075c495358e7a4b982801ced04ff79821021c5e2870d3ba6803af40da46d19d8ee9a6363eb22041a52424b90df1cda3145cdaa787352d9290bcb0362e52ecf2a04676e4890e42c3a7f254d33a80fcd1ae3a102ef84d53ff1f485b76f92d799304bbc5f0bfdab4774f3e97eb5fffd27fcc361ddfea708b011344f7d8575c17e726981082f278f2b5cbf7a2cc08ddbc577489a860a971408dcd2354866742567d1f290c803a54e82eac412e6d1b6448a1ef85046e9e253cd6e2ec194447a75a8c0ae6e6a5e310f10705e615c32ebeeda9c28c90b2eea76bd6216e7ee3fe814dfe80fb7bac2cfc7e79ffffacf9f7ffac39f7eb42a19900275b5308f24bee10531be0df40c7bb0cdb87725b9d2679866760c971b6903f39f67038b4dc01ec63204d730b2b5b5c5c4c148a039cb5653dd64dd70295456286a35974c042a4344d55c55a7521090ea1c21bf7e4c2bbb90ee7a0fe99ad36749aa924eb75ed7a8d86ea092cd61b1d38fe8323e0399625b4817958ad3d9196de31804a7d9bbcc68aa7b33ed8a8275bdd6d4408b6fc17812364b55aca49e08cf0049861a4665b762368eb614f1622b7db92b0d361c88266675acfa7683ef77c3b71e75b32bbeedbed11d9f3eff5f9ffff8ff7cfeeb0f0831372fd165b3802fac1423887057b27efc29f27a20f2bb0c093fe603b322edb27c3481c4cea1c9c86698eeb35249f63a44f87dc256f349e6d1c27a4c59e68804917612a390a63cbc6aadab2f4eea4e00c986404762b4c30ff4a386e9ca25b4d01e6dc2296605f1a2530a6c5e027af2cdcfabc4ffe6e3d39f0b50261aa15116dcce7aed807843defcdb94fca9e676aa741b36f052e098955d4d918badcf6ba820635e128582f921cdece281d23b243cbe4034b654d55437c304392ae57cc5fbedf3782c848cf557772667a41cc589f9611170e00d867b925814421b55e64276f1c997302e45022e8f694115b95f745e8c920ea95582a4ad5ec5cd063ef6d07a82d7a0f2fd73f8b5301f4142ab022f5d130f944593ff4e66495296422d778d5b4be65254bb0c20e8a0c6db6ff1bdb4a9d006867c55fd03f458a598f74317ceac808794b476213414192a4269a432a19582353e359be4f09a6a74abbb1e379975db9b79632d320c56858d8ce1de4f3951bb2eebae437d286d559c4cddfbefd24cc18c28bd6c8f68d9436b8fe6d5916a1ff5eca74a5697d78f654d8a47f3c58bab6a1d825deea55e8ba7d6fb6147e1d882840bd5b7501f9996abdb2f8a40e7e1e2b1c55629e4b231e52a4a776a7ac448f749dddaa9f94bda83b5f55060e12ff38c69abfc2e1f8d5af2098ab3f24d1b075ba32f0925a47dd65f2f7573861d724aea268ec8bb78e4ac2f825b21c1c15f711d02a51ce6481c9a28a60610fda855aa3ea5390b9f89c8885067859f844e84085c587e5fd493fdea632723a6bfa713ae02f08b68fcea312958c7a9c71de4572555e8a919ab9b63657320c9fc96945755ca5b9d1b69d3d7670f5b8035d391b74c1c4e5ddb83570f415a78d551c0af1e8d105f03c0807d5d7c7143b5ef5b328e6230c51b0675031dea972eea97ae69bb245bdc5722689c2ed873611c49eebd4a59a88da3a62f5f4ec9d984c67f8167a66e101f4751b168861e2bc3aef022868a407da3548d2345f6eb1304b5989155b28e09a5c374da934b4d0ec8d4cfad8c0753c1d04bf6bb885fbccfbbf868d9791e5b0ea539fd3dc12f0848821f193ce0d20424692eafc79ac35c4e7f77864f5591e590ceeb955b4790c615ea97736d5333a5501ec9364db75fce81bdfbbdd70c9af4e0c6a99679675e59157623a7ea4a65019b7850979c6c241d7a9eea59e354eead1b9569736e12e36f3aa771e484accdd6c5d3525e8a98f9d17aa646da99714dd5998367cd9b5929a81db3e9f7724a13f2371fd9318a90ab0d99fda279a03beeaac174a2b3e11d725bbbcd1ae9d20085d427bb0e111aae7026e7c457db427ef1d04001ee7162da6526ef1b6a58f175f9ec3131a3ebef3e4ddc05b547bab275a2b4910180465b422b939548162826ddf5bc0dc2ddc75493f87c93a891ad358b066f8e2b9821ab973d0f7657fb057a9323ed72f2a1653df51d58e95bb954321cccb1e43709a61f9a3b08646eb6c16426054f1ad01613e8791749b7c2e8a95bd692794706c8446d9b32624167593af6ed66e8931196ce1b9d3837dd4aa61f98bd3344508357d0431e0acc5b7364f315f3459d710fd7b91931db69e4959309f12155bbdd7678281a55e227830445d6d332dc938f605c5586cf1464ecc42fef595d2aade91af7356be1c23a9c87d4afdb01eb02558736299f486bb313fbeb7316b35b89879943cbe5a61a4a2d9d4b65a95985378104c49211dc81addbcf95b82d5491aa1481ab78702a323463266dac5b52938cd00f45db92ba23d4cdc375b39a8660f0513838eb3e8ba2316f2614755ae51130fe70fb65e7ab8944d7308fb2d7d9b17578150532d32075c9e8acbd9aac4df2d21746acb46c587561ebaa514469192a35bf995ad22efabe6e3c4ed8a1e7e688be0ebbdc433f3cac6e66020f91a3768f87393763d086f12796b942f714ddfb891476945b761e0f51edb423f07d6b9166f1fb336390b5d7322d15df12fab19cb9a1a7e44d9176b27a6893e84df34b4ca28dc70bd90d415e9bcd85494c6d2f8b7997a156c53106834e244b254bd4d40c02bce2c57837ab193da194945342975a0448c5264289e9b793f4a9c244080c13e664900dd6bd0013124599944a475b46b4aaa7d3fc54dd9657d1bbecde1af293e7f94be15dc43d85e7e3d3da8c578860935072791dd4bd4b48df971c10ae9b982917747a336b874d44d68b79d1f4a7eeb2a99d45b92c1a271942d5e60b1e4fad2a2086fe5443eea0ca87807d4a655720c0d931cb6e328a6f090f63e042474771d066ca8500a42529c826e0b5e20f92f7c3905481cf96bf2d45b0b861568cad203ba87f82f834311f7c1f336bba9dbed94c57d26b1a7a921716c723e52d062fd2ae26d2b2756105948d91b70838184b99333055d70d69952e852a2a6c0c5cb6b916dac12a9945dde95a754037bb3d1a65b058bda7d8d9981c8be2254a9854a8b644b249290e05fd75fbeb1a3389d912ce451b9797da658867da0e1f64cfd74935dce7624472adbff8d0f653668ee8879e3db3a03d8e31053dae14778dcbd59279f19946b27ef244b8bac9fe74db5e91d9d965763267883000db512c098e965c5a54437b4c785d5754260abc977dc53aa9d35860867ecc0dd9ccfdb2a7b341995c4a5bd758f4d912e9e2922e5c4f815994a16373dcd6dc95182a7de6f5d9e77686169222f25dd56503df7a9b724b253a22a005b35c59f7fb4596d7630327a4bf1b9055b7b4b91c937268f829e87f96cd8cdd466957e727a5ecd2b6bd01fb60dd0abe0da718a11b33195e9f791b29b7eb32dd64e3157f7d1c5fb2262bb14dc382b62dab28a2eae4e8d6eacd32ef471866fe3548d3cef58c095658ddd767a6b2da433958e4aec4af62a5e779f4170fcb4c0ab054d4ad9cbe0969bdacf67cc16938bc263cdfe04c49628c1b7e4f52b2b9962baa689317a423d25626a54bf6d3434baa95252654144a6f4ef24553f4d87074568a6c2bf1a423850e1d0eb68c5ef14015ec3ac5f03356ceceab02d8deee7df6a7cf051912395b3dce298b303f8ed0126889ab0753b9eed78f397537b3d8449a96a1c73ac3aa4e7f77a7efcc034bbe80d249eacac49088d268d27a7db6fe0ec34a3db238f24f5b35276617f11cc0bd6333e2300fab0fa7bff1d40d069422172bc912644d367bd15cc74b2ab6dc3d227b9adf42547abe2430d3febbfb90f88707b8f7819475de71812cd3dbef58168e7913f72933f4e302cca6bf27dc5426c8a176971dd055a74888ef326078e8c7b5646ef359a8bb5b1f818ad48901b3bb124ff9c442880f3d737cae4e41ff0e4fca1397a03c4ee756419751db95e939a7e3aed5e91cfe43b69f3b5df34770994e7ff794a8c0a19759a010053c7162e4481b3c5f7779e1da89f06e833627a7bfdbf9d11ac224e4f757b006a8d3a322202932947ceeafcf153690746c869baa55c71ea557952ddd4d36d5c056a99a8dd89a97b607b21cda43eb00c480490c1d1ab86bdb5afb213bd5f462a7b8a912c2b4794762e88f666d508271c5f0a64d417310c8ca2240007cbf0b211536b38562e3fce94917bfcee948cb13dd85a9bac9b368f267ae33bfce13e5243c29cf462dadac3ccd0e4b351079df052ef17cbf90ea2df1702b6771dd793363f1fcf9f83eb9b3df22700487c20cb51c1a78c3d66f8fb66d6961351f727aa8e6999999d78e64935fa7527d813ec5bc9afd53e9bbb0b4563f41a6216c68fbd3432e33cce45a2c61a0ffb6cc44ecdde7ee5a680424a77e0b2ca22bab8594efa62b13d86b74653405484baf9f925951099976bb08f1cad2911621f0680b9df02dc2ac432c555d243ebe42aad06895902ac2ecb5ddaf1ee6a73ce353b649a2ae3092c8be1a5ed680d7c45e5f9f01a455006779412d3dc852f47a14eb6c4dde96ef0dd9a208c4b38526acf6121d561a9ecb98a86cefeb68eb09c52368b5567a328301369cd69d3ec9398c6e4b5f42b59c02019b1aa1e42b6858e7506d36e7f5892a533b9fbd7b7df6ab01b80cdd1617b2081934903d2098d2ecd51a23cd17b457ec7e570e1dc8446e07699f4e63b814555faad7be42958c9f6d25bff7ea55e432a1aca356255a2ac65b54e502af5fe0fa2d7e7fa8d76f8c441b50b787a1ed79670cfef4e57bf144ff06e85d9c705ece6e5d3aba6e9b024c2aa095daf55d0aa9e6adc7a7f7d78350d01a12958c214f5b51dbc8fb53ffab63eeccd3cc139fc5d9efaf19da48eeed525e9f4bac4ebad6a5871859926a5e602bed024bd719f2e2fc3987d988b4cc36fd1ca1e6e9ba5d6f5110a60d7bce6d64332d532df6ed175b566c2803899998cd76cdc50e4cf4de5ace77698b76d7cc549598ffdb603db0efb650b399fefba329742a6df9ab7737cf63177d3d0f808cf33cd62e6fe769e3ed34dcff3f3c5579ff54d77740c4c72e5bb279739f4cef8a352d307335380fb7d8214836d43c51c31fe97c97b744897d79aa2b44fd2a673afb07a7cbbba97953b463ff3a0f6dbf293ab32ed4b77c3efe9c4221cc538142e6684b6a1fc5f5a147af1e90b3fdafab24dcd728b3b4765157b94b7ad4d73e5c6cb5602b4f9ae18800b31268171aad4737fb753371234e8c8dcdae89fe58382ffd613ca636c358d99daf32db1251d99ae7817f32281c4d985c7939dd0783c28db0d652274d7bf01155aed76156ea5d9ada5f39a7cb25db00b5abc8531d426f8fae822d6bf2eb80b61d7725e9def5504bdebdc3954a8777f1d89d8962258ea4f285c6b063b9f5a49f57a761bbf01745aa54d581456f9cb929ba861e6bbd7e8b72525d0c27d51be670754b7d8f1bf3ba2add6cd1b7b36eacf20c77af4074dcce1fa7fb7aa0ec7e49bfd88d74be391fee39938454c9fbed411463ba6b51274f73ff48ca0849dbcfb35d35b37d4c7382b7ca534c167b54d1d6fbdaf770d8275c679fd4d0db1d6cbfdb07451876388b8d0d6b99f300bde32c4dcb3fbf389929ce9fe2a0d78fb9ec8eb0ea11fdfee5720ec17336610cd16e39c4426d722b4a9396e4d2d473e8538f6cbfcd693ffeaaabd40f753836cd29b2e7b37b46d50d9e133b7dee9cd3aecb13330d33faf96e774acf85eaa68bba1067ea66a990e8ecdd5c85c1c029a1f775beb363d65a327118568d712c634ffdc15a6dcf4d7b26d8eff602c50d2d2d9b6787f96aa1496fade8ceb11bcfad74b6d13eb39ed9f9331c8335d5467a7dae7a20f1eb8ba335ce8bbb71613cecf3e2ce09f8f605da23b85ee039d9fe7717e959bf6f5dd948ffdd95edf6ba365bfbfe57c7af7cd584edf685b66f5fe8af9feffcf75fe8fcc685aeb7679de23b0ffa63ddb3889968e88bda84b7e8af6b4fa2316b916f7b4adaef57df432275adb3739b2cfb6d1afd1c5d5d4d4a4d80cd947bb5db554adca96683a153ef77e97a1b7ddf9d062f389bd4dcd893788f5fcdd3fbabf56bbb22f7ab8511b7806b9e5a09ddafac15d7b661b13fe23eeadb6f9fd6cfbff73c5ccbfff079e6d512dbf7f4cef5bc1988005a5847f722b2ede3bda2210057f3382d1b334ffaf22bab09bb38d3cc324e9af416ad78c0e2a1a57f9ba9b21ed6ee11fbad4cabada5370892d8558fbd96f0f4ef7235a727bb344b98b664596720848ecc27b7d4ea610641347f6d8d501a3266ad4c37eb574b89cb7b2451d8c6f4ab1bddef52e472bfe96099b7f49e8b65fb6e39593ffdfcafffe9f3e3bf7e1f86bedfa0c653bb58b556a897499a4f02a3d0618800ad3d08176cbeb4ab71847a29d985b23f6e2d980f5d5a0b24dd12fabe97949017b101ff50bb991d292c727b21f95c2496f50d8ee5b726bbd9d4e7ce1b6dfd97c73f7efe3f3efff1f35f1e69e51f11a70f590652d119c2c9e43734ff1fc1f5fd3ef6fcf7fa1c5d9d99f36571b465c22c36bed2dee6efef4560024be274397fc90a8946d23345880f3bae0c08679640a3535bafcfa941b562630adada799fe30ae5535af3bed5902f54f1d4fe94a0464bab87f95467989f726d4fb3c06d3f9ebcb6ec979e5285f7cc0fa8f95b482fb984f504c9cf4b5a23d42760b19fb2f5a8fbd56178a2da44dc7225ac173f63e84f69a4303fa5969f7caaedc50ce9d7679f3a10e175519a52a001212248290ad843109d183a50f68d368e4aa28261d8d9aaa9202eee5e7a7db6a5a6abf46023b29ad2002d2c2fd888e0886543bb5c11a84a4acc8a470fb771bf60836c222fafcf894109cdcc45b4ce8df06cd9070ac39ac57554f4d525f95ef0fb200bcaf5ac895a9d2d2d34a492bdfc00cc09846d6d4ea245ca72b3c5e40dbc532b5471456d8198242974a56415e16e804f5ee9df126143201c1a1050a411a21db6f9fbfba4b2c62964ffd4d617f6511fd0759cbef3fb422f518dc9fe89d78f0512a7b4fa4b4bbb6ba5d5c278428bd57a5e58f77357b300c1794a6d84fa02edcf93f5b1f9d26218f73697d54f6975dd412d211f7d83fd04876a4e6a1bbd857ccfbcf629ad786ffdf66e48bd8701d548aa172912b2c120cda0bd9378177da67e65c148a49a62893290f0751bca3849eff714d2c3046bd3f2935dcc39ba3a4cb6adecd1d573d0f8ca2f14a332befa0b127907a582c5c67528aacfabe282ec41f0981116715097952c87c590edd78f69903f18240bf06ae8d8b0be4b464c99abe9248036f4261575afbc05bfe8250a96a888c87cd977e7ff5f4fe3b716815f1f716b25f87cb9fc70d985b294cabf6fa8d058eb4b081962523727acd620e3618cec92ea58d46bbbd6f5ff53317b8cc7eab5088f0d438317ad7f9af3b0f93a4a9c179d7e89f57b6420d738156135630ca95500d9d118eda1df4fa4f8acff4b8d642959946190eb9f509d1403f2dc0cc87c716d318b1cd6c13e683cd76643d6212f00205e9fd302b696f2b133b4fba0b7933df99974112eee8bd04ff1878bc8372e62ee8b4821bd7f11a9e66f7541eb3f377b9eedb8d5e17efae5f18f2f3f7df9d35f7e343b2f7580c1338696f1034bc88568ed80496e75d5e2f4bedf7dd96f7588fff5215f7f76f3db1ca182acb70f5f9f73af61f5ccb1ad53ce978bf2d8abed2fb5f3dd7ed9d7ba77ba5fef3cbfa8f3ecb7fe5787eed37905ebed40f104e5eb9e5fbd20e453e684e4b9aec3a6d5de993853ac282ee58134788a0bfbb60c92c5ad29edb5067c892553a9d427d543abac83b4d618e69096051163cf78517325cf5234e10388adf95e436cd3d711529bb6548f665f19a12494ae7a4c3ec714caa8bf4bb3878177a4d778e694ed0652bf2c79ef21b6c7d266a8d3ed971de65d23c4de7cab2116575a0c853ca75ecf63724833b95642a9ebb27ac8698638ea639a8d98caf97a928f85d2d08bed751db027a0b43aaaf4b07a75a9d9d5338f9809bc56e8d5cc87b642b11e3353183d1df6d804876d039663b8485a8863bfaeacd73eef660c230de8c087d463ed2a73c65ac8719f74b6c3cee9744ea773ba7d4eb7cfe9f639392a15bff7d5b066d565acf310fd7ccb2f3ec4fafa6c06f2a287d5d68e166a813ea0c2c6d7ac07c630a738c411ed2821e6fc5808637677be9ef8921546960c36e5589093ed9713c61443eae2e96be5183514f88fda34dbaf85bc9633dbc60cdb1ac38060bc8436d3eb736e298c08fde1e8e30095b4b26f2bf452fd9c21754239c91c8f3ac258e816267b141ce3f637748cdbdfd0216e7fe325c4928f9c432cd4edf73838704db7628814858c3033d2fa29158e49d47cc758ed9894cabe180ec94d17338bb99d36600ac8de35da4b48a9599f11d6ab644a4fd6ec36cc5207f55a52e55dec7e1f6287fb7d800ef7fb001dce7e1debbedadf8bd3fe7d344095b6424afc5cace821adf3d77821866b9345ca2e5a8f99509835ca02c7c447594bc421b5511b37200c69abee43385afbdddbd16d81821a63d87ea743f77eb78fd67eb78fb643c8b22774d15a5129549f3a801fefabbc3e17a2d5c5c59710ab5927317fddb869eace68865c29f04da37cf1fb531de3f5e93ee608317fdda27bbfda2ad7b18fa64557885d8d971307c7b57fe2d72d1aabcd155c5f5c5f3767a201fb00e43862d6bb6b6bc6b577bbaf0f763ad6767fdd9889d6e963eefd7ac711bdd904d0f9a4109c5d791fbd9bf2854b7bdfdab81a0f374d8eebde1b76c7df9eff70f9cbeffffcb7c7bffc78a413319ab15be71d6e804c5d09d0cdf8525a964a5f9397801be8ea7cb21d596c2275fabdcfd7f969c6032bb089f89e0f7d9dafcfe03e5ce935e4c34fa903537886fe9fef516ab8d38f86a7b59258699bb6e608ebc5af083884925314c4817bc1ef64ff5ea86010b127c403534a753e092422e955ca38ea08548451ea20a1b7e5b6e00d2457f68a2ce021a54ac82fd071cdf6ef65e4a796c27a676f93389d3458f9d8ef5df8bee953c1cccb9b576822204b8a4b1541424ee37fba89686fb6ab943cb2c836cce7bf1094a831e4231169c8801c4196be6f377fd51d6f75e5af76bfd797bf0f9d42fe0fd36c978886e4544db1c88fa8327494ebac21caffb10b6b6c591eb666b16eb246f7179f6abd4f430ccb0d0c90a0c3b6f5e2fb3ca2571966db3f019cb1bbbec9ac6782b9d8dcf7422441642ae245ee2a65074e559e46dc65bc284a5121605b2f66abe4a759bede57ed6585f562d611fcf322afe6ba5c8ac414eaa722d04b959ec5700a869831097a72221dadc25770c29940469300e5aef8b57feb923392e287dd53a3c80678e966c0fa76af7ab73fdde849fff6d35f8fa71f0dd65496ad5d1f522ca18efbd27268f5852a85a732432ffff231cf66bbefb37911e3538653ef3ecff62f1fe95de543fc001be0879542cd9f6a8ea1cd7b01f03eb594cd3e6fc5b3f769985df850e7087d7dc8ad7f8afff2b1d615e2f84052bd5d8804e60fa38494eff3aaa127f1037de8f5c5f77a9eb974fb197df75fde7b48b4f9ad87c48edb0fe9af9fffb75fbb2a45d86d867968a2174dfb16f78b924632b77a525335114464bb4859782495474f9f6214190f522d50f6070526c354ddcfb0db982adfac0e15d40c327efad07ddb7af4c4ce6b7babef035525ed7545bea158a71aa551b00d8c9fa5ae86fae2c344c3e32cf24112c7bee866288fbd855a87db2fbb847885ecb7ae73ca9b8581bae229ce8a24567cca95a7cdb35d35d52de01974ea232b6b73252fe0fa7e4d12b32f6d5f0722f8aadddd35ad8e9c2bfc185d714af1369c5c1cbb859c60e38ab557c1824f25cca8623442ee5e6ade55faedcb95f7d1d35f8f807746ce75ffbb03e8479be6aaf9f1032f7fa47e8492a904ad93ad15e21a6cd9420717772a33ecbc709bc5e53543830f95d7eb7b73651bc0805421941d21a745a6279541c0245a0fabf684079c62ad8b411643bed4bd6dd35823595c43de8c055d2cc67950563b0bae422ad99b6fe9670d63658802e7f4cb9c558417c7a054674dfd600e6b359742cfd02ecd34f71b73c24f205e35fb0bca8b9eaa2fa18d6273409c28349bed50c9839b0538cf3729e6b066433165ad2395b03a7c7f8bc2ee0c000ddf65845ae8a5252dc40dba4aac6ac1079a90ebc5d8ce777384b2d2066d2e9b7ad21a90c0091eba2ad2ca0d96c1de9aeb25f4d140b91672881938490fa5373442661c9edbf65c1fbce10038cdc3d29b5c43ac305c87294f69cc2ceab822418a55eaf53d375814276f31ef3b1db85f363514920e2361bb544e579b28c2e08ae317edf97341d200e9004e4bef623d2dfb71a3349785e34918328379a14dc4b033cc817503432a954a79a9d87d51cd9a3a552b254e6bb69ea76b35e4f62e63ea1ec3ef0ffe1bc3febffdf2a7f2a3ad9769d8843f66a8b6ce5552a11594bd92a005e61e841837a76881af7898f1da37ab0904964b44a654bc8337bc1b2e5715676387434c9790012c9d349d4d28363d344721844f657969b853bb96551ad4d8685b8ebf52d6b4743530acf44a5e316abd07d664e3a2a67d336cec5f24a4dec8742d699791ee653beb90618bea5a6a95e9133e6af468c5f6a1d532e139dae6bbfdc31ef6adde619fff7ddff8a73f7ca7f5e0b79852a9b27cdf9712d6ddae64b453f2246c215f9f6aed429ece5dea885e8dad9df735c1f538a4a1b6b424b3657f3ed9d7efecea385d2db69e97ecce1f157eb43b6cefbbd4cd8498a14b77b940f13b2729a115fad3aaa17eca0b6f87baeb8e83cdbffbdce651248113a6679fef61be40c375448f568ddf9fdabf27ed212b0aed9263b77df125c750efed978f61c3821071f59ba70c3a226df7252db43c43725b7592ac2d7b87247899cc97684420ed6f2809be0bb0b15e72a34fd9c7b7bad4df7efeebdf7e482ccd6fe5bc44ac769563a318208addf80f29462689dd17954f8bac7013ecc2e8e5cf0eeb37678b3d0aa9568ab2aa88a2008eda7912c9d9375f3f4e4911d043d03da6184b70116d15a9194a14f9fcd4bdedd2b7a4322890c9b95ff530dd5f3f7dfb2a690a74560e55f18fcd1483c161fd7405519c1799c621f90ec554dfe2ef17e5fd57e887a4d6cb961493462e165d9d613ea4915d19f140735fe425756c126cbf4ff7fa9cf30429a35adaddd82ad5b416be3e08bf9f5281c3abec6273b5a69ec11495d1f070ad9d8fc1ed675408700921753ebfd76740429477767951654bdd870eb5b02bcdc3c727c26f3534f2187e857a81a216bab926156434b2ebee39798a55a55eccbab0fbcba2ef40491292657d1bb1a9d7679562c7260ac1ea7bf657caccecbf3a9d7ffb5d337685c45849c448c88972794478e899286f89d85937451988203d65da4ab6a4af396768175fbbfbd6ec6113c2cdf9c376dc98417efad79f7e40b1261814f27cc9ad3fe4c48944bcfa29d9ac7b9936bcc0a6a5342e497ae738c540186df3c5a7962e3c9f040b8db32ff956427ab8fe80d91453a89bf49081c7c48b9ff611840db3dbda55ecabd5bf6f29d28ab75add3ebfd1e8cf7ff8cbe3772ab06de93f1c4dcdad2126710726b123fe40ed0a343d23bbe1ec904e32c7a685e1f6f4bd51556c89e9754ae677201c222a5666f911faf83d589bea24f2b27ff4f53955b3cffa9f29b8b31e6f7ea42dbe7f65a249aeb43f936487db7a40632fd98cf1e46be87ff6ad863143ceec02565787be9cbd7d99aa21f9161e88f163ce354c1b6bbc28ab1ea9924dae5a2b8cf3e5e48561d69bf348618aaa7139f31319f5731bd62ef92abd9d4ce9b74d5193c2faf688e04dbb6a0281e02b61aea7d0d7c59c1c3bc28cda38ae47a4ee1affed0b74618c939673cc3ffb1caa821fe6654dccb33e1fcb443863bf9c5c06bdba9a436a7ff6219342a0ec40f9dd591eede6987fe795602a8542e632cddfe58a9cf2c93dd2a22b159c670cb94138d945387925ff37931eae1166fd79febd9e3a89a6abfc790645b828664cb80cc3ee613afb77bd7abf2f3e874a5d4d9976cbd89b1d12b00e6be47cfcaab97c18e3abe68345e352b26f4f61e6c7af77d8b39ceb08ada1cc22d1b336ecf1c1afda78900e1538eb550e4527071f7fc98f957a33b75fae3d2671d3d3d96a1afbf9a2e09af9da1465bf3bb568aeb835b968cf8de9e5e79ffef2f9bffcf4e5af7ff93e4a47bf81ff3aad2ce770618ba0f7281eb988e19e43be9f2d943b4af85ded70c820aa21ef92afbf3efb09387695905e80f4dec7177b399028b37ee7e0e4a84fc8551e7e6b506e125cb1debf3e6336b6713f433b3221d0465a041e93257adef9649e6039c4020ca08f7ca1887b41f1bd3e6fcebb1ac67d0ae5209c29d06e6a8261e6509ec8271cbe6e42754a3daadf1477e5f55939cd158addcde00bd9ac42b3334bc8f7f1a586f5f6213f175f7268d7cfdcfeb6ee7c7f9622cdc3ad9cdfddc7adafce072fd47dfc94e6f58753ef1039450e5b30924c18788b9a008c29577f9f07ad8468050d954581b2845c2eafcf297bf048f7ace3a5dfe79942e29747c8f6e97e96e7e7b0dee9f3f1ab8f7b1876db9ca8646bb8585c4d7699390fbbcc4416786c09145bcfcbc9b07e5f6b58070c452a33743949813523ee9963f18030f5cb35acb70b45047e5f6935bf931d1f0b029fb185f15430113b36314c4b7d3b09a7d8f67d2e4703c0dedd129b348ecc74d2ed4ce427cb08e9bef4615eadb71906255bf20e74b9270fa4660ba70fc5b5d1ba21aead5ed9cc3edfe943883d936b5e19bf3d2e449524c24fb866feee11d062bae1614f99cfdf9babde269e5bf3d5dbde9b73d65fbf932edb6fa8c2219afc21c71eea876a267afa609d3e7fc0d2f9d07b88f3434eeb434a3da47ab1552bfb50cb436aa1d50fb9f50fc916d6fca1ac1e4abeb4059b462d1ff20ab97e68f10348bff9a1a550fa8726dd84143a599cba947b3427627c48b986fca18c1a5afb307b68e9439ef3432e3994720f207efccb73fc907b09bd3ce8830f79ac30d27d9ef362df691fd0474cfff29c56f990ea432931a461d7cafe29fdc4fa50db0caddbe7efa5157968b79ff45f6f3ee3bf3efef2cb1f7f38adee08b317c511c826db7c47ed63d7d20308c531055ffc26fb9a87170d99df0c724d209352427d00e1efeaa2b66028d707f448622a5ec2c03540cd577cf363ecc5cf2f18ef27cc5be26f068c90db664f2a3dd44baa8a5c0c08f9925f76259043cd2df25fc2b8e4cddb0c1f6df36253e59c0b37a913e25c32565ddad37af7d3154f014cf7e66bdb8ad92f1edab1ce42ca09e4eb930bc4a5d7f4928a18a0616504dc90091ae8fa363fd8080ae2db11926a2ed2e717451f2007c8a1421587a443273d983302a734a9415d6c9782c9ebc74c48d89ae7e07b6e7fcfedef7912b82a342a9b951c8a049b7bd70e425cab8b6a7552b2e6eb0452c20e5a209094ab00f919e969af7a1748dd2ae188423d5da5e2689eb247526869fa66f249dcd91410d1eebe788293dd27bfdb5de4609c12ac7fd0e9d4da7eb7f6d6bf4862157362fddfadedafadcdb541c8cce31227590bf5f563cfd1d5d8c378a843c0ac5d0987f8b94410c06157df36f37e1229e266c7863f6b21ec8d7eb54f9bc76e79bc9bae2828a114a1a7dd44db7eb92588cad02a468347a78aa2b989fedc39c2dc75846904b87304f44d330884ab2b049d54c6c500abe8d89b63b69a14d3bbdbd211a21ace2a90817decfdd88aa6af9bf31d7b6ecc78bf7c9fcad2df62814738f023612c3a0344afca8e43f99ad6a734e37d1961bd981dd88fe88635e1b4f66df0160e74e6edb827bef4fab1da3133bfe42d8266bf33f43d2101d244b8658a362d5f6376f6b1e7d4dae4884f9cecf0b6ae16df2506cf6428ad7644635e9f4b83f670ff24c08bc698900ed1d08cdb362eabf906346b583f1d90ecb1c9112fa29c3d20baf4ab507809e820cacb5de67340e519c5da6fc6524e39cca792c378b16e350e04de6d2605f9610dcb06cca711409add2b37bc9455a5d4b9bf3e172400ccc87a012c52901b60c04e315d0fb65421161d022368ea7057457296afcf03a260c8f792825788dd81316c242662a8e79a5522959614a399fffb62b3e851ba48aa9b9b89807372b368dd82579180b26fe606d5dde655784a563926d2be63f5cc1f21bf10633f28fef639db42bbf07ccc3851f0fbbd61f7cbad52e37ffae5468df13f7df9c38f665cf40a30a775d2565268e82c0dcd8dd01e1a90979286d91327e68580364d8d4ab28b709a3291b53db33269f2fefc078dae2debf7d966b9e3e4c5ee2c5138d80bba606dde97953f950623004edce449f37a5f573cc0371111e173fbf7625ef7115df3e5ed607b7dc21f3f7c4335c3a65276d9bf17a2f7540c8fc36be09a4f62ee236956c0386c83682b0754a6f420704138315daf77c58caf21feefd5f4dafa97a260bc44aca89f630588ae13479f6e7f1f166d242929af2541472ea1dee5d66c791a2e8fc232e10ae160da72881f7db90cfd5f47da515b59910cce9ecbbe5efea8544bd77ffdf010722a9ac9b0c40d793dd77d5e36429652db3514495abe3db3a79262487aca24358b13c16d72bb07b8dd3336633b10ad502ef674f4f3ea5e1cbfd501ac1fbeabcaf74f5ffe706bf07df9c3adc1f79d16bbdf44a360b3110257361e4427ab84549d3bd9c4d693cf43059ee8932615652fc7210264db7a8839cc8692de55626a700e533d837cbe0d5c3b0785203692ab2bd96fcefdbc4dd21254ad9e54e069cb6c879eab083291c5339eb7958901bcfc9638e34378c45b3ae591944a07f53e6cdd69256cc2475bcdca535af0f28301c624458239c39a5ac6de7cc883f0e53cecf06a0b567159a8445193437d9d6c0178fdb8ccc25afdc88d5a7d5967a0066cc3ee6b626348b3a336929fe8c4f553c4222db15377ebeb5f6fc9745fde0c53a8fdec99bd6d3fd55c427a686642be6fb17db9bd767cb9bd787cf9dbcf3f3ffe70c8e4d43a429c0d5674a98f3f99177078396199d581f823c81c89bcf42d9731996d20e1355f6ae0b1d125d14110331adaad2240404be7f539f3e425449ae5d84dcf21aaabd05c3a2e95325501f3fca95b5a3612536e203cc984f82ec0d44b94b82c95c0f5e00ab78208e380ba3720a597adb0ab2e2bc130b309dd96a84b2e4d11064b798b7e37448d5b6c96545540020e928739a354f093935e97be2d2a313a97b3a87a139543a27202575ba80fb9310f5d9058295833a4bc55cf9d3dea6ee6b79787b4966bb1856ebf61c766cedcc1a1644162d3569e6e8897c0cbdfc46461738d5db857ed38747ff0fc48600ce10677aac71175b64b61a02b1258afa806a20ae5e2a5d0db4f748e982046d8a2cf5c1a51ed1c81175e60372534f9d007a97b941da6df5ce375bbb0341c440e2d39bb673184e763f73d31b0a7ad4d859f656b5b18680a54096aa40756f14beb66d81cf8d1a08ac354e0634855253d74b1e45e9a14a5433dcc30a6a4480ea23557210b2f5e1410d50577fd6e45349217a2a3c8e091ce77a9c607b4146cc6bb906e2f66ca4fee0045fdb49b8f5ed761ad684d19e88e797d00cd86f4620b1ca2e4e025cd66168b47708e5c7fcf211d341d931caa1501f969500e95ee439c6749a4251f29f9bd4c14699815d447d429e3c55cfab115569be2ed5891fabd12da43117db828576ccd22465ee0b416984930ee2ef5587a4927623e0480e28a293e72a7a8b0e0ad929fab7b319a529b688d107b130f3923bc6d4cbe3560237932afeac525ac63bab5d9b8050bcf1bd15eed69937419d485f1a34797c231a4276a1738aad05fb920436d2d298590042503a00fd562491666486e663d40b7d8fac5b76ef6d301bf76172dba6497608040de1262609fb6cce1a56dacba303636aacd41c41f4b07fe5ef3638938edebbf5ff4e2ce7dee7cebbe7efbd55f7feed2f11457ba7844551d75904f0defbde51db7ec5ff486bdfeebbd6f1ffcfd97dcdbb9f4f7f5635acd6c289208c9a5cd985308a224150a611a65c24a932c05d5122c186072b64a1dc654f492734c5833a83221129eb7287cdb6a1b638ba94868918eb9b491a1b6aa448cd6bb97d5fed75c565a3c97ff054d55dfbba68ceeb7e06c68de21acd895224311e9539a94674a175e52f712484532acbb2e72a38a799b4ff729cf505e281ac38af01a5fcd8b40a93df934254a33047fda04212c9b44e624f022a949a288e36462aa8ea805add6d1efec7bbaea726fa433b10b46f293b76912c793818f85b0637c1444a77fef6f99d1456de7603ea01a6edd67f831b8c5e4dbb976b220e66ffc42dbbf507ef50b995926118e4961dca39256a5a0cdd25c6dfa1595a42d6b491d0209a1e4d2966a9aa78a6a426372a1e046765d45421b66c6569176563ad513cb8e0ad35bb4b8a7768a819939c7d693c7ec41980319717a993214fb65525e694e8d3580b435129d77a70a06520e6d17e64a80f46ab85689c2342d729ca2b933ca4c310a017dd4cb09475549c048a1a5306c4e59cea2497a780aadfc96772cd8bed46b4aa965b8ec2480c5049eeed34a67f9254f9bc66c2ee76dcc76a5b3e1d722b29ee1aa8ae328f835636746a44d300117a44dc8430ed6af3db89a4aaffa56e7478b5af1eaea4ed5eab5b718609d018688df549cbbba5cf52aa793136f1a335cbcbad5af86c4a3bcc44f0b59046e67302aab36f2375c28794537dd28edfa7b57ead3e3e31f7ffa4e147fbf413f221353abd83e827962cf404ae6ea12da7f3cad19fa91558f674e2c711536ec897f6a55e44a792b99e62ce51da831d2ef81bb9357a8d497a417b3bd0f788c97aa0e7bf61dac79becf13e5c75dce203d66048db368a7d055d19020583fbccc98a2f08454e3cb6683fbe2413b2cb1e8492eedf0d288bb0260f286bc4b84dbe3ce496532dddb551dbe8a1fae7729f8276df5cc9ddf45dd1db29d0489bb2bf90bf7b5ae565b0ee9c57ee0ae1218216f803af074a38164552b5711405560b036a7d953a03cff29ac577b62aeb68e552bf587eac5eab00babb9b769267df28938d922b431927cca25f56c5cde2ab1f2bd0535df56eae972f740919707fbd1d2f3c56e7b913718d2bd4abbc201ccf8d622d71611dab515f7f911c4fc08b4d1580cefebf5395d5f9510948801b99fdca4a1f42e184c03ebc658d48e1b23f1a7c7e34fdf6928fe8624947db5e427dfeb8574884bcb56f01ada43b73df7f102012790a7f9d46768a23c28fb931473980f1b0e769940a8e2dc809d095765e11bbee4b74febbc5072905f01a295d2cd37f3bd3eb56a5baebf5b0eba1bf256d36bcfcdb6ffe3e73ffdef5d42fd9109ce95893c61cd1205cb3ee508078b4f3d8bd163fa51142bb259c7dcbb49a471edc2de22a238d16030d8ba96392755eea2aa8a297926ea35bd221a21fbae386827d6eba2b01d845fd89a2a4346f3c00c94691626f570b65477e67698ac351ff4bd399a8bfcb258ee3c449a676abc6431e17573fc3bc2ff7470cdec69d7342fd7c129a0ca6a8b45a8c7106c6d4be9d52eedb9e90681c4aa7568b9b5b6db9727318650433e5a74099909f3aebbb6e6aeaa93b98494760181581aaa9b4d800e614e10eb53446c6322fa7623cc7f60b59b2ee5667e61890bce678255e2146d121d2406637374daf256d929716b9da163c082aaf005ee95b90124294b940f6552da8455799046d1e31ec02586cc28ec44ee871027c4a859bae3803515234b672eb21511c350501325d9a7e6259448c0861a4236bf31135c87f5ede9e0bafbbd39e1479b0df2a0155a0ced258cbb4ccc8c523c7bbc9440d8e248eeeea89bf035bb3e5c8ad243d297cf24764ee4cc4e09c8b4057e9383cf7c9871de10d7ad89bcc566f5bbd87c1d204ba3c47b50b26cae306138b633c4c89170a0272e82c743822265279d1397c48592a48e1cddda02d5895c500756d05d9ef16e35575b534fabaeacb937ec068f6867efae612757624c522fd5b644fd8a9856b15d884cbb1dd615030cd4b889107991a8b5a0bf754b0a0fdfb39ce341b9bcf403c1842e6e8d13a0b142ca9f9425406886456e8bab68cc344945448b2bac245e7c8e49e001e0a769eb8a024d1eaf1fabe893f14f4aa222db4ff070f833e05267945a6685c713e5cfaa5784b5a322646f731b88058a3e2bc17a8acb3a452470d261c48ace668bff0dd141e58d1e00a45345eadb55a73babeabbf405353ab1e1d6f43a28ac93403502b70dc054fc46a9a506e3bb63f8d6e8fd5e25bcbf85d2a102095977b5106fb22157c60a58e3bd85022a3e7a55aece5351dcacec7287c6f5dc56a83570d93ac591c23b3353e9124c909476a7342897594f215d4014a7d0bf7859cfd6d3c9c51c0c3042d17b3941f473abd9cf5d024794216fe4f5f43cd4a918d28267bb88b843f5d8d21426ee5079d2b87095d50804c1660127bf82df1b971043d3e7da437bfd58d189ce53caa0e663573f1727eb3ec5027964f29d641983710be26e0158ca687ccb90667a8a13c622e1258c11c3c02c4cc279d156d950fd6c61ec17a598c395253226899f02fc9cf4dc6266c2f0690a019714f4569e2626a453b9a0be398559a90789e6f2b6b1f8697ba09aadbb4badca72aa0c3010162a2e4c71b389d9629994952ecb0cf379106190d299825a39886426f99c77602a8b4da54b70da0e1718013d1dc58150565a0029eb161a6d52d5ab70c24bcc3d857224ac44b32498dbbbfd997e2cfa42f3fbd1a2d7bb74e6862c938cb86af738ad8fad0d789f3ada3674f53e94d7e74a640e88d4be3d52fababd64bf3237c4694198bec42076ca920b7e39c52cbf645c2d9b9025dc0ce4aa42e83958daf2ebc70214aee4f542768c3573a1571ac99b109abb987f4e15050fde968aa8f065836644a264540250cce64b928c3b6dc61fca64b94f8dae091d902a7bd18a410dbdf9dcbdd8a9f7eb96fa9ea2b0af544490d5984f211f8ba4f124df2aa6310183a2624f9bcc2e6dd33539c2e37b2d1eaa6fc8621fbf266e32b207a225efa15f94c8ebc786b36858a16b662f5f923dd43e4493ae3f36adb915281fe2b88b829807a01e0ddd2dc54ce65588d05d725b45925f9b823bcb0d32e053f5dcd50900f8adc5e376a13e9fdf5a3a9eff77f7059f55c1922a4f39899a2f69fe1f451aa4e6ced09fc14b618c443dede9a5583f37d0c0a65779195853439db52b63beb2f2ff660875c196c7decc1b0f61a603fe0a79c3875ecda63a0a7e1129527395bab993e697f9a1982b188aaa726cb02ab50b118b8391986835db926026ccb7a2a0cb928db723373dd86e9e0d382859e96e1149fbda541696d58f29e127c94a4e70a1ee2e927a9b575d9d0a026ed1ed6f05329ebfe9bd3c7fcb7979fefca74f3f5cf7c53b4104e2f059d40fe2b68924069889c7a64a407c2e03ba5255f3f4b62ef6bd8df67984115c7888decddb344b09482e25af936e3a6c166a7468db3c9949b1fbf1809b9e707a882e99a570d03d09aedab9907510b702ac550d066ee991f7cd57e13a68e2a44cdb7069d20b28598bb6dc2d921db92b8d00bd5c474a09b251216dbac2dc13be732f851fea0c0bac1536075b5fb7df4a12b6e38ce2fc4a9a2013de9e5d63d2910b49c26ff6b14fef75af4feff4ac1fae6309299fefcd4eb9a3c04e7363c67e1b3dcc1728dbefa2ab6d291109f7d1b66c667c62ff01e7923e55a11e5bf6e7939d65b3324943e7ba8b3f6637d8b38d2a3862ca6c8af88fbab907f3027f45a9b57cb7892d29828d2dedb1345d520f82a034698f223b6b15453eccb39d7ebbbbf36daa5caea9c8849c58be78f1efd93c5ea85e214d6a3647b7596fd9deb1ab80f239618ad34fd393508b71f7ff2cfd98d492a3b3a271b4e54ee425500fa9f49daa06c0ae1721a2283c599ec9911990183d4f093613b4b51752fa2853c3a7b11462a316a5d730bed995dfebc9b73af2cfdf677dff8dc1f6dc6a182fd62687078e5385c15b6ef3442636f864f0fccd19aa0593578b2453024cb18a234c599cc3877997ca70b565d1d0963ec48b1473184fa38676b7301a7b52a4c715f900f89d35d6d08ebc4fbba0dd304b2039ac7f8922c987c31fa4348f6a0c5c7d105891120a57942be7723196f736ae6d04429d655fb849179bca2b45b38d2bee4d2f4a7e37b799628a3b0d6836aaea384a92bb57b6554d5b880294582bc7837a63ab45aad14114aebdf00ca7c88eb980efd63e5877bad9f97ebeb53cffeb8f06bf6eb53925d08a7cab2da53476d6392109356159dabb963a5853921d0e0a5fa2d987c99629f3f6e3596ba96437d464b8414d5bca6f2e21afa5af750ad28cc356686f9d5f97b17da2f16426633f884ad8216ed81f893f294187ed86dbcaecdb46682f93c91b3f4ed657bba66551738d949aa133a1d21f54aefc2ee6deda64f99a28b0adfba2dabb1e4ee95035c82e6d635c11a58fb6f827fd49ab8576973a088fa192a8e56a325b944c6362a26e52d31526988d2cef9504efaee14982390cb9cc43ea2d834aca360598359f95ffbb82a38bf28a11d613cf72c745355c357f9b3fbfd322d4444a4b0c2624dc551a620ae90263ba5c05dc08bb4e1b3d996849b1615425d3f2eea8f9d75b63e65f6f8c989f5f7eb47a2178359df95627e007afa544cd30da7a00b5996248bf079c905676a99044a534194749023d4e7623ae7b485203b429f94b3bf31e82e19f5bfed75b7cc1db170e42b12050ead6dc9b3ba8ae1f15c3ba6046da7f6e01c6454f31b4df9bb59ced065daad15e9fcc264dafcf653517bf75d79c66a9b3fcbe4cc58cb3ab717eaf3b9fffe8ceef7b1effe8c6d7bef1d621cd6cd935a00ee7ade7d78f85da0dfc4f614d598fa8cdbb6e5dde4ef5e5fa03feba4519e63cf44154edee3c315cba96eba3fc026e5074c8e7ed1e8225499cd95df7b1a5afd278072942829ad74b389b984b58873fa9f6e36eaeb7adcbdb03fc423af27a8b6c3dd111de1bd43fbfdc1ad53fbfdc18d67ffbfcff7e9f52a4dfa22fd7b0b62a1c1a11acf1b4c5a14ee8c6ee23c013d0437572dc93f9aee9f5d99788fa607e6a254c0ecb64920b359fab87f2b6a74cca15c8ec7e0b48624d74ab3dedf3bf6fd17f7e7cfd3e66ed6fc87bb498e10f8b29f471d76c2927b41f5a71d4b11757fa0a6db9321752baf34830fca52b081e83ae50129b1fcd3f9f4e7f45ced45268c3a336166a0d69f95e45ebde43293ef4fa3b3b7c39fddda25c6db93a565836859730bb4fa174f3aa56c30533f70bf6d14c1848e30feba681f29cc3af157a56ec37a98860fa50a7d4276d7c556dd6ad385572c870b427c0f4a9112ccbfd6e559530da54594282dd35cf19e2722553eb8ce0585a23244ad9ba795935d89cda57e8c31c5091afcd19f23c2a7e5f42f5a2c0c73892f5b4bc08508bb8ad9ad75042a4bdd08cb239288591d89c2554843646b4c66f2dd8596717a91c736d71e6e625d770100bfa56e37c73d766c809b9b4ed2c62f424b3eded618786cbddbbf4397ab12635ab6698f130c9751542d6393becf2b45ce2a646587082fddd531d330cacb69a5f3f928456bd7a2a878898aa6b3c17db6eda76f18bd70607ecedf8fa9c520f6da023fff6d5fed557fbf955483147dbdbf1f519ead99e7854d0d75699b7989f0907384dcaae4087a74b30af671ed51e8db9d3cab535572b111f02667138b3a7a6b7f3b415325669564c8884ccc002845a3b128c42cdaf50055187a392acec4b308f3eb99e09bd75d7b3f2138de2e0182679e85961556140bd4bb06cd3ce8d49ca3ebe31477dfefc87cb77a210fa0dd9d90cd75f6f6196c39715a6ad8da384cc531ac54643ef4cf83061a76e1e51ec1e02527d3cabcd1dfb9015c6dc36bbb347eb67b393edbd30e295299ac27a3d81fd86b6efcab439910b72d1ad1546c6c7292102e39f618185272395871b8369b69480407528482536d008039c54696e65ebc6da2e4baa8f2386085eba768054c5b71296142fa8ea9b289c757cfebc74ccdece35aca173302124fd02b5d0d0cbb7a6dc7eb3eb6bc042dadcdb79841c7ad1dc6eb64b4ccc3903c7236bfbf53977668154c34c179a7b5062532ba571b87c15c86ece9415024ab13596ed8c7aa0eae5242b4df02e16d2a0177bd636eda5116a7ef261b5876ca367ba627e9a2d29ab6fdc7054651828b198b569fd260be852a0f119553fcfa2911f7a846172a6d0b0caec1aac49b974aa8793364b95aa91eeb6d9c8cbcb86aeceaced3435d59514d612dcac749b52f30ab15db82f3299333f85c507bdfb6476e13a7a888a06025ead2483ed3ead2769fb8b5986c820a4a4cf1d9feb3c4ee7394f1c8bd72fd9a405523d3747337aae4657b6b7334640d4cd38c90a68bb345b6f58dd6dfe67aeb30750fdb009d43ac9bb016ccd25b7a61e76dc9a7c7efac3f7e273fd8fcf3db69e8e11fa011a0204339d8870aa48f37dce2407481a50643bc403336d214a8a67481a799817decd0faae2502726e2cbb5fea400682aaf1fb322bdb5877197e224d5afd845d9a40d85e2cdcd7290a75f280c1013a9c5be35ba335364500109395e15cb553a7cdd803d29a10b0fefbaade304853b18ffa6184a4af0a354a242c4decefcf354997202d325748a93debea2dbb0bbb3fdfacc459140dceccfa4cc07b45ab6fe9613de31210da62cc89aa5c77d4736cff42fb0c0d838e8a8e7b4300eda5249e729393cc55dab4fa9bf7e2ca20769e6a065897675dd582d672edbfe8c2cae2ff36cab20f472b8ad75acc793bc64ed4fae50255d016aa5b0ccda9caa97dd90336500468593928b2e29c1849ea4a7a7c5c77cbc7546d9ab8cd5907c9b2284a1c06bae0d01f040f17a11a045d9b9ea2b29a64cff61a7f5baec2ace517b7db619bbf812afec9be6293a300c82780a010b33827524f2f76577906e8ef3140b4ada188fb3b218644401255c2ab8456022d51eaf6a951375592a086fa25f706dd368510abb2b4af9d465119e0b48258892aafa44d045411e243eefc67a99426e4e393ffde146a6e19f3ffff45fbf13b0ff37447c0b840fa9dba423d6879443df4c02d61277056efd2596a002a3043c5ec336528c4220a472eaf6179c937a804930cf570419acfb0b87a0533e5f1cee40879e3e8987a96a9cc07be7406bb1018c0b2e005d18b46b7a385296044b09df44985e54806b63bedb9550aa55b3c66395ba168aeae2bcde3fa3f156d50895122c7de8cf3df9aa9ebe765764c3f69cecaa6765be6e9c2dd059d6b67582a3d0f2fef7a770a7f67a95d6fc57a770a7f0ba0a3a8736deaeb5fbcd7d9bfdb927bf7e6cbdb862e6dc11bd35befea42a3944e1626ddb2c350c8e3de0ebde64efef4b6cae225a501699e94e3d9638ad2809474f5f1c09eb727de882d8db3ddfb5625e263023bba45e4276d78ba3fe7a09e6de0e1a3d8a0f82cafc250c6e274330dcf9993b7794db6db3af2fe95b14159d9ff7d76765cde37ff0d7dacd5f639912b3e3af7fedfde9e3bfdeac4fd18e1b13c8d3e35fbf3cfef2cb8f094acab9a2a3320fb4bc0869224cc9542e590d3e88bb98df01b851c2248674612d515d42dd0cff4b933f6b7c5887722a790312a775d693ade029a403129d08880f36f2b437f7cf12ba55229c72fa6ad6d2524adafe6fb861431fd9d6ebf3508a0ae690a2e22f82295a1f4f1407be8410a839c38059c759c0b9943acbe6ad80a107de81ecf7f4197e74b081b8156cd5f44575d7eb847e9712d281b3219e66919336a7db95793602a51bb06d825a1505183239d0692ea161b3cc081916f54b520d3b25756b339fee56da53593a2b32545c821c134054ac03495dd843a84ef5dee2b8ef3ea10f95893d8bb4e45a4bcb95ef62dfb2e92f457209bf45b9e20dc72e0bf9d2edf79c6031fd0096ba76e16ed6284bafff3f564801a6aca9848cd2490761bc1199805f6d3a78e8a4f1246a3229ece46966a1ca7cb39997adb142b9d384abfe0cf78bf99a2adbef07b50151486b8ae8138f106486aa0da29418fb128c7fed23a274301890a9017fedf04edbf6bb13d3afe6995b13d4af0e787fa2fad1a6a832e3aeedbc2b65b98619388519da8d5dec3165e16872ce6e319567db8d9ec952e7cc66cc9c30ed941e22558d4966730ceb109e6dc88ab1ae0c98c19c589ba912f42711587e2276bc37f9150f1b8a888452b3f92299856f66441baed4645604f4e751d38a0da02d6b7fa113127621c7531e4676a52dd1f4563f8e4d10bb102b1580a26c40bba010525f83ee35919bb0bf7d6f6f2acbd5c49c93a9bcaa4e48f52ac9a02594dd8487adef422da92443f22e21d3fa95fe6ad59a4c818db897a03410199278d42171f3696e6b7f21609435f74a421c2de5d3fe4f53d5e26276d995d81da60e68ae360cbe2baddf88b080cf6cbe8b206189614b3c05f26998def821eccee56523423e775e0a95e1e24fa260a86e1921f8a39690de0dceafa21a6fce831fdedf6abdb159b0cf88196e134bd59636dfe9b54a1b0f7a4528bb2074cb795740c185b1d5a592adc303f25e37a9cbdd74ffd9d5a539a57781b8d6c9ec4bc8473501b89fb07f39b15db893804adab2222f2c1017b493d3037ea57f34c97c637ab935b13c1f3f5c9ed0be9a7a7a01aa7f115faa3a67567257b412318c879a879b24c6336c46d4950d118b6e8ebfcda121e0bfcb4975669b48a687fa04ebdf05917a357bde0f01222bfb82004bf04c40463237f62bcf5d7f9960f14bc2f365689f49817b15d352d3672307360bc8bc44b9924f39deb4f6379c942017451ef052b2f8f3d35d963086079345dd84ea52915ca2f498621f40b8523efe54e98c8a9a8421148306b7aaa69d5c253f3389df10d02afe6ceaa5247756d54592f01a332893566d50cf24ca505b1754ad6acbfe7cb9be75d7cf9c58fd9ae0be7a7bc40def3c3f7d3bf2f579ec9243f4ca28856b9ff218223adb058662c202a343d0a86c5e39ec3cf2449b615191226b314944c391964555b73cd1b39c4e0e7826805d5da28a17187f059c8203077714263d0dec2dcd97294e02ab452df0ae642201abc08bcd1cd018138e147e7372a93524a9a8ad87569d7974ebd2e43eedab2c2bd407d875536e97b6c5ffd39bc529e3bce5b30c520aa19312a887b4929bf542df68f93ed7c63624950fb95437f26573280ecc4ad1f1d3d3f77bb1a857d1cd800dab0414fcae73698caaa4a2af2e067ab33fef92c4497b12eedce558f5daaa94fea7ea2f25e13b7ef577575cae7c46d4e0f3368b705ecc8454f11cbc13ddf7bd86992f65eb02578abb315ddd1ae04dd0afb721b13f693e7bdd0366ecbb0cb14ca237a7dde7e31692e0a77ffde997cf7ffce9f19f7f34e495be6a968d428a19b26a10c74d9585a098445bd51023f69418b85ca34f8d62f93643bfafa95dfc14fb08d01a2acd7bd9546c66c09895b673f23ee05592a3693e943ba4191bc39d6afb8c833a4464649b5d44415d95538ab1d8732fe01b3755748a7e73313e594f5b2fb6161f7e6bc583f9ddc4489408968d7144817bd0abbadd185701e01051bc84ad37cebbb7930de699bad7f6a5b86a53d99dbd1fb2b9a25f27eeb374cd0084d1716fc6a7baac03d71c5a282f1b90b408c00238042e4ac968978bbe5c8df21c3b8044e1aeea69b4c5536e12fdd62a149240bc8029bbdf97da952cb5736f450b3109882206056a8dea9476bc30d3c0dd2eb21fc8bea9b68280f4f430d29764b673a3ad09626cbeb2640fa9385a0b624770d5e3a171e882de746e6e5301f249c9508b6ded6acdd42f8922da1452f88638f1db40bb3538af3b6f8dd09ffff8a77ffbe1ec22f0aee392e64e8e96973446a8f7f1937d8e8854aed638b3889cb17cca7d4a18ac2eb4552973cdf30190d58c7b3f1f7332896acd680f77c690ee6b9d9f4a7ed017cd377abfb169b39b2dcd9e5bcdfc5f7fb419b0ac12ca544c1d0987126271cae5e6d0355e145187a7d0dca02a3eb3e61609e1eb2620795b64325c037b79ac33ccee168816b2cb2364744eca579bd8554d4e45ab1733136c01b34b10d4de669e19da20c224f95c06f54ce0f349fcd7b2b7cd9d19d2f6ee60cad3d47ea409cac3e446f25a61e2c3e749dc24973b9b088b7289f049cc2ed55845055358fd22d040ae23acf2c52c4b584df0742a534c3f40197972d86649e2d64d42daff1f796fb7e4488e648dbd0a1e200183ffe0efb2373f93a5645926995a5f9a76ee6a626a9ba509768f55f67077f9f4323f8e2099596476cfd4e4a87665dd950c92c10804e070b83bdccf29232af2805aaaf0f37383654900bc50681120a2f852dde08b0e58bc19a1cceeb9da80091bcdf111915a35d0a3f879f09f635b4cf03cc5fa434612f646046f84a94c0e05a36aad0f3277e9e7a13f6bf4675d108f36f73237146798a13e24ce4530713bee6d0cc18dc8f40cd3b426f12d68b37a307c35658062222e88732bea39071a4c28a6537303bc841bebd528f3d86e73a0c229b767f33841d988309f98c5a6b2d8d912a7c5438ef9854c0246a645eb00e6535a63ca9c321d624fa31ff7d89e45a569ee8f369f4cf65a7f46a232cab29d173e8cd4cbc4bea189aca3f00e8ab363a0284a5b4cda52133307116d2de886dc7cdb861d8d63eea0d66c1fe0c7d17f4c2d0970c7ba3831bdddf57cb422e264ab5253330347c31ba9cf8271d5541981554fc0a78590d562ee16ccc1e22066ee09a0ceb59909d91ddcd9f1401b1834679b11eac576799fa93ec857b27b90230b63b20b38953a60e1c5c113e8f2f8b14c0fa8a672dbb8fcfc1f5775ea7f5cd3a7c78f5ffef4fcbfffdbffb5fb74ffcbc7e7f72135fe06ed8a5da911440b32f72689160806b2c9bb9a83e0b42c18350dce1cab9ed9981ac0f59a39b6a54c94d50e7452472160136b96943516939b363506bbcaf1721b9b0eb91ff722353550260f5d22328300090a9cd29600a662d3c926ee08487da56c23a8506108122752c0a0c36114f06e40b0c8e679eb290b08794deeb3ab3101c6738ba0380c35271d2b1e1aea804d52edfafe87726a1ab6427d5a531b89eb5225f5615696420913b621d9c38a526293d44bc0d7921ca0c81631d1644e96bfa93de51e4df78c346a64a8ed624b95209132276ac70f623dda61032b2fd625cd060a1de27d61cfe2fcc3a637ed3986ad3b780e7c6c0e54496d960759777aeee5f9f01993b2624ca1de1da7b52d115981922ae83625745302d5d9d2b51ef7e65a672762a07b9266a3d9a1d4bd8c816bea1019254763cfa6da2325334d877d035a5f8cc1dc0428e0bbed488405ec9a04ce9ca8aef835d7c596c702127a546f8001993bd2b0a4da223cdf81dc08ab644e54506a54b7373d9b6a40d196083ac816a6e2b5ee15414873706d60127b53d15a4f38834cf08c6f753f32eb1ebbe88c145d4e19110d96cb631f3cfcf18b1052f92e8f8b4d187b2a20950f0033095f1e47f66cc48aa1405cb6d3c56168b69e762cbbea4074c58f949c43dac562568b796b8bd31f9535b1a9c2c57e1e7d064cac8f56fd50b032a2c6bc813c0e35b9832f0efd210a1ecd042bba8c167b04acb1d6979b349aa1061c0e444e860303e7e2c2d1056f40360dda5b1b0fdf5ed4edc8d45006fd84e25a51617d6c47f7951abab7d5a07d80691a222a8ab1c69be31ebeb006ee2355507ed96ad261d30102ce26ab797a08708dd8cce61cb66e59cfd839796a283356bcca186b9d008fca66ba822e81aa4fd38eb5894dbe91878deef3138e7b76dbaa269515b3d907d6ed93964d2c7dccf0e4e671f08c32aae943463e3c348fc236b655bb27a2e39e90770b1eb20ead67ff1648a84e48ef0aa3a7a10e004cd636475de8a06da1c6715dd331f3228597963a76191ca2b84c55edf0d7262b6b2ad6e10ba63c86d64d255b3f0441f846b89a5d0cba0297c68d7df46d24ec836c93313624a69bd54a6c9734b13fd8c517823d8cec5213284c6f34cc8462873664bb7c4d08ba961a158b0e9906b0cbe21cd81da9cbf6ea7f4a2ade48aea61e337a4b532db02bed0a76cac1be1ed3b8c9303632b65c5a715bc667c3ba5d887df12b48fdb15163b2198e005e3bee4de5399e047432e1dc86250dfd1787d994365dcf634a66c231463b91f55a239f7c7e9df38931d164ccb2de2c7e2d53f73b1bd6d547c2baef3cd0662d9a87c1057ce904c2755feaede1e6486371f6b57a1b55c1f976a2590cf30742c124097de66f85d15d6c128c49e79ad78f0f89cb716fa6b353622c6e1ecc6622ca28e83d97add383dae09ad84ed902da89c9b30fbb0b929c25dac7574dd2b0db6973cc4c1881509d6400cb9b33b143ff601c08607bddd73e683617f7de3771273dcc0e31f3c0da8355c1ef828973bacb1ccd5ce29c3919db881d0e040c217f1c023b27b2aee119538beecefa92dbade34bdbe670758d79c0887a3f98a2758562f3128b92f5c01452984836477d026366e1d9b0dc9cb42fa60e5c1e9c366d91ee71298978aa79356f859db15cb6718ecd6ce290033a602ab2eca2197d42a289d688d344c21910001c6172d89c54a7cd87ca64c49db155a4e2efb926353fdf87926cf51578517061d3102467b22fb3e7f96f9741cbbdb0c53415b3df8ec659f09a5bb08b0f00f4a47831a279df36845c6de9c082669d60bf706bd93ba136333c31546eba42c1659fd7e204f17ef2d61108272464b48793c278a9bcc807ddec67d35d32eb9dd5ee7e16ef691787291d65f6e2d86c05e8390c5eed1e1fb085f33c329087ecfaca2f66cfc780e5d35d9cddd8315e26295462daccfcfca2192e957e739d8bc754377e12252a081d417da6ea9c2b8a51dab9a62b90599f32ae652915d3b2598f7b6fb46a2ab4b8118111852585d1209a0285b208e4e6623e8eb95c0e14c8d845ec522362640b189c8aafa5a1fb161f60c8046b24b6fb0a220e99031c16822743f0a298b1fa2250630a737599c094b22ef4315b4c130f970b753e8e8c82aeec5cb47a9283ec531243c16e5ab9d2c184ea66b5f8b28cbb6fb21c618ec158864ecba90e1f13f3ef79aabc29629bc060b56cf5d5d18a2b40918016c36e9d4139c436551143d3931e608e05c57ba6c8c44e99e657af66146672e56f2e93bb2825153aeea5a1000da18658674f17f88cdd9678f27d439c3e5daf867243f5b483ed19ddc73a6997cd14f0de728fd28fd8d699c26eba646cfcf63679467d33b5d6388d2f6b2be5d49d450d7a608803268d0b131c76b02990065d848382b5afd8d2d75b6a7280efb278d90c0d93792feab2c5189a7275a1808022098fa071cf365ad3c5e508a7c10247479e0fd7e91ee22f72e0739b9d0ab134ebd625c2ad3467ae62075446650c2693d694c73a45aa79267f010c0676b68b138b0a8aa3705bd79b8d16b8d639b4a43d16afa529eefca02e121ab48899d67e0807d11732d4dc0cd03fd7f311e63a4a8c148556be6e6222ab9b04716a3008019647ef35cc4637527cb25c38e1be76c044704b7dfa75c3340eea2591d484788a5783da15dcec3ceedd3f1d08cbb8cd0b6334b738b55075d31bcbe10a7d6ab2b75857749be10590be882b365f5830b7e01bd669479faf77b2c25d9560798531e26b843b6887b95008616d3a2deb3398924af3d69c34c8e219000d418d32d74598424863a807f4b2d9879bdf81b9e6f99379b82d01e346f13f99aab69ec2625e6c1cdcc2ebe4b6af27830e3aeeddffec28d932492d80c181fdd8e02722ec654a4d923e16f114eabe98e98da0a8750423c3d56d0df27e86d1529b59a68c888a383b82c7811d249ddd9680f74ba121208dfb868e0d017868408b843ddd25b8215a3d4a2c05e96e0866bb376fa3bd42204dca97cd92c008c01e71fbd68dd6616a82262c3a76229a59f1b5a124e0b8e761f3b98d24e0d9b56e4214bcd9d9d36b830280219edd94f6f01764a3e361dda7aaec7f6035e1bc2ddaa433b4ce0959b0889b6b8124e5986cf16f7eed2e182ab7685cab62bfb49a42c50c20bfa5871fdcdccdb07e660a5d46c54d7773ea6422c19d73fb691affcd7e905d7181e6ae4d3fc266c001cecdf412f5b8c76281bd6888fc0061478b6980f44e5d28604ac4cd65abbe36fad286984a87af522fba13532d3b9293cfaab3f3e0010dbbf0665fbb0e321f163a0757f6a81c7b5f537343e1b035a2da9de0043066e4696e76379c578f90269d86799d9e313c15a850d7663d8dcdd0dfec7b3aeee77e98f9ddeb6691f6beb87d3afd9a3825250fe81d17beb6f955b6c46fc738d1f575c00a0ed5e887be62655f704f6184065c823ea35036e8b8352c5feff18be3d5bd21e76cedde24eba2d13cd9849ad9a8becf60e35ca60165d347d169dd1aef4908f6381eb3835338ed6c9855341904e7e16a73c839aeea712fe5e4c2997d830c4b6ca8e888c40dfeef20284706be42114c7b13f3a1a6b0e6ca2c6c7d8068dbda4baad3a51b9464334ea010b1ecebd4cde60e37e7bb747e0aeb34451e64434eed3a239c08802ef668143de37fe0fb3e2f87c0e07a722f219b15ab36cfcd3826141d878a40db483adc2920402e284ea8842852dde6dc8c4a9e62f88bab11378b200ba522ae00cfac746c96ba4bcdf09acd6d687d5aae3671d693ae025c5536add19d20d3ec9f4a51068c60d071623ac2a49854c61a7a6ae211f7e269651dacc713109f09364787cf8c586919494d358b4f5c0f1b03121894644ef566d66f35dd55110f1c23b69e3aaf11641bbda7825de929dc80c3041e266df360083698614598d4df8f12d8acc98e8463c4ba719f21803c1082e55992c7cc20b2fe40dbd163f30d6e532d39157451c1f66c450451d0df48b0ab36f0e43b0dcf3e15cf46b77d6837b2d1c612503199b80700ebb5623f77cb06a06a6c62d8cfc1c02d8a332393b0a7dc05c61ae9d223497d639f74ae7198eb3e3f7c39f3c0b20b2826a8320c2ba094c01c938c3aef0ad7bc6ffb9df0c2956283f2c0d6a673d7376403555d7109375a7c90a00bcac09e3d4385087c054a65b189d3234043ccd3135c3778acc056a1d58d4282d95c3cf807b23d676ee0e9529becaff3412acde097635c386c86af0a1efb9896d23cf23bd8c2f3bc8506b7d026beee0e093a20aa0da8864da6618b5ba112836708bb9379243e63915e30a5d3243cfbb5919920127c9382c698cc19dd2e1f50d0983d7212b15bd68e1f3803b7810a2795670f016c9ea53d1782dc30fe96883205f18dc869854177ac673b789642033ca0cca88ad3916bf56082087e96310270f44e71d802eef446c70f42c8c0a853a4378e6a808bf8a60d401b1d8afb90da586096b889e4959d34c2b41b6caac22ac7f620966cd87950ac730db349a0db9b6e0b57c841b2cf21f2588dbf639624ed600a157e20f6cbb6e01436d1b0593523e1d627f60af9b569614331e2a83606cc70b384dd5ac23bb376b0c101781d901dcf3537cf29d9b608043819c1fe89e5c5e6122eeefde99b66d3849f3e857accdd95ee4056fdb6cfd9d8eca919489092a41ef7582404c47465716b0e8d4794a28db9d1e10a603adb1d61765fc2b71bf93ee58c53f5847c1a0f77cfed3a8f359aeb0d071e2b1f66acf9fce3f8410705c939d5b26c51ffd374ba8863e438bf3d592353544e81c702903662df56b4213cd824b8995cf02a63e06aaac1ab73ae241efcb2fedbfff171f9f3bf7cfcf5d78febe75fdea926fbef8781e0da6c1a6ab3d15ec99620c70131230c5b90c2380ceda9102f0cb36c434021e7fff31d078aa3b90561963f9917833d109e3bc7623a1d294c1d162b869a18468abb2ab1e794cbbddac4ed23a83906a3e29aa522b868eea1acb0de6c3405f47f64cb6ea016d4b74381196fcec1a302c54012f535569bd722086275e440801c5504193403f901a8391cfe646103bd288f6a3eaa4de11579d555e679b644f1021f358736a179bad71d6959fda482a5c2cc14f7f13bc05f26fe4aa9a9e96ab69b044cf9681a960bcec5b4288853db6484c1034018b814b6f821a869e6664356502c66c7a03ca3c3b836d7c833278022a6e03d03f54fd936b29a136375738fd52c0a984aea2c1c28eeca00ec035cb8627f9e11bfe9086bd5322b5b03694384ba00dca551c45cb5afcaa354001331e7b505b84ad89b30df43e7d90e3e03a1e3ee84495cfc1a04053a47c5cf135fafcfc7fefb2993f373f773dc6eb671b4e7e71a2fc45b91a4d27c5f1589ed145a34b5e6414b8425711d3cc71c61fce49eba3fbd438434ef95e010261e44535bc8b15f3f517deb4c7be040c5e5d15b24d5ec00b4c847c10d32843ed5e51bd0641845cfc1e629854d81230740964e9082605280b8b669be06cb856066a84290869994855ceca28b1d7659a8cd7dc3810abbda7ca24f213569c600010eb2559f0411483b55ed52a88f398b3e4c380e8e1fe63cfb820ba088c6a716152c1702bb4683d8ecee4ef7b34dd4d0d057f323737d5bc07e6b07c2b72dfd516705b3c3d5ebd410111a6238bd962d1cc87d2a19d054d85d417f39e0519ef11354d7f82eba06282414c31647de6fbe576cc6a8b8520baed40082eb7a090e481f80aa32bd18a0170f48ea91d587d9e79cab5768dd29963ef7a6a8131e18388fcdbdccf228020b416a5d602b2bfc7d33bbcca5045396e77c094770073323444d32e704ca80ba1ef7177302e61d65d3374ed35a2bb683e187606b0c76131a89bd4a248c11c5167a0284cc704664a4a4a0c2157176b3318e7b0cbceb41808f42db6770f321a6c073b83fb298262f1360d1071fe37ddcfbd26e2d5c68403d615941b2bbc0ab34754918a4f9f48a0c5f75175d1cbfdc371ccc5dcd35928d7745b6106968514b6a40d040f8c7de2c08c4385b6b87bbd251b483003a634b8219291c76fb661e4ee3a02851ca30712a9e6338f16bf48d79457cc9ee5a8f1fa89a6b16a4d554f891dc86b2d18da7e18de7e18d17c3eba35bb7c135477c0e6e3fee2f35deb20dee36b6e13cb6e134b6e134b6538bb6b88d2dd083e6d802177a8e6db3fb201bf1727083839850b831b248ef3a8f6cbc18da7831b6f13cb6f13cb6e13cb6e13cb6419a0f6c044fe47954e369542f06356ea31acfa31acfa31acfa31acfa31ab75105240254d32833319d91197d1ed6db7517afcdc16b56e5eb73ae59955ffef4972f9f9e9f7ffcbcffcbfadd81af72a9a1df13204c7ae8c10b2191ce8bc2016059003e9fb56fff9e599d96029f46d67e5f50fa862245c0c6e00aa11f3f88f8b56ce9079c44ac133665e4d456f315d5d1cdefc107a50eda2f41c01bea3f3fee19a8944ea835428e8aadcce821bdd5199e87a9f5da519ade525fb08d4a81c0348bba656729420d6c54a8f41a1b64b81ef760961573ee16f250339604a7b2df0e884fb851b328d7b310d401ee1d6dc3435c3898cd2d2075f1aaa2368bc22308e9261e805f755e07ab49006586a7f8d12a9a60b0f02367c06c0c41699acd5ffa87b6d81187409e06ec2245295b1ea6c2cc724759144625882ca54fb646e730077d28281b4bf40b78193bcf17ef0d072d4301660359a703b4f4132097b8f6736ec3d03df9b2fb19f8d2515e9cf501176a4ec3cb911afc090fd286a64e35d1a2b923f5b8efe8555be4d78a62b251d35808559860b57034167b6d038ded89a3039460b7c4a1f6c157881fa0ca1e90545e6f8fccface0921ff49d617bd83c866c66d75f3424f5c55362fce7843d57c6f4aa6a28eb88ea42b659020b57e3f005542b0946db6032e0e5598ae2e324ac16b7460929e34f68a692a204f2d69380e8b3843843a8b64f1190668056a139313e97a7ea43ea8e4d45e0ea0d89da8d48e9c5f24759f141bbc040a103bca219d8a4c52f3c336298bb1150a2a5b6acd919a4728c111c41c9fb07969363bc7ab2981763e006f82c3d061a3064814ce52017a4954473be897045e9bd3578041004cfbac6d05209069d5bec4793da4be44de5eb64f9d5c1594be0989b1bed803cdde9b85977f586b2bb443f7a27dc0618f65781928d5497c8992dae68c9576fa48b2c68afaea5e4cc10d87ba40a90a28012018dda1b6b027d6118416402a3b2840aac8849a7a08b3370d40c46aa4368008d90594906d99b8487894a97da1ae9c785a9db40d4fdb6a62bb0ad69971af66d805cd12b482590348ad7e3c851934a9b18124b43ac0f6f183ad99e775f6d58a6aaff7bea2da79fde5ba3ad7da8bd53af4c557eb8c559a1cd6c9af83423c703e7b70a02044cb91056c25e7bff7c4483e72349149c93adf73a93f7a05b10ed0569479b46c382e7ea1096873bee86f6abcb774dd152df7973f7efae9f3cf3f7f8704be95531b2308c095f5bed0405d9ce9adce41cd4aa9ce2b26360754ed1860d21510c1d8e1421a5bed0d75cea4c05ec81a6beabd2529488f6c99fd10757ff99e69a4ae3d580bc40ce69e53e9288e055a5faec36f354a52e83fed491401bf316a1c943ae2322d55aef7b0e1d9c63da762be734eda06d0904a4dd95c5a5ea8955481a6c5bd208655bafd3a70aea90d093cb27583790df684dabcaa8d7766b0f0382042d3ca2ecef7fef6b86742e61960e4f9e0b9b863b175a0646c480cf2bd5d416c98468f360f4b0724da68b426564fe81c6d2994c0b65b935467296b0a1c9cde7cfe8a0ab81709f5aa25a75624facd77546bcaa56f4d7da03e5269a7a6de12ec93845e93ecd397d744fbd37ffc65fde5cbf727daf6d3a9aadcca02a8259b082287bdde037e1bb7c80084040291a90c72ce3c3b2f3fdbdfd36fddb28f2643a69818e9b319b00cacdbbf7b02e882b0a389ce632ef5d93146c1a271fe174f9fda8fcd6587e5858af26eeb9034373b2980bc087ff0165fd8dbe39e28c35ca115cc484377405b5963c9767d67aea39cede3b5382c6c75983f5823a1468227521d61a64e0f1634f74ecb0c1e7bf3d1d7ed34f505b1f6248f2ca6c5ebeabfee305c73f21d9e1534973c7d19606ca13e4fdcb5c117f6f6b6746e4276553ab72faf49e7bffdf265ffdde109d84f5b497c10333317c0484aa461c624238902470ff6e71e7eae69c51cb462490c6a6bef935de13e3b052c3082c47f1684777e61f693b7ef71646798049bb8db5915d7b1051f108ec01af17fbb386c5c9d72545d5c07506e2a8c2855d4ed02791fe72ed191dc0099edd70825f5d3530a701ee7a7f66f3653d206fd0293cd7f79fc408063a65e0fd21e5a4ded10a5ed9aa472dc677393f4604f71fa2ac9fc127019a42dc95a109b6d0fa3a6be56750af0660a3b0354f7206d670e152e4da3beb8f2e99b24fe5d74a8375cb9227fc0aecdc2a9af8e1f6917ff200d64f852e655c648fa245276e30dded229aa57051cdf5c936e3337de47f1eaf8bb7198cd82333b905296e0bef6b0c3ec2ad03fbf08cd842d34934f96e48fd241c2e0dff7e39eac4bc5d76bec0f1030568a675a81092273546c04500682505224f7a07863781c99d8cbfb4dd38afd0099e4356501e9c540f119ea89c8be1373a4cd2de8284d100d35810a0e090082749a6c7754874a04894d319b5d112c8d8adaf4c4636e74a082aa200c9e09164c43c232090afd809f031c2f44001399ea4565f04c4cf51c64f164ac197b16d4e94ab5ab3a50461af6f46dc4ea89b4c84969123ac2ee63eec4708b00d3e3326b9a41e79a86b332948bcf3db1bb9837997b704c2a24c9b04dd4da03b26c0af6833401490f481929b369ffc65e43c2ead900c0fcb7aeac489f2cc3c16e24a786d2256a88920080ab29f0ff251654f623a78a9c48a6e018c9a532a2a48164c6e2bb5a04500acabeef55510e250858f1a417c93602b521d97fd6387abe3d0272d6149d30024c0021c949054f5452454177490518120ddb591ea5ae3578574158119827afca04912252208bc9e32cb2454690772ba3189a129b66142fc3c888d5f401644b987c34c08e8894518e9aaae94d3553bb00cd530aa021b9a2b50558fc3564f07f8e99e1e2441f0e50615d5f82383c71c5662f5754cf9b196df76825351b4a2f51cc11f439c8a02a2643ddeb131af2b13ce9b6805292807c21be1b1d68e6dbd5a09ed0db5014835c57cfac1af66b1bd5eeadcbb82d524a3c8fa43b200c924e90faf44676852bc6abba14df7cad4bffef3ffef23e9838df60c14a05d601f5c40bc82acc4602637018b69e97d3ce6f044e6e3133cafc69058c3a16db928633738f244e290fdc2d333911b9043e34b03a6343441af40b88b6c8b81f80b006c0546f4181d5670766c52d4010197044cc4d428135038d8b82301c1b707698c436a498c5e628ca880f23313e3467c905e2581ea91c3f90837da9a4be6083c4a4099a8840e26306af46c77607c89e2df66081f0848a86503923ae9f9346002737bb8e135c98f204478228304b6112790cd9fc35046c3cbed39cce1ab46205e4af230c0fec4257ba8407b0022091df9c8c989069666e5e895ec26a93003028e07e1fb89278ecffb81740ff5549e55ebba3b920302c660b35eb6b6b5003e090ad0da84b4745be439cda4ae650eed1617b145c4b98f9f74e874cc32e83f85b8709a8dd3a47eb529dd20de8f04805082dc1aa43b96ee89e53ecd16c074c0555b35fd4b300c46bbd15bdec7cb7c83f5037de1228a500cd8d2249e81a90cba51e8724f37794f0c0f748ca812b542878bcb0e0e17bd225b5c96e19275a5c05b46c156f0605870dee48ae704516fd4b40d502d5bae4c8e2e380f0ba43785274c402649f4105dfd22ba624ae2815fbf88a46f9fcf34fdf27befd3f0d5e9c14acc09c133f0ccce792bce8dc560f894ee4b6aa8d50afa92d202075cedd1c13af11f25c748966025487a1a580dfd1ce3cdda520e03b504a349c13a5a7b602a5bf14734a20a326031dd878b6b451e8aef56098409e274d8ba92732ffc0216835d12317c4c17b4dfd9018585466d22ee0294a93d3071eb3350a5cdcdb83e22269c44917d3d66826984dff05db2d0999cadd66ec98ac3404550adc7f00d66a74be6e2729b6671e4b715ccf3ea134edce3745f62485d704f7f4e575f1fdded8e4cdf16c8129dba0820ec00b6d0194d8b0e96266b91957a163957364446cb378273e0cd03a38ab03439759c7a2684dd76a434549160855e22988b29a7e1b660ba16e59cc0a72844b0af3c7f440392f1e4472e607b8dd40f35c55a1cc6d7993ce601e49b44678d5450e491e459c7b0855f4a125307e2b40821db676172ba07e9bc34482442112522879b5c5de546f4f65d944a7d85c1cd93d75e002a3ab26a6314dc855e715c7d1ae8214caf9698061bc6d63de24c63521b921575f4bd4bfdeffb2ffe3e79f3ffefacb3bb9acdf1690113ea8f687fc24bc53902348754ed74701193b298366b83d7aba8900090086955749a38ec434677f64ca76c61a51963d6817a5ac0d9909666d1c86a6f2c0520fc85fbdd5bd173d76a5972fbebdd2d91f77bfbc0f29dcb710ab00ed90570dcc4eabd5802d8e492bbee9093721ceacfc31418cc575e2583532e77b5f576800a4bb38c72cfb6e91ade3c1838a419cda9071805d31137a4767a588784d7672250e1de69c40d7dae87249e59e2b812fcd8c70c0cddb3d9cfa157722ac39ec37303b180744736bc996ab2078b27b197603f059f0cc94c216a3f7c84d01b051bc36f4f6f9b541dfefbfbf40bcb29745174ed47e60b889fed7d3b5346767f95862ea9e97991a28681cd3d2edfc49818e2282d0b397db81c1b3f7d4da7367e02688b9c49e4d5cf2719f03b666da02a42e148b00f60e75d57029b6739f07a2031d29961757d6250d86776d9a346c6da28f0c48429ec084d9c5ab7790f194e307ad485263694b4c0308cb699488045ffc453e4686bfe4650dcd492d1940c3859edd1be8282617b00e23c9f7232abfb65437281854b58451532d1f010ae2d020933ed8d61a4f9f593b05ce25e5ba03ac5d6b91b3a422f63005e81485b75f39768a39f98fd440026eeea3dedb38d612948a570b21690d116d444254fb471227e4f4176f278bc37d0c989542f3afdfcc1c3ca5d4da926a9d4822c3530925f53acbc7b47938bb39788202fc1104447a7385f22971750ad917d7e6d0cf7ffaf41fffebcfbf7efaf2f3479b431fd7f73183f8ef4673243673b7103f0920e3c15ca07d574aea6b47868ff9cd8f8c007ade154af248dd71a95bea4f857807d69edbbdf655275cedc2afcebad59fefd2855cfeee18351504fca8a4fe58816d4ffcc0eba89141d60e7248e44d99d1c766a0ab1f99b74af7a03a0047092cac1c6c8ab4901fb8e8c1bbb7247ac20d7640e83eee918cc1be5bc223e91215ac7711ac84d84ec31121bee01959200c089491fadeb6c39d9dfca4f53602b7f7facd31bb364c5fdea778e81b361264605d9d1417039696229f0e1c85596d3df59c401b0e758e9272227a310fd3ae803c9d82c80581572c7af0c22c0f46b25cf54546c2c067f32522e41407d0218643f8449eb710a7f2a009e6e385ea13e3bd208c3450ebe655b03d96d41c6f9ee7cb33ac74b87c19e64f5d62755e9db9df2b9eb5843a3cf10c2875fe8b66964b8dbd4050b2a3caf324ee198eaa5fbc179a63043b263e38176073d9a501798dc2f3383954aaa72082a697faf6fa6cbde659670c2b2d275d406ae2b4209346ed74f40cefe41c925c90b6553df65f67880d953dd52661763a0f8c26d2b291eb509002ca6916de53f6647cc48a9c8b0661c244a1c029348f07ddedd950929af348a3f2d2015ad02480dac3f6524fa9023e5ff478df6482d2991a7afc60d27bce771ad8a6a2cb7ca71f33b29cc65447fefddcb67adeb29ae822aba90d8f7a02ecd0b1e7d0c2c812799290300767f52bceecea7c09031c4c3d0890e98a13c2e824c6234f2704455bc3463bc2c2a63d2077e4b6847ada3b8b0746d9e372a6ba902858c0e1d49098089e02544c63ef29b21f23a4610e28e8fe6dd6a0a8bc2365cda36ad8f400c5b38d127ccb2d5658ecb99a13e5f4c8a0b529b09bbb4fa4e204887000bcd2c259f73c1f2f01b515a9ac8860221ed9911a1f1dec01d3ae79f539b8953b48663438d0770f0d91a4d08635132428cec9bb258f016d1de9d5f080419535cc6347822f222ee87c582608f904c9fe5ab112940e16a2c6204101dac676a31275868f810c8e366e2120f7b9d9c9161a58bf68236d2575269d6934628e0b7c1e6c854e46a27e3b7069dafdea62f0e54afaffbf7e5adf87efee1b223f0a474b73125ec740c9614f95164c574fcaf42ec2ae2b607f1b3d22c9cffc352d1fd951acd9f1a56191f6e41c5315ae249d5edc261da65e67ad91fff1cf855075236676ef555134cae5238d0183d95fdc3a6f407db2d58a7e008e8423ef6eb6fb0014858ebc7a4c3aa7ce0bc28e1ed8027adc00964587cea2d5e6269309b5da13756f1e6f9e147643edef714fead8a479a4c16be9a95318f8d14052efd85c0851476f1b1da55efee25f15c087d6962afd70e9754855402db4bc46ca0568fceac834d971a20018ec1c0180392c842478b276752f32e7c4f211fccaeecaabd711e45872528a158537f67465fef56f0518126bace02c190eda3b9ca050e7c2885d6de80713825a03d79eaabcf49c14302104efa932402372a28e6ead81e7c6690e4e842bbc52761eff9e93eae2b313413b807ca11538c40ef5130aa5ec62d579eca693086a606879c4c54d55f94b9e79c88c9dde7c3be666d3f3da5cfeb45ea199fbd77743a3ff8630d020543aeea8d7353a0acd2e521b482bc51e338238b602e1a8e52407f35b75c94ed6eab4bba69a3b60ffe5496b7eb0ebde2bc1ca40136960d64acba93c51f57c29b235c2c4a48556c36ccb71cf485c2b75576b2af78c5c2919c8aaf74b92436ac03e2ac876327f7f665adba28ecd8506ce774eed600e162d3ae6fe42553f6ff8512bbe9b97134d9eb3d841e3c092785729e92323dd9d919debe47bc78da12f153c308b2e7532663bd361dde8206c49d8912d7e4f38dfab998adb96a8e05518be9cc65a7df5ac8ba2e8c12c5ba420a20f70d4f31baec60df8827fbd0e59f0afbffcf5d7bffef1d3f7b93346dd774439d18aa8224a614e474fec59f07687173b6517bb6141fb8376b0e99690e3dc298baf76cac2fcd07ff3726bed62dbedb88f40b7a9499e41a66a86438d1dc4a2ea5c73dd9334c1b9684a159523f75e7242dc83b3599f5e9f23c10ff0c81387969a175c834f140c3409a0d3cec582fd8649b7587dd76c3b78cea1a0c46abe5fd47938fb84ca725e7dbb0ea5714f6e2a75cf23bc787d9eed013315e6ca02063d6cf3e2e1800c0dcc876137dbb81dd10f743ab82d9f170277554e2fbebf29afef13546d7fb76f5c74a40a64214db9cb02e81f44d92a2a9f5b6fa076691513bd83ffa88c76afa5a7d62954b3cdfbf9e547149db37dd0345546bd92765bd325a953fc30f09632f2f4d2d0362f1dfcd28e8c8bf5b0d7d33b64bd0354e7f2ed730e00e5f71ca8f3e780064346702dc11f23a84f07bf534b9de97eb6d5e6a1b5fee2f5995a76138bcdef75f4737b0c7f8a684f41c19f02acaf8dc2d641b8f66c50f4a7d8decde6bd7afb9ca33f457cf9f9711f851acaa54952c9fd895a49d40b58e69a007089ad532edffe9604df96ddafa5f60fbbcfbbbf7e6f2c3436344583598024070686c56ae3229e47d710479186e121c4eadb4e472af2e4bf79f02b1cf7039c2334240dd9994b3b74c50b7633291694c7a3c21d891d29eb13227465d7cc5e3ed885c4b3da7bd21a8726190f0385b4003d69d8dc01b739b049d9a13376b6a8d7674a03856aa5c60e16234e423b5343651160fe89998a0d95ec13550b501d791a82c0dd3253c7341b6acc501b2fe0ba77e702cbaf0250343420e82123135025c5b31909118e0ef41746cdb03d7ab7f616c77f0d004f254d4576dc536f0b7c5573ef39d40a78eb541d9d451fcca01118d44d9deba360aba6f2e5f1ae9654fa7dad00c263f39fd511f22b9e3a071935892e0c829762b6bb667364cce900328cbb60e68500211684b16598cdef74aaa39a9534f4b901881319939458cd401c60f72f3df634e02c67607764e09c34ec23747aec0d2624a551960de46080807a448061f9e06040ccdcaae5398219074f0b245d1c1e5236378fd8e135eb823e02b2b30675e0e10efcedf3f173a46e6a18c59adc927464022f114888003b768c30be385c097c56a449b7aa1ec79fcb6389c3e643071210b06639915c1c3e0b80af4a4919742f262b0d3089c3849b243579469b51326a7e0f286db4a45e77d11e1114a45c7a92029884b6a1f2989365ee1aa55c01cb4f991675106602849c13ca74972967e6e1a464763949d4d09ba7d34edc6620ea62820d007f3b700cc0734da2511262c648b93c7c8e30df016bae36348e43da53b6096bfdda6dba55de10bd1d307200c6471cd954e17e23e1b7051d897caaa8237b23c253d174011e2542bd7218e67c3f483105ffbc79dc42137a050fbea36c1ae8d0b2f9a3d911826d16394e9c93c9b85d47ec280f007f406a2bd2bc7532ae98c79c06b691b1e0421ec45132b163d6350c4fbeee2016a106ae10d39b99e7e1b0999a91a80cbb9e6d6144ce714942075364c23b10f7d705284d39748fdc0177721ead290b44e3c6aa8425e6ca9a84cfbf5e917ef8d3f7b62f4da561d3b3f14e6a1af5915a0de67461b37afbeef8418a1792412d7b0a26bcad66070c78f5d6028efdffb87d12b7e3e8c7acd8170e554fc97755adf78ba302101fb8f7ebd9774af57af61d11df48bfe39253e9410aef1040d565a2a74f52364d02c54e48ab6be5911ded4c38ef62cb89c71a1b00902871f9816a3805c7b00f5f5f5cdac96e32e0743df5aacc8be3e78fa4199e0cf10f2c690c80e9dacbbc624590846ade61c5f493fc9c790a93fb4224a0dc1e402aa8bcf89ebfa78612796b71eb797cfca0e66a485db2279d7bb0af46fcb50700198527ec658db624c36ef0fa86d89de8c5a1fc33f2cf91699cd90fb7a8057bfe4ae3d8f8791e06bc5bccc8b067a820074acd2ce8a049f9895a5d72b4660510146c2ddb515df0a9fd2acc1607aa07aa3793fd7ef8d395f9f8c39fae4dc63f7df9f4fcfc2fbffcf2e7efcd0557d3eb352fd5013618a9daa0223d4435f7b9a24a4d233e8bc4bbc8f949fbd539709a66d96be27df61c6c2e5d4f71e57c75921dcc49e7bfb1518758f5effdd1711f997b145e048122f7d310460a559fe33c8e781b1d81ae45ff601efa17c73d614fc329fe1d5125fb5e12b397ccf3038ce07bca157ef9a841ccf7c341d5d40fd8af5cb2c38d484e148b39fdb59981dc52dd15303885e2f5440da5ff093b60f0d7cd14c3fee9ae2c285ccdf82d6a8cfcc8ae72b0bbdc16ed93c45e95f1d3b73785fdfee397775a82bec18be7fef764626bbf2ea63733b1f7d116b151ff29d2d46bd2fbe6319eaa5396ece09f2e4ba801175b1f013c296628c61efa83d40cae9f902376f2638fd632d3c4eaec9d765aec3b525d709e35c37e1efa81ea719f63d5ff22577d7b42d9acb83da1ecdb6b13eafff9eb3bed2a7c833977090036aa6fc567b90e029645cfa5a68371fe0653d267bdaaf827c73d76f1bb3e355e28536a604fa2ae48d021c221f942ed5fc7f317717e797b14ac2baf0e807d71a5ef3f7ff95fbe7c7ade7d7a2f30916fd8a49586ac3c61f3951eb903338175a723312fe4aa87dd90b24511b97df0c6e59105f9867524d35249058494c17101d55fcd97aac1151c2165649c54dc7374070b1f05330742b3b3195b76c5691f0a14e9a88f52e14b8e9ab4dd33b88e3937af096b1e2a37ff1b470f63247904a3883fd97d4472a888806e3d8906b808c8a228fc40351fa0d41737eb729c069cdb7687b1d9a117569dd9a166fa9f2cbe0b1bf510c76622c67919ffff81590fd17c39e949169a3bb7201945be27b6c52b6248651c3fd0f0583c6e53dc1ccde6367b128c9386650e672b797e1e2fbefd915ad9ca5835cc3730bf70d106ae92f3e97e7cfc2059830a5bc7f48c4633df9e1517427e6d6e5c7c7d6586ac9f7ffaf9fed3cfbfbed304f926dbd67a253f50fd7876a6f2140be1cb0fa74ce8cb5337817879ae4b03929d4b7da78b7fa0dc13855177a0a0a01f6863e2cb63cb0a281cbaa4f1a49af2b87682006753f80117bb72c6a8013f7eb2ebfce025969c686bdf6cc271ef6db0c7bdd10edceae09913b75bc2bdbfd514c939e571c0453e7ed598edfd4d213ecbe135193e7f7b4384ffb7bf3efffaf9dffef37b9461a5f712b37d8ec4fdbff4c57fb8fc05dccddf7fed27ed572efd96804d29b92561f3eb1b22f6f8e9dfbebbe49049b65b78c79593a84dcdeef99b5b9a13f78e194ced106de5bb7a4e2b20e7b3196e57bc724ac604ef72b8758d53536c70b9d4b75bd4255133dd77f566b33da6fb6e3607bffd8dd68c7afcafbc8cbc25ca268db7e4d8bebb21c4ffe7e79f76df9f1457b77c7f7fd7fcfe0e3fee15b98afc5e0260821ca5eb03b51bb24af537a5b54d71bd3d699045f3e6a4519993e624946f35e8b76673fb6dcd823ad0dfd02cb351dc6f966d9ec5f29638e3cb6bf2bc7efaf2d3e74fdf1f609949093178272a76adb15119017177685f0558b698fa8ba0c553d525e30a71fed8ff7f7e75392abff37ac2bfef7afdaba0cadfd4be1f07eab5110fad7a60a5d5b3dc85c14385828d110591b8ee20bb3df567bc0dd25117629fae8e456a82d816589b40cb065829584db063d977345aaa0b33fc65457ea0f9ce5a81f8bb22be47c48e9c86dddda06944f3fb42491495933c915e7f9ae3076ad52c3878a73ee91b48c023d5673f3aed8d84e6951b7ecee9635b0fc7b75da02219edfff336087fd3158443d56fbc42fcc67eb8a984a62eb9aa83e6775754d0fe8f7f5d3ffebcbc4fc2db37240f55d66dbbf1895500a58d027214ea69721267a00e3dea5000bcd312471cd87f3c7feb600d0a63fb6fd93412ced7a3f1d84c2a12d4963bffff79d488b771d49d8def9b272802325bd887cf8bb30755ce22e18eb8adbd2675d7324c9f5fe495be4c267d99a47adc936a6444ca5ee9c6520f88a4befa58fb953874a976fe952fd0b92f03d4a5daf95f7dacfdabb075a9bb52bffa148d6e35f0adfcdabfe5e97b8e9c3be4805477aa89d631d208f6e789cbed89b5cd906b136bfbeedac4faf4e5f3f2f1e71fcd9afdf8f34f7ffdf8d32794cefee5cba75fdf0b6be51be61b8f9c8ab6407da42c03d9eeec0437a4235a7fe94c7219b16a6a40e1eb5e0381dafe468933f0a5b415e43834f048955643c75f6aa98f613358b1fee5e619acd4e63b94acf140b97462428d223923eff9249bd08d4b909cbad6a835110b08ab0a28df78f4ed5d2aa5851c87266da0dba6f2e2cd1a6b4d9a41e720da96389274e05e0df0b6745b881b52c3fa003a63a747b0db587735fb8526aa6d5e9a121150eb3bd279863a452dd38aca75f6bcb5f148c8581aa9575a9c06ab25d68268b4106a785a6d0031538964868013f3cb00af3fd25f9380dfb475f23a289b3624c1be9ee76a68886ef7946bb3994ab3640a050825a3b0b2cccc3742b654c900e528d953f490a9581b7b970f33496a437a5313305750af9e9207ceedc6d607438bdf53424f22400e6ee2101025f8f738b9c7f9bd371027b09f0d5c31a2eaa703f08b43b336431291b1830461200f025690406ddb8881aad943b72e073a0791278549050a25c05bba5745158f022235bda4ae3dd6247d80a016c5b1208db1d105555f81199398eb710f0a261ea18ea48d97680d61ef5890d28b20d791bb67d70bcd771fa5805ab9788a086a9ceccac57b7cc11aa40c22eb9efb1c87cb53b091827a2e3cfdd8a4e0f22ea6ccb54258f0349550f19c1d8b436444ef4090119598b835175c800949892fce3aeea569ea4e06cdd21693fa1e20f50152ef7dda22a43e4ca9774c72948299d817b3cf0b27b3459dcb10621f5decc314fbe8621fa6d89b021ac261a07bb901bebe275bccbcfc0f628f0745c5a70c457f6c62e95fbbd80717fbe8623fb54a9c6200b147116941495e6dec623aa28b7d70b18f2ef69bd4524e19b9b825fbde16e02eab0257b5894bf59c163e8dba4f8bad812ef67e363670c8e627ba11621f21f6c1c57e1b3517fb00b18f2ef601621f5deca38b7d74b1476af0d8c6774e7317fbe8621f20f68ee9493e3120c495c6143d3fdf4be00678d04947f06521f8b2107c590882e4c3b92c445f16a22f0bd19785e8cb42c4b2107d5940ea728f73219863b369fcb92c445f16a22f0bf1c5493658591cce76ee2b9866cda977a0518e0a1e8f5e741d9c7a9629bebe02c4b9028ca4b9474d2d23bba1738f490afcb63e152aadc04a29a661866b021ed637de611d8983989f3e4cc37f35b540983a01f313dadab158098c7739d739f3360587f999b8f54d6bd9f4dc26f17612748f4b7771dedd3eef135edcf56bddb38deed43dd86565c082f6d364b83ce5b695f4b6b973d5787afb27576caa9f97dd3b81897d43520f50a609ce8ab0e99ffbda12350e5a6c3ed880109834c050d0119459c06e024b87d98452cc06b051b379232552cdf36a0be55407cded5b67531f6c269576700769373ba6a5cc63be9855522163f6d7266ed7ed4d4563f3f68bb0fda2a5622e67a991133b8985f6e277996f766253b44ed310e8b4d462d7346ca9afa9f41ec93402b53034652a6657ef0a2f35556e5b529c34799d16c7cd3fbf488d2b7c8825695b6cc5e928c0b665bf2287346a870958359ad94afd5ebaa69c1deebd7110a5547349cdbab48f240d6ce552526389d0523450ba544022826429045fda00a45b3307bc817a5a83dd439e68a0594b9c4f1351a2e1ad0ec4077b98e0df6d0fe9ffef0a1f6864eb1010900f31bf4fc600a14467b0ab98cef6be8bde775b6fbfcbf03f2ac6558452a1728f747c45283483459b91461ccea27dfce065630bb55451f0ee41372993f8e2399ede791c2e0acf8f3c10154e6ffccb9b9a0493fc9abec017d7b4c24feba7fff1cb5fff687ffffd7d506dbe05bd49c11796e4b13912f002a2a5ed1fab4758258d95d911599c647678e1338c38a794cbebf0b8e4fc13edcfad731f85302bc54e08db3fbf1d4e59230153b8a241c02fc6b7c30134121df766900c5e09f534e756bd6e773c37fcc573e160b60611fb02dabb73d36f9edd02b73ebb2a5c3ee0d6f6ade9b3e5616b79f096df94ad17a27255c85e9cf1a6b47d8fdba9cc92cca61c5f0dda6b516230644d61bb261f8f42a0392bf52c76b7cf1d8e5234969712721e53885b9ce256e6c8bbc8c5445140953b4c75bf1a5cdd06f745d35fce935712f948280edc9afe729ebc3e9733cae0b3dc14c71733a54c7974998b8982dc4e6c7a292c6fcbdb8d3dcff309dfe5ce273b835e93afd4c91509b8a2275eeb92d3785d5313af870e00f93672b784fc2c49255caa0a1fb53d0d8ea22f24f386009c67cb4d95f4522d8753cbaf9efcf5ec7b2de42fe72f6f1daafeecb737235fc9cbdb32776b63f27cc6ff7c276ca06f58505b03507cfb4a4f7cb5c05d19b5573239d725b2b3af0cdbebb31d9fbfdd16df97a3563681b4752982564bd4b49cd90263cc0bfd9d02f252d45eaae7bf5963be9803bc3d966e73a087db454897b2f2b6b4fdcf2b8835f3ebefd36e3383c5ec36a6fa4fb3db7e7b617ea1692f14c3ef1eabb72c9f9b36cfbb593bdf00eb29f40f33765e5a0c6f1b3b6e317c9bb1f3d608bd652bbc6125bc9f7df00d43f45fd93e786b8cde5c5cdf5a56bfcf0595caf8072ea88cf497dfb7a00a8f6f5850df1aa2dbcbd18d85e8cb3b655fff03b8f53662bd33abde354abd0b3ebd7222d3fb801d5484da86f354389f3670415892ae51c8f91c3b88f47cdbc0a9b81d660c7ea0136700126762ac02a933a7b6f61c58970e8858df6b73547cfbd24fe3e4a8dfdd297726fc2e8e9283a5534c0c88d4e4f8ae0db80d380bcc148c9c3e6b8d0272cd03493fe2e10ae83efc318f7baa1da5e2bc00fd148813b16b623f22cfea8f4ef25093382516e0b04cb818944428fbd7b101e1f69c2a8e9e6b9ea54cf82cd8678b63837a9e96037c82ae0f81d372dc37904ef76a734228585757e46e0150d42937fc081c45d79ef3790ba779306dc99193f52b12cc1278d96202e27122ef47c01c0f7f4e7b3a94c86354356e63c98e3eace134cc6bb7075fba9f04e45587fd1d60acc1c894e07222c1d9c3b227b28d3726e397ab19ebf6f9b589f8e7ddf7a622d9718177513555bee7c6494d1132c2cabd23c65f8b1faa636c15b053b2e454c74c59cd3f0acfcf111005c061039362494543eb60e3ae0036217e6075148a7246a15047a138c8441e619f65e58446b11b75a6545efd56789957dc902b8a23573c89d4dda837be9de949f665f5cf2f302eecd17a5e78a44a13d24e53613b00de85a3cf704b8447248d6a929f0197945114c8a971d41e6b4d4c76e05fdb2a30120a32938c5835d8396faccc7fde5d15b43fefaec8d95ffeb27efa61fdee222a825dca403c162e69b4a0a9b6a02d31b033ab93a0715084d42b944c0572b0754fc5f148a386d6fda78c1f6912d44a8b440a1d78ddc3ae2ad8a31e2df416b525a4d221b9b46a10fb65ac9aca08c5c6a4d998e0285594663a818b481405fb658ea01d2db84d4f42113bf1a3c5fe0cb4d8c076497c143a38612ad2325a6437d6fc4a76a092b8871cdb488c741cbb269a101d2c683468c39146898dec1a7880680f5092002daab608609cf9e4b1d780af6412cc5a13f19d775a6c8e8838132040e409705b11ef76003416005959affaf7f8b6d8a0603f1fd93f151851dc31480db89a4001f1ab0f5cbca2cffce2195cac1acc0fe9119f295a04528d0a1ad976dcc7a276a48464250e784226d721e085ad81c61c2099ecb112caecd6b2da2a327a2410a549f45ec579d933bd7d80a06d04b878e200c22d82cc5e38429e70cf48657b0a2c0fb5421a1cba1b094da3c6b292d39fda7f6541694b6d91a6d48a440508129873b0a78d81060452c399dd7e2eb7379fe74cbe36f5e75757a6ff9765f7f9f04e408fdf40020a98c3c56d80306d00ff7f271dfb6f0d6bd9857df044353f08c084ccfac991811154c1beadbe3d19897794f5844e121c9d24101fbaef5b9ef14a822d3d19f041201fe3336cc921f6e307ed201414bedfda974df138d2c401adef20b3e373b5b3f67c25ebf59483df2e8c9bb736077dd0ae0db47f737d9cfffde3fb58f6df020582921a54263c8d6aa3e7b5e429f38d3a72acf85fd7913f50ab57ebc89f90c11c8b4c62e6d123729123d291fd13cf4e5ebd7c3b1fe87aa9fa43a9f946a9fa96b4fcaa54fdb8cf51b53f50bd3f41accf83db4fb22baad79f84ae17c4bf2525fffef1aac9e9df5c93922fbffcfb0febaff79fbf2cef188ffc06c550b29e102fdaa5b3075a8a1e644c040bb88913dd62a3a43811527c00a896e6035105e8d75860ce41da4089e68e414e6525024da54dcc4527dc3a280471503d804248c5c739cde18a819e6917707732a7f220393fd10d0ca47aa167ceeaeaf6d0be1ea7aba3fcfaa4df1af0770b6e7ec38023e896f5de86d306ff62887f7c63885f8bc6714f54230f7ee0520f3ee479faf582413f0dd62331250eac2d15273b540033cf61470acac0900bc462d890030fda7d66fbedbcd493e4bc23aa57d1b0a0f45f4bc2ef1bf15ba1d1af4efaad117fbf60e9370e795f08f400af86f5471bfca9035e8bc3e58c070b6f98bd7ff0d19e711890f7908f559ff35ba20fe436d0f6ea838d5ca1356e27155091e21fc6789be476a527267eb0f97d65221f0071344d91534ad4ef1bec9b31d6afcffaade17ea7a8ebb7e217dd037de82d8dfd96a63fee797020aac8b3c358bb2ec7404792b069e047aea0a2b1f98d991db781f6833a372da84c7d1fe7cc8edba40edbb2f0c0c4b67a5c19d55dd52bf3fdf78df5f560edab536e8cf27ff7457b1f49c581f0c723d01032a7fa44b0ef26bf7f3a838e7ab52ba2b0a7b0d18c1a51e754d7d8d8e9ed0a9c48e778d2d4417c2636df93ae48bc0f4437b7a81f5946d0ac1719665fe73030961914c0dedc78ceb020b69db21219ee311a926e877a5e0efc2de1f94d13e0ff07eb3f0363dc24e8913386a9f707190804ca39d2b705fa606c7f2d550ff8ed6a5203f9594c6ac6e4eb32e9498a21332d82317d23173037dfb77d2bbf0f3b009be45c97ae799f2937e00be412673b7e87e0bc654cfca625f1dfdc8cd843db80beba62d0830dfa0381c8f9aa6a712de7747d677ce4dda672b64bd8984f16ede470dcd181d86425ec828c5b03fe086513b8c9ed5cbe06eab5fc225de3eb6cbe799f293560610c5c1279437e8fce79d334f96dbbe4bfb551029909263eeb69a179920d2afd2bf9a857f5d0d354379c3460a572558388610fa0e8c2fab06ecbc76d91b03bb6cb3de6aff5513501d0fc56c6deb61c8e99686cf212c003a549e3ef129adb36ce6f1838ef66da7c13460868d7995359c1226a7f6ea7cc28056df246da00767d5b7f2bf783d98167f9a4f2dd5498a2f048dde6af247d2adb1a76a1a1e269f7cb85ed420e0fdc9b8912181cc8acdcc51594336b47c21e96fcd628bf6588bc61827c9779e4a5a512544ba2359e87f78d3c0e6eb733e4903105fe8cf6568ad649864a98eb79c07a8ece7f2431df82a93e28ebf561dc3645e5429104d607fc74c5c0c2bfe9cb801211f0ccc27609bf6933bc652dbc61277c9759db34ac2b6a7d35a9ae1792a8128cb5db73db06466b4bb7e7b70b51dc84a8cc7f66b08569b03d0a814176d46ddfdb8d8c0b33f4bc0bfd7a6263023fda630dc0f2e22edde995739c56c66fdb856f2eeb6f2de8efb4947fcb3632588dfb48e555dfdf9aa12df8185f4f941b08fa0dbd5d4ff4a824b8a16e8695b9726173e562d247ae1aa8f6549fb4d4ab537567237c75ec9ff0c3c73ac01337926f808254172681ef1cff96c7787b09beb9f83effb0fefaf0bd196ad25a1a4a81eab0d727538b249a721987a8d55ebd9a573a472ea9171420e71135a7d16856023e7a1128cbf0c2c181c245fc9dc7aca98032c6865869edb876f09705ac1bcefb4d20d91c8d8226250a2feef3c4a3ee5825f5ce87ad79c19b17bc7901cddbaee13f9b778bf36e97edf2e3ad7571b62ebefc81b3828cc94b325ba4cef776719f372506c37f4b68f0e51b72f3f4dda5e31264244cf979a0da9fa6dcece6b8cc51c93e205378e680cc6e7b2455745fbb109b783924f38d0f4bc88fece70f49b9f76d5ca6dcc44b8199379aef1e7a3f4cb17950b26b2d716b9fcbf3949ef8e267afa4f442623679f6375bf35ec9d9e4c899427d212e7e97f9e637a5e6e92da9797a436abe3b6553387126af7d69658d6d241a2055a751976b33f2e5f06fbf88db2f2ee6e536fe2f66e47ce7f47bfcc8dc03777d20d088d5837f7cd220f15283bcbccea6e01aa721eda5a45e34789c54c863af89b9383ecff2a29de14281bc12d727e6fec0dc9f660b77b15062792dacf185b0ce96ae2ffbe66be51b5f09ebcbde7fa582bfd6bdf31d9a4495ada93b64d7653dc4ad27e30b5d1c2f74f1bccaabbb5e4ea98bb68ed342f1e8c2e23534fcd58cbf5829e2e56d9e6c98b9eb61b670e7fdf8522785173a29fccee9f8d66cbc32199f9f3f3ffffaf9f0e9f1f3f3af9f7efefcf34f3ffee7f3af9ff6ef83d5f92dc13eaa816b366baa24ad0a0822a02a45cc9ae7c87d7e16f1d99281a1440cc8a3de63cfa1e7d8f373cff3a3808ffea64b822ccdedb57a0e1a3f6f41c25addbe3beecda86ba6345aca8abc835643eb6914c1a1fddb6e1c4e37f6ff9f4ff70ddb7d6b05145191d481ad980371b6d7673bf68fc3fc78c9a195445563a394b3538a1381757c348f7532638745b32ed93327911f29dc42e158d8fecec665d0276fdd60cd7bd5dca50c60a1e5e0698be0e615fb51f664cad6349581dc3ce51e90029b580310b734319b79ee1d15cf5db4fd3bee6de858aae3b4363921b50ab79936ee6f4e29645bde183e8aa7371768a133ffec1f77c5bdf61ca9b73486989ca4423da60c9cae6cee7dd6123515a1fb4239651301cdc0e550a9890a70dfd42e6fd7d06057a0c5ee5367ea6007e3858ec0a9e701a01a4f5d578ec8aeaf22f61d28ffed3cff2ef889bda49181522660ab55a7f7cfa990a350e5d60267b2ee5f53ce92a8f72565ae80beeace3a93582a8e244995b72438e54c6729c63beec70f541c6c43dd165f23e6e4a3bd9300d21ad459f44dc1cef5eaa6dabba5bfaea9c15be75e538bbf7efaf2f9f97d68e4be410b6aeb89298899b2431e012b572af897996ceee4210b516aa3c49a14154f6954f275cf7c5916c7e793b6824d1f7523cd0cce0aac3aa2548bd8f9cd35c0009729738b3d1596471e3550afa9515f05605754cd6ed27b1e23b58a7217c06bf56ec6c84489d71ef22e4a4fc3376db554e70be6befd02b9ce03ce76217d348d3f6f145a4b5c4ba0cca9e60656c6926bb485b146aedeca44329b1ad0d4f980e1c50386ed0153a90cdcd38a5e81e191a5395d660156621b5b4f3b7bf028019d1abd53dd2c43d9ba2908efd417b7bcbc2398749882f769b86c281e55b824eebc46746a38752ad99c6ba1e49c868cc000529b284b5241904bbc43c7d2b2756cf08e8ddb50389cd0d6b1e37c37920ef0a66e4b252ddeaf01fd1abc5f01b8162e45607d2137976213ac570520a665c40b61bb9dc33827dad5e9ea5f5d999ddf9deb80eda37bd39266bb3adb564f63db5af2c408f86aa671edf3cbb236ed898a861c4649a20eeaab81a4384a5b4ecc0216975c624b9d5cd973f1e9d34101c5b61e4863241a5043d68b8a67b834d4bd35680172d4bc5a1b6a039a44f302c7bd0904aa2d466aa0dba524a441d5fd70d5bc44ca94b400d1b96bec9c8a35d6e9c07ea4a2f63e34d0ca06d08ae5443226ad586980d9037358459d524fad576b531ee228a01c4b4fd4421787266d4974c4a405409903eb492f0dfaa3555b0e334fae7589644f47f73214a2486a4f12a44b92dc513627b5bbd3235ee2343a7d24b1953acc9749186017649bb763c86aab78ca837d2d1e201f1e19f6bc3a006f6b2596015f64be3383c7a9a65bea42c126b3998df32d157268ba5a92645448b46eeaada4de02ca4270c4350de4099796a4c241abd242336b8000e52fe69714e6209a28ab390995c4df89197e8de69b7bada63c479036921276c5c58c33e0c86a301d66afa3a0fbac1b33cbe5463928d5256b52f3f838b1c29face0b82ea9b2cc379a536b1460808f21668eb4366263a0ab969eaa6c6fec32831da0af66684756dadee1424efa6ceb8348ea0ddbeb0d709054c9dfdcd42e57bda16b6ed0afebc7ef8e9e40a8032b2ff75d14674ca764e65f4b59624dc5568124c0db6410932b4a491a60e4584daf64140ed1301741224e39ee33a2cf25f1301dc0082c14c0f3528be71343b301a7913220451b07156bd0c5ed7668d7f103b386d19210f4cd082d2932f25ac3be31a30057ccffa908c0f5b6a0b0c824844104d050db64de1488d371e6711f9552eea127eea8726d84723f8d78b48047438b2f9bb3802f0fbd146a2a12d14bdeec5317387106a3bd3de22101bcce110f192fcede7abf002fce3a0c34e90076a516ceb73f7e606df69c18327f4c147ee129c1deaec08f06d0e6d61fa1a516adc38275588797041ce153377c008147e9499fb824ecf9a25e0adcf7e73f0fa3de2b252f439807a34e84f7a249fdc30dac7d27b6c02fa652116cc54e480da7cbcd14a90ab87440fe76dc14bca8e2e0edf6523340fe9b24331c70f2cc36a9613bdf25a4ead2b63251ee506a84233267fbf436ce8f7e1c668380db1ed55e1ca880f4be6af0cba10c2848d7075895237908cadbeaac19d6c809c5b7e3de0f6f54559a0eb8aa2fd68fd75c845f7fd97f6f1a8361e88ddcef98f5a3f09df05dbea3bb7c27663db46e9ffc60c75585ee4e0719ffbdf8f51ff66c664863d051504ebda174ba98762f793480ce9af54f35712baa36577b2bf792739241b5df89da07775c9bb9a6bdbeb8477e8ead2619b9d679621c2df5518bdcf59a88cb7dc949a48ebbd692d875726ab9de51eea9dc8dd479e47667f262aa7074bda38213cda269daf5cebc59e262971fa5df71a9a7af044f544e3f1570ae9f2f2b5d171e8924f7765718f737f3a76a2d7c87084ab9f34717ed77f3d1495baab92bdf696bb835f59ca42a8fbb427cf1f485f8198fcf35ce6e9a4fcfd19f7e818dd707dd516ae5aeb744aac51e3f6d77bee87435ebab9c1e438b246a657bcc3b2549593335eb84d3b75bffcc1fcfeebb5331238cac6bfff0a14a12e9bdde49e1256a6c894bb45f011edd7e9472964108e9943bd37975d86bb933f9f1076097034abd5b7fd2f0bef14e14bb8cdeb17758c5bb8cf1ef9c44b5f19d54acfc77b5a53c72a73b5386f6e3cbd6fd612f35f5aeadc323ed0db9fcadf05d9dccf9d650b6d6c0767ed91adf3ceb035e68c182606747a5f8ea1125496bb1fa23d424cd7e648ed39d59777e7f7b8761cb776839fad516393bb8a76c4e65af7a072fcf25ab2b3e68c57b25c3eab74f3adaf7878bc95d7519a9641a05332a7129bd5a47963bc12692cd730c1451e2c277824276a0820fba83ebe667f9c80050bcb5e8b3901972c7d1fb659e2bd1cfbd072a9016aa362d6d5035e968c47755ef2e9bf8877dc62c8ad654be43113517eb526be8f9b268e81d1a6a7d0c697064eede62bffbeaf67073fa9d66c6995a53e531f44eb309b78d008d3b45ed3ebee5a2f6ada83556c4faed4eb55fb455b5ff619f23117fecf9ae67a84cba4360ea879e53ce99e5ee74e0df9f7f2e52fff041ba791d437c9ab87aa890b34d92ec11ad7b4d7788b6714774678f60fd7167b2d7cc6f3639a9f8d4e7c09d4930219ac31793cd651833cac50f630578e0d655ee84d1abd2fb6c9562b25eb6f20f1fa48e544b917ec7d9247b8975d3897041b9cd4e8fafee13c99f0ce3e8276cbf9c2dc7ecee907f4d39733c4d8079c83485319b762e589a7c9660127117eb2f7ba2f90454e713cd27a4ee4ff4ea19fe707371ff657f756dff657f6569ffeb9f3efff23f3e3d2f5f3eff056bfb77166d30ad31b80436173a8fb5a76e1e60b69ed8c176cb751d292b457cc80b81f9c02c710a9c6aa138106ab3d143988fb50458b6257101ceffc08e4667c149d33363b3b86ad2a6be773676262985e530cc9ba79dbfb3a5b3618343abad341e66efdb3b9ddf3a563c60d875d8a73997783e27e7e25cf74428fa9e3c459323fb447af3b0f1e6d089386763d07e225488fb971734da51fb4ea92ef3576123d9764e1d33e34bd23282484d246335db3463f3ae83533753982f1b095f0b54f30e3403433f5e39073ab672e897170c54fb7d33c522c8e81ccca195d4fa70da61c5f60db8fdcc16918f5e82346f4aa94889e621c8da53691a79a491ebcefc9ddad69eda70bc87d67eb8fc256705b8f676e1c64bb7b1cf2017c835f6941be29652b1fcf54ac73d665ca6d8b16bb164607cb7660a7cd088a3807d63748039e0cd0e367dad37b1c4a9f61b60e20f628ed652c9a4d8fc185c566a1a22f3cda849faedc0e2ab397c6df2bf3ae58a22f8f78f5ffef4bdf1d10f3394829863042cab3afc8f26aab64ca869006213b88e04448a0cbe79408ab8675e920ad2cff89112b6c212487ec4d18f9acd79106428761014501759d662de58e494e991724928ae688b39e8aa384543c12fabdd40d3a8f6935c22714b95dd91d0505356b3077a0b231510300030aac0132fa6195aeae00419e6bdcf0d8c76fc20dddc55b4778d6a3213c96c079dd0fe2575b08798b3680fe28f8a0c3c46a8d104ad229ca82548a2eebd15bcb708417ffb6bfea37d8efba20ddb31b13d2cf62eb445b1ae45fbadabfb23170e255b4f2c17dd3969eb25a9774d40d7080c53e9c99c61f8b9d6b30bd9cd70be7923b0e1e628448cc2f10357d31779012f863dae6f046699a1205b1706e843d45974229e0b16bb9dd23570b7d63320475a52c0d7d8e015e44b8e16b8a451ac8b9bd3a08003c6c3280411532c108a0053e92658b89ee010d98a6aee78717ed2d4665c3bda33b363dd5cfc9c735294689bf98cb691e98e78d18c7871115b677ce800e2b33d0a90d0ac0115ec794e52c38843c248518a17cf12b94c16c96e7d44193f03f80f6a42c53ba7928dffc4189b7d69b76b3c87af3b280cf943cc308e8d07584a3a6eef034f7e89e09750f4ad0d873f43f06768f35046045c16c6c33b227847e019823f83f507ca3454bd43033a349cae5231bec141954dce3aa3277d2493d911361ae1fce3112e1e04b2db4cbca4848b4684f335024603a522235c3c091c1ddf6b1a5eae84ed7314e8bafc0a6e2cd8f716134b5b6c7a3003019a843f8234a286f982750f7c161220fedef5b906a9a904608c290889ecc747d395b50673aa469d2021623f67406a660e4393cce3671c033064f8e7019f479c3f8f2f3ff7dfe2fc78719d9b2b922d26d79621fbfcebb5e75f3efef13fef3f7ef9f2f9e34fdf1d7a0f2952917d2316fb341d7e1c747a2cc8adbe37a5187ce204c2de0a0dde71a98fdbcf8f1fd423912061c4f93956e8a666af550f551f10bdcca90616c716ae3999d0e4d4eeb9a416a48a67670f4555b8a23e423579ea8f67f90424fec4f941ec19502b2352c25465338e6d8e41cbdb3a02d627ec0d87da9106cecf5a934d7fc12771007a31b5d041fd088c453bc0557e5703a4a134c09ed62e680f165b4b72af5c82d8244434909bb50447ac8758f56fe4d6ec935af344737cc19dfb7ca614f6bfe0183e67bce8e98be35e183b07006daa2fbf7c7e79d5f0c6556fcd8f4b81bf324d2ebfbe3e5bbe37430d11eb9a17080292cfce83ff23dbe2ef7322e4e73873d2e24c7db9949ae3def4962d033df515e179e1582915645f3e960a9a65cf51802e86cdd066c59e69d31510854b7370cb32612e2bc6a5868e1223aa09606f8135f609cd293e1d185b8da1c752575bbad5d66c730595538b5d12af688fcd76ec8dd89591d4e0395640516da8a36ea65f7be8a138f32fe0130a98505943df1058d81ea224d0ec505d8186b87809a4a2f23579d834daea3a600962ff4a8f1fa455208a95c58974a927f0f9017d51632968475fa3662fdf2c8bd9282dc0b4c39c35dbc33a353f56c136bcdc2b30821c17380762b310c4eee200105512450ad4ade702e79cda7abe3e813a0e14736a8beaf0dd186e693c71ef3baaf9609e7a5f684480ed99818a93cc1c19b854f44bd9d360cb064f230d45c6cd1eeb265782cd8d1b13eada445afefcfc978fdf1f53726935547de05c12d71faac30fe2ef992bbf736ae571246981459234c84041769a1f09278f4b94c40520ce6ad64f59dcf164d8e2d4cdbec1297efc505a5d4c0e0a9e01808ba0e5aafa041e642c5ec53f8ff83c563dee635758f54553ae8b59fbe1fcc7d60becbc9923e798d3a80cace0de9a67453f0b873831e4475349922971596365337ef0f7ed5fcd1bc48b1b5cfc996df1931f45d0016cd31d978e1737b8f5abf5f2faa773fc29fdf0b2fd8c00ed7a79f5b77eb35ef6ce5bfdf8e8c389b65ff4cdeda931a5fdeafc98df5d9f24ef161af816bbcc9430f79ceaba2d3e0c1c67a85a0678155c4dc7e87f8251cca66e84d2c05e523c7dbbc6ed1a13c5da6c3b1c49852ba15804b85414cefd736ef7c638de30afb7afae8ee27bc576ff7ec044a6feffb2f7bfcb71e4c8d9287e2bb80001814c2412c0c779dbbf5ff003f99ef7786c9e087fe3d6c86e859ba3b538437bfbea4fe493e87f523547230dd75c9f0d51ddd5852a140a48241240e6f3a4c158792c63b1310e58351de628c76a43a8a9931abb1e669d3df1002738c6c02a41b150315a2af2a4c32eae5886b033d586ead2172e365376b2638169d8830d9dc397556ea5e5d429f434e8a1502887754cc958344930384a52ac0210a6e298cc166b581be5ca8605ecce9503e7010f8841286ace00f4b5c9e3024ad81a5a4fbdc43e52ad36f9d21e87cdb0c3e8082891d4618b6b04db24f2ef71f8824e4e4537b184d2c0ec5e4219350c4b926cd3f75da9a6f54b4d9536660c9b11c481704146b98bdd94adcad966a96621c0bb26abef79c07d9a6395fd63911eb9f0ce747e73be50c2ec85c0aeabc5f419f52025f66ebac8ac8b112d5f7b850eb32d5b6524d2d831a3aef284688511ea483a6295d075c3c35169470edcc9269e8506dc4f84ac9e4a1d4f518755402b686eb4bccd4a0aea0b94be04735da3352edba856caaea0b9cdd028e78d1bd0b8018e31d6b6d1e7d65cad0dc8a7c7390d0135a6999a6c225902f51c4901efde3ba0897b4b3a3692ad95076a436dcec7d9664fd204bc405d176b58ab6d865437e42c6150223299159aeb5707d3b6da7c2261b3a2b3496aae2fe884d5655f9c5fd306db870f6f4da1cbf0513073aabc8b44193ed9f0e4e91c295b9b2cc09526efc784e901baa89a4298237a6e58afe31cb8152ce359236fb865c0695bfdb396048c5b68f42536fc82c1ed57445f03c29dbb08c768447c10963fb29872ea036e9263c4818551a0ac57fb8de24c6307a50f5e7a7b295fddc404b54ae0243abd0dbd332a62032469db8d9ecc326608b424e9a19754050bcb034c9ed89e6cd80e1b585be271384e9073f89d25b277ca2d26a93b789480995d6b944414c88cc5ba44ac1d0375baa70e8e07662c88d13c86d603f26019911393cfbf5aa2bed36ecd601d22e0104cca0b56d6b1c23a520634ac7bd4f9d1487004a689025b7de9181bafcc3b142e7ae182971a14d236c54845433135670610b82fd817ed6c666173245457447505546344352e8405f18ec56a9b541606a742068e80eafececcc16a4ac29a6467dacb3ba4d5e880ff5b1bb770999f5714b6a6164e32ec128db8c46fc4ae12fc3b81685e4c450d78205283a9d04cf0b00f30b027d801303e40b6af8ce7909a2adb91829f971297305778ed12bf35f8adc83120473c28f883ecf9145080ebea63fbf061557d6c1f3eaca98fddc3cfcbfb1f9787578459fb9ee91363dbe4a654bea76addd26c35e168fada4c2cc208357d3ca3b4246d4785dd4373c1ba3e628bacfba3f93b683d9cf39c75fa9d9bb015d95446df64f751ad9060c84a6e2997d4e5b6f4913c84b3b44d69b0f814322cc35d040b675343362cda24632e8bf05c22c9a1242926670aafd094817695cb2e12d6ceed45725da2fbd0a6eed366c85f07b27f76f270ddf96a3a0abeb0db3ca587f986b807d7f9db22d62657ab202d8ba990c0665a755315be938405e49688ef65ac234d6f99d721a0b1841753a6230c74f3453c3b45ba7f2422c0da0b00c515cac39468370ba0576cb5754a150ac0d9cc7944533f08182b30384038d1b18d480d0eb876a704d26a4f9d3f90cd4de9e28ba97470d8eceebdd9f31331b6ee4c95738f3d6f63cabcbf43cc40ef3b0fef0bd825901b91bc7f8c6ce628f68ccd68fa8d326e226670828d12c07b9b8838d077612c0cff8e82fd4685edefaada033e2b767d61ee78d9e35775c5e5252fab8dd783d0f90ebd31d44cb7ab58e6d704f9a0630454eb368be028d37a18c32ee4d99382f7a4633745d422c670a7f37723b4efced40b7a293a362e8bf38e0b65c43d497415804d4633664c4900bb1707d0161ea440535c3c18d1fed89550ac47c514f5a4b06ea9701a8a39d051337a31024a74ae30e2b97e89670a067acbef39d746084d359ddb12c32fc5974186061b87653ae14341df037c9eae40e9efef7228f97776df0516a69a56cbddbd3dbf502b7d765384d3ccee7becb23601093c6ae2661d957b4b9de1ac9fe526ef1fab95eecb4ef658182efdf6f377eb9cef2c74ec5842a2c6a9f5335d58ca852e74cdf6a58a30cdf6153ae21ae8d217d7bcac25de9a82f05849fd1a15fb95fade24c1f57db1693ef47d29fa3bf4fdfe0e2104cd5a6a0ad86cb3fd63c5088a85a6373d8216ce6b23286c924b33aea0b0d98c6121ebfd85ccf812850781f5869bca7d5d4d4b5fa59cb829bd24954d514c5288b15c206a53be69993dc1456fa645c54a50e1ebdae8ea104220d45aaa99f18c851af70c1290fce02d02dee2656d77357fa175e290ebac1e5fd1997fa31faf75e137e7467a085a1d29179941ab03c1fdfdc0be88941506c6c37967611c363ab553a820959c285b762df5c18bd624d2c3fc6a19dd443a39a5974d6111d7784b35c3d524d7c4a44bcb89b39898159bf4d94f561bae5ba9f39eee59a875f86acf0aa5ab3d7b89feb4c3573369c143a33f341e1e5a94522d41b2a6d66589782a48a98a0d55fe54603a169d37f5389f7a5550d6d79d56579d7efee9870fafb391f01d4a3d3b4f0ec06ce197612a39c02523a86c07c87c54d69d36f68fb56954d9468f3edb0edf3c3bee9db5c3d61974b025c579f7dc38c3d6b9987959f1241a6c19ed1fa9591baca39b3e5d42ec5dc2ea5de228ee1f7318fafdb944b8a1be91d25c174693b07581b49435a1fcb47cfce9cd791d2134ee5e654bfdb9741893ac88074fdccabdca4dd1671bb81ab76d1c89a4ec1f41c75842b6fbba5d7cb8e2a6cafe51c44eada46e237eee1f8b7a2ab5d4484ec9fefb6b72a0feeda9a5a6467596a09f3dbd5f3ef9f3b452d318e3909672a6f374fb6d6fe6dee92f5de3f57be5f9f554b37edd29dd7fcff28b5f830639d6be34c5cbcfa69b6d8a9caf0a32a472559091b22ac86f2eaadbcc8fc207aba4b4935952a64dd6260d58697efa64954d9eb11200a0a07e9c43d367c96efc94160e59f91f429d35bff0bce728f9fa039738ef3a585b659a5b6fe989d725662da0d74eafc9cad3fb3f3dec76ffeb61b77b6bfcd8457baaf0731c3beea9472a692c2061664e23988152e0c79f08149bc11d536ba8922a2225fc88aac091b94ec61ca789e658e134562581a713ee5f251676e26742cc5aa88eb1db9dc49010381e5943c951b007d9a30e2ce56a28925a287464e7c65c88e0df95416a9e34b49a46682db5850ffcd9e01985072ef63483f6d4fd91c1f78a899c8b153e93c25e34806fc8063b8724c599814683d38083afd4eee45d828d9de2ee57f6bad85e61287340dcc4d2ad124b54424507547424afe4e4eb4fd8708e955205c086dd50adfe09962b051d966f633f5075474d86afa7826d9ad2880ae060725e32b8a0233610db246256a8ee1f23734743ec00fd1581d52809fbba9879b5384aead19aadc8aea041f342705ed2403d8c91509a5a52df3f327c54ed875f1c284ff73cc909913e35f4966a04f7b7f853833d157b7fb18af35752eea9981c20dbabbdefd4a1567be12979b537fefbfb5fde6a7f644811e554166bb31eac5abb82540efe799c18a07cbb6662681f8b73b4d7d4b18017bbc7dda02f130012e0decbb792ad5f28c45de0e357ad91b1895623493579770a7486039c0951856f2240515a206da9ddcefcf677763136fcdcd522148dd2123c2ec432ed619617a87561d803a80514cb665bfdf698839953ce9425891731c3ddf443a06cd25041b16e0f4739225ba1c90b48d1aea159727b895b060ea7ee40a96a1fb30e46be1d39511069692c560520d80d034a086cf6767f40a9c8faaac0671bd52e018f3eab8261d3864170dfb4ce6c75108b06ab83d810f4524087003d98912702d8105243de3c68a95363eeeff000b8b5b40daa3eb0a8b55b81a6686eca6bb786b762dbf3ad1a505534cbeed540e29e7602ff71ab8747220d3c7831d98a563d265b91e160e1e534d98a56147c38368acdd41ae8a4433fb49d37e30b5df4ac97ad77d2b30bd6bae92faf4362ff5dd4c2ef4a97875193bcc387a35b147ed728e5712f431f48df91ce041c6f0b7f76d257c7f24de9f24c5f7f47ad298f1f3e7fb87404c3df97a23785ffe54e86bee3aa373ddfeb485c1f9812eb3bfff400f3a21edbb5a391182805ecc87954def1384439bdab2311bdeb49f95d1ba9955d4c26b6ed878bb289bca3a63ba254e81d3e2fca0eaf8c77f9967bb10b3aa52117171c3c43b9f13be9e749eef0f92e1f9ebb606d842369e282fd7b0713ac11c58bd8c4a79a13f33bce89fb0fa88077fe796c2afcbcb72a22bd7895fc8e1baf36c8cd970d6b2dc28d2f3298557f2d50dc247ab523fcb2c2adffbf1e7ef9e5fda7bffcff1efffccbeb441f7ccf86bf0068ed59655bd83e23be6e7cdd652b3d3f924695cfc2a7cfc3a49f99e510747d1e201da46f2bf159f8f47948f67324dd76c476d57ae23b923a198fa8cb04d2ad75a69c71faf5093b7416e9edb1dc515eb0344ecdb0de76c7e4ab6df8fffff595cc8cbf37e145133e5ab986de0c7d264614fe3d8d1706a863e35c6f584bbddaae370fbb7ffd7bbbfe35da95259f352c5b76bfd9b0d63ad71bd652af36ecfffdebc3a75fde7ffa7bdbfe35dab6143d6b5be2fe156d3b1be87af3ce0baeb6f03f6d3fbd7f3f2f7a9d65bcbfb7f367ed4c2267ed5c387f453b5f34d3f5d6beb86ca5cddfbfb94db08904bd8046e014c039268d80ff38b90c4d07c57116c339ce82384be5889dfb2c5736b049203e3334f98b2df9b9f81b54420e8decd0727e2ef5cac677e12bfbde2e5fcfd27fd77df78c555ba5d41513652c1e1efe5f1592f7ab5b4fefd7b69ddebf923aff1e0c56ed3340fd48b6b8d2af6e5836b313c2835e18c739547d969c9d028ce1b33d7bea6405e5c6577bf233163869d773d2ac266da3b58df0486568285a53d6827743b050ef7e9c2575bd276c223801463c1260f8dffe913470eea9db7c2965ea617e218e328e246d00629ae8b670063451cf752ab6c5e1a64c3a4c705a0f537cd972dcdf71ee01c06f3df5029e7c972289d33310beab9e7838ef12f634fb83cc1c5d3fe2ca78383f5ddb1ee34090c26b3ee3aa44af0f6aef5787b2f7bbdd8fbb87a7d75925f90ee5a6a5a4ce416a4fb48b0373f696e12e4923522addc3c135f528296b02f678ad760e2bc5408377609e86f884c2806fd1586b1240e68c318fa94ae211726c581c44200295910670818644aa3591de3bed6143388ba4c9ad018767200cb8e396a452e671e167cec9644d722a2538fa8c24d550286584c0d51194536db7520133027ff30e84e09411552025a61eb8a44c4113f55bbbc63290baf18bec7a46283dc04de034564b1abbda7b2a350882d216b53239de10c0872551439cb6c2ed734723a9834cb4a55a8e9a46c355408b617723b51beafe8e6a738f28427c8bd575d03651b0041c63a5208483012adf6a04fe2e10c114fb25ea77a18510d532770d5073a170a25078cb4269f0edc5f3f677d6efcd0829d58382106a7d087cc6b1ca0d574db94c1f118fd0a87011f1e8eceb3e09875eb1da8f66da7a677a6b0304b3fc763d91e697ebe991a9a6322240eb69f96fee4e2032a88aa8a5a092009f9f5399c79ccd70a0cc0980ef1e3e099cedea7861028fc96f12c6d20b601012390d16fc7a911a0b879795d04bd27645d0d6646cffe1fda7cdaf9f9edf9ca7add92285b70ec86cad7aa22d2a8eb2f28c78134fc3e92379d176e832ef395019150767b957b9909272c692644379efdb08accd0d01aad784a06a18007203ae08e013d1ced2e18d60d29d03113ff9e983df98cd68fa0ce5066f0c10db46e21a256fb13ebcc0e3be598b578ea3a6aea137935dca888da3ca5b194916200f09218e4b536bd61998cc30ce02a68aaab124938fdca3c3c229ba901db22691fb3e97a3b8f0cd011fe78fa9d4e78858f7f55aadcd6a0ab342cc029ca802b511511b41f28d147e6e66d80f00f6255067a4a2283fb0c4b02dc6608a2fd5aab1897d8eea7510bc0ebcb210a9dda322b0bafa88e32c2e5eadd1aad51b007ce305d9b38d3326afb350505ff20504c6137ee819ee450edcfe70417da94eaff6fc63675e5500c7d4153df0e14fafe46bff3d64f47ffb3c0024201f9b53dcb3e96f24dd4a3fcd7e3f4b3a9f949ecd579fa5cf29c997494787f0b349accd6fa3f46700c3ae269673fff2b329f83d0d76a0b2b5d46770c071011653fe6a3e02492f31124006d704d7ceaf89ecf297e5ed058854e254f308340087bb0036a69598b23a8a70099c4605f2af140d669b576c6e6b8f045c89f283cf981da4a028bc1383ca36aa5c751723bde22eb6ad39a98c1d49ea43034f3b36f394f435bfb46dec2d09b8964d3792e37fb60614c631805001a63b49521a08c100b9ef20ca4d4da5562d93896bfeda4a4f8d27a61635b824382db880f2af17c03f6501a26671a841a0a2f2a6f694870051a39724c48165a40cc861769c88a2310939b005370451e45aa17f088c7cce81586d5682f97cb6810884536d147797d016876eabb55279386f04ce49b23aaa71bb15ca005dca945ab38a1d05889359db02acd03a07956e4376e91585e9845fb985e1d54652e1f3558aa5f731e036952b0562055f1081040694969a3569af7817ea0408ac6cc51ebe44c3358d8158bfae36b51d02f793ca1aed9ac6b096a5f9cf31747f07bab91a586b6a8d17bb080d5cedc90aa6482e4915d1ff5669a527e6be05674cd61d12e1cbc5e03a3cd4729e71cc66d4c6b98c78589079fa8c9e74319b674c7ce7aece65d552b6ca48bd3ad859cd35b462dd6ad3075c844b21b053daa8cf043e5a38db411a2a6f3ba50247b602704e6627f2500ed24d6797207dff484015b626b7322acb120ba69c945a850aaf6ea4f40107c3d24bec3965d65b2e2d954681ba6cad62ab34600e70572b884d71ac295b30a3aeeb026a9f623363521066654180959a84dbb31b104b6a8da913b07b896d7e0e36cceca45d239552ade159cb4e4c868a193fb5eb824580966aee0e1b2261a44eea38c68edba03b2aa90e89dd846fc1c511f7d9a52dcefb70a923eff2ce9a51b4c74649a53cb49146a630bf1c9d9446eab5474e32da7268f5f019e96c840613e0ed9ab8540e9d53b15992a442e043ebfd3ab689abfad5b101296ba3c3bf7ff8f9dfdedae020d96c9307dff7b0dacbf180ebee67b2c3b3fbce7120a68702283dc715754d14da56e5c12dc83c618a6c70a89c5abf45f0502eb84f827f1ea18cba2356581b0dbdc8a2d854b7e6349c29b7e48a887ebabc4a25e47beefdfc2440980137ac26300418636079d48eb9ce4883ddc9ab8c874976e42f7f60430aa7b3c8d04991e0593df8c1e7539035b7c0c3e14c0e3463701001c9555f2bffab826952b62a9796b026963f7f5c7eddbd96a3fef760ef10a6696b7b3147bbe3cb4d1ce9dba1f7d2f7775ad22010ac8fb15102302c308e4b1205a62b56d125cbb3d9c3bf77dacebd6f0bdf13f71bd3a873fa0a2a63424cb9a4028ec75120f463ff58ba63692c1133bf063f2d49befc33fc5a3fbe299c9f49f3b6f03339ebf6ef9cab09860e99636d8f5601916a0648bdd54c649194698f6db6c25f51a5ebc19a8f0239df3a14a3656325be2e9f07715b95d143e29a9c7edc3eec5f0df3ef3b00e33a605d8917ea0e83ac894371e0bd6e332fa0df03f11cd68b99aaa0858005006071067c5204ef76ec0c8f78334a4d1d57b8b5da5967a20734b22fdee141d9047ba40ab246ac624480324bb49380f71ba9eeef0828cd527a6acb6427801189b51870fe4e77674e008b925825217e136ecd032b151a11b870c26c76f65f1c38b831d5c4018be880f70f8888b08a80eb351100a30a1ce2ebfe9101342b9ccc60204c0f70a307ddd94bd94f0164614dd546658ac352bbfbd157402d43f65b043e3fc7127de287c872bc8b064b163835dbe56a83fd98deda79b8cb6f414846f57e0c28f758e0aeaf098bc005c046413d5a81c0bc69d30b6b217b9c102c16b3c73a7e20b2c3eabf44cb020efb1980d7c5b19b6c8a112cc12c9e16ec7dc9bdd941fe5b70507aaa1e6cd44fdee26352d0731a3f9222d237d8b78c84356713167697e516f070cb0548c2a9c554229ce1b138d04c4d442b4d4b351264d12cdd0d214aa4487262fbe6f06544d5b4d1b016353b00f9e6607510a9db19774a07b3c484ef1809188a0801a9516992615a37188c8783a000185c2d140f79b08c829db17297809ab37ac226add99e000604da16d0ab10db0fb6722c962346a70119780431fbdc2e4183176bb6027492017f79500f70000613782bc40305ec4aab30388103830ddf3d914952e0e428c49a6ae8a10cfc34fb3229441dfd1ad11fc03bc232ba4f54810208244793f789c0cc6daa05a42222241c6b2d34137f466d7817432841ea110d2c51ac18b1dbf0630f417f2c58340262b19f1cbe48858aaa5e45128ff5165b4327678f8341cd3c91cdf262eba82a3b2d7539d4968b014d75e6d85ec16147010b150ab0a203257d822eb1379a6134f0a406372a0828626313088a261020bb452bf170e79d23b35075f3f4691e1e498800bfe9866a9c879e707d209ae3c9ea3834d3d686a14fbf6c7f7af8cbe6e1dfdfe6eaa419228ee40243840156de04b872d6ae02c81d4d1d08f796d270c02de9a807eb45e2210db771eae012919698fabccf6feb89a4cf6765bebcadd824d41f074ae3d3e39e1d7f1f4d7bd1945bd27b22de9a152102a3e2daafc91f75a48f9acdffdc33ec68ee37194bd652805f002eaca62d160e872202021c3e5e05fc77e190660778eb62f7d95b1feef3dbe65be3b64c97b7d9e3dad5c7493fdc5779de577d417e7f87e5608c3fad1e7902b84e487fab6354396a5225cc2d3ad71936a7d627bf2108d6fb25ef1f31c778eb595eeda2a7beb6da4b4fc92b1d75f7fee79fde7ffa3fdb8f3fbf5220fdb79b8c65705013604d556e2da3ec100b151cb93b6a66b8abdc94c14b9c3c3e365ed71efbd18510e7fd5ce8b16f896c76f1ad374b4e457febe6fbc65fdebbbfa3da6dbc2e3565da2136148034aca0e730bddfc9943eac5cd0cdb9ab152b16d3e0a9210c9162c7899409fe336cee82197d4b8d776717b72425b5025e0bc54c279ce77b5e889232db983710639b7a35730c1822b9ed40a500b624da8c9e2a8151d106f13c62c272e8a8a00f688b0d4eb521844c23b02c01978cad7305da26302f619ff0985884a69480602aa9efca00cb9235d4a2a99b05c80c0201629bc729e8bdac60fb3be94ead4cd61413fc7e027d00e43e1c60e156a786a5f2d5b921fc12ae20e6bb07eaf9bee1f95edfd3d91ee28958e4f0dcf3a7bc443472d635d7faf559f2d57efd16172bd0589abfa5b1387f5b6371ffc31aeb516c0aa347ad647afb46fac65d9fb1d0378fa4cf358955cf69eb1d0cf2c312061064ceb40af7efd067bfebe6cff5d9eacd57f4998d5a83ef55b63a52e71d1160d6b9dfbcb0f0e672795d9ed744f9c3cf6f8eddb07400b2575362a53df470f04a35dddd31b3e86d87dd9d5222674dc20d6bbbeceb5c5c0e84209c46ed7124e97547ac299b9d96c1d07d962f32f45d3cdadf91595dd97232e99c58c6123a72014c2e87de13f7ba98ae3c80d65a691a960c1cb928b5825d9b9ab168526a339d3f3c3e7c00bfa0349d57445c2fe0dae824beae501aecb1de179654b0b92062d3391dc38e447e24ce33652898ddc24cae1c449e8ed7fadffe91aa603794d4c6866e95982381d6dbca1b6b1a035cd0cda6489441c4d74bb31fc4f7436f7a7e4ed986d5964834e503e1a0cdb448091370015596dce640bda4a6fa3c6ad221ee042d15835926021be1c097a82f0015dd9486bdad924b6a736235b08cd303f7fc8c2052d51da98d52b5d1b375341dfd76a4c12d08d80ec0640c34bea479d88c903b62c8750075bf6048ccd937f5b2cd2573197e458f8c5d1fbf20fae5b75434943c92967ecf999308ed3053c980b1eea40f128e4be68941c7391aede025e77b92d496811d4e6cece18d8b3acbaa3dbca496b1a6a17013178a3db12f48511d914b2a4590aed12fbeae0a3efcbc3aadb4f36b6ae0e3eb6c0b7d0f9189c30cb062a68e65be04ce4540c9fa0197d4ef4b26f8223a7e3ac0d2ad515b709c766bda6e6aa138ff218ee0996f63c7e54cfde9728a7f4f9cdde1bf9c616eb9b33f560f0a7c00ce40b89ed9232a6ca231974b3340d86b202c8e82d0094c06a3277797f44d772c7b8063512256064b8bf0c775acf788ead8df711e36f3313bd2311a140ba1f075a1e4ee0e158b7640f220fb03eec148129c120908288125a7e12c1256564b3dbfbe6e0b275a8613942916393b5c64daa6665fbec20a195ac9b15546c8fbc754600e8c546272ba80a08703d244cfc837e3894042c1f21c600a0006a30ea511ac87aab51e39ef96d404d6b054424b70276db3a8929a159697712231433803396249478de7447180d67cf4c41835149fed7a1ffab8ba8bb5fbb8b687f571f7f6c6516bec11b8f407b2bec047f2e716b526a64d51309d0eb5eb4a861b2e44c4ccb19b220fee2f337708e74eccf9c943b810a5de9eb9f7df710fe7910a2f2d3b364e01a76b25e743a589e4013e10e9c0760696e9005b5435cb00ee8b6ae375858331f1b6b7d44e3bc9bedd39dc71a7e9fe115f81e1ce6a87d840f37baa86aac77b5e0a66fab85b55ac1f776b7af5e3ee75d0bca76bfe376d160dabfe7c43e088124ebe3fd737cce08ba881a9024089730ef9a6ea466c582b05dd0f04371c38275846a64736914cdbb60a6fbf6a158cd8a66e06744fed7660fba373aa0b761ab07adc7d3986cb61c9b927f7dfc35e0e48f27a24de51d358b258ef06ab73c4fe0a06ff16cbf5109d8fbb55a4e58fbb3570e58f8f7f7a6be39f48b64ae9a9ee62e550f9564c3bab9910665ff97f16dff02b69ec803e8e1164f1ad353d0c87b51e8e7ac5f504082998550cc474b8f4ff9883600305a0e101c9037162a6d30104054f601f60bae34b25b92d4461a05cf150261c602724ef7c8955b11568af4218a6dbfeaee61c346fa38da6ea5b77a083746af8278c8d930c7ecbe0b8814def7c8b1c899fa25fed7f0e9a9cd7f27a46889782d5f594e9d3795ef7c47071d5cb3c1ff112b5ee10a1b3f8265ec3661e10a072249c8987337ed042de615c06a77a0b87fbfc9e4076a6877946fca0d9f8194d2587bccc9bfc864372587dbc3d28ce077d598cf5c7ef50b6fd239e56e41beefd8612eeef6079b4c372c21960ac7d7e4967fb74c1620b92ce11721cc0bab3f1dca73d76a3dfe37f4fe7795c57108f7f5a55108f7f5a5310afb484fb3d4eb5a3230e4024555d7c0b9f4dd15222a76b3d1caba65a9e634b2a1b7ba0e9fb12d48c1fabc0aaa0c231b3adb06fdb68069b7f4e3262cbf05bcaa96383ddc3e40a68a6020040ed59447e7c6333beac40a32a7353c659daebbc2ee23a6cedf61288607b904de2ad2c0d8cf9434d77146f5d2f6d06fa7319cff6164bc6fe875b8080591bc5df35e05d4d354226c98f0817831fb2f78ddfc43ddb0431c3ad0b1b22d6d31bf2df98ddc50e0868197bb96ccaa8cbaca2802a02701f5c516b8355a2013ecba822d046f9eb86b357df722ba9b765d650400d05d45038abc94dcdce53346aaa146a81ef041d9bcbca623354c4db58e9220aeb87a8466ff12563870c448a03b06103413307b9304dcdd665c98f505729c37fa25f9f605e59385d5f30fdf84a5e87df13d59d818d49bc7081475480f32828627ba8605053dd9406fa56a99418cbab18215bc52160fd11ffc6937a4407c2379b89c600ce95e48c59d690ddb0f6b68fe573e6d20b9e53e7530789df890f75856c15819fc33f97cf2959e325f12bf0beb0ce40e71cb12b24b4c742466c14047c8257babaab77733f779b2697625d5a6b34fb8deeb5a4263b13b30626889e3a479032e1940759547017d9e70efc62941a6fcc9c6d107630cbe1a6929dd9f7d6faa9efe474d08820ea6fb4e91e5611c188fca2f567cbb0803fc98685ead91288fe4f9f743b149197fa4ce8101b7b8f86c857df8a65671576e286828dd56155a80df156d551128b6c4ab32e28c3fa4ea83d9502a3af3b17366f99697f072f6cc5668d945b32d52a3555bd871bdc6e684c44cfd4293578900f81174e033722b91f1f905dc126df4aa8889b53533bdbc8b52d66458044b57b15209482fdba88eb5ee8c9abd3dc8fabae9a1f3ffefb3fbc7f789da9eef784e0360e54748511ffd28470b742f679e985cd0060f9c036ebfcdb8dac62b326f4c436ef98fddd7d94413b0e42f4807dc8c2f06d76b418eb2ca74a0b67fead8730273e44395149333c190bc5d8e8c1be8fe516a66507df1eb3e9b283f933a83f6db2b783439ba4b6d0748883a3dfe4a58f927837ba8dbaec88a30832a005a0aaf632a9034233d56097aaaf1e21b360d724f4fb0897b10c885170b0abeccc7c08257b5ec1ae07caaa7b55e1e25d3c66170ff9597a75f72c3cf196c5a95865170fe5c4f239b2b40a8b403a9daf128f6f1be7eb2610bbc1930bcf6cf0f5ca896068015d18d9e17a7bb24f88fd6ae75a6696d47e477c9947f17e67ffb8aa3e5c23acaa104f5a572377ef7ffab03cbcb960feffb6f8caffc8717668b4ea72a5f7ff875d20eed57b1e4fa9671b5ad87eacfa1cab7e76522eae0afdb9eaf6f2a2d09fcf2f8a3df46dacfa7c7e959fbcbc2c767bdc365e5e17fb2122927bfe3d12fb82b44dc1b9227033755de6feaf3fbf7f736cdfd51408d00f725de0f01c0a285ecd9cc276b994c825279ba9d55447041b2fbb1b3cc3e173f89169e6f65c14a683478f816d4f3103ea586c63f7291d410738ef04cc533a00d52a206e33037752a5123c4452077f6ec686bd94795c7252bd574ead2eb0ca1a5060e026602688608f0a78e96d7fc70ad2ee8ee9158d66da5441dedbcde02e3ed729a975af0a6c0c38860b363eab4fd6f0b87bc9197b1da4e0a02e89b08668f766e7990314c1c0f237760b46aa03fb68e4efe7dc52d866530e0ec951409a6bc6d73c2c49f49eec5965c91124608c8009205f35f021731ae325693591bb22aa96b42ea7fff8fee10d3a9894ca01f1f715ee4cc266ca83fe260e7dc2aacc3c150ec7470d1886c6c39938747fc705ccad3635a225d681c98402e5a1561379606173066db08c94eb860ae4799035770691381c27412f2ecf66bb0195044e2526fc00ec67874a180161a4418a8906271ec0c51e303bb4071ac5244cc8047cc0deb6ee67f3fb7e64a204f355eaed9e2ba7aa4ed32a495b642b794fc3e65482d006d1fd230ba04950fc250a8082d87a06218610f0fdf325e1389fc13d1d3855181e661a0df523a2a4e5d9a60d6df8762781c8967c8f1b74f855e02516140018d6ef18a26f8a15cc95346c5e63b37f30a98f68cf45edc02e2cf3d86a4aefbd5afd1da9262dd621aac2b5976ccae733ddfca2f8bb245fe9009eb8de05dea45da0f99e657d47d80c02773bc1d7c9182876e2cc10e82796a73366a7390f68660102e31f1b9723ba2e76af4137032b56c3e0c61cfc5cc18638a840e62d3ad90f0bd6275231a18b1a34ea9689177fbe227a40833ea3a0f64a386117ded8add137b835e2eea8cf91e1d7acaf902bd782e8b86924b474e64b7674eba5b9f32be7d64205b6894d1f00d59f06343b96565f12cc2b22b92e8c8f0f9f5e4720bf637717aafc5efae6e01577f28d0b79cbbd9f81879e3bc83d8bca2d5c94f21c0f5eaa267bf32b5565496bd5f5e9a7f79f7e787b285d708fe49bc23f5c4409c32bb25f860e4f8fc82fce3a54d2459caf63cf3c9a40aa3c13f71be7abdb3f46abe3fcec2e7b76e64e6d78f14d67e2fe8c685b5c7471ea6a63cc7a5d6d8d9976ad39fef76b6d5f7ccf928dcda319a0b92b2e0397278fa8a49f9d9ca82b9fdd8f90d0a121ff2de61db9f7572d39306cfef6eae535f3ce8e76f14a79bf5e85a30f157ec57a794561b169025c715e4b5e22c804bf2ff7fb4bd7a53f5218ffea59df810d4a6e409cf2c7cb8a2996d7ca3b0e7db5ac5fbdd83f9cdf80d085b72b232f1a1ffffbda9eef21f19af9f1e32f7f797b407aec44feafa9de5e4d31c36a7c45cdf98a6adf1d32ff06f38eaf38584153accd4c24e7afedcf43b7453f77b4fdb68e8efe7ab5a72375adabffe7eec3cffff626b91aa583e59eb03141349c15f4891082f205b3fd89d5be1fd94bb1871f1007b9b638f1340f2fc3dccea2dcce82dc548e28a61e8577bcefe985fb2e9f07c81b12f9eed25c95836363aecac131754d0efeebd5b659be07658c6b6ae0f2000830aa2cf538b0181ab92401cf01b1eea2fa86b026f89ca091e05be1108e76479d478085184ebe9a4aa4346e4145599fa9cdb5e816283b6a065bb685760cd49c0a02dd9cd8e12a108d916a2814f26dad947a109685047e00409504a39ef851a17ba6ba8b54b09b4f0bd60109ab868e394313e165ffc804276fe2c4b7b5abe54c4b2cd8dc66044523305ab17d3d500d2abb4188b0e0444b39c464206e256137a98696ca8e464b03908acb70780fbc32c03e109263354bfbbb0a8259ba459e52122221358c04daccecfbef1478e608bf95a5d999991f1e195b2ab37841117d62a58b9a46742411acae032d27f4f4c2baf47f5ddd95f9af6b9b32fff5d676636a1ea906ea92f456ea74ccef1ba94073417d1781379300c824df803571f09601c0144dec53b52fc7dc01a9a95945f96674137d7032e75806b203e6249e71cb87072f604d48025e049339c460c90d4bbecffb3b2cf03c8333261c71364e61ba720e9f711688756fb394eb900c1fff6bbde5565bedfd2b61ca7dc77eafe61982929f87ee4c6333b9bab6ef67ac45f47cf2bd39396458eb2d5fba3b6f9965c5b3e3bee489b17ce1e2b17fb4897154b976db0100f7e2aecf8b7bcb55c3d0fbfc3bcb6ac31f507b3fcb6ec0b9f2d9674caff7eed765eafd2a1a9c9d5f91ab4f0f1f766f0f6579c23d4e8e09510fd697237ee38f39f0204b99f68fa79f1cf00f600113ec112bd6e5002bd8ca09c29d9b9b0f4ffee3882270b02f702a1e7f9c40da1f732c9537f32965fa51dbb1d9ee4fe74ff7bf8b7788c7021fe007484f46d91f55c20000853ff8951d91c16afe08c930abfcf7bf34b3fc7fefa5ff465a9affc80caf692b573f6bfaca53d635d69bf37ce20c14271e30c7ab804d1de87c4eb304baa51ccd3e078a21db17bc4b0ff23483871076d4614fd6e026e6a6c24829086925058a2107762236b65fced40fc22884fd6f481122de3df611d08088835bb28781704e12141bcc08a62e66768e20665bbb5d1ca75f055cc8a77dcaa11dfe3ca1278a20eb87b5043740b3a601d929237198188a9e430ecd4401d9c436995aac0ee27cfd43ff00330c063db0dbdbcb3862a4e454a28e4461827c9a6d0c984abc7b04b17e8ea52444b3d4a80c3a92d824106638941ae02ced9b24ac3dffd052d51b2af14698677b8602931ea0fd6142d39c34c20198a661dcfab2d20aa1166af7e2b5a03d7af524473b1c8192c7f35da93384b1f5e820a4902634118f48a871b12a726fb1688dfa52b75b9d34d8f9b52ef7fee1a71f771f963787fd851dc60d65f7d21c65c6dd8e44381803b15f9258cc7e875560667c3de36b01088a6930e0f65ae3d1480e2ba707541f054431cb52466a3a2963401ca40eecaa1b7b093c5f148eb196c3f5ea3fd4e76a1b1c12d71ae2c3fb7f5d1e9edebfa6c7f1f704fa3ab08f99c4f74748c233148a28fd869a9ea1509ee1153e4b3fd2cb7e91c6bdffce999773467e5980fd1d0d0e43e1a550f88606c3c9c1466587bc80578ee996338fe12f4f8b43204d04243d771b5e4900de33303beccc9957f317a7a52fb83b74007e1e3d9bbf38fb021ae76762b22a659797bc206b6f4dc8c0e159f40ae1cdd06b9436d26ff233c87ae0ad1e1c95e1428e3ca2dce4c8d33083ef1df8e120944098e4b97cc3ed9d4df15eca3772820c7be2b97cafa5f50c12db7825d7092597a7b44ed9fdcdf67fa9e1d75afce3c34fcbc3d32ffff4f13fdf1e1539d58c60b2c1db52522b0b4d7f6a82632a10b680bea260d7e851d2703fcf3e59f65a1af35038757e8203340f1b1c4e67379c4be2119ac7f48e9a14ac7058246a98effbe363c3e3ddb5da94c3806323dc5bb96ca8e4a412062726e727c818562655c182721307b6ab4a4d6d58212454b61106aedb9a9a985d03e75806aeb1f8e1feae0f04fe96546433aa8d44c4a971e8cda3fd5a4d4343be11787c474d0c4e2146006faa03813cb0f468632620b83b4cbdd449778722b2c3b0221819f180ac49ad383d750decfee66ac69798fd47e23cbb38dc16491d81228831a68156627b2a95342a30a01aecb31e4781bbb4c2edbef54435266a91f3483cf6774a9232d658c746e1900c84b9a0d97b6c1dc34a97c1f302ec4b304066208ca16a146379469571059852031af7000b2a0710c8315cac3322082a5c8edda1da09552b589006f9f1b6d4c465f19a853f7e01121e5679019a3e365a1070ce9413b80567e4b7fa21f7278f53ee9c0481e543226046687f277dd82b9fc9db947738c5226cac231ccb1ac2e43d98bc07c83bc41968bcf3d0e51d1effc09696783abdc40289cba95853f73ab33bcb7a76b8365b12440882587713f8e8d2894553f568d60a5b5cc50f5da45170329b5a0108de00912e9e8a5885a8a9d5d8c11c4a001fad8e30c54067c4a486724ec45614d056b3f70d5396cd7b9ec730877390c702c31ecc3ffe6878e0e2c4015112c7ce1252401398a8da2881b07e33c62dd35d240087145c0342089b02d589965a011e05e7fac13bc41103508216bb28140734a91c419891d320b07ddeb248f235c3ade9b8dc7698149820505de643bc7fe333fb23084ff3e7c4d3736239a080a4d682d389a2405ef8e885dfdf71239386c219db10a6f53a818c0c13cd6c23696ad797192fc68ad571e6fc82d5c1e6e3e35b1b63b86a12ebaf9a5adb7505246e1e89fa936fc500004f635320d75693c50df0b7345446e7c9007bc4beac1f3c95041005538ea0f592b21b82d81b531a6d01adaea416536f80a2e0a840eb451427082938e5b1902411708402fbbe7174d8870a8c9a6605af0379011b8ab4f894d906cdd3f1fe4e0b70250aa55c76a6216dc4ac4bac368469c230563976eb62668450e4547517b9007e971ad80e8071250c20df9a32623b115c41122b428e3aa256123b88712956d05ac379adda5cb847047c2f3d928f2d33e88483a6e2c8c53b7b5c1e789c697076c2979626ec6f45f0159852abbd1a63b8e724d7dde64dfad6a5f6e3e39ab0fefa4a9ce7df83895639e49bc21b9fa4c24b621e157e66966de9f2396bf239732b1c2e2f689c4fe4b65b95678093ac253e5d32a63e475cbfacf3a93ec7c237d9ac55f8fa50968530069b7901bc41f0f0f154be0cbddeaac7920496a738a34baa87a778cc0a63c4c239bff27a4bffba4ecc6de7575afad737871e5961ccf4c0bda7b1c424ad03190b1862402b25f0493b2b0025ba1116e78b644a5d254aea1d08fcb50bb873835222a93bcd89d9cc28fb02f0c2c01023c3c19c866b9ada3d6cd18908938c3e2f8a481df3da884b34e41d56408bceaf4d1190e40501e37b7538da4a4110d66f13ae7ccfc5c103945bac60d43ce0561d41b5a6091b0ec90e86258b6907cb2e47c573ac8cb9d438ccf605fa09e57e2853f0afe5ab5e24cedff3a2f9eb50257ed9a116a37f6d06a3b64bebc045ed3d94daac19705810207d034416dd58031620e02519144ad6544aca54bcb163922e815b06d71fec576c8b61fd178b02cf60dd91ba032b84c3bd2bf7e5ab0aee6fdbe745b3a50fbf0e55704b427eb1e62df348d2c7ce861c0657bbb20376fc5636e16b84eb56b01dd4ecf8de5f70219bd038e9016ac3cc524230adf589c269ecefb83660a551eade6a043c089baddb2101bb443645c73c1d0a82887df3b0bdb050f7eb2a9ec8af6b7022bf7ed8fdf45a9484df132b54d4fad736f229e00ffdd8146f3d05fd55dd884dceaa070d7932044d9ea5ea0df1f53e98b722fd39026176ad077b085f3b76f0f3bbad834b5e66d6e190b5a3da3dc3dfe22c4bbf219852907c5ea0f327deb7e940f9577ade7394bc7fb4d9a1f4dfbaee0f2cd2fe11565e06495c047ed3efccba0b5cf808ccecdff2d6dff236ee22fab7f0c0fb6f93d8ebcac435c4aa46f1a435b5b2db6d3f7e7a731b9e762bbca16c6aa3c01a1b358a205a9b6d9a437c5f6cb2baa9e228041a6a994b08a04300ee3a3bc128d94ca17470c2f56057ed62073d89f694cba6a8a4b986462314cabeace3a3a1c7255e258a187a61c6d6938d5b8a83d91438f8498f6c731236dbc80fe1d55186cda487bd406bc8c5d7db0853ab8ae0f58ca98b268704cd5857103fdc823578614db94e8495819073b18c46ac1970649a04fb141c596d1a2f1d44ab386e2d0916b40991ef58b6a4d446109b7315bee1aa4b05d76f0e943baaaa036eab66abd06aadb33babd00740ff9530bfa68ff5b1f217169b69215094d9812cb005366aa2b2a95aec65b80be69f260a6a5210a65478c880190ec2bb68160df86345366558494221f24c2b9640bbb723f70e8a2900fa6336a0739dd02cde910149a069f45b331c87d957cfdc39f5ebc6ffec3dab5dce93d6bbdcd3fbbfbc5294c71fe0fa6dad38bdbfedf0e8000eeef92f7dc0e7e9e9062e69b4a327f8630e5278899431f7ce913a20db79e0887c1bc5138fa7c321e970979df0e43093218610f4e3e9c39d702d3163a2e5f948ee201ba43897c69ff0eb736edf783c1b8fbf0e4cbf676cbfd0023ca005b0af4fbeabff7438bef00f6b7472d8692776e097c4c924e38a3859d29a38bd92f6fe8ea50304dd6c1a50fa33398403dcb67328d9b191856b68039adaaeaec44f3438f6663f2313a5bae4d8461ab16750333a8a1347e400d192bec0a11a38b7b10cc0ab88fb57146090a919ed35d84c45e14302f793e160aea0a9c201d272a83501cbb106cb05e02c2f012cfd7aa5e3af77faa71f5e09e0fc7bf6d37dc3681bbb6f370a5e7b248e3d4766893dff5800a40817869e9fcd02753a48ae274687b994f2dcf3321759c26191c5ffb6fd0562e417a9965e605ada8285ed1bef05c8981e20c6003776c418c3dcb09f2d239d2f19cd3d54ac119daf1b4596fd1d690e6b2c455b6ad860e7b9c35e3bb6d869eefbb3efece0e21bd22be447fbc72836a8f53f88420a9a8df886aee7f87c8cbf39d4ef094f84086cd7fb47b362c0260d5ae563959f3fdb8da4b365c263316eb8795140cafcaa4466e882ab3dd61256fbecdf3becfff40e4b4077f9a37a146287ae65768f4deff5cec455af759db99bbfd677609700d0f5f5fbce7ac759ed351f7e7efff4f44f1f1edf9cdbbf59c7ccb2985d51611c8ad963d859120924f2845f61fe3afc8fc7b3f1f82b1e7e9160990373211e4bb6e93ab0a66c5207a87060ab37da3abaf0127d1f0309b82e1eaf7bf6ad3f40e81509c7c4534e5b62bb606e8520edf8287cdc97cadbd2ad28d72f7a0676f71e1562566d75c7c69c1a03114e43ea740f67a6156f21f827c1e3ec8ff44f2a36f9e3059eae9c531e410b001219bbf2bd6353a9700e436f26e3dff4537ad4d419880d9cfbb7f967b199866553b8250ac2d8b08727d840de3854745f75543ce958ef066716c7179ce5cefac37a1f3a267fd999360fbbe5d7ddc32f1f5fc75dea7bd67dc178237d836acc0e8a2e0eda20be39f4652597caeb4e705784c91776c58633acaf09308681868a01c03e6e1a68cf141e9148529092cc6b9e63e9c9d72e251c524e596c91aa2efe8ce04d7f003e9e2d15c817d0c1ff6d05383975ad1761ebcff86fac84bf4609beb716ee597beadf5a0652f56a70efee6f92857b4bdea88496d3fcb01f2072932d0f79b10099d3d5a58393a258d131a7c4550df3fee79f1e3ebdd6ecf43b544c0ee2fc255f7a654391ac7a650fbec9cf985314ce910e9b34277ea3d3f2fa61715d3edb0939111d9d2fe01f96efe57c53663a32bede13b094c2faaacff82bbc85ca1ff012376659bce63bbcf4000c782a5b08d97ad86fe1d5685cb38934fffe9b9ccdb9badb60af10769b734bf7ed501f33bf8c3fb8ae210e1d7d5d451c52afeb88cdf6fdf2f6d0668b3a491f5fdfd82b87508dc97fed46a759b2602efdfdbb7095cdf4fcd65be52ae068b9b68f6896107cd3c5d9ddd672e613cd773c64ea6f7a8c7b2118def15009883fc8d77676f78fa594c443c3a86948db811d4941285b86e352285c0b33fc76586b74bf1cf8e9c694b5dfd2702e16b58beb2e0a586d4453712ae5cf72d0f31c0859ecfc79cd79ac16bf3a1cef2c70fab067dbc50137ee3a27cd14bacdf9c7826b83dfe7d78679a35d8c6790701ab544124a3dd7c58b74bcb1e87c41bbd80bf75bfd0c9de5859e86f4eb7ded1f1efef2d67ada778ec72a11c004710213c4435ccd769cd8364e8805be64f839d7cacd3984c239d5cad0ff392afa1f1efef282e0fcc3c35fae8bcddd879f5f69d5f28f53d15f0caf47f57c1691f79972fe9a31fd33a5fc95b74c657cd4c5f533557c61217cae863fcfefa4822fd9b22f030fcf79b38feaf7a2b8fbc7921db9e04b26cf939fca05fde60d155ee5f33c983a177c9e5bbabeab7d214b2f0822d2af8be2ffd9fd5d12ff4748227c43d7446e1b353f475d4f92757659f893ad27ad0baae6675d4d38abc7f3cea179abeb29d75da7ce45f60581b7e4ebf2fe4f1f1e5f0942e9ef02ff571578aecec09f77d21345fb58273376cb141f5758816f99056ed76d174f995d2341b68cc231b7153661bb3b1cf309c7cc562e3de5b54a3ebcbbcc251c5e72e5cad33bae56c22deb008bddd5cda38b0ef242f742faf5fef5ffbc7fffe6269faf661273ef6b36b1aef10f5eb58955fee7d8c4d6fa2fc88e255f179db726367f2d4d2645a3c89996bfac73978a352ef7abc37765978adf7bd335a938a8facf86f6550afbdf129117c4634d341edf7f7af8c7f7bf7cfaf8f69c3c4261af2e3808d782eaeaf9d974caef4329b986922270682cbca5ac5f434754fa176c449ef7e79a6bff28ac61acde3105f1920f894adf95eca09965a1c95deacfaef679632a76451736f9bc94fb3bae0a2cd8a80aee446250b0751c10e7a7c38f304fd8b755700f8793871f87546cf9e40e4e32eb79bd873252b5efde9fe02d8843ff8bf3449c87d10f7b77e72dcaab4cb1e14592ffd33b3f5de87df7f83882a74daaa7f0e50071bde31cfbc06adf39a65eeb3e6fade7c09b54e40ccde76b35e87475f8d210ee7d072bad701a4b03c9586049231632b3e970b425aea92e0cc759206d61735bd240c8e46d69e034ebeb16effeced2516a48ee85cc426ee3414e57857655789d6ac9bab249ee99609adc5ecae79944fb6738c9f5cbc273556e5645e6cffff6e9e3af3fbf0e25f677b805295b53f52d80abfb6da9c3f9015b6a75574b128aada45a979a68c4e6680b0a1a4fb0ce5601465c4520ba13d10d449fd4883ba8397082925f172c334767862e6c3df51280a17d7c02826f6387ab1ec30d26557f40f7e00b7f00e2437059c00d5698e08541c1030a7e2bc01911d87467fe3193187e22f34fc4a330118f266aac6658a272808d3d28fae758a6e52a676e36604f01e083751cd234e79f9c4b52c70de717656a8ac8ba5ccdc435d9faf9a7bf6c1e5e89baeb7bc672d0b70ede888ea4a114531ae4407d05f8d379017250c8b12a30a14bec0084e1a4b72c7643190bc4218c04b40df28182284849635738f550258d450381e9554d18d4a1d471e43e37c02f31a5434e945d77760562834cb46371baf0ee5086f31a3b031600d0f45fe43aecfa9a0067128a9872f222dd22b98c6622fd2a25bf15eef6884c4b035b38f0d43310268bd94bdad3889cc7fe11480e2d50d945005da67acb03d0ee75198779f3483dda3cb864a7abe41d678f63ef4b1c09301203386ac59bab27d9df91d43482144a1d501a351600545a1d924dc015782eddc9cad16fcbfe91b2d5ba5a057cf54d7745414690f9773c88b399e0a3a5b2138da24b87e34b0d1eed4d90311734c9208c647827b60884cee2e098c314103ecafeb13364a4d90b5780448ed49792b0e11aaa15c7c4a525206b50307bee048c69bf813eaf3b071ec98996e85982d91ee8fef0d24553bcb0443dfbfbaa9e9869ab6ae2e7873f7d78736edd3597242d14cd89eb6282ae3175207316a01ef5119ba60610a74e4125718d0dd16d5d8055a494b4d98f5122694d2a01286535951293c0237a449914fb2d96948b7d4079b32f42512af308f89691130f4b2c4924951e4bea3df51abb627c1cc0f932c9eba18dd414f4b749f0cd6914a7fcf5c8421b134d6286995d25358ecaa996c836cafe40358d56c2fcf27041c4f50336a6224acc91571ae4479a29ca661dda46d3d13db7307a1a348fd9f93e022501941aa721f66d9672137b7dcd18b7aa261db18110166f13f136a88568158dc834af00111c0866171db167c0feb2aa0b32dfa4438bd997bf492a3d107ccf6cf02e6900ed557b1819a84e8eac854603b1b86997c1d6be4c303667eb03318a1e4853ce7603be9caa06d06370fa65ab2fb292694e0d48068d83294519f3874ef8524a43a3753ed3478877a3549a29043621b2b2958ef30af0a691d8b47037a5dce304c7ea2300b48c3491978d10aa9a8151e4dc3ad69bd3180ba55e62aacd4ce406149e3110f46ab6288ffb0a08e163ec4cc0bf2d9d42678e7132cf51ad3117b353bb0d1725b48a3e84483bcb13e51d574b145122b18967620e15d070199ced2643789d88861f0421842ef4de4828afdd5405f87b566f081f6ca9da77836770066fb6f34b4b996d10bd0d6a6289087ded8e86c46c478468e50a2669e0b515444592e9819ee0a090a8bea016a1dfd6b52292d694e29f9f7eddbd41f6875a31e2e544b702421822d07664b2f19742517507ca52dc93728918d0b2f36fa8cda5e790d26c9c02eb7f07dc1dc8399c9dc6a64c1b06fa72032e5af3180947edad1889207b0c4c6a4c2fd9c414f8d6489f2020f6ff8988e3e16424e27ba69e069658cc60c1ce0206460f60b92d6697174abc58b7730ce76a8a4b6cfa3f8ae37bc31c6c0e6452a3a616eccd1ce5b9dad80a4c6c05f14d06814e8f5447620f49e3aa372a5727b94f97db2f44c052127bb4c048a949e340307bc3387120f44e12818b6db603bbc960a61e92bad77b319bcbec12755e9ae13660776bc0e7c2050d1a846c3244a9ee14d6a5d91fdd6eb7fab82ef22ebdab22ef496b22ff7afeaefddba3530a50b0983895b29b1885dc1301b6a04419a9974d19d9c69341494b28324c9d5a1fc8b07a651b61c4d9206c3da1ab0d39dc80a1900bf46d4eb2f32c03b29c008bf6a40d3553440c69c8816506fd73e36760173b9cb5da2cb064c7b7b6761be5de9dfebf21b08bab7e5b50589594db326c026a6f60662dec23fb46990e9b0d6d02bd31ba2658a98a9831a26dff18b13d572c37d2a579103a2a41a07f73a266fda0363fde5afdd2b0dac7520f2217d3a87e4dc035e8d59cfb0d11efce1a6f7fd74ddacd64b606e019ac05844a7b294ae347cdc9e10aba07de5bdfc498669db399f9c5e0adaa00c49807f076366b69e62a6666105cfc90fe63e9876c257bbea6e300f958a075863bb1e3689eb9dee5ae3a915ef31ffdf4bf1e7ef9e5fda7d77169fbaea5f6ecf194858fcbd99f2d677c06f97cbe64221d7148576e3c6ccbadde572ee2f5cea3012fd1e32f3b8348bfd21bee11ad790588cf7dc86525d6b8f14aa8f173245d0b61265e0d61de3fbaa5fe45eedb28d99d3abe48205d7dae64df43fada22499ece505f94752dda5af256f2fa2b5c97f429b8ebd23e1357257ef3e9e195301dbf07e45a10226be64ea71d40d43888a6d2169b0c3ac42d962a8b591c7d444e82b59d327680be30653410e2525b70785eb52902f002013bda536b3baa36556a9ab42f94b2c69a58a3e324e7c4d6a866438c5d6c2d75055eb0f5166998f802e3da3e7b894002354b41cc2ea01aa5c017412cbf01a765581336eb19981df2b86580388f9298318524141885549862368fb4e2ee5046200dcb5281fb6823a71792010394538f7d07086f1476b112766095d261f8c474ac561476670534038d6441090565f1d55a9b0a169f378e8e55104054d362e58b0ef0ada960be60e5b3a2b65b56b33ebba6d297082c6280de54bb4c531eb1d9146cd8c05ed81e04e454543139b1ce826845bcb9dad047dd5ab596a83de51eb4a526fb471918c4c8acb60bf950b02002ad58adb60b2c465f03af35f048451f54536f1ae617265a260d1ada0e348723549b5a2ebebe20891b961ccdc2012cb84d737a847ec3a8ce00efb46a80d55e1d9dbcde56abc9cc495d89e616313c7373a466c2a762524963d7ad250bf090596cbcc6168b46c018e1fc12fdad91153208c80bf7637dacec660e76d3e2015dd646c049c29c4c418cc9ee656f735c13058ea95413154e0d03acf61d2a22a222acc294837f7a750187d6a6a1d52a9cbd93587f04e06ce568ff8b24dea16da2f7dd8a49fa30b3c01ac22ee82514ac1b0927a607b52141c3fcc2b3cc1e97112535de514f54cc6a77cc26aa137ab7d8bc1790ebcdf719261eb65580046bab3e506fe8fc22813535b1a2540a8e956fcd365010c86235b955807b678c5298bf93e50ea8f7c266f56aca68ec5ca3f508e66413230ea5f804bdefc89a05008dbd2d440e753f3c9aa23bd47dc9a957006e97079ad856fee5ef5f24e9402f58ba656eb343e092ab0407d022e806b179ff0e5b19155db7a43a2cf75cad5e6504fff45c1910f46c46df22135cbff700d42076342f80def754002d595101a6616501a8b155f8686864abc32c90432ccb54d38643bde582d8ab1484575865d45046ca03d3ac1a80c3e4a8fb54ad356ab6d6461d591ed15bdff45e89b598d95080145d7b0273dac8001bef89da2edacb47bcfc126d941560495bab0e80b14367176befeaa18e03bb5ee034cd6486ad778dcea654181dda5aee417aca1953dc3c4976b2d9e81d88e74a17ea0c53739bd8f4d0bc3a73a2be7ff4daa892b45ed4a06f86a26fd48e3a2fd699c48c75bf878b49800d746a8fb049500326fba90ad10c114064680674c36269155568754104bc6a573b1ad10c2f9814b00cd60d0a24ad9a133f7ef8e9cdc1295471be8c487a2be42b629a32ffa09232db6c145fbee656144c18856fa8d6540a36e2c9ec5fc1d24cb559521d187072e2726be3eb90c4bae10cd59209a1b1cc6a3d03b39867334a57b72d315bad256500138f1e86fadfd3d07838139deae42baf946b1ba198002007bf1e38548a9014d20981c6407e3fba1d14f73b783a1c1f5d14b000527c25261e8e3d69ffd838b2e41b224da3ec4a4f1287de30f075c0739def876ebb55f40e51c596daf3fe916dd26796f51f518ceb926d42ba2ed896b22ad76f6e463886192ad4746bd2d8cd74512ccc53d28d643d5b7cd17a587cb101efab175f6e1ba56eda4c6f40b7b0c1da26361caae99e920ad03a0049483b0d2c9b961aac7646045b05db18756c6bb06c39a7dc366c1a3070a900c0d7c015ebcb76f4b7bc7c03c51201b859d46c4666987cfd468699ec88a334638262312d6f26aa44d3c13b8d2c0b86a986f51b3c4bb0bc4f961f8ef78fb154b6390a99f2ffc39680baf81210f7cb25a0a1bfb50484aeebacc17fe412d038642ba4dfbf04b4decf57fbf8c3f3c3db23b9277dc7b93f90be237d97df91fdb7e31f0e67ecdfbcea5fee94e55de17c539bde93e61f48edf27c7659be51f941e59dcabbc36995fbc2f9e1fc248e6f863e0c7d370e4fa1c1763bcbc3f9b3273b73b92cd12cc8bfdcd94d52f841fa3be978017a0715fd831953f59d7f664ff16bffe511bc82f9a1f0bbc29e16716c25ba3c39f1aa7e383bfb0e65be6196f36bdfe1f85fee443a6aa830c0e03ebb04085e6bf75d1730939a7521b39455417bffcb3f7cfccf5742c3e46f16b542a9c04e426089e9433038aaa974f8b44cf719baa586c32aeede65f3981e7d6bca0e7a2a21df9a5d0d23c8060e0d0ca84bff18e8b578d80b3dd76b69bd6a3ded4ae5debeffd7d7d9349908a0df0a354adc5229fd19f58bbd39ab6372c3458a4f4add4617acb592f02ddbe45ec17e40c2a86e3afb309bb3c109c2a6fcb223509498a6c6f762a3f0f0397df08c6d96de0e3fe6535e6c05abce6bad6069575ae11f3ffcdbf6cd3503e062ad62ee6763f8627477bceb2a257a231ceacaabe750abe150ab7647387d1c1a217823dcceba2da3a79e65339b57889264604f6550081d0bf362f5a31eafd53f12af34c08ffff1ebc3a7f7afa669be27da4ffa6598c0d7ba3f1fc3043ef37ebe0862ba70581e6e85e65477c425105f0b34232ed1525bb24993064eece4c9dd37b0eb0d655ab0d0858d12df1b87b70338915f6cc353535c6bc8d3152fb6e6aba9b6ef8458939e5f02ef38b6db17c02687965b0319398ac7e73821fb3bae2355b2498624e975674d9732da3765c4256ad780cf794c6c5dd39d6a46a31daee411e6f7d252d5800febcdbd9a00e4c30f2ca3d77b2a6cf72e2967f816e800e5dc6038dd6481a048175cfed26ecd7973be2c112f2858bfe0f5d4ecf78844c7a4ea5bdaf69bc468ff48e2ad56aacdb4eaa179e3a179cf45c18f0f0231315c76f1e216109b56f58f29049088f92340229ed9e6d0752cd9b90f5c2730105bb2d47076edd788c38baafeec921705e29ffffcd6a4014b4b7fb40e78414ef68f530ae2948a837a8817ea219ecbc1e1076421e4dbc1ae040659462e0cc185e14c2fb814cc1fdb83304c51c8530ae2940948c1149faf10867ffef3cb92f0cf7fbe2206af2400df31b3e0eee653a97c63867f71206fb3baf234b8a60d3c0dae69037f61cd1eedde6972cde3ee3df90b330d56af5bc0e1dcea9d4f99bf5e6c8bebad70a5fe3f7d7c73f0f93c7ae200ffe1053cb3912bfce3248100ab46600263936a576be2601f8ba6120eff49e79a7652ec85964408dd3bf863dbc153ec887e7037e328a9dd123c1e995a80add5466a4be43482e7421ed1099fc749ea8ced3e30eab6507cbd6c47a5248d5a134719f363899a4ad4c4f8f6e2b95be53cef21189a7cd329e45d6da1b64019f7f785b19ce7eb6511b3d1da1245fbc0ca5854a45ae514f5048ea49a78ff3838619a36369247ea70f2045b83d907a128d6b76ab657a6d4acca6bf0680a84dc554a63d7435f443cf8ce59744a10b64ab064bb10b17cb18cd46227143a12f6714b4ee505a1fdf4f1ca18f2e9e3fac8f1cb0f9f3e7dfccf579b287c8f6f6d96d4c8ea35df806ba3f14e530523db96b527a1be504d020674d6034160c960a7965cb0e54f63176d4040482437dd542e0990ea64f3af1e6ad120a5a4cef318be4d851267b6ce526984aa494462d5d459ac878c212030e21293f08855c0b42c490b086ea9563b27d23cb04113f71634e50e81cb026fef9e0b1c7ca5df70a1444d376cbfab898326d20a921a919c0aab1f1f4ad709f3d5ead431e21b88da50b88285982a9152e11a2ba56663a8a4d22bb6482b99600e42184505cc712e80dd47383e25a9608aca7621a5daf57694d47b092a372c9b498d874879e487d957be67d9e4036fdefc02c569de52e654792c980793c76a3183b2969d4d9c8a29031ab7700acedd1e55ad3f8caf6c6569895b099cfba6724d5a5a2836c08b89604d63d24c9ec9d5fe4ef29c090cbe29e74841bf8f8253f3368a1b9bf16001cc69c1b40ae3b9b5b0d386a7fad77266991ea62af3c7b448e6f5715edf52add82e7072e15ce3d94ce52bac8c539f5fd715a7f47595f16aa8597fd7167fd7166f5b5b20486a1b0112335d6a4bc3467b39f3c69d01cca59ddc6acbc1afd63445bf9a4c1350b2343f7dee2ce07eaaab890474cad24efbfee5b0f12f793a05aca61ea073be788997d4c75508324f5a531a4fdb7f7cff6f1f9e7e79ffe636d32b0ccfd27aea3bcc472269364355e178848d493f5fccbcb5a31bce08ee3a07053d8159acc311ddcc46ff1c8de880207a02d008401b7d36791e89109bac66dfc24baba014d82db84d1dc56e4b4c1a4aaa318dd022628c53bd973ea9717cbffb0b07edb3edeec36ef7c8a92d883aab31716cd14365ebfe8ebb75ccbe860245abc0a8b4068c7aec185fa040913a1284ca1f95df2aec4b2c1c7b7eadfcb7a4089e00f1c8e411bae979ff283970cebf3fb7af2ee8fe9134a8fc01395d2be4fe912d1d9e4c807149fa1915d8f485d74b57f88033e7f462d3af5d4f9ef960a8fe43aa7ffd35f78fd2e1fff47a4fb8aa2c4f7a6f55619e92d794e61b5c4cc8a90ee798846323829e413ee37eedca96de6b1af5de51e3cc7010d8c67a7439bb1255f274e99703a71c39714d69388f3d3962119da86c4dc0d69ddf48afc49d6c63c142531c3a697756dcf40aaf667bcf7da4ae30f8d90c716d56297d0431630ab1d655c0c88ed900955419f4c035127b5802e832b02536741b5576ced4f94c45927c9dcbdf7de1dda4ec7c8c8dc34544cf59b4cfd329b8c73fcfdef2ecada04d3a1631be3397ab7d627d85626d79e2fda75f3efceb87e5e197b7879962e633736033a07907c4f81aa5a69ceb4225b5ec2ec60d2000a4b168ca056ef3aa12cd442f631795e1e255dd9d2fa9021820535d248d41eeedd51164c223169b82149b49d885f6d56867023686f8ed0d797541c68d36a5349b44241a66dd96d4b446b5790d6296c7302dc6fd962bdcc66b0b3675ca44383f1044a008992d95f00a627622177f0367e453edbbf9d8e08ff522d5e845da3449bdd9b463e416aa4d13343449adf4a02565d13018f335af81e035e07503bfb1b14959ad822ca31e1551eca3a521d655cbe0c094d3a03adb21783bc4f35f027ec1964154339abd46210dde2cfe1a1266b39c3d395e94c906ba311042df8b87d630bcf35531b1b02b67b378abcc2a0817d563a360711ff856e17a396cb69632f57051ad6817481aed44d230d5a22967826707a2067a374d38ba8999749df7c7d92c17c2102e04052e3e367fc5397b854a1eccd4c26702762198e14c642d8fd15bb4f9151c118b2a2259ed8d2f055dbc24de145755c3a9bfafa98853ea8aaad83e7c787b109a581c4278ef705c208eb506c9517b1a208404af98cded3803d018263f2328a0a41104d4eb2698000b7a269eb0c77d03ea634048c04b6b6291d820b221763e639d57a85831e6cdfbc7520441ec00f7210f808709673d04b1721a190e96d909d9c78d3058e24bf24d1b18527379ff904928bc89e0f454ecbc6053a10b06ed2e2727f8cb898e8fad9fcfa04a97ed85e7fc57deb4f044ad4258072571ac24e1445765ce04674ddaecfcaa9cedfefd4f1f1f3efdf44fef1f96ed2b4d67bfc36794b36904b3cf5219c16cf0d653a9118cfc94f2d850b75e1b8a23483701d89b5a6566fb5e60228187b501092735ebc5ff2f7b7fb71c498ea309c3b7c20b48c20810fc3bacd1d89accbec86fe7ddda570773a6f6ce29a54da8b2ad5415bda3ab7f0d0fe8a108c943f593a969756f5b6579b8dce9fc054180041e0c5b38064721e9911ace4c6b64f7eb3389c6b2d641c64c8a4413e48e964e5a95aac09f6e24989b33b58ce5d727d79d882e620b93a586b3a5c05d4a7bd446b99bcc861c228a3085812ab02be62da02b8d8e5d624ae15c487a78e6f410470deb93b0de1f25acc78f6548481ea8f1c91b01a0336e7834a88c9b5117f8d339e40507c0df5430d87e53f52e173948ef36250fb1eab54d83aa77b155125d78824bd401c435c0d83400c2d481cdac8183716dc74084e25652281bd72ba3137f51b97b52d4fc15623fa7de6dc23f4ff3da24786fd43f4c0d0686732e7257f5069b74b25ace9b2692fcdf759349aeae603450ae044d87dcaa7d6a0275916edceb5a7bc2104aef87aaff1d0085bf3a82af0edde698fdf4c3e71f7ff8fee75b8cd63bdbbecf268afc11e8c72ce977f6ecbd24e314e91226c2c30b2484d7a017b652bfde885ca855b8f549a8c566bbc9c385463e305cfe3cdcf528d18406a934e0a22835c01cf80a483c02ee5ae026917b37511eb74d0e1112877682979f1ed17defa271a5c5617ce19e61ca80fabfeb51af6a32b117d3012f0336e43093a4f79b9cf4ae2f369706b6ef3167d86e341d44a9f20269a5220ad6106b13d780a397d0069c883ac345a408a5128a24abb4bdb6dbdce4460ad3c84b16cad87a140da5daf2c3cd6ebc972e8dec9deff14907d697366a750f48a0c079d882282163212161c7b6e2648b246ee78e0470db2c0594aedadc7e67c7b5d99a28a2d79c60f78e48e52cd44b2cc098830b0fae7bab4d6a57b6328d30061c92db5c6058d474fdda97662b2186da08617a8e5778def30e26e335dd95466d815362825f3203162078c5d928e9154e713ae1b7d9c5698a6d9ef1f3773f7d7a7f18ca09e6d3bf3d68e27668919bf63b226f6613d0737dfc989bc0177450d9098499ba8fbd50c6160fc0293956824b53710b1590c00e5a5e3f70d2bbdc751ffb00106fa3ee7ef4958a119046c08f3680885ec6945ac7e6c2c0e2dd8521fd97f7e7d29801b39a253d8f707b1ec0f6869bace171cfc3d6c6ede8bae731748ffb6a33baee53e45a5c1eef87a950afd700d173ff7005c4b4a6572a108da27ea50a87d8d21aa7f88fd4a1bd5e85dfd0079cfa578dc2e8afd50011df4deaaa7a11b788eb15d67a6c1037b65b8f3e902f03133944ff3791c130872ecdbc7fd97431b437bbcfef11fdf97d74f647ad8a980c5a68e8620a60ee38233081438aadb4b08709a68db67d1653ef85d499b00ab5b28f2d536e7ec5ee65f14b86ef2a6eb560eddec7daa169d9d568d5942853efaabbf9a2f089ab6257372594e59870a6a98e55043f5bacda924d38d8a30ac12be2bb7582581926fbe176ad872ba3c7d62c0cc45cbfa2a5414d42c2ad77c00db32c94f8d88b055de8db95af53ad11e025b2b57717e8f6df3ebf11d9aafe6111401ab511a4f76b9c4aedb9743881e06701388b23b41493bc2ad07685780091a53b1ca55693c0b3d8f25d8143cf1976e3bd06e0ef0dd21a6180ce6d12e0f4c12e8ff7d6e53dc7aad4af4aca80b0b51f0d9a3a61974cbad590ba5544da00246d19419a985a805fae247a239aee44323593f678baaa7431b114f162d9415d1f3f0a5010fb4d49d47849a62394d801c13c01adbb7a35af7a059c91dbc60306bd106075a527234e352a4c9d0a0766a0f114066c8c28fc690a338dbe94441a8dbe479d24d84da2065896aa256c04609cd04905902a3930c08e9452dfcd1abf4a97fff6f92259fedbe74daafcb4fce7d5e79f96fdbbe3a7c586dae1f172a5612a0433a59c4df88ba2c6abfaf73de421f636b8bb3bf3409a09abf82040ee3a7e67ffdbd837caac2177fceed9861a62b0658d6bf07be34d6d4cab6869fbf93b7f96f8f4c59869e71f48d043da09e0173a31f7bdc91ba98cf973fa753ffdba1fbf5ecb0b67e585d37aae359c49f66c5335795b46f0eb4ce37f78de94d22b5bb947a2d824a6e3db0bf4f4af5f7ef9d37ba4a7e2275f7b53e7a1d3d7c51813fe37bd1b3739d3982b506e4a2df4043ba14c7239750b39090d24083351b0442185ac3b6e25945496f9d6df20c2003edfcba851462559fcdb1266210d26f2b0b751ca81535d80fdbb3a13d8cdb4cc97d4a318bb5ca63dbf0df7a94dff2ed78af00d4e4647937fdc7826ae2d974ab28fc554b952a85c4e5d3b6ca210475fce5c062639ee2750325d760f79a2974ba4e66f2f909a7bf1bcb7f3aabf8133e77d94e4de57a31b73f9263cad5fe069dc1504dfb4fc6d785a396169e5b77234a7954b64e66f2f90d97be365dc32f5d183e6419a740f9f1af5ab31a131dad9552afced12407592eef193e75fcb53ca1e9072fdc3dfafdc90c5e47c851e5142132aa39e7cdb4ebf6dc76f6759e1b4ac707a5deb3653eca30c351e69d7c4cbacca493be687b3f6f157c7fdd2886f8ef5a78777b770218ad2816bba5d63beb927e1b4417df63466b93129f1a38c016048394d80e3c01cda0ec7dc7705b11d4d66ea230e45800ee353e2e077970d0cd051db1dfbe9617b163d3cfccbe787bb2fefceafd2348b460822571870903861b5199683c9904af546b9c210356aa6224b06fc21276ad84ecf963076f5007d0950a9895a8ed5167041c81158e2d71df712c4b4a472db439f40a0cc94d938236efcfaf41a366f9479272d9134a81f0cbbc11e73a3c1512b698b4d888d0df716874dce2be14c1a0a80224d79d046c9d1c49e11c534e10366cfe9d3e0585f6e4613a421234528262a7c55e1380abb4593b7d9f4a0b5371f3fe6a4f324ead60f993cd7f500e7f4e13c8292de9f3d9d1b1dcf327855393fd2d93675ae6f2f91e89b1dc67e8db5682934080374a87a57f5f1630a55899bffe9c17f597a20b93ea6b93752b62f4f1301f785584e9fe59ea997b3fcef2db3745aa03d9052899f0a80c53f02cdc186df133fdea7c872f6641600fb042fd3dea08c0870b4f3d456d2b3a41fd3c993ebf4788f7685f42c4d0634de49d3ee3dfbc883c926ef492da3dbf29c55683e3bcdc0ea78fcd35359fb1a8d72fe30a08c7cdaaf55014d93caf30c7d544e6be315f4e13aaf92a59f599f7d608f518dd3cca38fd2f9985bb366daeb63eb8e459e370e9dcfd289cb0921cdc69d12cdabd3efe2a9fafaf2c2e4fbff7dfef1877729ca0328e1b772b15c9e3fbdccc5eeb946ecbc957a4024fe7464fb29f4d86f4a7d7a107b04ccfe4d7ff1ecec89a3dfc7d3bcfc613fcd3c00511fd109ceb93ec254c13d6ed7941c41f04e46a7def72d93a999aca4f5bb53b943d1b657ec65e6f05e220b7b77892a7e7c33701698fefd5128b2204d48db5e1355a008a77a268a8952ef968011c8ac109f75b47dd1e0635af600bd34b9a1dc8ac271cf31bb850a2c446b8177de00c8e4a124caf9d6915b5d7e10eccaaad0d03d7ceca7e1c17770a2791218353169873003ce586f10dd2872aab1171a1219fff3bcbd66f9cee374af99a8de7225ec281de36b511ba151e93baea1a77d1c619c3423c516b81d3837123eef80116490d4c78f05e69db79282cc9647bf5f9f006b3b4549c6d22b7c537fbb58f17b26e4abf4fbe3256499a7b71768f8df6edf1f5221a782a8907addd36fed4aae87e28635aa087f103a8c5c6ddd142a0cd791e8ea442e8ec21f1b429d89464f63dac9ddf9e8bd362477514cdc9581adf94e1956831c4ba2366f4d6cf41d8255c9491d314a32a6020f6a1ceaa02a481ffeb6d2a9d1c22522b2771748e8fff9e5d3a737b236fb1ac914be6cb7a59aa6e4ba4aa9d1ff2c6b4fe1fef19e5b0d39d7df416ebf6b296d629a8fd44c5df770c4669ce501ee5135faa9274741301121190007b8d5466504bfceb80c7ef2d249f295c9ae2d70afd46bc83843420447dc2a93de42c9c2655627bb01b8e2f8beb52556d7e02a073fbcaf61d0e0330e3e322c289788902c60c538b61ae4e868bde2f69a4bbb5024fe5e4cad87b63982766a25aac23b3d910eb4140d5ddbc970561fc4658985a4c78688146aaaeb2045188a34a252993ddac2b3f9521cac9db4ed3829999269e3964c4bde43e52d511031f1c5678ebaf9ea5401cd5f9a2b787961b2fcaf2f5fde66cfee2b24868c081677b16c711c851477f342ca0403dc9c30daaf7b27defce41ac8c64ff32621d25fab7b5349c483c4e71c19e13a0aa2e830ace4a40ba95c65e048855c180b4cf63359c4f32e9649ccb259ae9faa6649aba9f6c97acfb07a78bc678592f53758bf8d282e1193bdbb404bef8de736871aafbad17f2f96552cda85867e5772b10573fe1c472477bd33d96be335b8a7712c443edb1a821763e8c6a3699f33361413e567540290d22ad7ac7a53f54ef499be73aeb44484e97fa9ef707da6da9810f35c073a4d047547f490e5ba144ae359a510de486c85ca04b8743671165b66dab79bb9ad1072dd7582a7dca0d29fcf416cdadfe8d81a2411ddea61110fb4fb54509fb8f69901a1d55ab435a1f53da2c7862e24772c959af893684f105918ca461be77a9ba3ce53d11b1efdb686b5981a4df2aa3680270f433d883d576a7c8852cf3fb8ced67fbf273da767a94ba7732dcad60e38f5611f49434ea7fde4e15a0fee7ffc78cfb696556c9096bed39e5e19bf9cb71810d77d948cf8624603cf7b1ef8dd992f8ce18559f2ea18bec6b02e31ab4d4675f8e9cb8f7e2aff761864dfc69803861c2f8c38f29301c773e38d13c38d96115b66ec3917a0ca152acb7ae0be9ecc878473f97de416b95d3eb5b742a41758f4a849503d53b998dcb20b33bb1767fc99c64ef2f0ca6d9cf3eb6bbe44cfc66e7bd8cfd3fc0a09bc19c2f157ea0a25e9950db091c3c9a07fffcaa03f2796c78fac0293afec44108e44b0695be13470814476229506a41a4e005db4eb1f26a859b37cc910e43791c02538e3e7697e8504de0ed2f82b69a02f0c04a567e3fcbd51c36413cfe9e394291897b7de96cc3bc998b6e9eba62d38004ab1f90f7fce7a31f9de73bb406d3bcc7fa3cd4d1afa6d047011c0f845a25f218137c2b0fd8af1c7185e758ce7ef98f3a70bc4e3bde088d4860e231fa47dc580610d3026e00c201c19c01f61262d07b0802d62fcad2bc03656ee798a8be3fe1ee31448728cc6dc99b4d51d2263da646bc419367519db0d4f57512a75cc5e5586d97875fba46abd9f4b8bb8daf814117c86887f2371a4a4d35456a9a4b2b7b5bd6989f69b84edfb36ec935cf0bdda48656ef37b4a3a0b0c4f05b61c4eaf6b0583577027302ae7b589b34d482c6b6bfc0f7cf0aa63f1711c2f93c1ab02c09b2dfd5f1314c786c9d6454a7927d2a90332b80ef42d7a0b7d3a6fb36f8661187c1430083613fd32071e711ac107328ce1b08c639421d035130ab24dd3dced223edc71fdcc0dd1d602bc68d40755f1db5995dd6c4143a0d478ac753c493fc9f55746f6f5d5fdd575fded56f4af42252f46f2b36b7837d86675d00acbead399904f67429e737b35077c9adef1647efbc48e7396233a2ae6e88e7bb7b98dd5c36480ae60dc522007e45ce27196b38f8fead3e72f19caca7ae6cc9e7fac55dc7923cba4e0138620a70c011688f3a35fa1825f59e25f5fdcdf5f6c8295ff310e8f75cf43296b0ef3f7d739e84a04e18c088213810f7f705a383269e7f1d248470975000cd5f86fe1c97f41688e0e5b145c805b7c5a23b6e8eef5756887952ccf5682b93439a59b7e4637bf6698e843799908b697f9cffbb7314ffa9aa37049a1c99280b20e6f77925c6293d0243679c0d6b13d0a78e4ceed0dbbc8f3a9a77d88b640dab31af1ecf15e8ac25498ad5fe187a6a3fa4f832f5ae9eb5f700333560d0f362d816bba6635a6a0bb990dbcc87e633ef3ef301fcfbf3cad039548293b368585b37df204145a21075296f6e4c7c775996f8e68a1781db3dce4daef7805e9f903dfcf0aec075a19fd6739aff8695b81c282665e26cfcffb6d131e10c64bb2fce5a7e5eebd619868452c7ed14ab5ef7291c06d10221d5e0aef7bc9731387332b94e58b7726c56ec254f8a9ceef04e2d07e284cb207208fd6501b69ff2eb35b55fbcfbabf98823425969bc27237ea218ebae252841597220097e2a1ea04a3c093c3a877a3def8d7300126d108845e061e513149c9b8ab5bd68d42a3dee80ab2fbbccecc729325ed781036c12a15fd2e0b251c07e1e7688682ac1eefabc04e5606a9ec4ca5cc920e3cc4f2da1e1bff72714fe88840bba2267fa154cfe932411b856e52b4bdd82069a85affff2f3fbf115d7fcd264aef88fe5eea812bd53570524f362ae2615db8380e6207404aaa1507d9022b89449a352880476cbd04d2f9ba3b6bea6ff74303444e871389fffa2ba3e3ae33415c13a4d895b48552a975239f42a56ae0ac945922b746c2e34ab852e3115aa1de14a6c8462b08780f80f766843428015f850b353f8fee19c4c825c79c286905904bd6ab5ea9a61c3493760186a1e2585e520d268fe580389159167895e646c9f8009b9ed6c01a46019a0495ccce2a6abbcac3c1d5e18cca8ceda83c845aefe1b8931d990bd59c631bc40aa3f9d646e45e4998a320b079bdcac9d40bc738ecf0b305803ab69ed771bc48b54f44b845ba4f6f2fd1efbb23dd5243bff29d9ffeb403f470b2f7b3b507f4fdd34ee065f7d78bfe8a975c153ffffc5fef6dc9aac6ec865c6b4f376e999749dcd140a3cc7fd79965f13721c1f66abe0ea2870633eecb6bd54548a59e5efbf0fa0c0df7fcbb6bd18bd5c9355d423628ad5e08177e238e337c6c7b39b6dd2d943539ea45cd882df2044fd3e08b58f38a4f638b83bd9b4106f06a3e3dc3a8c92b480d3273f89bc7fb84e5f41fa71c18770fd92ceace72fcef68d3df6d41266dfda3b5e90f1474c47afabd7d2770b17a976dfa43055d5c877efeafcd55e8e7ffda5883f69f7ffcbc7cfcf4e7cfcbedfebd41099a7cc25c767598649753a3c64b64aa1298b4c64c750460891624a05c2e1846e896b9ef4d6646580e42381ccbaf4964ea3632627f0a3094a49ef8c2c51efa5d2cf570e218311f9eb837b0c74e2815d676cf9e9ea6433c85520f67c9f0f03c55e88752efce13e128b2bb6f5f1eb0b781eb8d46917a9b07f512fc3a6d1e4deac37ea71f399d5b9fc04647a8eea490e96e42671693eee56fa976d21aa984ce54f399298c30710b695704788280ef7b91074ada0b939a08dde5792d248a501917a9fb9460b7c8fcf4fd26bdff05b89a6fe755fd35169a19a8a7087101253a4aa77684767c88ae433757aaafb52328b9a339f502b35a6639f1d23f09a21db4df19073c06d83e89d60d1c2247033889d31d61eb3024685a668cc7295c05c8560f71debba8151d86b1b99c14e6adbfb0a59f498264a6be8fac194a12e28d340f3fe961bc6be41689f7a6ded5d83321cc6b9bff63c70cc8d66d370619899565be4620f088288c2d10efb5060524593211ae905c4a289de0ada233a4780feaf14673240e7cd940f88c94b649f124c12bb4b8fbfcf0eedc8bde212902ddd925fd0c41ff84dc1ecec8ed9c4ecfc974aecfef249751a309c4df607af5906bff8a983eaa9b317da630f3f790ebafcd539b66af4d537bffca2c7d7733b4ebb329f67b82b03f4db317f82feb94978119cecfb7701bcf303d3d5dc089392e1b50a14b3951cb8b13edc38c12e8f3e3696ae0513cfe7154bb4d0e63d64394f4cc8497933c37f83d49126aa877dccf9ec45f2795d7c8648b44bebc3f841629f50376ba3ef40ffd83ff4e4bc70f25a9dde3d7fecf231f9fd93d527ee8ff7e3f84747cc89cef4c6c4c1fa4dc72fdc0f543fa903eb0496a3a3e08157b5d5b5493426f357dd0345330c25e4a367a3bfdf483ef06e5e70f3f70bd9152f7a57f50a1f2dde9dbac1db511fef78be3f7e5c24afc657b01fef20e513c6d09bd84bfe42aece65c87e3e385c98e787f9b735d7affc80d2ed64b544580d4143be67fefddee7aba6179ce4b4ef339add5696d4f97793eaef36b9d4d0fb24a5f9e8b5fb6112eedf9e6583e7cfaf3d5ed5f6c20dfca8dff2b87f51539e9a90b9fc9493630bf534e12ee108d1bb545a847a1120003431c06098d3d038fdedeb3491826255309856a44d266aa620d05d0d7cde19c2174033fb8d108290ec41c4120734676f6b6c496ac68fb3f002595247028d4107ba800b6c514ee81d0f395246844f40c0f4dd263169c1e47561ab843405e620f2f421c5aa21286205a0ed5c77b1e893061fe70438b3574a075eda9a1ed0f3674a7627aae90fc8176fa842f4fad146fe5e5297246f3dbb3e52cc9e6c4f9e5cffffae5af3feebfdcfef9bbfddb28225f7122517223b790ad8b92e31a0185da161fdc64b7802d396a3e894c380826713617aa8d33100be52ad716aa5acf72f160aab0e19225f6ee30d715d0c81537f67f0a428d6c74edb34e7ca5c954461e0851242d63e41c43b90dcc6ea313d5f5ff3b13cd5b427027961e3d600f1054ba092d4c23aac2a6b87a28418f2bf8781f390b8dd03bb59d8c613ab2a409a0f884af68372b8062636b95b50df10cd92f4203f1bc3cf2acdd5d8b3191b6191dd38d135e44c764b9ab8574614583119689f1decab44c5fa1d43322dba6d4b3241728f5e3a7db9fff74bb7fa3bdcaafe0ef6bb026f0eab9427a88a1fe70c6d2cff9f833e67daf5c43fafa6ca21bb8132f93cb9460249d8df70cea5105510e3c4e413182e8964afdc5a0119bc9ee8847dfa200a96f44c90f51068d30a8e049908c2853059b33c8dd8ab14c0262225805bd1840ea35143f82176fbcd7320fb39060593e8065c389c11f2cbe576385b0237f018c0f79848e1929813b0decd9d8a7bec513143a75c777c032a9be4204142c50aebd8820f9c18a04f2e96ce902a0651491c384fdae7e937cdea3c7097102e7fed5b14303fad29a1bd6de46a9d18a8cb368f4e08395894e5d7bf9f1a391a1e3a23ce3691ef782d8e62a01ea941891dadc73081bb41541e78d769404629c0b71f66ffa0a685d1941353981fa9594eace061d6c0dc70d0d780a6c2df40074b6e2559da1831b21b41de2cf11c43eb9427b598bb38ece905ad0905072d07c0ccb75a79974990abd47e6363e09e43f0f98579c3a32bb78c3563adee6e35be3e08440ad2398389c683ce4e6ebbaada1f660b1c6584a637d563bcb26209b63c88299271a8377fdda84ae9267ecb1ec81c75e656d2b57bac4d7d6f79798da972f3ffeafdbcfef2f96533139446482f08e88707c7918e514a3669b5cb803f9a728d9449e88b084dd71ccc5166d35914b536c0d0250b4ce45e4b63cc3b6a5404ec7ecd46cb4548360f133b9b8f8128b6377c5ea6d54e6e8423ddd49a98bfaaa347597008a0fb00995289d2436239763bd1fefc571d66d356dc9f12b8c291584bac40dfb54b70715011263eba1342a717408042566201ab3877b81f02854aeb40daad483ce455f2bc2192ed601306052a3e98a89ac7021cbf602f11fd9c44635a6968d2a8b71b66ae26b36210433ae024a514d4c94d0ada042e03a09f22d7b5716eba9e67a065caf1d0a790a43c61d6cc65915c4637f24ea8f1f338417351d6289cd86cd3ac37b6acecfba3746554355dfaf6b38406b260b684047756794a4c1aa620c02cdf33e0bb0161b2693203c56ecc47bcb30565dac3444ba5f23e72080a0ad68030be33f6bf4f754a35779e6647a1779e67cff0acf7c77fc52a12c17a1b6146a71c0794f7cc1b79b2cae94bc384f41b0058f91d243853a80989ee4a8fe88e01bd5388f9aa8d03335bfdbe0a412a0907644c36ac64939e4dc673c555fcf6d857bb12a8ba64b5c541145d6a4b6661285a93cb10dca8ff7a6eb9658d4f48d9171620622b0a5a1e4e32d6b43d38be52f2372d2d0aaf14b08740d4772ece1bb0a1416a077b72bd50eb59d83660f8fab82d87608bb9982642bb4174871287fb85d73317a34de08c236ad7f4024446cb6ee1072b00983fe82105d41acc20da16f4971537c05420f1387b58f4d762181d6e42172f16d75d95005f0d154826f2f98e058fcacc39d859b8d6706d3675f7b0ab0eb4b248044b1070e532abf3a835e9b3d1766cedb491a5fa13e998a297df9c71171b3a41732e4c3a934fff8b177cc47593ca29642ff4ac12a6abfbd793468fb81a687ea2984587e70407b35f5cffe5e52ccec3a8744235513b32c872824c6ab5d9dc354ac615a44a5ffbb4a7e6d2ebdb612bdb20a7d7ff7e5af9f7e7ab8fe747b781b5bdeafc1e8ef90c65b7a92e4f4a54c30c9fdb94850fea8485011d37951f0cffa5246391551de4175220f795715ca5ddf557de2fb1ab0bff54a217f8b95e235c675ca812e31b0d3349718d92fef7207a2f0df6c0782bb6f41647773c3160422eb7fd34d88987b053e13e9628dd393cbe8681223ab8c1d56a3d93e884d95eb01306bd1f4378153da3021d551d6e0918c3b3f75c0369804927db71957a92dd9757e5923db42e086fca97b13f3731093c48173d578c16e81a9216c7d6e3702aba53d5284c6f8c6c1723d5f1430a0d078ec2613b9cbde5204a46d1c009d044569661f2c7bc8f594f733413c7eb24c197a8d4165b95ba69e73b136f3a0b6446b3c699ca68353aa472795606a8c2821fa235082616d24480416e2d5efa6de54eb97d2a1e1e21b362602cbc26c3a5155eca7e3048681b93262cebecd0d3d2fa47353b909bc8d5deb5c6ce8a0db606fc7b81017df08aa462fc3e80c4136e4f13e67df86aa24ef49c77f7fbb0effacd1d7edccccb5e0e26af2cb6bfb32dffff2368bc8d71c21b78293f4426d81b460333653b399ede0491bfb31384eb5292fc1a673c67150b23eac3177fbd4986575c4b66137bec76bd20bc4833863cf851472a0160ad97ceebe715343a616fb9ce1f36e805dbcd89569f2423c30b945885df3691856b0cf843363cdc9cfc7eb626a513bb9980883e8f8c5d696e3738836eb6dc1397818d8b36a8eb48f53169966172dcc0e84a36fc4999cf1ceb2cbbd868e53c7c8d82eb77e85c1f6e4ccb29336c2705b7093123be9956463d688bf3e7f13a9bdd9719d89fbdc2f1f57d524b2d2ed1f6eed215eefb1a7d26d543b544b86ad897d6d6b3f6e648a618d78bf26d278fc7089eadbefcd163fdf4c22e0b7cb1e9b55624b50f55d7e0d0c1706dff931a68f632946547a2913833be60a035dac9e6d10c08f710865853613326168d2719ae9f6e9b65c766c5a59a73168477d4730b335aec0273f722a57d271aa5fadc7a498c40929d37e17976d53ec1ab2916dd7602ae1afcdfd57e6fd8539fffffee59fc623efcf78e4631e262c49efd759fa44f7e8402e90b0bacf1ef1211c97d6cd40225704498830f78067ac476ef37dea783422d9732a4e8808322fc7f89bb8998141f136781a4e60a3b09d1a301989bfcd78e4486297a8f398e0028dfe9334df1169be36d2970678635cbf2cfff9f3ede7f7e7b7687a65d5bb58ea4dce9d5adf73edd434e2272f5ca808204e2428d9000ba502f94cfcfe5a946a47ecfc51fc5c6828ec435d789480643b0f696145dccc12178f9980536b1c20b1dd2800b6ecbb4ca503fca0fb798f3d4bc196f302ef0a0fcb9a10851cdffabfc78f9ab1515685aa470404c88b910c3454ee26ac14a1a20b504110af01e11ea445edb6c255b59b2234f2f14c254d39e7c1a48fd4a67c03df1aa584d8c18dc45434d7fb4d2fab0aa5536ac0f52adbc29a11971d7e078ad8e7bd07abb3f4be18f5621f47212969c31dab7e5f98fd159a77913027a56dd1e67cb5459e7ffef42f3fddfef846002e5feb3aa2ba6ced8b3dc49ec27c12002895e7765836a98361ff105aa58e932f1386d41de84a6476eb29b7e731914f870788d6d8a1b9146ad11deea81abb5088369d9d8b8d838dc992c5f2325e546ad4040bddd85c967959e1efbdba61adaddd4b366e55adb6d5ea9a0f3c06e52b3ccf15b1fb421ed54d6e3d22c58b0d9d87b35d9c25c5ac361f2556487976d760b93bf71dddb80dfb80634644a9d8463092f4bd16a0cdf03cfa106c918c3052c41127773fc6806009dd4f98d8881e6649d52d92f3dcdeec7ea4a8c67d71d70a8dc78fdd16a50debcd87b355ff6ca93fb3fd7cbc07656d89040fa7e9ce323fcbfbf15e446396f435b5b8380fd729b53913d797db73f1bd4900d23a4cd798ca3e56b6218761afef0c70c2c1558789108d5dd68a55ba2d8cfd2675cbc6e4e4d649f6d5cfde176cb4191de214dccd232d0719b0274a70aa352dc78aea6ed0c828c4d2c276147bf0247b35a5462b7c636b543f4137f26d11be01243be606dcd391a89a82d396029650c2ba2b3b53eee3536ed14d468179679387e1f65b765641b11563b187700c2e6ebb094a6a54f6acd0c46dc559bc4270d62d01665496cbe37db62583aaa7f5d569d6ca54a939ffa0cb979d0ec1d61b5093ad4aead5d6b951132c4d06327399b6a8d6e1b02430f9a9c3047a576cfd29756f3a780de887d984128b5b8fe63813a35bc3ec56ab384c574d1063f824bf4afe17087f8be4ffe33f3ebd3ba24720efae773c5eee6adc653169b23e4993ba4a93df17131f4caa75a4b66b9674e27d7be20e7b10b0f3f34d14b7a91d75f11dd9307764dd8ff121ce7bdfa0bd8b596e5099c77b18ade4aed7dae189de2091578e158a7dd5bb021f75713f1e53e6153bcae19510a51897cd61b4175b03f9febc997ac306383c7b1496d50a3d06db3d022ea1a6a6b464e47e92606087a7c1c4a53a8bc05e11ce196accc956b91e8b4d7d78c8644c49d38f9c4fc04a98f22e775b03998d0cda94394c2b82317b8e155e3685f8460af5c53eb6bc862d9d0580e8cc8410ee0d3cb6f946a9f1dd8193024c5a12e0acdb9a3ddc56b8ddb40211dbd6fb1161f085b3132bd0e407de756cefe35c63b637321bc38d6e61ec2709883b8f2db70a1b4f3439b85390eff818cbf1dd2b53ba76159b52022e85dd29c18d75330c417d2080188f8283831472e8266a210f780458256bc8c9a43908115e6ac8403e30eddc19d1acebc9e8593f07c876d6cfd0d9c3b1d907f5cd2d646ee9e0c2343b2dc074cb5622eb675862cf7e76122001967d85e3960fcd212243ebe9d8dcdcbfcfd3a47568f74f0d9eed0dccc156b6954aec2582f6373f198331ed91b6023b738ed818a50c1a61257e044e9c29bef0893c7a448e2922cfdb79bce7f2f270a131ce5b7f7199076c3a6b7dd9f2cffaf2c3db4400fb9abd0b2c573c781fa774919708e4224c9346081a3badf91813d8f7a31dc1c09dec3a240a9fe00513cfe6aedd185799724ff6535f080ad07cfd800cc0a07738af3c4637943865131cdfe508bb666c92cf080938628bd5dda660f03dd3ea1d32f24d0a2341a3330dc782f6f1a936d9cf07ddb7c5e798d5171e31cd37ca115949c2b195014a8f8b31f044995db33ff61d9a8eecdc9a01523e90740ace39170049616a343f82c42eb3af3870ac91d50a31a3a00e29c5e774c164c3b1670fceb18f0557a355f79661ecdd14df959b3de2460fcecfd15b96510e08c80b438719e5c2d83987eabb7fe88099f63846d33692e3306ea9f158d05327e4e0e7eff05bf26582dd88b680d54a72271158d17a1b63815727bb18491cd79e391d311f6a079645fed13bd7045debf7d2a92fced006d5d0c507308762838b8b2f2bc3960adff7375e6115b4cbe3c7dc4d37955e89f7394fb353dfea2cae0f96009f5c1f06448cb5e65b5bc4a475adee79554385752d84fbb19aecdbda68dd5e28ef23be46fe5096b24d279d5cd09610279d43ce0434555316e1c004ad71ac8715e262acc4629db36a8f3e8f4a9428c9cf6f040615f546b92f569d0c7d2d5be5188bb477e6ae69d084beb616db541f3091b57a1be9c20c07b32ae66cb2c1f41293586d88a11b0f478402dda0b7d1997936367b7f0cdcc0c036991eae3b23c554d01f09830f47365829f0e429c37b13db14d5cfeed7b24d14511f8de41bdb1cd64aef052ebb18cb6ab26673230c74deb1ed37a5c112116e5fddcd008a1139ec238a0f8c155d12741e0dad463fec2fc1eaee274e028b87ea03673d0da539c34e19abb40fecfe69fc2110759bfab05f082b8d60d701b32c64c862a6bb202e14da0b5919d84919dc0ff4b88f4f748bd8468c355c05c76535c35285b9b91b0c2f30b468cdcf4c11901667006d5eed7568cd656cbcc6f67ff3ebe3bdf82e47973366f4cf15e4dbaf204fbdf0cf25e40d96908f05319b34f36f5c41eae60a72594adc0cc1f8e587ad088c5f3efff8ee42c5a6a0a950be51edbe359b43afb09b1c629a370f71e5db6eaa1e8cb3b7ab6cd7a088ad26d5f8a02a8063edf77b65582e380014b27ffc98055b060b27d0db79aedfabd4196306a9265b1253d61f4eab03a0f994486f1c53e937d4b730b42df8dc1ba7aad8d1c35a2bb8f1eae6595de4ee4edecc4b99c79f1c46758a1a359642b31f96b91c9a708093356984c391ac540e3553759c25aee9aad779a4c7c3f7c24593b5ada337e68fef66db8de927d5aefec7e3bd1bba1693356bf2ed654ece69e78dbd5beb05833f18078e4ac556299c2adaa0b19b36789c52eb01b831965053288d2ec3e31bf56ed2fae71f37897dffcbfdfb23774578eb09f2a2c383c8966cb7a60d9e42753d07ca59715e5e02e578488813cc9f53a8178f777e0ddcec74c7351d3c429d6848d7d2fbd9e38b7d8fcedcec7dbcd9eafffbfb4f3ffefc56161f5f3304da43baae7a85698a436ebfa93a417630ab9f76ff42d5bb510f5d9714707a03165f5c86e330a8ed72f2a8f2389b5a37104f360d6f102ce0a511d9e50e5f7b6fb3cfd79717bbfd5fbfecf7b73fbdb79e7773832b36e97bc64f66e311e2dc68494107150890ca61144a384b4c8278464daf14d152549892491a2d682d346c7596a0b552f9aed11858c9473986d5d69e965a81fd1ed864025f9c8d01255bde9972bfe2ce2423a8261aa60c352a038b8a55da162736360dbe592adc18613e1125f5eff368f6ea685061e26bc84948d775e288567f62557306737f02657fc0314f86619a9aa4960b76134d8265af7ac73b8842269132c74a5d605bc691a914930973df5b2b048718b2646a1aed823053a66f40c8608e4229874cdc81991c2ad56a3d0ad94afcf62e0bb5bea8bdb2d628b2ea7ed76120600f4cb62e121ba51e2b313cac786f2a646a5350b2969458c99de8137be06d5b350663f7bc45a5544cfc4ab68852caa62c6836dac838594de5c656728f017082f31f6d02d6a7c02c2701600edea5e8d1c0083d633d1aac4721076356a3f162822873b01e0de8d1603d1abc47bd338377a977273ad6fad4d4658875ccc1faf456940a43f12e4ff8c5d6a7117d1abd53a3f7aa752332eb7ee7bd6a0f8cd48b04ebd560bd1ad0abe854176ad1a7a152ae017d8a3d4d0ee8d3803e0dd6a70873031d3fe5607dea87ef62da5bfa3556e41ce53237f2f7af30a49fdfdd5a7cca8e4eb8d12933725e144609a53913321e54c0827872a0fac47e161b58dfbe874ed4a2abfced7b8006f7136e045b138650d79f1891baf12c74a5ea5a4ce0d4dc56c2c3c6e8090b3ae3407ac2801082429ae0e403c660aea84404af7898b71ecac23e8328e60fe6adbf70d8d8f45eb2f93512fd795b4439bebd489e6f0a6fffdfb7601ea97473a93c21d4ef5690f897eb637db9387e971378d4fc9948eda7ebe2b8bc2e8ed3757100b1e5bd62e5bf4e5eaf20ca9f25b84864dfef6f1fde5d04baaaaf713b777228d8eeb499380a89dd75bbeb97b81d40b1e06b06f3066037e0f78ff23d69607b008bc85443032454da3538b474d88b14c0b5cf8df35cf0534c03be2fd5eda33af11eee0d0a83d7ab52c0f8e1b7515a0dd20789df21d606bb9916f68a25f538c93a562c12917dbb189631d56a5984da4e0ba035f4caf773dcea0df666265becb27b85a1be1a1ab67db961d74c84745f608aab45a92d38e2b5b7ea96d2d8b9dcfbbe71a1bc149c87760717aaeede63f2d56533e9133abc4cc6787d9188df338bfc075bc45f1fc5cb037871ec1ede522dfce3c6d0ea11c54ca0ef08586d8b48e49a30dbb8a6ef1330513cc60db05bb29240f8e51c4c052c2137530407d3e857a25439645613e6213be7dc4d17005caa4dcc4d3dd154b55c09b1536ba5e11bfd05d09a30c818fd8aa59b7e88fd47532ca09de6627cc0333042ec5013538f8dadd2b3158ff75144c33005af920cf73c1a910a8ec3c4984111a3a5ecc606c58fb4ac22ea802f2d52014f66ddb3add2c88217b15742554d6bb14f9a6f84e748cd54bb0e645be020c2ad4c602f27b8bd135327964aab81522c34c4ef4cfd19b0741956990a10331e5e15166a791fd581f81638fd8e58ac3999d1a86c2a86df6b8690e08192a1d69568220aced92a42daa676332692bfdba0af58fef568827e344d3f780fa203ed11fa2f989e15d07f70942d38a18229b9c2c8a5352a9897ac7b5890007952d8667cb32eaa60a8f64df3639a6c236ffd178534c7ee417f9ac03e50707b17bd03a3e371e2b4c47ad0ef660f06a751234bf4202a13bc07b500b07041ff05eb3f801a7a0c4699f7b3ffa04bc2153b01bb4dfd50b805ef3fdfbe5274fb6aacdf7da7c1bb30ba15bf494e8ff759ab298b2c99c6b82a958d4e722f342aa6732e9865b815049faa3414418286af7e916550ce91b5536ad4b17960ab3ff01265f8ad40534d38daeb2d1a2bacd5b7e0d5779d3999060effa12cd188cb64d01c997abf12cb39681e984b9dade78c0be7ea7c58130d9b706d506a71605fc386b5cd295b125bf95a9b0d78c9d803b00ccaccc09d582a3c1a4c636e94352a750d9e0b0d137b63b5c7d85ce946b194395adb6dd9161c1dc3aeafe1d0fb322ad31927beccc31f7e459f7e2365fa1b3171050fdf62e1a71c1c11a471e63c42ee61889bc4e7e4f6fb2594d592dfeecaabcbb2b1e02307af93813be283b1ef281ef31b877da1e17cb1804ce68d3a8ae4e4d94f2c9b6d0591b40858710d1946a7364de2b0f984620a1c3b9f2604e6839b4f63360037d285e204d1c466c2c04468cfe7c13a0d22818d5a2bc7e914c00ce8e713809dfa39c215d55def8a3b851b8b31c1d4a40cf484fdae040f93c309acd6033ea341cdd11e60596e646effe09f2147c78adf42e1afd0f62655ffe576f9f95f3f3f2c6f42d83afeb8ab9676c48365a88acc53d5fdf578b0bd047fd381e325a55e7b4cde04fb3f74bf2db436ee430ed30f4f9efcf0faea87770cecb862921cddfd1e5670920951b21a343fb9810fc4d2011cce71f3253cedb83c3cedb5bcd87139d9a389af8aa3ebd06d0ff9faf6c2a83fbc0d2bfb9a1137edaa032b30b7c5014158dce61f6c04503f884eef31ebc3c90b7734c0bb74f215eee6a71ed83eae2f75f88b793fbf7d7c223c4a79a53dbb3d929ffdb14181f3f1244235b178a5c37b964a6c2a48a754763975e2e647ceb7996964881e23af1b2cc62d1b7866db0386362bd8b5f54aa56a027465809918ef29254a758335d95bb2eedf94adbc3d572f61ef5947cfda5d031b5473a0639712acdac03c799d0c1f2e701d7bb34d7e3f7d7a7878ab334a45a4863fb69a222cba4aa3ccbae3646a61dfc3c7532052271957c584caee0b42615bf1aae9b1a51aa34f7e7475c72c5762eb0fe28c5778fe4bad1e47c9ee7b9a7edfb6ea748952a8278038a4114db61218188cc63b364daad57d1cc3ea15fc079106b4075c8145dac6fc4384aab49076b33d3a6828cf0fceaef3b3343f79fca826f1b2868e4f775911e17def3d10bc0716c65ea85f9594e146379a6f87b4f9c75d441f64a53ada531f609ecd3ec872c39070bd0f82f701cea046f03e88b30f64d4c0b9eebdedb3279693a6046fcafc63ed81bdf19406bca4dcf272d263e1f4ab1901532e87147ca2d90ba43edfbe42ee3ffdf4e5af6f46f45fb395931081f7babb57b3ba5333633422b7a08ce10f99addb05e4f714e662c515985d681daef62906271cdf3ea10e809c35f57d8649277caea7e19c0d394cdeec2672bbc908a5e3f0dfc7087b1e568f2556b569b6789ddd264f6c8de71615869331336a0b7239a2201c837338d5efb403d77bc6ee88ebeb7812bb239b4090746f2cc018ef55062e7d81a15bc706ab07edef2b9a838b9ec7908133a4204818f52246bbdd9672ba8b5a93f17b0ce3fed287eac833d0c9c34d029503b77d66302ab438ac2dde1a018c5194536488177d927ac8353d7ee49e4d267226640cb188c705bddc596a723aa02d2fd008182b17b1213296c260a981878961de95a2c16437f1113e06613c09bc78d3fb641c18741396d419d0afcee17522be3693d73497e7f3bb5bbb3234c167b473326f6ee0575e61b4aacfe358af61ac7546b1ee7ad775eb0576772bcc33f5183ffbf13e4aaba765442fc3ff1dc36b63fbfea9f843d76babedc69bb598a79203cb1d8b6e12037ca353bac928fe25bff87da57475a3a3172f4ebaeaa9f98ff7002a3dc4f32e7b4af01442fcac535e9be4f23b8aff156a7f85c8b768fbc7e5f3a79f7ef8f42f9fde5f201f041dcf898adeb0d1c289c9c9898d8f1be51d0d7fe2faef0e51618f863f27f62b0720ae1f8d5ac2faefce5e752a7ac55ca06e6825669c14e4410ccba35ce40e36b4f0cbee123bb6e9e0f83060c429c6acebe347d38cb211fca56a64d9ae86f6b4d9d243ccb2d9d4cb247132ba9b7471f27e8b38befce7e74ffff2f9e77717991158a4263e16ea36d1078d16a99b9a57495b2c0da1d8fd0f9646bd224c1cf0d60416b4d85ac50b2483afaad4a888615f082ca58de316fede0ae10c9413b9e52c24c261fd9d51dd1bb5114aa3ce0045e1503bf58ed415bbcffe3b0d947032d0138db267a1d443ab240da9cbccbbac79c32abf862634eabea8698b76ad489d6c2198bf9eba0935b66f52ddb76af72cc4659146c5a48f5c4d9469d1a8bb27ec749b66bc471b81e7c2dec696c3faeb39a38dd1db684d8c68e2623ab6bbe3200e59e258840ab6c5065b3f0e7e4474cb5c7d83a49e98a79cdaa7bc345039b55039b574c938bafa4699610348be51d52ecec6753a6d4ec5f5e5a579f81ee760363d4fa98d7d0409472361274a1d4e3a3a26e9c067a74623e1b2878b35bce45a59e00d87c39626510b71c7464d0415db67a9ec2d673f912b4b04194723639baa46b41c3b3802c878c7a951161c493b19fbdc93f262a2be9ca73082f5dfe7f3545fccd3178d3c99a705f314ee69adf83ced2dacbfcfe769c13cf533b367d3b48ee33cc579582b98a772324ff3ac755e6b7d324f9fa669b369da60093a60c32113b4ccd7b144a3fe739262ae5d9ca05b93f32f6f136ee02b34832cf8dca55d8ffb7d16d23b885ecff0fd6b48f0b328df739366be3e0d161e45ef9a1c0431e373a2de06bc4f04f04ef877c7b53fdea798556fd23517b91c7afce071f2cfca39aacf405b5dbf7c1e941c71904df8f7f0736b0bfa71b7407c7fcaf7af76b915fb0dcdaedf790973be964ea98c90ae7391c3a877a31e62b547b727c9223ef4ada9cb94f3974dd4f72f7fd9027afff297fffae9f30f77ef6f6fa8546c860f4a39039ceee9fe693bfcd27ef8c986f83051a5f957d811e7469c3564add40a608fca90c0d46b8b79506b3568a19619b81fdd18a0ffd9952ace00119fad6bacd924b5f52fd64205eca033765fab504af63c93260ef6dbaa1cffae9546f16372a65161d192b9e0d854c51d7d93deba1236b7d049329cc7abe43d2cbf1c04be00572429b661ab5b6a3493e67381b7a8640d42324a24c93992b0c27b4846944cbd03a7b8cf7be81aa6b0b64c83b1295f5a59ff6a9552879dfac0da24850a6b68037dd394a4b5f5afdcb1039b422d243d4aa79cbbfd5114be32152198389b52592afcc3122c4a6c004d014a3d30a592f7a254b47955e4d6563fd831e0c74f2ea8141c2ff7fa8a163269fdc2ecc0bbad29f2cb1bc1f57d0d665205a6efa1ea5d9674884777a31358f988972f42865e63217c1eecc0526e2121c1333166382f6c9f281e2c4be98708631e0ff5757a8e785d75b9047bef01b2725098c199ba73a3ab36fa041167bae80982dd1360dcc1d4ebdcf5a848ff866f6e3262e0f2989efd6eb064bfc5cd3c7f8fd3d62f1750e77ed9049cfbe9d39f3fff7c75fbd3db00cf7e852dc70a78b8156cbea7ed60f352ea753a7043c07589b680bedce2e35c7ff356deb5247dda2b7bdab13a440530071c0a36ca68f2db8b68f562091fadff7a3a68bf4e4ffe9527b196e3f3de38e9a98b14721cf22d3239bedca2952f7f79872736da6173731735ddacd3bdb653e1d7263c0f48305cd321cb51b0825c7522566977a9ea49a89a32950dc79da6cb6ffb94091df9a13c1dce385bd40bafaf7bbf6aa604398f83180766a7074dd7a2575e0a1893a5b3dfde0f7ab905f0a15d804258dba9901fb2dc197b9eecf6462ef3101fe84df2c09b6dda78cf8401182f445ec91c715daafb00c2694d104f264f54e19a770ac12ad80527379ed213f92dd285b4d3243e424712631bcf9dc7e03179eee6bf77f46dd9dd7e2b5930fa920a49d9b9c5b0ddde68ffef9c12af90dd059adb24b8373a75fa1ac062ecb2f4bb38ea0da49c2d56746782d1899a1e4e5473935ba64cb3f5d687766b628f7af0a05d9b6fab2e33c767cabead9877a35e783b45b8ad46bc3286dba72cf6fcc228dedd7efee9ddf965960461f60ed85055afb4146aa6a2dbdf5242ee4cb595502a49f3e36e154b798353fa4a555a849dc5cb833f69ebd19bbf36d96016b3663fb39d3feb532fc1eab59ee16d65b58a19d2fcf1d399d92c64e6ba36e198fb6c22d01aeaa09aeb4d491733f3033869eb119cbf84e832cb590b58335e7f8fcfbd10d85b584197b25b4f0c5ff4e8238ec13429d5ac37b9ea1fe9794df6f515d7425d6a30e55c6cdef1a0d6337472d10ce7995cbdb2acfdf757f62eae2559ceb587b544fb6da51d4b445c142fed86c1eb7f6fffcf82aceadc34ac05a269dc8e05ce8e033d59e7fd7e825a0b9a7db616b8f6d95ae0c928f9909d8828199c45da71f7f161ddba94e6bc666541d0a5fda9277e98ec111fbfb66f79e4329738135e6eb2a7bfbe372dbb402f05da54ae57853325007cd51e74248454085a119c5395b803151488f1e2609f074934fa8e61579647a6d2becb898481cd262b4800a26f376ab6a888905628c608d1930053da80f493f2cec849803f7c372ae9d8ab92726049c40b7c622a490e831848abc01bcb00d76d7b11f76510c8633922b9258a486e692292ef3223b644ee7a0d17271aecc804355aee85aadda0f0e285e7fecd4adf4765e02a200cc395f602d00587c652454807a9b8352930f6b41fa6d8cf0d900268898e287cd594f77b1b8ab6eefe3e6d324f21294cc129accf5ca67a58b7885d345b25b653b12bbc2a5efd759bfeffba4df9ef2f409af4a0daaf11c87505fe7f02e43f6cefd2a8db46bcd8a659ed059eb0fd1157a07a5000d7b4539c2ab5abdb26861307a0ac67587ec19db2efd444803c1023db94fbe14e0a39a8478260a6bacb25510ebd5ce5ca382783f344cdd387626af77116e7ff1ece2b60435e02100b81ffd1426efb88a8adac08a4d61dfb78866594441d3500c4e63e36a18cd80d8b508b15b676ec366c3306e65625be4f8175b86f5eab0f679b310bccdc422189332420196fe94022ca5df728928790252d88a4c118a2463d6cede23c9c17fe1a396fc600b3e75b04fdcbcf6fb465fa555266a3cc818d9ff03e7267fbffd669d74f57608a1bd24e3a03cafaecedb421cc7bee96cbf9bba9a1ee9183ebab67ef29553c7dbc8fdc061544fd50de03da7cf815fb9fd8859c0e03d36d200da819f8b91d95520f7e9d952ef007ac2463c70956fab926b8be27099c64b311de545c371bc249fc7b49d0c01bb5723b0a75470258c124502caa50f6a8a1a3a5d7becb5da8b7c0a33ddec37f089622a5dde6096c31fd0db4844e45f7b10dc2aebf091add8d5ef22dec5a825f276e0395eadfedb1c100201eef3f5c2fd3b011e52611db8b0d2afee54fefced601e65fa102f537f5d03abc705b80ff240729feabe52008ba8bc0b2135f33ebca046c81dcdbf79c60d5584275883eb813e3b59172b2b144e4a61cbbe50e66b5e68265f606ee6fc64d9307c8c8cd9130d938e1402d63eb5762b486603fc97fd77638ac7aeda47b1e129a1c18946bf71d566cad1fa23dc33d4ef2432ef5465aa1b2e79a622d07ced90ae3fa2ac0fa2f7fda3c4fffe54f5ba7e9bffce9d3bbd393b577aad68724bb3c2408eb0da742c5a4f66233c1562240260354b9190b80bd4bb1c58a237c34dbbc91e2a19a39c15aa420ba16036f571c8b979adf595637c2ba8fa3520db9925c218853f150b352bb7b53f64ce3268f292d99b88090068899098b71d95b6925ad48d86cfcc66fe0ad697c27d38830f9ce3482499f9793a6685901b77916e2d8b8b8b35437a8d2a5ee79fc988badf84a7d1f7b81bbd221d64eb2ef25e67668d928948b89826a349880740dae1aece6600bbdfd81a0a1f6da6e0ed1187dd72003d4dc31e5cac1581a23eb4efdd00a295cf5582ee4b159dee33d9c47eda36f9bef2bd3665397b3e75b13e7ddf95649eb94e027b5539cd5873ea8b445a98e78dc7a06f603f0ce2b0dc04977bf740710f4981d9dda3001c188b207ee9dac978d2956bf2e4ab01ca021a6c6c325aab3df7a7cba144ba624534d594f65bfc7ae33fcda59fa035e1e63d52c6a1283c9db63442c9099728d34f2ce4451191e672803fa0057440469912a9bd89d23c02dd68fbc02f3fc77d6228cfaac507895ce27f36c57609f6a198bfbef1d5bb53fe9825d367960c07d1991db7ac0051de9b76b4786750cfad318f4750c764f03f7f87100cdd6776bf5c9e4aa9e985cd5172657f5c4e4aa9e1870c1a3f2dbe47571d66c1ee9fcb2719cf3afb73fdffee9f6e16d648daf71ebd01e5a26d67c501399f50a90cb65d8a390b551adf066f74db421a6baccb70923dc4bbbf11caee025d54b037270cef0a330ddfbc1aef395dd7af24714cead1e38e11d8ace7c5e34ce54045b03dfa7e3db148c6cac686e75519ba0c556307bc7b6742553a5a834ffd86fbfcf635037653f792eb37c2315aee9ac1adaceab610bbae554d8aab1be4d41b35723e7df5f8d5c9faa91f345debc92ce06a9adaf36e8edd3ed7fbc37c946b806a9b0122ca41e6bbd60b73a029cfb2122e6973d8b78e6712a993d3e63efc7d03b0f7303aecfa08dbf2b4bce24d97787ea930fcfc36a2e58ebdcf5b9178d465d71344a086ac50d206503b158ab914e580b0ec782fddfc3b1dcb0965b2b71eda164eac661805c6eec363dd8bd3f0ef3f192422bc45563634a6900dc82d9fe1aa3c1caac8aece636f002b0e3da20d36569a18809571e6a165b97d61bc76eb0ea3dabee5206294e4d3935eaad46351dcd9487ee88164da98c12b3924a0f4d2c814d6581699c60c9f38e8a4f5db4feff786fd2a3f6128b9024de694f88af5f18466db5375cabaf0dbafe01e7dc9076199b3b235151f5f48851d0ebbcf7afb021655feca593f412fc673949bfa69c7fc09f38ed7ba3946387d9e5f2541b2c57bd799deaba60c9e3473651b8018aaae96c40bdd800abbf35346835cafb0df5df0179ac24749957e862f5ad7b783402ba584dcb69b6a7355aabcf7bc461edd57f2e6e6e1a03d9e2389f6eff638bdbdc7f597eba7d7761e06b067c7ea9501c01b167d20a9a6e624f8ecd34a18ab023a6c3e0f61a725667125c16800102e30581488a29dff645cb88c0a21ed72339c6964d398908ed094c7cbbec10fb41ac6404c7a11aad2ef083011c9143da202c05b47845e8b980e0fed9b47a848599515e187f38700e5343704b53f5aa07d5dd210ca84d98253644fe6808332b422d665857ee8106622c63f108ed044ff5e21ba0d21d73b1dd655eba6f525654db8385c441bae36c3a95eca135f5bb5ce4105b43c41c9219efa37b6810c01733e02611f2b2791c8c1e66886038f9efc58a4018d3463996e0803beeb0edf087f7312b23ac27f431d4d77a097060426dc1ae2b3b942482c7e1d06d076c80564d51f6382009a10c00e2332242087a6ac4fec98eb6d850805d788940d0898c28481eb8a553d90b9407f7c316cbda23b4666ac1b5ef16061458c79334d1c78464ca8b0698b7f9ff4235742af03987a6fe9b1b966bffc76c98f6f4f7d03004e1d0f1dbad520fb17b5006482cbfd592b5b8ad1deb2bbcdad9ef26bff6575b3cfbe13f7f7e2b1bb33f6ea55a4c359c9134dc836ade683f00af6ecb7e9587187dd96d6c17dc9e1fcee012567f8f17bede0fe7aedd969f651dbd946d2bd90b474d8ff756271b3f848ab853ed07e917cf5fe6806c0e22de6c8ce1dded4ff7b7cbdded7ffe74fbdea47d1d2588144a15f0fa628b55ea8b2d9670c1801b33b5614b70d5a819deb1a95087e7db000aa622ce1476fe6ccd7583c106073e137579a752c9564b25585b94ec172bd056441e9e8e5adee5c136d13b256326e000995235b93c6357ad742f3f7b6576d22b0d5b4b177b353cc7664a016250b5c8edce048aa18bbdcd2e62151cda0d4f12b8edadd9f07f93c5db1dd0056876f02ef062038add7bbb23fa6041cb23fa002d8fe804b4295aa3ace188395bbdf961f6010f14c9302ab0d4dea7c1fbd45b3e31f9ace1c13b0115704447dd719be3b778dbd13f2dcc2e40bcaf76f0e6a780f6c3d1d1bb604db047c32386de8d1ad0036876f02e382934efe35935ab6fb099e203434af4c0539384c92a69d7e5d8786f777068a9b59ff6a77d9ac1dfd1036876f02ef0668739f66879501b027b393ccff6d4b2c0edce5bef63ef0d8fde07933cf668b893ffe2348f4e7092f74ef062bdebbd9ac1ab593d5e05023da1b7ac0b566af6b6c7a7b6afa3cf6312ff718ecc3e9dd3c9691e5de024ef5d7032fdf2fe64ba5abbd1392dced63b611f56c2a70480c21943195de02ed948f6f81138561a46a7ca8b28750e0a7b974615108ab586daac07a551eb1ecc588269976389c0e82da48ad0271287e50fa72204d12b7bb5a2aa1240420a53ed21e161c043847013930094711c3f8c46c4b3089e859718bd442809ac809e7208d04c8dbd86381f05574f995ab31272de9ba20cb85b06fab706d419a7bf566704fa1a1552b5ecbdaad12ab8583744ef117403e2a4887783e921e2b8271ec5a4d3d89f7c2bb00742d3ea84deed1efcaeac25a13da898f8a18fc43538a54766b1c61dcbca8ff79c3d220a7e16af5944253156d12b79d21308c3ccd82958acd101cd47a303daffd4cb751fd547c4cf02a57f2b9f5fc1a4652994c73e3e91c382de89de5103c7ef007138d24ef5ea078ff06e5d13bc9714df78376118c21c771ff6e8c3eefdebb4b3140f98d3bcdd719e6fdb6838a5f9d0050c1dba3458ef8a7729a682ce919e6311b3e3d29a9e3496e8e48b06817cbd4168c52cc05a119d0a9d7ad120275e8c7538c97f9261b82c509ec8155bf2c8c9eb0da1e4f3ed0f3f7e7978a393d5afd80dd08163860d21fbe1cc64e9cc06ea4c448761478d3d2dea8a71efb6a417fbedfdfb5cfd29220e3ec4de6db52b11c05d61a6f37f8f1fcb30d5a22ae814267441862bccf3707eb8566e4ccfed963d54a0f1e86cd4576f94eb7440315546d7a8b5a1db5df6a5251b81573fa9ed0e615f9c618d3808c1a43a02a55bb7b87f7333651fa174016ac91e12d834248442e6862d10c437054a7650c4c9070abee5d61b35201d5c69828ecf08698b000b00541760f22eb1605395c503b7171ced67218904c83f01e3097582a3581640460f15c05c1ee478869a0533f108c26ce39b01b40a3c4fdead7dfdf8d154e6ac27284f27206a0f275a805f4f54811345022edf7e9ef70df28139c3579164c16c9715f9e7b7d9f0d5b455e8251bbe4b6c629de95b3c627db7c520964fff2ae96d8ec2fa1ff7b6856f511036c96f8700962d4106cf26c197b0066f2e34f2c49b9704f07d1184424bdd18398f44fcf8b1d92a92b990e65d47e488913dd657b295a61100ea6b8b46c5f61071d0209693e60357a1cec07d4f086f0b107993b11571c8c6e347ee0417864c75cf038a40a35a17f012d2e270f9d1454adc36927a88b550c5d64a06b8ab10f6a4b544825396955606b6171b95f678dfd9447829b680ecb80ddf07ec7dc1f170833c695f70596d6711c98e4d858074c389320270680b0cd339cad0822a223d9828d1d91a67ac6a3c7e84ed43ab77f031e39d14448930e9e84a8a87232e2bd6a787043176cbeb1b2cab9e7e87c020a60bd56bd1f4782f39d300db1a407931fd0327d60d5dccd61b65110071993483ee665303ed2e0af10d5b15f29222e2f265caeecc8eb18b3676c61d32beebd4c49b660cbb2d02dd1472089c56d93a20a203a265db399aa0bc18b31d1e02708541c539cc8c68c7ba6f0344686c5c1fefdb2078e927efae8a63c92c078cf482d8ec6a8457c2003c13c228183138dd44a71ba3b4c833f262891de68cd8682bb6f2f54a394a4aa6d539ade7005a0f3e0b2266c102059aaa15954c6f63c584f1f816bbdc609fed93cc475a52bf665b1ddbcefecc1dc1f1b226a35b7b690377910381956cf21fbcb9c07deabb3b871781ce9e068d624368fae6c056050f1a334cb5ea44e58190ab39a49dc9bf3cbf3305c4c46293d09d9c99a439bf2135a5d6668d50297b1e9d5861ebc2ba140f4bc236293326af8d6589f8cc340328c64a356388a431693d8864ea4023356e00731568f603a10a13a01e34efb908718d43483bf4ab3e5522136746c4849cf7c6620e9147a3069f1fe558c15213b477a34dec043c7eb4758ba9e7c34c0c51d7118d1cca63660968a259856055682670d5162a014b04ad746eb23638df78fb76282f70512afd0aac828b83c172291ebbc42bf12a75d64bc459b769f37f7c3ebc3b2b91dc11dfd8a3ebd6e2a6bd35d96d0aa3ce8d593866044f710cb16baffcc51a3c176f6355f72d776f0e3c7e826240a0c3dcf51be9880877fd8df27253adf797d7376ce32bd46cc479819eedd5058afef2cbdb44a7fa27457f13a0330f57f1fe6af61a1d7ef9652bcccefa6a9b0effe78fff64ac1e1ce06d51ed665f5f189ffff9e30536f1fde7fff37ffdf07c6b2ef10d97976f96d5b7e637efb08daf4c8cef3fff9f0b13e3fbcfff677b62fcefbb9f3efd9373d9d4f88717e35e211c50c105d2c1bb0bc4f3d72fff249d6f4a3adf947fbd36e07ffd7269b8fffa657bb0dfdb894bf1aebad69649eac242750419544668c402c8c8c82df44159760092e546a5df288079a452614423194fb63e22baf88bd50c076f8156a72ba21bfbf327539c8f08add7eadb0004dc47ad88efda2bb59d149c49a8c7191bc0cec7b524923cefeb40e8cf1d9205ee639e4222e0e2f193804f6c102cf90ec982e64c352f27896732bf5f73f66401b5599ef26ce1a932d6ec3a48e17923dadfa87730ffe4ad725fe3e0fdbde5fda6bdf20a5fb9c054b638ca0f9f7fbeddffefdbe5eecb0f3fddfee5dde1a35638c9bf86eff50a725f699750ba6ed8fd44b650ba3ee6045fa4970179af9b6cc4e33dc4be11fcd878d8cbe8c7fdf16313d3ce0e0e74f21b43266f54a5a7cdd0c05543fadabc2fc61dfefbcd5c1360d9c231d4495883a6a0238fd1544ec2a04c30be633895b87e74277eb0eace1c27a1560eda1fef05013e36a2393bbaf85752cfc539ff6c1a6f32806769b6b8c14f9f30f5df9dc77c4930e441644f813f698573c1f0289f32af59a8e779af85720d6987a5d23f9c89dd4d6adee3138f0a9aeb5e24d3c8c17f9693d4339ddfcfac67ea789ada3dc2c249753c6c6886614942c46bc436d9c7ae241c5aa39697388f001b6cb03487e905a13916eafd46aadec5511dccf005d1e70b6c29ad2c2e9c0bac77cc7288255bc929c281a97bc0ab0a43b559eafeb486a85546d451bb43c873849d6fafd80eace4b4498eebcb2d3a3c7cfef3bb5387a78baa636097230836d49050f5e15c8f79a6bb3c5758e626eab6a2f3f02cf5b3929e694caeae687f6d918485c8e61a99fb259ccb43bc08c77979c46de03647db5e6c8df4e3e31b45bbf8db068ebe8f266ea74a75eff64b7681912670ff7bcc0d16388e891b3df025803ace2e4be41281aad6ec8b1ace5387e3c5537b62246ceedb5267bcc4a680d390a7cf162e6e952670a0c9cd9db0d60f0a6049a87a3863b575f588fd7e82aafe7006537f0e391fe76d5cc9541b60ad0ae5d70bcfaa5ef8bbe8bb8c8092677d7799fe1f1fb76276e0f906f5fff8362e1d5fc1e488830e255e2213870148a169b1c81e1995fa3e0b65e2a57b487ca511f1aada8a35e0ae38028cf300cc4fb096e5ebdcd3c2544385bbd6805263b24db0b7b6e0851e1aec04214e651a2828122fc371e11b7184c7219c308d0894aa431549a11a5906cc1d469484f00530189c7046b05890583a9590cb0c678a59c1009f73b37f25b9e632a82d080c8aaa294c1de1170ebb48bd521822f118f6568538d4423da836efa2115447e8a44195a95aaa2c817897079a02141f0420a111d0186f7084b7dc884c6e0414277e0f5fd746a646528d2dc2112efb5bd4d0c62a76f79ad338c761c79598f8aa12ec3bad36d6cd0d25e650939b505ab3515c05930b1e444193fbe9052d4cb212c53c5be24175b11e8788d2a256b71255d84d47cd54ef583a908826e14804505436ee61dd9e8db164046a40747c4b951c570fd07d1c8543966b66b5be826c02ebb31c0526a16c628c54b14a0da326e35008370c6f42216c1b71980979902edddd02e1bb61cdb0090e1b40b9b62c2e4eea1f370da47fdcb28bfef2c37b73b693d129d50f22fa41b57f90d6a8941b1df596eb07ae1fd287f48123eeaf73edcf9ec23bb103a6fdc237ccb2f18d74a134ae8aa9491fa4e227cb0713c36bb53b1e729bc5eef0d987aa1fd2872c5655bf26fc8724fffeb1a87e309935cb6d554f6b65e1fe5ab51f72a1d27759d2071e8d7a737f3d9bcde583bb27d9741e1f0006687c29f32e03efe043d5bbe29b6d89067f481f24532b1f1a0df900c37bcba08e9d56fd30ea5dd5ef4e9afb61d6ecdfef23b37c48c7aee00fc93be82475faa0d672967fbf44695f7ed8a2b42f3f6c51da7e7ffbd3f79f7f781bc051e97f5c4c4e03be57991436843133d5ab8efd52c467ee2970af5470d3b2a39e6195c924516ccdb10beeee6a2568560223502c182d64752cbc02177ab035850b3dfc404a947d8698a04b83d3fcb074c629d5386b14a57225b987060cbcd4c81d5780f651f5067b10cf0da45dcbda30bed67e1785ca951a13abea714ab853c3ca96a92ee078708ab655a6c34c3f13c01f01e1650c17f06705ad034f726f01bb934ed3f52cbbedfeb173707707efae2b80bf55f742302e1c5a0fb9000dcedaaed67e04f32138499520fb0820c1ac3045b555d9c1d73af00a603857fcc236a0e0d53268048c5d4e1e51e185d579964da373ed248b56aa914618c921dcdc25d0e3323a606b65f7cdb2b5dc86b00995c8caaf885cc789b03975d697db33e8bffec7fef6e73f7d7a9b383e5fb1eb395d28a09c6df88baf1b5367040a3ec8d2f7513b62995b163759aee187b141b8be71fa7c0011270a9139a46fcf846bae578d1cc6d37f2fc308f71991efc59b2e3416c839254218b4d51f37356cf97f3f9cb9632f2942de034ab0e300d46b2dfc8d73acb2ede2fffb3c284ee8ec0289aeaf2f10e9fb13298ca39924d116eec1c44563ee26ab02f15894da9eabcde792a92fc06a248fdd0b0b5f1b1bc0adc84e0b00401ac9121dc341dd1709892d894974bc37cec0015011d9f8fc18a4bbac35706bfb688fe09d040662c90094a9808570e723e4e996ec24fb920171a68ff7d2e11fd876a51a43adbf520d01cc6a63f2bd1689221078633621d856b398db8e4b7709735c7151503f032a06a08021fd8e29d43b8dfd00d66aaba6d40287d33a221a5b0cc50b077252382e32a6138526b60e34bb1807afff1f7befbadc5692a38bbe4a3e801391b8e4eda737673a744ec8311da7f6e844cc3f0ddb53f469caae6d55b17bf4f427f06191a2ec45d5c5a5daead913552697b8ee9948248004beafc4acd913b3fb5550ffecdd96279ce2a0a8f657738bfbbcc7c6638f4571a7353b43fb3ec344b87fc2b3f5945ceb6cb83d43b50591bf3450d646c8c7dbd7c7278e36e2b66578782880c853a38e224b19dfa1ee28e24ac14186bdde5c65dc1f8f3cfe7b78e7e6d448b393dd8c42ae95276a77dcdba316e03dfeb10327de5c440aa10c4ba7430e8ca88f1b2a7ab29e34dc2177700d760022de9a38d0d2f95a515c50dde75360a5f43c61aa8cecae3ae8d734c68b5b3f1c9e7925de651daee517304e4d03ea724187060ca6a4eab7afc8ea478072df169ca4be950ad496204e482a64b1d50a020f0aee4b4ba16880432c64076e3402ad201f5ffeb19176884900ed201ecaf57a34223e0e991137a29add802c2897e26c0a98354c11069332f09c62bee8c4fb30cf2ad5ad2e70336ea529067e66f0d9c197e700738f888ab7119a681e0d3c60b9b6083c68f24946728de74149085a283789233abcf09ebb3be1de2fde46b1e56d449cd57ce6835aacc9dbc8cfb52555a2820c92ea521a2d2d9b116a957bee9a9aed9aabef2093f423dc72f5efc7c5b7eca6e640f9eab8ea6eece60812ce3310acb3c5cee436e848f835ae1e8103bc7375fda32377cdcdae9ea1a98c58765facfe6324db6c6ce3846320fb18c7be4068795903b94a595541be634d077dfabcd97fba7f7d86641303fb4365b9a985c626402ea907f189f523f1c915f74a7342a90308d155911fe71b7ee60d4824dad95ae9d9aae869eeb2b3e5d0b31a543b9a50c735d4471bcace965cdd8a7a678c62bddf9cc1bca5129a247a5b7e3e11ebd47bab5d7edcb9deedfff2c3fb5747f9b174fa2e8f7283f9bd6eaa99fb6d3c5315d46836c30a898fb301f6d9d90e3a6cc766bfb6c3d4dd73f719cb02f86e93ba6ddcb59b335523b3348100d2fddb2d7ff96dd2a4da6edcd403161303ac66524504d8189ccfcd151af78777d28e49f0679937101b318810326e5412fe447537440828b64ba68d4ac69fcf098ef7ff05b1f15d6b42f3e3e6c3e7edfe559a2c2f42d43d0af2ce4a0aa0d77c42750dacd7fb3c4a3e81bfe613eceb0909367d81047bb93b96965ded8f65df5a87bc5031deb7f4c518895b2739007d6141b3549f24ad13835223570475a4ba1312a1f89a19c0f9230b401a225a8e858fe98304cc1d40733946712c3082d45bb66131448b7b2095f8e19d15ff711b5c38c79e99d123c407f79f36c2158b63ee65b0b817a869744062ba2900b30560564042912c33d3dc989b411d48dc8c9540dfa8cd0ddbd4b13081709c367f50984ba31e578c40bd134e90c6d30716f91e84ec3369dbf8d58d619526a08701cfcfd4ed49f1094f803901f85541a527a29ddb91fc2d5a5e96fe38779a7b24b0d6467ca552b6634475682bee29556cb827396f58c65ec52d172be5e1aea40998c263e0e53156707f0ac17c89f5f0186348cfc513d6ebf33eadd6e67dfadbc7fda7db1722aafe369ce8b21b65155de3c06dec06a20b1d3eb3b4253e08f81e08c7b5b409262740fb74f7c921fe709f4173a3a95c47e9baa023581055845ddab32e5163c616d6378e8cb3fa258087cc96b4b703b3442ea63e85ffb8123bc3233c4302b9d1de56afb9636bd4f73693cdad2c51094e55a8c6560743d4de66b6796563acb613c8b42d0d2c75709e594afc7f9fa524ffd3a57da6f8c6ffd9ffca5222ddee379c77512843ce56053376ad08e7e7dbfff8f1c3c7ef379fee7eb87d2162da6f4137acdd4d49352313785a05bda39a2bc895b4138f3c805461934add57231d691a0c2d05529752b1ed0c4c340e7231006f040d0a90a7c7be53c1cab454d7ea73e4598111654236f334aa6d0b5e86c8e0013254a73973a312f01e13a91205d06db5fb88b0e1ae2ad0141b672603a48eb454a9cbc68afacbc960e29a54c5ad24a0f65457cb05f88113c96b400333d0394f80543155ddb74ec0ea69d4c696fc05129322614ca8f8f73df048f0d2542c93f0be329599c6703799fdb2836673bfb43678b2d5adc3c01b9bb2cf1588016352e78d5a279d89fd2d159401ccd10b55121cbc35368efb2fa831b61116d164d4c03f5390ab576ab24acd5d6b2c12bbf71d2aa30254af319a03bc181578066d649dd902ae1193efeceeecc642e3702f58f7c1b6e5772ce892519301bca40058231227c04d0bd814efb9236164d099a0396ba53952132a725d40c6d11a24264162b64c0071a73a11b809d0f019e28595f03d4411809086e93533d8c1363c80cea2bdfb25440a350195338460d876ba54fb74370b8de1fde13263b0345c6fda42fb749e4276ee8bdd7f510bf38523f7455ae245e5f2544face998a747acaa9aef3fbd3a472d40e4a456a0ee80804301a437d1a76d80499d0bd045fd3383ce5382ff8efd13db3b01d472060b27e23d8c5452f7bdfab23d94741c7c7848df67b0db020fbf61a40ff00878175792e9a714ce1db8222ef1d7402011e9041a6e712dc7d084ee5d262d649127eb1ac5c5e2aed646032bb5e0af2bd4508ea2fcd65c71495abe820b0e2c1db351ab07b772dbdc35dbfb489fc163b76d29a0fb2c4dd2be90dbf9e64e0bcd732eba72c4ffebd42650d039f0f36e7db4979a96afe0dc83ca50a5cafbdc8daae63949c7a606b38ec164d620eda9aa088d5cc96c5400bdce0084f5097950ed3e9803868dc113df14a89013d87c6384458cdca71a09538c34628c823883a5d36c0720efb8add1c5bb5e1bd494229379b6c46efe0f24d2d5991a0d37627c8e70b3bb70361837add0e44d45a8a78f189d3616ca3fc3124e49d53582cf534018eb148b423bf3813fb64d4926c2293ca196bbdfc495c79c99c1a49122d7da150810ba35cf1289402d985fb53dbcb3318901402b75ef8a36d05f818ed5419e1fe837ae0407e647f3a665400eb1bb93993a88ce463814f06b2a9205dae595618cf9756df1fda735d7fcf3eddffefc69ff9f2fa529beb59eb2ca3647e631354c3a54c487974e92dc2aa96cab9b00a8001bc0e4f5993536b5501ff759890d29549c1f7fde9f5d81b45261dc20c50dd22f4b52861e69b0186ca157763947623b32b926b16c5cb40b808666059619660a9ff124ad968a06ee4f5b1073535c5b231f410e5226f5ba897dda81395440a1ad9077c4a9d7ca4c978b96b8e002498c6b225f0c97dd32cc15c624a828423cde18d3db6ab3241f818f35aad1380a5bcd0d76f7ec078d71c39589e56d73dd5bd3f2150a2c9aca4d9d9d9441daf659075943920a440090bcd47a5ea4c0bf7f5156fa361e394e4dcba9fbc7ab2fdde48fd56da4e52b1e6b827d84c67878275d828edcdd5b49b0838f1eed7dc4f2c6c9a5c5e669775e0e8e586f59bad82ff3f4d0fba7c73ebd477a728f8777cdd2285b3c4b79baeffeb907787a51d7532131dff656770a1b6c1b57294ff7de3ff31e4faffa8c5a3b6aa975dd76dcbba6e07ebafbeec7f7eff73fdcbe8c86fb96a4823192cac6edfb69a10406286117e2ae29111b6ae1034cc34a3a0265a0621ab9c22cf2ad485d71f71627e438c1bff2b2fbe1cefdb63913571f60018e98165709247d5a7c461777049215b2b1712b4602ead45a82c502b43e43f2ecb6b82e8d3a5de65c5b782bd02ebd50d1bd6089d548e10f827fa5c064374cf173a6ee5aabba4fb730fe9bfb6100972f207de4ccb92d1ea4abf8d272002caab8ab67c7c4de89cdfb1a354b980ff0332a97362a33e08f67d2e2133de015971b82cc9bcd426fca44723c9fb2f8ef8fe9ff1c5affc69bb16d918fc06e5b1832ec086b0bf8beb760f528036a9766bb99ede1ce1ad00dd59007a4c04574334002bc118c1f832c5b718fa9022771065ca14d2c2cfbd0714fab5131346ecd70d537d63bf5201eada9a2047702274e969ef2ce1df0e22dd50e8fcced9ceef275390df86cf0ac0ebcc7ddeb23efd5c537d41d769873a5eebb02c2b2933de59136f814423cf7aed09079ae5fb16d03cad26c0fabb0b4e40e3b0f324db3012cb03389fbe9702dfdcb4d939a305dfbc0aa35b22488eb819b0fb4e826e9eee254efa6365297d43b8d76c85c98e66d507db80781dc897240f6bf6e550308933975f68e051665620ea07dbdd1eee3f3abf36f6c94ad156059bac50c9ab3dc03e23ce819f446318657eeed8fb475431c4c52c1a0d6018420204e6a37f182db924d49b112d2011300c0697791dc215fe0d3bb10e28a6c30d9c1c0ec93f9c456332a138922826de489c496fbe20c8c6aa51ee8e0d31b8f6932d8ec0727eb4f7a104093d1c90364df5ff671ec8430ecbd8d9be5dea8cac6b4408bb58175641e0d3892a0bd887745b105925f34e1a9c1788dade786da8521b63eb4ee7ffcb0fdebfff8f0faf280ac090d64c579834f80e7c7d7327400195e363cba1b0b030b0af07d42576173ca610473862142e32a71bab7dfd3843c20afa474779dfb48edb6b96b9ee233eed36a9a83ba6c540338160bb35827f699a42b62533a48805e8f9cdf965d88ad600ea9c43e3331ae5d537c2e76e1a0911b90490b12e6ba66a52e597a425e5cafd7a2c1b65a65e7af326ff1c2eeeee12b2ed422b059c0a1b2f0c54cdf1e0abd22ead348cd6e3a17c41674e4b8f06858fb9d3e33fb6cdf9152e232af20304752b14f31c51d559bc48a0ce3fa8c997526561784f1b47f452a7fbafbf77f7fbfdfbfba9053b134db556deb0c4a072e7635600ea59247526a79a411b9de8624a686b5e1b18b83970591f49479c9c62af1d20d682ff36905e544c1f47017d3f4d83d77d42e2ff0255f3fb674f9754f22c3df608bf74c03c463a899b6a51a1fc94b011ef0ce10127fe6eedcc695d47653dbaf7d6e2be5d73f37cbf05bfeba132f3cdb45f15fe4774df2975dab42ffc3fd8fef3fffe9c3e7578753648c0a14d0bf837e0040c0b9cb95163bb8e8b9850c6e433734156be341ae5ec1645f69717c55aeb883fd11163dcbb8922e37c08d02784f17e22d1f53f97cfe0363704fa095ac812f8f6821c2605126c9a88d6d04da1fcd3c531020cc2d13236ac8f8a7f1cf3d7e1a4143e95245baf70e9d6d532d164611b84474a56ac8ef1c34f7c8ed443ae03113bb3dbcc34c5f76b353b829ee225db9f381655454f9a5484344a2a6df2acdb6c992b846a5202e106e6c79b85331f27b5ea9ec0104f6ab880b64ec65f1fa5689f72e94980432078d85f94b519a882cfd4e33b618c9004837415c67c20b4c3596862748f9413021b80e92773166508423fee0a88c340e29a9884946027895dcd9ad22f87b921aca34fd45dc5e8cada928641d3d72c85b8a4471349d6fdd23af00258ac82b18645b6284c4b376f068481e7813dff77097dd164b1294a78c34fc1279a03371cf5850e69e6dba361f84a5ab1a5b6154f62014a9b9c24cb43c19849c1d7d8a28e018c48f5b7b9f8fb3f52d0c1b24b11aea842321130ca7eecef6e01c1dbad45c07ebf033eae6a439d655ce69f765b5f3da421a1523a26c51925a128f3ca31a16890af3170ed89392a9adfcbc0252eff172d26960bcbdb6e2269dcaef3fd02b88f97659cadef21f3fde557ef5397bf1672a3bf93dc85116c17b4662d7a4f5e3f7ef5f6885e11b3c1558cd3edf5452d9bb5e1c8c0578f46431b7eec5d5cd9c19890b22343535b2fa566ae436c45718f300dcd749323619891336487b823fecfe2d370005d6e6c2c8baed11ba67d0603450015670cc195240ddb598584a2609f62dbfb760b9735a12aade8d8a340530a2e760d79a54c7c33b4526631a1b7167a52571670b054cfd5883719f4d8ebb72531cbe8da51401c58ad2e41449440590424c3af7dab16a558c8abee546a5685abe16c75991bf66b6434e1cf86740a7d07b36b834153e4da13ae26a39aeb655aa9207b82397b59ca271ef28667e78c70c2cb1cb89b427ccab2f126967bb90e4eb27ac25f9dea170e98fb851efb162ab20b05150e6cc82599daafa29208de6607a042db0793329df4aeda465a4e377b8be3ecf72aa132c6b20dfe988bdb8c7cb83cc673101596495fd805057a6a15b005082c98d8d1a3881c1198cfac03e532546990b16303ba8b68efc950c6e8c065f938cd344220e123250dc3149e6c33b9dc33decc73130035003f49bc19dd8960c9e2eb7185d5ad3f1fb147bb39ac724017df2b41cabdfb6b0c7d93250b30fd46558a76558371f8be0c31b8440b418460d8aa8ddf72b9c061a0f2f8930988fb98431e70dd57d4cf48507c43bb762b5d8b77d6ec0726d13f7f79fe99bbcf4cd88e66a0329ac23638137d6ce4171095948210be26ddd890579478890a1ae68226f22a13e1cfd8e3703b766f409f80b2b987b145824a3459f26efd3e8ff1cfd8f74aa8aa577d0f2718b10988031b2f243b0cd8db103a8f41f3100ff883b2dd44cdedb37d68f28882710baf4048eef044376136780fb5773c471008706696cf80ed6b40e90b30696a887bbdcccade9cabfea5eee663524a2749ff70dc94d03dc74d691cf3fa977e06f82d0aeff9aab0b4f1f8c79a0596419af90c5c8608a8b5fb40930bdaf9a04d8f3b545f0cf7ff9f0e36bb35dad48c014c87ebae1e71fdb28ff8b7f8c956aa5712d1d855da552dbe729512caae81d4b1cc04eae1d39ca44fd63ef47e0d86b757706375a2ae7fcf4f8f28ff270c70d6d3ff7e1c359b86680155e806582970cb94ba9ec33d07dfce358b078bcecf2c42b6fc4253dde728f88352e70bc8d06888db9d2f2db3c444686358a5296663758ae974963ab48ad412001458fd5656b6f255bd976541cfa640276fa9a472c17d4131f7a4344aa826512982740225d6144f71dab5ce55a1a01b9adc003452dfbe9667b7f09ac2b92249401231c11df83ea25b976215d116aff7945a2bf7f191c1c6ff4df6adf4e496533dac2376fc1e1793f80ec75fe2fc74f99a77c27131e829f7ab15dbe5fc36cf9e7ef57305bfef9ff7bbf7d9981fe2dac64063a8a983f90c5a95137d74f599b8fc082fa588b273d2fd595984896dda73d0bd0e4095d501f7343716578a336a8005ab3ecd4e7dcd1b6c6d480fbdd5c1f73b649ad6334ebd03c0a99d66ba9d3ff4cd6a9d681f2d5c241b66d98bd7be5f80bb198de7a2ad76eba77b824b5d50d9c845e93f442d2603da0d6cbc7d2f1a12e76b9f7e35aa7fbef2bddbedf7ff8e1fec3fdd56b73f9544664f124c47414749092bb7fdee70efc52ff3323e640cb9ef84ccbd1a9cbc31d17cb3da8efdde57f72f8fde381f1ffd97dce6e90fd3a59aba4f2cdd7b9d46dc77e58ebbae3becbdd77f322dde7bae53776df6c89876da3b19e76c9fdd3ce7cae2fddde4ba32c42909eb4f2fd9356fe8eb5fa548d22ce2406fede84b3dd3c8d79eae72ef2b4ab9e3ecdcf75dccd331d77b3d2711f0feff79f7e78ff2f3fbcfff83fdffffd854cac6f88b8f49684db8e5bb960a21f73d1be30d1afb85ff2028ec1b02fbc009010472fafb808bfef03802c85856143730b586215bf48a5d2b2b9cf05ced3795d40683ada736410c6ed2219044ebed682c88d15a61961f002a013467aab1956af67dc38b61fee443baa3adc990e78a49a1b92c43a024c0acf1959cfe23e73708facf14eec3220f540216c2053ad3410db6979fa4f8d6adb28a3a830e2497d9220931791a76d944792d65ce192e3a8dcc12f6b4c665997305476d756e3bac9af7b05c09a689d1c602b78b464e36046bc64ebf73451fa8c8c6dc6f3e1dd40f2bba4e4d7b47c9563e4aa14ea72e042adee67904ed49bb9445d875197fd0c968b7a404d4b0dccbd6ee0bb45b64a47ac2eaa4f2ffa4c5f8ed4b571fec521cf0ff7d736d4fdd433113f17e264e3cac679279ecbd74d7482ddc670886a096fd1d1a349db568c26c347ad8204bfba2420b79ab819904adcc1e60dcf49c672944215eab36752eb10442a45b7a2c473b8305a82342e422b09f2a810488d12a9363a4005b447710222250c19c28d53dc58de9e3f3c0028e2a57cd43fdc81abbab58cfa8f020ee9da22836404b209d5892a2cd599996641486b44bee6e8ea0e99455a4c4724b5521d48142b1d519b2158cd902841110caa3e389fbf11c6a0dfc30ca3b04e1f216cba1c95e32824771a42513d0fa1ae965b212976bc6f5eeeabd47466a136461ede519969082fef91f01e7b1fc85ddcede4d96e7df80102771e53ae990638fe69b6be052177c74bcf99fca52be6e03601a3e7cddf5dc50d405c75201af481b49deab375a7c19aa63704feaa1d6bd35d8cc42421799e5d53f7ce7118f201fd309bae1fb511f7998690f1c875823a37ee9ce3ce975e21c72bc4fba25a8ee7c55595f381fc339ae0b216f8ee7ffd74fb424908dfe26c15f78216573fca094aaaea9b258d72e6eb7f350d1ebdfd9569705ca644e23e887db037212eb6199d4c266aadc447ef20ad8a3f59383543e08f5bbfe12a912f2235e2dbf6c84fb3932edb65d7a924d9ea52bc2dd52fb0cd62a41dca6ab6e9c3cb22b2cc3ebdb2e1b186d1d411b4ee9d5aad5999740aeafb41e1308626a934266ada6af1513a42bd616a11e9cb61588a9f352233c2ae1ceb8db672a4cf09fe1c7b24d0b93ac1839c31f3d842cd73b35cc1df73d611217e60cfa94c7f22d196e632ea5ca95884bd6178a83110d88021426c15d80a486b470165f3814cac962a5351e8b362defe141672919a1afb8d237bada6c1a402982b2bb8b10c75df96e7c52ccaa743e1999114075c1e4baf6e362d8008c34a8092ab5a4e937a26f1af64d46f22afcac7c453d0b9d354fb256edd0dcf0a5cb5c8cde934522099a3d83022cba94ae0eb55308633c0f38021cd0b865af3dbe35c7778ac538386454e106c60df01adda1217c93d602e985a9e58bfa83e36947ae400ab149f90252edd7c468a7918b35162d7d5cb8906a4c3820c101c81f5dc84ec14aa4043633e6e0c9a87cc73d11a67ad90d142eb71483f1e7072c0313352bf168677d2e2cda034310707521b9e22723153a4627a93d4257b66e03530f5fe9cf83e23b82b22fbbf7ebaddbf0c92c0b7a87d6e498bfd91041dc12ff20a2841a247d63a113b56baf0f3edfd4be5f27c4322f7ec348d9374f5ef2d0fcc15f19596bf9057ec4ddd3a8d21fb8c2cae56b6f9c9e1715c8bbf5a1caca9ec33f2fe919afbe4b2cb5fc7aba7e5ea0034786b834ab1b47c2d3697f90f65a7b56d1b35e9c838c895b4ab6fb01c327814b1337ecff83db35c69c57cba779d52eac8f13d1feeb23bda7e42c3d79eb5c715e3fb5a5adcc1b85d712dd464ec17482716a33602d5b98dcba61ffa7e4d58b06345587edcbdfffcf1fdab8bedd8c422c22edb78e411fb024ffc68b97d8daf6c760169fc4856b6b2e742c69588ada2ca961b44dd25325fed97fe1555965fe2514b597bc38b9dbcf4d95a372fbb563afaa7cf9f5e0ced5ee537a715ab1b86a525f359bbd56d6652361f58ea4684c2ea1c3db28dc5f2246d70879a5bb964ee23ba4d2e484a50b7650d182dfe87db132d200698a6ccac001c71b7da1ae751c96cee60858c798b92e1530931f532e26efb86f12d2874640cc34eb548362a8c5c95169c087e46fc7505542e9f3b4802385e46663246ed9fc078edc092b07a25b054bfbabd689e6ef3efdd318945f35afdfe3a804e637effa5dcd2ddff3825feba622dc4c3b652a86994704ce0bbb6997be464f824c4a7bf8c0c6b7b32a8a2cc50c0e53390c2030b9c044907d2608aa87554128251a81441da8cee99fd467e3f6d63eb1ebbe446ddd80f6ec8026bdcbc5d05252593fb46a6dbffa847992c5851ea8c7a769bd4b406b8999055fcdacd1fd80dc42ac92a955e13f776c5b2cd8bb2ce0cf21528e5c47258daaea4d87fd4e3f1ffcead35e084502948576ea567261ec0eb97d133b697de7aee3690900b7751443e36cdbb7e26733999025c60841300f217af6ba3b8a7aa255c55aacd450d99a24c5c3877eac8d7613722a84e38984580635b461abe1bf976b5a3e690e105d9654767d10d6b0a65d9b5a250febedddd7efcfefddbfdab9b3c5cbb1e31732f78e0dacae2f6b37bc2e1224fb88e8648d8ec9cb9f9d71e787ddb49da059029019c22e0766833ea04a7f13e80fd3656264d142032cdb1e00135260b4ca024567c4a3b829ead7acf0f7736860bfd15cb710294d08cfea42d9cdc919f3e683cc0369f3d6a5e7fd478522e6e98f464c057e8a899b3aa64ba6cbbc16ac31beb3c5cf1240ef0a4999fbcc333c53167b2b326738f7b57c56e7f7b77ebb2f63a61406bb1655118f08bb307c0a79d003efdfbbb018c0d6f742c216f16b0d0a1f16d7a84ffbcf733708571820e7db8c3756a01a89a1538e381da3fab6f59bb8f3f12fe88fff3e9a77cfa23c71fd61eee508481ccb24a6a6ddfc978f83b6c11e06ea40d20e72570770cb5372edff1d7ce1595b9b9acc855609fa86ab6e32173c0813e5d39c7957bcd8d46c7d2d604d540abc11c3064f96b979b920e75b53b62c54c482b70d8461c1a79c5f539797b2a34eb52f7f4986765ef7f7efe70fbf1fb9792be6f29999854b927b3428575534784d1ac0b95d2536d46a3b410707197cc37af90b361dbec120b07ac4e9a73ba7e29b56663aabd6728b47e2dd6c84411b018d53d396b2899f1e97309c1b945c3692871b554f6a2d36f65dca8c8087006f51bfeb7fcfe4af93d0adef3127c3cea59197e6df918dc9b4f39bf23d0f13b71ebca27779e731fc1c62e1b9d6433b03b66474cad18c3896900fc707fad3552db22411634134aea46bedb5903921f8b688571d9ec97e5e68e4840734dc0f1da529221a893b8b249a21bad541169f049b91f0f3f7fd25f2006cf77ff5ab7ff70fbf12f2f65ab7d0b29b04bfe6849b9ba7973cd52921550644e91a44c45e6968119c50bc9b3f153136df96397190059d4fca781076b73315bacb61b355beca821b0f88a426d21ec3a45163beaba4bd256f6134f96e36bdbc8e76f7ca22cb5cfe50f91f006f612167f7ce1f899e290d8c65923b0209af4873b7c0f306e3619d70a184adbe778f71cefbe913eb18252c31b736fa935403f2bbbb93a5210526f4c3b965354d0212e7556a36f8ed8bbf1ee39de1dab29d0f1ded2cbbb2b121c64bfbc765ade3e3fbec8c8f1facb1fa7d7cff1e2cb579cb1b4d1b27d6c80e59ccb62bec8eaaa902ffb2e8af8e7cf9ffe76ff0a051d79a266de11b7c0e849f109a5b92ca8a93b97a84d8a949f025ed699b967e3bdb6c030976bb088cea87f6eae5baca060b56a32c568293320278ce06c663709f84a6cf5d6405a3e8e0d0b5f083c0071a6df9867c29d79185980d0f440dbb2417eedc4a322ab1c4b399c8d83dec42f7053dbd7f73d0239b36c97370e79f4dbcf84e745c98aa4c757e646b6e702405dffd26b9935b9b0716067e0cea4d36f8f46dbad36f71126fb3826c2ab020c3ac7a9b835cfa5b91b102ca5b6b8f94871732b3da97462e827e4d07b8b19553448bb8c85f485ac5e16f4e31197c4fdb54979493cca2356c297a8dd62db1654c488d74568e46025822641fd28114db96a7618b6b66389c0c090027912f684516976badae30d12cb6e3c5eede90e2ba7477abccd25b4872b2de5f1e6296e9e581eeed86782de76d9560f380cdbe561abbbd61fd8db6a158842b184b4b4ca69d5e1e11d379fefc6e3cac493fdde9cfe002b7bcedbf3ecb1582e80939cf7e263933d2fea17257c4db07f7cfff9e3edfefac3c7bfbec2e0928152b75c592967bcbd0b59ed592dcb95947332e0f22642fde3cbb3c0bc38deda78636339b2bc61961b6b767bfe2bb671dba7bfa26245bfe6c95529fff6cec67853769965c4c4d2dfc4c452dfb89a75e5fcc667964a5ddfe0f39ab5faa9a4fd56ec8dd8e999d4aeb9766afd8df6a7fbd4de946bd34a32de30323cde58e737dc7c2a7ac3f58df11b23fff2c940ecedf9c978c24b84be5fc8c2aa143d39e279718a448d576a1c3c4d5ffa15298e8fe94be7e9abf9ab9ca7f38ca887bb0c8a942b71d75f664807eb62770c1801ed18595c0cecbdbbf5c392461ca075aa5c41976b3ef9636532c53a656cb3902c69d1c7f38bcca3516f48803c3bb21eff889b963d109aa5e5e53b6e0cd6f53979a37550a923f9f43c7b5f80d7153e18b6fdb83e1fe1907e558472456a7e46fc4ec7ad08e17fbeffa7cf9f7ef8e1f5adcbd7606a526f9d6d687eac9703ef57c6b28d558a1b13bb76412afb4875a82dabecac92cd6d386208304bc5920f4e5a16dff72c0d80d6fe2500126519d7e7377f786743690c00a0cb364729bf76aa79e249b0c90a9683b2479ae84492ea0c327fff5820dc03c7dda8d53c49396b987efb8897873447981c51f2d8823b7e0c91837e755a8aaf2d10e7f081ab2600ab2e57bd369ef1dc63fb78356c2d978cfbef1f1f73796c7c6efdbd18af3b526cfbfb366037e06d2fcae849a8d604f3b473551abfdbdfdeef5e1bc414aac7dcc0ea9546059c4a07a507e052d95089a94aec2e3a72a72a0dc12a4a9f0100250dcd58c132d1a8036ebace5b15c242e223ea5e415ef6dc801d23696fa8699f9d4a8726c7c3d870fd395d7f56415502f033b1006d0dfcb93a3be9bc650bc8f5f85a3c2b601ef0c39db2d200dd0407c267adb1f87cabca58698daf78aec118374500d2f7f583e778f05a0bc94c8c97050ee1d40002f74eb855c047a6e52b4e64eb20f4ebd4af7dd8b6a4a4fded139c4a4d8d785cfb0e6076d727bb7d1ff0bcf6750cd296ac1a75fd12ead25a161abc67e0104a25798a97099010402f00820968876c022876cd5a48c7db693ed2e373815265789eb7fe5b4bf1b9bc1866af3c8504d5180dc518ad2eee9e164b3ce5d65c09a5f88c2e6277ecd8d5890249a1d1986f5dd294d3f2b55c4290c5770b8e2c49cbd7524f609602f157989ae6eafd62e05e61a509be557e66146330ae8f61ec5a1dc1af6ee5a10b5549624cb6a93cce6593cb229beea235fb2ec0687d6f433ae488d3f899615afbf9306df5384cc3e91bf7e2422300c4f0db18b0137abf70d118428bcbe8867cf4e08246cb0604e7e8643d7e2d0213473edc952c566e67751189cfe5cad88646b260acc1679cdd9a8b43a3f9768258223efdae811fcded72d1ec7faec6fcff7325c6ffa7974227ff8652d92a3e15861f025e9292ab21f4ea3d154c292c34da9e0538dde27a7e2303a8de8c9aafc148cb48d226a906c3c504cccb09f2b577ef7f80bfd649a65b64b42cb7497147dc065370bb66100c891895b1891b892e77512120592431a1d6b75c529fd4fdcccae023d76041d7e31fcb9bc57d326e89dbe47833203a708a5743be0912134cd3208e4c7f9076d4b980c5f8ed3297e5f2f9fcc6396e5ca23571af68d0b857b4e83e6e058c74068c1a68466bdc2ac75d3b2c32bf6be692714bdc289fdf68f96381561ee34418c3d08df998fbbac8f9b37cb17f5ac5fffed31aecf79f6eef7ffc1fb7dbbffeedf6f3aba3e02bc9b4dd80a06e09de1ccde72741a5b3381757a6792dc0b3ecae26a5366297160dcd082cc231d26c0776e7e5daea3c1e6ba31c8ff587c6b1be31db4105c9fa9d0c0baf987a02bad0add56b00d38f4a7a13741e170f84e6c471c734a65f1478bbd8cd8f7db7dadf8fbbd73bfe4f9f3ebfc67ef7537b3b4465cc976df434fef7d848373e25f1b5f446158bf36d9ba510480c64e9021ad880e3b21c8f1d387c131d5683d0d14c018968dc96c25a141630cdec7d9a4ed789b8b9341a3f731ce6521cf72b24fab9ae5f7aef42cf2f7bd73afeefafadc36d005cf1a6bb3372ce94954123052ead6bc3b217dcbeb7e7645a5640d154aeb89527e7461181d978c2bdb5141048f9e2d7ac72e316ecd32b643d86bdf59c748023777997bffa7581683cff355290775ffd88aa7717e2f12257e6c0abfe077bea92d9f5e0949b663b6ee560e389eb13f7b101461d9671a55f7659548e7cd9bdd1e96b7dfe95d43c532af2a7dbbfaf0eb7bfaf0cb3f7b73feede7f7e85f1753fb56cac1512408db5349bdb2d4092ee41a0383a350660c04cd2a8b56c340c85a096c19a3e0a89edb907e3460711608bc894a0eed962cb076f4de5fef8b31ed7e7f5ba8367cbefa888158d53ac683c8d15a5d34efc3e63d3778d54f6b5136bae9d4adf1a9674892d0d508b0a55375b2b4d806f36bcc1c8c0d89be0349506784c15aa606aa97605ba43db8301376099c796236460340257b383978c412c5841792dbb3c98d8f65c1a0861948437b52c310498c4d5ed68b4a8846d71d11979149f35813bedbc2877af4de8ac75ef157331dae606dad226845c07a6d6733300325401d167a5aeb903dab10fb7bc5b01c568a12979040f6b75b16c05c460c01ced403de50aea9c0696526126ee105377393be848bdf55f5e4cdb53296d8de09d16ddc0711204765a75bf0b560773d260e4d5614056e6b96794b7a31ccbb636694edf9e9ab4815a02d1226ba41ce021bb3c3bf5b177e3b6063fc5d65cda73475a81826d920d88298c86e039492f96c22ce2745908d724f0eef685f236dd37faede8c1a96c15a98b08a20607ddc23ab75005da89456a9b8f87e6237bdec222f8dd4426210cb591ca1d03d253935623eec000cc3ce5ed917d07b3566f00d84582a31ba642dd3d43f717d57bb40243614ccb5d7d0094ab516ecfae00f08701df75b947e2291ba3a935a97beb65115bc5ca8c222b7e57db2303c66392fee342b3cac5b4f39b387fcb952ac2b3d20319c1a8f560b61f9a65d2908b91b7908455d9f11d2ba2f3e1fbdd8fef3fffdf2f542ef70d91f36a6ee5db3e56561a3ab9edb2d8b54827ae2399ed74522d73237d90aa268b709cfbf558ed1949c77d9ed45cdd61395035b72bae7260d9019a084c1c7bd7137ed028573c7ceb7a24566cdd4819bb71800d74106a6084b6340ee67ff4bd6fdf04e2f281dbd5382092a3d7711d08851a2ec9529216f3ebe0be7e82ec1848c2dde7bb86f2dae531859ad4e31fedebb7d8e578f96b3504c877627b0b1a4134d8761e8f4d1394707560cbed2e9f8eb9074fad5f153f5f94a99388acc9d569e79a6ced5f6c61fa1b501fdd7d646d37e54a6c833410288cd8103b0428cf4a92886abb4061d3fc5a0b72c4a9f2651ceb5ec02cba1e7d2863cdb33ee4b1e6af721b6b2198e1367c5b4f2bfaddaedfe5305eea0e0f77b305fcc7a1118335a7ec1af1b605474244126ae29efa7e769a698e2d32d2a826704ab4d49fcd4d5b2471557ef7ebcbdbd8f179bbfb70789989f51b04583b3076aea54fe2d441ce857fde12d97d83dcbd1517b68771c8de98de1dae55003a6e7e98371830fe2d29a093bd69912c01a65e8eada814079a774bc0e9f4eee8f7be13f8e5c076c882e2ff9681f449354b7f781c69a817680715f757ffb081f76e569ae1862eb77eb85321ccd7dbac714a1d0084cb95dd30159ad7ee9bb9dd73c8716a8e73bff83340cfdc673e5dfd707eabaffe1021de56bc2bde20c042025364cf9d348d4e1d321f4debfdd2c4071c2f5bcf8a77c8ea25118fbd17c4fca7bf7cf8f4da84fc0fd7d220490e06ad2346725a3092d3a07acdc592f6761528f95f2bbcba1a6394b1d74ac0c9aa8f40cfa013223007e0e20756700413d821db7612bbb7930090ed82827c8be0dc448d06928bdc791677300c143ee022f28f195b5d427d16176f714913211490c75a7f3e9df970375c01771750234bd5c70db6d8ddc705f76f9c2e62b976b04e3c5e224526778fdc66cd33f0745895c6d3c7c613e8e3630738130bd37c51f5ef427e6974f8bef5b1b1f9f497d7a7ff8fed651c59994b8b953ab70d187f6835eb20e29fc7dcb34e45e67ec12c89afb7625440c482af252de0f1f20fef6461325e1d348f83d3ea69785afd6280aeba413148d7fda065a0fadca424a5252b856aa9b7c053a2639e43a7e623c6608fd388d0c460797a582ab9d3e873ffdc318f97e249b54f1f98637c7943941d77ead6afb93078e9b5edad0090412b8d6e5f5cf7f18c7d3ebfb23ddc55269935d542e6eea574b2aab9d3ec7e8d02f3a89cd61ea90d76e53265df80fe29ee2e48fbfad884a3e28c3daeea4f10573d7b32df1f87ee33ae981eafa81395feb31f57f8a94d9cc00f77dc0af5294b01703d367d5a6bd6e8a11c5d04fe90bcd6ae68a51ced2ac390d8a00d896dbd695e6bd8fc78cafe990b9fddffb9c7a452fcd8d19f5520ae092ee80fdf75497d7cfcf1f3ed0b21bcff03cdaeef9aa52e41a3196c1b19c41abb514e6c1b27128e402cf69f4f041c695c75d9c6d9250731471e79dc7479b82b0970f3bff3a50fa058e109761cb171a5c51e2191cfe092efcfe091b124639d7806ceb1cf81ca243d4f62cb0a9664511a2d0bcd9a2ba2ab54666ec8ee29c41d9b7e51914860a022a9816c3b90b92aa9dd72a519d0c5739c167f8c9481e6bccd88a766ea3583a3cbef4ea582f227fb3f966cbe976da1901af39acd1054ab730f5f8293328db1cda824e24e0dbc7d3a924c3083736c1c218802faf90c17fafe11053a73dbf9ec3fb746c3c56712bb622bc0516c20376a7b1ec43357a3665b753382a290d8103b358013f711dbf73c09f57b75e267d80086e2d5880135dbf2a4de17969e6ade00937a6a6de1260255905171a36d36bf14f26eb0f5f0bbfa59cf2a96d01117954becbea060ee0fffa7eb96bb3cdb92abf8c5c0dee5710192fc483af825ecf9f8852a03575eaf5d58f0f0568b17d62fff70674602c6b82bd85aabba6845c3b913d0b79500d0ed263d83b125b61a35bf0893420b08062ff0cf69d81eb6fc44267bf736b20e8583fa30cddcb14e846d19c4de800bf5ac6b135763920c496dd8be92f24b95ed2ec753e7786c78226e8ed4652b1e3b3129b2d882648dfdb587edf1d0291eda9f39f933439414689c63d9c633635995c1d235131e339b2ba0d85ed2be9a1ddc74d89600484eeea09b6b611788da5c93c0d161b09782babc613d1dfb6e6475e639a3907a6c8ce5365ad1b442911c35a21e73a489443775858472831e4fc381c225d8bccfc33d5360e5fb8fb922e94e34aa3da39276e43aa8f1b28dcbfe8ac77cb863e1cc75beb8d6bb3f5c5278f787755df74f9ffef671ffe9f665b2a7fe91145e87650168f2b67757db0469b7084c541f42ec4358676cba778752111c99fdc84d5708833becc82ca891643f8d86f8962ba2433e62115a7a3a910793ea5796d061945dabc463cb863535e83fe48301a1447a924edafeb0a9f528311724edb87b5ddcfef9efdbf72fc3d5ff8f246bad1027245820efce3d33fc3495eab612a791a921c317d62bb676598d26e6319fc610ecb2e8da46ba9132000b0c46e129099872f1ed120c24e191d95532f42df4640ea27337943908330bb9a8eb1533f0c13099809aad2ccf820c607f5acdfeb4f9b40546c23c12016f356c3e6cedd40873b4eb44849d2ce24b8d14f8e3c9068d24483f00a5351eae1eeb48a096f1736e71becfc88095c82dba044d7025ddb6936a0e68010084e34e683ffb83426210f00b4303fb2e8d0bfcf0ca6a354e2db6ae257eb1a6797857916434f65094d099db459cfc23328d23e9d415f00dc83e9b1d9aedfcb31230948d60916868c0d3d1d7b8b8ca162202c16ab0b630f01eeeb2f699643c724e3fc2b6c281eaedf9f1fa3bea05ad6ed68d4704d94720d7e785caa5e3a254f9ce75b1fabfee6ebfff470ab59e258b0430465f8bb0de22b42a69f93ac6a582117af6ffcd11d63b94639a9fde2e5455df7f51b5fd85b71387f269dfc39d9491c4ca2e4b6d7bb251b30dffbae66254ad2695b17d5251cdd4e7cc4652d090366a1cdf4a1cdf86dbe9eea5cb5297fd7541767e5a667dadb29c5c8089f29cc442f02e082cf65d92d7975383df4020866a8b5f41b4cf0cbac6873b833b080498cb8a5287fd1293ec2e73d5a47c53aeb846352bea7aec0c3ce520cd96ebd4a0263deacc7cd299c8deba769da8253207dc0d6b5163107863a1a6d3a39a4e27359d424de32250677e37d6f61b0c24eded8281f4ac603da30a63e705d1fa78f8f461fbfe9f3eedf7b72f9357fa4ab20fcee4e4bf441c7a940b919a6fbcfcc31d9b0114628c1b03b8ced76195b61a381223995b1f033233564a84a447719d22adda874775333583e8dc88414e95a962159c6def1a1a6c5bc25bf15d42cd52a3e1a7f416b58a99ba26a5d1d3c2cf2e2d2975416da260732783d88dd8e00fa181f8776c81ff099969d31fa6c196e6198fc2425df7d900b65db74b695ff5d751c64b299a03dba60136262856e449a5022bda126a1e33f0b56f44d7c4603d728326440bfa4f6840b7b4111ed70ec3aeba6f9250af6eee1451ef511ceaed07b700a888c2db8c50b5b7606ec86da7dea0b894ba66050f1f99666fc01c55e4282d4703e668c1bcacae338d8425046c2d4d98105953c4a9bc09f130299ad06a420b46456605a53fe3a5221e80eda501916a0d12b952131a30a30103a0fc59c577aebf2ee9bff3639e5583af4d01a2f610348b6ef3f35ce64f9f3e2bffb75afc4397e7c08854d643ffbf22907ee15950115fca611e19549faef45d5cf63ae4d9d6036722eb6b88bf60343d3f8ed647d0bbf77ff9b0bdddbf4274282003208e35c6a61b04bb8579884a013b88cad538c5905c9fe57309f11f123a6ac756686e159a6f24262c0bf8317b9e34837eb8369f635cc76e857cea4040d262c30dcfb2577f8a36a95e699513a5c9a3b57cffc86e8265de31695e8b9524bdd2d8634520c52d7c264d40b964641acc306ecb35ab2161b25c353b70649bfd5a5394e552ac8eab66e56b357dc68297f28d41d547a1ba20928f073c2b95af4dafff431bb6773e7850bc19c32363788426aced50dbd73fdbe3e8ca185dae1e6bf3e3577680af6119778bd6ac6dc97a7cfab39d22a8c7317aa86d57db97bffe02197b5ec0d6a5ebcf7ff98fd726593cd88dc3eaf2922b8a5908dcd3330bbed240d3f48829cf24c916290af240d9e6ee8250dc99efa430d1b22c19c21decbfb9279da0aaf6dfa63bd100cee879527363380837b342ac0b8d877703116d3729b725850119e8978ae72b885a03671ee032300811da07cdfb2974b5636d0795a3323b13da2476e404d1474690239ba66d9611711a16a9ec7cbe3df9e8088c8fd3e078b8cb2371671adb2cc09c97ac6889e9a669cf5569240c5984f599402dde22fe6e8494177f1558b2164c87d669b8259e6b3423a166d24d784e1dde514bd2bd0907e626bfa63fd4a83432527389893349441dd89f7b027bc9af537335aaa9b99deecf3131976061acfa77e4dc831132f3001b4e6e48b3f5cbfb5b5477c8182a093d287e6e8fd471c3fd663033e21b7490c50d79009830082bc1fda8401aa3e60fa41990288a7c6479b21c7741f1edf22fd47ba0af945a49b7fee0de2b3808f80c4223cfa43d963d80e73dd25cbe9ed3077ffecb7f5cd0057ffecb7f5cd0039ffef6fef30f9f3e7c7c75c9773cd50748673a9919150b3a18e140ce49136ca034931b2fe0f47493c68005eda60532005c6f80aad3a5b5ee5c9ee721b7427d279de6efdaaf7ff47c56159058b22d6916d23c10b9ec78710eb8c17601d46597b5d06a59d28d682359cbd31fbcf5d1ea4a585034e277f3adcb0cf54f85ec92789e0eb820a59fdfdf6f3f7ff8e1c5c82bfea1d69a07c003fa241b7b6600d6f927600ed2e3c7936af1bd2bf4e98a6f5e6bb16465928e9f39e5fce2f974548ea3b089035381816f5848d9bb5815f737a9b49f39ebc8fb914f000df9ecd0600bd03dae1457bd06f68145ea858cb0e3565cced9d65dce47bec52f5dce1135d8f5ac043b2ab023c213395f2d68e72aca4c1a0a4004afae5649c7de5b17edfc147142c7632dbfa6f200be13e90bc7a58adb8283869cdcdd7196323b4e6f8545a3ccb5bc6c05e0f958bb345ccf0e591fb0df7df8fee3ed8f3fbd108ffc372c800b2ad5938911dbf61bd38b5d7035828623cb42ae08f8571f9b59a82cd9c2a3fd17cb16ae67d9c2ed69b630920f95badb723623cc3a49615eb6431e422cfbc001ee54e61fb5527fc856a24a3e20f840930f88e04275e4b9000d0f75ebb19fd75b7d63aa040c8648bf1597917663dc766dd09cc01a6edef4e801b013c727a0dbd4dd1b1ff6c83ccbaef15d2bbbfcf4f8dce649d3e2431a951e9bdaa83088593af40e3e71dde513bfc4deedf42130032664d6b84c2a718de7f4c469885f5012a7fdeb1ae25f7ff8ef24459fcc2b1027d95bfb4ac40ea3ac4e69bbecf3e47a1875942b64246ef3925088a56124370a826bd233320af78fa98ddb46cd67a8061c489db179cc813c4b96746d1834a33da96b385c0957ad7f709e6288cc05718b9debb276f3e12fef5f5de9ee1f5a9ff8a558bf449ecc25118fba032adc0eee94cca60bf78e55901c9906aeff91d4f448488544ca0adad21b9d727ab827374f6257635ce653bd91512e93c1323f019a79f2da071dde17fb5abdc5b37fb1826189c1f8538ee408d9c8e6f18f78f8e7a418c2784188b16f5d86ffdf4f2f0488f98fa42d2b622252aeb4d46d0f940025d8f248907213a4efb3bad13cc0c19d2a5524c302cad60f99a4bbac30c096ca0aac27238495514a5e9157ab54512f99071388d35a00b8ef32d6d6fd8e06fd85d46d9416b4c491564b9a2ae9725f8ee8d824be624649478bfb463a813f549e647b981f7979f09ebb1bee408bc0ab616b27867ce24778841338825ba42df59124b27b10e6f2c6025e3e61f15c522710dff584f09eefec894911186828a78f86f48d9d4c6031b4a56c2629566ed08412a3c57f95818a75f34bb6c4b83061ad5db244de26f2df5a6684dd180d5069221b9999dcfaf8a3eadb7d145d187bbe6b7de8fd1f3fecb821efec45ddce0bbdb2da23fb7ffafce187d7e659564649c87d6e06eec49a030934aa9914b42aad2d418566f747f8b68076cbe04819cb97bb0b483a2a42d3ae65da02e3d7373246149ab324380680400bbe82fb2572e23b836a11e7ec5d85d591f0793d38d26f7adb7e1972c9a7e88ca472ada86877136f04a7633a1e6e4f0245b21ff005fd13a554478a86a0724124dbc6b20d8613a8ed4abdee01a731537c6dc11893e2d31498ecc3dfd39d96be6c1f910d6d1207c979ec46ce8fec45986acff1b5e5c5baac9052683e9fb833086a1eee32732391d47deabe6a95a66ed9ad5b753b5bfd429de6489d0c93c750778419f9555cbd3d1b677ca60a54ee41cdef69809a3704487b5db6fd9e96ca3dfe8a4749054f627b14a3e5e33526884f664dee179a2d5fd906a9257c3e33903036d6071376ad0fa8d796a05b0b6265c2c0ea7f19f9ef21d5df2cfffa4be47ffe52f9afbf4dfec725f9b7791a008bd8b545ecdaef3e00f8178d80747aaae3516ba3812f0c877a3e1ceacf0f870b43617518dcbdb66160604dd9e571905f8539dfec6ab6f573aecc2e9cb2cb6373cc2c2a69c9361ae3a09772c1c7214bf9e5240852762ae5579f33d64d963156793a1fdecd96b4cb2f7ff347dacc5ff240561eee0a12d7fe71af2f5d12164256800aeb05dcaeb98edb55566f320330bdbdf02d18cce06b5d7d6960fc6e7df18f7383cbaaf16e5d35deadaac61f5f2174f7e8347d36bb12a3226323d41995b4c57ad058b6d4411419b1996b9e8218fc34be3114fa741ae06c1a12ecd57057447be249cd2ddb8255beb19139a8f8a386f52125d5e213ba065d9c3fcab859aebde7e1f64acff8ee9b2a858a70d06bb754cb2485f5707a83677ae9c775906bec58eba98fdfbffffcc3e797cae7f886ee426297db2f95e65226541fab9d96585e62624b5ddcd002a2061bd3cc82bc2e66aa350b754d935c8705cd9d9b11027b30b6b990051a1f31e746dee90a7ea48e5207c5325ba789a5b8e283a8522cbb81d5dea84a7030061b1f75c5dca23467949fd2686ef574dd30982263ddab46489c810052853849aba4b2058f66c7c20c88ed827f173c7b6c12efd4600a4d244041781b103c622d5a9b3f7501d047ececb902f36320168fe3b8905aaee5c800efde23cc5e36b89255a948264380cbada949130434162886d5b7151c31ca643dd5eeed2bd57fac60a5aa95ac83757e50a920fa4bb3010a052b9b6c1a6fe3e348a9a07017bcee164956c811f3479a347b0a10920676afeacde5fb32c08812883ffd65d4dba534bc8c70e02364342f67377b6ba591a375fd90313217430317a12eb0710bb589eb8e6dc4fbdc68045f5b474e9baa3f1a1818bc71a3c2038c843375c6ca6058e62c892a0cfa3a3262f3bd2eb055fe6812ada2b6745783095f91ae812550e9a8652900d50f2cca82c8dee0d897e3b80e06fae94638e284a3786f4f409a00ad3a936195798c3449728d55bde1074e6f3c85e0ca48a08af0379d596169fbab3edc71997e8526a4c1a16f0cd1d0e29e06b0f30c0c75aec0505ae32e5701d0e7e881a785c81e5064969d298e6340779ef6c451ccd1360dcbcdd67d28f4a448b59dde8aa63ef635b1761fe00d997f3a002da346752c0def1dec2fd69b4b006a7398959ae638c365afbb7c4b059b317b5b03d7db9db62e89979d1571596fb686def4036fa74c7f91e52b40f22bfa85270dc47d6bcbd3a5218f8ace1b0503c0bd3f1f8aee243ddc490587a77796d56d96e839d420d585e35910fe01a2820490aa251ce74f2208e762680b8679637759032ac9375d79f5d8ecde582d4304351092a8c66a101423d820644758ea60c408756132c5921f90d6dc7515211e64d92c9a766876c7da359e1577a967a12e1b0ba412430e8c6aa796d87ff0771eecb3248fd0354312331088044fdc418ad1e35583918f11e7225776ae8b5de58b356a759f315bb826da66f06760c260a80401841bb0fe416931c935bc1028ada903b00ccd1d2f1b091cea9bb3fbebeade3b4b949a6db3bf27e8b678a20b5d8b00d54846e60042eacd35c04893a163273240ac53038cd068a94d78a650576aa8f1ab545be26e88420051a94347163f5e047bd5cf521495b9b9829dc8dac03465c80c4105da000aace96543e134efaf5a0ba7bd6b26c3ab2446570105904faa204cc3a4a140f31fc93f27807d25559f4b3662c5877b4792961480456968dee6c6409bd4cdfb2f064099341ba8371956b39541a362454326ac1c11c4e7ef056e27c21d82b152c8b6052c3a3d57861e6c4aec6604aaff70844f3bae61935aa1563732c4359c950ebcad5a5d1381d5d6e7bf864dae18e1bee93e6cc3d09f2d890fbbba2d0011e3907d1f984d7d28816a166cda8da626846be680ca8da9fbfc8f7d1dae295ba331b6186ccd5f1bb690db4575c11f8af9593a694d3ed5c2a2188cd13c7b88626230ae5f96c84bcce9cb9e7549fce7bffff8e1e3f73f7db87f29aea06fe1ea57f733ba4f182a73ef0e6e72b7a3ba0652680c46d1232272d8e8b2730da12ac0f3d10a861c2e03face40f902fad9ad4bb6a95bc4ad9136c878ebcd3593c47427057aaa842e2c9573afa403d490c2eadab9d84c13d0b9d9680a6c27f579884a83a9251db649303cf344ee9a72f709c5e7193f6066a6d26b1cd0c24eddf40a3fca4d9c39017434b1ba5130bc58ca01a64cdb6663aaa6a1e624bb94bb72aebe358d58e68d8d7139d180cd2e271a087c5f73fd1a795bb3e5e12fe037ca5368f61b96b243e9b7ff6599a9bb4eaed4515180fee34eadf37ee93e3357ea92b8a1d0d850ad01531e9b5569a8dde8206e6d5bb24fba00a5a9a8c62e154d34fb121fed0fefbc3f7b24eb889cb2759061b7a4eff591cf527b127e8994cf7cdcce3f53f0f874a45c1865e787ac0fb757b7b4e92a516980b15209ac032d166e3aec12849e8b6d4034c4aebcc073594a7c8f65b9ad452d0ea7663e8d36f3231b3c38856fe4fe4e43285b007e1adbcdfdf6835b7695b748a3ea41c4e64f20eac26d4039ac1b89656d2550004a030d7049c1c8caa5ba99ec366180762dffee794a3efd9a7902d1a317e46935f77d14df321bf13361ed0b4977ebb9769fef7f7cfbe185c8547ffb7229602014d13b37c0a3d407f838c9c6cec68dca958d0d7e06096255acf58c12149256104ef6c390096ee3e1aeb996f8dd2bf05eb25af0e15d75432552c10d2f0e84210487f2d226d9c60db2985089e53f06aa909f7f5944d0ebeb62825d6ba272bf7b6d62a22816433e3f6c128495a99a4f7abd67014c6a02d0bc5e4b870bc854ddd197582063281109d6950829516bd7627e159fa3014bd12a160435d27a0a20a30b5c8c8194c7e379fbd1dddd6b8d4addb07ba57e3293b877d17d60bbfd164fed5bd6cccd58dff4569031e2bbb6ef965df378f86c0f77a3c3b21a761e20c324b8e4b3a5c865c35cd61f33d952fcf898c4968eb85b8f51acc78cb9cb5273bf5b9598fbddaab4fcf8ffdc7eb87ffffad2d210b205732f1f1106ce1266f357d9b4e798c76c6e476f6be081f7b1c4d58059c215fe234dddb9a7a9a18966a539b7990a07371ffcfa9663b639fbbc92d2114318a0fecf7eb5140120d4d7571af540d02a30c4c06a96acbb0708bac5d8de692569db49f06b90b00330066c8d03a3742b994f29eef9a64e7d64c48786cfa0559210124d00eded2e479e2ecdee4cd4bacf085ab9ef72db694e4bf1b940a733620a24b28761c8de8663e54041c58c1fbd0709a45f6fcb60cf14604216926c9059eb7e401d54105172af8a2a67e560f76100298f0e12959a5199a0c86e5677e12a55014a73c766742c2306070bc266361a9c15003136369dc9dc3607e64b2b0841fa000db4126ec8cfb348d09b3d334c8ec0a13ff4eea211ac9a8835d948cdb5f5b2b65fa8f235fada6dc743b35d88e20102d0f68ac8af7fca5b6f73ad69f95a987f872535b7e6f7c0a31f83441eeedcf8280cfbdeade75f2dd12c2054e413d82c224dca3eaf56b05bb91f6a4ff06acfb2cf6f4ef8b64f6f79c56d83a362bd98c3121a004e58c50d7fb8c35049e5e29d7ec3cbb5b27eafcb2a6ed15aeb8a6ed9b9a2eef6b7df6f76efb77f7dfff98534deb7acad18aac07d8abc910a1382bd6bddf9d22533d4879d08e921b781984acb089d2311b4528d42671192873b112cac8b6e7dd885e2cb60b007833c33fcc7b991d9105fc07842e2000f3fbed93663f23294e19365788960ba8f5f10f2175863ae1036ec43dd67ac694027111f5830a8cd9f843421d2e75fd0903cd3f4c7a951f86e95ce1ccb2f1315f85249d034b2ad0cbc2bb13b0868014eccb61049b9dde9723dddde573c5cab4128e5962aeac84723542f28d26d811b003ca98c10dfc8a8e2c6963b13373e0ab6c4084402790c1a2e5bf55b62384e579152a96e918d9c50b5ef622e5132cf8dda21f742d5bb5ac082e59343e68a8e0658eac33b43bd7b609f63f9205b0b78fae86d04446f64b4ad98fb5ae4536e400146282d4b3be02efe18c86de76c80ecb5a5321eb6112e91a527a58eb598c44779aad40ead93e119a67bcf900920c52f12077858586c28c3f723ca023680039486bf2bd869dd7e679fc660002dad2185e6d21a2007739b30d5128000c7179143676a5bc1ca83779c41aa70814afd90f194a2c0c531c04960c16019384c7a68e378448df60ea8823880fa0d9b6e011a3752157f475dc61dc2b81735d2b96259534ae7fbd7f5d2bfdedfbe368de42edb26e07cd202f4ebcef1929bfc15bea63e42093de207dda86c9ac5c936918ee4977db893e632a645c9a76b607756a4d9c35f070c76d1c02ee21b1db6e501906290c90117a2ba3ad0e943463472de2da02d900ab86cf9a50e59dd75d340d3d43c0a92df713b09b40f466e5f2676cd3a3344abf844456dc9eff8b9873c34a6ba9d1884584fa91652e346a01038a25245c3601c220b5f02647ba921e01b29e5173d682ac7e7d4e373d687bb894c59d74c1528793e674c3f5a66922284a53fbe016640813a70658695518e49441ab58d4c1f55135e7ba9411629e1e3901db832cdd37bd667dff3f12dfbf95bce467d9beba2bd6a9ee849682dcc7abe799fabab9a01467658d7dbecc35df200d8463072ba797cd32b180725c92267c461773712d7c460d3267e82efcc6195a4afa1a7efc33839c5f2e4ac78bb60a9fab75c2806cc17976bd051f377bb1e1eef77bbdc33baee5fef6f2f68b97fbdbf5dd76faf4eb9d9a4daaa9b3e7de8467c42ef63f9336c21e19335e44e82cf7f46b31e6da23293910eb78ba81812640bebad7781f5b47c2d4e01d50123a936093389b19e5ab8c2582a587e2d0d0693fae560a7a85597f86a6138b9a576329da8889b03363b0c28a94713caeacf44e72f57019e1953cc19391be606551d48c5669130aab41effacbe732ca695014ec99b0fe6951b98f1a70de236c3c86a0d66964c0b43ab0444531d9b5a1a3296eb04951f6a31bc933ac7b64e6fe64376439923b6ac338caf361707d300a89d6552e106bb57a107a78d0c2e11e4c68c6ac89a9e75f9eb3959bf20e8ab527effd7d7b7de0584c0a254af55dc73ac37cd2e25e48aad26e45eb1940bd0d67c31af982b5f03d30a37df045095d582a991147ddaddc8aeeedb9646b2ad5115377c2642f2480b328241f5e11d2b0c06297b830ddda96ddd56ad28108cdabfd8186437c151109e2570c64822ba02337e90e12ac0d6d965ee979740bd53d745e0feaf6b32f0d3fdee857c4b9bbf3d026b585f59efc3fb273df75422be48ccbecb3c257dfb7580a73636cc9c603002cc576abbf75f7cdfd9bfbcfc96c5c6773a6a8a3de3e1ddc082d1b620cbca8d13ac5576ffbcef821f52fcb06c9e76e7e5e0dcdd515649dcdb1522b6c2513cb7a08a95acb26319dbf81d2c5bb1941114db998b6de3fee5e975ef9f3c4f7ae6792e8b1e646955f8b06745fc3eedfff2fef3bb0f1f7fba7f6df3ad4525dd9574d947addcb2346433824f0350232e0c728835c03362b9b355a527fc0de7940d37dcdb918eee9cb8015c0d60ce6b17a086404ab18ecbc017e06d795e20867ac6707aec9cb53e7ddc7ba95fffe587f72f839cf52d15935da84df73084cad4eb5a402e673ec5db788b406a4fcb57a01a9819cd58a5bfb24a45169873718d028828733fa5f8dc5e224da0f95ffb2e6412393a5cebdb23b4135849aab8fed8e99c349b6d8fd70b082b577e7e8584eba5b8dcc33b9c8498e911f5734d767ea1c476b7dadabe4d2ac0521c643c36a391201d4e90f8c61d6f8ee2dfb8f9f3c2e23d7e51567ce72551f9f3fe556a80378b06b89632dea03ddfda7863e34d59fe63961b2be5f6fc576c5f59b32f7e5d86fc932b2cf7f8b7776e45d63732db2db737dce2e219db0b87d1da0efef270443058fc94953d32caf9af6f42353473377e65c7d3abbfc17690297dfdfbbf3d2b17debd17e5c2775e928b572813ff1b678567dbf862fbaeb5ed0b956a7c93e18fe4c41d16d0f85a3a960fab529b6f75b1610a1c0064f3237dc1a7b1dbb39dae8dc1ebd5e6b54e642a63b6bc8dd92e8e3952ee9cff7864dc91f1c5af98539f1e7b5c1e02bbf91ef1f4663bae42b5e1cfd4ec4a8bbdc04d81e287fc235749ae944d205c9d912bfa8c6df6693d49f7d36a76eea74f3ffefbed7eff3f6e5fa848fb1b3c031b8b9fa5db6ce13c093078dd46ad590136d2c93606c056c45575681aee8bb94ca4716db0ad8cc6361348496af6ab8c422d73404819d587bb6cad279d4cb6b5f0c25051c26e1963fd55b1088b158dd4c852736b9bddc7c0f146f3ba24054a3481bca326bfc6804f698019f61bbd33922443c9ae450a59aaa56c19efc3fec46203fee258b0696bf64fbb960ef817d93060e515dc4c80ba57e0b41caffa70a788ceb2287c5046ca89bff21286d654f65142c4a45b5c6bf9176b4dfef33ecb20d4579c7d5c3cf6f16a79d9ed4d8cefe57eb8dcf221b14cd87f8f0b5fc30deb83dafe74e1f6bb3ff1e972170ff6ef7cbadee91f6e89dff74f2fe71f72f1d8c7ab5de8beb37e91086fb7c76bbfe6cb2e17bbbc5475a68c5635d8e3ee354df6f96fb72f8461f54d4813856a121fb0fb8ca4cc5636323aa12a2e9243da20a46ca5e9f306928b419cc63493712cf7614db4ed972b6cb9c6a2322288ea5e883b8836491eeeb25faa3cde0dd7a9b144865b95dfe746177b111db1da81d8b3d2779f3fbd5010feb77b8f668daa628d4a37866c799f8b24aa2c78ba25823c7a4190051e620749b88fee993bd2085ba56a1b96b6d4f7d16cd99bb816625748ee8cce41ccc92a07807271ab1130c136ca4e8bade6b2f8f8ebd450dda79a55e2ff5dee936cee15b9178354b780a205113902a15a91f71355899cb9b4c89118334f9a9a2baa608d5acd5d28a26863ec17680f31aa739b3b95962a294020cb4c4a93b17e0e1530b38b4aa732b2a2a0ae474122cf3806242f48562873ab8d8665e9d45a8a07932850924aac013c357a1a6ef518d29e15c57380ff9f4ac2d7d626b09347b9aaadfcbae672ab53f7798e80e6356a03cb866679346af56d1d7e91f85c0af67a8b5c188b1c6e5b78e0ad8035ad900d6f4551ffa546ce8bf81de6cc8672cfb3ed87772e44ac4bc9727b3e23d39e6664d66fcec8fcfc697511e1f3a7b54584cf9ffef6f1c5023ddf6028fe2e115bd616a8152e283dc0f7e06f64957b5d966fe38765f3b43b2f076795873b1e6e2cf2504c9a8cec9996eb9206a528aac1d63d0a0e52a58edfa05f41115813b00105c8820834814a8353cf5662dd01d6e7f431ee5bf780e5c7b2b2ff06db740b46bf09c43da0e3f965dcaee587778ab2c6b28d372d4fdfe0fec99ba767defc19a10a395997acd87741bcfe2b8ad6dd4019d3365afb698bde3f274c4f85f0e1ce27e454befd3aa80849e24ece46913ca60dcecd00eb42153cb856b9075ab44ba6e5e9e79850f05e05f0fc929d419223ffbd50dd7003fbba4f98c8ab6840b0c005a5dc8f2541ac61b516893258ef43ce99649f261a56637c922cf49ce2fadb45f95a91ad9f3e7e7cbf7f412ad766e5b7474350e9ccadd2b43d700890c5f3ffb3f777cb8d1c3d9a387e2b79014a44e223bf0ebdfaef7f74c08ed858ef6822f64c43f7bcec7829b7d7b2b531bafa5fe04192a2ba49b9edb6fcf6ce4cd84d9658555955590012c8049e67f4eb5a0d88eee6ce42b5053c51593050dc2853b76ba52a914f7c3c740253c1a8f4c024a9ed91c126b00d3c45c0a6a3cc19f06f4965df27cd995ad90a0a881959ca86e26ab06ad7b9480a6abfd6583bad15b0f263242b2d10082135db92c7a43e530360813f18bb41ad640d85eca53dbd731787a76cdd19d1a8bb40926f536c712b0ff82badbf0efff2f1d77cfc2b1ffee2569eee51e23583a375fc0e8e56acfcff1747ebe71cadf51c59e3598ed6e8c2ffcc1cadf63b385a4f6cd2394b76b2fb9c41fbe55f3f7e83b08a287942da45a3e9ee363315d5c3b8e8dfdf8fa4d303a19ea28899bde354d75fe3018466cfe7a5e0c877d3b7cf548a669221881e9a612ec93837efef99eb8891c9aae561a4b52257a9b8be952ec8921a636635126eb9152ac5f005c08a42bd80358c8393a285e44e9d1bdca8ce7dee46133c1a540532d2a29a64eadcbac3df14b5ee4586bb757da4c8fe598da7d5b81ad5e6ea5b3a662edd4cc70dc7a30c8f38ea7ac8bc1ed21fde9fdd8d9a22418b155956436956f12b999b11ee3427ef3bf5025c87e1877834856a23b3ee83ac16d0370d69a0942992dcaf186d6b85a4202385053725280867030c33d52e9820c33939ce59ede5686f5d2baf6be13652dcc6b59950f5d7a113b76cb52599130f83edda9eee5d52888b8007b4332e36a6e5c9a42cf12a7aa7eec3963f2ad034aa00b1a689a4386e976723eb97d7bca1426735cf777cae73ff7477fffea737e294f81aff61803c612257e0ee305496c4183acc4378e9b29b2eb0dfbddc7d3c35b25ea48d3b00bb1dcab10229aeca6395733bc43ef9150072556ec6d91d2f0f5fc07215679cd9f1d9d189fd3e769f1d9c589eee855beaedce4ab2f57bb292e34f5b8b2df127ca78e7971d7a417296209c119db5e79cec3cfc8f5fefdf0854fa2b324db521d781db7366ee7326ee2330ecce24d39733d9f48f195cee2b55f7585bf574cf484e572b04a4dc3c82ec0bffdc54630333f7e5c5d47c2349eb3898f40587bb0180492730fb6c0b606b51a2912aea1947aa95e456fb81bd322ff6ca9509f6127c7cddb50d6a40c8c863c4ffbb3c6ec198ad3566ad7b3e0069dfcc76ddca21064302b94a6af6a8d51db771abc576638bea1e8814e82521518fd2091002009ceba9fb7954534731957b449afa246489d6d8ea4cfd96ab50c3d4c401504cddb543518f3ebd83459c7233db6db31d37d4c85d965e88e259e9c59e73d2fbf8fe5b74368211634ed226b104e48300beb6c02ed6f5e9e3569beb0f05e7874b5ba5567bc2e7467df028c3c71ca9758f1fe380ed494be9b4bd54565b1b65a1a623d853bee0d21bae6e981baac96d6c5f341edb874ba438671f8f95d6d39d1c7f3832fe383edcc903049ed1823502e144b184cf7cfa980199dc0f5f004d1e87bf00695e53d9c465ccfd751e8773d28b530395190894386bbf4e8eafed8b530ec7aebf0e97d9637ac0c398f8debebcc08b5b5cc0ceb5ee4f1f673d603ceccb0e3879ed6fd1f3006aaa9cd737ce400d5d0fbc7009991847f1b9aca98fefcf3928f8fd8c96be7f2380e9af5844196041d960cabc951b73ef796305c9d4bb3ec93d7b1677ed1bc83b5ab9619ba41b414e76d9b14e7708dbe1f87d3e1e583613f8ec4fef3095b0838bbd67592512db984905fb2df840fc2fdde0d8a77b8edaca9df4496d9f1990455896650fcb3326a0404deff71f47e34429c1adcb71ad8cad9bdadb462b6a4fadd1f4d8555156d9a866e2ecaefec509d37f7a7f0e2bf79fde9f81cafda7f73ffef0fee7fdfb87b749a1037ec41fe4d3354bdcdb1693da250de0e44cff1ee521afed8c3ff3c0b03a73fcb03663c77dc9cdae3128329c3cee310b22b53dc4cf7ea1e77ff9f0633efc910f7fb05d9c3f7ceec7b33d7fd879e605ec3e3e7c7b5cc6a3115399d76eed3869e0e04f5b0885a550a98fd274cd001a96933a4045983448081611eb5e0cd32483aa6e1b35b0a47b4c9d813b208c242412de9bf80ec0e46f3fa5783de523ddbbe7276ea2871fa81d20547efd1a785448aa91c381e970e06b2d8257332e0d3407f88846a3ae061919757e97789c148fc365515796b11e39a022811081a7bfe529d7fe22862599464333302d0f1dfcf4ce8d95804d1d3c9dc7c593d3d593cf974f4ed74f4e165080ef51fe9cb62e09bacbeb3919f7dfcf88f7877ffbe6909d5552cce41e17e6a207928afbbab72ae546052eefbd7bc2f1f3f332c9c9d2088e95311e63a678fa6f65974d40372451a6cf2558ba6a6c794c88aa7480431e03846c8076cc6d04ba94662e9ada205de4fe3d37063241ec8a0d54b7973cc217f16f94a821430c50aaa86e2fe431e90db0460e4b74278b384712c79771998df3715930d4f5e0f87a5efb06f0477363bd0d24020f82fdb899110f3faccd888eb73c8323dfa8f9380af0b134ca0e78633e2ca2a9f8738b327f18ee56a9c3b837e28caa98cfa3a287bcb67f23ecfef06f6725f9c3bf5d10e4b71923bf62aa460ce980d388b74c1370c8514d8d055db3ec2eceb5fb2496401197a4797c390ff9413b70ffee15254bb2f5c8ba62167d06c6b5e277d27d06219d6e7d773e5687fb71be3b2b78ecc45fc70c92342d2b6110f24ac8eca81985d7051e5275bf798bddba76273fce77a719e94d1e8563227ce6aac4d72c6e63a3a27ce4502e2c1e7a7bee815fa38c7c524fee214e0f7905f4b1fb58082fd436206ad1bacdeb6901e393d71ab9263c0a7048e269d3da8b112e81e4df3b0479922297952ac0e2ceda98e11e5d0d26b9e8c340f99e6e52627d24e8cf0b8d5c3128367fa533a8310dfa7ac97a0d03312b9878c55eb35e8f79b61bb311a68e5bc932c6ce6fc6b6420dd5edb6e056b0017466f85a354b473e8f7f706cd980d2c7dc839b0764a5f595f0c5c8c3719b372367c1f7c696d538d1df27966bb1e56dbae3e76f8240c8267e13c038bbf14e3adfed13054bb722b6e34abaa79e49a8931c9ed4772ff68eb3464c3acafedcd906ca027156888a051a4c6e64989602420a363c7207a9b4f7911d700cb085ccdbc0788ce43803d5dcb8516d3e62cc68781bc24c2387e536185ca3b1cb98aa09fc05e4f721110bcdf8f77aaf7ec1b0fad8c2a54baaaea741a6d4301fc71739ed60df2e58c3736eebfeeee1e17af7fefdcfdf9c516c48d536d5b02eb03706fe69b7490c84da2cbc927c1980f43a28f807e6d65c2cb5a68614f1e27d8ef197abd0d878c0a909d39b40f40a6489408241625543e9b14d605d78582a64203a9e989754c92ef098496c1bf00f736b54af6db8bef3c4009704b044008a4fca9364e3816e3261e2b8ed3c17d0b4cb62cda660c60441822cfa4ae471fb38e06fdea26cb9eeb9b991037a0c64863aa07f5c540be2544dc74ee3403d439109a07df5f9e21bee80b230d91a19d2d347c26c2b927551f50cd19c6ef33532785db0876ba5000da712cad50480fa5bb684bb47c2c7a8ab032c3623dd14771aebad994937b5b464564fdf65744a1a3104c57a1bee1f203769f54ae4dc074fa8916e9aba0d32b32d307853cb2d2e8a55a7a77702abe67de7430dcc99a13ec0e3f1e67739a1b82e4cecafb217ea4ff70393027bfc94fd271c86fc4e9c9afcd40578e2ed5dd4ce67753ba7a3cf7b2f68eabbbb9f7ff9f0e387b7c24dff4ae6bc5241d8715d5102a30dd92665443ea275f4e18d2a8d6b0dde35cceac771d383463f1b452dd2999add5ab3803015a132e188c23d5ceb302992388e790669ecc4ca31ffe039b9a34403f9706efcef4ddfc6953627b7fff4ce4c836d640f0b3d6e405767fb28c1da69af542f42e27ff29e2ebde6e7235e7fd5fff59edfec3d7fc10bfc8db777e1d5fdcbeec3c3dfdffffbb7f6ea6cb8df78a3720d6646159048db240c2483eade83e4daa8824657f9f0517dcc8271f4ad9d74ddfa30ec7703a7d7f7c000faee7dadee1e7a33d7956d5d21d99c81a81c77e141a67b51cdf659639a362beba6f9983fdb4efb6bf3a2279d7ce90daddd17ded0fb37aa34fe9aa274f87ba390f64d15f0fecc410dc0a013a07d1d18cc339b21214b01ec1405a2916aae3e964d78c2cc3e4cb13b2baa7b801e7a5c550004a5c8999ac10c83e4b1c89f120ce2b6af0b8898c7d68f73d71d0cdc031ee8c4b26a140db08098d3bd5d9d5b64e4e7a0c2f060b0f6a4002af77b0370de4c15f95e91da051c62f78683364df63a90f1589586c4e4833fc000d057dcafb5e0458f4d35b7d325770db6d02258171a1e1e53b71d527606d26f4687776779142aa831e8b18834dafa433972ffea04e31ab58a4b3116955adc5b0e5cfe6d741f1f986110f8193253155c4e23668b5aae51362523838b5983c5947a109aba0ba3738bfe454f73c7bb44dabef771bc16bc907c78211eabe84023c05bac71508e7717af3ac7ab1625910c245e0377100897201809fc5941ebe3b2d35d1f0b885399b36972e1daa0f40432f95d33d04cacaf7228c59d9506c01aa55e97644031728fb146b50a036e13052b9d58b6ad041a2cb3379a01fe846c141068b970ec9143a9839aee82ac163981f8e15a81fe9bc088d192c226f9654c94da38bd0ea4705d3fd702fa086cbb2f3a80ec4852b72557ef666a58fc37cd1c332615060af3ce6392c9d677404c27024273374f385746cd896fdfa0fdeb81b4580b7c5a9db80fdf6a8d981f813f07ac07160f4083cf48962a76a158590deeb8018a980eb462524d6d020dda77efb306e837893c0507b85f40a274aba2e8c66f6382ab0c9348beb9cbd13d00cdeb51b0c5316b8127c97892681c7528b215a47c22dbd11ac092717b7e2ff570ab338a96aa91a97be416a0ceb8557dc423bf6acbdf5ff486df9ff5843ffeebfbeffeede70fdbb7819ffc33ca02a8e8a132c0378fc501c122f5597dc0fa79950818c8d40e5502dc008145f5b1050c740d2bab30dd82b811bc7703b371c1f8d4ef18b062697dad842b775c33cd8e484638b293fdd00a88c77a28a267f548998607a9d42a0da422f4a4b0494a0dc5cb7de68ec51f25d833b1c49346732305d3c67e270c30abe0686b34777ee1ed70d35f704dffd1620b4fe9cea26d4b52b0c9b94d6ad4a27474a24a77445513cde15a69a056cb60bac26c0d0dc8a0ee11038bffbdcd60d723f1e3c41b94994198edf771c735523c0edfd1075221d8580406c1d6a45aefa453af9802eab51d50c7159c6242a8d62a8074006ca5f8d88da9a4818956b5bb3e9053b9bee2fc81e59c4a326fb575aa4897aa1ebace85917cfcd8617419988930e4686330a88b2a0c39ef77d5a8559476fad77af56bff6306cf404c9a21b5999136843aa1111310fb604494426da2b1a6697d45669c8a0f295c68ea8e860f6016cb0b70116028610a2af5be774191d4bd7360a4399089a62601bd01d3501ab60f40760621420c4ea0962b98f22a1a5b280e79ad7b301c6fb37b40c1c9ea32d43090ce968daaedc1cd890f284900ecfbd792fde39137ec4eeb3687b0c6555e5ef4311b68b950c868342ce0e931a2e2b062fefc1609f95bf55f5dda5d7f45d324361f056c3f96656586f2e4a3f2e4a3f2f8d64eec13edc947ed5937244cfd5a2b2a4fa326c25c0722a5a848320311bd9471e3a3e6cbc74bc7c74393978df6d1029f35dcc7bd978cf7fd7bdffb364ef83766be072c8e7ac4b9cd4a33a1f41576b36308e52530323258ae148b150d3922410cdc3963791dd48ce0a1f593dce9ee984f1f6ecf3b0c600bb6c82016cd3292519ba83aa8d87cccd249c796414d2a6e58bb3b3fda48a2b61f9e80d4dc72436e12a2098b4dec7f0c5e802dc27ad46044729d1ad236417712410896f46775377d6072d51d8c8198052c9acc288945cdaf10a8151833bc0d7433bdee338d4c5dee90ed3503cab3cf63fef058d4a0dd90af85a9dc8e2ab1d650922e58739dfe480c97dae07362024041e25562414d827f71ee81701ab8a8d75240b530c0e127dc921fcfd8721f9a1f03e0c0df650615253738e2a0fe74cfde036c79463a38495e38c96088f455dd487363287b70462e5e5dc02b005442626b44814aa464f80bc55bdd1e8f4a9f1f95471a77834a19293ea3f382c897d47679804844a820658e0a5e114a5b84048b6853d2a4563f6ba66478fad3afe30663067ddb56bcf14a2af9c09e5b5de681ae4c75ec4076019f1a006aee49042ca6073fb3f925c5e39cd2eeb851618879e17eb868a5ea26d53d555e4aa2f38ec1b11a9f71e0c0cee55018551f73aa8ffa0d1cc131bcccbd6bf048d53df3b9c84d19c4c13360f2b48439e6f610cc98022ad258ac6b1e3dfa1038630884a7a17d25a5b8dea06404c5126dde69894287f88af174c02233b8561a556d87af25e7a80253a1399ede19f724dd3c7871d571c98b107058ae50d6ea2f2c4cc244a43bfb1d28488388745d13f8524df60c4e4b71f5d98abf31050933461699698687c9750f9e68c42cd76605696f207a31b78382ba350b3a132421b49e5d6d3830086908c86f6df37cffaf8f2e6b88b838beacfd974698870fff2982035820f7860b8982f0d72dc200e2b8fb0f7d098f6fee3229bb6b04f080816107c3004620b723fbb00a15d34eaf599ee7c334294e05a3506c45c694163b8b5cb9f3610da9fea5c5d470cb1102db22f6a92b651bd9bb7828b38c1982e1a3095c6af78818266bbf184ffdd3ef3a0161226ee5e4d16e6aa1c1d78650557a272cc72769206a3fc82d48bb254cbe64d0fb9512dfbc90da24888f18ecc7aedf43f6b91698096493f9f0cdc115642849f5c03a1c300fa8181cd5958cb7e02717b73580a6c0043ab6d015b7c2ed5c99aabafb9e11921450a9b03b086e5c518c1954d1ba820fdf120fd37acb089e3a4c9377e4d33b2b23691d641acc4d6e7c1ba6fb70ebf330804c374cfe71b97b77989e6a2fa42b3f4b570ee9f2408ae3f34e1af5065253ff3a845cfe00ddbd66c0d982f102732feeb5f8c85abbbb0cee42918d5d5e83e4eb1765d0b2fbe79961107e8b4bf22398cbb73e1a49f720060bbdee74157f64d3bd4ef838d5dd0d10f0faf8a0983c75f3e6c39fbf96ba9740506934e65d07447b7c2e2c514c36f9edbb97e16337503f1b4647040711ca4edd63ced045bdde59b223307b9b49c8da0e35f220f53a04cb3cfc86ccedc0d81b41a9ac6f11cc774e60b4f77dcf47ed5c0fb7e24f5a9225f667b2648f98ba019da95fdf52d07661a5875adba33b31d4f24513f0e87ed8eb46fee1c3e500e2e1c3a5f0e1bffffaf3c79fde8643f41f0d09015383a446e07c78bc6076a8556a4686b41e00df29241eb3c5f0a4dd44ee23fb85a08840ebc1b70796a055406e7afc501ff3a0eef28ef4804a2ebc9ac71eb95d13d439984e892475454dbc46957c3be27c45ded501ebcb7db9b45a4bd1daa1b1d556425b29da52d9b623fc5aae0b1b0c2d3de2a4825c8b1797c0c7ce9dfb7eb634cda8067c3a682f39027f0f6605be225205ea1637e15d121951f1dda93dca62b17bc1aec99f93683e1c36f2b8118361843176055a293f869e44e2d076d51a1810d2906a14f919e386a7bd20bf581572b73c27aaeb052d0e2431f4051a5762ce96b7f17ed7e317d0fa4924e015b02a09cae42abcb94e6d1fa92dea4623235d33d28a9012467d0f6215ff38be2d7f8735de64baf4326ea4fa208cde3fc3587aa6f31eb38056148982920dc282e9708f9590e5d19107893b189930939449af7db4d2545b70245ba5a3cff9f48e9126c23ec26f3f974301cb553d2f89e9590cd3410cf1115c01d090b434248586a483862468c8eaa3dfd49048edd6d2c81e7dcc3e5319090d976da83cbcf40edc2cad8b220bee116a247be002e5412d5030238c06d21eaee00eff161ae2960269a538442772e5bd43fab607560b9404e2228aeacbba5326d942b0e000594034ccd0a2b907fb9b76e21d7b743b0295a241b22c401727d99e017cd4010568d835806f144b19be7163a07c13b258519e4a234d50033543e2b3d2e56aa8e721e1d258127b2f8c26dfda38a2482802409f806ec2fdb54ee330483ce46ea9895b05a01a54d971ef0b1a3c683cc11ce146489184a8a9d98e47250de12ff16b06b45f80d73e1c72c4c2d637bbe10adc29892ada501643f21dda7bba5790b1cdb605f1686e9d661e0d830b72ceaa5b39b7b8582e537fa5862c36e0fb94849d3b2ee3e91df71e2996760d0a6b90d027f3879ec8a7441a6f2b7ef476b83e801f03939ec58fb24933aef6f4ce4677b33be546bb50dfe20960cadc793ff4071e3899e643f7b051db2221b62009ae45f7e0d1ec01a9cd0b26b6e6664fef58ca8a1940971cddb77af36650bb5624f0491429e1f1c31fd0c38b19d49eaf9c250bbbef992d067ec9e8e44935cdb6454ae800dfdea00e24f6c3db7fe860bbeaf821bb386497877baee835ef946d77ff0044102c3e2277a4191ede90fbd18b21ca3bd6ad826b78a7910fefe9e91dde8156d90aeebbd34c03828a343dae230ec4e228c025b07e98fd6de75a4e2ef4aa1e5fd2e033bafb71ff6f6f874ecc7f587d2758977760f948c7c4e4633d4e0c0f67339e25885f5aaedea1724053b0e2c30962651fd0ec089b70be7ce3930bbcc0a053f160d607e90efac79918998e1339fbdd871ee16b9d01588cbabf48de16c44b136b708a420dfcf2e09ff8c137a4604262a04ac5071e1f15a25c96fd36466c2185b42032413182b4c0ff651f9f66023e580bf6ca86da7d1724e09062b23305e828c629b8287e926f3dddfbd09f5066f906cda74f9e663e3f0da023000af0975ef5921e2dc538a74a6bd7396dfae9d79fefdea84ef82b52d666739bb303738195b3ded2b194e9dcae2313f78b3d0f2f6386e057f82b0ffd7ee2c8340f4cc937a39c0d6746b9b171768f9f74019ee34884fcb20e6c945bef4b8da28a281bd945a5458e3ab9f86e6537ca739fbe60e0db353bd6923db7fe38caa1f5bc9acf2fda5fcd1f5b3fcbbad9c6399c90778bebe8dccd703b77333676e0cf011c50506784767e76fe09fde7f3f997f50a2a7256adb0e78c56fd7cf7c3af77ae4dd7776f83f1f235f51558b343b69d6cd490c4d9810d571194b58e8039b6ac519fa96c1878bc3807e965d5bce3746dea202c5a58a53af73630fd69e4212e176a3d00d6f22a31c61a0f83e3c18df6b582a05e1a66c25492f486995449c1a2c1c5f757e4104c641a2045cabd95ba1150aa9b0caa7acd819cac03b4f3953a234c54649b998d5dc51c34972888f67bc02c45f08f4acc286f06f21314505ed7b3908fd2a0d247d91d5817b13546ac85d6ee212cb23405abf10da9850393af5ca978e86fb690e30bb589690cd9c86cc0a737aa5b60184b740499c542e1eafdbd74cc800f8fdabcc73daa175452d59a57e767abeeae694542a1fa75275cf4aa69f89d54cce7297220b06457f699416a049efeba41843a90828309c85169229b8da7b8e7cc53e0f257ff2137db63d56920b3ce7ab4a5286cbaac4ba78a714ea34ef79fd3abf777bfbcfff97fedee7efcefffe7d7bb37f201ff389149ad24020fbacd3df74a01e68eccf48ab73aa8040aa3ced4a86816e8c15a354668c27bcc0f830e6a6c1bc41e6b96d290745589a76b9a421db86e74aacb98b079d48e957000380a16eed6b9d8d642dc1fc150db823db1b63c4950dedc503f79386a03625dee3405f72b33239308d5fe356afe2a3022db2640461b702e1ab9c0b458721d0020ed8009e06485fa7c7a6762c94ab941d17c80561fc8f91626d3a31d3941d301b77a71351ae8310e48d7a7a8d68b160bd8d8a778d9f932daf5a7e27456205f1ef2aa4c7e6b3010da90da27c5ade60688ad6eea0b6f5d2a8a0fc236b3fa9bcc5403a432728a64a3488760a6c65b1c97e21498fb78f7681ce76c04f08e1ee686eb6a91f932e7b510e00581f56a64cd9f07c178718128549149ee7739af5d307c0831c0195ab28ab36be0bb5bdd63fecc2d8dd0e43b152ac5232c7c2da4b64136b2cc47403aea3663e149c86032239d1e7366368379f50b64e375b13827111feeefb6dfdcfcd29f838a6e50de5d1ee763cdc73c76561ead80e1b97914fb98cf83a8ef060e432166fb6a98f52e514c62e3315bd9d938bd8717bf354b9ffff85507fa2314fb6af8f4fb2018bb307db0ae581e87df847bdadeb55676e781c41f2fcfb784789e956aec392bd13fbe55ede13f7ae5ad614a4c0626c41b56d492ac359740234b00c9c68a8e0521beb6585b0275b6e600d2b7bcaae25048b076815d9fa3ac1c1949015286491d3218a24062389e97fdbc40f8374c2b1e2f863d47d4f7ff276e16afc854b6b99598ca422db602530295c9d3cf5a30cc9840c1cc71f147ea34afb9e21114a439a524d516d8f1da1ea610a0ac130b6649aabb3f8c478b2cacd462121b854780dc4bb5e6a11e80ebe10eb0f98aaefc78a19833f69cd795fff6feeefefbfffbfeee8daa75cb1ff608cc636319e01f3cd00f827bb023731de182bf2a039a0df07b636e9a14b4157620ff29d786e50a807d5819a931be0683f6106933c93a280ffbd37d012d4e40812db42ff3ef8ea24f42b386255290b9c9b51a96a318f1961eb435fd6e5d0fc04e760f26b755175ff3c4ec3e9682b1260e5471b0faf94640d0e5b10db88c5471c08c05c8ce6428b96fb150c712d3734615093399bbfb4b917fe54d06560110d6b1f510281c4029e0800a42de634d7ea6217dcb62bed00277c0166e9d618650b2df02cab4b0753408ff90bb95df7db7a32419e5af3408f5d420c8d71b84a3765f300bc7fd978dc37fc8917494c4665f268728b7fbd3f546df4c6ffefcfb7d4bcd9969c6badf373694bae8bfa234e7f5e5e6fdddcf6f04ddf58f8ea62696508752dbb6784d582eea48fe4866911333f71d882c3309524716fb934820e26035a9a2fae290ac61492d3c43e05107dad08627aa924db7b1064ec8a93d2411d5d4f6288ecd017b8ac5fc1ac83b330baa2b245b27f9dd5e9dc452f9578b62fbbda278cfaa18f341f30996a378385b2bf73332a1f0fcb96d64c4a41792795b0036f57086181d8999526fa36578cf9666a4375420f5ed5da951309039d641dd75ea4907fa1b93a3784928d544d9785ef91133e0a6d0bfaf685028c3051d8a9de7b5e8fbfff3eb871f7ff95fefefde08f0e96b16fb4af03f79978165d45f654758816c07acaa62b21333f4788733d7422d53c75bfddeace59a4c107d18b2a8160d2f186e16ec209a4183607f09e6190ec0b9ea26f3e91d1760639442bc0d107a777f3be0e304dc446b3d77467a0ab2ae46f29b71635f481e2a76004148a86f710fb81bbf911cf050de843706229fa010f2fbc0c03283b5d7a32f01284756f53b0d507ae055993f0db2e020de16421ac07aaed58deab58c1aa55596b8310d0ffcc03e0cae63641a710c5f96645497414bdaa7cbad21ab14f59e96911c5217119d024b6f02d12e096afc918ce73784962c03244d22f9ade2dc34fdf12bfa00a6cb82dad2dd3b9d240fd37514d9423016be232a5d91a309cae581a7c2f33dbd93ea17e5d2b6507864dc4864c9216c688969ec2d084c353e2c88c52c055173a0f379048017e34373895578acadce7448b543866c5043fbd88ff4dc5910254cacd66b21dda0587bd81e205b010807b02c8e5cec8510c8218e6defd7827805305c301af45443662b3e360c71531dc1340cee8248f1826c44a9767fba178e7c48586d3787fe01b219974bef9576dcf4272b1ea5478270457241cf9346f6987e04d8c848e2e38904452f9b1b5d48a02bc7f4a0b037d207085073e5f53fb3efd8225125ec3a2d5f44dc31431d9362dd023692316da1788fed35549e97b6eb82e53b39e235f3f71fd189b8478a198f497d3f4ab6b145690d12e50cc30c23af6860ad179c967b5544edc8ddec811b870c4f8b4c153f7a9fa331f8b886e4e68e85a328714790dc342bd217e02583c3cc47b11904813cf6a3241b5b24ea514f8b3a100f0908d1d81d5adb828103b35aeb6cbfcb6c18230f5bbfcbf5f8b3bce03f3b7e0c597c55922f08f12f6f357affc31d61e442b54173af06687e54b62b53dbc64bf1182cbe5c520baa4e1312fbfd840480f0a8a8447ea50590a1ec91fb0d0aeb14876e39453ebb2694227b84b6410eadaa7b890a17b0117cc01ebceeb28a2db2fb78801f42b224264a91e6dea0220812e5803ba87f74fef32b3de5fa478236b0f2b88f3f697e619fa9d957f55994a9ac3e93439fc9570880eff0d78fca06e49cbcaa86bfbc329efc727124793b17fa2b727ac26dc5f2eb3fd46dadc0844329493eb690c3f94612f5c19bc7f90068a5706ec30377975c42763962807474da53f8fefe51019bbd603a25537f9002f802f74c4a2c9220df9985e03da1bca5c5939b5fe6d983f65696f8028c0bb918ee775e574c097101e0aff9480aceda34be0f4a67ece811960eaadb0e87cc62f4138aac8ef0a33f759bf5c46d86ea0f771b8119cd05c33124bd34b24cd33527617229b92b6c7e5b3db24735b154c0048121fd81bbfba7eeebc58f19b4e9dbcc1958390094c89a25627ffc8b2c0910c4fb05f5e99d9592b8caff2b33caff51e7bffb61eae4d47f11e9cf0342170c082e947fe12cde6b8ef82b2ef8fffaf8e3df7e7dff8d3ae24866d78ea109e16f8bd107dc26192407dc017b0f695878df3370f42536dc28141c917b989d1abe2c4221408a2b863c77726962d5eb00373cc91e9b46ea9d875d4103d7fcae5009e5811201d47a661900d0a479c870c5ca15d6e730e304f07fbcdda74bde19b22a1b70a413cf86208c93a860decbc7e31c456279469a41a50ab2d40e5ae4553004b26f8f061b2cec9f3ddd7756662d30d4319e7032ef4ad40bf92d2c82e7c8b82010b98c0c4e890903e7469e6111f1bc5954ae5d68bc5b5e8454a86349e283d31f8952be2424ea2b24eaa721d1d33d374d5abe282c1b2b2c1ba761d97308d82304d435d7f84a10f8aaae9f28ed25953f39e435cdff970f3ffefd5bd37bf761794422a23ee7212e6a48460d9e1dffcfeb874519d99f130cff217af6a6c1c25fa367d57da735140fe4a05b103308102963ab81209111a101b50c63ae8f8b046e9111633bca7cc5a30189c1b7ce98b2e2efa58cc4b327f14644fcd123d50593947025250b32cd87874292746ee3494a6e7642f7f9b03613fe4acd82ef337e589bb1c39f0e25e845fe830d2abf692e5cd35f35167ec06ba6e25b3313ffaf6af7c545b3bf46bbddd57d41aff307f322c3bfffea66300791dce1fe4fa68fafeae2793dfc1607eba3ce694f9fcc2e3ebc32bb78aab1005ac9763ec7f6e1a568a55744cb6572a42f1bb9648cc3c8a5cf23977dd9c8a5c33072a937723272853bfa72dcca622e4aa3d3f823c6424f5c811741a25c0a121fce47afdbe7e9f74fd3b75e93d557468dcbe3c5b726a37f5a22553b9fd6fdf05a16fc4b893d4e8c7c753b2334ef2f4cd9d33f79cae2825c9d95a99f6e3efefce1e9e38fbf7c7bf565517578a0ac6b275002072c81b6d0075a3fe506055ca56dd7399f9085ae2259ec3ca51bcdc7a17717e3cf7fd02b7aafcef65f9dfaa75ef1b22e9ea8d779ad3c39e0bc7e6e3efcf8fee1f6fdcfbf7cd8be918a4afd2a189079017ee05249bf9de76f3da9527f2e975f1cc1e72fb0cb2ec55f7b8557dedd8baebff0fa5e1cf3ca1bfce6d2d09675bd00aea0f27b3876fde8cf310dee4b6679d32bfcd6bb7bed9d9d7f576faa682a7f78c973b603a9d5c15c9564cd374b6af647ecd9ed2b06d47bbffc9563c45f7dc1771ea6a8fcd963c46ff6e95f3a0cfee5577c451d7fc38abe62407ffdf0cbddcfdf9af5ac05b0e73a37d603fdfc2eba2e107ead92b454363a98aca55aa9df6905ce063e0fb0ed15693b7d6eb415b01c94b6cfbdf9c9f8dc02d3b465205ac862bfe896ad048d2b03830cd5de7de4d633e0a3273016e46e08594df1b990870105e2a7f46dc644706da0cf42f26b502870453a3d7eef80c647e6009022ade62600581864769d794197800121590193721dc99a91d5ef79d454652069b4b66443a8ca96311f3800fd117c2d13eda1ed0e8e57ccfa04adcf007c0883d6d6143768fe64a0296807b060451d3cb8ae04cc2202fc5f01175a6de4319878cf7440fc21c535c8b0b467894c11ac66c9c6c00ac724bad7e6cde2157cfefae2cde125ee6189b37fcaa91c242a808e10373840a1963b506d0221394a11f1a71d709ab17d518fa00ae734083b3ed79d9befffcfaf773fbfd1fcf21f8febfcd45116e3b834f0783148c2567fc073c40ed7a5117b8396f416784db1eff0735a84a555b6eb24209daf26bd43ef33b3241b478f51fbc11d6190092d102a6e278850e0f588dd9ff89be7ce0e24bcd889df3ff53bb51f9c9ad8b910bd762ce3f1e0affe8e736fd9ecc27d5e929f250e670468ed39234177f7fffaebcf7f7bffcd19606b4800bbb171f7ac3ffedf6c3be3f6f2c73cb1d69cdc1b55b98bce5d1c1b0bc4ec2e96b7e2046cbb3c7df22b26a7b97dd200e0bbea20bf23b19d4ea32e5b35aa3dd8e21ad63ea65bb0011ae931aea1030096ad936a0521210231f84045a91a4cbc77104916df3f12c3e05e5be251a860adbc74bf6a3a5effe91d2651f9f93119bc5847915af8ec07d8b1dad2285f742cea84937e59c39744f0204fe784f0b0efac18debf950c7e0d9969901a4da569fb452b844f2023d7f800fd4d6c06574ad93fb32129e7c0821e34b715e7fb8fa42da31ece4faeb93135de6324a9f1b9f5b1d2c6fae486a128fe1069209f44d505271cfec8837add02b678f6d4a8c30b10cca9f71a07edcd1d8a84cf2d370cc5f83430f933cd013608fcac1520d6e058387d9c78f2747cfc97ec3ffbe881e8a34f1982b079e822dc3c8a54d80f546f0c30618a3ee9998a047fc6d37d96d1a8c7b2d5362b6a737a6ec1c9d1679e3450d033eb86a7ab89152320fa56d751015595c0eb6a06e436a0880d9afad02a950a3dabf10b76ee4507b166a9954a07e155cb4213e9bf19cc850cbeda49e62f0e9e1a3e5f518cfb4b5a717f41251ede86fbe5abdce2496ac08f937a5d8bb924ca0432984d017ad508ca541903c091319e4be67164b27e0031f60856ec4706ab51a52ad9805d573297c46597a56c73b0396606aec2c8d8796bbfd966ffdd6d9eb9cfef674b15e078a33c4a5933d51264e08267ef70b0d1293c49ea9d32cdd6d2fa8a8105787d3e5e8c3dd2272678638b5eb305cbea2c84948ee9fbfcf5ac19bb072e13a86a0c8663f38127b7426c9b5aa22e9669e8c58b82366cc42060dcb6b9025acdc7cbdc2c3e1f2c08912ce1cf141879f8ccd895702452400a70b2cfc79a0f2f03cc4fa2ca2f8c2421f4e795e4e10c8dc6cddd8f3fdc7cdcfff0e1c7bfa158f45b1b40a4a344b916aa5bf7fc168e4d47723bd554f65cc2be1ac91630958a8cf11999e92bf3c26325a0de078a7e6f51d63633bb9d4b9d3a5665b551f0c4441ad0b5d840b193252942034b9fdc05b4d52b1d488b5fb293a45181d8dc12ae16f7059e3a79ba97595207f11f732cf276bf1d81062148db98fa186245b6c1a0013e5ee4e81914d36ea4cb398688871748a67d906e5706a162c5ad0456b046c63b3680dfc3205e0f684fdfbae129db2c2e977571ace6e0226fa41b642debb04b7395b39d9d4fae8d466096bb3d43598c47c1d9f5af59d2deb72b2b9d30681e124a48b38dcbcbc39f8aed59817f79c8abb2ffcf0f3f7c7b92cf54da959b2cdd5723e9576e01ee06d579858f7255aef8aa51d3ab41bc2d575176547cb78fab2cbeb1f31e6d775aaeb4c429107010e06e83694fa230534654e854d22bd9679e572ee777ae09e32a3ed1821f5faf845af35f4dd667b4ee9ec215a660ae8652efeb73ed34aaec87d70071be1a34ae3a0dbde2760546aa2b6e3b6c6cdde7f7bbedee1b7692b5c5ed5644c8b61af4e0d4ae2a505b95af2a0a53fc47ae59e0681ad0fb31f15091d2e48a2efe28b3937dda99d93b33a333b351bbf2cecc83ecca3bd33776de97df9df4e595aaf823f2b692e895107a43c61553f76ed02cfb00baaddfc1fbbb8acfd51f6d90f5abc6dec9a657f1199d0c6226efc8e1ed0f599f6ba7f9c08c8e3c59f71961113ac83adb8d7b15da51f78d13a57b670bbeb9ddaa82885468cc2b75d3d569d42b65d7feca574d515ad0fcae26b52bb17ec5da695e9d4ae6ff7e575b75d95419282b396bdeaec2bc49bfb222774da9d9557c46b75bb90afb76e772d056d7faf8e8f64c260c9af75750a0169a57f0cd61d27cec962b7c44affa4baf64ed3b952b3dca65f53f8a1bb93b0678f1d5fa8a1e754b77e51eee84a9bb0a53f7ddf3fdf87f56cae36c77a73f623b0826fa9d3f961d8f5d46ee4a7bbf3bbd15689a5bb7fffddbd6ed9f1f7e78ddb6fdf3c30faf5ab66fcdacb9b8b847f38ab4fcd760f88707c3d765e5bca06c3e3cddfdfccd0d7f3acc83a01d4fb9550fdefbb89b95e61c697dadc925a3a14155dc74a373104b4fd548dbf8ee748a4b6ba76a96546ec4ae012e5cd722a160bba4da16cd53a1e9519947ae923c90f0ff772293e6e02d78f02c98906a059d63693d309911084f51d0161a83e161d4ef9e67bc3949656aa04ab51b96117ea4352496432cea4a187f3c821e07eab19dc01eb375b2d2eeacd39c35adafc305a84dd4a1d5ba673090a3a473307fe7617a0129b17f2d1277ef6a1e5475deda28af8959c8ca05298b9de785ecdd871f7ed8bfffff7ff8f15b9c28ed93a626e54e2c77da1172f558382ec1ac2f034b2c7363dc92747944d1e80cb8774c62b440eb9e48a0ae0183bfcf3a90546cd7aa0d18f80325ad023a511a51a92758eabf8bccd4a0e84fe5b6ae597c59ab367e45a49256c9b5bc106d29fec7a394f249232b298001e8cc706e62314141457fb8c9426da44a0c60efa40894fae2b08e6d7531bed5de3ebb406f7b3089b7c4f53bef354bf1b9b44e92da207bec4ad6d1b99ce2732d1115501e37d2b9576ce3f33b6649fe6f1de56177f517bc13ae9fecb451929557e5f654fc2e48efe921e765f87fdcfdf446c2fb352b4565501f0cc0da52fab58e460a50cf4eb57b483b121b96f7b0d906f5792bb5edf2b8ed93fac4a40d990284bec25f16966cc5db8d2fbd16779707f8b84c34c970e34edc2636fb7ce4debd4540ba5f4b072693b624d5dd3ccb642249dc49e3e9f7090c721b03adf1c4e1de9a6f5a7914c6fd8df2a5f7c76e6ec74856a2c582f97eb4580c934feaa3c6e27eb481520b9e988c9a53c13ed1b0d25a0a347930106b47ef3ec0cb3a0224ac735a1c51931f0faa62911447efd9cd6fe1c4ee1296fa4251fdb7d21572ccb3bb051121e906a6296a82195a1503d18398bb22a5b4bd2b6d1999d983ae3b9e4285391dbe0fb3555c0cab28dd8382b1750b8ffb54f69bb7d1b34eaa1d5fc2c3bfe6bc98257b94f80bfa827d1714e5fd9ba19d7f95a2b8a5051a4299920a1cc94eb3cc98f204a236ec258e40a7cdf2e9fce8c9098f40e1be05a6ecc91a6dacc2661b0ff9b0c61a2bb08f52c60e1c0b5d36d383d091fa20b3793d2055a9ba9f83e270568344c01c5a0b47422c793cd853632adc7368fa182e77eecba20c42a956de77a30e5e8e426ae2421f6b61c3dd669731980cd21228b70c24afd9479ed4c36d2983f70dcb64df4150a0fb47bf2bb1b630c756b64892706bac466da0d0a903e36e2a3cfba163af92591b9aea293e97f58ec4efb5a87cbeeb5f95d1f7e7b1cb8ffb2ec8e8c70f3ffef2fffbf87fbf398e86c934a4256b9de4d67d92d91064888b3e0d037b6fad03fcb500619c0c9030ae7aad958abf29abd4ab642aec0eaf904890b8c12a0cb7a48dc1dd392620bda50024ac4cb7ab090e0f5e238ba466a432731ff05a7b27756b583a55b5d469564c398cdaddf1b41e954a5593290d77320659b33dac1195223bee4c55dad6833f8ce16ea3664f83ea6c49947a012b8e80483a486f86429e6ca8cb7e07c3ba7214097445c33d899b4ce259c3695e9b0d00d9f0aa251e6830d56eb92364485d089427b323d967c23c9abb6685ba62fd10576af09898b80311a459f5c870cc28a7d3997ba1193c3d73dee2f56d8b1fc9609294c2c98c30f0e0fd2e244219eaa6083f6265b31efef0239edeb99bd3e5566c51991c63812849ce1e0b4cd9ae5d7ec117b1c209730a402d63479c7bc3dab68746cba186d9164dcad3bd8fb2715da6620da4fb065070ffff218bc7b8f1533a6ca7d8c6fff9f04b96d735f8a08a97b4f8b0ff154ddebcffb7375abbf88ab8028893ee1648dbb1bbef6adb1c3a0c7dcea1c2a1cf39547829f435b706959f131a0d38b78e7acc391af2199a6d438f4162bf9438543ab912439dd352e250e9b49438543a1d95183a9d961643a5d352e250e9144abc54da75595c9f1f0faa0cc6e4812952e830143a2f1d0e8dce4b8b3b96bd0f3a6c43f3d2e1a5d2195a0c85cecf6aecc106be439353c94b8943a5339438143a2f2d864ae7a5c4a1d2399438343a2f250e95ce4b8943a533947869f48d01bd119aecaa0ac58542e753852e076d3e55e253957f7a677020dacec6657d7565bea4b03b003d5c52d85b29e5a29178baf72d462d55b1963ed5cf874fb4fb75e5fe4d6d76757c4d9b7dff2bdafc3f3ffc6df7cda9b39f8a05e648ca536a02cbde6a3ab1d86b7b97e7a45179cb0d2bdb9d8a0dc444d6924dea6d09595ac3061ba12e5468c84c426cddddc112a9a0565348edb556f71f2d9978b83130babb4680fdbc8b7f8364dea2308fa4b7ec962173cbd0a0c6343b133760768e8949cfd2ea410f73e8e1354b81325be9d48622de56c42c33b687fba2ed162c638d61145c6d79eb410982b50617a315c07a8e71302339cc08f093c3cd70df775632d66c938a8e8369cacb3475eab303e57a1a146c18d89a86252b79993a35f773c2e9a9dd1da0b4fc2133629e20242b232bd5a1c983c999fd5981b51aa9daec260f06f8264670d1480dc6abf51e314d27af19b56252caab6afb4c6cf67bb5f6354bf1f4ae21baff8bc667a8e46b2a8d035ed1e97f7e1bdecbaff0b459ab2b7320853530c82dab7daad578dd8f076d861ee750eaa5c64ba94fddbfa5c67929f5d2e350ea537ff25a1b438bb90e3201171a867a0d5eb48455d20475ce31be2f8d5eaeadab710a8d5e6a9c0e4afdc241be06cacfd0a493c98a255585265b2949855d93c1c1c7b5409bf3d15fdf2e55ce50eb50e4bcd4fa858b7f3d954c382918e086aba0baafdc5b7820a1a4d2ece0a4486dfe4c705fc44f82af2eae2daec339f479e9705e1abd747869349438854243895328f48ba8e8160338c667ab4b894f6df5c1d3d620ec7e1b77fa848df0dce80cf4800095c2f0fc89f23ebcaabc9f68fe6feaf23f9f63da3cd9fb8a167f8313a0289e2fb1e6a63e24644c8b34e23ab3eb04960f9bec916ea5edda5c7a5ddea7bbe449a761fac2c7778d05ab1b6ee3ce0a95e2e30bbe62ce5bc57d3bd7ddaefbccd269fab8d4dba71389934a94620c0c35432466130128327cb089510f47581cbe661071b86ed8b594316979c8d6a332391da74652cc4a1d27a5524c4a49293b50c37df929863310ea7de9456c37bef8e8a7fb1c39d4bb3c1e67f36bcdf6743f46faad5f7e4b902f4f4ec6def382fc3f3f6edf06cae4eb92f569a45150d4313359b601c43992d8b2b1cbe376365ab38deaae272800141c1c38eaf2c96bae72943f7afed75e9fb5edf3c89dd82d21326c2eb5720d3e0c572ea4d07be08cb9f3f6d81a998f87c8036482878cc200499d69c46267025bc06271c03a3aa85124b6b4d27c6cd4c38c23607e86748bd94c20bfbd44777bcc4258ed038a6bb02ed4d4a966eda47b9bc0d4d76d0dcc0bdf217672c42dbbb3fbe933dbf333bf26ea2eaf17e4dc779d17f2efb71f1e1e3e7e7bdc1ec2ee511d8d93bc98510f72d028225ab60533c0a7d3c10f9f9c00fefad7eaa11e3e298292321ed72cfc3e73ef542be736a91b82fcd66339d7b2361a3cfcfdd50a3a1d164c1e888ce447e83a3ce188753c1c3c9111c7db7ecdc0a735211f53f0311fbf3d4cc0c774fc9a805fd3f131031fd3f17b8fb79a7d87a148d2fa8ac57b44a56d3c86a71833f18709f8988d8f09f8351dbfcf0c7c584cc40f49eb6b2502b80704335d2ef7ff6b927a10ba0bd27ad87d41627ffa06ed72e542b3947ac556497a917e65eeaa16bb32f51ed2c9df71519ab3967ef5bcb5b2038dc9b45bbd72afc243e5d2edce038fd9661b57cf5b9108379578581474ce2a93372c5467e972a55d89a58bde611d46aed6575ca81a0d76276390d81c63df3c7a5793abdaa94895f158ee6428890d9b57cf5b91fdc64cad17cda390b5aeb6e94a4dbbb42bb64eda0a73f843b5d7abe3865f98af7aa3ce43916ed979f4bd76e26a755cb154d269bddf0d5265d6abc3f721778e4a6d153cd0c6b6e1aa1e7c0cbdb2e91e6d89f5a2d9745c1d37e2a28289bdc2f54a0b156e6d5f1b956993afc0285387d43b2e6452cc5fcbda88eb4a212d8547a65a78a3eefe97deda5553bc8c8647ad72b5be560f336911ab1934ec53b73c69b4d2f50a21dff01b194d9a5cf9c0d5b58f2bf188a436bbb2e17ee9e87be0c8ea68f38a9b915f0ae6a7cbd5e17bf58c51372bedca3ba4b5bd4cd2d963aed4eae81642606c57c78df536ba0b42195748e861e1d7920ca1729794f5a78b63cbc3cdfbfd4f6f955bf815a0f73646e22937aaed11c0703a83b1565397dc257579c86e7d8534e3975b9646b6cf81b637afb98093a4379a69b6c4d3ffc4124f2179745508f8df46720d7e5d09d60204bd0c9209ad9d6c3fdcbd1841e79318350c03650484798520d3dd883261eaee46dbd806bce84bdcd01db767b8ae1388ae47df372ef82a8748533f01a5bd7765eec86fdcd4604c6ad7d51a4d77a5c0cae34e8b9b4b23dd5819d452b31bb0ac7b841393dc4132a52057c043cc3401a138c91250e331bdc1feeda3e02d6857dd078b5021a282844021af1f62e41f3b1eb605855d4915c0f81cc9778f32a802cbb8916c91583d82b129a61f8202c97bf6b5f1e920b81744feb0fb82d47f6be22e25d8180a5e4ea18619cc1c89ae3d1627802b68def1d8df230db641ea68ec7578077b50e04db5e0d782bce685353af7e1f406714223944606316143d52d283b78d3dc7f36b2db79a06e3fc18fcb2adf97d4078475b64737d1c0d5403aae0b2ec00b5d39b4ecb9e026d4dca14e8d6a1ac1de016e36ccff76d0743570bba0acb28592f91652833f07c8b9d58100b7037db55a38f10d93e0fb5cfbda7c7ad7ca48ed94bcfd04fdee91dd6ddf03400273d4de2791f80beceebcb8c6387a6dd14dacc2a0dc823bab8273017d0bac57f4fff1fda119203ffabbb3c599c1f182f13b0898d6fb8a3bc7a4dfb5364e2aae848aa9ef066b2449873d329fc5126265d09c738035549013c6eb07645fee20c6b3c03b0500b9f77ebca21caf081c20ebf52d3e11dfd27249145ed5d04baa79412777777f7f9b4ca3af1986d460be7779549adb8cf470d0e004102224082cd6b36c333171261f9108fc702d64198b95eabe7e05e82c52fafce5a04cde5f3274b022baa5ee6db0b7c1649964df27cddc9564db16abe7a2aeab8b4c2535681690169b5f0dbfef3d866280c46f2a26a094c656c07e6738d8635a14cc7948bb0f3daab0fe95665e2608345b9157614fefaa19d213e551bce105b57a823d19683a889165879920a4472b3aeff514ff1479f721cecfca9eb83dbdc3e2c082e9f96c008dabdd14370b7ebdeccedfd16c3cb7f9f0a2d1173782ba9b994e6fe7e9de149d3da86d1400c2c29dea3e2ba62d2a08f93a86c5dc01fa0b7b5038ea0c6302054c3500f9efc14d6271c446c60434f02e0f7f2f50bb1222a3abcbd324dbb0b8c11ed1df3b1ea4a8164f038c9a289e14a05413925e38cd9227e99e245344e4605b8ad209d6256fde02d80c2bd95e0126ed0e42c5a861ee8bc0ad894816732f0683b29fc116d9b7cc01843b50d0a16010a496ad5e26663a6af925c3e0fbce1a875ffffee16ef7add906f1e1a495adbf6c77a706162ff248e391a5ec5c2eb1a4e7bb73ecf2ff76812ed12cfdc15345fef0a97ffca263a40bfb5e6fefe93e9b953cfed855ab00da7201d1d8330ecd01c90443e1093ad711f4f6462bec4214d4595e277d026d73a6c529372fcbba4f8bb56fb9b7b32d1eaa872edd62949a4705392049d3c4ead463b31b3fe2fcb907d040c38f27b0818c60c49e61723e050efcf4f6b44698c153b6abec3dcd960f379467bbf868801af686b1deb52214a619eb5d1e167fdf50b490e2eb218b25b726ec1b5549f5fb3a8d7a753b868358c00fd15b2aafb4aae28dc6e748a351e3e49e1afb7b0e248f806889f6648c7c5863bfd0de0195b09cbb478f8c7a4d230e1958eac003bdd264e02ca5f83ad7e83cde26ea1cfc3ea183af34d91b9ac4d7b926b9c9b1cddebea84db1c088c2d7b93645daa14d3f086d2e7ce98b8d5a41a3f175b643c7b151908e7dc18d22310d806a17dab45a8e6d36fba236ab4038e3ebac70f251386b0cb6af0c601889ce8f5fd8756ef8faf9879bbb6f2e056aa192b8ca1f4b923c3c193425b3fbfe1333ea4d36ae0f3ce5f60439e98805e53ede398829967db64283f3606a723d98bc6f7512121c9394ee9dee5b633c36db9941e6d2745b7aa6c5974856cff8a99ffcbaace019d0aa8bef14afe7ec2bc59e736ff461f7cbdddb4c997dd5ea79a1d6dc0b14e232f79dd8345bd932296beea4d57d38350c695c80643458d75f3bf75007efd9a889fa6b1b93afb5776251d7995e2d6967b28637a8ee65cf0e5c51bfb277ba9bb843a7a3ed34bd958dcc461c3a76836219fbe432c24a1685061da9101d75381094425abfe82aac424b836faa92bd72ec3ea37792956bd580991b9504a93a347844f1522319a863daa16b36739098df55b9011c65fb92f6334707f68ef68daa4a24070995a2086ca2f92ec43359abe8925e9041601ef919a6052ac6c29286e1441b65f77997a4f5525797d42841f08bcc414d6d9fa3e7d3a1e7813fa0c7eb8815e2be508bac2379ea0b2ea45cc9bac4d34c2ab35d3cf68f0aa6088dda33cbf8ad2b3cbd93c6c8525429bbbc1efce4fc4357c44faf9b7ce8fa59f3803de7ccc32fd71fffefbf7efcf7ef3ffcf0cd4d68482b34924ca6d2b659c602719b969b64ad54dc178c6af5d2ae0732bb50f8d493bacf2589c9e5da85b78121674d3af8af58114983aa8b2de9f5825beb12a7fb4e1478560a58ac9b3a17fe9f302656b0c25e7a1657ca40f4318f783cfaaee0c6991b6b3147dc48be3b052cd489fa16e30dea716be2524f110d738521a995fadcb029805da56d91e630029a360703f8cc928ca9cf54d2c09ca13f257792892c1fd9cfe15a68e31a0e49437f544b3611e4bb0d9fc8df7d81cc8835eb6dc9584acb02ba1f9e1e5cb0f925908424af54f19dc8d559813cd9ff8a587e6b2269b3241f20e6b50d80f889cec0f2c35fcdfcd592c644ae0749d2c866aac08ce989edae0e17a0f88ce4ae5ea80ef04a01596f64f14eceea612216563d121d982071bb9567a70e762f1ae39a878f0149cb74b91553ea1a3cacf1ef819501cd87fbe38e95147eba670fa75c8279bcf43f26fc4b100925005531494fb3501f19eca46dfdc1b3d0c0d2cc140a08df6938442cfb3efbee85bb93a40faa7acd7e87e2bd5731351fe384dfae8df2e08a2b3df39c643529cf2cc535fac54d3672bbeb0ffe9bf2f79aec9d95bb7f7943588aafe304301b9743f78be177a0f67f79f8fd749fb5586e589dccea766a31f0b8704b20b01efff4ababeca48c7d1e8d8cf1ba9adeb9c355c129366b3d54eed398d92a59059e41015db509163478de21ad714406967f2f4ba8c0e99ec475e3a116b71d9b7b060d48eacdb288edf157c2cd20c85e7fc6edc5b1f970b7af3ad8ebfd9f179b7fb98434f1c3378763e2a76ab1484ffd9d48ce8f192b2867a19c5d9e2e4239dbc8a3dcf549b5f6b4be568a4fa1de7b6ac4ad6eac8907c0a39276fbcec6f210f1b5461f1152767b7ac355a98d793a38a1825c7171edb6f1b14e140b92dcea77e72e1fb0277ef3b8cb749c35d3e79536e9277088d23fc343c44ff9f8c7099a7f9e6dd102fe390d5e12ce1fce8ae50fe704f2fddddb81307d4d65a277fda3622ef5ee2534f16771f34230be51299ffcfa79dcbcb08d772ab7c19c521edd75fe3d17f93dd798e74fb8b571e6786ee50bef62975570df3cfd1abbfc1617b9285d2132e7242cf69c97b29f761f7f7cfff0ddfe9b9b33e2b6906c7dc8d4eaeef401e968f1e612cb6353ea2d88308d030529f6a4c3212b13e6946fa385de5269b72ac5638b586ee6e3f4bb872687639eeea520c19c3f4760ad6121a8b4471ff5c6385da4d4d8930e87f89dac073924eb7064ebf893e4f528198f8268a9c6ae7c3826e06455ae99852663badae31f0fbc59a350ff79c5fe534fe2c23cfe6d4cccb147ea1dfc779a312592a48cd892147ba9083083dc8bacd88add7fe89ad7b5748fe3d6cd2b0a96310983677c4dcc8f327b41d88ffb5f13f96f4dde8fafd6a82ed42f360f3eda7ab1365e1060b82446696413d9bbbc0df5de9f7cad46c5c35f659a45d388fa2af7d2d9021d4decb454e94545d2ad8ce7c2c217a548596c97c5b65919a9c925d749ad031064f49907d8429af48348954aa3cd341ab106e23e4ff1ef07df8e9fd3faf991fdcc6b4312242769c3db8458f8b5d03b604a6d710f27f5522faaa21eb1b47409fe4c6cdb0a5504db5c264deed91d97391233d39491b90ce2d1a34725a347bf3bed78d4fb683ba4cb1903bcc2df9bcd96a51efffdb608bf2abfe785f7e1fdb767a927ccc205eaa273061c962db5551617fb0eb67b51447c6eb50f091852c6d33d56a3cc3eb1a7680054127837d879b4a4f1ff59337eccd27a5ee2fd94b5e9c0e850ae9995d83d59f3b01fa0cd1a547f8102f8e566f0319241605c274c2fe7b0aa6e78c7c3b2b5cacbd68e5d26962df91f644a48e1afd4e5792ba1c25c317f3535990033d43f63dbbdb10bb043ab7ce218519c460e0f277142b2b1e3c1d4656b93869ba7597099e2c1606ce3f3566a0b332f877ed23930e90085be5c1310827e413d1ede9f37ec3ffff2df7efef8f7f76f83ccf35538814a3d75a5b1cf429685ea365bcbd633f3c815e0c96d461edfd82830f126cd7d80bf638516cb65e6ff022c1e52ed117bbdf6637be2492d0d942459f1cb31192ee7a2729d9100c9917529c8d0149a49418cb21700870a0f6ac8e9eb8435ef860dd0b3978d0d3fb6d2dc826cbe6a72c3973972a2493356825e79a187b773fea51ef65e78b1dfdc2b6d9824146ad7563a814ecb9d9796048cf8dd3bad37928dcbf96c54f79899cb5230558d64394319991dce367f8dde24184850fddd72f323d9f52c4fe42d779a7b9eea27cd49638bb7c978992bdd76264342781c96e3b0da487345d6ae66ae4658bd807b77191ff61242fa055874fff95fdf7f7babcfeee30ba65607084350e967606913629477471a381857a8ed736d3433a3e64e8bab52bf6985dade65bc267f7df5b2a25476a51be3464d48b1ee03c417797ab604f3c41254767d12d74cad34d6e6e864a9407cb81460650221ebe4848e13e6da8c13cea97c3fa8bc2e85df7111b23d4e1e8d648b4c5d646bc2402c2204cb647bcc5fb34cd26433cf0e329d58344b820b63cb3ba1ec517a592bc98d0dfee386c285e892dcf9be73b2b7ffb0fdf8d35b95997fc5828316203eefa4cb058726958050e1cca5000956ecf0efd63da17e2188e24be96166bf73921935b2480edb34e47a17b26bf727466a8d348003d5c7a28ac20e6e54f8baa2ca230b157399eec35d84a134c646e1d3ef3d866fe69ebe6b5825f9ce439229697dadc5b4e8a2a77b66c93cbc996beb832a624cd25465f8e5a576324b1558a1581837ef8559a9f2d3bdf0f43b95a607a5032b943c134621355a2c37577aa1665438778f3a1b75a04681de0bf8f0466d6ddf88954fba73447752d14704f6d1a9f5d0a97eaf878d9d4aa5695b1fd9470a5f3793f5d440cb28d3833d0facfdaefcb5541449944a13306fed9528e220f26755e5b0f38cae7cf8db6effe16fbbb752966a7f1859a524602a8fcd9c047e3671236535c767eb542c3e3787439feed95f1667b14285efb45175018bafb52616023388f70c3c60131a9a2b6083fdd39d2a125d9fb5d068a8ae6881f10da46ea4e6754d46b242182a001fe3889287df6aadd918f4975d498f5fc614a042664ff756e0e8732bd4f7b929093eb6ee1bd85c9f554931a75f416bc79285b46e7862d98d87521b7b771a7b4ff81a9b0aa684e483bb6d79ba980ae3ee718fd5b0fceeb181377879e5f7593cce09d6f3de7392f5f7b79ab4fe0ab89e5168466280e836833b8aa1a9d03835aa9a00c116e93849a831b5962a89f8999d867f85c54636bef6ec5e843298d28c44f702421437e0b363401eebd3db6fa8e91379ba77333033cf462c1b06ee6adf0a31d842242b312a396690aa89fb8ca5012e2740ff248fe1012f572a3dcf492ac053ee1bb7bd5295c4b619a93d5899f306c14c571307939537b86f8a9b02dddd70dd5825766d64e4ebf23cf2ac3dbd0bf8e735ff793eedb8edfc397bdd676bfed0f8bc768f4b070ab298b156d838d23e63fa1220f6d28317ab16b78a3cdc4ded6e41cda80aea4a66ac3076b9736bcb319b7accc589e72ca4732362801a937a1b3cf5e722f9874f49978780c00f6677e6460d54500c80a6be4801f16043e273ebea44d5d594c6a42699c978ef9d36739f20bef3f83c3eb72d35000a599ade1d60d6c3e6ce0ee5f7bf63e6d4bd81851d8d71bf62d0af3467904e5a49b39dacf09dae1a7e2f6dfdee87954f7186d3cb20ffb281f8fb857506ec3867167efae9e3b7e697d5c1c4028b0f216c3dc34ac2c1ef548172d792346a726dc3879a34861b58ab95069c21732362dbe0404a05cc60354914fd551ae3b6b63595da30469c4ea4f201f4e9640e331fc0a2688e6b19ee65611d742431064ba361bed47daa4a313b5012f0c82c20b02e0b54b30b73501dd0eb2c302c88667d4869d4050f88bc746e0f7dfa98373065cf2088ecf3d69afdaeabddca18a0e5bde4890629eff96c874bace953a8c816e44665ba3deed39d843a3de01dc3b7fb78c2e22510978e36ecc46f7e783667c7eab0c34d9ddcc76beb6f2ee567b5e2a79f3e9e538a875f3efefc36f9515f45336998e6a9ca5b1290a837f833ccc42e8683b4fba0876521ffd3dac87552f121c924b3cbb400ab06330d3530ac8c268340ac00187f46e67ca900c431a496e804e358e97bd7a786f1475adf0e6a60d36a05f8785a354faa9591e437fdd439ecda3dadd204f896ac15634c1f9ccc62aed1ac6c510c57aa0bd730b7fbca8c4d0e8188dd6b475e3bf0cfdc33f063a68fa8a8d39b2da6084a1bc9264d953dea052cc5d796835ab2c474ed3486ebc0169caebafe02c8e333f1f529dff4ad0e6ad2b1c8405251b9298a4a5a9dfaa235db9b473f92e2ebda037629e045666d411f522561fd24b927dbdcd389a4dbeee32e3c587f9ff8a92a3fdd6776cf8925f5417dd87e069d01086607b1c223b1a66097d57891e2fe152af45a9fa04694da486dde7295575695b8bdb6a203bc45deb74a5626dcf38eeef58bfb9d0041bc1ac79da4b83aeee4b2b242fbceaa2bf69c51d88fdbbfbffff7fff1ebb7873553501958b26b2b1bb53c9b777b9eed0192af29262163a121c522559aedfb9204cbc6dccad37d4943486e833afed0548aa6523495a3a93cdbad18426bd776f31335eb1c547dd3b23fcbe5b9fd633f9eebfde3ce732f60bffff7fff6fee737329a5f510cc18661195ed7d1e9aa699139f8f6719165b95cf5d9e3aacf0e17264002f3c25b7ab1f3e145abaf35fa749f15cd9cbb9def41891abec2b30778e176305f823a1ade12bbea9b6b29bb71c7bce9c8486456cc7917d21c046798162cc343a446e2b1124df7511b88ac1744402149d13ce84e29b237dc53eec0d74c1a05ed928f74a938472b214f6326035a00a661510b1c746f580c89baf9c3d57a5c8d6bcc917b5897daf41ed6882c30c74e86cb792c08538dd15f3d3ce799daa0e917ab98b11f4714931c25cf2de8e6fcc97097b945c1f20c52582cd6f8932194cb9864f54b554c30afdef0d10ff73181a6e24f96fd2efcc9f204975ccf00d9e8c7ab0558ba375603e34114103584b9af09e6177d7a675a93b60a1e5910c511e0bd34e39656fbf970e9f56627cdfc7c5fc77b1e84692b80a4c6f324cba0d2f57f73bddf7566f707a49abb0516c40cb9c8900b0e4811f5ebcdc464b83072e3dd2851cbfebaa3b6dc68fa1f4a9a7a6a3516bc669a6036491c280302773d130a6b5c3ebc558fb53cc0c54aef006ac8417a525c2f16560ea275143b3767a0033e8a64b6046e5eff37d7eb3e9e39939bc2ce21c333e4244ada31fdde9754659c848d96bc8f86776aee7e37a0c7e8c98052d333c76b80df04e08fcbe3d9d1369e35aa879de78ceafddb948d7c0d83ed28845cfb41d236b3252d85983dd8f8bc2c6fcfa80ec924f3e5ce8af99376abed5cbedd8ba60ee976d3e3a8cf2f41a56ea24af44c01e0ad96b2113ff370c7778cf997f85c139058907b7a57211e5299ac6f803a35846abb35a3525fd6774966d9e5fa49d5976f3f76a1c61be541e672f922b3b6712a1b23b5759597a7c3a6d1dc038552f9bbd39a26abe406b2f05eb492b8d553eaf6d9d304cc4f2a986f9c7ec2cbd2282c9d51c335b2f227370054fa57c8a33ede9fad36f9787faec8e4e3cf0fef6fdedf7d73c9feb54ca8be50dde7e676949b916e9785651fd30a59ee9ca7e60e767078d32d19d61c614ddc9cc3b3f251ac66207f60593237e28d47e833f54620ef9958e8c31c004c5f89448be769b04f6153c42df016f60f7067eebf2f6ed1468a65471df698a96f7d8068b0e2c362dce82896d21c390bd8c999666e308e0d9020585af58fad8f820b83a965096b1db830bc2c644fae38a976f725fd035b1eedf8cd69f6f1c75a781bb2b786aa846d0b78a71ae0369a048c9abaab853c40a9218c7e73802d01a8cc1e839d4e1a5b1fb2668040058b875b68101c3ebd531981271e3869074cee88561ed6e611c0fb040bf6044e2d895d96f225b8ff1f7befba1c478ea489be0a1e20e106bfe0f6b386b376b86729db4bed70cdf61f3b5b5d9475aa3453ecca39c3a73fe69f4724935224ab4a2a7673dada4cca00e38240000ec01d70ffbe4d515fae5d90f7b73658d7ee03ad0b6203fc7a76830cabc83eea0d37f62b1450577bfac84645e31cb8b159a901ef1e0bd4a5e5864d3820bf74ac690b3128f85bbbaabdd1a8c9403bd985e01a595b7781bf36eb34659f7ba136315606943ce705d5e61af829b2acfe54e87b4273e40ec582f9360056065545c416e06bba27c6085cc0dfe2da755afa73357780704b034d69804b7064124ee235e1a677a55291e8fe75d866881dc86100cf01af5435d75bc738b8b5ddc5b5d286481d8b481dabcb402b5e10ed34e741cceb6c4e32fece27c52169392c0376c10a7c65b96f956683610d5cafe1459a049a01d0862faf6ea8d4524940bb352c37a53a11baaf3e58dcdabc505b9796051135267b9e58042d3ed7b80db384ede7ee5753c9049a8e9ec9fc383235bbc55ac63cc48a1d6365c6bfbcef3b19766d10574a25eca90aa647e8ecda0f3e42576fa42277d892ee693944dd784904c84b76c82e9dbd53e700d461f890bcd25aa2f7f44b83c3d6c0f0f0af1ffe727778352ffe6f181ee0b0868dfaa094fd02d52d18b33741f39a5deba56b6030f91298ae9a6d61f80538cf06a41cc20c4c5d5c1bd0f67c50083deb3e5bd9e7462dd4b1f091c92c0b467e0b08abb8d795352bfb16c8e392221f57d6ac3c7ec460f4aa6ff0af78ed77fc35be22732fa06350680a2db7d4eeb3b4a3b48dd3659f637e865e915b6ec72cb87feb8217067a829ff13ceea5dd8ef6e5d9b20f74d496f0b2e46fbf97f6e5592fb25992f99fbce22f8e42a76165732c3a5dbd3c227dff1f1ffff0e9f0d6f4f3d58fdb68b1ff9694d4f6106900113cfdcfa7b3596afb5e670f5d1b3ecc1f390840f605887b4a2d01722c58d75ccd2839d67c461e00abcdb31d112af4cbf7fbf41680655881197eebbd8d3d6e4bb14836d2388e713f9b67fe6b6e965f6ef368b8179a3d6eb8dcf26f6d8dd61fb5294729d765190c1a35e9c915017dea24526e595e60d61ae3654e4d7e8104a8cbfd7881c24f5bf1c1278ab5f452ed1afdf4f19d1620c59c7abdf4581138fb8023367fcfbe2b9e4da7cebf649cd78bcf460be979cd2bfe610578a4665ff5f4d715f4f12317606dbdf838f0398f19c8bcdb256f9667fb2bd795ab20f2bbd6c6cb45797cc743d2f4c9e928edaea57565caa74729e72772bbc57d9f9deb6737f934e973e7ad8e2f4e3ebb2d26c47c9e599c2ccf8bf04b63cc0ba3cbd6b8f297fffdf31fdeda4c626c6ec501bbaceed90d290083c070418028162896f43d3762d9cff0c1e1ee26cc08778b20a9073051d6490c0f55cbdda8c2519135cf302be07ec6460c7ff521591bf5ea26e504e930d72bed03ce21f06feb02db296933128d38562f458e6284db1370746093841708a92514033e4c09c54828469a61c1743749510cf031c2e3d28d35a689280636ef1165a4f266aa457a39558b786d2c71487fe56a0934bcdaaea5b643662e34350f2581253f53fc2e4009233cf3c775b38b4174e213d276149d8e4b21726b8ce646c4dee33b401e62503a21a5ae3aca3906eb0942f5566585553d21aee671cf6d1fb7a6006285f2c13e560270e11fb97f99fbbb009abcd068dfcfb99e8ef5095cf23f1f9e37fce5a1d747d1cd81d72f6c0ebb7ffcf4f67028c6a08ac527b3bb51d22827583c444596430e287b395dc5d01257e370d02af9fc8ef31c1e3f66f8f4a45989e73e23ba8e2755402e55c18272cf95fd1ea9c476a55d0941a90d43ad25b64e0d40fadcca43e620208820044d6ad4799f850c3ba9962b55ec4f2b5c6982c969cac317ef13bcaf5e09b8fa93744ba28d0c4167c1f02d639cde57cfde87d7f5d3ebecec7576fe3a78aeb671f679f58ab9037bac48e232c892150dff107b06a119a1151abf7bc60e81d71bc8aee036d87abc6b792fbb4d2ff842cd8a21d3100ce3c57ee0200e00ee9b08bc8cf75e6719fbf570b8c7474429a3821e2ebc6afff9aba2569ebf093b640212d1cefeaa7e7a959dbdcabe78d5387b55bdd269e4fa3d1754549d516b0c97ca6728a601a01f55ae8fef94c90c04313c6ee29070ee805d60f87bd5bacf52fd5f531a15d8b30806ed332b75b9f1a9ac03097fd47d40eea500de13a08135e0cdf9adc99f1a8f1fcd96e578216d373ca6370420d2da01ef4df15ea949b0d63c2a36db1b3288bc0e02cae71c87fdf2c278b9bf16f4ed51c228ec0ba3d41f3f6d7a18e3c2e628f5fe955619be61e913c14fbf3174ab5de12e7ff59278296cabd21c471df6db61c504bc39254af18c8a6071c1fd8ccee008d088df0845e6732222d81650b2b410eafa68d516c5269df84eee5dd9d937ac55e04a8b1d9ab8e5a841fde2cfad179e32b887a6b4c795605bcceb0bf073c4f5c78f708eff5b1620b38cfcb72dc33bc68e3390347ecd03af52d647a04604b5ce195e7d06587d9eed61b67304fb6b9ef2f8112b71062ad26faa826ff9a2c78f05edf7b72bc0e541f3fdb649fd97f79bf6f4cf3ffd70b87b78f82f3fbe8effc437446c698c9c97116aeca22bf1b5d8d5726f6c6e2e49b100e7d8c68509088bd9823e13e35aa7ae5ef585862198f5aa575c9251485af3a714914ac8c66cbce4c1fc02248d6abbf8a52b40c8e6a7a692a3d0390a9d9742e7a5d0d90bad65d01cae22323ec8ab96abe15ba39a1f4ff82da04a1f589e2a96112a349064b37b00bca4de695acd86302200521457745f10ca2729db94cda7cb2f88e8f5dde14f6f5146cb3fa4edb74adb5775eac78fd9aba30f6fb0eb39118cdba9d48948c3d953152ab3e551d21457c287abdd3400d1db2b8d162e1e3e97f87501e506159e596a438e7d5c4da6390614f56a230df080f448b5b50788d028352bcdd111a3188192a5ce17cdee33497ea91ff8f5173ac2f77f792d2c947ff484ff2c3da105f12756ef7a27ab03dc01314ca765b84e18ca613e144b18ca7bfab56335a4ec2529c50d2f88e95b94d07fe8137f2d7de297c4eb25c9da14aa87f7ff7cf7f1ee8737e7fa283e59b07ffb4d037abb968e453da606ea8296951a82eb2d57dc405a2f3bc7b14d12bd011b884ee21974990ce0ba02c39a2789dc7857d02908b88f5b52b31be54903c4eed7fe8a0b7e764c2860cfec19622d866948ae24fea7dc3c7dd5e34719e21fc0c2a47203caf86164f5d62e719db54bd03395a9cd1b5de88f0a295f7975b1242517cfd9a922ded9df5f1e8210548184dac8c72e927e538185a78d049cb2b5a74a93730ffc3bf89cc2a952a81d04304c4a43f695666ab1a1e496266e0f364b12be910e80bac1d474dfa8d45c41fa05d40d2485897b2a37553a4d2f21dc8f97d7c3c978a64adac2cdd833c5dbf3e9ed6b5915abbf6dfa3d5835ac2fac819de47ebbc3ac5737bacc4fff71fcf1c3dddb1b8541f8f55b97908c6960445b4071833c033ea7aad9b0056854ea951625b564d3f397d60900b922932630ee731fde1c70c49554b2751a2d0daa0a5bc7074f2af3a60ba2fbc1c0ca8578a4418638aed8716892954a07ffc801602de0e29c7bc01f317c57715b8a47fc3e97e4886bee0a8fdabd9701ae3f933ae855833e7722793ffcf93d333c99b1789a001484147e4a487e6c1f30d59111d1cb95eab81146105c7f8129f0e292a21a693f64051ab0ca571016a0bd321a2c05e70b1a2ca1c19261b3140d360ab5960c9bb3e0589981515b8d4ac0d4468b2d0d96d06019eed968b08c0643adf6ec63df1eed95a321bcf2733484573e18f40f2bc60e1a2c47c37a8bc58dd1c8b893d1c85873ef354d1a77a280ac5a0e0b20377a7da5daae3178030a02dee7de4879626fc053d166b962f8c0f685b759f236cbd166881049aa0d94eebf8d705154a9e9016d96553c878bc34a8c0d5b434a5cf97238f9af573ffff4f0e975b0a2a47efdeceb8f0a151bb78800ab573803c064a985ba3462c4b31b711d545cc7f2e611cea4ae2ab746d626150e541aed34eb047e696bd415c138b3cf4cccd8fe98ac48fa2c3488414e50a9222e8ac52f1d7552b31ace3cc3477c57cfbd781d07b6c0e199e34a07b1cfdb4a663dcd965a2731f514fb9d436e45ecba7d8dd390ae4ca0663455b24facbd82a14139fbec55bd33cd3aaf2a19d6e53b4d6c475b55d2d2909a34abf827cda17855c53c277da98d1ee109129f0400caaa1d31fa1de0d4546a9027711d593b8d6970cd571c2478c18a0045abf807f8fc3cba5f1c0606f7593315208e78edbb1255eafa07cbadb542b2f8800d1f46ad621db5741cd80247698e2be10e8e2eb341b56a82db37aa6746ba14609368fb1a47376db74ba3ed4b8e4a4f51e9d9060903837be20f36f14633d7754234a06f585bd228ef45f4f3a52f6e74dfe5ca46f7ddbfbffae9fdddc7b7e690798295a26977305dcd629f3ecb68d8c5bf1ee519a75581afdb784e7455f26c8fef7856d2916cbac67da781b786df05b4db7b572a375a4102793d2f7aa7adf5b555c7cba5ad4afeb03fbc3d4cf9ca88c7ef34af2a23ba1c7176054d374a2ad72a57883b2cd980f8ef7a03593226398c085956b27d04304b50c923e1b9951bb6928049773043146327dd33cd3428f4b44854a0835a031c6d8be0464eac91b52604db2f87c0aeb54a2373f7f7fa600c02c8b16764d8125b1c80b8eae5acd9dc58bddca6689ecd26c595ad16fdf4e39b6b4f1f205b4d80baac775ead88cd6a6b5f70fba3a67298f07d9b9386ee05e87f328129917b27cee6aa2317a531aea4a8df8b08d18660fdc40acd58842c28e17d601f0757b1b068c0763595b0080a627789c7c5fc292f4e5004b8fa17d16e9abaf9b36ef8f94b1f3fb269c0bab93a769f6d1c32dcfed848ec4e3ae94cf1bbc4b3556a70f2ebe33e77a6ce976e42b0ab67979097e7fd9d20142c7ed79144ad931efd53a5e2064bf1bbd424b8292acb3de8016d230f01afa051adb7c8ecee8b5b3272c1af0f5166c9dab8ab92302c71e25425c79f755529917efca815a11b5c69debbf15fc741c4ed47800bed85d8a722ac4343bf9608b68d1059becfbd42c36d888261e019028dc23bd4243eb81d3a12974653f79993df0888529fd217c40224ef9b90f201308769f8bd7e1d62683120e06e5124ef807596e2778d2fa489e5857a9801203268f2de80cc0541a440b0eb2e5ba323f9f8cefaa03248f5466506511f71bfd253401f50ffc0af3c23558d86de72636a7703c06a63e1695e7979a93ff7a164d7c483fe39dce76c04defa5e2b6caca66eb061f52335738bb1b5db39a901762083b8ea68e0e07bcd3746e4dc84ddd010a22c0020110492be30ea7dfa717bccfbf4e3d688f7c77fbafbe32badb27dcbb281b654aecd55388aaa5d12368ec66d132cc795844df89b58b8c248f80c41277aa7ca7d2c9c7de6fcf2f014499882851a36f11af729a7b0cf272f9ac78f81da0f47ce70d894413dbc331ff2920e07de05cebf0741c519c1516e018a8c252f500b156a997dca252c1f210a55ae01e77d350b9ccbb0f58548fa9274361a47171de0e3318d8095a93ed3bac181d47dddb3cfc23ea503c41c91cf238d07c094005b7ed2c8e3beeed575828267fdde1129cfe5e86fb9288a215b5bc21857b6c4f1eaeea73fbec59056f13e7badc38ee19872dbec249f70cc1d35d007588e01a7b521a12b0fdf17120acb6d534401a726f6ed223511f02876cd135ea1408a2f20e4cc0cb412386d0e57de30abba0660c0b04fadd044ea7e90fc5ab9f15b65c0ab250036875755017d6d60fc24bfd1874006e24e0d77dbf1f80e7ebcdb91c3b1dabc191d3cdb3dcbb8bd4c237592ae4d915cae5d12cab728912a2719c4625955c8d628476ef7b5b7db512e885549a6bf5948655c97a316734d45b2a0859ec71db2d9178187fc4590e4b50273e1f320491f40b167f79f23d777a0239af2cd5df35d2c5bcf46d81fac497b21a0372c9ee4ded2f5f7ef7b73a3ef5d0f79697078b9675dec561b7dea87c3a7d78107fe862e052c0b5df6006a5ed7700172a67170f30a15d3690094328b4eb8eb8165e9d61f7f7c372118d70ade17a0dc01f0adc0711fb4c9f7b3ddf29465a89b64b7dcca3db8a2af6cf8f43aa7b796db57a9021a68b9314289220b97e916687363bad416d2ec45b1012ecdf01c68b60c8dfb1836572cdd13946ebb36667203a361972e60d2ca8297a66e996023f89a6580ead226c1d51b40669c9a021b838181670f000005be1fe0feecda7cf0f08fc5dad1363691671d3eb2a830af6b61c0a2d5ac725d8eb135e9ca70d96780b5cc964cc379141f3865c9a16ac685f87751665d04b744d6cf6f48ecebed467f0b255138865ca6053e532dbea405e6768116f88840b14d0ae2c7778c05e7b277719bc0c046c03c952e9eaaed21fe48f823fee5d3a97cfa23c71fb521004a0722d76ea5cb218f4e95eb72f0e1b78db6fcbadd396cfda3d1ec9cca8d149f0dcb21d78a27e3f06b9ef4576b3b5e863effaf17b663ffebf6462c4ebfd222d2d70f6d3e66182f6475bf91591af0f3174488db315ce4cc08900895c61829c2ab46b9576d8f1fe1a4f7a48b7cce4117dc35db1c7447a9a7127f06558f38c76dccfb60ed0b008dad8f7df8ec0b3ffbaa2f39b22788070fcf85eb4cb6d2b96ca527a9ec70b93fb0c683cbf1573ce96382148407821839ff827c6e9afcb8b021a13ffee1d3fff7d60414885e3ac0d835cbf8bde9c60770c297ccbfb34e735a5a0ee5b4fc57a8aade5a299744ee3991fab954dd2e4fdf6de49df176446c497d7cc7f834e875f7006c9cfde0dfa91a6a446f87a0f0bf16154fe666d7bdd1e411f799cff117c5c15b774b1afcfc9630fcf1fd8faf636e7fc33e1160ceb1feaf074ce2cf30380b62efe410f3fb157750e0e8a006e74703871510ae8fae9f17a81ae03a09bf9e05461d50c18fef4cc17970fd2ca2b1e40d32ee72f276685f62827e463c1e4b81edf1a31277e864528c867ec7026e65a1273036ac65161a7ad4416a1bb7c4b3b0025c95dcbcc7ab5b751277c49b6cdfa335a2d4c78230f472a9187e31bf542a117bb954e22add2f978a5b89d68007ca77cf5adca7825fdf16cfe9d6d7a6b8d861bc076cf618bfb0d9657e7ef8cbdba371b05e89b9266e4a7d303845a50a6999c7dc06051cdaa0c9406a9eca3018e6ccda680c800d8b8d1b90b0c7734f5c262f7ac986a78e2c6eb2b51d6308bde0ac6a2fb9e5f2302a32d792f6974afa428ba281b6db1497b65af54f1f7efcf097d769d56fe0acb1eef6d06c57566a9a2d69556cb376584f6e4b01a56ac0611267457123b741d313bd1222ea0a3c92c7827985b38090c37d6e568177b424e64e231bd0c6abdb967d500b186ee43f6aeab113eb2543726a3c09c4f4cec819f0e0ad7c5f9bb939dbd2fa253e0302b0d16d082b7092ea124c973d52cd1e0028df2c2d7fef01995d5257b2a45ed089f513298882a796612537cb38fff8518bf803fbc0da2ed91f74f1e13c630da690e595bbd2df90e27c1408af8df51ca49a3d649558d1594e5c96be10a44de98b4b9bd2f7e9eac34ffbc39b3331411e72c53ce19333d248480f0d621174f306f84c66c63d412882ff0f02b73786dae669b171558b9df2d029346b5f494a1e3fbaf895bd44dc8e0f2a89078d629e3279c8a7bf324e6493e5548e53a73fe2e2e347d8a6b67a4d9d7bf7004d6f8c735fab73279f6316bb0418e657412b2e5ff374b30b785f472ee59ee5d2d5cbe0c24fe2b32d75cbc56db97b1589e3f9f51257b0ee2532efa5dc4a9fd43b5ffb6001016baeffb94e3dab77ffecf7608d63b9ba5e48b816e06ccb73494a5c4eb87c1437bef09a4bb7dc5a2890b89ad70b91fb4b453a02c7b6f3a562618db05c018768818553415a7cc87b58fee872fa974fa77297efdd92ecd8779a2f50aa7beb5e10880d51f8cbdde1c3fe757682e5eba974e54bdd8fd73dd926e4c652ac875e4bf91cf4ff0b0d7e79f2fa33f4922d05fe441a80778c92fd15cc9fe7f685b6b93ec7f3f3dc5ec0fe8dbadf6a2a5cf8b2b1fedff77ffcf0e64c78ad34ab96b1d32afb6c42cd4a9bbb69c49dc7c8ae9e342ba3edb815d089cd61c3fff8b7dc48e730db45fcbc69ef9964b631aed8d5865aebd85578aef4ba1b4cd26cf0cecc3b85e9d88108d6baf9bbafbbdbfead8d1bf85474d9c954b2d2a4de49331a5245764fa9b22b3bce95b84c1d592799f0e83be94aad557d4ae0c65d70a1cc613aae9be24df54684aab51d0fb74ceb77d226f5d987bf664dc5d3ac852adb983b29fec870e1a1d274eaee94885b27c960e91917b4a9ca5362cd8ceaae93543c2a5de75362b9c38bb3e34a656ab79d5bc93afae9e837953c51e36d57bd5e6bd37dd9595447df0986afc9bbd1a8f6c1baab9dbc396dc720c735edfe0532e7c0db23b1be5d8ab2eea492ced23496f9ac4dd989a20abb2b9adc79daae36aa4f7f4d5e5e5776ad505116db992b0bca7387ad85e1a7e6a4314b9f3b16a6e9ed7610aab9d5f8921b512cbeec74f6bb41aa9379b71ea3ddb9647299a222ebef7221ca9c2784ee005cf09a55a9b7da5cb9f08c6bcf039530ee5c9ce7d82d87a880d83bab4deae1fc7e1e3db85dca3430a79d72982cb25b8f4b2532699d8aa8057fd26ea40d326f1b9097f8e7f92c39ab349786e6ade37975561407c7c86be4e5fabdb7eaf03a29529aedd663dcd651cfb6ebd4bde66fb474b2a1d3e295520fb0c70a807f96170e57e8a4efd6e352f8b2a3c152f14da3b5d3711510cf457693fcd0e0f7c5628d77cad3bf31eaad0f9ebbb37a9eda75b71e979ade2d356d877cfe088fde764b55ef741558af953ef1a1389e5adca5ca4be392f4dd20a9de95d663bc49b5d3e8164275a3de2a45fa4efba0aa2cd50570d72af98beade06d930031385b7ff6e74176c19700c77c9d8cd4ecad27a9e8dea772c4ade92b27b4aa19beeb4b337f2d88996181cbde369696abb53e259c7cbf099e331f6dabc7294dde4c168ecddb88dde7203cba23e9d58bbf5b8f351a270f37e7d4a9d460c8864652f3a069839d807a835711a7e7c14c94f03900f6093cf124f2359eecb608e31ccaa3e254e0362dd490cbddf49f7d16a9a0fd46b2a6eab5531240e89ae7a532358c1471dac3fb874cb55ad330a2f32e3c65d6d6527e01d575efeb21813e54e7aa1e2592cc7d3ac21d5074eaf8f7163d3bfdf5c1caafcdf0bb3bd4fde1b73bd9fde98e93f7d78a5f5d96f599430c062f260e2bd08189fe192ac70c7f541bc2de936a8ce5b192b7ce209fa30ad30d540443ca12a1eb1d4e38ab32909c0cb0ae2578c336825c12656da950520194b0592908d342762016da4ee59dcae208c2760c6fc84b70dc4c6133ae3b135e01659c4ee82be1bb1a1a9157c6869d41fdff1349a3d6905572f884015de1aa5a73afd519d16f17ba6b21f4a2d9ca547e25148d32849faa0696994fb31a8f61ba91644f5856c822da81b9c4cb3763270a532e73a69c01ba1f2e33bc8f748a35399fb5c11004623bbbae093558b1458477e531d08ea3d89800ebc1083016d89e8b3547d12bfaa15c4fa5c958a415de439a94652cc6be1ab5abb553280ed1983629527f0e22473136a8fefb4151a7083a052f77088a502003c17c29ac72084ec1eb07c85a530d3ef5a60762c8775b979a2c158bc09acde58017fb77623031e6b0d6695ba7af5da00c49d90d6c7770da22dd7a68277cd8997b5baf9b23a877f6a65b96ebc04e93f2d7baeab9e4092dfe48cbe64316058d81a44fcfcd628f2f34f3fde1dfecffd87c3e17536a7bf05a65dc732376aef545ddbda675d54473707a0772d7ffb2c05c5b4ec5c2df7e4ff4428db14d9592bd45d1fdc998d9df512f962db7bc77001e83e6fba428af7e435713a733ddb1e44412850c9b3b94e1a3763bfe976b6abb25bcf3d25ca6eb65db9369178f6eae9b30a8a33d727ece9fd47d5f8beffe967b5afe5dba892fffbcec788b80c489cb6cfdc766e98eed6eff2b4cac3e933f1e74ee5faf4e8ff7dc7e253b9cf76dc5ba4f66547956b53622b2d14f311e91d533d685f8c01ef9eae237ce7f53dabedd6e33289fb8429769f23dbbb49dc5bf72f8fe33a654a0d02671d37ac8c17c94e0a93f67ac56e380eb448811a2a3b1e0dfa61dd89b79d153f3e84da547d9c745d76ec7c6270c57a60a3f5905d7d8ab62da12643dbaddc76ebf15420d78d764cd33fee5aa578d1ad99ab1c718c3b97faca127ae577d39f2cfe81715c1444969d70bb9b5466dfc56f5c9150acd67c4e159bd78adde38266689216fa61e6dd9a402bc96e5d541a230bf4aaf0ef44d12aac0ccebac8e5013e6cd06e3c51bd0e8a35e8e9382eaaefa2fb06b5b42bb12dcc60b7d8c27466661a5cb9ef9e52a10d5a8385d2b3cde5554da9886a7b4a2caf310a25381607e43bf0ea0f6bbb5362a9a91a962ba647afb343e65065c1793a589a4b3d4c8fddf05bef9466ebbbf80d8559486ac892cb74a9f3745c146ab7306c7a7378751f7268f006f738a8b53de42e6b34f89d5129cdfa6e3d96a5063a2c683be4cf9fd87d96e5dd6649f26725d9197569cb6fdc11dfe279de08e6a3ee1aae41fd14b35d671a5e2d28a28eb65b8ff1f8d89543b6580ce012432a4b0e13c4e2a1786479202a8e77359af610dfd176cb77dc4859eb68ba39840f9b6db4dd7a5caa66d7a35c87b566768b7591cf720c63c63fd7dadcadc728087901e74ec260dd19d559ede9182fe1c532c00b8c0a7bd5aec75518bcc6a2bbf8a559b89d8e4ff292f1dd072e8b48c7e0d26f4406c53c61612cdcb9c43663db9d1221e3b21af8531743c23b0133cfa7c4536f402ff6ee50a36d98a6721d67a9a73ee6058f1ea6a7feb95b13b08b27f7dd7a7cead868a6a55fafc3819e1257ac65a916f6896fc0041337c36c1d80bf9c332e1a37e79ac6a6827276fd4b45e5bfddddfde175504cbe6565b37a3f4b43a90607abb66434f5ceadbd2669392cac1885c2f98b698c78e63b151f2fd272587d1adcd01efd68930a1fa4b91d93fba4ca7b37977565849e8294b965998adf9870d731e3c9501c7bcf83066769e05d047ba2b6c78f192b43e011949b927836d22364198eb8d89d3749d23d7337a55a5226b18398f83757a581cfd49e96c3a24573849dc67db92254d7a859868a8bac80b26d4b1ad9de7a01641eb2f485ea54da3e4f2ae6732af6f2ea8ca4b8de934a1013881662061d5803020aa716202a63a64ef0194590d8902b05b7a134867526496a27898477a9a397aa0e5080352073f8bcde7bf2bc32f21ac0f2008c4f9958078439849b6d49fa8d47e40442b0ac130e162f1470b6e476cd7093adcce4d922b216b7db9244b6bf5cc2d972e4f56b4bd811dbdbf73eb00b98272583d4e2e9b587b506f74a366856bc2f016aeaf419c7a568c9b3c930bd41d1f1f44a6f89a83e8c483df513b922e7d3172cdff8f831af95f772d94e95f78d655b2beed794edc20887216a6364c3f98d11edfd9bf31402a8970fe485afe069da615d25533f4ac41a28cc5cec70828753c46d72862ba31b2dd2b352691361c205b95061fb0e6039332d8705edbe31a03fdc6e11b1803179e65674e2cfbdcf565eba7ebd50f4ae2079cfdc928eb90f2a7562e75d5b4d425510016dded6c5d370b13d70631a45f272bc62377eca48e263325b78c6cc4ad239d2200928a90fea3e52aa1fbbd76052adcba77afdd91819a7bd62fba0ca915ceafb11b1ad67aec99fb9983e3c772bfdcc55fa335fe58b12fa7ecbfbe4bfbddf703cf96fefffe30f9fde6878db3744363cf3d3fdf5910db150f702eccb756fbf27a15710cbfcee7c6aff78e15ff585d9bbf46c7fdf1ff9f7ffc25f6ec6dfbdf703f7f2a5177297af78a3a8bc996abd3c4561ded99ea7706963b2babffbf18faf641d7e0b1f60a5c1a94136d4b5a28ad59e9ec1b4c41344ee54e48e2bcd6e69392cbee934192c53b2e70660c9468c783ac089e98ce4e86e0510cf84cd4d00a4f6c445a8c1e31611106e291c726fd4d46fd37a8493c1c10cc83d8dcadc6bd89392a059959964c1239481bdec515d1ddc2b38de7992342fc6b45cabdb75919e0d7475d90af599b161e4af65cdd5dc809b953a1f2a09d6130d804fa09f0ae81aa601d421d03015bb11aca0a472c87578c6d5cbb40fab97c43573983795f110105d0db9a7c8ddf5513f3fa98e2841aa6e9f2fe909de7c98acbdba621a60755de36b12bee6903bb6133bb98229a86960eb1002454a4745255454546842851e79d244a5d7e956b06a38cb0a76fa9aa409934c647a9653009583ed1e652a230dea9c1b03e4b6ba49dc033478f41c8200f81c3725c5df00bfd91cf0717ebe8ddc48bc990b96a5afb8914ae232a961c72a49a981cba52d899bf073dffd7396adab8e5d3523054c88b564934a3bd40af2c24adaf640dfa90005c6a61f60d578bafd0f0aa83ec1d728247a2332e0d42b7ac8d6096199d407f0917b8eee219ab1a95bfd07a9655b2cc368888081250d5cedb88cd3882158afb0c0ed5cd83b4150340220560af576b0024eb241328e3269d67d9ede9f2a04afe24d95742c690994139023226228429399a67fc343904a8234314e06322733da0f463f5395c80c5e16d8dbe4eae5008030d900949131f04fbddac59275d85a2e93d6e56983d0bf71dd23441a60dd4f5b84b13fb85cc98c90a7aca45882f19a4d5eb337b2c0468b1e647a5f126c68a3c9129acc076e4e4a15601a7d24d056a279b1887da8e23d0f22bae7e182193bc40aa8a20adcb81ae053680ac94381dcd5c82a00c5a5e7092c6b299d2a3f7ecc33aa9f4bec37634c70553cd8d4068d18c0c621572f871b70bccf237646bd9a91acece258f0ee76e83eaa70271e3e92162055b6602cc33a9aade9cad43b68993a4d4d884be5e8353e8058015634f8d5fcd6c83945ce23366dbdb690ac586502e1446d51dab494963bfa2830c10508aedee3e792f6cfbb08041d13ddd6dc880b1b33e38787877f7a35c0c7f9f580ad36103dc0091179804d0dc6753e8f13484b9cc01a23f0bd8e9ae2ca70c56c02fe6e1ef2f4b9b5ef337061d47f66a034607d11db60ed0118dca9d3c439c8249e4cfea44f7dddc7d44a2d615b66c6422ba90f610c3f6c9f512dd586e34315ea4926f97c91fccc9e6a1a84097442cda9c4c9a83ebe033a19b0dea36083ba0b75f58c6a32cb836ad03e61653e1045b8921db8e74edeff7d9a4c5208b06e4bca8796079fa072c46ec599435e1eca2dc3e9910008273e4e188d6fcb721090ecb3e10e545094d4478d91000e89da35afebf83a0cd5408146846506be99b62b99855ad2e6b511f86d9a969a7afce8ddbb0de2dfa77139f98b5fa5712ff5d5a5eb6df5d6e5d2767ffd3f1f7efcf3f5fbd72277a9e5abd1d76a71a5c78a50dde711c28106c04f55e22cd57be3f086f62622cd6040ab01db6159baab9b35dbcc41362ac97c606df025ca6aaee3b58308cd3484dadedbd2f594ee758f113475e2c3c03655dd8b01fc1011683d40cdc41ba956c248debb8b2a9ca130c3a1482669e63aa37d3b76d0d21c9eaa7847a7918c3435023269900358e2e1c50c95133339b42476dd542235cb9501b379a6b381eafb1706b8bd56a0f144805ca0fb20786d66d24c1d33791e46ed29853839a0e73fe15d9d81613d3c415fc5ef19a2ca19be0bf05b584ae2fa371a9680f228014af93b0c4b5eb89ebda6b8f9a8f20dc31242276358724bdc87251c7d5802bf38f0e215f3850f34048b6800b3325988b51a498c2d75fa6823c4df5b29898777214b529a7f2c411d89ed58308b07d89ae71403dff0cec61695212eac12a9c6a9dcf868297c11f5f1d9707261203a5ddf1e8dfe3e3587e19ab4fc0e1d48dbdfae03fde79cd7dd2aa9ed9babfe0589bf20e85bf2fdef1ffee9c31bdce4e858391237c5c755ed42cd12d7ee2662e501bf619664b5830285e5de2dd8becf35d013400424c1f65d335b77b3d04065ed96144c0df82c52c199e6da0c70835d80af186a8f31b164b7d4fb005e3af02661e7179a35e900e2b4ba742c665b6b54f8d69a5de013d926223ae66a246d1f041a0a86160623aa3460e262ad29e098b9501b99bae251e2f1356f9b64ba072234bce25c7607583874262b30ce2655be52c48b248d152e9d4aa361ffd36c9021b9974a16a0225438072511959aa98f43874dcfda62a56bf8578802057dc07b1cab4591f4274bf286cef091a7593370d6b18dbf92030ce2b97203d4050197d84dfee25f0353da1a15797c674ddd5e971377d8d3ae683d717c2d08cdcbb9d84b7d5809c6029661dd703df74b4e628f1fc1cee2570e59278d96bb828b71a14ac29c495dbddbb614770838aae7a47231e271ed929b7d382e7dd98f6fee7efce3c7bb9ffefcd656805d618e953ee61b01a947122a76a74cb382cbdd0f27ec1aeba9dc70211df1cc778cbde1b41c4efe41c5c5e296ed82e4dbb848acd46872acf0bbaac4a01c6e900ac522d61c005de329476e05bbac9b843f36eecdc6315fe4fe62e018dee76647103bcccdbfaf9b3d7e34b8e07c053fd10bdfb94d8e7349e856f9d910baf5d2a6d0fdf0f36b61ff7d430c0e57a185186d1f7b0eae7cf8c4afae36ae89fbecfa804fa9c2713df9e943e02c6aa77acd4d23ac61b66b556f87722fa3ec59016cba8c262b408b94f038539c3d67a9c48aecb245942b5031579805e620c80e9aac05dad1d56a03a8c6047b8405f3750f630cab759c782460a2c220542cd125986bcd3f02c619203bfd06373f61b687fa03f84885e8a33ac4087325bb020326a9e576b70945409fb55c4cb85809e131f8dac46171787f52bc38af2f16989dbc127b1b20c101b1ea1a5a4f8c49a7e37b320f3c3b68599ee09e05f674cf06534942f1f7b9a16339f3e086b4e2abd45fbeaf00a8058612567e1326124b3581336f24462d5a6078f2b21f051aab0195206944575ddb0260b1c257d80a5ec1c1568ff9f81cb8e2d2150685ce0a59612b9c455bb02e3ebbf0f8ceff2e47e912d30edab53f4104c928b7b3adae3efac486b94e4ad5bf42bc2d6f982135adbb91950db47f706cc6e69027ee55a8ee415e9226819111d7d2203e54b7c6b94d62e09fa2db10f679c0ff16bb75f72e1ef32eb63b97d07f86d186c527acec066783f8dfec233ef63c6aaa58b8c06a319ef1c4752fa43e08864aef65c4bbb079f0c2e08571687bf0c2a5adc1eb5ffff2e95faf3efdf1cd0d5f522b15856758ab7b5760137eb8f9b488a488abbde500d7e57064c68df974778ebb03104e6fa4c646d1948356eae8ca5d5e7ce690cf73cfa75be3ae48aee5c8153a1c7ef767199e953be858f4e0f7d4b8f3f1e384cee86f884f494f9f72f19bf168bcf017ca7f7ee72f94fffced2f96ff46470367e794032a915354e58b4f3dbe6b62c0d2d3c1546d9f5dbb044329e21a39ac3a3fa9722dc37bc808ea3c5510797632c4c27450daf119e5423a112d0486294c50f1ab40384ecdee2bcb89510370db2300b697316bd078e26d0080b75b6e2b37442cf09c6192b25c0d5018a5e0f068c1d971546dfea65b5bd095a50317f9b601bef628f505ed63ed8b9b5d78bd78a913bf7bffc70ffbbbc39bebc7e0dbb4fbda8eb5dd8db4d21245c4e7f9893c8eb9b6fbe7776528974f672240b5baf9d63e3ffbfcbe348eb5dd7f765b1ac7e72f4d636de73b10b1a5f85de33a97a6debc76d6da5b4d1d2c1df3ab84fd4b49dfc09ee476d7cc0dc1f88d0f3a89fae6b545da7f3df8e133d1ba2896cbf54b92f9d644f21fa3d02f8e42179b7aab8d7ffee1feef766f199e2c936cffdbb608414917fb00ccae295aa0e5ffce3bd46e4cc0398bb3517dfc98b99554de5459f5acac4f257da733ec8c76a5b324ed3da94cb2b42c02f8f1de7b047019b14265b9ba9d22602c03a336ded2dc821b8b3e3eeea597fd0c83c2edc4b128e8892f3ac39fe47753e6976b17c4fefb7ffbf9b5d037fed682af0a944ea67e183edb81793a2c74b7b4414d6d89c78d9a1ba33cca413d616eba8c60673798a562c120e27723f8c7468894510fd1f2062a400a82086bd6121b11609bd030cde18d6599c761141f106377b627a0392007b76703ee0d8b9da05ec2b3b92f7b18feb46277a390e653eacd8963c8d525818cab1744f2ff7cf8f175d63fffd60229c5cdee3988f797b7561feac2be3f712ef9b9679babf6159babe0d8f2d16c609169d9eb4526b140143bf1dcca1383cad986d5c3f31dabe73b5de9d94ed7e34751acc9d81b114497a64b62e8d72e08e1dfa50062a343bebd899749fa9bf371a9ecbfb734641f073be78619dc73b060f37c4161fcf987fb4b32b2251ffff1fea7ffe7a74f3fbf8e59f02d44ba88ca651b54e4202a342d71a9d4fabe61a1b778c7249b91142699a92c77e6e54e6e546bee54b1025d2b5ccf255ce18bde480bb25e52be934aad80b6d40fcbe64f647ab394a5749a3e95794ec9335d926055f72e51a8d8e3471b9d78a4314806167cca746bc1edc8c6d42c7525811e57b1120c07b80a07767816614792fb0396a567e6c5bd7ab4eca76f7a41085d99343bb20789afea59c1ceca85629dd75f9d6bfd8da7fa1b6bfdddd89cf00cee8df4a9face6a0f9507e467e93e60d74e013b22f17da3f9f7e9377d9fcc14b07de19c9bd4ede6dff5fbac788e97bfef62ef5abbcb66175b2f6ef4b3f7777f7a73fe0c16db1e3d1cf158161b2233fcf0d587ab2b1b3e7b37c1a4e713f6840b499aed3e8f72c50360f1d3554ea42260b327807a81aa1c9e2ef5ca65439334b8ad5438a70878a4e0c0f04b8cae57ac420d73aeb464ecda07cad402111c4b9b89430d8107203cdd71de1204a22238c418ace5b8b98238106e7dd631d0d2cce12413df4b334d4b03d8fbddf3edddaba455cfbdf93bbcfa551af5c056ab46ba2fb916d758e0e953e07109373433ba3c6cbfbffbd39648bdbffbd396307dfcf4e35b1baf6d4c2a3a9208cda6a8a46996893519c21c46ae3435192b4deba911cbdc2384a83484b4b0641e884ea84a05cb394ca56b1a8dbab5efad90f960502b150036b0cc253bd717858a0f5cc0f7cce19d021c491781a19a3a402d23a0a8ae076fb0198b4293e3961a0f4842d1386bd0d178c9ac25146d2614ad0d80de997e6f9d7db0e3dac8d5a25269744e7350a96d1f25cb5132f8cd708ea2e5285a8ea23dbe13531a83d3ac544550393c30cd55739b5f6994916621865a3148eb48cb31330d06f37fcf83d4b0e10828a38aa8f6f52f12ece5233c89b8b6ac34a666b2c1ae7877c9426c11c534b0973c10efd14c40705df46ab0570c1c8b4c3a8eca806044fd36e258eab43ef69e65459688c91004af943653e49522e787bc9cec2475c6eb386eb9e853865eb0d9673e7efa71abd33c3cfceffbbb1fffcbbffdfc4acbf2df80a9570d802e6c24072d20e667378afadeeda39902ba12c16742d5924524d424ae0717af99b55019fb460d5be9003519e2b23b3bd418cec6870cca4acbcd053331a260f0c7f4f7c8ccf0ba42b012490f1704040d1ed0bd1448dab1076d9883d527fe70212a2d5b25ae88796b37f145ecb3f8bc322f4072ddd5fbaf609c040f0dfbcbfbd1b5dde0a6f05e34fd66416c8e0f264188dd1fdf9958b2529e20259e369a17f7a763f0559ee2cfce696c4ab900e7b8b8cbfc1638c767b2b4298267d72f8be29be3716f150e74d565e086ad53b18468cf79101ee46350611a11b12519b18fde4475c175e04a36dcf2af7a8093ab4f7d57da4af2a1c247f982f171babeac62aeb3b57ee3598fd068f94e850a835fa19c7677961be6518dc2f70d519a1d82a2d8fa5cee38686918ae4d6840812dae53b816e8c289be13be553ec41e20702ed565ecfd2e44b836aa963564b9ba8ce3895f928517c4604b028eef0ffffce9df7f7c2df2f46fe170f04aa941f6a2ca37de2e75f4548b91aaedf3241be85fc258fa691dce8a2213b5d62d1557e24dc79a47306748d2dea928a7d641f0a755dc4a2a5201d1ca556e47b9f62141ec0e20d02d2d87f0e2f04676a5ad723d0419e955362a82d96d4a4b0c5e3ec847114b60993867af7ac66e755419f74d69b6b69742033474ca34dcbc329a311ff9a75bf1afb82c014f8db929054f972f48c2bffceb1b96039f885a9b2739e8d45a5ba4203f93827c410a961c5629608dca5da4805b59a5805b7129384a97cb6250420cd2490cd29318b87557ba2d7200209f9084caf2b92c7cc664d6ca0559c8cf6421ff0a5940735e92045cdc90830f7f7affbf3efcf8c35b53ebcf08a5f48c504a1742a907d045a96eaddbade763ed6eba5d70461dc55da9455816d53a0fb929e99c290e20f59ea30362ae62fda475608956713d436a5d0e87786079fc4ea030b5b41e03d12a6e5d0ec1370bb42cd7e679a6c00d765d830335f8e1f447c2df2044c3a9b076f3e98fb8f8f88ea57b41d310d26287cf3f065f91966f8acf48f14dcf8ab6d6c2b3afe992d6e3f9d7e4f56be2953ef1bb7df4bc3ef6f1cab41400af4ccbfb37df9c5eaac7e7351fac6dac7dbbf0fba5e996122c6d1725d86ac1f337bb65b01ecfdfbcb6e0a5deb774a2adbeb75cdaea793fdcffe50f3f1ffef03a0370fdeaae37a1bc989ba8754fc52d5e9989d765314460362020cc03772c82566a136eec33c5ef42fdd910aa62e4131e53e74bf7c0f374446ef929b711b78ef55e7f718e1753313085d66bf8cd1d80b43100bd5e02392399910206c46a1a46a326839ecf0cea57b72382090e1007dadcf01605123fa7c9646eef93342a9daa1033f571cfad5004bee4b894a9323167cf72d200f58b80e2bacddc855a649891e1956aa55a933440a8782389142fa627b9637800592227e9429333290c2670667625b3880d19428024e4de80db9847d967d06bfb44059f933173306c87bbfc994b3c96b91627f97030d997ec0dd45245e808c8db01f32ce9e4537fe66ffff03cb3cbfd6211f1cd8eb15cdbea19afb479f90df391ba9c7aad8c4a3a795f2775039fc328134b36d213576f7500bfba4d8d958e889b1244609136d27ec8ad93b81ae233c1748b17bf391ec79ea534c99e858f80710f7e5b7ebab363a3c06f0980f096e3b09fded8fee37dab8f9635b88c052bd5d48af7b8e11db8bba0d210b07054e909ec1455a8bb6a4b132be643846a43dff75229f5a109b6bec0d82a3e2ee0b0cfe2ca13a2b78b00ce62969a7ae07c1083e595692e371882b3fb4cdda80c9cec368156a452a9f2c1abc82b8be75e06f144441a074c4ae99abbdb6040a02a0b58502f9c7d7e77693799b9515d025a0ccb4c6d82472bc685a22ba867a369083f6ea5edb34f3cfe8c7fb5922e80821839bc79b1ac5ada41984a0dea915af75e819cf1eb231e0fc98d786265b00e78e02bdf7115b221693d2ec09785aa44d4f8ec8fefb0c46bdd0730b31932d2382f621152b208c22a23cf648ab0e69649ea93d0e5ea5f8f316e4cf1a7d5dbad1af5c14f021b05ac96d6e3cae11cdfe5056cfb4656241959c35e6269965c2a9e7fea67d5e3437386bb33d68d02344ae7f32add689bf259dbf8982859a8941acb410630fff316ce8b743c1d5c725c0a759e64e533d912c5635ea26e14cfb67359c4025575c153ef56a38bcbf5547b26d85f740803808e7f7ba5de02b4683eeb4309b0e051b59626158bbd8439cf7b23d512212c0533afd5a0a6b5f6bc637f3612404642706a0c2b9dd751864ae1109f7a3998e0c2befff696ff879feebefff0c3db5b5dea0c927da9ed3edb70c5fb4a5d89c0a9a440f1292e564bba63c1ddd3da164ce93e93f94c677019bd95ea032b1fdca26ccbf224cb774f811f2585b74875d938baed3601e6d5a9f59e41e780901544d9790e0088b21b7f014f26e1e99621f5f14bef602cc6da6d1f5eca5ff98a59f106b3af40306c83e6ec37937476d02ab1f2b35205d5efb07a5c3f3ba14c0965421c0f76485bacc27b9920ffaeb58fa3bae93e97ec4578237b51f9cdd94b37cffed6dab8044ed827d5a17bafef32117e2b012ddc3b0db524e27681cf054c15086dc0db1e92bd36117bef97b162d097bf2e77ace82b9b9d2b2e6d75b087bfbcd67acdb76cc0c1d7b8bc84c13bca45085e6e972078dd507e118257ca1e1863136f8413cb2cd353561ee28f843fe25f3e9dcaa73f72fc118e05b3bde5fc04d4a86b34eb66af956217bb2da266b76140cb65e4d102a4d3bfeb375eeca1e86c9b1d1457b6fbe77f7f9d2dbe6fe89e6ed6f56485ddba0e3ad17ac793a6a4f85d4debd27da6e079747b81af06b8fbb4b6340a85a9da35d6cb3f8fa5e1cf237a4468e8dd0251b11c961d152c992b03038f936b48f1eabaec9db166416c2a8d71606c17d2d4bd26d79f6225a2d30002825424ef8dbaee5d01c40a7c259febc16f80e4a402d075ea01683a00376aaef27af2ce189b33f85d62362b223b28a25ecdd5b50084e81611d41561b76efec0bf6822504ea94b02b8a9029681fd6f84d445393a754ea0fd9308e9f7226a5f8e4688c4b14108c4eb35926ed04ba602dc041d79fa9fe0a1cc01a7a05e4f8fefcc6d2ab16bee5b2142cf18abcb122eaf523e3bfb25bbf51a16f4d113e59b73bf1d653373f072bf52d1dfe154b96ff6793c197f163976ddecd6ca67e754ce4e74447f91c9218fc4edbba70c05413de3d8ec977bc7e3c7ac40f36de57a945f2c9531a9ec151e6bf05033447232f056225d1be050b09fd8b2d4ac936a73e17139465a60e321766924861fa2b5c4c0c7c432994b724680f5f0ee03c32ef89c466a34c61efdd562fd2c019c821ba491ccee58d1e1346059dca49d6470f140c88c22a4dae7ec659f1d80b6f50a1b5e831647dc1e2b5b5adc103dda5549cacd478781ed24d88d9e7a69c8feef9bdbe2b8b03d60ffcb9b1bb0a1e2dc05d383d76439b13ec4995348229c215bf9dd6f351b60bf7fb5b1e4f7e8ee17c792df63a0ba50f417e4ee5f2ec9ddbf5c90bbb72675a3b8b5bb1d62da6ca3e2be38897a7b7ef6b3266fdf9d3f5152b35f9ff5ed859ca3bd5fa5d4b0f8fb3f3ac26fea0817bac14627f8b4bf73e9ffeea79f3efdfb5beb0d66c06e56aa72836569b0fc98ece1b00be72345a4e3043613301016e0f65eefb9579a7c8cc3de0b42dcc136dd52eb9e3e7be6c0936966c3a6d43e70c17578f6607fcd7dd2ec19f05df17bb1f6cf2b74ab19ceaf6fb6c79ffffbbfbe7f25ffdeaff7163751aaa95ca92b32d8c89084b0144f7055aab7aef9aeab0f11932fecca33961178aecb08387b9af3eeb5ca3e9e48b15c516381e1167833c82c2ff9c4bffb6ce3983b13ef8bab5500a6ebb92f6088ea2998ef64a90bf5a4421ca92ec751b6416c543611948e79942bafb636522d6eb991a6a52e5e900034e176e3e3d276bbbf35b7542b8017bc0fae2eb952d40349d2d22980442c95ef5d12fc2c04418e5dfe1a52f0f83173b1140e431937e98cc67609485d7297872e389170e2d82f2f337cda6faeb07fda6fadb07ffaf107f4deef0e7ff9e74ffffe3a5d55ea5777556e23a9b9b5cb97d796ef73bdbcb8ac85fd69377aa6f11e660b202c55163f8311d14fd38de9028eb6d1e0801f87fdc4d24efc82a17f2e7fa87a96a92cf7e7e57eaec43c731cdcb8638ee5faf535cb5fd7dc2eafe67ed62e9b0dfafc96971bf7e6fd9f5e299cfcebfb24d6c5eb4c32dbb569bbb09c76f4d6bdc45214391cb3b5857d2f9a372fcd8a367e5ef93760e34ba2d38f60e6585b373f6be3b2b4ef67d2b034ebdaba25e4c61b393d7bcfadcccb5acd670df30badebb7bcdcbaffebc30ff76fae7995a37f885b7e97d9a4006ebcb9c4ba74dde3dab869e9bbd1b8293af0d2020bbbe2f39e78deaa915edb362f6d9b9f3f909ff5dd5570cebb705a5bf7059df5f386f985e6c53d2fb7efbfbc4e4ceb370ccc63041a6f9d2f6d80d54b9dfa7679f87e69db75548e465dba6f7a365c7ed15667adbbb4ebf2c7695ccecfbb6e7ed677f379a74dcf2680ebf1ab06e67fd90c9d7c76c356b3fefbed87870faf15f5f60d31946d929a2551a6a6e067a5d912abcfbedecf3a0dd73db147dc059e39d6462ab936e22220209e7908590583ae9579c355a877202288ed73a756408b3beac870024274163cdc4c3483dc8195982d4d62d03715c4e1c6834ab548c2830de45c78ae1d4c8995017b37ebd598643613bb2eaddea42211f5d886ba9cfa10a24c75f03e53612adc3315512aaa990ae6943ca8b78a4d83ee7fcc66feb22a23d6d4bbcea4832a98aa54d29cd44de008389a24ee42a3cec4c6a4366f6a455c99989116f94ebac037633dc602e708d6e5e25f71609ec0242d54c73d150e5629ffc46277aa854aad693d867ddd07228789fb21f398344796ce6477d23b3519693dc6eb7450ef08a902ad7b651aa0de6d54cdf6a8f1144d15351eabb173a9744dde58d15639da0a4d959707d1547971f4aa34f3d254d9db4a001bd8bdda0b7ee6be76e2c660bd80bc180dad6eff148bdd7fce2c8db4f09d1bcc3ad272886f87ef49b4cbe33b9d054e63a1391e228eab79dea27b7139001097974c3a75e6dc1b69d53428dcbddb3852d13dd8b01ae2c0b803a61eb0204396b4280dafce3809c23d9bf9fc3e308bb5b0cbfbb367f17bef6ff1c1ab03eb550c4c6e5540fed24c8395ddab742c5f31e22bfa9554a55e47625152608c1732ec622d5e1c52f6bd12831e9eb5a556e0960742016d3ed41ad512d0b1aa2ec7b3a323ce6ec9a5e7729cd03a846d0e7fcbb58d91efe71f7eb8fbe1fdd56b11cf7c0b96a0585229f72ab7b3dde785b8a1057d00e031167c8c233718dd27aeb6055f035c0d5a5dac6ec1b11ccfe7f5d1f8e7391f65b1d023ff95774057f00d1b693640aaadb06d9f614c5f73bbeab42c9f2d891731ac8f8a097ae3da109ab6cf4c7d2610ff2fd003a46d49b6f4abd8a2c1a0dec2710d5ef23d077645bbe7d9095077aff892eb1671f7bf01a8fb9d8d9266bb5d01f0568f90b3a519385b9cbc4fcedd4c8ed2e59ea70bcbe3473f1578e336ee673b5e66c73eeb005b3de7e9ea977de7dddd0f1ff66f6d49d37bcd6c076e0b760c124b1523b1e0cd20b1489dcae3bb8195e4c34274a7a47a83c8a972c05f169115377033c709fc6ac22d71e27407b7828e9758c6010fb6b8fb065cf26d3c7bc054dca279f6ea1a5e79cfdf0d54a4311e3ff602f28aa9d4fb8d71a7dedd941857c68cd04f624956f08e927456e29a003286609c80a9c58c1760b8feeccdc4c92e049a7b09dea91a2915ead8b7af24f5104106f83d87ed3532834503fc5b89e4b2eb19f8bb28175e09a5f8a04d892de350f7ebeb6cc49b158bc705a129f6f84eeb04696151b276c8b5d0e4f87555bab95a0db7fec9f11b27fce792e8437e37841ee737c5fdc7f76f6e438b9b81ddd106f135cb7354ee58aa18e5ce75a835584b5bd676cfaeb13d3b9bb41d47b963a601bf8e251c054062d34da4c78f0af5c64da5dace9e2e19795e6b97cfceae799e39368611c655be7813ec317f1950a32c999d3fb85ae60049178084b740c999813175cc553e7b00cb3142fc653ec47b8aa17d41f15bba355c6b0a411d71fd4aac052e4ac4b3376a0f526b9e7eae8276a4ef73a0bb8c4c927d44f04ebb5112ba18d51892b52d893fbedf1c793f1cfee9e7c32b458f7cbdb9e6ed60589c064c6bae4c18632c37f3d1b75936a39107d0e60a8d3c5b761df1d6c62515e65e6abba098dcba2eddf64134300943bebfd99bc7733dbb30c895a9ec061318e046e629d72fea547b7c044fc2986591725b4a7c54f1a1ae81a201a8b6b8d7bf0da907ad04d55b700e55b09f2e22085f185e24a4909d8f54760b649f4d0dedf1a354ffa66b0134c3767955ee67dbab92b0ab9d052853954c5253ea9c6aa72107929949e4d6a0045d52f86eb18d70a12c78b10c909ae466f7d8ddf6d3555c3b29e0c39a8872e10c1460bf4bc46ef552a6d7b35df511b36904d2b9ee6f6886e9dfe52ad3e5ce137d61b3fbc4a5ad0e74781d0e009edf108f98ca5e2ba9ad08c7835a5d90941ff2e9af53a52ea732fef8be155c77053215d7d8d90c54231afeb99d6301c4341b30badc329e96bb929b8b9ff9353fd32c59db8afb519f85f827b17b6e2f5f6f76392a5c2bc8322e478d4fb9a0095f9686c316a0bc9fde92827f7d77f7d39fdffff1d5dccdbf7e287573b9ec814c089d2d98e70d0b0ec9ff17ff5b1a22a26be23a8068ac3413cf464042d2993a5504dd0c89a418097699830dda95b8646c8907b8d8915c8e781dd04aea5ca2300298aeb9a428e83a4c320f1a7e34795892097f258ba8d3142796645c787c27412bcd9566fd4e854a012a981fcac9d9b0526b47a985604772b0523399262c3bb88c4e0c17a3dd2c53cf2d427d821a33184400d85340931a615a52b33532b9392fc3232adc75ccd6018e5a1077d883368207085c631ba565e02da00ab215aadd3b5443b099cddc1b7539f290838f05cd6ea53544a84f4982c05f9dde1c58538967129ec9933876cdc1bf6386f5df1a6f8ef4e347698d8a976050e51b63f8c31e658c037bb623d7a8d1c073d033580708a34923b55bee2e2141d8aed0b94c632927a34e810efb82defcd46d36fbdad3e517fadc3f3adcafea70ffe8297f0f3de5a56e72b98ffcf46ab0355f1f66c8dde57624b0fcf52b69f0139b0ce0a192a44d32d645132a69549a8dd7c372f6c17f97538c000d97dadefdc91c39cee919e6f56d5a5cdcf2a4ea5d4fa97743a4a0c61fea9262cdbcbf30a447f666c423d6675c251ddc3d35cac3f257c65ff12f9d4ea5d31f29fe1817dd90ce5be985f6fde9c561f0a77fb4ef6f6bdf5f6a8c975a62b319fec7875772301a5fef838218dd46d38e5c1bb57910f109068c2c7ba35e53f701d98d47599213381937ec431762c06f23076c56ea4c4c1364163e7bf8e8e5562395f600485ace8c8538014ee4e33b364be50a10938b0773a4d8ec21d288e07dfa9f4f67339b7d2fa201d98c8c5c69ec6d9fb5c3630dcd4dd58f6da4d8a4cf15e1ac0b43e243f0efe9888593407ced20e79591a7a429feeb0fae5c7a781a8f3ecbe90571f91f1fb6b68ae2c2a6a07cffe1871f5f8718fc9bc856114e328cdabc41882a031cbae5863037c34a6b7e5a74bd9671711727369936d948b95d83befa392ee4c29f7b72fafc12175247f5f20c9fbbb10c0c688d658d7859063625e58cdf13bb5bdb60777bc4e2be01ca7263e3486573bbe5568705032b837140b274301d1db1f9d5eca872dd0b357010dab240debc7bac1587a5ec9b086aebde1f7f812fce4652f3d4bea506948cb385f1c8edda6abb0898391652d1957ff817013357e9dc16685cda14e9b7a683bbeada5d95556bbf5a95f5265e55d4d12f6bc991752808c66d553a67bbf194ca51873dbeabd530462a7183d6389b5ff8754aa34e73a511a0fadfa0336e37e3560bbe9a06f10d43d2549a35c92c54f43b75455e475a8f8b6304f764a312f321535112dd07756b0d9677008f0e02869bcdd887bd43169296c3d2a6b3925a9e4ae3d02b59ee41c43a405d16073f95fce7f19dbf73cd6fef7aa0d6e5770a00f0908ee7523980991712d71b8c8bf8ad70da6ab2fc5a71db23d2d56ff2695807e643ae347e891d3376cbf0fb320be6e8c435e3d7fb429df17b83c88a91428a11654a450edc6a20aefa617ff6ade9e98b83ead6bff6b2345e54aa2e69543f3dfcf3a79ffff04aebabdf026d652595fbdc03fcb02f614202fae100d13f804ac77fe0b50397aa2b1890a90b311ca82456a8976559aa7e8c0d298ce4653ce0ec867e5457f5685f80c103a2db6a11090d6f9f7ef037c6bb4f45d90b21d07b217eaee02f51b09c84f60392b11109965b5e30059e088c334ba874a0f773bb08d8692e0d33ec9f87251916d26203cd307ff2928c0b8f1fb536c80cffe6aa846d1fe361d609433fb785594db3c47edc0011b081511b24d8c1360ddb832413278d437cc7f3b23e3c2fecf38ff401199f2ee455e5d948811360360e8e0acbf1ba4176c5cd5f6fb5524b229330a9252db0acf67da2bd3f6fdaf4b54d6bbfa2698f19c8378dfad2b6c4bfbcb3b8f6c6ed2ebc5cdceec6dfffe5a74f7f7e7ffd3a2edce3abfda2ac7bf58875aa07ccc7f8811f27febbf88137dc13692c8153dadb3183adfdf3be719fad3cf17e3f31791fa5dc67e9d4f6b9d2c096a68b24d6b010bbd6729b34ae78b870cc91a637df1cc97c94e06ac0bdf3b2fa4fa4d83a19c60925ac2fc6c5e53c9271a9a4e0db9a345d8f19de6d259d5e7aad285fb8383f518927967b2b278ef127da79fff47b519a47ffd99708ce62901d81a203157578aa4da3960d94f1d8dbd6ecb2d61f3f66e9de215a259f404108c22eef4c3352cc8a4e863f9e7e704359ae9e4e83d32052cb7369cd33ee4af15c5c7d49c81759bd20e5cbd597c4fcf6ad2d0288551a491462741206c8418644b81c400c8f2e9b762fdb0d6fdb322fe576b03fe5f2108338ec25178911002a159ed2206ddf83bed0ff431890e8a9dc746c82333a5f42e7830487382171cd2ea946fd7aca662fb34d299672f48f5a3c09bcff79af0392033e3cbac2d7f7aeda484f8f6b5e9eccb8fcf8113e4758e2b73728e5b72f4af9ed4b52fed6561bb5bb3ef56b3509d00e01de87c1046b97055304b3b2ea7e19c67013407980267bf087536433120f6c914b66cb2b364d4cdb485dc514df4a846462e6d762dfa4e9f1c08bd752ec9752460991e8a91cc013e53ffbf50bd64ff59aea372a704a6916a847bc706d2deac5d229a343ae3dd32bf6b6b7bd8fe8312cd4558b38298aea46cb372a8abf28c62f4af1b610ffe716dfe177f8cf5f5dd8fca5f1fa5f291c972c8857168c0b22b1250c0fafe3fcf60dfefa6e77b79e1a6a4830d1612fb77bad654c260dc2a613a37d07b3ba3f3401ab6ae2aad76807a980bcead411d9d99ab7e49cc91adccb916ecb9a00ee4db8f7ca0abb496f822561d349a28895b48e0d53b3b1776575c0b77d166a9a9f8a96b1fcc55ebe32e03464d82d28b9750071a124a35019b8527325d10c96a21aec8480205b964c7d8c922042d64985e39974f6fc03f285bf5c8bf309e7f79e5bf27c13524bbecb8a31f20d726444cbc633f9ecf9c78fd22595ffbce5bfd8411eb69ddc1eb61cdcdefff19568b8bec9373fc884b45077e5d2a8a12aaac58a6a4fcb61f50606d167b9064ef21578264b8e11cfbb95c051a0128f03331380c907cdb697495ddc74eb3db54e151cc7431317808455259d8fef6c56ec995deb301a020e6db1a0256d0de161d21780bd6a07573b59c36393f7861830acf6f5c020aff818bc019ec4e3a696096a4c2fe155e5762a782d231009d722046506b7b2cfb3c3b18a7b4b1d915f1de83c0f1dee26f1c7fa3faf27f3fa475eff005efe041b2bd74ed20e3ea04c4d0a0abde1afad42227b76e395b4e541023ec770de680b82f50dc083a7d21807af46309cb71af4d04656b1a8e30677b7780e5c66f3e0afc87845bc39e3cd6e020032bc5956177c1ed15b14116d751eaa90690edc62b09bbaa12f7b21e66c242335e299e16bc38564443218010075988438627990ef3c209b846c1272f779cff6086504c5831287310ceae06571f56237f49eb5d50ffdfc6647fcf387371735305bb251ee55ca2d7c7955cec06b3f73b5bce67e39e8c8c6f56c47adf2f871620ab967194795eb351249c527fda320a27e0be5f63e7343212e42e43ebefb65e85d50616c63eff2523e19234b19a7a034057cb40ff5cb2627806f6c5cbcba6c8e6aa87971392f215d019b73f9fa1af2a50070c6f9c8f9dec6c290b779353635b53f3153686c771e6ddcdbb870f105d9fdf3874d67155cd892defb7f3adcfd9d72ecbb3e2a4b084078d49ff18f3f3ce31f7f4e5cfe9cb7fcf163509c7f6b3617db2c9a60b3d5e2d266bbfdaf4f87c3871f7ff82ffff1fe75cca6bf71ebbd1b03ccc6258bd7222b05d75352c5c2502657105a662c1f098e2328e0fb591b249587672de119d2c834c3faa196079662e12e8fcc018715a98a90e51a367a3ff9e63f2ccef93d5cf31f3f8a5840ecb9f9248c195eb03c14a03f3e68eee33c98b4bd6025c277414e137b95aeca9ee79bdee2b7bf20c66712b92dcc67376c8af4dfa31c6314e236f6317a3c1f211e9e0f11cf8796f46c68013b52e2099ec70b4236655bc83049c978c5116cbbbdb71af9e3a79ffee3ad59f6fea81b2dd36e11e1b419c3a472750a5c02ec45c001b7a31a4ddbf340b8580341af18f1fcffd97bbbe54872dd5cf455f8002282004190bc6cebfce8426d3bf6c4d18ef09d9c6eaf9ae3d2f4726b463e4b4f7f021fb24a257596a67b7a696d6ddb31d359a9fc616692200910c0f7f98e36c4e071753373b8367d387853a5ec4ccb439e23c2f8e0fb21637f1e0af09d28c0ef478e5b4b8763112c05321053e857a60f2c03c96fa97cdbd18f8814f7bf2205798d1a3b090ccb6cf7cf28b36efc06d701dfdf1dfe19d3aecac37910ac90bf4d69f5135b02fbcbe72fb76f3332fd80c4627d3014fb73017daa3b6f6cac1b6e6011dc4d7379f8e3f72312f87fe50b0c1fc8ce6438fe6405a1a7bebd479fb33595f2987ff804a191919977a6a086245f6c7fac200d647cdffe58416e710533ed0f1604f4c9c0a0fcb18230b6a4d8bae5e9e5f88ee9fd777e594c9098b6ed902ffa55190dec4272c8273e2d22f940dde4acd4bc266fddaea69de6df9ece00674bbc623b2fc00b92ce8b04f969709fa689d45c60ecf3b997390bacc2f67d98235e1b48e3f50a8b77294702d6e05ffd4395a5af2882183137c7589cd91a64bf2cbfbd915af0231e7a37418a9bee70cac33d3f5c176fe1222ec4099816349212f8355227c9f0eb2bf550d2eaa49115d9919504ab7834bda2c399894028a620b9da218bea5264aece214efe4fa4a64963c94853f7474e327f44cd52425f1f973c7a6a460191579fa2d8ee3396db807ea57ebd5e76a506ae8e649d1428d0c994a63f2459c5e700d86c066a82a472c542fdb221c09f40a5ea4faaf065229c6bcd9fef9c54d31492c54b15b83a2b4daf98d4fc35616fc0ae7119ae81835b80e637a801600b7c5c3381bd53811e50ca81cbebdbc20baa3d54fb8ee8996abbc002fdd6f08a6a0f2e06b6d8eaa96e201aed1cef9df1de8f7719a36b4810a7673eb4fb577c68cf7d6fe77b1abacd664fc399ad9ef6eba7cfef2ea2b821907a5c48a151a463a5de4a6ff3a20eea454c7355aaa58b5e3033f5c2bd6663aaa5325ff0e8d44be9fdc268ce31eb855099b5cb85ebcd45e5422f5cbb2ed6ea45a336ab0d50341ab77171dc2917e5822f26e91c4d2f446896c8ace762172a24d36acb43c866d17e0194c1d932ab90f6c1f34258494b75fb7cce39f482f11a35b3ff6df34210b836e76c7a0154bbd93ef0541ab5a85d3cedf97bf045eb5446bbe03e49b994b9a0d496f942484b1b234b94a23dd70b636a734ecd6dd22c4de705bb30f6ea13a4f7faa2bde2156baf5ae3b5e71054c45a0dc74ac0c74b57d4c61c63f1c26be38be65f64e3f0dc0b70c85543adcaf45ac67597b54faa3a785cd446a5346b178aa5f9d2f582856a91c1173a9958fa54ea650a7f60231e55dac571275ee7857cfcd3c7eaa348e30b84421729fd0370624651be78daf35bcb05a2a77b31be501d540aaa1a887fadd793bd82ffbe2af99feef2b14420e5cf6941ffec57adbf68b0bcfe75b80a3e2f97e1f8894f797a1b19fe36a2fd9fee0ec5f4e937de023cbfb77671dc89f20f7fc6ce1c5e5f4567477dc5cea1f92a4d6b9d2faaf94358fb3f9d1d437c40d81c42fcc4c608f2f3f2e5f3b2fbf98d724b7e80eb800d0e0b3ee788b8723de79c7fe10992eda57b4144cff92ddc8469e381e5d6d281e2dd92ed328f077b794ce5668c9d9e5c9b2cd983ed783c3fb492c77d6ba9f04dfce72bf6632da976dba93ce8b8aae5b4a86c0fd9aeece5217e566cf6421fb23d3ff67857f2fcaf5deab991e0d0b1b70683c3b933e3c19f779f7ff9f461ffeb4ffbdbfb77b75662ae1e4bd23688af115c6ea956372f2f758014a532b8f2c13e37d40d23ec367bf2dc7d651a9d35fbe060e44e53b28fc2ae670f048f0948e98117d822fe56964a9c27120480584522b12b93acefb256b2becf8a8c0ab9d230f4767934aa1561ebc1048ddc266a63dd05ff9a2b9da450c0470618b29ff96b95b10005ad4818921986649e76eff6fde1908f0bdaa8dab536527090f7cb3a7c74152a20a1d69a11044dc56d0a1ed7c81dad4cda2ee322bf5efc2245c6955fe426c9dcb701827a6de04d346fb5862cc24ec5ad12463aa65a161abce749a6591a495f1a29a8d2bb5f656ef017c981ad2ba4ed11bc1d6abacb2e01b582d086a973666472555a2315aa37701e5406f00ab1441b2110dd5bccb54fa68118300086b546a3b921d1f274c173b3d02ac07f7904a17703b1b12853e507a3d19602383124cacc9ed826b596b849e2c164f3667dd1b379bddb0b096ce5cc42c299dce157878d67fdffdcf8f1eca2df1948de2610b4fdf1dcb20adfcbef75fbee7ddd940004ae8067d6427d22d4a98ecbe992e1d39a773a1da9722766a815ad50bd89d586ef5964d242d1c4bf272358db7a5b1179ea2ffd5246035128a3d70216559526f65e1b581f3f7237bfeacc62d50f8d5bd2e587c7bebf521967c6cf9f4659d70a47a855407ede5a43fca6fef87b5df1b55ef8eee7f27de6d67d6e15a66998cb8d3197735de7f2e6f3cabb98cbc3b1f85f68caec3e655ac42888f8bca7d44067e05d20a8930b31fb9cd9eb7fd539f3f727ccdf9d2ddfdb54f9faf87dbe1f7cc7d077c70626e7ff9e8edf7c3afe5d097e5578cfc8edfdf2f9cfef0e3e800d4ed51dcbd926d0f32db0e3b360bba667424acec3f4989e178e7300c108963b471251d670012699973a2b8926e54a7346d6bb4d92d8430a35974663e401666c9ec77f0fa60bc86156776febaeddf81ecbb8cfc73ff37ae815d0d974863862bb8ad31994d8bb5c0db14fde55a16a9534a0861d68c857152c5433fc77c54597d0cb4a1e294e80e07c29a0454f713f48ce5f937f88f139f9c7c92df9ffe5b7fbcb9fbf2cef0f3f439a21da6de2d3e3f79ba2dd668d2bd378fcc8a249e689abeec96ff6c4a9f7e4becb2c3b313d7ade9e9c75478ab627675c02dafb79c7f353d56e36caf1ec9956f9e9df7fbbfdf236adf2831ca255ae745c82d413d1110df4a9699487dabe970ff49806f0820ef4e394376db8793e7cf0a9f2cfb55b9c3dd36eefaec580b8305e039faf720e0cbf0e3d338fac211e9ba0edafd5ecb93addaacd5f7f7d23e2e41f6174b49194ed6acdbe384c8972a4478fb91a010627587198470ed3883c31a4c78c9ba380432859737b63122f20ba42866036245ccf3c0b711a30f60acd240d061d207210b599bb5f38a3673464b10bacc4715995c4fb25a0fa24cde11a1752bf8df4bab9695487ee6a99fb2ed4f2e88b0875bc44e219af30dcac2cafe006a0d5365bd94f6c34f3e77ffe79ff768b6cf2c709b1ba00a73e46ba1261cc31829db8f55e0c7407f7dc5703ddd1a3f772a003a8dcf8f17c8e3bc47994b135da59d91a486fac6c8ea3a56c8da3f51578cb43136e35fbe1dcb996ffef667f932078d4edd9f6d86a8c5f3efde5ef7edeefdfaa27fe48aa7b0313d50e6326784b5ee8d03bd0620e806fb89502f4cb75fda672522a759fb9f9e4c585446e3bcde9cafe5c892781d205e047a4928e0826e3afaf8b4b925fbd27ed992adfacaff6ad4afccef45b6d83c78f5646327d25da5fce12d9b47e96c8e66c5ac1e34797e7523035057cdf13374860d05db99d53b2c8818f65292bc4dfe1a235330779f13c65c9ebda4b9e8645b6e63bcc7ec498c661b9d18fc489fb096a2dd6342d31bb76625885d38a68b6381a0f0850d5e081a92d5ef4485902aa18bceb0abf78cc69c2454f7c32677bd153a7d8ec4b4fa75fe951fff3f6e1cde6b71f59bc167683b629a95db62158b705815ad34a0dca7d2b807f86ee28954012cbe0a1725914aa9add586f87fd12ee070b084b02703272b42b75176ced990104331bbc97408b8edd4b6e5434f5e9820dd402ef6c85063f54ee24e07c015642270143b981f0c30d3c7c41f773da2b0d4ed3481b50dfb83612ec2ef10500c0357f5b03b302de9f0f7fc407247c40f20f48f80024bd7927d60e7440ff80c491828f146eecf66043aa0228dd4ae887be5f9906df8c4ab3826e37fb87a86b7d9a4503e86d4093d3fef811a89a4d02f96406f4897711c45f4e4beb822580e3d11970f8fef982e5ba5859013f5fbd63e1f0ef4afa2aacaf49fb7ac9ef48fc7f8bfb7f8bfb3789bbfa640b6c88005546bd28fb2ee06c4cfc5d06cd7a094ae495111a75c7feba582c8fbd876cc50bbd2b49467bc8daa98fa52a216bdd8478243767fa4a5366ae248850abd9df39bb2400ed81332ef0cf3279e32e89794cf0a680d492ac54a75fd55d7646cb4da94a1ea49a1abc5106a40fb7c7b4b9b61217e824190fad53174c7bd58879093175f10450d330aff80e4f16031035102834898b4b1daedf98cb1cae8010da830e1ae7312a4efbfdef8d1caf0c1bef6ec8f8df5df9eaf68612abe36fa179bd264e6744e972f769f9b7f7a87095914e337731e63f25963dd471ce65f29a389df5e7acb12bd2698c9b8aecafa37991609e3cb75a8e7687db222433108a66f6a322243dab8f4d95a97660cd371f53b2d0ac5989f3a0de3335e005b2ee99c1e8ce24bc08a893e083f4a108f4be5c886b069c188d9ec4df029840987a1834f1bebb93e1a35818d7cc3472f3790a7b5c43b61be898402cc2c4335e85857add67c5dcd490d1dc666efe3995f15115d5817dad5467201c34d09b94e63d47d5bb8301efa0f41b6e7288a1399878194832077bee68e63d4415a206fd102a3029354070ba75ca9880c96dc9896887e46fed135ed45f4605063afde255069005cdf00e7b0d66d420b0db30279056802a65281fa840ecee72d46046157ab1237915c6de5a857ec45fc738a10af13229aa50a10fb4051598bc02132a0d8049b2eeaf15e88a4a0bfa819650811915882c739fecd9528545f74216afb0dabf298b5b55ceb259e70770940d511fe5db8b1fe54ce9059ca33ff6ee608bda2afdb5a1f030a69d1b0e0fe75f1b12dfdb7818e4bddf3fe2b18cabe293efe39d2a40963653f277f32439f5c4b1fb94cd7aead1650bb6fba39ffbc4090e3ed83bd7c7cb77c8e2869c683b2727009d128ce52fcbaf45bfb5fc2ee78abf8be9fceb97efdb83d77715fed1447d6663bb448d46e2f4a448311f0f00432837df1bd47114dc57857e53e27fbbfbf4cbbbe3b283eb48c7f9709d7369d66e797c579af5e31d127b2d5775531209628176b8821de649c23e4aab5e4b5917490f4443f9890b29760f8c20b91b59f20d9f293245912086b29d34dbc3fab05cb991d8e347d1926ae984353df2d90c29c423b8b37db30343f782332588ce6de5d6c6e601c823705c683a9c792a6387bb71330ea6c313b079f07b5f1138c8cdb6b8e1d496b07d7e1b1fe58f844e8c4ac21ccc118366f09635a6d261564e7193cf6df09ea7529f6e69171bae379591c9ea44640b52c19b21d71c44354a52aa4ffbd6344b756d0349c6addbf14f9e46b379db7537ea8345c08ffb6f6d813d3b47e6ee562e78cd0760a161ef0bc2577976575d1aa068a57e9036889ba5c3efca43ba7e6659322b530d38d56689d9152dc6bee0f2c3f9f54c3a9c91f6caf0f379d38df9f9f3a613f3cbafb75ffef1d3fdafef2f90a61576ebde0a4df6295524638bd47dce8a2e3e5dbf6f9d586f6b239b96d69fe8dbb563b98c6abf96060f085bd9b948d5be9f93cac8be05cce90a0bf5bd835c44b915440117c0e117624e2c0c1c5437bba1d576a0860ec0197449d568b8d63e5b6a836c6626b53409847d45130f901519951efb3bb0052e5ca80436bbebaba0fa0a3a5a5c94ab5793b05b2bae8e038377483c28e341972a93dc5eb708d22cc8e29a03bbd2f041df37689f15c427d9da14c8a7d35b8279ffefbfbdbbb5d8707d9ed1fcec5cc8c90d5b39287ead4fd4dd449ce3400c789d4950ad2eadbaeeb74193dd4414bf4a99faccb3fa7620909e4568faf1a9598c14c0e556bd2fb80dc94c080726916b2dc527c1412c2e601d5c0dfe7240d2ea0521f01396196e4bb8ed526a45902f30f5c04fdab1bc06e658f15eb3848fb9bb4d3c01cb0c87a70b0f5e7f579b4bffe3ba8250aee0553b13ccc37256a7aeb2869c9c9c3d7a99ef0fe5c4c50fb14293911b12d9c758f3c95dee11759774a42e0f5d70d9f7147b1626e906f1636716334c53f969c5e3c1dadb8e65c4621ad693f2b4d89eef47de15367b909fd8ea3bbf7efeb2fce5ad62237fa0ffb4a0d2811428cd4c9c6502fea5bab9ed7ad1bcd6dac912ab5e35290bc0518edc8f41fd78035f7a60be14ea47dec75dd6464882407c93df29c1873152a7b90f6a55ef4b3e3f8f5cc7659de02a03a3d450025f59ed06ba02b7bc3742a50e61cdcf43a5cc48f7c06ea97225d2694688448e3c47ff5a2d3ed9f8ef55176a976d262e9a1470938ca80c10a42d5e2e3cfed37596a009add476cd9603d30108b2fc02ed019333b0f052414fb064aeb1c66500a9ec3e4e00befdb2011166026805e03713113395fb821c1310b835035c26474872e5d4e22a2ed3cb2a504a5d64774349bc89c25d4306d6323452f3b6f52fef6084a386d12b586858dade27717fd9816031f30fc46a5500e678858129caaf32b08aa1b611abe2db11b0e7a93319e840260d1ffb1a76fd119338070b8ef909cb7e9b028542b03f1f3ffaf76929dfc2d5b080a03e0d0294a8bf165fcf09fee188320743140de81f49805263bbc12e8f0c02b311ecee86c108903fe3f14ecddba937b205a4407e41ae2df51a2c8d2df9c6959d00497219058a4bec75702440e9f5578bb601a1456bc47b9d7e5cc80df196a25bb9595112b2aada1e98a88364e920b2722d37e39206628c3dd2847c66994b20a4b24b1d3c818911a5e7dfd3c8323118ff5d3225e1b586523d3fa61d86a8cd71ed70726b6cfbed975f6fdf888bfa8732ead4553735a1becf3246561d9755d9b5b516295babd372859c93e3297453cc3671ab1bdbb76065e5b4fe8436cb707409990677aba6f527ec8a0a553b56a0983a079982aed0ef32a84c40cf7718c1a3a6f5e7a9f05c8340d85f7132f1b8d6d270b3e85595b25ffd2475801bdbb7d7c76bcfb77534d9664bc7a9cd76befff48f9f7ffee5d7b7e27effe39176b5b8663d53f53146ecca2d472ea0851b3e68fab831eb52698c9926a98c4c2dbc9573ce3c491503fa9c739fd5f54184e5a9f425c75f1a4b1c3553ebec3348ad922775d63ddc5fadc600572d0f23334dc3ff1a973ca88b4f0a12edefc34b73a336a9769abddff02099f3b224b711408d3a85b35171d3a990f49e9a3f7a2f3ec0b02499424dc5454a3bfc17dc67aa540a965158e1266febfe2b42706ccf6d41389e3e230cef6d550c8ef55bb6b2921021c82efeda997e7d22b315502c96707021edeec3f3cbb00f15b1dbe39d8eb8e881278eb805f6e206e0a2bd5ae7e72a7ba3967ffbd3d5e77747c110d33cabb9ed4b35b9b204ef4f83e2e56a11fbb9492b74b781538a4157e7f6f008ba27d09636b0021a59ee400df42994359434cbd5154a2809ad52bbe483c729716950defd115703d07f050a915510f819e8c9c65283f76e261ec9fc6531dd43ad442c32c2d15d89753dc58766b0b322023a95bff1d789d4f5eb24826d0a54dd5d0e856686dedb83a2108baafe557ff00b917ec353ae9ed1089c20733f041069ab49eb337ccfa5d535f9b5aec8056c8b7154074b8e251706fcfb3dfecaeb5f19a196d11fb17c11f71ea39d4f22a1ef4f229f5d2b3bd79fd041b63a144e6cf5a8fb9f97f7d6a1b417aa233135bee65648394dfb50e580185bd64444a3c60f624cca1fb8cec4709396c0a605c199374d06400099374d32bd57449b60dfdb0ba7122cdc1b80e6c95e9ae5de1e782819df82013cc5765db2034840fde6e2db5a7c95db938f708bc724d7427a3efcc79b67b339ef7f5ebe6ecdbffff4eb7f7cfef26ffff3e72f9ffee5dda99f5a92989e4d62beaaaa0f59cbae9f5fc338b78471856098ef5fb5e9f2a0e5155cdf7309da45fd3efb43cf643b878afcca1a4d64786bd9553c3a200dfed6cfe6a29bcbae2be7958c1b0bd220d32b69f678e7aa78957235918fb59b86d0a5da0027feece019f13f95e78d5e707a7aab33fcf6569af90f420d07c5519fd440fb9857da47fff7132671c4e3747b1d29d7c637c3dedec41ac0ef20d8b26a1adfb4d2f0475821a339365bf1b74d95faef3ffdc7fd9f6ffffc464dd8fa1f260b694d92e9d5184be64ad21a829b40c4adcdf7441fc61546a473a7810be4c6cc14d0ca952ea959fcbfd32e273894a7d896c75545692d1f0b8cff1f3f364b5acaed008749499c471e37acba637b101da727d278bc931a08172b67baf4430e1b806c231d7844169bb8c51587d74c366eb2ac37452e5bed75cd665bc5527a3e1c8ddb1eefa4b8765a75fcad1e98a58c3cff737f63f9dd0f3c005b7ffdc06ae5dc030f68db5f3ff16cff5ebbeb66175fcf6df4f2cfbffe9ffffedb1b315cfe786ef7f7a768efdc961963df905665468317afc1dc816f434501aa6459560e58add7ca0d885654175ce6553ed6cb70875fa6c9efb8ae9126c72c7f2cef5c8a52b3bd1b60cd0d963f564a6ba4739ff191293e1272923a1856e11eeec0b1a2195853f5da147c997d414d34a8f8fe89a894b8069572cd3eeb890f6600a0fcee26b812ad54da1e9fe8dd43cfbb800ff2b725b5eba94da1fd74fff1d3bffcbcbc91e0fe4828543dba86227efc84672c07a3595a8f44d47b64e322007fb4351458cee34dc818dbf9b8c826dc4ec89dde984f7eb2b4fac992e8fd89cf2cb627feb2b4eec6098030d7b2065be7ea567dc49f360b288a17871559abba06d559c4d4350be5f9ab13ba26bf261c41049febbdcdbe3aac00a059c3fa0c517dcd76cdbe3a1a1905b16ef0ecdd8ec034cf5f81bf7ed61a44f8acd85785f92897db027d3cfdb550ffc33fffbf9f965fffef2f9f7f7b7f88df0326ffcdb49d9cce58a753d38dea619a3b9dfec0e1f07c763c9d051fc4edb8f3f75eb15cc64322f2b263df67969319f274e24c48f37f4028819c7deaf97bf5dcf73d6429bb3af441fec8bd4f3ac0579513ccb18f1fa725e976c3e7d505b6714e5de00309c757fac21597b3ba5090caceb3b74ab5f36a4d132c15ac2af6c1fdae2d468b87dc6537f495f73dd7894efac1461f3a397bae0bfd3fbffce9ed3ad11f375bc2187f901758ed5f638bb797d8e26237f3abeb6eea7871597b09f62ee6b3c5375cd8bec29497702988fdee95cf8ff8fb8b5d993edee928d91410ae27c594f4f21b8bdfb57b71046f7fa5653cb8189d4a593a4a991b7248137b66901de7b200773b31019f596c0f795cf144904f3e7dbdfce22b8b7ff6eef981f848afdb87e75fb679e5d79f2a76f34a74e633213edb03d6f31b7de0e7fde5edfb737e23a290ad50e56be8f6a201e53d017caab7a6547a8aed8a5b31c8241b75bb9251c067d0ce051e9e5bd4449ee0772d2e361042e766d7b5235dcbb5eb88330fbf46bc5ca33e33b57ac90af5dcd664371e852ad67fe6a0aa0f53693697d1466a80d8c0727517d7ed04e9463aae5db3aa9dd47bf5d94c39e94a569741e8096cd45b469a9220676a52e3bdb090581656ea6d61c461b811505dfb41226cd5dcc8ecc62713b7151a55dfb8a14e8c4ec43377b21933d218018c8f08eafa90cdcd84bd8e843ff1d7e39db6ea6f3a940c2832959a259ec469cd907adade47d2d9d3c948a2faa94d8965bdf8bd5f73ab8ca9af9724e0409fed3510fbadee82131bfde4eebd6959d50a198299f5960be082b15d5d2e4add52d9239c121abe6d5c85d89ceeb2db2209af40d72ec3371d88d987ddb5bc1cf199670b8c07e3b1e110b3c78fca8200e629009d34242a32d2ea0ad5997b214336bfb47d1625f15199a4017c782443fc69f35d840a49d8a285da9528e2971b4c6ef66773cf3afc699d7acdbd9120a48f5d281ac29eaae56ec49cc7a426795430ba9a4b73a359fd6d2652eff3342a8cee3772f76e6a342dd09691b79f909a2f4ab3eec50b7021b6ba34efaf2b41b4b9bd5ce1c4944cc20921b28698392ac041e81c7112eb3e626f61aee1e9ec767fec1ffc8a1a265c1cda81d60829aa4866e6493dc8e806ec6c44fcc9d8b35199a90a715fc4cb6c3eb6743752bce68090e063c5ae562a7509de6b0cb05105ebae9ba4fe274776731c5a505502ad4fa8224ddfbf4d1b306e844acd30eebbb7814bc801925da97b658b5c667f3d700521ccdd3b06b749532379a3509be149c482cb01d0148f91e1c33f72585d6010f487184dcea63b61b2b9ac72972077409f9809729743ee2070217c0b0a31c8a74b9d5fdd92c4228fef7a158f20e11e11513fd77d6c6f6a706056c81ed247457315d4a4e63a61489af968e60fd43c1052af426366540eb00d5849b2b87003a5ae51911b65bb2fe1abf40a375d7410c271700085f7757f8c1b994c58846e18b25509e90923b633f61fef1481fd2c801fcfa3f994610d18b3366359a837e0e7b541c5c5b74856c0784462ab578d1462f5f66d2e804a5332f025205a193d8131ab9371129a2d69c112944f32891901b0d8ef485a2869a2e755f6aec70559d4b5a39c4039771171a9d240e768351b8d1a489a8cbc056ec4e05634e80d6b2af4d949e16e6b42b8db980c7e7d2b57d50f27d5ef72957da8b1b1fd1060d7b18d21ba71279da95ce90c4e3f06a5bd004a832688d27af391aa5e576051b98273c93a23961f1c9603e30d56a7c683b7e9020014971303be0824bd2196634cef073c11b68b00134e5a7d6e11245d77467a5ab754c1c729345dfe7a1ae24a8fef5ead090e1b4b8bf72fd713d730eb7acc5eeda1deddafbb6b56acc8b68374550fb7578b4df75e0f3af328d4ae550182b93b038ffc6a513248648fb85a066ba9f07513b4064fb96aaae7b0dacf231d80c797b7d37def9f67f93ecfec7d9e31ec963e9abd2a4dbbd612c0975e2a84ab030bb3b56b0cd32cbbdea9b430fe7d6e6cc8441239b0a2b75700fad099b63adeaf9b7ec67ff8edd77f79ab94d61f704070f1412655ab403b280889ee5439500db08b787abe01803e1a0ef967b5faa45e399f5cb30fca89db68baa7d83c40f0681500aff2b3f3c7a4b267371dd9895f1c5dd3af5e14102d8f4e22e34a8ad2a81f028022b6ebed53522d85467da86eb56c5c12f7a6da6427b56c5fe3b55deb24eec864ddbea636b05f8c589bfdbdb702c4ebefbe9588befe568298d4df7d2bb612ad818cef0fcf1b4bc777b4c58d8e8da638d761a2076c759938f375a7f9c7db3fbd9563fe07968915a042e6c67c3834b0e4e1fb0fd2ecf46860feecead01747b3e90dcb785142360d5cd16ae36a9493aae57c1c974f8fae33c2288f7740c9b717b70014615d54785e5eb4eaca7c21e324628c57daf3692f0ee6c83e3b3d1a13d9ae4a7971f49571136dba210438be25023ffff2ebdf7df9ed8db8837e88e0011ec65a26555db202fb0cf64b37375422ad7176680a423503b1cd48388f340198a96e1dc42ebbf1577cd65143221000bea421c7a55d7ae79d3e4bd5eee332e62f196163341a118a03141ca0be0c70f4025aa7fa340dd02657a569f63c89eb3e0f37c4907fa38f1fb575e4642c503d418f000856a3cefe65e20243da2ec595b39e7842bf460664a950847db7f5488644225485410cf56800256850df1bf8965a251e0be0e70061a36e48bbfd06eef019bb06eb1bea34730efe228c7096a519a9cffd358c45e0db4c7fe7b1ee6aa3392fbd9a0456baa28a0e9f795e360fc2b629a0879367a4f47f7cdeefdfe170c5113577de8f7dc4b35ad741b057e5011e93ed3cd4764ea9750d2c9b9e86079e9e464e60b35348b153dcb18757a2045e09383c9f707c3ede102bf6aed26cebaa0f27c868a7a067f97c18e1890c9c939e38bb253efb4fbffefaee80075cefa8a901b571265164347a7f8de3149d5f975c7be2e126337bbf17f30b9b9b44b518f5a44c12681f1cd1f9400c6e79f2312db491fa4098e7a0403ac0deae4fea4b6d887237a5203ff3bd99ad51bd6cccd4928fb13e671223832cadef8da5dd2a7f05647600178cbf02c2bb8cbcc6f3fe6839e9af50ce594186346e0a31ce6c0af0fed3bbc3eb038d5b3bc2efbc606f38d2253d236fb8aa03a3d7de3b3bc6b254e5a604d9f7461274d024bdcc82865fd087dd4dd688037ec4f307af01e22f1f7080db789e65ad887ffeae5bac7cc7dbecb20e444e072912a27dae58e2185b418c3592aeae6a93d3a3e7856aff694bf98f135b22f5e74f5ffe717ffb468c743f943862aedc5c47e6762f64c0264446b0ba0275c87d26491a1772aa6d90ee657457045b255990ce4c33ade9f9ae25f9bf7acddd9296fe300ab5f033c199d652159a1839933fe45a862415db33b0859b902c587145fea266bfb8622557f65db256b96cdc52a7917456c2aa635abfe57cab1d1a61b3e50e27cfb4deb27f235aff1f89b8ac246a49cd885596dcc080698564ccdc3a5565f0803676ddb40ecb82d53fbe96a654a7a4aa8b2a5536802cf8f8ca46b571fc6970ff5a249d5610012a8da9fec704fc7da72af009989074bb962a24aca98e4a9865a0c602dbb9d59efb20737da61033672e9de6904c7346c65b070cf3c4c25635b0c768af89499b642e46b3d53dbb5da035b31a8dda16231e029464450a1d637a1689a51acb24ca7b111ac6d0c8fb5cfcaa06ee4f49716ddce897aeb75d7347f26eaa48a6ed8b8b770d3ce8961b4945261fd2804d4742062e3c4ef03b1996d349b425a5eed5dfc8c620b6b6e7213474661e46a3f1c2938c6b9642c5e0a4f2bf9a509796a930e72ed4276853794cff31e95927cd06afac55002270d354ae27bc2a322bc96c8b1b5cddaa77e166ae00ca9c695678158827b020a8724d155ea4daa8cc9ac6a0399affc5ae0c49a5d206c9b03d77a16299bb5b245e8fdc3baa7ea2068bffa1b53e557d33547d47406b0527965f8c1bbdeaabae371200b070db3ec763523c662cb94d6a3dfcac6e24b506e97339e7d571de33e968aff67cefc0e73abe9fdbeaf75f6e97dd6fbf7efabbcfffdf7b1bb75d599c5e43c82e07d684f72ecd5c0503f7a08a6dbfacb3a4d6a0ba1afa77f8f8102c3488af2bf23aab30b525bb2a0bd48891995aee118eb043b4ea941db35cd6a1a9fb785bddbe4e2550cd7e723dae07860700d0fdda07102b82e810ca5d4b3433f03ca85d5b0fd8982bc0e6742f4b2c733582bdac10b37ed991cfe3f74f92342735608fb405c0151380f02361293071dfb961ee657460cccd2513a06a8169116817f0b63e9960fd44a74c01e4b3842efa5cc95ced2fa19981bfa25e54f60ad4816ce629fef065d28ae425b92380068ed0f3a2f924639bd2f9747a5b40fff4e5f6cf6fb39cf4231313029f9f2fbe1ed7f0fc848dad335f5def9a2d5c20f25db7d426eb99a7b47a866d5176a25b6b87afb40e2af84cd3e0dc66bbfcdbcfbffce9ddb5cadf8a2e11b89a52d0d400d55d35f21374db2a4fdafe93b27ec3ba92d03d59002b786e1304724d73e5832397fc3eaffb79e53ec6fa2f1e0b6d1f2b29c77eac27ae4afd5d7ec0b50db71bdecf6c35fbfd3dfe7c67edce328322c37615086fe08915109b1b35cd0df0dfae6f33f04ee107eb884811908a170182eecccdf57b5cf278e7f5bab84a912a93eb5b0d88dc9db8a7a7eb722783eee27a832b354037c752e7e169bb5c03aed16d30194636974ee63385024eaa7757645480f15da145ce5d76fdaf2f11a7a624c02eea2d7557bb70a5265cf9f8514a01a05db75ddc9485cc32ee42549366dc954fcacf3e05f80bb862d6876b485af369b1770604752e42ca0b6a0cee7e45a810e24078a2269e7da6cf5b3a13aa3f63711dd51f15b2d62d163acb95e96524c347066dec1db1f94f980ec23703f7ccd9d5ccf38ba68f7779947067f266b7bc7fd619579ffdc1b52d4f9eeda70efe7897831b6b4164d9445812b0bc2ae79504f9276ec0fa3505e289e9fd4a9b7cc0283bdc70ca9afc78a74c6540eb5376311988e232c0c3c346ad239dd4e52af2aeb2238e45244350812fdaf353f39c1f08a2576f8e04716a7328f8f5f65f6fbffc7cfbcbcff76f13b6f843a1bd0af02a756158729588ca6908eaaa961087d5919c064f49e4d5b941d3d005048345d0152830fa2b3421c91570548546cd13bdbc816201fbd5658e2bb1ab958aa0aff0becf8670d196047d90262774b646dd4d853af2a0d62f5b2920682feac3426370e65457a15d7163596aa5e93da41520b2225ad160b0a8d04090640358965b8a98b418519453d77d04eb3c2546ac81e99170f59436bce4f541190f4a7850c683121e84984d287eae8827949df19c759f21d500b2d5910de0c6b363302a4c93f7dc576f59bbd4d110e0e9420b836176a0d23222cfb657f5ef5fb822c28be58338dea1c5f28e816f45788f059f965cf15ebc7ae6c80ac03ab729a87186870abbf7886e9b11a274705cb54311d98bb89486aa18c0806c963a5c8bbef73d2fec753ca08e5832a4db1544db55b2a89e84ea6175c33a4941baa7d792d7b869e23200619fcdbf194c1388a32e359f34f965571a2349084beb342d4941d28294b2e6223c65a3afc9e8f707e988ff977804fa81a606d7df536b5ffa405331af89a4ae88c461c10bbad462e500688d87e8cc00b3e48e805d9734b7ff93bad8363243974803e426053350f42cf51695492dfa1462b55b4688a9149fce7a04b047a74cd12911a75b3139fb9c803041efd4393a350faf3016426864176fb7293136e4756c80975341f3014e8e883d6210a9d442b3e3a48fcf3e560cb07a601b27fd42ff1c368c1eb0c634fbd459d94be6883d042b1a50fc6b410049a1818542855b3492027a38fdbc0b9200337176f05701600f0a88aaab321318cab526ac7321445e7df801710cfac9849a384145028a308c85ae468197a482854c10716a0c972f029f119e5781b9c723cd4203eb7116bbdf284e06e250efe9a5e531c87cecea3ee002204e93ab48b42e402544ab49a136b07bef153a3352070a5a82582f6b2b211335a8e6d8dfc9079155af5cbe75ec931efda915afad5611e15b7c5af52f640086ce0c990edd29faaf890f67ae1b7805a94b70459074f10e0bbe97a8e406b4640eb46dd7635a89464ad148c3bfb6522ca98d14d1d51252e6bb1c41ca75207c975df78090e41012a4580349be4550369ab985ace555d60e120d97bf7457d85651ce21ad0a5d0f6b1450a50d6337eadd2f1b8fab05ec7a921c6300c7490ce0781903389e6200c7490c2060e3cb0f97735eb7395153b6359c930bb6f59cb7f169fc90bd33120fcc353e414fcc7822195821b9d98eabdd204b791b176407d46dbe84eb3534cbe1c35a2503731f9614eedd7c389ecdadc52873257ab966b505a39660bfa4660f15199f6b7adb694e5c12dd71d11b1e1afe59d5b3f973f72f93e65ea6c93d834d4112380fdf1d0061f259ed5cfadd9557dad9f4bb9ba8d267af7f7c8857e90397436a9f9f1ec76f7bbce312f0a26dde48b340329ab6333f721b971d5663bc27bbc230f7d6682aa7f8b915a55290e951ca21360b162c6e794d7b3fe3fdbddff6fdfe76ffe9f2e72f6f05b3fd23010ccdd2b8649e206e8e5f6976cfec83ee38fd97d7635974fc54678d2bd370abcc5295ed25191ddb4b32ddb69664746c18810f6ce5807cf8968f38dbd8c7d6db6cf2e3d9330dffee0632d5a47d5e61013d08d3d615b85869bbe9735d814bebc15899dbcd6d48c49335be17e08877b5e8b3029f2fe9051bd5f1154e9e767ed9f0f41d4e9ef66adb9d6bb5adf6fa8ff7d84181aad7a76bba80b1481c999e115c5842c5aa884032d796da61c9aaebbaaf6bdac06037a5a5511989a52045147fd41938579d6940033d5eb0fea14ab3c6051d8937637d42c6132e11f3ad91ea511bc1e5a9697d7b809a75e84542c64b461c40553725d415b08cb848f0ec04817a05dabf44629e2a143f24fb54788c3b143a2f25a1948452124a492805ecea35a114b7d60ccb7913b0ea33a114181cfa7837606660416e71454b33d4413557f014996a6e158e3c2b55bbcf6ad424774174687723d6404f881b126e80953d126e5898bdf2156ab5626dceef95847b13ee7dbc93015d512254f6e9b5dd90678433e8c8275f964f3fdead301b507f4faae7a906130ac928249d54723a6d07ea3da390fcac763237575753bc19ea27d4656bae7f4b7145f7a41a405ba9598379924cf368aed43fab42dc9b706f3ea906e42c1debca6f4e7eb3a493ea3cdfd5ff63b3a3ffc74637ff74bbbcd1b03cff302c84cfb20348c2a5a6c0ac9dc1dfb3cec75801f87a4a5e0fc7ac3cd4359d383f8e3ada82758009ee4c1785c0bb6a3d8d41dcaf65b83e58c8ea4df7fb9711e42d0dd1c74ddcca6cd8611f3feae347614b5a5d51c2b215c8ad66cfa6b05b98248f89ce56a9c8b5403df0073eb0db45f678679a63f7badac462ff74a957c22c30c40715ada986ad8a2b50d64d940348cb2cdac967ee4666d7c3fc83aa2ad65f842455eec88fd3240321e186f168296e53b68ae4b39efdf621fe7579fdba73f2e542b325617e7c4bc67e792b7ede1f09cc9a30b4bbd7d2de2d6ce6d8223eabb775abc13c847deb6017dae7666edec63612740f3f3816e7979362d253610864f682dcf654f059791b2098de64dd2ac6ded86f58a22bd7bdc10d2fa43598fbd291be0f311ee3903db50f063f6c97e385eb35d83d50fc718184c54f7aba4dae27566065162af543852f65a4c36f387c897bd2d188799fa95412ff06840590db87ec5d46bc9b896145d3a8f12d8a90b4fe1c929a7c78f5f170ec791af599d79f012ae175ab345a6ccfcbe52fdba4a971625332ffafdb5f96bfbc37d9ec13d4f543686a705ab4b4feac3820053e38df5e835e6baf60c6f7cd84bd8ced92c92c8b4f728048c0ea2cf6fa01a9fcf7289c5e04e4afdcc4253712cd34d94b4291fb78643cfe3a5835f6dc0d43d8c0877ccd9f119f109fb3af950adab9f43c0712b8b1c59184b38f1f3148c22b57e59a077c0d229d06ef67774d2cb63c91bfcaa312f365035591759ff355c1a28c18a7745ada2b520521d9962b9cda94acbffff99fdf9b5c7135ac6a0eea13e832a5a6f527e44a831c94a936972b2b7b864c617bcde6b35215d7405c10e6cc5898d3959c7b602f564ac3ca01b683cea3e1741fb60dc0635f00c92637c27ad08046da280d8ec2bcd8eb0a9f8e8fda95530bf1923e9136554936bf27be24beea00b103489569fbcc8d0984df7d3ede5583fbc2d4c7cfff25b3c179e9fbfb9fff795bf6fefee77fde94bc9ffefdb7db2fefced8d68291eabcb17d0c7779616c3f8b8ff9266bfba3548458f74ef31af103a97225db67a38a088a256331c4520b7aa770f260b3f7f37ee1752dae3c89cab266e48172cd028a9adab54fdf3d711f11d62760b8adf81d20777afc58d527de467c5d39e2b71150a8f807ee2fdfa9952670672a71f2cd727c9affe2896910c8729adbb16d59cfa7a0b80a468d728dc7cdb94c827f38f96f909fe119af0859c8ccb69cc5b94d517b6f239c6b2c5ddd3c12dd3feb8c595c1a668a1fe8dc0c0c19bb0c76fec615382461571602be03349cea4551c73d2251028a1be3f14e0ad6d426157beb81c34e060efb868163bb3537db71f979ff5e75f4c42ac4fb6073f3cde2067ad288a9a8b1d3bd3e11f3ce71fef80fd7b8aab3f77b510aaa14359abc2a630fd1b265ef6d977cb300ac05a7b0e757a682cb1e3fcad088951dd7c264a99a90fa6c322a4d4c8d08ec4820f6ab852c091807bbabb818dd04b483266419db657ddff4fc9d4fbf691cbe4763a7fb0b3d7e64f1e1abd64988c269c77f08ad0558d2d8b34b76d3653d1724322d707e462af7876350c7418bd834f90db8e8581a7670c7e3c731928aee106d4a750fde003893736502be0a5f37e4f875bb1a809e3d2faa217fdb021be7ce89edfff8ed1de6d17299a49644958aee39167cf083253c96756b4c16feed71eb9d79a6d8aec1b6b0a120d82070f7ed92ab57eefa0fecb425ceec514c14e9a3bd615eb176c99549bb5f9f98b1b486a0ce9926c9bcc68ac29ce05bac237cb36bcc419515a54b69d89e4b410c8fff8cc7bb3a8697ca6c34d0a1ecab31aaaf6354dd67457a3ab63130ae57e3bab1ee1bc22a0aba7ac10261f15786bf0b5b0d5026c3ca4b65a332925b87bccf327b926934ed9aaa24848c631a6d3545a001172a080b84ef861a92549b7f17a210bd93ebb5ca84f53a1b054de5e1098f776e6cb87d8c78a1fd490deb6933a27dd2b16d7ce75c3396b9b66399e71bd2e544637b2da8cca445a8a13984d11cb2447b9db6daea6357a4fbefc7a40e30b8be9c3670ecafcd0ce4acf36b8a4f9ded6c2fc5d9ad7efaf9cffb4f97b75fbebc8da1fd23499fe2b6c0a61fe5276ec11a0be8b53482b5d97f75dc3ff3c4785fd054b64b69159a19069372ffdcb7935e14c3d2305cc674a799198c4c98f5340374c8b50f9fac26c9d25646d5ee563427018598efc1bd91c18feb8a0ac187ebbaa9212f1be8a2409c00dfd3e35dae40612b3e9d35379efb8859d6b214ef189641bc5ebbbfb91290ae5a1eb9ba01d85d4f0153401621c41b0116ab63a91a4885a94dd26bad41810d34a9245a1ef2dcccaa15dde61086d586748f602cf3a906f3ed409ea47f9766353c32fb23417d9f1981801637f8bb6670200f9ac92f44a2a4f85705d1b1d244b89da6e15dcbab2149496b6a7a70c136a3beb74e927a50ddf9800a55b296a41310700aaa381684332002085cb8aed4a3ba5a8e56b00c1c557c92b7adf8d7d4e6532a401da7d058902cc46e7ccc6009e68608c23d8cdbac334aea0526c1803f61815923312b03221129f9584ab27d73c1aa426dc10782cec765c7ed21ffb0168007c499424dce129cc4921b6eceb81967268507230b088d1b1851f7ebda2662822cf9abe16593a2c53a52f8617a05889d25ff9c4355e293e3ab22d8a1d6a00346b25d4d4c12960ff9200b810e33a91670f8a7ca41f3e72365d4a2b9f286d8bab9b835e80f750528473693f70c6fd7c78f6a78ca886e989803ab7d55e95ca36be83e2e10383a407a54d12e2127a0a81f7befacd93b6b46f09ea03bc33b767e9c3d0e969be3ecf1ecd638fbe73f7ffaf20ed928ab6bc03d895562b9e15e49f748c00c304ab91410b726591588d9a981623aadfc41c14374445f6559c4e54e017f5fc81a303987d73cd409e1e2465b0ea7898fc0fa78e76a50f1996f50ed973a2b4d848b4e4eda11e9258605c23610ba7b2427c2b43c6ba636f73ec47957ba1d08c1f54d5c8208a6425217f3299701791c7c23ab5c28807de4839b333ec8c64f7c5235a5aa0941003eec3575835e7337782fc51fdd81aaec43f57ce8834477635299d7ad182a6f8ca5224c4efcf591902acd3596c84d9d54f976d5ea0f80cd587c75d56abe228fab506d4ae37a6e4b16bf2cef11c18e05210416a8d52b17261fb8307f72d95c4f048a64c198c22cf787eb0eff900c65e55ba8319faf733d5fdd0a60048435c44bf97be0b9797dd0574ffeeab5f3e1f2170c9edbeb6cf7cf9efffcc55faea3d58911765f19eb598bf753cc5e60d9071c1326fa4ee3ba779f180b93dd4a788fd67401983233c67181e2acae5ef08c75a942709422f1ba7b971dfbea8aaf55ea97b5fb5ca4a90ec520bfbed0796985d86dca2ace9c95d4db3fbd3bae643722c5679aea56936b2833639b62df1a35371a66a1c6f9e47c9c59f77116d1864f77c6fe7a7f8a2ba4f9ff714cda7ab03cde8148d11af9acfdc3cf783a7f7812f6d7fb53a013fb250de5f3e1eb1eef72e414b8295b310a9bc416866b8b4d8d5820df85a999cab544908b6b831a97a6e3f5c0720da82fc02363e08c428f17aed760772d732f5d3177f540945f8bd3998e2fd1029d4d5e71551ea4eebcacdefe6973cdf5cbfde75ffeeef3e75fdf08e3ee8fb379805369da169c4cddc4d4410aabe90378bbab64e9b2f3b16cc67a0130322e1961e86cae614d1f6c5c9d1e123b07c2538e056e496e8e28f4c341e3127add2c18d205240a224a7ced0389048065f92a491dda7868e62f53d4f7b03d0af5852692ec2d61190ffb7d2f40f0afc1fcf475e6fbfdb3b21eb0bcbb943cc346c3ba1acc291964fb1c38584cf5465add0b06dc4273996b52bef00a068f4c1eec8173762bb5fefe04f2295779fc680abca14d8b15212e5512c08cbcfdda4aac3dca4bbb5744f3349f1d5a126073616270cb1918fbc8d3b1c4c0f383e757638f5bd8426058f02e56413a1ccba6e16e042e4d0a90b0d588f8eabbd2ef57f34db992311e0eb0c1e52198e66f4aa4486fd16a3f7e6caa09173c7ca73c4702687f51dde7c7804357de1e040e67374681dde75f3ebdd305fb3a5335c61a324bd671127f5e5cbb35f4ef19bc0ef6010abca5f5678d528f25f3a2c4bcf7ab703dd40a641ecf2338aaf79d012e0e66f920c88089ed6a2bf8704ec66e58fa6b7c38791948fe82a03297dfd26926353dfc3b7d6f18cf5809d9236adf4f92602a93f9c4325190d87d7e0d6d6db5add65e4f9d69ea9ff6b76f8469fa038b6762c307d2c16ece79036503bc95dbfd235658b04ac3597c609b1008b8f941b0a76e245bf0f223b11b8bb36d8f0c0b5d30a816c09d5024b4c50a06f63008c3575109b9609ac45c7d1c78ce283e72c68366827f58622da463c5d60be1c7bb6a8d2c75a37ead8047a9b551bb6cd52501b0a1980eb9f998e47b20e46306f248cf3e1cc7ea98c0a2e512195c5867c2820950b5fc0f40b25408fe80fd9ae13f42e80cb2b16a0216e180b427af4c282b089e82504db7096a56732b725c6bf3419af4d28ddb2c80fcca34927841725d63e884fb4653c7d3b82721e4ece9be8d419ab429f5a5075bb33708b49f9605815804fbb12e0d4b872381a9191dceff099d0f0f3c4aec3941c7c973a20e67f35b8d6d7f0d748f0f31011ec69080f6b83d3d78c4f5787134a21c4e0fae881e775eb33e70964eb5ef33bb26fe01c1ce0798e4a649d92e79e2376239cd471fcce576cb2d62effa610c65b2485ae5bdb5cced83f7472846520fd7a806023b607ab13d0cc0d4679a54e6be96d4cb07eeb118370f1720618b6fb9275e6f0a772263b0ad80cead7ceb0afbe4b4fe1cd66f00f8103ffbca71f58793a292b80d30bd782c95f4c34a09a7e6e5c04bd24baae5031f621be558534353ade6f72a162c95d7170cb4e07a1e2be899fc9d15dec305af0af0bb95decb88b93a80d3e87c894ec3a7115aa7f8345be4df87901dce8740af03464dc829c8832bdcd0954af39168f4552cb1226fe2e2ae80a8b3767b2af2837a0937b7ed6d06889dffcc675771a7c63e3ac97061a539633d62b445074d056dd234a0aec9ecd984463b485f7052f411123b2c4701de994a4106acff84f4e009391eb7af25c72bbd7c17b68cf7de1b1cea738e0ff8e969fd79125216d809564866641e4f45cc6d9659fcf71be4f475213d23a1379ff7bfddbdbbe50e571d6b4dad184dc3f43769747df66b8373d54282850ff526f05bc8e6c8d87a2d37e9d9c8aab8208b21204b646f4ac367b9428dab8f0e40218e9f6814a3a16165359708212d037942c271fd48ebcfbaa8d5c90ccbbe9d27484e0646c1b1786f288d531b24862846e3c85552803d729fd418f15c83e39ecd47a4e78f387d25d97ca5e79ff0f52763103f0618a07e34eae7f1a36827164bb391f68a5c9d0abf4ed14865a992d47b0400961b95d63296f88c6c06f248713b6936a8459d0710ee798f94087026892d7e0b73aed415012db3e6492692055505d819c43c5b4deb4f39180fe821e1d4af7eef70fdc990676b26e9a484fde9231b1948fdfa08e6367f2ed6514f5ef2f16e32f5d1f3649788c50ab1a6ce640518d305cc1b8d06f2c4bdaa540658993435aa12002f2e8b5de1fc694d5c38f7405971e96c0d2097cddc30ee3e9ecc8e0cfa26339357a051ed13cadfe8c064ac083b322f501b44bd6429cd9b0b84e6184ebd110ca83fde344f05ed4f1fdc5c62fc6a469063e903b00d30abd7377dbc03107e17b84095976a545a52a32a92aaa175194c4a58226f9d9a5aa03f3432c51bd8ec4831086eb286f591a25e0983f12e7d8265da47539e39c67dd0c737404a20336b5630c4b56a48957255c7ffd23c845a8f38894e0c02c7ce2e09c32f2566200f000ef4a4acfde9c31b71c373353cd5862fa83d9dbeefab036f8c9ee706de387b66e07d7fe6faea13b6bfbef552c3b2ca736041a70036056b25befd2e83f1d26dc36ab0e352ed8310723726e96a2c5e4a274eadf86bc1990be08dc0dd90167e61f581aec0c36f9addc63f6bcabddafce71a7eb3c97ffd7cf3f3bf7cfafcde2c77f321fc8aed9489a5acd409d3766ce5c674c7531eaa94dd73ca9772443b7b71331616a54ae2526f673acc3133cd5daee5f4489e37fde49234f3dc9d5e91669a8f77b5f9e4337eafa887fcfcd6cdb20ad66cfe66257dcbe765b6915abffaaa1ebd1164bcac7230690cdd68089e9b2d3191ed703cc307ae9ef41525cfe39d00a249af829b7a0fc8a8f5ba03345c00409eef18aba46ff78ef5e44617f9f94f7ffacbdfddfef26fefcd97d10cbe829deb1c0dc148598aeb4be69602dc949a9b50b0c3cd15705382f6b26141a552cb1dc8cf3547940fa276188bfd82c8fea037e987ac17a6995a439631b0f8aefc2c2b1db26932ca146c068dcbaad493044c8f3f528a4b94ffec78a9c16d0a60e0a0e7765b0de339f56cf80f40f125b71ace05e49e2343de2e338e819703515d202206f9f14ecb5280209f044c1c833816213ad59b330be6a69b74023a7c743962987ed33da35087729a7d6691d57582f52e841ed7ab66656b795efcc5bf8a36f39eb83264fc0e30e333988ce7688cc026f09153c6e27552a0b1bb143442b874a64a9c09e15408f0a8596b06b06a9e769f01bb1a28ab6e8613fc2c98e7cc9fd348d020d5357c49ae7dfaced9fe78e8565bddf1706eab37eef7f7efad27ba0a50e512f10e18b786444c86eacaa781b889974112f72f832456e85bbf78235e420f03e07ad9d76948f7cf738f7017d7e9cac3a4ee664dc33fe4f31094e14a239c91068f34bc58f14a0d1dce2292b0c686d55bd818b174b6ca4e0a6a061f4306b9e87ab1d70247a888517dbc434865e6b9642f263628cbbf5532ca82269c35896f912d34722cadd7bd0496906f978a55e596d09f62c5bce6185e00e2662914b9a8402f13c59f97c3fdfe7e5306f7fbfb2df97b7cbcfd69fff31b2112fc483cbf0f849db801bf91914e0b744e4903e00e0050132516ac660d4e808a5878f488c652efbc400585738b0103a02355eefb666bb6771f8b6fdd50ab401bd1a02318e0f5c063e6a5ce8260330bb4128dc5d40e02eec36b3ede81abc2cd76b906e2e16432c54a2f40a0848f09b808e169fbda67e6d222f0d7cdd91e9cb65201073bc176eb82c72dcb54e247444f2bdba98ef14424f49c21d07b58e626df762d17a8f5df74f159d13bc8d2a6fc1d4e6e08e1fe76f9f40ffffa3f3f7fb9dfbd1123c90f21cb86f0b83114ba4795f2b0b2016cd2f3ded4d9e8193f235282026045f9f1634971c5d3d4ad2784ba3e11fbe859a55ce3b6f5d91f4e15d143118f776a4a58ae982423526eb993dd70011a814fbf3a5d0b01baa549a0d80279e0bafae48d08e4190007b1016e41ec46844eb9960a14e251966cc950060220347651dc0d1eec262b32712695f1a1722c0ff3712536c0e6a47bcfbd692cbb404e3bc0a80233d50233359bde1f5054030cda6da5693771f7ea19d4dc229ecd22be58dd7cd6f323e43369db12d567176c8aeb2f9f3e7cf9f2f3c3edfefd09ab26d571609ed2433cff416d3a724fbd14b8957d6a836afac03fa527b4ceaec47d540cba521a99edc7a0ae69945b9fb24a4febcf3ae2811c922bcd0a8a254b7d506d4b44ff8267b22948bda94b1a60f6810059cf83a4039207f0b6c2ae89497359e99c2a7051158c1ebd220e8c33f04073539ae6dd4e00d53e90ff5523566ce60e3c672dfb3c01070c50de6b1902523c1241f83fe7757d7962c1b362adcbe044997cedf37089b5672e88fda581f0fb89e549603a052fa7eeb5d374e51508f1de33c585744054dbccd66944f83d96d666362a9c030f17acf49366bd06814e3284c0e17d5c53191268262950dda1b98eb187dfb1b0cf6fc4330d9a9c0cd8821de055420d53dc2bf1722762bedd4b8ea7cff491ffe3d39f6fbffcfadb1b79e6fe37e925a3b83250955d3731f0ce03b47545acee08c8ac35fc0d7bd7549a66e2711b2855b15dbbd12443f9b2975920dedac9d08fbac254edae95f7c8b001fc4601144845384765373f15a92a35eb0434311040ac9235b7afb096df7a1605d05a73b5a40d4c04411c3069b4080c6dd355ab4653f2b0c8e0231dfb3c07350610990fca83802653e01cee13ce10ff59674540f9f2f50474b7759209c9364448f00a2eecfa58cb2b6337b5ba072898c00cce5c2ac60ff129ab0bbab8917638b20b56dbfd677d9e51f13ab99ee1225f7b7a017c1b854365faf3dc92f1da944165ec3bb4b72134cf3bb29f09fcb9fe72bce04c8f796f96205812a75c55f3e1f65a0caad0a0621fbc2a839ecc7f560155f321afec104a1c2d09473402100b70e21bd48542755e0b2357d21fc0aec56b25c0f5c36355e06fa900f9ceb0a704c19a7a85475e0245424616f246ae9dfa403cb0fa507a5d039d1d3680b9ae701917d60e3c01a43e8df5ed7defaad9d2087232a97ba9a0098b275e87415c763e700fc3423a4652f657158cec2e492bbe72189deb67ea0e55d102feda0773b755cb4801adec55791db5eb4fb8d25196957b374d0b4879df019e7c59f1e5f1f7ab82784efe36c5ee2fff89c16119e139d2dd46ece633e2120c906e8ebb0e011891d8e11b0e3ae2e10d3883cd165c917e721ff7f705296933b2df34381f4bd2f356d1b182b71be52f67e15bf7b76f93bcfb23212d4132cc4afdba0b01b5fd522b0da823880e85e3a7d3bcd1e03cc0f266a10e8487849b94a9ee6b73c5652c9523cc1378e52ede81f522afc474ee6f3713f5f6b75b197afbdfde86b4ea07c22eaa940bf8202eaa5c14ff2f9b5e14b76d4cffe94ec7058b2b271fd82ed8e28a8b72c1dd827eece920f6afaa3c54f9c056a8f48bf5e770be5ca80f6330b44c6ff0c7e6a5b5c98534bb11d11ddb8ba7ac88c6cf5ea8daf012fee923cb78e573ce36e26f9b4454fbdfb658a8f6bfddff671ea45493745bbcfb18c247593282577679cac394cd33cd2245b664282b3e416696873c71d7f63900501a309834cac96e80e3aead33cd161493582264d54f3c4cbf65eb447ba5cf1e5a70bbd1efcf8f82bfddff6f10def786d4737719caccb610fc11f1b87a97d2713eb8ee78725b3ade9d5cb02529e34abadc801d688b9fec980a6327b9306b32cc03ab5ebd721ac6e9098ee409cfa7ea039c29dba7eb791eb5a23b30346c9e5eaddb4d9eb5575af44c5b6eb4e2e77f596eefdf5df4b958279599740c6a562fc58464586aa553eb3589465c6b8b0c6784be00d3a6a1d1402f9c95547ae0518fe0e2eb97dcdd66e8495d25025db0ab1383c61cb10f50f35810e566ae18b18264b0b7641a3bf78684f509963c1c716dcbcd7e40cd8cce898b12f789f521501f0a0dae8f1fe1ed363898a935c54b239c70502d11f1db0206a7573741fa50b7acdb9c49a83475fba70b801ceb0442f26c96a6108be6c934065f4a77dbcefb3d7b6948fe03da71e9d81729313e0e89352ef30a2466183dc32c99bf9c642173a30ac9a7a48593d11c4626234d04924eaa001aef86a0740569625524c249053758b59a98ba72aa64cdb55605b98e599aa46e35d29880ce1d626091d40ab0f456dd92ed03a44a0dfcde2e0b2d338dd672379202e4f1365b666ff232325c945e9d5aa8dabc04abb7cdd4bd916a7293ba4e1206b24dd4836bc41681d55552074c5a03465d519a03e464ad26a1de39f535dcaefbb76babfe320328661df42645908a30a5067bd5889a00588bd784dbd63303a49a6ad16cd4cc2b7466afd0169c95e5123047ebca492050b5c8e65c4af2269f929a901541bb1a00901af53a931446d0ac22ba5888d9db4a7cf0a006bea3561b38b6ddce1e8022690c179c0ae2c115b359017257ad3313abf96756c474c09da1c3201b236bdcdc4973651a05acd1cd340fb7eef1178f8eb5b2aa9dda943c8da4f6d48113ce5d83efbc370486861b6e5e5629de8e6ecd74ed00c76031ea33f69f3ce118098911e2eea205ae9d164b11d633cd89fcca52bb9bfe06e49936103eedbda893d44cbd62fdc09014542a9c9c33aa2a79555dd6d948a4230aaffbe80157a6a20f6838d3f11bedd6408538786db3548e0005d57b07b00c57cf8a86b3e53efe38f26efa48733c948f7f1c09eece0efd319a6f8dfe71666b02d8efafdedbf00fbaab2ae7f4b2bf9ae2f788780b9e72b2167db2887cb2b47cb2429d39225f8e8bd1270bd54fabd7272bd429a8505d0aa67def93567ad4bfc193ecfb1eb47b550ef7fbab4d29dcefafb665f0dd89e0df8add1a5a878d33755ccf88e65378d7cb66acb2dd8c60bb9d76a052faf6271d49b4bff549e07df9034f7ac8f69d4f7a5d02cf08e096fc7dfee9d7cf5fde8658f70764b096916ab55d6e9dfa9e3bd56c4a7311445856ea1161c91ce85ebccb36966c11eacd09be590ec036dda336a52c9911d6a741f8688196e67bbb36a9eeb3d4343bc1091b98d10a0e4cbfaec79e02cd601092588249c6f603012f8b92e5919904fea582f5c5c73b83138119f9b5aeebb8f2674814c24e95c02568144aef71a2dbe54673017a5921a443c2d38a1def922f220b3380160098b7564e626a97124e1020bfc901a116c4da0be03e116a34d2287978efde65b698ab8f33758f791a6635e0ec3a80abfde50199725905658295c26d1540b3298a4fd512caf5a275505d88732c01c4dbd2d8bb984b5940260b9db1c388817181bd9d8d852b45f904b524889fb893dc33c2e8746db00a28b715ffb0efd8963551b61604c30195829348ea3442087af8de316ce93e034e5c77b52c0a74c592f10d5e3dc4599906e0f072b7dc11f83b5fc98f5e3bd7666f8c539b3df2bd2d372a00f4ab4de24b3537136ab3a4a304ed55ec2130a6cea81fc97dfd7f07e4bf055891e8472248fb887063ce3ade52fa5b394a7fb355fa9bfd31e99f8801ec6077c6bb271d575c74c157a792bba4f5d35397154a0238c94943e70520fda540805dfb77912b1abe0bc45aa3202f23f5f5ff9dcf8f517eea50f8fd68466e5445ad18c15a5438ea722f341f01d023cd9e20624e8053ee4f61556241e509c4e4041c05f902dc007f53e765554e1a98786e9c682c23ab8efb3c5a20554e604ed7254bf62a94cc3ede8eccbc7323479786cff08ff14e891ec88f1fdd2eaf189d0f102d272f74ffec859e7fc9f30f79a5136ef7bfcdaef73671803fd8f7aa45e753f43e332cd5ccf9d403f97917ec40ca107dde094b472f44e2558704971eeb2cebfeb12bbe2415f7ce08d0c120ca2e2db535e6a84becae5d12ee73a1394e3b26d0a1c14e8c70911664dc4da27702da2858aad03fe5590765b84b876c74d176624b3eeba4de4b0d24ecd2e3cb4e3b6ab7a79e5a9f75555e69c7b502986cf85b798755f4588e2e2b873e2ba79db6632a14fdaadb02746cedb77ada71bdfab014610d418f053136e5355ce6cf9f37c3063f7fde0a16fcfce5d72fb73fbfcde2e68ff820aba572b42c10bcc1abc5f0a06cdb86858c6d00ab1ba0b46c1a16e08b1c4b0ce5691dca6375e13eaffbc760cf9399e764c8771b0f04ac528d5c1cb96036828c6591f0d6cb1558472e67548bf7421feab0634ae301b180de2d39f40c46a84900d4fade0eb872353570fc534f236681712f1d50bc137fe7b16b4bed07660264e48cd86b60849baf2489acc2b0293d716a4b827efbe55f7efaf94f6f43fce163fe8f58064d76591be96cf0290986181f8b6aaf79f5fb141adeef65dcc818bba1cb7a6182fba9f69a560714cc499ccc8702e2ff5d1efa807556f8a8bc139b05983c1aaf0cb04cf679fc4b2a591b013438007d42cd87cb4e062a4124ed37e2e68ab47045b6fd1858e046b688f9c04036da5e06e9043e74e3ba2849adaee5f85043d22760364acb42cc00ab2858feaec4a26b58ab0b6ec3d094186c80c8abe16254044775a4a1d4157bdc3a4de31b11bd9272b65a31e4c5b94325c6ff3b190f0820903f72efb433cd735361196f35cf79795f457753e0d7735b12ff1f9fbefcc3bffeebbbd3004af106e5c56a52accd275eb1b1148bde48d2076e3baf6ce1c874d6ee23a98e4bf6ce56221b48d23106803405d64f852a4b33cde9dab28ba43f50165714b2db8f0040f06e973af56b467ed02ccb8a88ded2ca66346079559849cd07bb916da48efc6fb7b694660ed0ef9a3a48440ce6969fc4dee4f0dfba96933bb0ac6c6476dd2753cd0d48dfa044298cc28127a679528f543e013439b5ec93422d34f7dc021d9c97605441f431727bdc881cb9d378fc28d39298dec8cacb0ea6d97e42630fbf28122d0fbcf041d8fe80b5a89552caed93230b7d95256e482bfbfbca217f566643f83645364e6d48ec97378ad5fa81191e28b2ebd4db30f7e643224536fd4926c771bfaedcbfd4e04e722e92cfbfde8656934b406f8b2bb1806177fd0d01b3652657857d3c11d90f84e216f89b0b46c889f8e0365df363a057806653406337037388e3648e0b1bb4b20676b8d609bce1b90e9a4073af11c8a7881dab285610533f058a44a30a1e2e9e4948c70a4e0bc02d940ceb71062842edde138adb4b6e286af00683d831ae44312c957abbe60aba2aad72a56571f5a3cc54b2c2e7eeefe66ae93df613f693961d02dd9400e3f2ffb3f7b6cb71dc4cbae0ade0021a19c80f7cfdf4e91327b811d4eed9f1067ff81fdfb2d6d44ed37a57b43931bcfa8d7cb2bad994aa69d9b2663927266cb15155a82a1490003281cce7a9ea660148f040d689de23e39a1b189c1594b6077409d75b3a62dc1016d32faba49fb65de23e6dbac47dbafdf70fbffe7275fbebcfdfc779e25b000ebb249e4c93c3fde1e4fd60abf3c3d85ed07df87c15b783c80b4e0b3a1338b6d5d6289436d1eaf3d03b78bec4e56d9990d4ea4ff5f6f6ec03bc1713fbf733606eaa0b06acba8819f486d4344938130c196a82831edef0cc9da4616f71eefdc0d58182f13adc06607879d294643e8e42a2873c0ba86c0a1543085547b0f5eccf389a3abc4c8f0820f3c9c68dad7a8636202ebf25dce8dd981a545a662a7ae08e5e663e93efa581d9cce0af9fb458b2a250902d69f58678cc3e8a84fb475e5b6275feb8576b04ba0d3764afab8ca4ae7821625c347c6903100741fc3a31de8b1ba8a2d73a61c7b181a2c84d4cef9ddef7c174da67f69e3b83c809513a1dd107dd8d36aff78c7a8f3643f349f1714982becd5b0e36244743a7b5a107add06012c2005d0c0948c54dac997e858c613be5cb6a79f84c64517dc9a7cc89990ef1fb2534beea6d0fb63b344a42a32c42ad7979e0441e94dc186fc1b6ad04244315b7b5781c5d741041c7185b06683c6b04606051a0905e8ef3391b0e2e8c21c7cb5b63c9fb87e5d3877ffa00f2df3efef6dbe1bbc1487e8baddb4a2a57627b2865e1cf10abd8163808c177151adb516bd0b6e0f4516d18a1369c3413c1c99366f2f40e6afc8a6ddd82b3e6e479b52e013ea35bdb11494406dc77ab042df9f0a7e332b53c12accdb67ae6bd3c6d6331c01e0c3f99461a8fb5ddd5f6c5d958c141887cf33bd3b8cbb50562f667a76d00292a953c32de9487bf3b9c09bfb8f00abbdc96546ccad646beaf11b2372761d8c0bf63295f543f7f51cfdee0cdbe5fe6bf2682cd45f83fa2a37cb5cc7c95c0bc2e2d6f4e4e0abb36a0550e1d1332fe2ecfacf2cfe1d76ee008b5957941e3ef2b41da9aca752cdd36ea76c8ae1eb4f80bb21fe524e04d825dd09bcf464713617bc5f88adb1e1320fc0e341850938d47a917a2d6753b1ede67ca3b70141e5800b313df9de2eb5f63d6d7af66d68f8f9f9da41ece9ffe2a1bff79d5bed608d7cf0d07247f44a1a33bd9f3ae4e3bdfd669a7ed90ab6637afe0389d49eb1f08fc96a87ff84e843fdfb24a626eeac94df7a6d8861fe8c75a9d0ae38bb42f40473a210aac3990bc9a6ddf07e9ba801c8ec940cb7a3c39b47db907f1c87c2188d7c6aa356ffb48978b5ed0d3efdd467c907a0230f86ccbe6e93ec7a6ca15cbc033a4b6c7d99eee5db60ccba22bf2db119369b3c000cce9b1fa2115cb1f58cda831ac06dcaf80f107e762147e581749d6d17a1dc26bdc1959d26b63f2876d661f3fbf258e1f97f73ffffee9fd9b332bdd32c1726a974d9a43b63320a22fc811d730f1cf6f0affabaf23aa00ee5665b980bb7581dc42db45f8a477ac2bfc55233e0878d52b49ac04f211422c52c367fd6b6d034648d209c2bf765579ebb50f2f3fdecaa479ad2318cfc75e7b739503fc3e0dbf4addaf5c2b206406c921f3242cc900d3c0007f66c44021f5871bd915ebb34e79546b4f2acd51c749e3e95ed07b9e7790ce768d1e5eba2a7ce629f0bcd3945ef1d13ac9eca69c1f2f6e0afbfff37ef9edbf7fb8fde5d3edf7f1dafa06810722bb9440bbbb146602bb743b9044c6c550917a311604bb7d174345ae54f6f12028966beaf572cc4a5d0e5d311ccaa0627b61a6399296e23f12441423d41a19e30e4b692b727065d76eef44eca6d9954f4a60e20114a7db6a7f73cdfce920991722b42d7f67193664f0f7a7a7c3fbfff9e1fdf782effa063447f04b0a624c5ae5053b113c53016e04627da70219a28ef508cc7356a60b2e89593234cbe9f721f36ce46d3dca31999564f6987a876051d7cf1af4b8f560549aa3ee6369910474354a23c219b850d5995c8d30f8ba97dc1a690361c9987c3caa2dbce62354235892182cbbd2fbf16830f5ba0fcceaa0b7e900fee6d6a8d7f19c7a545512ed0fdc0735adfe54407ec7215488e6e204f872cd56b215e2d23d353820cd81885981932335af056c4ab5f7e3912ab58e6193a98f71fcfef5a81a75f03fe8a41eb819c09c2cc4751c8fa2f6fc118546512ca22122a752d7c48349743d0014aa5177fd42bcb8d8484780cf7aa89566786e343251405c5749a311369371b4afb5516701e706764d47a7196c305a8dcc74c17b78024078364190cec48642ad633dbad8eb9e3bcd56977bbefa657ffb3f3f2d1f7f7e7381a8019b1aa3db1590c98e364ab3c766abfd71cfd81909e0b2c82bd54f87457697912d6e797a079e36e49331d68762814ac6e9a98fd06eb5fa63ef62d4bccb13cefd20f29a70cfc79eff6c8f2a778175bb06a2dc2192f16e0d2f0c2df9f393175a309a61a3f1e2c246bbfdfefec19beb6dc690d7121a4eec1dcfd9e1a55c4c8fd1e2fefbe30011e79c3df68cf78836a732347eed144ffe2016a0f17e6dbdfbe99d34a1566b9a65c9de89a64f7bc3470e58c31348538daa4d1f42baf77faada524514a39056effa645c9350e795ff651c7cd49c33c1856aa911781448ef424d3829c80bdcf26b709190a0416fe00869353c7118de157df6543b69391d494110149c38c034a1c4a00bc6910a220ba14bcc20a1d475a9207668aa1a98fa7adb07d182eb0b83600cf82c5001ba1fe9d91eed924f44bde412f19899547d389241d6240d25f6ea9a88875b8fb8f8d77b7dd741a5486e8518140a1275ae80040b445bd5b144a01e082d9bd781cf08d612a61f5cb2f56c8ab3d61e2c1cd9d50fb2b9d910cfc8a7dbe3ff8b5dea450fd9ea5a2f325cee626f6dc54d8a2020b2ec5984a4f8e4d30bd502aa8b5ed4a7cfc99626531190e7205ab4501db9529998dccaf09ec01d4237ba1d4c8975c423e6c20532e1728d899155d2eadbe3d6b6baf1033f5d2a3601983c18dbcc40e1329b60d7acfd78a4853a5696daa0e1aaef0466d67a64939a722c90d50a96f3c6b14bad966dd09c8a58da66de917c9ee549a3b9b625732633aafd74e4d269a5dea894e3ea408d2583fabcc8dbc1a2b2ac574f9e14b62e213ce64abd7b3f3001a29354928610e266f574c8ad7837829ee7835ef321a481546ba2614e8db59a125dc9ea5cb20ee289904557b740345f7a3d1ead3f051105b3ae57e3743acff31007f93c03e71727e3289f5ffaa32ef34a67d9ea261f7efef9c36fcbdb63160c46466e6ec81b28fe053b9e706f1202317a0b30e5bd14303e48c482542e58fec7ef8312e2dc39310395fd30c13ac842b25836ea9966440b356a79523df87808c6755eb06b6a202015ea79c0dfaa01a3d155ed990dbeea4dc9756270971e934ff7a23e43d4259b6bf17dc56e1a91ea33709ac0de0aa7773ff17cc9c2fbbfcfc0851a918abbf229400127f2e9d2d3bba60dd6cc7563af92b6e40a9f277812d40c9c55cb42ed1a049dd097f500ed359b7a6ece2b5834e74ad19993901c3080e3f35d3dee09d4d4a9ae80d4b68cccb1c083680e1f6f3407fc6a3c5c685e3735c40b2e5ea04a350d7f913f1f7b0617b7844f52ba29dbebb52de1fef8dbfbebf7fff7db5b928e15d8bb3cca1adf87d5a4172ec67763d34deca6b60b9e6863c9a07404273d688b90e056565fb40d07ea4b0cc0e173b08dfee24658b99aed6f2cf9be83ce0538cf45c3d36fcadf59ec8b82b54ac8a660add72e08d6bf7cf8e5ee4d4a96ca956a3b63fe3f43b15f979236ea7494d8aa3d455c9d1ce1215a9b3e8ec73dd8cf5d1cc71292e8c297d1b69ee0565e01150ab1ba105afc464bfd9a54413c2e89152e6ec9d5a7dbefa3b17e23ee80d641762395d0857d9a0433ecd99fabd9f6164eba58936a008c7c0c2dce0dbc3839d7ffef541ad9c212dbf915536f4ba7c73d660ef027cb1aeebb032f458845f8e9e2a79508b053d064203382678fd1b4887ec036b75b7d5669c8022216016209403c24094d41ea4148851aa700d1a421078653138cc3246e4c365d845a905c53c7d640f7ac9c2ad576f019b32004b56932441a198db900419a983310ce9506be634da1a3025899dc90a32a99347630849946c7aebb2230b9d725932bb0b88174207ffcba7210c15800dd25f13f430e80f39740f31ff02becd8bd07702efb691a3d22b27865306c07319a13cc72fe5a9e61213fdde7da01093da94005c7dab3c0ad50c00b5a4847ea647cdba8bb628bbf4140247021536259f2bad6ede5f192babd80847f0da79227e058cdad8a351d7f413da371219d5f88bf704b2b49c9460640f7fadca4340313722437dc9168d4218134517fe68de84569aec1982098a227f3eaf10160a64e6ed414e248eeb94fff0e2d41ade8b67cf56720c90154a6547d44c74abc6b5633c5cf7af4f44e87cbb1d9b89a6d81d0aee18e82a859843bb653b0e39d0ca3f14aa03fc691cdb1e7d3ed8611f02fb73f7fb8f5f1e6bb512ecfbfbc6eaf8cb8bfbb3e8917d44b02033538ffc11e3ebcb5b25baf597a1e4c034bfa994bc7c6a92bf60c1cac6c849d68a5712d8341c0220b231807ceadb0e4d654b5a77b57f4b12ccdd70ca450ed20709c885e95a0227791c10081b90920dae6ea3be89461d561bda93e18942482f107c7d3ba0c6c3ef21a41660863868e5e0f1151de1acd254f082a1c2c2d612bd32d9d49f3012ee5403d500588c07c7a078ca6d8e187fb9ec84aa10e6b1870f2d9bf09afe8fe8ab140d707019f8fa2fe0af1c11421db2d49037c7d6a6e7744e02f2a9711ed0fb02bb44af0d578eae99df88c536c61c5f0f039dee4a8299028b160865d890d9ccaa7fb924d65e112c1803c2c0dd0c20faf7b7bc8c7a3bc9ef9d115207058ada1a36cde0a80351fa963b557f82c00fa2c56f8e12cbcf88ba8e7b3f0e257628acfbbd246073cbffc4a3f7c739d5006020b2b8d3bf6716c9941c0d4d0c382383cfaa2db8ddd85d8dc746613f8dbb981c7c340b568b9866978a291c7f87a2d1340d5632c3ecfacd50d0c061731a45a27e04faee90e827c4d086a0ac23437d7d12f258c5838ec1798f92601da6dd758ff4956c16239e2f6e8cb0c246eb791f7dcdc2ab7a92063f2d358170fa97e1812668c8f1ddd7be6a4b6805035b03f8009528342d30e79e09c0caad131b4286d9b300f2f55cc97dafb4be5d79566f541c28ead8275df165c61509ebda672436816beb982a72aa29b02fb1cc80868043fbdf7564bb381328263350341d03efa66d7a952c7f9b5cd91fac3bef05a47d8ea051f7efdc7c77f7b6b1bc8d206c51aedde676da00d622fb537fcaa8fab2bc8f4d7fad348d937973bc8ee2834d328fe12f6f16b769ac9149d02f169c075e4f855e934fef4dba0bca3d1ad6499835a76bda567199dd4353ba8e834f7dcbc074a0285e4847b4e7295bdff957776ef0c0dc83b0ad41c2b5835ea84355757102b3422c112ec9a6455e2bff4896c187420d8a59265014c10fb00f374ef6f988d74c9e69f3b5c9980c033c05b68a2e6ffd28b572fe767588a8735f2229d8054ffec33eb8cbe3c329716fa6206f5d6c54e87deb3d9e57065abc3fdfaf3c7efe331f46dbb90343bc3afabc85c26b634ceff22dc3aba1e4d631f65b1763a0ca1782b793f6335b6bb1960734dfb54353bdf18b7bb5c07f5516fc19d8d89a31c4126f3a0ded5d5209643ee856a6d3eb9559f49955435030642afb50a40a9b04fec45e00554a1a6d86599065aca39477a5180c3b1c46052f3a1e46ed8a10af5608fab955fbee865217e600e2cc7f859c9ac7c2c1f35cdf65ac0756d1736179feeb54b2a8f1a1509180683613e1bd4e3d337a4d337e4b5d6d12cf9ac89f2b189f273134566dec38f0f7bcad862818398511d12bb6b8d0acf9bf95afb94689f84f6b9f6014affda37df31177fc7a2a4d26021d6a239b6c5ce6400cdec8df49afee77d69b3f7f9858dcef77e79ffe19f6f2f44a902128be45aa540f368e02821b90d1dbfd27c66929354e0e36603cc27afe66b9662eb11b9f65c5d3983051e23e0e31ab484c80eb097f4c8edb630ee6e76880525a3f1f95bd27969be26233eafd941c79a7141dc7a8705458d2cd6a4c059c0ed144112e456f9746d052b6ae58b10982e1ba14afc65fc94d856448d1b40f3cbb89ab7f8d04b3d22047cab4bc495cd3ef1f1d3cf371f7efdf7ef8380f98dfc0a5ce576a5a7c4a25649c7a3e7b310f862fe0ffe45326e639d39982c8f8eee71c6a79af07bbf2f59ba7c2b7f4349dadbedea48b5bef148e2fd7cd6dfba1ebdd276c786d86ebfe3d5cd36fcf737e8dbe446686d9ca431cda28b9244b42ddc9c84583023c1e7d1a834d0aa721b07d71cba6271da6acdb500b17c3059917dadd44a4b0ac2574dbdd00c3ea7e9d31866b42bb671e6b5733e039da19f9c3bf32496abd988b92e3edfab626b4f98b4481e4ac5065c2fcbc840f41e072f94889fd431506001009bd980a55c06e74ed57a1e341bbec52775a3d14105ca751c7c2a14edf19dcba08615eb39501152382966459ec463d53c0ec8eb6a3b6e7dba9fc3eb38f3109a5c0fc62463ba6a5f7a43b130a85a0dfbbd544e9daa8c8c2177568d12a597254aa7127549abded349b866859a1525ca6725caeb9d8b127beb2a0db3c800ac109e6b1be7b3366e23de24d8f797a6d9cb3d64c9ea85e4dc0a157595a2929409df29e873025f9872c0ca468b2dd106e6b0ca012fc1012c59d6457f2c0aaa1e5c35e289b5c35917d0ebf93d12792d71b8b97ae6063d04a8a7b3012bb19b2e2cd419ac8b80e2639a1d7ce8cd8d5d23a93d5311797a67b3c385560b83a5583a559f7fbd126a9434002eb02a30618da81a962a756027810f587bf41ec4c4752ef9b9c0c89d70674541c75aea83bfa8617a6596f0dae9008167ce2e001d283340ba676d7170a5526e541b15b8b11b0963d5480ceba03ad4b3ab9f64ff7956ff19117c3693ff1d6b9a1b699f6b149ff493e63df75a84da70fbaf87d7af84eb882265b37aae1bb371370176d72b4990a77931b4e6b1ba419ef7c55746d47fdf76685baf6c8da43f7ffc5e0bf3df3613fa4898c6e2367b9bc4d8fe6864de571b89cb422f342a1cc5daa80770a4ae54a9756f7d101bfafcf02e522ca99b3c13c9dadd60b8c106caea05f6c2c52b895da9b969c54bc8436c990075014f5c6dacd5e4f351a857ac78bba89770f91c346690afba9d68344bcfec6f5300b4b83523a47364ead3878942323475a5d93bd0870ca47d082dd88f012f39b541a5b8c409f1b0641130e4bf8b79c7ebe1d78319c7a8010cac80efc0d8adbb64deadb311b7204e28deef67b8ad2a6828f4a0939a773cfc2c3e604a3afe6d0adaf6c135930d38b89aea5efb80c3a1f5498335294f9ab2ae6bd6f885efae1ad2fe191c5ebe6df5f2a552c47563189d937886b76fb3963af55ad3492a2e770048f36607c095ed0ef0d6a4bf968278a13bf03cf06d9892abde27a0b3ed07ec55f4f683781e49ebcf91827825ea02164ae06df1a47a84e00247aed73ef61f51d9e70d750b07e2147f8f2cd68d78e4e6d3493a2b4f22c30c67f0f3ca6a2f0b8ba86daaf507f0090296d2f5452b420ce8b77100a816bc4647ffec4ba97668309f57c211bd0dd5f4d985cc72c3f2d9835e416df3f6bf202f5bc2f2cb8787dfde7f7afff35b131919417722a593811d87073c158682eac5563adcd3d11df81e3be03688ed0e3cd263412c0e10578c262839b0081207d2a997f9f4b90f7f5b7df875d387ffd8bbd7debfe1b9af679efbda948cd98d5d32b6255ba32e330fa32115a4a93ea60e6a0abe94eeeaea1a1c47a66057e18e1d9d69158e817d1e8fba918d964a76c5c540a052232c4032974a36c77a78e7c3766b7d0d40aecf6e3eb6861bdf6897cb2ec422545b7fc585b833b5a677527d4c3eb8ee22f08b9eda6f5d6f2c9cd69f72c42be5813da82efd4e8cacd9c283a4718edc9386ac6862d09f4a80d8d671790be524cd9b1de07871ab1bdc7f7c7cff3f3e7ebabffd3e9ac3b7c482ba8ac7ed0e80fcfd3029388e7abf96d693ab7cde4005ae24dcaea48cdb582a3f8e5841c0717e725d487733fbe5d995dce3b307646e4ff732bb6be126c4d7da5debf78649260d6e302c57d56cfb3d5f9cccdc6eecf3622254db0df12f0a6f4af3da2a598339f5c3f9c344938ffed7402250267bf18024e0b817b27aa86390576535ea2f0be4d741ffce07ccce419cfda22041d4eecf797aa725e8a74ba7deaec5bb11a20a6f186ba39dc64520fb7339db14d1e7cb5b42facfc3bffff09d684ebe61abcf874c750d6ef8e0dcae95c52d0ceca656deab0b2ba805aa018203de87f0929358b8ae8f98f8dd3473ab34e8987d5c174b55485682361e4a15e0598dc90c7083d5738bf8fbddc857d7a2ab112b5c915ad534692abb15c6b09eaac2f1b1b8423aa0fae98035c6a2c44d5c7514599555c4ea539db0cd514e23c65c24857a613788155257d54be3d6300fe266d7c74a11ef1fcd1690a475ce336c7da6325a96064ab1923db38ca77bac30c5c1350f5bab7110d73dcf493de964329dc1413156fbdbd3d5adb3f6087664860e32a89596a7521ff5875a6902626086446387d22578ce715b631961fd89cbae69cd80c71b90f1ce34546ea2c19682c8a4062f3919191d6fae5590d72a18e752b1acdf9c26d55ed7da70c3a7472c7654c0c56e1392bfd965e2d285eef2d6b49a177572d6c4e82968629ec7ae12ed4a6ad1c4c7ae52a8545d221807d4772e0e63b84a531411dbd82297fa794fe16fed29e685b1cc56a9309615aa1b8003e07edc5bf4944adde426d6f663d5ff522701a9379562a07d39ef2172a987bc262097a46353347effc7e1c3f29dbc87bf05e9c46cf5821c832c1fc3128effaeb8950bdeffcdee7c020ec81a6d7053606a00f3c0729fbaa1ec1aaf2e20e09939908c5b861f38e935bc3183e847802a2c3417e40ab0c60a349070cbd383f91bc2518086ffd105fb208a7c880d4a6bf4821ca493656c470a1c6b17812b5fc5fb8d42134de5e019828506ee0eb6d484c24d38cd696494e05c2e7fe6dbc4a7a0ff45bf0d94b5ff29beed5d13009b9c08bc3e07e5397a913c3b763c2377ca91b62c42da7bdb720e996d13be27a2e14ff0b35f71cf8d56b95371e55383e273242d698006df7ba08fdd09016d4633a1bb82832a3aeea4332eb217903caf8c61eba0b43d90ad17b746b387df3e7dfc4e2e29df3096adbb659bd03f3f1e7de56273ed25b1c44be49f7b1d96caf653aa759cf519f90482bd0d2074cf2ef4d0c7ea01be4c98ab860bbf02a03662fe44b18e00c526734d93108c3e12ae5689dfa3cf79cf9546aec1811abeb1ec5d052e5a98fc26101549e29d09efdceb6030d134a0c8fb071ae20375d895357be462db41377621584c870fff3416b819162053074aa4c08b7b921b2edad2e5ae67db9d63dbdb0afbdc5f48f63b46f760338253515a59ace049d0728d35b235ce24105078ad40021070db5706d1548ba0266e3e84043ce7236bbb1089f4caa572a1beaa5c8abb8be917444c3e387ab3619906d1abaff4dee8849b7d372e6df5dcdffeedfdfb37b7e2d06452ab3da929d539aeab8c70093357f66d39f35992f0591aeb41f82da5026c68353d3e62bde5c5dfcf9d9d80821d5ec2a24b6881f81b21f9b80d4e4fc6936cca35a89a0cfcc437ae1bc974fb9c63b5a9a6f567ddb98fcd8d4e45e621a4752f6641db2c8c2d15a915f4be6e19f5e68f02ca9a94f355af170b638f2278fdc10a19b740859765928c7a5ca9341ab505dbd3b1f4d98bbf7e6f3a7daf7649e77fa37e622d2caae8e93e4bab402ee04aa6fc83283617d69f1559dc3acc64ade2eae28d9bb263f05ac674564637c69ecb985e94916cae4d1200b0227fecaf76ed1ddf05c5b54f6ecb4673af072739e10231e136c88a2c2f9ebeedb6188549a732b9809c8b493a1313af68be9e2dad7570a3f3b5254e97559bcb717b2c9d6f8fa597db632e50a5f0abd339faf6e678802b1bc3c1877ffce37b4533fcf580c646d1f375419820d080c18802624f1fa72bf5431ba1fbcd65ae4a9ff8e00a3807f8031e26c32b9723025ff2e84012c09ca2e5e9de10b75f1eb24cc92a462dcbacae5569215e5ce233bcce8a4f399d66ea9d00273f1f9a20b4a6e214981c30ad23a4a0b6d4ecf9f7d027711a9d00b92159b145d0e170ea32a6588b3f46e657280b4a1d249550aa31e5212449230068640ef7910ca629386afb8cdb33778683984f62605b91500b066e4b3cf0ec96ba06596a45683fd8a94000ca0c4fef76ad0a088562cb4883e0fd602b638ccf975ebdde0020d058d8ab78243668ec090ed6f595990b52b725a7b8b025a6bffef2d6d65504adbb670683c0cab25a690267a58cc73988750f1f4fc22e0d4216cfd917a5b635f2d053ecfa7ebf91325ccfc13810cfce6c9623075cd59a2d20820ad23cac6d0ea82b691470340a76a363c943c25104704b73af53c00c5206a22d5d65d3b4324efaef436640aa217484330fa6327dfcd6b96fdd9f89c54581ae1b3c158016f22283f20fe06f2d0f942c8ff2f48ea5906912ef08b6679ff07ce89b34150c480d5b0901c668e5810b5cb37099b55245746eb3bdd646c392f449a5272d030f7886717c403cc1f00e3b5db9f65bb30f08af48e1afbf6ccae0afbf6c48e0c7dbefb45ff90d88895dc10051845a3f64d6497d6695b237ec4fbad1283319a21e9a0f6395da40e4fdec54e7c195173002b785ea4a79e282b13259cc8614763919d8abbdc2a7dbdc10873b91b7350dbb9606fa9ad3a3b1b43635d0b03b74fe892d24c59e6abf76f3260abecfaef82413a5e12f544627d142d53c75c7d35bde6761657f7a1b0bb089882d752fb3db403092827145e5ce47a665504029562a3535174e6441fc875cab8db53fae2f5844bc37606138fccfd8b05b0b7d5cf5e99d0076c6458bdb6dc44596c409b5d0c90d9749321703bf4fea547d982c131900d07c309fbf94ea58bc2ac174643418ea415bab0ce93b1fddab2dfe5c8d7dfc367223ee912ba09b0f4675663cf0e99dba3163498bdde55abd2058578103c1e4ec5d3daf75e47578a8c11bfa87756995b8be5e9978567243314db2ea0dca88af1f79cde5e98bfdf0e3ede6e6e9c7dbad6dd38ffff8f8e6ac17959d0860138ddb950a08781ab7b63b25caaeec7857763aec466abb98231ef5d37d65014da68ddb66549acad89d12c89a9bed9ab9befd4a8edcec867bbbed9366b7ddfa13af022feb958c71a372abe2af8e0bcd76e566b62b6bf6c3d68dd56cc7bdfdf44e9aeda4b65b2b3b5b3f3023fd83c27b6ab7fe14fcb7e6fee93e8f1dd806a704c6e34ff7b3ed5092f5f89dd5f6271ebce63e3d58871d1fd4acf8a51b1d767ba1ca333efdaaf67623207fbbd836ebc37eba28c7fff8b8a97cfbf92d495efef53b19e2dfe4365589a5f0dc81a24d7b752d91c7b49a2b5565501eb43a808de0e39294f0cb1ebdeead1537c3bc4d7c022ede42c685ac74f33430187a157571b04ad266993b1fad8ab2ec784e2a55349a711a0ded00b06fa4d69b526137d1150e1f75ec00bc010795319a4b57231ba6e35aa87ace9d5425996d8c1f7c42dce14f7916c7b0db47ebbb5362bd06437ec80e70fb9d0637d79c81ad6bb5efb07d3f50374cdaaaf00e0986df31cdd94adfa990d43e18124a52afb93612f3c75a69d4a4badeece5d41d304c7af57bb836af7dc5958a5b7b97b603f7045e9f8fafbfb131fee81b7827f8f05aa79e25228fdba3a5e7b5ba0e735097a1166467a5e902a5750c2cbacd36ba57712dbd639bac3e1f7913d4a9fd46d98dfd36c6d285eaec55837b4fea0e70dc6a3e7915b7bd9bb4b373c20c796bfbca42a55769bbeeef783eac1c8db9fb52487f7ae76a76b1a2bae3367e781e3878675e1378fdce0a155191e7c43aea9edf7cb97f7b87ddece07e61ab87fffedb9b8baf30d0b394bb3cdb1961de191fd9c333115956b99bed61b6cca5a719fb82e7d4fdd3d5990cbca0052041808695d4c08a584953b8892fb922163b6e208e5b1e3cf90c3834cfe886ce62721fcea88792ca158fea663140b96904d0065853b130dfeccab82df13a2ff2fa8e3cdb435e5f1dff2394e76f20da7f371b1cf932368dcf6ae401ab405e88f5e7422daee147df8b441f52b829b5bfffb6e5ccfef0f0e3fffbfbeda737075a6dc51b69c51fb3790220b319086441aee123125cf76c3e6390f9a5b870c472c05557b04ec0611ca7cf99c803513c60da18386de7791e8ee978d20afe707cedf94b8004c1d50d023824ab912ad8af0bfb737de40b482385116006abbda9e54ac296e180016c51d3cca600c3b249ec2afdfa5be1ae0ec244bfd54f1860827180a7f2e3f1d52537aa5a53f579c42ff6de235408e13726151eefd55aaae090e4391042310d18cf528c262c7ffc9256498daab85d780c3a3a7b921f3ddd73512ad24f35605e03dcd61a609fc869c0018a4c60e7140513e41c5896a85ab13c26c5b2186ecd528111163f7b37fb865b2f42d36650ff749a5a23e99f69375c3a59f0525bb5e4a61daaa0791ea63ef06a3008b44e4381cb5b931601249931f1642c4000ba3a7e11a4d6c85c2068067bf8f9937074b1871ebbdc562f3d5edbeca96fad8f623a1f9ccccdbe3a57d8bf36817ad225b97d626e97f8cf7af46349569914bbb2eb8d0f91ff65c61747e0a8e9ba1ec495a77bee955af3e940ea920769b5cc008465d7ac46cdd207d5d1332084ebfab3efd46a50aef61628464a8c9d1c9eaec5e9a30d2a6d62b7d2d82d60c30ea3750cc863006da57078630f95d44946707c5bf769907a112cbcf57efaa56a3d0dd2d953a756ecf347e1e86e7df524efeaa5605fc0c6cc1df0ec5e6113e4637dc29183c426c9187bd309200401ff424fde49acd56485ccb0c4b7625a174e1da554a606f4361d34478c9654b0514ba5050f5103ddd950bc1958cd95ac6a9463828a973be0b7742635434025372665b862a208eb2f30e207351ea94758e5cb67e1e86e7d39c25ef2b10254bc02cc87a606327d7cce45bcb57f79d862ebf997870d9a9e7ff9fd1f87f73f7ef8e5ed0193eb0c96b8b257c19a3222da5dca9a8fd581cbe0425c3aff78ca924ef75df576117a41dc2271edea223ac38d967111efde2df9d7901d9e0368376ec5c4bd7d71d02b50fa55aebc4c972efb3bf359d06ec4b064962b6cf607edc4140056f94f168eb885ee66d082a0895452f75e8850575ed3dd48b15268d5bb3a28ea5bea157eb6bd3d1fdce5ee73cd0d9742fd321ae949e2b644f4786d4b500fef3fed3fdeffe3c3af6f2f96c6355e19e344042b2b68411d2f510b10993ace886b9bfdd97b028364eb969b2edb77fc79ca290326ad50c73a772584fd561fb7c7b57fabca241d3732c6d3bd774bff0c951367aea04c47d65cdefebe0afa93ff987b8c49fbb5180942694d17a1da7cf2c406cdf1db90b8f38fbf4c71f82739ac5e88eda6c49f5dbf20f5571f3f7d78faf8eb6fb76f2e3201deb40266e4c731fe44a30c10eafca7bbe76a8c0bb75ca95ca64b0ba7882dbab4ca72892e8d5bf92bb2f62c2c97a4ed39c70579bb79ffe9b70fcb779236048cfed551768489fab5a3e51831c25e68b5ff9feff9cbe3f236f1debc2449c7b2bd2a36c736bf2434c7eb1744e6aded51357058b8492bd7b5b640d2ed70cb0458d220cd524032410896a987dc26489caf6b819b63e345c89b6cd04c836a869b6521ec3dc38913aead2309a06ae16c530244140ee3bd1eb033191e2402f4c44ef6d71f0a4ebcc42249dce4ae5e4a05f6a8d4ba3eb6ffe9c71e7285274d61ea7f6b7981e7019fce7af65c7f59c2cbfe7289af07f0841bdeb136da9e7a52f8031b623726fc720426d93874f85569a5f043e7eaf6b42617006c50c30fe8ba891127e1b270a00f835ccafc33b0c211ebfeaff6a24bbd67abd7fcfaebf772f30131e05fb4babaa4d92e2c1ffe2873c479cf561ef27111f0cb05c1144b8a4ade3eeca6eb213068d5c80d998b93e5c367c39a9b147581a912ce0a75c4f25ea0b7649954e661509fde9f6b2c25220e036f509c10cd0adf2271d3286ba739bd311b3f810956e0df7907e4193d64699eb72a9655186430952a80420cf034a2191491b9169a76c89da9a0a6d896185b003ddca9f7ec378e42b05589ed8008ad9eb490f1e2755274e5a4e686da2a34b0be29807f6b0f1a37435bc599e41701b831733c065348c55aa45b6019787602706f3b00c6dbd6efb69646279df8ae266ee8d9080a806654c2730aa8af7cf06e166c9770bcb30ea73e90f208b03f464bde06dea683bdafcc9eac5099099e3a9cc233c20df3e92a14522e1310a1e6d538a8a32eea1afc7b50a666188d4a5be09721c5ab5168c0f723eab959ae46eafd9f492cab7f290618ce7d78f1a490f464ecba7e0095c0537f8abf784ceccb70a4af74d885a9f3e1383103a4c94f79e2f210803ebd3908e0cad630f0cff7df71f945feba9347193e106caf36dcac2bca5b8b0db28f8cd8b0d058e82ac9ecd18cba5d5c53192e548b04e41156e2a4719a60306c902ce924f52f2ebb701dd46b0710138305b78c86c089c6a90e6a2ab99b67598f5ec5ed542ae0ce57529b2ed5a945e83580a806e283b9552a3556e7b5b6800be5b4fe8423f9200669070fb91b6e90cae2735ca0f235e2d67c2eb43222a7f784c1e39abdeb81e56dd22c6de98d6cfacca896587d10321fbc74d6c43a4839b08d67697f6d010990a70d0ebf36b065530d1e56600610035380d4505ccb2b13e42aea9bfd63bdf6650ff9f1f6e7fda7ef1366fc0d08f4600ad833f34bbe80a52490c7bbf8c2e7be2796928485f846c688989ee798a0cced216284d24ab43f9b6b4633820c2d358908c50992437d682de8d3b0b13a49bfeea1a310ef2d42e904d3c16c49ade117feb913602be98c06e1e93eb7ba52de554c5423b0460dd8fa20bb4180014b12d550d614e1909acc33f4c411c398852c07498605f9857f5aa040848fb809f14a6027c43f4a1989bdcb03984048161aa906a15b016505f0f46b10a780df8d00a8d73322725da13d61db9f3635d73dcde14ae2c8cd1e00640ffcd7bca2c07a83d9400c1c83b221e3e8e99e0db19c83bd2e5e796ff5f7be525b60d0f99b6bcb4a416d993f3b6aab218c9583942303c35ce822684674b18d6e191736fbe4fff5fef6fb187d7f7fa7fc63b0d273a91f3ef68e6ff793e02a5f881e632fdda7144104610d6a47f396efa09640f0af822a0aa18e4021de730707590993a4249f76f08b3d3a692b5f43871ede9fee7d0ce8ed9b5d2cee0130071403d92b43ec5b274b32dc5ad31a24265a0590779280318ebba1d6db8acaeb2a25c3040b4a190de049a8652b3ba382cccc0800cb17f7b556b9db9654bfb225aabfbd3f1c3efcf6febf7f78f83ea4a2dfb06da0a592d9acb6b32654e7e2aa39d7beeb24b34fd935e23164eec4b5ead6382b955274eca452295a21369d75674ca3c80894882eb5ce1d787b8bd7aa6b06aa0ca0c332649f2bd96c623b1d8d648874e0b115db8177a1c94e8c8c75f04ecaa45a6d311a93a566b7b6ea0e0eceb3030151e6505bcbc3230a687acdad91c8e8b2538425f4320eaedd4d73a30d890acaadd1abeb2eadcc6e99a94e1fd74b299dd7a34e83b5f1ad02693d3c0d23110e6f9f9daf75c9427d76d15dc9f0b5ec23d398a5d7dcfd82eb30fe642c5098bf77e7092e5c7f7a579969f63a765a944aeb8056222eaa6d774a84272db662c52ba31431b9b2e60a605106b6779bb5ed4e89f50eb7d1a42110ba1461dd9b15b2d63aefb857aa366507c0a9aa3676bd505593be93d2a968e963d794aaaa003e7c980dbc2212a75794c213895946951b06d372951f3c3175ccdd2911ee80dec64599fc23ea5ebb90549bbc1bd4788aec6a51b26e5d76ac9386f1eecb4afae93e07b6b07026996da2da84cbd4dd2971aa366636549ccca976e5834ab3ea7794369aec4e89cfabcda8972a50cd67e92c2efe85cbb4dc06b12bba3a5ceab567844a8a616db5920820a82b4ddbc5dff5d1467d8eded6778c79c3aeaba94e45bbabedd69fd5bf12652e882f2bb3ed5d07b7ca2a3b2e465527efac74aab549dff114ff2e1d3b387a34ad73a745a8f76297dc2e5f8c579b03ddd9f55786bbb736d4d5823edee64eb9503129ae2f35ea45a7ee3cc14deaad328dc19577a744b493b958f75677e55a46a18a71c58d7ae6ea7ad798a2bc737ba8d779cbb3506d6aba7b4ec5732a59e9ec5d7950f5f169c946b594de77836a61c6328c4e35d94daab3fa00aa24a597be8b61a55eb31a55eb5c775610d22b0330cb7dceb98b5f998b7f9ad82e8636d9313ebfee30b8b57e3ac690343586b76ab63b25206ff9781809535b500cadbbb2ab3e3db8c497a61d4f1aeb8bea3cac05cac7025d1b99b24f266dd2347c7b038e6cf311d6dc1cecc5ca0cc2749ebbf54551014d7ad4ebe0c6bbe7d4da2f509fa359d4f061fa83ab65fc0a67ac2895aa609ee2ce2dbe5776ebcf29eca1529973f46b294cb359b7ddf42986ed07656ad2d405684dacc317a00d471bbb82a08739437c2271cc03efec797cd8c1cb238debce13a5f7be73eba8541068cfce7aab4aadf4ba3bfec683ac532da38c5d39acc91ee77cfcf2acaa65ec4e89631ccc9ac50e395eb33bbee6dafb45e759c64e5aa5a28895e963ead89d126b1cca973de8a777c2c03bab73c713a8ba87ae34c4c5160937cb9b0f89033f3859a6c90e8936e64ff7a29dba69959d9baea5216311d5b8d1750c3c72777ce02e1e889f3f1cc65e1bc2b686afc7b7e789bbc6d2b32b54e08c51386ec6cf0fb1dcbd2203606e1bdfc171971bde767bf636ac1dd7b986fa3fbd13b130380069d652c901e5d2aa4568542ac74ba7b381f2f210582eadae502eab23a3b57c3a9b578c97d9b2fa442737c2728925e0a5e3d5f96ad20d2378f66c8d2e6ec92c77e206912c4a3c821555b42626699606d9a80075af07859f17d908b6a196d69f884e5429f049bcec7ee422b629948f5bf2b8dc7dfcf87df6c1bf6173b324117b14a0c90e1a8668cb674099516e78beb6c7f274afcd0dd23be0ca62ddefe4e790f1df4bdf88d3b675a0479d76b2c10932ee6c2c91338d93abc4d9a6f7d9639feed9079b0a50e87608d0b5d2a8754c0792e26f88b756b79b0f411a8f4c3fc46491d69f237ef3c032676b3795e58e65dc685bd7c4a2664eab622b0e552caf9e55da239be1463ca72f2508e12be94aab83f54d37e49b06b10e22202204bce481b2fa88e0e987633ae1308db286acc799633a2e3dddcb18d89e6ff6a852ee46792e615e4b08482eb13fe90c12a2bb25e9b8b025eb9fdeffdbcf9f3e3c7ea7ddfc6f89e2f1310fd448b33d3621d71d8752d184bf8bab31c9db08e1c43d4d2a582f2df0921860b1c53fe0da036c6dac5790eb5aab0fa2c9bb8d713bcc9659468c9a4f80d98223f5bcc6f27cd2590940cf46b526fc5dd33a886bf0417706711a928b5f05155f6d6b9e48235f2ad7a24a06d2b105ae97391c3023dd1b48e30137cd0f388cebeba9542ecbc0a9493705e17475531a3e7e2724dc6f18f95c0e40c8af47886ba46c9c70ed3606431bfbd9d6bcddc83aee48def9ca4806d078e055c9183770f0434405761b9f43bfae7c5aa973cfc2d4cd05cd8253dbd50241cac623861e6fe201f49306bee556133697525362d98b1a8924eb2b0f835930dab5b52c4fef80368ab0de05b234350a13915da0abd7b6340ef271f639b6108397333363cc0e4c83237058e67625973d80a2b1b745e4e316f4eb8f3fef6f3f7d1f2fdc6f21899392ca15cbb8c6b4b092fd03d7ee0554dd9d0fdf5b707737c013f42b7985b93b8d013e09b572e7ba58b33b1b8fb361adf88f4f5daa7354e1569de3c2469dbfbffdb4dcfdf78f87c3775a79ffc638ea62c94ca8b95d3fa9b3ff6d80c9acf8074ef19eb9e77e07237b019a0fdac102d0717a027b95736fdc7c809fc0945011ef64809a8186f06359af9400591e0f3336f47170cc16478b0d34f5f4c11684e209913b9ccd1e5110d7362d496cbad5d413f703be21c5374cd09cc381a021e13a772a8770231ba49e23afb9b08c3d0940bf733edd67999d8ae459a82ffe9915c459e682456a4821cacd75890eca0dc4981d4f9e5d5f6ff653c863481d6fc665c553eb7a323f5f7fba978e39a30a5503586261c0322eb962a080a70af59e1bf5112916ea3ef7740a7dddf33322de4624ef6410f382c9ccc75fd7c74926362ee0dde57fc4ebb668eaa47e79825f9e3553d703830687998417f5e207ce3c018e4e38538d787baf5ece8d06fcf6ca808a06502945dc99d61b66f97a4dd62d3559b2b8a54e0d38dc0d5e23b5ae6903cc0788196707e42b5821065c09eb48a6a4f36041ecead55831f1b81a00af16afc548adb598bc165dab4ca83a2ff588e41d822ad0551a066f57404826a81cfd6b02aac6b25763f66acc0cc812af46af450435c28d4d18c459ea55d8bd3235793d062f8acf119318114d09d508d723e0fa2b4222b5de68d952f2b96d2bf95e8ba8c44c4d136a0e8e58b6a6d75acca8c5400b005f3a834a032e3d7ad1a1e67cc8db1a29cf2e5f1a2faf3f2edf8fc2febf46ccffb5474c2f84e8a4e94348f1fe5cb01886cf5997d82cf9dff0cff6e10f9e4ba8ea9a5a8b5e6934daedf471107fcad1addbcdc78507d9ccc23eb2e0863c98829f1023235cfe4abcdf6ba8c4829cc6db23fd74efa65150cf3430cfe4f0290c6eb2b25e389e0b20d68723d866c0331e711be3ce13abd9eb7df3d8bd2ef6ce63864bfdf3dd875f7fff3e81bddfb42f0b5b30f4ef462d57f48075798b05b1dcedb8ba6579f5a0823fbf5f8873ebba1637f85c1d6936edc86b2d85930ca37e6dbdb9a158ea72de23d06f72f49b6b3505a0993e8f0efd797c00b3508c0b1821faa41e03c348667befe8700a2e312cc4a8f0234e2399ca83ffc5094f00e2ce2559a3f3fb3890d7501f74ff46010018808a897b8aeeefbdbf2f7058c28704792930539fdea91dc1f37a25c90d308d3e95c5bf1fbb24061074840c3f7886c4ae323cffcbc7937ec7eba209c9ba2897b87a4928ffe7e13f994cdee5da4e7ce29f5d51d996d6bac6117ebd2457507f6d5d51d910f1c7daee229ef5bf64ff3f58f65d802f8abe5fbc24f96f4dea6ba9d091fa352420a9e9a67e74e552f0b976749403d78ca281cf44e0a811ad62f0702e0068aa331de8a402fda1fe7314823fa9fd34577eece99dbf5bb52db983f501ab90158e9d2b5d76892bc773271aedc88f55a80ac7cf13ad76c752f67aee8f08b643082e4ace96d4bcfff9f006e16a9ba5d9ae40dc2ff0ad2c05dc0476fcf7c8665f8fc6af52f6e0fd99f06503b8f104cae86ce04fc8cd963c0c3e705cc1d0d1c062803034ae2400d74c5a48c23b18c0fb75262e9dda1ea4ac006f02d3b275bfc88880c9ed151d2c6a7fb3c1e2d256937d7a8b4bfcf0bb2ccfbb56faecb8283db63a62796ebd7abab022779da2b6f5d96d537af835c6ea705ccda70bc7cdb06c03919b97781b1f3ec331ff9c9a319f32c7ff4ff7d86cfd3b1f08276b1bafd6ceca86f25fd5f35fd5f3f28117078f4f17f685706163e0b8bbfde7fb37a717b38c9dd4f683ff32b0607907e0d29d0edb3d9f85134de4fde95efbccd50deb6b7870f51d0f9279ab9da4ede22feec8cd886d57ae054eb84c6c7b61a3de762295aaec44852a9eba93c654a627afac1b4ddec3735270b10a93d8f1ae5afafab89f7ce4db090004ca192e6d09a0d61b1b2fceee02bef5cbb33e3caa941fcecfae4fbee8a383f6dc12005cd814804fef7f38fcf64611f36c7ce65ff3192add958d4be87667c078e925d0dd674e39e72e3b4fb0c904eb2e06828c825861d114e038daa90f8c35adf321b74eb3069141afb7b591ea4ceb4f39d2a076ea530f2fb2eea537e2de83820c6484934cbd2c2da108dc162d34a1ef5544b9962e9eaaed613dca388affd3e9545a9154faecd44a059eb5a6e306e798fd58eab416853be303a5e0131303b348108dc0b0710ad8ec5196cf5ff5702a58fcbf1cab2d45b5e57866545b5eabedc5fbbdd6ca1869fd59fda09e8bbb94b4befcb3573d7c562d7b058a0de38c82ac7a7853a6b5492f0e9a2fbac076df39cb70b90fbdb5de03da58294b16a1e6d61156e607607178022360262934663d642e8250c06654aaddce46155c3ef8398ab231b5a1879779f7086261d7a18d787020094d59a91df0bb20c0f208682ac066c3c6f78f6e03c615cf5a1e803f8a0c2754d64e88f59c585ed524241d61fcc3f89a6bc59581cfd8b34e7c21800fb1ab35f0e9cf28a64b3e16e5f3373d9cca15ff2fc76a4b516d391e896acb6bb5ad3591a2267e7053a2a0d6f499b31b4e00fe1deb8b3f7bcdc36735924f655ac155ff406c5f11d80ba2fa1dc7fa6fc11d6a836c4862208e8d6b1323eb33292b99eadeca442053a7dee04a011002b6c08f9b95e6a860549f4d17840ad45e69f61ce35a4b5a89593337f36127f9b0a7559391c5803ee1b948c31aa69ad631ba94e66aa22a883fc47bd48aacc8e2a34d230321bb4f4fd3877dd7474d6962efad5385b73616969a65ee4aca722316e1c6c01780cf082963e7d3bfcd8a7f38e2776c1cfc4b4a092e9139c6c2858af8a8de0032506260b4c052301ab3050082f6492c00e0bf6a76c332ee6aa1c9ed16de95e163798a5a6e36b2529b00cc9e15440bd5eb5948145801c3ad572a6c3e07b6def660ad2d3e419357e060aa03de18dc82e2bfd9b3cb2cd865460d975966f96b3eb38f790c1a2578f4648c3c8827bce74a6b88df6084706a915b702f0703f3ca67a63e3c4deca2f605fbdf99a9580b7412a3ca1649661af5f20ee6731fbad4f75e9d29de9ab6ed1a6d9bfc4c452e1d7cc3472a72b8d6f18960798c13c1f23a6b9f0896f7a08bec9c583bcdd869ef05cb712a422a58cd06906f7ac9ae9c5eb22ba77376e574ceae9c5eb02bef5bf3964f5ec6c186f5d6c93d4937a075825da70b9551cfc895d319b9727a49ae7ccead7c4ead9cfe1cb532daf992706c89c5fb7f7d7ff86e9011dfa04288f9dc391e79c54efdc217cfc6b6732b6ec8dd875cac71cff3a5f12bb17dec48c293dec4b53d57731fadfcd9f7b0dc310b7465909aaeea69a8884fef2c2067b2db09f180bcfa09af0c9e021503b7e7e39da1da5e49293760ccdd70bd7bed89e00485a99f8efbae2b5b9ed70aeac4bf635dfd9fc7e5ff1b1b9bafba2c6447a9d994b4e3c52d71fbf0fef0f3f75258bf65c1b035aa3e14f4430ef6ad5b8367adad3eb8257ade0caa6749a3ecb1043b99188282706a4f0840d5e6a0d8abaf49811e2688aad6514831ca8386582a3112f168b723fc44176a2baa0222fae7fad8cc33429c3bca029ed86c46faf44e6a10ff35d24326ceea239c6b21c927fea0d7e30a6269214ed298387b8691b474ba88af7d6ab1cd965eaf6d36f43fdf9cbbef6cd4dcc8f5ead579e805bcf8f1b370a3e11a13e030689a64abd43b00138602c0a94cb9ae00a868c4456e9ee13bf5c5e2608e75f69bf0b2c7c2dbe7cb685762afacf23d5ab9c31ec0d9f2e38b45c647b6e24538b85dd427662d5385bde5b3442765b875f76a2e5bbc2a98da527cc7faf1297ef62c958600dd8264745797eae841b80722b157cacaed2247a7cfb80568bf008e9f305edcce37cf3edc0ed4e9ea1c0364db4607e2bb20c838362f5680c73b30534f9a7d06acb08a1eb96cc7a06e727c582d836cd6649309debfd568364c43a90594d93941ec8bc5ce35ce64bbc9306432f6d10a5335c037815494ddf2339f72b4f1d33b0e07ee3ba9ed7174aaca87ecd6a09411606135220bc106e93febc2c384165baec129c8200cba796d77edeec33fb73be53fb7fbe33f3ffcfacbffb87d78730c602099af7287c81437601670b6f55c89bd8da777ae70e7bab6696057e025cf3c0320e27415a92be3753e13a040b00f912b2fc515b3ec072281828511a82cc9c6a38dab40db5cfd3adbead619be8b7e62f55c942ecb0a44713c7bca967102c8ae56beee69657ccdd3beb2685ff7b0668f3147b905aa2f1703341602eefe304328455ff0f6c3d3638367bc95643e9e9da3971cdbe5614dbea002a9cf4c20f58c08043ef9dffe9851b294014961b33b33e2c39c3ef04f9a37525f517c9ebbd185be77bcbcd5073fbeff9f9f3efcfadbf7d9f5f816ea7f1fb15ab9c3aa7ff8f8b8a15511f519c19cf9c4f5dfea334bffbbb22e3045f69757f1b82a57def0db8f7bba57a0086650f8a88100764581670d025623c0bff940d027a0f786ab3c3510668e975da40f6089010142772b5e184412b1f815cf0b2cc295895185da4c02b4c24a8d5a4fb3531db991ec5d0773d31f28a32cc9649248eca20fe0d559c6a2639e2d73770b354fd7fa2793892be5736f75928113d25c623533a000a7d2309a730172490225a51b9f09088fcf25b46b9ffce2db965648c2c5d447c08ac0b3e3c703fc0786e418a94df8ca9f5dded78a3041f109d982f716bf50290167917512f8415d911940c5043cdce57e7014e5cd5e70bcb8d907d043fedbed77022bfdb6356b6ec507b1bda76bf786946954a1744820e9550dc7f5d9d61ca19c3faa5c95358a16a19c8a404dee11a99946b9933196f5d2297813d7f3283708079aede91ee607c651ad2413b146fc797075e7e862608e88323fdd23aa485eeef5be50621ecef5b6f8fb42637ba10b256c1ebbacfc9d4fbc2c4f47b1d816a8e3d5d724eae1bb51427e0bcd707375f65c49febc4eeef200482c631f43a88fb1af6e389699ac0999ba326b24d535e492ac175224afb8546a8ab893315c3375f152acdfd606f489cac34d0461b95628d377795c6ece17fa6ffaac6def5a2705a33f227ad81a0de1850be944c4aa4c01106d090028d71e8c7ae1dca95444c8cac4c231b0242307f28f143922fb35f742d6bb8f5377a23e10b66b0deaec2178677ef1525736d4c08b551a1e35733c2adec96bf6143990bdae2f8b375fdb306a752264b7d61706c20b797e7aa73e014cb9c152cb054be1e14b1b09f006db46d2c367dd241c50ca777d43c660f63d5ff1871dfd619b0ff26586cbdd7d7ffbe9ed7576192ea45a9894e7c13a4957d734f7b563f320f581edb9da00cde66378add80c6976c575ba8978c81358ad663478cfd6a9d791060c622c6ec39c767d42662ac7f54c0b2bf2947cdd2ebf732561e8a11702e49ea98f3278994a05e939c34fd87c0e1289746d5fbd21ee5255a975cb8dcc7a964943018634c4b2953b29939af5bdf900601d0a12b79a0ccb0d80d389f49f7ba90871172c750c0c7c1a28cbb5cf5c7da8a9874a95bb6b93d2dba2648c0da7c2230f2a45bca8cad387542bba1e5d090f62ee87dca85acd2a773295d8c0422ba5c1eb973014f56a69bd9907b55775a89324bfd211fcf26637f8b7b7e776a9c5762ae5169058abef14d23f1ccfc0bd2872fd74af9267fba3ccda82d45b65d7ec3c7318972f33b70117a5fb7077faa3dcdaa21c5925bf7cf68552c3db8b65e43f7cb61db9c8b38d1d7ffe915f9464d84ecc4bc22ddbf8a392b4b1e32960fe7e59908dccd6ec587ff98f33cf164f0e7ef43fcaadb252877f51db5bb94b59dbe66b9e8db6a9f295cf86440dfbe91e3af257541f9a5dd80d51efda20c724307d2adf9e6586ff8aeecab5d642a5ee66fb819989e76efd59e9a2bb0be7927992d8ae64ed54c6ae9202fb61c74a037e2e99cb0f407c90ddfa73f424540256dbbe56326092d55dd94da119df5068d41b3bfbb472fcb4ab33712947e1bae13a08e00385b8ee84731d24bbcab9b9b5795b07e9d8c5df15896c50602bb67ee0b2e3b2e75649774040142fc18e6ba3de22d9dbad5700c8b7f1737227ec834a3de44aaded7c067851b8b2f3fa9483d7f3ee8bcade9d2a7b4c6a75c73e488fcf3a4a5c29de74973d117d6cdc1e52ff6ddb15f5f7df7e3bbcbfb9fd3e9ba0dfb4340a9b5eb850abd76e05e84c3649fa0f60970c8ec9d595c26a8f659167c29fd8e46cc1f8d3ec11f8dedb8c3f810ea25424dc84bef412fa6c6df08f73ea45362af1a9191b5a0c3a0d9a86b91b64b6e262dbf5e95d438cda0de8ad1f67bb0ac8b02456fe2e5ee1e626100cefd35bc28efefbde9167f377f8f35ba322875140ec3d5ed1918fe2b829c3c78b1b72fce1975fffb75fdfe2ee2ab76436eef2b810eb7a640b78190718441a67e2f33997593f43a2c6a6dbf6f36ffa6698e1b005783fa01d0f095ec9d5aa9e56ba1192935d852d7c2d6e30ce2573f5ff8d23768c1377174f3158d6fabc47b61a4e73d5c4839ae56c4f5e5b5cc3f2b434ef8978da81dbc80cde565d03bb3402194bd6cb72736cfe2db1395edb969aebdb5f7ff9fdf69737e7853d994c2dd9509aa32f99b4f47c64f855e2823d709609702b5d0fee9a904c7dcc953adb556d34a72e79dd552c9ecb1448fbbc82631defdc071da915239b9cac80ac57a75b1864323c79e7c697c93c3e1ef7b7af7a3cc9ec706f13c086cd8ef8bdc2f02daaadad4777c0481fedf4019d7ae97fef1b1a0e0fd8c31c35fc741b787c7a933c09e8df95ead02c9dd8666ea4050bc59325ad193c3727cf5023b7a4c810b90f0cb46e4e6352e77aab86dde5f5273016d9dc66964e5dc62318c215dda5ae9024d39a37ae7f4823f3194449bb1d80fdda39b16b2e76eba631760df0b37add311973526ad6ae6265b4529d0a2264af09690045b1091eda53f5d8d37d57129b59a4522f7ca7dee2018cc2a3e7b1b6f88061c94a95c12ca4acd96566f4acc43dd746551b38c8e0dad5a82f79d230ecc63743210c0628778e5b73a532865f2fada6192e0846ac88487663daa886f758af076df07ab3469d9fee6528c91c59888b1e807cae80e80974f4cac35f85272a7509f65d6d90a789866e3c238b2237aef774cc8deb29721f98a44952707a5ffb9b6b03664ce1e91f893d04d282c78a8407be82afaa6aaea4881fa501803df8aa1acd58ef1680b68f86fe37f8d01b8d31d31c588c8a95d1a8f369e40de0bab4dadffcd66964a6c91f2e63bc786d77ada60266a5feddafad42a56a6a8d86cd05d2e90227b57bc517a02ac9a8a07998348bad9d2cfa9881f3a758c242117710ae4bf1de773c52239e802c9a731e1a536986a5629bd1416b5a7f5664112529212afdb29bd0d9247261fa395ede9e81fe8fdf7f7b8b8a0b98a2f45a652603c35a4d98f953ccfc99fb23d0fcbc7f9de6febccefd58519feb8aba9e69043926ff1bb0edb8c298a4d204c9853fd2a7ffb44eff5be1ff3c2599b667b5e959d5c92c57f30257c799def4925ec435a123aec233dcc3496bfaf2e9f04385da945faa4de7fe02db4f7d4d8042062e884f5cdc169eb727360d2bba326eb86d78445c8d020fcea303e74ab5f468e38adbbe9384d37a070b0ac2d0642bbafc8410f99571e72ce3ce6fd8b8848d806dc70d1d76a7821d4aec35ca2babfb173c42b77d413ffcf2eb776205fe068b5bc277fb1527db90f53fe1280c08b42defda7701cc0967a1cd57c138f8fa37ad83cdc69beea5b6ccf3556fe4f127fd9f038064eb652cc3cdffcbef8207c59ff4b5be5085adac1099175e657089fe53eee37fce151a527c41e8b7088e71feb7dfbf5330c637ad35811078ca922b833daa6676fd375503688912fb9054616ac0fcca6ea7f8cc6470da89949b123e0d222a467c7a537fe04c4c9c11e1d2739f413cd6715f861b74d0a7c54ce7d66fb0d635b843f21082a73dbc2c27d85433574611837058685c779f65b891ee7dd2e12cfe415a6806b68aebaa07ee40cf588c7aea04e8e4e66a7612095fec431d59074d40a9c1d91ae1a218605508d4917cad5e52b713792ffe18134e1a1eb32d3c6603f0851bd5ec15ebd5025bde24be3da8b0dc5ac3a200c39571561a28b6048b31f824112ad9d2408010101f9bb74ff7baf2c360d603a04dc584db0614d0e4b5a2594b520dbedc397313b017fbb7b54a036cc9ae1054920c77a48aaaa5f198558817126065768aed3bf0caa2655fed112ee0973a855fdbea17f76f110518cba6315efd19e85f9601efad72d56c8ff308c88c44b3a77b112c6e02aa3d37bb6bf6b82e6f96d3b9583ffd8238ee1140112d40a4da8aeb7c5a0d3b8149dcad301558824c25de707cf68b931735c6f02b72550fcecccdae8e779713fec5e7ba24102e90ef1534f968eb4d01b9bf8057fce1b7f7f7b76f2ea680058c75afd023acab7f5b4beeb35de4d87f0e2df81ca0ffde0d8b51ee78caa30dd701b38df3a3daa9ce6380a73f4334c34a3fff7ba5163266e5d21a3d7cd0b68a7005be823ffdb556206a46c6fbae2401a0545b12633ff2541332be5129eb773ddd83b0032bf4ff61152c0695e23fee8d177b09447eb397e0ca462ff9d7dbdfbe1b0ffc37806994976edbe9d957fbe1d94bfb0b5fed97cefb4ff7252251be349c1e9e2d1957edd0741bb95e98482b2ffd29d0f7e81fbe6106dd6771fd230d02c0a124b0b0363035ebaaef04b405fe204f3ee64122f23c04776a40fef929c05124dc730279032dad2560cb3eb8d19f5d5359c31b96f5c9cf25882dea87e3ab509c9ecad37d05d96b9f340e792af5e47f82801e287391024a604956e399f8c7762c8b04e0dc031e0e44bb5589394ca699f1470b61c3ced5c65c3302d44af0d8a28823282fb8953b2e95ea214b716daf532c9960cd10711a601282fea8c9bcf45e139d4672d552bd840c46dd4efdd00749f23f37769afecea6c8a4f2f062cfe8318f891d71162c68b8cef91c3872c88d73e3c555214bae88b98e041e5e3e0cd7a1fccf8282fa1fc4ec83ce2881ff57a9457baf0c2fe27a9dc6ef157cdb4fb3ebd96cf9f0a2bc174781e8d25ba3405cd91a053e7cf8f597fffde3a79f3f2c6fcd474e35002e36bade8fda04673d4f7978394ea417e3c4d33dd06a8ecece9fefb8adab962e88e3cccfd64d8a6b6bae87556a0b2c11ef5c2e905069232533761037f617cdaeb50f84968fe84b6ebb54b00b6533f032d3c8b5d0bc16ab58b25e80d1985d77ae9d46a69a07a0373bf121eb0c1c3f5b32af9fc02d4e8d5c6926339ad4613ef5c4ae81022a92af01f967cd8efb8e5fd4c2c3faf9eb6ea35bc2785b49ddbf86d47fbbac78cea8ac73dc30690535eec329cd83b9bd37398b64567c3b6394141f04f8148d2a9dc675a0247ad9e6a47aa8de83a431d9e23d8ed3f05aa619b660a576f07265d442c79989c5ea0c973faf3a3e80eb17814c6e6d8d8e0af3f1096ff57a6996a49122c4e3306aaa3e3079eba4c1244ff7cc6e44953b74d783789fed1540fb81a9e225caf84a1f8bdcb4b56b99587a9de3a06ec676b7e9a4f8f8e41f03ca61d8abd35f3d1320173d75a74a7a08926dee97170fce3aea66077fbe7ca997bfb9a54f958bfddbea88b32a7fd8bfbb1bb30d717e016e8afdeffc0ce40b09040b810b4e75bbd5b25572e9ea87ccea963418a76dba69ab34164415f2f43e220822ca08846fd7321521977e63e9b9aabf18123a692675ab7d9d635c2c0edd5f03e85d73596d83c6b5ba098eee0ea906608364ff3e74352e21c82bdb05f6fbd7d33e09eb417d364d5284e0543a138c7a73f125a058a1db242cd294642dcfd4bc57a5b9f2beaf3e02ae61a9c6b45bd204933ce62cc1937d6eef814121883c37a1918d06dc95e1b9ba64629f7d310f7ad1228cbd62d1417c7e57e0d5f2245e2c1ddba125110c353e3f5794752e8c0874d07b2734b04498a6fa492c3360dd0768fb04de8c79c8d51b55427f21ce955d5518110c2ad90acd5c1bb53cbc0575921cf2e0589da9d9e790acbc2094896a8c51839af7f1e90375d407a05ffa5df69bff3ff6de6e39921c47137d153e40114680e0df656dcc19d3456877cf568fd6acefd4ded91d6915aaac93ca524febe98fe183c79fe411f9a3d4b4baa7ac2a235ce1ee743a098020097c5fc602d614ad67e0e8d83d6576004610f463b30ea1121ae95630569c67c087669e55e82555fe6dbb5d7dfc707fffa70fbfbc1228e28b382b07a0104aa664bad2885bc85db7ac4c63d8b89aea641d9a69c09f63e782c14a2c7c3bad6b647657a55e265c1721017655f43becb28655d7b5cd0cb376b09835d216a4349059ec1e821417f310bdf486c5dd3523a16f64b26902ea62d78335c12e476d82d7860bb08372d7d0a9ef5e0e0f08fe00ab53f0faedef6b360e65460e639e764ff0abfcbdc3be3a65ed1c9a83cad872af547218899a4cbb6778ad00d3b17bf5e20f888707588d989ae28dc517a571f9e3359714243792be8d8514a365377f031353a10a94742cd0f6827947f16384b0a40e9c99eca434d89cb369382e8bb8cc4a8583d3dba44cad9b6fae1c5a322d6bc50e380d92beca1550d199434ed969d49062f2534ff3ef7d4e38049431d6d14442afd45b682978318fd7d281d1844974392c7c95d9a78fbb3ff6eb4dfe8bfb6761771c764b25c8a4f93e859dd5f513d55d54fa932bce68ff5b1bc7b178b962f65de734435ea35727c080b3639670c62451815d8f6926d58013f384cd7508bc765bac7fd78a991fe6983554bb46ec6a24b0ca150f997901e6ecf60876a09932e824b9bdd44dd5afb8b835a0a93b38147104624b21403a092a1777956bbef09fcd2d04c312763dc64a31f49b67521d9e62e88cb28dc52c96b9a1f2683ecbb766f4c556cc567cb178e6d29d29e1eee7c33d31eed122f3d19a32968de77ccc1716734996cf49f082dc6e6fef5f07e2ff050bb2c544318792cc80ae2b31f2bfb126336c66a1123b0942aeb445a1ce306a652dc812b71b561e9465de8e93e950aa41ed7a00b8adabb95712cc9be5c98a752bdb613d7199151b50ec36f2a08af80e69139e6fda81382cedb807cfafb8e76cc7584b2f758cfdbed431efdefff5cdf54c35ef3be492cccb36671573389b38da28c33615c7e20f8830cc0fc73295b559b126838673c34e9e5db51d702275c2241986075869f3c1809bcc6612181b93d50368ede36a7915d133e69ec55214ae133075cdbc21212c600fb27624ef2bb26f23d681b0fed6b00af0789d653696c5ec9c79ad3eca79c278a672a3091b3047ebf7fed72e2c791f848cc5e3a550e8fba70b14a33eec19b74f957e83a5a9c937fd127676c19d26918b5d3c3c0c30966e6f330818a0bb53bb8c8243420164e17405ebe112580d44725184edc4920cbffff3bb8ff7576f6d5c042a5757cfba5f0cee71fc8c45f1bae2c585e933e13d3d9d91c8c5e81eab0d885cbf1c97e5ceaa9136b1bffaabe47c4ebbcebf8b93577fd5ab5c49ef7b2cbbaf78932f0fb992d4bffa45247d45c8d559fd717558d4203fb5a04377efb7effec7bbdbbbd799508e6f5e04161bfa56cc1cd02ac0609652ef19a6ba1fff8bf36f51b4ff947b097ea63f5e83a601eb15d9570e1890b1b1996b69933626bd0769366cb64d469974a216ba0d0ac9d1563d1437a80d395849043e2bb62f1af2f97c3530eff628ee61ee31afcc5855c1020b6255da147d61437d61035fc81179bc9382e789505f65c48ee49e48830c1bcf3425bc95a6741fbb8d22e635385b5f2c991cb20101183930c75c1d4a148b1a180ed517208b39dd882d19693ebaaf8ddcddc06f883c997c5cac84f86d0eba8b2fb5e21eefb070c59df2f769129b77c3e1aad6248aa1bc84afebb4ea9dc67397396c6239ab2d3bc15f5297ddb933faf27fdffff2f35bd317680772885a78a223f71774e458b71eef2425f32d964245ee4fc33e4e233a4e834f1eef00d28fb826301574df3d50084d86ef13d21af0b7399bc9758d30a130c518d45df7d457c7b3ba4cb2b94903473fe5ae81470bd90a11c82b788f3c3f506d9e080d01df2c00135aec541eafb934ac5116ea2beea601d9658973c8d55b25d7fe652a21079578b9ca929c2aedf939d84e06cf89ae9d3b23ba6f4d6cbf8799bf0393535f0c84ba3f95e24b42fc7867fe81af05bdac1c1e4abe0328df2c16f5bb5a723d27b61765ec9c7c2dc9d687d7d9667a296664ede702e9cfcce454cff8688b2e65544fd53de3e92e3f83651919f1cc33c0257965f3c42f7fc439277ff911d72052e97dc3d84ec3049b07b550989071da330d53820a0404a18c5f6296ab227daa4c336e7e2c88db60f30de4a7d207015bbf480fc03ee8484ec52e6d8d6a4f60215e69d1903968aaa832a836a6a800fa6bbe0d9e2383bc9afa4a84e7df022303c96a6f92429e8e341fb0ea3d0e9d5f19ffce4bfb87c5bd98bb0f4b3b31771f7e06fad09bcb297136994591e306efb522138997e739551f9fafe9ce476e936135cac9bfb8ff354aa93f3d59d49cc3b13815df8f1d62168f718075caa818adcdd3037f66c65aab8de35ba90d96ae91ae1c1f5b213b82470077b82067fcf14e11903ce42a777dc8b23139ecdb5db01e8a0bf85ce70a8f42d295a6e5c963d5a56c1ca98364cdaa8e00da56dccc3c370458a305b082675fd3fcb60051ecd8cf9de9661262023cd3ab219cc1c91a99b01694c831bcdd0f4ebe25e97e01d6900a36aaa28d0d1a2b622b9a7d83aa5da6581098d69077d6119d65f5426c3bb6720baa690fc7913f05fb54f03ec039802c33ac6ad7a088aab2c1d01e826714d07120bf3474ac869b26e7e47ebd442b38da23707441dd660d5a56baf9e459d57b73234d164727d625145ed07e9ec2f0ea1e857707baeb04107186e18dddfe7bbc2ec57aab37e22916747dc7b22827ffaad46ffad3db96ab510524b222886c089ac96156cd8bf0848300a851285db3c91a8e58d421e03efb060f2606794ab1160f68d0c8886fe815014b423bc283227b62b4a7a19ebe32893327c11e9bdc97c6e51be4b62d8dcbe694b1d8a88910666e306f77dd54269b0bb5d28a5c0929302508e2b18396287f719b5642dfe6d9410bddc6cb0af8fe543d5f447ddfcaed17b4cc8e6aa7fab5edaaa656c2b19b3b57e037a66e96a3e4fa2ae277597bcfabee92debe391647c7cd9d473a2c5933528c1cd7c5e63436aa610bb284d29023d456aa9ec7431c04e16b3598e6801a62f2a41ceb24ea01e31822733c242f0785efdd115a63dfd597c899b14ed2036ba21a8b3d123944f0b32ae28bd4c1f1e7430c991862a37348dbd89bfa3cf63a86a74dc3af59ba095cd22b360775168d5d0fcfdee0935d513313d561024d168a1fcc8029942382e05a444c958db11edbd709db251e4a83d19c910d947d8b018014d60a3c6236a3a3661eece88acbf37dd8e788e41b789d53442d126a5cfc604e1f265366cce38983554c904e66f5ea88c891195d05f95cd9b374e6101f9b80d9d408c8448a239bc331f5d8172ab2d49215bbc362dd5a8ab585203a6bf86244d90534a5b5934137ea374eedf2f9c26f904c1a67972eee9210375ca70a796538e9100c1b2ca86f3181cdc8a76eee65e8e460f91a3a659485296b27ec83ef0cebc1677ce0a48f772024ef57b9bc55e1c9e32d084fa783f864179fb3a67331fae36e29e2e3970f7ffbd387db8f7ffe170ee0140862c954272c865b130bb672d577672b22409a871f65489b14738ac517f62ae2f343a31eb14858cd2155932c73aad586ca82d5142c283a004e44cea6967957766bee6a739608c413169b918a62a611c09eebcf4dee1697c957ee1b8d28b3d7c4aedd884c44e22bb6fdddb77707a07a9428e88044b748cb40c9ec11e5758a3eab9d03103104743f2a8de4a164e26d6cea19b40ef463830ce04d7b10bc031c3b04ba2214d1833707941ec3c9d89ada60611741b3e650224c0ef9188819eb5152f4268e56652487d9f8045356eff177f033b03b8cc414eb5ab48447fc68f7a8f4becd154b6136a04d7303ce4b0b089a9e0fd883fa41e48108804ac030715808701c7a7560ec509d9fb469d082c5846a23b039490872d5790dd90659049c9b826fe348d6a09978f2090c00f431bfc2620284786cdd222599b25b2689d9fee1f99d386a27ddc622318f50ab87159b94852a341eefc0eca8a1b09344510b03b1426644387aa0d30826bd92b64860d658992acc3321162f5a7f99b5dcf602ec9f09cb8375cec4f14106475aa8dc48a95b8fc22f743edaf4c8982c19a0a3d3cb96e82fdbdb9fdf1cf217408043b6c9ff16f1cce0c70952639bace73cb59b0011d55cb5cc566fa36f31c15f3329db2723c1360c204a6d63c36edc30f330626e3671ee4eef359fb167c0fbe38a310dc169f3ddf313760f903965231e55c2aa19f6b59e1ae6d22015c42e1a1c487334d7c03f0ecc037b87b1f90a428b76a55d1011939e319bb1f76f51eac527fbfeda349f174f26118f7143e0bb5de3af19abc96aae240fb1352adb624fb68f736966db034cead92437a43d974aba0c7d7276235e93291f0fdf636ce7cbe76c9e8b4d87ccc7f6abf249565d4113676a0f782dbca7f5ae9999e8a93b17a5c37784d1861efc6d8eb85f99dc7718db66a278e8e13877f19c233f77aff5f31ae1f15ae8787bd8e4c96d7cb37193b7fb1e8e5243f36db3f9d1323f9a038f2d1c41c85ee8f399e0d5db772fba9607641a163b1e8ee67397c5637e46dc3d44bcb6ae65fef656c9bd54226a5a6d848fc383a1cd1b9d5f8c8ba73ad8ac142f8ff30103e6dc42db7d33466bd58b0f9ebbe68276ce5d1cf69d3e0bc15e28cecb0db3efd5e5699f0ae9499e8ede10d2762f9e373abe260a04c28d2103b27db6f8bd769d51406784e98ddaacb27b150eb3525f148dd9385cb49f6661c25e1ca7b9675d5c79ee5558254670f8dcb30e1de1f0101d3e869c8f66dc8d3967462b9c5b1eaaeededeba7c71e12c4240dcc36410190e3976cf3645c80232cc3ab5b596eaab010f51060c6475030987a5e2dbe78a0723091359a83e68a531a540f0ab029adc44db0444f2e48f4ff334abc389b51eaa61b7e75883c0e1b1796a84679122c04ef79cdff7c7b85e5332e7938379fd0ae74682dd859568441198d05b678be978f5aa44c9933944c56a11ec83ca43b4aaaf3869e094c330691a3574fbbc6ab2f8b2620369f74dffe2260b798a8d8a3bc4dd53bd902eb86bf4d083a70d5bad019c92b78ce4e152482673c0ccfe0adc3060648acf69d9132c11abe9f82b63c502ec9881394b5250fb8b1f35d0aa63995511f3bd731d6cfe0fc0b6323f1eda98d90f3663f8a62d62e92be63dc871911969a6ee12c69ab9ba1d01f3c8992a9eb85c3ce15aac174ab379a939cd0d083771605a006fb6e1c00147a21d42fc3802654648d62549e02654a78e19fb9c4bc76e3f20b0f9f15a44c37136fd612cbf3f5eb038595f3849c67fbccb368d92171501b4917f7001bddfdb3de269ed314b387f2f7293fdd3de3f9617b5e005337ab7bccbe267964de8afdb0f7f7b6b7b2c20b46f75193ef9fe043479472ae569dd47488b485aee6966abfa9729457c556c78823815ff000e4356623f2a4af506bb9853f240124c67d30eb1c1ce6f7375dae00bde3d2eb68fb3def7d62356508c6ff2806513abd655cc07c6aa3a68147b77b4a192c807ba860c4bccf78be766cb3a631b5f06f12a97ea8b00666887a35dc280a62b36e158dc5362161f2d17cf0e265921d136636d23858c2db114342567841f6117d7b0fb0754a733710f8e0b90615173767c3089daaf0acb8399ddc924794688080d99c3bb16d91e9aee9c0378e880b37db4ef46c701ad8afdffbeadce3f9daea4d4ad6704dd2063a8cd01eb2c5f429c8997df2ffe1d2deadd3f21d1bc6095ccc49c314b766ac12e7d987e7e7b9b48ac04827fa6c41ed058eacda8572cfd815bddc65e9dee922a4f3103316550015574afa12b29e88484e115a4bacac9f91b0a49b1f999345470544a582899247942a6269262fd5f02481d1076bb15a6eea163363b1bd44b2c853222308b22a5a36bc8032253481fafadd68ee3c460bca4d47cb9bd53026a4bee2be4cbd290202311626eec2e607d9e0540cab2e19a6eb23c5eabd9b9ab5cce0360d9c5e3029e14c223cc47408b72fe8a1645ca2078944b373dae60c4c8086152998f2f372a03f0ae57d21fadcc315ad87d3bfe31283f93de200b263d5c827330315e127cfb7d49eab7b71ffff7ed2fefde1c08aa66a6d183825d641bb5d16894ca8db24d4d407649329fe894e09c77a104c8f8d166fccd6265d8e7d846481f53cb53a4c49e728d3472aed63940b6f7cfad48a6512309f6ae04d7a3d819a5b3cce973a36f2969f452edd956a85de30c01d9e1f2fdf3f1ba749b0348a5a6abd2c5e4050434a1d44ec34c7d4106784857bdd2c8abc600ba21e5dd8520a0450936d19090eb202bdd53d553b717811ee08d1ab91ac8f02053ec446f4a536a3a31920513100bb0c1804d5d2a88b469c3eaad66133265845a8f62637833b7b320f55bcaa09e61fd6d88ccdb41add95c4a4aa254f1a7d389b662cd2ca55e35a634d6035e41ea40631a0d4b7a78473088920c24d28c4ebe95212382198518e9bb7888f9b4d4c196bac5568c0d9aac836ad9faa608cb95e44cad3ddef1f024f25d2128d36aaa7950522f1455956aed8fe16b57ea55d181351d0801cb959ac13bbf14bed7a8452ddc9d5c52c58f9f7edcfebab9fdb70f7f7b35029517ac866310f728901b103e8599e420ed01a59ffc885caca4085e65251ef346abefb7b8df823dabccce48737c3fdc110969db531c75c5a32151de1ccc1a78241244fa84b95a60ac34bbb06139a9dc2167eb799537b1d46d65921a5b222d3f7aa6c14c6594059ccc79f96da53ffdd553cf9e3c1b31bfe60cd953c2f3a74813bc4d6e37929e561cd33e2e03329995aa6c631924665dd28fc7d7e626d464468d66523dad5ba18405b67d01e16901560fed69234a3d9f56a320579929f52d063f161ab2696c7f61c63ee4a4284d3092dad3953e6d8f4209db80b93f5ee75c3058a6b4b68ecc45b6f02b2e79764f746451c54e2ff98ca2fdae655fa765a22956fd9ed2af5a4dfa9d59eee9cddf5399b3b069734efafce6c7bbcc269add7cd9cf281940d8be55c744f43bea98887e918eb12a746cd4af53b1cfe9d705e5fa8f5fdfe21886e929480bd292b83d13604763b73b26f3a310bec798ee986eb957165db72254e8442676ca15a177ab58e04aa950d3c0d48048e94f4e8f77261df0a57e1fbefee5872f28c725e5c20517b5eb77d5fa72d5d204e0a7df47ad7ffd51eb3f16b1aa0f67cfe8d4dd87df7ef9f49a13af972c02aa89f8e699a499022dd9f64dac4f65e59c983fde4131be4660af44173dd0c5d2a59817295f71cf464afdd2aa3cded99c1ee91763c1ba7c87fac7aaceecf2425fbcbd862f7e49158ee5f99c421c5ff339b5786b3a919306fd2a515fd49fb372c5d24daede68cfefa894be46afbe4245f6cc1e5f55fe979b904747307ab95958ec9b2fd38bcf2ac5258d78bdb9cdefc3c43fe130f1dd7cdff1fd7ddfcf2ac3c5a9c8e18acbeaf0d674e17587873736d769a7731d4773f87d60f88681e1fce4613ebdac05afe62065f9f6ed53c66a8ae43e89a77366412a27780d82f29a5b73f08499f6c5b1290fe0f66bd190054cf3c43b183175aaf9a8e7236be70639d392e787d6fff9dbddbb8fefa7df77bfbecd231407d874aecfa5d1fe69adb12ddca9e7ad47099e2e1a24c5eb02b5c34afd52751c5f3e2c5fe79c80e2ae34f8b68dd0c67cbe945094b8a1e110a0420909fb3cc26866f1aa551cdc8225df76a5d4827fe2a108cc05c5d0e029362a2d64cf41ebf6a3823dbd233256b74803489350072a9f278b016f59113c3bc2a0c1a12033aab5d02b4238982acfc79c05eca091928029c0d3b8e260caf654465040a3341eafd169596e2505494e3e1f2445ff53d2befe412e8edda7ca7246d74e2ffaacd6bd359533191cf535457073de37fe6a6d99a307b804ae7259a0cb41a0858f04bafc2304ba9e11e89ceb170b742ef58b04fa2e72abf17b4cab5fc5887e99be7d5ed92e6adadbdc174bce9b50a98e6f9d6abc8a3bfc08de3e9d55f5f791edbfcdc876695a7a7cc96774edad29da2c1852fa3f9164fc570e11ff7ca3fe1b369e5fa2669fd3b165057b25cd7ac18457daf08d4506d4852206dc79dd07981d78cd9a43d56926730b3b32b7e0f3dd2df34016bcb3c6ccf0ce4141cb38c2e519efd9763cd7806fadf95e7fbde04e4a899c0a0aaa7a9654cfcae19ebd9cb02b27a09ca0fcb48a71aee2679624ce74cf42e7fc7afbd6f84a4b4586010f41ca4552e20c7241278ba9513853d7d033f04724c8a09a63c9e627032cb156520e4391bb912915a0a4033c4046acd8c7c735d1af6966f362abd4357257eab1db58313f287640e5306c7fa30676423b28a151078397341a121ab106b6599186deb1523906e51537b1bbb4271a8e6aa9dd533eb4a77bb63e1fe0261bc36ad613f53e75a6aab1651b3f7b47b24933bbe72547944c49232211b28d42cdea6ad5b22379bc96de68f49093509d58a8234bb517ab6d0556660faa94462c890a50681252d22b873ca800de25879a482a681e916aae1a1b3261999a44ce68de51a9e568ef2912959863b6fb9991f382c362ad92a22a8d61c5b3da8b4a0b3678d68c2214e9b109f4b0c05da7e6003cdea665d8144695f2b8952ed46a0fbb6f1f68b550025c8c9e5ffefcf57649397ebd5dd48de9dd4f9bdf3e7d7a25a0ef17912e09d5a4415227515d9532a865680df56cba57a89904760ddac4beafb857ca02508c5124562a3051543ab8f74643075bafd6abdcea4a641003abaf51d3168407690282f7a894707435ea034bbfeae926cfd96e3ce70476aa45eda8ea831940c9c46397ac942839d6b7e803000239d3e8c05be311c471f7f4016986df70df9e91471d7510b8c9a8cacd3c1b62e91b7b87892593d317676253b354fc6ddba0315ae45cafb80eaa090871b944a5244e7c5401daaa4818f176d3269366347d0abd599fc48e1e6149d66360d4545d5511922e41faa0ae05b2208d6920c3d011824188ccd0c3ae256aa33caa7db5521fafb5f720a3de3aed80f9948e9da7875f428f7dca4c2399df6d072aa127d0ad5c5090bdd42f6bcafef492cabcdb6e579b77d3eb103abc6054415c57a91bf3d8ab75114867c0ca2c36b1281c9bc9cb6d1bd425f8e7ecd816b380359b65b2df79fe74177550aa306bbc5201cf64c26ca40f200e646d216d622b0b9ebdc8820bfc78a73659481b4db73b6a6debca046268050af4a81b9b603c3b6b62c1a560501492d3f03a36cf4343bab2a1a3de1e9d020f74f75bd65446101b1df28f4fea66cd274ae359589c3a94425edbc83d90ead41ba96ccdaa28c052da69611d8d29a55e3d8ba345716243c3e3b5b56143601cb304eb1fe4eb669b1cb6c73bed988393f6ad0d5036292b946fb950471a5cef87a949319f37720197bc7dc6526c502f85caa53bacc4e0c51ed5128b6d656ce7fc65124619e060ece3683d2ea4ada41e61a6f944046c684421e71571a74b8b6ab83bb9a484effffceee35b53406b74641f36caf08acddd6d75a354dbb690e3a6b04c66483392058163557ac8d6b32660630bc118d19c02a0f4f5684ed198ccc18a1dd342f744cc4fe144eca2a46bae9dd47ca0c92f134f8b5780fb65bf089824020ef13e426b54fb6d16641be27316506aa0eed1bc15b0d416a5fc78a72270ffba50ca205436476c100bca484848b4af59be2a55f1e5f12be5ba454aa48d0dd04ce4358ae7d0baf2216951a8f2b600203491f2a4342216798506989b059c7de0f4e3b10512029234fb84eb6ce09f2fc31db82cd81d5bf880d554ace7b526f58cc5ab5cfb16588fcd1cbe5e5648e657a06b710f59cd390ca3c29b1d75b2f7961a52acd6034187798d3678c28fe4b296d4611f62aec4db5813e81e13715bd7645e3dd6df762f06b61b706dcfef14bdb278b17078b16037d855c16fb0ab823742016ea935d7b976056f2fafb962d0bdb20ef43ef02e3beeb18cf4d2b216aa23641d9401113d022a2b360940f386a30a1cd57557d5f922eb8370f45ada63938d364a152dd373188d72fe11b9c13dcc5f5ef52641b9533ec06269f06cddba8b444036afee90b1f02356896c52c1dba6943a48a78acd3e91eea9e6cc0b25786fcc7ea866de563c24e4e1cc9ad97c6ea70ce8c859be37b7a4dbfc6b54ac86699eb09ec4567007a6504569a05061403299c6f4f12df537af684ab146a60ae0cc0e3e7524ea8fbad6dc9d1659e7c6d41ecc2d9bfb09326273fa3c77916bc091b234ca353ad8675697c1b0d7abfe78ada952c23a65e1d924619ed22724f662994acce934a30ff315dc7c9999c36446dcecd9643e47739481f68994e37c6bfd3c90bc6d5f07ab13ddeab87d8ab04f2b9562e22ca6bcca85acfd91489ecc7452972da65e2d14706d9bed0bb07d103e7678830487c14ce0d679c5cca69e1f966c74591c92ecc4e270f4cb2faf351ebd3068aacff0f84e853ef6581bf73360870e47ec08bbe3fd15617703a077a3d35c9d4e800eb7dc1f5decff1f3feff8411140beee317c9fd2ae47752eb378f4a2fbd33f999b32ec669f725c2cfaf10e490e12c6a0d4beb17e7345d2f01ff9f8bd8712971ad27729f9a8093875d4bb26fb7a49bb1e55f7bc7e98b82f2b889d59d290ed874fd3ebd007bf0497ba8959361e666fb636a42740e58c3201c8a3c74a58542b6a467048cc9d1858e2799dcddd0b4d89c70438b91e312f8ead5269b134aceaa541a3fbcec1362a5679b4516d407112a0e835f64760a306442858aacabc35dfaf03fa50e078244ccd5b049a04f0927b2cc3cc6317ea799bbb15538454c0c30f8f3f01cab90b00186bc014a9c065b4e992387ad10488a701c609508675b539636fc01b02ea50e76d1d30bf85a44fe6d27054a4f1b0b99940b648bea895b766e7012eddf394871d0375058b61c906c2d20227252d004b96ad528bd5acf5c4f08bb00ec9e218cc1db43415ec8e636c2b10a69b4ede04d663152b7ac3fc466eb1d3f035bb0b461e12b928c438b324c41f6fffbe7a7b68918245a13340381ba0d49d41d11988e6bcc99e8100f776f94a90321f58997784d1f988d9ee087b07f1d9be7436c592e1610202524c178002f9e034d6feb4d3c281163557e3c9836edccca3c8b82bcdfff7505601f3801288c37a8ab950173be8e97e771cf067e8583eeb582dda5db93fe51044e35c3dee9fbcf193d67af2423baafeefd5b878dfef54d8c058f4bd8ac28ec6f728ecacd2ba062e6aad9f5a50dbffefb7db8feffefdb7edeb4022bd08e615b75ea59bb4292c0f85cfbff9fe2596de7d7ff2dcdbff9f0f1f3ebd5a8acb0b36c21a5090a430463b8c92fe09b04007d6023859f7435f1b4b6b6c2f35a55630a8a6ea9f97ef9a1f108e1e10f6d7075c3faf69e53598e34ac892e60784a3079cbb6b7b5cfefec2f99a3a0facfbfa8359ae6c8f4bbf74cff6b8750e1538bceb1ca090d745800567753f6e9b4bf73c5e9722215de5d4a83a076f013c60c3ea870dc28946c18254dbc60ed8aa6c6e422c9d9423a74afc2316807a98bfe6795d2aa40d5bf9a2eef5940378a53a7ae5839308e39cfd5cf630961bcde63af58ef5cb9aa9e5153bbc56492087e89532b45092d25060de71236988ecb149ed08e65375a44bf7753637258751af4a016cae389544dc3d388aded8e8e41e9aff7c40cfbca8a0b39e9dd5d1f9fc39357d6bd14d9a6ce4bbd2be024e2356d34b068e634f0fb9c819eeb5228b5c2f4e4f0f70cf0354e4a589061ae56c632eb4e2a7dbbbb797bb843b37aad8babaca0262b9dc150066b15632a785ab2f2bda54157c0ddce7637c3ec4418a296ea3dcb0d8666e908252482b568c240c73c96dfcf5647dcc534618366fa8895462b5f949eed4ba7d6a8b2d51b39b0545685909c3cc0c73d2b9027834671c61158b95b8060f4a6866233a160a0795bec2cab004ae4a9a670e4b05feb5d9c44a3a1e28b5098b9252fd1dc3d13bfaf125a7d1bcdc659f51b59ff1d51e227ce3459ff19cdc99182d899dfdbe28751f7ffce5cfab8fefeea777bfbcb93cd2acc90cb0d64ad9040d73b558a99b44c541dced9bb9ce869993f9c9436d123bffe15f3f0923fa605e19cf08d5c61f93106c43a3466ae305ca0c3603c6beb3f97658c5631b55232304c2e516e333152c84eb30296f26c169ac325720706266dc811731d3c48264b6cf1b83bbc31de16cd763b6d929274745acc9468082354b9b8e62fc9380f544175b5cd06c76ec87acae919dd28815c99cc0b4e08289bd1d3fde213760442942656b33ff8ca0100690728d7590b0b579cfd1292cb255a2149ba1661cdd47ec1351f7dfec7dcbd66f0fb8dd4b0555fd143b769810a9c2d03226112b074897636c4b41b0a98dd31e19145a35ad8b4ccca162cfc2810fa96264df1d3215ece69a09a1eceb0476535be7ae21e742b96dabaf3b171a3cd90dd47143c0c6175616d89762bb03e00fa032673c07fc4f753bc72ba156c0cf073d4c6f93151a0bb516846a016916e3cdb0e87d7e227faa7dcb6a7b7cc5b2025fdd6efff26a1e72fe760f39752a2570632abcce554cf5b82412500834c011745e0167170c821d711d2ae00268e6b4a5c95905e1eb35a71914d86ddcbb8db54094b2407a15e226a6dd58473457d2694f1a90a61376d89a9a5355c6d6fcbb3e02a71ca5003e570b695ff58a55fa51307e98abe6c0c42c823d45c67e05ec438abe71aa26b4d99c7a86bb196ba7dac1a439143be29352afc1ec45183424646aec3b62f36177886fecb67245a097491df829b0af90724405071cd3619eab8d0913db8817b903e7bc00a01bfba76d6626be8b2c8c002ec9245b907b612fac821ea1075178a803aac899b4a06846dc5e01f79bdb86a65689cc8d78202adc9b470053ce7df6f705d180192a65960878b635c76eca117aa27cde6d3a88f3196d98cf9ed784b73651047af4b118f79d14bb02ac79e8ac16dab0fdc858d3ac247be135d98577d440670dc16db3dc4268cb049a6aa9c4417250ccca104ddc00d5ad7950bd391f5634b7dd85365f6ef0fff5977fbb7d78ffe7d771feab7ebbf35f4cfba480fc4a38dab83956dac06c09e6532da6eac0b857a9907f96abcc8346ddc652b00a9b69f495946a9a5b4da845e120a6204ef928ba3b156de6082d4ece9d9e1cf73737629e60b442b2e9ac4ac8a00cc5f5d69dbc2e9d662adb420c96b73c56717828ffa06a7a0d78b780e2ec6863d3d691b7a869986b9a10e55acc3a0c4404ce864bdc91bf477523de243b3e35aaeb6f7d54eae4d5851001175de7ebbdba87e6856d3197bcf7ad1311669b78ae33c8bcb9f68d09dee35d2c624e905db53bbae25668ff43ec3d149899de3708da29dbdd958fd756ff96a9c95a1c761a340726f76dbd3ff778ddc07d3f3ff4a43ebb33400f6975cbc317e7a5ae19641359f5aa819bdecad3dc49fa5a12b0d5ad5d0ecff2738fd7f68a32ecc6e3d2f210c28f9b6895381f077e509e334a379f3da777ebf77f79a53977fff6c07d8448821648f33ae73d803567eca5b74e9aa766839a9a1e1c9c5573bb9c93b36ea1198208b03c7908758357a50835c23d76a5b9a41d4e99151e50f89e644f77c8e7003ce719638692d3de28a2fc4c0d1c9a1d875c1f18aabe2e40311f8a0aecabeb214991a90d7f3e2abd864bc0a55063af6df0da3ad5a62aae0a78b5356bde45997728613e3c23f833ecf582bfeae1c6adc7ba7893ec9fe197a115c14336d7e8a4b59f4470340fdff0d7dd7883ece338ac9de6500e6fb29b8c58f0ed710b4ffbba865d88560f47dd71dc79fbbe0b33d189e6b8efe87259354cbecf6a869d5c568c3737fa97e164ca8be37cf9f6713e0773e6ce8cf470429bbb9db80c34562521724b7187d9ab666e257cca0297b2454e79e2b1f7250fae242cff3a77995f213b1161a30ed7a645c984440450428d58ec3917fd8d339dbbd4adef7efd1fb7d3cf7fbbfdf84a8ec6b7af32566bcc7ea33a25507f17d288894264d9689f66d26d90dd069c78e056417e58a844eebcca459c972807cc56ed163ba8fa90bb4e294823d03a60b3bad97059902fb6e65c830ca176a3b54f295430a2a93f3db05c352cfa830adc26b30aa2e3f3fb3447edbcd83987d3cb9df4ef1f3ebec53eb2c6547d50ecda3e6da34d74e6d4a78d742383dd878072745e8d02b2e7617aa5419b956207da6faafaeaa6222c2c2a28a9850ad2c9d6d91c301e94bf464c2e75d2dcce67fa683ebbd8459f361feea70fbfbe8ee3f09260166dce293581db9c4aace2ccf31a6b0e55a84697fa993fdb0c4d30a7b652bfc9d6aea134ca11b68913c832f05d11d06f7e1cf6d6c1953ee218e0c12a2183d9137c3b759859931440ce53a93a4d908226d0c9ef0765b36e652db95177baf528ce4b6e9d8a584a0199fe5a12ccb25978104e626109d7d9697b35d9ba91267eb0f939de414c7ccc568f4a2d0e9b0d0cf0836552425808ce373f1af5a60e5294132bf1e4d5c1ba7af4d4d13e576a1bb36742b615a786c76ab0f2a3842ec4664e3052e555f75447cc72ac020936e986874c29b446d9fc10b6695460f18b2bf5950f3936fc08129fea8e2908eb25a00fe25623f4c60eb8f61bc9ec9cdf586163ac7a9bf264f72002621b1a288ecc7b2bf63162d5c73b1aa1a7d760113c28c9b27eedce2ee9d7fbe9e7bfffcf0f9fdedc5e9859a02c69c3b9de200ac519518f99f5ae44573e11127b9690f557a90fce0b07d6be1396be8d5475c5db733277df0f054d1fcb08a56ce3e86174f75940d697088ca62db44dac9eed25fdc144d74cb3492f6003348209e9c2c2e9aea9173b697772a98f3efcba7aff717aa59cc1974442d99c60c53c420f3df8b7ef0b7010edc7ffe2fc5b14ed3fe591fdcad011c792a5bbbf7f22eece18f85c5b6eec774c984ee83b375cd39eb8f9a0410f97501cf72dbbd825bb93cb5df2d614e61fbd79fce9c3f21ede87c52dbc0fbffeedf6b522545fd28819e67ff28dae1147f6bc9538a799fcc4155912c3840b17464e1a5ac5508b81bcd528a950b9a9ba89b2eca8b12c39552c69c9f94656ea731f50fa43562a13a82a8b07d9634a5dc330874f6d3226cdfaaf5199945ac4eeb080fad2e641216da5bbcb62f3de1676ffec1a0c7d5bec1463a33852a5ba5210a08b986db5b6926a03ffdc6a8e4f1572bde16e9e065ef1f0d6119e6b3a34c8e1ed6ff2ee250fef6d2fa9870639bcfd250984509d11439c5b94c58fef5e6b2bea0509d9e6d681f453fa8d885e557d403866c0549bcdad7c1ac279b41bbf0be01405812ba04d33abf97dcad4b7e03c880cf98c20deaf58ac328d474cab5c313730d626f04f8b7dd93d4e46aee69e7570985b19580f032b25071de62b56a7bced5735f5498a1b188cdedd17036ab4d38f88cafb1a26fefd3b49bb240ae8d36549c0a93382f03a52c0dfbc16539304e64e755d32e61b655540445e305f03c121a790ae38d515927bbaa2a35a68305365cdea254c087bc79810f34c733e42b116e66caeb5520122894ddb3953036f3ad4afd83c8133c2d28191111c0a89019e10f04bcbbe72cddffd2698e033b72984de7c6d4c04a8451a36f7eab1db64c1263a1ddb5723e2251faf8b0c13c06e528b89d630e9373339bc616e9c6ab73ed8940b782d3508816ad4b7666577e0668c389a1d03197d2c36eb9b6312c0c58e652baa37dad3b2eecea1340bbadb33c9e4768faa235181461e9334aa367bf2c42b0eec8cf162071795e29c462ca9c3c777b7776fcde534c3207da36772f96e90b4b35b4baf71f7ff15d715ae825b9407216b5abbe33a3ccf157cbc5304a65fcd13365f7cdfadbc07a06b2d27199eabd943c48acbf3aacda0d0ad02a4f1959f755634acaf1765c34e2c0bc7bb4f37efdfbd0e0ffd4bc2af2a20136490cd1e907163a3d6005e58f2f50498b75a1e4468e8542b15f1ec4d66316f2815df631d540b80ca6864b882124a852b58ea4fe63eab2706f5a0d8c381f385708ca8c9ec114b44210fd11f652a8b6474e0a38819a98cd01bb34e54cbcaac71f3cd54003435542679f9c1c3f4cc33ad123c0b2f8c7a2fa57aa49dfd106d288db9816fd64a8b2d51b5c15d8963af24fa88899b8ddb19906ae6a660b3b704708eff2483fd77847fdd23d3c34edbc1ee38f871d5597e873c8c7a2e5cb0ead968c1b3491f0ffe264b39861ba4e862113f2111154b5c5203762424f4fb28881a131a205a97d8af2ee43f9eaff9258571f93fa3347e725171defffceed3e6e387dffefaf6f2f386934bc9c834b6b1633b522af5fca39ad006ff7480106cd5435136b5521b3f9a3b37827ffa2539736004ab9ec2caf21cad58b626b68ade6d27973487e522addb482547fe91c53c965d94bbf4661d897cab7ecb9211b8e45f33208a983f50a8ea845464c44c1180a87ab62a34d3620216cf976224ea29beeee738703a302046fd516db2b46f931a72a9a4de9a63fe9cdb74084ea48440e5c546e5cee024d3d3a7ce71c9d6a830061a9eb5aa8f10deaa80ab7cdaa8a29e9c9a36cb8d6a7f446f548f922abbaf198313b00a4af9d2407310ff65d5399c5fd49e0f3691fbcb2bf1adbfc431e98850136459ac59051be1a56e15d921f85c4bce949bf363e3177cd6c73be60c7b2554650deb8c02e6ab7677971abc84ede1e6f2781747a202616f151781d55c7151f527f8bdad53cd2765fa509056f398b28bf0c5e12ec2b7ca71842fc698c3cf514afd298f36a7e558618f77dc2b626d46212702cf3301fb143188da47ecc4c38ffc82b4c5a2ff983f8f2a0980499d3fb99a4dc7e7947d34650956981fed0a3b7eeafea1617f315e145950282a3cfbfccc4d5ffc4e47f53d7ed4e7ee020ae951f9471f5e133fb93d2e1e0d347fa2d7837f8a8328d9e7f7792b4893da4839e64e9b4bff4e2ff54c0efc75e23339f8a7edaa6329be7cd351e917c5fd487e9fcac16c28beb8a7d6754e202f5834385fbbf540ee0bccd9519f7d9f373aaa6d782604f3e73f732fbdaa213bd694c33050be7b2fc112400a8e95f6fbbccf5301a8c7a3c1b100fc53f6d02bdbafa702508ec782efd74b6b1f0560020efdd56f3b252ec13f77788276833c5ebb17b2778de65e5dbbcff2cc355a1f2ebfe053ee9cc2658f727776c19ffced4ff7d3c7f7bfbeb924329b892926badf87b5019b838e533aeaebb136547028d5d35987b9b61a2a3299dba01198016437227339a965cfa1ea15d71f4f91117b7ad0056ef44dcea47ddb9a275549dc1f2d4fe916cb38ad6b405d23eabaab61d8d5f994d5b90e74d0d3fbbd7d96d1f1bdbe5e4d04fbec8fae725e62617b46e77269096f27ca4b3ab03bb7a8017fbbfdfb9bdb86d50ed012ec7715a6cece9e80e974e49c00983beab68a673d51135ee55e69a4124a12526e21f74ca58ac7f47838ec55132777405041a23e240e2ae628d128bef1d5c67af704d5beaa4c1d4750a34ca36065aec8cda8abe4f9b21c2a16616d2abde12113d60dedcff9b41d8efa782d096918372c698e4271c4e4a6879477d4d14f1d25ee9739739f5976a9fb653e730870e1a4d3eece5d8abd965d808b3d3c5d7eb4bcd6b3a30943fd4e7066c0bbf9464cafa7859d57a7bfddfe7d5997fe76fbf725457aff69babd7ff77f3e6cb7ef7ff9ebebf013f46fce2e32dbcc355de9f945508708f293a74d0878eb33a08abe47bbb005e1d495df765f9de63a3ee9bc1b49fdcc9af0e35dc4e2963d6e86b02f3df4d843874221fa3fc5eee8f100b6c69a3d7ef7dfecea8d68f26c85147af03282bdc5e35dc282f4eb147ecdaad6d0a33ef4b401bdd7d9b5ef71568df6f79e97ea13215d14ef932bcecbf95bf398606c7bda48a9e742973ca0cc839de6962b73c3694a8f775563ee0aa9cd72c5c32cfce35d1678203e16ed0bddc336828c0d5b92fd104775146305b844ed07cdc3b38f2a3687b3ed43b3f69890e0b4b940ab3677c4854e5ceabdb707a756609900b837660c8a4cec1014f7761870e8ffc7f987381f1e019209924a7aa2b28d03e14ecde3056c984ba413a23901764cba170fe4458dad5fe2576b230591c7142b229410264ad58f7cae85b2ed29eb21d4424bd88f423e89955b918b829d8d11f000c45ee021a85c500fae11ea61f710644800567fbbbb24c7fd7d731a0d037e98741fcb3797ef45e3ea7ddda68a98a95dc93842f551b28385ec5f7b42c973a64e41f8c451f31c9a31ecdb76e21c2baa049a2b4220349b212ed8634d758a6aceb3c295b693f36187edb2c3c3879f4f38b9ff35e0d7f91008f9fb02c3e13c00e0cfa72dfeb60860f6db1276d96fbfbefbf87667845cd3c6e9abbecb84b0eaeff3c17fe1f9e05e9417a57f7f76490b3efefaf1fd2b0df126c7df3a526847b839838d8479ec37a93e136ede4bf033fdf11a0968f022f7b1588e9818b3dccf188a4780897ee208357107bf885091d4a7989176123d84a2454450dccf871e4f31c74c348f9788f3619ca327bad5c4f1251dc6f1e831f727d50b17aa775e0cbc2f1765c04f2d08004265fff4e1c32b91aebcc00a66a55a7fe0daa8f126adb32a951f5a03cb0153cf3ff867b2ffa29648a96dd2d6be28b5b588fec045a8f71b155dcfa5090b8d1fb3fc90c56ffce1e4317fbcd69e7ec892ae72cb94c6dab7377f28c99cf0290aa5fa83506a363eff006fdfcf938e2bede9f6b8640fedcb454e9fe70ff8e3350ffbf5e41cd7f443ba7af2a35d7ea35c6f47fd61d4dd95437e487fbc1ef50705d5cb0fa2f6eb0ffc0326e13fee7eb1dffca23fde991c75bdaa7ac3433655ff7897224bb71faadadfe7e46a2f224b92b53fb9245befefee5e09bcfd05d1d6dc87a3d700751ff0d08e170d7c2700fc6475743795fb9c1c93c2c655fb350e4040574a50cb06ea5a0061961e4a26ad7ebce16a6e53a7013f0fb9e818a4704df0ebbff1e13b72ba060c9e8e298607b165a0e130b6e205fc7309297d703aeb94c98c1226a32498c222f7ba4a043d88397dd9a7267992025e532a19a46858e5192d14445975a08715300a02156080d54dd54fc6d2d69a1bd51e46276d53cc891a5cc80e3224c1be46076c75a7dcb756d124a134e7754d947b6840061ba0b006799c546ae04018bae696812939c60414cc0c209f445d0222f518f004000f7fbcaee24cc6917d56984027573c745862d9412f0dc4c77700390c0fa52346ce1fd60b79036c33f8f2cc335c0e500d865f0410bf955636ef5b31eb57751698224119e4d9f78b4f9ebecba3a58ec3a3a5a4dda3c51be0351f6d1ecdeec9a5ef1e9cc11b7e3ede15b883cb041eb97b704a13f0a3816d63547b6457a00b0013aa56a4d682e1a4abcd1c7170bf74d7f43a779d671b013ee2621c706189a34e33a0f61398ecfb63746dff3f1c616c1fa36b5f226373f3bb68b471e68cc57effcb5ffff7870faf1375f502b36d3a3cb39bff97e9b033a1ec74589111867fafafc3f3a3671db6c78a37c0abebf0fc64d761f5407ae50b31ebff5d7558539a839737734c340f1b871146fe7cdc0ec3f913b45a3ddca947c25d75a0ab76c3324f562ac8a8727d365da93e21f896a5f62961d94da3664a75bf98763fafc2e1a730eac3a857223a8764ff83eb22d2a94c9c48396470a725520d031189f0e2d070e64765f300dac18fca073f2a5fb490b3b93b6726e7d30bb6f2efbfdcfef5c35f7f7b73f4ae2d051e365f5957aa2d0888157f944a557398bfd23eb8bad0c8370529a9fd4610c1bd8d19842ba94db150e6e8784b4a75f8a1a4901eef4acd94337251fbbaec9f7ab8470ef708eeb182d1bfedf0445400f9a3250ae506c0b666d3aae6d2f7789df3a03142a3c44804a8e06bdb4538e1d0aee8088c312d4f42ea88e925cc5fbbb59514382b299e3fea431c42a54d0956a27bac78acc07f2d19a8ee954a5981ae4d43d66afe3170701a207801dee22b6ba3dea0e829c56106c8f1b23afc6380d389d218a821e02bf5f1ae3861319b2b3d817a2b139748622f2b1a155f9b98bb79bc591430206d00f616cc7dc58ccc7c84f79782481f6b8ef9be2966f39a532c347a0467b39932012e1cd0f34a8d87c3091c60d12a62ad0ba27cbf7e83e2b6fe044d138075edc9c1eae04756075c10bc0a764b993053490ea16a1508fe62ebdc300af110ab0b3bfde9f965ae9dc22da9eaeedca29e4eaf063ffb82e4a596ac5b38dbc0b43211d7d2c1db93520f323af5de436f34107d5da86b0fe02cb4a964a7543b127db260dac92060166a834123de4b64ca8077cb352319090310b2916a611c5f89122700bce9e8f37aedc022686a48bc49ee3db4baca9946c65ec310851275de433b4cd5e66758aab339da60407ddabc0d341425006eb6acd5e67e39a8cd2457da3ab18e20857ae15012d0a54a19382c8d86f20ceb7212c2e0710641f42a6bb18b26e0df74c1929ac9b797e8e1711cf134de2a532b003fd2f1788da0d7bab1f748654cbb02602ef655f202c25c00ee2d40b92a5366121f84a4c106f68cb8bbccc381b39b47bbf560fdc53d0297dbfa8b4bb4fe520de8af6e16af52d711d061111d16d0617100bc0f1d86e38db92e49a7b9bf82f757407f05efaf30f797b56eaa2d28374aadbac132972f39c05f493ac55db7c5b9dba2775b9cbb2deebaaddbcc5f1b53ca2608d636da2b7aaf3bd694b21d15b4e64d3e8a3b39092bb9c4f2e06abaacdbd37216f7df7f99de9a5aab26000adab0b2d5d06d30fb51d4d371fc6b1e794da573e82b13c1669a641ac6ae6000c41b41d2a02e3f3a46c27c1beca7886e74502ab7c7e74c505a1c584e6a58bd99bfe674246e366118ba759acd0adecbe31222aa0d200a13dad3c201d956527af2ab635c3c29c5f11f1ae5767a02631c1ef2783d378066b9b56a56af6d9d6b1bd9a917fad6ea6ac3466f4f9e4cc554e7017bb8cf9f7ff5ac5281e5e679fd813dd12897e7ef45751bd54c66b767792fb6307f9df4a229130b70e0531061307356eb48411e5d147b0979da180017e5be89cffa1256dafc58a93f0288d6bbb4d7b92f0f8d77499fce28d392267d7cffcb5fdf5ca087b55a09dc94fab60005a1509f32d964c0ff7550b13353f6e8691c2276da4edb7c18df3895809bdc227007f6d4dc28f38505afb105550bc9d62c2836ec9d1a0ed89ad901d814400139d442ba6dc4a166aa6bb17af47628fac9d30f0f3fae1ad012fca56aa56c863ca33c9b83d9647704b147361a4015b06746c95beeec9bf2d88507a4263eabd208b53cdee5d449e2c894d76ade5890f9b5e3fcdaf1b83d175ae649f5f7a8338716372354fd83cdc73f5fbc594498c5f3add302b7b58a520f22f3dfe75aca4a8a59a75d39bb8ef4c4816d6c990a3ebc9aa8f00135e74ca10ce8bdb97f629ee5625fec85f10e2ab7a8a238f35c4bff70fba7edbb3fbcfbe597f7f76f4d5375d49937a1ac8a34a01375dad112d839d56102ca20e7e2281c44867d810e1ca7b6d1fc1260c43323e285a94c5a896305f24566eba0460a5ed10a30c6c7bb28dc688436a8ad0ba06b4b319191b613389bd6054e25b846aa126fb3520959a9ae2bb5a002e465539f629e569064ba613ddfb72593024b65ea0108254c4038c64e6fe4998f5e936c4d97827d4c004fe21d38132636a1250f52cab101463732c76cefc16c4689a3fd9a01fd51a2b4500933b9f678edab70698a25efc2a6f641534f42a6f601539fe5e23912a705293c3a7b4612df9c0c563da0a2e9d8c3a2819ff80417ed59d0ab9e0f43dd07183e8b42bd9e1764afaafa1a604d0f03c1a35cd3d31fed5afb597a5fb8f8c9af973aec5c579de9a457e3267c217c5ddaa3d7258709f068ca0747bff81af0ba7df8ec13f03aef9e9e5e1c6e710738d0b408615cd322e85b4d4ba06f59161197f3799cb37d179eebf565ca3b3ff57bb7bf46948db7edd9fe38d719af3362bf240aa2024a78e5d0613ee52cd86e02c787546a53f48957c894c3a01cba7f6f72ca94a702342e46a86a07ee4e5ee5d476a50451b05a58d1feacc73b2e4c150048dd1ce462831990bd4a9ccb5ecdf8c9e685a16af0202a5ef39ed586e7d26d52503c9054a94de6ce538fd9eb10e7ba3c5e97911d4dbe4ee66e16ffb0e15fb0c61b255587c353a06d295e714400a6515e97d18214856b5782fd7334307164456b9ce258d02dd8b43f72498e6c3cbce8c76b2ce5983f101d8acd9c0bfbc6f432fb3c4483951015c80e5642006e114a3077a8f807ea1dacdef3295ca551ec13af3d1c222caf774fbd2cc36747fd4f8b23feb4f970f7eed3bb8f6f90ec567a0f59562c1d99b0e22bfd769ce03601b9da692b0a7607049ce660d452101e55f64d25b67914a0a905e41876b851cd1333b1bac9ea6097eb7e0570ac57a5fad2a0a0e882e53640d135f7db5234794d357a15a3f4befbf778676a3cb1fa1ab980998f1336171272f3b3f375d81493a446a1aa414972cca4c586a4b68d830455aed8b2b17bcd55f1881ddfbdc146defef0c830ce96f12731f714dea435e7a8c866c8fd84e2fcf886fb230aeae7e4dcc7f04e1844b54784fe7f97c24441b7d98494b7a6cb3907eebaca9af1f20a6a4dc49f54f0ede2b03bd82b359b6566d081812e10d2732559a8776b3e5352f51351926377f56ecf4e73b235c69d799bc8ec50cd54c6d6eaa191bb52e249c1ef22887002d7195ba1e853273a6cbe841594d80c30654c4f1af49a9b5ff878c73aef58cb96c1d8a7954a9932c81c7da308e0578279782af3e11e66ebb819ef9fb42336d3728fbea5477dc40af29a8a95b542224ed6fedd84e0ac393ab22d8b46e9e8fc92697a9d14bc174c45529022c46c6eca2acdb30dff44ce50da48523b7feb8ecebc406bb205d2bd54c6d666bfbd4b98bf279b4f6b09a75f3a88b3f5746d76d15a46a62e39e868be337272799c2f9ffff27b425afb1341059acaf8f1b84efb3779bc6616b354af998af987dba544b53fdc2e24a7fde1f6af6fcea79a5b3d88605f6a3d37e8dca347edba6fd5bd43ac63e711cf32f2f05c42d25cd02c28cb12a227a251fdaf1a767dbd9d8b8df3f72c56cb72926611f1be87f93e74fe7197de1f09827f1ecfb08f0521687fbc2b3c4b7a86b4aed546d5af95da6d344b4ab9ae8b6070cb92a9086273c7184e6d3ac045544176361fd64c55efcd43acb0a655b1edb53bb3ce99298f16d2463b35e1efaca217447fd921fbeba237f64a24292f107eac700c39ca920887d488fb4352c4b3d488a3640a7067d83c5144af724f5427c5ec0e4c24c8d56b94fd88eb8cfd075ea844398ae8eedf4fc94957776923761e0174f3bf8da6b400387d88f63a70101c62bdccf8cd0b70fbf5b5fbdd4a9c7f86dd7adc7e252e5c5acf5964f1b09f97bafcfee737b7eccbd943e90b3dd9bd6a21ad0b4897470711aed81447849eeecad98588de1af274c711a8f436e31b61dee203b02b3e77e7b15f08cf081cd255d65c80f15a875d9f46f04fbfde832541b25806f17856952d6c400f359b93b8aff3992a4b9167155e1706f9584175e1e3b576545daf2ddcab3a421312f362e5b420d413f347336bd5b3896d5c88daad39e6150fb44cff2937ab8cba6669d5931123215f56cd2fab57929e26a79d4dfe93fe3465ee02fea57985e9c5a52fe7bcdd255f377d9daa9fd5ccfb9f97adf1fdcf8be6f83fdfbf35d5d42a5881a96aca17bb9279f183aad967897626d66486ae52c7d1552ee25c61f0f58fddfce849f2c7b38070e4f93f64014eaf1b7f71bf41402785e283156fd508a806fc1de4ec21883b48b3e90cc266f541fb9430e70595d628c1b96a33e825596e14172c420f67398b2fecc4091ea9fcb5f76ab279210f9b5dd91c6bcc3c5065e681420c429f12e2e7b0d9a4d8cf19359604a6b0792e5de47b4d7f93c34acb966d98aae6bd4c36f18b9db886016be804d7ceab6fc71b6125f56419844ff41c9c6358a92362a5d7751e8510619536515a37133467adbcf20cf03fdf2faadb7fbe5fd0b677ef3e6dfed7afef5e07dee0051e50510de96ad4952374a73043068514c68cecee28dcd26d52bf7385368505f0dcfa0c9efb0641d8c00277d8efc3a69e2fe0b65decf55180b559fa132cfba3c0f5d9c139da04db3bedf7a74efb03763eec8d169fb089e71f010e2f20a9836bbdf9b66e2cf51e98b200f2b65f1e4afdaf7984f4b38fa8fa5d1acaa6667a6585cd1df90448dd2d8f83babb4cecb66c410ae12712fcc6f96c1cbb3a40662015f5c84b8ea697209a38da9cdccfb1ee9f4cd08ed2188e32372248760f51fa4701fcbbee8f666d1d157fd7acded6f71188c0def6b1d48728bafc849e969f0022b6b9f75ff109d2437fcd563a67d276566ac9aeedce9d316eff5c866d5e61ff3ad9fe9c65cbf5cb3bad9e118b739d66ea83d4e7afb59d4ea4fa0526a1cea20d00b62f14ee52bf4eb88b470fc8d71bcfdebfd078f6feaff31a0e7fff0f92a94be3ccd708d5255b73cece2cd998bb5fdf7dbcfdf4dbc77757efdf20350503f1efa5185169a62b7b61f047e46a5db6f298794486150228ae19c59fb2f8af5606cb03d74a650552bd9c32e214b3d3bbc09eb541e6d9f96eeeeedfbd0db3bb1f2383b43403262a3ba16c96d807951b6699d1e3b44fe00b0ec80ece85c69c259c22f8d7586c8ad7c18e136ba67e033cc705e4b1fb1304b3071e4262731d9f16a049ba378d1583001042d4daf054e5d0d3e39d49b214e2f9294f97cfee3d5f74e6ef7c104e34b0c65b1150936da24a68707542dfe77120f727c11f1338ea30c7d1983b156b22bbf7bc829c48fca2aa9c5c715169d61fde1c15d2ef3af34fab334e2dfa199de1fe0f5499f58725eaa3d30b9614e6b5320a5e828ddab08f75c5b2c44dfa00e0c767d4a4ace941a42f9d2a7581b5f44634d94d0ba766ffe82959eaec3b5cb1acec5267ae6ba4909d33b5ca75e9017b12ffd3f2cf76f272083a7e5fead28f77ef7fb97d73d010521aa097a5098dc6eb9aa9e61eb436ca8c55cfdc105dd6005f58ea98ff98b7f3d2ba5192115495aa36dc50dae1b315dc261229391d41e23557a6c4a0c40895c6089c98a414dc9d0bee43763237dc8d75ccf9e6ad08d58acd855adbe495f15a7afde63ff6f5dbbf611e94f27478210947b775984ebbe5f1da9a53cb6e0de10c0674e64b18d0f9020474be04017d56da5c7c1605ce4f2dc9dc7f7eba7af7feaf9b37177596b12cfd1cb31024734b98854f372be665a64da90f39e9d5b3ed8fb33b1c5cbf989c6c1335d94086872c95b554ab9b2510c3c73bf04de5ea30b8aa1bed930dfcec710b3923e169669240f6056f7d883d652f1340826c7d205ce5e6004f8260331cda689de02c6c1cabda9e08e2e1cc4e7f669e43dbb37c047f16ca3b659f9b1f854aac4a4f0813e835940662b35c7b28bed8705e6677e2b728b5bb93cb72fb7fdffff99516735eca7bbe2cb6cf38efce8b2d20bfd303839efc2969c579c1952fde9ab36221b878cc97ead319c94522f3085213d5b1ca4583f40c04938c70c7dda16f405df17e4b0732e772ed72e7723d33cdc4e722370b9d0be36a68d0aecea12741dbd81f56b5276c44e61d2f176e572028930bf5cc0cf34c8b767a74496c217d67a416e7168476b3befdf806f340470d59c0b67034e69c8c490f5cd379a00019f5649c3b19086fe0929dc956bfc30ce14a74359709df4c05c729947af2e0e74c09a7553ea9d8f1739f8ecc8fd729c87849e132ce977e257a7ed87fbcb3e6e6fea2f29fb4f7136e890b2f7556a05d3297c4d9cf2c0af3fbfb3787fbc16aee610ec2f5a15f12593d2fb10fb19f0758d8981f9a733eab2a265bb99d3c7d81e1e3591927353ca9c1d789d7b54d7b3336852fa9d54b6a7751b3ee3a86cf2bedfd5b5f2fe1052e48f885ca3fde59297af9a28b95bbf4769fafdbe31d60842e3fe235dfffbc82bfbf5f74b2706249bddfaa6a976fd7ec4b63d1e715fb8ebb5d61c7e915bbf0b422754625497c7853fc6515328749d3eb887aee15b3e70ba21eb3849e5ea630dfa925a23f4843a917ede3eb99e57fb0ddbf9bfb2b96fa02dbf3d94ebf6c7bd3cc8cf48f79fcb5eb677eed6ef8ec1870d6062fdadf25dbfbeef6d3bb8fd7af1693fc92c5c054c1c7ad85b8201ea723a14e4b2c0301854c120b82669b3a9007760e9a00ee81a3646ace4b92130dd936aa193b25fdf17a14ea1c649475554a3d3017d23145921199aa20810adf6adf259446ad0297ac82609d05683f1cb8dbd7ee0f073eca6457b4a0d40bd2c2320d10d9680b99a98136bc0390bb8c28c8eee82322c222774a252a153c937b2c365d1d34b0e83fb084099604920c28b316a5ad7262c066521f411ad0fe529092c9b3289b89bb1d24b667b0039467025277aa6150caa1252b38d310a07df7c0940a603f4adfa2da81dba0c213dbc3c1db23817345da9e8ab5a324252dbbbf669efc4aad44e0a5266b2aeaf626456c3e9e7af4544af5870f426648e9511b00551153c2a952aab158cf4466c765526ae3f16e34c450e6465aa7684dabd63788a26cd45b54720c3c8d9da4844e0359721518a3ad202c4b805eee389725883d5e3a213d210fab57216ed1de1614b636fb6f34fa1c97ce21030697a961fdb6875cadd7b5026c52c01f0fd4ba4c5deca4745f88b693aa512b72f4aa497c60c1b66aef80791c947be4c1a4d9da4539ca00b063614493617101b0ae26803d4825a9b120d6b6d8efdb78d273910be5117ab3ae1dc5c174ab23ae762c5aa446b90407f8f33059f4698b25531b417800b55e137575a98873d94aa359bb31c7862a563bcc425c621d5480f1d232811212384d5de3a1d5e251abd95db9a2d5aab56ef6560b87562b01ad663d1ef63d1ef63d1ef63d1e0f3d1e8f7a3c1ef5783cf478dc757998bb3c47289d5dd568581b3bf6f2e39da94b0b3c3ab53ac552a8f638a88d3820dc6590b468c64101e26fed48086829e63c90b0bd01b73006e908d6ba0055951e900ed14d584c74667967002d0167bcb04961add438f442c5d44480b45fa8c9e31de74439b28908c2558e1ba11f3542fed24690b893fb38cb7ddccbfda51e9ce5fe8b7a30ef7bb01f7af0fc087718b816c7bac3e9c551efe39d27a2fe3f77bf7e7a1d2a55ec997fe3fc63ec929c11845a3d92f8c04c731f77d1c57314e91c5caa35ec7ff58bef77d1ab7388321cf96ebd9d271e3458903c5db1c95d04209419d1fdb5e4906c44a8a346a055e600c45b8fbfb271728414a9a611e11bd3f0a3bc2a955a1fa13053b1df72690082a8b952c20097cdad21ae35e4c2c4d937eda5840c71c12a828c4159db21bed0040bccacfb3cadfb517764ad33cc74ca76cfe3b5d8d8d33d9880f2cc3ed122de306644da97245eb654d2dab0c59ef33eb3f5a79e82d9ac6cc39c435833e9e8405e6f1e35a1d281378c8a3b4afb1823d46a4682805f9201209a0bdab82762aea1d9e08bbf54d6e040ac0a0201e40dcd0c02bd7b8cc105053891e1652538b9e4a222fcfb6fdbd7d90e7e811e08068a7df7c77df7fbff3f65d9757f96a3ee5f9d08533d92b313f99b4c3207c0bc92cdf5a9f566a24ddcccc333d764e0ef5ad5a4ddeea5ca26e226ebf6edfae170b9ddb544f75a02105b2db094a9f7580169bbd73f10559a28e7dab7914aaba63d329983da6bb4a222f619c0d352147fa9e408b9219e77bd81852fd57d2333ac90c108193c96efb097efd3d8979cc38e4ad6e59b05293b4a99e79c1a6224e506579a390c86e5444c110a5315d399afb05a92a9ce392bad4655cac0fbb2c15479d67da4ab788da43d03af9736a3d74bb6f12b3b74bfc273a91ec3c3d0574f3c523e0fa672aa0c9715caaeb8a84f57b7dbbfbc357dfa9671e5333d0402e22fed224efa855df4fb30f5af374c99465c562abbe2a252fdbfbfdd7efcf44a44646f4caf7aff72bdd2f4bb5afdb755ab59272e6bd67cd145e5fac3e6e3bb77f385afb318f88a2ab69bffa4a7aa163eab6ad8c5fee221acf6df75edbfadae9da8c8658d3bb9f4a2debdb5dd4f45a6bf24d229e64605948f7114e748cf20fd1e8113c9366aa11614c901051f2f02754fa4f65110cf1e80a8581265fbd01780ba4b1a816b23dd1e0a5e0b6b909a5f585fb60f59036b8f896f7297350836a63848c320c5f78e243e1378acc2feb7e144ee23a46d1fb18fcd1834d6da9d53a44e1929104a504801dd43f1f402fbfb0b24f6b2902ec9e56f777fbaffb70f7f7b9da4fc1741b195fa207a61b3ada76f0cb5381bbcf278a729483a1fa373ff64e7fe698cc0d3b080c73b6962e3e0142511f76cc3d320ed60be92e173facc360eb451622149d50c66ad3582e776d800965a944279e4583a8d245869a8666fa988461d54528e2dd3a858816660946762e6db99bb837709c01c3395d263a7227c53068dc44ee3a51c0a890215bf37dcd33afe1a5642a19e191c57b9521d26e9a90d1bdbaa73f670eb2b2995b88fc08dcae84146a19606256ea0181da384b411eaaa93b53b207646a65c33299b02666a0de47a2db7d0293bc06d2a0d5b815a83344a594325d60e8cf6ece89f8cd0e2543ca9b4e6a09d7acd38d72534a56685342a0a064340eb0c62c55a106704e4a78e31a48e2d3113f3644d3160188602edb148b6b15f0afed23c8013365a242e808bcf45c0c6531a9818478f65502979feeb2a97444df22adbdf193897599d9aac77d403dc643951d1ee29334911e46aca945da1ce5b829d3a2f1a82ddc97376e03f7e7d6b56801360bf2e475e7cb395108f153e137551356893f3313ff74f8cc3d3b09ea7c6e1f1da7ab3332900ed55481949d8a3996723a99b3590d6c250eb7c441334c953ce0e6c17cac0813440039ec815251b441a8ddca3c9780db99128fcb383946ee32cd7837aaea606196a26b99916a48cb499bd16844eb53358b5468994eac0b678d278aa554a621662d67912c52e686960b9dbabe94a35912471ffb5b79041e83d0bb656ea19b0d1db6806a2c0f99da27692dea29990d81bf554a33f28b2a92378429b14a03797161ba53140662d6cbff50ee7f460a260e922b1c4d9be15d2d2e289b17b880243645e2e4960922eb19234730cf6c63300440d3b67acd8e2abda634f78b7532b8c04436b36a56e1eb88d05ddbc2dc9d8213c98f69574a1c225f8f810643075d01699eaa709fbfc4d42c70764e9b231f88f5fcf9a82fff8f58c21f8743bfdfcd63200c5645c7a105692dad6d20bb591c3a857592e44a2f982e5b22750808ce1a3bf0d077baf601fddbf6c53cc194b6ddd4d756557a31542124a10081fe0b11a898787c885c238d707a70f6c76118995de47b021be992298ccb5be053cfe24482c2b80af34c7b42ac880e7157c0e696b0e41bfeda023f4cf199cce740a45dde422f6d8b38de6f34e9b40f66c523a7a8e834925e29533c4bae5b3fcac7b213a277a766e41f6de4fff3f7b6fbb1cc9ad6409be0a1e807083bbe3f3a7266777b866acedb6d56d8eedfdc70e953a6b3aa9ba5b9438bb7cfa353f8ec84c5645521f147bd8d7ae4915190c44201080037007dccff9f7b723be7845c4184cf39af62ae991875cb3f45baec9212f47bdc04ef2784af90ab6e23af74b88ace0efdda63479f80a8c7752fd6e4150ec734f67b93c83a318f51214f0d3bd65cce9851ec3925e9a88d30b72ae2f08dc2dbf308cad52b1254c6bda9630dd7f7cd87dfab2bc3fc21b506fee9847e8c1d4ece1749c0f6023b32639fd8bf35a94dcbfd77124ee7cba67b31282dafcb264b3cae73f76f4546e37aa1dec917589331171f67ed2109c6a19c82156303995cb77822037a876dc70fce7ef8adc0ef670ac25ce5fe24b372a900c07d565a63927034e5a48875ac08010403685226ddf0760e0359fad8f67d85d281832bb2c5e4739d914b063ea05117b9b79b2fc71e1caee1159ea8153822f1c7e16868f238ec1cf1554ebc92ccc0c9847383fda71896777fb7df31cf79a44b40a4f4881139209e620e15f7fceee8287532ecbb3c2f8f92c52c0ed379cf00293533ca7a6a3b65f7dee806f08fe2567f7da5d324fcfbf43c5aa6c565738afae8bcf1dce2beb576af6e6d4242f0ae125f1db12bc9f7efefe70f7f0ee00c72a80c1432e9df8268f6ca60d0cdebec0450e2ca594a067739da7957a03e91e53ab71c0a58e8b829321576a3daa99e1129b5370d8953c28e7a8c9f4f8d229039fa950c15abb6618002d0c069867b7c98fa550ed3719389a4ada766ad7a35002b06306318c28250e95b8dfd83d66eae7b2f39bec7e017b4cb73c2a3cf394c6a178206a2e999a2e95460f8532d81c125cdd9ac962ae66d7f08107d56c669fb4a550e65841d20b64a906c675fb567ba038028a82607687f06a15e0504260dd6e1234d692270f492fe062af346a60ae944d06db0d288b9d8fba75f04764b68f750079b14fd2f5bc75e2cbaadd2a7a9bd23ad3b625f6dd8d94a9807d45288de557846b875181e155dba1c07813a4d93a36f478dbb4be360dbbc2f9c0adc2b3a704109235b3d79729efe505797ffa603900ffc6696aec19c10a34406423b63536c0ce1e9e419c2dd38127a8190a01be3bf87f030eede139fcd94b4270a1fdb79afecbc71fde26987efc7157b3dca18271803717e68edfa482f5123ca53fdddb608749b01dbae9d20b039c998669bc8de0709e830d2559a90649fda0769213e9d2c9973423385f33c14fd7ee06f682357a9bca5373d8719b4f2451054c934605be1e56893528c1c11c1c3439723f7453fb97061eb016ecd773804f32e2dfb30f0325543c1b1b78b0fc692b65b452c6e3d913aa4c7a5f0a3b24148317165520582549d53ec9fed943f0fcad0e4925f69d526860dc8f35db6bc005908a0d418df203ba48c0865302ac532320c0d8170856b162436e560979c72ad4822a933bb433d88f66192fcbed978f3f6c0aee978f3f6c48eee77ffbb7c3c77ffaf16d1cbb5e8360d273a8f99a87eccc20af1c2aba721ef8c34579a680c7cdff796078aa94142d38dc9ef79b220ff93e8f84c4ea2bd2d5574105bb29cdec3506a5511ec7dd6afb9d29f08a9ce961a6fb4e77cbd8e198d78fcfaecfc5e94d39f3b57f4ff736b1b1f43da0bd52596a21615047f5d24da317ad91bb12064129f55a7b5e7e4351364a72515e5601d8929935eda2dcbcd196da9f2336758a4c49abb8d42d5159c5a49e8bc89978dc3b519b35653f35a4c693532c52d66be722d34fada4cfdbc8f3f81d0db4b9db3193b69ae7d3e1e3cfff7cf7b7b7da8b7fdd4253dab5ec9b752a01fd136b93431eb909619130b3a92636369a5ad7a2b2d39299d2bb43185b28894943a1b432319af65258f6d213393e0436dfa49a02c193df4c184177425da322244c4caf0461db3cb5b7a4726bf29162c7bca61e6aa3e0ef4820d7f34532c0e78b5c80507d78a6b43c5744bed243ee4d58ffae7201411b88a181b21c47f5b6b6131ef2e090cbd61bfd4218d5076b3bb17e5874e2332323eb88d8663e03fb7718739558f304fb875fb71f3d4c046ede7982fdd71cf1e7e5ce76ec379bfded987aa9cbbdb72d05ad66cb6dd009dd72dd8076bce6ba6be45c2ffecbf59127907ff0878f405f8f5c2ab59d29f2d820e8b019aaeb60d8af04d58666aa9368bd2318b0262a072cf4da4828bb029ed501e6f24c059dd9d55e0cd19389572ba84ba95b3fae31c3a5c53289c844331c4faabd063bcda9cd331425f27473e9304b811b5a486f73df9ba4f6149a75762c0142b3ebb1ef735f32800ebb5d0c3d74af8b0c95b6da3da15f77ac185a47e911cfc67e8b883516385a4450b05b098647bbe93c5579a802b4cbb05ef013872ff5531366713e8ff5c2cbc27b516eb744f6f3e15f3fffbfef6dedb824c46b984855858393143f2eb1460f18cc402104d094a3139a6a749910fd9adbc52d81c79eae5b43eedd998cb8daf4a2c71700c7f06678ec9f156a893554bc369c0a03742dbd55497b96fe18f902dab8ca364cb76390fdf1e7ba502b781411cfbe4452e55451f2f4011a674da61fdd0e7fce341c5380d3257870954bf0e0365ed89cbd4df4f12b4f26df3bda64bcc966685ea0bc19d0821f5fb0dc5daa37fb0152b63bc2bb233033f586838e42ed06e358eb64426c03190ec5ec59b1438751ab346ea0db964e7c3bea0dd45f53650f36c14adf57213e98755461ca3a1016fc8d7a1c24a66a2902fb6da2ce07e6060c8246088fc7b8548376123f2b669fa683fd443bd84d25ae7796883b13929e3e981d6b7da42cd2b1835160ccb38df92328160d331c8e162ed4b1c6a0a62873a502233c0a38ae1b71b443c883e00aa6766d44d66a96334904aa4041382f7cd262b109a7d9206d87589b9be97aa39ac3e8340eb86e87a5627da30675037ec4e2f6b8c40c739ea9c531a8ce37567fb974c2126bb189095ebc6c67123829d54317e26087a5db34641f0e7a785f17b1528fa7fb68f78ed0e5106d62c5e1863b18bc85fa12a5042976ac0553e248541e702e057f8474605355413d58175ff01834a2fd03ad9653823f77fc39bafd74df01c55c658290ac645fb905fa4ee7dc028df3caaf407758efbad01db756fe3f7f7e87c894599d1f04f30433e0310a09a482d906df54e310bb3ec0d0e73b43ddc93b432186d7224c0cd5a8648d493a2296b1159003f038c6e64e9ff80dc24ba32c219b253340bf9d6d5834654bc45e9c2903e317fd4eeca65e410cc8761316c53be8ca7a8683664343979815280c951074df010ba41cb3774ab3763a876c028d8f0afe514efe9d815961e5ea099023a6a13127ca0a7fab1a94a9b4a002c242304a692519811d89c17a62f6c9c289bdb39d0b68d1392752393453f49406dcaf8136d27db1710460a0c8b07ac0a90d586ee71183c4be586ac91825eb4181f4c0d8da583295ea0801781d5cab18bbac6d9e3f8026ce2aacf8e580cb9e4d98d92829ca54d9ca545010fb027bed3c775803942adbe8dad5cb0c0817fbbce89fc7892ac76c65c7a0a0263f6b6d44af0d533fd986536cff0e8dad50eb5ea771d6a93080549cf49241c8d46906c4466f9c173ae8361aa75ddfeaa05feededdb69c4ac20656b5ea3e700349e6a09af7a6e8e7fa743f060947aea63f88cd6eddba8e4d31e0120fe98cebd8358e8448b433523fbf4125e41e541e729faa89295c72abb21b753e6a86cc744c494ff7dc845a0eca4c65af957a3944bc3efaebefb932f6b690583d11510afde9c30cf2d89b826b9aacf4a7fb5a1d23a713eb9d30f6787044e16de480970b35de9741b91c64106bcc9d1adbfd6ceab51d8ff70b3ab7b6ef6c8c80f4b57a2416ee6ebf0dcb468abb1d5bc64590195ece672fe7a07293b9408d2f3564b0cb973b4980bac5d16fc626f69a85947974276e76c09e444df6d13ea31d22bec30ad0befd0c7bc087948cf28f795c13ed0345908780a3b477e45b90158631e6b3aca2ca8d08709fed23789420a9d94760b9bfcd5b4940acc8faf4a10c09cf88a8271325c4e57749d291e9d20d15958894a9c1e742450fd82ae81855643f85dca6f75c42297bec0f33a43c43ca9feec56710e67d2dd4c68df60a2c9c520f70cbd5580a15d9474f96827d9b17b6f46d20d81c37bedc6d8f1b9f3efdb7bb9fdf9db392b64a708adc47c989c6779a0075357fd2649b7fc9625179acf99aeb99c17366be395cfdd1a63b2da2e43e3dbb37d2ceedbd33cbea564a0561e81f7ad0d782be493b63973bb3d31ca31d8c539749486fd3dd467545d64288c5f301ccac0f104dee411e684627c8098e7f7bea0b92e6a2b32d6d9eb621715fee969f3fbfcd12f86b38ebc4749b0ac7ef1a52ecdd348d6cbfbd3fd869c0a9ff1fe785384fa39ff60ec8c09525414fcefbedcc77bf7de3badfce3cf7cf74f7fb9ea2d88008f4ef44e208e30cddd3accc564de16158753d9b0a27b110f0d0a07ba61a01426e16dcb8299a49cc3452909998ac3993bf8a69bc12cdeca1d677d9ec16b0f00e2cf3f641503cb1634df041bd86875fbb51d36530de71fe2e371a0c2dd27e26bc79b3b78474cd393b2f753baef6948913f2c8b952c1c244d558815b0745b09287e0f6119872bbb1515fccf28d20b3b6839f89508157844d178742a9063b2c31d3186110b61b86e3dfc1037f30d8e6e55a047e5d0cbf523155bd4478673c6658544882f305ae06917d23ce8b604ddcf2b1aa838d5cc329633dc4b352bc54da9b0abbb9d5e578d7bc01a7ea1320be09592ef63501df85af09f8307c8cbfff368f74a1e4194e63ec8e2471a64591c7886f328b141ccaf81ac88467ec357656af2f1615bf50dc79397d34cee6977ba257917f947d4fc497d9e744ff32bc357a3ba9a64b65affb9ea8e445d6dbc708a512e6e7306c0ec6acdfa93a4b142533d62a87825d7c21391453f9228e4b8d158b8bbea6194e6b9ad87c3263f2c477ed8bd66c85d7d571c6269cec86c6648eeae2bc160febf911cc06ce31e29e31713d5f716eecf34add47edb735ef3955eae39019cd5aaf795cde9ef421766b5cf694cd51f9878ff7775fde26fee235f09c3551c5f76e53306525dea23bea85f836a7bcc9c29449b7b890b82a319edc4c4d7d219e5c491a3d92674496499e93f480417ed42552899504cb54cc7e2b34b8bc44f06fc541f006f420df4e7c88d3a505a31bd8d01355c40e8522bee2e667fb48e3c146b3a888d5adc4d1ae7b0e71e6c070e2e928459fc1c476b296a2628989d98c7e3c15ac3f4a36351d1f5083751233a851697aedfc51ea91cb25220d552087612f50a1b1b03b04618551410a673f7b1a98f802dc90b891c3101ed4aef54c6de1e9486dc56abedaa176b22f897471ca32ecc690879fc446038f039e73692458540cbe38880588f5cc5e1eb11d36b04087370fbb1725a61c2a76ac0104e812c224d755fa3289cf4bacf8d4cbb6fada79b67b9ca76df6b91f7ffcb4dcbc1959d16bf6287b863f06540f6dd4fba2d89454b3686b363549bb9d8c448cfbce2da433c2f7a8723deaae75b7de6b0eebb6afd95f2ad7c93d0b5a0e52a98756098e40c8d786dc976f50497e83001b15d8ab0dec2d152c5b8329951d101a42ae3e4baa0d29704f18e2ae920c504a47c5642918e453a251765a0a902507f2c42e66c5ab702ae9b7d6d013b04530396c47e03c3c0fa5f92a7ce6ab489e953cf6dde575b9871c457dbb931c9337fbc9a7c31b39cdbcc6e95cf295495fc9f9166c3b575caf92fd77dcb7ffeeece255baeae9566b3fbff30ae7d7b550e5a551d75832095f951c47bd624ea4238efac049a8d42beb05635ebe1af5ba824ae93c37b329559fbf7816f4af1f46bd92ac64456895645ccd1f2fb4ca95246a7ccb5aeffa55f71caf7aecd7bd9f5fb8ea7fbd771dad603e538e26219ca8b4c8c419df4f9c1fec5a1d544bb4f210e76ff3de73fd36ef2b1d24e54229e385527e9b938d6268222df25bdf9cae73eebfe9e6a8295fa5bb6eed8aab38e9e9bbf50aaeb68ababf4f57cc72a772a5829bf90a43e377eb155c6bf52aabfcf57227b27eb0dd7f2c65bbebbc8d3fe0abf66d3af077c053693a389758992a6038a38dcec92cb17aa87046ca839af04e7ba5914a2849287303e850a9331ac15ddfae9b98ee541a7c0213f561864219d9b495d27c3766dcac6fc8b9ef2a237024837635298d92ddbbff76d45d5ac188dc67517a48f07ea965fe3993ed14309b666668bd053bf9a550c6f61285222864ff1087e27d34e3a3e6c541e8ad06565a7399dcebfe87939cfbfff178e9c8cb2e4ecc1e5f58613499ba20845b6e8f5feeeedfdbe2a2749b9817e72d7e4e48fcbda682ab764f7a881399eb1b0e6310178bac7bda4b1428d815fabefa1e6f8d0ef28395139b61b1210d5f23d38327c48fddb81332abbbc0181841121c4a24a585e1ec64160049c8c491ca8de4842db97e2b92afadcd8f0ccc67857d14df134644c079b9f7dab7bffdd63daee1ed7e627236054e9a3cc6c1d40e22664ed4447db1af9dce09f8d2951a61507553587bbeeee9318eba1ff5d17a08d774fccb5719d16f54b090bb5ed98feaead2a89be57c785eba17dbe8b210df6fcbf0fda608fff4f06f1f7ffae1e397b78a123711f9a3c369b57129b6b1f8d6bf332a0a0d17b744e5c0d5bd1b46ec30b912b59d0cd061a74c1ca476827f9f491602b5a79788dd62eddd2afc44cc4e859304fc3f7898e538a81f63659fc7dc5a2e8ac3f22c2237aef1bd87e82cd89e4fe459463bec38c1cf45c8897201d8c321ad94c71800c887e5c7364cced3dc89f59e8382fb9747ff7cfbfff4c253c8f1b3005e6cf30794f95970ef3100f8f8d1c1eb005ce4a844ee850a2a11de975e9b4b0ad59a21c3aa9502db56d07bf36d4e7d1fb56eaf6ba46d12e7c76d62e90becd1d2f7ba4539fd18e180f935efb395e611ee4b4bb5b1c6dd865862632f38f6be0176d8e7c28289087c1b2023870e9b1c4db1cadcd2a88646b351c497368a09e72d08d3bf219ffe605208f7fe2dfef58779fa6c0d6d9c96d0ce48d32ff7fdb3eebc3d0a9cddf0e278f0eeecf6267f6430e0d18f830137f1c180b32964cea53f204115fe4cbf45aeafdb3fc4fa6bb14650ed7f8858bf2cd39b02fdb07fb3a9ed8f5b0a0ae6db3b5f7558698743ee7be9fdabab2099967e0db5ac61e5fc8c0017d0fdc934a2f38bd03b1c1d3fbdc5cd2b7732c02e06621ca97de7fafcdc1deba636a56bae95fa9d2882a5d5237c93735767d3aff486b55ea261dea44ecedf70205fa43bbe2c4f108a6d6142d20549fabf3e3efcfcf9cbc7bf1f811aecb4ce42fdd04195343249bde34219de6679faa89c28c4edae80bb164e60fe4a962234b04ad9a1fb3b83d8b5946a96df33013aba6b7f75150b3c92f688556b6039973a25051e3233676c9bfe3d48e049982e09e2e98e97e5f1bd09635133e96a7b2e7836a1e6b2975ca87f931273b9c998d15d305b2233235bf98760feaf12cc5f91ca0b22f9de64f13f4773fc095de6a516bdd4945b6df8f16d869357a9fe20d6b39f3c6e6474cad68dfb5e13555dc01b99a0baf60853a0811f3181f82e764a3908fc861a09765ab1959bca8d5464c535ede18bb30cecc772238d056ece09547d70bd06275d27d6c0b8d8a88c98015a9429f51b494ab5864c1d5e484963851752b3f7e1549c4cf2a625e7c01452b65b3954ca23366a05a81205d98233b7ef2a86352e20566cf6522b6fe895ea3895fc105b874f47a2c14b043727904f404e69990efb70d0cca5bcd346a305e91a32b0a6a47744c89453b5de146c0ba2ce118146cd8aa815a1cf965ba9969b209ea084ee5497bec41b8401ee62e7d75cd3a364cae51035910cc0fd607b050891d55a27cbc9915dd9cff7a3d0a88e188cb079aa1a197e36b8cb3dee6f005e6f564eb9cd5cf70ca7e6a350a0c90b8997c8d7a7a758700b208fe446b9e17bb0c3ffc2d8f8717b4cfcb839167efedbfe6d88f15e110e5f8a849ab111b4c2782212a49d0112165fc6d7d322fe5cc2cf6945faf66d8396b178d5fb23f63bb4f84a5a09086eaf0e720fe708363b52ecb9411d315581d9b7be77204208aab0e2730a5ad3fafbd8640fe0162d284e754f6bfbb5e95bb6ec6a19dbe6332c57cb075e57b1d458732cd3e3b4c983877301be05cb824a7501608b59d40dcbdf66502710c6061d73fd0f9f196bf15f7cee6def9b35fbf4610c2c8a0b75201204d36e047e0305a07a3970ce8f91ebbe66928511d2120a75cbdda344acdf4be4823033c41cd8e75146b130553d7dc0febffbf855625f41573b4335666842d64c234a75bb5fec71dffd0e2d4a09085d2e58cb17eb2b95e4bab0bc14070979dfec1e96b0d5417e59fefde6f3dd0f9f7efab7f7b6015e12dc490bd545b071811ac17856310e39c78120a0a9f4a523baeeabfd02c57ec1212270104ba8eb564a71d49ee79b29375cec056af966ea6188493acfe5d80840235c6b8d14fd60a726de0d3e54d68e9d09b19623111f324a696f7594ec74612b4545a9de14e819698908052789957a2858e7a961503fb04962aea40b63b7460324d6cae9771e7428c2bd1ae55de64e082321369d66faa4148112b7d415ef087e891c26f2d66dbad69e9fee01cbb6e2b91e9d36cac967a37cedb2514e1e1be537386c9ce46e535c4fc91784f6c3e79f1ede8a76e4755e1b4124efe1605ff3058fa53d86b69bcc03613c99927c57ed58c2fc710553eb0005f6f557201861cdce84675400ef6e0621f4f4fb0314b8529345103aa580d368402dcd701f34352a3f8c4ea901e2bbccaba1e67d2d94cb1f79f2ba4afe7d410a4ff751b5c6516f6bde7726c987c218c7afa5f7a77b4db31d0ac98208e1663556801c9aad2c801131d5721c80f46287a592c0b5b2049c010f1e9edb802570e8011ce1e2e8b7fa5d7eead801e980dc821dbe63045f86f9e3ed6a1d1138dab7d22e05613c8ba43f6f377c917d4d8083a67d4cc077e163827d97bfdf3fe9570aea2767df144e75303fdf530f2f7f9236b39db4c8b5d64bd27849e2ec8b04ae990a701f6c284bc7a7046fa25385fe4a29cfbfe778e3bc07a7eb979f37ba1b16082b2d2d20324812795da2be7f4fd0cd23640ee2261e362f1d82873c2177a7ba7cb98ce702f7b2681ebfe66eab714eb28ebabed8d32225390a637749b44be86fcc127afa937c02a3a41e7b7aa7fd93c73be99f37a513f7a02953ffaddd734b02e2a92b5d9e2cfed13ddf77f7dc49ef41cb40a8784ff0122e26a81877ffe41efa92e23675af4b8adb4cbea8b83dbe4363a30a9b42af8df4108b59077658e6f62a3c4dd84cd65ce6d975eee97655f0bef66752d9ad6e42090a3b0af7a83a616b05813927d05af15b32964605fee720c372cc15d83a0a0312367df65fe4738cec99fbb729162ad10154cd22c158c5556d4c3293c8ec5506168c1940349740bf2dd2c3b36c97ad6c57a5ed2b94b1c7082bcbea259a39af000d997527c0ddca36769a36eb886e0c702d785ecd53f7c39ade56d95dade23c8dd3390efe92afcf069bb992f7daa82c19cdd0617e358f12c9d40e591d1356add11fa3cd5fd67924bffaf52ff7b2c717ac234fbdd0c7fef9d3f2efbfbc0debd56b6da3de7fd536ca7db58c4afd15cb48e545d388a5affe8b5bc97f287c7b50e52552abd6979af505466f92796afda93275d0497276bf15fff7b05adb7935b7d1b1728fd4dd93579109169f1a89befd7bfe80e505f7d651a7d5059acd51cdeaba1df52c46f1148b1bd758dc75e940bf593bd0b3c5033d5313e125fbe7e4f55257f3fe72a9ab79ea85aef61e3b9916d923fa3f2b01931d685dc400d346dc2980686ef2c850447889230eab3039a5e2ec3a63af6c42ec9d2d0145d0fdec2650630af3049b7069f2039dad0a05802e2e29588ba8b3ef0610f246fc191d99eee51b36412d4f72fa0cd5f2e903d704a2dcd7ae6001b239bd3e9b9ecce6418572cefb9c890f63d00876b87d0972c3c4ec926c6e48e5c3fed397b7f18c79158506c3eb8fca4d56d4e42e73a50c20baa0f094cb80ef14ecabcaf7222b4e5d90a4f6c44dc750636a19b664e37139d8235a99caa1403038db64eea19eee0b4f13b2aa911c4a7510bd062026df973263add88fcdcfb7b9a76dd7769b6cb65ddb4d8503fd81c77cbb9f7a10c5848f5782e07041c9412a38919aacec3755a174705f6cb4850f70c36701d5b25c140db4f5966c206143387e7ea3ddb057601e02523329759185b55301ee297e110c39b4e26f950afc67a9a6f6564aadcf63a3d4b22385556bc7ee1666f7b067e11cea20d67ec79dd451d65427769159685a6cead7540eb157ca225133953afcfe12e6cf744561ca0a0f869eeb8d160634fb484bac429c8b739c64041a55079f1ebd461e4cb92ba0164651d05caaf81b38cc9ff337047fc32c920614697e420ef3e7fc13223ee146a87547cd2e69e6af61fe4c5f1dab2158a60e65ada99f3c5bc5660a6d7a742cbdce88e7aed256675b4f3d77b795e697bff6ac95b66e017a626479ba1f35a417deb7b7a47fbcf07dbf30aa8240ff05b119f29ffc1bffee5f687dbfa4975ef9a7f77de8f32fbd90ffd0378acabba9d54b53f5cf9bfbf23f6f6dca3fbe37ed0d2077d7b97f77eefdb66afb5beece393daa5c3ff7ed4c47cbfab77ae93d3e77035d03dfb588a5d85b369caaf3331f3dd7d3412e84cda99a6f6bdebfc435feb8d54c8fdfb6d2bfdcffeb978f87c3dd7ff978b7bc3b684cd018215a98c68113b061b511f7450b306a994a861b0b47ce1938ad3a2237a51647a1de63a63e22f73e5147478d924d2903cd618ff07ceb94a350adf0eb32e53a63371b50f82a133792eb419c75a357ea6a256835b2304ad8a94571f0d2eccbe945699831675983228a3502d8358d9863e99400b9cbd249e0ccc40dbef3ad066e4c5c9e3e1431652bd44465a9244ea51f3851d7c94da024a1585584422d873cf0b5f0434c9d046bbca304ae9546470d56c73673b7e681dd01fb6ce5a800c165f2107038b4a9582d5620300f8edc1b7cdc80cc182517d2faf4a198859a1b8d7ead5681f5467b0d52079543ac893843798c4d3c6697b45d5cafa2c48f6af5b24ba1a46c1f8ab51c674901b142c95fadf4b43037f8d8ba1325de5eefb9d0519ec9ff469f79967eb9fbbc3be7bc060fba9ea8ef4a86935cce40236fa4a10ae818b0543f8e88345f2dff7f15d5fdc88dc60e168c3f0fa420e48a58d0049c6fe08613c3cd097b114001078252918870fde698eb1968ef352826a5e099f96e58e0e1c1e5894076814d8211b1353f12353f2b1d6b35bd930400065b524052a6eef964ca9eb367580065ed856090667b21226c37f42ddf3e5b4b0e23e6099cc09a98da6d5e17544f4b372e86ddb1c7c551af0ab13bec150fac6d51b219c18572ccc96363b1bb661f3f701dfeafb81eec0ec759522c2830d550943434bb0f671e1cf73ceaedd68a589738882370e261802be839a683981030f865025a81b683daaff58d17bac5468ff8e9878f5f0e9f7e7a778124a0cfd99b2057c08f761b511bdbc4c035adff1eb8a678bc1ab9a65b3cb5e17cff7cae9fb3bab4dfac2c7851ee7caf6a0d1049e177bef01bdde2d2fb9c105d7bbefe269f3f439fb92844ab3c6c49d19ab629469fdf8c6cfe35ece0854a2ea12fb156b2498ec1a25c296b0f52495423b744bd023ebe979bdc6934b64e3d1aef54a9170e52f0039da49411c0b436323b75d7256c13d64ca98c054a07b031c5d4899919577b43f4171de0c55bfcb8a815283b48e8008b5b72c4fc64833300947321691a86908e1ea98d1eec3bc4a660a5d16c9a1d947bf6df2cbb2cf6600d9a3b25d3254cfde01ab264c7ce96bc44b0a1994dd2068d8129a6b60e58f7aa965a4a8d995ad698892b968d46aa516924e0f969ed548adef4419a4316a15ac6627a5dc340df2466aa0a1484ce857217d053aaee5815df919b15ccdda553cba659a080055031a61456c46b371a6380fa35a94e5651bbd677a68ba4c44076e5a141ad9a0a78444b0947a178a10f7cde0ecd9b29dbf2ffee84dfe60fab193041e80a36394dce738bf496c53438d8937e340333a47dee6706e7b935fad83a31cb8e4d116956c3246d04ee880a69945b90d2893d3a24356fb854690ceb1a956c66b0a6aba2f89b4b0baeea8b375fe6a0c3fa55c7afbddee500df64b2106ba6d4c1a36453246c0552d668fa730135aa708985d2182674826f56383b949223e50a16d42c07551a155e03a3b625536e39e2088a8a6a32dba0b9524e1ca948d9596fc3aea3e5e9f818a587ac722ca3291fa39154ec1eb51a5ba7660331988b6b4811a96d5e8ff33afe81671b40039c40dbde295b521692964343cbee871923f95213e5beae239c2f1584cb56a809f105a1df92f84f8f1fbf3cdc1dbe5b968f0fef8ed408235a5fd894d4a2d04e7b184a49064eed5f0a33399e12e24c8cc727e134e837c4f586744c3e25ac4fdfa798d3ce861e1b967ae8e1743e6991d701eb6b6ae4b381ac7f6f83d6a8cd9f0a00e12e75b7f2d2d6ec4123c7bfb6696ab78869b5ca4a4cebd0e89675ce8b29a03e4dc1b663b6e92e687d88c7bf222e44adf352f44bc73f3cf1e91ec342e630cc6e5640ef349650a9b501ec7fc604d0728f5de03150a8a7e6f362627b0810358895534a4580fa657a7f2954854154d21c049b466970571acebcc060495150b4489db762676c0cdc8c683caef3e6d8a9256ca068c20e58eaa069c6368a580ed6414b1efb38a8f60ab4dbdacc2eef05a11c45732895d0fe829d227f20da9b8b1572229717d0cb58be285f9805181e9b88525a7af69b8f055cef166a6ce61d95cc667f702fc0f4c83c6b27ceda8962dddede9f0a8279b2f4382849f3eae6e8f51d1ded2a293e6308de58218bd447b13a930c98db0a661bbb25f8c579cb32aad54910a12e23b05945be11d6f093a835987d54c6c0ab109767c24432f2cc2c786641d00b3bd5c4d1d29bdf3c5fd6e6dd9787af6723d2e648f6ec8e8b83daa7f7b761999d59ed91eb5d0f7dda1f3df47d947c8c87fb66a4bfaee9d29cff1859ae259fe716410a78ba12b2e9b8b1910e39884aecfdce142c9be0c758a1427c6c487643e8fdbbb3a7bdc84ff75172d094af737a0925f0f4e264a3e63ed77c7e25ae8c85db1084d8570049e0f8faab9f2dae4b322be931cae5a579adb72b4af0fcddfafb7abc6043ad527459063f6dadc1ffcb4f874f3fbd8d73cf6b584b4c1deb1a722a66812c193dfefcc8423297f8a631636603d6816acb4b2c36c261f759aaf82035e69f358acda49543f2dbb2ff94f52fbfdb4117ecc603322dfe8ae28589e7c558ff4051423ae8a032407c5146ffcd852fc7c24b079c247e74fdab21f03961b2eaa2e1fca635d59f98b7e490bce47956ce6f2d799b257fba8fa552a93d4ab569a12e1b1ff15506cf5fe885f32f285ec6f875199f7d8886edaffda68ace4a12b72bf57223bc50f263239f4b4409f32f178c72148c38e5e999dc1cc5e82865df08e76f2cfca91d44337571a778e9f0c797497cda9681c104c7e0e702af8e90605d64bea98aaa6836d72df1ecfe79e7fcc3ef0ee9a6b96a3aa896b63ccbd9cfd7fc833f71c899717dfe2ea72764bdd7ff58df707918b3d1687308b384cde1ebf3f2efef10212927307a5f73915b2e02f744e738666ab121701d00fc4223e4140916163cdfd9cfda649f3df2559e21d882005e4ff0b50e5e6bb3d54e5b0db58323ba443285083e65a05c2ea4a149a80361f3019cefb756ca6701b0e1e4ec375742379c1cb5c8e24f3c7701bcd59437bd289f3e48cd21838a178070e02fc866b9849c1e624e4e498a2b8fd17d3165e522c04d31a7879cc27c30e4f478d9ddf52818dbc2e46997e4e91fc2f4de85e9c556bfd8e41bedfdb7c3e7bb1fde9bfa2303a0bffbd8d3193ac619c0836b87bd5183cf3f02b0564889e9d99c896f248b73722c0dfe97136bd64ea459ae0793266b3b215910758f839aec4c8447c6d9b54a7ae4daa7087d458e7b2f5c633fa16e7f957e8d0092adcfd036d5ebaf1879f7acf5d15ea609347dc447aced7d4f0baea609bccd0ebbfd18bb3d7592e533317fba8f2c39385406c71125f9ff0f5152b03f83fd06ffc5ffd1fe8a9240209efec07397241402b725a148d890d007a0a77e7f782bb4ab57393b2bf5904b27bed10e3fe03a487719d72503fab79ac9dd81cd00c811fc020c558753c94cc773107899f5a421034a44873b29dce4627753de29b02f9c8cdadea0a192dc28651b0981f293438bd944ba057122e17c28bd530eb980e2c6015c5ab09b4400a5d10fc0c590028e9c0c380a487f75222f2cd43c7db0af00f2e80e6b0e2876cd417b725c157b417e1c542f0c725d486e00aee58427b9d14552c0f356df1296b3e48b22f3ee46b55283f4be346f75ce39420cec8473fe5ed5a9bfed3e0076b894381e6e7e58ef5dff79649cca3e9602e0f8e95a20313bb6ac4f875c1f6271f7f78e2ba01491be2b0d4eed1ed3df3c2e1193d476f365ae9b73d45c2268d8cb6f20b4eaebbf5f69ddcb0d7ba14d1f7efef2f9a7bb5fde9db25b1d838295ca22d6e9cd6c0cdd4669e01f57201f3fb03081e7b1f8b538eab5f6edd8ca5137825df658fadca9f7a1015afa01f825314bf27b4e260348680def44545c77df8b1a3cafc0d5d94eedbabff2b4ff1dfb51f1748dc3ddedd29e733eb5ffd441bbe9a06007287a0cdf09a33a8e1456f211d71391f0087e09b36de5c03297ae71325782703297bc7132dd30b1bc5d10c4ca360aca408c6cc6fc56c5e12850055ae421c2b7cd2181127c3b12d59d698d41c53d621411d9bf325ef5740a5e6c676e3e5105214cc7f090b3d091c79a6d7edeee277853ac83722ce88702df17499423ab3e7d90268ec5f36d833d9cb7d33351791e0de5b8c29b4d6e43b04cc3e29b28aa973aeadaeb2e75d7357dbbd3eef61fdf5ff09cf806fcd29cead9862b0c8773dcfa5e86a3ada15b591f46aa2fae3eac77aeff9eeed10915b178a691fe8e91d81fd9559b42e1330d5f014493dbd47d9b4d027f8fc9f0183343ce5a2689966f64cd90b0e3f1e95e05e334e54394463d4ab71924535dc915d84f2af508b28694a9074e399a2a6287fed2ed969d69d8636547a82b3b0247821b463f74a616ba8020a1ae0409ec27953af18133fa30086bd72ce6fbc4b59317271808de059945da0579fdf46539bc916bd6f8c3de8a927be83b660ebe873a5c4f78b02b1bbb9aa71dcd5e82a7603773d4c57989c3e425761ae287331ee26fd888cff88b2731b1665335bbd30260a0954a35fa9c060a10b601067e8905b866837a18005bb03301e146265327e17889e83ed7482b80ce069c8170c21eab2f3d9a1d6f97a35d16d2b8ca8319f92610263e02cba80d983e94f1d6606fdd6919a42103764f53b58767a5e5170ceaa3445c9224245e10a5375b4b79c5d087d0393348db705a850c6b042ae8aa67e6733d735554f3aaa8c6f5f6f51f6c4406c5265c5aa23b9536b0930e6a7b1b87b089ab4e596a37c479c3636c150316e012fdfafaf0deacf1058fd9a530f3b57fb75a64af1d16cb46f2a33de98cfa5aa1d134eaa19a8eea1c2b24d154a4d823bb9fa94471e0bf6a27ffa1437906d52a1047147ee08538f64cc5cf50c3a64231cb9f3463bd24ed975690d6b40bb2fef9fd41bd7032b3b929e922189f6c5622308163714ea81ec45a90338d45a3b3c72a0285756247ce5525d01402b8531ce8a478dc82426a6a54e288b882037c0de1a80dea14ec2d4451eb31363c2a6c6a267d8c32c82453919159dd1944bfcdfd8f35da3cebe4bbceb2aba4f0976e61fd6dc48fc80576011c96051cb38a2112a461a70f8429cfe4682d6c050ec0542f0e4a0ac954bb5be13c6e1fc8560fa0b6ed76062aa4b3ef13f720679c4cdd1ab57a5e09c058890e622971e61240040595defa48b6b1fbf85a1bdc11a65d83120714f3aca1187615507c6c5042b1d7eff5ea4841918b153c87595341b01818322a2a78a5a29de163dea2ce5fab556f1cab556b8120d332996d775607180dc038dc308f410802fb9082deeef03a47a1091cf14e2cb3c4296667cdf484113aa70404d30a3d3e775f00ee7e668787e39fe1780d67560d3d9c120452fdec96a73f5bff95c4584daa2beaaa75131f49ebfccc71f0587e9b07ac59e112d8315b2080bef8a2e95891feb3f753b38fbcf3a97beb2b88bf145b22a6e00e0cc2651a69344cf4f3dc3329d40e38b197ba944687f20d2936ea2892a7728dc3fa003a638fc7e77d010c006f6845d0fa98a8f408f6e8824f75be3afa0f3700104802acee024a6b69289f17caca28b1d9f805671e33402ffb21fa107e69dcffbc01406409ffdb0f9fde1d02c57f7edb4eda1c5dd731c2b42c482f061fbb5613c61d71680c1353eb5dad995036d2051bdbc0be8835b9d13686cb7479ba375523b01d0f58ecadeca061f65d01db249db0c60396f57aa8ae75f7c08ab0191c1bf6deec80bf91d69f3e5455f0008e9b328a8dbacad842f779d04a652758204f07105ec3ad2f02bdd8bec586af86410b231c535ffc7153ee3c8bb9b3ff92309b645e90664bda16e7fffdcba78f3ffdf0368eb5af09f21cf070be04e5fc3d2229b11035805fd29319d66cbfa6d0aff7aeff9eee81e564320d4e45413055c2a86a020d423613e8dc6cf8c6df10e74ebac332dc9466f5b5c79c9464c67d6d4973ef17562aa44301aa6afd063a1603b6ee747cfa903b0cdd050ec56720410fc76545ff3fe0cf809323aa10e0dbec3b75ea48c3752433817b04189ed9bec904d27a74b6e1f31aa875e2446e3a4c272178d036208fb85909203f35630360f1381b83faa37642af2689d0c834c2a0cdd7656c2fd8841481666fad14678bdabf97847bcae905f99ea9db22fedfbedcfdf0cbddcfef2ff68c876f2ed1e498e07a88a3983d5828ef8a29702aea4bae5d7c18fd950da78b4b64be12dbc4553206844bc382588d6c43d3d307c009b541fd007d82ca63018f0636cee0d808bb116c7d8e2508872a1711c72b1ad46e143c0bc0646cc1d72d387006e11fe73d4637dff519d0276c2c374be510b958e713ef7219ec0539941ab8f6f524cd955c289b0cfcca447adb1bf1a13a0fc912bb0fe212399b026b534928568b981fbf9eef1ebe9e2ecd74f6794dad33988e1a4b3b8cea568d2c6e1751769b5a7c0f53d9745a1ec9343953af141612f6e8ed04fd25dda0926d4e5cc0ec04f39fe7da219473a61797a65761bed011d6e4ed9ef07ffcf43f7ef9f2f16d7c1f5ed111c4e66f04048fbe93ca94bad54b0b92959857c565016184a9cbd844562556c49d171bf7f79d89c76124aac3c6ef244f1f348b272e6bec6b0654716da633c366cc23e641456e44078d611971122af2cc6280e7db2a27bc0a4a589107873b0a1f8107477320c5da5cc9dfc237f45c8ff91db5af0f36fa8f41edb630765d486c58e8e0f7b11e2ddfb10a752d61fd9dbecbf3b9a70f0e0ee703049f03e186dc6f6dbc91bc3375a707cdd9b96fb43338c74e7adad3bd941a73c75eabf68319b90d688805bba2b99d06990945f8708e6008688a82ae2dddf5c2b9630b370deea64df63ed5c97ed2278b2994e21731079b703c7f7dce2e164ef5d927d7a73551a70494e90a4c298459670eb95fe7e47b547c2cf58a08fc6cfb40014ed03636105ee893b35b5de8923375bb47debcc3e5d229f7dfad529902bbd5c0d2ef4e17d364f287c900b2dbbbaad675fde8def9dd463ed8f5a68540132e717a2ce1c425e38e5b06a19effccb867ecf926bfe33bb48286f973846959c575939832d1b032951cfc382310cc6476c01e60b2aa3cc67e1e729d3ce4fab12790f539429e274cd4839aceafae007a92bfba1a55acbf7d9583bddc573cce3267d0a1c6158d6f167502f9028f2f2336c04a7a760788925e92cd9bcb4b9b371757363fbcbf29e24fb5703f70ca8844def28e7c78e613f99c62e93961953bc1b116ca8f792cc07e6c13c57a988d9943eb96c6d4960435a738f0b5381436176a87a8a6da558293b83add7464aca29a310c84758452b52562ed46b1e8d3a164c3483c30ec4b1ab7198e2955a89b89500bb159084ce3d1f410dc1794c682176185b0801c4e8365632f0aeb8be6b2b0ef330dac2b5a517c994be684ea24433d360795e856ccb514da1d17b2c4961cf61b958198728082f8a648b04c402b6419767c13f0484cf3c2eae1a0b95b17958aaf426301d897a3b1c80d9e3c38c7c742f2d86d4017c5a7c16f18bbb336222af6e13439bec6f4230cc5a61ef72c8cb8622a20160caa655d01bf810837eb7f947758575410c069c128e523d1a3cda7bb14f260e0dad81b58825d054e8d42a31697d50cc3cceec1991d1e7184a21e4b45a5a6d5bf084afa0b3dfdc3a509e8c385b9e7c3a79f7e7977863f80b4d3b448375c3a56a895675e3c7b1ef23bf073ef634e3649fc275e2f7b952fc44b42643271498e2c6d5b94fecf4f3ffd8fb7813b7a15b60bd62efa20817dad661b8015b3fad55dc941866fa66a913fa7deadca4b8e2cb0b2312459d7356b04ab558bbb6187c24e185c421d4eb487c5160e58d9aa390c85838850f7d3df24ac8b89583613491d8d2923861cc1027d37e06ed27c6a5a558d05313dd840e060534730ab2bf4848d35eb38f83b57aa71a680432d8eba1f75d327ec1aec801b5e642f891e64e882e821ed82e8fdf2e5e17d2eedf0954aba12c957806f185766cc956157b1b873a536455da52b33beea55baca45a98def4a27e12b3f26fc37afb05c6b1fdbb7e4dce7f33b3bf52c4de2c77ccda9487f356dea4a53360ddf0a35b3d02257dcea6d35fbeb4ee54ac5536c926a356aba01a646bbca94da5dcd5735cf1b72a691afd20ddb7056afcc28abdf9de57035ea15b2bde556bf7aed2ccc5f3f70cf578da9b6bb725590c4572596bdd8b5db5cbebacc956a3dbf76556e6ba5daaea58cafaef74eaaa76bb15c956b10a2e82d73f93a81cbb342c412cbed5052bde63e9e5fffeb07cef98a6bbad6e4d1c5e9aaa799ce355da5bfbe24f226bb9744ded2b645fe9f0fef76de761b053ea4df7af25e98d22b2c9bdf31dbd7fc88f1f99b04ddd6026aded76d97e37fe807bf533f30d1bb20b096b42dafdf7f5cbe7c7c771eecdab185943ae941cceeaa427581c157a2ba0f4c8becee047be74c620678a64d8b1de81d7e66324fbae800d79bcdae9187cda6d90ca616265bafcdfc6e64b404260a6cc0ab596bd2cc5af33c6387fde62caeb053862f8dab5debd4e1c10aa0cfbe4433d48a3b1460ff13be8e378cdd30258fc29a1e09695d882e002b84030d372b620e25f9f7e0dd19f1833462c34e7bb35f75b8260227770f32b514fbbe4778c1c9ea35938b877082fdb254d2c5f59c04a48fc0eca092e0729e7e2526883bf1e88c817eaa8861fcb3cdaa0c5457ab68acd35784fc70269ee42e3d0122ad461e12b277db20d9ac3f53702439e6f201e08982f0c90cc0cc1a556ee0cc6eda9173250fb06c6187112e6e019e76eebc830d6e2ba359eed9839662b5b245f021c34989b29f743811720b05ca65054716c8aa7d3d6d122eafb18070c0b117583dc09f4be165e5bffd1144570bc8a54d49ac0c06e80122e8870aef092b1806a247dc1b89e14452e10de20e462fdaa2dee32f0c149e7861a8d87ffa78789bd5a7574d6e70cf6a0cc770ecd5662c69b2f38599928f110336c4bc25d82d5848c27a8febc2fe2b79ee6a330111b005ee703f5078de60d776cca04cee01fbcfc87a570a76ddfa40efb3ee91cc82c82908c267e07e873d8ee6e8ad72f2afaa36634853d2c340741dbc26ac55bbd92aee5fa173ffb104360be54ff79b82a3d7924c30e101d1b1fed3a62f2abcea47f480d548fd3f7acaacae23209cd54367256633e7b2653e40860ee4569ccacb5bd62ecb973a01122f7482771ff859d11f7227dd65c43088a6e95dce1df7656f73cccf18d7479a76e2f3c04fab663785052dcb8df23b09fe3451fd359149243792e0c03912e98e9d6e30b1f7012dee9f61d9bc282a2f047dbe10f1f997bbf7e781aca64568cd340e36c9aa1de405b2c97d6c032ac216797c1b604065773685b72cb0a373213958ee01b9b31080cb8acd8cddcfe0f0950ec39adc0e8b7b55ce3b6dbe261bf540dc781f197a8ff076d0fac3b348f5e781e61398f5ebf0f828a236915f3422765ac4bbc6b311f4fbe723e8e21bc5abd3029cce3094361a4ff70c177f9b46e45686e97a022fc8ea6c68d8e2ee98b15f6f7c344c593696f21c4bf5d16d898bae9a33b6d7a1a731df0ca8cf87587a2cdd3d20fc2076c8567a9cd5f6b2abdb5fee2ef96dfee5ee82dfe65f3ebdbb55a23f7b6af53073aaab22ea6aaa9abe184bddc7510f2aa15487f8ae3163db6630e55d81a3ce80074a71f79e575b9882dd14384f22de533aaccd5fd9c6f8cba74b2b227ff974613de42f9fee3fbebb0591e2e008391db2d96e76584c03afa4d8e362874b11813d87d1479c081bf7b81a0f97231bd2d24dc939f0c8940ff194e1a5bb3dc770cc31ac6ff6b72201e50ac7bcc231c3cd9b4ff9cd3b3cb5022106af7c9e53583f78f3ded3f75ea8929b63f5fde91ae8dfd16a0c04ff626fb9ff78613de6ef7c1cfc3b6ae00b6dbbddac0fef37202df33f02d2fe1190f69f2c200d24036f1790368392b54c0a7dc057db6fcd0f388f38f7ffc3bc10e6e944e6869b26b8c2170f9430a9348b9a6aa41accdac2bb25d9bbb1248c55c081a0971c1dd524f2949d79567d750aab4f56c73358edb046b3c1932f588784777746753b8b03186aa2ae5c352f38fb7f2fa97bcc869d60c33820dae3dbd80d4e361a98f27339d62e76a7f8895ca6ef90000e86fa1f8eb183d1a719eeec0437e1068a0efb14fd95e03a44a291c4164b1c58d085c8c116b3c619d4dd4aab265a1b41278c58759b84007984b8132ca8fc4ae4492994172c4656d87f2c2034733f798f87fbc04de1709ea9eeb8daf352e1fa05c54d8abf498a43e9b8803e9741df98db2011ae850674ba6cdd4cadde7a7392223391c7cbd3ddc3e578bc878b0179ef4ef3ffb33ab66954e9f5d978c3608715e16d08242b612e7e0018a0869c5c39e7503b8d50c55a8c035a6c5fb789a1e7f6a915f079799eee2300bd2e466f69678fde02588184af87823f377eeb8f76a5d70471f9fa0fd0ecf33beb63973ad846effaf9e34f0f9f0edfffedf3e79fde1bb25cee2622caa6dd94023cb8c8d5ea42b10deae4ea98728181621a60814873420306ae89f2cd0899150b94508412229c4c1221410016bb018a0a7881ec712c6805d76bdd9b9d0f3c6c1a14ce9417386021588e9d9b3d41361339d552a81aab692c1de46b4dd672a2c8175beeac29b61af02cf9623bbecd4099f98f23fca4e64ed0b260051e30481c0650ffec8cc59d368af8ee790f66db450c519c32d51baed657cdceb3a7d1e360bc614ccaf8bd9e88aa0dabba8e93e688fea6d330d6fbb513ef045b73aa88f0e4e1ba29674074a7e1816e6adad098a573ad64ba495786ede0842995f491cd505918bbacd95dfbd49d5512747e38187b6cb1a963a679b2abf83ebc652bab9ff9daab7d17b45cd3b280b617f0880da58465f3eeafaa21dd5a1196193f5de79e3863ebd004f6e99eb1172f1d1ee8667e74202a32320af68d527d935feabed44dbce05bc99329e12b2ff92e7321c7c3f860c365385ba417d675a7945e16ef8d21eaf6e3f2f3e72fdfff3fbfdc7d799be5ddd7b0ff03caaf1fa934ab73699ec834f771549f94cf763ee6d6c7b5c73a6e3d76adb2c3150f0199672a8e70e8d9f9d575ca78e421975e74f9a9e9dd59cf267e5dc10087fcee8726c0e3d617dddac76e3fe53040ced1e8c13ab7353f7dc00ce9d79cf7d8f59c9eaf6b068132929eeeb54848fba9acac17eda563faa35da8146f80a9e16c36c2a8566a40696f16fc76c02dfd388b7f5b53de2e97bac3b9646f7489f3e4ad6ef1d32f0ffff5f32ffffa46b06eaf8184353d0c18d06df8b850ce81b5be4f61b8d2859b0234bbecfb5e051bc4d65089f2add67eddb0625d570296fc15b7b9effdaebce65a1fb56e2538e1f94a779ec364aed1bad7ba99b232ae477fe589d2e511fae052279036906c63632f3770fd7c6bd0f1a5c1d7aac5f4b7e46cad0f1ed138031acf685cfd18e7cdb1a7a77bd57aaa89f3929e3eee5811a7c28759d0b526be4a9984f12b8f4f8ea7ba885ab7d3d6da383540f4daf6cab07947b08606e736ecee96e681d30a9718ac4315a0a362cfc899899dfbb79b828bad565c96bcc972fb7056334050c73a932f2f863163de6dd2c2c21ec296509c1c8f6fdc69b2c933dbf4afba2adcd58c8e33f8e2f00c92d8c5339ec4331ec5f372b73ef6cccd5e7d4cbdd0a93fdcbd91c1fb1a5ee99a6d906d63fa3b397bac78281bf4df03fbd23b8d98bbaf85b55d16b01860550ada56cda8701844aeafd5b9a454631ff0ab003a62981213a6c484a3c4c4a3c4c42931f15c62cefad6c3f3cef54c62e22a31d125264c890947895985d17d8400f958bc74a7725ec0bc0e303f042b42c54d15e2d82ab543866344773dd8ab6b91b9886add54e1b8e9bf533b751cd2ee27a0d8dc18999e3eb8e4ee508e9a7d8fc5f7f640ce717990cd29bdf741b66e0cb2e1c2ecf2749f1c09d245e2f990faf06c280e2f0cc52f766eeba197bab6a55de8d86fd2a96db2fdc73cfdbf749e7e49542e89c986887cba3bbc8df9deff38ac6ac3da54afc4379a866368e9e24ee6c4b163ab09e4cd0a9fe90c3228dc10e64dc1b757ed9603c8ed992d370dca40d6d36ee3f97418e3c049108bcc597d66a9d008000752116cedcd221571be45b0fc1fb0bdab89f820194e1219d046ebfb96592014068b745e62cdc0dc5a50d6e09f04af4546381ffbfa1d573eb099d5d9aac38c5d3be8cd4cbf28009fee0e5bedffe9eeb0ddfcef6e9dbb813b5ff2a3a01f1f7bc944e3402f39eb1ab7b879c968991e158054fd166ef988edaeb1db7fd74d160486a7d803ae86ee2cc319735f05db6d07ac7edad7fc68a6dcb4014d9a9dccfef78413a5fe3b82833e684d6ff3dd5ad31ffdf017646c7390b1eb5b52f6c3c7cfefddf9f8100bb632cb82000986eb2dfc2a4c2744400d63f3b8348fe22f111e88d0dd4a9af11f3770506e8df491b591c0554e32b5c7c8ad3b01559e5b8688f5590fd72c4ae3951eca3708b0e982c5536d89ea01ab6481b5ff068fe50238708f2a88d3932a23be38a744733b23075fef6bbe80e887bdf44e79c1c897827f1e48ff10f574a312b858250840132f4ad52a269ba2b5265e90aff766bca8bae9716df5b3439d4143ee051d9681238a6adba59001d6ee159bd77acd6bb5ce5907b272ac7c48cd2db27941ac9eeeb9030dae51bbc9a06f876c9646f9e0abcfad5059c417684d333251c6bec414e95b9646c5653e6fc9fc8bed79a929b75a717ff7e56d82fd5f354208f58e0ed018ce925ae431d67c2885407b4f7598e0b7115d3fb53311b2c11451737263b3070f7f4a1a2922027469d4002a6b9a6b65c4d6e4982d5329f698130ab156ea25f44a09049acd3a707792ebe96661cf047f862b6cb0c79a6f72a29e8364b60246942bf852829dcd12062fe1c03ea63dd588657e2d0619535c2a8a1906558d0013b09e6da54ea6de14a0c49b05d904b4e77a5321c63ec7742b45a333c295194e9bd789d159586c66cc7dcf35fd473e8756f430c7b6a041854a07bc5423157c54c4475143a45a8b4c057b3db5db7089104a19ee4dcad2b1365bf3b508e2959feea3331a3dfa5a73b234ae97d5777482cd4e63091bbde6f3a7e5e3fddda7b7d1e25f498e0060afe39a1600b0785043855c4b556af9bb533acfa5b06c4d56e4f993e84c1d0bf4d2e408aac5818fead10ab3c5eb4a660680eb57f7c66fee7dc9f05e6b77ab45d6b4ad46391c3efe7fff7a7738fc97bbc3dbb4cc6b56ca954907401073bf935e086c6af899352dd8f00462d3c04e21bcb10af08c1152ca1d8e1d5ca9df49b6ccc66c2778fc77f7f953ea6dfd992de0747c43e0cba0eec59f29df49cf04266afc7831e0a6d8124ac1668d99318455a995f469e5ac52cab1c39fd0235c257047310753b1391071cdb5102f9d6a1cd38f4b238f4625e220938b030e94cd1d3000f6dced83a87cb7f53dd206b17d3e5b455a2dae0876092c594adc9d32120368b9935e49ed3bebbad166124962b6645dfa0cdde10e6c15803e837ecce6f23bc98db884f9b302d59144846d9ac2c1f3b88a36f6b3a12e66f729e3042735ac4f14ab8a9c683cdddb476a180324a005ce8d3609b550f2ba32690d8312a416e68f97403ae63bb63946e61e7694a40e30dda32056a30a76873b0082c16152b04f9d28076ceb32d07f5b86178b52454d9511e6cfc4a21c1ee36d169404d298ed80f59f848079b3e8798ce9b451a398685ceedde7dd74b38b9fdfb0d9cf7fb9fff85f3fffcfb77163d19eff701fe742494da852be61a9944cfe79a54f1530d27bb8d90c2d7b7457494b2c7efdc4eb6bc29ceaa1771a2dd8114652d2e04793a1e6c8aa3845c063bbed83121a8a018f5a685490b2608764de650aaac0cb20754add23fa6d62553021f1886293b20a550e83328251a06599c604bdc7d46c4b418812ef541a0d338706c12bab06c962ea0a4ecd78c37e698f9d1260fe1b7c188704cdd4b1aa543954cac0c6330d0a3075337b4b50bc1eea7a2a56053d9cca670a95a83d5a102bd85acceb49abd4fb83a98c25c7caa40262848e84f682944e21db96d09978493a3ffcf24608d5af9981a6745a059ea433fdc74a673f4967bd209dede943ae4c4044a80844026b5bcddf8417c98c2f128f90123f3e8fa3926320958404634c3891560fbc5a73befcc8cc3a9cb27e16512533a44a6eccf287b0cfac154153fac22387f39ccf83abe4185db5965993558857463856c6f60387f3bab8586537a73a7eb90f98285fec039678a90ffcd38f3fbecd3648f9e33e6a5c42e343ec23f4712df9cec579ea5fabc89f5f7d26ed37f67ccebcb08d4021f314708e6ca27d1a756dec8cb8fc72ddfed38f3f5eacda7ffaf1c74b35fb2f7f7b6feb2eff79c6967b534e544cd39c331f37b33a7de6eb319360a3a0006eb45892e3e163dd0f0128c0351dc07db1bb2a490ba6d69bda57ac0b32c3ad6ffe318a19b729b46e65d1617394e9d269c467b778598259c0d0b6b05ca0391edf151a25af436c620fc52e790da7d2ee8a4d84569a61efb406d5c2a6f3daa994fafdbca189cda83977526c7a63d09d4c15f0852e6ad37faa0075183976cca55caa558f1574984d9fadd29246b501c7d46e04a2d487a8d43a9404b60b8844d2bacb092f3793c01a10bee28398fdb4d487284a0d300049ad14b907e642d93d7a1920b7d9f7f8442859c3ad9907c081b38fc16c25e1428c4daa59aa5dce8d460659f4c8d82b531e54fcd4c6c17b786d4e9da1fd996a513fa9456c5383ab45f5bdaa45bf3225fccbdf2e8e5afff2b7ad41ebe78ffff7c7f7b7c898268f3b10e8f666611fb9182b7668ec77128a67841b69e81117af9b9e1342566cfcd8ef4a279e41a7a1b1075cbd1e40aebb9e4e8adf6263ac7e9b5f87079476295c63f5bf745fc6a32ba33328632389d4ef188ecf8ea8a8e3e11a4eec3bce0eb4e13114154b0d3dd8b3b7daf35e7b7efa20d861902407df8029e0bc15df0761ff2924c487cca4c1243c8c421247a67ce14ef84b5b76961ed67fecf4ba85e44653b25e3eb07d28be3fc2fe6359131f623383ba65339f33483bf122bb2de1a6cb420c79dc9461a46c88f097dddd971ffef5f3dd97f707679500cd767423c67e47ebbed031eaa34abae4b36a2220b24821f0f1e66ec32e676a2d944e5aa3366a583d6f18236ade49c7a0ae0a5e0f4d62138807fee0df832a358c89a94312ba2f767b26c133d181b5ebac4aa288c6aebe03939bcd1b39f7eb9afa6557dc0b5ebc4f1fb8a6a06986e014b89c6137a07828d3c37aee815733bcaa160fae8aeb793cc65a01dde8cfc8eb92249ec46a4b1a4fa9df4ae47fbf3bfcfba79fde2644dc3efc0f4781f430ea66a8d5f782f04bb8a985f400a03c30f42346eb59b8d6d3bd878de401366e20783160145b94011cc44c2de64c15c456b121d8372148b3804411b19cc597e2380ef5e1463c8202148863bd8458d05c496e105227ac0b801f199922861b30ff4ececc856a68346c8aae01a516f755d49bce36d72f4a253680013a4251b5f442f920d52358bbaff755acb262e52f814cda5f906958ffeb870260b842796908f11dd8e9b1be9cfd2eeb5407200a8224367b22b4c316002b09971bd1998029ccaecf4062ab58ed13b34462f708742ba18278d1344347e4c79b26793ac0ad1b0916fe42995fb84c887d9e0e9dc377cd5bd076f00230f5e585da0b78237c79285baf639fd9b23e7d6870e4eda06d57126c15a181a00d0aa4e7104b42bcf17204862af18423950022f5a0e24cedd083cc5a2e8372b4c352c15d00257220d6cfc91d903702d715189da510886550752d3acb5fb34cd4ea48404bc59777dc67cfdde8f03365b3b31fde0873f535517b583c66e908caf2cdbe3837fbdcbfe6619efad69f69139b7b82015be9859dc8e7c838748df9c6c65110a4d464a767739a0fcc67a32ea248462359040a35c4612535c269eeb7ee0609ce236cb9e06533f1e903165bf45920cff92cf370165632e95dcee6d4f3692a5cc647f7d6dc6effc31696e67fbffbf271fff9973742467f0d2c52c2cefc35eb643c79e6ee743065ee5b97a7eb92be71a07a8cf91b172ae7fb47defc5bf3de6bedbf31efc8c30b5efffc8273c290afe346d57dbcdb5deec4408b5877911c5324dd089c2db9ed983134e5e9693ec3adcd36bbb5377ffda93d7de386e6e6bbf39e66c0e2c11a44b454171b7e0183335146b29fa93cca464d6e648fb22c40fec5220088d7bacdc8c5e662bd2cf0537e37657ea66d89fdcf6f046ff4aaf008843874f8be427f1102a2283bd674690e39b9eef7317154374b000eecc033980181a3969a871864306435a7d352878b164795e6981d0ca547359d1bafaac8010f497412dbd343c04019362b7180c184d950a256e02d5b219ba314371a0e1e6db3f23cb139f85105be67c3191d6d4eef3eb133c04500461c4af54fcca10df74b1a76adccd95d9b9d30685dd3e504d70e6c1a2fc9941afbb3d98b010a3388e7abe38ca368eed0c95417530380f1e3aa00488b2a29ba77ceff68a077de40bb0298f261ba5691e9a65792bda969c8237928f608b9014fa6855c6a68bafca381deba812e0ee53f6f0299e1fad610fef8f10de3b95fe329e508f1d72af94e6bd0ba92f4d5a8f5760060f3914bfd2a3168bde67ae75e6e93d97075303fbf3a355e66b9adfd3c8f8017ecb9c8575783d647cd7d3feaadd4b4f5484e5fbdc1bde0bf2a4ce07a5d58b6cb7eb959d776da6cdb3571a3813f7efab7fdcfd7773ffddb5b2d46bc2a663f1160ab0bf57a884d29699421c4eaa04e5c889d56145daf39d855f3f33d20fe8a59f300a2482514ea602380f72808270398e4920053bc1fd9bc1fc0e83d2f055fdc652b0b80d89886e7e5583e788bcd461958c50ddc99894af6d20494e686edadfe29bb58a972c8d6c5115ea8dd29143a25058742e642a32c8a2dde144aa68a65dfae013133b512e7a70f13b9c6ad9d7cb276ea99b553bfb176ea99b5537fddda3997902de93a4fbf2460ef4db272ee666c62bceebb6c4a7e0e434856b074b8e9e2b462f9351593ab5e89d5c66c5052f090ef6b0e522dcd9146d2924c1919230c2a3556382ae32571d4690f37e709b5d735f6e8cf93412c231c6f990671077a958c13ee14fbc2e4add36323d1af9f409f201a966befa4c0f1ac2936ec5dd919d7f4bd9acadfe6863c903c3d7d60ebf7e178f3faefe93e92462e4c231f54a9f4d83a69c5725987240b0d1816032b3ac9e6e00cda5909733310eed760184692f0c126ebeaa15a652783a969e0de83583946c336d8a83336567cdbb5d1e09013e83ed243ccbe4dc211977c0b79c0cdbb81a7a53510e4dbe9b8b896eb827a51c037247bfff1e361d9df7d7a231be715d23d2a71622cb8d53a0ea65948c34a4bd54569c808565f85eac05260f1582bc6326ecee5106ba15c7de5add7c586d894f1506d2670c5061ee2914142d7e1cf9d4ab9511bb1da30c9bb7698934243003f33284b85d5c9d1efb2a132b7b263a994554329a409b8603620b64429e7b99db5c0dad602e54fb95bf9aa96501ba522b1fa37a992340e4c259750ed79ec5e8c84bfac1c554812530792000d051029172ce56651787ca61e6aa1a4e3904d30cdc61ed7aa75e9d4675782abbc86e7716c0aa04c5c9ed3b8d8fcd4e590a934c0c86891677cc156b80a147d1d72836108b25aa91fb412b70e54c43c163457f4cf4483b588c6437b21aa8efbd307351bc82aa9c83e4aa692ea121bb5de6d0a919411e42e3d0c6b8944bd889d9a665e8014e0d870927505860c2966a692b0615f478ead514fd07155721c8db8806e85c55d364aacd4b347d4d4382877c0b5aaea2edb9c669dba53c60828661b54e0e520c678344a1943c1281ab8d5e3bfc6ee3d0cc0f204ea43884a6562861b060fb939fbfc8bbdfcd869b77afa3171a3b77ffaf1d37bd381ab4d358c28b1de77b9609fafdbec03c6a961e71a0aa531ef41dc770d95b8c68a7dbe4a65442cc39ab2733043da0383db622a4698fb01494285a7b950b6ce6946d770fc78eb4acd4c6f46b84728dcc87a7c70b586baa3e9d650e0f72208949a6f8aeb9bb2ba2fc67473eb124d7141999e3e606bb2c8f94e5e38dbbd7b78be82fcd5eeddf99e1f424b2409d516bb5241844f211b9612d330dd329130feea12732aa4a65599d55511dcc2621f5347a482ed172ef621d9ab6c2cf691037be4a8658573a0a90ea12b9c9104cfa5610dd50433e080e711aa6b8442056f80aecaea8f47eafe9638df02d582325ea136f5a51aed1a0a7451f23ffdf8694be63ffdf8694bda7f7a9b8df257cc6a5c1c68a4febe8062ce66c7db3ce45cd3d0cd87b3ac2280105b8bc98106b51158e2aa9fb103534805eb36ac0b040cc293085ea6ddb7dbd8bd1aecec1a7cd77178f91a35a777c35666a71cba23c081fab5866687810593e6cc223ce3209aa3740ecfb753dd2164647090042a5d1b4ad72a79fac0c039dddb405a8623b7a74add067c50d6f6c995d4c88c5172446c9b468bd955ec87527c61b8fa90ea50bb8cadca569c081d4e35d5914ad51d96ec6cafce1fe08334e004b0bfe775b25387a10074b062ed077c3c36fb2cc06c4980cef4add153fdcb5c8b89b86ead158fedf6bba4e0e95e7bb61958b2525b40bd0e273f406c3bae8193c45fe7944edbdf67dbda0f675be121bbcd351cbf55e3a0e154759251ec114d25f6da86f34ea3ba9ffb8f130199b1b53d2192855796be924c2a1295d01d4ac66aa789fbe588658a0817bccd6e69b10bb55d1153f751403c6cd291537ac93dd8faf8e680f0d396bbc2a79f7ef8fc3f7787cf6fb489f5aa6d4cb46c46bcf0dc6b2c8a06ece9d1268e4d44d9ccdb6e0eb73df9fe6289d3bdc1ff7fbab739a3825aaa2c191899fe0f30dd70d1c9879813f8e9098c74dd41b0e11f632726c5e906a6192be9c1342328b1ff3f7befbadcd8ada489be0a1ec040202fb8fd74aba75b274215a763bb5b73e6fcab59aedeac68cae56379b367f4f427f24b2c8a2c9194cab2766bf676d845425c585817241279fd92cef6f611e37ec4fd3fbf2a7a6d2b4ac6a1eac8da3adff9713c5d8bbe71aadef04beeef2aecc73cdbf7f179cfbc921b3c2ae2eaf7435e22c949656728731e3d47a01f3efeafcf779f1ffe8e69943c70bbea2e763d0d05974f81d3f5f38af1d19b3d3b2f6b87b353f3f9a7f73b35c5e666f18a0ff938b269770e92fadce44cac9213b373f905cff773fe05cf0ee75ef09f3eddfffae57d02af2a401be66b3cde47378f311d26151d43075e13f75b9d500de56052e2d790e00773f3f0c1f67a6af5ec358fe7fa60921e834b5e7cb1bb8810c913d056e770b60a6fb8f02e5e50520fe7f32c3dcce327c9e1d33f7cf9f5d7f707375a724b42016ad08dca40120390166ae2e21f30877b93395599295c15ca90e7633110f7bcff349f673fba8dadc29a689f4bd48abc0ce4bf66f62abf4d00292608b063b9a19e5a09429c581694ea1b907bc76cd7e2295fb6edd3169fde5e0eface5edef63e794ba52719d1bf16937a11918beaafa66d0e84dae22ee62d6d71dffe0ccbfe39e723a2b9be127cfb7b5990d3611fc1b33b6a92165346d19c8a0a132331076549ec75200bf927f2d2b311a67d8583875b7ff2af0b843a29ed3495ce83a749f49fb71fefefbfdfbe8d6fe035587b6413a49ba8f956b4a64e4bed49e161ed231075d3c9db80e985bc609026aa5b2879255273fc72e4f954a377ae02ed934b494d43be164e0ced8550885bd368e839c32735957263aacfe054e12dca2570adb07a4b2a124432f28788036e916fb52ab0ba60210f308daf36f1a0c879775892d2677c1067445af18c10b2df63f7ecc2d5c4eef6f4a8f9e1034c840190219acab6256aa1e7eba2a974fc75015def70b2cfd0c97af802a5fc4126ef9f4c9e23804bb37f62eabffcf4c3e73fbf51b18bd701ecd2e06fc1b8d4bea59e6aec39d5856017287185cd582bf06f6cbb027e104cf1d9d4401c0d23951b2d19d185fd5a34a7bef55d0dbe19d43cb0dd90505a0d038e249ba8ea15c5319a063702613cd946cea1d76be2b2451219320497384bcbcfc1ea1ab65faf0b12a63cf509b1d5cd035f4087f5c61194ae89bf015ab432ca5839c0feb79cd8250d533cddce6d6f9411c68e7a1509e99ef690ba2935f5a5f83c012d78624dd9ebb9615412e1de37a524da2adb999d53439908148fc078b28e2797c7538fd8e9fdba20bdfbc5d4d172a22d0c8fb659a362b728de077b89abea80711c5b123436364ff7087a6246d12d056c1e512cba919efac31d374443f54dacd5e80585d778d3b31d44cd93bce5d8f1fa0662674df6f292799274e3e1fe08ebd730132714cabd1dde72e8a93edc91a340535f507703f918fbdb5d1bb8dd25faf43ae6b7dab3ac776d9299ddf748f470c75eb7c7ee1b06958684b74da774de92e58ce21477f1232778cb2f9f7e5ade0659f195f271131438a125b2497303395d928a518cb15cce0954553c834e6ac0a7bd2d0738139a9ff8651ec5a711a5cd4a853b5e3cb7b0a45a31284a108bb3088d63a4528cb99398108d7ad11265245397ed33969c4a09a379fc652e816c3a214f6bd0ccc9f49fd3f2344d793a7c2d42d381086df44992d8e8c5be9692a7ffa551a0dc92b65052edb8aea0381cb3dd676e119f41c1224712fc3c9fa509f0b0d47641cf5edfd717f74234ea1c8e518008bf798195fb3501fea8d478f1331f8b8d9fa35110dc2912c581a714fafffce9e3ff7e6f0e4756e0eb9cb2bbdf1f9adb8fb05b8f115bef90e3c727305eef8f3a1e0d7e6ccbff506d8eaea95eb5e49e74fffe464cd95b24fa3e8194bd43f55c982510b2b34382c41b42d8227b7d0de05f63f543bf16b10b6ce83169618dee7f4c697ed2bbea4b9c17c7568f1d8ab355f5619f9a4bee8fbb7f6519f1122fd79c1ff172d7548a835cea999911bb3d0f4ea0da5f7882d4df70055443faeaf7fae44502ace25bde2fc9d341e8ecc6646bf8c492b79f9f2ef8fff1e9edc4dd57806249a1348b1696243603b68d232dd17d9f3dd4d4b6f01d069ae5dbd4039d5be4962834f20c446f993420f75ef35366e91102defb0de515617c891c153e56f6eabc197250bb869f310e87fe866fd38f56a448df50468466ced7aa27254a2cd9a712654fbca591b0cff1adf0379e4fb9efc6c923e53418fec039a711f44f558db866e11daadf6ebd446a4b6c9ac0cb47d8c4d2936cbb3bab3332fb0535521170df7c321d9bf51c3d4f123d41d2f3c809aafefcd3fff8f846a1c53a7e3be08df6d0af4c2fcf12c0aac9242d8f86bc9fbf5ba7837ff1f1e7c8da7f900e8ddc8f23dd4ddaef94797867546732b5200ff2ab68e47bb403da0155cb724d1972cb6053e4468d3348f507e4a155a4b723e67599438675481fe33eae7ff825f67770ba24d7fd3112c1574ff0755eff396a72d238454d7ee42935fde9d39fbffff1c75f3edddfffc3972ffff1de4ae7abc0f9f62dba1fe747ffc6b1b768ef2ccc0e0eee7bfa4ef79bf4d755ef399fab7adf37fc8d3705e0dddf7892bb4424ebb5f65bbf31bbeb07600b70a9af2fa26b327d75dce036122fa640ba07404da1f5068dc43b7c2e390a528766e20f7425f616f6af1c4d69093d0227b5db64ccc80e8dfe6304c7b53dc74e9d5a79f3eaec75e71709be0be5e0c51c614e18e7514c8e49f9c42238ee70692d5cbd15acc96bac64dc7f93c7bb9fa6e2f31eef1cd4767beb6167dbd07fb7a4867218c27943c44f339d5751f9b92a17abf47b58e522dbdafe3f63d467d7dbd569b896e30ea7d7db4f7ffee56d94f2df439459e5984721e694047320be9443d94511d3461990589c73046cb03538e71f485a6aa154f42ff59eb3e30a9ba81dd6de61f6b6ef7d0aaf97f035e5c1abe2c60eb3a0899a28b29161d784e910657d8248eaf7b31e2f50aa7b94c5419107a2dffc7b20c23274d868118c8bfa4188ecec417c605c0139c400204984183c80c8a00a830958eca5107b9d45111fee8cb5345efc5d005e2f22ce121633723b3aa7166dd12236d4d19b471adbd873046822db6d9bda037c69af0131619ec503a45a98a18ce4b02b389f3bd0518ad76552d8e7c48dcd658d593c053476ef5297ba0006d4e8316251aff034ef171032781c06304c4d64371ce60d377fb2e171981cf777e56598324400c78ea1c013aae6c2cd4c6910d20247f614ed66cf6143d7edacbc5796f9329bbf6a0cbbbed18bcbd956e399856c874e2fe15f7ef9f29fdf6f7fbdfafccbb27d3b14ead7e0fc968af53cc0cffcfb45eb7988f7fc6a3d97c7f55c1ed7336ae6142f7effb89ecbe17a2ec7eb19c23cd51dc15ad4ce97971c238cb1686a5e451cb1ab209b90b763c43116db0e01d59480975822eaf6e4546ce05b3ae745cba734f24b04f264aecf50cb937e2f209d9b4ffffeeed21afb0a4a292d7c452ef717c8e590cc1eee4c0142ce23e016bea6831f4a0d8200d1493ccf51d2c35d042ae6e9f2b7d75ceaae3617695a9c58f8a0056383dbe80413011736ff911707a5f635356580457058cfded5b6213a558bf7c54463b3fc12a2b17e2f209a3fbdc764d892914d7065df46070794f1c3373020db379d7426db5919ce4a3ecf3399af890bd5d54cb13c5dd598a8ee8c13656745e04234e9a03f61447b66645b9611961d04e100500deea8037e64235fd3e912cc2f269f3f9dc9293dddf10504f456d0d1afdbae4ad6853c97f8655ce66b5a3269d136acb95f85af29e5fe9bf9d0c31d002dfbb92adab75cbedec6e2ba8dc5b98d45a79eb8524e3cd8c682339e30b7b13dd185751bb37df204c37b31e99c04e93dd1eb24d1fcc3a7edf6ddd60e1c2368a394f9464c262f7485fa689c32055861a36d020e8abd8d84c2ca3aaeac03f46119d6410a32e00021deb765f4a0b5a5428b69d46b1edda8500e4d431ed13eb6844c2f1d4bf14201c33a90838b47f60ad03a1e3e50f508aada17789c11f0244134698fa524a0a3aa73ba0e64459d99d140386c6120d4546a52239e9caae762a917e2e558434d6a245301e645a60e55877ea4449080216f8fee42b5a911bce13652addb5851b5ae5ffb6d7a8ee4a84ba5d4b1d711a06448bdf42f71c821714c19c1b5f65580b047157794a802ebb1054e6d00615ab665d80bd09a0a1cbe8257400098158d05507fde1e9cba4999ad99788f374402519e1b100150f5ed16aac023f0ab5b8701f02e7cefadd5c64cfed83bcea92b62b533766f8a0a606c9b2e8d752432252335de0a10084c63d02b6ea6574a22a008a45a906d863704c998dc30045042c1bc7bbe28da554d2649594e20140a22f0cefaf80f17dee9c5bb3f7c76d5be3f9bf6483282544e3c16d30e057b640372aba2e493699ac5431f817bff66947045d453a9a19ad65f15402b625abab71d23022e405b7854902f5ec4ef2ef8ddfdc685275d525f6824ac2501a69417bc8fc201a19ea998f8593d17b46154e0b4d2c307e34cce4c9812c3e5395a503546d0e03851b51ba532106b197db1c6b95a232a10445fdd58d771ae6bfbbe7fb2da9713ab9d2874846849120a2464ec13570d7ed56bdca4d7e42bc4979708d5fc9a25727e759c5e185fbefcc7ddc75fdec6e1f31adfb8d490a78d7bd6725b5bda775a750b371c012bc626e6d1d9f335582a1813f7a4b24555f78ec2eea1eb6dd18fb6cf3962448d75c3ad2e36896a931338d52e0199e7a3defa1097defe7c956766601e3d3d0b7ff9bcfdf1ad60a25ec1a2888d5bf4735a829ecc773ba98d9e13161fee48f385a2f7df64b0381dd48a7a773d8cfaa6d7b04be4b77d8a5643d7df65b0d3f7f970d7ea5b4f05751b567752aff32e4a3da97c8e546e116584fc56982fd650c18d485bf0330a1041c3f0aa39aaf95ae5a449e243331547ab5c7bd9dbf67262869d8353b9d571d38df76ca30d751e0ce260359f6104f3e8494670f571fbe9a71f3ffef256c93bafe10580fc39abf5fd0e3ce2e18e72ffbd48ed1c898f1af29b5ec0a33cdefc126ffb1000cf7ce379885c0fddd52f4e24253e9d486ac7f8e524587843fccda7e8d96455ed41b4de5235b165c7c30466a4e7a7164ccaa81bd1bc38e7aa11bfc6b3e160c7ace0342339e87091975c6d3e2def2fa02767c0041e4c1ac381d5e429a1715b49cd0ffb5c98a4fcdb4fde8b96fb2af8c3b5fb0392a429733e4602155efcc01a4481a3c764f954fe8c400cb93e1437638da0151bd288e5f048a80f77b170ea3a22e79c6ab9a1d153570e9a351572ab7d2e4153ad6eb5cf48f79559cb8d4c35e9dbd84aca83ecabbaa9dfbae3d4387be354eb3c4fdc32a74680812e08c89d7dabdbe9b2f8893013b494ebd8aa26ca0a8dab7a3e5e6e0ceb0d757a6600c26dfab550029efae27df7cf27753dcfaee6a7bd60d580e82faf1b74b9b8723e7cfee92f6f931df92a995c83703fbd07f349600ace27d919322d9eb88d8851e0472353fd833d3f4b68a091cb84862e1709ed5fb6ef8fce50886f9ca1924d6c75d74e59e13708d238459badda59df42b7adda5927295a4f1140ab9b765201b8833da7ff216e3c4fcf468a97c9d97a5ca4e67ffd7cf7e9fd913379c5254d6d1ba905426d3c6c34710da4b0dff30d03a7b1a5b145dda2601f67fada48718e74c2896e67c6e38f735d7d9cd32eb1fd5d84c7614ef7f4e73ae996bde1e28501f471bc092cd55660290423b50760381f4b427fac96d3ab05a47e79b9a0cbc5f5f2de96ca09d9fc650ae05732f98b4f5a43995751bc3c91c4bf8ec89f72f89358e647fa7b02dfb5cae04bc434474cf3d762b893c54a00e125247079f6cf4cfc2f9f7ef5ba016f1626f72a0913de8cdc37345aea8bbbf167053b09fb68b4387a1a6174cf5ddbb347f606c2afbd4ff43e6dc23318cb9a81448a86739cdfb43def83d7bfe237471472921774132ce6641b19c47a481c01bf86ba1358355ec72b8e66fb1cbd1c757a8e6cde2c44ee1564c38d03959668e764b3069ec90c397d0c3ceb4940174f364346b4481adbc72e0d109f6d0d419335044dff6e88e67ca0dc579d9e239ab70b917b0db34125764de316b4b38f38931924bd8f38eb490228e22bf1c6f3d34d5a7bec626c06453367ec99acb1677f3f5473213eeeeb5ecfd1cd1b45c6bd4698677659f61a7bd541a459a248721069b6df7d0e0466f6866f508f7b987199e6e4b2929d86bfabede95c60dc5197d3d4b2f9f8cbaffff046a2ec2b422851f001451b50c4be22190a1924331405f91bfd16e9f1905a15fff647f0b141e8da827310e4d6c3da0963ec58727233898675e0c78f873b14b5c9cfdd83e6d7dc038a3f5cb887519fbd03cefaaa3b10bd74071f74d4c78c4207ecd08392b891aa238f509da5da113de7598da86271b254bbd6d3a57367a6dbd38b3cdc45e9cdb840bffc3e76b1615a7febfb681789e2c28a9c8be9cc629c47cfacc34fcb7f78fcea7b5b8afbe49b9445d698e5d97e440638070d70800d30388dda8e127266783382aa6680b3165a439cc3ccb8108e8f07f6e1f3fb33d7541e2db426f384c7c38f07d6b3ef6cc1725604ca716ddbe93489d39171e46eb16da716fb43ea0c894db9f61ba692446b902ca98eb68d65a43618a5cf5a7bc91863eb171c61fa6c8e7c43e81ce69976c5e978d98e9c5aa7302815a0b73c3a5dbc7398674e3f4fdf52e354fa88d4c89e1a9e1dc5fdc18624eaf75753aeab17ea228def09f51c99ef3b9ca7f4372ca0f84afb891c7818d70c6d78188fc4886f7130ee458993f16dfb446d29b09b18932ba9578dac941aeb0dd9546b0b5229697fce83381d884e257152c92507e2f8cd0e44a7f8e0148feace5218b0bd4c2f18e0bcffb086d9d34ed343ea7f8e30cf167c3cee709a30df37f77d5fa98f17e6e1126fb8c016b69f7ffe9f5fde0ab5e19501ad553711cb588a09f6875809f7c76009df6e123d82517f9149f48309a59a4f46d3ddc7d9de07dec519861767bffd81873b520d4a4f6ca7a76dadd45daf5935985837ca3ba927b19fea191c273b67557156c5e7122dad4471869cd6c36728eacb1b85cffced2de7bb4a261c674dba8d5dd340013c64dc4777548d58d2c0f748ed16895c270a69f029078fed0c6d5b8171d0535d0ab02946a88e44a081672de91b4125685164e88f501cbad7a47080e0035fed22b97c391b3b6287ce91c94fef8eeba318e0b5d77b77a962a20c427c4024fda3f1e2c4512f9e7a5a5299a0484f25959dfbfbcec931e7e3f43f48e5a0554f044a95fc55a4bef28e119970f2e69875a7fc754c1510b8ae8fc6c2e84fd20024f7c35f42dd1dfdf29c63c828e12cf9fc746edffa72ffe9c7ab8f3f1bedbcc382d17a795b7aac07f2d23a3b173d7522dfb07b64fd7a2bd83142538e3d7977918912391a37d9e6669cc5185caa719a8b8b182baa2811658a3a9290d08cd56b928d96241003599c8cfd412d02d07460fb17389500c494503cd4c0fe468d2972bc0fa04f2b80166d18cda947e138d42b9a0db482102cdbd042bc6ad960a045222bd64be437b0550a23711a5b1a76a8a5f6704723270df9b9c71cbfd763de28e7c09c8150f9d77aca8b2bf068319d5d8c47bd4eafcb2f77779f7efaf5ade2f15f59683baf85af3d41ca1b55e7720444d711ead666d45d37aed992cd5bdf8b5ac1c1b76c5e6005b737ae37924db0ab1bdb404ee17ddd7af9e027c2ecc31da106a143f83e02f5a2726fef5bb7918d546f38f7a0dc771185b51e91801f817cfd1a130938aec63dd4ee5e91801f3182edc12fd1c57e32cf50c4fef8255af8c72fbfbe4d74d36b2a78aa2247d3cb62ee31250f20259f204a1e004a3ee249de21a1f9bd0c334bad5f118157c0d387d804d3564c3241a14fc02a0d542a00c609d72457d283e662b41c548c09d91e64ade241280dde1d8031d9d85c7f00c6932346dbd75269ee6e39328a82d830516d70284e6a34cc00c7b2a588b290da179352d571c2e210a06fd5c8d9446f54e0e4e00f0550d3eaa297bda3623c5313c5d6dd884c6ed7f3950016ec352ed553a280b73520f8c402b7d508cd045d6395845a9965c57dd29c780b085aeeee89afb6e9f6ab3a520b825aacc8ee41f046f7971b7b4f1c860053cac4fb6edff7b6621b25a404a3e0fd408e563525003f3cbffe6c015d5c80d6e1d20a7c6fabef0f32fd5b24d38b247a893cdf6877780562a8f1d95e132f285d02bc7055d3cdf13d3a026f7a8e0d1ab2c28bdeaacd6869695c49ed49505b2ef098dcdb5ea3e0c5d324f92caeb303addb0db42534bb42b02b78395ec909352424144d253af6210c0549424d46efc00928c0a3e4e2e8934656b687181de17be29d8eea311e8c05c711e58601dce965945b1093803bcaab8c2bce36ba6620cb74a30e5b1252f1bd3050440324551387caf00231575aece614c59f758cb9fe4a112cc0e11128f6628bab3fb68d398ca6ddb749d91db60fa3f58822edb08e474655c6364b493fdc451926f30e4e72430c74845c162f950d18178c576d2cac58b77978584349266bb7d001ddbea5622f9712ddb4e675acafaada7b51d4c0ed10d69b35305db1da5f0d8b088540b2a31f54638bbe6e0089d0b08888e3fc6189e4510f2226f74745d1135450ea51113981a01c29bcb5c76d816d5aedee4cf4a78561fa3159d4b945e88e64699c34160015460f719659dd663bb11669022e064dd56ec3663a0a4f454707be0a3cb379824f5124211b6ba47625d28308f282c9140ae3c9d6f2f721364d0a7c7c80e05f691b60538045e21e18a48696abbedd631e0117511d47f32256c3ca2b2e7299b3bbe0cf6f55b6ed1568a9a22d0d455ded6e92bd60d32ba9cb47a134ec7dfb975d27a3d25a430df2b68db5a4d102a9265120878109d412462a0adc510a8caa4dd5f608f4f3934e8deda3fa15b6e815e7d00d202235d51a6d64609692ed6d8c8f87bbd85a921a487b42191b769021401071aa63b6b52034c18f1f7d7aaf3c7b1c1c81523b667b9e1f0ec60f07bd6c22acc7c31ba1e9efedbedc0f2069f91893964f80d2f2112a2dbfd497e3047b96d47f3e59a40ec77e7e2350e0d7c0f6481a4ac1e84a691b0ba5de797e7def862fa742d19e884c4b27146cfa9d2db0cc7ac902dbcfd9676fc7b05bfd7870abc66f7319d11fede103d7fa52436cd34b86d8514fd861893b0cb19d9f33c452ae3bb057d4832a5e24aab88b2ab06e7adf717e327e8d8e40a7b77607a90a2f94cab0372189a8d92f4113ab044aadb4adf60421005f07b780a3def3962e02cc19a19e23ef9f4fc3e5da815fde2368e55b06eaecfd4dcf05dcd089809bf09b837c1eee28b7248522654ab9ea1247aaa461a4466cbcda84394a322abc57b996f5cfce4991a3a5396987d0ac5cf67f9a1e5550c6a38d446586311460736926a863adf2feef52f07039f49e9a745b3595c368a90c40e0b5363e12a551e1d3b2af9514876d4b2509f3d6044a2ac0862212c050abc950a3449c048b58679394748cc0693099303a8a4934ad02499fd463343a7c74b9af7fd92ab00dc676c2013b5e1259ffe839e50e8b2da5d287dd7eef3d74497570681d211cf32fdbc94a335aaca9ab4410118ad135aea684309bb0c626c0f6d2804b386a54f4a2963adb02142fcb534b30b5a5e1e5d866e95fbeea096fdea44aba6cfe9b2beefc4afde57c3cf42f9f7efcfcebfbac0781c43ebe5694bd7d694d0828d31b936be1aaabd8275cc82ede3a531b02471e3e14534b7ade686da93ff1c0a8dfce3e8cf9d161f37087334c27b8b6319e7a798c7be3be76d4f2133f0ec21644cee24c35fe16789a76cad5bce29f9cc155963349cc67a0744f63125d20d33da59da1d3fdf19384fa8f9f1f1efea8a4f0c24a0a6bd182864ca31e1bfc0cddf346b269dc72634a9f985eb84555cf4b7de3fcddd34dd030f537df1042cf643a043b3e9673bdf72337d8af1cb6b727c1f5c3fe26d05ace750ef377ff0d0d0cbedd5f3fec3f161b6d4db2f2463705985153320e4e7cf6666f84dff9a39dec1bcecce0fa103d1c4e769b5d616c52efcaae9cb1f11b778e1d8770dd1f79de8e1d675fb9cbcef3022ce6d36c00874e73802fbfbedf20c452ff4b62b54db17a1b99d6ab6d6aa22e30a29ac0d451b53ff47cef7f04fce1ffc7fd4f71ff47f43fce17fa3f9cd533e4b01e3e4912ffedc7cf6fa467fc76b94551505254d3d87a399312e13e6891dc8fd04249ed56abfe5e2804dc2495651657c9a9858edd1ab267dbba7f72f1aba71265e60e164451c8b5a9e3853752f8564a4ec5ae9108964e9a1d4dbb2d15a0f794fa0d63eb808707b1d41a28e39ed9847293a50a8a5b990652f1b1a58c8e372aec7c9016b6bec8782b636d751388f256e1d791c4e8141e3f6a0e269e79de4dcd0076d01bcd1c880a1c32761362778942e02696fb87fd75b33fe5e1aeaa71ca614fa028e9833aa43add40a81e8a86a61ef28d4a0d9db7c5c44b7c484e23dac7a25111128253fc8c7181de8d644f93ba1d394de53fed3e6dbffcfce9fffef9d3bbab3da34353e93550d57d2cfd68a6ba75019b692cc6d14c87939218ba6a370dea4aa425160ad2130d0a3c46522f09506ac80b662417301fe0659918442d529624524ce5ec0535c2b59a1c93b4c0109e5ba05c12cd2b520976c1a2e37bed29670df32bcfff8ca4b59783f5f8c4dcb3467b9d303ad9d9258f63ab534b4a1aa5a631e40131665abe0ab47b6a83e2ac4914b5295227499daa2d5546b500aec81528a60d76585e3b291eac0d89bda55234907092aa28eec943ae38e7d44a31fdb5f7c07674e036e12ded0b9b426b42035e650b4249ea084d9252d092c4346149a5099c4e4a81a8a692250c493a645eb006bba050fd58d21880159edabdddb82217436eb5c01544690c8ad45b6a48b661b834a88c20492bb2749acd1c0c6254d3e870108d5650b0ab4b2c2371d3a02d95d162cb69f0802e5ee54aa43aa954b6bea029a321cd4e559a9daeb4c03348897b8bd213cb9eae00d55f2351e23662b76d31aadd0eacea4ae2976c11972cb12406cbe82dda932324b733fb13447f822d19e59bf8950af74513b51e4bcaf662c9d6422ca92b00055a1b76aacd7a4f956cda52ce603aa5567bea2c05216508752b8d30cda412846d9d904f746ea689bab7bb30a61a455c4b49acd53857ef3ed371ce34d9d4681ca908ac44c39fb834bf9ad80397da6db618a596dd0f503399a6abd5efbe07bbfb369f38e0892f45951ef2b6336cf1a0c745f6f8ee58e3616ce92944c6c7e8d26fe1389710191d453ca79ecb82344e669b022e23daae557bd09aaaf16031b6ddb07215394edd96b724d6164b4e9cc101728373540970f32d53b445987b9256400f6dd892d63266b7e8ddae6c5c53368ca757d0ab7209046444f7cf16b6bbb4a7d9a817b5b7d579cba4c6a5b0ef1b87b39b877951f33089a0570e94154eb1cea96ab557073b5bc352b71d5ed4ce20db9690c4c5f0c59712946d0bc1aed3b3f16d54ce1cc3fb1541fd3b6d41872d54e30cad8b5d270bc7aa6efacce813edea456e3d45ed05147e99ba4f53f6fffef44e6bb218ffa5b51acbf708525c7d945f9761393a5a83d2bef48a8e8f87c74ed45c393ed7affaf0c1c4cf3602694ddab646caf657363676a53ce0e81c948689163919b1a9a29a07a97e24a47386f9e51bb611b5ed56da1eee6c500e6c6a54bb3152b7bf8ca8ea15534eb580cfe611d8cb9d48ed185b6aff48640c5dd6e7b151ed79aa575bb1853b50f62007eac3c628b6abb5645ba9ea47ee30d8cf2f970c54617adf9af0a381472a1f454c85f04fbf523149ba9544148cf797f999d7c71b89c655b1653d82c9446520806a88f124bbb5aa8b892bb0f7536a141afc05151b7fa7adbd140a6262c5423d0d9379c504374112baed4e8ca29cc6828cadc5f9a0110fda6329d11f34ae0faa2dcc2f971554532ed15ef4d8227e060530fd696bf04f7f1ce31c23d8e39e7adae04feb7e5c69b8711a2de51915c36e6ef3a70d78dad8522ec11f38fa03473cb1bd13ee576222470f32bcbce8b0cb7b322c32542fadfdb980cfacfd79f4dcda7f6f9a2df73e97504644847ff9a40825d600a95cfdc3a7b5d9cf0cf36559a55d6f7fd5333282edf47b280d8eb8dba0d0c23c862b3fdc71d754e058d2ab629bc32341dbdd881764eea1ea0fa5a5da71d4883cc1f24149e9e379a229a661ec89a6dafee7d1851dc473cf9293b02d115cc66e25526b6706f575f780d706c1f3684d8ce3357135ba312caa0dbc41bc320b9e9bf8fe14bbb8d286dab25a100457ab4bb97eb1cb3479961c4f52e23f7dde7e7aab448157649eda93b2f61df79370bff91c94703fe9cd3848c93c7498588ff6d56807207febb55f96dfb95efa0840705607e83dd16f300969bf9ab5fef705ff43de982a49575c61bb08dc1a82d1b87bf9a21ba988d9edcb083d0dfcb646207a35e5e1b54562cfb7c47dd36aa21b1839298d07a4fc6ad55b6af59a6158724fd75132ed2dee7aa7543797931726759d26c979f03c59feb26c3eefde8651be823409c678aa7927bc11de2177a06a1c751385fdc787bb88cdd7ffba1dd57a04e1c31ec65ba0abd18d4fde15e632606623a29b39514cb44f609b0585caac27848282df94556d0afa92bdfa3302150b0235a3a8a72d18096c8d20827d5c73a97b82b8063d6eda486d47d51e4afb35e7bea3ac1eeb2207a9d8817543591f3ed04004672da92d9112c5926aac7120472b756b009286ec35ceb78350cc66db80a91a1ca41714dd47122d64c659b44d60132dcd8d75a6caa5122ba3663722b88935e9e2de991c8567f4b7b7b8dd9322b238ccbff11dc84b7c25dbd9ecf514fb9e7f3fdc09471a3dd1c14c3e43fe4ec51796807738bf0cfef2e3e72fef6d1180cb28d92421a0ac0b02cafceb28a00c548c80b2b385b1f684fc345cac9f4dc935627e26224cc42f4ddc8d966f3ddcede6e067d74c3de8ca56f49e984f056e5146929a298477a41a5b4d195164a6390c42bd5086a5242ba0dcb403f4b1971b82d9ca7ea99b3871f0678d87c31210bb58ea5a1ae2b0f603d0c3fbd664212a303d6a5b5a2a35da47f04b454e9cd73ffcba3b139046e1873b25d3faa3b644b28c940bc59178b43052ae08ea1698a2600613d8eb49f1d50a035d47601360ad414c892fe8d909112ea30714f4b34fc6a69ad4447e28d4d9146b54be1b626aa0f46a2399964d39893d900dd8e680cf2d275b0d1716931d3ebb94aebefcf8feb61345497d1d89b6a8f3878afdf03d8fb06f2d627b055c113d7507f3d2b53f35636c3dd50531e0d675447174528dd6afcc940504ae34d3ebf13df62062dbc71e64cc1689b21d1996159f6bae658f04c4303be7f1ba92049e27494657149dd19a48cf3972a1c4ff07ed71478ce0e4aec61909bda40e064bc86328819218498f506f002f923b601e91c8d1ec68b0d3aa8d38b6482a6809d54682f519a9a2af1d8df5863507c6c3a0b62b2e237160fbb42e0f776c7b53ab696cd3cc3f46a0c088fb96cd760d708021a9d561dcd4fbdbec8575f68c24202f8ac34d6a5290440449204d01d3dbe2d823c73959c595ac0a901f6df6ed82738cf87895382f13c553437cabbd1448b02ed9f3cbdd8e9e5dedffed7f2d9fdea680ea6b374e6c9bef6245602f3cdc200fd6c6d9cdf1c49ad86f8c4c1c59b3ed7209805d462ddd194804684bb555d24d134109610e0ae90b5eed06ece534a05d474ff6f744edeac406e90d99571cab2fb76a8d6b62c4c722ead5b66e3b6284b7d59a24b41ee7b7a37ef74048b60ab3d7861da417467c7037acc3820c2f762c80c012d56b9b3a3f25059eab099e266bc243bd3e0592b91ce88543f53756ad71cd352fc3eb1b1498513398a85770e0bc60a1c3052db16494004c121bf0ea62870c4d1d3b67bc1838ba5f01e7570f0e9f5d3effd7ddc73fbfbbddf26f7df9c844f8d45b600eb0f14bfb588eca6fc47ddd0f47a2e66d94619c759cef89201fde557db8435c503e303a1c449cdc1fbd96e377f115e8c965da03f99ca73d1c3e4b7bfff2e3bfff41797f65c65d32924051ef0580d3c4515bf4a03fe4159688a46e30460403329491c95b8d2d7bb9859c286a9e56b852a3ce4c35cf1b65934f9561291bd82080809d344837812654e44ac2c5820890114a8d524c5c423e2a78a6446d48ac8b858c4532c40b2a26f9c0fccc7815305dc3f9144d1051c0e4d8cbaeb38e03526e878dc841295043bc847d7399c19b089cf46459e9a90119b9dbab6ea92f05199a9e245ae0d430d6ad514aa4e15cdcfe0e524c86f2d6c35d2713f6464e7569d8746a6a5e5b1c09be1e9fa4be15aa3dabfd82a8ad8ca45bcf48959aea32d6ba15d4a3e0362092b5d0fd7dcc0764b837ec794d8b8cc81b066e059edef6e282823a0301b462f757ee63091589cf11e1f2a0c154edfe068ca2c8896e177181e76a3ecf08fee5c77f3fcf06befce7a75f7efef2f98dd013fee00667b941e358f32d9fae755c47e2d5c756a16b34ffaed5c3948db02a02878d690c5b48d6bad57cba7a9f9c4c7fb08d2a95d85bd20d0be2bd71dfc3c5b39e08283dd667a4ee725b4f65cd4ff768bf1a471ab1b98edc36c67dc6ae3c67b47b24bc0b84bbef73967e6f3ffff8e90fd3dd3b33ddb109e9bd01594db2b8e09d4b92a6b75cbb2d314a596bec6914db23fcff6bca79998710cb1dd6e381f757f7a33810702070b68b2feb7981735c0f47ce3b70d7a6dbc2764fc1be9a5e71afa96585535a4c57421b99cf68b69246afb7c66c32a1fc88262182b29487bd6ba111d94e46c89ad0736a3628f53cade3f05932ffef5fde2174eddf3883666043003eab78191113b834a262a003a2a66acf3fd33f86b15526c44215180d134768ba35425f9098badd761293d66043b4610821e226fdc1628cf1adb1816370017c082e6e02605f2f4f2ea10c93dfc2005201a48b2ca9218cda5e3d47b65b29900ff1ced85f98637ad828639c751a519d293b0125f78b23f490ebe53df489c767bb1465886540fe930a435c01b22aec5061bde70d97c4cbc48784e09690b3695726cfa36a9474819709d1f0c53630c1b2dbcec8775956cb560d50dfe17c6af80dd795c3eb56bfaea676eebac124b5d8699a1a22995469a2a63fc98870223afac88838cb5a9b68a2f0338bded6edf9356f47cf2ef93f96fb5f75b95f9ec7f373787afeb61fdf1d54ab484dd434f4bc441d89902f3524492e80d8ab940639ca9eedda14722c9ef35d939af4925333ee5612d5fe517b9aa9006b26002752e0e9346e574310a84a2395564c5a45604e2ac3c82f712614076749ac08f54690524e2a2ecb7851975661b22f0d8ca532b0cd2895cab73aaaa3480a6029ab38d063a0baa1baf8effbc22fb2567ee99254e5ca9855af23c828b6df9b42ce65606dd018a973b5f6b2bea4e02f290887f992ac597ad2067139531a8d2373aad48c2253d11e65a4d1e9aa64495d6b1053b92b6102a570ca65b6a5a45ecaed2869485b72144538b094c415d868adf6586b1a59914e46ed4af34834c4b478c92308e2a928f41c1ee7d8d32644ea02bf6087a2aa840a221d76500740aa64cd62f26a99a04839f35704a192a41a418c9aa48d30926689c40def8af596b82fb88c46bf4cf0cb00e2d12f63cdf532615ee6ab576af3004ab0cbc0e786e408bf4c14deb15e0accb24577669d6e3f9e8671fda7ed5fee379fde46b2fa1b4c8b1e350a31d21af931a9f120a5f14942e3413ae36332e35db655723a22ebfe2833efb80ada7150d7c35d4652ff3e7aeaa0fec0fd119b0f33b2ea49c502942900b4190a8ddb631ddfeafdf133860bcff870677dce059afdf51f0b506caad7d41583f17eb0fe38583fd80ab92fde6d8edb7ddcfb384f99035f5a7f584ce796200e9e5e855fb63f7efae5edb2f35e8ba1c1acd7daf32eee31ea8fcdf4d7dc78eb39dbbf01093de7c5d1f28055067040c55472aadb364ce434ee8a10e111058922113dac0551e714fe398926dace141aaea79038a838525f9f915b70602b992827896fb4072994f4e1ce0363f9baf1b6c13ccdfdbaf04599693fa567c8617ffc0245bc3709ca7654089c36dd05d1eef85c5088d124538d23894f9da0f9fb672fb57a217b891b5f7b8ad3863427e22d6e30f86d2230c2ee32d8ad05dc65f0bbac80eb7a76422f4de69989fce9d7effff3d3fd97bb4f375ffefce59ffeb27da37081317efbb4dadb09f9bab4a4575cd234c179c37edcc14874657381dab3760464d412b4a90d8e2fe2d0b9f66bf43ecdd16df5b678bc3dfbb93e4c0ef3c20f7726688f20aca6ee20024881f98bfcc9d08d050c9861c9c44a47478c40f8454b1da7a2766b237ea88a2bcfbb42a8b80c278996d45cc3452bef2297bc44986ee1771af62d535c20249923b933d887b7186869d35943617fd4639c38c239246e6570757ac7b408dc4d1c2ae047e1580198ac2405d295d769c1fd13508fe1082b48f45f55f6a0eef7127b1f3baa198c4918010cead692b66b39d175e7b2c858515b3554af066c5fd77550aa3bca259902a1c5ab17b4a035a9b710b39dc45619c3e36323d9075a1b725ca3e1c84888b6e064aaa87d3ddcd198fcd376dd3aa325ea98eab14e93af0682369dfd3bce63fe0df968d4444bec04937d4721067fa4f9ddd9519c30d67c587c3fdc49034cadccb8dce2d925d3d585967dec2291e91b158e3bf80a399538460212a6ee4804752a15c618db3e9452f756bee56c5b8ee65081fc6cf759112cbcb3b34c618805616e18bf2206c49af62605357bcae2b8bfb81de0bea285346a935f80accaa806ae0ea3d21d217778ab96d46fd9f4a46bd2de81b6622f4b6a6ab138f28a7d6da8a4e25660bb634a6277daa362d2c4dedc4e5a2a1b2c3ff1841a01f1796d030c022fe90e99f00bd25d60f802faa8046e4ec812561ec05e4943263e434df2f0818c4711cb02406c6489c271134b8e842868d3bf1ac6b3653d5046a9f0be0907500e80ee36d51caa74682b64f69610fa55d2b8e69cebd694aa92c64226ad43d84757b8291b3bd28203e14ea4dd9abacf3fae64927186ebb28d44db82a21f8ac7a1645a33c30696259587bb322849ec40f92d30aeb59ac481528d6e38360e4ab16bc85b7bf50270818126928cc6da39a7e19d13c78eb782cd96e3e39008c3d0a0b6288bcd4285ddaea671c36c8fadbc55947742b806c2fdc4049f32523506d442438511f4c2ba29204c3ca02e6e229ce0d635b21149cd484940546083a7bca02c3942ab049e79f8af511765b69b8bdd88917772f0262173d24429a731622f04eb80d6d6c642c8c1d3e18b7dafab1f8b80dced8ef7001ad3a8c369d0f4fa014f1d103d4c77ef1b52e368e4be43c68382f70e8ffc1a0f1fb834238d96da32fcce35103846ed60d01d7ba4757bb81382cd57117fe6241fdddf9e8d85d4545d5845702cb530670c4acf64a8f35e0465b78ca81c909add8fae93754722ffe6e252ea801916e99a76142dcaf69275860048b4c513464fd55b73493687cb1ea103e67b78f8d98a2b6de75687831ede825f1f9256f308b95a3d0e78aee90c17a887b0a1052a01e718581c0a69cbc3dc0486d1a0e228e76a4f4b4811458c033ddc71b5d507feffccc681623bbe71d44b1b47c7c6f1f26d435b85ae73cbb6112fc0f40708a49abcd051200913bc2399fb8244f04fe3a4deca8f27db6fc548496da6d69309db4afd8ddb0a9421758ed21d2ebed93ca3352bd178dc208a2b1b911af94f8f36e23eec49f05bb7958d966f2f019bbf6ddcde6a9cda8e8c3f2cee6210f781acfbd470c212f786030d7d36f0f1f00122299bb8b1e712580e934bb43dc7d8738986b27a4966f3904bf4472e213453751eb9046144e313b4aeb497710a448bf6fd5d4d5e31523fe015f435afb88bd433dc23692036a681a781db54bf5190e826a27151a978a21d9cd3309e743cad6efcf2e53f7f7a3343c2dfa0452ffa751680eeb4e33a3bf7c7057ac285023d0ede8c5cc65756088a7d561098d25cefbe6d88894a3d54930ad8f4851ec64cdc840b10985276d024b332927a5d890629a024b9578594d3f0131073179a0b1815b23d0e19748db01718f0516f3be2a27679b42ed1f34a7e67a8783d7c9e76ffa0db17d26d3715b52e4e6ec724757f4c5397a8d8812cabfe4e74cb7d41b59a90630352a4a3227961522ffb61f4d4dc8820413c5db87b6c2442f841b4f367a47150451c23ca50b8ac55ebd4e3ee0b64d2f5376c484b8798839d0cfeefe15710d79ed9ef823ce6b9229bc88e5f09d7208cc280a89c2359311d922f5a858c662f10fb6942ffcbaffff3cbdb98815e41e9da31116d24bd52db024d6244e477aa4eca89425f4c1235810baa978915ad7a3a0f5f99c6122a645dd443cc33d515b0c4a922843628c43f52db520bde71338d2aebe20343a74379da563dc09c03b9d186c1a0b0d7a3d41195615d3d0bcc36e1126800b0b03052223442e0ac26d39ade61f2309be683ac10586f20ecea123d72b52182b792c33d375b848c648ee179200009eab3562eea62e4681ab86e3d170455a05c8e02dc0f47ada9dc0e4e650b31d04e5a64e099809e15a423a400e11b0f1fa86b1a46cc7ac3c2c14edc35497d8bd1ec0dc25c532323469a60b358184b116fd4a4aad23d2ca7c7867c7b9211a48d546ebac9e6d204c5733c36d9636f5d2fc4b3d9ceb09511edbde05d0564d0d8353cea526dc7a8941a822739d4b69d72557711bf0239fd9a7bdb42b4b4bfd003f0d90b025b4c7e2d5044a0e5e06d5ff46d62cd9c5969387672a9fdf3a7bbf7e65299b587e1469cc0bf3697a1d89c03d6aa2e1155773c740a5ccb438e78cbad06d19cfaa2a97b4e90ac0d28a8d6237a0f416a06a1e2d248dda51bbed1e682805ea917020b5abb9b63edce107a6e4a49df422519756342ada2a0478ba36e4af5f8f0cc1072474e0dc69130ea350d184a6a1c158e45530b32cef0f3ad4ff591bd8b028a6453c89e3e03fd3cf4eeb8d20f7794a1696e6c59d71b409340cb21d48bb32e1f009f54785b514aab661f6afe7a81a0fef9d3dd696afae74f77a749e997cf771f97b7894afa4340b928a084fc7b0c13a8bac7ef544ed24e4e940208da3734f86470d6cea4fd33859aa976ac1b3e59b97517fb46f38ed5760fcd9ba87917fba962aeace85535a05bdf45d68df6c3538f7e7b7147cce4892ab476cbde2fefe08867f5db63ddf0c9c2b2977ca073c59c59667ef0dc52fbe9ad00835eb3d4b22d0fd316ddaed7dd13e55ba87ba24a8dae4035642a636f5d0ff4486cd2138ab4a9db631da60ee8a86e70db9f61abcdf5ba1690d5bc5ec30ea018209c69ece2af0f062dd416cb3bbdbd77cbace00e8b645bc7e2ae4b38583c030a864ac0c348a2fbd84c5482cdd44f1213694c5516afbca7012a77f3b76fcacc08da5cee94002d49d0b887a8151dcfda7e8b3d2f1e926babb2d93ce9344b94249717da4f672190e6c1b30bed1f3e7dbcfbe13f3f7d7c77cb4dd5784d5e90f086b22d12e16342aba0a837d2034d2e69c558704d8c12edc0a7285366f786476c39d60e793e21bc40e22d1476cf139347dcbfd47025b49c7435e7a590bb2d9fce5df0b0f5b1ce5d799cbbdf4853fd1c4d75a328f290ef038a7ab82338baa9f62480f330f1dd462ea1a086a860ddeb042802121dd227edfbde9489e676ce5231f812a1a47baa39ecb033e94f004561bf694c05ea91295ef0fcb465a6d823fc956d7744417bec93f51e6fb7b9b68eb9a85b2fa4bf783e7b453ebb226e1d17f7e529767763896c47dceb0ff8e001a445b402ecf7a87a8ad44372c3420fd50ddce0184f56ff0f28750a3c7a07b6fe8a7fac9ef4664a1ff9985e56714eb8c30d30dcf36d061700485a031224d874d2957d856f667e266434a46a02a513bcbdb5c40f1f503ca58fa4c6f0c501432fbeda365f6d5b5f6df82fa7917e8a469e61757b8e759ee1edbb5c647bef8de3fd0d6f8f6759d9dc1ee9d5dbe31d2c3123360694d19bf1a7bfea225ad59fbf99e7797e655f5ed467d7f3f5a78fbfbc5185f1d7d4fe2d30326714637e9b95f37ac1f22e024c3daa03d418a57140229e1bec4bac5bbb7eac238da5a08a0bf2f515c1b280e189aaae59d4286e3a1c1e4b8bfa84631b39342453532484ba74b7ac7a541dcc8a0aef7b9cf5b618e0604a6eba653ce9b66173ef891eeea8db556b49b2c419a2503d58011f365a64dec2d740d6b6d612a7778bed795182056e78bb45449306809ba1c43a1025babbc70b9e3fe0f909f75b60736b2e6b9450716b78aa0516cde2b150c3eec69f00c078ef5605babc2e7d719d5f997efcecdafce1fffbcbe79f7efdd74f1f7f799b05fa8a90669a619c001843908d18bfd3596f29678fe2ac461df0b70eb7019596104b9393dc2338c1280a7fa67145b03d69737450090a280c02047859503d5f811b805453446739dc5a44d097526a570a5b43eda10862c928d8a875fd44d80b4452ce1e6b17661531a908f66c1925ff3bd2b3d8166143f62c2382d496a8e9e8a86a7a25ee83336ae661cb7096f10a343819d9110f072c657b44943bad4b8421d93ee240f8471708a9819bbb7dbcfe53f3fdc316b0c09df3702705f16fbda5ba28f0e580f838f0a0005aed5e91df038be097e850c92a0acbaa37c5c37e0bd85aecf652c9f9e540e25dec418a7b90c027e13c246818c545f3d19dd920c80681b6b65c23180eb53203434383431c8e45e7c52569d00206817b32f15b1dc3c5cb80227ac52162a1b48ec5680b59b75de75e9d6705a8ba272b77e8473871d288202ee4203abfb2bf631a5732309912a45b03b670e4ee515ba2a93b4003acabb2e2d0331eb6d250f2471663d2b048aae75b6b94c437948d8a80a35b1c3170aa370d69c2c40965fee17020677c3e3c6d0b5e01005f7ab03f967d4f9e086838636cb0857c9d878c0b6cd9a67ce45416f2846d786b1deb8f5279b81330b992683b0010c4a92ec5d11191905e67663821e5bcc4e2f9e61e96e7eb8ce01d94e841e61d7f2c8f7de156d348e4dd6db3738b18636b40cef54874c32208352b4ba4a089a6fb5a568b5709f032cbe32f6294efde8db2007cce838b8ab162a8761d606e056f9d1d07333b2610ad91593271766c1e5d70238fa9cba9fea064d36764018644e069885cf3ada920911be3d0c4eef29d092ca3d86e8c6a675d2ea6757fc5d1cfef0a079d9ed91ade9bd8f64e37e9dfdd4ea96fa588a96765f4c5b8ad429c1c5e50b02049ab6c7b8e8ac391a11ed8a648f826b03dc6e2a7b8feb28d7e06d6b338cf4288ed1c30425c9cdf8468532aa96c51f743b33bc8bdb51cf405f7a1d9f9e18e11dfcda92ce571351b27f43b8feca0b5508c1c8b22d8db2ca9dc880adcd91d978cb8d063d716714fe81a65c5deca696211cdb1b76b0a25869ae924d5df02f8e53dfb1613d61fb638e145abf5b9857a7e8dfefa5682db1f4bf4bf4ae363a83ca5f90606fe3ff768d3d7c71671bc34333a10f72fa6f9791815100b6c9141b34342c1080cf417537415782b25cc087806f20b49e22d7ac6325701cd48075fe373a9db1e98b7e811001187c10ba246f6f96015e5833024a286ecb2e01fd6f9e18e0ba27219b54bdff28ab8de5bbdc08a2099f90221345e8c675817ea8565feeba59df8edd4b357140a73f58c4bfdfdd5332934d5331e3cd533aeed927a5672f50cc28ab4e1e11f0dc82cf8732fd20338d8c1721a761a4fb5c8fe00014f42ae0d603cd706c2fe29f0001e8930a57ec0da9bc48b6769500b5c27f02a33a64355288e9e9200e94e46359651aa979a2aa6b455e46e98d8d83d3c8e3ca53937d7648ae95b48380120c5f00ae55a53b9a26252ab564f148011247bfdaf92f59e6af6741b099c0b9e79386c374776ce3380ef848af036e0c30762580e596d744185731e40d3ccc805f0c1eb32dc07481df644eccbf0d851ed28464c110b9001dba7d6b95d9502a69bab317978606cb0fe8397fac8d5c761048dc27a8594aa3621ffd4f589e1a5d7fef0fcfd9778fe3eb0e6bf4b17d7339ad5659dea5fbffcf4e7bf7cfa1bd6ac10e79417e49a5557a5ab2de08ae0598d4091f5ec2ab2c3dd5bb5ec6cce5154c2a8a02f642a71715a42e62d8c503595adef0889405688d72d6e14472654c8d601857e16980526ae6d773730640e0c8385db53bfd5dc1fee6020e2926499da8deb10752a13766487f05aa4ac7aec0de296910ec5cdade4e5f767376783571c710e273b76b0dd042ce2f6441e4116908fd5a6c5de1ee26a1052c611b4df83c8ea5b07f0250c9053ca5e65e72792f592436b9e9e46d8856c7feac1f62a79b81358e93af9f6b257a62416cf9b7f9532f516aa5fda2b7f080f44786ff15b74a5765569f9f75068c3ec1b7e37edfb397675c0712e70ad835ecf30affffef9a7ff786fac8b0a07ea197268f3dc7a308b010bb42781a61e9c93500e6e61872dd66bdb0c848cf429bbface15bbaff6ee1045886042ab52c8d8daac0343c8e1d0bdca0b661953eb6524aaa70383b8111f02b1cdc4210142f14c45f594ff873b6a3596bf3114ab3f36963f3696d76f2c2fe172c69a9ee371d6e7190ef7deb8db1febe78ff5f3eaf5e32189adbe3e9dd4c39e5e3bcc4bd6f3736bf9ec3a7e8f328a70dfcb2875b890d20136320072da2be414d81fe1a06488b908e4b7ad77a40e88e0ae267b9874a21de20940106898804275b66b4ea3b994e2c52017fb30651805ad4a4d5c7c4898bff44a5000007ed3c101b151c36e37ccdb866c9c4345ba4f3dc8f7394af8799af17398f27394f3d38bdd5ad554a7315e8e9660ae586ea5f81fbe0a119654e68188035889265591ecd722228e1ae46cd12b12b61b06c8ad3b86f32ca7ed61e36ea087d9a837586db8c69e53e68552ed71a40e986db7d4771f1b8ce350b4495956ee6ccd3d83b63f4ef0e8f9f364d36a9375caf3c1fdc0f5c1c7be0f3ee1fce023ef077f4318d1e5adf3e2a6f9de16dadfb0fbe9ed3dc4d826587f97acbedf2339f032d59ea7d893d47afdf1a71f6f3e3f7c7ca37a15af01732d35d55e038f9c8af28d1add31d2233a7b5851ce644204370ed2342935bc221d69a0795dea1597446c5287830d115ba3f79d491d00e866e893fd518ddc80212a6f81c903a1e39a5417044ab100e524c848da9ab53a60a472ea0d4e31bb1842db42a91b3291b0f0c269749bf39206692a0a1fdd805a2c742385511a55a9df6acf287627b615f2587234eecb25d654db00b45306b90b69ac25716f0f1f0af7a0c2d79af30ec5f13a9b8864db00a4cb4c1aa5a59211455a1d9abc49ddc631522b808d6cbd7fdf28359130bf264ebc0992c5086f4d034f4a642f21da8546ec111c99532e90df866ad41c14999c64da7f1e0b8dd47c8b6ca975786e34379b80ae88a06bb265b50b013aa0d3d2d31808ff29456c636744fc76ad3024c9fce3babbd85501873e975429be843c4fd5ef77de6be8b16f788811c8d213d58ab293a90e099a321272481a62bf94b7a43549e981b9a446c55e5007cc4077187d0af6eae75cddeac5c5f9b8d24e2fd1c7e36717eabf7cfcf98d6076d558f66f14e21aa7d20211a7aab483f0c4c55ebca44a0cb8538eada2227897946518e116ad10fb784438af86bd7ea08f4db8adcea969bb029a461d816bd2526d432175e4082deb5f9479475c133958e32808f76608fe927b2c29d71e2ba7dc4da4ea0dea9c14b864da402dbd363454b1f58eb4bb82e0c92237262b9954347a2a757c742e3c9786c94d6cdb930a6f9839f5d14cfe1ca8b2c02d75812f953b3c40d4bdea0bc95672228456e6344aff9eb3d1b46d8efeede3dba408e554aade521b405a33894f8af121c0650c8ead2405dc9d14801dda83c3df3898bd0253138a9444902ba8d576cc518ba997bdd71ba93d355b8b55379133a5c137855219142473923cf1376444ce89b1bb66863faa3540f3c9500437e6b265e3b03d484fb90dace182404c46c72c883de86dfe1147e22eb794919b5eb08aa5a6d2c8dfd3fcc328e7166adfe9121235f572ae8ac46d6d73ec2abffbd894291168dd2e60bb908d7938fe4b866f670b60b49a240fcfdb67dd0f6f2f6ab66dfc1d76997ac91eb4671ee7590f0e9fe73c9fde0c4ce2159ca77222adc0d71850e3c5f410a65475604fab144553a66a1c276704618bd26d535f4c3d2375bc13c5a6b14922454bb3a966d97f4161e651e71f4d6f80d55f3be403db945b4fbd5c19032aad8762caa387a516183bbc1a67f660a8dc434f4d1c86584c952aa696654da34ab09b74acd65eb6a5a4668c55350d6e0b02c80bea598e022cc431c0087b460cb86dd9831353df164dbd08907ac6b8a26c0bb0808599cc81bec8422093685a012836e7925ae645726a3a81b14b713473855dac1480a28cb6752613896c818f8fd5ee81c2fc72de45a931c21d39cb8deecd36babf79ae125b4ba2c0a1ed456de3cfac406284b8246ccb8692f61e13d91690466b3195cc4193b26ce3caed4cc3cca82c3f9abde0d2d978cb30c9b9b40a61bef3fceb7a3ef6126bd2ee35164dc28c922a438ded19e1153a00656bf7365026bb94163b688453a581f9af70656598ecb4f72dd754b50190a9ea475fe8939da74e886c26194048ca2352ad260e5e494bccd5e66fd826a7c95885822d0c20cb53ae49fad896915ad740a52429edfbc3f1a951626e811b6fc8244b3ec7b740fe62172946aedcb14c54e61f21efc824c86fe788bbc8ddb9a1c9d9c6a2aa47c09731ff0a79c7fdb70c1de6b087a3d6c741db256d7ecfc12eb0bf4fe7e03d70f4cbe79f7efdc73703fcfbed2c10796576f2a22555904217af2bdc6af1b67dec00d0a8eda34935dac3fc9a720ca75c359ac43016fb23d7c0a9b87c3e1a04fd2cc6b1dac0fa18bda0aa91604f028e16ecb326177b9bab2dbf71eb19e135a76c227b8e2645412604682aef6c21b5b11857e0584ce00bf02d16a9a103f68c6f815c03131b3272fa309eed697cc2d7546aea5764cc7c28726200122cdc3c858977d5b1634ad72029ab83193709403226def92de450d3a828eb370430c3d5abfed58e2ac15db6d1de59221ed63069d30d1002d37c419ea13dbfad70829ac245103c57e8ca588ee915c324cd8ef259cdb90f80826d49949a06b489c4dd5801660fdf29f3d453b48f983aa91770e644addeaabd0a47c7cf6398ec4599fce4fd078075fae2302b708d0280bbb5e26dfbb8e5962708bd7099bd2077473be02d00d9ce01d8a4d1398002541a52b4706a84a3aa40c80577195c9dff1a6bcd4d016cce05e0ea0c9cf9de00c5d706d0c1a4298a6767708e2a0820e852ad671935161ba56ca8d5d40a5f89f1d3de80b7dc861b33b311f1580d9b3b2623c9c5cb003044561acd8d021a2be1a98be9c7143b6c0ba4d06044d268488ba442b1087653e23418f999ec7663a980f4900e6085d651f2219760b4bd9f23db315bb107b3b3f6af1ead870f6ede5850bef1b168ab7b9723ebfd7437af755ce3fe8f7d97b83fe572f19f23a676812bae5d2e73c69b4ffffe36a15baf4895cc88caec57a6a6d5a4b657384f94acbe2e24ebe60257043b9cbc7189ce0f2773747ee8cc31383f9cdcf10a5ea6a04a608ed433f63eed1929822d93b5afb9eae24c31e4b0e789a89d668d8db324e787e08d61e589ceb342df5475b7834c53221863988cf116fb8211524923a3d88d705b7926be37c05175b698e36489e08f715ee25a0625d4a11e551d8dc67822186474963819a47146e78a26a909813f024cac54e7907132456791d199e264915762cb212359d378a4644dc5c46e0e5c864d142f7132c71c074f0e19570e999d41822d3a8b0c608ce091d7d6e56af24492863a20d40aa662d2c8c39d4dfa922708d5235b7c5ca01b2a3da9ef43c2056c7032c13d7fccce1c0fb86250ef149c317acd442d934386c9158b973f359ee80c324c9ee81c324c9ee81c324c9ee81c32ac3c111c32384f9c1c72b7678d4a8909d1d5c621258fa48382dafbad6adf9b3879a31b6b0098ea5cd179649c5cd179649c6c113c324eaee83c324eaee83c324eaee83c324eaee83c321a593b87f429aa8a87e552e1e49561b38026a6e803248c9a97c91a6d3d1d31c3fbe7b8e1d7dcf425dcd118db33dcd1ba5ce68e7ffafce7cdbb638fd8907c416c62af895afb485492b11affda97096d1570a8a6bdb53408249d9bcb9571cc6f2d4968124e36050df20e4a3ae4165a47b1c906cd97382921dbc414589624d4264708ce11b6e022c644c0588caf5c91b1eaea05287b6ee095ad6a800fdf33d66bdf4c79d245c9e862a5b3ce38f95aecd713f81cbc139e9655a80cf652762c39e955067827e5ba4a9320405bd2e0bd93714e5932ba60392f30d937aaaadb6e02376b0b2b830fc6e07dbd55289ebe07f4283dd5d2c380fb76d8f3fbcbea2864d1496cd5eb209493eb65ee3cd1779eef4fed61022326b6ba6b1741b4249572a026d863ecd58490a34b91d13966dc1f89538a446911ddd8ed65ae8bbd3a01da6badd0b6950a2ade70c1db0f2e03916ba63452d51a0895dd4d61619d1c234ca9aaaec22031423973439e88719d92d3dabe36b5c2eed4f85806be14a1928e9115a3ee486df5968d901b2d5c12cb888c7d4ced0b1938cc3c3966748e89db6cc8c1af6e1a364e5fbcee51b39702167cc5c2301e13391f675588057dcaf2a1e7c5c8ba01861375faec0b3b410efb5dc39ed92e8eb6ed207393b117cc65f60c1ed6b36e46e13911b27714c35debfe7fcd14ef9fe38a5fb3d597704930b867d824fa5ce693fff6f3bbd3aee17e86fe7c9e45c647556c991cd25421f1295919a5e97150d18c4b4e6570b24a678e61b24ae78ec159a533c73059e59146b95d75d05529bd324e699c515a4d221d95dda56b62a9de36716e6abbce1a83b3c91e561639356268cc9343ee054b30c720bc017f5c5cb2b41da27bad75e39153c0dc456831e091ce1aa78019f73a3d44cb1c278fd41cf74c726f1998ea5aacd33a07ee18c1299d3946e794ce1be3e494ce1be3e49447368b932c921b83a7756db71044dc9b0c558145a139d8a2039aec32d9e37e821fb9e454b3c11e43deadfc118c314e363919e364938feae1648c71b2c99533824d1ea99b2b6774363955d623360905f6963183ce2027630c934b8235da8e794d5dc01e9d31c6954b8231c6c9268f946d678c7172492e5eb0c698e491f67ed5b3b3c536e0d18139a8818261071e3ef3ce201d8c29ac3684c9e39c33863d67440bd3e352baf147638c5f49e993371eb0ce9545ae0a76e1a0ac7f5d21f2df7e7e8637fedbcf9719e33bf4f9969ea833ea2f4825785d750056b255a094d486a217434b6c461c6c5df2e800e66544d6d4de00ecd3518c5d7b3325af0ca80d95877beea422a080476a52636da8ebd5adf5039cbfd89bf3ea189650dbce2444e2e1aee08c5c0382c7a171b4d5ab879e603ef20417f704cb094f306f298f54c708546cbba72b124d5538944ca9f8cf4dbd4c3c79d8cb865ab7bb5d24a79e67044a691a67cd6138140e7d2a63f5a97c5f5bea0d35e37b93437f30d75dec10c66beaaaf665aa561b891be0423bc1d55d653c7ce819b609ac44bf06a15afeb778675707ea34bd373a30bd37f80a5a9906fdfa22f7a6aebe0229cf8c2ce706bee6f6c4b9b11f96e99961adc3b7dfefea80a033a3bad4f59cb74abed959656245490df1b1c67aab444ebd61cfada3c586a945fa72238e54d4fdf519d6166618b3c750c4ac533f72d8d7870f40eb5209881d1ad581dd0589a9b503675da3bd99c52412c89fbabe357b31bbb1f76d479c8297a54067af0b343e94c653f7e5448cf670d74a52eee1ad2ec94f2ff9013adc9b3de4892bbe606bb8e890f70e67b7863f7d59de26a0fb355685dc53af1ada4819b50b3869f69245a31beba68cb42e635526c89178b85a372eaccd4bddd661dccce43ba19487a0aea988c694d97109ab2da5cc38d02894944dd3a19c6a4371d19eeb1542cb6a30115e3356b36618f54d9803afdd959a46910538dac6b949137763fda3b80eda432fa98a6e0782a77b49b9d3a2894da54e2ddb27d9f50b6ca784e4868158e7557a76b9788ddddc70e163b3ed7a3c8282ec6598289bb29776365144d2e85e4ea86d6d090be4de5aea52b199919a661286db6347a2c6f30fd5546abf353d6154f12a8f5d462c8ae8c1de53ad8c925784bd350da207547ce14ac6403eda16957da7cac59dccb124ee483fa924a80ddba504dc513146c55019a8516ca977682b59675b7ae272abc2d7d4fbce23a390cc61ca81ad1d2fd5d81abc42c33956db46bcfe88d77f556ae2a6813b4184837029d07110bfac493aede23ab53031e71e0abc3850ba38a4dada4e4dceed470e7a139771f7b9b6ad31873ccab1875d464001251eb7d0194af34be4d1e6259a89e0f3125c532bc77b8d3eee35becfd4131b989a76336f9e44e7c8b53d8eac3969ade776b1f33bae0b19f39e65bde57ee98e5f306ef03bd5bade29c97e44b2ad48cb33ccd078d9794e6847cfb2c11f96cff7f75fde1f54a71bb2f3b6e59832c95212913a8e200bc5543a2a5070b6e5de786ca7e437635aae74e46443a86081d99d2819d74353ba2d83768bd29eadb83ed5d53340503b7e148f7dca4068ac03abc8c6f7e0a005111fd94bd557b2d56f9245499d357a1851f0a0a21b0f47329d38e7be00e4b2a33a5369407dac046ec82d8e92aa7a2de80ca53b0fe061da8f92aa383c4c034eae7218f64ef80616dcc1db38341adfa7658666851c1bdcc91e9f153c000bfe5b911995e53f52580fd3a637bb12f2e85d85642d08b766146b1b80c411a5e021615726a3d7d2824a4d4d5a60a29455dd67e793e8de734ce394faa62c18d7f893b5712e2cc6235ba6d8b14a09d5ffdf44f6427554c63af0939137dccfc6dc5c1afcbae932837bd6909fb846f9ccc686fab948a15df440a2433609b65db0ef0ca30e0f4cf272d884fad2a5c01f49408152412a171bb90f372dd4d4a86d67e8534020147da4ea2ef73a37e9eca64e92111138b5f588aae8f1558b11aadd29c33a26dae348b97a9e63079641eedbd183c76fa17b0f883a0b88ec0a2309f5d9f690af9d87c039fbd3613bdd18ea07d5e9bdba6b9fb7714af1c157eb471aa9299ed0be7ca384d46ff2ff263e1b9db472b1f34c70ed719e11fefc0e0542d38db3e422df11d544ade602bd5c462e301094dcda407946358dc5d46fee3a10cf4cd9fda7995a810f9b683a023ae502e35eced28da3e58e4286d2a9fa9f1f9bda85077db76f64fb2f36c45d52fdaef434a86ea3a6aa55fb77a610d5ec445bbb98666eb2435b8cb246a9c36e451a65b8309590a9904b6e6a5a77ad11462b66f9d84cdc6d3abedb37fcd205eae377ada7a18dd90ed7ce4d1e1bdeaf9ae83aca77c328883a6d59939421f25d873b966d99f5c49ac9967b511dec96cedada77f69ebb941e6b4f4485f83ba6d4b555b51babcd5ec9fcc6e5be333e3a98be437df3213cb68392d492c777bda4d16af99e8ada76ffddfaed27325cdddcc677b075e496b4e8f89eb825c9b98def1e5b7e82164e2283bf5392d42bc9d8dadec412d9b684ca8dbf6ff6d2b9e977fb869f7b8292fedf3bc4b995d1be534d3517d51bcdff3f7befc2ddc68d240aff1558df1c595c1330de0d48c39b4d147b94bb7292891365f75abe9e66b325724c911a3625c7b2fddfbf5355e8669322693bb676bcb993e388dd001acf42a15ea8428b8e10ba5602551f94ceb308d492f2dde6012a543ccb84cba48a5d0fb464ccf45133a21cd19a954e77174fe92b24973d06d78e618cdea47d04ea340669d5a151c2581354d7680066ef63d77be19532a6ab036034d5856fa2b7b66b9412ce443d764a286dba36082533130b20325d96759d50329aac0b9834a0565c7998d9f48a07b65759ae01abc6a86c77f144d0a424f0071946fa544e9b319c28521920fd35b60e109e194da6d001d6d3a0a44b79e0b674a6acebda284cf01ef1a0d76e4ca3ccbac05f6559d440e0b86832db0532465a1dba485a2a15bb0ae5c1217461cabc0d6839900575acb20c90b6ceba01a822ef355aa44813225294d2b8ae55c21ae532a06960a37ae84af04e3992aabb68c63613467b19bb2ac06677056c9c2c335d95090d5ba80b7c91d7127787932676d10443a2359db43ec07848516045cc24f05680632c7523b35d9709a7324b37f3656655d749a15494beab10744338365e0237e7d31a84a8e1ec1599d6dec1b4c04afa2e9acc64d174b515dec860615aa4f32e76bdd0b0bac7b03d54705d6581c7885e1f5a0d3c410c5dd43c29ddb51924e00ecb62a64cd7021794c960baca4b98781bffcf7bce9ccbad5437666f3c6daa61fef26e2e047c82ff45a7d0b3028570b09940f8f55fe3d56ecdd24f92a51acdbc3d82235f17e47841920b082750d1eb91ae38562a508547f21a9d8dd78657c0bf2bd27c698a9d0020348c428d83159e655ed8c248f294895e00d1a941c648a968c83184232f8b1a834445208c153da9502b8bf12e13034840ad83168a0591310c66ab85671eed24d1f05cc30e46c79ddc8b48bec56df2aaceb519ba4cc482023f3954d643c7338a0e85bdf7f684068b3379f3c406661cba21bd1d18b26a077f5c0ab38804545c0ad5787361a2844e8d818023e7fc05d7e86012a503cc727440ae841e032f838c89e546a280b5e050bde1ca91a3f1c0b4b088c8021211a84e40fab2200fa92a13a8ebd24892c1c96b98177e4cf1d642388afe44654e84211c3c638cf9eb61a09a27af9d2ab9dfd3c21c69afc7789f04d683dca1a34a0ad75ca5b86ce8bd11878053eed12b92206e0873a0ef761c30a2b843cff69a850cbd4e5b465311f1d6b2226f5ee6e64249f4cf1586dc479a3014fe72f4128b130704004a7fb5c87830145b0c7574b6f0c2c1bca1192dc32822fed878209831b8080009da11288e0ecab4f05c8d61ae346a110b4e0e9d3272211529d608f03e5118bc791d04aa0115c320d8062612614f0a5564c2728c4196a13f7ba6e9771c607285468728127dd107e6d06194c1658049f347ceda6ba5c932cf6622fb7400dc8e0b119d6dc68598bd1e170ebebc8bd33e13561a945479ab8fadd7c268c382152ec4afc9c155c2825a8ba880073b5240be0695b7b261035989168d2ec4e3205cccea5abfb664229d7e647325d208e9ec09f9d5d17875452b61e32244ad0db2a08c3a462de6721b4ed2d705405890e8383d0aa0b5b069948c287df324759529a587da47114c1867192ab995d2471970e8750a57f0055e9096f208dac8347481a08b1bcd5bc60ecbe258a32bde88685b97f2f1a529b324e2bdb9e0d133f9192bdc02b6834d1789071b6e1097f9eccbb3437441e0f5327368a54cc11299c1b3401b14c064117df4921b5fa6303c05e27b8c56059f92b75238b93c2019cf340665b186e9e0d07d127abbce82c80a4522380a50a128c2bc48c7afa2c88b580f1ed258a113e1d8fa8875f9c219e180c5cca0e58c2b0c7fa228c8bd4af104a0be900977ac1d7ae935124f0d72acc793833dc48ef238c338364e8950a0a807581acd1b5f45f5b907a33780d430386d84278d9e8ce01b0c6e323668ea006714b2d10506a23141388aae6fd14924368173041c07b386fe38a6141d3f864163db7cf4231c6d003dc85a0f7cd3ea7234cfc75f9a2503fad1b6f69a5b590081e27586fe720c571a3d9feba19505a54b06708e86f298790ddf30cce375327d3684ea526d922bcdeb2ab9d237170a2d4197eb6d57d0ee4cfb4b7ebbe2765f5bdd69f79242fb649e05fbd92bde3c869b0bb432fa6f1da442272ff6daf82379cd8ddfb4a02a0a77121c708a87e8b32d33c22af489a9ad63de32e7d03ee348597ba2375fc8192aa537da125d5b39c4e839ed02111b827c05cd9f586f8facf11b00ece649062498f5e648457dcdd114e32361d467d04be14ee06834d25eebcdd6a147ca87a21eab5cb57dbae6da1e4187ae8d53374fb407e43be4da9f98907b568b873df743ae653b85f96b0d897e35b1558a79e6871a0aaea62d15e2fe2442b995b44c2ef7601bfa4a986803064bb91b90d8d5ec7c9c5777a36c32c1fefe9bf0445a6dd86b274a6fd86a474a1f52415280d293d20425ebb73c50d7e894026fb7a3bf368786a7311300dc321cda4c8418998e81eec37966305c94f2e466c26edcde9bdb357e332ac13dba019514925377397597a7ee72ec2e87ee1ae385929a696584579119bc53808e1571626f9e78e0c087e4c8017839afb9cb84911943371ee810ce3ef596291b85d78ae1073717a84052fe886ef5e1870c3f0426167835fcada082a085a1b80e2a6cb52bac81701300a7ecb510fcdde09b7c707e37829b4f815fe31950e7876818878c043dd8706d919f43b7bd0bafbcb81a2114e4cd77d94def0945a1f6e4bb3eb9f8e5963c9801be8512f035547df3041dc8283d8c78f3bc568125ceb15ab09ba8a98b2d51086bf8cfaae13c51d461c9aba471484d7a0cb507e422f7b6c2678ecff48fa504961e193d7a7b73817a058088a1ca80fd47479e92aefe0641f7db507f7b8d7f0bc9512265a450a8f345a52e3da194295d70c3e8a781050af689ba7bcb299107203f1543736c34f208f404955c53234c51041014b7601ff0690bc426a05b0faf297303b41e7e898ec9f05a7903ad26192ce3a51a796d9c5e0fae35df7b0b5c83dc0cae521e1969842e44e4565044192fd08a1eaf61dfe57a233bcfc9556d1481ae53da70a2ac450e5a87802e30030f1229218be019d0837de0e19a2b4ffeb720854363e108b038724092e3587860e11a77388a23e14b46de06b9b7ff536a854960f1d377fcb62d74b8d17118e5addf4017f91d21fb4f61f971b069ffa00100ac848347099818006ba3f048f94dc22385440e66527a6b2771cf8cf147ce3654a2022af144a905e5aa80901c5a69db2940a466befd158323030ee964df28f10a9a45894f94915cdf55f4c2f085fef12689372f9c5eacbc79123d334e0f8d96d73cc8310f9970caa51f80421f7cfaabb4d0c1d62f5ec44c3179ac225ef31be3950de5d2cf877c1931e4f7f5d6b87c08481bc00fb23643df1d1966fd7ef46d830492ecba212b541b8c980d47368509504d9c801a984ee05c4f40c6ea74fa70a8fcb50d6d104b3c8eb52b0c8dc9f432f772cd951c02985acd014c95bbc53dbdbf9293e05758a00bcf6d68ed96f65eba265276edf0d1d7e586f13767d5ade19b608127040a184878da194b400ffb6215f697760dfd65edbd7373c133cda21f2f43750ba8591ba85903d43aa0cfd6b192063f4cbf1ff025da7dc9701d2431ddefdf171b2871ca5bbb33fea37cdd9f7ea1a4cdef46cd9be5fadb507300cc4c47aa52e452140e6446db708db3d154db6db79ed081549e05966a6201e994272a934c673239a85acf2aeab0992d0d9bd8521d364ac0a267ff6af0f33608f89105bda5cda3a03f6f93c0d6feb70ef289d29aa181fc7fdf20fff890f3c76f9047a04a6b5666bdb42f6c16ac233db4be4de53735baf964ac8fb8f567639dbbfe741c55d537657ef1a579d147437524fb0d72d7b7222f36811753d845bf08bbc832e13e7704cacdd1231d890ba00b297ea4aae347a6e891c0e9c3d3670a457507b101d0e437901ff3e4eecfc2d4642824b118490f4d60489b1a8486e9e0305d184c06a63c4bb3a3c740dec1aa14ca90b989a4d066e9492be12ab44322275519a68cb9caf023ee309ca6e54434e26d32113eb552d4130b87aa66878a61ec2b0979981514a839c338807a285c61b50818d90fe7405b000f9a0dd8ce18b51a83fc98e4d4cf1fea2801a40c3931b1cc6845bf1847c872e5fc1f0b9cb720a484553620a494bb1121fd3a9abcbc430b0af9fb65e7b49cc2fd6bab7cca564107003c022462846c232c3d192feccd452685e3c108d7443934d8b84160b51f10e5d036310ef54a8cc36a5d70c6627d744612012b745594822b7e5070c69b27ca60d04f8013465152da5145aa2d81a996a391dc5c188f367fd1163ca0473fb2c1c43f0e63a53911c73c20b869345a0cc20264a07b1198773275b1911b936277a36f7ba60346b4674e0b3fd65a4416b4f00519631a96c1ccd34464428d035afeb8425bb46134e8b70585e250918369cd6e9e1863f1729729c8f6140d24d1ca116d4383a7dfdf7d7691b4436134536b04868fc258029a45e6d1f008af164329cfb411984a1d01a8b64ca136074040925d4f32607581a4ef8a477968d1415564ad73f7e996f3ba300e45dc9e2c21f18aae85d58ab02d38c65f130603aed166b07eabd5cf120edc8c439b221b11e91749d57d962070e86749ff0b0ddf19c5f2c5d2aa41721dee3200206c9ccd9b6eed5e3bceafce875f221bf559165159409c0683ede3956486e68e213007470865c36385a25ff23c4bc98056fd531bc8136a0a2959513e146dd5f054452b7c0b16a800ed9aa689a7e8f15c02364f910e2a4e45b0652842a5c9c3f37b584838e33c5d0b518a8c5223b344787c028d6d29f03f59cea2a759a4a9b7d1d2175c4bc53238ccefaa6d53b72dead63dfe56b767a6e0c880a0115e4c5303748815ee06438158a6433852c6d07d15f2c802a8073d8032e5806961e851d8053c6c8194c01b37d20d157ce613aa5418181d03ad43018e4579e018d5142fd93baeb639356836dffa4ddb646fdeb91478fc5f7bf70bdabb18375f45df8a9b1fc8d6c2e0d9ae91f6c62884a109e78f779bf09a0eb90a272fd03e05efc768a61e4e5ea00bd00c1dbe3e6edac24d18a9b32605c2476b6e01473236874e03a0ca3a3cbf5274018c6b2093d1d71ad098eb63f1a3cb6b89f60ce8f1017b09c5bfd04db52d6c7fabc0e68df52506c2fd22b6d5a147079f2e0af4a5f3fe1d76a8ac054e0caf797dc8662b9a5ee12b4b5da312dbcfcc141237a320c10b663922b3cc914d4ef7e6283c3086f2c563f4bdbc71c3d2c3e982d4b912c04d62246e85fc2d85d506eebde1dd337c5a0a02fc89d141a3c5ab305fd26edb1c03b7c9debcd3feb5cbbea0c34b07a6b5fd7428e59f2788ed1709ed5b207d3d949717d3bb0909f529e67581a2daea4c84100f2da0cb10b9d0c630abc8055f10d265cc844c4817591001c34166c24bbc121ed097bd114e5a7446a6148b0abd2de14f06893acbb00c863d54226a8335d84c637d3ed50ee48817516b742aea144a587d10d12086965ab308e5d014521957fff820a442596c34818a64f481c2d8bbda70ad319c9d371816cf46117d643a3a115ce0410ba323c3e89d99e5f49b213065866bf42297a1cdbd511c3ff28a02cfa34758e9f0f63c7614c3ed4aad39751428322dac742c43d7d8e88b2530ef8597117d37e385086f1ccfac081686e4850c5c61f40f463f866b1585cd30e025065d814299c7a86f1607e7b388f77464869e668ce33a13da2aee243adb851f74f72ed0b5a297181ed8f3d43ad5e4a8e270a82db929b4e4b7d05a0c1716a290c1330b67a78a18ff2dea426b91a16c46e3d54c291dc6220918dcd0a69f48675fc4990b2233be502285ce05f233dd1c8e0e63cf1bef98d678d7d59167462f0246ac47ff212c5070106535f63dfd7245ba668920ac9430141c2a33e8c0d46874c8843146a0550c738ab166328377e08df7a9f1ba38fa01e199c1185be8f1c6675cf920b40256355546bfd8ae3350a90f3416e836dead6e35be4de9841862035a81acf568657456fe349a9c7f6998453bcf9cb485325e448ce6bc08dddf8add1f35e6e2798416d2e82bcb184aa95ae5ebff0190a41126069e7991e9b133680d463f0560248961e09df48019d0fed60807c8238a985926d3272c7dc2bd115ae19559a32257d60897c5fa554b2fb2e899bcc19b27640b49c1c079130c9c6330f00a982a4ae394d6bc3465960288df5c4425341dc12686315f1e0b0e027525f590b4e6694892d36856878f9d664b2362f588809bc4c1dc3c01caddc48c050b53c85726845ae4a97d6a91a7f6b159c3e4b1725a78a9a98a825ae4cb2dd6afd4ac8339c4d22c7dbbba1069d55acd6b5dafa14ccb774c35d00042919ae04bed376b28ebe5dbb6edd20edab0f352ee86cd773e9cf7afc6fdbbb923e57ef7ee5399674116dc69112dc08a67d608e9e12162e0478c4d2eea7b484cf92a79f3a3bb4c0502b2c13b079aee1fc0df2052209b56d10a9f9b7b4f374fa217d233eba250592199110a0e66e685462734016bc108eee81e3bd8020f672bac67193c6542a192d4687c1c62ccdcc20972802a85f11cebc122e80a966ae3549b12998502d85a96941b1e089960c7423a6e8d50e108baa9c7425abcd88e669f9ec9c3cc0078c1fc07ec9644850f6e7983fe03ad03900f0eafc27b0cef91a10f178fcab9885c66864477604e0bab59d442f96b21fdd0866b2e942eb8908a5b91651ce637a2b1ab5018ee4142975da45015701405f41e9765dc6b811e52220c4b4be12caa9e0d6a5335aa53115b78c581aeb35ce0e9e52d90327074e9e49fc8e16326850b290aa6cba09f5400d28c14314317e2169d2453bd387265b98918a918c802ee3c8e50094b1d64d03feb739b515450fa49d14f000480b6bf168aa642ba22c2da1803b30be77b40a76969e638cedca1314e38c734f604f785d6923e20fff9f00b50c2744651de702db76efab47337edfa94bd61db57f3afc75f9e7b0cbc65bb30c8ae2f9ba141f6d26db38fb92ab3b0e25f7753c64a79fba64ceb76c1a68b32c6ca958b32171c97bb75a977c54fc2919676939f84f6added5ebee5a6ebaef7e730198f18fde22d7b049f032661421602c57a502339e6334c08a1b9fd238a5352f4d19d67cc38cbfb9900c9ddc7fa9f56ddbf6b873376d7acc5cbbe59fe4771370ea935c37492129e0a512111d6b8b1880a771f0aa84f2c7265821158bfec8047bac558a87f9b527bff4e92739d08d4a002a256b718c20814859c191094ba3e028b7c75a62c44f3846be3629c629fdd48e9d94ca84873dee85d1879259c0e870ac3b839e92811ec038a705759c19386ca02de839c79eaba899557eac320d0750a6720fc363f43779a492423aa1dc583925824197f5ea6ba3448c4844c6d8786b8781452b8c3db141488d5ea314daba607041a929ec133ddf3cd1dab22885d563380ead132a5e6b74703a86a39363ca099640c777560521dd89d251c86c8c25ac70e61af8693de60226da1c37056f2e2c710aca607d0c4b9f28ab84f663e1e1e4b6c74e63f8a9e8ae750822665be0fa49be216ed0937c7dbca027e5f09b71fe07556edc81d106ff4c561b172411bd3be38f7a61378043cadd04133f4dc7e3d1e4fcd1eb3bba8af907848c10b88143db4434d200d6140d1434cb74058f2c5bfce32981a7479ea57f142d936e09d31d61bcfa982e3e222a26ef5ee442114d17b5305c31f4c4289022c0df80d7ca0175a38721f22fc43020384f0944486811b940f608bee3813eb0e419116d3e51dd0b4fd0144b968bd0ade6fe250a632c79678209581e54b53c1b6ccb6c40454a5360e52f73a8d5f29adc5cc009a5743852c1921f24f482845ac4143f93dcb5a64e0d950e05154be1d8438ad4ced327ef0dc4bebc4137eef056994dfbfc5f9bfb23d0bef29f4183e525c650ffd4e3233065ed91f2f2c3402ef39f0e721be16c3d708d2657d5d37f5ce5b3bbf125f149115a03d381f8ab9abbb2356f6592d72b4669355f6574e1290c3c705536f94983c2c0bf714a4abc9b9229f4f812afddf2ded2f617d05c9777abb7e5594aacefca3bbd7005d37213030c7360c602bb0dd817bdfd66c07f737fe4d099b8418f00984a2c374ae30ca40013cefc10d20cf921e198bad51b5a6b6d3700c5a2c07ae0984ecad7df8cc6e3bb929e7c823f70a325ba23c0d00c9a64a64e0a6539dad2c31ef20ac57e1a38104849190ee62f7a0ea50d3c60690ea53dc646059ca53965dc5c58c9940f748b5de35575bac33e44040189cd1d76bee46d46334ac30becca5f73e784b5632e6c268cca3311a366f497c42a4a091951e836e6410414e1af2bc8a008951e2b270cde4ad03ad706f834fa4b05b1026e8534474687823a9b2ed0e3fdf9003d5b93aefccd132fd16180d18780d40c390cc8023cc2fc5d1bdd38c36554a20985e6324fa1d016483821c8138cd0877994dc42965c79a6335da0281b761c39d1f18e04da47e41c0033799d4eff4e6a9f5cae71d1e31dc9c087e4638c32eb74fa77adfc3699631bfa37ec9f56890d1be8cbb321d059442dbc53bac882c81ca24b2731149dc180384cc5800148a3155986d3a6336eac0846712d1c40b51319c5fbd136f22cc35880410b63d1c8d007c3950b1897d566148931bd2a8c248ce1e883b01a9dad4b8f71a9a2663e13d658ae94c3286526908f4a2d247623460c4b9505b48e945a7360b555fc5abb4c44d4f7d16f1d009ac60ac7af55a890e01a950056388c738c1a42bc4181d92a8502aa33b4f31820cadb42698cb72a313c5e404fee5261bc55e5991136c36035194a3294373c2ae1a361510a6975fda65c269cb3c9ac25d864ce631553115dae2987221e9565225a7b68a5162eb3cc1a8311ee8db5c278f4b4d80cce22a1a2ac08197af6948147239476f8a865a816af2c256d05fb4d5a6dc8590be6df97afaacbfcf28e62197f8acc0d856647c4a949111cb07c26086f0de2c60c438f688cbd7ba4ed927fd42587b0d7809748cda231d683cc3490a6f86f68a36f7b825d72bd7a1242e36376c9e52a10721884216a74bba6fcb5b6619db794aaed220565512c1ca1af6cad0b61487b86801b3082a3c12774a602d8af7692a2990e72a8cca60bff297aea7ae702d966a714719373819b0b8dfee382bcb672c883bc46460c5d0359b94d3eae36bacddd228b5fe9e38a5f66c0385b9b94f6e39b347ea3f81fd086b2f6bfb949966dd53b7cf61637a3910627acc7254df65a84f243ffef6531ffcb6c7a754762fc4f897a861ad84dde78ed666fb55bb690d247d16ffe76e1c9177584264bbe7cadbdcef426cf1eb0a6ce1fa9cdad6efe36d31b7184224776eaf77c9b6d72553c2447c661880a30a7816e33c0b70d8164f468e3caeab4234aba005233007d0adc2065dd5c58e59984afda89dca26f48be652e700560749b9620ab3bf8fb678656e4e6021564510f79b0d7dcd52d865b8b2e6f3b91d18d4397da8b4c586d25d86ba737652e2b1eb1c5841b4eb4b41b7a7273c18180d37608084d41d78c3f511edd4ca0eefe481bc43bc3ecd6e1a29bc5f743e7e1eb2d48a3b5efd7a38d56812d88e397c9f9dda18e4fd1005ab4d3fe1ddb632bee18727428653703e7978596949777819642b8d6db37f9efad596b7b17084fe392dd3c316e81dc6a84778102d5451aa03374556e9c5e4179c8d21052ac930c70129f8eceb68f9b56f2fd58f5e6826c3afd2a5ad6e143d0b276db06324c9616b0fa9f7f89ae7908db6ba6494029110c65cdcaac24be0ff925dcb50dfda5226b11e08f4053fd38ce275f9e6b609822e18e919ff222852e662a36a1d624860bcb5870221e2b6b99c9a2f02716a338c127745fc43be158f0c9a3c8d81a11b88be837458988f7bf0a2722d314304d318ad9837e873ca3d87bcaa3fc55316df03e25aca508e81b5e2bbcd8837234e8a21b3b0c8f16320150a4b895e43926721fe83ab5e3368878f3048d20bcbde6de0a3f369e2e7daae3947e73a19516185d341b73e5a0e3de08776ca262ca47e10a6010b972c2f1281c86b5e7da888c6b25f4b172e821c668bac4a7434039800d638eb188a08b660b802d60633d742df23780d655551e8e66c5f88b832db4463f542ad636e90b7bf4edfaa8686a5bf6257d945be8a3dc421f6501f0926068a18f726d7d945bd64745586c091882e2ee2f85ad1be285dedbb1ef9223e28037ee1751f0863634410c16e1f06a45ec9db6b10da41a98d804534d81f54035ce5f7f993065328551c9c298abcc7325b302e385c1a461102ea6854b0fea5a4b20c855208c16988e78df1633c7f4bd2a941718061fcd9231222f93dcea9b274e5a80aa43f8453f400bb87cfa11f00c9c8e0da4954728aee1b786caf7c3ec53e799f1be01f46d6bdf2cdd86a56ff237acfc97aa784483652bd7ab0d91d80e616d4eb2c5bba5ac0c01befa18452610f421accb59afe14432654d06a220e5ffa00ace05086d82c0adeacdbf5e951500dd97897f9a334d486b1677ad42c20c18e8cb8b1833a47ba04c0b2b54cded2dd9dcdeaab10bd68137b95cb6fef4337a71fe59a3ea1390115ab111118bcd741bb530ca52786b49520155a31946d9cea41a974f492533a1ade5da390c42e333219de6991656e38552196cfd16b508de9c18b9253c1f4689df6c961d847791148928a5476f6c524863f1f64316b957c229bc01e8bce2315df414466338666755fda663bab684c1c83d6c9f1823aa1fa3e1268a2cd8fa4d1ba1428ad11222aa17629621e568f1066df4915bbc0beb8442fd2edea494998256bd879da3b41d637048685c091943c19d5032e346844c0325eb4891ecf1d28dc51e1b6f0e55a0ab99ca285c26adac88181d8969af4446cf858dd020a34858d6e1953469ebb71044b879a26360060550302617b90a2258c5ace65633ab2b6e754ae394d6bc346558f30db3db98a2e53dba7e9b2f9759bbd57f2acf47d5bc9c9577e496ffb36c73633eec4ae5875ccddcb2a1ddea867646b145c6d286c62f9b0ded6e6f68cd1719ad1d0db8c06a1e30f23ed96858cfa3c7a00c4e0aed7804f80e90a53305593238a6add01e7d04842ce265f0a0d1d19e37f51b1aa77bf2afe5a4e1460a6d331e50718a71d86c0ce975c8b320bc2764a016f28590e40b2726243ca2324a6fc5a40bc2793c53d5426e101ab94130c27b33344a4417c61663b9c024196972e043c9c3576dfa0e738577ea8c1f5a2d822aa250963cf74505446116d145a44333c62caa1b800c1161854d1451fa21228ecc2177a9ec5067c2645961b4b0d8411344d411395e63ea37a3442623c738ce5aa6a0c9c2a9c0e03b83deb9001fd3cf967db8d840ebf7e0227fedfe7b9a0f0e67afff90668c28a8085ed8131d923dac5eb6d7ab968dfeae9553c21e1a60f399b519d30138019b2c1dadf315f799703c72e01fadf01f5eb3b249b0e2b9f1dc791eacc8e0579980c1aec8dab2b6b35ce50bda7e4f5d923b4003e85515ce8e805ec5a5030ec758e18a3b76899be229b388a1f3c387fbc46dfcfe688a3f8fceeb6caa8129e16f9e186b193acd5fe77b887ab5a953eeb3744a33741ff601fe858d88cd74aa95e9a4b8e45117800981be709ea29039cfbcadd02adb5b866fcc91f4097e3dae90825f7cdbb2f969f7aedff894b769d3ff5ce6776314f2cfdef577713381a3f7c8f7db0917e46012800b0de31df38aa4a18105a118ca1f0c39cc8acc98daadb4149aa3934594701ae121194f9543632433e426365a415e59818e3012635506ee3f837ba1cf65544d5e50580c221c2a203da2c4ade999d1c4f97a66ac1691bc37e37581c02cc644d7f85b11816a911c55429149a2e3dae1a534f40b8e7e1438bee11d048bbfe8886c9bd56002fa8d9b053237ec96eb2f4e1282666716e636c2ef18a89e1074faf99aee23138563ea2b9dbfef46732d55581761ca636b79ab35bc77ef22a7eedd3cd19986fa83c4a8de410e958693596b54977dc085677dade42276f652acefb661fe7a032fecde380b425bc3e8a755bf1299cb9885d413ab6fc51bd4d082d10530824e032e090149dd2c83a7102a7a61f842ff7893c49b174e2f017193d28102183abfb89c642d5d85a99a97e5b86cd6b6a219e24bba34b40dd8af37f06490b31ecc87f9acbc43b9df27e9e7157aa4522e08e98f2dce03e02819f5a1099988dae3bd53802be399133266f8648390465fbb4c28e0c8ad06665909580f2b24d0fdcea18fa80ca50a31e26552f2a7e4b83742664c67827c5b45c56c14561f2a19d001035a86460f6022d01f88ce948868afa584c72e0895a18dbbb08edc5d644c59b246cd84b3e89adec9c0025a3b0251e19d62991252a3277d8b4a27e5b8cd8452e8cc4239cf3389cebfd0eb18b052993f4911ddb488d130a744f474c9571916a0570cf7e4585923620c5c595ba82032879e9bd0e346e6b825ee07c8dc106e9e98009ff91318a0f287da396164440a5306cd94f7c246cd30dda1771a6059702ebd003e11ad6a1952e21abec1c77a96d003873116b198b25ca9202290dd00ea2a8ae04e6c1863a8686b79fabdb9d016fa1bacb0d1e401260ce3787b57633ce0a73260dd8c34452662e6b915d1a16843072f82f6e9118f5e659326f3a3e3522e22ecdd8a4b69f4267b3e2b6ca0d87b51655c8b1830f68ac74bd41e9d2c2b87b46926f14ba3a00d8397248433e89b47a2bf4d175c8e6c6560e927e12ff48524b22cbb1d1ab3ed3042d6a2ddd5d098da89e87d21513ec7c8059192c96f1dc0a412ce6ee34a5bc864031a5a14588f8d2e46e3f20feb48fd2e88548bce9a2cd9533320983050761496c32e8ec256e8dc8988b680ce676c017427de5241ba131716094f74510ee90c0ba073712800f42a11ae9219749ca798437d3aec3a7cac22c6bb90752287c4a26e876514ab84020a615389feb5949ca564a08131800a2a3ad45d8539f229c85196821c7d9c73f414ab095dad6bb291c0349b224bd8dbf19a3ec81ffda67adde67affd913b40d1bd49b79032ea8b33763823facffe83bc0044aa18f7232e5a979cbdb7beb13f044f64fc11337183546dbcfe1071718de0d02a67fba73ebf7eca3cddea19beccdfbe85f7be8bfffbefae770dc6c59a685ff94b3fd9fb36721596d38dbdf03e75b607c3d7c4fa6afcec6f9cb2f4f56632506b873428f6161603918ca8b2306b3b05c0bbcf5867435469943efc77ecca110f07f05d7098d63b03274bcade0f8574a9863630dd31130147056c08ef931b058804e34cb224594ca0a8a0d6718b21d8135158c9b66ea56b420ffc1bcd597bac72c0da1c884e368280a4b8cb1d69c4006298e7946bd8c05b7b8ec1957966276680a6515692a9836e8f3d958916d6d5d01aeb442153c4d1857401f059c0686a380aa81d7056a0491b8be062edf1d1be95926854523518f01c050730f8caed6583b36a48429782a838ed2f041a3b7f331d75644a69db0272a59e8f10c6df6d01b8a1fe20385f690f84c067cf0a0fcb5f542511db013ecc6768e159c0118c4c453642ffca5de6230bbb10352d04561ae617463de2c354e000f6a3bb464406d06c40e080e180e8cd533a018ce378664b422abe1b5e069b55100c1152d349085b4d8ac596c0a7e02e095a5c889081169b1118a60c5b7367fec99d656e842138e4ad187283a4bbddc59243558c69af5e6ada73a771bc0603cc07a7b61439adcd760813415a9c7a686579c0ad40829946e5ba1793dcc63259989aa48f3c014ee0ec39ab94ad3c9ebf9dddab2c2188d426ddeb869c159030209241a10d90c4535aa31452a81aefff021417c03ac27166f92a24d2a1a9e124c0f11e011de3189ec5b69375c7304f866cf6c6c64b1f3366e4e180c4778c7ed3c6e1699a50dbf0d4c8e4de698d5613b9ead5110abd7382d31c68144556283b61acc66854748480e8e0c77c46b6d732fd79c511b0eb73a7bfd01f745da645a2917aa05d76816dcaa62a16590c8568d155b968f0bebc696c9e3b293d4c660b136636cec1a6b0b46be64af585b312eec1a6b0b46b6cd8671abf46a8be06a9ecf8ef2f1d9972643d718b5c009749408f8c93bc02a48189a80d84c0a8fe1ec0d52789a7940a44afb1389e1add28e0c18195a27475fe158458b5e2a34b314431525231ab6b2218d5dc68ca74d92316701f748c420d270ed185aef172864c048b1da30ebe9568931223bc6db14260a7fcd9ddd7a8da29efa0d6b967237aeda97b6624e07f4dba68084093a4db2513ecd3c2e4a46723b8c418117631c1cbb72ddaab8dfbf2a86d4d6ebd7658c8e43980f40c219bab1a39993c956c2a249bd11d9986bc7e9ae0636c59534854223456496b9c3a03c403f407f6e9e98105086a5e1a443c11600ea710dc9b605c9e6c320191f500dad4c6490458559dce678038063334c6d80a751f1f2f5f7d3f99787afd1163c0825fd6697d4db34c54a44b4b25fab2dd63e08a542bea480465d70d20c8f372baa5b3dbbb9406fae415ef30cb5d743fa39365ac2698e65f0e809f25a03dc8770a4a3dfe22744497b84c70b1c3d5b17bb5eb94d4b5ee76f58f8e9e59769b6fe055f65b9d0d1f38dd7b18e3050f4875f95825a3eeaaed462cd362d799dbf7ec9afbe3857523652e873e4c5c9200d960aede132a0977db2598453c303d65529e83e8f803ae97623292121198dded518d5ce548b95c2a2b414ef5e617805c30137d093cf80658642c08644f81005a5d9610ccc433290f2cc63e4318c9aa40a689645ea5a8616ec44a71b2fcc18d332952c00a5708778cf544741961f680ded9c70159c6c14252800eac15ba2f4094f9500d3856160341af7694f517fa92546bdc0c04934564ac6096886c19aa11d6a239993780459a817960d2f222a5d69cff1a0c548689908e366da5833950532c0a802c2958023cf27e1077404a70579786d6aae05a784a7e564cd02179899a15e073874497e5f03dd5785f9a44bb519c6e42727ac7032d35d45115970709c6702638e691eb18c3f86e15817c6b4c059c6a3a468f938cd9e63e10c7aef344bbfbcc961117b41d53833864aa05464a97e5eb7a828aca5a3ca98d382acad495be63224fb95449a22c307256d659120a297fa7f5e27f2fa85d72f4ae2257e74fdd9186692c5a5f3dcf92a3d327c2314858250968a3519db50cad506575d4fafd67bea7a7a35bb9c8daa7f09e83f50402f399e0a185ba7f64798913bc20a7993da9760f23a9891d3419e8ad13fbc19478e0614c9285b02f96a9b447e59948f8e14f092e19db923afe163135451ee5ad0fa797875d1afbe9dbefaf28e29ef85ce98d64e185558e1338c30e76d2682b7e4fa3ff02062e45ea30b4d115d40b5b90fdc0aa9155ae761f438612cf75ec478684d1031f814b290596985a29b183a63b2e024a06542e2b1a5b590ea504b255474422aa67cc0db7b9622fa583944959d75057702ba2562866789b49aa3ec4239c743ed8f5367443463d0860cdd5e5e6bdb78e4346c51887c727a0b783bd011a685ca1cf7c29ac07426321980a4c17b77858a42590cd1111d30c9422a0387a97706b92fcf02ca528df03e6b7ea450ce30258197ca3032053dbb8ca21645873e24157a67a41725adc810d7066115372262f4eacc00b1e5009d3a3b046a21143660ec320947477d23c8a597e0b0050efd76306d9e1b0b8ba9b02e1b45b0e83a6595725f72c757b5c978fabb6406ba64f3c9b4bdb930460a8591a432738436c8b1402f3841e3fd40cf1cda35d173b402fd3e020309b484f3d8b90c20939e55107052e1df28ac07305301e3d06a8e9f1f6a09e799b15a84c894cf8486e5d3c8b1460d8f474a87139817533823bca2ab7c5248a9a826e4d1bda59721fe2d8c138e3ce64a2a21d04d2efcf58e62f16b1684f224628325c1f58f169717f53e2ee00d2313d0c6cfc7c89c12d23be68456508dd72c0aeb08fa0c9ac64585f2d90c274d7121234b93e045a6682a53aff1ef16c4b5c03eeb51d7227f0bf2fae58bf33657a3aee0858f87367342926163b0189a054926f8355e045748406652399834ad026d0ddeda2647c665222bac889a2b2d8262b8d530302b5becba43e49b1c4bdbd5e82082477faa18ff5016dc2be1251a350421a301f08ec6f0d6ce07a497d98cd10f6c43af1cf3003b195fe091a3749e79c404e944034c0148ebfd18cd8a1031004026ac243d7066291c1a62f0e830580b40165e82831944941d2d3a590d52a7b74c684d2a0644d5acc6d92ccb125e47ff32c1f384f09196b53c3a61c89b280999ac7628f2891103d769dc4ff5a1c1a208ce6231a709775aa0a98d85e9af0fa09b0b98dfccc11e0ca6505a00d1a2608d94d01ecd8391ca6e3620d00336880c055be8b8d989c8175b7848dba88005f2066f2cab20a48e09bdb491c289b672a8a488ba20d48537b26340ee2a1222e33113d6136ae3548a766ee68437ac85b318a138997e0d7ae36ea13d382fa35059aa05d2346fa1cca19246c458c0f0157919035040e4d1420d35ee40a8d609a1b4900b2a6400695ae19c43ff3f9962d6096d3c5fa0a89b27286ed4cd558055b45fad9e1bec3de7c67b71d62f1b7c3dd5b9ebf1d5e8a2acbe4c01d097ea8b474954277b2df4b18e4ee0b76394d4c29fc2c2164aff2b8a2aa2b231128aa8ca2c78cae5988b0f1993c86e627d63bea86c7d59aa8d37b535ff537b5c65d81fbefc6753d1455d290fbb4d0fd058d31bb6a86a7dc9c518d74ec236105ec0e106285e14d800c8777527ff0fc88de205066ea411a140d3be641e60c8a18c4395a31bf320d1b2c3c0aa26b3012f14fe42e98a14d98ad50963fac009cbd2b5c18022abba46466dc16fe44ab164c7736c2c3621c3d8a076480a532c8a6624ee4b856f9e680dc308181c4127db11ec140e017a8dceaa1ca73bea5c416328f0120e46cb2cfe46a6a052b4a8c07619b4cb9ba7a2553663d85b2c8b66cd646411d1d4b9ae7b4c0da3e82b5917799a1cecd8cd850e0c433d38ba412da5a068d35cc94c60cc37c315ddab84898e6886496daa4cc443950598d9cca07a5a338c386ed18746e5233af8712ca2d580131a8d39b1eb19a75a48828676a30eb6b1e5d424b48e8f5b37e8c62bfb98b57e53cef26a7857313f3e41a9a47d6056f9a1b639b96948ce15d0c5a90aa19d5a3b715c2e9bdc4a6ae5576a604adf3cb146b320873c6861d5981bcb811c59d21ee9cc0aab983c52b09c71e952a255c82219618e2370b42cc823e5bfa688cd75b0c5e8afa1f1561a396a53feda18bfa4d14abaae105652f152900ec35bf570e54fe252621de35911cbe0a488eaebd6ddc40cc8c6616c877b754239a64554c73a020789a370569878f30420d77a7b14247640877073c1b5d21cfa79378bb205b413946e80ee94bb16c07fa9cad91d524f9f78f42889616dea38e01404bcb286513470fcc7f195e303a7878891593126ce3a875ed5921baf65df5dcb3ec1d071a9959fe900b4116595d109146e180c00820235bc5b1939caced0c3a6f00cf0213058c8430136b590e919a0492f4973531938478d5098c2a3f0858e706e3187740b0c1ef1aa41279a8e618341425da8b887777cbcb9505e8b0cc36f175cc3716a94b018189bb4104abac5235dccc7ce709751af309837cc7596b45a0e15128242093109edc21989669228d657221e7aba990fbd86698cf583f3c5c7f8e8b0497b168195465189c100e771cbb659c0fefa8db3c8dfb875beb473c1a0311e8675d464186b816a511e6828d4d7da0cc3347a54ac513257fed0a3a98bb4c0577a8b9e61ad09a27d53f3030dcaf032232c5e06c48d47930f83e4d9e22f991200fe6c95b700472688c003003bfca12765d19b9fc1e8879ea59100f800379dc1ce49c9f08bd548fc1c6b634d6d309674cd3c8422234da6b296a356345d797d0a4425c9e62c5a6090ce3460c9aa2ec99acbb188200a8710ce104b016185788aa767425b84a1842204c5d22365bc07483783e75ac0fc7534194c5f1d8ea777a4ddfa5c91de3fdc78b18ef2fee1c68b9219bc17be647cf8a1b68c56da75b68c374f8c834ea8688547ce5911e7ac8465f0a7b0e8ba86fe4787cbe85f3920b76b50da0b2c2ce673ccc7072f428b7b5663bea8705369aa91373536ff53ab580afbc597ff6c2ebca82fe5e200e8819a6c7ac516d56d2abb182ff1d0bee6a3eb29d902f12df05d0ff8ad025be0ff49fedbe86274f3af2df0fe2da0620a8f64b609e996a775dbd2d465b6adce68f265ae0e0a00e4d1926eb9a534ae166a666ef410e8bae6ae594b635db554ce6cab9e79793ab6ce6a2ab365567f2aabf9f4aedc897c1ac8a3439a163ddef2a57bbdea7cb79d47b115d7d11f5a6ea03f60b784f59bc5864dc6eed1277ae484a24dc86b2d033a0d8ee83bfc4461f48fdbdfa2a31dea0f74f6bd4b9dd668db4aa722b8d03bdd9dd119ae625156952827d7e2fb1fbe7df4e2d1f727ec5eafc7ee5fcea6832b5cebfb6995012886d339ebb159f98fabd1acdcbb2f1e8e2683f2b7fb1d319cce0fa010547a311d5c8d4b484a5fd2b7455e0ccbc5d702df0f4e2754023ebc97bebccc67e5645eb1b76fd9728a189793f3f990f57a3d269bca199b0f67d3576c52be628f66b3e96caf4e67ecfe4f655eccf9d174ce8fa7f9a09cedb3bfcd3069389df331263d9c4da7f3bfb151c526d339abae2e610f9403369db0d7d3ab19ab5e57f3f242b0fbec41abe21fc7655e95ecaa2ad9df4617b86dde0ca7f377ec6c36bd60a73babad9ceefc8d8d26d5bccc07f7eb6a3a07f4f48e7e1e3e647901ebc168bc8bb9a377d6a3497cb63c2bcfe4f3e707ad59a4e43fe4f4ccca8be975c9aa727c4615e534235460508ecb79b93c47a301cd0dd6f1f021abcaf9d525c2f1d91460723c2e67904598af1204e1c3e97c2f4d236c35568eab92e6f3e143065b0300b3bcfddd023fe6cdfc27ec985337a03ada7e34292fcadfe6e56450d5f3f2effdbc5f8e1fceae26f3d145f970588e2fcb59f5b0ac2e1ea692b87febafa718b0e4d7d17c38bd9aff389b5e96b3f9a8ac8ea740a5bfbfca6d9fb7db29c67955014e49fdbc8f091348b8bf2885c0d4656f60d50fa79379f9db9ca505bf8febdd2afb783abba8cb5009f1b095d62a89d57d339dceabf92cbffc71569e8d7e6baa150f7f1e9617e58fb3e9f56850cee033d82f83f22cbf1ae3882ad6a39598bfbe2cf7d9fd6258162ffbd3dfee130ac5a30eda85e4ef269757b08c381071369dbdca67839fcab3bdc5babe9895675d362bcf5a587134603d06196234e8d6c0dbaf52575356fdde2a707855cda717abc5daa94de16601ea724d425364549de4e35657e8b595fddde47ab9404a6815793acfe7a3625182de9b0290faa7bcaaf3f3aac9399c5e5c4e2784a39a52bd1ebb9e8e064cb2afd8fd11cced7db65f67379f5ea645da0acb69de9f9dee8c06a73b5d76ba53cf67fdd69e364a6ba6885ed384d42f69f0f52b8d94def2ea74e779271d4db0c02f5a00dd6b41f75e0b623b8bb59a4ee6b3e9f83b9ce94561d1a42f4a629f578b61626abd0545a9f0576bb6c3de0ad4b0fb5498a726394d7e87edafffb8f9ec6c3abbe0b843ea4f0e5a041e6d8b6256e6f3f2d1b8bc2827f3bd66e1bb0d2adb7bf3ae4babda5de0c0b37df893463e1aecc3a679fb96adce49b366fb2d9cb3b70076b6e86c0defbbbbecfea8e2b89af7bb2d384f19a3c9222bc137e45c4eab116c695e61dafd0ea2e70ee27bf8b38c1456e8aafbcbb9f7d7945fc640edd7059d9d525710d0c1bf4e87bb3d1d9ae93e86a17f3cbeff6f47edc3f9c5f8f174561748afbf17837e34e64cedfdd190e21856ffe39062fae47d48f174070bc2ec7d38524cb3bcdfacf6a7a0c78dd80c417e2336c3dcfb5b101416f88322a87c3c4ed9b04e1ce8c58a97bfcd67f9c3f1a8ff301f8fb763b32e3c3f292fa69bd15a590efa79f17281d352c22aea5b10a34bd86fe9c0592d4fc8ec56f96649bf18c21b617934198f26e53e3bcbc71521bac1a8cafbe372d04e4b67fc72523adfdb89f3d17c0c6dac23eabf487a9e86df34836f4d663d137576fdfe1949fdb31a125389fafd634ea56afe7adc64e34b9385eb5167e1cb22ebf5e522e7f5e522639c0e63ccc197456786a3f160564e9abea4f7a513f0b03937b008be7d00e7d2247e092c0b01023dd7abfe7eeea55ebcb587372e0c3de242a4c7d797e9a939a992f875564ed21bf66e0347d41cd2b49cbd1ebb5fbd1acd8be17df6159bcfae4ab6df5a9483cf776a7fd4797dff0ee99556cda3c9a49cb5f16aaf3e095a8866551ef4e6564b9b78a29a24da4fbf492846f2a42e7bb6289f0a74d968f09c881414dae6554de8d21ebbd76393abf118d8a03aa147c81492eed56070b0185f5b2cb24cea2c9f4b5be91d3a07d601cce26c6054a0bb9e6dac4f836584d73a1156115dcdf1edb37bf52ca49cc569b3825df36a9fe5d5827cda4ae8b5165dd447617721f41e5f95fbb7a0232ddb7aba7130ba861d976ac0bdbbcfdab8f52318e4b4cb76779bcdcc4f77d8039ae0fa04dadd5d6ccc07ec7487d728a893fad9e0deb76fd7f699d21ecff2f30b94020064750964ba0bd0dbdddd0e3db4340da4d0714ef88aba8180dae9b2bdfaec7bfb76b1da9d8df5d7c7da320cd6757cc5ee936c80ed03b6a7e7d4608d543b9d3554f44602fafe72a9ad428045b95aeeb822076817a977f00a25be9952ff8312e96dba7b3bad7de72284bfcca6579777203df800d2ebbd04d1d2f185256e1d2a9f22cc1d8cae3f035db44c0fadd02d2bc448ddfd35f4486b423f8030c0d0eef717a763f18967f6a2679b8ee5e79fe51829de7b7afc2e51ecc74a141607c2325afccb9aa0faf79b8c0d2205ccfb7f0051bd4fdcf92a9f4d4693f3949bde5af987d305637f38fde772f3c5747c75316933dfd5ec87c9f8754a5966c0ef4ac04a9d58e036785bf0a5d89f8631c5b72f45da4a5d4d9c19f6ec9f2771fd5de8b32d0125f409033a84eec38e2fa663de2ad7d88400dd353d6bd60dc9fff90ca0bcb35245fb0d0952a4592975d12a649758fc3d44700286dd5d76bf9af1e964fcfa7eb7eec6ee6ebb351ad3468b98d39d8549cce90efbaadeb47bad794e7cd5dbb7ec5e0d35ecfedf9a026844313a9f4c67643ef1b73f377be47ffd8dbd1a9613f6b7f41d16ad2ecb6274362a0702b95e3a7eb1970b105d272c6e669d46d7d9aebf1bb78f8b050fb4900cac3f28ca6a83dc3a9d5064a8b474f4ed3d7cc8ca6a3c9acc7962baf8a4fc6dce9111f97bf51bcf957afd109be5c3bc0240eaae4bcfab6a5a8cf27939a8a502d4930f16c5d75b64e52cdc32c8f5c36c0f14de974ec48d92f64622db2af5b1dac23fb21c1e9771c349f97b69f59f0967de3a87d8c387ecfbb21cb0f914e61700713e2c9ba9264a930dae0055e14ab34159cd6757c59c92e653d62f5931bdb8cce7a3feb864af46f32131ec009c8920abd8f9683ebcea8b627af1902c9ffaf5186ebd8faaeaaaac1e1a17dde9e4ee59894f6103aa8b7c3c5ec7085c5ccd17e26b7cb9131e0116077eb185dfcd1120a17437860e1f21ada12983730afac3f175ad510280f23ab4f273a2f7d6600bc8fa6cc862dbf65c285d6ee9a1eaddf814a57edb69c234a70b607f1fef040d7cccba9018e874874490a73b2bd34c7d5c9d644abdbfc8bf25b611b5dc2615b825b4111ba43654feff417cfe1e8059e17266d3f12d2e67768b1f22b94cbb5cc383b64add5697aed394febcca58fdbccc552568ae4b2c40e4779e57f5c42288c3027c53a3b2fa93db59dbb8b52535eb326f76076cd956ade6079c452880cd5b474793f0598e2bc0f69f5d6cd556d9ad1c4f4def3f5568f5cf3a9d16eb01e7d2ab3c59d941cafd0fd5202c1f5eeb0eaefb4dde7bc5e5e2a7e92b60fa6eed813d3aca67d357f79ba66af9ec42d294326a54d26b23962633d90c2c04e929a339b812b24ec96d1c5f6377cc48246773feae3d99ffc7a17cc8faf9f56583f117a6321f88f1df7366e06d87a68d84c59085db5fb42d48762046d54f749984f0c37472381e152fdb0501a12dd0de3a0c99eabe8f17ff5af623f8fecdd57c3e9d7c3ca6dc62cb903a5967a6d78fc1921f89ae5a0afed4d82d64d560a5ad366d7d9c8c759cf406eaaaf9601bbab95fe0c4771769b508ab59cebadb6dc1c226056a75994f5a1ad4d39d7c36caf97034189493d31de8d57c7655268a0fa6e1f4f4b76fb3d39d0fadb03588d39d24516a6a23256583f05a20b48af75a59f7574ab6a1bf795eaded63e405ad0fffc7a19bcf2431f865920445e372d0905f574d62de1f97ad4faeaaf2d17539991fe6e371cb5cefdf676535cf67f387c3e9f465f570b5d4a7906fe9bbc1e81a720e1b1c507fb59af1e914e6e37cb0a81e5edaea8616ea6bd40ecb005b93bff959f9f5a4184e670b12b849da469756c3e9ab7d341422fbbd593e2173fc7dec19262262386ea367968fcbd9bc85a4db0bb852f7fde96415a57f0d5f6f47e6572d40f971950bad65f04bd0d45b85af75752cf5b3b3d6a670a596dbc4350c6b5d41486f1d1ff59cad2bbac85d7fdedc2ebf4df17cabf4aa12fa1a702fd1e3ab6553d6d2a9488e256e154d596debc88b5155a1b46d4df15676f3c9cf0d78adfb62017c1f7bc4aed4b4863b80c5a98fdb7aee3f40dd9da667716a235a4c5681f5f092255fd3fb156dd1e587f117b4a5dad66293c1b8ac576315c9b5b64ad968c75307f74825c84aaaecdda2ce7c69e36db079ba45544cc778c8e2c7cd11db5acaafd232edb3ab09c96e07bf9bd3b94cd35183ecee6e3d7f0b1d540db34b10b8527069791a95f9ca076b19b8057eedb6e71509a0d69aa40125aab50554abdaf94609746f31658d260871c957695df6516bf53e0e7351cbeda5ba9a5c4caf26f31f268f7e1bcd09adb789b56640a3c93e365d7716db6fc82580946f47d74f5178fe75756481b25939f8f6ee0f2d02eb52c155ea6a29138e21c4fcaba530b195bb95a6a232c714bf7c1dff8963e1e3d1e4e5fd34de8627df6f9d9369ac54dd51990f4693f3ad350ea9cc9a4a974699ea5d21fdb01920fa1efedbbfb17f1f8f8a725295895cba565e2823e4e984fd1b43aa492c349ce26234117faf200ff30fa797af67a3f3e19ced151df6382fcafe74fab2cbbe9b1482e593011bcd2b969f9d8dc6a37c5e56a2f9f0e7e1a862d5f46a5694ac980e4a36aa58eac700f7ed0c152e4fbefbb94e6667d32ba870021958c7f177878fbe7ffa889d8dc6654a67b3e914e8a55959cca7b3d76c7ac6e6ad96e6b3b2c43e3c047c78ffaa2a19b08c4018227bd6ab5d189cee1086e779558dce27c0074c7aa73b35963bdde9f57a4977fdf4f5457f3adedda55f201fba97bdc9578bd7bd74ab5d94b4654e773afb5e2a69baff585f0e962a1fd7c57c77b6bed859b2adac0b66ddf9fa8234c41778353d950dddab0d6dcfa6309db35450d9eef5c682483bd635c6eeabf5056b03a554a1ecfeb661384477017f5a97d5ddd71b4674555d024cd4054df7667dc18bf2625a1772ddafd7171ae737afa1d0e9048af9ee371fb6d2a37939cbe7d3d94173f61deee59d3750334a457ba73bc3f9fcb2da7f48babcbf57623a3b7f389816d5c372369bcef8a004d09fa129c957a3493a487aa73b0ff26ed15307c59ff3d9f9d545cbc5c541f1e041a7ffa077bab39bcfceab67cfa17039816a7ef9e9bb0609ec35df3d2b9e770e087d9fee3c194dd06e20ed74ec04fbffa0b907a73b07ec7a548de6ec74e741ffc1e90efa41801d7576351eb38bb2aaf2f3924d67e8ba01d227d309bfa82b1c94d7ac9c5c8f66d309348b1fe387d84685a8201f0cf09cc8c70c58beb3ab716d2b5189d39d7709d1f7de8caa27706a9483fd7a62f73a6f6808f7d4bb6e39f9c75579553e9ece8af297cb413e2fdbe59afc9fcacb715e944fe79b0a3c2de7b733df751ff5debc5bace8e3bdbcdbef169d3780459005af7af901be24b8eef5e975569e55bd47f47c85dd9af58ab76fbf7df7183e9b4f018650309517f3669da0ad767e95fad46bfa9477fb9d37a3b306219deedc6be031dfdd6d03ea52061cddf77a79877c7c907f8fc3bde03a9da52e8a95c9d883cc2e8cf974a7eecce94e67b997678ba96f7534cdd14ac5ad65aaeb3edd69558095b7f4d97f8155f8cba2b15eabe1c5b21c7dfab200b07dd73b6ab534295fb1bf1c7c0735902a7f3aeb1d1d8cf7beebb6fad039f84e8caa1faf66e5ca4ade937884fcefde9be26a3683831896e05df73f7a3fe0c2b5e66f98573fbc9a24aee175f7b8f7e665f97aff9eec02757a4f765fbca8ca71fd8407d7fe3db9344b4feaf143936577d07bf3ae7bde4313fb97f873303adb2310e8770021e1f9481a8f7bbd5e1fa6657777ef253d75baad9c97e5ebddddbdf3dee90e200278ed74fb9dff10453e1eeff5bb656777f7def1ca10f620756ff0ac7cdeeb3f2b9f777026ce7aabc88b6be896eaf57a679d055bd82b0ed08d0a64fdf96c813f87bdaf67b3fcf5de59a77bd19307177f3e3bb878f0a0337c76f17c51f3b38b07faf941abb2e1bbd1d95ebebb9b2fd16d8b3938eb2de774cf3a34f85eaf0703a8c77186e320acf3e64f7fa28db57fd9451966de85053bc7f57ad945f0db1f745f4c5f4dcad9feff160900debd6badd8f7b49337554857dea0d63ed69ac3baa49a7302f0bafe5cd0c3bb774de53fc0eeab917c8d277ab7d1410f27a66ebcd7eb5d2eea28ab22bf2ca1223abcde9ceef4d09f564fa29bad7d7ad1a73bef9af3e44fa73b0ff61050f28e9811c2dd7bf8acb7fffce179b78d1912ffd07f963f7fd7c1adf763efe1e9e9c3070fcfbb7fed3d7bbed8d93f1164774bc47a7f4d90439d1af4fe2a2ea7977b9d83819895d5d578decb0f0600a2441af7fa070394ecf70a008984084a7cbe9acc7b32759c0ddea575a05a683da98efd3e767cbfe8a6eff7cb2e7ebd2f97d6f3290c2bafbb815b2e6ff524256067d273dd9fe695baa4e4ffaa47b9bbfb577179550df7f24ebba99f175342b3502feb019e0b0d938b4b3e78fbf674a73f9d8ecb9c68974127a726e1dbf3de3d55a3865eaf9777ce016fe1f6239387bd41e74d9157255e109c8d26e7a73bfbe97d7275d107726f1fbfe9cfcafce541caaa416e3f55b280b154db2555f20ffcf61d6cd1f34e5a8b62afc433013bdbffea74479cee3cf8652fefcace7ebfd35507e73d79d0ef2d17d8070a65ff7407c68258428c2ac21679a7532390973d79f0f2cf794d39bd7cf0a0f366d0cb9fbd7c9ef053ffc12f7b83eecbcec1f983decf7b83ee194ef2bb1a1bd5930433bae6f0fdea0ce7757fefacf7cdee6efeec9be76fdfe6cf4e77fefddf6bc2f074e779f76c032d79f6d5191e109dee867c1c46de3b23c49b77ba2f7ba71379706f6fd0cbc5a4fc6dbed7e988c174521e7406bd81c0db00dd664c0f1e74ba4ba36a70ec12821824faa020749f776b42c1a8eee9ce332ac9e8007b8e5f145fd5159049dbcbf275c5de9cee3c48a71cbcefe51df1f7e968b24792a8ce03a0ee76f60b5ce54e8d55d9f902f99cd4e759caa2a9cfbf92fb00fcf019662f3ef8a58d4edf8bf31231049dfbaac67378b2edf7c57cfa14017dcff856fdbf52fdb483d312d43bb8dbefa6edfbe0c1d246cdf3a563b957a387eea0d7c20d0779effdd51eac42f557ffb99777cb6eb10eade6ef3afb6988bbbb7b7018eceeeee53d3872060ff6ee61db6fdff67777f1380790c6998069dd4fe81b67a341e13f764f77feb4fb90960e7f8a4ea75bd6c8a9354fff59e3a6ee80464d84c30175a7404a829a28b6547fd0effdb4d7ef9e633507000c394cffc1d3bd3e9d16ffb542552dce8bffb347ede6bdffaacfdd2504b74cff1aad16f0972796a39ff7de103147df7f3baa2ef379312c67fbffd56d677c03a987d3c9d9e87cff4dcd822632af5dee07a203badf554fa717e54fe56450cecad9d7c57c3439df6f0602bc0c4917f6c7ef0e6a7f71873521f3e622bfdc6fb3010057cdc8f24ee33e8e60edd9f30382102402a1703dccf25df76c3a7b9417c30faa0e9602eb5854040bf26bb31ee9385c038750ee16cbc6687e10d7bdebcea708d04b5f13bd9106d0a776d743793da4febbee74325eae6574b6770f407f65c59535ed157fd7c8c22ab1a0dd1f37d35fdf57edcd9aa41f9344a477b548ba9a958baf8f9af4a7286879321d94bdf92231014aef7593f4e2c5d347873f3dfaf9c577dffffce8a7efbf3e7efae2db1f5e7cffc3cf2f7e79fae8c50f3fbdf8af1f7e79f1eb77c7c72fbe79f4e2f1773f3dfab6d7cf5b3d2fc6d3492d80ed6d5c5438b91ada767527689f75f34e2741cf78efcdbb6ea2333b35baea9ef7880c7dd9ab69ce365bf1e6163b714e4fdd97bd8606ee1cdc622d066dd6022a24e2172853e48e96e8f6c448dcce3980e37108147d8b3919ae654e2075af7c367cde6b66a3ff6cf87c77b7e9dad95767cf86cff72195f0cd700bef32ec94eb799761e7cd59e259869d839a0a21de6588bccbd91adea555d9d9bbedecc1e9041884013208e78939286bb6e0e5bb051221a971bad8b3224b58ccc1eeee5e1f4998ce41de5bb4f9aafba2c8c7c5d518aa18e693f372f0cd685eedf7bb2fd2a29ee0cdc37cf95d43c27c382bf3c121d1cbdd5abd8c28b27b389d545717e9eddd41dedc686cb57ddd7d5193ddf9bb66d78afad35ebe3ac67a133c59497f9ca3fcb7771bcf3c11fdd16440282eef1cf4716a7bf902b5acd4f45379d6bb85d4964fa3c5270bdd71ef36065b0cf3b7ee0c0f85fdbcf56dba7c5e8fe887d67e1fe737afb756f875f7058c1796a09ae7f3ab6a9fabee8bc4ddacf4f1a2bc98aec0c46a7537359b8b171866e5fe0268be429ab7dfaaefaa2a6b2de0da6ae1886e17c2bce5cfd702eacad7e94adbad8fbf2dfb57e70881ed655a2af2e8ecac2cb6574f456ed7feddc525d0f2a3ebf208756db7b0ed7235abc553a9f6a9735595c7f9ebe9d5fc037ad52e78bb6f4f362d64fd39de5abef5d94fe5e0aa2867ef19492ad50c60a98275d0bdf8f00cf8d7f607ab22cdd54f48f2d8fee8ba9c55a3e9a477ba532ba39273ea0fd257f1c1f4e28faab37a085d010a633619ddcc981152c8cb59c9f6929ba36fae46e34187bd855e9c4ee09b5b5aae3c6fa9b970c248bdb545f7356b6556c5b01c5c918a6841875ffd4bf5f1fb551f40bbe6cb14dad59ed6199a0c3653dc4fec6577d02dbb67ddf3eeb0fb924eb531911d6d450200606230ebf9e89acec17cf6fa4d5fe49797e3d77b4577dc7957004fb3779124e9d309b57ed1798774d020efdd53dd922448dd337c1ba6b751de7b93ca2f11e2f08d3c28f31e1c6e4de7ffbeb6f358ff41aaffa09fa79e8df26ed3eb16b3f9726d1d7fafbf22f542f31dd06b03620c06793d4f657eb0d426097b96275ec5d0e91c9ce56fdfeec188258c789c26649c067f917e27a9ebad659a2e49010689787dfbf674e76af272327d35e1e5356a6d0ff29a4afe399f9d97f3de24df2b3a072ff3bd41b79f44f240a2dc2a06fd26efefbd3cff1dccc4c165be4a239feeace7804f773a6fdfee5de6627df60a5bde796fcd2d167a6dd5adfcde0a8b5d9b82fc23ef3dfcbf7be2df3acf4ef1bf87cf1f76af3f5c373fcb7bd71fa49caf36145cd5cecf3794bbad9ebfda5072ad7efe7a53f3b714f4af36975cd1d0ffb6a1e42d15fdebcd05d382b77bab54f766d324ac53ea7fbd691e6e69f5bf794fc917e351356f54f75a760f377cb06c07f0ed8652b5210099013cda50aa3f9e162f5331adba8ff3df6b2ef0973c092ede2369eeb424290779ef71bebb9b3f7b9caf933737e7ddba0ee55fe5b495167ad4ba075ca15830710f9d37cd638fd49a7dc804f2e4a0dfebef014e4adc45af0f2cd4b09c3416807bfdce1bd9ae0df9cc7ecdbd771755ab6eab9acebbeeb61a165fe9e5af3a4b6a99ef96a77479ea50fabd76621af157db16eceddb5c4cf077f175ad1459f7ed41adfd484a8f79be5fafc6e3061790caa45a64fd98d009655cb7329a8d4e59578bac859ca9cefcba95d9ec22cafae676d631ee9a77abda8066449bd438bf2daaaabd86d4ac79dddaabdb457e6cf01015b9c9f76b902236f800c1a33df1fd34f1284b5ebf362855be471aa1c70b93ed44c2754e77f64f27ed1ca056b1f9c3ba87082c8294fa98f36839873a97f2becdf747677b796f699f7cd54022e9725a5f77deb5c59f0d7cfeef7c2189c0c10da66ff285da6c9e9fa7a936a431b3f4e3e927a31f25e937e23c92ee8614722c3f48db6cbf263e5e0c8041469174b76cde9f226fd13debb5e7804899c1eeee5e01e9034aef1c0c7a670767d44af9153cb0bd1c89e5520084c27a34b2fd7f90baa643fab907a5188f26e5f7a83a4ccb52eceeee5125246019b0fe6ba8aca07ce8c7e9ce696d180a397ba8d4fc85a827a8fbec5dff41af40450acdf2bb57c31170db2d09318cff3f1295769cf7de2cdb4fe47b8825fe236fb485393476dc2cce71fe2c7fde2d7aff910b8c65f40370b58003eeed71f5e7a2b342ac478fd254c8ff3e07c603e5d17d816ea28b39da4a57abdf900416cbf7fa0745af2f9032a48b3d75bf907b6c544ac9d70b89458b6783e7ddf35ebf3bec0da0e91f6e115fc35bfd8cdd61a773f043fe6cf8bc7776406ad2337139ccab72f053793eaae6b31ca6082da1a1d297c4d621b3fab2f3729de5c78ff9decb67e57320c83b0765ef9e24aafa4ccc562afc6aefc77cef76327ed8850f3bfb65d250df2b577b1eba039caf77ef9630fe8f794bf0fd5758b5950f9594f81de6f5fa073fd16f6bae9f15cfc5a0bc84ed3e29466585b0f37dde7bf6bcfb03404ef7aff8f7a77cc934ec696b2bdf53dd0257ac8069ca3b28d55e99a9a2d37004cf8ae738c6e33585debe3d86fc7bbdde0087846fb786a4bb45a7738079bdc1411fb5eafddd5d806becfdcf79efde2ddb8084df5f61d42f624836668bc1b44046ea43cb2d0b643bdd5fd2de3b49bfbfdee694feb33eacf3de053c2643b775166dbfdce28e834cda0b3847001d97df4f07e50149b5c7f95e1fbab0d7caea26297abfd36999cefc17f6e124ffea57f8576b38f77fcd7bcff2e7fb27c0c52e748d096b9ce4b5cef124eff67bbfe607bfc2238d0f0705abdb4f1a7c7990ffb95fcb30f2070f3aff99eff5014c5bbdf853be24bf83de2f32f3fe82ed6d1749298b82fdfe5ee70d2e7fd1effd29ef0e10304bf8bb00dbb3fe5e4320ddebf54e72226feef57abfe61da8a10bc36cefb0f37e6b8795fd4ebb079d03a85ea25ca136e8a88bbf3b1b4df2f1f8f51bec41171a26267ad8ef3dfcbfcff6bfe6ffe745ce6f4e4fafa43c941c7fbff5f413e8f531bd3ea657fdf831fc988c0a9bec5bfa790cafea31e66a290f39fd7e8b3f5458ab80b987925e1f3f825723a582d76f33fcf671a4dcc7df1ee2ebb78fe9f5f1e36f9fffcfeaeee929179247eccd3719362b532f3c356b1e53b3563effb73f3dec8efaef3553fc7b1f90e0cbfeca513aeea74d3cea93bce9651fd06db2d79507ad9cbfb77310cb0ffb625e56f3bd2699bd84ad0110f5f7faa1b1fc6d9abc6836441b928bdd5d601a0aa25a9a56126d95f048bf316f5a6099dac0a9423eed7467bfe97bca68cca980041c2c0da06ebb4e2c445e14e5e5bcfa86bea99048994f8fa7afcad9615e957b1d92cdedc9ae5b482707f93ce788efd0a617ef26d36b43cf35d3d0de9a93db33d1ebf5fa1b7176ffeddbd6e42d2dd28671a5e94bb35ad3a6a968ff2011a9f5a7d038a5b99a941e55dfe7dfeff51319ed5793dfbe55ffabffeef61a1fb6457d493ab932b53d4d6335f463b1712a389fcf46fdab3992a6bdc19ac4ea322fca5e49391757d5fc97aaac21bd571c3466c5f08e9524eb625416a656aa7c329a8f6eca5f7e3aee9d21627b447b63716b8f0df2c979399b5e55e3d74fcbf9779349393bfaf9c9717d1107f556f50b7a952807e4181c4b55579797b3b2aa90939acc1f0d46f3bc3f2e7f4d6e41ebeca3d70322a69a0cf2ed2faacbf168be77bac34e773a221981ecb565b58f608f4dca5738ddb27b4f7573b2bfb8a73aef3a07cf9e9deed0a41f0ef35955ce29e02aa6f0a24e7ade7db67c6d31bda59cc66725197e37a9f3cb47ffb8c22b7ef4c64b7a7dfe7c6d57d351ff4c3e3f78f4ac5ff7badf55d8eb67eaf952c7c933706bceb099c12c3f3f6fdeaacb723cc649c757b4a03bdd59dffad244696c727957b75b3f9dc0bc5dcda73f95d7e5aca2d6cadfe6e56c928f7f2a49afd3b8a84813535c554dcf6055cbd975f9f5f872987f4497963ab1938fc7d3578fafc6e3a7c5ac2c272caf5e4f0a06fd7a0cade1d38fe3fc757d0bb96aae870dcab372b60837921e7e1c15f3ab59f9dd243db0b3e9ece2fbe9c9ffcfddbb37b76d338da35fc5f27434c409ac4a4e9a3664508d13e7d6e6d65c9aa696a70302e0a5a2284592633b92befb192cee24e524cffbbce7fccef9c3160882c062b100168bbd68d72f07ca99c241359f2f0eeaf90b88b37950bbf7f385a80fe4017ef54c7988590acac10ba7be5ce2074b85307eb062f385fc11745689d5eaa05c8bd95b99f7dd547dfb5b068ba9a907c89f5d54eb72a147427b90036b884a30e54eee9b1a1d36a6d2e490d185449ba2c4f9655dcde9b7d576a73d31c163ec0aaa5ace2f556205d19ab1714df10d15dfedaa7839bf7cab7c5b4c0ec1afc13755f5d357d02ca7ef3c253f9e4d2647f17974468fbe9ca31f73c7972e525fd7eb6c743e58cfdf2f16a6ae9d5c56e5ca53af8f0a01b7b7b42a73b8723b4ae94a0045d1254d4b069e660f4ce6d1aa28b3f501a30bf321abcac5d182ae0b955a4a3a65f36abe3c2aebb5582ee615aca65d79475959adc572a5df6961bc7e520223b900f3f9acaca90f99a8c1af694ad9345fc2a5705656d5d17c4159b9be560f004856cde7fc082ad4695b665eaf8f323a2b2b9d9603ee524794ff7bb15aeb8cf552800332f5705de982c68e191e2e153af2ea7a511cd574267472be2c45bd56fd2de6cbf2cbbc5ed3aae3e567b15c978c560750ea88f2cf47573a3d5f9679591f5d1d94339a0b0f359558afc5f2486ec0f0284128eb5cf778469753b13c123537c9596993408d07f3cf6209e36a2235ba9c7551b269ad022597f5fa68bee46279b0a0f57c258e46078b398ca5ba7f5b1d58986088ebf5c1aaa00b1fd4d57abed07041d20cc46abd2ca7429e472ff2c28111663b5856ebe57c2a8e385d1574b9a4d77ec63ccb56626d726427185df88fffcecbda3ccfcab5ece8acb41f7810c9c7cb92af8b03f0134995f70d4873c1e68a4150cfae87a0b41022d365b91e5cd4259b73719496bcb40f4bc9dac8a7f5ea6821b13a3bf87c44e58e958a75c90e3e1f15b4ce652b9f8f4a2ee6f9922e0ac89fd17521665491ce67d07a3812a0e47220290ae8e85a252d19f94fd70797f325b72474b92c818266732e0eae6655bd8aafaab29e1e5ce909ff2d7b8693482b39e63cc5937a91a22e6623dc66a1ad98b2f585dce4f4d3922de79579f2926060af922a16964e5f7fdbced601e53e18155315fff8e3e5e5e5e0f236e85f8ceeddbbf723b43839740bfed5ac8ae53a052bbe7ca8689ddb07e094f76d01ff4378fe7af15cc2f4cb8fb561c97db8d6347d567371a538cae57cb57a05e3ff4dfbd1e8abdbfea30160e2e95264fa2b3d964fe1b252d56086b750795f47ea10405f2d992a6d3ea3faaca978e0d9897efc9f7564a83a62b7d04fde6950898b1f35e58b291acbc189ad45903262e91122c6f2f42ce08413f3716f14f7a2632bb8427035a92e5cce86e7f290faca3ec977b57e1ac1bb97f6092a1a26d9761bd569644c05e08a4199bf70257f926d8fab344ae53b9dc1c692b266f3cfe2c49cdda214c574b0126b2f076bfb02148be6516e4ccf44708e3b27b6eedbb6bb1246308660719412119e14316fe600a1e29b618c84ae1b33020da9f3a9e8f77b436d450317241270ccc761975ebe050d10d6d15586100a84734b609b422107b5420e27b9681a71352db7f6187d795284d8de73862209d9094f94b94afd8501cc7655b988123aa8e71c70882495403028104f34e8bbdf8f344f9eceaf94dd97a4b125e5e55c3d0638587b4d42f3638fa38fedc90e3323e3cac5da9b14a762c596e5623d5f2a631c63fceb4461384558abadd3b354c9ee5ba2fb14fae421cc49af5968a8ede4314c82b2ffe54aaccd4c869238239099e87ea8a62c0472f26f1828cf5c2c25bb19f7863817ebb61dfd81d60d5b17e50aedf04a84f61ca6af49e68a618a763b7453cba2be9809d52e1bb8076bb6b1c985561d6fc3c30188c65b0f921d961cd8bb2565d3b2cefd0ae8e01f185f7827966452ab5b4c5189b53890c3b5db79e479952ac3cde0a3ed366a560334e5c9d6af8d98b3479da0cc6a46f89f0275a44eb6a6ee68d381e97da40e43aa6709058b0845b574a0a9766cbc11c69343e5a1f730a6cac40f2594707b25de934b49940e0cee228ae4b610fb92b42fa956fcd770e8364c1d75b4d9c9d10b85505ae31bfb722a93f7d97fd0b569fb333666311dfc73b9a4f2e4067abd83b22ed725ad74c5bb60e69e04b0a925d56a8a40a36aa10cf330d79b96edccd8a65c51dd60c2c83235462b0a8763fd1b335064f1a1259b10dc98639da150a0cc82955bafb8b94659453f6fa1521b4c03dc3800c7a3ce071a1fa9374eba6cbf0fdbbb2fab488197f1d0f9507faeabd1a4b74c23dd925cc514444ec6cb105cba998d81987b47d8a6e4d2a41768a860bbd509f99d4eaa19cad49daf7dad734173c72fe61ba2ae2ed259b97666cb4b01f24405427b5bb50bb9595076695bd9d014199f020ef41e8ce28ea23e494d0e51bfef7f0248f34b209418fad42360ec4a9b14077d0eb348afd72c150cdc23ff8aed865e6db75fef87b9657603ddf370dd2384cb51d5b8ee01ea3d1b2d68c9dace1abad1ab99b6c3beb5678a030409db6e539f622c01a472b6f9c09274c788d2b14ab4368f221899032d795f384cdebcc074d4c4025c9ffab87684df0326830ec09aead45c6a4bbefdb3b9d4ee1142912202c9f6055df92a5ee2f0837086b4abf28d9d1fa70da5214aad9da83d40d0c066d29903a7b70845bee9a4533fd4ab052575b43137167a5ddfc9e543d222792c27828bed469db95aea1bd23a9542ef102239bef94266afd48df8066e0f8d6a8b20c344dc67e66e5cdcba85d233e555829d8973b8fd03a50a324c9833e467b76e21413a26c20fc09fb173b3d841dac86d7bc07d47411e11088b7e9f9b7c3d0c6fcd6b79c292cbd546dbc72fd388a14419cd0164aa07d4ef01e8339c090d845c44d1069e57aed644b5283a5b348b9b9982dbad2aa9a5f1db6d941299836c0939ca7ef50d95c8d43a11b2eb55f7ad5453e3c6b395365c42b0f7773107968ebe3a21761e85ffd6e051a01967c7cdd046712e3a0071da6012fcddcceb67b33fc74a432b34ad674aeda4178d7e2586145b5a53b7114a186167c3f35d4ad84e6f04a06aa2962946d2dd3e5642e10768271898df834e87bb747bfbf14cea353532cc7a769df5365a86701727e5f9c4312b50c7e2c3906989ef5999b8376ecfc3c39eb85aebabca446d01fb475f71168a7a3d3a767b055ca8be48c9a658cfaa78bfe045be9e1ce2195d17fbcbfdf2e30bba2ee0df8be79343bcfa9c77163d1e0e873fae3ee793c340c7e1a57fc876a76b28684fc137d56634092494377ed286b575dabe1911be57a034502ad21ad192d1bab90a3972e3976994a2afe0886875856cbe14655ebf729ac4e9f86b8dc4c6fbc2eb14ff91761807ee394abf787bb258f4fbf033105782bdaf573413cfe78c568f752563a7486eb4a66e2c1fb5cfa39e7a15dac57417654d876c8ab70059d0fb37cf7a84bc4807abcfb944afbdc097c9038ae8c0e69014f8dfcdeb94bc4eb7db6ee539e3fb1625af53efd3c9e1fdd5e7fc57b09d8759f22a8b90f35f826e4d0eefffa84ac0e6249b1864e572b5066621a1fe0332fc353c46fe3b65bb9ea48de27222d75c15f7df8158c09b2c6fdc7e6317b7a0e9328b58bfcf6081a8a8ceedf76f83f24e3de7e29d523581b46614cda6b80b5619e271336f83d574b34bd85943aa742e59623f23616793c30f229d4ac6f8163d2793c34bf394c2cb17f32fe6cd0c9296e7614acd32251b5a9733b85c11358fdfa6d1e4f0c4e480bcd73e3daaf9e410615b5e996d94f3fac6af9e9952c1b7701576e3776fd5d52dc2ce11b405f09de71b1afb8f0ac41d7e0fba5e7f6a5daf77928ffc33255fa1d6818e47eff55819ba95b5d5398db45ce65d3af0f1e61e7047018ba89b8b014edc230a7bd602c5d51060c87bf2cc5b3f18f1cf7b50ddd444000f70c27ae767532d18824c5f3138455dc73b86fa7d78fd671a544cd23376de7456f3574a3ec821f4b12747f96333bff4e9e6efe6db95a18e1ff49b0007406a92cba029842da0f502f444d4afbee13ce017aa01064e220ec46cb12e053f10355b5e2fd690e2f23f98da5673ca05e7744d757226d6d43eaa9bdd05bd5809d010817f3ab462be14abd5c192ae856e6825c4147443c454ddd25270b8af6cc2f8c1ba9c09e5e9f1e0f3bcba9899cf2e295c1336aed970cae0aa658f65d00741a72fe862ac7fe31774e15105638efd4941421b51e3f1c479d81097072fe802a720ba8545ca3b8d790b27f76aa39811aa9ca3d00a1487d602e965599fc5514a6c1af6144ad284cfe16379968fd281ba547d47f3fe68787c57ddba986f10a6ee7b633e618c566e2bd115cdc7ac613126989e08a3db4a6e4f73c700cec46c5e7e111cd8bdc4682382332aaf1fd839e68a5a5f2916dd7084663e484eb6002d37c1bb0d6b32031760b1d7747873118d7ef905a124d06bf6f1edc0d3f2db4d4aa02acf9b54f340a1aa3420ca3695770cba33275c4628e6244d1227c6d71877b50aa47ce9a9db381102a2cb6468c389687cab4c0418e1099bd7ebb2be103ba869576691f62a233f552965c521eb87c7244b005b1971caab1287f2d49ce87c1ee6a74946b2c1aa4cabb2ce779dc8953bbb06520267288d118139c914951ad4e4604b6ee129143c853a30838b414604981ed94e154a32082f391109b32f0b5258c8e4f0e5aabb85e9bd5ffda4760d6450cf9e063280605f034d04dc03d314c0801dc19ef3b0e78ccb871a53b77ba0ac4cdb557954c59cfd82b10257978eb1c7fa1440c894e4865e7ba1dda373cb401385879fccfcde6eef9aa49d6b20aad154a37ff5489214a7e61cae4613444472b2291a8615aa971a5425c60c4a7dbedd9a14699a66bab56c67bfb68d0eacf4d1bedb05ab8037a94b16483bda93f6f61079739a06bd6eb992dcb43253e46c451717ab42fb1e906d629a680392d4f338a613cd5ac667f41ccca9e95a1eb4ce284ecfdd88fecb8c8cb2e507905a899fba21eef7b5763dc3541d9aa7ac65695399d5d15bf0fee1da8cff79b95a8b5a2c5772cf71d9cf249350336505d64282354f23c3845b35817ebf4707e54ab23634d76ce87cb1103c4209bf750b29df0867fc1cb3337eaeef02d27edffa4c48bae0322e53dba09937e5eab558aea0fc3a42db6d788fbb1495900c3ff54d6e66ccc949612b9a3252b268cac0588c92294b0c2215de604c2a06c433654d09d14f8aaa32b3ed5052d086c30c9a84bafb7ad6ca3d74998bb5847ab5649aabde6e159f0a9e62974bb15acc6b5ed6f9fb95e1bbf5b6bae7ada540b54d9b63d5980e1654ae227245893ddba6b9a190de3bef829392c9a164886e199616ac24cd3920494118f99563014e4325068a27877a42c3db3dd6f3c05087e69c0b16b80afea4103858cf17cfc56751bd0327de8a206a70c2044cbfc9525896a463728084d6f3a5f130a3bcf12e9825e605ebf2c7bb6481d1852d6ff678f91578291621683411cae8f0edf56a2d668f2b9aaf084f44006c2abf729032e7c5515fa2fb55c614372b8c39f6aa8b53ec2a8b19b63d8ecfce03625c05bc90fb0633602a81309844b6c319608621bd41aab580c93920298ec38ec209f7f7af79bda6652d96cfea6cee9881845b8e965b9e21e1e4764f57a398aabd35c17eccf50694aa2d35f949c913ef9a5b9d36d88cac59c491b61c6628b869685206dc396c804d346fe4d94c8db79cc8fe18a2049cbe78e364fca1fba5c0bb6273f4127deb1ae55b72f78e73225818dfeec3647aff65e8d25839b679097e8dab7e3faa48159a1d8332518605ce913c02146452972c2a7085d06ec6a2c25f152f987739d663f2a80afb605bf6c996f3aa9a1cc69f1968609967d0800b9c43836983d3284aab8ba5fb4cbf84af74962a0039eac464b394af4293693e55b941934c8e52e5da642a4e560c8b5cbf0f0dd136a4650d616c3d6d287d696a9ef5a569acbe328259e53b837976e2fdfe63e577cd1cf994f7537d84bf64f88ae16b86bf30b93d9cc8550d3f507b0d7ea87f4ff5ef23660f908f5df2097cf394815cea6225f8fcb23e80d4c5e2603dbf608542814ac3a95826d4319b5e5c310835cad34a25b462b4fe463f419d3a7db138e04b9acb8ae4afaa872fe78b03369f19d561f9d67b5485a6e21a2a9a8a6bb05592898bc501a87e8136b20a960e2374a00160f3c5f501bb581f2ce86a2d0e148cfa14af5dd5cc447d7100c3716006293cd63f93b801123990d4a3c15f0b95aa04fd2c14c2e69fc552a7648baabf9069d217eb837cbeb63802238e836abe6a643520f0d9afdf982f9b644c32884f59a7eea79d803b943cfb6a1137717f676d23e10d78aa11fc551d531cec1b697bdf60dbdbc7c1d621b05d66631e6c16cf75775a8b42f754d7a41dce353b1eaeb81d98c961fcb0eb1b3b5eee1b337093c3f8b4eb136f3cdd476e602787f123365092c0281de817cf786361680dbfabab8b0ee2c79d757acbec0b169a37063e80826da2270fffe630417e6791fb0afbf7bfe4a5a42a2feb4a3eab334973acb79e06993faeaf021ad2a39bb646577ffa8091172c7ac0b0fb063b9b597f7cf5070fe183877b3ef007577f700a1f9ceef9201c5a233db1e84e1ea9c537c32f58f44809e732a4948dbd0a0d8be9eaed1a6c2308f11bc08fbd061eef6f00f786cebed5775ce1b15c6b1619ae2b947fe92583c392e1dbe5c2c11b781d0c92387de142048b982303c9b1d94580a4c9727021d7e5b412ff2c2fea0fe5ba78bd2ce7cb727d1dd1c142277d1fded7b23aab3db2b3b1116e2bc19e2f9ed0f2b9b04975a90382c47dfc9bd24577f73beee350c2f707f35c3bc1c5b72dd9d4c87c03e8f4163cdc9e04983a3070837feb1801985e893335bf9288491ad835a36c482a08186239ab3f1417e2d6086f197fc72225ba02de2019de3fb1ea31c6e7c4093b1b9e27dd78d85009a89f93b813ee2588871cbbfe3fc79341d238c0437cc20660731759159507acdfff432e169201d5fb81fdfca17af9105e3e6cbc3c552f4fe1e5a979f9c8ed8c6f194a1e078f5e940866c23838f08c9e414866f80bdb6e01e943ec4d12e3ebd4fa2ef6debd9c2f67b432f307bf630dcdfc3f815e9d738ec85dc5bf070614c9938b37c268f39e4530ba983ad65f39437564c00ccfcf2525b0f384079d037de246e7d0ce1f87f76ad10ed0ff5eadcb01d6dfaba53740761ae03af50f4d4f020839792281c3df009c121a0e5d05704df104f0608c2c7c8246afed1217beeaf79f38c253acf60746363bfcd131ce7fbbe40f8c9ce91b2e65a2a3537fc943080d2e6df1c720cfbb92c57f076ff4a52b8623c8a2a2d726fdda4b7b7768feeb775e5678b516643d7459fac6ad9d3637709d4fbc9d5a2eb57dbe4b75ec822af7b5ca7de8e52a43e66642ddf6798fa7e1a3b900f4b25e34b356169ff2e9adf7d4e6ba7476077cfa32b19dd6978bed077db728d375f074a86f1bdb6975fbd84abbdb48fb6802dfe11f24edacc3cb773c39b417957eda937b51ae5635b74234d423c9b1ef690a0bf9736ba4621181342f1267c3867df52ded33381a21946464b3c72358bc492fd2b4123cceb0c63c8fb35b93438bef1df65d69c567fc5c9d35cc4219a7bbe46fc539719ca2e4a3496728f9c020f49a3c6c50aecffdeaf8664e86fa479d08f57f3839aaffdee150a75fa8b43c509a53a5fcb367607a71f5303c0cf3f9455a099de91d7a1f350ebf347feb8ec1f04f1d37d57f75c035ff41ae607fbd33f169f36cfcda3b244fc5f5fbc541e3807fea1ff5e1f7fd421f94cd7fb8450fefd2bb8ff80ff71ef84fc3c3bf4ebd5ff8f7f04b1b20429fc4f579dc5dcfc3ad7c0af6caeaa7259a78d825a67814ca2b20a9701d5ce8ab07b31e86c7ffa13c7f030dc9813ab0ff9c08e0914d89ab528de7239350e201997a6e5320129089575660309b1b21c20b9b9a5fac55e295493801c32b4faa00dfeaf40b2fed09215e75cb23a016256e333feb799e57c2fd5cb002ea8714d47e590851a9ff4d548d504279f403c3c78ee94839991c5a758b4a304fcfc313da34853dfb854166090c9b665c2e5dfc7ecaede2c56fdd427a7948f919e3e76a286139e3c463bfdeafc4f281dcfacb3ab74c98088a348e383803dd6ba756af85325a1a38f218c7cf2cf4e1fdb73adea5c8b893723123c7c7b18999378c39c9b9175f24c5234c0359c228e6a4d85bc448143929db65766c4c079473e0bdcddd5894620e165ffb5ef9bdcab9bbb8e0e9769ba691090054729c119e26dc7a73a32904e653c5ad2bb788a7441e729533377703edd52c78c4390e3a601d4e0537b53cb846c9380ad9e17eff6874ffa92f56452000096ac427f68a46dd28a8eebc71573481a60548aeb8b341ea6e41ecadfe00a24cf925d0c6d449095c0c711d384bf9dacfd3680517b306817069d57061e941bb61a46611d7d7132c3cf3ebce71ff05744b4bbe2c023222e016c4a8e964b25ec122813a7c961d30edf93538dc2ba194e838df7bf78ad0ca58dc7cb2f72b374ae7cc9c4b2cd2d85730165ef7cb4efecb3ddd4bcb92abd843bd214ec1f9c7b319cde552bc12cdccb792db69e47d28f9ba5079578f2b71e5259f2ce7170bfdfc6ac9256c368bc98dc8b5ac1e573299e94a3255c3a549bf8665f1b330cf6f8b65594fcdd34b9153ffed2b0920d8f22e4b7eb214d4a4dfa81a75f251cdbda7b70b5afb8fa030aa9f1f0284e193f7b5caf02bd039a68e6c5eaf3f806b0df95495b57858d1d9c23c3cb5afb47f12489a4ecc978b822af4ac69fab6fc02fdbc2cf9fc1232bf80d30748cde73368aeacaa57aea6490d7e71bc9cd57abe081e97f3a93835fe56c22ce571c5e5bdb04e555c5eab2e43183b3ce5c4531ac693c3993a3180a63006af08e7891f0bf35fdeedca63cadbd9caf2f3161db0822e4fd6d1103598743a585da4ca463f1aa1e45f7e969e937fb90aabeb292656bc33a066da0c0eebdc027af15527873103970ece32ce951b2a63fc7f79538b95a27e1f2019ab788f291aac97e52c4210ab75710511de9df60537b66754a90d3b79c74d8ab2663f568e1ecdba3d393c3a92ec8420158f184e41f08092c96156cda932483066336cb57aac3251a2dd2eb8eab1403178d415ca4f69cd491d6de469a25c8b190cff86eae997d2955a3d967acacb1f314b05cca20272cb590e3f92599289a9b8ce45ad6709cc76790696bf0bbaa440ea36dc375e2f29833297d044a8633fe7be8ebd5cd325e6b5e78c9e672a659cbbeeb7f96a6a9fddfe5987e3f53531f77fee9b95592bc1b0cabb5ae3aad7e96d7e6fd5fdfee4f09f7f94b54859ef2fd7ecc1dd9156b03360017dc9dadaa115f4cb660dc70601c136bd7048d7e1123c0294c58de14a3b48403a2857cdf00093435ad773ed49eb6ae65f57fbbec55cb6f6ffc5bab28ec0e34c3bfb6259766567f3e58caebbded4e0c2d15eaf95ab5559e747e0facb79461d35bd920ed584f9c4c98b14423ab9a5686967fabd401369bb1d8d1aaa4971c3fa36b1f7a51442c482ef8d6ec533d02ebb6011e896d12054f08a476813b80be15af10a8208745a191995a6b14968f346d41572bb334c87e710998656c4db2d1da4737ead432f795e9f55b6a78cc14d50ad0402b707f638a14d8dbdce734718eedf39435509254387bf8429f5cca6dd0d27f416f3ad6c0c8acb2ca2f749daeff35fad66f6467e1733ac77d5f488ee124af88ec60a6edd068388d56f95eea66446830c13bb6027f39d7ada8e6977f73b80bf613d79c94397d9fd7e3aa6b083f5863155e6441e71f54671aa325397a9eaf09a44b1721c4acb7aa58cb7c6f6fa63a57c0fe9908886465feb03eeb8d78bf6be8c52d41fdd45716f1478e6b8e29193e251a214fe704ad63c42497a506a2d47495b03b9d23d7bbca433434609da481a331120bad61ced02f58372d45ecd9932a2299622d3c407078ede08d49611258d4fb47aa656ac92d3c67a7bb70c7960c170cd3d2d3249b1c6dd8f9f6ed860997ac0e78ff308a49e5554226568a07d6bac045db2a291b9165523e762d9cc59d0d5ea72bee45e3652df5eade5aeeefc0c29df2b50aae1455629d87ee1048ccdf1894cfc28530f206b3c39c40f21d59b1ce253ae5578b83618b78207be477f22bd58af7d8fd41a1d561d092431eed9416ed6e15e3ab0fe5d3b2f9d9ff030707ad079157f68613531e1b99e2bef482ea793d42cbf11b812e97cff5d3c807544f195127b0b0c140f0103f794ef51365d89f5bb7226e617ebb14b1a93f667fbbe6295a04bf39dffa0bf7423fe9b5bc9b56706f00b1e2c8a46f9d2ac4e26deb0f170ad341c775d8a1bbf9b1d6db0588acfe5fc62655656a7fa3f4ca85a8b7f09164667a1c9e91a4c3f1821e40bdf6ee5ef43fdfbc0f98449bd50e14747ea582f8b9cf07e3fbd756bd70145707897cd3de7e4055d178325adf97ce61bb1debe6bfca31f23fc4222fe9f7f20ead6b35ab94f36aadf3f4c0e6f3de7f8a55704a45f2aeeea72a5dfbff2de3f34b209fdb1cf50af7dfdd7b317fc5cf9abb0c6019e418fb75d98ed2d25ecec153fdf6e99fc54392b6899f1f48861916dc40566e99b697b0b153202c6d3dedceb2d54c1e58436ba985b88296149085fb7a9d44ba3782eebdb6ea904dde82ed0edf6a79eb6eb52eab33a39baedd23669cd9dac4e0bd73a1a3f19e3306560427d03133f5c47c336e3b6e4b99dc6070f5c02bf94d036ed3dde40193e3f70c1808c355bbf6fbbe2ec314c08345f3323e0947ce894d6b3cfd629ceb3a25a02d7e3c15b46e4813cb1019d9ceed4bc860b25cff19eca78d8d4279bd7a7eefe694f76c7472fccd55067e6be0f5ecc3f7767eefbe0fda2236b5fe1475afd2be2a4c7adff12b4dd82dd027859e210a5c66c7b6683f1fc02aa1dbf32fb056d6dd8ca58a3c75bf1afa8e66b5a21e01acef83c2f7dcd1033b7477852a7d8be7656599ec20ef73d3711a0253630862a2a92e5bef04a67e93942accbe0a56451573e4e11665d663061799b0f6254ab0c63e6267066df06a11fd2970efe09ec02cece933441cc583ce194bce1462524b5ae5492e1fdf4e82841ef78c4ced2736cdda0f3c9a15173919b53eafc00a5b76e79c5f57d33940e0e007f5accd37e9f813e55d8a76698295093ec1ea066515094ff5f1e196f683ea8fdbb635cda7d90dd0e4642dd8778b5fdc5adb9d27bae38d68f9a15fd5bfffec05b266254a8b8403fd825ed07aec245e394fccdb1dcd3d400618e05b13ec9cafae0231f7fe4daa5de47ee1f1d7146841956170d89f5fb60df4e8838a3e71013295126a1ec8842394e4609bf4f7259901d7155343be2e770ce4f2c80c4682d503cbacfc7a323e3b8d08f8a24ac5b8fded065332f3b6491dd650c84f90847c40402f146c0c403f1cd78e4f60c99be1d1af03019654ed8290eb483908ea86a91f1f33496159d897392464c1e5055cbb0fa89b18a4aa20203f3d89464f23b0555b93a552be2eb25e861084e8caf24e3dcc7be19b7b36208ea62ac7a952ba2712a62264cf56d633fc28ccf570864be9bd475f4c4f3a6ba59a8da3560be374f85f126c0da8ba646a98767709fa9f84d57dfb8991149ac5d98f0815e6055bf575091f74c7a2384f7613015487924f53aef77e346681bdf8d5b39fbe155aa130f604984bafc0cd21b5a883b0605605e2833c916ca7d034a928a1df63362263017868cf7f4b393d0e5fea9967845e8409fa972c2dc9e34ad89d535ffdca79dbddc3762865e3b96e8303fb43added50f2c4f5876cc03d36aca10a4e950e027477b8b785aab41e94dc69d5576a6b5be92a6024c17baeaabe9c89b76b3a5bc46ddf480774605f6fb7a7742d06f5fc32423bdc9abe5057b97ab7bc5899c75d32a99f0cc4d55ad43c70bce4e9aaa28db7527a6e7abb43ad6beb3f999ba46ea213eed2c6564e5c1ea4491d09ccdc3b94780f44f84f3e59c9e38d3714e0928e7bb446653dba5b5c27120eb67d966f93cf4fbc8b32210225042005354cf379d5b0eb6cbc54369e8af66955793a014d9bcd03d96b59d0b6e5ef37993096b711f5657ee09bb9c992fe7c0f299f980629114a46c35f3be1eef79b106b5b56e77144280b5a5b44327574900b78109c089150633e4d3201e39c0b62a827da70bad6072a848b7d2f4a41ceeee1d16d7cfc33be7d7c8eff15e41d380e7be814849afe79f054dbf2aa9246eea8621e7b36c8fd7e3415ce04d92f67f4862ad3dc3b71b56eb6d3eff7a602cf5491a8f7afd86ea7a2dfffe5befc3f1afd4aa602e15a10259f1864cbf9ec6141970fe75c44b78f119e0bb24945365f0ad0898abfae3829cf470fdc179343a748d978b557a77272186a5ac1cdb3d122547aa646494be9b6d2d55a4c0ecf77d8fbee51cdbf11da87c1474d80c3b7fb60d6ca9c0d0db13dd68156e5b1a13016c0afb411bebb075689b8ded70b28f1edfdb8d1cef19b7aa21482bfbf2b5691785f4f54816fef8a769bf4bd7d916c05e98d825014628f881baab202eba3518f9052d88bd4743015d70f61eebaf2aa496383757c7c0f2469baa0574e537f601ac80391883648b4165fedd88aeeda5218912a176b5a5636546347bc7458a0406d5ddf18b9c54fae3f2b1104605def434d734e9b1e2f850d9f18f4b3cca2dbc7808bcba2644520e7900332b4ce5b2d96bc65c1867300d1f99a624a08a945bfafdd95c7cd380f8a89f177ae0b612fc457c2de7e37bba1c436bd7f45bfafa9621c51228f9bf218fa3727e6700a78c21429b5b1167af422160702b72ea4f4a274c0d6cbea7771bddd822056a766624d7f17d7e0455b17e8f74d01ed7a9b1574d9ef8feeab94e100ac1b2a99a9fce30438efda1d4c915d07c0fb867a067a0a531d6805aeec2a3d1c6a94f68d89a4b3cf826c5c50eb782e70e00620f65d587a41626477fe15288d6fa4486d89a1ed2ce762d05c89b5002edddbc5e6578f6a7ec3374661b8f5995ad3cc97bbccdc11c345c44a8c81c6c05aaca34179b0b22b8a32483a3ebe07075cbd9e747c07dd4349368e82e1617a78fafd6825b6dbac47babe1b67a499ffa8e6fdfe4a7e27601aa038fac809c77ff36f95aaace0ac87704672e1b8b528037125e8ad8a7106f442441c09b2149e51287451bf4408ffc5a30c614132146b8e2ba2a412e3b5c2637ca17ed1384a49e1b73617038ff1310ab38a4c0995f5a608c5da5976a08646c4388d75321d8bf84ce0f47cb7c397826c40f725ee0d316c89fa571e7640f3efd03c1d01ee27874aeb8a96a07e359bd74a7d53dd402ac52a75e92bd310b00c94ace00a1994ac44a57eae4041cbb473b184ec4b21a6716fe8c57cbf12ffe9057770b73deef52ec59992819fc7cd2be8716f1883484ab6732d71028af7dfca1f18fbb0902980dcaf7102dac50298bef8662c1e4370b1681a04b4b80187ae2fc28a68c9138f74aec5407d8badd72738fa199b83c961f211ae584094e9945b24424e1495e207a271abfe10c606dc3ab96dfcd41b30b89c92abdd75eabbf172851fb9fdcc41e2bb2a536e881ec37e0ee785c782cc99d35b90ab4eaff32cb2dddebbdf7d4809f4fa9e88086d4ee40c3d11c078b00216ef488ea18963658d029f0a24d1a031e2f5faa93952daf504eee0fc4058fdfea9881e088420fcfe1799c614834f2a84798a008f4aa3dcd904fc40a387c2d7cde65e6477d7fc333becd66900f8948e64f7f08920a9049be11308acf5d53ea2d8706e6ac596b578aee35d5f5b84696e8c34d3e93dba1dc08cad4287e750232006751bd728ef1b6e3ff78b372eb0ba48497daee6f88b70e3be16f89f7205ab2a20e6edc562315fae058f1f7fe3964ed2f16bb9fcc6fa2c9d11e1ad5462df4ae5211180cdc2cbb80c2ece4025d1864e434a6eff4858f3882b1129aa7a2c504e9eab179b9cfca6444005792660af8e7ca01ae1c0b2af8503131da1763440fd7e9493df95a5430e0fb9f2b96a30ff4544b912d314fd7e11512c708a9290c4224a44e8bc1ec915dec5fe91f07a7a2eaa6d882023b07b8385f6e8bfdbe197be74e473292e95684e9d2e8ca46452bf12647352ade3c9a1624b2787f8a16a359e1c6aa67572885f88358d27879aa39d1ce2b74599c9afc0fe19b2bc75f8b5b70ab684d296b7cd855c91caacd45d1eb7b3228ae2889257e28c9ea371af979ed1f340a5ed0f77ab72f05a68fa7e23c810bf95ffde018bff1efeff29c84b6131b28218d57f29a4a8878f5a305a95a25effe53fe8370b9a8bbf5cd2945748d2356974a827855295d6a8530fcd7ec67f08ac6ea58da456a6b5a476292aba16bc29ecf5a5b341110881238f065a730fd662e7e96f4c07ebb94ec74141b4c3b3f96748fe15b40313d5bed25ee66de3f685f1862192374236a9506c06fc9d18eb43f20cd400ac56dcd8163d4ae3611cc9411be2a107cdc7fdd07cdc07cd472d8d4bc95b91bc75f07c34f0bcff2a3c1f153cef0d3c3b843f08f2a72322eb9b450d1484c35549150856d38a3c2a5e2cad18bfce45bd2e69f53acc2f2b437432a9896b7d59ae4c35aab177f642a05cbd5e9633babc36b3f92f413633ab09116f9a97b9715355a225e673ee8d70e021e75c8ec5c54a8079ea4d153f57fe94bea762ddaf9b607eed15e9a8dcf7af841b8e7a5c0337c1feda2b02b2baef6b62873f865bea5f5fdb38b15684cb48800eb38307f5cb4c9c131f89cd72260f5c82f6fb43424824fab78f955a41637560c19cdf6e7b79bfdfcb420fbe840fd45e0e26a73c8e644ea02c8fe4894f076b29c5e5769b694530a5cbab5901d81561cae6e0cc1734355af0d8f5088dd74cf21140dfa14b9cc239254a7b84144a712c758a63caa970aaafd1803dc8ad3fd5dcd72434995d180d076352eb7d6c4afe54fc4445fe12033717206f66f38042216f61c66b72b87311e89ae3d539d6684a3e080c0df9a48b675e0e348465233a637298501dd0301f67f16b1ee528c94c88439593a2a42253ef5c5461cd9954ea3cb4b83539d41ed16496bae5a749158e1838aaf6ab99997b28e6aad1beb86496fda8510d4d38c993050157c8bcdf5f201a6fa6842733b248726d3a40c934a10925a07787f25bb7ac51414a66499a682d20446fdd328e5df2239aa0a9cc9f229c1f1d997c7a94276826f3670853932f0b00814e0921b3ed167e3c27f846cf6b52eb2a135dc56eea199aaa743223ca27f5949c9d27bcdfe73d426609dae484772a68e6fdbea4cc99f6263a5557661c255cb6c1d14e29a79c9d278b7e7f612b5b7c4b655c55b640c94256b650952dc83059dc9f1a2599c5ad5be84f1e4dcf16a1ee937693b320dce9552d24a6fee41157853dbd2a77e3a9579ebb77d0f8ac3a8fcf2acccefd13fadf22b4a2d09af7c31e4c86d18f3263f4638ab65baa9c48c9b9ae8ec13f883d6ad1dafab15c8d6d2afe5b609a99f0bbee7637547bf14fc26966cf533f28185d445598ba6d632e6a2349535fcd3c305f3452a7d063980d0c0c169b14611e64a855cee8a7815bda402edc1b69a5a561c29d1a1bbf750b812f761d4437553eafb7db9eecd0997c38c7a9fa45ae26cf7718809691afde808e46bf76df80629e918d3ad07da3f4e8ad3efd85d22395fbd57b24e77cc5f84d5142a4507cd47658fa358112166ae1c499fecdf56f9135ae9dfecdc2387276cf4cc7a9c54c7c2fb4024ae3b4617756665191196211d9762b3249453c62a8a1ef2bb2c4933be8bbc5b23e60fdfeb52c3e6664a362f5b041580c8b9afb998f6abe8b2346221602d3ef3732c25d5ef510c9d5ffada92a4298910dad59315f829f6f36700f58255f29832df3463d62182ffd894dab5cfb81f7e4c24ae659bf9f66519e6186d47d45946784e150eec733dd5f9c6558b9cc37823f2376c0c60f22111906f11fa6464e32cd02a68e675f65ea7086368264db6d14f24f212d70470b3c6eb255ca7235233d81d086c61b41183852c8c81b3a30532371512d86497e3f336b40aed70058e9a2ec2c3f4712a0dec89abcc9b3cc4ed6be93ac62405d4d314efb4acc78e4346297c07849b48c974446849c43a99940a197537d3b9a6724cb88e82ae15fa9cab9376cb85d762b40e31af66211ba790d2ebd6016e37fb348f12cbead93b726c84eb24cefa593ba753ddc79bf7ca06b0d0c2176b8ca3c598cf52101a70f58574445172bc1df952663b11217dc1ed2f5f16ee6d7c2aa7291cee912bc9c7508054086e84a38e3c2e03b35d061a63ce6d6992f2b0905100a1ab7a5cf83280fe69a1ca4907031a99b56c103741e1e2ab9d7e8b60dd833ba8d504c499a8c86562636baedc20a1cdf070e01cc2cc73436fbd522239b472b164f0e1fad185dc8d3dbdb056522a5cb18d673fc5c80a0ea64b99c5fcaf4e410bf5f988cf78bc9217e0367759d030f93437c3abfac4d9e3274c0a7a28a2787a7e0457372883f94b2c0abb7201eab2fe2c9e143e7036c72884f168b552bf32d78508a27872af17ccea6f2fbf997d7cbb28669f3bbb88e2787efeb928b7a5d66e0646f873f6564f34b3c397c40d91482004e0ef1bd7872f88ea693433c3a960d5582cae3f1e8b6c4863e2b8feecab68a12fa3dfa59c3b39c57f251567852c11b59d76b0ae7157c3c8cc1c1da4a4377fcb38fdedbc71ab1b76fc337395869e0db77f49346d6ed9f000ac91ede96303c9dcfe0eb9f1b6371fb97602c6edf6b0ec49d616318eec89a9fd52b017a3577eefa6332024c3c1e4152c2f7f8189212b8c7b72129bf7e7c074ef923c0cee39f205f02f6f82e2425488f7f86a404e7f12f806209c7e37b901c41234348ab06a1c5636871044dde914dbebc98691c8e00ea60d08f8f65911742cece1d5e06536e2aae9b322f985b66a22db233783edf6ee157f1a821d10401ad76665970ba0b4ee0155102b318ebe965c927ee5234a0a875ad6dc5e3decd87aafa9306547e792e4b843042d8de1d36b6c2ffb944752916826a4999ba27df2f6935ab50e7b219e06752eb6e007ae2e10eebaeecfbf45b5062f121eb039d8daf031280f11fb5b4437895f9c24b4ed714e215666269b698754084ca4bdeca573f7ee767a9ad9207797b07e88641ed18a31dc217fe76e75f257ecf9ef939ecb2a8d6f4af4e6cab574ea34a959c1c820bbb53fb7252d3f1111d78b97210a1f4c7fdf57e0cebfd18d46b5e06d58645ba4ad876ff36173bd59aca4398e9fa65c8bd7e60df7897f7d10616044e326011bbd4eb3c4d28b973cfb3d6a9e52bac1325cbac93336c709d94d48d72fa9a54367dac7cf3c2bd4957ebc601a7c7176a079c376af079f7037b194c2f26c0fec00121af4ac9a4fe53b423147471ad37073010577ec0103fa481971582629d8afa59733512ab06863d079a9e1f00ed3db39113a2c939d4848ad741c57fa5aad847fdfb771a535205457e9059170d706c14184a5e36d0a77d4dc6947c6e52c97c71ed0d843f5046c78f9259f63f0bc11006096862ccf378daca0cd116c48af886a0127a064dea0fa2e1d49192273bc991bbe3b030725ad09572b1ae7672a6ffde0a60391c2194fc4e898ac5e684686001a7644c93c3372a169858c2aaf2babac8cbfae06d395b54c2cf7964c5d87eaed2120abe8463989fe3e9a77bd90d990d4a5e50ed5bf22a232f595251f2074f66945c65494dc96b9ebca5d1a605577c99e14ed0e28f02b7a08b5f08dc02309e66b81bc6f8b3d82998ae3372768ebf64e4c8d3cb7d2a97d1e1af5f32b8af35c116afb3b32fd939563fda557c76741458703c5342a72fd9ad5b892e682b485c554a6c7a9291cd0eff46363a3b3ec976f877f7d81bedf0838c9c649e6653161aa81bc318b980c166121aaa9f64da4cbd61cacefb7d3e68b85378a163afbeaf677435152abcb73e21f957347b3f7cd1fa4c5bfa6c763803b1487650d6070c89b3ec9ca46719c8e123ea0387e9778195ee2fdf868608cf1cc769eb18e56ee61555a8f4f62a25f156faa532ed8ff96916a1cdd3e877943c8d7ef3f4801e659e3df86f66ec7b849c64cdf97cf717849267d16f38953fbf074eab1e67a1035a7f28a9f123f1b04102dd66ed5cae383e4a9c0b094e5a2f23141aa78257d65ea40d555b4bd22ff8198d52a40e12da60d18baa7200465a0c6f76e044d6aab9650aff2119808acdbe8115cb3c1cd8edf6244b1e64c4e2185049152a7f379928e98ac5f1f406ec2aaf0ecda1ba8750c2e4b94c0fcc830ce1fd73a2052ca158d20a96b482159c2806ead103af8427cfb29bdc17ff16bc6d86a6c0bf07afd58e675f3e0f6b169f2ec46afd9a96f51abf085ed5f34bfc32c89104a2906920817021f85550ead96c267849d7c282fb3afbaabbe63f82228d801a6f8297cfe797f6cddbb0655eb946dfc1eafa3ec45431bfa8f8c752541cff69f4c57b843ccfc6cf33df5873873fe88b85bff4ef47104dfe9d91175984f00f19193dbaf3ebdfd9f845d661e429cb1cfd9ded02abfa3cb2961e2fb3086946fd55660494f7ee290ee7b5cbf945e5fce1727e56396f5cce5d95f3d6e5fc64198da64f95637064e86ed67239f91a27877bf74c45af3255f5bd5f4cce6b93f3b3c9f9c3e4dc35396f4cce4f26e76df6ad00b1dc780804d0ccd2f14ced7a9eb562eeb4898392bf99e9ec8529cf4d745742c8876c1c7dc8c8193d9703fb5b16bdca709623147fc8ac7767a3149579eeb2f3c88f37f45766ec9dffca124d20c9ef19a81be75168d2a9bfec7dccac879f0f19da7ccc9c29bbd2a855d2a30f59c2f2e8de3d3ff29272fbe71c1c5213f78591f48c9e277c7ec0088b7a43a4fdddd4c6adf36e87124dc8dacd1b431b350616967e5f62e44366dc27dc1a21841566f21c619658155f9802be766f618781fd4846d6c86834fcf9f6cf7746bf1c8f8ea228f29ee8adf4c7d110fdc8b643746b84fe2fcf794a99db4b5ee5fcc2582fcf172bb44995896f8a126586e5de85ce62297211f7cfd879bf1fc91f887de179470297d1b9e3b39449f654a9a4e04affcef28656792d877296932a27baac3fd0f3dcc9daffcded4ef434fa37374aed837f34a736f847bf56ee05bcf8dd8bdc05f4f0bd3e197e2f502ed03ccba3ab45a96e71df9533713f459df924355a3be020a5f34b5049eafcd6f93cff6a25684f15be0b41e7a1c9a3a64fbaefd39cd044e11906400db9bb65f6e2589994f67fa9b00bde1044d0faaf7093b1ccc12f42585a2bccfb01701d29ce72d54e6fa422e90d7b26bcda1e9fc896d8959fb6594e284e89cb4d52b2d14410533c4f5762f959f007e57a15a7b896b9ca2cdfb974af723f26e0b41922fef650b28e554ed2649a0768229b1007f110fbfd8e53bc3407442520d49a5995c43cf8a323a9753117522ccca0751ed8325ee4ca805c596bfd71212e04d9a4742594dc900e669a258267709a0c858cd4912e058f3712fcb2cef594145926d8da40e70dd1e7dcf98cf61a4cd2a079755795ee07c9a63d70542ea40d5474a012161e3ad0293fece6a585a989788a5518a095508e2b2014731e0ff1825e5773ca8dd707c5a0690d3b470b760c604c3c2395ab3d58f002c269b7da007e62bdd62924279aa6d838d5c31d473aa57cb262a6f3e502a63f22693010d779781e75eb935b273ee710903e698229cb5b5c3b60222f9718c8b049a0bd30fa607dc99ba2d3b06945bb263e821bf09c088d2c8b244f89cb670132a3fa9841fb89fa216ae2247afe14bb8ce449b34ab5aa155dd82a202873e1c38afd571e6672847601381614a514293ceaaec810cfd4aeb6503f5756fdd254affaf38514099f6f72f2a5b18282a6e67d8d4ed6a6f166f926c97f1984193003be40d04a330bbe0c74ca4d852f0393f427842695ab71b420576452338a67648ae22b72a5498326f9af2a00768e605533d1fdaffafdc8166bf6c12dd3ff8bd0a3e4248f72dcac11253406dc9e128ad7e44b22577446093382fd35e8d06e74e89853b236ed358ffb4efbee146da6e454890319c5539c23ab6c3225a7d64f1ed4793b3ed5abda3b9a132fdd3fba33bcf7f3f6ee9d4447b6f1dbcef728fe9d8ec376e3536f4bcbb75bcba6e5568b73aa783c1f4ad5e2712ca7ebd0462e7468edf72775441da85b72fb18e6b05e9e4d64c07c6cb3c8d997f33857bcfe1784765fc817356b1c785fb6db2f44ce08504e6ece5e5ba7d63f813df30b09e63f36f31f7b8b0bc9488e3bd7021d787ea462640265cfc834d654ba48bca94c66895fe555f2208f2ab93c87a44caaa4b1e19269b06e3ff40f500637894d3557078a9c733eea3be7b3c1e5d2732c08b723e37d2bd0c6e5ab8a39118920ec06415553ea726f84394209d7fe75d04e79993fcdc9820ede804b57c59f3c70fea1f0a39c44b5b83ca074009e306a51afd16029b295e780d9db2952d2405a228f55109a8e11b33f79b4cbc669acce25ca703544388308fecd9101e6d45bdebda1b5b29fdf72b229572fe617e0b6a97d7509b2b250def4b84cc5128d398b2892ad82ec58d49f64136fc55a313ce1b5a2620d3aaad122e3277984b020a7b95da9124e9ee611c7140b94087229d332655603922656a2e2f9b3edf723e10880a104f81681926739844bb280be118b8a32f1bf0cec9ae664f4df03faf17cc9741cc700e69b21660a621e403ca9998499610822c525cc7027c401e6630767ea9c614318550b67aae1e41a4e16d860ff9efbea90383731578cbcd35c8c772de892899c5f54dc4e24d5e5f19efc884303b1e702acdff71e06e5eaf5c552a8996b3e1df752a5a3b7ddca94c0198a4369edf33c94d6f64658107dc991199ff54a0c9e74f9677132986c9c91551e65288e04791ea568fc208bad0019f3b0b215ce48a47c93f408e1de4d004763b89311283ec950922ab76611c3597b453063a650ee55a273c6fa57793d31e79625f92d4fbc6122699276d115a1ffe3eb941bca775ca764de3da537462fbc15959aae25dd54952a671835d82655d51bc144f95980604792cbde976a5eecabf3fdcbb7278f1ffd7363d55f2ba35ad0d02b21c06ff9a063a18ae4d9044ae19624e165c731c44d370156f82bc2121d36adb5fd08d8acc8a33c81d3f57f44e6f67ad0907bd641eeae10107386500247288605c4c8db039f842517eb53b12c3febbcc7cbf94c09e6ba4727ebf723bde7669821bca7eafd83bbafbdedb6fb0bf053f2b6a68b55315fabdb60b544851ff4bc0fba680376e37deea2c5a05d76bb9dd4514a74fff03ee0ba1ae9ca8dd0de2a6e00f7869711c2a9e4cecc62b487ba85192145ddd8238bef1d3baf5ba725d71086ecfb1de53ff255ae351bca15fcfad728af3dce95c9f9e1b3a9fb068876c77ca23a22cd3fa0e7af82d1a83458f9c0db11f8f79167afa6e0ed1e429afb606e56ef3a2f0deffc8c2932013621261af5630178b12d96220b3be1d33ebc849fc13f2af4c61b9141d8476bb92f119206ae3c95489a2bbe3725843ccac1fdb5ca219b1d32076a3ae6a0ac7b909e89f358fe237427371bd796704bbe7211a10380f8386df8a9fce58e8ef965f1dc28706f08c8e90c67f147eef9d270be717a366c4b635046787278a6065a1b9f9d030a5be66626cc8436c84263431f0797e5ba38988aebd5c16672782b34fe1afc3b2feb6872880f2687e8d6e47037398c531b21cc8f45903723fe6b3d006a58977450d1d5fa11d0be11fff071c4e1d0a7b209c37e29c2243f05325c9d11be4d98ffadd2b0f38ef4bff8f76c917173da0b9de2fbf70e3c412994c39cf0c14a8711e98c23e18521a726aabea9264d90a5eea9b85691f6947b3f0c6194d423f8fdc3e03c3e6d36e6c93c85e1addf2aca4874e83532943c92fa2cf033e57d9b45e6a0a7bf01d989c3004bf89e681dd611bac4848294df67e328f5f03ba98f3143314ffccce38e380179948287776380e85a0469b5f7b1c760b93bb7c04bada963bb7576d6e61bf20ece12831998ff219cea2b1742719aa444004d262eb7a3b169ab31b55ca503a19479250b02ea9d30192d92a06ec5de200c0b0db1eb363c6b3878c2c9fb3c529f63f0bc66bed3ceec0df449a39684b7e0e60eee6a0f92ee18246db7e9be50b52a048b9f1316064535d97738d3f70899d4ac91e986e0cfaf0f811710e9ecfc2be331b307b8acd1b39fdbc3ffc16f1b67ff11012c3c15a6ce704f7ba23c0544a882801a50580390c084d7abc26d8a5645211dfcf0837aad05a14b6a740c98a4a354d1915e5b3ae88821cc1c1dd52a3a33660e1ca6448e2b5b2f0ce13ed8e51ef82a574a4ff513eab91203ecbbcf34f314f45b6f6ddd8179ae9a0707838b31742eaead9f84f698b0ee3109a2d748ce4f1967aaf50486c8c4c8ee1a0e4f34628783dd301c124a70efa71d0f10b2a6634dbe6a602cdd83cb8dd82d35b1530e5f7554588505f51830b4dd3ea10dfd76d74b3771602414f2d91ee47ff15d81ec4132ef46b2dd282818a8e4620d9001a515105c1e300da2a83d98e616d3dc629aefc734557ac46629e0b0c7b2187e4dcb3c180309056f8e81c0ea8b78aade63e37777f55d2d55f66b3d2e5c8d0b774ef648032d33f3891b9ab469a7e918171a099ce3024f5d3c9a4a5d69adb5da06c9f135c9c9109f283e402373d6ef5fdf2f8cecfafad62db499a9adfcd7eb71744266fa860cc5276466191008654aae228167b838bb3ec7533fdcfa27ab5734ebf7a31939d137173b79dea867768bffe46ff1a9ac0c2539c9a24f38c7d796fd5e8f2bf2295e5b2ee653b2269f92193991a894b45f347cd032a809571e4433ad3ad2e8ea8c2c22613a801d462209c50ca0c01e14330f8a195e939965442af05431235c75a2d1cc09f912cdb0c0d7cda64ee441cfd2f5898f8ed9401d3a4c0f4e80acae63f845580278d202f0c403f004af25e2a9acaa2bbab65991237057e8f7c42af06a9aaa8c439927342ad0fedb8969f378f7d310a1a420537598285032a9ed9014adc223e4146b67646aa837245bfc8914c0ce4736fadbbadfef7d1af0792d24b2bd0268b3f62979ada782a4e47540c9a740c96bfc49f9a2c3954fcca79698e5b17c1d10f3da92f2699394d78a944f03529e8da7e434b6d3889c2633729aac1529ab3ef844bc4678ea41b2d644bca7b79f80985d1f0c917dd2f4fc29201709ca270f944f78463e592a98023daf819ed7687f8b5fa235d07577ab8eb4277530d7d70de2fea489fb9323ee6f82560ec1f710b78d0de9dd48709ce1c250f857a486fd7ee6b60c3bf61998b34ec12f72d6d8409076c1f4958ae5285748ef6a59c7ae46e34da51b52de7ab821ffa9f605a41981ca6e8e53ef66fce7b8cc220f76b46111c553834f94c8b3c914b7a1f78e1394d81072bbd06e079a0f4f3eaa2dd5cca4ded750707c99e26c6f7b3b00d7cc3ca531a772a6c456bef33a388eb864359b1d329c678133456adea18b128ee2a8900cb3aa489531b0060c738170e120875344e1d7e47c9a8380da700c3ae6f3548fa41328c811e47a04a7a8cca23bc04980a730beef4406680e72c2c2e1e10b4a37ce63303c3c1c1c8eb3c6d16bcf9880fe0853b76a8d71816bba496d6bde71795cc81cf61a75fac8daede12cb36eced23a04c9940031c3ee36eaae41e2380a3b8a75473bc65f7508737940f3006e16c4b936377d95479965e218b50b8a7cf7847aef4eddabaadf07463bbb29587ad6eff7a66649a081968b5638511ba88d14e976d263aca2e45514ac8fb75b3aa8e157c793a921c08b275b549d56ba037fe5e44d1ef586087f54a911c27fe764b3c33f78bac17fe73b4c8bf0390d9f7de9b4d2a30747ca84fcdd94198f7ebe835087608a174aaaf52c4a0b6502440b65bff2438effce11d8f9d860c04d7d7d85a6d128061f7eceb99175dc970256c035c5fb37cfe257296c474a6cd9b24c8498c0633f127a9c620846ecd5a15977aa42aa4adce394bc4a25278f764fa31f720dbbafb32f0a309392ef9e46b490ffd3c27b9fa92e15515a38931d25bc6645f4431e6632dd9c5a7e9354dfd96bcc61689df9811573a89edabab576280084012075f7f0c28ded3018daa230819bb543154fc00917052aa23cd0af713a155e9705dad31183a87bc5355fd2b5e0d8e99730e5379f9007dc7b78e88e50a9755b38ba47aca345ef36d9340b176383a5f82c68f56ac9c552856eee11e2cb19fb77ef74545d07718ad14627ccea9026a97997c8a5b9ac2fe0ee230537898aa8ac301980348c6820b8d2d56db75634e239c656d7e0b6d0ced6618130617e3d9971f7b9b12c7ce7761babf91c530c9b5e9c9ad019ff164d95a2531d0e4e2cf1b4f5d2d737aa0a32c42f15fbfe4afdbcd687d222d095fe23325618f6e2e27814c43bae0b7bef51b7fcd4b908d4c38459b3907e9f39dd2ca6bd4d29ff72e05c6e8f673967c05084ceb2aa8264c94bd03668ab313434ad755643096d98fceba65b6dfdf1995458ed7851c49f8a8482c695928eb42a24a42ad02623c384cf371dcd817de2f14fbf664debc4db60309ddd22a3e43579b5b7071eb84b078a56cfeb8666e77db32a92d408ea5e599ef795d22f94c4018dbfd4fe28812420b47813d6a1bf49f891c90b1b677113e04e7ba6b69aedf6d1d3b0ffe4926d55dad7e3978d417e4d68fc9abcd63ae7069cd78e422f8ac827cf5706b297de050a35d8a0e3c668abe661ada106436a59dd0751fc3ad0d304b9f06b92e257842abff20e96e615e4ed91c4e82b60c11a887bd5619660de745907bcf294c53fe99c4f4a4dfbbb91bab348f52d1b82856acf45f0388d288a03ad9bcbc2ddf5caa18120bd9f7c7300b9b9b41023a705835bc43742ae8782bf11fc82813691baa77c057a9daed719611dbaf1997f41a41d28e744a821533f4d4df99d572b11e08436508a0dea13a62eae81513baa52c1cf89b6d19c1221570675129d7668b057f72b7d049eb5b4bf9be59b3ae0d3a60e3805ccc7d3814a604173b1d4e893b5798fea9d222cfd4651569b6a8a71949382cc7026d9f4420b21c82ca97e7dd9d2259dd45133935418748295debb11831bc382efd47bff5fee33c2277954e1662bf25412d6053ca95f494c238e0d14ea702cabdd05f68fd37e7f0ae4e3709b111e6b2ce4c90ff26cd4d8ddd076abedc45afb1e4f524f5b37d34f8a7e8bc62cd25fe8297ed6a8ca8b3a7eee4fe2abffad49ecdac3c2cd5f9cddc0a20ab40927a48ecbed66e2fc202334ca706e8601e7c6fe450d43ae90ff8388b2ef4073e658468b5fb818f770dfecafce36e8ce300ff07a5df8412fa27d0a4acab3218d501b28bf750ac7b14fca9ccc3758c306c9dad7597b40e2cf056ec11dd39db271d45f932fc5202d6bae4e692fb135496e91113d77fbf149e1ab5d6ed6348f29664b211b4855cce6f975cc30178b55ccfd8527252f03e32883fe7194928d5330d13679415930ccf274508c8d1a8a231668a7d8e3cdb8b37c1cf1863d17c5fa1d6fb4b087377a5038eb7b3975424c39343d2c9a37ab40102f7d2d349a88c6f09f14d1682bbf52872c6c4d00b8ba5ef43d5a9cb65a90f0249cb43ed2fa9c2adf9b7aafccfef9aaa56f990ff448faca29fd7e5d441c83f9e70aa1cd49018a2e998b3fbcdb7d6b07b3c03bc7a3801b91c8fb697417dfc1a135fee3b0d46977a927ad5277f0b12ae3fbe3283c85af4ee6c7bb488c10969c906f2baf641b6817aad7b9b371e36bcbbbd3a092e0d4e287b32aacc13b714779673f3006cd1146d7d1193dd717d9617f9ffa733bc51405be0a7e2b8270dbbf6b64ac5b044dcea823c25487853cef102d3d2f7c034da0c494b4beb4dbc4bedd80fb1607b5a42f7e36b227ca037e363c4f581b441f245f45fcff39a0609cbf069a53d82e1ade6072f9711eddfbe5573ebef74bcc7d2aa1516f8876eafdcff7f9f8decfe17b55c5b470061e5ebaa3bbebe5b5ac7384308b5c5c35ff1bbedb8566ae0d70bf6a05d3e4fc7893e11386c363216b07e4eab15fcd73a4d14c6f98166763cdfb8b380a4e01589f0284dc6a0d972117b8a68b0342c84b2532d0f7523203c9c3f3108b16eb5be0363b5cd8e3e11e7b2c03eb763b84bb83b0800a1f9a76b157d81e7e9071e091374aaa7dba2059946386121172b599c9505459242ac441817343c4da6bc754ae0a9a207660d933a9393222ab5541364b418d6146bccaf1c5ca7a038aff8027fd0e1ef4860ee967b38558420cb0a7b4e69550b9cfe9f5fc62ed977b216673953234a11f3295d0ee4165f254a41739380a30658cb44dbfcec47229b857029c9d4244d4f88f1d5edcdc9fdf0bbf43eaa586f451d1d9a5a62dd9772fde0f6f58bc5be80aadc0c21a60bbb3e80c4baad570bd6f35dcbb924d6a7f2df347a8d96fb54a042da88e47298ad384370f3c1ed32bdbe7ff21d34b3b78def45b795edee6790dddb5b5dca16bd449f0e9cec5b40bfba610a560b92e1a54fb5b11926d59b4e9b66bece09c81396167c37379d03a1b9d278fbc0b7b53eefbf60411d1eeed6052b3dd0ec35e869c126c633eb591745da84d86a472834c492ac1d4d8febd885eb688fc2cc5f41c41b818fce9e6b9f97cffdc7cdc3d379f15ad09f4a4b033e445e1d3f3656186fe41e186afed7eebb2883e176a9efd174655d5d618d6c7ff7bc3fa1f0deaa4d660760eebf3af0debf2ffcd61bdfac661bdfaaf0eebd5ff1786f5ea3b067552b786f555a1afa1f4ef1fe13dd49b800f7f5b443f29e50ff837949b8dafec32393c7df4fcd1bb47a72a76583bcb3751753ad5a1118a75dee41deac791ff141ac0d086010c0d0c60c2b73e6bfc4e77ad43afe0a7d8f79e9aa4049c3bd9fb7515f5ce8b396bdfb6e3e49a810f758e53d9210f19b83744716fa4b463ee3acdf2c9a189c6acf6536dc7783b00473781bfa5eed1edd85ef1991b7d9311b87f786fd414fe286c48ec425d4699bb6bb84cd358449b94fcc623259a796b9468648174bb75853c533e427d0722a3e1f14fdbe34451dfabc2de27edde14d1ab42325190f9ba90ad6813273035d642ecaf54acc85a123bf5ceea7fdafb7ae76dcc731df693b221a379bf7fdb2547369d20ef33a8dac3df07abe6d123e49517fc4be2e40faba00b20007443acfd0da586ecca2cb2206cb793c342501d18a2df9f1ca6737e6d9e7a4fb83225f06ff591f6c8f1ba48d204e9898c5385c060980088c42828e889405bb6bcc15d9dd34bb09606bdf6addacf08bcd6502dc6d32d26c655085557fda05062c9d9b98ae2740d46908c1072a20c756031451b450734ec86d5c83b3a5244c17a847ce1fdbefc7da87f1ff0ed36bd756bd70069a7d73fede1ec75415e156368c22991f98df9bc7f7849fe5711017c7a6155240d7a231f5baa01af2e6bb1c4cbd04dda1bcfdd88529fb037e3e38f79a4e6b9b26ef84b59904021c871b4fd77e19b28303084959b9f3d872f45967c92df0b9470e25ded67fa6edd4d84ded2d90c05b2ddc04f09f61546c8d14fa39f71f3287d9f880ed77b6488f00faa7d38ec7b62c851a2b001f7fd1604e8af8f735a868a09fe45af3e74333ba7ba858679bfdf4bcb2847e6bc470888529d1f49abe4cac04a992e85579485ee282da8e04ae427accc8e488e998234d79026d4336e5367256d73a4b4edc045c45298f1a24eb7264406a1bbdc38a8967d14f7b37e3f12240f9704cc1cf0d81d71c72c4e33cc228139b8555e82c930346945657a80b2d600819d658ef9b743ea2bc335062edc252984896b2c6b6d18b5dfc61116f733346e6b6134e90ddbbea098979ebd9ca7895686a1013d2372e2bb956456f044355060fe14a2e8f8174f8faf6c07117e1eb1d0d9429291875904c8363394fd9f3e43d9cd33342b1b1653b2d30601bd61f24432166aed85308da6dfbe2298f3fded3a1e79d240a2674e2bc303f718e1e7b936f2c52f750a0bc9e4f7868107537ff1f0dac645537b2ec9b5978e42fbd5cb8dab0c5c693bd19b3c71549698aa7145567954a138aada44812b451495f61230236cafa70b882ddcb5cacdf6f9c0c8f7f9c04816fbbc60e4dfe0456552effb76ef47db6d045153b7dba9c409eaf75fc861922b66853cb78c57ad9be95c3b9bb84abe808118ce25054d5be574f5573d42a6dbadf5febeddaef3f19edd61a67c92486a9949ca69558a70549075beddfeae4a1598e32b3c95a3358ebe1385373a12c93b1d89ecdbd43a9d8774e5ee751e72238837bc8c50abc649dd06cb73f391866e3e50fcf54eedff1a37262969a9719029c266e6726c68678aedec2515e6a4f81f82c1496f844c3c737f19d1fe69dbcb89052a35261c8129fdb8884b6bc65c484adcbbdce0ffd272836f5c6aa26f5f6b3c02d8b3daa0ffd162f35f5d6a302c35ed99ee918ab7cce0d67284bdaaaffec365a65529c2d1acb9cc4cf1d57fb4cc288c7f23da8c43a46f5b684cd59dd911c7935a82fc5d2b8eab72ffdb882b54ecadd89fb1a6c2d694fdce0db259c3f14f779b6b5727562d08db6d11e83a6b6a9eb615a0b7db1b81ed7d1dd8ffbc2dd9ad6f5854afba16d5abc6a23a43f1a4feff278660bdb771aecb8065f7f9e1bc71f0d1070ead41d7657fa162cdf4fb3dcbe98b7effa97258d31b2177a8011735ce87dc47a77d9e1a6dd87d93be739907698ed647d24284a87508701c792e4f60eaa81788278017071723de4bc82ce024a68e11853a61366f19958740afc3c3d661c359e1947e48638708ab45a02f29c62afa5223b795a12c5c7430a4d826fb7dfdb9d97ce5b82b2badd010d1b86c2d4bb26908cdf052ac97d7caf37e6048f46f19dec76a698070ea136aefcdc80bbb5fc36e552451d1493d48ee75ea4dd63f464ea781ba136c63ab4109281af7868d63e3dd9f94f4cbc557e89a1b5632220699be23da6e7b2ac306dba1b2d4bba25c3db645a26c4b46287916bdc0597fe41f00e5a09a0b695769bfffbe88522897a34deebd4904f990475aa832d4ae2384934b686962a490db3f56f252ea7c7086c627c6ba09fec7fa090b23d5f0427158d98700f33763d5c4243892b7d0be5edc05c8a44e13610dba598bfecb3231b346386f519c086b9dda6d81d390bc38e121c7cc770ddf1c7917ec2ce15e07148a858f62a69c6c85f7135ecf3ab00c26f8df856388b0a18dcc608cb44324921ba4e709b2165f0c748c0dcc5c0208d243cf2e8d595cf3a43b14c9f0a63160ee768e856b9c1b10e536e9eb6332a9d98efa92bbef24e236fd814cc41020fa3f88ca431a67c1d669faf13dc3e04d856fc1b41aa87088fc1d79aa457e2d8958da25104b517253400bd65549335356b2c8ed6805aab055833f507c41f346a636ceeb9b7e8437e5ea0165d34bbae42b08e322776dab8f631fdfaee972ad23bf5474b58e395ed3b28a19fcb8c188879001018a05f614beb35d1ce503af3192e27c60eb5702382fc336488638879b59601365e572e20ec266a190699808fd85becbcd82d19bb576cc60a314e0cbd21ab9e20c8ce1cbca5c2f04f396bb5d3531c6b05cce1c4e787fb43d0e258a77ef04c6656a0ac237b4b105d3584d3d6314ebe6d226bc7beb5e96fb7d2051e6022d816daffaa4f9ca56a16d7369689b4b13b7e8f8b6b914aed74c6c05df3a97765ae7526b9d4b9d75aeabc00be2449b96b9f6e6d45b3d76bc4f463bb9f7f3ae95ab39cd27354c74e8b3bec51736b875365f02454e0e6366512e7b2402a74f2c4194303789718bb501ab6eb84d61082e50dc52e7c7a411a611ecdfda81f370fb096681034a94546594e2de080bd0abf7cd185023a8b69960d01dd5eda0577ea3a66f22915bb9e8f457d9e89fbb6b14c6a70fb1cb75b870436406ba53a00ff53a7f33f4eb792ed6050440363d765a24da60a2eb73a3a1d0b5beeff65f36fc60959ebd4d310d435f8501c38c9bdee6dd5132544ae40ff2886b83e3ae886681e3bc10c9fa036f2e369d3ddd46fe658eb5a677ebc41e26cbb1238a27b2dbac9dfb76c67a53cca7e0ce7a31eb6294ba302e515697785ee245893f95c9a4ae4b12ea51393bf4c6a2c7d432f213d1ae93b7dbbb2689e8802e2448a0df11794a436e79bb635c2ebb9b38833716ae74926059c74ac7dc4215ac73ac739d63769d63fe3aa7573066dfef587399336f120fefbb5d32f7308536f2f0b70871175e1136e411925e32e5feaf754195345c612856cfb80461767d2ceb058429cfc89734ca95dc00525c7e73761ecee0f942c90ae28c3cb1c59fec2dbe8240db501cc29f6478035eb16235d977f26b78c15b2fda9539a7ce71469ed9d69fb55b37eb45b774231bcceb87550941813a657cdc1588f2c1bc66324d561cede65c79fb07f9099eea602f4038c541591f64e04a810f0aba7a7559cb3112cbf57554a07e3febca54449b9d15e748fbf8b9ae84969117c0a14f65b53914c139ca9b954ce58ec4b6db8891cd0e6176363d27ca5b8b9c2293434eeb5c2ce717abeafaad583fab6bb17cfaeec573404721fb6f181e97b3ba582c9662b502b947bd7ec44b38a47fa0cbda38f00eca3d05514639af5b25e8c57afe78ce2e56262bfa83b6b130a6db6d24070fc51125141c2ca9a84b853a3a20875f4de815e167c57962ce8fd958a22776d6719d030007442df0e891cac83b72d444bd0ae7a4162d857ed4eb40fc765bf5fb55577ef780d8ea2ad4f155bf9f9f4dcf7b845467d3f3604c27355422f3f50d927c679126d76d852c86245f527d6de495e57845aa7135f8e79f623dab34e6e481799c37f234b6fa7d79faae94d96b30441542b14f46507d4e88c47097d7f74a52463b226605fd09ab06ef5595acfebf4593dd0418d94e2e7904b76974bbd55d5048ee20cd0aa11d6be1c3d21130e1842a5ec1d7c410a156c89d9d5cf43fb5177db4618ae7684ab2bd303dcbb2a5baaa0e4976752f4acee5a8c4a04d284f3a6e2bf65944dff5baef649c91869f75cbe8aaeaa09238e40fc2559bcdab8a2e568203c7da0082377970bb8bfb40f026c7ad81e0e3d4f311232b0ea052e900b498879c4c10ccf5c6a363621d4b3bf5e063ed4febaefefdc9b821336eb6b4a341f8f945e7ea8f8c2fae3bb1cf326a6f663aebb9bedf45fdfe691629cf8f26049f91fd1711f2a2c4b3e06e993544d82a68afbe8069be6c95564793c639c8f1afdb6def43010ead5b572df3324a7d687f8a7390cd32d2e1b34be80beef699a417e8fa2cd4f008105a62a3636514bf9a9a56c81ec67ba16777afc666b8febb082593da770a459bfec4ca2c824ea34d78b9623b61b42a43368d9fbde0e7244df8d94b7e4eb2a475482db3259d093943349ba5efebcdb398a530811e4793c36a4ef9e4d0ba1834f3ec73c9c5dc7d412f78291f95a86198d0fb94f951c11f47949dd1f35635abf9c59209dd9490b8e968ab9ce5aea57246730ff4aaaca7edcf6f003c9b2f67fa83a55889b5fb607591ceca75c7275cc899bdd25fade7790e4b6e0b4ccdda9ea4e0d910ea2cebcfb42a351c4bc9ce4d0ee7f5c342ee96cec95d937de5837f2e97f234b2341287cd255dbdb8a8d6e5a21271af970d66fa61f7fdcd788ced6f0a54dcac03b7eb90cca8d61db54c289c022c23da6239736463d19ee5e74963dbcec75d4e268b311f4800f5d6abf7514acefcaf71712eb7e9b62fcaa2df6f7e0ebb7a571deac5398adb9b746e79e50236698673b46bcf223dde57a93ca53f0254c215e13e6cab82cfe17ff7c0378f3dfbcf17a4f37c51473c384030421beec498272e6e6df5b088e5e41e1c3dad9d078bd900e2e39c6aff8d0925847c5231dd5ea6914048e7c81165cb72a1547fc438a2241f28571fdae7633439e4e5e7c9a15c524bc32492c9e17df5ddaf93c9d56df6a37938c44a94379b7f16ea584e7d1b0c60d5da0ef007e56adc6e58e04db98ae5cb1db057adf708bb8190d0c38d11c5dc4eb5716e93a43784bdfd0b94820451cf08a1b855f9cbb72a4423d50b3385859927b5da647a23b8c6f5567842939c2c38a846ff5796ef494d515218dfb1dfb08817649814de225e9845bc38c75d55752ee45d05bf7331a7c162de5561c7824e1b0b7ad7677b16f54e90ddc20e9e750bf245a7c275937e7dedb533bb204f52cf736f6b25a08d2da0b101706f0328f6c934be1bba706750b6fc49419e7d776fcd8a5510aef68d02692de502368e4c6e1ae06679da5c7b33640eddd3b34c6e1aeea49c8d673ca2188e68379d37b3eef3a63d76fd91422dad8364d6b92355e366842ff0e30ba90af5fb6f5203537b3faaf4ebef3a5a665f3d5a666d7147d679dacc9421a0396c329c19258aaadfff2421cb70857374f3ee466177a398c33235a96fd8df28ec6f741fd5abb6b9f255dfef4388ad93f57a59a6176b114d0e21dfeccdcb34d225d1fe59e256646f4e24ccb4a1773b367e2a3be09751fa4b16224db17f2ac0daa5c312de367ff3e65c78b23d1a6ccd8fb9367c69edc2751072af7dd6d8b58e7077e3328b3a8f319fd40ed33666b107962ea109f762807ded00d33a6535ce3070801947e15191b7d48f99da1ab1e23b00c9ddf208f0e0157d8d45417a037e27aec05574c4916dc2df6759073647b7e3a7d10ba5d0d6f2f073a38fe2e64d3bc36962ed9d78c2496ff47f93f7376a6d1bcfc3307c2aa2772f2315616c48d2c4cac63709a4a14d420aa4490afcc94a5adbf287e44832e0601fd07b1cef893dd7ce7eaf6420497fbd7fcffdf4ea15acfdded9d9d9d999d91915d270a55b64656304b0ebb8954096be8cf84bfc48ca24c8620145992242285e4441ee2d467ba42cbdc4745d337a1ff189fed6b9e775dc5bc2fb9da55679769127fae36a8f299ba246632de66a6aa55f355e38add541e436cb2d684c6ace1b6dcf3ba6db2f6934dc63344b14a2b3e4c582fe9d25de31ba4c40cf76954859c349a3e15e27ee89ffdef3e7f4ef55e281c552b458c496202da8e0cd03434a624b25da2d919df5ad9c5fef96c0b49fdc8293423e65a80349bd39670fc5ca2e42ab0c3738e2e589cba8bc84da1a83da2d46066729dd0370acdbfab61ea8820703b767bc1cf36e6c5b06d5aff9762cd0d0d7126cfa166190623a0d39a1968eb94cff6de0af5e1e9893d89e451c7804c57e0f453a5637d07615ef7d52e9ce277a6f29734f4f2cd53f500477853952d59f544fda46f11e4c03692b5169af7d52f12ded1353432dcc076a8782eb52fdb3b432c0cae34769cb256dbbcc21db27943d7a9b02925bde1bf62c357bdd1481dd0319aded7accf6b3e5b31b277731d26bea9fbef4d75e747a4df5b13443931eb86f7c8d442db6ab66c4a8a7d4b45296483c308e81fde3abcdc33c90ebfbc7a737523fb2e060dcf40d2180bd777cb6ff5a32dc0fb353a26ca610e9cbc437946c37d67a0a83556cc1b374e5d6927e22603495e322956eb7b77ff9b9e77a9b718df9d6b3d832d56a34da4f2b820c010e4153fccab95c6b4e81a2cdb617c4ba5959d795ab5231b3e90123c2662821dd55aa895e4796f45929d433988d3501d02e181c55a7e6da49880266e361abe5f9112fef6b6042911f739b3679faeb2b60fa3dad832f7460590bf9a166ed4d119974438ac29db0d1f6fc88c73ab4ad4b1ef914154adc3782077c051bf9da882aaf5dac1f7dd225855c57b9631a0f5a4f1e75f51308858dcd07ad27bf2e1e3df0b11ea571a7438fe2e095fb07fde7772f305b94ec1c30717674e8879e17d477227d9a097d837878015e350c4692e7d0b3db373af7bf651eed274643ab588e15cc861893e97885a91c3437bd891188828912b0cfe43a9dd02f4a1c8d3abf633794eefd9e272bdee07d2078744cca2effdb3926a5d222beb01eb9b31e7caee18846f21c574636a094fb1d82686ae2cb03cc5d1878106643bfef513ea58da4f394032cb00b3c2145595a6463d20419139d0ff36548bc9b82c03ec866a5ee6d89610609969e06af3d3e0dda208fe85a39c4c2fa38f4f056437f46964ed8db553e90c8bbd96786955a7f2f8df7256678f9d0bbc52b2d0c903b9fadb4cf0246995e653525e56fa6c657d7465a6a47a18ddcdeee08cb23b6b1cdc3aab1fdf09152ed299f2bd6f5b4c6098caeff0a59a8ceba8754ae1d019a71d4dd487bbf1a79cc6fc4c5454e70541ea4708e8deb9a43e1529fce4e87ef787eede69bd064e36d62f868c78ac1fe8a439562adceeb867a305dcbbfb5b1da62efa050783ca73c81cb4cd3b0a77c08808375ee9759fe127e9de505346e34628a7cdcd335f7551f4157ba8fe17f75d8ecfeae8dfa96216ab0fd5daad5652ce0fbe0ec41e2eef89160cb04ee62a49901c20556c3e4079e1e030757df65bbfc162566541799bc6b5d752996462258b4e95729c0356f14ab7102fc7be1b5b70c515477d10a1b8d177d3702477c8189fa760d6369b956508b24c52d23e53230b184eeed0c8b42fad65672be765d81a51c9dd89867a9d69c6a48ac0cbc8a508bd668bc8c55587713c28d066ef6b26856b8e6d41f1924ed8149e02c7ab7d391b69b96193dc4d5aa187c8b805be61aa6b746e362397f45f43cf42c9c7d228911436d8ef2dbedfb12a73fe406aa3f505e278dc6ebc40dbd3a13157b833da86c346c110fc30c031ca255af0cd8936eaf19e1608eada3ee935f3b91edd81aa358845a01675eca2bbdf22b2bed57193b200fde011c8c7d7fe02da5a72e4e6a30d8bd2ebda581a02f136668a21f4ef5608b6a8ffc46632fe1c1ee55b30f79b35ad283ce1bb12c06b57b6b30055a7c2361070c9b12eb46faf69b1d9e58093985ab77e6c0f67a13e08ab423c0b6b423302dbded5118894a306b588b351a6f2944d45174986831661f22e9ad6e47fd7c207eeaf07a07f5781050c54be91ef878d0bcc304ec6e84cf41e9e44d057db337528b6ea4d0a041354710f3f10892606d7d2971b51ef006e01ac8c0815bcb08eede1e16846fd34960fb51a3e11e852e8bad4faf7bfa33dbf6af5e803b21e88023848380873c4eef67a77e98c827019e70672d81772f8375d6b1eae7a1b2b97fa47eb61f8bdf6c20fa24b63d6171ef847ac06b719830dc608ba29564b6ae9619bf2fcdf89710c3cdec8779b8b30e2f072f9771f74f60b0fdd0eb1c895f3a22fe6959ff01a6fa04515c8ed9ab04e651cdc38874b58dd1d15d03266951e234227ed87d6c2944b43099b418c9f9f10f2c5c27aa4973ad265c8acbaa153fb4eb449ed7a185fcd07839813d663dc99890a32c036119e0ac767a29622c65cba1d08f818d9fa62b331f60c4fc9c50effbd91141114782d5781c9aca176fb5f9faba1cfdd3eb5207e9c882d7bda77774c7f46af38df816727aca2436f4095a6bfb3dbf1fb0bdb40661cd62f9500e6841606cf8aa329052bf1e2255e2470ce2d797844f484f763a3d3b8872d097644d947a7047a92541e279f292a0b5d692bff289d52b1fce7bb2e930b334ec8f50ec8f51e44fd028082843ff47e20efc8916467dc256a2d178001fb48d89492426fe4494926a93098491ae7bd138a9a5a013494127eaa58f6a60220b2c2736e514395048ac79bfeb0ed059daa313d4f4ae748b0fd4161fe8544237b31a799d8195e081805ba568cd7a3236eb0305672d1a8a7823d5432b2369b3c58c4dc0c61054cf7a4425fb024615ac73ed7eeed34cd273e3156fb1e2da158ae50ac5356fb162b55fb4c0e12e013f5cb1bd64b2aca62430f8bae3fbcb5daa2cf62b7a970dedbbacfe251c4d87e6ed96db4a68ee3f4c954c5dd04c766b8d41406398241b12822a7b6944688cb83d9cb43a61bae0b39f720c16690ca2f32911a2a318823e371acf43f6406a1a3303bb10c1afd8e34f6e5b0179da13266c64036d0bcebf774acefd01fdb3d1368d8cfadd49ec46fee02e23a37ef7cf5094b3ec5a8f78c617fab7ef0fe8d96fc5c656f6352ff814181ef2cbac6156f38751c23681a1a7b4612ad6d42cc5fc5bf20c8b191f0b8b19be9b70f715edd62c031633e11a32aaca374ea6894c4dfdaa0d4da7ae90b4b73c3def501695f6ea2d974bf34a7e3f23fb6dcfb0ab54c62515a3795bd661c81b9bfcfe0daa26fe9b1e9a7f45aeed77c7da7715f140c49fcaa2aa178cb394de0b3a6ecc947942e37492805e46d7a047f2557f14a827ad4ca3d2d3dd0ff971d705dd22c5ef153ec67acd8294c264ac6b7c81b92e84b107a3ac344b997556329966798921887da72742dd2351c2ebb8e628882de2e503222ad88bdcdbf417b10dd9b471785d223a647e25f8ece428c6b1316ca2f18f8f2494702d52c45d8a701dfbddabf47cb0a3740ae90a6f0969ad67224d8443cf41cb4827e8e91e12ced29e3aa7fe01cf0a51cd19f70d7e15a2eff7abf01ee418967caa26f176c9b90a0e60483b568b22aba78d900655c4834cc266081ec895f33ca154a397e5fb38d2e26e84e264fc2bd1a25b8003b588222c7b9e1435711cbba1e787cd72405237f663cf5b4aa5d987db94666ff0b4cbff76dee0a9529a7d4c5488a8abbeabbcdc94b88f76027a519b8f331ca31b2e65d6c29fc552391635236e37a53f03ff942c16eea784129dbf13147b01d7d02d95a71bddcbc1ed2391d7a6f994ac74ebb6da1fba0c4da9862c66a68d980f503a447289b75c8a27ebe61a0b6bd97ac2a70bd45fe0321ab0376b3540aa7fdb1d6b1ecd865d3c04ec3926a57b5a0e92e2dcebe0216003fdf27c3e6ce1c347e83b696675242e87807f23b38e4105ab6c0de0745c7a4b4f5f28d81e43f4069783664492b11f0d6dffff7b3cb615c9fdb892c98203fc855a3e19a2c77e6f88da8ffcfe10ed6cfb65825afe6088da7e3244dbfe2c413bfe65821ef8c3217ae87f407ff927cc64e023fbf31eb5fc635426fe68c812c643a485749e185f292f73453bc986f4743da13fa743f4b0d5f23fb15c8aa66d8aa66cebf13a5fa078cebf8a217ad2f24bfe351ba2967f291a1fa296da54bff565081ff743c3ed0d17fda1e7ad21f457570eacbde9d2c377abdd5ab4bc0ed80b0ebb57c3ce953678a38ca1e8eb8bbd1272677acabd4c635bda8d2a28045a7447555259983e7902ef50550515227b9b56703f347a439881a8f1dee41ad0800e296a964ccbfda658b4168b87fb3bfef6c39667b8b48939a7fae449076beba473a14f1e777883ed872dbfdd329f3e3de12a88278f4429d98f5eea6107a3ed5b65983bdb8fe831904a1b4d7aa8bd6f343637716d10cf83be8cd4fab0f57436e44ca18108f28861661ee87ac8288a61a4c84f0dba180a002c00f1870661706e3434d4411475e643177b1df76f177bfe070445fa7dd7f33a3425703f341e40b9c5e2c963260a7bf28489c104252987dd9251923778ea9e4268a673b0362a8794a4d2865d150262b1889e855ea3510e29e7c6288ca925e093fb977d8c899380bb1933ef7dccbe43f99e2206e1660ef905bbc22c306f22146b038a6b3de28460355567dc157ac61c5655aef7cb17ea0e2105cfc586cfa51d045594984b2513582aced63de16fcb9e8315f03142e8326934ae1397f8ef3d303b26704608c31e23acea50678040cf42074a62701ac4cd996424e110ec244041f38e296044b1b55d8611aaa45871dae6bb24edf3268512ec8f34bb4a7923afc92519071845cf7037eac82db8fd0cfc0e8178a0d53136e4df3c26514b85d752c3f6b03c6f2da86b87832af32e4fb23c29e7e8c9132d153837d277e7439d31f334057c8800786023a9d70a64741f4de76a35cc5a5b35cc56ede85a86f2ffb71a1a12a3274f3a6dfa73b1d816290fe9edafddfac5d50e97d0dbb45262cf8f51eb198abb4f9e74b61fb25f8f3b0fc5cf5f3b4f1e9ad745ce5555470ab16c574d0d546fe499b42c0f224a807b8dc61f3d37f2962beb9da56150039438089105849a35ebc47d37f69f9ba9fe0d3fb13a55e0d0b377e905d6a2854b83063ee7341038008827268d562138f10b96efff2dcde5d89600ac115b0b0ef22afe58cc831d8e6afb57cf0bf6862e7b257bd26844f4fc5a2cf687cc799e5aa78fe282f121f8b040bd21f758f092d68d33a7cce737bfd1df8cbe489df52bdad0c0e39aeab617a414dd3ea0388886d2b40b464ac9cd401c88211a0d7d3e08ff9a1984b1f9871ab9fb282c3808109334290624fe90e5230a08d6b666d5a08ad8c6b57e8c8e057f28788b32612cc260681ff90fe8b10c79c9b0036bb3fd34ea6e774c4df92ce9f07183c7584a598e21aa61cce9d7591a21ae52a9a763e86008ef97e9e55ec7ccf110a4b727c9c6740808e6b75b4f8907642c1b2aff5816bde4c4a4b758f49e516cb10ba02810abced670d93331acd768f0583e304b9e1a371a3143bf4a83b1f09b27583a16e612bd8adddfad2d4444a7bf0fad177a9777c1f1fe50cc18e0ec71fa2df6408950b0dc032ec4040b6934c83781e52c158051cbba86d064d8ad90d7c99091908e8500dd18b56aa8f178e86d524656184bdbf991b749fc1891cdd86f3d8bc172b545c9b5dbde6e3d8bbbeded56e7c163faebc1e356a7dd829ff44fa7fd841578b2ddeaececef3c8bbb3bfb3b9d073b904aff74da4f1eb57e09876ebc457f79de66ec474f63eeb186e3f053900ddd890bf14a5c180e3bc66658639b8153a874e8ddf4d078c83dc6a7c32046fd66382be66f92746fc6363cbd550470120108092fb147c6784ef3fc1ec06ed3b540d7f336dd7ee56ae251e8f59e22d26d75c846bcd9d3662ab0d69ef1597adb9c8d49afba733ca1778ebf390e5a678bc66459e7d452b7f0d7cf9ff9adac5b088fb5c26ea821e1f79c2ca176b28435274b649c2cb171b2fc619f2c849f2ca47ab244fac912574e96489e2c213f59c4c91a1963b24ceec156e5ee43265879c884013b6002b6c0b447633de46abc1ebaba86b21c0adbb1721870c101edc51600525cbb793174231f5a8f28db41ef7606a7f166a8dbb703bcdb606726eeaa60c9c4e3f07e40917e49d4ac6ddfdacd34d0e6366d8c0cefdf9a36ac7d790934e02bcdb86a01da921703637f059b6dc9299b1b6fb3ed1fc46ee499b8c76c7a3e5a96565120ad7d85b1406cbc0989b9d68fddc95ea8104385bc176a8624317f39629855d9ef3f742bbbfec072c4f28015d72dfcf853603de94935a9d5c9fa6eece9064e2708071fc1d3a97c3cc304a5ef51181ca33209b8502c980c9121170bb8242cb84a502b0049982153e2eb1867f0f40036e45005db28205aee847973648bf7b6c67db7097e163e5f03aa1b0b9b3dfe62521a5e8f07a815bc4387e82d1f3d84ced5d845f91c592cb7a094c76830f447431472f160803be256e2f76469bf8f3efa0344efaeef83bee1adbdf5e071d0370c0efb155b438575e0a0af1a886ab04a183c00693d03c9080da4f8ad2fdf2973b7147d8d128dbb6edfb2a71c57e23659a291b195e075ec268056b1607b14b1cf52e37db33f453d61e17a4d87798d402f35657b87267f45d3fa57c26b087df5ae851effaba695eaaeb53a6b6d75678db0d606d3825dabc0e21196afd4bb6bed0e3cda8ef02defb469f3135674b9a4636603dd43d33a3d0e42688f152885443d2841903ef202a3062a99866c4fe48a659baa659b5a6f8dfb86c1e3f693c780bf6d88bc4a41a806a12db5d76741557f55209aa3abbeab4bb061a7cca1dc7670dd77fbfedc5b56d6df96a53a7839104f32fa3c58ce2e22cd6992f65fe068406f317c3cbb5dd7c801e07c48fc818092bf0b32c0913ff0bc8e3b40bb202f1c79be5cb941a3e1d61667917e06a0c7ea7bdecd0020da6772bc2fe850e773883ff2fb5e30620aae2ffe176f6900f941ebc9a3605a9109caf94ed154d049c65970849c7ac1003176c03dc094179c4f5970b65d0774148ed4859cfde46d9cfde414e29ae240438e7cd3e83be1ac74d2cc1178eabc3f70ae70e114531225bd84c4cdb3b3f4ec2cdd8d63073b4f8f79347c591e359bcd67aa3f6790f407247792d42907c42973429c3273a6797699c4c4c1ce38c3945e3a491a27112eb3dcc972673ac6111964e398e4b434574a37cf7edaf81d53282f8fd7101a0ec1574132a4b3df4ddc01852ddfe4fc5c9c6ae7e24e6784ced241702f88c3333df43171a7fe887284f3be3bf59f7ba6715dbb33e25144af2815994f893f0bd1d4340ee2bbcaf026d068ac50e35dad54fd496bcf59b88a12cfc25abd9cd4b32d166b7808783a0b3dcfdee0b741e232443f9ba0b80c5500ef5bd072f911bd1bba1fc53b818f2008fa1829553be39b059bacbdda1bca67098a63d699e762a03b92003700c5c0149fee727d067e4a2f62db4f71a3e18e87087b9a7d3c7e3a91799321c27e3a44bac1fcf33e18be3fbb4a1a0df72a4158cba38cff8d2e6dff18781fd19f305fa52bab146a34d6de537eab5af64fedae7334d463e5fad87fef558cffcd0702dacb1d37a460c79e17c443e38da27c0c6c18f743b71f1116a763883eeab706c5800a74fea85b73b71e3cf6e8b216891bfa1fe938f9a9f07eb1a0eceec73ad580ee6bbee5c7a290aeb7603c4e5cf12a806a15150179c66c128817f4f84ff03bae0c056b0782a2a56e042105fba9f2db812cbf1d30636d63e9ac15b0f63aabf551ff9226971f4d5f1bd248c548d53ff587ff5693c6c311bd61cf6f3fd5574af67396ea75ba2bfbe95853b1baf2b8e3c3107d4ddc8f465404cdb38fe6f6a3f5e0573f34231fe9ed575ec0f8d8e663bd25c54d2dc25575e13e226c52a18f5ea079b6190ebda0f66a7b60081aacb812b8de8387dc4ecf7037ec60d5d8ef7a63f4a611f5dd274ffce3a165ff628e45376495b71507e414c68cf2a1775f2187b886ea775778265c7f71d518493348c637de7e79c4067987b3ed0b7ffdd5ab281e789babb445758a912734b55eb2dae23a8083a11b7941559d8748103fad93d976795923b1aee02a151f6a75a0e56a2b0ae3cd86ced2185c683cad887f2515d044b42dada4260b530443a5d1b25cc2e57e4427d2bac40bda4fb517395d71b3d5a9821bad200b914f506490a00e4151c74ad436a70c8b01329dfeb07228edc5a81773c9e875cc4c38e63170d3ccd11ad8ec26590a0e37ce7e025fffec25c24d41933afda659c62769ac27eea7f19269c771e76680dc01ea5b7ecf1a8d81b4b24dc8d5627195a4717625bc2fc2b379d11a2dab7fb3118f988ba75133c7699fbcc86669e9dd0cd0a889d36890e5c00f72078d3ce9b0d72b48e99fa51334620f68a1d0487cb17c905aa9c707fe44fee45cd55548fb49f51763b49f296af9d768b3ed7fa5ff4418b5fc3dd4f24bd4f7e7bcb47ca1220ee35dfa01ce839983b071a3b1b3865029bb5c2cdc6b34dd187b012d3561a54635a5bea2e9c6c80be8055ba5371aee74837f83e1283731d7cd04dc5d541ace6a99c0688ecaa044bb4bed4d4d496f9adcc8320ce6ec92b6b111518c1f371a74a01e244f68f21e8281d281e947157447b1fb981d2aa2bf12cd699fda438f25ed7e8036296b73bd58c0dfafdc1512c3c26b40bbaffca9055b92e580c29217684181962cc02362edc7e80647657229fcdeee91925e5379d851c00512d3bc4edf97387d44d1ac3358063d7815f989523426913e19ca97b957a16ea7fac93e23765a9e17ec27ee27ff2af4824fe893b6d1cd53f493a7f74057a18f30089c4401ceb27d419f3457315fe0d9e451e87ed2ac9a59a08da4e77e69b4b71fb36acfd1a7dac057cf59f6157a0ebe3b78ead5ea1b54f78af9ece85c1944c65b8aa7045f1aedd6ce63191be05de2d2b919b20dc35aebd18a22c789ab0dd9ff648936b71f74cc1aedd6f643abc863b3c859ca0adddaf283ceadd98f3b63f4c97f93b87d7fec0f3cff6de28ebda5b5b2ff01e4b842fb71f09c91ef2fe8aaa9216d3040574d136de9023f5f43e84ba341ff376971a37115bb565a33e63ff80ef1bf78325cd8a0d198c7ee17ca923f4783266c35ff0a0d9a248d950087a2cc157aaebc551be7c997aefbc53a43d073ff8b718230dbd04992ba57fe1766642ae897d771af90fb1c59a35e2c6275be3caf3b5ffc2beb64394bdd2b74651d2ffe187dd1ddb3f36efdbe1a9298f7d8f3074ade0830e8f63b5a310a94b1e7af5d35c97549d2b8d1e83f1bd09b311af803d4f7fb684cfbbb8cdd2f7edff327ecd7c0f3c78dc6a4d170e995ee4a3be3168b2bed84a36706907795cc4e31c8c8e027cd92a71d3c0e1415b4530fd25979b6b0cfb96713c01fd7f39f370b52c242b9ac475fb4eff957fcc5ddee780cc50bd7f3fbcf065df7aa89e398b5f09c16632070d9087cd9a1d771a1f9fd9a3cdf6803fe0b9ea3d37378267085be0474f9d4a91178f49cb8d28ec0e72c048d3438bff2c7a45776ae9a459467e3f16bd2a32c41994d65d249365d7a2bfc237c6140a39b48b8e0a003f9825ac197a7cfc513ae2f1b1bde157a7efae59c4e9a75acf587ae9a740c95bc936c8aae9a65365dd233666d2fa647d59e748820e86b641f0d5f54e859712ccc42e35c98858d9d478dc6ef89fbc5b78859d27367213b189e4b973b4c08f5c9f2df74c9f57c1f23f4a9fa82f693f182f639fa1859aa6b9ab4ac07eb65d8bd0cdde75ee75239797abefc17e8e827c114fcd5038d718ff10a3ab0e9c139f4a4ed36f68b210a95ede7274434e0874677fea78ae3cd4f6885bd638bcb92b8b178c50e8fb25997c3ee6cb8b1d171859130f63af4e70a647d3f6c34de0ff518817eccd4cd74529f120e3966ac8ed1df89b258e7175e625a6903a4fa7d77c59dfec416be096cc4063232cfac8ded878fbc46e3b7cae9ca04408d87ed6d6fb1f8325c2c5c0afb961ff7dd27bfea6e54e0a6ae0fc4ab2cb77ec7dfe3caf427b4ff42aad29ffcfab418769ffcda29860198e4cb570a7d17fb7f0d7565f75f9a3e1e816080955d6b07acb17c1870f3fe7b480c76da9e702028ae6aecb19c3226d06f78a97c3f0f1a552e6a90de0175970f1476de3739967a95b80ffdc8f30fd85fb1d58c284178d54ec33e8be1a1413ec036e6071845cb0f28d4f167ada52fd087a17a86b09bb8911f7a4188f89322b51bbce09a499a853dbc9ea5a45d6055a1cc0a12696cafacb9a1436849ee6621c0a99a00f09a1c9c1fc0bac20fa52198787aa78a08a5b5a19e58e575e7d677488bc5aa888cf75440c49ee7dd600a54f09785d1cf090cdf022ad88b4414a8511d50230a546512a85911e8ab7838b45d53280da1d2dcc7cd988c4949dcd00b4ed833eaf710408d599a0bf7d78d46c5dc114cb24e92a7d361176c45de7b9d8cd287ce2eb3cc03717cd5ae8fe91fc2a71025b062d607563f9e862f7f19de1f6b5e6b8179be9a43885a92827353dd10bd6241d55316ae51bddeb09094f671340cced2a3a115ef4e3d7127b57243f5fe83d881d9c01accd05fb088107f4819610ebe0c842788f869e4dde4e0f7a2e635ff4e6700cf213f5a86270f3b3d886106de134193fda0d1e04637a4c97cf2ae743b5fefde96053f361dac690ec77feb557c4ec503d7f0966fbd74b64c602a0e03f80b3e11acac79c163c10507eeb0efd36f063090a078819560066169ef74f460c58671038b8ec69ec3d609b7c10590b0177da604c243f192d1f6cf4cb14e06730e4c97bd61570627644f2cab750d5ba1b87e359e31fea736603b608d18a48c301f583e8e97a4e20a3e55af4c881d0d9fa84885d67c99e2df701e2f8ce624109680c05cdec390b98275adfa9885b1700c61e84b4c3f627e584dd035261eb89730b621412f7a6ee8ffae66f1a5cf3ca911940d9866e22c0dfdd8c73ea980afcd8e8caa7990f10abdfe7010a015a6670821d2fcf96796ebdd84cc4e24a80b1ebec211c66b7a8e70d9f25a2b809dc840dd6390aeb64407c836a66601c753bafc2f73c039ebbbfc31561fc57527218367fd5cfb8dc64b0ad6d8efd3234c385dcfd1ef7d235c15a1bbd7703af93209498ec2e02dabce4cbb513f612b4393d65a7e4f73414ba1d6f28f443e78690da5277ea91663fbea5107776ee806d07c6aae4230760ff90e147b855dc294c000db0b3add59c17935986f311b970141ea37437544821e6233fa38a46d6094f45d4221c8b7484ff28d218a1335676501af6c3342d4bbbd042df2f7e0d6220f3a21c25a2b7438ccd0037be043474adc2d4eb4f5c8e7724e2f589a8b205d4c8b1deedb67a56fad10bc5d259da4efc63ef1fc9891b698ed4fc34dcd77b7d933dae4de54c4211bd7fb9ea45c92b45ab403e56f3fdef6584d8bfcd8c457edcb2e69ea8ff0834bce557f655b011621aa09e5216a05dc3711f12857e0eb6791602a88ee9e443824f1de0dd0efb1bbf2c0d6b511fee1001c7ffd39a014071c9a3123dd4f7490304470ada4a2fd4781a7dd84907e2bdadc59b45bdb0f8c98b9b0ab8ff862449ecf181cb19f2d54921ed481e99101311a8df7f0bd1a197aab5d12f16ddf47dc7c3827a9ff5b0c58d2e5d17953e91f00327a95604ced479e4fb8f9fa4a36acebde9b010b45740d0698be41e33c3f34ddcd3a361cd21acff28a89311dc2dfc1bbf93646ab282462c93f1a98d0d1d6521065417e7e70cffe3da8d001191187f56a35670fe1b15e9a1efa6679b5fe95b16fdfd6cf2df55af4fc892b8c6de5b2d0afb819ea21c2f962a6f8ade58d07366f6c25205d780806ab03d4e7ee227ae867e20efc9ed76d755639d9685e44781ccdc6b8242c725ffc3c298bee8a74684d7b98e22d5af09cab079c6a5f82091821f1d168aca91bd18d4ec3a4b99d940d0ca4ab23a5097107c2b38cbad70d02699e6d38a7d58071968ebc9b3e1af0d5129287311a19715b448b63267f18cb30d5704900ae7cdcccc282e4970c068d9ee7ddb44113c13cbb8d35e727fe98d9fcfad77d16a93d18d88fe42398911d1ecc0bc668507d650f81fe6b1ab0136903d3be841405eea8ae9e9d88a4ac618cc6ccac9f2d461fb55b628edd01e365a4077d20991cb0e2af8186d217d040897dfa682066c55d0df5e1f5d48d1ebb7d49b1b76a0c35f06e241288b603da20abd49789cb013a4bfb4bb68789be6d579e3832a086b89dfa3d9b68c5a8a79ae2970b9fa08272723d65eaae630944fd718967f2966d7f25ed7c50330c6015cdb1783c9917f17c2ca293f718f726a48e42c29a7072c61dc99bf352157efd51d2fd23773a9fdf947c7afde9ba18adb57cb8fa781d8cd6da12e4af19db443c9fdf25e06a206e12ec8eb7d6625caf152d455e9e6be2d3c8e8344088df73bf20af131edd5ac8ab3e0db9f382b39f66694c7a494a629d965e5c1cedefbe38b9d8dbffebe4f0f0f5f1c56faf0f9fefbebe787578f8c7c58529c60ed1eda599b42729f69282a256bc58ac85cd62369d667959c0854ab4d70a94a43a6c2629bdc6bad80bdeeb822e119b244b5f64934952420b47595682889207457df48099850ac1b8298a502f0197cbe0757257e3229049e463a3aa127a2febe4d37f73c9a61f7b37e00c89e205667e9146648e22f653442562fe928047819f9c44b032f24aca1aa2280bbf741c861586d4248dc9356a05bc9d9e9665f82c0f599ae1111d52cc9b392419af53f4329aa773964e8719b3df8ab1e683d14c48e15b373085045b0ba0a062b19dac7d5b5603a9e6065542dae3815a10c18b922b7d9df4e50b995375849bd33c2b3310f6f06576d7f062b1869b49c15c4c09a9ba2610fea836581daf82a59493f6d26d775a862b7fac0793a143108298803bbffb2a1b68b745da0b95f6409c0bdb86d56adf14529b273488d3dd081df31856105f7544e63e8625058fea1ab661fdcb671a09ee20cd8ff490df9a36510b1481b0af93d6c8ebb891859cba0b77d4f2a38a6e34aa06258c6c23652fa8f77d536f305c71f85331358ecc807f41747bc0bf20ba3de05f10ad0ef8077a5f83218c6a03fe85f501ffeceb9b7f961a21ffc29521ff423de45fa0e2a629ef8a11273198fd0d22a0322c7e539d77bdf77db1c5e8e12ebcd56e07315348aeda23b03920607d5b39bbac0b668dbd3e7a282c482d9fb42516e7e687be708444791fca6584fc6c9de34e1f3d0ec802fd6a38e290c94658834bd922a6bba5bded47946b593cf67c6357a04b8ae4a5fc558976c9e558bb567b3bac3d4f54dec556bbbbb7b5f6dc6aed896a4d6fe3f98a3684f5c50a49b24e9964c43b252686115c51b09da56dcbd9f9354d7e62a67da5696dcb77fa0b487c6026ee41e2a320364c6959de3ecddbde5e21ed6befb4b81800777147cc438aff420aa53e075260b28558883ee3aa62a0a75eeb2895745f9d3000fd5f7decc7a07bae5c569493376510211deb41e5475c1978577d6da3fda5b9e63b1eb80f242b2bf1beab7e764ecf39890fbdeafc2243147e63085a3ad814bcf89c72bf102dc3b093c994c1121aede0a699b0ac7dee844762069267e26c8a6194cebd4b6a6310ac957a46aa333c62645aed95cf238c5cf5a0828dc7f20b6070559c96223938faa1ea0a0fcb9cf1ab3eaf3092f567148a77d25e0fc8444d332d79a8eabb0759dc7cdda0d8b055e9fab30c83c1dd1d9afc44b59500d7fadde1ebdee27af167eca91fd236d2757257d3fe0a973edcfb5fcd8c98de397e162e16f0d8dbab7b351206e1bddf7984f77fe761f84c1101e79e55cdbad4d875a887fa4ba10a8c5b2218ee3314fd13cf63c2677515e4c42c786db43d9fcea4b6b55b7c2b85baf9c40b0b93ea7c002aa79055001b14241c29222c6c1d84b38a1eb3b5e8a3bd7eb3e06fa3831e7ad5777b3ef1fb5e80e9c117b1083835aabf20ec801e3b72238fb9b76c8b883d9547542d6eae354091f6e679609a49308b684d984daecb403c9a50b1265fbb4c6ee5793766152b28de1bce5cbe21799fb0482c2fcc46974bda40dd7be08117d85380284b5533a5110ff3c7b4bc230818f4b2e746fec81f6892d0080d98002e42bb3de51d9ecfb22b7fa1a813da24340a42744557a54f8fa68a1b68bc0c6265477d96c68c078e75671fa1f2781c83bd12a1e7dc0108baa4fd434f21613412173ef1a039e9b96bc235b96ed228199f6af03f71285722005a616a2b0534b3c178c45f46576e0b4a3025cf75e5eba2d1003bb47cae394195dfc6b369c23be01d056043a87c42341a3c43df55bd917290cd3a8f1a8d35d895e260e3de97e89d5a9ee23ea17c08f322c1fe614e217f653e22bb3b9d9617c49a3b3f2dd60e8a83591f14cda787f1398ad5437326cc0e1b8ddf2317fb4fc0424f867fc11d6cbd1e63e7e745c237c9519695285ef646ea66cf8d1f0c4910d0916a4d35156f19186dcc989c085542f7d534020e178d5031e1483c3c853f5a23214c9f99ac2e036d4dfa23152f8e0925da6b3a281a8d27d677db2ee03e3612168bb39f1ca0289b3097cd6996a4e5a6100b3be0251cab17623a111f70ac0a170b3744b86b2f8bfd4844bc5f062ac538c610adb96b219b46a80d6a2d6c0e70b15b967912ce4ae29efd14e3126fc240f32c2b2927cf0c7e42e52128102709741078d808f4a39940912b86dd2d3fecde705ceeacb5961d46608c6d908cd44d5618b7d40605a3a39137dd9eb9faabefbcbccd01dd08553c8a466edf0b0640d75cec2d97e1c80dfdbe0fcecc4089be6230683062c156be7d28a3db86325243793bd4634beb0393cecaa08ec297e1c8b45adc798af33e2048c11f4668464032eb74e7bcab7f306304d6c38db888760aec8fc89c072de58703bdf06dc4bebcfd60dfbcd384f685255a2ecfd2abc8200a46b80cf1867cd07781ad90fec2b9afee8013dae532b8369bd1436eb8507ac7f3a1f48ee72d83f93d3a05e7bba6d1684dbf67e97b5cb11215166d75517bb8495304a1881876a870459111ae2864d6fb11c24164bca9898c107be065ebcb8ce473f6662acb77c76397777a4abb41673f6dfc7e7cf8b6c9243b496feec26285dec6faf9295cc0e528ced7d9139a10b582f069249ed0841b1bd284fa343c074e9f9d9471b397e513e60922cb278227fc3376634632ecf03a4f28e3360f69f68b101442cbe5d28852644631c256a0532b8a911e7e286c345ed10a6b6b910a0d14fa6b6dba543f63f466189ca538b4164ca73560f9ff40779517f5dd278f7dacb92e1055740f7a3dd3835e1086fa9e763f34dcf64273f7de68b8af87aee7ef0d5d8a8f913924c30be0f6fdfdf629fdd368a4b7b37dbf9dbfadeffced7319897bad3f7243cfb6706ab594ff064e6ab88d1258508f47e866ff9236d5397d1bf9ef62ffcfd83fc6fe21f63fc6bebefb8694c7f8107b4bff13f6ffc67e12fb93c8df1bfa379c1fe9acb597e774abb97a35e1aba297a431dc1d9ecf5f654579c083288aa17d1abaa97bb3f4b17f935d923c4f62f22acb46c7d2d4d117c9cc0008920a520acf4e4c1291f3f46840e2d99847c36669911d1de388f43aab4367d0e1eae37c3e87c177f4a96134885cec555cfc0099d504fe4b7fc5e48dd68414a81bbad863d6c79551142f333aee9c140373a6f58959564a40f112069cfa44cc9c4d8ef156ded2736f568db88cfc70469ba01c49a7e55f92bca087c4d94fed47cdf64eb375f6937f96323692e4ef7034c27df2164f48e7ec27c650c5d9e4eca7a517906bd07c362f2e8ef75f1ced9f5c1cbc3dd93f7abbfbfaf862eff0e2ede1c9c5fbe3fd8bc3a38b4f87ef2f3e1cbc7e7df17cffe2e5c1d1fe1e1a8f646df6dcf25d9697788c462a9d8e7feff00df0cfd619c285a0c655865fee149f2672712010b8ee1a2c9555ccec61b50c9f33d6f6e5f8f163cfbe6d6e3f7aec1f82bcb93922f3021e58044b403578bbb312cb942034384b2518c6b362703c4f238b70ddf9ccaafd583966a97a39658e620c62eb99048f533a310e21f3b38fe07b91ad445e09427fad4529976cb7725ff9de66dbd0ac021cbfc4489de66e59874a6b70f5b03a79a0f581ebd8d0ae6b728962207c346b6dfdd653db027f1aa65f883c88b8b7d656b091462c21d0b49851c3829eae9522c636325185cf841d55fe0f9c51167c79cf6c058f67619913729096999aa47dfc4b9047f5ebaaf6f66221b765edc6b59fe43d36b08275b7d6f6630dd338a1431aa10bced29ffc9fd667057128c71695ebc1597a96263dc79de659448aa249d2cbe6dbc3bdfd8bfdb77f390821677d9a67f10ca6b5ee393767a9e34c324aac9bbc23073939f9324b72e2ae37b7a261b125c879de54759b93246d0e8b752f384b970e4897beb1ad985c9271368577d4a22198cfd62fbf38ff7b9c44e02f91f965bc6c35db4f9aadb3d4f9c5b96534341fcabcc8a6f33ce90f4ac78d3ce7258e48986523df3948a3a683d3d849cac2c1bd5e324e28463665c5934152384536cb23e244594c9ca470f85062679682a3c50171de1c9c8864a797cd6883e0b811da787df062ffedf1bed34bc6443874a49763274e7260bbe74ed6734aad278a7930862dba7cc67a02b709513e47fe98bd355a612ac43c25986f0e5528b137a428701fec2e5332665cd19487b7627f0c798932939b7ac21608a3cade49b32bd70ba6ee5acbc75ec0dae3d638a177c370bc20e50953d6b8a5dff2fc30582efd19dac32569b2fa75cdea83e11b43d5d89c2d839e410ac560bb5a6f3d9f8eaae34e11f6ad41784b7a0337a8cc17a49561f1e906fa20a231c1b9c8ffe22d8351758894f88dab50ea6579445ee678428e8c23c8bb618691dc750b5bc0e694e4f47e0401beaf45229dbb7f96cec5b71aabff55a4e9230c6c3c5198106569918df945665756a6fd8d77d36402776e186d508f4abc06ddd8a428cd2a8d066fbe4980b49dfd043b2accb3ab82e44e9c91225d2f1d6e75e6d4b6d174dee011718a594e9c72804b679ecdc0ffa9839d69369ef792f198ee2be6f794375d349d41594e8bced6562f6c4ec816e3f544f9e2ec276fc57476bf71cc7590fa4f0d79696bffcf52b108abde8f5dd12de2dd734b5db1fdb4545e879fa3eb6fdb95bcf8e6731622f1055a6bfb7b3c0a1ada6cfb2fd143ff37d4aadb2e4e3d3d79867ea3db48df26d5c1acda53d8bb693dc38b457bfbe153dcb517d6ace59478440a58a22229934b4aad4b2724e51521a9d38283a2bdfdd07768b524ed3b3d5a93b29185f0d75b0e704acb38bd6941cf8a342b9d59ca5185ee3baff312b59ee22eb896e98db32c77dbfb3b5bd8eb3c64a6a1af582836833cfb07e85593b6b01db0bfed66964e5811a484a0069ddef36e27d2bf21bcf11258e83d46aebb07cd695694bc67ee0dcad5d6cfb329794d05a0e670fad38a3655de433878b158d0465b7e4ded1a32bc8fe63a678addfae978cb2a85feeaee7b01c5394d85f3bba5cf64422acc7ccbd0eb8cf4edc665569bed67cf9eb57d82f0697c6ed8029246a3f5f40f163e8d66a2d0c7a7d139227e8458647e476adc542408aeca3a6d9d0bfe4e3186fc06654477d02416b48e3e006d1ed36ccabce9453c26ed69eb1c457c366c262d888acc271c3f257c8a13b4fd8b1b6fb4bdcdb69f227c3a39f72fd164a3ede7089f5e9a1da68d46ebd91f6eea479e2713739698fba9d775010eb94f6b4208a64bafc3d2529f360d69136532566d24e2b0d4dbb060298d536a7d97fc61bdf7cff2f2208dc9f566a87e1b760edda8839b49bc1936931828d65b747aee1fd27fdea1b6ff27235d4768c73f8620a1f49ff768adadeb7bfea2ab24401da2d7eea172966c443c56aa4fef0d2d240011323754a0204418f27c6dc015c701feefee5be9ef82893859b71aaa7da0838291fec53dc5ac9d788a3ebc76df7ade09dd883df7a311b9ce187ea3d1773ff8daf836b119e8e3230338854bf0bed170698ffec0f5bce018ad89801e474068fea23b8c82e94fe85df4f167a3e1aeb97f5a537c167a8b056e34d646b42db11fff9400d45e6ec4de8d4a6737d123f46773ca0d75580441ee17b9d2cf53046e1f5650c9152a98aed61fe9fc8918381b8d37745a7fc9f7d4f0c926abb94bfed3631b4f786da05fa901f594413dd5a01e7ac1845254f1d440ca3624824680a0c6da7ca22860995d8af7739bed803f991726c90f5bd6f3482d7480f9daafbdffc0d69b3fdcdf6107fedf685c3d9d0fe2319176530f6bf2271312d3ab972cd4ae167a9d5dc9ec07d5ecb794491ecb123bd512eff28cdef0b88f826afefb82e4cfc75934025b67dece768d6c0238be1795b0cd18e2a4eb7858c3a8081feefbd7249ad16afa9175b2581c2f16aedc96f5120a25257da7a3780d43755433803e295f827a573773ab5605a4ad61fac87569cc98a3d791442f8e55dc908691941dcb8558888e9682321ca1d0d45428b9dd118a96356398e259510fbf9ac2fc4af10e276989feaec99fa51f927220d7db643f2a9bc79c1ddf167cdb9873c468479b23d6e71856e658b3ca42ae518367ba767605e15a61261c490b1519a413dcdfe07940d0d94fe96c1292dcf250d17a4abaf106e9c441545b448677eeca5f1d4a79848d11fded1344ab938d28c0e826893bef36367cb1553aa16fd0ea0ef625e1eb10dfb29f8f7c792e7636dbcb803c8bbbae76d2237a3a1efa583eec66a419c3af438f1e51dd81eb75ded34d46c92cd98c3d8f322a5a1b119cb0d8f32b3bd2ab156bab551b64b371fc2921e3b8aa9c5fb156703e8bb3f7adec206467a33a25d5992c7e496ad368982c04fdb6ce39fbe05b2c466edd0ebfcaf1b496b6f1080bd242cb9c5ddd566ee2e9743c8770f4be94be5aa8bf0cb8906f0d8465d100e7e5b0d89c8e67fd24dd2cca9ce009bd6b5db69b8fb9c44fdc9253dc4fae9bfda41cccc266926dadaa0b95dcc873b65bed27ceee281924a3ccf9635660da02e41e9131c12b657a5c14272f228edb1f67211efb4e0f83000f04a762c708512742ce3adb81eb4ea3e1f06c261075d668ae94c7ac3bddaaa494b7ed4a8929cc0f64a3be12a34e320ad575cf733a7208ac55360231661803cb68e249ec74f9877baadaf51dd1dcb936b5ce59cae7eb2087ff582c9c828c7b3eff6ebea04d1ccbc55283d7f36569d68907225e861d8e022d2fcacb38374e459e0d251ce4b0bf8d06fbd11ce0e2f02a7d976753929773779d13e275cfe9b212a732e9dce9b0a4e02c651d3988f748db63bf6e6d9015315b64693044301622e329c90b31d026ff96f94a700412080739da4d9722d45999f41cd790b2d978c3cb9d954280b35a7ae72c16ace859c94b5d917094942fee5576927dbd5fc1ec9eed15779493a0486239c99a89ea52d824a618c58a2de1d7922218e01903b9c4d057b0160e8296d3b3126827130431b5346d33ef2822c74d6219a2ca01d1f559e359cd1eab0eecc6c19e366890d96b6dd3ed612db49ab3abe67056d637ed20815bbad095091ec1ee8b3b49363ab541f31f6a7e0960f70554b3e93d802a61a0014a8da57e9001eb812dc14ac85b5bac76f8a296840af306784bbf729a740c4b7bbfffdcaed9f17cbf5fe2e295a40ab27c93e5f0624584c7e498e4974944644b7a222f4781794c931d64d40127d8f4fb459616653ea374d85da78cd93adb087715d6d1136cdb193cb7b69c9759ee50b6e00ae77101c1ca709984c93829e73ab562070feb51ac054b77d67382c79023f6a7dcd1e2718e184661d35f36966eb52058a251022ce96220d6850ffa053fe19cede6afcd6b39077b0ac0513382be1be3692929049dfc3b90e03abd3c9be8ed3d6eb636f3a8d976761e6effba43082d3dc57941343c67a6660ea8714a837808bfc9b400031b33b5d3390656cdc835880b54e5878fd595c056870b9a1c778d9570126e3f031c093b8d6f6fd3d8e072d1983bf7a4f80b8f93d8a5abc352e0dfc39eeb391d66cf22a8b158957b42b3e9bcc962889f47a774bf756c6a129032a3dba428f164ea02defb0e9837f2c9025b2e571a0a342f44c26261214320aa6453da7821abf06fb8fdc8428004b45991cb1264be58565170b1902559962c29960346ce099f863ca22383dbd3682aabcc4ae96bb9642d6d6d3987e978ce0a501c494aa6b7c04e2960e7e0714e703cb77a666d034bc2ae8580b63528f616723d3ac7b5a47899a44949f8502a035d8df5023dbb62cd18482d9c17a53a75a58c99d399a8298006c262a73698ef24135aaf7148c6858373d0e6e3d44952817f6322c68dd3d84933e73303fb6767800b27242415211ce3266fed64409c195dbf09d8271465321ed304b883c4649a9308d39df29935fc9923096c07da7892f69b62326b1c15ea69c76adc60a55cb633e4c9bab5a53a8de8add6e15029b209290794cf07b2023a2f0d597c8a4445e60b8c2a5790bb7f086fd43456aeb77e5e9ba48b19997c0b45d2880beba786acd0a9aad33d29decec6e3c3fc3d3d9d38906d44d369e4375119b96baa848ed5ea93f28862163c0b11bd0726faa315e85fc17e5a450c23cf66695c41a50d938832a1c4614fec51b37270c7aa4848e7a4c8c697e4106a8bf98dc85c23e382b1389c965590894c0936291b308ab38bb0a4d72046289ab26ca08d532d2f3beaf23d7654b8fa384e47647eee9b9d419a2766081c072e71414ac1e7fc41e67444a7b4b37578e6f31c47a33e40ec4536cef2755fcbcaf298e42b923f247139d0938f709ccc0a2325636f2af4b4e3723e267ac2aba4a6e6abec92e4b78c8ce5d70f4fcbab8c11f28ceec2da4ec24ad32ce578944ca72436d2f44e06abc73da81ff2a07eb483ca4007169c72e34340fa2c3d0f2ce486cbd11e2e31436d0dab232eead0f053e27012cb8c2496a9f18c89f8c0d4ae66d7ac8b02ec36c0ea90319eafae4073b5d265395e59b62cc75a4910d4af2c0bb95ae92c55f7e3fa1ab284566b82af251826f85aa5271404ca46ccd974dca4788bdfba6539a68caa04d4069f7f87ce4c6b9894d887cde93b3c709093d0cd0ce2a9289ba5a5efc0cb35ccc2e5689c991ca8a48f32c58545b439b0237801e764e3187aa4a98c18d1af26a710c018eee368a0e4443cc7174404a4d7b2533a057a838696faa4dc6385de9012bb4685401dd114ab1082d937af77af93e2608f1ebf7af29c256b27306dcc416210305e799d66b0e3b9c20041f018ac4fc0044312b2b5e51cf4800582957592822153ec3bd39c800b3cc8bd4c0ae0ba6000403f0a4d9c92e58e9b38c869054ee23ce5ab18381b1b89d119679e5c7e74f5992dddcb2c07e0b8890ddda714e93cab89b392a97ff4b4a5fad07e02065176ded970b69554461acddae55aaa8c029b9c1b94ba7d7edf383b44f78e3d3d7b724b7d4c5c98344bd9b436f9a0f425565bcf5ee73f0899c25a8e71513ae555a62fa693cdca2289d96243f42cb89a949983c19714a493eba428293b1a92af09c99d68965f125d88c606c6a279e16b97256c3adbbed3f2ea800b985a4cc749445c7dbf6b32a2ea995ddd9c8a415170105bc4926d40d146c3d1b9c6dd3cc7735181b10dd6a2e879b78f575f3095aa7a2374e0faf61dc325c7b7641895e954c75be1ce2577f83d23d42e0d7454a7ad73766de07a154b32ac68b190db187ba9c389b79e01a3e8b0c16843092cf466f707c537eb7dc94168149b814fcc582fcd03ce1927475383054743d616f33ae6f2f639e5638f609d329f11392a935d2eca6c4a69bd2e76adb016825195a7678549ceb5ea208a15259a668e76f099190a3263827378f07089c776210e6b2e76bda58fd58544d352cc648103e7e53f008f84f7b2923fc975ee04ee0ab573a13d905282a3aa0b008b207275f0adfdd11e6d5e523bda57418d893fb4fee8659c116c2d55dfd3b72058a0caac86baa92c9080f5823aa8696048d43acbeb5399e3b448285cf8cd094679dd11a3a5fbb1e39cae5faffbce7a94a5659e8ddfd1c3e55d4e2e936c567cb433de92ebf2e3fab9afea17a4644d88c432cbc6653255ede29cd03a6742fb51ce2b0398af1ac0a7ba017caa1bc0bc6e007339804f7c0042ceaac4a012462ef7d402d7e7c26739635cea3b41301e22aae1054b582c9c9ba5123c24e44a2f03df6691491693b15e8625988512df49c624e518ac583696ec2018a7601b81cd81e2069303fe10c89c173e4dce35a487b1d71db7063ae39c9da2ce2652203125de202e49c8d5aaa31b00407712b4a68ba71272759fc6013aab5a67a0a3cdd3e6b4d621e3f6e6ab0411c2547ed365f36eeaf89fbf78d65f78f94e90f71cfe2df35988e813598ae7372f58862c976657c685516688cb1fdb302c9ea9cfaf871cb50bdfc263c03c36d2e25596275fb3b4c46357219dbc15b1525749cc6e45e559396264cca46b4d76b3356f0956230392f407e5adadcc95da8d4dc4417c7ece2f8e4b41b0a90ed701c1b1e76cc995adcc4d4924a351d1ccc925c9b57b9cec6093fdb2aebcc783a4573a783c663c3c07a43326bd12743a59eecca6f4172d6f71aa3577638d55fd2fb914cb29f11270ad592c9cd3f3a0e61ea7089ea87707d18353a042d729f563a8da64a20b1e7fb7ee9a0344872818ae6a5a2fa3b50d5f75cd9bfcb2beda62afd62f321d8fb95b1b0d73fb9eb6ceefb58e76a5e6c53fbab21a6cf88c3858e49709165dfb2025554ae1087677a7edf32627b06c1b32ab4cad0a08b48c2a2d5945b5ba696f57633bb3d60de933935bbfc8d25ed217dc137b00456f19eb615696d9840931e3a4609e9e58d6384909e652d2309ba571d171d629a059125701141de786b1447414922b62aaaa8ed3c3e382f8ced616fbe520e460678acb92e4a9c3147f4c273328cb69676b8be9a4874533ca265b7116155bff6b8bebc1b658f14da6b4daa2c8859d685694d9c4118692ec395e94a597242f0bf6ee975b26825481ebbcd9185943fa18f7f6df1dedbfd83dd9df53c3a55734875d480b61b7c6bf7dd52f0ce61f99171bdb2c4dca7ae8cdca6c82cb24a25d0a1f25ce55520e9c2b42467484293dcee604e7be43caa8c9af0e7405f516d32c25fe37361227c5748ce72f6f011cdf7b45f68190518ce77a29d5132123ce87c678ee6c3a0521b741aa4fcacd82945b49916d5eb176399c2649fa1e40b53e49c6e3a420519632ed805072f21d50d0f5a7505d2f9c28cbb9ab6dba4c3491cdc809c938bb326032a32bf4ad0bcbc144d7d65854037c4547e3f2d4d83bcefaa03399748aa2797c7cecf0cd066cac95afe74d927456129ea7670cb2594e937755122ccafa9b376f9c3d9548a14af7fc586b93e2002ff9e9d3a74f2ae7cb0ce725ddddeba77f9effe96c5ad9146b3ace3a24720ae9ab9b9320581add88460a1814bf8f47f4eac3f086a5b297f31d679d668b9e267898e51a14490a812e94ec446390a519d711c163ddb64afe1661ef998a374dca048f93afba9d8f712101ba5c0e92429ef6aa25e59b50b5c38da527c47794adb4ae8cbfc3fa4a9ce78a2b334db1e0563fb953c9a91d733c068e02143f779bda6540ff9217bb74f5fd7f224c30f80e6412ae7bc1b0acdc4426e635e4ff30a09cbaf565f35bb9b63a60998846bf084d343599d69d65c5daac35b394d21ecb08ec9656ea4c606533fe0a9b557e979c68921f4d7e6b331fd6f54a9bfd0fc050e052384bc6f1092316f7c7276566a150e29bb1e9df402535bd7ba113dc8d954144c57a44a84f87590e8d56cad18e205b2bbef2923fa9b9e1df76c79fd8177c43e45c5fdc1077f20a8cefd4c6cd12f4fe35a6552ba727ebd8202eada29c7677958ae513467e0474296b6e80f4ba52802ba63598efb3b388a29db1044d7e48990d9ac48eed26fd8aa0ebbcabb700d50ee8681ce49cd2421b02dc3ecd3a0f74bc89466a1398a075906167ab17b0402d2e085629096238bf79a60e4b07399b6dd27e58c902386839f59003a9c74c9d08dc79191bb214ac01464d9274dd579baf4fca3acaa1ed4bb5d2825b618c57d9d1547769964df96614a87adb18f0f5378e812f63b3a0776aedbdc0bd07c4c11a8d0a83bff92652c3f855a68e99106d0b68690ceb05d7c0b153169c886bb0da1d154c3376f30a34abd9c915543376b1856b7c43d7631bdfcc77219cbea5d5f4d8359d6eb71bc6d04e92d477a659d1715a4bdf1189f89a27b697e781751eca9d284fb95e528b20df75bcd5ad7d2f29ff1956f43fcc871a5d00aaf2db13ed404315913459298b85b59ae2980541e8517cd909aa59604669e70dc07de51b9cd3d1bbb5af60e21c5fe98f5ee8bc777382ef5c3a218f9f68c2f87f92c7bdff0ad4e1099dd66d8cc8aa758399b1b7357c6ea576389e95d1389952f0b04c73c99cae685b238b63d22b3b8e046b937e6b3afe329b769c9696008ee0f40a90a01560222f5e824bd5258d753a4ea5ef96dd9d6abbcca62bba6632ff55dd42659622bbd6d7ffc538998291395d066528c5f28d97464d0150f5864da488a5fa9ee535fb98a5762f266b1e93a2ccb3f9fdefcaff3df7ddfbddb634ee4c40a856496edf7fb77ea1ff3abf38ff7b9a2797b824ec13e441b6ad96063d08efb642c1b18a9c48037d7e185ca804ab14675d599ed4b09ceabd9d9fc21074a6515a8bcbc55965030f50aa7b6f2456cbd0ec98fd42b2d979b533c66ed5d922f1e931d37d8ad8c633813a33bc4a0d0d34cccc878fa65609629ee513694dbfac798b97937e52942487ad78329f12573d97f34db9946fcaedd50b570185edfb3c4284a78ab2867a86c89f58378564b4c9df6d57368fd01788cb46c769b75a2d460ee1722268634ff858eb383b2d2ee5630ea2a106a4481359f6640cd240f8a14bfaca72acbdf3930fca7e61ee3a9947592087ecf01c1132a5e38414e633c5c1e2c9b113ce981bbf9c1420c5c51073224b99dfceff3dc5399e38374c94bfa487562fe93b9b5a039caa70ff0052bfcecdb658054dc16eee4ab090d64cbad85b57da45a3c17f35f57c5be3ed83c5e42ea8ba7c91f85a4ba2d96fb25941c09fbaa6bdd55b552f34a5867c420c25fa59a9fa61b9ea3b30eabed6cb493d7ba534a53de1acd72339898fc0dbae766513bb8661e0bd8540b7cdacb63ffdf269168097be0e526f72a08001835500d027ab40f0da28ad1f5d1c938c5348993e33144e0a4716f301a19da47466699930cdb914c924056825443b0c801257059191093506ab32af62e729739a9c2905e5a865e53911e17a5ccb325a9107ada17436392ec9b4d03794882444333ce717a7fda8f9e891ded6f27683519b7ad7c0125e362a784e4c3f9d783c56a60838270e6626c6e0b2c4116ad142bb00fc90813e6fe3362b8426370c1b93bca9e99ddb35e256e36a6499b9e8da6b9ec3a914dd7895164cd2c176bda4facd2a61e19d9a19e6058bd024eeeddf2e68e9c9c593bc3dcadbb295c3a523cf108dd2522e15109d3fabd08dd8d419c5980af31d97f235404f0c5166259bd89465cdda7b4a204a0f3267cb71a59db9ace23b2d78c3b8d352564529bbff9840a5134e9d0dabe9c582bf01b8dd4cc95eb2dbd68b934b18c453b009908b25e09ea5e3b9733520a976de258593a40ca1d4a2f37ba4dc54dadd5222a16d13c7d9bc1c9b9a80bbd08855bb2f265116bc0a5dc4a76d43f919834297ad4c87db49287c34fc87bc03fc10ec4f1277e09132cb13cae590f4b29c1ca486bc4647d33b11b52645194ff29b34f06cc66acb2456577175e26e20a1f59ab29b297bfb2eabd766cbf1136b458089c90a838fec93f2888c31c5927799304fba04a353edf153757d0cecd539f0f994749c7518d824bb24ebdaa5191ae477662d3985de3b0eeb56a55f77e8689bd75ad29c25cd8d6bb671dd66106ce23836c0e2b211c5d955baeed740d5bc29afaa3e9bde5259dc1271af24f9ad98a4bf177010e7400d768395a0fc51f977964db435649c024de40d1c8942aeb15e86548b61f77b5b7d5bc56f48e1ca2583c86a2809d7a0422f04f255966ccc4295d4ed776562f37af79a80779008975ae1e69ca67bd5f3198a58cd693d415d255890d73170805553c0747a229990ddf138bb729effffff7fec7d123bd19d32734262bc7082a9eb75152c94556092926684a7cfe1b1d33bf64ccae467573047e66554f2db3a8ed5afa77cb77d5fc2a52dad78036aa864b6b69ca407cc165b2260b5c403bfa2cca6423325bd6c73964b1119cd0e94b5a129a875c366633975df02c67dda583236e4864ed2ac47def5afcb9b50d1d71c7ecc0a52950ae8e687f6cbc7fb099b94f0eac774fbb29d55ca7d9bbdaae7392d9ac059d9bd1ab137dcda0a4b5205669c34bd497fdbf26f2e0ae6679948d14b2979b11cb92d96b564c0b7886157cb7e97817e75d3cc4541b750629d51175e955e66f9416c94f6ee8382624a20ca1693970941a558ce35139648bbca58e9f6acf71cf7fc7bc64d773032a5e0d55133501be55892396e4b62a589b3194a94d75581f6ad34ee16fc54c7a9d5a92edf16dd5ac62780fb708657b1dee49aee413ce58a414ded80514c90293238c697c49199ac43f01193935941eec16f11ed2aa7f98baaed3f9b9556f7fcfdba35005180ab84efb840de713e555508dfc44bdf8767fe112639f8367d8149c2753e9105c3fd114e73750bb7319bffdef9ca4e4fbe9eeeaa037259e75b6fa7d69ba6e5bdc7f203fb35cb264eabf96bb3e5ec44edc7bf86bfb23669fadb63d920e577cd0f65cff8ed1db0c69bf4cf4b0e368a71b5c9a21f9e39c5694d1523f54746a6fc8ee0b44fdee0ebd7c9242949eed2c2ef70ca2cae0adf49c9d51b7cadb934320b30b4a06c353d49ac3cd1b6d36888d55d936b68698356543d5dd5ddb967ec79d9155a3588d52d69473a9badf34cb6a7a12ccf4332cf925729374e50708553a96f5f9b24bd6d6d92f447d62649bf7b6d92f4dbd6060425dfdc92b53649ea3c95ed596b031d88bcdbd60672cdb790b47f835489e78734c37722929624675f87c625e8df743a65995eaad5bac5f9545354b01c50c9f4ea33cc7bb64b4b571aa589ba74f34a938ccaa1ffe2b8dbce2600d3f0e0f38ee411c887c680eff1deaa17872b2c7854130e12451953bcc957b079ed395b7616fba23c353f728c6b545da39c6795adceb556651efb2cb3a9f2e820f7a8f3d469ab47a0e66c3502a3ef7b7dd3ef196b67bd065dd19a49456e69ed4c7b7c61608a83ea16a6ac62055d6bf8bba1ad2a5d75d9d2a6dd52d57bc514a7b51b3226e312fb34fbfff046fc8fec160b7caef4de078efb5e66f9bbe49a8c5d00822791ac92dff274752894769e392dcdb35fcd9ad95837354f9a3d355a13e36e694c21dd2d8df195af638af4372615125dcf2be9556c1c0a0c0cab9772b25971c3a3fac3fa51f3d14ae7c16c29bf66ea4adbfcf9ab60232fb23ce927291e7350749c9ba5103033fce5639175658ac41229dcd565bd41a585dd9407d6ad7533ae90f65b187c6b8bd5baa5347699a8644d9b2f66d306c7a978d57f2e05ab4dab4860be5bb6465391de5ab52d91ac555b2774564525dcb30cea5734c437c1ea563493fd3ac9dd59d5c98d3dc8e03e65ed6e6aef58f0931b56806b742eae90a3518afb9679370b742f453af25631ced24c54f154ca6cc47694d7d9553a0de85f271dd68696858ff44d941a174743cb66ddd9b5d2e21810b659aea5026470e42ca69507594b20c82c8c714d2ce2ed567b6713ac5628fb634626feef8d42acbd958cc009dac97c4a8a6312e5606dafc5781e27e1565d29eeb3489264329996f3971af22c57657e48ca01ac2b2f559fc990f203ced324edbfc0d18062905114faaf065d31f0d75171498a413271a779362d7c87fe798b27c4873300c2b1b3cf711671969b1679391b8f597a0173e64d3a20582b38b010aa85a22ceb385b5bce0198ae30dfd005ee11a697a75b565c2ea18da6a8222d59e9c792fda1eb45f2dc01574f3cd2b828bffe028fc7742bc8513897789cc4b8ccf28263c8782ecc67643853279c031e7da6b3dd2c69bdcfce144723dc274d67ddd990edbf2f886abb190d4834929faee794194c863636312b1e111c3b938c59e2f017d52c3aeeac209bd0d0a6ea7d9dd5f3f8cc499e3753165a65fd80226c82d3d2f92bc9c6ec991a2fc6a299923c87ef25fc4b97bb9914470c93c1f1cc209904064af449794cb142ae95f08f2d4ab2a6e8fa4d28c0705aaef104eef410f67151d2fd58ccd3883db05761cc1d1ee39de67f6e6ef1983a14c729e05ed0c9534a362c3ec3ca577724d389d0a1e13cc7f30e0ccd672961968d8d043a2f2381f9e63692982da491c49ebc9b49f349a835ce47909afdc3880e7b1d01469eccf59c46519e760276005aba9036565b49b398d40cbc5a304b6b6a4322ebcdcc2806b89a48ae3105894a64c92692775610315f608e45adacf2029be85f73899bfa629b59bcbc880568e72dff3f772ead1fefbf38da3fb9d83bbc787b7872f16ef7f8f8e2e4d5c1f1c5e1d1c5a7c3f7171f0e5ebfbe78be7ff1f2e0687f6fbdfe80a86b9a01921908e168649e801790b6ee096cf932c36378bf5758e5b41cb3f4f3f909eed715860cb32cb37caf6d9a67c9f27d5256db6589b20cf7ea6916e2895aa1e7603c6b9762a95a310ab2b8b64195c31983ad5f7e71de5334a247033d640be2844939c1c5a800bd167b330077b03c2928cf0b084117e1c5e19b77bb47fb17ef768f4e0e765f5fbc7cbdfb9b839cb66cf83303c5ff2ab363205e9fe9fe9b8d4b27273d929334225a6b38ef170c4eeba78c8a38bbc2f4f87c5d27669552399ecb122cd12ac2c671be6e4e994e2f9c25e37233499d092907595c3b32d6c8bb3c2b3307f1b694c574158c9420094735d0497605f128a6242f13bd61d3071dbdcea89e2c077586f9fdae534c49c4dc59c4f2f0ca7acee71017e4a0d8a768f819bac66c07e0349623ba1a24d1c09992bc97e513b0a977627a4c6a6b0ce5cb1c47a382fe017f63aa01788e49b918d9223d4ea3248f66639c43830a8cdcfa86350ee1383851530f71b4370087fc0d005fb79381f0f823f013e78c26556b940392b30af0eb8e6aeccc5d0a5c878ae2776f8cfb45d33926a406a0c023c5a4c4c9b8309b1467c892fb424abef2016951725496b1a556b403e4847e569a894949f24992125a26b9c46330a416213f8a7a109d1694429e3b27f6c27e66c0fa0ccbfe19e0f7592c2e6f8a1d6e857343d91982d3a573c4533e97f98c7ca6bc7629578b191aa9a1f9ecf6fd198ca73e37ed771c1a90f70899bac2a9138cc417ebe26b70f5156cc0557c34e2cc21dfaf0794743a48d055dea2a0900e6db9528476a69508878c88c8d6ba8afa743851af6b97d7121dd4d682ae38dba077043f9024855d8d9a75783eb0ba7a37b7d7817cde9384cd613834fa93354cf8f062b28b6ab1a438c613620fdfe894392517c51a0d798a09d819b7b535950b30d2ae67221c2ab7bfd36e5cda7a736b0699caa6a0ea2c6b87b426cacaee00a59cc502fc9a02a7412f73c061884b0f1f8f2b7b5f2c8ca357ce4f4ca0abf324df87e3a2a98ec6b0d82db175b86f8b2654d65c41031bb5a7bb5a0f894b1f723c9dc2c54d02bcd1b04e3626f412e35cbf80d8b753125f5cacabadc3914e6b4fe0e0aaf6d87ccde602712d00e1a43ec0c5c2e840c32c3e97f7e995391751536c29a67f80586b7c2e6aec307aa3057d325db6387a03f45b0ef65e0827514e2ea2ab8fda3746b062fd0bbdc1a5b9f6724bd8f76c6bfbdc39547d989c19fe3e7417d2c7cae5c03a30cc0b16b3912ac0ec7544e69b8c8325699927a460521c08839014a513d13be02a9e04441ae0529d7d4f08e5190e7bceeba428e1f6681f646391f182d612020b08a47801ae312f2e1cc41c93f2e482b2022cf644fd54cd26d50d08174516c1d3a5c39e75b7d0b36c36ffbe3c2f1c5a82e5656e50aa1cef73d11003715d3bcc333f189e8a06b9b77e83a3156bf67944e68c0d49ca8237fbad2bc644f5b72d99e48c984c65094ead298b45ff668c91617d97190b2040be910da2d83677ae70c1abc77770407295f760f032a405234e3cec8b8147ea0ca60b4d01acadbacb7cd2d256f463184a3ee55acad51b5cbc723ae02d6b01659c4db8dee9ed21a40acb86a1ca349bbafc8091da17a075b0fe8c88b381f267f66ded38dadc94fb43272afc80bf63af3028fec06681d5fe8d948585780225b39ca1eaad88d827e53f86857d52da28f88b423e85722c02c84af4fa8d94ff3c6ef1a591e8e574d5cb71a7e3688e044edbe7772fde6fbaa0e7fb560e44b605bc7db865f158409be2d6351ce0e247d7902d8c100c7c0321c129af6b8ff8bec4e4152eb4d5e6cb64aca5b9ec2cd4df3367b37df72abd0233de1f5aa5e39afdc5a65966ce6758acdb3758f10f6eb0426e305ee99725cf3ca92f2657505caff5cda8cd4808cf572fd331db94c247c6bf40f737364ce22a08f6ac18b8a76a28e775d4dbdcce0e92fe4838e1d6c24cdf8d45c7fa5e978b67a1904cb7f0e79e8c1ef092dfcce3013f6b2f1934752b6f47596139de6f60f354cbf5ccecad8cd1dd33ace589e414fffbf82198d1b7f3425cbccc5896d37536ebf57357db10fa72b0f8631687c1dab87da174fea2c22db05bd18f310adfb7343fc624c0b84d06410f192f80ddecf322b783489ee27567722d88beef38fe2648fdeb47314cb4f61836613ae0456e87a971e6de835af27df1064fad326ff054cfad6b4624db1748cc919ceea03263ba00e28c71de27ec8e07cf3227c957eefc44de045fef1efdb67fb17b74b4fbe9e2f8e0ef7d0739dbad563d43c0f0e3077981efdb43ff2c1fc0267207230085be8909905730c8d41e03c9c5370475539ce485a077461b5cf4433164b1705c2828ae7a4fab4bb6e9b475912c2bbe826b60161f8ad86e6c98e456bb7f725e4113e9d64d9a9fae0231d960b51b236bde0463e504ae25f9b7f22a6275d4ce4b0aa1a2b1d5ab2f65e877a98b7d838b110804f5cd2592b5720c7bec060f79fc455eaccc8e996ede6c4e245bfc9150484e70190d9ccf47a4bf7f3dfd0c59a7c53c2df13598b8e2a8247971ee72ab1f124df02604804b610be37133cbfb2c79fbd1f6d6afcdd6d6ff2a48b4c96331149e406866bdcaba7931c0b9839cadd3b3b3b3b3fff9b9f9cb46d7f54ecfcece6f968bf3ad7e45691a93924e7f90151035a428f359044651ee31eee13cf19a5a1707c5abac285f941974f13f676742cfdbdce8be5095cfcece7fdefa3ef117dd9b42fa25165509c00c55f3bdf5c2dcd336732645a26c324dc62416d616594f2af8ac719c70ed39b79a633234a152ff77b5cff672c161cec198140ef30662aed45bcc9d7431bc70d7ff879b9de95363b220b34faf9993e91843584f8553beb34e31eae7c63a284364992db3f2427a9ef09abf74dd2e3a83ff5c6f0120696ea8b4736fabef3beb3fb79bbf74d73d67c359ff79fd2c357712688771419c6432653652dc2f5dcff97cd14cf8243f83223c9b954e8863308a62abb192a5b9f584f95616851f92e0c78caf84c4281f9ab98f1296cdc4d50f21ae1c307c3d3265172362bafbc7db858a227a0bd248a868b0ab634bc7d8e43aa9e64d344b5294aea07b620477e80b58e39a111198cfd9564490f8bd62f3ff3a53911ae2c30e80cf82829ce0fee76f27fe9935b5669931eeca83e64d4b043e0786940c281a51d36752216bf75131cc27276a2e0e12ebdae53f9ada4c9d8ee954ff9e2635bf81defe33379d49fa6996d33b79b5fdcffab4bf75c77f99917c6eef78c1b3ea5c658eaf1c63fd2a9bb94fca237c7582fbaecd4e2614551c54ab5185b2be0550a5a12d01ba50e8d42c732e2ed7f95cf19d35c5ac9806823f9da513c1254905fed289806d7109333f17e39757fc3a6cd2a6e1491e59b46e181a00180c1d70fd704b6e71614bc11c2e5259090e53c17a3fd9825c357973fe4f509fff1be802b7a4e5d1e5c4d10781e5786830162fecb30d04d9d2cadbe4ed8732ebf23e9b9417a51c1ec34d7b8f66c6848d8d2a9e52df8de2f5886436ad4ebc28cbc9efc51ebb5ce9a79ecaa8b10be5cc1e43bcc299e082522a0c31db7095eba3bbed388ffe8040c1aefdd003f63b4498dd3afd9fe6f9c6cf5b4d724d22571b1ab8e5155f4d08b05a4d6a1eec5fbc3b3a3c39a4acc8faba617940dbef3aee3aa3cf6e9147de45bbb9ee6cd01ccfe938ebeb1474aeb74a6bf4998efa33a591206ee52c3a232377e08db2deebd519ee7d3357c7469214bcf73be44d9227a3292632adad690bd36838aef699a430c8d50825da55a804b6e32612d1a4d5e80391fc088ec0d7185dcccd61014cb246c04cfcccb2f274fde28297bd28063807239ff37a8b715579856096ed625c72c1123ddcb9e1e33dad52f935f3dcb24bd5cfedbb254d53c1c3dd4b602b4bd7cb6cc5bb64695f539133f26122e667d952cdb24c886a7ddba1f417d7f0f0a57f8579e428b5f434494a297e5832f93d5a9e099e7eb38e4788926ca84e787a55d3a3e971aaba1fce1aac0f28303a20aca270e1735d9fe0294f75b9bc4d49eb441986375ae533fe20a57e6d8c81aa05a20380240bb8325d2e004d61ca8c9aa22cc328fb9bfdeef082a71aa55e61fb61044f354a1dd7b6754c4a5b999f135c5204805ac2166fc55a6bb22363438209d3d239e578732e76254727262185e771c2bc484708ba122eafaaf3d25c05bbd9963cb20c152e10546dbc96d311a922e4b4a6928a18ae01625d0d923171dc8d0da1b965c50d992e5347c87e54a406257725258c797eda3af759f9d3f6b914980ad739bb712c8ff632733ed3b9528248ff6a7c53c4f149e250601751fa365e4c6ac9aca6fab0f01c71aad903c01e8e31d5ec42d66642d99a6d416ba8ddc0f813864516c2e959df4776e838be99eef08d6da09884eb4acdb23e8daef1e9520ca37ccdcdf21b54cefa4a7eabc6f9ce69d72a9cc5bc2b072b6cec13de2e88acb338e9ddff4cfd7795d30ab72dddb4bc9bc202089d1e65b6f865d1585371eceaebb58944235da7ed74f84173bfdba3b1e5be17f725d75694388de97d13349e9269f8cc96885fe224e3f66af7f8d5c5fbb77bfb2f0fdeeeef39c859bfb81867312e0640d42f64fd8b8bff5b1e6149b65201e4bbd5fd958df19fd7f673f27b0feb0a2948d131c6388b4cb30b89d616e2c21b7c0b514c765422b82935a91355294327a7abbab5c47babf7896163f89d9be4ffb598ab5b62d421eff719627c0b0effeb76189c9bb82fb61bf21779e4ba0acfd69026c9a427efed387a2b2e1a561dffcd04dbb4d180667fd044e3bbe8de3f6ba101d358699ac1d9cc6fb4cc50e7f986cd0bb06b00b3a157e8844ce24a39061eabcdc4b3aebd6e1dcdfaf23ec60c8a6de6f8d627e51b3cad9108aa8c158cf1adfce15db7f15af650bf8efff7717de2ae7d3be7a7c006b6d56cfb572d11ff299ecf1cd42a833b4d355ccc12162c97528959411c5c38b334f9329302ad1199ffdbfa6a31a83b859b7f90392d57516a31bfd9f04768187420badcafb694af388b8523d3d85370338d795631d3f85cd6f92bccaec3860167c1fac5059ce8171722bb23b2119700dc265ce5f3fa916d29d9d1099efe2037faddfbf0c7385281cbb526a8b5fbea6e5354adcd1f01aece31d5c0f7fb18a66f05f3bfce3409e0d5daafd62fc89d76ac5a9b3fb220c73ab6ff2013f2dde8fecf3222742677188a0ae0ddc591d4ae8d1451d65842ded37c7243ab454922fcd5399afbb020da241406dc69842c1c43112630df8d6d934a2da752ba2a8fd6724ccc3225ce29376966eba2343e4599e5449c9bb75b7cdc259066b5cf15cadc22863ee6a36627cb7d25d1bc555310cd075d9543afb0b6bd975c1a1ac0ff0f7befa2ddc68d2c8afe0a9cb3af495a1429c989673615c6dbaf646b267e8ced64668ea46d81dd20d951b39be96e4aa223fdd7fd8afb4d77a10a8fc2a329ca717232674dd68ac5060aef42a150a847aa34c268bcde8d12673d2cb971f56f22f0e5b0d6918ce50adea1c8ca1f462b40813259f2b8d45897f4942f7ebfabd59334757419245520f8b791acf134f5c89a1e0e26f33ce3359333b60d2b679abb8566dda6d86e57c661d95cdb07497394e6913b75bded75b41d14b88d0756decfb69dda88cd89881819b6117f5e25738938fe7c6a0f441b396370e3769b8d8945ec9812496868728bf288bb51c864b6ebc87d18d4e542381ea7b42aac7262095959232ade089cb77a5e56cd9c17e96dca729a5242c5482871e99a52d708ca056d5e94969548b3444239ca185971519e8b942d85ee58561677e2aad6da61225bf2ba16fac15eb7066cda369ab7309a77e54274e157dfd6b12585c7e970093ca4b9f4fd36f2ad023b63d3d81745c28d853e2446bcf210bf3b81d29b56048e639b197cbbb5d819ecd1b33b72ddde131392aaf78668dd596fe37767bf13bda9e14744b50349d7ad2c7712f0db1b159f157afd9015cd9f233e043fd80ce211d185113f7fa21bc6055fbe2f638dda0ccadcc5616dc66fe8e350754267fff0eaf5dbe72fdebe78ae010e3ecd09a24423cf77e153c42ce3e030e58df0409ef346987c515565e501801762032127d3cd7fc9972617cf250fe015241a984accc4955f091a6918985af85e18df89c6e6127d6d0b0089160630d28781c453eb831408083a0d8b3986c41c3a7bfcc74c5c863308c9be8b48abf2a97a031cebb2ca165993817a40a1f53b5d8df44999eb171f5f1ddd30a6f4b5ca1932e85b8127055ad363faa562614c3f51a19d384fc2535b213f71ea584ea11eb062946c50a8700ef90f1ebc2a1b317aa0bcd45aedd6225febc3bf26d5abdb08b88c6cf8ccb473a6f0fcaccfce243ecbbf80b6f207a29ffca58cd8fa4cd2d2ed34797f379f92faf068f80c0a3933a68f113dbdff764c69e719ad64ff706e29db7dec35db3bd8c313bbbeccc098a121ded5125e0b4a8f469aa7927c986a71305937e27be4f3ee8d9517399bd663d7d727c4071d2df57a3aad45e396c234cabf45fd2a1a335c66d447b5dadd04c8a981c37d619ad09964802e79fe0c63bc67dddf15e292f029c61927f3d3d195e41d46edc5c6b4a351e7f3c85d41e1259923d40c773864cf4a51255883e0054a3ef6cf808eed218aa720746a4ab6c8f23cab4552aacb91aee2a88068010a50e2720295c23975f68abf3af3221330f1737747e3ee8ee376547555730b23afa05a1af4eaaf1705beeedfd7990b51d77c46f25582db82e115e80c99e33f3243500027429dacca1db1e08d4ee9fb67b0dae07d521daf713722c154862c97979783ad8d59b0eb116316d24a8cf4861329e708f190ed286b05321bc8908d4e883f4acd758c094fec1642feca2994d56f78d5645cb2f69b1d791a94d7ed5c5fb3ae6dd3b2d03de2a352b9d4944b0f925fb359e1ebfe7d76cf74e00e7b6d38644fea7ab5102c59277996680e41916a9e0fe81081a8629c08707a33138ddef787b49f0a2ed60f53c5d878e1f4baa4e7ee7adcc2e0934981a0bcc9aaaab30b91aff5996e0e9c6ebdaa13b16cb2492e4cf80d3cef20401b5acf33a65d808234cc396decb89c8766ea4b562d9c258026017d1adfc517ace90979b4f627d87f9ba658a9797687d23b6c6d744d28007517db83778648ae3b3577143ad893fd2e062d5bd8a2bab7e6b26c0636252e7576f29d3011dab86dc1976728ebaa7d8df52d39df055f02a326ffb61bb129391b95efc69af31ea4149de82ef872b3b4ca60ae8107baa1098cfc9e96d50b9eccadcd98120b5bc987aee65809b14ed99851d723f8d4d0bb9b068525afd1f9af4583a685fa35a89c5a95976d9740b2627209e4df3b2d816b2e4985be7ae66b13c568bb99af45e3ccbcfc8ecffc8649274edfee32dbb6dbceebef933cffab08244436e3f70856f1afadd379c7ebbe13b98188e8a1aea56222fca8107f947bf6bfafc87fac2bf2aff2f14d3d136ccbbdd2200d7237283345452cc2a00c939fbed74f25ba847a19a1010f62357931219ab9ad4815709f58148becdc66d5479c3f6e7796a209b9a98e3ec143e6eeaea3857f2ed66480ae41183af7b733fc18a0b3426db8b8feb25a4779fa6e138801fed98e9bdf8693275cbc9c3b02e44686d8c4d59bc9b49639faa16a23b74d324d5005d531d3fdf36ca93c5099698d2b499805345ddeb452ea74f9117507a985ae1b29c100c80e6a9b0bbbd876cf79810e74201eda6f5bf163b259bbba95bee91020038d340113e7c6a6606ce454628adaeab012975a8491093edfdd0ab1df8e9c2a5553d1d263d6b5538f88841fd7d76ed08560441b822df4680b2333ff36d5dd5b0a4fddcbf2a412fcdc9d1b837f1088c12223e0d6987588de51c78bf2a11a91044917f4e37aa8cad46d9fd4e522a1060329008132a8381cb25765a1dfc0f4d1643446140392665360b13cd76f72ad8bb271a4008ac042c3485ee1e7fdfbb65f5d67ec40e4b0d5fbf75998059bde297fafabf488cd3c8c59479f781d25ff820ce2785127d18a98564836331554a432684598742b525892bbe9b61ee4591ab71dc34e0f78cbb22b9f4871b6ddcda461f0dea927b480cd571906f63ca8f5dcb905c4b5f4e4ec5d164c14ab85a840c9dd784f28f8423fd6a93edcddfb4394af8dfa6c8a5ce34c0fdbbb1473eee0b134cef3bf3bcfd40344dd27b3ddae1860eb279edc214cc72a70f060d2b70c59b8b5fb3cdb09c5c4da84a3427bdc5ad50275b0cee4e8be05972800aca60e5350035d296b6cc001543ffaedf020b80be84e075701dd5dc077bf27918ac8705beb6a1bd8e7c7cf0d08a8387cdbdd98ad8c067428960e26e1066e03f780506c6451541d644e3b26ead6465f80df79986f6ed1cba5285265aa80988a13895c2c2a9943fbb7218b9a629c5647652d66daaea015afecaa0273e8d32d4b483b15a896c15c29d5b24fd01c0eae4af8b038fe141533542a5335ec30579ce470c25498cb95c0688306991ca347c5becdf2c60f96fa81e4584da2663589d03293fc1b1bfe6e2156d69bf2a87e61099b2b1b8a81a8266c0b4167612ccdbcac85d2c8d0da1ea8545cabfbe119ea2f9f69b5ed81e7bbed3b7ab6ab81ce44436e942afbd6031c2411ee21fe7ffac4f6c89f1259daf1de0be6e03141a9910d75ef1ce2f6314d2b6efa37da63b211cc33bcf2c21aa19804b3bb7e8feccb90e90c8eca6f3386456ef43e55ce8a7e6fe2ef1a768ab657229e42ef6f5323866ab42af1bf861a7104bd0a71c970bc225594344abcd58afe469ac1f48d4087fbda0b1f0e8e4fb7a4efb23fcaec915105622286b21ac6ea75a75db5181e1d74cf7676dc7787bbbbd724f3e9e22468ae19da886bc4618520383c591e5cd75af2af896714f041e5654522d89783fd87833d6501c41b312bab35fba1c9f2ed10c36f96fd97b8e29277367d30a79c1cd88741932d44dd3de8b30f03437a608f22b4bcf596b918e4e50c3109fde63f90f7f3f137ecf8f8b4cf8e4f4f37c01fef9d8248447d293f52ba02b898064f54ba235df7de72dcee6bce1471af9aefe5e822b74c48772e242a5e7878295119bf51c075bd755c1fff90fa2bc3b2ffcb3e48b51deeed37330500d0bb79762e6eb3e7dcda99b202340f2059311755d68894bd9367d174ad50332b6624cfeddea7dfa1e274fdfbec5cc0b5c95041d5aef322e286a8c64759127df94935930c08c2416c6583e921b0c45a07fa1e564063320785dea3657dac908ad58ce549dc63af8efa3c5bc24e10b51e0a7a8f97d5c00fa8c5444f0e4f1f5ac3634b10b0217d9029e5f11e1bb1e3d3f020c4cadccb8a44fbae7e39d1fcb7630dd3b5d8707dbdc96536bc91785244daedfbf759970a0625ddc4c016ec3fc1cd2cd916675cafa1eaee99ec5cdd5459d2c8dba318383569812fc2763c6d4994c0a662f053cdf606fb7b7e634559ece2596e373f93777bc087da6daa6b57bcab9bc5bb1c784ad0494b5e89a2e9f47ccd4dd99737735e34e5e22fefd8c1b65d91044cb148617f003f697fb0e34e7fac2e69908c0ab1f1aebe3bcf96ccef90db0145e3d1645ab14254b01f7033182cc73801f9441e46d30e9f8bd914a4023884b38d66798497860acb8a2df895226b6a276d15d0423fd017d027fc02f20ee7b8e4b781696667bae5568197e9da67e1b90d81c6498e4bb490b6147dd3f69d946b8a5e1ba75cf8da3446f8a11bc257dd5e20feb805254ca703f93c1ab94464f3eff92c083d24912a1e7e48e610bee44e064dbc9ad581598e226fa79d3b055931e53ed175fbaf88a75210a27c4682bf4702a8f807b0c3fad219d5f9f7ef93e5d289c069c3ccdd12d3c43477fb8d86ea707cee7b4c388fa4b1f0f6125c58be95d0ee9d042ae8e3d5e23476b78032dedd62b3daa729f5a93be57bcb4e905da2ce963fc286ea13316bcc1ace40fc2e868610e2c905d0a4fd331a23aa60072e0c4ee9ef6cb07829f8f9cb603c7fc7d4dfce6451cf765ef2e6e1813fe198eaae3e803efa3206fae84b17342b9a3f7b70475a639902ed3f0aa1f61f056041ff8e8aa077ab489b564dda057b96f3c552a431689515160abafa4316f67515ebec0f19e96d70a9ce525134f2367916890804fc0fe564cd8e6eccd5e93d9f4932055e9cddd463bbb8a7cad1999f09cb79cac64151359b91727a2e5a4ab535b7b23506c5bc456929dddaeaca691675b53c10450023356baa17abd8dd7291c28a20c6ca920d1829a8c864aca0a690b12543d2182b85143152c610c35829430523050df58b1544b217295593384841294bea4e8962caf6cc9c9517d83b89bea7ba01647f6f5e8feed25bb45f91050b441f5bb07c2e43e148328023bc77cf474f9f456c17a2fabdbacb2d7155f06a1dbf25d64d0906dc0bd170f002b679616e8b83c397ccb0d431f738b6bc2f1c4ff8522e90ae2dba2a3fc8714482e0b4da37985c1a3dac3df08669c37292d34a88eff272c27dc71a3683f07ccf31288ecc9337cb0c253faa81331200b412e2856956e993997e8c5907f73d6893e964893feaf7a02853a165242aed963ee058bd2ebc8444b9d3497feedfd71d5aa86cb73f2a5576474d20ed0d26f99d01173ae57295f38a3d2b178bb2f8cb3b26ae1a51c03be199bb12a4979861a78af4fafe7df2651771ec8ce6965959566522eafa0c5ddc2a4ae5ced11b046163af2faa79448181aa28601e780285a7bc6e446548e15ce44b51d1f7f63215f2fe150bad45a2ef0d87b26276b66ab27c2017a9c657555deffedecec0bed801c0a63953e81c4fed76642b9d1eb6e36821434ac45b9002540230d3e5efc58c276b33d9834956a45931d30db843f89aedef0ddced4b1641f5f48d5b534bb26e201a78d084090b88805e0b1a19fa8d71eee1bf06991c7351c457fa8806a5cdf8bfe63968f3b1730eea7fa8eb9796a22e3a8db6f75ef24a7b11a819af592a8abad55fdbefa0b1193d6e421d4d1534d72cbad14bf38e1cbbd48e4e4768b8a0b441fc370b571fc479bc889a74581d3de033642df77c6df1cf2eb4d653f4db87b58cfafbcbb37391af1967d6f38e526cffdd794b1b42fc3657d716737c27af4ae91e3ba43dc54775f4976acab4427b5c095da6dae984d0ce64c6153d570b6d5d5a2f55669b4beb37647d14752c2f44852f9694d8a95443e97e7b6d35457155c35d8550a837fd9a18fa8404df14f76c854d8432e09f09a33be78d7aada8752847e879068676c8feb2a6e2453d2dabc5af0d2e795929b7fb9102a611a5f9e4b7bd3dffddca78eb099d82f2afa9b98503e7d52cca7f9b7200711b23aedab448a6c5621e96e9e4db420faadc3755b9c86aff1057a9062a8c60f78e44c253723f0f42a51aa8bb08a075bc730f52277faa4879b308761bf1ea1227c60352d3b5a580755be1e9dd3db8e9f8b57c59f76527ea3ea8b5cb06659a9d085db5a488260cb10932af5b20ce0ae3802ff9b2e74e4c1c4ecd0ff5561d857b278c31ab9aa4389c9aab96b8008137b2cfa55db3310a72344cb952a1c515b4787ea8fc437fcbf37cc2937320f7e0d2fc221397753fba82902839a1a3176c7f1f92d5a443aabd2d3c1a9c14a0d36128c4fdfbaa17e0484a27c30791c377f77bbd9e649208e259750108e5e956249740c2e3b622a09aa8587095325051b8bbd890dd4da4b0a4356e3b122d24386e2b02aa098f0baeb14316b17b4db38c66395a24240e2f1a08a38855a0e24e4cc82f423f1e87ac4ac405a2fc2fa1f80d353eb6688ef68a2a88b365776d19c2c06abf6bd14ccf059bdd54237d2091253ff44a39bbdf14c035f761032a3022fad66aa9fd320e3530f0b5de280e6c40150cbc5d68dfcbd18d73f2d2c86b9becc51c8f3933d1bc028e2834e8c3747370dde65b6713cf073c14af04bb105536cd90a44f4410769c1cfca6035dd94a9f75ece91f67ec74fe1f756c961d0986667892f8c854f61f7560c8410583b24180635efaffa883b10c5f3020c3f5c507a5b2edc0902412310bedb89b79075b4b5ed7d9acf811efa3603f89292f4535132a5989fe959239b8d3d946e56ba3c8e58ed15c698474ece036615608a42f9e7962c74d25206efc14798668d5401bcd0983b7d2f93607889bec566cce984e5216d36cb60215c7ce08de34cd41d7b1da8f411674ada30275d8e4cb0a4365297845cbb5e412640abf50be5dc79723fe9a364969c84cdd699759eedc47dc4d526a909ccb8b2cdd31afd53c762268ae954ababfdcf459a7d367bfdcf40e832be41dc5b86e3b9e11e193d9ac1233ae991acf90d0e63af7b9d6426ea653e6486b3a862574d6a7985e5bd184d911a85aff6130abcad5f2e9ad96acc4fa58344dc42d522d1ac69364b558e530e4981b235bc97156640d9a7f55ca0a8b9435fe210cccf672096e67bd554491c074d825e8e298fab4c516794552e6b9809f816aa883c95a59dfc2f7d8e30099461ea210e697cec798768c3da65f5d13f03b94a1d0beea11524ceaea01f4d941af4f5bbc4ddee24fe0b6c67dee68a989df6f6cb6b70169cfc8b8cf6e415b4711d97c342591ab9d8b758bf32ebaa2501e57d160ac48a9407a23b23b7d8e5b9610ec564a0c06c9cdaad315ff5d638cdc6220883ded92eea943da765e5f3995c160682c6ecb6ed6a2f79158ab83bee089effd42277bc455d7206ad75b80dd7e67ac2c3c3c03f92f387c20725fa86eb2261af1c09f29d53189ac321367672bd703d726ee89e90b063fb19fffde40718d1eb27f627474d326d278e2148c7833ed337a3afc7277dc27c5234e38b7d902ee48dd1df06d59bdbe2c227b00330c1f8287c1d3f89e7133ef704bf9a0bd916e6dadf2fb6e885f6b9372ed4752a3f4828a4809317227b36bd7a285a7d54583758d2feadd1c2fddba78af2f8bcfb5761bef95bff16a05eb44bd4ff8540397c3dc023d0ed17506af4c3ebe2dab001edde76cf65e834dd9a5b5c8112eb093778775b4ed68bd0cd5c31a66dbcc055444ecf570a02285f3ca75d664de41ed19277142480cd7577e5c027317d2335cb3055f3371953576b598e055be96ed88ab659e255993533bded0dae50f825e9fcd3bd4d678ea6e7f0723ba1be8c7b73e776fef928035a6abe05a57c5f3d497cb69591d154ac86468c22d8b6194288ea755b9789bcde6cda9b1d056d358cc5003af92b972927231dde2d4d77744a7e32db7433d35a6132d17c2f8d625ceae5a996a8665d0898fabc1436096ca1fadef268b8018ee7c19baa235bc38a61267b1d45d2c14b4f3cd1eeb3a474c7bfb76e22a64ce0d72920b744d8a4c8d4eeba17225d874d1e716eac6b2e52102c7b8d525f429c551632e8fd6b151d1886b76e5a1f4993e3231248bfe8259397351661b5989a46ad14d4d890ae384fd68f155f07f7e2f00c7a1c7d367b76d8b8d721278a8b31c97eff9c886363430aed753a5566796934a59c25a74a7e37d726b960864b6135915cf4f0e33fb39ba676ed9e42edbeeecd22ead4fb977b69bd05ea4c928e3fbd18bd8f919f6a4b718dbeccb90f77cc99b641ef5e2a2721c69a84a6b7900894058d9281861f94574eaddfcbf2ca3cd2feffef0f261e05aba6f54b7c090e0e30f03dde9534f015185e9c19014bae2edf6bd031d98b2b8b74cc492e1903d2f8b4ea3629ea34e07a8131a9da2ac60dcaacacb6e5d9459ca38fbcbd17b3659cd24807676315075ea904cf568389cac66f5e0524cceb3060231d5f3f2f2c364351b24b3ec71968ef7bf7ab4f7f0cb78a425ad65aedde7bbea8dbe8299f30a82854da9980b36bd026e91a03d65f3109476dcb6e82df63886e00873bc77aaaefcc7fba7a6c0881670cc5308f95d3a156dbe3fe8757637e8510d4dc4de1f30877af28584e7bce1e19390c922515da1ebefc083c933f07fadc8a21be2350a75a75da6eaf055c993bc2c043bab417f64db2b0142d32b01d505b7fe39a1cded4fdd7a2992cdb64b7aa5b103443cbb20934e275a431ab7f90670a04fb431db079b1b9d71bc777a7c70ea236ccb12749d6212479d84fdd3101de33e0fc3a068633dcdd7d71409adb741c8250d6e6398a52690c43b069ff09ea6a64c735fe0305448740340ce1f219cf056c6953001bf8f04a690f8dcb4c42cf9841de4befa588c7f3ff7fd85695fb6a80aa8630340fc97964ac923a475d37f7aa7302f5b29fceb982ca0f10ffdd8ca8ef416cca7b105226f36fe9e0f5f709021d4c945f9cc46ba19b37bb6723794c90607a5f7721b97e4562fa51b0297a448d22c51097c46769ddedebf0f452401b37cac3c582175ff94dd336a8760bb7dbc07ae0dcd7f2376afabd26d7400eab769cb5827b7bd756d1e97bd83abbed0d00ab70500a9ab4403a8413bba906dd3e5de1d9c5817460d13ec35bb3a3c8c6757d43227f6e2e0a8a090402f6c0ca71f505d47a0100d54e2e99b46c389e829f0c289e87de38534bca16ddeeb1af5d49648209a4d5394bf6b1bb31d88d2f2eb161a1e8b0ce2363852e3a5a9779878ff0456ce1336998803c1a1e2935b38b410e06eef0646157d7b42fe3bfb7c86ad8afbd66fd90bcc60992f87c309fcdb0742bb8d1e09db2476965628df61084129c245482f886a082de4864cec47d69db818b8939d1f9d17ff72712b6f652f172ed48c98d4cc797de4bd4b4212b9d6ff55f8d2024823109f8ee5bff22263ac78c23e42dabf087fb970afae6d972d45316fdbb75a0f74c99b397279f247441374269a400dd41c838e80e4b7ba9199cbbaeca23d8088fe28a01a64f7d02d6ab0b34ca16def5e801958256972eb0b97174e6c46e29d419daef6e40696c0c931fdb0420dd8876eddae00e3b31da577b802864a9dca74256e6bd7765e2166f1869dc9719d3967033b425455263c4a6787652a5e8d99c3b33ecace5231e5abbcf9d118059b17d3ac00b3d065ce137127277d0f077f0a7cf4e171f86927a4a336f1abf6e7311d2d15639a414b7a4626c99bc6e0daf5c0ddbe2ef40657e9e666f20bebf0ce881dffc23a93ce487e269d117bc86ed8cd29e094f15048b74a47f2e783c920e9383e0a1fb6801f7778a7cf3a7bf29f89fc27e99c6e55b0c3a111547e9613e7b66752230c89b3f5fa8c4e7c8c37716f76ec31d9ec23bd492294c2e1033c22f1d869d4f0b39bb805bb2f176251661fc533f4ede31da8342f724822d7e67913bfcc9a7966e5a23006725056a0f0fd8a2f24551c1effcfe0f8e4e4f474e7fae4e4b8fb78d4dd7d7c7292ee741f8f4e4e06f257ef71efba7b7cf245e7b4d795f98fef9d9c1cf48effe7e4e4e4e4f45afe3be83d78dc938932a1fb788c65657d2727a73de7ebfa3f7abde1ac6518139e9cd739afe768bfd8deff1775c297e2d99ccbebfb5076a12bffe93db655e313a70d64ad4c819b123d11d88a8308079b4e6afc8bd1acf1e79d025ab735ac06a6bc8e956f3870c9ceda5b5b829adaf2c5fc6460f450093448e6bc7a56a6e249d3ddc357b02f1fb1e1032627d3f3c98b9e2e3a3460a2aaa4124097bb166f88629f92f1a07fb63efb795536f206ba9a782687b41100628f2d1469c22e6d9f75fe63bfd36323d6556e94afaf11517a31c53fbbe35af43ae8ec069bcfdd762ad1df6f5cdf94aeb2c56a618a263c91f8907d24f6502f9ffce3c3cb172f5f1ffdef171fde1dfdef176cccbedadbdb326cf58781aa5af397492e78a51ac71ceb03ac83a72d76e2722ee449cac45522445ab333bf1fdb5b3c44bd2cccf9858093ba5c35cb55637ab33dc719f43fe03a43b48fe1ba82520e170c3ad270f9206291d30221df01fbfde9203206848499ee7aefe30ac3cec5dae29dee10cebbb9d2c2e75d42f0d3c15aac7cc997cf4cc58e9b06482688095e67d942d4359f098c21ca8b8650cb6f7f78f5ecc38bb76f5fbffdf0fec53fdeb331ebbcb85a8aa491086db1e836cb19300454bd350c885c0a89b0e0dd03d8c133c59654679a0d5c56e545968ab42ff1d2c4ffc62a70f2e4ed9e7ad92395cbd3380547f873c453eb374fd70b7ad4b18d31604fd7fa584606749a557563aa707ad75a8b645357cee65fda6e0f6083e0f0a1baac36fa6fc64bcb5933cfea33a6dd7029f631be0fa092070f5e958d183dc0cb283696d5e0c28e74e40c32ceec9982b3642a86aaec5c1c3535ea28c016e36b3611562c072a8b4883f5025822340094c3f151f37518a0bcef5e82571a1bd7d6dc9ccdaa1d9fbde4cbb3d3eebc6996a3e150240bbe9b158da80ae80fcfe1ed1b920f1e1d0cff34d81bfeaf5a24bb56b972b79cee3673b1bbe0cb5de3af67d78aaf1f68db55a876ca1381d608723b9ff5e5d523178d90bf66a2917fe6bc3eebab409aa2b99b67f0bdc17e70e9d014ef3352d3f0e9466faef0e146e5b8bbead752e5edee13fb7dbc4f1ca83b04028137a2b1b96448b6be33625fd27b86b187c1384e9aa27f18a8408dba36f941df538c9bf4fd3e3b3825d521a009f36be01ef6d997164e594b7025fab94b13c3217b09f6bc9446e1c1412a1aa84327bc154dcc5d684393069436fb1619a4705b0ed455ca4975ccaaa3a7ab3a37354211398ed2f00084bde7f8cbbabe86f8d9504066c1edc93ac2a459440dc51cb1cdbc2a2f01dbdeaf9702ceadae7738790ee00c5612d71c8e74875733346952870291091b9131f6e9b1f939e0cb65beee4aa2dc870a7a60cd35abdd67287dae9b3da94f769fb798f3ba8b217002453ec897f753df7f9cc7cbc8c185dd5205dc0eb031b3d805926cac055c9759e6a3cdb945a43ab9205d177baeaf0d03e2b0d8baace6668643f6020e2576a6e1253efaa8a8f3e26cb982f6a29e95c6054a10f84c65f9daace6aaa77ccec14d4fdd60d89342c59553b7362a7b02318cc4653ce2e048205219b5a7f1ce97cd9043dfdd03f9d5b212b5a82e1cdf65db0496d80b8e8fef7931f3254831077cf1ab66ccfb900215a99e843845ff30d05e8abaf0ceedc85c3a31b0dd3d1768772f0a06a4b3cf1ebad29fce7effa0ff3010e29852112fd28e961a7bcc3a1d25a679ef166ae5b175e5442906a273fa5a3190689e2ae0761efa30d3c9778da6176b52a746ee999ee3bf0b5e65e5aa666718ffe12cc6e81fbdfaf6e8d5d1fb7fb231db6743b617795041e5491d54b629d9b2ca1659935de868d7304fa44e04d5ee27d5181eab1fd67162c495119624fb9856f5987e1994a1b5dce14dc6fa79f31e63d47025da64f59c1cbb72e4941c7c9aa375eda9778bbd48766010722986f94058e5351ecc7cf06e041da51aa64b514dcb6a21796e36cf4015b52e178289e222abca02a3a8b5ea6dd68a88deae25eaaa72f6889be5b7225955757621f2b5996d35c3dd7a552762d9644a2d36e179aeb42172897275cff55facb7953614a553d3633be8f0cae914e2a0df2bed2bcac5bec75e02895f67bc69c51ccf2a0d59d9bc73105a1d0ad6d9033f295db9e56c00a35dbd197b9260edee756e1709d3116f1f3678c197b7c50c367a6f50d9ef1633f8f3862f834b0a0ac837040c9608a4ecfeb78b60f649c18269cc33a5f6b4a50780d6e867d41d801715f8ae8a087a225c86eabf43ed810f269dea1828d9338553a93ec365dd0de3cb20a8fca55905ca8e552c98685ca3e5d318a6dff891ef539c1de33488abac6eea88d6e32db7e90f033421e9aa6b35fd56d7eb9e12796b5ecb7d77ee70f7c54cf9486a031e4cee001edc5fb769c26b201a2839f2741eb31a26b74d858dde9b9fc1e57636109aba4b4010281057254e8558aa67a9cd5454e3a472d57a7a57aca42ec23e0527cfc57a034afaccc87f3bab6165e9ad8b11f5c4bef188fb6fbb0a283eaf9b08c9d1c9bf6980ebed22576f15f76e0bbda638d1c4a5014f299f59d7efee442e38c2e73c6e9c8d2113dcc0b09f89487ab421b2d355a714662e117734be28f5a4927832bffdec97655a8f791bde693b073f2877b29a4bea50ef118d6eab821b276fc4e059455726b2256ab3a86449e60871f51f09b7acdabbbe363695f7c6216f12088ce43f669602ad09c92229592a5186d7faf14a411e55c154a82712e429163dd8c48632570eadd0a56366abe8a25a337b13a9b7afbc9be28286af422c6b58251221efc42d4c4af008e0732d9168a1fe4df249b1761477625a3ed449f596a2782a5e4fcaa22e7331c8cb59d71a549a391d1b4381e891ee4464d065dba433edb110ac112161463798b60636ad34f1b93c75dbcbc8ec3b68c36e4db35b1e43290e45b4e4389b6517a208c36ddcceef1e0cbedc1078f6d7aaa86de34e100232f9ce0437e1a05cec6348631a192ddfca6efad1ac7d990539a794ad5df0a5c2d2bacf3e0c8c7927f2acee63c9419fed9f7a653f0ceab26a9eaea395104eb6176383ed8b0fdd014baafeea07b9b37aaf8f1d74a5faab3d25b3a4b8dad5ba65f1bdb3741438b76359975631f9d770ad5b3aa8fd0c38e573a066ee02e6735bb3ca98525f70306e64517f9de6ec663f90bee6b85a9e7afbb5f9fdf77ddb1a591cbecb42b52b586eb72ab2555c99ceaa46d16ad2a0fa8a8a66e3392756d5f4d9c9171f3e881a03b89d7cd1d782a17c25b44361b85eebf0814a75c4f8767836e759c1273944f103461eec05ed03d4728dde480ef6f61feec2d350d1f4d9b73c1193b23cefb3a322c1a57892e7e8b8a466e10312b029ca7c34295381519c1251d42205a4ae60b99ebe7bbe5b37eb5ce84c362d57e069ca685d7c7ff4ecc5ab772fd85472ad988ebec05148234f154018db5e5309018f653c4d33d4cc60b38a2b5d99722a174bf248aaf3092fd8c46d98bd79f2fec5abf7ef9c46214e916954e314bc1fbe2ceb265fb3869f8b023dbabc151cc22f2de534cbcd103866892d84644db294379a3bb14564be04ec66f55bdcbc691f5dffe01fd46704639342140d7ee665c2d1658a04f97695e732dd61f49d12eff8149e66699ae45a3b5f7fcd8bb2582fca55fdcd371d62fe48eb55a569922cac7be73c3aa3d3229d751a712383e2713dd698159ddceaf8feded160acc376cca8d90eebb0339912f4728775ced825af59513648e8c029bc84ed76b2024b8553238b0dd4d9ad4df7bcd772390a3f2ea289f8f62117057de8d7d735ad0180d70580fa863d628fb1c02e7bc4466cafd7671ff05af6e8107f7d0df9f8b1b343a608f4000064973d3aa52d42eaa9df41cb0403f2a9477cfb16c68e37639a9c9c366c9379a783a42c12de744123c0c8828df2a1dc09227da6715ca2a0fe0d011ee14db7af5cdf4069bfc8c0a24a5b69491b7b6e2c34bf16a4dc01dd56bf8e8df2fee9618c6e6b8a6bc9b38d80adf3e0baf87d569c3f2b8b46365eb1b1f75c088802f152d3da06cb43dff8723f199ad06d783513f264b21896b131db3f6419fb3ac0b243960192a045af8e426531233b3d0c62131a0716b01dfdb87d83587c426dbdab94491876523bb1c75c646124dbcc6e8cb52bc01db21b3b0995a4a1945b8104e2aa1e210ed8987d0085b972a990e0392e541701fc026fcb5523aae7e522a87bb782acddb45cd066fc0523ec9393d55a6653171d40acc02c714b9972f2939c5acb332af32e8a7a8f215d5e5214d602ffc86e0e71e7d926929cd7f5339ee7b00dba5a01b2cf9e592d498d01f74cb651942ca70e202c794445eae48b67bc90d4169e5039835619a7f7d1932f7a877895a2dd5b96759d4d72411a417eaf5b8b7cda87fa4cf76492db83b75a0341770318853987b7f589108571c82e19935dc9c98263760a219b10a9ea9ed18a4241977e9286eff178cc4ebe4096f0e40bb959c35c325af61833464cf63b5818f5f45477ebd5e4999cae3ef60e7eeb21ab066c06b84ea0cdc85e7ad9eaa86d59a877125812bd4ad4c0f52f5675c34406ba9013813793b2222bd78773f4e40bb6c382fec0a4e911105d0b43d9d4fb10e9a2d3e10109b8f90bd5dc1d012903b6d74e900dc731c2e3a2cf74bc0d159e83d1701e982691ae77880627648255ff6ad1984898afa7ec713cbd65916cdf0626228924830644adbaf1d1250f15ceea8637228768d2668a9b92f13c2f2f2548559bb00dac12d301c4bf11759e15cd6e9ad560d20c046db804159c5d53e1aec12fa370133b92369e57f604fa006cee7f3cd3cc80e2412cea86e5fb2c28a40e65536d58c8ea4bfae40a350dc3123d3faac206428275f8ddf25519f19874b997b05d723a5602ae3964be30a5ebdf25d531a6af6a6a47bc40b988774018a8be611220948aece6407169bf3071c59346233789c049789fb0eb92fbe9fa7d7156c9229928b6c6b1d855b4bbd7f7cfe2c165d6ccf1ab17419b9e64b902ce0c18e6817e287398235e79614002eea571d468007e4cc251429d108bf2c6463dfe2f7d4d05646117fb8f06fb0f95941339085c867485828745560c7eaacdadd8deaebb49cfbb53a387e5a6667c3acdf28c375472bfe575fae5d1fbcf7e9136f75c87e10579d2989e33e3f158117fd469ba7f5fe9d74dcbaa9f8c278fed67f7e40b98ac818ab970f2456ff4686f7fef613f8dc3c9f5e6b9067bd41771b069c567b4be3ff5a771401cc58745990a0dfbe7feaca5edaa94335629c0fd2ffbf356c08b2c35807bffd93f8f032665d1882bddcbfdbd7e1e87e3f5ba486827f7f7fb8bd62a93555589a2f1e08b96992aab4b5ea51f2a31d5b007fd65cb64adeaa5c4280df8b0fff378f2f8a4d800fa21cf6a3dbe83bd7e15af782116a5aef4ab7e1307caf9c7b5067ad4bf88034df23239d7ededf72f5b06bd2a520eb2668d4afb7fea5fc5612b512fcbc2aee6fe9ffbeb96e949caa5999bff3c241cdcc72eeffd924dbb9625b47b84dfbf2ff9a87be331effd2237d36acc07fff11f987b88412fbbabde2f101d3219a9043ee6036085b8cac94718ca12ff08fc33c33f53fcb31c69e5c4437d13b0b5ddbf6f5b35959e63c102ff34f8a7c23ff3b03695b0bab9c1609c24e1c6ccc51339172a43cecb783c5edce883e18944f497652ac6f9a14e7b66301a32163443ee1e798c4b5e6f7ceee7bc51fb703c3739ea2c1d2726e55bdc006fc5745cd844453fc6c2247dcf3faec78df97c2916e5b8329f6f802e8d5372c37fa3c8c57866a0d023080c636a13d556192f4d5256db89b041b6cdb4c929bcbe569397df9062de5c3d71b39cd98ad4ab6a3cbf098b99a96c2f36a7c5f43c87e0b7ec018a87e3f138a19592a56aef46e194d0ebd80e2f283c2c723b6c7343d637ab0107daa12b5ab3429076e8d481d6b8d30e3fa3f014b15a4b4c9d121aebdae197ee687fe47996aa7595b7c4e8dae23b8eb3b6d7d771e6805f5f7339fff867817f66f8678a7f96f8e76759c52d58d375d0a6b9be76be2bef7bee7d9f7bdf85f77de97d5f79df6beffba267e71aaf85e38fbff3238f95837e5b564ff6f7d7f4400a32f57b43d91232cf8884bbff373f3584ef09efe7e24e4f096088a5c4cfe007e45ca8c7840d2f09ea9d126c0ba665a5eef512c3eb3aab215a67078c061a91cc8b322f6799a859bd4ae68cd7ac4e2a21e49592a7a2aa079ddee77975f8cabe3a7ce5be3a7c75975787afeefcea5056777e7668c3bae873c39d64fbc3216bcab41ca9dbd0bc5ce5299b08361305a8baa78c376cb2caf29435d942de91828a3b7b83fdbdc17e07f77f909d97dc8afbf1c2ff5dc5978e866631932903f8b7e3498665f9ee4f755940a93e2bca54bcd771d8fa2ccf8a73f3498c07c0057c0a33e2946063effbfa9a6508e754257bee7c5b38228d34fd02996760a4839d6063f69777af5f0d96bcaa851d4a2c10ae2960a0fc27a4999a3b32935debb131230e71b1ae811c45edb93fbabe562d0de45c78b9110360452c94605bae88ea87d65ac146e4bd1e2aec38b223d89f191bb33d7cafa14d9b279b9d9dcca1a13059e9ab3215fe8a7569f9e3cc55d5b4c5bc379b6e274b3b543133181daea3ac95819d56a3bc43c85d3b62d0932c95698bacaeb541abb3cf118b790aed774957b2b44f063448ad73f08d3304b3da3a4332d7c75267d1fdb99189c1ac4cab727194764067330ed194475bcd1cf42798b9017b5a367386cd0086c8fa2044b93e48364ce4f75971de855e6105b8df07b20af533984b456c676af3b84f0d59dabd220f4a5720948e51ad9a5f08970ec994ee0c69103ae278e552224cfc3e428f8643259363094af96a7606d8ab824ec16a9d9118b3ae559b9a78283162c7daea1d4ac96f2af394057d7a17e9ad5c6d750e98b46fcb4ac21cea6a7c7218195f4b351246f50757520549846d21e751fec04573f261b565befce1bd60030545fa9a4dd74a433a10a8ebcabb720ea8e923c42684bdad74ae907e814d3898852a9732929f290b88cea6b89c6926f2b436159d65a95a35897967d44e4c51347099e5522ce88dbbe3698f0d96073d863de5f798e77519e9f6196e91b33e3b93fb037a69bb1df616a90bf4d6a521d093786f5b70c69dee18f23226896881c450edf643d3bbbf0b96c2a3d0252fc0300203b8d8030b1741bbcbeaa03a4b21e40cf06a3db244aed0f4159effc233cd8c5e393c37f02d3c9bab5e7fdb5c840b199f0b5ca911a394cd50d7d2e40099b39365476928df96a334f05b8df2c65afb88a2a978ee852852dc9acdecb47870b3107faff872a9dcf55b552f3fbb6be9e5fbd7cf5f8fd4630032a572c52782bea25be2a0863d11cda5104521eafa99a97b144f56f39a8a59250485f6531c4d47ab5719abb34bbdfc1108672a0624a33b73cc949bf2c7ec82c3696a2bfd164ed42e29d50b7ae3f7b93bebb3f3ac48497710c4ed09a619e06dbb82c5c25e6c2a635b8dbe5581fb7102031ae1ddc91a7d8282963828671b8fc2ce4e5470ddab3e5bfb4f8eb6d2e3f529dba5df57a7d17d6d1b72bcd3b9a8060e6b46e0ce5f2728a1056940de0529ad337bcbdd2903b33644dda6ae9221a60f7e427eda2be4e297579264b6144ff2b216f1c226aba5a848608c5912842e93a569aeae20c661e1e05ccb0d9e27ab1c8c37668619af35ea1262d4cd8aa1bc7694159b94cdbc47ad3554b0aed170288ac165769e2d459a71705826bf861635ffd773a8f84342f7fa0347799b5e4c6f54a7d4aba9e4d95127fc52003b9ba8de67c58c6eb2a8a2feb1dc7063d9f753f6f7396f6003ca833e1c6b018e219b121cc0e9094a47ca40a393151d8960bb368f65c56e508d062f574dc7032f574d3b7c5640895dd655c75d0f45035912e96a56931efa9ae89ad82007ed51a79968241ff15ce3847770ba0a34daef8d0483791bb32efcbdbe661d39a79ddea029bf2f2f45f58cd7a26b834d21b4bca903982c609370a866bf3b5d829034e5aac12f8da710d0d35ce1dd06b2625355dbd7b3b14fb7f4a8ed1e6ffc4992b553ab090d67f58865459f912de6dee843aedeacbbed9fc7c01b1ec321b691722133a94418aad99968249f5577153769fdc283b306957a8a5e9b49b5504b9f39a56e820b62b034b4dc11c5d9a66c204ac49e412fb83fd73d7b86363c3f24377cadb7aa6ef9eef53e633b63b66f852f50fbce18993d7997077610904277e531db6723d5be134f4535ec0e2d822c7f9cb129f9c0a78f2eba3dbbaad3bfb48c62cf4551a7d3f1b39a8d0963e71c5e479d055bd592f8abe3e7f2f2729015d3c1aac876cfd1fdd3c7412a863c9f95c3e56a926728d2ad8793dd8b7a394976f7fe3c58a653a80df4458d5329986290d0ba566481b58fe99aa6b3659589a211746dff069ea715dbf20edd504b96fb6f2bb11270b585c8478a11cfb35ac54213291a1b81f53bb8a511a26ed0060a4d41509946b7b34449669c7643dd69a6546c23a565dee6d2cac97439559d89f5459e9be7626d84c2d96cc16fe993588a221545023a42aa96b2a0b5a4226fda6bd150ea9dda11a938f7a9f6e211a189682cdff2befcdfa22a23f2139712db023d2215bee76104deb6e6ce395e2765256ae03c14e39166e87577b266cd65292b722412f26ea6ebed9b5ad138161c49b90b04dc5259d4592ae01de932c37567add70135c02ef6e3e9fafd651913fad922fe39430a3a5cbdc7adb3a172321aca69c215700f2a52133982f6a29545d6c8abcc228f1652a8c70726a775968b778099efd4c4822f0552489f893c49560b68a91b17e85000c365c4d0efb9447a8a79c6bdc2bb81e7990071fd928dd9bbc1b25c76ad15113e8e8ae954b26cfb6c07b7d2f1e5696f085bf3f8f2d481a544670c5f14c29e3be9953a79d22bf6352d4585e7e95510b5ed42d5aaa08fb394849067aa7717a7f2a8c2fe5d9c82a1be984ee3d1da2e4120431782364950e4122ad5c36f8b90e663205904175fb0a25bf1ae15759cf8ad310cc88acc412c499e8fb1946d8ea959b2e9fb2afd6f2867b4c15f1d0cfa5b1c83e4eafc6d50cfb3694370e81d567561530219323eb3742ffa0c1f0a0cc90b5e8eed9dff28454fc4dea20d87ecd5ebf72f94280a14522fb33c4719aca6616cb1ca9b6c57a43351f7d5a550d2b872da8882d494cd0a78de9bacd9b25cae72304f9a369712b6fb9d58ceb3e12bd15c96d5f93f7a03f61c4e2270415eb075b9827773521beaac81930cbed6e2b154d420b596c7782ad2d55296a75748e58550a403f6be24b5d5fc027d91576b6065647da682b9a8c46030d0e04af60c936c268d70e2e1fc6af471b1d63e5748d6cf23730cf73be69e5a36051d4182daa582035cb470bbfba60644479bb5d7da413aa44b77fdc1523bcdeaa4bc10d59aee7668f8f214b8d6dd7d67ab4bbc016491c7232a28230fa7fd9734d942104aa36bc25f92e4b07d4289d4feb98c0489d43d4cca55d164e09536da4152b1df5389b84c6e97cb9ec435ee9ed71654d3684a0f4927157d0ef6a747d45ad86a23753a3ca94e0af9bfe4ac2be4ad65a792b228f0daaa785bb0822fab8532ddb7122dc2ca80638f42e991cb02fc42547c2654c5cae98d7a617186ad9969d54c8aacb1e466d0573acaa694d639d6868488bd9faf54ec81b2327c95ed06761c7a5bb10cde4ad1e285563cc02a87f28f651bf40863dc7de5f2f78798701b071f65e0ab4dfc79b50d87ae5630c20957dbf3c2a6926df9e116e038476c6a8ff08e266f2bf6afba8501ac10f1c34a37b181d54646b0ba132b58c598c1d65e792c6165f8f92729e2bf460b74750c582d1118fd788aab245fc1a9b5bb5febc21a5db0d4d861f3653a4af8bda0306a5d806e49defca637986679232a0b78c173a3d479c17360be76f76fec908743f64e34e4aa58099eccc1a207b619eda0c992b356bf571210d36d2317b0553f2b17cb552358bd5a00a189ce0d6d024417cff5aea29557225d25c28e8cf727444f81b31d3661645ca082e454f60ddb23abe5602341068991dd6e6ca4bbf25818ba3dec1d325da191286ed1c09ee9e64d3b966dc18a565b30a3551b3b5ac5194fd39128f3596d603fab2dd84dc245385c279d0efdd1ce1b559bb9a36a03dfb3b1a128db163428ef6d94a9b3b97196a7ba2bd353ddcaf65451c6a7b2fc4404bde09f185f41dfa322acc5fbb9704036320f33742dd6d893d13209bc315c82aa9a176b72a46b43b40239fc018b9df0b427773ae4ff7d54fffba8a627cd825f3dc745b7b4303c75b558cd1a932ad9984b08cd41a83c72391441b7f4b584eb91862f786e09924b7adbcf0e557cc398ff7d70fcfbe0f82d0e0e7b24fcd734cbc5eb0b515d64e2923dd32a9b4999e722d1cefb4c240e562e955bfc5ad927e33a6365ba4abe6ae665c59e14692532f6575ecf9339675d7ece192f2ef83997ccd7bc6996f568389c65cd7c351924e5628899e4a808ce37dbbc4152fbe467f2347dd03360b459e82aa819d0ffa9a8d228e54f455167cd5a8bb7c0793cd40da764d2ac784ed86c1085a18108c4def4eaf50007ec6820066e436c9f2d042f6ae0aaf1aead9e0d941000c2d94946569db1f0cd0ba871e0b5f75cd5b9c776552b737089a59b7fbb2a24868dd8ebee7ecf2beb7d2a4d0eaca512ca6d5c6d36adca41c70bab2ae88a2a8f96e82265dd72a91cb7292fcc3d5aabf3d062ad331a387c537c25345511bc6befbef62aa8a7d9552e9d3ad393cab979c55fe10c5f66b518181784ba3cd8f3146e1fd8c40472649395f5bc4acb782532c96aa919609da65a890e28e7725071e57959cc6c84c6d840870e79500d8d889b04e4a674b31e01a244d3d134801bd2b37255b8a4dcd2356b40b117a9936cb557fc5550c14d5863d7f4705365ae2684ea1f1beaee3cd03fe4ad2eec7778990b1a3830e2ac4f6e842658ca0b70f8af523205cf4fb5701d60cd4c6a9b72a901782b92e6d0d3052059dd5c4c9b3e6bca651ffd20f6d9a46c9a72d16757fb7db6deefb3ab833e5b1f786e62751db43cfe6c2b7e7dad2ee75e510d7f4beb6171af80fa849e6c5d98f43b56f0d051f7ddda3a2b588d2907bf1a5d528572b33a644fc0990f52e9545c885c1e4b3546d36ce622ab587959d0c6038d4355bb6dc75def58e3ce622a7177ced3545423f5573d5427e562998b468ccc2f2fe369b6e45593510893649c5ee7f2f2953ecd8af79510233f41812d79331fa15b7cd54456c95b45f5bdea98fbddd76c6c968ee05f92f010531eaaa4a2fc1ead41d40f957cc99ba67ed754e58c371f47eea7ee429efdbc12cfb22ac9e500c9d789312b71f86f9cbc6ea175b541fd853d60d86762a5a07f166014240f1a2c8ae05a231203a4ddb082bdb5c71e51ed68c4524bd969f9a19583dd03678105fb1a29b0a239bed2dbc917476890442a4711e017c1b3156824b6dad8592bbbd070ab90c4d035d5626c662c99b23ecbe001c6bc8d0c878ac3adcacb10be603b2ceb33f81394ab45521669bca02ee414c0e9ebd430a9de90699bbb6cbf0f0700fcec59338d9cd70d147617c47740358beb3c38b81de2cf3395af2ac5d3be40048097c7076d8813479301c5934d98f289d8e2f844d5186336c7a1cdb353bbd777a7d499f6c894df36a38a1a45e652e5a82df8d762f30456b19d47dfb74c539af56add82fb1bb7e09386e5422251735912a65e687d54b99ddca63e657792df3fb5ef547f9702c04f92b180bb24fb4903fde4e00a78eb8587869f3c1c7276df4fbd43cafd14ce0fdffc66f3f29ac386492459b4aef5c4c0a95567457f3120966fc643167ba0880e165051d3edd54a3d473a18a0a88d29f16b310a3b803d3595c6ab5b6c519dea5eacbe004fef2d0c19903f16b79e1cc811a5d9425e2be43d5f22adb16f7d15f608aea5767289593de06cc59a392fd8de2721f727e174a1f099edb04588d36d987b2774956c4d4889205694b515df8ea0b7acb15646f8a31cfe3363eabdd70bd764bf654dc864e3499b055d08e7d99969c9f84549c1775596ba935d95976896bf604999af16c5ed47291451334ea87d645796535d69049eac119c0b7aa76d3e205a9649d63f33837316ed534e04db31796fdf67f7efb305fef4d7c9ae6ee43cf65d906cb513f770274676a1963fa823e827c90d1cfa070f3ef352be0144c6804aba50efd09e3858eea7f6723b32171e7fbd9277dafc7017019cecb38f3e5a3e7c8e8bd78a93f0f591e5f26ef8bb216800ff11ae28d087bbe0b3fcf1f1d722f6c34fc66cf6539f9d3bc6c12156cb9f1f3f03829f23fe9eb3afd94789bfe73e826fda015bed0165ef2317818dd93930c40fd8e2d087f0f709dbc1420ee0f63b46177777ceddf6cea63ace37d5a17bd03db7753d600be656f469fbd2934384e7f35305c02659c1ab353842d51b75cbfde86e19524f6cdf7cd2292debd623c19aefba4f4039928dd94bdecc07cbf2b27bd0670505d0d8e36fa3bde886d98ffba0d278bb7fa850f86b6c58e239e286abf90a3e69c708ebf4650ab25099fb801d901cf4a86bb3949668c85a480014fbc5ee9a980b956dc17b107452d2a5108dbe234c47897654b7a18dc3da21f5bb33bef8acb765b4bf19df81bd069e6e2b226651601bae8d5ee68860adab3e246af455cebbeca3f027f589919950a60ee16b084b2038180d670598b7c0131c70b5ed534f9a26bb8cd499a5029acdc5a60a647723bb144ac3e507c1f48ada35a5edc3991918a786348096c9dca9ec500747a46b77ab1a8ac46a26481373bb751878a023b8437aed63115f2e45913e0300d26b791c3ca0f86077363dca2c3970dd24b985fdca5cb9d28d433ddd7af6faf1e72f5d838bedcacd929a07a3984247584377a655b9f0f9056fca2460c836b85eb5e48909559d8452b8edeb34909ec0474307b21d6fa6b10f7df693df9be8411d920347122ff9e6f33e5bf6592d8c5d9ea1027f97a0bb1a96d50b9ee7bb976595a7943d6d23b4efe7c13e8d839e534191270c3a6785e095a81b56886c369f941510ee2a2b66ac2997655eced6f15a9718ebae2a277c92699dba4a5c66501628854867e2444b7eb4f7064f0b42e9cc5dd91f93bc9c0c17bc6e44651395d3c2b2aa87152fd272f10166a81e2cd7fed9722e4f882242239ecdcbb21638cda26267e7670376d4b0045ddf4d04cb7935d3121c9f029e15678a6e58ca813d89bca76146a7a77e74e5e2cbcbc497071ee9899c577dd6949fe3cc1a0ef54ae3626865eef3e1815d6bdb1593041445b153d3bc2cabae2c415e289c0da6a5a9b4b4bfcbb6b83f34251b4b8e7b87653df6ff3897634782d594ed22ace110d14f28151550973443373079592e5979212a57105a56a9907c1e9f485e0edc1dd20da1b2b52e66cf54579410f806aaad59a90cc696b9ee05843b112999bacf386d10501a506c5088abe679b99ae4a2db635fb365e4ee051332361c51ebcc07373271f95e429196f019c4071369fd165760ccbaaad4788ced5e5fb3d960ce6b5849a4b000d1eb05173b5ad1fdfb6c66dd42003d1ee838d8e3b17a5371870acb7229f4be563801d674ea66d680124c53966cc18bb5f20de05691944593152be174ceb9fc0d87ec45312dab44681cd86dc1015a4a2918922106bddf62bad9e799ec9be0768e7e27fdb274d731d892955894d4b99d97ad772c6dfa531e4d5aecc97066b40e02fa137b2e96954878231e072a06964cc38f7e0bc05183278c01d409279108d492a28b94bd79fbea3ba5bc7459aa88e6b576e0032ba76989dd9dbe6707754664c572d5bc138e3f073837c63a1e958140f731784275d863923162dd1d79e23d07bd61c7ed974cfe4e9fa27022f57c471b5e36f60382f2a88ec83fda3d87bd202a7fc2b53e0fb3a211f21c5547a88ed2c28b99d261df63ddac48f2559d5d889e522504af5cac0b3646901ef23e064add0ddfbef8db0f476f5f3c1fb0d78bac01e74cb8cb311b8c79959fa10c94b4d08f973a19e4d219f99f193909ad23d78c8d61e90e370f388595bdc378f78381a2113271726ea3b5f21a0f6385273d282b960d1a26640d4bf4cd1891b277dba01011d5d0f0c37177a2f500b91e5f25ac06e8aac8a665b5c821b4e2f15e9fed6b848e35a7a0c3b662c033beaaeb8c179202a99fae32904e25ce045760282dd8b2947769ad8d025179cbabdd972be0f41aedc751159af05aa4ac2c0c3f9a154d5526f520a907cb2a2b12d194c540a4abe14ffc820f0f1e56225941f0e8e1bb267d8b745966e97d5af5d9559fad61bba5a526e85772ebcadde39ccd0fd801689220cc7a0b184991aed80376c576d89a3d50eddce8b3a492fc2ec8aa2b25d7725ddfc8a28040f5cf55d3dd3dd09f7939eb56bd61157afb73fa1210234d0fb45b95b7e544540dfb8b28ceb3a2eeb087076c9235860acc793d778258eb8abac816efb0bdab3f89f4abafd2fd473db6c330f5ebafd9fe41afc7eeb3bdaba9faef302cfc3f6cef2af9d3a3fde4e061d263ffa30a7ff3cd376cff3f6f2f2d9bde7ff4d5a3477f9aec3b4d7fb55dd9f4213f78f4e523d2f2d75fb32ddb9da67fdafbf251f295d3eec3ed463cf9ea2bfee574ef3fbd113f8a958e906f8319589614e9b1a19c923dfc2f8a175d4d855d353c725d88a1b329644f0fe738cdf4d98b8c39da9ba23abad630ce1ab1c0c80210272dd30727b2e668f0952db43ecb95725a375bf18a178d7577f35af1529123589ff75dd53e7a45c6ed4ef6415e263c7fab790a0a047b505169e35d4b1ddea4149e2cf7e419ae7bd069f7ccee349096025df22c78232fd85abbe6c99ba391e637e821e2fa33773deafc62ee242f78321fe91f7d739fc2f30e74cbdfcd57d3690e3a3d72f27190f9ba2f976199f34468f6595fc46b2c30d23f4e88236b6bef83795dc7231cbe7b35fe15181ad6acff2e3ec17f23af46bbbbf44ef413842570a7baab14ecc04f073327b12ed2e8da8f7fb22e0f7482c9cbfcbc4ce6352d926200894a8bb55d56c2f37cc293f37fedb1eb643d9a6ef8ea20f7001d00e9b02985b5ee9d3a4f3f92ff57c63b267a2032ee4c45a9ab61b3f3265302a89cafb576e1dee0d1e08ae5d9a4e2d51ac43cc00e4e848a7228af2fa9b5dbbc6ad8858013de440a94eb212e40312914f060469bc6b41cd325afd267aa77b97801f02e37d306655c0d27655197b98083fae40b1c3fdc30e4ce4ef57d271db037b9e0b5005ee8c7ec82abde757bfa21015f4b3441ba37f31ddf3aef1a76dccf9587ee31ebce0665e13ba4d67ae932733add903b959754379b74c7698b7a2e5393cff34af014ac4e30a00abada710660300aa3895adb90ae73bbf65ec019bb310f70653162729026a16eca25244da70a27db49a86e15ffaa2abc1abdfa025a88655d521862081bab69d1eea55904485ebf0195becfea4660b8db0854591c3a931882dc720d7f2779e599777530da7c9c2de7eb3a4b78ce6a001ca8025a2c59c39d7952a699a8fb20910139345209a8ad6eb2e914ddbe94623acd924c140ddca78d65d5a5c866f3c63fcfb121103f3c2dd3759f3525fed55183a0bebe2a4dcedeac1e2829992e7b48b240568655d1642d8f62c6bda4c9d21ed1b45f3192856ddbdbbdfe76aff62a750497011bc3d552c4ac664f7955889afdf7aa61750636c3f04e93cfca2a6be60b38470e52702a35604781974959c53c9bcdf3354ceb023cee74f94599a572499215c4cf96b33e4b18c4d35e55706bc55e109798c1f5292957552dea21af9279762186539ee77b0f8749bd7ff068c8eb3a9b15105b69388121ecce57cd60de2c724384436314bdb11103b40350f5053693f8ebfa9afd825b56a50c6615bf403b7735e341863bf57ef648bb9fd219cd5c80b348af3a951caf0c33476c6ff067850e28ac54070c4b4523aa4556647593258acf821d30179571a0b9f5bbc3fe7ffef94bad0aa18cd7894befa24c4547671f15b5a81a700fea426536c30067f53bbe106fca1a95605d7827af43fd66da15f0e65655bb5aa6bc11e8ac943832cd9cae49d69874d6e882e8d57066da30b320e77fc693b953b3b2503f2a74ce9eca50ea1b85b884d715ef46fd0bedd753206023e7ab1f72d0606f0bd5e23bdc14c2242b6ae931cf33d1bc2dcb267e8c699fcb6569984f67fa2475fab6ac12315209fa3cc279219516e2f2b5b38b9811c047329cdb8c8588ee9ef08955ad7b582e26166e6b2adc5981ad07e2805fc66d246008243d8e997ef8dc8519c988b9886bda1ee11f5397c3cffa47bec12eeaaeb56440790da16565c1be7b8624423278ca85987db7b33e2910bf8f5da43ea54ab1ae873ef01ef0f38aa77b0cc3091e0639fbad3907ad390fa33993325d4733161c021598dfffa01fff249efd14bc52a182df5a690a3e9a72a97fa25925f50ae8784d6766d6c425331bdce6c4275255eedf6f76765c3897a93225fc7b20ee4de58442ee5987f3fb59d14042116d300af32bbdb23f2d2a567d36bd22b48cb1e9daf984cabfd74ccbbe6579e7d9b4394addb2cb553dc734ab8e06151cef9d2a7535dfe727a93fe20f928d5579dddc29d9441a4b34c6902b26edf5ee98b85034dddea1a9e81b670a5eb6255596d576a17a791321d37e48291f00dcbfef96f47d2a1ea180592dbbd1abe02c171cd5055817e3e06b07cacad7b4ac9d6a2682a74f1dab012c67e039515c89aa511e99fd76e4bd113859f05898a640bb9c1af902b4a91a60add79d9a15a2c18ac913272ca8cc1f2ccb7a70c576c98c60122199307706781d0253225e69dd019036a757ec816c6c4756f280a5eb9ef3be0cefd78132a61ac89bb2acd882171d08e4d528ff1c7cc6e5ad967d1455695c23398fb730b6e8b3f82edb1b7cd56343f6d59ef36089c87197125b8c52833a070e38e446ae5df63ce555aa8e12251b4a48b011b9d6ab46927e7471ed543359b3ea7f1e42402d30b6be2ca9b71288a6a51d68ca3b17567d2192a6acc86c5da04304389d1fe01a033d7e409718528672a51e30f89f0e6f0afbee02268026af4db2c50e120563e3067bad7d52f4bdfd815e496467aabe2437a212acd68f6597596afd7d5662a68cc44cadc6d2cc6e2d30a92f946e25eea94a5717f103863bd8dd6d456abc8876d03da9a876cbe9ae9c346fbf91236e48cebedbf71e390e3716fc6df6e1bbb2aad68c4fca55835e92d3d5325f618083013bf2c2bba13a132a56e8c3aef66ac4639b5ff2f580fd655593d870c27831468f675955377ff0cd4dc6753445dc645fb3ffefffeda32b1715db81221afa76416757849a3ba8eed48b9b376bf0644017af66e5dda380907f0bd27208c855ef123e6ad732583d350ce06643945072d36c2aa95803e20489201702f46eb4eb6cb527d4be2cf2b557cb44245cbfdfe27e6597bc66f5cf2b5e65d34ca42c5da12222042392b3a99f10492dda256f25f0b4356737d9ba18bc4375a4627310aa3815b984d0eeb1ed09612b296c21862153ca02ea57ad9479645526225d4160557889be10f95aa2013a490af911498ae6599e5642ce97d7c011a0638112b47ccd56c5b4cc53a110282fcb65df9c2bb5b81015cfd9b3373fb0649de4c25594327119e11a11a83221a3a75848cd4023ec61045271770e1f87ff692e34c80aec71ecd5e50ebdf19bfbfcbd39b8436f0e7ef3de3cbc436f1e7efedeb4ea7f91bd86c40aea99eadd1464c3be9ac61fdaa83ca68b5266e78a7525efb6a8493478f9e41f1f7e7cf2fd0f2f0c73bede987b7540728f5ef96537e65a8bd505575c78465c1017541480ae83995c062482a95836262a5d5e96e78ab763e28a270d9b942b0c2b3029afb4db62b055271b3743578c87ce952ddbddf5ae6ab66bc7d9a9c796c8fc7590bf766e5257ec6b76e5ee4198f12b5f7f57837fc3aedc4d0293dc02be665fb3b55b3bacd8ba0dfc1beb058a2c52004e9589dfe139b4568cdfaa48a9dc051891ab03b6cbaef6c92d5c562a13d7fb44ee92cad1396c2eb60e6152ae5a4414387c0059fb3287506ea9a50ea1dc52276bc1c9d53e4dd41294ab039a8aa294b50369642aeb036b4c87b844749594358bcb48aaf2a983335434d68287b885bba6481f6af21f8923bbbe5b884be7624144c8037909b05147680eb895440b3a5d812fdbb847e1b3fac562d9acbb3d6fefd432f7a811a06d4deb2f978ee9a21287187088321d4a436cbe2712412f095a56e2dfa2f445d3e13d07ec071029015263b036e06a140f618221b817197a63b4b421bcad10c210de48a2d23eb6636f9d31d87fb8f7a61de78e7a152bf14ff7c2e496581f7ab7f1b7849fc2a532f73ccde5f2e5b22a975526674d52e28a1794771c0ed9d355a39c9e4c33751fbca510caf878aaa56de083bfae570ba189bb6a7caf5303a0c375511128f87f736e2f6a4753ce7e8769a6fec0812522d3a65c3a5966bb77a944754716817a82fba3a471957a4e051f56e542e00d5d0d4580494f010792331c3b11fad78ec73b68b35959fd616cb076acedef09f210c061a81e828c0eae52cdfcd60eb94c194e1cd676189d36326b6dc220f0cb27b9748c67f94cfe54c6e3aa5d7abf80cd0ee0e17decbddeba74bb4f56eaf2a9f14f4b231b7e2e8a017b92a65e35f56aa2ad843277897437fd8385e4eaf345fe89e4e28c35e53292676c9f83f5c57c33a99109d7104648e919b0d4d189ed63b9deedb7316d08c26a01afd8c50cf199ccab7b23f2cf1368a88fb2df187286ed62d47c49049a6a8d867878bf2fd1079a96320ffc22e8761182575d484aa66f8450222be4b2d2b3c0290e445f8f95a7c0451a575e1ee52af3f46928a8d710c1730f4a0c48c3354b4bc0c484576bc511f8e4c47d46eeaa26e5a1d237c74b2f2234ae403f8665c5342b3208e03149b38bacc660e26cb25a2c31ee96f0e640cdc29ad02cb2c6140e238a3455a6ec67d998b99724ab02eeccda745a8bc635ecd1b2a8c3101c255d6de29907aaba58c1b54fb5770d89770aba45c90c0faee8e94299d418f09a3ec0edb8220e862f6176aa76c31be370c85ef273b952159c7e284f940bc5b20603154fd5a17c3560475384e9a3d61e2a0e134f5cd3ec8a65ce72594579da916fd81ebb7f9f6d8766de6481b8d44180f1f82ed545ecd534b37621e48ee0691f5e7c79a1c7bfac4402483c088a666a46185abbc1b3232831419c2a5418bc149d3c97870c9081b00abd5bc0381242c2b177a5acb6e649954db344b0a4ac2a9134a08c020e3fd7e5aa41e1e3b9104bcdf5b06a551424569969e3955c2e2c15ae9aec99b2be75eeb08e4739704f29db936becbe7b31f3e27aabccc17626e885a215a93a4ca7abaa990bfa5c1210773c54d4323ba7751cd23d05fce8699eb58b7b72d92097401e257940793d796926a2350ab41f02ed07400721d04100f4300442d2a753f179df351ba88381e8e3373a1e472d01e0a005f3744446e5e8296c003de8b98a0b1b401ff65c4d060d7ae3a8de1de9e32ce50db71ee1e5e16b9e99d8c173f6b7154fdf57c29c350f861b74da18d506190ef112523710575239e03056ac03765410b95059e46bcb18d4ac3b59831c1e3a9695454f559960c4033629b35480a1222a23bada190a18168df8f2345d81866be57f123a911955267c5c43f59c91aa688f5db37df57b57fea77e1fb06bf6d0f421d04431a9fbd1d48368eac36018ef9d5b2e95929b82ea56ba47c60ef75f5900f292b2acd2ace00d5af39a42ff30b21793f44fb722879cc5aa516c33a905596592e0a9b3409ae699f7ac5e688058444dced1d27dbdaa20dab8510395e334a80a1856ec9a9706603f4127e9bb676c0e67abd23df590df623e482c200604ea9ad65006ed792e7dd6565dbb813f35183df0557aa97e62d7d5d8ad9566e0f12955bd5d964b75bbd604e988d2646d75c8c6464684d29c5b94c79dbac744c3483b025fd5731a9b80d07ddf23608612223b866352f9a97ff593d02d96eede5501d64ac57b45353231d2efb285b8d48b12d40444043407f8a42ef35523f2352b4422ea9a576b17bca5d3a17ee60b6c2c7afec52f5d0c26664014db0e23d9ee8d2f72caefec908ef98b542ee91a855a8e64917dcf3c3e2ee024eceeb6acdd8ddb32081f5bdb0e115755e1b1069be7d7d91c741ae522fb2712734f00984f083cab95f72103b72e0d368cbb16cdeab0aa162b01628ee6f0c6cb322b9afd3e83bf07ced30c8c1e5ee0f9a45680a0a484b003231731d71d1f786d81d78163a32e8412df17bb7f0655afb5fae86da0a476bdb4bd422dc0e2bc2686815bab65a31b1865e3a1ce87a7a51c34fb855ded8fd85e9fadf1cfd5017ec93f4683d4d54b9d9457235a8dd17946e5c191d10b0e21001b590b3a922a07f0744313e0b5c53ee23ab0073eec0173e924fe9a89e6a9a89b57e252e3844337b56b144fb60e33fa16438a90460e5d87ed135e8b7fa06455fea46732334aceaa81d02e2dee6eca2f10ba6361aadd9db1050e5fcf34dc3fa370eb366921563d1c87fd7061feb9112624b87aaaba666607f0ea443e0fb4c4d76dc729b376cbacbd329e437db408323aa87a330d68ba291baa614b84c79976bca4d0d23db6ebb6e2cabed723bd0677aac10cc77983f215bb830de759b8465e7d99793bd35a58fa3ecb6e2008240845b480ef521eed704da7dea436bf68dff6a67ddbab76cbbbb6fb40e63de00d874afda906bbebbe725591613cfbb2106c0a8f0268b329993fc9fb3d26c5e7e5a5523d5b664521d475e4b1b3d7e30f8b56a17790d56fa0b0b3592754d8851f95b878e36dd50995723950815a6350b7aeaeedb5ccad2efe6c76130c06bb1c7f5c8f34d35641fcb97deb0ada1ee0b71e42db937c7b05868404079379d20e8e21f3ac1d9c5deb58197c963fd0fa24ee9d9fd836a615572ab5d64b41ba52a1a113817e668c7e16c8ad266b36cb2e045adc1173c68131a4d30ef63096e78db164d3e1126da30e386ec8b1811f48b8676077684b382db2bdc13e89e376ab58c2b3b58318a4a29a8908a703e91dfbc62d6bab63809861acc3acfd1ed4a05bec6bf430631ab1bdc11e90e11b6a59c69799bdc821f975d81aeffe35a11a46bbe3c8d42965e80b919749d6acc97e9850f5a3adcaae6387c570c872d130c1eb35e389bc6349c26ec729617092ec64f065d667c71d03d439f50cd3f8320bcd4409dee271e6622ece96c2dc9af1a4c1f711c73a37298ba201571350e564cdb8b6eadd1a7f69e39b311821713269a960dfdc56853ab85351679548957d2ec67e56f5f206ac8e07bfc12638fc55f782cfb573c85cc2ded9dbd36c109da211fbf3dee64d456d197f58d67194d1d3aa2187ad1b12e13cde5e6e1b499b156681f738876b2e53a0d02abf299d5c6386adb2d5f7d76c8fd8df3a783172419dda8c85cc81319181eee1970bba7640d70ee8da55ced85e2bbf5d27ff0fa503ef31f6a9c458b6cbbc6b07a83a285bf86ef79e9a764cb9be66ce377806f7570c89c1c881ecc9ae80a2fa039d8ee6f264167121883269a24874ea52f47daa516a60d65e4d07f4d068a9e9801e0e4e4dc119d042dfc9883b7dd6a128db39757cfa297aef90fb37683f617627f8e1c277aebe5284074604022f4bd664c07ea845cd5eac7251e9f742301fc82f904e1b5b9d8ce74cfcbc4291715719fe8b6270999d674b91667c5056b3a1fc1a426d1f546d3d724868774ec68f30a8fb8bd4dadb9453a598b6d4f6e5ea881ab4bb05d0831461b4504836621b39e8778d581232ae55b01ad7f0315dab64d778721bf55d153bdddbbc6acdf61c6d65cfc7eb825fb96285d805c7097e807b4a0f8b0d1d753acde13a9c0cc570ca081dc6a0d72dd06b2281bb30371cdb08e9e3c53ac8a644f1c2a1341792d25c484a732129cd05218972562fd8378ebf577f68635976c82e0ee300b227176b0260a817208199c536ee0fd6a1156aedce381e1b3b634b20c8e547265bf806e08c1033bdea1d4abc73d2d6311f5edd46ce972ccec070a559f786a8dc6d43bfa22437e6c548e50c4cc0f3568f46e6496459d6aee3b7425cea16064fcb740d1087add260282ae146f02fe0c18f609578908eccafbe867a988ed45f02f9d0403e4c03d138f4e1aacfd6d47de9b2acd5cb846e0141ec739aba86df02855ca80743f2352a6c00514f8dfbfa510af5438c0fcc5a34c4ad86e597821111e1821e227c5c05631aac29cc5aa9bd7bd3e68ed8becb5fb1fbf7b583932bf459e7bb5e806765e5819417180b180d4d4fecf3c295f5937235b8f2bda3c8a49111114381352d10f8669149ba802b7e095a0b8a6e68296887b4a2d64b4f14593394a28f4329baed8b6e672f9c79446f98771b602b8ab5046a33e2460143dc7d783bee3ebc15771fa65b62af3fb85f8bc01ecc470a233f3eb6217930d9ff2278ae0a7ca4053e86053efece1b23ec56d0a98fce2e3ab4dbe8e1276e23d3e226ed077366d52b904818962fcf243bf90e534deea1effeee5d53561c2ef8f876fe82a6d2628ca98f01a0bd535a7b593310c0ae7920dad1ab8299a2537717482652d65f018748bea9b346b5486608300f4375d95c798aab51c938abc16def80fd55801755042af842f4956c3353ae40557de5d43873649548ca4ad94a0d870ae0899f8f66c275533b656d9419f09f515b476f495934e2aad12a45bfb00e74ea155f880e1b7fc38e7fd1955831439f25cdd5889528903ac5cb176aefcee4802b817ef224b6a0d46a80b3d72d56791e77fae4be529a3ef4cd18a051cfa192da1866982dbe5f59d4ffab2e24d741fb7bc53778ce6c1da1b85d0e74ce8b3497cb3a0ec67c6cfaeebe98dcd3659c6e6d571155c2213dd1855113922c94336723f9cf0d158104a8ce9c07e4723abd652d3cf9d2252f9af7e55b70fef924cfd9d8ac8c298ba4cb38aaecb8ee61bc0a7c8babbf66790e92b03cd5de2b6b45446cf8325194abd9dc289827bc16235bcbd698690b44e6c811cba0b672eb9a056a49a9c8452387f74ccd62fd6d59413132616da8ec692db5d7e5cbb400702b248d6b0d81844937b225bab3b6f85eba9e0d2ffd2a2e99863cce4e07664e240e455050ff67abaf977996886ed6a701bcbccdc3da6da7b7dc27f2e8886e146f7bdc75fad02249178a29cb6dc04a08489355e249355b2d94735c5b2dd7a95a8afb8d17e6c529cac6ec097818269c28cc2c2c89adac1f89930618707704a0f375544c4b6657dc7983660e944191015f2ef375d7cd6baefaeeb8a252d6f8629f28b1a2ab79ddc6eb58bef79e9b14397f60fdb3e95ac7d359d5824d795eafd5b9ca786d881dd665bd8debd3b616d58548ff2ed902794474caa2d3671d3956f9b79c4e3b3863b1cde8948eae871c87e69de6bc7e7d59bca9caa5a89a75d7297c9c9d52db8b30e6a49a2612114ce0e03391f6599d15e885457b249e73f04c052db1cec9176c87f9edb11d76f245c78b69daee511754b6798102eced9e98eef2c0a4c095f694f5d93918fed064793dace40cfea485405aa0fc5cfb9caf04b80b510e7a18844e027b0e784833ee6627ab06c3cc2d967986a6530f50c1a312452a2a0891d2886aca1331604ff2bcbc04afc0790648d494dabd37ab9722c9a6596224c1f8b4f4c09e3ee0955680c2719325dabc44d90be9c8a3eef32478c8fe0ea320ca7f6f5400c8a654c5a38f99ab5a54ef949692af9aac570db5a1fa0eacc1379a681eeb68629f929705bffa071bb1fdbd832ffb4eea3fc3d41a03ff749eb7b98e5df054b00598084996a3a35051e3a4b63e4a7279bdafb3c5325fb36929d7a5664fde1c41c02c1378406effba5c083dc986b82a2666f8e0a77a9e150d5b15ab5aa423a015c23c056a74356670ce1c40a00a6a214fb5fde44e953fbb810a53a8d414aa3105294e886058788831c6c6ec177b74caff20bec1ab3215cfccf9eee977b7e9070727ffd508468dba66cec0e582f7fa3efc7a13fc3f7b1ec74039246704f87ef21d994bdb7fbdb5fa76aea39c8e8603dd23aa2a08b1afa9eae09859582f607650d5379e9aa153d5c11daa5a3bbd5a7bbd5a3bbd5adf56d5379e22a353d5417b55eeac23524198552b1b719879bc6c18e6993d8ef1fa6ce423a428ea5505187954644dc673f0d87d2b5292fe1c83095196ca0b5b80de58da63473d14eac62aa328740b2eca825a5258c7643eeedac483d6869a92be4dab87973e99386c838e6a4ab64247f526dbebdea845e9c00f54b010b00b8bae7afb3c23b824696d480281fbdcd92674f058662b14913f5b1b2a0bc08a67735ecc9c16ba0924d5c18a46af5c08bbf1c2c58ccf0408ad36d6855c7e9be20d020ca2db2102877fde835590dc993c4d7d0fd3ee7fd135715a8d748cb5dabdd0ffd48598ee3352af5c98b6aac3e41b3ac8c8b27fcec9f030ce69f5f34c06a227a9f78e93d17acfbe31bbf08ebbcf0187c097d1b970c1cba2dbc141a49dbeb78b0293152a67328a580c94b19e348d582c917156fcaf0d299f154ad9c386333656cf8e273fb74ecdfdaa186e37ecd89602ea7b4a2a349c7fa76eab9c818712cd271b2b7008e452a31c0c5a941cac537048440aabc2d120f37a14a0a632ce12cb6e3b91f4e7f27521505bd718b8dbd1b5f50be05b2dba58fcc8ebfa2e05ac4d59b54243ada2047b2be5cf03fc720cb61d878ee0282f741cdc8c5a2bcd5faef6fb6cbddf6757077db63eb8b11acc5a4dd4a94adbcbd64b9e085626c96a99a18daf0d511e999599682cbfb9717668b4f9b7545874fb207f5e89ba419b6b8c80c431e227b809ac5b7a96663568566eec94daa2d3a9dea3d12ddad64fa79bcfe62239078fccf062a8b6a372d683460d876e286a74c3a9d0af120aa86da6b31a300b607cc3d356c3c5ca896cbcb1ff6a9aeb6043c04d3d2b86ab629915cc3a0eaa0dce6836d9a9ef0db1e3d06271256de1d3293e6f4cd6616be0e536bfe46b173f2bb1e059c1c0d1aec8aa689b64b6965921a72bb4d08dda88e810dfe572cbc982281f466f0d148d6162266b98982c0507269074c9956f78210af4479db9230b66c0bc4ad837385c4f15d531325cc5325b033b2f612b2af28b8e027de30d0d0edff696e5f11733ed93c58efc8926e1a77d2ef4c83bdedb6ed7e0f42418223407bac4476978c36ecab6124d79943a37ecf6fbb53f71ef5ab0a029195704c0f3041099c0da5f3a17638f528c391b6c7150f9028510ff8ee6cfa3b9f746d93a571f23cc5b3bfe33d5b4b4ced0907d8fe86c647a365876fb443ed5817ab59489890ca8a8d22857162c38bb70910520231ed4aa19aa3a4e582580a6d41855630de90a2a1bf84b0c62cf425c6271d3665365b399a86a5f7d15ae3d86cedfce7b69c963212edff857f4d7154473dac53042187cc2a04733172ec5bd6d96808e407a8a725a39a8b210038c19654ab87c812e3d076fe63af27270fedca08b20eff15aeb2fbb1d550f0ad0872b28b6d602f60c62aec3618f9ce78619340eb4717a3a4867dd19b21895d5e8a85da48cd78a75f63c833d40ef68340e47641a558049b6aa718c8861ae233de728d2abca5cbbe7b6e58e4a466c90a4362419b7eb1a043d2112cef61a23f4a08dc3f5e162f196f0bf4074331c92f8291c1e2b14b3a7b653d0e93ef181019941853cb6d38d364294538a48c7da172866ba6d2f95d4b19373dc206d8ebd9fb653f0c03af1bfa6592e5e5f88ea2213970cc369d68c172c5bf0990a1b0524e8524c663970b259a284fe684bf56ece9720d6578ca8f2c42f88f23e5f35f3b2624f8ab41219fb2bafe7c99cb32e3fe78c1717fc9cf7d8d004559f65cd7c351924e56288994e68d5bfcb6e3c69725ebbe1e32e4dba7e8902abff1c5ea822a0f6bd2a784d83fc23397c98eeaa9c557ce13e6da96982470fc17e388219328c3854605ead94bf23cdbaab64a01a7a9a71229d07a442993934592eea37a27a2faee435cc00d287a46887bb5e49abc4f57731f9ee7b08729df1022331b0054fe65921c07d1cf86bc2c71a4245d5bb0d82cf4585da2772929fbc7ffff6e8e90fef5fbcfbf0e6c5db0f6fde1ebd3c7a7ff4e30b3666fb7f368669303bdfbe336a71b2abdf567c2689e1bb394f45d5edb9c03fbac03f8aaa115701a8374c50b47753aeafe1e90b6ec7ef5f3f7f3d92ecb60de6bfe057ac51a075f6d1444be412994c334b8306ca9f446e7e4e56d3a9a8cce74a629cf9ca4b8c7852bb63d30e20f7dc64f55cf56d5ef2e6e1012827741f7d69070ba128ccd75c18c7a73013152f6a79a09a14399ce759d5a0c5c049a09496973c1dc1bfd1e8dd3f28134fca92bad1ab54741b980043024c4c6f539142ea2cbd92bc47918a2bbfaa810f2b59d15db41220ad6b5fd37ed8f0a5e17697fe0dc522d088fc26ae4c16e585cab6bf493650f237661f8cc224cf71ca7bbd0c233fc1037c977d345e56e46fd2a8241123f5f724e62aa212d34ad47385e25d85bfd4db9f3ae7316350f026bb10af5d9d0dc666f90065a45e452ebc6ff402e84a00d858568493ab2b3242cb7cc01309aa3366f9f1c917ef5ffce3fd0f6f5f80ee43965e9d12e84956a41676a0203f1c3cefb358a766f9a0115740fc0e9efb05f6fa32ffed774f9fb83f7e78f5eee8bb572f9e7f78facff72ffa7af70f1279ded46ecd6fb47c31f32b279f2f9f7cf7e1dba3ff9fbdafe18edb4612fc2bb0f6bd886db7d8929ccceec9e9cd73fc31ab7bb6ec27d993c9b37c0ec546b77861133c922da927d67fbf872a7c143ec8ee5632b3737beb99d84d12280085025055a88f371f5e9dc3eb37a767af9e9f3f04cee95908e7cbdbd3f76f9fbfff227fbfbaf86035808b325df08a3759c7df16f532ab5dc8a4fd555548fa3b2a12b31d7dbadc6b33797a356612907aac73518414e4fe441e1d973493911a74d87014ab79c47d8424a906532d38ab8b16f627cfa24c352db7432cb6e09d82d53a91f00bc33af91e711a44efcd10591d6085a77a224f8b47f47dcfcac1751a5b849871a088076db6ec2a0e2c2f79d640c3c9607e02b947278bf2055a339b7e2c4a587beab502b0522c8f627e483533b79962a0e4fe6a39aa806530e5d5e9c7a6085cad75cd69a8d37aaccf784a79ad29a560e88f86120dd005efdee897baf4987dbadccbbedcc0d9ff5eb4977b63265fe4abb613cbe75dd71457ab8eabf7ab2f6dde705ec9dd54bf31a7a22982647fe83d1f79cfc7def35303d0e3c8f63e3b4b52afb5b95d6ba95765ecb3280e005e6557a5e2767080c8075870061b04d19b6bf928b38daaf39bece23fc29b64145de03515403e9e8e195505c1fdac495bf7f1342d66ec712f8ba8fa0f74f3a9c04080da6d5ed5973c8c5f8c3d6147b2e881f69b1f2e7bfcd976e78b0aa7fd987d6bc64fcb3eb55d78b201ecb73b74e1bb781754c682b0fc9fb6c7c4bf926e6ceaf2bff576e338da8dffb1c3841ceed08fa3a31d3b7274bcfdbc1c3ddd61628ebedd71668ebedba1277fda0527ffdadb93a7d17568b9d96465cf362d47e09ecaef3a5ecd702b802f63227f8c7bd7e588f60f65952734932fc66530aa687a4ebfb0af935591b64d6e52e6cc59422a91c3745598014f29dcd40956efdff73bb56c188ac984013ba895406bdec1f1092188552e04ec2d3be7f2032bba13f75486d3163b3f267629d1be6fdb7b6239193de1adf0a1f655875b2213e10616251f488cfc7beafc6e37e2ef69f16fbe61bd504935398174b48821ec2d2d13b33957cc82a8d74081efb3a6a354b8e974a0b43a586c1319f720dc93e312adcd060950e72cb10b0b9fc95cd3f2fa7574a57a726052f15bf360e01b619d4de945abe15f905dfbe008f9f18624fb93dc8e998d4d89292ca7ec560145cd019b321d6a25da7888b10a742f96fb1ce0ef9428a7388945993e3f3f7ffef3971f3fbe7e2dc51be439686178f132ebb2b0b0a2994599befcf9ecf9dbd3175f5e9e3fffc90df1604640a8958e0aec899f11c157316a6fb3ae29eebe9ddf507ecd48ec586d6c67611401714c793dcb818e11ed6385ed408c5e948a93439eecbd00f3f6189f3766c730fad76fde3dff60faf4943d763445a994667105bc7af3eaedabb30f637648303cdc98cf1e8ed9d103db3c96a7969d9c017990b2bdb326bb05902d88b1e7a7cfcffefce6d50508f1ce36f027c39502268d52ef63cbd9a26ccb62be0669b0054d611bb8b8c6148f4e688a4fd8a7cb3d933c832df9ac582d6b3697437f76b937d6456e32bc3bb8e1f9b72c17a5687abe3e65376af47040d2528a8a98163c5e322ba46c59ee68cb72c75b967b8ae5cc38203278565489fc25b165a1e8082b7474e05fce0ed3a0a49ce92faf210e5d29a4c4a164e6e397891df3d845557ab71e3d73c19084e091768f1ed6eed1ef6df7f861ed1effde769f3eacdda75bb7fb9b0f4d527b72083bc42138c7b17b52f1fe724ffefc9cfe6f5154c9e5dee565859e4cf71187f350b31f5f8b99de9864e3c78ca8045c52b5e560adb25055105b0200936a0f62859659f72d230a8558196c345012ecb2296cb9e816e517123383748b3dc6f921289ad0a1e93923e0b0d7b9682a50032cc52c09f13666dfa6915a72a4a7a0d2c78af3528826529d4d64fd71889b1e98b2c4b9b8655306019eb6ad2647c8e41e302140e2455f8872b5ac54b7cd30c6b4f59e46b05f3852537112d6d3358b79a2912bb7c5437f32fd75884bec380926ca6c0404ded1f6f08eb68177bc53ff0e63f0b6ee8d57dba57f5a8d3d9e9ae97516930b5b4aa9646a1f6f5167adebc849dda6c2dfccd40f93fa6498648776c9988fa7bde475aea24994d64c12322f81f9b1d7caf18b626097c78c0a779b4dc6c14a515f95e2351e66bdd337798596bb512eeab360f9a2619c4080bc0d0d2a714bdd35eaaa0f6b58c1daaa5d892173eb0d160d6861249f0d7a63ad40c513edb9054f5e601b55e2e9f1b03920d823eb2e6093ec746e079b8b25d892890e6d18d762d5b0999067860328e70d646f124db1282a085cdb14392adfb3ba2e0bcfae8c5d70ce5498c6dbdbdbf4d7eb4654a285288de8e0dfacd18a62d2d63c6f2765d6f1b69bfccbb7e93150df52349ccd789749f1bf0f4b4dced889fc4789454e44ca66c83845595b19b7e0ee3a0307d3569936e0d5be1428c0e711816990bfd316a5c135d55c56f2bff82ad55632cf7431b8ba87b557d5abee6d56650b3868a92b357c9a04a5949d0a0502f6b1e64286c280e14ffc421110c44ea41f0429140171814ba2b7367e8f777fa09afcea56e23a904024a631c40f206537fabdab09b12466c29e42eb07483a94be8a6a91a2a3334eb67569560eed0a904e6c78b5ea3023d24dd1aec081a7d5b9d0aa19e3b385b5a5519e100e79a2f5838ece7c006e1c70bcc82d63a1cdafd815bfce6e0ad1a4ec056e81e59ab5ab5a92219f59a7180595e1edd08f25c79c6207a0e321b1dcc72c43bfed4e80a736309375d6f02a877cd672009312fc9c41c8d58b8a61fab6e686bfc4d586ea1e76a0dcb7690b1d2f4b856674d6c78a7a9d2a8d90011cfed1bb52bbedb674941e4efee5bbf4d85bb4ee71a8172b0dd4adcc7f0762641303610fb72780db312d11c7917271774ac275304859c35fff0286fc276e4718c45f3e614763ffed22faf62afa36936fe9cb7bfd706fd70f337700901790370e184da6e74274ee87d27944f5187d839a32e7956b2ee57c02828c7fa25ad34ffe10516c85fffb9f8c501bfda4bfc63fc9aff4cb67a7dcaae54d60001a2f21f7ee68097db7f3e9738887f07551159d03867eccca52bb98ff763ff6bed088065e3bf6d4f08f996414f4d52b4cad13b1707fd4070fd2c7d31f574539835333f455f2170172b2e4184a4660fdf73f576dc796d9af9c658aa5d3a1ad55e890195b9890712cc9e82090f87513f701422572e2bdd49eb303bd94a75e727877f554fe6f3e8fb515a00ab6701753de3dc347a594f0fde4bd8e90694dfd9b0aaaf7f6aa11dc6c5b2dc41a046fbcc8332943abd4a81b7aebacec81954cff0cac6aaf58df0a0f8bc9929f378cce5ec76c1a15de8daacd947df38db38746ca3372a9438ba6fa2504805e667716aaba8efc09ef248ec20965f462c8016adef642fd0fdcb8fbc042308612226294a964e625a3922016bd4b127bdef800089d4a4821d9e2bd172060c28e3548f97b082c5de3ecb70859ef06f67e9824e645c3cf792b29de0daba0111e996cfd09827926977b8daa0ffa02da9a733ed319943b7051cdc46d3a1339f8af28431f9d06f2720f8d1f35487ac81bae73ea764db9ea7d3c8d3be9c5b73b7dba580fbd4174299f07b70debf8d0db86e7fb30d8861606f41fe588273974eb9d25454c4419b2f3d6ef19eecf521782074f71f5577838186f992c12c0141acaf29cd79de355e479a44929d870f920592ce5d966fca374b256db4df0703169a087bbab932d9ccefd3e2be720f01c832871e110c6aca8484a0695c7cd7a9cba6d59a7ab013755b74ec01cb8299bdc0ef7ecb54a39e3cfc8a3e9945dee6960977b3d3baf0e1c3399b04eccc409c684fbc164e397d2612e9675d61557a5521b8972c66e78d34a0922ba67c4ce57ca50787d7d16abe3384afdb1440f4eb62ed1ff1d695eb6f607d23c7a1c3f90e6ffd1d49e0e903bccc27f4972f7f9e718b9ef46eac3e4fedc283cc40d6f9a6266dd828dc749cb3b496a3a1319fadfcbd165ace2b71e408dc6d4f8403a91b194a12c001e49ac5935c475915f7bc08a16fd41afd61127c964344422c3fea10384129550894be7ef980aa76f6f7c1ad60d50b977a87fb41ce91f7dfd3bfa1892ca0b50c0b1a2aa57527c44ed2d863e07025a8a55cb7530538c430989f9505c9f35d9e2a03a9835a2967b85243454532b8eab7f260baa2d3e0935c8db743d2b25a3c96f78b3860c34ec8acf0524dd57caf3b6cb9aae25cace810e5df145519d43c9200e8a876f9dc29544bb5481ac8dcfb80a5e911655d10502d764623df4e4c49bbc5e3b4f5e800148556fc63f2faaa2bde62d132488cf56d8e0d56c3b5c68e1c535b58c6cb454a4d1c6760125071247dc3e34029e8a36db810f117c0549c58aead70fe275232a37480feee191d6216ab32c0ea1ad662a369ceecb8277afed474f8fa4ffb44d8edfa35f3bbeaca31c116d07faaefaadfb1aad24314abbfbefea744a8b98d4e1f44e0d0dca4661ebdeaa82ed27d2d0e7a8f01c1633754db3dbd64c0b903aed9b817a1638181029046f2a8b2d98e75de9ab8f2f6db2aa2db38e3351abf85dc836da00f978930921146c5824c925420f871632b09c2f78d5f14687233c89e450ea53447d42e784e4983d66776c820a8d113b6047c1e0491d7052386207586fcd26d64cd43ff7a25abd64936aad772bbc5a3312ccf82f05bf4ded55aa80f4b2b9a8f28677e6c689895557af3a0f9e529a36ac6e789d351c2374c08e880152805b75a22a6f213140a50365cb60e2050d4c5f369b495af337a231a6687e6f78aee8aeb42a0abd6671ff7cf224bac1ac0ab3b2158f9aa8d884fe6c15b80224e0d8478cb1e3746de3c685321844085c15f12d0b97a16cf433341e34ed285ed2de628a4ff2be04d4e511d71f4c5b5b9016f0e2e13d6a8cb40c65211bae2e663d59967a972b991746239f9311e3773c5f058a9ec70121867c37f812ec4089f6241fa2444739a023ef46c8620b6ad4268421497a650135d874b42dca5eb8be49bdc537516c1075f8e1146b8f90735e3a5334bb1bb3d9e61dfe89dae2eddbc3cf98ded66cf913e7e386ddff2080f71dc023478103f0bb10e0034f06d01ebb6995e59bd759de8966ccdabc1165091e0271c6de34a88ab25a96055385b2a80f30e42371843a89917b7ec7a6e02a409a4b0d2ee5e919a5fe7c4d8f4d5a773d32888bd25b0ed9779d390d109aafbd324f3f4761059491dfb1c72c91fd22a80c0f07970264bd756fbdfeba92eea6b4c2403bdf45cb3e889098777d9148e92dde57132fb267350c5d046e92a6c22bc3a49f8b874ba7e82e6aaf76e25756c6afe456b29905869bfda1a7a4eb09056771f4dad8ab62dd87488d410fa2de916c317781e0b8b54e2438edcf790b864de6f42d72508c895587f3a354af1c292f656ef58f2d9faf4a54a5dd1437daa0afa858c666eb2a5b16b9352d71aa46aebbc3302aff2cac4adadff5a22a5cd139efe10a943182091f826619bdf4aeb5245193a39ea5103411af6d3c036364156ca4e62e7bcaf2812da76701f6aef1681b6956d7bc9abdb82eca59e25c9c9b96fdba183883de7183eb322022b9dce377356f8aa5640ecb03d0bb5dee8d4344857d82dc48bd9b0e9828b60b3665977b2f4c04dbc284fa46c560ca2e385fb6ac2c7ee5185fa911b72d6fc0f2b0daefb4a11fc408dc8bee09eab2372b79d325cb7611df393093d1b25d6ca763d2b4e51abcf50c7551a657b2c4eb5595278b32bd387ff1e5f99bf7ff810178de9d41b09b8f175fccfb78174d640b09e3c737afce5e6ea910d39db536730373922bbfa6b01218daf5f5cc164b0042da8c1154bad03faef48f6cc329230901e69ab71dbbcdd6639536296517a8e1c8c592b3558d9b662b96bcbb06ab49b8a2e8018d47d79cdd728c090e76d92a2bbed645139dee18496ec6ebee5a9963460f3cd0da525df006e3161f65722e5fbc7bf3ee5c39f87ef9f1f4431c3df7dbed3654565691724278bbd98b6c12707a9bd9cd7e6467662cc28e9f09308f96d4732b9a7226675c1288a838bbcd0a29c8ce858e7d9b2a7a537ab3965733b83abde155175b47eae690da128237c316d786b44e645b0e66d53c6c5265fdfd8e701d10dec4ab3751e107ce725dc939cef5d9d4731de018e77cf30d1b2acf9cb30e232ff49d757e3db3bf64d51a370c5eb63c58d5c3f80fd1efc6a6479beea22516e8ea6e471f5d439c507b616a6de0fc61abdec594292a41c2d19f03d2c9a1ef3ff73001315605f31094ff240a33a40fd4a2825790b9cb62ed0a93e75d6ed494a1a2735853062d104d997cde5653a6964c7013dc632a1bbd40a3e6df10fa2464047470f88fa76c1a2a4083a954e962e205878e13c439e86787ae9574774e673a1970705b141b3529fe3d1974dfaeebe20a925db1af5f99f7ce053c706813e38f4a200781f6e642d31adeb0a088cc5999b51d44018f9ee731b418d464ad322834f75bb6d343175cee58e076cc808a57339f53a3fdb700763c9dfed12b1bd4b00f5ed97f6f1db85ad9513d78cfca0eeeae83a046f195ad86320d15c5032b3b527088830ba332f5ae6c3436252bdb84388aae6caf380dcd34b0b2a9378c5ed9de3b17f06e2b1b2f4dc9cad651abcdca566eb865d1760f5be1677ad62a33137485c7aa56c498d75fe508ae77959f9930533e627a5b9b4cd805a4ec35ab53459261cb6ccdf22cbf76e2622b847c3cd5e6877db21887a43ca5d58d41261cf0460156a9bdcd6a96f0749192d8ebaaed1e98e0f30a95b3ba6e44965f9340f7b2fabeef3e0dd1bb467d48b654ef87c6d2166c16a73b33f1b85bc1fadb82cfc36bd2dfeec0579bade53fa130688299dbcb06d6aedb8e2f25cdce0a29c14a0691fda48d04e2e2321836b2ebec464d85f5315168c35960395ee6ad3a5674ec56c28c4052bea7cae248d5ec04a478c0c04769b07262a90dedca30c16b7b9695b911c4948691523a290bb9f14bef7a4baebd92eb5e9f8ea8c9e0c096132d9fac0a8c211a57010ced0a9a604d48d25e505b1127b07d5b18738102442c0b4c3674ae8f6137a768cf31d189f7db90b6b2985a6e5538463e9675da8a7c9093ea211fbb20912c202d52b4a4ea32101b10dd60a9b5898ed9478bb6c94ec47598627373586643630e396fb044d57fa2e58106d508c7d8f68e944d450b87b23741ddd9b6ca24fc13a233e6f398d7ef5ab4da1abfc887cda754ce3eadce70f4200a293f5df3ea9c67d16b766356ae745273b97b6a9d14dad7f36c2699d3ebecc698f42b657cb09512a555d0f8d69a2b4f43334002411b5b28654c949c1e98aeb22d6ca29f9a065fd08c89aa7f3b9b90e99410da545e1d6f3a1564057c121c456e450f8c1646f8ad76115681074c1e952182d329ce5455df94dcf8f2c548e3d1a284c8a743e598d1ab82c64c4b426bdea5e8422c192a7bb083c884a9af7a2081152227373d990aeabe2872d6490e3097bc61762556780bd0f01ef6daf5aab6a308b7021b326ee358f11ee872ef4c740c32dac86d80cf52f622ab20d5a0e44cd578551aac79b94ed394fdcc7bafa08ce6715541905d51ce340c898e864b640463dc7907db8a20e1707b38416e34206d55d2c2ff0f09d28d09f0df04698da35a969705640a2381b22102b5cad0494345b31741590fae9c8f97efde3ad01a5e42760a3de9562164ef0b5402450f1a8502360bd7a2e52c6bdb6251a1d227964bb5138ceb5c565b79bc9a6c84353b6099b213a3e9fa7eb9fb05b0ffcbfa17664237fa6b4d85df81c48f6cb9ea3029d1d08234021ca2f583c014bcc4248d2cd13aa042432ac669259322ff55c997e83d62cd1baeb3962db3665154a1711028569a255cedfbdf6ae05913b062abd3bbd1b0dd789d1ab337558358bbf55e0c66755dae2d2e7aba5043707fc7a26da32523f627a921c0be63d416b5598c717c46c4ee8432ffe9a37dd355f9f76366af5243ee0afb25ff7ecc92834d17ad3a57dfce5c1059e3befe412df170e9a7ec9cdff0a605ab650fde2f1be93519fdf2775c6fe3a80f6243430b067b56fa3b56258cee83c0c1fe27ac4a4b7ca047df81fc265b92df640bf2db6985ba76c723f66483252b59a1ae89b157b5c7c075326133be71f3aa2107c6d1883db616d0c77d5d012b57d8b81e13fbe6e3dfb332557488e71d52d27be15050ae5f8e1946f2e6706f3dec224d4b6eeb1f8ddadd99a8f63bf66b256eed653b3250109711b5b9269d3e84af3c497ac0d5a2e395e4cccab5967615c9cf78c917994a870b304da6a4ab5527d9d51e900d1063256ec75a15bd28409a5ed572fc6bb15223a8b3b6456780ac59b35c22a207a44971cc4e3b9655edade4b5215935245d9593a0e24d7c3c65b990bb1f53ee5431886ad2ab55596eb6f19a4cd8bc68da6ec34112989e83ea6ef3766b68275ce470aadf9ab851402e88265674908d0d3cca2da7041beebca866e0622ab7e1a26257e22ee89bd9e0b4637d2d44c3de2567231d6b30abf2f062f5e1ca63c8e34d083ed14ae431330848efe8c37ab4f142c968a253e329e217dc5a5711d0820d46e7ec1b93097bc33b1ba966ae14f0f2ec520ecfb75c032d3acd2f4b0226c6293ad2a48dc5e334e2e94fe01bf4676fbc071ad2ac69bdb09e939958e26b9a95b6bd59780130fb52d1e66259172546fc259ed4f032696f161f6c32b8ae599b4c22f8814dc123295b72f0c8684d8567ce78da9b45a2fa08ffbc6ec4f2a2935284ae3066977b1dbfeb2677cbf2726f640c6f94c58dcac7c0f2accbaf596233a6a018c79d740d66146ed748563b108af15929d331482e669dd435d894eddf2dcbaa3d696f16d3cb3d12aef6f62984843c3e3c3c9cb4378bcb3d06053714da37595397300e8c999fc24332f95fdf5f5ede3e99e050650fe1bd93f5accb166f20d7209b22884f879f75f64107e100b75d5db55d931c8e6d3d7932efb37df6840e53bfa2956c0d85799a1709912ec5ff574d239a645fc9cc30b72a86810476c28a0a639adc2dcb1ff669528d58f869d439bcd4e4ac727778c1fcc9673b97ea607df9eeed7bb540a653b66fe29fecf706a0f6a8f184cdb3a234abbf52697df44ec16f6d1349986d40d6d5bd0a5064fba6a29984866c75997572074ed97b6522587379bcb52b7596f7860c9e6096e8f666b13f10debbe34bd9042e75494e3f9e9ebd3c3dfbf397577f7d7fcea66cf2db6f49fae487d1fdfdc4c5bcae98ccc492e42b820cc665f9630146dab205140d94b15c2277569c737ed73559de3db78535a83185a093b57819841dc7db049c7649021ed5e6af7cdd2614563a17cdab2cbf4e4ccd5ff9da493305fb24865f99d26e7cfa95af3f3f73546f1d6f0cbc1cfcb7df4237dcc45bfac192ac2d9a2014a703f84a8d8826b732ffdc0744b62d2aed14c923f2c3bae66cca54c954bfb2799dd735b73692533402c14ad3a9e4bebf7ef5de3db5fbd423a736d95255aa465350377f9db5605c0a17f5c9c8d9e2666209df1a5e910ee7a6b842939f8b9554eb49c71a479cae040c89478acc4beba58d63080ed86f20ebc9bd0ecbebd4c260e25975bd64ee007da48769c5e591131109a46060ae4122858d9a9d71e4d0e7c54272fb520a0063fc4eb09940ab82ac6379d6727bb8c9065a82d78ca42ca942ac42f1283ee5385f9284040914052c0e0ed925e600ca8c3c8cf56d611f6163542b188ca994dea03785c62c3c3ac85c5552e63003ffc12207d6a16418deaad3192aabe399ee9584f4dd3a4e4326887729c4afe8f690c1888b6ae1ce88acef8fa3147906809f39dd53f6326b55c56dfed3d167bbeada0b3813fea29014d44e21bbc2bb79b29fee8fd8f790ddd00ccba93d0a4f3373dee8f408e5da8e57fb0e55bc85e34dcddcfe887059caba694d0e0fba0307bdfd6c51ee573534b9334c36659f0c215cc066fc39c2eef870d37ad55e275ec5781e5baf90777829fa4e5bde99893fbb8073736c08638c5317e93e5d54ce92a21bd0c01a5297e2ace1b355ced96c559705a66af35798eea8dcfdfef2ffd802fb072d9b7f2aa29607c4aef46cebc449d97eefa162431c1a6d7d03361240369bbd92f2f01b8873661c4f9c7720c5066f2faba0aeff024553af5644fe8d159293f90a45fb2928087cb1d2a991f0728c823daed752bd1fb355cb5f6435e4e5416c19a0ea8764ab108bc6d32418c70f58e0b76c363b616d377bde75597e3d66cd121e5f72f978cf4e683151ce4e5fd182f04215950547f22fc26b637f64e35b8dc63fc82353f45f082bcdf2414831bdda0115bc0c869a3ca05d1cd36eed46e770c7a609867768bc9827c1bb88089da396c116954c2eb4b83f223b964421f4008692ec8b6a9f3d89f524defb87a06ec6b76feff7651f7a7171f19f997b48f7c8282d77cd9e33174dce5f160dcf51d0f42bc077bc0824b5da9bc59f6d8470a2fb241fbc3440e0bf673616aa08fdd815653ba105dcaa33b1dc9843c92be302e88a65500d1b852f6ee105ef5e164b5eb5182129ac430bf83d6db24505413fa37dd45f6da54b272f91be02b8e659d369c71c9291e84599b5ad1734198dcc1519cc94558b711142c70393b9e7b4634b51159d687475548860ccbc19af8b1ce3412f652b7033b228d7d16c4558fd80ba3bc1ab64a4ef9edd9ea56e75dd337610e9ee18d4dd422e2ab8ab055b1f5196027206d510bb34d179d98a46db81b5acbd16b7d5e84435c56c2b3a8a3de6189a4c82147aab92e3a22e5a9667757655c29dfdac68eb3283d49d362e7b1061d040cdcad2de475c677031968ba6e16d2d2ad00de800d09089799ee57851946795c45599757087d416e5da056ce2a74292e39ae7c5bcc8c1bfbf55ee23d90c3211a169820d9058171ca354e79001a565a5a8165ea7b54183ec30b1bcd2144c3a3b823015ceea971de277905d9622c360e124708823b575d8cfc76e8f7e02e5aa257edee811c93d56857e632fcccd3fa4d65b6692156ec7ec8ae7d9aae53e0215a0dba22ca52cc49775c77288ff68571246972cfec653f6bc6c851d055248ebc24405d08cd71caef998b624c302d630e1c4724d5762b68e0e599f34dabd5aadce0c32f769e25969653ea90b7393e55d71c369162a0ffc9b8855d7158770d329fb70cdc997a265fcaec6e300c87759976b342451c4eb827629d9ab7dc5d5fd6871c35376ee4c028c062c0d2b68282bf3955c012e7840c47eab6c5152f6dad29bc9a966bbd0f0399a4312a2c3b1a7ce41978c482bcacce56473a5f8d4c1e79651474fb56fa84d827d6c5770ad6fb73a74a7554e766d296e790bd7359d8e28efb65116574dd6ac537621dc8bfb4ae91c9d06216a4d0bfea36607c40b0d25fa8196322b5b67c912771836404a6790d1527653e14d4db0c0b8d8cdaad2b7af64f3b4111b81daae8a853cc8e5305adea9141500d76d0bee6b4bd122528b19cf4a1ba81d9708aee7bae6929741e38062c953f6e30a74b379d6f0f9aa3c419bdeac59a87e78f82d3a586bf386f3bf39f1772882ea86373af6f3a1797f4f5834227e212de0adf2d84c83b94877affd7338d88b56321fe029789d35b8e2c196b9cbaa19ec77adf2099e4354371baada403b4587b68c753cbfae8a3c2bd98c5f75705b75c2e6c51dc4e62aaac5a4e1b8f915d5e211c9275874fbf244ec4497956cc95b6d9629b99bd7e7cfdfbefa727af6e1d5f95f9ebf6153f6f490dc9593b3d6fcfcfad58d5b85fea04035b654aab228ea2b77927ac614d1ef4c211a6bca940a33d391dd9116a4af1f4da72431c30ff1425e82bfc20fc82e5f6655b18475f0413295636b4180a4706a223e41346627d11ffa086234e2737dea4e6d9ba6ddf6a203d62400d0ca06547f816f75bf17edfb0c720bd00ffa23cdae45ec3cd089f4af274e662c7cf9b3fb12e2bd910c82aed156bdba2a8bdc70fec6e0e2b7fb51389d2f9b6c4108c65c3c6a9b0f629649f278da7d351e1d9656520ca8ddb5d08bba986bbe8acf3c6e416e6990dd5345a1351ba08541e0cb5310ceb4b613754ab27f780946c1d60707002c165060d171cd6ffbfd3e131d3f91dd24fc7227ea5a258c90930b61fd51125d2c304bb072ed96423b3edc4ad62a9bcdf0d8e8ae3969c2137261f072cc8001f015f7f67a3e2f25a7af8408d26f6302daac2a7255ec215ded86969040f31a59309efd910aba77a156aa1726ce6cd391e84912c32f851f28912e3fef13aa0a3e0824df08c4f8f2f682e6795e7f58e7d42023c0cb33bf7c18b3d15d63103b8f20da4198f1e7b311f69c51f60edf6c0c29468f9d122b756f8dcbdda5af7db2f9787871b7cc54d233e94030c4d5729b366083eb6fa4e1b04c06dac1e9e96b09bffe1965dd67bb4cd2df8458be5bf54e9336cd82f99188eaeba184735a6d050670d107c7dd4cb55ba84eaf6e261fdd849659d71477b125bee09db18ddfd0290373ab1e214512c63aebd8dd786d448298f1b6edd652dcf00f82742808e96fd645980bc026b354b90effca0e9863908d4b62ccfc823fb303b60e0bba9412a3a0214c406e7a3d31863f423d4b7c46b484bd61421cbb46db0bf96b8b9e28992cde0394a036b48f10b6a44f39a34a90b124017aabac2c458e7e4df2bcd6f1db50bd17230e299a88fe1d4b6e446ffc9d5f72d9a7ecffac8aee51bcbf82ae49a26ece634ee5942b4a7bcaefb4bb88f9fcc1cdcfe70f6a1f7f5006df4e5910300e99a78230a960bb33c170de901d0ba37eeaf81a7ab68c5055b4a796254f0824d96d323a278421e1ffa753b6df8259e17e8c16495973a71c34f2ef5376681160dd1bfbdabb12a2e459b5a9411fa764c75c71bc5bd7beaec8f428d45bcc1b2c05cc916dd909d06b7e7ffd1a04d7bb12c4e1dc086ceac7d7afeea5819671e9faa921631098299db07f736405f8f4427049ae87e9e1e1e1b1f97a6f298e0881e6e7d7af54f31869d68ce9248c24ed2532074ed3887ad759fbeeb6d217e3c93e5185ecbbc6efa60ad596787c8dc3ed990a567b308dbdfcfa951056e15e7718dbf4d4f9f0f5ab7f3532d248718dd9e384e21c43768ca62d12ecd5e37b4df006886285be2ae00ba1eb522cc730d6c79e9a02f45c0c3a46820a2521c5a426455732347aa186f6bac9969c8e9fc8d8ea7c6b3b5e2723f6cd37ec9127673fb3abd53fd2bd75fc4883dd3821036281bbc5b97c6d64838913a4acea0bbf8e0ec481e43622295dfe9bc48f4d1648d50753cfb135d6faf791e4656027cbf9ecad68384c511be1ec097eddb2a1fbc8a523b241158f02a8b836f6745d237fcbdf8c2107fa00bc217290d21a104de24dbd9676b69f744f71644a6d108e7a0e182d5f13c5cc847d1092ed630b21663ac68051d6b6269fa693126a32d12a10d6f21bdec81a664794cb0e42ad495e64d1885565b3a4922337b6c1ca9317d534fb72d9468af809f362fe546135f9fe09985f3be4eaec13bed8bf61965de1dbc23549b8cf796e0fdf54b3f6f2ad9334cf1c782af33cbda52691899dbdc9a464494c4be9dd317bc2c8e391ebdf0955d66e95b55b65ed550945a9a9dbdbd478d7b20396e411318b1db0fc6ed40bf1e700a275c3059011814c825c474e8f6d64c188d4e722b6479f4b975e8c166c02a58f851f3c533b0ebcb7c99b2c49388962559ccbc8d854ae2a959f8a421be6137438ccb057e44c3621404966aaa161422cd6c28ffeabc3e54687f9867c4854a0def8304d58deb1036df330e3bdf28769c00f0144d5a1c48812213ddc29bb6e2ad3ec43fcc6d1d6db3a18d664edfba2aa3c02a3fbb2bd675a666bb0cfbde26cc997a259333e9f177901f112c9fd12fab95e67d5ace48d5634a431ee34058f81265b9cbd6c44ad288b5e225417f240e913b499d37d35d3450bf40c6f1d627276dbbaa80831bbfa3216bd120932993827ac73fed301c8d151c97aac2e41bc81c8b910e50c63f76dbb34e9e9112feb8533c716c0051f7b01f1097cad54b4cedad659877542cdf600025d24c6f5a12e122f3a51f71341744a0d656c9a579f2dbcbff4e5c9f87a373b56cffadc44e6ca9daeb70573d910d948e4b7be63d918debdcaf26b40083d184239763b094b0384bd8b6ec15b32a380adbee1a8cffe88fa184848950de140e188551e7c91d34e1eecf02d0d3210ca91ab6ff88ff102dbcf663357e1121eac845ce2fb34290051222327ba47c4bdd728f79ef030d0733c847c6d5194501de59c7f427bbd470250bb114a5dc90883490f0cc2bb890635d419bfeb48466d1d2a1a2f140fb441552c41e70e58c04efc4158f863a860606928728670a003e40cf1f20d39cba7670f21e5ad163c8bf0587f1c416ed98590a17a581762d480a6e8fb1808109c65b517b7133a4e19c5e8576cc91fed6f33a5a2c2e0204a0050f7dbde841663359906a2efada9efc5b5bf664478c422862ebc68bc042b9158fabdfb28c57380de48ba8d5e0aee9565f5438c838a23f4275031630ec1193d437ab6cdb87666e0687a414d48d4b1edeb4d1c33935154752cbf98e38c22c029a1bc9076383981a0f45d927782c205cc3ee27cb63ff6c86f68ec78cb2b565d5f0657d473f72477d5b906b7d51b602d02cd351862eceea44fb27758d2b55fcc8aeb84e0420d30781ed8aca66ccade66dd755a8bdbe4883d6187e9b763f0bafe811d1ca6c7ec841da6c731ad81b66630ec0ba2b13721aea7d08df1bbce7dda1cecfe01dcfe7898d1f62fc6b1cc46a9d25e4bda09701c284495ec37b0d8809e9cd5e7f76060f938479427abce9a6ce1c9aafe1a311e0f714a72171d4a5ac94641cbcc1a4dee9c6869686c649c3e5b9d5054894e1f0ccf7481ee84a301c5ba8b2224220f49b024fb77a29db178df8fd00b68df4129d0d73b18d450d667b222b030fb9e1d4656c5304a4249c667b3a2b4e8ec95cfbcadb27ae04e19b9d2b7431e30d27cb655e7b65b45ee12959bfef01a0d4853d619f529ef89f954740240f233b410f0017f2c5bb749a435fd08189bdf25ef78ed2ac58232f708e78bda0242df696c2f79c2471cd626f6bd0ef0158be2a58223a9a859865e620194dc32411425a49a4d21946cafa8b7b81bb94754274c5463f5309f9fc8bf2ea3616d5c1b12a50a546dea4cb3037eb1ba4208d7b5358902dee0f8eac3defb3cde438b9f7321babd93bdbdfbff1b0000ffffd9593a6f3bb64700", + "f2878aabd5b805cff92eea4c217d28fe": "1f8b08000000000000ff9c92cd6ed4301485f7790ae32d6a3c6edcfca0241b2a812a8daa298328ec6e6c67ec218e2dfb364cde1e8d5240628558593ee7e85b7cbaed1be525ae4113836eeab3f6d7a341f5192184b44e23106920268d1d7dc1f1a6a6af155a9c74ffc17f32d6391dc93d24337888aa655bb5cd263b7f27514f1d4db84e3a19ad911213f5d8518318d23bc61c5ca49af3c17b4c18215c3fd23bf63b60222f72ce644a7fb2dcd9399729516267d4a76871ed683250d4e2e6747a5c9f76f6f9fdb03f2cc5b30d0e0ab1bf7fab3e323e1eaa5ab07329bf32fb703c7c7e34f24bac2ecdc3e29f2ec7dbfdb71ffc48898c3e251fedc9ce1d85d9cfabf32f89f659cb363dede0d5da67adb20bb1aaa3d17ba47dcb945dfaac4d32da80e42ab7a3a82fc8ceb0c0965292a2ec28831058a5caa6d801970244c9b55070b7cbcfe90adac6fd3fa3163d2b1ff39a43797b3756635dd492374d25eafa3f8910422e7663537221eab1002e80abb21afec2b157136c3b9f9f010000ffffba9b1a5c56020000", + "fdd306b40faa94cc05d507bbb1bc7cfd": "1f8b08000000000000ff5c8f314ec4400c45fb48b9832928b35a0a9ad98e03700767c62416c61e394e08a0bd3b45c28a4dfbde7ccd73db9caad3f24a6bbccc11a6f0d3360000416b7485b239069b2650538207fea8e6811a97ed5936314fd00be6f71d552c8575e884de22c1735d0fdc7918efc4421e9c513a141e3441260df2cbbf8ea3b8b64ddb9c462e856ec10b4fdcb3707c25d8cd5dedb659789a51f89bfc6f576de2ed42ec27933968ff79a42df4e97c7edcd12797186fe4fa1b0000ffffa045f6503d010000", + }) + if err != nil { + panic(err) + } + g.DefaultResolver = hgr + + func() { + b := packr.New("AnalysisDashboard_App", "./frontend/build") + b.SetResolver("02e38721c5d141236986.js", packr.Pointer{ForwardBox: gk, ForwardPath: "cd6f8127a728e3217237b0f15d086205"}) + b.SetResolver("02e38721c5d141236986.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "af9187dffe62ffcb604858b3adcfaa0b"}) + b.SetResolver("app.16de3e5caaa0ea30c806.js", packr.Pointer{ForwardBox: gk, ForwardPath: "a1817dae2c5d2724ffa364c179e53b2b"}) + b.SetResolver("app.16de3e5caaa0ea30c806.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "2968a8ec00c8e84bb194cd1ade785253"}) + b.SetResolver("index.html", packr.Pointer{ForwardBox: gk, ForwardPath: "a34512b7858425d220a55a6a2feb021c"}) + b.SetResolver("vendor.3457f7aeedcc46a1723d.js", packr.Pointer{ForwardBox: gk, ForwardPath: "ab9c4d30021948033f1365fcad58b414"}) + b.SetResolver("vendor.3457f7aeedcc46a1723d.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "04f9f8b72e32aedb4d0f836ef9ad9e65"}) + }() + + func() { + b := packr.New("AnalysisDashboard_Assets", "./frontend/src/assets") + b.SetResolver("index.html", packr.Pointer{ForwardBox: gk, ForwardPath: "a531f1ecaa4c59f1b1b4d21b3a1bcddf"}) + b.SetResolver("logo-header.svg", packr.Pointer{ForwardBox: gk, ForwardPath: "cdafeb8703e8d4201c7f208b7921b261"}) + }() + + func() { + b := packr.New("Dashboard_App", "./frontend/build") + b.SetResolver("7d6930a1c4a461e4da50.js", packr.Pointer{ForwardBox: gk, ForwardPath: "360c94a3ccf2d956c9a83e60f5b96cdd"}) + b.SetResolver("7d6930a1c4a461e4da50.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "464b6c41f07a2f39a73d7d50cf88fd94"}) + b.SetResolver("app.40f961448f3a14a1d67b.js", packr.Pointer{ForwardBox: gk, ForwardPath: "146f575b9993b4bbd5fff95d27c4337b"}) + b.SetResolver("app.40f961448f3a14a1d67b.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "8f27e84f7d53f655652def702b1930b5"}) + b.SetResolver("index.html", packr.Pointer{ForwardBox: gk, ForwardPath: "f2878aabd5b805cff92eea4c217d28fe"}) + b.SetResolver("vendor.81a625f7f838c1997488.js", packr.Pointer{ForwardBox: gk, ForwardPath: "4d68cce57fd2733e1b5f2e94dee17498"}) + b.SetResolver("vendor.81a625f7f838c1997488.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "dd5c8eeb04afd962dd3f8390c15b6ac7"}) + }() + + func() { + b := packr.New("Dashboard_Assets", "./frontend/src/assets") + b.SetResolver("index.html", packr.Pointer{ForwardBox: gk, ForwardPath: "a8bc022275366f5e8ce8a9fc63118a67"}) + b.SetResolver("main.css", packr.Pointer{ForwardBox: gk, ForwardPath: "fdd306b40faa94cc05d507bbb1bc7cfd"}) + }() + return nil +}() diff --git a/plugins/dashboard/parameters.go b/plugins/dashboard/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..51c425c6144809b9700a21a97daf75a46b6eb35e --- /dev/null +++ b/plugins/dashboard/parameters.go @@ -0,0 +1,26 @@ +package dashboard + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgBindAddress defines the config flag of the dashboard binding address. + CfgBindAddress = "dashboard.bindAddress" + // CfgDev defines the config flag of the dashboard dev mode. + CfgDev = "dashboard.dev" + // CfgBasicAuthEnabled defines the config flag of the dashboard basic auth enabler. + CfgBasicAuthEnabled = "dashboard.basic_auth.enabled" + // CfgBasicAuthUsername defines the config flag of the dashboard basic auth username. + CfgBasicAuthUsername = "dashboard.basic_auth.username" + // CfgBasicAuthPassword defines the config flag of the dashboard basic auth password. + CfgBasicAuthPassword = "dashboard.basic_auth.password" +) + +func init() { + flag.String(CfgBindAddress, "127.0.0.1:8081", "the bind address of the dashboard") + flag.Bool(CfgDev, false, "whether the dashboard runs in dev mode") + flag.Bool(CfgBasicAuthEnabled, false, "whether to enable HTTP basic auth") + flag.String(CfgBasicAuthUsername, "goshimmer", "HTTP basic auth username") + flag.String(CfgBasicAuthPassword, "goshimmer", "HTTP basic auth password") +} diff --git a/plugins/dashboard/payload_handler.go b/plugins/dashboard/payload_handler.go new file mode 100644 index 0000000000000000000000000000000000000000..d3a3db10cf031d8131b6b5a49b72fac662f3b666 --- /dev/null +++ b/plugins/dashboard/payload_handler.go @@ -0,0 +1,173 @@ +package dashboard + +import ( + faucetpayload "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + drngpayload "github.com/iotaledger/goshimmer/packages/binary/drng/payload" + drngheader "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + cb "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/hive.go/marshalutil" +) + +// BasicPayload contains content title and bytes +// It can be reused with different payload that only contains one field. +type BasicPayload struct { + ContentTitle string `json:"content_title"` + Content []byte `json:"content"` +} + +// BasicStringPayload contains content title and string content +type BasicStringPayload struct { + ContentTitle string `json:"content_title"` + Content string `json:"content"` +} + +// DrngPayload contains the subtype of drng payload, instance Id +// and the subpayload +type DrngPayload struct { + SubPayloadType byte `json:"subpayload_type"` + InstanceID uint32 `json:"instance_id"` + SubPayload interface{} `json:"drngpayload"` +} + +// DrngCollectiveBeaconPayload is the subpayload of DrngPayload. +type DrngCollectiveBeaconPayload struct { + Round uint64 `json:"round"` + PrevSig []byte `json:"prev_sig"` + Sig []byte `json:"sig"` + Dpk []byte `json:"dpk"` +} + +// ValuePayload contains the transaction information +type ValuePayload struct { + ID string `json:"payload_id"` + ParentID0 string `json:"parent_id_0"` + ParentID1 string `json:"parent_id_1"` + TxID string `json:"tx_id"` + Input []InputContent `json:"inputs"` + Output []OutputContent `json:"outputs"` + Data []byte `json:"data"` +} + +// InputContent contains the inputs of a transaction +type InputContent struct { + Address string `json:"address"` +} + +// OutputContent contains the outputs of a transaction +type OutputContent struct { + Address string `json:"address"` + Balances []Balance `json:"balance"` +} + +// Balance contains the amount of specific color token +type Balance struct { + Value int64 `json:"value"` + Color string `json:"color"` +} + +// ProcessPayload returns different structs regarding to the +// payload type. +func ProcessPayload(p payload.Payload) interface{} { + switch p.Type() { + case payload.DataType: + // data payload + return BasicPayload{ + ContentTitle: "Data", + Content: p.(*payload.Data).Data(), + } + case faucetpayload.Type: + // faucet payload + return BasicStringPayload{ + ContentTitle: "address", + Content: p.(*faucetpayload.Payload).Address().String(), + } + case drngpayload.Type: + // drng payload + return processDrngPayload(p) + case valuepayload.Type: + return processValuePayload(p) + default: + // unknown payload + return BasicPayload{ + ContentTitle: "Bytes", + Content: p.Bytes(), + } + } +} + +// processDrngPayload handles the subtypes of Drng payload +func processDrngPayload(p payload.Payload) (dp DrngPayload) { + var subpayload interface{} + marshalUtil := marshalutil.New(p.Bytes()) + drngPayload, _ := drngpayload.Parse(marshalUtil) + + switch drngPayload.Header.PayloadType { + case drngheader.TypeCollectiveBeacon: + // collective beacon + marshalUtil := marshalutil.New(p.Bytes()) + cbp, _ := cb.Parse(marshalUtil) + subpayload = DrngCollectiveBeaconPayload{ + Round: cbp.Round, + PrevSig: cbp.PrevSignature, + Sig: cbp.Signature, + Dpk: cbp.Dpk, + } + default: + subpayload = BasicPayload{ + ContentTitle: "bytes", + Content: drngPayload.Bytes(), + } + } + return DrngPayload{ + SubPayloadType: drngPayload.Header.PayloadType, + InstanceID: drngPayload.Header.InstanceID, + SubPayload: subpayload, + } +} + +// processValuePayload handles Value payload +func processValuePayload(p payload.Payload) (vp ValuePayload) { + marshalUtil := marshalutil.New(p.Bytes()) + v, _ := valuepayload.Parse(marshalUtil) + + var inputs []InputContent + var outputs []OutputContent + + // TODO: retrieve balance + v.Transaction().Inputs().ForEachAddress(func(currentAddress address.Address) bool { + inputs = append(inputs, InputContent{Address: currentAddress.String()}) + return true + }) + + // Get outputs address and balance + v.Transaction().Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + var b []Balance + for _, balance := range balances { + b = append(b, Balance{ + Value: balance.Value, + Color: balance.Color.String(), + }) + } + t := OutputContent{ + Address: address.String(), + Balances: b, + } + outputs = append(outputs, t) + + return true + }) + + return ValuePayload{ + ID: v.ID().String(), + ParentID0: v.TrunkID().String(), + ParentID1: v.BranchID().String(), + TxID: v.Transaction().ID().String(), + Input: inputs, + Output: outputs, + Data: v.Transaction().GetDataPayload(), + } +} diff --git a/plugins/dashboard/plugin.go b/plugins/dashboard/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..64553804bef0ff5b7e403b2363f03e32224a7d31 --- /dev/null +++ b/plugins/dashboard/plugin.go @@ -0,0 +1,251 @@ +package dashboard + +import ( + "context" + "errors" + "net" + "net/http" + "runtime" + "strconv" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/banner" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/drng" + "github.com/iotaledger/goshimmer/plugins/gossip" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/iotaledger/hive.go/autopeering/peer/service" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/labstack/echo" + "github.com/labstack/echo/middleware" +) + +// PluginName is the name of the dashboard plugin. +const PluginName = "Dashboard" + +var ( + // plugin is the plugin instance of the dashboard plugin. + plugin *node.Plugin + once sync.Once + + log *logger.Logger + server *echo.Echo + + nodeStartAt = time.Now() +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} + +func configure(plugin *node.Plugin) { + log = logger.NewLogger(plugin.Name) + configureWebSocketWorkerPool() + configureLiveFeed() + configureDrngLiveFeed() + configureVisualizer() + configureServer() +} + +func configureServer() { + server = echo.New() + server.HideBanner = true + server.HidePort = true + server.Use(middleware.Recover()) + + if config.Node().GetBool(CfgBasicAuthEnabled) { + server.Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) { + if username == config.Node().GetString(CfgBasicAuthUsername) && + password == config.Node().GetString(CfgBasicAuthPassword) { + return true, nil + } + return false, nil + })) + } + + setupRoutes(server) +} + +func run(*node.Plugin) { + // run message broker + runWebSocketStreams() + // run the message live feed + runLiveFeed() + // run the visualizer vertex feed + runVisualizer() + // run dRNG live feed if dRNG plugin is enabled + if !node.IsSkipped(drng.Plugin()) { + runDrngLiveFeed() + } + + log.Infof("Starting %s ...", PluginName) + if err := daemon.BackgroundWorker(PluginName, worker, shutdown.PriorityAnalysis); err != nil { + log.Panicf("Error starting as daemon: %s", err) + } +} + +func worker(shutdownSignal <-chan struct{}) { + defer log.Infof("Stopping %s ... done", PluginName) + + // start the web socket worker pool + wsSendWorkerPool.Start() + defer wsSendWorkerPool.Stop() + + // submit the mps to the worker pool when triggered + notifyStatus := events.NewClosure(func(mps uint64) { wsSendWorkerPool.TrySubmit(mps) }) + metrics.Events.ReceivedMPSUpdated.Attach(notifyStatus) + defer metrics.Events.ReceivedMPSUpdated.Detach(notifyStatus) + + stopped := make(chan struct{}) + bindAddr := config.Node().GetString(CfgBindAddress) + go func() { + log.Infof("%s started, bind-address=%s", PluginName, bindAddr) + if err := server.Start(bindAddr); err != nil { + if !errors.Is(err, http.ErrServerClosed) { + log.Errorf("Error serving: %s", err) + } + close(stopped) + } + }() + + // stop if we are shutting down or the server could not be started + select { + case <-shutdownSignal: + case <-stopped: + } + + log.Infof("Stopping %s ...", PluginName) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := server.Shutdown(ctx); err != nil { + log.Errorf("Error stopping: %s", err) + } +} + +const ( + // MsgTypeNodeStatus is the type of the NodeStatus message. + MsgTypeNodeStatus byte = iota + // MsgTypeMPSMetric is the type of the message per second (MPS) metric message. + MsgTypeMPSMetric + // MsgTypeMessage is the type of the message. + MsgTypeMessage + // MsgTypeNeighborMetric is the type of the NeighborMetric message. + MsgTypeNeighborMetric + // MsgTypeDrng is the type of the dRNG message. + MsgTypeDrng + // MsgTypeTipsMetric is the type of the TipsMetric message. + MsgTypeTipsMetric + // MsgTypeVertex defines a vertex message. + MsgTypeVertex + // MsgTypeTipInfo defines a tip info message. + MsgTypeTipInfo +) + +type wsmsg struct { + Type byte `json:"type"` + Data interface{} `json:"data"` +} + +type msg struct { + ID string `json:"id"` + Value int64 `json:"value"` +} + +type nodestatus struct { + ID string `json:"id"` + Version string `json:"version"` + Uptime int64 `json:"uptime"` + Mem *memmetrics `json:"mem"` +} + +type memmetrics struct { + Sys uint64 `json:"sys"` + HeapSys uint64 `json:"heap_sys"` + HeapInuse uint64 `json:"heap_inuse"` + HeapIdle uint64 `json:"heap_idle"` + HeapReleased uint64 `json:"heap_released"` + HeapObjects uint64 `json:"heap_objects"` + MSpanInuse uint64 `json:"m_span_inuse"` + MCacheInuse uint64 `json:"m_cache_inuse"` + StackSys uint64 `json:"stack_sys"` + NumGC uint32 `json:"num_gc"` + LastPauseGC uint64 `json:"last_pause_gc"` +} + +type neighbormetric struct { + ID string `json:"id"` + Address string `json:"address"` + ConnectionOrigin string `json:"connection_origin"` + BytesRead uint32 `json:"bytes_read"` + BytesWritten uint32 `json:"bytes_written"` +} + +func neighborMetrics() []neighbormetric { + var stats []neighbormetric + + // gossip plugin might be disabled + neighbors := gossip.Manager().AllNeighbors() + if neighbors == nil { + return stats + } + + for _, neighbor := range neighbors { + // unfortunately the neighbor manager doesn't keep track of the origin of the connection + origin := "Inbound" + for _, peer := range autopeering.Selection().GetOutgoingNeighbors() { + if neighbor.Peer == peer { + origin = "Outbound" + break + } + } + + host := neighbor.Peer.IP().String() + port := neighbor.Peer.Services().Get(service.GossipKey).Port() + stats = append(stats, neighbormetric{ + ID: neighbor.Peer.ID().String(), + Address: net.JoinHostPort(host, strconv.Itoa(port)), + BytesRead: neighbor.BytesRead(), + BytesWritten: neighbor.BytesWritten(), + ConnectionOrigin: origin, + }) + } + return stats +} + +func currentNodeStatus() *nodestatus { + var m runtime.MemStats + runtime.ReadMemStats(&m) + status := &nodestatus{} + status.ID = local.GetInstance().ID().String() + + // node status + status.Version = banner.AppVersion + status.Uptime = time.Since(nodeStartAt).Milliseconds() + + // memory metrics + status.Mem = &memmetrics{ + Sys: m.Sys, + HeapSys: m.HeapSys, + HeapInuse: m.HeapInuse, + HeapIdle: m.HeapIdle, + HeapReleased: m.HeapReleased, + HeapObjects: m.HeapObjects, + MSpanInuse: m.MSpanInuse, + MCacheInuse: m.MCacheInuse, + StackSys: m.StackSys, + NumGC: m.NumGC, + LastPauseGC: m.PauseNs[(m.NumGC+255)%256], + } + return status +} diff --git a/plugins/spa/routes.go b/plugins/dashboard/routes.go similarity index 55% rename from plugins/spa/routes.go rename to plugins/dashboard/routes.go index bb7d152100a782b27dfbcff5d087ad18faabe0a6..31882e5bbd52faa65ba2c9145e4b8b310aee55c0 100644 --- a/plugins/spa/routes.go +++ b/plugins/dashboard/routes.go @@ -1,28 +1,34 @@ -package spa +package dashboard import ( + "errors" "fmt" "io/ioutil" "net/http" - "time" "github.com/gobuffalo/packr/v2" - "github.com/iotaledger/goshimmer/packages/parameter" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/labstack/echo" - "github.com/pkg/errors" ) +// ErrInvalidParameter defines the invalid parameter error. var ErrInvalidParameter = errors.New("invalid parameter") + +// ErrInternalError defines the internal error. var ErrInternalError = errors.New("internal error") + +// ErrNotFound defines the not found error. var ErrNotFound = errors.New("not found") + +// ErrForbidden defines the forbidden error. var ErrForbidden = errors.New("forbidden") -// holds SPA assets -var appBox = packr.New("SPA_App", "./frontend/build") -var assetsBox = packr.New("SPA_Assets", "./frontend/src/assets") +// holds dashboard assets +var appBox = packr.New("Dashboard_App", "./frontend/build") +var assetsBox = packr.New("Dashboard_Assets", "./frontend/src/assets") func indexRoute(e echo.Context) error { - if parameter.NodeConfig.GetBool(CFG_DEV) { + if config.Node().GetBool(CfgDev) { res, err := http.Get("http://127.0.0.1:9090/") if err != nil { return err @@ -42,8 +48,8 @@ func indexRoute(e echo.Context) error { func setupRoutes(e *echo.Echo) { - if parameter.NodeConfig.GetBool("dashboard.dev") { - e.Static("/assets", "./plugins/spa/frontend/src/assets") + if config.Node().GetBool("dashboard.dev") { + e.Static("/assets", "./plugins/dashboard/frontend/src/assets") } else { // load assets from packr: either from within the binary or actual disk @@ -59,12 +65,13 @@ func setupRoutes(e *echo.Echo) { e.GET("/ws", websocketRoute) e.GET("/", indexRoute) - // used to route into the SPA index + // used to route into the dashboard index e.GET("*", indexRoute) apiRoutes := e.Group("/api") setupExplorerRoutes(apiRoutes) + setupFaucetRoutes(apiRoutes) e.HTTPErrorHandler = func(err error, c echo.Context) { c.Logger().Error(err) @@ -72,7 +79,7 @@ func setupRoutes(e *echo.Echo) { var statusCode int var message string - switch errors.Cause(err) { + switch errors.Unwrap(err) { case echo.ErrNotFound: c.Redirect(http.StatusSeeOther, "/") @@ -107,54 +114,3 @@ func setupRoutes(e *echo.Echo) { c.String(statusCode, message) } } - -func registerWSClient() (uint64, chan interface{}) { - // allocate new client id - clientsMu.Lock() - defer clientsMu.Unlock() - clientID := nextClientID - channel := make(chan interface{}, 100) - clients[clientID] = channel - nextClientID++ - return clientID, channel -} - -func websocketRoute(c echo.Context) error { - defer func() { - if r := recover(); r != nil { - log.Errorf("recovered from panic within WS handle func: %s", r) - } - }() - ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil) - if err != nil { - return err - } - defer ws.Close() - ws.EnableWriteCompression(true) - - // cleanup client websocket - clientID, channel := registerWSClient() - defer func() { - clientsMu.Lock() - delete(clients, clientID) - close(channel) - clientsMu.Unlock() - }() - - msgRateLimiter := time.NewTicker(time.Second / 20) - defer msgRateLimiter.Stop() - - for { - <-msgRateLimiter.C - msg := <-channel - if err := ws.WriteJSON(msg); err != nil { - log.Warnf("error while writing to web socket client %s: %s", c.RealIP(), err.Error()) - break - } - if err := ws.SetWriteDeadline(time.Now().Add(webSocketWriteTimeout)); err != nil { - log.Warnf("error while setting write deadline on web socket client %s: %s", c.RealIP(), err.Error()) - break - } - } - return nil -} diff --git a/plugins/dashboard/visualizer.go b/plugins/dashboard/visualizer.go new file mode 100644 index 0000000000000000000000000000000000000000..fab0c7c5955ff1a1ebed3742536299a991695a1e --- /dev/null +++ b/plugins/dashboard/visualizer.go @@ -0,0 +1,99 @@ +package dashboard + +import ( + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/workerpool" +) + +var ( + visualizerWorkerCount = 1 + visualizerWorkerQueueSize = 500 + visualizerWorkerPool *workerpool.WorkerPool +) + +// vertex defines a vertex in a DAG. +type vertex struct { + ID string `json:"id"` + TrunkID string `json:"trunk_id"` + BranchID string `json:"branch_id"` + IsSolid bool `json:"is_solid"` +} + +// tipinfo holds information about whether a given message is a tip or not. +type tipinfo struct { + ID string `json:"id"` + IsTip bool `json:"is_tip"` +} + +func configureVisualizer() { + visualizerWorkerPool = workerpool.New(func(task workerpool.Task) { + + switch x := task.Param(0).(type) { + case *message.CachedMessage: + sendVertex(x, task.Param(1).(*tangle.CachedMessageMetadata)) + case message.Id: + sendTipInfo(x, task.Param(1).(bool)) + } + + task.Return(nil) + }, workerpool.WorkerCount(visualizerWorkerCount), workerpool.QueueSize(visualizerWorkerQueueSize)) +} + +func sendVertex(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + defer cachedMessage.Release() + defer cachedMessageMetadata.Release() + + msg := cachedMessage.Unwrap() + broadcastWsMessage(&wsmsg{MsgTypeVertex, &vertex{ + ID: msg.Id().String(), + TrunkID: msg.TrunkId().String(), + BranchID: msg.BranchId().String(), + IsSolid: cachedMessageMetadata.Unwrap().IsSolid(), + }}, true) +} + +func sendTipInfo(messageID message.Id, isTip bool) { + broadcastWsMessage(&wsmsg{MsgTypeTipInfo, &tipinfo{ + ID: messageID.String(), + IsTip: isTip, + }}, true) +} + +func runVisualizer() { + notifyNewMsg := events.NewClosure(func(message *message.CachedMessage, metadata *tangle.CachedMessageMetadata) { + defer message.Release() + defer metadata.Release() + visualizerWorkerPool.TrySubmit(message.Retain(), metadata.Retain()) + }) + + notifyNewTip := events.NewClosure(func(messageId message.Id) { + visualizerWorkerPool.TrySubmit(messageId, true) + }) + + notifyDeletedTip := events.NewClosure(func(messageId message.Id) { + visualizerWorkerPool.TrySubmit(messageId, false) + }) + + if err := daemon.BackgroundWorker("Dashboard[Visualizer]", func(shutdownSignal <-chan struct{}) { + messagelayer.Tangle().Events.MessageAttached.Attach(notifyNewMsg) + defer messagelayer.Tangle().Events.MessageAttached.Detach(notifyNewMsg) + messagelayer.Tangle().Events.MessageSolid.Attach(notifyNewMsg) + defer messagelayer.Tangle().Events.MessageSolid.Detach(notifyNewMsg) + messagelayer.TipSelector().Events.TipAdded.Attach(notifyNewTip) + defer messagelayer.TipSelector().Events.TipAdded.Detach(notifyNewTip) + messagelayer.TipSelector().Events.TipRemoved.Attach(notifyDeletedTip) + defer messagelayer.TipSelector().Events.TipRemoved.Detach(notifyDeletedTip) + visualizerWorkerPool.Start() + <-shutdownSignal + log.Info("Stopping Dashboard[Visualizer] ...") + visualizerWorkerPool.Stop() + log.Info("Stopping Dashboard[Visualizer] ... done") + }, shutdown.PriorityDashboard); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} diff --git a/plugins/dashboard/ws.go b/plugins/dashboard/ws.go new file mode 100644 index 0000000000000000000000000000000000000000..3288d77d6429b7429f19ea88efac0fdb25b77512 --- /dev/null +++ b/plugins/dashboard/ws.go @@ -0,0 +1,148 @@ +package dashboard + +import ( + "net/http" + "sync" + "time" + + "github.com/gorilla/websocket" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/workerpool" + "github.com/labstack/echo" +) + +var ( + // settings + wsSendWorkerCount = 1 + wsSendWorkerQueueSize = 250 + wsSendWorkerPool *workerpool.WorkerPool + webSocketWriteTimeout = time.Duration(3) * time.Second + + // clients + wsClientsMu sync.Mutex + wsClients = make(map[uint64]*wsclient) + nextWsClientID uint64 + + // gorilla websocket layer + upgrader = websocket.Upgrader{ + HandshakeTimeout: webSocketWriteTimeout, + CheckOrigin: func(r *http.Request) bool { return true }, + EnableCompression: true, + } +) + +// a websocket client with a channel for downstream messages. +type wsclient struct { + // downstream message channel. + channel chan interface{} + // a channel which is closed when the websocket client is disconnected. + exit chan struct{} +} + +func configureWebSocketWorkerPool() { + wsSendWorkerPool = workerpool.New(func(task workerpool.Task) { + broadcastWsMessage(&wsmsg{MsgTypeMPSMetric, task.Param(0).(uint64)}) + broadcastWsMessage(&wsmsg{MsgTypeNodeStatus, currentNodeStatus()}) + broadcastWsMessage(&wsmsg{MsgTypeNeighborMetric, neighborMetrics()}) + broadcastWsMessage(&wsmsg{MsgTypeTipsMetric, messagelayer.TipSelector().TipCount()}) + task.Return(nil) + }, workerpool.WorkerCount(wsSendWorkerCount), workerpool.QueueSize(wsSendWorkerQueueSize)) +} + +func runWebSocketStreams() { + updateStatus := events.NewClosure(func(mps uint64) { + wsSendWorkerPool.TrySubmit(mps) + }) + + if err := daemon.BackgroundWorker("Dashboard[StatusUpdate]", func(shutdownSignal <-chan struct{}) { + metrics.Events.ReceivedMPSUpdated.Attach(updateStatus) + wsSendWorkerPool.Start() + <-shutdownSignal + log.Info("Stopping Dashboard[StatusUpdate] ...") + metrics.Events.ReceivedMPSUpdated.Detach(updateStatus) + wsSendWorkerPool.Stop() + log.Info("Stopping Dashboard[StatusUpdate] ... done") + }, shutdown.PriorityDashboard); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} + +// reigsters and creates a new websocket client. +func registerWSClient() (uint64, *wsclient) { + wsClientsMu.Lock() + defer wsClientsMu.Unlock() + clientID := nextWsClientID + wsClient := &wsclient{ + channel: make(chan interface{}, 500), + exit: make(chan struct{}), + } + wsClients[clientID] = wsClient + nextWsClientID++ + return clientID, wsClient +} + +// removes the websocket client with the given id. +func removeWsClient(clientID uint64) { + wsClientsMu.Lock() + defer wsClientsMu.Unlock() + wsClient := wsClients[clientID] + close(wsClient.exit) + close(wsClient.channel) + delete(wsClients, clientID) +} + +// broadcasts the given message to all connected websocket clients. +func broadcastWsMessage(msg interface{}, dontDrop ...bool) { + wsClientsMu.Lock() + defer wsClientsMu.Unlock() + for _, wsClient := range wsClients { + if len(dontDrop) > 0 { + select { + case wsClient.channel <- msg: + case <-wsClient.exit: + // get unblocked if the websocket connection just got closed + } + continue + } + select { + case wsClient.channel <- msg: + default: + // potentially drop if slow consumer + } + } +} + +func websocketRoute(c echo.Context) error { + defer func() { + if r := recover(); r != nil { + log.Errorf("recovered from websocket handle func: %s", r) + } + }() + + // upgrade to websocket connection + ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil) + if err != nil { + return err + } + defer ws.Close() + ws.EnableWriteCompression(true) + + // cleanup client websocket + clientID, wsClient := registerWSClient() + defer removeWsClient(clientID) + + for { + msg := <-wsClient.channel + if err := ws.WriteJSON(msg); err != nil { + break + } + if err := ws.SetWriteDeadline(time.Now().Add(webSocketWriteTimeout)); err != nil { + break + } + } + return nil +} diff --git a/plugins/database/health.go b/plugins/database/health.go new file mode 100644 index 0000000000000000000000000000000000000000..af6a4770c9261245a2535a7f9f25798be046f2df --- /dev/null +++ b/plugins/database/health.go @@ -0,0 +1,42 @@ +package database + +import ( + "errors" + "fmt" + + "github.com/iotaledger/goshimmer/packages/database/prefix" + "github.com/iotaledger/hive.go/kvstore" +) + +var ( + healthStore kvstore.KVStore + healthKey = []byte("db_health") +) + +func configureHealthStore(store kvstore.KVStore) { + healthStore = store.WithRealm([]byte{prefix.DBPrefixHealth}) +} + +// MarkDatabaseUnhealthy marks the database as not healthy, meaning +// that it wasn't shutdown properly. +func MarkDatabaseUnhealthy() { + if err := healthStore.Set(healthKey, []byte{}); err != nil { + panic(fmt.Errorf("failed to set database health state: %w", err)) + } +} + +// MarkDatabaseHealthy marks the database as healthy, respectively correctly closed. +func MarkDatabaseHealthy() { + if err := healthStore.Delete(healthKey); err != nil && !errors.Is(err, kvstore.ErrKeyNotFound) { + panic(fmt.Errorf("failed to set database health state: %w", err)) + } +} + +// IsDatabaseUnhealthy tells whether the database is unhealthy, meaning not shutdown properly. +func IsDatabaseUnhealthy() bool { + contains, err := healthStore.Has(healthKey) + if err != nil { + panic(fmt.Errorf("failed to set database health state: %w", err)) + } + return contains +} diff --git a/plugins/database/parameters.go b/plugins/database/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..c860dd8b3a2cda995b9682ce4f1143c6d84d21d6 --- /dev/null +++ b/plugins/database/parameters.go @@ -0,0 +1,17 @@ +package database + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgDatabaseDir defines the directory of the database. + CfgDatabaseDir = "database.directory" + // CfgDatabaseInMemory defines whether to use an in-memory database. + CfgDatabaseInMemory = "database.inMemory" +) + +func init() { + flag.String(CfgDatabaseDir, "mainnetdb", "path to the database folder") + flag.Bool(CfgDatabaseInMemory, false, "whether the database is only kept in memory and not persisted") +} diff --git a/plugins/database/plugin.go b/plugins/database/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..a3f4d25cd7c4e97c4869f076b5c8861cc3aa5961 --- /dev/null +++ b/plugins/database/plugin.go @@ -0,0 +1,121 @@ +// Package database is a plugin that manages the badger database (e.g. garbage collection). +package database + +import ( + "errors" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/database" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/kvstore" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the database plugin. +const PluginName = "Database" + +var ( + // plugin is the plugin instance of the database plugin. + plugin *node.Plugin + pluginOnce sync.Once + log *logger.Logger + + db database.DB + store kvstore.KVStore + storeOnce sync.Once +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + pluginOnce.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +// Store returns the KVStore instance. +func Store() kvstore.KVStore { + storeOnce.Do(createStore) + return store +} + +// StoreRealm is a factory method for a different realm backed by the KVStore instance. +func StoreRealm(realm kvstore.Realm) kvstore.KVStore { + return Store().WithRealm(realm) +} + +func createStore() { + log = logger.NewLogger(PluginName) + + var err error + if config.Node().GetBool(CfgDatabaseInMemory) { + db, err = database.NewMemDB() + } else { + dbDir := config.Node().GetString(CfgDatabaseDir) + db, err = database.NewDB(dbDir) + } + if err != nil { + log.Fatal("Unable to open the database, please delete the database folder. Error: %s", err) + } + + store = db.NewStore() +} + +func configure(_ *node.Plugin) { + // assure that the store is initialized + store := Store() + configureHealthStore(store) + + if err := checkDatabaseVersion(healthStore); err != nil { + if errors.Is(err, ErrDBVersionIncompatible) { + log.Fatalf("The database scheme was updated. Please delete the database folder. %s", err) + } + log.Fatalf("Failed to check database version: %s", err) + } + + if IsDatabaseUnhealthy() { + log.Fatal("The database is marked as not properly shutdown/corrupted, please delete the database folder and restart.") + } + + // we open the database in the configure, so we must also make sure it's closed here + if err := daemon.BackgroundWorker(PluginName, manageDBLifetime, shutdown.PriorityDatabase); err != nil { + log.Fatalf("Failed to start as daemon: %s", err) + } + + // run GC up on startup + runDatabaseGC() +} + +// manageDBLifetime takes care of managing the lifetime of the database. It marks the database as dirty up on +// startup and unmarks it up on shutdown. Up on shutdown it will run the db GC and then close the database. +func manageDBLifetime(shutdownSignal <-chan struct{}) { + // we mark the database only as corrupted from within a background worker, which means + // that we only mark it as dirty, if the node actually started up properly (meaning no termination + // signal was received before all plugins loaded). + MarkDatabaseUnhealthy() + <-shutdownSignal + runDatabaseGC() + MarkDatabaseHealthy() + log.Infof("Syncing database to disk...") + if err := db.Close(); err != nil { + log.Errorf("Failed to flush the database: %s", err) + } + log.Infof("Syncing database to disk... done") +} + +func runDatabaseGC() { + if !db.RequiresGC() { + return + } + log.Info("Running database garbage collection...") + s := time.Now() + if err := db.GC(); err != nil { + log.Warnf("Database garbage collection failed: %s", err) + return + } + log.Infof("Database garbage collection done, took %v...", time.Since(s)) +} diff --git a/plugins/database/versioning.go b/plugins/database/versioning.go new file mode 100644 index 0000000000000000000000000000000000000000..0b62a5bf481e5f8de14b2b54b6209a63f9e896ae --- /dev/null +++ b/plugins/database/versioning.go @@ -0,0 +1,41 @@ +package database + +import ( + "errors" + "fmt" + + "github.com/iotaledger/hive.go/kvstore" +) + +const ( + // DBVersion defines the version of the database schema this version of GoShimmer supports. + // Every time there's a breaking change regarding the stored data, this version flag should be adjusted. + DBVersion = 3 +) + +var ( + // ErrDBVersionIncompatible is returned when the database has an unexpected version. + ErrDBVersionIncompatible = errors.New("database version is not compatible. please delete your database folder and restart") + // the key under which the database is stored + dbVersionKey = []byte{0} +) + +// checks whether the database is compatible with the current schema version. +// also automatically sets the version if the database is new. +func checkDatabaseVersion(store kvstore.KVStore) error { + entry, err := store.Get(dbVersionKey) + if err == kvstore.ErrKeyNotFound { + // set the version in an empty DB + return store.Set(dbVersionKey, []byte{DBVersion}) + } + if err != nil { + return err + } + if len(entry) == 0 { + return fmt.Errorf("%w: no database version was persisted", ErrDBVersionIncompatible) + } + if entry[0] != DBVersion { + return fmt.Errorf("%w: supported version: %d, version of database: %d", ErrDBVersionIncompatible, DBVersion, entry[0]) + } + return nil +} diff --git a/plugins/drng/drng.go b/plugins/drng/drng.go new file mode 100644 index 0000000000000000000000000000000000000000..6bfebe7c3486544bf9eeef52a1759046d7a71898 --- /dev/null +++ b/plugins/drng/drng.go @@ -0,0 +1,79 @@ +package drng + +import ( + "encoding/hex" + "errors" + "fmt" + + "github.com/iotaledger/goshimmer/packages/binary/drng" + "github.com/iotaledger/goshimmer/packages/binary/drng/state" + cbPayload "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/logger" + "github.com/mr-tron/base58/base58" +) + +var ( + // ErrParsingCommitteeMember is returned for an invalid committee member + ErrParsingCommitteeMember = errors.New("cannot parse committee member") +) + +func configureDRNG() *drng.DRNG { + log = logger.NewLogger(PluginName) + // parse identities of the committee members + committeeMembers, err := parseCommitteeMembers() + if err != nil { + log.Warnf("Invalid %s: %s", CfgDRNGCommitteeMembers, err) + } + + // parse distributed public key of the committee + var dpk []byte + if str := config.Node().GetString(CfgDRNGDistributedPubKey); str != "" { + bytes, err := hex.DecodeString(str) + if err != nil { + log.Warnf("Invalid %s: %s", CfgDRNGDistributedPubKey, err) + } + if l := len(bytes); l != cbPayload.PublicKeySize { + log.Warnf("Invalid %s length: %d, need %d", CfgDRNGDistributedPubKey, l, cbPayload.PublicKeySize) + } + dpk = append(dpk, bytes...) + } + + // configure committee + committeeConf := &state.Committee{ + InstanceID: config.Node().GetUint32(CfgDRNGInstanceID), + Threshold: uint8(config.Node().GetUint32(CfgDRNGThreshold)), + DistributedPK: dpk, + Identities: committeeMembers, + } + + return drng.New(state.SetCommittee(committeeConf)) +} + +// Instance returns the DRNG instance. +func Instance() *drng.DRNG { + once.Do(func() { instance = configureDRNG() }) + return instance +} + +func parseCommitteeMembers() (result []ed25519.PublicKey, err error) { + for _, committeeMember := range config.Node().GetStringSlice(CfgDRNGCommitteeMembers) { + if committeeMember == "" { + continue + } + + pubKey, err := base58.Decode(committeeMember) + if err != nil { + return nil, fmt.Errorf("%w: invalid public key: %s", ErrParsingCommitteeMember, err) + } + publicKey, _, err := ed25519.PublicKeyFromBytes(pubKey) + if err != nil { + return nil, err + } + + result = append(result, publicKey) + } + + return result, nil +} diff --git a/plugins/drng/parameters.go b/plugins/drng/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..07a4e8ac4f630563c556c7d654153a8a453b93fb --- /dev/null +++ b/plugins/drng/parameters.go @@ -0,0 +1,23 @@ +package drng + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgDRNGInstanceID defines the config flag of the DRNG instanceID. + CfgDRNGInstanceID = "drng.instanceId" + // CfgDRNGThreshold defines the config flag of the DRNG threshold. + CfgDRNGThreshold = "drng.threshold" + // CfgDRNGDistributedPubKey defines the config flag of the DRNG distributed Public Key. + CfgDRNGDistributedPubKey = "drng.distributedPubKey" + // CfgDRNGCommitteeMembers defines the config flag of the DRNG committee members identities. + CfgDRNGCommitteeMembers = "drng.committeeMembers" +) + +func init() { + flag.Uint32(CfgDRNGInstanceID, 1, "instance ID of the drng instance") + flag.Uint32(CfgDRNGThreshold, 3, "BLS threshold of the drng") + flag.String(CfgDRNGDistributedPubKey, "", "distributed public key of the committee (hex encoded)") + flag.StringSlice(CfgDRNGCommitteeMembers, []string{}, "list of committee members of the drng") +} diff --git a/plugins/drng/plugin.go b/plugins/drng/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..55deeafbf8c9f7063673bb3421ab00ec53509db5 --- /dev/null +++ b/plugins/drng/plugin.go @@ -0,0 +1,71 @@ +package drng + +import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/drng" + "github.com/iotaledger/goshimmer/packages/binary/drng/payload" + "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the DRNG plugin. +const PluginName = "DRNG" + +var ( + // plugin is the plugin instance of the DRNG plugin. + plugin *node.Plugin + pluginOnce sync.Once + instance *drng.DRNG + once sync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + pluginOnce.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} + +func configure(_ *node.Plugin) { + configureEvents() +} + +func run(*node.Plugin) {} + +func configureEvents() { + instance := Instance() + messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + cachedMessageMetadata.Release() + + cachedMessage.Consume(func(msg *message.Message) { + if msg.Payload().Type() != payload.Type { + return + } + if len(msg.Payload().Bytes()) < header.Length { + return + } + marshalUtil := marshalutil.New(msg.Payload().Bytes()) + parsedPayload, err := payload.Parse(marshalUtil) + if err != nil { + //TODO: handle error + log.Info(err) + return + } + if err := instance.Dispatch(msg.IssuerPublicKey(), msg.IssuingTime(), parsedPayload); err != nil { + //TODO: handle error + log.Info(err) + return + } + log.Info(instance.State.Randomness()) + }) + })) +} diff --git a/plugins/gossip/gossip.go b/plugins/gossip/gossip.go index 0293370e71bd87a77386fa39ef0f005013b846c5..d08d8e61df133348a9e6113752f3475ac021f331 100644 --- a/plugins/gossip/gossip.go +++ b/plugins/gossip/gossip.go @@ -1,66 +1,72 @@ package gossip import ( - "fmt" + "errors" "net" "strconv" "sync" - gp "github.com/iotaledger/goshimmer/packages/gossip" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/gossip" "github.com/iotaledger/goshimmer/packages/gossip/server" - "github.com/iotaledger/goshimmer/packages/parameter" + "github.com/iotaledger/goshimmer/plugins/autopeering" "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/goshimmer/plugins/cli" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/hive.go/autopeering/peer" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/messagelayer" "github.com/iotaledger/hive.go/autopeering/peer/service" "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" + "github.com/iotaledger/hive.go/netutil" ) var ( - log *logger.Logger - mgr *gp.Manager + // ErrMessageNotFound is returned when a message could not be found in the Tangle. + ErrMessageNotFound = errors.New("message not found") ) -func configureGossip() { - lPeer := local.GetInstance() +var ( + mgr *gossip.Manager + mgrOnce sync.Once +) - peeringAddr := lPeer.Services().Get(service.PeeringKey) - external, _, err := net.SplitHostPort(peeringAddr.String()) - if err != nil { - panic(err) - } +// Manager returns the manager instance of the gossip plugin. +func Manager() *gossip.Manager { + mgrOnce.Do(createManager) + return mgr +} + +func createManager() { + // assure that the logger is available + log := logger.NewLogger(PluginName) // announce the gossip service - gossipPort := strconv.Itoa(parameter.NodeConfig.GetInt(GOSSIP_PORT)) - err = lPeer.UpdateService(service.GossipKey, "tcp", net.JoinHostPort(external, gossipPort)) - if err != nil { - log.Fatalf("could not update services: %s", err) + gossipPort := config.Node().GetInt(CfgGossipPort) + if !netutil.IsValidPort(gossipPort) { + log.Fatalf("Invalid port number (%s): %d", CfgGossipPort, gossipPort) } - mgr = gp.NewManager(lPeer, getTransaction, log) + lPeer := local.GetInstance() + if err := lPeer.UpdateService(service.GossipKey, "tcp", gossipPort); err != nil { + log.Fatalf("could not update services: %s", err) + } + mgr = gossip.NewManager(lPeer, loadMessage, log) } func start(shutdownSignal <-chan struct{}) { - defer log.Info("Stopping " + name + " ... done") + defer log.Info("Stopping " + PluginName + " ... done") lPeer := local.GetInstance() + // use the port of the gossip service - gossipAddr := lPeer.Services().Get(service.GossipKey) - _, gossipPort, err := net.SplitHostPort(gossipAddr.String()) - if err != nil { - panic(err) - } + gossipEndpoint := lPeer.Services().Get(service.GossipKey) + // resolve the bind address - address := net.JoinHostPort(parameter.NodeConfig.GetString(local.CFG_BIND), gossipPort) - localAddr, err := net.ResolveTCPAddr(gossipAddr.Network(), address) + address := net.JoinHostPort(config.Node().GetString(local.CfgBind), strconv.Itoa(gossipEndpoint.Port())) + localAddr, err := net.ResolveTCPAddr(gossipEndpoint.Network(), address) if err != nil { - log.Fatalf("Error resolving %s: %v", local.CFG_BIND, err) + log.Fatalf("Error resolving %s: %v", local.CfgBind, err) } - listener, err := net.ListenTCP(gossipAddr.Network(), localAddr) + listener, err := net.ListenTCP(gossipEndpoint.Network(), localAddr) if err != nil { log.Fatalf("Error listening: %v", err) } @@ -69,65 +75,27 @@ func start(shutdownSignal <-chan struct{}) { srv := server.ServeTCP(lPeer, listener, log) defer srv.Close() - //check that the server is working and the port is open - log.Info("Testing service ...") - checkConnection(srv, &lPeer.Peer) - log.Info("Testing service ... done") - mgr.Start(srv) defer mgr.Close() - log.Infof("%s started: Address=%s/%s", name, gossipAddr.String(), gossipAddr.Network()) + // trigger start of the autopeering selection + go func() { autopeering.StartSelection() }() - <-shutdownSignal - log.Info("Stopping " + name + " ...") -} - -func checkConnection(srv *server.TCP, self *peer.Peer) { - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - conn, err := srv.AcceptPeer(self) - if err != nil { - return - } - _ = conn.Close() - }() - conn, err := srv.DialPeer(self) - if err != nil { - log.Errorf("Error testing: %s", err) - addr := self.Services().Get(service.GossipKey) - log.Panicf("Please check that %s is publicly reachable at %s/%s", - cli.AppName, addr.String(), addr.Network()) - } - _ = conn.Close() - wg.Wait() -} + log.Infof("%s started, bind-address=%s", PluginName, localAddr.String()) -func getTransaction(hash []byte) ([]byte, error) { - tx, err := tangle.GetTransaction(typeutils.BytesToString(hash)) - log.Debugw("get tx from db", - "hash", hash, - "tx", tx, - "err", err, - ) - if err != nil { - return nil, fmt.Errorf("could not get transaction: %w", err) - } - if tx == nil { - return nil, fmt.Errorf("transaction not found: hash=%s", hash) - } - return tx.GetBytes(), nil -} + <-shutdownSignal + log.Info("Stopping " + PluginName + " ...") -func requestTransaction(hash trinary.Hash) { - mgr.RequestTransaction(typeutils.StringToBytes(hash)) + // assure that the autopeering selection is always stopped before the gossip manager + autopeering.Selection().Close() } -func GetAllNeighbors() []*gp.Neighbor { - if mgr == nil { - return nil +// loads the given message from the message layer or an error if not found. +func loadMessage(messageID message.Id) (bytes []byte, err error) { + if !messagelayer.Tangle().Message(messageID).Consume(func(message *message.Message) { + bytes = message.Bytes() + }) { + err = ErrMessageNotFound } - return mgr.GetAllNeighbors() + return } diff --git a/plugins/gossip/parameters.go b/plugins/gossip/parameters.go index aa96e7cbd674429c80c2af2c923a975651950bdc..ade8e8a22e94808dd3c130be13c20fb509e107e4 100644 --- a/plugins/gossip/parameters.go +++ b/plugins/gossip/parameters.go @@ -5,9 +5,10 @@ import ( ) const ( - GOSSIP_PORT = "gossip.port" + // CfgGossipPort defines the config flag of the gossip port. + CfgGossipPort = "gossip.port" ) func init() { - flag.Int(GOSSIP_PORT, 14666, "tcp port for gossip connection") + flag.Int(CfgGossipPort, 14666, "tcp port for gossip connection") } diff --git a/plugins/gossip/plugin.go b/plugins/gossip/plugin.go index ff4b335fc80c9976533fef1dd6fc751805d435f8..d32ad25341a99bdb1c72d93a9f4046771ece4259 100644 --- a/plugins/gossip/plugin.go +++ b/plugins/gossip/plugin.go @@ -1,10 +1,14 @@ package gossip import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" "github.com/iotaledger/goshimmer/packages/gossip" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/tangle" + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/messagelayer" "github.com/iotaledger/hive.go/autopeering/peer" "github.com/iotaledger/hive.go/autopeering/selection" "github.com/iotaledger/hive.go/daemon" @@ -13,32 +17,53 @@ import ( "github.com/iotaledger/hive.go/node" ) -const name = "Gossip" // name of the plugin +// PluginName is the name of the gossip plugin. +const PluginName = "Gossip" + +var ( + // plugin is the plugin instance of the gossip plugin. + plugin *node.Plugin + once sync.Once -var PLUGIN = node.NewPlugin(name, node.Enabled, configure, run) + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} func configure(*node.Plugin) { - log = logger.NewLogger(name) + log = logger.NewLogger(PluginName) - configureGossip() - configureEvents() + configureLogging() + configureMessageLayer() + configureAutopeering() } func run(*node.Plugin) { - if err := daemon.BackgroundWorker(name, start, shutdown.ShutdownPriorityGossip); err != nil { - log.Errorf("Failed to start as daemon: %s", err) + if err := daemon.BackgroundWorker(PluginName, start, shutdown.PriorityGossip); err != nil { + log.Panicf("Failed to start as daemon: %s", err) } } -func configureEvents() { - selection.Events.Dropped.Attach(events.NewClosure(func(ev *selection.DroppedEvent) { +func configureAutopeering() { + // assure that the Manager is instantiated + mgr := Manager() + + // link to the autopeering events + peerSel := autopeering.Selection() + peerSel.Events().Dropped.Attach(events.NewClosure(func(ev *selection.DroppedEvent) { go func() { if err := mgr.DropNeighbor(ev.DroppedID); err != nil { log.Debugw("error dropping neighbor", "id", ev.DroppedID, "err", err) } }() })) - selection.Events.IncomingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { + peerSel.Events().IncomingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { if !ev.Status { return // ignore rejected peering } @@ -48,7 +73,7 @@ func configureEvents() { } }() })) - selection.Events.OutgoingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { + peerSel.Events().OutgoingPeering.Attach(events.NewClosure(func(ev *selection.PeeringEvent) { if !ev.Status { return // ignore rejected peering } @@ -59,19 +84,50 @@ func configureEvents() { }() })) - gossip.Events.ConnectionFailed.Attach(events.NewClosure(func(p *peer.Peer, err error) { + // notify the autopeering on connection loss + mgr.Events().ConnectionFailed.Attach(events.NewClosure(func(p *peer.Peer, _ error) { + peerSel.RemoveNeighbor(p.ID()) + })) + mgr.Events().NeighborRemoved.Attach(events.NewClosure(func(n *gossip.Neighbor) { + peerSel.RemoveNeighbor(n.ID()) + })) +} + +func configureLogging() { + // assure that the Manager is instantiated + mgr := Manager() + + // log the gossip events + mgr.Events().ConnectionFailed.Attach(events.NewClosure(func(p *peer.Peer, err error) { log.Infof("Connection to neighbor %s / %s failed: %s", gossip.GetAddress(p), p.ID(), err) })) - gossip.Events.NeighborAdded.Attach(events.NewClosure(func(n *gossip.Neighbor) { + mgr.Events().NeighborAdded.Attach(events.NewClosure(func(n *gossip.Neighbor) { log.Infof("Neighbor added: %s / %s", gossip.GetAddress(n.Peer), n.ID()) })) - gossip.Events.NeighborRemoved.Attach(events.NewClosure(func(p *peer.Peer) { - log.Infof("Neighbor removed: %s / %s", gossip.GetAddress(p), p.ID()) + mgr.Events().NeighborRemoved.Attach(events.NewClosure(func(n *gossip.Neighbor) { + log.Infof("Neighbor removed: %s / %s", gossip.GetAddress(n.Peer), n.ID()) + })) +} + +func configureMessageLayer() { + // assure that the Manager is instantiated + mgr := Manager() + + // configure flow of incoming messages + mgr.Events().MessageReceived.Attach(events.NewClosure(func(event *gossip.MessageReceivedEvent) { + messagelayer.MessageParser().Parse(event.Data, event.Peer) + })) + + // configure flow of outgoing messages (gossip on solidification) + messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + cachedMessageMetadata.Release() + cachedMessage.Consume(func(msg *message.Message) { + mgr.SendMessage(msg.Bytes()) + }) })) - // gossip transactions on solidification - tangle.Events.TransactionSolid.Attach(events.NewClosure(func(tx *value_transaction.ValueTransaction) { - mgr.SendTransaction(tx.GetBytes()) + // request missing messages + messagelayer.MessageRequester().Events.SendRequest.Attach(events.NewClosure(func(messageId message.Id) { + mgr.RequestMessage(messageId[:]) })) - tangle.SetRequester(tangle.RequesterFunc(requestTransaction)) } diff --git a/plugins/gracefulshutdown/parameters.go b/plugins/gracefulshutdown/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..fbdca5fe4f05e120fd4370133284404e778bf69c --- /dev/null +++ b/plugins/gracefulshutdown/parameters.go @@ -0,0 +1,14 @@ +package gracefulshutdown + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgWaitToKillTimeInSeconds the maximum amount of time to wait for background processes to terminate. + CfgWaitToKillTimeInSeconds = "gracefulshutdown.waitToKillTime" +) + +func init() { + flag.Int(CfgWaitToKillTimeInSeconds, 60, "the maximum amount of time to wait for background processes to terminate, in seconds") +} diff --git a/plugins/gracefulshutdown/plugin.go b/plugins/gracefulshutdown/plugin.go index 2cc523798146b0c67d1686595e7a51e5484c3a66..b191f7e3f4ff6e0bc32386119a6f1d9ceb4fd5e1 100644 --- a/plugins/gracefulshutdown/plugin.go +++ b/plugins/gracefulshutdown/plugin.go @@ -3,23 +3,35 @@ package gracefulshutdown import ( "os" "os/signal" + "sort" "strings" + "sync" "syscall" "time" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" ) -// maximum amount of time to wait for background processes to terminate. After that the process is killed. -const WAIT_TO_KILL_TIME_IN_SECONDS = 10 +// PluginName is the name of the graceful shutdown plugin. +const PluginName = "Graceful Shutdown" -var log *logger.Logger +var ( + // plugin is the plugin instance of the graceful shutdown plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger + gracefulStop chan os.Signal + waitToKillTimeInSeconds int +) + +func configure(*node.Plugin) { + waitToKillTimeInSeconds = config.Node().GetInt(CfgWaitToKillTimeInSeconds) -var PLUGIN = node.NewPlugin("Graceful Shutdown", node.Enabled, func(plugin *node.Plugin) { - log = logger.NewLogger("Graceful Shutdown") - gracefulStop := make(chan os.Signal) + log = logger.NewLogger(PluginName) + gracefulStop = make(chan os.Signal) signal.Notify(gracefulStop, syscall.SIGTERM) signal.Notify(gracefulStop, syscall.SIGINT) @@ -27,20 +39,24 @@ var PLUGIN = node.NewPlugin("Graceful Shutdown", node.Enabled, func(plugin *node go func() { <-gracefulStop - log.Warnf("Received shutdown request - waiting (max %d) to finish processing ...", WAIT_TO_KILL_TIME_IN_SECONDS) + log.Warnf("Received shutdown request - waiting (max %d) to finish processing ...", waitToKillTimeInSeconds) go func() { + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + start := time.Now() - for x := range time.Tick(1 * time.Second) { + for x := range ticker.C { secondsSinceStart := x.Sub(start).Seconds() - if secondsSinceStart <= WAIT_TO_KILL_TIME_IN_SECONDS { + if secondsSinceStart <= float64(waitToKillTimeInSeconds) { processList := "" runningBackgroundWorkers := daemon.GetRunningBackgroundWorkers() if len(runningBackgroundWorkers) >= 1 { + sort.Strings(runningBackgroundWorkers) processList = "(" + strings.Join(runningBackgroundWorkers, ", ") + ") " } - log.Warnf("Received shutdown request - waiting (max %d seconds) to finish processing %s...", WAIT_TO_KILL_TIME_IN_SECONDS-int(secondsSinceStart), processList) + log.Warnf("Received shutdown request - waiting (max %d seconds) to finish processing %s...", waitToKillTimeInSeconds-int(secondsSinceStart), processList) } else { log.Error("Background processes did not terminate in time! Forcing shutdown ...") os.Exit(1) @@ -50,4 +66,18 @@ var PLUGIN = node.NewPlugin("Graceful Shutdown", node.Enabled, func(plugin *node daemon.Shutdown() }() -}) +} + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +// ShutdownWithError prints out an error message and shuts down the default daemon instance. +func ShutdownWithError(err error) { + log.Error(err) + gracefulStop <- syscall.SIGINT +} diff --git a/plugins/graph/README.md b/plugins/graph/README.md deleted file mode 100644 index da7c4ca7925aaed7a7177c4a9dc69d661f0178d1..0000000000000000000000000000000000000000 --- a/plugins/graph/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# How to install this plugin -- Run the following commands in this folder (or set `graph.socketioPath` and `graph.webrootPath` in your config if you want to use another path) - -```bash -git clone https://github.com/glumb/IOTAtangle.git -cd IOTAtangle && git reset --hard 07bba77a296a2d06277cdae56aa963abeeb5f66e -cd ../ -git clone https://github.com/socketio/socket.io-client.git -``` \ No newline at end of file diff --git a/plugins/graph/graph.go b/plugins/graph/graph.go deleted file mode 100644 index e0946cc3a2e8a5c38644cf6fb0e0cfe750bed436..0000000000000000000000000000000000000000 --- a/plugins/graph/graph.go +++ /dev/null @@ -1,144 +0,0 @@ -package graph - -import ( - "container/ring" - "fmt" - "strconv" - "strings" - - socketio "github.com/googollee/go-socket.io" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/iota.go/consts" - - "github.com/iotaledger/hive.go/syncutils" -) - -const ( - TX_BUFFER_SIZE = 1800 -) - -var ( - txRingBuffer *ring.Ring // transactions - snRingBuffer *ring.Ring // confirmed transactions - msRingBuffer *ring.Ring // Milestones - - broadcastLock = syncutils.Mutex{} - txRingBufferLock = syncutils.Mutex{} -) - -type wsTransaction struct { - Hash string `json:"hash"` - Address string `json:"address"` - Value string `json:"value"` - Tag string `json:"tag"` - Timestamp string `json:"timestamp"` - CurrentIndex string `json:"current_index"` - LastIndex string `json:"last_index"` - Bundle string `json:"bundle_hash"` - TrunkTransaction string `json:"transaction_trunk"` - BranchTransaction string `json:"transaction_branch"` -} - -type wsTransactionSn struct { - Hash string `json:"hash"` - Address string `json:"address"` - TrunkTransaction string `json:"transaction_trunk"` - BranchTransaction string `json:"transaction_branch"` - Bundle string `json:"bundle"` -} - -type wsConfig struct { - NetworkName string `json:"networkName"` -} - -func initRingBuffers() { - txRingBuffer = ring.New(TX_BUFFER_SIZE) - snRingBuffer = ring.New(TX_BUFFER_SIZE) - msRingBuffer = ring.New(20) -} - -func onConnectHandler(s socketio.Conn) error { - infoMsg := "Graph client connection established" - if s != nil { - infoMsg = fmt.Sprintf("%s (ID: %v)", infoMsg, s.ID()) - } - log.Info(infoMsg) - socketioServer.JoinRoom("broadcast", s) - - config := &wsConfig{NetworkName: parameter.NodeConfig.GetString(CFG_NETWORK)} - - var initTxs []*wsTransaction - txRingBuffer.Do(func(tx interface{}) { - if tx != nil { - initTxs = append(initTxs, tx.(*wsTransaction)) - } - }) - - var initSns []*wsTransactionSn - snRingBuffer.Do(func(sn interface{}) { - if sn != nil { - initSns = append(initSns, sn.(*wsTransactionSn)) - } - }) - - var initMs []string - msRingBuffer.Do(func(ms interface{}) { - if ms != nil { - initMs = append(initMs, ms.(string)) - } - }) - - s.Emit("config", config) - s.Emit("inittx", initTxs) - s.Emit("initsn", initSns) - s.Emit("initms", initMs) - s.Emit("donation", "0") - s.Emit("donations", []int{}) - s.Emit("donation-address", "-") - - return nil -} - -func onErrorHandler(conn socketio.Conn, e error) { - errorMsg := "Graph meet error" - if e != nil { - errorMsg = fmt.Sprintf("%s: %s", errorMsg, e.Error()) - } - log.Error(errorMsg) -} - -func onDisconnectHandler(s socketio.Conn, msg string) { - infoMsg := "Graph client connection closed" - if s != nil { - infoMsg = fmt.Sprintf("%s (ID: %v)", infoMsg, s.ID()) - } - log.Info(fmt.Sprintf("%s: %s", infoMsg, msg)) - socketioServer.LeaveAllRooms(s) -} - -var emptyTag = strings.Repeat("9", consts.TagTrinarySize/3) - -func onNewTx(tx *value_transaction.ValueTransaction) { - wsTx := &wsTransaction{ - Hash: tx.GetHash(), - Address: tx.GetAddress(), - Value: strconv.FormatInt(tx.GetValue(), 10), - Tag: emptyTag, - Timestamp: strconv.FormatInt(int64(tx.GetTimestamp()), 10), - CurrentIndex: "0", - LastIndex: "0", - Bundle: consts.NullHashTrytes, - TrunkTransaction: tx.GetTrunkTransactionHash(), - BranchTransaction: tx.GetBranchTransactionHash(), - } - - txRingBufferLock.Lock() - txRingBuffer.Value = wsTx - txRingBuffer = txRingBuffer.Next() - txRingBufferLock.Unlock() - - broadcastLock.Lock() - socketioServer.BroadcastToRoom("broadcast", "tx", wsTx) - broadcastLock.Unlock() -} diff --git a/plugins/graph/parameters.go b/plugins/graph/parameters.go deleted file mode 100644 index 7b49d680d262140e2fa4180da1dab811e430ff48..0000000000000000000000000000000000000000 --- a/plugins/graph/parameters.go +++ /dev/null @@ -1,22 +0,0 @@ -package graph - -import ( - "github.com/iotaledger/goshimmer/plugins/cli" - flag "github.com/spf13/pflag" -) - -const ( - CFG_WEBROOT = "graph.webrootPath" - CFG_SOCKET_IO = "graph.socketioPath" - CFG_DOMAIN = "graph.domain" - CFG_BIND_ADDRESS = "graph.bindAddress" - CFG_NETWORK = "graph.networkName" -) - -func init() { - flag.String(CFG_WEBROOT, "IOTAtangle/webroot", "Path to IOTA Tangle Visualiser webroot files") - flag.String(CFG_SOCKET_IO, "socket.io-client/dist/socket.io.js", "Path to socket.io.js") - flag.String(CFG_DOMAIN, "", "Set the domain on which IOTA Tangle Visualiser is served") - flag.String(CFG_BIND_ADDRESS, "127.0.0.1:8082", "the bind address for the IOTA Tangle Visualizer") - flag.String(CFG_NETWORK, cli.AppName, "Name of the network shown in IOTA Tangle Visualiser") -} diff --git a/plugins/graph/plugin.go b/plugins/graph/plugin.go deleted file mode 100644 index af5861654331de80acf31a44c52676fc21f8d41d..0000000000000000000000000000000000000000 --- a/plugins/graph/plugin.go +++ /dev/null @@ -1,143 +0,0 @@ -package graph - -import ( - "errors" - "net/http" - "time" - - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/tangle" - "golang.org/x/net/context" - - engineio "github.com/googollee/go-engine.io" - "github.com/googollee/go-engine.io/transport" - "github.com/googollee/go-engine.io/transport/polling" - "github.com/googollee/go-engine.io/transport/websocket" - socketio "github.com/googollee/go-socket.io" - - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/hive.go/workerpool" -) - -var ( - PLUGIN = node.NewPlugin("Graph", node.Disabled, configure, run) - - log *logger.Logger - - newTxWorkerCount = 1 - newTxWorkerQueueSize = 10000 - newTxWorkerPool *workerpool.WorkerPool - - server *http.Server - router *http.ServeMux - socketioServer *socketio.Server -) - -func downloadSocketIOHandler(w http.ResponseWriter, r *http.Request) { - http.ServeFile(w, r, parameter.NodeConfig.GetString(CFG_SOCKET_IO)) -} - -func configureSocketIOServer() error { - var err error - - socketioServer, err = socketio.NewServer(&engineio.Options{ - PingTimeout: time.Second * 20, - PingInterval: time.Second * 5, - Transports: []transport.Transport{ - polling.Default, - websocket.Default, - }, - }) - if err != nil { - return err - } - - socketioServer.OnConnect("/", onConnectHandler) - socketioServer.OnError("/", onErrorHandler) - socketioServer.OnDisconnect("/", onDisconnectHandler) - - return nil -} - -func configure(plugin *node.Plugin) { - log = logger.NewLogger("Graph") - initRingBuffers() - - router = http.NewServeMux() - - // socket.io and web server - server = &http.Server{ - Addr: parameter.NodeConfig.GetString(CFG_BIND_ADDRESS), - Handler: router, - } - - fs := http.FileServer(http.Dir(parameter.NodeConfig.GetString(CFG_WEBROOT))) - - if err := configureSocketIOServer(); err != nil { - log.Panicf("Graph: %v", err.Error()) - } - - router.Handle("/", fs) - router.HandleFunc("/socket.io/socket.io.js", downloadSocketIOHandler) - router.Handle("/socket.io/", socketioServer) - - newTxWorkerPool = workerpool.New(func(task workerpool.Task) { - onNewTx(task.Param(0).(*value_transaction.ValueTransaction)) - task.Return(nil) - }, workerpool.WorkerCount(newTxWorkerCount), workerpool.QueueSize(newTxWorkerQueueSize)) -} - -func run(*node.Plugin) { - - notifyNewTx := events.NewClosure(func(transaction *value_transaction.ValueTransaction) { - newTxWorkerPool.TrySubmit(transaction) - }) - - daemon.BackgroundWorker("Graph[NewTxWorker]", func(shutdownSignal <-chan struct{}) { - log.Info("Starting Graph[NewTxWorker] ... done") - tangle.Events.TransactionStored.Attach(notifyNewTx) - newTxWorkerPool.Start() - <-shutdownSignal - tangle.Events.TransactionStored.Detach(notifyNewTx) - newTxWorkerPool.Stop() - log.Info("Stopping Graph[NewTxWorker] ... done") - }, shutdown.ShutdownPriorityGraph) - - daemon.BackgroundWorker("Graph Webserver", func(shutdownSignal <-chan struct{}) { - go socketioServer.Serve() - - stopped := make(chan struct{}) - go func() { - log.Infof("You can now access IOTA Tangle Visualiser using: http://%s", parameter.NodeConfig.GetString(CFG_BIND_ADDRESS)) - if err := server.ListenAndServe(); err != nil { - if !errors.Is(err, http.ErrServerClosed) { - log.Errorf("Error serving: %s", err) - } - } - close(stopped) - }() - - select { - case <-shutdownSignal: - case <-stopped: - } - - log.Info("Stopping Graph Webserver ...") - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - if err := server.Shutdown(ctx); err != nil { - log.Errorf("Error stopping: %s", err) - } - - if err := socketioServer.Close(); err != nil { - log.Errorf("Error closing Socket.IO server: %s", err) - } - log.Info("Stopping Graph Webserver ... done") - }, shutdown.ShutdownPriorityGraph) -} diff --git a/plugins/issuer/plugin.go b/plugins/issuer/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..85a997f99e514ab8c4482511107facb702be24f4 --- /dev/null +++ b/plugins/issuer/plugin.go @@ -0,0 +1,40 @@ +package issuer + +import ( + "fmt" + goSync "sync" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/goshimmer/plugins/sync" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the issuer plugin. +const PluginName = "Issuer" + +var ( + // plugin is the plugin instance of the issuer plugin. + plugin *node.Plugin + once goSync.Once +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(_ *node.Plugin) {} + +// IssuePayload issues a payload to the message layer. +// If the node is not synchronized an error is returned. +func IssuePayload(payload payload.Payload) (*message.Message, error) { + if !sync.Synced() { + return nil, fmt.Errorf("can't issue payload: %w", sync.ErrNodeNotSynchronized) + } + return messagelayer.MessageFactory().IssuePayload(payload), nil +} diff --git a/plugins/logger/parameters.go b/plugins/logger/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..d5326d8ee3867be2f43234783b3385a36e2d6469 --- /dev/null +++ b/plugins/logger/parameters.go @@ -0,0 +1,29 @@ +package logger + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgLoggerLevel defines the logger's level. + CfgLoggerLevel = "logger.level" + // CfgLoggerDisableCaller defines whether to disable caller info. + CfgLoggerDisableCaller = "logger.disableCaller" + // CfgLoggerDisableStacktrace defines whether to disable stack trace info. + CfgLoggerDisableStacktrace = "logger.disableStacktrace" + // CfgLoggerEncoding defines the logger's encoding. + CfgLoggerEncoding = "logger.encoding" + // CfgLoggerOutputPaths defines the logger's output paths. + CfgLoggerOutputPaths = "logger.outputPaths" + // CfgLoggerDisableEvents defines whether to disable logger events. + CfgLoggerDisableEvents = "logger.disableEvents" +) + +func initFlags() { + flag.String(CfgLoggerLevel, "info", "log level") + flag.Bool(CfgLoggerDisableCaller, false, "disable caller info in log") + flag.Bool(CfgLoggerDisableStacktrace, false, "disable stack trace in log") + flag.String(CfgLoggerEncoding, "console", "log encoding") + flag.StringSlice(CfgLoggerOutputPaths, []string{"stdout", "goshimmer.log"}, "log output paths") + flag.Bool(CfgLoggerDisableEvents, true, "disable logger events") +} diff --git a/plugins/logger/plugin.go b/plugins/logger/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..f05107bf69ebcd13e299c564583755d3d29cb785 --- /dev/null +++ b/plugins/logger/plugin.go @@ -0,0 +1,44 @@ +package logger + +import ( + "sync" + + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the logger plugin. +const PluginName = "Logger" + +var ( + // plugin is the plugin instance of the logger plugin. + plugin *node.Plugin + once sync.Once +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled) + }) + return plugin +} + +// Init triggers the Init event. +func Init() { + plugin.Events.Init.Trigger(plugin) +} + +func init() { + plugin = Plugin() + + initFlags() + + plugin.Events.Init.Attach(events.NewClosure(func(*node.Plugin) { + if err := logger.InitGlobalLogger(config.Node()); err != nil { + panic(err) + } + })) +} diff --git a/plugins/messagelayer/plugin.go b/plugins/messagelayer/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..2286db7e2b0b0c4da55d953d8bc9fe719174f65a --- /dev/null +++ b/plugins/messagelayer/plugin.go @@ -0,0 +1,148 @@ +package messagelayer + +import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagerequester" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tipselector" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/database" + "github.com/iotaledger/hive.go/autopeering/peer" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" +) + +const ( + PluginName = "MessageLayer" + DBSequenceNumber = "seq" +) + +var ( + // plugin is the plugin instance of the message layer plugin. + plugin *node.Plugin + pluginOnce sync.Once + messageParser *messageparser.MessageParser + msgParserOnce sync.Once + messageRequester *messagerequester.MessageRequester + msgReqOnce sync.Once + tipSelector *tipselector.TipSelector + tipSelectorOnce sync.Once + _tangle *tangle.Tangle + tangleOnce sync.Once + messageFactory *messagefactory.MessageFactory + msgFactoryOnce sync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + pluginOnce.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} + +// MessageParser gets the messageParser instance. +func MessageParser() *messageparser.MessageParser { + msgParserOnce.Do(func() { + messageParser = messageparser.New() + }) + return messageParser +} + +// TipSelector gets the tipSelector instance. +func TipSelector() *tipselector.TipSelector { + tipSelectorOnce.Do(func() { + tipSelector = tipselector.New() + }) + return tipSelector +} + +// Tangle gets the tangle instance. +func Tangle() *tangle.Tangle { + tangleOnce.Do(func() { + store := database.Store() + _tangle = tangle.New(store) + }) + return _tangle +} + +// MessageFactory gets the messageFactory instance. +func MessageFactory() *messagefactory.MessageFactory { + msgFactoryOnce.Do(func() { + messageFactory = messagefactory.New(database.Store(), []byte(DBSequenceNumber), local.GetInstance().LocalIdentity(), TipSelector()) + }) + return messageFactory +} + +// MessageRequester gets the messageRequester instance. +func MessageRequester() *messagerequester.MessageRequester { + msgReqOnce.Do(func() { + messageRequester = messagerequester.New() + }) + return messageRequester +} + +func configure(*node.Plugin) { + log = logger.NewLogger(PluginName) + + // create instances + messageParser = MessageParser() + messageRequester = MessageRequester() + tipSelector = TipSelector() + _tangle = Tangle() + + // Setup messageFactory (behavior + logging)) + messageFactory = MessageFactory() + messageFactory.Events.MessageConstructed.Attach(events.NewClosure(_tangle.AttachMessage)) + messageFactory.Events.Error.Attach(events.NewClosure(func(err error) { + log.Errorf("internal error in message factory: %v", err) + })) + + // setup messageParser + messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msg *message.Message, peer *peer.Peer) { + // TODO: ADD PEER + _tangle.AttachMessage(msg) + })) + + // setup messageRequester + _tangle.Events.MessageMissing.Attach(events.NewClosure(messageRequester.ScheduleRequest)) + _tangle.Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + cachedMessageMetadata.Release() + cachedMessage.Consume(func(msg *message.Message) { + messageRequester.StopRequest(msg.Id()) + }) + })) + + // setup tipSelector + _tangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + cachedMessageMetadata.Release() + cachedMessage.Consume(tipSelector.AddTip) + })) +} + +func run(*node.Plugin) { + + if err := daemon.BackgroundWorker("Tangle[MissingMessagesMonitor]", func(shutdownSignal <-chan struct{}) { + _tangle.MonitorMissingMessages(shutdownSignal) + }, shutdown.PriorityMissingMessagesMonitoring); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } + + if err := daemon.BackgroundWorker("Tangle", func(shutdownSignal <-chan struct{}) { + <-shutdownSignal + messageFactory.Shutdown() + messageParser.Shutdown() + _tangle.Shutdown() + }, shutdown.PriorityTangle); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } + +} diff --git a/plugins/metrics/autopeering.go b/plugins/metrics/autopeering.go new file mode 100644 index 0000000000000000000000000000000000000000..7a20ac62cd59a8de6483da83eaa86a03a8e22306 --- /dev/null +++ b/plugins/metrics/autopeering.go @@ -0,0 +1,86 @@ +package metrics + +import ( + "sync" + "time" + + gossipPkg "github.com/iotaledger/goshimmer/packages/gossip" + "github.com/iotaledger/hive.go/autopeering/selection" + "github.com/iotaledger/hive.go/events" + "go.uber.org/atomic" +) + +var ( + neighborDropCount uint64 + neighborConnectionsLifeTime time.Duration + neighborMutex sync.RWMutex + + neighborConnectionsCount atomic.Uint64 + autopeeringConnectionsCount uint64 + sumDistance uint64 + minDistance = uint64(^uint32(0)) + maxDistance uint64 + distanceMutex sync.RWMutex +) + +var ( + onNeighborRemoved = events.NewClosure(func(n *gossipPkg.Neighbor) { + neighborMutex.Lock() + defer neighborMutex.Unlock() + neighborDropCount++ + neighborConnectionsLifeTime += time.Since(n.ConnectionEstablished()) + }) + + onNeighborAdded = events.NewClosure(func(_ *gossipPkg.Neighbor) { + neighborConnectionsCount.Inc() + }) + + onAutopeeringSelection = events.NewClosure(func(ev *selection.PeeringEvent) { + distanceMutex.Lock() + defer distanceMutex.Unlock() + autopeeringConnectionsCount++ + distance := uint64(ev.Distance) + if distance < minDistance { + minDistance = distance + } + if distance > maxDistance { + maxDistance = distance + } + sumDistance += distance + }) +) + +// NeighborDropCount returns the neighbor drop count. +func NeighborDropCount() uint64 { + neighborMutex.RLock() + defer neighborMutex.RUnlock() + return neighborDropCount +} + +// AvgNeighborConnectionLifeTime return the average neighbor connection lifetime. +func AvgNeighborConnectionLifeTime() float64 { + neighborMutex.RLock() + defer neighborMutex.RUnlock() + if neighborDropCount == 0 { + return 0. + } + return float64(neighborConnectionsLifeTime.Milliseconds()) / float64(neighborDropCount) +} + +// NeighborConnectionsCount returns the neighbors connections count. +func NeighborConnectionsCount() uint64 { + return neighborConnectionsCount.Load() +} + +// AutopeeringDistanceStats returns statistics of the autopeering distance function. +func AutopeeringDistanceStats() (min, max uint64, avg float64) { + distanceMutex.RLock() + defer distanceMutex.RUnlock() + min, max = minDistance, maxDistance + if autopeeringConnectionsCount == 0 { + avg = 0 + return + } + avg = float64(sumDistance) / float64(autopeeringConnectionsCount) + return +} diff --git a/plugins/metrics/events.go b/plugins/metrics/events.go index 03a51d819cbb0e6e09bbeea5798779bbc9e04cbc..6cb8550a9f5f498a2a1565ca3d56af448751f145 100644 --- a/plugins/metrics/events.go +++ b/plugins/metrics/events.go @@ -4,11 +4,17 @@ import ( "github.com/iotaledger/hive.go/events" ) +// Events defines the events of the plugin. var Events = pluginEvents{ + // ReceivedMPSUpdated triggers upon reception of a MPS update. + ReceivedMPSUpdated: events.NewEvent(uint64EventCaller), ReceivedTPSUpdated: events.NewEvent(uint64EventCaller), } type pluginEvents struct { + // Fired when the messages per second metric is updated. + ReceivedMPSUpdated *events.Event + // Fired when the transactions per second metric is updated. ReceivedTPSUpdated *events.Event } diff --git a/plugins/metrics/fpc.go b/plugins/metrics/fpc.go new file mode 100644 index 0000000000000000000000000000000000000000..3373175208245a707efdc6d31bf0c76b596272c9 --- /dev/null +++ b/plugins/metrics/fpc.go @@ -0,0 +1,107 @@ +package metrics + +import ( + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/hive.go/syncutils" + "go.uber.org/atomic" +) + +var ( + activeConflicts atomic.Uint64 + finalizedConflictCount atomic.Uint64 + failedConflictCount atomic.Uint64 + sumRounds atomic.Uint64 + avLock syncutils.RWMutex + + // queryReceivedCount is the number of queries received (each query can contain multiple conflicts to give an opinion about). + queryReceivedCount atomic.Uint64 + + // opinionQueryReceivedCount is the number of opinion queries received (multiple in one query). + opinionQueryReceivedCount atomic.Uint64 + + // queryReplyErrorCount counts how many times we haven't received an answer for our query. + // (each query reply can contain multiple conflicts to get an opinion about). + queryReplyErrorCount atomic.Uint64 + + // opinionQueryReplyErrorCount counts how many opinions we asked for but never heard back (multiple opinions in one query). + opinionQueryReplyErrorCount atomic.Uint64 +) + +// ActiveConflicts returns the number of currently active conflicts. +func ActiveConflicts() uint64 { + return activeConflicts.Load() +} + +// FinalizedConflict returns the number of finalized conflicts since the start of the node. +func FinalizedConflict() uint64 { + return finalizedConflictCount.Load() +} + +// FailedConflicts returns the number of failed conflicts since the start of the node. +func FailedConflicts() uint64 { + return failedConflictCount.Load() +} + +// AverageRoundsToFinalize returns the average number of rounds it takes to finalize conflicts since the start of the node. +func AverageRoundsToFinalize() float64 { + if FinalizedConflict() == 0 { + return 0 + } + return float64(sumRounds.Load()) / float64(FinalizedConflict()) +} + +// FPCQueryReceived returns the number of received voting queries. For an exact number of opinion queries, use FPCOpinionQueryReceived(). +func FPCQueryReceived() uint64 { + return queryReceivedCount.Load() +} + +// FPCOpinionQueryReceived returns the number of received opinion queries. +func FPCOpinionQueryReceived() uint64 { + return opinionQueryReceivedCount.Load() +} + +// FPCQueryReplyErrors returns the number of sent but unanswered queries for conflict opinions. For an exact number of failed opinions, use FPCOpinionQueryReplyErrors(). +func FPCQueryReplyErrors() uint64 { + return queryReplyErrorCount.Load() +} + +// FPCOpinionQueryReplyErrors returns the number of opinions that the node failed to gather from peers. +func FPCOpinionQueryReplyErrors() uint64 { + return opinionQueryReplyErrorCount.Load() +} + +//// logic broken into "process..." functions to be able to write unit tests //// + +func processRoundStats(stats *vote.RoundStats) { + // get the number of active conflicts + numActive := (uint64)(len(stats.ActiveVoteContexts)) + activeConflicts.Store(numActive) +} + +func processFinalized(ctx vote.Context) { + avLock.Lock() + defer avLock.Unlock() + // calculate sum of all rounds, including the currently finalized + sumRounds.Add(uint64(ctx.Rounds)) + // increase finalized counter + finalizedConflictCount.Inc() +} + +func processFailed(ctx vote.Context) { + failedConflictCount.Inc() +} + +func processQueryReceived(ev *metrics.QueryReceivedEvent) { + // received one query + queryReceivedCount.Inc() + // containing this many conflicts to give opinion about + opinionQueryReceivedCount.Add((uint64)(ev.OpinionCount)) +} + +func processQueryReplyError(ev *metrics.QueryReplyErrorEvent) { + // received one query + queryReplyErrorCount.Inc() + // containing this many conflicts to give opinion about + opinionQueryReplyErrorCount.Add((uint64)(ev.OpinionCount)) +} diff --git a/plugins/metrics/fpc_test.go b/plugins/metrics/fpc_test.go new file mode 100644 index 0000000000000000000000000000000000000000..65b0752f991871a7a00a04d0691155b83605da6a --- /dev/null +++ b/plugins/metrics/fpc_test.go @@ -0,0 +1,89 @@ +package metrics + +import ( + "testing" + + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/magiconair/properties/assert" +) + +func TestActiveConflicts(t *testing.T) { + // initialized to 0 + assert.Equal(t, ActiveConflicts(), (uint64)(0)) + stats := &vote.RoundStats{ + ActiveVoteContexts: map[string]*vote.Context{ + "test1": {}, + "test2": {}, + "test3": {}, + }, + } + processRoundStats(stats) + assert.Equal(t, ActiveConflicts(), (uint64)(3)) +} + +func TestFailedConflicts(t *testing.T) { + // initialized to 0 + assert.Equal(t, FailedConflicts(), (uint64)(0)) + // simulate 10 failed conflicts + for i := 0; i < 10; i++ { + processFailed(vote.Context{}) + } + assert.Equal(t, FailedConflicts(), (uint64)(10)) + // simulate 10 failed conflicts + for i := 0; i < 10; i++ { + processFailed(vote.Context{}) + } + assert.Equal(t, FailedConflicts(), (uint64)(20)) +} + +func TestFinalize(t *testing.T) { + assert.Equal(t, AverageRoundsToFinalize(), 0.0) + assert.Equal(t, FinalizedConflict(), (uint64)(0)) + // simulate 5 finalized conflicts with 5 rounds + for i := 0; i < 5; i++ { + processFinalized(vote.Context{ + Rounds: 5, + }) + } + assert.Equal(t, FinalizedConflict(), (uint64)(5)) + // simulate 5 finalized conflicts with 10 rounds + for i := 0; i < 5; i++ { + processFinalized(vote.Context{ + Rounds: 10, + }) + } + assert.Equal(t, FinalizedConflict(), (uint64)(10)) + // => average should be 7.5 + assert.Equal(t, AverageRoundsToFinalize(), 7.5) +} + +func TestQueryReceived(t *testing.T) { + assert.Equal(t, FPCQueryReceived(), (uint64)(0)) + assert.Equal(t, FPCOpinionQueryReceived(), (uint64)(0)) + + processQueryReceived(&metrics.QueryReceivedEvent{OpinionCount: 5}) + + assert.Equal(t, FPCQueryReceived(), (uint64)(1)) + assert.Equal(t, FPCOpinionQueryReceived(), (uint64)(5)) + + processQueryReceived(&metrics.QueryReceivedEvent{OpinionCount: 5}) + + assert.Equal(t, FPCQueryReceived(), (uint64)(2)) + assert.Equal(t, FPCOpinionQueryReceived(), (uint64)(10)) +} + +func TestQueryReplyError(t *testing.T) { + assert.Equal(t, FPCQueryReplyErrors(), (uint64)(0)) + assert.Equal(t, FPCOpinionQueryReplyErrors(), (uint64)(0)) + + processQueryReplyError(&metrics.QueryReplyErrorEvent{OpinionCount: 5}) + + assert.Equal(t, FPCQueryReplyErrors(), (uint64)(1)) + assert.Equal(t, FPCOpinionQueryReplyErrors(), (uint64)(5)) + + processQueryReplyError(&metrics.QueryReplyErrorEvent{OpinionCount: 5}) + + assert.Equal(t, FPCQueryReplyErrors(), (uint64)(2)) + assert.Equal(t, FPCOpinionQueryReplyErrors(), (uint64)(10)) +} diff --git a/plugins/metrics/global_metrics.go b/plugins/metrics/global_metrics.go new file mode 100644 index 0000000000000000000000000000000000000000..0a0ef13968431d42b13bdda64da79de318173658 --- /dev/null +++ b/plugins/metrics/global_metrics.go @@ -0,0 +1,72 @@ +package metrics + +import ( + "sync" + + analysisdashboard "github.com/iotaledger/goshimmer/plugins/analysis/dashboard" + "github.com/iotaledger/goshimmer/plugins/analysis/packet" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/identity" + "go.uber.org/atomic" +) + +// NodeInfo holds info of a node. +type NodeInfo struct { + OS string + // Arch defines the system architecture of the node. + Arch string + // NumCPU defines number of logical cores of the node. + NumCPU int + // CPUUsage defines the CPU usage of the node. + CPUUsage float64 + // MemoryUsage defines the memory usage of the node. + MemoryUsage uint64 +} + +var ( + nodesMetrics = make(map[string]NodeInfo) + nodesMetricsMutex sync.RWMutex + networkDiameter atomic.Int32 +) + +var onMetricHeartbeatReceived = events.NewClosure(func(hb *packet.MetricHeartbeat) { + nodesMetricsMutex.Lock() + defer nodesMetricsMutex.Unlock() + nodesMetrics[shortNodeIDString(hb.OwnID)] = NodeInfo{ + OS: hb.OS, + Arch: hb.Arch, + NumCPU: hb.NumCPU, + CPUUsage: hb.CPUUsage, + MemoryUsage: hb.MemoryUsage, + } +}) + +// NodesMetrics returns info about the OS, arch, number of cpu cores, cpu load and memory usage. +func NodesMetrics() map[string]NodeInfo { + nodesMetricsMutex.RLock() + defer nodesMetricsMutex.RUnlock() + // create copy of the map + var copy = make(map[string]NodeInfo) + // manually copy content + for node, clientInfo := range nodesMetrics { + copy[node] = clientInfo + } + return copy +} + +func calculateNetworkDiameter() { + g := analysisdashboard.NetworkGraph() + diameter := g.Diameter() + networkDiameter.Store(int32(diameter)) +} + +// NetworkDiameter returns the current network diameter. +func NetworkDiameter() int32 { + return networkDiameter.Load() +} + +func shortNodeIDString(b []byte) string { + var id identity.ID + copy(id[:], b) + return id.String() +} diff --git a/plugins/metrics/message.go b/plugins/metrics/message.go new file mode 100644 index 0000000000000000000000000000000000000000..927ce519c53aa8da031b1dd116d69682885fefb2 --- /dev/null +++ b/plugins/metrics/message.go @@ -0,0 +1,95 @@ +package metrics + +import ( + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/syncutils" + "go.uber.org/atomic" +) + +var ( + // Total number of processed messages since start of the node. + messageTotalCount atomic.Uint64 + + // current number of message tips. + messageTips atomic.Uint64 + + // counter for the received MPS + mpsReceivedSinceLastMeasurement atomic.Uint64 + + // measured value of the received MPS + measuredReceivedMPS atomic.Uint64 + + // Number of messages per payload type since start of the node. + messageCountPerPayload = make(map[payload.Type]uint64) + + // protect map from concurrent read/write. + messageCountPerPayloadMutex syncutils.RWMutex +) + +////// Exported functions to obtain metrics from outside ////// + +// MessageTotalCount returns the total number of messages seen since the start of the node. +func MessageTotalCount() uint64 { + return messageTotalCount.Load() +} + +// MessageCountPerPayload returns a map of message payload types and their count since the start of the node. +func MessageCountPerPayload() map[payload.Type]uint64 { + messageCountPerPayloadMutex.RLock() + defer messageCountPerPayloadMutex.RUnlock() + + // copy the original map + copy := make(map[payload.Type]uint64) + for key, element := range messageCountPerPayload { + copy[key] = element + } + + return copy +} + +// MessageTips returns the actual number of tips in the message tangle. +func MessageTips() uint64 { + return messageTips.Load() +} + +////// Handling data updates and measuring ////// + +func increasePerPayloadCounter(p payload.Type) { + messageCountPerPayloadMutex.Lock() + defer messageCountPerPayloadMutex.Unlock() + + // increase cumulative metrics + messageCountPerPayload[p]++ + messageTotalCount.Inc() +} + +func measureMessageTips() { + metrics.Events().MessageTips.Trigger((uint64)(messagelayer.TipSelector().TipCount())) +} + +// ReceivedMessagesPerSecond retrieves the current messages per second number. +func ReceivedMessagesPerSecond() uint64 { + return measuredReceivedMPS.Load() +} + +// increases the received MPS counter +func increaseReceivedMPSCounter() { + mpsReceivedSinceLastMeasurement.Inc() +} + +// measures the received MPS value +func measureReceivedMPS() { + // sample the current counter value into a measured MPS value + sampledMPS := mpsReceivedSinceLastMeasurement.Load() + + // store the measured value + measuredReceivedMPS.Store(sampledMPS) + + // reset the counter + mpsReceivedSinceLastMeasurement.Store(0) + + // trigger events for outside listeners + Events.ReceivedMPSUpdated.Trigger(sampledMPS) +} diff --git a/plugins/metrics/message_test.go b/plugins/metrics/message_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bdf7925a2a2cc979ca13dc62ed831423ccf1afa4 --- /dev/null +++ b/plugins/metrics/message_test.go @@ -0,0 +1,45 @@ +package metrics + +import ( + "sync" + "testing" + + valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + drngpayload "github.com/iotaledger/goshimmer/packages/binary/drng/payload" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/events" + "github.com/magiconair/properties/assert" +) + +func TestMessageCountPerPayload(t *testing.T) { + // it is empty initially + assert.Equal(t, MessageTotalCount(), (uint64)(0)) + // simulate attaching 10 value payloads in 0s < t < 1s + for i := 0; i < 10; i++ { + increasePerPayloadCounter(valuepayload.Type) + } + assert.Equal(t, MessageTotalCount(), (uint64)(10)) + assert.Equal(t, MessageCountPerPayload(), map[payload.Type]uint64{valuepayload.Type: 10}) + // simulate attaching 5 drng payloads + for i := 0; i < 5; i++ { + increasePerPayloadCounter(drngpayload.Type) + } + assert.Equal(t, MessageTotalCount(), (uint64)(15)) + assert.Equal(t, MessageCountPerPayload(), map[payload.Type]uint64{valuepayload.Type: 10, drngpayload.Type: 5}) +} + +func TestMessageTips(t *testing.T) { + var wg sync.WaitGroup + // messagelayer TipSelector not configured here, so to avoid nil pointer panic, we instantiate it + messagelayer.TipSelector() + metrics.Events().MessageTips.Attach(events.NewClosure(func(tips uint64) { + messageTips.Store(tips) + wg.Done() + })) + wg.Add(1) + measureMessageTips() + wg.Wait() + assert.Equal(t, MessageTips(), (uint64)(0)) +} diff --git a/plugins/metrics/network.go b/plugins/metrics/network.go new file mode 100644 index 0000000000000000000000000000000000000000..3a741d5b2ab47f1f2c3226b2ddaeab6e4733d1c8 --- /dev/null +++ b/plugins/metrics/network.go @@ -0,0 +1,82 @@ +package metrics + +import ( + "github.com/iotaledger/goshimmer/plugins/gossip" + "github.com/iotaledger/hive.go/identity" + "go.uber.org/atomic" +) + +var ( + _FPCInboundBytes atomic.Uint64 + _FPCOutboundBytes atomic.Uint64 + + previousNeighbors = make(map[identity.ID]gossipTrafficMetric) + gossipOldTx uint32 + gossipOldRx uint32 + gossipCurrentTx atomic.Uint64 + gossipCurrentRx atomic.Uint64 + + analysisOutboundBytes atomic.Uint64 +) + +// FPCInboundBytes returns the total inbound FPC traffic. +func FPCInboundBytes() uint64 { + return _FPCInboundBytes.Load() +} + +// FPCOutboundBytes returns the total outbound FPC traffic. +func FPCOutboundBytes() uint64 { + return _FPCOutboundBytes.Load() +} + +// GossipInboundBytes returns the total inbound gossip traffic. +func GossipInboundBytes() uint64 { + return gossipCurrentRx.Load() +} + +// GossipOutboundBytes returns the total outbound gossip traffic. +func GossipOutboundBytes() uint64 { + return gossipCurrentTx.Load() +} + +// AnalysisOutboundBytes returns the total outbound analysis traffic. +func AnalysisOutboundBytes() uint64 { + return analysisOutboundBytes.Load() +} + +type gossipTrafficMetric struct { + BytesRead uint32 + BytesWritten uint32 +} + +func gossipCurrentTraffic() (g gossipTrafficMetric) { + neighbors := gossip.Manager().AllNeighbors() + + currentNeighbors := make(map[identity.ID]bool) + for _, neighbor := range neighbors { + currentNeighbors[neighbor.ID()] = true + + if _, ok := previousNeighbors[neighbor.ID()]; !ok { + previousNeighbors[neighbor.ID()] = gossipTrafficMetric{ + BytesRead: neighbor.BytesRead(), + BytesWritten: neighbor.BytesWritten(), + } + } + + g.BytesRead += neighbor.BytesRead() + g.BytesWritten += neighbor.BytesWritten() + } + + for prevNeighbor := range previousNeighbors { + if _, ok := currentNeighbors[prevNeighbor]; !ok { + gossipOldRx += previousNeighbors[prevNeighbor].BytesRead + gossipOldTx += previousNeighbors[prevNeighbor].BytesWritten + delete(currentNeighbors, prevNeighbor) + } + } + + g.BytesRead += gossipOldRx + g.BytesWritten += gossipOldTx + + return +} diff --git a/plugins/metrics/parameters.go b/plugins/metrics/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..601c31d596cf62c8971211bebc4f5101447ef9b5 --- /dev/null +++ b/plugins/metrics/parameters.go @@ -0,0 +1,17 @@ +package metrics + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgMetricsLocal defines the config flag to enable/disable local metrics. + CfgMetricsLocal = "metrics.local" + // CfgMetricsGlobal defines the config flag to enable/disable global metrics. + CfgMetricsGlobal = "metrics.global" +) + +func init() { + flag.Bool(CfgMetricsLocal, true, "include local metrics") + flag.Bool(CfgMetricsGlobal, false, "include global metrics") +} diff --git a/plugins/metrics/plugin.go b/plugins/metrics/plugin.go index 3624874e7043d791ae61c8fb9129d35d59dc772c..a60b7be6f95dfdd1d71a5e105eedb420687e3527 100644 --- a/plugins/metrics/plugin.go +++ b/plugins/metrics/plugin.go @@ -1,26 +1,160 @@ package metrics import ( + "sync" "time" - "github.com/iotaledger/goshimmer/packages/gossip" + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + valuetangle "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + "github.com/iotaledger/goshimmer/packages/metrics" "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/packages/vote" + "github.com/iotaledger/goshimmer/plugins/analysis/server" + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/gossip" + "github.com/iotaledger/goshimmer/plugins/messagelayer" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" "github.com/iotaledger/hive.go/timeutil" ) -var PLUGIN = node.NewPlugin("Metrics", node.Enabled, configure, run) +// PluginName is the name of the metrics plugin. +const PluginName = "Metrics" -func configure(plugin *node.Plugin) { - // increase received TPS counter whenever we receive a new transaction - gossip.Events.TransactionReceived.Attach(events.NewClosure(func(_ *gossip.TransactionReceivedEvent) { increaseReceivedTPSCounter() })) +var ( + // plugin is the plugin instance of the metrics plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} + +func configure(_ *node.Plugin) { + log = logger.NewLogger(PluginName) +} + +func run(_ *node.Plugin) { + + if config.Node().GetBool(CfgMetricsLocal) { + registerLocalMetrics() + } + + // Events from analysis server + if config.Node().GetBool(CfgMetricsGlobal) { + server.Events.MetricHeartbeat.Attach(onMetricHeartbeatReceived) + } + + // create a background worker that update the metrics every second + if err := daemon.BackgroundWorker("Metrics Updater", func(shutdownSignal <-chan struct{}) { + if config.Node().GetBool(CfgMetricsLocal) { + timeutil.Ticker(func() { + measureCPUUsage() + measureMemUsage() + measureSynced() + measureMessageTips() + measureValueTips() + measureReceivedMPS() + + // gossip network traffic + g := gossipCurrentTraffic() + gossipCurrentRx.Store(uint64(g.BytesRead)) + gossipCurrentTx.Store(uint64(g.BytesWritten)) + }, 1*time.Second, shutdownSignal) + } + if config.Node().GetBool(CfgMetricsGlobal) { + timeutil.Ticker(calculateNetworkDiameter, 1*time.Minute, shutdownSignal) + } + + }, shutdown.PriorityMetrics); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } } -func run(plugin *node.Plugin) { - // create a background worker that "measures" the TPS value every second - daemon.BackgroundWorker("Metrics TPS Updater", func(shutdownSignal <-chan struct{}) { - timeutil.Ticker(measureReceivedTPS, 1*time.Second, shutdownSignal) - }, shutdown.ShutdownPriorityMetrics) +func registerLocalMetrics() { + //// Events declared in other packages which we want to listen to here //// + + // increase received MPS counter whenever we attached a message + messagelayer.Tangle().Events.MessageAttached.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + _payloadType := cachedMessage.Unwrap().Payload().Type() + cachedMessage.Release() + cachedMessageMetadata.Release() + increaseReceivedMPSCounter() + increasePerPayloadCounter(_payloadType) + })) + + // Value payload attached + valuetransfers.Tangle().Events.PayloadAttached.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *valuetangle.CachedPayloadMetadata) { + cachedPayload.Release() + cachedPayloadMetadata.Release() + valueTransactionCounter.Inc() + })) + + // FPC round executed + valuetransfers.Voter().Events().RoundExecuted.Attach(events.NewClosure(func(roundStats *vote.RoundStats) { + processRoundStats(roundStats) + })) + + // a conflict has been finalized + valuetransfers.Voter().Events().Finalized.Attach(events.NewClosure(func(ev *vote.OpinionEvent) { + processFinalized(ev.Ctx) + })) + + // consensus failure in conflict resolution + valuetransfers.Voter().Events().Failed.Attach(events.NewClosure(func(ev *vote.OpinionEvent) { + processFailed(ev.Ctx) + })) + + //// Events coming from metrics package //// + + metrics.Events().FPCInboundBytes.Attach(events.NewClosure(func(amountBytes uint64) { + _FPCInboundBytes.Add(amountBytes) + })) + metrics.Events().FPCOutboundBytes.Attach(events.NewClosure(func(amountBytes uint64) { + _FPCOutboundBytes.Add(amountBytes) + })) + metrics.Events().AnalysisOutboundBytes.Attach(events.NewClosure(func(amountBytes uint64) { + analysisOutboundBytes.Add(amountBytes) + })) + metrics.Events().CPUUsage.Attach(events.NewClosure(func(cpuPercent float64) { + cpuUsage.Store(cpuPercent) + })) + metrics.Events().MemUsage.Attach(events.NewClosure(func(memAllocBytes uint64) { + memUsageBytes.Store(memAllocBytes) + })) + metrics.Events().Synced.Attach(events.NewClosure(func(synced bool) { + isSynced.Store(synced) + })) + + gossip.Manager().Events().NeighborRemoved.Attach(onNeighborRemoved) + gossip.Manager().Events().NeighborAdded.Attach(onNeighborAdded) + + autopeering.Selection().Events().IncomingPeering.Attach(onAutopeeringSelection) + autopeering.Selection().Events().OutgoingPeering.Attach(onAutopeeringSelection) + + metrics.Events().MessageTips.Attach(events.NewClosure(func(tipsCount uint64) { + messageTips.Store(tipsCount) + })) + metrics.Events().ValueTips.Attach(events.NewClosure(func(tipsCount uint64) { + valueTips.Store(tipsCount) + })) + + metrics.Events().QueryReceived.Attach(events.NewClosure(func(ev *metrics.QueryReceivedEvent) { + processQueryReceived(ev) + })) + metrics.Events().QueryReplyError.Attach(events.NewClosure(func(ev *metrics.QueryReplyErrorEvent) { + processQueryReplyError(ev) + })) } diff --git a/plugins/metrics/process.go b/plugins/metrics/process.go new file mode 100644 index 0000000000000000000000000000000000000000..9a058a2729b6319e69f7dfaf758f8e75d67055ea --- /dev/null +++ b/plugins/metrics/process.go @@ -0,0 +1,42 @@ +package metrics + +import ( + "runtime" + "time" + + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/shirou/gopsutil/cpu" + "go.uber.org/atomic" +) + +var ( + cpuUsage atomic.Float64 + memUsageBytes atomic.Uint64 +) + +// CPUUsage returns the current cpu usage. +func CPUUsage() float64 { + return cpuUsage.Load() +} + +func measureCPUUsage() { + var p float64 + // Percent calculates the percentage of cpu used either per CPU or combined. + // TODO: use func PercentWithContext for more detailed info. + percent, err := cpu.Percent(time.Second, false) + if err == nil { + p = percent[0] + } + metrics.Events().CPUUsage.Trigger(p) +} + +func measureMemUsage() { + var m runtime.MemStats + runtime.ReadMemStats(&m) + metrics.Events().MemUsage.Trigger(m.Alloc) +} + +// MemUsage returns the current memory allocated as bytes. +func MemUsage() uint64 { + return memUsageBytes.Load() +} diff --git a/plugins/metrics/process_test.go b/plugins/metrics/process_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bd396f0c2eacecdee1ccd653961f50529fef39cd --- /dev/null +++ b/plugins/metrics/process_test.go @@ -0,0 +1,22 @@ +package metrics + +import ( + "sync" + "testing" + + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/hive.go/events" + "github.com/stretchr/testify/assert" +) + +func TestMemUsage(t *testing.T) { + var wg sync.WaitGroup + metrics.Events().MemUsage.Attach(events.NewClosure(func(memUsageBytes uint64) { + assert.NotEqual(t, 0, memUsageBytes) + wg.Done() + })) + + wg.Add(1) + measureMemUsage() + wg.Wait() +} diff --git a/plugins/metrics/sync.go b/plugins/metrics/sync.go new file mode 100644 index 0000000000000000000000000000000000000000..19c6cfb50c78ee9630dcf5605c12c5604ffaf0cb --- /dev/null +++ b/plugins/metrics/sync.go @@ -0,0 +1,21 @@ +package metrics + +import ( + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/plugins/sync" + "go.uber.org/atomic" +) + +var ( + isSynced atomic.Bool +) + +func measureSynced() { + s := sync.Synced() + metrics.Events().Synced.Trigger(s) +} + +// Synced returns if the node is synced. +func Synced() bool { + return isSynced.Load() +} diff --git a/plugins/metrics/sync_test.go b/plugins/metrics/sync_test.go new file mode 100644 index 0000000000000000000000000000000000000000..38d23ca6e1094f682f500c90e793a33317adae7a --- /dev/null +++ b/plugins/metrics/sync_test.go @@ -0,0 +1,23 @@ +package metrics + +import ( + "sync" + "testing" + + "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/hive.go/events" + "github.com/stretchr/testify/assert" +) + +func TestSynced(t *testing.T) { + var wg sync.WaitGroup + metrics.Events().Synced.Attach(events.NewClosure(func(synced bool) { + // sync plugin and node not run, so we expect synced to be false + assert.Equal(t, false, synced) + wg.Done() + })) + + wg.Add(1) + measureSynced() + wg.Wait() +} diff --git a/plugins/metrics/tps.go b/plugins/metrics/tps.go deleted file mode 100644 index 4acdd176af5eda06513af810031af0124193350a..0000000000000000000000000000000000000000 --- a/plugins/metrics/tps.go +++ /dev/null @@ -1,36 +0,0 @@ -package metrics - -import ( - "sync/atomic" -) - -// public api method to proactively retrieve the received TPS value -func GetReceivedTPS() uint64 { - return atomic.LoadUint64(&measuredReceivedTPS) -} - -// counter for the received TPS -var tpsReceivedSinceLastMeasurement uint64 - -// measured value of the received TPS -var measuredReceivedTPS uint64 - -// increases the received TPS counter -func increaseReceivedTPSCounter() { - atomic.AddUint64(&tpsReceivedSinceLastMeasurement, 1) -} - -// measures the received TPS value -func measureReceivedTPS() { - // sample the current counter value into a measured TPS value - sampledTPS := atomic.LoadUint64(&tpsReceivedSinceLastMeasurement) - - // store the measured value - atomic.StoreUint64(&measuredReceivedTPS, sampledTPS) - - // reset the counter - atomic.StoreUint64(&tpsReceivedSinceLastMeasurement, 0) - - // trigger events for outside listeners - Events.ReceivedTPSUpdated.Trigger(sampledTPS) -} diff --git a/plugins/metrics/value.go b/plugins/metrics/value.go new file mode 100644 index 0000000000000000000000000000000000000000..2a9d5c00e0f449210bbede24ddd10a894053a869 --- /dev/null +++ b/plugins/metrics/value.go @@ -0,0 +1,28 @@ +package metrics + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/packages/metrics" + "go.uber.org/atomic" +) + +var ( + // counter of value transaction. + valueTransactionCounter atomic.Uint64 + // current number of value tips. + valueTips atomic.Uint64 +) + +func measureValueTips() { + metrics.Events().ValueTips.Trigger((uint64)(valuetransfers.TipManager().Size())) +} + +// ValueTransactionCounter returns the number of value transactions seen. +func ValueTransactionCounter() uint64 { + return valueTransactionCounter.Load() +} + +// ValueTips returns the actual number of tips in the value tangle. +func ValueTips() uint64 { + return valueTips.Load() +} diff --git a/plugins/metrics/value_test.go b/plugins/metrics/value_test.go new file mode 100644 index 0000000000000000000000000000000000000000..1a67b480a8f14939d9d25cbd7ee59c3a5aced6a1 --- /dev/null +++ b/plugins/metrics/value_test.go @@ -0,0 +1,33 @@ +package metrics + +import ( + "sync" + "testing" + + "github.com/iotaledger/goshimmer/packages/metrics" + + "github.com/iotaledger/hive.go/events" + + "github.com/magiconair/properties/assert" +) + +func TestReceivedTransactionsPerSecond(t *testing.T) { + // simulate attaching 10 value payloads in 0s < t < 1s + for i := 0; i < 10; i++ { + valueTransactionCounter.Inc() + } + + assert.Equal(t, ValueTransactionCounter(), (uint64)(10)) +} + +func TestValueTips(t *testing.T) { + var wg sync.WaitGroup + metrics.Events().ValueTips.Attach(events.NewClosure(func(tips uint64) { + valueTips.Store(tips) + wg.Done() + })) + wg.Add(1) + measureValueTips() + wg.Wait() + assert.Equal(t, ValueTips(), (uint64)(0)) +} diff --git a/plugins/portcheck/plugin.go b/plugins/portcheck/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..e1c7530629a779c4e8caf283160b6ad0987ef2d3 --- /dev/null +++ b/plugins/portcheck/plugin.go @@ -0,0 +1,82 @@ +package portcheck + +import ( + "net" + "sync" + + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/banner" + "github.com/iotaledger/hive.go/autopeering/discover" + "github.com/iotaledger/hive.go/autopeering/peer/service" + "github.com/iotaledger/hive.go/autopeering/server" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the port check plugin. +const PluginName = "PortCheck" + +var ( + // plugin is the plugin instance of the port check plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} + +func configure(*node.Plugin) { + log = logger.NewLogger(PluginName) +} + +func run(*node.Plugin) { + log.Info("Testing autopeering service ...") + checkAutopeeringConnection() + log.Info("Testing autopeering service ... done") +} + +// check that discovery is working and the port is open +func checkAutopeeringConnection() { + peering := local.GetInstance().Services().Get(service.PeeringKey) + + // resolve the bind address + localAddr, err := net.ResolveUDPAddr(peering.Network(), autopeering.BindAddress()) + if err != nil { + log.Fatalf("Error resolving %s: %v", local.CfgBind, err) + } + // open a connection + conn, err := net.ListenUDP(peering.Network(), localAddr) + if err != nil { + log.Fatalf("Error listening: %v", err) + } + defer conn.Close() + + // create a new discovery server for the port check + disc := discover.New(local.GetInstance(), autopeering.ProtocolVersion, autopeering.NetworkVersion, discover.Logger(log)) + srv := server.Serve(local.GetInstance(), conn, log, disc) + defer srv.Close() + + disc.Start(srv) + defer disc.Close() + + for _, master := range autopeering.Discovery().GetMasterPeers() { + err = disc.Ping(master) + if err == nil { + log.Infof("Pong received from %s", master.IP()) + break + } + log.Warnf("Error pinging entry node %s: %s", master.IP(), err) + } + + if err != nil { + log.Fatalf("Please check that %s is publicly reachable at port %d/%s", + banner.AppName, peering.Port(), peering.Network()) + } +} diff --git a/plugins/pow/parameters.go b/plugins/pow/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..422260b1e9bc7521319f0103e9970d6161103f08 --- /dev/null +++ b/plugins/pow/parameters.go @@ -0,0 +1,22 @@ +package pow + +import ( + "time" + + flag "github.com/spf13/pflag" +) + +const ( + // CfgPOWDifficulty defines the config flag of the PoW difficulty. + CfgPOWDifficulty = "pow.difficulty" + // CfgPOWNumThreads defines the config flag of the number of threads used to do the PoW. + CfgPOWNumThreads = "pow.numThreads" + // CfgPOWTimeout defines the config flag for the PoW timeout. + CfgPOWTimeout = "pow.timeout" +) + +func init() { + flag.Int(CfgPOWDifficulty, 22, "PoW difficulty") + flag.Int(CfgPOWNumThreads, 1, "number of threads used to do the PoW") + flag.Duration(CfgPOWTimeout, time.Minute, "PoW timeout") +} diff --git a/plugins/pow/plugin.go b/plugins/pow/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..d8056d6dc213d5ae053b483a43a19886fff8eb35 --- /dev/null +++ b/plugins/pow/plugin.go @@ -0,0 +1,35 @@ +package pow + +import ( + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser/builtinfilters" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the PoW plugin. +const PluginName = "PoW" + +var ( + // Plugin is the plugin instance of the PoW plugin. + Plugin = node.NewPlugin(PluginName, node.Enabled, run) +) + +func run(*node.Plugin) { + // assure that the logger is available + log := logger.NewLogger(PluginName) + + if node.IsSkipped(messagelayer.Plugin()) { + log.Infof("%s is disabled; skipping %s\n", messagelayer.PluginName, PluginName) + return + } + + // assure that the PoW worker is initialized + worker := Worker() + + log.Infof("%s started: difficult=%d", PluginName, difficulty) + + messagelayer.MessageParser().AddBytesFilter(builtinfilters.NewPowFilter(worker, difficulty)) + messagelayer.MessageFactory().SetWorker(messagefactory.WorkerFunc(DoPOW)) +} diff --git a/plugins/pow/pow.go b/plugins/pow/pow.go new file mode 100644 index 0000000000000000000000000000000000000000..69207f5b6792ae48585dcaa3c81e3cd0d6ba7225 --- /dev/null +++ b/plugins/pow/pow.go @@ -0,0 +1,81 @@ +package pow + +import ( + "context" + "crypto" + "crypto/ed25519" + "errors" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/pow" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/logger" + _ "golang.org/x/crypto/blake2b" // required by crypto.BLAKE2b_512 +) + +var ( + // ErrMessageTooSmall is returned when the message is smaller than the 8-byte nonce. + ErrMessageTooSmall = errors.New("message too small") +) + +// parameters +var ( + hash = crypto.BLAKE2b_512 + + // configured via parameters + difficulty int + numWorkers int + timeout time.Duration +) + +var ( + log *logger.Logger + + workerOnce sync.Once + worker *pow.Worker +) + +// Worker returns the PoW worker instance of the PoW plugin. +func Worker() *pow.Worker { + workerOnce.Do(func() { + log = logger.NewLogger(PluginName) + // load the parameters + difficulty = config.Node().GetInt(CfgPOWDifficulty) + numWorkers = config.Node().GetInt(CfgPOWNumThreads) + timeout = config.Node().GetDuration(CfgPOWTimeout) + // create the worker + worker = pow.New(hash, numWorkers) + }) + return worker +} + +// DoPOW performs the PoW on the provided msg and returns the nonce. +func DoPOW(msg []byte) (uint64, error) { + content, err := powData(msg) + if err != nil { + return 0, err + } + + // get the PoW worker + worker := Worker() + + log.Debugw("start PoW", "difficulty", difficulty, "numWorkers", numWorkers) + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + nonce, err := worker.Mine(ctx, content[:len(content)-pow.NonceBytes], difficulty) + + log.Debugw("PoW stopped", "nonce", nonce, "err", err) + + return nonce, err +} + +// powData returns the bytes over which PoW should be computed. +func powData(msgBytes []byte) ([]byte, error) { + contentLength := len(msgBytes) - ed25519.SignatureSize + if contentLength < pow.NonceBytes { + return nil, ErrMessageTooSmall + } + return msgBytes[:contentLength], nil +} diff --git a/plugins/profiling/plugin.go b/plugins/profiling/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..4035e2df98bec4c8fb0eb3b51a900f6d69a1a1de --- /dev/null +++ b/plugins/profiling/plugin.go @@ -0,0 +1,54 @@ +package profiling + +import ( + "net/http" + "runtime" + "sync" + + // import required to profile + _ "net/http/pprof" + + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + flag "github.com/spf13/pflag" +) + +// PluginName is the name of the profiling plugin. +const PluginName = "Profiling" + +var ( + // plugin is the profiling plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger +) + +// CfgProfilingBindAddress defines the config flag of the profiling binding address. +const CfgProfilingBindAddress = "profiling.bindAddress" + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} + +func init() { + flag.String(CfgProfilingBindAddress, "127.0.0.1:6061", "bind address for the pprof server") +} + +func configure(_ *node.Plugin) { + log = logger.NewLogger(PluginName) +} + +func run(_ *node.Plugin) { + bindAddr := config.Node().GetString(CfgProfilingBindAddress) + + runtime.SetMutexProfileFraction(5) + runtime.SetBlockProfileRate(5) + + log.Infof("%s started, bind-address=%s", PluginName, bindAddr) + go http.ListenAndServe(bindAddr, nil) +} diff --git a/plugins/prometheus/autopeering.go b/plugins/prometheus/autopeering.go new file mode 100644 index 0000000000000000000000000000000000000000..5d38aa8444c689f061dec4cce1360de8f1dbdac3 --- /dev/null +++ b/plugins/prometheus/autopeering.go @@ -0,0 +1,66 @@ +package prometheus + +import ( + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + neighborDropCount prometheus.Gauge + avgNeighborConnectionLifeTime prometheus.Gauge + connectionsCount prometheus.Gauge + minDistance prometheus.Gauge + maxDistance prometheus.Gauge + avgDistance prometheus.Gauge +) + +func registerAutopeeringMetrics() { + neighborDropCount = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "autopeering_neighbor_drop_count", + Help: "Autopeering neighbor drop count.", + }) + + avgNeighborConnectionLifeTime = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "autopeering_avg_neighbor_connection_lifetime", + Help: "Autopeering average neighbor connection lifetime.", + }) + + connectionsCount = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "autopeering_neighbor_connections_count", + Help: "Autopeering neighbor connections count.", + }) + + minDistance = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "autopeering_min_distance", + Help: "Autopeering minimum distance with all neighbors.", + }) + + maxDistance = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "autopeering_max_distance", + Help: "Autopeering maximum distance with all neighbors.", + }) + + avgDistance = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "autopeering_avg_distance", + Help: "Autopeering average distance with all neighbors.", + }) + + registry.MustRegister(neighborDropCount) + registry.MustRegister(avgNeighborConnectionLifeTime) + registry.MustRegister(connectionsCount) + registry.MustRegister(minDistance) + registry.MustRegister(maxDistance) + registry.MustRegister(avgDistance) + + addCollect(collectAutopeeringMetrics) +} + +func collectAutopeeringMetrics() { + neighborDropCount.Set(float64(metrics.NeighborDropCount())) + avgNeighborConnectionLifeTime.Set(metrics.AvgNeighborConnectionLifeTime()) + connectionsCount.Set(float64(metrics.NeighborConnectionsCount())) + min, max, avg := metrics.AutopeeringDistanceStats() + minDistance.Set(float64(min)) + maxDistance.Set(float64(max)) + avgDistance.Set(avg) +} diff --git a/plugins/prometheus/db_size.go b/plugins/prometheus/db_size.go new file mode 100644 index 0000000000000000000000000000000000000000..df6e1372ed97805b0c1a22d3c72d37608ff3eab9 --- /dev/null +++ b/plugins/prometheus/db_size.go @@ -0,0 +1,48 @@ +package prometheus + +import ( + "os" + "path/filepath" + + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/database" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + dbSize prometheus.Gauge +) + +func registerDBMetrics() { + dbSize = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "db_size_bytes", + Help: "DB size in bytes.", + }, + ) + + registry.MustRegister(dbSize) + + addCollect(collectDBSize) +} + +func collectDBSize() { + size, err := directorySize(config.Node().GetString(database.CfgDatabaseDir)) + if err == nil { + dbSize.Set(float64(size)) + } +} + +func directorySize(path string) (int64, error) { + var size int64 + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + size += info.Size() + } + return err + }) + return size, err +} diff --git a/plugins/prometheus/fpc.go b/plugins/prometheus/fpc.go new file mode 100644 index 0000000000000000000000000000000000000000..a8fbe667c011da1115e02c342fe3777d767ab1a5 --- /dev/null +++ b/plugins/prometheus/fpc.go @@ -0,0 +1,74 @@ +package prometheus + +import ( + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + activeConflicts prometheus.Gauge + finalizedConflicts prometheus.Gauge + failedConflicts prometheus.Gauge + avgRoundToFin prometheus.Gauge + queryRx prometheus.Gauge + queryOpRx prometheus.Gauge + queryReplyNotRx prometheus.Gauge + queryOpReplyNotRx prometheus.Gauge +) + +func registerFPCMetrics() { + activeConflicts = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_active_conflicts", + Help: "number of currently active conflicts", + }) + finalizedConflicts = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_finalized_conflicts", + Help: "number of finalized conflicts since the start of the node", + }) + failedConflicts = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_failed_conflicts", + Help: "number of failed conflicts since the start of the node", + }) + avgRoundToFin = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_avg_rounds_to_finalize", + Help: "average number of rounds it takes to finalize conflicts since the start of the node", + }) + queryRx = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_queries_received", + Help: "number of received voting queries", + }) + queryOpRx = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_queries_opinion_received", + Help: " number of received opinion queries", + }) + queryReplyNotRx = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_query_replies_not_received", + Help: "number of sent but unanswered queries for conflict opinions", + }) + queryOpReplyNotRx = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "fpc_query_opinion_replies_not_received", + Help: " number of opinions that the node failed to gather from peers", + }) + + registry.MustRegister(activeConflicts) + registry.MustRegister(finalizedConflicts) + registry.MustRegister(failedConflicts) + registry.MustRegister(avgRoundToFin) + registry.MustRegister(queryRx) + registry.MustRegister(queryOpRx) + registry.MustRegister(queryReplyNotRx) + registry.MustRegister(queryOpReplyNotRx) + + addCollect(collectFPCMetrics) +} + +func collectFPCMetrics() { + activeConflicts.Set(float64(metrics.ActiveConflicts())) + finalizedConflicts.Set(float64(metrics.FinalizedConflict())) + failedConflicts.Set(float64(metrics.FailedConflicts())) + avgRoundToFin.Set(metrics.AverageRoundsToFinalize()) + queryRx.Set(float64(metrics.FPCQueryReceived())) + queryOpRx.Set(float64(metrics.FPCOpinionQueryReceived())) + queryReplyNotRx.Set(float64(metrics.FPCQueryReplyErrors())) + queryOpReplyNotRx.Set(float64(metrics.FPCOpinionQueryReplyErrors())) +} diff --git a/plugins/prometheus/global_metrics.go b/plugins/prometheus/global_metrics.go new file mode 100644 index 0000000000000000000000000000000000000000..920bc90f17651897d00df67a249411cb603815df --- /dev/null +++ b/plugins/prometheus/global_metrics.go @@ -0,0 +1,195 @@ +package prometheus + +import ( + "strconv" + + metricspkg "github.com/iotaledger/goshimmer/packages/metrics" + "github.com/iotaledger/goshimmer/packages/vote" + analysisdashboard "github.com/iotaledger/goshimmer/plugins/analysis/dashboard" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/iotaledger/hive.go/events" + "github.com/prometheus/client_golang/prometheus" +) + +const ( + like = "LIKE" + dislike = "DISLIKE" +) + +// These metrics store information collected via the analysis server. +var ( + // Process related metrics. + nodesInfoCPU *prometheus.GaugeVec + nodesInfoMemory *prometheus.GaugeVec + + // Autopeering related metrics. + nodesNeighborCount *prometheus.GaugeVec + networkDiameter prometheus.Gauge + + // FPC related metrics. + conflictCount *prometheus.GaugeVec + conflictFinalizationRounds *prometheus.GaugeVec + conflictOutcome *prometheus.GaugeVec + conflictInitialOpinion *prometheus.GaugeVec +) + +var onFPCFinalized = events.NewClosure(func(ev *metricspkg.AnalysisFPCFinalizedEvent) { + conflictCount.WithLabelValues( + ev.NodeID, + ).Add(1) + + conflictFinalizationRounds.WithLabelValues( + ev.ConflictID, + ev.NodeID, + ).Set(float64(ev.Rounds + 1)) + + conflictOutcome.WithLabelValues( + ev.ConflictID, + ev.NodeID, + opinionToString(ev.Outcome), + ).Set(1) + + conflictInitialOpinion.WithLabelValues( + ev.ConflictID, + ev.NodeID, + opinionToString(ev.Opinions[0]), + ).Set(1) +}) + +func registerClientsMetrics() { + nodesInfoCPU = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "global_nodes_info_cpu", + Help: "Info about node's cpu load labeled with nodeID, OS, ARCH and number of cpu cores", + }, + []string{ + "nodeID", + "OS", + "ARCH", + "NUM_CPU", + }, + ) + + nodesInfoMemory = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "global_nodes_info_mem", + Help: "Info about node's memory usage labeled with nodeID, OS, ARCH and number of cpu cores", + }, + []string{ + "nodeID", + "OS", + "ARCH", + "NUM_CPU", + }, + ) + + nodesNeighborCount = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "global_nodes_neighbor_count", + Help: "Info about node's neighbors count", + }, + []string{ + "nodeID", + "direction", + }, + ) + + networkDiameter = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "global_network_diameter", + Help: "Autopeering network diameter", + }) + + conflictCount = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "global_conflict_count", + Help: "Conflicts count labeled with nodeID", + }, + []string{ + "nodeID", + }, + ) + + conflictFinalizationRounds = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "global_conflict_finalization_rounds", + Help: "Number of rounds to finalize a given conflict labeled with conflictID and nodeID", + }, + []string{ + "conflictID", + "nodeID", + }, + ) + + conflictInitialOpinion = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "global_conflict_initial_opinion", + Help: "Initial opinion of a given conflict labeled with conflictID, nodeID and opinion", + }, + []string{ + "conflictID", + "nodeID", + "opinion", + }, + ) + + conflictOutcome = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "global_conflict_outcome", + Help: "Outcome of a given conflict labeled with conflictID, nodeID and opinion", + }, + []string{ + "conflictID", + "nodeID", + "opinion", + }, + ) + + registry.MustRegister(nodesInfoCPU) + registry.MustRegister(nodesInfoMemory) + registry.MustRegister(nodesNeighborCount) + registry.MustRegister(networkDiameter) + + registry.MustRegister(conflictCount) + registry.MustRegister(conflictFinalizationRounds) + registry.MustRegister(conflictInitialOpinion) + registry.MustRegister(conflictOutcome) + + metricspkg.Events().AnalysisFPCFinalized.Attach(onFPCFinalized) + + addCollect(collectNodesInfo) +} + +func collectNodesInfo() { + nodeInfoMap := metrics.NodesMetrics() + + for nodeID, nodeMetrics := range nodeInfoMap { + nodesInfoCPU.WithLabelValues( + nodeID, + nodeMetrics.OS, + nodeMetrics.Arch, + strconv.Itoa(nodeMetrics.NumCPU), + ).Set(nodeMetrics.CPUUsage) + + nodesInfoMemory.WithLabelValues( + nodeID, + nodeMetrics.OS, + nodeMetrics.Arch, + strconv.Itoa(nodeMetrics.NumCPU), + ).Set(float64(nodeMetrics.MemoryUsage)) + } + + for nodeID, neighborCount := range analysisdashboard.NumOfNeighbors() { + nodesNeighborCount.WithLabelValues(nodeID, "in").Set(float64(neighborCount.Inbound)) + nodesNeighborCount.WithLabelValues(nodeID, "out").Set(float64(neighborCount.Outbound)) + } + + networkDiameter.Set(float64(metrics.NetworkDiameter())) + +} + +func opinionToString(opinion vote.Opinion) string { + if opinion == vote.Like { + return like + } + return dislike +} diff --git a/plugins/prometheus/info.go b/plugins/prometheus/info.go new file mode 100644 index 0000000000000000000000000000000000000000..43b99e8dea80772e64f8bb7f94717ab03bbb90a7 --- /dev/null +++ b/plugins/prometheus/info.go @@ -0,0 +1,42 @@ +package prometheus + +import ( + "github.com/iotaledger/goshimmer/plugins/banner" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + infoApp *prometheus.GaugeVec + sync prometheus.Gauge +) + +func registerInfoMetrics() { + infoApp = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "iota_info_app", + Help: "Node software name and version.", + }, + []string{"name", "version"}, + ) + infoApp.WithLabelValues(banner.AppName, banner.AppVersion).Set(1) + + sync = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "sync", + Help: "Node sync status.", + }) + + registry.MustRegister(infoApp) + registry.MustRegister(sync) + + addCollect(collectInfoMetrics) +} + +func collectInfoMetrics() { + sync.Set(func() float64 { + if metrics.Synced() { + return 1.0 + } + return 0. + }()) +} diff --git a/plugins/prometheus/network.go b/plugins/prometheus/network.go new file mode 100644 index 0000000000000000000000000000000000000000..b0f46f6858fc22d3243e23973b0fc3710648e691 --- /dev/null +++ b/plugins/prometheus/network.go @@ -0,0 +1,68 @@ +package prometheus + +import ( + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + fpcInboundBytes prometheus.Gauge + fpcOutboundBytes prometheus.Gauge + analysisOutboundBytes prometheus.Gauge + gossipInboundBytes prometheus.Gauge + gossipOutboundBytes prometheus.Gauge + autopeeringInboundBytes prometheus.Gauge + autopeeringOutboundBytes prometheus.Gauge +) + +func registerNetworkMetrics() { + fpcInboundBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "traffic_fpc_inbound_bytes", + Help: "FPC RX network traffic [bytes].", + }) + fpcOutboundBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "traffic_fpc_outbound_bytes", + Help: "FPC TX network traffic [bytes].", + }) + autopeeringInboundBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "traffic_autopeering_inbound_bytes", + Help: "traffic_autopeering RX network traffic [bytes].", + }) + autopeeringOutboundBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "traffic_autopeering_outbound_bytes", + Help: "traffic_autopeering TX network traffic [bytes].", + }) + gossipInboundBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "traffic_gossip_inbound_bytes", + Help: "traffic_gossip RX network traffic [bytes].", + }) + gossipOutboundBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "traffic_gossip_outbound_bytes", + Help: "traffic_gossip TX network traffic [bytes].", + }) + analysisOutboundBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "traffic_analysis_outbound_bytes", + Help: "traffic_Analysis client TX network traffic [bytes].", + }) + + registry.MustRegister(fpcInboundBytes) + registry.MustRegister(fpcOutboundBytes) + registry.MustRegister(analysisOutboundBytes) + registry.MustRegister(autopeeringInboundBytes) + registry.MustRegister(autopeeringOutboundBytes) + registry.MustRegister(gossipInboundBytes) + registry.MustRegister(gossipOutboundBytes) + + addCollect(collectNetworkMetrics) +} + +func collectNetworkMetrics() { + fpcInboundBytes.Set(float64(metrics.FPCInboundBytes())) + fpcOutboundBytes.Set(float64(metrics.FPCOutboundBytes())) + analysisOutboundBytes.Set(float64(metrics.AnalysisOutboundBytes())) + autopeeringInboundBytes.Set(float64(autopeering.Conn.RXBytes())) + autopeeringOutboundBytes.Set(float64(autopeering.Conn.TXBytes())) + gossipInboundBytes.Set(float64(metrics.GossipInboundBytes())) + gossipOutboundBytes.Set(float64(metrics.GossipOutboundBytes())) +} diff --git a/plugins/prometheus/parameters.go b/plugins/prometheus/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..dbc77cb0d17fd0c1e1c1544425225e4dd72d1f99 --- /dev/null +++ b/plugins/prometheus/parameters.go @@ -0,0 +1,23 @@ +package prometheus + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgPrometheusGoMetrics defines the config flag to enable/disable go metrics. + CfgPrometheusGoMetrics = "prometheus.goMetrics" + // CfgPrometheusProcessMetrics defines the config flag to enable/disable process metrics. + CfgPrometheusProcessMetrics = "prometheus.processMetrics" + // CfgPrometheusPromhttpMetrics defines the config flag to enable/disable promhttp metrics. + CfgPrometheusPromhttpMetrics = "prometheus.promhttpMetrics" + // CfgPrometheusBindAddress defines the config flag of the bind address on which the Prometheus exporter listens on. + CfgPrometheusBindAddress = "prometheus.bindAddress" +) + +func init() { + flag.String(CfgPrometheusBindAddress, "0.0.0.0:9311", "the bind address on which the Prometheus exporter listens on") + flag.Bool(CfgPrometheusGoMetrics, false, "include go metrics") + flag.Bool(CfgPrometheusProcessMetrics, false, "include process metrics") + flag.Bool(CfgPrometheusPromhttpMetrics, false, "include promhttp metrics") +} diff --git a/plugins/prometheus/plugin.go b/plugins/prometheus/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..5f32a260f1d88e7b54efab6614f7709b0e71c207 --- /dev/null +++ b/plugins/prometheus/plugin.go @@ -0,0 +1,107 @@ +package prometheus + +import ( + "context" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +// Plugin Prometheus +var ( + Plugin = node.NewPlugin("Prometheus", node.Disabled, configure, run) + log *logger.Logger + + server *http.Server + registry = prometheus.NewRegistry() + collects []func() +) + +func configure(plugin *node.Plugin) { + log = logger.NewLogger(plugin.Name) + + if config.Node().GetBool(CfgPrometheusGoMetrics) { + registry.MustRegister(prometheus.NewGoCollector()) + } + if config.Node().GetBool(CfgPrometheusProcessMetrics) { + registry.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) + } + + if config.Node().GetBool(metrics.CfgMetricsLocal) { + registerAutopeeringMetrics() + registerDBMetrics() + registerFPCMetrics() + registerInfoMetrics() + registerNetworkMetrics() + registerProcessMetrics() + registerTangleMetrics() + } + + if config.Node().GetBool(metrics.CfgMetricsGlobal) { + registerClientsMetrics() + } +} + +func addCollect(collect func()) { + collects = append(collects, collect) +} + +func run(plugin *node.Plugin) { + log.Info("Starting Prometheus exporter ...") + + if err := daemon.BackgroundWorker("Prometheus exporter", func(shutdownSignal <-chan struct{}) { + log.Info("Starting Prometheus exporter ... done") + + engine := gin.New() + engine.Use(gin.Recovery()) + engine.GET("/metrics", func(c *gin.Context) { + for _, collect := range collects { + collect() + } + handler := promhttp.HandlerFor( + registry, + promhttp.HandlerOpts{ + EnableOpenMetrics: true, + }, + ) + if config.Node().GetBool(CfgPrometheusPromhttpMetrics) { + handler = promhttp.InstrumentMetricHandler(registry, handler) + } + handler.ServeHTTP(c.Writer, c.Request) + }) + + bindAddr := config.Node().GetString(CfgPrometheusBindAddress) + server = &http.Server{Addr: bindAddr, Handler: engine} + + go func() { + log.Infof("You can now access the Prometheus exporter using: http://%s/metrics", bindAddr) + if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + log.Error("Stopping Prometheus exporter due to an error ... done") + } + }() + + <-shutdownSignal + log.Info("Stopping Prometheus exporter ...") + + if server != nil { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + err := server.Shutdown(ctx) + if err != nil { + log.Error(err.Error()) + } + cancel() + } + log.Info("Stopping Prometheus exporter ... done") + }, shutdown.PriorityPrometheus); err != nil { + log.Panic(err) + } +} diff --git a/plugins/prometheus/process.go b/plugins/prometheus/process.go new file mode 100644 index 0000000000000000000000000000000000000000..05ea6542aa97523b2f748fab3241f43dfae4fa50 --- /dev/null +++ b/plugins/prometheus/process.go @@ -0,0 +1,32 @@ +package prometheus + +import ( + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + cpuUsage prometheus.Gauge + memUsageBytes prometheus.Gauge +) + +func registerProcessMetrics() { + cpuUsage = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "process_cpu_usage", + Help: "CPU (System) usage.", + }) + memUsageBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "process_mem_usage_bytes", + Help: "memory usage [bytes].", + }) + + registry.MustRegister(cpuUsage) + registry.MustRegister(memUsageBytes) + + addCollect(collectProcessMetrics) +} + +func collectProcessMetrics() { + cpuUsage.Set(float64(metrics.CPUUsage())) + memUsageBytes.Set(float64(metrics.MemUsage())) +} diff --git a/plugins/prometheus/tangle.go b/plugins/prometheus/tangle.go new file mode 100644 index 0000000000000000000000000000000000000000..ccf33cc15d3504c096fe984885b40329f44856ec --- /dev/null +++ b/plugins/prometheus/tangle.go @@ -0,0 +1,65 @@ +package prometheus + +import ( + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + messageTips prometheus.Gauge + messagePerTypeCount *prometheus.GaugeVec + messageTotalCount prometheus.Gauge + + transactionCounter prometheus.Gauge + valueTips prometheus.Gauge +) + +func registerTangleMetrics() { + messageTips = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "tangle_message_tips_count", + Help: "Current number of tips in message tangle", + }) + + messagePerTypeCount = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "tangle_messages_per_type_count", + Help: "number of messages per payload type seen since the start of the node", + }, []string{ + "message_type", + }) + + messageTotalCount = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "tangle_message_total_count", + Help: "total number of messages seen since the start of the node", + }) + + transactionCounter = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "tangle_value_transaction_counter", + Help: "number of value transactions (value payloads) seen", + }) + + valueTips = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "tangle_value_tips", + Help: "current number of tips in the value tangle", + }) + + registry.MustRegister(messageTips) + registry.MustRegister(messagePerTypeCount) + registry.MustRegister(messageTotalCount) + registry.MustRegister(transactionCounter) + registry.MustRegister(valueTips) + + addCollect(collectTangleMetrics) +} + +func collectTangleMetrics() { + messageTips.Set(float64(metrics.MessageTips())) + msgCountPerPayload := metrics.MessageCountPerPayload() + for payloadType, count := range msgCountPerPayload { + messagePerTypeCount.WithLabelValues(payload.Name(payloadType)).Set(float64(count)) + } + messageTotalCount.Set(float64(metrics.MessageTotalCount())) + transactionCounter.Set(float64(metrics.ValueTransactionCounter())) + valueTips.Set(float64(metrics.ValueTips())) +} diff --git a/plugins/remotelog/plugin.go b/plugins/remotelog/plugin.go index 97f4898153b61dbb4d15396d31b291523c0c854e..a7018f70d305b617cf569ea5e70c5c1700fbd692 100644 --- a/plugins/remotelog/plugin.go +++ b/plugins/remotelog/plugin.go @@ -1,77 +1,79 @@ -// remotelog is a plugin that enables log messages being sent via UDP to a central ELK stack for debugging. +// Package remotelog is a plugin that enables log messages being sent via UDP to a central ELK stack for debugging. // It is disabled by default and when enabled, additionally, logger.disableEvents=false in config.json needs to be set. // The destination can be set via logger.remotelog.serverAddress. // All events according to logger.level in config.json are sent. package remotelog import ( - "encoding/hex" - "encoding/json" - "fmt" - "net" "os" "path/filepath" "runtime" + "sync" "time" - "github.com/iotaledger/goshimmer/packages/parameter" "github.com/iotaledger/goshimmer/packages/shutdown" "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/goshimmer/plugins/cli" - + "github.com/iotaledger/goshimmer/plugins/banner" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/events" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" "github.com/iotaledger/hive.go/workerpool" - + flag "github.com/spf13/pflag" "gopkg.in/src-d/go-git.v4" ) -type logMessage struct { - Version string `json:"version"` - GitHead string `json:"gitHead,omitempty"` - GitBranch string `json:"gitBranch,omitempty"` - NodeId string `json:"nodeId"` - Level string `json:"level"` - Name string `json:"name"` - Msg string `json:"msg"` - Timestamp time.Time `json:"timestamp"` -} - const ( - CFG_SERVER_ADDRESS = "logger.remotelog.serverAddress" - CFG_DISABLE_EVENTS = "logger.disableEvents" - PLUGIN_NAME = "RemoteLog" + // CfgLoggerRemotelogServerAddress defines the config flag of the server address. + CfgLoggerRemotelogServerAddress = "logger.remotelog.serverAddress" + // CfgDisableEvents defines the config flag for disabling logger events. + CfgDisableEvents = "logger.disableEvents" + // PluginName is the name of the remote log plugin. + PluginName = "RemoteLog" + + remoteLogType = "log" ) var ( - PLUGIN = node.NewPlugin(PLUGIN_NAME, node.Disabled, configure, run) + // plugin is the plugin instance of the remote plugin instance. + plugin *node.Plugin + pluginOnce sync.Once log *logger.Logger - conn net.Conn myID string myGitHead string myGitBranch string workerPool *workerpool.WorkerPool + + remoteLogger *RemoteLoggerConn + remoteLoggerOnce sync.Once ) +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + pluginOnce.Do(func() { + plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) + }) + return plugin +} + +func init() { + flag.String(CfgLoggerRemotelogServerAddress, "ressims.iota.cafe:5213", "RemoteLog server address") +} + func configure(plugin *node.Plugin) { - log = logger.NewLogger(PLUGIN_NAME) + log = logger.NewLogger(PluginName) - if parameter.NodeConfig.GetBool(CFG_DISABLE_EVENTS) { - log.Fatalf("%s in config.json needs to be false so that events can be captured!", CFG_DISABLE_EVENTS) + if config.Node().GetBool(CfgDisableEvents) { + log.Fatalf("%s in config.json needs to be false so that events can be captured!", CfgDisableEvents) return } - c, err := net.Dial("udp", parameter.NodeConfig.GetString(CFG_SERVER_ADDRESS)) - if err != nil { - log.Fatalf("Could not create UDP socket to '%s'. %v", parameter.NodeConfig.GetString(CFG_SERVER_ADDRESS), err) - return - } - conn = c + // initialize remote logger connection + RemoteLogger() if local.GetInstance() != nil { - myID = hex.EncodeToString(local.GetInstance().ID().Bytes()) + myID = local.GetInstance().ID().String() } getGitInfo() @@ -80,7 +82,7 @@ func configure(plugin *node.Plugin) { sendLogMsg(task.Param(0).(logger.Level), task.Param(1).(string), task.Param(2).(string)) task.Return(nil) - }, workerpool.WorkerCount(runtime.NumCPU()), workerpool.QueueSize(1000)) + }, workerpool.WorkerCount(runtime.GOMAXPROCS(0)), workerpool.QueueSize(1000)) } func run(plugin *node.Plugin) { @@ -88,20 +90,22 @@ func run(plugin *node.Plugin) { workerPool.TrySubmit(level, name, msg) }) - daemon.BackgroundWorker(PLUGIN_NAME, func(shutdownSignal <-chan struct{}) { + if err := daemon.BackgroundWorker(PluginName, func(shutdownSignal <-chan struct{}) { logger.Events.AnyMsg.Attach(logEvent) workerPool.Start() <-shutdownSignal - log.Infof("Stopping %s ...", PLUGIN_NAME) + log.Infof("Stopping %s ...", PluginName) logger.Events.AnyMsg.Detach(logEvent) workerPool.Stop() - log.Infof("Stopping %s ... done", PLUGIN_NAME) - }, shutdown.ShutdownPriorityRemoteLog) + log.Infof("Stopping %s ... done", PluginName) + }, shutdown.PriorityRemoteLog); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } } func sendLogMsg(level logger.Level, name string, msg string) { m := logMessage{ - cli.AppVersion, + banner.AppVersion, myGitHead, myGitBranch, myID, @@ -109,9 +113,10 @@ func sendLogMsg(level logger.Level, name string, msg string) { name, msg, time.Now(), + remoteLogType, } - b, _ := json.Marshal(m) - fmt.Fprint(conn, string(b)) + + _ = RemoteLogger().Send(m) } func getGitInfo() { @@ -151,3 +156,30 @@ func getGitDir() string { return gitDir } + +// RemoteLogger represents a connection to our remote log server. +func RemoteLogger() *RemoteLoggerConn { + remoteLoggerOnce.Do(func() { + r, err := newRemoteLoggerConn(config.Node().GetString(CfgLoggerRemotelogServerAddress)) + if err != nil { + log.Fatal(err) + return + } + + remoteLogger = r + }) + + return remoteLogger +} + +type logMessage struct { + Version string `json:"version"` + GitHead string `json:"gitHead,omitempty"` + GitBranch string `json:"gitBranch,omitempty"` + NodeID string `json:"nodeId"` + Level string `json:"level"` + Name string `json:"name"` + Msg string `json:"msg"` + Timestamp time.Time `json:"timestamp"` + Type string `json:"type"` +} diff --git a/plugins/remotelog/remotelogger.go b/plugins/remotelog/remotelogger.go new file mode 100644 index 0000000000000000000000000000000000000000..d2fab8432ae3d28c454a4126eeff8cfc7ede8413 --- /dev/null +++ b/plugins/remotelog/remotelogger.go @@ -0,0 +1,35 @@ +package remotelog + +import ( + "encoding/json" + "fmt" + "net" +) + +// RemoteLoggerConn is a wrapper for a connection to our RemoteLog server. +type RemoteLoggerConn struct { + conn net.Conn +} + +func newRemoteLoggerConn(address string) (*RemoteLoggerConn, error) { + c, err := net.Dial("udp", address) + if err != nil { + return nil, fmt.Errorf("could not create UDP socket to '%s'. %v", address, err) + } + + return &RemoteLoggerConn{conn: c}, nil +} + +// Send sends a message on the RemoteLoggers connection. +func (r *RemoteLoggerConn) Send(msg interface{}) error { + b, err := json.Marshal(msg) + if err != nil { + return err + } + _, err = r.conn.Write(b) + if err != nil { + return err + } + + return nil +} diff --git a/plugins/remotelog/server/.env b/plugins/remotelog/server/.env deleted file mode 100644 index 68aaea9a63f638a31870bb929bbc323409a12ebc..0000000000000000000000000000000000000000 --- a/plugins/remotelog/server/.env +++ /dev/null @@ -1 +0,0 @@ -ELK_VERSION=7.5.2 \ No newline at end of file diff --git a/plugins/remotelog/server/.env.default b/plugins/remotelog/server/.env.default new file mode 100644 index 0000000000000000000000000000000000000000..89b017525eecb4a7a0f397ea8bfee33b8bf05ad8 --- /dev/null +++ b/plugins/remotelog/server/.env.default @@ -0,0 +1,3 @@ +ELK_VERSION=7.5.2 +VIRTUAL_HOST= +LETSENCRYPT_HOST= \ No newline at end of file diff --git a/plugins/remotelog/server/config/logstash/pipeline/logstash.conf b/plugins/remotelog/server/config/logstash/pipeline/logstash.conf index fcc2ccbc0a770d42433a8323a5664fa956f20c8c..c5d451334c6e63916d5aa88a49fa292cc327a40d 100644 --- a/plugins/remotelog/server/config/logstash/pipeline/logstash.conf +++ b/plugins/remotelog/server/config/logstash/pipeline/logstash.conf @@ -20,7 +20,15 @@ filter { } output { - elasticsearch { - hosts => "elasticsearch:9200" - } +# stdout {codec => rubydebug} + if [log][type] == "networkdelay" { + elasticsearch { + hosts => "elasticsearch:9200" + index => "networkdelay" + } + } else { + elasticsearch { + hosts => "elasticsearch:9200" + } + } } \ No newline at end of file diff --git a/plugins/remotelog/server/docker-compose.yml b/plugins/remotelog/server/docker-compose.yml index 69ed87d88d86cb6f112359e7de0528274730f6e7..02784c0051b36d206344b8935e06180e801881a0 100644 --- a/plugins/remotelog/server/docker-compose.yml +++ b/plugins/remotelog/server/docker-compose.yml @@ -4,7 +4,9 @@ services: elasticsearch: container_name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION} + restart: always volumes: + - "/etc/localtime:/etc/localtime:ro" - type: bind source: ./config/elasticsearch.yml target: /usr/share/elasticsearch/config/elasticsearch.yml @@ -23,7 +25,9 @@ services: logstash: container_name: logstash image: docker.elastic.co/logstash/logstash:${ELK_VERSION} + restart: always volumes: + - "/etc/localtime:/etc/localtime:ro" - type: bind source: ./config/logstash/logstash.yml target: /usr/share/logstash/config/logstash.yml @@ -44,13 +48,19 @@ services: kibana: container_name: kibana image: docker.elastic.co/kibana/kibana:${ELK_VERSION} + restart: always volumes: + - "/etc/localtime:/etc/localtime:ro" - type: bind source: ./config/kibana.yml target: /usr/share/kibana/config/kibana.yml read_only: true ports: - - "5601:5601" + - "127.0.0.1:5601:5601" + environment: + - "VIRTUAL_HOST=${VIRTUAL_HOST}" + - "LETSENCRYPT_HOST=${LETSENCRYPT_HOST}" + - "VIRTUAL_PORT=5601" networks: - elk depends_on: diff --git a/plugins/spa/explorer_routes.go b/plugins/spa/explorer_routes.go deleted file mode 100644 index 7d324e149a7f274b5669c7496fa1dc97f6920178..0000000000000000000000000000000000000000 --- a/plugins/spa/explorer_routes.go +++ /dev/null @@ -1,177 +0,0 @@ -package spa - -import ( - "net/http" - "sync" - - "github.com/iotaledger/goshimmer/packages/model/transactionmetadata" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/labstack/echo" - "github.com/pkg/errors" - - "github.com/iotaledger/iota.go/consts" - "github.com/iotaledger/iota.go/guards" - . "github.com/iotaledger/iota.go/trinary" -) - -type ExplorerTx struct { - Hash Hash `json:"hash"` - SignatureMessageFragment Trytes `json:"signature_message_fragment"` - Address Hash `json:"address"` - Value int64 `json:"value"` - Timestamp uint `json:"timestamp"` - Trunk Hash `json:"trunk"` - Branch Hash `json:"branch"` - Solid bool `json:"solid"` - MWM int `json:"mwm"` -} - -func createExplorerTx(hash Hash, tx *value_transaction.ValueTransaction) (*ExplorerTx, error) { - - txMetadata, err := tangle.GetTransactionMetadata(hash, transactionmetadata.New) - if err != nil { - return nil, err - } - - t := &ExplorerTx{ - Hash: tx.GetHash(), - SignatureMessageFragment: tx.GetSignatureMessageFragment(), - Address: tx.GetAddress(), - Timestamp: tx.GetTimestamp(), - Value: tx.GetValue(), - Trunk: tx.GetTrunkTransactionHash(), - Branch: tx.GetBranchTransactionHash(), - Solid: txMetadata.GetSolid(), - } - - // compute mwm - trits := MustTrytesToTrits(hash) - var mwm int - for i := len(trits) - 1; i >= 0; i-- { - if trits[i] == 0 { - mwm++ - continue - } - break - } - t.MWM = mwm - return t, nil -} - -type ExplorerAdress struct { - Txs []*ExplorerTx `json:"txs"` -} - -type SearchResult struct { - Tx *ExplorerTx `json:"tx"` - Address *ExplorerAdress `json:"address"` - Milestone *ExplorerTx `json:"milestone"` -} - -func setupExplorerRoutes(routeGroup *echo.Group) { - - routeGroup.GET("/tx/:hash", func(c echo.Context) error { - t, err := findTransaction(c.Param("hash")) - if err != nil { - return err - } - return c.JSON(http.StatusOK, t) - }) - - routeGroup.GET("/addr/:hash", func(c echo.Context) error { - addr, err := findAddress(c.Param("hash")) - if err != nil { - return err - } - return c.JSON(http.StatusOK, addr) - }) - - routeGroup.GET("/search/:search", func(c echo.Context) error { - search := c.Param("search") - result := &SearchResult{} - - if len(search) < 81 { - return errors.Wrapf(ErrInvalidParameter, "search hash invalid: %s", search) - } - - // auto. remove checksum - search = search[:81] - - wg := sync.WaitGroup{} - wg.Add(2) - go func() { - defer wg.Done() - tx, err := findTransaction(search) - if err == nil { - result.Tx = tx - } - }() - - go func() { - defer wg.Done() - addr, err := findAddress(search) - if err == nil { - result.Address = addr - } - }() - wg.Wait() - - return c.JSON(http.StatusOK, result) - }) -} - -func findTransaction(hash Hash) (*ExplorerTx, error) { - if !guards.IsTrytesOfExactLength(hash, consts.HashTrytesSize) { - return nil, errors.Wrapf(ErrInvalidParameter, "hash invalid: %s", hash) - } - - tx, err := tangle.GetTransaction(hash) - if err != nil { - return nil, err - } - if tx == nil { - return nil, errors.Wrapf(ErrNotFound, "tx hash: %s", hash) - } - - t, err := createExplorerTx(hash, tx) - return t, err -} - -func findAddress(hash Hash) (*ExplorerAdress, error) { - if len(hash) > 81 { - hash = hash[:81] - } - if !guards.IsTrytesOfExactLength(hash, consts.HashTrytesSize) { - return nil, errors.Wrapf(ErrInvalidParameter, "hash invalid: %s", hash) - } - - txHashes, err := tangle.ReadTransactionHashesForAddressFromDatabase(hash) - if err != nil { - return nil, ErrInternalError - } - - if len(txHashes) == 0 { - return nil, errors.Wrapf(ErrNotFound, "address %s not found", hash) - } - - txs := make([]*ExplorerTx, 0, len(txHashes)) - for i := 0; i < len(txHashes); i++ { - txHash := txHashes[i] - - tx, err := tangle.GetTransaction(hash) - if err != nil { - continue - } - if tx == nil { - continue - } - expTx, err := createExplorerTx(txHash, tx) - if err != nil { - return nil, err - } - txs = append(txs, expTx) - } - - return &ExplorerAdress{Txs: txs}, nil -} diff --git a/plugins/spa/frontend/src/app/components/ExplorerAddressResult.tsx b/plugins/spa/frontend/src/app/components/ExplorerAddressResult.tsx deleted file mode 100644 index 6326704d4f15d2f4d022529f116cc02397ce94bd..0000000000000000000000000000000000000000 --- a/plugins/spa/frontend/src/app/components/ExplorerAddressResult.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import * as React from 'react'; -import Container from "react-bootstrap/Container"; -import Row from "react-bootstrap/Row"; -import Col from "react-bootstrap/Col"; -import NodeStore from "app/stores/NodeStore"; -import {inject, observer} from "mobx-react"; -import ExplorerStore from "app/stores/ExplorerStore"; -import Spinner from "react-bootstrap/Spinner"; -import ListGroup from "react-bootstrap/ListGroup"; -import {Link} from 'react-router-dom'; -import * as dateformat from 'dateformat'; -import Alert from "react-bootstrap/Alert"; - -interface Props { - nodeStore?: NodeStore; - explorerStore?: ExplorerStore; - match?: { - params: { - hash: string, - } - } -} - -@inject("nodeStore") -@inject("explorerStore") -@observer -export class ExplorerAddressQueryResult extends React.Component<Props, any> { - - componentDidMount() { - this.props.explorerStore.resetSearch(); - this.props.explorerStore.searchAddress(this.props.match.params.hash); - } - - getSnapshotBeforeUpdate(prevProps: Props, prevState) { - if (prevProps.match.params.hash !== this.props.match.params.hash) { - this.props.explorerStore.searchAddress(this.props.match.params.hash); - } - return null; - } - - render() { - let {hash} = this.props.match.params; - let {addr, query_loading} = this.props.explorerStore; - let txsEle = []; - if (addr) { - for (let i = 0; i < addr.txs.length; i++) { - let tx = addr.txs[i]; - txsEle.push( - <ListGroup.Item key={tx.hash}> - <small> - {dateformat(new Date(tx.timestamp * 1000), "dd.mm.yyyy HH:MM:ss")} {' '} - <Link to={`/explorer/tx/${tx.hash}`}>{tx.hash}</Link> - </small> - </ListGroup.Item> - ); - } - } - return ( - <Container> - <h3>Address {addr !== null && <span>({addr.txs.length} Transactions)</span>}</h3> - <p> - {hash} {' '} - </p> - { - addr !== null ? - <React.Fragment> - { - addr.txs !== null && addr.txs.length === 100 && - <Alert variant={"warning"}> - Max. 100 transactions are shown. - </Alert> - } - <Row className={"mb-3"}> - <Col> - <ListGroup variant={"flush"}> - {txsEle} - </ListGroup> - </Col> - </Row> - </React.Fragment> - : - <Row className={"mb-3"}> - <Col> - {query_loading && <Spinner animation="border"/>} - </Col> - </Row> - } - - </Container> - ); - } -} diff --git a/plugins/spa/frontend/src/app/components/ExplorerTransactionQueryResult.tsx b/plugins/spa/frontend/src/app/components/ExplorerTransactionQueryResult.tsx deleted file mode 100644 index fe54c2e0611b6dd41aaec20bb353bb56ad984c88..0000000000000000000000000000000000000000 --- a/plugins/spa/frontend/src/app/components/ExplorerTransactionQueryResult.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import * as React from 'react'; -import Container from "react-bootstrap/Container"; -import Row from "react-bootstrap/Row"; -import Col from "react-bootstrap/Col"; -import NodeStore from "app/stores/NodeStore"; -import {inject, observer} from "mobx-react"; -import ExplorerStore from "app/stores/ExplorerStore"; -import Spinner from "react-bootstrap/Spinner"; -import ListGroup from "react-bootstrap/ListGroup"; -import Badge from "react-bootstrap/Badge"; -import * as dateformat from 'dateformat'; -import {Link} from 'react-router-dom'; - -interface Props { - nodeStore?: NodeStore; - explorerStore?: ExplorerStore; - match?: { - params: { - hash: string, - } - } -} - -@inject("nodeStore") -@inject("explorerStore") -@observer -export class ExplorerTransactionQueryResult extends React.Component<Props, any> { - - componentDidMount() { - this.props.explorerStore.resetSearch(); - this.props.explorerStore.searchTx(this.props.match.params.hash); - } - - getSnapshotBeforeUpdate(prevProps: Props, prevState) { - if (prevProps.match.params.hash !== this.props.match.params.hash) { - this.props.explorerStore.searchTx(this.props.match.params.hash); - } - return null; - } - - render() { - let {hash} = this.props.match.params; - let {tx, query_loading} = this.props.explorerStore; - return ( - <Container> - <h3> - Transaction - </h3> - <p> - {hash} {' '} - { - tx && - <React.Fragment> - <br/> - <span> - <Badge variant="light"> - Time: {dateformat(new Date(tx.timestamp * 1000), "dd.mm.yyyy HH:MM:ss")} - </Badge> - </span> - </React.Fragment> - } - </p> - { - tx && - <React.Fragment> - <Row className={"mb-3"}> - <Col> - <ListGroup> - <ListGroup.Item>Value: {tx.value}i</ListGroup.Item> - </ListGroup> - </Col> - <Col> - <ListGroup> - <ListGroup.Item>Solid: {tx.solid ? 'Yes' : 'No'}</ListGroup.Item> - </ListGroup> - </Col> - </Row> - <Row className={"mb-3"}> - <Col> - <ListGroup> - <ListGroup.Item className="text-break"> - Trunk: {' '} - <Link to={`/explorer/tx/${tx.trunk}`}> - {tx.trunk} - </Link> - </ListGroup.Item> - </ListGroup> - </Col> - <Col> - <ListGroup> - <ListGroup.Item className="text-break"> - Branch: {' '} - <Link to={`/explorer/tx/${tx.branch}`}> - {tx.branch} - </Link> - </ListGroup.Item> - </ListGroup> - </Col> - </Row> - <Row className={"mb-3"}> - <Col> - <ListGroup> - <ListGroup.Item> - Address: {' '} - <Link to={`/explorer/addr/${tx.address}`}> - {tx.address} - </Link> - </ListGroup.Item> - <ListGroup.Item className="text-break"> - Message:<br/> - <small> - {tx.signature_message_fragment} - </small> - </ListGroup.Item> - </ListGroup> - </Col> - </Row> - </React.Fragment> - } - <Row className={"mb-3"}> - <Col> - {query_loading && <Spinner animation="border"/>} - </Col> - </Row> - </Container> - ); - } -} diff --git a/plugins/spa/livefeed.go b/plugins/spa/livefeed.go deleted file mode 100644 index 159cb4cb8ddbeb4922741a6359d1d391d4ee4a49..0000000000000000000000000000000000000000 --- a/plugins/spa/livefeed.go +++ /dev/null @@ -1,46 +0,0 @@ -package spa - -import ( - "time" - - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/shutdown" - tangle_plugin "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/workerpool" -) - -var liveFeedWorkerCount = 1 -var liveFeedWorkerQueueSize = 50 -var liveFeedWorkerPool *workerpool.WorkerPool - -func configureLiveFeed() { - liveFeedWorkerPool = workerpool.New(func(task workerpool.Task) { - t := task.Param(0).(*value_transaction.ValueTransaction) - sendToAllWSClient(&msg{MsgTypeTx, &tx{t.GetHash(), t.GetValue()}}) - task.Return(nil) - }, workerpool.WorkerCount(liveFeedWorkerCount), workerpool.QueueSize(liveFeedWorkerQueueSize)) -} - -func runLiveFeed() { - newTxRateLimiter := time.NewTicker(time.Second / 10) - notifyNewTx := events.NewClosure(func(tx *value_transaction.ValueTransaction) { - select { - case <-newTxRateLimiter.C: - liveFeedWorkerPool.TrySubmit(tx) - default: - } - }) - - daemon.BackgroundWorker("SPA[TxUpdater]", func(shutdownSignal <-chan struct{}) { - tangle_plugin.Events.TransactionStored.Attach(notifyNewTx) - liveFeedWorkerPool.Start() - <-shutdownSignal - log.Info("Stopping SPA[TxUpdater] ...") - tangle_plugin.Events.TransactionStored.Detach(notifyNewTx) - newTxRateLimiter.Stop() - liveFeedWorkerPool.Stop() - log.Info("Stopping SPA[TxUpdater] ... done") - }, shutdown.ShutdownPrioritySPA) -} diff --git a/plugins/spa/packrd/packed-packr.go b/plugins/spa/packrd/packed-packr.go deleted file mode 100644 index 6dd94111cb1b3deaef66dd98289504d098bea781..0000000000000000000000000000000000000000 --- a/plugins/spa/packrd/packed-packr.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build !skippackr -// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT. - -// You can use the "packr2 clean" command to clean up this, -// and any other packr generated files. -package packrd - -import ( - "github.com/gobuffalo/packr/v2" - "github.com/gobuffalo/packr/v2/file/resolver" -) - -var _ = func() error { - const gk = "7960f7a7c6691afb5f07d4c30819cea6" - g := packr.New(gk, "") - hgr, err := resolver.NewHexGzip(map[string]string{ - "0a565b7e0dc999e762aac08b16b48d84": "1f8b08000000000000ff9c92418fd3301085effd15c657b471d2b86982925c5809b452b5ea52c4c26d624f1a9738b6ecd9d0fc7b5465018913e264f9bda7eff069ea37da295a3cb281ecd86eea5f0f826e378c31565b24606a8010911afe42fd5dc95f2b323462fbc17d1a8cb518d83dc4a17310742dd66a9d8d66face028e0d8fb48c180744e26c08d8377c20f2f19d1016ae4a4f49e71c450ae06f1fe5acf81d0899e44926548c7fb2c49a295131726626c27330b4343c0e9097f2ee7c7e5c9e52f3fcbe3b1ce7fcd9780bb93cdcbfd51f45d61ff7a51497427d15e6e174fcfc38a82f617fad1e66f7743d6d0fdf7e6427ce547031ba60ce666a384c6e5aac7b89bcddd462d553774e2feda6d6666646373c3847bcad853673bba9a30ac613bbc96d38e195c405665853ce62500d17e0bdd8eba2ca53c8940459642835ecd2e4126fa075dcfe336ac649bb90547297ab1eaba2daeed26d9e2274e57f12c1fb24dfef649697b204595565da635ae8bf70e2d58458cfe767000000ffff6e2b03a356020000", - "27369919a4954e44d1e4636e64316459": "1f8b08000000000000ffecbd0b5bdbb8d238fe5574f23fef42df9a84708742cf2b3b2184702904ca7697fd739c442486c4766d2724f4e1bbff1ecdc8b27c0b09d06ef79ccd3e5b92d168349246a399d1d8fa561831cfb71cbbb0b3aa157c67e8b5995fd8f9bdf0c05aaed9bedf29954ac562c9763aec66e074867de69706ce80d941a9efb4cd3e23fec46e93fffffaba787d5d2afeef3f0b5aac6ac974dd52db19b88ecdecc02f5dba813560c5c01f3f83f819d9cac31c587ebb64f44c2f2806fe33a42e3e3543cce75a3d668359512ba6df6b39a6d79901b73a76fb8ec7bc2633bd76af657a73d439b2466c9fb1799a9901f5c41cbd86a90bcfb47db31d588e7d3664dee49cf9c3fe2ca31612a09d8ec77c7fee7a6bcb6bb3f48e59dd5ecb99692004aa3f03eeb9e3e4f24a5d77aaac5e357304d50f1c8ff9a513a7c39afceb743439690235d5e0c0b470d1fca1156c73808b7960ba119ee1d8011b0705ade0b1af05ad60755265e7cc77fa2356d00a3737a2e4c6635f8796c76e6e0a5ac12968055e5af53cc72b6885b6d3e13fefd984f37edaba636da41f9241d5c16b8d5dc7831e063d8bff713dc7e57fedb0ff05ad30042551d00a7e6006435e1a2a29add061b7e6b01fc02a3d75b900f272d6675c27f1af7dcbe65503668b1aa66d0dcc40d41e7ae1d79e33629e5a5c89ca3ce6bb8eed5b2346334a790b89f64ddfb7babccce73a9143c6740c7f03ab7d0f18c3c069de5b7c1e06e6f882438fac81c587e9d6b183a6f508e364d9e74e10363430c7caafae67758e2c1ba8762cdfed9b938256988876da66bfdf32dbf77cb0ccfe9013b3ec0e1b87bf39ceb119f4382b2dfea3c5ba964d83df98c76733709c7e60b92a25184cb3c5fa51713d6003deba1998e28fcf60d0c5d7ba68d1303d2e54bad3e12c5e5801cc7ddff4839bc0f56f062cf0ac36270b0df6f8120cf067937916f0eac8b1f57bcec3af479c1194171604135f0c17b0d363a67b63d9439fc91f9dbefceeb13e337dc6f919dcf8ae694bd4c14ddb6cf798fced075cce7d90617b38b8e9b643a65d73e833fc0d341d90701f39902cf3c5635a3648d5b9f3c087b26ffafe8909b26c387c208f2c3fa879ced08579f12cd3e61d17e33a743b66c0501fe35a89d63a1f1ed3ebb2000a587ba820de333ecc3efca476f45d7eb1ec2e6fc57687b2f17dc71b70863d60cbed9b6dd673fa1d60deb18d9e6977197c6db0c9a58b2267b6fa308ec1d80f77252ee9bcef17bc8c0f8fc76e05759040b11a4d580a1397e1e2624133cee0c518c43d00906b7ae60004c3f47b38e5a34f424df0efcdc00c603c78a5af7cfbb9e93b66073ba99b1d609c8fe4ade30d4c3e601551c11a303f3007bc3bbed307c51780f47b439baf9c9667dac08289db13c7b3bab6190c3d763360be6f76d9cdad6776b9b2296885a66bd938df62f065354e0047aa0ae362e10f2e50cceec2327487d03bda671ea7658b8de8181687af40c47ae1209c7fabc3ecc00a26423cb9a00d3d0f596a3bb6cd6063be713cab6b71cde15a7d3ec9ad49c0fc9b07cf0a0266cbdf1e333b11851316d44ff9248d8181a07e2ac53b6447f4e8d6f1aa260cd6888b60d474412b9c98a396e9a1089b3627df82b9f1f0c7893982a500636e38fdbee9c202bcc06de981b57ca77dcf0203098294b1b109a45dd4617257e6df7b56bfe33154dc7687791536ba7040aea9cbe7ba67f1dd930fd755f3d8ef5ea01cf64cbbd3679e0fd5ba961f30ef00415c1611ad5e891039839f9ac7a1ee6a867bd3311b38de249ab6b6d3ef875cdb2c7870bcfb1bcb015d11aa3ddcf01e50c58b9a1533303f39166e627ecfba0dc21900f16a3b76e7484c36df7b705a4e5d440fe7a81faa49ea79b03ddce2d4f36578217744aeddbb9e33b43b86d3870dbce5781de65d591d185cfc152f334cb7194c60e61150c1c519fd38bdbdf5413c1174e8587658c3e5fdd2635411946244c10cb901d001dfad73d0b12c4d5d81c7689d9b1d0b660eb1ac24805793201bb5773b1c8c6ed8849c66654b8b4dffcd800d14382af72bd66aa664bbad7c177b40285cf8f324a51b10de91cb322a313b1d29a3381f96ddee0f3b6837b03e0b98accf054a95e9c0f5e57709e7f54206385fb03bdba72e2c38c736fa8e8f3b45680df61d5effc1b23b20e2dc4f1426ccd0b3d0e40b9c36accf9e0312fdc069caa101624e48bf2de93341dfb1852ac6755ad00a87cdd313dc387c168da74ab003aba1e70c3db4b286300ab8ac78e3b77d0768fb81273679dac77ef0ef75c5b8a847b6c579645a80ed10564113022c05fc0a3e52383c9e330ca24dbd6f068c9b45b037e066c6bc6847b9f1c0434a1807b8d57930a5b70c774d8978e7e3582bf8e7611992c6a2185303abcffcc0b159bcf848eeab274eb0cf579e2c872d1bbf46db1eecedb0bbc29ec6adc416884048c6ec7442d30108dc5a7627b41a790d04a261e10f5b381de8fbc0feec3cf8cc3b90fabce3b487622feeb2a08a5e803ea977b8fb33305dd7b2bb7e61a7b051a5946a754aeb54ab527aac19d4b8d04e293dd36ad438d72e29bde2df7ecd849994b6f9b7ce0f86cdcadf7f11ac2ec7aa2ec72a0b16d5adc7eb66c1e6a2fc9d61b3f23c2be559e9bd35eccfe22f6aa3ab536ae9fcfb9dfe43bafc9ae99c7508fface9fc1bf673cdd1acedbeb58af999c67e3aec0ba526ffd6d218a55dd0033dfd0773734669937fbbd0ae28fdc2bffdf62a6d322bbd2cbc0896a32223d4b751642f998039b4f70b37d906addf6a4d4a9b06370499c12d85910ea621401af0afafeff38212347d5ae3200740d5753daa2db0b6b1bac08292ea09d0aa6a35616cba06e03438b82e5a3be665439dd2897e8256698356ef2ada31ad5040ac56b506a5a7da40a7c6c1be56a5d54fc0cf27a0c289577fab40379a8878450d0f5936e0df0a07373e6b755a75913176c505e1f25cab52e3516f72d0a901a01607dde9601f3360bca135b441dd783c73a1835f755ee4e95a9b52c7d0be50a367684d6ad4b553fe0f9f30830b515b6b6897d438f8028d63370d3e0d97fcdfc3b1ae55b5c125ef6e95ee97752e27a79a498d4f5a831a8eae5d19bc9144835fa1c1bbdc06afa8b17f906ab02ac6e28a1ef60cd1ec296f7635a359adab1be79fc5c4f239dbd47973f4927f3f31387198ca7d235c4bb53bdd40f932a8f14920d768b5033c9c72e881a1ddeb940e740e1fe986b6a653baa16b35cdbf340eee4266ab1cc5c6a973f00faf6d1b06cabe418d4349941af1dfbc11de5b3e819f0d3e5a8c7fbd150c21145663951a2df1b546ab69eeb91841a7e22deda7d06ab4dafa14b5dfc4969a30c72852f82fae0e9c049c1c2efa8728909fc201333e5722ae4dbe4e4ded98d61fe3e3aff0000dcbd64cde4eb5ac23b8462b0d2a5632e795af1bfaa5c61b681f72f1b9338e145e60a17de14ab1ee55467c9aea0749e1f341f8fa29e173a0798a6bba418d0a82a98436a0d75076826595a8accaf96d685d83eba60d5d3ba3c6e5ba9192e115036a767543e3846a2543483ee71ee6c8089d245a3f07291da5a96ce1f8a1e8f6f99fcfbd2a6783d7db5fcf5a0efe6763c4d5c9312ed53f454097f5f087d17ad47f9cb43a30fb57b61e93da06ad96f4f314ffa7b41ee8e6f711d5769a8f5062dbb4deabce24b1bcd616b47fec56729464b7c237c9c050c4fbf31b48774363d43806b3e214ba026cd4618edb15b18f5d52fa05fa5eaf715bc1d20fe0479d6b027608df1b302847f0fd58fb42abbd03be66dad4e8e2e6593fd54e354be7ba1bb7c7335e839b1d7c6819fc31fa55fc4bcf01a5a981b279d03fc759e33c8f8c7d0598e0914bc2766a1d9e47c18adc75b85601e168e1167246ef74b73275191a7706ee867c71d016efd47b8e66acea4975d496a3dfc439191a7cbaa02cd25435a1334046cfb8b9974268c86a63fd4d64a049e959866a43c9eb819517aab5b56a2623d95043e931f60a86b5099666829bcb6ac8290d670e6cae26ad9504f2c1776ae4546bd333578cddd17c33a1d239d3ce68b52f1add7f0d9d2bbaad7ba121c6adc07d2f217b5fb49ab6a11b95565cf686b0724786d6d61c9d56a1a714166a57dfaec23a3f53e6d9afc2baadc09ebe0d9358edeec3b4aff271acd9a08fe81aec0a967eb7cf4940573e03ebd5fb7d90ad72354d95375bdbd4231dc7e91a625a2f29ad72654bcdcd54d5aa67a44d48be0bc3ef4f2f5b2a5f2221806a2ddcf2cea811ce58b43e61733887a1fca2bdd729ddd2f9c097f4f007b7f8c73ad74377ba5d81dde23d4e1d2ca6cbbb7de8935fe5d5b6f52fb8ad2370c2bb687470833bd12ee9a3be194eb5c5d7f3c1a63ad7f0cdd295693753b39ede4e783583ef6094b9fbc9f145bf291cdf178ee79ba89e7b5d4eaba3cfc3074700a31dbc35e3485bced2a50ddef8beb6a1f3b2659d77f91ef0be1ab4760870635ffb425d7d3d9c812eccc0fad41930f613e3bf051abf9cd2f89e9e54f91baf51f96b357a7a1ea9098b9b29527a39a40b903b9d6fbdc30a351e2ada579dd2da571dbda3894ee950d72c1d76b6d57dd1e733ae60dc0c05631a46a2a7cbb028ca71fd72a7ffc5148c115330962ac97207019bda3050c44eb9be00e45f134a02bd68e8d0e7f4d25fd52f51890c61e455556194314872c9f5dbd5bd2ed44195afce46425f0c746a47fb01ac94839e315549ac19c66562ee9c0a1866153e7346fd316340bf82c5f6a8afa754066dfb1858d9548b36f685b5801ee431ad6d57b4079d9b6c300bf73a1fbf3a58ad077558fe9707b12aa794367bb569248d712586300f3bd51197aedaaf8a84344047d5283dcb6ef60cd6718df20a5cfc7863284796eea6f8880bd27972b54f0c5aa37cd5190dcbd0f8eaa0a7dcb73eac712b94a6f6b71550546bbaa45855541997cc3b10cd330dcc9ba37b03e510c3550d908c3aa5b76092d71a9cf040e7444f7bd5a3ec16e1b7fd42ebd348f637b103486b8b936b6ec132ab0555ed583ba5355b183c5fdf90f6319f9933fca749eb23b1273d7ee7fe719287b896dbda25353a180bc5b13e0d3126429760b40076dd1a67d318ebe7e2c7256db87a06cfaf64e98a821a372e6661a9c97b30d62fc48f2ff4782c585affee62f285db0875eed92618fd2a18bdd7b9524146b9e234cae81bd62eb54b5a135c948d6787a3034bed1c2c80062ea3da956619f4ac27c4727bdece1af7424b60e9952cc5d08757c3e6bb3a2dedf72a429583dc1e94a7ab72d3a0094dde054dbe6ea026ff3c9f229fc056dbee1d4c55e476f50729f299d8a9aebf509173ac7b1db776aec95bb99adc36560c94d11a5f2e5cdc783f0d484b69409b55a4c3671cad05f0f11a35a1804f293ddb476c0342351cdc83c61b6d05b3c25be8eb308aa7601f1f083d9c7654b9e840e38d09aa383eea86aba3e41ecfa2ff87009c8017ef56932bab9ad60007607dd4c4f7263ddeac289bdc5d6a392fc3d9940f91b98bfb8a58056bd0ec198d0f11784e2503f744b068604f6cd01af07401b658d2f3abf20d83b642520d38df38a6d4c54094a47e06f1c1cc8dd3ae6054e08affe318b4be29100f5fafd3e24187db2dcedbf19da0dfaf7c373df25819877a6419f44830558f189f125ac4e2e8d594fd7c0f2271b95ecd5e90464f35797a2969b02a7c9026e8237fd54dcea141cfe5b112efd0c168ba87bb7cc95dac28b0dddbff3bb0fdf306b6f3fc605ee7fe00b78f71faf06f7800f1604b47ea651563f9805b21a32a0ed021fab6dc2b3256d5d0c5e6bc8beb4dc3a65c6097b91eebe23e3086f39f4e469cf4f58a85ffe38b7847931aa1f61ae9990671f53357f6745811fc7ed5693d8c13ac57be57bbdc7a134dde6a5f68230cdb6ece6f372a6192819150e5cb20c4b00d1bab15e10f51e3964b0cbdc3f53381d16fd4350651e0636ad0cdaa5ad2d04c5a8573f370f2d7f559dbf912b5f3b58aa2798987199fc35f26a56609a88fabd07aaff22c3e17b9ea6635796ae1ee278f0fad7dacf6055494bd8f33f585f62a1e94c059454638c7d84c4673e22715bc49072830beb6e134f1807af5fc956be2a818e114d6781f8c6d0cd49bb7181a51c2da067a11dc9cd98201a9b5404599dc210c0f6c1eab1906864929f3a1c0ec81a66c620684b032206a87457cb84b156da5426b4697abafdf0e9f89a31bed64900b862500f135ceb42a3d3e474b3b6b2ceadcf37854437f439d2b832aee3ca6f4b22751bf8ea373e15341b1c6659f8fe6b88a83caff39900b25a8a4889cd6a2186a2b3ba4b8590d234c2113f0afa9387f350846a7cfcb85021ce8dc664e56f55e5fd59c567559a78dd0808ace634e8fe1a00ac89444cf863a282329630e2c764f4f8fd629923ea6c6c9dd616a1abb8730c3a3b4ca8a075e205afaa0d386ad1c2f1e2b367c68ff53e33d1c9fc1a669e0d99a58e661c653d94856d97f831a5f754abfea519d7ee5f93a189d8ceab833d409bdc3b08e37439d2f947e896a3c2abdc1595d15c2d1d569b5a7975527ed2bd825bf063875c3432e5e77950bb1b4eb10114d19954c59e49e7e22e61b72beda42b5570dcc679112845a978252a55a43ab1b478f86a1d520f6f01b97c02f1413de8710ad7b0fff3271aa7078c8ab7fc1ea5a83b6bd3077ad4621edbd7a2ef2d36a983302f62d588025e380039b607e9b8656d5565a460b4db6633e480da50327dc0ac3e8fb7a4d6417f07636f88fda2656e2aeeb57d1edb012ea44ded74b4a07d0b06d08c815ec08355a5d0df3c16ad438a1d248a58d126e63389def319acd75a56d040d80dd433c2ecc93d9020a3ddd8d156e62b4e01e423d637d142b3cd6ce68d55612fece1e45799d4f6c6bc847c2a80be0009cdcab6d95e26348511472b3b1eaeae3187013191cf01adc176ca3f6a6a78f316efa598c6b355aeb57c063c14d7384dbeeb69e855c85e4c24684c6ab435ae869bc825be72565749c8099ba40d8e05e38bdda440b79b981112cee518cd07db76b211e575235342e7af5089d5e95b9fb63dc556a58a1ae56a8730cf32e86ffc8c5c1d8e6da995710131f851ace3493d6d6397ff55f610baa0b5f85abcc512de6af71022b8798c909e44ef1386a082a445bd169d51301cfc6a83e53d5af9049c2abd66c438ddbc8604d19b357b4285a631fa4654609d86ca2d16555701f7163f2d283a0cdd858c6a8cda812ca37ae8d3a356cbd0fbb4d6d1dcbde5755943b381a73f52eda49222ef71e5c89e31087d3e1a6847418979147cebe71eed5434f8f1a2bd8b92e9f8af5caaf9cf15fb5b6c8af5931b433cd82b435053ed4a976a6dd1b74c2dd9f3aad18da17cddfa79671044c80f2b987c44a570feac8c415a55faa38e235beb21eeaa157cebd4dc573ee623af0834e0dee18277d6a5f87ef98687cca558281f9cc356afc66007f10a533fabaa47586a44419a7c00bc5c49f72fb2c597159a7740551577583ffa543fc398a7e56f197c221725543ae04c51aad0578c2e482f7738ad95b6d252bf95109336c1fc2f73510ffe3f2a11c325b5fae8b0e219f773a6e532678f2adcfa2c14becc327d18753fe73553f09991eeab45ee282513df6801f08ea55033dd4ed67dc2dff048791d486e3480b75e81a2c1e0f957e871b3918743650b7500f765bbaa187ee7a0d8c1d5ef415c76c197a5b0e37090e42bdbe8da0f52af4618014f8f7ae2eb6948d2a1c39afe1d21deaa3635478b07bd3affa572ec6353c9fa5061e22bb988d86bb0e64bdd1ba7530dbeef3f518d8f345c0486c08ae314a146f72e9aa96c23d41c24bb866fb0761e30d6a8c0c9193078aa9c9f77eee4bc30061bd8938b5165bfd3da8f94b7c5850aa2354feaa3a6aa01777304d0d35d7c5b9fe91587f40c53256712027f110ca32ea91de11a4e5578727e0de52a480b353a7d531e690b7718f1fc3548e437527293ac051fd5192e49a787802c284c190339158b2a5b45a03d5421b20960eda6ae37a9cf236efb1b1a9bf87e0de1968b56600fab1af27917d8cfc8d78f1f1234ad54315c478a8f71ba87881d30186a7e07b1fb4b5abdfe349850d53700c6ab4a723223751a6c95410cad4062aa47bdde1f50c5bbf3b01b8a3084d86acc9e2f5b8ac49f836cada0a1fe751a5c7ed673009f721fa0a11efb31ed679e0e6aa3132d60d15e5a1022ab48fec744fb86a3456b9b42a4813ccdcb61169027b2e375eae2aa57a8d8ffcb2eec108b4bb986e8c7b2908c57a25b2c2e4594c135426f8b0c7b47ac559b893f9a057d438ac60e119ad7ea672c33e3d1022cfbf8f794bd5479c36118f112d71893cc4547c3c7fc0b1fd958ffc6ff034440dbce44b80b4ce005297906a0b92586b605099e5537c5c86935e8102be502297621360d5f77038b5ad0f81c74b34c21ff0ac670c0e63a00fb89d553b82857386419cfafa91766aac1cfcf6fe4833a8ad83e7e9e8902d498f03f4ebfd6350e813d85ef01993e3e078f6a23abdafac83000afb6a8c3b4cbf9263258d432b09e458ec1ecb3aad79735a4909f15614d4b892652749fc3b78e6c6ae4cb39446280e9f320ca580371f3382de1fe418417ca368d8b8c1d7c3c076fd57ee26e0604d2076d0080538146f63841af0b28cc3bd026903c7aba7919a3fada0f1dee01b9f0f72d27c8c61a366e1ddd9d641ce1d9c481d34f4e93886bc8f435fe77b3a1576169c0142c1f128868c9b0ffa4680dc965b49bd8e8bab4637f4cfda295dd7b94b493f81c2a70d98f9234da43f555b22d654a7c649acec8a565b202667908cc2fd8e0a3dc4666be2c4f398866c083a7048d747f1e2fdae9ed4a0de8114abfda81eef6bf556c6f06aae2e1ce03aad7eaa42bd68973c90f5aa27b0bd9ef30556ff55117b98bc2f779f72a47e3b947a78842c92faeaba710f8bf54bffd9aa70b8a254dd34061831b6f3aa6e8655c196549c9975c381aacccdab7a6788aac2d6552af72aa85f4c2faf7229c6b25275dbc010e9719057759c53b5b63da77a48585a79eaa1e9262cacfefef37e14eade4ba10ce3eae17d55bbe4ab0824f972948552aa61507b19709ae32c9ced1a268f208ef99885b359d318970fc4b92a67e19481cebafe804f3eac66e16c55931acdabe668b46530891a479a7cb201ffc533bc36dfbc468d724575eb065ce136b42d486711f0af556a5ca9486b7a456bc0e30677ba0abf37987606872da3049ca6e0f755dad52be8385e6acb555a973fb62af44afe1856a91fe17dad52b3127a9bce3e7574f96b799f6b51f1c3daa72b868af8605c72ca816e6c9edf8270f9902b70c447ab0111b80a97dc0a04dc1a1070bbd41ab47e1eba4403fd42041c6bf44ea7518ceb01dcbb31daf0f6a1d0c70d48a5e5a036ffd7e7dfb90fc821f0882c2460188f0819403691a5e34930805643b7ab06c30c59ad0d712ada90fed62ac413c09b6c0a3f0bce8dc170e5fe30adc02367b6be8a5234f90453821e2ab81852279e41efa0bb8c52b68afbe91a2c91c0e81e71840d3d7c2ae6945bee9b88b3f5093cb0013e202b8e852129f1a88418dd336181f39db02198b721840ba9839f4508e3e193788ea7c1b91b63e58d6ae8ddd785e7691d4183bebe8f76fefaa7586dae610c2f8486d5aba1bcd68533540d3b780a34949fa8b93e0b10926d7b87e8828bf0d857880a7f29a10613292fe0d7d602235e1392e06cfdee2cbf627090ac402fef1a90d25c151949a26c951ba886ad6f66b281296dc8c67ac846020767a2cce7babe8a427382de323acbf191505dd40d6477a0af37d00517c9d01bf8c4146cbaab9882dd8578c7bd5e13e9275214b775d19ffb3370bc20ef1e83484214cf5551bca2f46a95bb7ec61d6c360390aedb657c500cb6a6eaa1f6054c8e98a4fd062602d32eb9b58ac9539008fda00f0f2319ee8532ec9c81e778d7c0d04d1880c99361114ca52548041b72433dd14fdb98ab9f26a526f6d37e6d3ffb879cf09a3ea947fd74c37e7e8527e5da6e18c8e1fddcaa3fbb564f310db6418dc300c57850134f8d53e3b35812c34fa87b8ee5426d631ebe7b08af0650b2b78ed55cab01762976f25b97496dd51e38605f2c7c4afe0e7f61e3356e1e8db1750bc4fb14f6c1dfee0e621c71f1d14762a66b32465717fab70bcfd97cb98308c0b9e88de820d04bf6f0197a5b87423fc141fb57bd7c1662827ef2794f6a3d0c5461cc0e7732a3a78b49100d9da1d62a255a02f526b20ed3da71eb08471d6204550c7a3d56440ffc4fb0a47c5d3c215c0b8decea26c459cec24cbd33eeacf46295eeb8ea29d57fd5eab47b78e41da865dbd5d8c188808a530348fc191f3cc675679b6208e4715f8d3138e032d7b771c856ce3446d70e4686722a5097bec5af916db97ea81a9411c3e2d484d6f65162d0f60ccdcb7e454dab8c0f915dc7281986611b8f8798dbc32dcfba483b50b328cfc52341898cc8cbec8c4863ac87030d6bee086d6b386b3fa6b5551d73813691e1a0aa3521999b23dd7fd26ab48759545138feae86f1f8da6f0a7c6c54b975a5d389d154c0dbfa9176a9ade9d432bad222ebaa66de4a85d6e48f874adc00ec19bcfa5723567dad42bf4686da46853bbde28713b3e1b62ad250bbd4ac2abd3722634fadf55e3503972bf44ca517598bf755a5e47d857ea928a71143fd52bb34dce35b7968d9c6c025e3ce272ef0a606671b5f304f05127f0e05568d36fabad6a687f77a080073e5b46f8459956d302ac089ed1a7ca9539465ad4e6b5e05d3389463693e578d58527a3dccdf181fc897b6b4c224b15a94e30465a7dc865c3e1067bedc4ad3aef0b59facb053305db7b8bab9be565edd5adb32d7b6b7b7966fd9f246a778076f0dc5b7fdc33bbfeda0b0f37b61647a6460ba648f7cbbb6af83eb42b164de5e1776c8e69616018a777e12e601605b012c751e396c6b390e1375e3e0fb078095e3b0103506ee4f00b6128785a831f0c004d86a1c16a2c6c03ea2aec561216a0c1cd8005b8fc34254151c0e93322a38241b0a20ac18c15a0c009b0a204452605d006c29801049810d00b0ad0042240506fdd95e56000249853900282b8010498181106caf288010498121605501844811ac0dd3b1bda60042240586807505102229b0110036144088a4c040a6b63715408814c13ac8d3960208911418ccddf6b6025832030e2b2f2fc781a27202deee21b01c074a64151e36afb43642ac150522ab4640d647c8aa0291680ad05e6ad610b816074ae418dc1c22703d0e94c831384e717979230e94c83178b785c0cd385022c7e01643e0561c2891e3703114db71a0448ec16d58bee5f2721c1822ab700721650522d114a0802853e32f7544ddd53850568fc18702b816074a64152e814a73289b65656aa460aa409cd9b23229725a15e02dce697953814834056821644b8148340528c6615b81483405085aa7bcb2ac4042e95a29c78161f5041cd7dcca4a1c289155b8042acd4d10b2aa40245a04ec0a96d614884453801d84ac2b1089a600516e57361488445380ce60a96fe296555ed94cc16515a508e77a654b8148b408d8c355b6b2ad40249a02c4b95e5d5620219a0ac4495c2d2b1089a60091b7d5150522d114e064c91c2070350e94c811dcc2015f5d5320124d010ac8ba0291680a1017d4ea860209056c75330e94d555b8044614ee507256b71488445380a8fc57b71588448b80f7486d6d598184682af01e21650522d114208ef3da8a0291680a1025706d5581483405884b7e6d4d814834058862b0b6ae40249a02c485b9b6a140245a04ece3e6b2b6a940249a0214bc6d291089a6005100d6b615884453803859ebcb0a24445380035c65eb650522d11420aeb2f5150522d11420cee9faaa0291680a1075cbfa9a0291680a10e7747d5d81483405884b7b7d438148340528209b0a64698033b8be1507caea2a5c02150a3817ebdb0a44a229406c65431976d98402b4514e36ca0a44a229409cb28d150522d114200ef2c6aa02596a89ba6b71a0acaec22550a18033b2b1ae40245a0474cd254b606ec4811259810b3e37158844538038d41b5b0a64091d82f2c6761c28abab70098c2878b8e23697154888a602511b6c961588448b803eeaf9cd150522d114204ec1e6aa0291680a1057dce69a0291680a1057dce6ba0291680a100779734381483405f815219b0a44a229401c76c53df7bda5f6c4138d6c27c192845a22810a158428aebb2f579d0a44d5a6b8edbe546d2af00121cad03f48b40818e076a5b8eb81dcae54204e9be2aa0772da62409453c54f0f228b57857611b2a140249a02c49d5d71cc03b9adabc0fe922b30b7e24089acc205eab60a92880a14e75971d303396d2af011275ef1d4834739e931286ee68ab71e3c2af6a3e2a0877049255624a111a16177a92da8acc581125981e3aa51dcf8a15c352a50f47f4381483405885e9be2ca0f1f954e6d25c192845a2281119511aa00c5fd1e4915a000c74baecf86e8d4ad28ce7e081755d4a289402e2b108916011f7b624c5714df1e80123906efdd2370350e94c83178f080c0b5385022af5ddb4f1fae6dfedfedd086fba648fc0ec1458f7d7d8771c491e911ab43f648e62d8380c869051e0b869e4d32ee1c5cb43a1ce529b7359516366add2efe238352d1591c98ae4638a2c0440619d923367b207023cae275c1306ddb09c8ad6577085e5f4816ae0be43daf49de93ebc2c27501d9be0e58b1ed74388185e3d3cae551f5e6e4f4e266fff4f2a4b22030829ee73c1006bf9e94be0e4cf7778f7dfd033b17ef53f19e4d7cb24772badc60137f51744150c39b17a11eef250cd9871459712d63de7c7cb8b6b1bf457159630a314d1266776575f343412b58035e8bfc2f317d72cecc76406e3d6740163cfe7de1c3b5776d0b1479e725625c17b2eec3bc2ea855be5936efa2469c96cfbc11f39ec2ba03a7355e8236440da86507ccbb35db8cc00572e41b07124288bc6ef25f3b111b50ed29acfb7fd8d4e2757437e575e11d94848df31f384844dc4b49e0ca3f82d7dc12360e98dd11c35034c23bcb7681198d98f6e463c412de5d06332a200885995d5461fcb38b34f7c565741f93e5fc23b8f816f42cbf08176d1665578a78c9e6538a6e690ae1771fc25f4f72a8fe9e719871715ff19f3de5211bd9738ef7a916c56daa6f32f7fc4fa944c23bc6085c4e47c4ed9d24707889c74c9f1197797021a3dd661a694d085e2869d95d51475ec4ea2b83cc3573c695af704225d809ef7edd898f62dfb25902c43fe25ed81db2ac96c8a178d2c26f929d0491f00a59854254092e954d54485d309b5973ca95b302ff693ee56a985e275c2950bad4729cc00f3cd32df1b2f82afbbe0b33ac7164d9ec29ce14ccfd9dbfb49240cd98f42795b7e802f0375afc6dc7f60392bcdb97ec859b2a5ef1bb2849e24dbf89b9865b7f77c8ef69b1b3daf749642920e26ae01d127843a665a1c4ae0cde215b9948e13dc279e5cae5c23b6439af9d69284f2988bc9438a76fe2a2e21d726bf67d96a2175b837fc4a84ff286f2954da6ba306d6ac2bb907722236c11ae53d608dcaeac11bc5cf95d76751269f36333e815cd968fd523653a9d37129bd672eea4a9c2b19689a45cf79c2367f1d695d9880ac25ba213a3256f8cce1845b891541d3ee52a698d74ccc0cc19bb3e0bb032d903b46278ddf4ef0a85a27af1f41f45c0cf1c5a310bfffee737c07922fffc266744a587b3f3f4ef1491a7eced02548896b545bdfbf01666c5c5a72610fdae7605df0e32ad092829ea4e6792591ca1c015df1f2f3cd3f6cd362ace4fcc234db85f73b7a4e0e4d2f10766bf9f5bcc3f179f9a3b39864de26af162e0fa4fc5dca64a515bb9385cc310bc997cefdbfaf213c8e05e76ebf2def2a7d0f0d9fb96dc489e4ad9235cca1f622c7b5b03fcbfcd2a504726ba3a5e0c4f0458f8db8480cf9f614228f7fb676e717f9b18339a1891382f26ac8d79cc8d849cacce6f93fcb7191259e39eb6297e22a3e2980ddecca8e0a33b6003b247a6451c066cf0e1879a22d3ec08bcb09f5cfa66977d5b200ba93888fa516777c00645b8d5dbb2873e23ef8902e9f4195922f2b727ae067f47de037070e3bba62d2b22a86db67b0c61ef39042e11bff127febb5c96deca96aa19c498b471f7e14ddbc3c14db7fd44168f4c3fc0225102a6956b0e7d76d36d9312292fc3e769e0bf234be4d9f13b60a6bbf33cdaefa7ad3bd1208c9f033ba6ffa491babd74e973667227e25db6220b3fe72c302d9b75f248e4cddcd31fb3189099e549e3711a7b649a65396083e72dcb3cea3f89c5e9d830fe5eaed91922c44db673e721afc6b9f310c7359c7e3ef57e1c5704c515a3b11dea3dbf8485f10a614835bb86288d57915e5b769db0f84f30b68f2c3fa879ced0cd1b2f899018e1b9fc06b9c164f73f2cfe53c2f6b805564cbfd77278a7beab631d8a76f64aecad7e947cec967aabd9587c2100d327e680ed7dbb2e0c5a4babd785a729fba0335df9e7efb229ace93b6e1a1d37263e5179aebab008acced34c7b597228664224b38c42aa42b43646a6679976c007fbb63ff47bd346fb7972456e057edc45dd52fab85b4a94ccc5645479f69128cd33143fddb8090dfb530fdc6e6916d19cb6f5a6f1f2d7772e5bf96cbc508bec865b151ffd1fd76ab841ccdfea6e295be7beda8cf9d6601350d4d511b383a73fe9845bd4d877bc01efa7976ff72828f1bad5b1db773ce6e531192bff312659dd7687d3ad9208e37536032f656a07ffb5131f90992d0b59c2e2e3f58cdd211b63a6d7eeb54c6f76fb23e47fe876cc802101b24716d93bb2f7316e90281b6f8cbda25a77911503d3ebb2a09838927afaa036c7c6ac3d8cb5b743626b21ddbc754b1659f19e4dc83ff6f6c84295cfd3c23b61267d9889511f9aa3f664318faffc70c437acac11fc6bd9dda7787882a5667c266b6e86f48bef61ac29ab23a21c127e7ecf5115c10c3b99db37dbace7f43bccdbbb2ed04ec763bebf441c8f04d1e90ee9997c739f851eb708962054f676e43acc6f7b568b755a93bdeb42cbf4adf692d9e9387679362220ef7b424c9e88631b3dd3ee32e183ab6be419cf1d3f8edd60934b57548fad9799ea63220ceb841c71817dae5eb66f1f7e761585f96666c4f7cd0cfb5e7bcb0fd98fe7f38e5fb1035f7041c96b090aff43f6c7236bc4f6197b13f71cf68460ec87349fdd0dc28af93bc13c5a7eaa867fde159fc30d575d70de59c27b3b97973dfffe95ec2919fb7bdfca2bb3fb7dbbbd8d58e2c06ea9b7317b6590f9f91cc1a0c7cce7a31ff12ad9019ce9753a1f0f4cbfb75b0ae66b2cacfc996f5273d7de2dcdc9eb6ee925e3d19a352a147e62eb6f4efee66a6cb734bb48cce6df3fefdbcfe2d74ff1e9b3d94837fb1f178aff31e9252997eb29272c9d42cc2114ed23d3e984787f62983b64e54f8e725f9876b7cf24373f34d6fd7cb84fb8b6b78e474c7450989ff0507cd29a107fe8bafd8965779f2318f498e591b6e3615277c7b2bbe0e2303f37270d582db9d373d25e12814b0975cea960526873d0a61f7c5ef42c5fda8fc41ab8989a0fc940c4f2498f9923ab3f2196edbb96c73a7c54774dd2f3d82d9fec5e10b8fe4e89ef4801484cd1f1ba7cf66380dd92f931731cf38e65ff8e093e1713e405d32abdde7ff9abfa2327e6e8ef90dd4f19b20babe76e4b20d496ddb76c464c9feb978e35ca75d2660893051397ed5d1702360eae0b2f8a1ac5836b627e821e23b841168bc5eb42223a95474a0d059281b7e40f9656ae0b73c592e68d5ba5b7845dd00e7f1ba9af56deaf0809355dcb9e325aa2f86db24074b3d3cd0d3f416146da355f17f0e05f38e711602199077e1fdb44973c6718306fa9e30c5e95a04d66da450824bf06eddebf12d9a7aee99983ac94546ed3ed103ff02cbb1bcf794daf81efb33d85bd5002286743e64dce993feccf91df19f22bbd988ad5397686769054d6b9dadf633e0bc42ef56e9e0de362bca860c0041471c48b7c7c13fa24fcd16541d3365dbfe7043a17267609fa77d1f5d8087ab743442739a41998017b97def12476ba5dd807a73296f16ce91bf594245383c51e670ffbfdece198b2b372d289cd546dfa43aa4230d6c8572e44377dc7ecbcc956fcbc8798eb5144829d6df2e77992f96e9f1891a929a9b9a9f6fc138cc92fbf4c75e46638298ce1b772bcb21892ef9af66c612d54d36132ce75a16f757bc10c6785e273610dd80ef916a9e9459b3d900a5f5ec1b8185803e607e6c025ff0bb9c0ef34725de8748a83417132994cc8c1c1cef1f18eef5f17f2b39863dce2c6314318eed901987a42a57e32190bddef243c5716a6cac13c32f0f2a8fbccc95abb2fc87e4a645b41407a87eb07f43e9eac172564cd9388356380f6070e42d3e95b1d1c049f7f25ff220b5f98bf4076c8c289b3f0f4130cc90cf1eabf82bcc53c1cee732db53c66decfaec6e073e10dedfb199e3fc860c6be2781b3f7eddfa570c32b05e3d23ff9cc079ce8d3bfe7cf6d8c2acfc54b893333c709c89f2e82e4af282aba67daedde5bcb4a0ba8be545844edff6c69f90f5158734db0c8847a2b69333b1d0fe54d9c60bc54e0c2ea3f9bc491efb5ea8f99ef9b5db633930d1ee3e6f987ecb23e6039585ddb0c861ebb1960eb37b7c24c9c73dce763e1a75fea33d9efd9b6fbdb1f1c7e8bf9c0e4975fc86e186a936f74dabb2eb41cafc3bceb42e9e3b467367f8e1cf6bf43ab3f6f687586e8e74b82aab4cfa2c7f092ac40e18f38a0237fe1d0aad8a9ff6a6155c1f67f4b6c75beee923f35c0ca6dac978658398160ec57fb8cec91dffff8901c754e3b63f46e1d8f2cf2ba16d923cb1f88457621d7a5188cfd629fd9dda0f78158efdf4f79854630267bb2ceefd61f996fc740d68aeed0efa5a2c0e12769c6ddb3c91eb78a601ca75b0fb3d93b6f11b99ccd2e9feaf9417ffefdf4517e9fc14e7ef6cd02b39870e9b7bd64bf6784bc2e642f961cca332c69be7cc0508248ede2b784843da9d17cff9d08e83e7d8f18fedcb1dc781ffe35dd199d2fba3ff52c416d9f0f556c1c13e347f6f6f6b8e03e73fa20f9c4bd5f7926f7c1f46ccbeecef354eeb1392e429bb16438d363f0da267b6a3e9b64040d8d67db7c7eb9bd3a3bfd05bee6ab1f6afe864a7166d76ede2795df2e8b790ec1def993c3356fe79d45dd7fb9f31a331554823f951bf7d3ba5b3f99ef8116e5cfe17dac2dafcdef6e3c9b6737abb9fa7629df646d79ed251bfd458f89f92023cb240b61071648c7ea10db09c8c462fd0e1f04e28177969d639d65107cb705fa978e97fc983704cdf642ce17a69dbdf835a1b3bc8af415cacaea303bb08249a85ae2c9cb7fbf3df4efb787fefdf6d0bfdf1efaf3bd3d543c0ac1ac6eafe5bcc9b3647c546d41ef185ed9ede7bd41344413aff6f68b5d16a861be50a9be4bc5c9faa61fc0a54eb1768aeda1e7313bf88f79d27b261fb1b73eb3cffa8d8f5bd19aed31ddddd20c947ff023e86fe4e48b8746202037afcfff9ad400fe39f5acae654f75b2b33e7327131039df6dc7b619e8c61b071a9f3b05e06567fadf25d841fe7324214a1481697a697ec64f343933be2bef07aa81dec6c713163c38de3d59bc1897cec7efe67b0905fa27aed5efbf3ce91a3edf162e9cc0ecefccb98a551b02a4a43509987ff3e05941c0ecd9d2b0231648e96d9af798d999bded59d3c0153e67e7f22d67c840f3e135739463919cb0a07e4a7ef925cf6281f26230fea113fa2a5ebd39789d5700e22fd95e9537b42419b239272fbd9e25cde4df6f0cf96942cddf428f24ef451c61f99ff8028e9005ffadbda6ec1480d93ca85bc7ab9aeddee2e24823f7e967c161389466f0387f57fa7f70607fff24c359fc47e96322bbe2dd5b0592a311fc16634a9c897e24cbea917306cad3ab4e9a85baef4f88b09059271a9c9943cdfc13e32de3eecd370d46cfbbaae65eb8b282396a99b9ea014b13f8539055cc6ff2dde879eb5b22a8d5660b16cb46ce21c90eba1566df45232352f0d4f10c0f349e7bf94fac91acb748e42aad0cdc38c7ac637930a7c0bb469a0f56d0ee4dc91d8ce5184a31cbac20872aabcfd94f193f3712d9b5625dcacfb57b8eb8a83185e6daf2da7344d696d7e2d3152ed4e736161faa65ed2ab0627b165f39931daedc3f08c51e89dbbf7688227c1fa66e43f6136f26670352e00a792c911b537c5b3a779c59d31895fda8c246178ed3c74bc7430585b97e4e9bf97e91d9a3e2c969a57a533df98c2f12713da73384b95f88d522901569fb0111447db247c425ed8bea0aecb051c08b17de154544f3439c8ad85a76433aa58f1fd4a8a8509d367ec948c4dc2123c7eaa8bc656ea242fb2fbefb9020a96cd5e9ed2eaee23bd628f6d0423b329e3e66ec2342b5b2b16bda1deeaf74af0ba4d58d3c97b42f93f298d7c063ceb62f917e51f74cbbf3b1e6347bd660c0bcdd520c9e5f37fe36626fc91c064e664764a598fa2181b3775d2875221d3ea56ad8661132e8944b33246c9aad1d6b775e06ed68adcfcca0d40f3f824126779c99f97bded1491cdf3fe7efbc592f81d433026b38fdbee9fa2c268077433fb06e274b7c4d313b5862f67489dacdda674bcf54e0ad5fb071f0cc007efb47a60a79602ddf69dfb3c09096e42fbf3c33b2c947f93ba6dd85a9be6a42f683344aff21fde7a9049fa64dd0f33d9438e11c64e92d81935584a64a1e71d80e091b7373d635835e423f44da7b4fb10df3e62c939ab298556ad1863f173535e57707df61ae527dc66c7a5953f0a4df94c6324ca89735b4b6bc56dac16c9bec96b861f522d2d9e4a6d012066f7ac7c8aab25bca1532f542a276cfea773c66672c08444b983c4f4977ad63a97a4a310b9ee673d07a4efccd814b3d2758ea3b66877925cf7162b8dc6c0b911326e9b940bdb64b25619310a0472aa7c791f5072617755db2477a4eb0b8f84dd8a84f1006d805bb5080f6641938f7bc53820ab3870372d53cf6bb17139745c183265ced248fe92f3e3545102e028de5d770cdf14a8820032da299c8aabe6a8ac734a3b68289cb76883d1cb498275de48e1998c2da56e9715c523103f3c0b43b7de6913db22851a1e3dc049431a23e0b480f31b955fa2d7a899d604c661178ac6bf901f304ddc5018e48bd1272a6858476d4f695b04ed8ceefb2ea1f7c6a10fa216b5464e342f55fb15613769545bece64d62271ec5397d9fcafd1777cc6bf543dcf511b874372a74df6c88365779c8762df6943eacd071563e859648f2c3cf83b0bb1b7f971c3bfefb4f97a0a9cb6d387f4f4057c87e742227225698444889ab2c04bdfef9185526981bce71c157b8e1f90f7a039626d727e1e7c38d47f2051cf879ef52e86f7e0171ddb71994df6c4407c8815b5f99040190c4ebc90f161824218b03461f1d46ece9b1ce14654bfbba348ed1e396c9e9e145dd3f3d922836c9174ba424f0aa72a14452ebce9e77cfed14b8952f8c97867632cdad48b8435c1090afa53a4bdbee1aea581be1e06ac13c691cc569f69e4547e3f365d357af2f2e715bf25a55a4b2e322dd23ce99cbeaba612eb9537e8a316527487eba75447e0e764e50111d46c1105ab13c3e6a0115e5396820fe1dab7547b0336d81137d14609305caa6330f1cc5f829b78b528217092ee165c699a5b00d7a7e61475fa3925e105a9d9a5e2e2d6747f950b70330a95ab7053a5f25adc5449ec6eda5429de693be74c8b83e0faa9222ee3140d2f0d7a8e6c3cd94912ffbf684191b6d3ef8331bf43a8e79993dd78ad8ff178bf5ad346ae6f2c27aa2afaa1d40a6b9a9d0e525cc413819d047b09a58248c5c0c714b8f0d1ba8a19b0a2ed3c2cc27374cac373e91309d9313c4a4082ef524a2d812b23fc03732cc68d6fa29f1ccb0eb2121a13d5fd9e751b2c4e79e8138f5382fa69987aa69e5da69803cc8c5625e3d11ccccdb9e45ea191c57eaa0b5915618891dbecbe271ff625a2df392f7c8f0febefd993b444ca7fe43e4d4c7cd676ecce91e9a7da806752ed0e1bcb3948535e49cd05d6d825cbb9db5feea467770a084ee9802a198bef76b2b4445c88119ffcf20bb6140d402ec7395231de89c9663cb5832c25c9c7cb33b36fbd6c921e333bb9f478612631aef5b21eb74dea84749aef2b1ec6febfd01c51a74839e7cf1232787c399149ffa411c8eec75aa76ee0a7d3cb91e075e1627c5dd0c882d76d998bebab1a296f2d6b64a5bcad95df2d64c2978b6bef16de5d671ee5854c79af64ea5c616a65755d23e5d5358dacaf442ca9d05c96926c416eb29f3e5dce7a8a3c5bf5e53d4c0eb6b1dc73c235b497a492f5783932a56e20c5c04fabc7600c466d1c6f9cc6f354bc2581e88d335466866866a797fb3be26f6ac2c29cf11df27b30d688378e3f49f09471c69b673a4cb541cd305930014f2577a6ac976899e714098d9269f628a0c4d32c0949e6de7464bb4146fe75a16eb79d013c96ac0907fef768786ead7e3ff1584adfb2d905b3fdc423222db37ddff59ca1dd319cbee3ed846b724b231bcb1a296f9651fea30af06ce895d5e15e733901cea5514e51304cb7194cb8b5bcd01a0641b2b8026f3251ba14814f6f6f7d16ec90e5e272a2f4d0b1ec90e8c00a98175175b911a1cfce24e2a706e7ffbbbdbdcd249a1a10283b7046cc4b5379be65ac9866776565590bff9f5649b0b3124738373bd6d057a71feb59b2642559c4498685eb186f92ca4fc6548466b54deeb185919436f21dfe6c750d15f04ecdda496b0721e69c628678670aae68208ea48e603b559c168a1c9cec799c8a3cfbdc3d656800bcee5dbaf39fcca047f6c875a1f4e0abae3ae06659cb648f6c2f2f2723704233ca64954c770a9bde099d7774aff1876257ab35d227343ba4e5387d66da640f1fd7caac077e68e0fa37e1de16051db055f93ba76169892a54fcd0959395a738801181011b2409c4e20553bdc878a298603e16e6d90d9741c2a3fdb818b7256046bd613b70322e928a474d653ca72802c844bd510340c96cb23c024ac85925c22d5959342bad78805a2597e87ace6b9464c640e229b564d8366385a40c884508332a2c487429a98b7c934cdbd9b3d404c17e4dd577d9667afcbded7934c81e596ca7d65bd476c6b1e95e74eef9e1d916e5f25f8c2b8474e416cb8b03367861b0231dc45097e32b031a3152cf0637a6d4059337ea6b46bcc60f870cbf2402c453473b19e8da23c914f29ce05676201d897666f34592a9dfb3fa22e98704331d10997d2b3b92eeac7064321e59142e86d549fb2210d08f91ce8911c57084764ef0304bc42846a6988c0666f854999df2d54e6971a2691a6222637e59722c628cc231e6c01931d219ba7dab6d06cc4f0900da0df7c4b9cd61f29e4dfcc5773961bb7f844c5976bb3fec307ff13e0b357f083aaccf02b6783feb1bb766583fb1ad8aaf1ee5b0227b8904aeffacad41f0d4e358f8c32e88aaebe795bf3cd29bb084b01924fb9ca6542c9fd76a4a95d4bc9a52ad0bc22a3b9077ad5966382a70fd29c12837e3bd0e7345a33e35a3c8cfc6a646cadb1b1ad98e45a354f0778bfc4c9bbe598240aaa8e7137c4d3cc8f5330242aefffd033dae3f35ca33557a649e52b60c85dccd4312cf21b3a4b1634e34d273869e4606960d29e518008eeb0701237b04de5370db771c6f5131178ad80229e1cb156375916ebc6a48af443612d8514be1b7ff211bcb3114ce6e9c9c68224d4db62dbea46875cc499c14102f9195b577596dc29fff212b6ba970ae1f78e0db0ac7362ce2ba0edad823e58ce5c06bbddf032ede93eb02a9f0e9489078caa2f7715672fef3f4a0531ff7324f5464f92e2967952bad5e1796af0be43d8e116f7e27d130344e58df6753e94caf3fb5276296a7f44560ccde1b51e115fd798ec2d41e858b604a974294d9fb94b5c267ec4c6ed55934aa1f787328ad011be4efa23d66bab48f094cafd84b0f98e912a0136da9e58d2d8dac2f6b647343dd5255f02ce73b9cc3ba3d8454a3d77258b7972e7da69cf7acac68646d5b235b9b2a8b2a7866163bfd37e1b0d3cfe2afbcb592c92087cfcae1b9c83979032e43520aa76246c9ca7a9c53153e0ba790a8f20612d9e4749222b9bec6cdb9b246ca9babb14347153e139793d71a9f4e60f6d32b661997065f23b125a3c07f80199a8eb7cce4ffe7537985ed291554da020df3b2b22b81cec8a904395239d53afddc5a9d7e4ea5703de4540cb3bdd29523694f5795295b19d5261906790af33b18e43eb783e49468d1406b72f0b4d888684a17673bb015a713e24135e501be19532a737328bfbd28093227075d3c16fbd2fb27321e99559f2616d594c39dd8998df230849a051dddf610a5fde5de9233f3b9f708af2c4c1e5987ef814f97e06d71092a2d713158923fbc0a50c4abb392fe620fa746bd6d997dd36e67f0358e8e7ca251fa1835e842dfa734880f3225db0bc63beab0a7472dc667949469f5991f3836cbaedd1a7249941ca7f9fe98c5e1c5f899594f4f59ea059923b6cf58a7693d72a3a5ac9c0ddac30181075f206f3b6ae8c409f69da1ddc95aabf1d7ed264e134b25688edcb2c82c8d9ffb05cc0f6ed4891b67e45b964a70db83150530552289e9217bf1cc271595cf5862ba5474956d7c31761691d89bb3673bdfc42accf3e089899c26c5b34219d5e32f544ebac869cc1b7c93ef4e5c9ea78c8bbceb3ebb3b6115e5e9e8c4b3d73907977915b26e6f5170c99edad4ac47976371c668763a4742c62fc639678be2d213980bd39fd86d715897664b9c81850384a784f1b8ad37c9368e3cc64d30f3c1b40272cb82766ff1df25d3b54ad878e99fdf44ae20bc90f9dfe99d5ed0c89a4924ea31bf78e73b76c699458a77acba88f412b602699b41bb47169997f53c84422a520e809b1d12991aa457eee3217bb9831e13e3a4e026b07045c4d7de0ce70489015dcc1ae819b9f3e27a7f06fec2d9f5c38150f0f3e8903db2b0907d061063a8188cf326515954683d266f5dc997c5e71e8ac9e145ee812f66691a517145cc9b712b36f497f02a2e907cf9003edbc2daf25a660333cb3a9ce0c77692a9f20dd1e39840cedc128afc627a57899212d4b521bf7f48abe88b71a4a1557b67aab6063575841bf45b286c10c43c59e3b2c4157178e6bfb747d696d7a61d83a67469f4b5189a5ad9ef8cce10a294201199b09d348be6d9342ec68bc9acdfefba4dc46e21fb09a65cace7bfdaa4671bb8f34c7c78111c5c84f6e79a09530c04781a21db2a90b676126306f515c9df62c648a67991b74e4537bb157dc70b16174d8db4b2df0c270231a6729dda2e6929bffe45ca64872c95e3c396912b00776e61cb730c430223bc01e8052614e8e6c5849e993661c1f84fe153d50d9ce3a4eb16ed4ac9a6c4b7199ba88ae79e1743472f672cd42e332f77eef27a4c5e69ffc6fc233983e334b3a5125c50c9ec404921228b7ecf19f63ba4c5c8ade907e4c10a7ac4b1fb130217919497df655a5a91ab5fbcb5ec0ebce97f7111d75480b75aee710911f757728dba94753c9b4530cc76d98b0537a66963a5f27ccf092a1531b925eb89978c29c84c7119fbe144641dcfddb267f3f672066289943f100bce3b3f106b692927781f8cd324b2a2f59c91fc2b2977036fc62b28778367dedf3fcb6d90d30810713f38c72dfac3961f788bcb1a595d9ffe16dd67ee95dc2d4de1fbb93e7176202437e576eb1c12bba520fd56cfe7ef60e5b3950e7ae485d8e3f77dcdf1de9508a1727a1c0b7b27de99f8c9734656277a5d6214e956b1da1e3303a67bce83cfbc03f1de145143bc4645415f082f1572fbc3ae652ff981c7cc8165775592d475d577bd50d75dc87e6fa546b8b1291abdb282deec6fb3442a33bc3a72eef782ce7d0f1cbeb9c6f5986b7a8c1c3bad5f09a28681df7880cd660f6a440edecb8778f2855b61826cf85bc1895dc626f0621ca9a1bfa81a32044fb18178265eb8b8a3f2a88528cabb1a7722e66471e25eb89d386f1a3ca664870cb4620246f64896dc29fdec49c42c11598c93d348a2d339ef120a578d78459278cbe16eb850c8b762b18823a5be7a105f09e5a5df2e947851d32e75ddac571029944a484a80764b61cb1fc5a0769cf670c0eca0d86541b5cff8577d52ef2c2ec0fb94de5ddbf03aa33fb482ef0cbd363b779ca0b053283cfdbf000000ffff2a0d515c0d450100", - "33b0d57119113a82bb8b4c59edcb6141": "1f8b08000000000000ffacfd5b771b37d2280cff172d5fda93d849e69979ae36455116635154482ab667af6ff502bb41125637d001d022e9efcfbf0b7500d0943c663bfb4214508df3a1502714feff174fd23a65f4c5fffef2fac299ce96d25dfcefffbdd8cb752bcac7fffde9a79ffef18f9fb4a964d198aaaba5fbc94a51fa9f94aee4e11f5fdcc5ebff96b6318dd49efe7d37f5ff598bb5ac7fb29df6aa913fed64dd4aeb7e92aef9491ebcd495fb3b4598f51759fa8fcaef4ce7efad69a5f54aba5b639cfc6eb9652d9cd3a291eecc9ec328bd591be39db7a28516ac76b291f7d63ca94ada33c66e7df8a9566b08fc03a167657a93cfd099f95e6aeed8d4dfcdd75ad3bef1c7f66f8dcbad72febd355d3bf5b2f97b25fc50ee85d9ffd800095b4d9bed0fe7fd6ec6ca346ff2255c8a46d6eaeb8f4d6769a5f032acff4b776fe5467d7fb2fecb6e527a27adf2676e1f2b9da99fe49b56f85dd84550c429f0bba53c89ba936fe45f9da8a1802cfeddbc3be5bcb147c847e11f1ac56b639bb1d15e1ebe8fcfbcd2c7374a3f09ab84f63f55caf913d83fa4fbfe826fadf4fee8d45739688f59d37969df54a6a1d1ee037f1025682f943e037bbd947b296b597ab1aee5b92388a5782bb4535e19fd661b36392e67a337eadcbdf76209ab0804d4f1ffa04da9c4ef96529b4ab8dd4f8535e6fb555262e546d68a73d76d98f8f3d64b25bcdc18db080fe74d8afed02cdf89a7b5b0e78e66a74ba3bd35751dd60514d079557fffa47f21e3ce98c7339b5cab8d2c8f652ddd9bd234adf0df82ff437ebf298dd2ea0da2573c7bdf94d87bdcf2882e7f68e37ef3ebb32dfd378e84f12e6ce9eabad3e5a0a5bb95fe4e78f57406f5b413362c051c8f31c586b7f75254db730f3fa8f38b7bf3eea7bf459b30beb7671043ffc74ae785f5b010f198ec9c1c9ba651decb6a21373f58c4e4496a3f1675bd16e5f75778c41693b34e469eceb570f2bdf42bf17da41a6b98034d7dab1e7f8c24a9d453a047c681b8be3b8702382588cc5e4bfb51e9ea0c0aeec5bc57a6eccee24d4e73ef8eed4e6ae187b739e65cfae31994f96976e5e09409087a38fde8be8fcc4ef36ca51f9ba6edbcacce6bf0b7cf844b2bf4f789de6fb022b568cf2234bf7d20fded225666bbfd5b03f0a3597f982fba134fb74a9f7b283ecb7b36ee08fcd75894bbef0f0ee710ce99721ad0f2fcfb5891332d8fcdfa0c3cccc9359c4e6338e4869c6a33d15e092fcecee2cd07f963dc44e00287d19dcfe6e8ef641fad43b8f47f67895d4b599d752cbdc811b44aff2837e1adda6ea5bdb466efa45dc84dfd836cfc526ce448973bf3fd769c22c7bf3a698fc8d6183baa7f94449849bb05fae0fbe8f945b99258ff3f5a053fd8fe6b634bf9d0563f721c96423f3879359f0dce29aa0a08a3807ce439abe8b4002b1bf324ff5e1935641c9c2db18f93b38f44e20bd2e40566ed3cca963efdb4ee545d29fdd3b636eb3348c3d36c670a13738a723a900a9d89efcbf04ec8cf21650f3aa41ee5f1fb1b3236e656eaaddf9ddd18e5ce393462e9671e7d7b61b5d25bfeffddf4493ab5463cfaa332c161f2c056f8dd1b6fde58b99587f66c6502cbb699090676f219f8bb05a126e08d704e6df59995b7d694d2b9b38789341fb529452d7f12dfa7714e320caec1bea9be0ecff3f8fd23f3599efafbcbf6599ee6fbd4d4b33cee07f2f8efa3e2933c43076d7d8e12a697e1fbbbf024c3f709b1930c433bbd3643330c5d8eeb33a466bd0ce5d0c92e07d7f07deae624c3d0755e0ded4335742d55f2cd1952d96779caef1f4b2779868e95fcfed1749241bf59be1f9e4774c3f30c5e5a52bfd9ae87e751436733e4f98171d34351961cbaddcf91799f6478530dafe44d37b89ea18b5f0e5d2f9ba18b65a38666183a509ba1c8776387aff990672896d80c4590dba1adda7e9f373ac930743f6d4df3a61683c986edd0757506d7719261e8bada0d5d26bbc17d38be11436913357406d5509ca086e204e5872ff52f4357ee97a127e8e3d01a1ebf2f723bc93074ee1e87ee8ac7a1a8ed71e8127c1c8a72eaa107793db40ff5d0f5570f5d1a6728c64e320cc51dcdd0b5d40cc5b3cdd0b5d40c4567cd50c4d1b837cdd0e5d40c9decc135e8a10b560f5d1d7ae8dce9facd60ae570f9def56bc5183f30ced493b74fa5aff6630ef6b8762103b140bbaa187ea1922b9930c4331881b8a41dcd0b9737f0dcd3074e29c7d531eede0760dc53b6e28fe7743857467e82e4f320c5d1f7e3027e6878ac1ce90a59f64a8dfb4c3f30cce317455f9af435794ff3a9452f35f7f888be9b66fcac179866ef46ee8807543e51bddd71fe9fcd350147778d33ad90d96731c8766f8ba1b3e2b5f776f764327e6ebee8dff3e6689b6177e80ed99fc3eae8e9aadc176871b2be5fbf31498c9426309775bcece0046e5606d3b400338b25b30261b90e5b2db6cced02625a5e1f42c6d552c7f756c65759ed570dfc8f82c9bbed4aca5b7aa04433161c57a808eb811bedcc91fcf4f568b67a72f85f3f7e28cb325dd6c79230fde0ad0b68b334c3c5015a986199dbea8dbbf55faf17c8bfba4b4befcfe64473b0eb654de18bb17f62c1bd5976c48a6baedfec60d9cd55973beedaa3307756794f36fb4d1a418765e785592fdf1373efea3fc72aef9cdcef837b51195b43f9d65bfff4dc3e29d2c1f61e8fe5e11b7627d8602e6bf16f1c3b97f7cd243eebfd7f2d58f9a3c2df7ca9f2103fc56bd3f96519ca1ee7bd148b0364e5e76de9f7146be68df55cb73eded7f2abf50e81fad35558707737306639eee9cc422e096d1c0625cb9932164cfdce8297da836c68656cb9705dabadb2afdc6792b45a3f41611c6b7be0e38437eda88d21b7bfca8fc6eb5b366aff476b95367c8acb232c299b008237b6f4d1b4e76b794a51d70f865065957529e6d6855d46cde3baee5199629cfb25dc95a0e30c18df9861cec31d38d389bfe4a9996036a7281121e36129065e028409e2123001986f41e320ce939ae9f332ffd6406d50bb11f70ada440fbac950944e119bb2c51a133e11ee5f7656391163456feee06997a6fa5ff53d4dd10fab6fd819d7323dcf996843be176c38a0f3906aec69065c8620ce987acc5907ec852e4711dd80db0ba1cc8a0b4837111e71932009c67c8202ce5c05b178e328caaf37709e719d2191158c8a539437195f8b2815500877e791c82571e94f6ff1ac40c8759599961599cf443b3405fd098f9fc01d84a3faaeb0f036c9499591e9a0d66f3be1b8092b6d2a3c1f2c04aae557d8e012fe571be5b0f1b68c1a28dc1c3b652cd195651fd8372b03c2874e85ad467686bfa150d97f240c6072dcef082106f53994a3ef8330cd6f22a068db372f7d6781388ddf35b05c4c8a06acc93b4237b3edad80eba145b047ae24f25cf97acde5bd3a801733ee484f828c5e3802b15306723b08b1f46e65472a3b424af3ae7af29bc803eda6eaddc0a7fc605acde46fe817cd0bf1fcb361167480cf20cd7c6cef7e78bb529cbc0b1bbfce15c83fb33f5d20a2f8721a719ca77072234c8356483428641947cd6b8a1cb763b88290b3cccca9c25738e54876c8cfa2ac7a26dcf676728d3b9c9fd50f60a4ec1a199609f0e40403be1a6c3b6cccda01c3be186cc84aaa4f6eafc95d10e4580a10783b1669ee92c39ce8bba0c70b392bb00096c51a024401e7cf6a5dc173517a0a51aa6be38b912d6fba61caca3411a15e53249a4722f4804ff7faf2fc0a3dbc5fffedf0bcc7bf1fa421e5a637da86167cc23fbdcb8787de14c23091abe8ab6ad8fe13fd37817af2f48751642baedfcc5eb0b8e236d7ff1faa26502e7e2f505efc08bd717a5a86b28202654ee41e3a15a41ecae6bd6d242f04af8909dfe35a28566846f1b1d125cbcbeb032b4a7861b89a1d6ce857f3be1e67b1d564ec871f1fa62dd0386e50423e0a50e95827badf926340f16c9c36a1cea00cf40a174d022879101dd5d4c761be0738ba93b5f5ebcbed84a7f2fac537a7b5d8b6d685a73f1faa26843d9b269a1da4e774e562bf328b58bd1298d6320d936b5d9874a76c2ba5bb9f1f327180fddd5352753fa49d4aa9a190ddda6e835b7b873d24e11263c8dab09c323ac935518cf7b8173df48ab2a25432beda67cf7af77ef60c9c9c74a1c67ca81d212b2ff190a0b7d49c10d75114be51295bb337b4ea2dc9db80bb92a1c9cc05ca4f67ec47ac2f738b45db618d66a7b633a5c0bd7d67c953a8e3df5eee2f50556b0e9c2b75080df295a12a17b6007907c2086fca63d8ec1a516accc90d79a06576c8b8b01bb399a41e6b8508bb0de8a309305a4f05f1b4c880ba0309b8d9390302e980e6e8a4fc3a2db5ae942f55828b483da8089e69c5bb998c4acbf84f5bb76d7b531b804686fcc04cc7b29550d13819fbd99423edeaad7c68e8db4a53230702128abb8bf60d5e3d82aad608b8127282bd11c00379b38bee540581a95d17e6cf493b4a1a246e9b8fbaed46683ad0dc9d46603c84b589806173aeabab60da370255b2b4b1130d447bcbd8bf3a29d8151abe87b086f9475bc6aaa94ef46e8aa865e08bbc5df50c6a30c8bc9d5aa0ce9bf1868dec45a181d10026322d72f2d8fcaa56a5a68464099383c64b771f1fa220b36d26e252e24da0412860627b5dca9ba8ab1db8841608a45ad8483c528aaea412b3f0a0058fc2a7c773b63fd4e006eaacd5edab17088476fb3980ebbbd565f65288173bbfc032e5dfe0ca83aaee698a8223499008c645aab8c55b46da8a5f7083ba6cf21f8555a73ad00b37b61b7d2df3242de185bcaa5da6a5c1a71f1851c6ec5995a40788d38c02a593b6f23fef5405412ae848d75fd1c8e497972120412e460511192842f30a4f8bf15550538c7d84a694001653a12379d2ee3411088ef5843dcabf2d00a9d30b0a0f39011a8956d2d605536806c4ce771901bf128af7bcd4ff8910e3eca7b6bf43640b20ee098e4e00010ce035912ba279de756bce5c03b0efcc2815f39f0cf98d89b94cc9b98e0376ff234bf64e15fb3704cf3a0038b0d230bf1652f16911e7e0bcbbe0ffa686c0523b095075e868b10e1f9832ff1685e508ccd74d2892ce1d3b5b19c7121b79343cb254c5c295ac9b54203db305e6d188436f4b20ddd73bc62a829503297282a38d07ab0628f1f02062359e9b5354dfc1c1652258e6eaa3f4b1116fd11ff29772b45cb303e63577b73a5b6ca131c6088f115fa17c2fe2e25a7088beb3d0000efc99630a993fed55b4c0c2b12a9880a971bb687498b0324889486e1f40e662bc6fa609e0704f563303ee1089bdfad6e96c5f4aeb89e2f66a315e0e08de86a8fd872c6e5bab606acf8c2576ec30e8e039c732e1f6abb231c1e8eeeba2e09878602724c5af45b56842d35eb830025f7614efa591cb9e37cc3119c81f8095b3d7b3e38bd2f0c2cd10359bfa6b2696fa55ec8273e1bee952c256ffe1869d4415631e670688afe1c142fcc12c37a5b284fd8ff820418e1a6b05342376770ca63efafbbbaa605e87ab1485d5366249cb6d23facc6fd4c7d001001616f45e450c1815199b03536fb2a9672054817a623e40d7b2de47344d426da1659072adf4a77c559f2ec943c46ac741f5329b13121927670fa74270f789aab8d2752171a026734523ca5f0a94d6e06f40ac77871efb3ac2921cf462ff529f034ce0baab795b2a6bd08e776bcf8119bfc6cff0176a15a690f16a78dc03df5f114da287d0ac3f9a2fa3f9ef4ed04fcd216fbf87cd8689f9dd6d428ddf2266b697fb5088f1bab381ddde2c539285e98ac94b2bfd77a057ce3db4ce9fe975d3cf177a6b38e69c552704f3a8f68211c69b3c4e715ccf32544561a5d01fdcca45fa1dc7d03e7d0fd2ccf02b49ac3dfb7f82f9c90e8652952b9880189755b0b2713592c6aa92bdce5a291b85db53cf814a21d16a81804861001439e490d8dbe5d2de137fc843ffca1dfdb1e4e9e2349c7ddb5b206550a9d859bce7756c2710ab41270694de8e90ef077402eb33008c763c62f7361481246da545e8b46d5483147823a8e4b6d441523a64ee142acd7360edcfbfe684ae6d51c9ed10213c6efc82fc728155544fe123993f87d63ec44004d8a32a1d7175f68e4816d31c6a5b2ca9d2c1fe7492451b07822479711c898b607e8ed5de0f322ef1bb033cb8dcace8656d2c1200fad2cbdcc0404812e5a9907627cf67f12efaab1599d93f959929dc4e9b0d9a633792bb9a2ac5a6ec99e3017f5cecba64db82c1b8bf7ef2f5e5f7c0cfc655f20c47b164ba785bbdd8210e4a54386cfa8a9de04e2aa48bb019a798c07e22ceee8ed491c0559b29a3ac3c8612d9c2ab3b8ff9a686313ba8ba21a03dadeb06a5c7b27fdefce641892e768ba9c87c50b8c6b6df6cc8de73c87574d16f91a838ee57ef220fb138f12c151c63275dadb2e9c8832a38597c00a9ab5c323d501d510467f167e2757f0bb0cbf63088f213c83f00cc2f710be8770aa7e713d266117d039584d258e18080815438846318c7812c356baaef651f815170f2e134c839f18a5c25e4a0b3a76092aa99517f61801ba6b6278d720de2cbb3a17134d97f3e25ffffc3920e1c5f5b8a0ceb847d5b6c0bee0c8473edc1b4f18101b143fec58c006f89ed11be16e8e5eabc3470be2d7d6ca804f2242c7384a2764d346f85abac41bbbd258b9329712e699f6dc3200f9e3cb4b232207d85db01443dbaf13637e9a29ce589c2e1cde5ac558ca126521d95267f9aa8bf8249319df11c27ccc24d81392ea0a3828a2d41be922e37720ed48601071b4aa7cbc3c46f1a443b183a40e5c7556901ca04ac1b01942c2bf3a61bdcc834c81e286268443045dd6759610dd0877254bd500a682b9bbae8dc04e73d551d87b92bfa0628bc8f415742015eb6ebdae65af1414f92c4c07e36ee97f1493bab0728407d95ce7cbb8b21d4a8b305d6f6acb5da71ffb0202696388a47078c8d446c30b2029b5a9644d92494e80a895f0594dc89b0e879891a4d65f8dce65b40f20ee47ac9961d6131e290d8445b6456d360b68e81aa93464e14136afdca5dce056688d538142c10de4aed46623add4258ace5b54c06c70eac9b0a0aa2056292b5988d44aab4c18710f2798a8aa65b706ffa7584055e1a8aa284a77e93b4c308974f73b430c37cb78c1872c500dfbdb5c2646c77c44e9bd380e592d70979a0a78844a3da90ab53021e8a058988aa517d6cf37745077beec0348da0227684fa2b7951e470689294e7403ee1b79afac404a89f31f528c400c19cf64ea0e6d27a673be495116e624fe72ca5ba91522446cdad50b5203465e185d32d28275327359ba1ca5017a41640c15dd1be77b47731457a26000cf0718cd8c264fb24bc718c1efe05f58fb57b2863191ba825cae371b345255d209c64ddb1ae7a32a6d8f8f522dbbcd46010fd33542abaf92b4307740597983ff69618ea20e2e61e74be9f752a2a8b4ac3ba79e50108d0262d4e74078855b6b4972a050c0cc45d0dcf236e278da837d351ecbc2bfc2e10a92f63968673a9231a6ef2c6ff786cf2f6fe251e30d8d9837d3e53c0ed2a3946dc22edab598fa2b2229e598b26ce13923d8aa3482defcbe9cdf619b22e65146f797300b0f88c86468145ac0fa4a33c86829414203a111842d433c11a030d4a3ea4b071c5451ee84def6d55e50e27fb03b9efeef841bd5200f0ee446865caf805803241ba1612846c8da84200915aa48c95e2d57cb9ddaa0b6b33889c306618927fc572420df28595788077021d4ca91486edab4354aea09ccc202fa800cdfd258ac03c43cd0fbc4e316cf84f3b8131e5ac445de4088c5907db17f915411ca5d33975a9cb0af816b8d1ff15d3bccc035167d716d2eeb9c1c10d9837c2d67e91280c889221342157d7155712aafea0b7ab88e62d3d5f5a9b8a5dc093bf2b4c2f738fe02464ce0b1be1bad5dffec82d9136b3746d567286d65667d19f4ca5c11f9231ee5c8b1c60d501bfcccfa648d70cb2c9c96b570372459118e4a148eb79370b156e1fe48549900a9a24bd2775c577e67a5db991a2a011d97f29d87591c6d0df609fa962106887f0e2421c0afd501561ad0f2fc9f746bc78602301318dc351cc2f51fb91d173024752860e4888e5be3eee4b647b6a4c5c6ad73c99a83df54642576141cf8a68de1bc0c200631afa560a6f6ca53ae78bcf2b1838dd88036a03946f6e26635bbfdadb8068ef06ab49aaca6b349713b1f8f6e9f018ae5643cbfbb5a3eff3063d8c5eb8b00a67f59068842b28f93c907d66084dd8237dec222a7d71b6119101deb99d428fedbbb8cc0229775874a48dcc71f50518d762b40b3d2eb318e23b84aed76857636f0c44022bb429b77b2e137c822b198e263a35dd7401e7ead11ad472ed9c8e99e0f1c2a33c6f124cac40f4bbc5c8cb8349a3703ad5014b0008b22e483781c9da288a22db4a30fdd00f34ba0042b3c298ac24a014c04f437d4494afda2702d7d9bccee579f8bd16231fa0ce48494405720787ef9fb64bcc203e04e1efcb48a62cbd0705418ad0fef3bb46c11805c1ae99cd8b2c10a780f67463e1c0c4c903f994798356d0cd2e6f7b5503a1ef9dbd3e1105575a3aa4ab28192c96ca65a3ed87a66c64077858912c863edadf21444deb5e32f6c1de3bcd0a5349b7b2b2b45b614652dbe7e4dd65bb7ea511223eba47d0a0544ab2e3759fe73060cbfdfe176c5187c4075e292b9a3acb7b462535bdd331e9a6e4b3c835f49575ad57a32d50808466d8e1fc0a023e21b6fee6dd8ffea29b4fc5598b18bd717236f48562d01a33c68833d626dbabb944a6fb19ba8e4c7a06553151627d6c2f951594ae76475792489baf394d3f24a995e49abb07806ddcd57c56a311a7f98debd87b571294bd3c8bcce13103fc4e088ba90b877391977a2973701f3dc56b6c6faac2a048c810a8bb4fe2559229838db616457a3db095abf485d495d2ae9b84b0ff7c56a5e104a84c7984a9c851092335361bfef26304e5b80127dc9ed5d7a3c02c2c2165b34bfa436495d5d46e3329a41e26531723a5ec9e4e7f96864e64054121a3201654f96adb8acbad277164ecf4aca162e08430b808003f12661822b552d3a7d2bbe1ea75a7905827ceb228e0a4968b95dc9d200beea2ffdb4a0e15219e0073df92f9fb1f7bc1fb25a7b5ba3a4d42a7ee7cd1e6a2f80a7ce1bf4288f0ea01880201befc283418867f32a62fec82547c828330295549a95beb3bad78138245965d4a1fa38c9315995a5044bd369d3c84a092f6b6425e1b10559f506f9af4e948f2ee0af515e13cca8de85b100fbb6703c9c2038682e0953b2a45a468d02496eb8d86b63b3743205db4c26082cff7f1d3497668c2b4a13087dcf1a194f0e5155094a87053dcf008d794ae732befd9495d126c336d9a67427337300d1a5fbefb9f33cb44972907aa9e939908f8e04c1b3c3ca4d5e8e959b256cd01c68ea8a076c2b3d4f05486f631b4d0ac51aae81264345dcda1c505060ac95a5af8f0f4e56239757939ac6b5c14dc5d3697371813c3f334ffb7bdadbb06012b5d45b925be9af4ea627c9a7533f69691eb56854f9c2989f963c8ff466cf00d6ca4dc485483ebec37f60cc25fdce54b4a849495ef5663b611b5155fc601e2dce32519af125bdd319e52f58e75b9c3f07c4287ee019188b6ebbf39343295b3ac84bd13924599e7f733bd3d5dc1e58b87c4407e276be5c4e2f6f3f177cdeb5563e8dc24286c36e2105d2ec7d08081c29f1830edce723497f28cc09cc3a2d3e92a9bad3de54ca85390163d4cbc0fa085a9db1b409c8f24eda804014a85c9d1ed22bf37356171c4559a7a1d8532010afd30d649f994a6d1499c08eac8401811eee181d2181e15042873387d225d982d432b5164f76c44b60f4398a4697d01068457a7b3510d98878e7d9b0757a1d86e64ab66e6c3aa0b66da7a7154dc28a7a44d13c27126a775971cf6934f533523ab0071af3c4a485cd512dc4d60a1a11471b8867296cbfad6945882873b760a4259e2d2d527ae1a04087b43ce4d10d0d4cd87afd031f8922ae41c454a455edb28fcacdccfa10a3ae34c017863124ed329082318184cb1485d455ca1312b06cc9caa7deeae96f9b34e5cf9601ef0c6dbcda1c97ed31b67c5a459384acf76c1a0e4e5f94d1b04d5e2cf974971078aa9daae438e196c27528632be842c04eb8078d94b1ac3017f08f647a0e782a1b70f896d8f94ac2c91377b3cc0801d088de2512e2e16e7c33ba7b3fb9425e38fb0297bebcb4016d61ff4a6e8862786c1a5d9ed9099713fb38a23924e68c8658789a6e431a9bd597181f14f1c93eadc5396e1333929fd9dc87a268444b973b22e281d8a2d35ae9ed92455e44842f73aadbcabf3a65659c6812258f6a64e922a33013c775c62d28cdcc026cba91ce30fd0973012a68db40b6bdb07ab4369d8fe87b81b2023a84b84f2d59f509b7ec1c6cfb84752bae1496297ca59dc0b945e78ded787f3ca0eacdc12832473c33eb4f68d603c2f017f8d40cce63e3f251cd81aeed2d001463f4b60e31442e3b6f17cf47de52903ff58892444bbd90930b1df7a50f8d291fb19b48d5c4f01e5e2e8e6d858d51a3f249c39b90ef7ba218e54c1d2654d4356ee622f05bcce8f0d180d034aca4cb45817dac9dcbb4d29d8288264e2568646a2b70b5028c86ece4b5b1a71205dbe97c3e02fb8e4cf0c5eb8bcbc564f401805a92e648fb2bd9aeac845d8dff2a3a40ab935366a7ea8a2942fa72a49cd9f01b9d6e77b130ec26dbfa2f4ca77257cab5c6b17e64491ec4280a472b31b408a17507c70826453559962f1b8628758834d954f78e8e0a6ba7be61848f5ada61d09580ae2ead148ff746e12528dd5bd9c0d11fc82cbc94d92ae696d993098a9a5f51d7bdad0562468a58d90875bacf54bee49df48b176a5a0b27f3b883b3ae323aa40629e7b59228f5d7a29174d0f629eac808023f8d7540ae3c99b0db5ff92ccf0efc18448921909611f6a4e43e1ba16c2e915faec9109ad040a7590615ef4c717268199e8cb1b77d2e2c5b1a90784df61ec0d5af4c26a5405c290f70e21321b2d9200f03be011224f6c4767a79844b38816e4a3c341d6e37c63cd29d555c612c515a67d23587d2c49028479f2c41cd104f1f4d4891b879895a3dd3f604293de98496fb1e016765d521bf5496bd0f6dce95c9e21d98d1b0a4e65d0c9090c5017b986597f4a94d42e280bf56e619e6501e2c77b7324a32e903a63f0166c9504cab511c0f84da756df6e3308f752d7a7bd27deb0b994bc662a0335f24135bfe801fd3f1475e42b067144a302b9da99f642c054856d94e514c7addd51b458746401c5fc08c145548685bb0c34ba4d0d01848c51fc3b6037e9600718931251f867b9e61dbb0d8aa4669e57c549bc54c99003fc222454698b948cc22927b3dfeb1172136bb50a7b8fd9998682b9330de5bbec2d7c0be53ce477178a650c84ec45c8a06720f9620d25a0ccc531c8af11a36dadc5e2b9b0807d96f120dc2b36fa9ce5ce6e465e9c7c7b226f552385766a27523b2b943845d76d6c9c993b447d65178f3fb12d54bb595a23a2e25ddf1fb7d190f014b9df1665455147f47ff7fa1ffbfd2ffdf4025da268c8216cb20cdbb9dbfc7634bbb885c03a73182fba87b5c666da67d09a0b4ac0a4ae19160c1e594e2e9c0b4cc7bf6489b51451a0f1a5ac46ca848bab7e6705c59d1ba48cae433b0d7b43002762134b9909b9a5550f2496a3f098c8fa3f9b82739a13a59b8aacfca209a653d14d0ce2fe9381cdf8ee42686ee803e8a4d52e16baf05ee3489d9e32dc21331dcb38d8844c247e5772ca6ab85f31fb4d9eb589696fb3f49d278c2e891e901b2f8e17f144ac00ea852883f68b98fe512cb9fd733f5122e49a1b6fca44b7515c315195be1ec71e1d8192863aabd894d4496104a5b325194c1c681a6c437cbe3075e547438a01c8a2d58c21220fb0ce4e0e040de74bae4eb74a72ac367e35e08b016e8c94467c23eca8ce0212b8f225b87ec2862258008dd0987b254b86b4d104269785d643fa1e04ed0e95ee0d8466e55545104479f6ea0d4492ce3106fcb36e2117dff10622e41388215d1a6d980df365445ce7f9fc331fc0bfe166f4fa5beb1c705aba5c8721906d4f4596bd7cb8d88eed9b892aa9b4e4ac6f001a3f7c5dfbce1d3fd743a7f4fd072b4d7c665c1d94655a5a2c80741f3bd96b9f8f6a51a4eda0bee07526a2e815b927f8bed30755f341e0ef3ada851294b1bff65a5c3b3b112fab8a28301d8a975b765b1d95fe1f392fc01ac3910ed2b6037ec2df91bc9dc218c916859d3ff9d706c54b64476b62866f3cb4fc5d5e4cfd57c7ebb2cdedfce2f47b7c5cd7cfe01244d4a87a6ce506f0d1e6ac0a2ca1f5b69203fb421f0bd63b23218f76453ab632b99b0eabb22c3239ebc5e8d43296cf7734f8a07f4feceb1e2998541c12f9ba38112970172348e14cf6d3b9e993714ad714ead6b99357dc13ac245d4be712f8473d2fad54eb9a4f2ac325b95a631fa8b9bb1db1a6056a6ae485e6e0af442b181e2c26c87d97df52a8e696cd8c81d75497aebb1d1849f13c0cb83cf2c62089219c64c6a492647d7f1118110b1624bf07b6b360ae9c27b63d14c0b6fed5135e43d854a62bb1d97372d907b278d03d049f3222c6ba072a9896002981aa95cd64c201cb8a1cac5a6f2bd79aab628e4b3810f7338198d57c572355a4dc7cbccd745680c38eb4e9a20ea60d9ff186d897029064aa78ef74493328cbf0304b407c09105228c57cf0b9f3857a30e4a33c1ce357fb89b7fbccb9b2e6a1c04080093462e2d569fef2759421b382a9bd358d1bb11bcb27047620ab2822a4af0ddf4d2a7681216f09fd17443060cbe72c8ba16e5230996a2163c4f808564565750448a4f808e6b94cfef09bce4fe0a897c9625818228ae4b12fdb1c814eaa679aa4d29b233e2baab6bd685d7e49a01ad81d1298b283dda5a94a109b21a67f5200a6929164a8b82d90456c9f8e254059b75269934808a003d7853098d591fb260ea7e6b65a99ccc5b9303742c6402f712a1dbb3681bf6a24278bee98fb0efc5c208bda3b1791717d5dcbea0d475d0e969c28855b2a0d2721fc7c4f507a767a832e3ad00562be8e1e22aa07f3ee4b7d2a734a0018ed1da948f090c16a356b4cc4b897a06703403f91326b83950a24cd7d792f43e74fc17de9cb3586418871330d202bd561aabb64a675582a4254bc0b61b19a8406d37b619b48ff1140ed4490f2d85d1597a832ec59c24837b7350b29a520e462ea86863681af5903b836ead586389d73adf42b10d6ccd99e529f24d7e72bac215bf50de22ef55265ad372cf4d1444c3893a351a90648d941465ce6b7b81a0483db864040d0de08683f893c74ce36944d406a58a7dcd0780e909fcd2b3c9a38900722ea34e4001e01e74139821128b5cc9276f4ced2680d210f6e094de22165c00ce460a702fac9615e88258b885639e39a3ca1b7879bc33955c804a0cf804f22f1b8f82056a122d5dbac4ba90058193b7547a8b4c1702e108482772dc9f05db8538e97b56a11ba5ababf92c34e3d5bb285ecffb24d1121a18f6d82e52dd16c5abc6ac3135aa4c7308ab67c1829c728012c1e5dd42531fb69133eb2f23fc77c9c203fa7f49ac535c4a2827071111685fdf4521f3935cf0411a0e17ea4bd23bc8cca2c3665d0dcb2ce5443a91169735c687419a5ee1760f548af6d26a51671ba3e827ab0237f0428e6bb58e5c0e74e5a322a50192fb51a8696c29234f0d45e41b893b0b58f4b4385ac339f84a55b31760b18264dc029f12332f0f9ea5d48ecd98c5a37c260e0429de8da9e31a0d0c691e2f7a235ce4ce1e11b525c232b393200549dccdee841328996da05bf4bcc7f3b182a301d828c0feb76a23cb63594ba05f22aefd0415655507c4fe8e894f2b7556fa94d10d06f2cab800c052cc62011f86c3d09b289e1227e3209fac8b52aa27c918afb5f2e9c57471ba428ac87ff517de528bd6ed8cbfae51f4f1f257e235298677d562e945f16d077b203d92a5223531090e4ad31e23f236ba3e32de764c132e332ccea593561e3ea5e2e328bfc2fb55b432b2b1df984e57715ca9d008cc07f3f41b7691a00f77cbd1f5a47871a65efa76324b2f25c9f6d37ed42aaaa811c7b5cc46dea5606beae3065dd7910d7af8c778e2c54344c22902860471505c4f22c0d9af267f4ec7936239fdcf6409035b23c249bcdcdac56b18611bbc122e9f00986b01c4dbda46356a00f13d733e7680ca7e455f94c6126f95c3f7eda6a8358aa89c2cd8d0612a5f8680c387a4cf7a5c2bd8506885c23112295fc54b29ce9bf69e8c3610d58fd60e2e77dd8927aa7587745b6c0c3053567d35da8bfacf583d78fed081bdb486d43ed85e56f5719617d2e2b0a538af90ac310187607b16a03dd2e67de7e99e171edc5808dcf38fec2c690aabcb344d6361ab6903b7fbd5d3d21f6b598ddccd6f78ebf9a3f2bb71267bca93fc93325f9a2a794208194e0a0f930d2a1034bf5cf33caf299fb055760d48d8ea468a4ada935252126cec4a79bc26d0ad3d05a921b74a87b95d616a2c0ce42206898769b39d3f494b0ae69b638bea0ef4ec58ee1883bfeaf3fe00ca17f2a5eb51c301e7e388a38498948155da0e2cc3e24b55ca8dd6ced4642924fc8ebc7aa22c7dcef7505756a83a108eb570e82e83ddd96eac69926bdb95c10b89e08fb6c170d3393fd115466a7422040bb645220bce5ea6a2e4132202c11cee3a5a1155d5ad1455d688169dbc3a6f557bf2096097c249eace4eb82c065f4fbb44d6f954a614b6244fc9bb9eff1a26844979912021250bca313bc7e06e2f151c167f251f16d3806a1753a6975858e046360e05d6b9b2423b605466428b2ddbd637ad8f37c9304ccc05464a34f24a99e19ef756fa0717a80bf818e5c06d2b75d5b36a1b314e2b857e70f26a3e039b8db26be2fdfc9342a842fc76a3c22979e4c37e87d1d8a54b6bf64eda9b08ee44b47c4a40ac3ac5b578525b7687e1a41d6d25a99464e56e84db8d7b2ab5848180165dc88d952e7a5c4d514ad41f9a047f9449039587d769356da5bf9acff295d0ef7e81c65daf3281108e03e2602b7485ca9d17661a4f8a7bd326cbaf49a0c6b4349dbb372d10b513627062e2184ec3c21dbf0bab046fd53dd2eecd5a8ece1f638417b0c06782283d43e1562ee8c2a844e23b6e4ffb798367152b38595d0792b43072b9e2b3aaa037d92ca206f114aadc656dc8bab8eddc8ec7271ca6dcc0b023a8dde42296536dcd25aa34b686584e90281a80759a43d86200c56018d2b097c7a6c226877dbf46a71d5287cddddbe914d1c63166ca31d40d863b4bf6805c7874f34b5781b1f5d9571a58e1766983d08a0ded5945d3580e16fd7663aa308e5b6d2cb712db5f512c0c653697a2aec307977bd0052e069e8380e3e6af4edae352d651bc23fdc87babd674bc74f0121cf70110169558d6a269d943df255946756d9b22d8e3996c8c3d3eeb33adbc4934e57806e827e41572120d2d4a594aa1df1bd46534196d80f4d0945c25453da0535f49d9ec5a34d5c3abb930738e7c56210bd11ce9c200dea5a55bebd1f533a1c7053ca7109a0e846fefd80fa318bfd321bfcaf76ef4add783262279b95301e58c895219b1c31a4a215929a2b5b41824f40b6b2951b2b27ff5396c52f44c0f8fd4a25894584751131d5c7a5b630814ea2c13c2db16b2626c86c44cd96390f2e6031b954010bd134f447821dd6f9518e3418d9a8b2c8609e09ccb69cb6f4180e0cc75a024389087e82f08d21198713d455dc89d87434e70a9cc9b0dca8d0e078dd2e31c101fcf007b31bc838dfb4ca01e911667231e1153e2a04e3e4d5760653fb95b4d1678f3168208fc345d212c9109694f0454d939220fc8e732b0912488d2b8f8f06b4cac105b820067ae270774454031cae23871d86ed9bb1a05bbe9413384659e2c46d01eedae9f731b0d9b49dd1f6bc5c666a242343edf18db7073388ab9b03f642e95951912270b2327367299a41e06fb4656755c3085b02ca3d32093bcd1ef94fb05d361dd18e0f4212c2bbe22d11fa990f55720c9a4bb33fe46a04f08d3f9797e3d219ca63dca0e32be62892a8886982b4bcd037e32f381900448e0142c09ba1eee66f3873b5c611b2b65b4660f1152f85b63d2593f9e801806f5a3dfb401f0e44d2c0b8e6b05662ec2c17437a1c847459e96027449663d211c7a7383ab82bcb3dc456791d1614b0b76221598b8a9b7ff22cf202cb5aff043036e4ea3a36c87a0067c9d82b7d39b1b6a247ff6e05422fc859fff846d1a5591ab5d675dc50e2baff2f71bd2978a45dde458659b827b291fc9c118615c124da209433273dba144a3b580e38bbe5380e7020170f1c30c26dde879972ac9558d2e5dd401f34ece75522861babd00fb3b3c3f429a9e2836da28bb7ef2c45c3d6f2d7f47896b5f81bb4b573a0cf9c74b77542ed16c23ba891cf7c0059b08bcca54f5a86a427382572faaebf908884d086c51a6ebef29abdee177eeb5d151a8c697f4b9318006df814c85290042bd7819818c9bb2731d2d57c6a7974b17c6e07368c8838ac61103814716d252b192285886d6b1c4d0e8248e8fdc259c9d64a0d924fd662dd14f135cc1672a9fad99f89c334dab6a994289d8f41ef540e8a32f33a5e23e40b5f48211d401677eaaed557cc1810a2dd2cd670ebee2033b02e2cb3a0922b5e3ed92878b7e93a162dc7174e72990d7e47e001fafea7713db271bc3739b96d2ab747de061711ba734595193c68e278b583d1c0b26cd80c7c72f8bf89c06c66f997dc1e8253138d979f02ae3687370bab22caaeaf2c534ef4ea2df28ea5d56560f9c31c6cbbdc2b996999d4e6e11441e99e2409c6a6911d9c4db2a7cba7d7caecced5c463875b9a4a173b9a4a773f29e374fe724d4cc2b72d369b0251165498c103f8a1e9d97c21cd7c6c62be39a9c42b96449fa411ef7c6562e7e071dd9764df84bcb1ab9ae350676ae86dfa7f0bb8754cd314ce7e1f815d3855f145f011e7bc4f2c1e6cfa9b7ffa4c0bbdf4268576ee9168a447d3608252a058f65e0bf35feabd46653a6565709538f6be3a4f31f623d7df8958a7ac6a906e38323cacb191a9aedc1ea3cac251fa822476f27e1bf9d02d6f9e2f5c51302f62084811b9361a2c2911cb21ec2cf57b8afef059890dc4f43cebff0190c545dc211ab348d024f10482a6bb25e6660e65a156960ed254966d01bc6ce9a067cb1c1a56bbc240357ebe5e5f59204263372adbab5a2ddb1ab5517aff902bba4eaea3d7d864b75b0dfbe8892b4201cc67b738fb4f0c7713181b886eb293bdb5b69e84c0c5db659c23b6cf0a1290c8ec7d0625bec1906211887f4a4555ccc6cd9b9d8aec9e3fa8dab4584e10a4e5f70dd721c562dbc5bddee04ca801d2ed738e23b79b8321df924d9ae235c5096507a72a2296d189ed3784ab073751ece3eec53d1b4b09998dbc903b7cf91af36dd35a87232d12c0ce9b568a28c5c40adb63bafc99064a702fd0de1f228e8aedc92a40476bb66d3fb9dab53f02906f73141d8e61c0eddcf32c6b09370435ad38ac31b1e6b243a9cf0c9755d8a3cb1391d35b211db3076e054993cfec067ac35ca29eaae51da38722c0a0313b015cb4850d00fcbe51d26788bff20269f70a952ca056de24ad8471e3e60fd48e40000a92985ccda8f1b2e8be070739bd1e5ad95479e4130eb47feac157f75284131f1c26b1831b28e648d3bcff65e52abf6f078c73b541ad2d332e2c0bebce24a60395029c8e578181d878a52544344d76e01bbf82f8e6bdac1651c3870f895c0aeaee7161e828cef31daa43104c0886472195ce24306b5312dd98be3dd11f6dd227e0e3fa08f469bc4a7007882cb4c0828e06a0158e8e1c37f8edeff43f874c3b70f208436968e617089121f8db065b2d374ec8b858f41188d71188374ca2f3b6bcd36d3dc4b0bdc61111fa2e36be6ca742e0d5ac1eed2455df745047f9e8e1ac35e1a38b85de9e89a327ad40ba7bbfea303c63144e69dcf62537d1a1f776b55a6b4791412f701e021b357728c72d119e08f0e79bc983a4529750e582ae0a629711683b4bdf8e4d09a94348b41d25e7cac6cdebd14c3dee5f1492d9c57e8111c0e5e2e3fc25315272012d453862c06a97bf14bd3919b2f4a9cc731394378b1c8d09e2d26517a3b89d3be185d15f793457135797ff1fae26afe70793b298096b819dd5e63e88f87d16235596064f5715eac6ea68bab25c6e9f95824ec773877807b16c8dcec5585ef0b3056b17802d3672b2a05cbba961bb44403d33a4abb361e2fcc34e609c97e01a35d067a8bd81362a22a2bf66ce300780eb1ff213a0e4eaf2a94c66a69175cb385b5ec0410b3a09caa094b5ab19f3668dc6b2518c4c08b065ba5a9eeb069a059cb3f16abb7707f90cc419cb706dc2a16ca41b3a67a64e102714b8d14182d6bd58e5210c48a196c8330e7657ccf0142b7b8981b5571798467a0855f95b4e3ced298915c019a714f88e4d309fc4e1efc298cd37e7e21ede71c1309fd04caf830608b34bd426ff1fe14bdd5451eca08f9479ff0fa2510bc9f73ecc396a84dc8212463e627a9949637bccedcceec6fc9f742c09545f6f60cb73cf1cddef4327b732fd82f7e818f231864f341f677958adaa4866d30c9869bbec9fb51e7c56fb2b67b833db1ec85bfedc820083cf500f74d871aef356044d1db2cd65c9beddb9f2901b17db7f3f76f7f9ee09b9ad2ce37f09dfbdd08da931085bd1b31449c4d4a643d29ed16be1e55a265654c09ebc549ff9176786031c18f37fa5986ff87fb3aeeee6b636f3ddf34e44c451e314fd25a55c9953cf8abec050336f84e5704a4f5c7cc1f1c83b257499dcc2f5d83d7a89352694b9f82a323d5be9e0007bae0bb1e60a10b4f783c81e0b720170b05bf2f811e967aea6ec2d0ec5c29762c541a66a77ccb97695b53b37778537bd5de9b58c24e44e124acea2440e0d5f14be24b971ebc5ce9ae092114198eb46a5867c35ed933e8d8342d793d81f2057f003632854ff27f339bcbf339f24a82374244558db2126bf1f5981213a3026963aa6b4bd205d08ee499374a57acdecc72710618f02bb5e58a9fa29dfc81070929463636654df8a80775be5b5fa063fb40c7e29be4c28195088a6e2dbdcde564bc4d4ad1fe55af00ec438a7eba740dbec8d22668608f97fce698a8586e44c4f94c025fc3ef4ed3b556043ace4515c6b74e2882dfe7e88cef303a280706d2871192fec708391284ca71bd82a8055be9a195d7e437020a47836b264be13b7c0c20686c1f94523d4bc3fe7cd2ad5e6493bc35c74c99ee45ea5ec1544a71324ffdc4684496068e6069a447ba5a50d55873a2e941cc31b70f399865d2704cb3075277d465f6bdc85d901480f9ab502fcd45ec20e2eae8a1321550a15003ee83e1e95290d6fcea5b8b2bfbfeec63e029b640aff1098df684917f334f7cffa74201310d2935b8ec1c926ff2b464ec1b6548fb36907937063c2c63f35f31e3c30050196509b614ef37900f1468e0e5b35e20f879572e7b990b6c0f8d5cafd6c2c575de834329a997ba6b681be8aee18738b49391ff43da843510210589ba2982064c105ed2a57c8af1fd7e8c3ec43bfb48e9bc809456a387486d968c114744a1495d71b0550759cf84dd92e0705bcb18036174a49bd168826361e95db2b5e95313a782298240fff0c886f0eff828fba6abebc0421146b2627f1d21589c4beba710c45edf8ab5ac1764efd598cec94f3cfa59f338016cf84f1cf8cc34f8825e19c80ed7adc42181fba34ca7d3c0acf1a919f8ee483c1feaa0eab6d28f417bcef976a2def0a086709e92097ea9bd959cc886e6869ac7000edf952dbb26bdf914788bb81180c1e0585f5202045d8d1c02ed58d17252045ca145568a44ee0841617aa22d88682f81a580aee5f3417510b5f1e78ceccbdfa3438f969317d9e50c24a0718f04923bdb09f0d4a7157bcd08011c2c65d20fb2c1768fc01385cac77013cb4920fda94f3505638f4e06e7dd092f02a375e0c5b2533ece1474804781fbccfc162cbbcfb0d03e2da2f3c6cf1c6c23ff00ab8e66bc57ef3bd4fa48eb557c72ec52a025189cbda161c7b7b47e423ff7d0dd4035866ebd639bdb3ede6ac4e123febb09cdaeb669d697f159c02c5f028681fd44ff3fb3eb2e47d43eef031e871c66499ac0daaa35bde9b120f806ef5f846143ec43ec2bef959c5becc9bd4ea6ee97a42dbd567e2cbcdc1a7b5c5981c2364b0ecdfc4e4521ef5ad85516751e2e5e906566077e4f01e539ba95bae557b8560a2fbc06f62224b83676a5e8b1417c9b5be9a508542fb17f2535e79e64f238eec2f6e2f0741de9464062ab2a6652f1a1bbf719642d6c7e33c11608001a8a8ed846e94b61a3b96e230e97fd0e173c288183a3601189a7e2c8213a3300b3b2122e5155b44bdf4bd348bc07f9e4d223bf97c249182358d037f9658ba738b8d126e15258205deef98b7a310d2081986647fe3ad91eabc03beff14e3213a0010e5acb402029a0b4c2111ca79edf418873bbcc1704c7a3e96f9afbe83c060e4eee6d2175157b4ef4b57aa2a4504d9c1a1423703196d1042e8e6c5dd7f2f06c61bbbc51f8c63f4e3fee8f3c1cf7caafc964f2d5dbf89820a9d080aba41107d131c840e86a4705a407eecc032f882307f2e5c86f3dc6f59496937b610cd37b93276dfd0d1498d0cc288284180921f1b12760f7e482951814e71a6bb995baca44e18181e313a36fa08b3701c6e46393ee1fc88327c339c06237abd96d2c35b3efb865ed74995357988c6a2b3b6f3adfdbf634e294200cf00bc359996ebbd3ecda6ba1f43652c6595839a23c697913c64fc83f4a994084f189039f238af914439f51a2ea62a3f9b8fac86514d4920880e5ff89039f9178fc84ff58502894763f67e17fe79177fff333e2ad4ff8ef33b6fa13fefb4cfcab38f40f359413a7cdb48dfda7d1c006aee849ac884818d0ef47240da264823916c02f9f62e873cf98ea841c037a3336f079e1619a9789bf1407f43f1dd1e3e5297a3ffd74b24bfe99ede877e4b025972c03462613c24031f447d0abf2917ae9e968636a04b3784381ac4544e0b12cf5025febe73088bfa3d8b9e013018f0c2419c799dc98d54c517fcf030b5f3fd3d7ccff9f23ee8930f7228c6e44a079c475cd3d9a3b74cd9ddcf206ca52c079012ebffbcb860f87f2a49d25581d4450c09f4831ac55398d223a6534b9c8712d90a39d7d9233a38da7576513945d8c2106e069fc85190c3ef2e91e1c13ff35beca189a10110f282046fe3fd29afe648526595e0b9eeeaa1531249873295208a72a12bcc08bd200f5e512703631a7d2284d34cfb36dc827e961cc27f5318688c458e69c273a0106fb18667da4cd8e5b90ee24263361c8bcdfea0516e87ffa69aca8d250f639befb1c9455ed4a111d98733930fe7ceae5e38d6de05ac2ea7bce5d6ab698424a00c78d5d0106e281de50fe52f303b6b0d29c2c3da78257cb84952e421427c92c8d66d25b502d364a673649f7f3e57435fd73524cefaea777d3d5675893bdd2b2e9c042ae8d1d21de22269b989e16cc985aff8ebd147ee2c067265168678044025a19fd6306e2978c937015502bf2ee30b3878ef62e8fd938ee77925eb9b4fef2184f2674a5b4565a56f8bc76230e498b832bfd4a35c8691ef1b0d372cff851cbfd4d5654cab9365931401b447d05100a59269494a0f22484ae8de576bb8c044b09a083fed21cf8811a7e994579fecf1fe1dd4caa188c1ef943e7a44d0d84e1c6fe9164f8d2202f2d8efc4c58639e244231210d354612fe154f42d5625d47b94d04c43e63166ec9de8a96c3b5dcf891ae56499f3bd2d525eb739f12d30bc2d2db5e39fc95e3d9b9c8292ecd6196a89e1d464f9ae5483400119a795c067858a08de82c5f257069c5ed249cdfa3bbe96cb49acec151d862554cfe9cdcad9617af2f2050ac3edfc3c57c6fba7217b53d21426e71214c26b306163663428a5606de73a4183bd3c518de1cc6702d45fe0997ae95a27a70b2224c2cf38b83690e5dd78256085f8875887f44553dbb78980132b3f388b53846ae95d4130813511684252ea4535ff3620295c1de5c5aa12bbc46e9e8a1abf17259dc2f26d7d34f31014197d3ff4c8ad9fc6eba9a2f80f6b0f1aa132b280232be4583018cac4852ba84586ce722565766378b1aa1203282e795d9240b8d148905286b053e2188b6037f28ecfe36d28cec7846926b6ba4a9efd9d811ae3adda2e7b67d6049af8dcd7cd738697d7c651aae4730438213f26c3c3bfdac144cc9f9da5ac00bdb45651a9472a1a786f172891e50884e93d14d5221b5ebacbc35026d22c3b945fe71328f3aa12fce65243c88c45c745a315e2e6193a26ead044f71c9e4781bb50e97c769152f55d3571cdac4b24094c79d54af892c8a88a83773f4311612b28d598b4de6fa798d61cc7af735c1b797e3b7c77beb9d2feaf62fe802b7df62afa2f33b1a7d0876740c00364ed13c082a9069953db81273c26467503020ad7bcff339508ea4d254fe0e04d40ad4f852da275414646fdbb8ac4ee09e490389fc43cfcf2880326b0756e7f55331344b4877db4ea0ec8b8cc2a8bf5c995b3e8e4f68b87f45c383e8b63bad5d9056e446200058b6fc3a2544f1408ec74eccc36a1f00b08a626daa63ca1f6279d210e7941b706f91578e90941be3583d22a794874b440897794ca750762095c2e6b4084409e3375dedd507794cfaadb417a00a6416028661ff1d9918c2b1908f2976b181ab7f9e941d211bf9f8c0484f32c85d80c80a1c9222004ae1a410e91512fd826c38006922982924ba25ff242dca4fe074cb4969241893ca9549df4bd4d2443eceb774217b1e58d15290710f6ad9027be6efe49e9f68215126f3a7345a5113ce13c5017f623952f09289463fcf003149d2c6f4e345becce247363ee1e51bcb7b0e295ede17cf8ae13a8ab42eaf93e1d23350f1ad259f17dc5fd0266c06349a46d15c5822bdc50a780d1efeff44a30f8b64c4cb869962b66cf915e958e7a3df0e90d3fb2887ce576d88d3d233d591973c87e38ae42548cdc956ec56fab82e556e71f094db23f0330abc688ae827096ca0d82220769bc509b4b8a2eec0a25c0e029f7bdbcc3ddb6780f14fb7c49684f7d7c64651a197cd121fe38f325d97ea46a133304c30da2c5c83f511c69e5103ce6b0e01abce84961a71b8cdf4bb8d1481ac20a7409bdcbc2d4c58afe7a4271b69266451d237d2552a1ef6e5e900e2b5db0df807855f081f37681589c2459048563210d74ae392677c61c57e1cc63a37b2c28211e5f606767c023afc12aafa0538e04ff0fb99cae4d568b3332be08980574898b651754d43834a73586d3e43a2d038d82dc4eec0e8e63c5e6d4048198a0a9fe69b15fb7b22ec716dec98c46b64ede671357d8abae345329c8deb1c1a946fd1bf3a5159b87519cd4977c2d1140251959945f22d1264ac98524a04a01b79005e1b4bc2810cdfe3cb42817249cbf3841ef8371bdc330d82bee25d4d3734ed36019100497eede53e314548f522f571239ee4f4ca9d5aed44d32a789e91f9de6497240ed1446a271c3e66487d99f63560f476c2bb5bba0a528372fe1d1f6aa0f9d337644913798bab2ef3f5ef5aa389754b91d10b49c76c80cde41953c33c0cc5badb6ca49555ce88c0c18944a1575a44158e0ca423e86e98d25e2b5d456338e4e5a886b0225664aa8cee1f541da77f260eaae9a299678244925dcb3d6d7fa3175c6e3444635e96f49e1405d3b4143df6a338ff401291cd669569c094cbdcd03d2381c95b252c285003a76277c23dc4927b2b66dc13126ab9ef03c828ad6f1d9792709dc0e366a257ec462490498a950cee7aa76136bb6c6359e02369bd7c277a8f5323cdf48e30989965de9b9d8747a0498717054a0169644d2a000fc63d9c24ef27227794ec252d56564c0f6b10d27811939c023f91b032d921a68445c32689a4c963d55ea77bebda9b80acfff92b9bfe7b032656705d198d07737fb2f97336b0a1d35d667a662437107b3e4180f17aba44417e07d1ba54269beb9e3d974f0ef6376a3ba3875160fd7204c4cc17f13188ccc01aef67aff9dd332b0b81b538b28b8c5c24ab8a02672bd8e56100b294bc36db2b7aa52680e3415f9b2d994be8ae99905d3a32f3def4e3ba6bb25565b6c22abf6b54192f383f3f09445fb1cc46137c579109a070e2266b69d061008db4242746a1c58180756c92980361173b2f2b6667f6aac239dba9ed0e434007b978bd259971a088f70b5eb7551ad9e4325d6183e82dcaf9855d8b7072d5f4f61208839211ca4cd86445803406ebeb4f3e321f0e0d8eb8355e5fc80c13a15f747e6d329614d2ae6800b2f446272b2158122b73cd2fe0e03e46c38ac8ff42dfd9bd3444d01b8cc73511ba31d7e3cc32eaabb426a72139ce2de3f8656ebef61c1895af2e0e0493cf7169364a2fd20da1461cf298224f85a2f3668986661c4c04189417abe203935b93fc21427a1254520c85011459c42982689453c46d573055efa22d868bc61889bf8f3e369aa88070a2696ba5b7c927bacb8d958a3adf074520e0038039aedae8ad745875b4da44187021e4fda160fb2566afb0d8c86c41e396d25fa9a6f788572f0eecd76922cc1a10efad6ad00826d2f13d28e4ee41487611ce66de29eb3c8252891c5290378215aeec38b8ba6b929aadb42c6bc0818c358da3ad812a1fb3a5547e030ef57f2b13894914e28128974140415bef0acdbc8b7c8d8654c94f786ea3949928d1c5ef6855559c02585c543ed230f4aede7f63983a07fd61bb1b1224bd5c446fd9f1aacb8c57faa82bf4f7f4e395125ba3f9e0e0298472b3712c944b9445dc4511ef9bab78033a210ac287bca629aa5cdc9680986341447de5713c2172081d15bd4c4a4bbe151f3a98d08a7268dc54b1b67e212a25e87e5a0a97c6653d753d6c56f7c60fcf224240185944155936f0ac0963e4a1dc75a66db462df33a3c8312b5fcfb83696175915cf7278950722d9e796fe93b02dbabd7ddacee0cc884788382897c924ca47075b1c97c22a8fc3be60a9682864aa2b55b2486fd687e8ae3981b847d502084e43c122720c115977d2b640743e499d0071b327105e2ee4056af19a185121ef4ff0269ae7c6b140a1d86d46bd783006f6600decc1fb87074720757644e218c511ab690ca3d2e4a0dc8da837311e6a89868cbd18442e7b6d2a72fa290a90339190978764faa4dc0c0e5274bc4514163006a1e7712be57702443f0e89238a2972d94adab19f7ab1cfbd582e69ef437b80b4fb76a2def42e8186e5879792bf8629ffcaede869584edd1680a9227c29d82098a72699eca687060fd1d61d70761c6d2013d9961c22e3545a7e95b55ff9bb5839dee75fe37d43dcdf70d48422136107963c5b228328145834a0b95db7dd02a1485160db7b70714864eae9e6247e91e90d5a3e794a6c5594a08b1abd95d126955695eff9b1e0d4627ca3892ffd1d64b54c951067d7636b2be1058fa356a5c4be40085aafbb669979b7b8cba2165df0d80613aa52de81f78f8230dc3dbb3c1575639cffb833e87a0262d1f704b39b39d5ee460edd8b38b221e6798ff7030253874bc98bf291ee0e69366d9be3fb56925f2cb4d1d848e5628399d23463d992402146b49dbe9bbc1f9d1a05419dd1bf475c6dd09e13466cfdacd1ef905fb8935b6852ee6d829ad1e3f0a65760ae4dce48f49d61c336741a720f8fd4402711706d2cbfdda5343d34250e18404f644e6db5daa852448683beea6a0209a4ae96bd3401f710b3da9b2de8706476991ebf065786190b8c9b35e2be345eef9e8f57f92d2f26afde666681bf3e1bd55f92c133db6306ec7529cac70addf3ad2918f595142704f7f939e853dabc5c4ec47d91d88e647548c937bcaf8d65033e517de9dc331bba13324e1e5847a461d9cf2d4d32b8eb8b2bc30612077810c1c268a5b76c61c7b87bd3590f3415b78c01f16a56910c2699e243149accfcef4fec0033e6864def2a7988f7b7625d4f31146829494f4fa238cb7f547e77dfb3d574a7b7c26a61433df7f43466ee8442752e164807cf0974110dbb7b60b2b1ea0323d15acb8d9f9927665ec0142b8b7bd3663174b8910102774cb506021c9b1550bc69e9ba09d713a650e9ed35534dd533b34e7e193b997ec2c5913409d112964eca348d99e1f2b3a50a56789999233ce3d3cb9d5591803dc713ec3c244e1cb8b2409b73a5652615e22c6997ffd2bbb4d4dbc7bf3d470001dfcca677c5f46e35793f59500cdea2c940a34f27b1930421b4f87374bb44c15613c5b30efcd54ec14ccdf10b5e5b3ed1b77c84675e0610c9918709878f347afcd7a05726505818f4aff4d8a1a9f84a35d27974662ea284b248419024d91c933c68e503e2e8426ebab8a37480a2bd356b8ba16de87d09cecab080627551ae46f91cd1f791e40044e2f129b34ca8497611d720c674e4cd963b801e0747f4c2b7cfeb8a57351cbb0878d0ea2f44fbf1e1fe5e8e10614e92d8ce71ea5cd8156078444e17b5f2cf091828b4c30e9e0e1ff680fc2314f950c494b30c88d695306f2b6e6e92501251368f0052bd6125d87d4983891b20c0338d008836636a684d8ca1907195ae1d4419725f789b0ece9c4da71a7bf201de83c9f8bcf7591e4030c3efd8618c19d5b45f7f3d5d0ed9dd3dc2a3d921743d5fcc46b09d0ad80d82bdc46e1449e25b7ac208b9cf963c9ac11548618ff185846b740c44437e993e97e07ce098be8dc9f23f4b03cbba876a25626008c6ab00c8a141d3b3ccec381fbc33078ca41cb9dc7e8a2212727ec02f7a2a7765c55e24c50cdf58eeec93fc99038018a4fe19ffbd05037dea66c325f115de90a8829fb7048df38e666c451cd028d20b8b32cab45ec5ef493618125c459f07d14e0c509a36a67d8962e5a3c71c12eb994e98ce21119dec7362b252817af2968c71eb74e3386a92d0d0e526196d17704748f2cd30bebf40daef4c529904babd5892554650ba6a16e55e4418ed94670bf278dbdef1eb8ef1b87cead911748d8ee9307a133519902ff69e3c9d9a1720c9ee3a8c4924f76934e2478866b91dbdcf4b5619e9de140b82f9b112daefcacba6475326fb5c01a280e51f8bd53b5ab0382768e51e38fb0c6f3019739ca9aa4a02c238ae231a4c32918f8e24e234e266b99354c9485723efc9052140987ec1851def1066ce7a70eaa73a8978a3bd7558b7efd80ce713073e9320852faa71134028027e8ef36640964834f9e409198ee59938243702c73a0a99d0043a739b045b67aad34d5d87869ff07273e67f294293101f567b43e6c34daab08dd722b37ad8053bf950dab215355b1fa74a0942cf66773ef0ffe4a52025ca9f91d80937a64c21987f52c9476f89ca37162bd4be27d1de285ddd85f546174f800e5899253f9e05a29be84606b745bcbea22bf6a3c6d965eb54cdee6aa337da28dd05ef0f3def131cc949ea4fe95a5506fd1ca1788c3dbf5b853b4eb89e38f6644b5f3db7fcd865824390dd719b1ad843b1b99b8cd7a97e8623e12d08a520ec20bc01c776eb8bd71793fbe5f4767ec77479348787587ac304a2a30db7bedd890fe89003fe7bd17d00dfc79db0b29a89ad56beab62312e70652ba1b7ec2347d698aff91093a022d6d5a695577c996993ee2bede5fa51f9c5379c5135e6ebb73e996fe671dffa229f7ce6f18c9182b365e65e28f3aec0871942c6706d81e078fdc4c5db0c9f62e8f3e9aecd2c731230a2da225dd48c4707a28a7cb797fb587ecc59ee725f646c366a4b192f5de46b0c2284a3053d9ebe537a9b34d6104ddc7a92276c7adacb08a4385e06781fb644e6a99cf1177ebd07ca54b36c37b9a6cd4d23462f39434b36f6d3de2db713037ce65092650c1e0f29c53dc42ff97181d0aa9bd80cbcd29412239507ba18caf1482644e5260cd1a540c71f2dd263053e2d1ff682e97cef69efbbf9d5a498dcfdc9f663b9f37814d1cee33b48a7e62f46b3ed0da7c01b1c6c88662509ccc9fc89e1649d47312d0f9e449ce02d2f300ae0ff885e12da89caec3340231ba3be4a863872df4908233345c2e758521c9e0a072a2f6c16f04ef5411ef9558c7445b50f643e63e4d0c91518deb7756e86850f337f14960d469f37e519847bfd7202384ed0558bc2e730e2130410c21775e47c43d250da30801ef041f193e7b442d6ab747f165e26f8ed8574a1e07b2539c9ffbc90e457fef86fd4216f7e7921d16fb008e36b3c6fdf52da5f5f48fbcf8bd717372797df31d72f94eba59686a62de8c62da6fe8d52fff385d4ff027f337596fa7f28f54b5d0c3dbbe48bbe989c3bfbaf17928377cd65bc308caf9d738fff9d3dae66716ee06e185ea17253cdfed5db3ae05dbea6242a7a478d53bfcbc2615caea5ac8842e91c9adb66440bbed2c08f6c06f648ecf1f93a44052b130d62dcb1e118a5d86b693fc2738ef82026c3aed2db98f68138bc26c39d3b78e0153413c79a5f6a8ec0741f51562bdee82edff54035bb4e5666923d8c11d3c65b5819ed583a4752db3bf1b416f6d2a250bf08349d689d8cb7d566a3c5fbe9dd92c8bddea76d667e92fbd54327f89036d935eb28c2c8cfbfec23096740576e4d5d3f2b3a4b0b5b9ce2f83c96b76abb95969fc7e3db85290d316fc0018c7740f16622197ff2fe9645ad14786b636c892395f58c01bcfaf04226bed7079f5666bba527736210bf00fdabca4758a9d9d77030d6fcc00d56344f207a1a3ab5006b6433587dd21e9ed4bc6ea2b0976223e3bb7ef85673a79fbfe65cc417ed52f9d9abc75f3ae7d5e6183f91ff1830741ad7b20fb892e4ea3442de4b9f476f84cba34bf87acbd178a976cc76995be9e3732a2a9c322caa03577ee00ffe4e3ca5e1f0621ddf72144f782a2145960db1ce736c737780f9354c1ca569951df6253f7ad8f34fba6c6109c1b3e3148ea38712c54c71beb2ea49899a5e44f5f84297d11fe4f10aef3c7b73adf90d9bcd08ff5db2cdf5426e1cbf78bb901b53760ed37ab14e5d0ac39bd8c1c09fa121345f8775e981cede839d789552f4d262d7e3d04195dc1a7a23523fabc0aeb33708c995f492f11bf4b794791ccc83f97d1cd17af4f3492f9424b3e1a2304c5c953281578bd1dd728ad7d11feeefe70b7c904e36684676b2eb4b41af9e61cfc84a9fd9894ab956f872c7714239a785dc2afd9833ccb0e64e81c573e82f7823d54b78150dee0327a950f12ce95eae5b513edea7c7f45b7a2e353bc3ae2478e9550ecdd36f1578575f2b4f8fe5a1af51baeddd88b6b773391e372e0370df72ec86fc5eb7d9ae9d518c49ac50313db61b5a17dfdd9dbad042225043f43e1ce6f7ac9b75a12a3c5cf7c26ab270b2d1abd326b07f6e65e8856127e8999330122bb3e057b6bc7994daad4c8eef09b4905b546fdf8f5637c562f27ef2e93e8956ae64ad1a4502832c4caf7382d91b3eafdfe0fba4c06abb709839921b91b5b695ad049939ae7841f345040096c74ff5632cd219f8eeeec3621ae9a67b7e0e2d7e2226636c2ab492c60f2f66863dbe252ae1f725c811f02d61c4e402a461718650f30fe2807c34a0df2e3e65960d368979621ccbce0045f17172793f1a7f28269f5693c5dde8b698cdaf1e6e2745f13320edc6541ddf94771eb6e42c828a82167e61718f6459001feb7e2aba05c9af83f04d707a64c46a5117d6185fccccfa50a052f08b7b5734791463a2a93000ec6ddbd6c72b591a2bbcacaef2724325f17dbe25bd7fa0e53ebe6f78d465117ee84db130b49c8c9f4ba077d9e89db1f84837791ecadf1fd3ae5b87cad720ad4acf9445f0f3445c9915fbfc99c0639338de656bd17560969594365337013b233a6c5ba2294fc05e3a7cb24b3ae0a136d634635aa104fe0504bf44fb232bf8e0643cd1ddb1591bf26f58ee64b58ccfb8461020aa04a44d8b097ba09384b6d35951c841fe41ef6a5516df86e3a7b6a280b296423fb4e1c05c456b7ca5395b23ec234a103b7d529b4e59d6489d22127b429f2de9b537f0b050d7f98be76dc01bbd475a0932d765eee562ad346b27f6f89850a550ca09576a08dbe390ce441ba53d186eebce82b56913232e86c84657cac74a1cddbdb04ef21b91aedb6c14aa4ec25c073e32b079e0aaee5fe127cc7ce013df85c86fe1274c7ae065dffe1c6281e3fc37c4c22780841ff07cc7d6596120c144045a430a51b49313ba1235fa0c032fb86aab3c85df41c4bd50ceac4bd71628c83a5e6736fe85cf54647cda0a9e7ced8f049cbf35ffd671f062ea25bc23093830c176c6fafe87dae8ed2c158f1bc3fa3ea8b5a694ce2db28ec532ef4ca3c8f74caafcbdd42a0301796aa216b7782151f16269a5a8a5ae84c524bd58d6a32b93448cee5e64024777dd11f9f624ed5ad427230ab9e1a03168f2d9879aced387b01827b0e0432c2c965f7f86f39f996ba936b20e5ce056d6a3b6ad552012626df1b59aa5d25b7216e75a59f249dd5f2f5922ce880f7ec53719ad95a57f6f45d30870c03446c9624880546e5ee4ccbe3057a9b31da05f0481d81f6439347c77a6d349521b62f0d4a0ae901fc687cde88d454c3372948ad60cbc16dcbb9b28ca47a6f7d06892893d8821a507c19be40e16693cb630f4409f6d3a5d66c291a5f43d02706988808f04a30cf469680afa648c9492b0c931aff1bb1876f8589db051046dfc2ebfa626e8896dbf639c8d84f0c86e3bbe188aa7db3d3d25ae7adf9cefd6d7a286b9db58292707f601a54dc5575dc307244640d4b5d990e23f060311fba0c87d41a83e64acf8fdbd007ad06860104a7df0aaa6e0494a751a4d0361cbd86de13c3daae40d3f954fafe713d9459fc9cf0ddae88bba0e24f68a2e43c66fe9d623084802560c69c63b593e4afbeebf7f46b11d3d9f0b812876858ade45385246576094b1957eeae2555cb71330ca619846cea96d94fd3ccae3657a9b62b4dd5ab9a526a3ec1cdeaac467fbebdaecafb39b3527f1a96e3bcfb4768a8cc0bd6d0f748f676d0f4652b385a840fb029d5f83ca3b1690b2c583c55b85fc025e59c882b5e41bcc74439d8539b3c96c5e2c57a3d574bc4c2b3cba5bf6aa4441e80c9f0ca67f3b40be20370d2d837683f001e5f651f6a01c9671816f6f27f940ccca26403bdf04d220ff049439fb6548e2d430d5637ebc02441d2cbfc5a277c271a1dc2e8e87843c25219cfcfcd65d0388ca925817213c48212dcd48d3a1bc80c81876ec14405c72122573378a8da8923cb317b91640a9c223b5979df7882f77061576c6c9535fc461ae41dd55e35ba846435e141c34cab1d11009f1e89ba0d457ea09aaae46ee26104837521045370a9806a73a3ef32d3510a7d7c696e91a2301e97567663708bac4551320d728384a16ef6172df87594154dc590982fa9c65fcfde2f5c50760ac1c3edd5f14f89c23f00c7ba442e761f15fbcbef8236c10dcb471c1fd79f1fae22132b7a1e3e2e2f5c527d8ece0cb3e5448ca1c92b34099f987cb004d0e2c3ad74a0d8398279a5363a62e9c39e8b141da8062603443eff28e2d532945b19c8c179315588c06be74595ccd8bbbf9aa78584e8af9a2f83c7f283e4e6f6f8bcb49713d5d8024a9f8d6abf1fcbc43bc0994c5e94decc063b17575919ebf461c8726c1c7cc2b1f0c3bc9e60ae78507695b61a5431951d8c709cd754e5ec975171fbce99cc4070c313c6d5ab8f5f144c2327ad91af4a5793ac22b9d9360248d57f41db5267bb5bf4217266105813756015433704620550d1b4224762b9ad53d82d171f8f90bdeed0537bca0d3c4977f41f473f1fae2002fcec29de7f03312a0280345345cf9bf787d3111b06dc3620e3fd3f0f3bb40be7fdd6d7961606cc9ab77a3a2ca25a0b448257e10809f409805926436922e7d747a00b2493e46e7d0939d70b25a809f381bfd1d86cff7223a90b3b923c43f60f90b90c9c39111364af8f933fc7c845d42be89bd24c9ede700f84ff8813bfdf0a4f71a2e95841f09cf27879f5df851e1e74bf8795ce36be4b2f5eed298c0d13a94f8a0573f6a512fceefd4369df30f2e572139111886aff424bd0965b7e1e7aff0d3841f0d4f8daf4f5cc9832ec902744db40f557c58c77b212b2b88a8e0e793c9490a7c205f7521f971cd1a6b408c5ff3ab35115aa0b8d8f26225178929c1689d3b2c0e90cb0019879f2bb0b95947e977d2b1bd0fc0ebf073b38ea273f49ec2a288089942c30286b0a673f5115c9cebe831fff7f0f943f8b95d47bf46ec27e8502bfd485a8159f87c177ee6e1e73efcfc117e66cb510bd2c3832c1fb4131b1013d519b1af793a5160a8b2ea176b6272594a1f6685877d193eaed6b9f506923731aabcb4cf2c3c9e3fe587b91e42497f869f8fe1e753f8f91c7efe137e5ee14087050d6f96869f0ade86ad415c87671a2028140ccb32d93654111bc9ddb1b274fcc3b3f43b78be49ad6bba341ca25fc2cf6309efe10362a0832797c044e03473f9a3dc3d992f2ba397de908f07e5eea575901928925028f037c02306022f1ce90f2e5b42a0246ec3cf5f25de2b018f47c46d78c092a16618d812de5e0472b164ecb33c3a2f9beb5a6cd1903ff7da3ac5c7307d007670872afcecc3cf21fc1cc3cfd7f0330a3f97e1671c7eaec2cf24fc5c879ff7e1e706ee9d859f0f259b98ca6a1ea6fcb64c6e7641063b0b80bbf0735fa21011acfe0bdb6910e5a40727699ac22206a16909160161bd859f875e6e57ee64e0bcf2438ebfdd19db883a2bf8cf90f563f8f91c7efe137ee01e99a8a237f22aa994a2a6292b620ddfabbc9a07272d18852abdcd52e232037d00688fc2cf1c56586f9b4c799bf0a18f2c00b8cc99773e7f490a604b7aae2c03b1cdd9da1cae6b647231c434eeda1ce6b6525ad40c218a995fef811850bb987f8399f714c45b3fc08d85e892fd088708df4ea4e89cde2ddb5a5591a57b082ea02c0aa14a8c22cb56e82c46f82144c74ce7a748ca89f12c330128ffc6e8f4f206dcadaef1828ab12dbda9eec53af91a30fb00faca4282af86bc14d4f53c5e38d9d4c654291a0e9e3c66cd2358b1b3be29414cf4a402a059c08c35dddc45d069393ca38f600a1f7e1a40c01092ba53e47711fd31c395cc668de8a6d92291bd45c10f24316012034ee840db0a3a5d900ec14286fb0b15bfe119d1e12180c25930058bca849f4a3c84a255cbb14ac049a5f832cf55004f80fdaac8f7cb356983dfc3015c043632d4016761f8f93dfc7ca8b287ca52736e0189801d056c25e0aac3cf1fe167117e96c05f57995a3632060f15de33ca70e79f01f431fc7c0a3f9fc3cf7fc20fdc2c13b0c940a0120d123748f6449767f716d0039a1d4bdfd964f12293ab55989f8d64d33d76f5cbeaf69080b08e2e651d4da55a3c3662393b9420229672313deb565413c8eea625a381ce79f2430d2e950234fc7c41b9099a2281948b2e50d0e30161b1c8cca8bea517221af6f8463af104e01d978122f309e7d55f24aa212d4f25bd00f99643992fbc42a0d0d41e180ed42cc092c684ad708e04981e98eb43f87a94e027289c53207603be1c965df899004f1b7ede73a549477f03132aa35e93e1bf07d00709d750407a82de4f6014204d6e827017beceff3feafeac297da7fb1b85dfcb5df799a94240459eb3ee4e8831464044c4aaa7ae4244e6416678f5bbd6faac4e1af43bfc7eff6bef7bef93403a3d0fabd7bcb87d26b4c40f9d0d2e5993d54d44066c91903a4853e686d266a547931e2f3db860eff566afe93f8e0fd1e9b3ed02fdb2e931f31d522946ef23259b3e97f369764ad78ee2d754cc505f9dff54570ba283de6a0516fc1acadd43ba35b3c4e164fd2abf5468bdc3b694cb5dd012427f865370315f7b36aa9fd5f0e2978753e7fbc1a90b7ffbb5dd4b55705208c3a6461d56c9fc64bd5c5ad3cf14bd66ec8f26801e7d7a0ce831ca72381b354d08045fed0ee6cb4cfba5d1cbcc17f02db5a6615d16c9c9ffd32fe34f56f2e92c56bd0f11bd2c56bd8dab7b37fd8452f7e27dde597e583704ec6ef5d391d453497a0f186b63070ad0a1124b9b261d706b472c1a403e9f8a16dba526bdd9067cc715634de2c43f991f6bcbe18c413378c15fd44afe861e257adcd2a3fcbfbcff55a0d762811e457a5cd1e39a1e94b9c85f297391325fd1872bae059209164de4f32cce6325d23cda402368859bc9b3fc2fcfaa9df902972d70d92b2ecb15170af47ff529eac4505e84b8e633c5849f33e57c305bb2840de5da7e22d0496f921a24646fed93376bd3f066ff0870dc51150df653cf70a0667dcb07e9c63d4d07dbe7340d1beb344d6760f6f4c3915a54f4d0f430e0ae31a79c6fa25967920879d39c4d3bab710f41d832c6ea2f72273fe5f579c7d1a3428ff037adb147c4f3f2775420a2c73d3de24f173dc635e5e0e70f279f25c478ad03f94872f271c6a7fff1242dd309b7c8b6f5075b3dc9174da7bd8f6167dd7370f21ae5a8d3e3e924efc37ce7e46a9cd6f33171ab78a68fcd931cd053680f7b8ca9bdd0b7163d5ee9d1a6c7db279b5d124861793c3d3e9850653119fbcc610a941e23c6e0d83883fdedb21a315b8a2006ea70f211ec1743500d026dbefa69e80b57f3f434d39239a4fd54b2202181d7ece437f3f46bd517de3b19278ffedb744271a14edfb30a065bd6c67219b029e2b5e81c2673a6aff6f47aa0c7117e9e688bb381053d0c3d7c7a04f4a8d0e39e1e213deee811d123665c901e093d1ee95165266e1f2cd025dbf3f04253ca535fb818290393b0dcf485e72c7d6b50e667c617e9f1428f163d5ee9d1a6c71b3dfe37eb9c31cdc5ae24070e42e5dcc09dbe30b17a6cecc5764103873361356a098dec4c2ce9341cb82b441b8249012ec8e195580acac18be8f1c5d95908c848143d362cdeb3cea084dffd91316b7b9d7e6f79f66a97da2d91b24e049da655a4c7815d46d2430de0b38186a1070cfa681de911d0a3428f901e77f488e8714f8f98cd7de991d0e351ac4f1da8c21ce56c169877fdd95b2e337bc9cdcad1d6a47d4095d4e851a7c7d38011325ad241b65deda43729ed851e2d7abcd2a34d8f377afc6ff6eb3564351a9e00d620e00d43ab38cceacb3a3ce3547a7c0d41112c0f72f4465cf4071e45673b1f7e3c0f862b4718391e32d10a1972a73bde7596123b98a66238eb332a23350b364d3f19549004b9bea6dc9b21f3ba9875be4ac4eec631c18196ac354e42dc22ec64e6cdaea9e466c896ee4c32d356a0c7811e477a287ae821a3951dd10730f45aa147408f70f8fd6669cc3a8bd5602e268b29ed704759237adcd3231eb2162d0bc568cfd0e3911ed5215bd9d09a0f1d69f27ced6ad63e0df90267db315a7a7abc704fe9f14a8f363ddee8f1bf87969c99b1e0e9c3c8d6ef8cdc0f56d5e18952dff9133d3ee831a6c7841e537acce831a7c7173d96f458d1634d8f0d3db6f4d88d84929b6fd609adf89e120ef4388e2c18a3454eb14c354aad48b11b259d72d6868c0d2181805e3c9bef6692cfde99366aedb71bc57e70ae3e9b2428b0a6b60d3d7c7a04f4a8d023a4c71d7a361bae06bd8fd67c39765ebf3546dd85d0ed23ed714415dcf3e46e568764987a674f5692e6f7269d03bfc5942da1c7e388cfe0ac6f354daa3cc5cc16a77faf8456d7e95f239dbaf39639a2701a9fe11b93df676252fcf17537abde473091d8b8423a582f69cfbca81f4ebca74c686fed7f1c8f3a22d393c236bea3ab06f864bdba753e3e9c7ca064b6d4d32635f9428f16af028b8a462ec499bfaf7acb6d2a937c1b39a02c0b2edf61d5448605acd7c8560cbc86f4b8efa67ae9b3ce844e1b0145d6011843a8ef46851a50da88211b605feaf80362f907dedbf42915a27d0e671f95e17b6fa90f77f3956b27f9be61077c203a9722c9ad75bae34edf8a8c862b1fe1ba3e3233a915d70609fc7c3a1daef95d7a7e92d64cbbd71e398ebeefe6f3b1bd0e6d5a6a32d95b5b917166656039d32944eb9e4bb281a5d050dd31ea83edeaf99715072cfb5cf6107247eaff2105a362b75afc2deb54863cdb46b0e96af325622c7c4e36ab41e330eb660b954ac695351249f7d23b0fe403435c9d60fda7d53ae83ead5863f3be5ef67ad16c3d77c174d25bad3a7d169acf7a27c5d8d499d9904f96b5b4642738d814a031be5980d3c217e437cfeb3c450b8831b14ed2b7d53c733bb038232bd24ed496f3cfa17023b381ce67ebe16cd30bf6bd6ee68b28a355d8c79d39859c197d23988e7d5f7436ab9f6bda2d3b0b8786ca066cc70acb7af3f3444ce7c75f7c99ffaac4ea171f1aeb65af331dcefa69501696e9616db0dd088c2ead258658e7477e9690eed7f57cf15339facd426730a73573dd2f2e78e096523c96388ea2ec2b58e9e8a97c4adf33eb642bb916cb06ea90df5977cefab3745e791cdd49afb38c32e75a92c149e139f9a1aa9544a245ae596f7752cb74beed4c2c5c5fafc1fcdcac7a12ccc3cedb7ffa507b77e213d17826d6afcd62d923109f453de182ae5938df3876d09647844b2e33aa7fea7526ee524c53ef60e95cdb1e4d87f626679fa5d35ee6aadec2e169676ff516c52300bb663931ce87033574e0c10dc741f84132b7a6b9e94e0228487764ca3d99a6591d757876a8216e623836c81b843cf223f19b9d0f6ca16f1d6e517b4e7818562d5f7698fdc63186c4fefec4a192f853729d304912b2d9c1d8f9288ae409ca10b40d92cefe2135afa14fb5cecc8d3db0739c922a89782be5d2bfc359560595802756f924d55a8500de3d9d99fb4a9f1d2fb79dbd44e3671285eafd70a665d6db396f8bb3ce32be4608b688d7fe637d7364b9d28551b38ff4e2748eb864fb5e90b5bd5205d646af8b8054bde9627d70d41d4ede5bc3f5e04922a172c32dd89359d471351802ad93cafabd750349a7ad31a7f8e04400624614d48af17786245649718bb9ff59f7998f48faa60fa2ce402fb0d61313eb13f373fb3f5aa9e552b49deddff7917c5e0f9c7c55a657381ffe0e578dceb4e7e468c196d2e6725edf47cdd9cefdeabe7656ab7917ee583f79070c99c5f4a09ec2e03feae949b539282d34179915c9273e55bc5af6a215a13c0632b2cfcdac6b15b3e9536a080415f9eab9f9fd7055dde1da9cdacabbf365ef7e25c08f521bcb2e38e051f09fda53f5b9ca68f20acedb5703abf84eff53bd777a81da3bfd83ae3afd6bd87d917416d2c44a94dcd5c787f38622cde16c7d6ba1e0b4b3789edb97556fedbcb0498e1d37de5ee0189760c761dd4bf5bee9259542bc5b7d73443915f83e7f1f593c75fe3eca34c6c7c385ccf2fc7d94aacfbf8f6ce27a20ffc4e432ab91ce416a88c5e26e890239ee1d56a2bd2f965af2c699d23027abf5e6dd8e150b19ba352e7b2b57599f1d568a7b0709c6371bf496e2776f281b9dd5f653adfb54575e060a17202b783e5b76d62c9e5da7baf4cf5094f95cf608a5ef5aed6b3625b49a3debb904bf428f652aec646d7b4bb4bf761c2cd08e10475c1ff297f267d1533a8b93f7c5723e1dae7a2769b481dcf75daf334ececaf118526383aefb8927fe44339ed5e8cf13a26c563addee860da1d38f011ca1d1dfca7c890306f45e7ffb7af209ef9fcbf9d40aac78f621b0ee75ba03d91d5436735dedbc398a85b09b488413c3276edd1da4c79ab3c36cca307d2dad4c9d5cb3b9712d9b4d35a9a9a7e03f35f5f41ca987ff541e54284af0dfaa197456d12c3b0a190bd758c0b76462308d631db0463361056c3338178f1defd9daa37c86d02e1dbe306bb0e20ee213303f5d4f18e8e18439df28eb9d7474c06e9804a639d37c36a3f6554cc253de168da3d1f9ec89027f6533993849a776e70556893d8a418afd93aa50ffffe1c192edb2fe7fff6b555161a0bc40a9aaf1ea4a35e96fdd4bbca1367745edb555380dfcf47b3809bc96523dafa38299f622a522e305ea2654f4530cefbd86520de345ca3c7855a5aa152ada09bd44a9c48b954a8cd7528d85917cd498f14265de39b7f23a4a0db5a197a9ef4db55279c36f55e335956ada72b152f18317aa7011704a4235351e29e583b2f735b5f8acbc50a982efcdb9a2e037150d75d1e7a42ad5d4ae519f46347c35e461bed01c85af9ca5ce8d3d51960f6a66a7bda1e62ca152fde02f5a0bb7e8768327f6996a7a7327a049d58e7d6fcc353dfdaea6196a6a514dbc162a36e859a45497135ef89950ea0ba5c6bc9e113d425efa8857298aa8a626fd3779cd65a2801bbae7acbea4844a45ca8b54b0d7d2b1746642cad2e2a221f762862c13ed0c61acbd9e52bd81e6babb69e6708615087852eeb24a3eb9d3bcd91eb90cadb679e44eb7387748e9e623a6ff014d0bf2a8e0d18b547b44ad3f459193dfeb2af3c1030a3ea9d1565ff3cb407b4d157e76ddac9d346bc427847b16845e4385aff7d9d8b9f1d69eeba91eb46ced74836fed360e6981af7f914dd5e991045ea2367a1464a7a4afe973b4a4a1dc756473533f8c972853f1e57fa416da7846993b6e6e4cf59b8936b4adc69afa412f6df7a5a9d494b3cdb4f1ba6e99d6f70a62bcf4dc2fb4f7b3b7d87de96bb7a5865b45e3872a2255fffc4c47f2a5df79fc3d9e9d810698083967a2d407c63fd452955166914124559fe96cdecc5ef3185577cb331537791f5de1603c72fba8a859e2768e3e4d5f9bda79505eac82da172f4fd730245b62b7ac282f6dd2b63247fdc095719f5b040007bac32903edd59579c40e4b5ebc9e328f0c661382b2ca3c3ef2cb1d9d76f3c8472879a52a1ff95027cf348de6916145f24440d13c30084a1e68f13a71f6bf4d87bc51a4aed6224c4070a02d6d2adcbb0e8128d3a359da6b3e3fc91bf567c71357d66d4efaa4c5ee4c34ed7cff404ba126fa893f3568d737680e667acf73543df8d4f2973ea6afb468d73435d13536fd9c7a72575b6867c55a34d06409c0e07e09b1eadc95de2bf5579675c299a21a3d9b5fb4d3ea0c576a380e6fb499541107ab9eadbd8a78078645edee081536b38d1b4ecc0b5d5f7e6d413bc25709af72c0e0ea8976ecf3790a410ada2e538287d1bb17a93b956dbea884c9b8f5e974be629bf17c0739830d12a8e0a3720e87a7d89d339ff6cf520ba8a5ad3af419aa01061f7d4e2bf04f82b33ff22537d5c6b9cd04b3ef052afac4bf50cd7d86a6116fb3a95e338c4b56014fc6945a0c067e067600cb23e32c034e50b8e39f84be0ff958e6743ce0dadab718454817a19968dc1e91b47027dfc65a057902714e8988666b828314c63ce07bf910a9e06d72923946663e3c61c2991fe403659e9d644e9099f74e58e5cc8ff281322f4e32bf7b2dcacc3b307c6398df910f0d158cf4c8777357e974cbf908ebb422d59a7c4854f0b13ca9ba4e6771a29f39738316a5f1241feab4a7d627b91be8c80be76e72479ee50377647b927b49cb6d267a8efb77c10717bbaeaf37063776f9a4ef4d34f0ca055adcc08b7c68a870a2dfe965a827bc9b1b400cf832feb673e7be9bb55ef122150e0c4d84ffd00fd2fdef3f72e7aaf7c8bda0dce142afb0a718b7e07b30de0230dce17ea57dd7a68f0cc5c3adce7628dfa8e68daf8dd61d1f08dc38233d0186f1cacbcd7514edfd9428f5be03a2c1005f756eb4f316f2b5d8aed2d1dffb2157c3d8a0791cfea2d2784a6389024a5ad26d1329a354da6733d30b00dc4d85c1eb8c3a6166baaf254fa8a222c6c5f3da14d427c50a7bf7d9dd578be8ff862fa3bdc60abcd3010bf738bcddb32a00176805830aba8b27ad1380d11277771c30a0bba3eee49dee245cd7ab8038c66168cdcc48f32c12bc4d0885bd5f69dc170c8e361a284c852672607031f3866f5469877c504af49aa17d5d738e37cd68e386d19226ef4e0140261b2c429bbbc310a53aaaf0c61bf3245727153a954bf305fae35d504dcafee0646f9c642f994dc50e2678e37d7efc0d888e9579fbaad0307ba86556e1d33fc7db82073d3392e5496e7cc9982855bfc1b9a8daecb41ffc031f9d2759f780cf52a0c299ce10ec98e9ab3e9fefb5290163b80dbd1badcc5433f9f1ceb7cc8d5674a6eb7754f5c80fe585e6c2db69a52e8154e24a42ddc06ee3eb8a03f1fb218d80c021dd7ad4b12d8fa9eab554f4e285eaaecf3bf15ae781e38cef18f43f4eeeeceb14b74bcc884aa8829c0636ee191cef0a5d9e260af8f6c5b9a66c9549783eff8ca1331161e18c8a3da3822d0dc55743cc06f57e05b26ca447775c04276d4898623031194d31a5f3ed3fcb90686146d26aaccc9db44715aef5f08e3361dd78b16777f6b30aa7f84ad8c1b5c161479f85fca5fb99c0fc029760e2f62b58e8311637c7bb28bea5fe041f3559706e10e8f43e7470910bbc9400a30abc52095e18fcd3d72a8f95918106df11e5cad3f98a0eb8f170c0e0259932dd974c024201b7ba47f853cd8bd42a880e94711d6091e84330d3a7648ae0bca132317685ecd05fed8a565622286b865c9d80e9b991f6527af6c17e88402411a4ced0943c4dbd91b108115de0e95df9de8aa9e8e3dd6fc8e895168afc8a3bd731028ca852de2a73b3e7833f30c07fe4d4f29a6e68d6095da369de32525667f4c83c5c8322bee29fce9e81c642034f6a6cd0164a342571c7896d645dfa682ddaf89638346f03b0636ace87eac6b75545cae4f44f5980b049c50c80963a4b635afdb4b1ec6393918df463a4a22d06cbb8697d83b11631d602ff74b732d6857f360311d14adf6620216cf0b47d19044f713a92588533a0b59c5968ef3eee80122f18df60cc8c314a50803e6f9ba84cdfd7fe48af2b0ecc54b77c412f4c397437e61715bdf2b7bace406981ed3327f0694ede821a530223e163318e0cd641c6777917be0b7566431f4d05086a6bca3ff13600c9e8b25d684f87239df20de615e0ee631e6d93e14376067075e29e3e3a84709bc71a33cb6309dcbacee843e75efe53260666486018d2e1d93d061906d0b344c009c72ba089e2d5a9339869daffc0f8e64c5897688ce1be82b5aaa01057c7e8a4e18e1ac5a87245ad784618898bd6d8676b9e90fa9c67ee61cfe36fe1a474160c2bf6fa2b004ec983e88d681704d71a95f5818e8c35b6f482263bce8346e31ce16b36611d9ad8d10950630439210cd4144137b75e788f1208edbae868e3c84dd42ffd0c82001397d560bcb1e83b08c92726e2062578503dee7573167955151469bffbad0d63c74d9e8102c601081fe22e320b9347b5373ed7cb07a784a45b49a25dc977667770efb568fbdd5bca10b456b8c65161a6c2547b9b0702f0dcf59df66e0cd110265d9f6082970dbd24c5ef1741d5c1e71a3c19256732aa0c383abc97de1903a8c9dddf5206276c84bbac1f12a130d0778c56cb0ee2096944b837f0e50e5f42d4c2d3d352a68c33f4c1bd18e25259c467375d4ba9763fce400e98e25ea2c219b3a38cba47e53cb12daaf71af5ca8d3d0e19b1bf632c2bf8752317f75eac8626ef70ae3b0b2ccda35c24d59481d9d78464d5d6dce94681b3758afc53478e6944277b609e30ed23ee5e7318a5af912aea325f78575a81194633736540f6514f9f667a402dd4f7fa8ba7a07ecde5ab37110fe083e6184025ce47194a0628fec513932cef052503040b043d335b731361e6c0f5dade536a516feeed2b6dbe1ff2046b93e589d4479716b0db450f91f6be36bb7b60576d651ed6f8b489790d78b6a99eb2de9e7e10a4a82b0bc8f03b03df439de766df0bfcd3c80078f1de3b43479d712e748187d2cc01272998ac9f2a39196df80c92917b15e7b06457519623d8437cc035b62e8df10c1dc7117f1b05ceea86bc1122f5b8001d48fb81b661c3ebaa461927b2e6ee9a0ceeaae8cd0e2778e28cb7dcc92b7d1d33058d8bf61294f1f49ed9f625c62b9bd41651be91f2d5814badf417a3ca04124d510fc0bfe107b6ed4aaf701baf7903ec0d68529cb35be6add73f004d981c3639038edd49cd13636b0e681aa983ad0c806f84b140f070041034a435765eeabf7ce9fcf24b1b2f201ffada7d6bfef2a547b7887d49dc2f2df7cb5756dd547b975a2533bcb5bdddbd0ade0cc0be73d91339b900a0fc72782013c3f4477dc6391a33ecc21da0244849dee8b85b2680c660d78cd120df2a3dcedaa50b333afa4219322dbf4763c540e872825240e45ab7b16d3354d1444f8dd3132a40e5f234a9aa21dbe9ce6ba83b9061d186607dfd89723fddea3c35531fe826ce2a414ece055ad6db18e67cd04886f65e49655f91c3af1cdd090b2914b4287b5655340209c0c222669b9b91ce88ee606dd0da81c964afaec29cf415b34bebf1eeacc704c86a081401fc6a303ea7f7e955d7f8f022f5f425c813df58355918a39461a1daf312406777cf7c67b90f19c1c4e5f415030fe38209fa0f266352a48b282c828672a1d405404b294a896693d77d461daae06626b988c114f7d632a22e6457ce9cc1e53452bb139015109adcdbae097b83c654e07d32f265f92f7821e2dc9d7d13e4c51c85a1da18a0b8f064903f427eaa2c618043fdfae2a6777a897e49eb63e6599421f99d5470bc98bfaf5a573c4ff511931f0b036e7a153c73a73cfd0c81388da26c1097bef0c44199b48c436cf264b4843c8bb057c354be6dbf49eeba4af10b70ace53db6823ff73d50393309804ff6c0ae607924dd1f847d00378e800b46db7b86ad5f74098b343d009c8c2d7e87bdc09d24c22d5c9ba254cef5d216c4690b057b0c1d24e7ba92d5af1a848d1df5f15bf1aaf0429a48ab2b9307987733d5ff2653c37255b0cb24679437e03175783abd58454b30eafb9860823f7b3de5f560f4baf9c0978d8e91429436df7aad7b40317085badc73e68ab41ef1a18bf43ad3344e7a07e98d93f460660a52911d62c36baa234b462ecdab4a2b030cce25ce599ef1e88b8656a920b2b8915e0265c1b87a909025578fac1330d6fb470643858a3df8890acac14582761821fad6ce88db29733bb7a67a8cbf554954b8b195300fe95b2503ae64e4532543bf3ac7c1383e62e356556f62eedd7ae79093717fcd001845d66b5aa0ec4d00abddb3898ad7746087417449c54781e213d5c1b9f2da20a7923d4e1bcf711b1cdbe49281c1d6c1ef7277a99e4927550e31aacf3b3d29f3f149408d274b5ca81aec4787654f796eeef1b1448867a02eee01a7d20a22150b6fea8a87146f53f94ccad1c7bd1d1def0865a81d18c645b33b6c783a60532415c1a666ae241fdc1598454ca585254cfe90f776759d36930d61a62f03db525ba92ee8914b3ae7e69506f50cb9f6464fb9afad323a76c3535ae0ad38d02524eeb8b93e03894fb0c3a2032110262f60ea6f8710a283b465a47f3b9fcf0c83ac36a821e7535385d795fdbf6922525fbe4cd39c57bacd32ada425db8396ee1ab33264ccb631c2db559cd162d519cb1409c53ceaf68acecd413fe1e2a7d53fea5ac8690471f6fa49a5e0f652f316f415abe3404b07dc1766263c53ea3bc3beb1fe706f128b3b037233606cd95b7da1af8317e6761f1f1d56f0e691f50cbea75959758ba5bb22c5a5036bee858b77862e8cc134c0a50785a022a64abe4cf8a7bae14aa0b9c415869f1608f706fa36726eaeb3cb2511ca5c480cb95cfa31ee865885790d996c0fb45a76f135c017c9c4db1be352dff380c1c29a4148b23544bfe7cc54ba52c5bdfabdaed94f757d8106db3a75c57973002713203e56d13abd7fea005fd1d1bd7fea6f101db453a05a77ee9f917bffe06a801826cfdb6f6d3294b47a9b889eca827a12cc80ee3b97ca2f4b5e243c294b9e8db26e3917152f4e06235d480f026d92d0728e936a3e3801d3b10a27e955c15525524be3acaa6f286111cc28c0da7a39127a80c651b8e79ee6c15dbfb9b70487d00f0dd69f20e0bd8ba1ee4130e198d01a1e9216a342c1e724c182cc71968aacbcd4dbd2da2682c517aa426ff50d149f422233bd5d45a95dc5586dc5e6e28ebf14b437f6951afb7efa655b11a125b315416af11150751e631eedbc8304a802068329749989c369cde6daca18e2d9036fbff983d751f123eb942c9c2416b7988596b4af874c69c3ecf512a9ab077bed72de7df5fc70f36656d0bcbac4553de09f66ba239217e6db6839ed52e5982a23686493635e2b681440945660e547b3f667275d1ceaed49c90db65cee5bc9083a45d19e014b8fb6c42bcbc17a5eacfccf1d743600b6ebcb47470bc67672aaefd177a93b01afc5ff54bf2e2abd1c8387b8b6456315be730f187709da54cddb5f762151715173bbfe5fb65b2973bb21e126e11bb7f5775d26a0f4c7a64e66a792b34dc5eac608ad928075852d9a0f1cf12f6f920057c5a092e12d01347c0fa2a311b2c884295b0615a6e689c053d58780ef2346ca70dfd5210564a4fe034c7eaabbf2b002a890cbff9121f10e50fd9a8897d0b2a5284395154c2b0a4285ce2076f402e64186a18876653bef5bf486d2b6bce0795fdafa1bcc0208175818970cc2173e4f8a48a2860c1e3b45c111cfb1cd03238b8d2d1f8fe4960fe9e7372c53a4c566a2d50f28a6d7507511f05c32597ba98b04e9e63aafaf7cacc335128ec0436f5816f79071e79b00b0a1c97a297c0f9077dca1e08ea8bc3d24343cbf216f05ff0e4bc40452263291bf941a2c19c2c793da37e0932a0f0ffe047cfa5cb85d626a38be303fc19c5899ad286db4ca2719cf404c4c57ed8e33b6737fc838f939e3b7a6abccfebc53988d7628aad261aa14d30ab2a40164126d9325bde5bec3663b3d6660c73fe063141fc0e8819c971223658e66c8795aa3933c90db5262c4c2a31f513cb7a5315a9a9cd472f06d22111a4620f738c13d449bef1af233c60421ee6a9722508db1553a6015986086c2d344aea659925566ca7a82d77962e5ae2cab756a475f5ad73fd5beb7b57f25a2d3c2c5734e711164177f281e4e708f4ff984b5c1b90ff7d040dcd943923dafa1a876e3b3be3aeef8237d6ad3c179895ed22bb6aa2c0e1f0c20d4a85ac49b657489679931f1df356716a6c8f478631c018f60fd6af39187d67fc100c9a3a3172e7fd9e4df0e2ea78f8e62ff15889db5efdc0b4d5c0bb491be0f5b1839468c44b690c8e57eadba52f35a2a581bc8b6c1e1df84768eccc7f7e1402f76ce60391a3d6516265386ea2323225c99ad5bc39ad31f2070e950f794ea1d89ec0cf73fccd62faba7690e8fb88318b113fdb53e83debec62c2610e7c6990a09a4dc0aeb0e26056bbf2d8870a874e4b623741a842e56eb027abfbcb6dd3bcb0b0b267e60f35835bd00182d346a937190b6a01a8f595726bc3d22d8cbb0b2f3b3c8a52d5480ca2dcd4505e221dc188fb66db3d7bf1c698f15be5f23a65f6948c13b58846bea9dff09197d13a41da184660e09bd29839fddde06c2618d286d7e9a9ff50d5147cf9c668f69f3b8d9cd4b9a312484ca2873073582046a048fbc0b99de8e66ce14b616d8829761366b2c2e0b78c7ab06cd4fe599b778e71d33710c5db4c25dfab20179937b10ed4a560b07be31054f264c6fd054b0d51d043c8f353beea096c82a40bb3d54fe08aacfcdd19dd336ebe8f6dc0e2ca403bc24ededdd8f1d8d94299ae6590bbfcccdc34a7e6a3c52c1d62e9afbc97c40d996775158e3c5e00396c094679f2e4c48d8608a8fb685e8749bbe064469b9f3ffc399db1b3e5243fde966a95a0897cd0fd0c35cc6d957f503b7da11e2ce0bd4fcbeec3bc21e47c8243650809c8307309200613d2812a75670f633ff1f3e78911adc97ccf6375c12fec77aacea0f995a2a5a9e73c6cd1267aac3fbdc8b55b43f67951b511eee6be4611d64877991bc01de67cc8bc4615ee4b4655efc296b90d3175a6633633b58c99ec3801860fb6da02dbbe4b912aec132b8c4c1cc837278b4c60d2ae4f6650f302b7c6596e6eade3b139c707b551594b44c676c57e39c1d34fa891d348d70c1567f642dfd433655e47595eaaeddba46febf6453b1dd5e63ebd6759df62b1b7e20029dbc563f7eead25562f75002e4c9ca19d33d64774c879aee42dc683795685598ede9a662650f9bd2c17689cabfe191fd4d4af2677659ddb2cbc2137659d572a8dc92db1376595d3453975c72e930da9adf4aeedd92fd272c2b950b07a6ed6ef938d5c64d7964bfd9ed0ba86115a0eab706330d3cb2ab476ea408e3d19f786423e653bdf6f9c654007603584f31e91a3ce76bde098b8c4d32879a9536a391df7ffc765823705344aef49b9e97fdec9c12ad3b09b2733916dda3e88ae53c3bed157ca50a7e2e65acd58f953ec3dd1bedddb26ee620b0df9251300c841fb7d10a1692f6db3500f49833ccc191eb6cb97fe0c895ffc891bb1522c687e1d2094f6e58f37ae0c9ddab512d4b52438d7d2989e31aeb3cb265a029ea0952a7b58c29172cf4b2e19d9363964833a35fd2c598b827fe59370080852c93fac754b3c367fbaa32c42a094efd13874efa3bd78b9392ab2aefb1f2f79279df9d11d59b9d94db6077e7be953be7ec35fe9eb38786fa3a07e17dc69e338f0e7baefec77a64a85fb4a35809f91fb008658219bd76d98bb1982bfe358fd0194cca237cfb0de3ceed74c282c53f70fa4e7bfa08565fb5733e5df11f7b7ad6f2c0fca9aba743dbffeb9efe0dffd32d9ba8b8fcc779fca79d3bdd2c8f23934ee35745f479195b551bbdbe635edb566f18e05de92d12aef5ee0eecb93dfd7e69d1c63bdc65dc382860fc8fd8712a1e026064aab6fe5a67cac6113856bfe3d605bfe2d6e16fa482cf7f02940ab8998eb59f819029e931749cf2b59f818d1919684dd58bb59fc18a29ea39ba526c708e1db7fd5914100ecedda1016e1c522d87f0b201869ce4152edf4ef21e4f526d0df99354aea1ce061ff73084698a4637e3c59f98fcff0a43d0ae80f9fcaff003cdd6fc036edf8dbde1982f72f777ecbea565c8dddaabb05ccb6a330353c2eb85bd1373cee7a0ace573bfee7df11dcf8de7effe8e1b98b78d0febdea5a6c3c8c58b777fc50d34838a141fd75d66e2b5537c058cec987c2f1e0fc4c2e111079c3507ea968fc4d8a3e8bcdde801a42e7b56396a0ea114b70316aba199d313ddbf13a52fa1374b272ae7eb3b283868a7adc6022dafeac2e648545fef838ccfd19b450e1a5bd62eeadcf07aea6826fa3af67e49775addadc9ef8853cab4e1033b31dbdf541612fca7f145ae3ec0bc0e5bf944558b7a1fff4868614e12ab29b1611e4a7dddb48af74428403ad41854dc1961f2cdcf4bad75f04e9c5af3ffae562226fcf583fbe990353832a5bf1a463601b46d160fbfe8fffe2ffbff37d5114cfa65c71b2353e2ad0a684b993fd4c97bf4013948ca7e08cf14f322553f51cc4b5611f0b975f4fbb453c6c2dfa4fc924ff1971f82ec034de12b34815a2915d8101155f34f7982addeb96a814244152ff4b317aaab0b6d15037fab8b210a14ac11cff068c720bc81eb021a196606cb8df28566f5be0bcdae56d42bcac3f908fb9208d6a678f7bd4fdf1406b356cb38e1d5438df7fd115c4910a33780d6d74db0274487b650637dfd5293dadbea133591bf19e594aa59e678285f397da27b6216fa569f50af7ba837616c5ff72999ffeb168e98c72b1e495286cd09362a73508f9a6d5af2e8c1e5490f021873a4cca7cd03748a1968e773baf1bb12c83c3383e73f8fe0d7aa34445a620437588bdcb711ac751f328dc1cbf9a73c0637eab322e8b06f7e33b89d0c8ec1cca86f1abf2bb183071ca0227f55e220d331f98be9f86f2ce81e63defd76cc270bbac7087e596243d77cb035b9bbff4716ad8c01dcfefda29531805f96f8be687f2a71a02117f4960673d0cc063f6ad1cc655a48b5300da10a46064451c733cab0538251c1c059d3448b26785f2bf322ffa7f8cfb77e8f3de770f2dc495e694e6f801f799537afa5d8eba945deecb8debdbe65c603911da6060b14af91991676b2d41effe5bc546bcd009dbbd1eae2d2d4960f5e5b958ee64b7b3d757b344bfde6d5d5fe68d8bce87034233d4ebc8da6a4bef19a943430c6eba8d9d1acb82f6b2d82913a9b72c4d81ce6790bc28d87feb083011c75ec61ddc48796320f9b66965e8611afd754e6e1025ac59c0766fb31d5ff300c914e79724efebea4b795799848c30d651ea6f7367d73300f33d886f0d5fef448245ba7ce462e07ea77b9afe7e262eb01486ca0cca3b1f8ec6d5f3f8aa23757f052e30a6039c73cd11efb73f8bcf5bdae9a991b5614da98924ead9b687d4361a7854b9d495bfa441164aab8307b0175f4a599701c8aad8e152a4013fa566fc112bc859afeba2676186cc50322481c39454281a9faac063b494a7a65eb3ab366a34958bcc109224cfd4db4790551080732ec032338425d9fbad1dd738b257de00e4c75458691b02d4da4029869d46ccba14a44108912733d6231403cad0b8a6e2d67bf341dc5858e18c90fa2396cd4cb2c146bdf3032f7007be125950d5f5610c9aed30a23151f350cb47aec31286cc27348be7eee3a24289913d72174b583c4f70a46c54bd3af6633100278437ed72d03206fad557a28e28d579e4df6c561461817a4def529efe8de8ab954ac75ec2b4c4375c5c8663547751af6d431d25367f6cc932fb8ce462bf3e415aa2a7a027e7c51cdb2a9a45fa74395d7c24b4e94daea2d46b46bb0bf3f9e7ed6031de0a59e7fb2dfbbca7c966a6eb5ee37d5f5d91d9cf18c0a529183ff916390def862bbf156292dd1532d5611afc52ccbec15d32f041cb6fa3cb5cb038c5490373f7cea1e5b5823a3ccd2ec20f362bef223441c7566e73c78b17aaec140b537836ec6c58b575705cde2aa0ff5eecc177420ac0822738fc1d75930f10b4c19f416cc60f89cd7ec1b4df598771344357b31b999f359eb2c181605797412e2f66074efb55435a7fb0d9c99638dc5f7ee32479f5e57f9d5d3956793ea4f68bbe1bcf3c6b7e77d4bf030a176efa30d3cbd00844c70938c8d7da37d3e6e80b01dd41d60e37e0b479abf196819f1fe87056a3ce175ae8f6176e819157ef21ede56dcf52fd744175fbce9042a78851e5b22a6805c6155ed6376a9bad2053ec7136d9de5646e36a9d002960553e6e7ee758e7fd9b0d747ef6fe165e5ba055049c756b3f61a030b5f81b15787f15b1f168449b9c59377018b022f2118547a2484e7e516c50014d9778b5bca7acf99e93ec3c878749f2ad0b058f1a8fb624a1d4251480c1a662d779626305b2cde6572739e0615e6c1dc20e024a2bb232691d9097326c3606c1797e1d78cc7a9621cbc2eaccdabc37bac52a454c34fa76cc1be23eef9a4dce75afc03751fbaa8a6f7ea96cdb13b65f64323f0ee823bd61bb51c0d29e8a8c38b4dc4c470307ff04275d02f5e556d7534e0a6577c8f8e4ccb73dc13c66009f0d98db88ac58eb7c57c67f89284bc68b1336b8d54b64c5deccc966f889d51f2ddc7e7f149a1ad14da890e7f9bf1d5f5ce2c28fb6a676e78e32c77e69ac52e3eea347f57278d07ee9edee45b8eb088f9cef4d9e68b7d77ce768699ebd39d198669ea6467669467bc3307b6119df11c8c76664499ee6aa71d3168b27fd291a574642533b29619f1ff2785127c6eb965065266c89e5777867dc07cedcc039fbc93f51cb7849f59220051da19f6d279b333b7dc407167ca3ee1b332b46bccf1edce9847b79a698ba5da70fef551664604d443f22871755e62de6269f6182572605dd8360847b8d8890bd26ceb114854709af99069b87df1d81ba3d70cf08443eba1d3aa493f4c5ef97a56ec6b8e534c96703fa4af7dfd9ae17743bd78069ec56706ba5e2120d958afe2ecc21942aa9137473e4b8c9ec2eb52247c0778ef7bf50ce32f11d125e317b69862287aa997d454204ded98ea048c1bb0079c98fd0f24176df692c5838a8e9cab7af94c778262e80c505ebc131d7c08e91b21e3b9f81f795d158c02ce0d5947ee8e3f5fe07bccbe29c06c4bbc96ea0e7c8629439d7bc6bc8b2a021f818386c755b19d66205d3a0271ba399a034bcf177a14659fcb47509b87a279a3a15fc05784b54d079d89356c5e43a1e6545790054b51fa211c30694e13e3bf41b36bd0ccba681ebe18947dc13d216ef618482ca7f05003261b46668d7a858690bfc9631f3ee158610b1e0c03e8292f9ad9c0d657b430a15a5d999d394063ef861153b11ea61dbce0cbaa18400bb27a133a55a6ca40662913dabc72bf8b4650a40c5f42f1006c72dc5a377cadb3f3b960c6d8eb1dd8e8c9c055d1288051bc8f20aac218473fe4d8b2675359941d5a022bc10e0afa61acab1694cc0f53c454629477a668728d291a5f9b9dd94137639db0271bffa71981cf58c67feb8b88eebe09160d1b3b2872272bb07a685ea689ec6b8ba648be9c4d51a802569bada1009349c1337809b6961ceec611bb1678c3e86c22577da14f92d8ad07bc55b0bfe868ad215864bdc5f023f3df23a6f550649c23cf289b4b5336cb531d983efb59563c16f3890307d79db5edeb49cee1b3089f994431620d52be03c67a73f7eb43152ab3f7651fe098de1842416e6f4c6fc8c9312b8a9aadc6b6aa169a04293a70fb7abcf35a2a171ef5342260b1d2cc768d7c387353b6404719f1b5dc66e95e03ec35b4b8bc041df67569a6664ec772796966743b6f2e8d593ebbad1e1935687d31c93f87bf49bd4db3749559f8b9d3b9b96888dc9c7d97f9e2d201eae35d38d7e36b31ccaa692b93374567ff162f59e3aa70697abc41e3ab98dadaebe2f349a6fb934c3794a9bed683b6f783ad0300d3409453c5c943b8648cb4cb48d6d17cfb16a637024bcfe30308fee32b7b4705b7e85c4efbf2a75a56bfea49686d1f1e158e93ad38fe21ab38f65a9c54739d678bde9bbc81d8747d72255ce7cd23be7efdf62b849ec5f3afd4de4ddebc48f24d13b221b6232c39ab372af0c20c0b86dd46a6ad94b8da44fcecf2756a615d5f13e9a8dac77aa666cf10611decdac003d6cf6eb1fcb373dd877dd630e8ce1237b1d0f21a2a9af0d9f80443b84a748ca99d64bb6a31d90c5eac4dbc6989ab4df061b95c58f4133bf096323577c8650cf9b6c0aed5a3891df2c51d58291e5bd1679e4fa88d95586a2d1fce526992867c71cc827cebe4702d1c4ff917fe0466b45faf803bdef43e3565ed6bef966dac84bdb6d32a7811af0946995748627a29af64249a7eac9d39d504ff9c1ce3f31c3d31452d4b22fbd9ea29f38e57de175d289798bc5bb09bd6cc451a2a783fa9d67e6d2bd5495b2969a7daa68adebe0d44e0f686dd8d9f24ad9c246e92c6f2eef8e8e8d035cfaf849db133a6817612e64e42c372ab5f53672775825ecf8e34bba1c29abd9e569ab67f86e976b72f90d4b988eed51b5d5c778eb7f576f6accce033b951c2467c064be306269260740c75875157de0d2dde0cddb6a4842a1c2060c7112c34cfc0916b45eda393adb537561b3a384a748a28eb9f8a60b7b87e735cbce14b78fd06690337b37be37cfb37cfba6e09c7e85e1ebc142bfd3739bde294cee359094221f8e54283fc7b38cfc082f2f0c9cb4241dc525702e5b595aff298aa89b162ed700ddf05d0dc1085036363a1ecefbf8d157aabdb3f8df580b11eff38d620a737756c80ec037821c3fa591da664ce0777e10cae783eb8481cb2175e3366e647c0d1057e2ef0dbd9882ec0546b9d0d239a69ae6d5139abad32d1b7af9e5051c94c5fa339ee7e3c86341c7b9f872b7ecd0829f679c62e75eec5abab4074d2d39a03366a8eec6234bdcb07f690c164284bf97b6e4c8232d491a1087fc92f0d689a3109577ef4acf75c3e257c699b9af284b9c9ec43a406cc995ee957cbf9728457a2d162ee8d559d370f50df620ae8bff6375643fd9c818db12e596f25913a06177a082619dbb7344f1d6c5a2062f201fdec0295830af411bee1a60c1936ba9cc19392399adb0ad88273ebf796d0e7cc85a2f3de102da6c87d8fd5adb9e6f58c7c0b664c0d84668370b56083e01b8560a84b75bbf18ac1c7e513a78e3558e8925ab0a9452775a0af903cd7d74ef248df20f94b974e72dfdadce534391f2cc20bb89fa71e3ecf74b6933e81811d34dbe3a9faaa0a43902d540f612ec99b65a4f7483b54d38d36d147a45d56711a62152ee0e256dc992fe0837e070bf242960d32b00b9fc8e8927902b737c82e82cefa5564c7557bdb072b9dbfc7799f61e56e98abba847cb984a66e59d51d3aa0eadb5f16b9d0a5181c8349fb1768066d24837812cea137d4872ff378786336e8ac9141923effef2ca00e435d0eef9583bcc65316debc2d5e05b18ad55633dbfe600149ea3e961592b856f640a398050be8d5827e3d93c12c100b6a56fc1d60df89ffd51aac7b6b164499a32ec1d4f216213d28edddab2a7fa3855d2c9678ec09222524bb950b8202aaaff7ce68d5b7bfb10af6fec26546c53b18750e1c13d2afd4d31cc1289321c8ff08230d8a7ed99c2cdc527094aa0a26e6cb9c41d4be2f96a2c3760a7a43a1cbadbb5b00c232c4fe5382b7d11edf4bafdf33cc1920ef093d8a54f9d55d67a6e781dba6dd1bf9d6b229148b58f8f70c2f79a7766094528737c0ea9c707c3fa727806d5cab8306054b7d408c2038baace6e8be366b3d657290236b4525884b9688d80643e9cea492dd5111d022e84f6e2ae2ec36120236d806aeb75b907a7d9001e587cc976251c3c1627d88ae335bdf7c5e42407704c523c40dece0568e33cdd81e47afaaa26570c1f3d8c4b0abfb2747af0392be25ebf1d76ff9c897f5fe1dbc575633ee9e4c780e26e1d6097a173c2499502c78e9997b75f37c5675681d81b6f7ef5e5d994130ed62d7bc66a9e1da14c46d6f00c8c8aadf46e53bbf5ef8bb934f039f355847e8e2159c399b33078f5028274018a9602bda6879f884edbf01253c6bf2877ae3899f3b6dbc64204ebde1b2ac6f6b66fec2d94f4a74c57f37afb76fecf4c9c8e6047776e53325bef2fbec8b163ad40b737622587664f67aa7b3a2392a1aaa8b95dfc3cdf2bd4c47a92623f76b533c5585dbda986b1be39cc6709446a03079014f69913524a02b1460cdbd206f8ab5acfc7aed13aa74b3f65fc1453fc28b3c8e6db2ef789993f343075e01d2188c6f474ea9eef8a72fd2f63c17ad5ebd1301a6ae9d37d5a938b5be32f98ec85fd5f13341b68f03c065f1dd26d2220c1a34cd356e0522c6cf14bd0b6a56b52456ea99c559cfa923cee09e051d2c2cbbd6d510507ed9f6525e2dcc2fd2a960bfa7abb57fe50bdc2eb0eb827c7010b3f8855069b70cb3bae586575725ff05024846e6eaea7ea2372f194d388d854e5c01b75db71de416f0ca46b6e1ca3f111ba10155780665d1029e70ea59c761a708e0d6da706f9a0ba839d4e05e9b96e9a51850e65b7d60dcf87500a49371d197a38446b8121b122274d79a3dc713ee3210873f6b06e735a78b2a866d9ded36b8de976d788b24101b5e1b44ca692c5831860583d1509cbf62ee582a638eda8993f97122ea8997883d214ef7296d5d813ffeb1e105b16a33cc48023286e0254695bbfc73d14d1d591c38ef5217dbd91511729c80f08567f7140ee42d87a4aaccde5c1ab763de6968a84445e23f1d3e464e626705e7adc9bd52d6dc37966c984f8995013565bebc983dc2c2f989d04f97cfec50120e065ae5c0e5965d124d110c8c7c1c30cd19d79db6d96b90c9eb6907a0fe6070d116f954d50b44ddc6ef21b679ee1d7371c5b75c7bf9ee75694d7708d1c85c87897f9669ff6e430b565570f4bb271fd92b60dd97e80b74ee258614d454d887d11ac09f635d18c4cfeb704092a55e740144b0150e50056719aa396a363838e8521b16566ce4636ae0560822d4862ac8013ef297bf3e7b12868ef54ede4e77a3bbe8ae2871a18162ffb885dd42d0fbdc680440e0b3b5a523b8af01405c6a78391609a618a340ffaaafa11491d27611d1d5b49bde98bb18df0fab16e444ca3019b7c8e8eeb156468d53a4b1a1e289be68a7302b5226f953896422e15e92798fed6776badcf61235d396be3f1b325d4ab7b84cbc487dd5cafaf02462505ea917f11bc8e0e5f3c44173bc87271584e6188b8a08a35159184f31089f833100b7a231ef3d3d7c4ea135dd07d7086540b8fa3ad8ff34d7ee005e19e38566118e7341224fc0d72b4fbe5998c60f1d66180a65a70dc8812d02398cf9245727ccbe0844d96dcd550453364e4c66f20d060b6b88efe61cf1b8bee00d177ce16d89b7d50718b1ac91cc53ba0c458d32fc6962c2813999981bff6dfa86159931a205df6e887e1c0cf4ef7632838efb6fdb2154255dd6f3375cb40baa35fc040e5f9fb263dae7d3bd92a8f09979e897a236b096602e3f07d1a5e715b39ed979f02c88f63417d340ad5e3d1107cd35a1d513cdc648af455601b885d2270b7124e209eb0451770811647664f8045fe88d472f52d7c3ca8477ca467f890d0683e5193b8dabaec03d66ca74ca776bd1ac7bce2735c7a4aa7819d0a6dc0b0af5e1ba66a5b95c706cd3c78c4e8b0601b3c7e71f5e166439f5bf4affc6c34a87350abaf91e38617e7a92c4afef485cc8b39f0653d2e2a29c6fcde8ed8ae9cfa094ca3a03028aa01382aab8c5a6ff7b0ec2d0b8e43e6ec565729007123002a02d30c72ab876300353fb824654f124e715729610ed92b7c0b2f2c4771e4eb708b00541d8d1bc6f2aaf1c516f5d19e84b8eae703f0027f7eac34bc3deb0cbe36b3e1651ff8d8e456bcd0cd137a60ba7156cae4b06799de3db4f7b0b96067f1bc7795f2ffa105cdb0370a999f161aeb5377ea1b5a473c97aa8e6f14700c92ca32005292a69788e18ccea96c78b000306c9ae5a5e4785233dc315344fd36e6aa26b7b05c6178b4acda7b70a9551b0be631c0cea358c96a9f6f5db69f076c2f4ab58881861315b4a75c06c4acaef888181d77aa9238c557a329515acf58808d6f8730cea78f27fae0f4dd1b69e724faa13562089a63d476f74c4691c7637a27d7ab711a1c458a252b3e55d5f43c7af3efcc45d96a4e14d9a12df2126a446d932556510bae440082e6b8efa2a8fe8cb43d44c9d78962e39b862d66eea9af9683b33e931163784fc6cd87513c14843a82cf4cc363421f810aeb358ee7d667e47d494c8d9acac8b194975b8ffb7517452bfc578f454df886f5cc81ec5e9395f957cb6c75aaeca4b70b5252ae85e449d071857d2c00606ecc4d651be5db63c899d6cd62607a64ed152b395d4566662e097a45e947205a0964511795d65d5147d41da25e74e2c7ad923198ce6ea7ba1bf774da76765319e956fab171c4826968eb04c2fc9b78dfb6dc375f6cab6bd17f85364976e0b488fd85b77de3c031b1de90c1d8dadae5b8c98a5ec7c3be27028ac405a40940bf16470c5ebd71c3073e99231ea17e0b3c19889ada12ef96e38f331c21805f60e893f795f72a3008b508e792b7ddb967c685463e46c4bd816c0e18c0ac6ac45df98a5e6bfd09d54d14d2f63ee32fb9605b5add2c759315a5c09980a4f4f27dfccc0bfe979d67e242ea537e2463702601aa35716879aebc072c77b365c9c61ff052f235a30e0c52fb4470d2bbe3ff194f52c5733dc6bb1acbe00e38d1d9a701ece19dd6fdf2dbb8d76d9f1097ae28152afb775d41a2ac5a60ac1bd480586e2d02854c1fb08911718b034378405069f6b3039c65dafa9424734d4666e7516b986f6120b4f4361f54241b759ea78e791804365706b1525f0ef4d27e534465c2dab0fc817da259c9848c5174c22d67132ab97a2f58c03f72bc375466e20bb5a6390bbaed756e643f2472a7ef5aaea1e117d1bc2a7b1b637e645a2bac5ccb36196ea2b334f81d735b0b342abbdd8deb20c8fdb03b9cc11642a2b96946636ff6f40853df14616bd2fc5ac37e238c86c8e1c7aa995b0a40cbf99f5fec1a435a5cf1b020b465ae8723eadd5db77c1289a406ecb0f5ea2ea70a41b15ac39f258b3725e837153ce0f74bc845630c7b712ca817f20ad13e6f3aa855825c0f0993434cef193abc8441cd7ab098c119756e9d37af883ada02540a1d7ffc502e3beeb2f4a16dfac7d7887da8070823a22f4ca66b8afa7ef16bb0b4a7cd170f06cf5c6f412ab529b0e027667653b7b54a1d883267c291c12614c006e57fb08422bfe0247488dc7fc8beb17d2ca64d6e5c009f093920c91310928f14d18c5dcc5c602014b326e9470d189606f2ad51e33906c439a5fdd002be1ab28aa7310d5102f2be859df7e30536c21c6d9925a465d971c1672629670dc65bd432f8254bc32624e45a02e4f5a9d0fb457b7762de2af704d758550d29ef38eba3607df3ddb6b86e8c10ad2a661cf3ab18ad4d7fdc4ba3e64a71675a5aadb0f07ed6a4b44748e8860290b1b70bbae72d1c09fb891cf7b5e474def85bff22551760abe8a3f44af674510cfb5ffcb0f843d7e97ae6718ed98de10212533f48695a98d3eec032f2ad325b2ada839e267cc3e59c00f957282e11bff8dc8403fba81bdc98c8f99799d229a3c4bb18fd026155d88db4fafabcceb166199459de3e29310bed73512a16993f4fbec8aed69cf75359ee06ad9d61c2a5303e6abc68cf63526bc8a55f69a19d88c8d2acf58fe930dad4419be3e7e05330d0e6606ef88337ec03682a2e33b0c6998644a2f6b333237cd6c6490a2438da10f5748f0f7911408a894f61c03fd661f4cfd29f4fc7cb1472cfd215b1e5833587169b617641ba6d9aea1d52af1a07f992d074f3539347ae08be75618b5cceb2aed03da9037fbe0ca4c5b08bf3d1383289eaac6d19daac1bf9daa0816b98dfd6b0a87a2a9a866c0542cfa7afa650e71a6caa2a89f734c50c7e6d77560fea3d5af7360eaa38bcf5fe6c0ac47c3979f72c4a2b3fdb6d6a22263b76b5f67615a099b6cf0b52c2601744bc4aa60663e33c1f3a6b140909b4b70f8cb04652ecd5eb37c266f2eb41076f23dd7a15a4bc18e0eec9509607e50ee9d91752d15952d593716e0207252f6be6cfd4cc67073c3921af35106193c04c27929c1d7073edc0b9c7f9558777d1f9e096622222c625e0b04bdccdebeee585edadc3f666fe1273b587b039f8ff3436a10ce9eac2394a21999abba6775122a0263c6a05a2686da5823aa7203aec1a229be2d89f00f8f9a85e3c21139222221f3ea3f812830248b10269f5a11011a477337057105790d8f9608f9905cd09c85237d459d4dc00b61b40752a498d500221149e5193a25634c5a75099c5d825ae55f1d73ecc45eeaf51958b44bb1bd873b12fa7b4995d990799bf3450a53b51659292f54cd17afaa9e607c48b34e9809b40993125cdc804f1597d868878b97f50d7240a2ded8c1d27edf8441b7bca2eb5b3428cc2234009cbfc08c1742cb98c42f3b39c217d906851eb60c23744d81acbfaf3858f85c78251cce3926160a40ad6247eebd14c544b4c9f8f603e20caa9495bf5a84d63cc3c29a3197b91e812538fc24d05714ed171ba69ff5a68543b1f1953af822171d872ab80e21174f72dc5d185424b71f1956c87b2e5e1bd0225b76e5f878499df21fc17c928820888835d799f1be7947e7ef243ae2a247d839aefd0d135b1d5816c405f8a5fe82a7bce587e3486303b93d0e4a0b360250a7164b35444d6611cc51efa1f975f3e47eebd0259dd77b78b0e72869f133349e2e44515fe1c261edc0238c978dc2396b48bc14c4858c24d01bd37d17e0130f9b3012c94117acc88d2712aa8d97ffac2cedde2124381762f45346595816db2825823c82e2b289823b4e193af56eb9fcc8c79c8905b24524a18314e31aa84f083f5954f666ca686daf24b6915fa0eb733db08837d8973d224eb72f9f99c3ae4f94faf01275d311cdcd5bbea95b3b311c0b105ac5e4d9a78e6ab19e5607c96d7579970359c3d4716b0f18c51e11035198de21ed92d77eab254b304cf83c4f4488c2fa75430d239be02a011f196f37094790f271b53704af0c2e3eddc3399488f15e932ddceb1259f0f5411a8c0ef825123abc3b3a8991102495cfdfd50c86088d399998fd49f1cafddf146caae0d9d069a115bca91c013867589afa063176b8dccd3b24dbecb69a79704fecfdce54477ec664a88f399c2747995fea1be15aed9997d45c12e118acb55ba079c1f1c0dfca746617e1e742d4c5465abc136c34dd5fb391f0be47da06aa3a68b5098fd68f055f1d5d840a9ade13159a3a10610724edbdff439fd9e75df030014a27123e56dd8a650b0dfdccff9e64a37e3706c2eee53d0dcb2cb027e15aa40ebf8248572979195e1bd75815d255278a06414aa8190fc484fc240c46f00c9d4cf80bfc39ec47a85edfbd36918a9cb5e6643d694885839ad74c63175fc869ccfdd0a5fc6fbb24bd91e8165bffe74e2d35f56aa39fa44727d94f9adbc4e2dbb4cfe063a7f3109f14e097cd5cf3ab13de15481bae83529479afdb315fe5c2c6dbe539ffd247ec24eb6efa9b4d9d7049360d08ced2984b792e67aa5708ec7a0d21ea382ba9e2b28f9878acb0e0df4fb91b5d80e93674a7abc0cb62f6ef3291700a53766f740f92752d6a66f01d9b2026f6cfbd8d5876c71ac50d403a266b7e692e285eab0f0d9ccab5b8c5f88391e1289078d462787781616d5b5eeaf27ec3174777d4f05a3c0b5575a78a601c7f219470db93b82963adcc670e5ba60f5f7140d0af62f6e8a9d9cf9b8a87b1688aa7e678e6a94c9fae2baf5715ef1f461a9ebe30f64fa0a9a44170ff93e2379f028caaaa3a80ec74c319da5e1b21779152ff96c27cae1e22dda67928251a98253455a1169f105621def0bbf0e9185da74e0f5b12e3f33af57ddf051b39cefd263ef13f8858fc8f4319ffd310c7f5f310c75727311c1877cda4414d2b03fa8d6ff851e5ef6338844b73ea865ec237fc395244f1cc03fde8a740c75f7efe5721225a2a2aa58110bec7cef83152460c39cd4ce25cfc3e7af2f1b64268cee1b682195de8b3e09a896acd4e7bf7736490ef413fcebd6e9e87c3fe5b4f99a9434827d641b090c87bcc33ba87ebd1ea7cc8f7ba2ae88558427f0d69af9bbc594ac26aa8bdb151e1fb08e669278e27b71715ba34761715eb0cf377d1ab8f1715ba700e179533e7742b002691595659cf8e45dd6d40cc650b5fea322b79337003cc663b3a8426b6aa7b1d1515d3f96d0b2ccaa7f3db8627eda894ce6fa254fd19dcf1467ae4ea9f5022ba7125067f88954a3bc94fedb9090c4e9ad9c9e896f5eff6862089d124edbb18e944dbb4ef62c613e5ffc9deb8fdc195697e101288b81d844039c170ebad65b65b72568ee96cff1fef716ec83d9e8eb8c71726623651cea81583bddef6b4eb7d9f7d4b5e1b753282f348fcd43deb65b723374f5d8533b36ffed5cdf553f9eacfe5ad575f99b79e3d1ae781f8eba78dc09d0900ce52676d0db50a06fa7b3312cdd8a921676b88feae061bc23fab01f1dfffbe86662abab3358cfe610d2d6bf694d630f98735b4adc3fcb486d9af6b48067ad2fa1546d0c5ee894eeeff3a63ccad2780b861767bc8879a7712263a493f7028ad6bbd04d9274cd830c5a7e1e0e586b17ad8429a39904198af5699851e4a8450a8cbd61763ed405ca87a6ea721e1099b69281077c3c8ee809f558ee11f824e8d6fe0445134d77ed397bc196306f8eca9eaa643f3e21286737d9473d8d70adc9668e63b4750dcb408296d39bf6e4c27f9d416ef2a9790582f9975592d075e53ad2aa20134879c7caee1a2ee98b99a5c565e377012c623651e16eb4817f8aa4e2635afa1461bfd48f57ce9794d10f250855bb14d8583d51be866e458e6fc81106149d19a0c4001b308a73005c412af33dbca4c8453550235dd9f70ac9ede351b96a8e4129cdebad752c1b5193143a5d1677e7a3bc78ce71694c8eb03287fb5faa2ac341861eb2c4e88974213bbe3c129138ca0342a71a7c4e35a9fe7a529b21571453f96b816cc7fada34072602653fbc34bd461add715e8a9240ba2bdd66bfd98f19120aa8526376b35acd67aad57d8fdc992bab85d60b27b23110bc26d4e954589e69839c934a2e6bfee64f18ba5b323567904f6d985de41ac2a6a2835e66459524932ab672ef479b12aab2ba8318acd7902b7d0f588d71cb2b8bb4f151d3a2a581a382701a7a14787269ce9547da03e0421073172b388cd7cdb97132e2a0c08e1084e6163d9f975892a3bec937b8f20e9ef324bbcb18403e24516775d769c25aea659e5263525f38fb3b26ef2cf59254096b9ce7c9257bf670dacf2a5c4284b94d9fb59ddebdf1510ad3593f779f2d6988f93bc61c909e8d75c2007b4d01b5382008799de1a382848e8b85ebff16eeceb3def3fd6c78afa62525257aa9be383ea7f5c04274b1f2bd365d8f6c212b52bbd0f9cad8968495516adc3b164249bb33b1a58793b11aa07d17a82d9046c47a0ed736f27c5f87d1c286602b46df9af7bab306761a5b087680192b47c53197ffafacbf2f5e5bde50b10a09700dcf2e6a55a6269ddf9c0a9bbae8cbf6bfd6ddda7156d7da7a2ea3fa9a8219d1cf28e21ea3086996e537005ae7f52399b84fef33faf9fba2df51390e8387a6468a5e8b69228f3908de7e5df0d27ad7a149c4d10383ed53d2e8e981175480ccce790ef82629878b12a847d0dd3e704fa20755ba46377cc7598a7437a15de9af70cbe1543968b15c271c8716243a7030d9ac1e04f1d18dc11c4e8dfb91d08d4e06e4d25fa77370cd097fe59bdea4fd52eb9daafb36a97a8f60bd526259f2dbc4eab1129cb9748a9aec727ca38df42b5f75f5fed5d551a1220c90d71590df52518044f6c5f802e7767b2ac1b6ea5591c9c33cc17c2429f8ee8d20f06080ab886c60833403a33302da6507602825db515db4bf99da99922610585a1de5bf835e2b1eea58fbda9683e393a85d1526a1a11bd6bc4a8bc31676102949fe2e34043c18fb50055fb82b77722c9035de03ddf83ed20eb6c4608648f08a0532030d5f2109077652c63bfa954f38ae121cc5d836db03c1d58c3eba9e9508f4c01031a12e2941b603c6338dc667b98aa2d88b3327fa19fde151db78b815ec0934032e1b5bb96f29db93b1f9fff774cc79215a9120ea897c0d7e1fc7f381d9b41361dec406626c3e9eb3b5c50ee7480a8f972a6633ad013998e6dcb8bd47e1872f1b9de56329fc5114b775b791f51f7ceafb6e04d6eb31dfd04cf7b8245f361989e8e290d63df7430bfe2482c99c7300bbba61cbbe6c88c4113250b2249afd7766d27c314fbcbccf5c6dcadce1a0b07c35259973adcf5404dcec0357cd20fb2d5549d02aa6c158704aaa3259f42ffe35039c3d958cd3d58db1bfb682074155d8bd9987a1e5cebd304d53e48d456809403e320f519f360aba33bafade66b3d092e64b85ba29f0732dca9ce0ddce1aeff5f38dcd3e1dd42b37c9f0eefbc4c5bed567a900ef78b6a59acb4ecb5b5804248a6c44016d64e239362f8aa7d94a1f386855242750e6a63f1020f2222ae6de6252b846670ea1dc3d1747bf922b2169aa57bcfb52911df96741ce9fd02eff51c268d650e7e51df20b9ab70b613659848ef5cdb030a496b0122c6259b253565422fe0d6e836fd96b0123e3ba09cf30ab74fea92fca260b03ea94bdab94abfc5ea66a98f1568172707ea6e7e69efa4dcc4dd540b4435601d2c5f3dfeddd60afecb5b8b6826779bb4886a3a2001b1c965c7998f3f9c275aad03e8fa16a4b903d154fdd516eda8fe52ef43bb250bdaebaaeb2f4cd64e8fa6ee6415019ded128a27776742bf2f8a03b12275f5a5af7d59952bbadc8fd2d0414f4e1abafe070dc9ce706045a40e5fba641bdab26ef0f6c501bb5851be6b362fb38cd2e6994a991d5f48bdc69d94265f59d0cc02b13479ce3458327807c364f782e49d704c7a92dc46f225926f68a71cddae958419e5a57e5af872a8abc3cbdad88eae890e2fa77714acd9f306aa8e5e986a20bdb06222fbbe138b962bdae78be737b868340ef300b627f5949c83d9cd2d949e5917e1055992ad44c4a0bb7c7c077406bcc3ed476a09a35a072a1a970d0b59458dedc0ea70a09dcb4ef8cf85437f0657f0dd5084b3dc025d12c18c1503af1abd8b0fcf287fa2a19e05e3c32f4db470b0d010b0b9263a2b6c99f6020146e1616061433dceb139dbeb0954c0bfa0ad2792b38ff36f6d15cda0b7f4fc7b446076b27d77acbd8ef509e508950949193bb8015135939e5cf37c9ecdc7ffc7a8ea347abb99fd3769e910b2fd7f4b4137e492fb6fd3cdadb34efd37a9e54899d17f9546ae2b333b671dfc993256f53f51c43edb255cf9fd138ad8e770fc57fee33f2685dd160335081ebd580d5939fb1f91bea7d52cb99a0290f8ff21adbb7a4f4f2ce457d9b5805486d5fbd7c7cca8f7882aa3211fd4a74cf23a62e015ace0530b41288321ebee3546a9621f7d1335bfaf772c32ab630453383898893f04bcc11f48f0c5f060f39a0bc621480fc2f2166eb7f23f77cbdccddfc184fcc87a679ec7009ff0e6804e9a17f0b9274e57cdd33444697870f8421030f6c8d240b0a160d3a0957ae5e04a8d3cd22e91367c60c5f1229a2e7cd02576d5daeb2b86a0c99cee92f2eb39e77c80a01bf1cacff0a9dbd7a34eb16c4a58ceacb4c208a14fdbe97aa8bfb1c60980034c4eec5d1a29f57901a39b47b9a0118c3a999ea0634bf6a02e0e1d20308b4e56198c2a596a9b14b3ab1406e61dc84442098a33344a4d8dd7372a1804f07fdb1ae0f6e55893cddd942046b0d665f4ae2afdb91c5a0fbc5d15e01e197d9ba5266bfb8684710b56c9968912c32499726887eea29b29b6dfbb7d64f7d0e13cfaa1df175aa9a1a19fafa99e040759880d13b3139dedc2b874b600bc0b113244be086fafaa826b89030aef1b1cddeea66b9125f3589602b4ec6d7ae76f5660390a9d11ce05ce4eb53239b3ca4c2cb1eeb02e64795b4e1a4888fc9cfb164552b140da2fbe989ba76ff4bf8eb56da8e0da871fdd063c6143a80224407a2ca2a50d70954691b2dfbd7b3badc20b7d45d8d8ed584f7c8e9da2922bca5d6cd12406380593913389a9695a616835531375d91af9b041482663da1ad733570075e5bbbb782ffe34122645f9ef975157337d6d6e64256f68bf6cdb2e27432e2226e192bc76a9662f519bf6d6d8f3986386d5b55b5af69f03ca1576f2d26e4dd815d365d31ef93bb06a6e8dd751658b3da7006c01a85d15ea8c1180b701f01911e671ecbd7749136613d12be67dc74e17aadb4e7ad399b709f27d21df93d7548797a516114e32627bdc4e024da8420b64c0abd752db69784274b0d664ba531a6a330d8b9a63c9a864f64000ba21d410dcce48f0bfc348e0d0c2d5b83447cd8261a3649c1b025fe661fb9871f6cdc3fed16595ed6a4e848ebd9efcf4714b3379f1b410a5f8e4d96babeb27eed7952e819fbbff9b8ea50bb07b6741dcfedd4572601de445aaf074f4c1b81bb057d7661fa4d1a8e235d4ac0a2d939d5e7e667402fce93d8b86e10eaa0860a01df509fa988a1d32b432e1e31f2af53ea8a6c7b9215db5e52235ad16c315d672dda242dd83460f6e9a20ff5a5e5b1df395f3156e4fe29f31b2a63ae42b472395e6d8d3d150c3a54b92a373739c554a1a97d4f633bba522a8fb55b727cbf5857b60cb4816d43b645e06a2cb7f5aacc0d271d0b40331e5aac3ea8ec6b79b5572be74061ed486fa16d7ee05e10e4bdbb79d5eceb49739ea9356789aadb2b1972a0a6d382afc49f7b64fffa27b73a77bdb06cdfc9383cb6c18254e3592dd0d2dba3355447f6ee71eddc51942d2b9605748f11c56fa339e8ea7a22f0760e87b3d557e72d679fff2435d763fdf3e6d8d9ce9256b1e77fa2d8006b0c4d9e84475c6b08929d1bebbbe0e8ee27cebf899713ae37e708e9cc814e6c4032e3254efd85056ac83a08bb1a83998fabb035c256c8478cb401a478d306b3fd3211f30d9c7b666a358bc338b2dbf169e41927119f2304766bb81c739184c1c512d6e320b4ca2b4d42fc5a29963a3768b0dd8f772313a254fd1e1119e12a1e54ac0e1fe73c7118754673fd32e501987ac6da9c5d401db27927d0343c118461c1c3eee3af8941967cf9483eb00e201b37fcacce5ffd58417585db72580765eb3ee5254246bf00df65a5f2b39df696122a702ee6e9bfbc71f86b5132fde89baba0a723e5c6d266dafa58e5718cf8d9e4c74c6d4f94703aa4e320d83e712780b749fc28d0db77d8cdf703fc1aa4c36c3f54f9be1db5a878e9836d81a779b209e3e73e5bee2d70316bcaf8f3faeb8712d5ce6f07b2d33ed4e3e7c543525a84ca8822550996c9d041dbf2906252d7ba34864c8e2e1116791ed21acd481bdb3abf64c2c5ae03664d9fd8119cb1517fbfaa74f0da8e9c263cf2c7416a43816499034547437402c1b40be79899a3e2c8302d67fc2174155626f4ed8e745bd0b762dc292260b6ea931072d3880b5e8550deaa211f00f6499224ba9c6592e250b122721830ea128af03c6a1a17c7e84356452f6bda6da8fcd231cc4ed4513e5122bd9b3bec4e06d2350be5ac3eb897846e95a174501e2e6c41fffec3cfebc7d1d7e28fb8ee03921aac6ff10b8044ceec40d4994c6d8ec075e5305f73b2d5d646174986ddb022b33998129c2131e8b32a79a519591b647b0030bdd21f2c28149770b172bcb0f220a0646490b94939d8d9b4fb7346f1a46603e814a1b756d112fc089210834b6f1d66b8ea2d75ac317f3e3e54c06999732372304b9d9ea35ccd2b7d08d625356d513a3bcfa4a1c4279568397f971135f968c6a996b65de4b4eb55376f3077714a3f9af382a47addc8e50095635474de2dc5eb90c4a3824e96593b6199a856f1932479edce5c008127d33d10e166d87bdebc26883aeeb314dd1d7c09434e050c2919326524341af68ac0d8e54fc14d90a3a1c47fcfda7ca984d94e593350b5e6e64b9eca74bf618d580166b97855f4c6f850ba3885aeb9b94cbb4a313b5ed1b413fe0ec2951eabd2c75b1b3e08737b73ba27ed7b633adaa44da70743cb5c149787bcb886b04a41657d62bd1935cdee153898f44a77427f923c6e6e88c21a751b9d389e5d0f7e1e759aadd38615e58e35dbac5723a1de7a54f64ff31072ecd851e30926e8aac141abb82b6f005a7bffe5d2ea7aa3b9828b0d3f7a3d93b0e9754772fe6cbac69e0456a9ed339b31a8bdc8b567e94cba862138dc6faa4f809b09f3ca7b31b227cf6b7e67e9fffe2428ffc5b6cbb83f1ea6a5db68dd795aae6868ece85ea38ee6656653d310750c057bed756b3938293715af0cc4fcdb4ac47b6608ed77003e665495f007ce72a48855f8934f9c6f71aaa1c3818f06c7cc2094ec020ba0dd2fa6fa948d12db2382d72a325d65121d8fb52e882718286581737bdb1afd4d4fffaa04d778dc09a49ee05f72b4c01bda9afd4dcbf414c89404833d662538d7d1b7986be5263ff82a35b160321d0774ccc37267d69eb2a54a391390af9751da6f7564aee8a752592b20b25b23175d8603a7cb744af1c45e7060c55f099670da34040fdaeebf5d46e68965a36421f976adece402154cb9ccee98c61b6e49eb5c591d166acbd1e3b43e090da32c594da653fe5ccc5044244e8382134770a5635ad31c0d6b2499bfde30b7a8b53be0aba1c8c38789bb0ca32474a7a843a391c72ece1ee549ca0225e41f3064e4c272ca9485608b08c888c48345b7f76ef7450f5f5d6ddac66ad114aa2fbd5b0a5c2b4d1a470674d2383a2d90fb533010a5aacc7efd330d46a98d30347c7be29da13d5eb3bafa968ee1916afc014a80e80aad48733ab446b55698d20fc137c695cbdb0dbde23bc57f3a8dbbb105256b9332b52ac9a555c1de21eae9621f08eef69d78821f1dc62108b6fbd0839424da86ad10c176a8367c03c4b96fa887fcd13fcf6f659d8f83eb0512f42c18299c32a65c4011a76decfe3f61ad6cc212a4999bedce7343404131b20e53cf824bb8a36032d05224074151730c8b4450456be9176bd860a969831da642d2766f218fe3bbadb1f2687ce28e11023a6b2cdddfe5f4f52acc299467e5f8d64ad37fc1b3c8ba64ba082d77fdf422456125576e35dfbbf987bafe5d675a50df081c42ae554ff1500523445d1342dcbb27c2727e59cf5f453e8afc120db6bed7dce99a9d9177b59240022363a7e0d9408b39dc0e2b369776f24a041a2b743baba668ad93dbdfcb4989a22994e85b8f7f43cdf1b25b4c7f1e3ee3f58cd38cfe7d79f16537f0360d38b95fce18bced28ed775eebe203dd9fac9ea8aebe8ee111e5f4bd2c9f90784132cc29483c21c89a74ce4c51c3e81532419890c4e021eaf28c5489d453e50d33e6e338884e11a5aba859f7c488473fdcf697477b609ec4144e50feb5354f3ee23384aa40a60b7bb33fce359a3bc984b0eda9983d96bca05bb47ad39654ab608b9784dc8c395b35c551115d12f610bb5214fb82fbf7c4184fc8141fd334964b64254dd98b8f4a293b8bb78256848359bf931b77f68d21793bc3b560c7712d53fac81a8e6dcc794921f73bf9b6bf25dc9b9638969baea0eec7398a6993c3b890bea916931e3378e01f141c2c4585f32bb9c7b54c66a9bf7d14003bd9713077bc4d6947f46d842c9d3bde6a2d64d7cf420cb74cd458d2f9c1c80c65d42082bb460f9cff406bad020c47b314c5c88236402c64e515f8cf9dffab5e1bd429b216792d36c3c8d6ad2749bd28c8a1cba9a0d747423af489d7d4ed2db096fdc4eef25d33564ab046a1424e3c8a8e942ce883175537b9a6393d058d8f0924e3996276a0df7e8f0be3e93905a9fe3d8bd036b07c91001a97d86c78f95c0b1933ba2d33a91dcde46c68310f91dd6ba79e7999d6a10dde6137e89f30c3506d1adf40bf72cf1e602506fb20d7b5f2669d3481a1ba267b0b5d456ed4977e637be1857bf068341996be508fce0bda29faa2372ca92fd49585d919bdd3525885434d54cc4796c760e8cdaee3d6b7b42217cfdc47340b6a309db06a09d18bf9b5f7a760195ed4c024d6f8aca9819deb1d933452b6deacc941cc4669a96e8977bac199657773f481a6c575bd3f02f5d506395f9cc4acb0bbbb1bb55e44927a2f9d01a88fc0883adc8636ab0e5df075b9b338756e7c9d50fb4fcdec495c2235edb3c62f37a6e005dffc1e8f64e7674bf7c536dd54d272e7a8cb5915b541c07da7cb506a2d96cf118e923fd235d3c11c011b091487fe016e87cf8a4a174486cf4e6bcb3e650890045273f04d7510c13e39608469ddbd60765bdd79e7cb60fae3a9a25bf5f77cc2f0e80516bc9cf361d030d448ccb164f771da305f1447096e7f057a68a7cef0634f66781d10438f4bd38e83b78464a07520cf5b96bfce1893c52b2a8a9f1834b3f8f81f84f9dd8c522e0937700e06f9e51bb3c02934d60efbc38fdab2fd4b57574d3e39ae911fda9f19d4ff047cdbf361e08a7d9aad274f49339d7bb6fcfd9e15671761511cc7feb3a72d1329ee8b78fabb9c3af92b66f7b8f992fcb6c2f297747d1ae9a0cec5d215e5af8fbf07d19087996fdb468ab32d342dc0e25d816de905b8a4c4b2bd3d2cddc665b624c73d39247c2b73e8edf26ed5bd5aa32553dd1a8b79692b587515e9fb472b9c536a12d04234447ac9343b49042892a78c57e83a3ff279496ba4242dd421e1fcca90a847396e447a2426e6315e8269cce1aeaf659607d0af765fc90696f26e195c52586048ae709672acb1dd30a107d61286fca4ceb6223d3cdd74aadb24226b2684c61ede32a8659926be35afb3f1ee626a024e51d64e4f717d45ff7659a1de72135ce45c04482121ded65b1631a021ac9d4010a7de603a220335f98555a631b098523f25e38ef5acc9ce4dd240c2a5c910eb0bf06ae0c1f87c2734a16f1d985801f1ef155cf0ac469d72adbb0834607cde556b7ad142799678a9eae58d9b6f61289dda393ae32dda5ab1837afa403be98ed5a7b096cf368dab7ba623d6f31af7e8e928b8e61d81b401f45325373eb4c16887130fe51138ad25145957d20faf315d873fdbf7b80b64c54ba440f51e0f5cfd4d5d737579f2a52aa06321fdcd305f53e437a6cfad13b86df06a780ca1a6c20686240cee6916dbaae98cc5b6b35217d56b4ec5b03719c992b701f258aab77ee71ea9b537c6db6802fc6fc87a9550c4b649c445074c8da07d30d63e35ce8ab7b376bcded2208c55c0fbac9fd69c86304defdcffd592c589bb3fca943cd4c87b8ece7fac70ee9b723296ab3d6da2eb33cf36cbd8bf5c8f488f8f8219c11c024e4ff1993b05ac0e2813b60fb02825cec66988487dbd67b79cd243c182661f24074e27efa607e7e721a07b597fc70f16018021282973cd50f06a69c38b8399e6e1692691af02d8eebdfa578621fded7ba81975fd907e8b180cd47f86baa7cc34bf01717f42df27734dc44e6cd1ff909c0012141e9f72b9f5d71c04f4c5de62778025672ddfd333f1112c7d9fc278d1f4de33ce733b9fd73e31b72a318d4ffda78209cb9691cabfcb92497cfed8f5ccab709c97229df869479fdad53eaea9e6f3ffd2f9898ea1f9998db558e39088ae0c9331bd3fd276ccccd92665bda3bbfb6149a9616a6a59bf5cbb6b4ccb6f48d21ca4c52b66a5399aa9e58e49c84216a6aaab2ad3b8ff08d22c330bba9194e41138c8de614e6eb2ca7b0a08bfdf480d12c9f529c42f186531845ba09a7330622738dc887fb52ee661a5ca538851a93147d849da5dc3e987676243b1388a21aab4cfbe220331f38d49cba02364a947fd6fd9dd730d29adcba0968ccff72a493c82ae8914ed191c683eeb0fb52cd8ef4921a69c350441aea59ee1f4c4325a97b4ae7416d55e603a222335f58559db95dc050c77d3df87cc531ec9ffb9dfdfb5f0c751681fd9b736a9d07b07ff5eeafec5fce5c098f60ff98bb9c45ccfe116548d83f7c401464e60bb38a33b62f186a55f76f7f7098fd230708178948277482396f164050771ed19f1147695b9e581d9c265b96a32ae9f8c6dcd8855d99427853139b82e4f8c2e33c05fa09121ec0673a4c250ce30781385d9db1da3ee194634694a69e5342dc152700ef9ee51ca0c7a4fd840292ad3e4b073a69f6ea76c9da64dc35db2bbaeeea124a39a8e1e20b7048849a4adca3993e40766306e6a7df64c408f3f20c43c906967080fe8a9e7522c8f15d44d691d61ea9082aa0b1fdea942d7f2347888953a04cce556409863f626f3a4f3c5116328be5f479a43ba5b704de5303aef2bb7796e91220dba886242926cb0865cf09c854d5161bf8abf74140769c588813c510ca615521fb10a54198c84da60805e0abaa422b4344ddae324516fa1670b6ca3874f4c470cd985c64e6edaee1bb413a6493bcc911aa05420d27732d9d382f7882ffeb412c6c46f7da207ce37da9253177c9aca72f04f23bbc5b610c04b62261ed7dffcec0dba18192848f31d9136736fc5fbb070a9d455ec4379c03ca5b4b620df3ad23dc0e2e65e9651daf03cd18c95440f091eccfd1b6381793c13f9dc84eea518047f7a947211e3da41e4578f4987ac4de1d4fa9473d3c7a4e3deae3d18b79d447605397e4c3fe7426f92c65477a05af970d394046afe00cd1927480de12caf71a121f8e90c148f3e6aa88ec64e21362625f375e946b3c5ba59fedf16cf762442a5d37405d6e30d2cf96705d5a7ce0598feaa2dc2e307583a2dc02960c4912910d48bdede8e1505397b73d4d10ddfced73db68df54bbe9277f5fc2e46f3bf913d446affba395e4599cc93aec13c0dc37d60410a55e134e05e394b9263cf548de2a4796c967e5ff608238395bc0a36c908073bb4888833365e86f62727c70f1709f10a6930c0940d70539d4b84bc06c973e2c5f44883ad4ddf36fa2a42637181cef0422e509d72b81886ad273f7049c672c6650e7764c163a020da55c57e27315648a509a39556447d3cfdd47e62de9c1bda64422c2958462a8bb7800edf4843a2a7e8528e3ee28fdcac55670857ab9337f4608fdb968bad6f1af0b36eec61742709494f4b9d3869fa13e48c1fd05392d48a9aedad0db788443a0da088133f8dc574e8403bf15dca9a71703cc2adce258c62ea23d5c409abdb2396f49345ff1842fa535a0a525ff5ef27bb063ffb1172b4189e060a578a16194c42d58a6bdee5f63cb419f16513fbbd0ab6e5c656d9385b85fcd54c9bdd175d5fba50af244d633551a6facf5eeff54c96181017d27b8409c3bda41dd4e6a1c3ef92cd2d5e195708394df6edf1fde92dafd9bda67797e43cfa0d36df819794aed25202b3c64dde935df6eeb5f71f60f50cdf48e1b795b026d7a173ab2bdeb57eabd275c86f3a07467a2b725d28e7c132797f8ccbd2b5626ea764de1527b3ba50be3d337d607b2b2b7c7f2b066d316a5913b3f3f26c11139da0313b97d4a68f49034312f621a2f0d195e4a74fb44d745ea9caab96abe99350f282169b6148eea5ce5e30c90941cf6922d4547d6992ba423f5379ea61b23099ca068fd649ebe53fa3714aa2a3435eaa70b516602355715c0b1e7b9d0225328cf85722834b5d1f54da610c5b8abb982d791dff470f1cfded3859a9ebe5be6aa813ee5eeb8a54eba50ee8edc92e45a4f51a9f77258314b7c6f79a2fef4082822787183d732f9ab2b60dcde8bccdc72e814736e96276a4f757559b00aab6d75c5f58999f5e224c5bb9998acdfdb6364c2cb53336e8fc022d60fd4def00cf513656ef0cfdf020708fb9103242b6fe47142310b4a204bd367f12dd94bde99915bfba2f50116378d8f30b006ec8c2d2674dd3c9b9c13a1688909c002aee95d17e196d017f5522d110771f4531bae57a19d34246e4fd5c15a24800170bb0f732de4ebb66278c8e4c6ed4220b60caa62e655247cc201b705f222dcf4ee98e22444704257eac9d6ef917be84b064b813fc0a3b562340bcaecbab58d16868b99d933b3b0b5b3edd09e7dc894f29352ddb8947f5bcafba954f0bd94634abda38b229c0f13669c06fe90234529f22ca93df026e174c2086ef4f7881434749f9dee8f762e09d927ae4040afc0d46f4b0c66fc7413a3b7a69ff2695b4ac4adf153dee4b04ec54f674c28b365e1511321594afc94413abff4f5183f24f7f3e823531d1463bcd58d96ef1342ed73f42a9d23ef7e229323a222b871a7f6916a6768289c59f56ea01d5c9680320dca3253c813f71f4bbdb085fbaf02cfc4560bc39a50f02de079573a408841ee82b8c0921daeee2d47b4c7aa197c3bc66a8dcc529fe9ddaed6862b4b1f40b59620ed9fe97be604b2b454e1037606ddb7482f4a7fce1f0d33a58a6af1f8e7429e50531b850e44d08f6a02324cb2d590e437d1a3609e38f92c65da9973e4942bfcb746fa06fa14f1fe5eaa29f38c4bb093ab617c8eaad92be933092b6a2269dbcf3c68e68aca546afdce9d66aeac4fd6be50be1dbe7396885a6c70f82ae9fb57035cf2c6397507e15793436a94a790b29fabe73c31dbd12c3d7994c4d4adcb351c1b9aaf370cb02acac48df49927714582038913ea83f19c718df2b3ccad49cf9c07ba241b517c496e3b5620a6418abd89a09bd0d2ff24284a53f0acd7a9d9e1db14c87caf449445e6862179357d83c5022a43f5c0855c17a875e6b6393475b221c767ba86496abe644e7a838d8d832cf980c4bb240a9710203c6d92923e6901ed8eeff5a83ba951338cf51e5dbd20d1b6e5894967ae4ca5cf0c2d1b81162defb39f8567e5f4ceea8ab2cb8e950b8a4ea1583effbafae7f29cf0a6d8021c254f05d44748e82face89b4c38766d4b67e1b38c2871602a7b9091fa07289c461d9cf1f582b44445b5a06ddc87bd3c600804e08613946a5d1691cd3af77b892a4a4017f06309e8c5fa835f0b5c811ade78fcfd236882410cbe9570eab2ce46b71db0ea91b1b6bf7f06db1fa763a0605335077dea71a9262d6598244ba8dc2117672ca1224e875221a83a2b49612def57c1fda76a1fbaa8ddfa53ed036a2fdf6e3fcd6940416f7eab3d8346657d5b7bf680daf3c73fd55e414733bfad4d4ef66aa96ad10fb5335971f46e37399cd80d8f6e8b19a0501ee688a824f5487040b6ff0907a51d39f93f5508919118acc54ce6b71ca2e61be4a3953acbd3963efd595e015ce202b3f3204fd5823c694ebd1cd95f9518e34474f3f0e01c91579e1814a1ba0d2eaea6b579c9af0b88d50154edc8adcb06bbe0565bbada44525486ba42a1172d77cca514b632fd7cdb0271a838e9a7f54d96ffa9310bb505b6239e3b57b96116881ca1dec70bd643ef5a421c5a334ab7a98e7768132016a4400fbeb6afd64d8610fa5f841be3a7577de1152514564823d481af5a9c0d6a7ebd0bad93148bebdd5672be26ff7b6aa1246fcc912ffb7acade5ca66d52232276963362e2fa5528c6ad483865950bfeaba6fd09e06eca7ade83bc842575b297c61071ad7baf4bca295caa7b03628e9db1acc3c316d37d9200d1504dc9804c01c590cc0b760adf006eb64469a0faaec3aafb607285982445932f1ca7bede995a561b15eca684034f50d0a247fd9a6e78affe6dcbfa31b55cbada75d3726e6079e27cb53ddd32ee93e9005334a0e397fc32f9f4fde9808c3bf655712e62228e276238555356396a94347ecba9016f5a4253ca161cc4fec12fe7f1fa6a79623195475e8852688562face15c1dd4688be31b92e4811f8791b6c63f5c5e4fdaa9a1ce842016b27dacaaa299196b921f110288f4dc9569c1a21db8893ac7fa234a4efe0f005ebf001d9ed6493815e4f2d3ce7b611511094ba5657e4df3886fa829475e9a017045187067563f24b5c8c3514b9b7ab6dc6315be9ebfe384d03ff6c69e907d5d784e221abf18820920e53d95473aebff3f59b935cddf37ec5980fc8fa76027d69ca23e34717426b208eef1c4b5fcf4c7ff38fd33f92e2909aff4bd71a88ea1b3754fa713aaaff643a46525452f3517ad1ac4edcef328633dbeb813767ad7bf670c4451f1c4d94914948f36c12dca9d8d27886ca7583cba53f47d5cf1d25ada130647b2a2bf49dc118895ef60f9a7558c2fcf839438ddefed9ea6a860288695d42f114430c8b5c99d55ae1635d28ff11ae48e926d41b85978a4f78fa2f1f3818e521f929a2bcde69ee18fb572ce4f5c18a98024c53457da10a74ddddd40f261171811fe9367f2a718f16e3727da11e93729ef0180e33fd6c376d2d61b317c14833dfe5711a64674fb292bfd3bd2b8d5b6339c6c21534cfba7e67a0a2c28fdba4f94fb6c94c8ad57b6a9b78d667ea8c42c80d567b32ffe78115b15100952324df8b3caf1974ec440ca10aaba4e1dec16186b44f0a1e84518514e69adf2a74beb67b3e697b69eda401a2d8216f689f3e51a74f3464199f28ca198497fe491f6ed72ee2f97389bf7c8ddf92bfc039fee9f286c2127d10c727f835ac5f7eae6f044c8790710bfecb997b887c3cf5b20994bf40e15fec590956f50ecccd8a4e7e975d6df790078ddd437126db1d6215887bd64b8da478c9efd75896171e2105fe9bdf7d64b23b94d55a6d99f2d2457622b4720abf34976f610f79519fea0fc5a1a50ba98fb832fe063bf237a00ca16221ad82d4bc0b3b6be83dcf7f46f4e7105a50dd1827d4544f99b2016e1cb7bd3ce82eacf3dec5591da4e55b335bdd6d1d8e7ff4c427c5a67c40d6ede711a9128e0e32f17b0096ae8abdb83cde516937c0317c5567091e2ef90302964378350e6bac43c5d6236d8c6334a6e48680cc3105f0d2cf5706b353a6d94f213e190c6e0781282a224832af667cc8e61c045b601576918c813e53831905c2b9e1fe004e7ce1403470acbef86a4a6ba1ac9a5402200a3b9a36d19057c8f60538b027c9099f8b26b735e79053941bcbf1587fee2f35f56c7536982bb2923e11411dae0fb12334b9bc11cfc672b15fff1e28794213fdfd3e85363c550bc4586e30f8fe99c049d5db813f58e6cc57570a1e26bf90bafcf34cc148849972c4eb939e92915442fc9ffecfd5abd1174a5843e100f7d9334313ee7c8fb41a6c1c267c1bf7d1f2444b24d643d2f274caff7cfb14396937860ae87b6c1ec54ea078d5b194e95369c9724c19d1b55b039fd217e295034b57c48ed0f1576589fbf5cc1a9206057ad1cde135097634401cde88904f800fe1e5492a8a741fd903a684514574c5f4cb8794b8070c8fbcace0beb86b653e5820d6de794c75331526476d5f61a10ec9cef072328b78e006680a7c1249236adb73801dc325e34f8df45e0898cd352ff76cfeb67ce18e24201042327495550ec7a08fd4736df27893e3a38990a604e6442a7c3a9bad13bd69712247e30ea5341fd022201667ad19a1b3bab33c7dda1e843573840b832a72d1297206039420d04b35b1526f34b0a16b75c5706b60481d4d2aa7b491a29967b931bdc1dd46ce8748c4cb002175d27bf416d8b8a4499a4981beac6553fd5ff63f08b2317827526776eb8025279604590beec4e8c0caaa399fa1c5915cc5d59c047c87f32f923d747be4c4c89ab8eea2a4317234a594f59f745de805d6f23151eb1ede999229cac9db00949e6d4b0edd329f33bcf3c624a03a2312b74c4967419b54ad6dbc768951ea02b5cc5bf1d25b7d11bd58a178e02b627ffc7e45cce492e47f3eaf0cf28e039eef24877d430a736fdbcd9e76fd0cafdc2db9205653cd5c6808f613d3552f1fa48840f8faeb2d71424862012a48efccba9913e881cfcd3905a27c4e134e32678ac276fcb97373450c843b661716ecfeee7accbe6424f1d2c798157b294158bf48e60b9ccd38759bf5eb8798feb1738ec79931b0740c733a0ad1be12eaee822c3f565f389af0d8de95bcbbfc232965fd0369d79d2df14dd186646593cb45efbe23704c0fc40f21a9b80384c4a00142151e69da7c4e167f62073e0e727709488431dbd6d13f1eab9ac2ba57056d44e6c31db9b5505b0bc919450665524694e596b8439e8fcc4c88b080b27e7cd92ae2c210f851fd00fd1416e7be1351096e344cae9c11fc621a2fb4b4501a35f9ecd4f8448c49ade5508e1d11b2f2ae5b1f60bdf454d648191f32c28dbe2a0825067716dc9e688944b7ced79cf1bdec7e1b17e5bd9fdbb155cedbf42dc640364dd506ba3fa9447a2ea02b88c0779253d2323323bce9f11f5cafaaac262887ede09611580fb57a983fc67c9a4fbc1f296ba802790329003cbc234e6f7c42ff2627d3cff86070925138401a9e5375886b2555dd409f2a06aa0445a7b4fbceb315085bb05394631a7da190f0a46c0f9aa69695c05b52a89a9dd8878f6bbe8935c3be21aee1e3c3aab5847794c79b8eebcf8d14327fd02ef7cb08a745107b05b6df1ed9a0529e8b1e7b93ba6d361b99427755866359fb3fd213cac4708ef52a5daced19b768f794e4dc826b347c1b16ca800439a447d35526a06eef53e86e97ac50f8b18e5153112f81980de000aeb13fc2c60984748ec61869e644d773cf14220e0a8cec3392cc38572690884343e03756698b96b6aada028379c6175aa932400ba34c9ffab8a9576540d0d433f3047adaafd0a38782fc944903d62d60f405995fb320b9e1efd1f090ea86fc108a54c0216ec01623385805fb33ef7644f40dc0e600f1027a5478e4d6a9a56e8d28e78eca8ea18c7646e43a17f01d4122e2e0384d6b15e7618a975c21ece73465ebc099fe70a6a0be174e53abe2f50f058c888a6ec7d461e9b6be95d13c9e5fcdb0485fa9704528d2de996a78f1b9a107f90d18cd09cd8c7a45e1c191dc77bce28be58a9024b37b9107359f5c4874153bc90e174702f384c7211037f2ea08d78ed905e9ed2f121aa9e80ad9a1d2a5b4c36a98fe58cb0a34ed3c5352f960c5c1fc24e438806feeb238c5db54b257b71b6393d435b7a8da35d7fcea73ee5a6f76c1a26c991ba077ef79165e2e18f575975abff804c2dee393cc1e9f298618062d85c76b151eb4851d86ca4a220a2bf882317ea7997d9fc7821c5af0f55024b23d095c91ac74206f2432b1aab3daeed89c6b5b06e354bdb2f374e120293e8346a19ab2c8775c8941fa60c83aca323faf1c5839019c0e8f58fcd4bdd8e3133195757eda38b0530d39e44873896a490021330ab3a4aca16848c243af4a410c9ebfbfe0ace52e2631239cb1e70ce9a2f9e69214aab34c3d2850b8c9f92dd95917b2f00d78df477aba5f32edcfae71e8226585df7273bba3b46abafd7dea41852277ca7f683f6cdeb4bfba9a39e8c789a580e3742406d92fca0b988ab8cae66aa0f3fb9a8151962f2665f5080db4e27ded9ac884fe0bc754f164f639a170681cc3fb2fd9d9ee5354a08d771f80314a8d68cd4228e8d5666ad6ea15b587c0c4d883f438072004be9b5b36d06b0474a8228ab80bd0acb55c729d12726d3af79c7f903e82c0a257d3c5aea897d55169c1594ce4f24402c854aee80fa75dcece9882f358224d724a810b053e3d8d88ee979566436a6a2b2bac6452b80d88d981fb611e74b90691a68e331934f0ef456a49161c6995923e891dcc730579b5e1a7a91f3665815e9ef0b2228bc4939c71d0e1dccbb943547c9a5d722b0bc5bdd7c08d51d16d12be3172c84f24b649d0824a8c3ed5e0b69b30ee888564bdb18d6da2dbff7c498bba4aa8173dc8b736f6d3f98a555229c394cd02b62b866fa7abde862f6d28b6afe9d2ac2fbb40cbdb2bc6ef3cd15fcb1331fcf76d38695cf7a98aec2ccab8819502a255caa9fac15a96aebafe33d7af5ebfd7fffe61628a7d3138ca0a9e2dd41e9c8435232dd1813889933cf2534d41f212393d2ab0e5e098e4c01fa9e4765ca926f8ad20b7337b85ee4928fe606b1bd66c3465b2e686e4e1a46be54f806acb712b79a8c14935f432d9cb847569910115b47acfaef6fa4ab2891901189c5848cd8d04a49cf60946c713ce98771eecc9142aa05e4ec76c85a5343518eac0171e0717c5459777294e6085885e84bac34377429fa9ab11cb7f3532a6bd24da35e28a87f0c80971bd43bdef81e7d1a37e3d0287b80916106dcc88c021bdb857c4ae094bac16ceb34e21612628739218ee8b1955e90c0a91a203e12f665bc00a8de99eef2e1973d12830702ecbe45ad945fab56eb305e1b7952d61547a7342f5f48e88ae9810b7623b0872a8525f9da5bc90d2ca59c56867672a1e559167680adddf84932ccd019cca863f67c7b52672cf4f0e73b2fdb875c89e74ecbbc0a8840c4ff0a361ae05329e489e24050e851997163dafac83de617e43c47fb36ad985e798bf2a827e3b89fcc952642c7e7ac796d5131e33f650b5ae70906a14266670c3123988d255c32f6300d5d018fa3976630a7690770691e5926dd3234e850c5b24d1083a0de4001f4fe96d5d84bd4425dacde436e1bd40d150fcdd6cd060052ded5acdbd298a02a79320c18fcdbdd4be9eaa71661f3768f8077905421f4d584d6f942eb90b3d88746d7190e5142198039a956655dd6fce66f105182b95a20c8a5f51d6413595a53b06be268f9aa97cce12ad0a1d66c6a187427e23cf250ae7d9ca5149e2499554c71f58c2debe24d3a6f9a1261471d17a112f1df0696ed681a32fd4556dc8add35ba6d8f08ddc1f65a2692da4a5237f4c69b9460acf46ae79d813ea15c0d1fc0c772f1ea1aaa6ade5dbc6ba2603535ccf8d43cc0ea075b06bf3dd31a6ae39b85fbc09b2590ee924ddc37bf4c83302f1ec52a2a13c60e5fb5b56212c76acc6d2e7310fae3710f02c63a3d4fba595ae796643241d4b377f91e6b2160e107d513daf160cc7022fab1657cfe36478b5e26f1f9eaa1dd7bc646a16194ef274f8ad665342b93f932fc92acec0871e651ca5d07b49aeca12b29c8dd51adb8890ff593702ff030660205b3ddd550095882ab431df71c50d70dcf02d6fed2624fc938ea87a03037ca08c5b0f584ffc1283662939cd74ad5f6070691e89adfedac2fc5c020fb19053529446b33623389008ff0eed555b739157275f24030ce9375e0fb4f4a2c4c945f4968dd6303639f7449ad6580c2f574470351ddbc73c3df539de0f6769a2f4d99f2a86c8d4fd1a93459d0368d4fda4800b6f26a78409a3e6725660f58c2bc2d4dc1764de507e88b9915061894e750f7268b905c056bdd26bc8f1c10a9b23acb44c17f4b9e6e683bd6aea3a5f2fe573560fb6d1847522a1c2f3418ac111942430fed481390a1202e6ada3043fd7f976ea989df4f46eeb0a471c786160fc0dea0e34203578549ed85a071625b8f04f5a4d7bdc22c9fabf3aaca41e3a49a31f54795574ffc3837bdb54d9aeb7fefd21be6da5ae8aad7f7fa06f5b29aae91dec4481d839af05b8506f790d5bb0d59c98e2d3511ab312b6c46b0861aa875bcc850ad85b4142ed617fbb60ad8984aa7655f7a562bfa424ad030846352127222282af9e06c90f3191affa2a2058a0a944afa2374df9db1fb4a7db962372bc1d474677a2af6fa912b6b888450a4f48a9f571aea4b5de5de8452f659e022d47e731a56b8eb33cac598dd84ba93dd9ce4dbbb0ca5f385c7874e34d4a6077aa6e72c82ac032df110083336db1d3013162bd03d6f09351c4fed2d1ee3feb28d9487630997e3efcd2bf503875a7e9269336a9a4bab2ff5b57fecd9c0182abf5b7ee5c9d30e94de5f4ff566f885d7bbffb7b6f2e703c61fd25e41c38c50d1ab49981b2388d3b47b7b02c554caf7a7fef95c7e95cc4eb74c3e200112d05e915316af0e4f5ec740fe0a7eab284ba59330d06d1dca83ad4de67fb848cc1089087f7a8770663d6c7dd4a718d6a6e1b5f1a34d1002682534450223cf9370a3277c87709f7650691dd262cf22ff07b3e30a63b4b04e9919a533d11986040e6ce7be85d23e42d7824e79abdc32a8b06ae0d2847494de1e4a95b15c9735eacc6732e4a8a1f0a930a84e5f230871df23eaec8ac03aa8b64955ea5946200df62dac461a8d7a28cc9697231cce5b79be1a6b3aa2c8fd51f2ea6e75f2ea61ce72887c7055f1a9d5f2e8d1c43624220e2bba1f3cbdd600a53461307315b342c4ff70aa9b408d72ec4589d97cb31f6435fd84f90f63c6c6818dac78a02761c61e5941013dbe4041a51160c811f3329da53ef58cdc8ec13e80736b20af7099cac7904d98854749890fe9483331b98f8956cd285161635bd5a290fd1162b4950f9675b9498db247d1a739d20b005e48ea8aa34d7c96a5200df81067a0cb314709e807e1d60e97e1e3ed315f6bcaa928dc43baa1dbad6db264614a47106fac382d5753dc52a814c3fa04ee8d2cd7d8573af0f01b0956fc5bf845f3bd389ed227fd216ea0685135a00ac0b22561c4aa91a4da19870aca1f0f3f6828373ba716a83e029d9a357c573a5cfce1381693f245ed33359afde9c19e7ca390142219e663590261c3de42d282808eff35a8a583b471cc54245fed26ec89e3a0bc329a04948b7c6e6e10aaf8e4cff6403f6e750a106d831ea85631a7156d823e1e97066691e8df45265d4da9ee0eef6cf1758ba4ea9df811011dfedfe917f33cf4d5c3db8d1775b0bdc7562a24417c94a74311760f4fd2665247a604b11fd93232d2072865a9fc22bdae9b735520dc137c31a8af098793b214f1e7e3b91c22d675e83e7e3d79198cabd6d293193c064dca010858c3b65a8d309351addeb196f733f6e22d4c26cea2549459e6125e3f83263074b7ffbeeace51d0f5f7ea71204b9c1117f901605e40405ef94354b732b70f411455fc5ee5db473e6b0a2c622e95088e1889e0dcf46ffe092a522863f808f5ebfec928fed177d213673f4e3c4363080eb976f566caf52ec2a675b89d5e55bf917bc3cdd599fc2a720a6bb9497e30e5c292ee3b2e2a47294bd7bcc27122669c4bdac6164f516fc6fbdcaac0d1ca3acc48d03199fddeaab65fc2359937b802afac49269becaae499aee4f6a2c43158b2c9713e38c77307f0e0a3ed9255fcbdc40c123df615282163df328100e12baaf340df2ee0856a101b3ef9058b6b71054f049d7d49d0dbe12bda25e8f8cc949cfad4b59905b6277f76b2bae089792890049e6afb86c7b7fa83164d51403a98544a6422196aa49a77090f3090afa98da6a2b5577532e8450f77d36a160aa83b855e23c9bce562191d06091c25d0758985aab3c1f7657b86dd0f15587474f23cd91ca2f2fa76863d32167c1bcbdec987a33f9964211db485c3903661ec62ad5d5c1edae73f3aa9b99ab58a1323427ba5e0741deb14d8cf662af596556db176aee1c102ed53fc5a65a0414e1e905fe7f458ca0d0e1b4b89e70bcf297e58896a800590ab0403ce52eb1742d914faf83d8503087438cdd514dfdecae44868d137c18cf75f6efabeaef231d95f2ce1fbf952113256ddb226c81773356e0d22ab3db18fc3cc22da0ea16afd9ce0d88efd82af0a9748ebac4123cb0cfb1c4192f277369267df8904cefe02159069557a45859a9653b214dded63e702c83c3f04dfaf0d5be52eba0e6725a977fa50d4ecbf2853d9707940da046eb8d297451bde6cea45d6b9f8087746ec776fed703f948847ba2dbea61841dd203771630d74a286c82a89977f5d8cc7be014e0022373cc5bbdee637b06942ab3c756d431b5947599d99dbef08a72cd236747c4f739b9c02944ba8605e419d4a37cc72819d02aa04fbc9fc79c107331d0f4be7d21a6e99301795817dc903723f7d768fdc0ce968a8d6244d515c1f5d9482c1ccfe60e93796cff32976359a04f0f5ae6d39ebedfa0bcdea5967e28d4d18623b7a693f1743afa22e063b875f5f26f9daf9d07f3f954c124d037d4cf15ea75ad4fcbc6811a6605d88b4f32193a9c5b3bb8b982d456a637691c996163738f6bacefac66eea78ede5feaee8408d6cf6bfaea11dea52ad394271ed26b72d33a6bf6766a33cb1c7b98c2a96f4c3726bc0d21d749600545fa56c2ad037809661850a193d2128580e94b517b2dd6de921e5dab082b3c4f5b396e9de4a84c2b62c345410eba006edbc88562eb87174bed5cef40e034e6ebc7f443f23e276f1c3bf97a9135a4c8837c96fb9b1aba6830c7d7af3245e7c72a51687cbb6d357911c41c3ae276a3a58ab8633b09da18dddd6e95a9fcf376304f791fb89addce78a90cad81f0f730034f8c2c438a6f2039906f30fd7991cd868cfdc60af0687a677d86aaab0a598b0ac00f39c86b471fa2790b1e81405d04ecdb964ffa8984918013eeeda1b10992e0e255c3f0f7df6b89700ba75d386f4664f7bc17ec93be69480018392278454573007f6e13ff86db52ca6bdedbe11ae941e0222decc04d976baae4302ce1c03cc62d7e6aa61b74cab8f04ef87547aeb4f0b5dc53605e74ba27bf4ad27a3cd381a28ff6eff4715aa698a29fbab145370ae8aea6739fafbcba790510f2a596fd952066a01683c0ab671fb16f02b451593b29da27302e6417f0f36a6deb0dd34eb3337e59ad6cab2f460da93b92afcb3b22b130bdbc407748565ef53c61ac7fe2caddb54c3c72671258995dabab6f9da764915c1ebb269f8f7a915771d19e505589ac3cbe55b385f304c84fd3588fd0b1db470002cc650dfb5fcf7324d4234e6ee9de38e451fe58261874e8222031d765d1f8f9c0d85c5784035d965b9766124e144340e2463e718b5368eaa3c8ea09f7f57c7ff3adc423f7c8a214cb82d773b2eb94376f534ec21a6ee1106ac7835cd28d01dc0caf8c331fccdaf0bfd61b665260bd0e5c32d9c5a85e4f6dfe4623dd18a7c3f710136988e38a72cd18e2b8eea41eb21e00e85a71a3bbf4676324d6a40acab25f348c4d23352f243bd7c1905bf190b905f0f1ea2897b77cbd438a4812867e98880d38ffa43c6a2c556a421842b35436fa13d25291c717a4f22e8c3e898d81ddc27b5b701ac106a7adbfa4f034508ca739e4bfd84714d7538542f23960f6e342395611902e06ba32321fbe503656a321e8b212a9d942e017141ec416000029cc37d98d14b9282e44c2bbe473daa39ce64f62c3b373bc4b0ca35379c0255285a80f5fd5b70a8613207f09609dbe0ad0bad1d61750f154a1420b8ed0e5463c2ddd315b2cb7d0808e1c4d26e60acd2e5a2f5628ce53d5064a51939dd42874cae19c810b62c644a88f2ec90a35783c4ee976b797aa4662c77b3adacba130762d61acf5a113304cdce31618b29ae090e3aee103c102b4d95de762d028f20f42fe17a846c82d6dd19479870c7b3db8324d246d91892c4bb33d8e6c7538e5985bd61ba95e318e6b034e9f44b408d94f2a35322139551e277e8b6eb3c2dc0df995bc542e32fb85da1db49b649739b00ea67a61eb3bb96baec125b2beb66f5ed66ac6236aea69a1f00b79ed0727e83b2c256a25490bb72c49d5e47ee530ff83a516b1fd2bb3e7497f0a39c9fc0f7569ea71f08c2b6c41d1b962a5f674f1a9b11ad559e931aeb3dd4dc559112738f6b8df46725e4ff0dff372c631b6735203a9c78579db15eafe48f9127b74ad9131d2df788836d1eb5d0e9351aa23fb12f537700adaeaaade5e26b862f174352e58105ae15e668645d89489c3abaa2b76f12eb18f40b99029dc808e789099efc19c66eae8dc4e6825c749cdf598965ecc60088fd7739d6e5dad6533fd31d6d2ab37d3e113073cdac0dc1aae21b1bd6dcc526c53133d9799899d869949af604648c9a89e4fe687af2730b819c43d76699fc22288bbe764d04708cbce91fdbc4b35a41a2ad7e26144fa82fbb6f11779f6798f63df19078455e7ac5c080e75785ea9ba9b6d60974f05cf6f918889b88688dcb71f28464109c40c76f5747460aafce3aecb6c0cf5b50333dc2b172015cd1a6c352c73dd156d7767ae7637a423b7601d4fdf789384734eab9f6b5ba170c6b2b4b99993c4117baa6e1cb17d93c386f7266f0fcb174ef1fbe4ae786afa2639aab9e806c743dc87482fe6b73e1c58055c53a07cfd78614cd52b192c9e16a48659ba176929b172e78ad2992a0708762bb92657d58264a8859926741b3975707a72d2ea8b613e1595f10e597629f77c202a47f95d9c554535e5add628492349aba98c3d96cab182431fa6f29fa3327e8be2f8f7d11a23be3ae9b48e2bff2e84638869aef3c872e5b42af02cf33c8a5a5dc6d98982f303ba658254cc8e209b7581a901b4854b333775a40c8342a8c9eabb5c3d3b37797ede4074e2c00427908be01eb63640a147c70dfb57af88f01ba250e2ac6c2a554815cd6bdecd35f640a99fb8e318718510a15459c1321aed11bcf03846685285bd1436d04b4fab99081dbaf94cc35cb36973559073657798b9ef0a7587bf0b77ccd315312cca1fa1c6aa6a4c7e7da19e5a29ceed28ab70fdf237b0b84579f8b153b4b6da92772799651b263ea61c3bd39272514d1b0cdad8c0fd506517be3bab271a6da218d5b60087f29e678b7c2e8e6d1988c61781698b1ca58d70ca7f086aa1edc5412d77d60f412d646251731b6af8ff30ace51a87b57c8b4841fb4b651c31fed3b8979514e791bc9f90aff64e2e4973e114e50c7c6e324f99b0a7a5faefc39e1ad985c8c63d6dd57f1ff774f381e4c6557b7370707c55875194ac891262a1ced92035fa1f5f120772505667e237ce9215fe8d07320ef2c3752343f17a150a62ff3c9793edd917ddb153462a0e7dcf0742bdece0dcf1be8787d033822236d8eea30f38b9cd14d5729aff6dc095fa8f03aeb0f3aef1cefb21588aecadebd4d6fdb6b59da6faf1d80cad4f71fd28aa0bedc78bdcd37e7ca9cbf4ec44427d60760e0d0acc541d0a0d50e27acc506e66fc4ed0720d31ac756005a28b547e79e4edd90e521c0abb9d1c0aec0130fee428cd38ba20cc7d20fa8b765b9e2c402fb58fcc6edb8d14364fdfb8817bc53c44c789fdad57ac7c5eb233c3be2a6fbfe9812c72c4ec16f6a19745357b4ad3b2cfdcc01f11208c4cd37a72ed7f6b004bb5b84b2e2d78f0f33130b79639068b3ba1c62d3e08b7571c69194c0dfe4c785ca5456f43d9c3235156674ad16ba66ba90623e195e596e042e84e0a01ea0c2b45423046cac8557d11ed21010053e5460218cb0a09f86a506c248c50664f122374b6110b174b38e925aa4bf88e5378dbf396578a74156a2e27aca9a2d951d358de34020f10ad497f0590b73b2f47666a516e7c934e5ce13ce7dab4c0d72c0ddb8c54223d7b84be8471d7696f513ec03bc11b2ccb9b9c1f8cb2672185f3b880d3759df764ad669c9dcac63337c5770c8ea5e46e1e0817d9e44b0a564fc067c756cf692db3cdb989febcf66d2f182c01e5ed1bffb44e482a32bd8be64038b85b13f6043013565599368b067ba45060b328c6ae5eafe5efccdb6b3ef7f3912a8c54ccf95f653dc363a87bb8707d5e2b106e8459cabe1011a933dcadbcdc5ca5bf8a596a0ef3022ce6d1b606a10ab9c960e29cd4683f0db6a49b3179a876d0d8448415474d2c91e905310601f36df0b6f3e77059a8c18e4070c2c6538863bed7a4bb7d3ddf25825eaef34dea5d902efef17af75de62d78a46aa89307c19042bf9ca95c62932523d1e2d39c726baee5cece4cd26a0480b98b5ea2e1d4dedeb06d2959b0feb32cc8ee8a71954414ccdfc6e4de8a8266ff2de1e1342499d06edcec8c9448c8089ebf8984b75df941222cfe2811c23bf71c901aab103425e7e03fb6591204c1a6e9f6eb76ceb50c40b422106525f45d2d884116c4a70962a6ccff67f4ff0bfd3f3208690aee4e7dd1f5e64c9c6b66ac8ef0beea4cd51bb5585af4a6d2a8c33665999827bda2dcf261bba42530ef2ccd214c49795e2ce51d80e9ac4fb6379647bea1568db817e197e1b2164dc9ec0f79ddc9257779d594897b8b77966b7ebe6982f413f71214e5969f17b8df14e3e35f65d1488895d445e71d659dbb582ac7d7a523bcbd2c73797d1687808ef1d672cfad1f9a605a49d9e12dd5d1b0264d70cb4422fcb13a1bbd1997a743e2cfd5d5f4f2e679d128b779164807ec5765999f8fca2969dc6fca31f7529fbed8b4e3cd550961ab0c1b012b1ad9a4035268eb097bd13b5409610d8443da5ff26254a41474ba5484a01cf5135f386d5c601c89e319bd38473e8c987c55093d0e909050dd233545cbf285ff4620e2c8d8e39934cf9ec94b19c2985444fc2642a0f7f03d0b7de8083afce35d88f7e333dd6410e649de7fdff6c8dfc5593d272d6c49ad1c79493beab5c33dd898095657d94e35bdb7f55db097489c943c6475876a266f4652b81f9dec8808b425d51e5cec3d7219f95aaa05097644b85a04826f178148618ddac221c465a0575376cc57bd901bc5b602c06e20b3f1b8ab6f44d8a226ddc4e380396fd8962547ddc711cad31afb96903654c16375aae076fd79bcc6588d94660c304562b065047ef6e1f93cc225a7a84c81558789c43af623fb1405c9383294976050275e6e90833badcc876979a5072fa8292f1abf34d24401f25c3d242be75eb57e79bb90c26bc28e552077d0cf6afaa36395f968e3c18a51a288df68663b45829eb3457209b193d307c2e4c7524c1ee2879e50e4cbb6874f6a7f4c428cf3023f4afd3351a0ad99831fd4228e309f43b2f02fb41611234410dfd959da461eedc59096e3006b4d6112bae65936e36291a6544adfa127dd2ab9c0da2997d0f0d84d7d5d7d6ce19f9276e0ca3168441d7ad11408263b2cb02e75080b949f870be05ef2f3ec785b98579e8a785e4352484264fc22c3ebcb27ff48a490bac4b38eeeabf3e26b3abc930420efeee5199a98c5bdd52708ad283dad8408ec42fdd3ad92bef5d34db91e018a67384d7be030e3014ee44b4b81010be4ec610874df3e02c7c66ac0bf883471f427396b3b478e546157b221478e9e8c9042d976d41afed318bf7afd7dfc8f9423fa55b36070d86ac2e89fdea6e29dbd40b109280ca569230a8037a943c12e27365f939168b8a3791890c3299410b6c8ef4004160dcc155fbb478cbec9feead6456991211d33c1ca1555741bbc15ae6e4a89357a882d60c5143a6604388e24c214de320128b6cb7eef5ae805f33b9e28a3e2d54762206c319aa04a7e8ca3447e7e5fbc9193a771820376569991df9a08c7cc7a10df920389f3af64b0537975e1078ef54ede45f85b2feb759b0a2441b60ad1259282a01458dc3a3c0e1a6a205e8fad96a58418fa60fdf244a78680980e09a08ea506c6cce034dfe674c5f3dfb08518398ddbc748fefd6d594aa110b5b041ecb7d8494e5303a942a499e3fec24f65ea8c39696b650bb1b32fecac54afa7a64c3779263f9721d430ec6c546048a5c482d16db21328cf3276c63b290e9670259836b2ae047aff1847027a73941b408428011197dc2fec623ea3ddc820519df232ce86a5d6f26c8a661f5ff971216f385e7a5194a6e9bf9853dcb439e56fa6997f6122f98f6c1da53cb11943b8b4957904957cec1fa6d6b2ca4f6bf9aceea76ec69b69a399ffcde851b92309ac78270ec812b69eaa1b653c4969f3130f88da759e1e33852bd344a2dbca7caac79f42dd577f1cc1fe09342fe2f0dd25dfa539059d65855c20dcc77ee64b3520d9bfa784cd315744f3fe18ac665ca391ad41093eb8869ee83e0067dc395cca291d7da2bc4c77792cf7ed58ef69a8e19601736ed781542966314e9808fb9c5ab49114bd37b89483dbbde384fcb391629d7a9e586cf7aa261f34138bec0a5d460a1b8ef2c3109d3500f70b3b3dbe274b090f23abdd6962b6bcbb8bb5b3997d6219a068fd9dc357560db5043c4885cdd9e11ff659763696f1aec4ce763a507bb0aac6f9da9412fd2ea9f058099c4c459de1aa737a2682aa1a53a46dfb6646725365243bd2bad24d0a0599b709d38a9c5756d927a44475ae59d232bc220076bcd367c6ae4b9a45aab7db65435ee8461a7762c06d8f9263f4ac9d2bc4c9bd1a3aee0975bd33754bf7a8bb2fe3c646a0a3d590428cd45965d4212b5bb8579bc087a20d478022ff863e43fd32f2b00f268f3c5bd575ea729bcd382c330e9f77eab8d736946c68d9e25806338ba359a2655bc7c7b28459ba2fe7bf13a9b7728aea0c8573bfc5291ab5331ab9d589f4c9af37ab3699dd1e506f4f01775e73cb7a05e8fd22583ab7b4ef0dfe668331990b003b3a133556edc6162ac4cb53e65b09992af219a63bcabeb131395bd5600f1f5373314b9d36baf4e8265b03dbbb21d93d946e129b78fa603fe28c67045ae33c517841dea3429336b30813d6924e493187542c62fa905d506ec9df017a6caf12ac242c5eb0ec656bd4591aacc14f736fcf5a50dfbb423ddc165ed8569cc8557359d118e058f088c2616a7ae95de4939f8fee7f4e8b9b8ebdefde70b0c26f6210b94873ce4e59ed6c4c9142c20fe62cb43cb4efa54ab23688285907e2cf098004c75eeac6506589085dbd03bd67fc5987670910412d25beeead9060471a300eb49639993945d6e54ea8895deba1254fa8aa83909b3b13f7ef9e53710cc4746da0d93045c8b2539da68431c4d1781b58e516323f35e2d86d948d9adb9399c1a0a76878e12ea6ca7ad71c7df9e9dbb4380c47cb3aa2f313eb1ef52d967b24a07788edc6b1763d4b87146c661c48f8008e47fcb2c063f85bb980c6263417d47cdfb6ad5034e41a2ef23b3ae05efed17285dba1ad7bdd65e99912eade1a8a1e5076f5a5ae57bc8a2da2b73c22c56b3dbe6c9aec928bb925ee7cc1ae1429002f40c2c466577d8307af29336c930cb9ce4b7c4fdf09fa73c15119678ecf5f30be5b93b4c06aab0e5b99a0073b09ee9e6d00023cbe25473dcc64318ec71a90b0137fb0d9fa5343faaaa8b54041fb7a12c2381576dcb91a9c3edfa773654c2f5de15f71580f6376016fc2fe1c54efbec343ef393a669e29ebfca3d92d722983b33cb533e528b994bac1268c071c43130e85dbe1c0f434eee0c2604d2352364038d186c324e63c0174356ecc0d5e2bb194868ce5d9b074025b08d8173a4ce0e08af318c60de86114de3d22f3812aca09ce11c696c46b43f97c80b3fdf87b707aaaa943859b2aa49b0a9e284b092a5eab371527993e6c4c706687057d2d4a9df415ed8777bc6e48305acc06c08fa4b86baa050c1def392f3521851fc7d540514c975fbcc6eea1e4a381ad826d354052661a46748c6d34ae78287090fd929a3651f6e2dbfca9a3992048b926945ef72f783c160161450ed1ac369bc070dbad3f21f0382055d002f0c81e85bb920889e0b94347731a9c6a00490966f28c7cee8c143647a8495dad18858341f8f8f50ce11073372eacc9f2698ac336ef5b3e65e225b285e492358448973b9441c9fa86af5c6fb392d1138e7779a60081750ee70b88421c566e9002ba0bbcf5f5bd14c06a2886701273ab1444f5592185845feb10ab02d6cd6f74ac40784b56a68267c2ec35eb1ca14d3c0e0bd11558b483150558bd229d863f0a0822624c87cfbfb4ad93240e4421ed97f04e46c4a7f0b07980d09345c0de7724c63dfcb1075b59a2883b658ba4d218b0071456f9e824cf5fc017ce353ba89e71e174a72dd3f3ae70abf2b7ae6b1683b5153ba407c0b411b2cc53e231dd6d9240db8291bb4b426ed15ecb2b9db4b0d0b602b1b4c987a821e703eb3bf05c81e01caa4485495529708f2af1f2d3265c662e982ab1ae0f0dd22a7ab828b6ce9f49688cee5a29b3985486562cc8e16865bf21ba8d9fd1ee4ae486947720f5e488423a63993fe03b2bdab7de3df529fff4e3e5755ccb84949fe0d0ff820c79df7b457acba2baaeb8cea7d8b4deb0af2abc430872cbbf612c19ff7ee7a7b69d71f415e62cf484bae7b3805f9df4c950362e9b54d3276266fad03cbb301febc29150574559cc91b28112cc7549e9003549740ee0f5f8c7f37e503bb921dafb4e06a6a91aab2a29e8ef6150fc8e1212abc728e5f28e3ef939f63337a0a933d273b5535f67dde25e15d4b99d9c839d9aaa2e3fd7df3ea8a36304048ef48301a1be50dfb296394ddc0294af5991784a80f8539572f708164f5620aaea64ef80c7b76e21dead1cfc469cd452215e31b38c47b5bea61c0f16e05df4e6723eb6d0dba0037eae05d5fa1e4fe1a5ba810a97f3d826e14694d1173161b0bf5d9ebe91a225c5b78a610eee396fa4930fe0f4829487d8e3a00c3d8734137f20376a9f22374e87d4ef63ce1cec0af53c2706d1a93de97d779fa01f8fe96a46fe8f3ad9029c066118512f915a0010ab03a4f52ef6c190d5a83085be7b42bcf3651ed639d82b37822d47e561178a7224343a8fe3117c4f57306cf8971623004cee2034719c3327bc58ca294e3958a8d70603810025f5b6f49a4b2bc1b16149c0e4049ca233214d823fc57cec7ad6bb1802960279b8270c4b11026010e0001cf946094ac53b3364d3e7db724e110cc092a193cedf5bda665b4258d80f2d55d11297034739ff564cb1731b3ca20f0c179473c0e29c90df7e1957d3bf2ef1433d2e67452f375cf37a9f668e2867db5595e8e12780e3ac818888157ff0f65d2c20a1d875aea95fe2fdb862b721c2a6728ff29c7e6decd8504f51a6f289fedbfdd0ddb09fb8f08eb209758e7d239da9a744d380fcb623594cf7624be23c3c0fc4fb15b8a0072736cb1e25f08fcb1459fd90774d5d5f049c5f8438805e334c62f7370c9cb3e5acb536c2716b74fa4b92422f098ef542cecd8ca9bcc5e34d9bd7b84ccf2fb288e3503059324b6d70ae70f78a3601c770cce96b3509408568d126eb4dc54055aff178458fbdba6679ee16b419f2e65d2eb476524bc08ff97e56b9bd260d96aa4bd04f765356af898e64a3891de8816f551ca19e0a8f8977c62bd9940b4493d78a1ca60701ccc094486680b8cd912c43433456b51d935632fb46564fac76927c573c21967206635043737b2e1e7a25724ef001e41e0a1111e80abe464f3b862151768931661c38a67c2f14199e2f5d86790753a64b659cf82195213fd43e9e9e941005b5e8603b5839259cb3b34db92988892c75606f1d13fb65bc1908d4413c208e8c92a488076185c299cb3a94e475996b8272810c0d668f6cae1356249ce73c66252f47e060c512c5168f564d0a9143b1d7718e8b4db8d81ac556493147a8b2e2c787c0986403536ca274afa668e72a67dcce1615368fec7b875ecd51ac2c0fa49557e62738d06d21a37ca990b1abb18eb5d517095462573847556a539d0022e63d3c3b20ee80912f828c91aec9657840a0f617582e8306eec022591129900685331c73ec123500e7caf994415f60a080ba6c23a7444cfa73681df272eba4c00f0b4b7262fa32d97134d9d297a8c7eaac3a59a186b1a6224e0d04ce80741504e9b89ab2de8bfabb9004571fb22a5793da2b4df630e1317bb788f3e08716925c77d4dc6b3cd2ec9df9a2fa454bb20298513a17217356d10cb3f436a21988303f0e721122ff2aa7695bdde1966cfaa063a43e1c6ca91af04443c6c278b512284ffb08eb65efd962dc504f046b40138d791a90c9612981a14138d744f9f0a13a4c7ec1e4c4cea904b0bbb7732400892b79216cd4b4f343b7a0759c3be41cc95e0b391f155e1938200de74bbe1534495309a1eb4d7f7b22a9b9cf0ee9615aa970fc3f7e97723b88e10ad454aff046cee5be67f024d8496b0956332c193d6d8573e6df6486404a8823f52bce0c51021fc4791fe627c02d2e38ed1a0c58c166705326931c4278a0f7c108de0edde5846c9f5f2cc0fdb0b149a9200655f07a57ddf0905946e23d1f064566070eec2b0627398e20e91f59662bb1de135895eaa184fc576060dd033bb5467348961460e8b2f57c6f834b10e3d58f5bdfd499106bede6552a1505944a043bd9846e7631b06e525190b29053516c2988a8bb18c40b49be73b49b90ebb3b864390558137f4c44d17cb122c26fd5df5a6942e351e2a4ee8c25d82bb5191efabc0de2805d424e4b7176077dfb1bbd1597a8b662457b7deb0cc84de8b1492b5bd93a6247f880e4c0fd5425e78c60c4de29882ff7beac50b43cf3b07c47baa0d29df99581568303df1b18ff85b4dec574e7a807cb11939db38107232a8d77ce5ce5abacb4d58249839dc4e669179812a93254049eedb88435a344724f5461bc2ff31876b8cd929419cf479afad2d629b0f4c264bba9c674c0f8f8cf766ce92af653b3cc38af5eccbe7f9be53a66994b00c09e210bd7d05dff6d52cf4549200e3b72ad89d3bc81f8f43f689edfad8c531603f46d8af268dbe4f23323349a37fea4ee9bbeeaca1799a4965b1725fc20767273fce9433db128ca91ac3d538b63a20161937338d6306b4b1b6489d13e36bb5842368ea4f0062ecfd846bc634f92898c5177e8508993ac0e102d63a532fb95089b2bcd7a938e0c5e905b395ea7f4e5ea9993fee4a455b28d9b8f97e78c309b3167661cab38c6d5a419356283e7eda8541b306fc1986c19ea7ec434516f51f53083e350af801d4aa6fa00902a46151292a3cea1006d2a85c236a8407fba66adc69a33664d20cf39b30911a889bcce157c750a73ce13090fb66e62cf8d5325a6933feb3bc5794bbcdb06d715a3a581ab26dedc6e1f9632fd1dbc56deec13c4fded0fc31808f17e204d728f643e6f79c686ba0224b4b2e2b38a0f9791bf67454707e6474e34182e61ac984bb0ceb576625b6bb07e704a0adc31f34e6ffff3bec37f6ebb5699ae5fe9f2aea2e75b0e14faa75dafb79347ec5b21a04f220614493ebc11f956fb80ddf0c69cfd7e420e8dee051849454c821e7724d451324b38012f18c1c1205be8abc64a30e849f40adcaf5593cb8c38f4a2ce46951311afa23cc640788e98a917928807f9b9dea30b49414253297823463465dde9fd1fa6790813a1cadb44a06704562a48be7c7f612c1ae26630dfc10cff7a5352e186474cee546e163ce0e7d480f75c38a7bba9ae6a04adfb270408e42c0e042eb6dcc03218b9cec79715c35f128cd1145ac433f8f8bb0a43ec540962c77d1e512f5c1881e97a7e275eab4fcbb8e444295d9af527cb206cb9e31438ef27b4f1219881cfab9f423d5b3f9a883be1d15e1123b924f2da6be16a278eb097bbc7af3cb2263845a242ddc61b1eaf0708b8d683f766ac529aeb7f430315248d66e49eb4893558c3e6f2a477998253faf935366e8f815193f98463d89e604f8e2f2779841e612d0b0c8f7fd16449897568b1dfab320de19558c1b83697ab0ee83383305f49da9e42fdbb7e3435de85e82fc9b7c66323490d9ad11ef44fd949dd123d65dd16a5508a68e14ab2786f2e3f4d45eb84f7c258f6053f3340baddc9a9a0c708288f5755f2f5c53793dbef2be9c16f61a4f81385fb941630d5b63e2797fbb8d1bbbcac50a307b94fcd6c37cd340cf6d8d4e16e623204ea7db2275f642552b0cc11299d682dde4aa884145fe037669cc1711bb1b8746185a99549850c04f6a0809b3b5c2339c004911cde349d4c31aee395e16c7680a1713ecef498c580ed3d763641f3389c6171e7e2e11499d8ca9cac0fbe24fd3304a231534637930ac311eaf5748c77b4f354798de7cb8d718d2f68eaf3cab3b8d91af78b20ce5f4b74980d60df9a4a2ab91c7fb1a197efc5d90fa3a475f914ce30b50e9a8d484fba47990dff36c97e3eb352019c354d2d4fa847843d52a09f168266f055efcf01d4f63229ca646e3d4afd45da1160bc0cab0873231eefcef81b24536cd8273325add1301eb51b672b2fcd388167393bbdf53f4daf7a4ab5959a5eb69c41ed217c6cb5679ad502cccf0b59c4a6c5fc790b807887b381d5d3374991b5c5651a8f3b26d7f5386f8d2b5a4feb563a9732c38dd351f2f772b3610be51e8cf60bbe52a4c280206a70320a22c1ec724f416a57d5b8330334847f4d1b2524ff22f5faf340e03580c10a3ffd291c0d0a900d1952140ea7533b67724495d1cad3bf6aa500fd41d3a518237b74cecc91fa798e728f7a8af7f230fc698a6a8424f5b85bcbdb395850f9680fcf99b7ff7412d82f4920cec94fe683122dfc07f3f17383c9d484c229ffc3a9d9cd29c4762fc7af7fdb3e3b36208cd91728db8bf04ae121ced23e7c9fc83334371e3c87fc0a7b5e181aee264e43e9432c267252ce0c6290078ec3cd22c0258a09d001fc5d70c4bf7cced43314421be821bd335f03dbb69934f225ac4c11cd69b3b04db913c1aea2bbee570307df3b3e714abaf5291e0ee58fe4f72e851f21fd8697ef66d698a9a107ec00efcbd48f840357ba45f6ecc71576840fee155ff41a3fd0da14b207bfcf2e438b845f7a0e89943dc2858073470427174bc319187d7dd55ea03bed5d397091c845ac0477e0ffa496f689fcaa9577e63b8077e0d6d1bcd3cbc631bfc238ed284cd032d9fbba1ad20dbdec28b5dc5ab5f52a7a2f465528bc03b973f4f35894af1bdde0086278972c771f639c97788b61f5e158db254d30036dd4fb562816ea15f219f14a617d1e6f4c84feea96188e2f3ee9cc2ac784bb00989d29f96c3b5ce9f6349b85dbb04eeb4ad12714af2abcdb23fa53e15017fe619dc3efeb7cff3f5f675eae0d43055ce115a9a73fe41b79c5d33ececc20c1b3dc4ea0f35499313e4815bcd1548e3838720d15fc7366fa7ebc053f58eecc54f49f6f66478d25ef312bceeb1f24bb3414ee5ea638048f03e9ae9cb50b4933e2c1e8523f0ed4f971a0e6864791fbdb2dc12348c8b51ef8f7fea7da70db299aeaafd391b451154cfb0e1607e85828a783960e123fbeb74227162616eaf89a1626c6b015017ca3c83eae3fca14658f44d7345ac7e3d42e75f4355090e7d75fbae2ad1d083175166264ea832cc41cb28246e5fedb97ee8eaad2811473bdf9922b8ebdb97de5b0cdf38a1469033b8be70ab63998de597d317a66bbcd6acb4c20c02254e27005185b920ac9d4be30280a863bdfd29c0445680b7cbe1e9789c7914bce4ea168c1333a9a3d59ef423dd68102ed6deeb2c4df65446f03fe5f83ebb03f06e26c54d27bb9c72a879d165adcb61588970342e65ef74fc9a9ef91a27ff644c02e737a71a57009b6faf626f4ec63fa647a3693426d641e7ac6abacb10e047d36f1b373145f3d919be984cda6ebb891a1703ee6f1af4fa11e3d08c7d8eaaf962ff246019aa3c5ebcf93d1910bd253124be5efe3cf2100784c647348483b063c1218e25878227fc4b9b03a80d3c211307d685eb1d8e9f31b8fb4b33372a6f163bd313c68d0b037e9636f4efb29cdf20c1d370308ab08293b703e5f1a885f2749d99bc71df7847adb82caf81b9a40b5e029c70cf08c93efd84b7dcc8465828fbc33066e71c4d655f4955fd6d999a0f2a67729b40cde88fd73c7446efac5753ac55d65cdbc9c22a834320ff37a5cb1bb41223ea7fc949aa48da8ae0a013ed19a27608cfc1b601691c60c32466ece49f1f84e66cf3a3d4581505524660f9a1b0490e4361c7f4cbf0d5a0ff52d9551c9c479b00610857f0cf3d8aad19615e038ebfe847f4fb79cc60aa835f494f70439426b799fc278fb5764952484de4f213eb7a4a41b6c40c2eb676990915595b45d2ba4ca560b70bad1023b384754e6889b0bab5dfe799ac9fe40ad43cbe01190dd9d28875662888302bdfe8841cca0640cb67bc669e7e4773fcc7a289cb9f228176fa2718faa7f597193cbed0f7d582c92992645f4e6d795a7a478beee03724c4d7b98f1ed1f677c81192fff47330e6b7ffdf71947ebe1e9ef334eea2e092bda84058ef92ccdcd57667f1afa5105b7d3dffcafa63fdda199e9102e90f00f5dd142b40a09cf08ec141f8d1d8298fed09b327a0340aa85dc139989d2bd2a462013f0f267a56edc19433691d549047c92b95357855bf25334364adf653fde13ee115a97bdde1c14f2c1b1627bcea7a13bd03a8261b362ac0ebfeca494711141e1abb53aa01cb22d045ca6e4b0c6887056f2cca4e9abe1936edda23c32538ca6293a1609b88af200c9711697591150b44142641f1a7267d13b1f6a06befb0ee432cad8e4f9762c51bfe6c82e93c58850f0faddeeff1104c5460a676ba7c02634b37489d0d5335c5d813a118d81d877186801eaea30c64ababbdb54ca3e3d7a8ace340e69e8bd71bc63bc100e7f4edec3a12d1a8f78a12807d54d99113c69934271c0991669fa9c29e3801d3fa822f341ed210e167da58db19374f9f7f22b46851c91a38df14ca16b1d10444d0edb28ed14d24d91ecb81e249e0b1b6254e119d1876326c5ec70c274a3d0c846204de408d87cac5e7c228e64a94a88e1b44d63d40c425f80e891fe02512ba788216f9e5285a6c0cb3807b1338df02aa46d3e991cbc55b890d62837caab0df6ececc7e04ae030fc029d97ee913460e1e2d104ebabba5c01b111f6e8f7847a56571c223582873659d61327fa48b81d30e09aa6b4ee277ef24644d3be9ed9bde4a7d43de7b58ecefe96ec93acefecc6cf0672f6e52fd28119c2db2aae4f77c608e1fa4b1b0c7b7f4cceb22059d34758082aeffa40892a8dced910409643d0484ab86416bc83fc3a27655ba71824a6d5463771bc68a756f5da658180fc3d1f60352332c0d6435cfaab9f6de31c7c7a415b77a93587a76eb74e3c0fe385d0e9b8209e0149efe145bf012e678ba1ebfb42751644fdc4154e01d64ec271c31647b64fd6e06b841c1ff7e8ac6bfc4a70c1343f6325311c2ec28d934ad55180c6bcbc32393e8398597f2493f242fdf8c311ded9c11e5e717a1dbd0397b2994a1b3fc70e2c2e52ca448f36673767646a42a87bcae3670161e35d38fa191e3a310755481a0e36a9a179c0b8f5729f34902b28df037b527ab8c5ab30a5bc528c4f5480a8b894eb512a6e6705adeb7fdd5ba42c08b99979c6b133d373f57640c0f48c5469b76a4f326799bc63931da3dc4cd96349c5397f002edadd401f572644de903210de7fee89377fa91000a2e0dcf89939713a959ee588e08564e11ad421348b5a04fd71163b1c1b4b43f4f44e4aa5995f2c9259e45855d8f5227dc52e55dcbcaf17208442f57b1d0f2beebcec960a5eeea0015fe9256aa2550ee335ad3e9de69949ce2152fb8a5077b2cabf54e664e7ef62977ec1061f8a56aff199aeba80613e0f78acfbd190c821c4b3b966ca9cb2dc7cb19f3cb5b5fd8a1336d962c3d7e1c8164a9f15b6f397881de37cf08636369e1362dd78265a5cddb28f2d89592607c77ecbbe8711a87f8b93fb3a42913d8c8fffe60e9c402164466020c44e4d37ec993fd99818c677dd159b7f50128f9d327650a70cdfd21379cf8b959c1183f7b90c5939445a1a3c334d90f379aabd4f7209749250c3617197416d7829b339bf2f14b0966a08d6c56d3f9c32ca45ed8c9030049c116e8312a64c3b8dd41090372365e76a61164ee8e3955109e82b1c80ca40b27a79bc8449cdc1c1b64888d9bdcb47325923f4c2aeefbe231b4c104a64a63091783583a6467d6aff0026b940ff0ceb3b46370002401b241a816856ced677ba1ec3dd412da94430069541842c676c1c93c3da30d7b23c82e625843858634f2153215affa559ff050b7fa0e713c4a4f54d6af5faf72d50c21698c809f57bb045bb984a0c098938fb8a41a2d24dceb083b10bc016d7b3bbe0f1b75db0418abb7576177ca537812972bb09388fe39a3701f7923e641081329be071f69419c7481a380570921d4b017ed060aeedb35bc015f6587238d900aabcea42f74145c48bfca802b9aa119ae98df7c95620d7a4f4b2baec819623e7be21a1a38f47ea4fd75798b9be1ca15a5b27610054873090f278151a9a4eef44787a239287b46b4fc7052c6fa78549ec842f7bc57be0dbecd3dfd60c7992c37e676217a86577a9e246aa3ba2169f485e7e96f18bf3024ecb327dd1b8a273f7d7ef8f184f522f6778b5ff762fbd53a8ff1ba5ef7c4254bcb89988c21bf5710d47c3370c0c451fe2ee4ca126f4ca77dfa623fe967394a9ca629399163557d9b18a8812ed785f8bd55fbe910c597797ae4ea7499d7d292cd55fefa683cadc4d1b0f6b06641948c6719ebcc202d15a40b52ba2433f27c8034bfcdc20c4dc15005522e6673c512eb54e724a4435625f59bad54aa5d65eb18d162cf7c9c65d5966e5d586930353586eb9d45a2b6aa6526a7510f1c05c54b5d48212bb526ad9b4c5aba516e511a0476d7ca4acbf57dc64fdf55ba96e91ee553949d0b74a604a52e688eb166e7efab49d4a2df0aab5b3fc76a5d7559ad38b4a25ce234551b2808ef0a64fc98dfe3861aacbc992ca49a804ebcd2a496e4993e853cd558e84082d9180a013bda1ff5d9fe153b46b59df334c4e5bb853489a219517e55257ecd14f9df8652dd4d2d6970bc1526d548a27314f574f0682487daca185285d81423f277b867a0374da6e13df190419b7e7062ea7182f4c78ecab3fe6f883d4e6f3f5e51ca747ba304837e55f210e3980ae82c65b446e8df80569ab31bad0ea8a4b9bf896635b94f0b021a707f56b8ec0bafd5fe408dcad6ebeb03b187683ce2ef8e8267fa2fc74fb891e19f9d8c0b5eec79e6c67b5425cc11560141b3b5545ada98afefe08f9d593ef7f4fd5c6d6c7df52b5d5c29b01fc96436048203caf0948c42d50d8d8fe4b16376c9d40a8b7d39d1563fe5ffb707b71847a182d382f7d66f785f3886039e565a9486952cebea679536759d9b378e00af5a490804193c8f983f5731eb8d15b76ecb53d33c2565f385bc0548cb3fbd89f2389de9d49a297f421d297c56a7fb32172719b7a42111f44d491d31e7d08239372e6604da80343488b4bfe0124bd02d2c6b25d89a300f33fcd060ba00d0478934ed321a75d24e20618c4a7a51810288dcc8c1d973fe0cb35e87007c049a461ddc0348fe212a4d73e28e4049be171777ea055f14b0a511fd8fc9b8de15a7be8896e4f17748fca983a92325d66ed38ead113ced97ecece73e36038d844cfd3a74ed71d1eb79e8839b7cde48a552798ecb999ec5a4b9fb1b51d9784d277885893afec87f538535938b5244f2ebf600c86e4ebbf6e810940866483dab803978a249d668f0571d0c6152c6977647f5bde4f92cc3fde9118ea7942dfe4b075826cbdc39f8800506f85a54cffbe33bfc9768aa226c945037b8bd60330d3dd0285d5397566ecec0deb61f7479528fd1554c75d34ade654381204e5e1882a8751a45b6f625c00ce1f21dc65b8e65d53a0e01f555553488e6f876d2a34bf0f49ffa5115aff839ca67fa44b307d6b3e54d31322531fc415840172ef6b5e35ff90322c40f135a36df2bea4250f2b0fd650cbf3d08f5271115e1eac40389cc03317d3554ae67b20c2f9c967abcf0184079598836b45f65fa17c1fc074409ae12e256f77f3a4d2f51139e00137c0e4c1d96c1583be9717dff7ab4ba86c2d60308c2531971776ea6fc7fd8b846a4ade9cbbad62d7bd2ab7b7c3bfbde98195adfce5cb061c58912893d3949b5b8a393b2a839c4e07ea870eaa220e549d180a132ac171a798bb7a5bb7df6893c370b400d6c9b26d8e92164a777bced00d30cc6087c09f06cc625d72c43cdec51f7785786feb0b0501b91e934233a5c95d45e9e7c7e8350e17aa1b03df7a9be1ad98ada25fea83ebd309398de166ba27c620ac3098cb787b7b3ba6be48df2201754b33ef7e7d9be0d531ce80437c104f30b4443dd225aa3326b8000cbf26a76ed43c6224ce274587fc72528a5d33d6a4d6a20cb70125ace0d377a0e73dca2ba1a6a46b76aac1bf3b7b3384b6dfa4bea5e8725ff8f7262397b9a0a748ba7b3f22e01ab18cac4caedd0902479a9cb63ac5391d331788d9c723fe97e4bd3166a519fd302bcd33662577feff66561688d1a65f4fadd41bb2a6bc237cb94a79aad45e96f6609d80e757244ec921ef12f79ecf7076029dbf4ce0111338f66997cdfca6ba63569092199739b375cc86724ebb23c3b5036e4b848d80a35fc89bd449d4bb69d6d3bd4a6b205abfb39e4555ccb4abda935b67376a3fc7c0ff7d6359baf2512a8c204dea62474a2715770411238ce5b286634d75a1d25ffba2baabc10fd2db35eb1b0d163f1a1193146ced2d00a908c48d0a9439027c665b5de18ce568c4b2635f385094998bbab4d46b188de5f40e257467c7ef2972e56c5358af3071ebdede1f37ffd47c8f82ddb8829b148515df2074b36cf9d3bc44c54bca5cab3e5256e880fd095e6e2cd3153003c9549609cf5ce56f4dd8ec30962d989a00c665383bbf97c295e2096769bf98b44bbff17140e3b463026c365bededcf0de7f7ca2cb3d34a96e4820b84142c77d3ed3f5c94acabd58d57054389fcbc1e0eac90b7fbf4e72d4afd281c18beaae9dc968934e7b2dab22ab36f5664bdca1ea8793ec356ee5b99d3cf814e89e02b481f460c874bc0cace64256fceec742eb367d65473c1a54e3a38bcfd8cff8afdff87a9b662858e4127fb65622b076506112299521156c068fe61e8431413d5d190ba5038c057257f043fb3611e644dc9499cbd5a44e63211bd0ad9ec03043f94ffdef8f4915eada39f9a5eaa1580c938cf2bacb9c8bb65148337b4e16502ef8b055c996a367185f5642f5204739bfea9de41bf40ba7136691000fdc3ffc3de9f75278f336dc3f00fc26b314febdb9264e3388e43082184ec91840006cc3cfefa6fa98e920742ceeebeafbe9ef77edef5f6469fc19665592a956a3cea32ce925b0cfa4de9d5de77b19472159786603614ca07cef1936369f2c3b251a5218aa3f14ca494e13799bde244b0cd1aae15f5d38682163cbc5e18909b6e1a643ad83ed389a3f2930cd4d1d8166266cf4c8818aa00dc7cb9e85acb96f0426f7c977c68611c4b74892f1b10cf3f966105248fe325ddb9c9d7d852385567876038c319943e23b735565eb74fe6ab83d8b9c8d54e274c255b8a01d9719f7dc81300b322858c235bca0f698dadf0102f42535e7e168964c331d95dd57bf8744b62f4844344e8af3d7368a8fb0d62b7d6a873b3f190c806bd72cc50fdc8d76f198138a02070920d32df24ba2434ab89e4074b0e49d67bf953a8ee107a0c6d65f2cbf7d2b31aec527688a58bbfd74a88bddab25ccfc6d2e4a98eb82fb76e1e954ecc15b50a33d3f3d5292b4a05a24c6c640ad35fbdf87f6dfdbf4ffdbf20befb19376ea3702357766c85df4948cda2c2e915754eca30c538fb31b4c9bc7573b3317bcc6e18b2917a27c4250535febe5bfcc1c0a86ec854eae55063aa171ec1fe80a0a9c5d9917089307d6ffd68b9e24154b8aaae3a90e1a920adb11262aa2a9f9a758448efb97c5a9c6c4f7956105f39a4728f0febcd28f060ace64098e86ba6b3d2eae1f1d53b7e59ae38bd0a4ea1d072ec4e46140c9de33a34897dfe73496c62b842fec586e2fb3a457d0a3cc149f0b13eb0b300a44a817888a27c6902f53676ea24e5f97da1c21f7675019ae5e8c59b858a1614cd1234103bf216b2db77b1451e08e16d88feee98e981565c710f050e02d7cc886cee8150cf44c4cf3b2a8cf2943273ae99fcb7e44064cbdbf4132169e496a17200a16cb27eb4dec6b5b78477a0fea2f8e6760b0ad032dbaca78fe2494fac68823fcb15aeb17ae432da9a8477ab34b866987e7db05c73c00ec0cf8a923d44714f3378e771acae18188e832c609e4feab47834ba4cece6479c4ae3537d524cb4191127606217744e7c97bfbeb39be23dc8b5e47a40dcb8adf9f47362d61db004e4013b0ae045855b6f1541013ea205e557f957a56c2bd06e87ab0d1fc43ee77117ef78e6ccf036cb74f8f6119fb493ab2f449e2de9df5e529661059160dca5a7cb8f71c65e209c328371e2e3820ba1e138a184933c598d74a1f2741e101b55397cbe6ba259aee6fbc029872647f69f1a1617c6bd828a52f062054215e5e93ba5dfabe70a1b5f9a94e9aa5e816a1d903840c83054812b567442ea57bdc102d4e152d2faf0ea8a0ec91f8f5e83403b84f9b2d2168141c5553ad7f6204dc176ece45e397ddb096513a5261a85ecb4eea71c5ba2077d41c9cec32f444e3932f5d40c76857aff5bd3963edfcd4c81f4826732551881dfe10c07fb26f9523507045eece1a0fb932986529b9450cea6f3eb2096052c973136316f987793ed4753186861255e4b576f405f7cea61bf892dc26e00143f072a54e3198bf04936ab89ac9152121cbb9c1b57c517d1f6fae0890e56a31f2f573bd9e0e26c831daf0ed7a68fdb9fa732bda122b947f4e82f161e37e250a53657037c8bdc0c49148ecad4632683599a90d409fa5e61fd7718d745eeb1fd60dd0f2ecfe4ba0f2954d22dcaf1254b8cc763aa58bda1ef128394e1c580bf1d160fbfae97717c95185f1e4ff4170f2c48851e403628a0530c8eed383d6685d2f285cebf4959455204fbd51d637bc444e408f5583a5c993deb735b8bdde385ad78dc6b022d1f441ef44a8a1dbdbdb4bef0e7ea6a2dcf4795b88dcbd91965a91575457f775e69d1a0aff92c557a603287959ec4bc21b4108eeae2189573da6fd1dbe357b5246f9f361e27bd6fdcabad100e52e7ccd9d45b9ed9e985e599ddc93d578ebcb9c99ad2749d6ccd85e46aadca1b7ffee3350ffec0d26eaeaddbfac3e291e9fa6af12a8fc991675017485536c7f1229dd8ad5a7cb9544365b872ed0f3cade16ad1bfa8f2f7f1333329c4705e679fe0ba78b5376f8558a87f1e62e198108bebcdbfb833b22640836cb1b3d3b269affa497ac4f321bbf7cb0398568e57e2dbf4cd4ad5fb878c80d37582e0cea7066246114a7462e96a739786fe7880dc49761386323a83aa86388cc2aabcb2f4a2628e187087fe8e667a4eb8c04e83a2ccdab306eb30058cece2c6925420c468cee5632de4eeea07052eb485579488b24d56669d54c2e34496b2f75ffe5012056e7d28a2a138098cf12cfcf8e37ca1be93da531340780119057ab59fab6567a6e9eafdb993a5653c25ee57fc546a5acae969e96b959fa07bfc35ebcd4dc5e1327d46aae3fc803257ef2b2d08dd6522916a96ccee5b1236537e84d20fe5894fa4f00d9fd70522791678630a64c00374fdae894cc3232538f0dc79156e890bd91adc3db4bae0c03526d2cdcc04afe0aa6479d15fb1f1e28447dcb3323678e171d4e3182736ecb0110ca09dc526bea8767608e0d46ef93ede772452730816af50a8e7cd2de30d39c0727469ce00997b80cf2ad7b2ae20738bc8f382eb94be32859a8b897227c0b1bc86cd3d2202d54e60732fa4a8a671730f2dab2bbc8d6a7859b6724c5544bc709d41f0cde377eae45bca77ab2d22e98d0b2ce146ef54e78551ff20c13408c7d499cb417c16de9f68289f7304d32d5fa061ad28d9ac3dbfbbcaf2648c26731a6d60c83499b0087dabbe1173762677a90474ca8530c82a41badf255cbb0c5ace24173149cc608ba1496b222330c8ad52b430675a98a56881a3dacbdd1b632469d8d9482e69d9cd13ceef2b8655fa46945c915051761261b1be75b68528d9e567d3488b34f9124ed9164c24994f4aa7e9fe71c622030d352070fed233de87b0aaf2330562a8faf0a6eeb33d2853ce2acede79ce0843fb654ab4afc3bca7ff7e8482044ba6fa1b1bbf02b5407fb2dee9407eff4f180052b90d3477d54eb6bdfa3082d0da89f5028fa0f1e9e899fc7d90eb26d2b4ff9d1d8b7a185748d723e1d7af77ecd24f386e2d48a5b64ca3b442dad7fbf555a496c8d36269b3ea0eaa44ca8daafbbca7e260f5aafb1c010677cc18548daa3b9514545badba4539873ab4849dbeec62abbda6b61f4d0e1043509117d13ac7202988da2da412b5cda61b22ffe50cab65378481b1b33696080e252df2cbf83806e4a757721120395b997d44a511ea1c016ef9625d750fd947c7ac1d82d6d4436da5923a020c0246c145884c3ac9334cb29d53081d2ed7d15454b69b6eb21f1b6e129354f94e535738a35d7cb0f9f2b40b69938a003a2f2bca517f6bda99a06e94aa312b1ebb1f546443e64d9513cbdfff1d2170ff8190abc8ff5111cc13edb9dcdf6565c393ba160e5986b9a73a20938883de19cf37b3b38feaff9633ddd9d9738c76c139a433c62000b75e6e323a5807a6a41032ea11ced1ae9d308a0de4d2f67622af5905c243ff2556e15f738a0d41833a21db71497f0dde72e52b1565a3627335cbb06092708636292ccc89e4f539905b48430d0618dc04632c779aec9c09e3b6c68f24159af37ceae6ae8c65c8f48f6dac8adc59e2f4abd0fd5676ad9b688ee9453266d9a1390c77c7584cd69bd041bffaef57ab2ddacfa52ba5e8d72870779e0a27bf11525d6865a5aa9fe1e8ea0fe1e84d491acee4951c448bd7a6fc820f06506b05c9111adb3b7d52d5edf320f6ada89d3c0d7ef1ad2cfe0ff8566e3951c62802d281bbebe38030908c5f23c77e8dc99ee397769035e694669376b0049a05fdb56f6575ed5ba9def4adfc0f532c3ca126ce99ed8673634377e93c2891d77f1bd0d8a2404470b854ff5b86014edb8c5ff09f8a69118a53fc2d058de534363fd50917ba9f7ff98f593be20b2780d5b9a894b4f67d25ad551b69696d7afcdfa45f91b4860abec9f2a7f4e3065b04a84abcc9668001f46f49c9fff6517a73be4b381ffbab93baa9e6821d10aca4290bb398fd6f9299bb5a9ee42aaab144850a2c6655fe8e44c51c2908472451ddff1389ca99cbe35d960c4689adb23e48b94a99bc79af3aef649bff61643e229e75a34eddc4bdd4fbdbeea51bb6d8b423ce172e858bb7c94706fc265f646ca8871973498a723d2f7eba749827704c4b01d22e07e64f0cf03e71d29d321e1a2a482a82c9886ccd937fd3d69cfe3e36304735721e6c6bb65f58fdee027285c7a0a9213c466fb94296e3669c829a21254ec1ec72feeb4e41e335d99d53ab96f805d9c7796bd13821bbb0fa57fd82bb733cbbfd47ab2d9ec52dd24896792c857a6767df957baeda60f7dc9fd6e6967b8e4b7f576f852560061cf20bd8a229ffcece36810f1b8eda31fe027d76fbc2a9aaeb03f8868119d17d7fd7a07c900d14cd8ede7e3659bee88dce72778971126ed99c3d948824984b2a9e4265e86c94741d92cf6585a22a99c03635c998dec9d8cc30d44b60469ae614b427bab3bbd8f85eff697c5fdc67e626f15a18956367279fe54c6469929dcc8c5b825344ae168c337e19bcee960d7f002dee02dcdaec7cf22a93eca2eaea2fa735edb3a07ea7b278246edcbce9b3d8d8442d80e498caf71f1e8bd0f9ab494b5b78b6bd94852763919d92457622bda9b1c8aefea64576c77142b1e1d413de0bd024ba84f07af7853705cb672a925f05415c9b2063584e23a315bf8de3b32d82bafadde8e8c646c76bdefaab06e6fd8506566a6509ef9f69601b75cab291df94e5329465adb790b27c3dfe8ce64be6203b1349a4ff77ade552dd2bdba8a6a2a327a66a73f51deab92f44bf0638c1f6e9cbbae9b039641d36d8602fd85fab47d2c5b68fb16679c96a96fb3b726bdae48215635b7738b1135d32274fc072eae429eab053268e4515353b4295893edfcad01dd79ccd07496048a66e6582d4166b887ca4317e45eb743a315fe46d7f4bb5cc2d4cd6a940be7d9eb9f476c5334f0448b1db946fcfc9f1a5473a032e8f6206a3504e9e4e30999d4fa988b8f21ac15a763a228e13ced200ffec2176268cf39feaafb44e79540ce23fc7142046c0cb41c42e17d353a2269211b68ad91ceb4c6101c60e3f1b84ad2387c1807cfb458e9cab107dda916651be4074b7f723b6ab4d2f7afc7bb15d3fe500a46be97523c789dac9f9f976f806cb2a0c18948a41ee0a8f24c61627b8de8c46717e8d461137a3519c7f28cffcfc8ec3ff2438e53473f4a628cd9c7f1e9c12087fae0add2c25dd8ab0dc7042095cc78c8f50db31fa429d4d2d3514a542dde8fc3760260a14acdba903c5d45b3ea6c80ae8cd1c70c9b8d61c9444e54c9d0f102e129ffacd9dfa8d427de27b2d6162373381974b94718b3eac7f1e663977f1d159b4738ea07a4c06db16ee46fed895b3b24ca7394268ec9d11eaee681eb623a5f843a40d62265438072841e6731ed01cbb867961ff3a73cc61adf33f8ba1bc959cad69f2740f9a2c2ed0ba003cf1c7713b517e0ede3f8afcefea2d928e17bb15a344b4df6bfe6189906141c975911bed324c6b0510be059787404255f1b7d8a46a2ba3ad73115a2a2f99bbdfa11ca712408ba149aa8c19d3b03a26f9af2e33575c86188d9497e0deb4124d7d174a2b9bc065b47eced05a7ed3cfcb98c1eca2552aa1c6e490301868fcd07680881bd85bd72d2b1027df3b7e6879af26ebc062db3866a6a67bc55913cdb134e44870acb9e1d511559569ac852d7dc4c6c9f3630bca13d2db392cde1de50a116b553200a989da9220312ede7997bb1b74abe6325b2bba5d83b847bff54976b1ff440204f4f2e7d507efa0f3e793846b755284332766324f4bb12ade39742a2e8b77393986d052bc3bc8ea8eaf6ea918be27a2e2ddce393bd6edd2ca8866a16f0fd8c059959800d1df389aba6636fc7aa82dd3df39d6402c8a77797b75cada8c1a98de11a6b9e687240f2d4187c8c1e88ca1221d293fc6d7a262e68aa1c35079949d8cfca2c1fad95a4bbd1d769d3fd1e41afafb56ad1894a4c26cd790a57d932c09b43ff55463a17ed0e5ee21943522cc929cd3d09d79eb880f4ee82eb74e193a4224049f08c5c5cf8a46a6641b0e29b1d162878304c419bcd23f89ee06b30c68240fff0e9fc4293dabf0b3038451536a80f28a0f496da0dcc74d1162bb67e095ddfed7c34e4dd482896b36b452d85707c256f009daec5eec4d7d38dcdcad89a379074aa88c543b2dc1769bef6426f93a65a5c0ed2609637685fa0eedf4493f84610e860bf6576f33b2c0a019669326b2b1c7a725636cf484fb3671d2a27a7b1e97d7a263a2f23f12adccf24cfd14ac41f97815333e5f930cb55e3bfe9fc2b461a3a31a4c5a57769ff75f59ca5d9ed378546c80a10db9943be7b4cea41d0e851871f978720cf5d726f76ceb8976d3fec8f69d51512f8803ed150896c48d9c5b4aead8651d35ba924a7e6aa9e53fc3562daf44c4c629836931d964d48d3a631e0ffeb18cfcc3a29a2ca456f2521bb97cb5e17e88c5ed47bd07bc3f08bf9421163292c1bf4ed0e43a638a4eedb1a9d4d717a3ec7cee53b63c0e00471d731fb633f5c2582aa627a0ed42e88ab3f76ec5458c230ea1c0625c1235bd2344b7c2510d213c20e1113e9d192ebbab095b3b263f9a194f46196b0d2f907f84f7a7bdc003ee7cf3333c82a3a2e844823bc61aeaa36a4d29de2a946578d1b9523c11b171bc35f67fdff136fd48797c56a8624af5b11c767252254940e1d761a1749b011cbed10f9fcf0940ee59cfdb75f083735fa1c08e799b9c46cb76045b0640e81712f317435e6ee9d872091da445c2f0cb2ecce24576599a58c92dee347067264f3d84046e4a92b72ea7d46b1902eb16e35f023e93ad8e697c53f7c3189511056c7035637ccf4e2a265074b88a114431b8e49b7615f0f5368f184d8cc39edd13486ac7b1e7226cc018762cce60d66b05b4dfea9ae55a94545bb560452731e2b3a9cc17390001213384482019492a1515593765b9b87a16e585a9c20ba4f5f0fce3ae9e0302f17d811c43dab3d1bc902a51c13f9331a7e0ea47fde54013a8bd7b857239fbb2e2026ad4d21353c9e691297484850ab13f0ad29a2a21666a01213d422a6cf5dd4aaa472baadc20bc742eac2f9c1700e92fe4c5a6f7b11e3255554853419faa9a83fe8e44c31db014944263d57b8d08a4d703d2c4695210343a2668993aec3e71216cd4ac1d88bba95c2152e303556895a826157c5b6b3306bd8e53421ce7cac9472ebeb17293296495bfcfe5f1a9192b85911bbb9238b9b986efebd7e95f4541abd9c13842b5b75cfd41b36c359117d29c8763541ebfa0fa82c9bd58d7e8d9213fb3c9e64cade1219d3be9ef9be9afe842dbd083bfd392c49d808862d6e47b4f66c1e1a16f996c651549c478600d1e4d8de13987361241d1638e5d24963aaca7a792113c5816e4a16dd48fa13d680d9b2fb5d9c852438104d8f47b33ae743ea7ae7a0b22fa7ef49232430aaabece54b2904418ae50cf495bf3590e8357bcc54375596c9cc4b93e0e57523d7399d6745d3e973c9f2d9fa850d90cde6e35a4509dfc36bbb248779fc9d0bea2694fab77080af9cb8ff484b3b317ae952ef6be7453946947a46f796fd96df69d50aa52e66b09bcc37ca8271ca0192c804a3b64251b1fda2168a547546c4e7d55076b94dda17399220f1aff1f06ac560e31435380500b19afa64f4fa8a715294240c816de86b864bf953a3a08839bab409fe1dbe915713cb808d5c8d1473a84936f9391ef955419862eee5aaef01953fe4c767af7725257cf135e0f8adbd0e1c745deca58318a7d5294774ae7e1232d320007e81dc0f3207c4de4c1505ceb838d2fa7bfa98b8fd8458d7268d4201071ef9074e982c353924381f1cf09c50cb2a638d452facb18202863f27a00b17b0a98ca873c99ad5464a75e48271abe7c503e639890213f91f44643aae0933fb32d289da09aaef04e18c8279af97bc8753309ac1dfce9c6c84ec2af9e3825d7c0b173a526d350b3179bc522cdb393a01874f868c3708292a3a9f976e307a9d7d046af63823fa73f1752cfb21e6caa5d94bc1d00540549020255cced0088557f69c4583a8c35f449169ffd5edeba89196aa1e351fcfe9170994019925693a6ff3e9932a20566a65d3f016201572b7cb5ca5771c260e90a607a5f2dc037d05b60bbd1a7d13bf61e88a0896e6afc933e3d1fafa18b6e1be8b693c7bfceba49f50686a55ee6f2922e2b84f97a053262f5483a4302e52b31a207aaf938955846dc501c0bcf373c3ae3e1679b9c993de1a702e8713c400ae3c086c61e3525261de1b48495c22ee5d96d7f94103a40577a29351d53d1bae749340d3ce12848640a4516a96ebb7b8793096d696d7c21062e930ef9c8f95e93ef799623020a7dbc1367be57e598319272df4bd9de7c0ab97ee677e8b5a3f5b0851601f508c924efdc593da13c325513f25b868398f12aa0fe5498ab317773e82bbae65997983f7b2108d62b61774606b702e17e594a3870ab9ca03fb75777e97c878885820671692ab7a7397a4ba0485697ebb552829ff3fa957e740e84aefb047fa498662999f9b74526217047a97d0f4b504c30c12cb9358212eb70985efce90d92d3823a39349c1a7e714cc2cfafbfc45c3288e0ae814c72a138e9a702170572817fe388e69d3812aace8d83c4156353f4b8f694deda28f57f3cb29c70421a16cac13bb91615542b3064e40581da41adc4b10c7580cde76505c6e86e955b344c8b26fd619fe45ca6dde9702d38c7953e23dc5022fc86ab684d793299e45c9a35d4986ee7dd5fd5b7cfa4b1cb9a6483b33f57130ece4d4ac674eda4a34121e4acec6228937114287e5e3d40883ce8fd51916f2ce169befc7a462e7349814de7f518d5210591bd33199f8b401c25a36acfd56cabac9c14ce93a0788b86a4a39238e546ad50628278d5c3ba1ddb0eee3fc83a2d10ba188d4d7d00df5adbaadaf0beff7fe63f3215d04cb2896c459e9dfeb7d5162fce924ca6f6120cfb2d1fd279b1b4696c2b3e6248bc814fa7b7031edc5c9297468fcb7d8cad47a63c2e71ae33f7b986e9ee2c37a01cca07214b5fb34d4682cd9a3388d8787938b0890d0e9419559d69baf4ae1064bb3696de3c2ce4e3217bda7dbdef48f2584a5c3ca5f0aab8bac25a098f4b982b58048aec85a8f956528511eeb60a673e2530e2338e9d995460cbe1f354c585da381d63b844a6c9bcc230177cbd7f70280464ef985f43767885365fdb5060ea08f65772a0afc95804ab4f7fe7c0a9aec7fac309c2ae380016f4cbd0eefc12fdab751b2ade4646b4213519d2b70d20522a2ad345221fcad4cc24fd33385d68f2fa950b3bb5b199ee526d86347917f5a0d92d24f900ab54e5f29a9838006f0cc8fcf3e6c114d9aeb2ad2eeb56ccb33ec30f02622d922904b53d4a4f65c2791da1be6c2cb527dcf71096358f8bc29377c37d7c4946c9c8f13df37fd794e56139e69be8b942db9bd418b54b6d6ba02f585b5bb83b89da4b93c2ad22e425522a3eb184219a609b3beb9c8c4da86fc50a3e1044ae9eea53f9a32a882fdcaf1ad4a4016f85563c7a97cd310e6e845446c6a3f8ea3b315d30cdaf0a3850170709dcffe89029bb0b78d1b32c4f014bd44aec0d8ee6259a8457d94746baad2f9c030957ee057b6cbce0114ef0873b230e1cd0b9fa201a48249cc92835a0c4777a364076fc98b34195a739aed2507a3c0bea694ed2a68b49e627fa5c747c8c4d5e920764019727ca8a6bd07b8667259585d6408da1329d2fd8386355c243280d07c32351442b21886397e6c2aad9c2e54034328176c499a0baf792ca41de6d649924c60157542bd0ecac651de1fd1e8553285849a78cd45c949ca44c065c86def4e292686d3069f37747b81bcd379e8f92ca8175565404c9d11f6af3d945b115c05c87a4b172ba993d58367566862050a1d62ea42a2f860c40d88d43f3b594aca174707accd827708068e3005ec0d9b28a626ea3501898f506489c4ef474bb296394eaa617c43e38f9d7db4d81f54e4df36436712eb05fff6cca25ff039347e45cb0107fec74c5435dfd32d454d3a884176fbefe7202e63cc6ddfbeda64bc4c550582c0423e7975985931d5305c9dac977fef2fb37d82a4eb4ff65ae529fd5c4fe758abfb5fd146af58db12277d329ff32afc4da028e9feaeeb8c308f60446ce9d722c21fd4838121126cc07bc6a65feb7c2f581a9b18de7c825cff4088729a60f7d8d736cb3a766fc79f4a33c48fe5ebe267f179aa94693f7a4df222f24ed87d470317e110f90e41dfdf0ae94ea09056af8d5a9d16e9eae3a2dd1a9cc1f766092c4e1c385c931a32310605126d3b79827b3ec53950b223c30843d87e09ab565b0d0ceb10851eac09f177e40e628a2e25ac453cfbd148aa63c4a91bf6e82b0e8527ca33a4bd366a752842579c2f35a1d403c2b42368e102be6a02e72a7c1e59057303fed46480aece4f83ad676c54c6e5c62c0675444779a78e5b484be514bd759b122362b29065fa2ae4e059ee8c06458c6b408de6716961c886479762708712513a38b60e402af5791c1fe0a30cdba45d8d3bde55ea6a97db597697a37a673908e1ef40456147df0a72f87bc73183539bece69262ed391b9bc83a2e6eebe3297ab6ccee7d95e94e0cc05f4a8990f8a7e29ca98bec89f74455a7bb2fcb84c2ccb121787949b6fac7d895d6e2553a2835e514ebfe2bacbed17a618f4b4cd3e59fdd393eb273aec464c71fb122b07e4d3fc7d9563f5c6cdae40b181b9634a3d96806908dff59fc6317ec6ca6372cf4c85f054fff1391017937a21fddca4f887e70ce999ed502a317bd4ff0bfff4e4926c052eef974afa0be77f7c634db3f98f72b7483ed5b17c3d52cad1b77d8230e22c96087e5d95d4ef0e59822aa2c2f7434cfd79acc58cb1dcd839bc712f7dd2b9e5037e05564fff7ac4afb635d2bf9ef0ab4306d8837cc6cf2eff7cc1cf1e927c5ef18b6ba3bfe117a5481ce43b7e0d4937961ff8f589f77fe1d708cf7de3d7587205fc090f764ad6ca03975cdecb1960850fd27ccd820260d541467c61692eacf8c25ae21337fc9b62ccd581516af6722f318403ff3ef2ef13ffa62014759017fe5dd0cf6fe4414b757be921a0b42eaf444557b86525621953f46645ad7977bf711ac0fd399131e3249324538b23d447aab261e6cf54039685a8ea88b20a927431b2c55dffea7021a967de008e506ff9b7185aeb713c488fa9680c328e508f173779fa23797a5acef41aff7928a75e712cb339d215fd27a2e2349ad1906d2da15ee2179fa1c37b464f9da57a7dbf39033edee48a00093a4dd0c454ce33dabe3a714dffaddc8d107436d2c2a1aacb1291f25186673c303d4b6b2b85ca93095b9428f23f158aa9e66ac5ef681ed35a9d3ac9f38255b44339d9a07b0334b227716ea3ee138bca1a2f9926ff209502a807b02d9192d2d0ebe2b2c5fe1e8de3e447e105e82c8ff78f6aa83dbb5254286d2b39f2fb11e66127f36632882e49cdf1e688b43941fc6ca31efa52ae2989cc2993f9c7134ad4194f0fa5161a4087c97d63820bc4ce02aa4e7a8743d80569d14c0fc9065c20bd3840c077dd3ef3862046320c522d68c73a27bb08369cb62f1d63e3b4de702d8bf1d14d31e445dae47c224337429fd754b84e7cce8f70e1d68eb0d1a052701d57fbe35326b27102575a3f77cc5ccea33585c2973dc8d5102286275ab8b33c1b92ac1e4d1c9c271c6f81391c1d177cbbccf032a5bd49bbd5a7ea656405a6b67efb4c591cee5b7cbafa4f7aae9c7bcdad1cce69f2847a3ab149a37880a96f4627a4b393f302976d5bb12ced8aa32443f9468a31cdd870490f7f4253509a7b8427b6f4f9423db05949bf6db08096cf5458a5d5e1243ed7e468a65e17179b1e93a945696602e79a07dcf64e892820383f5173536c7a5f459020bde6ed4010ed9f574d514b87cbe5580199b39550f685fd6afac4498ffd73ff0c46b479c90c516b9f712a60b3cf215fb146e21efb564ff82f355a8aaa7cb15c919322d9d2256c62ae799d32980d76b441da75b205f69638ac462963dac149eca9ec76aaa8741993121442e4eb152b60d1e70a5f748cb88b3f895538f16f6c9a3670fb1db249b828aec18fbb42f84d7e5fa3623ce7c4bbb5c6dbb3fac2fb26a7d803880b4e6a14e70ac15546021e8c1d72999ff50023c9b5ecea770835a0bd0207f502934091e40834a4b192202456b2fe9d7a90b3ebb42c10b29387728056d2e49b8aeed2b8e07c760f8b919593426c558b4fb7231d8a5cd03410ee0e7463f9c279a2bf902c7aa8d01946ed3a80a96484ee5f974f7c6e161cf145fffa2b37617e0b30bfdea4172743127e5815f9dbe71e78c033590bed5b4d555551aba37c49280b453ca3149055ff84bac9fb16d7ba6eeb39aaa4d362a7557aeac5ea08174edeb52c52a5798f0268f2920c6d335942e671cfe6ea38015752151f547b817079445eb2437f26858f9a166fbb15bb32b62b89fe71652b37f67145c9c54097a2aed597d5156e4bbf6bc11f47c4b450e95391c387a1a9618ff6a2bfda51ab569680b91c0ced6a87c878908f692c10623443946657f375f22c3071b8c8a1f2c6446028dcd5b14d728af0b51c7c876385e48a2f2b406528ca60e0ea9d9f941b91be1524b766c9ad8e66e64911d3338b62472aa138866b6d1a29c20c805d119f32e1b83cda2f9c07e52ff0450302451df0de333badacdef5441ee513821c5374d48ae9cbc1668d979e2460067b45e00b96b84221040766b16d8316bbada8348da966cc833d1c6420b3b19a4acad11f3d23e899e3c11f20513130b94aafce380190beb8094760af29e33aad4fcc07e881cf78b2c599158cb1241631559f96a9951b7878b75ef87a809efbc2ff4836de423d8236db29da3cfd53da8cb93d9b8b9ad5bf66f7a56ae2f7f744f227cd752a2400b78c85db13eae44210f1676ca7d60c3fcf6fcc114f709bf2d67e2961f627e43a512fc94c1f0c690e8518c5138d95320c77a984bb0386c381411a38792adedf9a57ac6c9b92c9ec68fc83cfa23ca8cb3d50ec49751993996857a85f9776448b4d4a78c5d596f8d81c6f7829b12613f8adc84be9ac80243f833ed829716f7a7dae4f05ec96397a71cf58b251eadc073e4eb9ccf22b59639ee37362a4bfed70523fbe864b9768baeb2e561cd46b9988ed936a630a37afd953626e377ae9b6e45b17e92b3dad18a4ae506ecbe197fe1e28d122f0ceaf906dded2cff5c4549e1c36da39d0f806df090f997280404a123a5198824ff2ecbdbf874d7ea4e9c8176a2ed3175cf1412583497f89a389b7ec2d9f2e2947e3250e2315ed7049091790f7bc33c7deb08adc8c309f6540b4602b4171e1dc951e6270596af5846aeb933b984982021916a95eae9bbf1aa3c331c3255c85a3b707130a91d91105767b7a4f39080ee8d2187a11fcad9ded037130f473249b48b789add29ea2b4cc27fb66e9b7c73af4ca26d162b4e3a85b32f17da203fd8bdbb904c1d9129cf437440ebfcd7f9bfaf465852b642c87323574803b40bebf56e206a6b776207f146db272c864e7b1618f519fee0a859b922c540d96e0dcff548ead9ed86f7efa5596f5eab2cc51b2b6d5d1c29ea74f59fd7e8af7d227fabd67ebddd102e12091b759038b5b38c877d2e7ad5b96950bfca8544bab6ca73aa618b7501ee26b9a4af9d791b23d3acda94a548c19b2dff35028dd09178b3f025692ca08b545c061188d4b8aca30f95dcad77c265c99a7e444818e7b7da2dc98f65215504a7f3a3a562df69ef9358e24bd3a378a72c8ab0efd8e04ffa056e32da83965b10455b4544a518ee8d467d897ab07cb17c11c4a6c0e9f1954d33bc4dda4a88cb7c9dafeb9939c9ddcb359695ecf7cfdb4963064cf4c74aef687f3d4b99e1422bb3691dde4ceeca1f8345df1fb9675937513afc7059f9d2e5179c4a56158c3c943452a391794dd1d6ca9c0763c95581a3b62310c39e5b904cb79476b33c2869d3be936a72a57a1add16638a524bdb19c73c860926c0c986a9e4f86f62881b11acb07490691020a071db9c6f206a36a1b6ced246b46cce23361b58b174bd341c9dc66830a07940eab68d63f82163a4b546dbb8bcc60b3613cdc5b0d710dd594f6fde38d2b04f2543896091d4f9c58597304661d18a36d8c6e45adf2f4ee999cd04bdf002edc46080c092ac2d44165931717403147b90a4d289e2fd4c3e9ee46a32e657fc31008735f939104c960a4deb6f81a1ede0476b1f60291af758245814965ed64e6fd50c6063cc3fb743d0d11421bcbce1562c10a4992f1633520f29ed4e66af41c6ca0bffe70756b28c4678494ab213ec365e5988668b40914b42633baf355ad629d0b75506e0b8197b1466d1e9ab71016a6847aaf2e93eab588732dd19e705ed8814819bac3f39e93ab9a874cb66ca12d9cefdc5afe0056d0e339af693e6020ff9a94e2d066f574dcfc0c3c4a3ded890e27a6704ce8124bf209d111ca00f6d806504f64055822506945df37e25fa7028eef238ed5dee58bee9ebfccaf4c2e5d5fa8faddb9409f3edcb4c01d280db8c5c58f0d1770eee3445d17f98a365067cd22396232a276eb572b635a5c54544adb04afb3ffc191ef123ffdfd74cf3be9d35d1f19d983bd4bc9bb8fe280136846991c257940f587f61a52c542e69926514eaedfaca74faa638383bde8a8dab0aab56c9ba329104efd6e5b6420268253e2682f594001f1d98863b1aa53a44be3464e6a09756e8b1a4d5b6f4a9b8ee6792b5772473f87c02fe9c516d79d9c17637a4dac967dade8a7ce853eea12c7f37e2802ef8913e8c764b251df130663c26fad8a6067575a9a0b55e51e2ca47b807332fbb808f27458780c777d2cf24cc1983fa970e672113ba941e5830515daf48620d9541336393bf594ee3b269c13d1a58552139893ba65c819153ea28815b62972b81a1081ae2565d1bb5152355ff4f4aaeabdd3a8abf8b7269535b9aad6c145cd5a7a96072f948b8a28c408e6eb60c3f3b425fa72bfc9e0f24967465f53825727634464bf584a2c6dc71a6a426d8b7b0e8eded17eff64f82efaf8b3049e478fb857042369b7c3a6094d12aa2af37ca2151ac69f075be123022c8344f2662ba1e2785d735ef4125b60bb8cdd401ba81fcd5382e6766e22367d53c960483258c898163e0574e9cbc429868909aa5c643d1f55086aa0818135d55fdab26392d64feaf76a25caa9934fa9ffc6063d4fb84fc63ce370124305ca5c28e70d8e2a70e3e2cb336cc951ea969ac3b4b226f00995d234fb9b0c6325f75787acc44f38ccbb3b93a7a2c59fa284c0d8079111ab7b4b5a387a10a478f92f89c849069f21657a4c1a3f9c511399e6752d941b1fa35d5fb7d7f22137a253d2abf277825447c3d4da2220b4e75ba6e47e7b75fd7db42b409b656c7badccfa792e2500060148a8ae5652ea92f7ed8ecdb523e157e59e0800f9ff2b492c875c7174187b425064ad7350c83d42c4febb425a1587d70c8518442443abb2b3acb1770c6443f6a28dac70a66d9d5ffd2954513638b0b2c9171752387999a3ab0db8c4a9a44c8ddcb1cc75210a5e68bfd0c77542e0f02202e433cf069b3ae62b406246d3a0302d6ea6aed7c9b2d0d9a9da8a4d4f9c2a49c6a2a7efdb104ee615f038e6b67f0cafd682c16963e2b13dd18629718df3ef133b13b0601407d882764a1b5c7ffd40b09d5f77d0a4a824efc9d8a6d98c6af9864d4c095b408c6504b71256e3449118edc247e695278a35eacc3eb0f664173aca72914b04329cf1f11dfe2984868f10f1071c0b65acb9ea09f21b82d97a7b03670850b6de91428ed4dc463cf724c7d0f9842cd5d986d9560aa815482c7a3bbd1373d23337a25aaadeec33456784f8d8e528ea02c53f422b23007c07517cde0402a89be385c36167a43836726fc9c83d979b07e80674de222efdc5d8cca8c10a0dd6d9068e96574c97ee4bc2a03af51c983c674fedcb10fbe07eef34b3778f65c3e263a36e906f42fa1803623198e4b83ebff980624adb6c5db3a7692ee9256650133cd14e6f8a73cecc9cfe7f9883b8c9a5b1ccdc214991ee52615b3ce327cff8425de27930f4191f63a6b732f898fb4eb659f25411966b40756fe94b1e291af04776ae6ee05c24dd0ce8baff6e996c5b8fe3d80b9017b7f27267c5c5943d54a0e9ce49fe03f81feae194e5190ad794f13620af4665064bb6b51478425ec882a21b583ce6f4eb18e81cdabf80bab6319a765b88419578bd7aafe1c41fd4e9f75452f8fd448a25228fbb21a7e3f5857a4105f356c4b0b56303f6a7579237505bb8948aa39cd2824fe6868928421a322762b457401e7a9aa188ee604effbaafc0d58edfb2189bcc8266f2969e16800af402a76505c21694a7317a84b4489cf64bcfbffbcc3aae23bc9744cbfb3cb1c85d3ba3d86bfdac0cfa5a0a8bed58e3aca713178bd017346b5d0f324f99cbf912fb853f856ade8d21300e2ffc2ead3dc2e55b4c5d01361d4651fe1b2d298d88568fc65f57e420d9cb7aea0a42cd3579048747b09ccf39cc6141a3aa8c3536889497b997c33db25d3b060d19965aa82ced08010a9b319531b8c82bfa3abc5bc66fe569de4438faee059846ed25d8f190ba58ed40daeb1d93c927944d75803cae9999772792de39dfad096f4e7b405fb950effc6b2b8583c21c55c4f9b5e15b2c6989d2631c5304ccf481e5ae891471729fbc6be0bc5ec255c0c520db48e01dd30af7ca4d4880b53c026acb799ef51c824f9ca179817a237becef2fd8a9318da6372771ab5bd4477a278f8c1f649d75974364f5840de26345b96009cdc4f75dde485c52f5095322e4912e5562e04a61a3662ec536dacc7b660d3e98cdd1b9967ce4700d3fc38948a253f7976ae60ded062dd356ee7e5ea7c88ae8ddeae90989c65cc7a5ca503f046640b225c75f305bca0fd3324144b66e6723cf00238054a05e5928083fe2d4003754cb8fdf44819e504f1b1cdf217cc26fe79ce4133c10de7be98b78d8823efc03d1082dc033cb151943dd955cb310b8a4565ff5dbadb60d4502d29e587e8ea5db3ec9b5415e2b000f5e13bcad59526963cfe241786f9cbfadd5ff0e452378a2f306496058655b36ebc1edf18c6a4818f4091b93b9e31a6a639ba37e28d2efc0b6506051f780b2cf1ea8dc08d7a652a88b7d3cb02c5ffc43d3b1242b2ce5e069f9c77f22f7d924641a6bd0173e5f5486b3945883222aeb936e7a2259d03dc4a89625a248f7eb32b66f09b963db1826d4eeaf01479d3bd268a68894e99417a92d20023d29fa9bdf4d5582020ddbf92a5652b6b96b04d21c48fd28879945293458d198935417444e21caf2dc42c358b7296df661a5fed882c225af5ba4f8b68a54b37febb38ec8c253912cac7f79ba2d0665500da1c3743788640e5e38e8022a1825d471a9a2a4d613e7245925255c46968cd2c541a79411d121a3ec83cfd9d708bb445ae441e5b3845f7b12ee6b8ec836f04a21bb999aace193490f527f2467641a1067493275b7494b7d0fa342af82fc6fe8a74ee6c316d4b05d353a22ed85886e0e89f3bca18ed65c2df0c468c36164322a6606dbf084fbc62ea3517dc7c6a529c5e7969719ebedd11301851b9322f301f30bb9eb876c985742855c4d027a340c95a3b216b7187f3c8e755892dbb692ca8a3e55798e96b67018939e75d3be81eff0ce080818e6c7e44b0c1380fdd17862d30ec20984aefa941aa89bc0a59727807a1154c0c79624f477a0e03730b448c275b64068f968d22495e4730cdc32fa9dd8bcc400e50346357af914472a8cd44d1b0e1dc271866531877d4f42de33db10f2d4acd7c02d9b750d0a8f74127b71834d3c6dd112a7472b1b7e4a061be7bb4cd23b8cb3fafaf6c83bb04270329dcdc44e3b5be78e35a097b4c5b758b2c57bfc088d49bfba333716d425aec616d4950c6b372da88c4cb0e6388d6623decc389fd21cdf184e6b45690d8597576b8ae299c8174b89a9a47c74649ab737542ce973cb1e7997444bfe552cb2e305a4d13e009713e1cba313b5fddc9367b03df149d4045cc62874e9141de3de0ecfed71ef103fe709e7d226ce7bb907d517e8df850c1d4855532756477d72eda9bb84acf3c6b897038b2132801cd61de3743234361cd3427e829b35e484b1ff613627e1702d49663ec26ab395a77e62815c5474eff9eea9a57f4e6599ddb4a50927fe4f5167cbb87dd935d85b9277f573d5b13c91ebaed4fe59bfaf33bf24cd02e17e7077ed0522f8ddc7e89c5c80684f56c74f4f0fd109ed7235c36bc68fe2febb14653aa1f00d3cb39522927945c29b58cbe8c2d12d668e968e11e7b458aebeb2f28126c3b2dca20aebf5659af325924d862bfcdb5eaf8ce7bf2deec56695be8a323240f738df41cbade632a4bcaf234050114ac84c4213ab00edaa485b1ae8c70bf83f55ca9a6ab309a08bb41262df70c9ec1c64ee145ba00f44d34c28bafa1bb6ee0180f506a1bee754391254f7fe450d4c00996f2892a0ead95f7721108b975df614d853ac381936eb6cc6bcb07b9bfe793a394818c79164107034d3adc118c7d655abab3937990aba736c592db7b0852ce75b71024f8542ccf42bf2580f7f7bca8676b9429d709a2c79bbe90df95c453cc19aab31f685835a7206232187eed8ad2266365d5e4973bd064d05b28377e1f0136ba1fb741627c5113dd4d7e1fb6f7405f937d5d5adb8c809a2862fc374871d8e93e42f1f4b6bacc4fd5cebaf0b497bb8bbbf47e434e1b680a44f8dac827e1c7050c1e4a26eb2572d7db7858a1ca109ae659ecfc1e0d5251ee3c1f4df3d32dec4a445167e35a9a61b3f3c80b138897be0f217838257b23f6d4195041112cd1e154783047a17459fb112dea6c0788207210d542ce5bc95a81d2832cfb14500e41844b9f4a7ab504e39a230cc251a0815e23003e549ea8c295a537d980f45431cc3eae3c0ad973965d508148792c8d48abb5de78c5163c357b6b8a2e68ab455418e600a3916612efb6a8469aa8f28977d35f1b0aa0a25e4d16efd1e7e3da585608a62e82cc975f14cb6f99e6b79626cbf3be07c5db24d31009efd84e56ca72e5eec074caa9f5c6c9840e78c0afb9d32aeb35ea07f3c2c5977d05be56ee303d68eeae593b0cd020b4785300f6b0f53a672e22aed7b82ddb8f6778f49807576720dd4a9b4c33923d3ec303dbd32178265be3c461c459b8a07e59dd2827df5ae505f53984a2e86d783e72ea88e9c968dc9373523065a55c6a53c9ff329491f378c9dca8c3790f62ae723f90799888c4715a6a862961882f3526f1c27a49eec9311ae66f2ba273d7fb506077eb9c2ff20db4a0b1f96fbe92dee0b3118dfa1965db695e113a595c1c255423d4ceecc230c70868fbb2bd6794825994df499a919843ddee480e2f0436c597316f1d2fbd3d4656ae212ffb1bd662363a22fc059deaf63eece54416e2cab282dd5cf40a595e015eb373b3fda5299dd562608c513aa7cc7b161bd5acbaa487282c5b67d3643b673e485553b1bee3532646aa63d66dff704edba68277a79380882c7f4db664a88a502ce8b35738573c0399c23a1d0bb9f50325b5d6989b7a1b4c4db05e33f23f8bfbf627f819d382cc80f60d02359db22e8221aefeb1e4cd3185e030cd7c51ca191f0c924e019b8e47af2043466cd63f67536011cf0e1389ec4b320113d523928f35d2dd1519962da02e3563ac8a80995bd7b8ee21a3a9420318b5b913c7dd2b47ff20f0a7931479fe9919c9c5392960625fc3bd4bf7b544e1c80649e8132ea55a6364aeda474ca3247215a5ba3dfab058ef1a22a606686cd07ab2085629cb09daa336d2ca6b666e50619b7a315fa94bd9dc058d506f21bd58a5055fca03aba634946eaef0acc6ca1cae3037aa5090d4045120c642d296d6581762755e776e3d0d6b4a98af28e9bd5a470d8a59f34ab4d6c1a7e24818b5e91f4147797574d6e370d6d6ba1e2ee2a9439e0209b601eb7ca4d6ccaaf8924acbb5b24eb726f97f82366a1ad87637adb4a7d96b8b4830f92d8408366ad09873b12794f40ad149a06e0f347b4f858423b1b86c87498921a3bdcd4e1e8b26b70ebe4142fdcb359b6b32432d10311faab9d475aec2ae576aa7babd4128a643a7a6b572891f3f1f7de3683e2bcfc46525b8e57b6197f8023941bdf5514dab24e7d10bb27f12cc58fabbc6d1d3d31a68ce0e7b521b87b336ecd4277d2d019130415bfa348e5f224b3b4a24209c641d7d027df66fa144762d065d23c626a8bcc428d0db5259b2224438b7ab6d677c2bb0fefd22bcfd9000eeb2b7526d1f938d39d13a9ab2b10c8555d4244a200198542f33d91527d4ef944a2aad0f25dc952ea6186009639c3364fc676fa7c5f70093c9608f5522d5a459b9208ba170a9b7082e986cfe6a5145bfbc2dc7da00f9e7816ea26b9a6a66257adbee0274db8d266450935a48fac4abd767ac69792edb6657bdf94c6de5e919451adf5c53bfdba93430de7aa04096c6c934e04a7f41df1d306ad5e1395c9a08953b6f3cb61648694415c7c04e2a2e674ee17403b90ded96c217e124586648b68031107ea22a72e09e4051952a67651ce5c6b2c45712d39b919263c0a40095dd62913d35cc9b05147a8bc5a96e21207b0adfaa2b4965535f7193af2d8e170556054db5660d5a43ad535959e6de17b3e7423922e7c63174dfd2f10ea84f4251a40c020f024655e48fe0a22440822adb5c645588a74cf2f7884842d2362158333ae5e3c980c9774b557c6554617fd5e02b21960a1ef36338280eba1aa8b8ab89a885ec2863c4ee3f81481c00c20e7b585b3734eecebd2971672c675d1b494b953587c92dfab5c02c672c5596a91e624c5b6c8668a6d2ab6acb455b18bdde180851050459d19fddbfa3a659314b744871ec13ddcb5779bf455d7d3dff5b12345a080a838722debaf57841e4fb656ce0dbcd0bfbd3d553e9a0058984056c58a5441aa6c45392e11c6d42d402feb15099a521f753c580cb2777cd08afb9cc1e20e0f493447e18127be2dc40731cc25a2070157087b9b1efd339c3110e1572119362937e4650be70a62a5fd0326bfcbd0584824285e5fd46fa028863901e8bd4020ca1759bb656f0e39b1ceecbba167e8a88381ef753e63efe3a29d7d4a0bac99a75654e3c93dd83984e5049b90ca39bfacd18abe87d46e12595cca810d1ac02bfddcc276ad698b7cd1deca542b55429d6c9f0523ada915de01eee809d19f5fae93eb667068f5cb281ad19e72de43952249ddb9b3c7f77bd1234c39019991acb1544df9b1e1ec492e7b633eeed9f2acc69d7af89ecdcd32e8c1bf82fbfedcbfac78feb281a9dfee0ad5fa9784eafcc51189b8b6be47c3e6cd9d9ec34edfa1edf65e4ff277c439c835f2fef9f511f55a46ade12357b066aef09a83b3ad7f40177b7e1d4eee132e1ed1ef64fb17fca18ba44fc3297a66422cae194d379c8357f0e205e62a3214be676a39d3b03fc90c8c3ecb2e9b45a810a7e62f6e8bfc04074074545c12e21eabf85973f571e5dd03f31a4698a2abf73652c7152ce06457601b282de11ca6be2d49bfec7402112abd8cf98d11c95da1ee1f628a7cce2143b1974026f5184f355853b53de7a036001ef3485468a3ee7317795fd4282e1f08ab5f5bab990f14984ce2d9cbbc9b103a38c5024bdf8333c804df531d6b84f28a7e12d811a0b452b48449610f23759f0ed9cd3da96f9ff9476b2836ca072cccac0dcc4b5fa897561aa687636917ea1db9064dde3b6329d487d551a17a43017284620136167410f23e86faa3f7c5c09b1151bd0b8eb2d78dc7f2b44d367c559db780e6b586c279017ed7e0cc45c42f5dd480c76cf4b7ec37df91b05695039e23baf84af598710d81c653e9a0343dab3577b878aa31820a9d04d09d4fb204afe6542567665399b07fda12f7569203802d4034cf63179f565b0c2e5a3f7e159c9c94d9029fc2db017ed47688e28107f76de4ee616c6da56a081bcd423db2520655906e2e21dd614cb97975daa629776f26094117d598321da1eeb5d27b9bd006b749aa0b93f74626374852768b486feb15dbd65084aafb93ac40aa5620c6ea0b39ae973668694060484445bd0ef60641bfb6b5945557df5ac6ea7829f1a9f91b95711caae1be73de9733dab22a84342f0613ac47302671824251c8baca97276d448fb30885d8e52fd0c33e254395d59c42ef0780cb0e72efe86df1122f4923ce6fbb16ac88497e0a67de5aec385a1be4c1a1ad9a296c12e0926065ff3c2da91c527e9d5eee1a969b64e88fe8e57a75972fd878c42c875a3e76370e75e9cd9fe253712e674f38299faca188e408abb97c32f0590be9586dabe1aa50be71328a1e634472edea5f926b6f9e7694c6f65f92757be0c54ed8fa45e01dc4c5f3ffee925c4b2dfc4d4d16d8200871f77cb193a393474d9cfcbb1ecdc3923d25075ea09ed6b6f730279fb040fdec760bc4427a56474de4db9ee385f4a8c1750d0e4f2054a854eaaefde32e1717c93e4a8e2b8f992826e2a27e1387ae36e4df5af70ad1a81fd199eb2f282ff4156f4318b5bf24d1fd1dc23962affdf543224db577b8b6453ba4c9f511a1eb4f5dbc9c0304fe3ba4e4738226f41dfc4577dbc299dffd425e1d2df5c01ff849fa39a5e49d92ead90f26c66d32668bf950384d9c408441709f10a711af816b26c0e02a2cbad039310714527b3a49906982d0bd49d3972b36939687deaf990c8b439d525e2206db4c1f3b643a2462a3701547b7f42834c217eae0a6e86a82c11490cc48939a270d6d202865c886f9ddaff3ce20ddac463bc36fea9dd1949fbc333a06a2a2219fc150a0bb50182864e52e3c2b9ada5fb3d48e7cd1aae230453aa89d0f40c5f58c0827c45bfa294e0ed287aecdcf2df01cc810a0531f9c01e21044b0cf1906e223dd9341b02f9af753197a802df9c3e4a1afbffdd0276202f443dfe98746314bf0474913c449dc6833065a3d350a338d961276776beaaaaafd665c4b1dab24551ba87d7ada9630a772f8222884c2910f39698deca7a9dcb52d47b53b353d70fb71a2eaf882f68968a8b36c22250b189af063bbcb93613d49afa79cb46652f939f28a8114ec27149698c9da8be5aa1efb8c0b1b164e2f7990f102f2212a4c7914fdc5a924af089642894a70fbbc2c31821750a6fdb203f986844ba200b19153a2384823fd260719376853abd0e1108a033aa878e0f8d401227e2359a2fd594971a6890d6e3aaa809aaa8e660e2bb60e912921c8db180b183566124a02bbbf0bef60c8248b059736cb3390b6e1180a0a1ce881d8af3e62568353099344dcac4d73e209f1416db69cca35a0827feaa4c24386872ed312522248b7857370309b53231b213d72de94ec9afbc1ee9624d4fb31e33aa8fafeb7c39845a25724b7a04e83f740aa2647e90c56cf248743dce3b91c44cf49e666a467c7d3826aa480af4ee7c928242d04711f7980a5fc5ebfc254aed0ca891ae36032ad7b5cc40200862a449841b73e437a2cca3cdc1da4b550d6f24909ae4a43af47b23800ae1af4ff03b48feec454197529e6811ec9b1910b0ee2204ab9b8d995083dd2ab70d01385ec08affc65c5e9436b9a21afc066873a578747c2b9872de16ec8cc0b6c8bd297f95bcd9d2518859fe7da855c9ecf5fcd24aad49806fb7bad47389aa957ed6fae678124154fe973f48b52ff5f48295d9ad2b55446c9f2c44c7a8b995e92b9146c7d9925e5f8847b669b79c085db2255e3304d6ed761448e6c3be7a21a68d73b707fd319364948bf55591e7161c00d3a636e304183bc69809cdabeeead4f70aa2fdee9669f4e24b7dc276d2ee0c3752e549dc9096521825eb623c1fe754ba8658842eced1895604d582b6e91cd4045940eec40ecf008e68b2abf7157f17d65f210bc066eb5a1d78974b32ef0458e518a63bd50fce639952757209bc80b1deb2bfb918f1187aa7578c286cba56d31248a12218a007995ab31b512ca1296a91fc442e80ccfb4c941d6ab46366aadebf1e0966a21931a313e688040336ae00af572a3c1464e973655c32311ece5f9f7261eca25022b8f0e6e2731060395af971f98fa03eedc9e512225557f11a164b0284fa86761fe146d64f5fa4644724e4a643af2f42980882b443775d70cd47898c02cab4746626fcb5b932c28001bb193111fb7cd2efaf235c7e94264f385b3b385e5aa03d71725c29bbc2551def8ac266a56231e58ffd26c6b932e11bdcc54531ceb359ca99d6d05222f6973772b21c32b61b95dc5553f812768ca7432503ae185c0516fdd2ac569a2381ce120f3d5636f220c5f4b133ed216ca99a7ef9004acbe50578d8295faa6c49e564d51b62f074ac459604a1f57bf396397183f84f77e996fce0128e66c2995dd9f989ce8a914e2f180b00486777e34fa9a8a6bc4e430253cfb20d390e8edeaaa83d7d303faf4c355e1eba6e637b969d1611f983e98697bbeb2d3212a5c1670bc8f4f11e1e561797055cc11e26908a7342c2eb6379e6616f367c5beb6f0260606dceaa822a37c2ea76c813769ca089324cc5830e4493e19cf709c9756ac4990092d9f82f999499b53e7ff562f7e3e1f03930b3f97d77df85c010fe98a1cf03a35a8096d71df02f0c416699ae61e32ed2a34e91b9b6ffa138ef65f82d4b6c88f2b8e68d9f7c426f20c33821695baca8c9661dd265451c32db7ce4b42481cdca5de2d7ae675e6737030d3537a936e89061cc6d522e25e5044b342701550525806895f6de668b78c39be18a22be1afa6b651bd20dcfb58c7825c3909ba5d3f7a66518588e70904828a9e8d272d70ae1884a1bb82357df94c667336436c7071fd4c3e3d542368539c3819a6dd03d8dbd660ee0742bc098401d16153a34b1b20fdb677690ad8e653b61ad27eab8e8aad24e205313b4f9c0d42748483ea90ee659fa5468a1e7d4a729c09346c441f113469dedb078e6d6a60f3b0b7e4a0db385ce6f5a5d121b822aa1d710052fc42d24503b20de5ad0fef610705bf19ce589f67ac6cbb423d11fb1ac045d6add6184b3f100e99eebeb7c81a6b21c914e27137cf89e867e4b31d241e87641ddf8550052cbc74e0f867f9ea65be68932ef8005b4328f7fc523ae3babbec4b0b63dec2e55f5f5ac04b2f88052c43f121b9fd756bd4149082c19f643da129c9913fe215e63a04b07ecce4b7162b444fcb98eabde9b112d6115e374ff1907651e60a7cd4c46ecd06cdfe1b62188f324ddca48f381b9baf81b461696eca34bda748531fc53358f7f81e283469de11cec9c93cdd05e0e52abd59b019aa32bd8352b49b7e0dee818493e68170564ee6e9b6d511eefd6a412cee35876cc982cad3628ac8cc4d77ece91b6b39f1cc4f4ca427dc2a8139397c8727a9063c14b836f5c55e8c7bcf70644ffa07504686532a50a55e38f4a50b739918559f33133f6d096762471455b594af565b4ca43727e390bfe792c107ae054ea1442bd92006e6b887544f0e38c84465d635d1b37ca1e6ca4ca479379d6699077aa6b4c1459349ebe064c92475b72b8230f5b2bea6c42c49f9c20bd13b0b68b5679c7cfa30375294a9ec8da37811513ed970ce47f32c82b816f16f7da8e8be4f4b2e2ebb847077e1df053e01cc6fdd5eaf6971191ff5fa6772d4b3b347f49bb8b4ce33f2401e32d1328f007ac0b634ee1318053680fa62cab91e17a836962b2a7292b299163ead9ea8da2d3047c5e54edbc206ea111ddfaaa527d0a6fc8c3e4a82e2a6d511677ba75c6b29c5067dd4e49cc4aa5e1d0597c67b0e2a2b8f4d550c970baebdeec7764a6003479ea32c26670ebecdf0f3c84a6afed9f4ad8feb0ab13c2744e1d8373caa3837e424b7f80d06b5943b74d5d9d03eaf2635f0bd3713d9e409f1b6d65fe5be512b621a0bf55619dbd648d491a67194f9956d2508dfe3755cf4de813c7ea12424757746f2736f02644d17cc2d60c9b12fbc1080f5632e056a0a3a2c2829403d530c3877c23566d20aea9aa80ba055758f8365daa6585777ae77eb42aee494e004bf5a08fd8aed156b0851ff6780e5dc8b6c32506fba24c4f983a5a75821ea1e2ea9595adc591d3160ec83066c8c53ae753c8127cd94a49fae10fe1eae64fc9ba46b2a3a7f40a0f58c4350b9845cf782da2e13361b35b872e60290fb9d13b9bb4b7a8014a64d3fd5538227b4e297adf981b21f2bf5796cb20d1580769f8cb9a0cb15a64dddcdd5599245860e0352919302eeee4b0341e05b4a4f24d4aef0cef2c4c6266d7f6d0bd6784e9971105ab26e454001761ee966fe811b15563829c8a23627ec13922fc65a96a629cecb12f25fddb2b9a97758896e86eac74d0a09a59bc59f4f0eccbddb0faaddfdb2908c9e78f3a710a34de693d67659e963a2aeb6d45764577f7c8dfe7f3e796b43edd41ef923dd90ac76eaa574e640e7229939daa5476b28541d24b457886da0ed7c4694dbc976c07faa78a01090f53e8f27c6fccdb0bb2dd4074e9021f0bbd8505ec7938d477d2017f1e0942ddda61c9181cb554df62a4e2eec8387f9b1bfe3ceb85a0843afd3ed3e03a9ed5a89fe3652290655ec60e81d04ac41140d11b015ec4188fe81802dd5db9e11f191c3e68f5be419293de0f51bae965de85b5de115b530ed88bb7e8d6df2757dfea94892255b4ce501b96872cff7772a36a6d81eacfd3d865c4dab8918ca5ca156e24fb9df254077820e9a33b2a61e547501834d6d01cd33dce25f9a84c57d22f71e4967703995af8de381446f87a1a10f90ac4ec6d8a1c5d48a0f71dc472177fcec446b9ce95bf0f8cf1dfd5679b9ddd8a08690b1f0c6b2c19ebf323c3225d81f4e54b8d66d62b0154e800d35b35839e03c0b059d88ecff7b5947c2d04432267480d25e5362ee45357eb8b5217a62ed14ed468e62a70b72aefb574d0e5fecc139527e4cba73434cf18c4aee3ed9a966df56c030e5c2430eee08307ff400dc91618fd52caa4c4379652d619aaaef2a15f9d08a82f3807c8099ac4ac6fd2109c226e3832aa945374924edc14810b650feb88e25d1e2c3d38acac0dfb7ad40f84fb50fd6653cd1055359c8752fa5f8c1605d4ead87b7917be395d01777794cdc12b256bf3eb72950199e9b06ec4b6313ae84eacc71bac8c0cef4b1401fc32afa40a5caef31548019fa18a4204f9a6477e85400444b88b173d9fca2d3e1f895cc22c839af6f44528d29c4ba57ee596db1972c4f557a985c2e99f1ad45ed503552d96c1e584a44bbc7c96311970b58a1ea062a526f9e23d977fbf000c226b1370f147a180b651ea9572ee5f0098c3bbedce7da3a9c774c063e6795a989bf2290fd3bcb17ad9d5c8c604888467a6b423e7be510f7cd2318d18674fd7ad0b6faa2169c396939521fb0a1c7a784694735746ac1d6a6d904c0c55c0ec8367d6213646943943879d49d8e1f2bc8cd54bbeb4ee376d4e9f8f16c7f5b9ef0ea5cdd86ed2b8e989af42646ef237865661c9d2bc6b19325148aea50d6061372c5c021f759fa53efabad5eaf95475cff73cd65ff9b1eb893fe1e0ffa617ffbfc938d5628a36c18c61ba027d4c469bcdcda892db2c9393777227090c92a201e92541f6056b7c75e86880e101183ace2a8bee33327a5e91afb35e5f050e4f50342703ed71c7649196845ec21765fee012a42d5dc1441a90535ad6f380f14e5aa5acd55eafc12dd1a2520b405a2ba481fa2e1ef81e6fd9ed9c467082fccbd69f0be507555e1ad027da73967831e1958706b801c747c74758b530a050ce37e0e328713b947d2c36bf3e19ab5eda8d0e85e3ec4ccad2bfcaf62ffe607b5c5de2dcb26998ee62e4344e438bd1044b2f9d789a4f7bf87488eca548e571759ff8f8824dc63fd1b359666fe399d04e674f82e199e8f67288e74b87a4d53c2ca6e24a51ecce2afa4af4ff03f2e7e7aa01db177aab276978a661d5a6d91b7a1057ec0deec899c7d6f0c00fa3a1d38aee5898a7d37b2027151443aa3a28d3a5a1e1b86f92c274dfa8da60221173d04d0cf641342b996b3da146af2e0d397abbb3b34c062bb6091a420f545f0401063a9170015cb94baf384fbd5b70271942f8ae684063796f95a2a88725ce7b8111e4911185c2752a39d894d1a37833261186fa4679be01c8286d57335951019c9b946092bca9bb1608bf47c15878b3d2741ff4b19b6581cf89b1e98b8bcde4c5235cbb9c319b3e86efe8fbafbe98af184bbb1172dc43e6a8a42e724e0abf7297e45045df0b56e259621a486cfd16c1137f3b8b09de86e5b561cc4618a5642fa41908d37e79c6c64cbea5121f69aace5a44fa0217b788b518a75c2aeefb253aa9682bc461e46fb10fe64e5ea204b184119613ee5726c3b57f59b23a069e2d667c25ee8351dc3b4db8c1397e3e20f971694a7537493432c411ebdfaf67a688149069a12c8137b9010b93793931269ed6f7fb4012c121b4013e51e3ad60ddddf39c8f9a3e58aa8e7469f7f5290fb62d1ab4ba488a9971a14e3ff919ebb6445674287477bfaac95c04b3a228bebeed6641cdaa8e6363badffb9a6abe62d9cab47d4bc1e211447a1860745e26fe5bbded411cedc611fd7de089e8681505298b39cdb344320ac4f150aa1a3d6ffbe8eea0a970bc1c0aaf9bf42a3a4e11c65a23170612dcb1741888115e38978a8c8c3c6d8be1de197a58909d913c2f11311dc27cd799f981ca38f2291a79bd333e3bc315c59a007fd969c95755a84fe9918e91bbe6d1439c9f019bac95ff42c4f7c1d792c9f25b92400e7afa64412dae7582e081be62352c0aff8970df2437d0c3991830c2bb27a8f2e5c03e019b6d8b6702eaad23773e987ac6356fbffd76abd6c29032a2c5c107d520919ebf943fd51e1ddde787c967afcdbfbafe9baa1fc9a922adb0b35e99c59106874fe48bbc4a1986cf5f919936d12971ff2a94c6aab9a4b13f6adb5e62a3e91ca4ced9d72caf4c1caaef35fd5819d9f3af0a9ddb786e2d83ecbaf0451634eb0de3f54db22b52db42bf29b9c32f67f53638da0a32e656c4cd03d4f91ab52c451586298ff8e50a1da0044c87245f04695e40801895dd81d07927d4f53d00e2db7f7bf9cbb6d387ae2d0821935ec1f38ae313664f8a272b7b151d4e972f70f54eab610411d91b61c30cb7180ac2ecdff3d9d9a4358b20121b57e8aaef9b3084cc725374c6b26f724d2cd64874d744a78df08a224a7e2c9db64eb425ec936ecb37eb21c71f442b975a97e2355b865c72242814bf2e7fe3fc68ca6afd59a35adf880365a77b3fc454f6e2a04e1f4aa7b28ca6b446d7d03c6b18f9c84e6e3350f8c64db6a8ba57c4a6948de3ba5f08eddfb130982e5d63fd184ff93b5fd87aaf03f5b5bb54badaa2782b94a2da8fa38b70c2bf3620ccaec2ad559309f72499564a1066465d6fc9a02bfc54cf2238ce3bc7360cb80ee9e9d7f3d294bf9929affadf355e85da9a0f56b15b40615b478ad8216fe3f15f45a05654ea929b7ccaeb40afe1da4a3154e6bec1c8aeff6a8dc87dfe0cc7b2f7e0a853d5cd12ea702ff96322c9332f271531941bd902962e013afdac978d51020c6ca435d532989e961170276d71ac53a0550458ad00c162a46072137b0aac2efb695111e5d766f3aea90821c7bcf56f60ec5ceffa9d3ad63fd1b12fb020763e734666f3095d852a1fa1ffa82ce07f91f7bb73610623a4b84d106d486a2085c401947872410fd60975660be472cf1e874a0b77a34c8da01219a0ac93a88c21ceddee9dd7948802100465e73f8b9b52b444963bb4a4a63705861951773bd9fddfc1d520487453d4367c54ac9deb6d2de046c6f64600cc6c0e984cedeb9700afaa10fbea1ff37665361761d9085103a4706b03353ce8d162ea7187cfcc6d3835f78faef72f98396cb83e44422c32ed7745f922ce7bf4cf541d390945fc8e0a759718b97c450d3e4a6b8057aef8453e66a824d9c8e504fd36952d54dbd14507a3ee34528b6fe177a1194d7d44b610fd6c3d44a93bb4a9d6405f4fc19b532ab78099589a775566a8950aec18e69bc41a7a83ac823d1d0a0ca52f132c031f87da3b5e8170850b1693720bf6c0e89019f4ae6edefafd7fdbb6bb5c53875145e2fbc5e96888097ba254aacdb3b1f79da1173e7ff6163fd842ab4a90783f5ca137be402201714f4e936c84fad42f5f3eb1ff5bbdb6939a060ff9403227525072c14c901137525078cd5dd5acb8a1c7e355aa152c9478629646884b981e230f9120a700c131a33cdd30ca2232a72634f29b1e222639983403707e27e7453f0b8cf5d0b1b9e58cb48553405cd7f08075414a2fa532af0c542724266ae2c3961ae2a5ff44478045c6a131a0eec6f4171c2755195502b559a28dd517f42404e8e0360080a147dfd861160ca953c42caa564ffb337a54c0b837b4662e84a7ffde383b595ba8f0073bc5f319a9112ead92056fc44f16228af6159452788b30c16a4a92007912858168d9e10d7b8ea20cb95a26ef688dc7e3738832aae3455861cda2ed1bf0a31c93dbeea976041fdc696a9f2d50ae156a9379826ea7cb5569206c44831a65fafc9f71a25690d850305a92b90cae308ff90aa964d260a0c3d5d801aa113e5838dbd7444420f8a7dc0d0c1c6b4233359e2511f14b32938021421707e2813d58803b4f5e61f9378618b0dccccde06d92635487634ff9588b3de2e289ad4015eae7a5ee3994e35078a8722dc2ea3c2b2bbfca6abb51979a04e7215b2e55e4fd49171aae647db0452ab839ae10b91ec174cd6e93c064f3855d900d97451cd026965c83fd3e7ff85b4baa0ac6a9460e3d888c0a37bf7a9b681b0398b2180e195c67b59a5b4476a78c6db341976281be7def3686ab1f8c87d3a9cc84fd35f924fd13d4981bd96b7dfac7d558a1195afbf5dbe97bc0f4c0279b2963b3ed8c8ffa1104a9f0ed096a9cd3b06839ecac909e71117df3db1a889e2bb3bcc53527cd717a23741240bc5337718ab692d9bc820093654c063a588ef0c5eac36a5c50e8418a1ce0982cb3e43c8d19fe189205a57725d6629ab9f0192dade835779cc4142b52668b56e1461dc1885fa2a62da2fcd5b58c9de5c969e2c479ca85cc459223370f268f5c5521204b0377b4cd6ce4ed64e5dad5d78f97fdddacdaed62ebcb17653b600e899f96454b5084b17fed797aef673e9e67ae94658b9053107d4572dc9088795579a233b9466618da0eea7f29c9d2bc845461bb19065fac3d9d9cb1d27d523187d95edec623a9ba63a0362d5880116e2b3ecaa6f77d25aef8cfb97c2c091cb6642ae5de13e5cb8ac2db221c65238e4a9fb46ea2ba0a88e8f5ae7fe4e4ce7c3e2239c0a297c98653f65866663252938feba9fc2a4ebef70719bb908558881ea267203a51c68021c309802643148742b67c3194447c0d1f8270af674be6ad072935c9dd2b7e944d5e53a804840426b919428f283a9e04c059a90efdcbdbc246989ed82fee13c51ddc32249a841c5253867d1a00acd777cb5f442a0e8249d84b2cc4d5ff4873de44353b9af4792992b0e12eae3592e8e1ce61acbdf22a891fda45f47278d17da3e4dfccae15e1ebfc63dab27f6b20e9cd9b10c299df743a407fa58d1df3dd0cadb83d3040266e05b9eb0ef975499452ce4898a4ebf94f43f0e1d44706107f94ebcb1fc26a5d7f6d91bb245ba447b63a76802de47828b5500e5f00656cae51a1c5a5ada67148db182cb754f645043f1a6e110f0e69c19de9b42090e42b28baa898c80bbb284392958a12af4db9925c70d5948827507e816f3f7344d4101490154f4906023022d4c991aae008634df3d967946dac041aeff6a104ad9dc41cdc4bbd8df3df130373033f576f8b7a37f77b4b25b264dbe3f7e076be04d6df8c899713d4b231a577994fc5293560dbba30e0d906d02338809e4af408df5d03e7dff691714022e79e408f578c6e7686e0a06b703525c6ef0ebc8fa5a5b09390fa43266616d0c1e6f7ecfd7081f555af50c44ff4d2b5bdef43da6362a61c9906f448c22d8c3fb3426dee054659d49b506b023326cbbef69aaac23023da4bdb4903b7586c6b260b647c9daf534db836a481a527069277c2f94e776c2f9469aa4a7324c790de99c06d84d6ffe96e27c17651c52f4e215ddf30956f124d76f560a2cc658f362c8ee0d4c877bb9c353fb377aae9a363b5e9848543c072a6f7361553c757cb30688f141e407ae02846b2317ac0d1771b9f0a6d7e503a100655c5b735e2e62c446555ca58a066a65e0c0bb0c9de1d7ab64dcf92a400418d4d1bcf1860a27f303d28597d8b6fe0a358d5fe3ed993d1cb2db33cdf20934da00587fea45a30ddbc1e16f8e832ef0b68ca23714cec54f8905adbfbf8b8fc92e8eb08b6747d67fd7f720cc4335de055d4ddc5bf2470f0bcecdddcca7f28ca1ae1de2d86de822fd9363758533e7d2579f21b90d198e249fe3c0172e01a1b91eb0fd3a53e80e9f54cd0de1459c4408535cd51ea3e2e694e0351e1f52c6b5c309563a184db4f664cf56241d7d6eb1f238f6ebace19df35c75e59247d16ae7cce583c9bc545694c694ced3620bf895a07a3cdbb1ace11d20d7fc2d5175d3aa9010daaf0e6fe569714819b7d9c074881cb3cd51711602b6be2fd4e3da3518194bb596db2d65d5c33035e23aaa9441787220445c12b45b70d1235f7009e2c315624495ae9af6a626530c97e2ed40bd35c4430dc61e82037c2d8435bf5315cef763995a21bd7708a0057ec4bb485363f78e78678338df5ab259b058fdcf5827aad005bbbdb47a5aaf9c77370af09c057c0d60602f4fbf0102e6ff08087806aa6144c788bf1810d339d1c57f0cd4b7ba092e08a8cedfd1fb129ef0299cd36fc8e743a1762ac4af0264edd7c29613deac18d2856489430aa5aadefd5b209e7f44d7ab3067465c5f1c95e29016df15eecae191f4ea9f297cd51ab9447acd4f6b285692f159739f269272290398d58af29b4a0890500ea31c07a835678a4b97e6007f3e825bbd89041b8a2b01af0075be93ae70961700fdb4cf48faac4b546fb402e1b4acb6356eab47faec3bcb51021ae9a104342f2b509d931ccf395ab86b100ba884e61b476ef40c3ca4feb3d622fb306bc9d5948903a7447f0e3b1d0a385d52059c9c7bacd90fd5f54725264f1f5f548d4c2fae275c6f7184e14abfa2f579a05c70672f8f3584f46dd836b8ad834277c656487e8ebd2c6a0172230503b407b312c3fffa5a773d70eb23c5a2a97bc2e3687162f1039981c91a967ef2192675ce7cb9b31ce14da44b58c3117777ae4b54aebef085425d3f7bba234f60e98eca767babb8ebc5944b4f29a1de17c0b4a4d7bc36b9c53e19b6fa3a90c1312f5f48f5aca1c9808af0cc54599ad5f8a23a0ec8989d29d4e70bce2e2530eb59690d0130e78f351f3a78cafa1467efe18014ec42972a09520c1e093f9d0febffcfde9b75278f33edc23f08d602c2bcbe2349368e7188430821c959462633cffcfa6fa9ae922d1348eeeea7df67effdaeee83be832dc91a4b355ee56932db12134e6148cc7087988d5eeee868b927a42489cb50e4f3b8b28e5d93cea7a7f7c49c935ad57684c9822477f51d1b45764ef653df2260abf7dd245d8828c91ae268a0b02c75b2ec3ee7b2c35c998c99efd39394557405632b5e55d91b813fc759d45a34e1ee5c9ae74603c19be281d8d11ea52a7c261adc7bd277e15cd1f85f090ac57b7afeb9d447d613c1548ef81bf6f843d2321539b37ba1cb29edf58495e5d464a1db3b944af30e710fbec998a8e05fc610ce2ff185edbcad11b5d5adcfd28a15125e7ba4537a1033060804e946603e2aba0f0cdfe109b1825df685f894b23495e6f8b73da3bc1eea0b8decf1ddf68e6453772009d5b144d34b18150bb649029449f3da5c831f90d2d79b3bb4f59e2dd1e8c5ba981b31e3e4bf7478165f63ba8968717d9a83b916839a00957cf313138ce61a3c0292fd6af2e5a284bb9539b30bf60e655b8203ea96139892d3dfd501a90be77bcd39b96599c1d03e07306bc91c5bf9167b87fccdca07260344a6ddbd9c32fd5bed1df83c5120b7fb78ccc8b4122c2624dff76c87c2863ca18a4e9dbf671235121d29e9033c0f3fb39fe2102e25d8bab63549e95e01465ef82392063a11a554721f56aca95f9f1c0ed0db3897d4f39647c409e5ba552b632f9900995ebf43ca82b3d29e2b0df7fa34a8816c33ef07a7148224c296e0440c6422f4960e5d14af64fdebcc49bc5147c92067799e743d0903497069ed27b842f48472ea24218411e0695a573518df223a1041519e2e41a986014cd9d5bc86d93a4a33e273df7b49be574d7faf52a379e8cd53cdb97509292c2cf5d8c76369b9b67b7cd68f0aeab970d78b3f19fda5219a4fbe8bd65251e450d80129213cad2a06c780482b06b5cbd148dd87319be6a27d7a2f8c6b74fe23d0ed935575bf900c6fb0d31c74e72d4a4f6f1f98a6e1f6c8ce0766fecf4deb633246b8e08439606fb6866c43dd5333ee5672df43e7643ad90cd141fe2fdd5441810adf7c9bd2b7e47370148a3fa7b95502eb38ea6b3992851fbbfd67ed846221cb72c684c633775f4f2079c23a669a4a744daabbf22ef9ad3f3900147f24cb91b25f7c6643e1b3b1327cb508c014f0a8db2bcd39f84b58d17a038f7144ccd44d570e702ef88da132d0a45175babf2af0600a5770531ab33ad5540779998141efcc0fd8532542762134bdf7b76c285e44b9efa47bafb9cd750fbae195671bd15da11e76081cd927fcd15a96d193ce2a4f98016feb8afa3653c6647194fdb7c4246f7ffc5d788c793e4c8fc8eca5057c76b6a4a9cd399a994ccf5cf98a3353c3a71c766200403e6d811c3993a7f7f3aaae69be5b75aa60a1db25dad3c1c3f2e07c2b48b942d6675e7c0af159e57e9abdc98302eaf9539de00f55e31810415a5a855e8578af1363f1509717de677df11a2144265c7e58162032ca7cfcc06991081ef5488734ee7d09ce486167a2e66cbdefdbd4c8d4541e7011f46a44e29eeb5d120365066a1f889eacdb20c1f3558c655573a65f8892eb0d94166a9e1827b20e3ced27868bce21c1e2131c337a73cd11aba719f3d3ba35f53466e3896601d4d38a65ed39a1773fe5912fb6d7a0343a4f5086bed02b92bb7b4f6492784238cb1b19039ea02db9a76fd105d8bbc30bc037dd663bc26d1139783b76c199c552ef13c972c039dec8e334892a2c3806845ecfdced1542063a63d279b5098cc6638c0fbeda1064b660cce20181c20723c6b821c8ce5f3e394d7f924a57f8c831406a38215f38bf2029546bdd79c82ab1e9a0e5baa691c30032a5ae10885c13b001a50848cd992fdcf5a03c5fd9ae2835ef34f56af25c99fca27b59c256249f210e10700962f4d34485dc24d9785ce302a9ee9e8d7380ba851eb34e4bae1e32d0ec3fe7f0fba53206fc7b15bf9fc61110992392a9d5fd24c2fb297e3fcd224cd53ca2100fa8f56b28f40c1d123625db535dc20006d634639aa9b579609c5096a70f6e91766b3f963013963868cb4524a3c7694859b5725f4754e80c4e7f6d418b5e1f18dd36c1cb0e08c378ef66a0b1094937f78e2449d32d7b92be33deb0bb54533f9b78f0ac8a4ed6cbbeab4f839a885c4d5d37467f75e70c2a890aadac97ad4965ec719d61917c3c286aa004f8a6a952d9bea29f946b51896c861254ebbe34f62aab444bf7a1db24a72665bd85638eda238c7b4f00d0de5d156e3dedc59c45bfdb6c20c281dcd17b25f6c59453129291eb698e8047fa4e207804014ad85bafc22559a91d11215302d65f38945c37b7352ae7e7da686aa2b70b1b887bd94dec76f4a9c9f50b2c1ceca232e17fb70528f577e466f64ec8b64f48eebf94dba263d4bd6d725dee0931922bf8b887cb395dc59c0c3b028545b8d5dce5f6c329fdabee808fb50f289a748788199165c04be16f6fc962e30ac6eab98da524fd8a84fa5bf27baf02d0bb8274e4e04b230663e84bd1e250832ba237d74d48b9fae4e9cfc352d22bf1354250cf70b0a274f2d6bbcf6c57cb075a5ab15d7c144de2c7827850817c891fb4429c96969da7a25dec89a42209cf52220564d6f8c8172806a0c1cf7de1c3bbb88cebc42fe759e9d9415608b5947922e23e025303c6e32785e9db1118efb98ff4ab8e506f0534e48f5be9773da1de221005bf9b7ef52ed45b1fa0eefe7eee7caf3798e0c7fea42baf42bd95b94d3c3b7907a5a85fbe4ebfd317d91bab00fc7d0b03a746d0e9c503e707ce51459fd3b1b68f00c07bc9a39326ae70cef0ca839bacf1177c5cc12f0ed2ff907cb55a0be4b4f5d7c0ff7edc0073b915c1f8dc9bb01f0978d401d261e6e410f078ade5c5629c21434dd5081a748e2c27ffdb0d59735b1bfe78bde0c4e53f2680366bad4f9af621e85d61606ac1cacefdc5622edcdfd4525de173a53778c78fe168b7f4e2cdb996134803ad3af1baea1608ceade1346e0725073202f0786bc59d6f5a057c7dc7086b96c9aed37ae0827a82076891dff7b10a336e6bceab50b6cbecc838d7da7199c112652a58cd09c6ef0fd0633a9eec1ec1f0d5bee1742baf34e03d0e0aa578e6f48dadfc315e0111546be9296d9bdc7a2228d62fbc527b400db7befee376a0591dc8ffb821ccede83f6f087621ceb94617fbbec02e8e9ab53820a175b8c4c66a1541f54a80c77b8dc369823aec3eadea00f6cfd28a8d9d7a977a75c09c87f13931bb2a1022dccd4d700e61029a2535d77e40b9720865fd1ace9aa4faf7cfbc60746bb56d6c163c8873d98075bbcb99b52b92bf44d23791dafcd66f9573fb4d6b13cfd8855ec0cc11721ca308aa2bb8b73ed2d8e972e65416ba904f1c5467794d7c27b6f58262009058a0653b9fb233efba0986af2d66ca6056303958639b07b78017264f4490da0c92ef87b935b1286fb7716fc1c7de821873380280ae5943938cdcfdc81af0cc1e22c426f82053699779c885f15d2371a1e4989b9d0c8ce44ffe099883a046d2e233f03a838cfee5eddd0a30cc3eb18b10be5fcd115ff26ede5533cce69ab50b2812b581bd903111cf1497c43d9894d0543473e08fc0f4c4ab3b33cced3bd60ae11e39fe2230e6c57beeec1797f8621f8502babc3eb745c539cf0ff0a2783fe2892a3b0cc6f449714e1dda439f340b9469c403b7e52354f036cbc93201721e2699765c36c52787e470d44bd0351165d2be2739ed04137df85807999b6c47f85fd9505c9355f3be4e1b1b7a1df218a73fdb8cf98fb8d9307770e2008367fd3fdaa82ac83e0bcf2319eafe3d7ed085d44029f203d8b0d7ae95c76147219e0fd9b6f08849f2a62e3bd21293e9421d72a5d2b8f5de4c66df45d91bc815bcb1989b83e3a8e41ce3579224bf2efd2094103dc9a4cc544756cd68513bfe7b6157e85a155ebf55685bcff137a986b4cc7990d9031afaa41f19fc9849f3cb2fca729a4c87d0fe59103f462abef83f55e0d21dced9d6b3d235714e5c77ee7a78a099a35f9bbcfcadaa8b2f246679ce6d28387b7c925e2f71c933be9e836b1f0f142380238db445894f9e3d8b4363abe7a5e1e81986a85dacb3a8549362707b0357fa0f4147ea5377a735ee42680fb3b586aac932e3062dd8fdf86025990839c99d3e438b51826be48d24d2bcce61a5f05706de485525c749d6e01df5b93ee0324bc234a0d958c911248455197985d86f941c13d67886acd884acc0191fc30437c0df80390ab7cc24e5b728525150a4b58578ad2393d643adc02ecafa8a0314e01e44aeb5c3bf41540691b849f7aa0767433161c17e5b32fec97177822458a77230b29723c484481042fb1ef208de9cc9012eb44e85a33ea67bfda5c6b6bb2b93a3ceeb115e4481c9812756fc690ea3e5cb8fc3e4960416b4504b8fa69d5d90faf208d929acc300c0be810328044d4e14b8c51f862a7128e23cf5ed053612a35090b78d98d24d104e09d54add6dc0297dce91c61b2478fc09569b4ce0af4bbc1a7fe29accf5d9dcf7dd09ce5446aa444f885e0e0947fc3cfdebee1bc8025d660bf82ecf2962f4878fea1ebee5fc05e372f28eb4d68a2f8b033c7e5eb32b32026c21617c6c2882df9dcbe1803d82265288ce0da82addedafd0aec0813982d271fc6c9eb94be9c2e65ab09a74857a98a1c52ef468416c227e1437f113d1d534bd3500fa39b264f70071730b1425781e762a4fa44ca709a39bad33e50e8f4dc7939ce4739a1f557512afb592492fff47f115c65dcd17c99f74b5fce4c9167976d0856b30cfbe018f2fc9a26f729fe7e449627c08a5e1aa65c22c74d34e8631f84664bc57f754f45096d9407c1e64a642a77b2691e1187c0aab105a35f2c05645779067ffc2bc71c022079f3d764677877fe9b1cb591ead3cff406009fb83c473ec1dfeb26530786105ff7669009f06d37c46fe35aae015fb2aeb655b6ae4dc804c52c4b10bcc2bce9abb67df04dd9767219e77cfe47172908363da0963c0c6e05d0d28882ef10f0d53df1894b692f06440e877ec0136d07bae3d5283b25df8e6063103c45080493dfed229ec9ede90f07b46b88570dbef14bb94b5843755d377aabfec233d027a33ce30c2410474920d40fc15d0dc138bc573daff448de410aa95e711bf802d442da5e9284f52bb4f019aeacd0c948d26c42dabb72d97d66249453204819aaa3937bbc8a8ec4eea095bf293159ea848912c2208734b73694a8cd24e32edc91c9f9e66d29f266b708bb3a34d64475fd6828c232a72eeb03ea1f5f0e8dc609602f3d0cb8ea752e524e773ea3fa3a523ce3cc792b2af500f6b6965e4f5183ce039822bcec7905d78b67c07ae0822ce1dc8499593297684789d561976818b73fa9ae5dcf2472df6d3f951b54494a1bc30de48eef7dc5a8f93d485230aa47e18abe42b25445b7433238e8badf289add1d655f7a511c78e0e69f060a84a53761f48aee5f6119ea36125afa5952b9fb0b15c7d2335aee1dbb854d94f31e2a35192353041ef7ddb5a4f8f36f037dd42c9ff9ecdcb38956936106ee4e408b7887df866243bb213df7c2d1354bb855e5dbf497167e86486a1648c29cf25e62e72c92c33d63280daaa7e1141079c0a3d825dadb524c099167c2cd45e6de8b0dc11f7f8b9840f2afad265b7c10372e257d93db1bad10cfc8c12df8a48c5de6533cf18667b269fa67ffcc200d35c5867f345842e77c51645f4b4b3d78fbdb5c3092daa1d3365849c4ec447cd81e6660ea631b346a01edd31e4bf6e5454f1e6a53571fd0af5b321b6b0fbf7e679f9ad8996506b893d237a332869a9adb618b85f0b3feb8a89eb0d491333754595949313b7bba0447c23e490ba3dcee24c1ffa22f48c32560fcb3d1290176b078297f8efbe1b498e797b27084f9aaf1aac2a47eca11588e342ee195a89ccb77b77ef667ba2dfd0dba03197380414c6e1bd15d373dc1e1c1922ac909e283d3bbec8b975ce15bc8776c9d31d5c344672c5a92f53e66532471cbfc70a7685f77624e7899c7ac82ad177284b2ff0673a872924b685c9730ae7e63c24718a3ee95681f411cea600b9d8905bb55ba633e8d7ed83335959deafd395050739a18504f6ce178e4ea78fc42bcbaa73f1e8ecd5ce1279df0a15ccd0accc0e08ef5af81ec811b5148edfa1b7d05dd9c320cd64c823398b74716b79a4e8ad70f29e7d17eeed2370e8f86125f114fb18d5be7ded5d046ff4b1397c3d3fa7d8a03cf28de4734a5fea6ed955ba4cc774ac48c0192831a9b2f3d8cb9953b5c4bdb920cefb130c7877f109a89e65913de88a0e67096e8bfab5de72b5eb1245877873a4336f476f9687e93af630358e67e30120a0cdc1b79f03ba8f62c2f9ed8c2c67dedc22a99fa62f66b72d86e409503fdbc9adaf3bb9f14f3a397db3bc3a8fb157e79f76124e8805ab933de16f91eea38d7499ba6188befeb478ae15757fa9f501050bbb0559214dbdff04eb53bb3e4adc64beb2a1d85fbf5210cbeeda3f17addb11dbeba3dc0f1c4b1f9487ede19903f44d9eb7cdf58d69c1f8861408217b7f4d6edf6222afc89ff9eafabe4087bae0e8437d4587da6b100816da2c99d08e49fa60ab6f07bb5d9a0330c623f6a28e34200cb0e2f0df7e76ecaa69f331eb8a5be379bcc69d3d650fa603472af8509f7247dafd0f3acf73c0c47ca158a07bad65f22e0c0d4c3f7684e6f50cfa81bc42e116c663782d500c769ea8c85e8adfbde7f530076039d3a4e46500f8254420b62607062d219895829cc2037b52e7b4f694767b5a671ffa3a04fa89beb4dcb93c72b6cdfc10d10a0f4b2e9841ac6c6f6efcd9f92b7d2bc954f11151c9d6177b42dd9b6fe5d9da4fe46fdb34ab21bc17ae907466441017c11e9d5f2bb8c17300493b0ae000c8b3ea9b1150b6a7e503eb0a62269383b3f4e9bb5d358c08aa6efab750827984cfdd26e5464b88b7ad2687630690d920dd631e72e99c1c8d4a925c560bf23717f85dd13173ee7eecf9c81e8a0e1956ef8ec5332ebd3c2ffbbc8a0bcfa40896b28c1ea47cc7f73195992de00e30676837fdfb59780579f0cedfaf593b809f28c13e09682baac3415e0cd9ef22fdb21aa9623561876e1691930afe3755b053d45c329499199aa10ab47bd552461b34366417542ceb50168bcef7f22681e1d4993dc0367142c1f5061e4b111c49b259bbe484e4c20969fa94ed8931c342242776789b5cf887e00416e2487bef7f152cc4ec0416627a0616e28023f77e0cc805451ee8c8bd16e91cb8d3df9021dcff141982a63b8d0c51d0abd7ff71f5f241828b576065e07e7f81350bc4f5dc017e095c807a053dd8164bae708eef8c913ebc4c031f4bb03f1708c0322600b10b34274b1a949c6fcf89565753e45e6443e1ed9d0abe7d3e4a26724ee2605ab321f6cefce428e8e7fae3b9cac947f4ff271972ed1db8f9ce4ff4c5b4351c21f47d743210fdbccbf3733a90723c90ef54a825bcc6866ef5232d729e17b9a817b985d504ae5a58e85b109ab9054be68c45a17fb785faca03b3f799b3830739ca1d3a426c37a2043ff2a4841235c9a18ec9b65dbe25dbf642e0b25bd4dc8e4309b7c486a3977da1aad725e27dda6540045480c1f5699c5e3995105c7a3a2c2c32448168436154954957a6b771577ac0f11abf59401a03e892f79ce961c1d0f998e6e292712aaf1689c5692ce71cbd3ac14432f071b7b0976c5bf175839bfbb8c5ae50371c667be60b81be5e764b384012d72f4715bb65aad313ee5d79a918603014af6c6e065f4b46f3e134f65f1c1b8f403c19016f63a567b653d024e19ec2421ed69d047834d4dc3c993c9e56d663fda747e6105dda045a1f25967581f870a487f747ecd435cc4b1888481f947a68d0ccf7fd44ddfa9a3f72ee7dcd7384945df3c6efeb4edff5b22dd17e1b31aa2637dc466df5b123cf572fd81345efcb95bca22ccbe2794a437e9910533906380791d0a5f30e5f565fb45f923922b57b0ce7edb38ebf2fe7f823d00fde491759ba001180e7cf4baeb02547fa932353aa128f9fc19129584726f7fb915105874ecb2189f59fff82d8b1e1dc155578bbf169527b89e33385d0198e1709f04560fd063086daaae186035e357967b5408dd17df6c67ac62e06af53fcebb315ee7d20e3ab122a77761125d0b6dcf578cc506e5dbbb6671e03a64037d2152aa7f64437bc1b92dec86156a8068278ca70c016440c717dfa970e7f4fa83b3faee50bf7a1349497cf38e70b07801261397c4e81b496238d8cbb5500881a2f1388030cb6decbbab19f39a7700e1800f475498912dc484e60cce4de784ff33c54ba74d41f639b99b14d3db2cfab2b0e726a9df46e01490606bb24d3c98b052edcd5a7a56722143d2d022ea1f364217443bf544e89b8d7f7fd3d18ff01a97ad98ff38a9dfb8becd1ddc7d60bafe8dc758a0f48815f7a00d780cb3fd7445a3e2084d09198ca3eb92dcd900794b3778d25c7575609fabe881a154e72b2c3295a284615e68877406593c3681d15e051b545a651982e5c625f1c52f27983253c4ac638c30fc581a5f6e608e54e0d1ec8000422915c0c694218682abe99a0d7f3eb358e13375a55973d506a747be760d6dcc8012d15cdaa679272f8c3880f9a16ff47f8d11e03b4a815f1efe215940dc06814ed0c79d7abad83345974cdb7093fe0fd81fff6406a55c149cc7d5d4268602a3de9268f0c9222bb1d86042285b81112ae9e1684addd20cf99d7398f831d6cfa341e6fae06bc6df48cb509bfc93fd02eff78cdb6c4e797f541d11e91d7af8a649ea28abca040583c19f9be1a9009fd7d89cf100957e32e2d06a52550370936882bd47d9e584bd11374ac117744a6da571f6914d87f34ece3dfd7013159ee5c32fccf8ccd7e85215b4ed62a46db12c120c33650b3ec9c686235660f35fe971c776b907aebf0259b271ed34b79058eb74b52b2785d514e34e445f657c4bc75af38701e19974838dc76b226c8d76521fc1d777303c759bfbe47c6a8d7c4776daf86b73136b1fb80e95aa307c1a26ff90a0cb1a75a454c4e7018204a1019b4c7ecbac66ffd36294fae1093b0ba875bf218a96e6eb3a196295a62286f4e648c6d2b913176ad44c6806bf48f32c64411eae45a41aeaab0c3c85eb7d87ad861a20b7512ab5ed2521539e421f05a736381705f92fb579ff21f2ee0cc465937f077b49d355c417aac81612bce8ed0529e57115fcf64945255c5c9d7db9963cae8531a29f8e06c33679eabc83979bec27287793ae5ddfd98091672f81bd76c124a45a7c6caef3d61d8b85b37bfe150a6f8aae2227455460abd354a3fa3552045d3cd909d5ba392d52135bf1473b64798f28a26e779fd0a14b52351a14e86d4d9cf39cde28724a837fd2dcc1e9666d437b8f2ec83dd39f609e269ad0e7d3689b6848740aaa74bda181373358603cd2ddc6e0a1b36ed82a3cb0002117ed69b6bfe1a6c461d33401e117daee29ee279e9923b403e80b5de7f226e328833eebf714ba71fc87685bfa77829576cc93ab3e360b2e34bb6276a12a766c8b9275482f6f72729f00c41e8b2ef2ca0b876bc331ee0ff4f640e3968bb38960f1c4f650304efa6ec667aa5f8fe0af51d4b4ba4f60fd64eec942b9c9e9768fd4c32b67051255b2f6137ca92f76ffdce6e239701b3bc02284fb5aff941bf8c61646a4c4b914016b8be57e04fb18e3b4c0b31b03d01bf57909f88c327c78ae34f69d67a42ed3c2394fa45b21b748a7e36109d871362b6e95b06ae52eb44df55cefd1fd0772d249da348fe531a2f77ef8e2b0e12c3e9311722992c7ac844af06979f5e91c91dc10019257626c7fe8554bf1c1959f0a7facf56fd7e9f412b80e34171f0742f7b0f70ae6e0dfb2a46fae044ca7b946850892283c0947018decbfacaa8c96a4a3d85c400af75ba40ae5441b7734c8ce8ab663c073369fa597db382b64b65de4fa7e1b89b88bd0e802dffbc0d28873b22d6678c96b721099bb622a7518d1c9896e508d50a358876a837e60c1dcc8d0fad8a7307ac39294562d0be91e4aca9840257755f20c4f369070580fa041440b996d8f6f0fd907e5a34403c27c7be271a454927b8e43ac30964f263c7acabf8dc537ebabdc33091993c00ab26f07088c6712f7bc28bd402c6dc6fc1d3634eb75da8a4667b2eaf30db3b8e702e106ad31293b6e08c2800a19c58733675788dc03f552941bb9a2b4b98381ad8297b91460e7f8d4490d7886c28a79f5bc05f01cdb4788da289ed3d9961626421819152e855b845779b4cffcbd8ce839a73acb3e4c40b424898a484ea1e0958b5ae8aabef192dfaf7f61d60adcd88f3748916eb474101d453f10803c5161807b30a21927c44f76022daba727304cfe821fdba1f50c44daf4fbf9eaac4ed513a17b20957c8d9f96d4edc6438e2c72b7aec5adaf0fd87a50d8fb72542684930983bbb8e9582634368719fd5816626fc97192d5c814c18576cc2a8befc6ec2b84d18d4e3edaf0c6a1f0cea9419d45a858344748badc703a23e8b196250dffe390635a521da24fc69e423a12e7b071d8990390f6356e89ce55713e8d68ef8a434b70ff0fa1a7fc67731f16593143bca362df8e553723db564e0512da1e400f387c89896a6a89f427c1691da92547303270f99bb5ba07f3921cd90cfc8c87c2e88b95fcdb69d3c2e92df902a2ae4316b7370ca052639d94648b2649a2153dcdc650e9b74fcaa714460497bbb251f9a2776852428801562f767486644f9b0d5766273d0b3319040d794cb90c26cfdc68ed6634e8cde8219bdc22bef498a6e02e4411509593959e02da804c11de1f6eb6e11cfcfbf8ac6aced0bb7e00e17ac6feb08d12b940c8f440474c2d74b843f5afa01c5ea48f6df06659a4e58ea25cab493a4bf4ff6e654fe91c23f340aff951f6fd00222cc86dc440a9490728ebf82a2ad0dfc9e12aae0d2810d2a0413f0fe443b947079855b25688b7701443a4c9f9bbf65dbf6e02deb8af607446eaae0ad6fe1be8cbd06146726d13d036d4de8f6c15d42614941d389bad9362567a520a16e52a69194a9d2263085faa42d08e0001541e9d7cee4ad36737932310e94e5f5083965b58f3348b9038e7d831836d55583a51d4ec1db1d29bcde474fa0f5386b99c7f4e7dad98a54eba5be487cb1975f27c0a8b3cd5917f37cc689f7bf7fccfd3932eaa051e3235b475ee8536cd40206624a6d3796566efd988d13b011fcc40d00526b3749993ea4d2a03e32e211e88e96bb6e713524e11dc73c6701b972298b5f1cdab529b137797dc4ba294a1e97cc0bdc3cdbf5f26f2cfd55194c3a789a6452da0629c1176adea8c2933fa81c145686dbcd9479526aa0507e3d97ba7cfac00c9215d859dc01032625af5bc2fdcab6b37da9eaac8a2971346096a12ed496a5f19e79f2b995c5aae95f5bdcdcc13275600bc368212de44a06a55b603f7746f0b93585d81c77c5e6813ac2703a404a5caaacffffe13fa16e7772e4c6df6411ad37eb93e7615773035596fe1156c1c27586814a346bbecb3007a4b7038995dd829b78a8513c18dd721cba6b0760292023f5e59957943d882319b29c30066f4624b5bc9fa98388abce9937f39fde84e0f24edf2ced3a710e36b6597dc6525cba52f55bb7e97f819e84935e7b1c37beffd637ce35a3e5aecb1397bce1e278b33d3f3b9e0937fcd69a7fae07e6cdfcc79176b0bea76fb6b4177a6706b4fc695193d652f336fdf6c65aa077a233dffb5dfea973c92c24cd116ec11fd5395d8767a0fa9837a6dbfbd4cc254b84ce5d5ea2cb9be4644ecd669cff741c7e385dd6d4995857fa52e1c22bff2fbc4a2d53e15b07cd1c6dbfcdb8e9c4da9ed7546bdf27c2bc59fff426e941eab4ecbfadac19d0f6dbca5ae349dea416f6787e9140652eefa0cbcb971c96d436b940177092cfd5c1313aa166a6b5e8fc48b1a8975bfbe3c36fadc2e5b94e68b0c7780d1e701bff1645bfdcb7b30423a033796e4abddfeea8bfb3aa97eb2c249994ceccb7fa87bff4c7f4ccdaf5a767df9a861f66e887fbe3efbdbadcc173770b44af7397a56f14f91736d1e5a37cc230184a3c85027c76aedf397b9952f7dbf2fbec59a4f8cf2636b51c6520424ece55ab2347c6e21c9daea7eba5daac9e69d3f4b29aea65ea2ef99b5bf0f2f1fde3b54fb8aecbd4e8dcd27b176935a8eb395e11668c73b4cd3ba16da91e5c625f2e5323ccce0f957e78f57788c439e20fb6f4f2b570f9cde51e9c3b4fa8733a20b3b1e0bd119e398483bfc7339f6c2c73337def9cb57ae706e41bf88ee733e4e6470ef3e43ba6073fca277feda6fd8d93fd6b1b010b74994bbb3cd7272b67de443f090797477a79de2ef7e04f24bed3ebe0f29b3fded816b5384fc83c04c7e69aa415afc928c7a0635021928a6aa8e06750904099a04eb97054d5edb0ef57080fda44a3506b4e9d61815db7e85d44900ded110c69bb3e690290b77f2de37ef939b84c8715d227980cb5475602941a20309912eb0148f1d4ad0278a22db29ef03964ad0fdf91eeb19fe81c605fa9cb439f15607a4ed8f957ef0165405f5451aaa444e37c09ab8debf325bca444f37c09ce94a84bdc7c2bd1d6430d92366ecfb7d14a4adc9d2f112625eecf976827251ebe95a09d439d617c1cfde0f17cb167a106aa9b3c783a5faca799945ed2dacb0fad3d277d7b3b5f2cd9d52da1d6ead5e8f885fa385f210101d2c352efc92a7c9dafd0150846e75d3acf91d1ac3324f383e2cc1b50fb9579af5e7dc5a68f8831da5e85784715d11e5196227db7c4cacaf20bfeae4921faaaf492f5843742880019044faa1ecf549d2921565c953336d9b53c21c2590ecae7790e0ab8218e7dfc7e42de236aea24adeb43493f564a881d37cfb1cc1334df6b9c6ba4003b43e7fa5b0fc8dbfafa5b9dbe14eaab71a6bf6a2da33eb02ac6d0767c5636a981b50d229450d11b2dee82923aab8233faad66c7904eaeb9a29a7ec1410f4151e834c3e6711d3b75b6fc02e126b982e2eceec58cd4effe0c265706e0f3857a5b8282fa8ba53c79538756d3af659cd3378c94f44236533a083e436b7b19d8babce3917d5bc63095d639b10a13dac985d21920b1b61959a015c1233342cc9e3f06458d4085678c21e80ad55a516c426b4f0dab811c039d7001c3b98f0f8800edab661eceda5b0a3941f1788c73f207f0f3c89f1d2c08d3fa3e0707d5d698aed6748d15402a33c06b0c0aba716f2a8b709df30737c944113e5573c669575bc245f60184feebebef764c1778b086efe99861af5cd17da2bd80ef86d940dc3f45d7d674dc611e38b73625f844e442c79a4c4fb85f991994fdd437eb9d2f3c32b936575dfdf7526e904397379a9f6cb4a6ed3d2c63e464f3ff2a39b62851c4161c3262e63fb3f90a484fe3b3abef2f3b6a2a2bb436e1e63155ebc74d5b90e33ec7b890532330fd60ea6a4fc880e14f3fb33188658993a4fae220c9f0b096087521bbcff591cc2f7e311e09634dfab36ed235f574050b46883c737b72b2526f2b863f0288e9710534c91d82ff425e3b3256b80ff90ddbb9c9aff7c1200a9b082e5a1467bb42218ae85703c9a5e2a324822b2e4fc9fd9e46e04a28bbbf7fbe4229fe8027dc88320999736936b6cb7884604c3f84594f5fe89b880e23a1712ada654d9a2bfefb8a5cd9fdc681f312613706c96ebcb176e39cf798b5d7d4fd996da6eecfecb0d68bb9a26f94734a62fd18ee549966c870ce5e40e90db55ed8dbec00c24edbcb173ebadac906a2c131607e368dd03a73cf6d6dd3283fde2c9356431114552563771a30af3441b76cbed4f7c291507f6fc5e2fe1f3b93bd519ccb8b789d26e8e79c524a3a0f4b7c6964df1620b03c5931ed8c7fe821b504a56113fee223cb60c9fe7db625ae19c877069f507f8e980ec0a90853d4d30d34e081e82f3f520da50aba5dde7bbe789f2bc644e629ec8139d753f894b8a9fa9cc071cbd15a2ebff2cc2bc62422f8cdfb38fbd7d74e2e8f0640c515ef45398609fe404cbd57b518b9373d55bd2f84fb5bbeaa46e0d891fb15e4068e9bc8b1cf4f1fff763579f222f99ef5c45aaee49e3ebd929d0cb95faee56df18027bde335e1881c1500e12bd85d35223864040d5ee23f7d0846b9eb7fb8a82f16722467ec93d0601a4193e322a304dd7a3ba9d7216017504a1176cffe310494495996982af4785974c92f9e125f4fc98bb5c26152feee672af20f9d8e4034f5696dbe994ff0f9d752b239dfa028ad03936f48dd0c11c57e19ba824ff92caecb928f8eddd472abeca6764bf563531e79b7368aea78fcd62ba645dcd2c8ffa1a1b66811f2cf3579fa36d9d91f69ae9adc4bfe859bd67bd0441013f46bf14004fb131ad74e96efde5a3ef20169dd9faeb37fc75b121ec8feeae024d741c480e5e3a3f59057601aaff550be6443f12422c2fe652c8a459e7fb4857b73a4374d21cc23df23c54dd1ff7e0ebc78a300043c0602a686db4b27ab44b3a127f4e6c55e16dd5efa5c8d7f6d2f101ef9742822c32179b4fb2fc426d203dddfe6d30227d0fed0bce6d85f620f959f3ed5169daa53c4b1f4f9ea8cd7c98bd7c9f3776758473c821bc89d18825a57b6a75ce09e9769773c7d5304d34ac9a4ed3721c46122f7b7a8ee5e9b93e9dcad01954497c18472b9845324ded633d399ca55dd49d89e29e1eadfdccf0802cbf1e6d364d73444c219566f893103b4befe45a3b94dde05915c1c3978eb4473aff93c5bb68f992af6e4317f920a7038a01d106cf7ce092f51b8cbc66c176d6a5dd417aec798b3fa11e56914fb3a0683894d86ab6e49f425b82d81cc2701ee1f97d50cf196a1e26fccbcb9c601064f9195c354f76328509762031911cd1d28fd31efaec8b73b6e3a8afabba5f3ea3dc2b387e231bd7bc7da662ad9668e450eaabc7bac5da4eefffa06526f1c85322d40de9a71fcecb196926d67f759d6de7749cd7a23aab7595f38a2721b37d5e29d154f00f1be7b825483d796c75e5b366aaafed3dfc31670dcb3275c201ae45f750b441d20cc713b08d00d9d44dc9b2218b395ecc140386bc7de92b45c1e85361524c725b6b1099bc904fbd604d779626ba963aaf7ef9167f7f06d96eb2cc6d5e6a7572c3bd2156a36d87a2d303d7397d25cbee63266f9da2aa9a612215eece8799d1cc9e21c685172385349897522ce0545ceb6d2df324e43bd6831fcc8e56c158d5bee935edf23157543203b4d40472dbf24d27b47dd24fd43a20b2c18361eb855de0e8aeeaf736537114b0280d21f5d5f2c49bbc61b5ec74d5f2ab8c31c7a56d3978ada3de4d67ffe3c90b9a9e940f82339614c686c2627d94c2ade4cbe8f382d41a4451ca79056a2e07483a9fbbfb3b7382d65397d62c76b698eec331dd93b517f3b21e222b8a26de17e5c61c182352799d9d0bf4183065e4e8ee5f5405e1126b72304c5663592433dc7310c3694b1c825fa1a5cdb271de61b4f78effa841fe576ea988bbc756b1433d083de241319581379cc410b932f604609204889020d632cc5d507fd06a3a50458bfa214335c18996f776e8d3d5c4f38df0f68b982dce9734026236b71a00837608410319fbd527da19e702dd072df3a7c457822b82b4c54421e814edeb8e7cb2cef5a071e4bcdca045f0852f4340bfab0a966a6226d22ab59ce021fef31d414c19ea263ee1e968da4648d0e6c48d748f0b81db838be6dbdb3cd76bf317f09af0f21c407d29807cc44bf00a0180f69c47cbea235efacea32a9bc850fae5f2429d5cba3960fc4458f31db7eadbde17ff76b79ae7a062ec0a7b5af3ece563ee9f9ac20cfd62e78e73abee34646dce35f6aa7e7ecb432f5db2bdb2214e984e893a4643392027e40c5e215a5111442fae06d72445ab13244f853ce47339931b313efdd234b7187cce99b11939be1f1f44d8e132a6506e9379de8440284426450754e3422deb093509d19217f07c49abd6972c27cd6373d8ab774935af9f7b896d7d494a370a9d6c4ba13c7f75cab258269ac0469b3d0144f5d68f1eec59d3a433e6e4406e7d192ad987a9c11b0f8cd37298b9ee7412ce6529497ccb9b784b861b23023c1be496211cb88905dd45ceda1bced408e24a18432a00b485133bbb8375775d2b4de305e25355b240002fec80d01f222d312cb7a01f9d62a121fda2702128bedd0e2c29a1f5068458b559ceef589c01eb76449eda4f75baadf5a3a91d7e39612a15d3734f27f6ea7e5c75bf385a5703fadc17cb1af4b300108a3d03c917fafb7e732d64398615caaba59c6de08c0c3ad4b330eeef7a59a11bb55b5f42d644e78fb27de7f7df857d6ff6fc9fa9dcb6c9de76f0fe0465ec08bd0b76f44c472737f12af44fb0545efda9b64cd424dcb9cfb292f053091e26c66eed798db5952bb77fe245959428f705fb014e0540675e7dc8432900888f7285da66697d9308849543f3f5d9ee890b1e85e2c798e87dc2acd32e0bf47059b0e06719a21acd62affad0243a77cab60f8dff7d30a1fdf8bb7a64aefb3bba3d9d3a150a06f27dbbb2b82dbd4b29e3d5fbe1f1113d5849939b58eea7ecb2a8b4dce7ab8e61fabe4e1fb0bcd55c4e1f05a566eb24837a9c3c4bf053be0d1a7912071015231ab3b48314066d4f921e692030573a9ee58a3193d22ec9757acc0ec05f6bea1a19e705f66fabef3be0ee07edbddcb7b3af027b8f2e6cc450cedc1aff9e12a4979d7d5e36c0ad46a4f63d924b84eec1253660af4b03c2d33c1fe4f8d5c37598d5b25508f605377b877246a73c025bfdcf14b4d528248566ddbd93342fa08f0a2ec580079354e175ae744a304505559f35739492a3d2c83592e359247102049211c0c3c86258cd3214ed8a26ad9927d4ecf44a69d88981812763eb825b64720c9e43649915c8851463cc4504fa0ab0a0901e8584f25a71c71fec816a792de4b7337e2fd2e2f4f0bc4d7304a1cee4c8116b9213429fde1e380e0f5d4f5a4ce199e7ce135908d7060eb4cdaa793ed71d4fcb0ec9cae49f8963d51b6f851d94ae208ff38275df335b152e5b09ab9ff78357dca6cea23ab8c6819c70658cd7059ab8134bc0291744a299498788903756293062196b5cd549a84926c7ef18537600509793e2495ecf93719530b6906e5741d936227eb6876027f3238c61c04e0d45e92431ea54ec518482feda8c6dbcc23838987449be251bff728db9ccf59c642da28b77e5c2310ca14d3c733b8ce2ad1b8b3026ddba0d0bef10da03bdae39419b45200a223b2f8364dda0dd62c5cb8a249babf7bfeceab32edaab94c3480904a9277c54bef5a22d82ad63300bdf2ed7482dc9c314e9a84d30132ebc14c4a62ce0420943002933046b9d42d894ea120f4d19e6e2b00ce6886285ad02485ccbc16a7770b8957629f5c5602b03f44424811641697d10b9c079968cd6b8e55384945ea0bb555b31a6be313178796de2b53fbc87593992897edeb30f3a0996820a4ace5f6d1de7fcb97ac49f2f609c01094dacb8ba57c8623b85cc85565246ca37e0de704181ab12b2121497016ef1c38ec30f742e42243ce726535e61526053b6016534780d96844c8b7918b24b03f39e6ac7525a9452fda03e2441998b56d1a1eaf2de374e6387b9ede4d445d4cba63bd2edebaa9459a97c5109851f4e6799fb77c0023da52c0d0bf1a929a66e45821e9641e7999325fabc927a0947899bbf50220994ae0c65e356198c7c0e84dd785f581f38913b2aa49e312c459451e75cf8387b5bd45de93a9fc882732c444de89c2f19f3330abb73290f14e7cec2e7bdc79b1439ccac93ea2e45fbe095edf5da452f57851ba53381cc053ef0074fd0f35635b9282e4ceee69eef514bc721be2a38a4561e39f675a250041694ac3d545dd5011232b1affbc2bfaed7ed08f22bf3437166781d2e4cdabcbd897ce137a6786c46d704e5e4fb800cc7da01608d163298f4a98fa4a2ceb7103c25fd00f574b540bf9b1b7ed50bd64ed9fac43f4774c4e83596ccf53cddd28be6f9fefb3a178507b7ae2788bc4db89b4c82ddbd4e83e9a4786d6b52ac8fa4f3b7802654730b53264b7962a26a52d016f403acb7d2b833351fc26f710eab71da0640b72c6604ac129bd7cb426e4af6bf0ddb71177607f8319436ab4fb45acbc6ddd139adf7e14f303ea6e07db6fc02adee96736e508e4bdd1d886dfc636fa716cd48aff918ceddd5e6c7682dbedbe2d367fe66a76fa668a5bcc9facd267dfb54dd7a8aeae4f34a2bb9aa50515f69f9ef0f876aad061680a1b5625656ffe606cc8826545265df7579fd5238cd11ec0c1709e14f3571f946e98f8bc41ea6ede1109e2d816588a0e32e13792cb1fbfa7e04cbd49c2a19ad8264a9f92b4625562e9c73b2c9ccb2dffd6c8d9f2677a76dac4f79efe51cf7ee8c9e539b8309cb650ea2f8c049d0ad63055ee162c87111611f093026c28f75173749fba9373b9c71ef3574b6b28c426b45060b974fe5601b20eb2a5f9f39413e95aa7ead2d9f1def64c0229b76c43a40b049ab92084594a89afa6d222a54c308cf947d30ba62686864cc8990e06be5d426a99484ce1418de346d9c9bd8234ceaa18cda95bdaafa359932aa1e1af2627c3685ac3c0f401d5ad209920665dd1d103ba336e2689f4e823d29daf86dd4dc2fa2e286feda34804b344909b9e56b06b05fac4eb69b13bcad392b76827ee9b42ec518e697948a6a5f307d3e2a617d9f9b6c82ab5c85b4bc4b04b5258cd83d5546c1f7830ab1d086fa9cc1282d1ec247d7db0faba64c5e3627adad7dc3cb65f3a22f3ed1e8b8ce90976af351963efafaaa7dbd29c39dc6335bec73e7fbac7c6dfeeb128758fd5cc3dc6e6f83e2276be92117e32848e993fd756f9b698f56ffdd9c396f0a206580b668d3fa16bd11ffa3afb215b41d04adc0b7f79d8165ec1c5f602567a3090dfe4195beeb4e9a36f12a3ffd9c396f0a6ae51c3f0d7201e37ed47964a61cdaa19754e2e4a943b7379d2ea29e9b007908d23449306d61244cbd47f4cdcc0bb27936d5ffee95e6c4f1ab94f3ad1be3c8bbee98fb73ca97fc1fc5a84100600df480d53326ea5ef9cce7a20bc919a4e3437d1e8ed7be0c58d418333440b64e09ebaff8454cc319b329943209397639d8be35bfbf0fb9f7c3c19b34acf40df5902958da1d85536c1d8d37d99ca9b6c4f04facb4da0f9b27ec813ee3dc2d6aa9c1d99b3af1f4a24880c641dd859ad1a54eb616e48e5da895f033b0e82560794304f55551ff85770cd0b4723c47b6495f02259e9bb800375857a5a2883e4e93fc690734140ace33dab8d10334a1a445f34b0c75af0e123e03c6aca5dca0d87ae8cdc6c5b4b9cbeb8c670171c215bc15557a7504435901998239e47e36fa3278c5a7df1ba3903b4dfe2089eee74f4079300bdd51292f20ad3d14337962317211f574867122ef06f4b530697c8c35416f12c18e790352f822f0cfdd643669cc36393546dab6b330faaa04cd10dc0f73ac5262599e1d16ff348527320a8da00091fc35b4416e85d44b26830c0605bccdc403d4ee98c15e301e827481f8a8c97c19502d745adb06feb27f697bedf8281b503f7c09106ff03f04e7254e80053358442a080790bc6d87ecf5053c425db5cd2dd237746ebf1a42115216eba0583c1bde66947b240df0b8a2f40f3e6bc3e5691bd9cf28777fcefdab5bf9f14156d0abe6b15b1a43975c51bff315530a41ce7a1700437ec95462ee1bc4ddf48ec39d26dba6f3c9b917a84ad4982f733a9895e88637a2683c40ba9af9fc9d9e985349dcf1d524a21bd3c25a07aa11e3cf7e86f4aa5f14c99335e48cff7fc4a8e52641b787ed7637e21d3def3a79eb517526b3f13f89c7ae184f20478aa5e40859fc774845e605679a674911577a41778267d94a10c2f4e2ee77ca72c1b2792f39995237bbc72e017c937558901573d7dae8ba3f341ad28f49c44c3e660da0b87d01f3d43bfdb2b10deefb2712938d6b413c7c65e68e7a83bec4e1b38d27a1da70d9c8937c6ad8cb7b7e5a666c8f133d8254fb86f8fe768eeaec60088d5dcdfa0b9203711fb8b609375ef63eaeb098f529d3c18c24ce89bf777d98e081e4851df23a7b95efad0fac2e3186a4d5ac66ecbd5f3d322eda3534cf71fe6453792b9959dfc1c0bcbe8e4e63c57181ef11ab70c4e17af434fef9bb25a725eae024e16e79ec9a022d6aa4c5f5447633168a7c2a49ad1b58567d9015008a35a32a0a50b604afca80206fa2efb2cbc296ee90dd9bf3b7b3a26dec42322465f5b0193e869f118e3fbb24f3d2d736b46ff84cbb73fba2d3748d0bc8583683e654c845559bff385cf68aa9b37e4a26989a68f4cb8fb37c8553c3fdd6b222e658bd83c6b46508ffe7327c98cfd3c18d3cc16d42ce79ccebfbe057c11b9755a85a11ca1ece0c75508cd2ac02bf23f5980b2fc34731e88f69335d2a9f7c723ed3b25e9e9a1b6a3b1e6ddfc32967502ef8ccf9cfec7fd82b6fa9df252fe84d6f22fa4e6bf909aff426a8a7f213553c3fd1752f35f48cd7f2135adf9fe1752f35f48cdcb13fb2fa4e665aeeb5f48cd7f2135ff85d414ff426a5e9e6b6b46ffcf426ab6b69233c451260a6483e77c552af5772816d7a49deecbe5c2892108fc159c174200cf4d17b6a27905ef0118e48269c689a332f554afafab729671b2a1389896b7a88edc533b6e1976b379aae55daae5e549cb85ebb25c65ec2cbc2adb11257c652c0b680aee8657fc95fbeffda777bef060b209efe27eb484f765ea91d6213c52c99bb72be3cad116c163d613917fa319a99d7f8d8425c80d18911ac6a5bde450526dd15bd1c2dc528a40ceca369063a83882252c1b7d89801bf398ba8a0804d2f677efb2c6fbf0ebe7078170dfd00b36a3c58003eaed80d6bbf3beadc102fe45f4154bd5397f20f36337db1593268fee3ed649f239492c54a2f560bac296e0d85d405591ffbd97a8fd5d10a1ce835530485cdd2ffc5e37cb4e97d4c8b4e82f2afb2efa01f56d239f92be156cf4cb5ffa3687aa8ef4809f2f4907d9917e80cc76a72ee7fd28b150320a23f12dfb5d3a0eee97e2a331c7c9babf9676476cc3d4d3b62d24a03e6de347493f8c8764b625b6415955c62ed4719c9f4aefd5fe0daf26662c3cbf9a773fac264d56ef25ae6e56f3ee87d58bedf6f1efe94dd5794ead6657644cdfaa8847d834b21ee1ff3e8bebf7e590cc938f0bfa5739486529f9f153ad96f83e4ca4ed23e009779924a5b4e3a2ecdfa79e055da196aa0e1f5afaa667720293a33f9c4938639659a5696be98e1ad9b658b5aea1917d0225a29ce774b85fa738e383b24dd35a62de9a22c9569f4313a68656c6c7f726ab80d3d8f227113b4f9f30a89a6ce73296e3e804d4f5d006196b675be2fe2e9b97a273dfc784f5d0437d6206c63d5e09975e7bc211fcd0c4fef942712c5c7cd1f8fb66f64473ceba6a3f8259a94db85e55691e33b64b70459e011d78d0b4f664240d764deb97be65ddb5da4558f3698413b3b04f4c58ee203d190cc23d20a6658d0f071c05b25de14d5d7b98a94999cab7ec4189893c68eed02313594398291ad4625f75720477ed584875f30f8d1f09db895636e75ed640ba34936349b33170feca6c9c9b87bd73711ecaf22d5b6a8892cc4b060af685e8fc730bccbe116e4ec293ec4079b47a6bdc0d64b8b3a9b7ddb591fac8d63c3154e8dae83fec5aca7e33247a5d940f766f4cd38170cbea2f77774d88d42bee2d029ffb2464bf245be7eea24b4ed613de5c5f3a8ee008855606e69c22bbddeb7e51b0a97ffb9fcdc401dba8b5f4ecc7b1ceac43c0a6d79e9e81a68b5468fa7f37044a743de3daf3c84df5fe5a5f10c15dc68e590069520dfdd0131e4176737271c3009ea377ca07906a6a7e9d876cc913ee6332fd94451371813b38c4b4a389935a305f04891b54530df95cd74b8ebd4fd35263559a62c56fad59c5727fb5d8740427e93cee16a03425984ffa520846e817d2b81e0d5ffee733943f33438fbfcd50f1ffa119ea3b3c45747e2c16d3dffec0352c0cd7f0521ac4acb6e11a82986bd802a3ff67aed4faadea4446c24e96998277988d3a74282cf6d23753dc16d76addff9dfdf35eb22dd178abe69cdf3945a197fe28ffa4ac423c303c712c26d978de75234a35d02103bbc5f1fde1e4d6fec3c9fdce34aab9139ac91d4bf6a7a3e96678b9799f5d919c84af0debce256c099e14cef9d88ac848ee6dc189ad3852ec39e177fc3219bc5b25b8e1ce27df9d0d0151dade30027879c26954e3c92dc1ad80f8ea600f5bf781dafb64d93466acca19ea791b907cea03e1bcaf08cc7ade23d09bb8da70c91e8bec244036fff9803dd898bb7f15e2733600b8f39cfe751b4b2862fbf24087cc5fcbe310fb31cf0e2d243416f8e1ec01a35142bdd566b14bcb2913fae25d7ca3fed69be00cb39b68e8560d739c821ea9ccef8fb4a2ea71c1d93610bcf20c0548bb4ab9675d4a22a2477535848b03b532820795b0ebd550af4ef5d452fd69bd09c4cb291d7135bf54cf13ae8b7e2ffb7a47b98d325dfd5fc321771fc3710f0bea485f2d81e5fdc605823120ba5599d7e9f40b6da19c114b4aa6ce604999d5576a44aec653695e4ca4967eb6aafa171a8b709ec72a876868d3f5a04cf963d5d62040fd4963fb15f7ecf898eed98c7b56ff0b3d5baea9b1a12a132ffc619e13ae8fdaaadc695b7ad31332edd49c7a1c7a1ca77776d95dd092e4e50d5eae2754fb19fe2925ce48d3d30c0985fc4beb4cb96f7b3e1f3da19af43ee238d5fe88298a1e503475b3cfc2adca8dc90f13975ffe587ef7adfcfac7f2876fe5b73f96cfe3ca6a2145b12ebf3f2daf2711e5bdba9cc029bbabcb1301216fb7849e849a9404c29dcbfef549c1285d7038e78235efa4e0345d707cb620e974186d64fe90945748c58c305096f0c2fc8676ee756103b17832c7a531dd7032724d8fe0964465dbc22d4abb7020dcaf9a072fea9e66bc68e5d2fd9c91d4877e2605e96ebadc4f0e716602ecd7d7e73bd4116ea40ef2a4dde9afed0e79a0a30b03a57645ec53df6594bc0169a19f49bb7bff4e48b077f650f3d49c3b97f5c1c989d36765ce31dcf22e1b0aefbe34e42da93fb0c4bb0f6a066deee099db33eef8c283fbba1ba931d846f42d1ab99623f4af752723ded91df6208fd537bf561de69ca4c72312a2820f8ae4211ca26bc180901cbba062ec01133a23a034fef54333bc825fdf7c64ddf1bf77723564af7e8a4c191aa7cd3faabb20af3df18a25c177d77f5877637f77fbd7bebb1ad97d1efda5ba1b696d53f95776c26e68ed84fdf0f24e084d9675ae3a551b0a6d60e8972d3a1c9dfdecf7ba3b8e5ac067477c26feaceec1def8c79f36fe495d6faa345f98265408407d5e215ea638f846b05bc22da8abc64935642d79dea15af57b357d46cc756751064d3d1d858ddd13ea895e40d1fd9ca7e7bddc5f69acecb8d977e46967c2514463574a3f7f1f0cff426339c73f196695194a0c331a7ebba57463cb0bc30c4e8659672e13c39cfe95c6ca4eeba467c87ff59c41cfe6e9c6f80e0bb6177a46da6b9b71014cc533051a8b76355dedc749f38ece449ddc3d39601444e79a615ad2b603a83c3b2055a4b0b37de15555df37334991b60db8f50ffc1fbe12c9215e9377fc72cae0aa3f6bcde0b7cf99fc56a81346087f376a34188917dce012cae6d60aff1216548f75175aae358c3a675760355998b5d32bb803966bf4433bcab47562cbb07efb7ade99db32a865eed442130ab7637c793c76b3af42bdd0acb29db3a99f8054f9743f851416d1b03aa7cc9f2ea7b0b1baa7fff406caa242d7963f3a4d575f16f8fb8bb1cb9a1b8f14cd2115f1c841c317ea4db785eb72282dfdb52fbcbd5286fd740902d93ffeb0e26c8705a0d543326dbf3cf0f5bef2852a53acf347dec7a07a42ddd2b628f330aec69ad87b1f4cb67bc2bd23cc77ea57d1da6a9771fc69ef9f6a6569c38fcf1d372ee251988123b84c4a143a9260fca5e7a325bcfbdad8be903c2bf09073809dd016901c8f26ae21c409a3824d4750186a2ab79933df5fe3fb4bfe7e666c5f6a96fde8bff4fd7e649d88a397a859fe4bdf1f4616c756f09861fbef7d7f1c59f35fb4e79f431a4fae83c91f7cbfffd3f7e7f8fe96bf3f89acfd57b6f7df7fe7fbb3c83d15ae9a3f108c48220b0929e4c4c355d5b94c3416270fdc2a4ea56939d52d12a4e6ac7f10fc7ff28bbea37e2eec79aadbf304a9b25d4f73409050dd3d8216cf8a5514b384cba14d093855a4b6194ccbcafe5cee7ffc731b7b172a6b134e9b970f818ae404d84b36cec2848cc33d8a7cc3269936adb76ca4f8265fb942e5e43ef7db8109ef0f91257d8203e2fc80646ce1dcc3a48e550fd30a5d5e9f759ce9a7f18416182055f45577a48e496a3ce12f7ae66ff53227689e9b4e85f21cb9b501ad49177c57487c975b96d057b70bdc4aee296bd2a8049927cbc327f714334a7ee629f5c83870149cfc8cf5f22e6188bac2a500b8b01c919af2660cd81e91d773fad2c3e367a54572cd990ca13407f27d584094b6a2a0fd372efc4ab2881e07526d98c26fd9b6de111415fdc165df551e324f67922afba2473e02e2c040f6b0ddfa329ea12dfbe6644af154754c16942d05397b7367e99b6b59ddb13e099a383dc650786f0383cbd0035881e7cf11e6b720c7b9ebbbfa9071c4083c8efcbfd45bbd86d8cb22431b4189f291a1af77ea1cd1d9d05f985bfafc3a21b4b617148f6b54c5eb19e25c870e9cfce043d4ae203c375c46a41f6e646752386f950ac31dc29c2a9983a2985d8a833fca05ac046115194ada68af35e3ecbc9ee6ec6752888721e55b518f83fbefe5dd2f02176d2fe65c2d2f85b8921191bba0cc018efa00fa0f98945805dabd9abbb191602fcb4d4badcf5a7ad1d1fb606de7a3c6ab5721de350b9a4a776dbdea9c7d454a895764f74d0c05b4eeb1de20db15de520dbd544f4b73ec68ddd3adacda3d4d795e0e523d3d79a5fee6aba4a7b6b72f71f3de569ef4b43267f5b2a19d3e197c1839a17a38a3d2fb58b12a92b64f79fc4dd099cc61b91fcdddc43d60a44aec7db8c1db228716efb1915b2bdae361e5c05479aee59bf65617ba31fa532e0339503d3671acb907c3e46528fcc72601e7a694e8ddddc41a2d1028c32da9332836d4f7319ab112331ac35a89fad929c8f3d37ac47935e90a521f08fccef1d34ca4b7817a1b71ea5757042f594f34e22bce3285b924d23ed2d4aa6b087beda66eb491d8d9830231bceed72c35599d2d9b376c7fd6cc305985b696316b63d3a8b50afaedab168ada42d4e481f64c21368b9c2c957e4991156e0e9b6b3f977fb4f85579767545f0e39ef0d6aa1fd97dded2e8296b8ac84878be16131b0ea4670f8ad0b8ab03c83668e7262ec2b26b309dffd9fefd750807767699bbe01ed25d27ccd70f5a7ca3c907d723dac64e6fa7254859967527de8b2ab688bb42ace4692ba40bce39b489884fe06078e03efdb59162f38b8e91a82ff6ccc05db8f68cf867262a10aaea5c98c074c07b855223fb39eb76a3f7e4aba2dec8a7a37b4d823c53a7b00fe8f9ce9c740daf433a30bc0f06c080a38f06c29fb3e14193867dfa76a9c0e60eaa0e5684b11314e6decfb32ea590647071619b78ddd20c3d602bba7e81cf779fdb26e2724d96d8872db934c0d7333c46eec548f82b0f1ad4419aad4c91ad2ffda55078f7073eed66348b29004668340756d000453c9c1292a962634c0dfbb4bb9ca47872ac12c7903eef276e6c7d714d957691ce96ba99929558b4ede7816815e515e396eb077a85a648ed32625bc4c990344f7df3a1fb118aee2bf1124f358220d0d34529fac68a37bb273cd2fe0c656bff9875c5483616e447f2494255f0c53e165925fcb763996fc55711dee6e9870ab62f8657558d58fb128a6c4b741f762f50f16a26a808ec83ad31647544e73ed788e59b4ea6c11287defa5552acb5c8bba5e7f2df9adf41a9489933e9c29f0ccca008479c5656f17649715f84d2a0dbcad362ac25d70aca06b7de04a1ec48d13b97a54252a00daf96e7a5336ac6ca8aceae91180f86f47f60f5951c9af7822a372e77c817eda3a392c69ca4ad03420bd1d84a926fc8502e96e44cd59be3df8ede369da25b326ee4f4903989b0763490f3cf1464aac95e1dc778276bf8e3b34e85ba6ba73276b32b4952916ea4ca8d94c05d8763243daf62e2afe0cce6115f8cc893fdc24d168825cc560999293b656e457fd517bdba5bde3ac9b0593484ff756b17290622d31ba108c7cc83cc4ea4f1ccf4ee3916497705669201b8e0ab15d8fe3df9c5be1665c932174233da1d2c40be39595c079084ec9e53e77ce08c2c026982b270f843e63ecc406b0b97af3f4f38a20c99b255c2bf9d2add04eaa9440d2aca231170ebbe25ff7a26795cac693c4a271ea408263ca205dc953a39be1b44b64da2b59f4a56790e1765fee7ed7160c601d7567bb4800278432305542d46aa47ccf137735c8f8c5eb3217395bae7e1dffe0cd9f273d7b68c72c3be183bcffc0ac47359f51789b1132beb2b465420fd1156d99b2c2c043552b0bbec194fc204a9cf450bddd073a14f579febea9d12dac406492d026b50dc3cb4f3d4400254a3dff91428a0cbf804a37d2d66a8819482de88a656dd2f524f236cada62eabc5aad11202db7889df11fd56f04d0b56a8db2639ebd94fa6a2cc542dd4d2a96792a58466127850fe83b9cadbf7a3856321f1f949e44109907ff1e62f99549d9657c280c1854abc7d96c424e86d43f9d781481c6faa05a4592d84b608d6e806a2d28e338479423d54016d7cb2c71643fef681efe1ba4117f30875ebf061d6c775b0e9ae56d0ce14e9825491cc53284cc8ed071368606a80bea58e537a0b9acb70398c4b05c2630a482d7830c1ed49c2bacf0f9ce4369b33373b46d6aaf61e737285701ef6056488c329cc8b6144b4447dac98f696797c051ab0fbc1f077f114f697b4c13a5fa9a7434a3aa7ea8a913d4715d0c63e004c71125a23da8e6e414e03ebdb2234df3073b0a0c0ba765daa5854ef6cbf8fcda3ac65c4ca1ae6e87f745063dcc7d73c224fa8a7397fb0be82baa6d4a04852c5bdfc71848178adcb5135f145e84c8767d68de8adebf7814ab5dfe2ae00616ad59887c7266bace5105907ba66965247871d6b11602a30b6154f0ddc930b447d3c16af362734b9b296965b8930d249434c86b89006d4c9ae307a5875b338c2a317b226650e71ab72bbf82ecda40897bb458315a8ad3a9c43b15d06e97a39bd2d70b08335fa1ddd24ad5f118899f3c2e7f5ccb1f6850a8ac8edd7e6637c72768baab2c73e1e00b8571f4b4d5f70a453ebe58fd8bb534b18ddfb555d25e7738dddc27b1791bba1a172e6c89c6c02b8590d61759ec730aaafa2bb75a2856b1eeb96fa1b19e7fe810195fb328362f2db27c8ed7b04cc9604c2abcb192efcac12eae8549689829e844a97ed9b2e2587213103fa6730db2264a19af431a16847b2324e2c6d9d538453110c66d0300fa104e84bba3890dea3a777a43e5900a2c863e3f4b66ba52f9e77cdfb130516e18e31d2a72bb0ee90885a11791b4ee56cc5b8673da1be220eaedc55884f7d3f5004ee33cde303dc89bbb925d44d7afcbadd2afd564759c383d73a17a09164e8a1aa622a5e8b5899ce90f72931b86e41d2e0aff74c24717387578b5483bd12d11d6faff0185fb9b63bb1a44e6839d84bf891dc86254520a3861b7085dd01e95573b27cc5618be8c42b133312dfaf784368f9ac4f2486003e9410633520d2d0cd7e8aa0ac86f4e393504a7b538e7aeb2bf22287d9aebd256fe56e8e1c545df60f89f725aebb70087eab750571768b8d3a583b9644bdb9a52e2e91f8ab1f7cabe88b6ee450a201d11e2ac21c99c9117aa1c584ce1ce92fda63953d40558d97be963a42d60c6418f15209f5a692ad5e9ed9ae52c8e455992526db4e75663b9d818a51b197dacc6213eb33cb17af2db22938602f9299999bc8abb99925af0616003bd99462d31167a77ba4d040613d3615bc48f5e756270673f784729b64772c8d0fe7ae51a68bce686eb9f1b5399d53d2eff8535e5d8ee7b61418a1e2fe0fba6ffeef52c2709e97ef1fa1a14ceca14c7f184a3ca039a9c1e201cde30175cc847d1f50f2c5b95aa486b5fcebc3e21562b4890ba34bbeb8552b7b8ceb5fc7188f742f37f648b77fb274a7cbb856bbd478f77f6fbcf1926eff60d4c9d80b4adfe6f1b13acead6305e9ac2e0fb0a89914870313a4c886b67a9ce6d11ba94a904c642135915cdce4421c5d6e65a06a81a5459a5ba792e2bac3930e6deb4eaa8d6a26f6d7f1f6aa648faf6c8f8fd242dde2a6a309e1762b96d296c48435cb7f81f0eaaa62ef95aa3dc4d3f6c89827b6f2a459039f14ac293f4551d5e61611aadbc3edc62d2a926e5cfbb7c71eccdfb6c76fc3f03517a89f2049f8f16c070321c275834cb62a634f61ce9e425fc4466cf2af7215b765927bd2174db6acb8b7de282dcd0f1667764adc84ae54cf38f671223a315c58f3c672f519e2ed7108eab776cf74cd132ea49a9f3a614e95194c558ded9e44714f48490cf15c7301cdfc30c9d1d89c5b091bef93c526d3f985d5de913b834a323bba4edc8a27d49d485acf830b8fbfe809f7bec03ff2d0d1610272f3e400ea4d32e701e7994b43a115f933d719c461e15edc60b19f9c75dcf5bf23f6a5ab256ea3fef23af5e5e5913c04ea6e29a32c7a385f187af8bf6a3a69a79d9d4e9b3e5814f22fcea4d99c45b79251a4591ef37d8af92cfcc7f34999d53ee26340d6d66f931afcb72775aa4a71ae17d506ccfeffe086f58528d2771b6694e756f39ff9569c65486fd57da3965109555e2f6cb46f6b55a1b0aafb4ce548ebe527ec2abfa02f7b3979185854791b53e5736db6eb7e9a225f6a98bbedd5557e6091c9fd253249ad07753f7db535443202f8710da469bcad8945ea8345d2752154b7eedb44fb8faad3c9c93957038bb93b2eecf01a2a7c0599b99d21143b0ac9f60ba44af1d62a6fdf0905fb76628f04734010afd7b158b891fc56a21dcb1a594e7a63f997bb5b93f9c54491dfd91502e311ce155a84be631568b1f4690a74f49da605e3be241b17b1610b4b6f92b0af0a5990ead2cc454dc270a57f343167eeab2e3255e9e9024852b3c0ba6c68ad02e1d755098f081550cdb54c0958344f3cc371e5754501237d4894ccccf875f80bcc53dca07a1cd2797a1fb5cc0ca9a91cb7f803ae10371165857999d0b3ee34ce36abbe66f4f7eb3c7914c905fd58a0ea927e68a93c38ca15fd78ce2a117c1d739666314fa979d5172c6453408df933846274b371e4346c4470d547f60d2fdb11ef75a5ac33c91e7955789d79648af538ac3f8480cd1935b216e496128a34de7e219786cf820285dd1660c6e8249da104434705adf89af3b45f9146563d95d0546b0a03babf19c279ad9263451b971fe3dff6969eabb9aca14067c9153328d0d9d373b720c7342abfc2b1da9c20dedb20a8f1114a0c00509839a3ad59c6e4f8359e62ba5f1886a0cc13523b80904e38f9512e4ad7219d45e8a4ea0cb9c3d0ea9daf8131d7735638fc30070beab76fdcf0e2da35cc37a62dc090565af128d548167964664ad857da04681e3855d99f0c429c1fc5e95c9df4c9c5949167742f99f3c11fcfb9a11745592ecb5f6703bb9a9caadcf2851ae7bf219013ca54c94cf4e151cddcc9049a3d452ead1f66fefa5358eaabf1dbf4e9f285bf97bdc42e329aa213ab05dbcce90e682f53d5391572157dcfc18db8d547541e0c999d721e4f2bf4afaa93ae522f33e557a13473e403ca367224bcc8c71e03be706fb319299cb72992f28426394f7474b2af42ed947e2d1e3219dd40ab48be8102898dfccd54ff54cd2d46e3ef0045dde5f3e9bda437d9a68f29cc9083f6d39a6b1db8d694f082188c2bf386cb45773af78681bf670dfa863778b74a85498157a1aaee9a972c4f0d07a488f4d76b2898672491885e027e94d3d7454b90ebf99eab5e4df5eabbfef283984bcaccb95ea4375331b558ec12071f834790953a1f15b397b22da138b0b877796bf9453fa5f05851cadf100ad31193bedc754a93b13165f44171dee9072dbcba1bf1574a537ce538fc7fea2b6645cecce1bbe834b7d8ff613faf37be734789a6764804a9f7bafb4544a75b64eedafa08f96ed1b178df9379556d5509cd75cb5cdceaf7b9e2bbdb733bc2ef63609d320fb0c2bfa9ed771cd802aae6d130c733bba7c4d5b4c8bbab53e5164bfcdbb55a84af7d8798549573ccf1fa1b9d83e28f3b5574fe994ef1a0b55ce09e12596b51353da1bf8894937effa3c08b3cb862ddca126103d87b6b69f6c80915f6176b7c76c412d690bb91350c73fc273c0e5bc2756a795050aa0a973102906cc201e0dc46323b5a1580a7796ef75865f6178efdb985214e633e3d7fb6cecd3f55985ea8f0cf7fe102650bbf4f61fbffca29fcb5c2e917fef29c5fac70b2e7c5bf531357f092eda3eefedd34ff1b36cd49c72fcc1438c698abbec04c9c19e73766e2db383de1976366a2c68c6bdd90b1a9caf644f7c6561fe3cad19781c79ec20c9f68844f8e81a0543c8d7b7d79e439e0eb5b19ca25d238ea1bc67b5bf15d3862a9d8f82ecaac2fae1bbac8446ece97211dd235e5c06d7dc1fd96fd6239366f3c5350174578f08d450763ab9ac569faca84520583213563dc25116050180439457c2f09e5566715d70b843aba059eeed94c65dbc2bbb1d48e4b7474ce86813c2d80776339ad9459445ac035a01b6520294f460efb1ec4be28ddf908a2fd62e4e8d12d21ecd0b3a6e6200c626bcff805af4845c40ea0a410784628432762bb4ebf0f7968d08ff5c9eaa838662fde99c46e7621354fb913e53ecb09190e58ca20cda473baadedcaa3465c968af0d7755ba1c9c4f1d21f93ecb293644d5ae1218d6d431e2c6aeeae67e983893025332aaf6fb5eb09b72ebf1f35271eb6ae304e0dc2cdfd5ac1fe425b4bbd66289b91936d8be0a5c03dbc9aa9ecbb50d737f6f8370df22cdfc92d7eef1ad9b1146ae4dcd9a50ea6d411bff3a6d4436a21f22387bd4b0afce43072744d7554b7a992a5b864999f5cc5258b237b80ea2e3d858f777f654202f15e940cda3f94e457d65b4ad81a5eab351cb003920977a10aece46405d9e35faf1a94048addee477378eeb22dc81cec232a9335fdb9b085d0bbc036e8cdb7e457c548952ba0bf6795f03f6a6527f17eaf32bf3d9ad89e83636017bf0ed0cfd67a05d2b1208043d15b9665fcdbe328db6044896a5b3907b3d0e1ef201a1bb19a0aaa72bd821fb1c18970cce01c3491d98523d4542aa35626ad82659bb28bfa28d9e390f297844af4e59ae096dd815c218c692861697f2dcbeca7d8c83ae3c950eaa4ced2f48caceb70440bf3e4f86eb2ab165fa17da6085efa3bdc61c6b3bb18d73ad8f458e9d213e28bf5aab14e9f6cff77579a1650dae28628c0b7be93793545dd07aee51b00168a3c05bc5fee1596369348a629ccec737eef3c225342b4dbfdcaac120cae0e8c5f0642033bcfcb2028de2b80d67bab17bd51dfb2a178f04b7bde052bd744b55024420e6492fdbc4a148006034c2459d5160ca04169554c54316975b79b38288d9c63e710eef4cba58c0ab09c9749ddddba3251be144e5158f2358bfefadc5f7ff562ea30d4b037277a7f5b9a030ba008bfbf9bd2124af32a34cc77350443b6f7141ca9ee171bb823e628cfbbba2de5e1d1b9e50f130c957a196ed04c11e9e0fdd963d617bdb7fec8492ebc7d455976b64345610312f57b2feee896cec92d92b58ee12ffc39876eb29daf20f40781380f7ae7abad83d83ec281e66efba95a950a2e5c52d67d3e662752a88243b0e7cf75643018e40106b5aad05e7f8dd22dd4b805eae5e71d05d6cce4a088a15c0b9a1c328cdfd6180779f6946a210354ad1ed1dbcf7b3ae57ba7cca1fc8150f7652013b629fe1c283880bb0fa2927e536cdce9b1afe4b8e424d4085e14ed228651851d6de78335292245446da7cebcd5035675972089f09de217eda9ab2ffb576c119b2b7eb16e82c769dabfb20cc9afa68a5fe8afb3e14cbd1c005416e80e4d1aa19f5542bcde18cec713eff7e5b9e56a3c5e60d60a65d69f239cbf06b470b21a2bbf80b0d7385e05a9039c87ab351819bddf994a1451341d80b28255667bb81c81e256a953ef04bde07c70af0ec81a1d1e0f6eb6277c7545e4ed657645473faf687b3ce68e20c2b8978c3af708d7fe5259a18f6de1aac10e90d3438245101b59c255fbba5dc501628150b9544b8813531f9985f3bd257292f5af3593ece7d7880ea0497b7178197a508bbb4f457addbd2b71a279b2be590c6a759dd8c55d7fa067a92190361a11273bc427854b361b1a879f1c25dbf060fc0e06dfc29ad868d5ca0d28fe692481c6d91e348c95568d24e7a79ebf519384bcf5927e56714d2d5f7489fdbea3a603639ebca310b1b73d7793ab95c814e6258fc9881be08e4354a34a2e27883c3e456f3ef4975aee507e8ef482defda68808a0f986a358374cd5c9e81db9d63d9947946a6fc9455775be3ff3b83558b05b510b5e5dd27e7bde6e5261ca3b8a3ff40894bb319605e0bab4b8aeed369187f57800e1e2594f919f4342a6cf5bb840cf89ed7e5d5dd36147da784d13902d28ef0232edb9784d04be44a53bc494aa871db84e924fd4039fd5ee8248ba7a844444863675a75b79e244d79add2d4a962eb11f719e220a0c455e9b907643516113daefa7cae00ea9db88c5652a44da4b800fcee03c8ea3d28eb0b1a2013b0d2d269643ffbaca21a4932b586ca757c4e13f6caa4ec21e28660e5af0da47be1c0567830e05bed3a766d2acbcbb542a3160efd11f6fe96713dccc051c26e899fb52dbd85ea45c3e3fb103800b78eae72922fa20c59d26a350306372a6b2287f9c1832eedd7f9b8040731167079c54fa078673951a4e91621c86eaa134a138dabdbcc29ec82dd93209b61b4e42fe18f6be300feb3961ae7c9411d0bf2032fd2180805e0257abd902e7a9c0e14fc66a35e1fd552589d27db91ac0084851296a2b8b03e6dc0692c29167fad2f48ab2cccf2b0c094c1e0539f3a557a10aaa04159d3f5b196ffe66d6179f47196879e529cfee632bc5db9802dae023dc1bac545c7723856a14f774acdf367b3d91cab70b68e6e169ce0fec01b54e3b786de834ebf93bd950f465e4d24dde4d3248a929423fbaaefd08e4a0584dd21aa8b9bc024c6897026ec8bb5b8d247da79b20534d1c06481cb0108790b4be8207d0927599b87ac33c62e4577bde1eeb3d2bf2f6c0762d14ce04c554e5049c72dc4c06c181eda8c091774a4ff3a2408d84390a4972ef6a7b37812addf2970e7b860df384f7a52c584472f9004383409f40f366cda03fe32dddd46cd45db1697e69325a480f2fa6c5ff3f7bffd59dbab3748bc31f08c620a7cbee969065599601638cef30b6019173f8f4efe89ad50a187baddffeeffdec73def3dc2c2f145a5287ea0ab366e94bcaf75a3aac54057754597d72847aa88137a67e1faf9ca4ae9c4bbe867a18c1df37424a8a6e3710ead5c56ee8c58dabd79089b7967043e12d1d2290f5b4aaee90a5e70af19ca15ffef3e2a8620c62fa3ed2089d0f2f3e9f7a1a6982a726aa96afb1d7042b0ed957e05d0bf01824e32a372ca4f5b831676795b1e05bcb065670036c69ad116af665982b4bff6b8dad1a785cae32e4f26f54fc8213eb46f2bb16584a66c2ded60207a4e7bf080ea375167aef6c3ee7503c843e1e19d7fe637d0ad17598aa4446e54916610f7aa50c322aa764683aef7948a54ef81c9df6854d099820e2f385789d2d227ca7a869f9ded712b9ed650c754dde4e3cec22cdf1dc9e33daa8a3bd8fc29b1e94e1b89ded89e6471dddc900207dad0b9a1831d0f3ef795a26d7d81d65b073677b15b28006c5073d72af87273df91fcfa89257c3b9459d86f5755f8e37eaf7c648a5bf1f8e18a7e0c30c44fcf18e34bf592bdbe7fad60ef498250a41cef630b5a7d0727b63953abc5c46e9d16a659f5f530f1c116989e8f224ead44122d06dc29f99ed08b7b938aa6f83e488ba7a9b2c2dbdd3c280fc6136db1799d3e2fe0bf90bbf8a822ff2832ab374cdc2f120035c3192cf6bcf38797ae4eb88551e163c0b0f7aec090d5f88b6497d018471b84f9ddc2c7587b921656ba54b0c60abed5e2eecc5b0beb54ab854266af9e132ddbe2fdc9a5d87afba95bb606b29c2eeea2e5c2df44a6cf3d38af99cd1f0d95f730c631f268f1606017feb425577ccbbeb09f5b4bd038acfa64cb70e502beae5c4596f8e50ed425d1a83da6ecf73d8c109a8a73652995f81706632e177e86ee4ae88c74e4fc8845ea28a4e7753641fd1d454f65635abfc984d5796c8e94da0fbdcb07e6f8307540955bad906313a6c504d63b188d91a3ba0f778e76a2373386b5a1bf22db95f65b8e486edb443b122cb76b40dbe944acc1ee20af59261f74df653a836bb3690dcdb5d84166a064f51cfaa9f8b8f931b9b86700eab698a3a70323227d51b1bf19e683d27bc86214ced22a9093dfd2eba4d7664cc88d8c23d1493db807507d8e96076616ae78bdeb67b9423dd16f7585577513d25359368bdbbaad0eedf1f73774dfada5a2bc9393cf85dee0922aeb6c7e44dd15b193c3efedc35dfe27c9c8a37bc0678addeacf8b3d74085a836b72cb2b7b948b2c759efed4891d28ba1af05eb5df2126f447fbd99a487f6c2225b7e05b256298360c7e7f41bb484fa18612dee2f76f62c85fba492a06368e81cdfb960d45a7bc89dee91f47d5ad4a687fb46f1b8a7fbac38834f77365ede170ed5517ed5edb942dd15a6323144a2773a733e2c81d3287fa821cfcce0623ad815ee4a2ac39fd3235c38e5a23d24b51caa5cf36594adf943b62bdcc7c583f9a55f8857d9d962357e5362956e0c979e6e7b65b147c9dca4db7ee7768a0fd9b914ad4701f1d213eaae445d623f962f7a0935fd0afdf69ae60b79f4b5daf630933402fe038f40f0e019be79e217784031bb0f4c7d44b9f698aa642f581594adbd9ae9f64caee2f9e7302d879952187c7b23e77b50cb60f283ca846613d117903f56cd249ed7a3b35dad80ba1b0963a5b739e3a9907fe366bc6644cb2c19bda47a420c966ce29b25b42f59c6d3a62a4db4fe4029e921ebd540479f4fbc0d90465152d0d3bb86fea00e01d6dde5587a2b215491f3c08ba414f44b77989075fbe6ad7746b6eb5b9df80ebb64b15878a0246f2679f9e1059ac956ecc47373e8fe68f292bc2119144df64ac8c05b5fdbd254d2b6b94788af5b5e73bfc1926a655a60c03d23e77d9820f78cd944799f1e591b2b3205c45216d8f99859ca8419599ec28d55c259bfbcd35fc6d4601e9d7bc82acefe7067789f3e2f0a4fffeeeaab5733a8da4bfcedae4678e13c311ea0fcf86b81ea02de45d7dc5f2d766723cdb9c656199bc03dc83a266f7f4129f68693a1054a8025c4c3caca0e84f3c4bff467f484fbc1c12b9055938b001bcae81e21f0453e6d30a2d4ac3eed0ae72467693bb10c613b95b952b443fa353529dbecd8d7cb791587d93cd10a2599e5e22811ab23135c50fc416487fa9f81fe674ebf71ee53742c154f286dc54de3cbf91fc71a276223f16b13ce9bbe9aa1e32c0f9f235168c55bdf2b745a6717e2e0f960e130e8b28ebe7eb9bb137e9d7d8a365ff81cb454d45975f25477a37ba81040e3228f9544e2441b4107d3d5f9a98c1ee6904118d7ffd0f24e0f90e555e86ae5e5f3c4fcf072d00f6a7a8b0dc9571faa8c7a255666d181a1ede7c96cfdd273f3de6b500b6e2b93075b2887327065ad88f9b91f5119268af385f064781ea2250ffc434f0b0254f6a0a23a34e36d73ba6510082df299f5e0d7b10dbfb07042a249b7c16c15ca226c322fc0539ef8478f423cf1533c3cc59c6e9120c209fd142396a3a72c68f2b927abbe9057055572dcf1acfef98d1297279b40886d0af1c0b488c0f4685d153e295c3531f74851dda5ef3ca8ead18a33af926ef05321dd401e6bbfa7a55d218e44f7a2fa3e17d3741ea4185aacf907197cbfb2707565802bbb8c44ea994a4525be6e5fa0ecb0e1817f9f0b76762d853f56cef52d951f6ec9e31647df12797c6a7cb25e6021e50aff232e7d779fe3f393a19ea4ed3ab6c0a5cc5da2e354b84f9f76674a2b746c3bf4983846b93572915bdea246a689b7cc93e4e19a3e216243147933996e2474ea44ca7ed78256e83866f564bcec50dcb76674d8ede6090be0aee4f96425705c979315a5012bf7dc4bbdc13a4fb96afc06b37fc31b90de913fc1d0289c8802f52573b02225eb8d588f4ba5a4d67f77577cbc29379010d2f436cf5a6e781006625018476170959323b8727a17c6695114c890951f7adf75f90a181dbd4def675dbea4f61560870e15e8e8c9dfae78faa26225c151ce8b70c36ce83a676cd5f16d1eb4fe26ffbf235e5e21d4ba67a9a7879e820be59bbd87305f18ab0a976584f3a59b43611dcf3c884774a68c026ed6ce863960d79c6b69f666fdedba318ab298d6f645ac8a13627a9b2270df6008a89fac6b15bd109ce5e2182b21b6c807155946d270e49dacb36fb6c18cd0b407bd33bc31387346db650c3d3af99b2be2780755cc33c9208a7a762b2e8530938703613fc64bf0213aae976066c37132f671b61610a4fb2a26cf8a882e0f4f56467ff9f1e9517f83234e4f1680fdc7a787d163d61187a7d732692ceab99252af4467b1e692600c019a53a1503727674c8f657c0139a6e5834c57429dc8c7c749afeaa309cbcb16eaedb049787b46cbc8952d546190f585fb9187aef74d8d8a27cc1c0825d2217b0bfc70d786bf90763389fccf15678bab8848bf6211064704a757a39039c20e65ceb9f9412b2b120fa1daaefff049914b9d5d6739e7470ae22792970aefe7d7e1baf5c613998c048cf4cbb52812fa2826189cee069e94c3e8fb58f54c78ab32e4f8965e744c04154c89d154857206af181dd01307355784bf66eaab193966dd930cb516517c6c4f98658ba75eaba2cd6e2f9aa9f940ef01c17d5c0aae592251a91ecfcf288dc19cc1a5301a096230b34e12f032fbc1ecb946e7c98cb45dd07cc6be6fafe591bc71cd8d3c91f1e53c68293914cad283d35c3d66bff1a0a5d90843c251b6c13228108b6b0b046c46dcb715979e7d83aa3110fe42cd8f093e47124e6deca7eab158d4abcef2f1e1f6a356c24750023cd17cab604779acb2238ec247ceeb081661054930704ed933399a25b4e65133eb687d3d26c4449e4e50c927550af5066ba7c778da4362ef38c9329375d74955ebe42a44173a96116cc110635e6d0f33390102a11356e1e51921ded4a3d772564cda45825fb59bf186d082e6afaf73855b90c9f2b35411eb3ff011e490b877e38de9fa9da67a7f779e66f8a63f7fecb4aaefeb7e2418990f67c3c9ec0ac785e9db145bb208bf6fec2e1bdee6153e29e61cca0eb6488fe78d523562075c4b3ddd0d58468b193ce0a9b53bd036ec4c4b76b62e85a84bc285524abcbdb256a832d312060aa742895b5ff8d6ae332fd9d92211ad1d54428310de9a50855d0ea37ac2a1920de28bed7afff8a1076142a6c1d7e9c31c0bb44ce49f5a9fc7746f60cdf89985d4a6ee49e6c82de2b7cb0b496fce155016b46977f64380a6b3ae08dc53f576a86c4bbbedd3c7e129b509cf21965a6c1f92cda85e91803f3cd1b5ce214f052d4239425b9d025270f34338cac812657c70b70a4d249241e7097c1339e8164b2831731996990abe60c7add8535ac51359c093b73e45ba5792c10a9dac23dce7f38403c64aa8f72dc8c711657ea258abe8a4548ab737f232b3a90b0b580fedd9e21b1d4341cc7d97d600cf94a7fa59a8fee2cddd584cb37d864ef359a932adc7194d7639d59f52f170cd5feeb670cda88b3da7f7081694e81b2cc12bd582777dc91cfa847e7932c11247a8b710c3d29a84e4887d2c10d7bd73cff86b4cab4c88595d6636a06142cd3339d55b34144d9c73299a0b8ea9f1a86744a0550c9c2a6110cb01d90d63641a7c92e94b31355812b6c97c9b4897bbc63f3937e67028bfa6cb7f305bab5008fe3423d73eadba919cdd9891a7eb19b9f7b34b9a918b78463abfcdc8330a95ce2e70b82c79fbfbc30c0d84fb51672e7052eca0178cb4d2e09f2455ea005a234aceb6bf4e7063cef210d4c55a825ac6abfc8b73dbdea032862516ad6f53dc15ea893d985733f194a7873fed7175ff80df6f463fdac0c87c2c9f39601ec3375bda30a5772e5c63321d61bd956ef2dc6afbd815cafbf5534a2afd2989b8bc72feee3bf0ed173cad24ff85cf73448b70b9f76c36532e42fb7297582b622af93b82c9114222d72716340969759eda49baa9066d0005397d4969886760bc5b55d8ae35326f5b99a151aa7a422dacdc3071d41913f48edd3ae38f6c4c1e94a1b071b7f10717d30e48fcf97bf6531bc62740e05b6c9fb6d6ef503718d3706b23b954714b86b984e9edd5582e69218e248ae9763377d9a1b01b32fc30efff6942a727f9c27ed915daf297558b64d041c25bb9e1e3eb2a25412d24a050214a1efa931ab99857d21ce0fbc554e64ed12c11ca4c920e259b6c2593b12f2dfe4d9370384e34b2a7bd8f3d1a3da07955c32ddc255e470cc7e71b0fe9f288339dfadae2df77a987e826f406fb59b97ac61d3f437f9b7e46e5d6337adc2638b65b5bf38c55a263a652cbda72dcba2bfcf15df16211032da56e9868e28ec626724a18df833610ec8bcc5106e39d395b2dd91c9e6b0cb5267392fb8f6bc782ed9e6ab7d51b0fef079cd0f040efdb9c299e44375f415de40cbcd11492403dc139f6d587ac42d1a27b91e379783d1f8b00c91eca1c928b94cac5100aa4239c9d157296da5f88b0490122ec50fb5584d52989ca1225e04652424c4db1e7f9e8db99c4aac54f116cd13d835d814b4fd44b566af5cca872965f90f5864aba485da1dcc66dedfc17b79ba717dc9c232b15a80f465f267f9a5ac933c6b3bbc265386e7f99c3b469be5fdd6b7c5619640c009ed465a66ec1f739a2fd76a2b1e93ce4cbf086018cacf80a5704079564852d20b65274b286959e4b3cd56a897d08365eb506c83c4ea98ae47ac4dba2cd0a2ecce1d68c463598a97acd4ec53f38e9b255ab634a22936b2739586fdeb9c0f32bddb1c621d929e2d5028a2656ac44c1d75ad9bee9f1cbe4f583fc8dcc1f55ec696dfc7075b99dede88bebc471c3588d5cb2a36ab2f4c3bd669cb60ccbc5f533155d6f3e11cdcd8a898ea080a09f53a37aa29efdb892be91c6a312f75f4fb80b352d71e8aec211f834c2884bd2ccdb592a8093b301cc22535c60f5bc14181f007ab3c1177df47e000f2112febcfa5cc5da15939e0c76602ad93e226a013bfc8083fb476d4a7f219c7bc2b1e3a3de7e186934b492a7f2746aac3680c1b945c378437f551bf45d7bce9e3ed05ff7cd64585ee72edf26e23177d3b3c400bc6f4813a2a5d203ff947dc12b15e9b2e11dbefbc63b17f99d2ff9bf796ad49c7e9e09a6d906913c70803374859d6b1e7e6d30832ee2366aa9c1e31a4047524b0695eb738eb04bdf285672895cec40d4e5038dff96acb11e13ac78457ea5da63c2abba40158722b9c9167274809d420449af212a03dfad07902079f2db224b3a84aee0504133b590e1853f38cfe55dbbc2fe6af023f9cefe1f6ee908e76d0c12c549901d889d7ad6273232f7fd13a87ad0181105406e6b3b6c337bc02952b3f893a0a96f6e610f74cf1c9f8d93d1a5b40af44c2224a3bab57ade45f23e44aae307e9bbe3b6f45ce1f53509b243a10a2a0ccca52820406469abe89a9114ee237fec8f2b4224569570cc2a3b302d577aae0e4adfbe4c78abe41bf66134eeeadf368c11af637a77f11936e02e5353cef1ce2cf4b0790f546e24f70305c1dfbdf412a1170760c842f29dfbbbab2f70859ad9ab7ff57547f27ef2a835c8ad1c177e99544e886a2c77c7bd75631e381f8df97ff883698ea882b5c9ff7f1f7e4cd7eee1dbc06fec15377f2d4ad05d8be603ea507c076256dde8c773f890e502baea7efbc0a64c814687d35f45b03caaec40a89d9ade63130f847aefc7e8d7a234f581474dceb32076d621cc80148876a3a67906d1fac27ecabbf14ecfc918743f99b05e89f7e0e28972c03eb4e5e6925f42798b728a9797037c1dbad139319e3b99c5c617c237299c45401bf61c8e990ebec0155ec54e247e420b4f56257bbbfd620e5ecc4698a4f5947591e8275c663e3bd0ded03d7a64d34ce587b95628f3b273ccac568e67d888526ed4c106952249e0ada4087743c294ee5587385ad35de884ea4c51d3013eea09606d6806f0f7905ef00a4a7bcb24ec3b2cd06cca450cb83af606099d6ba0d8c90f64bf242fd87159a8c4052e4affc31131011f4687d9d9f83a90838516fc05236d53ebe78fe8439c26c1e21aefc9637aa5d9a85fdea2142c31a16fb20b914fd3695f9910c29dc91b23a55e50d67e00a737f590e92d087652b015f21f87a810e450e8706896fd00caa0e2b02ec5455971728efc9787f49a192743df35a084c4b13a9dd2126585bfd754397573932bdc9952090c8d3ebbb9f999f0762e8eb106a2c70dcc050e36409f3b803f47b8497dc517a2657877afd60da3de893720bd04cd154d5ce109a772b7ba4be70dd0757737470679dac39d1999be109fc18d17ee7344376781aa782e416687371b3a897944df15bf949e44d190ed6e0f997735645332b03f69c816aa747bc8bcab219b989b5ce16ed42c1d4a1bb80867bd0bdedffcf10ce1fa09071b436422cd24ef6fdfba0a18d2a982e607ad93ecab22f530d13bacac06380c49cc9b4d27fdb5eaf1edc6e7a8c7e911ace171d7a9b10454c68c3917425e2767c51055872947cc027c99d4acf726ed8e09a1f485005d4226bd77513db86ce0bfbe10fea4cc6fcd018b50f75387d0400f62c6db1fa894ec884a695984c60ad88d7320dca45a48a63e20f88a7e59b8341caa7d658712406fad83d0ec5551083756fc7ed43767ff16bd8f2da35f548ad2ffb04aa1c2c33f56d6c0e1653f203ff576b705d7a3ea086765fdff6b2f468a19778d0015b436a606423d9ee5cfb69eb3918d046bee40b8cd7200a1b7a1f9da3ddc673f855d9367c2a543605e296ef649e1f0af8ae091a59412eaa1f668b24fd573fe9e2578780f7da17e1f6b7e6ff4df199d795f3ff21e1c40eb4824e170fcc086ff817784564c1704a6f150360284227de13d63c7a4affddcc15d90542477b1221908fbe9d84c09d98ebb3bc78c519490f19cb5c573281b486d34a1c56285c53e14474a9353ed129299fd11a3e8274152308f25e71ff6008a70965a9ca90f7808c760809f74c953942b535acc4e72e5bb6fd43273f0a715e5025c2c2317296df47a0babcfe9b0d4752b0a25f5515dc25976b33e559774a8162e915be5a883de80ad27a594a1407431673f22dec5eed87869b7b6252b6a45cf8b3c69490ed58d6e0aeec81e4817ba4b9f5c84800fef4a7a3bb037ca34b103082e98700dbaa2473a45487dd3d9de9b8366ca6d2cfa7a142c081a65c8ff23e2b8c1ae07a03ce71a98d39022a455a895b546a0b63f6aa1e2b32f5c7b4c4894bb09c2d9b90c7b25336827eb8aaa24a7da458a7129b99d38d176b22f21dd1cb9264ed5e026e84bcef225fb299c9375e2ecdf63894ca5a75329fead050392d49d3a2a247670ef73b62f9c9275e17bcf2505cff88295dc12d33e495e3f2ddc06b69e55b3504c3b6110d51b6145cd6580ab9f68fb6b58a562daa1734e3f04d5ed071075671912caa5601b47cff74d53eb573bd012bd6507c259588b552cbf07c2b99f5314bbcf7ded08e16c8865f2a9487f3e76dc47866c12a3d4353a5691b3740e671baedcf299571031a55cfe76feaa935ae204bf4a7a6eaa82dc914d9021dd6925eb24208e72e6df9ee7da88314fd206a65d036abfdbd25ff54c75c297327a3dad8fad69798889c21308bfb5b216ffe4fb9d99ca73094ac8c00392e1aee8187969057372373694871ebbd07bbb5feb05dc82b9147bb7f390761da87be313d29bce50b8cd510b9b0ed234a24d67d2c31c0a6f6d3b535940b1fc336887a9e00d1b67b7cc7b45e67d40e6bdf08d794f3c6c6eb5746ddd6b996794d9b4293fb5b25d3193076bf117bb5ee33eb6082e9cee650bd5deb60da04fbd159abc63ed9bd80177b070b6f4f3bd609bfdd07e3729aeb650af1715ef93e3680bf4c527bbf191f5339227efdbde7688f7b696b09faa6eec9100774c35e992d8587feacde05f759614b9df39339ccd1dbad2679be7caf8a3de177d6441f2c8104543cdc907e4eb21226ff5811121cead173fdb115f049441b95a9e257ffeb0ab6992af7e7b5dfd4dc6bcf9364f7ae273678dffd275f011cf94d3e26fad2957b8ed88cc234a7c3955d2a1812b537bd34c3c57f80b27eac486aa3a7f6b50ff4bef4b6c7a17bcefc9bad16b05adb4bb05198267164c07146b4356dce5e698bd1885ea4753b70e613888d156f47d159289bd336907ce854cc50f429e9817a2d7536f5ca2c3bdfac42784aeae3ef1e938bbad8c2dc1a5f0d98ff635bb218f9c97abd7b3d7abd52918fb516cd8c025436f63a9bca01497cf22082408f5a766f6aafcdb2e3a234eaa9532fba7d9a169918b89e4122abc43cf401bc86a22e4973f7ad0db752edaaebfdbc0d009427ad44e81b994df798698a6a97dc223d1df9174b851fb2410dec5424c73224bb744ff8025fffc894c1bda7c62f6a6967e9359157c42538690eeb4e6df09111c9f1245d0a06225a29e40d1b839387546c418e486f833d57f46924a587eb8f7e6a1ae501f804404ac32d35320e267724e6a9807b849e4b2db5f688abca1696ffa7ef32c6679584fa615ef4b29a750b4ae1a359a0607591c31ac9197fb950fe5d67d2d611f643597fa880d16243891a6f888f1cd37395df9b8a237e132e95e78fb4d7ebe0fafe03552fb810be623f536439fcddfbf9d7584f348a228ec90dcc8b449d4348085c5af87469b44d6ec1104f3c810583dc2af4cf3e98bc42544c9051954f95e8a17cf15a283335e1e7f2ca61bd4ff2fe010659bed6543319b1bcd64c84817a84f3f26c5b2dd10f6c26dfed5e63338505baca3708cf49520343bc473cb12d49c9c43cb9cb53b762f5056c4cb0294843edcec819e7a443de85a7c5d582699df9c801c9706c51322a827263019a7f50bda278a75cf47abb48374851d3256e4dbedd8add441e6f3376e2785a9259c9a9c3175e294280eb1961e66f4aa6fc4083991ce72dccc2abdca2993a3dfa04af0cc5bd52d5d920cb5bbff3b186a99819703d45ea5a55fb255dac4ee3114f7832769c20626ac594c1f955366fe1c8fbc496a8b41746b5cc2ed5b2becc1e056e8970a2d33fba639bc4b8190de3d70e37e6fa50c1e4b6ea542bfd4ccda429e97190a5543bdc05cdebad9c87a91fca0cd42f77b5ece806d2e86340c2dda965d233bde1278ce2a46880a453d861016ed69f260830f6600f9ec0257139c51148eeca689fc887705bb02f307cc124d8a8e77c23ce60313b105b50e0df96e9c3e5cd29ab4baa83ced3294d9e130e889ba882454b098a40f173ad996b8dc3514607c7f70a6ddc554370b13029938301fc60e6de423faf93e301858f515e244d617db3b56edf60e720951ed306524946223a1ffdd01265c0676fef3e8425d3f6ba7c8bfb9970d3b1196056342e72bb13defe48e5480d6e4d9f42eb1f676cc10784235001ced8c9e4d57ea459cef98fed6624bd596c0e94e6a322590b9f92c821c0c83b77789e8dbf239feff81b7b0c41cf0847a99b12f3731c8ae502fa722ab9bf457ddd5988fbf0e5afdfbd228f1981333c7a79a164105ef1d2c48c555275608d38f123e7f5ed0201e7a7590f397c4a345eb946a46b873fc0d7214c55735b9fb8a5e4d77c225d59e70ebcc6f7f21fea2b55cc83da4f09064b3da4908a596c5fb9b36117250d75b75fcf51b17fdbdf64c326ee84fb1947245c556a96ffa9e81eafec230e9e1af7f5ab15a81bffe8c96b75d50d3737c0195d37dc10eff02333f71b93e3bff44eb9fdabaaaa96399230d7f595203d3ee5f7c5955889e07c496ba5f2d6feadc1457520bb939a71fbf017ec937b3e9c828da150226ce92893d2f981edc158bcff4c3ebdc1a31a73512de9abe701e56ecc8e809f504bd2eb8b5d01124066ae1a63a40f187fad1fed1fb400408005b6daac9b64500566f7d29256e375412e71137d2f8dd854122fe2161447c75135b4d0b82c1d7ba40720b2241b8b6a86caf4ca4023654821fd6feedb5b30195c94fdcdb4cdcfac327e3b15af83a33ad3a5e619a0bc7d890b2ee58c9bffae4aefee4b61b7fb236618cedf1ddb44d3a378cb69db63ac86d601f64e139e531bb6e32ba9824d3ae9bbd369a1de110e7a022cb18fe563609a978ff4ca6bd1c3f4213ec5b838ae6d838abad922e9d75e9b7cf530d69262c5b458d9b77dffade40380b75cc5bff517f8a2fbc872308e0c94e79ad8354923819d423d2560394ce799a02af36a669da9e0098d306d2f042f775eae45ef609e0f6d5c0b10c39e228b7508d650e07472e13f240e5206f5967e2928422026536abe9218331b9eabbb53b2db30eb2de83bb37c46172f7e6ad90ddb97da099397726c8f3df06d8f081ea77410ae067c8b1fcf8c809f3fddc9a49533754c674255129a075464aa343d06b6c7ca0d4f1909154b5c03cbbe304fc2a27809fee29c3bfacdfa924c97b2deab201828929e514ad1863ca846f65fe5b9800d2cafc7e5f352477f873ced39f7f687b8709fb2b93045fbc49683bf6b1e14e9a3f276bd6d4167be35bc23c472ed65b629ece1bac9a4e80f32ce279f49b259ab3419d2ef1fd4578c75a7e500277e9b7f73958796e1ab94cfefa8333121bf4685593fcc2bbf88bddbcfdebdb4ff9ed2b73d8da27a82c1beb080462803e77e0fc5cd1d5c3fb73c3d612652d4929f46b20aa01a0cdd78ab5a2b4e7e17d3610af2e122e13e34d297135b80b8315e7a74c813c6b1d379499a436f2c07cdba12996b0a105ef8de501a45e4195e3869419a0759ba8be8bd3a4d57e66bed313df0004b2fa580d92a997d0415179b435e64bb38ec8d927392da56c0623472e7299083f145de351759e560f86794e3d45d70b45bf73151569fa8fb54f900a6adba91c260836a3b8ba27dc85cc5d371256b991a1f09ef7971f4c9af95d6cd264bc1828fa68c861684d72165f20eacd19848a0f057e45a2682f4bb5c86ab16756a668ead0a3a427a492579017ef477ab2d1f57f3ff53feb04bdd94826c8cb22d62f481b3fffa097f8e38e162c87fe9de7090874f6b2c1591dcbc215bf371c35ee6c6b6b136b67d5cb3cd1117acec3dada60ff6f15a76c63206258c0b651937b04f2bce303badc16f62b1de9e3859cf2230fd66e4ce9c4635544158d1ed983f07d749fd0cd1345c8afb3d6c39b1fdfae1a4b285a2345f1c6a3142a6c3e7cbbac6d4670ab84d8ab6c5d0a556bbec7d78544b7e214cdab6de8d5446bb2b5be3d60e100e2997a8219e4ec5c09b154d9b214cea959ba8f693fc628ae8b5cbb1c43bd0cddeaf19532c02e14b2577e3addc7a3c8d76387f2c0dcc7f3484bbc7bff32d236b0ebe747cd6c4fd82f95f096d4068fcc65fcb3947c5c2990283d1832a229d8584b28060211e864ca14df19ab6e9cc60a6dba57abb0a838c515622298ba819e94f3d7b32966a048f3145de0aeede6b1509df91313432cefa2c739c23e58553cb7bb0466a184f9b57fa48f00033549d60257c5e9ae19dc70e3c200172e71e1c605586b86a80b331bd4a479e2824a07750a1434528be878c987c34e69edf96822a96cb4b6b4d1aa17f4857365737c3c33e182815587fab6c2d9aee595a5a5c041b2ab848bc0b58aa6c060197872502fb546be7ec99d1424fd1af848501546c9c499253c498512992a1769e8684d6a7b0633d3904179eb36057554fa0b83ad8f0ecafa5afd9ff5307e7dcac2dd4b64a5a5e685fe7ba08c057b614d20a9ba352dfffdd7f593a177a4fa16bfddac2ef0ddf3dcb8e6e3df237c83b75433b90417cbf82db1bcd55b83f10c734e16d5c68bfa38c0eb39d8e26f60eba32bc9fcf72b4888739f66d0059d9b27e17b921d4c0a5688dfb4981047b97a4b4c1ee34d2c3f917bc2ca6cd1051b5cb43537ed6edd94563aedd0de6159e7a7a086e58a1105f0dffb03d290472860d51ae36fb0c5d7b676c4bca5560af5ea6bf4f204fcd15fcf95f7bfdd45db75008bd8d19d5bb34eac435e9e215510f61b14d17f7495e8941e7e6c4ee5ac0337b145f9ad4e0518f4a88dda8a02ec418e703baaa4f6acc7ed61c19560fc0f42aca47e19ee7abacf179d31cdb488aba854e73d9c7476d65a1cf0f13cdc6d3a24830f13c8e0728192a6d56b9dbea0b7208794bffcd29b51f3ad4464bdf65181f849d5d41280960dae0bf75cd36c479bdc499640ec75a63f9dc2b409e060758ad45942f990ce919b7eabd60481adbe8a2818492e4bd1a94cf52bf89478f1569f528082fc0062ac60542cca4c2c04cfbd773811d029272b74d9db7cd2d4e78f6a31a1bbbfd81d4417b6f48547f6ede359c26388045d1008fbc3ecf633906f749723ad69bd52e73a62244f9c4f3cd55b49d05671c6291d6f30e5f1794c10f6c165aa5fa85b90fa86689ba9d0670f0b47b06e607b59e2cd3ab544135a9dd93dc25d730164682a43a869cf64e9a817be2fea9b90d2bbf5b4b269b7a6ea8de2758242370f7304ff821a0d1862316399076bd0fda86e2528fd5de1b8bc0bf306dcbca30ebd31abaaf757c35efa6e743ddc850b520006d7f9bfbf71269e2c634f9d26e89a2dc21efef92b5693853fa3ca4c8f21767f7faf9881749c700267aaa0902401d3be3cd299cb1384cf97de84de2f4b188d19280dc52fbdafbf96b4607a6f1d72fa7d07417d4c7ba1fa3a7cb1587345ebb9fa4942efcca54431ca17647646829272084e8cdb5ba39a5400ebc6488f3c848a9fc3bee957697b795ba919d42a10deaa88f0b6e2525e3dc6c4f68b664cf6a8305882c7b5f8a937808d44658dde0c3c0869560eb593a0c8498b8707160f5e423c14e03d699dd9e2ce7c1154125fdd41f1b9616394e0bc523bab0a77cf6788dd82f5517560968f1f85cd8126f9b3b7d12fdb89f54928e91b594495b4a33cc0cb3c964ca63545e55094507667f0edf8a83841c0360fdbb1ef9bb8a5701ff9802b84ff68ae77b586bd2335e92ccfeaf6434cfb7920067d46e9fed5f38eb8253a1d3ffdfb9b34ee8a86fb32297e9d158893ca538841c962d0c8c5b9918b2fb47ba1648ef0501ef3967c067ca2f51c896757d84fe50591a775cf07fd2e77ce864468b0903c99fd46c654267085bd90990c8d4d469668f95a3959c67a1e36be6ecc1c6c06fe85eb5f6cda66027942edd41691a3ad5c034c5dc36af5ab88a7f4433222b8ab27089ef673753beeed0c82c07450df697ee34e7b931a7e6a66348ab63411ecf02335a4753441b1aab1bd22b46567d9caba622edfb3817817bcb20366db8c2517419ced864421534b64560c82fdfa761da91d20fe3811635520ec60452459a1ac8395a02e0d4a9a7d3ba87adbd26ab22bd4cccab16b23437fed4772ec59ce81f6332ae821fce994190e66f15e2ebc29fd5005b5612d334f4139fba930897f3bc27d46c47d89cac728635a7a4bfcc88776e21798ea1921c31f0f4e97faca4a8ad3455a9c5ef92d6b28fb31d9d3d10979122f32dc27fd95b3f68e9a9aabca6de727f1e2796e9ee85b1e04606b1d1297e4c9545f562cad8d57f3634afef660061c09e618b79b638222ea4022395180c405658ca7b990bd90505dcfbcdd7dbfdbaa37d8bae10f634fd944127fc6c74037f23c5b50f0e48e15f4b9057f0e9d63e8c4486ef11fbf026dc22fcf3890457b628b4b9b07f98d4d21202bbadb1536b79cdf246105157a8eb3935cd7a17524080aaa2606e34cd209c99e45bf814a61f8ec3c41209c8a82935e657d71e79f52d3f9c8dc5853cc6abaad4c93c65931a5129cd02b3966b75fd2733814ea2bf71851f9e59feecf446a9497b9c6cd09715255b8727ef297db3bb5a4a178f00a24ddbc5e664c9ade9094bc870b53dc7b7995dcb4026df8cd59e3c3f67c0086630fbeb103f172b510e3ffbc4b1e23dbc836eecc7151461dabbeb424a2c1aeb0a77ebab522a39dc8b90baa0aba5cd3dc9e7106c4a56227e9820be097f18b58f09db16199b3291ebdc25975e3dc689d54b3f4392c7857b8ed634ea5a00eca2585e4efb59aba3e7ec7be25e7cab7a43612f4cfdfb9fe915099f620a9f7484975dbc4a73007fc8ac1956360645054ca5f20e1cc9b036fef4f3ad99eb0578af7842bc55538e087434e3526e768925296408612f9260e3dca85515b90b27101c82a0d49076aac3998a13e0ad51c0950c6b74514aa81705fc1bbc35fd10057f12cfe0a9ff875cfca7039f6e20a1169d2cf25f6feaa61144e561e036b60c2033baa19cad35ded960f56ad9cea1c5b32acc71bbed32d245bbf820bae3c98ad952276e6d998ebb96c6df86dde31edd1cddd0aecb21243f5f4559f429d6c7360ba2586a4cffbd45d1bf84667898b8642ed6c7320bf0561d35abea5eeab2976c71612172ea550b3a639b2dc197ee29d4cddbb30f974ab5d7ca59ee615db1c99eff0b21bbe33cf6f8b98fc2271d550d8394b1ff084f770469ac55c56e0cda130a0aac9256537f7e126b92a223353ebd50fc1845bb18eeedfc63a3a423d96179689c7ab9706f412373b10f6c37c297f8a6fa46e0c92370e85fb9829c838c2a192d113e607b721ecf59ed55e254bce0205e687447b60d6e8115df979c2df88a830c795fcaa079a56c3223b45c97bc7c56f1a87dfef3186d004ac8f5ee54b7f4e093aee1cabeb93e4f1a1ce40ee0c57bbd16a660369865e2679100555372506fd75845f68e2430c87fdc6fb16c27137df4338146df60af2f4730887fed9cbb82ccd3c3ed78f2ad6f4856f6dd5cd18c195ffdc7e1891d26c059c7009ffb90b29eecc6499250ef3af2f5fb0e3c76cacc16109049b62be59674f39cd43649b06264038a7aa114198f4f3dfb82476c4fc959f1fe3d141f68f7ff42256ca8b847fad73008cfabbf73e27f7016ebe7145802b6a3f850c60b59b6fcfa90d3422c30d6f8257b1b39b18a7325c7aeb8227c2196bbf1f0013633dae95c706e9302b1de5bea1c2d881ab1a232cf95c025875c94cf7274af6f5aaa682650609037786f77b0b21d8626fdf81f324a17804275331995bf5d7ed443376cd3e9133decf83dbbe0cfa0db9c3d162fa28ea72f86342fdf44ae43f56a12c9679c3bec76eb17f849ec24dcfef93d18faf3dd78b3265d994501fff3cf6d1ff21c481282f4fbd967e5657a805275cb356d73a2e2da8b1159af2dd0abcd9ad728932fc669230e6ad35cd06e8c187316b7c250566e53aa19c7d66fdab22ca396b6063463cd84764d9a77c437548c083d49d810739c2b9370ea9b3166efed3da899752c34b208543e6459f1c133da83e764cad69868186478d658634df6f3cad392caaaa17f3b4eefe1d3cad74f80230fd69cf9e99bd562b9c2ff33ba66f3d3f60bb3db0a9550ed35cad85309e08538abfae52af2086c7ab16aa619a88d5b4a0a7cc50a84dd37c83215e2d7be906ea51038dc4b41a0875b0cd771e39f030e30983d910ffaecff40dfe45855692c73b2d564ab779bc6f13c01711614c873cf33f8b47aef6105c556949d0e2ab8644f652a73afb471a664f38393b53f9a704db74f2f9f53bb1f6481264f0cdf484530eb814fb29243f0c7388de568feb2fa8dec265afcb1898ed2b1c2d0420010b44105274ef6981989277261aa387291401662917ad0c690bea15fe886b8a724e25bb1031434996c0b1d659e81dc07ed8697dce7dd81f59272c3c679399c004b512c18afdeb486c546f200416f0cd3ec1db814286646ce85dcc3ec8d94b52633425691a8982b1f6cba46d5838ed2f284444435ef06f2995f6d328c9b5da00531ed5c27137fb24d040f8930f6deb3d6f90b11a4cb9e451e8e1218431bc70f10ba6b06597b77a6763ac379e247537359621c9be0efbca38c6ec526758e28000aab7a595240634851090f5679ff0d550b1992523e2376592826fb449de8034a01e3539d99cf1e40ff1102d6bade5029c9bfcd5de7e46f2a2bf69a4bf9e66c276a16e9eec08d5504782fb27ea49204e8997c9480697ed50a2a0666d39956d972377db0bbf48c74e3d61db40559f9031eefa6a4f789cf29e8131ed9da9ea8afdae62fb61b194f10fdd7df124d8bc459340b826de7d35a02892c00837030c58e510c85bf7b249fd9c0765acf8b8b9fc42ef2a909e3987ff33184f81c18758e47a27c10510472e7b07456b0cf3bcb5e524e4ea136ad83ec28549fd686fe252e68f5a1eeb693fa5042af55868d2a2696cb8521106468572823cf5dc26aef741fbd91176cf8153ac8a4b3a1eca13d28e3767e662eaa63e3f35d90e3d60c74d2834f646e8ab8a79dd53cec9ca6d1148ab2ca85ed19d9628cfd369a2464f6d0789b54709a015b041954533b5648b28783f635d6134e255382297c6c2d4f66dc11f64f8e39d1061b94d22518a59b2458be366c95856176581858b91fe612dcdecdba379227090bd90fb5e22fcf03ee5d4af4352bf1641668b3936ffe5acdb503ba064f30fd99ef0daf547432ae0687be7d2a7712cbf12c17889f03a9f7957fffa7affddca553f58b9d89406078c06f3ce1e11e0ee337d5d34f18f1c40998d6861ac5405585d5222837d3b357df6e006b9b452b62dc7ceb9891ed50b7a76af0139f5a536529d0df6c53e97831e3789ac819452c24cd86399019c7690237fb8f3942127b9ff1a239fb7b2f6f01da478f86ee112f0da2e6883586f5030d6b90294b793e785f5a7daaa57e6ef520ad73ab6e2b4884a0bde6f7222226d0e112a8a912c4e89598b18db76443371247708e4e764ed399bac97507f63c36865a088736ac5bde74c6c47386d43d170656d0fdc3510b7c01e6d96c925f87e929f7fa1d84dc843d40f917033e9683b6526178cd99d42c1603d44bdd7b134084ff0acaefe4b499d2f89ff96100549dbd4753ed84aac22f5b6447651e784c08f97df5b9c0e1f659a9e144ace8ee48c77c4e90c2ab5dc7b50b50966e3143f6875973e124a9e7ba029e29e91c93592b4e888434e8d21f12fe0f8e0ba45dea408c69ee22b19a8f2a4d574eb9e7c2e43e26d1a1ec9bc22ea5131bc78e69843c12307ea8fba58c4d4aa4ef24c0fe8ac189462d80bd703a4ad9c818fd9f069c353b8e4d3791fdbecd5dddb01a6039f3e5cddbde6d3203b18547cf35ec243ea02653ad0e7f4e9d555c342aed4b0866bf3f491037c5eff4cbff8637187182aeaa126eefb6c5050f533be4fff49dfb7472791c4ba3451ee6b98a360f94872af1ea24b5d613321b7515d39be04d00a624f1d54e2852902659c784b2e366dfd540989c9260bd3642be7542b34c35a7ea2150073ec3e37c98b5db8276e85d3f2b7a3bf78999d3d889b815be6926e663ffa8bb729d9240fbb90ddf8340a185d907e7bfb842b44fff3ea7849bedd3aee601bf176ab1b9aec1e62e5b4fc2585a1a4f210465e618990c51c98a35e06d8d4c8d5c5696f7c1911a24d24012b3ec49a7d45751f05e2915fbaff24b7fb41c255de6fc0af7069a3b6741b5b0d192ac1a3b97f20c4e79cfc412bdbc27e83db4e94f0d041ccb15b20f3d47f4adeb6a4db36f68c06cc5f0728c992e6d8648e064ca93a42bb5de4edd04b83377f8c26b668224c375165bc133f60e267392cac2ed68e9ffd0ecfd6e63d79e52630add2c90b1883ce80a183577de7ec70cb7cc0a00dda19135fa4c68adb59262f59252eb1c78a89f80a50125b75a63dc97f6a616d8f650125188eede48ba55f73fd4ebd7ac295c54f72b7ac25e04b2cadd5a6698cf173fb565fe53955f8ea4168fa23cb0ca7f6c9ae2cffe519ccf043e3709e3c5d4dd404bc3c27136e67ec23de6a91723b2f6eba9dff1d7bf2f6cc5b5a89f5d66a5da13e7e86120a7b97fbe49228b6cd7231c0c09c9a23a980c91f7811e4db668118c2869c42eaccd51ea966929696e8add2c7c7b27c0b296f0a37edc008906961bb2187f1528610af451a1b7a85b5c41738994f466aa367924e254f881eabafd00ab0c5bb422dee57d00e2a56f2711515b30fa3d631a69a2a59f40dc3d29f2e3ff2e5ac8d748f4c1557ebc02c21c4cfe8359b74191d21d13cadc06ee4928cf4cf345c3f5d01db164e7bbab36283f9dfe6a26642f81ddebeb59df1f10be74be60177ea161282432d648eeb2ded1b8c597f8f85865ac8854faa3739dbde909a4bff7fa91391ec27fdf82ac904f1b04afc7f7d47864d0da0e4dd3dd57bda4ad048215540042b983c019b9037b30402e186089381dfbe558777d5ad1384ee15c411dd78ee8da4b04b3237e734bdba95ed092b20185d81c22e6a2479826176db0f33ee283f5de4a66de4b67078e482f35db6a38deb4d9d7dc7bc199adf789c18f097f9f38c95fd144e496d48e8b8656d37390fa39774beb2e356c8777127468c6730d5d8180df185c0ce753dd813e332b3b618be6503f12a328b541c6e844d992bc582402c8f4b4c15c852643af2b393ab9154cedd0c7597f324f97a136446b4f23d2d1a6af2b0c2022b40c567ec8f964aadf72551c83bed6ac64ae6588433e6728662cc5e98d9325dc9fc449b932a25fc44c4f0e83796d10bd10b66c08ef3b961add2bc01e1fae80dec99bed46daf3396a9c8df616a0d20291cb7b0bce1f7107e03f42c451266fd059b4d4ccf3a2025a8b9b30a864fc816ea11fb7f9311323623641ca2bbf388ebc1bea7ff176eed69379c23b107ec873d0eec3b6ea466195374c17b9c96520d99a75f96604cdb2d178a1ac385a2da046e79b5099cdd0b80cd566f1978140735eca1d527ad4d9083c9a35c698fc8fa61f12209f5c7effcbbbd9b09b0fdfc5b62d3564fc505fd05b2add778d46be4750381d99d63907abb47564de1b7f7c6c4d9646fac23e0dc4941df11f6404fba93441412727428d42bae1da6c5aebb9325a2a8b813790cfda0708ea33e73a9778506136d7099aa61e9c66f47a8afa8050205392715390cfcf6f96cc70a49e82782770d13654aca43f5668277a96f531f3fc4ee40bbea8efc3876b7fa0fd658dc73aeeae6f0af06e9b6572dfce3205dfe21ddc0ed20dd5004273b1ff0cb018442c9128d84c7a84eca0b092ffb63b1fe9636b32eb1cb08906b9533a5e4beb98cf43af5889f7add0414245c70c2cbac49cbb3b644a570cc0d5ce6b777499ffb5eb2cf9db6ce59ca1a5d671868580a9ba957b8163355929ac3c3985dfb243d5c116c9af55154a1ba475422e47f9ff36bce9b46fd9ffffe002dc77ac2ad5879f8d84c208af3579556b06f81975a423d4eeff07f4f384fbbce3f0532f584f35a7afc09bad4bb862e5de6f69fb2bd7de1ade4eafe3613d58359b76e28eb767c8dc153263f28106e1b397d7f480b6fa35125d4c7eeee765eb8378b78358831730caefa1c20cb84295a59f3725466b6672231c1a590aef617643bc23fc8cef72b0b575776f490aee4bc8370e506bab281b05547b0ef77ac4227316caa21e7130bf8f503ce27b83db772c334185403a53b439c2698a3f4e9c5b06a90c982e82748cde394948b15a1bf4a6a8c186d370386f04e8e5e452de489808a622f114b0fe5145b56e73023d56229b7c8969832d9c20addb997b566fa86cd846f584e12375c12494d851728bf40a576778c4e25f55d1de412c9285e05b559baa71567ad10a9f481d73a7ced7d2e45c9f9480f11038770cf4f783ab2a5862882d3d831c40774aa5d28bead39b38e2d807076a790165d4e969c82382a01351e9386e52d60bcdb13a4b93ccd3ba06e0054c05e53c6897a5e62a96ef8eaf312cc67078726ff8eafae2e080a0beec93ae1c782f13c4150ccac803779217bef085e982ce1efac8784c28d590f5da15e2a4c0598e43ba417e3985582e9500b8459011b6d8ae3d07ef985dd30bada79a16ec38385072643f550868c0cc049a89eea39c568173adfd6fa9ceea25c5e8f7dc56a734ead11124600166440714b82496ca9b4927eaafd72b1ff3f325ed44f7f0ffc8cae1d4931b5c08555afd2b1a96c04df033f0babce355597b288c00fb1ebd83579f16e431e2f9e312314294208fc4ce2f0cf208ef924824267fa6f4bf8964a058eaa51798cbd447d0ca204d4f79b926bf47f838d20407bc9366a4159eac915b18d1f252a6ea47e8e926de6b94ec7402b6a6d8cc150a87617227e2285f35af46e8688822bd286a7bb7450e836eeb18a02ace0fdf128a9f66d0a7ac0d55dd2346c410220ed340164048a9d3d540bb902df5aa70ef3da94e47f635eb7de9879d626232a94d97f85d6b1028c3ca8cf9bf4a50566c29b5775879c25d55edb4971413da962ff7742858542f29953eeff4aa8e0e4649554fba53c90fe2416129c35c19191e856b8a735793027468b264a508e1107a703e427e6dfface8e706bb20a0f6019f0e2057f39bd920ae5065ef34df30693837d925584af3caa5bd2d7ffb74370f37860ede854e02a9b3e71f1698a80db3905bc444d6b1dae55c95f85d7098a890c272e4ff21355d29557f48caf9b51d9dca457d4218e2c573cb8d8de97b4bf9cb83a01bf6d30232c4e491660442f47b43a5cb5dbdc30fdfef20541b96a5ec9d133bc23dcb7aafd57c8e08ecb929998d39eefce19eb2f16cc2f40611854572e5012f29f09181a39fe7ef7a86c6495692519744cf35dbd55f9d9ef8989f476a665da07c981079574467c6a17696cbddf61c7f6c262e4f0125e7f830f9e4254bdcc10aa5a23c4df0a550a1f7c4671db8a5d59ff8a0f0e994962646048275ef4e549b2216763cf901ff5ef4408d306af76929b4e21849d9b08e10bb3caa5d1b3faff99b3fdcf90b8f6414d2698ca691ca71a4b2e6df1d740e1e9c3bfc92b7ca0a9db2973ee0b1c3641ee9e8e16693e1830c7209ae4059bc4d5a04aea369faf0dc8c9a3d64fdfa0d07d116c64a969ec42024d0d814da6ed7f920e924c6f6f1e23b8bc3a0572c7b7f2c3e87d4a9203143f6e481320e98721fe46f84a5474cac90518c6bf4353335553d57f73139adadd6905ff416c693b098a4bd2287bfb87f48e56adc2b4bb2cf8f90b028857ac121e1c6cab001b99813037f2b632a095daaf0d68f8ed1da72b2ed9dd917933f053a11a18c2d083bb9f5395b65b20cd506eb23f7ed78f5f3517dcd0a88ac4e73c8d68d04ebfc4748ba90ef3aa5ffb4a6cbf1dde7eb1c77638cb26a84eedeca7b00fcd1a99054e7b5a88c8a7c84d7273d5634278ee862922a75064dd23f409183073144fed8f390eacbfe8fe64d1ecf89e6fb8ee9393f5440e0d3b288f9af05042bb49e35a1c0a8bb92bdee30e5682ae80e481474ee07b512706e821d33cac911a9a232bc45ea8394d224b208bbfc7b2a9f8919d28a1acc646cf18fbf547fa943d94ab4e83b41c4ed0575709fa4d1b7de41f24779237c773ae3d2973f03b3742c6ab768418cb3a677b6f90783f97eb1d26c2e699348d3527e31425d518b08e35c60c87a94fae31af6e696c250075c4fba70e723a857d7817c18ded1c3861bb4d3ee4086f46c60cac732accf3ccdd1aa59094d1114d38e8afcf167196b6b00bfc5ed797e89dcb15ce586de7cd6c9eb63e2d5e0b60d861dd23f2e8879cf49a21bde0612c2b1f3767d6f99e6616822db609b6bc149f7fd889d54582b726809dc981de779009dd50b4bb4884eb1471db48b2ab164bc79ba256303e395d3322854ee0e44cb71452affb33da5f57da627a712738d9dd9121f78ea500e8490dbe11461dd6288892935106b07036aff4e8bc56b65b6be2b8dba80cea6e0dc8547ac76edf9dbe913db5948bc76c4bd82018f666b97f5d2b1db1e6c4d065a3fcd509d6aa6672fe8a2e03bf5877fea6b7bb8b04f955ba7ed8f5bdaa82f89f98c0fce82edfe0927cbc75794352e10ada1f3bc27e2d70924cf9685130f3285179635860ff2b72f0d5c6aa22dc5f8f2e9ca42f6c980bcf20e3ac1e2dce530081c73064f75ae91e9dc20d66a2eb46e9eba8dcb58bea0d6e19fe946f19075c9e980c6b3ddc7aa01a99ffd4407d94c983333c99a8161170a89534d4c2845ccbc3dd3d3c3d446d9873dc9068d137aab135fbd6ffcb774c8531b6c2e8cc5e528a837701d1100c3b8f8a96a852b3c4a943f1f04cafdaa947ed20e80418bb8742dc1e9152d8876683bd44c64ce1fe02fbc6f1ef3fcc361f164f83f9d50b993373f9fae3872da20f8ba7c9e4aa9d4cd4cefbed0feb89e0d05c3ea412fe5b2e59a24f826adefdb5b4dcfee2656032bf2b71c984321c49259649f5b5b9443354dddf9ca173490eef82ec10ff41b73959520de5c71a207ac7bb6b792d8213bd6b49c2e2fa953c801c45ea4c49f802ec351f45e6daa661809ec355d8796882e4152ab4e8015bbaf92bbed017622ab11c025817ad6a34a404814b5caa7216c97e5070bc8326cfa39d4e6029ba3c8e18553f79856a281b144320428aaf24c631cce400aeb94e399a0e84a78b2eed0867658fee13bd39a50abbef7f242f702b72c6bcfd57726426afadfc29f3bc37eeb3ae084259f5fe1f485e9cb6a0978f2fff6a5c7472d5c23f8e8bae9fd20dfc83e4c5fafbd5adc86f1a34189134253636b764d509d4da07e7e49fb80cb830b8cac9d243ecc55e2dd8e3fc29d4e3726f45096cafca64cad82fbbfb380cb7bf873bdc11f6ab8a1a7d6bc6575712818d8c4492982bbcaf5a2f6e254e885371429cf355f1a2fafc7eb2a23fc561d733f9bf6971ff9b16f7bf6971ff9b16f75f4d8b5387445adcdfe5bf05c2a95de5bfcdfd7f2dabed3b774b6038c8a2e9da28255856982da58cea86998c5ef77ec849150e47115bdfa389a7ff993432df9acb9f011106f552a18220feee25eb0aff228fcb1bf75c7eb9c7b9c8b2292cf48740a0f0c98c7c7a2e70714a76b672d9e1ab7805e34853310fc0d05b632ffbcdc32a5af529f403f2fca83341073b352e9f541fcbc857bb938ca9e073a349f2dc89832dc964b1600ca79b6143994c484cd8771bd86f19265946b6c814515afb75b5bbb1fd54d3d45cdf761e5246e1870badcc9619fbb6280032253f8c7acba31e113ad2994f08e93cdc10bc5d5de464c7c53c8077f7ca0ddc5640bd17badb790178a371c3b0fe8fe7dba882f5f7b90e414e2ebb093e64d2a961ccfc7b330d019be85696c964ad11a22b37937dfc6294b090cee8f184bd6b22a5e776f24e1d5b1d288a50c30b95657fc8d429b27563921497f2f4966c1ef96bd07fd758c26ed476c3319ffaa76c1eaade8f5f5322e8b537f6065d7d33c3e6f366860d47171bd655460da7097dcba0190ae7a2c2d6bf339fe5267908935dfd83749603d834915302b9a73e1670f7629a5fa502d82b7966cae1dd34561d5a5a248281b77be0e3a32558a4218d96f29067277a4891b78b04a9520f99089c9d0246cb19a696d6be11192abd64bf519ea89a9d479383553b29045b2b8a0ea8936479d64386e9eef1db83380b8625646b37635cf20881b121d82d53a92a172e54f787971b3b652412ff87725854fb1c4211a9906ee8b4d74fffb5941675b76b247358d4dde611f6982dd43b6cd0129bc3241286392296560b757e8746605d252ed1324679aca5a4f155071bd92fa75faf5db4915b78be9df77200f35301a312e4f92f27b8e4ac25d699c90f39f60dc4a817d1ddad5eb27f9f18025b50bf44eb8d18180bc8dffafbb4909d8ad23e0adf400c9e10fd75116a43be47169a9adee94ff1005b7ffb8f81d65581d98626720f6904569c9ce42483ff292c7b8186f8938b73fed16553fae6b229a51bf883c766f1cd637368a7eeff09c8eeefec6927b109404af1785c734615b9fc4aa99c06f84e6c9424472ffc51a7b4c9d1e3eeb8b4d3ed19d4fb859e23108a5db586ea55b8951a33122499a252fbd3cb3f658c72b8c66499039a44222077acc15e69c2269012a2e26f3900cb03b68e4ad2f9237c8adbab0f96839d85d672dc8fd13a05dfd4ef0f486a3777c6b38ed8cd8693215576b1c2e1f50d60a23af78c3de10a7781b1a48ac75af8523c35949926d0d8a066e565122a144d324d72fc5b956435c28daa97d3db0d8f9b56cd9fca359580bb033da0ffff700962583b1003595f786f48f0fac09bd4dadfcc36b5fa872050bba085e92d73eeb8b06e8143634b0e30d16f08d1ff1b60a1feebf1febf6a75fa5756e7e37f047e3ae5a49c7333b900a120867283c8e6157e6829c732db1163b997e3ee7f16e3099d477d8c1017fc7b6ca732d8ce013ad716f63b42707f0bf66c0947fc8f803d03027bde09d80306c8e9d8ff3d20e737dbe40c67d7df83344f9d5f661533298d24d704f7cf4ba96d347196bb39fbb6d9c997d6b51736ebda7f647d6546f6fe8631c29c68ec262024a162406244efba033820c3e820fa846165c4551d905c60a0987c2d6c1fd1858a7aa248aad350860e74fa9e9cc55f7974df9fa0956983e0220d98f27f3196066339ff60541d0059bf632c9d823dff2390b217d5ea9ea5f9dd7f40505647bfc3f6997ffd9fa3203d4241de5da320eb016713aefe210ad27495b9d1a0202b971bf04de1d51eb31d616f0816e908a73d2ad8d7302ff70f30afbbb15c7409b8001b49450885d31d0117663b0017cc86087fd658fed7d05bae78718f48114ea316e614923bc87f1dcbf575fa3f0b99451fce0d9cfe129e95bc67c5f7083f7fd413c77dfa8ed232282128d669b09670321c35bd05a939fd82154ab7d6e0d658d07f07d6b4843a342bfb9f803e8c614ec2be7e7fb5f12f689f7463f03cfcfc661de186cdb9ffff00c8e2fc0cd97328feab208be3550bff9c21ba936ee01f802cd65f57b7de0659e4ac69cac63481badabf5411225c724a5f4fa8fbc649deccaab6bf67552ffe7c5f57b86fea5f0f295256289f654ab53f9460e8087f6595bad93f2659975f22abb81d5a308a7de1bf9b4afbc4bba7b4aad440956e7a9b873af2f66a77fa577b8d066b143a7ad9223b1bafdd00beee487eb1c7353da187e8e8eb19cbf3995aecd20752cad093936d89afa39ce98de4282f103b47ae1bb162d36c54b662f9ef72cd537b0d90804d23bf01bcce018ecb1e13c2f401aa5919c72af75947b8220f1da3bb7d67886ffa29ad0b0037db116778eeb03f04152268549445a45ce6e2e856f6786e06a57a971716dbecb5af9040b22ab208e841025b3f52c2810bd41b6f6fd820a9927ab7772f3b072c1f1e8edbeb25c2f2bfc1558fd82741f2f51eb3ef695dd74411abb8ad0e3a875683ee54393565ae1d8e22756a74817aac37a07e153db8d07323564c73baabfad8d5aa47eeb70bf71b51c9a2db843b465547ddcf5fe4bfcd77e35e76cc42a0d275aac6795bdb2f521610c4ec5478b4ca6536962a2845a7b86c4aa7c12e2bbcadfb3c1a666dd16b4391e82223bf10bf1bc973d4dba6f15d5971eefdb0968173a19e81d765031de533eb88a95ce87363299e7ffc02fee80cba64983bcabffc204788839555da82250f189fba307ea54ee5f8542867c424d75b2235fb73cc8e635027a85a8839b70683c6878d77d7d26c716217081782196e70cd3d3d70803bec83a45b06e1a119756920dcf739ddd4429f920feb2c89e3c57cf184ab00c23b81140cefd260e209c24b17d3d7ccbe5d6333e3073d844b354224ad12f40860a00c2aeb2443d288394b165cfb95290b889d931060646a6e71945ba8dd6c21c7778eb808fc388c5b684015ceddc176662578c37fab984773785e503c6fbc6926cf2dcd394fb8052beeccee81cb4ab1a473e670583175f2191a40efe8de9292f64ed53882513d2347aac60c3e5538635b7abd0028efe2d689743188b552f24a35b32ef04d7399eed6b144521dbcfb574b5cf4ebeeb7d5e570d03a18dd931fc319bf1801601328c6db6ca06a1548e1775fe7ccf5040929466a51201b0c9ebbc918940ee8c01a54f02adc5691bb1d405f22d471f2549bdea9c90d950386d9da2af71282ac260fcd9f248723def49094e533baeb050edfac12f64e26806289624385c4e0c50a67195edd1f064dcd54f9c1744c4777ccd36f923154b17bebafa4894ddc4b96b82523f52e3c1aea39d804a76bedc2d1330204b8a2539065383082f28316f44fe3257e8e96baf1de53e535469941c9bf9ebaa5bf99baea2fa6aef75f9aba7ecdc906e2dedd60cfa3e94aea974bc1e43d577764e43fe3d42a4c714233f1b856603ca2989393537a9e3aa2d3ce723932d1e1dbcdd4b94000eeb1217c930a24c88b443b247a594ff44eaaf6196b938d645b3650efc1997ca1d1f75b2f4bccaef45078a27f504584ff79546f4ba4fff16165bac2bc7d731fbf9872a418eb9ede8c7a15abc2ba217dc9882b165f7dc9e6afbe64a62e5c411fcaf0d8d434b5c5441204f04bece41f359a29e794d69bd19a75f5d93de7685cf62ab13c9df6df2e748ff4206c5144e3e47f5dca7197109e9ed2262e54c7907907eda6d0abb8bd98a8b89bcaff0774d39cbba9da4c6a7a35399ffcb7bac913dee36a8fa81db3dd31eac46602a3fc819b2d71be709e4aa1aa31fbcd50ee70f40157fdbc197ffb7c2b19c61c0149ed02aac7b626e45676177806398ec5801d73c19e3820b576a06f3c70864ab9a9eff4200ae0ea56e85c20ca56f09bec6accc60409e692a76a21476b461bf3e90b9f5648948552bc62672dbd550fcaad435a9b3a4866313a4db0c2cf703d3b17faad3e8efcfb90ccc6d13777c5d49ab119b8a0a9f1c9d9d3e4fdef852075c0c7841007cb34588ef1f7e111e0402ebfdd0d29a956f8eb9b578ff96aaeb2dd1d23057786848a09cef6c0f0dd3b0140deca1764043db7a19052a983e6cbb8c21e364caca051264cfe7b19bf07f89aeea895ed896e49b7f2e472c6548190612f6566ed9d82d5f25487a3f6588f2ff3851d2ac621d201028af3efca86a2af8319f8b6dc7a113b5603b2d8ad161521baad4cfb4fcff1845d915809eea412e7a62c128af86056892f1868490185a680b28bfeec76b7f3696f04d8606f8cf2c01b2b8f1da7a7771e8f0a28dfbc9f4ffb13be3f9c70027891ef3f81f1afb3ba7d3f9f6ed5f9f2c61895abac231fb8f0125cdcbe9f4f0719be3c47edf9445c7a27cae6230ad8a732054963d2fe3eaf8d02a96af612153b2a7cd308a8b1e1f38d9b68b7ef0abb60cf894276b0c0bc9a916626bc2d6d2d62b8c2e10a65e521d7e35e9491a3471713af23c948f5b1485e2cdc11e26d4fcdd4b4aa2286997c2045ee6e3d702ac758466b9407ee2db6f88c3c65e99bad7fd4fab634ec124401696273a9124a0793206825e830614f1c04830b034dffd7e772fb8e32b48f2ec98c3b31c784e9aeaa09f3027186829c3638b20b3eb960f7941a7bc469bbbb2d9df5b7582abd5d9d76828ac2ed4e5b4b4247779be5aee88b15acef68ac9ff193fd824e8e49f0b6d86180a56bc422c7a05a95dba8f2b6ccb1a1357b061a4cad50e44cd4134531ad9a3c038033d01b25e76aec4e37bc4e930534d8d9e927b793a3bf305f42ba158bb70e8546fcd589981f9a79ca0fb59fd7138a01df21e13c0851fcbdc30207534615e4b2ccba0623ebebedc4dc51256966cd537202d2dc71f504418ae02dd1ec6953a9046f2201801eb91b7afa4d3bc2f9989fb8a4842b9c87124bb02a8938d5c6a58b138cf6356d012e23ab2837ae057e78074bb21d3ddf25e209da3a9d0d527a8a8059f6ee6f8c29ad24e70f637a17ca0cde6f5842166eb09f91acdac83127134f98643bbc602123985ee5a335faebe0fd3cd05cfdd3c1b7ff6ef05da19ecdcea7c7ab2fd48bd98726250581ce9848dddbda30039400e5e1a32200049c5727cb5c3c2fa15afce2eae64b312d60c16a5d99c81b25378aa9e9976b6e0949ef4e4191e983fc51bd4c98f770c9a52b99e6d135c7b19faa8d4c6fa8a2c5c6ceb777c587ab8a9c5db5b4a400bedd5ea52e14011824d5eb1a10f1a841e6a174cd71dec957d23cd97c4a3e513344ad24030ca22f4a9714c9a756dd418d96b7f50673b7795b3c4c35e4e1eab5e60001bf70ef873c490928f131494d4a1c75bee620eebc51f6fb2b9187d88ae31897b691f6ea2192f6ea491938926a3313ad2fcee4c3d98d83a5da91c1b01d0763b51e71dd1da5ed78de0cba5947b45ed6553bf6eaece04b0d6a2857329355a637cd90d0522fb9898c7eb393cdfdaaac208e332b4cd35ce2b701742f94397acea0a0d385433cfa3781dca9c4be39ba1ef37c1cc7bf4dfd8b9a3447976b001356000dd06fdd364330d261ad06abdf046159bec53409056070bdfc1996d682c1146764bdfba7a5ca7e0aef22d74c67ce5fef874668d27ed59ac935c78310e8e2ce3c8712fb2d202190422d5335c1f4e455cffaa7691359faa0b0a5dcce064df8d719f206efae9af04fec3740618c20eb8a6e45e63fe337ca2c5434bc14f8d57b8a0f7e4041d2794cbc0377229f67cb967a8f0691d4e1ae367b27e8af203c733365b286dea38dd6b1c40d99aa6612e1a4805bf767e41b52cfcce8de0a4b48da9d58e02b1a81ccdd1b4f4955688df8adf45b7aa27f92fb6262f216c0d601214ff3b741969547e1dd8738d0900f193356c07f228cf0a8624560b493323adf633699efbeaf2a14c785536658686ba9b6b28a0c6bbf841cbd40fd89461bf39a9f3935e73b559caf91fab45020dc2a3d51926e5e8a0441b21ecd9c7cd027e654584ad1e6a6dcd5290d9db9d07858cf476cb143d43a04a7cff94a0bd2dd3981e5d9c1bcfc6537542b2b8f21f2f36cf1ad48a5506f5334dccff1520006fbbc90519aae9654d82d854752f1a1c0aa19f789bbdf5ba426ea55ad6799d943f35b2bfb493482047d6b2d4ebce59c14a93534d9d72b385c7a7a918bee1792782e86bf8c1c3a62c0ee8a11d359750ca7b4b5e1e1dadfbeb0ab4d47968afef1f635ada83cd48ac7767bfbc29eb04f0926697269f6793e5044457fcfd6101068b141b9e72c47fc035f71c41535796ca38ae553fa3103a12e8a92c7bba5abc6f7b87527c3356910fd11ef62bb44dbaec804affae98a48baa6b15c0ab4116300972b4e69d2dabcda4907d39b53c34f5b3d9455799253d28a3b851a1e3039ca083c5e90c7313a6147c3a5def6134e1dc2eff76a3b9101506ca33f04b825bb9410f08255471f01e0e4ee4c5929a1753e13c2f7f3056fa6d5e8862cb5a180018e1400cc523f34e9351a07f654395adfc871aa45b864e75a85d396102d73f6f457dda1f88b700c5d28a53aaa57d67f9cb26111a5c3cf67bd976f9e6939efe59e3c659d46296921de5691158576bcd3f156141d83d22a9c7fb66754431d716f07fb5aab72d65b8bfdb2dfc319c2de05b63dd44296376c9c95b9341abc2203a3874e495eab9c9c95d8435d92d981b05fe09d2353476fe2a344c3dac6c79c08aa25991d8a7aa742e8063124f93d9c8d41753f1f7310a3449de36cac7511f20a73f673467dc7e6859393e634658989895cc4e75d619fd46fb7379e760a92f79822a7ffc5583f32563963472259773924c0a5226ff95176754c3b46fe46b63505af2c0a5e254fe9c1438bea55cf7abb3de722295aa1d45bdb9a79e2c06307a434e9a00eb15bf0c9963e0928ab5eac2ffcdfaed83e3d2b2cf34b0736f3b41d1b70fe0842a2d14e76f4491d617c46cf315a2edb1a17395ddaa9b734b619b46efb22eb6cebe231131674b9e473ec8ada03173de1244802eda4738c61388d25bc212943e00b8af26f46d14ce58b488ffcd1467084bb5067a0ef4cfadd96edc7460b31293d198802489d800b60f7c4b55734a465e2f0ba21ff4551992fec11f13030c52e3c0a22d83b89d7158ee956fd621d5196a1da5271ad70178c5489bab4bc0d9a61e79ba41d5befd002b560cab6c4fd5c668f25292edbe07141a05efa0c4affdbef828b2c6380ce120a609cfc1254944a60a838f5a54f55c6e8097d43e6d32598ae42d1de81501fac47f6a35a63fc5fbaad4bb7d1b53dba96dbedbfc78881013b183b255ac90664bd43a0a4c531f5eee80e18d161f2da953a60d8ba39726a70a189230781d7929c4ed4e9e00ddc1ef17387754e2aa6bffac8da2263111dea54ba53527a281da817a5622b74a78dc2070a0777a828d65d953128d393348c2dc28d2af7cf481d7199bde7be8ac0891e35e7bd71e6a0e0c6d067e242bd1a6670d0cf38a98e9ccdce3342a1e4a47b2f4a7ae33dc633265b5ad971f7f6378857fae01cf5730f08e9a0b8b197599b076f10f5d017e86fda8fb5a4720e689562659fbb5b4d2d4c53a38d6454daee6653053485cab33578fafdd191371518e00e506f7994923a24500a1c222058a17ad4b7f91c6a524feb111ce167b6873dbdc137e6c8ee2e1020f011991553084c575f72916f700e50e1afc7fa7dea025f9425ef09286c858aa3664b8009b359ab14f35120ec31d00adb3c02929b09ace7250aaa048436d4a7f2760282349515ee5ad4a4a3622844959075c5d899ca1d73d31469ef5633595f0297bd230c5fbd29f600f3751b26c35faf358030018876f518acac0cce77111bd4d64f81e37f7b19165991240cff04a8d6ee63d61125af15684151f6660c75a71da5dbc966f41ae3632ff131fb00cc73b0a3f4ef7edd07050f6009a7c4417b21518c758583db47e0a49ac983473e889abd1ee00b3dbd4920d1d5cdf6c4879f75c5e73bbc945eb62bbef48191e45c58ad938ea53e3491306a0327db15a1f4b39e58a2842f97ad2161d5e64775846aef8a7af2f9f0beef51d9addf8f244817c5a54b2726e63d71e0b5a76d2c628bee0fe38bddd4c5fbf862bba6f4cb57d559ea2d7fe17cac88ba7fee90dead9019efe6f3cd68ece04a625019f56d3f374f9bbfd50620d57bc9151ebce2857cc43b6bc68c2823fce5bc1827e296a9a8109b2485d4a9a035016861a99664660e8b2879dfa2c1ea4391177833db12ad85c580cbef2df922e734e41c4d21d515939a168b7d4fa0632456e41c92eb9c26831f35aa58e33d81192d8fe04c976a6ef74e4b95f5843d965bf877ef45fc8c0d57d5385b46fe3157dc193e291abd833a5e620ffccb053def206ee617f1b0ce69a687a7ae08b92f8ef25c63478895085a8f7835fdba3ed5ca6a8095a00cbe89d627068338bec87439f8a1dc66ec6c558aa3bf913bb0c5dacb9cad95f687317174b8cd3ce48fd16ee698225ceab1923749703c95aff688d35dd617ad8b342f012c432fc7f36794b7b43d709263e6f198e401c9ce11d8f6f2d8a917292768de3ac9296d4e9fb33c92b0910546f3b87eb67e9bc797f46c0d6593e79a6b0cc416a9283b05c14796e3803384a889aed65bdc9282f5daf2b203e1bd2224ce04db9b7c7288f8851243d4d57b319970d762f353d85ff1eb9f2cca771579993b5b0943e3b7166f0cb43d96a50c699577dbfadf8c5f19e377bd319feeb203e16c64dcf6404fdada253d5ca78d1668a7a0b35f5b7ab8d6ed93dcb28360478fb0df3367c47e44a2c341c1dbea93a24c19207d82e46e254368cf92e1294ab456527115baac2d828da40db30c4de1755320d75c1da9deef9395febe6066ad199c8fcd159e568011bd05a7a14d2fcd383fdc65a571016f49b0246c71300d117d9eb1cf56ffa6fcc9dd562ba82705e4ea5ceeb706ffe050397c827be310c8009689e5ba8c97eb18b5a3183034514c2b486eff5099839cb74e4614068872eb51dbc38484432e717970afb91417ea0856a76a9e9930c939dad7b7d6d8e75acfcb9b4489d327fd9a0505d93b7ba28b1a79fdc8895ac9f9541b8ad64416d0715e7184f04d893b720c1e92635542a9da07595fb82759b5920c8a07f61e12b653bd90407d5e5207b0591a9c0d1e6a0b24e10e25083650b7bcdd82c2485f5bf665e32829bc24b39138e755a9f49c3d96b54df23a7db8856c10e1ee9840f81c246efcff11f766dd89f3caf7f00782b598a74b4908e31042134208b92309c11863c0cc7cfa77a976c9d884f4f39c73defffadd741a5b96658d35ecdab53f303f079a4abf4700210c908dcef532c999beadc29f615e645468b55bc08db0ba808dbfb137c5832136fd95aca2457dffa0138efe15a3fa3818b4579b11c3e1f711a33d65535eefb4e0a11d52ae4598723e2bb7770746b8360df2a5382ed8f68cd9a828878d2faffea502735e22985a3d5f3855581ebfff5c1609f17a51c59341950d80f45b7d0753aa03ce87eeec9342cd60eecc81592b6374b9be27f92757344c5644ce9bbed064f0f5e49e548023f5a727ed9a526643a34e03d61fd2cee4c0218ec4b7220b475a71be3ce6e9446f37b88b98abb94c414eaecffbbb799f2f2925429e5ee763cd55e87e99ac392769070183c35fe97ab20a331c5330f3af067e859662f502bea872ae0962a89e50a72675e955a09cc9cbcdc74ccd61f7ebc7d83712b5f5f9d928e44a8851e3669d15f364ba31a3e13c1f33c92579ca3413aca65bce62c44b832637b97f495213d7697490577f4a158d19d6fcc43cd3986146292513420cff8d66ad2b14257ac95e931e72e008bb14fa850bd24ccb2273859c28a6fdb3b4e075c309937bcb852589f5f22d447454f1486f86b3be86c086ee5182cfda9a0af8cc5cedd87cba88e1ceccbe7ae2fc1b4bc0529a0bcea3622740b485b2169a09d28fe226f124abc7bf26427fe317f179380559ba325192ea68b1c750735965e64c3c19168953eceaf0de9063eec5037bdb435699a387f613962239cbe3fd63a9ebe93c4bd9259e70a626473c3ef1f3fd19b4522ffe450eb28e509e5ab30bc0320e53726fa411c4e82ec91b13350392ab76cf649839cb05c4ac1e82a8acd59b3fbc5785fc372e30215d085ad1e5b7fd45c0d688b966978867bec6b9f92795aa1c569c2ad28bfe30267088a75be2d475f4c73d901ee8648ea62b96cfa15a546916cf6450bdd63e127f3cb55832c29783f4fbacbd905eee8ac94e153c69c50f82cede1de7c27f39ceda3db5b3ae680d0f7694871809e5cb6580707f4264fe3e56ca5327b3efb98f4c7f34ad24a6020b897df15691a6af69b32c117c252f4f50bd8747cce151c9dc1f45b2c68406e705a42abaeef0165366987401b057b4d12cdb685a60069fe18dc8e0882e016e1fdd7f7dc43b4f388f93c7fa880188836c4f6ca63b455d312ae1748c79f5ccbe9693f3bcb6ac3e83f795b5506727e6fc1ac63f069eac6d62f3e844f4031973117d0a1dca05a19e74db87aafd13f2515cf239dc11fdd7abfd709a55820c28314e83ffab45f735b1993e240c4d3b2095dd43249963ce6cb48ae8dd3b25d8b87a67d814078197d885f794815fbd2248ad847a748d99118f11ddfdb0d7777bd43f27f0b5fb1214e0fa9d155ad9b1e83d39e83853f1532290ed7f6bde954ee6c29c01c1ebbd5652e2d2970bd49e369759be52e510e84c9b3d7981f81a37fab06e5e03972f914a3491c295942773f9e477f69fa2cf44a8b3a9dfd2aef163835c892c1a3bb92ac32d678a12e1626fcd7d668a0ec5f8c3bc3e063214394066cdf8931c459e42f7d46e80adaa0e797ebce534bf3b44c2f4fb592d5a3939c7cfcf885fb4a1468b71b0e13d3760a90406d871444d745875fa250996c503b8147b29b6d26827cd9ddcd69a80cad50199dba14d13769c8c0f651a9b47d30f7da11e42b265ebef2abe01f0d63d217f7bb93a73a63fe21c21f36b8ef394a3fc284f4ca414c3e8ab3ad4a7dea18eb8dd4da51577881b6754cf6ad1c12c30abe9f9dc80a3199e824d32eaa35161463efced2ee12a9f84f6c4d9c8785b45c887eb33f777b9c628ee5d339e29839835bbc4443eb385ce8e850333225c4d24a4c17d4d31ac21cc47c339901a362bf686c2464710995648f235e2a4ae245f0e6e7e136065465bec38eb88a2ac98cebd4851cbb75253d5ae3f805d7ac54bcb7ea370efac458d2cd793ac2b9a6d908284512b5e87403bc5f2a18f79dc99af1837b422a9f4dd63af31a37f8a651a3092865f3c02d7ba248abd089279a11ece5869bbe5dc2bb1bfa65e447ab80a11df3951b31cb2b7bbd48ab72d47a80fe059d7e5246e65ce0b9544ffe7ca4c830b88459aa1704359490ea2f8a4926be9256680d9cf6e66c04b8762e0f475cead37e6a8565f2231c7dc371a6dd2709c83647798233a5f118600f364ebb5380f10d57460960a46fd2c001f0f9b155ef9e7428b6460b0f0883ecaa9822c7181158e1236d1f6ebf97407e709ebae0f4a25c59842d5dac328dd3b267efc2ed3ab4677af0381d5bfbdbf03a150bf40dda54b7a536c2585e112d5ae0be9dab9a1b951aa6edbde92afe0cb73a0e40ab58263f033ecd2467de0540389efed983e7585ce39e56a33f97915eed42a3eb320bda2e92cd5fad9868ed901d144fdf84b5f42b668ed24e9967aa6d2e57a55caf3e8149a2a39b28d0d7a47d653da0a870ee71f607c26dce600391d309bea11d237db040e369b7e8660c4ca53f6c61132d6e8344b173c03909593f60698fe074070c6c536146fab6ab20ac290097b4c5937adb8d9bee81464f14277979285207059aa9a3ce31899067cdd65f9e75368df28de7705a6fa30fef1b27a8123530bf55282f9c10cd2f3312648514ff584333ae35e13ad1786d6dab6406e8b6f96ea7a00144cd8b3f1150f8986fb2a558a249d1e79bf63ea623648f6c87d3784cca9de62e35e0f7ef3cf6b429aabd5cfdc48171bc38a676a1d58e742eabf89760eedb77991bc5e9f4792093a8973095f805707333e0567096e4cf309b3c7d827fdba1fd275eb3e0761a73a48a320c661b87b30b3ac91a484ade4ac84233cb28141be4968a3beb670814c38448f89b1d6b9a625dcd605c4819f112039b954af5cdc0ee6044c176c105c5ee21810b596215bb28f75428f3f5be813c38cf9729bf35c30098dfa6ea54af1d5f676686b169d35575c21221bca15ed0a7551272ad3e7cf4d26c7e80b97e3938f6473d1cfe7214da042aa6b9d9dac6fa07c946e6f643638422ab78331cb2706035883c90119502c9fc28e6168f81b6761d9931b797c21a6f9cf22a832b38e181260efd9b567af034e58fdc8e4d86c8c591267d4b83127f1f1a46600d6711bc614f8d88ae44125af9ad25de17ea3b07e9ebd5d5586e005a3fc1e136d68f74011e6adde9e23cd39f07c9b68ba0a6563a6d94f0aa9339869aca2f98ec90faf46cc3c88eb2e05c6a017287a23904d5e7e27be712cd0f2774eb238b33ae048a86f70625889a2025a8b3c99d2f54e32b832773b7ccb0894b3de2a752392ab48d382f55337d4496e22664d4cdf08e436c24c0813370636a39cbb8fb405e9f4cc2e1247b81f10e0ec5fe1b86290ab503f7d5839d90161734cb7a9856a2f3ad9388fdffbf5bf2bbbc2b5d0c82d550327a47b7d5874eb459d78518c4e2411d2524003a584850ce1b713811ac8af5a809dc3371d6bc8721ad3384a93ad0b1c35d2dd72006d6e4afbfb870d15640b0fd97bd40b79dc3b7b32f7b8873629902b32cbbb09bead13e7fb822a04de7df5677d485e354fb962f4b21c5e3b3b07cef7638245c0712fb544c78acebe6c7eb69fa33d93b8e0efe79afeaa001e347706f28e4fefc097cf00a1de72f73817f67d1d5affa7c3b0a0a53900c5aa7300c9f2bbc5a630a5e9f0b892ccb04faf9ae6464878ef839bd13de76853fd436ff9bce410ef35078fd45caecd8075d847bca241844b8d2376b1d1a1ea708983fe246d0c27c3609c037afa0f3a7a898e73d081cef375168cb33fc9503ba28bac5a2b2087278d2a4788506f0d4b66705eb087aa122fd5200ff69f6a9d54a94896eaad045ae193f694353b186c5408b276f92a8717742a33c8c4c59a51addd475c07cdc66056c3f2f70b8a513a3d3aff8d84fd2ca06308e435011be6680b649d1b5419d2c027ac3ae805142e375766f9ba2bf45b86a803170aef5be0889ea8841aed6d18860b542fd4331dc68e24fdb4c2b6390491cdb8c240725c844f685ce38b7538a8707c282bc8c4b3784ce9c1d6b2b2e2c80274f5b840bf954f12aa91b868928c9deca7704ae65032d720128cd7e6972ac9a315c17c3654e2fbc71d6cff6c789ebe12f9774dcf223e17c27471a26a9e724ab4e933b2085069b35480420fc98e7192658871bb740d03ba78e11a5e68099df46a05996d834284a8762eb2854680c0607c30429eaac8b925283ca4ab1ef12796521f93d3db48f29d4bfa8102cbbdbb30f93d35bd89d0af8574f1095daca59a5ed0fb084d2797fb78a790d1a54d9f8950a2f1c5f4842a482b74c3483e3ee114cec901370fbef6710e99e96ab26e1fa8a41b32b33e162f4a7ea9df2a46f64e23fd446087bf91fad49ccedb81cea51f58f0e5204a7e6d459759084735633238a9826c53d740331dfb3ce7ec3b671cf74ebf9d9a444204b6f415c862709056bacf6ff9fa56a2d33296719f7d49e39267fb07f17b71627de4474683c717d20f54a8b01ce0851b9f249a667504f65b8c0b9e04332cd485fa8c3f8fece1fb2e032157c0cd8c99bac6f51fd8c9d825e566240479fbd5c31c6ca9271ca6ee910fd55d0fe1855a280a727925a632a5fe5e7c8b28f8e317ac6ea7afbb85e976f71b1e2a1acba3dce55b09fe9222e0a124e8bbd84a6b142be1b03f6e8fe36fcc82dcc41c58166b1daad8773012eaed7082545a3ec155bb60774ea37c151e4929f72b30191dab2d9bbdaab3b61e809150e0e6ba3091aca5949edb9060b8bd9c5c8f10fe1cd733f6760cc4da99b7685fb2a27600ec09baddb8546bdd618f560d65b9dbe0d2c2fe1f85770b07aa0ac9665240dd79526e468dbb75eb8a5a30ec25eb88ce3b3135004f51c4129e709c7aaf8adf9f74aea8823a3189cd6fe54aaf28172cfe5e2e300768b7a4322a9146cd0ce2034f896a5aba9f91c54e0c8bf8ae9cfd2e50a10746807773ba9a695d0540709b58ad98fd9c9c5fea3a82f04d8ffd8feb00dab7a9932c12e9d338eb8829916e7c08deb4ad3988a92881fcab0d129e923921d98996f52b668650cf8d1aeb8a8e507f32f607d3b49a9e02e2648047c0c2f659812c5bc68439d5d8200fb67bb74ca08f09e6ba3ab5b6412b59538d5f325fb04f1a33e9b2f8b51622e8bfa9056c6c41aa3d190c46e96fedd1bbd61ef378586aa05cb96106cf793133c17d76e3b803e840af7f9f00b357fab3aeff9c009d865ee6903dd55407879e7f91ff7ac0f549cee9cba63e3e70fe4a06d3a87e77d179cd0db36bc1d3355cc0c7b1bb5f7cadb628fe19a2f8f29586f370b7b86efcc76bf48d975ee5ef4b8f5768f80fc55eb21dd129a98397486a6204549bd5a42edd1a5c6550712ee385acc3babde3c4104a10b44c80e25b89f3017fb77dfc1cc565562315de0ed4bdbdb5f3cac45c33c99e16a7fc00373db399f76751f37afdbae3d7e61a368d220789ad201a381bf2d4e8770f39b07a36a3662e22c0ceeb06b4efa45f7d8339abcfb8af35c9c23b9685976cef3632bc0e25a08a04ab5591b4d1c273fcfdf4e9aff2a1613a55be5ca3c05efd35070a87e37cc22313001d6096cd518e7b628a255e21bedc3848bc3ae3245f6d0398ecab3bb0cb705072fcea6eb62f3aac6036186851f19b3127422039e8babb0481aa396834a895183c04f799fd6ed27d0e6b4625cd606c1faf9999bdbe05b8b5b04c6f1e6b0c4bdf0e4ff582c4a63eb9405db8b1291e1f7a66a754fda96c1767cd54fb7f2adbaaa48a6cd23c55cdfa5bbf0feb04c35dbd4f4252ba7b0dd241c2f7823a2fc99144402a4ce7014fe701a6f300d3d9967912153a38069c17a55f068d8acf62ebe0c2d7aba0211bd5985166b5839d585dd8b16c33c56d3e60f4c696305d03dabbfc306222c13de9ec5f33860b3be91bd9e930ff3fb7e4ffbe34c19333b9e074aaf5a0d8c83d1a3029e07a83aeeb88a6d0d3993cec7d24998489783f6638fe9ab3279fa1e4cc006ad18b3f3f1ed9fec32345388a56d4f9932be46df4d7e72a9a135cf7d8f59c7c72f4f7272f8766223ac9dc9c58a7e297b7e1006266f1af1278a587b42cd632e4b0ffd3de8d68efda8f3f583be82cde282e650b868c29b56ab2036f064e1eef08c229f69f96e3e77a579892b330d577d6b2cc3966eb019d28cfb02673b5a7e8173abe0aa3b0cad787c9cb96b12c77b43bd02b6ab2ccb1727f936fc0053e2e641892016f118bb96258855870b92f16543ef13e1295d7ba88893793a55f6aab13e0675af8a7dac6a253d33e13242c969c1507a7fcf90cc5c84b898427859cacdd7295548649051ba9933f237bb19f2a1e34b9783d00f87a81a63bc5b3b4a94612c577b6f6790db9c87d6640995d80123ea48a7bb6f625a34a432e3ebf40f039258b3b055b7b0d6951393a752663c6ab2ac0e817b2e8bb757bbf61ef9f11dfbbaa92f17b1ac274db597a1afaec9a8d69c54ccad75ecab0af3da3393704d1ea9c64856fcc72e84cd2f79c50d2d9df18b5117383887b3f67092b29e4869347cd9987d55bc2aaea5344af8ee416472b34715fee383dc5829874d4778d0347c8647858b1eb87392a3158ea630540c946aef19f4ef87d5d8433381c7a8b39c255018209e6bc9de2ef80e9351bf080551b90fd58bcee7a7395ba8ed8d65ca305c23d42442d722d4077829c4ecebc5185dd6af688e53933f46b2d0a56c4e167a45b04d7f3e33ccdbb010148544dae506221d75c8267532fa48a544e962183ce64a5ce4da86b7388ec10b3373df1e5635d8362718057fa883debce1b3a3b15ba244b7b4482558f6c6a3c288449ec12379c38521326898e6df9b6a26d825e75d05e7453972db6af68ced04229629b3e172ca3e046d2c0a99c0cf6d71bd4c302f7e9a5b6b7f3151dc7cc35f49aebaa1f65bacf32153bb5c1be72b92d08687ae378bd4c1e760bd0260725d755af208f9e79c629601861fab6fe676de3677233f6540448f15c5ba7d820338c198bb018dc3d6864c71ee84eba411fae50f20194e581b1461116953bdf60d36270e89ef2e38a1116c3d44e86625d5be3245f39d7690454459fd629cd9779a7ec1cecaddecdbe5491bbbfbf90b7603bcd3675cd965dbeb0ac6b365806f7df6797cc690dd054b917af98911063c26c3997260edcc8ce23e4cb9bcbb9b27dcf14fdcd43fa350dc424209e2653623edb4a5aeb9fe7133b42ffc840de687bb790d5bf995b26277f29876edc1348de4324d09418cbfe61080fac10d9153a6b686b76e52bf53a6509550d5dbbdfa7bc4bf497a6f33a3b487d3e190cdb4df63e9b1644bcf32e69e77503598b6cbe2c47cc5f7acb13a2082f753aacbbb32f3318a1dad3d9b0eeb51154568135d30de7ec1b83b03b0aa92735bbc038d43cb61cc292685d452b30873a6bb05afca9efa0d7176076cc7f65874221f46f7ac1b5f397d9d1029963cbf816691a774fb85cc4b00c38c68c54bd38647ac3617e7c11717c7389f469c853599358d84bb9c34631cdd08b166aa7b25de129e2027b23294cb56b7b6479d820faa153bd1016626486f4adb8a338ae572ed44d178225e9ad868475f145a0d62951684106dc794c45de8538947c8432c3db6257479ff9af3b3047e35b1dbeb97601eeb5cef2627eebc79042439af0b3bfe5e1147dbcb00051bfe01c5c51020ffd1104e9eb664a3fc55fa98522e4c15b33d52b7b524e150231df0a146bf99abce9084dbbe61b85145cef1d530f96d20f1ee94147c1afccfa6fdaa7e888cde34c6e2e2d338f97b2c2e9378f34815b158a612d0d781e835ce98288180aa319bb1b7c2e58ac1fd0dd8ab903b5f812cc2ddd9fa3e67eb46138d38574a53e1f322c04294f2ee135ab4e53b2d1b26de677499649c0a594df2fcafe57bff8bc9bb2f437dfcbc41898b98e093530534ea50b779896bdeb807581a74c9d7216a98b8a1f1d8a2e4c6c73109a352846e486ece5f21c3b332beac8e12939944c13be9c9e63a3824fd0aeb70df1b7ab36f3cd02f978067e340b027333aa194c07100aa054295dca748129d511cefbe3dfeabab7d074499e91c0e66edde6a9d4221bdcae4bb3a04a2a8f3a70ae5450c757a27db76fb65beda60aed216271dccaeb3e76ab2ed101ef7431597ded7faf9ef6610d0b09f7d6e547cf972f1cffdf0540d739496ca9353e766b94bbe2bd8a8d7190ed09e711e9fedcdcb58811cfe322d7893cc306cf0bc6ccce8ed02f7bbcd369a49e0f655c415f388f78d4f5f8d1ffec1d2e874cb00edf9b219957dff369058409205386d345e6d8a895419ad5c1ed6fe84e0ae282c7e904673e6edefe367d7bee1de452630f5ac36cde3d5242349d9127b67cce7bd989d08758e94dd8e556925256fb5284562aa8a3f6d4e976911eaffd39df4e9d731769b706d6325727561e60cefca165cece7cdf3bb7525ae6660f8afe25fb3761d1540569e7e19653f52db84040fc494e2956f6ce19349043a9624537679b90e702912d004d57e7e43993b208c350ac9f8b941570544082eda3d744bed793d78c2f5028444da70c0f5e44f154df33fc7dde90679899a860026e043a7b4d5475a435d1f56035e8ccc19ac9daadd98b0153ee9438614ef1a429217f39e20f39b0dfe4d868b13dab15bf86c69d386b74a359424d6e99c99438b9da678ebed4cd7ce33162462aa94bf97ee94686791f32fc74063422ea04cbcc8f0790081b6d7288c85fa5f0e4f75acb6caa2e4700e6a6983f7028b89e755c336d720e9a988c10369096f12cb8e017712ea23a9ccd37238529c016d7b6b886d4e05d3a192621ed2f46c4c346d3a55a27397bb98ebdbe9fdee5d5072a4e9e963da1614e9f26a59df605e09ace8ae38c76673e4fb5d004677acbd3b9a7db872a027a9019b4b3847ed8d9117aee758579eb5357e947bc171dd681a94fbd6e5026c8c9f8b22b9cd74af947c5c44a417c10aa39dbcaffe50d7d31936f59477c40402be2634e1ff44a0c7467c1498c7638b6a6f02acda2d48b3daeb40ca2da118974a8eef597ead0977d7cd074468abb3a2198fc5eb5a6376aefa9aa6031ac234783267fc32f2dd294841c02bda67135f5ccbf53a3757092fde453e4b25204c1f2bf6f1f488e422692b74f9a51007f468e777c80f2c0ddc045d4a3e02169524a852b0ff302d819e4f4324beefa639693895fde2cf9cbff4efc58c4055de1444de7baf5550878e0ee0874e89aadc8c22eb55b864f6dba63e59f2cf5ad9a5c8140b17f00b064ff603ae72dc0d5c1027fd9bae58489469147ea0ddc2d336c0a25a20f989c6010de115958679b42ac3809c44a4f4c680b7a1365ec260dd82fdd05d2b0c4e019802c1784b0d10559c3a7b8e708c4d92c580da31dccb48b8744797550b67ca6ccc40303a14319b235d6e7acf6f399048c1a3d342de12b8a9fe6a581dcc1f8ebae8a78290b00d5cfec948eacd3bfb1f1d877cd661666c6dbac53ffce2ec8c556aaff883d2493d5b065a9257164ccd829df205f4d77bde4bc361e28134bd83a751d5dea80a5d39c28f85de04cda9b238b0b745aea523fbeeb703204ba4b7da2d712d386345423f7ba427d301a357ec65a05ca9f6c36243eb05015dbd7a85da407bc99a804dd9eba5544a80fe1af61d3caa4049f482fe0ec557713b17e47cd2a9d15d31a4e97ea370e22e47bfecc6148339fd9b1503eb25e8e7dccbdf237e1da2f458e6f87ebdba9156106d820cddc5c9e16ecf3fe32b3652dab4e366d491cb081b8d14ccde158b35a3797a8e23f5f2ebaa0e61736cfc25e39e7c0d843313d2b98feb9bbe7f427f7a6034d57e0b8a68043c4b3627e6cc56742491fd293c2de6c985173d7b24ada715ebea4162158cae648f9fb2d2aa7f49a5d229ec893f6466271aa50e6caffc682c9a39ce7c8a5027e1e296daa5e6b18717fdd55ca6427760ef250b9bbb4675f4ca4b24c19ec3208bc9903f29d7748ee63fc360d799d6aa948171f688a7d95b88fca57db27ad70e0c769f6906ce6e842fd0ebd718819d36904cd5fe88d19bb3ea00df55964e00119e590bda1e311ce4f797285fd617ce0693c9f5bea904686415ad50c43ede7dc0fe0a41ed7a880aec55b90edaffa9cc7d2dfffcd444bb27a495e36890fb4698c4b5b76e2226d38196c7b42f5d9a3732f87317fb1ce213a6abbb11bd915ff4e311be3d7d40a58d08c772a32ba3feae71941f25528d7d888dc7205cc950b984c821de66019a7ce0844b1d3c422a17ec522f9349aa4e3b54e7c0455f39ceb81faabc6cac2a6085ae82d634977441ba11a32022ad83d83777af4f6dfb620885b603f77cfef3a803b4655e49a5ff6cbf72ef8940d7740e657f9edd4fb5ebc5f0837dd0e37d9189af88e88f7965cfbb659984b8e4fab474c772c6585047e74767295f68ddf18ee09cee6a9f85dce77b8bfb778b7c809b171b07b46afa90d6eb9a329f23273af5159977b275605a2d51c136526435a752d4f6e80041d9cf0c1470a867c0ff9ea127fd921e8acff2f85aa3da49e82f49fb3f74ef1d517417fde72a77f25737175071514eec95c0db6d973b275674b31657a2dfdc2ddc5b8a1b7ab507ae77fe57fb1f56e62d87bc4578c68bf944287da6bfc6702160f5654fbef04acfc91e501c24b692fddcdf15ddbf2257d7127674ed52b074ce1c7ec23f308386823752adeedbd83e2deb32bdbee338875717614f317c5bb8cdd9c589ea33d8877d2ccecdf6af20d8ee34a4b1ad66594cf257b47fdb1aafc8d516acd2e9fb4294a4510d9064b206bc8cca03d1921f0d52d86f4410f25fe5d5dc24852b0198bf8653e708864ec7e43264fd5f62bcc13d26801dd0a5d6a0f966869bbd81a5e2e9cdc69c1753ac99a7396d7d42d572c672a13a2da077a0d66711edfbbeace5151082bfc99b3a8d2f0bcd980fcffa9c1f19b32f83be0f79d96eadf35dc3ed867d4ca9d9eb0a588022b36c0fc0f9d9d1cc044e525b9fbadd520c9be6d6bfa2a3e3dbaedeac1ffdad5fc161eca40fedab5cce43dbe37490fca4ea5ccd2cc6efd90e36aeaf4362daaddeb7205fc732d7dd8c0dc0c0558b94ff3ce35d9131cbb3673d17f6611d55f8059983abe67d8428f33825efdb9d29dc0b77b039ce5d0140a5451af90ea36b816f5b27da19f8b745e1111c9331f5ace8de3f9093d95743c3bc26d978f8c6e2f2793fb6f5848e4060e6d408d7099d581ef383905f3e34a060c27232b08ac1ee6c9629d45aa698c144a5e868e08e93c791d520601889297491ab0a7bf0edab3660a65bf042fe9e84c1ee18aacb19cbaa7f1560f07deddea15f074d2573a810c19ad5fcc807ae46f6786e3abc3207befbcdf7f9993facde7c86d97598611a49a03cf58872787b3378a97535101af8f2aaf8f7b7628e720e3c99669fd6a05707671b17ca60510e39d62fa24e7680c377126993a37dade69a32ea98005cd7ca8b213317cda9c1304481570f64490e78ee4be68890d7fae85c36f216c0ef397041c7eaec8cdd39022c3c157a8f8f37496f16f76e719516f22c45b84680c3d5b9171e1b18a36330e1e8c2c1f919581f86274753999e99359c96c5e1a9db21671403513f01523d0ff972258f99b4cd34a38d8b7553d556dff4274af9d0f9f92288db6f8b661f8403adf22557860db60be6926859b53c9af4c7ef586c898b42773ecba3327fd8032eff289ef53d857435e10225dbd5018e19cf5b70283f56724576aef81ccaa58fe655cab3c982e7db2aea56a0f604247a8d71a8622ff60763f9d23d299dee376cef9e42ba4b47bb2ea90e254c2d9278b1a610a60672f3bf03c732435ed7b01d0a92070294b1f8a529ed851d53396351749b3f13866b75aab5b1a768434ac9bd52899c60d544a9d05c3f0c1e6d02ff6f8987290874e3c47f0e51749027fb6103fc5a499ca0d4194b68113a9bba28da3f952c70ce815c0e4d42b302ed077b23dd12302b487ce12f27d2f20624ff5c68da1df0ec2a59c57bc202949efe70e29e88739d9dc0ff20c9753bf027e91f865a183938a1bd79b118243cc6505adebae89be4a7cd2b705c04d2f4044961d0a9d6b520d3178c736cc7c45df54bcbcb9eea1d72995c8e2e61eaaa28eea52588a8a9bd0a53888eb6ff2163ffff6744738277dcbc714ceefbd0d0c4df932e778eab24800e227d15b513215a7a4f34fffa632d3cd7de1068a8b13f590e8af7f9d4a5d312a61f6ce227d9dbdd1fff3d94b9b3536995e08bb2c7d8ccb98aa9ddca2865e05563e9e329a004b34cb75fb76362eeb9c698ed966ba8aa353cce4d9517dfaf5f6a119a0fbf1b7ce3817011c357b991e9803e377d65b44f0afb6848c5eb7f2eebfedf1bde42e9f839d64b2ce2779f736385e26111395232b853ec8628d11017fa7bf52919a6f1169e500ae7ee5a1ea0a27a6449c207161855dc72026505f45043a7c3273b2bf814438af924656921b5aa1ba996e9e18563987937d8069f7860b72d6ab83b20f98e3732b857adaf1853d2e384f074bcd7ec49904988718ed21ea8e4e44eebe56b5b754b1c2c61ca70e0299577b26b2465f319ab69fb724b884fa5d2118ae7ce6a83ef03fb798a4f30ad529e308258c0d9c5e4ab1830fe88c419ea2539ff688741b1e1128b1645829bd6e488415403054e88d0ed822aa6785a6e63e992caa4bf0eabe101f84ea59922ef241a87e66a92718a7f884e867dd253d0b9e6fccb1d5dbb43b31d9a7aece69bdf62b28a1cb730786e01a5fa8d305d1b5bfab28f0da48fd16dd6405aef01ebed96ffc93a0acea5ea9fa966b1947affd31cab9303a88305bb4c84ef08f6e565609404f751513c2aa976026af4c66d5c72b7bd9766859c93a46055be7d4f5a1e5299147414572d12359c6fc7857d9b214a24ad9a06c2a04d0e45247fa302f326f38f8f79a22807c7f9c615d05a942ea8b32b338cf73ceb36f7974e73e7a6ebda0c73244081935378b84c7f6a62a9b0b0332130b9efa85a4b09226a97945a9513b6c97599a85fff0804c7f03ced9e20ab7b91cd004c68dde7260a17403a2ac7b4618abe5c01a790c9632bf8708b656beb25733cc7e97642ee32cb1ba260398ece3753f8b1058227fdb604e4c21ce3b4b247dc03162024fb3afbe23b6b4da74f63902828e0e14b8a1d736881c2b2d83540403e40a9ddee45738a9391448e2734fa72ce8917285bb442e238608922320b62a20ff44bf9ebc45ace6ba2639be1599d43a33a67fbf90ef3c901c35e4f99c69fc0f914e2cb1e9384bf78a477b0f213c35960990da3b0fbfb301608b2ebef12bb7cd444178aa9dc516b27705713703349ca1a81da14a8a0b162ed8b2d30ca96a2dad466324d9791c7611c902e42e27bf9476c4871fec0f7396681e6239df604e3e7f223fe6a7d9ba3cb92f03c94f19de8625ae2d37a17ec94c4ca18b6c407c8853c295996f27de387ce553aa17ce0a87c5c5523ff71c66b80e64f407056971d11cf8587077268a9aa571301b97fb950139e3784b1364e04b1e92fd83d99fda0c8ba8f6b243f1d8b2cc451b6627ca6eb51879721f34af7c17343df1182fe0a57cc9f68427451dded6c98ea39b8e75f60d7f92420b41a27884bbad524edae979e8fafb2dc582e848d5b837eb658245a806ffb625334490a6bf22be9e215c102948ce5b8e2fce2a32fb299c76d0bddfb089d03e6d38cef3a12e2dddb37ea26d9133730cd1ad8505931a4484c6f2a4c0ae08c1bb9b1d09e7911ef32049cd648f3d8fa78b063d1d9ec8cc9cab38e9c4c1eec20d382cf1377d1c5fae3eaa9097063c92b4e0d47b06ab745ac9b1ab314ef6c5c4c6b48e266473ef88aeaf41893fca45ad640c10a6124c3688fcda732e05337f390bc38994a64a7303a61f6ffb0f551c39d69c5f098eb64f9f89d997279b78d0a78af5c50104c9b5db04c95bcc3873601bd61699e0174455ef9654f4954d2466e0ed84b71884d7a9825c7f6513593576a93d870b5524d7645340643e127520c5a6a7d6e9329427c45621c6e6230275f8ba3be10b184e9aea4b69b6db0e0e68c51c7b2e3c3024a77b45cc4aae79e823e36e9fc3084f6adbbe3fb307b6860d79f19c9ccc81fca16ff482a1506fdeeefa9b846cc65e6e28258ab39351852d3215f24eb47dfe5dedc55c382f851ae8bc9688169f6d7576a64427921f966d771413c48780b70e7779c81b667ef785fa9eef2c54895bb49f5dd3b4078a5196d380efcef76601ea92645d90d586224ed9cf689b101cf778f6335767337d0672f3e4443613e5cb23b459ba401e2b2bbc96afd5d1b660649ad3d1f4b27bd1562ebe7977987cf796dfed35f8dd9c5b6f72b1ef3ef3bb2fbfbc3b4cbebb807747ba5ed757baecc9819fdd735de6b70b89b27750e7b3fa390e85d2bfdb67f69caca2060b7cb51b0fca4e86eb9838443ddbf49097c0818ad48e793acdc40e4eea1a07cbc95c3b65b2dee91d922257227631444db49ef26ed30fb2e86b0b0ca2b93110eacd36008cc8bb064da5f7c5f25aaa47b91fe3742f0790f723ed4b7d411bef455da18be10e64e04b4cb34fc79e0662ccccbb9f42d79a87c41c356fe85ddf7049be21f3f30d6b7ec38adfa06346d721bf61223a85f80d669ef7847aab01aad5bdec55cc64feba29c93873ba5d12ca979b1ccf98a9507ff4559d68da2f703f2aa7146220a8b1c18b48cbdbd96bdadd05bcd9d3a0c17c467d0853450ef24fce3852cbd83034ae28182ba04a4e2226d0594266d852267a1d351bacd0b259e082fc86994f5c3d41eceeec1b4d23a8d4f4a32d6576fd0b13f79abb23a34402e459b0935f0b05fafd2dd2039a794e5ca0eeee951a53869184e5de0a033f1b482630282fd93975e27c6edb415cce15eaa554661b000d95f2a4cfe8e003faae3b038906cbc8ea7b0fd344b7ec5a99b22bd4f33537d40c1bc8e4d48555a6c3c96e165d6a07a443c47b99ce6b5eb85d60fecdf1c944b9ee73d8105cd0af354e5030cb4b38982e3c07b9e52f279cd99d9b063f2f979c6bb849c45170c2f5768883d851505697fad6592328b99bcf511a9c4eabc4f3e5d8681a8df8b9c1c7c6a5c5e27e57b81fe9bd3b43c06626d522dbf698a92d0f6a5e2012452762a3662544f8aa24f99ab625ab31e8f7e28ccd5a03529f17d22f12062552cbb9933d933f01ac84c4d51a71ae0de0d0daed696a5f5cc124306746dd1cf6f351842080529e3300908e69136b985de607bc6d459f3488cafa06dd46d01fa0dc68590710a066a86488c74c9564edab33c54805fbf1f689d489136e5f62537391f35b942a30ef5aef8bd50fe694c16f4896f667f7cc5c05172e9dfc8d7e75cd8e10bb70aa201b5fca43e0e028f8bd59aed0057b9b2aec58269477fb9a755e82d90fbb40dfc806369aaf2157b8da098e90e3408bad5f6c9d55caf5fa5cfb73fd25460da436ac95981d3b55588cfc3e057fbf5e175f7dc7d6f7f51b4998bb51a247d4810eafa32c80f47c2dabb0fdb7a12191e09e6bc53fbac753fa7bb379299c50d90f462b26884cf982dcb3c3ea770398160a6a8b79390d0358a38bd74f9808b70421a3f8957544efd949b0dbd139574d9dee2fd66c6353a1c91fb3776861cbe0f47d031349981ace24c58f18558c48a22eaa663ab0fb507dba26caa91598a47bee103ae7f1000b5d675e6fc556cd4fe17c6d5b572da854d0b11ea4988089574f33b528e7f225eb88af0e2810589b7f13e0f000db35f9d7e7e4f71cfac476ffba3ce3043a94f8633bc20de419f6abc98192f6bb1f75362e0f409946a9aff59e06bda2eccd1f72b6d1882a32ab44073627679e6723ef0cfb5d865511f4b8b363c0d1de721c57d9da5095d9a2b449b43abc33a5f791e99d8de7efdb8a8a9ab053df6c17c22986f03efb94ccdbf1d589ddbb55999d0a479daa6975fb9821a3ed04b96a5397c9f65102cb65b39e4f49c64788178cf32a7d614f077552c5cc18f7a386fdf45ca5d1746df452dc913083bb6f6caac857d94be608c79395a7fbc332151a3139b171a77f99b3964a51a6c4bf4986149d93b912db81ca008b3e59c350118d124b263a3b85adebc4123d9a66ca97993c70cb9ecd4a78201bdbf7129eeaf08ccb4ba29172be2292659c13f6badeee6c768ac1fbd67312448544769e58cb5da1f78a27e36f769685146e451e391777090c4fb52266bf00c62782d8194558a7dbc808043ab6a1254c61eae332bdb3752c960925a740547e4e8d73e52fe774e6ff61da05fa3d11fab1d44b0fc5a99524c1665a427b7b1070c8dea24ab2df5a159688f04a0f688e28226c4e2d5825bb956f1877cb0879da66e0e90832e673871faba3bedf752be228fb7599cfa5e85fe4b97acd11e07c9bc138d289bd6e9692f3b0f57ca204637a29cde2c2fe00f050070746f376713ffdf143d3c2ee5c6e5efe61795f31f14f6173d124dfbf39943e8da24ba7b213c8593939475e1fd0a2e1d40841fd8be4f2a08509331077b1fd2e888eacd9a9e4e900e96c0bc49f32ad1c399f7581331c9222523ed9d965c44b3ea87b14bbb5a7be2935d37dfe873ba7b7944c534ccad1cc3ce8ae9be553eab42e9993467b72f69da8e283bf6632250bd7365183e3358f47753d59766795b0b0dd381e1efeff384620b1012ab0948d3bdb26c1404a605819cd16eccaf51186d0e37798fd9879dbe95c28852df360d05a2054a497dc443a14f7e90a316b6247387bff743c31766d06358a8366693867f35f9e9d9a15c1565b7f83d958afa79bd93848eb29170a00ec06256b06b5ab5b8764bfa2ef61ab968d5a2ea24bc6f483c9688c10ac104975e01e8313e5de166bf6a93200397359394b841015ea093ad122a7202bd321cf99c35d8e75ca9dad3bd37c3765c114fd4d95cdb735e25c53852638d73fb747beb13b72f8c2913d4027fe1b97888e4007359168b45b7dc492664b16186e9952ef08e47f53b3a1666909aa72d4b56aa7da7cc745880063c11d24e2a2f174eb742a8f78920dcd9ce90bbd6bf24933fb6394a036a04948fad6b6fd2db8bba9e0a16db5be8e70783ed05a7e9efd81993b9e385fb4597855c6d12f1d12d6825a52fa1c1969ed59cc981ef45027f650650deb9c626643ea790953ea9322df995bb0fe409bc0cc9c16fa952f6e38739063c4a4d882cb596bdd228df0a5795cff32ab27806e0a55efd1f6a4b2ca28a5ae688a15c773f347f041a3fe544e3f20f5f85ed10b960e2c01fc7bbd045aa63e03ee90f6fc067140a8757375536a51c521ec0123b67acd8e44976c0c6db146d0c6b2062abf884e26e7853b3cd5808145f797e4bf7983134aae7cc595efb6604592b3e9fd4e232421775a57740fca6b5d6347662dc6feb9a2457be8c036323ee01cd1e2034e2f9207dcd02effbf9d72ad124e39a7390f2c3d41b86a995ef224dd711fec21752bde9606760639e261ad1a240bf59fac32128261c8dc7745f720f75b99dd4ba3ee31d782a51074dcd3d249a92515b0469879e87c40f7ffb8fde8c7363e5a0d7e7eb3fbe76fdfac0aeab874b2ae787276be03c1e0f6ebd545ed3f30da1fd98ef8233274aef6937de18a2e71deb7842dda4d0bc17df0ece88a2cd009d47d3e1f75b62ec9a13f2263205112ae1822ee3b24d2905ed45fab16d613092a5b26e4a58da14c3bd2b0b2204227524df181be4e8b266d96079ca54c9ee6f522950e9ba45a51ff7ae4c66e3e96a9ce3f838267dad4ebd457adec5c09e536a244e6b0d675fd9925fb9cc354193cee7d070602883183ca82235fa87aa7965e04ef2c6b8ca7d6906e5bd715fd9c3a6f1330db123c7fddc535305db98d8bfe27690912973573a8f7d599a0cf13da79330a1b5aaa5549212ad12c0851c1ad107579a2b1e36c34a98a12a214e7908bebe937d46ae65cc777971adf25b9e19a1d9f78d8541f2b4a7df895d6f573e795566ca5562f6120ffb7cf9a73e6579f2040fab9fef5efbea4d750c79993ccbc1851b098624bcab1c2e04c7878210ed4e0d4ec2e5f4c732b6a7b6cd98aa9375043e56e0d8d47fc99c5556844730a552cb3599ed24196df92751efe562790e7dbbfd7d8682e5e08365d448d163b5d87866531d31508609c5977b0271459fca65297c9c6ba3605b078ab91e5cde6685d979bc9662c49fa7428e998f3bc39e864579ffed6d58d37da861b79fdd7cfaa344fa344b858c89c1b341147340d5183eadf284fc48ea20aa051ebd7f7f01235b04ee937d367a1f1c2f50010ede94481a7d70ab6e025659a73c59446e8ab53843be041fc78e4f90f1ee9cff811825daa9ab4f678d3d8a746c83f1ca19ece9ebe42bc8a8c3fed08f5eebd64af892f9bd73289e2a53c07a1dcb1a29e6403083ca2a67685dba223ebf9fc6a4fba91d0241737a1221408fedb07595eed8e391b679ae8fc078aaabae008179d9f8798acd64c51a715d37e39cfdb6e92dda7d18ff91384cb9e983c9b2ff8aca329e1c2fb55a74c60c203af6c276cc280cb09d9f0737839ddfd08d0e97c1628c57ca5b53aff480a58f39d84f75af48b8726b5c05f980fe8aed566ee24173568636d96c600b8d9387ff09c7242a9d72a07a4f04ab8db2c55c31725661ad1e7a56773b754246cdf4ef1f46c8be45950001dfb8bfff3a18e700fb26ee18923a19e295cc4af24edb1ad1b27c912e6e51418a5eb4184e56bc00f383a5cfc0f36cdc45c3ac436cd5b6f8413ca0df274b6f9ddf59a1940d5aec17d7c83e5d9d7592b2cc3ee33f80394ddf68a7023cdc47ac718db46cb925f60517094c8a10ef2f7bb8639edff0e17eb08a724ebc5db4435399e6aa68f895e9d79bac39593c84c626ff7a33ce51df79b8bc0815032120a88122f0d2d7ab11a19db5887205944e3b151f98c6cf57b94a3695ee785e0d327294f227985e8a5eddbeab51c0011c2e142d61092df93813894de07f90cea657983296380573cb3eaf0f08f1719b63bd663c3afaac8469e9559d35be5328f4f9df519db41897c2763d3c7cbfc3d67886d6339d257cc796ec1ce9833b2950cd691e29deb08828b1a7c62dddc23cecb3c198587a51ea11e7246e7ef7cdba625616b13a1befcd3b5fdafb650a66c06d87908bbf7df481d5b2933f693df372f41212e515a9d5e24f3797d63476ed4fe4dd7aaaf75b5991d0957df5c7ff5f329cc4083960d437c0b6845e6118285edad3052ecc3deffe8adbe702f6a56d0c93d9eddbb1c68df5d8ed0f974c4479c3ad8675024ab60ef3ed20d0d5610b1390272201c6462eaec2a77b846eaf072dd24c94cec3084a767fce570f699b5c931c9e8c6a7983d760ef4f1fde507fddaf7206e73dc2d1937c0efec06440bfeb20838401892615c8f256833aa6baa2eda5be20a8f52f44a7ae925b42eefd48aa572e1566f734f816d65c803c8eb5d43d8599160e235c35f20649fd64054cbb3999174317ec7af60da84cfa4233437cc83e575c831874ea6c8a0388a4cec5c641dd2409b1931865b8631ae415efbbddaf081a512cfa9b53c32ddb42d9fb8ef0a275045ef175f496c07c2d769cefcb63831bd7d544f7dce525e4c4302e95257eab6bd6fbd385598c74521a4a934b65fba7dcc8e85bec8dd63e2307463309d7d9cd074519916c3b0ba4d019afb331f0900cce14c7926098cd0851ce93eb395efdf0dc87789a20306cf3c043f23441d8e106dff638468e182401688e39cfd6bcacb925bbd85e81f2a8108d7d881576053b9f9cda1dd4e8000d2c3e17e00e93a94d6f6a7df6dfa1e7bd1fe9e956e23475708d29be40997d62d98f9def1f42e6ddadeb21c558d1034508b74e23344370edc205c26b8c0f58605158e45a2c6f4b93146dba665ffc60c6df43d5d21e6203ae0e4827c555d640ddc02f92d598fdf0a1043e8b7990525de7c2c4da8adf57e1b3a6b657b847b7c54081ca4089ab1fcb4aa5be4edba9e2a3a66ccb0e9328e9373c3a63f4e7638a53e32c2c3bea6af65d55a71b19f95f3837d36ca272a77c2e60ee9587f89d0b58f263f692c9c9c4acea2e4acc203fadd5f9829347829fbfa2a7b8dcdd8b0eb8602c6c502593fab2bb9e380248e1a8c411ea167640af592ad3a94cf9882b23cb2b28e8323f8b9651ada2a8602e7a4234a6b5992f32ddab040fa12a2701d84120ccf9c4ec65cfabad87596c7d2a0c53938491bbe58cce36369ef5faee441c661b91c9cb340e0e4385a5134cec66cdd5d5f6f17989e759f6a7c413ea427f3ff3f8d2570e975321d0f9f2beb169da2e5b5293b7cdc85b03d6cc94e387caaf830ee94a9aefecbc16f81a5887e8ffef4ae79123d825a2092dca8781de1bee4117835ee610789cdad3999cbfff55b46d5956376a90b72c72bc6172830e977457bf49a75c5f07964a5d98e27957552f5debc730278b27b66ef20054e30d0dd464150e09c85586691f2c91123af595d260242f398dca312089e7b0b9a683ac07172415c70ff8cbfddcae66aa274cbe0f4ea66e37452bfffd709f47a99a47fa8ae90721f1dbba8d211fd69b553e0ee8b3ec872257bd4fb0bfc1dff2ce60a97dd7288498c40a23384256bbdd737af76cd4a5fa1ba09450232f2ce94f822a3afd9669b718b383880e30250d136e00e30f32cfd79f69648779b51c7607b4af0a01dc19d3a3cfca5cd198aeb53a1a24d7f2efd45b207eac0028dbcd4d532a6edaee9a49f497f0a1c181b9f0acd2079d281d844b23048601d92069bc89073c59e711a7f331bc27beff615d9d127e15f5ebdc7abc7f19bbde643e2cd6b7076f7f3f4d7f1146e9a25f49530b974aec2c09f3b135ab17c3427697e4036a2891ddb2a077e38e654ba173b8211391748020968f5f04c21d3305181d038bdd1428313ef4ddcfe3f4fff7f0d99118eec55c305c8cd934b4b955a1b9e131df07b65bba2f3545ad3280f17f9e442576b99df3073c291fa068e49552038351123d47866113182aa495a7a47099ab2e1ee21bb95e2a877087f5ee5d8e77d82d9a057e338f073ad196b355db746ed7e12e0971aec99bc7af505c7d5bc8530bdd99a3e6472e2198031df729c7c218c3507b553f335b357e3c55df08b89995c11804605ca630b215829baf9efec58a82fce15d8cd80b4b1f89d1d0ad7a3a3cc255d4ab7d0da2606899aacbac754f6a02213bab1aed13b9118d03d6fd5d5f3fe7aa0a153a2dab86921ed761b462e11030a5062f7bf852730ed8cdad3486b8bbd6807aebefeda658037b121e68980edcb081c9f5bc9b47ae30bc9955f81caf6c44262359ce9da463ec7479258d8242694ba8c585b6915f48ec4f2e79359d5dda1f32d752bc34ebb355ac03dce7e38acd19419732c4c2f837e18437be9e1b0e048fd097e997f1f3ce784ea07f6d0c07457df67be6e5a829403084d8effeb90f3ad535bff60b3b8f2c291cdbd4f813f7fc46c811eacd303ddc686569b632e5390017fca08e8b0f87e7d4d46973e78520789ff1bc55c9d9a354bfec524777ba8fc932a75c96077a00ff2d5164a7526cfb862cad7fc095614f3cbb57a69b86e59fbb970cff068d25612688e7199cc4b6c3a28014c2173a9e8512df47b0d7bf08626d428076f603fb368216c8a2a4d5e8d45c70ec72bb9c9f1ee61bcbb0dbff53bb3a7aaa83387c49dd0995d539723f477f98cdcb855d830e6f2402c8ea2bfdf380876f5313bfa0c12dfc2033966b84ca7847408de94ba6686313a17c0de77c1b3bd798d33627a35ce306644f99777ee9dffa5eaf32b6a3e11c4604001e0638a57a14d618d5d6cb5a743e57dc31f73e1eb1b5cffb0d70b7c7d09f493d9197a9c829eb588fe6e69c1c3718c7d79c32416dc266f89de47e6e0ea8653ecf23bfcc4dd930c17d034365867fdc0de75844bf1f29e2603e7511699fb654dc78acac9f925655d3c62f2b03931cfd47924b48211a225664cbd7e29e84467aa3754cc6948d68e3dd73418715c7eaceff1dfab2cd4f98154596c289a72106c1c8055f7cc468161ec701202c7a3727a27b97267cdf102f4634b3ff2ea5b51f6ad8fc487eb83dcf31e841590637045e0268f87cb833558886e99dea56a484136c4d77a8d7f7aac4a8f0d4fc8ae44c9e87aedac0d43fbf6e7900ce7009ff673899d116d34e38acc772cf78355813eb1ffc7ece221e6d608db7eedac1354145004ea6740381a9891fdcc5933b193164ed4bc9e1a2be95d74c2f55344dc7777d123ba165365a7b662b9bc601e743f604fb4f49fa51a8308ab0af9e8901b7badaa786c183ca5caedab00631ff0a6be293610faa002fac28e434a63861eead79eb37df1446e91c10b685beaec06f6318f070bb43f8043fc504aab65c5b3bedb4a90e67448e32a16b94accb951c456ff9a6d6195282d2b4d60d0ea37c54f6c0f2b70f13c7da03a353ba4089e6f8a8765e449c971f10cb548159a085fcfdf145f7363381575bf5e5546ecbb34cd17b491ecb097e9a73e32d38787c01c3f4bf0478c10bc17a2d3facb8b4623388813f410a2b739126b871b38b0365538fc6d8d4e467489bbe759354c8f04a6de9e7ade6924620a459c5d58f49ad9ae68bdeeb8862d7216774fd4e2e1f2f95e8d5b8c254dd88e07a30605e08d2cc3902b94bbb3123649aabd0bd9649a1f65805e47746ed1e61322f33d0892514c748b28f659d96001e6993ae8020da077a60d57e78cb8d92c4900b77b5bbcf333f0c92efc983f51f29c6f4e9435a86cf8c008152201a893f7f4d44643783b20ab66674bf6d1de82495e2171290ecf7485e37ac8fac21bee12bfba21d157b67db9c8b06df9c2130831ac6390121df6cc35594e2a6579689473c958c735e7de30625bff468ceb0b956b166145337d377a2792f325db74764b7c2ac23f374be60ca0f8aa36e5c9130decd983199a3e223da3795826354a1c31833a6da2ce497979d6efe8ebb408f0954464f5515d901b55d498ac6a3780a23781c10074c67d04f2f74d43290923605a68839b4f6907f9adb6b50b37405bdc3ce8613a052aa422c55ddf635a63962dd50b697add198526bd2cd1f04e8da33577e4a0565fc011fc076d1e095d923880438a2a5cbf7cafc93463597fd8deab4a72fb41538a804c17402e8db4fa7a59b2cf500be7b9ec63ed13f869fb707d62b761e9642185fa539ca09416eaad7de5ee39eeadc11479fbbfaef1bb8a510834f09ff0cc202303fd7729e9ff8c3a704030ccd18ec47b10aed2551790c9944430659d068e39feaadb18d0addf7253fb09cecbec1b060247381f51149bc2d5f3e51986072dd423dbc55cd1799d7d269298c12d6b8a7cd4a7a847534623aed2fc977b513d9f6ceda6e70e2775edc67223f163f50d14be26656796f83a65dfa03f1a738cd51269914738a26003549e3a232895e6fc1ff8b3b35db1eabfd09c5d8239e98400ec895fd0d655a373321f39761cfadf870febcc2653037fb647dc14adfe85626d34a9e73623f1492256b8dd2fd05d472cd64e9c3a784777bbe2a15fa2bbae5eae9d38cbaf2ad0ed9e78ec57e876c759ad1d96425cd16fc8cb1a07a739fe083ed42be51858b276b27dd1fd5037de77bfc83ce0009e2c1126d46d90b54dedb0bdf24d0b7da98770ffacebd8f9165e0b8da84131ea2c8aa0860d507967592402d571c8bf63a625574c22a71a280b1c9b98a9786c5fddd89c182c76d6786910ceb2a0af0ebd0b7de2c86b568b093b2dc87887b06eee1760a6c3f65fd926a1bd5665ef1f91f5ab9721a068fb244b5eda1d56444cc3a8048670ebaddb5e08c6b9a3c80a9a389cdd7b3e376b6bd52c98977b4d51417dced933ebdb695ff8f7e28bba954c635f0168ee975fd47374ed3be4ec641ef88e2e95b4640604c712f64f0a867f62ae014dd3fc76b93a423dd51b08b12a701b369eba625d22be58fe868fa223d45b8553d078e05c07a3458d0bd6e98b7841ae65832f673c95c8b57d9039be3e9b2bf6507af3eb9545bc9dd594bd3e9fdb8a3b4404cd9717f3b8158e2f6d129de55c11235f3be40bab3928e3db6bbeb0999350e6b423beb09dd336aadacc53e1ec6d1d07be7044cb06ed135f38e311b75de364eedc33f9b9e215db154e4936d2778b688a98c91c2d5a3114a6f11c7e4462819903d653473dafe9846d8ad823a1da8dcd1d88c3343158d62c7a1f4a95537596434a9bd6955da28ae96299a5b8263e8c3d59872ad5cbbaa2a88c22b353a2c290113b6f2eb468dc772c1eb140d8ca8493ae58eb55a45630390ccaf06197d1dd622bc999198ed7b4c5cc640e6bb433df1bf1a74bd1068f002c729a5d58c0d8ae320ef6904280d8aa22a3dd45e676b1154c3d0011d865ee115352ffe16e8ab18244804675a9b5bca072e0ed4507b13760fd60218be8c435237809729f7fababfc9938de7a21335672c815a5a07144d76bd949d1cb4e84d3e668c999afb27533f53c869fcd7d953d9a0b3e5f58f82a5b9542b7030b50f3499f6a87fc7b45dc9faabde6df1bca7bebb423febdf5159d4825346c5025056acc789bb9473f6734046be93360de9b93c8b3911b28dacedee72060f880c0c55071320403d4edc34edd1fe2cafcda8aa970766ae7a7f699136dc0ee1b3f78f4cd8272dd93fd38ca12d57dbbbca4ce32edd6d9bc6b8ab5ded9807cddb523f6d4947c7567df165daf4ee84f5f592ee9c53ba282f7ec14bff083673a1b3d399fe154e13739458abefaaae7d2c50967a23c39bb295e264294af4c8eb50b0113a36dde7c425b1b3019ca97b6ba05499163befe1dd7e6f30ed9c49cb5d5e4df405fc82c1614b67b91cd2b50f050fbeb11bb28e96b18d02932476c27a7961b2745301454ff5a49b5a093c0fe70e310056c73b5b9a531e01dda866a3e5ac422c6423f05e0ca66822fc620d2c1191f996784fe9280883c6a66644cf152cc0e66c6294d3dc871d074de3af1497ba5257a811e815113834a2202cdf538b99e33b7a7228d986fcf750f31f40050067c75e9a9582a0c64c857579e3d3d8814722ead743fa28c277fefe64c4127832022ea6677d7dc6e1c2bec8f4cc3a2bf57332bc6103d53cd0ea3b56eeee34167e68a61e8d352c8c97c435b517c643ef2f0f7372c8a71719a566868d83cdf34f4f4f76a96e9865e6c43f31b32798d2fe966ee64f5dacc449e39a627c5661cb3939a6176811ee9570956c6b441f6105bc7865fdbbc1967c8b03bcb26fd9925cc6db7fc8de006defd79d72bbdfd3775095b85911a9215aa8b4604e77c212d39ec48a88aacfc7dbdef4bda1627941cad789d6bd623c7c6698de2940248e0d6ea940823a207b6126ca92d5f56e886f3540e8dc2d5eef2ef0e7e8bae8f8e7567806c0d560b89e9bf8615695082756ae839c41ea5675b275b9414bc3d2240dcdfbf265fd2b638c1b7b6b47f359ab3c849754aeeef132d5f4c758a673b651e3936987dc460cc9e3bbb9e4262ca51bb36f104f3678ff8f708bfff9474b4f867c85d5fa88f0d76b45184bf56e9082552458ad16ec187d15bd29f7c91671c7f9f0db686d56732de7e760aa1ce39be979951a4f341563903580389a92f339685177cd6d416b1fc60e6df9ca2f511e73c2d2351246da0b6518bf7ec54a85c8b77f1fd82373baabfb396e4046b0a78747d7ee8bc20c95b8d98662ea0b81615a8fa8c03baa18e5dd88f508379a8c8c7adbd4c8bd6f5741927caa8e0b71276bb72a0af4789185aed0b9201205ad519417a1b7050d30edd5e73b64dcedcd7f7c6f4ee7cf260122346af8dd6a0d319dbdfd9ae702b9a05d7c43df3d72ba76a24ac1825cb6e56f101e330a521b26c09e70539f32839910a9a67f2950c4e1d188437f2eaa52012390a1f50411346b9a5ac59132ba34d363b9ec4fcdddce98238e3b48b8b3bc84cc3731db10a4174852da8937aa71ff91564e602ff1dc350077fcdedf89108ce433c22094a5be3efcf7a00f5414ff21a8399b95bbb79663ee7f6d32e1fb634da9fdba480364b606b267e98425f20167852a5b0e45af3c033349ec71406bd96914ced51fedff7a87231b5470511ef51cb8819b54742bd067fafa35a8c2d904285d89e6a6a1539d92bbf3089577e5abc5a6d182cc449318d6cdd67ba8682cc4dafe603656d06ce237c6f61f3ba44d45b5000d625734aed57af76bf2a20d15ea7786a82463783ad632e0b45188db6678d4d14daecb4c4d7e71b8a20595bd4cd09ea086d4213a13ec868031468202bfc509d68629527d16d53de7068ff994b4a86f505aabc36220ffaf8d6b444f9b225cbf2eb3859a25ee385766e013cb4636a8c8d39cadc405f487dd1ddad9b78b8318542fad7875b077d607301974f4aa55d5f826adc6eb757c6128f9935085136b6290372cc89b35dc81f1bea5c9adee96008c8ad3bca115d71455639e3286d2fa390482154492ee07c5cc86f0c289d2b35996706144f5e17b16af065109bd6640ea0ac2198944b7ce866c08e68b110d8a17409be6e78253eb3ca862db80ba83073fad648ae83e4e253dff4edd335ea1c6e1ad8877689525373d2e188fbccf1feb46f60c16ff70c57c2296904850e931912cc8f6eeb03f2777ea26dcfe8a79247ca764d2de638f99ed0ab2536d3d521da8fdb7cf978c534e6741d39be90248d99e01be939d058eb3b0715b6fd11f63c5b7489cdedf3891a4b9e229741f014c4f7015cdea4c0bd527e4bc2b02a6fd9ab7a7ba2cf214f6610abb709252a7e949f4ac91bb47b7742bd3a92d3aa8da4e49f4469a33e8873e4934025d38b07fe41db72428f4c4fd4472ad08b13207f7c998d4c47f42815eb0b75685691ac7b4ac878f5456efc29bde0f3c2cf9cf1cce705cfac9b73447c60143f0b37ed78890b0f84f675112ff8844014b79a022e541d736e0ac69eb82ad3053b15a535c34b189f3384e9c739f3790618c98e0b739da4d9ac37985e20e7275dd2b1e5ad2e594ad75e45ed5310314d4b7fab7d8bda3f517b57a8462bab84f374c5064f7c20f006332f0e337602b5d1c96520fa3cdd698de883b2939977cfdaddc9cc521703d0b8e87e8e80d6662548ebd1e8e77836905bc5f298c5fa33b889e3e137925bc516aa066484d5aa046e83f65dab025b4e0e345dbb297e71b6c0f77d4a8e247a97f4e51c397154a84b2913437d6ad7eac02cf35daaff33d3ebb7ab50de354ea45be4a46ef1abbd0cc49e42fa7283f2adf4777a3e573716975a90d63cacc5c53c3a14eac97a066ebfd9482249472febab3cd127fe9dc7ba42ed9a97fb0d0eee57c7633e0e6eaaf3327005340bf7ba1e86ee3bd5f142f90c6faacb915f4d9d9aa59ffd667a797dbf3a9e6dd3f54d750d3a7ddc4af39c4b38e4d67f97e132457da56f8f4886732b6a61a3fee2a8ce3542afbb8d7eeaf1f39e449e037dffd45c7af6b1ad9c25e7987284bec859a3958812269297dd4d43282db71bc953eb4a168710467dc0e9bc0bb15b6ce9af8df008f6843120c7f0199ee78f0519eec5590af3192b59991129f578cd9829a3d03b42819a9f6b7009b4e22ef6ccb84a504c6ea4e98f99e434b74b79f1c880f0bd85dd7f50a12d8f3f2cec601b5cd1777c2e58cea85032354ddce162290b9d540d270a57571cec7478b85bc58968be3b11303e47fae53c874d6b0d40f48b8ca17fca85515bf439d0d106b3beddd29cbae22b26ce62cb10ac4e3e123680667c1b718eef2b42ad13122594132706a9c28fd0695f0e29437cddb7798402e848c3a4dd483714ff9c2dc8cbe0e8e0702780bf384b7a747ef13355623f531a4d2cfa05c8a4bd5d8e2dd2f4215bfad57dde1c55927f810081370692f9963534166ae190ec51f8fa6307912a0fe99be21339b02739ce4e17b0f38a83f93b796452dcc8024cf82917412fe1c42359670c8b9df559aaa06dbd95577fe7824dfeadd872d1134ea8ca644ae83e97d68958ccd3ec1a8b29dc055639c3e93b6bc6e2528ce53432f57cb88707a093092af5b6c0313ff0c05718cfd9dc328eb65181ca979089ef5469fe5aca534402dc7d4f1ed587b83d1477cc8947bb6c24b881fb9cc620bd3d92f5a27f209b847ace90d9bc250a68c4a0217fb48160fb78fd13b9b04192d43dd13c1104b040e010a96f8f8b66e28779bd05c6a93fa731df7245efcf31af125432cd984946b807263b399d39886f4e1be4f81c59ebf0983435da9ac47b0641dbfa9823b19fe67bf79453898be42a173d7b711632574447383979dbf10b4295f72bd21fb031bb1625cdd6838a5c149a7c2bf79cb8d3abc8a5d7e23b5e26f950b722ebe766d2d61dd49ab1ad5bb96b97e87376e4bfefd98d9f6c4d6a2d67a494b43a3bd282f460c38edf68eb205ff9eac0a147a6df2a69d3c98cc3f6bc23bb67b50d11a2d46308c75ed166d2bfc6baf5cb0caa20ef95ca76c45317afefb5f37e8be93e3c06aae7c19a3969206078503f24b428f3cc4917563249c77224b3578f3cb44f0373cc74846e9523f237a8a72d874dc0a4ee88f6138a74d51cb3e1734edae7d3375f2fcb7c8e08e077eabc4fbd4925b0bf001f315c7ccf84d8733ad0a73ef3129b7afa4279e89802e3754ccb2c9242b8dc3c419fa0fc9d4c880494dfda6b318f8a65d9f1b8f6cd9ebed0092927dd558c50ae4f1b68b3439dad5cec982fb4bfb43a3bb2e7bbdb16e5eccdf6c4c3802eb9aab86ec52eae833c84895046c47f77b3d62fa1221934efdfa6eb8a1658afb55c2752c7c1990c086adf659c430cd1a9c21e38389ab6ff0964895492263b20d48d0342ed6471090fc501233eb2bd2deb08fb9ed458a9a92f39512f813f0385079c4533bfbfe2b3220dc5d3e3f0abf9f7156b7b8924400b6779ea2588aad29f902210d4f70904ff7ebc2658be773f8e574034d4fb619f422cb4110f148313e691dcaa7d91d00933e985f21a52aae7d67c8a30c6d2c941f0e282830e604e9ee0a8aaad011eade22f5919185358b8e6a3100b69440f4dc7d6219284fa5ec9ca928156f8fb5973407042660b8693322ab7d5de01150ba8a0857a5661ab328d714fe0b24230fd7df0ecb7c5a852cd8893a8a7e2aa4c47bb84a2faef11a9fa6bf616b7ce15cd3f1e0109555932f8344a814fcf1bf93e031bf28869a2e21ed1b6f31ca14aaa86605532eb7568cc5a02e0e6c20e91e97959853d21c75d8be9cfa8e702115eb8482f01ec7b704e42e05a6b392311c9978f887589ce4e82229a75287a65b3ed91813009a3718898cf9dc70b9d4188c8114af946be92bd8a6341df0ec9920e921e32f02133b48bf90f7255fb7fdeec450f2db25c73045b8de5627726e780e14cff20aa81bb3148af30f81b8e27d31f1d86340f6ce615d1bbec5287dc711ec798b82028eba4e61678409bef75e4581e36f8744625045c196da119bcf86727495ff9739d6baf49537b81c1e24488e63123e302fbcd1acfa27dfdfad3af4d3e6ee5d7a66dfa642e9f7f9d2ffad4ecf072d688146489a9933bdd5108caf8542e6d8bdcec587ef3c899f96fc0f998b793da09899faba7eb6f8de8bece8968430586482c642fde6b4427c7fbd06a4e1f3b2cb6133709a3d83a9cef4605d438bc854989ab506cd10dee1aae8e159b6e9127a9d6aa6cee56e5f998f8cbe87e959c61329e7175b8507ac735896651ab9458e04e8824adbbc7db5739423db66d4157744369ceaed853442b7588a3fd40b183e3f4a9e85ce419fb4c779d4b5acb1fde763465dca3dc6f1d443c9fe0fceb1e5201fc5f69dbf9916487938ce09fe89eee148e2de954589f248dd873c72721af3f3a6f1d764af04e3f9c43d01e1f1c4b63a385baa81202d7dc0cc0c413249548685864847cb6f29c8a9a25a852ee39977ce2c6dd588d9f708858eb6b10368c28f6a9006f567f0a084c75f7670c339f7d6e7dcd9a10ffe6b3b07b4039f7487f55a04ea90bbf3f70ef058ee8eed47197866f3b6ee1908630178dced47ab93cd0f887c881de05aa5bbd6da6240b9d287e56f763344ea199ed930e1ea7ec78876f2c66717529f553a7b0bd033b5db039aaf41f70f91548ff73379cf4bbfe9e2087ec0a15a70fea5d9817ac93a03656a15c967576283e5a3ea59d99cc63bacd22132df6cced8a0c71bfa8705f71de6ab3c7bfe27f646e98a70c37c1f96ab859487779663cdf39299110c13261ca1f08ed050845e7e7bf6b3c0e1bbaeb910501b4f7ee068eb75991e10109fc622877ba404e882be5221313a51daf35e429ff011429e35c1e738a3d8203901bb5cab00888a1d66c18ca0a6fdf08310460ba22c93c95729faa809d7bd61a0230a97a3b72e4d6eabacb11e0c06f5dcf05d201d7cd329678a7e2c210e3874cc878422e39e417e48cf9e3066f08270432e6e8a8deca3d356a68bde4744659d7c8aeb542a7cef03d63a4f884f7cb8712315ccc14602ef493796b3d66a3a1d9c11c2f3998717a732676289b99919164352a48b8cc3ffc1d7c0947ceff38e1336315a33dfb045a615e83429840818ac1925ea10289cc01b4db7f0e01e53c6106758a36e781c7ac96856704d4e3d983bac0f9de29237fcbe9d9bc9252377d2c49627dfda571e0700c54863641009c4dedae50df0836ed944f2afd72aa5d0c377879418159a29d6cf823264298c0c18aee0634d9149df1e1a1d37e6b57918853ae9d760953aec815deed4b6c120fc9775fb8d3cab79d562272a73e9211a8933a71a715d16917f359fabb8c37de36e8dc04f4883beac1d6d831ca053aaa78db5197671ae12d5e7851f468b7956c2c3dd92d85097cb1e86da9a39c77fff24369992155eed4a35baa71575d619e0ce7bbb8867791dda6a47798a1f3e06f4ba94003e11e149eb56cab331bd4c10760df23feff51158c475e13d8fa31f4c3e17c25b39f46f5ced35c189778f52eecf512c67ac271c4cb1548bfb71cf2c1b797921398ad56e075a345a72fcd0b14f771f0726f1bc821d1ab037d27832d7b1cac55aab0c7ac016bf6e350ecc7ae59cce864cb2eda12d4a948a954a34eda86a9f4cd41e0d7cd16dd0ee41108a131a33a72f00cbb8c142745d1f4fc8eb97537c49dd5db353707fee8616ac3a957f96440a2868adab4e95cde33e33ccbd63cd573f02564480ad33bec7637657c805c6734499d836c708c6f2acbe8f1ec248caaea5ffc7f0de19ab34f2633517adf891fcdc4ffab20213b025e54a268cd1e92e9ab3f6b309d21ee290e5514a6b3c8c2df161ecb9aab0546496025ad591a3193d35ed61f359aaadde7e242a7f0d459578cddc3252d43cdb04cba212be30c4472f80c04966154c4d0f6424e018a715fb05060fe7d2fe9c3eadfa13aeb489cf1d9a87210b7355fc134fdf3b03e33870a5830c7170720cf4bf813eef4eb79bd646fbb0b9f471eca8de48d8f639d7dce8623791f8d8fec1b98614e7a14bb3e6602d55ff037a1aacd38ded91173f99e75c5179f9f1b624c55ed5385a5f54cf3e701293a24a6a8481670364fe0964002e63723e150d0ff4795c8295f6f2b4b9c41d7ca829f95f5e3ca06d7ca2a9ce4b3da685e4f2731a8a2323a295cda94ba153e90b9de71864342a0e70f850e54849d22aeeccc3080df2adbfdac8c807a7de1e464e1f25f7ae87445213355532c79baa78f1025e0b1735ea289e5cba1fc575bccc0fe7a790325da40fe4bed75a4c1f25ebc73b263a14bcd02312134059d12bd19335547d0dfc00dd4ad3d247f551ecc2cdf490690059257dbf8907712343d4c7260a97840a0a216744fb57358cdee1c6ede07341f9ad0c709592efed44638c2cdbf848019ad1600df041e7371c0b29d2c429e285d92b580a7c9f50d31d95b33ae84cd964e4d59a6abd416bc788a8f7bd57e4ffcbf08f58a4211d46b7998f077d5481ce424235b064e60076de46021200e46f80c720bf8206781be5adf7797abf55db8481714ef5e8b194395c7599da2cf369a05e3f6e0cd196e1fccad6f9b80ace38660ce4276d1f8dcb55b2ea2191e0f38fe6ed328bf2c3148379a8f5d2a3fc479c81dff95d61082d4a1bfe510b0791ca1eadf46a2da0bdbd0c6b519bdd1154e0e897d77b33bba32075b750b7bf5b735b9273aa4a6c8e1c37b3040752b9409520973bb2bd4077ab35fe17491e5aa593cfa65091af1907cb9ef1c9ae5ee43ca2bfe708094e956f314bd37a604a0ca9311dee56e8af095879f8843e6c78f258259fe399554fc7b6c260338cc3b4bfaad22798142ea9e4bdc5121975895c82bee9464818b1443f38c167bf0852d420a3bf8e0d9e15697cc4013f22b22f42c93a87556306f146401bdeb96433cb0e36377c30f44fcc096ec20ce4116786ecc9858f923f0efbf7281a4e66ec0697c979442c59cb4f8a81faf5c22f19d1bf2982c28ebb253901cc9ee6628785e3de47818f2a159a72ee59174b798f8a3ac42ee24c765ddcf856ce7ce603e2029aefdbe3cb3aaf1063588d6e54cfa1b756faef3dc8e25263bf755d022ddedb3e6276527672db917e2404860ad3af9735a2d0ee313cc6c3f8b80c9f344bc41aa5007686ae70cede8f6592874bd79a06c2ca4b6a407810e2f29d935030be26b0394309df3fde6e0a8efccef34e7ff63efcd961307ba6ec1078208e6e9323325842c638c31c6f8ce2342083183e0e93b72af9d42025c55df77fed3dd27e2dc940b0da99c738f6b8576c4d529deae0e648efee44675227b79ca88dbcd03a969af7b9e84665dcde1f5f1a5cfb8cd66619586377511f2ce5b66b96169a8bb8a59ad3c31cba43d12faadfab99c84512f3964d44f7ac28d45efa119a80b768846463a75b4b4d19e49137c944d8fb5dfc07d1f24a492b6cbd640837cb840645f973391ba6b74663707fcbfe11eb153bd3d99f6da2775e4cdf072bb6771d5ecc13393501f5e64fd9bdfab05edc04e8411dfdf1286fe65e3251fc77741f7ed87d811c899250aa8fdc516ec808ed3f169b1ddda5e0f1192a343eee42845f84cb387360a5591dc0bee6ea2d897cf461c2a40f932e4120d7ee282b10d19387129a7d006dd4519336f0affc3208a1400c6cda4ca552de47c910e51401cad7b5ce3b568c35bd846ffb6d77205ccb41818c6dea149c57d60fc849be3964c3794b8711f67a430e08bfcf75889764dcdb1c0dd490da182744e23338b7113b9dcad079b9d40ce10c80f08fb712285f3b3e42132e5a00824dbef892ede8e9361d0fbf1bbe83d6881ef82a8e442999b40b5b99abe2540875dea78d3225b1f8be7bcab91b04f29b16954a0b84d3f59635d7707a99c30411f3ea8c48d8ceeb12d61131b7dfd0a3c466169eda64979e2a97505dd7624515cb55495fa73617294af10e68a35b647aca59e43158b11553905efbb95ca746ea8321debd7ca2ba46bfd8f03e34098e4787f0bf550c7e1fc595864cc61a74cb8346dc5aa8c212893b1e023a075a05e0befa94d7c7008b9f59cbeb2275c3b5550b58c4a58bc78ec14d2b09dd419b499bf4630fde2638baf7d4cb0fa3ec9dffdba5e662a5dbe512a2120963289e9c7db8f05d606373efd65c6865aca4487a32fe8f01fcd7164d111d36dec1975b305400bbab864e71c2e3a8155abdd1610cd0eb663399bd90d7d26d731fb5599648857b34b99dd04e957273049fcb2f3980dab5ee2a332e0b2cd56c7c97adf519d5191cd566796f20e04b809f293e0109298e5b9221d7ecefdc6cb2734b60b7ae67e49ee3ddb3a90abb3ad627244761f8a0707960b5a990f7778aef7d03c38f977f1d86d1dc861f9503f387a7be9de45d32c759670d9d17b8e55852fe22a396ed2825cba86998792e340e9934e96135d9ffdcd3ce9b1b178dbc639414e2fba6065e5cf097362b89d266fd9051a2b6f0116ff83c9576cd28edba329d3ddf31c23d6603160ead80311020e1b04004a8be1b1c63b1b2aa23afb3af3d9e953805f2b2e30791ac56b4aa69156d2664cfede5c600f0a4ad70fbe53bcb912aaddf43929813fb9bdf1c9fa021a897fa3a44f11c8489e9bf02fe581fad88b1af65571df6223b7b21eb60dda1ac5efce2d86cd24b0fc4df6b498019f3a6b9a637c2dbec6d9c6e5affc4409f5c59b2f08f78f912134d753ed04b5a47f64b544ffee91e183f4a11c8c13df5bd20f3d42cd1c07b02814903f94f6938a7194dc1b0a6f6d371b9811b50d96c20a3dda3fb999cb75b023c568f0119acf7b897c7c1f65b61332b8158221ba35395bb34c8dd8c8a8e824d8555b35dd666145289fbe45abe7519cee331dba686610843694d9a1de3674848d6bcbf4524b2caa7b1933c1c0019ef361bc7700cfc2e1899b0d07906df8fa6ee398e34abde2c02d71b2ebb2c01b704f38913e8d5d219ecaa49d745620fa1aaf110b563a12e4597fdb21b634147d441d46cb9c1e56d7f28bb41e9f286eccee3031c565119441658a3870edd6390abafb402739758422329658833ba399b9dae2abb51031cc1324b7f58e259e6ae6b5d2140f349153d52b1292bd13c86527232229774b2aa6e501194ef536847ca7de762e051e3462c413d763c224fed20f77bc165d75064dbada79c6ef2e6346e8e3d615e263bae2cc59eae5f7ab21208300834a011735acf17a42620743c011ababe38fd224644b964b8fc4e3079e7ae5fab782286c62834454a3894a40f8e4e7a60f90c1c7fc4a8ace499d28f6c099db207bec4436d81f5ddb847e9720cb5e464e3019656bc2d07dfa50b9db5b25a2b4e92974aa78af01aa3c96d3a37521aa0249eaec76009b994125306bc2847b6f38b0209306f2530793fa685bc26a3fd441ccba656af1f21aee3fc021e80d6d2a85fdc87b593500ced94cd65200455a1c5f4a9fd24edc7bfe5e6e0975aec0d34dcf5dbd29ed4b09be17b8520bcab460b2c22bf12113e2b699a6c155c570038a85fc3902dd136ecd2a86190aba90092faaccadc0b320c62c30c99d0d4cb87e85f4046b2f77517a835fc967a209f38a88609b487f4b6ed4d164cba9de7bca765005b566d78949d4e17dff5fa681d75249793544772de5fcc0c856ac8be2701153b92cc0a0b3a23dd15d83e6e1d8c90f845d902d820408e5e1485cf64515c3edf702f3d14e96c096b9092973cfb78b30fd5deeb871c4d0aa4cfa416419e27bb766d98d72806ddfaa4e19e82aef092b90390a7ee99619abddec6eb50e9938cb0898ec163e1068be0d6552198fe27069c612869ed3313d59fc60f2419328b041481ecd312d7f9a39a627d0a7706ad6f2287fcb92102e538cf4815a2318b526c9760b124f964962b8c54912537cbd98581711fa55ccd59021865000d6b8f0ea64b576d656cd4a4f55276f087195bbc5cedf7f38a3dd5a4f6b4ae898ca5cece4c7ba970bb499aa999aef1c4ea2d0a36bad2de423a8a93d39d226cd28a7664921ebe72dbdbc2095f6f28e68ef254d66bb290d924fd26457387b6b3a6bff92a2505ddb5ac878d9905ba4d231144ed19e332587a2dc79ad02c3e0bbc7e8970ef917c82711d2f4efcd31b206db2990abd064754d5312c7a45d93e5350760be5e891cb1daad53498e4840e21cca1532185f08e8a44d8ee47679ef6436c5e2063b790c826eaf0c1b6893a6e5d6da1d9c33db3273a1b8eb557ae3b0194ed4ea65e0445517128b875d180163838932586c668a96e16d1bae4da34f98673bde29f5e1ee0955339bc470fbcb83fa902708c309c23948834408db90cc3172bfca8a037a72ab5b4fbbc28e9479da48175a3ac1e1b43850ff176501fb4d20670becf4fb90706273aa42877c29b9d15c493d457d4be1cde074f1e67aca6f36dad937276bb2f0db05195ebea3bfe60af56692d04d4d77e1f9fe40a899bc559b6f0e0c7f3d65daa91e7e2b0d4db04379bae898b71bf9f07ccf4bbfbc90c2f5a57fabe5ba152625d98cce6a7abe4fadb8d533492b2a99b1550fbf95a65fa256542e26c3451a60f6752ffdfab77003d5a1a351ef7cde4b29d5215ae9379da05fee0af53603886727bef8a4f94832c36c5db1cbfe4f97c6f3d00b64fa5dadd95c7cf3fc002ed876d20280ce54188446bfdf17dec3818c03e7f42a97c23d3b222453ec1ff29366b0d58e22b6d9ce61595b4ac86413d94ae5277d8a4f8a567e751145db612cb0f89cebf2f874222971223788e23a6c918eb78dcfa0f08f7b55c253d602a989c5039ea2143d5b17fbdc6f1cf51b836eee484a99fada7295041fe3ae705a0479a43a8ca9656ac2dc6838a1be17c4f3de90201cb30dd833b9f06927ae8508cb6de62893cef9c9cd256bd621edc87649565bf685905b9afe07fb68d7976c161f35781e5557043ffa453691a2047af29d56412c91690d4f6a7a6947dde96ee5e9e0649628ef265f9c8f9a5e7efa72750b27dc9ec779b79608c725b4f861837765969da60cb97a58131cde779c9a1d23610776c8d9e469913de8067484ee242358e3a807d9c1b7cb423eac1848ffa17f7f4ab2c6a5513c809991643b98c9073d1d1bb20225aa57def144a1147932e47edfe3c947303a52daf709a74d77629235fcd8418e00abd9cd2ddf686df94695c30839e749efe7aa25c996de43406a803202b943a93dd0a014b67c99335c8626a5a31c284ef6054d8616b3d83082639c842e6f0f4f02a058be3ef33df1395a7990b10b641d10fddc9ea5fa06e00a96f6998b6381aee99252fc83e003ff984e3fe3c49d5ee31ec243869f61c2376bf7ba152555d67fed9fcafd555bf4c6011ab1126e96ef2f5ae308676b9b217a458dbff5fa29486c7003931494a6eeabc2fb356408d96fa230770a6ad6f9f595fa16148972899a5ca7db91439fd254c0c576529879c356fc4beb1d6399d8ab234a2dc47fe84501f89989aeac6dbf66c7ab8ebd6a5887d3735cc28ce916432441214a45abbf15fb808f8534bbec87cc50ebb2caab6c59318fb749a84a97c5150f0063f1c6e017a0a81b82e836d68f38812aeabf96b3877a3c6c0292f91d248c66fe3089c5bc42b2ad1977b2f259a6cf33cfd8afd9a9972375d4d9c34193743ebf33ade0329c6988293a29d6e30ad96767fcec3ef3ec9233890c8ef8ace49c4742cbe933f43c752f31c5d3f6088b217cd9f9735c73b94087d67b85327594af72273b533c737bd62992ae67aa7f42628f3b2dc2a8989a772e25f3b4c5aff5c48216bd295b89021a327bad604ca876a672b121cbf127edb54719903a61b7704a3893b5ca97a5703bfe3a2b9f987953819399ac13a45cf0a66d241433571b5b3c772045c68ee00c1a141a1430f236612a59bf49eed90783523df14882f1bdb400f765e497b80729a0971277ec44e4cdbecb22ec97b99b7d179290fb75985f01c10ab79505db7e364104d38d8996622a6fc6942fcd0885ab219bb3739039b924fc0ce74037cc31cf8a23eca5ca4559f54bab63803239b1abab4c213f8e6f957b1971c175d764debc136c434a8c630c3c90c1f650af15b065657be67501148e7497b8c2f9986f9c7f3195056c2a4bd9dfc84ab53e1b0d06c26ec94909d15f2564490d674c9a7918535c579ce5df4c1bbd9234d2c4f173b20e4d007e842d9ab64fc6869698dd289c540592db3adbc0fc06f22df5c36d4d4c6ed5a4329e70d7723ee5f81a2d3fade5329667929cba7d2645a931906f9691e5d4d48f1f658893fa084d7dd880a3ac07035e1fae8beede3f33d276dd3da24ec878f7d09933fbe806f3ac1bec741fdb1f01c510ac91cf5c940744f8430c18f80f092fab702b30d813c1f073193fc8b1321476af049eaeb7f9942c8b07154d813b3407a591b78f6d18ab77fc6678b00c0a9c0aec19504ce8b19e50774cbae089c1637e2c1e179272b3852f1718cd5e2d072b7f1515a6df0ef7e547fd216f387fef7701637c7ac2151c2dc64f77dbabd841962fb261ac1fce06f3ca6b4a472a4bd305491e00bafaf8404a25530c77fdf82ccee9eb4b6485f66a70ca7beb51be47645c37a9082f72fff61206d7fe11a1e0dd1c510c8d833d7725a1bd56e406e647648475bbd8a9acf435eee28d79d1c7c2d813fe9f532edaf981704f5605df7111a1ee4d86e697b16244725741ccd01e29b85efab7d12d7fe61ca3bcc9d95a737e3aa1774cb9bad60a4deb768dae29bc075355f3b5bdcaedb2a5a75eb27d59eca5ebc7f70e5abff698a67086b3f53d4000486f3548af0fc40e64d687d59987f6ff41231622992c9a5c9b48e65c05bec7dddb257c77656e064836beb04a4c116a6fee7ab175ae93cb5ecc39baf6db78295b296361e9967fb2ef9ea0b824ccbf7bf896bb94dffc532d668f9bdbb100f64b6ea29fb3fa6bb86211e37ce113505bb922b56c548297a5fca6450ff5c59844e353ce4e2fef00998d6048a98163f2487f06fa00ee119f8a233ac2d0cd189124b73a2be4334aca0e38afdf0837f5084f1c222bbf93c2b6c312cde5af698941db740fd7781941cdc0da7a37172fa29ed74a3fd013a22c8392035240de5d7b4d6af5001e2fa5768e1e31663edd5f65c75d14bc973b5a0abd09c17b598fcf37caf4aa0cf8b6a664be58ae7cb483027387cb0d8761be5d1f48764dce7d342de6c7aaddd47df724abf0551b86d8e9473e2188cd9964e3d8873a71c0df710b1bbb5b628c39ce2c7b2473ae5a6ffedd8a7829604e9e00cacd53f31f6d7897e26cf341ef20a7a4944b7136dcc18d359d9f6b437125d8101886fdcaea8762b60ef99a768e2f2f0d78a61e97e5ebfbbafcd0c9940fbbb6e8659bc3e51f1d3fb1f4ad562a5f94c2bd1b660d547a2f2dd1017097ef89ce604d6a97d366580065109bb4be757747d63777bc028f5a5feba60dc9c4dea36599535033f1770f4bd922bda63b5369fb604f8ff372de3edbf63ab0ed8db4c4a89bca119814e9f829dcbdd21a3c47a4d0fee49f32a089f673e8a73d59502646c2fdd0f2c91f1de2145eccd48e931d61537dfb8c6895258dfb9303d3136e6c6f5ad6a5fb952c7cf99eb08008a75431686bc1deb280d2af8e328b1167ed159e9c5b5ac37d175664b1ab6b450ead4fe114ecc24de7996e8a01e3829f4c7c1a5d37eb251303f31c7c644e60ff47fec269915034e02f74f77b6649fdb3bfd0571496f6277f614f78819a1f4890fe24deed5092b0f1be87ec5e56c0faccbb1c2b2ee6b2314b99185543ce001e48423fe3d23ce5bb6262ede53cccc8f4fe3191e99d7f90e9fbf94fe1b140bf78cc5372618898ec5ef364217d0a21aaef99950ce816b22ec367cfcccb24b23825c60f2930cb726c5d79f34eb70f685e769f909298c0b9b7431e368b4988137f5aaaef7f38add54b1d192c171949334423861cde7c7976d761aebb8c002314544e0cdd1230a4b18b6fe818f96fc2b81ce12deddcfbffc2a18e272a7ccccc813cf2ee2f3265d8ecd23c2e6eca1f20f49c495696b2b2c11e695bdfe783fb9bd9440c72c89c02c2ed2d484168f42ef040001b114b1f57131891563f4f24fa394e0ddb129799daaaa864df52db88974a95e42a3e5bb7dff25d00a70937ddac8110a326679ce8975ae801d22928c0c18649c4e360ebbfb64f9007dce6b339345aa82dac17d642af1b4d84ed3e74d34fd64d0379c064a56a7efe4149ddc926d2d8bf29a2d71ee46faaa636ad5d974d397fee5c8770c006e2be2ab98b63592ec1fd1391415285727e3c5f70c023e88632ba019bc55a4a8f4990d2274957a807525e6e63e2217db205617e436b7b3099a6bfab6a9299a84dd4c8e6fd5a9bb1e3ff116da6af4f7bdcfe5d277485e33b4dbad6dbd2bb1e6aae7f19adf124b3d7ce7a6157785b69a42296300fc45760d04e159b4d123cbecf7535853906cf177aac0a21748db8f344649c9e18070ee3c159dd892c089bb9aac8f5f6dfc5d2d9894fe4edf63ff1254f0ffac8f680b0e92dff7195fd4fed227a7d437b64ca9fffa989ab4e6c3bf8ffd1b4747de7d2c99e1ed087f3fb5e7a703d2dc45c8aedd9413dabde067739158342b8f45ffc886ea07a4e582ff81caa9c9cbf54443ff9297a35155d4cc93fe927d78a08a1f6aac25573fea4855cab1ba69404869e9b11f23aba2c45dfa71cdc6df6f8d58ac7d28e4a4cd07474b4c6e23c88bf0519fd85b3d82d5dfa24aad8a257728d347f766f5f8df375c714f7176fc2037e35c815f597180c7aeb35fd90476dec09f17a518bed55d4c7db95c7b261a5bc8e33caaf16dd5a27530312bdac5f66eebf1686ea43f50badecfa79d512d9f852a77dd5e3fad9a196653be53a9ce83f6b58521757d890b95fb3812d57913e20257ecd565b3dffd7fd19498adbdb4822e43d87e7e819fd2e54fb727592e475b9dab30f9d778374245a242f1797d923fe93ceea093bb0b20535e47bde153315c993f7c70894bf13836b6d5beb2c2982d96f617fcd204e126ba7da73a884f06eae414fa848718cc9cda5d615b6cfbecb6c7848cce121c78bf0900adc29c8fea710be87fbc6360908b19f9af8317c83459472b592880ee1fde3d438b29f3b88897ca1d4de41251c6805eef7c70b5b47f7dd526d10513295cb62dabf5d65f73282406e2ed60d45ea38f03cbf91fed981f0e4fff1d34d8a390c8085ff19649e2df3679bf2d7a936a7cfda0dabb6cdba9e8f5564cc216ec0ca947e598027ec35bc86bf54b6096bff5e5a376a3929b2effdf7d2035cc2021bb3f38cc413ffc64b8d34aee70ca1887dc257a16e55b79bea0cf25d618592f051e035ff249c64f2e459f686e621439dd33f5b051e8083cad61f91088b5afb8f9da6758b2de05a8456436b16b70b5e5a523ffbf4ff210a7218993ea13a1afd64e73a829484073e2b678f9882d6456babd45afb0e79a8736f2a67c0759e48240fcce592fc0a6e896307fe37850a88732ccdebff1761029eb09f11dfad3ae9b08591709f66133b133ed06222b65c89715a58b831164a440ad80db9dbfdd5f76f11c3a7d56cb4ffdf31663ab13d6bfccab2706d0f441b8d3d701dff4fd9033d3158aa4ddc4ed3108445274544503c397fd8445a349d1cc2cf6ecfe443ea11f0343cfcbabbc95bdb046e3a916ae4e49f3393269c0a7311673183938ab0dbe6a5f6bf045740ee7d99901bb623d2a54e76caf047ec544abe56816aa01707876a9bfd7d9b5b7983a25b23ccc321691a498afdee60d081d805587ccd0f8413382530c398108b083112dd05730c72bda63b666da3fd4c85329ddea46f2cf9bd948042c0902bdb14e73186915ba2edcb896f2537999c11e1b26a794e4ae5a0a7bc2d7a5ff99eb8174b84b20c1212a1894ccceeae96552eb42584c900337f61c260281711d32a5dd6ad241cdd3d3e07e4eafef8d41b71c0c354fce0713bac38daf8976c18e1320cd955cb4286279bcf55cab0cf06e839823a68e8ab107ccdf33c13297a44896b19a73ccdb6a961653e87a68889344dd16d9d48e1f9f60c609c303a84d286a5bd00c3fd84e6722b63b8e73213c37d11969ca28cf8c6f62ebf91ba4d7c67cc9d91f899727df05d4d633b6dd76f01c98078fc9e73e71fea393eb1c57f2cec9703c8d4f53bafeafccc76c5b8353329d463f9dde069a9d72a2f7a2705dd0844f343c252ab5e7677b49c292fa4218d53c17ea8329d0ac5bd3b9164bebaa314ce4f529a2d9c50a67ed9a1ac1c9c5f028cfac2091438ad2977c67e6b9fdb1dbfa3a58e705efc2533b0e9bbcdba9d32c58bbc27bc17dc28d1f4dec80ad6168f5611068b0ba65b7b89cd1e073413b7ee3908637762337979c3a97131f00d06953f6d37391add9a5c91236190db51a292bdd5bbc8543e256b434c64d4e480a025167e9121e8972586a7b2905849755cc0723bdc56116bb4a9e2f7b2c45120e4f4311c4b2103e370913dc0324e40cfea951656f6ae23ec971972b6fae90f1086203e50baf9812e8a501fe9a21de1820a6ae6a71f568fc58595fe3ebdec885dfb03b4690526f85a36e5993f8dc4594af312479a882f109db42c059b226d70aff99e7008291d5dbc09409be20348c4ab229b77ced6c2ca3345482318677b64959249604a2d8682073ee5c0e054d699ad15b1cdb4d3b08f0c56bb7e1d2003ec636821d13f0b75b48601d4e3ac8adb00ec153503bc4a02a5b16c6007d565128b07f041078c7ae9bc21b608183b7572e63b0f97d03a5c88e984cccb2e87e37346ca4cad797232d0d330283204b0de6d5fd62e76b9f380441289acd45ba4a96d99b26f958499a850ce10bf0c0e2e1ebeae3eecb36f7be9b71d51b4b1e70d8e2bc47228ee674a5e641a8fd309c260b18e53924bb78d76892d7b2531cdb2d143bed5dc3817dc9bcb8c01c149c266b344a420a3fe624efa2c2528d100ab1fe682370ca9c507ec50b5dd599a31c9194bcb20136d98ecbbb568a724becd3c53078283342cb63b7ea390bc416e4a63b0ced46cc69c7bb40a2cc3dfb9d8e36aade4dc700d5c9790e6fe64de5abd5587f6ac202f3dbdc2dd5f18646e43e617d8a375e910fda83007de851fd40e64899de7ec5e61da82b48e3034e70685ae0d086e7d8d9574c3afe0e869a0383747b8bf7a256c5f8519c7ce8ce4e7fe09db5e976723c2e0d7cb36efe6bacc1ad2adaf24391079aa12a5f4b0d740eff2cd63d65db02212ce5e8e98d4ddb55ab3bfe0ca03d0eb221584337b6e19fa7b072b3f12de495eb8137a44a7d4bf1808016fb2db58925c1c5c5a64f9ad8b51326fad2920cc399bf17e0bec219cc74c86c909c9d78b0a82429e781195cff4a823e1f8f6a162ff2d02de7e5ec07a379541f94fb1ea8e70d66c0c28fa12f8809c5b78010b9063d7fba940bf5dfd6d9e3e73264e6e0079ccf0cb4e8c6997759945c942324c80b08d90220a46b38d0d3f30c6600ca993cf449b31b4455febd6b19a7cfc55b5ee1bd5da84ec3478b7f80f55ebe21c8e03ddd03b3a452392132c2f2853ec0f13d6da2fecf7d6e2545abc3a9ed0de76be2f1a8f7bda02abcc3551855d7ae49e0cf8589df33f087efef5630318fac132cacad206336d8f103fc499a36fdf85bbb4aa5b4644d3cb7b296b13688614f7b0203c5de788e0916ed325dfd696832fe9910aab2b216f5164361f1480dc509e135eea5aae7a79136ee0aca50feb5277cf926802148813beb79d103c782c0fd8c6bbd392d15b933021bf7d9431ef000b1ceae3e253de1693f65695d1c1ef217fa8eade9c99c062e149791d545c460f8f2b752771d4fb6a0aa6ba898c993764ce959bca1a5e708edc19f56272a284edad5a5275e76d7707880e6e7fd4be4703e6ede1947b202090a9a87d4f4d9ab7a772ff8d8f11e4ac18d736a434d46c4c83b0ed30f46e227831aae117029f78c87280cc1902664c8c2bdc8368308f43b7fe043c916d914fb9221f1f0c50bd209a66f7838a0e51a4d3dc332a5b0593f84431a3bdd30bf8711a061d9d625a8b76a7d1cd0ced549620a3786891c386a00a9d31df2d0c71775522f5eab3450fab48550149d63f212eecd8048cfb88a3095ca16aea807bbeccea18808bfcacc18dedd491fd3b68f9c90a10140812d8554ed40c6e9710032acbb910efc00c466e357b05be8b7e2304df2ae3e47debe54634b755acbb6f5e7feedc4fbfa02a72c76f34f8817299b8677d89d6f5d739644637917cf31dafdba0c63dacdbc90582b6c35f7e4155648edf38f1033b9f4b3ea2e4d6459d9105a042c5490774814ac65f7e2155e7981fd890247d2e797b51e7b00e0c2bc59b1b5d20583cfce51752758ef8812919baddb53413e5c01325e62d80d722081f27645499deafad415e89bbbe5f75f223d1bd9f56615b4d8d3ffde38a7e43a66037e8f24ebe9dcb52cc16b6df5f0874884fd9c88fcce8862f887ae1b776d5f3d852fa4dd1e74f98b3dc70d572449219cb59339134199257788da57db3703dbc5a8e6aefb0776ce44f66f4984dd890a41daae7b1a33aedaa4c8cdeba5da790d72f67e7de96ae1105588a9c9bdf8aa8083beae4eadc6d386adf67407907a9c94e02c0ea9d8e03b5c4d59504f2c8fb02862a5c3dc835aeae10eaa6b687dfe57ab5966f29c5e250e6062bd48574a5034a6f9b81b978d4415514ebe6ae5051db7c720a92f06fdb3cc3a5922b9592b1c3f67d8af3197e3cf40cfd0b150f92a85b3a5cf87231d34695437a4af4e7f0944d649c69b83aa9039458c478eeb3776b122ede01288a4ed9bb2589e8cff7165fbfa9067d1e1e71e897326fdba1bddcffa6cf69696c86f988ec6390899b3681cd28b64e7fd0eefa73bc3f80438dde37f5cca291ce080fca09ed62efbcb4c3533b211015ee710e031030d58c44d8fdd83dc29252d695bc1f50a9fcec4d2963a83735c69bea36caacdcba423d34671664045738fa1f7b0d23c8861ddae7b062fa08828dc31aaa93e0a4da38689c92555fcb7c530a91c31caa2cda490ae2a539dd7e86ddc4500481fdb1328374cd8604fda20b94d0598d61bb0aa90125b3ff3e1b0f978d815130eb243af3a5a7c26fc209681c7fa614c44b0fa615ec0932e0d3e5d2a25fa6b5e754f44a4f89fa3e68177b1bcab13618790af2788d0ef661b542068e4f0cba188681bcec57ad1327f1e3274e1da9b899ed6b56c75cd3373b81f4a974e7a83604eba602abc02246a193d999a7a9f7eecc7bee51ed56edfc50b8913548c3756ed1ee1ef4642db5ea016246fa62c53144dadc6e83cc755cb56942346585968913db5a5f4cf90063f41033ad6fa7f2bfa1d99eac812d7a94ba9e1c117f172954c3bb4fd37007ffeb34dcaee8b6373b27c322da736bcc8c74401aee917aec91f195ff8a835d2025e52a749e8dbedf4cabc470b56a29a748af9cc8108c819e9ed1a4609768e71b6f9a6c259f20d861cba4269cfdf65e3882d6c96642c5f1c6c93c1fd449f0ea15b187bf97b67acc2732d21dfce106704ba5d4c681d83eee3968263051a2904b58e5c8aa1eea8ddb9ccd42561f4d28e8531971d3f00db5956588f92b795219a74245ad02568c0aac2ece1692675e5cbcc0076ed21630643d2dc99b4ca7437a4255da3984adfcaad46e08facf2ea9a5e13a254c683bc184fe45b50c1360e614d0b3cd097ad46181cf5211eb727f5421132e64b3193bc2688c76036bfdd88494a47f3c9cf063b86bb2bc9067d553d5145f092a6c98bed22e0f4dde8691d141f11db60d610206bc034fa0efca13cdb70aeb235584e75f21ae2f9d25a6520270bd223443db675f25d23afe1b1d4cf96a0deb6502b4bd9aab8c4f63ad56582767037b44c7feb56ee8169b8c66137f645c19665a5fa8c7f43c8957d159af1e0bdbb78d1fa04898e1e587f664ab38f225a6589e8f2aa3882f290a4df972cfe424b06b42f977aa3fb097eb7db48594a125e117b09ff70570534b58f28dbffc38352be3842822833bf1bddfebadb5f510d8e033af43cfe9ad50df4f0e1fefb7e056595a4456b4a28dee5e1478dfbc5ce547eca1a379808d27429b62c958f0ff682859ab3a736221b4e520e3bb6463d21b555c4fe6a4f2ed39e4acf10ec39b3cadb73de277c17d9ac131a7fcc0d9fcaeeb459926354a68f90423bd08acbc12ef5a067a160d048f5fa1c01bd69203c9a82a948d0b9e13104c99d77fa3095a1cb8ab6269e4335551575c41737e2c8c134b30c55b6519839468520059e78481709b7308647b58d07320b81c1418f465b2e0dfdf89104847d88bbf3a0b7e7da17c8b3cd0f30d1f44d726299a5c2102d64a2a66ca2443ce32a37332b18054f197ec19b4ab9eb7c35337ff47eb982ac87f308c15297e275511430433fffe43459c9a615e717373b0ccb0b1eb1772a2f2bd9862397f5762fe1056f3e7f600e3c7c2cdf78417ab63115faae0d81c551e31ffca49c2d480d6d89330d3e8375a2a01460033af2ea6e19779fdb7f956274a0b3124842e68f59fa5160213985784e622052a74856ad95773b17aa38853cb08c5b3f83c53594cf6845369d7902be61af6d45facf87f3ae8546041e2bab1c1fd76f41b69ff16eca147c8543854464c8e51dc5f9d833fd0f38bec47f98d81a8c1dc13cc7ab0e545b123e95795e49e7dd2c95c441296f10457ab678f379d67c95ca4b9e7dca7e7de58f41ee6b33ff316fd2680dacfe5a9f53b20a00df386970466f485f832bc2b8e1b22d2b29f23f292ce53ee01a7d7131ab1c7918df08f3d5dfc25bb5b8cea63987f99cf7e2229073615ecd1fcf913818bd3b28d3871b956feca0864283c62fb4f63d648c6cc707ad42976e175c98befaf9c1e76243918f6dfce7337759e9305788ac0478a601d09b721b7908bfff988b763cb9451df916758bd45a868df30dbdd34a51712e23b23aced000cd1dcc9fca7b04ff284de73ab946fa9dafbe7e4147119597db28707792dd7f0c50e724bfc6d00b10c902e73a00099881db5576b5471c1113da9e2f4fd406efbe952e6fc58ba9cb9146e4596b88ea60d071238952f6b2cc85f721f69692e9e5110c7499a258f25d7bd37dc470d0e65898836df8d640e72e027dc7da17c87af306823ebbc03a8c17324c43753080c1b1d3292c9728c0835e61ec846a8a9962c176d14c93182087a731a7207fde8b305db18b9a5e7d28034ab92c26d7f8bdbd36de2139e4a619f709b62d87e828993a028bfcd260ef0c56ca19e5a53327c513ec9438e9229444f6be84f4bd273449fc843e637df71d3efb8c27e5aa7df59fcdb3b91efe08e22ca905bef7857efaccffeb4bbd9fad63bddcb77fc6dea3bb9cdad777ae9771c613fed0fced974b339fcf51dfd9da0d006378e12ea69821f7ffb4e18a7ea368d6f7d6720dcbb494073b1bfcd21c666016350aeec204f92a6bb8b64006c3d4e3ab71e1b1ef909e51be2b95a481d5802041c3b57b9919a87e27b79647de1993eb624fdd3e3049ec4041753a28e03a563c086fedefadfcb0d3fa8dcc93e5bee96dabf6973c11b6018c2a4dd631ff089fd35a733f6ab70633a5a0245286813b9a97254204c801e99363c7288df81da8f6d935e0d89446e9dfeb69f71f012e5b70f55ca2b73807fa395a4143b819ce5a86e5d0e6ed7fff55b0868cb2bfa96233aa215b2c985f21dac7b9c106c54c5e3c48bd84e7228f732c7747410f581d9896ada776750d6e6b46ddc85e72fe79a864427c984767c1e1d5215d4522eb8e56c50eb0a75af4b75b9279c08d19f3dea3367295338b03528d52deeb36698fe6a7b290b5cf326f758de11bd8ff3fb80a1c5bc2c34b9afba62f8346d91f08d58ebd438538a4c85196bcb4be8aae52a1bc92a18e4ee9a9c3d222757cccbc84ff88a5c155d911d3d47889aaa63c17461c72c007aa87f6483fbdf3fc1177c6526c75f3e629fe496d9674ecc9b3401d4633f446f7ab3295b55f728b2ef7fd3fd896169473fd073ae10833d97072b5000fae6614c2a9737e5c2232e7cce2f81ead0665b708567e71c73a97fcae9a79d35b696660e98ac0d38db7afbb931f403a60426a916c325e6aa0ad2930f53ed70ba4b9b0879e5ab58e65880081896721a914c17c816ba6bd0c43635340f34ca92b0672534a27e4b5f7e7fcb77c5eb0691d4afbb02e9942fa71a0f24fef6f46f57b8af86b9e30cc4422b8d06ad08f5e695d419f556452dfaf18876a4023cf93d8a64526b79e3b62b1cc298078f02ed05dedd116ba5ca15d46d237f21b701ba538f18d89c17664ebc59bdfeae76f5454fb801838d03626b8abd88a90fcc48c193e99ad2d95f735aa5fd357a1b87b786f7cc5fc7ad04dbc2060d4b660526fe668ed8bb0659fa1502d73ea9579a6d0a663ef011128cb520f4ba27c96a90e0ed55113a5ba9e3046d804d3bf3d25dacf65ab77b7f4650202a526408b8356f6b3098780bb0f6119481726b399c8f75fc1d56087ee48335b11ecb5edd9896af13a441038b988dc48a47821c10548695dc19e4cd8634203cc41ebbbe961edb627604c36a1990765b68db28aed4228fd2f3b105e6b1050763811dfe8e127ed8e33a58b3d7b36a42f9f43cc0eaef86642dee573916059f1a4433f003cdc82c6f22dfe01ba74f3bc2c5316d9ac7c7aa3e8c261dde00ca4546225a8385ad17ed99e8120c839458ebb805ee5cb2c1743acd30c9fa524fc13af1dba8870d77558331249604d118fe1344a30dd6734b2082b5bf2195145821cc5df2d15ce163265d91b23018ce0904f2cd19872bbba2fbacff876cf0e74a016c2c55d207031533cefc961bbe62665f6e8e372b3889f0e1b80145bdf5b091771ecbe5f6ed9d7149309a833941e9f44b3cd5a7916dba4838ad107262aec61f28302519539cf23993a4cfe9779ac4f91dc1f8d69c61b7000d3d45490f5a3e43d2fbf0901eb90213e0ef4dc1728cecc629d1ae057604e4e93e5b18dde98ae62b39bedefc9fbc7d66f6e9e913a9673c0bd856e889955ca95911d0d2fb3ff6a438a980ec5ece5a7f6166b9f322c23088f9360b82152a30cb72d6dd3e8689733a058bc3fd814c72493adda28474bab0649f93289dadaa97e1fed7853cc2ec72412ac69055973cb72d86578496dca2793438fff230bfd45ed54dd8b209473f257e7ce1ae472cda52f21d5ceafd6284c49d42ac77857742c17b1175464325028e2d7283bdc254a2fa1489f02dd4de5a356f3cc7123cfaeb5da8c02a566e3cc602b979ac1b5826653776699a0611c79c36da0839015064addece8f841dab499ccd622cd6b1e9f837d825c7a2db52b94d2a400a31db2ecd9e8e2bf417cb724b20f3e2678354b781bf632685092e5002302e3bc2fe6262b2bf5117e528d5d9d95ab175195f3f4ca04e7f61fcde56395073810ae8717d895454ccdaeb6e47e5cf38d93b3b1dd48711982ee75984edbfc72e03a33aad3f91b6d015aa260ba8570e31570f0de4c377cbc88d7d803d451fb5ea834de0e4647b0d9059a5fbed790ae7dffbbac8f5a230171b19075ebcb980af22ae70b87f46eb82f37b064e606d4052d68b10d1ed552195761bb0e5ba2b7c71b42f500004884539b634f99e164c6737d31110a26f60906ed62184ceb162c13ec9508828ccc52d414b63f8d466c5bafa8c9e9c7b647339bb1185cc2460a7154e96c164f138c3d8156d61d091f84d8ffa198f6589c27942798c9b7493285c55d40af36dbc7ecdf45f856de57dc438ee78564605080a539c52be6c60e89386e480c1a54ba503f8e2be67c6cd104c22fd614ac2b4bac39c02838c5e7b7a954f76c8b39339a0177ee6fbc2f565eba260dde76fa6f46581e8b25f40d79449bba0c23dc3d789d6b5cab7d22ff0a421ee14f90c65a6279c582da0a88c96057072f2eff7880936f3b6a87cc29bb392fb0642040981ce35d94506c8aa428770fb79e727397feab13049945de78526b0bf90d74be65ff8f9edbdca515a9f75bfe74fa458f9bbc27ec36de1ede16927abd1474cc7b1db8810c0b32251c07d05db9dbed7fc98cb43a5ad0fe23174ba8849f00ed86287ecbeca5e56057b8d20c19b83836e852faf5576fe3038a9dd9a86c10cced2e2b13f4eb31b43f1a8124b9527c47b7884f142716ccf0e29b0c9f3657e7ecdcffb645772968afddb9c85033472c64f4b04b080039fa663f8a42979a9cfa401f62c5d82de57750918e0feba0e0887edcd1230c048f2b5ff0433866e42a6ea5e5e026b65bb343c073739f4865349ded81595910ad5db9e77f383c929507a278896303de668ab500ffa501818b29397e08da6a66eabfbb2d9a90cb4c1c8adf1e16896c39456d0eb737871fc2d38362083ecc42161e7603f46e878661be0d5f1b73a31f917fe1a90a148d68b3c59317958418d64b541bfdf979996938b806323b546d23ce1ed127fae58347ec22dc2530a7287a807935e34f0093749857202a1f87bcd5f5e2ddaf977b142a64d20d5a35eba9fba435f4f65e02d50f7be927d7043fd1970292a5060c2292c48b226a6e1d70da59e3b47a810237fa277b2f55385b6a799849daa17416bbed075e9f8ecbb2175c39330d2e73f1a68942fe768d655c7ae58e7aa929e33d856a1b2ae2aac80c35f3560eaeedb8a78c1aed17e389a76ce3e670cd4a0028ab032193c07cc33e70ae5dbcb3d87e3e8075e56b5367c275c917d43cb9e6aab265cc116293feae9705641c76f79473cb9cb3a4db64e11455cea60bb39ab40433d336a6dbd006aea2f0f97203a0fd119f4acd352073cbccc41e8ac10508617b2f03c435a2dd9e2a65d98ee8002c37c6250db7991ef94104775d8263bade806fa25678fc4b135d7a4686ac47fc30f8c0050d8792224fa1e7e763747543fe822483c805297101151ee4a4fef0877e4321683f003e3ad7b2992c6763f59516849456eee6e14e0dc2f48bfdd3df6a794fe2e0626e2a116de98c5ce174a5fb2f10fa58b8d649a62738cd7141f1dc939e4900d91cfa15fce1c57b85bf5bff7cc29489860b3a7ff9c05e6e5af02b3aebec5b20928e2465b92e3d4037c92bd668de905b0a29606042de971c87b1bf94144cd82b7e5e4c8a13dfe0a5a8e18e29ecda6dc2c2275e73e59e9badf0e88d41c4c7d72a747aa3ab8b5f24fa7cc07bd8b4ff1083786f0ee2c54c436811cbb42e7c82c4e6d20e7ec0574aab3d2e290fd88d9dfc9a70d7471cbb90c38f993edce15f61e88a954a6e8adca4eca3ca69e776c860ef9fabcec2079a092de4fc5607d73a5e7483e1bcc5924d75d5f80421cd125f71921105cf8940102e4adfaeab9bd18d61458bacab2c00ba88a15cbc6a0feb1e0fceb6874856a2422c9a484f48b35203306531053c57d4414ea7f3f9688b7e0f9110e7d0bb9a695aa73f60920f2eb62584c5bf6ed4428729af8f285ddf517150e183bae198ef320512210bda9d8ea64a70670327c9d4f3abac3e632c0eaa3da8f8575506bb2e2db81bd5ba445a7c237b32831c7613d7392e1bc53058e46c5614e3b63533ea656376fe97023d33977409a407709ecf5228cc5d8b170103ed27ddeb70ff7a637410162bbfe30bd9b74d77c72573983a444f686f65ae6d89145924eb4679808fd85ed1251aa54f2b6fd5fef5045a66faa6217a43dca15ea91f7a80582b07a21b06562b98006d83ded9081be235753f783d4e4d6297b73e56a45f9e1d606fa2fea93aaa9c92b6a8778a12e2b702ebabac94ceccdc18d9ba661a64e35928a1c5126a3c4f3bc46ab2a2723e4993eafc898bb91db41de3b13f6ed5d7c01ee41207454117a1bb457dc865acb31f669a1763c3726051ecb1d962b732e25ee054fb81578edaa54c3dc6777a5c07dc5c1b846d41f1b213f78ba317d6b5685cf053de203d1eadf639d33e35500f9b81787edf4dbfab437d00bb65b658a812505a0b51f67db24fb483dc508c6cedb62265ff23df1e3320af06d3e38559133c49bf78bcf29773f0d33d7a60b5f714fd82d55d3c29fb56048788882bc072af8966704706277fe5e9c186c7ef29c7b6247369a237a4df0d2dd7af3dafe4ed5aa110b5daa5e8b9d4c57acd38c749136a02effd30ff41946ea64d3949994ce3e0dd18bc767ab997700990e20f7fc562a278c1e2b3e96549582a2c5f792670d6b8dfd4af10f036faf2dd6c77ea16b74c4e460c35b543ba58fa71e233cea53e65d382515faf2cf080b7a5f8fc0086134ca55037ebb4bd36980e3b5572ea62cadc680a77cb958e2f83d15d3baa5d16cb67233e14404044352f0aaeeec528503eb9e92cbe998d6d52873593fedb0de7db26b38cbfba0dff803068423bc86227b3753d42706c5431bd59b14d8e34d2bea12aa6e2b39a47a30ce7f0a75cf91fe351ca6bd320eccf1928703b817fd3236a1c138ff2dec08baefcb9e7673a00adad60eac3bff5ad21305f8d081d8dbdb2a8dd15868424285fdb6c7e88fbd6845a10e3e9cb370a95bdeba41e26e7fd3705276f1b6b72dea1dd2ee030c437d34c8d532aca73d2eec96507b8975f7892fdf3d9f26c457b490cd269dcd2749cafdbdd7a0af79c3498b202b7fe84cf8f45b1ceedd68c3e85983b3673dc1ea84cb4b7d7028e6b57162824cb2e90b89ea8823f98ee9571f4b742d09acc96a853c4f2e7a3b87f9d32dc0373993734c62360e7f52a7ad91c033952dbad887f2c6a29bf935fba13a594d7a665cb38ce6ad4e1206d3ef5285fafaa7c899f995a7fcbb503f4ba618a810ff8d7a2e03b060b098c9fcb7705e700ed1041f03e597b5220a7e3543ed2026961060266b692065683520411be9266e0b8edb043cac41a1e28394c052b80103569ea4b7d85f45824b27448e0591962142aa40eeedb66856921f5befae8cd1d05cb5813b09732ac554749f0ebe65b07668136bb5133158b97352c32daf32c7849eb730a1d71b564e97ba53da56ad4e08c533b96b7220a5fea7d06097794fcf1262e48a69123b441ab5a0d53585898a366d3de2a10f576cbdc49629373f104ecbf2b7f2122c93e423cc31b3e9c6c875adb05f3eef89e16bbe2f9e3e0b1304314f430956d020e4f3ad58b411e48c97eefaa8a36b1f9a0e849048a5f7bdd39ee03b01a0f30c8b20404c7b2b021e79528d99ee8efea0495098f7f460f11b7c3a3df1c65f18db7abf98519b74b7bbc26dc945e13f00a92d17ec33486d2f685866f3be0d52ab42c5d0b4e70f737a51e201af9133562db5e0efb4e71be7368aa7724f9d3fcc8cb6d722507df792a48bdea241d5a7cf1a90b51190f75a96cf6af4a2aefbb1d3c6b472e6e769a5a7f30980229e166a7d3dad1e06f4b5aec27e2b06f188cec62df105766b72d54a39680bc8bddba3194d72495a5e0d8c64c334ab5b573f35a30e6a7b2d1275edef097c7bb723d42b6af5984fe503ae5a323f149d8f2dc5f03a4509263a319545c62008efc8a63d238bd330bad39b56d86e225bb1b0ce8245943f50732635faf4374e26abbac8f757c8aef82e70f60272f08635d8706f4355da8d145bd8b2c68921904aa6724fa2d7441ee8ef37fd544bcbe754d14dcccf6df9b91d9e8bfb7957f4b7d6b19f82196899fea724ee09a672bd857c748c8ee8d5284cad1baa439499823b9942920dca59733d679afe2a241d1b9cdbdb4f8e7ba7246344fd0c0ef8fb8d9bc662d4e4f3a4e13b14176f350306fd28b3d4593270b5a4da226767adb2122449bbd3323c8a5c6d1224c742bcefe1ddac3939a455f70e8c3250e774530f1a2812ba4661ddb981014804055a85026519636034f07d8fd348dce691538220feb18ae8f9380c287ef1ce3d70de5086fc5a7d2d88f1dd815c0ff72effd7135e419211317a4dd8a51bd200b40e5eaa35095bf8400cbed63969ce08fba9d89206d455bdc48d762ad4bd9e0a415f56008047ae9ed9181134b6508f393fc1ad513f618b32edc109b6ab733cfba750cf7d061771851dc875519ea7fac447ca6ede16c39720689fab36f5dbe7c76043d21af26ef856c651306a102eee78da3da35abb304f208cfeedb0c48a2b9165fac5079671bf49d3433d357a34feab4792c45677d4475187c0ab2a65f4c5ae41bdde39a844e6f908b8cf8e52a89730e01c898914ea03101a7aa63ef17f07423d7d9df3117c0f2699be50f70d79bebe67b08791508f9ba773cf05033cd317ce63b5d14e85fa747425ca1c161ac2f279a0d1af58e529b05df30361df175a3c1223a19e805c47c79df3547ac347695f4ec7a776b77a88ee9132225e103cc198ba1cdfba571c819ac366d52bf05f04b8ea77de8912aa6601f39aef679e7785fd0c3d95519d731cb3cd61195de1d4946d3a520cd2222d49d5c867c8f1971bb002724413811f3a3539fb327d2106ecb298e620ddb0a78e43588b956c3934f4c2e51d871f16dd9a96f39dbd2afe98140b31b8b2d90200215deabe0c688ff22b640034b5778234dd253bafb355874f0c962e152efb35a53a755714cb4938bc9698409b582137826bace8487ca6e795bba2d7bc21c5ac95c8823108faf9a1b04b46eaf360518d3f53edaac86320cfd3e2c954e10cf17ad94d2416741ba9424681da45ceb91d5b20c2b1a094aeb427ec373d0bee663b204f3cc1a035e0b55693e5b93ce7c5d497f29c28849cc17c57785fe73c2aacd0d6529dbf1eb141800f2dc8bb2cb7ce2352f07f60e6ebc721837086247efc1ceff2d770a3b583052ee30d7584355c9227b27fba002fdd13b6845a4a43690f78bc3939683fa1b70650cc07aca0f7fc0228c7b4fadc92ec44b713602646cce94507c3ef9f3ce1d21a1d9a824200eb3af5222d9f61be2bac921e572f94b3ad3a837787e46f047daf706770458e42fcede9df037db754643cb4623a62ce5c25a66504f2b99b52fa896d2979c2f6019e5d9c73903ae30536a7d872a93ab558a55bc82b3ce7d3521814fc0e2252f4a3733cf2733e255aec67d7ef3cd0f7dfd943d0e55b807929c9b7cbe78a2caa9702f35c97206e48e841f6d0a804e3a45b4204626f5ab412ddd376639ac16d016ad1fe82210ce31f6375536bc946edd69ee368f77af6f5023dc3efded7a02a795e6d8d52e36a19819f5dd44951748893e519d1ac94cf209e19bac69cca08c37fa7e704b41e5eceee13f9a92ab04e0ef63d5a4133e68fd31fddca0243a22e60801c55163225ee1cf18b7475afa50fa2bb09ed166f482186eb0607fc1bcc1494542dcd378111d43f52dad7173571040ca401dcc8467fd293f9b0d347847b52e85b874eafbefe9223ec27b3ab2b4e66eaebe38dae75936bdde45a2fb93648bf7b7f3e8e53eff6d8286aeb93584150cf3ba26c2363607a64cec8259cf5b4d3b761c0e81dd75879c11d069e0c6c75629bf609295d4cd53ae4946e80686cb0ebc0deed4d3828a8346363062dfafbbd2c01bbb0067b69fa431454c2d1f0d7e1185b4e7adefd0ba28c0a5473cfbb0cc24ecd26f965c6f06c4e8968457087691d50776c474cc0a2da2f21f12d03b89546df09a03875a7c07867341e155a0b0ea034f6fedf0ab805dfe3ea7d7506156ec0b1087ada02238a7ad42784f6ad0a51cf74b20070fcdbe01145cf8b2989a8cfb4cb23fd1debea24f7de45f121a028c6f4c204afcf25830ec794dedeb0728c515b26a20b3d8d002eb396073e87aa6b8ba4e2dd1d609d62880039e4047b31ecf1bd35c23a436976b90926a677e207822a3f60b6b7e303e9250c7393c5d3115ef102dccd117668b136d70bb7d808609e270c2ed16bd194e8a95c9182020f724f2ba26203c13e47c945d8215d374776de3bc110e1fdb29b99c7a99db226d78fbfcdf5d4331f7f9ea69e9ea68e10ee92adc839381fdfcc749d4abd21be1021076f95fae59eae78898854c456ee98ac604a727e557295b43ca675b81a0417beaf90a5fdbca62c55f5c2c5554d7191296e31758096d5e0e2e67734934b5c9cbeffa91b5921bfa8589a1757538740fd64080bdd00e78db97edfe2f28a14cbef9b68d7c1a29a5c9f48e1bce9eb7d218e8ac42caaf5d4d4f2a30860a89e3fa1e93e51252f73bd36e19016d86fe9974320e06e1322549282b620601a7b9bd2f974a98e685b3b3847deeb6c7f2d53d5ec36a7aae8015427896f09675ee518744f0bd39416eb9592dcb38d12f312cdc18dac70081506bd8ae0abcf06be36f041add19bd6619947ea4d4c702c6dc14818038012f4f5c38e509dc50273ab88ec63449db5a804e787b6c229a916bc1536488a719e749b61f97ca6a3ae4ec6ab8a2c9a24e61224f04540fb0ec5566ea1ba997398e7ec477226b95a443e1fe23bde6317e4caf1d352801e0e7eacb7291122200cee9523aa67aab19f2223bcbec7b770909957759778ba99e792a95fb1d7bc17204032b8fb9c17e3d5a264b94eeb1f14500cf9a44c97953e909c4ebac99e501fc93b63e158474e623fe16f377e217d8949e1ebc81929519d5474d6ff10912abaab470ae296cc47022341ad0e6f5d1d7ffbeafc6f970a62ae8a3000add46c8a901418952292656cf2fb7ad3228418baf5955708f4b584df600c28c684991493f438e1944a8c4e84bfb8b8455456435e231f4d0330f205541fb597f31344690404ed718ed7908c685ad52b70ad693ee4f0832ebac259d2267090084e58cad5a473aec992d0943fbfe84c2f95d819cb603533cef3b3cfcf37b8394c679ebe7562a84cc58d9a05fc1d42890ab882c6fdac2a7f6e59935be607609d9f70697eaa2037df17afe42be8081e37eff35ca12f521d50dcfbf93259707f30b2c2ddae38109e43a7d759cecc633d356c155674ea4625c241edfcfac2becc1a95d190b4ae68473c587fed20434a6300bd783c3273533813a04c999e72aa2d98991710acce3d666e7252e32783a0ec9099df0b308dbd09fbb3677c846f81e1d4ddb0c031f5a16b5bc494bae67563c28df6bca3146108762b0c005de5bfe7163cf88a07bbbfc23b3e45bda99f1d6fdf158440cdeb082268c2e64eaef3e7cbffc25699fcd77ba5a021b33401df64abc63e250d1adf6011e9a10d7e36eb1474d6aa4c018ede915a60dda39796d43bd6fd16626cbfc6b98ff506edaf3d5f6b64aa136cd9c5f9058bfc119de99193773440ca0d2e51bace280422ed5bb142c7c64e9626b421fc342734bc554987c05e2dd993532485efb18aae7c3f9de791fbb5c394c046f74ce2560f93a5c6c7c19c9e5091bc4bdd6cf04d8a2d53cf1bc46ef7c985f47122974757340b38369f6e94673fdba97ba9e23cf1fc3147717fdf999708d1e99dc7f7ab7335013c310665dd5fcbb397ca4c874ba4370314147e022728acb32d9f3642e71eae9f136b84fa048fe41ec055aed635ef0ea7243f908c619c2ed4281b7e3d2d7f6c2626650c66830d16ae7b226b6be763821207f143fe2f096c6aa9ca30978cd72b76e212acaf5a1a6ccf21e2a3f56e525b5da9407a96ba420c30e79d58d639a73cdf15d63324714b4025b9308dc55528707252b5299607304d46b43ffc90897d8d94fd5c47d7b6a1a21a8b7b4aa8a7660dc6ea2d33f45f24da295f69fdc33beb3a8955668b1e737891c5327e48256c4fe706cac415ee032aef35d750270b90dd7e72c86fee9f18ecb0085045f454239d8c75dd53f449d353a620ddbb5de105e6068b43a27744e513a19487c1a9fb1df8d1fd8c014e8cecb4c181c8c528eeb58ee8aea74412f3845b90934686e0342e4198819d0a36cdab89162776a6ec0eef5353da913ac0643ada93efa95bfeca4f1445ca07ac0071806644079283bc322fe463aa0a1d78509ab52f83abf954237ba649676c027ea03643244535e868c1f1beb566d166a5d7a417c9460bb3f180da7b3cb0074afb10278a5b7959210a843965a21722fe825f7f8a560eb65cf0664db8715f3e0fe016e71a85c38107a644132071df2e0e94e31a58ac9b0f7dce8d6f7e26c71601c74d33020dc29e0711e3f399be9b929366adead3ffecd89d19c3c60bc28611f5c6df6ac150be5ee81a776bb2da60ce3506b71fba6c3effa49ca503cbc67c330a2c24ef4c8a9c34d3e03b04c8347198ab6e0548f1319ca43e04f10204f1096b4d0c176971e5f4bc0ea1286f89d94909f3a4be19386f317e5e7b0556a3b31f609a7054aae713982d69d8d70363ef538fe52f380b6ca15e4f53ebfc42aec61e0557384f95993cbb0d1a4ca5bf232a50c39be673a0df047f47fb7efe9d7a074f7b91df49e1f5ab17f620ec982cb7b156291f82d3487c03003a3952657c394f2ef6758f1719e6be052cb22414b042a500e2cda442ee6df3f496168973b75972ab3ca19ea77ef2c37ef699f790bab139b3ceaee042c00e14478c9f579d1437c4fa2d7f06f79ed1ca1a85ded5a134205b320eb5619d71b9f591474815072b31e384aa8888af89ac003fa2af4f56c2296109b0c92a477d66e53f0d4f41afc5c8c1b3aa31be952818864e5d319856414acaaced1c23b7c15faffe48f3217e80fa088ce309084863da83ed530a7e7f1e20e5ffc8e414e47df3c2036ab2685a609d2911badfa8b5863da31949f20a07b2c2879a933dd3d6fd54397ad957a85f0601d3a5cf3632ff2dd44f3d84c3a6c096fa39f8d47c39911899885f586c00f2b79535f8a863186cbaab0daae2cb162090f77ca3bc90c4ef2c17e43c7c2f70dd738467ad22796c53f266cc5f386c9914ae461ed9610d96c9ea677ea0f7fca94b27fc2069d740d8a12c51f488f7309db55333a9354e6692edae91587f4e09fda204e9353be4667c94051ed044bb42b5e40e4043b7a79f5742067dcc412a9b903038dfa9837df2ff74c36f1c402361072a3adc080d5c900236b88606a0930e768a865a20c76cc4b5f576218293d6ad6cad91ddc60c5897370742b5d481f62c3373c48c71199284fb4ddda6716ca88b1b133a57d50fd2ba0776e613fa9820e6f6c7ab77fac2ad601607ecc0395247cd259caa9316b8110b702abc0725dbe0a7d8fe193f85760618869732c7205995a37ed6b28a44e830a6484deb2da4f0be879ddfc1699077c4ddeb9eb6cdc1c3c1ef0029d513cfcf315d1c3f1cfd0ee2971cd18ba43fa629b620dec82f7fa5cee101207b1be208dacd18e49dda51f2d3b14a45f99cef89bd148646f4e8eb7dd9e99c9840938844e1c34ce844894094e1960d8d68d1c756a52f3a1ffc11673e55c433dd8900b6e32ca664ea571da631755653955f496177d67ca15853043ad329417573ca353a903b15fe5dad519c93d3a9f18579407a4a27622cdf4540dc579d25ff5e05fadcb73b6bfe7d088833dc8dcdf314e368bf2e40a6f8be7a216ab5d2889595e20866bdd3e88f54acf6bde9c3d91b996f1fb221503799598f96817a552f4ca953c6e3d0981d4ad6b4bfd69970a93491ab938c005c48749833bd4e158fd79297094282df9e1ab255a20309cc78331d2cab78661c7dd0ccc087121962569f19cbc1babdf4cffdd96701e5adf08dc30376072360bce4729205f383ee5d7729df39faf7039af6e70580338ffe19c099353b0ed54c62c4cc9189cc8723f6a14f76a69f692e39fb216ef2b941666cc8ccce1cb24044fd49f8a22d7b82cf0c1b944fa03e8a706a83e7725c82031f81220d377fe68629c2fd46ef913d1c1eaf224fbd5476c550b86b65b22e12821e2294fe9a82f7641c944999fc30c8ddf51a865090832a61baffd13d1acad20b1d70c517c2a7390149c330630a7719647b740a57e215f94a11c2c8b8b062e04332e0ea8392e19bb3d4e4f64fcce9bd97d8da4df4c5b8c18371097a3d3b32fea80f6177d46419784bd9b8ce5aee50855181077d5753c9d669176404a7e170c970cf9888ea230481212f470a500474dcb34bda560751af7dccd5ec428d8ccfb2f54d6b6946d6b6a1d1d76c5f8dd3efced3b76d2df78fd36f9f17ee48af441c9ff730923bfa8c66720283d25de71e28ac9c7c4fd881e413f733af288087a2b28096f2ee435f7526755ec17a4ac3e908dd019cf701422fce00ddbdff14a05bcf3a1220487183e235ae45a48f474840d9d1c1678d8aa51bbad0d73970d3f39904c4443137287c6cd4f2551265d113768196e2c39eb80bc46816d2dae754743fec24895ddeca1079933db3c48b1632fc70fa60866a2054a95d4518ec770083f1c8a85c785c2d551d4a66ea3b7d76890b37f58f8bf43737b2a6a8d820083b98014aa88f3280b81132ca7c0eb650f7f729a30c76468aa2719e27a7cbcf72a6bde89ae6a55b36124e6c71d35adf1c15006c1be4cbbac6a03c82cc6f1ab8968c82ff1df1d499d7799ba7cd93558125df5cd4cd6e7fe6017c5f674adccb394aa464171562e211608bbd975beedfff7836e54e984db3c38dd9f4f29fcda6ae704ef67ec7b63ee274c7a0cd25033622a298bd08a3160722b468d204768e63a7b999db4cfb4b8a7bf43d0ca1fdae6826a85082e322e2cb9b900dcad6addea2f390efb4269d3458cda4c501eea798fd72c59843bc4df55173a720ffe3b948c41cea71df36b3b12bdc97d5e9dc60362dff73eb22e8257ac5e9290ce38d13ca354f29968c72dfe72d5445322beb34bf4dff8f45cb8e8cf472e3d564e7be7a93b78749bb64e50ad0070f2f842e55297040f84828c2559ed2565192a18f7c00938771dc5120cac4d27b6b4916a6b76ebbb155b847078f388eca85aaf1df9fb2e501069cdc2b6c6d5305b980ede99b8e97efb7fcbbdee719fded93810abe27b000909d586dd50c6684ef13773ff5930a65b37c73a9ab4882ffb2941e2e5da5f2ad13c7b06314188712e280783104199e3ba7b4827bd1402edcb809baf9ef0ab77981a8000fe9382c1b77592c66a91273499d2ca660b8a2903b220268bc7a836d0ff2d7fe0d40349890dfaf44bd10d88c90f4df8a24ee491e1e32a7e9ca9c985b8ee6a783e4c6e9aa2259a8e2b037f43570735db2d72c36bc3b9c3870332108c30d3fb9f18bd060e21190113eea5c6fa1a1ca71f3b28255ddfa827184735ef08c3a8bb7fd0666ad77acd3b4fc48620811fdb139644e54c6a53d471616b15b526d1419e71062d8b792cb62dc3a6fb10cf5e9451602dd33229dbd9647d2402c07caaba2fc8da742993d0a88ad332ad7bcc2931e10572f7903bdb6b64e8068738e4c98cd9ad526234ec0b4e4314c9d4d9f5ac6373fb5cbbeb897b5937deb03335325da653fb1e2099fd36acc95f996fbb4a53b6cad1e6a055b6c24f8de7919080fac82de34b075d704383dea4beacbf7c26d8967abc287ffe68416ee6cceda183319fdf100560d386dfa75f4cb383c9e0f5e0f71216aa91a1805f780bfbd98feaa57045733e67e6f497fed9f1dbc37c32d07c230ba4d66d7f04ab2aec759a9e5ac7d16005658c233ff5ab6d2c254f4921ecbebdda8af3792966f5f554b977da0dfca67cff1126c3c8f3c512eda26dc7f99a3a3a4a4be968c4fb9b42c83a0127c55bc177883ce92ee9aba43a489adc8bf5d1991a912cb86effde4f3fac43d86991954b30e1c4f615aea1faf3b8636cc7f98fabd544b9d1a508b8a6c0a8f5896ad20bec3d6274cc121e08d01581ab035cce1910c69f9b85b8041779b143e0f1e3bda7845a4f24a78226cf20466124bfae68626c8781a294e6364a4968647874a19beabf17ea57be89da841df046b15c9765d0c2fdede52d2d6287820879f1519c2a60aa6dd6e76f17c44a8158329cebdb11fc19256b0e24b16b2d5e5ab810b2b478ef7dbd61cac930ddb90e4358bd85d27976dacc1d954e436ea7d886886ec0abff917f2b5e365b3d79468fa1e3e50ae5ad2ec4385dc8757a46c9bcbb6949b10e0e6d8870a7302c128581ca00314d5a182a94e0987e94c4e58d5832283f29418d1b5482128c8ee0b0cfbe5704afbd63042b06637e6dcc65cf98c8c16ab659ded1f46a34654b95e9f4e8381bcd8f3185270c230e0b0ad620195a85106cc784b1120fd1545f1e2941da05b46f138ff2d9c5a3b64faae6a0d4e46d0060e43724288d1295541ad21733c91536622ef10073dc1cb8baf3ae57176cc501d6b24d48e5eff8b22ddc0f6533c9e2351b6ef8e6542d1f934987e4e6a21dab15ce104318a89c33a496f7594990aac702af4c2ece3bb1dc57654ac22266072a30a989f6e44e250c52608c4c1f8622f208edf9ca16fd633830e8a6f86b81c212b8605e9fe9e7799df26024d4eb55510320bbcb7d571268572c97bb361d2dabe25c72139d1e03aed51dc4da06a395eadcff981b0bf98d5e49a54cf888b99f566c22a0f583f3de62d62fff8395831ce3688035f7bf7b4115276684b999772440537b5efa7317006a70c359f1ed37387da15d982e0d5812086a38408a46f9ead764b26c745eabcf484fbd562c90432ce0448172bb9a663f496903395a21b58ab55160987ebf9863852e00500e9b5088985229facd753236d0b75c0ca3ea7d4222f7526eb8d620b5c88e47219cae6728acba9734d4feae8e23259e49d8a4521b1758c95c75f67a95b754e338e4e3b07d894515de734a76c57324239209b74570f7957b4ef56682cf60fa732ef903b51afae74b5f9a95ea1026521c7f325aa02e9b6c5cf4d3942b3c5cf9986a4afebd5d6e4f7437adfde0271859574b64f8f0b33bd44bd13c7647745ff693ae56c61ca755b9f23a71d7747c09d1d51ca0ccaefaa336a3423e7cd2b2345db13e467ade08ac85e75c0edf4aecf8867588011a2c3304d2b849285b0b57af335458c97f4b6647b48291b0af11c102889f792ef81022b2920475f55cff99ee8b51913f0b36406b961d071970028b57d4cea09fdb16b77c8a9a44f5469b92ab5a3982ff17dda9ebf3010f65e16a0a0f12745bf3283ebb70c4030b7018782bd62bfedac4a7ddc90a624dd387df06f683827d254f380b918aab876bef029d4c37edd4ef58ae8ebb1fdd31763e499f2fbf63253a05686690f757e4c856670d18c00766a47327d83c4d6c0f96b137ba28b8cf7018df451c6ccad73acaa049e45b86bf61dd38f1c233e684d6e2fb74d80c66583b9d46ba94f52d866df46984d55b119d715ced30a6893ef4bce5aca311bce02cc0eab0292b5d5128460efd893b7e821fd14a5602fe1935f50760e09b31c43e66e40aa62822b6be524b87270572f236a85cc81f6cb519dfdd135349a03778e9c3e72e23c98742c4a4f6fe25ccd8e75dd75ae704315bd1b0c0531d8e64cfef9df8b5615f02f0dd20db47fcce72a10980d3bc6bcc9ca218e8c24ceec30272f534161e14ebd7fea711ee95ec001371b02cfb40379b391f65eae899352bd70f9e0bf88cf2335d493e4dc9081707f8e0579ee7343e6e457adfc99e26b01bd2fd303ea072d4120e3e11dece9eb76de135e289b07c401fb38e7390acddecbaaff4b9ef8e42545b9e89c03bc22dab546fa8baf939f731458f864029cd473b57d8e1a8b2689c9413de4a60956468f1c896e0ce35d7f01d0e2743c842ac8ff91780857786bd97aa5d976a038c5afe5f6ff4639f037feab2807278972388e29caa1f5c6510ecd371cc18db7ff1be5f03f1fe5507d835767af38cc61c7f9595b40ef801efe63ad587c5d29f8f05b94403b227c40f5da18677cf8ee77f53e6f8bbb577fff6f9252133d76e12047b0c45ede70933b810cd667effe40745f0ee439b7c69c15908017cca00d7be50df0d32a9bf36fbd43d542cbf861d45e9920e04b837ba30a288d798d7ec35cffc3b0d6de8ce240ed9acd36b99b4e2032f19d9b8195dd8420155bdc55b77d44803efd6e02be6e649e2577fdd3c9e229f8dfb89e8667cf53754c9ea7c254a53c4fb4d00e8cd0d0bf722d0d08a7aaabe7665f88a7e068e3d8d27df42408c854cee6f69f5d4fb739cfd533b4a88bc9627f91b88f8974e5cbe9bb80f71c4e70ae921af5c41ecc119337fd32b82a56738ce7fb848d323ee165abad6c01166ac0f050948fe666475f15245078717a0196a5943226aa67444a9e52a654f502dda896da31d41b22db2ba90dc9f9a95c24bb44b0b533e7ee090e0def10db7fe25f5767fe75e3946130e8c19a3424c797d3d84a6da3ea81476570c20a1840614e20be55a88ad5f313bad14b0af5573fd5054760bff12bae169b59162bd3a40b65807c7cafb921317123b7c0756602c2c18a8908d728b466d523275d9f3e04176052c35876803503468d411b3e1c320f8f4aab7302bd6b20cf4359e1287f5d89a1103b60b36b8dec64155a6cffbc20ac377cf4458efc87c545460536d432fd3c72455f8d9dec5fe8e7698d448cc193ddae0cdfaf71e7994dae4ec0d370a959023a0466a74b7ada75a62a6781d3f6671477152a93b4682c434bd6755b218bf4347561aa28c3845d9395069b1e4222617f58ae6e1682b7b01d51fa8453922102d0c948f7295c447b9781b25b972167c9e975794ef6e593ae4f3f0a051e2c02558bbeffa41c4d1048f01cd5fe4539ca6122ea6396e4b7d64de528f70a31ba404f7717381fded7544787549b8372cb94ff83c8fd3afcd103c02c3e0750ef06d0a1d47365a2bf5751df4480288332463cdf4fe952950909ae2fd589fd9b36c55bd99837a944e5a9eef47e629724b70bda54b6ab893ba3f1ab36f5e7a25549ae3040ef9ce4c89d6247123987cc3e6714aa7a938dce170ad59c0e66bba5565cd342e9172d96eb43a5971000340a0ee045d5634e2be3663bed8aa419f262cabed0a76a8a15aa544b3ec5dcf2532c08ada593ef8a927a5ed44161c7185803529f02d9c078f7b7fdf4d50d98a32a8440d0d7177bbe5cf8ac47175a10808a5af489c3fbc7fc482cc621a31d7134055aedcf19310d94ec6c41d0f7c677f9ae7865d2e31fbafb429bd344860c04caf1a6632d40934fa901557854a833577d4fd85b39c5631369a0aeb4a81be2c35ef90433fde64836acbda5f2896fd0a10ff69ece6efab96c014daa6220000642cc695a53c4d430b018488e0c8b3be6fcc58c51a9849125984a7a73ee9559ce02075403f6faf7883d1dd312327aeea071532ac24ceef1ba7708da6cf60283aa427674171f3f5d3de51391b318978fb0d55b24a48c5ed0b61ee21a5df4c02b2e0e109806cbfc1a5a41af9993fa44b6819fe5ae603345c4c15321e824a461ea9533cd4724e57d929b95c36e0634e13674b8a9936de1b3e482f924196523196c7e5ca5fad2b38e7008c6b1f5feb467bbf7e40bce268aca81ec30661702ed3eeca54ace9be2922c93dff192bc545db89126311d914bb47003c2c3d116f6afde8e921a6c86266d7ce5d963d5ffc9f7c483a85532319df51c62eae0dcf7db48565b00aaf97be9b791c6ba036ccea0b6721246bcae709f7704d76b3f99520fb4658ce38a9daaefa6a2ff6ad59c4e29888e3d0856ab13c697496e19b27fb1c59b8c224f4fb9c246f6cf809fba2c41e82266b2063a09c2faa4a1e1c7fb13fa0b9c13de53f6cd542aab4975a93186d2fa2eff2b0836721b5d040e0f2ae8cb0927219a56ecef38d396ecbe776c9e201807fd9ef39c676201fbc5a03c144b46d94c56f2771bd38d32de1b166fdf867b7c5150c0152357f6a77ee6e7dcbe02c80edd1cfe0213d65c6ce2ef676dd1e186ba1c2758e160c3251e40745f6bd141de3135aa8a97bf5df899129811f7a5c1156c96a0eb72c252e7aa2d81fd7b5b7465ada4767d328827ad6adf6e13c75c6bc9cb34845d7cff4d43ba49434ee0101841667a625f12018bf768961f3ee1317d20497f0920cc4557cfd8926ac2f5356c06cac89e62505b1ac714c97940bd0288612f6683fa27427630566ff022d183764916b86af580ad1b9404c985d61b0e76c273e4eff0c485d6dfa9c6e1e0bce8064d4e86a0293d6e34806370ebaaddb29a212bee580f68eb77fe8cf2c9ecf538589111b18663d38b0d1f454f08af849020224477ee28e5acad6e915dc604bab3942b4e773c44842260bf327ad6b0b14d55656affb92e7b360c3efc5a952ed5e49a4df2215b0d7db05035fc4fcce1138c5cc10798c3f41fc5b4ef5bea6e40ce56dcf37de16d07b4af498e5b2134bf1ec0f2ac175ad29e9e8c6a58f0a88e3972dd7f8055e24ceb8be81fc04b991102e637efecad885301b85f1c2146feec02e5ac2bec865c91463d3c36536f1fdeae5e464011cfaa058ddbb0655eae06262f43bf5d5a9af9a8bf62aa97c06251ddc9c14c4d6d43ad82378cb4aabbc538f9bf5558ca8b896ce369d355a2ebdf313ec29de91575bfd023695be76deaa988548be1c14bef5245688aef2a15dca6708c58907701eded4ef077ecd35f1558735cd820566bd4e0e7aafc5ccd3cc711dc65691c670653e700a0a80d76bf8d54e69723ecbd5343c5fa610d83366f2175a88cb7562477776bff0f7b6fb6ddbace6b093f903586dc37e3bf22295956142d47711c27ebcee92cf7bd2dfbe9ff414c50929d6435bb76d5a953e7db177bc512d58124080213138a88b32b1b65f641223457a09354229bc405878a4df993bef0de286ad07cc9a526d8aff05a2da9c1cf1d5017fde35212f0105bfb1e579741ae3bf498cd35f4bee10c9a2255d45f8d7981e57f17f81770009e2c5797c4135e01f812db5c1288dec135acaafb32fb784d189093f0c1123bc46ed6e535c3b77c31d8288652f5a7a39c5e8d19a3308687a66b8f3197a05f8f7016ce65898b5eec1bca3a4aad5db171d835781beda67aa9b172f325ae0a09528cf684441bb6c0eabdc44098cb26fdf6e23683b5faf39fd9cb1d5bc68ac4b005264a2f70e10688b92dbb87f6e0591eecd823b587f7e0d54141ecc391e703fdab1eed1302fda3330ceae4ea3285eacad8af1d669d5ff5f508beae68067e4f7f0a34446fc6a8882ffada5cd2e24b9a7c49cb5ce20b75689f3099c2e4d7cf3f012752814e996e2fdee6aba7f30560b5f49bdb8b77a14a87b65be467c32586a5869dfa6eee84939e08171205235644adde79982ec06bdd58c0baafd371505d51669a6faed8f01573bea2c55734afaf080e397ac14641a571c10723ebabafa78c123d1536e8e75448b92e22db04a6ca9528a8d250fe6a23b15c6ff9c24dd43ec808f5f1844f2f32e65bedfed18bd4afaefee24542e19794d10e4b8659ceea5814a67507465e48017aa6079a223ac6257616da680869e7dff76770407a4714bb1c66b3a22a39e30eb44a60660af5ff8b12f5085c11bb62dde09d62c3686b4012dc8cba610b62e7558e806172c48f31a66b582634dccbb4cc6127bdad85616b852268432170825363ad0d7d17866190ab58084362ba01287646f5265d42b73be284ef7b0f710f7bad1ba9899c82ee38dca208d04166598c23ac55afc93ac331f9857527bb4366b28442cd9c22cbb0c4a7a6a8788965ffcbcb28d98a2f1b246b2fff2a61cef22fe355de1f2e1a3660352c31838787fc61afe298e35d6622f1858869cb22d6f2f246e707cca1c2e58dce04200b8a38ac3765decc23e6b277240cef2ede586dd498ed0e9499bbe7c74742ade02f41a2f1d597aad2d575f436cf113907a4d61154c7eb159a0df91fcf11997557279b6b2f7be4c2bdcbdd1348c67b3ea2edabec29a277975e4654ede1844b2d6e3e21d8d23e25a014fd50b1fa6274810a854744f0a9f3b38b52716b698442445308e3424a5de1d7d4062c40bc051b1e1fb2ee45f954238ef5a243b136c7cd49009548bbc698f4178af0e0bdf6173dd6152a51c8266ee72ecb75e846b5f14dab7927bfe42ce188c3ed2697e7d6cc55a9fb9c82767e020d03c5bf985fae7e85a58358fe6dee0df1cef070dc646f6be363f83d6f736acb34ea5351bd5ff4aad11914a3f81375d115fe41fe8d9208fe999208843a3b477a03e353bd987944353325f1f40b085f5fea02e1cfa10ad2cb1a3d332954e25ceb8fead1619bb8cc01ceabbbadc708ffb8d74f6ba6579eaeae640d33e67ad1e6423d13dd4d9bca36bf7fd60d5dbddde22f1ba1a8e01f283ff365874f5f563f3abc4b2afef2cb5acef59715d22b8f7ffa65a1f00fed16afc084ad62df0bd31e3cdb2398a6a786297ad835050dfc334ac3f40a232ec1b4eca4346bfe09be9e819556261bf0bdc80bb771c5efaf1597a7c82dc3a7d27bf9c28d3d53827219667e9fe54a7df505abafbe001362e4fdf153735f7071ed575f4bf5f7cc1b9639d309ce1a20c4bbb3b99bf3221d114d1f6c00d6e722087bc673dd622bdaa3c209aa8cfdd2a0c29cf5b629ad056546c6c991c89cf79288b357d24fe8fe4ad537fccebea0ad85ba4dd3bb49515dffa6ef757f701e8fdeaf72a35ffda664212f2c5d2ad9f4bd7ce1ad142a959d8852430dc90a7caa512958d581478588b7d587b002e1054d0eb39c4acada4ba15ece254604acdb565d0a75b7414dc5ee76ddb68afac08e0fecd76dda2fde1df8c071dda68a4a77f01d218cc3f58af831a857b14104a10f9e9240f80d35860fbbbf7dc91baeec980e56047c560df68a8259be8e5888de93925e28190ada94a24e9de58ab1074c9eeeaf0a08fb2d513fc8a7fa7f152c4aef07c63e1eabb4137677929d90b8b57b22b26ff5139e24e402d636e9d056b69c23a5a677daab7451f4c0ca40e6b23e57dde4ce112fca4a56f60c2859d0f56e114f7a32d7f047bae59267f544086a990602399b5d1b7927c013f747dccf3c63f438583905887cb8fb75e391146ae18c1081783ffcbaf1540ab571c635267f4b7edd7a2e85da39904fb40668626837918e57408c77386961b3cede81578a59d84e83536f967c59ab09d07f932f8be1d308f9b221051517b97a7c139b6ac03a5cd0a157a95e38329ac889e8edf79f5fc303b04ef45b10611704cc3093c869729222b0db0bfad01be78488482f695c3ca28ce04ceaa8cbbfb2079c5f0acbe9362822c6d5a3f423ca52949d897766474ab38a92794c483bc9d512c2bedd8445d3c266dec6e18c9b7ea1aaf2730c854c92af2ea6f8fe588a60975e3caa5d04476ce0ac06761f6be106b00dbd2cb485bde1a0e08ffc7818bf982b7ce19ee5f98c88a1496613fed1e6bc88b38d207491250a6739f96fb93a727a2610c1cee3e7703c979db837b9c5a035659416fe8d4a0444f3a9f04ec75f21023aa2b92f76b0bbbab5896b0df5f4ad722411878b676d16ba8f250ae2b9f7637af7fe3431b46f08ba1074040cc1c2af21f0fc3cf92af08c7d5f80369c665ec505d1f924ade7144c4f2ff04a63a3ef59cfdaa65e70261fd44fc7e024d3de9a4ad351c8a724bff6cef94533945025caf783db64341d6323d2e137971879c036774b3338770a28a7154e9848bdf4908b49a0e2be372e92376aa5cc3de789647e56f4ec248f8afec792dbeacebb10dcfb8c23bed38ab486c23fcbda85c7bbd363d8ca57527915e27d8af573e1fca21db0b068e99d5d446e182392cebfa59ce5e7ad91de780de919477c7c9b93de1281c27a93a567ee89b9056b730ef461bccb45adba2386154fabfaabd5c30c9a867f8be16c06935496c779b88478f60caea1c811e790aaf6483edca0fc1b77e1d679b2978f3273f29e4b8c93a160bdfed2342e31dc70a540763b8ba204ffec18d2793a234fa788f078b7307649ca9437a41a24a339f5eb471949523706e49962db7a40038423302b22e98fb52a9500ff801e402badd6dd994422b551c148fc98d2bbaab3e41b9b350026c01c670fd27cd28219fdf72dec1dc788753cb3a3d3dca4c15bcb11150c1c70490473b4f0a22d80b36abad78db3f7d23b455b7ebe307b372b12be2dab1c5920d6518e2c8c01111c3077ca00996c702a223b92542db3493f23198fbac86d29840e8b8b7c141709f3c1187ef6f0840bdf375502589560acc6ef96279c9b1170c66cf4fb4289f89d565c9c08638093e1533921553e38a3d853582db950f0b5dc01d6ba9e70574e7abca558588405a9a12c6bee190178f2d44a7efb0c7807f2770c3896e8bd4d18c768b0b2b40f7aa2f4c5c589136e098ee3312b76d882a1d16d52fd84f6820dccb4d210edadf0ef6b694b5e4f94aefeecf5cc7398fab488517590232d66374c5481320dafb5add62d1e85c244232dcd91d6ef4b5082dd29a07d9f9339fadb2d4de6e703b0c641057bac90a5e537a18f7b7683320d1903bac4075cddde6324443cccbec49085b358c2c611912ed4b7f753a9555c94d66c96f4b46de3eb5e5b5c1e3d1e5a8170b76ad9bc7c6e75d7215806f4ef5f7f1455c0a861d856700c9ac26bad3cb3bf5609e43e8223322aa221771e889927dff9ad714d77b6f6f42ee4630f22117e0f2f5e7b2808c4f7f65673ce5422842c6d73dd372c776012bcbffa444cccdf7d67e344e640822f1da332fd73e580780471bb456422dd05faa42f14e47fd944f4c77bac10864325990104be25422eb5704e70e8788d15b0584d2a1c7a6b9e58a57b7f800781d2aadd1b4ac30ed3efe2e42263f776728b0a43ea2c574404afbc130dbe8801634d2a3ac8fe8c468359f8bf1aabe4f713f901d96b6e3bd0210c709c34dbe9f981f0675237f084776f1e6a9341db235747c03089644a9579ef29d42d505c77bcec60872627708b4455d4a6bce0a77f15de4136e046d477f1c5e3e60a7ae18018395aafb00ad06efe6eb6d60363f030678747a1934369a1fe823b3335488788def3f67908ecc0bb502b9a404ad817df1636d780d8c4336663d7831ceb077ce5fa1e45fbe6ecacc9afeb8ada8ce1abf519401ab319ebd7271c6ff2f10339d1544d9e12bea23033e621425c6aa1d6e6dcea674a26aa5a92b251f5d1a3e49d4a01c128b5def005b323e70ed7114396d5129f99205fa43f051f404916cc430ee0e719086053f73b3e3e9a63aa555095bd25cbfc2db53ee2745c6fbdf988c3a5bbfc6d8a77387abea3c60a6d8f7cf4042ba3e8031a44613c3192e339d96cef7651c2ebd0ece2c4748e14a6cd8ccb17bfe0f81c1578fb0712805f92c8ca4e61c45100680ff55b64903f86c386fc7cf3957bf1f061a328d9ea3dd4a1bc970cb7c6cc291ff4b08d36ce866ae350baba88920af187bf2fdf280c24ebab765e00919feed944b4aaeb0db45f516923c8aeb799e857e085d12f51ebf04430f993f7688522f1b61246643227dadb47d890a731044ac1dde718d0c391e4280cc5697b89393a22d5da3b6ff3e8ecee9e92a17a894a3ed06c11e36aa63364c076581d29dd6e97b65bce25a6de6a2e739fdc8f9d13f7f67a0eeb6c33bf1c8c91cd9cbc962f7a3567b4f0707a6beeb89b5fa2c2a3aade04f512675ee4137bd3f4609ad2e8ecc54eb58fdfc7b9d9b8969eb5c29fa9d68fcf634451b4545102a7d082157ae1d2c255c27ad6ff8bf0970b95309fd21ee4fe6c1e7bc21fa8cf6033edc068deceed22d1a9e6829d8dc56b4bf58872af33a9331108cd6e54e4f2f5cb256ee380caefd50394f4790a720772b8c56316c5697e0962b0fa22b455997474e3f871721b2da28389603293efc1acbee4bb0390ab31d0cfda385660d5a5ba4bdad6c91191dfaca40e6b11c61b6273a7ed59ff0c26e5054c4bb051f875d0210c509b2428fac8ffa118517f770311dc68e97e2c19ed5b82111714cf9425f773c12cc527dce2ec5b7d223b06b2ad82a3c911cedf258a661c690afd642456bab15025b500416aa4dfbb29b9724c086ade019747e50a1ee462d2866a3b29322dc133d54c65023c22adcdfa365c39049a05fe61a0db52e1a086b251bb1295646e28a447debbfb024810f5490e2870918368ba04e873b644d217a5f134e1521bb45a194b42d824267d6f92d62758555dd848e49c5d56193b5d75ada158c921196e725b45c0c0f2c45276adaed594aa243fac2d15228fe1f3b7b9c6f5682fd370443f834600fbbbd9c96bfb2f06d5e2545ea29805e04fa6125163856623cef349ef885a195d63719e9155d255e6a6542f00a0c32df8f3a2d2987e47d305c74a16a08ee07b744b94bc4edccaa23ba593ee014a77848f3dc91630c9010adc20c9aa3e67495fbee1860bcec2f818703ef612992335b8f2f42553f9f3db571f41471cc899faca796ddd0d965fbeb37f70b3f98926ee02a962fb197ba76d82dff44743188101f60d436d1fe018ef9ed943411c986b25dc185e4b32cdcbf200f46125ce3e3e289b74b3f4f2638fbec0aa3b428c60b32f8a4ce841560c56c3358c59aa5b2b9a92ef7357a17fdd1970bff5b3496d31092e84cb1045646813078300070e4ce77dee3beef11d535788a54b4aeb1d1ed098b99860aeed0b183ae5c71c64638226031a91eb0292efe947a90aacd61adef27e6b8c0d95e5a67d6801394465310221deeb3cb06645cedd3a48d8998b83cc1f786f8262953f142fdb98c22a6cd2fe3e9abc230a040f4d132aac55211ba10c033dc27e5c5b0935a759a12104bf563f2e70dd1e8c6a3205d45da5c1894fa503c823d6840b7039a32d66a0e3d40c8323b782576d2ce384e96bb440f772a15f6d23c51ab1e1709cb433bbbb1fa31e510bf7aee08b0720e60fa7d4d49dc81839bfafeca90b376dbdeaae6419637e2957c87b7e5e26c8dd8d550727267c629c9e5050f0333e314d68e4a9892a40114ce5044f7b1ed71c0a17cc5403ba610d894e658ce7f6467b970dbfcd8ad664f2e2a8923bc5cff4820672607af59db9607679c11c3fb7062fdae20b9a3b97ddcb8bfc050d774a821373b30b6b7001e5af2ef0857776275c9798b28100b4ef83cf50ad6409fcf3617164b8313ce1cdd2c3ba23e654dcbb05d0cf47957a7374f76075452d12c8d7efcfcdd0c1c82ac8921c1996d7438766c37864b004146d54aba6028869d3b1de85777773d17a3a72cc26774039ad5aa96ef8925189cd9e72dbea0aef85022da58da132ea1039c76d850fe807bc0affeeccbfabfcc0bb8b07ce474e0e125d90701cb7b00cb1936052cf3fdf7d9beb75d761be80ee292134dfc339617f0e3162bf71264699d9d72a33a2979ac83d6261fd1a5c84dd6a5de1c48ea228bd1dfc6add2d958651b19c2055db84f8d704475631a0edd18a0f2f13a249478234e06f1bb96176be2251b798cae1aee14a5b8dc8ed31d871b3ed096b381ded9b8bd727e27f65ef6876f5ec48e65baf4ec96afdc61be74e64adcc5a182d5778d903fbc9f754b9901372ae1b4f0092ec15591ba2fc924964481bfbfb0a83f6b97f9b9b0e4fb516312db8b0a971d3b8862e2c6cb81a18314123dd2e8a2b6c6d343841a741a5c736ea8898463a5846238738edf6343a5b6ac103538f3dad38ee7e5c342f1f3ab9786159b6cab0f531b82a317aae8c7fc30a2dfaee84c6f81c2bdc3de58cb4f5ff1d7f8350528140afde4369a1876aff6904e6d7f4a9f543c7049306647c6a5b21de762ea6101e266299c50d10dbe387e484b9c9aeec8a3e056cee455c9279798e652bf6322ba8363016b33a282ef7d68fc1a99616fdccffa68c936a06a2ed0352c8636e9cb7b026b49ff7131923c43cde76f40476dd1af9d0bc876b79140e39bfcf5e72e152701cf8cca2bea605f885b6ab2055a56c1db55150a227b9ba12e0bad2e6a180ee7ba7ad952ac1df3a97332e8dc9b5b7b4e9e48294df9f1f2880d32363710df2dc23ed2dd90de9638745e4370bbe4f292629a16cd93ce6a27e58f04721e1258a1b65b666fe0bad1aedc6aa73e918dbfe10c14aaeedf68588b6c7cea5d6d5523ff317ef4d171f36d9016ddc6c08992cbaf31e1c2f0fdf9dbd2af5ead5bc11c49ebe40f3d03161f9410a75b119af306be859e6be08e0254b48ecdb94dcf4b721627f32074fdb8eee1df5d4aa7a99d8569c425886edd69dd719225e37e8a9ac6fb1a4b66c8f164f413874a759b81c5aa74307dba8411aad6d7039589b8c22f7618b6d617f579417e3e7d18a84b7911356022cbcd1b663428edbfcb473773c8d79dab1901f2d255c7f52a17cdfb67984e98109eaf6d13e2c1c9fc043b08431fb5c997a5f35a67051b06923e05a6dc39a29f1cb18b11e902cf1be032f65d6b9e46a349d30dde2d6112801e9962e6613bd125ba6a52f66d6520adf7636db6f075cae8ee4605b6154c9b193299039514f2ca06af7ece8de9719e3d180dbae6b37af7bfc405ac4a532c1b830833bcdb060f536301c83f5825d8efcfbc100d9bd9d33425dd92846edc560cdfbe4da36d736d80cf4cc6dc9e6207730cc46ec16a3a95bb5917aaf92f2e56d8fa060edda507a7c077d3414de4a5e1c9e804bb5ce389ff18a3b6303770d3b387a229c40edce0799d65d82d7b6b7e8534233be65b5d713d3f71ff27a7c85a7b025d93d96f929ad8ba70c855b51bfd418dd6aeef193b5fc45d3701b2334eb568aeaa25da948a57636f258bc5438dbcf33175ea87eeb6238aa0f18ba474c8528a922d8273995a3b707274c745872e98f156c9d6e99b74d95449b1aeaa388aeec8fb9bccaa4aad73177265765a63e2ac8747d8f84fa5942e03caf1a8e52b8b4b97d3a2331b30c03a6094a97f7333970c4b09c98b0462054dc668b8a191d1137f116f2306de78505e60a54466aa14404ade00bb5438606ad883f5a0b99fb650ab2d2af076ddbe25720fc976bebe978e0ea8803439d10542e9714adcf7ac2ac33bcb2332f560d4bc66051835361fa8431f8905b05d42c553ebfd1196457953eb54e4aca7ad6e385cb46a4efbeae209a4e854b19e0506302e9ab01b3658aeb9329c74d5067356183bdc8874be43b57b15cd1362268da9c1b45ce5e6f2233a7e1223235369116b65067a8d360c3ebc1bac4c4976595664baa7b279711baa262a1402bdf4c42d4118da144b61b5a75fc27fd068de8d952a219e109e164e35a03e1de8f41dcfa6e3cc8f432b69dcf812725e9ee8bc473f4c42987ef8b2aaf0d4aa8b36cd85c7e43ef30ca3530ca4025e8232d1b658ce8c7640119acf74434d672d6078789f8e87ca94533ab21f7ad76fef8c11c3fb6d242e2fa7882e32db99eb9d953ec958b823aa349eed99b0a97d9d916da8c07c3bd6708abcbf59e2b11fb302cba422d6479e16607975538ebf114bb8d3c926321f79423d156cda49dc069af85fa0a0aaf2e229efde54266203edacb8465b0f43fcfca0c1ca0f06c251b30be9d8b838a93ac72f01bc0a16792d5492e17ec1dd4dd75f69a654e42a47e805026b2b9eee445b89a77f40e38564bd4df321ae71d2ca646ef10ecf4abc2d67de1feac2d38e16b20d48ff931655e34e3957c52eb11c23f348e576c9b502cad50319d9a19de2329c20f7ac250cf9d9621e2f08577072741ebcac5b5dc918beba381c041e6d59aef3ab079760942234cd03773ad67719bb84bc6824e7147625a88560c1a9d249fb50553bad4a12d7a1bc265b82fd9ec6e36e12b645cfe48aef25b29b3f2b1754431811908ad893f7638472c2546f7d74bec84e0696a9f5df60911e1f4990acb34d4eac8036e24452cf5045c4b706385e31951665394aa3fddb984e2fb24d0c6b540f72cd0b87525d0ad11e8f9d7025de3c28004fac180f52fe4c995914675461affebf25ce6e5c998e9ee84195e6c120843d0c2c28ee46967f2ec8b580624ce8f9c345b4abfdac8b929825483bcdbfdf29e79de0021dbe7c4bb02896526de2645fadc8f038cb74cbc2723deda17e27d25d7d4420a23e42a2e0ff1e82836d8fba0326e7f9234fb7fa72ce9d2bf2de96db59d93348c9d05cb79a972625ea92b290f84df299381bd923d923650ae618976373c788fdf0dde45e16af0d679f0eeae076fd548d7fef5e02d7f31784bdf0fde2d44da6f41a46fff9a488b9f451a1d58a4c7bc48131269ece444fad5c075e74c7f0a512ed4b5280fd7a21cef21cad2b528477b16e5e2f44b511670e13b8992e9185e5b5fc8d2862c8b75434df22fcbb2f9852c2b2ccb6a5e96b56b592eb5527d27619e2f942a82e023aa88ea553e8dcbcab530d72cccd6b530974698875f0b738e3b7649981308339c9d3e0bf3c065695998bb7f5b98d3da6761da2ccc91931366ec5c09f359c4b24bb29c7c21cbe577b2b4af65796259ce0a57b23c1a59567e2dcbfd57b2dc7d2fcb296223fdd2bf2dcbed17b25c38ac37f3b25c5dcb9256fbaf84f90c850961d63e2b4cfb5a61b23077d7c2ac1a61dabf1666191746244ca620ee96be1066c21a9385d9fab78559fc42980716e6312fcce45a984311cb886439bb90e5101a13b26c7c92e5e15a96e3036bcc6b598e0e9c20bd387f21cb73a63171618f64c9a8eaa8f5852c1934566459eabdedbfab31bf9065856559cdcbb2762dcb5711f342beb890e52b20445b650dac8252492c6bd21ab745e43339271a2c0edf628ca888e258fab5c07285e756a71e590d6d7dc917a0237bca513602f9079b57821755183b8f6040108f68dff6f3840c8fe04c3ea2e04435db1f67b49fbf8622c55c5593199e83739542601ffb2312e25b807b074dd02eb27e79b6f970e1e2f020ae72eca4eae2bd37076678fb13a8932986a02abf873a71fd0811196d2cb82205fdc5e5fea99dd7f0c75a10ce2b0546065a448eb0fa2220face8e3810bdc0000029209d296ab652eb034d16903310d46968fa872bfdbb42b41ccea859522f7685022c8ee6dbc3ac68800e2add736d8b947d01c7046574bc1ecc6dfb5cbab262ee3a764733cf0a85aa394478c35898abeb13a06d08ee111e59e889b92999a04b99edb84a6d9b3e7ae48d677ae0f9332f9b6db593fb190c4671d90def12282404a893f1beb51925e60a753bafa3f207fd7a3ca0d813310a89f09e8e95deaec1633b0cf05e0978e001f59e1e8424c9a514deac8da2c6872663c45eb540f78cb0eb5a5ccf55dd5b5dabe8aa99125628ee69fb7d928d1d70e9e8803d736a524ca37ba074419f3c5b1d4183a4afd5d23d37f3475ca8e3004af8171a8694bfe2e9269e7a035de0bece7dad17990c05cfdcac10b84caa0c3e86c0f752f7da404f21e46b57b367ea2f8a014032ef10257550b51d91e11b1c6a943b562358a4dad7a4a59753f50395da8f78a3578b618f5355929b22f83ff4fd6e084736969cf450a0488941ce21c1fad9c65e439f0cf4ad6d5963d7018001e6de6a2297536626763131153b203851c30a44f76c8eecd0d6a46e72f2da6b851cfa53b97090da49aff940afb9d4af99f26a12d2f38160aeeff0943f9267ef2dd23de8dcea293c963753b208c45452946e2a5b67f85d6144db8acdff7e4cedd4e318bfdf277a41b75e95bf913bef4a5e5b7e1180fb8051037a6cac0c94ccb7ea529de544596525bc11f982546e499b1754b63494108cf39a2631366d765a48f85869614b67e2019e334fcfc4d869dee4265f3187cb644a6cf73821b0d6405803fd5a3f786b3f452ade739270e20575eb29695bae6af710963ee3dccab85233a74d316923feba5ab956cf5115b95cb954abb1846b989fee94e448cdfcc92df9e5168bb6d5753b9c03bc3d0133640d54f862a5e9885a7b2bc7cad1501f28ac4405a39d3b52b0738286ab38e7eaed261138ca574c82a3cfb4361deb55852d39de76f44bf61344a8226edc5c319b47a4ee998c8f2918ada6ab0af2c9f24545923679b7114209019be008e21c350f50e18861b6439485d2cf39627cbf6cb6a0b3a797025224a81fe1162dc7268393866463abac40dd83a7b8282b4c197e6a33ed82bec343ae0345589e1bc6ebca3cd7dae90e77b7faa3715cb73c9ed4f5a37ce1d9de6cc9092e8c5d1901327b060c09c1bf52c4c8702a79c039bd638ec321e2154b00d5e0f97e1496e7bc1166738deec237f509e0d12bee1923775ee1a993b6e5ab775b6a6b5e09f15c22e5ed6de4f698968c10fd9df9411505a55143ed832a63cebf26d05cc0b42e521dd49ea932c85f52c96f6317e850b255765a45442b75dc9107bb3d6b713137b218d3be0d84b753f1e9b20ff7b16b562211ee5ad2f2adade71e6449ee993e81ce348ebfb60cbf459f2feebfb2e26c8ef41e8f326f673d8ebabfb6a20c4cbce416fd2f8d20434d8f457605cddfc56dc335aaf1405381452dd35c873f3222826f34178c82f9bdd513de4655e1ed7c9e14b2a5ffc9f2d5c7d354ef319cf781e55b2347fd78e2d44d25d4cf126a0445f85cc3b9a0763225c0135c346724459ff7735510d54f25230cf40f147fec93c40c977ea05f746870b938f07c7dc064ec032919b27bef1d28f62a0a6251dcabb4488336eaa16a54be2bd49b6386a5fab8cd020fa7930351f5847a5a77ada9141f6d60b936a0b6df76538e03e56fb0618bd6f4af03c362875944f917498ba1b0c716e79ada9e012cbb13f738076670cb7368d1cd9909f608372f0393ad8f89e68a6e43ab855fc5b80fcfd91ce580d164e4fdd535a17825d25654e3ed6f9ae4a7469d820291c5797719e9af5da6b6c19a725bbbb5aaca23fb9933092df1b128e7c889d648e8c47a6252d17da16cb706bc6e50e5dca216dfb749573725f16057a438d06399273e8746462ad2118ca4532a85ab363b1875cb2e62c7c42ed0a740ac9bb8eba493268ef6dbc8cdc312dc8891093161b6d871a56d72ae033d6f26bc664c2bed8c7da37fc3f4b5fad3310a9e93653bbdc1bb7077007fa5f7df9fb1a331cde6152215122790c285bb2ead1e8e39bface4a1d53f00acfeed2b87f9575e57da695a7cffcecaaa1efeb337dea054fbb4d93638e9dc3c81ad7aa6e02bf84e900a20eff5671d081f49ac08179ff5f0e79fd592f8ac957ad03df95ec00dfb365175ec8d03c4403798956652ea587d317568a2c58e281639177de4a678050454f7485a385370308f59aaef287c52968df1e7137a4c7d757c20c2523b3e315c64e45257a3f4d354a51deee9a149c375ab45e9847fa55594adb4601259de319ae42d7507413162976240760f7bbccfeb01e5ff0caa6121ab5c659d76cdcf4f7a19628aa821653c3c3fc2c5045397b626cf54713391c4dbd1c378ba23023ff66ed056edf9075acd60443f1ff9df848c6995c8228650138f69f55158edbccc7b2ef6c658a0d5a66f568db45a713fe7af584ae1563a07567dba27c652a81f8d1d4f628c5daeefc65ea6cb11bb950d1e00ac338667f245a89d53b6392b822e09bfb8649f3004b9846b6a4ed5e6e224748dffc535a784f029ef0087a89253c02544af84b2515757141394a9e787acae1ea2beb8a4ca0fa9e092969343a03ca2d6c3032e73d9a6a1dcb5965a2a7cd0118fa065f8a3852c7124b1a50b34454d9be4f5ebda9c477e04a72ea81fd5124bf489eea51e129b0ae83c17f1fb67cdc6920cb88c7a3adbb03ef8fcfd99cf9741b6fa00e02747c58f25977712e9976d6c071c30c07965f6d3bec84420545a6332695f1b4d18963d3d0e89790456d514b4e6efe7227963a634184b9253b79665907534699f1aec3aba71a9fd6029516e238f2b4e00b8a19b273f4803015d654556a45a9da7353cc840a484f1e95b0b77c524a598298309b080630f162e8ab55fdbbdb3df390487c26b389473ff95298bcc1a2b97eab884ecc15ab1583010243419294da2fa9fb8598f8c33bbccf48712aaa68a0f644f56ea32eb8468db6c43ed2c5aed342b2d6c5eece69536d00c62eac2049e535d90c733c1fdef8ee8f1f795cdd6ef985c095aea3f9ff6361b95341dbe97f9ec1fec2a58c15df5cf1accf5d10ef493c17645a9c72f9511537afc89ab372d905b536427f513e4d31e914f1b6f7fd3db99833702e50ef980dd8df755e74fa570791f53e2b440f204178b3c047ca6a9511b2ef8d4e0c4af7a91fcd813aec350e1c3653aec4ee40cb935d0c39c0446b76353eb6c8ab1d477b9c86cd4d801362ba70454d31be1aee8c67ac2de4c29e1fc6d72227bb3cddba590134bf580b807da2a967fbbc12a6fa0c314a6ad5e88ea547253bdd989fa62f3e5093118a33ce8b3f5ae979152917fe95778c26036c8aa92b27f98e1cbcc5c5e494e41ba333c98d1fb4e540d18b6c3c4d6b6cc4e85d8144df728f2a7fb67ab421ae30df9744c98fc8e34637e904ff863831c15e51c83071c1023996c3379d4d4bcc555a987c2a5d2a76405b28d4e7412aa26cdf3664776564e090ea64ab2c6e1923e8e3fead15a915cad76c1b79973e1bd3d191851e916878bb77a9e9c09e64750fc23ebcbc2d1c5dd13d0d73e9f7a3871eee989d83013b1c04bb8ede035a774fd16a6ef58267589c1c6536e49e248242860c62a65a0521be788670f2ae61dca471737a5777e8e133e5ec7f106caa30d26e6f838e1f626afc49c98262ec853540bf79e4acce21b2bdbf0a40510fb1875011c08e020e8e766376340c8456efeb796c25d85cc947531d1fba9bfe274326b51ea60afc836cf35aa3d56263b840ca1882a1d4e54b54c7ea3a5bc43ff0548170f84fb446f9d4bfa9d4a4ad7eb07564ff82ff68968a1cf723e6663667ea4fdc0929cf66f95842673a28e323b1dc0a3e4b1f14f6af0b5744ae340ea8e3c7434f8292107fc27ec61801b69862a8b33a413cc634667d16e2062949f596b6eef21dc81e17f25d533b825d23aa9a74216b319a7bfd28fe7b9d21ff3bf017d51ce622995dccf0bebcc2cac7a7a3b336c57ba058aeb288a5184365f071242ce53ad4dd517d7d5f3d7354a5f789888acff92b3606f66376a73367a5f283a82d26343cf343362d84262eb008569e991b47be8d5b978694ae8e657294e88c10c1751b4990190c72b9d3621032217717fd48b4c1641baafe13c43f7350b2af3f0683d13813b413d541393ac6b79a2ecac3095ba67a3517b7ae7728246eda6a49dea83beabdb33795e2a46c1812ea88f06a84cce81657bcf2352af646f96b1c2c151f20e7b7aa38cd7c975adae55e8a89afb54e5f180be24ddac77a59f2d90b77fcb0029fe859d91aabcf3ef43ca1741e35dfb5b5bf2f9da94fc5ff5711261e059eb67f7c71eb3275a8cb041872288ac91546f4fc860c67019774d52bf7a6ca010a5e10923fea9f66e9aeb9852f73bc3b0f14bb213da550f3630ced63738d8fab2b3b660276aa06dfd86a008a80770c0b13d5f5fc45a319800f0118c1bae29ad8c9efe5b3776de970d6e98e7ac233b7fd19199e6027d027767ce826839ecf5e6c0b7b65473dd0b0630d6a236770b921beab5fcb96a92d7b7a5cfdb38d64a83141aef559c2689336abda44363279b44dd1bd92fd98eecde8ad44c3e6d479c2c43bed673ce6a9a82a6662e5b2d64fe627350203fcd540a5e4636b480c73296c98545554ef8728cef12d72fd726d5c3372609713d618794c872fd9345d252f0937e32c59ebf30b746dc1fbb0d37de6e24aa911de748666a196ba499b8b806069d6d8e171263724dffcae4826bee998f2ab43d5fee56b6326fe964164cc6ced3371d91d339afc28d6fbe326abae9e6a57c62f813b62f4f66aeab8a64580a435c5c73a647197177bc40a97684f7a6a1f55aa1455ed9726d8683ee0f140a3c226891c8e448a6cb03a723839082d860993b329c7934770ad9dc19a66bb1ad1af5fc1c5877739365b935516957a8a7d2c5baac07fd7acae085b4eee9f3ec4c96ce90df38ea5869b9b231f043f9e32b18a06b7e4fea8b21ea3c2ee592634ab3b39b5fe075135888dbd35503bd6656d1b9e116032d3b099423535f533ecfee7155c0deff44ae18f7e504ddee6f8c6e0ff502bcc634f577a3b6351425c5fabd38cae5a92473c7501e9dd4fd120ff75709afd95a7e4b0c6dbf76c80efa56572f1c67e703c84f63ec5b069fc1688c6976a4c4b4fbe981c3ef0ef42ab9fab2fdd9ae8dad2d3d7132666a31fd1125ec8fe0977a2aaf728f46f74615821978c4bfe588113cbda8beaf7c1bd9f65109a165da72329ee788b48408dca3d184dd4cb234656420ece3237222c36c4085562082865ca31660bf54315998cc804fc7cda6c89c4604c9df56b8ec907f716d15d66999f004aa849a6be9d9e91a0bce969cbaaa24dd8bd375da4784550ad4b925b9aa66581dd15f563b9607088e912fb3b599be58ca895c819c88ae7964bc4a955a748988c5a5408a8320194cabde9a16681429563fc95cbd45200e3b61efc0a2db800610d686c7902abd05a01b794f9c34a55f72221f2d5f787e91f69f1d5ec27de1397a3170677286559e3f6eacd77a7ddd2d7d9be72f893eacc360224f78b78471ea372a1da345dd8d7accdd626de4733bc96575a768a4b14c649213e81da38a300483ad9743882d4953764be0bcd55ddd13ea23c38ff66d6c455ed0700ee0c6dd2ae2314df6355145a341501a0098f5f604041ae096032394a53cc8522debb87b7ab777e08c5eb02bcdb354c9257ab9b73aabab5447976948e8defdc3c0c84fed68e2614a3cee078045d1f71db4f67b23a1bd1eb932e30010a6896c51855cf5ae451c9e7aecf3d1e79c052540fa4baa15ecd0e061e36cb5f28ca79302c5ba79fbc32abaa2ef6fcb6681645cc63796e90656c91eab7c6f052372498f796b7c69832e67eca8032a302837d9b25cb19efe634b346108e5855b92b682cfb58b8dc744fec23abd5ae3b3ffb12de02e3a55bc2aaa426c98049aa9f408614135044767a3ba530c2bbb5e86d99144728973ec98dca7222d97cadb815783221ca1105512f94a22c76a80b1b39426ee61e22080b29aa3cc2ab2a45ba9865cf13dc7554449d6a8923250144818c90e4042a61953bf6cf173e072ab1bc4030e3bb3526b0b64429e09109a3d1ecd97e3f60d78ff5ed916ea259448e8d99496f95163b9e94fe80a756f5e7e6e835c76c7f2d9eed88de90a95a8c5e53bd6418dcdf1e6eace185dc3d4adbb8b3b80a17de9d6bda3f71ec7041e12546fc0789dca9c638feb2b724a7f987a62e081a3b35de13672601abd58fe43672f4a9fa887d2ecd316a3f904218ca4f026ce99cba9275d6b282acabbdc667aa2ac3ccce385f3614d5d11f8951f1647a2c237fb29cb9f5e6185ecee5b127927bb5dc693d82fee3c6b28829f761e9c4c4079ae70fda5dfa0c934087fbbeb5f7da9276a70845ca2e917deb7f338c398f784bbca0585b6edff750f40ed21435576adb914deca390236de6b19b033c9b1c9bae2dc74535793dac8131fb69bae35143309af993c3f99e4ed29d1646a6dae3eac932302ff5883c503e917bf0d1bfdda3bf01515ea88cb82ec1abcac362464cea58b3f652b308bd2bfe4e5f9babf4134f91be2d42b0702278078156fd972a94042a9e85a5f3911ee60b4a1d6c921376de3f217319abfa555adcf1855bee250e2b29503a7852bfc0ab72b06ce47ecb755156f4308a21f53246b44ad38ef53a2017190828cf7668115f0ecdc06052e702dcbb2de9474eeacb9d2cd85b08a545a3d35f85fcfa48099602de2cda3ee9198a1314502d60cd8b032780812cff9db71173b7f3feb7de3943928f2175cbbade61c394f3829f6d8e2dc9578f49b996f36e8b673a25bbe02ca5af1acac1c0e2898ba9b6db6720742bd50d7f6399e198ea8be931b4b301e8cf14624435ad1516529ac5281178fc6856a83d13fac7bd6540aff86968e36569c9267f9624f4cad3ffd2392245f5bbc9ce95720348c79a76b80039b0391d5d3ab9d396a509df92f0961417b678244a976c34425ed364834c8959caea34c7ae1098f93f74de0fb2f26c2689b0f5616cea98fe920bb80a697ea2e5beca1106fd8cf6d2a148cbe5f837b8925a97e60b75ef1ac501bfcaa58d7769eb7726ce89e95d9910f857ab4ba5641a98dfbb439323a1af50938d7773a05974fccff6e3bf9b3488523fc535daf974ba95ce4e6f88504a90648b9a8d9c071e7e6cd3647aec780ab3e9253d4d9f92a19c5134e59520a8a582aaa6bf3e303b2a973572846ce7579694154e885208a1ef0f3594d71c37e1a6393e4372b8076d2b99f2dfcf2eb7cd4cde5d4018f79a6a1f95421db0ad849b74ccd6e4bf963452d8fad6c6fcf80e29b570d68afa0a79d79274a38995150de010c65b3361b0bd59b282673b286c2bd2b1473f8eadab7bb0a8257bffa739bb5aa7ed4db44ae8a7f91a896d69549147b893eef203882fa3c09703c602f3913371c3059837d1d4ce1081cfe53dd942d5dafc25fb5f53354fb9508442183883555cabe44214efd918e38c87ad5446af5cc2574ef99694ccc8ee33c4d9d8aaa268b08619bbd8727bc445242541b59109c28a23fe163c78eb63a6fc11a3495d541164efc54d4d97b23787643323096fc4b830f52840c561db17794b2b65018cab024f6f47e6186ec9005ad1dc1182470bd19f6063d0cd400a3bc735047892eef15eb8ee57a7bd590f6aa6d799d835acaf541d2b1fb63ddc9eed239a86869a3b5b2d6aab3530d394191f888b7f451b9ee706a856305de5ecd14d4f24dfe6da24a80614cb48231aa34442378c8c2788c50e0980a9870da20417c9e264986fcebc2859707533daf187eb8d2e3d8a3f86cdb3fd2681643308e87a53ded4ca3e681d36cd8456fb209314d9f73ad4d31cd832a32530711ef784f4de06bdfe166aa9c80c2d5da1765ce4221ee36e4cf53e2087e49de0a25878bb6892cd4dcfc5e689564e70351972595cbcc83ff896b87cd6c54db1f1924616c7a9c3cd0249e2dce7dd3094d3df0a8dca967dcbfcfae15e981779fddb2c760004e7f031210eea5d733a669301d79d7295ce7ea6fe2db9b34bedd3ce7e2db2dbe6e59c93ceb83d92a8ba79794b98ec2fb63d00c9209e4fed0b32eb56ad997af275c969120e6b2445b1eb552a7857779e6bc00dd20bc95a3e31f608d56ce68e4597dd15253995fa05dae9e7fa2ee726fa8ae23319ac2c0eda39967cafb6ca8c3d54f60fe9f39e595d467a779e234fe3b7689211129142e33f50fd3e6cf42c1e7c8508db9a95d488d23a1880e8c0870d4ed1943293517181936f4d0fb9318e3651a03f4596ab8584a0a75f76a7c90537733b4427194a282fca7e044a343ddda86b0ae2fbc800c70b7e2096bdbb622e5de4c99489b2ae94885c9a045469e080523c24af35bac577c03981fd8deaa517a3a0e7314cf4913b182925a1c002b8bb930417193a69c99faf53db8364a4c995cde48ae8c88165c1cce6d01a9b52bebdeadcad00ac506f971458ac7118b375321d79086da9b74188a98e60337b1e4fc246f74515691d74f219006b600bb150c6be0c1a312f19c7d1c71b4cff4be5133f6c07fc8b1a056bd8d3cb432fd21c652dfc7a7aa72b8146df4b5857a3bab580d8d3869a286a6b3638aedd3ca61291411241e504f0c3b18070dbed50c347241191dbdad535add46daefe993bacc88e02d648df3ff0a6bd30965be398faa1b0cdc0a3eb2af3fd2135edcae7c7b614ed2bed2ab93158a07ea95ba9c07bfe81476b636e34cae17dde3222698c9dac85e955cdc3818a523a578f53675f4c659352e44ae1e1bfc21df5e6a4416b52d5f058491b8a3cf194916c2d7dfe312e39bc3a1fc5f7ef98a9cd8b4f358fea265a03a07351d9378f6b204c40f6a79af25a6d3b08164d5324839d7b284e286bd9a0d67c6684cd168a44efe84c1c46e044f782820bd07b93c4266f0f1efaa6d58b39426bea6d4e51742903765a501b03e07c2904d1126c842ec8dd7a0e4d3bac2967bf089fb6bf6e9f1c4f7386b75a31a78dfa8d9001e82d23cfa777b4a965b4bbb41d8f589e2ef198c28b55f3d4e985a92266a1d1b959eb93d3137971b8ed11cea5ecf6ea7b5ca52cc8047a36e58be82291461c49733950d7a1d58be78345b1bbe7f62735c6024b30848b06ee881eb0ff4bd7f6e1a7ace6fd4516e297963ade6724bf9222b55518b27d8d284dd3d6499077eabc8a9bca029843e2c221516a52d0ef240b00b7f565769a56432d0f49233570779d286c34c7df4a8fcf608bc61ddfd8be589a99a625be66c2bcee781822dad61d7254962694ec80cbeb5e5b47135be2cca05f7c48c9d117bb9a3af54899c13cfbf12fb17c4736e7e9490581fd5cb9c15493ec406ba30da3698747507a2c768df207e57b19607daf8b9a4295cff886d20ea52b33bc20a45689b90b27371dc6f99da78203a2e7590529b6695737ef8382197dc90eb65d04ec7ddafe00b38ac50fda60def25bd1bf8c1791fb0d9621970160779f9395c8af0b0f5ac9ef5ae62c9980a781f3d544ff4f510043f4083e260ce8d1e4c37fa83551dd05fac5ba8a533db81784c3f42f7aca2e4be2e958a735f01df2c6377b29605ea26dfee5991e86ed46e9c45fb447f59529667bdaa859cc84d297f861ee050ad234a2d5cc8009ee26a83a8f0d5530d3dd55d76e08b196af301e9ecdd7aa3638ab6ba8f0d6e381e9319d39f707153fddbb06724ea1023c1669aa0fa4b2d617480b13b0faa9ea4c565d4cf1d82ad81961d0a3d1fc8eeea4e5fac4078b14c865fdf2f48897cffec7ee497f26293b3a2bf3f2b30bb905a0c14785e91934af8cd061b8bd6d7e0065f146545da8d2c228c70796f095b23cf7c41a97028fecc26c2aad861e85457081fdecd7e8178e409abf160eb7d9528821d824e88b92ce21ec333d93162702aa180640989022b1757f55184b7f09c6e985c5b9e9a6c8e26a55fbc578d2b526e3b083827928280be7f225fea4d1a4ff7dfc673cf52a2a38c38bc2ee582cbc305ea60ad35a0f5aa8e7222b922079db925614d990b83cb79af01727bdd103d095375a40c1964e3e9417abf06340e91c87b01474f45f26e6ddfe45854da73c935918881aebca60776bf3bd02be5802abd55d2cebdf77f13a0ca7e037b448ff53c50650c56890aa734f26906aa1c69842b1b3a30bd96812a751ae4ea0ca04a7ad600558ec475a1ce08bfa6a719a8a237acae70cf72d7cc0f996df31aa8a2beeecf417a60210f6befa2bba6aa2467b9f106ee9557541fe59a31b46179267740bfc9d7b7d6c8a929e077cf5e7bc4e4a262b794fc62f886543f25c558a89f5c08dbe3d01df63e01fff6444bbe5854a05139dcbb36c7d40c21ce4cce6b97300f6f4174cea483e68e501f462e91d8cb95ace4a4f892224048b76f78a4d09058b00a257c997ab4b8000d233f3ecfc188635cb969d7a76987bf07fcb7b2315137b026c7172093507807b92ed30bbeae9294a9436bb1250e0f17d9619fd82042211ef1ea622a5784d214bd5a1bfc420973159d2513254d01ff1da602dcc8970b7d5dbed2d7bfedc327a35fb5bef5c5461247f35a3e6ff1c6835db98322910ff40eaebf2fb3937e28caeaad7131acab34aceb52bd4c64fe4c4da276e61849fd83099ca01185c73d00a8c6646c7a2dbaca43f903af486b57f70c8765bdc8fe4d6582de2856a06ef4d3df0f401a3fa10a6e7bbf97462cc2af91ae528fd6da179e97f184215180bcc55039bf7f1b6dbbc29935200ff86eeb7d7e0eb647dda60fe397ad77f8a0bb07ae0e4ae9eb6e45358a1de049b652f81f56281cb1879732dc6f3dc45d5ca1deb46da627ea4e3d263968d80feae4a32c164dfe0df1fdfca6669ea99647f59046b8d4b4ee73e5bc576aa726707d5e94b42343a263c060cbfcc40e44b093712b3f3046f44b4de4247f385a628b83d0f4416e565eee64a1e95891d87a1f18c235ba7bb03bc82c9ada653eadb16c3061d90424fddc0c043a3bcf56ad6a0e4a178d5ba6d2123d79a66617af356d71e11c7db6cb550378a9248fcb1126b0a50804d3d7a679d1134a2c509701865b207a2f34ea8b7019742fdf0d3cfd7754b6c53fd0c6f3561468970dbe74ae134f20fa53cc63d915eabe6a823a9e50777b034d3e4cbdcc65181da79ea900eb112a2f56ac17c23afe7daec59c3dbe250f0e98e0b916ce0cf8593c950a39df8f9acc03867fe9e0dbfe83def740fff8652aab12109fd38da8623f1881f0c12f8d98978d0be7ac7c445196b4e8c21d2f7a075265ae7e65efa38075b97d662ef413839aadae7066d2a2383b409ee83d76d7fb339bc6c8139edc9bccb3cf7829a22f40dd46879ed6b008fb9b5aeecbc6f8cc6892fbdc9f53fc18cc72073fe67c70911df43ef64b62c26b274df455e316ac0344f3aa7e3294c53725d138f40383ea7151f632cbf87e7667bcfebe10bde91df2139765c3be150af1427b45a40ba0fe15a7230268f072737dda966cc037f89dc95681b87792f6617d78210714b471cf7206be4bf3257ab43c1e0dc3a1ee1d0a7cbf153eb2706d9f9c99b259f27230f66e2eabc3b1f2352fb272244e4a25a47efae971ce2c7c4601f71b68e0c0105c51a2e2f0d16262c957226c7cf057e8f0680a67885f9b53a2c2db1684bb66746e0a5ce2f3436f05261283f79bfef3ee7078291fe0ce82688ab2019a8209eed54481ab7e0bb1dd60d36257c8c0041d9b3f38e06aea378488ff6e671d34f284f00e2d260ea2ddf88a56efb96c6163bd466c6d2a6b4c6174246322a0b49d0ea6c7f9c9324826bfc60563eb24ae6eebd68a84b743f676becaef283d6faafcaa7b52996f7c260ea9448d2cd0d48fec8f6cd37fbc8576ec0ad18b4c63fd25c766073b763d683675a8a3355542f1376e16279f40990755aa041e1244e216dfb266cf0fe9be099810ba71cfe262daeedbbeaae782d3af0023495692731a23425740764a59fadaca7163c73673f6575f8ec1ce746e05a82b760cd087b9a6e62809e8112d9e2ca57bd317ca1fd36ed9118c1a88f614320b12b27ec2155b8e9629cefd002724673990398b249bf078ee181f83fb969c21bfed595b11eabec14af20c9f58387fd35d1b139c4664c575abc829e9a3163f766efa1d02c63ff8a845ea174c380129bf3ff5dbd0de2be097d9134fa47ac86e9dacdadfdf7aaa84582a6d55ea79042b6356453d3d2b105ecb6319fa429840578bc6c42b491f82a8fb3941a8fbab6f3bffea05d6f8b6b4cc3360e7f99eb7ef734f8dea03d3f51e95e76b8b316aaf038dd165b44758b8b702e1cee4e8263711bc31190141013ca78b5c75e3d9ba9d3997e7f2fa35c9eee0ddede9ccf30515f67a39d1b501650b8477f013828bc0bbfae30cb7603fee9a51a007fe821256c3f199f4ca90b86456f2ec584a5429a2d946f8b43f29f2ac2409d7dc97c8ea8baabb57b58afe929a9bc8930b2dd633d9e8d062b6fa6b2d5676077b5e8fb5347de16e9cc2f02fc5f8555fff428811746120bc4527297e9a325a58cdb2674562e36ce46583a3833df5897cd0fd2750843242ad56caa1fcd8559b2afc3a986322d15b200032c2e41dde59294b2aae09cf27147e34b58b22d14fa0ea8be75c32975fa379e952728923aad8947935cc2f606f3a38dac32235e16da1d6b79e615a153993b100ca9b67a3c88f6e030fde1ad84083d71866f71cc1d110ab29acf06886d8e3d308bbefa98a133878704095e8005b3efd874cab5319ecf64d19e86ff8f6f4f47345a52c51cfa8dee0b2cbfa8258ce66f0134d899355bdcd99c9d4135ea701fffdbfafd4d543b38e284dbd0a16a70a94e044663bca394db5de11f619b548d5b1aac925166c22d2890e301cb231ea0b77a7627466b041a1c7aab628dd1f22d5ba5af3c530cee82e2bdcb297bbf53051e7926ef2c33f95f4abde08f32cd69d9dfcfa11094f2dcacc18af27707aab40b4cff2e22997e743112cd4d7a702d16560033697cfb4811bce66182ce90e25d01bd0353b141314db0bcf4c6255857ba2df825bed1936ea545295af9fc10225b43aa309c8048eb8fcf23ea17114e66fa6c55de6abe8fbe65546ab0c84df6a2f88f6de71176412ebf1ea8b068660ffd8643a56cc142a24096c915ec92b0ec3b531b2934e067459e311dd52eca6a68f2fc400d3e49d83a373bce5eb027b8230c6b0e4e91691717917fca339e73d703333c5887d571f1b1246a3a5ef3dbba1d4627192a3964adf00c523517917c4732d68bea062437f6d3e20e9a1706dacd6707eaa76b6e8ee5a9fecad2d6fbd57ad4e666b4ed4d1cbcf0102bcf26e83ca51aa1fd3b934f4f6eade6c314814b9bcff5c2d32274b1675b206be41be05c85d433abfa131c2878ffc8f42998098ef364e50468f173b9c261ecdc8f64a3a6f70c4882ffacd2345c5cc9bc993d1566e271ec96b911c97ec28583a99486cc9790161e3836402afb518f2380912ec687c488e1f2b7a95ae15890054afdd2d2db7edf0726cea117ca4d919567ea61e0c6422cff243d55df0f01a752672542199609905c760145385f58db769f3084ae417b230e8af35c6f07b8b9d37075e877908f779e4f2557bafa2109011ebfc3327730fd19164b8a2a13676767ab4f578dd3c1e73a4e84c4dc91ccc996307e0a0432efeb1248091077fb0c758d83c0b5dee90e82f6cd2a24cd70dd7dbd4eee49aa08ea26ab14bb1098f586736251b98c67467f262586efb8f5657fc1023dc2282c3fe5080f54c3e5ff8aa7a70a48adc11fd584af85ae0e2eef405b945aef06e66d9b545470ff98d23f83d97b2c6bba122fdeb25929d123bacaefe7acec75940ab3dcf662db416b0512358e885172449cc51ed632977587edc5ad734f3859aa943e722f459418f9bbb506cbbba4a639f2234b1cfd3a315882076d3fb37f65ef62e1b80939fc8e67b1a1fc9c15f9402882eca545325354309c34f0fd7ed4dc367a6a674776bb66f07c26d38eca1bfbe12d495baf9da33f8d3e8e0d4ab46c0f59cc0b8a2dc1c05e20e8ab6adfa10f904459fd990a3f4ea46b50345408db842549f9e83b6ca64b898f380639001b3c0cf2df08b5ccee578cc8a8574130adfab1825a40b786a5029742e3cc7e966b52da6a34bd9bb85bd87345a739191cf69c79dd387f75eb8c9cecb3af5b0915cf0d4a77871eef5ab1cac6061ccb352b7fe5ce688cdbba9947850ba5b1e9c35ecd3020657a4980a4612e38ed1b22533d7ed8a60feaae5c304a19d8f7fdf66cb629bebc34a0f1630d0d75ca1239ee6321abbcd32f9d81b1445e291d52a9bb0568f364e03ea276390bb3b40b3e6f6d5278d1fac94eb9971e6825eed7a96e1e5ea1c0c9e7216a3bebfa1af4fa99e75f7c4f8f6fa316def0befecedcbfcc9ab43ea2df5277279e08709fcd34a52bfe7a2dd509612dbf60f4ba524d4a064218d9b00bbce41814281044bfba87e6c9b540a37d561ee44191d862b524d65f922b0a1cab945b4c5bf6bca1cd25b97a150425c0ed0d181f0813be4cfd75a3cc1e8dfce3d3dbaea30d0cdf2446f058689d6da94539f4142f5c060b50ccea5fa69119f725193b82a2f371d0221ec26825943acf5e1acca3613c7b80e2e59c77bd7fc1a72e4b7cb87362e88a75cc311b746811bc0a0770c6ef6f470661232331bb9c03990c283ca1e1ab54cfffa0d44ead608c514650be64434060b658d7cc3cff4a1cfa85b0343773d63be704f88394c337b2675afe6aa256cf7f491cf1382c3e78a2588ee98f5cd043ea16e19d13b7abd90aa6fe37c839263c57b1d2a857e6b15667e57761eb6ffe5dc81570af513bbec0e6e4164ded90b6afc5e40666b50db79a9d8a22a9735294114831d0a0747c52526cf846c47782cf70cb5b4971efc78e986be1ffb79f935cb340e7a82ffafe5b799115c74445a64235992f472afba0bccdbad6a802a2d11a7a006cf42bc9af3fcfbb955c67c3ed6e885115bcfdf95eac894ce7476cb4f3d353a974f9d54be1c35b9ef483169644112b352d0d81aa3ca1373a78f64403d4c16ce834df34c6fac074231fcb24068eb3bcb17133952717231d8929e1966ae18cb92833c996853d743e223e65d4a192efcfe68a8dfe89d34783cd4836429716c94f31ba1efacb5126359f3da7a3e6615dde654687921fb7891b5bc5d5032d3460e97448bb39677d6406c645d12e46a2d6f1a4420b891f7a8d5bc96b773c2516fe4da695c2d839722245560731d273737e99f31d9d7e93cd7bf809e67ecef0ed45809af9b4d38c5077b046d2f7e7d1e0dbed8cbda43830b90cf178ef1c9bb1f0b54780e6cf6a361683334d74702dc8233ac9a483f8c666b5c936be70bcf9649932bfa7b294aaf3fdee7ef3551d7f7aa71f1e85c3b5fef9cccbda6704ed35adeb7eba07694d3ede55d0a30d96d60cb1772d18513718522fa7af4fd2c1d2eafa11a055e2ced15b3a7af1d38c306427d54ae1ad7f5e2e2c5325e5f88aba072bf82e504ff6e46947059417d25238e8397fb15356b32df76a2c4c5e7cef8a5f8b7d7585e343ff0adcd079a6fe0dfddd2eaa2b9cdcdcd279aafe0dffdca45f38a8213672b19013c84eed77f9f1ca260383b4b2a73d05477c78d560b2db5942b026235d51d32f1a8867c6bcbc5d0a752a8db05a7e6d024ded63a185eab06968a63115538aa736d6a4f9ca373d8f02acc3599ce205bac12bf0b718d79946f90b519ea65fae45482395d1a3b0f962fc64eddd1cb52dfd450a317ac17e8c22de55bfb945d7173de79599d917686bf5499fba0de36e425ea09e67124dcbbe682174f683cd1b5475c8e84f37e734f9c9237dd6f195571925c38a2890530bb16b5d30b23273dac0d840215610d565d38797fc0aeac717568d820017c99e3403f6275c38633eaa37517975b192656315792925a18f39ccc8f4d6e3be6a684df213b5588297a8219e9c3a6e99a7af5da7cf52ad0c3236c85aa1228fd19a71acec9e3ee6e5c6c501645372d7a68f6eb4b34ddf39536156c5207a739376548c09c122ff452ebade418e45527b9c395d108f36249fca55359d3837822612cae4da26b54e9597df1de90651470db17b549f5122127780732240ab376fdfd96b31ece6cef34d1b9737afb92ab7b57095177976cce5acfe28eea77289420f543cb1533f968714931ecf733fb72b3fb645fc6325fade5dabaac033f7462a281c60aad470833c6f95f64cb46fb2d54ee627751df6a0dd8e7daa1e13751670e568c4f9240ef4735258f02363bd104d9dadd592f6db5a5b04be2d3538ea8e38395a5b86f67dbb18a7d3d0190951c4d018608923d32f0e672040464a9745d724b74473bde58b5d8529f71dda722569a6e69ccb5f1e85974722ae3d772427e2530e9711870deb6fac22da9156ed53b6e1999cce323d96b43268cb159036f526f8a467435958aefa56d23a14a72446169ff21e19b54c12cf2fa83f8687734fabda93a1a3c88d9faedf7bcbb41b9a3144a46b51736283af0556bea2399b5d792df74cf7ee3625f9542e580dffafff47fae0ad99b35a77739cac949e67b55d9b275e414687689e576956aa6ca3c09648bfb96eb00d91d62a866f75c62b29039fbdcb02146427532b36d7d60ad7b7284c741b6d299dd885a6805f5c1fcbe043854da4e53141bc29a830139da5338e9c900424300e147a73c846fe719fc824b9e0e47f05620b44cb58b293983ce2a1ec147b07d37d95971c76011389b5c3f26b8cf08e5184cee09d5d9d89fbce1fcf1be5ed5d7380d7ad206bf5513fb9fe1ceeea4a1d6809c47ba9fdf45e7e9e7e51b95f98d129b6634b906fa47aa9f50735828784ebcd702773b31237c7c43e866b97a521000b596c6d9fc9f56283a825280f63249729dd5f4b389595e724a63c6a200f615ef43cf73c75db10859e1ac3ab98ec276d29f9f3c72d2cc6a1df366216757aecb94dc706f1afb518158f7c4526ef8c67cab1e3b7e693aea1113ecb4aabc41afec6892bb02602e47ace00a25fd4729f0e4537dd8c59ff4b01de6f570fd36450d9454a6bf6b6d2b10ed07e6af5b00eb724317164258a909f91d8c2f66c4e9b694e9db906006f2ea4892aaf1e2ae805522194db16eefb98cee1a1e8ffe66cf30b1d64e66ae2abc1460a8f96f29b22f25b13bf9c043eac8aed89dfcdb31f22d2ad91db24315d29fbd65eeb81ea37b84332e9b87334c8fad63f9d6ab3ab4ef69295d5323450cbbf76265b2582b39f866dff244df36153ac9917c9b0dbe438d47e25c09173cdbbd63ad73d52a31add64a6c25373b61740fec6687e1d25ab2e5267dc55aae0a7ac576d310ff40efd80a6c27a57c6841dadec53fed8bab6397968b65a10ddd88c3eae7a7db21a9d9c5182e374d0ff0b8ccc0e8e19aea6cdd648db72b6eaca756ead4447928ba10b8735ce8de7c7d0d27e8327b66280e6aa10d4e4559ef11dec7613e960ffe8867fd11aed8d2b7b9881b77931509f3969f30a7a0824bc06137d2efe41c7197892c9ddbd650a857610d852baac4b7a6c5a06f73e6dbec57bcb4e9293c915481e8e80afa7a9712ea6a4d2755b1f7f5a6635ce2ee13cd1e6d3cb8b3acbabb1264850c1dda6a621741ccef7708f163f1522f53ce0aace2f6c3d29e4dbd8482a335d9c4a3e8fe6fad26bbf52694d0fa634a62f5efd90bed1bb4007dcc8d56170c6505ad59bf00b2b9018364dbe6adbca76c2569612c84639e8e332ac6a31ec7bc4956a6da5f1d0ddf2119f5c1c91a8150aac95fc343fead8e7f99a61881ab73bd6d85c29ba81352c5b121b2bf7cba1bcb26b4c53ba5a1a7e25cb85c68da67988c9e5a047edd73bfbb0733b1f4fa36a712e01eaa4e06dc9066d411332abb0c33aa7836399f18456ff9fbb8741f77f08021d8e38c603db0e2350656367ff666a46ef2f3a709a705f289f82aeff6eb0b78f2cc5b5a5d8e9c8652f033ed8a6d2a6acffa6644a46b01074703444f3e38e4dd4e9777f5e4c216cfc0f2cf13d658b497abc907f6d216c07e0174e9a1051246ec30a6d8375ab97a8e9ddcca45224181077f262f4eb8a6842f968d4f58d1cf3b11355308ed06b334722082fcaec38bd512132a9c4c5cb3aa0bbf8ed74c65322518f50d5081d3567e5289b12cd85cb41c9385a2be0bb962a6a1ca0c7bd2e51c995ac80e3f8c55265f7f82aa84e8ae54cc91705b728c3d57543d38c810edeb25a1c6a92ba3b597f259cc648c2ca4881fe4516152f2f5adb92c91eed909b73a0766195333790237f174cd3de7097f2167dc723ea11e092a0470532fdccdc79643bb86983887d44ef2f1121e46073ff8d89219fc6bb8c51b1f3eb51cf8c927b8c7d9dc63bef63865b8424754c39c29b0e3e04082c91eb0f638cdb4860b4ae682f5da63d45d838eb82d73e63880778d024473e40918f8a0db5075939cbcce390f17f50e585ab255fc365dc3bd959c72f86abff64c779b426281500bc5e973d191e7510a0460de5f0645d42fcc0773d3a2b928dd4959be35962abe452ed96031e60a27e41984ab64b74489ba3491d796f10de654b32d44b31d9ac1a71ade1df27ca68e1053a79b9ed8b945ce3dae3a42549d92935de39e1c2eb7d92480e1393bb7728e1822c63ecf4e555413e50289b1d99699abb74643f20532234f2ae097b69e586e22ab2a532e47d44e81d7663cc860effe22235476e6e05836287d77624821030e25c7aaf4c1955795502f05640fea25f3d64927ed0fc6f30d85bac17cb05e85bae5c9b69442fd608775590af7e927de520975c7f6e2580af5c87fbfd39fd4e25da8a7cb167458ef6d9ff8ef40b81f118a892a3aca3b09f5c04f7c16ea0e7b7fc294ab9be34df686bb3e4e3c0b75b3efe3f8b350b72dd6a13da16e40811fe8bf6f632f3b8e6d0c8edbdc7e20d4cdc8cbee33e307f785ba99f37307c27d78a05e3f1237894ae42ccc66519267a51319a4f289fe2ee7fe1ec93489836bf9e8f5bde58e427cb912aa738b2e70a9077c0cb0867394754241187f829e28de0cc3b8ce4584f43c31cc5c63a62127d21e97b79eb7ff7bfe0ae855cde39eccb2664891feedbfd2c7a198690c52f41d3ba17c217ef08430191abff8edb38b80d7134ebacdfdfeb291597f55c91b031d401c050f87123b1fc83f4f65404d2523538835637e650e3db568b7823fba2a5f7546addaa76eee2a6a6f9032ccf2f5e979ca769ddc354350c1b1b73e57092d7fa12ab9ee1f5fc3ff536777f6470fca7f96aab94da6404028aae1e5c0df38c4b9dc4dca8f79df61953f9121c059766bf05d6c513c7c5083e9fdb166ac1cb395462dbab9f0ea8dac9d2f7cf23b763046b6346f952830ad14c6c0619c4b2ad7db64b722f7389641d3c9986d6b3d67730a430f855f23a184563e42ef29047e667f65ffeb5dfeaf2fbc608b34df5fac7f26cd4baf50304b462e2b5f47886d7e953b64abdc51097154b955ae95ae7270f9e756b9953a9d3b4c3e04029773a5f32fae3445bdd20c3096c35fada32167c3b98bcbf59382c0215cd9eb90f7f3b47efeb04c86136d6be12c8bfdab55ad671d252d43f4f71e7fd348dda7ab5d8fd6b2abe386a5efed97eb5a2f5bd78e0c9bd6627d8b89715104a36d76f06307bc9ebf1df9594b7b8396854dae6583c142f52477cf16b76ce65b1a585133dfb2c12debf996356e59cdb7ac71cbeac53d8b7ccf62ae65855b964dcb90c852a69c6b45d10575b168eaee4922cc1fe670d2ad28b59349e9ab409df56b950e8ad8f0740bb096ba1b591f66351e37418650bdba7faa509c1c70b6cc77af7c7bf751e7578b74282a9d3f5da4dfae6c59c31bb952c6963db9429cdccc964dda6ccbe24466cb36dac696fd87b31cd18cdc2caffd9f98e5d7f6e4e5ccfb6286fd8399177d39f3b4c24d0dca41cea08c7206e5206750767306e5206750863983b29f3328c39c41d9cf199461cea07c16eec3a2fd6b9bcf56ffde703aba421c73c3e96086134e64c3a9f6bf3a9cfe6b168dff0ca7df0ca7f02f86d37fd516c2fd8f4dff1f9bfe7f904ddffd64d37f52dcffb1e9ff63d3ffbf61d31b333a56ffb5467acbfb8f55f51fabea7f9055f57fd431ebb91b7cdfafa64ddd15a29e9b3635336d70229b3613efbfe5b4f9bf67b5fb1f31450bdeffbb4ea540d4daffd67a157d722af17a35fce45432eb55fff3c4dbf1c47bff3cef1a3cef869fe7dde2bb7937a279f713f30e6387f984f410a179e7e979d7018a42cfbb1b86dbe97977cbf588f4bc7bfc6919b2e81fffe65c20aea4475431d22f78cfcfec09f50373c1d363bbf3792e102d780773018146cc05b4c75cc071cc054f8f910ee6020290763b3b3eca1d9fdd64c731177c3d17eeb15c515ca0cd4ad9359a2a209fd2e9ef96abe298ab0f421fa41ff5dd9f692f5efc997ef3c59f9ed10a177f7e7d5fdf68e5cf37fbd583afffec094fd526572bd4672441c115a2909b28adf66f91046b5788b59b9f28ed7f8824f8dfbb427d13cd9fe6a2f9d35cdcbe20b378fef0d3e15f84f307d9a231c82d1ae37c38ff39b76a0cbf09e70f72ab463fb76af4bf09e7f772ab46945b357ab955a327dc0776af14e5af56e939e5465c203616eaefd66bd7f80344ba7edf914320ff9b28d77ac2fb58740ccae0a8be451978a62c973077e7b5482fd52e8a1ffa2b8c8825d779a65247193e81c963456f1583a7724929b5edc470cc827768e5ea4f3e4a9c750e2a6ea19a16c615fd2f12de4cfd16bff0a7ab58f70c105e7dc209490b243c18ffd0eadd32c5d66ea7724f2c5aea6d4e20b6e71bdd6bcf44f05902e4b9bb7c67d74e1fae2f17b8a4fb953eaedcebd35e4db640bf6a056225dbe3d8a522087539217ea185aca825bd914f6b2b15d10d7705e6c8a72c9b32fda3268418858be92fcfa01c14fedc677f4ea5e835254960210fb2da4995462ccb15ae1ee25f383da95b40213e67a01fdd6bd1ca9a87f9e669bf7ef3db70d884f9db65176f65cd6ffd5ebf2a3dc143aca87b4f88bdb7fc917ecca65328766072ad3d21d69e5de42f0d855be9b0262e3a4214739ab8956a62add55a116e8e56b99b276e7a739c4b6faecd1eb700f7b35550c27ddb3db1fe8692ce5b3aea17fa3b76ff89ba1ecb4c5f1f73fabaf0f546fc3d336c46da8071b3c38ef1c3aa1fa916739fdcdc512d9af33d326aef4038191853e1977f31a9aa569a4f7fd2b02c85b790db5fee2efad942d1cf2d147a11ba61277a99d48fba59ede0815aa27ac0ed0c746bfe149c58370b3e3fe7f30b3e4f16002f16533e37c99fe305636cae2b773e6d3546746ff7c1de32d0eff4cb9503bb8d8b9563f26fac1cbdabdfa15e39fa172bc73c874feb99958354e82b80bd9621130606f8ebbd7cf8f54e1fe459add7748dc8299becb7598e02ceff0af3bf9931c71c38677f2bdbbb7c90b94f48343c91503e1f455183df2c3ac91fc7e3ff005cba6c0bb1cc814b17bf07979e1c214ef9bd53e99f824bbf5429dd4ca5f43395f2fca50538ff9d6bafaf5b3f5efc490d5e33f32f07f21c5029efbfd322ac12eabfd51d9f2e69e6b4c877e666ff6b73739a3737873973b3f78db9197e636e86df989bd137e8d1bcb939cca3479bdfa347a96428cc9de75da1630c37b5917bfc7a3d1452e38ceb2be70cc1dc64a1253ae6cb94482f0b857a30f7cae625a98599cab7a2c481b72d5fbffbcb332046f7b93eb65ac85c33f7815fb32bbce4b753b8e5fe8b53b8e90bd1f473f8f01b9ec2634788716e0a6fd2295c504214546e0ac7ffea14fead5550ce5b052a9bc34df5e51c7ecfe6701e7cbd965f83b24fbfddc5e5a6d5f04fa6d5fb37d36af8cdb41a7ee3fb1b7ee3fb7bce4dabfe1f60685aff97bbe7dd87cc3d7fff7fc03d2f3eb9e73f4f93625b88626ea53b9b950eeb590e7af64769147b25c4fe2b37e12bf1974f556e9aec9c2fa7c9309b26dad8fdb5b3a3985beac65f4f937e364d46f26255fbc2d531fa9bcc85bc7ffcfd9b3932f8c63f3ef8c63ffe5de242ded3d1fb66e9e9ffabfef1ae9e26cd7fc91d4e375b8730a6b59efb2883858cae02ed4832b43ce1d34ad7a1a1fa701c12802335815d4aaa79a186622b8ff46f0443bc9f9e384a98db5da61ae533ae505e76c2bd1354662419feb5951e5e59e5bff3f744da6aef0aef032530bed75f953f8e56ff477f19fdb5be11627d93e9af55c0fa0b2732fd750e8cfe1ab58518b573fa6be2a5fa6be908b174ce792bdee82f9ccae9afc4fd527ff532fdf5fc3bf5b5cda9affadf58eac7dc22ff9c1daefe567d455f9bced11f386af3eaeb35a7be9e73ea6bf0cd12fffccd12dfbf72d4fe77505fda34fba7ea6b906aa9535e7dc5c408c5678a79fdb549cffc6bfaebdaabd0ffffd9fbb226b575a7ef0f0455ec5bbd57922c8c872184300c43ee0821ecfbcea77f4bdd2d5b601bcccc9c9c9cff935c4cb02579915bad5e7f7df798ac0e9fcabf007b023267d9891f03ecbeb53581af71ad052d28ed7bc2575808acb606147faaffe06947554009d84037db45885a94a8e6b97a8121bfcde9d4ac6fc41ef0f3d854ec3086abb7c46b54b78436ab46cda9e0b37ca23b04f56235ecc4aa130771786cf623236629a9e6abbb2e498492578f7fe4fd4d499d7f7ef1ccce68cca34c42fdabc564162ac2a923284bb1117bb1c9dfcb1e021e3832c4bea116fb66c0e5ea0693d36c332f182b9ada51c28aa21dbd3be3a0edf1d15e201fdd18ea52cc60a49b6039706038bd563c308775e057a36eb0d24eb0247808737af53c5e7a22dbe3fe5c89dfcc63ed78fc744763b6e618e2a91b6a3b6a5b665bf3d5b384b5301273002c0274b136e00a37b3b8e8dab958c563b40e29ec9289b2d98196a03c0285fe12590464833680398a66e431cd3d86c9af796df29338c11379e4c9c69d5c5c69e4e25a13ee72014598554cc4b6cf779d56c34799571a0be18cd7d2c7ba7455940514896c96daae1d0763dc1b50964b1b64abaca126e38bea6e330bd080df608c00eda5110fcc2e4e7b6faa3eabe6d2537e6555c5071b705a627d1d696ddc78f8e4bf7133ea8db53b33fcc6c0077a8c7030efdcb716f5be7512abf57dabaca6aefae414db4157bdee4c8f10d439f2ab5fcff9e75cb58957ad8d790446be2a33b63218f95233f2a2c558d160e4d3f22e05d5dcb1ccb498f2c2b1725fa15f41b10883b3673e1ecd106ccb36387bff8168068381eb9f9756eb7db0d59acccd870b0b359ddc059ddc3c6ecb5e802d7b71e3e1ee9ad46f3d51faf1273a45b0aebb2a02c675102ea35ac02fb8ad35674097e2e58ca8cbcd13fc2f5ea654dc6942ed4344366a0e06d83ea6f611b58fa91d4cd5b8cd3507d496c09a596870c16dae19cbd1b8b1f4da507d6816738022f5639fb7f47ed131b78b1a13af873be17719e7130dd08289e7558adccfe85032ddcf5b7b89bed9f8aac2d8a162b8adb78ef64ccf38933fb73feead68a89724e6de8ac6aea6acf65e4bf627ade89992d576bb8a6120db55c8c82798f8b2d347e0bb526d5872502df39d3e3aa8f53fdf577ca29de7fdee6814f8315fd3d26a20d211e26fd430ac4f0ee584df18bbbd3d76c68d657c3d767f7bece2d67d8fb7c7ae7cf755d27596069f6f0dcec90d8f28cc360c61b61b22cbb62304708599355b2166cd768859f3028f651524037afe6e443b7372501e0a6b61be4dcb24873854f4dc950eb5b5e9d6098874710043afd257d3f906776200a1af3a42157ebc61534dee17bc5f7302b0694b5eb4efc4fc46f67a91d56f7b24ce18e4a596015e6ab995e405f4b2f782fe9c38944cce7278bba01e4d66ef9f2cbcd6e1c945018c612e547d8d5526bfc7755162c42dab7b3fb1daf2773ae13079a62abc581335409a065c3744b6cda0548dc68c7b52b51bbeb0e8838b92cfc8560a94af34bda3a5a536ece9cca5d153bcce41c96ecd16f872e30445c3e9e0b2bd28b6b5a2a261f63ce917d306b15a56674671b54d4aaf2cbcf3d664ea915bf7d6ed3fead68dc1d3e56413e89118bff3ae1a3469eedeb516e1aedaef33ffc8bbb6cc776d467dd7c6fbdfb58e8e72b974efda60b53d3f8c1fc18281df3f6de3b7457572455c421c4d1a6586058fefd4e6cf05b0d6138f6f2c26ce7c98ae188347e90a41d38dc1b420a67c92d6a5ffa7786acef364229a598ccd4cb1636978063f1a568721e3efd11b4e9c89af49a9ad30f2dbb6ec0bb1eb7921767d2f45c00da0bbad444c4204f1c066cb8dd3f39f5c049d1c85f474558be0470e512d02f59e68fac67bc62423040536028302d320e48ba7392a0d55523a9e49e97048e97822a5a34a4ac733291d0e291d4fa4745449e97826a5c31951fb90da49f17826c5c38961b8f1532287eda47c3c93f2e18ce8f94ad44e0ac88b56404ea0809c1f524086d54f5440066a1330f21a12f26e10db4232b630f31ad65e5e431ec4026301cf3f3f026623bc159c3722601656605cece63ae3471abf293236cb997895c6ef3bb9deac957a56dff1976753ac82c17e07895cd57dc3d8991a8c3582cfdbc3729adc259db08c886e08c0a1e968eb8408d4611911ed088eb6962950f72ee5e9fb343a8f8c4e7897461bf15399b19321c2ee6d4a525b598cad02fc102d4ad73175dbb24e528b71c66241aa6dd74fa2a94bd556de4d523368364a925a3a38496dc4af62b9891cfb5e8e9ac1cc0f7753d45a5e8a5adb485153bb0be5a8210dddcb51ab19396a4d2347ad65e4a8754372d49a468e5adbc851535bad4b6733c1a42f50d966e29712a89c09ea4c719bf57ec4ebec570394a81a24cd3268b4d457fbaa942b9bd5275c1d4c015fb35e8483121e24d5647c4d0938d8a8cffd756b29326c34d1085c63af1094d801dfdd1b5cfb0dad35f8d455ca7ca8b9b9bb75e3dc55438d8992659cbcea137458674f676b5a8e3bac6fb18734c5e567c6476eca8c6d8c95b7be1fe28c6b32203df437c5471ae2ddeabebfcf84ac5d188ebd59487ce47d875f48ec442f04b3d6b491f40c96de7ad04662b2f4aec1d21b57b1132fefb67b0e1f019c05dcf5a92e6c9cb876dc1bfafa1abea6939893071f7cd9ba2616a5e4291eb8e677cf022e515717b781b2c6a268692d89aaf14204eb5418c380f5f7210acc1de676656dd7cf2896e628b0d8f6206ee07a5453176a52a3e45e5c38ba7263acb171a08fabfe1ccb57a7ec84c866dfefd6c95b8ce58dd539fe538cc0c1e9dc51d66f3638e90984382c54a838f5eb931fd3676564761f8cf303c1e4cf665468834508e874718489487bd36c4d8b7895c424a4add9460b79436d6b6a5bedd039bf249c9d05b52fa97d41ed5b0c387236194a70a2f6d90e939172bbcafb57f82346c6bf2bfc632bbce05fe17e5c94bf2bfcef0affbbc2ffaef0f7aff0c72caa7f57f8ffa9157ee1288445db560ba0eb4252c261d5c5aff4cef5dd7ef0a7c78435f060615eb153dded5ebfbc6c87d9d5cdf6dde8f558ad89281c5a86bc4c01fd108964d0f4d9cc1f9277d4c8f643685e8d5bd9de75aa3b2f97ef41f3aaa2112200cd2b2cd6bfe5e9abbd47d4d55e708d9551588d95309fbe99ced70b89f5ef84f8f44d1364fb2a4b3662acffc35892de807bf090fbc84025370c2abb6d85ca3d4124cfaa324e1b581d4f9ebb8c9aa74673c9f9e2d99d4f18bc3be0fbb1e3514f7537562c4c1e385ce60d1bd98e32889fc0f8bc8529aeafb696aeaccdec35adc2510da705908053d87f3474281410faf487990afa7687886130193a54fcb46cb43f1dcdf61567f525cf91bb90d2638202c73f2f337e5c8b7f7ef9a4cc6be03a4fc2c5c6824afdc1643b58acdb5152c3aa4eafa0e49c212f3d7f3015c8b79bcef615ac95a5b877695ff15bb506c151ec0fa4ee93936e007891107e8dbe49711d25f8c59bf8791de5438b30bb1d76b43a4775b983f50d6bb135cf58816f3174a0d2f91c23cc537c069cb0917b32c242b24a2870f63cde6005abb354c49bb4ec93e21167ab5a02b971634115ec94389b75903174048bd13dc76b2c69652c7a005cadb92a104f1ab19c38d68e2dbb5ca29e7f723f2e417153593399b38a3ca29ff252f680c2fcf79c3aad90046993a3b64312a4cd28a95e18ee40db0405a931f1724fb6387e1af060337e283376f0fb746e5996d31663699345e47eaf65f931f83433936416bc06170f55430b116a0761ce4273a7ee46b02c37422ccbad0878161d93ae76b7f12ce638b3331786ac6ac0903d8da0f0e79e7bf0310036d585585698fd2f731234ab14878738ff41c72087d9193e6bdc26ec7d64d3f67f91b03fb4c1fc25ecbf84fd9f25ecfe4349d47f09fb8f20ec269b5af5ec86ffaf52ed5f39e37f916affb2e3cf2d2cf197b0ff12f67f9db0ff048ead8b8efd25669c9ef1ffb46cf157d5fb5fa4da4f66c111e23ef365c6f20665e73e16f739108c0d4c7c80ed3f90156000bd640dd23e08cf63d7733d7635c392ff5dddfb04df6c8a96fcda6645983c3663f61000316486a7caeff52ce8bcb8b5f62c90cfce5e8af9ebcda0d451f0b27b3766a71993da0ef1f13543565d58b99e7a8845ba1912935a0f5b75ed8773f11f8949550bf780f12c234e411347c3cfb62e7f2c33f6f69f2613d30a65c5ce9e997c59dc2ddf1e4f97194b1bcb30a597a1a2c0bd9a0b667ff110bcabea8c444fdec0f5f9d94cfcc843df0e0e912345fdf2e70ac310fa5bf01dd2e9a73157e76d56ff95bb48f2333304c5458660ac7c9121982c7f3443706731b63359c9f15f861a3918bc256ff096457050b997b5dfd5b0c77ea401b35c862c587ea401355f8b10a8818bc14150033dc62621500317634b961f6ac0187b0d357035d60f359054324c08d4c0c5e0d41da8811037da202c2ea113c2b3fe59ac8113f0ac07d3f7227bd1fe389ef5d5c7b3fc42f11fc1b3bac0767e20cf9a20cf9aba3c6b863c6b4e3ceb803ceba879160dd63c6ba479d6d8e55913cdb3a6ff1acfba2be91f1e03befbcbb3fef2acbf3ceb2fcffacbb3fef2acff833cebe3b90e983d40b9e1606d503afa16ee7299c610949040a32171bb0b291151d2186a46f203fd1163e11b6ae432b400b9da37542cb971b285b4c63a6ad24bfe4771819b80db8e7dd70306db0598ca2869150eccb3a847caaa083825a796fa3692b1367d953b8919a9fbc99503eeb381cdb1ce9c6ab94acd98536ddc018f8fd4a667e20eec3d6c0c2c816b5ac12815c36d33eb5e0499c1ea4a55fd7aadaa622116811dfaf0d3d138315f6fa362763d54cc9e6744f28ac3e81e88fb111dec187f1228e4200bfbcecb11d31c9a074c83782941da056b52fac50ba55f3477d4bec6348a26a560bc500a467343ed5b6aa7348c174ac340404ae4334d4ac178a1148ce6428fcdd0584cc178a1148c26a560fcf8480ac6a766e0c7ca8cc50c2a2cdd876ef5e5076d24639b10a2fc570ad1268d7d7e202ef6790f8349ed28e92565dd2c787039978108417b9c84b82e064662bf59d536f929e56bbb1f285f1b5615a16fec94bd904c89f68732fbb78f5a517f734911f5a8fa766ff13fa3a4c8413276f0174eef5183bf703a7a48c27093b0cd2c2952d6cbd0b7352c7f473d68f2981c78b8cb04c4eeee4541cbc27b929dba4cb2782f38d96912e20a19852ce3dd7b5d901d6315b72394660a8bceff4da5995aba8f4548f2d7954d6a4ad11397b94e6b1e3139ea6ea993e0ab279fdfe9c8a9b1d2a30686130aeb7abd9d0dfb42ae9cd44952c8a04ce3004ddbc51f91b22c6430b6ae6d70f1d36172090fd22c251f4620c55c2125322f5f039047eb5a748505bdc1fa051ef6be5901a18d993e6df822014551fded6a3c3d0626d5501754136afe87a1ebc0f26940a7b0ebd022570bfa9fbf0ef0c136683d61d7812e1df0af7fc6f338a09a580c5a6d2885b1e10826db184d38262ac1a5c713aebf33ab8df0a01d2b003be80d079087d78aa146d949208c2728724f7b391a3850d8658c8563e8ca4071ac06b7ae67c47d68cf78da662c6d1bf62b5d127b2719db199b51c6db8c24632b7333da963f0f8533c2de337b58043476abf47541bf200970616c1d9b1009d0940cef97c5ea04e6cafed72128df23318e23d74189a0e284422084079b64256359937a0befd5683e35e02f248c2a0c642c4c17393c22c4744284985e480dd65e04a35d2724a0a31712d0715da0ed77808c4520ac5d99b19d41585b4d5868a531aafbded09d2dc636a68d7cffcfdac83f39887a159209dc0b840bb81fc0d70a26bc30648d0b25b81b8258da09412c6d8704f0b542e0ed2e104bfbf72a00e88af7ceb5ac5002e4fe955122aa8f2fec303b23a07067b8f658f355c68790c0a0cb55e17221f5f44347d5993db7ee95a9da47b640dd0f72fdbb88feef2ea2c1dd3a1a7a15c9a73b0be3e612095d72ef5b234d56b0c6fcb4f8a430efbf2be0ef0af88fad8048bbc4f451a8a82cda5c36da0396338c2ee7721e8d2e274e727bc16b953939b81fed3ab2191b195aecb0f2ce288cd104d4e91dcf981117f2cc4f68c25af0d44528c6161a6c56ffb5e6c1cbf76031763097eff99f2d95f5a9cbd7c510bf85273ee27700c5a3d4b79f7d56d440d8faed862820a62fa467aedf906aa0c2a806aae839b0e2e200c0c2a1082f627343919992bcb7ae1251759801bfa7c4fca0f802f8142db45e512c80e1f5af231e0d7c50a84f8ef4456efceeda51e4f84a61557532f03ef8a7c1da7bbb18581cf2b56d863e50dc00002bb2bef1943dd62e94d5a27901bb2c13711321ddffa7ce5a194b3df9377af22b7c751fdc7a736e1d6f82f31b70851f00e73717d3247831996b2c7d179dbfeea1f3770c74fe8189cedf35d0f95b063a7fd740e7574bd885e787ad54e3f3570d7cfe8681cf5f35f0f91b063e7fd3c0e7ef5ee0f3731333c82bae6bd4c1185dec466a49786950849fa4b7a8312d25a0f832ed6d5273b66abccac6f2146d29f5a3ae248c8ec36f4058a31072c37a66e80efcc163a369c059775a7d70316934c0abc5b47517d3e566a317133c410bb3842e163b2cad3e6bef7fcf5afa675361a3d8684db75ffe111badba4870409b59a4b0656c4daa5360b6533724c7d0dc9bea213986e6ded43723dad4623adfa954fd8ed5f419d8a0118c6bd745598eefa8297cab14d87f2bd1a7a564c0e0005412e3a166a6cc0504a01a63afe34fafc6fae34f8db1d7f1a75763fdf1a7c6d8c0f8533d3613107fbae2903219187f7a71e3fd9df853c0b404ca13b08924e1e65ba43f679a2727b356996a93bc5062ff2bc863a077cdf9f118208bf61f1445c36a28fd7b01ace37f05ac9b5691e2ba99000c6eb52f110b6a337134d1b475f0ead21ff6a923d471d4d687dcdd0a44ee565b9d17b7ba7e7c54e36a94ded1c5d63fecde8b75eebd5887c9d47b60c203a251db14ec94726d50e8f0aa198e5ce2b65896dde3b6c3701bd4ea37dba0140969760bb2c04d69c164b779a3a2730d8a42bdfa3dbc3a22cfa8cc0842f6cec00a6ffb20c46f28b5d5c050788a5e7da2e8d52a45af3e53f4aa0f3c9ca2579f297ad50720bed120e0d4fe4f83889fa07a9b4fce08b361f9cc5254b15811ff03ae8fa05fda64e54085d19bb28acde4eba18c42709133f12b6de3e7524f0f2ba876ecc66d28b95c6715904f5e0e5d751786928bba0444acfd387621ba1c83d15066c22e6e47f15d513a7564d05174d5fd2e4e211a40f57aec0fb58f5e776c30eb4d3ddedbb1fb48389cd458e9dee5bf2a5abc386e5f1d379864f1162bd9339e6dbc3388f35bfc1f0fe2942fc2b8dd3f1fc4f9743788f34661c19364ec7411c41922c3b6fca6419d44d5578c8bcd4ca67a742b0dae807b1a4cf548910857b60b505bc87801213337ad1779c37aa144d600eb45cbe3999d8b7ab0af7e4e3abb6bba680417166c1b968bb661b96887d4156c19868b56485dc19661b7681b768bb661b76819768b3693df2206538ed026e0063c16fce19475b56c8a9f143d5967d5335fd59048561e7bebf9d85bea367b6b44656f4d3f7bbb3c652362899fbdfdf48df5b3b756187b2b05b0b7da15fbba6677fe63a978a2fdabf07cdb5634ac44b41545d16e9392b1a4216f9dc3e52d1d93b4138ced84c908ac28117501e1ddef8b491a19baebee12ed3424a2aeeb0d985d56c20e8ea8332a4f748343b10d54f9d8234e4033f5b01b12895d3314b796a1b8d50cc54dd1e1f09b229c37758fbe6b3c116a45ca27370b4d2ef9e0d91bef456cb3d638e2f8c9b3dfeea3c64f43c6b7bcf16db8bfe3dddf0b9e62ad79e8fd696190f1073c146afab0c39abbd979f287ab35d947bef846a596e4ad7a25e8c5ba08e62f89c782f9a52ef272299d5c1c63982de11ff5d5531ba9006e2bd1925cf2788b2dcb337eb2fedcec94df2dd844c94e294ac68a06fb2a94ef5695f219e76e65874f04639320c9a6e7976ccec1fcacebf1b3c15de530791df0ebb7c5b53ce6d4baa86df1e63f3bbbcb9b9ac1bca917c29b5a21bce9d12c91768851a9756554fa8f09360feb6d1f116c5a51059bc6e7ea6df7049b2b4e8885a63dc1e686d9bef2a01d300dfd02925430550878e42bec1098d1a03614b1453340921b492a55d6504afb17d5dd66561bb6231823603d35821de769cf69210a8a8583826a4ff9952940dbc9883bf4cdc417baf1f0c97fe366d41b37d58d9bb76e0c1caba7785484fbd6a2de578bacfabe555653577d728aeda0ab5e77a64708ea1cf9d5afe7fc73aedac4abd6c67c93bf1bce23141faca19eb8b0195bd88b2f9e53a8124b5690e90c9420632792142d546372ab037f621663b18b44fbd0dd0ae5723323e05f7625f51f70841ad08efaa7e76f5113b8bf599909f205ae4fee824e6e2e4e3edffc4543169cd973beb8f1702165a37c570a7ca2f4e34f74e2d785a76e2448a00d989008c0b881fb7793d2745e284da749693a2f94a6d3a4349d174ad369529ace0ba5e934294de785d274b08212eee94d4ad179a1141d1427705f6f527ace0ba5e7601beeed4d4acdf9f191d49c92f360545f5167520e144f942523a8ef58c6fd64284336147fd6e3a08470206318235efd9b8ae6c20d1cc83a730d154505f2d4722959f1cb0cc8d910a6bd3e2c093dc8d6911c00ecaa47382e9d28429849e31603ee4a82a908d7bf1c718c747dadd89e235f5f8fd8ff11d76f62b089c844bebe1e718e74fd1a590d8f91af4f2328d90be4c337a0ca127a2d471d455baf711794a6adc564d68535312b82d0ddc90c1d8f4f01408d3d94a7cddd7d0cf72e1f0e4c8f108feb464ca83605dd8af6be81851c55750ade7b7adede33e03760be29b3bff93bb1901d2640e4f88e80c833b242d498fc09a7d9e559fb1c048b3c0849a3d31b511dd954758afb519ae6d1518f7bf87663dc347c5cf2dbad5dc68004a9fedf4e089d464e08bd9f6f610a8e599bb1ac2938a622098ee199a3b8c9194b73ec658ec6386331d34abb76972636194b736e7ddc4a7b3096662c3872bb7be9ae91de4fcbf5dc7c71653bf926afcf16d5d99b6eef10336c682c773d921dd6b375540d5b4723245eae15820ede06eb1af0ab85b885448272fc85f9727f6dbeb4a1aa7cddb523a0da7ecfbd0a9a5487d9bfe62e225432280ad673a8ef3d87ba96796efbc6ebb409a2b9177ceea2ceb454e95a736bda09ef4477a457d93c32b2c64782fec2175c5e309637dd2225ebdf4ad536cb02ccc415c8cd2745183c6280a2b136e04faa51a067eff96d6b54a4c2039ef5098ebf79d6273aae936de49716e18c8d7613829d35313c3dab8740778c8db21f869d15664f3551771a213c262c48af15c19eda61f2655ebebd88b68f86e2a52768a35f9f2ac8a55cb60342a89288e4331d53286f35854357b1873166ee98f15cbbd7a28f4ad38caa8f90c2a5be71ee4a2077060861521f03648960603862adc1d3e525084f46ee35908a9adbe5b5c16df0646a0b4d6d86346e374b44ba5d8b5029a7162808820d9fb416edf2c9a6f700dee517952897c71a058a2e65ce7da19eff851c78210111ae4f7a30650889d2f5cdafa6b2427897fad11bf0e8ea7134088d764194f8d55bfabbba0ad515241096a821b7a37e420a0013c3ebd9bff3842ddf6db5003d14574fe8efeaaadcd7a0455a859fb9b57040f817a53b4f17f6f174c8f1587db91b1d9cbdb54a8bbb6a5f99b18509ff797fab9b95199b95cd7076fb33b7ba474c8e111c6651504946ef45481cf1cfd38740b325aeff5fd0858e91fd3511242e54723c324cfceb35c63e39377564a4d3cd8cbcb9110f4e4e05d5e686d999cc44902984c2728df42bd7681c9ed5ca5a9842fc0bb54f352f255039aa458e2f57a39c2e7098d420683665ed9e346f89800bda09c1056d86c83626184f27422efbb5af382801215abdfff3275675fc4bc77fe9f8cfa7e3080cf920183b082366d822423e09c64ec223e482a5091989d520e484b80f0afe8991811d8f90270621efccc0c0ae19181832e0a0283fb7ad5c1b907de1642350425e81aadede81085b55ca692d18113638ce475d7c615d9b789c65053edafe0bd0fe4e2d38f116efa9cbb799fd6b24032f34312f946979635913d508bcae79a599f404a37a60c6d7adbc0b43510b4aabb8ccc57002cd40693f1ba879e258cd58d055633dd78cf55c35d6732dc4ae570fb1ebd58cf55c33d673dd58cfd58b38c761f9c4376fff9e592a26188b9966a9e1bfb6b98499a5f21f304bb5fd66a97654b354db354b6d0cb3d4f953cc52cd2b3394ff38dc2c950e491637cd528787003d09a7c1e3867a8d4cc20c53d010649982448da06daf1d61dbbb953ffa79a6a9080b4930f1bc4a917f656533b6f2fc2b6aafab2c5166896f1475b87e991a93c7fbae17f5295747edbc013f8c79f169595f1c71b50ca74f42c6baae34257f6edffed88ac9bed2add280f7a47980701dda2feed7d43085391dfec2d2dc14e7c41c5db5727b09c92d864a5024a62cbf6be90ee0949edccdda51efc28a9757ccf1cb2b12008dcc604041c3e8faf5b2a716742d281ce33ce927b890235b11fc498d9084ec5a48ec6c2d0461fdda9fe48299146f620399b1f7eaaf74ae4ea073e6971792df20b8a0aa571e4707eaebe32aae52b19594bf2e99fcee5d6c79d79b537814b32b3922e39722a91518456c355595a5f1bbeafd74bc9fc2fbf9e2fd6c7b3fbf783f9f023b50869afa325fbd9f0defe7c6e85110815d7e783f8d0e5defe717ed44b3d9767c3732fe1d60c3498bb1a4a98766fe083d3404526516c17963820d4fc403902aa1854f3a218a613b02c2422b42c984468862d88a00f6659b605fad41092bff0c4b1535a76d3c2e17f8901ad42ccc049eb672429d8635659655b3a7e2de4acd3cba52ffcf17556950da2d6c5d05a9bec3932f1f574ccbd090a4f88791c5d8c85c9c6337fd7601e5a9cf6638954ebfc526636deeddb0df0584fd2e75d8ef676289ddaf423f02d4b60bc5396a722528ce0d2d3ea3e27c91f9bb08c12d330d542be37cf191ecdf8691fd3b3281cb3a21c065ad0fa4ff364260cbda46fa6fc7852d3b8109df53c4eb4cbc265ffed0fc19fbcc4795db79ae533b6a9eebdf7c38bdeb5fd7f2cbe95d3f2d194b1b89fe89f00c835b62c08d0c8303ec4d06abc97d5c11d95ca6f70689011d4f0ae804a6c31978bdf7959056b0087001aa0641a74180bd61324058f1b36648c5011354adf35f4988b3bd84b881f83c7b4e6842dc356a890fc8e44399fe0f25c435ef44d65d1fd72967c988b40b42f1bffab690f07c5f719a7ea653164dfd86bdf15ff70104738f9090f0dda51dc37302f44c2740d8887c183c40c363390d8fb9b43c96d3b8060ebfc171ea1ec7a91b1ca7f6a0f1bafe01e375cde03766927edd74468d82401c3fcbc81f50c4eabac90faf74c34980500090d42286dc74de24aac1ce9b712564d967e7156fddd753145e8513443ec4b574de0d48f4bfa700c997cc99144ca14ef7515ef7ff696bde0919c5109f8c9de1cf8033a7bab90ba60e66aa1764225049fee7802c8e886c628a315e003c7adccf6670fc1f51857272b30a658bb1d645e477ea3d55285bda9517e07334036277dc2738f90262a35875833247c2fd0ebd10677b3f04a4364c9eea8438dbdbef2b4319419efa370a510eee549bcc44ce56f96b450d14802665c626863e35b6efe6c4fda1d13c215654b3eeec2442ddd9c36fb3a286958ffe342beae13f6b45fd340cdc2eed784a86bac29ced03e6ac779230e4c5d83c4918ed8aa75df5ec2bf6843c12474444898525a0deaf1883d7caf2239416956335031601434d60eb6a4eb19a28a603cc2199b3360326fe0539aa64f22dee16b86daae317dd229ecc16178edc219d514d37f9b924e0d3199d1d7c57f5866a7637f8a89d6daca22f26ceea62a27d00f02babaefafd9c2a16696d84d1cf197235da8650757507b7cd416a917b145e99a62a8151e75040556212441defe2ce9543fb07ddfc2b9e5543aaac1a01d2a2e1ab04b5d67891d74015a1c5f85bf199646c66ca5ff3b23658fbd8e0dcc58bf4b1c15498f87565b0ee7906eb51307e64dfb358a70d8bf524183fb2cfc40be294a9497f7df2cefacb60cc2ec21de5cd70471fca43f22af031cb99b3e74571c958cf6548d04df32c40e763ea9d335803db690ed7a8961cbf69ea663605aaacbf6809434e912dafbee0bad0c0e2abf25b4642021ddce2c4d3708bf53b6fa1b829de020c2d6d758b98fc39ad07487e46bae535bcb059bff31a5ad89400af6185cdb4a86b486133fee41a4ef8d265de31131fbdd0cb706375ee334119f392b1bc816a967351cda0c14035b3dd4c7cc1d8c60cf3da7bd9870bc1d8c234daa65ca963062b37d03ff4cf683bf988dace080aecbc3fb2b2ad6d6c776aedcffce5687d5acefdf8aa66b0cc330b93799a21a1209d08a5389a1162abea61756ac3ed8cba864a83c5ab2c65f523561524bd619db1b023f8426c1dd0fd15be15e67fc701521ef275f06cda3b9bf5ceaebcb31befec2eb0efcc3bbbe0ac09480acd030a66137ea662e38182d1dc4dcd02d964138399aea58a155738a9e98af5b3bcbfb19a2c56ae4fca29c2c80c48224bc1be8b45f1eb5781324679939a27829c51f659c4cc6b2344667d070f53db635c7bd6a8394799980f80d784a5539ab140456c4c2f6f4d2708160e5d3c65e42a2afac82ecd7960adcbd70a9b470702f461ea459d1e7433f74ff6920358dbfb6fe38ca5af20c1fbd1bd264ac2ba08225c5674305fcc62f2e7f64794b8c112554ec2ac3cf356b67bab7499b174d9bc55c1d6b7ea450c1b448386c1f8d79fc5f8cdd2321ba3e07d568445e1df18116c80370152ba811678e3ecea9122e32ef75e4a1086927c7b43bb9a5e66a04e38934ce7604e30c462c6d9486ec5fc251e941188051cc5536a8f53719d117848a19072a6f6ebacc013b51fa9fd3a2b7047ed7b6abfce0a3c51cd872db5076405f6a278a61a513c53a9478d51be4da546fee795ed4940166a9e23c1d8084cc9daf98c03aecf17c4fbfae7396379ee9d3f52ffebf3e7775e1fbde7def939f5bf385f63d52350727389b2ce046b73d49731974a6d2867a3334364bdf4eb72e3a99a119aea58b34baf51fd7472d6f242158d3ed4ce8005be095f66c7e7b1eb15e46dbf29eeed822564c5b411e33657c30ef85e728dbb637e40f55733be1d092d1eeaca645808bf5aadc00ff9bbc9d13b9bb19d91cd170178e796df01e32d4c3861d7018a4d47d337fa11866c784477067b2d1aa2f82a385d7a17922ebd32a4e38b1276772d8241d2718993b2b93529b760709501f81cd90c66adc8b7620846e1ea6a8b75613243c4159f110fcd110f5b50fb14bd504e92786086da67d43ea7f634b5bb3c98dac7d47ebae6c17a7c9ac667af78f016ebd29cb795776756af2363d910abdce0b6d305caa02289eae2097c28072d735e75d5361329aec3d5bc3a8c23cec49cebd03538ef42ff003620d7a16c1786c231d7516d5e89461d38b7e4225ad3d5c3f99ab475a5c0d37b7766d5c912b181188adb5ba0ba0902ba26b0ad1fa33ec0061224281a963ef89266a72a25eb2869b45c4a59f864cd30b46144a5705628f9b7e06f1b0d92f384e1409ec163612cbd33b695a266af2664201d0d2bbefb2bb627e82d904f66f1a02dc95666be7e9555e7f23cbb1b7f8a000e3eb746979c171e5b2bc950fb9e0f8836e706a4faa2c4521fb7efd5b57dcf00850833ef45286edbbf28142d7dc9ca7f0c106dcf04a26d7d8dd7d8cb0c66e61768d84c4914828156acff16e16f5a9f9103eed9221b6a01bd0b52168c9c84295bdc23856760618825d7e0b20bac48ee356894d9fcf5080d378becd768d0b8b3d9eb114100b4e9eb4e4148b449df950220694f46a7369347fe11648c656451f7ae35b0112f3a8c151dc31aa883c5317dcc5baccbf2134591ab5d60907617ae3a9ef371ba023bea044f4cf924edf25175e2c8e7275adb28dd186b7beaae6d1448032abc74fd11a099e05a4f8fc4961f8ca51c0b5eca0723dedbb0cff782e108ee97a9ee05d77a9a85457b778c68ef8e11eddd36a2bddb46b47723a44875c788f6ee8414a96e9945aadbc146ea1b64f999f800d73ea2edfd04235f09b1f3a7bac68371833a8136e9d93da08b4b2b433f3816661080b27adff1e3e3f8d9c7378962046cf07630e0e5240ce8a219127b530bf1c4d742c0e81a21b1cc66c66f37628262987f75cd7778d4db7b6a2a69bed7198db83ac0073ba46182b9c3d4c2d1d7f2ccb110d4381566af2a387137347efb608badf47e3862284819dde48b1be16b1fefda514abfa5baf57565c04278bdd58364ec606abc6723d24e30963645c1b17c3461e0b30be8743f3563a01b2163c04495ed1b8bac1712e0d60b4193698754d0090b7033506507d67b63f2eb064ec2897b81f5628c0a3a3609a508128282ed9511955f957e65fffa84a8faebe3fed57117f16b97f281f2a0378bc85cba4d40291885a14d4a37be7d82e999852b6cbf7ae917dcd8adc802008f5d3060fa426843866804fa61f4217a1f2889c84374f1f444f4213a75e681bb180fe6066f431fe73542c995d83363b1678f6b956aa10ef250aef57978bd9fe43859f01b6ccc0766ff5bb188fa8192504841c4fb0e9760c1e47f004e3ec8bdfef11c89c6758e438d65ca0f3ae8ffc7732321cdb5b98277ec0f87177e812dc42b374eb01fcd2920b2ef4a9218319cc57430f840dbeac51762d56d037b83a65803c01fbab1ebbc07c76ccd439c753c77896e4a70df28509b8d0b1aa39a646b28f847e9a612f78d6a2154ae01cdeb8ed24d09ffa81b4f78e3bd6edc6bc09943d4be69844c669faa9e88b97f36f5444ffd77bdf10d6e8c7adf1beacf33f4dfebc69703466d3c86314a37cd1fbc979d339306ca186ea7f4c0a19218ed6394326587326387a01ae083326383b2517c2c7ccffc874b65f6bd2d727257d2f7a189dd2c95d90d94f4db9e2dc80c040bdab51aea6a0176a1640eb4becaf4809e96c981dc416809b50fe89eaa8ca97d44ed09b47bda31742f5586d43ea0f621ba97ec411adbb52727b6c7f6128d2fd2f812b517a97d98a3f1f47c056acfc3fff25b6951f9accc977f2e9338f689c870a199c42d7f26716408b9eb2ce40fd60cbfd671ae4b69fa338d29caf15e69cde5d327da0cde8118fe1f288e51fc407dfa80e218bd3f0185f0ba3846e70114c24d4866d024240ee0f088d83fe061b692d6ff44758cfb38d17f17d1df45f477117d18a43a58a8bdb58ad06b6afa36cb7f707ea60f6733a078c563b90a46b46bd3a09ffe834ea16648aa422b0406b611a10a5aeb43e8e7c3c8decdff13380c9180e83094dc5b3f67ad14ce2cc66601eba7e577e21eddd8803420b61acb67e8c6fd6093b77c64e9e3b10166984f3238366062c4066c8c2880010fcedecbdf8d0e5023b51a084aaa8e0f9878f101e60ac238001d1fd08e8006d734e2039a467c40dd880fa81bf1012d233ea0cde4b73f1922ea1ee6dbb8fc896974a110a8458bb162942cd636e5f91bd4be7d6fc8c22779098cda47e97bbececb621d8b10fa37a3639241f47f3759e296bfb31be2ef6c8580a43623f83bbb214105cd9014ce88a55dfff0fde34fc41b0c0d02da49c67686232e73237ce0465450523096348d8a43377c20cb21e3dddc6ca22db18f59194fff01b3d9e913eb7cfe2366b34f06e0ab3f68360300bec6ddb22b9de0e487ce23e121f56076d90991b6db11c050c2b86533845b86296b518a2e241ecdd9ca222cc986c7f31663792b97ae186141f934a5ee907e56f05ae5b84c31585eda81de9ed8841b7908842dccfa4627ef4f9389a363e195568a692eee6288c59365c6927e29182d18fb1a88595fe26ec5e3aa3a236167690ca0d640150b17fcc07c3eb6e39931fc9023b5a0e4999f70a92e78ca6c78da4283cd1abf86990a08ca60b7f861d15b03a2d9941ba1bcd9b2e29d426f72b33293473e4cc3e01e0cfe394a572812658cbe038cf4c5649a299c92739ed74625f84ca651e95f16701eab46660af8a6201382ce1118fd1b8600db3516ec228a7cd30d916f9a21fa713b04b0ac7b239eeb1e08bc30e18b36980503bfd3c6ef01a7b417c831a47aaeb2243f1debfd8f63075f7decc06f9afdcb0efeb283bfece053d9c147b4f57053eee729e7ef33e53e5287f8b22ec1ce20c299a18b5fe8e8e29dba783f0475a61b62ca0d132e1fa5cdcf53c5ff7453eeef56c5a54f15a75d4b7abbd646edb30668d45a83466183b77e5265bd7e4e16632773fda4bcf5834005671350cac50e8126133bc4fa2d81fbc115314d579a717af65eacff4e08326d2b04b3e9519cca4e04d5ec7391693fd9d050f50c0dbb0f181a1a510d0dd7c6827fd1d050f3191222181aea11e273869151fb89e1a531c97bc6e3339bb1998d18c1944753a1af3fe354db3067b44e113b93f26eebeb5305a7b9aeabb72102a6fa53378f6b80e507c71adb543dab9c22dac72a067275707afc16d3e317aff140d8a946d2ccab70730608df694698ebe30441ab42ea440be0772e13312e33259afabec6250999ca77493d601c7c492c57d455373d47bde4f553ba038aede0016d75870e60a3441b403280531211c23f15959f50df1af0fdd8f148bcba0325448e20afe06d0f470e83af3c4088d5113f0346415fe9253057aaf100c8176cc48fbe463105eed51c5b863ef433f86a722882aff4820d36ebfc9a662b77a3636e682e3ec7e4f8dff5eb3755ef809ce588f0032b75cdeb93b3a093a3a0931338e9218e9a8003efaadd9e0d423e08c448385d819da62354796f04a7b11a52ee67678a84eedd460ccc7576885939232033e4716fd467d671b976f3a72284c994191b95cd3019fbdf35041c1e8131ba00f80831040c02087d87f82c26b9b3229e5b7ed5e7302be300f81a27cee4b7c8f4db30e8b71d6241e8845810a2b8005a2178e8b7ea2e07c1094444298aaca5dd0f87fc5fa3d099816398fc8f52681854f31f42a20df0d88f2651d3e0003b0eb975382a9dc31acee63b2af70e7340e5aa38c31f718d7c07300275af0272dd04c5ab3271b6063f707883c9171a08a7be57004c148d6c2d17b9b6e9feaab9bfea81bf6a2bbefd1eb7995de211804b11acd40830d6d0755891dc848d092d05e8c38199ff06c08e6099ea2e60c7854c35085e5086a8b5bb6bfa6d079b7ecd4216d75874a6fff61a87ce0cb8bdc6a083782e5a21d7f873e62ab9c69e836bd24ad1b873f3d31db69d88cab6ebd117cdf384ef307df6e70c801c3b4feae377d49f6f29c0de155e9e3c695b76866b74ca2a1bf3f26828e3361bf13c1f0396f1906704424c3a54b9422d842d623a0e3815880799720c825c4d03076e905d6c38249823f0a687153df07eee2eced68a1cde69c8f7dc035816439e462452507a0d28cc5adc85c2c4b74628ccdabce475bf00c7748b82841c6bfe52332fe70d9ef035e8c8ce3815ec1cf3feb49103f91b4cd758755899ddf78e5f2020df8025c65a392e2c718d49174c4430f95aa04b20fb312e5192ee25b0cdbcc4b66ca223af8ec11d21866ff925fc06948a35b14c78646453015056811cec419f9a3de73af4b5c66cd7850747533ef25c78878aeaebbaf0f265b5c715724112c85d7e390a2965588ce82d9306f7b43cf3e3c222f3a35b03c559e20eb1ff0222c74e4d7d6f69421c520b0a235289579229263ee40067def08495208d327f1711e9d18e31ce5a7bbe32c02427bffdadd2511f3672c73cbcd56de9ae7dbf38c1f53e961e22a6ea721b8ca96a42423db497356eec6535ff5e96d8545cd4b950e08b3ad9c02f4ae38dc5631018817164d7c7357fe1d6193741d87c900ffb77423e54c3cb62d6a294c5ac0696c5bc8bd05d7dd00abd3d12da22ecce0db78c63dd2df25873ff34dd86967bd8c05f924d30150b981376f72e5177ffd4f09c5d5d0cde5d1772a23eb8789b7fc14d60068743befc025d1770f833d7fa870a3cb66e9171834a4ec9f57bea3ad69854af2edf6e07351a89f0271e0898ff50b9934604cf999942d40c898908ab911d16021ea62e3ee039d3651487226291466fc0edba8b55b68d8cdf1cc178377b626cf6e42972d3aa063b028bb70176e4ca4a088364dac2bd1cb799606c663a76cfd6a345981f82321a189690dd7b2d2186e276b8abb885542034363cb41edf8364eb85a4b8f50cfaec19f4d90da1cfee5586e46f888b7022d015562c3140a0b5810003f23dbacab9263714ad5366dd5cafb8b7606c60d2d5f616fe4734935b70b5ef6096bb3158eee62ef29f81f1d70d44fedbbcb7e8533f840b7642a8ac161219560ff141d40d2a6b8654ee6e45abf964080c4d28a8a3cb66ab2de0b26ef625d0589380c658511131818e252e77ad48c9d533f8ddd20119728e64dbd2df2b655927eb3d0249507abd0cb227a7641477b8f6844b2633fc8ebf3b7ab9a54bbfb796e11a8bbebae588cf28a609084fe964c72bcfb03397464ff13aff72d3152df7828a3ac53bcc3e5ecb978327cf3cd3d1656c74619dc23b6f4df420b7eeaddb7fd4ad1b83a7cbc9a6e8473712e0d1bbeae8c9b97bd74684bb6a60a2e547be70c7fcc291dfb5f1fe77ad6bcee1deb5c96a7b7e183f229d934585aab66f2cc636a6c579ef599c1fb3d704482ec15504c2423a23841b87589c23baf127215a7e60f3ad938b477a1aaefea0c883db9efedded470e2c81f09e31a777c705fc0fa0483e2e164646777a4ff1e8c776affae5eed5a64538b9d8be5aaaeb3707f88a05c1446f707971858fdbd2b68e377014081bca041917875e6db5dcc713aa25a56626a49b84ea59f6f47afbd1552091c4ba4ca4c4d593429057c893ead8b1f9cd27d51c3e75fb49a99bdc8b0b1eccda1ab0ce3e5e87a8b94fafa76cffc8d3d7104a90b0d6c39e5eef14fbdb4f4fdde4d2f7f4642cb0d7014fef9f808e1936d7501dbf84108bfff6752672f82ef8a8212fd30a7a4a7a7e7b7bef29db54f968198da4fd1fb2a57133439ff211826906114c0b050b3b15e965baef7b19cd890bb75f462b4cc7db2f4329b3721df6656a6b6b95be5bb52d1415281cf8c1e7fabe2588f8ea1b653e1e5d72d7b713229904c6179af840f05bbe5d57a9784781a3cd23bbfb0da7c5eaa2c0d1889b158e6ed7d0f07c39fe07c9079d2c3efe74d90895359a5e89a4965722698095e05e8e5852bc79d8e17109ab3436a9c4f90b95386feea87d9dc44a1054e6fc85ca9c3737d4bea5762a75fe42a5ce9b2b6a5f523b953b7fa172e7cd851e9fa1f158f2fc854a9e3767f0bffc91dbbdbf52dd38b2cb2082450a9168bd759b28df0d02f355212b448a508950f73cb3aee8b4d2d02ae569d83f97f866b5cd0a4d2a7187c9234fcd79046b48ddb38620e8af7a4999e0fba77f1e5bace799c3cc4236fd407bd87d64ba4670bc4c18b05858365a58a6643b24882cac10c635d4c1fbadaec747b3d1a255636cd1260d6c2f13508d71f02f5663bcbad1df6a8c7f5635c62b71e5262adb7fab1ae3e3d910810684d5ef2ec688a517074631c6e42717636cfe778b3136fecd628cf347316cfeb2efbfec1bd977c2f2b1ef16095147f199ecdba76d6effcfb0ef40adf2b7b36f64d031fe977dff77d97794589a0a63b38a114be3dcd530113ec13404bd172ffaf3631e568692970d56f2662108e42680b4092c5d7c24ee61642290afc2d2859a21e9425120a47b2108e4bd104dafef953c9ca9859d7879342401c2134d7cf7c6d531141a6c33fbd7e4e95dc0071d3fce7d2b2a9e41dfc5b94f82c48038f77bd8085ff06af5b864f2890635d8d35bdc66f5372f62b5652ec06a840598fb9701db1716630b736f5cff5e949f109012b5577cddec2afef4a4835a89f37dc5e72eee5cee93d23b6b79116f127f8e1e41e2ed87e4275d2cc37684acbdce3f81c41b1e80e460ac811a3ea36dc466d5b10759f53402b96fcf9927b3a93fb0aab0c0d61770150838fd4575038705d6325cf259e336719f3fb324f6a6ccd8c620eef57de2468f8441dc894815b57e3bde5a8809b11f5c9da0180c973a11efaca6db0db121f6426c88dd9044d44e4871825e48e466efc1da1609f167e356fd7925086ea02d6283a13ed9eea22933563433bf135ee637162e30c39b5dc4e80d676c73a92e7d78478820813d526ffaf488f4d50a0324ec872c1125f3b96b0410dbf522e98718dabb21c055bd90f0e6bec9f7bb51024feb4c2ef9a4132962fff7635d391ed6d5c1274e3e5cc75a0661445d8355b7ef1c377412927c97f4d97a10dfdb660c93e67e606561923aed0b51b5fc8d0166108d7798bde5f720afd69f0970122a56ce24633323d97d1f8e43ffcead386a71cbf7c6b2e783b94ae71e57e9fa74bd68bebb4e982cd98d10ccde8c0025d9898000616ebc231e521608ed07595a9f23f11b6a450660d145ae5176bf56e487eae35f272b76de5b2bb21059dffb75b52eb5a57c7c1f4a395c22be8539710394f204e4713483837f078ed7800787000f42405d6377d5ba0869258f82bab64244e0305057732576c2929776e180c31f50ebaaa65a4791832850826e17780c5e103b7357d7db3feac74f8ee819d4e7598131d4563ca7b2347e57bd9f8ef753783f5fbc9f6defe717efe7536007b2c4d7987882fc7bfa6d9cce19a71bdecf8dd1a52002bbfc08bc5ed7fbf90545f83ab3d9767c57843f49c64e06f4ecf17edcce2de8d93faf0a9f694485dfd2f86d19ca2d65312cee2abaedf02a7ca5aa7f8f0d0b906945a805d20c4918bb4e9b25b3e9ea03253c3f82e9da88ba8f5e179ef960cde57b98aed7ed0d8de9ea99542741200036b37fb90c8fb506250cc21b96c062d8c6e372810fa94111ca4ce0692b27d46960472e464cbcc1eca9b897c37ffc4c774928861416d1f416f63a3c90766431363257fad458e982b1a2b99f2fe58dfdfc9302698da57f3096fec228636bc04df862fe465cdd14531edfde91a70fee835e70f12193cf98553dcdf24307e37cfe117341278234d10c01b9ee84b86a1af781322fa489fa4550dede3af1cddbe70008be43d27ce71e7480456f5066ee913da81318d1bdbaa7f05d960f18f84bf65d7bdfb377054dba0896360b2d256c6a7dfd08e6567347ea86846c86995bbb61219badbbb52de4db3dc6f87079bf18caae7de260090f433bc975d630e094f9c258b6b083374eb0e24b14cd52529332e2dfd4c00ddf0e1db24ba9c61de2eeb4d4d92a635509aa54c5158e1b28ea1cb05b6d1fd2ad8e5e91cd1ac1c3b66b4b0bdfe2d709c7aa476aa94deec5818fa1f61725cea8fd16be42177eb7119719a458b5fbd03cce8025be309c177767c281f04195282ecfd6342dbda1b3b4bc3b3891527de41ae8f16596a6a9d7c9a209fe4ba84fd74de1bce146de38bc06e18617d730255dc56d740e6cf50220e7f73635d88a6ff9702eef69cb931a63939a1149f4459bc22b8c252b8629dc09b56261d091c1d472060c36b49930d865cdd4b0e9681abf7e330c76cfe35d358fa3f9ce8631b4791956d689a79e217791d6303855ea09f55fe32d5e675f59ecbb7ad0193c638627b0c3c8d22661b1e798cc5cddfec4c9b09986c0af33d1c0613beb7ad8f0d38701d0d3e6a79670b3b2b2ac2b014fc28bee78065e74fe3ff7a22359c9bc79624408c6b7598fe33a87d754916e617b5fe7eedec4f76e7d2ebe7729504e97feed48061923c8bcd0f02c0dbe9f6e39ed8b9f6e25e98b9f6e50e0c5cfe0eb3a9a0df82f76ebc6d73f9bcc16b9fba6054432f25862eebe69e1563dd93fcfb4300989cf4a1b227ffb1107613bd8417821d47dc48018868d6f9a191a37eada643e889557357f19a879baae804dd2c51b8b13a89feb6b6c3089e9e4ce123fdbc2b54eda8675d253d697432c76b200e1a97cf4947575760922cb8163abb50fd2d99bcc49ddd5d9e78170618e9f1714adf724f027e694720b287d100a0091e0243f28d9ff0c289835385f24a9b1ad489f66ae0339f1de50c82dee81fcea8e739184589f7eb62096fb6a54fff78cd2d04ee38746697fdad03faa4ee51811f22485dee2d1043ae6390a77539e1bc35cd70fb4726cc676e258be3a779419e983f0f6cb83ef8827ba95b6fc3b985f589586a4615de9de01416c533aa55238658ea7ca8f86706a54a91a46387ba85235fc90f654cc5f7d9cb817880ed6f3d870ff9128590384aeeeb1614a117ea214e12aa5083f538ab04329c24f94225ca514e1674a11762845f8895284ab9422fc4c29c20ea5083f518a709552849f2945d8a114e1274a11ae2ef4f80c8dc714e1274a11ae528af0cb4752840b9115effbfe44c498f6e55af4a8c1581176147f22b6996e7dd7fe884d473323e3f68a4053466471e03ea290a1faf4024d3cbd472c3ca697a16e88022d43146884541faf1ba240cf10056a21be4403e517440a2d0a1868f54ab0bd134e5763a5c8e1746f5794d3a620b794b81b21820d06dae16fa79ccf297ddbbf4739a6d1f02ee98cfecf90ce3dd372c3d886454add563e5182173628d211096c485220b7615a16090b9a743e970fc52c276ee47321e55ca56f3574fa96c1732ed2b792dccbdf1a092f7feb20987ca55d7865bdd3cf67d7bc3404ca5d60f873c4292341ba990d700ac3c8b2408798b190e0da756733f99585b8fb1c66a7c47d979e927153e062e9a8df5fc1e9d8059d0091aa9c358feb5858a9e6095f86b48a86770cba45ffeab8e66b2707e09992f78c4cb89961a49f709f35fe9a83e7838cf48a6ad559a0bd3613dfe8e32926b1a758813e13150d65db71a16c6df5bba2334e9502a7334cd5799d56aacee332b4d512aee03244052e51f6ce0f8cf3d327effc8ceedb62f637d7429fff6770d01b51c0ce9b8160e711634a3f8c02ad940459a647939a652b5ac9d8a77fb9d08a06fedc024ec937d00e85bc598765a9ebb02cdc3a2cf377d76179a8428b5196e5e0fd9c70d6a4b22cf33fb42c4b52ac9fe0fba1d573c5b709704fa5080ea6cd44c52324b8dc01d49f31cf5181cc0510d7885f78fb9db5755a472acfa27eb5e2a73263a70b17a822e85e7c643336b2595cd754396b2f3eee5275033b07f6afb180d7c9f323d0adadbe0461aa394538854648bc7ad2622c795977d36c60e6f9a6a24784ec711fc79e96f1f11dc6be946a183cd2c089541792eb67ec0a0cc866cc9ec0fbd6edb03e0e93c3f25c71b2a6842b3d37204a77c78fb062a91ce95ea8ad40c43782b183d83c194d290161d74a629970b8aa5c7d8bd7d9b731ff4177edb01d1f8a4f83268d200e9ac55d0e97896801f260fe58a127eda94d3277acc0e9ac7bbaa34ea7e874d23ddd56a73394979e362f92e0679dae7e0f2df45e6e3678e9cefada0bced8821766e8d44c83d074b6225c6202a56ad5253008dbb84483d95399fc764bc40da92b3af9485d94e63f50e3cb5717c50eac8be20b54f9e7eaa25ca72c04d445197d963c109460f460ad9447cba0949c8f974169dc2f83d2b85306c51b580f1cfdb70ccaa365508c6c45c39637323c2d1bfece5cac66843a28ad903a289d0865331b21c155cd1b9e96ffb13a28ef8832de598ced8250b1fe4857e0ee3aca38c0156812e8ec6e94b169005c98215ecd3fc419782fa136ba19e7fb15fd5ce3f4dc702523c040dd20124d3f318bb198493fc3729494b07f2517251afdec8cf3f7a3d42706fdacfeb7e92702035ad98cad8c68e865e52eacb02f3ceb56cce9634a44285e69f3cee6dab810088f1fa8da02b7a83239d6fe35c22fb58722f5eba375a34cac8d81a2f2a411419b5e56e26e786a4085e05318048769a033f3b24e86816ee63fff78be563bc450de0e89b07e14f6342c5feb7a857c6a0ced3c726ae07d874cde662c6faca6dc7b56138804e66a2a4701e9ce72c6b2e66a1a5ad1d133c407b9b419f0b30986dd3599f4eebd8800b33044009347f743c4d0283830617800ad2b57cd7f3863303af26f84ed233443c15f903d8afcba118c6d4cfaceb9f49d06b3ab19ccfbf194f4084017031ea85f996030fd77e6aeb483a12e903d06415d7423d4f17b14513a3815f6c4e1c5bda4f4d66716f28b90f97200fba5e1d9b6b479573076128679d772015440f731a10e441429e4d3ea43763cba9a9865fbb8b1cdb7cd6d3e64c04e11626e4b82cfe203998b75d74d3901eafb41a6a9baf658dadaa319d013760ccfa169477168de326a3ce8d0ac5e3934ab570ecbfbc78896450ecd8b35ddf49674d35bbb1d6f45fbceba0bba1e640b6cf96d81c777fa069d70bb9f13c56de8041a07d37e3e54f3f850cde04355637fad1bfb6bdd60438d905088464828443da4d06323a4d063e3420792c1894f913342fff29af7f09a87d1460279cd0537998b2b6e733f2bfa1e5b7a006ae42ffbf9cb7ea2b19f16cb943f2f85f72f73f9cb5c7e277331aae2b702cb41fbcefe652eff36731970f18405ed9cfcd24632a2da0262c93750e4b94b9d158582b5a6e79ed8e289b67b627eef44738fb159980a5d2896d1980a6edf33e67aac31f061942412536df03eade916ba9f456606935c3d64d0303bc73205d5d9441d3b733ed8c0cbd4d67327de62acb5d983bda391cca81913475e359b27b85246730847c871e7626c16d07b6a9b5c0557d5e595272be43f23f87662cbe545731e018d77905724b73c31c7bc715c12b1b913b7e33dd11af3e1c26b78fa0aa13d2bb8533dd601bb311a6f12b0cc5b708eb512f81ff0a4664c1f38eab38e057dd71d64caebafe8a8af582a548c8fe2b099d8f39feedd5fe1ee0bbeb2bd94fa2ae6dc3421e706cb792b4ee3bcc02dd29448bf0664d4f6365da19ce11acbf14e7cc559963fa721d53cc31db5cba4794f3d74817f8f2739cbf33c5787295e00f497241f58ea3546ea35121660afc18d720798dd22300af65a8292a96cc319bdb97a85c210190b8319ce0f15a5c965793f12c6c42f32969a2621ca63f57eb693872b573a8904505df35889b798eda84badb87a4c3df63bccce841faa646bb375b820c3b521c8022724ccd20953dcba8a2014c9662122ea0c1184f589222df1e2f66e4c3ddffb2fdda3cae41b7a1b60bd6e394efae150095c6a1df7c4f26aed0dca7bbe36c8ac60c1bbac78165643fd005ca99e2e02c1e012edac205eab7dc6022663801e709250d763ccc1bc3be22f7bd091be1fa06f2783af5c5b2b41444c39ae2bd6592ef17c41ed80720b53e70ce69063d88505dd079ed745105f8011dd5b9ad66c7cede5080bc5ef63b8d09236ee8116ed0fea9abb02a22e5cf52936bc58997a6c867d126020d5898c79acb800611eeb9af73b0f180825be532f5ce4bf52f0a60bc4a2988198d09e4281895a422dbb2786e96835645f2ba1271856f2f1cd68cbc3f7a91f5bf12ab3bfad2098b4b149003787fd35858f061fa55da2b95df5f152c9049edfd3dcc20bc835ce43eca41a4519c667f14362a0ca160fd2f05f0b67f48c97aa179ef403a9ff8630b14b0b539d583b8943e0855a291ab2ee9b047454c28b4c591883990336f4238be5370e9c5ec926202b518e37992c0f37156fb6958481d1d56ade6d7a832aac8d5662013deb18228aafdd920439abba414e6613193c6cbdbf80077741c6ece045aac64be46a06b92f93aab348e0e2cd63fd9aea9816ef6aaef654398697f832be78e60e93c030ade25adfcf61e22dc2fd607e21f074f06a5cb0ceaa6a0195d9f015394b9d3139b090ed0c2defdc41cdb778390ae4fc09892b65b281b9c1ad1118428a0fe171fa9af1db7b3e8233bded02451ba1d8de9ae3a0119fd1d29dcf9d789fd9059ec550ea1ddf61c31e0a552cf85c1ce0440ff68901c72ab8ea8ae705ec84b8c036e2840c688262c079846cc5465e890557bae714cc60eb8cb02543d8e4ab274cfb54bbc1d69ae529dc3197a85cb4b699bd155bdbe0f583a5da64475cccd5263ae1c6c6277e5db24c9b5866564c9790aadc01a6de982de11d3af3a57a783b2717f08375814a0702b723d54adb91a3d32eeb0b1aba8411b57d79033f2a030e11dc3d74a22ca9d7846ec07328f7566347a974ace67aaa1a367c2f36530782b7471ca3e418bd6a4fedbc53f5d433fe6b04dde518dec39b0a756f273e13622968dfa31d62a6bee1afa3d119a580112721a4042b6c8bac681683afd75be71499d8537554662578e219ec6cafeaa97e75d4bcf40f9ca9a99d42eaf13735d666a20507b06f2f38899ecd710cbfe5b80c5e4481728da74451594fefb82491e4d77c8cc2ce08a96be6d17ce6deae68d3be39c30f825fbc29e35d36e347cc56ee5bd8a1ecf21ab6e020d02de5f96282b3406b032e527c8c7345b1aea6109dc5532e15c6f89e9796d7e2df8a04b039ec57585afc056664c40f18a9db3ce2ffb59204ea49e25e90e3282914f810b76b14dedcfbf54c690f6f96a59ba5ccb47d20e39627f955e33dd1b8585c4424024591ea0657f31293b96181afb3b6abf3f688321c66db48b5e3152ceda61ad864e26b09e897fd28028db334df8e80f1d613c82006471e6fa857fb35c4efbdc9da81425043bfeb862ff978e5cded7722ebd31149649155e45883922f15123207ee25c4b7d45cb5579e360b8c0d9d0c703aa6f87f6d998575f4343da899936002799d1c607f9bf023963fc38b8804570dde9adde1c3d7e678adaaba719dc982a7e4aa9eea6f0a21075a13b80b6b9ed54254f3b0e409a1e51f0819d18c6dcad34be76226c410a7a6efced59eef97cec5f48df8de1075bf92a84b2c60015205c94fce9c2610d454518134b57296e83187ffd310c8e962628907cd3c3676e9e6cd64395e8be7d53795b93206a21f0114b09f3912d2824ee3ca88151242dc61f2656d2373de2bd5bcf12dde565234e9efcc292e519dcc65052a6a38ad59e410ddccd20173d5290b7201c6e880f5846813bfafbaa0189707b4848647e0f88d125db408a3ed04ee66a3a31254c457ef21c6873232aadcc5430c704613363c423a078fd0f028171fa161d1a7501faf5c3821b242fe04bd9b09ba640c46db242516962eebeb2a35ed8d6573b844c627d06c1a6055999d40ecc8c01781ccf09712f67b8a0b259801eb4249eab445194b2da3366335946cdb3b8b1886a2f8d5ab7ac8721a4634324a78719ee1c87ed1023c7362788b3c9f176c9cb08292cc87988be50cc41184c4a71c4fa3b458745f466e05800465790a9aca49e8e330f99cc1becee82840ea181f09674d30267760b761cdfd52bd6a91efcb85b2c1af198a39f1a622c0ad180acb68c47b036d5a190c4868e4d3545a120c76052c9edfd8142a50037bc031f35f22769973000589b513688bab0f76dcb36c912dd7a595f5163a3b1e0138436e520d4ac1f05aa8392c7079a86faeba0d50aaf6ae38b381792647d0af775e7257c6838bf63de16a4374931ac17163821ca73e05d6e55ea39ec2a4aa0eae536894f3af9b29b46601fd84bd25c6f09a0b0be4a2256774dba65b1773bbc2cb2aa9a547db7c535b32eade1e74a22bae5670c5135fe38c3ab31c47bb740923dcd57987b1c68a8a86eff794ae370010d5895ab672da202da4a9a5093946a6d81a82a96bc7634af776c602d8416facce962dcd429d359f403f2d533b4c9670e94f697c2155b97a05b42146a14e670fd01ccdd50eba0c0864ac350053711f6260865dc50c171ccfa15400913b0e7ed5f84a3039441b06b0f534dfc3dbd63243e432401ee921311b77f8a109e410cf5b8c0d50fb9927057d03f51951f65809f820083b58e4749daf19f8df99d651f338597157c63ff1718baa8b34f58aabe5b1f04701f845adf802dfb08447316c4be0d1a0a544faa13c21b8d0806fd178056baea7f32e5b991840042fc191d14cc7a4cb889d5c0e797b094858bead5ef142a93d6602c7c05c25b7dc588aa372d0de71c9b6a3ec1c199923409c2cfa6eae778e335cb98fda54131f913526fad31df011175994591305b47b7e8307d815ddf2434c2cb358d27581a4b784e4ae115f65e08ab5ec8ca3af06260b64b2d2138acc201af7a659ecb82e639acf09994bbb086cb05302dfe09e90e85a3b086cedecbfc51bac0ddafc37678ffac879814439d8a82f23c63ce07c43711af510f69a27e161cac85e536a3fb09f9148d22fe0d401fa1c73dc8d6ad91788b3aae23744d2faa564038983b23654b8f882440d0ba8bf46898ede6dcdcf3b14a7664978b4ee3c69c51beaede6f081ab9b3c9edf42bd4f31e5b119bdf60b4a2e8a5eed3dcf41c29028673171a8a18ed5abcdd52bc9a11ed698ae30fd6ea6feb35f6707819f770a9f792e8a802f1583c4d3b10d4c6046aa3aee123df52789bcf017acc32cc8d888f0b233b8c037e40213c9d84282be84ca4b739844e827b4a7ed62c826d3af86123a4e0a1de7cfe42ac671a35307a92cda2b8933b5149d7648a9a2ed042618b4d01e58f2f2b4514c93a80d28290d3c827332c0d1897e119929bd283e6c6182dcbb087850f5c4cfb27a8c567e064bab8f8bbd28ce3c8d16be5e2e5f81a758653cd836f28ea1ddaa3985a5235f46797885e6388f4b6900128cf8393be163900576f225de60ce98a79e94f8dfc18cb4fab90c1e72b23564ce6ac909913ea379eff433de63e2c71995ab83156f3139e56b48c8b65af91cf64a9d957421be276954210702def7222eadc618d8537df4aaaefd6b4fb9701b5cebf56d5120fce3e2483cb68446b7628be2e686037891cee41937f0e7784ba945233cdd4b60f718e072ad311bb7b1c67baef09e31848bed2d37f89ed99a7aeb352f80385e40c0cc89c8a0bfa63af2f615273f2389fd521051a28d9a6c049b6ca329bebab061b5e4bc0cf209ff1e2aa19092b497eaa8b7da92b308cdc87465672ff15aea22d8252fe7b5c1108a829ff894bc8946c97188a4d6802e4a146c63923f06b61a09973a641a1605f8951ba89ac8796d51c16f80c2fe04767ada36bf8e977a33542b6932414893e9c422e1406d3d729440c69f9fa14eb32de0dc14e7b06b36872d348c80bc456069a745f9a2efe40422516fb3241bdc7e235dcca794b5874b4c243c5501b4c6afd329a5d8c3deb0daa350b0de43eb02455e9b1eb9ad1e593291292b4aad916023be2a0a457d55e9cbc58457127dc2c7daa8a088004d966de495d5a1baa818f229b294c684f6c9e9512d2af96337009ed93b249018e159c03d03cb7387d6dc29fc2f13c8d5b284dea767243617101ca13d8bcb578f3863e8f3507353b062df5dc687169f76ea2bee185560add45e04bb7d7ba22d98aa29b7a6d46a70ee1c2b6a7566cae7294efd19f5eb5cd15816ab292e654064e883e7646d8deb406e30895f9e81b4d0195c8f9515dbaf8d7931a56622539e89b860d9724aa02c5a2f4ccb00ef9da6655b189751f4154c1cf9a805171be03476f63435c9020a318807b65e8299a586e647af5766826b4ff17de0a8892d2675d04c87759c8a580b1652b12843fb7599580a06700e92d2e3cb179d37c0ea4a3c8736c57afeeaa6d89ee18715d6da38ed6440fb5cec48e9482e2eafaff661f5ff790679fa5b91c4e53e9b96031e5a14782df0dd37231b9b4be80f7062d3cb595c8c6cdc221579cdbe5fb415403d6e2cf6be5753cb7e318727cb95b388de36cac8a05b67f87e0f90188dc3c209ea90e3f3189808db8b4cd97f7f91e083ac2006b8b8ba07f6588b1d0a98f57c3a689633bc3844cd7876fd8cd03e16e91c7e854dc24f1290fd5a442b626f3e29bb711519bea6a9009f487ae1ba0391f134b49d4e6d87c4c05b4ccef9f68cbbe90ce30d30dee250208c95f91aacea9d62c1423b5aea698a06c5c3857e5765319e020db1c467aece57e46465c4e289cde50ed9ce1e3d79338ef0321bb4730df894da91fd54e7ea7ded04bf7052c4564edc8ee7b9188b314fa0c132c4d880f6aeda37f4d217f19d5afb65d9c015c980210d45b0d7347cf219770de722c1c7c0fe3a1bf4326c1571883147ef50164fe600db69c963e7326e12f33d6ec18b7d59093a29d4eb77b059ecd17a7e00f6298e56614437454f63352311e910862088f69a8f408b28f22c766e8ec760936b8cc8bc5d38976163827e7259de36e21a7174c08fe873c4bc6adc115747f423a4f0ffba123e48c3aacf739e0906fcbf05725d1219ae521ca82e3da3ddf3cdd7dc66ac7daea1d5064293c0074ba6e9033e0e3d9522f9257809adfc4ff886302f3faab008e1f7db17306bb278956d394459c881d8c32e58cef1ecc44173570ecd5d8e2648d98c684f7014357ddd97e323c9face614a6e08251ee56630af1857865b546d8e18b76457cf93e12a85fecfa4839b750a95c2fa0085c9aa9235ab4c7cdfc164754ed8fbec20352de0f3b63278f6084671f16b811fe200b4f95dcb1f352d419cc57c4d2bada368e3802a3162c7a27056a7c62e608f2a4ab758920cd91d4573943ed9876c4b8016b65032b2dc4e102b591009341b5531a2ecd91509be6989c075e4b567f8366a0a94b89b24fd18aeaf4e3699bd949bbd4d6b0d1e042217b758f761a1cfed38137ba11948478306ab0e20a8a9afd3c2afd3ff719a91e139894b412dc9331f24f1ec768cc1eaa77119cb04a18f5eada26f6d32be9c6ca3b62b3c6d718e82e264a59db5550d93345d955185a352ea384feb7266e882a288e7b9121d6acf795c65ed6abcc97ef5d08b34c5bbcdadcfb95b47dfadebde0d64fba6fa5262891ed0365a00e1d497781d2cb9d6aff8c96255a7a67936ab2de7a1449f11b7887efe2d88b87759f40696882916f765a5d6fd22430d9d8d81494fbb5eba4374075407873288497c7ac06daa84f27fb598006df447292102171a99695b5b88d1a86e9ee09e3becdd2da093aa9a5f5878f9351552095d4a1d37b71f0ebbeec78035d6c2444ab977d2559384c7680500f38e754ee123c152d9e0ced95ebce03240974f1b277681785cb8bc9bdb252ea4f44563068f6ac53d06c0cc51165ba05eb69882fba5b374cfaa1758e1d9deda3daba4c119069934e7297dfd16138966326b7934912859d704a804b81219bf4102d1cac1164b71bd65abc431aaccfe8a214c6bafeaf84fa0a4c55ca018b1351ea9965202d45312f5c25f9318e8fd2f6e5f469207122b5807d7c8bef6637a4cadcd0d45e20b3c54320bbbfe6b6ea35ed67e26b373154297e3452eb6e257bcc36cf26c66d0e108f1d1af089654f740f1b1beda8602e54a79b4a817f3fce2187df0d5784c88a71c2e9ccd9e0882f6a8da9493055b3dac3a9819e9c6a893c17648f622c9c4cf8b9f46072a522dd59a13f124073b9854d2c7f5912b0b026db7e16325de74750cf934e898cf94c288504cee39dbdee81fdee851e6e2aaeecf7dc6b8c52143acd566cde7053266905dc7e481904c7c3764d844b21cf8aad5e0a75e74f0823673e6286eae88f967f6e8d4407f6c0a8d019b14ba50737b248c133022a73cc741dda4f496530d04bbd7a1d547e684dbee582daa21afa2fae8bdc2c49880efb7dec0669d1f55f38abb5419f677c5b33a05c278cadbb8014e31a69b7cbee2c873e0aed8f06d1fc911e3f70b1c7d8b073e3ee180d109b7d704d7d6546a989c1022712a9614c55442b779bd78a07b9c50989ff03d7d3c116fb18d2890d0a7de740db5c5597382a6f79596f8ddff6c264a20f3c638b9b92c9466e382c93d22c73ed1262fdcc23235bc58021fa09f07a95c2e85342287761c200213e88472ef6ce39753f7744a28a61dd1925c9fbc61db2a0797cbf0140894a25c40768a3ea86ab18aa2ef2f9ce1e4546d2a35d8fd28f681f4a3ecd9933ac04d4ce6f6349d4f9ccbe83249a4297fdff3591ed086beb5bd540b1b1353b44f52b1a02aca846028ff852601bc546f7a808eadfc01e6108b04b40a78b63d40370a5552e80d8f783a76b8389dc0de68dd713046196dfe5d349b9ef8694ac49183a132a36654ca194e58ff30a3e60c4e71558db7951e8c761d459c556498a70105de9de5d779961cc21bac748188212b8782a72879201eb3c5947fcda39a4730958970f964895f3b8bbe9cea19f5c81354eb7a4dd4828496180036b2113f93c8713a9415ed6ff934570e926786f89ead13be41f50cf8c2e2d70eb5f24e09d5fa6a3143ba62b683f7a5eb270f24e924f0ced1c47eed8317999b623f01f6320828537ba427b7745c388c3a9353278d8f8375e4db99023c34c3906bf49625f15c2755502fe2c063590c2298cbdd119988520725c1ca6794770e28a50d38142b4c9214a45f14f8d3de0e5534142358ae3d89e26869094232f19ccde858589b29a55e32f19afa19a27ccc211a97a435f565207a43496dd90e06a29f38b30b366e42f314e90c2360a033dc22facb5439de85407cd8a4ce6f5ad64ef37abc2172fc6db4b50dc29c2fee116688e0fc300d6ef074ab40fdf30794a9d767fbb6186b524587c963f9cf20831b62e5f6820806288060b4573b078f26963c900e9a4a2c9ce003f6f7e627fe196f88af6f27fccc1d94b5c3bf1d058e7d0e53c190e6049d8e1d9410227ea6b07f7b8ddacaea092f53424f40745633f91ed7c157a03d1d89d59c83c968874a53a3f486977903952a7ba6089735de3509ac5cfc48ccd1b7b782b4a6eaba078a561a3d238ded127b6f96d87b8dba4f7b8cbbdcc8c62719ac51bc1ad3238e20944f4cf916a7f79a1b32cf3cf77d0651b417dc70f91837241059edb7f25862c7cd0cf594ba061523223cef3a93e32fa301e920aae1655b14187db9013e208e628fe4d6de65c88f71b51e26dc530eddf5d063f2a8968370768a3c2c5a8c96bb142d2575c9231f1575e4b0521300a4bdc05d5de7795c44d375c3e390633e58eb28c92a932f302f439cb2f680a6ee08b61d31e7b4d431fee0a500c1662c8db651869e2efcac62689d87867a581c585ad0556f19b890a712a3acfa30752cee4ad768f1db8b52d958e8db34a785ae540145f09e3d308b9f0fb484b7d2bcec86cb88d7424e6f125526bf18b69514da56925f7152d562380ec90327d41a9f2e7126b333904130952db72e5fea93397e689a2e3dc43a0fd88076190ae8546ac1167dd2b5c51674f5d69aa824de0117187ae8e0866f783bd0659f35fa17abedb108563dbd71bcbe8575d99c74c144c95ecc043d9e7a0794249b8921a8fd6d358b8ebefcf1246174fe24dd2981a918cb63128c65b565910c165aef3df3d3527138f98c947bd64c152cd6c44f5b29d8364b56f372db6c33f1454d40c38b182eeb8008f15a1a5a9ee6a71ed4d5f1961b7ca5b8c34ed6cb02d94d0bb2b51b68cbc3f88fba7ba6126fc41b622ddf84c7df0b77f9fb4346ad643d90b90175753030a13a7ac5be68d8ff7cebee15f7aa3339b783acbb3da83506d1052bfaa02efb581aec239be6b4c8aa4c7e2717af436034b88c325f23aea2181476a3553422c3e64d616f79b1cf2783acca55c00287d0ef2f2bdc475ae3b447822ff146bc2fc6fc6d923676f6d27bbf7c115769f3485bd5e1889b3586c59ce9ec89ce4ef39f2ba9b908ba5a58b353e5d1eb8ded21c7f7b55b1f7fb024494f49400eec886fc07157dc081c40e600caec148367f7586fe1d26c495c2eb628bb5cae0d1237247dd80509422260d6b72e64b531df15a9c63218b637c8c326964b5155d7be3db786c4cea1f24c6cce2fed8b254f1614dfd4843a4c5a17a6f44b7bf9529ce7dc4f64e1d7ab33fb6b0c3f546b9a36791d51586b9e56bc6e2e88d72dd2659f1dcc6613518d37c45ebc114e1cbcf8b28c71450164f9f3717ef48807c950254748138d1c1173f608817f3f96c93bd4d971a1e65acc1e867b96ba373d4bb715be401e00c91de0c145204dfb6861dcd7567f9f3613dfe20d31e56f230afbc60da0eb718131ddb37aedf03969bab97c46538cb97cc622ee94f13eb35fd3e89aa88f176e04a958737a887a712bf506a5a6bfa676d3d216436263beb657d8c2ecb7465cea675b2e43f958ea261f5b111fbb563a8e214a0131b212d144f158c686f9f2017b850b029fbabf91995c0e7d9590e6184c518d4fa528f5b2601ac090885f97e2d948d1577986ef5d3d6a0aab2b59f9801ca07a460ec07bc801d2a9b25ef633fe8a9ad2765e7683edd0f60f2c7146b530b2e8b9acba34207ee0096047ad6557b346f16b04bfab8ed71315c6fd4e6234a764e2e70ea37b30f6197b0119554b5342ec924cd8f17a7c24c452bccdd4ede3799bf518cc6bcf72f701744176dca835d651c76d0f5a2451961e8166ee1268f27b7459eabc08a79a0e1a7364caca63c83a02152325e54eb07b6d6159b3091a6231249f4fc11cab845298b75ab6889e020a3b8363884b3e734cac84fb9d9faec420777b71881702fb2f5d6d2fa312c71a6a8784b757ff2a15cb2e757ea3fb354f50ab0d0de9ad14560c6faca01c92a05c14b4522410c468fa8a8bc1a5f95dd2f3ac65acf1b8ec11baf7f5da38d36e8039f9ebb279b261431c8bb32c8f7052abc38c22ed9c26ed2cee4beadd9e52737c7070cc653dae297e5a981da1a8f559af84037f3dd03513c6227ac214c5b978abba0fff33bb75c57dd64a2c31c1625782f0ae23a7c0336cccab9ed531a7643a145d72e15448a9af54dbc867b120d772eb886bea802ee37133886631e12490381b58df174ab8cab5f43e1e893a2ebb03a2c95d118dde509a4c7cc9be185fd1954c127cd434e494e186bb51c51e61d6317657ac858ec0153f2181348ee5a52e3a6db593140a7ec78e20613fc7d047de5154005f0c2299061416974963ec244631f13449dc6320992dc7f2a97cb2a38fd9641b5e833d6d89ae2372fc0d9696e75c1c662ddc102413df47faa0cfe4eb8593b4acf549f944528a7aa7e1caf8ee9333194a4a2558f047fcf2b30d8fbb4127039e3e52af3c008e6fad1272faf6865c1a5b48ccc8f12c9eaf6f1764d6db2c20f1fa48d10a7b7d7eb7286321a36181f6d626369ca1e47341f3ba9885a71316de60854a6d0bcfbeaacf95e10bda6f53faeac945195bd0ff93d1e7d3a0e188041fe7e185baa93a3de681ea2a958ac2a4d70d39f5ae4385ba28df6ab51248822899f5d587383f1d63a6616b522285b2a9a888025780b0d891b62d4747ffb5ce451b6348308f08c59d7a225d8130e6095602c68fb9df9a76178fc18e52d28bae290cf16da79407bc4f51a01144ea665301a2beb1f327482a299630f2a2543284c5221dac50d2eccfe7547e7dc29998dab37925aecbbdd7d65bcf0cd3050ab5261216287e40f1b24522af8fc00b209eb79bb20bf25a050ac174dcdaf205ae843121e6c65247a6aa748373c1936ebe1d0aa81f6d72904455aec76df6bce018ee5cc7f96cb0fa5ae805a4becc70e16d892388a2598b019eeb9df5621f70459714045b5bead35017519f5d6728fe14a22e577436332b6ba46b861aa096767472724eb125f5395cdb93c3e48f0162bd10a2991a5c9a97cde114b50a334c175014e73029e3f5ff47ff6cb1b510c62587611bd2a5aa11df3b780683c8763f617fc29ccb09c237396bf476ca25e4a6c8ddcf8b561d645183b435d521834120be8e88f4071d4ba833cb4cf02527dc0d912fa06b512eea813db1d818f4dca29356ce5bf7ae8995f9e59a1ee246cf14529644a89a5baf7e9ee173a2a072eb39d718b323b3c13d8dbb0f304f459e310bced755b3835a16d516b92e56423a8a631f7ae6a9277def44cc363e38059aa83f31cccd94fb0398301003298ea9a2301e8b67e073610401be0ec3611d23f5b1be7a8391e337bc549bb1f6a958a1b89e4409b3af761dbc076c7d58b5654ad75503e8b6a30a13094ccdcca26a27816327477815b491d62925c8718387ba80a983d5ede880c8514de23a45eb029e4fbdff86ce64b6b83ef0f6237c8375cbc8fe62b5023a36242585e55328309f31295266f1746c8530407bbaf2f1152fb27630921d37001b2255c4f2cbff27efbd9adb468276e11f445531a74b1024214ad6cab26ccbf29dd7813967fefaafd0cfd3333d20297bf7ddf79c53f5ddd8223098d0d3d3d3b911e23e929c263570e40798b63a9b52fbffc29cdaeba4312450b64c6e376ceb11489be5a07ff4af557f2de2445f279d68ed485aa0886040c8083f1eb4e0a708800f433c59832790fbeebeb8690793bde586d6b9a67a6c80245b5ee05eeafc6af9188188e9fcea39cc4c23fbd8eb3b225039ec55ee82d98f067b6cb2c7d23618610daa9be3d393ee5fb90d5c954c135b8b60c57d22531a564977c0a474f60844ecdcb9ee533ccfb96fd75a2e832735f627235fe840e6108a52c41466bbde79ac1c3270e1abaa8414c135677e6cf91fc392500c842ccbe7cfe2fa8d5d6e22c35367f3fe1c436562bc4a90cb01e76d3d8efdae2e4a2dffc3e3c20af704c0f9391df51e669ccf18a1c278aa6f20833fdc53d77244ccaf75413137b19fc109d194e93bd963a0f190d01decb0f5b834723822a4cc874f0843c543aeaa02f4e6dc729f3ded2cf0c6c9d76d6e8647437b446705a7c9ce06ec58677c00615e2c9cb3608491f6234302fd302b7eb8c3a657c011254d2295a1d30d3e6a32f4e388b99c30c608e83134a0da3f0653620001deadc4a3159e5c9d6391ce7d69b727d440bad7f517b9c2b4517adf09d7f8bce2155a492e40d37d3a6e997b225d778559140ec4adca7bf97c00aebcd360063b6ef801f9428929db6fb8bca158e90cf3280e8c63969e9ce7283e7c4238158fce66dbf378491246aae5d236100695135c3d393366129cf679d9e00086f70e7e9fb6995b27fd6fd2f2a4735ff194f8119c2f11608b9337479c596737928936c4a7fed0ae939f69c0d977f2371ae39b751e77a88e3ec5e30db6830c18520876d60b06e20f83033d47d4283c3a160810eaf8ad0a872d906aea78b59e1d683f0847d84f3aead81a57ff1660e589fea772db407dfc374092f69519091707876bf47cec65138f0a158c8976a418fbba5f1376aa8ff830817eda5cc97edaf3bd682d93a853423e0e7b259c93c44724fb8d1e268e856a4f90fc6a8d82da725b5cc505416560ce4276eb1ed2124ea25c25226e76f0561682a8ea024cec9d1b57ca592653242974af45084edf6cc6b11bf31ef7bafb6b3db69d693e01b6b2dda627c26d841e584477f3471b1d8985cbefa974728046b2c3968317ff75ecaf07057895ff4b2fb1a3994781dcae75e48c804027730545be2fffe7e30c370c34d9f35686295effc852d60d9e809e1ca9268c35d47d8eb727d241cef9d781a796bbb5fe21223548cabc84412b44fa0974519d3589fd61e4a0431523b774f062b92dccae50f3a01fc65c66cae9d4d9a07204526cc8e1ac3758a8fe4eafbd756cbb79701c9c039f92796d76a8e31af88e7bff8770babfc0173cda85975e10c02eaeecb5d670122cbdd8d2b563ac13e3ac8bad4b40ed2850c74212be235d6008a694482b4b9276d530e2004f66960595ef204facaac41e087933e4379a231de10c70ec8388fa5c1b282f4c3e47620081ddcbb83242b4bf1e7c22b0251be9b92a4039e4f03c3ebb95dad95bc9b0d5722bde367b0887148de039eb08a4bd579271c32af1289b0fee0c63ccef004c4d11f6bcb8f363c73cd70f51928b6b5b39058f7525c201cb356839c222337b46c07367f16a96d8b6d4bb7a478cb2e45ba59cb6a3dfe935fe05a40ab43b695ea4c786452579e16dd27c67f153ef13bd4aa27f35a5e8b9d8e89c5315e5eaf3fcbfcf89b440192561d417bbb5f7ba3770c35ff3bb0d6fa37472779b3be6b5cea24abacfa553fc1607d5cfe1d84e2a4c1347fe983f99fca733e6ef77a1005a06e1dc9730dd1567b794bbb337edd4cb826c9d03a5da39a47b42dae387bf0cc8c223c581f277f847d8dcaefd728d38efe9a4e72f1279b12adfdaed9ebcf0ea76b897dd87ec054cb6c7e18d93631c70d30b4be2c21b86753bf047f3afcb131bb742868102e2a8a54766af748dffeb4d566cba39f5a2e8db9234f250361a9c92d599acb7b1970c818f2d0fcb03c98faa595c6b8779936adb93cc2c7d7cd04c2a3b71f48c0f9004fad0374a4a9538665d90d5984ce5f856bca3f72dbe7e465984e821a65a0c4e079d794b156a69bb59a903ca93320db33584a4c3478830c2003e0dcb54458844cce4f6f2e4e90215701ba85c99abe600f4e089a40ef6318a06ad1c19f2cca1159c5221557affc4bbecc951cce7c3cb3f9ac3b295e52911e6b54b6f1e8b209ebd5554198a22ee75dbf7a8d163ca738703877ac76fb11d2951551c50f5d1a5cad1ab5452b65aced49f87a56cca246e5c3c53e04ad3cfdb19baf60252b51e304f4ada663730086d899d03d99bb8d88be2e64fb00a4fa53134318525f5a7c0cea74611b877e2315f21f5ea538ecf273b3caf33af43ff0065ec0016ddce8071a2c31204c032c564f8b63c0d0fc0bdd988ea23f1d67c1a1f7a37d376144ddbe2a7bc7a57445aeca77199757a647f8a17b47f6eed8f4097ef17e120ae6bfbb63fe3c4d2ad6134765f1dd94602ee96bdf832c2b4b2f54afa295593f75daa70ea3666a1981947d15cd452339915d2123835ce1e529b72e5c3b0f7d29e47ad20debacf50ef9016f16e58dff915cddeeb9bfb287ae2ed90de6969c3ec1d77fce2b516798ca75ceca5260bd61221782eab8ce6b84e896354194df1b004aeb32c4a3541690a72e957cfdca7e725797c806985c0e8c437741b8a06c5a737b44b7bb2d81878bdbca65baadffa9b42c7afc2b5fe61fb94917f4e1cc54fd26b9244cb69f44c57344bf3cfc184aa2a1c3a2e65fcf5f74c4a7cf8a55c0a51a031e71d0c9caaff0dee04d1a59d6505025a1e6ee0bd8144373e2d772de797f05ca6ae4f4851435c31cbf7c45a2324a6f4b0ed4156214fa51a97945d5fb7a268dd3ad0e476dc816814f9bbb4eb2171317f57763d0d8f8d3a79a6e59435b79d60fd14fb6b2d3701f7bc03d6ed6b9013ea3ba18c9f28d76de8dd83d4670909e17200c7b115ad6d03914e9ef6a46bd0edee7a59d2be042e554e2d7fd74c46f4dd7f8ca28f68966bb6ec5e3d83a883417c3a1e7ac672e376bb5ea2da5a02929153f1693f6ea399cc67d8cef0b10af32a15894b22f5aac43cd718719b8743ce51cab6c4e59f03d2d94ab9e3af9949a973a5fb236d68250481f3ebce70df5377fd1459fce499c87b9a3397d8a9119843ce58f1da9ac2ec300ed07cbf14a4102dc2f36e692e7aa65dc6126b879e376dccf6818428ce43bcf94b15e432f24d4c2795bc81f624d7bed6490102b46f61fa682806a598dc242472bae5c2315c9f5dad22c13b9f569766d73ff6d49e9776b3d95fd3afadfbe8ad51e9f083b3b6bd28de7caf22cdfff0e82cd5729aae4f2f57e9b0e5eed204c7c79ee1f1ae77d3af02d30f973a991e7b7e0f4ebf5de3b00a16edaca5dc9f58e0fcc86b5938fe7dcff7b2e78cc655b09be94b736e96c79eb7e7952f7d38ad76dc4bf3e17c430ef1c5bb247c3d40cc9f8fe49ea1d752929eebe6999342e9877972ef382150f8d924ab8dfbbf6ea28e86b84e6a5b4a3b72e7ccf1e5f8975e6c2c3ffc5c43219a64b0bb2069121a48f7df5133481f6cda8a32e7f0d183009e959dd337ba64489e774e015aa8f7387d9e89a6b988dc17a488a5214d6509104e488b864350b7c9d8d89cfa8a0fe9424ec8fa8fd16aa3ae7fc31c9f89d7da42141cac137f589a5435572ef5399bc64646079e27f92cbeff53c8ad4fb7d7a63fc78f9468488e64b83d26339ccc2912212ff9d4ae2bf8331e7cf3069e6476b8a67d6a061a6065534967f4169893aa2241c2a096cebd5d93e0b85762e4bf858494b4884ead235c8592d511cb9ee2969908aa7f1f1e8d189fce1baa993e6ec4f2328be911bd9dab50a3558071c971995c867aa395628d26d7cae0ce46343771f363a37c9b4e20190d01cdd9fbf42cc3fdda5a84145c5e95094b05a4b2e413a52e286093c5017cd84da59582638ead4a56aaada00ec1b02773b8f2f82f6bad28aab92f17f105adc663146f60199e1347d2194e1ad4424397de4c2eb863e520c22433b66d26579d92fa39345d5c696a3cb2866cbabad2d4b8251d456a4cea85d6c596c6d569cc4e37bfef74caa6bbdf379db3e9e1f70058b2e9e94a531071888c6c5abcd2d42c6bcba6e5dfcf75cfa6d52b4d259f1b5cb38e6c5abfd2d4797b15d8b0f9bb862536cc5f6928b82a1e026ca86837babdec15d6e065bd39facb3f3030181b93882a7b3860cd68625ae2bbdeead873bfd343aebfd31915d41c751fc527c953f9bc25b5d9e9b0591f21a7d4bd095c893aa1eeae4097842222873beb2463cce0f43749f64bbb44f16338987b1dfc19e432ffd0096b9d4b2d4fb3ae79fc8d9163f78de0b16b1d9b87747a75931d1d7bd9d90646563dd7f89ade70d9c99ac7a4c17215f192023fb12c893035957fabad0532ee74426f8f1341bb4cd4561f7d223853e83b22aced58c2a303ed543cfbe59bb82be651a2d274ff835b51dc050a896f9704edd2293b737ea34e4024bcbc3ba1953715dfd2c623b21263fef6163a1462f458e8b12eddec3de77b389e89c95ea92237403bbb61eba97145b87112dd6ffe72d8e857b2d8593f46ab3d7e7296e7f796bf381e21279e68f1a4d1ab7084ea61408ea1564e2e6e40736a2cf84df0bcec6909fd51a23ace0a53a756e9a5bb0e545ad045902f51fe04ee1ffc516a4001b25b605ba6f39ec7546836a9b1aa3418292f12481db3729e522c373e3213e7144442bdf5fcbfcef054837ca1969f2f66deb502bc49eb8556d6e00945e905b63089e2c92ff2823dddc86e6631f52350a29165b4e48d0ccd374de21b259c12e1be99024ebb07a361a024e41e8c3e047c9a9c8c89b101f54f1ca34eb8b8598c305adac05d37834def5a7725d329d4a1790d51729db34b82597f9d84cb2eb4fcd093e6ad63f35e14577443b9816a8b531532b1dee8b9731c7d74eaa93ed6aba9efced6d104afd6d0398f0074558ce2f4414aa56f47a19228db271d148d3e559a6fe02080429bc4a7c50ff52714a1027c7b92e7b71b2cae4043df8a625229b971ae3a0a8f4a25211b023a5fe649aea0c449346c55f3dd8bbdb87c521d8f92c61537fffe0c36b46f2dde4bae6e280b97c49cd5e992a023a003a14876a773cb8df69e8ead08b9658fda9e31067c7a089e126b5e060d402cb76c799d7d6e9ff88bc0fcd9f37fc6fe4f23b49d4e9eb23fe3b8bd83c200717cd0c07c819cf4c5c307d013e6e667ff4be62085f2ded84882159ee4eab1a79f068febb74a763d5e097a1047ab7a682f9c7439c28f67fd09a2a2bfd9fb0c3a248da329caf1823fe7c214e78f89534a2e59b06bb810a7e24f783662c466fa54fc46efb1a442f78c3c865273d34acdcd93e1ff786b93131b1d7a06b0860b2c9d0cab56dc9c09a6f0c6994cac7b46ee04fd643a9e477fab6b1038b3e732515cbfca9ffc2529e65f6abfa1b0e04783023aa9f03716889a196907ea461825b593b901eaa7f0b32ac742b440a1e7398377996b435b5632b3e66ff89e8c58b5a3edb7a26321ff60ae36d2524fbbf0ee8e7c98504b8e553f2923e9e030e6fa278533bd68a067b66d678537953cae83c1cb6f9b89436feed623c0668b37f3add2859eaa1d62ff2714d6a83b0ad1bfb460368e47165b8c12f08469df7113262b5cc1bbecf41d2acf95ed103fcb4bcde660ae0c730e2707ceb639892f742d3e45f6c3d5d2147bda2ec9b2343e4751e333e05d2c5e8a0b289863e7e2373a79ba7a49793c440abd017665ecd2afeb659c88dcc1a92044e55d309c7364ffecf89095fe111cc7897e33bb07272d408ad11084d947793176eafc3a27c34899dc117742b51844ca4cebfed49a61a76494997a164760356c29918c0f5f6fb6bd28daf6caf75e3669f4bc4bdc016e984b51a57656af7e7d5bc4583908facbd7dfbbf7de44847f0837aa1a3405c0ab37074204f4cee1af081c8e7eee5fce26656415c32271aa0b33d535a7ba399baa758bcccc77ec122cbe7a37860bb3f817a099de3af6f35e0edc0f0c290fa1bfc3b8e07996efffe3fdd8ff1545fbbf0a7ffdd75b9e5dd7e9abd9d317c6be4be8f2eb7fbe263f50dafd7fb34fd9eed58388ffa48bf9df19c89919ff57f08da4b4b121e1327643d0c949d1e80a8ca83b96a4eebd3c7c528764ec67c5cb179c6709417c609ae9cc709ee9821b1ed607f5d3ca7df6f40a13e823d5c57d2a89f7d43f844e3277dee5ce28486ec270bce077f6fd53f47e26bdbc5ebe0e02fddda37099ed79f78f3e902cdcb7d97ba141c5151cd29c263ddff456c17ba70ff021090fee2abd779432998a2bcd7733123d930a4d84174ec5223e8bab05ebf84bac58b4bc949d4e698d20af3cee47672e900896d9c779513ca193c55b9bee279a04b110e6a14eb613ea941a53a323f32ff55a0b1f3fdcf4bc1e24fc80269d01effd6b2f7b8c0fec84737c5cb5b3eb3c73a015aa79ebb0ebc1324382f01f06a24e7dd54086a7284a8ee4157645f0bc471eb43278e09fd9f77bbe2ff2bdf234d5a573da4ea2e853a9e0bbe929840b05ffad3e7cbee9454fe3ee9a8b5b7118083981a2685aee922e4cca308402cffb33c914f02d3fed7aba404b3d8193cb69506bbe10b895567eb96c258fc59ffe20f23b9e70386935a774b9c274480f6ab9db808d226569e4d4e60d651d59a68b4be945d1372e355dfb978955e8a5537864fe99de003e58386daadccb0872a11cbc2d42e69d4d7b963c91b3e574b2101c4aaedeea0ff8f9e7804607a5c0ae58b43df4176299b27fbd6ac16a47e06ce5633804718c53f14cf5cbbdce791af5a8465c354ad0c143e2097846a6baefc86cc403f18989033b2744871714e78b3654aa525486b7caded227dfa3f64edcc65eabe793dc67e7ff89194e9fa85464480b8b2344c7d6e840ffb926f8ab550eb48e91e08c1c94bf171a0aec06054c3abcbcd4c971d952b9c59a6f36548ae3d91ab4670555b6176e391e516bc31afe9b503588af86128258bf8712919523a29fa37dcb506114dbdb8b13a0f8df25692732a673809ec3fba409134d09458bfa267ea04ee1ee1c16d978a81204e33aa8e9a8f5bb990df7a827368001bfff35459329a480c682f63a37d1ea121cc2716adc77eadceaccec44cf53a4df61da4333c0a1f8f04bb6bbeaeeac8728dab61ba482f962cf2fbf5fc20883522f7b6587f76f7052300ee946b9d8bbd43ed410e7aa7227ffac9ac8aca5ecc6a4bd786f6d1ecb6988e6d420957ade920f0b50890e9972d81f19b50fb5f5b706e4690e9e4e57c1a957031cabc65cf6a4d4cbe27f38ffbe1d7fa4d12069e3fc93dff2b4bb790b8965a2c762b3235295e0e663f3241010083dae0f3d4fa2f239ab5c26d99c970062298f139f5e0dbbbab93a596026fede57e88e2ef4b5d20e1eae16c6e99e645b973860f7d9dfe9e204d519a9a7b45bfad811090ae89251d8fcb57db61782ae8c7e16d2e58c7bc91c2075dc96cb3c6d4452e195d3c835c93209d74646497d57014f3e747b26dc4fc94dd0b9d5d5a88e3c58804a4d9aaf91bd254ba2321cb67e04fcbf4c2076aa8511251862d429d8a46de9c248c1d629340d202526f5dedeac6e990eeeb4ed8177064ff6a0063ec70a12f02574c993c25f5bb17f777c13b50827d8b547ffc6c5156de11478f99b305eb319dc8a289ef31a45e51689ac675610e338412ea60ef0228068b164597005458671e2775024bcfde5be9c04104fcf86f3b5d00393eebd13b6ec49c008333e99ba2713d346d28f7c650093f000a56bcac570fa29b4daf60141e4ae52d4053e438b7bc584eab665e1eea216f8811e02e14c3bd71e193658cfecaa7fab0794b3f6ac0231c4a3170981efe548ea43e08a1ff9c7900f8783e1777a23ac13ef0cc647d333d87b4a29a09270defcadc5507653493721de7d0656e56f2fe006b6044e1df432251e9cc08957462de5db4a72996099e36011474b7a4f95cb20cc53a37954b4135c6471ce4b1df1dd9e190b38ffbaa52835b9518bf4a6ed7ff037d37a17230c2789a2a715fc90a10c98f428d627e7ee105be96fd1560fd91d3d87f339b86c4045836741f032ba01f81ea2e855ba1cb66b25b0203ae9655fd6f769c350b7751f4113e904130934eb44f1081b96e361ce6737ace3247181e15752160afd65716a7e99944d48a551f17883b7aa60fcb76454575fe4504ce1aa90379a1a2f24bbc43b389d67195cb89fb7d68b9992183b24f6a62f40016964dc3d5ba2cd870d5e8c8301e6ae51d0fe6d0ab1f42d382891a131b7d08499cbdfca6942823d299a3f15167ad2621d7666ffe1edb4c9055e00e9ba9fcf01c7e9dc5ab879931fdff6a127587d104cda22dda4e05b3356d1114dfa831e32183da6cb98f5ec3ad86438e8e93a3473ece3a0dcb307180d0b1bc4fa9d4678ec5e3a6b4dfeb3b5269638742f8a17e0c1986fa01c5ce406f505bae59e7a15887bcf2134683a219349f0cef8c842c7b38a8d53db709133da0e6433fae794c5dd9acb01766a51fe0d675b30d7b7726b3a919cdc224d4a79fc60690ea9df737296f453dd0d4c9095ef7a64d8d47e720e134188a9cde1b1a6a654abe2dc1b9960f5c5b377f3f3de468f667a166b33cc722f482192814e0861998612f0633e7167a217c579ecccb40fac5b5d85fbdb9cde7cda3be34a9cefce0e11b63db32609c07d0899b4f00a26f79d950d44af54690777d095eb471fabe2cf9cbfe0864aa58ac4d983e758c8a67c45ddb22dd35857ee192ec222b3f3326c168de35614f21c8ecbf83bffe1a6308aa3a8308a8f6fdb7acee6c2d418b59594d0394d637a71818bfe67c6356f752875a2a8d4f98ddde9edb9d0b0fdef66d2c7117eb049eb5fbc44f52726c6ff6e32fb580ac9672673c5d4f91f18e366dfc71fa4cd9409b3a497d18c7a7e51187aff29c1e1be2379bcae1e34241d44572c16d5f87f61b62f3985a2c0f9f926d792525389f07bb5561437bf180d40b11c18acbcbaf4c1e57e4170039e3e6afeaa9b652c51fe5e3b9a2eb90f5d54899d96cb67ce1ed296677b18fb6444057e72d2f9a4d3ce694a1b5894c94dea9b4e1497b11595b2e294a319f5b2cdda06b7a546b9c7653e886b0bef5589402af7324c60c77b8f34063d7e71c4174ed5962f6738c8c728fa049257157561ee8e1c6de68627b350811e44b4564fa0a3656b561956e06234a8f8fc7725896b2f7615c82062836d571dadb4e8cba775a5eb35bb6917699710e4662d1765f8ad4f875bf63719220ab48852569d020a5cbdeaef1a7fd733efe9e78d87c7cc4743d42b7d1dccfcfb54a61d21b1db9ea1bd93ca192f1499dbdf72ca5fdce0ac231c25875cc740446d18959ef70e1e0dd0ff762f7ced5e34083f764c30300677f869564104f5f9e5d25111655ee1dd5cb9aa404ba2682ce595f321e73e056b35e19838bdb9f7beef8949fa149fb11913e3ce2b6f9ff5ad683e07c62d0e2efa0cc6932d82bc99d0e4736bde20541de878679ee3e401a9dee1b910383c7ff0fbe4b62c2e3e18fa52af185fa2127f942b86e89c3d14eac51f9bcab93dbd1745af90923f281f19b686943f8663e6e8cc3133b6de9511e23b06669876309df3d85bec63f34b01de82f7f0874a06bbf0044a9cecb38db7381c54e22f951568e29134ec5011511a62a21d7e513f7b93c8e49b436666417cf3a0883569b7e07bf2a38e146a82dbe774acfa93c47b2ee011310428801e6e2ddd05208815980ef586ebbfa268fdd761d5f37cc971d533b708cc38c54697f145e9bfcd95f18f3cce295c54cf78bb311fed501eb957156cdb8a6713abfac55996bbb067f60776bb39d2bd3ee1d66bf2fb7801bfe53907599d8f1f04129ffbf7aeab26c764fab9dc1805443e570bd6e6973e7d4156fe28d6303aaf1b910d4200db8a02129416dbaa5866c6ad15031ed50ac151c2ae2a976213cc7a9653cabb1a34e236613da44eb96ae3ad7ca8c49a5f7a2abc9ada50a16355306e2dab39c03296f6d5133fb0a728fa61e5bb3556b56c29d07c277d6f8a3e54cfe29cd2163e1f919b3db34bd8b92fcdae9a888f0b1ee70f5167404c2c0065aaf856cc7c1fd20fdb1b31bfbe469711c4e181c045671dab689d2eff0bc352cdac7aaa1e3e9b0ff9c409dde04d066ceb81430a675073ee14b9e15651a9a26135c814ef118406126fe1b68977657da39e091f170363ce0737bdba45fed0f4c51a43f4337d4a2b25f3feabefbad383cbd7fc60bc06561fd0687f6b38fc74627caef34a9b8b7edd86aaf8ebdf45fc88444c042f338c63e0137a2505f0b63d9d3e6c19cbf003aad68e357baca7f9c4f3bfd5d399ab39932a3f2ae09f4d86a9e304684ec08469b2d7ab5666edf24fffabe7fd3588bb9404c0a81f5b17a151334103cc4ec790e830c7aa9980c70ac1d955808ea208b6496037e3d86e3ef7c84561a5fdac8208b0fdb2e783d466d324c3e6e9fa34e086d870797d71f5d76f17a853c960a95f6139f9a3055e48bfeafa41d4dc9b0b4c9b9d50dec9a1caa3dab9882af32138ce89a67b11d3eadd65f4025fcb0f77b75ebbb2ea5f887d109b331ad71a1066eb35d81f07c3b62527b2da69abb0105827e505cc3e86f6f6c2f41bed8c723673f3b84ff4ead0eb487ad487e67e1d0ee91ec1a451fa7b8592c6e10deb3ff9843aac9c44fab1d95527d41259ab3de33f2d3cc6957b3cfd2d6265c110091fba62ee793bb7b47f91bd26b7e1f34cbb289c0dfb8eabdfcdfdd6acbea526beaa077dd476b389e662ea44d1fd85ecc68f13fb4cca61ab0884cc9a74775c9bec58896c3ae7df653c3144a7947fc9f6e84e2e98d0e10768d73fd8179d3016a4c13b335fbd60ef5cbc9ead82c8b387c3f4eec536a7e8842e7e21bae05571dea16cbfd653fe2766c80371a976168de4112760196b1a9b306030ac8a7eee05686abd77013eee58a95395c790c0699709d86b3da6a918ac687d1a305f49907284e18ef4bb6cc2ac8398af647cb8f445e87be7d7043f805a2fbb22b196f2f1b2a63e692b7d42c7b15a13076b52373939d784ec06ffef05deabd8e8687553ba148fe412afd9682d6de1a3f69f0635cf8c09fbf23197c1a621ba783489c5f2a70b1696f46d6dcc681cb1df2f01c81a63c4eadcd29b4e36e74d5df47071133afd2d67b9c3ff35511014bb818f0893270d361a387d2b902b2f054f9e6bd5e4a6d08aa242eb50b3baa27d0de92dfae496f8f238038c4f748c19526332a26606bc2fa775aa192948e3dd9c3716b221312af2ef8031bd8fa26f9585587396f241b55b5e580b43092fad7eea793983fcab4a219b54c9fa040aa6bc9850b4a33d895606a8058e91b59ecfb45025381a27a3ad6a9ea8d2aaf57cf285bab6ac81ef1dd5993ecbdd4f350e93b61495367f576b3e8e2fae22ec25c777f9da1b5edfe93feb95eff431a8f030658cfe987bb4131484d3cdaa33a2f1bf32c66a75a1f41cee4fd4c9a1ba0a3d7f9bd05cd70903f5131e03146550aee7b3ac8c67e3d4b30314c6dda0e74a2de8b253193981296e3e90960981ad5f91c16b991e4626b9d79966501e906ae91e0eea2c35619467f20d05129bffdd3e1f6bcee8b2f5ab2b8dd1ebf43608c7128c220c8ecc917b0a9ca495e9d7a7867ce948a0ae1cce0ce47c247584740d62d2fae07da595077c507de76a6a0dd757a041de89e8955f815e9c075e988564c0ab4784ee08028ec0eaa90dab23b3c304c276ec49a29e50c9da3206fad03ce84eb37cca922a9aaa554ff5828664cd53eb9113b01be1c670f9b9dd5d1bc81c08303ccb705a2832c3c509ab35451e8080795564a05db10810e6db0688ecaa8a1dad8f027777152f5d620c3a286262f1e2d79162e98992c1182c758e96e2d1caf8e3e6485016f54b9e62e6e23c32adfb2236a255d61c248e00f5b0472d06a519f2a4a18a3cb015cdb39fb8bcdd676f9e28d1e83956a76f67355a3e05cfbde5e921ac3fe2a65139f95b2dfd243b7f5b7ac4f771294e20cc9a0ee50b5989f2dae5dd481f97101a66eac8253e9508a75e77f9863425d8ba6e0d58faaf89484e326a76481e6ffc2942e70a3465be326779c187cbd5ed59af85a7282a3cedb6469dbbd73cdbfddb28eadf1efcbbb80c3be2912d668ddf476bbb5b643e054158f0233ddd651281f4da1c3a4eb9dbc439b9af347069359b3898b91c64d7f2a46b2c0f4386e7ad1a1762cd3d4a87985aaaf73c100d3abc92efc15ff16fdabcb814e6d9364ac0ef598d10248f21e02cbeb86cf44c565c9770614ee32b329281673f5cf8d4c503b3f7b737a46302b46f5c5eaf62cd8a51295d9548b72a043aa5b7d3066d858d2b66d36ce78f2768d95e53a87f40e75b76b2431d8d6f7a083675f5e2f0b2654ac871d792cb7896e085ce0022f2915d9d1ae75604f63ae3a157f6da4f2dbf6e5de624a6d41a2e02b5b889f8ba49b8591f427f20dec1af789fae58f51b5b76b519ca1ae7c2ffef9c0ab741036443c85ea7c0dc49b9cd2de3708a7a5e6e417c536c5132b701eb3636771b1d4f392dd5f854846235da29c2acda6576a983e332605c826a94d466a05d18a7836f937aa603a7990790ab8d2cf8a2b07d18eda174a4c2cfea191271ce780e38815c01f6ee7ca11b70127e606549cfb67a3df1b89844d1502ec0664b373b7db5249fb2e2ff17f64c0b3a3b91292ec285aec6b534b347327d58e0d8299c8c5a7fb96cb913eed5210da349dbb4fc1561085dbdcecbd12d92e7b16ef7c1c1a498dd3e786e3e45d1a4a5e479cff91f0cae8809e7873bb1215f1dffd75b6877af7d0678619e3889eae9d6c7d7d44ec05fc6a98d5ad499f9d9ba3c1ebd3eda0cde6a03dfea5fd9168ca69900f06a2efb0594ca3c35ae9f83a6bda0fcb224437723f065b367eb0b856eb7f94de6945a6f6fa91ad86c591878ab1556243fc909e8488ad8ec59011adca9438b1cf72edf30cc92cfdeeab0a95e37f2ea945d6e4cfd9ba295ea2c821b7e783f0e3bb3828495c7d66be221dbf3717f03982d1a2ee3983e56029393f8d583d0dbc78fe080a885c37fe5ba7101a8f00aa24e11395f92aa6d5263132a7e662db780f4ff86de65dcfcdd4bf078173c76d789074863ec992a02e4de83a1423034c7f44098bcbdfe302efccef5fc2492517a3f2dbf04c3ca552db7c9ebbd9b70867ca783a6d70fba9b14d25317e7b171ebe23973993e2fae711c4b6bc39196f9b0b2b696bc27d46d8f9e4e14cb7f46d14f760546883f28dfc942e51f3eb8f89f6ff5caeaf2af7e24f30fd92efee71357082d927fc27e7d6f4c1bcbfffc78de61f29314c1f36f32ffb821b83e06ecf84e448f08a01c9a67ee47812ae44c62776103ee1cff263359a6389af182086c7b451be53d867fe304dedf23133d5d2a1856cb24cc939a23e0c8f3ac39dd1f31f46044dd4cbaf62dfca5e1474153e076cbb21aa43d4bfe7f42544d6feb44ec44122b9182846fd7a4028521dd516668061e363e7d6ef0c54d2dddf1dab0d5dc1929296d531eb51a5a3163fe218ae61fb24da2441b5862ea368d3e35cb6e142dbb93bdf9766af2a29346a3877c13e4a19f035bf03e58b9c6b9d0849c447113c5700f74a85e239e78babbbd69b4a2a8c123a5cc9e673bd796d3108f7d61ed32526e56a4b7f2b5d51facae6a2454ed469152eb1194e967f64a8796e7d034924436510513756e55ef9af880b6d128f6dfd96222ee6352ce06bf1ed4ffe46bb13e311c0ee1464975dd7af3c3d07563b9d6baea8b35eefba9c9c6c703f97623b0999cf628775dd93c9c285fe1f8c805a3861b55ee3f55caa5aadabac2546430c2cc72410ad98b8a6d91c67975941936b4dd75bd2a65485fa5c91b332e2936106b8fb5f81cc693517cb1839ef3f4d2ad69ee7e9377a6b2ed65789d8d67ac9fb5e0cb9cfc517117e45da56748c32813ae2946e404f226afd6d57410eafea9c5af4d4346faed9c399a35681aaa41e6efbd3f027a5dffc1123423c71bdb7cbe088ef3b1f98e9e53973eed64d2f8e53f3b4270ef3978e533e168f4d5f16a6ff41860ab49e85121268217fbe2e6fc2fbaaab12b78457d76e8f1e75d3985fe99bf1554636354f08e611c1f31d342edc4e4758cc942d1c3c90e6f1b9b963722a8aee6ca74ee537ec24fc7703a5726f40997cbe4ca4c30cfd9bf9b4968687caedf4de708ef9ccd7f8b7dc890b139c3f5c4e7dfc81ae13409869ccef7fefa5933f14f21638f929adfeca35c4b2fe678f21408f66f1c4cb50c3f45d117da99686bf93c1ad3384eb3c86c2500db9af06c3dcbda6298d5a5904153fe2b7467511ecd6d25cb9e79e2545d7936d0382caa7793f30c1dd1655132950499bcc3d2328e2b742e383a76ae69b54f4fde3bb54c0aa393dbd01d5f3f989af0adc1d89b1e3ed14372dc32d60ce3a17d6ddbb909a32fff7ce31dd46feea3780131729eeb793c74212250db4f611ec48f3144850b3f9e556f14fb0434b146a176d44ffcf5bcf503f99624863af0ac8fd75460387bfaa2673ff8ccf46b3e33035feef767ba37f8b3af094bb2b337cdddd8f54dc73fcf2d5b7efc7235f63ac142a36b6766fe7ca2513efcd38084538f8bbf82b99b150593bcbe3f6689dfa8d6ed5963d9b3d67e70dc64edd6c640f4ef6ecef95d67d752441c8bbdc3b0b32636533f620d88c08897fe392512a67c542a287703d45ce44cb96466ff2e43142c979d33b866afadf521d237ddb413b5bbaa70791f45935690187f7a94f0fc696b723499413301171e6286d9c77d81bfcbc6d476c4e835f5c45d04b67f02c4260541a61ea50362260a6b2b15f894a5f858462c8c789787ed8f2344eab3a6fbb0c20884d979d06585d05a2ccd3baa7bacc9972c3bf36283cca0e8e48425574b9bb627a6c7bd72d9bd6083d3ad7c8ee215363fc7c1f33befe914f7f73d6399155bfca1e3cfc56ad7f63fb6fd9e3533baabd81cc043bee39b1cf31ddf6837bcf3cdf6c33b7f0c673933e0f693ff7b3d343def0e5dff0982e7f022e529ee816ef1e4a335690d0c4a9e3be2a5bf1b0a92fe9d3f92b491f5db5e1fa631e7e3725015281b60df6346fa4ee00b663a3501fa6184bac6f56b903b46adc5e7de65f20f4eb6e62537b392528beceb3793bd0fa2ef5d5f474464e8103ca0639c5898cf27eb76d0133b892750372de90d7208e1ef480223e51e4c0115e99af5759022b37032f6c0f2c9a6ebf43e1af72641b435acdaa7f66f3a1f5eebc59b966c364ecefa3800aa0c6453717287d8e0a25de8b66d956a63b044c5f642633d3cd539ce8c9a5e3deeb21e78b4689e240eb0d0ca1fa9aacfd43bf0d07dc31154621510f1d15f8786ce69c0028f4d50e151cab5a9871a8569c062df46869ffb283ab4957cc94410424b1fbfe7c855621ec7599770f16c6656b00a337d5535c5daa4edd1a33831e5bfdbeebd530e8c1ba08175ee132f457feab3a1a9fea90b132a5a37c7063b6a9ea1f1be05202f5abc894abc7638b670aa77de0fea756c6f337319777c74a9f0e10596d75b55b2da55d00628ee8b884cfe6415e6dc3f6eb5779d580e58829a75fa8780f8e417af190f9eb0f48f77523b9b7be46e5a3970a25d5d5a6475afc44396d01bdbfb3fd7848636df14161c35f9a20094e5a510f4f27becc5b2970923180cd16fa90f942af619e23200252f0fee44fb0b4c190eeff4f0875132798d9a70bc9236178fab25ce40edc1e361b3c0ab03b9086e542a065c486bd94f3a995e14e55bd541c0d40def523cefc71b8db9162227a720aec22b633ca4e585ff1b43693b40ea5e901bb4c094833beab9b1db94e39094cb99157df6d107cd3d65eb653b6de59f3d14df5cf3d059405cae653fe67c7867e8ef34beec9c64aff2617006b3ce3919dfabcc3397119d456186778127415cb7290e4ee1486e691cee452242e5cff46950d82ec337e0a1720e571e9b3b5a76eacad56d1e837dd8beb3019b320938419f06b79c647aa909b7fa58a0d6854df2259dbccfef2310e83322b83e3424d4c48dd87f73833b7ffec1a113c7dbc13de691f730eb65699f37980bea4fa07b6d70f826ff0f861dded9a21018985b660ec7454aeba6e4a6acb1fc1ab6f0a24c5bb77f77f31075ea30f377e7f7378f51a77a17c98f3bf9814e1f3323a9b3f1a32955f214750b29ce764694cc9e82fc75670b0b6f483aabd366539bd2337eddf6de850d5f4f2f19ab9dbed48aa2125362904503eae09aa4520896c75b495007de99857e66d7dcab87a33b2f1e0e46777ebdd988d330f9828612a4343fdca2d01d6ab8c64a476b3a79ac7c38b13854fcc8af02e16e89905a787d6848ed7068ca080c56411a1fa1502b53ec64c2a0b12ce259bf5637dbd018e3a0213ae95510c073b13b19e9017870a77887ec7f7a2b662296b7336ce201da43c448ff0a22d94677341d6137a6a33b387c8b3cc2876b1b56b7512d9aad2d78f630dbd2e968f52182e2479469f97ff6d8bddd9d382df1a1d648c23dbbb920aec8cdc83c56abd15d7657c704c4cd7d144ffe36de2b1b3b370bbab3127d17e6ad534cb0fcb88aa3b7659fbbd199981362be5b568f398c3a414ca0556f54188ed5ac1a978766f60b1f97d5f1b66a5337323657a37750be2636b16e71c6ef942e096f3cf5e29615abd033d95102b2203abd656b5320e7f51a457f07e912c9306ce1b930c8b5aedcb65e8735379caef2acc81ae1b9b224a88a606ac08e2fe41207df962d84168ffa22663f23758a43d9c8e3bf73331a6514773dcf08ae33b84222b25d43e0593d9136335a4011a83fd280397c5e656607ff5cc30c9578ba17ef820ffcf3598d3a1cb172725ac5f07878b81d4777e10433ecf3ec6493329446e0094e6b139f1b7a952ebef8b84f8eb1e4e0ee3cfb23a89ef05f7c4c15cea49ebdcdda5d050e61ce338a1a4a197448a78e2b7d21196e2f8a37e0c82b6c57cdee73e2a345c73648467777f644d86bb9c3df60c3ec89e76cd1b8fd5f46037a02703ef5d1dd550c983dd1a57afd144041f71c42976ea1b071fcd1e4ffd970ca825e9dc69de55aa4427cf8441edd9de1f6d9152dfcd758a6356e813e0c5a9aaa5827b30e7807d1893c33664e763c47db20fa5ce459d63fcf33fe80603596cc566bd5ecc573e34916e788132ec449228931e24035bfee1e283016c9655ab0e99acefc58987320d142a6de94287987c382fe9b55cb8e2686695ab246746ca2f7156b7fca3fe1a08f3cd5507fe50afe86a4e2cc6c928a57347e6e90b3b7b9b96afbac743d3ec0d23b4a58a7add207169e88752cc7d6e803f98a7ccc726cc303343dd546c702911fed6bf0c0ebcfc462786cad8033ac39d1f80c187c36848d795a399929ece86c3134a4873a546d479fec2ab276b0161dbf1ebb8410bd28ea0bd5afdef2c3e3e04e4dec72bd1164956aacc193d5d83d19fb6b5d1f2f37f09c06ca7b65b850ceb216abefcb39fa8417c98ae99da9f43a8cefae6d13b3976335950184e9eaf8ee7220aa6e20db1daa884715c8ac5a8b39f6a48c63d170c7e2cad89f2aa6fabadd93fa65879ec449f76b2df1330ed4832998a865c7416f9fa5c150857e697ce703049a04a75d7fca7ef4dbc1e3f2f8ce05f9f274543881ead84ab7c7f19d37e79c08fc1a1fbe0bb6645c6fa324da2295e46e27ef8abc561a544935b7de373fce8d99e65bf013795cef87dbb6b55982cb64c6c85a78869aa7aeb9907323f496671ae3f437f94a1824f5c5760c0dda8e93de0278b0861609bc14cf35b99c7857f49d03ab4bc23718ffc1b4fae3363fd4e6e91386db6262faa23106256972620d4c5476b5371a660f490e0fe8f72b30649b7d1987ac815bac09e4c861531f8d076f2f8a173f8a325c7bffa37d9d14c527e4e15e106982a655732d66c8dce8d00da86193c62c259af8be9f5ddaaedccbec4237a014ebb2320b1bb65cba27028e85681c3adb178f6dabe9ad9727071f3cdb3d67ea4223e0a667abf2d187d2c7de1e14dba7ae48df6c7226f04d2777a83b30c19c8770b85a3b4a8995304e446a40be6e5094b9bc612842dab5f1408cbde46d197e0a5b45dc905318e3261d8fa8c7274be54989471068e678b778f27260df5cecb849a662631fdde6d0b8cf74ecbc275e65a4f1abfe4a3b621fbe49fa7099034ecda641f6297af72b0b0a12449b0075c82b5224b2a379ecd3100cc0e83dc298d9a60836e913f8900299a6a660fb0eabda32917c06dc42943e7b1e644e2fe7c36fda2d77c673c6afc132fb32850f90d397aef674fa71636cca92e4d90418d25c402f55abd37e54c74dd8a8776fbe47f1e4b3e97c4433b9244c3c92cd65d7d51af33dcca1ab687ce0873d5ffcceb137115945a1f60538573436898f59af4c4d029cd86b5a8bcf17bce049fbe85a82f7a77ae2bddff53008b24a5fe2023162de76c9b976b1639c76760c8da2eb78db8ea26d7b5768f9db735d7111f4692fd58b7d2e5b515cffc93e912ed8f5796c47d131ec735be9d9c409f58b7d221b25fb8477baebb3d08ea282ef3305f5bee21c19e2c127a3fd9f4ddfb43384ae685bd2a3011337d1723d9dde19e383afb32bbc04fb4fdb785385af3fe9752aaabcbc6c9016af7a061ae571ed7ff7467416eae6d15f623e634067c519503679314e052263ec1d64525ad70b7d975620d72568f5ab88dc803e3a5bc9bf73b938a93cd8ef34b089da639744c002db6b957a5a126dca307417c7239cbaf662b45cc7cc071d5f61a71934079b9d6dee304eb2f7106269a347f29eaf15b6bc0dd0865964d5add18f4eae26dddebcde620fbe7ecb78472bdeea36b3ce712b8a27ef6e1ea3f6fc61c3a7d37decefa5f2096c4219be17b909d8912a03f7b310db649eebd4704b6ff6b4336da5f3d7aed3847c609edb0275d05a0af38a809c7bbc71251dab2b3592abefaf04624a4ea4f8f4eb44d8873893915d0f63dce47227be98b0f0dc94e568261244fd5d41ef3f484c09dec582c577346506c39f5d4092ec37a48f92ecd3ed16d545cb93370903d111a19018a36972a2dc3bb6c7faea6da7a2a6ff260e4f7fe9b18b3efde561e77dc8ab93402013183c17e840fde02fb70951d1d0aa872819bc1ea777e2237df2a89a44dda6a8305f5d163f77a3a644c361a9b28153e0d69e38f6922199dea435761cacd7d4b4fd1cb7265bc5666a6d8dd944227e114aa1ee2d6b28a038d0227620e77f807834e0efdc1e86d73ce59b4bed1f03439e7e391ed24029dcd5b0e31eca51199ac255bde09574a2edb9c9b87756c5f0aa1fb0d64ddac8870dfaa51ab42ad73bfed05797e8fcc17ff097e2c57d08b787a833fab8dfc341bee837ffc167bb5e92227d0453d9a2d640145dc43a1b2213dd37886a38280da33d34a6dd7bc55ce68ad202469e79d7023ebe34521efc5e4171429808e445c73d382a1a77c4e529f11ec9569e3d4e8ddf60bedaf33f4e3def4378841f003e3f0d4c1dc972a3e59b2d735defc4b81a247efcc5d03810cf97c62172d5e41b775997b48ad4f47fe6cef1a01508e9d3a1a02a736703770c14248cab88e3cb59a84e16b71eebd7c54bb1954c4f22ac0c088063a91aed286a842c154c6254f18e66e72af2861cb3725b8da34c7d9383f4386545744eabd9cc048108da4d4d2af07e89d1ec24b32eca19d8f8c918a3c73343622efb972cd824935b101cfe922f57f81f51fd2c60fa71fe173a00f2bf9e1987f8ed6676e68b4a6345c75beddc8cd3af943f6dbe1ab1f42fe3d5f688cb4159f4f4bbf796d23acf3828ec8b336b9e7575113b95221c8b8f4c8ddcf5d6fd19273de4a79de0a9cd4e987eb2244b304c1c081d862d0bc673585a63b0f1c700fc486d69db2ea84385b98a9e44e50be88525d10cb39fc9fd43c5d90801b11ffa7b8f9d52ce7b766741d8f548a1b0623f7808ba5e0fc038a701d1c054fe7c75716c905df951d7db5c7079362fa0852fc2187ceb602442277fe4af7e9f78fbe995aedaf9ce9145096ad886a68f9c7dadefad188c88864ed3c8c63fa34e111e066b2321341176de4087c316adcb8879db7cfae70203af8d292f9919ff2fd0ed6f141a620aacb953e4c55a60493a473f1d58b6a7d6d9aec9d6b3a7febc65ac329844e594f86c40386bf9bd09b1dab2ae6bfdc438ac42e28fc0aac0429205a3b338b022c89a714ea3cdedd97a5cfdef015381ed4e2d5b00bcf6e826ec6e87c1dcaf22ed970b9817127fba17056b6ac5bf9a0acf08187d22cd8e8b52cb14f7cafa84ae5c6d3cee5ce2ddfe8cb216afe77dcdfabaa0bbefb644bfd174c5bb7e2f585681c19fc5be713de1b01f027f8c85e8724345d27a1c7b41b732b8556e2b5efd6a048a16773ef37f63ab85254238190bef0a90b3d9b3e667d77a46492b236a4e9aed5cfd1f772c14ee9f1ce6c230125853763c9b237ac2b00c20eec7f99d679d25afd9ecc128972c75701bab011c9994715f1d497170abb00e575641bb6162deecf3b51649c673f7e7a0d2b5ed5d0854d733b06ddf605fee12185a76cab49b875d3982b2589c6987e70bf5a94b5fca895cc02cb1e2eff50ae76b431975bd80c5659369dff15ae8ddc25e00e9cb28cbd86ed90b3c9ed8d5113b09ffbebf41718adcfd1cc0fcf3d6775a9d7b864e2048d75a367d6af2bd7c519adf65aed7573fe1c3ef27bc9709c7e55ff2ed8e332e5c987159a7b5389b71fdca8cd9f4296f675c09669ce20942b6bfb8511c0e4e6d36a3c5b66311cc61c5b6def15815db2cd3f145840cfe74fe0bb157d7c5962ab8722cd51795c9c42be66075acd22805c4787e6b0ab8fcc917d3b94955d27c09d3c584dfa0609c20f5dc7e95b75fc5a3c1a5cfd0603937a1d08b2f328b1cd891c197df5fd01d1388df3311e948abc284809c21851a5e2a48d47a226453709898c542cd3be049c05bb70815ce9356f038c23b667264c40a7f978b98c7e0abc76a11bed0b95670d81ee0c4b53ba85944f8fd55a6ce0355e29b0a08f57c838c628b0d733fef00f22ae4944f39d1f2d23d9a5e187da164cdd87ad1683450660df323b222cd10e2373191c48d96d8083e6a199805cac07c3317e9d542098fe677fae3e57832b96a39ad9e64e78e0dd0dc4bebf0fe3d8a4fd827063fc399618f7cb18f3bc61216c8078941ece7ce90cf4403797f36eb74647c15a2920262b1cde04b2f25c218624a896eb20f8780d9f59419820a9586cfffd3176e76f36eb135ca3dc545624b8167a1b803462b12a54d5531a9ca616d3b83a8a7f97072347833986b431fe029bf32ec52ca6957b6a04a55e3b2584735dee347382b3393fbf62b318e098bb630ee6bacfd3c0986a5df53e74be6b45e1b53a5f0cf326601da23ed3b455349e409183fcc09c11976eb2f8698a54c552af36ee820e1001d134f3fc05ab9d7dcf41a1999f6494e73d0e26e4f848b1db702b750759453f7dd74f77a349bdc29af2adde1cf170383cbce85ac2370af297c141f942c71367d664319f0ff79a995f950472ff0c3e691bfe9ec5de4ff5ffd776953f9de691a17ecb608c1a4f05d7f494f15e30dbd11a7b9b8fcebca04f59bcce8053c36e27e3a8367c08f9fc87f0f86144f1e0d894041b8a5b07ba35683abd4fa3663847a6d5bd509bd488ed8210e7cf801b6d0ba038fa9279814cee341d2dffd5f7678a406391b5fa35551eee07cfc3d84a2cd7b8cbfb5796ac7cc373729be95b5bc0933fc0925b0b65b968ae337eab2de78f25264dd64b6a8e14c0fe047b47bef1d58b73c8ddad3a14041e797174e2736eadf5d880841475cdfd6c4b9500a12e45a5281a461a10c0a5a819faad0cbbdca9232fc5d4d60e338d9622db471181b36f4fb4e9490fb4d7904f78eeed9b1ff7bdede2f89959c06d8ac717a05c475d6f4d426cb3385c696af0ecbac0986b651f989b0aa73a7500dcdca880637611a5912cc19c43406f2cfd0353d20574ff6ddc42446f54ec52286be0fb63c1c677b169ccb0b8b1ec98cce853e4dd33fae20e1fdcc907631bbb18dc2666c097f2fccf54faf503323f5d05cc0d0bb65677080b6fe114e98899cfa27bd6d59cb924cb263d84f5ffe993679d88da26137d0266be2bdacca36f85335a4c50f46129facae456368dd79961dd680d1b0e2887c50663cf29e01638720163b77bc75a195c9b0c28b219dbaa6941004517c869f4cfafe932cfc1dd5ae27b9148e2d16d21dad7a864409e44a4d3823969bb45c15c03d36b7d023ce266d4750bf47d1b63b2998c40ed38290e6726756b03d37ea2c0a4a6552fa5bf24abc93cd98cd205d9796b7c293e55aa8ef0be67dc50196851e934e0acbc3a7eb428f2a9254a0daf1e9b6c0ecbf4880037539148d4da552e92a1bfcc1879dcb76825c97e425c512dc17f9a53140dee79ac648e044d00de85d834a2bc643369dbf7b2f8a8b28d05058192bc901baa802a5d23f978e3adeb83cd5aa37bd285a75ace5b967ea089e8b278280b5d863e5a146efde0a749a1a244e7c1addca812de0d40d4ea6c49d6adc98166a31f2e92a05c4987032f9e9078313c1a09b25576490ebf08578ac9dccdd50a4d1667c6a29eb20c0270b24ee4b4d536ccf5adbfb2ffef99955de4ed6892a6b99c1a8a5adde56147f2ff76d54d4732af3d21e96df9b50082a8ed67074ecb778769a05cd38cddfc4b9dcd29bc96dfe7e7f019d19bf6fc24a0049460d729389b8f2f15b4e351165157703ceae693d0ee8c12237a8cfb81d1f7e65fb75b6e2c78b9d39bbf49a4966e65b143a0c14acc362d7e7ddda96da56a7e2e2d031dbfc8ff3cf4bab3b7fb69a2beb7b8075582575838d672be871a7abdb405d5867ba53abc81c5291e78d4915c26e7dc1202b3800172de4a6d981fe2d6065ed0b89f93b08c15c8b236a9faaaff59df1861030dbac86d477f6826ac42f373eb8cd388938be34254662cd5cdfd95bd761aea11414334c090aa3b906dd360d4c0f4e5461831462c19f8f1ad41fab05425d0f3dcdd46aa069ef0cac91822c3c0308c4777fee67adb3e798ad4301d37ab7329181fb95492c109491cc3e3585364c8746cd7706aa44d520137ad94993e9e27cc433c8bdf9673cf8f5e78d2ffd89f9bff127e62f7f62a37a5aff66b2c3166ce7170e48c9d8269b5dcfdcf2c8753d0d97bfea5d87f6c275adefb49df8d87583af1c233e6cf13bcb899b140b1daf3e1657870fee02e7383c589f643dd3432bf0a619e56fc1b87aebab7387d0b05233c27d6ecb924b9c7c7ae2852c8aafa038666f13af55ae7dfd07268ce1ca28d58af55bff63e82c3d40a03d194f44f55bcaf72d8a9b3fa360ca7d4ed9512d21c8ea4c2a6690c071eb0f21a1bf5d4f89e8d99c07c1611ace2bfaf69b69fddb71454d42cd06161798022adb3b5fe0817a97e41c97d7ab5b634c1ac5fe668a7d40c4287779e73a177779694c5232490cbb1ab4ce2fb363b1e54b09e68ab717efc23dcee0e6c22ac7bbaebfa656bbae01bd37e853bda54dfbad289efcd2c6fa92fe0d02a07cdb77ba79b3d3b5e934eab73641a76bed54d4e43b1bc3b4dd2118c370e86f58550e88051943e53cbbffe7ae014b261439ed6dc97fd6657d09b945b0648cb7bcf17e84fe03a26eb31026ee5457bc905fa27052ca5b387abf6dd7aecc50ca5cc0d278b6cb0d5f27d755abc6173d01bd8bf8256771ff979fe6a57612b7207e90f16cd86acccf26e567ef3b0aeb55fdc933f1e0a2b5afb13d1bc433b7973e4e4f4e734b53e2ce7e4c9fc3eb7a8181461607db221c29c3a7466c31dd9dcd4a228c7654a39c4346769d6b9a9f7fed01177eb2608fb57304382fd67573969bc1832aac08967d261e3ba2f9884f83d671610793b218b496509a46b685bf2074ed5af591cddca35187750605fb3857af5aeab766effddd5e39f6bc00535d9f57122fc0ad25d172b90cb5c6079a35bf701b4585dbfda30ffd5822fbfccf3cdc3a97083b5888c7e6c7ad3877fddcbc937763bc2bbfc744848c7ea7eca039701024b2016e6cbb7ccb7c370d2dcfb980bcb9ecd075e970e78d6ca7a9a9c530ded398d05177946255faee6c4a464ddadfa383c19eb855c56553a1cba37633e18de0ba850cf010c59b1f208b284bd4c9076514723b749ffd3c3bdca4da0e7e8faa5e38e9a57374eb1a701c98950bb80f73e40ff303f3725034251afbe5ae15759f5ddda2d9fe37f951941bd87ff1f14f9b9c11f773156329d0fcb89aad5b93abc8f68fadaaab3fb8bb69c451d488750a1017a9151ddcdd14e228424e92e732ea75beb34a073a7f31942053c35fb514d64c9844d19c517c9b957cd50bec59e9645fa2e875f9fda6124751c54d8c39c2f63aa5554dc3eb1c72a14a52a7282b3dfa3233f540365e17c5f941cb18f479b806356066a58cf4acd5b22cb053e26ff8aab2eed56e7fc9bd5290ad0423648a1572824b86d00e96776707bf029b6907a30d582b41757a099e964df4e59ae6eec3c539f4ce0acf70fba1dcd9b4f201ebb02c223c7ed9a21d6432a5916ed9b6c9b6aa4381ffdee4149bc8ee355bd5c40037fd4cdccc59be7784686ae52ad2050f934c0299a83727f1db1c7b5e42cb21ac105c49d7abb9c6264ccad6c558322eff84938ab0c64d90a9c3a39884199dd46a7e77538aa3a8147f245f26f7a0d2121eef5aa163f669c47dca05fb84cc3ae999ff84c4ddf102b69b234f7ef99fed192c0a65cdd12ee171e71834a26b0448c59e842a831e7bc6609334acddd12eb2dd1a14f92afe7733ab171b5ae69bdb339c8d0f18b7a06eef4cb3e24be14c4197267ce14baed1e376c617f3a126f6c3feacf48361cfc536cad1e4f3fdb067aa3e9df8b430ecdd0ce3143f99348ecf2bc31e8337a9201b2a17a4a57c4a7400e60b5f086e8f05e44dc6195b4f6bc492c4e351384f836a8b912f5ba09f3e11319e476a9775fa162d4879cddaa3ddce4094e7266d575b5f24aaf3a19a216d289184f1ee3b2f262712cc8cc362c770fe6ee48b0fe33f7e78f6b94b595e5e85d8fea822fc92aaeac3e4dc9ce97d7444257bb8bbf4b873e961fcc70f3b7f3c5186d51d8ee68617a07fa0018d2be04a3e55787cab214b2006e02309dcf19c88a04b2501993e6becb37e91fa48d7547f1731444324ac32e4acf1f1ceea5d2534863399f27f96270483b904da316ce168b27b7c6a1c8c83feaadacb40558984d7a1cdb8541dc86c31359b4daead2403c5f99fb4513886f4bdbf458c2dd6a46097f78ba34990e9ef38428aa37be139f12176876037a0a34832aac071605eb50cb23ae224e461d47cf118450ffdb30aca83a02ea8b89ed7950bf6e099adef821c45e26c4130618beaccbfbf637293148fc775c69438518f59ac2e60db330eeb6b14ad65818796fa6474020d7e3136575c4d9a3e187e4d4b44d78f671e0d36e2eb5814e7cca3b1a3edc00fcfb42a3e134280103fb1077fe31fc9e5c012fd7c28bac5dcfb183f9fa6ac0337018737239388a276b48177d5aea701b56af7225d3eedcd7304e9ec114853e41bad4de04c6031ed8c80c5e474667fd159e80420bb77f65427378fa19f71ed903087472a0f9f7646201bb3f3d929d80347fcdb991319e6f65c578d68b1a1e6607ed2dc4cda69fbca7319616813c28d1b3dd3c60842e18b47023df95d0f90e41f5219e062471da754f7c92e9da278af693403d83408fb3c81bc1d76825da4e5559cb106279b4a603814e5ea162cf5882955d727e4a0d9b0edf6a42ef91b82607ba227782a441ed82cfdec1b42a3352b3093659cce4ed39a61b7bb61c79ff16cf2dfa9b4ad77e90f944d2ad959739d3b86edf298bffa002ad1ec5600c0628596ee5a1b96871ac05c7871e40c5464d9b044dfdd052642afb93ee7796bbc57751374539a7be3f0bd3e307b077050dc33089ce3e9cee71ffa6c88e78a05a18b463bca99d3cd145839ce567064daff9355f7d64e26033474bc4d9d4015bdadbf79cf7de320147bba529c3b22139f5051a63407aa4d0a76ab033ce6c8550e5739315d3b512a764fafccaf71baa39d4c22c3f934e79e8a54c6e1fb055c7b27ce74b76260f7ca04855438e7999d33eab58fba6d8f405b1e871d879c17985d91df2d352d2ec40813647358dd796b44e32f47c37e821b28bf78aab72e9071b1933185c566ad2c30bfa9b7164ccc6560edafa0664f0a8727a9aaeb1c06b4dab37a56bd28727924e1337882bc3ffb9b6dd5bf0956a081cc3f5ebc06abd9157ea34672e43a9dda82a5c8fa7424d3e2d9f0ac1cca227e2033e320ac4d4478f45b72fae7ad2c76280ef9d5fa6ffd336fdbff1308c4136cee966b3d14dec8be672c20749ed1f3d0cdf07da36a184d986b32d1539fcf9b6a8eeb511af04689f4f7ae6f9c88fc63759277d7e68a26ff25ffcf8f68601d657ed3173edfb8fc9bc18fda4dffeb5bb3bcd73c643faaf47d67f8618a07dfa26829ed06ad51509b628ff46fdb9666d32b50db9dc2c41babb3cbbcb642f9a4c4ba9fac8b4a20ef58474efe29bf3ab6f15edde1e5c76270562d48ee0dd9794123a4919a3327c5e2d076ec378c07b3d692ced8b935fdb98e5db963e7add9f82eb3554b2474a0a483208ce6b1ebbe4b7f7f435c0d63154b273c6db248637d8225d526e019954a55d9be72029d5482552963e6d5320cdd4abb1c975f06cecf090940249efd3a22b639a9eb818393fce6c96c6709025803a73bc9136167355be56f4a67359f66a8388dcdfba02bd8991b3d9f34f1ff0c3844cfadc46a701b6c683a26e3180bd90dadb1b04b9dff57c843c3675424e78f79f6a3e13e7bf492ec00b6e70d9cd50b23930c3e7dc270e9692b8a7e9de82f3a6264f1f120eb19c6301368082f0249ca507edf6f8b1868c6fa15f352cb733e1a41c188067e0a93d0d29e0a590f9f14b6125b071ffabf8bdb5bf7f493a8733d7fdf91524c7aa2aa717d42d56aba9c1f752e23b39c7e7c60e5b8df2da10ecd139d9675c25c0b3381813d7db8be74bfbe92e58205192644a014515ea2b8fa93959ab6d59e335dff4c51ebabae4c09e5b628a8356ced8a6df74068a6841782cc284e54199452ea0bfe7e735cc2577b389a0bf11e18b71a0bd09fc5c19b8f200f783a744eb09f3559d7cb81abca4fe27f733590d4ba8b8c17dcdb37c583fa5c685a92c5831214d9ac277bfe8fcc53fe1a10f389f26b9f83f1f3ccba52d2c40aeab28ff928b737e055c0c7ca1dcf1a5022c3f7674d47f06af6ee4fa20831eae556a08358afa0bbdf9021d5dfe932c09f29ab6a9862b3a7d8407826f5323a9d69500c8a9646ac9d16911d3da3dc9535fdcb5126d4da3fb4324de538e151c59a55c09ddcd346a3d50e2ed8037ac895e929f704bc71e3c55fc635963edc81f748163135d99549cb8b870324c74cea2b247f2c2d4df68f2955c8f9eb5c58a365ca387c094e8a3cdf68def1b6dbf1948037e203d508199d4ee74c45a348a21a7f58a5be38bc62fa00e2a572801068aac2bfc765385e379a46063dcd5a26947de3b3dc3cda451472b1a8f397ad120c8789ea33458e7c286c347703ecded99cde661dbe43efefd0dbec784b316deb284fef176e5e7122b35cb6663ce02c68f923af597b195ea1c9fc162ef344a235aeee9739b83dba3bf3c1a574fdae89baff821e1baa790d3a51b909bd2553a6b69b154903a0745de66e7549691fa7ff2761e04a380ba163b5a3ff65c0cc73b71a7f2fbe8381bb42fb3a400eb3d811d714209a7beca8a134029078f733cfe42e39e4a2fd31a26cd727e406b9a00c0faa7b1320e3b201882c7c0591fb3b491e891595f5cb8c28cd4ae1394e4957cebc8fd0396aedd5e265ead1092344787d252e9da5c06ed1521621701c58c7d5429786b6591e0da6f9984ff23bbd185cb73d531c6024f9275f862dfd25a94d76303cae5b64af0f27e7fe9f2e69adb613faa7216e25ae438758aa5187985d6b622cbf2eae83ab1ed6183a0e8f8b8e3a50ac8b1238d47849c13079a1a6aefecd5f31819dbb42e7dd0a3654655cba499ca0b51dd23290b1771f5b079698d1f81b31a7d39382a47b5b1485e63e2ed5a06854670da2ff9079afd4d3c6dc4bdced3dcd9b5ad25e69ba2c466f82795e962dde63cf0b6e6afa5052ff677e4366e4c3ca06e758efab41f1ce210b341556f23dbad356ccc58accbff750599077a1aac1bba89411bffa09dba7e5a097451e982bd89ff822a39995e1f6776bebb769b2aeb2525efa04b6f3f222b6ddf14bee5a7fd8be19c751348e07c3b67b02ab787e197cc82fd219a4605ce541a2fa5cc26ed622c0948445e18c1fa2388ff294e3128b22bcb1ea0b7a1bdda83cc9426d001250ee079e46cb05065c11368a46275ad62b659cd531f180a5aaabd6b2a219743387edf5ea2973816a43c8b3b95a78de180e36fd93e3f634615500edec48971f3d5105caeb8dea6da0ff527b0c45150059bd7f2f43a584e42ff5563e97042bae14e39b4aca34b5c7f9e4027fa7691e0e2307c56bc3886a0058a7a738ed1dd8c917f5bce6008eb59223f174858efaeb9818ce1783352b982e63c991bdf95924ea93f3d6a9b0fd6ae1db034fcbcba007eff7a42ffc983a58faa422c6c3fc00929d192cc5865231c99c8653d9c61dba49495a7c36feb7fb6700abc83d5ce8ea466c680560ea817175154b1017ba374f515c4635c35a896e05176ea81727eb7ef17651010acee1d0b98d5528bb0f4d2cda5945c069d9a7d4149ffb2fb300527cff9aa918a98de63b72260294feb913ad8a3f1d1f355e6bdcfe9927558f85c99d8d59fde3135fd35ee299ad57882706c30ad59d80c788e62f7d6c7fa79def9bb05315c1d23eab077145c0dad3e6cc0c9784d65ff261fb1c885a798309d70a6093eb44ad4c336fcfae6e349a8d4727f1b57af86b00a7f34211663233cd4461e2f2093888663cfbdc8e8c1ec3dd976b7b7eb92ebc890ded44f10076f012ef9b72f13c97e3595814f4a6f9722be85fdae2942ca6ad1b9f632136b94391b794846182566136835cd7a86605dbe864711fc58bfb60b2d5a27176b19caa7517d5e2554eadc0540abc782b843fcc6b536b5b2c4c59d723175898f48b72ce652a90d35064e11342d036f333abe47adeb1453b5e0e8d8d1f9e3b43fb91bdbcb5cca00fcd709adb79507e3bbcf82dd77a5cf6b239ad4578a48d22d0b7d0a7cd215049fd534583bd3f2b695aa37b043355e17baa60f8aede354258d8624d47b8cdac7536eb4ad5ccba5e350e16fd4cc1a6449c661ea36816136d497f07251ba4af83c9a3f46691f9e828f751f41a8c92655e02f84a30d867425e3b9e89fa8e85212bf45708b16f591547d95a6b121888a69202e469f564110ca6c59855d357b42d52b699bd376d2251a53fa3497bfc0d071db5f3f70daf864fc4f1fc318a76b171f28bedcc5eb596adf543f9b4b180d1d424efc3bbad13866fa36f960935ccdb722a54ea455385e95ee543f9b931a443cf0991cc47d28e7a41d3c5dc7bf121c8f5cdbccda51fb63d7c0930ff25d5e53ffe7cfe74732fc3db472d990d50bdd72a535085c963d965a92f88f08ccb62cb112e71060919f2ec52213169183a29d6808a1b4d4fdd64e19d052d771fdce04e82ab975b1741dba02ae45fcced192408709dc2a8407df3bfc10b7142d41c471453a6b7aec81611660c966d540f1bee1a527126defcdcb08ad1ba0fcf9b756b57665d23229baabdfe0b64932d5ac4cee7e4e1b46a5d433d50accb00ea50891202ea543b2b119c3d41532e6a727d51da77bab87af7bf3a48d36d9882ed3c74830c8d16370d38597f8728090868763b584475d5b930998e2dc914f85899486f677fa5c5f5e4b7eabe827b0bed3735da75a8611c71269adc254f438fbfd6e4d097df38623aed94b7bf74c48c63a3928b7081e4f261c5c0fc30d9c3a11760f4e45f826dab7a87e29db8aaff5a32ac6e75ec6541a98836bb3a966eecd3c5010b9779ce902bc9e17e1efc759d8a189d063c823e9bab94bb635c1b8018f30f577010764f63fa2d27e7f79bdd225b9092dd356e7f87768546eb3768b7601568d865344b0e19ebc28985079896f20209515a7fa46d607288f5564ae7b6befdedade7b8cbe5b0e7e7b7bb38bf6dfbb7c4deedc09c77d62607a96a8e949cc9a29ecdf662b761f1f937c452a6b39d863835fe7209a9b6ccad75ea77ae765749ceb6b59a5cc499b8fa131d08a7d71efe92d8e689669ead408c59df3b447cb157e81be35c479ffdf81ad55242108c2d6ff6cc5a786739024e6273e78916135154b69751ed8b39eb64fd8ef310d536d4f490abdfb0562533d4fd38ef406120b6efba276ba578c2fc521bd9f74ddcfe9f2dee45176780be277d5fb0b2d0184a9f6432f2146fdf621e295943e8bb78617f430b8b8c5ee228c5a2531d5c404cf58c3a91fb2df08e59d1ab61f8e8491e84e3b621542ffeef01dabb5495346bad67c6025faa76fd07e02e98ed76ff0ea3a1f303b2086e1fbc7dfe8006a529259dbf41100798b5965e37b9558eebf0d550e52cb1284f01a832232335b81627fe08c88f185afcc11c17f1522bb53247247fb48e55c7b589e85889b139defc7af51de408a3d20431272af190fb59405da390a443def0abc1e214baaebb03bd3198ee8cd2629e083a2c330d0e97accf73fc3fcf618e41f5fa01363bdc0fac3e506e72aea557ff2dbcdb5e0d88e42c5edfe031fc19b9c3ea27485714de857e2f1ea2e8fb9c3b40d034abad33dcbb021dceab1fc246f323f0f1c07cae2b13552313fb3edab34608bcb13e380a4d5a8aacd5354e439d4789de35d53bdb43b8e0cd0f837e34cb0c91c2a4c85a1aa5be49a1d158d10765c6a04eda203983f4b1d0f14d8062a5234f058fe91b706c30d19eaa7014928787e0f11179202b32b553bca2e705e058f98c307a3197bf64d5013c0c03b18bbe322d345c86406b993f3a4bb09859054a7d6a63607295b04d7f94a1d41d3e7a92b1fa92d175c6bb9f3aad76e167f3b35244d977e4d399a604252ea3c8e2e23ca8c113ce9d9a96be7b1a58fc0668eeff946816756bb8daf5addff43c524deac19e2098fb7e3524eb3f8b2f7e2a8e8c1f31d4f832755d9e53d765efe2fec334bc0372d47f04c4f5634077063b18422a9f32e495dbeba9eb686edd5a895296ba4649c520ea507d1be13379465d11c4a820d7cc8e600b6afc36c4fc7776dfe8b039a2eba35e2bba66f77c99f1b45c1af2aabba85b04363724ac9866e15b86b01263009d1404ff6cbbf7540af6796a769380da96f8d86c4e4a7e34abfbefafa200547a51ea15a3b07257119fa7f7a1eb62a5b7abb83760b5fb8780e2fe1b3c873674e516dea023689d5966e71f2d11d63e3270d87dd579c6835fa553788b17e90c5ccaf92c158ff3678cb2892d1dd6eed3c717e8f0ff127c950a9799bb9d3ed3958f7f4e86e9e88bf509e38d07e4aad50567b5323a23a5b094827f5849c3a836db8ef777bec0035efed5020d6c88df9cff30d4a81e3b41c09904f3e4ea38e4747066348016616092ad4cf963fcf55ccc5109273d74926af203af23fd88137ca2c03179f4fd8ec93f3beb272670c05573fc98a1757a632d6e439f74562ee7b56e80e5a21a0e9492352c88eee530953a530b8f10657142d2c0f0258a5e33ea43f5ff78efa9ffc2fced836738e4b0c6c2388dae4ed64518a892582619af7efdc3595e5763b3236297ba3765d5a8175792785bb6879dde302f81f0c817d648944e3d85c02c7fb635e2eea81924e82a5d64311003723946fd509575a2ca54036faa70b87fcc6daf2ce8de8711531f71e04804ffa61d1ca50a3ba8c7d77587272aa36b57d4f3e6d0a78f3558687f11e84b237d3a8ff993894c3ee290252773d848347f5834d0158057b8bb78ba287fef7d8c37768307734ccfa1097d104ae38ca6ff40fbcabe8f60d326ab9b68436afaa361abd9e0c635dabea8bcaaffbd2766871cc005245743a496e299b4ae2af2af9ec4c7107f699615fc0d1cb2e7de9814cf7e797e2aa5ff3a2dcd0f7d22fea8175f162b2e6ff3dc188bd7d96d360a2757f7e88a46de6c267494ab332b84eee26277fbafa07dc114e1d6205e59d96e7b3e069830dafd5b1809b9bc049e3d35d4cd9ad14ce6e00a9d9c0a67072fb86d8567a72ea95a362c35b95b0dd7b9fcbd78137da1f8346704b76a35d3fd7aa238b344c1a2dec23003e403d6d35ef6def27f899d7d6a4509f5eec83a76a8e3888c8c4c11df8a4cf0b066a68cefe9694b87ae3c9def13b51724ba1f6f5c8c11848dcffec18b079dc9d2b969227c6dd98432bfe35fed32af12ffea10bc8a47bfe059b1648986b551db0382db92c958b8d95f901ec55439318e43257e522e1913c65198874dac19c64acc0f7462637d5ec83cd74c57473e872bdcae64cdaf7b945ad222c49d206af330eb9ddd88e90c411c758eb932d236bdf3d4defb7ca5101b778a8c332b201c681517f1c7ae655c412233ad7e11212c83a238773ca463b87cb7838ac5b25a4982dcc6ad5d1f69acc67dd0911396ed96bf2b19ef9e1a23a30e998f26fc3de5ef197fcff95b3e66b019fb1b73e7f7c484144f5cd672cd483864a3351b6dd0e89bfaf31efb54e71252de3f4a5ca39ab8156132edd598b1ee771bbec99b22000d2a8c070c4d3df2a314e3251aac0afcd00c619720e2f67686b3876bbcb2682b9b182f90d6b1490517d567fed0c66675378f61f25c8f3fde101d4670e965400f967dd516c015297b289f2086fa97c55b24173b759677378fd1b133e81dc8bb895be4a9b3eec9f3f22ddd94e12d0937ae11febb34bf4f84c8b3f33729df31adfc371778d813b7cb248abe8eca6468e1ee09a7f94db567fa370e8a43b26fe9fa35f7883e5cfd252dabc1dd93f9cec5b2a51f1bc72bc7131a49b052059a64c2e2abea0acc2c2b3a5efa3b6dae779fb73b58bfb90a4b32b9af549d32b90d9f67da5df0d0f2360db2e9b37260e575809a9611fbbee0fb1a6f9f6a39dd82788724e8739e823ca86fb28a991975c9b3a3c1742ed4aeaa59d9d24e9bc83a0f5ad960de3d6f6dc79ffd4536e3481ef597411a77f333775848dd4b9ac60fe573dfc9c76bc59e943e74c278489e14e4a058067ce4ad2afcdde75a60cb145e4abcbfd8d0e757ca945acab3507e9fbc65f98f828492284266d3fc6d65d5a504cca0fd3a48f7ae640d63eeb80be156c4d48428e2236032edb834320da6d0cb753d36a5c42e034f0d4018fe34ec42b91cf87c0726d607fa05ac5de0e26863a899aec5fc83f4064914cd5a2e644167aa05d1923a638004374e85d619d7b0fdecf1b006854ac760e36a7b0130fb100605561caa5e5bdeb377700e97d74baff3f4db663bb78f834e4b994e815e5be628731aa14e999c7d6967aa390f795963214d7ba2727d5f4ee66153f6e17d0ffd0bdecb9ea5d2e89d46d9243b6e964dae81a345a86590d6c7fd3938744d90926a3b1e34e3de018a9d4a99396439f1e1a8ab05a8048fb79a821217340051252060677dd69770ab5cb48c8b89d85217264931b40fec75cf1b3b954f3e596fcac74c78995b6fdaeaa48e981c56b7059a59934b491b5c599baec2cf941feb773acda5f9eda8f51955bbec95fec971c9ba6f3fa3e8fdec9deb304905175d1fb7f28098215159f8c448273e3df2a96ef07685e5ed5694bdcd5e3ffc579b0c88a285baca1f597f655039bfd060c5b27bd82675ea44f104c936860356b8e4ff86cf52d4d7f4d2ea5a3ee461f122e4cab006a30f67c78af100b9bee6831b554c7c2025ce314a957436f4b1a0345ed264340cf9d594d3b9462f9b9aa77a31358fcb5eed305fad829a1b01eeef5fccdf67597aae64ed5133824e32dff421a117271ba2fa2867d459769b308b9d0d95d1a43c104e18efacca32cdcb2354860ec4b7e1d581a5d3318a9ae46189f14582408c6accad8dd48ae33c31802d1d71e58c68d1d03e9012a6c9a70d3ead56c0274c70998e2195171a2c19cd212b354ddd9b4a6d753eadd5109c7018dc658ed206779cae5eadbb27a05983167f550b5996728de3c4cb89f6fb61136c57ae211eb971f367bed1754f6cb60aad2db9a893dd95b5dd1b013418e65ae29cff55283d9aac39337a2173bfd3f1e8aecc40f2f1a3eb5a8a7057028db9f63dab04ba257e34fe0983d24fb3f0b249325cb2da8c8d5159d172b3cc141a8f2de8f48435d8cb822ba1ca3265e6c056e4be7a7d8da67e50566fb50c3eaa315dd9a21a46596beabb224f158d25e3c11deb1f0c16866d904d35d3b01929a683b4a7f8f0b7c910b8a99c65f3fc3f4b58a9ab4ce786601e6e7d489a7619a09c4bc71a7e884a1297089b28883289d42c41839a813451f5a21ac9c28435935764a77d355fe71bc8379b22458f55154567a2a50777e773ff3d7668342c16677041e2a64c1611c519116eb41eb8438ea275f834941ce4279e7d86373aeb8fecceb1a1066c98be4b7b68ba9c2fe5bb80ac78e158e7af324c2dccc237ef0aeb30e95a8d98432dd9bb43d76fdabce333d12816814be869f58f8acce47159b9335947374563855c9fc0151dc04b3e33bfa49deda9ea13ab3c1f098553e56a70f8586ce4f9bfd49c28f93da9d25145f1ba09c17f455c2b55105b5d1ce0dedb93266e787eb7b7ee2281dfd5a0456e734b2678d914a66cdd525910245ca3f2109cdb754d6dc64d6a1dd8b45e742e51e4df12a7580ab3435710a9376f5533a17a17bb48c2437d9e3cb16c932f9602462213635887394192b9c67568de4a15738b7c05f07efa32545314e4ae5edfb6c0ffbda1f047e1b24e6e08bdec4e5dea30d7e30828a2e5bed367070e319422d05410f5a2e8594fdbbd4b824d369829cfff706a394e8d55c68460b2d2a9d1d141af01439ba094d1b255283c7b3ea95a63d0052b8b4cdfa5cb423df1af4a6d48e6c613b158e3a63cb0c0ce9c3596162caaa456a0fe444a5b4f255bc957e67af700ea30af86617a5ee6b3f6ff00e4177a04980b0473b372162451b2944d5e56c346224db351fefcfbcad9f7f5f3ef736c34a85effbea36caffd3e9eb1fa4b953156d5acb89438712991186c9c22ab759696a89b29633cb188353413cbd6f937c34ca521f3b5be4ab77423f3ad307eb4cf48e1ea79a05b4df405c5d84bbb107cbf535d9778afbdd107e700fe5a3b030d93295b1a3e1ad9758e4db180e1f0ce6b8459c1c2824f7d877891ddaf483124b916b4d3385f71e6e87e2254446dc98d5955afe5b4adf5d17d7a33fee6c84e0322b91dfa1c33f4235b9af02146fb6da9d3dd958368fab4bf17df7592ed5317e9e6fc2905609cffc1da3d0c2ef97f7c552ee14dcfa77cffcd12b96f5bae7077015d834a37d3d19d577193a9679135ca09899e9005e336c54fe378f7fb0face59f347446ef992915efe9efefb4ab3d4f34237e06c25c570220f4b44aecbc1ff699cfa7f4381e2165dc9c34f190bd7ab210782badd9b34d6b86bcd84d91c97ecdfe24b7d9b635cf41845b50a7a0ee051b4da835b8f315386353ce2290aec5777214869633cb754de0c21aaebb4c1a6555a124cedefb678a147c41719c033da95a44b5282a2930e8fbdba60a36705f6a7bed70b3de32e2a69a00acf637d90dc8063619a34b85bb9a6354da4f9f3b3aea777133e5c1732a6dc86815c35dd0a85c61e179b9e30fad7a25944ffa953bc939d130d9477663b6a1e7e8b4a202469edc402607f401193051326f1053c3391e629b0fcd7083a643307dac41793fad871a82e5d8c63b8a06b324b3fb562bdb9476f1a4df12378a18803ece8d9755a9853a5bd0e46f905dedb58cadd8ec7156d77be83f6b50a072a31a9a4a87d5f0735a463b8fdf7d24a442f4456708041ee1d718db35c1af29127cc033b6539153ffbd8a5e862b94a11d81a7e98c572d6ee5844fa6ab160ba9c3fa36d6f2d6e9fa1a17d7376493491dacd6165e07c982f9e4d49e7e98b76c76c4cdfe3c3be2bfbcdfcf599ffb3fb8dfd3cf97d55b9bb572b7ef5d65eb5cdf9ead138de2bee70b681cc2efcd3557916b2e6ea6d7557bfaa3fee66dd7fea3cb281eb1c83aaea3e4b8673213491f7201ba01312ecc85ee6d45d499dc07131ada1c95234bd5787d2e97a1824995b3cccb3dedca8c46ddc0efad746aff03195c35397347076694c3e7ff500e9f87733e917a16f63defaa5ddc23164748da0f13e5696b654a6100eaae2a2d72792ad797f650895666c17dfb3d47ec478d6c52dcadba4862f0abcc9196f853ad4928fce2d491eeb5f451dc7c4d716cf8b53260fe68c72154790164eff37fc42378a777996d0a9c75d9f617377f8e2ab7b0d44b4af92ffeb8bc30d072bbbcf35275b97aa6135a574ceeebd52050130acaa7fbf4deaa9cfd7e4fd91dcb7197aed200a3a569eb59136fdbbea1e9b58b344fc9e2ec0acd73be458ee655f8a43c57ca6ee9620ac5c6dca711179175871ddeef5837487d2bb86b2651125b364a0cf69ffd07b8d75fb65da7823c5abdf92de47355286b67c857ff3f827cd1f3ff10f7e243bfa536415d7ab3ff8f1070ce3e3bff16010b16012bffd710b0465296a2d3db085862cbbffe3bf49b93f4fdf5ff27e48b3acb8a5df67f857871f5d71f62ded0548fbc5c6bd36841f25777af31b45c93f77a167183069865ff162e36b6fe8c664c82469f11319ad350b3d7be998dc5a56feba8de54757f35e68453c5728d8ae038c82bc75dab65f2caf1718e7de4337d20af5c5c44f2d71c973faa9da9e9182c73ee0b6e3d34c32ad847aa7f9fa2a8dcd13c3746dca217f2a71d9379e7dff380d36e7d2c8235d96d8dc3ce4490634aa59dcd0fac2a804733b9c7289a0b23548f0db7caf2e1b53b5f274c579ccec9f174078454bffe76ac24450775337b90dc001f904db7c6735633da9046d546b8c831274256aaa659b56a4c1916496d99c37eede28ec59231f53e8a169a3e843b5b66d44b6d0993f2b2357e3def20c7baa2acb901b755162a51acdc42aaa7e3ecb6df72327dd275f34f8f788e8b82b85de444f4c4ea2a6b6c3500db5ee5613b16bba4bbc562f79fcfa6939d0dc8c09c505bd40c21b3b4a95630f19ef5c2599c8a3b078159cb1e8eecc3304842fbcfb1ca3ba0105791e975c969ad2cd640ac721812fa819a60e287606529aef59c1fa96baf089749c8e9563960cd7ab7a4673a3b3b10623a7beee26168fb1b96bd7b636f500e715b37424f41488c436c552c684009860ccd7f2d5fed121fcc75b736bee37d71e4aab714f0e9f95cb4b28e713fa3e8d852256941d3f13ea8d1f0743a4f5e6b9dd2109e3c08bacd0d84d4f65b4d5eded9fb2b8b4cc79975c216a5d23ea0a76367866f7617e92e37badb04a89e55768d4c9ed24a78a4ea04666ee00a52460ff98142ff296a76eb77370f51a3bbbe17c1bbd9cdf730d8ddff47dd9b75b7a9346dc33f485e4bf3b4be234032961547711cc771ceb2135b488040f3f0ebbf45d555ddd54876927ddfeff33eef3ed80e089a1e6baeab3cbebce54bf602dccfbf5dd9f07267eccf3d28ee4f64ae0e4dcdd4ea93db1590d4e9c4da384d7c71c4a9365b8e65fda25aa11be5cac08879cf39803b09a07d67670520ab3180beb72553c3f00c4fddc4d4939d4aea80228562d550706beeeb92a4943b9866315a8b6010d445f1b3150e52e7dd28eae291580768a455dff85847cd7fe89ec116650ce31e3d51f7530063e5520590238a11afb7cc7e1fc62dc965759e419e16162b477baefad40a255c632d87891a185f98f254c3363d0a3e2017345c8d24f541229abba5fa306df59d6729f768d881a9cdbaeba3b4c193f9c184cec5c87d75e6bcf2f56ae4051bf611d462a4f8bebf2c431bdcae22f6c5fead221861243ef42c109b18f1c58f59a36519cd16dcb9f9e2a6e8c94859dc2abe2dbdb013427dbab18ac006402edb0a55c55b0f4ec8b3135cbf32ce27ab3f5b859326a157487ecc3312b7c7071e4719253bc175c7cde87870335312ce47a923b2cf24fad06102951658c41ac2d0f7c0f586951db04627170d42adc0c8f3b694fff9550a69e1591cbe8704181178d814db90e0d2ed9cd2836b7eb56af9c62f2748f0442b92fa32cdfb130d642c8545da0ec672cc50e17725a4f1e72da077dddd77e4f201e149f94e04217e688201b08c9bd98d99078db9faef9727f4820507c14d7138dc997f7fe71b89a98e4ce0da12c707a92533a4497517b7bf9ba2e27addbdb1b4fba062742996b6944bb15365998beb8b871bd33b8a9178d77ee75caf7500458a17ba9db75447c997e1e505f2604bcd8c06114c9c4ad8186e14d1ab4385d42cee3e16109600bd78afd7824947e4067b5b4a5b2075630ad36fa9b4058703e4c10124e5c85551c204952d8e58d446eb221f8945f4fe1fe7233303b2f3bf8f8f34f934f5624901fffdcad1c97616cc321094e1e12244152cd061cffe572c10fd4893f9f9f252f17c4bf985932a355c654a264a8e8075537008666479e9a6a652618f81a6a468942b19a5a95b54e7e214b411a13571f2047444a1c34dc5f52a43a903d3593ced203abb39603afea1d376c894410278360683ee1fc6ff00483af855c5d77566a2de19020d8e73079617febb170dbc31d2c7e9e4af815235fcddd92466c39a660b6618de848d8a8f822c2700cf4b29970dfac69782a177fc88acc6ead1f97d0d8d663bb98a032fd8fcc2fd1dea417c445d95c321b0e11661cc426715b556e09896fa59651e9d0283a0332ac9ed4d149eac321e9489f24525d0c6078ede3c4ae63a3c4b6eed8cb5aad7195a5c5a00bd489bf972a4fa9f038984b7586bcf692c519d9d7a4781fce5a9a81e9963a5a8a2d6af39fb77c30bb29fc8cc94be8e92b7703bae636e0cabb070cf02f0275024193a07e321543939a9f37869f5d613b708cf867b31fbe816d0997f94db59e9fad263a651b4b69e5c757ccfebd063c1e905b7b71fd05a84ca369a794968b414777dfb61a20c6d37a5ba8b4aa7a5d0fd05d091e5c8e2549f70aa654360fb5481647af9802fc620ca6ac12549e5fdce2e96b005de7bde837cb34c8f5214f34d9cb2efd9a73f20526dc0f75410312d56d475936dd0490611740e83c9f1d63c4f61b25bfef445fab6e7208ac83fa7733fa91c32b1e59eff7f92b63d7ade6cd007d22f4d7d141c8016aaa85cb107d301edb9f9cbc25033a74cd5e9a322625e1cfc0f11b11592824ab4a644bf6403c688caf90dfd8a2ed244977ea1eb1ba65f7134faafd12f101df575a65f5d4070548e7f4cbf400a5198787bf70efdda4fb042c2c4f8d5e547d484945a611fe536d32b7b8dca6184501e9c5e318aed9dfe98a01e9a8fe12b7ba1737d301afbb69a45f3f6077c7c7e892894c89dd9a74934701f267dc97d782fe4a6bbe36d0ac07831a9361105026c9ea3599bc32551ecbc272c2ef40fff61e364d1fe33422d68d03500f8bd4fa885cfcbd31709f5a1d8f941f25a126ffe1f9a3bc3370c2e620306c0ea6f34d2a1d19b8236c700a176ecbb6f9634f577b45921795716be44f899812f299e5b8016c9fab1de0ff2d5009ba8ef0d6530a3dd82559d2be6a142f9c3261216ba4f814717850077561042122825a190201f605c352324b34f0f1b6bb6a078c306cd7e32ca1ba5833cd45e58dabf80f492d910b3495a838e75d1d6cbdf14fdd07ff74d8e29c360388e715441b68aabf1aa8774c3e5fcc9d91ea83179f0bb657912f3854691e9a0b26c757a96637eee12a5eb0e1f8613f3c9ddde5188f1a3ecd3e29a5d7b72e7d842016ad881e4ba831a9b6e7bf895d8df6856e1479a0eced5ac3bba7af182fce56ae44db26f15ca9ab9e3c928feffe9f46db5d1312b2b75466b912fb5aa822450e103abee1b01e39580799f384e4b46d43e30c2c542d141c82f6a40e708651560250132287e5c525c45f54e52a6d5e9cc6dcdae9f14112ba0c4842d32f4bceb629b8ccba6b912068a55504264681b33833efec640e21c8d525b051126dfdf83a49eae138a36a024f8f10681f0dbe416ba4477aa30bc97b2e37945a981eb8ce7e6feccaece10c04d3a2c52c2adf85ab1705243167e4243d9020ad80d3daf8da000c979c58b0fd24389baa1d58b16ca9b47a60941228539959cc194fe8a309762ddef043fbb3fbbb634e57242a89c3d8f8da125e827315cc76bdf986b4d831a7557acbc5d4ef08e74622117a60b9a3f289cf79f26f29f63292ba10cca4315b6648aef04f357416b42545167ce71c4d25409a4abb902a7f97869300f6c34cc48d548029759ad977ce856c051d54040cfe539cb404b1da79c4dbc711d3370ab1a609480c2098ac384549caf4e21e99855a1c7469398cfd30250ccf032879e570ddcb469d948b9e480483977f44e94292288537f958c7ebb91ee3def31dfa9259763f9e7bbe8c1f31e65d7803fb10a210ec9e98ab7d6fef3e59dd565808326341d47334c539a9c1e395f36d706a213f6be36ac3c2d2294e3ce8b1eb0098c9af15e9297b1fde2de4802f089aa96f2c1dfd8621814124f3382f04d0692542fd55a2e326d396ab20373f0cf3200ddf9460c16aff82ec5287c4dbe95f6d19de73dec2d187e8f186b77f8dfa4437232df20142addc5128a104944bcebc0a0fed7d22f2f23dc8d76f8d7f4eb6c92cae40b187f332505eec0c4b2febfd9862ea563a8e795fffb9df49660293cced99a41fd1ba72dc68213ade57a4471c163b16107cbe8fc6ed9a395e88aa1f010e4330d0eba04468ab429e1ffea36d926f057a64cfb2143f1b0edbb8251fce7ae768a8073fdbc86a893b90ccadbd98f85b0379bb13d5f3e18571400d8becf7a042239a31a1fbe1df0f5f76bcebe13e89146aca0e7786524dfaf5305180b3b33a5bfd3ecc6f9ba4827c7b1edc489d5dd5976a3fb3287cd6ff6e8744914b1188590a56b42a6d3ecc676718136b2ecc6e9ac78c1d3d98de974e805a77fe07f44fef15b02b024e948f80c24dc045d41a8496fc19eb7038ea7e87c98d42532e3169b4b713ae0e9f1c121cdec1326ebd5c6472786469a7ef4bca5dfe76a6d2c4f7ae69fbae6ad35cab8505446ceb55237ef7fc422fe1477a122ae2ef1330144a1f706eca9095da3e44f44434821f90a1cbf72aee36f0a438ba262bf398dc4f5779e571250acb1464ba281608d762f608dc66758a388ed8076483faa9a624a41e85c461c9522c91d208eca573b401c15b2ad5abe14af695e2b418eeae6ce07254f9f24117b88617d6ab01222cac8f0bac42995865770ca2e9824d3f5207ab584f334b77b685c6c9a256dd9af709bbbeaf7a3304b3b7b4cf2665c56cbadf19fcd468c44c24b8b90d2fc2bbd0c7e119f97c286b44581cbb7c2ffb8b2fb33f07bbe3a9bb8ccd1f9736b279d414438694faee98596dac6d68bfd55bfbf2f25310365e5d9a4398fb9d275f1cfb92f55d1f90cf8173afd78d66933a345cfe538a2241495d181c0218c764e93bb3d9bdcd04d47288b392c833a4d89acd185407159f648f4ce4403c7eeedf9c4cd5415d73f98b682b8b5aecf9b31690bc46c26de85f70902b8ee8a3b761e4b127015619bad4b4111333706c6528ce98ca193f57299e0fceed1310a22e287636bfe616b24049f2d92ed77fcf70e6fa42749cf4c7a0a2553053daba01cdb014aa02c51453e09bd738056d54ee2daf9c84e41e4711e88aa058df07be4daabf88d1fe6a3485190e0fc926e738783ec4ab62a5d4388ad5057870497f69d9cd4f4e75fa8aa65cdcdee8ab6b32bc6886cef018e2beabd9160d2eb5ab8448e3aef76b5f8dbea2a585704f0dd9648e5fc5bd92a2565e8736ba42853430776da50c36fee471d91cf19b2439e9edf7adf74fab02e77fabcd82fc8fa7362b5e137483877fa6451f34a932adf6f632a9df1946f5623df8e4bd7fc03190faa9ca99db12414ce7b7f270cf21261432fdfa82d61041bf5af4bbfda7befff6a26a4fc35daaa073079cebd125ffbfaa8eb35b9afecf90b5247a0d5e468f43630621b4dfa6e586d38c8f5bd13898bcfb385c017f4018cb2c7a41f507caa37677d427e976bcb77a3ee6d79c3c42059a9447d756eb580a99c5b0fa5311d195c5d6a1b48266d1df54b2e953848e603cd6e25e0c0f62982f380ba5c0a8810cb6cb7143037544a02820f21e9bc11212ad766706e1ec562a9a00f6dd74ace256aa9bf29677a0487a96ff60ccb0a735f923fe2cb951d9ed32834736f2404e82ca5cf56713eca33485ec481c3cee162e548fec8174f6b07e17ad1dc0926e8e1f68195bc87ba5297c76605f5bf08c81b38c7082b5770e4f619f75f12beabf90434a5158a1b302168a042c5968b852478489534bab33dda42d46674cbf37e5cea51f1a98bef999b6f0ceaf72f5202e2f98bc502feee19c2c344319564014f085c763341a1a30448bcbb961200b26d4b22dc83c5d19b2e48c3687271aa5ec229010714f73c46bcc50e5bffefbf529c23898f8eb27fd9ed8682c8d9f76867effcce860fc76e6543b9c96cd7b1da0e97911a7a4eb9a8438712195ef6a77240ac38c414c80e3d50701a647c72b8a63cc8072bcd588a4db29176e673bbc5042c5172484a59593b9abccacbfad6fbf42b1a89391e355c9d46661423a907b182d77a599ac4bd0e2f15bfba3aad55b8449193b7c53edbb9fb0c0106eee2cebaa1f36e9c8dcc602e1c48f52fa30d48e80e663dcdfdab472fa8bf9e6a10e7371c927cfac1b1fa4b471e7203b29b5a2467fb7439025e6c32db67f22e3c4b5006933918b8b6fb1b80e168fced5e972b17462736bf1d819b754288158a1385f5c8c477cb63a164b09d561cef056d4ce28e6777bc1128f6afc528fc1417b4f5e76eb1a2fa3512b8d93c50ab5fb328c4bb6b9322b315c7a179f22f7da7995bff65d0608e2df587b728f2fbceaba1cdc71b6930f593135250593348cd0906c263c6551c69035721b5ce50c26ec9a6cc15038eceb1198a5f8bb55f75dcbe3432c12c5a4164640c3499d6d9fcd6e166f0c9e0ae841874102733d7266e64b218ce8a67e5cb3dd09dc3ca24e8849ef7a85225fe882d06fdd7266a132f7505bef7996450e6919ddce5917ba6126b701330c9ae3cf5e9dd0f9e71ccdff5f08fd8a734228c9b95a2dfb4fcfb56083be237ad9c31d63f9972e1b21bc46242b2e0a9ef80cc25ee8fe623c517e523351cfbf73830e21bf7f866d76db6f43044a4aca11c0fc2adfb384ec599a3281a5c3714ff6bab14c21391ef3b0e75c8477fdf7bcdd9732a39166c08164e4d96c82bcdff68b2c8cca5e34053b03761fd4d95a684e06480a2d32d84ac485104250ae4bf988776fc922420957f81992f35898b0e439f4e99650a38c916a202c781a2ec2fdbf9725f5ad3da769a93424e3ef3a9df655da78b89e2d618e95f4a0883be2fa45671f1db4ea5306f39ea1846e630698d9c8e69d9a3fc0caf0a1e4c03cf4b03531299836a00b2fc9350e88acf745aa12b86749482267d4cb3921832bff0500b99c48b3ae82c28bd4c5ada51e55cdf965d9a75d007448f379d934498608bd7d2f6dda623e7dd35d8f7a6795976a1d8103e83272651cd210468f060e318d96f911702e7cb696c2dd7b645bc9ef6183fa5aace30e7e94c3cefeb1cee3408ebfce59f19ce40b531d2718bc272e7c96d4964c3ebcb7c40cbb8ae0cdf7b5fba82c77f28d14f896c798e689a1a7b3bbbd0e3b39e23b131c4c26e6d18a64a0a76c36427a865377c4f2d3766aeb23185bed2566be75a0a3241a5732c05166542e28e4b4e3b7d72fe46e3dfbd8208bd65fa989e788f94d4fe07adf69fe784ca679bb1e37294c069c934aeac5c751e8dc411db01a39c7f2eafc21dd5c9b7de253820df1687b9fa71c07f9ba8075d3225b80255575b275d582476a8edfcacca2183d182c15daff548f7129ca83ca83a2efad9f396be6c2249e85df58cb176646783bad09721592f0632044b98d532c54be65c206658a5b52fa8ca040d82e00271b90838c86ea6821c3924938b1024bee3a3110741836ba9a401172a901ae2a65045fd962b15f4e150e909325355ab0c3d440de4881ad0af539d0ba7e840b079ed5e7c9d373a7edace47c6b67ebfe29a992385b17fe6d23440f7fd192593300d7767763d94ac8d11820bbeceb98237b9de1f0af589cb1f7662a622dd986d083dbe7eeef35ffa9dbc3db8c6ef611fcf57e2d07462145806b348f8f92cc119e4bfc3358cb2152443ae703f4d38867c27c0cc64e63d8b0308c13ecaa6dfedafe2c6937b0a50369389c3fca4c2b54a8f1c29f5e50f4ccda15420d8f911ea12e068ed69f7adfcb313f622a7918e688dcee32a30e55fecd1931a7f3cd48acf7ecf2e2a1d483846651b145b6d2d4873587709e8c32293f6cb027a3670d6913943cfc41505fd97abd01ba4af3a762298bff2a257dc63e2f898113f5f1078fe54f1d16f6235cad817bb4eb00503cfe3fca4c3ed251485f008c785194148be733aad2e0de83025da9aaa2226871c5804ee442a862886e763ca4e8f76e9b0f3b92c150e392146b278e9c9f35ee4fa12184d9f73af266281393069fb08f3346bb8f7e9f2421c9ba10d14932ebca73ab27523851475d4935c03e59760d0b9def1ccdf5c0e92cb315102dd2d88da82ba21c180ecc087eb7c16dd5a17f31c761aa97cc1c61bf1a0f755af6551666b5f399ad0a6ed97e4c267ec130e9a2fe54e96912476f8bd1cb9580e17957e4bb95f1150ca4310b82989462b8fa68c5020f0f2757536c8572edfd503dea93a2b0c04dbba71a65eae07bc3171b7d5e2a265bce011be386df3dd4daca50238031b446b167e9f0b2122448698c857ef4a653210c97b3435b1316b072d96a455d68e1424dedc2a3a4f452b9f7128d5711f4bade58be77c371f19f920c5f9c6b613acc4b7ce77b3e704b3ff967c8c94176ebf46d50daaee0699bcb6e6239ec340dfaa84121a142c5eaeeebd41ed85c114827cea7b6f9205ae7154c270e4cf19ecc80327892790e4b6eb5b440feed099e35a402de8b2896cf44b83d573189e91fe5049a32a8e747839e202bc969e5e33598c301dc5f25390492904b61cbc7320618874b62f52d10b4d6e5bf4c8cfd31ed646b8c6cbf25769fb09b32b5e2772b32963d9e8e844536be1a0a6923db9277587888672b14b113c74558247a59182d192748ac4e6d263e5808393e22d0400fa061bb10bbfba75bae1442ec8942f3fe9237bdfa90df5a91ed66816397892b9dee84a4553860c8166a59ebbf3c277232f584d7d098e59a6a32b53fb7addc099ea9d39b5cf1147c55d5fe7ed3ead946428f2c7ecb50d79ab2298c9f57dbd6195f3de01b824fcb91ba8216c13189405b921c94ba1e775fd5ee3f6b7410023e28423188d0e7e845856fbdd6712e88a79da9c630d76a05c89d7f9cd8e3eea604b23aa4e81f22bc5ff2f09a452f81fc2654a7d89fcd5a7f37ec6be46dbfcc3097beb43e1c5b08ac5ed0539d811ae1347b8b685e26dd222f650d70d313261ae35361ec38eb347d4e40e020b8a10afd9f011ee8e859634f777bfa65d851fea381fce2bb1977329291c62a50d96255d3ddba9bd2b60bac5cd9182179d2dd88b54dd71d73b3d5303c234d7edddb80d925a8c0625bd87ba50cef941b42f727bb4d9d3bc66827d2324a70ad8a41b57a942c22e04fa9ac0d05fec23f825574e94af6ac7897193c7676e78af6de56c0c0d82550e22039e451f4ade4f3230f3592e6523221d33c71e1668a58cf46458905a61644cca9f0476a3040c32a5b4b28ddf8591ab6c5432d5c70a2d39b68155bced25e4730f6fee6106dd858dc2d2a91e0ca6f2f306fe6689ddb8603415736edae39617f38b2d1fe12a909fffa2e57aae5c1cb55c4d5fb5ee5b27c7914943eb0ffc2138cee58f16fc503ebac7700e9787d3c3700ebf1d8eb2a69aa9ca012d0f2812b8c18f30b22e18fea296dd281b2b4224364762704d3f867958b2b7d932f3d4b302fd4f597367db259f48e0483f19cfc950854ce036f55c7e5bad3454e5a317545f145cfc8c2d7c062be6bb7e672cb83887131b10b35f2c5b6872a6295b6814f67b188ae628c6c8211aca81818b37dc17e5280a00d3af3ee90fdb7037cf1e62cebede7eb2a405af8c0d16b8d53b52de7306122824e400ca2b91a17308ee77456456ecf2a68d0356ecae4acca4dd3846c89ba2fd2f69c75d12efd1a47a87aa64b6ed67def0cd32853650c6ae0a606dec6fabef7fb36086a7f1345575ce856d89dc10d828d2a3aaa9557ee93b41feea7cc83e4dee527e1aa1e1679d7356b273a37e5982d5f2164b586e88c767ccccf8f086054fde85e7dc6e17da07789de08997c55be0efeefbbb1b0d4bce0950dc91651c9816cefd1472f1076dcbe8d4e1c190cde979e3c898dd87b7c5df5777fdb2883aa89d824b434696e71f8c7e15c87a5e7c98abf431678388cb3090e31266639f68e499bd6dec05ed9f2dcdd8176f30f6904b40c2e27dc98d32f27ed6511a6beea0e37150adc7d9006b646991d307c83651ff4c1a7405c12d84cc9ca74fec79a1950e63a5f7d86ed231613b48b8812340a5cb2ed9c31eaebab60645d162d5c94587bc2bbecf92e429ead58cc1e40b797708a5ca2abb0cb270bfccf9667bab0897a07fae2899f2c91a2412161bd7ec851244ec79ffac7408e27c80556be761aef9be29f25aa208362703eaa7182992be93fa2622b9546f1d7b41c232e72c8694d33f4b490069f98b18f5d0759249f7090de3bb601c63cbbd98dc4297b2c74ef6edac84ae047104b6c316c10b859ef76ba0b63de2cc7fb68fd7007c34d0534d8289feb969f29691a063a958d200005a1947ae0ffc1d9c24896ae9df5e6581e765814c5e79ec7ff02f3b65c52a4ec3b24fb6cb48dc710bd2915ea6e9c048179114f8509e39cf10911f8e954fd9cd66be9d78c9269b6bc5a3f6a43a6c1e059c9ed2d0ace4619f72cb9ed522b7ca7971fdc3e8af85102bf5a4510b531b483f518f27a276191ab4c479dafc3f3b2d590ae2882d28d3544cc6efa721d8709dfe35e661d77f2bddaca469ffd9617e2a88dae76913048f0e20139847d302ebdfa59c4c94fee1c4b5efa296a3c6cfb3ed9538bd611baf0638b0ca10be73b00c96533ec1e5c24342f4c52f8badd484cdefd263543315be8ab81ac058d8c7f7ca306eed9139f3cb808afb3c7b5e0ebbba9c7fd1fd7b233655735e65bdefec20b2ffd8f993ec847bcf5bf841b9991f321b645ffa24be91e26d3e39987063a510638bbe99c565739318554a6f770ea10d10b14f4b40e91b4f776082391b279639c85fadf59068a4207ea8ddf22299c2a82f44bef4ef335b1ceac9f37e000864b5725755c877a52a484eb2aeb516f1df17f3fd87f2bf4a2c2b24748d67cf9bb369e510d9b2d540c276d206b359091d62542aa5a3eb5d4f76171ed8cf5494f701d11633982de629493c3f7ec3722f709292f5f9ce0b9aa8ae034e72b8402a18e9a72f5893dbf416dd951742134ef8d76281fc2bd5fb5df6a195777f7ade9144ce57d9eb12447ecb7132963488a51fecb8c134b9d355685a9baef2be942b6f8364652a8dc736de734ad0b45a4c9559cd2d9895b031054ede73cd5c22091b9d0361831d40ae1d72a034c70ea2a22783a1fa644fc232ee4cf4b299706928e28599f1b2fd3a0fbe7af2bc6950ad5d5fad7defc381348567c1f33d33c6b69a7cbabb4dd7e627858cb22af011aa2ea8880434552ac1d596b200d8cbbf08de124c47de38f6f7e96d3185e1a97febf02c77a895c4196af9e71a6e37cb7b7ae4058b1f6c7b13efdd5b12b8e0bc6c141483a10ba6589d4ea31747f851e7840ba310ef35bf7eb209cca6d28f78f71c9c79f9ba14ac63ae55f678529bb819775485f4a4e3fadef9435839812bb4b66ad0dab0a1e6cfe8922d5c74fb4a3bbba03b3956fa376f8ebca0fec048371027fa68b72c1f9dad8c538dcc80e618bbbaf4d3acec5b05e32c7646a04e5a4b5a17ddaee4845a72716193d5ee083833ffcce560e921d118c99f189eed5aa93aa6a40deed1accbfba9bf1a95df3511b98bdb723f99ae7e4704e792b3a75f60ea94841c3d2d78c4adf8109c3d066314cfaad939f1df783910ad1f0ad63d6ed34bf05658b7a92b486af707eae7f87fe205793af382988c14e9dc9b5e27ebb82edf9451b270223f1bb196eaa37318c3eed5cec6cc8a4d9332e69c280ba6c2dcd07de10f7d536322ff45a7a4611199a8cf2b476691ba9c6c2d39996cd4a117e46cae686c69a1c2ea4575429967047d13c03b1b04dbd2453b2cb3163eae4e8c1902a97055296530c9f5aecb2469d7f2cff66739d0b7d267167f4f54f1849c33de9cf24a6558fab1ecc22c1aa50c52e413e276d1f6b3e7fd70dbe6a2f463b1b1d02c8d2a3b4e08992f287a916d4807dfd9d6bdf49660b77b8cdfd94f15a1456b690f609e70e7a6364e1de0ac98e11dbb4f281def227e23d7841c756035bbb8b40e5e5f4743427411a45ee9bfb3332ebc3e387c8e6392d9cc2bb1a1ca21a1a5536079859b9d57fe776eb837378eda557ac52ddc14c4b73f599a0a96e6e224fc7e6966efcde185d7af57d71996465ed14b13ee9828bd295b397e921fe29b637cb76f024108c6c666520e4db7fc59717efe27c00f04d1b1abfde125168375641af6a9cc0cd9e2fc6bcb067309b7acf4c1b4057b60bd2f33edf6f1bac4732543d43c330b94e0d9d1b6e63d8c138745f846235307cd914da08c3f8987cda4622ae2a6625209cc96c54dc3934d814f43c3902a087d62cd6c23411d08ee376a5da0ee41eda7b53dc7526a9b59c0f0c4ef3594d1a6f9cc0d4781e5671b1478a82580a54946e621c5c3e617d0d48a47889699052e1aa3f0839f768d375a4e289ae24ecc2ee3a9cd25920e786af2dd19f0d476dfce5a7e565d9a412634af95f0d47473e7c392a71729bc49741682d5ab38a07367491ab1cd4b1849f1a68c0d170fb904a8265c30fe9948ccaec5a40dc2de3ebd36b789de70fb6977c0188b48b02e3e548e98919c1cb3cfcc14ca66eb1d55d84c296c50ba9e5ed8f70684f4e84831a7e47c07984f9892626be8ca62a4c85c28639504e374af0fa4acbff9a609eb295e569eb152580f72658ecb8bfbcd042526bcdfe48bc57539b22726b9ff5baa1901defb713c30bdd8a01c138912421597ee26d4df381f257734c859fb5dc2ca9854fe5b5e1ed7445c69681371bf64223ef38b9c2b672635cd68f7a2585976e1022a4d4be1e56cf9d4f4f50ddf11e076dec19b81df95231d1767e1d1d6f82aa1e904854d3942d5a104e64ee12b95cc7d1a5e8e2c694aee43fd57a89c46ff2c6ef6e1a5de23bd1318f9f03f4926e521728004e01ede4a5e7264ce4ee8791388416a7e24baabcb719693f4c9aea12a33d7770261044da789bab9aa26c7d0782b8be1c97b19d007da39cf034e36421524b223851bb239759f2aa42d79668f67246c1acff412d84a2b081c861d4e22487207102c74a2c88ec8bdddb9137c7547e89516320461028be9a8f4980eef12c73614d82a13c55ec238bb51727b76bf9c066f536845de7792774d0a6db7ea38c9250576d15391e94051b649b2c635ad33658bf995c4da375abd9858fb87efc8b599f690a39ecf7dc4603a18f66f3255bd16e5666d02b1cac8f348745cc0dc0137cfd25a5a7a34e4f640ac9936d1f3c9f39e5ba8a08898fd5a8f9102899fddc37c09c1a2cbe038db32ee975c06a77fae426fd0fa278a1daf884e956098d4ddcb4a97c351599d3d073e4de26967e0825d2a19f4c09e87ae8330a3a4eb589b6f0cdb2f01e6b657008a0601acb819bb3fc8b0fc5592adc0609ab4535b7e27e20dbe698b3d33603269fc229c44839f1b878131a53f340f834b1f8e0391d0afa876b793692a64bd1f33e4bebfe82171e02b0b10c546ef312d5c368636d65f3e7684853bee30b3ded706966c7585c19bb9c2678dca99baaa22b65c942b4f436e8b23c5be94af0c1d63ac31944e2e001e333f2fe5490526972d88aaee7ae9e4db87a23325dcdf62fe82c5ab81967a90185e7aaadccabf86437e2cc321c71723a425fde8df41218bc150d90a7567fe2b50c83f8b0dfc51008916152dcf50626cf1735ab9bdfcf37bf11cc8f8984167cf2b6f78238cfbc0b42752084d57e92123c848e61626a6a2abdb767b3a62b0fc04192050405b7207b64f4cfe48637ab21d055399ed30015da5452773ed57124b2644eb79ceba336eaf61bafaa5fc00db8c1fc9dbb22ef75e50650535c607a5365974a362d3fa88ca67df05305a76655bc8c87c68d687d8008a5eccd1bd31c792e000fb6eda1f597bf5a971ede2628c0e5ba7dc11079cada9e04634d83eb02cc2cb4e27b851175c4a534411859530bc96f2eb0dc53cf9447316ac3eb00f05f164f5ff647c8e4d410a71c22bd1fa2655c3d4844bf1302b1c42a884e489583b8cd94cdb9348359f1b1722061fb19b5a2ae8b69c77805dda23c12167f16125e63e1d1a378b25cff504a15fcfbcb8b55582f67e274e28b3bbab9b9165991190af2bc87fc9237689377f206ef9c2525d4c866142b0e2a8e05e971943eccb024a9862f14da00da3dacc420b2a24051235ef7ebf1a7915bff2a5455ba1ea37bff02eaa03f6948f510d1dac7351d17025ced9e91e723c7e4802ead136883756957b0eac4660ff39c9395e93a153968318d817f4c123d2bfe8c2fabe860bdcef40886fa912000a9dedfc9fc5036dd58f4e60cfcdc276f561771ad90fb74ea3f2e9a2fba1fde7d3c507f0cff0e25d350da5bbace48f0d8fa3128dde8c348feb6e8f3af342b43aee8c14a3309b6efb516d436c4632e97c749e0efa5ce904b397d4cf6db2cfa6d109abaf4ee05a67760d1b04f128130b513f01d8677eab3e686aa86d8eb4e20ac446b0439e4cd46be80daa01c736855e700ca6b77c41c7ac61ed19103a9a6e80c5d1a9e04b86bfef101f5ad92dbbb2e86c197e56dfdf968c12b9ee9395392c73297d0536d3b11b5ae1b6f9972fe2985aa9c7f08ad99928d042351c56be8fbcaf374d46c56a6d49e919b739659220fe8284573fad83f1d61d6b8ef95fadaaa224bc8b7bb7d93e73204f6d60ce3f927159414bd5aaa26f2f671ef665179341823ecdd17512b0663cf486d3202d64946b0a871fa6246d5f13fb7b69819145531660f64d4e933cd0dfeb5331d3c3d630232ff58467bb5209f433cdebe219ceefbace481862592cf1ed783d45f2b37392bf55249fddd27b1f0366ee35f6bc7f305879bf8f32c06d5afea96f9d27c5dd2366aedbe2a7bab204632f38b148d53b9bdcf07f43b9222de2e144956a5295245ded777bc33fa7dc6d2f261c8fd81b2a4a1493ceb9d6fd9b9eb1c59076b1e401090efc3496d4fa05c681beba3f84cafb6ea7c0d6525bb893e0fe104a24a5587d61d6a537c4ceea7a613050d86a8d4d9f726d63ed7d87b9b64602e26220f35ab4b48e1842661309321eb25350b5ba381cc5ef80021a3139ad4b6db9d60dff0a062ed116d5af243f12be78b0fac9fac712f908d3f165fd239e8ecf7c05c5c343c784b165913b462b0b7ea0edeb96b2e998240b181917d3731b30b6ee723a2e76473a306ea5b9bfc2e39cffd9f61d8d6f3d1d9334d3f2f3fc565a2aa84aa0ce8c793e58407676488c77e634b6434ff0f12dbeb3a5e4cca71d6eefa763a01f501307dc3e4e990e5699a5aff94fbf5752928c46a1e67e8a899465717321a461dbe1835e11841a961fa6a0b4f38114971706e2f62a3f20f02ce1d254744023064589c07c529d200aff496946d523b5c0e6b01cd4bf51244cbd4a373865eb51d3f1a1938daaaf43b12c9e790e6c72d53beb564c0eeb3c1b4c3f927b70a6af547652ab03bc380037409dc7dc639a83c5cb066d0f4a1f9689155f93c5eb3e42d2786bdb106fc1332b609cac0fb0f8f74b0f0b650d1aabc012309ad9fa4a80b7193e7003c946f6cd81187290b03e7dc48cd4a72a31942ca21f5a226c0c0b69a56a9d313f6b78a9c92f7dc51eaf93e4f1e3d4bf768fa1316260d757b2128d325b43cc4a8144cfcf7d13736ec7f0e99fab9137995257af57d92d8b2e143cf750967db83459d33f429069431c59b33416e653a6c835a6f9e10c8a71d7214fcc333a12f2675348e05d60d7fab090453eed8af14cf6d41c1f5ce05bf796b420829e6c654c8a23c04a37f0378a905a49078753b6377e0b427c970b5e0fe1086a41d7ed03018e6b587cda15439db4c6c768c04788f0619a9292810f5e1a6fb847586ebd77ab6fafa72e855599bc7c88b60a57b9da72448459c4fb6f8e91c54859cba6d74e786e1c09298b960edae832e38f6311e828646a8bc51ba3367cea7fb91a7a9335b3e955e34c242e24bb4fab82714e3a5ff7082c6f0ad11dda88193099d009f25cd2ec043b7204d4fe09cfa72ad8bc7857636f707c71c39bd2687cb5f4bd60f5b2c03414ac6eed7bdeda67c36dbeba65ed8c007773bae02a80ff2cc00b533a3f9f97c56ff7d511bb0b9eacb575fad1d207166421a788d505fcf8c51ebc663252a2b3783ad95eecf0f017e94423bfbdb4718a957f316bf24d8287b6e2ca9b120dfb5143e2adf9d29da93435b2e08d4ebed8a5cecc416de9754c716dc515b66648f9ad717716950b2414fe55800880f646e3d272efd9fbb6a78dbe1a0e2f9c8ca34fe9e4a646a3bbdc5ecdffdd72af733ad97b524816fe06b38cb3b3047f59fb2bc877b10a96fecb15ba333e82628524fa59c98dc5024dd97a10ff07cb131c9cf5991225abf3c69e42c58ff6b72549a1f885be716715cf0e7fbbbabbb5f4a62c615476b7c644b7a5d5fd5865b2d815f4c3758f34ef8a9f3019bdb76de441efa6d4201f05065f4cfd0b2188238b2430742c070ab3e1ecfa4f9e6f809c3777b75a2cb73d665985e126fa6afaffc509d0e8eeb3e3e513f0a5fde16ae83d64d8014498aab756ef1edaad281ad13156b8bda715f7b1b1a27db3a5ffb729aae2e0cf790730e45fee4bb5d7d6866bc31efde4a8569d579201de7e4920426743895dbdc18207100dc4a1d96ade58733e838a319fe716bea3666db6be613bd4bde73df5717caeac3a023911b547781a1c709cf5e622bbc471e0f508aa2f7fb32024f85f5c90770c4f6422fcb03c6a338a88d247900747b510f1ef4cc0348b7b35f6828865455162a2dfe9968cf7b3f2e75a25d4bebcab27ef1ba9984fc4aaaed3e7ff44865bc1b2d66063cf990c175811ce0828360d55422f7d23c27d9b179bed29beb6229c1455392811eeb124c21dc040a62b578463262322dc8c211f8c0827710e0b5784e3aabedfe6c5889ed623c83e2cc2eda628999d5d14e1781f1d7bee96e4bbdb928a2c528ed97246c6a5f88cec2c3ee34e0c887f2fcec9934bf481a6a19287ce163fd3e1650f9e380be388e74e911eac63f0b10be9a96a3a6c367bd62fdd7bdf6b05bf7d4efcf4591663e4790f5b1541380317adfffe8363f1bf15dffe4e156b9e2bfe3b5fcf07c5d75b830b5f0faa7ce6b2ecf6c2e20e9c25e0f0035987c8b104f0ee5d1a238ae20f333a356ccd1d1d6abe3632d400a3ce4d826cd519c77de26e147d88e466d2514093cd5f257154023c6d2088c47c9a605589ea61db52d31767268cf608ce597f23d3de3e9876c3b2cdbe78ee0faa198ebcf394c40cbaffe2724aa260f939fe819fd6742a9f338080ae23a1d0e1e8a4e3af830300a4b72393bce106ca5a05646b06bf9814319543479fa8d579584d6031ca51bae4981b621b85e2931bdadf2efbe482051b1891a517b9c761a269ea16e195d313cf543604bb63077ba3c2d5a63fda9344ff5ba17ec91a5ec7d9fcda4db07e6f177556832b0b07731a2896d3896fed24557bda64fba9e85f0330588d5d68073ee34dc0b9eec3bef67d56a6a1a12dc0f1ce100764306cdc13d0a2e5fc55bdbe1a7a3fb3f0c8d1d4e11c3615c3948ad6abdb326e8a9bd822a13ecb5ae87ca8c36775d965e34bbdaa15913d0d6333c026c3f7922e878f779250659fa204d972c675fc5733c44aa072be8d913d48569383f6a49df6691b4174d65e07a9496ae2c80e60887e8907cd761477a4ec95bb1c5e4c09e44d38a8ab8a922b72bf9230b45a8278ce78ca2156558caa53e5321151073e878e44ce771179252d5871bd6b532c83035702a84dae742180fe120172775672b47d8787de515be858a0aa4c2c0112562649b88dd5518a00de5874460e876ef313a7d3400973b898b587088e342d567e5c519000c2d13aa8f537679314a7ef1c392021ec84267b74ccceadb0c7f85b3dbfc9152638182cbb2b8db4c3115c089b3926a352a49309a5336fcc339df707afc31cbcabc58e61aeedddbb771a9db3243699a181d547f56c695be1d55a6d60765546246611d46b28e3b4bab1e0d072048a7361c3c27961f897d6f19a97cc0cad7dbc763666bbfca4cd74a273d04158ed4295e36302b590ec6f15d0330532551be0281be4deaf81ac2cdbda362358ef4b940e197ade448e978363906df813aba62869b7842b4a20922b80b9d434169ffb2422cc562811b153fafc3ee2f5dcf7782e0ef01d1e9f84063c902636f6bc6f487b45a4f7698a70a17bf65feb125abf6f756c0ae775da78766c9987448fa79cdf1437fcb23233630d35ac3bfa194ef11a99c3782d0748608cc25ee907b09790aab5fbeeee2a9e58401b4e9391832caeb2d8b3ad138f1b5a14fc13c00599d8e77c0604d4b75be13d58ffcabb6de91311d87ff0bcfd873d235d87fd4ab12123fff0f56ae44dfdd6d7cadcc78c855ee4e785e63af56bdff20cae0d01b5d86043013e7483b19dd33cda317786b4b9c9271161630407b3a695973f9ea2d85fc35fba603af64f8a348ac51ee1fb7cd25704e0f8a466d4760059737a47d58014ce1ba84542c1b8037cba13b23c1ac98d9b988b9a23cde4c60ce0076d6784d44552fcc0bfaaf9a682c98ceb2b8f349f0c9381d496281e096014a22d58672ad060173087914997fe64ced2b3395b4beac9a5397bc69c1179ffdd2e6c4c59daaf40dfae1e7d2bf04e4f7473d487a0d8e3bf9c7dcb5662429c56c93a7de838d3aaa30baf39e5b3873238a221438c44082c82af3b4004e7eba0ce5078354c41bd761e8f612c59c5c50217297ab0a8aa7803fd56a6dfca7191e1e91c72dd525d873274e94bb3a641320a6dddaefaa9a75ed8471a369ca61ff3cc92e6ec04248813669f4c3547bff452c47746d3392bb71183415e7e5d6e46b3334b4f0781cd7dc43796d1555a6c84599348b21822cac9d60c6996c04d26a89aafe475a8f8c5ce21b140a269b0f0c5309eb9ea469033f2887ea5f82bfa9211a65da903fe383cb4a5e29c4b1af13703d32232328bd78f38f163cffb1e7758f2de530ad194a42c72dd7f9797a758bfa8e70af87496ef305453f2895b5bc6be10011730c5d499185a57182a0d0ebb6b85b5d93f964b47c2ee0df3651adf3a0553c48269c36ba4600cfb9b249e9c5b95c8ddc35cff28651437ab728a2219b1c6a5a1393533ae141a824a9e29a57361d21143de26e0340439ee14a40e09f9085c10889d88b5e5e174a1eac8c8cd5eaa6e76150e4f71b35bc2e5e10c8d6aeab65746ef01982435fd0ce1732837f763be37f182c5abf45cde7cff7bb28bcbe392fbfafb0f1070553da93e1e6b4801810d4d294721cb8f4e4543d9c7580abbdcd28377718bb6aa809fc2c07b9556e534f428b90e4caf5dfab1189b0142a8304de1657fdd34899d97eaaee53e9574c9fc1e221609ee04d6c53c7ac3628db8bb2da4168e10abfa1a143a3bdd922455a10032fb2aa7dfa2e1d5f907d64722e93deaf4c957a19c4736f157cbe6ffa14909b81a7bc1fc3b537290e0f9cc31b830ff1d5b80b9dcc0ccae7c821d59fa079afceb7cf16e8404d323c84302ce0acb62f7e024d82adba2d5e996ca49550c852dd5d5a0d4d43b46ca71b4bcd5c647c7aa353f0ddeb441ffcb50a850c506597fac950737185206437e42bed1805cd883a54197b3313f781e3e42e5fb8d512717a39e8d8145996031cf9f29f5274138882cc06c0ca95e5a409bc1e2a57f74bca3eaada5e9a904dd390100f3d237a6d22789922b850c26cafd529c43490c386923d95a2e8c454de2c2971a5851f08b1a1556eb0593b5b8b684b08dbb129f09b75f8541c8a5aa9bd4c03a7be859889d3ca972a0f1d86666bd061b9ff2acd7fefab6939e8b1ee334672bc34a85c66d9670116e5584396f87d336546cd9d8c8528df9bcd230f8fb04bb1cc81bc7264a9b6ed994d084c9a3d69496f295cd20ebf1c0d664749f0f50940071c2f8ccba3ac48236e72887df62f17ec110372f8d255b9ce660d8338412b358b33d2bcada89c10818ac015875d0f036239b8ed03f8097c154b52dd630e8bf347186800c126f111bbcd5e6da74ab80cdf29e0ba8d115db563ab225921b8c483faa1e2dbc2a5bee01a2c282bb384b88d6450af1e088bab82c28d548bf8650952bb14ccc583d14e9da2c14b4cce24e114857b683f1657c5ac286a1822c62c5519aa8db18f34c9e603d120b6297b552604a46ca4555fb69ff5dffe134122d5c2363fffecd472523eb2025c3ea00536a8db8962a25dbc290248819bde335cb6a9b9ccd1287db9288589a153a2c980899485a2ad8ab3839a01ba4ccb1669c719525c43bc64997dfdcdd99a9610d0681461fe8e9d91280ff6c2e4c51247a75848fb818c84c2aaba18b6995e94cd19747d4e7bec560388ce5ae933188cb0a5640195d54b15568a566002ff449db258ae1671cabd6c5aa2c772c77659ce69c1fd4f3e24937544528064f331f0fce8d25fc8b60c330bdb393f2a1545e85cf70c65371aeda5b3853b65c4a516a5289639d767f7e62dda3fd68d90d1bd9d6ca3176cb560e23261c9af07170dcfc1918e35d450a9e3312c270cfd723799195dd783522e63463a931618f2434e1b31ef11140948820352d9d04086aa6b184ee6bede538d055b8811a5bb2fea4b44d762c57b5d92071b7857f6db3e18949f31b63177d28fe779d4fe12c32ed37da30d5cd50866eabad4b2457958debbb3a008bf137afab6cc70590c61cf78b676717f4331aa8ca62a668dc8e55bc7b6b244b97a8ca7fd2f35b4c82d16b4a5e5149a97ee78d061ed9209f4fc65cdfde5c95fca4c614625b28b95c29d589edb47826e8f22eff8bcf102fc4a1f8b3c7ef2a00ea982f69153e2dc41df7b9b8fd4021a15eb8dd227007f52ff857b5874daddcf5ddffe44189219b77399177bb44da2eb27c39a265b50587eb227673c94adf1cea0fcca5fb25a94eb13faff3de6bb6af95ec0989a33abc7af1a20f874f1cbdc118ece1c955661e44cd0cc9f6c940ea08911e94458de382a7efb0389342f60b042a71cfd567887dd7194c8bc35600f407c09c19eb8bc50b6363e46bccc60466c3ded3aedf4473c57d46b3afcf8a3d39fd905eef6744c6c33e486831f042806acd03412e9fdf283990d44d98d27b82fa03e1518883c1bd4928f3915c929ffb3d006bc0d4b4a1a49a99bf8907863c2821d32e0ab50451b2cb46f0263e5448982449a74cc19983f47893b4b00d2276cadef519162366bf9e5023698a17dc7bc973ced6accdc1fc135f0b980f8580f9e205f3d7dd494b785be49155212666e2ef9db32baede647ad701315fed02d5e36c6ce68bb0b6ba28ad38b64e4ecfcc9a16a52f36230ff539506674e067db5c78652b3d00c8376a3225ba3493c8db7c25d591040e01ae0b9c36ee6a1fc2581cdd3abfca568150d87cb6fc2d853a8a532aca6841d78a093702f78249c90e55e9f698e90895715a1c9c01e8f2e3890f595bc4f269e0bc5d3bb103b98bdfb7e47a7c4cb73a98655da7526d533f60005d0456163da14887857fe1cb95a564d00b4ac30a6307dd99ae1879e854e7e914bed8fe463be3c1f4b7f8467d1a48ff1e55ff6a75d4e6c089bef0b8ea92fee2c4860d1be2233d909322841359670c2dcb2b96f4512365c75ca683d3b1195949b0d7672edd4d70a21b2ce9ee1a7cddea15472b38bde629645bfcd0e9d19752daaebb00b2c01c25722af1352bc1f1b5b9bef7bc67b9565d160274daf069eb9d687a468623a8433f82545df4b8d2e03cba766f78b1e79d8447366dfa0cc983e7f60d3e61c71d0bb84b9e5c71b8841299b49ab9614fd18cdbad7d7947fe6b40fe6b8ad79b2272ce24be5993fd7d73b051487c1ccaca96b49b354b83930d6a36627f889058121d48f6bb41bbace3ecd80bc8ee78ee5d1df00d5cbc61b8fe78e5061654589508cb396fe1021d35e226c98139e4c96ed9f18ac88123a3e2a850e2137072cc2fbc6dd830c2c42a6ce2ac496fab39db43b21a922120c6fe5f177048f890b224cb05426ddb985b3c6b60914adb88453593445e429138c0ab27f9dfc5f5c42c23bb8fcc16a43d461a40d85c0252138f141d2f0e49021078b96633306ee2252e16d2a6b55c41aab7c9b719c5c71f54d132a2f8cd8a98a9c90784ee0e2e6306b4250d4c25fb0d054e454cff242302f84d30c625bf3bcb9c80ddbb7dc5812830937840af8e1527499f2cb71563426efb4de0ee0dbd965fbbe3acffb54f1bf903ff9b687125bf2d3938dbcd51e948b731f3ada5a3c4d1b2d0b25defdaf4ce7d2a55968e6f2801e68d36138efb6df50ceba76f8d37213c8313cffb9092559ca297efa346790b3f7b419f032b7bba3034d98dcaeebc53555978651bdac924affa47cfdc7d9c7384e501b6af743eb69e114f7d8c42266db83557cc63ce822feef963141ef5d9ac5cd76f161debf86b067ef823478300fb71cc3385557d2c26b1eb578b8175fce375ae117be590767ad7e240f326d57ab92204cb604e56f59572218e2ce808f0f35f1cfbf35f96cf0a1d58d405acc459aace508e123b2c33dfd8b562c14341d19ea771181298f435d267e896aee989db0f7eb79e76c6c94d1e34b988be20507dc1d3bb7fe6b4c1a117b4d9d5d4400e583ed76a13c32cc44106d8a90d07511c8005b0c6790620d72bd277e06b6c021b730e049b1fe46ba30a41904a4a50195c5eeb2c0b802ae5e19026fd73709491410510808a5ecf7706e3e11d9b2c3d3ac32970ea913861eb2545d3a06d91bc862f256b27caded66757006bf89ef33e1f8ba61bcedcd3f620a0a2f5dcca68ad6f1258e482786d77b7bf0b27ea232e8ee06d8318c9be70ff1f048ba186a53d7048e2abcc12d6b6dd133e535e5aa9fe25b90b995e5bc921de4c5586873658511191e0f00fd379d4226d47e77bf252fd804634b6d2d0eea8636cd2234fc80606f225fc571b6cb2d696c4859138aab6531794a3cafee6510fd7c46c5b88d8651351e70321762d4382f0aa5ed7f84b92bc81d898b0b6f72ddb60d487854dd25469a04ef2bb4d02cdf1b00b0c51ceffd4c9da86ee2fb1a62b172ffafc2c9c210c2aa3ced29948e26fb736b07926906d4ca4bfcc418aa60c8ff72cd76cb7a0da09de455a403bf7879bb2141cbef42a2a3aaaffbbba12520e17003b76cbed34ec22bd81407b60decd244289ceb62abf04730e34f4b8c5a26f54674bfdba737d65e1700df1c8e35b7dbe8b1f88cc7c5cf7ac6dfdd144ed9e8176ef12e667fd29c4d4ce5916ca10c00d1f77b02534a887e4caf96441c2ee8400b6e1c09440cecac012bf556de84c9b04a9a627435b868e3bcdf6b4ced836c3138bc2953e6f96e311c0effbcb59350d84e835caf0bd80a17f11c1c232e13eaa059670c337474ef75f7ed6cb29b0e09d03360e33c30aacc57d41066ef3a7ea00002faea951241494e1c4cc7672ca4a0673cae329e8c5a0f34b0adf0b8c345055e3c3cdd5daf782e8258a752ad0438acb55b9e673b14f3a005c3bb16b8978f9579627918ed0f3990a73889c37dc0329f0d4396f2e1512d392c2237785f0f0e1379f2881b031036cfa9cb468069a22726629715fe32b1b372b882a1c2cf4d39e9485f60c36d62009e5a9286ece2d3096c4ee77684b331071e2ef388657b640b13633d2994ef821cd025b386d91417649d4d1ea32e692ccc5d04ec3a3e7fd90019be0175645044ae06cc68b9be6c0df93182e679fa35c17be900043b08a1db179832e0454557c103f89f820555904039f3c49151db1e714a55b21ea6a79e9a69ed7d02d2326b43101554b3b905791ce3f9528ae1a8749a51db642e7522ecf298d7e8c0c704790bc1e9a0efc90c097326dc6692daf3ced2d4e43dacd475aac08cb3949cb69c0d589479ef7b082bdafd5f70d62f18ca86734107bd11202255d4802cd5e57069402894e19814595a760735dd2549045ce40e095baa58a045bdf513f4ad502f3310afec5d65de601d7f3a7710062a6b849c10da56beae6b606247e0d0777c428a5a8c7310d041f96670d9926cb883bdaaf39ab23e9faf59301d418220fb4184e0a1db68ab7849e0b0838bc2f5920d8ae152815d0ef36f54b7b21768e7fafa3d022fb1df3829946010338cc7d5d32dd59d75465e01d24dcf2eb852de739249c435867ba8e5068dc475781179cbe1344cc7757b458376fac2ebb6bde9c1d4fb160fd67e773f32923b7db73d2512bae3e36db2bfce339f201cccda1491fc62fc83adfb34e5bddd9646751be62bc2b6d59e4e73b114077595056d98a2f12d2baf3d67e838a2b48bc71fa251fd01fbc138c68efad0f5c1ce2a5a626defa53f44f36679fde6a03e04035739d1b15a288709c986f2e498eea0692e3e5e91fcdd408898e249a0b916872e8797bde9f88df3e6f5255fbd6a167cc26b1c0cd8eb6e20d3d05a8c69eafe7624084b9fd8f56b95a272226533fad20c46922f8227c7e0f30b01c47e59f278c24fb797e9d1db8e6d84650ae410ba08475216111cbf21e6b1d05e2e98cbca10f7413071a87116d2a281b818ab7ed204f41b7d2fdbb5642036db5d5adecfe6d2b47ddcac96da5d31b39d333cdb02fb8484d582a90a4bf72c1783452658ec642a04075946d4b2160962406d98eae12d408d812d176041a6e6115b858e105712bb8d52283572c74c67902b45d8b76d6cfb8bc0b341cc01ff68d3dd1fdff337dd335cef7c814efe403471973a71262006ac069c4d24c59fdceebbc668c922ad57e445be051567c91b50a2a92e3f02bc1f645cbb5adc5c0c6abae1b2c82244ef6d316f9473b97a1d31b8c2f14baab205248b74b9efd97f60206b798c5e515e6ff4d754322fd52d4534a9cd514d1a0454ced3e66eb5bc487ab3d73e507294b96701db438e67568b69da3d59bdfb2785d10effe5c65a682d6662ca385ab868a0e4d9d03572ad112993c17650e618332c790fe2316658439ff80e35273b6c68c6d4739d4acede86ce3cae7b3b93bb9bf153fcc11ea41a18615405749126c7b110bfe8612fc3854156c47dda992c8395e419b518077082daec3ffba5e7218403a03e20b023f5ac044ea6b9302e92d94821c561637cef36b64da0abb30621009d708fbec76d45e2743c41f5a408a53f387c60f4907a1ceeea1f1b88b29d2f5a1f78610f9ce02beb3604a07b4b4a5fb86d1e002793d62dfbf6b6c295957663a612f71cf36b6635ae395cadf3e4e5b00c4bcb7e74b47ae344ea904f887bc817d7287ff21be7579789e338111705f2e0e73e805f9cfd288b7ebf0b78db6db6cd5caf3e0fd3994ea3f1c737cf1e08b85ac0b13589900a4c8d197caa730bbed60da948271abcfd6e957e339ca2f7e8815ee4350b2c8c9842fa71ca8b482056e09488fa8cec8b434470072e313009d54a2afaa5b9a841a2d561e56ea88d5dff1765ba0c2d672655d7a7be298ab6b48da92dd587c9a83a67567d6b0c9979af92939a5213ad7ba233ab511b0902527b7b4d842600cc8ac8cfdce76a785417169711d6237beb9d8010f54ce1ee7668fa292a6dc3e0413d74881d40d6485b58ebec2a7a60cc666ace0ef328020c8cc77a404a7d13725d00e691fd3c6c812936a5b43fb58be9abe7262716e011ac6a872db980ec08cca3ef215966ad6a4aa507755e035b43abf2b9a23181b7329e787d2bcf0cb207976c5d6bb51f7e6ec7628ee8c5f5861bc3a5b52384ce657052db83372dac2e3fa76d19119fe8ae4222b07c76406a0a286dbd885db66af2c35e968f3f6abf414df95059c310ed7682e501f289653059336f6c5b1e7fd68227bc6acbad956fbcfea7b5d16880f892a962f47d4e43f4d005352de0f14fe7052a4ebe8146f2e659a9629409a864835a552b73030cb7c023909fdc395e911cd9b13c7a9065290eb57f9b5c246ce129d862c2ad24f8940ffb93c87765c6fc6da6f6f81932d562e118b0a72fdb3d891c21a2a47a4273a36d834d0a6b84478e211cefe138e8b58273ad988429f7bfe067e756d831d22e1fb5f73f7a98f3ac4297bd5be8956ec0efb59f62106d9f13977a9ee50499eb18d2f7d479b679af686f8cf4f21f2a269bb4cb8b74689d2f8e68c09cb69d0bda2d0dbe5ed3b2dfe8d8e6b0cedff4656413ec9d37fee04900c6ec774da3eb0ccb3e1ecc45c595e8ff0f51df652ebc4fcb4845e5cf208a4288c91bb865f0c640bb97573f6ebd01a6a3b73ed4db8641076cdc8a565e9c4ef789cd8dcf7f9cce422414dc5c4187cd0564fc988a76bd3a9e89acf23df3994836d86b60ced8e8fc771ee16a8eca0d61e32c498c8ae78dda64d647e35d953b4aca2607695f7d7144110800319c707245a1ef8f9b4cbf717f85baba9fc9b7a8da3a46a88daa40fd7b9ecf578893410de3e75dc6cf2fe9d63195adcf5acca02458e5eb51a2cd3b51bfcfaf400a4830310046bb7d6dd92d7f8e66c7acdbd42852bcc56ad816d4c9d93064f1c1b1501923086ab26c1f5eca462a7e6b8b9dd8bbeb7dbf39ddade3ae58675dc3c36d4b9618c17644a4765a94dadad6582192c316fef84a0cec130db9563e69d5114f52f6dc88d685eb7fe14918fd1e02af6bda0cdcc27830748e023df0cfe8017a255b09e413244acbc44d8124d9bdd3a4394b02b7190b19cd7639ad0bfc63b14817e7fac71bae14e026de00e594ddd00a7a8028012942eeca76042088eaac22220a12a122095cd5c481a97e6611ca084d3b9bb41673648d06c22b1deb42a2a525772d29160ce07a45b4a5fe71867dcb4958884e865c6a020c02852b249bcc052176a253c6bc527af5cc455ec5295eac881d911d81dc97cdfcef8f77209da9de4e1f778345d7c5f0a91b61de88b827953be10026c2b4b0db0e2c82f848e5db2a3f075707a65217e25ceed132f05729c71f7881e1c30038d191338534d16810b4db1bbb14f6687e4922dd25e56ecec99023c2e6909f6225d3f4594491d40549a82cf248dcbe757319d5aace0e3440b1d420abeddd84ae5a4aa6ac78df6d9106d1189f61e713c02ac2989ab359dc050d7172a96ba76501e1ae95c82d5cf7264e24011d03e27d342072de415951752efab78572bb8c535cee73b3cfdf6d1066b4c88364652d2b4a38298fb33132b3a8470715da11257936dc4142263184bf33a0843e3143af7e5d408d2919829c101d50c49f6d33b1d19721fc6222e4e01a427af0af53afe706fbfd78799eec3fccffb20f350e36fcd7ff7adf256f22cebf1f4f619c20768d8d8147ec084fe06f9ab157fea5af392cdb2d09be5fcb10a1e5bc963975b13f7e2e1fdc7523c76d28fc951b3a13bb9f2686478a5fe76cb6f78d31cc0190ffe656977ca65cc075038da885a8085ec00d5faf21a0af7c3bb90ffdb5bc7bcb97657f6e1a40a7d3fa430ede76f90a990704e279e3797ca1053ed1f16d66dad8045f7d62ec779106723c1c2e183f3f207438150ca05f6e7e2976884c1db9f09564fcec01697be4306bf7c2c93dad61e6f3ad21d1bfe4ac40e68f972cd4b34750494eef5a54ec9c289619c98195c4f09ac86719719e836f305238744c835a7c11e9abcdff6cd6bfa79ebefe84ed0e79275c739ca6f5d08b90f21d28bf82fa21564e86543f9f856c8b45bb6464ef7a02af42a0cd5daaf30af6959449f310a2ad0db955b0d9db4c2d359e5d6c22ce5b8d9c914427c17b5bdd3164fe0a28587eabeed63173a410f1cfb9420a68a87d9eaabafb4fbdc40a37fab519b9ab8bdec4b18ee0a77f67dfef201d7c7fe2d0cb327dc595724b17483212cabb7c8925e219b676b3f37f482dd0f5a23f6c12ca66fe1ff0b6a15d09d8e74103606a149a017185549eaa52f7516146747844e4d2dda1d176b38bcf3edd417ec9d3310aaf9d2301415af63de9bcfc8dc79677d81fa5363fb29db62c29867f085ba31ea6f404de5531d20f51ba4a920f9c211433c2f4d6712cab9700042423b169b6ba16b95bc35691ce5c4959846588cb79efd63e8ae9533d6e27194218dca0d24b87336b0a245061ad89cc195ad80c20585d329c8f7ce46c1c4c898739d2031e7852ed709e5327d41fb2b7f0a14abf98edd82cd1f8e776d8634ae0374ba6d874d09bb08063fc417d6138ec43cb19435dc771020d971bd4b354899867d87aa9a49509cb3b9bd40651df633f4fd85e38ddf2fb8727a1c1c166f27fa900e313d2f87c2fa2d42796e940c64501ee02998954b5b0ce74e4d8b1a0acbaebaa18d2c3bb5b453dc8cf348d138c315f39686942ba1024c0e68af34daf879550b3cafc6cae2096639307e4c43a274b843a2924af3b34895899d267888ce139a222447e7bc8ea2d333f76597ceb0a51c3f786e0d6790e8ee706700c64c90bbd462776fd86c07f4006a32683e5d4dbc418f9111a5c6d8b18580424caa5c1f22574c43917ed4e790db31ac34277845a7df4964684c6facd7eed4602883769f5255f297ab7b6fb07dc93e09fe4490bcaa02009483f943a286f824032c4e52b2361563ffa6db521fbc6acdf2a1e73d7a9667c43912a6f89c522cc6776d228adb2407fd8c9abe753ad8a88bb265218b4b99e40ddf62088945521eee1c80644f09ad3bc462cc155162a480c441d83cb6b908c39e4d93629ba8b5d9165197add0652166d1d595b3f5dd50b2823a20527dfde9b085bbb643b6196b232a3eb95d9e773dc89900f6d04af582c886aa867d554b4ee0b71d09ef14cc540c9fc50206b4d7918bb3b6fc26e6771a6b29d72e07a5a521e8c97ed253d7a18defe9e503551dd43a2f6c3e37d1017caa0d0f10a21c538ea51a89cd4d1a8b660aa08758673469135cc6f3e00d5614a394cb02477d2a5e0b1e3597503fb0c7214369cebc3b7227fbae50525154b2fe772f4e27b3616f7d4bb1aa517c56a1ec0810a1d3427389e989a362167b26e35934e668380a9f0b4e1f796f60b11301ef2b8523db2f98c209f2197393bc05eaa6896d3a7b721678de2c90db598bb2c951abad823084457c994d0f957b68a48030a520672f35b14e44871058a892e5d8d615f19f6d3e52154a003cb22d27d83551433d54136bc7879d26a734d923ee0b8afd82b5080a5e1e354a7a93b883451c983ed97043daa0c9e08d110e38f5e339d209911cc8b4bba193d91878c576db0db468f6ce866935443969437fadd5af0d502fd73439017e6a8f053ee0dd3406a2ed92e8e1426f4f7d8600cd0d91bc8522db2854d301d055b3a280b6e9ed8ea453cd55a55be555aff57092ee19b223d88d6b0b8eea5ea0fe03443c49fc70d77fe6bfb9f688c3d8dcfccdda4b758dfc45ad7d8d71e199d370a1acf7f6c19d70b616e2d2a5715ab4162e36e5731296f248e97fa77bc6bef26d0a51e2db446d4fe56c1b33144dc1acce96d70ebb42c2e66a64e5cab5b28e28713c3e048e01434c0df3ae181eafd9ac3ebdbe0abd30ffcc09be18e52e7e4b15a0ffed9eff6e24c5fbdb0450d4b12a47393d472fe0f072f1d53a13cbd6cf62763fe47637c69cb3bd6cb2c44ce35835b8e78d92be018b86d05f2bb85c3b6ded93318b29668b1de28b0d080770e7f898298bb87c9ab712c312d3c3e089570f5e587feeaa5db5e9ea748db161ece22553f14ae0f00d64492c033bdff42fd44eab6be5f75cbc2103877c949466b9703f4e421a029da44dbae8959a64a38a6ef1f0d76342c277e63b6348001c81f4f050d2c16d26e5cf72678af105f50fb513ace645779aa7d185033be19202b2e5690f1c1121b36f40ce68406875d2c87038dac465f898b7eec128202853d653df2f11b692820d2502a05fd5fed091b588e4adc9dad81cba3f2ea31bb13d153b7029d6527310db3d85ecb7f59594e7e911ac38d2bebc28360a6768f03842110f6de0862885cb3aa31b9d703c8ef1d83af4988581c42f3788acab8dce947f9eb24f0e8520bb20a86e1b694d4b6039ae162626dcd2cf919cba6584a79ace02aaa71ec8b231f1bcafeeaaee1e08d53a03d062b5e1e0c5cc12c6774bd8dcc69933330c674b09c041fffb66e3dbc3b0a88dfe4aacd2f8e2675549b38e3a5982d613cf032be8cfe76f7c68c448bfcd41219536064f9c5c47485705499f03f1aa21c4e9c96b0ea262fd1a831e3d7a1df56eaeeebc6850fbcc79d8e618ad17658c9d3a70196ad5330827f969ffe448e26a958e30359d72839212aa7aaf05932bc82bd932a683e6d7193387719f5109fa1d455efb49f0066ffb9be2afcdc189676d363a2bc03af13c8aa70c0e5f4ff41b55ff192cbfd662554a2c30426690836160f101ae456729fc48ff6fdcab012046a90215a82ace6ca47b74f94524c4c7ccdaf64bfebb4e55d06b7d11f28c8fbd60fe63dea698a04f34a7c77fe8894e6cd04a1149dbc87d1bb2974be23f659d2edb12a370f5d31b04d7c59b0b7f4aa685e76eac410f32caecefd5075715aa8e51828eead681f9671f208dba2e68842ce856415fa6c9d8e438ab5658e7dc38bed05e97e7bdda0526e65c295bc9fcac10c72c11436bb4357bcfa2f08d094227b449558238b59c5e731e17c513cc99791e17cacc70eadf963f162752a161be75363a0b4b4f969310aa5beae7dfa60dd645f39ae2c7112306d30a2ecd00c0128ce01388019b2f5e60ef1907e8c302987eab007e9d63c3c766a001d459a283b274ef79304fb5b02fdb8c8f860f80899d58dbe8ed9da6cce69848a92c60250cecf01b0903eab6a4c3ca071558e74fe08e160fdd7bc1eefb69c13827f16174950e0ae52e0534e18a43c3ef6b0bde5852d60ab71b754e15e3a263b581dac8161f5b99c22ea8ec52b86c228a9e5a76e050562491bd984b7aff4152da4be51f3258c0960d1011b2b4ee8373619ac27d5ecffcd23933ba49c6f68805d1e11a35d616d9c042ebc88236794179f70cd47a06bba713430adf37168050a2a94a4b6567fa837dc10d7a8384f9c7fba5db9de232ef11e73fe3812301b6b7049b34219e8a054545dc2f2ba0682426f62e898964c080a2f447da8c4404f15c6bd58a434a81c4d42616735f292b32ff533d08165fd085d6c254c121b298aa2d1de37b89fe6e29f4610ce17922a10fd30a3b54977e6d60d5efa3aa296d7a66ebbe148f78e6751c0d0eed4358aea850cfc04bbdef72a4f37d6761d816d4075606ee7b0be366a380fab45c887ab2c6b876aeea497298ffc76aefc40b765f3ff07a2ec65719578da5154d7fe3fa123360b4515847a5b0619b292101268664786562c2aea0e07c81f4c638b3f499add107e81ba933f7197015ae9eae3a7e103d543fac18616142e86d14f2787f75f7ffe1bf30b8a3ca90a30cd12c30fc9954113edb552a3401a20bd9205be04b4cf01aa84ca940efa4b232f9de13e5ebaa4afd0f137bce09252b55a689c920fc5d9cd475df39b2f3a63a1bd9f1e750784d9917a35b2cb6cacf358b382366031725134c0e5789d1b976c2fb77c6e0b6c977f355e25ea61a571b81cb78aec1489c5b24e213ebede8fc2bf4acf7c0d64005e050874f411e9101c7e5de5268c55e450f880d0ce8d9b83af12792487ea4c63fd9d9def7d811c849e0a3154c70666c8ce75b65e631ff87266096c9611515d6acf10162500b70841d14703ec06dd138018a3b222d7ff1dae1b0f22db01827f4e16d957bd1aff2ddf8834a48e3ddb64a03eb89636b27f8747d8d1c8e642435717947f613663ec7bac847ed3d07cd2d73e8fc8d91e735a4acc6bec2fca9bb18b94fd5469e27eaef8cab713d695ecf279af5ec37f74c0e25e093ada4c4d40468db0241b61fbfbff716c815c173bdbaa24cd5ded09e8b7aa28c7207540c1c12fc8eb279aabd78d8dfb87b6112bd9a4e201e07052177353c4ac1d567bb844c54c29386b69a8d95b8f6d7ee1467379e97ddf42aaa3b4d541c82a944091cbba192efc8fadc5066fbe99eab20ece0083e35b9bd6c0f87f71e25f0711d14bad1e2b5448baaddb24ba4bbbc488b567038f4d1ddc646898f7d2067d38274e176ace0895ecbb738419b467861e9ac3ab154a4ac576e809e4889a33facf703c3a247ddba7f4e933a18880c68bb5748d0dc813d6c57e60bc5622d4e376f919f8c95eff91d37514c657e579e2dc6f34e0eb767442943fda39cd1a6434fad2f99f1b163e726f3ac6c19807d8ea305787d397d845bd1386e664133c7667665529ec00ce0b490e4d947e1df620022328d90dca46592a947a470de496dea2ea8039a413800ccd10e4e1a6c492c694cf910ad51478884964746041b9792428a2f2ead0a2780d36bfed2e65359875568e85628094a9bdd9dd6d92ab0124df5e48b3bd8bca3da2ca1341b562eeb3db4d1f598615eb4ad930b667b927fb56def27aaeff434968a93a418290648f74341bea7ff550033250134cbba5f9a8155ac02db63d8e012fc8dd583c76ff6b92d8a89edf0b7c9c214fa8335dfbe5efcf4e245d69ba618315b2b9c58bc7b6980eb27fde261c239694fd2bfcac67fbb83a76f6a83f21a9576e8dff4760ae62e54c62ad8144f8cd39afceed4f6525649bb90bc3ba942f965cd6ba7a12ce435840e7677b045ed54b00202cce846afa9c22594baa0f8a3ba1b35151355e47b6def0773891de5a952a67175d08e9c5fd46aab94b0d5b69c0daf63f4d90a71443dc2ea0dafec9de7852b29e4db63e3de8eb30fd9acda0f70d8a75538d5a5747069624daa4ee2b2c65d839364bd72bf4d0862d240bc176d4192ccbeb6b64a0ab753312a74b4a6a6322432a30a432fe245fa695f6d43f558d6c2128596f2c5efcda4813844f512e09f171345450ca95a6eb0e10a5515345875b6e4b2397097b9c40d7755448564ea399644e0bcdd362d132145f703c47beee4648beff5115e26b3c02a5e4b5771abc4be49a7e200a61117fcbc734acc2588cc03e8403319d9f077a6a7a125cf674f514476a273f9b62d764cb11c89983a941697d78baeb11c8852ca7065375d8948a0252141ed5beec7d38fe636adb19a121a1880a7e205d0715a762a4964fce4fc3cc5cf6733eb4caf6145ed8d2d4fa24501f605d606e7fb6c03d5bf3673f7190220b72bde671ba4033fa91da212718a9eb736a332c1d9293072086d41ce70fddd353f6224bf522a98a2b843ef1c5ec87898d53d93dd587ece560d34dee93d4ef01c064e08f9dbd3ad8e824622e3fdec747bd5f0297a901ec6eda58108a6db4805bc6f5546a229d008390af2be968db5c1bbce85baeef7d5d1558f400998df7170e4fdf178abd58dea5eefc88e2a12bb8389381b4b178b7968ee788bf039beb94c8dc65e70f8796248c7fbcaf1163159ca1080cc85059e696563e9ab7946cc9d6683b7067c5c32f844c8e3b850f6f5e376545ee74bff62fd7b64391793887b53c36abf55aa884ec7b5acf4a01fb99a9882f00c578b1f05c314c6c79e55f4080701ebd4389a9c0c14984a18e6e63eab8c04759654879e230f5820acdf8cf7d2bf4a23b6638118ea8ef674365a6574de3ba30da2170cb751194925063299f7df323943368221ce5043311b78b13fef8cca3cbf5cf849d480da866534c9187353fcec9040a22151e34a541a7967880250e58250c57515c9e46d54f9c2c4d5be38d40708b7dcfe916cd6739382476532207c1d2b3cbb88da7c90c2ff296ff62a2491adb067247d6ffb643ddc0d2439cb998d6cd8dadd5a05bd6fd95368011f448a945f67e03bfcc1cd564d7dedd13991071428ab5931a3d861acc016cc9fc2a3aa8a4824dd6b971904d221959a281d12e1b502194aa4ae034b5de11a152a7e438abce7ea96c3df7f40a9ae59f26a43ed406d4a568ac34cf49f51591f3c3e5e9d89243bccc8767b0eb74dbf6fcf36728bc356db17e55448dd227f56b1c9ad40310792032c4e95ccf102ac16676e5f43db2c67fb3b2a37647f0121db31454960f92a4e416f67898118cbbde09fe8be4b44818ce9619f42ed1f7b319d8a493d061ee10f6fb8086a6c41bfe7e24dd48fbb64cea6a9e23b3fe239bd46b508c92a166c86757e89838a39ee7f72a80cec4b7b86d8228729bf35acf3b01884ed71ca29a47751a7786418f931e7c4a6c57a04ac1aae7d32aa7e6b129e49f015ab2846d4b5ef05ff88f1b4958eae5abe177c6aa7a8cd9912310f3e7571a3978eaeb6c58d3e6e545262ef018bdced66714a83cf6cbcdc3906de595c08e79fbf5c85de8fc4ef700071ec5f05de70e5b3d116ec3de1f5786853d6417062bb7d6bc7bb3cdd8db814e555e005287e13f0e43e7941e247d542960ebcd2f3331f39c6f7e947c96b6bf25e3846e4e3bb4f178542338c863977e02f5f1d7ba3f930a0ad0c57dd6a4767b8ca9d4cb9d599bf709a1f9e7cafe8f0cd275eec3c1b3b4dc714231e6c9cd762dfbbfb55e522f6cfebbdde0641e22f636c9c668766e6b1383941ddcff8f2256219ed6e4a600fc1ca6ff10fcf6dfefba35ef3adf77b381fd4988f98fb38aaf54e4146c6cde0eacebb212df90b0f8537f3d5b3371c08faccb17ecd38312d0e75ed71d6d77df9f74d874336eadde2f71114b40603b091376298fbbb29847a9206677c240901f48e8ef987257b2fbe72f9c97d4057df56a4cfef82e590090f8b2c932afe520341f1ce8fe253158ac009ba3e7e779e1f79c32f7cceab14d7f7cca2f3dd8e4aea3e5f4dbc5ad0651fe37ac125c337ac544c76297d87a3fa473346287d3c30bac7897a1c347d11d1c3cfac13b271e871b6e5efccb940d37dff0b09ae7efde56ae835034a455efac7e9507faac91b70c976a1c77e8bdba8b4b8eb3d2a7d11b4fd3e4bb66f7ea4c2354e1fe60b3e0eb3c575b1b1e67ebf4f2d3ff4fa28578707ba8d621c41d3c78c53c8f48fef5777deb7357b6ebe6dab05a50fbe9e58dcb83ff2dfc989826a469ce3c8254bf6bec72bb35c31947ace7f1f06d43da6ff355faff5f716f7ecfec0e13ace5e2936fef9cf232fa47849fa6640d5b6c6b747163f5ae87431de51419267be77b392d1ad78d24fc5860e33bf77fdfbdede6fdb173a309a93ecf7385eb7c978f4dce51563ee7bb74e597def52f469b0a0b03a0ab7fadabb2e0e8db76784c8fbf9734110beedc886f3805d41eb4e01151d76cc74c9dc37715eba3d04bb1f5743ef911377b7ecb1ffd9c7fc6daa9416d7c5c6e244da17ccaed937b3432117065d0e139efa73e682772d0ec0ea36f8b1ed143af3be383c41c4618207ceab78dcb118d16212fc633523f1e06ecbdffcb9a36ce730613a71e4bb6b620e279f789557ac99f9ffcfe27f53fae78fe27f33fa678bfebf57ffe7a7e3f23bf4cf375a7d2efef7c0ffea0c79b169e44b3f9f876abea63c0f4f11e6a3b87e28ce11881c852a3c8c0be6500773e048b141313f9fe4e782777fe18b49318e11126e039e82037fb3ff9b6fb6b9f0cd538dff9a25be7a2a445dbc469df1663e617d3e178c761558cefbf3bbfbe6b357bf3e054c8ab88a6bd18787d1f2816964c4fb70457ac63da751c4753e3d9c5134d96e8adb5f56419569ce3dcb9abc75825f096dd9f1fa2b53d6afc547bef50fd49ba798f3e3757f822838708198fb35e73fd95f6987b6302dbfdcdf887875f8b7fbd70beff5f8b7674e3cb53ffef0827930efd394decdf0b7b81e79c177ae067d57bf96c08289e73decbed2a1a8b02b7512ad68104f2d569aee332ad21ae603a25ccc611f0bd524f446df982ef4511d6e3a83db2e1ada10de9427fda1d06187146e39f01e985ed187ee52949c2399ebe0270bda379306a32f8dc9ccff1465ee5d8a347cb80abc51b568f2c6ebf3672647fe7b7f8a0a412978e5b57e5872819fd5d3d5c41b7ecdf2f1150a2a0f195165c3773839804635a2f17ed926a05df31022d8811f0d976caa9ffadd6d4103063bff50ccd4b8ee634bdd27fcb7105887dfe5e6d5d00bbfd037e567d981724d1ffee7fd0f5311acea813e9cfb04ff3beefb9d2e7fa3dbd52d079fdbc7a159e3b137fc72d8f0de5e409aecb122b63c992e921a1476fd0df762bcdcb060b0e6ad3e214772b0f02bec3cccfceae1d6ae79fdbef8350a3a072c4693a14c5a94b5703fddb0e891d498fe565ae8f681d6ac3d90f78a1b2121719c7dfdaee81d471b3eae00c83761467eb8b6619a278ae30a7641ba2d7d9358180a22dfb52a973ec0d2db779903da4f1d567d5f0a3aff2ba911123cb1c7e05323c4c5bd37feb4a535096e4046cc19a964cc650a3193c291d840fe439a8a59b6feb1db14224ed81c1cc8927d57fb206e8be07b63772d66f4b5ff2b204e9dc4ac0109dd9c90273cf343ecd19423393ab40382cde0a3c31f56fe7e1e5aea7d57a846599b52966f5a4c9f1f26a445c7fe62595c87d0802a74157845c7ae578c7a683d086cc33bfa574bbfa0dcc5e1c4b9f52854e76bcaf15d0fea8d27eff69f23493677ffd5564773e6520b56429eaa4c194e6c83be8b733a7749f17c38aaefd83a9252476e6e2a6c7e6477f47def89c3dcc242b99973c0d4246d33c16c9145f681a959b30611becf4ca063de0c993f8efbb5a1a53cfc396fd29cf396db90f18339d5a8f8b1383e8b254cff8117f49199c34c843a393ed0927e0359b96bd6cce163619a4fc25d75cbcd6d69e0c36f6d46741befe2401fd606977e7bc82866373804398f77dcacf8fafdaf07f690de355ff5eb15c238786c91121ed483365b65eeaadfcdcb236f8ca549f9b04c72deccaf5723ef7eb4e3e377bf86fcc0314b6b3670df71c1dac77947afd7e753100f2f70ef8cdb3f974572e6dcff8a836fbe5e1009a63bee571f2a726f4f2a72e43778f1a67e13c2fb77aa54ebd753a613f3671bf4177e6b6d78948d171203bf24312b42c21c7a34aed7ea82b74d362f64d2e1a73a730af358854c30af51661f0bbde1678cfa6143d06c8f8d6f3c576cda7c88622e7391a7c55bc34d902d204d40ca5e9fb8207cd4a3e8a69dbfd9099444211b344e034d9db1ebb4ac6022c43f59096135f86f4b0861b5d8b8d71e2bb24f0becf2885862c1a8860b7ff7747e067bdcab6a7bf8e6190caac1944fd9d30c1a2a578f1c71f8d7b8f28913c16e8b031f05d8b4e3423c0a3e472cfff602dc2bfa7b60ce37de1f70dd2ad8c5dd26582f81d74a0ceb27211307d1f1fac23cad0fd7fc4ce879617d7f4d4099c13cffb3597bf0824db0e2aea54c2a1f9a2d6a71dc6891e2f6d0ac16b330ca8359aa054c2b704e3b885ea7589e2ec99b932ea90c771945c904a760cfc7ea6e31a539bd4ba1265e7cb912b95fea14c76d580db2a5ddadc573ed75d148382f86b50c4631b3eba9cfa6eac7ee626cf8681ecc6a648d25bd82a3efd98a3e2e4e4a2128a56cfe798c72b6b2677536dfd6eb2c50a56b26dec97a78f54c5f7df0bcdc8fd708b13bf149e9906490f91d76b786e9e04d3df487376a0f4e48f1def609e7f969a7aec9ca5388d2fe3d33ec6abf1879b8f33b264827e030d1ee440d26f8b0e5c138ad3d5064d89d9840735f7efc175d7ff2468701d3cf15b7425af8caeff5ae7911a4d00551a94df085ef4ae0ec3d1bb69f0a4d9c21cc27cd4a4183869fb7dc9e59e56eac5498f075cf24cb2c53ad031cbfeea565fa9e07cb7cfc172fbcf483d6362ced943a5bd5ccecaed954f98820694c60c8b1ac4b9add391fde624e277f38a78f5e706081f1a3d3e12df7e7a9bb0dcf3afce485f3e290fc1cf508dee997d7a981f6652cf7b35d6de1af539ab7997f606c4b43d2a7af055fa9fa27c687327cd1aceb73c1f9e6a9cb17f5aad7fd0a1b4e1ef9e4d91f9fbca0ed7378d943b464f1684a050f83b9bfe450f497157abaccae0b9576e7afa62cd74ed95f1a3df3f335eed8e38e1b7a5875c8aab7f03b9ccaf078c00f8b267e683152da0b8bf1750ad60efa7e7fcffcb7361beaa36776dca11a70764293c3c8efd8d4cd7428f83e6500060eb9eef227ee8efcf7e1442877eb8002cf1781378587a018f5b3e73d742b1cefe5639d306aefa598c89d2f73113d334ba34753cc4731e0315b6c83c85f7642355a82cd0d5ef7187131d607cece189efca473cd5e92038702c1143f92a095200ae6958108cf01a772536da2e167463c1ecf78d33d2ee6c5ea0d23bf0df8a5bf6a33eb33054f668506399cfbf3e852f361e4f73abc5bb61c38fc478721f6bd613d1082dc26f75b70d34a40a06705eb197e95556fb3398fa2a4822fee537257afde045eb760eecb5696b5a3dbcee2a987f5ea152db768b706af3b67b77a778d88efdfa8cdea3df6f643de8b4915949c93f6a0ef14ff03dbfcffc9fb13aec691640114fe2bd9fdcd0c70edc22b18aa2fc39164635cc6b88c598a026e1d61cbb6bc48b224af4dfff7ef6444484a6d86aae97bdf3be7f5cc292c2997c8ccc8c8d8b365a1be2adfc649af7bf1fc79644ca6afc86d5ce1e786543b524e8a9c85a9dfacc6b2b052e0253bfe08c9ab8de563d2e77b0ba42fc9936d195fa047a9fe8ac47155963df2f8d123e7516ad855631d265e6520b60f530c13ee4c0a78df38e568ab4fbe83ee755ac5e887ba3e8254f23d5c99f1883a1d29b8056b9232950d7a7b3c85c0d2c655a528a34c0a39f1415ae90b9ec4fe14cd5037df41d61987521fa051010f5cfa123d6f872865a51c0ad2b69a55a4a6447eab38dbb30d0239822847e5758697913f1817deb8353e42be0f95ed3d805f0497dfbbd20d920f92956b927205bed8ed0d7edfdef0e3602ca361108eed561d34fcbcb1cb3a4e454d52aeb1853c562bdc703806d814bc6af1e35579454605aff6b95bdf643b52c3928739d4e96e4f29674d09cdd44e49416dd210b9501fab8e8f517b65241cda0f926228270bd837bde5297a53ad4b7c2e6d792d3bcbc6879b7a9456b2ade8c7a46478941ae0377f39c81578a5fa85434e2eb07497d76858ac1fcb7ced77b279df04aee8ebd7e9b4996d4aeda1c2f9b43bce2073186fba254843d3bb7766defde468f21e01d96c6fc0274619a3dec2de70c02f24070e826ad33a0107b387d5491d64597984bc58bb8cce250fb919ce36666bec6da1b547088fbf6d2c500ef06c84e31998904a68f4bbee40bee956dd1b67540d4c4d9e0e716ee737fcec185781a856eb1b5417dc95b6581aee4b53061990ad6fa40ae40cecdc816b47ed1e5fdfd3ebbb3bf384ac0a4352a795946c536a9cca53de59e33683b920d54a5ef622c139fb3603f1aa74bd845d60c8a7e30b3c12bb92725f3e025fb31e7fe8dba811ec7036e3268f09be40e173bf26d2ca5bb8ca90290bd4aca7a7f5e0214f4945f8ae983c7a3e94cad7cca8ee253d5606d353d255721e62816d75b33da97edb097c0d0695115f3c49051dc06b15e17a94941bfac985c93ec2d494946bcc6dc59146b9aac8c1fb6515cf612e1f38375e57caedb8eb91b2facde4e44b30d2d2a9efc2aa5c0f47b2779d85723f1e5f04b3a38f2e8262eb8ee714797cf51d0d4028d23e566628def9de02274372c540441897789b4379840889bef5ed1284ee822aa8d6f0ecc0e8bcfe584625cf0ccc7c176b6589c7a14f7c57e807a6b998a2805c5d9c6933ab72691c0d5c4b14f7efc694e74087ddacbc621f2ae5c1afe78fc1b7652453a7a66c1369dfca7c2d8ee4f5864a96656f9fd6a5ba2b030d6a5993fabb92c60397eaf2f326c04509ecc5e66a5c982ae029592f1ecb5e1adea6a4b8722904a8a402a73192f15a030452ea9d406fb5a9ec12e7e05c65efa4dab5ee929acaf2a22f8d12d2cc65ae2ad872d0fa7aaaa015086fe8bf0327696589c24d7d4d41971c1b6e6d3c8b3780a8a74a1175ad7780630f4882afc0a7a4a26cd1b851ca7fd096a4141403b37c38d7817a48ea3998afabd4f56e4f695855d26374bef3adf20d25080bc3a53963541fc97964ff759970a8be41519bd31f5de6ebe27d98516cab39e64ce1ba6ac823d4beb50c074586a285337042d9d5e9c87e04d3b0e2ce69873538c9c1bc5048193653f06e7b0005e22deecf86a4dcdee3dba6a47cab06740496a55900ab5db1768d5b0dbd64c1b949b1e5f5711d39be47a9f68543f3e099458eca8a6f1e951a0e6eab47976c15fcf92ef2fc800119cab8eaa27dbceb909d9c3f73e673848587e09a31551698b67e2e23d378a763a2913985dcbb7029d1881c8cd1b5b1e560b2c3bb4aa5466e406332c81cc3bdd94a4e2158f9ba68e497a31464cb69200d7be4940a53609055668ef1439d29b4a4dc18c858d5d1de8bf92495afc80a22bfd08044c48ddbf28c94f1333f249953e149064d260aa6e10f7de70bc5bf37a4baa528b86e90c708fc231483cc4d68cc0161a0f6ad806ab1cd099f64e5d6266c728c5a28794909ee1968546427e31f5352d7859c388a8b0b59c6c3fdf108ff12e7a14ce53c8690a8195418de4db77c95eec0dbe7a6510f2cbb0f7494cf6ae49887da4df4b9db8a7bb1e8006136804da681dd19533863f240c20d7986066778dd966aa74ad921be6b8d5b658563f4199bb6d47015903eca4b9c6df467434d61bb0209fd3ce7bb19f2fd11b455a63238f082a1f53bfa1ddfad877551099dff1264f770bbc83e918b8f33013d8125df82eb0ad52f0cf1d0a6b509fb99485d15f0ed94e490937523fb20d55df0b4512e91b406caaf3667685c85983f4ff905c1970fd947a95243779d99ecc26590ca74d72655a6326a4c1eedd09ac70486bb0cc74ee548e960bf90a26e3d6b8af6df093ab13ca0eaa0c165a402aa96dbc535eecc157a6e5551170d91a00a455c844c17cab7f286744b98ed0e376cad246f31aaa7a3f213fd7a5524330e2404ea61b43d594ba48e05eee28aabe03dbdad63be6f6a970be4152f2d1af2f02820c975a966795d22b0aa814991da933ce98209e03608bf6d4ed64eaa85ea620b3994ee72277c6f345f87a717c03ace90628d507fd536ccc04e2835cac8dcb48f486f5f4613f67714801fc7e878a27771a9c69d2c2989947e418e4a4d82dc15179602a1eb6100bc392a9c488d0f24a4798c61ffd3afc0ad7fa3ef1828555e83c1bb502b60dc4417fb6f8724c0828c4c50770dc7522710ffda526d2de37d426023901ebea676d9a62ef3d12e31a6b715920eb732b24d5d74daed8a4261ad226f2aa43a9e1e933e8e6c06339c332ee382af24100dbd72218a48e3d30b34d14e3c05f4084fb28769d04a4baa4f95f9b811509b29ad7405cf1c8fdad89709fbaf0b6e9f5fd1316e606099963100eb8183b7c4fa67d51832d72aa01fc22c59bca41a2e3994a5da3718cd7a4df2009cd8e0c7307e8716249fcd8a21279fc63543395212a91335d42ecc7c875c3e3f3a9e7d6bffec13bef3c30ebfd75ce5fa17c82e30242efab9b756b7594d6a5d2ff0c07a240b27090ff5a93c441b6c976c9ade71d97685e393ec7b6d4a82fbe0515cfa0303010609689006a61d15fad3eaa0a6a66170f98ba337f5a961be804baa0478a348caa990ccebe132a1e00327a8a8df8344fedf2fe8775daa63c24dfea2813978eb082551aca600ec550cd816027b9b082caaa8ae938105ac7bb84e2808c0e214c30efb5ea5df3eb0fc857ec149c3b62e0135687379521acab7f4a0d1a53b4a0e616bdf814aed9e7ef7e89296e36a45b90feaf7b6fcfc33141b36715126637d3b734c16e40aeaf5f2c605b69d6d484d9cf647feefd5773442fe4d5ea147c0b18335147308de1d9104ef79861ac4d1cf3d23c9fc0be86f6a9e0bdd0293d9c62a5242c0f686ec27db31d8e98d9a83e7606fba80b3120496c60cf21135c6ca316430aad68fc8eb839c039a25d0f5b64cb86ba3738c536aa3b358cb247f09fa8a19345b932f9cb2e714bcafbc35078d7cb78c55c765ac3a44f773efab4dc6e62fd9a654cf55f3402dabf553ccab04c249676213d303613f6a1d0d96371e32fbef46554c02e4cde1830ea97e94b58c6be84d1146de754cccf1daa3248c50bac185b6ea6b805f2ae87bfb16a04fde471f0b0388dbb3cc257a84612453edef4395da9172c2a1ae76305bcb87d6bbc331d8b384e76d852489531dfc08ba26422d7ce1b2c5696d5e12e7a77a6f62d02b9fbbbb39c6080ee51eed89ba543b92eff15d97de35a48d62545125debee50834c5589a0d481a757edee3b9b7410ec7c0bfad79e622b03528de71db906a5b05e3d41eb7c4967189064ea5dc8a580e947440fa5106c71b3a9238ad59cb1671daa3778e0cf2ff350d521e5946e2d28d28d86222bb1846dc9c399e9836f502234009de26cf9db95187c3b75405675905bddf28a065bd40fcdc2c3c1e12d51316e0ad625557de87230331963247f925d76308ba292865ef036f936fdc911caafc20350bf209de8ad95e9362fa04e703b42a5379b4c2a0b06c536a7c1faeaac274a3897a2c7b8b40a2264eb63200a733458a7c95b20da93596f39618cf237526396cf11b4480c94bd47cb50a57f015459fd50678ee1108804649ded4b6a76062c20055be56985231dbcc9ec84acdc640c7630cb0c6b8d30ee7960c857cc89b92722bfc94b09c42fe8c1cee5a497117e8c14bf9e61e246580e0e0fbe6185d43e9e6a43b13dd5b34647ed0ceb081a4568a850e3b604a413e7a9055e8b961231f8f19a1ac22e7f594efd9d995d4bce0db4e323116bd91236e1a5ce3af32056447514e5e4112e0affe017f81436a960a9770861721ef508bc43cc04c9dd4d3b931786db6cb1005a17ccd9d4032cb56067c8694eb1166d46e0dd17c785d30c1bb0582dc6b9272933bc1bbc43310efaadc4cb75f30b40b0420e526b7c5ec1f1948ba54bb81bc1a4df876353a85b9ed4ec07351b9b596757c5e82c6e4765900b399ba28c0f757c8affd080ceef7828dea98950dfd5e036b7107eddee388ae603cc629ea4866d8c7b7ca18c59f63e05295afe30abad4ea15de67ed6b0b95e2f7a8da54483c03e7679b8b0f1798f7576b01da7256a666c952b6913d9615a37a7b2420cd85296787d5ec50566e294a2983fbb2e361a4329267e82cd6f35fb97820a8fe0b5ba61040efc5125f74fd17633987ddde791b4299ca430b392fbf9421b742ed7496721e859447d08f7e2fb8bc91cb9e215348f99d54ef40168fe3ea98282f0cace291f1cd1a37978dbe74c5138f9be38dcea1bb87ed1002055d0a76c3ccb80f63ca66305bcbe4e58de1e80f53fa70a2e1fb39b90a72b42ec810d392971d194503bcfd4771151d532f40a912962aca0eeac5db6348a9d0749505fcb8fcc24b9dca8f7c279dc8a89432b1ec631d75b597a8086ff9c573583ce31707a81e1b58fc0b16075fa847e0a78000d430e71028bf247589ae2cdd0a0492c2e9862635a94911a3dde91ce8c5774f055bbb9d613a8807c0dd86f7b3f60aedc294f6805c8df89a55a59c0186193443e0fdfe339cfffe0aaf8d7b2ce19aab4699c2763638f38f5bfcfb91c52c5517b48e8570255aad0e65554baa5c03f5855d05997c5e35e4195e63a32ba051c6a33783f535f8f29873d1c83292292d3f91744d52965507979e8a8e16a1a22b0cff825311144a8d3c4e28c9683df41811026d51dcb1b1d1b665c331756702b3c9d928ea0d8b9570b8ad1cb8cddc6538175d074564555a7f4b598901ccc65d91363efe3bcd8b1366e5f911567781f56bea2684815d8dcdb4c51dccb131b5f4c1356c657b8a51b36b7876c1a6befaca8fb8da822e3fc95f0233021a74799cc74c02ab129d410da06ae88e30c34b06340faad6521e0351be54b713ccb7c659d7bab29828d9b65496d7f2147110fa1dcb444c56c834531e51a0916dfb568046f9be5ca2a9493760de55b78cf36f818f6d0e83c93723ffc46fdc48d9ba547db4412cc0d01ca09bb52399c275329043ac768599f9daf60473390fd151797e93a5ecebb5ad5ca05cdf2bb8924e91b24d3e0b39f936711a2672493656c169f01586e9d030adff6898905cc51b665b921a634c33f158062118ede01c6c0ee0a042a9f08c2f2100b5307c5fa2f0418209b4f6a825bb29a2c5dd680d3c560711e13bf540a5fd1e369129780dbae050a2b33565e15bdcfcf44c746026aec505576ec4456af2f31f83019a16650ce222051a8579ff4d4e39b16b7fd2ea92d43c02c573edfba99c6df311bab4c8c7983af2d11b616f2ddbe577f710af0947842557b6b19dd4535afdd14970bade7cc5e8425c086317a21c55484385c21f5fb21a4c4dfd08cf837135d49b3719339824e5de1840ffd5db4a2f820713ea7e847840edd088e09c824c31f56c33db53ea25797bf9530d1cb917bebb1720e93d7148e5557882154bce4d5194f25ff5f5795d606d1a52465ecacb930082911c8010209abd03d14678501f0d2fb9783f9457c3cbaca746a7c0d60cfa0a75968882cdf2f012033be004376670a8774e9000b78ef002f0eef10268770159478a5e59349370b101d1e601f6f2ea9105fbbe8685acddce6fe38320443b412ddaf1961ff70d57818e3da06df4da1e08d3d23f9577e208ef12f6c029ed010c3712f953d36c6623ace67ad90c2d9162c89b65b854d7f018db1359aa0ff08c724dccb9b8bee472bd2dcf4dd463b86623604a6d79818cb4b640ffb3bbca9257ab6f654c0fa3cb332cf068185c24ae57e463640cd4a371d34b18a6b8b28907a06a1b98b66588d908e5c9173899c63267fa7419e47e6559955053b0a94a521e3dfee0728cd145ae19d9be8e3c276d33d8d0315ca2bb02acbf1bced1697734e7924add90296ee44846850c7e562fd0276d3c457419a26f7d77cc6bf1052979d937ca285477bdc9ae8fe5134ca4149db749e2f4b42bf2094ecf422e19c48298706198a194716beb9eda1c53c0b4f3435475f44ae042792c1b550c288349b07007ce68163c9b020eac930b33691461325920c1533668882a8d702be1fb1a78ec2ab5291ad0e16d87eff1256c7285544965a7e9f3cb701b457b7af405325aa0f911d7e104ad7373f974d9f440a84b9d25df2c5f1b0b748f818482ca858b401318d244dedca20fb1085f43aadf974a75a0a65b85f7d56e60275f7be355d35f82764fc9762575a97c8f90cb15cd14c5c0ceb1d310804027a7b2c1cfda462b0f9a922f1727481dfded58b7d1ec50f3c9266ca725d25f076f33c304990f230b24e5ce104315e019a25cd165f11184cd1ab9008d66149156977a056564d7e204bf49041fd23763acb706b707f7dc5913598591bc462fc239384e5db67d9cadf3ad5673e5d395a87639e68d667b4a7b1cfae075e909a0e339056ef1d9d3c1b278afcfe9698be6f1c70d5d20c00bc364de12dfb2f262b53dfa35382a2bef1d4313792abb9be0d8be0d9dfdfef95ef3a9b640a7154901673a64e257d09902ae6ce8445dca60bacdcc9462a0f940f022d672994ecc913c1512043dfab05b29fa833bffc5f4bd175d178d9b68f23d85fb6b11bcc61813054284c06d01555e78f5c3b7227ad82089c1f4e89d92a54088319fe7aa344424dcd810ccd7c891eda2806e551d3e2dc4feaf30b6b183a6d90ef6aa583e0b8ee15c8d1592ff16a9d76ae886d8acc83a26a16fba2b74be759620887474d8b3ca12fd01bdcfe01522355680604a09950b7eddf235468381e78262a3a2c0ff3a99030eb5566080516c540cf89f8f81516a9dc00959b365772d62f770cdb11b84082291a5b2a8ec6948bd92ecbecb60a2f54fc265278ba462554f9378cd6688d7bc867d6412af46086582b2ba6ba3afc57ca6f8acda832469114e8e4b0275a96654a3fc2687c318f8e712cc8e019ab2a1acbc2239de54eaa1d17697f21692cb2529a14c39a484ba05d075027d90ce25136f877eda20efe330b721e6b9097cb302916a3667234e64692edf9b9054ac2c630ec5c732ff531ba38fdce8553cc548628466a43642c21bed48527b5dc561176497d220e0bd03a2cc9c3ef06178e0573f3170de12e85f4f641b740a529f444484d391d16f223e08a031864c46dce355185e470ee3e5d700a680b3b4d219eefa08196251b1c011c6a39422d2d5893203068d95606639cde080752429ef0def1e22cc07f7d9b22c69932a2692af7a629c412c6cc6690a34b2c1cf087929eccc6b3a93718addd0b6c8a38bcf43ce41c538de2c8eb2974409483ebc157a8a24ca5e5f93b8a6f91150e39e0dc1ff88a1d2109c216ee6c83296f1494af8fd00bf3965aa667b92744faddc511a2840cb6f2815e8767856b4f0a47c89caa5e0804aac4378369a27f5403e1ccaca7783ee08b1feb61eccb1129620d3fa9847d6f636e82440d5750855f347094bacace505ba2e4544a406e1b2f7f61d190b904168c0373d07487e2afb42d7d4c3d81209a4813ca517922d07fe8bbb021ee32e1eccdda52f9103337e133bc8d153f8de845e74e11c6f5b0ffc18df868ef1a8d4d990946f36f982e391ae0ca86811af135f22c1706eb20da969c93ae66cebaee9a6f89586be009891da7fddc3e06c901e15a36ad368bccfde015c8603b8b695b7a1237662368081bc19cb06ca9202119de34eab19a82d390db169ddf10ab51ca0ac7c55b2c7b2d4438d504fb9b85d4719606accc3db48639ec66339514067f25892ddbadfc277daf865047d0ef78537002bf176f7c6681267bc107b6ee764d90dd6ab65439ce3a99c37e4d07aa00adc4676cfc6f0e2d61c72fb1212da1a85fa9009823c7180567dbdadc459f03206dfb6f1fa2a851263d23d50ade17d7897de923e6b63864556652caf30da48645cdd0c6e52ffd56ba6721945fa5532bfebbf98cbf4a657c21e48825d2ec167eed10139afa01ca3956188bc218a488f5cfe52391af116cc8bb528e48e6bc43d45cc606513a11e83ac90660d6b4b52c7c427ce606ee55ed694a5bcfc1dc8db927285cd875f20aaa280aeaeadfc863f2b25d91ea283a943054a54a0b8f9c25944ca6604362477280e7b31fc926d732a7084353a949e68f305036cb30d69aae8905e6ea60cc000b1a4be92805139305b8b04083827f1e16134fc82180b6103d8c483bdf9c23974ce104946f52e3b9325b37a4f0f43ef615c0593247f8044ac78615ba380ac5cd7ee8207a00cc1110f5c3edd546f516ea6a41e781d53c72476e61bba9a5a9e2b0a275b47e8005b062f50c8f8b0c65e37552eea2cf1a14820c085040f36e12b78bb70386bddac264de8ca2c13f347dc4de062349cca70090ba6e6a806b4b55cbb5a72a4a8c3a82ea4650578c34774739f418a9dda549e7a0b8db27aa987cb0c3911bb0bc858a38c82ed8ac78581b754dc2d33e4e382e7f16cec9d764007f2a8e10892223fe430118b25174f78f7ee056ce3cdc5523690636d21b99f583ec60772c39a8229113b1e0b78734327b7001eae9bc1cc9b1d0b1334777618186be0535a9528110967ad8ee15660e5b602b1e57c94c60522c9c53d261b850bdafdd1f08ae375d337183624e9c1c4a9f4dfaf34489254f528dc50568e6002eb8d390c42544f48d9078e7385d0e9b259a37ae2711cfa704f840168b6373d1943a0e036d206ab07f63190bc1bc7c71c6b9b40412fa50a065b3586df8280880af22770b3b252904d20aedd79cbb3274bca166d219cef68f1736df10094bb2e72991e7498859ba0cb0f53a14322dc586d45f0d65b04aff835041e9c7f8b0711ae231d74d6af00ca5056fa88a2f34298dc776dd95ea53920646a211168542325eb4f382018945e1a3403ae0ce15a8e7c0b5b50f93ec3eb4f1f3029cd1a4897e2ca79c49847d4a9974093d7206a54067dd7e50306b9563650a55ae9f393b795417540450e6dcc2ab9fc20e3d39958e80733b5207f5117f542209b8ec8278f34c563b8965c31d0a19f92dd3e9e0e416bdd2e63cab03524788c98be8fe0c2d5821fd5d5c0d42245240cef13084e1522854e3ac2419f8134bc02e5f04881874cafa3fb1d8463fd4df878fc80c70cff86e97568c28a747a9c5ae0287c2d4e601d156ab502f68cc1444750a13a18cfe3f3d8906adff2d8c0c31279cdd6112686c261aff2e4430ffa3644a26b70c070f1a18816fc3c9d7a156cbc89cb406750a78204cba89a48391fe688627705aa66a0feb8a9cf4338bc06cffc6d9533b733196f4a7f2d4f009dea1b980049e56dd4c9ff48ba1bcec32d1f898c8705ee154aa5361cc13ea84250f1c8b90cb63b271517ab02646080a04e09efeef97a34872c5ee4c682e4e661851bf74e50d7212e55bc93ea9ab3286379b5459f648382778a83ec233fed165b7464013df53dc49ee9f229720b77f46877392bb7a59cc4130ce8d96092e419265e1d63b4df3725f2a92929cb6aa940cc475d6abe82788668183a4c467205d111dfae20e6f376ad209db22f9050950b1465e47398dbb88af5682eaa901b926ac8a7519328328a487261ebe07c6939fcdb3922dfc8f2bc4922adab246b78ad4dd8dd6b22bbf2d76c58b659f9c471826cef9d178e00e2048641763305ca8c32fa22981f0caa89de59d21d1cba52f78456fe14ff7686d8c8a331fa021e25f569adb00ea8f4b7b05093e1c74113649a2f529a08da45e113054e65243ba83619c35b126beea3520d0a402d1d13fe98805d5d17cf4a0753022083646b9e1502975647c3654c84f6e7ba65c92ea4bcb8ece5f01a333c957a27b9cbec5c96ea86b2c0941833d9dda09d47df80d5b05b9033e881da83ed9821611c277a4d89ad5b74f7b9d20cd2ae774768c7680f115d6e4d5cc0c71ae2216fa2e105ed0c11952d24f09929393c1fd1555f9eaf142fd691ae6fe6a0b4bbb395dc26c4c76c908fb91acb05e1c38004db9058da024a7bf58b62691b2c7c6bdf14ac7cb308153993f005cfec2493c00986c293d336c8ac4a7f38213778f4ad6b977197f2858658b321d254b308076caf04d6c13adde54bbc9112f17e789014ca49d01475863a468f8bdb703c8f69600aa86378c711b36cc52c30a4a4f1bd335b4b79046d25b1437325c40e95d0daba90d12fa27d02c30c5d20d139c565ed64d0aa2c0f5db0cf75e184ef5a3892c712048028a7b28e9fefd0608da7798e342fe331795d4ea8d02515f28b7a2711c40ed425c5aece50b8ee215556827fc15152292825c28232feed7dc57545456deb14e565672dfb5951b75517694d778e911936a7f3c480e0dd5f3ae6ad422a71cb67851f70a40c8c589fe1224865a90ca154adc38fdfaf2398c89a726243d509a856bf9eda30ec3c3ef17d503b9533a12239bf480f8ad4e12aad9e57dcade651d7da29d8e44cce41ad4d651a8bf58aeaf83a24752495ca3da06b418ef3f233390f885ecf0c79bf0d4b501cade75fd218fb09ecb9fb05a2e6129cfd0613daebc8bcaf28f721b652a3bb1bec56988e6672a2111a921ebf66457bc1502ec9b94af440dc90c68c58c90dfae0a9db0247a8fb1b4e45ef26b283d70d3db8c54bf2365204cd99b76103118ee48b223a0489304daeb3111d6aee3a04e689bc94cbe8e7a393cf10275cdf7539bb91a54710cdbf7d87df9868ef5b8f03f9001feebf6517b2f4005197f71aff7d07ef6fbfc36f787feb8061a90b1f6ea67276254b5d0c6cb81942279d47bcaf82bf1a2bd0bcae40f191f28dcbbbba022d595c8259c99229d34703a22475a58f5f2790bad8ff3a026f0dfa3a5234ded210dbcdc9afbce810bfe564c80193c18aa7f22d67b23232c2782a0f81233bc1af15f93b3ee1d70a563dc68f4758f5983e1ec93a405496f9007b15b9b46d4638963ca1c33a091d94a9bcc29826087321a2f02049ea6c4337349008c7f184732325a5501510e59a76caca8b726d7b97ac18106ddd8717988ca069d4b2adac2e2bb72399ae7bce06fe15c73af45f56a65623d0d874661628a41f0da0f7f5a39a89841ffc78a421c631ddf3af6078c36810d4c99954d5821aade5451926e772282fe78ae0b06151b909345277e553d4423f2cc1f7b55e508ef1527e88d0e1a2640da5de2da5179e0dc5e656730888795823f587677070e2ff94e6fc14ac95606bc12da2cd7a1eef9c4153f3e31a835e1f56a8f88167aaae8cf108ddce391b028eebbd41e99bc071e4f9dc65e78a52f14cdfb3f8691a66b35bb63cdda469089cb091f4557010f16d1e4d13c3cb1f2dc896ab0c5067a8936a125e7a122cb1bcbcd86b70a25818ce95ab8bfcd958ae60bebea8833a973e1b9cbc68740828ae8256c45d047eeb39143ba8ea165db886f2560e66f16bd4ee000a0e3c69db053ae0291d085c808e7e8852bb50e6805ecc51bcbac9635107336c34ed2d04daf4e66683e4905c1594621958a14b9fb9a95fc19d799de516395ff31213025e663b52cda5805b5cee932d3298ddb19cdb460dadbabca26c9656933c35fdcd892c1bed4e4c88d9dc506a55fe0dac64f785c0fb2bc26a55907716bc479d6f51decbfa2614694a4abf8cb1a5629915ea40c4e3a488410a7e6f8f868cd923e732c60f77cb98cb48a67cdc1870da1d83778fb295878879a69c23fdd2ac812119c539c5ef5132a2dc69b4069a21bac6868bf1dd8a3c59a3d1acb0c1dc260bc86867c82aa7b933b95aa1d83e50b3605df8ddf22ede57465503364041ee702a9e97ab43f465c54aa3d3065261874bc95bf9919f361bb99ac7cb05da05fcdb51b8ec5f906d2c054d6de4eac989d0d4e909355506854bd0160d024b4dd7971cacad3f347437b19a820d1339972eb11f40f9c1ef00f7404eeee0e155354a306d0e25e16e7909af7a3950b22ae3ea063150459cc5b4e2dd0d2aaa3955d86260fc9daf6286fbf0946bd8c5d759cf0b2a270ff85886ca7dd6bf1c57cbb6245719643569a15c05afc1d86a2b030ea2a3dc86cbdb50de492bbf525e31576a894b828d6f024328ddcd97e454b4ad02656de0827f21c9a52e356e8f2a4a56912ebff81bf931fb28d572f25270e990ee26796ae89ada59025a0a0ddd171717bca14bbfa187ec03e786c30d152d25dc106c38a19d7e665ae7ed287e3b6dcecb1722ed2c3672b81ddca72240b3e3da07009a654200498db5438eb1de5e5ec915f9681d3d4f362187c3500c832a418a0e20a3980b4c59233dd52e4235309b1465268020433f3528dc8ddd05215ab9450fcc8654ef9b76e0b758477906185dcbf300d43761a7f99a259766de1d840fe488a3202760a08cde3e71316cb552a2dbd92790820ccc2e19f461c3c45e75bc0c5eb9c65c57788308c7fb2b2e86756c3974ac17d7b444f734b319a45893407b5690956ca23e4d8c7074f3610dd72ca4e1ba257e7146dae4451b5da58363c3a1a41e1bab8ab612f45e24474ff4a4eee42d5082f6f29812770260283905e863cf40f2d703460dac2335babe6b8a8ea4cd15e9e12b43badf0df316a8069d1ea03495513596ab9ee68373ef1ba113295616387487324d9b703d205cea4a42dc91fde53fb6febfab4d99e239d5ced330d614cb6a2247d1b5904de095ea52ed14675b9f9367afe7a9123e134d7929e7f2d128a8953c9c5f86a62e3c74d0665d4aa86e389d57314305b00363dcc7335a01fd12959ad4cebbb017c7fc54a92d95e339f9e48d096ef1786f4a0f36b801dc7b58da90eefac0ec685518bc3c2a88fab3138f54be8e8518eb108fe18615c4bd540531a8eb904125766da4a36e7c35468abda6bfc40ddc1dd99ec2181c9ad5068efa75e803aff6214543df0841ad177ca66c2a7c187beaa45921c68e15225df7b375a9050194a4102c5802a6ce28657929df1419e6a98cb279c7c4bb533cedf3589e22e7dc1d96294d4059869badc08b1c2c0e034fb3c33f67d6a431c72bfa1f8fb6c0a63fe4912c63028e0cfc5b523c5506c6d3778f10235ac8f396e149c9f13d55a744e4e32f38ab968c3633703cf4c5938c5c90a782ffb72d7b8efc38957717519a6460aa5b8126d5bd5ddcdf5ad5b0f51a03169a394c82f498295d08128b4d99e8430db64e05d53a0a4a527783be280f5b939379ce1a114d98e0d2c094d529e7eaa97c8cbcb9bf600b8bcbdeb5fe8c7a9a3a90db8524de02d8231570eeca2913ea92e6d770be086e451c139a526389d361d9559cda124dad83edc7643f2738244e3d971791bb3fcacbd988ba756e8629505e5eca47662cde940274eae82962a22404fa77e502e61f526ce08be631b841d4c0d544baadc0937281d93a49a3fa6d82e14da64c11ec21a7f4065c05821f1ec74bd02a7e73d0ffaaebea8a371b53ef3add64bb442c0740de9f9f99ec2aa542d405612e4fe6b2201cd209f548c962e0542123356422932c998adc59f92627129ae99dc4707135d8dd60ad565ed000bda7b1d27343aaadf196c8e9e44b20c0a1d26309c7ee9d43c0e488a6a07b209ca22da4cc68fd6c1cb9c4187aa31fc9a55b61821a52b95a000f606ff4470a0ddf23a842db80df78f1185d6d95c344bc9dbc130cbdcd7109cd3179e2c88a0e858e1f4146b39a85d960c186b304d53b890648c5eaf760c09e10498b1a75d68d88cd1f8394db19bcabe0ae00bdd155ba4dbfef51c09c790082334bfb18438a2adff1558b234df0b975fcdd777414fcfaba944f52e0106ac421e87c51ab5fc8b35c84aac1c7c951dec4144f646df718542e23ea94cc6173e9014bb3d51866a203690053d2e11ce11110bdd739064896e5ca1cc7a663c33611d39654fb02566cd4d458fe318701f135dfe73f771518f22df236354958f4ccf14b0a2174f5b0399e30c6054570cd800c973a61e4378803506a2bccdbf09807b1f1ce8b46c46c3919a5721432c1972e86f7bcadeb2c5d3dd47815d4d6852a85a81d516c9a8fed1579bc08330f8e1ce21e5e056f9888f69fd458b93b3ce5d058d8f78ed990e5e435e590258d95fd0aba30621cc33249cd90c552d088a4e87e686b0d92c8c31866f276091616bcdab7ed790559c486d194fa3b5b71e5d3293a69f813d2df18cd284138b5451ad1e0af8ef1556826bf84a9a632550a918a79d992c7f3c053185d738fe5638b2e3c1d5e041eb2c8e7b5ac21e058574795dd4c1e390a52d632b6be92a99b9601d5a53636535b624a22bb2cdcef50a6732e87171383530ecc791956af0402e35cae4cabfe6e015b9384e62d4042a5a4e878b745cb9d7c11abf71798b52a016981ea1ec9e422106661878a2b8f8b5195bdead157931836a7930d62fa97a781e642ba3fbe0b87e30dc922b90cc357800b6b26def070ab490b79818d69bc51c0988a9c4340e7478208043afab5a7399ed5a5fa2b1d9d0f527730c639d13236eac151a638fe22784638e4985c97da7c5b5c1f834e772b53f06059bfc4acdf1014e88e7017923a1778a51324c46b54a39b680944e9c5466b5f3b47d70dfa118de011b0c571788d95f1e0ed1099b2e138eecc6d620d5abcbd15326f1950d54f6b991b3efadb903a68326fa06852f014eda613b63e6f64575e0a4bfb9dd8ff95c7fd43a52e9e850863876ca0185d0a0e9d8d29df110358ecc781e7ff3dabf393e886b2a1996ab623d5aa6b53e1705e51a1ce08676cf89d97a5236af41d57d9cbbce0796c79db54af2ed1a16278acf810814c6037837373461a6eb2c7422e56e93b169116e840f41d78bc125eec824785dec8de49a36a27bb90a549d5f26e02273bfe0399041a94c4a83d8560f5af3324531924d668dae91a45bc157556c3345ad580296ea27fd89c6681b67d979fa62ddf190d1948c18ddecf0fe44db14bbcdda917ca20042b59b06a4d2b0e43ed14753dc49452af9e37b84d314f18c4428e5f702da6622923ce4ad46fa17af9e84ba83a082de435d9a9630e8363ba5c65022bd5b8bda08f100903ef6aa350fe06e9ce29923cbdae11d28ac9559a52512ec9a5623c18012d21684f19ca3e078fea1ba939272d2fdf37c071afe5122559b662f108f9594cdcb08bb1345bb3232584972d439ea1aef19d708332923f5dc6f8438a3718af9bd91ee74e78a9bc5c10e30d28ad45375f0c46e13356266ab45160b915c54860840451a5861eed447cba2e11a139d212547491ba7b8c4c46d78267054341162b021cb59ba3a210420f74b3b6ac0adaf9bb25cd0dba97b540e46d4ad2fde281e45fc887cf096a092954515e41121ecf41e7f5b42a50b46f5edc09827d6c72b09b4b41f60d793c7cd827097921cf354203cf8898a319f24b11df880a7a9125c4d1780ac36137ac6bd28f51f2c9d6c241dba1d33617c36f4d3c6d7dc50c85bb5b65d227cc31d36ac79e7e091dcd4317fd27a6f2b87a1a6b7b168da5df4663e9a171889d0f5b4031ae674ba767b91edd3478b57cb6b6cb47aa1c7268048519c57989de1a28a5f927801266d45c998c89519e64021741b42b028a9cba1114a94b975f1c1338bcf664885922a6f8b765c15d74f52f53b87a4ee9cf5fbdb8965dfe6ac43daff0d400be8fd3d2a3a182d64320c5e88f13304830c70e2d9c4b7fd18cace414f0d325f984a80af1dfe851caa97e131ddf398088faca489ebf42d218fb55e88cc4d25094df142e0ce3f21bae50d735c1c1e1a1b84ef05652c6d571e026ca8b2d481c5a96eaa0f41e588ae80f9a44a4db5278671457cd6c92a26316b0ec2579e4c678fd6ae84539c2c37b3d1fa3e6cdb3b77beb8b2c7967862611959a8725836ba95dca8062d10e1a58b5539406042376247316506a925bfbc24e92d2735200fb7d4b4ced6a11de115a98fdbe260b088d682d746a95834edb0b62ae4526bb953d86949416398d7a572996c89f0eaffe50b80c31af7bc9726ab7366ebf1908eb8f9079d4545628514ebdccaa7eeed34717f67d5a76d43a6416017917c34b4cd9ca601e40c84fafd8ca3c43c294811f86b20b8d7099a90e795d5b9264c8c7c8755560f26f601bcc10f19b6447c61c74606533d74454380d33bd0eb24599f386d5ac67c6adf385a6582a6c658c65db476505a34ef1c617b23ae4f022ae0d266f680b5b0a7e66eb9e7d019eebf809910fd2b49f5e1c2160cd325d4603ecca2975760257e9d4299804d444dd6519d231b430e7365e0abaa0504c9af315d20f9c4058840ca5b0594f50bd6b5d71c256a2b08e35ed344cf23eba4391a685aaccfa116692dadce15eb801dfab6a52d1da91b2e1a4ac76eb1e057a57ca5ba8cbd92ec7bfb53255e8aada226679c5f4191554cb7416954bb8827f2e2f21f4b94669b856ded5fae4aa3e5c904b68d7773e0d56cdc6ddd50866bd41578cd1fa5d6059459228cf0185a5562c2c867c63236871862ea579a49bbdad15382241a35ae005e4905eaaa0e34d281352844cf1acf0da681720e1b684f7b74de063c3f89ac1ec1477a3afd99a7451f5285b632c4fc00e3af1955e8d82bc7128f54aa9a208c55b52a38242126538ae403e62a91d44fc61a45c435f0336a97417520b666461612a9f25ecf1da126fc7986318df50ce81d4763754c1250c8eb391ca698729e33b64c05b6415848bdde68a541b6140341cec457989d79794460a1ea07ca68b23c51b00555f75f142bbe3aa240dd1d9d3c853e087c7f7d62569ae046a7ce944a676be96e06f6b8a8e2545a418737989fb04502db837eaae04e99aeba7a8be2e5a1c33ea5f01f95d832ef9282c314bf2106fab1d6cf16afda2bc44d6b535c75bf57579bdae8ab2d7b4967d94da4b3e84b17c41d91ef20155c42bd5f328b60e308903689a06b484c19cdce0944e38d1aa41360c0dcd42a3bc77830e9c0078cb60bb782f78fe8df37473145fe77946f62e6d906a85325e1746cb7c778a57523dd23ea6ebf9a49602f728f03169c784c053bc22b63d5bd265240639f6d20bed84bcf571a0086c053da61f4f2090a099eb5fc00d392738a1a68cabd13995f9420079aa1c5f0218f312dd48fbc08552e8288f56ff8e5bc15b12271b70b4e8650a94ae7e6c42b2f7eeb72ce978a40671b4cd6141f6ae18946a9363d95335d74b172770e1c7ebb19255a49e55c50de877b22ac8d907a93e954be89e0627245d822c355615ba66c3b0e16a8cc74ca50a52cd9132adae2ba2d08bf88ed7b14303701b5a018eaf13cc44bd54ee057a13a433979aed6cf30ffaafae74289b22304435ba2bc7414ad99190d090a96989d9806a6398921a2f247ef66e04e090d910042fd58cafc945f1123128bac5eb916ab9fbe4a2745f660b73e7f2225b0c778d179de3ce6c01ce414974bbdbd9a845a05a29a00a450db457d6ecfebb13302518ddefc945e9961ab8be01a3826a29b3ba918172c154a115b096ebbc3b7e1bb3bcd68c45ca5c09c382cd52c33ccc8a358815c52bc1f02636dc96b5425ab33dd237b62a986ba1564a5901bf20de095db30a292d6ae8e626b50ae8b35b3b4d992861f4db194d542bb9e84cf6849b966d10a6a614a5ee9529c62d0f914da86d8735df9a59a76b27247cf083ca6b780136f002de72d0dff216372414de423a0c096f9a18b7b12a380fe148b1b16106131540a92dad033c941e83dfa8ccc3dff953a1102a4ef137c6a6621f16ad24ba6307b0e360241f5a4af22735dda21c6f89ffb6dac1ef8c2d161a04ddd95f23bdcda6c2e08906607c1aea31619a26e89a50b3dd4630c79b61cd5f0a5e196781e4bd5501e9de92f6e11804dacea6a0e0cd794418a874bee0dd6b58a0d18d00e64ed1ff703411f75ea75c4007f611cd3126fdea1c17f09e52032fb6aa15504b7852c0e5b632b47d300a7b5e427d1805d8d55cd4f5cff1fac8e60843d46bb6179857c4a30b53622ba3c129c292a1d6bfd146c231e9450405adbc350b89b77f49a081e688da29dd1f3f43d61a8d0f5b6498709ee76ec39f7c700c88ccfb02d290d46986cda277354c112fc8aee51668389e17158fea802945ec23daa6d3876fb40a4eb8e6d1ae9af3aff08d966951243e04720e78f5802f4ad8b3618ce793573841eca4e55d15e17e49bc98ed741718438857add3fa6f682da05e6e67bd07ac8708e2949a81b07e042e5629f5f006d56d9f50c8741a8223d67cc7ae2912f1f190ac5824ca04698d0a3b403571a60909f3e21047bbeae551635cf710b52c4eea7467cd6384d5c3e545a919f459d9353d26661cdab63d749f1415ef1480a4a7e9a8811c91871c7c03d01a8d3013c1233c60ca4b6f680552717a00178ec9d44293cd892ec817549e7a2c6d15111d1b9e6ac047c711264ba8a3acecbf1e130d2d2de4d0fbe5048b13d1f55e730ace5fbbfdd0eb231d4b8f6e42af2b152c9dfb162e3da3d2d7a1d76b8316b715864443ef99222d5c012959d9917fcffe3ed0a7daef9f7f5f6a46dfb40f4fcb47a5de403b3d3e2d1ee58ba5bca6be9e1c8e9ddfb3bf3be6c2ee698e621aae66b8bf7f7efa7d6fe168cc716dbde7eefdf16c3c1bfa80ed5bb6d9d31ce750339687d7ed6aed47edfa9e9d9d9db13dcb36fb8b9eab9bc6de01fbf3d9606c66f61753ed505b5ba6ed3aec8cd9da7ca1dbdafede61ae377672b6a6f6dcc3a0dee14c370ec7cedec11fcfc65f4c9b3adacfb4d3d796dad4b4669ae1fa8d3c1bbf677fcfe57e633393def371fcb13f5818d023db1f4ecd57759a6503b5e79af6862067ccdd589a39607e9f7c84e6eb58ebb97bec5ffff23e2364ec37fe7561f4b5816e68fd3d761e0799dadf3f609f431d601d6cdf830a7ac00f87eaaccfcee961df0792da40e00f71706227cfc65ffbee4877b24c18ea01fb93c5d69437b3546d3632cd89a24ea7af6a6fe27ff0ebf2af0eb4801ff87fb6e62e6c2354f150b5ace966df584ca759a6dac30587cbe12bc12bfce5359bcbb1db91ee30dd617dd3d0986b325b1bea8eabd9cc1d696ca6b923b3cf7aea74aaf5d94a7747b47e7c60d4007f6b2e5cd6b335d5d58d21ebe9766f31556dd6d72ccde86b464fd79cc3c8381ccdbd14e065fb3dfa151a99382476c67ac1b48486e1b7aa3b926dab9b7dddb0166ed21cc107a61b8eab1a3dbeea509ebdbdb136a014df03aec931e2d035bbaead1bc343deabd72260c713a21fd67dd9db010d369a004e2ec71ab513b6d2a753e6f289633ed232d5e833be704c7518f5a40f98eeb295ea187b2e1b9876a8211cd36f67502965c4f495a3f32f0c14ab7c60a4b599e56ef6cdd77168b09c5a51af43cd6daf8cafb66969b6bbb956679a132a2a00bea30af47038d58ca13b0248f31e66037802c10afee35b6bf247f8ddc0b4d9fe84e9068b822c826ebe8e0f47aa2300b13f39482c2d403f50a78ef647bcc85fe1577f250eddb51762ddbfd2a7fdcec39af7509ecfd2d2d4fb2cbf6311af17b357cd4e6f8a2865d0e29e0135f67e7103617f3bf1aaaabada4f6c675efc1781e15577803253ad7dd5b6b36c608420e178656bfc60797ac9325d5836c02e9d9db1fc1f4c67ffcd54db269cfd8365327a02de3b87d6c219ed0f0cded393cedb3b388823823001b6e6a4421ce0ecbe9a65af49f3179ba6309ee36441e5d45eb4b5ab19fd780f307a3e393adf5fafb1d1f29d2540f80a634dda54ea93fec2ced8eb93fef247eae6f1e14a6e7acf5bfebd781faa8f1bbc17ffe18f8f37be54a70bad3d486c9bbe41d3f43bad655a133575aae184d5ee6e1586089ce5933c53dd2c9b9a3d75aa65899f485a69ac7bc5cbb5edbb5b65770b59204107870bb7b79fbef47d6da02ea6ee57d576746378315587ce7ef4947bd098a1697dce59f435cd62bd29f0199ce9c07d7718033532871a3f5384e7cf485bb3e1520b63e168fd5b73a2190e967a7a492cd200929152c45c6af6606aae82be3e1523457a23d576aeb481db5e6a3614c9474af08336e8250d60dd58aa53bddf320d7784a580594b2c74018b943e7647b31b585275b57e5a878e293ea694b254dbd1fa9c167e5539bf9c304933cdd6fbba360b1a4a80dc1ef48a27c5e23bbdad346dd257372ddd99a96e6fe4951236482af20db530e2cd622cc7ecf087356067c8f9c4b6267d4d46e29d34176a46e1e294ce3167deb1cdfb07f650a0adfc73080cfe829db1a4725ef3315686ea04b2c46061c4c6c681e15208b19f7cb71dfc112f32d50c76c65c8f91faf7bfff0ddc41028f8474dc3fc9a69af107d3339954960968becbb9cdc1c2c053048520174fb52c73dfe5a0224c50c27ab0280565e9fc573a22e9ce3ddf39c908441f53b1884fcc80e30c3b4bc0c88439c7fd857beb0c5613a7071a398cecbeacb0ce717e4118adee31f8d113320904ddb93657342cf69bee5cabd77ca87dce69dfea336dffe080fdeb5ff1be10449f44fe37cb2716fb0dcb21d9de51204400df2ff780a46257c92835d95134a0d1eff74cd47747c128014e2aba4f657deaf9f6c6f623affef52f113f80f58b334db3c31f09c7bc5f425c5ce1210924e62f6af8500389ea9d1ae2791b92c4dea9f7aa0f2fcd05f6e18bbc71be2e3e6c625575e7c236b79c709144fbf6c67e8b7cdb9f251317713f0b7393ce55f2ff92644926ecbc0f349378841024ef307b8455842931c163c6ce02ae70ff5abd16f73b9f35a44dbfa5502fe2dde3842b8bab95720e264d49bc8dd8ae384b906be33393a0a2fa3a5d0c75c361ee487599daef330be5135d7398333217d33e53a78e099fdc91c626da868d345b63a0ff62c0761f64fde61c93ad34d6530d6a67ba21aed45cd88e365dfaca2a986150777d0d3a3c4315dc61c287a797b8beae675a1bc53406fa70df35b36c609bb3d82aea598024cb21fd232a6bfc260af9bc3a471da905bd23dec791dd35638538cf9054397985d33a4ee92a68fca79a1b243737f09b1bfc5473d3e4e6a67e73d39f6a8e886c629bf8cd6f181f7faa75779b40a478d3ee76e6b7eb6e673fb73eceddad92860e5c6e0c90e0ee56f9a9a6cdc1c0d1526603bff98de3e34fb56ea5a00270e851d2027be8e7300384db14f4806f018ec0e32ee13fbaf17df699e5631d4455402975d399694e17d859ac5e5c17c2809678b8fec4eb2515894dd0524dd836c1fc6043ec8c4853b440ba363389b6bb6692d4b4b0fa70d07db5cda1ad3968a241e6dd27d948b1982f2391ee20426bb1d47e0fc86d68502215063984ca0843e2ef0f7ff053cad056a00ca486f84b4f7d7ecefc7701b7cc3eb38493f73768d0132e12702fde5fa4156136f921686b4b3e07ba31d00dddd5d8d4342d2e66f55447a3496ce346448ec081861173422de1dc39876178e3cb70460b11033d61c51284353c2645c01205d11dcb1f998824d18d10236672208c335fc7a276984a73ce9b7f118c22e6eb387e647a6c532a8fa6be3a175393ef71d483c724487ccd45a5d824e672ec539e7dfa37cb27caaf2dd51d1df6347dea37fdf6e6ebee59aa9543ac3de0a079d53f329daed930dc7dcf5a7861da8aa9d93ddd8c2bbc7bfc83d647fd3d3b6399844ad9a8e4395d684009a30435dcd86f244430ddb900440f7f8f6f24af616f3122e5dfe137a17602cfd93367966a6bcc5d994cb56d75e3647d3236d2182dac39607d7d30d06ccde8694e8cf5832640bde3ec4323852c3656ccb2be69b88a692c35db8d4d2f2a66601167ba4155e9acf05aa0c783c834e3dbaa3e18782da8af4eb805f66977137c447c1b46f59abb6c1ba91a21bec0fbc258f9ca22344ffa0b2c36c2f2a4bf70144f929b23b53d2ca5360ea011e12534957ca6c1c832999f91d4703232c2bca65283956a1bfb336718a30248099d8565710257d52c5beba9bcca836a1bba3114686db2ea80ec6e3dd3704c727210bd1c0ef8b4d0c7430e456cf0e2c7fd3d0102005a37869fd91ecb300efc4708459f1ad0f870132d6203dd76e0780cce86d8d492f419728b88230f4e5e3f00f95235fa532014c9422df3cf9e78257288888c93c53919909dbd312476c147a9da435fee4bf99ef02549a3eabb68bccb11f2ff547bc8ced8de5e42e31ef084327ebb6044135c6752dbf6dacf9cb1bde767e389e385ce326cef85a5f5171a1417be7543e838ffb2b32fa13f5e35c3f61017c5069e26dae6857fcaee84e1afdd23e2a46678e84cf59eb69fcfb24fc5833f38a5bfd166e65263aeadea53705f316733159c301c4bed69c96d269fbe893dfaf39f02790ad41cb7d01cacda316c4da9e751203e55cfcf86e4758e331ab333f0992013af3d740e0ec7a66eecefed1d50755e679ff39035db36edfd838343c7557b932458c4ed9ee4f990ece63030c84d0979f2989b12d404f292243708bb9b6fc23fff8a2b5f7c3ad5d567d654db37d49986bb3f9944ff049549a7307e1f3b445411f6275e23be47fcd3243295f1aa898ab5d0747de0000a2d5bea6cf8468618237e413f7fc257c3abf28bfe1a5ef51d3e1b5c184a1207c110031ab7049e868b54f12a2c10c6f16b7c4383e12b98085e3a990de1e88e4e0dbc4c74aba45216a8b6f70308725ae54494435113c1f6e1ff2324135e6986ce4523d3eeeb863a05330427866aafa759aec3c60bc765aac7f672fadeefeb2434841aa21219b66f998ea3bf4e3707cc711703cebdcc788b03db9cb11f7d75d31e80e9a78d3d7e556d473b0c3575dbaeb63f7be4f9f9775328f8fc3bc757740bd40d66686b97cdd4b169335b9b6a6aa82512b4133bf4868d42f88d36acadadfdf094eeefaa7f88beba1c83b19819ff78c032f1b5dc7b03ea9a7b7eeeff59c816ffca1d78a5d31d90347ba8a112c3d9e7820570c5037d9865bd913eed2bc9788ebe49c46bfdf9579689550fb2512c824d0088cef7414abb2cee072314c53693511ff708d9a5454850d17480821f7d17daa4cf3b6cc68eafaafaf3af94939626c12f1b9e0beae2c375e3d0251dd2b89b41cc8d96dfc9c1460715ab9dde594a6b7d6daab95ad0e8cfaaf3bc9f210c0921d33b2812c659c0915463e16f3b512bb5da2ed44a9ce65c8ecdd489c69c85adb1de4835869ac35c53b430f54d63cf6533b3af0f36345e22a1f1e6c41513b69cff7a87d4f173be7de0c8a5259d6da85101529f865f40aa1ccdd794eee01c88a377fc235f30c5f2f7a1b6f90bdfebe490aab144c4a4a281ec97e4804bb6315b4b14b282e37a97f3ae8047e6eb38d5c99089fe97fa07d8ed648e36583296e473826c2bf81b29ea5433fa2a67a944ef1e75a655d50dfbccf69e6ecdbeba61aafbc2ae6ef704550c3fec823233d3b6cd554ab1074d9bf072fd7ebfcf9ee265a6aae337f5a839ae662777c9cb796d3d5da98efbc2d29ae423a8f1c5feccf6aef668fc0966516ff8fb136d93653373966586b98a9d5ee6c2055f638f87a16a2810faa7aeff7acfeb7e4fc416df54eff366d8ec013ba70e90cb0ca0f84cef772ce095690cabaaab9177486819af6ebb8c4fc0e8f36cf6d9719824ced0d52df33f46be30fcd26ae5aad5dce3e3e363e8eb95f7b5d562d52c8b7fbf8a7d67099df07284135996543875d1a6e121f3a58b2b7ebce9c09509578165cbc6b6f14c75ef2c0bc48bb45a87ae094514d5d1f60f5e623a64eaf6ed8dfd263498165a8045d234c3a990738215347e686bd654ed69fb393e896fadd65bb5fac667353714fdb6966a9c0007ba675247144234f820495b960ad50e1c25ef0b708a3f637b9e33495f75b5bd04214e289d1860842008c576744d5c32eff69f7d4f4213be5713f96976c60296380ea1279d24995b423052417f89380c5916368524417da34d55575f6aa4ca10ddd9172e67113eb33ddd60ff74c41d65a90efae6eefdd361ead00c914378afb281b6628ed6338d7ea8aae340b57ed2b719559de9c6c2d5425f66540b3f856a8db096c146e6c20e7d185125fe2154a54f1df5d54de8759f2af4d54da87ccb038caf5ee843cb838b7f09d5d9509d8da686a0da6ca80affe0a4931e5b5c185afeac177ad65d0c06fa1a7dd78d6116083d5fadf74e13b1d127ac9c706cecc7cf8d03761eded0f8fee3707d4eaa1e10947ff6737a2abafa73c2f10e1b64fb7d7d30c832ef58db4d9343c3e615d9bf599e9db33dc4f13dbe22bced77ce506c959fa1f8cb3f543fd30b613c0e1f0f7d4fda7eea54571d2d4d8da7f6fb7786ee4abc10db5f18ba9b65cec8b4dd916af4e3c6337385e7043b63bceca16b5e79af429eddd4e9935f8113f8d84b96617bce9ef8c9effa857a485d2183cfc354df6a1c7c07207776c455c177547221caecb173bf57f8083c4fe84d78742fec73ccab720758c8a92370a0622387b2e894fa15287a822f5334e8c12fc279ed685001ea185264c8b49e599c85178aeed23284816167d185809a29de31e1baa9c242644a9ec2d5386608b0fe9ac01d4393489f491bc9b275d3d6c91f71c75efa8ae536b49ba85a989d0bda025443952396db199541d5b65a5f40fb76444603cf1fc4f7b068e71b92161c3712eb3208e6e1c80fe2da9ffcf767b60886f13904fbcb5f29aa786cc3316d573042c602d98405500fbd1ed827f67a18990d1675b8a75ad04dea8c6d35dbbcd0a753fff070557ba8b95764ec1f98764febeac3b889557d757cff8bbd3d9609acfd7470443621efc8b985bef85120f4c23e058d795e06e1ba8e3e3440f90ffdfdfb2ce489e29d9350e81c787104999f2919384ef6f8a9b0f7692fa60b05982d73b55fc867c9e1415defe7b322b40707be3560ffe0d059bc3aaebd5f38609900eaa4ad808790ab1b438a0a3b63b9fde7e7a7a7ff797e7e7af9afe7e79783b7fde7e7e7e783f3fda7cbd1cb6cb6ef3807e76f2df3add53ae7ff7bab9a6fd52afc73ceffc7b9fbf3fef95bdf3c7f5b3d996fab97f3b78727f3ede1e5fcad639ebf3dc27f6fc1bf6f8f8f6fc3e1fe70383c3f387fabd7f7ebf53affa5bdd5ded437e96d343a7fbbbc3c7f9b4ccedf66b3f337c7397febfe59c89efef5b67efbf6b6dd9ebf7dff7efe7678901b8652048093e2c54f8cefeab6fb7675fb767575cefff736fdb3902dff156d1527cc3bdf2304242800bda594cae598cb3f7fe60f7bad3dffada5f6fb5a9fbf7eda6bb5f6b2acf8e27f2366fd33af610655bc60ffcf2c9c38019818e030f7390e14bc1d2d92b88b0052b60f10650984acd75d9625661c80712e8c5e3cdb000b5bd67b7e5a02e1bc8e3b8062533b7c1c58587679f2da7dd98f290bd30d8a30c424efd3d87a3d41d1178229bd459cad8f3589659ff22f2f1f1eaa4ff578f1142bb0b7644f8517ff6731ae424d1f03adf4c70641853f3e04c0437417aeaaaeba7f70484dec1e132ed5fb83889f143658c2a2db3ec1e00a4616fef610e2a0f6739c2a3c3f3bcfcfdd975c9c6312edb301cfcea9c8dbf3f3cb3f72c32c27e03b4322237539d509574b8aa79fd058621245f4a083141d9eee85c614a5ee07105548ce333156133c6dbccf8c7cce02571b74604b75bb09144c119c81669ef497640f17efab0f7a5aed0f5b8085165390c12bb1dbd0105bbf00e36791f81416159df7f6c2567396ec0db8d387891acb9c89f2a40f3a177ae8b7a097f590e3b3fff1433e26213d2e4b52cae7729e80dc575d8d2dc0ee6d80848c6f127dcdb10a799c0be045b6e16fb31d2ee07e3058888a08fab568207208ab51a4d7d6966ad079b7ef05f3875b3cf8235a2fc0417c0e5034fee5ed6dc7564d5254a6341484c326e590481804056dc482a5d8193b0aeff0804002fd096be653a9a4003276751856ae7a55dede90bca52d4522337638551db761f4b5350b33cbab913ed5f866f937b93927577735c79b8938def88b1fd1b3243695dd352d5132f173630124679fce58e11d27eb90be3dc4a403312ff8ada1fa37f787d8432e473ff2ec133b8d542d46aa466a7b75f350375ab914a9fc67e92fa132d5cd53dd68e572b472395e39ef578ed63e166b3f653ebd9cf3268ea9895c8e7d3a85ffa876ac7ec1358b91719fc761a7398b8ddb35cb91cae126a87ad07fa48123d73c4e6c2068069a786f08a5d00416b2c2fc47469050b91ca95c4eaf9c50fb383efb852cce7fe2ec475ab833b8b4abf5bdfe33219c0df5af1b8348e52e550d75efb780953fe9c6c0ab1ca94e513e58fdfb1b6f00e7fdf339ed80a10e0b90c9e73f7304c43f19c446f8d7b4d9f7285023d376db5e245fa8ddfdf3cf5ed307e742e3bcb1773b897473abcf34c755675668ecfbcfcf871e0a1c10fa148aa5f2d171e5e434f87558289684635b35366c65da7dcee93377651e407216b5e76ab6c37b477585c374a3375df4f9b1eeaecc9c3bb2350deb811489decaeaabde3bf45bc61a9ac39c9ee9baba336243559bea3d080781aaaad167a38d35d20c886d468b4764ac0fbc201f66fed3e9cb9ff96cf1e8f8afa73df5d3f6f97991cf4bf94ffcefd1c505ff53c9c363b5028f17a7f8785155e0b17a818f17f90afc29d063ede2e5cf02b4fbf6c45b39c66af963de4acefbb6fffcecfcd779b480f7f500ad6d7a48d4b7b5a1b6dea544bce105c20236d4f13208c1f788ae1b9a0c045081f7b3b1f4391662a2c8af3b5d4a4914f034a929e3bcc2fc600dc1712e3eb2cfd8cf2eae309a6746839a17a61d1e738a038ee8be44e3f624bf34d80507c485a1393dd5f2f810aaf7ce191b9e5e3f76d1cbe7e43d135795c0042b665f43efcc91eb5a9f7339f0f6f6d27d1cf6cc596ebed01c60ea72a5a3e342f9b494d39d4fee48b3b54fea2700c0fa84a07ff2e6ef936e7c1aab4bd5e9d9ba1565a223034db48d40b33528b6ef04065d2e62ee818419163bf79f9f9f0edee8d70bfff5b4fff43fcfcf2fa0143b787e7ec18f870761333d6c58ad9f655621cbac629659a52cb3ca69ab6515385f6815e1df12fc5b0ea981d399ddd08092461c8c32f7f4e9f91986f53ffff8afccf9e1fe01dfe62f7ffef502d235fff08f7fc5656c48ffe3e90453f62fe0740497d3f4617af6632a316867b73e8c8a3042d374dd8d9f8cd087ea7ddd1aa53403f9708744ee6bd8981737869cfec7144b51591706b2336a07970247ccc5fd54dd5b4280691ff2de7c74b142ebea954c9e1f8f2278642921620ce8c5ca7718e7bfdfdee2deb51e245ef37ee96817496692c421731ee1d68470950bdb9c854613ea2459eb25c6f50a74d8257128850c8babf4121d8bba6b2c09bbefb126dd08c2127fd56a5fdf5eb24056e2efaad26d8d9db1a2f0eab27dc76b96c49a8deb3b2857165e766b4afbba4ab27050f2eaaae17f3916be3cd46a4d76c62a915755e9919db113517f7fd1be6949b7b78debbaf732ac4fdfdf7bdccbb23cfc3f4551ca5bdf78ee061b4db5f713ac621bf6df67c05db373345f812748067e79c811e8172230e4b3ec69eff111ec08bb201155b50808fb272be4f31fed00ba60acfc92a506f359b6073e2cde88d2ea41c5a35fa8c72b1e63fe451c5a50cf5f23e9aa21756b5d0176df3f621f8bf36ae13a5f6f1aed9bc66d2356cd37057b350be17ad24d378c0c01eb87b800ff09828d30c45051afac2fc06649864fad40557c898f2a947754801abe9047158e7755e035122bf855049a1a2cae57f9250bbb5de84128ee8de10367149e4dbc29df7940ccab5564e714960519c26e5766551feaee23476a52547d4e3acdfe4a05ec57c0da0dc17b5dfe4a8fd0973faa2c2be40fe29b37976397b5abafb59b6e3c0450dd380d0380e4e89d1898e65c69aa25143967a5e363f699958e8f528fa958a578bbf081fd9395fdc4688cde14f279cc7300da45af583e8f051378f3cb76bbd90d47f3c51621ce0a25924201455886b313c2f3bfd9f1093b6785d37c9e7d66c57c3e98ec50369676ab767ddb150fbca1e676350f8c993ad1eaf0627fef62319d3e225d8194b2716674a8b90d7f3293e9b730d90229df6d5b42003c77b189a659b150ee98f103338525997f30c9c4ae801d4773ff51207b1ff689ad2578fda4644611a04ca8241c651fb617519da1df01076c9769689714ccd00e034d24cce2cc144c1d51ff48fef147ff696fa8b910f736f39350f1d3ffee56f1bc4432d0fe8b9754675764e73f0a0244de6c4719c23054fffa9797ef124b272e356f0e85181f77312acdc741de28a120ffc21f3d7f045eafe0bdec830907c9f7697246429a17e7a3f3027067c52eb344e2c0973ae1fbc13b990ed270e7d7407b3fc0e9af744212ac2e488f756ffb86a564cf6b2cd1b9f28fa814e9ab98c0b9029d2853753042997772000bdb10069438009ffe3869e81977fc4c4bcf101bb5e8bb191b3b8bb8036e21fd62aa735eb46a52860aa1a9777354c03c0a159ef497434412e82ef1d32ecc4944d28fe2c1cfe2420a3e7c10bd77e048084366667fdfc8b2a88a1419877d83fd937fcaf07ffec9d6490a1edde86b6b48268fef92324e539930dae1bb84bcd3418bc9931ed414c2f692f25a35d8c43057716c7ccf6d003d6a76dc90e08dd30fa03f3b63710822b319ed957d3498ef53e1430a6291fcf253218bc680b86e020e1e6416dfde18e55d86a269f42838012350626652ca9d7c06c8042d6559a128e228b0969933865fd927bfd201cbb142312e95078dc24176cec18e71c7c553ce1d9ef0337abf54105a65ff6415f64f564c522fbfaf5768ed6503efc02c38037e48b0177c01df95ebf75ad07e547d91e0bd91eae585a61e30971157153843bcdff9dfd3fb7b1dbfa723a0d01db6d74a54123ca6aa08bc8a273fa12368a1dcef8bfd29c278ab1512f6dfd30ee054ee301425cd27397a084b084dfa759344d848a7adb014fbb39deee82f59dfd082656aedbdfc84f00cbac6a87a9b7d4ad91fe1ee5ad4e1ae2e77298f9134215d0a1b9d6806a03bafb99019cdcfb92bd0a55c8e13cf95c6fa7a1f2ebfd28d3ea3d83346b976547b0249f9c05b4b75bc40c6c3a828c0aba48970918983c27fbcc7824433d392563a9cdafe2cc97d28be5fafda8a74550b09d5004df747e3fa07124f76c672d527b3fa72eefb793f3fbf80abf7dbf3b37390e1ab769e8b075b62b6000087734c7b5f5463a1da9b1f17daab0d3f5aaadd1bfd902c5b9ffe68a99b1f5f1686f6e3cb62baf9212d860bc7fdd1d52c579bbd6af68f76cf35f9df6b73892faa5a0f7eec1d3ad65477f7f77ef84a4e2172580060a7bb5caa772addec86216c8849fc2c129fa36175cc0fe6c5ef4f7b8eab1a7d756a1ae100f10487d60f74f7e4cb582fd19e43c5428d1ceace851fab1c5de08390df1784e4c14f10b544d885ae9378c384650762476bcfd79d2f395f706fb9f96af3c5e62bcdd798af2f5fda8fae2ab6ffb72d2d34179d70ece39d458642ffe14aa7f7fec135c7b2d1e5fd1b5657b8dccbe84f353c4590a242956ba0889e0b65c23d1164cfd5754aba309df63c72c7eb4238215fd5e490c920b1f10f819827c9002e5d2b69982e5b385a3f7daebcc0ef58828f20e2bdf591821096f94ec9a8c45128a60b1a33337cbbc253319fcf6759dcb73a1d0474d50e9854e21a61e2f7f60ede99ec9df3106bfa675add75715acadd22429205d05370fe20593ed3e1c4035131b8f9273e37807a3b149dba0e2af24f5c08d175ba64eac39acf342822b3f8b700f11e97f07f377520667a20bf2b177f4030febf9ecaffb5f5fc3f9d99ff15548fb38f09f95982f31849e0cf1d0a40413ccfb830558811ecda5a4da012de4dc4d1c349bc022c1da4340fb70f9e3aff4f1c2a2138fd9c856abfcf1cd376756318fadac577609f7230e7983e60a6a1913cb36fda4c7d7db50ff8c9a932cbd606fa9a9903a61aa63bd2c2d7fe3a9ae67582392b67d6c215573f289d74ec25e96ebd6c685c98424f4c92bd2005da485d6a4c77993ab535b5bf0957fdf069199c31608e493bdc52f5ca2927a1e03eb9f73f7b2c937c34faee8387e83bc8326cef1ffca7bef7b3a7faae0e23c7fc4ff49a9086fab7d86ccdde9f295cbd33963e171c88b7dd80a7cec86cc76440cfb1217f64b09c6bd41c37c0be5d881339505b78177c0a7e20e3ed139e9d3aff28ed173238a6f62e749e802c7f53ef021e24adc27fd44bfae1b2cb4aa7e140c90c1bb7708128eae7798adf6c1532ce2611a36b939956e209333367bb4e0bb2abd1d510bb1c5279e9dcff3c3ff733ffc8e114a698869970d504aad5922d42a92c8c57998f3a41a58b425caacf807fb648781430479f6a86cb06aa3e5dd8da7932cbf39bef46bb6354a9d32a4c6fca6368e283a5162faf080ce1614b756044f750471cf64f589ff7a0bd3ddf361e8091e075180c30d1c7a1eba374b2bd76b71b88b72188d1495ccb54df0fcf3b266155223e1f3b6f7e097c3d685e3e74a1c35073abc1da24db5ac4c513bc70b22123ccaee46aad88d61d3c85284c26aa5a8a6ae8034d7bdc86fe31d6341a964193f44350cb275ce0cdc0153aca5905ecec07ceef44c0135638a43bea06d12a3febed136b2bb1958f08ade9d315b49b3267c94004d72d477161f7347e6096d04587a27f12a8e1ceba9fdf9fb4242fefd0583e88d2ff9fc3e6bf0791ff1770f8a3e89b88b9bf88b4bf88afa9a8fa1e9686eea20aaf7a84c8072567d69566dc68cb9d99b05e85bba40efdac1b0218612e10b8e2afbad6a354ce59c8251b7a31d3d75a5f7c1359cb6c8439f97f934c2b0c0f5392a58a54f1807b6f1a621553eb0833f5f7544a07f1afbf557dc1f4f045842b7d3a457a09abc3e742b399c581146cb7e2e442ae361f43454885894c2f244e427aa98f6296009897934588ec0b7d4c5ff678cdd0b794c58882582c2783280c38de51f863aaf62d891686941ffb70759830b5788fd01b72e7077145472a73b08bb4a511c424600464f86958de6b5b44c75d8da7dde88de995375936cbb27e968db2ac95654e96cdc25eae90008d5328bc790592491d30d7a456980ade0e9f431546ae6b39c981bbb9c249a1543e89cae6ae1676b5f0bd287aa6e1b8f6a2e7c2952a33d57230432fcb7f3a3de560144ef3f94f053fb502a3e376c3f74b1e631d20c549123db66ccdd1eca5c6a69a6a51bb9876476583c5740aa110e0bad6dbf4a61a973034c8adafb9e1b6fa98d8dabf4075c332bc6ed2dc263b84e20593bc99c3a1e67afedefb69d707f2728e506ef3d34eab3188df813529d2bb9f90793b826477b70ae15982422669d179e9432e5d8bd9c6fec655176ecbdb7d0d59fc06b0bf1b6938184f794e0c095dfed8bd44ded4504637bc41102e4cfb1052dddd2a1fc52bb1e87f8e5a6970d30cff0a96e572cc7155dbfd640e3ec1956f9f569a36619f82b77c01221809051f346d42ea0ef491ed9b2bfe4f1c3f73392634dd5737ecd327b61ae9bd111ba3db127017d395ba71988eb7b142050615f6cb7038ea8e996505f809acc74178ae06ab3e3b631596e170b04f1c906c0ce3226080ce0e3a0901157ead3bbced5867d3153b63fbbcbfd0fea4b9c867799903c296aaca293d876975c0fe0921bbb1c5f9846d666020825f9fb050de61a019872b7da25b5a5f570f4d7b98e34fb946b7fd83c3fc832ff3ff4f51a7bdc554e5ccdd0f155efd18ea4bcdf8e18eb41f1cc6c3a282c531a5ca0fd5e8ffa02147561bb46f1c832f6c73c657dda141f2e2596f9e76ac3fcce7034d274d9a3fe9fea444566be5a3173b7b0fe1a2b7dd7a00b3335660195661ffc5f609ad21c96c08a08cd055362a19398fd093ad3955afd198d23be8eebf93e82435c28913fff329945a8b0a54058885f046aaca41ee0bdd47884618867fc7e223df8328f30188e8f7a758e31f50628a9d7db0a3770859a40bdef0677fb15270e173a833a1fdd47317d1c20b0fdb81df3b5155548aa7212ce0e69978c537e9d8095a201e422f80c639560107f938ce3ec0bea4f988a12b74f6df2cee3211ac54007332ba3e20bcd0126e9f08c60a434dc657a8faef50d5c4894a0252ecfdd3fb4dc4c18f8f32bc05de43e4a0e2cea9f93924e6353efbabb703c13f8abae236fd55e4dd4d6783aad7da3aad3aa068e26a78a151b178ee10ae6722dd00e2ff5230ca0a8251562b2f18656572f18eb79e96c261ef01aa3c3c78551ea08aee980f5e2dbfff9dc119d009ef4cec49f8eeb5c8bbf8e91c0fd4f851a4e9a040d0fad14fc478acc4b40b69211b309b1f8def78f8488b30d9892dfac5c3f973f69f00540405fae06d24053a20bf921ee7c0bf63b6182f257d3ecb0a0729498576262b887bff475cba804ec452f3d296889e3ca8d1e06f0f6123859e37078702b549771a27ca24f4c619e5cf9c55cde558776110b31b70dffc85398017d0975873c33eb363b461d367e68e54b846d15575c3615f54831dbba3708b508e9a042694804eba988cc37cc16bc1a18df3951a50e54f4e2a498c36989e9a203cbb09a426cd7b02adcd08693c5b83476c3da558c861807f88d96b42b72c9f5106a4736c848c066abfbf4f2992906a1eb0ff62952cdbebefd05a219c8d6efb03a00aa888b6964296954318f7bf00e987c8791fc3eef6fa4093fbaa981c2756b6ff1fc6e891b8e2b474e3672304fb7f5be7bf14a0d8fffbfaffd9ae35bfdf3d6a22f5a0ad0545e9b40a2fe87b072c5c7426e252fcfca522daee23984ad5d28228130f58ac5428a49ec041ff3b0a852028fc4ccaa6fec7c231b58f15ab7dac581f7bfda5c049613bfd5cb466ffefe8f517a244fb7f4bc71f89148d3137d0310d1ce1f815dec623e9a8828944717af0fd67719c43cd65aadfc9ee40ceb848caeba47961e1594ca7515fddbc2babbd13c519e8a2de8fe34c5c1224244027fe3346f357784be1b640dbd1682c5ed709b828784f7ac91477784f8a47f94eef7dcc768060a7e6544d4df5156f93aea14b47c968d45a684ce0118aaacc5f1b9397b33788d348ba9e910fc727d33f33e73b3d5693a985387448c3f0f6e64bbe2c25f0315812768e5cd8e7d0b0ff4a125042637446fac0a5013a6c7fe564999128a33874d1ad91659583c39e69f45477df7f9be7d576b90e0642097474c6f65004f9d132e1cfed4273f8df07ad6fe0afdbd1c2861f17b6ceff74557761f3d3f2dd78d66038c9c1ac027174208bb5183fea7d088247fda289e1a2ded7a7fd19648d82ede6da0b2d70f3f68af891c391cb21d2e34813d427b3ff3f7befc2df448e2c8a7f95627616b7899fe135044c6e9604c82e4e58122e0792dc9cb65b8e7bd2eef66db5099e09fbd9ff3f951ead57b76d6066cfffdc93b367b0e552a924954a8f7a216fa1ad29ec9ad327052bb5af9096ee64078259539cd791747c7be4b92765d9da53a9dc924f16299b4c36936c16d9fcb1a963f3b6fe944927646f509dbaae9b238d68d61c054f4d7d403c3faf3d36c338e5237339cc2e4f17971fc8e5e9f4f2657e7912ae3f240cc9770fc8304ebf693886715a3d18c338ad949d8e03d9cf7dc99edfe8e1acd55edfc7d910ae15fe6606cc0a47b20febc1cee2d40b69c2da36408f377665ee5f347172e21a4f1f8b14cded58bfe57e9347b33b241eecdfe1317db302f59fec318da7f18dfc7e8d0efc40ff5a0f65dfe090fce10fa26e033a6ceefcb7b873ff51f3fae7bb2caf37967f2a5d7fc80cfff9abe04f1db3ff82ecf5074ee31f212efe5f9fae3f48bebb2f2735faaef2f4b3e9c96f65180363c4370b64f0735f0f65504758ed73c80f3f5e561d195dc84d0ea2934592d482da3929ed03e90f70c8302b6f7a92f5461b70ba551f6fc0075e1900c03d5c9aaef0e7e7e7e79ddd4d220f6cdc746df4818ddaf79ffeeb5b37ae031bb7ed8b7fe03fcdaf1bf6c099102bf0817fd42a80f4ce6d72eff8f7c647c0136af9a0e4e367fea6a4c9b31f1b23c124c0cbd67f38051a011ebefe61cd3b611a6c76f8ce96aa37d195c6069a6d843f69385f6a2b13169b5996f8a38f11afdf2254c481500e3ed28f9f7f8b0cbbe71dbd148baca719a371f7d22d14033e6d87a3abae71b7470b0469808006cb9aba185639e15b5aa7aac30e9f953782a27fdfdc94aa3e7e40c2073b34856e7b14fce513a0b04ef75260da7530ec3beec02a6bf0f52c50feec312abf74bb3022ec68c2ed93683843fde40cd37fff85f58e7c1993b9e9de18520819f10541a370d63485c710a7b4206104d9047a10f4db8f210fd32b6294b71f355d5454a0a2dcfa8a4eb34512c18824597a05458694cd73f239ce1654da606db2764c56a8505f6db48822a917e11cf557786cf04369d6ff78eda5a5a1f36bb87cefea1f74957a9d8fbea17b5fe9a5bfc63da2ca05dd68a8de53dfd8a9fe205f7d7508fa5e6f7da35fdff2b2f6ad83e569bef4d9ffb01e55eb0ccb7a7efbbe8ab6fe638308131f1c5b9475987883e829ff0d39f98744517187f247f3f49a91543c73ea70f7374553a91aaf0df9bc2aa24aed00aec1f1d2e66b1d7e57b0ffef71fb304e7f18afcb61fcd19c2ef1aec5e7dabc5770c437f0b8394a9b71b855d7a3ccaee36e8b637d1cf2a7c66399c5a9117ce547c5676160e95ce09b732cf3a77ff413a15e75d30742466f9d46db02e71dab57525b55700c2a75cf2e397a901646ddca60339ca6559165908c9551617c0d3a40fe061d30a7c575a3c9c87bc11f134fa61ce2ea1030fff69833150be3cf0e39033f34868c7d3aff115164bc07a3fa8376e54ee3af56d9e28f0e42537998fa9e3034de0eaf425e2e91b522dc783d704a5b2e6eb558ed3d35cd1639e599b9b7d9a55ee525739f82aed7c5757b0bdb0f6c34b61fc96b74d87cfdba4c23de60f52bfd4ea6083f9d96f0a26f5515aeb1c2f57559e1baac50d1c66cb62abdbae82f264d170488181f78be842df88de4d9cb58aa736771ba28080d9a2d2d335b2d0594fea134c09629614c504ac6591aad4deeebcd06cce092ef1ca9d79b8ed4fa8d7fd710952127491e4731994120fc3392ec86e4e3d0d2365bfd12b0b5bdb2d79d19d058341be8fd957162cb5e96c4e8db86235d14b646d830c3e496bfec355a3009134ad67702c395ce56fc46ce5ba256ff7e9dc3959687ba184f876a12367002ba947dc3bb814790e9fe46a17295966d553826edad0bf87a1de7ebe93a40d7eb00a1085ed7311ce5efbac0287beb1dc40ddc284c10e87e913da8a240ac7b847b58648faabab516b6d73e6c0ad2702562c3c406eba205af8fdfbfd3101a60181ae0fa7a75fe3ec77ae6fa50e8cf3c6e46a0b2e4b1b6d94150420f06b0fd0076a1073ba24c97493e0a19c736f63624503a97c5f4edcc754b8be9dba14bb0045292d0f4e2aa241093634ea71b52680e4fc51856b99b8de2abd7d922076e925f4fa060d40d67779e51d9fff2b960bb727a35fab51007f3cc8c1d2612271e1ebd3f3da8a86557f9512380cb66f331e8bb83f0e0a903b5fd4386aaff0d63d567bbba5bede4e0c5f1d17e75b5ed1f3fc6afffffca65351dfa1fa6f1334d6d3652cb3ef390be1dfa74f0dd2e1c1efc02ff5cc4f93585611611b80b87078fe104bdd2f248144619e6050c9324bb81703c26140339728f470a497c4d38fdd4c0fd1ea1c6d330df2b4af537ccb29ce0936a58c4a3447fea51f9d4b9e27b4b397b28378f0ec716f49adc4c68eede6edd849afad10c06d03d0be717e7e79dddd92efb6f37b6151489510d023c11e353293b0ab720a64891a3ad4038780e7d5ff82de1c3893561171af319faffbd1d36d655a56b95435e79cfacac0d84620ccbc2a8db851352e03b5e3125c0289633734dc81c0b8b78465a3022e37041f99bee82921cc89779128fe322592a54744ec6f124269188ad88e88a2959c24d98161d38c9a0c897313777988531468f292d32103c884bd2427cdb60edff96a5a4299f1a494a4907f6a2284eafba74312af2708c5de0031e6584e7ad9c648c4115363413c9178ac3186370db14215119fa575810345811d5ee2b65955148c90b943366801dc6236c91ec486e7b210a5ae68be37e58107e5ddb29f9522fd6e0850b3bfb4d011f96651a649647711a260aea987fd720cabc2ae237e47f5561dffb734b5f8c4958c49fc9693c2b6bbdd30a5bfa5b1b8fc8bce34b65dbb2a1f0c1cc0bca3d3975bc371839cdf1b77460a27069b72ed5352d177218a715c0c338f5c0fb2836d4b8e658e802c7eea7fe9b58b0ba208fd382e46998002db23cbc22f8d2cc0592d8ed6012278496fcc97f647bf8ef32665c59fc329cc549ecfe7a9564a330e124b9ef1029e3cb24fe8d7080e09a2c7d77df6bb2845df65f4b462b63d94b762a6f379aec9e417cc196e6f1f85abcfd630f277936c3efb89b942b395fc25983a4ed7081c119d2f6d5a871012105bb103f345a3c1805ccb2cf4c80e5d9e24aa818625a489144c2f1b49464b8c3b262246196d1424ab731135e090969d182d1a21048b9f9564abe149c56880b3263bb405c3428263ccf4989e17398c7615a40310db9fc1b2ff29ca405e4595658833f9e661995239f8633425da7091840af05bfb69000f93cd1027432369ec06fa671422088e119c6eca0e29ce32a2a584d1838338f95cee28ba674606e3b2ab05f61c0abbb7a4cf697f2e8811588610bfa8e06435661ffece23f5aeb7e5f15d1cf5fe1b927482ba02446061b40928591a08153ad421afcda14cfe76d371d03882ddef310a4ff198f421e143e9f9e0904d8d3bb777957c549f4f9007e65657850ca09062da09c6439eddc151c01db9e909ff2afdbf5b22a85111a2872a60c814ef17c47726d316034b7984296123fee514ec2ebf53afa6bbbbdc294626bcbaf7c94a9b24c9905150e496a7a198b394b274bc4cf30b0f948a56c7b19a7118472786ec2255bee39b98a29fb1ea611b6c28ec39aec4281739445c43c13de11bf9e316a2ed884cad021b32c5a2484c76b59a41199c429891a4db87bd71d3b017bf7aef8d4215fe6595e50d709295ffad840efb53e8c9dcb7034b2e3f6caa10a9338a4247a47feef22ce092a12f19307dc040d1a9d2eef76b7015b28787ceb899fc55e69e4048a4ec7ea06c6a8270ed88cba36f560af3d31de9e2de794f173698b1427099f4d2120d8ec62247a4ab8e7061f2ef9ce0b703851a8d2ac8ccf0e614e601e524a2288d316c405c74de3d93c59966fefa5e8e7881532d13edb4d2d9676c709d88e2c12d6b9bb431416e153930bed0d1c94e5d27bc97981c05615f13e64ac23addf1161fd6aaeb26112a878ab2536d51b17ab4b36c3e1a5b3db1536de9d6891876cf4e47b238feccb7e290bac81927ffa02f143add95546aa5cede32ca59958eef67a973f766ec23cad11e3ec677e178b277ece63e713ed3835c68b1dbb1a8d08388915e49fde7ad010fd660b979defb6001ae272b548a30eecc7112cb3053b965eb11592f1d51317bb5e0fab3553517a24bc219a5c39aff30f043c1e99e735884d813836df19d4d8d1cb1314db6ad3425df7cabb9fd537f14ecd48641b4938b3a562795890a2bfca8c9ffd45649e9371589013262e48d0d0bb77fc99e4791c9146cb3f7fecafc1aeea82c179b24ab1b4380d47c6f814198ca7e8c3d0b0f59606ce3005f225a678d596f24f2e2f7df9ea6dd46394148827872c4d968c35178c77d94507edc0788e9094dc4836aec7794208264fd8e9763971bf52cca173b5882342bb7fc16513a757b4cb896e8bad091bc4637a9c4eb28e977d2d763026b47339f67186e65a2698842311ac5ac7053acf78ead6b3500db93e5c15d443adfd29541ca43d0df846d3ece3cade54f6a886f6d5f4837930931764ef20d592560e462d0e9fb7b6416df54f6b60e7967b2ba864ecbac36336d603f21676c4bf353457cd2e7863ed39d537d927400d8414a4dc024ab0de8ce4574244d340e71625ee9a4e24a69207d5d822e69a8ba309d89964f941389e06a55ee24b25af18a2f24b876f555f3a823adffa5b7906ea7661148eaf6ff0859ebfa4a3344bb39b1d08139aa9d32ba7dea98dd6ba68c279432c58d87b797af00e2f37e3699c44ea7a8366bc23425c5ab8f56ed4029a317c3768f54bd2081673b8890bfef4a223634d764c349ecb80bc37d8bdaf39e843e5f2ef76d92e335924385005c15dcd048948420a5289172a79bbd261d4d889d73ba3ac3ea214b3f99b0d4f2bdd2e0c0fdebd3ab0ee8a129129cc7dd735f4c550e07582db224955aada2d7dc72a76565fb9ac1d735979a92f65431da4b92b0f6a67dd163f89f96caa8df277acca9a05a006ab8ab3d9e99f3bc7e2218a0f6291c122e51cd8b2799f7ecf61d5815eff84533d9a3e54d56793cd0886f51637acbaafc88f6bbe34481762c19aec1ee9deecb50bbd7391f7f099b8ccb34be33559aabbacf9955f9d9ca160f5062e5c950d381e927c0f07d5cf717e1c32e22ac3e5711d41cbe8f638cec78bb800f299e4cb628a0ff40925158b5c13579e9788150fb5758fb45f7d4376764d969551740436e3d55ea3c9f342195331ebd46b797a4d965432773596f1948caf8f45ce503b62283e748adf2ca3879009d7ce65e87055c898c8b64299353b120feadbdbdbce8896bfbb231d9e0d8f8f4e5f5f88afcfa007b7b776e973e8f70176010beda8bb1ccbfedee981048767d0e7588c5299190df5884178f6f160efdd454bb5d5845d60f07efcdcc2c3a6d2287d0edb0f587120cb8515ddddbbac485a7bdc190c646d69c9a1150d0fdfbc3934ca311c30c3e7a74ba2b5464f2f7d0e0f9fe0e861a11f8d6cd24463944a34bcb08a1a8dfc67de4e3d87274f9e2035aad087abddf79ec93ddc7729d9ab4cebc2465c31dd336013cd285145cf71a2fdef9825b322d00a7dc40a92305b2223c75c227e458cd6f28783837f7c7fcb51b8fcc6b6f7f73eaeba60d4ca019f68f189c499674f7c2b15be2209117f05453dd34d06ec7432cd09291f37edb770a14ba7e85cd982b173900e2b4f0282aad0af63627547abea8e6af553e36a61cd9ffcf7c382ebf102cf2da0db8569965d53f49d1b178b30499638525cd54322f1f406d9e857322e4ca99e6637ff3b4c16463e59c4d649b31b33e687f63075b9a0e4fde98baade9e49ac4e5adc16583f71a9eb962321cd8bda61339aa96ac3db80895d67b371967e267901612a549e4526327077148c323390af91b338cf910309bbc5843352909c62bc96d2a628cd0ab2839763aeae6047ef4265bcc2a7f86ccee63c4c5095843a20c1b4d26820c96e082d609e511a8f12c23195749df1bc7c682ad3c2384c2d34749206682de0ee24ec7b92c4fccb85cd7138c32ff36c860c073e8e13e117f9054106623abb68e9ecda62ec47c6059169355ad8d1d3ec3d750fa692ada20a8eaa92175a7b30a85c2c4fcd003fc2275bcf63865380f61b37289a710284958e9fd21ba17dc12ff244214321193f89234b950ec149a37b984e32cf05d48a52144f44fe14b30f316557c5164ce2ab05e3a8450137d3b080b880b8a227651ad72a19a6e6adf4d1a741d9417160d2469f17f99fcfdc669dd4b4d8167af6b9c083812f992ed4d8417b0e028649b47780a14cb3ede67146fad067caa1cfbe50b86c005aba70219b2aeb08aed2ab70c955cd17b05f8a0ca92fd6a49700bac7a622cdc01118685d90165394479819ba6508a14ce581d6311935636a571418d3089646a25259bdaa1e2a79fc5524b3cb1af87028eb8529bf0796d56ca7ebfbe6128dd5f2f447d63721b9c4e31f75a68f2b6f7add2e7c2279a69623bbaac24dc86d4f05d52462a2749c2c22b47a8d67c422bfd65dbc9ac2c0d74d767960e3c16e22b00b7dd8618b6ac74053d39917ec0a89546d3fd8e9f5767abd4eafd7f38b17e7d6e3ae5c6d9148db77bcfad4c32a83f735608dab865f8448e0947c29f67908435746389d825ee5d62445833e07fcd804bba65061038fdfd997a691c5dff129b23655cd3baac42d5bb6c22d1ae532e0a231af7bac6565450d194fb58bfb227727c0ac9efc8c098b622c72f18ec314464468862303233ee26380b94f59aa0b219d458adf66957b4f4934e522537895da9d94e54d688386b73638b335e5358b4acef6f6839a553156ab621653f4f1632b59c846769aa8394994b61ebcac13d9e65dbac4923f5bcce074a06a4b14479ba120d3e5f54abd44ed69c53e22def0b8d93cf3374f7ea6e240cacccf2d28c86cae7e382e2f8825ae1b8dcb6fac0bc94de7d52b15e0f1f6166e3a1fccaf0795ac15e195d4ce631e656c513df0bdd1731bbf0f04524222dc0e65e81ab9d38a5c8dbcc7dca42664127e4ed28842e6a29c66377043b8edf63c2705bba58827c8165b61ec24f705afb96ca535d13182cb0a075588753f939cb28962cc248812affa01528ba8bb8b62dc95ab9b71468bedce0e46de1043dbb4746e725af503219b891638c7c29b32532cc7872f98ec42c653c62e3da7a61b9e645643fda1057d1f1417811ae0810750cf2528de00e5d7e7f0d87b98b4d8b1f2c4a83e7a152c9cc32cf7553b27b1c97815c04b871fd9021b2ff20f4e3e5e6b94f514ebeb4ce2d595671245436ab21c56f19c3a6fccdcd0fe79bd2971b31ffd57062eeeaab5346c9f910146dbec928c429767fde3466ee32ca571447212716b66531abb0c75d3892accb84b3eea997cf4a85281b4162f814785546aac6e3af5da316905aa8fc3385ba40577b60bf382f26d7c44aee2341506daab4781c016b89c5ace0b51e3d0217fe418f8bbac5d4c36ea97db23bfb64eceb72e34e0397f2210d7d5727f53eb6ced5dd87a0e7637616dfeade1abe285b59a8a7ca75bff40b3bd19ef9fd6ae4f83951b7bf5ad16650aa380cce628512a2023fdbece605541cd49a5db659b30fcf2a8d7d743e777bbd0ebf57a6dfc1ffff8a1d7832c579fdb3dd88253d80259bca37db03eb3db0e6cc196fa618b61111f443c67269fc99782a411890e6926433075ffcff939bd1704bb3b675bed8bf3f3e8f7475f6fd93f0fbe36dbc1eecef979747e1eb5f93fb71fcaaff2f32dffa7fcd46c06bb3bc1e92d34035e10eceeec783e9d755aacbdade62efe5f70767ebe757e8e3408d05d8170f796d1f88981fddcd55cbf46218dc76bf64575c5ecc9a61d713f7c7b37ca8e14bfa92e7cba15b4db95cd1a31cdd8e50c032296cc77d6f8887fede1b0bdbfdf6841b71c88b631935d3d8a22af5656e243565be1d5ab57afda671f2e3e7c681f685534fea8ace0827745081d0f4dfb3645bfdfffeaa7dd21bc1aebc78fc3a1393cfd9e0fab846210bf9800dd2e700888291c1d9f728f7212c188ab3aa8703bb7870047401bb10fde2e29480b70fb6b75a7b4917afcb52b5ed12f9e5a7288dda545760afeaa8c324977c28c69761acf5cce7afd7a6736dba1b473727272225a3a3f8f768c7fcecf3b6c2d58dd91555b75555b3515abeaf8c01d58076836737a61fecfdf0756ad555dcd4fbf88fae081f780da800e4809e04e309a44d0f91129fe4eb3541789dd5d262acecf83e0fcbcbd8bb20a230528c6c08765feaa4233c11dd63dbbd4c21c9e1cd7a86012cb2e5778df95f788d80290177e7b6bea902f641cf0eaf8f46e087be3570b23ae44f4eac68e09cf74e47cf5f937fec9d1fb20356b9f62d868a9838b59a57ce06d4182b99ab9bc969ea5f8769af8df4e41b934f13a67f1c559ff827719093ceb5ff88d024068095e8af433a0a3e855d96eab01b32a6c73d30e94371555d7749af41805e864d65c24cac84b985903aac9711473150df311bcef3791f64c1b0ac375a70dcaa9c37aeed4ddaf993a9026cd0c70fb420b34d2386db0d31c9d87e30af755f657b2380c6447b72fd8e26900c6d1d4c9aa6407a89957cf985614a19dad46cf0aa3c6f5e719aae6da43882fa757c9ed77efea2356779dfda3b8f0819f0b71ec7ed3049d82ae1c3f29d160008d4f8d8d5d61fe94e1978d4c84065150bc65300a6356e4d540758917792f656c433ac15d602f1591247daa6a6fdf57f7d973977bf7f2056cffb2bdcdcf4d3bf032cb212245182714a870dfa23bdd6e916509edc4a49874b2fcaa3b2d6649379f8c59d5bf50827b6afb7ee77eb9758b1f71cb66d78e6196de9e2ec8ed0712dd9e4e17b72ff3f8f6242c6e4f1669b3b57b7e4e9bbb019e5c5bdb5f9be7e734f87b98debe24a3db6198dfeecdf3db61b8bcfdfb22bdfdfb22b9dd5b5cdd9e90f9edf1b8b83dca3edfee9331d6c13365ebc157f9855d3476e40776fb909f9bac4546d6fbd3db57c3d3dbb38317c3b7176727fb17a7cddbe0ecd36f17ec1f71987ef0b5d9d42e38ea0c41be60b81b3667ef5ebe60bde5534751897d5248cd2f7e8ac225fe3bcd16e22754a8e0476e287252e4ce092427749114e6d195fd2dd2225fa4e3b0204aa9cfaa5b2787aa302e1d91a83490e4d91579c6a2b40824d5fd5e2588ea500d8cd6d77e4fcbc774e11c58fc4301b848d95070af2a85588123e24a6594b067e2282a6dc12a06d59e93257f315134a8c9eef76c6b2e047d3680074faa2cb9b6f94b87f54aa3bd4c49144f9e54e2e83ff1e270baaf01b89d9fe7649e676342a9e0e580da4670ef080658196733e1dd9c4630c912d4a7df4ce382e0762e6e61186706668ba488e70969e34f94ab2b436047cf84d8dbbf2093aa2835ddf3f3e0ecff342fee9d9f376fcfcecfd3f3f3e2a27bd5c2edbf840acecfe9f939dd6aba3ffd1ffed3bdae9944b32b8a7feeea99032a4cb965da2ef10287538d931f1df28877158e4325bc2f2b03d775bd13e3c4aed89fc3344e9210fe7e825682c29a500c598ac985e7242db8c1c9b29d4ddaf85e8a345a7a002dffd8db3cfb1c47242ad5029e18494a2068347b1c12c5af7b5c3fad19346ac371d6bb3086e7ac6f7ddfbe68fa12125aa3a6c8662776a3dd8d6c93562a62e5dfa62722efcfb53e297a9048fd8e9b8d2857f3533388d9fbd31de86993f06a68151cec9fee40fb01dc834746f1092b7e6817bfd8f71723f423bb78b8ef2f46e8c776f1db7d7f3142ff82c5a2e3ee263a0e93f122090bc2072150c38146947111e64bf93d5dccf84767a9a94a5522b21ce433f5d1e399882759a355dfd2658b154da7e41b99ac02c56f1053f8e425a1b7f200c7b8613ad3b716d5637b7391e00c7a3a83bf42bfd76b01e3ef603a8336cc9ad065657e27c9294e096c293b70f01f0ef11d05c3aee02b5b9ecd2027137e5e5cf1aa2237918a9715b91ac52991df0adc2d48ad4ac74edaffb081b14351d670dbda41cd194dde4144b8e8b3fbead3b6faf4507d7aa43e3d768262e135ccd82ae4ab464ba7a6747bae767d5a6532a9943c924b38ea0a054ff11b4677b6561827ee17d5a127ea53bfe7b129d5edac0cab2ac38e4a1156a596fa0efba2f51eafca0bc75a9ab76fba2df91e1621cb59d564148eaf2b970367badad5805bb4f5e0c9d745b90afcef7b6297ac37efd2b7eb2d51edcc0df0b6c21cdcf76a5ae1c1a006563eb9b9f641dcf1d3aab072e6d625d11241ffb5c8ec76e1658cae08454166f302fd808147817f697013fbe30e237cf5e1e833380966755035535b098f8322b24d5036d4408f0798cbd357cc4d68e31442c8c938bb4ae3df4804626819eb1f9e1c8b852023d0a03148912ff81a604b83a2f7351419fc4a390736ad70340d1ea556349793240e470981709c6794a253c728cf6e289a9ba49134c2a21d38ca52494d9791c257a8d407e556849a4614d371b6c8c32b12954e202302395e6d22ec680a8bf9389bf1845abf66ec129e9090920ebcc57fd91e4872d61b13f77a916e7ea56d46a313e3463b3795a12b3cf202aa16b5e24fd8f2d8c336e0fde90b8c4cdcb0afc9ec1f236235ce9f888959f0de52e921c3c6d8d40572363b3c39be449b808199e7e4ebba88d543149b3c1df3bb972f2e8560afc65c0a66a1a0e1775394cfbc648568769edbacbb2fbfae0d79d4d218a996a9d3e6615e481f111e2589b17d92dd30a0794e3ee39a8873b609e76cd555f8894c500699c35931f5d512b84af2ac6a508e724d83d5f27455a3faa9c588b853b5973389b8f4a9a2649440112d93f2f85418c2fa9a4008c2312ac689c19bf37fca05f29f4c5afd271e5cde9fbef84f7307566a3d4c2e54a5db8bad8b3fa6f7a1e2df16d0eb783e27915763f886870e1d88af42ff6281165921823df31654a59e993c0d9bc5c3ed3cb4f8b673396959368ecd0e6ef7015f0e459c5e61087f8a5ac833f309cef6e3e04d95da228f9a0841302a3e0335fd1a403e0246321b8ad0710a92c4fc133cecbccc72236b923a2d23994d57c123244a96904e925d050dacd750d3d1d05a6e9833e7e0917f0d7c066fb4602dca3cf700ad15ef315ff048c90865ba0251209f62744c55316f05361598b6c2730b6a96da225dc866444a4a8e738d9081a0ebc3657730646f4d57604b9f0919f4d8d358c562d81a78ead7eba7d8fe80fe4b58514582c6bc09709d6637296719773627652eaf9762e7a067085bade85ac501759321e55ed5db936702eab460f573cea5009f74ecd39a531e46d1693c23a7195e3dd9ce602c0edfd368fdfcd851f92e29cf247cf72edc59359adfd9c5aaa897dd2eeb263b1686315abd2e524e89f0c6150b4e9c5df413461d51e36998d33764521c7f26b95a336f647e133fc75bf71663fff0aef8f5573a3737a9f3b8494898c3657f7b8a6e0c8c00cc0c1153783680feb6ff5c21dd7910c4711c5b994e67c0f77da7a28d7e93be97b97a94c34f55b7ab50f0f967e787b768ee5d9a00853250f93a5983b4f459b2be2c7a6a8cfd344ca384a88c059ed394f29a92302fe32f1ff2701e98fb7fcbaed1725a361f16ca239fede5ad20f41037befba775dab60894318094f7bc24c331c0a26f67ee9b871ac18a370f1e0c602a929b4499ff0d345b5468cbca18456ab290775644a0f05409aceef91f9cb5ac6b956d74bb9e570124966770d333b7f99a0365c7f376c6e42aaee267d077cffb8017af45ce36dafef66ac38f3b064ab678eb909afe9c1e9415b353155e0def62e2d5802ee6f34c5c07a6e17c6e6fe8b513ef7fe5d32e93fcc6914dcc5b255d7dadac0c2b8286d2643617d1f34c62478416437c4968d90fa0749ce5e434fb1b09ed83ac7d5f119e4227ac4265488889dc4bfc6ebb95b6823cf78db2d2a971e6359e298ec2a3cdde1ced2b894d7785bfb6d6750fd795e38e7278bee45f82dfbf569d59dce02cb5165665030adcf624ae5f083a82895677e2deb0aadf324a247ec7af3be2315307ac32182be2747548876e1778e08c9c60b49c74290e4cf8e2233df2c5518a9db0429893344c8a250f8038e581199566c93b9d5b03872b35facd5396c7978eb583e7c26f6fc2385d8ae5730ffabd95ca0a1d0915bc59b94ae52c690b5e4540b9bd35097ea68b05ffcd53c762376a0397e247f806798397569d9eb9edb3582e2d1dd9ed2d983c097ebb0bc5d1c76804e1139fdf13d64666ea51a96f7833efd3580bbc12fbb29f6290be701e9cc51d1edb23ee88e81e71270a97ac83ec03c6ede9f0ed3feec8e8407147c60762656584203d8b6236fab55a898d69679476381bfd6aeb85bf6e7292f38cbb521608e158b56fe5e84fc1843a9fd8c03c11ce73320f73112556e27074b839a1d5b101ba5d91560e43eeccc2bc009262b6a830cf166904fb27a7f628d14e184541bf058dc8b1afd41b5be71a509a8cd59a4ca95e56c771122f5f558f8a13b9832a09ef99422d358655707babe5fe50bfb99ac258251896f223902d0fb4e1600c5682361aee762043aa21ab880c78c1ef0c295e2d77f024f0b5362e8408c6a0b5c34f538d4a4d472c63aeb81edc7c162871d3033bedc654702b07adea5a255bc7ce639c768c8f299e6f2a50eb67213d6db283842f543e355568aacf977eac02db1ac86a4c8e6bb4e84abbb82aac9671e6a8b286308e8d4e386f67858ef59da96e2b31285cb94a9fdaac53a6e359638a5785fafb26be514879ac1854d51e4f2a116fbaca5c3b857a1e5d41b1dc29459e5cf142b26aabd326b66e9f03f004e35ffd6e61f4421c2d6abbe11e41aab01d6134842a6cddaec85e58eefaf6f1b372a2575bfe6f621e0075d167b4d016c739bbb3c8a4ce13e168a6d219e20b6d0b626a47a9c4b01932a7a5ef51a57ce0bbbd05adc86f7c219e8207fe98d06a535cb99d63c2276bce71af134507b37951b2f4edadcb9516dfab8dd2bc3e3b1d9082a582428d4184bdaf613d315b50cc101565a9503cdf844b33d49cf4d0b88a8be962845607dc0441fe1353ba20b4db7fb07d5f3b56742e63bac777393e02ee1d7eac5f5d193cff88ff9a60896f82c6dab66d16b3fbec443a2c6ae56ab2f987a73e696f9d5083f1aad32c72f30a46f605fbb6d7c2aaa5c0f9d767e13bcfb32263d27818a75576377cae8226bb2bb013af028ab8659048ee340bbf409cd282845167cdd44ab3386dcfc22f5dbf8589d78492db350cf421308cfd540c606f328a694c3b728fc76582e8caa23a99cf5b7ec6597d97ffb3c34b6de95fa9f9f21e50eb153f6098c09873167e593d676c56aae78ccde87ffb397bfeef9d3319c03a94466833992e98fbaad08c3f2ecdce26e94580c435d99ce14634c972089332e123ef3cb734c9092669ce7886483509939447c581220f531a17f1e7324eb0c2a31ae77eafc22c6544cae0c718d4538b1d4d8191227e6dc1cd34938916d8090203739384cc7828b41a347670ee793cbefedb3298a42d4994ef4adf02fbd82b80f53daecfb74dbe178adfcf7a1e574ed97b99de919a161c96c6e58ed954fdb55304dfaaf276aa6c53bd25f7f95bb2d9a63f36a94edc597ca12d93db5b28cb91aff2aa2c9d264dce0b6eade388e7094219a4bda704ce2e3a34cb0b296376ada967e22770663bccaf3022c6053f9977c66192044a46b4a0d7f4edbe828d1a31fd1b99643969a05ca9c985c124e38f6f7c6f5290bcaa6d1174dd361774d0a1251803dc551f318ae756a08edfea66f5d5d81bb23c22c2eae5acb1242123a5f17f1761cea96ae08320fb7043c835fb370a97ec9f69b6e0bfe37320fbc46f02bc4c5d0c1a17ae974c4cf745d654ce7ca6aa14d99a51764d96985cddcfc481b0c7e1e32d7bd102cc2473079314600a87196655d19f9aefc4f4283c123f349bb5dbc16ac728931916695cbc0ee93e19c733f42ab311a8de694a2049fcca953b3b93a067f145b5d18e4944a5dd8ed145dc29941b10a459da8ed3825c919c22cd74162609a105f6d0c5571163006fbd2f932c2c1cdad9141519fad39abf54d2eb8ced9a41e1ea5f5c7c9e6c1aa72287fedcf72e3a3c685826f4550777710ca8c02402fa8a55a1ab155d7c120a02997bd811494a13a02c15bdba0155df7ac4655280ea95849d0d7aefdede1a7e7bec4f480b5f15f193af160a165f1d1ee0db53e34644beb32ba0e7e8edad532ee2abfa5045e1d28749283d6c6826eb7ce06805e0eb1a77fff1f50d7ff1d511ef289e3afc177f3be5038cb731f533d636ed6e75e6c58bb029942d644ef4e79cdd0f28490b61229e614270b21745dcb3da6ec9a275cbf8bee51f8b7bd027f7618b35d7374286eb837c0f1e91072590e6a0694edfbdf267fc0f13790bca763eb35c1e3dd839f4fe23f210ade33f6771041326c858857916a705a0e6061388e57996d3b5df2eb69f3cfec518cabf9171c8ae58d9c41c42289858a0b0fd407421a410c59309c188a97823080d448c7d6fa624859b2cbf465b0fa55d6ac14d19899816598e6eda33a0641ee6614192a53d6162896ce1bf5bbe95780f1e9b565e8778908f672ae54891f12b451216442ef8382d32befe6ee2629a2d0ab45a354c0ebb5de02e34a2ca325ba0fb0bfbff224c78d746d9a290a9403167a8ec9881272eb42e761ca69432684b7cdaaa906cf7e0befd1b9792f7b85d913b78987dde7a37e4bfa977be52d5d5f4808d16a35152666ff06d4ee55660bf3e6b4ad618dd54c6249ba8ada3126538a2ef9063021e0fd7d151f36278e6b1ad114d0ec362da41b60bda7db80712d13d9e8d4b42d7b999e93844f57a1ba797c7ef867ba7a78747af9c1e89b8d5d29e57f04266f62c8c84aec8b0fdede1ff56bd5470fc033e692acabd73dd47bf8cf82a850134b6ec1040e8f5cd11f94696fda976dafc93e7dc23d1b76df47eab3404df82df489ebd8c9324f8d7bf240d5d78d46bb660bb095be58079419bf05778d463a0b6dade98220e1c343eb1cbc18ed266ab622c6f98ef1f7bef4eb4f90c994cbc225ff8042122ee688a111f8477fb533f2c03ae81451b650e7bc629fcf4a961583188b7d2d0f07bd627696cdb46d96fcfe277eec2ccbbad29a86ce2ac440e5f8d81797df0e6edc1bb13ad446560184f17e935c9d50f8dad7e6fa7d76bc073386bf47b6ccc1abd5ee3a20468f71fdeef350001dafd87acf3f715002a3f18ca63c97b5d153f550661ed5ec5eefdcedf41924baf900a97615a7ad488a852c2b14654af7218a6ca10a052075ea37855bd04401d1f623c13ffcaa7a236f42f9483915e738ed6d380593b10c99646b73678dcefa7d16e70b162a3290f8c5b01a23ceb5fe061842d417e4be2c5db17ded704551fb39becea83d033132372343d9ed7a4b1d5805d557907dae2a3e785e69dc86a279fe6ca341f2dfe1619532d5b00b223f9bf8bf8739830e82283591691c47ec91b27594a3ec4c554484d811061fd6f7aecfce33ceb31cc97aef60eb4b72a0682ad3992996164f367d953a0f193aecd865db054d52a130b7fc1e3609a261bda68a8a30a5c8faff714d3b4b513f2992410cee3168cc461105f9e27291f570da2e3f44f8423388d6724105f4b12b7b07f76d35cc7ca93368ba1c7d135d43e168f952f77b06afff68c4a52f5c8e91e4244c63d2175acd7a16e178e537819e764927de96c3fc0b7adbf5cf1ee33b613d56452e4d03ab56fa86e9c2f92a4dbffe571df59726ded903213911f4c1a020c5bf2901d7dfa0f3d4beaf5f1f13f74398e2ff46a14a433f7384c1212e1b11e1341a9151853982d8ab0205199d34f1cc0531ead952dbb6b42e63cc60b1f973805ba4cc765be7cb97b08242e67d4ba2a0f8f870747a77a2f588338f3226629ea2466244c297f5fe2797f8ca65bf226a09084930919e3a4a934e67805c28c260f77eef777b61fc156ef7eaf07edf65979eada6e617bcd8b76fbb94256c26ff77a6288ca1b0a935d1222ca084d1b05902f3115b1aaf8b0295c8843de3ac2e8d785c8ca883165428a372c12b5843a059f7c5c4dca3f0899cbbef18a320f671845b44b17230cf34221606294f5bba9eaa2dc2dcabc4aea1a4e78609b0e9c0a697c335d322219ff803e9fe5208b7bb6a87798c238a484dd986ec2b4a0b040c7706dbe040b8557615ccef72507384cdfe6d9554e28db84f8a4336c6c7360f7d1f28ac6074dc9b9f21423cdacd30ce8623ce52313734d15266eb35955171827a490f242ec21061ff2af222a8bb3b19867f84bf1d5f3de828cb8871db0f6a03ba6d2b1ea20c2ed2764c621a55e3c0a8faa7549461defb3f0fab651a0d9706c7a0cb55b356d3057bd32b39eaef1565b1a21a1780d4754eebecfa0ff089d28ab66d2ee1fff175f7a6aaf43e5f409a3104c72af318fb7158d15f84dbedcb25001bdc24bd4e034d7ac04b4073aef8d02742b244146ad0707431646915ea1058d996359ec191c41e59d81a0b352ef70c794fdb7b7a20fb684a8e495308a4e84f0c3416cd90fe37c4edb82777907303594f7e0022647ddd9901a3f78b5de01fc072bde11dc962a2a553664dd5b2ae6c87fbdb7165ced794d67b55d290e77567075ddf9ed84149fd8dee515c6cea3d28612eeceba12aeed5b568e978ff570e3a5d8f164f986416ed7bc10558e2595fbda6986168cd503a94f65d948cfd393952d0923b3fa49d378c68da2b11e1106b892745263ea72c16aa98c98e4f929f0f0ef2a99e78974594e71eda07157777908a918aebadc95d6a0a90a42b8b922c4b58e1603597f06404f4d5c9d556700b9fd0b745e1b2b44b072c7d1bac32aac133a6135aa9e5f9a7efb2c4e43ba97c45729895e678bdc38473af3b8e641af22fc1e38e7935ddf65591312b063e9ed4403812d4da02d77e7bfc2a31e7f09aa531d84cb24be9a1627e1e738bdc2fddaab990e6a99b4292ce5e4d30ad7dd063db30bb601f27a481e1a484a0cb50a11a75727d378c2ee46ee8abca37b414811b47f722a6a544ead0b5afbb4e86a81340fdd315f64866f1e0cc0f238731f3ec79dcbb0de70b2dcce55984b51cb7cb41a7ba25cba3d947723ddaad25da7e36cc6c846633a8a985bc2fab0e0e155d87a79be46ec582f019e25e5dffd7c73e36316b1cd55eea2656777c1b820ec18b4f850bf57d98ed743bf31f66fc07bf7ae75ebc0b7e28ad6ba5dd83b79db393a38855f2966f2559108f54479655aa332a551707edebe3d3fdf6aee06bb98a2e05ef3ac03173c23c256f3fc7c877fc0346df2334feb74cfcabe26df3b849d71948d5148d0454eda493ccac37cd9b9cab2ab848cb38870f3e3b8e80a904bf6d325a31cffd3f9957668b6c8c7a4332d66a57d2ccd66e406ad6979fc4248e294f0c79f079d079dfb9d6dd8eef51e009d93314fd38b26521422618814a6cb9b29c9cba70c0cd7b7c87129ceb2289ec4fc2d8e9b56a135158fb7809ee82226cf282ba63c6724abae12e78ba45fdaf08ac17dcb46f7acbd75b17bd66b3f69752eee353ff221370b87bec20fbec27d2c3c757f78bd36de136b022d23a8525fad4ed94be735465a25c92dd28d6fa6b265e34b14151c398798628eeb94c69f490ba20ce20218ef929993af58866c467372f3271a5fa52d47f2dbf643f164f20e1fc4adab0c35efaaee2ea275cf73d49951d8116a06c362c613bf3e8212340a973e90a106c20d1cac23d3b7f97fe95df8ea391cdab36ad7131699de578f6aab7a59bb635912555cf23cfdba732790f3ae092d1e965874d575d9e24a7515049b9faddb0d265ddb7dd8713382d7ceef92cd88fdac087236853d2436b5bf777a70d1b4c1d4df3d1f9fb2bfa98d08a3247d03a2998d687878f4be86a64a44d4467472f0e2f8687f7344b838382269a8a2487bf3e650a015865ecda6402483dcebd670527473432e54998c9345c463e6223043bbd662d1982a36f2dffd691cb5239c4b69169421df592bbeac174317fc7e0df88d0bfea0063c72c11fd6804f5df04735e03317fc710d3875c17f91e06b4d6d39f0ea9edbedf27061dc281a5ff1b3bc74875c4f4eba1777ada50134b8db4b03cdd71bec00d4606ca9606e6fa1516446994746f30daaf4d3d81786836362e47c575295b5d36c81f7b7226bba4f6075bb4029ab190582164370575518eaf0b865d51cf9a577b1dc72d570acde9731c857488f6fd2b7793697e7918630cef3478ad04cf7c4a6eab889faa36e38599acce35067c206517d53de7a4fbdc0225695f28e5396e5eea94b723f9eb704e75bcaf40fa41109c3e164898e7efffa579cce4500a398f213ef229d6479b148d18a921dabc28466069e71967e2698383ec9c202358771aa5cb70410433c0b973022e5924165ea38ccc96491a0b2921dec64c62576ddd155f665b416864a868fe10e06713a5729911aad460b1a1d333a383b99cfe7c9924be09b699c10b8218d9c405880eed4209f3eb89f484e2813cdecaa841ff9ae52793d9b67dc816ee82cbb11ea4385b79e37048df55090ab3500037191e64f234d6803c3a6be5aa6a9dc2510edf54b58fead292d56f5d581bfcbd797308a82b2e51634868d6647b829095f436771b4dbf91aeb95da47b72dfe5cd186add52478ed9eea02dab8726fc504d82a5d4e53ad2369d51bd1ef7a47d9814f5832ef40ef6bd5f8a8a71bcb260acb5b388776cc214120775fab9a1bce5aebb1e51aba8c7a6415c456cc7fdb2ef355910b602d165be963c8732340230d67a401617e0521636ce5eecc5f58640a05ef2d762f8a481e4471ce3345b680e1f23dc79466339fc3a4057392c7991bdc4bdc795b50cce68e85588c52951b7c942e854c248fb3d93c09e3941bc283ed9485de57d8a04aa782da732ed3b6042dfe6b9af4fc3e8967f38404ac7b2dcd41bc015bd865802d6888465acacedb701d5759264a0f721d01abcfeba9d1e9987928e45fe344a4ef5ced6e1e46519b0f1b89daf3300f674e7a0a6f84eed91c06f0394c9eb2ff302647829e8a7f61e0991f4797c86b8a431d7ed13431b00b5bac6c075b71ce3f6a435727159d6b2c7857538e2ca498b2c286cfd657563b0294f8d16fbaa54e682d88298f65d632cc8a5ca35e73adab135eddbb86f03951b7bbb212fbc53ee42bd1e081e7bfb907c13bb36c56a3bee976e128836cee1bbd2aa96319cb995f4b539f7c4160c7f8d5b567e6443b37465260be533e1157a4e01f1a5888e978c548dc537353e14dce737b2fbd4dfcdc1768f743f4e72ddbc102342565d3b35623fa1cfb7ce9759b55f155b759357867ad062b5911fc56199ca7597fd0f15d328b85ddf0c30ea388ff383036827e0b1a6154c6e8434f0fb9764cd0368395bf69fe0ebae9c48b30216914e62278d96c2902e7429addb86fa5dc76590275d8f720cd6eb89b366db89a522108b0e233683f825d68d070460e124a1aa6a938ff93907d069984b4f840c8751d644f02ee87cb3ab8be6c7a05dc368313b10eebe01e4b3841a0d6af6adf5c31d83ff7799a6b1910c7c916fb81a051241a44722d9788952fd3e56451b86cc167ca752c46dd5704f39470e076366923306002d4088371dc4c09cff182b791d28c5e686ab21cd2ccbe06f1a8008530b4322249d80fdab87bd9c74ae412543e7690b0e34980aefd766d15d151c4e532d993ef3d941d6b6e6fcd1137c9cd1605577bcb745677efb20b964c4421a2fad133feef05bb715945dcd19f37886b61c786f05e11703e38402088908669fcf6be1f1661d0541d0b644824dd008d0f2c6bb55913a129419327df49500bc2a8eb7b7dca3dbc672905c9228d3dd14d9070e9da6dfb2d083705af738273c57163e594b8d7b8e7d4983920e5ba5332f739171d62cca24789b0081395d9e14987aa55c997fbc773bd133eef8b5a3b2d5f5d11c4495d50e58ae1bdf1b7513dc5fcbef63f73fc3d73fcecbbe6d8984c92469ea95ca385ba192e6e08492198e4ec9c516462965b5cd140e3cf71e16a3eb1bd977936d3671cdf65993464e5e67cf3275bb38388e334d33114199a026456ed225b9b55184d9ee2d3ecfbd8471b0b7cd12bbf31d6099a0df7dc126850ca8b2d68485307f94ca5a856ab6b07a4e596782d71405c9b16a331a9a8696a8de9a84e334f5b1a35e5ef75d2ff845d8bff20c160e757608543f7d5ebbfa5b860f5be496088518295d5edb6576d15f06ca090cbe89b43cc44b486705a4f0a31663ace571d284cdb2156c78295c725c9cec6af2b78f9385fb9d96dd0be586feb1180d70203b60521455d81b3a68aa9937ee4b72c25fb242942ab9c9f21dd7785f5ec421d4f9ff20b7aa2b9e774e5631bfb5e3358a5ef6a55751306102036d3a6d4b6d56cf2782b0625b5ebda80a43771319e42e07201fb43f7331e836ca7bc30e0e57c9f5d6c8527c5944d6017fadb4f619493f0faa90f0b0f5bb60a4d1d0619036d0d52eed7e111824a4383b5716c454f8842e00f7523bac423add52062136321f284c3e1d8307e5b0daefb8fc8432fb24a8cecf6588110da25a331e4bf3c7a50871deec1f68316a4e42a2c0844d4ce9f82cd613cba35db7bd47bf0cbca06e11e3cae6e3422937091145a835a7b2b141242ecc0aeacbc03e1889565b9b893d6041d943c0741d88291fd301129dd0bc6cab38cbc986cbb996609192a2c03088251a91a0c0dbd6013b62018695ac6507eb64f0fdd2e8cb8e10c04613a9e6639b4a10f227d8828d9922596bd85f87900a1a1f2332995b107a9f324c1ab6fb7842fa92315478c70de842f9c8aa8bea279d61d8d04d7773f895312e632ab371a0d3158ab2de921a811c518b21c3341cdea93c89a646ffd09646f9785559cdfeda29d0c3793614b2afe4c30804c4b2e0af6854d97f1abb374da6eff38714d19d2cc689a3f5289b5aad279353e7efcf8b13d1cb6f7f74f5fbfde99cd7628fd240f989e2aef8b7145adb34f170df7d9b6c8b8fb4c8d55b69c31fee6143448da68ca67a9461445301c0e617f1f589b205b83b357c3d38b4f9f1ad5e2a1c80e4f8e85f3ce352173cf0bf806c71337508afc88c12d7158ca56780c47d31912353f3040d85db3eb8b628cfe2c96120ad50552203d831e3ec8cbefcfe1c993274f2aef1a387ee206c42e72d828ce9b9cb9b3d30b399a9d939313367fb0530bf2a951a366d05e2c31ceaab2d5e96813e1552ba59cc951a53a5361f3620aff7ad8fb0293901624e791b6e342047123300e3d6e708b625c17b214c7bcc878cc579d2c3704f5aa08d62a76ac759bda725d78c42e8a969766a3a551cea746cb99b2c6a7869310bad693ab66ce57cef88af92ead05eedd13edde2b03df4c17b330859c8451384a881dff309b949139f004524edd3db496821101c286302cb837c0152920c42116d578c8bb980b651ace6420bb9296ff95c4e9b50a5a926611f99576b2fcaa1bc5b4e826614168815e12dd701e7717459ca0abc35fd8a7cbf18216d9ec324ee99c8c8b4b29412ed9ff789c6dd94ed7becaf12a3e1faaf5c48ab01d90a66b41f71e3424135dc6b0050db8d7359e7b2cc9c348611299e36958f2e637eeccd8b09f0c2475422de25027b03abc2ca22829b217c51859487c459bb34f594aec386b928e4f353d99e764127f6150676c0890842d6804e73f5dd8ddc270ab03087aea51400845e9c92365e6400849b10c340167a38cc282143c2e4bc3bb18ec0a7431e1e462dfb6a07176fe53f3a2b14ad1227ab9c5fbb055b6bb2530566f6842dfc4efbd276ebc30eeba57f123c8179b1399c95db0c07bdc7b76ab36fb1ddf0fd5936829b334cd4e4b6fdea37775f54ef38c16867aaa6668f26c26f5942262ce091f4dafb771bdb35e5006bc2ad09d9a71553c23fa6af6658e31df9059cd351e052dc396df8b6c47e8d7589f76b0e1afea70a40d52d06c7650f0c6bf91e08ed9e98d1efb8d311772886f91ebbca5312a8fb21b08aa87dd580579360b4c952c7869f79de7fe7bccb09857fe4c92fdd79fe122db607e8b6cb3d9ed76e17002f39062a25899e8e99a2c5b78d88b9304d8715ac5ba22cafc5ad597515c3b00c7c594e4373125656d459c42c0434e8ae950583e8779cc4e2f54355022b60644e0719cb9d0f680dcbc51a3ed5cbfafc9d24cc358ef492d321f5e86a3d1ea2cd946cb46085d46a7c717cdacb032604169e16ff751075d2fe28ac504a8bb097153aa4fc0c38002c790f29047a56e99a6943ad3cb43257241985e2dc22b8b0f3a1870d0aacc2b8a305fb21eedf8b3f5f85cfbd69b737bde75ca37bd97e8e2c333ef75a9752cfe46aea809ee6f38781853393cb97c7bf0ee923b9dc1006f3e4f9d9fb9cf1c0cf8edc8a8e302bf3e7effce02e5f55dd007bddee5c783bd7727ec8078ffd143b8070f7a3dd882278f9bf23153c3aa7b548bc071b32c5a2419b4611aa6119308ea1d865be452ccb48927370a23aec4e93f79dc6bee380f94d1cffd208a3fc71149a316b04fd40ab02cb5b7120afe2ac13040a5a8a00a2b77479c8e13ae5143d9be6cc1ac0591fd2aca9600baacabfc73590e399985732ae276f7da4f9e30beef3fe9f5dafd274f9e98326c09cfd88cb22d7309cf7da9e4bb5dc00b60fe994042c2b9c0cb23ca87305924094e099e80c7cb712263e1b14a85fff5455eb797b0c5eacabeb59d595f77632c310a5c9ba91017c5788dc1c68790f7a72ffeeb0fb0a4f4c70d708951e05a6758854ad8a7064365643cd35fd45669d7f4512d95e4650ee4db5ba8d09d63329cf56ef0eede66dd134b36517114650012938b60c759c5dfa822f46ce1fc6aab11136817650cbddcf7d9feafa104dcbc31fc526a528caf7f85fb1b9322349adf47c8c6ad722ddbf7368adf223c8ccba16088230c09b3113d22a7cb8f2649dea7103992056de86f481b2a40fd3f14e48752bc195d5cd55bd93c5fad51a5558b026d0fc4662f9e7202739df7c4dbbef52e6c9c649a2dfd58b2e10210faef1fdc919645e1463449e5fe1f45133f2aae43d3574f1212e562515851f7d60e53b94ef8343451fa9fcdeccfddccb89e17373426a9fe8b6c6ab0c537b68d49fa219b1b1f936f68fd8fdfe4600b1e6f4ed79fbbd97d1b8d7fdea6c7a67773fa7ed4e6b73530aee9ed1fbd156ebe647ed87658764d3c57b46bb6c78de9fc715b6449a77875f1d229b6cc35e9fcf76d9ba2bb75af4fba53641b02c1645a7c7aae77eff57ad50a85451adb596bf52c5b133442b3f4fbdc3cae4e49819b5fa5ab93c766a00e19c686f464d69d09e67007f66ca6c4c5ac9415332128d827b6ecc5cfb84ef867ce8bb25c1d1e82e6450d793c65e646f4591b3dbe5cec28ab16af1bf38ed613f377d6a99db273e68f981870477498bab879a0fc1d350e2e888a522187c787458f66610c1dd543b356fb9317d9df4f8e8fac31ec764b6e390a8f9a1d0e2534f0e9422631b7d78513e1d2b037811ddd8ca93aa7ebb69f7f25f2a2d64f6f1ee6344eaf5e26e115f5e3215f0a9246c1ef5fd193faad06cf51d758ce73ddd55e45f0502fb64ef699e49324bba9c48a0aab384b85aec0c5eb53a3efc8d3afd72954fe3af1f920911de309dd763e611be58e7eb6b6b9b2c8e3b16a817fab61346f12402bad5faf05678dabab460bb62fea52fbe9acc60e701ff981fbaf4c28ca764b8582af9157af366a449cc4eadbd143334868ad6195e1f08a1405a94d6fc84814c0f88f4872c6c915d5edf1f5371a34aeae7040d95f438e55434bae575949d45abfd2ab5738aaea50bc762556cba9a4b866efcde1dec9c189d64f7623dd4be2900625712d608ca3b5a601e9a85bc0e6de4c64f8eef0f8dde1e947ab85b7799ce571b1341ae95b2d944066237dde42d9466db2c45762824412440c745e912bf16a7dd057122d82f68b6c5b6459dcaec27db5610539e3aac20351e141650ba28d752b48f650151e890a8f6a5ab8aaac60f0a29156525453f565df0405be6c938c2d64b249b1508d45cd7ee7cbb84317235ae401e6e1bc009956bd2a87a49f3ec1badf47c9850a13803672a737d97e7c151728d86a525a5a49c4ac442292ef7d11f9cb2d51037c4d9239c9b57001ee2dc0175818e40580f5c7390219bfe29db90ac0b043b964e09d28bbd9087a597d38e05d3d3c39fee386c5d894d41d5c7f2ec0943b0f6a891414d2c39413e9a3efa604309f005662af468d1e2f845c1fa6934cde2ddd31764fec95b448643889fab79593640ebcb99a0417b500b13264be4ed0d330bf2276ae319978ab36e529ab7e3c51ddd11ac29eadd46f6acdc3c0181dd10f85cf63748361cc9feb38bce6200836a8e82954dad9503eb47b49a287045931bc6be96515e2406ecaebcf57142ef9780bcb24f5fd659ecd905fd740eab9f9a91042ef4f5fe04dc9680827130f6e66b1fad674338b23676344fc2b52bc3f7df1729124fceca98f92f60ca7c10e8537980d1871ca14dcbea3a6aa791259e7f0def8274f9ddbf867c6b62af984bdfe594ed66028363ca195551f37d7cf51fd4f99765a3fd569bb2e02f8934c9ba7775672363c3e3a7d7d816e8edaeecedf6defc1fd6fd857ffc97b55b37f18820676f983d198c4897889d29eddd163543af7881f54b6364ea234f8d7d4053e43c9d59cb0df6077acfd7d71c76aec2347e073f3faec10f120678dfd2a5ef07282a8f5640336d8d78f8b55475decccbae762ecafc638f4046fc72d71efb69f5878dccb773ceee5f94f591ec5699820239eff0493304946e1f81ae21452f2a58059f82bda4a61dcc68ee77984b76626990ea41127ca1d1412c75a3b707b0b12426fbf6986f3aa47f286a431490bef81d638cceee3bceeb3b3ecfe5ea9d0b5569f3d8af5cb0fa3f19b476b3d39394eed59ef62adf32ddb2df812dc571dc5d4e3d7e415160732049f7c56de6471eccbe5811feee302d9974b446c0a1bad13598723da70b994951f6cb266f68d5573bf72d594ebe6be7f9acf042e0efb6d59fd552f565eadbce9f9eba5f0be42ee91c3c6b90206a0a59c0e0a5f90111ec14d6a1f9d5f51d5dc540ef828b9dd2dda16fb250542bc8751540af7f2a4c138cce34bb70ed7ce906767b3f2d94caab7d6e754514165f85b7f7f5735fb9b30e96c1dc18e5daa13ec06afce90fa19e3d3d21865b518e1d9702d112252e436b4dca81b4c08c509a1549b10197067ed09111558d50d2744d5ec3fdc6042e83a13825d5a7b4228524fd984949638ab27e4846719312784177eeb849cf0e3efca07e57ffd4b9ccd74ed1657e8f9df829cc7eb9393751fafabdb5abba913b147f115af85757a5a5b8b557bb0f6fbba49df3de81bcfeb75cdb0761e7e473beb37c45a7af43d2d6dd0146bebf177b5b54963acb55fbeafb58d9a63ed3df9cef62cfdcbba1b50c9bf8c9d37957a66fdfea30d44df097f5a570726cfcdd3003f319ec9efafb870f03175c0ef9704a2a51f03160826592e14523000be609f1aca26745a1645b0c5601ab6ca4aa34068abb0d5f72935d4127edd2c19d295376a3d67943cd9058d1e86a71767b17b15861066f736ef9bb6c988be09a2b5a656effa653e2b7beb2fd5f3dfb8ddfcc6269cef378ddfb294ec8d467995506efcf69bda9c10f8289c5907b79a33f02781bdce0e469a5535de9fbe40eff6ea88ce02e3515895d0d6c2f822e317d28244f03e8d3f939c86099cc633e26f88fbf06745c68ee3221e8096af8703614947c50b577f0336744f7518197558872983529ba0185ed8448765061446bdb3a0589901c42d764d202c33a08427be0135d13de305589ecdec165999037494dd384047ca6281c31519386356641688898883d888ae48e120e279185e1193fed2dca284546526a408ceace31465169c087a68c0f1320790078a3501b1cc82c4c8a056d3accc0326633eea60a2cc0b5d523bb0c2365ae0681963d1208c690c487473b5069f959940dcd3d604d2dd2d75307c54b7c034c75c0e3a0bbf3873ae16e730fc6202c7690d706c0ebf61ee2381b532039856b2de89c57ad211cc84c432134ea613d0e14499b536b82d9d0e28ca2c3861d466c0f1320b102dfd2c84c2ce5d075306581a982ab3d61b8f26a3a31465164e3419b39a66651698d1ae00f3b48b8690d6b4b03203481a65ea40a2cc14c69a359584d3cb0c60f45094507cf3fe58eae0e4e27a43c2b978e7b922c5a1fa6e804915928e4bea192d7cca6044016a5a630356e837e40290dfa9aa285405e6fac1674bb357f894696e47e1921ea6f289f30adfbb6481d33163d4cb620a56331f4a0daed159bbb228a6466531084ee3529d2c413515b3af2d093e7095ddd600a8e533705e7deda1b23b80f9494c8ed55078bb21b0484019c2c0075e6af4f5c1f1c3966f80260d4e7fa7d9a26424b44955155e678bdc16c1fcdd4aff5ac2f3172c4bb48ae3aefeb5acc19f58ac36f453b253a6b7a60a4db1a152b97be641e5f131e0c1f91b0095c0a7d9fbd317ee0e575b0367d1d990300655651dbc62441e02a721dd4bf00ac52644a52df2155becb27f72ea9219d3fd7099c457d3e224fc1ca757a7b1732679e3767020f3ef5ba0efddd11ee8f9f45d701f45ef8bb10d78fa621d4079d5e1132caf260e08de2e06fa5dc359f3148c381f0d5e168ec784d22cb7837bbca7225e41cca37c7478fe254358345df14bcd3644595d235c6a8b5654231efcdcd9dec4cfcbead0e34e6763976608e61802d8c48ba824f8a381db8a7952ae48395a6b66866398bb8a2c36754d97c34fa6f1845d060de28c5fac7eaf9f992ea2459b7224564a3a76a98ab3b4d1f22e27d1b0c716585886a08b47a51adfc90450f9ac61a23d4c3f5526b4d1707630a96a8099f4cb2485cd524405354f35394139f536a3325a6b40ddb06ed2f0473fd4b937f29ffb3000bee155ddc97fee3b37eef2befdd4044cb2f48a1d74055d78edd04b2c702de294142f6589052b74e09a28122516dc3c27388a259c3b607615154e6eed2a394930f00b63355e452fb1f187b478b92816f276cbee41b2c402b5ef41b83d39f32184960127fef8356fa8a7fc346b9d4cb3bca8ab8500deaa6fb571f55645006f557c985455b5b26a1a4515095d96595584451ca7c33e84fddcef4ce29c6a2a6309f9d228aeacf341c7fed22876a6459c25a97f88c4b9d19e155969c8efd61595accbb5564fcc67453ddf64ca9a623a2b6acab9f4d735e753fc193fd691aba6d6aa583bc7621854cb4e6df9a343744cdf0ed51c1ed2b7439be9481e4731992998a128f0261bfcb90f2adf599c46e44b0b263149a2165baab61b894a3e438cc06bba915f19255ad92c064d2608028e4fb4e2b10be488cfb0f58b60518c65a8e0eacd2389293fb9d0c3d93cf177c4899b18d3230c6f25a0dd180158db7ee9947f2a199e8a48a00118aea40a527cb8bde58fc91635d8585554bad28cfbe77ec53409c7f96615196c42626b82320c5d7a76f1d4a016821806d07b0a313cc3dc1af1d6964351b628cee20b3efd3a4d2be8b13a942d9c84f8dd2e484742f6f1a1f679322b5a601568dfd046cafc6a82f312078b2a6e7ad84a0a0ece589c374fb21ccfa26bb1994801acd7e4212b465996903075f316adc59c2b197425933a1c52c7acaa82d7445cd5d27bf97483d5648e8eca1cf5ffa371b1979a4f3cda8e8dec306f0d1aec2adb47e92f023b98dce0bbc585a8b3c5db6dc25fe171b958d15aec078b8ec71b498e205e9f34ab9f1e29e2d91aac6dc177ad30f7115bd0daa934ea1ae3e7971fd422225bd1ac9453b532aa8a025dc8d5cbb8863c96ac498e18873f87a64dc6891d4cff24b28671ea12c55f1e5e25d9284cde9499405a7ab37eebe71de89e9f47bff75bdb5f83627a4b8bdb34bacda36657132ff25ab9a319bec8b4fcd672648b79040311eb137d8e3dfe605a6e25b48ed0a07bdcce0b37b53e869e2fa6deecccc14883a1451dcc36c2a4511dcc7d84c923d4ce17533b04bfca6382846e95d9da2c39621aed9ec411013299907101f16c9ee50595bf727746276eafcc05803f78dfd9f8cf7c3f705ef5740e904c52b6243d88bcade18fab5ae44046ab6563e5b3c92c2ca67b232a2d8bc311f5b89b8fec0007229140a80dbb0ae262c783e6c5d683bb6836707f74fc8a2e0d15885d1553d93b558c1705a73595ea5d5f7145682a05b46ace8f7a83f8a3aa6435a8ffe85492ca0e6f25f1a35389eb53dcd1287f74db319e57ec769cbcf791f429ab6c067f6c562580a894c261149d088d35bb74462222b5f2db43256b0ba2382758c1e1b80c33a40fec40f37a756b5665d06b93fdb6066523708fa335419efa70187ce8c7a13d8858edeb7350d1be7ce47246b544335a8c4689e735b5db05ba98a3d4822c4d96b0dde9b569b14c081bf5a0cf0db021cbf1abc4675f7bc2286213638ca7673734e6d174bd1453d8df844069c5a053a9caaa48a51a237d3fbd6d97605df8bd2071e2dd4631ba3cdf677c59e6dc204b02c7ca7b955e13bded3c15ab08e63ce28b55648a6057f43eb505bc21774b796bc159c25617b20e466dcbb0360c1d4ed0d392b18b5a3cc6518b47516a89165fe6d96c9f935356ef76d9acdc1098869f0984308bbf4036817946638c6c1ea65119e61ca79fb6e49045d94d0af8566ae0c32c763b2ae7d2555c4c1723d4eff00d57fe1353ba20b4bbdd7ff4c864913b41608cfdf30160d46b1c60f9458c228f83edcbc961e278a6e37866e2605f3d693a6c1928383be0b54e333696e24b1313f62c6913ee89449d262a6c75a072efa916a446b25775a3ec76e1744a609225497613a75730ce2222c69fc262aea684128221dc0b420b4c5561e0205fc2d99cd5c82670330d45bead190953daa9dbd407e620fc555acd9775cc9d9cf3a94ad469543623a481f7283080b2a9476643e6ee6f3554b6f1c86dc1a83950889c16cca382d3155ecbdb8251732010fd15b61f5867a6a5e4238e93c37561fb41d35e93e32cfd4cf282d72932274ba9b9a27542598dd38c5f95f18be1522e386e6be0ca0483cc762dbbcb5a4d87eefeb66ca2fd1cfa287fcadff921491f540ecaaa7988fceb00fadbeea95388590c17402bce6eb27b15c7b4012765e313993eb6c007d7f21c96d1f52997a7fd078f7a4f1ef3210d8af09aade0382d3208c7e36c911665947ec81709a1cd5a646a6cd9adeec12f7aca6379f2610dddc3dfd8a862eb95bdd12716942073b342e4e433c92961b2431f00a77141dc3dd9eb2ed2517d50a0be20bfdf93185c7e949bb177dfb50bd7d8e4cb1aeba7edb6f3efe31bbf158b590649b08ab9cba9dd69b1856857bc2db0e4ab6fe7510bc2b8e86d812b26ac8af57198c1c91a6eb181e731d9ce116eb24d57456470eb88fce60eab75b980d02b7c5d7554ec7645fa1673f4289987795890640923320e179cdf274916166cd1ceb3382df0560724cfb39c4280c717f84bff97478f9baba74af3433604aa71c5fed639c060cc00b063c8812e3c4618874f446aef2a6c51b864c82c6cf26f2dae033396b0830cd3edf890610af54a56e34ec70eaefe83073d5f3731e7be1f958c806ea3fae511cf09e439b9787075bbda6505e64c50a6ecf455cd35539293eaee95ce6c3b9ecb504922f743afb88a282e94d9d78b699edd60d8d0034644d0789f5ea7ece8ced80ab38a3ab1e4c19b124abf9df21019ef2911feed3440efbd5d4bc80b437076edfce1625e6648326b799ecfb67c10fa68da10c6aa64a7de6dcc10f5f0c93679e460c3675ea3425754b8df7f78ff11d12e37d5b7e659784df62804611287d47729aff0cb04cb4b2ba402853e643ef3af900eed17464641207d304bb813f3802ee16cb0a175ca96e82cb0d7e65159824d2db07dfb0d93834516d807d3d65d82ddd8b4d9cf9b1c6c6881fd531af19b60ffb4c03eea6f7d25d8b2e1b3364cb29438dcef4f00591f3ef78a143f6ffbb68275f343d485033ee348b6a0411b17180fb85c757e667d85c629411acebc6f486bb2ab1396185f37ce18d60b83884a3e76dec91569ba3c359995ba1c2debf8c0edfba3d1048f18a1834f5d0e97e0f89301ecbcd597c086f2d0f36e64d0612a5c652ae40a32f0271fb772d7112fafaa3b9b885db6a418b7e0b1c3b0ac6d3ce718c15734c28a694ee8344b70beb48628dd81070f5a6a34ba5d0861426ed4741599fca855821d78f0d0a8a481f3e9d12e962eb49cdc22c389d35e036007b6b70d583eb345c6664dbb5832c04706a0716b2f2187b003fd3e18cdf3392d32edaafc55d7b34d3112a291eb59eaad2629fa88b6acef47d94d0b9fed44b17a0d9fa42a6bac35ef180d352e16059aafee5d65c2a2b825b48256b2d616c4949baf7a036819e66986a9ac7cfcbdbd857e0beedcb1b0ca4625f66a61a82365d2759ed12372b5af342416620f91b8f804bcab2231f1353be1883a467b9ae28b9febd540877c7bb42b2839e2ad30732b2849e2ad30752b2869e2ad1079489222c55b61e8565052c55b61d9b05e8470c3d45ef5302bbb5cfe1d4ae1ee5de0216304c40578df72557da33a80a86f20f0d59743ff6c007de307ac3f6b5c6845b5f5f5f667aa3e462ce220fef6e54cfadb9fae6c5fd5d7db9faafad38678f1bfa8a82f19c3df7eb4b27d555f6f3f52f5a30606d3c4e6fde327f8ccdffe70f5f8cbfa7afb43557fd8903a8e0afe916ceb6f7f69b5cf8a960da13db930183a3cdbbe8081295f9eea3fdf673f6f99f2039e1b0ffce1d9830bdb711b34970d5b189bde223e55e1e934a6dac35a9264371496d9826f993cbd312e57762935b612294879b6182e80a97bf23c21c53b4de4be93b80289f5a500762e7936c07a69aef5330398b7bed254d4d338be9f49c2dd3734792eb12bfa2d628a7c416a6f9ed2fa72d3e9084b2efe8e493855380285ae05493c8b0b4fea7bb96aced4c78bf5a642efa4672ab0bd7573977b88f063aea097f7ee6945dff8ec5377dacd2d4760b1921db9b3ab4dbf7b009107299efede93fb7e83070e37e0764d2a7e736f55c6b30e0ed70a959ba5992727a1ddbf5376421d969cd7ec8a8e826ef426ce7ca57f53b0c55be010957d318f8ca5435660d6335f304614ddd7aaedb0687c95065e03c520f8c28432a688fa82b6084d26f7b7be544eb8169ae1e7be939387ade2c39363b976e1864094419a15e886c9c42fbf9d73cd2d939ca8eed93190c03df3362bb4ec8b392cd2224e181a7c9cce6684eff6766ddca545bba2725830f9e334c3b7d3ba0670ef33eaa1548ba97a1e2fa62447afd33483719616e44bd19ee48408dd2545db0a11ab859f5fd8a584d168a0652c985e43368171928daf45567d4b13c66a8609155d1348b1bbfca2c31572dbbfb4eff77931bb336171f3cf5e92e55b0432a8cf62cf7d50f63c05e8b56dfd8ce735c068ccb151d3ae1fa66d88adbfbdffa8d7535d683f87473d75f64585ae7947fe269dfc37a9d99559c0806bed6d0a64b9d1993594d1dfa28d36da88533a8f7312c168e9b37889b23c8a9384089b97764c337963ea8e926cd49d85b420b9f8b9a3fddcf9959af3f751535bebe5439fb69bfdb0efeac8f156292d146cfe286d23ec9bae7683db959f3a45f632fe42a2e07eb3939379128e49d03d3fefecf6b67eeeb6a0d168eac1c04045bc2bc244ee57ea6d3970779b3b08e9cb705f0839c4a42a0d6704420a2ffed2a0101c6551d84489305f16531ee83b8bc282343b9d8e8367b428509c702bc9bf9f40709565571889a0e9150a8db7bdfd5a571624f924be4a319e0eebe833e8c12e34da0ddf582c670216f72963e9c29d812ce6c3508904cdf91d34dc34616d24d399078729b26a71b9672735125bd078db70f42b1f6157767f0b3e32a08f1c59d3011deaa043063aac02dde79197a900de67c0fb55c0c194edf833f61f8add39ad829cc2ae1aa12d9832acafab606706ecac965c6ac0e2ebfb8980f59d77b8bbea360c40de2b2b5df6b7edc06365d4312340decfdbece0a41385e2d0063183f20db8ddab0564c5db1a6816a7363a47f83b0ddaba29b3c081b63454aac083d678c957050ea0a5a512050e98a5a5e2050e94a5a412052e71d6864e3d5efc0cced25295050ea4a5a81205169815be6b50aa6c2d40614c5d02f2ef169415727120356016d8952738901911efe76dcbbfc03246b4f9cfb443541b9683d238b1d83b9e04b3ce28e6862981ac5053c6662b618c605c2033f7d84499f11caced5c42992e06d66140112eefa58a705160c159d1e706e6fdc601ae8e53e7013662d0d5035b010d7dd10c15948a1b670533743a4625b9863f90f643d0b4bd81de62ea0e7e593312a30a872008d2ac88c7fc2a370ee7711126b4d968999d6bda7473172811c6513d0fd5b84ead1568f63fcad0b18b34fe521963f64b0927d6746383f8c85f64d0f7da9486ff21a14ee319a145389bfbe3c223e0b72492804199f01603bbbc4cb2b09008fa3d27e07045fb5f7e40fb7a260b4fb8f6eaa9e5bf736f3579351e4063bbb3fda0d32b0f509414afb3ecfa85c82f13681183ca56389689719428d70fb2de531dd20dda0952f099704e245001a7828072b8d48a242be152154d56a4fcf60575d3a35c98d04ea44903ba8c3929887522e070f0d24bd8008fa91d921354203615694838133a2156410b5ea73b219a2df0e7810afa0ff9af460da57cf4d690473cab1b3c7cb2db0d5e6e005bd1688c21b262d168f927edf8785a173e957193f5a1da37dd1a75477e7b0e3c3dc639f0f5d58d5664cfb01edbc6ecf2d060f981edce6c4e03be59bfb1669ded1c65b9c9a998cadeada0977b86c966564e1507a7de5e987d1fb8dee2d6b2d4ad7fca5a66b95125f7697414abfbf43d95d54b5d84afbafad5a82f6388bd34626663fd17c64f2697ca2b8f359a52f029513c5ee439498b6409af4f876f1e8a143d58131dea947bddf6833646e0e42fce546f0c6b5ebe1c9e9a962afb7ba707a787c383cb37c72ff6deec40e3e3c78f1fdbc3617b7ffff4f5eb1d5407eb7fdd2e3c2b9b1f9cffc438a58867a48dbc71fe13749f5761bfe4e1f64f3cadeca0de7b0decb420f3c1f94ffdfa8686156d74442e83f51bea757a3d5f63067e6b8cec3f6f63164e46fc0e347c43be1e4e46bc07a736e6fa406f84b362cc11fd50c7ac86f75bd0fb46fac3c1c13f76789ae4f6d9878b0f1f361d6926802c9c984ab19cbec6c623cd2da14aa4a58d937831c20587855f9b78b8faa9f513f9c256a834642e8f6f97e44b41f0d990af4af91d06c0e37177424ae3ab146e6fb5335f616655c5202c18b00506d0e781585428469196c28ecb828fa1d9221f13769d96c067b16e23a0f05e9325c4a980777483825025ce3ad3901edfa46ff36c4ef262c9d3b4f2ba2d86ca5655f0de9c5d93e505bbec22207ef3e9346dfb6df94a57269095f3217e91232a4c0fb80eaf0c54f9f43cfd5a373f1976ee033792105d8a097d936594a84e912fe364112975311b1439b6325a8fa0e6776ef9894fac32bdae56c66bfd832c3506b8264b2ad03515e03559b6303e0f2bb083f09458bc93cf6673a001f14997b329fbd2c19026c79380cd98f04d1d676911a74a975c3f715f8d695013c446bb7bef0efbe945365fe6f1d5b48060dc84ed5eff31fc9d44f0212c6896e22bf79b784c524a22d4c8e778651d1e9eca62088687a74d741865c0220cebaf24bae11884f222cebae324a4340d67849ea7f7bae769f71e5ce1f9571c8e80159ea78165eb7b5e34d83d9a62ce4b7eb9392ff09519391ce7cee27601a4594d87941eb196154e8e027fc078d76717a2d27961ace4deaa95cc6a7064617ee559c6f8336a20c2fcca983dabee293b4a0c40842d0bf32b0d84d557206895804f04e8e965947383c88646d979213ad9992fe89461692ab2844713c38e090a3a31c57f110aeede65b845870d8c383869ca8341a8b1b5a3d096edf00e600d038f451b07d06a7df5106a74970b06b3bbb6c0c4be188d32349c61b8580cf32b2e13459771f958752c5219f453fdf7af3eaaf987af721ea599be40f46b16a74103f8238a84d222d7cdb2689110d4943494314c83fb99b35f3a5c5e5245a936155286eaf323e8352bbb10da580b42c4f2348da1181dc6ef9d701619b382eef1ea274565b70b39b98a6941720829344ab1d0c0a713ca7e4a0bb48983743e837938be0eaf0830188e82630dccaa67174eb6313e0dfab0eb03f1b5a9f75780dfc46994dd743489e10ed079fa3590670afe2a531e193015cff94fff6b148e48d2cd17293b6075b9d535ed123aeb0ac8f39f9e9ea7a2f624cb6fc23c7a4726bc7ee37fe504939074852144b7846894d5de91705cb4e0775850f28203629cee219965f055a0ca1910abc496c4e994cc24280c38029e48439606bfe3b030e017594a17335ce47abd8e2c17d1aadee6d9e73872c164398a31353108227f0a2e7332115b2257499149fc05c79cfdd291df555cacf1344ea21c737e2180fcaeb6e471368f49f4b6c42386c3de54b4538b3afdfdfeb5a528e09bfcd7169cc91291585854d247ee202118165df64a8512c357d21d8b268157528e671f3642e2f0a3e85c50f2b72c2b689187735e37e0a4b4e4018997fa87afe488409f14a30f1c9c6d21b2e29981f982fd6494485aad28e58ace17d96c9ea56c2cd4a7166473e560a4c914566a6c654d5124078fd3b483a5f244292222d2176c41b2f3936a46bbc7dfbdeb2beec414e74cfdf4945d2a0e2710170d0aa11af73081b104412717a08b9c7003acb451c02827e135c4423c859093093f6231ca2e4517d83f8a67c5300ff8af82a7d5af58f873b9bcf7a882d40b5bda75c081b4aa0f06f0398b2334155063b5cb24c104d5c1b8cdbee35fdcfa3a8794e5dafa610b6fbb05e5ca55eae43952a42f27846dea4a95393dd35bbb4013c2094e06a1499c16ed28a6e12821ed947c29da09db7850847559e5369b4aaa6bb147f4ad1c5fef8ac9e6b42361e4f2966fed356b59e35f4b3e6473aac50a94a877d427f98caf2488808d623a4fc225db4676e0fc27456970fe136c41d9604703640bb0fc81fbc66dc1f94fcdf39f10b92d3c7eaf5c90ad529a8754c9695ec0569675f532a4f453bc2cdc836136fa0f68e33561188fa724810f84623b0561178787d086edde760fdafafd20027ed6bf03f77ee4df797e9e9a5797613cce339a4d0a7891e5f34c9834c05e92000251c80925f96712755865cfad666f1e8ea74412de82ff2d542bdb9d1e040ce0fc27f1dbf94fcda768813d0b97d22c9321455ba2499c10761b25f3829d3f993849e2301d132e338ab2890e7c1438b25111b2b32adb2c96904d189446258485bc59dddcdc744224b493e557dd8403d0ee9bc31707472707eded4e8f5564ff7ffafaf0045e1cef1fc0e109bc7d77fcbf0ff70ff6e1f808f68ee0dede091c9edc83bfed9d1c9eb4e0c3e1e9ebe3f7a7f061efddbbbda3d3c38313387e072f8e8ff60f4f0f8f8f4ee0f825ec1d7d6458ff7178b4df8283c3d3d707efe0e03fdebe3b3841e0c3e1db378707fb2d383c7af1e6fdfee1d12b85f5cde1f0f0748f21624824244356d7dee9e1e99b8316bc3c3c3d624dbc3c7e077bf076efdde9e18bf76ff6dec1dbf7efde1e9f1cb4189ee1c1bb17aff78e4ef7fef6e6f0f423c375747cd43e3c7af9eef0e8d5c1f0e0e8b42347e544443612b3ad4fb21c6d7685a073328e27f118d5ad0b76febcca3e134c23027392cf62caaa5186314c236e038e2c47358e92f3cca07e28fbb34595eb57e877649210761a7c9b67b3981201c0fe9f89492ec34e18856326a5a5380fa2168c981c17968c369c78fea0a4782b77d2e309dcde9e6b968fc1ef7079891bede5e50e9c5dc0575473338ecf26c0b3e1ddbdab9dcd459b1075543d18c0e8297c6d5aa8dd3aea7637676b6bd4c433c5c8baff07f36613fe3feede85bb8924c91ffd2a69cfff800c42c2cc6377ed71336e30336c378f0beeeddd83b9a6a44a49d52e556a2a4b184dc3fdecf764443e225f25d9d073672fe7cc34a8f2191919191919f18bf2dd4a9d2e9377abf7c74ac6b59ed0f7268aad43112ca8fee7cc4ff604e8231669c31bf9e5a5d238d14151dd6eba763ded84d296cb63f6c5142f890273c2106755e7fed74b80927d303960476c7079e99777ff1ac2f3b2ea54cf8772c1e5a53664120620f3219ff3764f5368d0919a9ea1520ed1063a640db58738cb09fb336bac01a5bdf01ef0646442090af80c200f6e60fd1c32c5171df285547c411bff42ff610c66b644c440860e5993668e9910616d20c8e48dbbacd68ddf6e961351030f5cec9b9a17fb6a138977f8715475bc2d3ad1be1f6a3395694b9163694d9d4b9cba380887ef115ea95a47c1e53920bb6a56a81154ecbb1326ac554830a36d462b657a32f7208113a8eedf7f3f54da343f627b8210d65b842f3ef712fab5bc280762c89a6f44408f727b8e74e298b6ae886c893964ad5a6b301b0e19b705bb76e353ee7aa17481c1a0a15af9e7cfac79f000e345eedc617b03d55035528b3038381829ca1cb0a24543533b32b8aa8630e62fd302b07c000846491825087e455c9823fc0ffb4224ccac6a8aba0ec6170dd8d0a18591b53018f5d781a26ef5ee621f8973b1fffee0c0d0a33ac8ef23db2b9ab50f34780c1fc100c9f0be04fc59b45906902b6001b2fc5626d835d96abaa583845a45abc4f3b4e8069ac5a8143a88f68f1d5f83a2f5d5f7cf7e7afbe4f4fcece9e5d99b37afde30c57aa70d64a06aaba2e9d8aca86a5e0ed9425cf38f5a3fc065aa241393d95a82f318898741bff4425d3acab50117adea7274b17f6c44fad98bd7e7ff73a9b4a8ffd156ecf6a2d1e270d672fe0f3e20450e827aafbeffcfb327e7faf9235311cb604d1a3ef8927fea9e7bcba04973ff3eea24ea60e4a3a5987cfaebba2add72ba80d1a2aa074b2e6531e7a4194bb201c40a0e9929e2f61930d1c5fe7f5fecc3cd71dda82be2425d1be35e5c730024ea9a233daa9d0f5f3dbe08818e2ef6dfa9d9bc677865d3eda8fd1cae3e3d7cc7785961f7d8ebb66a3ab5a0c65510c04fb09521c40f802781da725db544ad91dd636f80ac122327d55815e7386f43d302bb2e242b6ac5bb1bb6525d0133cd44cbb1a1b1597b57f70556958e751c36a12d3458caf950b123a68423345bb562caa51cf1e6e3e8e5aba76797672fff4b4b5dc7b3eaba1a9fac3a0c94341676400a93b15cecdf05ea2fe51caec277313321fe084de0cf167a5d5dd52221a3fa8ba9605fdb96728e110a0f0eb78f3dd10e486ed5882da4343f516bb1e718e9a9ad7bc4ccb422518381a3313bbd28aeb844f3548718ac5c890a75672fdd61ae8448f3515cf1525d2297422a2e9b1ae61a7b6bae3e80a527385a4d0327c1d493e03cadff30adeb1ea4b503efe470ddd82987945f37d33e852bd01cd4d81b215644df8531ea32ced6da547f5ff3415dc92e98794bf786fa519519cd447b564c17c42856757c99987c4b980a8b9cc45c85f3336f60aa949b4bc40c2d9709495a4994dc030bc2edd7829f81a3e152e19e6ef0036e597cb6d1674bd8feebbaa89a4c276aa6ae21e8e1f367bf873daf87ed9bca06a8b8bbc8dcbb830e02b5c8dab4a1ce89ade5ae4960e7365fd52013f32ccaf26f555972b8390c70b868f47b592c39c138d7bdea4ef03dcade3ee37a1e63f066bde4ad3aac8e70d6434f656cab0ebf417a2cfa099d88d76de6b356b3e13f01036566f90c729bfc0b4c35fef6ade65a4933d627a4456fdcc1962fb99cb6d50aefe88ef7c875f2a92de1b71332e31e69eaf36775e2987f8ee8f46073e0e10e2fa6b690a18f2b905c4d2979dbdd6496d9a37b2f3abae11ab00b0dbd2d0d8addc5fe93a269847e4559e916f449adfe69e3400607facc1613c9db8faaf121ab3a8c05ef3c5680684c4b97aa418c7274e2b1d2254124e3746ccc52af5b5e5610c8d100d74eebe21fff0818c1f034a8f2957c2126ff0d636f20d9b439d855452765de994aefc3532c3a2b3fa5751d2bca3fc1edf0136df12468f34b4a2d30eae2f5824324aaa2903926e13ed1983885b2922d9f172d38ea1ada5775d56d92da81760ef9b1bae2dee0f5c07d0f924f0080a0266396d4fc9edca4676ffff4a258453aa00b9f07a06b6b547c51ac72cdbce5ddcecdbce55d1f053b8a947fc4c475c3aef8460e993b54d4bfd91df824d1e88025504bdfb0a2e5440826c9aace3577b8fec03752efac801d5d33520791a8a9128b63e0f7a21b498b63392aca12bd58d405ea5e51d7f7e8e740eafbf20f2d2876980975e82aa10bed2a4aaf0e466e2091a2144dc15396602ee2bab9a757c3ce633c662f45a74e12b8552f57f8ce57181519ccf9cd9c343f6455b3e06d0519c6b0b56aeac418789decb173a5785f8b755dda7bfdaae55db761fcd38a37125078843a7187642885f4d02ef86c564d2bd89eda28850a7dabf910576765fd1e931b6fd68ae5805027b5cff0a9bd9a6d7ee01b7429f4ce04c53877ee28feb1a239a5a9d1ef84ff782d79a234302a96553d8635bf847be145b1521206f6c1b2088f2d5f1155df5323a44e9baa8c77cff4e554ae8965b11a2d8b157df72e126651b0aa4fd889b14b5e1643767830d4ee9d9793770f630bb623a36f37f387696522102190a5e6f7d4c8093ba849001162fb957f44abe3134419fa0ce155b458e1b19c3e513bf1baad9690d4a5ffd6419e32e03f477d770ff6985dec43f7f855ab78beadedffa8cb333bd166dec1c53efcbb28975553c173345a1dacadebb4134b76c2c6f7eeb1bf802f17bb376683e4add51c02eacf3df604b406560013179d588ed833a134c4c97a3e8787c075bb12924badadb47c2a964bdea80b7827d85cedfeaa53f50b63cec186cf179c89e67b80c6c15555d7f3a6b43ffed408f3f35487ef49362d1a3681a85283f3a51d9c974553cc41a0914ec6f66030135574b008bb81746e40d1b1466a75496e8ceea3eafd05168598fd8e7d432fbc6fe91a9e82643f56f23587a81f3337839589373f037b84d18e8a726b5dae6ae623f67d2139ace342094f4c1c2ce05db32d985875d5b2fa8706eb94825590e62a226503027ace3b09545592dd585bc10d486d8586f3929789d17fcfab666e172b3485d882bab3367d48db6265359bfd176e80e0e904b1820ad99d4e9586cecbef379932e29acb4e8fa8056b2b3b61cf9ff2b642daa201f6e5abf3cbf337a74f7e78fef2afb1254cd194bc9b454c79d26fddc12907957e040f4edeca84c0ecaf9050256afd4d71244907aa7e0226cc3c3eb867a5cc0c095bdc648eaedaceb34c54f92de6e98baee7604b437567c9bb850089d488ae9a6d18c84b50313662dd8264837d35e1bc41f122c5922fc4359559562b6ed7c60a8d1a8c8b8c2bd0554b6d5eedb89a9247c182b47c25da6e1786b326305ac1c09cdf9c1e97c5ace3eda5f79ba202228601bd64356f8a9ad0aba86b142e7697cb05687f3a60576db85da7fc44f7d333637002febee8a68b40862865b098171dd78d045460a0299761cdeca6e81cc4c136ea5b419f7f1a578de3896d140f74dbd4e770fe2e8e47cdc5fe109a089e9cb09a3dc386d101fa3748c3d20e13925f7f0a94c94c03c131982d05a6e563ff5121db75a6d144b9b05978d744caa9f3c41de2c7e446611cf73ea8ca1face460d7555dc3b15635555741e02e5c6b17425ca9a369177280d958781624f5272c3e5083ccae4ae611264f872dbdba0a41bff1a2c73d9b375ccba79e537355f2a6abbacd13b15c152d6f0785eff6636ac3924ed2d7acf5b45bb745bda58992f3d5d9dfd7458ddf534d2d00eef546ed60fecfa829cd225b9ad257a74a864342ef7aac0b5eda661535b58e22bad91bafa3c7518236b6984d30138cd4b583c4380aa97281ae36fa76a084f5d3aa7cb36e7e2cfeb1796ef9be95c62d24b8389455c9da75c3eae21f1bb24f5a49ef10aaa4d65f9ff2a9805bba8c9a5a610956da22b40d773b77668f27e084681fe0f1c5aa39db5e32908bc6a042e64b6c2beab81892fe03d3d25437ed0ab0c73da33dea1d62781a0ca0753063be0f3d07e9a793588ddaf208c082170662bc098bcdf9360727e0654b3c733a25ced5c4798833884a7d898621fd6184f7e65b8fc50dc2006ec583f16d0d49336ca24b1be44c2d919787437659f8aff71886ba6df3392376c274e1bdfe95749791d6a34de83b70b96a015dfda73d6c70b855580c71ac1e35c763f6fdbaaa4b670cbc024b6f5b6cd07e3211ddc242f7aa5b7d608c3453bcc21063ebd1d46b6c25131b7a062ef221b867a69cbba895585e1e42f7da2351fd82a62b7979089ff0afda33ed98ed994fe016769c2d99e168639b3eb115476956b52c00b82966763aa83951169c67f17d4ac942d1dae5c52feabfee590dffa55b3db705ed4fa7b14b417a0fd17f18673c352b70c603aa38773c20d397e38c735c747d4cad1c73565aa4fa9d3bc18a80a3de65e19603b7d5c101bb2cd0550f7fdf323116fbeda94969cfbdcbc3c877cf6be14b2c57dc096577ed60e59f57f5e68c58de83e58cb514a2d4e8069f15d34eb49b50b27b92c4aeec71b608bd00e91fb9e526cd4b8493c015e5f972c9cb0a723d0662e2dcbaf041344151b355d1164bdef196dc2ec19d0bf2d1437b95760c1333f014d3031b22eebff63977966068e7aa5aa13b61d3552d47501a5d53b5b42ada6e180c0d9f20ec63183c52a8c968e732438e4e30ae144b491e5a694b194fe1902e4eeaa7f93ab77f638adb9dbdc376250c63fd3d7ab9fea60fe37f5f17d32bf96375c54f1d673b97a4e8f18ab9b7713fa74325fdb59eac3b88312c6473b7b37e517575c56939eada46a7b0b7933b3c3d02a343b54f86db77b1a7373fa2e99ffc891c3530746107bf7e19a64670b08350eb1d625e0b350c7a84ecb803ff1e853f242b39b63ea22c9e2eea9d5747661bf496b53be328f15b44acdc33d5eed78b1e911e182f8f4313ebb68d142fca78ccfee23642f0319e2e3ba19ed2b9b9da7a2194454ac278eca52104fa06a9e6232391901c2a3ee1b9ed2beb6aca2d56454edc8593d81a5861c54f8efc323e790703f8a07de941ae3fd22824de8fbf3f6077ee78773d076c22df1dbed7ef7ea8255fec1387c1a000a8bf17fb07616858348c3f68f40e093993cc79739030f080b9a459a873af1d7c1cb2cb210b5ec5c663fda25734c429c9785763f40abd75d0b7d9c1c7e4b3ec476aae9362c9d11b05accafa614f27e9d74f81cb755774bc7c4cfbf1dfaed31db9f18e0a2c36d48f7947f8a4173d347bbe9ddbda14badcd025e8d9d6be7ec8dedaf45215daa1b1b77c87714adef535e6ad4ad2e6d6cf21e0f3eae729523cfcd13e77f7f340c83496fa69afa9f8772468f86b9e321f7b7c206ec74743d847da77f3b766aa2d9d7d05876d6ff9b6ec966d99ba60ecae6ed2fe95fec80da3b2a528ab59c55b36269abb9229104e02ef7918873ea91abc112078855a5539d48e6272c896c54adb2b7827d35e1f2d9ff19637536e7747c3afff2b30638dc7faa51d1d1a1b75b7a0c40ae8605a4877f7160cc674338aba84f2c93d7903f5bd4f689b0823bac23010f3de87898390b8404d724ca03d453bd2336b9832367a32853457e98f39591503b0d843fb99682da5b8fe4b32b2ca7e4cdbdcec2b9d7f69d77e170104a2d3fc5e6aae77d7b5cbd8d242149ed0467783054c5d3cedec02c76bf2cf118ce162ff2f64b9a6e803655613ddd0d415dd1a29d8c585f64af23ce8e8b4d18559953bc088a4bf4cc572b5ee60efc591482c5420f162058ab3710b71a30e67fa987a8993178bd4752057965e029317557a2919798ef6ae8495d6dec48af860d3fd8c8a92d82ee0dee7f30e25c190c55cfac567580ccf2172e70cfc81340f3108e99343347654922d8ad58a3792956b78ecd6006b9628e838a61bd3daa8690a39d0ce172508e1d5e09f7dac4b49f5d8ed26c7916ec3a52f3e603bb86ed5645acf86f0cb5a76904f9a7780185fd77c0ef08a665b57cd4781e6253974816b80920741e04ca3c9273a8573a15aaeea8d7bf9e05a4aa0299c65ef631ab7cf0bc3657f668f927ce73b283e6fa6a205db586a16234637b22b510a0e9613fe690566b566e36e7129abc957dfff8e12d7ae962b56400e86c735fc6b3ea2abb968c663f6bae546a19c14730999ecd00f914c55acf422aab315dc0a942aa088a2ee147cb9126dd156f546173467bcea07928cc1e22d8b5f445b758037332d243a16e339800fb0d02dd9cbd829b591a086e3bdcca102e4f43857141ab5cc9d2ab36ac5a70db67761f113fca0e4feb1053e23181b03998ab040c2eb796ffc7fc3e1fc590dfc335a3b3f8783fd0c233bf83fe351c76507ada4225e0c6cbfa63a3cb6a0c5f6c02d9e0ef54408c944384f666a5154830d9af5c3eeec2f2e816a42c9e827a3ffb48792d035ecaeeda9968d0a0ce5879443e8f21223d0ed4ffd68743d6186b16841e1c0cd6ac92080c854a26f6db804d67b2f62afbcaf09d4f4bd2914659e461a575297a3160be74fa0f5ff1ddb08aeb5ae9996cf766c22d2febd465053dfbd295fb38f0106cc9767ad589a3da0972ab64be90fa370e3fa876dae9495d3be4c77c5f90a381fae72b13616d125d694e80aa6628ecec1b7b230925ae79261821ef07091722e96c695c60205fc055e97d84710eee83f7fbda8a60b7367d1a958c99d062bfaf148d34024a8fb4ad1ce1fc1ffffdebfe6d1d3570a808c5ba56487c3d2d862f98b4a19f35f061780eca06d67f6977f65e39e536643cb49c0c0299b09591d9f7f43334fccb929238f6a2e2a7ac48895257dcf88ed2cc996486b68594915885ad4f6956c8bd8aab70ea0f2e336986afe27ab007ba9e1d79405caa22bdcb61ada904ccf4d522d933a673ea618c128737a08900bf4ba927c88baf9447c22ad7db501c8a23dd059eabbac9b696c8019b1e733802fbc2e9a0e47a6554c7f4b58b9a6a8a5840af21c226e90e626e293f665f283852053b82d864ff415f714c889f81479440d592ce659ee1af15de21a51994b43bdf949f2f254ba1bd5c5fe447c0a8f7818276434cce95e82aa97c19a2b267235e0ea6ae6913bc50e864c8cd046889a9118a1e249c495558a61631e79d9c6dc2559feb6c482bebf2db9c2f305855330a7ad844b116a59acfe3f22d3b258fd963ca5a4eeb72050e07ef84f2490e4915efd2d09a40e926f4120946f94461af0b724ae08793a6dd7766e46b5f485e496840377fb115cc19c2e9b303079009944f321f0c71e356efc2a4e2c0cf4b230e7ddd3e0575838a0815bbec8760328d08504ffe5d498c98b12f96ba6214d1e7373d934c5b29a46d64cd55d5c3fecfd95cd5ae352d60ca0832421439264ad54d044e6717fe8ae45b323ef6697f5a28f4be095dd53ae035ffea3c47dcf196cfc63df52d351e658dba1ae79d596ac6babe995d230aed4354bac5b751f00dfd9a69af27aa3df57d678159243344576555d6b926bd5c47668111f9df1e80a6115225524055ea05f95acc783abf6aed1c81e8996f09b8bd423d7b6ec0ec7a0b397fe2b165a279c0e797305f162ffcc9a361aaeee90ddb5705249919ade0121d8db8e04de3146ec69558286584ca710d701dea05dbb519595fab7a5015648c7dc8f9d52d8b8409235f5dfca3c386900407a64a1bf62df9bd3ce4f4e6a2498fd297c2092e1af9263c200ef89a692da5bd23e36cd04b6388616609393957c45c2948fd8ac801428d489d522d9b4d631f3313b9572bd84dba4e77d19b757352513eb4e09fa924feb02de388001b58f6705367150f7b1f3111b14b51480d0230d7e1cbe78914981d59fb70723f6fd1a1cf45ace967c29da0d5bcb62ce472332a667a29d529415d688eb21c3b4140bd1b196d7a228ab39aba45c73a9c607f8fbec25a4773ca26b23acbdd95bc1770f2133c5afce8298787032fdc393d313cd6ef0e0946321e76188d122a17f1d284f5271878e6d3d7293fce2b402cde9ce3266783d611e0b77c1e057ed6d7b6443ad462e60ca48166734728d29c643680307137244de201557c19d6440241bffb46a8fd917633e7a265a56f37931dd385c03600ff03f451b8964676fff4865ad7e003a621f4c5f83c1013bf90e1a3ff8704c2c4c9418d4cfda562cdaf961c6d6e46b578f42adca5732c66337f3d4052424fbce9623ad0b1fa690f4e0f700cc021dd27cd5591539ec19f0e057cbf75f521686db8f7e3c76a456ab6379f6f1c13730c5dbc7f7981e0e8179c82ef69f55adec1c2255271ceb7c70964a56207f7280d98fdece5d778977c5dfab6ecc9e671d08b7e44158cdf0c9bf70aed849b8502d8ca4979eed510c5d02bf1e51c904895cf08c5104f17fc753266e912056db364d05bf050db8e1fe8e9e9887f61f17fb00917b4f9f4c0d6fe1b9163ebbf07472a73264433306e4ee39769a9d5928e30c7392936e361a3384a3806688b2157ef7edcb085fcb265c1d29edba514b3810eb4e5625671388b951ca209abc1c8a1979f21a8f1940a35692ad44d574acb4fd197cb985a82168b3683668012c26ea182df98a37256fa64aefe1d6221c0ef85df4c3c53e85dcb8d8570ae303751364e1176a2a6c84f5e7223d1b2c0259a963a62e64a729eef92a28551ab213b57c5ad4d3755d749c4c34b48956925d2f8a4e1ffb10b8aaf4819bccf0a7d797e7af2e9f9e9e9fe1fc1ee2f4e8cfa1491c2e1489b961b4036657ba6ac4b5da95794ad029ab1b40cbffbe86981781de1e6c06e2a59a313716c535af5fbd7dfbfcfb1fffe7f2edf9e98f6754245af40af096f3f81fbbb0580bd94648738be2235afe2bc92440b2a8bff0a9684a36a9e61e54cd11a987f35f1488170640426a1c4a3fe21f79bb89494110a3af17bcd108361e7acd2e2b19cc095653336bf889aee8696a8d287a469a6361bba2d29ce04e442be0689d773408a707ae2aa39b4c92cced11ce8d4ee9cb41248600af33faf184fdfa85205a9cb7c594bf106524d4ec0722cdec6fefdcdf943c78e9ef20fce1b8bfd68faffeea2d14fc7b4b9defdf9c9dfee09140ff6248600bc3dcddbf82493f29d6f3457706e98d10bf69175c2dfb63507d00e84b812e81b9520096e984c17fc3f8dbb3e5aadb44c7b43ec6822e707e068984b84b8543492098718a16996cd757c89f554d29e11266d037e150713b44cc02ee873d534cbb355cb0f5e6311af9f399ab5b71f9d6c89343d5488359e8400652a9efca0f7533d52c1c86d9a4a60527e2aa8e4df477043208bbef047ba4c7a79bff7ea3710be10036a90d684de3702495da215acc8e8488e51b76cd5bae317df07154372b3bb15ae92b2c2071826037b2afa83170d2cd1d54e6a2d5e9f811df0bd41e4fa44bdd3af40f739f70d6b5c5f48a976ae66e654608ee58498b1176ad2e4072bdd478eb1a891fc7f549b7eb4d3b5e6de39886d3c0650c8a681558693b9666d7c546b7bf5eb175d355352b001d4cd1e7d3836e411637f9a88f8d6a4a0c5c6f84e5e5750531cc8402d1ea071b755a481e038eb983f72863c18ca1d3d22d516de9687b7190e9b93e2348f9741bfe997794f4bfc473ddec19b8c2160d13d3e9ba654639551a3d907e1c4262b1df3d3afc8f3fa68dcffce3a93a5361286f780129e80bff97b75dd1768318958036f2536338fa44710bfe1d2b22466a23f0989d01d4a890dceaf1601d9cb80d39d49b54ef945505cdae21f912340c04e4e533cd69a3d498c4048d3896b12cb0df90d5684e35c959c2eaa964dc752e7994ebef176c3595408a59b78ee0ae33f92517f56aaad0bc263a4d256406f95eac9bb2007b72be0186ef4bea363848c72ab354d0aaf9937e4ba17fb2a801371b41ef2818c13ad83257a6753a0e421931a83ade72893e09c449e99e68efe98489a022eafbda522c2173e564dd797873a2e143836457d4f5b631d80d70d694036f77f4d340fd09f69e6921d8a4dbdbc9c9a0f04f96eed90fe3b1a28d7f6bf92026bf7c88940a7bd84fdc6e0775dc1efea0767be876d16e26ddaaaa1fdc9efee07954f15649401848dfc88d15e76dee78eadb8d7d07155852d207c416b6bd2dbb7c0b56d9854d929c10fd18fd804cf034a4d3b97848c91df57a136adc960259a5208129321eb338b1538e7b8e2807e8651f8f911ca2911d6bf8f553be32773b529329a5bcd91cc48c45da503c48fec9d07f7d978448faad8e541c784349f1aeaf98e86068d202833c7e5b1aa10ad50169e02068cc045fd800127b7300dd47fb318cc72c04e0c745006405d3732243183d47819dbc0ad6ba8e98c0550dcf64eb4e2b54ea36012a16312bc88b187466c1a757cf67d0c90b0890d4812fa72d0796d4c881c17be0c2bc2521822f803e3b7128ab7f70f61d01e31d8fd95b1d1008118f4a451252561a9945abf94e2c96de3b752b96fe64006b9e73f6bb7ffb8f7fa736794a3032eda77c05ce380fd99d3bdec8e3d884dbb91932784db6a6740c6cb4e77981648489c20509668200ced2bb46ba494b8da3da5a87dbc0723b62e76d858d425ceb46874bc04a44b8976fbd68cc04e92ddd516937eab9ecda6adaa91ef8d0e46ad651617e38985e8f3ffee9f7743df6e88238b98760ac1270983c46fafcd9e379decc443be5a79a9fdd631638fb7ccbc51be4bb4d9d238fd9c5fe5b30dce1681e2802a9839d376af1ca61b8a43e436bfe3044b6fb55527619b1d7355777afebb640d8a22974d2a86df201eb7c4085af32e644cc62d601b27a924152933982c9108e04fc1c3b0164889097bdc782113b6d39b84174ed06ccbaa64f5d5bed6003445e2c57351f6aa304648076a17d3356e867eea9c9c8fe38358d03763f359380f7f3820e4e5822e0dcdadc3a4c9a8e27c3f67853f58bd2926e146fd05a2f8116bef981912c79d745dbb8247904ec0a2401713d69acbf897e22e245e9d82f42a38e1ef702f3ddd9273e5d77ce152248a5f761f601edd72dc0f1636c05156d857dab2a3476bbb1e49d2fb4950925cc4cb44bfb06253bd162dcb1ead653a9b5bf756c34c76c03f34aaa1b95b19815d2d3be8bc6da1bcd70e8689376a2d4959ee8454336b3ee0f51b6a45b1a2fc0c5899bf845ae035f4c38a368d87dd60ab1845d060a9f56fe945642bd6bb09e33e955cb259af426555352c5d7d4b9a14a4cae1b0dbf7e652c18069619bc9853260ef32e7d9f1d3e7c986c6edd4cc41ac6289f8875d37970ffa45cbb6e9e97ec2448b00abf1e874b716e98ed648bb6656b6e51caa8fd268cc15ed7dd714e5d49db49728070d8183b61338c4f37bc16bfc9c7f690a4fd636b832c07e598748dd58dc14b79f47cd07379d989c074dd6c5b21f726795309ccd3895877aebd9fab6e013f6ca97ad35b9b0b7431abee1f47371fcab7ca291bc06de477a23ae71e6e6bc0db62fab832c71739913e7ff676685460a7138e70019c7054d4d8134e2943e86c355eaf4a30d75c2361e1d8331e0ca13ab6edcc2babd94c324fa2113c134535fbf250ba2074ad0c4d78a2266653a5478d6e41dbec5cee04b80a7851896a7216c03d7540f56d071fbfcb7a08f5da89f6b65d9387ec62fff9cbf3b3372f4f7f6498da3b1c838619906c6b4f0f0ee97218594dcf9214df7a1504299ce472bf11ba3c7ecf983ee625f91e3f77f7bcedd0f3fbaf020073d6f305bccbf95175082984ce1936ebcd11a655814405f07aa2e472a10ef53522a0727940dd23187b78a45fdae09d05a2d286f6194db043e8053cc8abceab787864b204918a652b6841786078a8ce5d7c90e8399cedbc777e99d029b7addb78d5ccc377099d8f9a66050219151f414129761899d3e06de321b05b95b49f925180d341c95771230fefdfcf1f91e331fb69352d24bc8ede95c58cdf650bde72924e095eaed5e7e74e160e95721b6c8b0f56638bd12098f18cead8a2ea10da02ae8b4d5975014a89a560b4efbedbcee9093aefb23b92fd6d5102a2c3e8845549652fd4318d3dccfb1d9f759bbb1d4a62708e31d71f7bdd18c05d159c2d9742ddd84b71dda83d732dda2b56b48abdd9b3676cb29e6b6bc79f0eff7090dfdea22e77d8de1862adcf02c8b483ce40a1f03c0877b9cdc45535a12419da9c603cb1cbab0ef6bf0c0c4a43ed5b05b1ae2e0752d58d88f878681aabb51ef62a5827a76a2daa9ab341fde041769b7bf5dfd5b7ddea2d57cb658c48aad290e56cf5def60c65c4c3a42ff0ad8436f8e775c44d171738b188ecba901005a1a8abd61256bf166235d20b621cbd4aa1141788981f25d6548320bbe5acb9e210c70723e866526010d1c360a1aa873d2be589c21d962974dceea7b6f96341af765e45ba4e6f9576e45647ed5f5b5db265b1311a94ec8a9a1b2b269caec45e90f61a95029ff7c1ef705194ac41c329467c3baf2068bae152b2c1effee3f04f9ebff8764999d4b19c2611d0b4ff596fbb603ece34661204bd557319a494626752ab79d1daf6775031e965a16a20ed16fb4e291391eee8374d3692765802e725fd26000ecea1c298f7a5489d22542b7cf7de6ba84a3b5e986df3e0417043f28411fa56a43979cb026e4f50e82f867d821c443643a340a7dc5c4c99c82a60d237a16d2b615948a665881e427b19281c4d72c8dfca2ee361dbdb18519e82b68d67e146b6937922d166d2c417fcb89d004185e4ec438b73645edc910a199347861671af7eb3ee2aad153013c9fa2191a0f303d3c1a023f46ab6af11f0163878c444ab0e197b8edd4bdd8177335cfa66959b3b4b1001dd632ab9e9664f5c2077946a37975928a476cd931a8cccc0f15d73adaea86b0de10bed3bc7253c5d69a75603c6671f22759423d84596ebbaab56b5712180b80b8db76891f77434023ed181b1f7a1f5bc6ef827fae1d07e308cf1b25892645cec249dbd9de0f67baedaec8b3aae9a62c969ceb24a3e23ad3f2109b948085fd0f19d3b992f239ad0cb77c7d6d91d512817b6ee90cd9a216bf9ec76ef57db82d4664d3244cdbe425a10e509b75938844b3f136149d230453b073d2e0a78b5e7be465774ed7b611e4fb586001a1a820b42eaf9219b8bee48a7ea267d7919bb5918c4861053db527c727c06cb2f86c61994e978432285e5a8922fc4e41336c54e7cd7a6af03fecb73664249d73b012d0c66270c5a4547c3f343f62b5a4c8f283db379772f227b78e2a4e9a7a49c8a15071a860764bb6e9e3733c14ed825a4804d34402b6f5576668d8e124dd6b273314f1f6d1b32068e07333fb113c65b3fbb84ce0d457eedd7a62e7953ea39e9a67bd5a99d88e053106ff96f571b80547bbbda9ca107c3e00032f7900de81d30d0d179b5f42f729020dd36b83bd26f2a9baf6efca93a721a713d88b15d6a7682d92d4c420b7ddc01daffc3a8f8ac2eba4ed153d5a08f91752c9b6a752b89254ede92191685e2a4c377d57b0c6d8d5cade56af3067cc851218c739c6d5680845a18b91b16401451b2da610103d6834c105dba5df61b3a606f3367a4a4d2ef3ccd377bb948e6678e5fc38d5f105558f56fa917f1af7a4ef7c58747767f5e47c1bf8761d168fc47e99f7b2ac228c36af0a357c9eead23f7d76172e71cb9bf7a050aad171d795ad2fdfbfed80aaa5b1d85ca567c80c5da981184a6bfe85914bf278e8284c8f3559ab033254ec2ee028112a00e173ad6a72ba65723486bbb116bb5bbe768869b554d2517ac3097dfc7493d213f699f7e9e74f40f883d0f7dd81f33bd5ac9f50a22fc8d3b103809c8504db0238b368fbab9d9c1a558b3f7993b5d3378ee4e6451f72ed1b491a709630825ceb738428c54557dffca3ad812ee2c610fec62b9c32625e6765a05e7919dbb3f6b320fa25f10b3277dedcfc8c0e8e708eabf4fcd317aedce069d2433250c3b6c9b8eb7f3746e6003d155b658417a8e951b5b4242226cb385b8be776dfa3918358d2ff120cf1f7dcece498a441ed15477fb2d78674be79622fd4ca4113202e8d0be80ea4bb95e79095d2e2f11014d0e8256864c9775cfd5a6950c54a941c01eeadc45ee20d69844892b18c28f9c9c30307a3c3cd0d8ef105d1e74f317b8a8ce79f7927fea9e978383207facaf62076d125d1e4e86b8aa4e52ead7333f3a30258db1771ce75eb9840793134d369d1c05aeb80807a76fbc9e8a0b757a533cb8529a2e0dbd709036cc48f12f89128b42fed498a04cdc519e84f64b7fd49cc46dda245c640280e8bbd2c74b000992c27bd3ed93f38cc76848d1afaf72b5b12ede9820b72b9af24151034e8f659db0157bfca9b34f5f20d072a4eeef786370f41edad452e022ae1890922777b5279bf5d25b735b22e06d92a9b1e44070b393fb53bdeb040ed2d40a15a770f624e3bcada21b3e4e0cde4faeedb4dafce81190882021c6b9bdcc7e3149aad496b424f546612a9b12ab96ab4df852ffec1a8f99d0d454e4a0b2f6a7974ffe76faf2af674f130cd67fe94f7ac97c037d2c62cccc6dd7fc314c8bce74895bafa59ec9a1a159395bce72b8f95bb6a859b223fbb754c92fbb24d255c3924a96f7aee557d1b997ca4a4dc919e676e0f3801577e1f95dc2c91459626e5e14f279d3f176ca579d682596ca30f0d408f6cad44051af8fa2245b193308144915d889e7623e8ab820bdb87b38e6be544ec92d1c3546e4053639f21203460bcdb4db3f642d372910fb04100f53160e89e81ababd9614a6e4981ed05a8e5d1ea7e7c98e58348f1d65f14df8733799ec290749f24209d43390f5c28da659fac74a76bce13dfc8cbbde2f9761e19d38742b9fef280ab78bc1accd7f87659b0747680ada08c9ab1f2443fa260e7994b16eed526f2df9115951e28d6b513465cd233bbfb9a3606411915b7af94cb51b8dc0b86ad1fe6bcd174336ab5afe7cb9e4655574bcde2474a4b044b85ea6adf4b1fbade523d9fdfdece59205f6f3574074b36334c5cde46e46f24efce7db572f7778eb83d9f88020bbb5ff169e3377edc18631bc03359cc821f5e37b825eb64bef50f3d56c97cec5ebb65a565df5516f2098ea8de6faee2de4201a91a6deef3a6d3dd0247175b9a05fb40d0c4e3bb13ca0aff0b19500ef3dcf2d3ed9eb9697e0393f882edfea7214fc7400089dce77e594353a0a1740a73a0f4b6cc35a213a0cd7d09b59626e1ba8a521d975a223eba6587592d7331f2b2c01afd8f2255f4e346a988eb0d2618b143850bb5bb072dde20fba0c38c90d99cef4754ffb820431e5de189e120fc9ae5a728aa36651170daa22dc4767808a52563a0f2589fc301896bae9109111d1c3684028ba827cf0e8804cf9c11fe5f3e5aa06a76d0d1ca69d282c6ce43d76386288a5ab277137eacb4ccc4c4bad922537925ab7c5189b571f397ad19a22bc34eb8190638f462683aaaef5c81b0162cca5303e87590c4d7099a96b17133464d745d5c16affde441efd7ec47eb61090fe148764d134cc5d1e3b74e4265bcdccd4f4b72332c4dcc810338eb7d124c0794b3123f838cb8eaf485773a19a523f2a7af10ab68d057433ab3d6305e62945945a986a0c740b1c45bda18fd434788718a198744c95c33e0f69882f60377abb6f37e4462322d49f7bec894e1305cfcc530f17029270807b4cc18803848370b6ad90f6ce179c7d5087c307073d5f4958fe924fd6738744aeb6554f1ba89a9356e48a4fd595405a4952b434265fe731d0d972db65d52007a999d51b8677517276dfd3b32cabd98cb7d2adf9aae51f2bb1d6a9c646ecfc5ad8ee3024dc46926be95a5793b66837c7ec83c9c2a98b7f20bde926a4232be461a8ba8dfe5449b55227272707287e3f68a4f8a2b6cdc176ac37ae2d94ed5eda40ecedad439927add3d4754dc51bc0e182ac10f575b19186489a1d8af9bce58823e5e2d6491fc9300c170c58cdb4c07488f7f5c642208ebc0547abe15af2d9ba0666b916ed950d40fcc8a798526529d6006d27dab26a8a8e4bc6bb2969c902f73a78d210fe3a91e947abe6b7f16cf69a087cb331d4a9e4d240a6d542c09c8a6ec45ead5bc37fd0b1d4700192639da8f15cf890090fb058044ad0148d8d9eef167eac815d9fa8874a7eaf44b1b9c624add1bae06bde945533ff4907ef18b78a4c7941f077d458de467075b802d9980bbc64ada9ffa4f74949e9537d807cbfc994b995d3a8d7446f58bf2d7579b92c5655096f26bf8b1e49fa2eef5104ba5ae4441582ca64890e58e016325bb46cba99d60936aae49b75d354cdfc2da6c4ef59e4f3b6986217163b78f4f2d54b9f30ce03d3e456d509f99715829992ccc9e67881541ca1a7a5de84c449873418977440f950c6c1e37b1b3e7ea40aafa2a60199489a6faca24827cfa1d5bf033dc0424a2ba7edc5a336cf42614fa696fe8e58602cf863c7aaa53f11f19f3fbb8ee1d79cc9f8712a0f49aef051f4ce969812386b9195d0780c291b940f15c34ed8de9ea9157e8cab5f71be3aad2bb03ab87af6d7f84dc7d7c889f182860df5ddfbacfef8a2d84cb8319ef9366177fbdbd61d15abb91eedfb5158c91add1266b9fe0a897458d600e112c758838b4b77659a4f18cbb64df5271bf07fa3c9ba6a3b4f3751e5b798b0af32bf8126b41a8abe55fa281706e3cad3a3a9a6f3332439533f2336b7f4afc426d501069ea4149b1cedb798292db1c9d99173547fa24e0e50a2a71ad9958ed1997bacf83b223fe6222143040e135407b1b29075c7d3141098cf7edcf34540822d54fb3e2676ce8c6d99c8029b5808cc37bc483d2db2d03114a23839672bdece58c765c7eeda255ff2a5d0507377b35d7fa4567d5d1535544ce2981c42c2732de2d9e81f6994e1c0601dbf73f591343536cb5f40c9d3c65649176754bca264057fff76991c4de4dc61717b32cf221a0e3a50a7b0563c227476c7afa3383d410c90c37612872bceaffaf6a48bdfd8890db273ea9950ef6c6e3095d08fa0d7f90195a1d41eb5bae25e4a171dea24d85ae312b3d01e7137217bee42d23e0be6a7316db4a5d2263d44a84152a068d8a5f34ab964faf1af6a64078873d45cc94b6b84781c6aad2caf5727417fb390de8472ce5769a4c321122e21d1b66039dfb62dc38cd5ffa8e948a0e41756e777bc3dbe250380d277be612bb9f0efd9f3ce2051529c504cfaa74d18c838901a3e3c94f76fa2c505626ddb51fb2d1dad888b548a58f4356c948e9c60e44d4c5321f728e63ba9445cb1452c6f7faf56a5ae0bf9762dc1da02b764f2797c0ff14a0e1f3dfc77766f9cb5cc6cc3788afa0c5d073c611be75e70ae1b6a84de80e3bb592c940d1d0e762aed1c00e2d27bd44dc1344b9c14a213428f3aa738f7ba0aa41ce6747b37d82a94b4de3e813d9432bdf9f68c486ef639e706a046a16fb0a14aaa6b665d85931899f8581be8b443b2cd6e9c26fbeb80148321fbe30a8f8c1dce8a7cfa89deb413b7ec3e3904b65bee09ec720784c66c47f9d3ac8fb71e3cd8cdf4f6f5da150a976d87caf64b5000739256eb3d39605d1a8e49ce3ac083820715ffccdcbbad5de02bdc45a82b77e4af0dd192eaceac633023d1618210fe2b9a6e62d18a7527da75937e35a32d92c3e432e16ee1ad991bdee7cf5ba61a0efaa7be4045faa7df5d86ddc44bd568139759e71a765b1f55bb0ec92d9b9e599cad62272dd871445abba52c913e096fa21ba6ed08db76f36d6051590cd7c1e8cd2b36b1e6cf126decd180a57e468094910701aa7746e38e568658a0ccc382527ffda785944cd300abb5989be18236cedfe7ef833b61878fd85301af716cb6a6be225b67119f196ac57b71d05916297637c2ff3613dae1daf34dbccef2ad7fbdcf1951424c7383831e1fb4dc587e0b0fb44c5fbfb1ff99d7abf63ef33ccf42a7913ebf33afecc5fed06f3df4393b87f76b9d3402f350f2565668d3c66de372e8829f0b56b4fe2cba386fba1ff8461df9efcce42ef6d57ef9ebba2ac9e975b12f57ce21d9fb10a4c6a09f727bd62b944788f68ae5332178c5826065ef5bfa1ae00f66dd3cf7e76dbdd13153c67bbbbc2fc4e4bfff0a949637cde44aaa862c481f40183c64d07e34e6d12851045f10bb6a52579df6464037438393c46a51684f9a255f8a76c30af59b1263121f537449b65437052ec35e9e77ac6a905fa54d42ea339bec142b425606c964b5ac6ab50f5cce06bfc5a0fd97a3ef8ffc81000a6acb6b93600d7c868ae95531e7b68c98c1f4d191a74267274c90e70a740b1ef4059edd0d19b76855a35e63da85c766122da6ad90922dc1590f5c9978d385e3f173c3b8d72466ef037a5827ec8fc7fd0b8f94ad370609b613571cee0ab29aaba1af9b20b177ae4b1750714213eca77b7d62937ab768bf4ce49bce75b41d632fdde7690b19624d8785f70c66b38c3f8670287b1c8729ee12e3e98d6e4e0fe5ac982eb44f669033446b9c43ed6a85c64f5eb2c2ac4fbb6e1e545b1723ed5c130fe4ee7c5d9577c19b63ae846e511b87be11be6d4eb815e2252b96a299cb0e457db873e3411809bfc338f4da540d2bb437e5a416d3abc76ca0f6c8425ce386c05db6dcba24f635726bc7afc2c45724cfbbf3732a9acd52b41c772ca4c652f70304d80f1a94c6b23864eba6e652426efd89283768a2d18eb11216986410462cd13ec9f517a56cb05f095ef7bbf75fb6516295f0ec923ed6689a30ea1856f496d3052fd7905a4aed8b0def0c6816f8f66a14b4adbca0c7614ed39d86a099c26e4d6374d7ba3336f4782b2f982712da777c8f8cbb7f0e6b4473a8d18c651a849966a37a1c36d0984d35c4c3d3249746ff67f4565ef0c68a249a300f580d863cc26c55e141792e186fe4bae5e69414923be03b75e46cd45ee65b9726851911595e76200f5e677625ce4f126b8175ca853468884e25903ee495b10fbbcfc92033ed32a3194d3be76555c3c14d357d208dd48669272a9a9e6cdbb8c2c4723b31e2db15a64b9f14d3abad273fd5a077d9647f35e77fd17585daeb0c2182742099968ab0dd8ccbf6141d7f059684e4f1763b6e1b1eaa1b1e92cddf4c4f3b8cf6e7a26dd4e5639ac878e87268e52d1a3b1de5f15562c7851a9c7d5af1b682a090fa2033749dad0e040a3aeb838bbb5502c6d1a86d1a199752de4f24b3758bf7e4c7f986330b33ad7d8305c98b801d070ea1df92898fbcbd6e2bb0f3534704ed085041ea02f456578732979d845821788c6e45a96e2f954e8452ac6578e8ebab4ecd8b2b390257a245d7ade4d1783cafbac57aa2186bacd4a15f24fc678cb0b3e3c37fffd3bfedca9321b46b62f2c1a89e822a33b5c1292dd73090e6c1458e52aefa55a3f6b9cde6a1f372ce82c6f5a7e9151e6145431284432217a923bd204c644e7307e4669a7b40db65aecf6720e187c637dfe42e0531863b860c10735922238dd869b349893282fd6e10b8d45150c898121b9ba612dc4c148740a68ea39df9e0f77fda2ad8b7a380b1049c11b9d8c7c6a3a5985ee1477769b3f68339eff0db2000c2d300bad755538a6bedf4e06269439f073d0e2c1d0f9334a82ff93b3688a57b1b94bc9eedda9c2a9b25a2a313d2d0d06f5a342f783be77f25b0d344d540fb9ca8956a85d903e86aa9af73af62daa0e3cab113ba28c774c658607479a9d8cad8fe30aa41a71fdef38a6896f044797a363e7b457d19a3d19d3b2cf5bbb54440ce687eed5ba5ccd75b0d632f513044e3e3f07024d65dff2b2034e7ad54e62d4fbfb29c2f788b72c660860f89b1c6dac2b4a187e19937622f8a2b254b5a8e3f57d65a06e624d14c39132d44bd7d3040dc7cf0ab612132cd23e031f6e5e043ca81cd7f1e1fb2c364387bb41831f7c38535b7e249d8c82403de0fb360910ccd01b73800a17052fdc5517cb1f1982d158d978a2d2056f6ba684b67b4e45939e2379c21c5ae130ee7ab7b4a6f9cc4b608b1960ff4e2903cee214784329a3e6a85776f93d9ca774f4a7973f794886ed57156ec8bfd789c714295099f09b223ac79aed9905b05e1f250a04688e5dbc5822af5e00111a5e9558cb2500211a25a6e21d3ee08be8cdfb2edbea48fe0688d63e41e7732b9079c67a205655611d40bd43dc69b39a6766b7971058a4b60af1633c63f55589b26f9d28d2bfd585bafd7fa323f37799e8a0e21e394aeaaf3784386315040557ba86f614b7ef20c302e66668d89a1e0d6ddb37d2c452d6ef615df6042625af5206409ffb56a543525fff46a36b8e29b036086078719a904e37c77c53798ad8f7602bfda016d83eadccb6783d7cbdb104ad10cf6e94ce29a4bc84dd1d934efdc49fe8e911adf69c369c48eb7ef90f0e7d83d525957e354c3473439a1ee05128fe1eb7b87d9294f92dd456597c52a53f4b95a681ed750fa96ea41cb4bf21d18abe65d36b5a42ee7da022bb86aec5df5de84940605c1d138aecf3c87ec65b17a5795ef811fab44faaa65b1f2d29c9ae8d54e30e06748f456c94ea9c16a1d043cd2c2d35933e541d75fc8b1971dd1dea0c2e7be62759018904b78dee8113cf4b3222e786dea8f761b15f937fdbb1b525081aca10e41fafcd9249cb8e21ba9887a400bd00a0fd8e130682f9a6307ea20f8aeb35fd6cd959e0ebee5ea8a07faef01082fc93c27481ece46943c97cb4c7dcba6af8d57600842ba28b596b94bde5baf3bb2632e9d9430c211077a92e91bba3557f1a254aaaeaa90eb2b295c6cc9a4b42aca12c7e0a900a4682a4efc3b96a661989ca8af8d934c1bb798d88dc99d5b6a5656b0ab14d5299dbf04076c98296e27b6db3985de50f770c3dc79df8e0aba7bc377f8cf6fce7925af79c7fb992f15ff18ba628c19b4a4942240a7317568a1bfaff99a3f13adf78c971cea977f02fb65777b0fe11fa57971ebc4fc5b0d195d0eb4e2449b0a62326f9b243d21525cadd9199818c60de7d4daebdee546f7d2ab0797f41da6d11f36917cd51dadd67291678ae06a801b18c260252b58d7168dc4dbd65069ef3557bc0807b1bd37cc7430ac6255cf6f4ca20db8110870044a43298c6f8f05f4324ffb1fe2706f97655a8b8aa2634ba1764333050f84e8b5e31e3bfd28aa52b275d3f02997b26815c74d8b7abaae0bf2281d5c2f68e06f1a435f0b371d8a12e48bb231bb3e633e78900d868e3335d92b73e0ff3d1e3bc03470fe00b0a07ae3bc0d3041c81070af0cab912ca508fe0599be3d633b242d4255792b1779234a261e72ca512a993af3d2e0ebc70aadf84696aa5d3642dae5fbe68236533340c9e9895b512244030290c92d8ad2bd6a512cb2b69acf3568de4288e0e1364783ed883d99aaf196ca041724a3767c9a40d82cfa8e06fea1bdc449bec9ae3bb12c3af364cc8bd6a43707896121d9ec2da1e6c5479ea5d578ac3d0ad011c4a0dda97dbf6e65f591d79b6100d9b0ace68bce78d891be8a0918388a06fc1787003c35da81d0dabf6757eaee16aab483974ec23a1444fd274f4d0a8b0dae10040e3b7554a0858538d6ed9804d74f618ad6fe755d6ff53b7d5b2d573507b499a586591822d2212fa60b3a94760d8f76da0dae2a316d4f193e463f01c4a46a866b0d3e76e196bd2ea47b9bb60e58e832874fa1811f07cd84800f7c12f0a83903b751edba67d49eab465cf7393106d95eb15f45307ae3f010b012fb2e5bd6cfd20a8d479c3a1eb3f3b6e22578a4aaf38382910d99685dde75f8d744740b5648f696774330fb91cbb9b9734086f3692d241fc5fb888c8876f58efc1e8271ddbfffde33d7a4c3b16e2cc87ba56d32c49fa5056d061dba7fcf1bd7ff64f62cfbdab2e55c734f6dd1652c98f42dae0d261fa59f592a69b1fbf1d5db9cad6ec896727ec430a3aa6fd252a768775732fe49496eb5d1a56013442f684407db1c5d23316caaea443302a6ebf87225daa2adea0d5bf07a65fc15b4813b36f8550d3e9826af3fa39697eb291f0c8a219b1cb093efd88ba25b8c965503bf248c0343f6e8809a9b666ca0baf8ee648ba9e0c010753c667f7e006203ee108594eb25fa23a08297cc474d7a44ef8d865f3378fb0fcd5c17fb293b4525d9752b9a3990ea629fdd4f18f396729efcfd629f4d387833646b564daee69f7375faa9953399b99bcbcb57e7673637a0859d8190023e5d144d2597789ba81a90d4cc7802b4bc5de3db1246864a36e1e0e8bb6e14374e3b5ed61af5953dd7c8bc0e74d638ff7582380603c8a805186dd78dad7e5769276da9c4e7b2d84c38ab9616d5620081132d2fa400074390a707e601a5ea580b4a0b9432f32c56ab5614da45f81efb9b58f1d95a295599a9152d0753109bf1a25bb7aa0fa14e5a7d5540f666c20cf8b496026f5c93425653788456c4a35e30e28a5ca8c663a69fe0261b76da89a58154d638ab865e9ec61260046574167a57f7858cba961b1c07b8c8790f83db0d7f49a0098008ee4ba1bed512986e921a589e971c34e06b782b537b71341233b8a9e1890ac8d9e2ba517a6ba5a84aa2535aac2b6b714dced6e4291183a5850721681fb748319f769a286f1afea9fed4620ee59e37333128872c7520258f4ff5a7f401ff725966b0e84e20b0fe627d491bc6f27cc89bd2b36d791b238053d7a0e3ce4cc1356ab4bf69cabe4de380b56eb3794ce5ff45dbe79fc1e83e5e78f4cc7b2b4e6254a7bbc596b3b75d73cbd5d0c0538b582166ec43f961c87e59cb8e5d71be622902af57e061ac1aa7438b2679f3754a80ebeebe7d2c2726361004074c36ee166fcf9618341ee5e73577f0d577c15656396006173b3d4aef2c0f11f416db0a4ff8db6ca9bd2d62f79bee2b9fcbffa91bacf724d9717b6586ffbfe23cda795f202b857bc2ae823f56026494b6fe6c035ba017730f7241a7ac8698d8d242ae610054d51ce9ea84735cf57007903e0808b5b738dfbf393bfd21811453570d4fc485acdaaae99ef2d579cbf960ced55fb550805f0866e9109b887c20c763a5b5775dc5db07d5bc11ade719a8ae581638ea621f3dd8797b7ca1ae2117178d99440f0d2f2e9a8b8be67fc41acca0bce9b8cb69820e579847c2dcaf88a16bcbca207604ac6209da43cf52a04fc2b5d237a70826ef3013471717cd7faee1914787a369877e681ac254b4eaaf5a90dce69e29f9c74e881a6e42eae755cba795e49054a5e8d8aae253b8736dc4ba65531d49a5666909a0616b2e9a73d3e7ac5563de687219607d884690ee39eafff9d3837fc7f20fa0826a698494061a500b64ce86cd1e53d226e126462d5fd5c5940fc6efeebdbfb8188fe76a638e2ff60f18e62945400aecf87cc1fd8c339807a7a25e386a5247649cc093a35f44a5b80b7eb42dde1b5f201f5eec1ff4fb067a9ba06b39b7bc5ef255b7081ea8b04bfdc4f9dd093b7cf830b41661117844bcd887b85b88b95d8a961f842f98c15164c59cd706cc55eda5d3b62d36031c969b7687d35643d769fdd4b67cf1f3d9918da49815b2e3b27357245ec88a4b75ca6fd8d1019d20344317c23b3aa3af89f36dbaa8ea92604a7b04868f3e85d97d25558c64b7e9a24980d28de01a4cbd0166c615cd732b8287e82ea903e586ac8dc2b86e98fbd9f4b54bd2e7b8b3a0d5540193c5c06badebcbb3ac71c0dda4d9894783b830a5093bf14814174e0e32fe313124fbc8fadb2701098eb96f95c7e4f689387e930c19957c5ac995907d29492e2bf9d6049ef7965247f1957e39ee2da8ddd5bf2a4186e566b37f6e938640c32ae2e492c03f89d64df9dd300529f572c8a10185934f1fbd410420e4d390843d3e0e09b0aac47483d5df054989ce2741531ff2df38ba43d027738b61e2731dbef45535bd626236238020ae9d71cf14080d765b34b72d52a0c114ae7e97f5cc7b4ddc10553fde63d957b25ea0d148be675ed019c5960b3b4fe34bdb6a214a735fe1af4b276efe40d67c7266e9c750ebfcd142ba3eb0e617d7c526ef61c0b62343d33fbb661f377f0c60a445f37860b979bfaf6e06c791e51c496e8b09abcf68481d6ea2749f37ee98bb1d342ccb6759d84d0ee1fad1ed3b0ba100090e62cffe4da03c32e335e3c1085a9961bc094adda8768d7f293a7ea4fe9f154c5551bb62ac211baa86a91b3efb834e6298358c67a589cbd1df9fa05f958346ceab659ca941b7f07528e9a67576c29eaaf3a711d70989b14b5aff5df68ad91ff95dd187951eeb1849e45a97e5220f503d6b862e8c2ca13ceda2c9eca216edc6b6e3b1e53f637d06b79a76dd8cd8939a170d5baf686e4bc4b4292403bdd1067d71d30cb8774642702bce717429b94932902d9285e60989f1d7bf092f1b263d6bca348b76956251c7e7ec81db003761c484b0eb956f3d74f1a41ec8979b20395bf6a2b7b29c2a4acb6057e8c497502c6331da0be79a4694c8e457819ea34dbbe4521673bc366b8cd7b366aa2e43907f173cd2a6c08b045fc26e0368b961930dd11f9d7f15c71c7aa2e14d37246655a0aab6a54664a5f34b6342ec0c563bb0e7861d5b1a8397e25fccaa4ffabc11336bd6d3b527bc16d7602cda6261dd015edf0c19fa1ae865d096909833c6f70003c4828db0492b6051943a8fcfecab9a83df1ee0542999544cc4476e17f8e8c1c1889d379ff60277bd84eca1e7e2cd337c98b30666b25be28e64193df023f3976421e804ad96ec3efeeb260285325b0f7453c29a362396b499d9d597b8add378dc09f9644e8dafbf40c59687e435c6bb43eb8336a3b6a23bb83d1e11ec4647af0fe14883c3b12e3ade8e18bc30825d135c5dd5d573b2ee585bb4e86793eaa1f7d2c776cd0fc06e936aac7755e6bcd3746cb7e6c3b2c925b0c2685235a98c60edbbff8322297196981c0cbbb1cc0d40a89db6fd2e21f5d278d3994b82cfa2f0dcf37dcb8babd7a26aba04c70625028b6af4356d4e55fd6ab531ec3131723d692f23a70503b263178db7c1078be8e8de5524807dc8540f47d1cb3455f929703cefebc7c4a6455d195aabe6be4b4239ecd8835cd5d594ab76bc77c42fc465c13a27be28e6d594356bc8e05fd4bcedf6f497a7a0d34bf0eaab1a8769aa743f49d503702527a88a0f8c3501b3a0e9e630e3bf45895d2fc197dd402e5692cd45d3146c82c9bf95aaa16f03b5102be346e690ba5f9cfef7e59bb3d327e7cf5fbdbc7c7e7ef6e654fded2d8397a26353ca8cd1589afcfdef8b7c25e67ddef2cd829e6fc5795b2c57a2ae50785633afac07e865256cc3af095697091f5b55d32b5eb2f5ca349e4b54f91d8681df00d324503e235a0ce898ffc6eb9561c62f592a60a96c205a0ab9d43bb6d49a14754dbff7d96cbd7a55c75b1b68f2907a27fc4c8f3247e390e42eb206f99324381d8fd9df783305f8d66bd15ea12b6b772d18f83d20426053eaf4d6d70b4ecd15e331a0be8ae623a0f8402a7ad6f26551f9e3d1b7cb028f5edb371ec4034a16fbee1979c82beeb87f9f92e2e424b7177ad46ad45189f5c620bdd259240151e0e0c96d3e4c17610737320ed5e1f13eb8d867af5b312926884a8e600405e60c37cff63648cd70a24ef34a09f5eee1fb835845f048a985e14354f1410349a37f26927cea25a4ec9a699bd6f583108700cb11b7e542121d16477c7d0c6bbdabde534b7d0a046beb8e0c622510f48dd8fefbf23190ec02f6640e4e64c9bb3791a8f1cc90aac749213995ca9174cacbadbc0c0f722799dfbdbe0633d4e7ed71d87838559e453e8489d93dad24dbf3a07128c8ad59f858d2ba7b18ffc83d35ecb6097bf4118041fb4589de2dbcae9655a361e40bb5f7f57e931ded6fdb04face1a13c06b507d734dd90aa93d538714cb6d155bf05df55e93ae8fba687afdc624a633d76e6727ecf212f1f007f62fbf7e1932ec79c87e0d866441f26c638e21b0c9037fd79ebd7c7a79f65f672fcfd9096decac294d53c7690a9c35a569f19b13c02581f44ab9a9a489a2ab0c331321523e4c00eb5ab6f4c82c3f4dc47e9b59fbe769ca44a598fb3d7baeceb2463c102b171686e6a675559711ba42ea8a41ee415b21fd123b14ee3276b6a9de4433e5fd1893b9c67bb6f36856d59d12b12ecd1ecd790fa2d28c2ace7b1f798f51c95c8a461d2bc030cf2a5e979e460ef07d3790ce17fb7fd1c7dd0cdab270b8adee0213eda4f848ddb74bc4387bcaa7a22d3ad182ef527c5c90d4a3453be71de4255e0d59c9e5b4ad565d64a246efd3ccc75e6e4d4fd3b505f9f95521f756934befa9e329010fd150695a348a3a06390fb4e339c44046dccc528f9ae3319b14135eb331581371548942a6bf25ef16a2c48d90a20199582a15386931df1d996df699f723a60e448de894babb4523c83e69f366bde42d869c627aea5cc92941cc46c1972d7add569d2b6630c8dc6435aac0722d61d54cf121663fbaae24d7f0e06a59ab66c1dbaa6347633640bf59f837e8fe466decb8ec92a9f4bfdc60f545536f8e824566274afa9c7cc77e8dea813ed0545d55d4d53f787b7908b1e296eee453e6e125bdb0bb2dc88e8be12f44b20819e751de9014100cd23ea96b258487d0d890aaf928ae386dd580639ab847889fcdb56df22ac72ced91daa5d44d5cb092abfc256f95570c00efabc6c959afbd4c1c4cc81c20e203f93a2a56ab7aa30d88453b5f2f79d3c9a47dcbe1d5655bf3cc391ad5c1a4d9d7ef616dd501fc2866f404c24f516dd659b74cacab99d6d7ca7f8df18712fab51e4c503975a7dfc6a8db397ecebb1d7853cf2b0d1b0b4b10352cfd86fba47551967fabca92376ae67a9971ce9ea33136b1ed61a09f2d801bc3439cd25911fe6520e8870c18f05c98ab71a046065f73c94f9176dfbb116ced589f302935ce4b23e641ca67990cdf81e2233428736ecf123666df2bf16d25f7083773ee901e8f59514b71a4857eaa5246e8e7a4f63f91c513ab631931bf36ecf3e7ccc9b4558e129fd077b493187c2ab3b962cdd8db0831772865419563a5617dbad83b2e576aa9fad760cb228682221576b7d3da7c0cae155e2fdb99a057c67d09858a8ea188fd66b5c82adaf9211c568fe0ff7f0fffff07fff0d145678d1ace172f48c49e7214ecef50a9f63a63846a5f5f554dd7c9ebb97fdeab5af870f8f933bbd8fff3ba815b8d1ec97717fb30cc432f04508ff2625f155525761eef237fbc8f6e375ea4a237a4bf04633a3063ba2d0911ff253da0e4bd2fa292bd562607f287dc99a0e8ab4e0f843dd6e70751fa6859ff98a40c965f63c78028afb4bf522e8542eaf13937ff47462f5347515a2f83ad02fff464cb49f2188e9ee09e373117f8b6646cf52506eae457953dc65f8fd856fef7cc79b326d9ace35fafe147c75b4d4b5b9df01cf2a7ee76d6c49ddeb9c3664d0402fa8150ec034398180929b935456d6e2eb350e1059ee4a32184ddf349f9f933db735fa38ba1361f04898900bb065ccf819be490cd45677cc8485f51546e78eae8848e862f6c4d7447c54321704af5f5bf4aba03c4739831a731ce1f7d445394872fa34abe10934fa75af89f90c74ebfbb5d553eef952450879315bc1d1fb6a57d57a0e2c10189fa73afff4fa03e982b6103d837b78f15bf8617cf2bce573a7162f5910f99142ec9311482d7ffeb62a37323e858d912f2ab355c6740f5234e35d20e5ac21db0a269ae111d9bad5b48d3bcd6c00a52284dc480b51a44d5bfac8ab65862c573fa64a87e31657049a5f17c6aed5618b2eb45355d8439216427566e3c00988421cc766638dcd9bab3d92a03cc560d6a34502d0c99587532c4055e7532f0a1c19fd8d98bd7e7ff73f9eafbff3c7b727eec6bf4df4896c0b4429e56a2e314479d121a85d47760233522a1617bb15b4bf573e0f08d690fa5e0b8ccc574ca579d3532c94a9d7bd48b62dd80ef3935c77a0201020050f02351efdc014a6280ae12536a1844d6eb21c481a4b4c576ddbcdd345376c2f6a031699f1eefdcd13f95bc2e367e25eaa864d64cb7141ff78d6897456d38c53f6fad36d9f0eb30ccb6577775e9a6073683e2ba899e00be204f8eb4df90fe5722487717f500422b0c7dc0448742c93eb83e6bc5f215a6ef83258a800d4aaef400400788a981afd336520c3a88a303be82663a9516e92187c31b8c221b5646a8d1ffc2926bb91f4417066c264c9d487315288176e00ecb25db1375dd968b08222c1d47e45b57f16b3bd4a436a02795884e354e98a608f1011d04cfa84a22ddc42d6c1b7fc7d9653c194267f8b8e7db117382265c88c799e1d2fc7143523f8c93c7f6db7593f2f7329b877f021f7a3829f96cc6a7ddbfdc59e686983cd19e796796cef9ac9f832d4aa03be6f2879aeece4ef5625f80a916bb395f546de9ba11b3644ecea261a652ff4166cf2f3cb1f2d807b42e2e9051457d8b29dda6ec31bb6e8b1575181df8db185b3a6047e66f5f7f344ae2bab3f3e900572fb5803aaa2e7224ec0b2056dfe1a6eb13e9ef6b4cc105e3842c7b2d7fdbb5eb69b76e8bdadf99fa733b92c9027a7bea263f7f76e575422d9f6c373c99d41e7193fffc99a515092a058d0ced89b632e06e7bfdf1f63b44da4be744daa7685836bff159b1e31191e201a553fc5f470c527b540dddf42db4f1382474db778a2642b89c8f4f3a72bdd5a76cefe10f1b9e7fea0cd085136583c4814cbaa35cb187ec37d0461ddb5edcc047dd8d2d92f3bd88b9cfa8d4b3aae5cf9d4d2aa2141541664409f7f63daf653b316318bb65abb6d1d8164164482ef5709f0691531d9c452594a73ef8cda490fc59d3e71d12026ea46009882be3b366db4b280b777e4f443b1dac7bac1832de1b7fee3be74418e37055a776ef78fa0069a16e7f7f13e26a70b11fb6a18ed6b89904f9139924bea27bd7cace03f09b5a087195aa18982c3bb1f4ac8abf4f5915e7bc3bedc492ce479dcbdecffe81399d6c6f157e0f6c959ec3e60f7cc34e20090898e2ac7b17b18b8241bb13cb77b4d2fb80bde20290fe6c3ad9e96219d7d667e85bde0dde4d27ef335a9468abb9d28054753587f7dea08d26a70aededf00e7173cf32c03a687085c154a6ed4b837573e078eb6611466a1ed4012fa64d2410bd2a897def7d37c9c1e8d2641bdb9eb2065bdb36ca484af5ca1897605aa0ba18ec283ffb28ea78e067ef7f185a8cd6375afb209eefa64aae88abfc843c66262ad2cf43968eea26d5d2058649d7775327fae68abf49618785f5e2421493b38738f942c7c1b5108a27522a671ec15249a2d3be0dc15af7f935923d1f7208ecdf8910352f1a7cd24896905d5bc1a52de4dd92af5a3e2d3a5e0e2ef69fda7f68556b265a76d76ff02ec237dd052de42e3bf98eddbdb8b8d8876837f597bb437657d1c57db2f2427f55ffd5e351bfa872f017b4c0c367783fe445195e66618f14cc5cd3bd6ff2ba42fdc01b6e2a7ea8901c96ee28f9850c783f2aa1fec000b28633c0198d555fd532902cd72912b0a7c7bc41ada74bb7f2b97ef5bb474fc7ae8d1bf4aeef8fc956f5c39a4670ea6135f3ac16b0343cad0d99491fc1ee02ed146b691662aa2db38a774326cac6da47d29717c7b9b2a944d28a5a5a2ac0462c82cdc71ee322b2a34c321a083bc849f63e014147d67334ecede53ea6c7d2238b771d4daf38dfdbcb7f4e8fa847b8ef3aa2def3616f6f879321cf0b90ec2b4c29be438b490ef08ee79bae7e70b6bb95a71f324e77e9937edb019553107277e220f4e4e7d3372f9fbffceb117bca27ebb94da0229a7a33824cf3186dfcf2d53900cb7fe42d3e6b624e7b7c80fd901ec3075649c631206e144a83edc83540bef4a7fe6d63b59a805ac9e0c2b8526f24097a9a7073abb25e70f4c0db5de3bf481a8c2bf9ba2eaa061d7a07a48b2153ba82f9a76786bee21b2dd02117b77fb1c3677c77b9cbb8263cd69e0916ed811de12f5e6397b5102b7c6ab2b78e552b56899b87712a20633e21240397c5f8f2b10708caa34a229272dc480a8626d9d5bbf8d7f7f923e976cbe62f5ddce10800c3686601f3893cbde875713e95e1da1cb32f74f5f9913b850b52cdd9355a5628ea31af55f31971bbf18c57238e9d6698cd8e68fc52d989f1309ff3eed575f3daced494f0dc4c12507bfcfa296d2d412a9da5ccd1aa984e9f1217ea14e9caa40bf69079550f8ed917cf753e623a6f7491ccdcc5b7de6f21f02067344c15485e3569e1a1fee82d36f009193a32b9ade9cb28fea9e34de94ef4d0fda742506fd3f790c577e26ff1ca16f94e7ea7bd39a30f7f3e617f50cc7d371cf95dc7e58f1efca1c7eb2c7c6b33022f7a6dcb7621dd13db4d1c56f62aa23abd288cabd541a62f9b63c085c38946496c89b7bb65b11a2d0142217111b3ebafd78b9db042a21396eb833c87c19a7aa25b5f0e9e3a31c320a184ff2bbcaa0125b28d391f7513b060260e0f28cfaa4f5cb2df1dfedb1f1e9a1a05a1933ed80c5b9acbbe898df34733e2cd4275d062d3cbe28a33091a0a2e9697edd478856937453d4c607c19f0b6de09de560f170c07fa73d52d5edb0a5b77533881c858870d246cc1375a8b94a300da83c245fefcd919544ace57cead8a3d662d9fb992474c7d0f461ee404ff4d481458e32e0f87ecb218327ef968c82e27dfd429d6dbb19411d4963d83d901c69f950610afaa3327d3c4ba03fc7e60bc0ee57ab5126dc7cb117b0de07b9899b35d4fc1a4cb3fadea6a5a75f6dc5b162bb5e955671f3af19f6f3fa8e9355cd57fcb39aba45c73f6bb3ffee161cac7367b74181a5ef18dc4ed4d74c91ff846d2aa91f5200b6a6dcf2ed52e287f979798f97aa07e3918ea0ff009ff3a6af8a76e7070ccf6cca751291a7e9c2dd9e3e4a47bb6352e0f471fa37748fa07f44835341d446f16b9d7cf49db47cedb0da0bb0ac5b335c031511d4ab46cddc8159f56b38a972eec0fd5297472ae669b1ff846f57f90d6adcc9fed90cee6f54d4d1ae0d28070bf1aac43f89d7d49b8e8ccaa063229a66119fbd0cb15f1ec22ddb9132ca0fa657059b8d543f97370c02e0b7c03c4df779cb0375434d0aa896a94d2cb43841b4acc2f63fd377f49e20946d3eedf2a8471bcc924a9e76f9147b92df2c831fea3608b3cf2b748a264668b04dbe351eff6b8b15a4fa5b8e2e864abb717cd612b7bfef5f7869b3750baf85d9d7e187c85255ba996b564974ad1937c2a9a32abe98583aba4c9af14c740ee32bcd78544085976d71886eeaa61504d05a409dee5e16861b568e6bc75070c9b6ca27378c47e924a5021b082baff39919531ea9b3fc92d895ce2f444776aa8fdaf05abfb3137f5c7f4ba7fc537ef73058f02bc893e5a3eb62f695683e82b7e14e91b5fcbc12400ccd1a8f74198fed1ac80b0f6688af78f97de9344c7bde8b469918e19ae21027e7b17eff8c67cc5377eac32180eb3548ada1c8f1d34c45003345a0cc362b5aa2b5e0e4d66bd0f41a8f387543759e2f5dfc46122e1f076858165f4b47d644edb47fe69fb2871da664fdaec296b4fd847f4847de49db01327fcdd093b2127eca31db053c293f5913b591f254fd6f8204dce2e85bd1e5b22e26c85da6c6ac45c7c8b6944c9cf45502b7065b1b593103ba906d48fc125c3e627f0e68550d4aa385c4763230ec2e4979ca4caba7387f9bf500446dab806dff7c2994ed8baa9febee641a307a365b11aa4e692f05297c66134ba4e9a24a937a1bd57e7e694f7aa7f5bba2f8c1181b7129b4e91d7e5ab3fc15c7ca3592b9603420d5399d0988eba9fc23a687bce1b0e42946413b39478568beb274ab6d535407e20ba302104c4da50b0fd673fbefaf9f2c9e9cb27673ffe78f654bff80279936d1113bdd5dfd0377a107c0ff0152b991e5b98f3c0c44a6ac87c9b5d32593bc10bb35a5c0f2c8d42ac8bd000a88ece436f2de18cdcdb4b9ec7e028a506624d7787ce7f1e80567dc0a942ba232f7c19d15ef376a4a9c05e35171ad63b1eb3e7cb55cd557f88e83229b4256fd1752b79341ecfab6eb19e8ca66239ee7e194fc578528bc97859c88eb763c0701efd22035af7fa704dbb4f29b470f0066ce7600a34448d0a989477f7ef13a68d4acd79e0fa8f80ac0f54f5aad40a0736a53f289df5627fe8886782b9a7dd27f03794f12340cb15af26324f68f4ded7ad585680819fc650d0e6735da6e1d74cd7208f062d97a2fe08b90fd040933490c88eaf12990071417090802caafe1a9520fea3cfd6f5acaa6b5eaa7e33579b1d27e7132aee956dbbb8b7f0c8779335dc009687d6371541eedf870585fbe6012a1b73de80527583dbc30e49b0ac6c855bdeae19af18242cfed40d5adeeda2fe50a4f75fe0254189baffff2c132873749dd4ecfe17af93ad93d79b15f5dcfdabe5dda85bf03884ab1f21ad68582137cd54034ee72f90a6fd811a991529591b4126f55996467a42a0f667ef3c4e0d51720dca27409dcc9f888bf5df463bd63770c55e33480322ed86644bedb0c0544e127005b51436e964b7e0e60ddebb91f8cd6be93f9a821672c37d84950080a63714baefdee61326bb68d895399d824a49c2c3c319deb526b5985e81efb75e8d816851081c30d9ad67b3746e45ad5fa342a36f8d834c8235d22b2f94de44939a99231651014b3164557757ea39d5bcdccbf50e63e4651ff3c93ee6f3ebeb9d27e0795d844e05694afb2d9847c3cdc460562ab5d0ce83a4d50e68821b9d8935c604a8753154496f1a541906904d3fadfeefb04db6c863db8b9e17a2df4f9d17101c07904c9e3252bff923090da7a71a7831f83a7ec0e19ae0beaaafa574b869fb4c657ed9c141c2c3c106cd80df1fbd9cbe72a153713217e70ae55d2ba3277c8475f9fc99d12fe88c94fe063171fa5b188f655cafd44dba5c564d253bcc701046e0f8d12ce1c0cc9b79aa0f9fd08e0601ee4e263af1a6512a29c6bcd87fee2d096c3430bc7ba8bf05d3ef66536b4918c2dba97e63b56ffa8dbe54d4a1cd7a1b39032eb80946d55792e162ffccf8aa90476278e4d5b3b23e59c4bfa42d3649170f585298eba8e4e8ff1038827efd0cd8c5fe29d94b902a8eb790c9cfd86e3924f1a8e4c28f3a0a47661d0b7df64b3818fa058ecc26dd399e29ee39d6d193b919cc2c77161664532d32f349ad81edc8d9a67b3b3ca67cd9d79edd60e8d29565f64c7861b27a3c6bdd6b4e588d1c1d173b749aa2016efa9bf64c4c8ff931d005bf242f753af03761f8548bac839b4f4e000f15507fec2f5bb61b0d0c216e459bad3edb09c9aec16dad6f4e5e5aa7b2dbee41759d570e152c395a14f6097b13bf4e66db2321a6c6fc1b5230a5323882e371a89ac83b2f86a5894e18a2adf9ebb8cd96f85d6049fc56d2dd8dc39a1de18073b6477c82a54babf85fa332aa1a70c331874355571db8e71696ac89c0ce888dfb4904686f64b15efa60d581a290c0e6fbe7900ebc96ed66819b5bff537c8e1a64966919405cbdfef5a4c0ed691ae9ac7a6b247556ed9dd0abfea94522b4428dc5070c8c1ddde0b11a74184c70b62c561237c1b25829e963551eb339b52742140cd22b13f338bb5b855eded93fb97a14e5f899d0083298b76dc824e7ec77fff6f030e0c91e59fef933ed71cf93d1c1c74a3a391b5674f9b572df53a2342d28c2fd70cb9799af93062416ed9f2b4aa3d96fa1d1bf82386517fb5f2d34d352302736aff8462a0910cc34c1e7aa503adbac98fc62f6e59ca3335de696134ab27c9be431574c7e19c1305328c461ab6f79df486fdb2acad65e0ac0fbb2bbca5c0e193cfd91e015f8f77194bde8f6dc420772b17f17677337be8e8b86de52b53fdc500b7325eb3a27d2d3a98cb46be357f289e5b58056e0eff42be5a62bbe799fa6d4cdb868e71e15e3c2afbbf57a232ed3c4fb567c262193e46fc54466b0bf091bf1a66bab7f161fbd03ff30c34dff4476b21d5ba6dab1f31b7195a1e56f23be600aa1007b073f80e35d6646df8405edcc6eca835bb84f2279b5e3e04e1a914d4ab0b7c33a6593da5b8841699cbc6fe6607e79c8aac6b6907cc4a073bb3c1cdac2efe0dfef7b74e3ac3f6326b37e42b1dece80f92d0df68772c94e881611118f7faa645735730fd7a02897e61a60857778cd882b26ee17aa21c8e034208c919f736c53368d146519a893aec12194d0bec96736ca2dd94bffe3404644c1d1807488e6d0df60869d55834559fa84ed6f292b6788f27cc5375a0a602af9c453054637ac8a56f2e78d9ed1e1c35c54a62afd9dce6940ddac41581970135528199b93ddb4da6b5735ad2891c8646b88646485eee4f038a0229c3fec84c5511a39c7da349b7d2b0bcd5dc5265f2f5c997303f6418197e223b7c2e856e73cb950e8e66ec0843dfb436397dda0b19ebd71f3c6fe176e0f902a98bb1cfbf9e772aa5efddf8c591785fc3a4e05e781403704cabe9aa156a8489f3eefe2c70f553b656c5727871ae9d76f02a2efddb0c17eddf4160d6ed3490ddf9a08a43f1359fb4fe54135afdf8c01e7446f0b1870cf63ce9471297e0dbd95e9e68ac22d7e2d5b45aad8d771c196f1fd362b3effd6e7a387808bc107fea3ee93c9904d27afda6755cb872c844f4e1a214df19d1eaa75a7be761a3f58f70f63dbeb75d449bef1d4f52c5bdde082f61166db53b6a17abead5d46947fe2fefa31d247ef9d47abe353f4b5e295850ab17d96bce3d3eec9665a7319a452e49f56a2ed5e142b792a514e84255a3e5db7929f7de42dfa0bea648d17364b1b710f9b2ef8001c60e89d270d36e3f029dce03cae5d16abec5d86be0625d6ac13fff9f66fbc5ef17620c5ba9dba410cd9e5a5767579cb79134a5b877a1a4c3abafeeb869322193f1d27f62b7ed132c8a677d8dec478cc9e562d9f76f586a672554deb262b09bfd03ef517f3c299cc5248f3c1263ae9169c3d2d3a07bdd2495ecf54eb53d174853a764c7e2b2714136320f144aab91d89163bdcf5103d5a7338850eb22b4fa7ed2066ae3903307e9812c004e88c647ab132a34b0e0c9441fdc1f6863bd5b13c85f5f57e3e09904f11038494b87387b213b0c39d3bfe24411d33434b9e937e7145b170c05bec89ba38fbfc99f9206ee96eb5bf32267e0271e18d60c8cc7e7df7de098ec814d489d3b26427ba7060b53436bd0463f80229e288d833565e1eba9b3df41a2a9f8c9ae92a0677ac3a2ccc2af667561fb3eafefdc49bbcbc3c7c57bd3775de55ef53ea3f14dbcd7a4c96c4013dbc36e181af66b680e2b1b7bc23a183f18dd4c262c70705f15c4a075ca9313fdab6d006a2fd20b3deea8f5ee79968cf8ae922b1d6610543d84760bcda990312fedaf14f64411eddd44068a8f2fb5bb3ff5791e3f7a3d55a2e7e3b7afc7e8b29337593b811b7be2856bf29b7fe61176e55a3be3db786b7bc708dfee0949edf6c9dfe705bbefde336fafcfae53723cc1f8d097577817e33aafc710bf78ec7ec5951d713500f046805b2ead618100c41344e172b1a165ec0c135ca83a3a13a0106f1dc9cb6090c23bd6112748e09dc7299202bb6001fb613f74b2a7a3ea39487ea3819cd78cc1465af8bb6c4dc585d856e3e0935dac221fa98fcded9ea20137f0d2e40e68b0f356074ff4c23feedcad64ceb6e892662edce1a6e42967cccf2d710a31686758e76d42201ce97aee3f18dee645e551d8e0de2306481dd6f60097724a581f34198020783dedf39edc8aa5d97a0771dabfffe39c21a553fdfbf1fa69a69e7f2dd25285db6bcfa77ac6061ae908eb7dfb7bcb87a2daaa68b3204d014d8aa61f57f466d7cc00edff7f269dc38545f89d520bc35b4d5471436d64dfb592b96a7ed5c0efcd87be067573eadfa7fbd890cd709b2123c4e99caaa46562504a9a92b152f2d8893f6b40581683c1d47ec8980f22d5b69c82c7db38c6bd90c6d0662b1cec7d438328c2a79de1653b38dd4dff90b51f2d1cb572fcf021a19c8f45acc0717fbef9662f209b2b4f1f7fab184346be350efc24421eb3442a02707951e50c4078fc900bf7f7376fa033b22bffcf8eaaf09119be40a373193b783f06738ed4272f6304a25618c5604c01d96b46ae64fed6c8ea3860eb30de92003d82d0f03c704a8fa68c7aa883af1ee30ccee14242e7fba6e1183ad6b8b461606bd0652c6eaccd13a5bf7bae9aa1ad88e37a5b9fc935a2697f8b9ff3342e64f386487959b66ba684523d6b2deb04634bc5bf05a6d33acac9bd0e9c87503247d36e812382009a9cc5da672a9886fea9b54e54563d0e3a0e6752135b510384ecde02ef67297419fbce36d32133999d1c0e430ea16ea4a3f0f0dd0f86b90c9d5fe4a9e256e0ad068debb90dc2e759d1a43bc9bbe02abea7ac19bc1aae565352d3a0e9c7468b2a66df7083a04945d55876013c03f7d0ceaa4b14a75edc268bd11c4debcf971aa21fcfa2565b58e2a6532f28235055300634c59ea5083748eba949e9d7d970e82f56853ecc44b30bc35abb6c9b86f5efd4996cdf4ada0f4d32c869fe1e806382354543028fb62ffe7bf9dbdbc3c7ffee2ecd54fe739844493a9d8a420cd06fdd3421a5329d960f85c42ff687c360bac44bff991db436f2d12dbc125038e1203ffbce0374b0a8cf0523a95a66b4c9d740fb0e8c5fe3099f5d72c8c526630473b05eb49c6c568464d029eb623dd6062a1814d29d725576a5af3a2359ce8178f5af43288e69cb3f4460af7aa9978624766b67c2243f60d220520c3b449b89a62553fe2070cd9fa4a735717bf0b6f9677750cfe5d02a53515cb09dc4f02042d0cd33f8e6fafb701670ad825925bb6f6e5a5d20ae7cdc0fee557b30a43f62bd3b33932300e5f0e42ad428387f4caa11e89a2e170b4f820c06d018ba4efc5d2a19704e48beecc019ce269b93448fbd12b22fe4e1d26c3c816f358f90387a8b0441328e23f163549a1d5cc31c15df4d188fde447b9594e444d91ecc663a62ecccbea1fa0211eb16bce4ad1dced00f51c141308edd54f9a0ea5b72935c6c5a2f8a82e10ea0a50f38ed71b365dcb4e2c59e1bd9ec25df0e9a62996d554dbfb867a00aa2d7955ad18af00cfdd76da14b5f690d531fbf86da2d44f0a045f75d205e138c8540988289041140abf6ec5a7cd795bacbca7d745218f08cb19d4d2c60f2b323b1f05f7c90983155544b6bf5cec5b6c79a117c07e53859f56e59b75f363f18fcd739ba9a1956f61497271805166bdd02fc9a678a085c663f6e2e7b32393d9e243d57c608a3a00663b71baea63f67cc61ad10dd984d7e29a4d45c9d9aae81656579e013a1e1bb3a568395bf2a568374afc56d38a375dd0e7f9aba7af8e30328fad783b13ed526d24d088e55e5018b436df35d8864f017f1f1c502284ebe0ef1b58ac1c0d8d5b566343ab8202d06fd58430245f86c482f72fcc222861543bb147f65656c1dd9177d78e89e6679ea3efc6ead697b7dc23c0a8ab898fbf496dc194ee09d5a56cb7a8249b99ec26fff127c5cdd3622d3966adc55b25a4f781bbd7a250d22bd396ed4edfd6ae4114b6bc6babf99cb7ac30ce262d1bc0e554561031891ad630d3aa125a5acb42f426d5a85c4f94a09a00fef26c0d09deaef846e74f976c203967452d05e0af29f9aa2e3849dd29cfe12c05681423a8268b86afee7037d41e343a17831bb60c6a36a233775dcc5bc74a01774f06f048ea3010e4dcb9cdf6debaaf933bc3ed6a99dfd571d8092340f8bb0a9e18c541f22ed94f72f45e56cca1b34da953d68ce10662e9eb46be9330512ba25d81f38b929e96b86e7ee09bc4499c8d43d9320ec5934a208d5abe126d6713d92707f586cf6a3eed467a1451a36e9cab967fe44d073969a4d2d2b78e582bf65af5497826127d7ed68a7ff0265458f361f1a177175c07ad921578972ab529b02bac9446e4ae059f36506818e94b6e3ceabbb9fd9bdaf0df505b763ffafaf2a29016f646b47250510c9c58f9f53e3b9419d1063938d5152b5f96807f2774f096cf95506bc9b8fc61e570cbbce19cf48df5f36736e8f97cc2de11f3a8377270078880898c2b67e365e64bec95aafc4447a65a347eef51a356f8969f80b80fe21836af211d7050959ffc80836404bfa988198243fae2a1177127fff813182af5ebc45b7502f51926c7634616119e3b96a2ac6668610507e0219b8ad586559d3abf0ab08b4e45335db72d6f3a2cadeeb56057057489c3fff8631419102cdee5a55cb5bc28077d6bfcf9b35ae483ad6e4909bef5bc93623d088917547d57bd1f68aac63a964bbca5eb7efeac5b19a93be39062c719deb7a94d2d303dbe77c213916ec65a54936a9dee2ca9c2c489b353c820d8c08e2666cb3667ff2f7befdad5c6913c0e7f95369b63a458488063278110af2f64c3c6d83ec649f6f7471cd1d2b4a431a319657a04686dbefb73baaaefdd3312d8c926fbac5f1898e9aee94b7575dd2b4f5a804b8dbae629e52fa51f2f971ebd719264de75713cba5b4892eadbae479254736b4075c428d3a338681aa2a0440daf5d4aa4617e1e3264c07d0a0d32506e4380f2a24ac7cbd80edf95faacbfe8aed557f789a801c3957796cdcf2910a31f9987610dc443378d110b7db8eace91766b3f7efaafc1c99b9747cf0f072747ffef901c909dededed6dc8867ac21861dd493796855f7011ef39fce841653ddefbe6d1b74a6703d43ad0d67c8a28be42828e04353b30fa1bb8a0f5493b1d4042be053fdb97d02b12b62ad573d6076a6c36d62760550cf7293e8289c69d95a827a4f1ef6a8d22fad0bfa2afa47c70f771e8b84704d43c221fda9472abecd92dc7125185c4ee92df433a8ce14a386c174db88b26abc2da6f8d38fedaf218c6ac0ea7af411ca950c624674d78632f7734c87a0d1fc75e8fe48b192bd391d411de7aae2e56ae9e75b3d07a6761d04a9020a3d23eb30ce8c700c8527610a2c13b4495ef559b5f5cb91a3607978def80b45adae307f0a1cdd275f001f01e2cf94ccec8f5e642015f08a5de87bc802c1cbc990c4e432f0f4d921fd3246139647087440f46bbd9c13b01f23db8777a2814dbbdccb5647f6856230c032b63af3dcaa9d683b8978f6240c801a159565c81470f8a4e1cf990b01a9c18057244bfa6d514f77dbb23d802e7835e271fbabae4ebb3c6d892bdbcab1bb7891c90de975f92bf8f32ca39f9b247e2aca27e78973df77c1ca629ef2a04839ffbc16b695772dc15f54bb599f15a23d024a3bcfa292faef2972af8643b6c2433b60a4c02972863ea5f7582da21303567c7429ab3ab5f3aa4c8925fac781ad5d27a8b271d3c034ebbdd33415e6c43a8faa571ed8d5fbfcaf5fc0ba6e324cdf10dca19699dacd936d1b5bbc4eec520c49038d6ddbbcc858793f1eb07ad988d38e097f6c90e2acef943e7101de580ac9f27ff84899aace2f624436992d83682503526461ac9957dfbf148538a339a750274d52e782dbc0b26781b5c35357022cc8b1a552b6a8342adc79e453aa2862031e73dc133018dee6f441bc9741fdbd197344958b267d32f2511d6377f5e2cf2caed837819ed82dafb648f9c9e35bd9740b7fd2637ab59a940b381e8a456f853f0c915b89a1c4934715ecb3a10aedd270c92d70f3267572f63cc80cd7aab265ef219b024eb77df45280e7ab0d94e76e8320dfccc1979bda8483126a5e00164911e339cc01224d5a57a0e0d2ba4266046278ea903a0863aee0702810be77b0f4adcf29cb3aba38acd94f313b24506c8960724505cba2a1654a6d4768fc78f12a8bb85c3c03052cbf5b6d723af0a953430cd32c22e59b9bc9ab29275c38242b0d03e93e70c01183ef5b586e318f3768c42d793ed78dbbe15c390db1f08f4a2ae3b134596a8af272cab682ca2503581331163ced63d0c67e4d8d2ff13762d6e3cf08a725c92d081635132486fec241bc15a2257944b9d6298553bca3c3e38c0d97d0a5d71b7cd5944990f124dc740bb2d1409058f01d8e923952dc1b5e7680ce282bd52fc69c99e0a4182252d4d5a43aa91dd825cc0901b12bd137557068cb7c95f03afbf273529e154efc8003c103172aa7a1fd36ada9dd16b2169c9f93d9009398339c59dd403d0d636e9e14165cf845dc787e9f47098d18f1f89ff324834117e335cd0e6f6f622e0ef69de72b0cd9d453b5c1b43a61bb7dca2e687c76fdefddfe0e9dbb74fff2f80e61b9905c2c59452709705d63369a244c6e48fe2f8f08caee6b9ec656de011d542ade0d0c81aa639c905d5ad3709d0415a12ed71073dac8d94cd61e0f5f7957b8fc3aff631da264f4c13337d3ff18425240f1ca1ba75d921760dc49b1045d774faae41331ceb0b41e52353d8b29730582c1869704fb6241f6f83c6127440a7b918b4beb3f4c5946f2a2bb71bd67ae3536b7418b7580218f0515e15282937df2ac1ead928720f360c59566719e045e4b64e7917ed7730fd1369f6c3ef2b189172b81145821cbbd3f4ae97adb7209f74e5d25a8aa8d6e63bdfce566f10690da87bcbb6e58865acd680768ccfc26938d4336bac2b58c85a774fef9ae7f696e1e5f9c0fe6448965c2d9df5578c4649f8db2a1976b4cda8c847b46a1984a919a037b2a68c04f1c5b93d4259d8fd7c9a66c9cf70d8631895b3ab5f644a850c6b8b44d009c19dcc051b78cfd286debf4f527e325f1e62f06b24ff35f62407ae3b04dc9fa114a86e4ed9491c68f5617fc99e7c968b1469e05d2f52b5747b6611a36392ebbaa77f0b2e51ffc19e9ba68b28c76470b5e7105ab444efd794932227653a99a2630d81f86bf0896d893ff3a22274585cb27647b4853e5714fd9716934c90ed12bdf393b29893b4ea90e1a2226985aecade08d00d9ae64b522ef22a9d31525cb272ca28e4044bd825cb8af94c3a3e3108a6281615d1b71b6795b81633c639e1f325447c731d3aed132c8d74f7ef93752f4b7f25f97cf916543268e58887144966a5234d527b963e07b4dc7e6491afee4106cf477f338790edf49c4790358cb9577dfe8538cced817e1269c18b33465580f9ea2856f3ff4714e5b3b0e67bea97268e1c977835832fff6ad2d2da8a5df85d36be0b9dfa6f38b982d215f9b828677bdacf481237567667c5bfd32ca3dda29cf458bef5f3492f2946bcf72b1bf6fe492fe909448bf5deb2312b593e62bd7f400e85810c52ebc1c9e9495bc55f985e48a6a5916ca05557591fb517967170b05db1b4bcbcb7ae35492c830e1d8f170c256e5400aefade7fd04064fc11acd1c7a40c9accd64d08eb4e12229ff7ea8d15b614233d1eb763704a36cfe8c859ac068963ed39455c0aac1831258386829f19984af221fe7d499e17f9252b2bc9dba05caa127651d2e25370496893f7f4926224a751b8762d383f80e371c2d89c8cb22287843604b3c014ff3c310d7bea57f178dd65f66b37756c20af5f3580e9f5c8cf1cb37a88965d74544ac7cbba6f41d2adf8b259b355dfe3185495148466951f2beb28a62d8f7788ea80bcd8593aec32feb89b742bcbfdf44bc2d37cc44417ceac4fd99fc859590b5ffc0a61c0c0cc62301cb7f7ea990cc88b3684fe4be55d2ebda06476229359488daa6381150cf318828269a5386df189a40030232ad864366779c2f2d112b3e220b15506bf089a20beef35caf23106c9e8a73c8f123709d6ee6d926011db723448c916d9ad4f8845625a9ce6636ea51b7206130b3288e71db2b0d99b36a9cf31b482c244d4e7a43eebd03ac03af5aa86988d7a3d38cd44cfebdf8c4f8dbaa13b53eadb0e79bee0d306ca0646d07550fc5679dec4bf54e2f767c5edd88a442eaeed0e7e3eaa390cdac756ad98dfeef2d6d6129b1d725d86b6c84e876cb73b64a77dba1df54e9ea6e3ea963c433db445be0ade7fc1de6f7f86bd2ed9252b396bbefe6523c101c8949464b6a82053589a13e0d1c8908d8b92c94f433035e88af822f3553857d3743485406c4ed28a0c8b6a4a28d93429ea303b0c259bf011f1a0eb81e00564f5609790c1635c1633bc25e5e044f7f70b5e61b4772a1e9084959769150dcdbebb194465ecbba2656e4ceee7852b9174e5fab5dae7a8e81257392afe0ccfa157128b120730240367c3aa0a28925d32aed56ab8f462fe325d05e691874c1950582287c426f325a41e890c1486d05af971fcbac28bfb6a366a0e41829a402d02fced419c37b55018daa9cf4a5d3f3ceb98a315bdab8ad239fc90dcb5643ff869290197caeab362f6a4609cd0094d735e11c1b04d8a2221f3928eaa74c47897bc64d526d63897daa11009eefde1382a96e1b320a802f4c763277e597e5aeceaef8d97e223b7404ad483edadf02d5e7d1798f043acec689b010dcd37e5c0228ec62a20f17bb2b5130b6db16e593f16d15b89209fcf1af5efebd2d0a8b2afb75b0e9977a726c39f7278092ec39af42b504e73a51fa5373f7f1fac6d4063e4d91a494c62075539333ead2a369b57487469222e347528c5f45ae0dea84c7d820c8000997252a017e4b058e40997ed82a5c03e5df226634222c17c47f2d5382d79d555de9400477c485032432b864ca7db1d2ec97131fc57e349abad22561bace6990aef7464b4e5d5ccbfc649eb3bb20a537a3d455ac43243a734475fd3605bd770315348176209643392463b1564a6702aeaf7e23b0a89935183ea8dbe423499d5b80a9175cd97c4325ee880a2da962b4d13246af08cb58cb8049135dc8248dc51d7ffb671f0514f569f6dabaf5809279cc5b37d475140fa5ea29f0d421297bfea14c504d9a776f32d4cb2e046a72ec61c37e83718f19b5725f4bb709d24d7388134115242ceae4006f21b34e80fb63be4540db8a942756dcca64355c3cbb3d12ffd08a6e840e8108f7e0bca9dd17202ba4a9ae36b77456afc34fa3a7ef2543d83146d235a59a7b4bf013ed9ce93719a55ac741f613107e799642a9c67ef8b34771e649457479186333a77fe2e59b2706c95ead1db74327507cc3dab667f831733f741559cc8a86fe7e1cb624433a65e893767913215e2b7576eccbd1f85ad9a9c350562ac27caafe6308cd351239317634e4b668d55f2a725467a86dc291ac88c792ca8b615843e623cee91ce92f746e7d10d8200ddbefd8d4eb3b10e47616512f5837eb1a662985249d6db51efc184df1c74092de5ee78c91fa4e79a1b057a4ce7c7b4bc8058c50fb868bd1e2a1998c090841cd3f913480e0119ee4c72085e75ad0c1139e3d594960bdedb7938fc2af9faabf12e1b7f4577c75f3d7cf475324c1e8e47bb0f473becd157f213cf16d5de9aa926761e3d7a1c1df9dde3558fe95c45fbbea015f5e3ac23164a13d3e99826ad50cf84b1b9aa431f895d5b2f4afb98ce9b62b44924c454fd1a9ae3257cf12378793aa0e2bc47302184335029da4c22ebaa98b5cc37046d873c6ead762c8ae214f3627615217b47276730ef6341370366554650890dbee797628dc974feb504b7d28cce49c97e5ba482d80850f3225b42d8ce5826a75599a4866571c559d925cf413e18d221cbb674eba224a3a2645bef798ff1c7bd199d77dff3462900972ca1ca7dd82bea629a4c2947246e68346325e4e0d2a81a89f676f6d0f227121f70487aac6491d13ec3902345a7237e4cee77567fa6315605d8d7e672188d81c78360c8c4d49a29974aeb21973baca7acc700cde32c595524c59eb2db632a638818c7822d693e2135fcb734381eca91b4d490dc9409285cbbb3e9905239ba1c6ae2e41d39a014da6efd135be2da8b774fc4ad8425da6a3c76d582e812696a9c61fb227fc646c58cfd9c17ea56578d3b2ecbe0faecab4fd895fdd7093d8555f2d2ceaec643ce2a1f0fe30960c4a64c29ff8939c811c78adf3b4005254e399a2796e849841c4a93a44608b5bde756f8d05ed63ad0a267d7050b5cf6ee1e7c121c6fa284b215f2657061e29ad469f106b84e787262658d039871a90781d124b905a4d85457a3271e824fa5947f0c3ef63770b47746becf8f5861a6db30eb917394ebc28c2dffd8068758724ba7d860cdd7708c25f5ceb16b6fc55adb411c6779ebb6579761b79e4690a6ed0cb641fd8bf8af92cfe944493ecd8f1573d35cb025cc2a706685d5b7ca3735d6b910ff062e9fdce803ebf5413af6235c9470a3220dc2ab3bda31c8043f88ec68b4a795d39d0bf902c970cb0aa76b182880b76ff235cf768de72db995f7edef873cae17aefaf70956a0951741b8e5ebb32db76369eb385ae4af6c1468baf2d69e51986448f19575d60d078d5761b1a56cb610795eb2392d999e89fe5ae8bd6dab986d81e3e757cf7f7cfaea1f872ffe6bae8cb5ed176b5e19d67aaf79537caaa9e3bff352a921c0719c257f55027a1bcaa138ef5b918d4fcf7ba1af6a4fe7b2eea51f10af98406f8c476e08bbfa7b95205fcb05d837b216dfcd70c20e71d289f9d848af2705b4990c76bc6464c8984ae21dd4546e665cc27487e4960cd24d5d68da4a0afc1f88625314f75324f5469ab99a5efe5582c756d0c7bf5894561d459b845aa8babc845a52ade33efd7408ad98e8066ab2f5d229c438fd7514179f3185646d2a846a5512c918ebbd3aa3a43b15417f56a69bf3a9d41a39e7704bd002728be15c86e92822b71d67d93876d9a16ef91a2dd2413220f1564e57e62c2b95cd06c7199dcd8c5eb0a38a9562ac610e45f1b506976a0f9619db7730929ad857f5ef09f980fbb907335608ce4f359c070fceda1d921439dbc39b31ce261220811f6443711f595b11c5a69bdb6c9a109ed2ffc25d431129ba65353dac01930312ec555499608dba1626512ae33d720a3c858d0fed78be4bf5cfc28eba662132903a89438df477c2a553ccff22f35b4b2b695a61fdc776a33f864d7d2446de8af4484f11e713239a65433aba88d529274a0131d8e990c1d0e39a97e1669a68931114de415a878c58870c12f170d415f8d26aef937b83a42bd678df7bd3e0e23700d5d70052e30c12299792dd7647e2e380414d7b657b18b0d39d384aaa69cb04f43875d91180e17adcc6f16b44215a8f0d76063be02630d82107e227d6d585e7e4c633ec476be3d4ae2f91477600a91dd4fa89df5b83212e21e248bb4d06439cdb60b486bfae1e06aa90c4046451edc14e170b6bd7ccdc605defcb2fc9312b278cd0bc8052b1b20a6c9a57b2ba203ee81055781f30d98aeeac435cb088bb9927c5076e6b47b11d698ee95c0289a01b0eff007ffa31c0c102ae2d40cada89194d73e9e4234710dbe709abac9650f80e5b471cbe90df74edb0464614bd044d3d0b0db1c47658c4cb479c84922e9b8686cb120e63305c716948b280c777e81cdc917b70477507975885fddd7946d847bd5d0db34ef9e1c9e3466c505b87d3b66ac4029b7b4ce7b51eb8b2a0c4732c1f91eaaab118e6052e4c4cc68ca7f9949569856f8ee95ca6f90dbed9c5123242809f97acaa52566ea593bc28a3575fdd4e193a578f37723d638b17d00fbd9a7872eec94c96505a5d3fa94f1cd9b856333ac755310bd2a83bb89ba516f23cace2ef6aa9cbda2440976b5a6d5fc29b7737b879cd376b6e08527f130f6caef2936f647ba4f218cb3bb9f6e812ad176ab22ae99d5d9b69d397efaeba7c77ddcb773772f9eac5aabb84d5bfc6a5269fe9526e9c1f895cd2bbe692de8d5ed2b5107d779cdb3091ca216a652986cf73607a3d3229e910820fab295633468a494b264820677905f5c1a70c14b2825c0c1715c4f278af751d493a8f7c86e6898cc6178d67261417aadb57539613e443ac2f45c0607c609a6532bf1b96732f728e85960bad6225f18489d27bec27140827ac3aa6f397e905030e20e6294d4c68cd4f811439a8152355b759ca799a4f645709a48b1ef4368b615d1472783a28efa20d4eae5b3bd1cbc2fa408c75092e204518e257cfc072918cadc62d2f03c15b75f15ad205cd6a30bf43fa1b3cfd37eb6f786e345ee45fadf7d27a2a26125533890fbbf37424620695b7c4905160755e8e8a7c9c4e16d66bbd126d9b7bd77dbe246f25834ec95cf0a08a9397a95ce4b192b1b0333ab7b3c9bcd2b5c59d233b64693ed1e68e9425769f234858533238d3c9629e8109279f60573aae58296671c9ca4a062dcf203016a0f10e19b229bd4c8b4549520e6c46c5ca99e034ac8fac1432aae2cdeb7fbe5ec502b0c1c3e04636f10d1f6efe9b84e45e8ffcca4896324287c5a222584f0ea08815e32459407dfc884bff713a2a0b5e8cabdebbe59cc92c6ecab7ff9bc70fe38a177e2afdc061a06e0dbb27f0702fb498c50bd691f564f5878a5d78e8b20b0fff3ab2fa43c3063c6c96d5493c3beecd4a2220d37e91bcc8c312e932d01c924e359103410aa4f27b964eaa29e195b82587cc364fae481c76bbf3fccf9335b469ca11df55f7ace68330d758d307ee906c4c50a05ba9f45478c59d25179594da324efb08d7df38fd00c297ffa2465b1d3b095eaa7757f08c7bb34b09b8d5df809f78f12b85303007d10fbd2fd2bc25eee8fe463b36177273668772d421bfbc9db9adb8ea9277653a99b092eb80122831c9c9264d92cd0ed944fb38267dd9444666d33e0d278cfd0e4930f1679005f34b18a5d27492845534cdf82d4ed0a794005bd3064beedf0fb464bafeb99f03122ac808ee86f43764460d764e928241de7cbe980bb6ca1fd70128f03159dd30cd31f20fa2396674ce830a309fa31096bb8a7f5461b72085e8319dc34b9d32b4f725d9bca4e52619a7d78c133ea359b6355ca45942e06a9628e1874e62c0d27aa19210ddd57107d1de37e1885fececf783b0be1321e4b801894183bbc7fd9db0eacf19f777c2aab5e2fe5684f47db1e306f5e9d50c1a3b116a274ea48d6942eb63fe6e11e577c2aafa283fb19d778ff2e3ac32517e02d4e789f2e3ac5a2bcaef3314fa74aa7b12b7102dc4fbd548902a695034349004b1f32e513a61d57f8b7f873b953fabe636b4999a6fde55738bca00f9e8336b70b53c786b1d6e83e525d8e4c6877732a1ea85fb6b6a71579a5a6b21de4e8beb1e9a2657801ff2666780d024f19fd173ac85b066527153bffc716763ff6dec0d7f5205c24a3b42d4b7bb5973ea60db276b4ed74b62f61fd09ad61d2f9a242b6fd5cfe4d41ee6dafa2343463f5fb0f20aea463e311cb9d723ef5ebf78bd47d28409eceff801caf8e715a4391f3270fe82ca3f1dc20b546049e5d588e664180c170abba15d67b8342b59945d7222f8773a9f672943c5019ac405eb4a31d90aa1f37493776ba90d4c5cbb0f2332c50ecb1dc217e19cd02469f915f7902e1a26af314e706511909a1dfd6b465ad5233d5937cc6a05f2933f5138d4eac8a2bf629812b985a7882f3a0531fdb726ef7f9da87e130ff899a9f4bab1fd8d14efaf493f3e7770ff9f9e84dc3662e8b305e7af752f9178bc7b8d54fbbf8877b21699f43344c568e4badc7d3c655518ea24e9c42d46b96660c7670bde7092f7fa1db45e2736f9cf12ef01aa7d390f3da7e88130337e704076a24d54c6c2589ee13aa26505fc9c42f008266dedb8395ccffe13113f2e62ac8a1ab35152eddb2dc0af8e025bf76c7c5adc51e1862fc7b0d2d339fe6eb8198920f34777cb68328736f8b0fef321662e46c4fc2a3f39cae18455ff912887682841d34d0d4afc9abbb9d1893d701f14b2ec9d5cd72110a071c1fe54c35dcfd33e3e895a5f7bceaa665ffb604c7774be7771ff531c0da462876c7acd36a5a2064eea13bbc75fc03581b3eaf7714d70d7fd8f724da8fbfe2d5cb4c4c15ceda2e5835fed1c65dfe33a37c729e2bf7713b63ddf22d1e8ccb272af1cd0696b40bfd8f90cc19f0d0c47e00572c22ad70bc477ef40e78af5dc3bc0acdf71a11bf70ef318cd0341baed3b7a70c4a0b52a5a4e58a5184734ac7754e523e59b1131642bcecbf1ced0ec9849cb1b31fde327c5bd0bbf84ce131a4ca424c74a578eae37767033719e845dac24cd62e4e0aee16667767cdd42fc8c2dadc394d0e416e984a508e0a6a9683c1f2bbe7f55a661faccc63441a9c460955b2cb255f12464ded803b6caea91ea53429ecb0aa8b1e19020f95343d2a748b18e1bef9ad3d4fa3fa5496ccc30169676271f3feaa5fa7d92e0dc55f918745bb31e8ab3239f929aaed753ea443e5f92fbaa9476c9fdadfdc4fc75ebab396fa945fd4fe7af5b13c3c8ff32dafd2fa3ddef91d16ec5bdb55e7afc1938d6223ab33c5151781f3f4ad387fdd0624d42fd8fca103a5b9d18347eef44b3af93da04daf0cdeb9457625cf7eeadbc3f0992bc3705e729048eccab7496fe1b566d8fbc28848c0429e828e1827cd24a867d1725c49cc0b7543c5870267b3d08f8e45551cad04d19efa9a24de81ca804a349872c38d46d247cce4629cd544c53559084e545c5487f43c8c4ea8b5864c7fe5a53367f5c93cf97c53f58c4999dbb9fc513f74776140bdfd2040b590ef9a84c5d0f864fc1759a24a6ed9bb2983b983f2f8bf92b2029263322abe7ce57bb5ec758e5fdb0faa5e1d56bb840ca392b2be5baf4dcf2f6d1a2851afb1fef5e13bfeae4b8ea5929bdd84d5c5cbdf7c29f9de3ba65024eb6fee1d33b1d3d79367d13a7cfe0745dfecd55b9373d65b49d85537911a50e9b1ff7b7f311b54326e206a515734f2462b79965647a78a32ac84f932405293b3cbe9f24cfd1245112539452886fbfbe02ad1fd420662523290762ae5e93848d325ab244ebf4aced98838f5ce4aa5d490e645725a13b7f8aa3b73606ad893902751de1b1a5061f521b67658032cae908f697474998b79866e7fd731847ac9aee06bfec5dacc7ae3b600816165e239ba6c375acc8aa19304c2bd1e14f4ce4ebc41245df710543c6e5f3d06ecf2614f15be642e47846abd1f43379e0dc52342d328b1f5947bb43c2dab42e8cfbf7dd07113e99a0a0d9d4499cff86aa0b462520c42e9a27c0ecb24a2bf623c5392d0de04a2f177b199a72ef68c72b4bfa688a73b18b13585d9a8b52d4cb23ea9f2e57d0aa618503d9bad7b3d2b700c9f25be8d7facc435ab43f4ac1a10ee62d151c0d0481b8ea0df9dbff4aba4487fa57543d90a6a81196273132fb29b25c9a656c42b3a723312bd715c163243c23ac153b4f20f4fcdd34e5644ae7739673b16ed430702927143ec012083c594ca6eac8e230c4faa77907a47a87f5bba2dcfb8c62064992966c54654b423929ae72d3a7c85de05d178207efb03be9ee79cfd060f5d4db802fbd13f3a52c9e6ad6baf5d40e81f940aef7c88e9fb5c0ff3e7ceb19825ae79baad07e564c84e4439eb5daddebe64f1c55982507e326afa60cdc069c75e653150621e0a709132bbcc92b5aa5a34d52942a5ba19d6047ae5f0ad0169c91737b6c4fbbd7ed73af6d51ee89fd2b043fd97a2a57c892ef562cd5af53964b758e82d2f1d025cd3242b32b0af98748c934b6d420091d550b9a6995b2fbc19efda79adb152df3567f4331ce64132403754a4058d824c5583e8743241f5ed1f58e4197fccc19d95453dc54aa2c5459c17cf4acc5d6204c925604f70b6887829f569b1c47f1bf1c18a42607c60a1219f355314994ffac4931c43e899e24b5ba6af487a0243fafcf6d1d50d4227c92f8f7c77ba4ac18505c2f722b93f46daa93dca2e8c91f5ec8c462490d07fdbfea267ff1ea26647d99ef6ef25eb3ac67e4bcb08850e881b352dabdc3099fb0eaa715cede26a103adf7c16976d3060b0cd0abb76c9c898bb4b8ca21a7a72598b7056342f3a5ff6d4c2e78ea4aaa2b82ee877ed0bdfa464706e40fadd8fb918abd77de34e5184cac1c83a3488ec1c4cd3198d4e518d42e59b6578da7d3af5512948c77e70b3eada94d598b4b7f64aafe1146ef8face87d8a8b6ca2f7a98cde1fde217a7ffd54fd6455fabfc0773076725c67427d6428f7bb69ebc42acfbc551993fa1bd68c44e3c051cee91773a38b666b12a0a4fadbb1dcbfbecad57d2f7346c88980dba6ab6356de6fa84d820606cfefc6ee19564f0e2ee587200ea6c636d916dc9e74df9ed10b94001226ae2b5ab1446566343cddbe1008524ed0b6ada0d90c1ee882ddea04f25bce84e5aec87741667ac11dd80ea30849b9cb86e9ae9caf436ea4c8c74280f5800471a2c92c300e36fa906ad78a8e6bd4c9d124e8a3aefe184d921fd32461802f2e9a74c428dafed1a2c90ccf4f5f3ae2168e9dce987138a4f482ed47cfdc9660808c03efc8b2bfacd74b9fd4f54c84e678aa0c91b5433d559dcec8c78ff6f6add5e520a49d61ea8d808f6c4cdd41d64a2d425ce7557978c1e5b5c69a47820c22e21f77bf7459f329fb1be0d66a19032f570659b40dda581be9e1f30f4569dbe5c078878a3b6b4ce680c01b9f66c14114a81b44590c19263457a807e223c794cd4aaf52804ea572f97e488a6eb2b2690f5d347a0b8a64ca4f9a5894842c99ebe9aa5f292f7539b7988c1a9ddb4dd3690cce479389333c1d3507b2fe6caceeb0f264d8fea00a9c6d056e3c356056f9b463b31e0262e8c4ef75ac6e33864f3a767ed8444d88c37a7114b1ce6e6045ac8547c8c3d18879e6138fb512cdac97e1c13ed207abe4a45ce424a3ff4eb325b99ab21cc3fee6690679d70bcca108297180ede00bd43e2e810c948bbcdbedae38b3388ad8995db5bad8551eea48544310a87ed3cf3d7229d359e6938e567e79ab25535442239982bc903c8c60def1b98aba8bb825d893c0e8c7e8b213cfb563dd023977d720aa7ffd8d23cd09ce9543665588e591a1dcb42a661cc300a998419014933837a7de92aee8582fc0c762536bd726027e7dc8329d771c32dc7ff9f21d6e307e21aab3d05b73b0726bd47d22c19a520f713f03db3bc1f4d1155e0d667efc68bdb70affeb16718f0ecb2bed77452450fe833ec8983d60c5d0c291144c091c29d74558acd9cfe85cf69cb0ea051b2e26822e2b2206401a50cf126e6a31e3cf40dd1c5cba7f9fdc73c858a04c8097aafd19780b9e3046feb6b3fdf56e13d23711798d191a711ab0f896e8219e648c72862ed5e3a565ea8ded5e2cfaca9010cb4fe74f82e479610f771e1afa2c8c1f178b3c51c6c4b050c2ef8beb8810e68a6ba37ba0eb6468bf792b2b13ad47856b7c0cd42f3a2e3d7281d66679c621bbe35007235e0b2a49f9bce0acd49ce19d2f8e906db82dda4bfd4b31ac689ac3ad69c5ce5b846085d4b682214172e1e0b80cdf3fbc9eb3118445f062a690cc57e9acc160d471f3ad3a8ec9fdc227e15c4c97e6605bfddd8e00a3fcc44aa8bfdfbdb0fa4e90c696f815d084be9f8ca1aeacb21eae7aa42a8aa660b8a43396dc16f3a01356398b22da7e405dea651e0f1b6e8d27f65822e7d31dcbca4960cccd25cdd2046c32c84813cac915cb328ff40084ae0e0abf51f1f456fe82404faddeb9222168ba7f5bd0ac453b64d821099b3b95bc517b3eafa681ce1c9e6109376f74ec37079841935e8f3c2fe6294b10952255a0de533ebd6039e53db1ff251f1525eb0db362d87b34da7df835fd7af4f89bddf1f0f137e3e4d1c3afbfd9dd7e38de1e8e77779311db79bcfbd5378fbeb23a76dff3bfbddcd9f9e6f1d6cb9ddd6fbe952300ab7f4e3352b2d1a2e4e9252aa868997281e36a61c41e9ca71cd6e6bcebac993bbf0ea12715b8720ce1a7b578e26b09cbc1a746f948000560026a979c6f6319bced73edba061422dfac48aa3a762d6882af139cc2e98fb49c15f9929cb309cdce01ff0b4eb3b39658d3bd5eef2abd48bb6c34a31cbc60c04726292e16ddf974fe244d0ea6d87f4f746f77edcda630a4618cc6503898dbe278ec901ec196e2b7a14d26cf859c7b4ec4f2e9337c8ea50c61da823ca61524a06af1aa4c4795b5fee1583059cdc78f64a8fe880dcdcd352746f18abe3ad78b9d5ed28ce55547d679ccb74a36ced8757ac9bcef8909d2d80786f0ca99e8e1f5942e7845e6653a4b2bc0a3291b5d709bc88157d601912c0eddf7150741550b501998178e2601818891586fd65a8de7b0c08c9c9f9e3ecf28e76767e740434c066130118857afd082a2a805dab3a87b199986e04be4341d462f537744fc2a0573aa8613aa984e54a5be7c311bb2124224278b0cc248e725e33c2d72de2109ad18ef80e7d8b028324673dc73c4284cad0c128223868d84f0d1df38955cf65b3639bc9e9ff537f6bc41e00b0591952396585504d151cc908ed6aba2627b6473933c203dda4be1786c8adf36db0d5fc799fa5f972378a3708bc31cab294ba10849c9f8bc00570a252a5c95743e179c898bf2fba49a2e78879cf7371ef537ce491a0405f47a567331bd73c89e03a36a41aff679b786699695b6a864dbe10f37d1bf37d957b09b3593bdf599b5facaabfd157dd52629f766f48abe0afa083c7e8007fe016d926e1fe0d17f1056e6e8f5c8d35c91600b11524ee6ac1c17a5b8e64dfa6e50a5a72395f6b066491fe0626e9327405a1f585496eca93f1f342ef20b5a317f89bd26cff0b0d46cc473c0753c5ceed9aa0a3d0d43f6e484e0bbe1f1039c8d7c64966659cad9a8c81353211453d677ad2280698e3c110e06cb70d5f78c7ca7182362c1c040b9a47163c51e34af32e6628aada0ae90278b1761c03812747d25224d97099d60055f8f15b185afc75e0d3d7f316f48c734a062fea05955b3e7c7748e7b7dc22493b2c891a600cd93ec683146fdddd69ca68228d3046810cd499a8f8065a119c9d825cb6287f4c734c1601ac2aeab926243cc7e3f2a19e5b2542bf255d1138b6ce7f707c084c60e2d3478f060b557ccb064f4223409f47ae4679837a1f992a805d0feadb21525077279ecab71689e0e3dff821255fb9c1cd8b72c6084da1a6860670743c3aaea19abb024b90a97210077cbd5ac02694aacad09aa3c71493a062fea8a58ee1b3c72a2905a9f63e7730e5c208cff9c7bf041023070c7a56047044467df61f19e5745490e08b57d473a64281f0fedc7811e153b03ef06bf858abb7b7a1d1160c890c5f00c1b5b1e68b4063c915eb3623b6ef381a1ff0178d08eb46ef537ac15e86f1021b9a3381f3c1f3628ed1af2abdfc4c541ff10c6133f07223902f82ee86ec994b173f994f3c54cca4ea9f4411f2d47593a2238c945296ea1775346683629cab49acea051c22aa9f6c2e6164cd311828c123aaf94747a78421e7577086728f4ed3ceaeeec761f76081d0a397f549162cea462e4fc9fafcfbb314d1156b0a6a30b28765bd24b56f20839115daa4d6e4a88109ee62346ae18ca4d3983880f36937ef75290cc1345960df361481408a3e2d8e02f1f3fdaeea043f576187b2b4e1d26ced5fd65225ddde46a9a668cb4f0e9d656c8c0bf4c7306898669399a76c91b6488c08d23e5e256174b21430a8a522c238a86502b1fb844528c3d988b3cfd6dc148ceb8d8256bd383530f633ec5d19d01ae863c9e92ecc2b6c338fe25898a8ae0952e708e235e6393e53a82f7a97d69588fad5b03a40fa99fc8968aa18aecbd2bc0d6dc16960808bde4ee720c0992b5cf31e80e0b293bcc6cce468c735a2e9d753608e2e3861a8d6c01c457b6b9d515f4c20c05d51ea322af585ef10e492779018a2e2118188e14b480a98710cda8aa067b8ffdd6a20a0b3a64687e45b2b44576024dcf1dab55b814d1df2867d63e12113781bc54f241de781a067ca067352aedf6a37b277ac6b6afd72387b9d45ad38a0c8b6aaa714fec0295b6592ef8187d5cad1d2043362eb4248021776cae89777062ed990cdb5d0b756e8b38abb7db5f64464753326362127e535c41c83b2ff1216e5b6c4d29ff62a735046f76714983921082c5052ee1cf0644fa544c0272017930020a0597d92d6954316f8514ca79e8178270cd009a370e1d8b5c57171ad516d12ecfd2116bf966a3c393c7c70836a2bb8f83b232f25255bba115d8a3641eef10303ebd0b603595c8ea20ae50892bbe63e05a0ee6b273c469c9c9acaf13055bfb201f9d7ab984cfd02071c2b2b13f07d5246eef113d5ae13474426f185e0fa244056b060c8d10f6a48e1dc4c1718a2e45d2ef8393b9203dd302a22b44cf5fd36a5a2c2a9256a42cb26c31875cddda917db8c81330bd8d699a115a81f0362fd21c9d48d219db47339deccfc9622e4f4a26583f24665765914f4851264807d20ae381d189550bee18f3c1494b8c9e5dd3d93c63dad5952fe64c2a5219483f5931a21901fffc6126bd5b864c0c755aa4828d418db7989fbd1482e8c2c77925fec7b078f07814f215ad48c6a8f290519dae985c94898ce12d19cc05e696ce049725c5b9aa4c69063c04cc852cf22acde442a65942f86234622ce1844e688a2ce5973ddc468cf6fd92b4466d729c8ea62c23bf325e81e98b91dded9d47644bfcf846b63b3e7a475ea623967396e023f9e257968d8a19530cd4ac185e135e2cca11e3f7c83bf42ea3b9f45825c5252b2f537625c8d7b4b822c7c5f05f983907635bae8af242e6f9fb129744b0f364521409c12a09a0b7a565b5271b29e3d38c25e96206c6a7bfcfaef4547a43362a66693ed91a2fb26cb9558219fa926dd17c2bcdb780946fb1eb7946310bfb5631de9a19a78bad478fbefdf6d1eee35dbafbe8abbf75af2f87d3c7bf255f7fe52cc1094c978c8b2c612557033b70ff393db6089da73d2043c78520f1638ce45e0c510aa2553a2233564d8b8413763d2fb8d6c19159912c32a672dca3e3899035ba1a3618db04ec2381d333a554535f8135d792d53e7afd895bad4c2f51fbd621a5b4d6c3f339cb13968f96a42a19e31d278923ef92e74521f07b311e370d4a90402e46f534431405fc96ba412e45a3021dc2c388e48eb6a3e689caee9872736e60e9bbe4281f658b44a99f66503e93959c64e90523e794ff90d1eadc8c6951a5198ce9e72a05511466d1b5b70ac2c42d25cd1b88843d087480465923d58441138bb486f5cd4fc1e08f5bf3e881a9728e9f03751e8255373d391a9365b12809cb2fd3b2c8c52e07b1dfaa4f29e1e8c5947e5b4971954f4a9ac0a9826f7fd5253f142501670df28a825af8699e94459a74744a08b2988b5e6299ff79f2bc10bbbc6159879da838c8cd2356c08e8912b7b5d870494a6492ebb13ef082b8822f99f46a90e44c9277e48a801a58dd5b692e58c6d11455a5e0a1a82d4c64c8b2e2cad4f8e48b21afd20a821980926e9a8f19234fcce3c24c5385127aee1013bc7f314981c7f9480c9170232862f32793ae6e473e98503dfd181652bf8221adc8ab5f315e3d2f12769ce6baacac68e8aa8562ad30c20b35dfb1f781f6eb6efe77defa88f69b7a7936fd10e8a37fbc7afdf67070fcfad9bf06c747af8e7ef8bfc1af4fdfbe3a7af50f35d272c102cfb35e4f5c9ba30bc20bc145a82323ae29598827f1c5af4b5a4a6bea290c5f8c006b41b0fc127f5173ec6f9ca95a114112052f73883cf2cb62a19c89724c503b838515045f603d6a62d181500dc4e41111278533505fd8282c8e0a500760a8046584ac3c25e38bac02b2490573af140269b624192d270c280d1747053b0635046eda12a52d741ee016bc38fce5ddebd72f4f06ff78f9fad9d397831f5fbffe6930f03ce95da70a272188e53d42f36479514c7a6285b61276591545c675c28ec6ef75d35c7ce9b8185ebbf5a8f87cb927fe73eb405f5725e57ba16869fb3fed397f39f29b030c9cb6f6f0875e348bb517f77859910f2a4cf087acb87a4ef311cb323844701774c8d10b7d1143808f1d1b724ce75e0d8e0e518e751d42b3acb8823e181e0f5e4783e069a4e1111076e5bc17efe6b6b181bc6534e187b9df4f3d0e9a42ba85586378d1210396274fe59c02a72ce8173ced189a0be0542beb51c76468848f4113f751477b30a6f9c46c03b68cbd118c120f3fec3fec9001f0ac6a527ac31655512ef28ed260941d1d63d7d1115fac23438b9e56c5ac63653c92c26a27483fd521e3acb88225e928e7b48e83c4f22fc5d8bd2b193e92290c4a7c30a5dc5a34b1386a02b2bed7cbf4422c2bf7a2f6c51aa4fc5971cd9c4119ef50fb77210f8bbf6b4e830ddcfd0b46d0f1d5079d483091fb4c7dd03b469060dce23cd5efe297fc991022984af0609efc9c17d6337512e5d04b7d3031ff5f47d0f8a35cad21175f15048954c53f4f3aa42ae98875ec6a6b1d21d095747421c0ab6a3720fedeecf7f38dce0654d5c9502a03c90bc51b72f9a8fb55f72b607221b0a78b3243f73d07c6563c7f5ecc972584610a0910e4bd400cecead6707ba05447464502aa7ff9dd04246a144e8590a886833200b26c00e3e5d1f3c357278728e34a56ae2c8a4a26702bca250a28e64b42dce822139ea3dc4b3eac4281d88e035a584b691f27433d638452526ad825eb3cda4789dca0666e5334dddcd72305c083818c20ef900fa0b92f7230aee2080e5138eb90378b92596fc7457945cbe42d1b77c8f3699a25a5d872f919d861eb3b1fc838cd9317af8f5f1509946de79598f36028d85396fc3c47870ba7fb5652cc36f71d75d3002ff356317c2feee8dc61581d9126f471d32db4124a36c514fb78ebe3d52d9b3bf905f5176dad13b62b86eff7e5450a3f6f94aafd76d08ae1fb60acd1d914c3f7b615daf2df906f81b3949335e9da9e5873257bb583170b4e4c1140b3e0fbbef26f009aa7e734cb9e4fd9e8a2a54b9d90e76674d63eddd32ddc1245a6ad5e14237bbe5bce99923fa5bff8886619a132ef21e584122b82434dc21baa93403a65dcc94dcee57775769a148a9192947c87ef95d182a40f1ee8318a8609439757f00d80a6a7e9995c4ff3ae6b029b21dd47ecf9c78f4af5ee77b683aac98154826b41a8bf81e5b5c1e06e7ab56d0857655a85bd9b73b65bdd21819805ba6689915c80c767ebb9ed3b0128283ec03b526bf4c65a74e98b2f5bb4235b6501b333565a9df61520077c23247728fb16ce3fb71d3c1af16829ce055ccaf2e6b3a674c1966247ec931e5f70034213844bab6e7a473d0c534ae45a620bd251c8576ae3f1b161f60322550cdf83d948d5868b90022414de72c8449bbcc51743d8f90e2aa5e1f790449b77515764efb50a616ea00827a001b75428b305af08c32c9f4386eedc45192711e2871ab74527fd1c25d6a89c313ad95371901655de0bb6532f517c771af65389b6b9de3dc0756ba1079c556fd4705e8fe3db116edfc4ed55c8d5f69e9b1571bf429ea8e75e7b2b3142dd270c5a75070358c8c140d0c028c05621f7cc3ea621e4707edeaa141d325753e4eb4d5190e535c011671e0764beef4e520fdf9e400c5c38072c0423785b131296b438cbc6d6f9c20adb76cc8c7f6a74665275742acc800c7a2527b789e096b7106f5a6da785b878410318210f1c4c79fee05504bf4553df427b183126e5b4a60137fbfdfb9a5ec0df5e9603a3c3b6de5aa7db4730d12ac6d934acab9a47af47de4d9910132478ae6c07bc5a0c872c216025cc6568713ab2f5dcdc5909b4511f5ea35dac750da3ec577230d762d2d7ddc180f163349cdcbfbf9e69f6ba433625f7bed9264fc8b5aa3d44f6c875b01ff28a2e66b3227f2f3fd51ae71d69ae7107254d3890780ec7bd473edc909b0e19e72d7ca93a766583b6ff60df0a1703a6fe880f8c0670304b4d4e127f549a59569f52df10838c5fa5b245a7bf6156b2bfd1f98004f8de36104f3194e1818d320707070ed37dffbee49dc745d9191d0c9f983f5bfd0d984697a154d4df68ef3ddeded97ed849e2edc48068a69a3deeb078b371492736bcaf3be378438c611acc8a84a9b6df742635df2e0b21c696b2e1ce579d696dc3cb34d10db7bfed5cc41b824bd4b51ae5ce76278bb7a37c998fec41eeec7466b52065e625af7d5eb35228760e4a36566d773bf39ac55af0b910f355c3879d32de70c6668568d4cf45b3479d2ade2ca3ff5e2a588ff7cdd96ed1f68774dc3244ca6014bd7f5ff020f70e0e68fb8340bddf0e68f78b2ff0ed3e8626b57e6b7f0073d0684f3ea007b40b8c05956fb23df831c31f0c7f4cf0c7784f7b7fc8b36f81b97fdf7c4e43bbc08e39fe9886fde583df6e6ea045623db8d1d3be14d3962fc4121c1c1ccc6ee411ece29d76b0d8570f9e0a94382e127690e967cff5dec38b99fd42e099b83504d37b70e1bf792331f660aadf483dc5c1483ff9416b280e72f3509eb403c1e3aa876fe4493998e8766fe0e01e24fac1099c3c18e8583f4cf92f344b13f96dc1991ea8f5b156a7bf81415c0e627cfc18a741f4e3477a7070c0f0c70c7f4cf0c7187fcc45df465cbb7fbf65f65db4f8f8d1f9bbf4fe9e7a7f5f787fe7ed1b6bce662f23931568f1f1a34488cceee66df7a5fbcad9f0085c09f1e226eca6b1a1bedbf4c6daee942b64896ed68a95751666640fc742b8fa91e44e0f858df5ed99dd5e236a7dfb89d31eb1b8be7562b7b651bcb6c758ace40d565577b89a56fc8257776efc2d64b68dbf9234a4b9fb6e7d778da5cd101ed6437011b619cc578d606ce46e86f368251c85edcd701ed7c391c8dfdcffebfafe06cd9b417cd30042e27d33806feb01a883b002b9b61b20c0d158d1bf013bcd615901a30145c3eb6305ac0664b5c8f20a200da8ea13e915901a9035a0e92b4035e06b40e757806a405d4df9578068405d9bccaf80d280bf86f4afa06f0d186cae8315301ab0585d112b2034e2b073121c38eb0a772878e620b8bb0264ed7751b294f750ef4bdf5eb8bbbdf3a843fe8f4e8be21e39ca475df77dd430f88a5d9167272f9407695727c0a023307de7cb349fb81642f02966e58c2b0b204effede1d3e7ef0627ef9ebe3b7a7e028952513d384db344e2b238ecdcd1fc8dcc8bbae76e07c9ad8306db7d91f2794697e816623d078b604d1f7857a6972c01e3e20f65313bc474f3cd8d4248b3f43acddd47f3b29887e3aff44cfbf98d469d9f5ebdfef555b876b93f1934c9f89f415589bb7e34cb58193e725bd172b200b58df734ad96e1187f78fdf6d7a76f5f0cde1efe108e7453b1879b0ea8920944fbb40df4d6d11ed2bbff7b73688f45bcb19f9dca6364ddde67e42036130dd2d5ae1815a9fb5c528e09ab2ce5d42b88af3db0d4b9fecb683794b96b3bcad7d1ae2f6c4b5cb4b76961004455c0eef37d95095dbc7b135a0934d2b9a66a70b87f25dd2d4ec0d4a48c8e96111d7d08ac07c38c8e2eb294575a8d699b4fdcd6e87a88a2e5a6654f467f56ac5a2f4601feec328f08694dab59d6060f1e00c2512b8affc4b7bc893a7095d953d757336339f096b3e50db6bddf0f02992260eedf8f0117135d352ef16fbd450f3f60afbb37ce1bcb91ce5e2a2b2e2e82ddb1d9bbcb1cc5ec6052f20b1038372af211ade21d83efd9d308c68d2b22d7871c38b4e3d45bae5343cececec8c78feeddb6ef02c651d400f686b812b0011db3cbdbb184e4c183348aa756409d36cbdb9b70cfb96cd0027aff3eb9d7d2e820fed47f408336b670a77affbe3b77bba5bbdaf7efbbcb8f2da3d81c3818d4d1337ff755b85600119dde83c744861c83f1684cd30c42d4c115a76434d982282a136d190710f5237087147a11b8ff6e88e5ae7eb3de39742a9ce8cfed6b93a9630b0a5b69eb448c740c46ef0516c75ee94bf2f092e5d5e12cad2a569203c18afe6d3078f3f3dbc3c140f083aeaf7b6ef9b9db1d5bc6f7c8f3a9c1c25b765b434aa06a922ebf2c2b30194397e3906143e89053f935280dd6df80e4eecaa9056cd57a9445de1a0ddbb62dbb2403301d1ec8a03bbd17ee7030c67c3434fbac024cfd15318031bff7017ec00205cf5f8f2534978e621f71416cedb4839e7c0ea19dd0a84376cc606ef66da3ba36e0cb0561b3b4aa5d12f1b295d08a5ae3f73e3b2eca433a9a5a72ce387766abd622474066586d675c676dd7646cefe23e9439da8fd9f7a63485b27c8255043462650bf21ad18af9680859e44443c8740b013d89f48ab20beb6b7e01ffcc8a91742d164d7e5864994aac86c11cbacc57c6727260986b49b1c123b99245703036175a7e4f1e9327d8698b3c267b64bbdd2103a4e28ff7f1b7efe03dfe61796341b5adea149a6c91c767f657e1e9590d4dd02e97ad28663a1317f2acf3379413faee3b9a17f972562cf8f7dff737f466da4b23ddc3f49f1f3feac5b5505ae52575ca6c788e30c44a4c8cdbe55d1e90c5062bc52a9f341b9acc71f884f437c42fe00be8c4f7388459a500b5a2c0de4d19e665554800911ee45c679cd69314cfcf49cac98c9617e8b12f63c61284d0df4873d9d15d57e889412569c5659db694cbb67276d0a8abdc11eaef06accda84e98e3f764b55207a44be7f36cd942478a0e39bddb513853ec9ac04a8b1bbb719db070b4b25ca658fee7ea380a5453bf7787699e40ada40e51e5e6731274e91a94a8eb2d8b181a8ae2c3105485789953e1deebbe51b2a718b353e60379d096124e71217eb1fce17a3d15a5278daa7de3f737c7c9c63d719db87f705aebf5c8ceb7ddafba0fbb8f020fd7d3bfff5d65877c472788eb9bd86813076dbe0ac33bed6f385dfa1b677224276b8de40755b757d0bbbcc8b7f89c8d003fb294e62ab291cb883f5a32322fb2e538cd329674ed11adf6f9d563b65d67b17dfd189dbb437997de727b51aa83572d7f5f05de9a2dd4cec2a6d9be9922663090211956137ff4fd0d88a19564e826b26bf60a60ce4c0da3d723afb3845cb1e185201b2d1dba8e31e73246947cd5dd6eabef6daa996e9292ca52e334d7e03651ecdc444d9f4a81869fed925fd9669691bc2867e03e8471019852a9c0a0e1de30a33d0d6d8e91fa7aadbbb268b5b702ca00e92f41e3510b17521da7083228000a1f6439fc3cc91827b3a26418090d6b41ce2d1c38ef92d7421a5870996d1263fa678c733a61bc1ba45d5e03bbd828e56c1d048be3e2be8b23163db1e3f972fb7e0df0e885e18c9c25141782be116f4c52b17590d10253b209bb9e1b40cd1b1261e94c9888c5d33d17af8ab20521214860112966c5f0fa9dd19128525fcf1c1acee71319bff5782a481ee50e3a606ffcbdb69818cc58a926d9ad8a97c5152b9f53ce5aed76fcd2375c814029d1554edd62be549e606ff5241b88992d9f226ddab359240b1a54c5f6227f1c764ae681cc03c0aa10e59a90b1f97aa08fe97c6db8c774be02a87211b25b8599027ece19547f6089de27c1652aa6482f71bb6e8bcc010b78588f5fbe67cd2676af18889ace285212233c9e462bd7188ae52c00f98f91da0911c3c562e0aa495192f7f4522643972c6b1c5b9185952cb8c37947f8ee23999b568cb59edb2ec698d15b353093c6f77c319f6729a4b1902c781303ae77f15c4ca06b10c599949ec683e6f512cd1c7edddaf4f0d82a1e39f489f669229cb3d7639ba20534b1322fff78b2e8c8c3bbeb0bc4bbe47bf2484ac4bb648b3cb2446201e6d1befc1585e25df9675c2c0600a15cbc7b47c1d82ea663d62c88eb88a93d6cacd6e6a5268cd6ab5d8fab644ab9112af1a4a80b84e40522621df241017560640eee74e1ea8ba1bd0253ccd7a13a367cd2e2206051f41586d5b26f4f15ebc2d8a06734944dfc53f3b73633260aff82a5d4d3358f00ecc729ec4b0abf9ff537ea64e33b2ccaed08885bdb0bb66cbd0dc762a4d636ef478181117135718a8af32eb8633abfe5c8e0960f0121a3704b58af4da9a61c134a8b2994afefb27460bd0e572e0ef20e0ba8341ac6466b43bdcdf4d548edd9235c6d762707c4d1ef4b13f0b864ecdfac0587c943893dff4127d2e8f53868f67aec353ca6f33df74faf018e652f7802cde2cbbd57f3bca18b186add1b39a0f81eecd5bed15e3cb64aa9a215cb18e72d4d658c2ee95c3ba7b6c9871ba4fc562c1ee4046fb5c9c1f7f056e6ce517dcd8bcb94926774c8321700a98aa26bf107f7cc10ac20c1fbf749e471179d3c24c1018b28c8e0470950e208132305fadc700babf541beb465c3f0d58a5c8220fd8dc1e00b2bfb8261c67320dffd0dd2ea6fb4d543356ef1a2ad6e4df5f0c1035b85884f6d1a8b534b8c370778a3e899e7ec2a3eed7b6ec7d31ca53de53d1579a94f76dd1a384c9edbd76c92589663f05a420e4c02eb6fcc69359ae21b43ba44eb3798b7e0051b43d41c94560e3adaef1539b1351f0858475c63263d8b6f848fa96161ab5333d4b3f8c38f1f71b5657780a9e786d04ecd97cee20f0d101b40372b461700267cf8f123e0b7d74125073c883f9679c0cd36d9ad02ae5fd69c69958c66c7d0b023c76ead57c436b9da1845cb098f19a3768d316ad73546ed361ba30440658adaad3345490cedf5082e2154c1e098609059e990250a88d7697e595c401dfb6c498a7cc4c89c95f054f15eec92e5a4c8ed726334cbc0643fb3f60b4eb078687904a0df66f50b38831a7d99596eb7529e2081de3bcf4e85c0d0835336931c255ab5c52ab56b840f3d10426ec838c5bc9b12b23d91ad2d67b033075155d100399e99837d1123edecdae18867d772b88370bc81a93686ad3fa87baa1165c7b99d1b649cb76e2336465177d71211b7d7101135ba467035140fe53984f853b940f251879ce24a85f3d53c3f2c623b160f3dce83230f64744d02d9485063a4e061744101deb1a65beec23eb488c2438f2a3c3464e1a15cec87f24f6bb16df0a7d8364a221e3a34c28c5b8a740321d3d9b0b45837f0539458ad14b1d7df4fcf62a7471d10e57661f569ab421af123053e1f76f388c21b18f5ccbd3a57f86b36ec28782c3ad0eedf77c19f46efeb33db6644b392d16449e4ad8dae4c2912d4a480f485258397368df259ada24c278250e9b556b7b3b958f5bd9cb32b6701903f318f2233ee78abf6c4fddbce25b367a8b43a7f1d6f78b833cd2960ec6f3b03aed3c8ad18bf1961eda8ac8bbc84f00af5a7ac8d24282a397089ab0b421358275744c9c6c08676820c2ee25527ced349e1b2ae4f7f63c2aafe4687d83c5dcb67cead814b6d443d3ceec1e3ac6ad9796574715ebcdb708dadd3d8b048984bc6599bd017a2d7d379cb538e65b664be2695fa59093a3d8ac10c96d804e7033996392dab7404f513c1060189bd0967735a0ab16e697d4f979e51a9957955944cb755599431bd331420ccc915033b2d8e12e333c01fc4e49f72c6da21ac1a599f64dd4917332fe34115c41533a9cf20740493a69b821394fbad1df0d2ba8f7d8758a24af5b5be1a87a2866c2bf956d306b863579dac4bd79c5173d40350c14137f4bb0173ed9c350285571c1c335ed1d8fc25bae0b9d7b224664a2d4a3b6c46c55a88537b22f085376a17f675be08ce68d68a4154b2ddbc2cae53961cc9261099a1bee6c6e1c8433361d55e0d0130150d221f540b2b7d0cb903469cfb81e383e6e4e43d2e86d7440d714fe7e6adcaa5ac074eab8a8ea6e4dc1ef1b9383934b754e92a47a74c2e7d8ec33c27ada224e732636479de263fbe7ede256f301737263a599afa386a470a55d4004bd899af080c6734e99223242aa311c3943060355c4ca6d0ef5c76d4aeb9e746537f63e2a0e279aeeccc58a0c3046c859729178b65d64af345e0d269c188e6625aeb8b2a41139c110c4423e44b0278297749c8fff01402c46ea27a20d15c8db33529e91011fb87dc52b477242a41888175575ae142a0e9c1565ba075b7b45776b38f1f2dfd551e3cb1d30b3aaa2eeb85eed6dff839bfc88b2b9d5b0bfd72ad91da5f7e2046b825500e076835b4ee7bb514e40097d571aab6dc575b83e79e82905859c914940e194442313410bdeebea3b31bd2b2bbef5a8c069e0374dc775b016fc72c34b7534918fdc3f62a67584ba8ab778575ec274a73d290b30927d4f2974574f2827ff4a4dbb698e87794f2a2271bda0b85fedcc013bc656e0e4d75753a93c6f692981c29eee540dfb38effb747a6d5763aebe238d11b743ad5df941ee3a8f8d53ee3a1d7383668f9615aafad2a157b82a5d17c047861b1f1381da5b2b0302ca2ac4a21c46d03fccb6251f134615f62be5af894bcd59dafb5d2b1dd3fb57367b63bc8bc8da0fc0005a31fbb9eb39ca797acf5a44d4ab68590810d1b4bfe451e534d219cef6100ade0d218aff6c8e68263f2f8d18257c5ccf496d514aaa220aaf4096487c706981198381c92be996fe2914232fd22a0839de253fd538c34bef4526bb52ed8320cc9515f5589124df753e74c91155163344980b9a2999a844dee7154f26eed1a0e0775b21d3d8a0eb11bb6b5ca36b216a8ff4973ffcbde0cf5fc8c26c86defea8382b981063f6ebaa9f95217c532e78caff0e5767212b7ac9b51c10c5dadcf0c419140d4394681ac655d0d580c1e0adb8c539625320acab0337caaaa735ca6c8c648ce67c27286dc9482ae1c7cd5df5df79ab6fe8271d40520595467e406536ac03ef3648729d4caf929b341c7185f4784b6d6cc15fd0df23e83c9b460276d162508fc19528e0c0f17fb765db9d868fa4754b4faa5e789a29f0b3cd730c1e7b6646386365cae2261c5a755efb6adced178ec0234036eb723de6eb23e94623291f5c36218060c96c35075632e699a09fef11e39a6178c80b61f055a998c0d2a29f162c6c81b939d4d8f51cff0547f401c58334eebb9eb0d6139e148105a177b6312294cd38910b1b1a297c17e59231d2b33e232c2c584ca00ccb150d10bc6550a562a281ef032104c598c651832a488574ef11250c96862ea074ac2d601984e06576915a1f9028c02333a975a00b5a60aa00f4b0c15d0600f8062ab779842b86528ad8e7ed2b4f5e07b4d5e749a07db5c0d0bd26a8be523e31c51c745eda224dd6ed7603600d1fcbb4dfff783a800c3bb6d9fd5db826d180ec3b77de6eebb394b7a5fed6cbd44c7e2bd47cfbf83db48283ad1ac3c4a1248d795c3041f07d108a0015a40f25e2284db349f582a93192d2f60ff743fca55bd83b22376134af2a515320d58d24f650286fa31e7f630cf3bb6de8931f2b79d9d1dcb97d44c587da3a59ead332308bb10a04b863a2c3da1a83a80250d39e3c1726f90454676f65da390e5dde5cb0fbe779781759abae2401a98773c446a22efb7462ce7125f1fa13af69d200b176df537b4ebd88d93915cd9e8a1f68a95bd02bc1f505ec5ea371b9641ff88ff9ccf8a458e08609bf253f30629b0a29109bb141c6ba60a9939196052fe4256043a04b7d244e3bc7affb3e085f19e7fabd96ab791c020963c1d160b5df304d7eb059b974c06dfd967e957462f8ee9fc3bacb280b7fef7da8d492feab3a568f0964d525e954be9f3578c5577e9c369178e7b02f79d7cdf6adb16069d3948cce12d132b016ee570413a31ceb225bf48e738e39f4096b517dbbc33fe1690706994e613ac121176f21a889e6231608191346c41744b82f769caf98271d2a27922abaaa3fe4aa6741584bba880ad03cd600769c5e3ed6f484ffcf85627f911904d3615e5aca316d3d4c788067499d71677339037cfa064e336f970d33eed6fa82c09fd8d330bf97e649990e0aa020a6b9d8b7ee7e2af73c14c9f1328ba956f5936a1d6344d128681266d00f1f7392de94c5a11ec27a289fd37161850d86d6b297f0498e28c39f514c26cf8f724071a4b616cf76caf4896ef7e45d395400378fbe4f8bee0ae265d97315f1af7c44082acf92e836c553ef96237f06713ab63b53099bbed540d8ac29a76ad919f58c5499e60dd7456272cf28afc6b9acba321447329d88b5b9533b667f516127ca4f6992099ef79cff893f5f054f576771e5bbd8f80332b19a164c82043c2942dca9457e9e849bfde6fb71ff86fc9b7eec296406c34f10c9616540562da07b57ba0d595d0ced674ba34b25df7a2cb59059d03e9cc25885dc81a20f78509b218d11ae19fefd219dbb354aee8b787d33ccc13289d1a7b8775c924f61415cd10d00b5ab16e5e5cb5da6bf5d42dac21c857629a7bf07f3f1e9701f1025a0ae5add0a351dd3091baa335e54611bdce10b620e826739112a6e4fdcb125d69755816579c955d5b217d2fb892dbd15b5a86cfded8c9db39f32eea56f8484db6ee620f7bb822d721167a2e25c238dc0416815e75b92a4858271613b578341b8cb45fec683a2a5e58d2b4eb6fa35e76b4520e1c6c4ed5f3b31003f81462230e7f5bd0ac550cdf3fed9062f8fe99f6ddfda12c66d1628a633a62c3a2b8e88d87ef796f9815c3dee8f1b7df6e7f451fedec0cbfdddede7dfcf8db878f761e7fb3bbfb70fbf1c324f9e6ebaf7793f1e8abedde9c8e2ee88471eccbcb510f6a0bdb63912a440ca2b507d6f6a2a6552babf0d1d3b66488ec1204e2b949a6f0f1a35d29e9594d8767ba83ef24602aff58fe24176cc99f1ae718f1270e67df6ef12c6cf1cc203dc09042010c0abac8076dfff3fd9a1a48361457b4808315bbd4c530b05cddd3d3f40cd493f7e4ca9faaa767b807e6ef76282ad8359122f78239ac8efb78ebba4396c661fc4f8075d7b0f74b7fe33173cdb6589e1dd223d84afcb68cb01c4e1f2819b1845f9771be4308c79a18bf9527b8253dd43d8fd95dd76516cf499c901d20896c1b4f4df14ab272d3946b5f3b734de3a7df7a1690da544229d79f7b23bd3e0e1c440092783d62732900d9b208d19eac16e9f5deab9a875db854eac3db223746606b0aee5172605db931439b9784cb1e6858dd4f05e50c29970b68c18c717cc45919161bc05da626188fba89691ed9d0043d060bac7b89214364da6980c807e817b5fec1e61295d938fe2135f0645ca62c4fb225e40c058296b0e1623291ca1885f8b2de8d54c7c38c3d0b393ccbed3f3cbb78cb7f1885e0dbccdb326d90e66454d220c0dba2a8048379f4420d6a80993bf38a9539cdb451f3fefda6d7dd8105480de48e9060f56ac1fc900e59590303de69003047e3217134964a79d00123d9cc96aa1e7e22b90e9459a44993e6cb2b199e44be24bc20b42a665d6499f0c024adb6b2d1a0db265f6450a267c92a42f302b4d2da92d9375e19c49767c1d6ede82a9ce43b661ee3a21c31543da8c16e51ced3896d7eec925f99ccc979459526bd2ac8882eb8108fb2a2985bf34a58c546e047c6191921295839d85051a2470cae7d69c9c862aee931516ba050cfd018f0d907b20e91768aaccb73d34c9e75fa671d15a3cb97b6fa1b26ecc83a7e1dd2dff89b157c645057bce92ad3797fa3dd89a58f93dcbd3f2a570c7ed57dd625ff605525c60b32e99743362e4a4640b997e6932fc98cd19ce3d650cbea611ffa29e584a70958e6c10ad2e2324974c93276095bcb3860dc2ce5a3ee7bdeb60601695616799aa4c50c8c8cb0326401d1f1c385acc78a58342aca928daa6c096a404287c5a2528567c9151a35d21ceb182ff882669ed4feb76f1e911e7923d8d3bf7df595a6fdb1cdb38a423ad21ab2065dbd12bfa65986230ccd10b56d5b887def5ebf78bd07fe616089867e4fdc3b09419c7aead833e07190e5707d278ec6621d206c46eb6ea95ca379914209dbc870401348ed5d845308be73602cd2d6aec200763e8c73c17ac9f83948b6f584bc9bb2dc265b9833d3df4246c660ae98aac15a046b4ae773963fc11dfcfaa1f3d91f8b2b06968f392be6192334e3051965349d2118741d41082459004fb1c853c448deedf61d378429e5872ae4dbc83e5116c52737b851718263328ca97f703ce5de3af4f4ac6daa0d5b3194163d45ae12fbba40add1db9c21b2455ebcd06da76051797b0eea936dc33f8adbbee0ace565a07339a3be29dba83bc22fb6bd5efb1eb9dcf26960c8385319f1156f04774c69c8b6dddd36e0bb6f5c7edd5243bcb5457dcbda69c8ba7c67dc62ad23264fade5f7147bed92ee35050db9c4d674638ba3f890da16c19e89e621cdf10ec52a96b956d5684b440ad04a5da39d77a846ed98b08c550c40d5a453a9d53e125b0399305e95c5d2725c735480c0589837ae06908451701d07235ea4c9711d3aa8773e2ed4afb1afee355c49edd7f150d77c1e5f7ef6ef2331d7673b1842f47d4bfb0aa0db0088806b9c927a277147797a5411ced84cf336be2b1f958c87e5b6cd4955a693092b5942aea6b21a3e964c163c4f79c9ca2d7185b605c3ceb483f84c7bb3587a5a71454b0b831dbb6a41b112b3802cb740761a5cd697f059cd069316e52af04326a36a2bb1cef2ebc33e10951aac67982ad1fd6c1a974cc4fdcc7e5bd0ac43d29ccf21cfe6700975f1714314cd94a1344cfa52ca8fbd5ff08a6cc2e5b2091c6887d05c795a8213bcb91dcf91a3e02674a5d7235375ffa3a3509e8e5829c69aa563365a8e3286c79acb6800b57b597ac19043cca4e8040e10c0445aeb804c71cdd49550d6352badd223382a5f23f0d8ee2f5a3fb51f28a84cb8466045f4023dc1c2f6639145edc680e702c2c0081826054f7f6360f5d68e03e08c5915b33b03359d254c47ef3561d5d3aa9879720a5c37ce57cf6c478d8858e734ee48e709802c872864399d3c0956ad2eaa3af2715bebbcdae68a53570919d60d8f30d563ea6365e46a597c8994eba5e743d20a3289c36c5cb4385b195773e9e9f870434236100b0104c8ed7faf432e5defd6d80eba7d4497fde60e9edac1e7a96bd74aeb406e07df6378c314c9b79c54c0f95afca5726431bbd25391484519f3aed3ce58b49cec4060c46e685714ef541261596ad358d203c3223a68e6e05b651c7ab5e325e5849a6c454e0656378badf86adb0e24760443e9884a66f47d51ea26e68acd194bb8e38c0af8b88ed38f1df3b99e8f9023e23bacc2268493a955de936e33ea6f2104a3c39af2aa4c211a1340b344c66f7ed5ddee929f3923e77f97ce90621f8a92edf43720b055fcbe2bf6e4ef1af073c7c5eb9c14a50a41abebdcd2a8e03998b5cf5598996066cef5375aa77148b6e0895fdf0c2826ec85856c72fb54060eca1dacb5c9d21a7e70a630bc8bdc757e94373501bb8e47a10cb2c1b458809a2d1bfc6ebb2e1adffd2aba07ee589620f77de0f9e86b6762d18a06bdfe2f88565c70463655834de0f97c976315a03fa59c6ce26c3735cb8961311604a9d783e7e21baa47e43c7b53b34af81f1c0063174697ad373dd427b9d392a9906da85d5960beba2a081d4d537689bf17f379c1d38a914941330e7ca2a5241aea4431130885d61303b737a8c9aafccb48c9c69ca4795590f3ef1481f8fedc8dd741665545606351572b92a843860cf5d426e43acd73a68c6cb84748ceaa0262a731716447025721d1c6598efc583cef5b09d0e3be74b68c0c1be4bac3c126457bba364647afeded7869f424aeead3ea14a6b40caf14b91273e56e5a8cedd95e51e9f64f2c28965a3429ec0dc0a25d5c160c022f766b3455812a44b3bf4f3c2e2fe65aa8b6de0c2a0876d44ec1b683b0cf73c1720f0652f0eabae138afb56fb64c6e182ff5a2e2edcca424e9b2b25698d1c432ee58e8aec38d2242fe9ec4bfa3b1c45cdd64b8a8546238908c25de52a9bc85404e5befaf3019f5d7188de7b4a58b0a55fa42caea87a9fd7d1a1bf1086dddf370d3a418f8f891d4be5439e7805f0d4835ec177e53bc3784078a87ea784dff4275cecf087db007159bcdb52acba49964a5adc8d4574e0bda9303d91f037923a1bc2b8279ed705e3d92685d350d069bb938178fcdc5a76e5121859dabc260fd905709cbcf70259138aaa473824bd5e44ead51d70597ae175e6afced5dacd0624387d8f2ba134f1855689fb52351b3306c7530ad583ab5ba5ed89b3796ba98747c8ba909259c919b01c29f94f55677b1137786e767ee36b6ab7146066abd9567416f6a6de85e7040ea583c8f1d74eb9859fccabd1a9632bc9024733407e284c56d5cd396e14d3cbec854088cae9a2149ee3bccfe975ea7f94ba58f020f45958f4bd6ac89f092ff8275d382a125ac346888fa1b80b66aec8d2d4117a85a06966e6c673801d1c879e6849dfb1e5c512f2bfb88f99e3b5ed6b360113d27ae8605c5919cf63702a53a8a3b31d38bf746abc1fb1b67b1aa65ae7b28a9f71fddd7b2be4655b986517d77db75a38f37b2cc59a0598db78a38cac1bddb045870746b8076453f64d540c1ad5de87d013f100f40288e023f073b786ea55a0154b14f29545f407e7bc8a6f4322d4a10704d0f2118a0d93713d22f70ef3a673f3abff02e3956b192e96c8eac9a104ecef9f39fcf3db142b0a0a0f067b914618c19c1d6d1f7bd782bebf06a06c0bad64b36deb554b9102d5a42e60b78d5550ff4055738aa0cdd0e05b94edf3172e9b7162fef88b5500c4b7ef1e347e21cf4188b16f34e770fbd0e56b049b33b66bf8b86deb298d7267d1142f6d0498b7052e63fe876bbbdefd1119e64453e61a57187d71232886eb892325a9de5a3ace08e3bbd52a1d87412a762b3775243e3cdd58fa8584758f060a3cc00cac236246cc20f74fddc36ea05b8ccb9c8077733b07736c50edfaa1cfd5091f436851cd0efb42ae94faaaeac4415855e102967f83528eb61de852837b7f249442402a795fa70430cf08aa2211d99cb70013e65f240080a22cf519a9ba467550a91ef91720b810e658db97cfc78c7b9d8dffa4c2551ec2a65aa4eefa7954651a357b508f186d7186c33a1321f0256820f31130dd8726b620d1470a54d7f5ecc9725d0ffd6a84d76b7771e6ecd4bc6e13cfd209ddb3be4281f416c3e7479872e648b72c4c8a848a0ac62968e582eee9e85d4e730727cf44e3d26e36291cbe01a8803242f8f9e1fbe3a3924636917065d51515424494bd00a2e31418cf9525532d60de3511c16c5f107e8f58890d6420fdac98b931fde40e023d239c217c32de0e0a1fc980a9e46fe21eccdaa17ac4c2f59028a831fca6286f1ff812404204c2485654f5e64a09a324ff44d61f1e302021679662d0b54e0a5ef79a88d587ac970447e668cbbaf0804c3ca8c866a4c6d69ec2ead74d338a314b52215c5bd1db1b2a2694e58326190ce11619ae02804d39a97ecd235b3df6d232c4f0803d21593d6da0bf2443edd73ae6b588d6729ba3ef637c4b8fa1be20ca433b17634af3021241afe94db82be5561eeeeeeca05b05c6523f9511d567ca5cb8797955bac83124b0d9eeebb0d4eec958699db1e5373d9ddcdfa41acd6c4f294b05f0e5c97ee939ccef9b4a87ec8a8e73adad45a8d6bc22af5e81968e9e55a288e4ecfb4633f8131e103c53c792e7ece1c3590d81c353ce738f67ad20366461d67cdd1afc7bdd1af6fdff446bffe4c54dafa2113b8638c6058f4f06992104ac66259e45184b416e8c22d73417099f853d0c5391ba5348313d5ede72121ec0e060a8865cafb15019995afa51f77e92fbd2ed7eb698715cab2a646fdf3c5173b16d364d40607c46e62f409b6e0e8ea3d8da2536933031da1affdd87c4e73f4335203d31a5de593b419b0311214b229ce20eb4815d01bab7ee8fdfb0e0c33f01aacf7fa8bce3e2b678fc31e302ab5c58c0dfffef4cd11baed6825ba9061381db3fe86f111e2e40aa21086581900b017e0a13b6d3a068f2b4cefc699dd0fead74ae642d1516917aaa66c49ae4090bc2aca0b92a4e3312b595e654b3264d5156339014f0160377376c54ad2da79dc7df8a04d2e5989f95aa0822695d5502131be603bf479901280a6e54e0b1bf11b1be2cafb4d5c3656ee5a7824b1a2b0de302b4f7f64a09b61ff4d5b5711fde6cfaf4e9efe7038f8d44fd782d934d7e0ea39db8bbaf2fb911dd8ac8576b785f8e4f1ac027aabd5513aaa15e370106e3302e16e6b71a7afd703f2665e8b5bf74cc4f3aaf5ae6f6a0d4a3572689fa3bc91637708b2673470dee52a9f9e4e15f9749e2210c552dc8ac61f04341aff3d219bb52c6cdb6ab707eda24c4f7b539b53f0069362adecbbf933106f92b1091d2d1d0a9e42d5698b88035f6179dca2ee2ebc1fbafd7edeefe79be48119a127dd9a179b64c119274e636b3d9d96c34525e3518a5c880b5c1aa905132d86124c62cf01db6ac2b52764b32f9a6e9207319cdc239b9bed38b05aa4ec5b46b22878bfa7dda1e18311d48ec3b71a06e0367193de4d99e0422f9d4bd8b8aba1d630e992974cf0ab902ed60a12931c2778f5eef95bbea962e1c7c3ee8cf530110ce5cb7cb4a5b1614b7f756b5a14177cd361c0351b826cf3770764e77177176cea764e0ee5315e775414f3f194130aac032dc50a755047f5eb31f00b8201473fb4cbe202c55881d912b41ea682f50ad88b80adc053934e72a86eee3337e998a018cdae535ee1b82c627c175a618c268d2c454407b2dfd8cfbd06eb1508b7dba81a22b562837e8eeccb1d3784569623bbd88e93673fd7ecc66aceba66279a6f756d0cf31873cb0c14d859cd917a4e73b19e5ae2a8a5fa3ead86a94bd52cb2eef13015a9bad703d7974ce0bbb882638969231cbf8ec88a1c342ed87ec3976d180d71386f9408b9862a403f99d1e590a95596f4c9b1d9818c61ee4b76cd468b8a916251c2c32d19f08192fdbed5f1484570a2fd9c2b3d06f85d08a44fd244f5aea6c56232ed5abd5f83aca3315e4685ffb6484bfcb64212a8bd608601c06d38bf5a4e61344f3246864535452d1c16ba1c5121cc416809448c58f54984a486a55bfa1bee426dd89930950c273a0aeaf0a87b6d466ec595827b547f436c822c64d1df905537bc21231fe00facbf51a31b8a0f67c2aa2dbdea3802291353f0575f86ab7552786bc0aee7593a4a2bd2a4c3521a9b8455ac9c89d3a76cad1a3628323d4d5603489b496c6a6b3389ce06595e36e141b17d0bcc19b10e871e6a901ed3b2a2788a056dc8956a2920d03fb1a5297ea28d123aa0039c93f45f251bab5a1837da32a752170bdedb73fc6a70fa320e5faa7fcce54b03508d5a7eda5e3fcfccbe49ea1f730653708c93d3da25117c5f300dcadd2c67786a77068e7af28372f51e15f325e64355f31af8668948e502b9c98e63995944e55a16772b5bed52a67047e242b7c8a5a79bcc71a190c48b8a24ee6727ac02089a8ad47cdf6be7fbabca70045832f4cc07a4d10115e604e985ac49ad2fd3cb72f4c8a549428aab7c251cb92baaabb746961b9e5da5c84d3d7ee3acd359b041758c66d392ddc2a8e2054259f6a63027a356cdeace411a71b178c7828cb90248caa1ae039d4c2033f325f3b23ed8c9cbcc10bae334ab58d902fbee894efa6ea732b33b9a7135776c47dcf7ffa54ffe1e79872632820c22860349449b522e43508d6305c66ec2533155d95296fac2c6565131813174021c4341689611e31ad0de8f6f455729e26564174c486ae2db41b58b3097be82e8ae06d4b720f7ef1b5c40bbbd8a967d6399c69bd7eb8db34832e7bd180d66bbaf5fb392cd333afa5c8b76e39d3edfca250f58db75bd53d310f75fcbbb5fd43bdfeb14d675fdba63068c45c96e0d0b2c1fc03d2661f9284396c66531eb90aab0f3ee8a675606857e1ed648c126968414419636a90a55f744b43fb5ab18bba6ce18aa7db056fd9ecf6220dcfbf7613c186bd180f5e04663394f5d801019ba4e6993947badeb9b230cf79589215ee7da55d22bd95d2ef217d8a6e4aff3483e8b9a8c7626cc547dd9a93e0ace76fec705d9040b96a04655213357cb945c1c63f62dd72d29adf00a6516acc468c98afd1a9f1a7754110f5071fc7e62cbd7a5aa24d9760dd3c5dc64bc0eda7a1199e409aece69d0f08cec85bd9de41bf0a5a0feb47eea559ef6dc9222113c167d5c917836d819d896aba2bc80ace10a28277c319a425ca0c211b9de982540e56ce11d8815291739d4a5ec7a64ccc8bac5bce5955fdc0f774c9506708fa03f6427849b95d532b6a361786bbcb56fa28cb6eacee8dcf623ce432eb27690e3dc8ff3099c8af549b055730dcef0b7d950b414a32bae97158377232184169e05cba0c8993a00ae4f5f5df3089e7ec29464c92f48e52e445c41597475161daf2668af5365a5eb04150aa6d869db334ce715c39476e522272d3992a4ade2d40055edb48b46f944f9538ceb3c96d925c801b92777d8a0b8b6e1228ba1cb2a9b33f0f1a372f7f60e064e009e6169ea384603e75a5d317ae12500f39c062c8a2f5615f47545ce54746a2c4a239ca3eb4a6f0529d479ebd7de3ad6f6e884084c531f825952d2b11db24c492ec883095cbe131aaf45011ce60016c53aa8213a1b6c568a322e4f9f8ccc53c57d102d01209f2fd70505a53f6a21c9b92f045119666c30c44ad0a86f0983f5da3af3056b49ce0669fb89e8b5c804635c034b7a3743f05cae1398e95407f8c8904bb9c05ee6d4226f218d445650cc4087ad0e8e5f3ffbd7e0c5e12fef5ebf7e7932f8c7cbd7cf9ebe1cfcf8faf54f32a8d9afebe1febda7dd631b21b5db1296ca706d3140b0d4070a45f87cb927fe539941aeab929aeab90425d6e1622278c53de72ffbeadbb781cb0c840609ed4c577bdedf7e567b378dd65edd8ba66e6c753f2f11fe9effa06fc501352eb48c783856d36ee905c09ae5dad3905d8315e703b1e2da8ce331e542d851cf259a75ac5a4a2672d75bbedaa23194d7ae4e6da78ebf0e9d48567ca38853e56e3be1fd26166fa3b3813e9b64c0ae2b96ab627dfd8dbf0fe99065bd729157e98cf5a6502b85f7189ff5644b9022546f44e25fd36a5a2c2a531def655170b606c8a6eef677e036c1824e0074131e4016924dd30ab11b1b005db1de7d10cbf5ac282a5e9574fea664e3f49adcc8c6dddebb299b31b5789b92ccbc38fce5e8f9e1e0e4e8ff1d9e884b71f33adbec90cd6c22fe9f25e27f3e13ff5ff3cd33d9e739d4b141672c2b981c6d79688e90862a2b0917e96f50dedf50892781ef86ec728b51858f90fe0adca015944e84bad3bc5a662cd9b20c62568276b44c0fd59483bf65d591878fbe7de4a894a1ce3816d151a463c8e58261b85057fd6d4ac5a8fd512df403dd443cfe8272d5801adb941d23a35b1d1c1050766c93276433492f37057dc5971d9bd107804d68242774dadf50a396717c6a84f8a7587fade4907ec138e3106f5a7afe647354649b26e887cf69ae6b8e499e0d9dc9cd431bab2252e3b0bc7853a47915088bbf80f9ec408681a8662a6b132635ac79a986d621c578cc05cf04d5090329113f71cff8865b9c8dfcfcc101d9c4e5def49320e8565f886fc991c283ae78a04535f936686f6f396455dbf3db6810380de713f8c8b42831bccd6a509a6c157e32187fc0be5518739e233ea8c5454bf735df044e000b72eb777b6473d3ca8c01f0ef29591bb004b96a3d7398b00024237100f91ec88feed53c7fa03f2ce0b4ad0fe2f4f5175544037cb3bf016f650571170ebc7100e14ad74282d77150f02a16dd8af3575a65cdede845c159a26c31cf689ae3310b2d714866ddd8382b2a4edd6dad0f37da84a4399fb16077c68a5951c460cfba6a643a02c4c90e39d56f74d16d187347ad49bb8d53d58178cf8bcc8bc1db7c5e64022f24cba1c8fff322dbdfe86cfcc5239324151931cebb2cbfecbe7afde27070f8ea173c28f3b248168e53882e0477c4215c19e48dd6a6aa3ab7a970a6d723cf96da209d2da5871e146edb824273e764297307157388cf85a43d42b049d825cb8af90c42826ddb74af07454db41fd7ffc7defbf737912309e36f4564396c83dd4e981fbb8f3381650233c30d013e241ccf5d9c4b64b76cf7a4ddedeb6e277849beaffdfb5155492aa9db4e02ccdeee3ec31fc4ad1f25a9542a954aa52a07ac97643ddd59d3453825bdc99e03129e8df5f0bc77f6b93eb64438a3de40a2fe4402daf4c6a4e547b8315545d9eab469dc515212dd769bda014a62acea4b30e1f0ff3988b8ed28f518926c7a384be67a982463ff0b8b9b5d942cf7659a8ee4f8dc8a94a1fcf96ca4058871f55a5ebcacd4dc0a9e41ba27b1cee539ba2df855ad98ac7aa852358613325d8a7ca1981b38ef306b33915985efbf8049e28b7f1e23304e4af0f34b6978a6d6005f2565f573912f1730d20669f80ba54df2db692449f8b299a65726db7cdf4556a5d19b02f4e9b59f67bcfddc3dbf6f1471959945ca32dfeed17eb69f26f0f81af2e9f3eb48ba8820fc6db0d12803d3385dad3c73c2b1fe6bba8d5fd4492637b399db2c35a74959f5a69a447a89a67a2741a3ad9641065b598c68a01bdeb59b19160f997381aef1e1ef732471e6dc13b3cb2a5fbca55bd224cf6a7e529b3c1bd2b03b66cea83b28e774c5b1253853e0a4feb03f90590226c025175f5ca1367c59c6cccac063186d4b63583c9ac12aebf7852ad324ab7ad4cf5ea63e56bd34c9486b443427cb8126e5ab2bd126727fcae0e84399d447b2d668595579063ff529ad43d569e8033e9f9b64adb65b84c2d1092df4070f440b7fb6ba6e7deb54f3d1eada35fbe0812343278c9a256cd66ead9421f75086f37859e8e7887fd6cbfa929f97d920037af9bbffc23be69a0dd2d8bc602e7d853bdbfb6c9c67559183f9a7d9d6963651d3c2176c86f5adba699b6625fd8dce94adcdf4ed37d9595e247fcbb34aa6037a6b51db5337efa7c419fc0df534c4dc5e88cbb6cf5170b1014b69e519ca1b78fcea346fa301b8862d956fea61e9da06cff6dfb06cb8173b8c359576b94e0f1594219d5458936dde8d05d62ba9ea057944654a7d7bbb0d3d80059b7bb069fb7bbdb785bbd137e8b83e63afe6dbb405fd1fd8223bdfbb3cbb1dd78a8b3d6fe69c02a4e5925ba0f770dfc8c9dd7783f7aaa6764287436b8fa8e0168dce4870bf434ca87d8f0d49ef1c963ce1a943ba2c67ad4e57b4ce287d6fb80589c32d743275e66a873ea33c57b451ab230644507790186e941602aa73ab1cb6f8bbefcab7dc69eb73d15ca1566eed167cdbed77edd6dbf24ad1e9c4df78d7efcbff0feec95feb3499e53f2fab4a1565eda8f82ebffc8c0d8df12e94496b3b886dd116b1296e27800ce4ff5866dda5842bd8c8f14d76e3de48e6ddb50d11c229de6e1b201cd40e767648fe298d6d10de8d06d92ea8f8c7dbb2fe22bf6cdd78786954b836322237641707e326b653eb7497cdad3e0264796f8a9fad9071bccb2f4356f02ebf6c999c8dcc24e002eff2cb3fd6ffd7d126b9c5bf2f8bf8e57cfac77de967e8a0bee43a35994f7fefeb545f95f4b977abb2887bbab35f83076d94730cb29fba1bb6409e012b5bec97add7e1ea1876ed83645dbbfac1e4162f7117164495fe95d91029d30fd43c5fab48ffcc433dd28beeadddfd4c957a16ab1727173a67df2e58532bcc6075f44c916ade1667694149cd017929a2113040492e0e81653d2b7ff94e1348d066bb35fbaed56928fc7d73e1ef6d61ddd08f79bc127b0d9869e3ca1be5f1ca566862ebba404da2d3907f079dff2d38e6686a6b4f6d224c0225ebdfaeb4b110c01af0c532e395cb8a9d9e3e70bf5bf7befb0f6ee6329ae25f7a3da853c818007fc7a4db772f85be948133a5c198ad8b3db3d0dbebfd83bbf88cb2887f5132568521d181c7a8679037dc226dbd55c563999bf5ef6c7146ce82cedadfc04341d67902ff65c2f0e26e72b0d97c46532df5ea89248b936917691c52f52f4c075a37448e35e037d5423b0f52e921b93f5d8b1acd284c5c12fb4e550cdc6f6feb6bdaf75a366fe38e0745502234bb1d251e2555aa3631ab4a1768113eed2c0c7c16ca7b79b81c5537012da9cc0d70bfe77089ab1abc99e4574976bea9a934c9ce1b9a69c916077e844b673d16f4f6d20065e141c1a5b4090e2ea896adf1539e579b6b4ca084abf1723e7d73a18a546edc6292f9b4976331a8da20f26879070228ffb25acc80f1f67beda8d39fd68bbb877d72aed2e46faa8d66f7be4538a645f88a52b5092e8fb873aac9bca879219f155195bf5f2c54b12f6d10648cd1f7af299319345299389ff74c6326eb773a48a228b190e558a61ad9dcd2dfa5eae9adcdedf1f6893f4de291470f9da84c93b16aefb857006bc9a84eb6860d63101376c552a889dea2316e0fdfd53f5dc3cb00355ff83282cf258da98249e2e60c4131bf266f8a61864ce88c34d104193242a124721bd85ab965df73f6df2cbed4c1049c1f07ecb37f83cc1f4bde66a36e60dd1d36be2761464cc3cc0b9254a8c9632e7b321b5d86e2c70dd2a50865d4c775211591fad8c97f8fb90028c4913422eae39af4e7863cb02558d5db0b818f6fbe25f2e4394441a1ca3cbd50f1ed3483c642d363904de2c3919cd625a1daa1fc16f28fdfbf0e497afcec6ddf3c32f2b941de08ca7a4b8d7d71f1915520c6bf8e7b58572c3835e572b48f51aacaa5e64d2c0691c98ab8af5f7abe8ee86cbb3aae103dd1ab55e6bec2c59e2de09766e11a59876848760c49f96c54e6e9b252ed85ac66998be760deaf516a349ec9e259d5dec6d74dad7e6bd7b9878608ab6227faeea398c8b2c2a887685f5a5de63d594c8dd724914f043ca0fd53b9002edd61aa364c7a93a9769a9455572459ac3e5277ecc3fc04026dc4ea635768792b118fc44e5768b1415722a3e35d712e7e10d9aeceded3f9e7f0d7f2045df43839a14ac7e75ea46780b3a027c66688607f6b43c448421e3d859d29799140e47688ffdf2ac5b248a3852cf4b999f98c010a7f4b186d577997fb17482602bc14007e99d77c4c437373c340abfcad4433cd7695831d7f1e69ec55ed56bfd5e988ab2bfe424143b0e501dc830790d858c7d44acaa3fcd9084c61a109462a55eece7c49f95391cfb1a081cd8ac200dd13b56559bdc8622c6d1ab8ba72407818908656b96b802ad71320291793f9480947350fb2981c5aa75b80854a25d81b8ab8c831d2e7244955665fddd9362c8d842dbb1264464e6dd65f6cbb92a63bb4ec707dd9cb78591e153249936c7a98ca72b6cbe9a57138ba562acb8af7e6382c2d7a62c7bc20099bd04b03eaebc51eb5f424b1ef30a1d574555f87089aa4309c1a58bce07db8b7c8c3deeac5fc44971449afe73f9e91853fd0e4c47ff902f938101e4fdeb21b5bb32b928eff8224a87f0700422c178f1ed5a12d177702d1eb0571a52cf1b8c544de6e76b1b8d02d38ec2db372964caa36747e37f4e9ce56a471d1eef0b88d6e6f5ace7d3b23599d7b7525ee058bdde4e163894eb8666c6f5a5cdd84d1b8bc49ff2d4f32e04cdcf02424a9070fa86a542e476555b47b3b1dec72bfd531501fedb1e544eb0bb38207a266870f18353ea7e43e5c96eacda49d8f7ef3b7ca7cf45b4499e229ff6a6b319db67bb78953267a41d3c06aae2aa00486d7975d3172a14e8e54499138aa22195742e93249b51293a4282beb115402d18e2c53b1b109d00f633553c56552aaae2e4c5e0fd0b7bdde83f0891838af9785420f91ba190fba71622d46c23a1a31817669ad0f9ba3c3d75c6558df967ec151c7d29e10d2302e1897f9e0f9ea42152bab716c27606ccbe508239e429b0cc15872740c654f785c5dfcb5ceb585f45eccb1604ea3e6a7749adaa579e967e84376d83bbe51983bea78dc4c9a477c7b4202eaddb79b6a4e3a90dfa5720e1695e49ec2e8b72ccb649ac1a32aa0bb4e8856e7b7a8199912dc166974829fac468f25019934ad430771c38be6d6cd0a18a6a70896b6d566406acf08bbac82eb039585841e2c85b5c6ad5592ad7a750bd72433778dac984d6cf90e95641cbf523236ac0ec4f3ba685e17cb414d50cdc4003e1ec107e2d7c9d955912cbe04b8e1b63b9ab135343093e58fb204990940dbf364bd892a7f955f1a4d4e04abefcd84b41b7e2676621b6c42fa4fffd472855957a9224943b817f4769ac67f8b0eae1f868f06bfd16694409bdee67503d2e1b793d3ea5300c7a7edaee8ad9b05387f684ae72da1bc44d4bf87a47275451b243d2456b218cf8415eb48026d4879a96780a0c021d14c49eb4fe1be4d65713e3a4c469cf1fa84505bdeb08ea0c7bcec765704c5996c894359dfcda75e3779e9a0a3162761f3acceed3a5babe0f3c34f3e8c81fdd5e51d19d80e69a278aa89a2d51226b5eb903b2014eb627fb2c574da90dc6c708a415d04908c89f5d84c3626370a7ac710658b787db2536eb367e63c639a6068e394e92608629ae1af7b38fc0e567cb447e921e30204519581186e3dc527d590b0cb89548386bff710610eb04e0dc10242a1b806fa27347635c3614bba1ef10cf0fc8a5040bca54407c518787359142aab5ed527c1e0ad215ea624c1a88517202d7eb63d2235cc242fe603818fb05dab24e318d830031eefd8f50b588fbc2e949a7ff6d3e265a6c2162d4dd59af31f72b316f5f86ac4166a481a0a3875490003273d708717e4b279b60416141148558fc2f435ee071a6ab79a9e9e79ab625d270352b4a4ea1510489f8f1a16da86eef96c3ee85c531cc1070f6a44b1666e1a4886dc2cba787e4d1319ab711eabf7ef5ed6e9c038f91a834fc7b6f25e0c2aee07effdbb97e0d6a7315a81c96cb7ac5838dcf25067bbf308bcb88eb9853ff62f8e2084490bd584a548937395ae04b86b0717873203f10f02b2aa62acb2aaa7b271ae45b0a8d559332fd847b546010052b8ede3b909bbcb3843331ba1881720f28a0482dca5aa527da3f972ecd7a654b96149ae4187ea7bf59969a02d36a741bf6c565d5952ab1d127ebf75435ba1d6b5be75aded8eef623264701f660a54dc85a210d38b22c91d83869721b61f4929d47c51adbae0b33401cf6dfd2fc0a0d9157daaa03d87ed117c7737c9e5b3a2ae5530f1037c263b729f0f1e081931a96314b9dd584656ca1845661f959189013d825ff0aec61d1123daef46ce6b7bd3267954c8ac4c74c281cce4d4f95c27af39f3057b0234e4778125b89d9f2f2ae3397bbea878d8993bbe11326ded919d4ceb9998252538cda03031e49436cf94e998ac848468d1e1c31fc1ba6e3be75fb635584d593f3ed8115eb753c38508831b30afc8d92429e60eb34779db85f6a6d7ee62aaaaf7a52af6b130658ee9adb6275a80abe197132133b0ff179505ac99bdc6cbe52c4995b8542d88a30b2127116c924d2d1c0acc7191e44b8d49d515970a428eaa2c16cb85483221c5a54a8a18f79048fc046e060586755216d04895fa40be629141c029bd5b6e84ab7b35dfb89e2ed2f94632f866f12c9f527a0d731d74d78bf3c9e78dc019f04d825a50b4610ad605efc17f0d15dad81e9bba5d5723dc6f3e6f65a0c308be2032a5e252c8c601b8abc78c7c385539044c9206d373559672dab066f09f1948bb2a96ca1b8dd5d9d586051b9ed337a1fe45724a9de5f9396c735a6248f1ead2e6460e926d9de651630660d61cae87bd68ecf77570604d93b252193e6bb2b7714e27b458a82c7e4565b8e760bc897b66fc66304d2fab6e80871cc554ec884916f84492c57439575955d6e228d99ea24b27f3d9b90d17731d7537421e4cba9845f814b4c0814a2a356f52e7ea749810539769713772c42caf92c9cae0b56cb358917421759a82659a450769660041183afa1215d76d5db2d315a7288f6defe2af1f00027e3c7ac43aafeb1f9f92f7780b1e53d6a3bcee55cee2bfa6973539f5992d376a66ade683b69881fb693d80d636924153a2f138e151ef20f8a642c1540cc204a6b6401bb2b1ccde97eaf99b0370906c58e76592c5f9258a88f634d2d23208e644713e06543724f9162e1a355ed815ce5c8955d53646bbd6093421c594efa0ebb3c0c609cc9bb2bc275355543042e32f0c7957894fa8c967f52f4707afbeb31cf7d9db975ac62449441f478ee4b9c2f805e2208f5591257f2b9c3b3113e3903d8fb2a5d8af519a8ffa7330e9e893f7b0cfad3e51b25a16aa17ab4a8dabb24f3d8f7e2b012245c280401640a2c8a833358513080607ff00d82cc5db599ea972d0d40d300ffbada4c75d45bed46dd3cbaeeffef2bdf565e6c44412de7ec1fe70f17229c59e218e4c5e245359e545b42c55f16caa28122138185e4aa7527c96c585eeffe3a865d4cfe2ea4a3415f936dab66520e4082f74908fb4d0742827b2481ca8a0d4feacc841bcdc6bccf610664bd5eee8ec9aa7c11aaa7af040b434778730282dbd63fb05763752e9a8c82f4b55880978995ee40b5401e0fdc08c661c4852bc7cb1b30d07a6972f767628de5fb47eaedee60be8d29bec1759ce301046db3fc8ac9f36879da32289555659bc340f07093199902fb669dece3af8da108661700547fd129cc4439889291c9f73196f18c7cf3999f9bd8392ef75037a449f31969f92424df28f378cc54c8d14d3e442656e52c09710d8d364e8873a535a0cffa046bf2615f9520248cfc6e37c9955a58d2337013fe4335909a4453dbfc99b439af542c9346885d63b86c2d51875da242c05313f20c4093cf49c29018ed7d01151033693f285edf15b6a0a9c24797ea48cbb70720b5553556962df88e1fd22797318e09722b9113942a3fa706e066c9e79392ab54534ede00a08eefda6aa225604300d29302d59e35aa5215d5d9928690d6ab17e5fbc7c21767620608a3e9696a8612a11e5125c126a9c3781b6200e956a62bc601c7a54e09c1aeede5f2cd3b4fff82fffc7ebf9a76be600dffac4844d572f20b3a2f0ea1c690bd6d69a6d2f1ba7cb184f920f8565575d0aa3a4e84b731738627ac4e8c8a9a679f811d997d917162c769471a7cb2d7cb96a6151ba68752454dd7372cad33b9cb1ecedb03d6551b76a67ade76f0ee0c414d4080e519a1aa7693e92298dcbed708ea79bc75cbac3ae586da3b425a10b8ec68daca605b2cd1cdb423835485b78414dc9f1c2242fc6ea9d9a140ab4d3981af1545ba3b16800801b6523731f34150c7be11f665d3f9a1425a66ae3097e1d40deaf40d0743df42b857d3c57ab57642163ba67936cd97a215e8ff7e27bd7ae2d61e76c4457e3ce47874978da74db5db367f0ea743ac6a3b277309baaeaf99b037b5136638cd10f6189af33783eb24266607feebc339e33c78c42989b09c832d7130c36ae8ffbecba8a568c55fd38584c451bd6abdf95b2dbd25ae1e0d6d4de9bd60ab26b9da61b5473cdc9af263fcb45929dddabab06c3083b8f5dd1fa4f72502bab4acdd149ad55f158287926244a4997b3bc54e2fdbb57d8771b7c7ba4a64986b72a206da12080d523f1e2e3428d2b852a76baafc1bb5ab8a201f7105310586db66d1b8ad49c31215bb70331986c3216b1857c65c70dd7ba9d666d2c54fa55ad6aaf630f64358b0a99c5f9bcdd89aafc10b485ed6fbeef187382c75db7986bb60f55a839b7eff41a74ea0dca73143f32f5b1f2d79bbdaba5d5d615ae8c5d38467430f67afea6632c7ab16cada351a88fb1d0acaed5a490ceb511b3a8fb353b4fe05454cb42185d9d89bb81a0aa0f3c280133ddf14dd266c7f72c6a3bd10e781913443b9bfa5f3fe16c005a131e3b35b2802deeb5fa58bd85f074dc4cb38eb9d00c84acce1908a66f5a03d9703a22a875779d601869fceeb6debe79dbb275eb04f20557184e65969fd714ef4112ebb6976a3c040f44e01b18ff999e0cec2f9e7f7d9306be5017aaa83cec376ab99b74c8ecb189013229f279ed06181f91bc725b5ab8c476ddd5ce074537de8b221fc951ba0237b414fe5cafa042a5891ca54a8c5676719d2bb5d09c5f82fe51e413cda94a71a95a174a944a81febfd4e78d3c3bacf2424e4db872bd32b3b25232861b2088926e2c42ab5c6cc3c993808938cf5a9538cff2cb88efd9556e6cbe649afeaa56a53dc6b9414796259bf726548774240ec636db5f3536d7c1e6980ea1b37a049f43e22dc42aad24bc5fc1dc9e2be999b440b9f5cbcffaafd7ffa639155f73ed90644995c894d1c38d8cc5ca818405b1278e03301128b1f584be5d8ed2642c92ac52c5448e55e31ef84ba1267586439b21dbbc9bacd41a1968cdcce9f36f7fefd5adac8cc9f783076490d96c1ed3906c8424721589fa4e0ca98c4be671667421e6464053be1e0e9ed4b528b45356281cd922893e061a8cf4d2e45c7947688ac407718751ca1509544a601f8cebf250c092df1ffed262394c1ede24f830f9a65be3329db522c0d7e7f06067a153bcfd998c59f1fcd044875e393c43709b1b8ff59b93846ff414dc037be76a6fbbf16524abc9f0f71e087fded8f04030458dc0d7b368ab009ec15937d8364e87dd60db0b0e3811e147ffb961f322e73117eb786448019c4f3a085aa224a66200587b6707fd91d8f1ab9a6a91676e586fc2b12c5363f7efbae90fd75e54df9d3335a8321bb444639941c070cd42b0469219057d89fc01b5ee46cde32bda9aefe26f4325e632bc99431b1f1dff3a4c9a46f4bfc8a7dfbd78fbead9fe8b3f58f5df8f55734df33f00b736abca00b22dfc2efc1a95e10682b9cd2438c736e724988dff4738aee107bf1bd36d9eeccd6c17ef3009093e2943d69a4a3fcaf1b953424cf3766f675dd19fd09b8b577aa7a68b30a629fb10b7148f41fec160a6c6e7fa1c625541fea9c707f0680f0f4fbee5bfdfc6de9e805b723a65ed71af1016b9328e41a5632dadbc1bbe6ea0597258d7edadb90ce9ac851d5c0e766b7a9f8617e9f5416dd74751a8797ea17eb7813481bffd58c20368f9639a8fcf217445a34a6aa4b3c970d3534631f3cce0228e19d9725d9417f371990160382f87fb9a3320a6663dbaba67bbcc1aacd32b9350f918d9e9fc3a7890bbd6f0b7a941d188399357ef4e6fc7e311e627354dd8686fb69643e2ab5b9c213e31b911a181f9626832b801799b50b37990a643cd630281c2de701aa602cae941a3cada98b2d1be047a4a4a73db51a00631d672566219b0df94a905737c25d5352306b63e303fba868d0ec434b71f9a230fe8af4d24de3b703f290b2677807fba9c810ee8efd0c613372f60b99d4fa32dc3fd9dba358329f65656b3fd3c467b4e40ae2e3792d9d40639873730a0cb19b8d97589fce52aa383a6c7c9f7f8cbe77bf0f479cd3b67430884027cc01374c1257e4e179ade473bae07ed667999c2fbcc0644d4faddd0d3e03ad5015e0f36a8724ba0c6879eff9219ac949645caace5f883e06591866f81f9abea19d7848aa7bab81840257bcaf7def45ed72c6488badace27c607a545ae16988ad44fa660a9a50a25460a0cb54452b5e09a916a8ff3ac84255009392ef2b274725a4f906d95b84cd2540bcb3dc49948aa7b76f0782a693a1137be98d61977c1103edb850b6a202d2d87ba62a408f1d1a49989c51323e246dcec353f5425e6731b30460e75e4d1848c8e3e09ffc95cd6ae7bf4a3abffa3d9ddfcc28dfd7e4fa39bc0289059deac3717bca521cd3f83098b26c723f49047bd3329de1372af08abe439ac045ec822b89862bfb70d0bcd85bf0762eb622fd81a8f4da74e5c3051cbb4f5089ba044ae08f3bf79632d57e406439bc0bd1680645ba2c7813b7fd894fc7d6d4afeb0f4b8d99c814e95a031a525d1f446b4f624f6fefd1dfe2af66bbf8bbda39d075b7dde9263aa5d6404318d31949c033778153ab660759860dbef8b1759b92c94b85442a69772558a99bca087790b55a4ab1ed5446f184e22f685040e7e83b147baf6b2d957e42e0a75b1c950811f91ef79e4c09c137813cc21766d1167b9a351f14cb8330df00f2d5a1256f69c26d3bd62f04eea8ceef6f61a2facbdc6c812092c2a10e02e4e02de0498252a1294eafa8471de6a03a59bcdb266cbb3c96ee40fd31ff3ef0fd39faf66faa339cfd7b3fd31d06e65fca3974419a5b2ac5ed2698bad468786ce175b026d6cc89b887f74b320b61368f908b6b0a434bb86dd0cc4484d3409c4394c76b6aa66fa8726ea081f54dcb081dd6afbdab475ddb8f1dccab4c9b3648259147be2984d5e00a1f3c5264de6e481dee2edb3d3ff59aa6285b198f3a2ddd2255a7cab271d43e0d9c8007af0c0c0d4c7b967555524a365a5da2d5dadd5611441706e38a8afd14e4365738667f375837dd6ef6ea0d57c29f78bff422fb081f89d0da05847d8cf7fd47b755aa66b8debc44d0227a300ae6675baaf7d7ae21bf082705d0777f0ac662770e9802a3f3da7954a537cd7c8a4b64b5972074c42cf5f5794b9de88620f5021c1718995b3405328b39828c3b24112f6c4d14cb77ca16405453d5809ddeca22f14f644345160500e6fd0e08c4a7e50ca245685a64429debe79cb5c4d78321dd3220bba2fd824708be6abfd8d9b548d324360e06e8618a40576b35d96ad16d9f5ceb319d7b5255976b318b64108db24823101ec6b580234ea06892435b5c164977a4dc0f409097e225456152b9c7ef22126e3189fbe03a119af42951c9f37db00d424eabfaf9dd5ed79ad67fdf0fbdb31fdc171ffb1382e4de1bf0ad3bd85a2c3bb555fcb80933b31dfb5065600ccb7b0f27adcc43ad732cef56cf3bad94d4cb335d1ddb949fdca236426d8c05a070b38c189bdb2ab33963f4c9c6e3671aaddebffbe864877696ef887add01fb6427fd80afd73d90a390697caf9a20d8af64b55fc982f332d9e2d16f4db77cf026f9ee749d6c61ff2a35fb1e3d5dcbd8303119da24a771fa0378db99aebd95aef02e4000a7c254b840dd7f39beed8375eced3bd3611d18bac0281c756f5d36dad35c56b60f85dfa71abdf3a7137e96b20fbb946eef17b03a9615ffca20100de8fed5a1f7c78ff0b8e30feb1ae5f4d82c2a9f9fb3cb5ffdd9c18244417c844bc1917dbdd809279b80ca66136541e149ecb05f39f0887f2b0f3f49c080fecdc63ab781a1e40a18c77ec64388158da37958714f0947c75e555469c7436689dc172c86e13de9932a4b73fdec4fef126f696ea097672357d4ce8bac995d22cc9c657e11ac05a29b7dd842c8a54889d400fc12a9995fdc4b5e709b6bc280516b505bba201504fb0fcbadaa5ae1ce430fc60164d32f2179ebc5926607cc07aebb2087d03deb7db9ed9ff7878f9c7c3cb3bf08360c51e7bfc80bfecfb5fd53d85fc088506afafe291c840726816939ce8b0c12a2598d81037b607277fe7890b2c58bec2c589971d72a2e1ed6e55fa7d7190cc9331da5aaa99bc48728833f9fccd0153d21afb11aa3296e86d558a4265b12a849c54fa7ff2cf9eaa38d0dbdef94ae42bebfa9c282cb39f3711658d1c7db5852bfa8482ddb9941f3609f7613f7e0725980d237a1bedd7ed75416bc16ed401dd462be3a3e956fa18b38a91b35136917ec23660bbf92aef08fcbfafb801fa1be09fafa5cba1b89c9f1a3da376eb8f36ba4dfa936eb00576ebc6995d1777accbce30d03717ff133ccddac89d725c9937673fe5c57c3fcf2af551933014235fee948aac709c675591a72fe381133a8619b08920002903b8bbd5dd42e5f35b2b03a11ea72e2b8100e44425d33d0c13a93793972e10a84c5215b7b88f79f796649c677182a8328ee3f942b6d90db110b8eadc68845dc7bd0a2e101646c1a218973e84e642e291186e0d0404be33beed21665fabd35913d3d58e0ea7b4b52c154531d648e83f1c66fbf9625524d35925dae38e78bcbdf34d57fca79ce5f93df1321b47e2599a0ac82f45a14a555ca838d2b56225b4e09f952a867945f7d43f1e3e17af307930cc6655b518f4fbab659226a342162b705d4cd5fac30cf580103932f91b9c558e71fcad1f57952a5b5dd13aff51ff7f00ffff0cff1fc1ff6fe1ff173fb68619c6ed00bde4db4255d54a2c8a24ab8404a848b9230d6f98fd75aeaa59aee55b5d6e98fd75210b39179f5e2fe723555c6385a399121924c091978174157eccf354c9ec5a1c6779b99063b5072cfc443c072349db8105280deab5f2ccd67893a5a6c779a6c478260b39ae5451efdd3170ad726fe7446092ded763354ee632159887a2b926c9a055e8ea72ae1b3b31c159207e929eb5719e5da8a252b119b7cc30e01ae003953066b6e679bc4c55847406e1f7ad88a44b770521a48b4185b05b5d416d7b2b8a4e3154a13980b3d9d3f305344665b9b98ba90d45a27a018d54cacc339e4118a33cfababa62676961ba6da1e3e71ac36a06b20ecdbbdb9aaf34ae5cc8181b883fc62026492c7ec03561a3f13f7a94c435ac2cb344f35e28799cc42735372679a6023b6b612ae93fce9c6827b07cf6dbd14302d5e222bf6cef6c3ffeb62b9238b4579a241f55bcebb70f04f4644f94b55e4069b12748438925fba2ec4455fe93ce6b230e3bbefb13b2e3d505dc834e08eca0c907d3ede1e271ad55de321676817d1f872d5dfb9f3869a6a2e6c186f6e8c1684bb43ae21120b66e466e71daef8bbfa9826265f1885cf4dc0158015c98fc884ccb0cfa1e76a04604a734a17ab2c5532286ed133eb7626093f920ed885adbadf5e3396503f22254866bda03891c2a0209e3a73497559bbabf46ccb54bc2973e3e89771054a42b4e4ff11749085d3197d57886020b174f280a49cbc9170fd7649b00e7493653455295aff2dc04abda14e6dc2bcee0340a4a76187794e5ac01b5199bf152e360be2df2c5d16aa14c64f645912f7a9aa796778d94fe2521de4f91639345c95bb056af12755b646eaa7dc758eee66652efdf0b54dc3f7bfb1298ab143f20f13c61f10d3cef3fee5a522f299a26ac23f634ec3f9d9ebe7dffeec5e9a92ee5f6bc5398f5fbfbf97c9167cee3b14f536d0f5e57d42a85d7065e79ff81da69354bcafacef10f11310bfa26f66ae38bc6324d29205698d715c7bad64934ceb3b1acda1028aba3774e1aa8051cb9836763c8082c84d7c6fe29ffd4820a2e87ab5cecf9c88e20b5c257cb30939010915e648feb74754aed068e9f8328a655dbccfba740c137107c5c56fd339e25695ce8f3a21b5164127d2d0b7592daf646a259691b7b13101aa9256ea375a6d1d550448cc7aa008c6de4c071a508e546734eb6637205b23c366770ee6e8d1719e5796a0ee175fd1c2fa9e7854adafb4daf31d88f38d2d6ccbb3ea320b69e27f101d9913598b77c86de9e4da7bd641e6efde075e409e9bf4bcf3a59578ac49179833d5e96553e170c089c0d75e659b0718aeb3308cdac64ac8f0b2edbe771b274e5233def9eeedd8680bb2b8f6df27ee1b35abdf77d353eeb80dd82c9bac27f70d8351c967b06f95cf6ead0fc4fcd5bdd30be2663f591f3b5b9eaed59a6f18ac1b3f34cbd99b48f875bc68dd4704b731a72a5841ff4f3a4c331d634e37f7faeea7af17763a98c97dd929f5204e43cbd5047fc91305b094166bbca6b21d47da33e52abe8c5077833b0006b555e0f533f10554e072fb83ec98bb94c93bfade95143f6ddfb443aa5adba658f06858e59f1ff4dbdc5fe4e5021ff4e4d0e67c99c77d5cf69effb7dda5f03c52ab35d925ddd340e5e18c6e334db66657bf0fc8ed46c3693f2208f9349a2e2b581f4eedda310267355c95fd16a0913645a79dfe3aa48bd8472964c74910e27ba574976fe2c1bcff2c2eb1e33d13a2dd4a46bb294ce64dec7922c53058eed147d6be1b7e5b314dbcf067a32dfce7230cff6d304ecbba1007ddafc42959a456c3c5e521f8f875ba67d6251d4187e1164cda576991717594c956e413714e117cb3696a3d62af0d375178ada9d86c0322f76941284bef182091ad589197dc7e2816ab1ab5d1350d0b7bdc1395d14f0f739aaf9db5ca9837707cc6ee8dab7f3b98710e886e02d0242f3907edf8c412c6c3a153420b0364687c41708ba661b9e0551849f0b55d0ebf4d1b212a99a5462ac815a73997b847c2d82d034c02a3a2d553ad12b08fb92aaca4635a5c8f2c32dacb0773a4a65763edc12aa1adb7be97b6b1692eb1bf6035d0acdb12846373120028de18dd87694de6ef01d816f29d09610d5433bdf09bd13cacabcd927371f9c834190739be4db3947056728b02c351a0dfde3eee2e9a57935bf9827df34c956c32da9979095f9ae3f57cc71dc268a937291cad56b740336dc7259c32ddfc2bce18c8172215a2ad04edd9397b250e207f9845b961b16b789b93d5ecbdd20f7be955888453d76328c1327c332bc16376966fc761096643c0f8daa4c7bfe3db580ed93b2aa9cd9747bbcf8719d19df9a973e06666a3b86fc937a811f558e7f1dc3b55c75032105badb683fcfcae55c8bedb8c9bb891963094bf4f728e1cbdc090eb798895b96a3d7ca1ff49c3c11f9b22a9358b1f32b8a6b9b9d0c86a610d44dcfc360cd76a949745a23e011386b95d69054f755619b7a6ad59a8d8e310662b805abcd41b879bf434f16e816b3b6cdb35dd0f1c3f0a28261e296a30e6e98e8f676cf2e14374e9332b0298b65c95f9362dd663b523af56de0d277e1d377e0d4f53b44f376c32ee9b07c706dd2b4da1c6311ecb87efd451c1c3dfd901bc8e08ca87fb68f6b47545e0c184f37387b9eb86703859a7c2e6c38c5f203f24c2eac151e9d1ef8b156662b440735afb940e3ae042b84f21b0ee7666206a6f3dd402e6c3c685b1ba4461d270a376b8ffb553ea0498892f29dfa9f6552a8b8769ef4a9143c467fe1890860dcfe4ca48bdf782ac27e055dad9d8c7ecb936c3f956599c9b92adb0eca0d3ab9b1adf3f99a390763a376ce17a35ca56892a4952a98d09184faac841666a487d91e6e89e156f0caee99d9a52e0bb95880918d441f5ca5e648e05679b825c75572a1865b222ffc50fe3891afe5454d16babf73dba39ecebcaf77c27d5c4b24661c0fb774628f56d870cb3954ad17f6eb73b968b8b59053ddf541ada03b2a42068c11688156291c1b8364d787c6e275287e5f2c22078dc503e887d52a0d3a02494e3a3415f57a3605c73568eaa3de73281b3e9c6c573e03b81c8049b385cc9ec60bd56c8ad1eacbc55dd65f2c73957a6d94de38acdcb941ecfc02a913844e9f98ba76322cf27922a01913c67e3ea08f4454c2137e595377d45bc2f8cd6f0bec5f49baa555ff65026ea07d63322650cbd5554d6663953db78777907d038d5f3d85b5415e5d589c51e32a96c4b9a9fa282a79ae32b01c188859552dca41bf3f4daad9720406898b244d65f15bd9d7557b55de2b74ad457f94e6a3fe5c96952afa606b14fd56fee9d5e3edc75c7056e5582eacbb18e88e7984635efdf4dbc7d1a3874ff7fefbdee0fea7eb76e778383cb9ea0f87c3e149a73fd5f3a77fdfdf41ee6f855d50ffec790d3c75462fa11ad7c53b67c224841960007c9633103eb3c14531a0bf462c1603eee1148d727161893d71ef5edb63514f3d8ed586de36ea7021870f77cc58b56de0692800781cb51b727978f8c94b30f825316b06db3beb5816d815fa93f119b09e32b9371c9a0c2a437e3670ed3e78e06d905757c8256a7b061b8acfa7a9378c3b0f18fdd3b4e1e1edce679afb3bc1a9e6fece3fceb946b3b3af78a421065993fd299dc47f7897e4e6abf994d23e36720c6e286ad1b4e9c456255d2566bfaa8aa5a25dc6f5889f363c22f573ed4aaf535bd063f616832d97b5e70c46fc83fa298e49c71ba1108f693ce898d5b0e694e41e88ac69ddb0aa46e06573c71dc5788f2c02db2c6e42800467c4677d32eaf7ff24ca7c598cd5815c2c926cfafeddab3d6e57d88bf379f41b3c77e7668cbe85dd70eb66133b20bfdbdbd86d04b9a93a6fc7cea9b10474a7995bdb392e4bf5639e576555c8c55b7cb6604c18a3fed14c0163be486234c14457bb7413416e3ce084972e937880efa2dccda416b0649281ad40781cad1d670aef14332adf9af72020ad9a6fcb45a145930b1fc1f9a3b492be73c0b11fa87fa1941713234e2e5af63451d6b9fcfa5381dd5c6e273f9b01215b810190c45cd60465ef22ccbe93a9cf5cdb6249b4c606f72da7b5299713ac6a54008843df73c370ab0777e9983910ad1efc6aedde205533fb95707f2d48eb022b9a7684ae776c0f3650263874a9234f41072a1e09fbb6864633a0143469e8d82dc6125fb061b46c46cb2fe59335ffac3f7db2d5766ff1f00a9d16cb51aa363fbf624fac50a03c47ef5fbf82f6c3ae179e8e3766bfaa15c54575ee774c86b8871eefcda36563c06ff23bdec3b60285031220afeb03af8d45232028037d88935297e24ce1065405509a3004036170fe5e8cb6c9e47c2360af3c87742b23f04d1c1bf29ebf39f06ce4e37cce8ac0fbe9a965e2f8e9317ddd5f7dcc3c9cc98562fc7e592569d9b77d6475dc63ec9f8b7cb930846c378ac6ec964fd0ef5f1fbc79fffae8c573bd0a97d93c5f6615beee63855efcdf9754427d4c1ab25f1fbd78f7f2f5cf5020abe072b1a90881d0251a9b30203e261541e0d7986e38ecc63055552956f952c4aa1c17c9489fd0ddab5c4405bc08b3d7711a1cba62a872213374bf799a5fa80266e014efb5a52893f922552256e35416124e1dcfdebe8cc4415eead99ccff32c5d013450208207518098cc01f84c0940267a9a8f05e1567fe6132105bb60182d2b31969990699903c491b2f0ecb892ac87b7336c78308e52c8525caa34059525d4eff57af6f7c387aff34a3d7c3810670e8367e8586291ca6a9217f39e9c6679592563b096735d8bc4cb89c66eabd01dc277360f5907e085cdfee161170a41a4398ab97029d1c5c5527319f1501c9fed1f1eb2f64fda4687008b45e3739925d52aca8b2926f55c33bda9a6dffeb82c596207718f266491785909b3be854c53c0ff44c96a59a8120ccc58e38471dc2e4a8023637c972a53572b53fa20248b153c614ce54a64c958217dec1f1e7a7868cf54368659077018db69420f038d7d63f304fdb872f12266ca9f2547e8361e944c2b7a27ca3d1398865d85a4a29bfeb2ab7fe33bc5428ecf4b31dc823538dc02c21c6ee90537dc32d434c98b3ab852635893f94223432fb82a1753bd28e64a6686c6d56402ae49725141342b8418899ff202c0a98f1216d5a5427a8f633c67c0934bb624d0234a5209e86729f242e83e96038bb4b3b3b3dfca8f480286813206e13f660a2909c4a68734c0acac44bc2c8c8aed9beded5a2ece8ed1547f822cee236320cef2851c27d54adcff64605dcf4ba164a97a49d6cb97d55997aa51c981d8c694eba03507f61051e35a34bc75203e39303b1844d3e6ebdd7d5d3e32563f7fdbcf0fabdbeceb102d3fc958a3a3fd4924e014127457d71db1f744b409e00f6c4a926cef1316ba365bdd9e43d613aa21c42772d5eda0e87f3fc4c905d2cadea74f2c5d88288af80475c3cc109fc700ff8415bb66adeb7f2f5b7321c5440fcff5ff1eef4c3f4e2e5c9dceb5192edb72311b0439a0568bbc23741a5d28f1ad98cbc431716f839399009e3f40d03d71e676d6b3204dc55e12ed9e419229847d08b61070469d4fa7a98ac54522910f25d919d9f77ed0abf1ac2a96eacce768b4594d930ccd82875b2f88b194959caa483c5f82a11118dc4352d70780ceadc1b812562ceda7a5d176d636bbaee6141c17865db935ccb821abadd953057e96d0653dc31df64ce49a81c35eaebb97aa4a45e295d2df953c27787a53c9d334bf84b031c4cdda974aef7dcbd2f1ffe365a9c0b74bb0cffd56c20617e7e3b23fcbf3f3b257a8892af4de11cdaa79faa765a9c8b395ceee34323c7be878b658d06dee4330a3d2abf218d7585794aa7a093f4ff0588aae66f0966297aad009c32db41f3cc2bec502fe6e7b3b583dcdeb57e0f3dc288abc44bb7444e3f2a174329424a380bd4f6d603276806d4d999da01b688159e5022992b782e05c716f39136eae6bebf68371d245bd494a348454f17a92f6690de915d08332073a0503f701850242fe6e7b7b5e8ab6ae7421d325c8106784ecb38e095f9454629264324d57a2bc4caaf14ca110e3968626ebc8ef3aace7a414674002672ece035a99cec0734d29d4c7b15aa024821339cf2fe8608428710c86da23e6e2bf486274f3e52f921cb05bbc487285dba4d3082f0cebef9336be086aeb4cab20b1c0fca73f788da659169cb59c311b06cbcb8c8b0838a081fc1f9cce4068257147429432985f3d2bb228f9850926c13d996befc103718f7d474979604e1b4fe9de00808366467f21147e2185ae46359b58fa0f9ab02866f841299953e128c902df5e58cd77e6cddb107b74ae6406668d0d9ae3e5068f5d35c078dcacd9a705155defe974f6267bf13181fb244c36891a751b47628fd177e9a43ffad0c701e282b8a9835342f5810f8daa7ad396a98fd5be4cd391840702ecfe71dd93334792d15455cf55915ca818f68d9f8a7c6e94705e00dea632a44f5d14eac2f70eecfc8a397b078f9228f3c10357392a095d7b0cc9f5d8f6dc891c2108d16bb1bbe68ecca2e51a56ea545587995c94b3bcfa1198edfb45acf74ddd9fb7cc9976bf0f3ebb2aebdfd82e0d9b6b626020deeeededb1d7721c8ad9b93f51cfc5b5a0a266ab30e5c050cc3dd4b22b8eb2c95b0802d1ed59bd0c79ade4c91689b6b2f0c7622a7b65aed91727f0a61eecf11e5c5d8930f9e61ea04a687d07ec6ff7cb9003876472af79883ffbb49211fd9aa7951b5fddd5329dc92e4cd512e8077b02824a57d4789cff56b2a15524c275cdae2151b7de36b1ee8df429ecbd3f01706449eb32f07fdb449d9f4f9a1be9b2fe50a491e77e063d6e22c6c65603ce529f77b231720037cff887244ddfe386d438e72c3fa0367435f99a71fe76635353551d91ba39e0e826d97fce4d22a8e0341251229321b42cd84529a62b3c0943e740242878a3ee641807c311a5698c2e49348998a78f36674fb4d01901f772458d50a9487fdaf9322ddb4cfdcdc2c662c01731311ba696c6f57c89b9fc2d2f1c95873da7851cb8097e1a660fb0036b36216f040344a3d771aadef57b31a0bf7cf70f269a93219f698f3c8d62daa350ee64cc6aae1b3d70badc661f9c66673f74eb1c2fbf2c847e9f2f3638409123a791726b36b7b704f6b1da66a2b73c30074d95b9a5892649163f7f73f03a8f1570ac262fde8775a611b820d4eb401593bc988378d88637e316199bfccb7a753f261554ad3fa670218bd8a2f30555bd3442968c7d06e187bf9f84620dfe758db864852bdb0d3f98914f577ce49cae3661a476fe7a4cfcc4b307b30bd58d992f1d7702428a430ab016a0fc931f8206b61bbb35ae6637368ffded065d3ab22cd0356f9779e9d6b94d711c26cb6954783904caacf364812e21414781fb0fb6d8efeb39bf441da17785542cb3ccaad3920a54efa5e148a7f365599dea0553aaca8be46461e8432276046d4e27c9343257c23552911375b8815cbc2e83054163f4223a8c3ca699ccf128a5e290e4ddcfd01928dbdd3c18445d7632accff1f5bdf7fa4e92e5faae37753cc9a64ded0655f2cc09952fb2986a702aba095bebb0bf16ff9b6660e31c34603098909a3ff3664e807b6f8d1158f6565bfddf34ae7edac2d9e277bbf8cd6bd6ac360d65ed62a373215b218a0efd5fba26fc13e7e649fec64d0768d0be6c4584bbc86d56813b5eddb008fcae9a355023fc6fd610bee388201e6e46ca2d28dfc3f22d08ff064cdf85d8eba28627a03708229eafd69a5aa64116aa15a246994c73837aa769bfe668e55df6d06d633575c59820db8e6941196e71e08544d68220c0f6861c6fd42b7bb575a9922216851c83d233a64bf2cba49a59683688aa69aa0ccd24924c54aa44c1b4cc8d443897e74a50a47f59597074a58cb812325b8985ca20fa465343e099ff5299d6489e1c3b741a71c99b4c8b146f916dc25e130d0550bdd958d7608d797edbc43ca5795140e117592fb3352dd6fc6c80e616e0784bc9820e6330626f365023476ccd3f873bb9ace92b117fb39fa335dd72e08ce39c106ad3b404bc8bb7b891ad9920a0857f120fa7d214625b599cabf2755efd222f146d616f0a1339c01d30c59e3b0673374d328e5fb848037eec4e38f05c5d6d6c8161b1b47b689d4575c5f64d3b517042f13b1672b6a63206a161db3537b70dda815b0f83ea6d3ad4dcec43ed96cab040ebb4416fedb3ed6091df37e6cb0e732cbc89f15b26f67869eb872d2cf9f676a6d00e12bab1305eddb64e50bac207b964583dc9e9a6af4af0d98c1942ac52a539ae6d1835fdcd59fc92656d21efdcbbb694a773aa67ab8d4da84d907d655743cbe1726c2e96df304c77ceb8a9887513de5862d350ac1877430968812d3cd4c139b2dbdb132db3525abe3647a6697e599212adac54ccd4ec65b0049aecd69b4d5723f3eaa1eb7bc548976a60ef5e482434dda475d865c3ebd4f80abc9dd3f9d6087c9faa477996aeda0658e0b3b17ddb91fe3e4324a8699e39af15baa3fe58b142a33b46d785f5ee18d9f508a955e8f55673ff77bd1afc0dd6eddfe6e2a51058fe0a78be7f66a8ec8c6689cca3c0469639119464a4ad101b114aaccc431c41d4e2888ad19013eee59b8d8d96a56873d38d2eb7aee8122c660fd165d6109daeb89c25e399d7d52a17e05dd41802108872a1c6c924191353f54d21513435b8b05640fa2334ce61fb5192311b9d9defd0464780818b6f9f238c0dccc1cabdc3b1ef3cf63e9d81199cfeaf771f6b5e9f5d8bbe03d7b936bd09ac7784b59f116017d2ec68b3d13f899e31e69c833b263153eb724f3abc28d2b7239ec3597ee9dbe7ec8aaa48a65355a0c91aeac3c8c0946cf1589f93ace17d9cdf4460bf4b14eaec704b4146f52299cf559cc84aa52b21d33c9bba1311da96a105c71a1360638c6d6dab875ba9fcdb0aa10fb7022ba43c2363340d7b92146525ce80488aa5ba3e03389a344b558933be019f45e2d9c45818633d44115b1c4df64e955c516334da2ef87dd3fd400363054fa99659aa4ab4d897699913edafc499b7bf9f456c0a78efbe74327437dd7ce031100ca5e57846ae4ddd1a466a880c25694cf9bdd4dbe22a5fb62016ce0443dd50890047b6a5499225a56e8ab8061fa807fcc691be065f009a927c62cb72cec834d54d28266439cb2f331b6cd22c51c6459e708373e84b59233a4606440940247cee91a85014432331301ded1a1bcc90762acec6842c4599d313ec87fa0b26c5ef25f5cd638d4fd84b07a788c888c4646af4e4646e0ba134cfaceef3ac4fbf557c862711e0c6163698cfcb382e05daad9bc702e1da88c42ff9a5bad0fb77c2d1fc449cfde0bd80f0700d0e69d62c3630fc2f548991a82c38d68733127b7b0fcf9075abb28b202fe5caaef4f10c9e495539bde24f2a0b2b4e2660845aa52b4e8fe692f106427c91c951aa340b25bd696d0c2587aa6eb58e1b806afebc0ee66d16cc51dd4898c183f99a27699a946a9c67b1812fccd66258d7992fe9834d25867a85a05e8c22ff335f8ab95c591e27459964d354d9933d787cf71600bc7058b3dd7b36b7e1064bdf39841f4f2e9278a979c36da07d325bb999eeefb6b78d706326eb1b9e04b86685aed775a6e79800f1e4d258c43ae35668e1ccd5c06fafc2d936cf07c6db984d85feaa0f2ae21345e1ba129f70144f071498ab0b43609fd8499b600704a4457862bef928a5bda8d9da2c98f5013ee3db654a9966ed08d4597081e64bbde68b2762473cc54a3db1230662dbb9ebdab9b5237d5df716cef4e928b1a8c8713e5a0774c5310c37f0978f8790daca7c16c7ce7938637d4aef1728ac45623f10da5d3913ffe921c46705dd97de69a4388bf34c9d59ed23c4e13387b5795ee8ad2b53625a48b0d9f01b2688693e4dc6116d2d83870f85359bd1bb4b592568f81feb8d4a3aeb9164b28627786bd0a785bd4fa4078b21e0d8de136197a63e52d3f302312e4bbebf6731fad7d52b612e8b73da92b59481472257d642d3cd0021ea8a5609d7f2a0b6b01f5de15e0c342f76dc2abc913438a4f027dc6a8a27c059c9ac1d5f9098f3163d485b96f05471b148131547e25926d4c7aa9002e2f22934ed87fe24e533bb9983b4b3c43a1a319a278ee19dcb8409fdf8ec2329453ed62740789989220dd9d692685d672e3f112f80091b885faa794a27f0ae60fd1808bd117544ef0918cd307ce57571f63688925632ff57c4531d3f90f78528d2e78e7f150cada724157fd9a2c3d34823a6eed4eb355d0ce4b33b4fe4efdfbd2f25353ae1fe7e1daccfb0de155ee30b1ec5ee10733aee8d537d9c29e81c22e27c0cfbb8349afa6b31109f5023c8e252e4f0a4ec3a50fd35b99749327223d1ad9fd25d7a70a8751946dc7429246c8291b493eaeda7e599ba93dd904b84891a5d3c0d600509b58a84669d848e36180ab8a3846d3fcbba47d809d29d5f84c70d3950e59b3a28acf16dddfb06d3d75268e749a1d4cf693e922938740601b2dd8afaa72ea3d53181fdc4735529f061a1b4045e2470ae3a2b553a398b80d60cc843954e9c479a12be5c5c59b0d9d669f4377a03e97021403f29c7b6fcde8a48f6bda3390a4cb1fb08db75a3c873b0277203bcba727dbbba726ba8c56e795b9d360eb7166157c3c3a098c6a7c4fe4c8dcfc103ec191c47ce70d1c8b284e007d0dd4c9c81607d66fa67dfd4fd552ff4648cbfe74a1f1cde4cc429e5257a80dbd14eb48d097acb98e6c54abc92e444c104167e784d87a1237b2caa7231d67dc3a7927fc5e195e2d3c8443e7e4729f424d71f81cc84d45deea2f9283df72358f464d58ee2344a4a3c391cef74c5e3aef8e6841e40f6fb5a0205cf6af5c2869744a33c5e45deed88a9490e666a555b72346eddaae469a4d761735122122a2af6f0f863aa365380cbac07f1662c1050ff7cff85b9f4ed3f34247a7afaeec5b3fda3d3e72ffee3e8cd9b5787a73fbf7af3e3b357a7bfbc79f3ebe9a951184f48af6e56cf0db5e016cd1a8eb7c4d5d51d6a47a6b368116f2fe33488c04fb279e7651fbd355fc6f018f035db9f5121b3f14c13d9320395293090911a4b3c9cf8972da833c3bb160b27c9846bc15a0d39232178895e2c15564e3211ab0b95e68bb9bd0ac1dea8829ec2a218e67a8647329ddf15b192b118ebf3a04a937992a1eae7529659cb190e2de0061c9f5abafd5ae76018f2f14c6653f2e782e1e223ba667aae2e8ef23c2d45a1d244e9f18aa4d287cc3277564a161aa0c7049c8f73a53b81f2222cd44b505926998fc62e6874484f0a68b6f024ae06b1c8f59670417aea5ad4fbd67f9ffe37791b83d9677174fa7df11faa48262b5416e23ce8c3f328bf5062264b31522a6bc0a28a45fbf9fe8b56dca1466f49a56df383fa63a3f31405a7358b57676b362e643943b47745a6d15b8105d74c32aaf8a08cff5e24824251d85b319625381d19154a9e2386f5808cd9579e95b966158030dd1983aeeb8d4e31f79ad78b1ec1fe0be423a643f8badac8dcd65dd468090179d447355e56aad4b29b316ae37818cbcc0c662463314fb264929053e0183d2c2499de9eb40431849b36c3c37651360b374327298c7f2bfbd65f55e44613cd932cfaad04d2e12f186e0f8baf5c0388366060e9cff531eaa7bc98cb4aec448fa36f20b53dee88c7dbdb7fee3ddedefe3fe2b0824ba457ea22a96632133f949090d27734cee7f870ffe0e5914893b1cad856f2321ba7cb5895426533998d41be2ec568250ec779a5a52995c552fc50eaafa882af2853d513fb38ffd72229c5aff9a54cc50fe3e4a32cc0d3f1ff775e246574ae93e11e949ccc8fc76a5169092706134029e6b23c87f58b49a493d2a9b8199b5d5c8a0920412fab0b55944c3d3d4df4e863ba852215b68615ea53cd0db6ceec57c99c95d70d7ae57519447ba4f34a23dcbb07fcd60d641b773e22ecda9e49666c169ed813ae6af084b0cacf4189d98f3fed74bfbdbe9ae39fd5aafd74b05a759e5eb58f7f991d9447d5496738dc797a75fc2acd0fffebc3eb93abe1d6f17f0fb74e1e0eb7ae5ac7ffdd3a79d8ea4fbde73d7abc7fcb33a5a10f87a3f6d3c1f1db83fd17cf4e8e0f9fbf3d39ba6a3f1dbc9570c37e05ef4164925dedabac2a647af5023c536757cfaa54665532ee88f6d3c16125b35816f1d573b94a93e9acba7a5ba80b99a4f08ae528992b0df3e783a3abf747fb1ddd5eefd1c970187ffaf6baf3b4331c8ed674703f4d16ba93c7ffdd7b341cc6cf7aff7542254d69e36d5ba1316cb95ce86506b1c709afa8781ccbf10c1c4f14f9723a13e334777b8dd5c93a8b49244924c86535ee8ae9dcd87c9a3ad0f67fe25d51ab32da4b5d9a6e39d18a1edda581deb96d3492adf747fb8316121a73fb88ffc09e34505c03e7dcd18784f3248bdf4ca07f1ddfe7e58307e25e7f388cfb51a5ca0a4b04c6ddd0e01ed0df2e4fa7b7b256a80adf6cba4f2a097faeae60d77c6ea0f121b4ef4107c0d64473927c02e5c20e113803063bbdbe758d9aa47c2d5f378e0e37727ddaa78dfc657621d32486565a1bc0125ac8a564b8da8ff5ff277ab450eeeaaac60f8e5bc4105ae451d9231150a18b525515be440212e94fe795bd28b01e8434345717bd6796e7879a4d8b3d6484a5fe686f77c5b77c40f0e4d015d564812446bd66e93f1f1c0d5acd74c11af8d68f36a789da1a49bbe486669bc00bbd7a9aea5faf9d12b8c4d124598dc553d19aaaeafdd17e4b0ce0676bd72f1813451e9f8a47a2a509a975d20ea3383d0f0aad1acaccbd32077956cd1a4aadbc523f2dd3f43f952c1a0afee215fc255f166543a903bfd124d3824d43b9d22b778877ae0de55e05f0dc056d43e1dce2785b0c70dfa4f7417f0343a349a9aa5aa50f624f4c55f541a9f3da8a85c82f98ff5caede4cd6169aa4725a72371dfa5f3c80ffbb5e1a242e64dc8e3b4186ce618b31d9f94b16c5e822b73c7e7e12968e071b4a8b47e2cf7e8d3974662e1e891d3f7d6e3a04799d2073ded0a9b926256c687e12969fd7bbc5cbeb361efb95562bdd03e257ab0eadd9c79da0902eb6f2d26630a45fc4bf899dc79a37ec3cf6b3676664bc880ff61704e1a7fd62ebf9850fa0f0819f76600a1ff8854b285cfa69a5295cfa855328ac335e75c5377ede2b9b77000131f26516b75f89bed8d9eef8252bc2c70f7ab04f6bd3a0c5109c85ed13519f2597bde3cf4f05706f01f6f166b0dff8608f6edbdb6f3783fd2e007b74cbde7ebf196cb07cfe0b7aab39ff53d81634f726764ebcbccd76dc4e04b139da46f2037751c7add649275ae48b76c78635e1a26157b45afe84e6d0683b174fd0117a0ff68c47ad8e78e4086292e679813fe5a86ce71dd117df6f77c443b1b3bd2d1e099ef36fe27bd86cbd560ea195e356356b75b500a6ff870be05611b74e8e63bd78b6c513f10df1d536a66c8b9ea0bc7b7b9a18c543faf631f701c07ff0d25e43da6bb66106920689b0b0875b5ce923047fec87f14f7c9e8b9b78359ee9733f70e5daf66dc4639d790c654fd6ede3ac23d578469c69a74b9f24cdf6c4cebad784f63161dbbc960ca52db76758b16b20fc7fad388e356715710c6c5033a883834159b608a7ad72961715480a7eddd6bc1ff7572b5b6eaee26439af176c01f42e40b785d33c9b36c084c2f5d293659a3696d63b555734d6816eebdd39ecf66c7070208e8e827ed74b42c14159f2b2badb0d307959f15fb67452e64dbd162dddd1de7cde8b635eb609b068d5e683a0d64a33a8c361eb6838b455735ef77d35ae570711786dfde1b0f55fc361cb42511f1749a1ca5f948c5581f406a05a301b444f1e3189ff02b5b17922005eebf4d158a29561f2377a4b0d4cae0c4859f34e47c9460c198863b3125a87cb4c7394831cfe1c2d95fef341019b399a2df59f9f8a44ff399455abcbebc5724555e9d7d15295f4f3838a33fb71345b16e6f74f4542bf0e65b52cf46f84699893134a7837ff5d42ff7e5223685216facfb345815f00efdf7124ffbe4c216f398546d442ff793306eef93abfd07f9eab311bc9bfcb6c298b15812fccef03598c67d44a92faed286a68452d2d91391faa4505374ed4644e3f5fe71736f9b91ae36f7fd4767fe38396ba02f45fcee127fcff4cfff7167e1dc0cf0303cbd1897bee2fe3f6854cbb2255998d1892ba63e8854c912da2299bfeffea0a6e4585b89c25a912ba88e1a83f303006506bbb251ee9df4e974dbc19d3aee9ae11145f3f2bd467bf3c7c23fef2fdf68eb854ea9cecfbd0e9b62c552cd0a912ea05ad87cb59552d06fd7ea5c6b3519a4fa345918f974592975196f6cffbd9f73b7fe967eab2ec5f24eab2ffcd377ffe3fdff777befdcbf7dff4f7653a5ea6b252bd97876f7abadd9e6eb727b3b8b752b2e82559ef377921cb71912c2a70f8eaee13f13e507cc21bd46b71a697d719bf02149f5ec300ae4951c7dd36b983895542bf438f467ac6991f6f914f60e10ebd10fe66e584da0b7d7c3247c276a76b8f547098e40950a3d371cc631faf4d6272b46f1b0097a31a2bba9cdf7854129c20d982173dd16ecc5cb5b544f4bd966ffeac7f7dc33a7224cf95a0b527bead6642966420410fca930ca96347b44be548a663300476d94d08aaf784a3ca2835ee820faf298b0e3fd5c74643de2664c09db7969162d26cf64a799164d39ea6921e3a9325232615830a729c1705180dc04594c1490caf526be30f4fdaa2276a1d6c3c8dd70901f40b0d28c6740d392ed9c0706568e2d6b82cc54855974a6504d8a15b0f090ded4d921992aef73c994cc49e089a0d47a105ecf65fbeff765bff7bf8672f58cb8e11b8512a37403b4d0cca3009cd9754918c45a116852a8d8d8eb904d03da09f44270f35adea09c12db163f5c07fc664dc333140c2d7602e81eac305848af34b52cf58d2036424933664eded31476158f8cf35f61de7972176ce932ceee5130102e27859f983409309bff3b8cdd43a4ffae50b7b87a18f07b09f848e3708504b27b6b853545ec3aa946bd5dc0d7e58972ef235887bcc882684e08a85003cd306184aad7530f8f05a3678b98eaa1c7183be8c7575ac4b8799bf74456fa71355f9abfc5215fbb2543087b8bdd74681830c9efe8a070f28239273871a4c6a37fa6d30536f25c8c0eb0a737d860ddbfbc62614d6ee2403b8be0736bcd38abc6babb0c230bbee58d7705f3f44928d1a4bb0ec77cb060ecf7208245cb7ccf3e5ae42c9f84d96ae8c65a0f133d18510247e64723713f4be5fff79ed8a317fc8c726ebc4776c18380ac1370dc7d4e68977d2360e0eac250246d89dc90b656de3851467143f0c9b138fc4700bc30ec0d30ec8cc5c067cb7875b97e8bd000cb4208dba40c5cc17862f00db954bb40800070f12d0d603139349a2d23812c3ad0e427e39210b7a95c6e6f67ea4c47c09f1b5c00a1f5ba4f9fe55adda0e8fd03c83f6a69aa9e2322955171fc5d5fb1a0db73a758728431e8f9e08ccf96eccc6795615799aaad85a84b65dda7fc874a9caae6021d618cff6a2f0a382027785e85cadea603ad1242f5ec8f1aced930f37d890716cc9df81d73bd1244fcf4b342fd198a3a85c689f40afe36d85e300a39d138878ccc2c5dedd7209876c108e4ed9f9e880ce9df6e79e6137b646702549e9515524f376878e2b9d2f8b3cdd7a6fe71348ac278effad3c19e08360bd10cefead3c1399527129a4c03b40d3bf73b5c2e59164222f627c820ab64749c5e844c36d7904818bff3611acf90c2d289cc47aaec369cef3b4e249491622927848e04909611d1897f219996351017b6a06c7e8ea5cad7c5056e9261e696446e3992c9e55ed6dbd23be5f2ccc8e48b9e5725456457b87c4396b499a2f56e85e0ead5776bee99120d7153fc9b11ae5f97957bcccc66895f14c73225d1cde75aae2028dce4c7898a4a4e8a868749594c6b0258681a2c5f98f87cf7bf88e9332c5245f66b17b74fa50bc7ab9ffe2f5e10b31d1a76b320207abda38d1127d5e9058e9daab0aa5e061047b5c3a2d24c579c92762212b9555a6f3e4da80372cde3e3b7af1fae8d06b148e38b651676612ced358666845f34e4ddae3202404cdd7bd7beed5ec8307ce29894df40d21d1a99f79406ffd7bebaa0dc9f0084f8e2bcf05c6f53f4d005a26169c5639955869b297c5b4233e012fc46780909fccc17050e79a70fed974b8d5d90d6452a802acac5ccd47790a6c4c270e8c76472fab5d143dfd2e9826926c019eb212984f2ed8410e714a0a31bc85a1b017cb8a89e9d42548dea58d2c99430cecc5b23a3e849e45accd935dda2f92794d8681fa05b92549e6281ab33eea0e0cb788350046588f753dbfbfb677852a779905a633de186efdf5afac6f62be2c2b5349421f301dccb82368f1da7a99811ed104d01c89a7847a31a0a36f07fb6fa6818712763eb096a57aa7265d1b0ec88f93c6224bc2c3fbf75592967e18cac0567a59aaf78130025c1b36d7ae61bcf4e5bb498323b704468fb1ccb16fae7a3069cce0ecd4769f0536e26d7558ac77592904b7e7ea1db31baad2394574f93b27ac39dc8dd0834d53d77683e1883d36b0882cf350d1594b06b3741b64dfbd347a3901b2c81736c00fce83c3b5dee839eea9a2de502a88a065df12800e8161074bf6ddd9ee1e8df0c1033b04f2caafdc703dfc1af1cafa3ef4721bcea1c7d4c45386c4016ba2cbe994499a175e73ff140fa235462da91b7931781b0dc36a7a1bcd507ac170d915ee8c75520bbedeb00a454394e075ab9685499a24537fbb0d4e063a3f2a54bc1cf3733d3aa7e8e299c93b4fc25cd156f8d87355795ac0a2a7aaeed4c8098982c41c031f8a9814e71ae237cd300cafa22dc78b15aaac6e1b117c43cb6cb827d15c2edafe96dbe978c3a5d9a368d78849d63d1f354df3b9b796d7968dccd63b98431bfcceff8271c410e8b1777def8e4e8d65774e425f9b2eccf8751770dd156d4b0270e474a1c81f3314883dec15cfe5dd177bc21e326c09eb5100c76bc4b5cf93cbef227e3373f3af26785bb9b839e087175ca6df87c7a8d6dd7d59154b0d399a3e3ffce92d387941d361512e473d720a13998dcac494aad75e17d18939a0646e2f8db2179d5d2aebcdd86e1f6b9447bedf5c06ca3cb968c6c03b3556c985c21e65ea63150464fa4c8cf4fbe23d5932db3e752840069ca75506ee864da4ccac057ea4706ec7aaa8649209154f153c334198419c8da2dd1c0cebee136187cde36bf95e096f3517e229a50e58042cc2c68f093a4e1e6ee97e0db7f41a40b91034967921ca19b83d247d9a2a0c6e61ecfeec1202a25192c5a851b577216b02db6034233650eb589970c79e30e139c0c430e28e5277fd02871cd33072eec3d9f859b58d7a0e9e2b63d64ddde099a7a7203a93a9446a6287fd94caa96f22bca934f365df187ccc296268a45d9e7268a284592f8f363ae4a786315a204d63b4f0bce50897c9725c8137a34ba9cf2ca37c5989f18783fef8c3bbb7fdf187f762aeaa591e9762a434edc46a51a8b1ac40b5d1ef938b9789460b2dc54295e0dbab540032c9a626f4b4e68be4b34bafa86898d51961747a6a803ca7a6923cfb80801ce6d7f28fcfa98fb371cb9adc36224f5793244ddb61984b52c7924e624fecd75512bb4c4c7745afaec4bd0d5a0b37efc15bc07d99e1c34ad3257cefcccc035a9df0fa8940e1d9d7f5706d80c07be1dd9007c0f57a0db1dffc92d5758277b5dfd787263d56a70b7af6f6253e9721a6d715c3ad6556ca891a6e893499a8f16a9caa525ce6e4cf1e1fab9a5d0190a671203373035b2a5e4f83360285e19df631ac5a894bb83db8cc8b73ee62cdde4de7295c4664b1eeb62a447be7fbe89b471df3080c4c35f036c9100b881a760d903469f9b7578213fbc68288f6b008d377b829ab2fc3754e801b3bdaaad76fadb9ee736dbe7f7df8eca717a75fdaf45a302dff61f4e63173a4ded87ec30cb4d642fb3c447c717f6e027a27ec98288537f4c323b8560384cfc3c567b5be1e5030f2b5b465e52cf3707f3dbed717659d32853cc607fea94d1fa9ef8e15b33b17bd33b88c4cce1593833275f96c9160752340dc9eafefd5f832fec3f74ccdd26a8795c3c74e8df24da7c50240e82d8b94a6c63ef13df06c91aaa91caf3cc6adb7b02c67bc1b440866edb62cf5ae5cdf16a2e1301b0eb39678e47ae8639865b4f4e1bb145e61864cafe46859a1675b7d52962630be0b1a5f1bc4c003dbde44624f456ba88bb6c4a326521c8856abd30c6c2d2d0e99a97b23f8b026afb0a1c1068a6e86cf0ad6c0b570928e66c627019b7a77358f911be348bc525a3405c77e289f822849c225b884188453de32d1f927a368aee8f1ba2c57d9b867a9a1675bed41c8fe96276b5be90325e41ff6c4cef7d163f4daaa29d39e3ac15dccda98c946e678560a09128384773ea017d57236dae27d78f7169d905de4e77862d5944da06d370dacd72055d4a4095c35c93423f75fbe4c934c049e98d5c7a4241fbb8c07df9951581eb6598c68d075ec6eace76f7deb1505779ba5351cea86d979df30299f391bb27235612e0e7f7cbf662a6e16a5d7ccc4e69ddc851bbeb72ec04378ae60eb695f661a9ff67cb196e5878c1a861ee7301b6465d610e3b863fcead98edb1da616d4e10629a549ebe0e9611b03306f42d8ee86966f19c4f9ad392adee2c86f53e672355206cbc49cbc681c70ae709b25b91b11f9b280c41eea68e804bfcb2abe24f25ce843a214a5d157d8bba538894ded6a962fa7b388d57e03e71b4bf1648105de42a06d4324e0d5d57583ee401d9c0f0aac5f747ba80216a3bc9aa1b60d5d08a1cf82df9665456e575091604e676370353cdcf211b5d5656d98739baea8b9c377d147d77374dd038ae49112126c7ad40519f70db7986f30d6651402c28e0db7d6e8809abb335555cf621d7b606f8d27322d57756c1de6010ed4c7459a8c934a6cd25519cd4cac2a55ccf5ea1ba999bc48f2c2c2068565a0b1da00924b889bca7209d19b20165eb0be50f0ca5ec3edb235c21687ed6a8745050baf25b926c1bf53b30cecba6e00da159f5ccdb557e8a7493653455271fb8ed61af30eaf2883f1d619d341f545912f7a9ab194acd0741953f67419b37423f8605e9564ab1e25392bd38367fff7f4f0e5cfaf5f3c3ffd66e7f4c79747a72f5f1f893db1b3fde76ffefcedce5f1e7fe3abb290d25f96ed8f5db16226d51f61af59859a9a8fb0876cc3c36bd1171fc9f1475fac1aec72bd3a1fc5830762053f576bae06309ace85caaa17f3a4aa54e1dd16b35b372d1f1c9f70fb336a31cf063cc85b3b0ce466afbfca68b12c67610cb76b5ab1f964c2e14c261b00b96bac32c2505aec2275d664403b0324502567281a7662aab88ff2a9aa1accad013f41bdd2ab57aaaa9da94bba4444d767f18f49557a1695787968caedd69055b718ad23c48d0fb3da17f5361b463be486b16ceed215446c72919abc6b6cdf84de95796a63d2e09378f355bfa1006223352bda74fbf7ad63f3f46bbf8633b8d335619dee431308a32b4ef7f3ac5cce75b28badc44c4f28956e805ba7a7d88f1e9e5328b7a7cf53d3650c568aadd353ee9bc9348b07fefec33f9d9ebe7dffeec5e9293a2b7413745ad71efb0caced02539d0621a274610bc9140bfd3f9d7ad12a296ea4d863c0c8480279ba35b28097f35497d58c14ae792dc7d519c1290b35c8ec2818d59d32907ee03d10dec49e1d484d176fc3054e55b5ef66d38b7e1c64d59051a809c385e913da44c00d79a126c76cf64fcc864bc3ee1a10c28b7769a2d46e38287dc6d5aaa8c778bcb07641b670e4dbea98a1e6696c6c32c2fa810b15c34f440d685090b1088644eca3dda04cbb5d0b3774b0c4c0904b5f93538fd81f963666a70dab3e7c1cf3b4b15453ffc4a0793ff606f97956f0f88fb6ff769b0fe64173a3e88e8b15ec8a56d34006e2c5c7851a570a43fbf09d46cb93202f6b06d5fa66a7374a2a91649582780e2f296e5b81a4170fa05823fbf716697d3aae70f6421cf122f7bc9768e61f5f51116e7d1eddadd98d4483af27d114cdf6d66145fd48b57e1ccfda22a7a2863fa174d4aef164cbbfd88e5399871fedc60dc9309fa6bc901bb1106e78fae1f1da1a2170134eb3efdd615f7abc6e6332b0f8c6f4b8616732e51a77a6c7b528fededef4f84e9bd3637b9f5e8fe14805a60a2587b67595775deb419467759dc18de219b1dd113e2c207e6500f2d4ab60d5e835d3f64a3cf09b685a4466bc8d11db6f1eb4f0fda5f0c5d4b03f9a8912cd9bf663b815c1495ebb6b3ffe3d76c7068c3b56c233769d0a2df173c45e00c1b3d6b9baaae7924ebdf90837100dcd869ce9b1a79f329ad846f594677d26b840407cc1e30f1e91ac2d15e519823074eebd83db805bc625ff29900b0a468a0bb88ec628ffaba37832d980e3e67e9b651a08b4b4743fa77f7c776bece6d4f3cb5797bfcc7b6176e6ba791c77d877dd01b26107c697c01459d53b4ed43665c37ed66dca963d8dc3fdb8e92468f6e3a6bc9bf6e335d53a0d6a10b3590fec2fd20d180003fbcb3b7ec3e3882c06b9a1e1d533bcbdaa9d9b77999acd58a603104fcf7617e5992ae76b15688d0fb6efa25cfb44433850f3bc58fd9294555eacba94f82a47e3afae48e957f9ac502ffe67295353e4adac66564538c3eab7d6d151211fab58749e6449af491bc0ea85afcc01bcf7d4bcf15ddb263c5341567721abd9510e4e8b170691b29af5aabc5740a287cca4fc0f99263105bb011af7f4a7bd84c3bec58bb94d9ddd549bb532cb9312a497646c300049bd2ccf08b778c34aaf9ffa7d71f4e6f99b8178877ee930245dd302c8b331b89d1fcb4cc8522f2022c89def1f990584355ecbb96ad223d473db99ff9c7b6c2bf92e0770a153ae6722b227ac5d08f181b15d9ad756336ce10eb3403c6fe8d370eb5dbeac5431dcb2c166acfff1c572942663f1eced4bb891582cd17330ad0574c1849db406f0ba7d04d8d03c3b1b0032ef879aabe0788080baa2569a5832e6c366bdacd4bb3caf0ec07d60b051f3bcb6a6f08c3f74f119aa80553110c3ad3ebbd659166998041e4dca81e6f276532d5f7c94e36a204c1bf4f2af3fdc1af27b0ceabded230ea32128a5af78b36ab7001bfe7d0ac0f08f36a79e9db01da8617c03ac15d1b44626ddf4d9c610494a21c528a93038e10cc2327e50e8160262d3caa21229041204c69817c287d5efd3a9a4142e6406441031d6f336e2830b032cb395f8e19dc207184f4a0b2988d286f201c43cb675bb64cb491125f48aef2f96e50c02295b405006253c70dc0e0180c6cf0f205418f89832d284090281b1becbae6610730a9ead214d5525249a10d0b879a8b61f709e9fb0b0e29137b7d169521e507ceb3d0c11e2cde0e9428175bfd9bb9cd1279662a14a91ebd11a673213025a66384bf430924d3d2433e5bf19872712ea76c20e379d2dd71e2d1de5f9f4414261e7067dde5a6c18688d87d29a91414d9d7ccddea91a5532b198f0481a6a6bef7806abcfb6353df7a4f3708c9e21c71a043be4368268c287e3494d5ae83b1f7f6cf70d9d7584f7491b5cd0e6cd223f4d18dfae491a699b7dc8dd74588c98c53b68d2d041e880659a7687fc866cc0e98dd686579dd2ba6bb18e070e93c8ca81f7d9c1ba9dabdd5039b23b1603e3ad6faf6b5e4e78cef2116ff0097dd112441b511becb31b95d6be8f149a2ab7689cbb1aec819b0c77e881c8b9986d71bd49458945030c8415f838c3357c83694fdb1a257003b85bba88317a7a0bc3d00ac8020d2424d0b7d2188daf2862156d15061f4f34663ddf2ed7a1dbb506714dba1d072cb4342855baad29c9c41c8e46bef486c7a5af26c37170eb25390b95176f6f10863ef33db97b3cbe7debc7e3b77838be513423fd7398d715c7ba56f094bc5174b324d474a2e537a6c173c2cd5b1b47f5ba0dee8b98b299746749e1b1d290896e64d49b18181fc8d764632182426646a2e78bac2a1255721e84511cbd522fb3587df4d81e86b0c7425355bd2f55b19f6793a498d34e520b69ab4b9eabd52ba0f0b5b0d6f1588eb9e6b9df2ccfb4bf801dde6be67c3ff07e3c21535a34bb37344f7ee072b0d7b591e6190cf0c506beddacaa8298d7f51944fd5132d6271697ed713859bae2d17a3e0bf14cac75ef97b3450beb163cd196adadba1abfb9c55557132bb02d7c6d4137b03dc833c8ef887a1a3fc51aef8debe5d25bdae4366ce5b51e916e5d3424867d62f68a9bbbf76562b3ed049608bb86a9b7c2d7add9b77b48eeb3564b18ebf9ea26855191cf172ed854a90a731ecee445329590252fe50a75775294e342a9acc19dc25b8004be3d9802cd84e4449f21117dda0d4527ded7477d5340ffb6b92c830aededd1d2174f3190e9c0e5729ddba60388bbd1866305e39ee3e0307ecfa8e9bec803214a8ff4a2464b909a13fe80e87a22f2655526b162a22072b89b1c0782260190024ed87068814e21a41c3325d52c8fc95da3ae65540ba3341f9fefde283330be68c506e2109ec127f29952a5134ff30031ad0b952a5942a032e84d9b0883dd52751d6c5cea1e70621e1a185ff2a10ec4c9f88610f59c99c67c9d05ef58dbb747b9659fb92e83771fd981df7f622d1bd1d36e4207b53a303f7cb1cbba7fb8bb2cc5962b5d8fb1135ba6de4cc017e57120f2b042e83e8dc2da217d37c9649a68b9e033ca7373b80fc776641ee0e3b9b2b6dd43a046e369d526bc4ae6490566d6dbdbdb3c639fb8fdf66ecd414692c26512e89e99e535543bd689277639b134fbde7baa3255c82ad78c9cdfd944041be1327703ac3f3fb05e5b52608d40803402bfcb72a1f6a3470d86f7bc3873a4f9d667fd540a18bc78ffee95d38913abd7dfa06f0545baaa54513abeeff93007400e815d52bd3344022cc7be9d9c0ae9a8810f7d232090e65a98635cecfac3b76d0154cdbc75c2a03ecfd442d709cdaaaaf4d907e3b2b3d5b4610765fbe4a2c8a7859cebc3c1183c84c0dd9564ce30ebdba6519b871b27e99d62735d02bba397683902c887905fe5fece0a9a74cad3bfddd588cba0427c67c5d0d70397fdcfb5b5da9b88cfde5ce179833bd1fbfbe43a1d1f2be9a5376dbd80f3a7a60d981b31b09f7411c22aa64e83ee5f8eb77d3a796a6c67354d843e2dbd755ae55d9fc622b36607be97315dd0bb79d32c621002b32ad03550cd2e2506a2ca3b7061f5410b2f28ec628c6d2d5de2635bc22361badf07f7def6eda7d58ecde72a4e64a5d255c4f5f2eb6e5668dbb61726a1d53a9393c21b882f9783bc4d7e6d4fbe5cea312e995eada5182713e999086d14efd58c2dda1c5cd7270eab3ef745a973b51a78bd88ced58a49499d5ab0e175086914a9aa5c53d157137c0cbf681256f4ca5c23ace85d7250137f4c24a87c7093f844e56b7af193ce8d22cffd9d66a107d29bc51ec85a2ff8dcdfa19d3b5fc0e4f39d48c3f81534b2c32d50e65099486531fbc2d8e53c41652538deb562926e629f64361ac8b1010f5193dbf5543d50e70acf420884b220ddb678ae56ec811a3a2606631a5f4ea3c1ebd20e05ac4ab94c2b47140862407f9dd6af1cc0fffc90eecb7af7773c69effe8e2707ed7b321f365a13f8eeef348a7cb6f47a790feeb51aa4bd2a2759af51b8835a5664420eefd3083c0cc1942659cd6605c21a7b27cf6bb31debea2a785a66da6d82cd77a881c920165153aab97af4abcbab83ff52a261a00b2b5351ea7df5518e2b5e0c126cb930db946f94b1bc32f5a66855b1b6308539610e0ad82a1b9b0ba0b874b368bd264d2273ec5c2fc6eb6e6ebb9131e03a35772de6c0e449f565dd3d2ed0a78abb829ddc8c9d859ecb070f704e91fb336fe26cb7b7514d55dcf1429282fb6927859d3286492e0e42f669e95065f140f8738a281f8870020d3606eea7d9db3ccfbac4b7782f228f0519361416d269de40e674a8c0da91faa8c6ceea8a2b9828066cb3226959fcffec7d0b7b1b3792e05f413c1393949a8fa61eb6a5285ec771667c97b1bd7672b3fb495a1b6c826447cd6ebabb498a8e75bffd3e54e15140775394edcccceef96e27a61a85025028140a8542550289e0cb68e686b5851bfa4297e9bcae1d5255f96129296c1cb196399d125c35f7efb36f14785d47ea7dc39c658b0e44c806cb02431d40cf3400f88e79a7c6fbf7717c8a6dd863f5fd447ef6512b66618b2c2f496eb15f5fffac018de399fa4131ac67a29c899cc9c36456a2c712e2030a241b3b36746893f359b312c43c832d2c40975f4fe39c67e757620351ab4c38e0e21c2069825ecdfe629e11ad54eec18e30c5135e35d8685c3c9b2f4af4f6ce45daf0625859a955592f020dd9824266b30a6ab1e289aef2a3581978e552e74800c963fa25b5866b93fbd7bb5f8fadaaa1e9f5f9130725c6ec9d297a873614c904ef74fbefe82b76936b090fa6f817b0a0643418cad9c585d2b7e0fbbee443fc72a22499fcf43dc6e8d8644ba63fa9f33038fd99be71e51c2bf0f42299ed9d9cc277950b35e791a172be71158b1a2b08512e8a389d26c25a8fcc118fea17c609f54bf9a0ee704907707fd8051d60fff44b7ae33fa15ee0f86f1f3ecbec42144d6b7af973f887185f24193eddf2523177d0c7e6e6b3bdf2f873d8abb814d21d8e56f74d25cd65fd3efbee0da486f89ef124177cbc31660d2bf081f197856ef6c441a8d6b2559f2bce620185ef807d520f096a9dbaafb4748461e7fc6daa3807f0aaf366d5bdcdd9006f3a5e63d0b33f9b264980727a6a372e7a67b482710871614d48170fd838db5068b35e28287e04dbd12b783980810379ca84dc7318b874305e1067e00dd966d57b988015e8a9008fd0e209785eb5d0a3410544369b76253fa4dda3eedf37cde8bcca6795179c84404465711ee07d9ac7a4f18204ca907d1a2935571c6eda377641db2358e35a52a0997c675970eb56ecaf840e09ffd1b60caf3b7342d8e371032d8c4f96a9ae98e4b196a5a60066f6e45f72c85a6b62db7d3dbfb8abe7ae9e9e3b5df4a5d9d866bc30337352e345d1980bb33e1b26eafafe23261fac735b26cce729e6f183143f36066e0b021126319e005a409716c9041863b4429d0510f525531b5fdf98f5cb884552a06a5f6b25b4b2b8f286d05a7e3ec15608c2eee5a4edc374ccc4e0aa68f0512387ceda6eebb3aa5b78e1bbecfe431cd3ea5e8dea63a173d8a87b5d2a01bd7d1e57d35605c64efbf7a0c3eaaf0aebf74ef2bd1c566c4d4d78d53212ca696e5cd1b4ffe9d44016b985140874673ae86a7f3c1168cac2bb0eae7e9e75df3f7f74bbac963fc8bfdd2192519d25a7d81b2073e112b09656ddd509b1a014534eef70a8a50972a520257fb5b39cade248407047dee9314978e55d9b6cd0f89266ece29e7954740f45afa47d3913a9cd5d9ca582657025b81c15e2fd123263e203b2d617e1a06f1aa8f379c47149e390aa9638245773952a9672f2889f41289d318bcb5d09530de5c6c7e39f051fc7e9f44dc20bc7dd8598596d9ed63a370afc13ad12750dfcc00b21cf37ed91fa61af09c98dc137bad418f59c735c5dbeabca65a3bd8df6c76591efb3cac1cbbd2fb4d1f9ca3c5e7c91cecb13d4085dc51a3b666eb42addeb814deee504604d5c982f40a46a4b2ae3ae6c48675b6e200e6ae3bfbefed97f6fe82633b50777dff9c0949c90b7fbce85af3f1bbc8ca3bfaaf085783ffc624bd275ab137eb649433df4f9b640ff9deff0f5ba3163048cf6a6c6a4d1b0f64c8ef95a435a992dba895889843c0e9204944d5fdc335614797aedaa60fc2315c636c60cc2180d9747e5124486924a70ac55e9300d03e8f060811426bf61b6d428cbc705203253a55f02836b8676d851afbdd8af85982c1336e7719a6c60a714053a93a5634003315cf2aef5f0282291f23cce0adf104809fc05ec8114dd0e66410afefff97b2682ba8791435fa1a3d8d6e7c6f429534fb9c3895fb2b6154517f75efdfae6aff6047553db968ef8f0059a7bfdecd5cf4f9e3ebbadc59ff51beb3a39624e96994a20db84e587248bae3e05c94e6fc0287b3699972d1568376a69c323879c55635fadad8f80fc596f619e75ce6c98b6563d2441406f89d5cd461d6043476c700ed7a0487dc7d0425103676bd34efc7ee37521727cf8b4450e89281769442ccfba9458afebd521cf21cbf078c7438417ac76ebf51bf8c40725de9c0f7798f461c3ac0f779ff6e1cef33ebc65e287f5333fdc75ea87bbcdbd016bea857f4ba1bb5163746f00fdb3a32f1192f4ab34a9c1ba5bb25d822460e717f73471a52673712fd271f603e70072e965d835ceb0f6d13eb0e55f7341c373db8f6dc71f8348bb268d98ed134e87ca756e91b8e0e421e4d5cb5724d68b35b335a9f18d8bce718ad60f5fcde61758410ebb9303a0762c0333cd4e3cc5f5e2de34bbb8d721103ff0e8aa0e4a7e77217fcaf235cfc775c0aa88c263e006a77bb8bd190878dfe300c0ce45eff5777a2c5c9384b8fa7ed87796f682014434fac14da7d6124e77be2f6910f77754df2eae79a6d1b9336a0a69b0cde67b3717504a8e7a0de01fff12d83907fda35e023b67831d5f026ff153b0a711481c16e74569eeac210403bade146ec005bc0bfe12471340b4cba10400ff30670544ff2feaad50e3abf047782ae80bfe7f94ab42bda382322806c878a72abd8deca0e724a5d23ed055e24194199e3a3bbd499c8e6d18e07e1f6379697b8182933b7181fe8265c67892a059df9a38793a666ba1d346ad795a128c65c6ca3c9e4e21c72a5be273c67e2ef0453564c759677a69a904548aafb4499d60b3367c5eda6caeecd7d73f17e43ebe9e224e3e027b2d4bd84a7eab3c0d551e22368f376277af1f555defb582f6a152be65ce5351edcdaa0ba93b88e405f26d926773a7ae765ad9c977c47103b158bd9718d421927ebfe9108f13e36f624a2fa86388a3be69d702b5c2932c350bdcb0f2aeae288ed34dc52585264f6fba2cc735fc4595032319ef1818a9f9a2d7d9cb3dc1fb2f7911a425e3d79ba0cfa1cebfe65590d68d9e68cd68164f6722ef66b914cd560ecb2d218a54167916cf17f0567825a426557dc5ba8ecb99b2a0d6a5617703a45edc23e0e8f9ba63ba5df46fedc053618dfb295d2f4f6b4274ae73be5888b1c1f41af2c0e074d79439e7eb398f2593e800f6db4fda4afe9e5fdcab41eb1ca9ff1b6949303f7452e40cb0fee7a84d5b464f4cd5de2993ce84f17b0c5cfbc2e4a46eb2ed8ed2e078f5d40be04bfe3ac5f2bf7b58698268f2d0eb6e3b8d445cb3cdb0ba317cc249d277daa227cbfa7c7d345473fb69c09cbdd43c405c16c23e78c639b49f4e894c581642c73fa38100ee48a36ff42331daaee7c8d7f9128c3f5f16a5d5bbd9f790c4f6218b5386a2b1c4532d1dd52e0cef92d80ec22c637dc4461a53ea195bd5ff2cf2d9617d19fa91639547c057f05ee67f18f9f4a0ee403cea105f4741abfe7b4afe9c3ce16727f880d3a331c87e1bb7fb7f16adc9e03e81592bc73887f9c9594ebb0b6f9b9b4f7cdb4e5ed9aee3749cad15a879a944260002d924d98827ec4c4193277b57ea05b84a34fb16fce1f2b7a3659c8cdfbe55d15b94ef8bfc26b74f675b8b7e2b4ed8c5bda7d97c9ea5ffeb0d31de8b622e4b9ebd61f36cbc4c4441e3bacfc7b2ecd7bffd4843b4e32f3938ecf0395c9adfbfcfe89f385251ccc918d5f343d4a67fd0fd6467a4cfe704c7a563ab294494a5639e6f1a2aaac62e311e3b643178321eb3244eaf409fcecb384a541e7271bd48789c8273c558943c4ed82c5b03986428621b4932b82d614362188146a969a492341c389de7c254976a3c287335a3009d0e70dacce9cad0aadfa9c13963c1a7aafb71611ec6e4cb34751aa85017d0ebd769d00c3cc22867713a2dd83a4b5b25e47d67793c9d953d726baf0748a7d54caa5e726e6e61379a2d86a10a4c8c8780a9d7621ac07516d1f659ad50f382bd7d8b854fb5ca49239f04767507443508e83e1758a91db8422520e72660eb7eff4facc8967924fec6178b389dfefafae7334c9281cbadf75bd19bf3052473d127b9377c22e4c113b22d195199322cfd7b9c249080475d80a9e8f7f6c1e604d27f63d0e63d96953391afe34290d4e4231e5d61967cc819a06a16f05e7599243dd3d6bfc14ec17ed7203704b8ccb08f088812b2b0a01f25a61b75b0f4ae139fe2d87e525ff57e7ebb3f8ec4f3190e39507dab3f8e2bef01be9a7778e21bf127ec1bf21ee8a6537dcacba328601337ec240af109e6a13409309d70f3ae0868e967104f54cf993c0804b8fd0147288b839da5803e6ed5d3dbaaac46d91f1e45269597f14e9cb89788761eeb6790f95e55c3ddddaa866a1a87761e876a2287ea4fc7b78a78570dabd339bcac7b9bc5a3c8bf6021892a278d65f56fa4bdb44cb5bc7d7a2fb8a7bd479f172fb88ab0a0f2fab75bbdfe5b5ad4ead8e0c43aa91885d59f5b6e1cd0bf8812cd3a293660bd774bf6ee4a6cdec1151c1e18dfd1e59dc72b5e0a67adbf04a81be51608576eea6799b1f74ba162971b783ca8de803a2181e5bfeab9bc8a8e556672383d4f50ecddb0d7ea37dcdc11f91597ad420d25c05c14e42176cf9729535122f1da3a95d795d8d43c1b3739d928185592e944e8e4e88f55f513bb90f4f4a36ad3432e28b001ac7caac4f93730e4a7339e97bddf0ab61af61ef50ee0dbac2c17c549bfbf5eafc137bbfcade865f914cada51870d07e1235b51ee54793c5a96598e0e9daf319ce4183a85f72f7f7bfe0bfb398e445a084520227e70b70dd88447723703e228f963ba2fa51052a605ef2eb018078932ca50a02595607ff40ab76955ca0456e61bf6bb0d69a318799ec985daea9cb21b1681322e24f00dbb69773aecc4f40d9bf33304dfbfaf0a7a7c3e668fd51fedf396c2dfbab4c6b5b6fad6b1bdf852fd3c851b8d8bb46d346cf5e3e34786f1bcf0ef1e4c232190fa8cc8c18475a3440e8dfd80a5ec77d69247177cbd8509b5b0889d31f5e3fe7df5ab37e3c5cb75aaac989b764b49a65607e64b829c9b6f97ec447d3badf10b479dfeb7e26f30cbed491aa80907d6b928f5b112b9e38cfdaef9489e29a5a09ca46d2c0c3c4ee9f81f2a6ed553513efdad7806a53fe5d91c54f1058f046ba76ef360d44fe9983e7e64a9135c2b4bb25ce9f5bf5fe4b2eec53d9ec49118254b7171ef849d0f0f07011b1e3e0cd8f0e8e83230406919bf5f8af52c2e15dc91843b380ad830a470ef971cca0780c0c7f27ec9e73c8f53c4110e1f68a87048a03e2c73da990a9a9188a71a4096c17f8603021017eff578a0f6f061c0c247c70422017724eca8fc3fa7288d6662cc9379968e091218ec80f643130d71b87d4c96621567892871a8070f03767820bb427b9167eb14cb8f8f02763894ff23c5cb3cd9acb34c7562380c58f8f03060e1016928e263519a9e3c3a0a587824477b4c8604323517cbc2a7bb03934559c2f5f48683808583a3801d50982ce789a508e079e896a793245b8bdc74281c4844878f24fd1eb890459c5c11f202cfd1598cf2785e64a91abc24f02060ceb0363c6d66b631cfafbc190a0f1eb9e5144378f0a806629a256391e66a0e14f9e57f420f2ee71b3593128dfa8f0f23846d6ee0b29d02b815c9d58c5fc5aa33b2fce181c4f5c0059af3a9484bae58ef51fde0b3245e09dba78747802860871eb22ce7e994aca6f0b0daf32c8f66b1a2d1d141c0403a0c0e5d207840487ae4e12860c5613b0772541249381c7a5082db3e877249850f25bf1f1e78709297cdfc3f1806ec38ac21028099c93b7c10b0078fe4ff6aa1c476a87299bf5f667161586e383896fff1c0a858904c2f011d7612421e8ee9da8035f4c00529ae3694bdc347a1bf00e2b9e5cac1915acfe1c00711db41b2f194ace703e8caa1d7d424cec5288f95480d1f3c0c985c240784012689141e740381050bbb0d618449968ba2b4330c6b4df28b836b19cd8a985b3cbef49df2382d46599e11e1a1fe4380665951920e8100aaec7c5200900e87aed474c5c33004c92ba526e15a3b09b00da9ffd0722a1664f1c02bdc8824c9d68ab6074ad8517eb09358dfc42c4bc5662cd6feae4a293fcb4a97eb9017a87c8fd371cc53bd8c87b2fcd150fecf059922d91f1c29b94331acb27c43e7dfef85156fd84de4370290f015b8002839a16186473530a36459cce81603dc764401d729912643e0eba1330189986769348b27132d9b2ce3d27592c4d399dd87719ac263e89d074476d1c341dd6c2194de9a86d82b7f7b0320c37e8443b06bf09fd06fdab0e2300c41ea78a2470159f12a9b3e00f17a5885ba1d95c7500fa506f3e8c003a2721fc08e7db98f6054f01f484c52cc840ffc3152b918a2ce76ecf307c039923f0c61f73f96db4ea5838ef4df0a590a9110263806b553ca1d7f34ce8499953074a83c178e763370cb2c31142fca5d9782a422250ca1569305a03a42ad109df33ccb522b56dc1d7b2ec6f172ee6bf483a1ea8a332f08ebabcb74f52004d5221e1e07ece191c75408b658e68b443528f7e23094ad868f7c38876380a9e4ae1d8607154047570887a05221eb574017799c4e1d910df40d8f0e7d50571d78009479e4a94508891a81518f1e49285056684fe371ea889821700d8c9e42a5a53cb3cec9f148c92b0a54949b3c2bfc13d2704867248b225ec4a97f8a7a48a623e52bfe5be6efe9704e7970e0806da8164e655d968c131ee9ea07fa34471915f4546f77f38bc7391f290e940c214f52f4905451618fddf584e56663932052f976200c6be22e8f3c47a672c113e1a90352720e51540d3c402b63e57e333c92d37d3474815c060a1f1c2961ecb0a50474f96708024af6cfd119177cc1377c3d8b17f44c0bac46e66a2178345b2c2713aaf3c0bc1f51a07c695580502aebc714872bf51f01e7d3f264a9f813b8fc181433c2568b6c3da647c80720410f3db6a05240892787b372311251c42998944e48e9030a377664206922cf8a0d39a3ab738677d8c8b30db732ff582b4ece622af8789c08824ad21d8e778f2810d9078d624059ace0e998746828b7e7f0f83060d4b4e148bdc363a53e3f7ce0401433912454333af2d8aa88459aaa03a49c20b97553cda988939552c26082f57f0844fd3e4c97a5277765f9237f67f0b7e9a1260cd548fc1dba1e2875375c5f6bac15ed68e62040ce0eff00f55b4f4d2eb5e6166289a7c19642a97fb5ca5f398b8b32d15698637db00bc90c97d99c97991d8adc2f1e90f5e3ca0dc91fb87a06a419720845050f356902b19e095e926d04c5fa230ae09de57c1515008a79765531d6514eaad584067e3915988756dd9140e83081f6cd7425f242c53eafb7dd129bb2b1e0f6f7e0c220c10b0313bba1df672f5efef2ecc4c1ab1c48e182513bc2e4f11ce382abc8d0edb8277a18afb1085896032aed670110e064309555a22ccf4554b27768e57fa742dd179d1ea9a5dea82c0bc146d9b541029e95d8d80bc8bfd9ee04ec0ddc40c95fa28c7a1d4d9b5cc82188ff2d36eb2c1f9b78f5e67ef24a40940b632256b66508f0afbff926f52bb1e928b88bd26be0dcd4424f1376269b905355de382669495ab4df7b572868db9e8e4ed8efd18ca7a9488a137610b0848fe0672b9f8e5a3781849a154923d4ac480cd46a0bd44a43ad9b5b9cad758bd17c73e5801d123059a8e0ae371f1ab15d6f3e28a88437b79970dd6612cd9aa1a299eebfb876a0420b75de9a89ebd625c25de14435c32a000dcfd3220e8f9bc1b19c420f8f6e011f1e19f859346d1adb796bd60a582b92ff991afc8b45229a6be4e13180e33f23db2fb99334774a96b62e6fb44ce9f7d92c1e0bd6d3e0f07ca387f0e0628ffef16419cdb3b148702101633bcb08bef88b086ad86504f197da2ddd628be03a07d04b0b7b51569c22e67151c4e994991eab5e6e4e588bed63f7e0b6bc8475e8b489e3facc16994b9d5bdb755b52b4d52167bf393bf3ba62a6625b977457e46c01420621d80b368f0b151fb8b953209534f51a9b3fb5c06ac01550fcae00c72211108f6f1bb67a20070ffa23f4f096d7f0905b432e16cd3e01fb5d85d2d59f6e3a7743a5b8c222c20f0a8d96e59ab9f3e9a8372b12e791573e1da9d9828d889db17c3a3a1f5cb2bedcec4f75c15415847ec148150cfd82799cb233f6375ece7af3386de7019b066cd4b1e5fcda94f3eb6af9582425873c0ed7ac2bb1999299f955985fc929b208beaebc868bf8799c1a469ce90c44e50dba6948c01cc1f8b503d69eb22e1b75581fbbe0579ad6561ab27dd61eb12ecb1b2b8e6a2b1eca8a39ebb2a95711c733a3349cb13d26f5fd83e341878c77c6be53b19f11e9fe9984a058e494b7e584ec63fb7d36bc855e451dbd12f6dd191bf48e1c289ca73ea2d90724b45e1de4504ea89ed60eeda852dace67012bd81edec325f8e3f2544b7e979d57dbd8791c4f2c0bd33f46f40f8fa1befc5a586de7f4783261676cc5ba5b968b048a9ca14644bb03aab5258648ceeeb1642589759f857ab2cb1b32e5d8a48919ae99b132eb74f664953e5b29012549abbe46ed5c8bad29fd3ad55f47f4eb48b32ef604d7e08aec18b22350a36ba7ac6605fa55da72a4071db60fb32e97706de5517de5a1ae3cc5ca39a96c3bebae34b5d6c26a2333f63d0b1db82e81abe1773d057b72e5069ae8b800d466867fc93f1a56c27ab49360af61e31a06b66bc3ee9d7aff00d414d39a9d219f1d1db13d8787cd6f60663df32380ef56eae0e230bf9d3a4432acb564186d930c52cfffc7ec7491ddd3ccaf8df975a506704525b91c7d1e0011a6f88f5aea11727297c92de14aae65f8eb0ac26ae0d29c6b906923c846838c9a400845234dceb9feb1d13fae7c021bbf6f218c63a0487bf3de3abe8a17621cf35e964ffbf2affeb36594c463c1d3b7e3b828791a893fbd79bfe4b918bfad160156d7ff3a9b2f38befbfd5101b5af03b671fdaadab83a80b08b6cddbe9613da659bf3c165c0861db65f290fb13c6c2a1f62f910ca65a971a2a5dca5ce5fdb180c8fdc63708b754fdff974848b0704a082f3a5b9fe4eb747e0360ca8f934c90a51949a34ec8c3d4f27711a9796f35c48d5ba9a7c6a5a8081d498176e3730c89af4fce1a43ea22606097869e4fe45d9efc30b4f1d055bcd33b3dc60f18ded08eb58229f8e026cb3e3e19f89e80a5d740b9688a208e41f4506f95c79c122248bae81bba26aeabb062a93a15e948d13a1d19c36c1fe6fc33c5776524ab2d7d46c114d93e90a3e854fb2a8c39a7aae9cb5533b4355417abdf9f087cbd114a68c17c5722e58f1fa2f3f40372520fb9e0d7a83c3c1e1117bcccc326db773b62f0b8e8ea4740be147c086bdc30e3b914a459f85c3dea3210a55d9956913a2e93644531791ecfaa809d1681ba291834851421e80da39db6383de61383c94ea477b0a7f1e1c3d38eee09142fe193e1c1c59557063ab0dc3e131a9f6203c1a926a8307c3a1adf6c1561b848f0e48b5307c44ab3d3a52ad914de2bab2377cd8b6f9267c9b32821ce5f118c09c52d25c6f3e502d63a33e117de583fa44f495c4fce296e3d460ae59ff8c3d3aea0d0e1fa86db20f296be18f0ff8c7c3dec3870706fe8c5de3740f1e3e3c3aa6f37d1d30a5709eb0f683de83870fd81ebb062a8652fd0ec3e38ed98b370d48367548363548e4403f3420f95087e44315893e0786e131b6d265e1316097c7eca3c180edb1b63c946d2cb30ff1eb8675d9079f259280f1808daa0c302b928a009a15096100a954ce8a0485863eabc2f94b1580d0d03303d3aa0a867e4119da9f43fbf3c0fccca7237b0ee3d44e507827a015b8c6cbe3a6165776b02b9ec03603ffb9a47bb23a183be7e272a810b543b6cf8aba03b102d96705eb026841919621d814f658c2ba6a5c686f6767d62bfad4d9c8637c8c14b3efd8c1298bd5032468ea40124f9d050fd81eebb66339f9fa78064fbc0ebca34d7900b97ebd035079e09d6cca836eb7ce7228590c70868e7a20095c4a9ab4cba11c59d8617b0c61aba7a8e1161cc32af881061fdede249ef7e49f07d003175ba5b63f42b97dc52a9325611777c746c6ab2e0ddf64d1b4343e635114687c23e6316a8de3d7ed24805dc0cadb6265178911167b67ca7450c89f68fe093bec314bd80993c444610baded9d6123124442c8df0ac8d8ee1820910bc21825801698ea74c01ee39c176088eab37682262bfcfb4415628959569ed168a5b7a755d3f6342b5635d269559982154aa78a705a55e761a50a2af3308b35d1274996e5ed59877d8bcca60026b032bb2e8ca9be904200cec72b94255d2d4b64e9fb6a69bb607b6cd2b13065030cfc9a743424ccb4d1c40a8c38d99ec5662145bc106c70a2d785918a012b03b6b83c25506105ea7dc0563ed4b002b500a8d2813aa88392e81ca8c30a94ec940f7554d77b89ce48f32a9ff8c6f2263ef90c1659792b73e5afcc849abe8bc45574f49e3e04d690d30ce56ab993cf1a090ca8f0bef4cfd45a33ebbb66f562cdc41a19a0deb0660d268d96db7e1fac0627fdfe58ac7aeb0330164445b186ff76e140d2ffd36c3dea9659379f8ec86cac47d555bb1ef9b3b11e55758ab52ea94cca28512595599187cc8c9dc9bafb6c64891ebb5212d7b0f995daa38caac8229e966c24e4aea99505c44db7d1f54c9212be2b8e1d25ee17ad6bb8e2446e9c5a5c28939aeaab942b50cabad867d5763b66f7d9e07a109adc2eaa0b13557f429b4b3505265264ac5897ad671d083091c4a9805816a5c8175982e1e2ace5dc1e025d1ddc88162b59d483b813b2528f4f1ca10347ccd5291c28d353383eae67a76c940b7ee50a1e804c1172b505728890b28c80a63590072ea46a7e550379e8b40ecd36401e3923d2904eeb9e7538471d236053fd63843faabb5b34df5c55168afc48564a240f5ff3cd152e15caf6735d52592a1b5d52592a57bae4a0b2889ad8409ded437ae111062cd21bd3953cbc5cd9b3bb0f38af031cd5006e6a003f8daed79b0f15b25e6f3ed043ad39b1d6900ecfad5e813dbdde91706d791a3fe80d0f0778f897c3ec86bda38307788c9747f3eea077f8e8e1b1252254ea0e7a8f8e1f3e32b5c2dec307470f4da5416f70181e597a421db0693cb00d0d7ac3c1e1c0d4097b83a307e63e72ab156770101e0c1ee25278ccda6d309268ebbf3ccae681442795c3de61471e50d19e8235e4b2d943238a6a8cd8756e453ddd8e7aeaa126969e5b518fb6a31e79a8737a1160f6fd41c0f24ea00f65d32698a9851935c18c0ccca7f3ba6fc069e2f51a2eafe16f5769f96a9df9675a67125e35e9269c6a526005e1ce5d21579fbcbb42f989cceeb5e506cb04aa5f1b7df80b8f3b38ec533d899cf56180fbaada0798932e1bc925351890e312445ca1f373402c864ed9b553f6c129fb60ca60f687eecc6d8672a636407f353faccf60e64c8fafbd3ad750e7bab10e308857e703d4f9d054075adaf316c41e5d107bfe8230b6da806d02f6a17eea9368f6474cfdccee59d69b22521d9b1991c74b9e0ea5c0e43801a09ae778ed2d679bf511eed5f3d3bbf8b7441a7ff13e2fdb9ced312ed56fb6c74635eb220ad8ac8638d1ac22f59268e613279a51e244ea53e85e98cb4f84389eac2304d3c499e199454a64bdb3200960f547fa5b9415ed596e05802928e25417ec2203f2e9a8872ea1ce70218e907bb503818b3ca701f8e6b1037c2343d6b7802124f0d3f18ed86312fb28bc64279e6bc10abb201141e68062c5badf33d5d36c51c6f3f88373d6c046800479b64cc7180b07e409f5905280ce894711e9c0612498adb490e7ac8301c2edb3769b3430c24bab0efbee3b753f7c517e6414624a2042034100720550df436bbd848eec9f3197d7752aa3b4886b6d5bdbe7b5df77e808c9194ed95a98887a5769b686283dd8239e8ed91882e4a542e8f8480a515ceae9136388a5b584a880f67ad167b6b66783c38e059a793a8d7c3a3cfa2318559dd431e3851c32467d166336cdc5a6887822183cf52a05d00943e629c8482ca02fd944e181a82598b7621697a2c7d22c9ff3c460804709335eb04382be98f1b140aa5967a8290493849f23e72a3e67dfb187c4b8ad081d1af3b5eb58f53d1b1ed6800f0faaf66c2c213cda069fc48760a83d7cd0918209ee278707c386f5121e9bf57270ace592c3f06c8f1d753a06ca039ad60155171e949fdebe1490e32a67368f73c0e2a4b8827dcbc281e50bcc5265e7ea823eb850066b48b0a2ff7ce0cc1560fc5eca213b01082bb7afde913f05ba27f8af3c0ff68eecd5827317052001a3ff5cfa93325f26a5d4b8feefffa53dd96770fb31e8d9db78384faa41ddc76259b743ae35f4726a6bb8efc178b5057ae4410f9ba0e901053d1eab9b951200dba672cb74e1e8cf24e3928b3edcb9b1b08b657b2c942ae8c3538fd8a02f440e81b1da995a78c6df67ee1095d8e9005e6ef072391dd55096c0b67331b70c89556aeb018d25f0b795f25da80a1baeb8deb638e2b41453810c4216a292b41db024fef413ee73c79ddadd52496007f6a105f5218716925016c3f6b133dda15e99a97754e171a75766bf2e16227fca0bd146cd488dbd3580ffd75299a6253cfea3d34db37d85baba8f8aebdb24878e692d3fbb1d829276ff9c772783eea3cbdf8f6f3e9adf0737fd183b09cf3a00d4d748dcfb5deaf92597d31b4d0ca8ab763ce3c88d9ff40b0d29950eec1d8e539dfcd52b16495cb65b2dd9f7459b262fe27975ff905fd93efca38558a7f75b16a71283df67cb430b9e17e2396499302d074c1fa18d28d215a48c39d6dce08a2102f2b00231b27c428a765e11d1f41ff43ac27dfde0388777dc7712ee3b0ac743dc858c667936e7e0eaef3ad74317738e82d19e409682f08eaa4c2fdb4d15066f03b4172942d6f934d00a8ece4a1b707cce97c2f338bff0de24e41e6cdbbece50fdd037aa0d08a61e02f7a106e2a8190a02bb8f33d408f6d9211d9b84ec9fa93ec83fbe55aedef4566c29946bb746a26ec82cc51a6fab930a53ba0e0377f70e905b9ff59a99e81968f06591d0c39e3c9a166c4f19f05c5ab910edb037605d96742a0c2099abe75e39b5133097cabd2b423765a81cd53f0a01b708bc2700ea4db6ddf157a9b6aa506dc78b5a42b7c2dcb1d6d1ae7688e65506ae9e86a1ad761d5a34ad5e844653ff22349a562f4223555019f354157863c61181a6dbab9c9bcfa71583f2d41a949d3d60b1cc45c56fc9b847b46752f1b65e38661262f9dd7c5aabeb1d4bfcf994505f5f2c52478ab8d3e4bf207b24e923d701744fd204aee4e00f08d23ca8bd62ac6258530ce16d18863518068d18eaae0f0f6ec3b0a618c2daabca2a8615c530d882c1bdaf6d24a583624d3902a6cdac73b687775c95b7306db91434f27d369faa5343e01787db8b874ef145edf319b9a62a5e59ce9abaebd2d14c1cb17d5816ae5cab131d2bb40e3ba22332efad7c7101cbdb48896dde4e30b4e40b0f0d4208d36181eb3348f1532a61dd7d0506c8eedf67fe1653a8b1828357d2a9d9cd137984932da8da54c83ab541c6269d7a21aba876fbcb42a0da7a9b90bd13d56e6107bf7f7ac750bd8421ad3a8d7d5d57d556d73366dde8ffd2e4fe62bc499cbd031c409c8156f63eab3beebcf381cb0ed9f9a64d0385a802d56399fceabe6b38c78fca7fefe8e8e0480b07058e94a82d19fa250dc67309dc705230bda04705d8df24da0040cd49c1ff3ef4bf57db973ae3b6d3a96e5f9dd3716af53077fdd8d02c8a12efd3eab69ee0c6af5a69c2ec2d37f9b18ac628cdcd882aeffeea31e1ff6d47e55f07d5605208ac66533734cfcc42d0a8ab12f70e43e1a4d35139e612db8cac8f2618795a517f814f877577ffe79851e44a9183d972a4c6c1eba5b2af4fd1fbead42c85c781232465056d08266202221eacdc30436f43c3abf0770f3db27da8a1073503274b1feaa002b5aa813af4a1d6752d1e795092656bc08e3db0ebcd871aa8071e54c2eb9a7ce84341622f1fea91df7d715d47d68107665fb15540fd2940b37c1da43f0dcaec5b075a998b685a07e64f0608ed3a407f3e24cf0223f7f724eb41ae799b8e3e5b96a2605c459351e9cb2177117ec2d45817a5fc4c7210cd780939b1a0fe98cdf84a306e22b1b0773ddb83778c97258f66620ccd6770e5840b408c59b149cb9928e3c860efb15f64170daeb8603cc51057124136510bb40898e0d1cc5e6315a5584016b09128d742a4f0b135c9b3790b6eb25a65d69218d0908fa363ed388d926511af44478d9486e032e34cb3922db2a288478960453c5f241bf31d308cc5b877917ac97c2143d75f72be98b5899498ca0f3a2a169afbd5e3e3df8a85c827bd289bf7312348f74a6c8aeeaae84eb2bc1ba75d39d66e9464c53217fd037376c4a19c31156745566a936168f3b3795d83699ed4fceae440e4c90de470a28f6ea0cb18a8a5388f21c49631a45a3768d2fd50763a566f7809e43c8ef2ac9b2dca00d22f0333c6055254f434a07e737ac2ba6160ce663c176989a9ccf1db4d8d0a063d35299afbf45d77cdabee1f72c1c7e5ac3b89f3a27c5b089e4733327f6391c72bf1c34f6fda928bfe06417caaf34867d96c69ef97028c6ee7a6267a012cd362164f4ad6fd5e8174bf678b6ca15c0081ccb6468f3c17d6dae97a162782b5a1b2d9b4e855103ead656788bfb7c8166dfd360a2e38c7bff108dc171af9e55ce1b8b48f903dd6314876e21eb7615afd3cd6af1a94cf7936868c4140070d459f5a4bdd5c0211ca9c9db16ee8bc65f600143a3d285bb26fa258985ac86452822234294772aaf96bebce750c44f36b6787270d7325717a057c15b0327315b15afdd394961954c332750ca9605fe77cf1d44c69bbcc80a302ec0b616248ad7906aadf6276aec02e151d64cf14ef9a937eea6e2ff5152fcf69c5d470a6990c0ffe9470b6992d5d68c62ffb6a26a00aa666027a08c4ad7693805fc21f019ba4ba22ed1f01a4426692928d0dae81ca1955e8264e121cd81c1d75719b18a91336f6c44a5bfdfd8650b556f8e32c9f7e9ed09795d43c998a76c15696ab37e364adea456592dcd1bd23cdecc66a470949f36077803662cc5586191db12b66b388b2b48cd3a50e50407c103432d3357676cbbaa8d9502c9ad36a00d0d2cec6ee1bb1b3465ff3757b9252fb06e62cff296d3a87124f004951931c8c7dfcc8cc578fcedab7249f163e9914322753a0f72c56a50d849481bd459e9559b959885e91c491e8453c492c824a8c3bb330da3aaf9f8dddd4efb3452e0a91af04a3ebcaaa7e90ce2e87f9cf52633f6b5958082138b191be0cf5dc75eaacdb9a4936d56ae5e86b799015e3ffd1f3844e1f053adad0d94ad53a5d8b562ef03984ce51abe089820e9e653d53a710a021c791b0911ef150f25b71aa3cf174a45908316b6a3ae0f6e0d1b3b450a9ea749f49163d42114ff821f08e3a8b9c0d098e6fa3a90398fe5cbbf753ae47c8ff2e3cafb68649963fe3d1acddbc6be9c08d5651a59bd2f6608fb64e43ec48b2671345d80b297987362a41251b5aa0b126b587041e8ecff047ddb60c057fab93fa58d7f8f659b81afaaa4dc8d978418b4124d59db53a507f8b2322ebf4d63abd9caf753ddc8e905d3ada144572fa3d35fb9e42e816bfe073f1e7f06bd2bfaf49ffbe26fdfb9af4ef6bd2bfaf49ffbe26fdfb9af4efe26bd2bfaf49ffbe26fdfb9af4ef6bd2bfaf49ff14d0d7a47f5f93fe7d4dfaf735e9dfd7a47f5f93fefd3748fad790b8affa92f1f78b94313615e5ebe9889fe81f81fefad722c1aff2474060352885d480f6db1ae1febab6704f92c50c51c2af40768b313613d7d8a713fb13ebe4d3912e313f4d0927459c962d441e89b4d4c5ce9f0e04f7401c2cb32231bdd23f4d0927456eadb5e9b1f9892526b59cfaa1a7cb18d715fd959767474d0fbc57753fc9e1c3c5c829fc7903ff05bf95d12867678cf5ffeb4fed73de9d3ce9fe84af5f83c39bce9ffb71a0ab33748dad001edf387f0e6f3a8fdd7a92d4ec8cf5ff4bfe787c71d1beb828f6dae7fbddcbc71717e3fd8efc33d8f15bfbf109f97c7e7131beb8e85d6259e7f1c585dbf2029c6eeb1aa635bff51abb53d9dd3a643351f4db1717ebfd4eff54f1f30aa35fd3a757b69a245f68ffd4cf99956b2fbe6196f3d871260bd60b3b6317f72eee9d1abeb0cf985d64f81e190270543060d9812dab0b640da1e4e1ead15e35326679002f1acdcb62c419c38b1ff553bf30c62a37fa078415529d71b172f7e6b26d909bbeef9b61042a9895f2d70f07838e7948411bc4ff9a40d5b5b49e89eb0ee9498552434ba946f27e2912e2fd773b667b6c1830f887edb361e7cb13f34b5250ae484ac22fc7506c9f85973503e71af6a724e31afa5043eed2e785c8bf4c9709952b3d52fd97d3d83b3afa43c6e1e482b15ca139949d499151e63c2dd0b3e9e29e370eff61c6e0b2da4d9465e4d2f45ce3b7c0b04de927061efa2a4fc1bf7723baa1383cdb6ee39fda54e3500cbac2d9fdfb8cb36ff4ab774bf0b0425da718d1733c453978659307b2071cbfbae1e6fdad5c2a4d9fb195e3839ffe7f49fda2669f6d3f3e198ba9dc941ab6b4e6cd6eb7adae7f6aba522f368ba4d3bc118132a2c4683383eba11aaa7beb3fbcecc0341c1c0fc86ec8183c71243528f2a1aa23259a532769ae73d054c7f2435cbce02fda1c25ed6316b2131c9fc326643dcd0256042c0918bf34335b6591f5e87338041e6ef5ff6bb61efd2bf2c77ad4c81f7f3077ac3f813b46ff68ee58076cb49d3b5e4f7dee507aa56cd73b2bf80209a49ffc576914031579b34e4ab98d28d9a3daa0420cda504d00c4fdfbf0ef6d4d80be51339215074fa4da91a8c87c456511402da3bd7a3ba4c548fbfdc938eceabc1d857ec33115a9c87999e505218239d482aa14304ec9007163384485b77e977af6dc78428f196778da354dabee5cdcfbd3c53d54907fcc9623dc1f39048ba21c2bff5f0528bcecdc0a33ac8369fb9f189323f9fe8c0d70f3c5308c1598c7043b0d44a55e5cd6553981838f5f5065376324d094a6aa31b8a582d8f98e85ece347d656a4d4e4963f659fabd36d2d0c0e62473bd033914f476d980c35056c9f5ddc0b98fd14563f0df153070e779521d5355d1993e3b84b551e2568cd605d4e7b6c467ee2ab3b6440fc1346e4cc1629e6ea30573f5cc758f38567d1b5f234cea413484ef9d1e2c0fbe6f92bd909a635a0613de8a806744841b505a186998062df2a1a4e9dbf46f8d716726ee1a07fee681bf8ecf6c1aabf142b7cfc68a6fee34716761ad9cb58f2a4027b3b6b4920c55afa673d6b5933a083b8763dcd8a04870928dde5049fd472fa967e5312a276921b1abfbb88d063f44584fede282224c0a78f497ef3a445ad90e8f741e98d0bc6d9282e21afb580f73ae58c83a46cf30e83a9923f8a388d84f5504f3385b55888289ec4113ce8e5d78057eaabea6930c06410649627ec3e0b6565157d47253ca5b4d7465e89e13328bf1ed5121e3f37d37dadc4834ac043a9be1e55888e2147e05385e2aaa7153dc47e0ed9635f8ae3bedcbcdc9479a26d0d036e92dd177c2e202d2f55222fe97c8b64211c650a35ee74390fd83c4e0393d7df92a59a9b0100d3e5bc83e0d50564f411096415e1027246a4cbf9f6900da665a92f6a9d0dd2e149820d805e12d589fcaf6e5c0e2fca052f05e32c898b92c11311208b0a469b4aeaa8f779845efa0583b19f4838278ff09f434b1242676ac19175e071b4fc61085e7f73845d78aa02e5dac700d9e837f51040727a36fa8dc529be57cd2608eebf07cd46bf99e71d1889b38defaafd7a7ec554acb1041aa54f4464fdde8a2731e484e64981afebf4e725d24b219b8e1c3f77f8382b92ba8fab9a8feb9aead17c7375e218d05401c7cb2e483f459fd4c8f3a51a4bc74465bfb06139f03915793724090b8f86f034d2228f2fe0ac42238aead394a19289725e90f742409c4294ff07e8d36ee5d3510b126cdac756951391d70a9cb0642b5bd0ce8ae4ce68d7a35bb1ae2b9dbd481dd43eddfcc756aa69cd8c9644bddc937f1f3f32fc2ec66ec9e710b39734b402ee70a9288a9ddbba95c2bd55435b18657ef77656b7b4b36e68076ebeef36a6eafc7a6d450d6d451b9eeedc8c5cb7b57ca4ef656189dab7895a8ac4c5ff91c2e684c8c1caab7723925050814000d9734b9d42946f163c129a89bc37908808e4d5ce8890431a10adee8468d588687d97a1e1fcd6224259ba3326358575a890e0f0bc7497995a0a1da48850f94eb5672a43a421ed1d6baf5c7a36d75ee9241f5284111cae28934889e6567db7ab1b5e8f7a519646bc6c9fd36a97ce9aa8a9e5cdda9d46abc22e9195c13f79bc6ec7a426b96538666abf547bb322b9bd3da508d8b6563c711e5e432cae06b155433ec0e74e8f2fdc0004a55be7b4320fee3211e3a6be79abee293e6cd5c26940d0e340c133e9d390851564237801fb29b886155cb366548afe4e0098847d6b331d5d9874d410e10db2251f1c0f30ca1b3bd1b1de2a4ba5d23994c455aa15bc5c42c2d13b930e31564967f4884f4358a59fede2eaee2857b57d347ac19d11ae9bf88547579f8eb03a68f506fb53865b45265593bbe252db5b9563d47b854fc457251dfa157e22baea5861263e11db818f4dae5eeb1ed8bcbfd07384bd6ff1f6f78ebbebdc0dabbd5bf0b00655e9ec35c4efdc12ffa4a63cc7c7dd5a732dee776b90f848ee3835c6feea294fb73774472212a3e81d9b5adf9131ac09d069687d1bf18c43e86ecd685bda9d6608f9efc5723e1279a3ba83fe3d75bab0e9880e14aae29d7e34c17431e4e9471536d4693859cee3342be2b25ed1b2c1f8d6ebb5ce49fecbebfedf9f3ef9cb70d0ff532e125ec62b0168781a89b198ecd66788a2b29cb33376ae4340edea6b7461e2bb45339eaa2422314d2222ff7fb29ca32f521ba0be8340fd078f860f3bec3156ec63e6597662b35fb611785f65a99520f02380f4b5b53ac4a0370c87c76c4f8e06cdbb83de83f068a8be84f865f060a8bf783310656999f3a2a4f407961aee3c0b1a4517f67f670a92e53cd47360e7da89e0972ce7436de419d601418c7189e77b80ad2abe588a448388d68052fd5d4b340742d5089d1a8641c54a245b68a38267c1f85fabc4f4305afd5157208371e1bf3f630f7a35a7afd693274f5a0df1a7aa280e7b4792b15a4f9eb4d8096bb59c418c795e7f66eef7d97f3eff7726de2f31e3e024cfe67aae87876bbe2960ae878370d08f78122de5724ba75d1853577762f715b789df9388c27b6cf8e8918d2bbcc78e1e3e30d185d91e0bc343e5713a70258d44f31d0b870fdda9922aed3649f90d744c12a3ed4e722aa6bc14b7c8bead72e2c0170fc615717874c4ba3e496cdcb986c3199e528c3ad27c348341bb272a5885ce00d051b0ce1401bb265cf8987c347b0c109cd6770cd57fe5d9b7ad6392cc5fa05fdd2fdd2f754e119fd7b3d0502cfc7214135fac6fdd2fdd373c8addd2afb5bff8b50d0814264db3f568877ec1794bf9076eeb179c233eb76343d3b1dbd96cd78e995c879fa451d91db73ed0ef5f746aaa3fa90056713a7d0b42f96d99bd3589ab2ea8b5cae647db6383de0195bb83ded1232a7807bd306c20000aa6f3154fe01406ffb9bc8d18512278ee2a97d559d2f7dc4d66ac26fb15d6ebeacb69357f9ddbfa942df8fbe51fdba7fdbbf629cf4a6ff58fe1ed73b1f3fa5f61ee38e5a881faa0c1f12d3158a9d23380a6162bf9f789ce3ff73922a3bf0701dad91e7b95611662a95c14bc281884c79e8bb444ad234ed95305aae35b4fe372b61c41ec6d59a39fc423f8779464a3fe401c8f0ef9f0e1d160f068787074ccf98188c4e041743c1a1e3e9a0c86c330e29118f76da0c568b1f8d3cfc3c1236ca62fff99c7d794d2f3f83ac6fb9c80ad85dc553d1d2fc972adca9e7adf8790844fd727a50b76a6907941331f43c29c1355784ac356ae2111de1e5bb0ae09e8ac9d40b117c882ed0eeb6aad597d70f18498e8750d19d7755ce9c76ccd4e587bcdf61957d95ff6198074540ada3e1bf606a4ddf550259c5987a79e1a2a69a1151ec819adffb828d721dbd3ddcdc5b82d91af87fadb10bf05f5f06023aed4505f1bea8c92a5a854c18fba82f9a1c8e51153527cdf23a84e5ab4e8b80a6399fdaf372f5fdc7a972149d2f1246196d66f09fd3e7bf1f29767ed373f744ed8b288d329c40aee420d865e2005e36c2c16221d8b34dab032633f2c271391b3f54ca4aad228cfd685c8e3c9263088e7fc4a07399dc4294f30c63b5b73c0318aa7f21f311f8931acc519cfcbde6f458fbdc95822ca56c1c6198b4b36e7e9922709414ce2a7f2525f899419c34ef35cb0908de3b948218827c4542de0b8c4e3545683bcdb29581e0a8b15137833254dd97a164733f4e842d01ed944758c57ebfc41cf962ac272dd250d8483e6f9549436926a05003e0410ccf5b4123b7e91670b492f6c84e8fef28c871f7b335ebc5ca726a4a7acd27182b2ea34f9087f2e016c0cf98b52dd2ab77fbfe918ff228c7d8b5e6604547b35a03fc3393a3460f4dccb96d3e6458903c7d6f0d66229b47b15c5e9394cb8a8d162b413ee2a4aa74a94a54596889ec8f32c6fb796a9b85e8848ee19e8e4846676bcab72077da37fee10b2b6e1d2be572c78643d80d0ffa7958b712b602d103af2871425ad4b7bb97ede9a2d852cb0f71ef22f73ad6260578db030180d076e431ace5c7c60cbead242812a67a256b4e1804659fae54f34d29b4aadcba621cff9b53f623f2a8119286446c5c09483011d555d010ca3a640755a7f24c54d5d9c6a95c3712783b9520cb7f51696bc1e31a17ceb0eee80b0d6c407cf37b0389af1fc49d98e3b86a155c9a53ec89354aa5b6ed6c103851b1c4495bc31be5fbfe7272a63a7fa77a4fee5276cd03b043e270f4c4e1bb9ba997ecaa365472a9ae5819a20fc650a35234119fc618ab4ee6cd384c6a735ee7865eea43a06fc286750fc1be2697cc6fdade232e5660fe9f725bf492693ffbb343360274f21b37ea59419b494a1cd9e5380cbba4eb80c33e85c36f81aa989967d9be23f23f9cf0dd9627662526f446872aae55cdf9248c7d5e3cd6331a807975b0723c66a3878c10f4382cb51332a6d3187979914b5bbb57ee6b8a185f3f8f29601fb2bcf59b524f9f720b0bec26150ebabcd1e3beb593feceb743a3bf1b54e2960dc5269567988697e6a8443c4177ab16613cc21017817799c99240e52b1e249a2008de0db89aed860130160815b92071559d8b1ca576576c8330f6ca5e3493e9d834265ed92a3c3cc5da80420cb3872bcd05ecd58e6386c60996458ba67d0be817bb33e54293b8aee3116b69d61f82e8044122b21d62889dfe0ec57053149b040762c958df1d4d9548a06ff1fa09c6c114e1bd54388d948d5e659a1baae6b8565e7c2f52e36adb75001afb8c96ecfd150549db10bb753d4c7d2b5273492547905d411354ec7e21a9d042c698bba4d8e08a05bbcac2ca5e4c1d5a1b2c27c0ecdd6ed0a80d285aac74b5aa84e64fdbc89713b1ce084b92da0a43b6da6b8023731fd6bc84e58601da7e30c1d785b863a9a0fb0b0a7bdffb515c4640e8288eabf157ef9450a3622b6c7fe0d9e31c022c1d3a779d301c61ab06ae117adb45aebd2939489f9a2dc583e80c368c45336126c598871006124c4359f2f12817f98b73b9247473cbaea5d58cb509a650b7b469747f4aa4deb35904b9e499769fc7e29583c0e5821de2f455ac6f290ac9ff96ac31767d3241b712996f3988f547a3839f65ca1fa1d17d78dfeae3b407ab68cc727ac4d7b66b756d0a6bc8bb22aa4298ac7fbfb5aa0216bb53b9dc6614a0127d9f91d30cd3b782b256290cee93249589ae576d104c8fd7a5cb0b399d12e78cee7ecf7bd1bdc3c5897fd3213ea7799b15214659532a32c4b044f0d69f0d9d6b0f7a03720d4898b17cb247999ff2a3b4226104f8dde7eab0ede2a690dfbf8915961a70a08a3375836b790c7e490c1948c63b0926ce4e68a6690ce1f4fa51a068a0bcfabd5238e5cf128cc1524bb7f9f391f54851af7d3dc495aa54d2c68c050b944ac04df62ccd0524725b5951ac8838e637a68c95e5190eeb102a89a3b1a7b57d5bbee38bdca0cd216d77a7e21fdd13f8ffb91c8bb31fe379af1efdfdf6d725cdb0f56b9fc9475c1208ba650b6bc3a6a3511eb53a8a548f313b4791b69da5511a0141ef57e448ec63e43430358479250b74039b9992c861c13562f32dfa9b7a4b063bfdb957bb46437586b2a52c4cdf5c97c191958a5f41ea531d47899ff88f87d4a074ec31563f916c9cb1ebb7d3e2116c5660a232a5ec229621aaf44cade815ef44e1e1750307f22f541c4b83380f8ca8c255976b55c8086617aa0daf5d1a8cd1e955585077fc7a9a17f0dcacf9c53a51dde7d6a9f94cf65cd2d33acd4ee6d13ad94b89ecb2c6dfdd9dd62f4b95a2bb427ac8e951a18e1294f9282bd9ba4ef6c4665c507f244026c00e7e7285b08cd076cb461efa406fc249fbe8324cb9a20e54c4b25a42c7e573526e9bb1e7b3ec1d6e0157929c59c220f3a5fb2b92867994558a5bd9a4f5ded864d52359956b1cd405fade5c88f06e34729d76f30299fe64ff5fa096981172ad0db62962d93b1549425e26a6f50dcdfb07345954b87bfb20992eb1d5be4d92a1e4b5d17125d223ad95f20ce76f6d22a38e1a8498a4763a4dd937cea28289354efffd904f2c2c9b6406c6804350ac024851ce39bb6c2a8cedece99bec2452fb252b4dffcd081612d443ec9f239e4da2df89570275651126eb4d4b903afe5922c5b487d1f3aacf0c2e2bb4ab375cab25cb2629aa50272ffa745bc122ccac682b5251fe1b4b06c528a1438b298cbd16aa49d1e7b6677ccb86c156c918b89c8b1c50cf21172968be932e1b91c46bb039511175f0926aecbdc722b3458d4b3c14725facc889017944a90e5560e8e048b4b3cfd7c027fe3718d47338964fec7b2a442aa950676ae5ec34baccf27a0c0047a2c05936cbae6b99c6640a929414f8fb2e384953548c026a961e7403fba774f70014b441ab02bb1a14ff57ce968e69e3039268434dd51a6bd0b7221e937e8d85b65f52e0b4f590ca1994e59dced7ad77a6a9dd9e5a31b0343605c7f2957b9ebf32d91b5892a3fb131b592ade9c5120ed5d55aca49627bc90e0dd8a94b5e59e89376a701350f47a23c8f2f2f71d29b9270eea0614b6e7cc707b86bbde3e13b7ddb0e014b60a7e37348495c4226ec2d67944208e38753943cbaca56229f24d91adc71783f3c7c7874f0e8c161bd5ec407be521465f305cf7dad5e8387b7806fd3eba1ceb3f74b9e90175d6d3e08180ffd9515c3d25a0d02b6b27e2c18067420b5fb6f3884f3e1031d9c439e9078e8df2ad59c1bc91d83e5066c909d5984c81f3130c8fe7e4c0dd2038073b2c787f253a83e9165bc1ad0138839a2afc2ca67870361a07a3d10b2b591201d6ffdd58cb16e61ab0e494aaddc9cf5ca9be58495eb8cc4e0515b85eeaad4479284a55234c93d43c83e9db0dfaf4f86831bf6cd99fa65d1d6f6abe1eadf9cf8b719efc6422c58942d36b071a013066a8cd9b26457422ce4b91e7654011dcef4b9bf8095868bac4627579e279e360e7e31b7a943ae8b50db732fa9db11144895499517ca9c2f4c1d405fc9975c2b2eab681da719bc5737df6b04a942e08235cb5228d6464c2a5f4fd915fb0e6acaa573e5709a723701f17905d16a9c91aa3e987257be7a362240e593c621650343c949d6e19fe6229f6a972cc798dd8312a9fb29a54eb399aa8136e99ea77a9e309e1419ea93a30dc23ecdd2493c050684bfdf443c311f419c539b36fbb7451eaf78290893bdc536099b5d894da02810a8c106aa4baefba97ae96ce94e53e817586889eee6cfafb058099734f7efb32af3c91232d30e11a11e5e61d84e9e3a0a800dea613b5a650ef2f8bd61a3fd9b6cafa02382a323410a2abfdc82c9b7dad375e3343c9f6c9f887f39fa3f9f9019a809c1f20df6ce777fbb121b276acfe7cdcc6b112d73795c4a36468ec7a2b0625c252197dfe2542afed860d522a038c89c0a9effedd5cbd7bf3c79f1cb89ada3cef5d0bb312c3dd8bbe4516f31866b1ec05ad378d301460952dc22d41f66835487747964418c05b85302f5c7309c86331afe737e49b6203da31db905292144e9d178c25274916721b90cc063133f9d349eea742564945c9fceb0597556de2e6c2adba3ee8fc463e6033fd28317344116d22ec24cd3f68c35eca9ecb1a6e3093bc75f74bd29254fa1713734f08f927d0aa4fe2937a000f6b0805db90a68755542cfebee586a7728353076a687281559b33b23e54d999a1709a2db5552a8d10da74e67359eb56ae85479ad1f54559bc0c7a771ba14759bf20efa0474f40ad5ed1abd628bd680bb88520a9a59f1561dd3cec797944f7b724bd99392548a1c6d9c34dbceffef62ea930483b3c7366caf9e955aa91a1e6ffcae55276ff93c9fdc3419a39f2c16899c65b042e1091c1db8d619cb7236cf72614e1565361570af0e634797fdbc28dd617df22499b3cb2e930436e4d0cc0c75dce7e371ac3c2808179379f358b506f10bd6654f2c1add33d2c86e98efca0de2ba14e9f8440b165e14f13495e2d0e38eddb8e2fcd2737642437bc0c24e60054ebdb63d2e245be5912399c685d1888a3ca2fa9d95424d7cf6032fe288fdc657bc88f27821e77e26f218ceda6cc4e51142192ee7d95824ea550948961f7874359287d3df0a422b559f5a57807c4565239d8beadb2838fd3cc3975eec8c91aa52e3b47ff96a622bcad2a2cc975199e5ad8edc82092c296327db1c5ce68218fc2b11e06cbc4deceb9b659e67535e522f3d8a54bfe9376d9f39c3abe034f89ce88073f2a7aa42b138b0a958db5e99572d0e38b232555ed47c39fa45cd8c59751e51b4eb7b1110c2574c064e95b76f8be542e46fdfd60f524d4985629a85df8ec522179164466af988b28508f4addf2217ab385b16018b96792ed2d28fcfb52556a57e60b2e6b942cbf659eb845ddc6bb17d8399eddb65d8bab887319d75bf7aec55227801373baa9eea874425a1d3a2147cdcaa8f14495cd8de4652de9b493b55618c7f7cf6eaf5b3a74f7e79fef2c51bea1bf78ade63980b08b09296f1284ee2721340a75c6383be55d3fdeaa1a39db96ba9423f553510d08e5c05c95e891c5e710d7bc7bd01c294d93863b998672bb8e9d61007586a8ebb204cea5aa2a73ef5e9f49386eefb9fc28df1cb893bf6262007df097b3acbb3b908d8cb85c879c0def009cfe380fdf453d83bda0fd8f3678ff6b79252a1bd958a0f3e878abaef4458812912eeaae601b81cc27dbd5a046a013690406f5eb5084e6dced0cf6248f7ce7f37b6d4becba6da1f4bd54a738441ddee7f3182f86e1577a38b5ffb1f439e4a9f3d2af9e50eb19e7178a66a9e66333ee60be325fb3a1b89bc64af449a8abc553081d03a404dd1dbea2edc43f067938954251154df66a9e8453934b000fc709f8555fac4d3586075ed699cc4a9e05477ab6886ee5e263789e7e9bf2ff9786b1db65753efe5b2bcad6257d66c4b557fd8a969771b06b94fb64bd63f6383de5107b25454b4a641ef48f6ccf4ce7797ec2240bbdded961ddb13d6c5f4037e779e2e4771742b1d9a68716bedb6e4bd121ad778d8be7a7156a14b33b63b12a691389a3625eb9e49a2d82ed5ced5bf2f795eee449c2dccb21d43b75d47a23df5a1917f1a907e029d6e67249f58d8b90682c5e9ee046b26da2d589a48b695bb9ab17e22d5eecc65b770db9bd8b956acb20a3cd08ab2a20d1206fe7af59cf5d9102343d491f2369c80a488d31a94f554bcb5936af0a6af1ae71e2b1b85d0b3eb4576db7c9f4112d0c76c40c3f10d03160eb4900b6bfafc7259ee883cd449ffba147b17d097f5f4058234a2072f79ddef0a3bb98c63616b582facc2eec6addbc9d4c0b535c3879da481699fc679b3c82ed9f7b5236a1038c82bc5fbbc84981ee5169e91bb4553cb0e6b6b649ec868e0eeada3b98de80eeb378ea281ec95de1ad181515fea564dc28bb261c384ab1376c6c2de834178f490d87c16e411928e5a139efef12cfbcd828041277a075528ee9196f6ee0254be05ebb3c3869b645dde1e6aee7ff5bca37f4a35b21db23ee3f513d185e485b56be60cd285ed5969090ba900f5ca69aa5f0944a385d0d7b9fa9273e5cf9411d33bced11671fe4f9f28226664a59a70aabbcdd8e1d1bfc694e1f8b74acc2fb9f07663953b23c7207c2edf28aef9c1758dbf8d5f3c4db8dd2e30ac17aad545adf8f8b426aa6ab2d3d8be1c6be342b86393bb6b256d3bf276c1f6ce583bec1d0d8f7474334d86adbba5a75a37635263ac555d7ec89669b45599955bb13236f4f44c4025dcd9eba7aa19ab5e09b04c86bd0747350e040f7a47c7c38613bea93fdca13e924852c402234506bd0735a2011153e8db500f7bc31adc8f0e7cec8dd58f6beb3f3cd418aa3c793b6d81fbfc9ed339d4f30e6c3854ebbab6c3f5330fd5f49a4291a011d4de25280399b255299c271ab931dd7ef1eb056cb7a76d653b592d6bac737f90a912ae58dcf6d899268aa1e1abe73a2cc9abe7a7f8e9f5931fdfbe7af6faed8fcffec2ce189c55c3870355f8e3cb5f7ff8f9d95ba80647cea12af8eb939f7f329ffbe6f3bffffae4f52fcf5e93924355f2cbdf5fbefde5afcf5ffff88662637d7670ba4b58845ec4d315a7d111c4f522cbcbe2cf61353ec2d344f01c7d0f445ac6b960589bf1a2c8a21868af3c0d943b1c846ba87885410f6e3096837234c0df9271d0c3003c9c05d7cf6d642bf4e61dcac8f282ea36f40c8c302aaf7b00f75a44651bd32562c93a1e9733fdc70c237436dc833f35d1122fee2d7839bbb8079de42c1751c9d36922d00b06a2d14094b93c157921b96b9115310613b90ed8a683705ce145fa14f107c1daaa3baa23e069635e59bccbf9385e16efb0d524d10d54480a247a2dd2b1c8e374fa344b4b715d0e7fbc6151a9df84aac91afec85471d343525de19af1ebd8c4078ab22c1fc7292f857907658950941cc3052db2386d44bc5188375f1a3190502137755b057e6faa8404afa985054dd57046743535ef7c9e2dd392b5e3942de26b91141d339649b6cc2bd3069268c6d37142e69817accc16dd444cca007ee5b21f011b656599cdbdbf24143e1ae8a367ca63b23e54b75ebb8ff8a3f23a60921903e6f05ca0c6e4ec51de271524d3c4738a5305a1914869a5f08259cef1c587ce9eb16bb6cf72a7a0cce4196053f99e63a45ba8a127d7854032a8ca662aadebe14529058014f5bf64720596d9a2e3f815429fbe532dddbf0f5df94ea1755d0bcbeb1ecfa3b6999780e501ebbe7a1eb0ae92d7f419990657d365e01568c0065ba0b179a83008d816ecd819026ed05378e2484d875b199e221322dddc6934b7f65157211d64fbd56a3440e827cc442d512b441ad49267b7169c8a94c7a2242bc42b5eceda16c0e5bd4dd38b020926254fbb6655d6faac8f73be7e95b9f703b0ac8b729308bd90f52a8728e07196ba5effe08e73fd723229849c6dfd436e46811254af010db113e47c0ce9361442f6f1231b48bd9268398ea7107487bcadc6bf6bf3e39ad0b40063735fbbabb51a34f6afbffcede7e7733e15ca0de8b2a543ef54e1707b348015a62af84ab47d0e2a739e16092f85338566da20c2ba14827e899c23e8585b4d4a17476664a3f942252781d17fb87c60f9a528b3dced2e1e042ade7d7446e2e2057f61a4fac78f7a1ffbaecedce37b68c97647621aa796cde17bb18ecb68a6a69b4622b33e0851b21c8b8245711ee93402ea7dd3095d0572d129a6552c3c08ac9aec2eacba0537ca05bf527f45bc10ac55e6316ee827758b92ed5b738a9c4388ac8f0d4b2dc5dc0a3965b639b91ef6cf5ceddbe96312a7ff9ddad99dac525cbd46f5c252d63ed2243a510e3ec36e80fe68c6d3291e13e449f01dcfa377fac8c7b209c1f7eefd928f735ec6d1d3652ee7ec9d3ad7c5a5098856b091284ba1837717f8540edb2d082e9eccb3a2645c71614f1e84c363a9ade986f138bec8b3f1321285c52775f6555c40b0728210488571bbb35c071c9063370e8072dca0cac7b22f7288511eabb0e82a0488c6057d52cef44a15ecb19fb437f758943c4e8a801542287d3249b2b554895fbd2ee80cd4643c50e1f2fa3a107b3f2e8aa528fa47478f1e7c62cd87470f0dd390bd829d6981b287d4b5c65a79c839b36a73cd0e7351aaed48ab978a53d93e39f94ab695b84c9d8d5b4771fef63a46d4b02ed90259d76e83b47b208c5897c9ed1f7f55d4168b70dfe2d850ec75088d2ee46c1f1417e9dcfe96ce21c21a758a0e7443716de9d7bed32fb6cf3e4df0caf567450318fd2b8a08610c98bc37fffefa97f0edd048a6ca9e277524d6554acac6fc1aaa09b6bfe8b648fb46943625542d9b1890fe1e3c792d5839cbb3e574a68e53aeec2383ab67db4e7518f5bc5a03e8ec51f53cda69da00eaf8af11b88ec11a80eb39e8535823cab3a27028f8c97301a8fe5567e276e2123de40ed376db4c54295e943cff4a2517b899e7bed2a79e8b64d5ff9e5c541dcb9817b3fa338173caab53ae2b23c546eb0757df07e748358993c4c84b388796797625dab7457da4a17ac02eaa54cc782c5cf3e945fd9b39ac83164cfcad626036c0f35c70df4e7a715b6cd19a18057101b68be7e9935c9084e26de84300cd38a60ab128e2244bd9190b45f7f894f5fbf0438e76cef3690c09bfd0de8a06f2285ace97095c444006989ef7ca168dc8d7ec7b68ab0736b1ae69e6fe7d03f01d02a071709f40e83945c08dc654668b3a441b8d48592b0d266782a3245e7814019b8e438f8a99a2e64c4eb52533c0c0f430a083ea321f42f5b16be0294ed9478f2f97697dc79d2ebbd60a9b6b542e2c7fbcf65d967e133949e2857b9f5f0a955640bddd541f7e8e53714acd4ff095a89be42b9a87e6f1789c08d71404cf0fe3312e8933d6d61dea4909a01abc76f39a79a242d7c6aeb3c7bad6869d98e1f52ab6a4a6cab6063b31986a4da6eed8f8a414398436fe0629f8f1a31dfd372e0400540c62aa4796004173fbf55535b982da71dfd488595ba3da54bd598a060851af0b3bae71f59351e3eafa108b5c991f4c463a7f6e2077719680647ba53efe079d6e0af0425c97ff11dc05d57f6e43f59f3e2a35bc4a93967f6abbbb239affdc8ec6f6c6d0dbfbb0e934fb1fa8ebc9337b03fd07391ca8eb64bc5f76dd0d1a6fc925ec3fc0cf00fb4448805f4ebfdca8c9cde08e631fe77cfddad6529bff1f4e8aba66e92345bbd1d46d84968064c0ea15b729f39e725b965406ea9a1411755a4d21ca86a7c645c3cb7f1ca17afe3f8b8b73a87409629afe7dc67ebfe9185ceed2e9f7d92f2f7f7cd95e1d744e34815b9818a2852fe0cc84f618b80ee8b0623c173a83044fc780a99c895cb4a40e1965691117256485e4403be591a103c2c8da92a2b969ed22d5f4ea495ab4f57715b5401542aa8e13d6caa723de1e04f0ff7b61a71510989fb2d4c0fde9f8f8b852f8139fc7c9065e5bff55242b51c611672f04e6ba335fe41f4ff218ba50f0b4e84216cb8b7b3eb637f10771c2c261e57bb949c4096ba5593e974848b1d433fe2a303d7cd8c39ac52c5bcbefc50928e617294655c07c25592ede1276d23f0dc0aae19528b2c896a7a22acd5041dc6d26190d8c58668cb3a76fdee0e702c3f0ab65e7aaf700d0654f280205a9f8f677ac8e11317c9cec0d09f339162b91640b91f7e6d987384930d5b448bbbfbee98fb3a8e8ff5d8cfa4fdfbce94b0c75428084f0c5b980cb4009ad16136cfad0be0d3c84d472b27640951e580477019c006775fc059b2e9344afbb0bfbfa5921874bcdc78cfcb1cf5aacc54e58aba5d2eeec2b5895bb5701abbf6aa04daf65e1e29ab59c02eca54e88639cbb7812f3c213db6abd7ab2bd9a06e7ad8df9e4bb7b55394caa53dad9c244f6778f60ac5888289ec411f2c83b39968690f51f3557d108f8895961f250bae07921585b4c7b2cec1d07ac151e2eaee5fa7e70f4adfc27ec1d8b79abd3e4ab038454a1a18163c1e18a38e9403044086e5f64c94a1e6f135ec62ba147d7985a0770a21ba004a784b10469437b7b5252482d5da57d9062167216766a03e5eebc82649b5d6cf3626b3e8f32a362cb0fb68f4b840660e16534834866ed568bedab54a93df8dceeff571bc5e2c7f6c5c578bffdf8e4e2a2277f751e77da8beb8f62fef1dbcee3ce9ffb3407cb371ae5c78f1afb7978a9d262a090ad89386a68e7ebe63ad3edbec635bcacdc48eba2039b200bcd3f8b6b627c26794c1c1bd1b716061beb9fb17030d86ed171fbbd2db744cdcad22941406a2ff818b2c028590e57838b5c74a592b7c4c85be372d6dfe6a7f6510b77bdb69e4f4cd6e3801502f3599870b2523ff8e5f50f3f831e99a5222d038516ce7881645f9e8e558f50bfd4d1c448702508052f4a12b2926529065d1a6c0fb3a487ac72abb5d1f5c6758a425b85eb24731be7bf42bc8df95ac023069c7c46014b4e6b425cea2d430515ab242d929bf63e26d428b30578c6d8b3a52d43ab8b533ab2a5caf6e21427b6180c55a4b01299949d816f9ec468ab39353c2eb555b3c5092bcd412d4721919b0fd8b31336325f64674e5862fe9e29c122f7330b05d374c212b6cf72d58586d5f04acaf842291f5acb743366789a49ad915257958a8c5a3898be0dc380790d606a01d85efca4252e63d6b50c879a37cb853c47e0c6bce7f55c6eb8e80c0d5a4cbbb32d742bf44282112ead0b31897af58f569b74b4cb1e1613a72d75c1eaa548d1d11b274a030e3cbc3d4f43ee108c408c33cb3c13a58f6f690255f66d8d20844dc79f90cdca59831a2dddcfda0d4d5b244d4d5b1c1db5099a1e147030807b65f309cf04db6889ce5e5b88094e527681a8214a1593349383b46ab5c89a815f4ac9ccf18d4655393e7596b7fcd4b0dc9ec93180f38c93d168b12c8b776edec1ca2284f0815ab0d7e61052b1f8119d5c8a3a45924eca540470ab2b4701719b94df4cc28bb21ea309211ba1d3ba4aa7a17ba1bde575042da363b96973d456776192a690c0d9ec9d420d1ed838486d1830f8d123888d4494cd15e952b1c68136699f3addd08e1d56a4aa76d7a67e52ed6f6fde502c4e27996c5d4b439bc32985f43370cce2a36c59a2febb840f717ad194d144d6eb453c9a093e4a20b1c9df554850502832f60ee2e9433a325c1a268aa8aed4dbbe612b3d9c084264a580a93932c9a1645f1ce9689a20a9c02b491bb452a6965425c702b6767b9e05a58122b81fb1d6661fab8b20d710abd6d456037523d011575a92dbac2e4991ed1cfcabd139570e8452b5091094c728e410ab74c3538b1a52397adda0296defd489edd1f8744727195c76189c5e120a976f2b0d92266bcf045e06153f8a59edf17bcecb59f3d95b9b2087d553b7c9284124e78447659617acc87213df2a94eb0de23020edb7e817581df6b42d5ab0927067ecdc0903ff3eb7f7f7b635bab8aaeb2954c9c1dfe7a59fc2c6cee9b72cae3c360701b04ccade6259ccdab1ebe26c0bd4998ca6efa133a46efba0e76767ead7473690fcc9fa7de728ce59f17ec9739d44d29e0c6d6bb27a2566a502903362b3e8f2808daa0759ceba6ca4eb777a8b6cd1f6766b44e6de9066d370a002c8c06f27aeecb57b4d7e8d47363d4f49369510ea61f8cf2fff120e9ec1e539f95bce12d35f5e84783a0367d0a733115da9a7785922d8225b8b1c1e6b8583c040a151788ca7c7499271fb480b1d8021d85a9e6739cd0c97e5b988742a2f159140a27f3909076e62773d2687d38a5704f81a26d7bc980f0781c5653dd4f58e47aa3e266d9e18e2355f4cc9a54cee64867fd0b5d4dc4ef56e1733007beb4dcca3cfbe89c13e1102e01743a7a9285f97c91308be97d32b1a39d7ffa10eec6ef448c5bcd727752c4d964554fe873c3faa7ff543b06bbd98143b16a2fc3b9e360db635c186d5ced8daab26b7c527493c4d69c627f9b727aee01b6eb891484b9ab49eae720955e36b4a4a11079cb05bec316bc98334987ff193d7bdeb57c992864bbe56ea4b954ed7acebec571a83c4ff5396ff5ce62e9ab814f3bf9349f150996207dd8d73433615e5cf655e33e79f32cf3bcea79460a248e2b4ec8ee342eee45d30bba65977992e0b31eeae785edc7d8e6b26f053e660ff4e73f0964ec25d46d640b5caf4d4adc7320958f3a2cccb843d7657b3b7844fdc796fbbb7a6d94ae4793c16bf88ebf2c758d68cc177cb75f219eb12d5387af5c0d139cbe3699c2a13865c79638b45ae9ca4c4f4c9dee7bc24e663f5d08c81cf125e79c327452cdd8454739ca37d6f2a4a1d361c4293b65ba699562768847d95c7591e979b3a706295866a85ad46c1094d02d68ae752caf2b46c51f7ab452e563e5d1d72393b9772bada361184fa8426b54d99e93080f5eaf85824a2145b70284f32322bcd24d16d9d0f2ec91fe1e51607921c2ca6d01987894fc8728099a965d4937afe0dd4a9b442cf935a2a07351d83500a744755a11b4cc00d3702872a35ee30ae7f8c2ab59776de359e2a573a0b556154095289d0ecd46cf77f0e7ba64fa62fb6ccf4c8f4c4965512c738a5aa37aa17f63bf605fb406e7e63b9c92e32787a09efff03b68ac53ac05c0381ec9b20fc5b93de050091559cf33f244be051b9846c5fc055d6d9101fc6468380453aaf638d85c0490b536f1fb8121b0548b32e9a6c77d03937a3161e4a3839968cc7369806a65800973db6885759d9eeb0192fd848885419b294d128166b83709c89226d19fb378b21f3084b44098e1e7119f324fe204c45dd9aeaa735c6a93b3c09734b1a2e09a2534ed4271842dab33366409d2b175d7ca6eb4b717f2536e703755bf8b6e5c6e2a77614d72d1018e796fe028cee30b6ede3422681d7c91ad6ce28be5b5676193b60d309f318598120324fbdb42f96d1baebbd4e969ab77a8c07ae314a0ad3a331588d063dbc53762d1f51e8575729494e1dfb884410d6227027350a7bf3f8ba2dd7082cc25e3e1d559e6bd74ece856f67a9cb006a25435cfc245954e8d112c3132dada6b772fbab666f9fb54d5a1b8d700f46400d520d56397bed5ccfdd37ca1b430a1a9ba2c4eeb5904c7199d3f76f44de62d20c4c2ce2820272481662176b731e12dc752a886b1271400fdecadf277613575607db525d4214e8cc2c1e8f41105a1b9ab659806caaab5897d605fd0244efad242b9940fdc96e527634bfdf044c9613f16ea6497e87354af3899a042e4e3fe1617f8c9bb8cd46c3bd1cda75796850129fd94e504b996adc748494a901e9b151b9ff22633c8d9531befbbdfcfb17d33f4a2a68fae34760db4a88cc5ba94629e612cbb8385509e6cb546faabc5151c2d7c8625fee5252d557dd450df00d3dfe54675952c68b575965be7d4f2fd3b9eb13987535c1c48779e316a8f7e0eeadf68c17707ad8d21015632fc0e8d876daabc8ba1a20e2478d1468cae32311d04c3ec62751184945b2e838b6e9037dc12c1cdc6df4b99d416477b8bb64e8404ad898c403c3c05e3a4d3354c58baf37a5589c48bd4ad5d6f761164b518a85ac902ee712b83861c708ae1d59d164cb20bc8858c0f918d5d613d66a19c44aa5551107302a135cb7a97650c14fc7f2a060c6831fcc249aa4b9ee380b91af6218953c55a44f74c1ab3c9be6a22808c2652172ed1a27c9a2f3d694199bc4b96059ca048f6630121d18cbe92241ff349b2fe451eb0ee8213082dbf9499cc6c54c14557f550b638d7e075fd8ea6906a38d9dda0c992d7c883f99fea08aff65b20af52f14ba1e6e8146473423a69b66cbeb83766e9e8ada0d4f874ed5bb875da89f4bae3fd905b59d6800f7dcacbb7f02c99c1eec4eb01ed4b352b574fdeb5dfb9bada06f1a3d7abb2e3275fee966664f8c2143a960272c1c0cf49d87912c3461464b15d2256f256f9a650b036017ad0be076b7ba068d63aefd72c2ce2f955de2fd5214c487c47bab704bb8c552ab1e15a70b8f996ea88a0208ecdfe063b516981cb4019d7688d084ad20310571cae695e086c60121e11f36ac0b2f5ff3a5c033af5a0fe86630e7f99518336ec43b0a7e91c2bd2fc453c945b1c8d2225e09b433f048f9499bfb523e1e3fb13ce1c6980c6ca703d3eb003ae6288fcef40193da2f55c704a3c41820c3d37631d05250877e894145fd51123ccdd6e60466c10c59cf4c5f9df3e9374ebf75e04c4b3ac791e2668bdb841ddcadae1370cc37e0e7f1a51eea991aac739873206943cecdf0d6e057a46f709d6bfeee5035fcf9041fc1c0fb9634a313f87e2996621cb0394f210e10bb8aa32b545b391bc75351940188f144eeb8d984711d96689de56362dcf08954d1e28151d4a2362cf853cee7f6d5af130d2e9292356964568723d19b832a8693381d437aadb6c7a001b92b31c4aade97f8bc7ae672eb4dc7e135eb4dd2ad0c9950a658247124dacac92724eff12bbc499d381cb2d452f02ee7d2b9d0b300a392d29574b9df676faee20555a564034c5529d8322de304b52d7c1d90a560d413d7225adadb6fc0f4cb0c9cd15236e38b854851515be459240a505be7995402c40a53c18adeb4c75af04deed02d8288a76355922dcb96aa8152b9cce3e954e46cbe9467a14428edb6e891e3a0192f61104247202126f75bc7e9385b07b5b94d3d54ced112ca60d9fc086b86588c6e6ab97bebab3b8268a799d536023e5ec945d37616ff8f99dcc1667ca5f688a25c4e26647b7cecb046751d7fef38b15812ecb286b78e52f5b669843bee3264cb529b983e52052c15d77014a39b92ce11a1c91312565f88ffc7debb70b7712389c27f05999935c988222525d94ce828be7e65e27b1dc7c7f2ecc4d7d2a7806c50ecb8d9cde96e4a6462fdf7efa0aa0014d0683e642733bb37b36763b101145e8542a19ea50152c1aa697a9915c542232b145442d3516c7c334b33a52f8baf9b5704cfeec01e1c1ec5f74f3f2f1d7052e3de885e15f3f1be8b090b4630ef94a896a522f370f71c45110e046f3e660df6888ef69fc7479fdb21d1ca1abb9669561465b7ebae6b712822377a4f0c45e406ffd4ee994b8510700c6c222c4aaf1986dbf41e5b0faeddc127a323f90324137df136647d2e0891dc09de0827f232ee8bb77168312ec19bda37a76c2518e1d97504860f6f1d41bdcb7d133016e6d6f26eac667884838374b34921296fc1158d536263674e65b62e58083e45527f2ade763483d3e98bcea258e87faa593aade10f189ffe6b99e3c70bef35fa5d51bc43a366b4399cab7a5624159e109924a228cda3d038e898bedaba02b8b63b0c6b9e17753a45214a064ec6aa140fbf7dfdf415ebda2ab66456ab522503f19caa82ef318025e36dca40de29f227b2969f76acd8a3125db829b1e0e5b29af585aa27030ac20e91d5adf47c103a9ee2d01ebaa535f96ccd9899232a940c2e891e5884f43f0f4c43e2402d1c4f4a6d1eaefa9ff8339b86d131703b362fbcd51c8c33855ec8e6d59a2fe78a3e03fef60d9d0721a5c54d3bc291786bfebee0186a0e27c3b8c1b4289fcac9accb73d10737b04623716ab6a8230ec43bb506dafdb0ee1ef50675f1f7c542958f65a5ba3d2a852cf8dd636ef9370699376288af83dbb852a0eee5eac2f822b52f935da838b38347f04a9fbd301f722c953f272f74d2c529cc2dd4eb7834dad317e9f56ec32ec693a1c97f68064ddac6624a2e016f71832e365993ebfff36bd3608d2ba01d6e54cbe74fc4d9bb36e82049b47ba173f32b203bdc5905e90430b88e8c68f232c994cc970ba156752985ac6b3999f9fe89dd6a399909cc770110cd226a966f8c1e8e680592a8dc50c11ee8e6a153a353075651e66b6417ddf10e49c932df9598a006693936586eb7d75adf7ca28b038119a7191067df92ca5380e670c3d942d03bd00d9a52770764a9f5cde61a46df6a341a08396f6b46f8e4e60476262d6468e45303876abc982fe32d49b01f696232c96455d9ac1a89ac65a5d056a22cb24caf60374b73d5176359c2e5d1a3cc2d58f3b1ade8e97a914f22683c6b7aa0c78dd66cd7e2363a0df5b9be8317a976c0b0c038b89b90c9426ab49676c67851221f6b143dcfd35c398745004312414c8683d56ed93b85a051cfaf41b71c9549ee3cb6e8c020dad0fe23db3e2c5a6061b462e4bc049645e8294a9c17c46fbea41f4fbc59ff403c1a817c281255a6d79013c6e2ca5caead9919aaa158ec0157efd0c650287ca0af670a0765fc71acc8aa5d8d80a22975a5f2040d2dab4dbea8496c4e23632cd9d15d5c81853e589318f977675c9489bec617e0e4187e8e547d2235f7d8f884e11b8382ff5da4790c2e98cf820ce422baa377d8ceff717b79c78d8c7cc3d536dfc0d30337856f40d480a49d2cc645707315157fcfd5c05c5e1c942bcdd2fcddd94466aab2a21690f824b408dee74bb2de9a8339eff7aa96ddde407ff3f4f9cb45226b05fdb00945674224be65802cf2218d7157812431d232182b2b358b65d68d1ba54057662107f893959b6bc0c02692e681c7463f2c6a07c7a0b283c70464b51cac1eaed2ead9132b3d15efdf8b4ffca23427c0109e87c6614a3d691a871756d46dddf8f45755bd3dba18a4896f1d6447b66e1fd97ae3c8d6f191ad1b235b4747b68e8fcca0855bfa9db4a303ddd9807aacde3ad4bbb81f40d5c8b21b483704403007b317c204fcfdb6289f255edc339929b63ecd0e7035de52457fa49b23ac5da91aac6aa063afd76877ee3cd35eecd7151cdabdbb5adda52b37ab1d3a72cb4eb640c1b2747b6d7183b74ef48ebdf3950a7b2f550b32636b24ac5dfd0adf63d489aaeab258c7c0c2e31640eb63c18e69ec0de62af6618271ed1ae4fed3dbbbe168b6516c77bb347963df38116adebb07fefcfaefae1df925595919ba6e851297fc7a817238a8e7de4b3a3a0bcfb17edb3ddc9cc7ef3009579e6241fbd4d8cdfef12e53787c34ae4398bd26e99e73f49c5615ea1341dea0dd8f28ce818e6f53999b6e5005ce7fbd7f0febea6db1739bbe757a2f775bf0b1566860df00e13880e6523fcc9357c1d16e6292b32e44fa1f0cd0dd2a440e1c198505f1050b477d03cf6b83148446d5a51a363c4493b08c976996fc50fe9d37db0b6f76e195087b0c2f60b0a6eb7d38156f2f7ce3835c008b0d694fd1473a5b9bf490d044260918b00e41b80136965667d6959a4a2f2b51a518fcdcc22d95cc0eeb744e563255af2f6e94c8153ebbe7459ed698a4b2a26ee645a29f2aa45384685eeb7c322b8b3cfdc581ad67643b93cb8cbdd8e56402893cafb2f580735d4868418c1490665eee091d9d62bc52a419af9c0d23183b966a91c989c2602ad83f88e88ca9e9c0418bdd00a6dbbe982b3f8a001b1b80bd77cfb816a5d5d31584991e670aca7cc7836627f10eac05364396f0c40e87e2953ad48bcf1638cd7141b6ae41518a74aab77a9e56954a2c4899af051e1bdadc42cc7d6d28a8c101ed9c71ad060ccfbd0ad377611cd173a3e9d6830c1e581b3217cc9480b8b709cce0b05a2e16594a61718c5d2f1d96c34c5dab4cd84096adac8c11ecef6ce3a1171f1b795a360cc8fbeb6ddff9869a5bcbbe782ccf6d9e90177d56975305e304dae784bcbc52dc11181414c6ffac2a96e54435a29bbc536b8cd97ea9310162b6db4f7a34a1b8decde712fb8bf6c204f6b7e771513c6d22b16a23eed75fa97ac7055eb24c85f01564f27a91e841c96c44e68a883af5107989c7cc2b377874a4f9d57f35029dd0fdef5f3cf71b9757c56fcac6d54ff7b7a96bee7056c1b3a280abbffd863760dea6170337176f062185b02f5ac2c8f0616a6e9cede0bce4a2ed47e8f75fb45da7a8c7dd6d2cd01e4bde00b08182498875554cc5a2544672874ee74ccf04b4d4c53d715166171ab3f3da12ec4a99d8ad942d1a09fd94eed844ad445a39c3fef3b85d2d563c34b704f1cb3ca2e13310d53dd397f6544ed42d0db920837a4b4bf5430f23ddedf94ed8ce5437794f2e63323efa1bc887b99135a07bf78c22ab2532948903a0416d12d777191ffcabb3430b4c378c580ffff5a274b67414f462a76d62c24177c4ad46cf36fac74fd30cdd61412b0d3225ff7b609b88a58170d7e6d665c2ddb04b13bcd6c64ad84d8ab06969392936dcf9acb8b62acf7664da20d0a4eda2cbc3210a6fbdac3033b8511bd107587256cff9acfb57bca50cd1c73bd3f1e3fddf80abbc55a05146f52aac1199d59cfaa07cc7f552c9e4ffa8357f399c4dca745183753be393681d2890dc6960e03d12fe433c31d28d3803632bb43dd4614f47b8b584559b9ebcfef26c7dfca233bddf885b06d2a268464e0f403c101df8633f5b1331d23f2d50dc0de3ec4b48de7deb782644a9b7d4b9e301ed6269048d15d32ed922537261231c46428db98874d5ddcee6f683b91b950f8f96a6c3fe29e395d1fc824ea9c7f7318a4eb5207c1f40685a9a63155fa0ffe16462d7e3ff71cefeae07ff631fec674c88f6a1273e3cdcc3a1f88990ec270cfbed622cfac140f5c3d3050405600a8c0a2b98a679a2a27dcab4d033b3a04606315cc726ea47df2390b6d8626948f82dd271f75a0c60e96f1c7fd87f3809db4ec476a03896e6bcf3098a4f711a8586debc63b486531b3f9e6ac32a2be08322a1568285bbbf61d976089d721e0b9ff2719728d8055df7f75b4fdf238647250d9cf91bef645af369a9d42faacb5302ed7455a0f5ee77fa660c197c235c350308052286c05f1abf7bfafd1793960c00fa0c34d960c5ab7a03ab54bdd3a8fc6744ab2ad40e969330ef0d4aacbcad983223827dd847130bc25f1e56e18a66667870b7ae5e89254c2debcaa87cc0d78f700c21bbcf42f75b76df56759f826a14718f57834f21d18f76c9cf232ed70098b047c1c8ac603c5eeaad4b37da53efa2cfa296f8efa7c6145b87c5562118122f890ec755d87528ffa0f8931b86f20fcc6911190a9534e0b5f6bd2b6fa8c9015dfcd1f3b7499fe3ab6baa20ea517872ad5fa34f81ba81526777afa8cbcaf22c1f67e826146da9ae37bfc090e980eda1fb83b6c65b804f9a2b104f32b99184f05ecce8378b322c336f955f79cba5cd619bf5bfeb851dbfaef55a9aabda0f7856db999b723e1a5eed762b65d4bf77c77a5f57f1bba88c59ad7c39ff5ef9bae2a600345fce9f38ad102bb7c8656a7c6d00c6a4a246834a95fbb6f343d34320e9e290bf89421ea479a5cada6a7aa84edf0ef9d036dbfb40fba0b9511186fd99144b769a00519db41810136a8498891e910dcd3542150722dd7fa4cea3a80d7d602460c56ffc8bbc4d26b32a6f290d61f251c718cd1f2248b30abba33b8db558b45ae1046a7717997c0ff867b374da6ee7132af675e53bf401d8bc0d2f36581278f537ec04d50bf74e1c8a93bd07fd77747d6b5d9aa0eba366b76190a7a61bc0cee19e9288db42039c6df2fae1df8d0be9cb67e2538121cfb7875251f6045b3fb8c96803fb1acb5f34e0f942e3ac6ce7cfd3e9b413e75f4f82cf14fcd944eee6e7ddaeab75d7c17ce613937d7de2f9e6c8b27e484968653919b80ff74d1d9527bc86f969cb212be0f798b81eabb02fb61664bab5b5789b21b42996b52a5fc9245d3aa79e15c15bd92f6bfa62a422c3a17852ca1b217391e6b92a052e8f18af61d61028057c3027a88a2fe58dfe2645522cc7993ac420ead888e03dcd33595ea139828601403480f15a1c0d3efbcc6441ac0ba1b2749ee6b256e22a4b3115e058d5374ae50412a45bb144befa9b2c27dd555facfbe1fcfb7c5b0ef9caf5dd661cf0efceb7498382954050e21bbed4ce9173cb66300844569a03e6bd1c72186d83dc342d66d7e4c966fc6edb3a31477a284e824e5889f3e3a2ccff45a5821dd1dbddb5ae7af6fc68acf97699658fd37292297cc054789aaee7b0187dc43e76b0b61d1a935e04252639d31ef1ea8d43290e3415337b129eebfb51085edf0e4b5c8dd3462ff7eec197a99d34774af71a1f9cb20161196b757878df274ddbce039c76c4af269af5a38b117ee5c8e4987fe4a782e1f99c951e435597c53ba39bdd7bbcd773ff1887038b0dff230db489b188a71e9a32fc446a79aa87cc6e14f49885b24e2b82eaeeb3345746006041e007ba5759c5ff5d0099e9c01dd96939e5ed105ba08dd5b5ca3a7ca30c66c7d076f7331c420c261f3d73bf09a69833b6f709310d379d8c3612c8f0ca86ff25fee7525f821b826752f0dd8e2c271deb37f55c8e55f64ae6579ccf85783e3f7aef8bebb9150678a16421b1524479d6b51972109838d46bbaea8b939ef8daa5cfb99e0f4abca20e74393cc9cd529df48258bb26c9602302709a87330019ed8f145fe3cddd6602bc5391e6f52bcace6cc2b9864255d8bc6fcb620e8ea25d8dafbfae482bf6635face9cf37b7bdfb1cb624fa1fed6320d99540effd144d4c5b9b980af7bdc03367324febb452d45fa9578a83f558cceb79c8615a8196bbb0aee783e0ceb221776cadaf195c4fcdd27633dd069070b4dfd87e83f86cc03eec02a17520b26d146ee93027553a85f81d295a01c3fa9950a9c542e54338a6b8ba7cc188d3848e21ab35cde8540417390ed3f1013e9660d7c4c79d8aaec5826f6023389777ef9ec391af4f031ac623229833ea0ff1de3dafb35d0fdf95aa1fc32b07b0bf4d3e113975543293d9d46056d7c33fa4090e0186f6e632eddcb2044b7110ce9e358e445ed6a4c9f0a993a2eada31f5c4a7ac231e93f97a3e589b26559ab73539777a0cbe620f4b15f58f6b5f2a1ab57b1d77bb6c7190bc724c1f8aee89c9c5f6f2594f8faacbc9ae77bd9df40c2f4ea5de9d7512f858ed10dd7af396eb5771a9a234471c6c9fd8099782c279d4c4f73100255c60b343086c420002312478476d418faec50f3601bdb0c1187a113ce95a44d9d23686309b2c6427f5ca2e336a262735d72bb6ef822f17e8b6739a3df1005fd6236b80882168265c4b48eb14ceddfe666b3d0ad6ded661db464908e772d5dc4fef9d79e4969b7d1f79954c058747231fad58489ec4955b46cd9432ce75c4c3ab5dcf0793b49c2ce753552a4d7e87f074e07b791e64ad04664e5ef39080fad334cd32a366d03be2cbaeee870f0c5ed5b7b2f4de923b3c1437be64e3ac33170034d9de3df9e7cdc0eec4431b90211f7d5eeff9a0e39bd38d78d56c5bc8067afc075bdb5bbefdcd25fe880bfcd19737beb8fe4a31de9a3f1ad9dab63d8663eb43c9afbaa18cda9ab4d924e93cfdd55f20c90c2bb46db8d4b725b3bd2719beab445a3f8c99481adcb9f4cd7934f8dc498e4339f5069134899d3f8b4baa37c9b22956ca4874c6cbba0ec5d94f6435b371befdcf1823450ff92828b5815246a2334f6b553aa813b978a47e498939ac82f8671a4be813245880c89e60634eccb62c95b4225b8cdf972b9014a77585e1d9e42aadce63e275fe3286663b3c8d75bdce4e6e294d652d5cb43cd58a7741837155e47aae1632ff9b8408a2fa42a25ffc964617380321cd9252e56440dc83f4ba93acc829ee946b86f848e85eb5a0f6fdb03e6ac39fa7b9f55415a701a88173a349739eed3c9355fda49437f93332753a3ce6ab60c804cd242b0a2ff82b5aaf19457bdfc447fdafef7d13075c8d6628d7b8a18371f4d49d354c2b69949afec39f5f0b0f38dc009e75f239d917e8017ab4c57c7c56ab791781047639e73cda3722f10ca2c5c30b522c643deb0bd0db4105cc67cc7634983f797320aa0daa77e9423fdecc30d8e7c047cfe212cdb472fecebdc1a4c827b2ee7a4547661e7ea43dbe9901ca125d28957cc7be84be7ef1d54024a1d59009fa974ed3b2aacd8a5cc9d4f394b503f13709a700412f69c18e2eda8d22239cd87028ce80bf12fa2c881fb829b491733e960b8ff122c22adebf6f3d4c4155deddb3a7e22b206cc7479a0ee6452daae5625194352e5022ab99436a18b2aa356c4d9a792c7dbfc4ddbafad70e630370b19b372388780d98b417ecbaf5bbc26afd5dbac3aabdb818d902b597cc0e93b0750398567edd3a74b27bdb021f39981d9971375e4b421b1c4513e75a594253f75b762e28546521d2ba53a17809d3a293bc322fc45c626a8099ac09b421b0961cbc3dbaf02e2f2038b65a484ff4d074bfaf8baeabb36284db648b02f627bc1b8e4214f368f2f11e3439320f4e1ded1018e50e47038126c583dd28ba18996e7c3017f77d27fef695c3f26e308a4f4e4fcd021c8a63c8c6f589a1ad10112a3aea80c0430003552a7103f4f44a2e80a64098b8b46ad253c8ed09214ee5c223f0fb6c6e2ce4340c0568675d40b077ec91570833bcc209d51dd68c11c04d641d473dc82308c6cdabe376f0b1bb23fea0f16f0aaed8dbfb5172b2efa3049e31bfd9b36481225bc74691e8c5bd2b5cc0bd91e84ce071dcd9edc5f297e3ed8f93461d7ad7b8cfc3a1f8ce79f89dd7b3b436f2a163df15d07cfedcfffcc8831b7d2958b5ec0ad448befaab4d86667c1ee6e20109f7e4b8f2955d3df1b508155c66f89a8e1859baaf1b5eb341bcb9fb20dee020d67b0d82bf999044ecf068828a9d56551c2e495f7813da41d28d93daa4473c107ea1993248ac032da39d332e41e944db6c0db846912b46112ffa58f063ece31bfab8b61f3f5033d222850ea5abe74cc2b8837aa1a144b04be406c0d6e6e349fd779c8e233b324920ef5980ba710f913641393cb8f55aecaa97d8224b77c410b93cf79b2b248ada2415d183a75f9ec6829456766eac7085df79af6bfcb46ebcd6777fdd0762ae4deca8180e85aab234af0f93b492e34c1dc203242f0eab994c8a9b40a6173037f187f870281e1b533dcde9a13488856bb23be54756d07c4f834fb84c2b68ff2cd70d40ddee363a7c0a6d61ccc34bb4dee1b970d2f25c684a48003f626f865d64fdadc36b2c88c67a343d40dec962655f98b38cf67906197d03748f5ff16ee793df92f728d50475f09b4c75fde1ecc0508475cedea58b854a46a2332eeaba98b7d8ef1e6d660cd2eabf5459a71399391311774dddbba7b70f4d553fe1e81b2615f80e76cea5778520e428f219eb4957c6ae600c691aae649964aab25f8b3255794da9595d3c165d99c2919b7cbcafccdade1a70d8c090e147d0db6db35793d9936ccbfdb40257aa7e244b6cebd601a8d6715fac4efa627ddc17eb933ee8bfb97d9ab77ccee3536653447d5c3ba7a25f1d131914871696fe7c623e1ff0cfeb639e79083900384f95d554ac4f6c1554288655fc278c1bd94ca557b33a1c1aef6cd5e86c1576d6acb2a609aefd09ae4fcc6736c15be34acbafd04c4deb915e77fc59178b915e7d3a5a7acc23bd23f81b517f24d62700afc1725637720129effbe2fab82fae4f7c14d7254097aff52bf9fa448cd8a713fde9983e35202f645991351f9d441f715472e51166aa74df94977e8c0274734bae54c8d198d41ecc2e10ccc9caf49722af65e6c56ba5bd10df1097ee8233e1686039f4df7dd1d1ebdce98b0e2c69c7279cce87c940fc9a586e82188167a890e8d4c5a2d3f337b87aab6b5df00498defc5ad716a818dc8473b9fa07fcf73bfe74d01758dc6e137410efd285386dd92b5babee8bb22fc67d91b1cde0110dd0d38f32e53aa713712a0ee0dba02e163c8851e94a607579d9d895e18af1c2cc15eaed7145fe21d63deb3e342cd784d58e9dab7a04cb61c6daadc5d7e2080c20c448d4e21b585af100ff190913f5a2a4667622dd92372cb1e13fb0e13ff4177334a9a19b6577cc5b8e1b5d8ea965462dcd127433de2e6bf498c5cf3e5c01697ea5af8c80aad3ed70da20fc16276e8843c29a34fb43f3538fcc5625426aebd2846de59af441d83138899cc651dc5e167de1a8b3918dfabb092af291f7ec6063e3af0f370afbf566845d3979c2883a24224005a03c6fed441cd0740659bc3f57a16e740dcb838ddd9f657340ae90fd39e6b4aab1eff4508715d5dc21773a7a972e7e14a76265437d79a4e28d38d56f92b0c862cb27d788c708e6de3d6ca41113a3898da2f8e4f60e01e1e0efdd3370debf172bf1cda9b7b4f7ee8995f8da47bf9edff08d6eb8660df58adfbb27d6ac1da262d4a4da32a9bb08426ce55d54c877b7dbd2dd54e620f193cbea00e283f3ffa4aed052c4d3b6e6ac147eddcd084957d4dd77a107cde7e01f6bf3c78df963e61b8350296011f43fb8d1bb4275d9e7ed4a5e5f7db7d18ea6dc63a875e072d4b6368dd876b6239cc08afc16744734d3be9d5b6831d351d72a2f92a4b341bc4cb88507ff4e5218c3ad1c3ab142bb257d8bf88e40192ae2baa29aaec506b9da07cb08fd8785c193071e7133b02164a1a932f2aa4072a696f1feb8c539628785809e03b06fa260775adff6d17ea829b6be0798f2afe5d9765e0742aaf37a4d06a46b92d2e9970e7b3385faa115555fc5ab233c26f20a030dfdba1ac1584762fda196d5bb60937da092bc548eab2ebdddcce81d5eb937a35f7bc56affee72d5732e2b8d5948d95796fef6100c7b9957117d7f8e5654dca88a4a5e92aec0d31d50d92b768536aed5fbe7b9959661b70fa13bfb91fa7c8e7dd9cfa6c397d4912de0bdbd62bd18e9d6a25413592bdf79fdd27dbf1f55db7db64d6d17937f8d6569845f14ab92b6695e24606ca6296187a34245199aa81ea4151a89b7ce6c10f90c3dd0aba25c3b595641b6799e75dd5599267addaa11d7cc62d5bfb932ddc6141b3da9c9ab755eaf5bc6a0375f5ac7f60b1fb1b64b034de02c3bb4b1e42cb499e14b554e545e4b4d298f067f658ac7d22ffaea3c26bf3372b7c7c57cb1ac299be7f99f8a459dce6576fe2751c9f92253a24a7f0145f55ca6792dd35c8c655909f5cfa5ccb2359426029d8a162524004df32b48c296c9c560a3c86c823d7f9fe667d0d559fa8bc29c45e42d5d31be7b0e162f503ab864e13b4c90205483f783041fd692f9d806d041c85b42e8606f5692354ff3be235808e16d7a61acedabb7a93814c7173d4f641109de83c3bf52f5eb74f2aeeaf6b68c42cf88b77aa93bfbb628756b975204c79a8a6fc49178d036660075082b055abd796a78458ab0a42b445efe58ef368a303217e77f4a1305d862b0120c4f6d1e6839ae8a6c59a3d0b69ea5937739c86cf5464d992aa3284d1248f1a95856848dd55c6699aa6acc6c712d33d1ad948ae24d0fe37b130a56d01f21e122cdaf0690bb02a06b02634c26b2b590d98d5c5736df651543efee32afd34cdc408a8db24896134551327930d007bd9dd0fddbb47e4c6bf5ba94695d999c2ae5325365df4063a8efd6edd4262c1ccbf2b5f96ccf818973039006552d27ef1e43101e5b01110acb0deaba687cee9c71d1d58b6596fd50fe5def55d70e852ef507f1434c03c0a3cc7ba3662363ff0acfe6f41750c6d469d1223c8b8fc01e13a050a730f24fed0235a9a4e10a7447fe4a06757c8e6c3814ff98a93cc0e0b4122a9f16e544257d87fb324fa0dec2028404e922bdca8b5225030bf14551abeed9a3de4823d50462d2cb24b1568d53c8ed8e1eac41c79883956fff4874be38fa8f4ecf02c7bc1d74690b6f7ea24af309a5c644895f5a99d199642e6c8ae6f80ebc8576553ea5204ffeca1eb74b1027b365fe6e8477ca908228b1c6234403fa04b67a2341a4ab4b8d4e7a9ecc264e95dc2d66f706e8035eb4fad897e05b46c7bd4a1325c66bfcb79b17601ca6970340bbddb4018af5a61ef7fa3eb1b356747a03a645961510af854690aa0aa9105020001c101d48849fa4537084a951c845297628918c02db574de2346d5ac809e0d40e342753ab3d890e058af189454848e224846e14b4d7c35b895784ab528c7c01598ec193ad6523bfa4758310c6410406ed133bdb2d44c07a76f7011319d5c1a18731fc8743b20c4c205d5b5a5788c16945a1787c3c70267dc2ba980c87fac20313549955051a774b020929a096944508a826c01f342e687d0c70a54caacc07b43f2a4fc4a123fc65ad1747d73c84868dc0101e143e513b287f9e30e8d8642dd2a33e1fe1d06ec2900f04e33df83070986e62f4af656090abd3a07ae8956a4f2240216264391c9a2d7038cdea5b28517863fa44297a55f8440afef108d3354505c7385e979a8a9fb604fee202d3587eece6036ea7909c1f37d730a9bd366620f616887fb59795fdd83c9ab6682e578f624de669fe4896cf81266ccf70bc5300c93e1e3713ff1e3123be472ecebceb6e20178b6cdd9d2b1628cec972db2354425048c0b6488c4af8ce2b22ea18ad27629d1935790c79893fbb3d13389fa0b8173c3cbcd122a8c3e61e60b6e8e0637bf076355c5fe847ee20d8594c7355a93a28e8edd3a3dde1960e190678fdb9efbb77d744b758a731a4745d474ab70d80f6c6a584757b33e0e81c1b8c87ee6c18def7dd57203855d11ec383c73a0d8a7c31dd1dd29171658d97ef7b4bc24ec8e9b3c46889d8ee95fec5fc3f22ef6ed4e56ccfe91924b084666fd30b902ab0fc67417452af91b708865a1b17bedd9665f7bc4d6d292f0b2fd7457b0aa470843d26f5a592c1251215db1f4b3accf380f7ee371aae37375cb736e471e2b139f7586015d38843032b36b19cdb4de8dccdbe43b8765bb93560bb35a8f3abd2e7b8759d5ff51f9e529d1602d442231b8a1c64a3b64e8685362b22c6a9d51f0d637eee04dc567dd1ccb6c1d3a152c39ea75ff497d59f9a9f34f0961f56ef74fc4d15735597ebb6b3e15e22114c5ca4d7c55e916ae37d6f3fa1e17b68c351250c0b5787ebaa2b770ac2bb805503a5e329d51e801140a540e0e75573565bae725a7d67bf7a95199d249a8999857da269c6695f7c1a95643681bcb58f6409038691408a569b4b03fe29fc80e540b1db00c1796e03143c441dbd0764f3a6ed7edce77568056107c5035cd0919916947ad5571e24fd908a379c2999889199d50083d67a90d62124bfae186d02ed41b276405170f056197916b4aea9b136f25a3a01ebc883d27284784658e0422bf7d6d3d471515909d7755aa5e3344b6bcc2b1c4980082e8017e250bc7679156389102bf16b5597697ef5f6e216ea666905c91c913f7ef664539a59c88da807ca0eb5ee77ebc10d0e25679e839b18922859cd83be91653d99a5f9d57fa59075585fd098bb583f0e786b9800d0466c6c283d7de74706d914d35d33063dedc66990bbb30f4d229ccfe6c4e5ac2b9e1f6038b44316e2bd708f1456c1fdefbd98eafb52bc079994f9db621c6b83964dd8468815fd8b7fd9bf597dfdd211ac2ca8cf6a325f88584d1f326670a42df1d337eac5457af4c3b4ebe6dd33eeafef6da7e7b507c30de0de3dc15f755e0a4ccf11957a03077cd695dd855b3e5ea8e0b26a7aa87dde8825107a72da0492bac71dcebc9a4ed50464ce2ed3f41de840e3989a530aa2950dae57a8c1b767dae9c7762457243e9c52ded6abf49a44a79af47c0025f3f2166da268d410e9d9ad789bcbb9320d7084fa8ba80b314df3a441074d87affd096d5f584a0a6717960fb80f7d7a04d1529370c1793bef4a273ebb0bc3f7dc38982948708ea05b530a1a1f311c0a2a1566d287c7229dda8c306905d48452f20678dc4db97377a35f272c769dba87c14e0ca3618cf61123ed7693589e2824e0dee336f2746dbc8db73e63e99e0702d3501d0333d7452b29b83e067e0c938635910f9522c7557ed0b891b91de11774c563c6d96295277e61c5a8023d12ed1796fa109a1314f69889ece98ba256344693c5d1684d26999c2f30e7b313b3cb52c90d84ab850d6e3d690153bc0d753624cbdcedd1c0397fcb66b43e078c5d894dafe9a569fb686c8f71a8a0a660a68e686733c27904d57b71f251303917d3e9f0cf7762b67cb92b9d2c2e74b5ea21e3de481a15ffc24757022c9f4b30bf3e026f37fc92e6f8e501fbc0aab3ae3233c34d7d6199ca93bdfa946058d7ec3fcddd776f2c5b19514db150709e427b5481f6857ecaf449950f6bf9bc9926c96c11d8bfb73151b83b9fb4f14fbbb0b8e7751ae7725df95474d380b7f2ee3e3f5c472c6253049663fd887bf480b055d97c38d8c0a26783bab5c7ccc16dc11d5e0331887fb1586316df7c37f8f5a0f1b901c05b5c0ae1e250ed6b044e23063f1c8d024d34a61adf88a35eb078465b78704a95bcb5b8f5b726ca0b9374a0e54204e86681e1c5bfb9aa38103c1f90d54642d34361840d16f53d5af64988f35687598125d3d71ee9e399e4ada14b4801b117a22466393ff1ae87f7ef0da531fbc14abde5a6f993197cb4b766501bdee8a0a5d11616a302051ed090732bb0add408498cf9a43b1a21bd319f50ce821fc581d1e99e6c6615b65cf74c58b5edba8fda506cd07a4090f4b8291746169e666ad571fcedbe461c8efdddd3e4cca2acbd269908de7b6b040bd1bc4af9454e62b0539cf9c01ca02efe0445bcf894f5d70b0b83a8d65cf33f4ff3ae996f6897dcb52c43a8fa7a964fd33cadd78ec5f4c782bf40fbdf0b0de17ff57193267768b12e40542a3f68961bacc57ffbcd5310c3df7d036f7e308bb98b8e6e1795544c13c74a4dd83322c04110074c5ca264d73a8351588b810b6ee13fa2dab903625137ddc174ebb21b177cabd3ea857ca1af2d8d753da2b0f6935cf99796511e42048a6660e4dbd6c92ef3e674f7517ab4aafbf60ad86a52e0bbe1192395db7e9b190b4bc5df3a88a8c94443d6b0b36983f347f05ac414ee8cbae9b9f9960bcd48269f75ed4842f3881800370553c688fa16d88c32459a07909b56089be1c72c1f5a41057d05847373470d2a1b071276e1bff21af0ede606f61291e60d52cd73aeeba2f6d0739f6ff661a1680b1aa383d0d9e68aa1d2fbadfe2ecbf138531b5d5eaa14dc63cff7f779217f1388138d1d896a0646c58bb218cb71b606eb4229b02251fef1da4487b1321eeb66d50808932623d1591dca555a1d1e757447b9528990b978f6445485932d4c642e4a6562b95b490b113d133b7b8be74c3f32220c36e18d676dc663a09f375dc7dcea4d64968d5157e4ba4deb789aea730a18a9cb4552a82aefd4622edf2951a9bc522063ae261837146daa6fe0e35c62c81a34d8ad840c633b126a763aee420855f9763469ade69881dc1b17bb72c132c06426762fc85acd07be8c0540eb3700ebd841321e635bc1e0c5a8bfa73c893f9b9837b003d119896e471c0868b3b25ffbc27e5c071fed78069a6beaf43ab19b3370d4e3769688ffbb985afaf76851ab49ad127693b6db61c2f8fe053698beb5652c617f50188114067ef40b300ea0fb662203da2f2e8096fd6422677936995bd6f68e16639b4da3583878c2e3fb2cc8dadfa14b0aaf16f25e4a4e663698ad1d147cb0c16ddb0dc578bdd0526c03ebd6b62c4d53b258071fb6569365551773131778403fdfbff753edef67fb0501f9f632fadac758cddb8ce0f5d192eafdad47a5a07215b32a73f365062438772e007aa226e95c66dda3c1173d318a54c05784becb8a298d4bbfe70b08fed3110ff0db48bc902fec66d288bc3564a3589f450c82c4887df73b477f8208ecfcdc44ac65267df8c77dafd0eee03a52e836cbe7c3a938b0dca3fefd3a31a33d2afadd0df676b0c16341754d35fb291a09d8d462a106ad948128a5ab64be304104f665f6ff48b0ca7ea7d5bb7431a2838c890edebf17f8225df5dcdf4cca01a101cc8ff5489898a2b701826cb5b46b52ae4ad5108b9816c1a75c3eada24de67b1e25073ecab12a57d49709d9e9259c7425c1a4fe625c554c8492762c3306653be0183786dc8061bc9a8f5f66c3b1461926c6b32f84c6789aafa5cfadc42bc61af4fd75ebb61c25fb186fcc6c7b876c15da3a7355a21db584158d764401462387d7876c63cafae7481c080f284b19fef1042d510ee20ec2ba5d446cbb5de9745d46cc7d1b55ad10e863cb7b385b76d670a466332af21a5dc95cf483193a85ea7f3c3b69b281c19b8f1740f007fa232ca046861708cfdd70289ee562222b65d6e246954a4ce464a612d1c5f401cb4a4ccbe21795f7c08f0fdec575419987f45b109b224493750741e8e542c1d529a17ce5492a37c9e0a87a68b7311c8ac7b8f184e5b0334b8c8beaa0ba4361e51addb7768df14a09ae1b781c3af206b328f2697a155644a9a5395b41c05f4ee02efa668723fe0711094ebbfce68b5d5207bc7cf6171b9ff4e53312eb3cf9e1ef8f9e3fbda432f8079380ebc2ef1e3effd62ba2383c51114f522caf66f9b236421e99a773baed9d7be5a3a2c894ccc5a1f8c74cd533556a94c19a882c364236c59d7d42501102d57ca52b292fa4c936d8d54466697ee5c1d4783b872f9877d3ebe30c8d6ec04ad2d2c4dd245775a6ae549e3c26814b1874dca38360ed7b2a926202b4613029157b5875965927c2eb3bf395b8794b9b610bba45980af8ab698ed587413d03e18bf9eb6c219d965b7f1c54aa7e58d7653a5ed6aadb9964121ca6706469220e44e71097c14e409f7d33a86696ae88ed9795c41c5dec66fa8543d3e315a730744d7df54eccd22ce9b6ad719676bc1c567cce0447ffdc0956b590793bb441a559af0823c3671a94720b6552739373cb456024b0cb405fab55fda248140312cd9ad2a2ab8635854878dfbdfefef9fd10e35d4a4380ce048dc6d5ff3915b49c886d78ced188f0d7d83ddebbe7a37d13c3ce7d299d693f978b2e339e1fabac2fd286fd059328e0a81c1302b28523df3cc5e890d7240ba8e5c009e95097bcce1405b1f1da856a56f37ffa9a1809dff7c9fc9f8d3b3812510c6b3460a1ef6d93080bef308b02defb957d46defcdf2c4d12958fe8f5e58b548f2eac6e117d71a8f06d7a31c076fd703d80b43f5dd5a544ac58562a4113e7e2eaca92f44951966a528348356c9f1267e47fbff54d685a7207d16ebcbd684861ed408bfc71967a545ef5059e077d1a03d5ab79fdbb0a033f1d116784c13e99b3c2019df6bc1fa224b41bb174d42bfff6625bf0a573e72c1145f894afd87088dba19839b9bec171b6e954a8555a19a9e33937eee7065e3ed287c58420e2547cd252d446c83cbe0c458cdda8272ba6c8f2029e2017821b0221546e94982c6b512c6b53384f9324c3681593655d2c6b1e7eec8b231f76c8df20232f6e203397cbc145014f2602829562360c273d39b48c990fbc2e6a99093f9d30ef07c7c88b479c0174c05e1013afb99d324d60641518ee5fa5d74a4891a713c5d5671fae6dda473144bd3ddbac1ff2944374dfb1964d150eb7deed8cac36c6912fde3aa2188a03f7703eee770a230d6dfe864351cd8a1b1a5191136640c295622ae6cbac4ee1074c2d68e9bfc2c66a229715e8e86409b8905f19ca09e079eb70e9e06f9b54365af3edd18538a0171c3f8491d46f0e7aac015f2e76554383fdf460e635f2e141471e96133a18599abf3b2395b4dbc8bcc0b8e0ff525d18cbceff9be8c72e1c6df89bf1fa31a4c5b90251d02ecc5e02c885c6f296bfa5085032cb8a9b4a24aa56e53ccd0d2a62e869992714a29adee874b76710a9f44ad5afd2fc6a93c78ff7be2a4d65cfc20a6e4a5dfc339a52ff2cbef60ca0f555f8333b8ffae8bacb7890567413923340f767fff01e1cd86eb7597ffa153f30a0c406011a4ba2149a8ef9c267e71ed1143c8345e08f36c419fbf826f88891447f64d93cddd737c1d7cd8a3a594e1a2a4d2bf0d3b72d0a36ab4178f78aa1383e3ae2b921a08d77399aa6fc63b868ff304ec9645ba5d10fbf592f6ecf6d43ae48303b97abefa05e1895936738c640255530ae14ec2da4982e33bccf33d517d63c176d29c1ba0263ced141041fe8213951d337594edcebdbefe46b7ef7076caacbea6fd6c8322effc19b59f4660d0e4e79f36f4874f4401c7259d388d7f95a1c521dbfca91c7f6aa3c3123e2bd89d8eeb159fc68645e93a2eaba86bd66cd37a66695e6ad35559e7810cda81ab53c68f15afabe92695e1d694e9daf0759b0db197f734a5e03fc4b6c1b38d4af22609d442f006f0b3675230e5cbd6897c77f3df277079c15a16900b515c4c99791611fb68efbb07de01b473c4ff31f813770037f200e35d259bb6ac49ebec1a24f89def40105f0bff6632f04fe8601d7538a027fd33788e7017f83ff6d032e577ce41ab4832c571f326cb9e2c3fe2a0e7aef41db5ba30b4307978a1ffd98eef60ee9c218a0ca1bbf8abb510e11ce41048ebb600e11d24103d2ed0667537dd76c7d16eb4a6fd30b6e0bb0d970831af445dad056e045ebabfee81e942b9edbc66af4e876b14f7b7d81dbdc3aee0ba440a10f9e66500ce9167700bf33171c836833f0b84f75b1d808f1cd7d3e27e0e05e19258bc520179eb9794df6306f8f95a411afa599c226a0662f0e1b0308c8465a13db4853332dd6971e4cd758532397473c1fdefdaf0b702fd534e7d8efce21aaf9eb53d1e832d2e28d6df1a6ad05ee98e684f0a5ef8798a121b18ac12eb44fdc5ba24f9b9c0ea6e16ff03bf03bba3d41df2dfd30fecaecda071dcd86619a3b7a77096026cbc99e3667bf35036e756a64ee0f9c99fdc87b03a79a1ffd434d29a702bac189a36bfac66f8ab9a842fa10366de71a21f6415ee464d7032ae599cc934c2542e36ee9803036efae2076b216081e0208f5de3d7f8d079ec691ec91643931c248fcc04fe1630e371a554c7c2abacd6787187aec3857cb79476cf338d176cd8e8a35e548e65185bd003649986fb3a497c65e8cd69e022a36b4f870bcecd91d0ec5df6b101c9b2f977123052b15bc4c03930707e989aad25225e23a55376251160b55d6a9b2f26734baf2525fec6d69b787addd1ed676a62a4872c2aaf091555d8dec393f10dee5c32aad47f644fb95deb04aeee0f27719ab600ee5c81e4f56184894bd9fac1ac39d11c7415685e1eb88e33dab42b2e0c0dae1216289357ae8fac1020d156f0b11d80ba534be2fa831d903ecb6067be6257fa6a911e99f20085e25d229c4dc80a355a7f9957b827f82c7edfd7bf1c9064213889e9c97fe91af9f01fbae0d54d74eab21898d346db838b278e526eaa1d97d4fac9573908c7c37fa38a04fb117bb05a417396680e9f3396dce7c8ef483bcae85f893c8c95469089d0c7b75145a83c5a8999ccc9c2e8b59cf9304b9693f6f740c91cbe13edf76e75eb954e86f69320ce2ede3e1020ef9804504c7760d0124b33efb1412d4d26403ec324bf042be303b04726c2ebc843af14d7aecd304bb2834995f9b6bed6fc6c0c126f12b54fbc6baf6bb95696401f444169f8a6eb02262887d7abca06d7be45b400ec595aa31c6d65cae4cf6d1a2142027a74c9c7541974cb626e7b2454aa23db8731aef399fc9dc21cea65c05d8b881d3f4d4c37d01d7acd38c5883d1bef0f2d4c37c6cee5f47afbcf1c1827c9b82dd9fd2347c5e547528e53755235c7c441bbd831a1a449771c17b1a6acd765659e3433e22596664174255d8474f6893e1d6b469e2e11b17f01fb1602a5105416cf53d1cfd38b20caacacd8c60bded54bc79332316b27e5c96be5ad0f182bcee46e908938cc4aeaa387719d235ca1dda649860133bc04c74fce0819ed825c295b159b9d3c1aa86aa324fdb8b4796f7014997c503efdb48b80044ae15ebcd34629ffc36b73122662a7ca0f3822c2751d7059f0fdaf8086015f6755bd060fe2d9d16f6764cf8e2f7764c083bfccd1c13a21d6d734c6862e5df546db4bd64ce876f943ba898c50dc8933e82aab93de66e2818db5511cddbc4f5d12cb457a88f4ef7d04707d762a3ef0316fb92e933d3f6301d4c5dcd21b55399cdeb16acd859b862d49d952736d08ecddeb7d1e1e02e0637245c3cee59b1f09640aacbb9463a9965c6948d9cd9f5b259d442dc423e7e22733156e268431cc58d42e45d02c23624b16dd31ff0b05c9b936eba48d98fb6242305f6c71888c8555a8d4467fd21811acce766c005c2baed39469b794e5b63257cf404a87ce6c64c68e4b68e42e133c04176041c1fbbb75b63366cdf800fc9abea61c0c7cfb01a586479bd79ece1e5586e084c103d4c36becdb364dbf9714f4a72d7de8f66b9e03bfb74b5e65d6df2dcf9cfdd23af9c6c89bc02f74705fefdcf72d23434a22b5d7a355a31479f548337d5acb861c701d0a05ac8fc6f52632a38c8d062fed6a98cfd282c9c56ec11536543e814bb513681200cf571962e4c62de99cca68fb8f613ba0339463a79476a199401dcbb17c462d53598549ce28b5dab1242339af603fa64ab604a525b0c3f831097c1a8ace98c931db8e672b57373df1781621d9b113f10180b739e1a99347880b06208b93a97e05668f3c2d9a5258c83c5c503d627977b4f32c156381ca6ffbc32aa2813c7c06d9d811eee9dadbef6aaaf37546f2c4a5d2c46623d50b909c758227bb3629ff06ed3d530eb227ed59780aed74c9d6797a82e60405c660698d617655f8cfbc288a143cbe21f20e042281e73f17ceb62418c9e7d3ba02e90be8eed571c3a7dceec673d76a46dde6b1d92efea6d11a7c2563634b065ed6a7fddca60cdc6de6a65de3a35ae980c13c2ef6cf05ba93a6ef3abc95d7f9b61f07e51705c5ffb1affca851f6fa6dd26f889ac429360fd0979c6a0e07f17691e83ebdb154f96e374f22caf55b928f0ddf57d91b826d334cbdac3deec64014db8d078ce63a49d16f365ef354f359babe23de6792d6f8e2cc005d6f92e0cfa137bb4dbca1b8cacc3b7b7dfa639def0091da9ef8fdcb9ed7b55fdd1f3d81c91f045a5d7de6fea3c4ea894473afa405be5cd56bf7492ad6cd63c35db021da14f53541a65338335255228c124032efcc1ad1988efa172f633e4e1bae4086eaa38d987e59d7a4d013d37d4d933cbdc7cbff472d0c68580d2033ab7326633445fc8ffb8982f644dae5c2363adec54e9e048623808c8dc5ce4d91ad50259023937fa94d3b7a8fc180056c0ac97ac5679a5afba4650682ad788f09aeaf8596502b174a3b2f07b88692c9b36071ac2e0928786f5a200990ac9c60c7d6882206be9379accd22c2941388f08ccab6bb29af9f58db435b02e6c5c245d5d9d3b924273ae42f5e32344028145f40738c4fd4daeb05dabd15503edf45eb3f97a087114ebe891fa25d58413ee759c44749a2f8a1b018b80980b21fef43caddafd43a76e671a59ebadb665ffaa8866bb98466dc66eee25d7aec10ea3a75d7aa1b6c24869fe293317c0f7f600b85ba0a97758f5c5dab3d6b87340357c8ddab060ad91cd68f67e6833fc18c4368be413da25b819b727030c7fd3a56c136d80f31839fbbda39d7181b557b111f2cc0c77a39d565b50b4b6285e778908361c8a878b8592a5cc2756d05706f1cecadf2ad8d9bf41783722b7a3084f83cb4815faec443e707f5b723d12472c6151ad160b0532d4514b3b5645302192d994d72809355f3605a123a2bb87546fd3653a6ad8ef6c37faddc8455ab26c6c775a08f34e0cab5ebf1fc243e9420ce9e2904aef1dbfaab1245b4358413e38c41b315633799d16903b4f0fa7126925ea4280d9839035e4c9a591f5859c4c8a32b10672104640ccea7a518d86c3abb49e2dc78349311fc27afc5c0d1fc3bafc5c0dd3aa5aaa6a78f2f9675ffc19fe9e14733db0c393e3fffcf2f8afc75ffc958d2ead68a9c07bbda27181771c852aa80b512d642eaee4c286df82305146ceb989e9a72a8ce9a72f41a8efda72a66da018ffdae77b6d9a0600f9197281ac4eba6f0d0574e57dc30d7bdf7817547011865bcfd285467926898a0c5cd7ea7b123d77e5f7d905ef02bc33b95a6f63d8abd0b00cefc3d0a22c7e337e80b9fe66eea45ace5f16556092552de72fd455f031ed8ba4d2ffff3d186351dea757e9d50c95187d51b2bf4dc2a6e081a8f965e21582bc5edc36c8c211a7e2c0b116aeafd02290e539438203a9108bb25689afadc464672c1d446b9a2caab05b9a2a5c94966cac14e807aa7c843455494bdab7b7bc8796de358944760fd422106a084be8910d85b4e269124b7cc5b7bc757b926a43be2b97408c41fa3a300886fe100d0f4e9bc8c69da1cf5bacad088446ef1d41f82b1e2ebd1e78d93e623af16de17ccd64d82989a48add0e04a61301e29b4db50160e7c67fd745dea21f293bcd76f1d86eaf23b9cde36807599a3328d5c0ad31e94b2bc43057ed0f79b6d6a5559a280b19a2e680b4a89437b94829a024185b98db95aee7b482f04e8ee8317ed1dca9e1fbdbbdd7a76956abd2c5f25ad4314cfb646156095e080e991a3204ab8699c805dfe2eea2ee83d64bcce5aa699cd9f47584fa72d583565161889b675ce08ed4675ee4455de48a9b313ab54fb5d0501e2fcb6bf53d5524618ced3238ec77177d906d986d00feb01cf5ce9dade84bb34dd1a176392971358cd9dfb35acd6d5cfab4479d7831c79a5f586c16b5aa7700d178ceb8424e85c979814deb250df34767cf80d3b51318ac7602f0a61dc07a2380176a55377bd7f3ded2b36ed8ec151aae5badc09c2576f4ed3198c805924404b739bce3c7c43530d7e6960d5da2559afe8536e268dbfd8d4903c85b992eb8d34b1cc856740888c686dad8012855e94f74ccbcbf6b7f6ff6eaef0d7552170bfa8bbc39dbae75b3625ffb5ba6d768c30a1edc65052d3a6f9d0dd4bcf3ca59ecdfa99fbd572c66d4ff5be4b0db371f48e36adfca1ea0d990ab023f396f10be7762679b81cbf0cab5d4846bd6187ed0b333c2db0c3c103b26cbe31162c1904057427f687db382f8c93af7b2f009a616bb2dc84e018a30ee02874063b821331a8792e2803561e0c006024aea62111f0c055ea03a9eab28da484011456c880c8602028d38e69ae1e02f9f0762af43bbf62e895fdbb2b7a7edf3d5324f4a79e334325cffb48ba605c6214dbec346fcc63f723478f2df7fc31c0dfff97bbb42841dfe66ae10d18ef6ced1b019287943079a09f7326576a6461cf8d99df2f5e9c747a90fb33502c570e8c6720b4d2b75f7327bee195882ed7368599da4d522936b164edd85f78c5962838370264b6e807dcbed599e8701a637f5007697dc1c5b5da5f9c3faffaab2f03a38f71d3f9bf1e4eb6263ac7aa07be7d1d0f7ed81ebfd70f36634d6549639e61f1e0dbe109f9af8fd7f049aff23d0fc1f81e6ff0834ff47a0f93f02cdffbf1368fe0382c2ef1b09fedf3c067a4b72dc26dde1f96a31236d907b3626ed6b77e3b29ce11f91b53f6e64ed8fe98886085e9142720fd3983d7deb36f47347b3f05dec13374bbd80658e98d1f0404441506828310683f6872f28c3c04e58c5fe086469ad91aa2d2195267812befdd4e012d7091f765ef046b8c997b9998afe93b4f284eabc7a3b53dbc6d0a607078c70e0a4dfa617267caf250ad24587ba9c14f3c5b256b0869c2ee37a606be98587c2cd38f03fff3b8460bd73b0c8cde787efe64792f17e94c091f3343f4b7f513644679a6f0d1fdb6f847b0cc3c13af4db18f3d5f4bd4774d77840f707b1d8ad10e59dc5540c1af5c4481c7fbc90b09643f10d641eebd3b96fe8d56e5becd5cd31567708ad1a21c4bf7174d35dc8f6c78a6d6abc33d8e513133d3462fddde746e22e402ade5eabc7f0e17e58e38dadb17635727a2de86ab9bafa4e66d397cfc46920a1692ecf5923529fbb9378edb4aa2546256d841aad8c85ca13aaf46d59cc71645e0eec30e86878dbb1a07f9786f887f6fb6d01f7bbb100a897e61270fd5940805e1681b7c619fd0873fc3789488a5f49768a1ee4ff4fc7298dc6256d8bff79d4163bd4b84f70b41ad953c35a71e9e98ef17d9b27756b44d40f801c09a6ba637c5324699680ef1acdb435b86684bdfc6d436c1adef628761cf70ea9c9c26546432e6f099e0983393868bc841b96c950b1fd3df5df20b41af70db0e8b42d7df0f9ffa4706cbfb306f277d23f7e9c406cb1370d7ff57101d46e26f674cc83f838ee1c7df0b33f3fb7f65fadc7df170173f1e00ec135ef9ca4ddf0c9169d93df284fbb09ce6654be2e9579430862856ffa384befeee99e38de15de3a7a8fb0309ea97c4bf4a945aa3a7d1e81282b72d5f56b9a347d80e8ed4060659bc9358f6cffc3a1786943ee82b5b14df28daf1670514fd2294424ae8dd8b66a8a3753e5c7a63223bcdf12c0e9cb6db43336ab52262ee65a2496d20eea767b7e9b21c832f0bb730acf34cb46a2035c4ca7e9f877847915c4180c3721c4a21eddf90eb260a8b8931cf823875bf908f2e23bc763898987f788dbf261315afe08b8f247c0953f3405bf4700191603242e68daecf61bc9f8f81b8654f9c80155760fa772db167bc00fa4c2d76e97082a5efc94cdd153b0342b0a70532d6d3e613fa6ca07455409e3a9d809ffcb03a9b841d0ed4d97b3675cbb3d728a81f53f2f64cac70b8ab2951e400f2f2908ad951a5fa9fa252fb0024cdf5f79bb1c73cf58265147c120bf4b3c9c0a8b4fe289c6c5c89fe280078459375aad5b5aadef6f095712a319778a4712d094df2e1689005540b65490f407ec86d2dc2215050e1d2f6b71a3c48dcc6b21d149b2aaf553e4e1cb6762acea1ba528dca815fffe11dbe4b7896df2e51d639bb875fd77084ff2817149768a37f2bb4410d91a6ae3cb8f176ae3cb68a88db833230fbac1f9d948748a8fe20dbe2d0fba927cb3fedbf972c77cb9fee77a757f0023b8cddb755fbfea6d5ed57d609b238ed1e1ef4d7ed59b81847ed5dc1a7938142f4b75adaf428d47c4c85e15697e258a65adf1cf38588cf5ad51995f57a55cccbc55dbd919b7cd577bab3fe97e3eb86d1edd5bdd4977778c8df97ddf61166dfeb031eff02da3f778f93f5ceefef52e775ffede2e776187bf99cb5db4a30f75b9fb720f97bb8dfa8f6a22eb5a6d4ead52a5f955a6f6ca8ec093201c77fa420810e02b9508998b674f44553817ad89cc45a94c8a61b8a73578cb21fb291208160d5c54b3629925e651a35f2d949141e8cedd85bd29894b2c3103cfc070cc34125b93c4f0bc295e16968f697a2f681592425579a71673f94e894ae5950259885d9c54af28f0589a219a16e55c17244256422291b24cc84623fee830bad6467f0536fae24074faa1e1befed8eb348c16b663e696bc303445b674c643df77aff43b023529ae0da9e134d2801cd6a98c9a0a37b39ea761207f03f4c50faf9f0ab55a14a57e38cfe542b39d37b37432037c7ea7d6a2548b52552aa7449d2c31a3c6a9bec66000058599acaa3ea4feaa0a315f56b5182bf158ce55f658f3b2692e30c7675de8029b114c94aa2e5375ad59dae1508cd761579a192e4ac5ddaf7eae44f72736f9b773134eece2a7dea0a950abccf53396e52848900338345e8ec71a8779117c8252a3aa1cc5f4977da4415ec69fb6ec3ce86907fb1d6c0a9458179051d43104eba47ee3458a6d4165386a28118dd213f1ae891ee7395e7bf072169f8aefe06e172c5386be592839dcb512866890f852007f092dffd74296722e7e7daabfbc7f06ffdc62b938845096c48b224414843a601e0c0847794b1a666c4c3ec0ba524969c57ec520c1b7000b811b88bae29025fcb852f52b9a82119875151962139dd04f2935c8a14ea869e1622935f082e4aac1da934478f9383c4ea97d0026efc6864da84b89e95f6496193edd64e833af6b7d526a7fa9e2eb19af64babba5ecffa5a949245f0f43add4645923c1567232b36340b73d7fd117b2ac14d9bee9474d8586d97d039f655eb953c444d3106dd9d2bef8d9bcc17f86ffd2ba105b1779388671165b9e8ea60f3fa022774501d83f23ec9f1d6ccf43e467f1359469d83fb3bb8946c99abcfd3948576d0cec2eaf537503ef70ef6ea3e5b471755b2fae1d0e3ae470d47b85228934af35d64dea9633e6631809a7de5edc128c43879b752150e2e0353327d8528243a621c18b42332daad2bff8e96ff6a8db99bad07b84063c33d3f1d0d174cef0d10edbb82269cadb86cead818d81a4d0dea5f92b995fa9eec24af95dc78375af8910d560b1ac66e1a6e25e0629934c8b1de888bfc76e6d23fb6b8554697ee5f23666a6ad26366ab607b1d1bd644501c18aedfa4ecb62fea118412dc71856e29621eda148a718130255be56ecd68ae251e47694d1d8427faf79968938f4d6765116d7e4cfea5c0d8c06c2280e3f14855f60791481fb6e32fd60a89cd6a6f913e708f162391fab72f0f287b367af9ffdd7d3cb672fbe7df6e2d9eb3796c2e6acc30f3f0e6eb5b9e5f0ee8703972e140a3ab712160ffc4ad5a82a43894b2fee08e22f53d72d25c2f3425f98565ff33564830b978a46e2a8b9bff4069e990d4691f47a3a3d3d6de96b38148f652e66f25a89f9523fd2ecc99488ca959c333cb4bc3d08966f94a834df3f5e8b2afd45c526b03bf9e1ad4212f437a51f177614733c3716a1210cc04d61c4e06359a94414c0c64073fd9405518da8545d433c73762e2b48c07b8bb5904ed80603b17abf7ebf5a478ed0136fcbbf2dca87abb4eaea96ec942c2bf5a3380578a8edfc61daedac3a3db0ff383cbecfeabd69d45b7bf5dc4a3161fb715f2cea13dffe5f65b5d49d42df0f50342ec795ae3d588943dd60b0ead92c82acd51b6cf5266cb5a6566bde8a4bdeab7f96358ade17c54d1747d017273d7120fcaf6ff45792ce34f2e9c1c4bf2f12656880cbd4c49674e174f8dbd861521ca30d3deca9c6145431033aa495e8ac3a9aeace653d9981210f85c85f8289a5112b416317d21f7ebe7faf1bdb2d0c88fa693b8e70288e074de9bc9b5247e31eecc2748cb69375b45f0d49fafd4ddc0a3a6ec0410ee2a8f811318886eec4750fa645f9544e664e69a459560f877d6e96ac2ff428de1e5d908dc005d7862545dea9c9989d5dcab254a2c2b4bea20b990d20204383adf26e91287bfcf1b8a9ff05fb3a9513259ec19eca09f924a1dd3ad01953f9d9de7c476aded1b9a6dbd883ee8ce0ff99d81bac0391d31fb92f433ed0c7455ecb34afb00b1c25bee055624950e53aab167a4e9802824d8ce0a224a554971c1a895386c3068fa9cfa93307d76715049af0871384a581cf83211b41ac95bd28468082de690079e7de0ccbdd79f8ad98e7492519c6991217c789abf482fa832a4b27aa7bd417c716a3ad3d05d942a03584dd9ec62e0f6067d093d7d54fd4a25413401894c75eab1214ff2783cf0747ae5e5d248528d5bcb8569aed30b53e7335981d86b5c4b0f25a7b6f44476dd2c737b91a683730969e4dba0bfc81d2ec605ad139bc5178146909e90d33d5df5dbbaa98ab7a66d3a6d0398e76616e2122cd374a4cd33c69b0f0200fb5f6ba310e0d2f3569a8820d7fb4d3b631af155d9ff62ad8a46defb21b05f41647a91f7b38487c9a05408c588f00e08b9100d002a4f9959e61a3698468de5af5e3a1fdab2e40be9d2ce1dd99727a64007aefa7017b403d2c4bb916c594891dcc6db2cc41f66c482d204f5ee434f26299277d9067ce17f55a48809356b426c6dac2a22f7747de117d4936874c39196bfc4b11f8aeb80b1391b599c41ec8da68f107627e6cc4b4fe6e8d9b3564c8ef7cc56e65acd71def3afe10eedac0f85772d84c10cbd969f14d9070c58c311e6bcdb2c05e9e1d3f32e26de3a24fe949fd21373b6ab477bdda07e2ef95e20f2d4d03dc729f9eb2b8ae1fc20090a2bdb3990734cb10795efe6a0745bad3dbcd2c100881704a467f24b32c388fb3b416b5267f5c10d1107b1344d2c290066c8f2b9bc6fdef4307ffe5640b40fc06cf019ad87612b11175cc9de8210f2c2e3d4227595131313ab351f8ef8a1177b919ff8df08976ec7fd235e85079f345d6b822e362a3365c5fb562b92391874022e90d335996f0d25f894901292719addfe576fa03e73f12ceaf7e4b6ce74c180ba58bf17009d12a0adb0db7f14796bbfc180a5e1aa9875a5516e761c6c2bb4b741a53656e91e7ad429be150efab7151025b8ef4ea4a959abd903963ae34ab75a348240a8a1d99af8d22d0c2daa0b4ec9bd75a5eb04720ceb8c93adfbb273ef16714e5679b9193f7604fd7772527ebbb9193f51fe4e4239193f5ff6472f22638f5cd93fe0739f917939373b259ba6fac3931e889e77e809fee7baa4834327ab4b6d80788de30f26918e8ddcc54a94c65970339d49a5d0f1645056a790310b568bd864eb42acafad1fa1f9023cac02d1518f1f96380b281aeeef46ab22fc69e5eedfa081c81d106f081188b91e00e6ad7c75eb1142331f6b5bdd747831b65d36a5d1f9b5f0fece13ba26cc087ba14ff1cb142aa7fe8dab6cdfca6948b47c54a55ddb1fe2fd30067725d2c6b2873a8e079cf8d8b55bbbd1ec2db2dfafdb8588953010d5c020ed63f1e6e673a4f125de64eb21ae9e6dc5c1e3e0cecf13025cec4172ba4d577f64bd7b90de3a26115fc9b50ddfa3cb82c1d6e9c4dbc52f573287e92ceab2ed6acfa2831e66bed72c14095fb2d6b4a00b6ac26d672d5dd920e87a2aa8b52094ccd464eda55ad64a26f2917d7f846a4fa74e2ac38544aea66600fdc729a957b608af4d24d9759866e2bf7eed1ac07f25aa6991c6798e3c2341b99e2eb47c5ea7bb982c270d894c4ad7ddcb3d67153d3c8c0d9d066d8f777ecc4843b3a5ea659f2dc6df99663131e2f7b8830ed9e4f781ae490c1ea93e3478f7c0c2d204abfb71724686312e7682090766f2f1075b1688ec5a4dfdb0b12f9cbf402cdbe416635ad1fe6c9eb623182351b4c8a7c22eb6e5d2ccc6985d93ccc93479409107e9b7ae49647552da68c9a778f3f2a5bb363da5eabb24e279a6ef071a053a10d8de4884b5d2c82319c47cd71ae54fdb8988fd35c25dfcb55772e572f6592a4f9150b3dde17ec8e097d715d8bb7f282357a2b2fac6550506fecd51b5f34af05f4e506aac54681c7c4502986f448c0ddc17726dfb653236d8773ea3e33d3c51b725acbd58d3b81b9c9c204a0abf4172767048628ada85b71232b21b352c9648d362a98b9a62f325557629a96552d4a952c271849c899d2b995a05e164575210eed7c744d47f5d9c72835790077864d37091788a565f1ae0e1a5dd1ac75e32b55d352793cc6b8600bebd7b3d6936e9531af660c17d083d541b321edfdf644ae6200d0c39641d01f22202c718801c1420f8cef50cbea1a8a17838399453918e6f54b4f018369e2d4d07d08ac8cdf0e773c90488d1d2dbd4f90bf33f70c07fd9d61c77684ad892ba38c0c23ecd83f393df5eeebf7efddb9090a9d35196f706a4fdcfdb0708685de2184e366f4cbe5124c5ff16d0e31192633fd9682902f88ca9d4a2469a998ced56397fc13d33aab51fba4e2d733ba577c6fd7d5512f6e54bd0b51ca599404a4862f8b4a3f16bd6388f38e23e35ba4238cd2ea0f611a065ba0c90082f31f03ecdbad4743066bddc48d0def649fce0c56411d6422a012fbca91987d6608d8b8b4be97e5559a575db7910c873f64b1e700f8dba2343773659fe8feda6345712a7ec574c6477d0189848ffa82f2131ff585490f7c64425d59584d0349beb99ae268f0b8356c7fc3dd0cf6db4aec7bfe2e22b498db59c0413f882dc0db80dc98e8e6a378659f7e44ae77c3222357ea119fc6dba454a676cb33104f3410dd3ed6ee1b7ad0fe3c848e777dc8042fc318b7610a4c4233b38bdeb3e5fd7b4e5dfa411dbab3bd4a2e160143f90609e3988ff5b92bc24ebc54cf0b9c0cb434903169506e2f6209178743f1249d639091ca926489d642fad5a7ff93ebed5f6619bd01f1953e5653fdbed2ec9407eef01b71a3501e5517b8b71878d1d5c28fc158b9331b99377bcfc19ef8550c87c23d0f711828feca29e7dc5889521d4e5370284f7390884da4eb9b2d06c807682503a1143b6a38d4070efb1d84e811404c80451c318cf68fd2229313b5f3615a56aa74e490788445c00aaf3c4ae998e9b5f77dbdf124fe7e27aff638747728186aeabd270ed2970a3ce00b8255464106a6fb1c8861fd4228313e8e432e891bf7418b034e0ebc8e905f5e7bdf2c03bb16078cc9f7ea18f1881beca130b3b715d7540101fa1e45b1355b45d76045a3b8613c1c1fbc97a52a3e11af8ab71a3e402b3c61ad715e1cf48acf3b720a39536226c599195cefdbdde23520ba5923753a423cd005b2029658188ec0cd8b1803770d2017e10fdcc47588f815a014e819395343e68b85f373623e91afb9fb3c592281cd26f70137a74abc2c2a74dda4b873b244f72acb02d0ed8e9c80bbe6319c03135cf051e5e039782bac60588fe98689d3ea029dccccd806e2bbf46aa64aaa847179a7cb125280cb1bb906e51b1bbe7e06f01ead87a73ba7ccc3932e255a864af0bbb49ea95c688a2e8cc8c55e0f3739efc2b97a7229ae38742a4c7aa8e89e88a4353b14dd540d4002561809562fde0b5ee47af1e43b55a12f9cb1fdad4674a1ea99e1791958ab6210161453eb78df04ed5eefe250d8763217e8628b919009c9ada95b72a5aae826d36ae3aa53bf03f13d85f9b896599a0839ad55294cfad7189899c1157a80dd191090b143f15cffa307cdcfc0409c29706da4fda9d695b1669ec83c2fa023134d143b8975a1b7ef50bc2e16bf55078698bf827f7fa34e2c694551e6c7ea664841645ebb6350a9f23a9d8053c4b52ad7a252d954a8d52293b9ac8b723d10e2997ec397aa5a1439d223f0ff7420344a6aae8c8c684dec9b4cb340cf21df7205237b992d35d70c169ca5cad6067d8391d0248492550a96f3576955db0834c065695e760dba3f0d600d8c2274fb0c2ce4411848e0f8d021ba2ee8096459ae29a21eea5289e632c729d29918a72973078dc4afcdb8a5afcc18250840eb822d06547808dff5a8d2f9225b0bc9c35015ec78c3604af5cf655aaacade04ea6a10ac685fbc4eeb4c19f8bb78f193a502b772701717c67ea026f0a71e5662d8ef4cae55a257ebdc45669549f2a888d82f79519c80e3c7a5e0fa112bf4c0af5cc3cca379a7795aa732d34413c684694bc8c1d48bf8aecf84bb5f4e45f0e1fd7b679160aa33fb07fff7fbf778b5f2ca460b2bf82f9637173e6b9cc1b045de4fdd7924ca96f1e864efb65ffc346f49296fda22745197ba0ac593c514d87e44d9864d825d65fb5466db80af27d83f944f44101d6dc60933c10202ae7f69424aec8c8e647e8e812c57d682a70d3d59873e92121ccb84604586a758218aaa0ea8274f3241b139863ee0bfaccf380730320ee62666820682fee471ac8700a5131bfbfc784b82dd335557a25b981bb6ea593324a2a357e9b5cac54f7a617eda993078d1c3604db3f45a6147376996e9d32f930418c3de9ef403830b2f41cd5ccfd81859d6a8481011676785be4d3708d018afb0adb51dc4a950d3f209ec9eca02c22abfed58faa0996773fcf5df78be3b5ea4608a5aab1b9b37332b35a9fb581ff7bde0b71bb20094f04a03c8ee81ed1beccc64f5c34dfe12c3b0afbbba6eaf61a8f3567fbe7066cdf83b2a8a6962d7b7695d11776d02cac256192c212b79fc086cec782d66f25adfa210534a1fe2b99295deeeb4d66c0441062ebe5ce660ae27c5348590104266574599d6b3f0d4b747bdf2aa852caeae877f43cc221c724b1bcbcfea46f4a3d10a10ac918c85b0eb061594d83672d9ed14fb0489c70f36942b9206b3e5c41585c919165666e4aca04c93ba30ca0e0fb4112bf959687deb0b716a57926a7be204af81d56cd975344d3c39082927e1766f184b7096805b44d13bcf4899914e9aafac220bd0e75575dfb9baea6955a95c7312d95adc28911737ceb40e9142233d617f8ef84ca7e07351a58942aa8391c097a5664faf650571912a91a5eff01a9b165956dce875b09535a3addfc395787e0c8cedf313783fc345a55f41520f5abc3a46b655d1eb42aed2aa2f5edbaffa51033e0a324f2cec47b6985e0bce630c7b2ed186546655213e17ff5ccaa494797d08e3cd8a8944bcebc238f4450a5d736b9aac98bcbb492bd5836416e535ead1e96816d7aacce4daebb1e280211a04840c38d4b4c1151479b6ee8b1b4d166a64c3e11ab72cb4155cd83664efe8d4fab57ca78c29d77008f6b165c96eac7a561637b9dd075bf1fde11dfef7de35178dffbd3e16dd6f975926489cddfcdffb8fdabbfb8f3f8c9348c741eff01340eed6717bef8f8f634bc13a7e7c12efdd0d6153735b61b7b9c78710347fae87fcfcc46bfed8225af7f151cf6ffeeaf863f6fed1e6fef8b36d2bfff96fb8efe1ff1e1d6f9ffb47c0f9a0d393dfebc4f1eb12150be254fc005cea605a2af58b72a6a84ee340f2bfbe57f21d9991e20de9cc538db49afeb005feed3c0a6e6b5b8ddb488695c4509c88a17fa512e7ea8c60b99de3a871c50fc5c9b9afc42653073a36a78227b53cf7ac7346b6ecb66fa6c7cc6a5ba7346b0cc316adec3aa1ad91f9be76dfeb82d2d0b04e2d27e01be1fa0b43167a015fd1b39a3bce4e7c0b26649a5df4e5d2c4ee1ba5a2d7414c1bc861bed6d7a106c9e4d10ca8662d2de0609031d07ecc39927c73039d3ea954a353d877129cb3dd6078e3af610eec18c8f38c144055f86c8420d3cc97c8a49d0a34ac036713ba6d79bf2f50735d2ce09da78449a461df160d5b99a6463030b8099464f121fa36a91b87893c313f5d760f5123e52b2d5da4f86231f23578a1b26b93b6b3a107dba00b0c65476c1f4925829b98e68c487431512fa58c8318c42b395f648a2c248244f7b86c6c99ecdbcb3336652f8c9822fabc26ea03b628c1caf63c9d26292cf892783673be1dcf6d187bfb6526f50b7f2ea626e272aa27375739a60013dd799aa77399f50628e9af9412b3ba5e54a3e1f02aad67cbf16052cc87d0e5cfd5107dc77eae868b65960d3fffe2abe33fa755b5549362ae611e7e76fcd5175f7ef1d5675f59813e5c4f348acbb1acc0511916494e4090fc189355b745da374132c4bd7b28b8c4e78d4f42ce960b88398f11c4d7465e2dabaa98a4109702a5def832eaa6f9245b26f8e2a75cd92749cf8a36d0738a75165211e65c64877585c9b6d4aaee764e920e9865e4cb2cf3f7c55b8d04b4dbe77f1a7e7a0e8bffe487efadff7fa9720a939ba89aec13a192d99c445ea7c98dccaad920977335c46a877991a8c334af3461a426c3f3f3fc7fbd53eb6929e7aa12b49587d8c3a1cd17297e3d3fcfcfcf6b9055fe2a8a859c40eed3a3c1575fdd17b7585817bce818bf63593e0820cf8b3cad8bd2c0b51d8dda877034383a3aaeee3b98f1a5a9d25f36ac0c43dbb92c273f0f275575488d0fffb95465aa2abb3076d055fa8b3243eeb7151caad542e6497b79352bd3fc9d99b24b8721c755912d6b751f0baccde9486475491f49b17fdfacf4c2fd306601f4d31a05d06ffdda9d66c5cd4860a2fcfba67b30033804dfd26a048e9b5404719729b9add7e69743725b3a3cbe1fd9dac862886f44925e6f9df20d7281c747f0bfc58a3ecf88b90bbfb72dc6c601d1eaef35a093a3a3ff08c6c23e6d1cc69fa247fa2fc7e2540c3ffdf3e5e5cbbfbf7a7a79f9e9b0c1945f5e4232becbcb119088fe79de21bd5167e4c1f292b957f53a53d54c41f2534d6e7eae9e42aa8d6fcb62fec2045decfa6371cd9ffef8f2e18b273f5cfe9fa76fc4a9e8fc8556b0731f8b1f9f9d5dbe7cf5f4db673fea52b3bcbcf4ecd9ff7d7af9fd0f2f9ebdfee19538e50d0e4487ef036ff4eae98b274f5fb536f34945a4e1c317cfbe7ff8fad90f2fda9a5ae2611adb169767af1fbe7a7df9f4bf9ebe787d0622755b97f2eb8bce8d1abf4beb87e6fb197cbff0ae50203d986662bd509538fc46985b907fc7fbf34551ab110655c353475a411bbd1261c85289b95c2c5412b9761375adb262a1cac1bcf825cd323928caaba1ca0fff7e364c8a4935fc871a0fc17dbc62f134619a97afdfbc7c7a662ed8ba584e6630d591e8cc8b65a592e226c76c3d50362fae9529d27fb3229527a664b9e8502a11202710c3da94c10faf5877d1ec8e0ae31d52e172d1d263a6a46b562c6baf10ccab5c51c800bd9e2971fe27c86ef827d40c905872aa59434a055b4c21a034d9a49a84b26bb21991592626329b2c331211cee435da458c210abb2af57153c940bc9ea59598ab7a562462592993e166be5842682c485a564cc54f7419fd0489668d15904dee0da0e95114344e2bc8f0a4568b52556440b148572aab74e7b206d38499462c48f858157305b6a895007b0480ec7a9f41fa2358149b8ca52e445a579afbd7d88af64fe0bc54d5a2c8ed08d6aa16495a2d40f5de07b88c7716633591cb0a274bd5f0faf9095cca0d78cdacdcf5003c3e3b1bea6dbd842d0cb2b8185dca196cb8592351942ccd7a3a15cbfc5d8e92583fa077a964f2f74a25bab971c4ef5bb46076b2883e41fa3a484e1769c6bccdeac94cd974669a85843f0650d01dfe7fddf3f3e4a0d73d3f1fc01f0f16abbf0cb1b935d347080f28d67e973ebc3dbee889919b64186ff899355920dc448618910b433342c007c0094db98a25c4a84aa72809774d6857a126ee3f467e33e62cd72a575505266cf0e44e9a599806c0c8a96e8f8ecc0093f260265c9b92547caa7152b37ae53ccdf1312eab8566ef4b7d1e81b35f2cb2b5cd709a176022944ed2da288134a6c361d50dd3694a7477e8c51b4febc730b72e4eb14f4361db5d51da41ac30809ff4dca4e457ddb3473d537ca5ea87755da6e365adba1d603728863b55200e84cc2bd1f50f6690d604d2203484ab2e4ad1e968b4e513440c72f3533664186d943443189c5b4f09bdc7564f161d2dae5b87f9ef4223a38ddb3443b720f69a040c4a556508120c8cec464179c2424f940a9da88b5c24aaaacb02e2af609bb78c87b970120832c46156b58693e35375d23d5c76362397b81b535f32d5b5a55e5034a09f5ea255ec0acb0309aaed0c4b6fb82bb9a7f1768bf66d514eec1a69cca783a677382b306592bc2ed244a8555d4a8191b681dcc2194bf32ccd150133015dfa644671034902d1385871cb07776cf179a534d99aa80a558bc3e14e3201900454c3932f3efbab6ee5ad9838f55710ec9860421de637e861d9e929e2fdfbf722fcdee9f8590e10a6c14e8f7c9bc3ccd1d325df70cdf4b9b474939bc4b0b38a09366c9b88f1b89bc4772e32863f0b56c0a6a11b72b2628dd9fd6a26560b270144b3a90124cb033a45b8283255772aa29121f5e409e81145f425afb988b172c4d2d0ee65a54ae059406b3b5e9be481fa3e20bb37d4f633a8dd74a0062e961df4fd4a77dda36042b5eba70fd1700de1e244be988a9341b025b38082dd905ec1a40d8ff4a977e1a4d7e2cac030c912c7382a79d4712f6c6a0edeeb316e0ee3790759899477b13f015148252a2608b30658240c23db3bf0514a1278403c4fab5ae5aa1cf8a2a55df8af872f9fe123e4b52caf543d0c41fef94c4e55b6be24214d7e4559802f6988c6b09822b9da770c15571e306786d20d0d0e791b1edaa9aecb35a7112e29313dc77173acd5d2afb77dd159c84ad340e3bd4128acaa2ccdebc324ade4385387b95ad587902bf34ad5b52a0f71674c832b2f56b2b7f76c9c513f34835037699e1437837049bb1d3d32901858db31142f8a09642ce97a510734a795e64b4dd1af6499649a1f2ba6688b701e44873123d378d5edd924a1265d0aad0b86865a6a12a2c98f9ad4481b1ecf4a7db16ba4ebb84767073d3dcc73b2432f6234c1dee33ef9fce4af5f52bca6384e6c449907e2571afd08c67e2b462cfe9765ff6492d865d6cf923ea523cde8232d2cbc581afbe257ed47c7d9f46e45d3cf9d7bc5ea1fa3e349a9648d900802198eadfa62dd1798af128afd581e845a98fb171a32d5104975e913c218715846204e355623b1f2c9a478205662c4ebac4762dda8b3e6759a814aa6200cb3bd766149fcb49c104a66bdd09c3c939abc859a98f1558fd5fdb44c30c4e9da968193f7c7df6cadabbe282a0aea3658d31636f7ac9e95455d672ae94ef33ebcc91f96fc6952a793776879e72820d8c595575ed692306b942518541162010e403ca90789e94006139965dd86f1368d425333faebfd7bf8d3aae0c0e69086d6e3d99dcd603d32e816b654ff5caa0ae472df96724e0340b2d86f21aeb1152075714e46e8344cb0436726e8b7be6d73cb7979925e772759e56574d4f77731815519d0fe22c7dded24e93531082a1b4022e317720e8fc70ca3f976387240fefc5ba2bacf7c159d0d1cbe9782231cfe2b60ebcb6e2451aa5c9d61981812c2479eb44fc0e5790971dc73557ef7fafbe756c89342b225489665b312a9442cf34a4ed51dde0f5f7c7574e29e9d306abd6c76134259344b5a850a894d95c581e890e282bd6e4971b0b521d6b36f5c843300795bf278966649d701a0b855d864631d400398a7570da11b1ad22c47c87ef965a92ad00f34cf080db69a9445963d47975ddafafb911aafc1eedbaf4073d900c2abd10461deb9c090e567502b3a587f3e365490494bdbf3a0f1bb9b1474a28343e8f46d3f83719a27aedce00082e220700eed205c39614310128cc6ce0ef47e3a5b16f5507375df16e52b78e11187d03cc03895429c8240d51792bc7f2fbacdafa7e2d75b87fd8bb258adc15c0ae00cf041f992beba18a87e12da81d5a620613b3d8dea6d188df6772f107d048616712d0ea3fdfa767297570bf7063323646182a93f7ffee5675f8e0cdb3a879758f52e5dc023f7f1d999701a693404c6cfa1320ba83a8184a8b79a414bd0a500bd52c8e262ae9254d62a5b8b2e24eb71e04127ffa037100f27135555246425983f15d369a5ea97202cffc9a925c08e780a722270d5cb8a1b12de1eaa6b992d65ad9a336912e2aa1e306abc90cb2c2dd36a36fc22f9e2643a3efaebf1f8b32fbe3c9afcf5587d26ff3c2e56879869b3da9fa2ebe576f45223188cf9547cf209b0b67c9eb44bf01d16586fac66b9bbcd1d880484cb236766f7a342ce0c5b0e05135821821934fc201c36be60db10d98bdd9ba84cd5aa6d90369498bf98d8cf4eeb29930419876054eec91132d61f408c10af9e83b8ea9d520b5197fafc80af435ad191321c01aaa6961509439ffcf0bdd0accf1a4f2c4c1123700f9abc845b2e9fbb303c1263b61b3713d03ebf7d60f435c15c8908d7f39a99cb148a1e3289d4bd7ba8064395d88b22719cab06a64f8903f8c0fd3d9864a9ca6b1437b944ace7b5d99a2e7f707470a81db35fbee8ca7570ef5e4b0f5f8b1b28445bb5d004cb88258d820781811cb99a95327f67525ca177060ec64a26ab6a39571e28bc79c7fafdb2582859aa6420ce0a7163a5d3f24aa6b9135fbbfa26a1f8a1074f4da76aa29f69d95acce53b37926a2eb3cc621307845631d8d1c003f688f85e0ad69e02c72b7eb248f313c68da0b0f3d95afc444f939ffa04df1f1bda0900a8abbcd0ac332d1660fdcdacc894388989e5f9caebc1c03a26e2a62cf22b94039bd46d28e944c5b04afa2e503d5a5279c0ea9b14733b4bbc9d447751d4e8a06474dd98fd59d3f69e6bba27de7912ce1e3bffaf67ca1ed55ca9a4222f6f59d7723243533e70bd2c12458ae4bea80a4c3957563c30134104af3fd033fda41bfd04be3a01344d3f28bc549aff8c124ba31981a19878ec1a66942ffb5052d14605da0f2888460ca7ec5afae2667b9a91c17c0473ec52ab3e3bedb078f0b2f037c9c9415f374ff79cd4abd7ca996ee3a9c687085fc1aa96a485dcc0e1bbf4b9316159e42ebad3e5de7a15101a36ae555b58c7390c4f8785b0efdddbb437cd22ba96f16d67d0c55a8ffa5afc9f41d8aff93b340a23ad9fb11aa18f12e2a8d5d62f6da1971a5098b99deaa7fc139261bc3f9bc9a4b8795514f5ad288b02c6653c9df59fe836ad1100be7d0d1d7d338866509f54c6495a8f13cf301eada8f65d173c3e3beb9a6efb1a40cfe60436dc6655cbc93b63ef084ce73f879f7d757272fcd9574d3430b09a5c48bcc43d8b407065b69fa65c816147153ca8c3625fa8a517e15474869f3a6538989d76c4819e1ff35b31b6056df22428b72a27d411569efe5d738a107849adeae1a4aa82ca5c741074f25aad6035ba7ac96d44485a225fe6a041f958d9b07f3cb1a99cadfff63f344ff6935e979f342f4b571e28239775a11f281343765dec2966ef48314734b52688e48691adc90ad83dd4c827bcb281012c7da74bdebcd0c9608b005637693d99394b0adb5a66faada256b52a7399f151757f4ad2aac6d74e77304ff3de83c1cfd54f261001a2fc5ce64bf04148e70b48838e09e6df2932ac4ac7a52cd760e8256b605d80ab91f95a3c3e7b6922259ced68966f446827477f3d778ee2a4b97a7c76f6cc2c3229411a9ef660c2665f9ab3224bc0760ce269c180cd56eb1556b9069bd8903b26d38ecaafd3b2c8ed7d293e158f2d37640c150c207d26ea42542ab3c942a0fbc053c1c58c70c91f697a97340e544a1453818262b81e3b5675d0d114992a18fc0fab3496831b4c95aa2a96e5c4d8ac244a1f0b81b1157149fc20101e8945d3223acdb746c78d01ceb0cce3305a27aa7999e7854cf46c9ddfbfcf8fa3d47d965683c8c6374c0998ad505a21df57c135a0cf0c85396397ca7c5919fd3ff0be4ae3348368833180a4c3411ab03afb60f297fff919e7983455f20c905e996bea41e463b7274676b3bd77550d5a6b6888f7c4605654b578801db84683999289e3c5ec35e5daf71949880649d9e8e7f2ffb3f72eca6ddc48c3e8abc0d9ef37498b222579bd172a8ad7b1e38d6a93d827f66e364752d9230e488d3d1c70674049dc480f749ee3bcd829743780060643514af6fbbfbfea54aa627100346e8d46a3af9195196e1e61293aa2180cc53b959b8190938a1be65c6a42aeafd7c7390b93e3ec1cac234d3b246bec4003699c50eb40da04d16f56d30b9135e2d3ff651ed9295f9993bd5690a4ff89be3b868f55f60eb25067453597f5b22e2a0d51cec14e2dcbf35dc50c7331c48873f371e0d07a71c80d60272914fffc395b3695acc778debf2ed5f4b3ac1d98fb5858fd69ef8f9e73a055a069271c923a7d94b8abdcc7a2c2948e6a265a048b86fca3754a222807af3e8a5956948dbf7d2970a1034bafe3ac1205be26554d121a8ab9020467592b8dd604fcea103f49d22ccd57b269ac64145fa960476fe32a15b5d0ea1d1c92fe806c22cf579a9e22284bc2746ab3525ec32d6b98017c318b42f7fc8033d1ac66b3625a007aa82ac7b05b058b878976d316f95e91e194f98a29ce1bf111f1eae3e821bbfbf44f7ffae343dafd7e7fefe061ed9e1df8f33af538437fd241024a548439b8c663612e237f03fa3b12c27783452bf063c068420230cbfe1490ff18a535c8d65994014609a3901077442ff34662749ee4857b4a1ae951704b0694104d45c9ca37a0be87fe598aca7a9c7a87e39ff7eb1b5acd4f29b32641e2094e188c9f96335a5f6698f82861eeba55d01eb284751764006144a5d4f0c49ab139dbc8b344acf95a2d239985b5792768511c27337c2f062f9a1f5665f9a6febb21a17d68394859c3e1d3d7bf65a05b2f85880cf55cb3e0fd63da0c71746d29932775918c9e668146972825e0b9da0cb4a1f82cd76d8b506871f259aecfac217f5b3c6f8526b8e3dcb89e094ee0b9612378f79d5c1b79ae4cc3ffa79f455e34d3acce653ef0a165ae003669e69becd2303ca8090223eafe805b5403fd220441598c784767d14bc8327faf1994d69c3db4a4a170d21de4f4aced278ef67cedce296b0b18d62687575757a3aba7605ff8fec7f1c1defefef8a757bb177a513edb35bff69e1d3c1beb0bb98b60ac95c3c8d470c03aedf32ab5dbc872b69b354d31b77eeca13d2fff196b5512672838f5b11d583b1257d29a2ba6024ca47e18f280c8fc91083524bbe868e6c56be48a46ee39641187662359598af35a5d35b2f694b2add8b1d6adb16ae7f06eb2e3252eb6715be2922ef11217af752b408862a52bf68b81117f4bb55e63b43a537e824b5be46247f43ef4c48e40e32eaed3be0cb37a3a21f6463332c7593b8ce10a68bb906d15b4bb2d5a967cff27a14e52144b9cfd6f832c614cb94d28d1aa79f7f6f37b3654df768d3ad2cb76efaf733e1c8b57dfbcfdf19b97a0fd7d170464a8d5659193cce43c9b7ebecaeadc497fc0231bade0996d75cbe0d4c64143c1ebc69a01646bf230146f96b2cec41f87e25d36cbea62285ebfde1f3ddb198ae36ffebcf3408fbcbb2cc2116c946f99ae633770ac94cb652da7f0f843b7b24b59836be6c1e88fa33daca355eee2ab66dad5789a322cf797beed471c7193dfc35fbd458933ddbd4ba9caff1b372a319c8d7bc5eaffa7b78b7505de18fc20daa3f697f76f5ebd11df1b3e863d28ac4031ab14082fdd9b21d318f051e8622129a6761414e52812688fac84513c8f45dd9328b84980497fa9ac573eada0addbde387a9c8de6853e57ea73332ad4d870b4aac9ca660c9c57a5c7369c0bf13f000416fc60f47b5ce87128904fe436ee47b2790701b6cac91a7d74ebd09ba11d9cf565569aa5c9dc534f558dae5764b75c182cb67e8c4c6423acbcc12f3e69a2312aab38f9e9e94b2b1a3d7825ac2ce3c5db63c368567956e767bffca52caacf5ddc644e9d8d6f6389ec131711d8b0e768a48e5f40a24031879520d19de37c5d7005ebb3348da30eb7c304bf773a8928b0b0f356ee12aedc26568bed50a75c71ab5d02e7ca6893e011db8014ce3fe443419cb5f02001987802a2b442ad1a88868f79dfadbf583842efe81badd99df3b7abd8b11a6c295d3a0f9e53833cf29bd5742a652ef321be27410172ca4371773ce293eb69a3ead343cdb9ca59a6268c7b1dc4dbef08260c3f23044468285a447a1b40b0ba56e0f87091fa74268e8168de0eb02c001501f1e93ddcd877c58f722a21d47666b84283e9142f2aca06e00e6fc38e6e3804e192d10c50f49755c4725a459f5b3c18ab9a4e577510497bc343ab636fcc3dd1b93301c6e22eca9cd46e6dc7b8fb6e190b1d5fbadbf4c1bb86d0b6d9b1f7ac43e1fd46da31e8296809b222a77128fa4d0b6dd6f97618dd9628edb83b15d212136c4c004e94af08520f41b94bb481c179b5aaba6e528016de81fbc11d0843a27a6d95f45f6170210a50e54d1a38378b93b3b4eeb4c8cd4d362b0cffd7b8a44545055968ac656e2e9b695d2cb5aa1b31cda617a175134478e661c5f1d4085c4fbb502085714387d016fef7481c57a8af9d668d1c9224c67474fc4a389d77514d6bd848cabfc78785f66173830540fbc926cd8591868b789a95e5c6e5823e8f73ca1cb181802299c4a9f59b018639f0a62b6c66d15938c6c42d276737f4d7addd46b7507459f49b4188ee0892e138350c03f2937bd3c86e3dbd0efb2767031b97d3b64bc84fa184ebed66a2bf74191a6cf1519c88e1542f31df05d5d820d0c4c1d142efec049206bfda7f77c8915e6f085954ccfe130bedf1f2bf77a981b1cfaf0d371f2f7820ae36755a9930cc06d80c1839cf7ff1f02db0e94920c15027cdf1b4ec195bc36929b33ae5561cac17cf54b3ed9828059961835dacf9f6f09eb7382d0ab173c7b0d5aa4a7a43db14cd7cf43c7145f74893cbe750cfafa31ba8c3db5bd26cab996d858ccc5d6b3f97fa45596e3b8b8ee11bf6db1bccd8fd327cdd47a0f41f2dbfe8f9950ba53e03598ef29364f5dc0d99479ce27e26eec1d58846a94a80c692666d0347b06ac00a43fc1d82eb3879d4f6504008739ba19edbaef7102f372deb7ab5d4811150360dcd76920cd47b96ea859e8333d0101b66caae5273e1dc0be11113c3b4fc142c987dd22d5c4a329a36ad92560045f4e5683e123dd42cfe1da2acf6063164f086bd152766c9cfc4aef80642ae3847581f7b885e46300203be8d863ed16046d61860ecc087d8d8cce5689a85af149e24905355e0cad76db9b1190239b8062152d8d54e54967dea07a27e965186d549e49519b2f2214dc2a70cc6053f0c12cd602a9ace6c331e5cd837cf3c43dbc9cb891b745568ab8f684827664d42152559d8d88a4747a26717b217de0236b23a4a93cfec3d04eed23737e2e48ca7b2b29972cdcdcd8617046bf083a0d730fa2687ab872c01e04194588ba30883771bdf4e91cadad9a47653568e226a96a4555d0f5a87e548510dad3df9c521849585dc9e75738aacf318a723dd876162adeae3bfece06e6e443ffac49543185d677a214705ee76703bb6d39e615d36a694222371e9b64f5a5044b1cd8e68accca1866cc0628d860f5a1205b521f30c1ee6c671540e489b41b0d84b4dd9ea1916eb5e2c15017c0063152859021f0304efa08f8a3cb0d9534b089d62134815792b1d55d3716cbabb0c1a9a4312b4a31ebd08755aaa4af6c3c72e3ecbec629a61251d28ec8a25d97a4e67a10227415077628f53303ab310135c18d876d76fc257b085d4218d3de4b56017824372189093b85d9baa1cbb17af7de22608c824382d17aacc83e493aa729c1a4c7548b0cf573a0c6f891131584b6258ac55058f5f058f6908ab0e39364393ddfb58a6eeefc7c1cf9f3dfbf3d3dfefffe18f1b1ec45e10d049e6acf54140ce4205a3136f40d8fa7724323972de12908e93d8e41a0577489947868571a9f7b3ca6736aae41505c147d33a67f159aab950b578f53516370367474f9dad1ae972e105826ec315cdebec9c84c698370180e0db80d40440f2518a67c0fdbd41b766367627cd6a948b176806bfa0bc095925be79f707b1c896b8bb90454b94aa9a930f19e8836cdc29e8c5a09ad56c3bd7335c36a2d2f67c9f26f2ab3ae101b4780f017102afde21cef3a59f237da1884a4df880e36b71628d146208fc616707e42ac7242aeccc9f51f39a7917019e747824f3e70d1f619cf00f1b3d6f57a4d1850149e381bc726b9b1ec5784c1c0a39689a2db2d3170b59cf257f21a1888c0c901a8e30597995ad1b87ada5a14c10d3b669cfd6d1f68e99fad5860140f0b093f05680810e4562b720442b5df3b81498e461d36a0c4596a3256ac8d64344191b72c7b1959bc7cf6e3856358149a42f6c55e2836919bceb2ccf311bf07bf51d65bfef2074e3b17891e70dca3b89f628efc343b94df1d18ece34e0b623b2e91472afcccbf569caa60f5b379492d8750e1f22db73a979827c96273d50fe37a176de02008041625ffc62ef14577218b660b97dc306b620aaefd2fb86b5afc290813c2ff408d31fdb3721ce3ce008c2bb045ef96f6a42befffa538006612145599f4bfda32ebf854a41ed5a97232c7c91674b4d6afabbd5035aa95217cbc6455ff54e3df5ca451a5b3590f880c5085ba85c4e44af92592d1b0a0dcea3fef7b24b596773694b4058d1c8a90e009b9d9ed76a55e52f55692862af9e9f67fdbd21fc37fad3c036d7852ee56b556194e789e89dab320f0adf2db32964983ae05fbfcfea79517d4d891bfe1043b3bdfe6e369b05d05e94c5dccca2943337b97395af5bbd988f5d904c590ad04c292debaed96069ab23fc8cf379af967e321e5a6a0c589a1ac5dae5e4b290ae5b5fa6592db5fb7ac0bfbe03138567f693aa2b59ff98e5c5aaf1cd17ab52177f93ebafdd3647a3a3289c30f026c40c55e7b24e61c5a01754a134677b6e6c9870a7990414e7453d07ddca44f409e30de1698622cf74e6dc58502a0549d427ec6c558a654fd258eaaf893638fe94c120711a7c4c7bbdc3b0a0ccce6509ef814c6723fc95aaf252adc01087ea3fa73f483464c35004420e3e2c5bef2bb1174935e0e587be3bbc81f72962af4af06132fd46306849acfb0f54095ac78e50d7dfdd0d05eb7481618bf295d8737e36985dfb4bb6669d9de0029ef866e1846f4f03094ff4a0c50df58f4d9fa06fa665dd893e0fc3c6af55be7e08b4243058d54ed42eb13485da1d980d2d2cfe9aff35d2702bbe9dfd780c6b8cc8e1c3f005189bc22dacbf73247a13d14b89ddc8a0b4cbf5818f24e106c13a68d5e4bdb51c213a1aae63acbd6da14e783c6ec3b5277297de803887b4e54475e6e47273a95fe17a7f2f75d6efda874144633288d1423e67e20860428360275bc7043898425e89a310c2e883f97ad89a7ab07e017d37f547eccb30a819f308583bfcca96bc6b71dfcb6b1d2f70425a45e217cbed05f77bd791ef3c56f73df200eda1273e4d3f5e0303d079e6679b8b61406910fc0512244cb24ca0ac13f61f2f902d140b082353665369b359c33c4486da2ce21e1d2cabb1b191f54573a1ae2a2bf0890c66df23ac111bc888009e068a26070df56384bf2767b7615fe712d29ed9bc2b3673040df9342d8cbf7553b2c338659655381a8689b6b3d09bdc7e6d3b0f27f411a14bda5094b26232ed6b5001f9dfebe8f794788cbd84e608608923110d07154a097d928bd26a1b70451284e729cda52d4bf350fe87a1b6fd418bb261d45f598e681d5da85f4ebe20292744f2651fd7f6e39a7ddcd98119b6cc0922858d1b04044a1ee3b2f0a4b26bfb91da77c861ff2a7588d80e93e9c964311ad82ffb8ddee1682a16e2cd56584e703662f92842733b40191a14dac6662876e9196e5f24cee62585b9777e6b41aad6f41949ac103b27349fc4391986230ba43306d58352871d16f1c3d2352b5d14d5ab8254e24794e667f4f6cdbbe3f7c7fff8e6c3f10faf8f7f387efff3617cd086760b6971ffa71ca229640ac3733497fa25fc7cab8a4af7632e200fe409392dc2d7525f49594193a61facdb90a00f5aac5c2ebee40b19f15ce112e701e31dae228c7b1b6dabe9346c1a2da45e8aa3688b36d01583407ac968ca1a3facdb2e4a6da211108b8048303f2592e0682596abe6422850524e33eda34e9311f541957bf11884d7a9ac3d4d2d2aa559302703e94dfd12558de7687fa8deae1a7b6de0b3907d68bb0d83e185ad14caec0c407104ff587526d573ab140731370322357b301cbb8a115b0da0410b17d53b6d65e33055e35c1cce52c95a1ba17d4a239a65596871be1695bcc2243d09231634b8412b16fc5bab56cb5194ef0c1b1b428a4d8a99ad69837e814937d9f4802530464b40c8ce323f74fb89837441dd1f106ed36f74cdf6d35a5434ba0e4296983796f9c6a24b60cf0343331a5d3b0d72eff4b4ea0dc4575c5d6cb353e87a8403c54a168b7905bb0bdc8f0bb46f444bc0f007a25d89cc517ab8f30c0758f2bdb0896677593c29fbad0f69078722aba743719ed5030697df21e84ca26abe51a021e315e205a6685c9e93b6b70c0b72778d4a2a478d471ff0cba1adb06e55a02f3737fe1348840fc5784ce1a4459de5596daa2c5599d52f28177b8db7308616c8e535870a1f5caffc59c76bf1efaeb2cf01c7ab269f8ec17371e41b1e06e3b25366c9e53ecca91594f57db46b38211d0dfee1cafa51506f42c86b7a61518fcfe90f336a2879ad6ae8b40fc31a06cb321013d173424f02b4b680d60f0444b212b60ccf45af2776d897fb0385359af0a522a0fecbfd81526261ac869f78dd49d0d2670971f801e77474ed7383442570c7ddc6d4d85f70731f8f526a3cf5ce26c13da13c15a04f6f96ba834d74ee5ce1219e4bfd75d6c8ef0dfc3e03c2ce306a3eacaa0fd0b06d5092c4bff1585836c1c56df5d272d6dbc87e6d09d979a57558e99ac4f3011cf866a1242aac5d053bc2577576850f55ca728d1603f25afb4f44df751902abb5d5eb98eaaf7c9a6c5e2928e21d7fad726274226d086f1d1451671fecc7d7d9a228d7939642ac9f82809587d1765a65a9af31887b216dcb569d40dd4d7d4085a08bc426b9cf91b6089527db0d0442366f1847f16f378c40431503a302be7120aaa67d8f5462c1c6076576caeeeb569b17d5bec7eec5aabfedbab9dffef966776f4c5077db9df9c0b58a2d681c45426566ab2adbc5b48eb3d58217f3cd47a99e7da5463a440e252ab433f29fb74280b8fa3d30a0a52fddb2a3fbe1006b7737128495b7c682401bdb86c7f1205203b72b8798d0520fb71bb8428e052f20d0bb75ea0d74bb1c82fb9cd4f70635594997963f204d61213551667286d9b07add52ce2555e1da640ea9ad6deed032b33641514af51c52d1584311a8a0db557fb289675becd15f8929824030243f63cc50c4d8d0d304b26152ad2172528cbb99a2d882a482c4d64ff5f5a1cffde3b25f12e7466c8878220ee05142fd08fa6e9bd9a04d2c43152a5fd50cfc82e0616aa5e2e7c40c9886e66fd79bf9c19e228bf3a292b9611dbe43edf411541fd5325f4d659f85725b99879f293be651f05cc43833901d573e42ad875579b3021865e23ba838422728b187ef96c42877dc749c76d6c3c412a7c461402b6609f05d5149abd1c716f0990fc1d4c543dbae8cdfe3dac1ad1402b65f0ff9b6b4aaf28fd1185a75c3cf8736931020d7ce513ccb27e1e010d3400f6fea341bdb3e17fde8cbaed81f88277c7e4408c10c22842da8e88e2e182c7e5986007b8d38c7cf58278499c09427c13a0320539a9a74a2f573d14f7c0d26cf983a3754d7437aea314e3d0f36d45d100e1cf208c919c7a09e887e8816030e2131e9f658faf1a760bac1ad178f309a72e5d95be1b27f3b5266c99e558051363e03c35a143af263a886a33996107e9fe98bd122bbeec387a121bda385cc9a550d31ddb111c5badb09fa0c33a89976330567db4b6167c098404cd588d5c475f810f3b8f167e29e0e4fdbe9bd18a60f8329b3442080426ed1ee1a62f84ca1a1448fa8e8eb9de363a49524cd11611d6c1e3cde478b6c2d306ab14497054cdc8ebb92afbcd1abb9cfc5b9ba362022fcc07e0326c1e069404077c4c1c065028ae6632a3253d8d62596a8ce2eb1c42c37b48159dfaf092c68aa094f0cf523c86d20a59a56622fb14a8c2fa0e3b835fac47c34a14a8b876f7dbf1389b06a27a2bcc873b1f46c0e9dd52371e0e88d95e424054257c8f2e1f9b78b6c28db8498ac2d856299e1f8171494c50bc8d157c732883147984b2deb4551e1bb11f25438aed0d4e7494641dcc6d842f8e0d93010b2c75c63580c42e93663698b5c6594588923d143b560cf8bc65325a4c0204e547c0923a7fcecee7cf8965a2d11203303b46dbfb24e8874b9ec06b012c0f022ef1d32c51258b3cd86a29ec1b562d71a9c69dc7a8b52cef450d498f1df2ebe6dae4c7bb51940310318e3088480d4568ddb7f83214aa8958628de2e26092c66089f23d39a012c823785982bd93878f4de300311aaa6e9c87c2e9dd66151e4ff74fe926697475079c763c4a8c68d1a8b8343d6eae7b09556cba0112ebc6b45386037e6c86388dbb472c66fe3ebb605ccb5f8f208c66bb585d663eeee865fb5db853ac9ed3aef03b62105198b83c1030662178da0ecb6608640096755d7f81ce01dc1e0d8f7897bcb875f2c3dff4ab0a1787645abae89b8de76796fbbadde7653bd7d491727f6b10eba58c75dac69af7f16cf912288497498195695332210d79e04781a0596f0874c1072cc4f9f32941d83d5e3c9b994a8b0c0b3c24f112ed6f353a74f57a98e79d79c3c0674696d1bae43d5b7a778f5c639c1e0ee3129220770b4cdf1375342db1d3e9d549fbf6a3a2c1731faf9baab85543b87edfbd6aa4894d78d88e7c1af8948aa4c94d795d8066bdb00ffd8f2a62e158562f3b7344f9307a68c10e7cfdfdd36eab73394ea5f1619945c2e063ef7212456ac727ea124545b56a685c63b970bbcea87be5568216c7861d7c629afdc5d2d8ec4e562e455c36bfcb066b20a7f70a1c8fd3c0c2a782ed0d6616c13897abc4090aab12f6df6c14d8876b6cd46f81aebb00631742faa9cc6cd495d7270350ce24595fb7904e36d3723ea72cdee2c3c77fe408add23460963aee57ac36d074d3bee13681b52f48054f3c3e92cc22d2d8e86e32ca810e897816308b714e52736beaa0d01f6cc15d85c06eb1f4f9cb725a2cd9adb35b302820dc0789b3e6fe456ab63c4f172c7db019742b012e94975ee678409b4a169081bd0221c07c08811751356b5f071a7ab7dd2d6c2dbb0590bb6db565e4808ce54cc2b99ff1368111c49ea91c065ad7547a0cf81f2881df38f43722c9af046380bbb90ed56bbf08589aa1182afc61e701db41d031253961320c1e6418c62eb1225566d4a0cb55f58510408b6fad6eb2c5c81c020efe46c185972b9462eed26c56957b56efeebf7d63ec19a5bf030c25d51827119d083c13efd42c308eedc60290b7e2cb346bf003f0e1f3fc5d9358f9dc6425b9df1369e4773a9df47fe721bfda81953b090213f60ef1c72efc38024cdc87d38e4d6efcc910f6e01aa3362dfc9307121873eb0148fc4a45b8df536cdbc0b58d0d67fee04e040a0f88ac5b0b11f027c22714f88526c7eeec9b07d6bfdc0767e72033f13ebef646ac4b8b40dde7ccdbcdf3a43c0759dc7d08727de7f902ce236988a7c23060f1a6a38c80d1ea15d38cfd19a217e88ddda6b6f00b64391948c2f1c446a6c9185b4056b5d764e990f910dbb6a7ddfcc1a47df0007cc37fbc9fb618576c9b188334d13ed5681a91b2c039c98f616b0d4d6e97e08633de0f24e90774024a969d7c0bd47d8dde3a67edc96a2f9b313135b56a175aa5c8387a0eb0bef64f69b1d2caff3dcf25cd9eb04c5b470f9727f357f1bd3efd22a90b69ca4f559dbfeded9ea0c46370c0dae7dc560c15d97c5acdd7cb65543be32ad6be68ebe7fbb7b063b7ac085317b684336bf6dae1a0cf0120642a9e6327f200f62a52a3f5068231fa719e3dd03c3752e41962b0add885906319ef445568955639e97c8c401761798fb474e65d364f59aaba44c9f8be2df286f28acc397f35ba9b3ca3fe7312d2364c655b2111fc82397d8bf622624386e1c1d897d4cbcec64cde45d62a519b85898c243db5cc4051a769c2b0af403d0cde8113c796b42ce595d2c7c9e488c247a5ecbec332636c8aa62916996351079dda2d14535ff9e5855b3de5e41116a305c59ccd29abd0ace86e5614d0bfc11a0bda112546afe0cc46594cadaacd8d585348f02686f2d3ccc2aee41982bc2004a71291b48ae62a783a66318cb66ae54ce26cf86e944f547b1546d122e4c680bec455b61252fccf2772f10aa507214f4d6ea88fb2e45e0db90b5b74ae25049351636e78a32af2a0beb78c559b29fb73e7c4ff70c405af3cfee6940f9cfac0fd78b779875a28160f379f8260045266ae248ec1f86b114bd2f7f405e59a1f3458f2ab4a7cabc3b4fe0c1633f9c79ee02c73904940ebd22a38171a630ecb8eda6184cbed349d10d99b12f6d771a8475529c0d92211a7d426c8814b8b489a032312b4acdd22a60fea702fc64172a2f66eb96f34f6381da08932384d139e628f40955f7f667593a102c03ddcf88f538f4f56eef39d146d540397ed54ccdd7772a0a12b169aea65736d3a138df30590b1deadd63c6af9cf2738a183f43730bd97872f0f0a70b8f9c41f817ca0546bebc831f37c7264c3078da8a19b101b4ab730ff096a3f7abf435e6c6ba90c2c0f3f6529ede5881c4027c80e0b99d7a6a1e86adfc8bd735f52feb6dda072db76be31e03aea17b456cd1da31c5d814b9bdae76ec6045ca1648555ee584746117cc50b6e5226eebac1375d6519d4803a29ca53417b2faeae1bdc07ea5ea055744f4259c393034e01f194dd314a0e37674f0c3f63f797ec61b2a04862951b40b4656e8f28f6d94e1f58706ca6e6e9ce14959b0401b06d6b71c8fc5eba2ca4af1ceaacab83eeb34b030b74c4e426706e309ba08b467fe9c8632fece6b9feb482a865c1b15590ebd362ab338a246737388ead134aeb10e6a58a34536ef4013b460cc5754edc2853ab41c322e2ff2c6c82ad752db1c0a3e90438151fa7907c8996d3878acdacf5d670f2bb297807b2d38a6cdc61e7efc98ce23c42e643706fbea297680abb17bff220ce19ed7d9d54b33ccb6ccef2d7a293323acc0361f033b73c37c1b4669e18a59ec24af64f5fc20549a4bfd927f4f743f14970b16835a5f8320ecbdea070047d7fbc3b08bd1daa55ce96e74d06a747077a3a7ad464fa300b9c19c362e2ecc2e08f9b13f146658a697f5fe50ac0f8662fd345ec72e6df6d68aea48557db9088f76a0a5be5c84271a14d4e109e0c7198b7f8e8b796c127b925bcadcc0b7a3499cdcbb14a1a77a7d601e1bfa67b123fa913695b1999b94a5a7fa7a1f60fc937151d706ecf5bed815f18a43e953283de4f143d606c8fac06adea316eba7589a82d70ed36607648db013034b77b36960e9a9d881a5e0dda6ef932d16f4c08d3fb24ae8bb5e8268486688d75d43c449750c714b7d763026ab870dc6d6d1f7af1d593c027b86fff9db74c2f7a4d3c6c161c152ffccb7de8c67dd85e38818fb1be663418a1d7111c616f6b0379d867df6653c164575296b2d72f2060747345f01c4008ba5598aa76984e78ba917cb16160757e32fd7fb1322be1322c01322c21322c41322c613b17e7adbba4863f5f0521bda0e2e150181b7af9fcbc58847df04898af51f6bb951255ca3862270a3154540235ba21eb01162019779fce5fee5021ce7e11a183ac3044e33971a58b8d85ae27231620ec1bc81b93eb5bcd6f612717dfbaffd44eba0edd759232106cd91e82d8a3c2f250fb6193b8ad9050d7cbf4e234764568fbe44639e156509a6fa11c4306ce23dfd5ddc44992340f08d3901b4e4584e6405e2ab586a65c70cee3a00efa4381bb2e5beee9bbd1b0cc5528fd66227f2af636659b4cd6be759c61c43820513e331ba297d8bd7ab79c734dc63c953a042ec887d20402d84e4ddd9850e9cd676dbbd1ecfc47759a3217ebc5840e5a14d4fea47a02352c8cf3b3fb191e6b0ebc0464e86978bb687a1af18a019fb105563ac958fb810d5f1305801b0ece03b0cb1eda14ae0d5c3b93bb349b18b98e5104b551b0e2e82f7bc75c2ed65ce4333ff2a5a02eac2a22ccde0decc4046d4e5a51661b7296b63b6d80926ea113dd8b700cf2dda45de4feded0a05eb56573d845024e83dcd851f4341aabe62283e0d213fd9507c0a8357bacd7eadea9759395d9536637c8a40badae10388d3d5187beea09d5bd0aed011ce626844b9122e70d5867ba263da03fe2247695e60b3d6419453a16c23d1ebe582090c8711c2f96ea323129d86c78f3bf7eb51cab08f9d6cf63669f9d98d85e1ddf6cd996a3be05968fcbc51481cb634a2525758c6f51d9473ef9c796c7766ca635632e64f1e92d16137ae7624b2e3354339a0ad1bd4ebb85a5d1f0ed65d1e845d5be8b5eea1a54ca811fa842bf40957887bd01f8a4fe24b3ca66267e7537043d985ff0e6236ec96c56789027f0c9027739987f75d88408918f5b5c6e5f96770e2affb4890c30094242f2c4b9189ab8b424b81099028258d69b2aa29858da88aa9c40cbca87747d95ed1882fc53e0799384ec9881487a9463fcaa9eefb619babe1b5aabfd375dfcd6b185055a2c6e1c7a84a7bce5f47acbe17c658afe6fdd6f01a5dabcfd2ce8aab5258b08b8e56ff4dd33aae2a598be65fabac969bb624187c1854e4febb6231ec6db96af874f607e178c5ae38f077e77ebb30513d399aee131ea520080f349ac99c7c4ae7bebbc3ef37411b78fbb6ef2fa8eebc8d74f23208e8ef8b963d75fad2711aa3ae41c102ef1e05cc86800102175b668dc66e183fcb99d696395817dbeab44f970bd244a55e9aed181ca97819ff1b5f972c9e509b81735373011f1ef0024df6b0dd13b41555c40d280a29d24179a380545b3f2fe3ddf1d388d8b4a49bf9af796122c03b9e98d1b274bc31a35a3b7e4142267cc3038ec54f4a9d87500b67e79462289354b67dad00ef19df26f1dde42afd1409b61f2e6d8784a9ba15fc7b9996aa77e9c702e17a5a3ba6b933595a75e0e67c2ee745f536d3177dae323154ecbd02ff2e8432146beef8b5412689a9eeac4e0a3632a145bd0d579dfab212dc569fa6debf56595e67ba98be5cd597418ba1580f05ffe586dd3566cbd43f7e2c36ca977ff56470302e104038aa3b67e59ab2e9f1e571e55df38cfdda7edd8cbafb4dcf249ac1c6b5d8728762a5c483a793c292ce59e0f227b1725aaa46faf313d026f6c94c2f242951fa2b4fa6faed6c8a4429bbccc71fa0cee5837226044747c1908274c941368fcda696963768d9575e2e3a8d2a97b12528b019f6f71a7eaf63718ee1c6bfd9df1f7f93cf259a1b574a0b78df5dca7a2d9a455696f48a2ac07a5b89a6ca962e708cb5aeb626141048293b6ff8aa7c29f6e5eed381782ef6040c830af828ded72b7db11e43f69335055f3717b35c2cf53a345501f29d35649ef252551a4d50acf0d4daf6dedc8840fa117d6f7d89a3bcd1e71667e8363e749db069de1f3f6e8f2ec6d2ec52f6431e0bc34dbe28971719d81d850be45fe0feaa6f9d5f5fd47df72720bec7d851c8ab67551e84110d58cc75e8341d32feb52e47ea52d6759143c82c1757b80f83309bc3bf4623814134ad29a14d1ce7ecc3663e4e315f0795af37b409a7e75a91555a47bb709eb56cb4aaef3b4db3cdd4324da07cae996f31967c56615e93d3541a6c97f0e0f81b53e796b2b560c203fc5b2b8a4a7f1a676b3957aa9459750b091ae3d032647073eab3b62014e887676ed9c6eb82d2ee77387f9269cf914f7b0465a676e0bd1a7d803cfb9c7cbc2eaa5c50e137363b0ec424c73935fed4ca915e2fd17fa2b750ab46aa55701f7a27036e50dd321de3b59ca1d9682e6d3292e68586f57aadeaef552efb72e852a42f54ee7f79324056bf50a59697b28e72effb2e6d717f907a1af8a7fe422ece650daa225a1c2b4b76ebce12ed419a8d6ffeb5cacaa6effb1a466b1f88aadf54e5da263ed0593d979a300fc218716cf2eb1f7bec74ec76e4e7112e8fa5b537376e515b56610837cc7674140a22af2742b23b92ee49395afb2fb781f86a2147e854d337e7863fe61672b42c2e95deb02536be29ce1ff5e62ecd9a7565ff4b952d64b3cca6b23b2914f9b05f8699d93eec87ce0587a73cbfbddd8d23ef8e7e48d98475bb8710d2877d072b0aa1fce7cdf98db749576c7321b98cf0b063cd449ce0aae11935af299bfec09f5afb615a16d3cfee9756abe945a3b35a879f0086f9805eae17e6b672396555f52dfebe3323723aefb173087ab5c25cfb13f1fbbd3d47ddb5aa5e9a4132f88baca87456542f9aa59cea1f4d2306b196cd52554d7129931f5fb4bbdb6be1d28f72baaa4ded724dc271c8ec0ed16c28373fa66368442d29bd4d51cda1d647ccfafd91ce17c03b87f08baa5e2ad367358f73c81795f878fde2dab4327cc4c735fd0de97b0ab4f3d6171281d9ab2813b9944b3155cbb5354cae65b32acd33e462d500535af5b4c8c06fa4a8962bdd8ce2280e303b9b8d7f56ccfbe327f10c47a39178320ec33924b3cf9f8d9ab2984ab424f58e96438b2950950b1e3fcbf590a89fe18f57f59451f7d038ecb3c437420f960972fab84fb05abd56beaf06353508f7e4b35c9f8542ca53efed84f9ed1b9bc4c61543e2411c200088d431ac2474218ae5d4919cac497a0f51aef570c85c57065dc20ddca22698597e84f388d7eab9e84d332de7aa5e439430f30ccdea5eac5f406b8baf8e049b56dbe1ab3573f406f9e53694e5dfb661f3853c29ce9099b8b9116cec9090c9ff7a74140cc6368a13d7c2855ac9abf1aa32c5399d2ec3c31828746d4c442975af11e00b0ca7a59257ee08b6e099e346671fb783a06a65ae05c3a4966b8885765517e4f4eaa875082c3e2be18c86e204483d407f27eb4b7382e652c399b441f421b5d58030f42c5ae944465e9801d2215c838c6cd49b6c21ef37ba20717f703d077fb647e1017fc083bff9b8a745b5837666b3ad2973867ebdb552dab1d3e7c474815a443cb15b6631866ad9943c8e940351861f1f993730d2644b8f01de6f4793ffe7926310c25c66104a9511c09b1bf18b0f740104182b316a1631a58e50e13af762cd39ee0acddf0cd75c9d4523a66ab12ce5f50822d7aa552dd455e5a3808243066e61a63dbc9058b7ee3d33a3210c99a1a2b7040e87da1ae9aac15cb890bacc9cb64c3ca6846698c34c3445350564ada5998232fcbfaa88aa748db275386190db100c339191a51a975979d69ad57feca8ba8d28aa42d3eae21ed2aad1861ed99d759883212d5e29f1c39bf7e0f4c94e823b94e0e28587c10518308f67ca1f886d28f5a18d9201f6854a5ca95599d37d206a3993b5ac20e9b2a224f850d1e66e1f8a650d2c35249232bde20b06e93b739fc7698c12bffc9908b2c2c759e2fdab1cebd160a816fde22f77ea830b093cc9a0876a229fd730517442b00cae9cb90a01789885e5165cae0953a5b5e5b84276d3590c46b35c95bc7ae3468caffe30a244a40cc72a481b98f32bde484e17672653666b6528291a727eadaeb16d707bb91904c3f8350b87d2eef6f2f90e6c97c164dde45bbbe81b1efa56b26a563592aae6dbec521ebf6ae8a98ce510b8ed4dfd775879acd667c1bddf7b0130d68f238c06fdda523e00dbc0075aebb7cf7a25aff58bcbac28b3f31247719cf7b36bd9bc59d2499a15d743ccbcc750a2c0d73c09a68f736ec8a9ce3fc5a178d4f9a751910321a696966ee4ca05323440b03f9b82706707eb8aab8ba2943ccdebaca8724c1de8c70a03191846782f427ae8339cb77dec1f37dfaabaf8b7aa7456f6976126661b02cfc952ace612935df2af3e806fd88db9f1b25a1e7c272f65d92ff787a23c08a1a75dd76dfcc19372ff0c7a38377f59fafddc141c9c895df3f9c07d9e50fd5dacedd6d9c5e57b49a1d25d9f05d8b406441ec4c3535535ba5e4d7558e3908d9be49eb88f8c0060843f94e4b834ba43317ef244fca59455ded0289e8c29c8ab130187c2de31d14b1cc764e39813e258460fc551e2463be4aaa9a9aa345a232fcbccbcfa16a36cfaaf5551cb9758925806eb920769c28f1c88c78fed9f232c4b69e0a995a90b7fb5d5f056a1dfaae9b4fa566a5c8439af5745ee04720b39422d1f8d887d76c3e6635cc85174c5fb023ba0c0eb567a97db60060b39cabc8cc7958ae7c206cba40f281cf2ad18a50d68acaff1e17c3533f77ffea3ac72303872727427575dcb3a0a2c47480668f6d646ac80180ed9f4f35556e7785075715e94855e0f09470d578198fcd2a79dbdc82ea53897f6956913748927c0e59c7e61d3159f7e211a5d94a5734c3f8797665199872e309585160b58867309f1af6c7ee565b99a172ec8109e0cb5c491fcce05d2c7925c2e6b39cdb4037a29ebc6509e83d11f467bbe9e56b9b2fe129976b59ef23edce973e70f7182a8c6420678e2d3f02e3033104baac0cb7f67864522b5532b46370f009f21d92e998d1d8597b77082616c863b61eb362780fc676e6016f42b5863919545d6f8fc2880d6862d9b888f384464fb8ea24bdd7cfd88b0de00af3ac23d7b8baf470c46d633b57a43cf8acf0347eae091e1fcaf790f9e1377a2f826000172a258b41ff2ab50a5c5d287d6038f2c59bab9118ff0ac8719d1dfbb4738649d2e501b9eb9e380cf3803e220b74973872490b171fcd0787f565486c7607e38288c715b4c4c081ad19faf341961365203a37e9e35c5942a8f799a6716c58b3f0c0dc265f88236bb3c2be6ab5a0ab5d26822cd7ac6395d6665918bbe1ccded86230d7c747404442808d570a1f5b2998cc7f3425facce4753b51843a34fcd18b1f053332e9a66259bf1c19ff6fe685b9aeb4a957224eb5ad5fdd32f5e674589679fd27c03908919784f0bba62dcd501675f071b72fa851f56dab2c21c8290bf3b0db43651d0c24d97ede680bce91bd63b6f98d644b9cc7a17b30263cd330edcd23528a69384d8735c159ac93599ee59eaa2ca30adf602357356fd954bf3827e5b5ccb12ae9901bf15cf8b2a07656413d9d330005eb7109e091b85a59610d69ef01b9129afb3ab46f417ab06a8765394a4750665427de903e6fb78690327575cc811020d9469f15e1aceff7db1ec077a47b4427ee022c3498bd6381d17625aca2c1971d26f09312250130c42ec3c42c6d0c36cb45aa6408ec7e29d564b8cad375dd5b5594ab76ca2546a29d4d41438a202336461f8a6e626289d6a68abe1e00eb001e126de4fb39f8aea4c2c9563af5861c80d39a56e42216658bd907d1a18e26dd9a48a1356ecb1464608392bc3b1106f7565780fe02c1a8d44a8a8b49c1bdea85162917d96c23c5019510de1926fa168c002d6855b84388904c90609d44a6497aac8c57989bb25e46c66ee4e36e27752a3fdbdb9c06596fb441d233a66562444e9249c924d2bf1746fef7affd99e35dba08b08458a65992d1beb8d43e28a9fe224777b43fc7b562a55b377e45ceaefb3eb62b15a40933edd9103cee357f2ea5bcbe67600e4fbfbdc0f601c6cfc44a4fa45d061c79c5a11e37d74e4c1228a58d61b4bbe0d934e755d17fc1581b86affb4d00f838a3edb2ae3f55d77615d4094163cb1237acbeb5eaa6a1b20ab7cc74570f72d00fc4f74b631f4295046a03a442c45768e8c8324a27fcaa4e195bcb2368b64ab68a73614d648d14dc00bd23b8931f6d01b8a13827c16996bd1f8d42c1a0c370751d58f3288d0738a51818242e88f3a49fad62ce4c8106766c1e119070637771af7f6d5d952cbbb6e92065f09a15817b3e1e92d8824da1417058c5e24680747fa33aed770d53b6a27100e249941172350cb3281e6f58bebc216862232877fbccaa8c8c3282461199c8384302e3986def56e765d34bb3ddbef8687c0c639ada339adef9ed37ac39cd60f99138da1b7de7e4e66207c43d920f8671c42fce5e6c6aa8336db24423cc3466462912dcd7144b5d6f12b882f8c8a475467cc542d662b6d6ed352a9cfabe588b1d50939ef3d53496c623b08d9a1b403f18b3854aaf988a7dcac0e3d733fcb7543fb326825b056e79f8622d86a75fee9045fdf5cfec205be766d874c09111231ea8da1178d14feb579533d72450df12ca07e65305a64cb7ef264a6c381fe42b026223cc5b95e2fe584195e0c45be74e1bcac9cf7965b8c0c86dd435c770e717d8f21ae93432473907080e0eb100ecffedd7a6fb4f622de0a321169dd3093907ab2f9dbb1d5595e64e0036946e8cb8b86349d812919b4649370c9167bc9db2445d58a28d26ad1ce0e115d00a64674a0ac6ea34d330e5b80de6f32e8715a19907d434fb032712cb2a4162280e055128f8e8ed25a0b04ef2a06c894846527efdaa47803221074c8cd66b5d7401c71f92d5922813e9d4891350b6a0c186f85ec16b03d56bbf4d0e2302a64f2613eb15635947aa3f8bb5d188b33539a7537c59765d634368d515275ffd2ea2854ddf71363dd2223ea80250f7b648116ad4825afd868fa41fb229f88220f2c7af10cbab10465ee04f3050c6a4cf5f584d62efc8eb22b6e8714d88ed1b6e12223d638de2a462eac04f2f3f7c5f4b3a56dfdd847e2cdab37fd775f0f26e2d85c8bd5677125457301d600e752188e02731880581b8c09d0281ac3df47c48d01c6a0ba5553989773a145666ef95ace57a543eda5c11232053afd022777fac5e917c80c54e5fa11662200db04061a1ed6986c715e4c85cc9a825281d868456a01cfe95236cd73375e95cb51708ccc0175d4329604074725cd269188b49470d99bd7fc34ab736b6497f662a733cfc8e845d6fcdd7e0cee7f406a5f1a0c3097a5d432758edb8c9c675becc167dabbf8c865798e0cd47bf51d580e30818f65df0276cbab6deec57355f28ab58c5927660db290a3c02084735d1894c5cd2611adc5b64a446c297676a2db8b2ab366dcc41467629342cca57e8595be973aeb1783a01e99a2121867cee9150ce64b745119d8ced2d3ff0043cf988e9b45918daed5ba6310a6cadd43bdf56f52db1d767618148073249b0efebeb97141afa81e3c29cccd979a995737443309cae8698c7607adf9f08a65517de6261d1b6e198f68feaa71a877e2e67e165d28ad6647476255917e313677bea8d5155c22df8062a277fa454fecb06ddc11bdd32f98f2076e485332ea0da29ba96bca744b45c3020944b052e1d1420633de8216b98864d6218c0e050786fd60d2c206d2d397a53b3fa79d9a90dab4fdc6b9696c4738e20cfe11696044953e0ded488ea35776fb58041539a2c148bd6fdd502c6452e343ebd130bd988d8852e85e231a9d69a7eae0797f9db01da0f8d5e9ccd918ac9d1b19147518246dca757487954707adb5aa4f32523498ac6656090cf1bbf0e1de0b0583d618a009ad016c0d671b91148d6129cf3097fd7b3df179ab4ef65b69e51c5e07d6778bd0e1cc8a282debcbcc1fd17800ec11d036d26a668b0ab49d36a9d3349b5ef8b446f7d06d3edbdfdfff1dfc3d550b338bdda7cf9efdf9e9eff7fff04776455b21e707df6d30097081dbacffc3dbba3700320602853b25d998ea08f83c38e4952eead0c8943975c2997206743e7b529c3ce97ba715b1d72d23c6608c6fe52686a133042f2e07f4dfc0492ce4a88b4309157e7e288c6605dde1c6a34f035efe30b1a95ab92c0a09a623a64b77321fa94b9a93a0603aad83cf959bb876c4b905937d995568595d3baadd5adc99a6fcf5c42f7a3b1cda138f6d4cc9ebf589a835697d1fd923cca61c91f270138701794ab10d9df43925c770eb422b1ca181cfd3060b6373e710e663fe35d2d4c95c5c15fac2df7760088148695e1eb9038a6b89dd8e5ae72326cfb61538d59207b0996266c8128aeca0a72b594b30bd2ed4aa29d76690ccc77ae4e0fc74212bf390f37b4d55863c2d19be5c0aed8697c8ed6b21be52f8f8a3fb8b34a2365a1e57f4c007e802ec55e8ad47f6e1605082398b12e4ada550b744eb30f4e15e1bbe06b21285c69fbd7ff786a2f7a1c8af7b6d2d5f64d616b90afbc27fad64a3375f410ea1d95d645ea1d5dcd5c09fadbb8a4acd8fd655d57606c755ee8736911d92f4bfd3027bee032dbfc5aa32cf609159a306eb23f9112e818fd67eeba3cda46a1a7d24a0174a7d1e1a2cc3447de6400cdd4683f6dbb0b3deb64e55e22325360530a36e069053aaed8d61b6b8e810e4bd2ebac050defa6263a219c35451d81ff89bc5d7891092bf61db8c2a04b66474ed5c5d879cd107dce515fac0d07aeaab02bc4bc094b1020919bee56994704742e985acbd74633c16dfdad42b1851d390a8d9aa2cd7c1ed8a465c454d27d5ca2a9b404c72aeae477e7001150e8bda5eeac17935ef10976dd47e1d0a80813ffa8336971d9ffa99aabf314b1ad92ab7b4685a2e4686108065722ead8c928945ee6db06ac85680ddd6ce82599192a3cdf15b40cfdf416d78a5e2f1f4153718953efb2d8c4a37d3553624f7fcdcdcc29eaa8ea7a0a53efcf1774fca632f6704f5ab295004ee4e4a64ebffa6b4281cc4bd6812f095f0f2ba2f6f193a4fc7cc8f97aa84e4af73e7e339dc8101968dce341ebc8761c16f8b04f7c401ee0911d095aec771b7ac8d2bd9c14aad9e379cb7302d27d0deb10ad066828b471bf50094a3dd1a8a13d3e5d97d302f96b47de076aedb234c3c82c842d07036f71043fc1f2974801db7afa037092b03ff46e2c26fea3ba5fa8cf9cf36f8c78f5bdffcfb8bf562a6e19d40ccaffb6019f2d0f72268606951bd04ff642db98b941b2f8f68b611c56cf787ede7a44dbbd9df6a65fc800c9edad2332fe48b4f5f0a6ae2791bec3c096e43cb5aae62ac568b775a2e9b89dffbb1d8ffc3e80f7f188af158fc614fcc96cd1d4f0d73205ad3f3af10d7b87df2d01dd4b785239488ae8ec05e5bbf3bee1285452334496d4e2258541c46eb00835eb44836731747f10846acb4d5b2d172f94a4e8b05b8d17338e3161cbbba8761dc0d7251a9b3ab7e38b33e033e18f2ae86bca7406c1f2cb1aa9cc9dedb5acd6bd9349314ead9c261b2a945cc093b35a18c831f1566b19de5b937d786c4cff6d75078c2614efca0fbe909eb12e98adf49791fd1e6d33ffec905c7f753e8a78e823f007b43e1b4e0b78316abd29d6a91879083edfc47e0dfb341ae8d2f0bfed840c3fb5082e091bd687e5895e59bfaef552e674167ecd0b0cf2ca23e1749f9fcfc018c586c81c6be5f1e893dd2209249ef97db0405dd865fa8b32b7349b331dc8b5b00f714b42b5733cbe31986ad117dec611cb091a6bfc1d03f12c051c781a2f355ae0d3767ed03e8e9278ef1b905322cb3e5ae153dc06191b0cf3e99b60fe3d7dc00c351921d3279482120f78cf7cfcd43c68bf360de38208ae8f9f8317d3829ce46ff8651c44cb82f8773653dfe5ed4324b492b4d2527ab4c220706dd67abc3069a18e3af1ccf07089b8912c4f478eee0085338d6f18e4830e7fea4dcf7906f7a49b5d487d686f0ae17151dcca2a12dfa47d114e7a5ec17835847bf51a8bfe1fc2735b34c7cbca9e9562bfa612ef53b556b99b3f1f1a72fa6aca799dd494437986bb0f81d14fd1c62fec4061fbfce94a3bd3f8f820910e5bc6bc770685661dedebd4d5a736899124983b1446f287af0a0e37269bacbb0ed43f68ea6d1b18571a0030c2c9cdc78e62bd71ec22bf0c7fb0d043b06d06f26d601601b1ef49c843e903530ef60342b281e22f3f9b517abed9e2ea44dbbee24afeed8d8c6f68eda15fbe6c07c0577d3ee6e2420628bd5b72d21c2598230dd536a741fd28f98f6db08907e4b64bb07ae315403a18eb80fc26d2f1cf2e656c304c339e1bda61eb1db61b0ddba5f2d40626facfbb10da9716cc41dabbcbd1fca1067f39ba00c87b501653847f540f2e483ef7ace60033269db99d504ff0710874dfe418863f99be8f1b9194b929d7660c95f491b6e26597a2757d4ad678d8098bfb09da7417073f1a272262fa896b7216d2db54252659e16ce7316be9079f322d3d30bf0dac5d291785136caebf8f13d32d5198ccb8dc7be72086b7c20708a039e8c9beec290d5f203c415cea00644086f463875526f46977e3bd0f8033a80986c16fe50fc128536beddd0e53f5f5c17cdfdbb3c2157bdded9c3bae521d579ef431106550f4f2428fa8eba8664fe6f195c48eb80b26adbece848f46c47bdd6b9a06a7e365178c1581c42ac349b1c91ce87ef22e1f57d16947124939625e6f1568a146f811dbf234e381cbeb08fac55f20773edb0a50cbe1b4a9814cf53615099c2def04e22d81b5a857a04f41361e1bfedc826e2e42cfa04ec4354d5dfa2ada28b22cf65653f73195deb9d3310645ce85b834bdef1ab16d475c77778c64c1226e0dcf30c9913be53eec1d429c8a3483d0c8f4206f7a55a559d06226088c7b22f773cf5311fc7bdd4a62e15cb5d8f46180245d13bedca7f0f958279c660b73b31807530ac4dd6cb5c4a04bc18a28a28802392b50db442878d4a6765361736d90a9ab93d45a3e566025121ea15048e86ab7ce83a6097a0ed0713ed148d28e695aa653e74b16201a9827b939aa0717461231e496b5361dfae8e7abac9504c40c838d213cfc5235e38118fda7b1e9210aa1a215f25eb4c4bcc487bd75bdaeaf028c3abd53bb5fd65363ee7db7e1cdba0023850227ee649fa79d7f4dbdaeb905e3e7e1c513722884c34dda28801cf8fd3623641e4b29484dacaaa85adefe350b431384c2c5e0aa232584c4e19007353c96ab51459d3a86901663ba6fa6997b0ea21661a9b3c7a42897e1c656c2147ab2a8ec7d4d28bb298420b266774f1186b59caac71f118d13f31885be1d6387049753110d9d7bba504345b66db4908928e41171c28adbece1af987df1f2fb2793292163fa63471adccc2fefdc7efc8068d950dbd363f3cb82c54d4b6a8e8df625ceb4b9fbccef78353720dc34fc7346f2812062b9da1584b9711d9317c40be8250cfc375fea8ccee20cc60d4edd492a6591ed5ee7342cba2d1b2622a16f63b88a6600bb88d4088ed107b1af359d5cea6b0b58dfcf5dab6c874697f6022cc3433f2b6f3f14a739cf477343ce812ddcfed88fd6971933b01d732488b8e5f129688639f5e0aa2a56b2572a9211d79f16feb7962bd7249f05054e6394a268b95023932058ca1b8eade1cfc9e8adb8383fd3d4ee8378773bb63b77848362640679ae5cd0bec83f96c5864ea20b1ca5be33427a0bf0956f3e783fb78a7088488600a5284c2ae98a1aefd368c5d4619915fa84bb92d1edfa69cc720a71124ede5ef4a4260fb66a6645ac1f251e4e9235b289e8b5e2335245ec171f5d8c2ba50985be8866cef775eb35638e39b70175fc8e486df030c4e71dc5690f3a1cb71f0c405daeef915eb9db90e3a954970e8544ed9e4087c2bb96a7a38cdc9ded98621f53ef4c48e8f00de2308c1f8eef033481c1d4e8def95c9af4b84b9adbc11d018b40bf7365900770ff05b214bfa6956968d7368412ba946e40ae82dc44874177c3b40328bdd91762609820b86490a1772c43221f6250b2d6030bd5928a52fdc52793b1f01d45afceef77ffed39f83d798adeaa33880c81333f5a859903b6f3c16ce56484c2fe4f4b3b852f5e70cf37e7bb0d6af0f32a0b9b8876656e2ea42fabc7c05a670419036a424bca5b102b7f0732b1042f7c7eeb92b0917c8d798b875bce9a87b3fad1547a860bbda3b9ad86746f1a39228fae94c5c4974aecbac6b9d97f9eaba98cf253c9b99af56ae44262a552f206aaa413bc60e919f50dc6968ddc5d2249ad7dda3851cb97d6a8d0fb23c17d57c284a995dc21f8a909649b11b6b5b26addb91e1532e8b4c40da4236c2e8b5854e6a121d122be77f07a7099c528a462c5551e911da959b3e01e9d0d0c8a66f52e25c3280b5347cf1ca3045f49237ed6620d3afc563b1023bc985aacdfdba50f5da2c7a252a39954d93d5eb517b499326c18c23827c7fa3569ebe96b9b021108ede274d6cee0cba7e0751495bc6fd26d95ff55db95f3b52bfa298c96c6f83fbbbeb31f7b7cc011b246361956073dae108e1f3618a14b7f2c5c609441f942d16fa43abb387e48ddd2a6d2ccf1abb315d2c5f13ca19cb3fb550137cc02fd5677356814d00d5a82bb3beb3e6f644996195c148105f20a593c63bf4bc96d9e7cdb6f8092b6e1f70137b67c959f1ec5181a1d923ec1b4258e3829c857e64c9155f61b211fe1d537f46d2603f1248ba193088e3b1f87b23851d81cfb37587eb010f280a50312399b99012b3e9661931312f843ed2eb12a89eaa45c9bc89fb12029ecf202302841ca63b9c4007ef3d8fe6ed2487ce9fc8338d6193248e21639664c48a520b301935db4bc30f4693f1914026f418feddc3cbba87968c13be4d2e6396cab82393f18664c909e2122527de2ab3ef0f6fde7fd37ff7f5c05ca6d954afb2b25c8b5c1926cc25ff222533b2bb70fb9daf34e72d3e4bb904876cf1648303e448bcbf50abf9c5d0a0d034ab3c0aad1a395b95d0943b81033ccc2b667b32bca5509558ac0c1d2cada4e2f923caf317c9fe9c60c8a71c0ec2e140755c8fb178f5cddb1fbf79f9e2fdf19b1fdef125dadab7f3a54b94813e9de67e9b42e49f384109966dca0b8235ba9d3783ab974dfd65c7f4ee3317883064c3c1da3d1f251341df39913f3d74228698b2fdfb4f4d6044a793e26a7d2febb9bc7b52a3bdfb4f8bdd4dbeab304bda7fcf4c81f9fd6f99a8ef299115323c96d4a82d03c44c6bbbbbe26b483ef2a9112b0d93271b8706ebf84eafe0ee3ce29e816529a7e8b48256bd56d5e6c87eec9ff1c2106ad670606e0df8e8f3658d1056dbf6c237a32afda8572e1f410e122bc075c178c238651f9f47470c553391b037ac11301bb637345486f21663d0b232b68df01e390cd7dca57a13478965b265cf49fce6dcf64ccda1b0acda503453b56c4b5f30dd244b271737705cede4be1dc06f886aa8887573f1d9c4734a113ec152b7421d260238c8bbc48756ff860342660dc00f110018cd16f423cec56c33e51dfa8fb7d1beb94abbfb5c83116dd50ff25aff141f13e8f2bd7a27b37a7a119f94a100d14aa847c6444e90e3572bac60cdd50058fa6c71df270694ef8afb2a8ed84498f0d62e3fabb98306ca5f8a601e7e435ac11ac953e858cb85dd3edb2a16e946278ab58cedff9100f8f2a455476a4bde524c9edf7c5b6495fff69b925ce3adb629b0232f7677ff676d8abb6cbecff405bb6074b856c092b33daa62bdf1a3a2f921fba1bfccea46be2e55a6fbd500ee90a2795d5485967d72a58e51212b17aad1f844e03d5c0fc57a28e4b2294ad5ea0d929c64e74ddf2cef7a20beb4153774f1d3852a65d4430c1ebc6d94a188b94dab023ffbd751fe9e7edf56dbf540be3c12d730675fbae34bbf32a5c9f12db2eb16fec73346621b47c05f64d74311676503f5196ec765ec6319aee022bbe620622cf112b2cc0583190a4486d10fdffcf5c5fbe37f7cf3e1f887d7c73f1cbfffb9636e45f5d0b915d5af9a5b1180e89e5b51b5e6f6f6cdbbe32de6d614f3caa209fc1d5ff7d7ed9bdd55f628d5bec5793b831a3bd798ca505597b2061a97890a86cad7e51aae73f079c515ba4eaece75e7525c8bafc49e782ef6c5a4fb36d5eac72c2fb22a38acb99cd792254d2080f4593c117d98f7db633116fb7fda4b2fa756afa83e835c63673164fa6c20efff694f8c05c16790a3b8abe8cd0031fc909aa999c8c91d7e5966536923af1623398aeb15f342f3607faea12a2a3db4b70d1af1c18fa2b1b8741a8a8911e8ad3084eb0575e1ea589f0b57ebfd86e16e70956019d8a9cd5b681250bfe029f088937b22d801fab4d48256e5cc5cb54161cd4c4b293f3227a3e2899003311618a499e3b9144f8ec4be0f8fbc7406a2a15de8f230babbfe6a03c8a22300e42b34c7a49866a5582d6b70fd26ef15d82fcaab9489a9ac3485000b7260bd30805ed76af116aaf38715b4788bbb0efdc1dfc1fd9117288a3100fef912b44210a9c1561e99ad678046d787e9c63fa71aafa3c66bd618d35bbc62201c04243bffaa753f35bc27c941ef2447f324f535d4fce14650a799ceaa837ea2cd30d569287846405f8afeeedee89978e20e39431bacb273240e467bbe06904b9e4c4e3a2b591a5dd1d848903568e0d44cf477df1e8f0f86e2a9f9e72c926e5aad4dd0ef048139d5959dd0a4732b384d8de99f6dfdb5d4575256b0bfc1915deafda158ea832437049b0b7f2dd5557fa90f00cf967a7f743d140703b12382c23515ae4d6117d57cb840c6d22697723c14c8401a5c488f662bde2592b93bb45b8bf6f94e8245341f20515abc8cac48fc2f7180b7e9403c177b6222f646cfb6b85ab2b2981b1c0348741fb8348459a58b5d181464962d57757437c01add920e7017887f9889b8eb32c1eecc85c23aeeaa8cd131103cfead82fc859b6fa3c40cb7bb88a0616b3728920e401be27042621a25d2132e31323e6e5e45e55c959995b39f787e7031160787ed83833753dfaea16b3630a42ecee327c6ed21edf836018a3046715916957cb9aa2f8307c8aca81b4d97c9a2c8f3d2dd2c86d1a0bf357fe5beadd51214c33faa73f16e29ab296aff41ec988ba2aad4251aa68016154c021a2d542560088077485df02a6c1ce40bad9793f11801793860f4985559b9d6c5b419e3449a31dca0eff0c7e8422f4aa6c181fc23eedc434edaac6c2056f0524eb538fda2f95c2c97323ffdc20fc2f30f241530ebe49667645a88e77c91c4849573cd34656c3de29559798519f5fd0aa761fbf2e066cbf7f683cbd49154ea16692e4da14d786dad35afc5283075b27f90eec48c1db907db5bdc01d458b31a1eb803dfc01ccc4cc6a26ffed9313df201343000338c560da7e0c6a405b87f102ad566611d42078f45b377e08c9e8a6a862db16f7c9d347bfb96b8367b9685c4aea9c2fe81abb07f10cc61064e3de209b43477bdc15bd0e16653ad6ac07e5d1778d5bfcf58c373db90418cef76bb3513fe7aba9e08bec9b3ccbc3ddc8ef83de779d7d6becd3a6c13628033cff289d74dadeefe77cc44eed97fd0a6abff4dfcc9376fdf1d7ff7e60771649f36f6c3cd8dd897bbfbbf8f9fc79eea7daf2aa55515503fc41d4edd42ca31cdcae9aa8400995fffbfffcfbf0b595b37138b76452532d1148ba2cc6a7195916dd20debf7c63b5d9dafb44b87dd88050ea898167a6defbfa5e57620603df825435ed046544a94ca3c27e4b5aee562b54094cff29c852fb78495bb6ae54533ada59676c439f20398ca42cb7aa94a24b30eca3b29c5c4599ecb6a74557c2e96322fb291aae763f36b6c57f3c374755e4c3f0490025a0a9dfe54e88bf786c7456e92d63d99fd6f193c66da07e3542f542ecb09199a7d805fdc2553963afbdb24f0705c98df0ebf0223693be79776a74553aaa56c441f010d60137ce077a1ed34fa8bbf0de2797e074a89f69c43612db9364135cc114f3f5ee241a15f90d89c9ac4a1ac5c77b1aa83c3490e2516e8f206605a51c26dd40adb5f54ab64c232360b4335497c93ea57ec8afd333109bd90fc4ca1359b99a9de05692701c94d06a13d7e2c1ef99f5d3383abc66cf82bb3dbff74b8c91b016d6bafd235b78bb4593730a9080655d357ca9e398cb6bf5cca8c0c25295bf8b5e53af9188ac6236bb8a123c4497114d47f0412b7e78991afd3235f1b16924398b094506c6b4128c3f7f7e686236dd79a863dfecd62613807df9f377365fbe5badab87b1d3dd1f0ba3b024b7c1080b6eb633ac9a84638f6c11d83d88bfbdc583b3106b1935ab2017b3c246dc95ee49f0ca7eb2814e8a140f8e0ae1a73c12c65ad0b6bd004b292727991fd6d686e0ff38fce567f1b8ae65fabac96f9f7d9bc2af42a97771122d431fd0a62145082ce53bf0dedda0e793611b55051c7d543297c188a3d4a3340dcc85d08c2071722cce661e146c5076af13731de78c4605f5bdd6e6e136fbf7d0d180edfe24bc8f713f61c0c822d6ac1f9f248fc79eb7d30a8288ec4532b5c87b7480c727098c2375c595ab12780d4e2c9c629c7bb82cbb645537e065fa2297bc426726182a1b8ffffad7eef5b9d06e3aef5cd77501e5ee7d1cd6dafc500c6b5a1af4f0fbbce2dd4a15d8547b9b51df867eb3cba4e82cdbe07c89fd320d70e648c8e8bbfb5156a0fe287f207b041f75bb61fe4b5ee5cb29d7b2f9901d7b95c3b5b2f57d242c4bc52c9262269d68691dc44a9d4325064051fbc011158627c75c42dd57c983ff19c7d3fd933e780fd2eacb1cd59521f751fd0c92a9bbb8bd7c53eda7febb5f912f9d8070d7677f3dab441a79778379cb361ea174b9449a34c93dee95531755ad1ac9cabbad0170bf4022f2af002af1728eb44c3c8ecba680484d8a238747315e15a31953fac16a1da191217826c381048cbeba5aaf026805b71562a55337ea554f3fd3d6c1e08f566142b4a1c91c269ec6feffdbda183cbdb9871bda676815e2c1c161907d90ebe14fba3670161e17098ba3660cb59f3a79b1a1fdcd1f88f9b1a3fdbc09cc783dc6b9189547f47627fc4637a774cb5a3ed4177cb83cd2d9f75b77c16b6ec1cda5eccc1d83cb2bcde934d58e2ce89f56ff3e91396aa5ccf0caeef3a59d2d5d5d56899adcaa22e9a0b90eb1fecedef8f6b6ceb9aceea6c217767aade6d1659ad779dc363a4d0a1762faa62f1da3431f7563b04008be3765554b9ba426f2167739a08e4e6495a6cb30c8c93b57e8b0223b4680f76c78709d3c3b1dedcd8c654ed4a9e7f2ef48fdb555ea87f6f59536d0bb1b9abe2e65509e7dc48fdbe5848b5d2cc70787f6f6f4f8cc51ff6e285bbb539c4d00ef0d59befd3668073a97f94253858bda5ac679c62ca4b4d7908424f44b56ae43f87f8efcf8cb8198491977aa4ea625e5459095e77e0557619e8736cfc1c535767f55cda4aa3a69e92d31eab7f6e486351cd7f945343a32992cd5ceaafa9e06559c84a9be27ea817d16a35bd001b1939a2bf0f191253e9e3c7b6a2bd15bf0a920ae07cc1431b6a9dec9d8da6d0a567ac702d52757e76236a392c5ab8b21b9ce450a2b711b821e02e88a952755e54205a2f2a7045844566df5dbbf3b598a9b25457367ae732d35ad69528b322176aa54d8dde2759d7eb4f3d6b5241a1f31aa1660e102743177a513ec34ef54aabbac8ca06358df965564d653e861abb58651746bdcb4637f6bbb6cc72b3abdfc9193ccebcf96980b8e8d4664317f5a8d16e2967ba175cd354f25e2def0f4dab6512d88f6081746f7060b89404f8b5d25a2dee0ff11cda8520af4843cecfcd086da676c38f66b1cc33842df86e3045ae7b9734e70002f61fc3d56ae901bde73f709e5c53f09314797159e4d2601d601abdcb51294f5609e0503e14e7946303e5c280e1456355e5ab2582c8b4c8161012b1a884cca617222f6a627bc5b7ea4a5e5aa31d0a1561a8a9ac7288d9529219d1aa22a80c4747e21dd8b15c49d015cd151c2025729991dbaf5ad5048535830806738579d00dfb8a9dbbe3cf4d16e8e39dfb645e89fd2b6bd34024d19a446c34a7b098e2484cabfb9fefda4ee89c5280fade0941b6e99e5feade2a76626f16fb654d5f7e26da474d99a1e05b344fa11c4c5ed1a895b3ac5d64d7bbb03063f3170d128c5c488fb0c830cd8aaca7e65932b71494dbe33ac0703cbfcfaef13836e6ff10267a282a70a35d6666d26f512abc0eae4de8f318ed65826b0879290f0bf9a946d74535ef05ae050c802515c7950e86b1bfc7f528203274a5182bfdcdacdffb5f3d94cbefeec70edc7e19c4138cbb651e60c542560de5e64f0f26fc3d36bc8978028b32c235f941e5f2245c9eb38ef740e78cfd543a18edf61adf76d9765174867971e96275ba38d4592530891765a06e749d15cc8caa6d15e510a4685edafa3287a1f64383773e52d803efacf5f831fb0c5165822fbd4a55141baa73561865fbda5a8139b2adf86c0d3f687606b5edd35a35cdee79adae1ad0c7a3256029c52c6b2e0a1f039c6ccebe7dfffd77c4a3dd8a5c2dccbe8a5d7cc59b3fcdd183083ac835d8b5132d4088e0b766b8709a0808ec319e4c5c1737a962b15aa019c885f424dd52630c6bd2efb9f3de1363d1f367be37e8e8df63bcc54b30a4a03fd58cceb49998b97a20d08f3564c0882c66a9338a2a4ba06c5f8d94e297bf9445f539e096aa4c5f645526cb4faa92c8279d976a6e9e6f4fc7b5cce06e7733d90db6e836857673a91ddee957f6b8f6697f866e918789e98654aa9057e248e46a0a3104479441ea1f85bc0ab8167ba48304781fe652bf7545b677ce9b4cfde1a0d6a6c3110c1f83d62065b54d4fecc0cfd2405e3aaffe2e487ea869601759f392869238bbd178075143defde6d6ae26075154b3a22af4dadbdfb4dc540221911bebcd4dd87d8753caa2a8fa9e64bbd6cfa36b2c9ae45038b44921cbc40d7b18c2f68bb1a1035769c890e8ae8eba22be471411a31f212124ff365533fa5acc44a5184d6a3d86fd11b256a6de1d86103222e3779d3b468e8610514512ec5e24eff98dc6fdade5d27f938113e57423ff9628291f7a22249e48190b3bdbafb7c84786926e8614506ab1c38dcc8d7fe99aa7de472d402d7e93be87bcd05762771fb196f7299e781ecb8d6b7f6f40eccd245d7ac7e2a4d626209b9b36cfd35ea0d150c8f82bc65552adc78fa9fe48ab7770e1f5314660ef843279bcbbc87275f5a352fa8c339bae176a7ea15c64b7c87907ca938a8db9d4dfe3b57de77122b2ee88e9b6778acd85dc4506ed1ab19317d312e8da17633660849768d616506cc0718e8fa18462c8bbdc2060b82ff09a0e6c0cdd0b07ccfcd86cb77cfd4fafe20317d1ca7863acba08cc7ea75703f15c5c8989bf96ae86627a95761af468733735fbefc11b1c4737e2b871c69813346c09a3eebbb95a2dddd622e44d92a4fb42275152a203cff238e4a119df25e471b1e5bab107216d469f0b833e171c7d2e86627ad1893ef89ee092ec72e858faf82694a5cfb16c9a3db7a810159c580067d6b9f754a7d8e4360b6a7a37cfb98129b2fc0d72886e50c9a9d45217558672deb687cd4cd553493e2cfc7ed8dab3c6c074300c4f19e9751e857a1d7399903aa2ed447373e3347370fdb04e8e8ec4fe9dd16803c5008d3ace5fe0449053f23c8b0e97157c62f195a5da501e0aa98e2cac276cb90e839a57819f51aa1e0e525f63842036e521ab1cbb58548a5eb8175923cea5ac4423c19bc78b3487e4dc08113051044311d1b346e445b32cb3357cf796f08becb315e6a37bd965d16014b47308a33a148d12a5d4bd46c80af65c14ce83f6f48ba9aacd6bfaf40b128c3d3866fad3677f7cc6092c2e254cd82efde3c722fc1e7a88b9f50f1ab9fdda11bde575ef305937dcb1a0e66dc06befee8a97886a49add84c99135f473c2a6ce93bb3ea022bc06bdafcf93a5b14658bacb84a662402024e5b083836f8e6db270940a9aab96cf47bf470f204405f63d71463e7cdecfd4551cd9ba19866d30b7f3bc22f5099997fe3c0a0e0134185a3f68fb8fa7ceacae7597d9ecde54b34f7e8fa1cc606c59041a69a1938d016f307dbf8d478dc084ef5a6fe4fce184ab83eb08798d29813db2e8620f6b8dacc82141ee92c34925de8a403c2a7a1f854ca0a6c57cd5ba0928d963934e83050c4e04a61541f681cf747f6889513d3fedd3d0e518cd5805f05b469a214090b9935abda7ab5b89c4ed5bc2d7df49fadf4b11d4f0cea9055771d04f238d57e0159b410ecdea030e22da4e510f3e9d0ae372dd8206586d2d57f2cb6c6909e05886e31e255297563e78e5a2072860dda614ce945b63e97a22916cbb298ad31d68313ad65e2bcd0867e5e018136f5a102c490ace5745537c5a52cd7cf3d60d8e74f1859eb934bbe55cd5d20a74fe24b2838149f82cd3f0537318736b6ddc9a7b3435ee5d721804502de510b15e2428b108fda3bc2aac6c1be1e8e121c6830f75bff238e1b163013f3297a0fcda756abefcdfdcdecb1fcabe4b966b3888f2c348bcf6c90d6e9643e3d29ce5aba0d43c0c07f6e2afb7b43843348bea8690d9217025bbad685905845c48d803dd4f2da3d7461b85827c8f3e7ea70bad4d1ce10657d1dec29f5ea39303b7d08d547a5e1d48128b91ebeb233e009561c22b97adbad5e2887f1410992a21854f9bd997d979dcbf23bd03ec4a18e2cae04abeada5113cb0b47d10fa3dbda27dbb908c3cf6f4dfa1c31f7a62bc15062da120d33a04a1b0e56f42c0bc0042bcde38396cabcc81f11aff8127ec7e194e26050535535aa942359d7aaeef7a0d1e85303a46ca65655fea8e7c90157a5390bbd38f052dcc3f8899897ea3c2b8907fc6b9de5e6454ba8601795b2f7519406358b6a475e6fa0b5c518a0f4126c46d88b7d19c24c029a104e82af523f886fd55eda39e52a79494bcc2d86551de64d8ea7fb966c7dec6c6da00cdfb43d69dbe6e6466caae6d7e6b9df4e57ddbd992314e1831e35995ed59996fdbdd1b3c128cfeacfb2eaef8df607a37a7e6ee5970ee17065fc457ddee83a9b6a6baaa82f6a7505d9c7be016cc201f4c0259932d016885985354a96f944c8425fc8da3cd4b23c5b6a09ef52c3ac53fb73899828546db88da29a2ad35ca3ffef1c531f400e0beb7d3cea99a666dcb73c36eeab4c4bd7870d24800f3d3285d1c582d23c0cd2d1703f50f306b2dd50285c8cb66db625ac930a73eb4743c6fce55a34abe51272ec8b5565381f7c0ab99721046d592f652e67e2977e6f519465d1c8a9aaf2de4dcffdb128aa9596bd9bde855ad5bd9b5e9ead7b37bd2b293f9b4255e98bde4def5fabacd6d214af6556f706b79b27c027695642fcbdc278ddc144305a357d76c86116fb05c2e987998c79164b9f1fc13d7f60cb1819bfd6b2cafb0c9c8f123b14e3274fc45f4a59e50def503c1963576d7d7d2616d912b4f366ab67aa5e64942f0174e16e27b004f4cd66531ad28dd325268a0ad642648db8926569feed99b532507ba296e0255f41f34ce4526745894ef1728c38067bdc0e13434af20955b80d74cf38d8893b77ad641b6fb3ba21f53d1a1e7c0424fa08acaa4b4e28793a49339a46678b651cea26abd6b7640bb1cb22b369854a18d15f91c063aa16b2c19061d66dbf4bf37f8253382388f27a89b9e4e0ed8965ad15e9e3dd7703f2bcdbd32826125b1e18d686c5e1161bb4bbb425d6e4b259ca69312b642e3e62858f8018995d4cb7561fbbe202b91a3443ff5bab6882d1d2602135f378a2d567192785b76d36ac0542dbb0182ff2bc89e78c367c1fcde1f86870fea395573d78fa45b55c69ffb5a315d90e6213faa1cd6590470dcc89bb451a89955774047141e26522f81b9629cbf32d11c60710a4a5e1912a707ddc349baee55964d7e98511fd5ace642daba98c8f8e6b5b54299c6a5634fafff452e5c56cb6c55ab970ceb44c96b0fe875068cb69467d9c985b31cfd6960e1dbf7b23f2ccc53031a5685dba2fcea521e1dfab2ac718c8e209d0d23f52c1bb9529107d97500a8d07b0bf2766304f0ccbf3b168d44f527efe38186d586258bb37dbac324567fe1fb5c68909c92a4f4da79d33e39ef1f230419de1d20c670e9cec6b558372a48fa17bc413121921d7e953d251a2f15c5698048cf8be8582f48cc4f78cda6fd78707d44b59227c98d632d33c8f65b7c9a235b6a1702f9c0f7259d3d98b045939cb6a6dcb46d9568ec7374f6c60fec41167ac0e83ec0b964d1447d81b349808621ac30c1c3f38465a2b71a1ca1c72af1753a18be96797374d79d7a526cd80bf2fa69f2dafe9066260b85178546af769effd1a593e43d424da1a42de10600b013eee5cb2f39107d2ba71cdc7897f093ec13fc413f1da1643bfc84aa13ba5abf21742d67457237c0ef8da783a8929e3ec1929ac7ccd906db8c17f4ece6ea1190c22d1ccb987985e3b11d5a16a5b7642159fd3c026a2d7133ba1e860e834759d2b55169544698fac0959b65e316c1baf9801810f644f0ff9f29d33ee306e8b3eb641bba575e3a2cbc3838726d24c84d84bc452164e3f1c940b12e9b6a668b44349ba70c8c89e0f2de20aedf3d1bd41b23b8617ed38ae1adb71d7c43945c3803a734b964afb93340cb24249a12a8bc32c9c8438c2ca5ea4f6543cc74f27077049c39fe038edfeb45ff722450dcf7269d9b6b2f82cc5c1e899b9b530f474a9b3a19815f3552dc101eb425d894556ada3f8d0365d151754b9b8f9006520be12fb6d09a15be647478193b32b8805f7e3310681ad50a8e1a3929fdaa806b44affa027591268974891ad78a9e6af085cec711dcdcc4303317631fdec94b4bd5ee4f3104e78af15a36a915d9bf369bd5f16d9b5efcdeee36028a26f0156ec8afdb3019f21e46923b85f8a7db9fbfb81f8458cc71055d11e36299a85f98d98d01c0a4ce45998c7f9ac989a45b731df341f70a9e634e0ce55627b791837af568b6fc8cfb8c8cad0d19d400fc24db4fb12c24ac371cbb728aa7e5865280ef60643b117820936cf8d7ba4156b19010a70a9e569ee66f98acecb91d8ddb79ed6774cc837494e868afd4404a80d5f17d73207238e0c1e526a260ef612d1e7ef9c3200621da50f4d6bc621feeff560589584ec81867a4484c35c5e7b892368a5300e5aeb322cd53c83700cc5f45e5418a297cb4506c922fc791c8b7ee0febe21e20243e841ecd4e4011eb50eb8350edfeba534ca764c4747625fdcdc08f6fb20fafd0cf22e60b6189786c1fd8ca9416a0c5db8dd9dbba2179aac70069858998006d0b7435b83a5c089eab112aa0d3cc69b9ad2ecfc574882c342dee20526c17165ed66710d9841a81cf9d048ddefc1a3a937c485238e0fb304c3b3c9323313d143a359f351cd668dd413cca5e9df70f3bac8813d138d0439299c3ef31594548e0b6ef7425a8a89e8d5f3f3acbf3784ff46fb83ded0b320a06f9c887dfa94d7d9d5d7aace651d00329fdf60eabf17b5cc5a65c013065f0d827c9fd59fbf03349a887d1b67f3dfb256dfb53bb69f5fa6867cf0cc8dd9d6c341beca9a8b893839eb2c7c438bba37b2fde332ffd5af9f5b6f7daacf5350cf53d04e7916668ce94b4c3e8818cc4f50b54e58cc586be2666d23a38de31b0ff531e3a7877aaae1cf7724baeef57865ad9663725a266b552ca21f2c3eaf56cb89f8bdf371c14613f17b7e3cfdccf0e1c2714fe36613bc73392faa17faff96b50ad77251543fd2a5efa3ac2eb26bfff199fb5ad4b5d975dedc8ddb56aacd1dd0c8b0560aebb39556ef3e17cbe4c7b73158989fdb586f79f89361dd1bc3c7d66a35bfb01628f872411b46345c8464a77040f1a1095ed1d649f78dbe308f6048c086d62c1792d278f8f82013f6ba6e3f45fd729a25fae5d6ade427fc7d1a678e653a984a5e91d51019469b6bb55a2d8eb55c902e21abeb50a1d4648b6529fb595d0f5d55ba02f0ea6b903692691aba7b4d6b5033a27997b74bb1ed7d4d678306cc9f3540639afa8a4c53d02a05edc8c4ce91ef83496fcc48d0f622abeb1376e31683b381f79eb27978a0bed57c710f431069bd56b5a50a7d38bf8e038848065b0c9ae89197920125ec0fb8e9015d3085cbc1e8b8301bfcca5fb57e698aca3a4d7be0769ca693be07e95ba158d8b6f8003fa191ab21abdc97cb2a8f4a31019838326cfe1f80f5327f88a2118bac9e17e6d584e69ec87965d3e96a0106f8b900cb869185846b461b0af9b5938b48c1be681923836a6cc2f957bf2abb38d7214c68d72f974f54e51823c6e8a480f7d3cbbb3f08c03223ab9867f59082e1ddb169b0dd01587f29238c9d238e365f1287f69c96564cc46eb0c8145d09503d70b103f109049b281a7884938c02627bb14d701d7f4978e4d2c519fed0177f056bbed34a48974abcc4cf9f83d03e8281d92b5ad336f65cb445ac906e95eab05843dc4038b6eb9d06f6bedd067440a312c674db9acfc5f944c97cce9bfe3ed488eeb6656561a9fc2f608d362443724bad6e05bac1799d3ba4a01842d678c85e02767417c5fc42361af879806a63cf41343ac2b4a2ca8b2944e0c1d455d30b4581cc6d0da795d66ae949c428b65598a2f7083046ef8a7fcb06edfb4ce7af55a59ba11566e1eea6082d7f9c38b2052bd08477122e47f411871b7de416ce307d3f226b125f83dd338c6a0878fc2d2d76b4f668dcf91d0289d6985f6e0c71ace52cc71ce4b968b227c5d9083e1c7acefa359a79bb7260064896072b495f26fc8b6120ac8b47682a1ebcdf4ded51c3dfcc81b57d73e25b9ca53fdedc885f0cae03b722e653c34b5b7377bf78bc3bff95aa599707e726610dd7030b6142d62d0d846d3e46964c1500401acc47569e8e9fd821f643e934f3f5c77be8088ec30d04e80ebc9b516bcefccaea1a4c9745786fb34978c26e1b4027ecb677763e8561113d4adb56a1d5f6afd8918e5d615d867bc30b22b9eeafdd250e3a10a459ff9cc4869d76986adbe134c89b5e715758224b587211f83a1271c222764ec6365636c0de7c57129141d2635d861ae7136e19a951b65c96eb7eb52a6d26ab8684abf642b047ef8eb654c989b11ca9277949bfc8af63756b78b226d4ff49915f03e9f0093910f8c47692a8616526b474be066d865bb62aee1d6ec3891be6dec03d07f967c6990fddc64a5e037fdb525a3d5f4c1fc0dae436f5f4781fc849220b3e1a327d1c39498b6102e95b2867a10c0dad5ede39790479a586fd40d057b8eee8d5cdf8f647ae777c6ac7bbb9c7d798ee147f086de30f18fe4d55be6b68970a7ae0a6a6ac57affd12853e600e69ec06113b2e148273a40c17c48de50dc2b5f02d1578b3d4d10eb4f4fb1b676851ccb9c04d5a22c9beef69e4eb0dddb632f7bba1876678a6bb61a12f1f8764be0470f4badc0610ba020690cca7c130becb37c3e20c9305e6bfe1d9180c9d6f1f4a00db2b5ccb469597b27f120d134486e130e9d326bbf5d7b6dad920e4af4334794f2c4a842aece0005fe5021ca6b0ca8e0c6afac73ab26847bed8fc1ec92a3b2f656e43cd6c06685a0cc44438de8ed1391218c13f4341e222f8a74d882a55bdc34477a8117caf5e43fe764e1fe003e41ae7bcb3960b1fc45be2db0f595c1276ec0d49cc1300f699ffe9714bbc4711e4ca2f307078d012037073af1ef2ed3695471f10dea3cec0bd761a78cb9a3683aef7aaad9a22a8df5ccaeadd329b1aea94d575f85269c9b4ec33232f6633465a4dd52f452b452ac83743aa5a8bbe69fbff91f72fec6de3c89e30fe5590b3b3b114d3b294becc8cdc8e379d4b4ffe9bdb269eee998dfd24b4045b4c28524352b6d4937cf7ff83aa02500582929cee3eef79dff3e49c698b040b40e156a8cbaf90f0bbe179028ab411d391f1eb03a4a3adaa77d9b93a800f28f982e18a2113c131765546f840ad963c70c80b960b30b39e999ba2f6f7b87495d57832d1a3e7d93c6b18b7f4b52e5e982f898cb9964bee72ba4cd1e58af7dae6aa435697fb02b3edd509fd9198f1c868c616d6a30101d9ccb2f4766dd3c47c0d35eaa94a17980434077727531c96bf7398393c547589286fcd4caf2d0468481880180d6535992d0bfc144edb9021d1fcb9f374d5230e24566968e70a76534ac2e69bf7f826fb55f75a751cc98b696243838918636e57782fe532749ff83c2380468e6f1fd8618b4d4053a26b067674bab52a5fb0b9d2e376db4ec5b59f03b1fe0b654347cfadd1d6dfc345efbc8a3aebdc683a14d3f5a76c013da2bed026eed69864263ae92d8b4668d8298528ff903c796cff0d695a037e5101c3273acb2dc7c32982dc08f8c3b8d2a04f87650c9b0b1968624dbb780c6636f964f7ee63a78033b2c0b2685c7275cc341976073b7dcfb2e3bc434b4b9a38a889ab539cfda4c57bcb7537e9a0dab7a87686bf9fb8cc065cf9de1285f877c37ea08a77c680f8674f8a6922f8dc0f7e1e750f7e4e3b2f8d72025cdf75acd1eb4774f2ac716a38fb461d30ae10473d69a75ee5ee2af699a88d762f1adfda522b5c627e78f303d3e0cba9411f32c85f1c8d7d154c8f7eeb60cdb881a176a304135c17d3ffcc79bd6bf3bf72769b396131774034b659b4e952f36fe48ab5a283dd816ca2c2dff727dd10bc3a5edec821df0577992aa8a8751d05cc2a67956e796bb338242a86ae99859ee8ba4eab35b769930ba527c9dc77249ebfc648e0fa28ae7fc8f5653356733de0486142bf00a6725fe0b45cc8f7155e7e7c0984371365ac7ddd172224ab969e6263640c7a18c0fcb39afddebf495d8d52bd0b69411ffafb833f4b6e9193469b572e622dab0768858eb5478e1939d85fe906d40a51ba0c8b056823b0907972d4aed85d0c518308a04de67956ffcd482d65d1a479afaf4e80e26085b5aa31fe5ce34f406b82079e0a9df6cca3e174a66b6d117240c403070f8c4ecdb34b3d59e77aa0fede6479d66468f52828b3c080683c2cd61e48c32a3fc1660228eb335d650d124cf3dc8edd7a4108442181495aa80bad7019fa2859ffd957046f24e8e77a9d66b9b950aab458cfcbcaad3757373a75c3b63098ebea0a6ebc355d39cf7ec7000d9830ad1a62f3067c74cb051fb60bc8c0f6f7c5548673b84f58ecb54dba226615ff3e51efcc3beb21d05a759170320b292851a89da1abfb43072767bf247572d7a7b8b4bf90b5bdb6d0d1101bc143e1f4f44a5b3b6e0961dd305950f3ce5fc29aa34a1466ad466a3c9cf4a65475b9ac26ba1ebba2cac3dea903fac65c6bf66a55e97f2d33b35e9a127d325d80436db3d69a26d4b60dfc4040c2cd2c9b7c2a740d45a8e5a51158ae20c4382b545a60b7ca2ab3bef56c1a2dc38960c728f14c4f2c13379e09d6e5fad502cc82733de09a555e0afd6200e6ead87d32f04fb905196f1089f308b292a4299c15574f50c7c30df73835d573d87e26001afeba2a2fd28b7c4daefd3729c66b822b2c6e158667e5b5ae6ecc6e13a0fb1c51d2e9b91693bf2770db1e5ed465754193b36e74650d349012c511702be0d82d8623fed219f4dcdffc35cee4e3b6123538885bc76a700eb78f547b7cfaa1769d9beb810b57628922e77a107ffa3e7746e9f6bb79ba12b82943ff8e5059e0b5e551fbf5a95e358fc88a1a7bca21c94c85d6bd13fdb4e26d0ddfd9317528bf753001de6a8f005c3b4fddb91ed45d2fd2cb465791cf5c55e6709f67c5e13c5d05959957a08011046dc2bb8ed7505ff8ca5686968f03f501367618c50f887371e3021d9f3cbee3ca3f2b1a5d15290f513045eba624c73d2b4651d8d0eb37cf7e7e78fa84e8bfa70a3062cf1135dbeb7c5937d69e994e8c80aaa704db9faf71472d974d8d6a9fac5600db3090ed8628234f15647e0cc42a8b2bc44c3055995ae669f5091b4ce25742805d7b8dd9dd8b2badb206a2449793666993b01c1e42686db96cd4b27000001795464045fcb01ea867976a5d2e4184876070e84f2070d6de2b12a33aa4af1b00a6e8743a606b0f27c18fcb2c9f52293e942ff58d872649119682ecc424123adb7679e9c6e962d9008b7e7cf8e87ffff2f0cd63f5e8d58bd70f4f7de36eb4aa9bccc85b082fa18ad2d2ebc9594353235f0348e5c55a19a90181265d346b7fe0af7c74345cb0fe04288066333502a29a97d3ec329bf86830d2f7292b98b4c9c2b467bc22cdd5e7cfca9d41b68e2798a71b3f76693d5c1d85bec12b82c740c0db69ef0e96f9fc59dd11ea0375f7aeb29b627071ad25fe60443f663f8ca8c84247282c078ab020bc255feab1a3f42e3b4ff86b325b807eda3fffd20a33f812dbf75bdcb34997814515f921c342bbcc1a4ab491d2413f85987f0dde723c82145d833190367787b35d3f135b8359404654282fe1c05e1bb9f9caba8863502c4bfe896bcd7c402a142928a8632e7dfcd076822297219a4fefc9fbf814ed267837ea85344faca72f174ea086be8dff138bd650a5483eb3a9a5b921d2dc64139da8d2dc09ccf587fe844d705256dae6e0cd753540a1ed79ba2e978d0762fd9bb9345124a1e12440c7da00093d556bdd24b0f45dae1edccb09dad513fa39ad32d3b35aa1cf1a6f306cfe5e4be18c178643d61f3d3113c151cb8ca05b7e424d3e4f4287e74863eb37238ddd3673c137117db8077e52bac6b44f35f54604c7b9edf351ac99fcbc8cf6a375a06e2023eb7b9a35fce34bf91368b9226ed35b36e541fd295b04cbefb47c5ca5375c52b6d10f77efa2c21c1e5ab77cbbd9a14c0d771144f33705f6ccb5df50b6a5ed0e390e9638648592d35cfa4efd84f1efeeb6424b3ecf555116d08d0560f5b8e8e75d1656d0e7564e0f267322b123a5d4e161788e3dfbf1d9f367a7ffe4a8ca2f5ebf7a73faf0e5e95801f3f17402c74b1b6460a48c0a27a938e12077f0cb273f3f794347fd1dd61a2016bb0e9cbe7afcaa77fd4d7f6c6ff1f3ac802d0793002d2ff26ce2330831b0238ceac678823c5739ac717551ae40c4006fb565b1acb55f5ff3f493f6376b10abdc3d82a9999c8ec8dc24b0319db7f608fc835d73bb6a08d14e0471262e375778251c50017e35747ef6e08fee7ceadda49ceb408fc5a6a5ff982e07fad23b98596af8aa6a7b0b769269ca4507950b8e626f136792578432d33b9ba4b9d3275434ae145bd494aa291700bb4d710029a0c5024b9c5b5fc8c33be201d74de396211a1f442d6009d60511b5806fc3fa62d5c1c5c9da2f1cb983b03a3bb3d822f91a8513fbbc43df74c8355be292f5f50a2e4126526f536fab27b62a002ebd214c1a96f2c89f770aab27e9a612c7d9b6f90f510be6c876100f448ce722ab82f0f1b9474567fa8923f63ac7242643feacb26a0a2d205c5bf96b193c3b57701c090084af6a7403f93144a32e6c5e0b576d7880f8ca78605f60b7106a07918da3fdfc4de054dd324dd8573869da6a80af5e11db2668e1f50a39e800fc12f17a81af5f1f9e466c7144b413dc0fad28cb85e7c76f6b4e4062c316d18457e9afefbda711ebfd05aba1abd3d156c8bb63c7064257d45ae9f98290a5ca7c0a0e422d55804f25cb7de1a99abb77a5fd7b03448ee3053bc2836e24eadd5c937ef63c806e36db1e29124c53c356f630c92a5cf7f5548a5f4e1b9415caf3b5df9207bfa6adf6f373d010d85f8145ad65c4c31960e890dcfa0844d91a0271bf764245c9c5e6564c6ebec5e9f388a269916d3e98d67fb45d85cfb8eed416f374e1af22cb1aae4ad059711df179e94dabfae1c6f8bbf1b49bda2e1244f496f7f5431b25171dda5debed92b73d42ad1fb9b871a6cb32532ce7a77e68e341b8ce57d736915f4df9e3cf9f45920c16b02ebef08f5961107f587146372c059606b05679d381ffe92d58d6ac656a8e59b8b0fce32cbd2a8b545e3aee188937ab7fceeaec22d7a8b1bcd3ba8e9b3d8475ffc1b1e8f2e7cf9ebb3f10b0c89d4dd29c91bcb672a12b5792b0c1801d84dc0b3058d0292338d3ecad1a8a0c301c43487792a7b23885675871ef20f6ae1d64fba46eb2794a5a3e4a487c89715780d67191d67a2a531fd9302396f1d79143a1f9c65d84250e2ae82a41617d9d5a1d24b3c739f7312606c319c172458193166399e5a39b536c6d5140e70917ab31901f27c158b1a73df7d8c6ae4b5df837f68eb8baef6cc984420ee6113078e09541a7d3141d17d8ad418cf3befa5e3df0eb20505687f6c9a075bd56ff8683efd4588d18a694306472bbe64177a0cec001b1f4cf9c7afac0ef13de82be210a67e0e142446bc4d2b6635dffab6a02cedc5321a782397f2f78e06b09d7aa3f1c9af2b1beaab4ae7b918cbb88cd5567857fd9eb5e56fbea7beb944df373d4ef271ba979e61fb63639f8dc827ac1674177db9fb8c1e97777ddf900b2fd2a51bc45fea9f8b61fd3f885d4c5ef5084f8ddceee6e6abb88104fb3e6eb0586a75913130f2ee3343b043db8e68ae39afc2dbcfacfc28f9ef900c276c420f7ab73d43081dcb1db1ca50cb2a30012f10b718b9797f24f5951bb59f0826e0361e5ecd98c87203bc2b98f49edeeea40c72922406d4e392f45797f6223617986f3dd1b5629bf81f982fca8c701d9a0886111cd61f460fbf3f61ecbd9d557fbd12d5472bfb5120f0fc9e38a89455bba1357fda8c3437599e539821eceb420bb533f1ddd3faaa38fc11279817e5397192655f080a81900765af3553d2b6fec7b6edeb4e10ca1c9a6dd2fbb36005dc0c6bf85e1729694c4b8dc51ceb3816755eddf4af90dde05a43b0b9b57a22c0a8b1da5f1a5284fc75ac7070ce6c1b7262b20404a33b0038a03e411abf7d470f0ed51c8589f4f3c14278e246660c78446414ccdfcb2476d0b6578e38a5c7238c5293af00470e3803304acd0ad830d50488fe407697195eb37e9344b03b7afa6a4a7bd904e3f203129ebf0649e94758f530e3fa9c5d50e45a5ac687f223ecac5c58093b817ce0edca7fce767cdbe68e63dd50be787bf56f43c134f5ad368e0007d86fdbeac407c3754633fa110aed32b84dd67aded26b821b8aba32cb72f78b1cf27609b6dd860523bcfdb284743239e85a62cfee91bbfc556c4a20899d865dea364799a4c0d9eb4f27cf3c560bd676669a3ca250ff24bf39b745dabaca86db41e656055bfcc74819a7c6d2371d0e405ed4ef3ecaae070168787ea66964d666aae53f0dc2787582c6eaf0359ada6e51c3c0adce283d8797eaaf8e54d732080bc90da7f270f9cf032678d9ca372331dd88cb272e60785ecf49474e527bde01b37f3a3b424c2466094e8ea4850a1d8e8f9053e525dd876c913f9499c2531b2ac1331e05e393c51c67bdca92827620d939f7c0926f8c3e9c765eda75983ce7e106c9a4e3094883cff545658d40c4101905ba65373755fa9a654e8cc7f939263236933c0bd9bed39a129cadda57a3209bfdf38fae652ea3bd5737f8b42891a1a79e89ba3585d6fc406c72a7b437381ed355babc352adfada030b67aab3926f3b51a19281a2689514361f2d88e13e503414024b5e5475698440dc3e68e3831984e34343795956d224288e35ab11615aceaa0294a8a15c0fe4d6e9651570912a8b3aab1b5d4cd698a325102302025c5e69e79e038a9e00ff367acacaf3c79c4db66d47b1a3ee66b32e4c94da67cc91075b68368def6872fd450ca7d17d897f15f1589ca5c534d72fd0879d5dc5365dbec4bdcb3b36046a3fe77f8ff670f1a4125046c2e82d64836e2bb96b0167719c62bb8d6ecb664d6aca857c207c552434adf3fcf91b70cf85cc9815e2ced9a2d1553a11b14c6d3f21c1fe5db515e4d610c698f09807eb83e0354b629f4cc2e1e91f4568a0c74084c469b94802de450954e13619eca0496b4e44c9383785081d9cfc497be0fab191b38e845fade08aab9ad075e0ed2cadf454bdf0f9eff902ea1adc4559db2045873544fa1469588582c7c76aaf29177beaf367ff806b5c50f595d54f97794e38d79ba32e1d768dfd20ec960db9b55ea7e07037502fd397ea229d6266a93ab11016946465bd00575df49fa7f344ab952a2bb5f6468a9b99068d012907d83e5f5666233fc3e851982b3fa3b7b6eb4c95de0459590fd5cb659ec322f420a408648c3b2adfd938e89b23d5b6e8bf4c5fb62cf359fd327dd9c3aef5958d1e06c0677378827b2108fb864559ad26333d016108330da27de5483dceea495a4dd5b3e2322bb28658c77421165dc6360f071b3f8709e05eb0b4b12fe1b5c5ae7b0a9477efa0ede2330bf497213e864a0b1acb444db36b48a758161a658f5c5f5b90704806100e8ccba81c46d4b672aad84f072b993c3db87df0e92ba60723b029e583a86abda1aa1d2a5a77c7038063380c4fadaeca729a5897d5ac11cbd0d2120b2feaef7b2bcf17278dd521e08cf048f0ee0882767ba64080bf48ee14f1e38efa10dc360247a6ef042b24b9428771388e28c5e37c551c0e5e4ba62c16c791e519e6ccbe02546b1b6f012130e87e2f12fadaf01deebf1d75dff6d136dc97c672b4db2943323470e61eab7a5d4c66555964bf6af5e1bd73cb6e66968dbdba548bb2c1c419f95a3810911ae816903432dea611c0b1cef1dc2356b8f561b199d1313d2e60c55cab85c6f636ee1e2dddaf7f20bd17fc73295cc9484df1a38d2f6c06bd592571e574e829d44fa4ff48128bd514c2512cfa73b3374294f1aef73b321f7a139ec532639c734b078f74b80581bb4870b7e039e4429f7475acf623bb2e147e373cf78c40209beeb22356769e15fca6e69b282cdf1148165624bc89d834f59d2df0b46dc7dc511374826fadb6b1c133689dd8828321e5961fc0df4bd8b7e03f9188e68c69a0584bc6a6bb443d362fbab038deb2bc23dd421a2424b0f22e9b4cbe24bbe35c0f90675d07b44deff30ed20e0e2c6ecd5ea2f00162c5ef9def75702b3668b21ded35f177dafdad481be664749900cb326fb28543a601301252c862165780e6392b5ac907e523f35dad31f9cf99c054015e3f05302abd8af9cd76e2b9e4e544640cc4f6400b21c2674072cb242daccfcc85c6bc75530d327c6ad335a63972806a39857b828d5853bd2168b53287cdb05c2c74750077d3495915e466e454deb2eb9cf0d730c82af469b7dac2a07060811d3cb888d8046e450384b3c86a4aae0b211fa62f61b57f045fa005b2ab2241ee6f9a0b206d75ced3dfa51fe1f898238fed191287b3d375d366be6027a9d08db7bd33df476257adc1d39ea0238b1866b67fe1c4e59cb7c0752be14e6756ac273c5196d3ec81e26e6a76df3a01e004fb6b1cd89f28671da198de63cddb67cdf04f0fd57db4df75ed588dcfa87ca5bd691ef372f0f14fd5425713239523880b074ff943469ebaca069f52ec750f3f5780c9d8ab3e8724b3e90747eac0a6edeb38048218b07d97e5ef1ed31c0ad65ee9861aee579ceb007055c250b9c6e04bc4a0a979ade0a206cfc4e414e05832ceec84f74c8d451f378379611becb134cf8a6cbe9c9383d2efbe95db01ff31a5966fd34685fb67cf3e3514f04930d1f9bbdb5c0650c042e72ee974edfc6fc2050eb75c97724c5a330c39b3f4efde0512e6cf13f84b9478e04b3cc01259e14b0cb70c5fca70015c3cc285568bbcc49b72a9d2eb329b02304f9e2e1666a9e3f56ab041a4f749cb6ea95dd80dbcc803f10a657c40072173033ff753ffe2f3674ee8d0ede7e6fed2ebab7d351283e8413a25490973dd81db3af6d813748abc900439fdf67982d6b238f2a9f7140a0b84b51ca811ffc4e13a3948d0f4fa8a23e91e49f51d6003a0d5af2c31ef31070166026b33d3103aedb7d6b0290fda00ca7083d802121b92e1d8c8fdc01dbf0503def232f3d09ebf09ff599c21ed8e0ea379969c0a2432485de0bc96437128573bead979f8c04ce5f3482ed360b8238d79a046ea04bd13acf7439f7cd1c3469b39ce809d3a5ada91eab41734a54f5211cefb83706226d494cd75616ea85bd4c8853935c625b51fd67dab69166f5a5f1ec67102bbe94eec7e75fb102526c5b6b659a702b5cb8210f30874e4624d710e59812e0318209895c5c0d75295cd2ddde5c855ce6a4bd20b72d69f9475af2abdb33bf9c7b5cad559e1cb756be8e2de99ccf3cac58f008b0641aecd30a4ea46aaed4eba34663e9107a535b104661b08b4420f02125b06ca6c37231b73131f2a2f8748438abf58ccd43d189607ea46dd03c69fa81b7508cfc60ab08fb3c2df3c6654e807286e0a9d40212c7e83c56f31c39dbff86da6f806e778e18d1e6483891d8e738d00af6e87b704ee304097507f74e78ea4c80d38e082871f260c9a2cabd535765465970a1c65ccfe53165aa5755d4e32f0ae23d5042b4de31839593c40ed803edbae6a371dc4efb2fa317e64ddf533695c337c719598fb0b967ea19bd483c3fb9b55930e560f5759fdec31d81ccd7c9ba295a24907ebf04d8775ae629acb78b22a3ea759e6891df15540dffe13472b64936e62f345ff96d9b7253cd4854fb018b65848850f8f501d167eafd0f889d174b406c13b3ef37708ade05236d7842066504b0e8fa53bf4aa07df4073051d13a8bc27916f8c32a8451809a1480a61dbec7b5619e319e07383ab9378c6745fc5c0e5164f145e5ae5166e6af85b9a5fda5a7c8d321727f8d75ae0177f34bef7cfc3c2d8429b3ab74325e066bca783b335c1ab79e21be4841356d185af83a1ebbbfca689750b7ece329ebac1598d12d5accdffacee9bbfee27ca3c324fcc03f39b312fb739d113e5f390f3bf5fc9f054b377c850a0a65cf0fdf642f0276459cf0192f80da9598f3870903a504dce5ede57c79c2146f6e483eb4a0295567d6e8f00ff25233cc63fbe6f774e282bddc2bc43413408ea569d175e54d064d142d9a00dbd212676720369f3f674751dab22ec987dcffbce6ee7fab2b95da703afaf663592bef97cbc57bb8ef76acb7883c75b67af5772c037215f6def9f74ae5bc95115410aab2dc38a9cea1ed5d5cea3babaefe1bec4b0da951c4db6f23c922db69595c2c309d3fbc34365a427c4b7ab94c3b99b65881daa7affe3dbefbff9aecf651a79f76b5c6209f06a0a93bf08e96352164d5630c1e34b10ae64a5169168c2900d82b44db1aeb4e1d42d001974d98d49e15f2ff4047c2a7c51b7a38a13cd36400e0d96864d375a1adeb0d27e2f8e16ffd1bff6e908c22f5f594bcaa6efa990b94e0d7cd055db459d77f616e77496c8d01ace856d642678446589daabae2ed2de30817f83517fafbf9d55175fc9a2d6cb90357ee2f17cfab18cff1605c8666bf9fcd974269c7d724d0170e56e09d6c314ebc79dee6e9b564f2856d8bd4a08304c0c7183cb1bbe3162103730dc9ce04fbf21b6c599d8dcc3730dcf2cf873bd99006b9791445b08c1cd6a34069949543106098a97ba3f06798a97328fd6fc912125281942828e2123a818228206859cfb65c3470e12577a892d368bc75c8ceb9ee6e39684e70a7f6969659173918bc373ae15c752f2b064bf5a865453fcf677c1e70e9afe77c40092fab72e1bc76e57bcac7e01713010cfcab556181ef3475deb2e374549b36684545f47356c2c0e78f39daf0d53c2bea97cbcecc16dd58ed17ba35301d1852885ec44ab44ad13d5e855f3d06c03ee8a8519877972585c3a4bf3d814bfedd566ddbaa6a803ce442f7cd9b60034a9e5c289da9be8a2d1d59e1a93147dfb1bc65acaea3292e9560d0051736b0b42617f2525f71e9bee682068f2fe0e5c119f61255d6d0aab2681365ef37676c89ab1c2d678b465e4af70906de771236f617ae113a9fd6e62742b9fffe6f37ee1417bc3d8e8505631ace53b04d4f44ac6a952766ef814ed9027b82fd1afb1fd65b3093bc9c985c807b9b645a1479480d07a95d27581d4f3de4a34da551831136ac1743c76aa3849b0bd1bf88267cd89eaf5f8e2b2884feac06f347d758fed40fcebb18a7c3c94e537c841eb6d6def8dbadbd18a17dc2822adc66ac54596b15ab39f958313b27fb19739ba8ae246ed1f9b51c6c990c45a3f66bb73500056f1d86ff6dd42cb578a19d32abd31f2f857a999b9b298d93284bed81d357798e6b3057e12c7af0355b6dd0727cd6a370df7ed749c7fb86ad69eeced3c449f3fa3c757989d0891f1dba60036325c7420283c7f654499c1d47bb46163c7c9bfd51c8329c3a130dfd86da82a64099771aa13bae3c2ab89bddcb30d0abfbd7b179b2c77ef6635a8d36bdde3b75cf390dfc16f02f5027cd454e5270de9f4217041aa14c0a8644ae9e639e011d7b3c0c013bc854ce6ec3e2c11166c83c4353af8e2550bd38007471b0ae076f53a6d663d19386d1a2ba7e269904dc6529897d7fab4c4b6821e1cff5a8fe2cdf545efbba2f7c398b20dcd78553c6a6d0df1c6b8b66c6b8a6bc98686f8e16dcd8a4a43faa95e77bc1ae46e77b6078192ee745da6413cd19ed537f0b87c8f9cc426a2237cc48b41c4fa57aa8c5a37cf0335126aa4c05ce2d67170f3746557d60c324ad4fa7eb01037018f7285b3d08790489a04ece83b7012d77519dbef351f21b98a6e2ba920b71f305252f3ba9058cf23f243676720fdc22dfbb2eeeccb05856edfaa335e3314ed8c1fb470276c4fc0f65eb8a3aa71d8173482cd295ce5686193af685da3d1ad1f69512f1abebe5d3eb91dbef52d1c8c402ce152feef2098f0e39ee515b467bd4835c80e7aafe7e989c33d4bd4477ba27f74e77ae2d0cf9c5660fdc79df5b62e7bc81941565ee35eb8f0f01bada6b0afea5563c3866c903d0a06901eac2c1a313fe4916f1e35555ad479da683a28ec39214b21901416a95ae067a604bba4993e0c30a85516c9f2dcae16574e8a10d022bd02af6c382e8ed5de3c9b4e73bdd72ae36ede70c2da078c61f6520c05787671bce6b8ef0211824718462ebe30ec1f71d83fe2b0f38be291faa87e801766d83f060738666103b0231fea0fbef4cbbcc9a0c794dc1cbce56d68f04c577a30080f78c3cf53bd6a7a7b7b161fe6ddc773908ed7521c58ab7dc6f2c845b01de71e088bae2e5a06b28e2f62ae04c2c22d77a1d3acb9a50b587c83d8a29bf5b8944cef2ad14ffddee59fdf6aebf29f19be0b9b943b21fe9432884c5845e4360199ee29bd513db8cacb8b341fd06f47ae1fed116d22fe4e66fb874193e675af8ddd2c6978056e9b4c53d25bdef40543ddb30e8f697ef99cab6164130751cdc1ee2a71a6071e46fbf08f84fdf8e7d1ce99ad3c01a11a9c7330337578a8e6d914621ead202ba01659cd2d950fe95ffd123b110ae0806f07ed61a1b29ec0d86b6f83aff7235f7b8f90764c72a5b29ae0d0222adba33893f093a03fc4b6ddda1374c52a82776005776f914c772c994711add8fca12e9fa883e1e03b750ffd8d5f3f5363257e878bbc75a6ca13b56b26f2d274b286876a78c8590d7bf0bafb9c0c0fdcc85e0473b8d2c5545790e895890fcb8a51c1dd2458bbe27c172704db13d0c1194a92d286f75c9c13f6803047c0ed94647e9b0e50a7b7eed1a6bc55ccb19a8ee45b38907ae15342e1b88d0b7f9eae75755bf9ba1bdffb5781ec4d7e2836d9dfafa1f7fad5af2de46ef70973de709f75721572ccfc0a5bc2d5af043f02a2e81df48e01ee480dc0453af97493565300ba489b0c13268c51829da535264f2daf755565d3a92e004d65599bcdd08591fa5154ef986cf2eb5835bf32656e307d02f18b9a3a48178b7c0dbe136975b584a4f171cc9f2edc11df845fc7eaca376053f57cb66d6b81987b9b0b5b4d4ca2789b9adbb50967f36e159ddf62ca43905c339965c5154da017ba490516d17aa1b7ae831d4dda3ec4019dd5015aa2ac1a3da5ca99eb7aed231fccd6d5e8ca6318cd7593c6b09c7a77009bcc3ab3c30fb30ea00f7c9eddbd2bcd43909724ea183feef28bf76ca72de6ac20cc2400cb182caab2294dc53880ea5885cfa764c92f30dca6d2ef31fe804aba57c2d4f7a79190f8c43bf70549a18f204da94d6c60858531136fbeb84fa0eaf793b4d15765b506d5b16dd040af1a5d4cd13414cd65774b949e30fea76efb3c6c8f3cc5105f57381ae9cbdea62bf92dfa061e873999ec630aacf5d8d0acd865564ca19c1458b3a213cb0491502b742084ac6ea6b40bc836ff1c515f3918615f5d1aca7d71f9f5651f1c8ba0468843b65444333b75c28651b76876badabdd9e96af7667bce6f6f368675dbf2f64f7ffc3362f6cf23fea587adb2df9e8b8fd97bfa5ceea8171b5326fe8699cf7be5fb189fa0ac9f47323898f016af330d8918ea72ae5b29e71355e7d904351b65955d65459aabb4aad2b56384753deaf9561d1fbb0877ffa4b5529c65be5663fb166a7394124f61dfeaf459c47f807d23b143128109f35501406eee4723a604799e66febd856281ddf9d9b4d78f4649f9334e620f4562c0def1bacee1f13be8e47997553b983b545a30f0eb9253ef84b812e63974cc6467053bf65c430073b537d7fd96dcba2979efd3b2ea104c138f93ed0e2c3c3a094703c12d4d213d755ab9583ee73bad8721e3a1a54d6077ecbead00ec87b548f18d4aa0cc90cf07bbb1c0a6fa262dae34872813515add38351cd095231d3194238b04530fd4d7e13fb5219724405ca2be6679c2a78f680c138f68399567eb9d4004b2304288832a5f89fafb6d3037277ceeb814c351c64df6da627fa6c8658b9fdacc2ca892c78f821f05030a33fb6ce2a81565c30a92a60a1793fa050388019112802c01b97db081332dc83dc1e2986c6e3d3b062b35a6bf78b0ac856b136484c400361d64887c7ef72ec1e9e270f1566d390dfd70795157aa657bc1d409f0f8b269442209cbd0516aca9a861f8cd409fc18e358040607d611016d4b54ae5bb64aff1f7126845050840575a0e4fed1271c14bf33b40eca9d31b61c1cac43029517b228b855b0f974025c7540fba007242c21da1bd43e96b57b62ab3f01d0d906d8a5cebdc4ee9e55b92ca6bd6047dea71108009e2cfd7b517e3b26396c49b73dd3c637ecfbe4c9ad6c320192d14e38492c0ad1df2acdbef3f2f4c99b970f9f03b063934dec3dcfeae01355e9abac6e74a5a766c7a9abc921707ef0b1c65b9eb357a86379493c3a2be40d70c08bbabfdd75b128013e5e62d11dc5eeabf7b7dc57413fa1eea99f74a1abb4d12a555654cd0a6d272f142188bc2b2c999505f9b9a3184b7f2fdd0148f45ca6324ec36cc46f6843a5801abbf59a5758d4a27fff1b61b9df9d7fc1bddba54fb5a0dea04db163ea6a46b4d7566b135f398d3e5fa2e4f77e78a84ef1104fd5d97f14d9449ffd87052c24742f68818358b9d1ea26cb73c8b8013e3b8b45552eaa2c6d74be56453ac764428787448e90cacffe43a5f9555965cd6c3e506fb556b3a659d4e3c3c3ba49279fca6b5d5de6e5cd6052ce0fffb5d435f4e0f02fdf0dbfffcb5f468786d0016cb2078ecac165591dc0095b1fdc64cdec8050c80e680ca00da60f53dda4198257110f5e3c7bf9feedeb878f9ebdfc491dab913e1861f232d04f347a41b9d15a1c1dd897aef4b200b829f7d1e7cf7483a75bd4cbe51cd27ed45172169ccaddfbbdbe215298f40e5eeb1025e8ca2c2a3dc96ab46ab44bbab7ae7c8515bb39232aacb046f692d5e44195d832cd26fae572deebc1970740bd8f894d3d4f0e817f664334ff75f430914ca20c8d1759417fa42b0083c24f8f9c1cfaa35e97c5540ce9655ea600508836399c80b5bad0005a58aabcacb5670fd1a9979319a6abb9019975af51d392d21d373355e889aeebb45acb256fa79a39b92d1b7e108d41d984ef53a067893e4fd9916ff5cb15001f1b2e9edb8ddafca760130b2173749623b30f1de890cd317b999765d583013e948844845f45a41e88e1e139119e59543e029d991aae02ba237ea95713ada7b5f8de9c12ee030757bf69b2f896dc73936afb94218ec010b0751872d70d783fe858ca960aa5fe718aa8c477d9e637727927a885488a5ed2602cca9bde68c891a8de13b6e2ebdc74c3ce158b42286caf9edd81528c353451207898c90873d6a7dbb6688e0ba86853e33c438ec2a1f133ca3ebb47dd376b18ff12b31157aafd323adffc981eb94f3c507674fa8a2f0acb198b048e58fa76c4b31a8e73ca3fbe46af1a73f5bcd600ad6fa6cf946eefe6eccaf076c3674d302fae75b55613d82c9a12d2edddcccadc1e6809a712bd23f985eea7419acfcbbaf9c5d0e909f6246cc28f86c32197fd3d77bdeef9cba66ad3d5a66a398fb7569b927653b8f0b4b7a09e2d7c6077edbeafe4c88f5d9ba7308f6d8a95241c9ab00b4ffeb54cf3da6f140997c2ddd37e77b75afb66f8696441c6f7daf093e84a20eaf4b06311054b817d93aebabec14b0044d24467dd891d070508eed846f0583327ec4723f6a0839a3f5285971aa3cf1ae57ab2af3efad5d98f34d233656353cd4c3db1e73be6e6b7ca3b9630c41cf75fa401096576b317779b90ba92fec8440390560673e45cfb0439e8d510c1f9da0f91f3fdaba8765234021594e6ee251409f6ee8679bc20ebb911b24856fbddfc04baf280b775fa976505ab276b101cf62a2b54daa86102b95386780348f34aa7d3b5bad0e43b82c722c809339f0f0052049a5375065682ac985002d31bc8d602fbb4fb46dde8ac9a0ec4015869482f7293164dad522c81a55d05e9ca7014f6fd495aa8795a2ce11bf224f0d287c80ecd607883b4d0900f0edc6dfc0654675798988f5bc94818ef2eece7f399b7df41718ff36b7f86d82090ba12d3002cd47261866278c62df62894b79034782d0f642d0f36d4425e67d3f2a688549515b2aa405b092b53372f9cb1d4da4adb2a3cf7b65e5e5de9bad1d31761b12349d4d958ad897527a26131a1e9ed6e629009afd521bbf43daf77e85080b767091f1f838e2bf4c4082ae564c3b18e7d28d2486614cddea2b43984a79bdb61a6c0706c76e2cf06a22e2fe1aa9b3fb2524e760b7f6466167c12e50fb729c7f84373dd740267a8b429fda2411a2570746571d2d3156ca0e68a715136b301fbe26da97490dd19b54594f78b157d461627437668b3ab6261b3fbcdd2c542435a3c1e314019bab28224e50444e5a2b476949a8cb9e01e1399ab0fac29b8956f0d59d176b0f220e820308cb85f5524ddb09bbef4e981fc62d360b0e5d46a233ed8df0f76e13b5b4e01db9e8383a8aa9d695bcd710dfe29b739a777033d67ba283f45b90aca1d40a7dbc1cf231f881db1750b026f091bd2e3e55e1a9e43e53f106a061a0cfede0f7e2b07abaf81c5e63896f6445225d1c916b0fb681433a98a621bba06db252f9bb81a3a6de48c8bdc2a2ebbb041078f591607af5fbd7d76faece727ef9fbd7cfaece5b3d37f4664c2c716c337cd1f61feebb1625959bece53e437098b4fc1e20e6851373647bc99175e13819a66d4a6b94c7a9810d2e950c00469667879e928db4850b321a50330cf17e50d66e503a4f9b4115927b87e5a65945ba756f365dd18d9f4dba1a3fc8b56695e972a8739432d061a61ab9b528d469408ff2abbd646f0046df668a8ea7f2dd34ad7aa2c4493afaa74311bc8c82ccaca3f4bafb5c7f7bdefd58672393aa08cf6fc6f4dd774d5bb1f4c51478facea64e828ab572e00a635fdc78e84cff195156321f0c8ec5f7c73716f9c2a89bdf7ba2a5bca6e08e36e63abfbfa325be9e95bfa20696f7fe465f96583d788d77b9385a4832f89e21e232e9b757bc9c984890f1b044e012533cc4e6b415f2ea669a3e108b76a2ab3236222246751a19cb27821bad13849f46a91823ac465593f3c945623e607edce58cf4ee7ccd10f3dd15899ac6065da121fb9a984d918ed73113c3fd7039b91ce673bb16f30239d488e12c9c1cdbf67f2adf83ed03fd1aeb725b9e9c6fdcf4e9287f54b320ff889435e648c8512e89195b4167f06601cd502c49a2abc957ea35b55d3da3fa4c75f94c9e64584c7de4debb7f95db53cbccc45b40374d3b985f54c830eb0bd7d9e462bb47a276ad417413cd8c5836355ca284ec8df173cfde246563a52c10fe62da58ba97da58b69971b156b72604b6ff948835775e8250df154b04b36b827135b6c06f1316a96900336a56d85380669656b74153e7ef2f4e1df9f9fbe7ff1ec255dd9c5d387ff00e59f29cd2cc9cdabea51a5d346bf6dd2c9a71e1865eb44c17ff51431f19915f9935eab63f5ce32847ce0bdc6c7ee67a9aaf522055b199002832cfc75ecafefee0662ae2cd6c66eb67aa8dbc80bae2c5660df1c875e40d012ac48be23b77b740f19abbdbd84351d3e30bfcf071fcbace8ed0df6ec4c46c1d8f0e2dd27bd3eef80bd1425fca45e94f558bd3b77e75fa1afcc6f7e727d11ba4e46c76a3cdd10c1bbc7694351a23434358e0c9afad9f89068874b964b77b41920fb049fe56b04e3db655278833324f280978345e9ab2bf4957b5ee82bf79c42e5c13d8ea53fa220fc6b86e9182209b763e9ad4f0e7698a704450fbb739e11145dacd0030d94e5682df4cfcc05d2c676d0f783190424b12d2bc03d73b783450910c610344958c6566d56e82b7c457fb442ac4a3c7ff3b4c9aef56b2358706f504779341cb6b52cae3fd6bfca7526d02d52e5fbc7ca7dd2713a5385be64cb0e24e7280a3e2fb2e245bab2d3343a3dff3f3af4d8843043b07d98787e3b8b2bbe0bf205db878967bb0ffd8999416cef9955e4f78ca5d9744fdc9476c56eebd1bc245c1da15d41f2d28c858af56440790d7b521ddbc4d83606971e7e49a09967ab6ce75dcbf894a5111009d5717837dedd99684ee55e3ef9e961ab9c9b95ac371d4a51be0ceef8e284641ec31671e95a6c5739c0c859c319c84ecd9816bead73dbbe2837d60ecec9c76e7ebcf347333a44bb82823732279a3b0de7f1a370831e58ec5273ddf159d0657f7dd2e964e68e42b788e0016c3b75e813ed4e457c6dce46731f98a40dffca1c8d7d7efbe9d0e5cb7b1c56d0971fc695dcf292187cf8a5df9ee2dc99f26956648db6e62feb0f9fbe744f4eaca277cce5cf703574904c572149b40bd377632ebcf22bf8a3723e2f0bd026a96cbe40bc148ce46f4a85d778aff84eec9f56e52f74bfc1ed3f34c286f1dd87221d6a971a49eab9c0f7649acd7561fdce76d2166ebaf33de5c840dbe02cb87fb155e55a1c8b6f8741123b8641b4113e24545fc79c996d650e7a218240d3e2efa334cff554a5978df67ea868a5b8586679e38216ce366a49dbfc44f5ff2cab374605fd8296f0ac50a98f022aabccceb001e4b66dca850fd1308db4e9dbd4dbd205098142d3c7bc9d35de3d5e2a5522d685af895113197f45527d4c84fb1511623cf0a7c9f2fa6c87489d8d137873a4c27e2baa8d287e45f0c26ecefe8267c295df861d743af3e337be0561037e43f484d34e71117697188af6aa67893abfb4bbbc31ac228c3bff7d230440251228495c94000ab4f118813f8d9cca234052bad810cf43ea90bcbc1a0d03d569331bc0e3a32de102e5550a1ee8d9e4ffe531037f1a7d5dd4007bf833e03084fc6f93c50358f89f329b21b0bd275ccffb7d97d593f4944f560be960dafa2a5df5bd3a4217d3b7d955915d669314949cfe28129f5825a36d16d6c409ad1689aa3d29a61a721c38e681e67a6b43b3e26589166777136c3715bf8d7dd56ab26daf3bb9c9df8eda672bf103c6abbbd726860b5e48ce1d9db2356ced87adbbabe9b82b85810ba656cc82de9e3ae945dd83cf1924fbb48c3830722ec0bbfdfd6038ad099c37fef8588db8da44f6ccfb26ecefeb95c79d0a1bffe0185a3f526325432ed8ddc20f0b73b5dc3242ea1ef3df568701f12fea6696e55af5907fb4783e7fc607a66bf4e8ee5d31157e08568d5882795a836561c7f56ea56c37ffd8885852db7c3de5b1707f93ee1c8513447aac75d364c5557d767b95badfdbcfb85efdf0509dbe7afcaa77fd4d7fec2364333014636bae3d3fd8765b94c54b7d958ad7369c8f3af7339395880f916b12c93f77ef92b849f30a7f8c05ad88b32c3bb1fe28c0953f5a49b423f28fe3fcb3c7a044d27508e26343517f132a8f94a458472cee8476ca23ab49229c78717f75b1256f7ca6addf55c5e4e8d9936333d95df56bb7505a71bea0c6483cf941b51215f3f7412afc4d1988c5558869ba36e43796b7a7bb775b93e6ee5d4f871b8b3a9d1743d55a90bff8acb9a874fa893dd9e8d726cc609f3fab982ecc89bff56b5dbd25d38d489ef85f63185a5643c653663b74f7ef3fd68288ff7a92c33b9b13fbea44b26facf6f6fa497caef8a76df3e26f9ea1c1d4737620371936992dfdd044be90590c830c016d1d6e5b7f20be8e406473e30fd32267c15c9373dcca1eb2b54791fe9031a1db1cc4e65a565ca779364d145a7ad033968e6d5b312883ae8ab29253e8379b9598a56ebbe9cefe6be55c0a36133eae6832f47f337b64bb60c4d4d7222db62cfa33508fcb314a02c550fdb4ac4e39da9f9cbaf4d66a33c2900517a18122734c1f6ee91fb5be4a57adaf9c323cfa55b7221e5bd02e1dd7be63cd716c49bf1b84c68aff1a5bf7efb73ffd27ef1aff8db701f1a03d895d55890a439aba66b26b4ca2da814dc11a765135b15687026977a3ac9264d336d7b531b581fc369bb498018ba94a77b15c313b55f025ef6567d5b693ae05f61b4fee37dbbb48cf30cbeaddcc5bbf3d1071b70007e9aa368abd4177b561db3c19bd5a0bbfe5606abbb1dcf2656c866f8b3261efef38f442ffbb3bc86bb346943ad0f7303fb1d5b9f173c094d8e79f6f881c6b9b6e456d8119365c6b5b83db6ed16b6836eb75403f1e1c16061dc150f87ec49488516e1b76f9cf5ae6e75877dd426fb78a07518570a4c12611f840f3784e7b0e8c3612d88db1dbe782a7189b12b148a8af0b41d96d9bb08654c4516ceb7d5cc1b6f585c73c64c578fbaed197e10e5bf78aaf0844889b5db8fbf47faff00236bcf4277767f9cf8f2fc006ef1406f1b52109cec4fbb3bdd6329f00167e00856f19516028b5acf63f5134aacdedd09465de640b54989ffd97f435f84da6f39f9ddfdeffd366f3163c3e771cc23b0aad3dc88087d98dcf2c923e1884c9c6fb858a1f80eb890d7f2bca46fd6af66a149fed97d44cf7e9a9a820281c07ec7f6a8a9f5a666e74efe8b00e124828db1b3bed83d8b58d864deb25bf8bedf23745d37446cbb83095e1e6c5b92d34862a082e48acda36fb7b1d5722d7a4964d2e3c50217f0b86d36d4b298561bbe85a233c64bb318871c0316ec71f0ee816e352b68a209c561c8d9452d481a0699a0329a79146e756717b57243434226a161f59ab3fe8724612234a56392b797a3b9d18615f8d58203bb83521a628676774578afb5351b5bf330eaaefcc26b453e9efe5be092e49c75c523ff17f8ee5fa6ee1acdaae1107197bba6056ff3037a6fb2d37a6fbde8dc91b603b7c99ee77f9324db6fb3245138e06f93ba265e8fb4ad7657eadfff46dd4d793de1ec56df2df58099bd2e18dc1e4e5e58e1fcb32d769a10ed42f330d20e04da9d2229b83416792e680c9e8e07f2eab728e3f75d154702051614f989bff5dae26eb03901657b9861446cee6df6a994d993d567bd5d545da1b26f06f30eadbb03097f275ac46f4c8279a66315d61f6e9b11a0e866291d9844ade0321ab26cb3cadc6ea32cd6b1d8869dbfc170447dfceca1b950276fdb42a17080668fd8c9d6077d6d4b312f3fafc4825c52021fa08a69744c902f37e59a9049b642ba17ed3af479c8df7bffb2eb1ff3f1cfcf9bbfe1eaf01cdce54836b32e50a54e94579add55d75a1f3f28655ebc2f965bd94f1ed9f63757ff73a2c7bb2a9967ddb5cc93f7825b708c9a46fe0fe662f02b151cc2e7134941926822c453cf18ee9dbeaed6bff0d247a454485a057f6f01fabd19053796a1d260e1ca43f5d2d226df1dd77670526466dc9cd3ccbaa0b163b0a834e8d74632725ba81834536703cecc2a110d74a62934b6516a6e7a47685bb2b431cb8a574b4ef4109c269a9ee515c32f49c6a1eb6423ae73aad9715de960ccddea45925cabbc4539e02ea828443ecc84b6ba57e3b1a371c6b212f8b2b5d37909b0faab249fd6c454ef5311b8b54b6ea1e6b15d777c8f055aaf5660c84a9773e576c1f830da8125385a0f9a5c51fe79184de483dd8db13b528eb04a678e2a040198ba0102a6933b0aab00769ebde2a65ef31c4b01ea81e2ca04375df734417537cbbcfde0a56785d1dd6f8836cc083ddab87be85156f65bb2741dfb2261b8a82c7d6bbf96f3039dc6a36abff326b54aaaa749aa5b98546c723e5266b66c1a6209d8b2fb3e697ac99bdf65b1e063362b7296c066736e8b6b2da82fb99fbd2b2869300015c2b4a7a9197e0733d4f9b59adae4a53a22c200d32d1335bbd11d1ec96bea8ca8b5ccfcdd7a6d4d8e18c9b4283abac992d2f0065bc288a6cf2e9f0fbbf7e3f99fc75f2dd7797df5e0c2ff4c55f2ef55f91b46db04e27286d584ad37c6056fb45b95ad6ba9a9445a3217ff5fc7079f8cdb7df0f47df7cffcd615396f3e564564f325d4cf4e02abb1454df96f912a88aa7bf6895d6f5726e3dbfa7d9b2761d2bf3f5154214cfd2fc9243e7103673719dd62a6df09a4f14d346e97432238dc78d91b3f4e4131c3a338d49c3cb6b5de5e90200d25953700c1a352d758de03b4d69d1c9704ae350a50d12979f3f84b09dcbac985a012f4f2bb3fb504bccb748e586c14a2b73041ab6717d67a5e7e5b51d6e2720d6b374e158d4941ec610276856dca4d5b4561704181434cf30fa5a5729f9d843825ad324cc363bcdea262d26bab6096e788c97acd8d09ea430f56dee958b7265996f765c5c3694214434e21557cd1a4a89454b327c636230f5c902f223ba26742dfd64d9bbc2c15c5465532d19ae7959e00430624f82bcc44f52266de36e3a4bf36b42fd84e199fab133fc5931e298e15876e7d42c6940069d1bc986397001c72eb3a6d1532b85e16c4d545ae3c4307f64c8ca0bda699c8066c1fc4da35c2662cfef79593788efacf4e56566165ca3e66951e84ab4ef56cb77add360ed5aeff4dd936a0f7cca6ab7215aad01a964eda48a2ef5817a827993dc7aa700bade3c2b96b55fc130187d55b2927c7c8c60e7bc95fd5a033739d4ccec934ff300a0dc2c80d5f3c3377cc8b3da63580d0da9ba29172aabeba5ae71c4f86cad2dc32e975533d3758387b837c8e46335a493aa1a53f43e17101afffec2be9f89e4cf36d3f8295e4bbe1c85553e341b0c0b01a7f86ec33394f4a0a5af5942f1c2c6e4b37cc78b569e630b35e086d5506b85c760e2a072e99326736db848670754c3a86affbdf46f118d76a4af74f39abfe86594691ad27f66c595b925ab7df59d0b06212e80fe2610441d0f12db7b2e9512f3fda466ee3471d6a00f9aad5198b9a653f5af655a99d3c25c8d7300060750e0a9beaab45643dc4ecc5c2b2fa98c5742c119f2c6082b45cd79018a0e18ff5ec6f5cf240db2d5db948fa122922f89565ffd4ff5cdf73c69e7cc4de04eb994b17fb0f2f36c700339af477f19f2965cdf8ede9ad19b25eaafc344ddfff3502a21a98964f2fa21587a037e4d0b5f1996f0af8fc282b896a020e753a817e6cdd0c5543d081b517537a2628df0704bad26543b34e17a33279aee46802a7d174e34b76846941317dd8db8608dd8c0898bee26d876e082a875f3464f9713f4f5696d0b49d0b424d841fbadab99b9bbdba4f44fcb0a171a34257a151bca8b985909c14d48a4b58fdca5629f40ec4fe442b40752dc5eabd12e313d6c6c6635254e9ee0f76ea67e58238e0f2d41b5cf4a39f0313a55587047fcaa6e2af437f5886fa32910f16d94b81a22c3bef9e25d76eebb61b69db5370eadd5fe316bb2981fc252dea21a25d902fc49a71f97b53c779e9615ecfba4cea1bd8c1fb9582e3a4ffe1a4c14b3c3f963cf0dc3c1b1eaf9cd10aee2f179f3c050f0247f507feda2e7c9c57b6a564bc7bd16439c9a953fe51b9f1b692310973f25b98a8b1dac475c0d26156508d0d5a540f3f52f1b5d3da6fb0c3f20edb3a755397f046bcf19b1bda2cd3a3ba813e5b18dac30e6608976178b6587ede165265f9d5e7b97878dc297796946ebc7b4d6666aab63b537cfa6d35cef1d31cc2858955b052f4099561984d31da9ece080e78079b26aaad4c2c9964bbc80419a6352d3f304406805371f1cc3ba3ec600bdc8c01daafb3c2bab9c083bc9757250f7a95e2bdbd9e6ff6fad17a46729545e960bef0c344fd70e9117a3c61755b9d05593e9da2957c2a699810085bf3536b74d4ec100c320c22710feb64daf0a252d5bec8ef4b65983c016698770fdfac30441d69ec61e79b4f83a4e40fa62e7cdb153664e2213c3053a8ac32c2692c7be8ec8f32cfadaf4b1d2a0e7e9b5cf7cb305be817beaf3acd016dfcd5ab8cc7827748fa53c9c3b6c8fd61a6618ca080decf3a3afbd4c41c07256e86d1356d64a5395f2a48efa821418047725e53e88928bdd3bcda9d5bbe31872f7aebae33b0d6103777c87ecaf5ff0e62f04232e11c9ad157f3655f949db65e548baf7bcabeeef23db42a0a09be710275cfbaa83e79219de4c6a1afeee9cafa99cbe703e221d5fd2fbcf9fd570300cbb08384eafd36646fd84961227f98efeb84a6ffc9c4bab49ad2e7473a3c971d22b2e906c5a4d48585ee1116917dadafeb4f3dd7adbbe7ea6ee05d248507bdd54291c03a6e3b59a9445a12790add0eb696f75cf1fda5670aececb6b7d5af65a57d2e04ee9cf0b71668e362b206ea382904df343be6be3f875063e86e4616ca8fd94660fba373174877b55fd5f5d953df0aeeb0ebd4703ab2d75a2d0196fec2d793ec21ecd25cf774263ac8df0452060bb394b3b2b3da9a297c5a42c602241f0ab25a62ef4655959e9a42a3134e4cc3a5bddd0a246ff2abfac11f5cc0a95f856dc17e65cd3d629777a77338ecb3c776b47bafb31e8b1fbcc5f6c1d2bcba0c3c0cdc737a61f7cce555d32642ffe3d781491f6d4b6d91aee7f231ec206cc839dc2fbaf5d9ad7ad109241f065c4e5964560d2a30e77dedd83fd44188245f1dc39b2d07d19b49d0a0e1032c135ba4a6f7e4e7df2ff483c68b7b39efd56469105e17a61581eba26b7805fcf9ae0983d8b87dcc5a2ed12d50ab38b45d8252e079e25dd06a58c8035f6ac175dd7b452276ac8730132fffe9e0da7e99a69f65b1e11f5df067eb10564089edf7ca739ecd811a1a0dd136507be3a758157b2f3e3e5168906ece0bd6e39f7ccc505826d5d42c69ea78b5ebb9d1621c81c3cfc4e651d86b83332abc4bd4f545a5d2dcdfcf191302d7722b346a90aba5de3afb1dadb3be24be3770250dcb73efe6c37f9ad410d97b7c3f88ca2ea38f57219737ce2ec0d9da0a0fed045c3b33b163da31b3c92e10b236cd2ff45c35f7c90831155c8a85939cd335870ddb9aa0a7d63cb9817a8014629f0ac333041a8b2851f1ab817bc2e6b38acde9060be45b1bd8dffd83c57e1737d69cef496f184c216eaace885f6927e37b5372472b903a0650f3970f289e1f8866aaa0dd5a0d076d0b27310b5495987d49a0dd47ec42c91c7eaa0abd917ea406d10d9784f22755fb0788f28f385041f29e23ccee3ccdef4f91baf0f697d8f5cdcf4b5e95cfc5bc7b34d9f632171b47788b37679f2709bd8ec37e310e3e17e7422f6a5c3db5710372c6ad1a66e0171267904fb4aa49949b495ada720c577b3d26d4db242be71e8cbe645790dc24b820e40fe67532efc0f4c906a7f6fdd3be6e9ea8dbf54e16de74056808b830db3fc9c663c6f21c681747e81b394b57a4b79373337ddb10e829e475bbdf1b6d7ebd9deec3bb6e094c0f6e56cdd76de027bd4bf7ddf704ea3c157a2e9a130e095c11ba309edddcd1ff6a1e2f8c5326fb2459e4123bff97ea80ed54675a43bcd2928190bdbdf9f3fcb240560777e480a6a2b36b187226f0878ef8bd80970cb29ea46a753230b57e4b5613de954ea3c2eaceb60cca902ec18a0babcd7eaf33e6b22f394e0c293b3dc1a390dffde074e8d15d989ef7195993a74ee166cbcba8d54bb477879b704a1da7169c86d9062cb85fd65fa32b4e91f1eaad3f4935659d1942a9d4c401f0d3e57deef7e1f58ba265f70cb620714ce4619a35f9e42be74dc24e4ada2e732a14a208b20b996b0d4b5bbe1a910a3eec99ab91ce73fb291a6161e25f6118fbee3aabb8894dd1ac7edc800b3acb64b60deb2e4e0923d503d3b85981e28f4ad5e8dbdb0e1a89a1eb55b851b8855f65a02ebb197bb762240fb17317623af22f3997826a77518752cf5acf885432aef36edf2805cd6a41fd35a778ddef673ce65ed15b1b21e8903a3eb7937e66d65b16b22ee39668b4bd83d84a90a501be1de653c953aed3780c6c34bf834e8f0e70934da951876856ac702a3cd1afda9caa6b7520636c40b6bfbda8e99cacd20d633c0459385c75158d047c1b1922d1b160f831164b8f52a6ed5ea07748599ad9b2e19d8da46374e2f4bc82dd53b8bb46fbd9b6fb9a1b706bbe2724aa21d6d2a816ed2c2792441f0534c29e911076228582e667bbecd15a395a6522815ecbfc0323b6f99652d3fb310da2d00a10b1924478f691afc5ca21f68bb976e4accf078d66c332eba8f3698276db3ba8c90671143a40b6eedbd93bdf1a6c5a4cbe698a877e7e77dceafa8c572872a5ed1006c346e266a38189e4b75af55db586fb1a84e6e9b2fcbede65cd4fdc781a331642ca2bcf076c0c8bede73cb39e46368b4f56fc87ac98e6276aac68603ac89dc9018da10e5ecea45791c1a0ecfbab55b5de7c2ed72d07ee5c9b03935b74c6edfded484f1e20bf7a011b78e96c825fc95764d0e64db11fbb6f3c8101199e43d742bd7218fd491601c84634e6b57629e662e2711f33523b79f2a2dea3c45c4be0d33122650d99882ec7ac40931ff21e1f0ba8b57db6f388ffc69e47017ee6cc0636a59b8d822f99d8e2ed6309fda3b0c53174db2d6eb4da1a5c162e7ee63ad585de941c63f79a3274d8f1faf07ce52ad0e3a837eff21e09f0f884f076c5a51d4e8061aff1434b0d6ee30e37f987bb3f842d6b52540d97fd8b91b860c149e776d6f649a7dc3441dc81d9f192cdb9beceebbeb69d6e422797c51968b3f0acee39b169cc7370ece837b7b74e0797c73e4f13216959ea48d9e06901ceffd9b0088e3bb2d401c119890e9669810644fd1e82b5d29701e498b06d16c9ddae8c9dbef55bdd0930156f0e2d9cbf786a13f3d79e39d10ccc3b70f9f3e716f3e7f56077f1d0eff3cfaeb5fef7ff7ed9fbf1dfef5af236ae18b87ff881078f88f1681c8f74801c6f3e787cfdfdaa8b17996e759ad276531f5801a608516e81e35e21cd85f8d5ed463351a0e3d3447b33391e17028e97ccfa8ccb362d9e8ed54be1f6e24332b97d57622df009580ccfd6f3d9969bade4ee52fdf7f1b21f30d6bcd8dd69f5a7400ac24e8d3b77f895062ed99974533dbdea2fb83efefff45ff3518adfb9e0e692b7768d39f077ff9cbb72129d6a2b54e7761f460f4ddb77a842ce199d5fffef2d9a9998baf2e3eea4933f8a4d775cfcd51dc857cbeeed2b4b99726ea427a98a5ea405db4fcd2c00bfbef45f6afa5ee658d9e730c8c595acf641063b96c3c423f8b3f4994f9f688b9c1cb0813a0bc25c4c494b1457dd656102b4d43de9917e7fc96ec1e86f92eca6583e97eccdb96379fe748b96c6201462fb2a2e73ccae23e7a729feb798da80569973a52d2a1b66b4a57bfa9a674d5aa09af48026bc17aaca485cfd4f66f43002e2c5f5409b3ca2789cb8c38b528734a3eb7d093ec329ba80fe6930faaacdc3507a8f73e2ccafa435f78bb408c78add30a92292b5d3455a66beb260831de2ebb66a5ffb5d475a3a7040da8809eca30335dea90bbacbfec10be1f8dd5505d681b278ee1761c4a54817dcdb4b631021d7c8391c7cd4c57405baf9a4acfb3664d65f75168a76fd43e453df707ea65d9100041d6a89b72994fd5855673d319c3fe79f62b726e0a7940f3359047d88245a50fc8db674a211d89ba583631d7203c178bb25157cbb44a8b46eba94a1bc2569d6b0b4e00e49b524d20473ec6ab97e5a7e54235e945ae2943a8f9533d7cfecbc37fbe35276f9366050ba46e6e4a5c6ae09a8560aee96a6048f394802ccb9f6941dda4f3450d92a4fb011bce148ff3bcbcd18678e9f2910a6278c3f902faeb2abb5812fecfb34bb5874e457b09a70c31fd175ad58b4aa753c204c9d7046fd02016254e136c3e42ca82c9e922adb3499ae7eb04d907dc00828e176591af391ffe0d2b77f805a8fd1b16d7e80b76c0b4b0d66612c75b6857841faf3a9d6ba7a747e6809f354cbf817a862a75203e496b9d506b3c69986e90b5c78f3f72c0cc583351bc4c9940a8b28357407c02a07d6186032b48f39cd33714901ee790644e383338e60ae02e3f8769776a3eed79da1e1f271143cd42efc40c3097433b0120c2c093a233233447b8543eb08f8db1be45598fd5f04b12be4b57f46e445a473c5bbef88879ecbb3cd8cc9c308fe6591139ee1695be4ed4645955892af4aae93efa5a7de93aff0c31515e1e82f0fa81229047f8f5830ac0e0e1948593cfbc8f9d7cac08f3aafcca13db74dc9fd86a5f8d6c830d7bd89b03ff867ac94f79780e8821666d4fa7140ec15640cdf1e5ec1af0acc1da4412a5cf9f15b62e7cca321df6a0c43e8c2519f4ef1c1f036b39f8326ca9c0319a5038ea30a33275a87ac0b10335ea7fd9206b001977321faaff556badd269ba707ba78509b9b9b919a4c5f2e355fa699656800f727f38faf670f8cde1707478911569b53ec0c3f5202b0e3ea6d7693da9b245c357279e073da835519ff45adaf5c07c525ad45114f6ccf86367995ad7be9d67d34465667ad88c9794e8312f3125e0ddbb86e00fc76ae6e7c73c9b22e2a8394bb3be7af0c0a55ac886b6b677a694992030661ef5381bf112e752cf980d65d26cc4207709b1cb6503687bb8ae7b2477200a31c884674229a9fe9d9798f42251b36cacb2d117e998087aac1126a8fa2130909e35c048d38b7dd73dfedd10bf7bd0fa0e384ebdef7084e4ed33dc0f5ac7a6d95626a0c495a79c0582fc08c91b36b4e0ba9edba397c986b828b1d2ba5c5613ad3e40e51f14226af9530537d30ff527bdfee012da1428c754cc9f3aadeb7292a566497c687ce1817a5a564aafd2f92207577cd7063bc1f7cccadc4bd4b7f713b5b728ebbd7e8bb6b31698cd2ef5dbacd2ff5aa6b91159bebd3f30073d67a011292fcc665127aedd0d9046b5e6bb6162666e59a977b00524aa3887931564698b9be41b9c9545eb2065ddf9d3c876a886255b5fa779a20c27d8baad08b5582e71ff0143fa3172ebb8251f760b85f769a47aece0ef9ff9f4b8d700950f803d79a94e68790ecfd5d83e9e65ee71b097dc37a5ecb76e5fa123a44d74b413d191273acb8efc815e2f5248d5a257cdbb1a96df01b41f7f1c7956369959bc50fc44f50cfb4449732cc0cb31db299d2a1a0e90770da7dfe057f790f49138027c01b5ef11a9e5a5b0294fedc4b481ae59b1587268083c345cb4d7e03d3df0ed73de5e120dca4c7957086c251573f3c207ee3d628baa635bf0f36757125fb992360206da79c41032d70b5d5eba8a8c8c67bbb9c7cc53f831966200d76c5f7b65e402286036d4aca9e18ac497709a9b0bc2dad67ca7338f6dab5e6aa4edad69245e52f6ec167c62198e1cb2c132f8853b48c6b152a2231eacbb9598c7bafd5f53165dde790a8a80f45f664daaac30d7c9b4c9cc4aa67643c2b0527d402e7e50b3d45cb6b59972e57536d5530bc8652e864b331c73f0b8ac1b737f59d67887f46a61f501097fa031879dcc10cf8aab81e3328decddbb312e760f3596eae1b4e6f29fab7402376c8bba5fce75836a841c1a9a167cec133327ea32b113a4e16aa3add3c0b7aa73f8a2d29c1d29b978f1dbc8b2dde40588e5c2b9e00421764bd9695dbb89ddde485cb02c0b2ba1da8fe40c6d25130aba2d26b533139873b235dafb7293426fd257977619c98f8fb670da8a234f21c5019ed037e696b02cb24655ba067308ae9374b1a8ca4565a409169f952e9bf2c026c59962b8567820bb4091bf1759f3b4ac1e2e0d33279f6a732c9a67fc7e3b4917e9246bf8014d372850da86d00019892f70b05f3a97467e07c3ef40be787569abecfb3b18ba5b08cd295154c7de72f10ec8bccbceedc5ebd2ba7bdad2035053ab93f0c1981b5084d8ed0aa206dbac7c1f9dd6238fd10cd2c2f7a8ba7b8c7af6ab59793f1c873c6313cc36ba7be55109e2c3f96e33a329dd4ea9ccd1ed02f56eb266b66df89f22ca76565cd985542ce7a768006f4d083e0d12a83c3ebc2dcf99ce5167ee34d097e390496664fcb09b32e76c8082e537cd2e2f7b9869ceb4d894ee9bea6d97e2c9686c3f360d0935599d7474c58850e7dd50cb2fd28f65650af6b04dff3e0b017524592cb56f44eed87aebb231085eb92542fcda793e8a29f713ed26b54a5d406879a93ed859fe816bddac169b09d88982cdcf419402d10ff3ac28ab0f387dfd758a6e5ba008018de007da403f909e72be28ab262d9a3102f098a3b39c02baa9d543c028bbbb21ea5043fd69d6ecd5ae2995ae1765516717599e356b8ffa9b430a85493905e4c4496e0431ba236597a0a706b9432e2ebbf5daa5b47123fd5a49d7bd372cf21e4bedc312984c3a37f05700767ffebce1087045379d05ae02b3a312d6a5b3b1f7de391af675225bf0d63d1e9d7b5a375a7f9aa66bd01940b38d98651eee01dc137d9fd5e52f54900c955ea407fd077cce3884f9ab98e6d37208254673f3a65a96d05d1b5eedd23a4dd1a264ca1097ad64402df6d073d480fd5018801789daa3c6ef25b6b3e155009d987c3aa95a95b83bc16eb185bc65e089da9ba6eb3d0c4a27ef2d24ffbad2d7ba68d44555de18d116f4729795d6bf023c71019a7414a0edd423f395020f01f3a0bc54cc5ba0b6bce8d880b105ea01d8fb8743301be1e0b3946d557903ab745fedc14addc35024fc5d99e557aa4bb35e1669d52022ae9b78e5251477bfcd37f0bda9987317f65ad8538e91c147b8c3809299fe66bc4da7d31eda10fd24c6cef88683451234a7a664eb368424111f9fdf2f51e182f31b68eced44926f705d26506f2b347cd4c594eee1355968a657bab6f0ce46620053297c9098d25f80d80d20948335c7e98a5255e91c1336a31151e44401846fb3b5d6a11913b7edd39946cd3702aacdd3ea0a6d3084ebdd208c36a08adbdc35d3f2065f9755769515694e7b20107c45bd32b3239d9ab3e5664658431fb0c7ee6a97d5603c6fedd464b4244a56cdd438b987f63c69bebe6649ccbcc204f31d0ee54694802ef2a87d8f20f58ab956b22c79ad4d24aa36b37a404c87373cb7da40262a89d47b000a1ac984365207b408e27a595baeb7432b46ae159628c7a9219314e86577ea54983af0d67dc4d1b0cc8f740e0bf4a049075fd1a4fbae49ad8e0609242875845f6063f33ff6623456237393405eefab91da376ffbed7c1db56e407cc4139a240b3b53d385f91f122e6f235c741e2776720d1c6e8aa5eebea5e1ec18b181bf4763c0d24787fec66f0bf0dcefc6f8f3071a3a65df8a1d99488d78a3d8351113f9cfd3c53b78cd6f10949952c68cf0ac92035b2173b5f10859b1cdd72b35cdd3a75539772a09374a2830c64728229bccd34580aa8eb23f92895cb61da72338e7edeb81555a20392ff71b8ec1b373b346dd9d989d46529f34460a2ca3efc79227def278214ef4f845c3cd1451650ca3b1f7b55ea4465eced7de5f12735601b0e6859ea4cbda4be33445415fa7af75b506325445562bbd5ae8a286538ace0397ef0492210440366c64d1cae93095efb0013ba1b68e6fb3103994997477fdd63a5db2746b1807bed7f2d87d9c36a9f426f1be2150fd980a1e3807833140afc0c9487e25e96452562c53578632303a29603a0e7381ba4eab35c214203df20789d0dbc50384e88019d8678a71496220d6e6637df808626e3ed6878b659e1f7efbddf0cfee43c054bd3ff833267e237f65ce8bb1f7aa69a1a480580282565aad011bb0d1576bd5bb582fd2bad6532369ccb3e2d08866c00c7bcebbfe7f30ddfe3046c87c48dbe0f870b9ccf3b5ba46f4ae24b872a2e7cabcbcd6534f0b8a0862f851841ad4c28935d5b200adf557b2f4bbef37b314c5d1b1b934343edd1f6ebaf558fd1b1d4ed035c0423c8366dc3a8aaac343fc4b1d1fab542d20655ba1d0ce206dfff372ae8be6630d0d9e9693faf07f1c92defd10cb1fa022eb50811573b2ac9b72ae2c9a11a5854128a61a4c2516de08d21f2aa4efb549f1262e9b720e6eec6505497a2ac36ab856982b54a2c0bf36516bf01dd2cd64404a62c3284eb1280b9ddc9208050ea1d28d137bfce4f59b278f1e9e3e794c8796bbe8f252be26731d45d1c1dcf90e149f1531365fe9e6a0d6cd6156970774533ca4dd1f6ffa63b5c72e763663a3682f4c8733e7f52b53281ab6befd942d98ff305a3e7055c214441d9c4fd28e56043a8fc6aed881da33d4f6c64e9f52abb3ff0057c4343ffb8f10850c2f21109b01a993d87a1e709a30c1394da4033314965d2f2b26f912b64a8c0064effedd7c5e7d5e3b6fd2bea08ca5bb68c3851a555b1f5878a1731578f5f2f93f3db9afdb32a32bdcadf1b3063d18c6c4583738747233d9d808c05379969f85feda18ad41576696a899a3716645d664690e8edf1d79dae7babac2ccfd128dae23f9b3a7d8958f1d33f8df12078c346c1d2181731d28d78c7420dc9441601308d84ef29e7bb11bacf537c82cbbb90ede9be63a62eeb1792a2c87766f78f6eae5dbb1391ccca249d55cd7757aa5d1b1ac2c4865bad0954246d00a6671323db8d8e0f891a72799bbe9ce43bff6ec4fdce9dde56b1b2db837efd93f910a3988ef4ec35cbbf7ec9f8c46bada135cf9319d7cba49aba9b2066350e08ead1b76563455395d4e20f91db236511fe47ef641dda4b52308c8ed3e5767936685ba97e6f93d50c1d101a5166956d5e4e29c81e8b4d7a80b6d15a053470e44d0bc4c5db62f72dcb6e38c2eaa653ad5e42f6e3ad307efde5c377bb55a940bc828e528ceb31a54e53848a81c6423ed4db0b0b29e5d82126920bb9c38533051e9b533c147971fd63448178b7c0da1f00e59b02bdeec619e9737356e9f4d893cbad4952e267aaaaeb354ed357b2a6d50a0e35169c2863b6ec3950a7b877da8eede55f6ef41035e08ce33925b3e6cf163565a2a2b36714134cdef43899270a87f3cd86d7497d97d67235b9b88b7b0d601501fb3b284ba2aada6028d84c5b405bb27d985dc2d17df5874c7f0796e2132c5d32c511fad63f247f85f84b1654e12f8e1c3e9544f836a38eae67b8b5b59f702846ee91cecbfdb9a36869002e0928cfe117312e27d0aaf160444a4ca18ba3081ba6f6dc30668e14ce209c3523c56319ccd0cc1358f78e4eee1a17a0e3bd1a42ccc7da4a22c95798e8b9a122cd25d10f79381ff3c740bc1f02ec0227e373cef07e01dac253ce39bfd073cfb883cfbe887c931e7a3fa019e1be67c6c410b7b5f2af2c572c3f4ee6300fac10a33553cfc0e0bb226bffb78ce9ddb45c12ffe47a88b6c779c26549d6713060ee0197a874df5ee6ed6d2337f529a2b240612d7612f18c130d22c6cbdfdb3dd8dd8e8f16f04fc8980d7609d08e09d419ac0b2ef387e4700ef0c0203156b01779c47f157ba0330021ec2ea7ca046ea444412fa32fd415d564d0fa312fb6accb9cedf1c6dea238b89d8d64f56b4d589787fb1423fe983084044e876085358a72ccda2f8b034039e82f067b41b3a6d5b519a9b4d36b51a9604547f39a6e573b736f45cf17735de5a0bbacd439d4fda9aeac7462029ca9b5edfba7a8c5b5db118dc3cec9a91d2c5344a685f8d10999bf7d4a7f0847dd090ce6a50744c9a7c8d316115baf0991ef42afdaf6556a1b629f45226d74a07342e670483827170e27e2280ad7494b480c35fbf79f6f3c3d327eebbf741e00f3de413dc433ba54dca676fc25f98953d76a776220fbfb140bb96b06c1045758a7a82ddc59e1d91cf76bdc37158171f4b1a082a5d7e141151463231a8aa25bd58af0987ed0182c1237ada63f88370b5c6480306ac814fb8542362cb5c8bf963293ca1e424ce26b713dafa8e8f493f02f75bfe14140646b86ec7b4918ab8dfb57bb21dcaca16327884d7433a941d68e53e875bfb28121f39779c79dc17277636749be9d166db7d72e0b4159b79b0976fddbdc3061d1eaa27c565699844fb27a818c9c719f5d7d4e0ffa4ddfe0d629d46fdac0e9d8f55a79cbb73b8a094d9625183c151ae1e1cdbe841ffec87e32086b0e563110876a1b8e2f667c634bb21079c11bbefe1e106474b55e93cd3ce01224caf5097ea46ab6959ec35e0bc9e35a04b7084ada6152c5ea8b0739632f7e15a37ea5351dea09b28ba331569deaa8c427cfdf14037c396cf980714b2f55b9e9ddcce9f8cd44456d5e316a32537dee4a23ab706179a3eccb5aca3068e8efdde19e8d431836a82a703cb4ac85862f96056ff1a02774fbc3a21d252efdf69bfe5d5da73b815542c8f124acfd2115dcce859af9ee3d08dc555b6c195e5484ac29d705502aaaed7da2bb9493c307ecf59f59ce9bf4b12892ea1619b4284eebe02e82f2e03cc23b107321107d3e29bfd069d0b7e5011ecc013fe905c0d78620d1ed3b063e28ba32ef065ba5fb762406cab5b297cda61207e4f8549d19465de640b5c7f6df761a949ecf1980c330510428cad50492e522fc6d9f85c243658a95d359489aaed6edb28a91e05e53bf3bd6b29359ffa50361f9e646640769d4d21d2329b7c52f3b4fa74d689ba85985fe65b4b8dcd7df43ab4d0c304442707e06b97c01649d9aa9503b5a0649014d3eddeece29eea7776ff3b1792bbdf76c58e10966953b325cf0339dbb91ff945b1bbc06f7d7d7cbb00c4d83780bcf3ec7ff184886c04e16483b1a3697162ff18537d27a28a31e71fbf0214001773ea7b61bf96e715e81aec03e7edca4712a70273ccb66b48d6e0930575bc37d2e6a3b04cd3f97513fb0e5f9eb74c0dbea527fe6f81b7488bc0dcedfda2df31df137df9ef60e0621a669666bc4370f542c76eea60b071b6973af9d765cebf2eb33dec3a62d97d672750bf2bddbcce5670b0a25c10ec2edbada24ebc60c2067bbf28eb963327933cbcf7a4590dc27b53e29453231f230452af47350dac4be4a2acfbea9e6dce00dd265b42842513cd5fe026d1ad6409b2ebda2845774079e8690fba616ec68c76a7e189684624bef6712f37b596eab21dc0e8c8fbbb5ceb7097245a51ba1d83833388b9a307e0bdaca859851b51eead7ec402eae31521981bde53938b56c2c9f4c475dac2f6878d657e9d044be140e97de8a9ef014c9da7650574581700d0ea775a2e04ec8a73ddd6656b380c26b93a700f74316dcfcceeb567561ba0b7d875d8e5499098bb623de3b1c840dc837cc939e162ecde232e576f939414831ab5f2fe5be9138202d9f615896e222df93cd4e44d3e4125bff8a4ac3b20db5e77242ea75ce586c159fdb7b2ca7e2d8b26cd7bce29948ee3d51b4a0a4b87726d4f65fb9c9fef93b276c58f7d0a0d91e31c5481fe735baece8a76398b204b8158218069cf37e8924a6dc77d86089df0ac761bc5cd182f8e8cd3f778b7fa6a1f0bb866dde3bdf1c9b0663142bc648410afe72ca272f693f051b59c6a0c945e6573646479e9152228c4613c0b02065ce88da7aa6f66e7fce5f944c48c77d3ee56e7b8d015b34a092ce67497d37ca79bad14f2b9fea72dfedbcd64914d3e915da3b8d27563e5dd1e0f10eb83b3f6d552d70d8d4128a69a9bafa8e39dd03d01705270496315b03e10539efbeb6e44fa629c0348e52efdc53b56f03cd463b81b9958aebfeac0cd00c69db7aa1fb70bc8fccdad9d86e57436950c6e305d00a515a38733a9d761234d98d12c8704d57c70d02170baa6614e17f7734c404e5ffe2870e86f5be0d0df3a7068b88bc641a1bf3d129e89ceae35491b7d5556eb31792cdadfb0ffa0eff858e414c717e5555a65cd6c9e4ddc5bff088a70a0ea712455397399f68de71e944f5fbd79f1f0d4e12f5ba5c358edbd78f1423d4ed43ffff9cf7f266a369ecfc775add02f5bc234efd1cbc1dbb76f6d81f09dff10f194e1b97d88e8c87bb3877b1ee518abdf6378c57b79bec75187a18469dd9ec410de7bf77fceff8f3a60af1014780f1ed8be47fc1f07d6a7d9aa7fd07b3980595127c8a9f799e91e16d923c7e91ffffe13f8d0ba30187455ee4c394ccc171b31c8cdedcb43a078614a2a8f246295541d48316d1596d5f7612f82aada46b23b845a9215186be15814c379e134fb51fd18428e65f5cf699e4d617fc12728375cf6cc45bb25235f5a7f75a9a50ad86385456c03c8875633c27bf7c505194c5b14d379b92c1a6b85df40379d4e7ba2b0ef80a8649a5d5eb25a426c88680df374d5a748667a9015d6334010274784562f30943c8c0fb73740d68d233fafbcbdc18689b7af66b007fac80017811ef43d1c72f8cc3a4d6c62167843447bb3712cd0896213e1c08939147e5e138e13c80a1751bf5e8afbb6183fe2c6d6ebbb782306f284cef0d7baaa8de0777ff0171bf6a2fe57534e7dd6c6c695f966c3ed052f3d5d9a9408575cffbfa8b1f5102fa4dcfdde5c56f750fade4b282a2c5f5e65850fabb8ccf25c7317fd45552ed22b684b532d431ffdbe3b62e6e9c2dc63d811934a55101adf85f8684328f11564a0e0120b79a3d2dbd02375ae9973a1b9ea628d2f7493f644822cb079a08322084c4d0a90af1d1e8ce197849e7aac7a96c6ddbb40c4ea5206ef27b32c9f56bae8a30725d7db52cc3051b10a0591f893c6f28eb3e098dd5071ad80f9365159242764a67eb075dcbd4b95bccbce07efaf337dd30f20400357198a56db3c422ea6cd0d837dc27a6986d0153c717f0e567c6bc7a2eb8ea26b56346a6c7a5855e9ba67cb47d27c6e62972b64bfe756fd2f1d52a924d8ae90515f8dd5ca29c9d4090e04747fc512bbacc7a6fb6129d3f375d26a8c137caddc8b9b88618b5926ef86e7b879ff8fbdbec0ff999453fd34cbf31e5368437e5316093c2fa77063d1f9e03dfeed33d762a8760e171af3ca2f4ab8dba5d595e628035834aa82242a77ee201db3cd5e414c9b4f3df3254208e3e63e7f56ee490c3acd43b1c468988d2afc620f811df6f847d81dabc67c9a974672c8f23c51a3a1077173687758bcef80baf00a659f42c5f43793dfc4681decd99eb947fbc205c9360877c67dc6f09656958a1edbc29f3f5369489ee97f3d38161320cac4889ddd574cafea9bac99ccb04344ebf0501e9a7809aab58b301ecb2100990047008b35e5222ca38b292ff1abaecab0081f491b4703a0f9b4bc335d7b025478ec9f602bd80353a5acc24dfac3439515e85d0ab30b43e8e080c35375dc3d2d65d43e794ee085ed47da87e496cbd726edb65d4b14637b44317c145dc9e1f9ea9732b33a206cb55305b045ee16000cfd366cc50da152cba2c97275fd0dea82012db3d018004583e80f070a56047c394b17fcbe801b180d0f49e3e12f4a809e1653fcfd7f7555f69d97525dceb5d2ab4657459a2b12791032992671d154a5117cea169467d6a89e1e5c0da0f2b773231582e8003260b8f1d0dcf222b86532ee81bca9124afd84444d5c376adcfe0059ecaf69be4e337d37d608d9e4a3d535e542d6755a2ec28ad85b48db1b3738c5ea35c5436a4ea2865cc5c2dee148b4cbf4da684758b8651b63cfc5b9e1bf19442c6af466dd1dc6d5da1583ed38028e4a8701872877abcbf5526adf8e36ca18ecf313db51025a1752862847d224168fc93c018a0c2de7e8e6f528ab26cb7cd3f6d5b52fb90d661bc69c9398f1f5c66cfcbbee700cf1c463e3246a421920b3044531b6e3dd89e7c908b73a8b5b144de1ee161964b1b67f935b2782026df90e12b53a1a7828627a72b646e2d9b787097615675408d562dd0ab83301b000e071e45e264431d86bec243ad9d6882c69533b2114018026623e9872cdbba4b35c6361b9e5d2670f26341fd91243a17a62ae24c8abc1ea2878b7f6efd6c13b6b9473ade1c9eafbea40b13cf552f5413b0806e6c185c14d94d6e6115d5bb75f53feaca759bb7938c2c9bc654db79abf518069f58adc804ea1cf54aa763712a754e0ddb4a10854983b256c59e9e666de403859f851ebc27227acba2df3d1e2a68c1c50ed1d7731b97bd7d6e6b05351203693fc6024ce9b3b1d8253bb4a7698f85390d8600a89f46dc12563b338cfce3dd25fecd60cdb4998d0d0fc2371ad239a21d382a604331d745a2f4051d49ee69b76f2f50232e992c6652f7601852ab76dd89b46c5566225d0bd48bf48c9f5ce943def9cfb59fdb84a6fc0e19aeb0e6cde02d868efde557770cfa93f658b36906f95de3cac74da9b342b488c74ad87f4df5162f6ef21fcef4802244f4cd975a2aae028438c29565ea406f6723bf88b43c43f80b5a5954eb14ed52bca6a9ee6b061b3d4ded8b077c3f3816ba5f9b10e8e9d913b7686f2d0f152d3242daed3da660167bda67c47fee7794b1644b6988a71ff8e0b717826b8a2137b2ee079e09fdb33a1725e10ffaa9a1efcb5286f58652b75001cbfdf57fb2af27e6ddeafcd7bb7762c43cc5038b46a732a1f1c707d95e1705a4d7a6e3cedd0bfcba88ffe0142e0d143507cc474f2c1407f2cb3c2e594b929d948d77684ed486035b6c17ea0f9b335037d7573a85c00e29816d3c8bafd8be9b1911bdba788e14ac00fce89d64d7c5a82820c08a0ca34a1859da8eb4cdf246a82d9caf3d225af46479a2548484297eb254bcc9162080cccdf3fa50b2fd5e2dc95a22836583e83b5cab13d8135fc81cf104a27e930518b51a2a6c3444d47d8e65736198a1dcb20457f3c451974af13e99b34f599fa9f5490a4c6a16388758003ddb37d3d428044b3e19b9652a3413b4d45a68602df315d10fa7414bc19499f0380ec834459b6cbc12df7ee5d35e5f88bbca0ca587ea9b386f340ed075c0ccfd329b80a4e390a280d1c8e3349812c9a9e8611879c5e8f22b6572063bac4b76adac7cda492e80abb9e1147fe1b6aa79856b4e70453943d1d0521f6ad687c644a000fd0c50b11e20f5f8e625fb6d824befcd2bebfde8a1db4302679596bbf305ad9d2274e556ddff404d422aa92dea3d1cc9abec065001f397cbbcb46576469aaff1ec246c12537c4fe957bce0e781dfe2327e2f27c44f6192b471266e89d3ed74d0ab7629d27ca8703cb138c6e92b46948aff48d96393f9ce435e57be4deb8ab803009e16cd1b959205e2f0a3fb8b382ce35c0040dcc4d45cc2c4756cc36128bc79d16c1be48ce6f0676dc32b458238b280a0489ae78a1f3b1d2399bd6477c5e332e0efee4a69688cbb67d21d77f7e658be2be6c18acf6b54b06bcde09ac82d0b1b268b2820177b06633f9dd4783b4ae81fc0a18f469c06c8e1d77e3f00b3c614cf9c80d43a8baacf11330bbec8234274cb81c033747871f8493e4fd956ede82cd8166099be2dec31c1670b3725f4d9a55d73243b9239446dcf62387d336a79df6a42549d252b45f18f991a654b0acee404980a235f3ae7d57dc3cea7e2dbb3039b3b2f40d9919994c40ba969ade58e3b9b09d0346f08242cb9a9406d8bd04be58612b302c1a3a9bdc8d1f099e92f7225676f72e72dcdbd2db41f711817492670b76f0e0509bff350ff9e9b5b3e069f802c2e7d1866a9705af381a522e6114af74f3a6c9ff0674fe3412aee755930ff0f54317c507b16165b9088a9a47f43670fd96deecf2e5d16ede28b9be02d8726237b9e18adcfe0cc6b82917163734cdb32bf308f57af6e9e532b7fed38c02dd4118706873d6dc8077eb18124724cce9380dd060217e1d93766099b27894cb40146de40cd38f678d9e0b9f39eff1e20b0c7824ce112f3bc96cec0a777d91ce2f59b7e70b953e3c546fb56626aed6096776598f634b07cf2c9b4e7561d79ffde59d17ee4cb210d10bc57f2a3a0ecf6e04e59e655395da002635180c54a52b5d4c297b3d74d4adf28c4000bd9b991b99b2f85b79ad2b61fd288be73abdd6fe193cb5a0316e182eca15cd896f87ee545ea453736935e39fb016fb644414c857cfca9bc2a6b4c04164c5c1c7114e365d3599ae555352accb98956af4aa5163fc0f64b98749ce0a7809748c5ab1f21276862560fb942b56b46eaaf29386c263fab1a1b41b9bec12d124b10790a614c1126b0436a682e639fbdcdcbc1fa50b35569374a16a68a13994ccf3a0d8e3b49e451ed1ed6b1cbcfaff9559d17a88f119eea9c55669055dcae3faac0df917119d8f64616f94c2b2566826f6789bbaff64596bd0b2db9b82fbc445e9cb2703f1c111079bb3faf540b290228539027bdead543769706942ebd6daf9b80dd88a3734cdab9e6cf5891aaa31d3941d4908bcb60dd2fc33d3d66333bd83aa68e96318ad2ceee6f2ff9fbd37616fe3461286ff0aecc99aa44591929c530ea3f195c4effafa6c6532fb8a1a0964836247cd6ea6d194acb5f4dfbf075505a0806e1eb23dc93bb3ebcc33620385bb502814ead8c7dec5c775048e88b72fee2c61c67d739da82421a76ba62813553e917368bc01d6a063086c5296005abbd6181cd31b0a198c0ec14dcab2be103de2e0901481469b9d0db36126e76e9d2dac4f89404bb26fb280f6bb1be203aa76a8acb8c4d8075589949c45672ecece322b57b4281256c14fbb7de1979343f1bd76d315def1f230666fa887b84fadedf74a563e4b219448528cc1996c0f6f0ccff0ced86e2db216e7de37a2228158ced46f8e75ffebdd5c7a4b6f93d8d3aa7a64ddd0b65be34c6addb28c23c43d6f6de3885a6bdd86b26b0017dda55b5b5c38453d317c8769dfb09c79f2c430deed651391a5ad0e935fb1b1502dc0bb6c52939ecb7c595dbd469ac0c6662e2c4d9a83432b3b6270a1651c6f6a553f0fd5fbea5591a886aa96bb69b296f266368b45a5ca9f0f5fbe70d266b255a26059c8700b1693da70e2148aea3dd9033a37851586146654daba2b04457159ca99f8804ee16f902929e69516dbccc2d09e6645c8a5b0f2e894e9465803cda0b849041b2f2c624f015b06fb6bc316c2729961c852c97a74c2ea31315b688ef87a5e81771132f80c9ec51c4078528234d46559de4dfce0fb7e6037087def33be2f281447317bfef2cdebb7878f5e1d527447d88814d605fc72cf17a32c1d6757426a816ef05fc05c7697d90c58078c7768260c65c022d6713d09a7b8ebfa65ceebc76091b6d2dcd2dfb6a8be19d8da42b987ec12f3c486a69fa695592da531a48d1c4f1d2fde4e73f71b0e15ef311231e8e7d4ac26131762ed3099c32a3264a094beabe3646af87595101d0a2e07fdbe7854822f31d387627136cd1715289289cb693a9e42006e29927402eebc2b72f17d35f76ec46ca997a6d080eb617a8b90c3a9d28a6278a237741827facbccd2891a5f8d33d513bf546635817d9faa5c4c8a2c2b2e6dc8ef47f99560ead6f8d0603d91a6f95495a08930ba02b7c5c4409aaeeac61ac6321723d44d8498a5d673a72fc7055656728cd77238c56b31086612b11dbc70fd0cb7daae0d81b71c99ec3a600be2859d0db12dde94c5488eb22b72f4762931fa89b94453bf6d4c924b3376dc4b6e800f3d1af131b403fc7c34d24539a2684dba52a67360400f825c57811d1afac2fb9519d463268e1673f137cfc62080033b17bcfda7e94ce59a7935b49d7da72a9fd7662ed1f4b20c90f4371773e1e7a3461e839736e6279c329b93a1815a11dbc08f3662bbabfdc7b4e2c527e127d4c641fafd30afb65cde43c32ccd0dc1f5dbac62253892e654adc3e3607e0274d661ce663e5c41c48127ea221f17b9ae4a09fb32b155d9200d78c259fe164b93f972a888c9d808704269a8a2953cd9cac6321b2f32891e16832a61fa2ebd4b88085b89a84eaae0096ea67aa5c55f15b88b881fdcbc31b6addd63fb2776ba2ae671a7482579e06dc0e37706df184a511c06d1f78b70a83ee33068cda7bfa5c1d573acf234b39f72ad133efa2d8fdffcbde7122f5a5ec63325b11fc5afb989917929a6d6709a6dc900a3473c7d739fc48e7d09dd289078814b24504dc08a13752084b5b24bcf7ef542394a571c590f85e0758099b0b9cde1cb4ed20cdc8eb3676fde2efb22502fb14843596803db472552b83c056e13191fdee86088cd4fddad24efd452e7928ec969184a8c124b16ba86103fa655800893b4ba65a8a0a59ef3387218b8d04531f3af61f3e9d32dab7f994287354146865e32e1ddd9a3929de113b4952af2ca2306bf324fbc6b1857514fd339116e58c78dfad2d3b41a1193b986f1248f80ef9c1b0c7e1cd1a59c917484a96bdb3b24e259a193e577e004a3819a0b92d502ab674e1f008a4b3a526dd7e440ecee887d47dc6ad43d6a7149b1860682b3a0d63904ab93eee7b9b9086b8c68a68197f5b372875a0f9e14fd64d427c77726ee9def38534973576bd0af409c636803be0c365926ce5bf9a45fed5d156e3a599a83709c986bc0b31e151397a59c8b22af0a315b64553acf14c06b1ed9d306079fc9fc0afc71a695b964175efa8d122612e85924e6dfdc473768b61695cc7e0ea68872cd8454ea7d8531da07a2651886d6c338fbb1d40a063610ad599a24996ab14ad805518ea7ed90cc75995321971a1bcea211b0e3bbd75de92329b9450c57c396683b02d147cdc99abf2cff346606c83c67b9aa01117cf4543fc347fe2777732eb6a8275b624fdc67670e7115e287109523d13a5fa4ad81a7705bf59a1ef2726bfad54ec9e18dd9d6bb9de34821eb868fd8b0b85551a2eb73249234249927b4b561ebf6c48fe077dbf17de4709b2277814b9cd3a49497a7be724b7431984a307483749c5fc2e998c749c4575dd684d696bfb273c68617ace8064b38706bb87cd66ff81b464481b6067cb739b898fcc2c3f61bc28bc18ab6503d2b5bcc72bedba394a3e30678ec4150c0271d351008bbfbd6746651962aaf9e140e7e67497e23c1f9b3698561fc7efde7d00b73ca4d80745732cbbae2ac30e41b03249ad98f29cb0fe80cb236615b7cef1b4ae210e587e8bc6ba22034a2416da1d6d1118e53a8f015d5d081d37e5eaa8bb458681a54c88df87a08d5e28a30390cd6b40aa3c2fc9feba77c9d82fda430884dd4b17a2b2ef44c94d5f548c23b5a5fa78048db458a51e25f80a0bae1de86a8d629e14af4e35a55ebd02c04dd1093422ed19261de36bf8735f2965e0eb084bf8c2f69d1e50b25afefa6b254897889126093c8b9c9151ebc4009c769d25a44c0502dc51c4c245780902f84581cfd685c2d64965d81ad0f97fad2bb0daa790d49b3f98fbb3aa246d653eff8ae499b8e5f35995e9da1fa41f19ad61d639209a65ec669f01aa89a94e36776dd09e4519b1cb0b5da98e3d6d843eb72463eb891dce137ec9a715d8ce1a6e2d26ae1e121c994f2da505759655d4122c22ebbda1273fa70f91d9eddc1ed7ac44a7a5c9c63c1ba4b56ed470bd08931e89f231ef08c8a663a9afdbe78027b4168552de6febec8af476e4e7d6a1baf4cb6f53537a6ca9b3db9c3aef715cb61da1762e0a7182fda450971d9ce55352d8bc5d954a8c9448d2b76b76556056159527f4b21026ca9c615696f6d7e2ffe38be6b9db885cf3f11777708b2dd5fca4b7ce27c5c185c7454ea7d575c2d5184c47bfc2bf9aa6d7b0d62473784ef0762a7415618bcc6fb4bbe15fd9bbd004a28f8b0ce2fca5a5ef0278c687b376e12cf543ab82ea75a5c4da713dccaf94aafaad7c17503121a566655eed677f1899c3775d06a40d5ab65fa78eb6b67ca4e0d8df8dc7a33a0dbb7be0103d654b5539baad7ec6e45f67700116ed755cd33c886a560380bd5aaea05cd4780a2e68af14c7c07dce3ee8e480a911795f36a03f426613a91d4475f597b93155836f791a60aebb23fee033d8a40c5221ec75b651f8994780f03ba828d65b63a946a7bcf3a6905ea126a5cb9771faac596c448dce4b7a29888497ab6289568a7b9ae944c4093a4980b43aa3be185b09449bad0fc36781f6f06effebfb7877bcc05833b37a091bf07a7c1fb37d9421b62e42a31d7c8c682ff2506e28adff1a8053eaaa78657f38a74423a1d5a7d351b15cca6a7a6afefa70f0c00d8f232c53c1ab4754ef277fbe3bf820265e4e6bdc926cf7616947396f6d212acb76a5cb5fdac99d5f8b1285f54259fba0e9074fbd57c9307a4739bf3ce2026e57c737eb6466f1ab0df34532a6dee78febd273832cdb80fd5fb6ad5a9d50535ed5f23a1201c9d329b3037f831d238b8f7f4fab90a25b782da3a41f9ab97c0a3106e72b848586c87130b44bad885aead29a66a0c1cb56f637af02e606cc064dccc5a3a2135f1109b225be3aa9966ef4579e44fa0a1a751058745bb369358c82fd4d20a10edda75bdbe002fc096c45c40dce9e8d0c3291474c5282bc6e74c8dcdfc675de401170fd5046ed023e7739cb7592101aaf9a863a5bc82c3b6ef902b695dd4192e13c948ad8276630d4d12a94e80d9b589ebf785bf4afbb9dce4096ef5cb0e5e0642310a680ea306c556bc5c6d76afebf2a7819de34ee8268bd41d1ac6cae04c054e3d8039ce8ae8edda5eae6a83f7a57934568f2bb8cb46235ad653bb42a1b597f5826e28c65308c18276053d389c00812b9ed509b6485aa999bb876ff01ef2a9b2659084dbfd2d06b79001bbe29b3c45b926420a8e96fbbae0bea4ac335bcab86244d5d327adb0ba76e31dde5f617ed14ab43daed4a081956a3b1c61f9246d667531beca691499e25e93c7f26e4ed846d9fc8118aa9ac92b3195174a8c9402fb94fcccf9b966fa3597523bb5221fac74c5968ec4ecefd9f35ce3d3dc8a8909380bbe1e626bc0b034965a1b10b35fb6b6821cbed2f64a7c2b1ac3aa3e6e6650bcaf07377e73aeb30df58358b1d0017d097bfb1e0b70296ed09f35cf0ccb662598d4c1c711aae669b909efe3a59259c4bbb7034bc640d4d006f058c6c09fb3bc0cdeeada35b29a540f07bf0c2ff53c0bf5e3aec2edfb634a2a161244ba38cd36dfb1654d1de65c4bc4962ddd3b6ec9377b11ad5d0cd6ec107bb2fbfe840707f1d4b73a376e11b1cb4dcd23ae2d65d8f2b562ef1456f171612e57d340440bf1ddec6e068af3fdc05347d8823f38d4864fcc478219aa99bc53b07d2fad3ac8623c056f47a85bc20c9fb86ad3b0caa6cb646c8825b187c669afc94923a1238adab229f96a08c82a8c1561c2f1f2b42dfb850864678012f92cb02457a8f189b3df17877632646ebd707008af39cc0e7fee6ea2d9bf4b3e6cf2e75643a89fc1261b9abea0866b68e60c609e3f333037082ab6c5e154d1efaa60d6dd8498980045b899f727bdc390b739d5c31f838168cd8a85568b794b1c88d6384bc7e72db14f005c64ebed28021c8fea3117aa56ec4208b627994e83073a4a00bbe97512d7f0f4f2cd6157973405b6f19bd7bce6f1a4df473b1c5a2b99954a2657601e52aa4c56e985f2efb4692eac327c687b6243663152d356bdf75da1bc23b3784e1b07c9ab4583dfe621f7fbe0495af572ec228f3aa2eb1ed4f13f5e1be8f182718fada3cbf1a07e9f8d6693bca7baa536bde59dbf33c059e175c6ecdaaa7cd75ba8bda9b771e9a63ddf642714617bcc37b08139a45ed6c94f5905a8fcd6ab300cec01233798af1431338ff2e45155996b11f98142ea080f67def95c66cdc872754936656debd8d0dc349d8719eb0c0129ce3eab8d72b85722e8a173885594ea249357c5a2d23db4225b942aec55d0bb87b5523201de2c284260d03f370afcd1e04acb4178575a640b5ba3f8cbbccce30565afb7dbfbaacbdfd553cd43c381491936da1533794ef26b713f30f513c5481799aa544f1c16425e14e0bf62542a284077227067afde83a4dfb44745a5167343ac8a09556cf26c8b68d866b806ab4f52aa6d6b7848fe2570ce7ed3629266ca861c9a56d55ceff7fb6769355d8c7ae362d607b8df74ff09c1f7e78b2cebef7dfde5ce0a668b0ee87dea6de018e9791ee8aa3758513b2458e2332120a335840634dc7c173ce4fba9db6410f7a95dada24dc6b175fd503c833c53e5997a3e61604b629fb2ad5113c5464e973e665312cf09a93defddc283adba1fdc7a619af883da508281602cac25a46208a24bb3e96aeb106301e8fac48c1955a91ad0a06169974d3d4d1ee3fdda912f31ee5b09548df69a1c256de2f6a84aab4cd5bd1e71ff4420aa426f0ead519125ab5d1cd5ddd934bb4d42671ead56e404696f676747d87ffdbe185db9289b67801da5304cb19dd4f6eecece4e875efae4a8b850c3464bf83fc6e0fad04ce60a7beb7f516bebcf6ac9dc6c51bcf7bf16c5ff6b51fcff8845f10a9be2bd8d6d8af7fed7a6f87f6d8aff256c8a9b71ba6e6aba57b72966e94bec539b2bf72ad27b9fdb3eb5c92ed34c193759def065d86aea3dc1d0bb866109741f5669e0fe132c15e187eb4fc0efd918954e06de11075e206e6d99f69dd3713b14d260c30aefaf56a935d575e01dc559a414fcb1ec3ed3585a31fa60ee0f383521bf844c8d60e54c4515b921edd76848b372fedea728e783d4a0d0d64966ac7cff30385d00902becbb848dd5f3814b4725894fd7d15fa2b9ddb8abd622fa725573736da0bbef7ac48ab65cf0c00f8f4b3e9577d96ac9b0327db117a1262b608f08b6d3d0d26deede17833bf9a4f26fb12c839f21231f228fdaf0475919f5d7b3b3b0a07fa7bfffe5663a56e25de6d316773a53a25fe57698a9d2df4ae9dbcd7da4f3dda06fb38ee9c0e18218009e80da6d9ca56d54be44c548d3b9599a60901a7ad00aecb570b20c42c39350c1a3240c2bc650f3ca97301dae47882981d50ce8ee8b03db59c2b27d576dd470d4ad769bd063db247442a54fd6490ee5a9be47501befeb3ec9999bfbb8bdd3fb4aec8b9dde5735cf12a1fab935432865ae33c3058728c861a013aa1dab7ad6ccc2c9e37194bdca2cdc2ad3d87937bf9924a47ea2c1611669e35c05e7243c5fc2a9ee9f30d9a9577fc40c14160d24c470d981e771bb3c9d400b618b1398750f1eb5eaa1ee9d7addc13a85eaa2ab24f72063786c4e829a780c563212de572492c8d5258a273613ddbbaa3e4d720fd5f08ead93db032417db576eb86683998f06c9bd1da417dc43ca27c8edb1c6db89ed51faf331527b2cf92f22b487cede4e66efd6bf2607b72bea69408cc4432e17de08f93f4966bf415739a4c5cc1859d70ea92eb8f75baef934f75b83aa7055438bb710ddfb420dd3e64e340060127c07b98900ff360bd5f8c6df34aed5727c56a459961fae4ea32cddc667a60ba355d50773c920e00e653ad17ef0844899962a7122f57098531b3d57b1abd1e6d49f2a6d8eadd26f1b2be0fe6b2e674acfe558213522a9b47b04602eb909f5387b8955d948ff86cb97d51814eeb5b25022cdab42c8f9bc2ce6650af6e794d3a7bfbdfb407940a913c5a78b3cad44a574a5ef503f0894647071d74e24c68070b6bff6fb611df6519ece2caf84b036a101d8e5bd53e5453a56b5324d2df0d8dc031ea9bb01969c853f7129ce7a39ce68289c2cb1786e0025dfc6d1234303a0b564865827f8b301eab9e1e0e4984f63ea931a0ad0f6b3c0f4d90038cfa4e1cd66b001f0672394dd7090439f0d80ef28122da4dbb8ce3110a4472bccd31a8a1ca6e373d73c04436e022a8aac4ae70e0c3feda6794b2c02c41facb6d31cc3e6ea157b0f75d1118ce9a043421714b488ecad1a61cff2263037875773055a4314969efef41c3241f4b08eedf48b4226182322eebcdb826da9854e134506c5ba83e4840a1b6ec695a175038ed5f2e3e7c267d0680c65b7a46c2af5ebcbfc0d06acb86a9f7b2e7f098eb8e1da2a8ece7d3cce9ba6c9b678d7f3cf6e447720624139b60b3ae69bd36a5f15137199e64971093a4a2d17abc0aa6261660fb5c29a2abaa1d97afaeccddb674f1e1d3e7ffdea1d27d96fcae2224dc87f7df32b63174c39e5854c333902ca7a352b4ad548f17b8eee8bbf266a5eaa31d068646d2f54090f077bbd6f7b3b0803a41e4f51212b07f180dc753b77cae618896776f9a0ff79c37bc19c89af18df6eefab4f1fdf8bf05cb747728fd1db7fde408177fa63c67918b028c45f7cc22817da0ec21276b209691e29021139fb63461c3459c7e09e3f816e397472c00d218ccb6246237c03d59d3d96868f925ae405d48814b5eb2c66743a9b675774c9ef3b9a6c27f12235174f99e6e2ffc80bf96e5ca6f34aa0277eddc351c3a93df1538b0d9b76d7ceeb579f8322f8f61a26f559a40a112967dc12b5ec198a12703b87bd66144320b4bdd06ba7e2ebcf311541930db311f6ff5366c23263aba700a136dd65dff41e7cfa14044d364c81671b3f07195d32ee1769ae2432471bed836f3fc3b911362906c8849d64903e925a7d0c61411a71a9849e168b2c2132212408f5fca93fba125a55950bae7d35574e32042200d13e7525da69d2151f0cccbe687d800bf2b6f9ba69dd9c767a9f878b6898a080ff355cd411f27cadc7d285ce6b3d5e8c4624bd339f4f29c0824b30b3ec3ede14992c1f954aba94b7326195bd1bcbaa5265cb7c1ee36bb365b7cf33a9f532b6f308728fb9093606599c9cd59ebfc89f5f509ea0978c1f843eedf1e40cfd6977b9100517059a074fd48faaf64ea757152f8a4b553e915ab53b628bf275968e557bd75961de740287038635465a4b1dd5e5183e6f3a0078b77b379d8118f20469b3c6c36b78f7af23395259bf5ce4553a53f686df577ad627c8e15dc32c53693c8c7e4dab69b1a8deb828742f8a42ab0daa5c559cb7036a7bafcc3ec74a3182116cfc96877aabe4b82280d2fc66791f0cf97c5c1495ae4a397f53aa49fa5edc1070af7f38553345db125e36989b31d32f8d526621e6108b17d424518064001fcbe4cc6c7ae8406f5294663fbf5513e78b5cb44f4a35e98a524d3a580f3c276aeac74098ec9efdee1a00f3ef4296a9844b3fe4d3a7cb9e63c05bc833bf5d869b2e9beb121c8849fe426a0b20b5cb7952cce645ae5cb3003518081069ef880381e195c4becdf5fda1895a8915341347c3bb76b8c3bb5d31bc4b83c30f331afce57a8e9f520fefe2ed8fe6706e67b0bebc6d379fa235322b047eb9048547a4c50a2347b9b177ddc6687fc0e1956ab26ffecf7cdd602c61dd1594e97ab9cf50b5ed679dbad9c525bb77cf767b4b0cef6edbc1dad58eb28777c596cdeb40eb1d77a507c4b3aff3b4e02d486cf9dc108bf9e7c3614eaf1156d7168a3cbcdb35cbe169c340bc8615ed49add333889beb31bb8240cb1df141044f72bbf82427cbb30579d6b321c32050182c9e0b04eda08ed2e387be9e7375654e32170e1a44c4d4957959548521999144014d66b048d7d4d03105b19347e7eaead8c59d86af87e206feb36e1701eea1b8095fe1966174bb18fd068d683b24ac0005c97c42d2dc30ee760ca60406a17b3d69a71d88a3dc112eda31c0dcd968a0d081b4c30bd358c1116831fa0da6b43ec0707c80aa4f64963d99aaf179dbc636ef8a27a087b8185745693b7fc765f318e81c10667c5a1697f8fc783557cfcab228dbc3bb4f646e5839d37521491b1bded76c5786773bb02461f7e68586608cac91b7309eb656d9a40bf5b9ee99a4b0076f1544711abb6e807aef54eabc55a1a7012b29d22a11db422fe6aa6c770208d3844aa87b367ea6c4dd6ce546f06d68e5f02e22ccf02e38eaace5b2d18a03ccd817a6dfb585a1eba56eebc5e88999ae2ef6ee09f1308289ad7c0688ae7833a6975176bec0396b5ea8770658a8f7f35269e0ec660b5d09955653558a91c298bc45c9560e9974a056b5fec0a4d911788cf68405c9709b7531e8b02fd2151fc4d863c13e6cbb6ca1f6859f20952f66aa9410611f0d1ae0590213c06441d8b7319f6690ae833b8f4f30f54f2bb3ebb10baf27e2a0397dc922f9bef54e4e60242727860a39105af50dd818b3f9cd32593ec81c43c0bf733e08a574c428d15b2fcb4ef5b3df17322380ac48a49ef62991819dababc757211024b59c24f5d5eba7cf4e9ebdfa9b18d8159f97c558117e31c9291e6990d553f945f4d9b3f5b88a61009c0f617c14ccce172e93d829bf4fc2b25d512b40cc83ab322cd0eed8333da68986667423685b19f22227405606abc8155612f7094939041df535426d640cf41a8d728399008364d75bec8123cc032a0ecbff9c525dd5acbb5f38a60de091adb150e69f0ff6fda8029b240b8b257bb5fcb834f1564b4b87f94b4aeb75c57553f922b7b976fa78e128175fd8f365a3be77af9ee80ec2fa2cd0f274d16e1c19cfe609c18ac3c4a0e2286b6dc5bab166bda26abda6ee781eefdd8b936e53abe8f79728e4607b37d11628d524447cac9ea13ec229f744eae5d84df5057bc2dc1c2c9d7a68397d38dc4f487d56207116d1d6677cd9d8a63d4d9397a4a4ed15b8e24c4f61687479a24a94cde08cdbfe6ed41ed93a2d69d01abed816815970fbbc57aaa494976c22212f51ba2a8b2bdea515bdf53366a7dbce361440d3ae5b0d0fa55d2ea73ec2468076aedee3adc68d07889ca56f8de40d270048369b1006405c0a650303e233bd8e0ce5530203f1efdc0442090cc4697d1044668da32d80537d2700fc660056c79ef259300ab7e86e727a76c88301b03d6cf1ed0da15ca87829514913ba01aca3ab8d12afafa91361aef798b5510b30d9610dee497ca30aee1017d3b646cabe2232b6fd88baeca2b2ca2869c3dac05857bd8703c22222a8e34e8a7266124da50c7d1f3676038ae9a94c8a4b5ba6ebaaddb02794e5eab4c8c886661fee6f49897e4db3ec977cb694f8b1fc88fe35509bb5cdd6668fb7599fda798d2a24b814b85fccc7c3180f8b09010d44cb56dd8ab8ad1c23fff2c32722895047dbc05962e975e76a707eb5fc1458f733bddfb448c0c1557625668b4a5668612b787478fb3408a180d13ae764a62a09e32c5589076cbf8fd6ad3379aeb430cc3e32aba22af034a60825d601bbcc13c00f9c0f5464d5ae2255a241dea51233352bd2ff56ae5bd0acb89ca699125ae5d01f2926f21c9a72c39a14258e282df21ed5ab95da4881759415a33e5adbf67539ee8f8b52c1ff311daede6ffa2f2fbedefd6afbc5d7bbdf58aab814b56810167734c7ac382f3c57efb083154248c68bdc4417929534c1d7e88942031d30a4df492b6fba5069d7b76ea3ccef07c80237ec20a137937326b1d68ab3589e2de22d91fb7504b8e9d000e3ceca0bf50491897864dd462eb0724f48dc899941599817b87ba2d93edc686d5c3cfa4cb520e2012e20f3a6edb49e8299bb9ded5640ba78868bd41f5091543f551762e0efc170ed9d9745b2407a61a6b89ed97ae8ab58e8343f7bb2d05531fb4f75651f200276c5ae0fcf377545433a531558603ed2ffa9ae580b36b6201ba35b703210fc010d041d26e3b8eeddab97bd774fdc69ee72441a9145fb5596390b8d1ea2636f5294cfe478ca508eb202b4c3909098819163826c1136c54e3d474b239cc42a7da9a0ba7191eb22533d0562b0d611c85fb689ee6cef1d0b5302dc5c3ce3be1572a5122da458e4e9ef0b25ced5554f3c761e2cd0b46078179d34de05ba68a8b128f2d04543aac542aba4271e65952ad1e15376d51557c5023ca3ce71b28514c3bb75ac18de2553054312aaa9ac6837441d6bb11ddb70e22cdd2967aa8a7631df2ef55c4f1d7948a3f0f275ef5e432a29ae03deaf87f0f4cc8611dee48a512749c105a3896205b70ad3a73dee7ac2f333bebef0db0650b6758c6bed037cd34452a9a844d3068a2fc57baefd23fa5e4653da098483b497e09b0d593176bfe333185cfb6a33f7209e39b243b516079ef60526a98da766ed506e3a34fdf91ce051c79fcc1ece32f7d1ad384440dfd948370910f325bcf22f2fd6b583edc43c41bf2fdea47377166a60caf0b4b37bc665a95c8e323046a2925ac959a6b44616188c06f5a7e01bbfb8b0a3a369c7b949e28766d462282c8d329fe7897aafcc351884cc71d9eeea03d157ddef8b5fc1485a683951d99528d53c93e390c3906529afba10a3a2304ca936ec6ba92a496a339e6bb64c33541c91eb5e30f0b5e46910cc65c46ce560bc1f1ca196ff1e2c992adcd00f966f68a8f3383af76cad3ed6a477076a0ae0d7bd7bf811f1b1300b8f95288bd14283039dbc4094106f55a62e645e013b5fc02b11d2003153e6ce90ea19bcf4a5b9b0a7295e35b775552a394bf3b35ed0cca1bd45c062e1f3d3480995a414011196b5271e696fff2693448b2cd595ca55097b27ad58ad76c0d0633d07151a374c62863a8c7bf079754a0bd6ca5d314f93881de18d1ccdd3e49816de2770fe84b325442089b8b93281445be0dcbe59a36901c3ea8aa396a9a075cc07d5ef0b204f16bd53a57be25551a563c3575c2a799e1b128271289f4f84df07681669d8f524a80ed8746c30ad98996285de6b4657d155f24241b078399f2b59ea70d57f2dca7359160bf49d5815e686810f7c806df4e8e824b6060f60a2b8ecbef9aa427de8b209648c50742b7755e468a81cb24b21214b9650c740cca8ab55ab8517365c2d53b4751c5da196f347d1d56f3574177ab2b2ee857795b4c1e9cfc4c1fcf40fa4c47569ecde32716c2c50dd6b90a846e2d2bdbabc3490d9eec542db5822bb17a87e8bb5a29db5fc47a7499644bd6e781775c2b86892b99e4e2f74bac8a57da163496e3b286ab2f8f8e1c32b859ae13289016a22061367868c02846ed4f4be8817892674df9b07895b70945c20c8912a1414d6252f1167b746f86218ad4525a42128810f758d57270842a1de9bb324b4b3067d5de78c85947089ff2ab02cb880b3420ca9753146b3c9cbb49a7279c699aabc04a3e7aa39341032cb8a4b1d750cbc1d2ec8f25be678cce2e987a50cdf33358435efbaeac011e07b399b67aa0be54425472395885f9e8b4b43e6d9d8ce4c33a88b9120af53a5330070d555728460187948813599afc190f88526e1a49633ec7ea7b7561ed4485049cb020e00e2ec13c64daea78fbda42ef65845fe68396e47ffeaa4af89ea3d5846f5a2f79d07eb1e781ef46cd07b9b9f262c334dd86d6985ae630bed105a5dbe5526fbf69d6fe2eab7cec5a26e4501f86d4ff645ea89313913a74a035d8646a240dd0de7fbe130bf69e30822c58b5522b0e0c9d83269563c8882a487d604bcbebea464434abf48fc9cee4dafc8d5eb09185e1eb144c0d52e0333ed1f777aa97e4b3e43615e6aaa02fb51110b15befbaf81d2abc0ec0afaac7c311ba91232f1c0088687233199d1337f63edee1c68acc11d063e1738fad793760cdfe9e21aa1632b9f3b2a0ad46dc673c9bff4981520455cf307556ddd9b93f90ccf09320df206dd4750fac8163e3eaebfa399431295e25acff30b99a509513a60334e5b624b4495882dd13a85389c590ae4d1c0b41034e81c007a791c8ae160a0b4b71ad7ab7ed38b5705d17a053f61f1da2e3d8dd9790126b7be70967b27bee4b5ccf792ac481266a7e1716df7ab1d3e94073b3bc1ea5a47c30c7d3edc2c1ddfaa8d6e37714d97b946451c8421cad6ba64a576d95e4dbdcc16ab2b71edd534cb2cec3a9d320be739477b81b9ad22d95e4fcee7d915e53aadea4e87ebb1d8e66e7f8e996abf8a6577abd4e9635dbcda552554a3a71388756202e6028def50d0991a4f6bc00d5b8d660f91f61b5de3ba219feb11d89e498d87929db6e5c711c3ae37a95a89580f6a88f52655f5f57c50c3a937a95a874e6f52f5e998f460134c7a93aa8f43a26ffe0424da5b8a45df3462d19e45a3bd4df1689eaad528f426551b61cf0b74a3b61c7dbeaca18f29525fc52f6bf863e0d6219081f9740cfa72130c324d7d1c0a7df727a0d083a528f45d230a3db028f4605314cad27c0d0e9919db08891ecb72250e7d55c3a1c7b2ac2fe35735147a2ccb7518f458969f8e405f6d82408f65f971f8b3bbfb2720d0974b116877b71183beb418f4e5a6183492e56a047a2ccb8df0c7bbf45c87495fd73029285b5fd9af6b38151458875d01f0a7e3d9d79be059d0e647625cedd9f30fc0b8af9663dc83468cfbca62dc579b62dc944fcd6adc0b6671232c04a3ee95d8f74d0dfba04c7d9dbfa9611d00aec33600fa742cfb66132c83b63e12bbfe0cc6fcebe5d8d5cc9a7f6db1ebeb4db1ab04abfe955805b3b6195b5e646bb0e9db3a636ecad4d7f3db3a6b6e00d732e706e8d3b1e9db8dd873d3d64762d39fc1a17fb31c9b9a59f46f2c367db3318beebc46ac66d40dd8665c16f8ac588952dfd5192d28545fd5efeabc1640ae65b700ead3b1eabb8d382e68ec23d1eacfe0dabf5d8e56cd6cfbb716adbedd98e942cf25abf92e80d908a9c877c94aacdadda9a11515abafebee4e0db108761d6611d8a7a3d6eece26b845cd7d1c72edfd191cfd774b916baf99a3ffce22d7779b2297769e6c566017cddc46e8c5dc8ea2449cf91d25b00f64447cf3f0dfd8554c17bdc23c2972f04d7fb3c4e6fa12557e2997be58fe8f4a25f0286c9dc9d8040e539433db8e03f3699fe8a8c6d65416d93fc10b8dd5a73099814e80c6503290617eb357409bccde0237704a93eabfc1038b2d8c9f2cdbbec038004a60aa0732cd29d200fac5b1095dbf8f65f23acfae2c84fdfe2cae71d27cbea83ebb6f1c33ebf8cb4c33fe4a934607393467f683e687bcead8b9c04f3bf0259e754ed8d618b07dd26678dbf1ab8be8f71cd6c603f75c3ad5ccb06db5c79e4951ceb6a9343d918156a419aeb2241e1dcbd2a8c213210414b6a01888f689ff6da8bdfd3c727d43b73c7eb68ec9b2c0c3120d6e0a4e3e4933d56aeccbdeaaceec45bdd98bba63aa6deac95ed09586561fac6af541d4ea03d76abda507518fc0d587414870a963f6bf070d4ef5265f0fe4a1c41bcb0cef8a034b6adb0c9bd05189b8be1677d2a42b5aa72eef54a45aa4677951aa4414b938fd9ed1c11f4ed15ce83445383d57e37492aaa4d7ea887ddab11fe50eaae6fca9a62d655d45b94fdc67fb222235a82c6186e6c6d4652bb5ca9f14cd73d791cc7bf760bf6fbbedee89a5cd4a2d2d88bd48b1698b7d49b1ac5604e98ebd813b01ebfea45801c649c019f78c7ca12eb47aab26f5d3d73a4b7c024ba28514a76fd5c42cab6118502734d5a4654c1a51cec1aacaf5a2b41e116785ae44a9c62a478789aeacc92c72452c256968f5c44f2a572504e22af2cc477c054daa27456eb5596745a2c442cb33743189ba54f3525da4c5428bcba2044fd8a7965f3d05139e911249aac7b24c5482c10cc548998e82e18fa9082a036d2e83b672029aaf720c7e556890e0dd01b5694a5fe6af7359ca198dee70aa68bee0db8505f0161a8646cf666955296012008cb105e8750117873261bbb895636c05b3f499f4bcde3a944242d01547f0751cb8602bd5c4facb8ef026ea5d8c3be69a02b8b78c678bca3bf6294a6fd531964f1068d4d8b6da93bc697a82499ce4c1f8584f9b67cbce428fa9e5b34fba320153e06f4c6e464b3581f9bc217f6d23a9d57372ee33b068db6ef5fa272ca715f9e055a53969cdf64a949a930570aa21d46675a9542eaacb02971234101355a97296e670ec555375252439b436ed5dc8ccf4dbe1e4fdfbaf8a4aeddf278cc6f8c1a01b539495b6ade567a8e50f17c3d2ec92c564a24add15a3a2c89444ddd2fb02ec09c8c8b92bc046cf7fcea4a1c9a828a3bbe21475074f3d40a9ced47b4555a151094638333fae66a32233ede70990f2847ad4ab5504c18fc9503ab10e58aba94a4b515c92172cba92ab843ba30a34ee7f2474d0d0e2d3d72fa1a6bc4854d8007877adca745c99f995e41ab6a77ae27430189cb2ddaf2b59a563fc3d5366165e4fc409e5811bd79ddeae75df3a96953a2bca2bf142820191a31e1feedf300ae234efa93bbd181455500d28fe5a52c01a227ea0f5bc116f29e5d4f018a7844b16cdcc04786cea226b730a2a43a7542369b4bae18305192c90e168444bb6f6c52e5c926d26f4af9607f9273de7ec8194f800ba83a5fb7d31f801782157c0b6341820240724dfa0406fdda6b7f5c3006df5814e22dba22194a590b3225964aa87e44a43244c804677ae203602248eb63e26b62ca77ea6aab7f2f2509e45602edd41e2180f8b77b04722f030d3d314bb5bfe5251d6a928953674b5b43ef874cfc54d379c1d76a5754453fa6a9165c72dea82d3948f807eb1e9c72dd7f0631b930251b0a9397d35b33dc60a69c20ee847af62b9fb815f204f300dae9bb512a9c13f439131184d3111a767aa3a9467a7c046148bcaa002107f7472305a9c9d5d09955fa46591a34f4c76767bffd26bb6e2ef0b555ec5fb0a0999df5666339db2e1e0b6e11869c6f013f43738facd5d069bf22e0283d3ca6632bf49e2205ca97dbbb0f612e00ab7a325b8772f5e943427a56fea15f91438f0884b1998be1fa1a9e7549af78c1f356e1bc7644e9559a674224ea106b83360d5db597aae7ae291671b59ba2991562d0d54ffd40cfb14ea33447d0ad6d8a76801e2f6413161de216f45bebfeced7c34f936c3bb052d6e9e848d08b1a1a5b8822fd273453eff9ba968047ab4db157b5df1e078e31227bdbc28e69d46eadb040ff8bc01ad6645f8de0876c01dba98debb679d1fba6dd3c2396bada0dcbe85cfe88d7b95e3c83562d1880966dcaa2b184ec20a21e39c4b1857deaf877793f4c25c56c3db752c74e7c608cd37e3792fbe1b438f2389395d78fd741797b92a9f166360acdd1d21485d754300c05f211c10faf8f1d783a4188b41583f730364cd108a31386129c65602ffb7545da2332d5329b1f62b9b0f6b0f96086cd8eedd83bfbd70a8d7d7a6d50599b5d9fb43f9cb7c0e3c52bf7df468fbff1e77fa672b463fbd9a4f550e5e5b81f4868d635a8facafdb587557b4b6bfd86d454eeda9078e1417f32b8cb8bbb7b3fb607b6f67f7cbaef8518ed5a828cebbe2793e46caf328cb3032af36a4559517747f6e721c34a1e27dd816e836684faad1b7724f7e3d52a39d9daf77bf915feeed7e33f966f2eddeb75f7eb7f7e544eec9e4dbddefc0b1d085ca93a244ff426ee010add9205aef374d448410cb8138a4722956663fd36fe0c52637f3fd8f99deee6f32d7aec9c649af2d899b7fd79a598299de6ef17b235dc75472683d1069e854bbeda2065f636ce06b086bd169fffdfabfaeffeff583a473703d935599be6fc36f439ce66a5ca517ea5a9fab4b03d739e87cd14f578c2dd5aed9266a7be70ef123e81038ee68af52daf10a34265a8433050f7c8b4a251857dbae459cc1c8e48a858b4159bf1d304b6b851ec4b5294d7696d6a09ad18bb13653de6a393977c597a2d562f26eef6a17adb241e8ac890f8f882e6c7d68ba77a6ec6bc3d5dfcc6cb53db2b8fe740c6188670729cb66e5b9d4976cf7ced595f6100d96f4e7ea2a9096d331ea06886eda034f1e0e21ec510ceed3dda1c1468df6ea2eda9cef3338860f7db2a1eb238f8ce43bde3d83f915d9022f1520056f937b7ed30ff3dd1170228b06a372b3c65b0311f6010aed8ba89687be127772b9f577fd709da39a87775d1ed5c8fbccaaa51562f334d6fa50bdafb096875076acf512e11c14898f513c07c34314d3561da18dc8d61573bd5049f12c70f44a285d3b747b1bd51192867fbba7eccf18f5e495bc18c9f27129c19cfc733f266ff00adcf8f4fa49efa7ab82886cfc2099c3bc6c8fccc4b00749fe262cc1254e9bdcb4966a220e444bb6c43ec54cf9b8f823b507a788295efb58640711bffbb0958edf7d5856c3f665b9ff72fa214e5d6ad38a0378a809f7c9c9b8c83239d7c818e043f3ad36aea1da989d14b36ddbe4587318efc9e9599e344007f91b12854357a62b3e8867af0e9fbd7df6b48b3f9ebffaa92b9efdfdf921a4fcfdf9e1f3573f858f2cdbbec9edb3b258ccfbbe3e3e38c0eb2753f0016385dd8ef034e606c34ecfce54f9b82c2eb52adfaa49c68e96a64c4bbc5e3e7afbd3f357efac81ab35463d6acd647996e687c5bcd515f4f118ed598fb999aa057ca12695877c6b6a691d5b4b537e7a3d4d672ad76991235394d8cf2e38216794b1984c34048619dec59f70c83af8a39de35e55c02dc985fa72992edc97a33a9649328d1c617dc72e133b6da8254dc791abe9f8614d90b125e6b2d4ea795eb5c75a8377f5aeade268e7b8d315bb3b9dd550bb0465f905e06883dd813a0771126a1e04a947887cc78608d99c5633d4f3573f7130c3ff360012566f0819b52cf4b4b8acc3765604084b736edc6ca849b1a8bcfd33b8407e9d3fcb2b5572c0456e73dea715cf4037493cc52de6be682182b79c6381001bf7eb493ce8fd133bc8c130efdfffcbc9c99b5fde3e3b390964616be36de0b96babda24dc06813628703a26dfc54d3ac954cec34391932e780dd5e4c1e65159caabb681ec74c5c939787ed87988bfbe871af003c24e391ea33cd34727140eca479f3aa1bb86e0ae625c588fa6a81df4441be775c5912975dc1b17f958566dd31e5eaf8281f2181f8012b54007accfe613d97574fdd6e3abdb06ef8dad9dd692a007ac0d7ccd59da0c20b6add6050609db625ecb58af3c9571c54ece54f56e5c165916114a2420ae44677db7c139e0a74c4ebec8b2d5cdbc4fab3f6c667cf494352788b9b8cddfbb0ba1683c1cb1ab6b47b766e93f76129745ccb0ce6faa420cdcc6f7cadd541e2182b622cfb2ac0fb14f59148670e790be8ec077bb3868846a77c47e63867fbbeadf17dbdbe2d9fbb9441fe6dbdb20ea13c2fb683704ab52ba226f9c34a265c8cf47b7f106e1d4524301e025f0e747f3126e228191c0ca8e4394bb0997e9360af94d6e5ec3a843cd6ee0724b0ba3703d26b50e8748dd009ae667756820230dc02a096191164480efd3aa06d5d83ca633d8e0decb60ebd75f21c6d3344b4a95c7a094cc9dd96d762bf695c0e598468c97613f57c1b74adce7fbb4e2bf1d6474abb6dd63776b211295a94a89a6bd1565d62821f308161e908d9787767c5c74ed82779a2bc265dbac2eb3940cdb96d40898b559852ae97a7c6ca80e916f7d5d061f090d9b6bd9749484af1ea523f2d024ace0f7c8385aaa1032499ee5c90b72c6ba1fde64e90089051b420cefca3295db0a88adc1c17d428fb2c89438a08f34271d03e6688c386a8e015126b86d8f56350251c97eb8a21c00187336f16116af9d7609bd3e76d981ab2b59811bbedcfa20ad399ca2a9ce8adccdb4dbf9a154c8d7d20d7cd8af551ea6ea7a31098a2e6d47d0dbe3ae75251e9dc470bec2bd191c59d2cf8eedc88d97af373b79a3b656b877b31cc3ad42d8ba7affd52453ab6436eeae66852036e11384bd540c8579b17152901a8a86fdbdf1b6d2617eb0a17fa6e8445b2b3ebea518d89f49e684f242e18f96fe3a91c45a516e3081bd2745ae1733732a01d96214615c84c62b2ba5c3ee965d23b769be2feedcb1b5817b6f6adad2d24e48743bddd52a191ba960b819b555db098f542eacacd9efe8267133c7e94689f3bfecd6fefc4689b1763a81fdb554ba9265d59f16c5b9eec7507f28b568f43868a6725fb40e8bb3b34c895c5ea467a03fd9f2d1f4b13282f8535ea0d6d2291886cd858fcf623d385a5455d1185abf700160a156fafca7bc8e85349362d6d86733bc06a003d78fa7a215ac6dd90acc0dc1e55a60681860550703a8b0197118824eda6c8283b084cf41d804d62a326c766eeb261f5e52127812a529e8d87569bbf86e988b3de9b84eb619391cd23b3e4307c348d1dabb667cc449e173b970e5733f233a5fbd6c4e288bb872c2857dc1317ee3d7c7aeb8e356c4b08bf6284d5af42ee94f0fb3d4cd87939ecb9c9d4e0d4711da26a6e3221fde6d7cefc415693e8130af5583bd0dffc94bfe0f38a85eaa59d1ddc8260bc07fc99dfbddc4412e5ca21c053a56b8fca6db8fedf2864f883cab764aa10e437846b927ede83c8bd8eb3a4312c013e909a13df2fc21472c41bf53991a436cfbb8442d67d5c18c5b93b9febd305b3eafc027a17b62b27bf6758e95ef5b0deaf0ec5e7d6a13150a8fed9318370631b6b443ea6569c9be68592adb223ad2749b882aabb305585f1328e674d92b8099982648caf21d386b6cda8b1d2629c63caac1408677b450a5e3f3ab2638cc69e66d62d8d57c4e0d3ae67962086272e272cb189ea6d201f393cb0be07cea808d277af32ab1493be11c420c5d63160ac2e86660cc63ce0ec26dd0387f114cec292153c9ba283ec4b545353770703876fc4d3848375e12d5023a910709c0980d383fcbee79591c327f3871f60b0747e5a3217f3c87c8f4ab881bf132873546b5c88061073a6e59e99916b12d32a6f5e56aeb7aef9ec3391e59cfb17540fd22ffede2c8e14b0d51baaebaaeafe51883a142e02432124a73a18b9942ea4a3ed82f9416a345852146b452332d46aaaa5439b4b178654e05727506b12375cfda8e9e3a03ad533406b20146d4fb79968ed38a2a19decd17190495bb6be3a280e495ec33175a95a254601b9f144ae7ad4a5c1a6258e4ca73b61186a3ec36b418bb778f5107888a63b6bf57686dac0180ec7d317e67c4897d62305a0c226ed0ee8f87c35087dad2fc40833aac887f79af1798ea70340f4eec81658b56d87c7f88af31ccb594bf3434b99672b98e9bee34b88eb2e3f77c718d88eebb5f43f79c8bf8ebb76333b6de4af265199cae7f1e04d59460cea8e5a6da6a5cccd21a434ab1a2cac6eb517827a2d2111e36dd3bd65d7a08c71c250154ea3a2ee2de3dd1e055c53212868300f71da333cc189d752d3700e9f89b5cb1202f404c0564c34fcc859fb59b5627be1dadb9eb58a0a6cb93bf36f5acf63057147599ee540e6e4a2e9b91fa48eae76bc06d56bf02b49d84c1b0bbb45c6eb9ad1a2e0db8f1def6ef7c63fbbc4ae2cf2b356b62f4cd31f24a615c2824f718c58aa619190b91a07b1688550c419716e38a3cb640942bf01f50415c7a089b055a29c9b68b9fa20533ef42c5d4911d42ed3bd57aa174ffc157df7d15e8b6fd59e2c34f911126e9c567f72fb6960ffc283e6e3badd4ecff119d7746f118bd3328dc40cb4c72f31b84c9f91f4821dec9897a948fa745e9850b2e89c13d1a196c1857963a58e028fd13694f93f82249b5611192407356efb39e07328a17697efe4f785ab0bdb000f6fb36c4638a9e852077ca9fddc0eb130636834cfbdd7885c54782e8e6f9f90d6bec001bc988e93d5d21a9ab4d97c68f272f599a9faf272f11eead243253a03253eeba2da03a761cfb229a7c836a6e4e3d2e46eb5f38a959b434b760271d8addbb67ce02fc683558f618146fa06d26b9c5216e29da3685fe4d29a0cc32ca3658b16dee887a5bbdaf4ad9cfd2515f66d947bed57e84e0fb0f111d3f916512c3b2b466c2de44d4c31e04a4bf4ef22df9651016299751f7df16ba4a27579cb84fd22c6b923eafa6ea8bbc76a38bc4d01e552257a86b84d30d35135191600f0f54a365f77d2ca9bebd6cb5116039b7b842a87a2b29f92d84df66859a45db4c6f8f56b6098eb21c686e9f166a9098f38708c1dd62362e8fcdbcede1da24e1b5e2d7f0c00da4bb6626f117cd157ee0746cc2d9dbfe7ee409cca4b4d8e663973d9665f2b392897269ab8465cd0ffedee72fa353013c2356fc653d0ff506681f865d1483b0230ed51f726807e5fcd01ec00b99b0f2abd80d30ebaa1766d6e6420cf8987a4b266bfd3b3f23c1755156c093448c0ca34931d2aee545da8c4606de832125f01f7c8776660010ad0308bd727981be8d9b0a34cc5f4d5206addda94336f76d597927765b5e08f79c01073ab60212f7646a9863036ec9192f81decd98465ed325b581896bd99c75b2ba1e0969ecd51513e9f663b9b92636ef21b986c9525d3d91e3a97a9229d80edc096098e91c07bae4a7a8dfbfa410e6d64bfd0456b28d457e52551dfe67380a1be17f96ba0eff6e79fdef4cfd81b73fe77c38870ac4d880914fb465defbc63e2446e09a0d0c156fc491caab3255fa185cb49dabab6db4c39dcbb4040fabd046cd5fdf0bdbc93695675c4b9a27ca1095ed5dafa10686926220089a11b01db16f53c99e926827c643376b49fa4a97d33453a2bdb5850d7c4fb506963ea6a62bdfce11801ef3e0ec5a55d0e7aba39de32ec21fed1e3b5f3140e6fa7df12849c83f2cccc2a91bf0696f98bb0f161a644c2819a2e1c346e0a3161a9bb48e790144c1e612bd33c0138e7b4b00a780801ce99600eab0c6770a8312d7dcc3b9b2deb5a7fa3dc459f57b84a83fa90abd3ee252c9ca2cde788a8e20cfd515f8f29b148b1c3c659f8273db53514c62045ce392927018bdf41afcc55f5521d21c5c3fd53cc49eab2b8be8064c2b598ea7625294b13b42f4dc1bbab0c4c1d043e44c56e3a94a047947455f84dbbb75d79652eb62fcdc147d3d694307bbc27b1902b2667707e4fa5de0501e53b6b7836765f53bd67684b9c780cf9197203aad598df661989de5dbbb4b5d03f2befbe52f8b22265a2689f95dddc0fda9770f5b14550fbf9a11d0e551f367aa7a050fca75a7b198ee3ae2fb41ae9e7d47f0e15a964a5ca8120e4612f5e75005f30a0bdf4879c5c037de7e4dce795bc80551a3b5def3f27e0ca9fe4f75253156171f834b5fb6a112594930f03c9dc9f9e99afd815dbc11333907ac377f239fad04693db6dafde126caa4c47be37eb82d4cada65b35cc3f53d54b397f2a2bd99ec9798cf530928129dd3b39311f27275c7ae666021c5321ea1e40a1237a2f07e37aff566e2e98f6e7be684da59eb68eb1dc3ef66f26e74b31ddf7952f52930f639bcad0fd17ad12730766e86596c83070c5428bd357404c4e059cc532afd83678feeac7e7af9e1ffe9718885dd1872010ecbc2ff20b65fa673da0568590e4cc1086cffdbdba8ca22407e21fe5d037a49c914bdf6bac385c7f8b217ce9abe23fd555cd956fcd35a95dafeb6b37d9d67b5e93a35f6f058d4eef413b65605d046f895628806d5b08704520eedd136d33c7d4abc1406cdbd9ef18e4d9de3188836596e2090c2cf092daf85411f1b0fcba64af8be8fe754d3d2447f2f7cde5353531ce04f16f2a22fd432d54d82a3059e1061ab0a68333798e15ffa7ba6282d35be9c4468f4a5ece18bf73ddfa25092fddee3506be6ef34854c9d173e2f9312c177d7fc6c7a2351627f143f5273c29e1f01be555765ceb9f919c514a632cab5c5ee06470b468bb4911de639b973acd65a9f28aa97832c1530d8d0249d832d9560d36d58f2c22e0248442ac589004be2f9939f4bd7bac35af65d7321d4b75d5ea70db694cb7ee6120e3a8650ee9ed72b40d33b17daeae5a24844192eb207b10738d35063e17495e593e4fda58a413d60e462324d6d4b6e6a61a925a0db59971f7571cb459cd3bee46cbaa6502da811d89d8f7d3ebc46a103a2c544f84098a0d70fc4e737d3af0fb6f1f79f978d01af0432530685b2ed658447db5d7f9f8f35a1f595cb7eefbf1680ecc9362ed582ad3154145e106e8441b222e73f3cf51f488ac9268b6369555ba25bb774fb410076a6fa51131bfdd8b6854f8dff9d85f72cc9bca0fafe6ae02ff766a8fd6b983a07315996d21ee8b771095ed4a5c4e15846731ccedc4c6154b2d4f9fa58961b1297e9998a42a4b34d640f5fc15ece43eb45b00d1ba6e116cab738310e0af0703b5b90ef7c84779aadf52842fa736e2611422aff9f0e77f13b340c15ab1590fcaa2a4fd9b69cafd1394d836e17c960523bd2dd3a19b190e88b4e978873f5c6d0d86472125e8c18110a8216c1fe5d462f6b1f0b30e866f42f73ba8e43664cf05fcfb9f47ef3e4663eddd1c5cb5fc1334ced87bbcc98fdfe0659ece303c91dda536c1db962d0be2fb6768b16e40003e495f2d783e77731187d66db6836294e2f6afe51a3180bd988f346185aba1e175d275f1a378ab619349c3fcb6860c4137bb882f60b510f63f0c091b18380cef1ad63c786f5dae964bb5c6448d921b243d94634851bf0f2156219e20f3d408472798578de542e3213b42ef89e60c2dd55866e345262b8365fd3ebd9c40814c55a258947e2130b0e77287f68dce19596c160cc6020e7b7f06dfad60fba57496e6d536091cb633c30ae4c5f6225f68956cabf7f352693314fd2fe8c57e6554a28ff3121d046b3a2cd38b54663f976ad29e7af269c387803eedf5356875f6aa329d59cf557fa1f84c2cb05ba9e07d42a7d582163b4111adc516c3269e6bc38cbabd2e9ebc7b87b15f29f09790a8295dc933c3c2e64a8101154423d66a26f32a1d83019d14e8d5c1425653ac02adfac4785aa463d5e3cad710d5d6bea44085beb9544308590151c9245684d5a795a6f8b18649ec89e79590992e849a01ce6b0141cbc5a915779d8a919aca8bb4280dff0d3565697eaebbb431a0a505da002a9d626c4bc3a93f86f674d7aa1be8ae785a16f3a4b8cce95355e39e0b454b67a31fdead8fc74f398164d3f9b35681bbc8ff535d3d2d2e732f17a3844f654443556a576d24c80afd95f8f8403e19a55ac1133da9947b2157e0c3d256667d57c2776016eb66051e0d6afb8d3b90356df7e625fc7d8ab4b1dd891d2af33a6b857555cccd6449b4f36c7bebc640901154e604221f22e9254d46f00e5b9b4dbfa2d17c524634a3f0120c5d3d2729534bb4369d03d1b0544dbdb3b168fc5433116524a222f11efbb8bef61e63c0b458a1956e55800054182a62c84d09e10c252288acaa321d2d2a250c499a2a38aab09d7e1f63915ea6dadc51a64a8c17a5862bf9b8284b35aeb22bba778ab67a3f56f30aefa2a63703e7dac62e198b8fc1b112bafd97562ca4ab614a4d30d7288273baf13690fda7f8ced980935ae13ec76de6fd259e380374eb7af8f8c6e769658d3d0acc71620ec9655ab5aeaa00450e31707188999aca28cd13f06dde6ec834e95d71748c6e841bdec0dc1efa5dcb36494fba0205a24514f396ba61c17af04cfe8e401f6559db158be2f738cf33f5d7273c55aae2c7fc2de0177b2085a4769d4520dca3b75240cbd875b4496426dac13beb8ab0e70fadbf7d9a2457c14c9567eaad9a68d39d4770ae3de6ef43f0eee9fafb885d1bc29cc781d47559ffcc36921d21791c774c1d75c488a7de843c112961c83c11f65d5a0a9de667991263fbae67e606a44d86fd80d5a82e0b8ab76c86e81fc54f4f4f2bfd1e7ec2c33c710c4d077fe02566f0038ce43e7a06d09538728825ab4a8ea76fd5e438740df1564dbefff9f0e50b6c8136f70f6d8afe69eb816548deda58ee2feda7a698ebb6f28e8f15ed26fb7b62af4a35197c7015dd880fbd1e3a56bde9ff00256e3a76f071a87eb3b4e291702fa44529660b7856321317413e5e07e982c2966aa21b03fe87e30bd1ce87ac5fe3baa01175794c7a4a3bee2c8fedef3bb2c973fca11c7dd473bc2ff72f27a7fa5dcb86683f317d5cfd320f5eb99e4d26a033b5d066cd563dd6ff589463f5cb3cf1c10feb4ff50c262cec177469590ff267bcf1dbd8471e959cc4ce25f9e3232f8a393f3bccb7d9083e780ab788fa43ef2d8bacd93fe43adb4f6eb8e2950eb84a00f191906b7eff01979ec814d4dba3984fd387e5b7a17e5f3c82a3077cbc71dc2d4a935e8c17ba2b46fdb1e17e8b3cbb722c308968f0028dd773aad0549514cea90dc886b4aa80e3357f53648c15ec29bb98bced41b491da4c2f40a944bfc57eb9030750c5fb10fa04b5838ad34856c463b7878d9edebb227acde7c1267d71770c209ab88b86d53620ae82239a2fedd18dc0a23e84c051664391725591928ab0b776d3c35745a2fcb4db33834dca2bf5bec2f7e227d3344ba22024516e1b8578a172866dc672831d1788d5874d01c58f4a416057c323c765baa27554d3cb38decf8baaede4119d1677f72f833ec7f5855c75bbd5b3efe0bc3f56c5c1f4ab975ad5695f2fe7190978602e5ecb0698abf795d39b80bf5b14018d6b2a38a01f6cd3d6c08097df692cf2bdd809c17805625bec86010c20f7c8c11f3f6c9605b85d17890248e7e11c141e6ae280f3dbea5bb07a3657b8880b7d164986bf6b7a321fca25ec7232dc77d2217d9956e32993873039c8586a255a8fcab2b884687afb0d19bfcc7db2885b21ddef68db6def7a598a10a352c973167389d58d41fb9a5a3563bc75bb2b9b258e93d5b95c5875276a2ec29895e2a30019a37a7a86686855f5cad133a7d816ac647404b12bab938f087e9cb5433c73dce432b77b31e5015dade636a3a85ab7a3600de431266a74e7e5b3cc3e7ad09dba6072f904c121cdf59c20cee2eadba31dc65ac5a8dbba38239e69b98333cf422fade903e7faf645c0eff5fbf89430ba72c6faa0a152a97296e60a15e0813b8b99cbfd50c1d2a57b4bf7e868dfaf3102d7d7c06d371628e302a52fc085a8b770fbd620c773c2ba502cc764806ee1bb9e25da773372d3615ed596eb8b3d8cc4596f55b218abb27e45b3c298b74e02e3655a53e982a59a0ca7f42316b0837bc0af9a2b9850bf2fd20b9929e06b512001d679c17e3f352caec4a7605f594f3ccfc5ac00f347adb458687c6185f030645b90a42806869a532de6609901028ad1a21233792546ca1a7524cec1a54c2e643e5689586879a6b440f91b2a7ea579a5ca622ee80d0ad8756c463c7dfd52cc649ece1799a467405777246e62d2a6f59cfa7d068d33f83a67cee19d66669bcba4821944894f571cb1d4e38eab3a921d5557733518dec5afe15d2b441e7c081abff9e1e714c5f5dff711f4072e51ea37c858b8d427182569e0f5c10405fcf09bb5e42b996a78d63bcb9d629a92563853ccab7496fe373d8e9a45d2e7e97c4ec18e0cdd8066342e56355557f8a00a4e484d43eaf785cce01236552293bae24d0f99bb0dbb1b066c6bb4a3384ab164ea0ea45a5114deabf8d3de5c1a6665c0eb3fda3d0e55bd2c18c99ba369bd73c75ad45c62b87b705deadc9a82c50be6f492620c2e661b9242ba041629fdfb910e80c88b6decd2b6d46635609dedb3b9cc7fd1ca6c02f7546e5398f81fa20ecf61a9de2de626094368d251c6a1f2b16a0219826daf0f618c95598d47a0cd626eba7711382bb591faeb6d333ee3a66b4f5d538be901afa2ae1361b81da718315b64554a1313b71a8d654d2fb013fcd9cd4da5eb0e2d9f4c1238d96c4cb376ab52ba6a756d13ee87e52ba85ca966c5855a53d4f4c99b448bb144bedaeed7fbb0fc37dc54ed512e4ee32e9d8a79915fa167028d23468bb153332da7d45ccd5e361e585e248a7847d402c293b0f423f4166616294869b198383481bd312a8a4cc91c76c69d606d82276a93e317ab673e79404439af162507a0147645b92ce57cae929fb1a76260fb1cbc64873d307d32090cef96d5d23b39812e5e5f733fbd634580d1c54a58d3f7a6a567d3ca6ae8da41f26b866d1c1ee34c851143cf63b08ab8ab8368303566d770d8b5a567bd0b8b77eb3be9c02df57ed87b6a636d0b35b45af26210d76128260b3f5a9fe34d1118bdcb44c8b516950f623414fb36e5a11bf79aa59f362cbbdd52e1427a07369b574b45bbb565699add862a196f1acfbd3b72e20c26656fa8d1156bc88b54ba3248de780d3f827a35bf993276e263308abf9fd6e618c7c4a675cd116ea1b4f6f99a3f9c60852e133fa3c3fff0eda357ef9e1f3e7ffdeae4dd2f6fdebc7e7bf8ec29b81eb24ddfbb275ae62a652373aa3c6919d61c0fae87f567ebb92cb57aba28513587a9354254e20aa2b36a4d93d5f215db222d88e2d46af92b34da13ebaa7452c7d64cb73a245e14076277676747ec93388fd60cbaf16356c8aaadabb223ee433d76ea635dcc431e79d4ea1ab07eab0bd3859839332bdd6efd7cf8f205fcd4245a5017552fcdd38af2c3b9c3639c1fe656b3c1b295584c5d5431a9739d26adbcc64e77454213d915739924697ec64e624a61ef455e65c66689af62c9b8395b02a68f0b14cdd2a8ea309da962b154ec7307abe8ac9e6fcb96db11882d3704d7286e3c9200a9dc0fbb36cf0d5d7103f1ca3eec523f5618db665833556baa2a53b2b4a3c699f0f1704d17dbd16e6728d7b86c8e58d8d1b365bbd3b44de3abcd6aacd8e98a9d4e4d6fca4eb4934cfb946823bb3d717d4dd2f6cdb03098c7b56b4693b0ec900fa6ce50cad642dbab638b29d1e8dec989d22fc14d805f6d9bf722cdcf9f1479255334b8b0e920f58f33ddc5cd3deb9ed4e1f64267147500724bb1a4f80373e1245106d99959a96e5363acae55bd58da818ddb6e6ad647a56f2e548c7eeb880feea635fa0d38e8d16f7c450e207d5f7c70427148b879286ef81a36ae47d3f459c3a4156b7cb2a484f55ef3903c4c1d4e5354dfd7e690cb8b7c9ba2a3cc40d3d1904747e390180c2baba98661ec6f3aed0ebf170faba8da8950173203adca2c2b2e5522da5a29f1e4dd9b8e81364d9c81c4525d3ad5bbf6f02e6b657817db88ee800d2d997b1d8921bcf318d3f2854cc19fac29c59c8010ac391e8677f19d7e78b7234c9fdc816f9d719d192e41e82acd3231527ea374419a9717d5940c109342c851b1a8445af57a3d28fbab72ca44be589aeb4ac9441413577aaa4ad515ba007932945452a7689341c78f9910103af6443a69df39cb8a91cc0c0af67abd255e65d053482dddad2be6d09c02fd25d84b359acbf1f99b22830b34410c2bca4ed4bc5463141d7224811b98079bcb6a6ada3b3aa6f47e5fb82c7a4cf06170465776972030ef8fb38c115102af1dfd0df5b03e52b7b8a23142f8ce4252e8261acdb052f96286925917ed0d33ce54b52f62fcc7ffacea1776247b68736ef007c6b5dca03be9e7ee4abab42bcdab2a06c04912785017e96a12d11849ad9eeb67bf2f64f654a979e4342aca754e06538d33f0223d57b10f239f13799a3a9c2a684ea4b3391e9e784a1713717ad24bb1995332be70529db92cab546668fe5ba61a8c83c000253147e9f85c9b3f17aad42a218785eb9cbb35bb27c20654cdb11b2a781a50fcb5ba005d9e6fc428ad66529fe3a8e9f7249367d8392176c5b6f8252fca44952a61a3c3dc3db12dded4461eb464c9ea8d381a2f7455ccd2ff56253a5b64bac0c2e5f119ec353af33ad2951c9f1f8bc3785aad932833e7a7300ba7c154336f4e6efcf615e7d420fca9a5e350910661b97fa8b13eee8033afbbb96348d8269f78d087ae9dd7ae1f64d9153008c6775a9f50032c15739c5c653e2c805e37aeaf69dd5942fb0e4773ab847cef9e08d3b1bd668753206ac15f86b78016eed83efafe5091681f6e320dac889d93a5aea718ecad9ce1b967c1d55efb3e87b3bc97721ef8c8330d7445eba59c2f738ff7127cb2c19b0329794fd518390a8bcfcc18ed2893f9d9429e2910891db7a75535dfeff72f2f2f7b6a3c93dbc028e640b064d62bcab33e24ef7dbdd7ffa6b7d3ff8b56e36d93a2c7653aafb66d6de821025fcb0c9d43ec38ed89b6ea9df5d02da3f6d73cddb5fbaa2b4a75a6de2bdd15a7868942476fed9dce6917b7a1497c078e1ddaad56e7d43fbdfd551bba3ac6df33658abd9e8813ca4b0df3b4d3dbeded44cad42f243c6eada59266126fb1e9d954cb9c06d7b0dfc55fd57b698e05370c7322e06cb53fdc903a7bbf2f063fd8eb6d0dec68b72bf6bae2c1f146d027bdbc28e61b815a153a07486eb24232e5c0b94d02a82ca22b07eea28edf272d39706e7fda5860205a385d2d6bb421026b8de5dbd9f6c4efe5999c2ff56e1ce4b93d6d531b7d1b8799b53275cfc62ca7065df76bcc726ad075afc62c679953637024c95d1a8387d6aa286b7e89ff585fc72fa9ebff535c1ddbf19a3d6f7f37383a0e30f2611368e0e638c4c646787272ccd0b0190c5d1c33fc6b06d3416d4bfd1bdb927e1f02bd37bcc17faaab18eb833c87f7e6686e00b6c98c237f64cbc70cb9cb58eef31bbd1b93ffe1e23217fec6026a43e67a23c07b089c62059d626eb3dcbfffaaa8d4fefdfbe255916fd31e63bcdeb850e518cf76cb378a774af9d3f7d93ba1e76aeccedd8dcf5c72517eaeaee8949d14a598999d9da84aa619dfd1fc60ac1d84f149e90e46a4a58d0c330df430a02bdc07ae3b21894e70e7a66ecec3095e721c3a9af163519000f7bedd8d926e7b3e652406620f536e5c153f1605df6c62201e3c64c79d99c236c86b8a2238ed8e5ab2d515ad51eb58b4d34a916c156e2e60f85f54e26c214b99570a236f0635b6a6692baa6ec754b70b2e74037208f03891a1b116c361977f106e2697beefb68c4d5a7a4e9af61c8bf829ae765f3efafbc9bb473f3e3b79feeaf0d94fcfde8a81f86e67e79bddefbedbfbeacb6fbedcf9eebbdd70e73571a2923c80c1b0b6c1bd01d2e6a66d061232e2a6532db2a2d02abb82a127822e8a47a787c50ba8e1f4f6fbaa2ae86058b27f9a19cb2f7b3b7f06634933873dde98bbc4b9693f58cd031214ae7eefe5f357277f7bf4e29767cdfc605cea793e49f3b4bada0cbaf5a0b5099b49d09ccdb477d9d80b32fa9a6f897bf79852acf8416cef1a4613bffe43ec1ad81d9ff2fda086d12b78cd1796df70beadadcd75fd1462c7d56d1c60833d7f359ec667d1655a4dd3dca78250d26fcb523dd7e6bafca6042bb7fe70d8bb1e0e8fda07fb47ff381a0e8f8fef5fb78f86775bc79df6c17efbe0ce70b8db39fac770381c1e5f9bffef75ee1f98b4e1f0b8efd4629feb37994c735be73f86c3cbfb5ff437d9de41e7e11287ceb583ee7f9ce88aed9d58a68344f0b8e9900202288afc63775d30a035421c70baeee4169cc6a30b0834906ff6d0cd94d2d7dda9ec334080fdfcfa846ec6c334a7f0727ded95f52319d01a27e2a11489120364e9554abbbbe1f5b5b8c3b133cac4aae9fce25743d25ccd8929b127dcaaaba0732a6ea5bd3fa9ea509e35f09398f1d1325e2bdcf84b55a05ce2d4fa516f0ad280eb801d691192523c86e3d6fadd049adb282f9206154fb1e8a99897e92c05a95551d6e3d7fcbf7b82e17c6c7c761132e29f1e726545b9fa24a3322d391a6f74ce0408bffa9cf1bb8a5077897cd4a359dbfbca77a8b00a8d79a80e1fc4607e55a667d34ab4c71db1b7b3fbe5f6bc541a24ca3fcab11a15c579573ccfc71e03806fd2c5a21c9b4b4902ef88593a56b93966167942be595f3e3fb4c93e988cbdacbc78fee4d9ab77cfc4c4dca4c9541644a0a8b46f30066e52bea5aa54cafb83aabdf7dbf1bc4b6769064e3dc0072cfa951b2d2a34ebcd8a33832897b2ccd3fccc0ad4c7459ea4d634c09c27334511160ef14d3187774d3a45b3e24ca0eb53d3f1445da8ac9883f6b6ca2fd2b2c867e04835cdc5b84cc17f175445e7ea5b352b2ee03d74aa4c5567e637cca26194e765912c48b7875706fee5ce959abb09d4e6fccb8ab3744c46cd59565ca2f1b1c9811ab1493767f0e67ff2f4d9df4e4ed097ce5869dd53f945efd5eba7cf4e9ebdfa1bea2efa4e7823773b630def99b9392fa85e267c9997695efd5a2b16a4b7274539935557c8f24c07e2930c9e2e6579067a56ba17c4c831d06200efe278e419e81fc4ae388072db6257ec5b251730b9106d5327585e8add87f0038436f0736b8be9e29aaa8f4cfeb6d83de63d3089c7dcfb1219a39567b1e9295a7b692dcfc0db0e0d755fb4c4966d0587dd2bd53c9363d5eeff87ee9f75a3374cabd74be4023a665bdbda3af65abddc2a94888ab95e15998a2d0eb8c12542f4545916659bbadb09c7e7f4f949c97e7b7b5bfcaab271315368ec315a20faa2bdc7f6f63603869d03b58b4b692eeb657199e339332ef20b95a7a082a00b7cbdb82a16b0cfd0e5a2d9f5951c9fb3faaa424cd23cc1fd2ab34ca795c2a2e0a731c152164d011a9f1549c1ba2c2e01619e350ed8ea4fbc3748cd74a31ad0de118baef8acd8bbe7b0776f05f6ee6d8abd7bebb0d7a00b0e00def51c96b0eae259f3482944eb94e6a669427abd1eccc9a9e57838d165fb002ab27bc576b665733bf50edf718db16e728ad293f3797605af0d68573593d5716f5ce46359b5a14f35176acda725f576cd61f9e05ffbb0fc452b7f4ab63b10c0486b555a4b2b5423b82a1670329d19be4d6abd30d7467c6134fc911f2bd98f0a0d2b32d9062f6f8414a20d07f07f683301dadb7598c3cba129d45215a631a828cdb130189e80e6d0a5d9f1a3b238c7cbdfa5a51d97d6a7a67a3f57603ec697808dd291e64b525732f3329fa399a13ff95077a9e225a12e2855aa994c4131009d6cd2399c140ad987249d4c541956181ec3be3b6b284b578cba62dc154957a8ae98700dde4dceef40f7f696bbbde53be977714e34bdb669c36de5354b1b762c3c8f985a1e6edc376c74d0488b5a2fd31c6f31e84d1004ab6330c74e1e0aebc3372ff2ed99054cd405e7af4292d4322417820b980b63345c83ad098e476662aab2f964915962a17b75da859791d0801d0f80a37871fd99be84b3583d0feb998aa5bc04ba1d0b3a4e6df572721af8dc21c3dfd2020d695bb1951096989472a6f461f106843bbbd6a924faca19cb525925405b634bc3730994b3ef6306153d8edc58d778f54b8dad040935574a9daa32adc899905e8c9e98db2e58baa9127e137ad92c2fd61703120d907a7fdb97f140384ff5c23df6ca29060e20843e390178e0c37de54bcfa270300f9d8c50c632424a42ef9996c83f7b3f2fcc7dd8dc060e8bb7ea4cbd9f3bd952ad2d0e1567f74013dc6a84d772c7c56c9e829e35fdaa4154c5b9caf561e1bc370f449cb4b4cc5b75f6ecfd9c95c08458390e28b319044a3b0dc3014a2073b1a8d22cadae9824030381603d3734216666df3c3afcf9e4edb39f9efdfd0ded3584691f0dd172f925708b4a8fa53938c65359ca71a54aeb6cb958648977822ae47cae80e68bc9022cc0303829dccc1cab0c2ac0f8a8b5205fe3583fbce9810a5bad19b3a14013de6c7da8add51ed2bf5ea7d50d7afb0c1d83d3a10c42180595199ab6c8b7cd464f783a386595609c9fbe1f7aa75768c32433a1179349fa5ee91eb6608e071ca9d4fb084fa58677fbfb209c331d4bb63a07c3bbf08835bcdba7481a4a935b2f936f7e316de0e1dd8320e5d8d75a168b4ad95a877705d4ca8a36ff6c6ca5a9fafba64aff8f75796d1b4173f787778f71758e4c5ffbbde3ce0148cbf7cde73e0ce072ab43dfed36fd8065bc46613a64748e3b5b1df3abd339b8de18b47db475ffe0b873700deddcef745ac3fcb8f75b91e6edd675abd315adb39060bc815dee0256dae3b09497b4f7b87c1d84793e42a92914e620291ddc58db372edb131feee0a36e2c384342d3d655a31526f602549b6d12de8e7662cd0f97001461205a2d9b40aad44f5596ced20a4c039849a7b5d94c5cf6f5b568f55de95269ba20a22a48bb8460298c70f4d47b35068bb38e153e070cd00ce8b63eda39664c111114ccd96539e80e0b33d0f86d48b65ad5546ca14d1c38d945875b5d2a40a7ba9d0daa654bcce8466a0fee7e5f3c3fcb0b733467a592c995eb8a56bf2f50eaec7935cae33730ea06e5b8ae839ca14af3858a3805eb270acdf94839c667cd6d980b330f7b2c83b81193fc80257bb35c93f325cb392b8bc59cd2bf62e9b32231ac6049595fb32ca92b55a6fa9cb2be3966b3f466a1a7d6a73528e8c3c88b9c9c54f8ede1bc7431b52061f3e70b3dc5ac60022d7a46f36495b707765ad85b06cc61fd7bc0a8b645d8b992a070e3066eae0a5bf08813a6dd6f31bcb3b43e2e78b0a660c2f6152ea2818f371d1f6455a932078b535ccbeb6b5c3c3b157ceedc84e6108d04b0e2fa1ac521cccda499827d3b6b604bea3d7cd82eecfb9fde87258d7adffdf27e2f611ef7e9af6f0bd768dffef0ae340999f6c59d3bf6372b0583de77a33fa01df49319789b523b625fb41d521e8856ef3e84503efa474b6c510152627543e9882dd13ade3a681186217f7fe3bc61224b20f32bce55a0050f5e6ee902cd7cf87d0f4426d2740be8cf62a4ab12a1a3e69ea39c1da0d5fb5457ba2bcc428ab4f29b47e5896b32d8378dbb2674ce8e2091d38b27c48fba930ce233576a36cfc0f7a70b2142075cfc741c1f6decdff2538efd6b3ef0dc858c8a74e9b231e8d44e41cb50379d83c1c03dfbdc8693332ce07f4513f4a6545565b6afcac705d8fc1613f1cbdbe7b8505a9da1f472e994842363897c1050b7fae5ed73e7520b9abd12688ecd07e34021cbdf648f86c3fec15f8ef975160470e1f371eb3fcc7e18f70c463f2912f5a86aef747af621b5bdfbb5f9f8656e6e5b52a3f725d817c1943c832ea06e99dd728e27eef1d7a5d3390ce3142545c4beeb4c6ae2ec3f79ca1ed9f66f31517fd42ce195525aed29d841f622823b0d38b4d4ee6d4028dbab8670e4d1b5b08d2931cef7fb7e4f67193b71b121bce7e1f18b0adb782be1b276a22544c61c818aab25d2abc5484d8a52d14e94b6f75e2a9f827846a4e27b1154fd50a44c32cf9e6610ea283dc63393b4d3198f40bd06087ef76cfda37db06fd6ced5d0b3c7c6966875be6875d134ca3ad9e974ea02b99a157b31fa0d26397cbe88b81138cf65250d0739facd1ca41f6e62164123fface35cc454e68c07778d39e996d185fd862ccb04dc72ded975c1090e8ed263ef06275e185c148a7b1f3cc3d9930ec07c053187cb78376c9cdef761028fa03088d48e390c51dab05b81f64cd015e834d464d993201b1955c3a0e489631ea90962861c3b1f5748e0517dd1e87b9cb9ac0dba694eea725011089c0fafe68a84cecf407eaf1231bceb901d85905ba235bc4bef0eee4593b5d0b000a816259bd4a26cf61d6c01f9b9cee7e9605e54964184c3a15463955ea8449c9a12ffe7ddeb57144e369dd87e99c2a7d170c28e029c75596cd07427eaed5ab4685a97e695f9b4a18f9450b37975c587c3d6271a9bdbd2bfe196fe4d7c2ff8581f8adf821d6dfe596c1e10a9c0c939faedb813e2219a483b828a1a6254b8539b9dd5633647c3f271a36a25cf67c4797877033cb0ddaa61426d77d9cdd8fe0df1401c04fb52ecd367701b7034a6b1d21544cccf35d6ca6e22219f6231793f58944eb81b375b8d8fc5bedbad02c2d9f101849f7736034dc42f9e5107eebc0e55d32137e4b19c13ca74a56156168693f4f11ae996b2e206e26e1debf84776276ce01ecd65cdb18ceda3ded6fd83c13feeec7ff1e1a6dd3942bddd3e28f0760c2fd9323fbfd86dd578401c09ea63cc29ca348a5b46243f026fa175e9b5cc133153325f3d58bafc6f3c5cb8338b36140bc70b497cc4833bfb5f0c87fd7667f5081f41441f182128f9ca405f970c7d90e96c18c71d7a5710a50a33c88c4540a5d1e5307c8bf04e17a12760c2d42e55174aba3182890859620cb9e26c349c9f28380570894076a57d1ac1404c53e5b8b4fa709cb94ed3a576c9c2604bedc68b6b83b0552bf0e973a1c481688188236dc537d64596896251e18240b7e5064b40bb9167d955d87c11b019fb3686328a6029fa7d50a89022576768f49d15c5b99c2ac9b4ef410b22da30feca829ff40cd743658e1e146cf787c336e8d71f74fa671dffc08e451cf96ce290a991660ed90c2092aa59b95acadc6a5a691a68d6f86426478b72bc100d5463598e95a1c5e94e88166778215abd0849d04ce38e742fbff9f88dc4972f42b2437b93f5567d70bf5c8569169dea98d6b0dd5da9959b6a2931301536a161d353899953fb52b2ece20ab8d6841c50d8cbdd6c9bf071941ec7ad12be72f11c8a9ea1a3e16596eeb2d8827b8b829b6cd345b67909b1e6e645b4d1e8f0f4e6748e848110c87695b86f23a2f1694b896d6db29691b88fa611857d58ca4bfbc2f2cb4437a1f8539e33b18d0fe187bedbb1b55568ef183792c372a036005de3047506370db357939ede6a16230d01273c6a9a47e041ed9510f0c661bb1764f4ef3be500b7aef7fb10ba05041c7e6a2d01756f9184f78150047e915c64e8fd5fa6103bc61d7e9060b3cdd5dde799af3b8381b331c06d552cc0a740abe5c5ec60c2a04471415a856c3d519505e293d366f0ece66dc52a2b852a9b8a54b0ffeed190e48f50c4d2ef06dd29f732582f459c798783fb87c116979e0592b396e7f4fd5968fb11088a96490a6c2b5bbe19774b7079a2d5b9df5a22a358716d67328a66e14c7d88aeed56bb15f5a073d05a2d93f1b5ada825a8c40da956db4675354d89430d02ac1fe7f11363800dcb1eef3b6c77e95fd36aca1fffa14d7a43df7625dd7b9741e2c43f5bda0d57f30c282e15be0508898f014256f675cb5c198097eb050f621061c3d4860ca27b81cf13a7830335754ddde4f534850015a0c50f9e34c7573dd07e0240aa2ed5d6183ae88164da515d90d79046f12c4d924cf5501dc9fc0f9c07a3e22bd487835539bc14cdc06d2fc4b217c3bb7d7397ef0fef0a3d2d165992b72a7717c72c54d519de752f7c7770d258a4382467edfae21c048bb3d3150debb38f30c041d036f0cb0f69832f2cf633ed549527510fcc1efe02c10284f6ab1d4e808240404dd760ed997ea9c56c017f5d65f30243ec9bcbb28d91322fe8fe13dc1bdcda91ca047f9ceb455d274cbc77af01c7eda5aa7d30a84dcff5179dd64a6e39788830c5a1c91aa7d6cc8bbd2aca99ccd2ff4669c1597aa148450f4f856ec06cd405239ef17894a36491b87232cc9a4bad517fdbbee4e2c98fdaeba0b13d2db2c4a9d3831cc0a428d41b4a143a9c02a2217e2c4cdb602dd8a59539ed2fb42afbfb69f2ffb3f7aecf71dcd6bee8bf82f86e67c86d6a48ca6f2a8aae62da711c8f9d6329db3787647a63a6c199267bba27fd203d0a754a6ff921dbf1d989136de72671a490b22c592f6b5b9649b9ead0f9a02fd4ccf6976152c562ddbfe4d65a40bfd13d4d8a92687b54254e37b0b0d6021a8dfead0560e1df07c8bf03f37f47b6c8adc26389927f1ffbb5309b0a9a5a18085b468541fff486c0bc899a41e4e0c4bf4b00561f6fa139def47388a4fa65f66c0264051fb4ee13d51b055c6163200bb46e07b0e5ad26c0a0a2d4a8002ee1d58acf8c46ed7b51adb07602ec7acaf5f7c70613afa6b84621ce3d62b5f5a5b0c592d94207220d127d5fa3e644588867d46c42c8415c581dc4f31641327f6e6833ccb2a9ce43f98e320cd2a09986882a374971638a1f3bd5c384fe4ae3706caee01085ba08d51c9e1b8dc4e80c4569e512fabcd5cfe30fd5cdf26be30ff5f3a89e38780772f98c51fcb0f6ef7f5f6414695d15827842dff84325b3fc1a6e6d7b05c63a6bfc213c8e960b99086a289326aba5602fb2c624fc27f2d58af38166eeca24a011a7e11eec176783f8cb5014e5d5677ff4b3bdcffc5479f6ffd9ffec2b2fed7d5129bd3cfaf3179f559421b1a15374afc17fc57f83a1c0c7fca1c0fbce57f963d7f891693ab663d1067e017811119298790f18637945f2f9b24ddbc1c8ecbc53e1e941077705643286a2a1fc0a456882fd008a504e11f48a2294ff09470052112804f7cec30b2e54d7f8dede4405b097c76b30e6099988482191f8b4e985bceebe2b56f4a0444dcfe1019f6aa16a1f587e0d0cb81cacc540cdfb630cc49a481e263d5d1f7e9c53ac16da08f10806129921775e2c47546d0487ea68edd21e3956f4d9d758c5753896102a4b9fbd3764849b130fc7898e2403c40b391c4f97f499fe4ccd9ed36935ac16b58988a92cd3aba80711e9d379bee245fb66fea022661e3897588968c46369ef392813177fb318771305726c2ff0495fd02c224751a2bd49d26ec53a5f410ae419ef7342aae4359371af483a6d8618f12da83207e06fc41156a356dd349a5e5b77951c3ef8b9cfef393c960be79f7cefb5c9beefc978995106fdb211431e343b26f8d724112c9b60946c51e383fdd9e349d6902bda2e14c4df3472b79625692d69fb88cfa8886f2439384f04edf0d6adeda7d54db4569209b49d38f4b4c0ab57e8da5a5dc51482c62a8404c0734930cf6afa8a37c24fd269c6a3373568c58b4814a7466fc4f7c9f048705423f53f61ea80ffddd4d24aee146797e2ca87867f3a3ff18396f85f14c34e61f1d84834402b9ef4e839380c3b5bf3a7e686474899d52818c4dab4ffa5efdacb229b6a45b4a4ba77fc50bca779cdd4efafd4924105be9421de0f82e24ff5472a2a21f4281feb0fa1dd20ac76180afb11adf93298a0f7640bc1fd117662f3a2177837422b7d39fbf8c15439bab601bd5a2ce62fc8c71bd1c9795d92af50d0743b13edf1bdb0bf78d2b4fcf0079aa879bfec1915d53ee1f40f815b7eca78a4d978280472b058d60c55040a00b2848ade61f5f1cf67c61b5a65de29dccfc64e6ae2deba7a833a5a19b72172d79e611a3bbc4f8ef83c76edde46ca091589ce20467befc30bed2c7041f80896c4a0e9eb1cd426bc7998b318f31f3fb42519c9e4c245f126b193bc76918379faa7dac72b34403096a6f8baa63c359e9bffc9897e1e8962fbf2ace1f578048e5d9f8c197e325e986e6fc148a8da798425cb479b295e81409f865bd6b58a0266bea274d5b9417693f187c61f92b28e0b79d1a4aa886cec415c7faa500a0244966c48952903a3d770e4911e0ca0e5ddff0bd7a76f0ca3ea0f112f3569d60e90304491edcbce349dbd481b580b347fc8701e6972c323558564cb8a039ae2c277660a0f1809e68a92a5c8f843414c11ec3cf22f8a846bbf77c292d76684b7d90861af6148559dfc7afc21cb349df187463cdfc5c0f84315b35e378d297b2726d7e3c9d1545a57430907f9b66e8f3f1eaca00063c567aad4c3b7fc8ed6557e91d2ce437e559e79f9a567f6ee7ff6a5bdfb9f1df5ab531cb4adca2046482f4ed922fc56854721503c9fb3690d10c561f546e24c2dcdd1d0676e8d46bfbd0eb5aa2c342e0c9030af0a3fca1f061bf4be06791e78d845e4dff424dfe8673de0540c9251e0a456759344e18c01326b694e82c44bf4d142282fd400644f4a061f28fd2a8f88930c016e90e8517bbcdd9fa1ba8ede9c3ecf193c409e09c235f88de667879dc66142a094ad511d7fe8196a18a68311aafcb3f169f818fef18740b9b87a9167a1313bf234d0bd265db80399b1197a3135ea35170ff4d6b0c7b4895df2474876a7a4cfcd89a0a1694fd5735f60a38d3fc48f657f8807c50b7a9de479fb05b37b62a824a2ba1057491372b88b8134fa42cf0a9bd03181b98d67b8385ae5675ea38a383a22bb5ff21c429c82ef7598673faf7e8471269ba812bbbcaf678822d17931a6d528ab981675983aea3783742c402ad3b253c705af8370e7aaf70c306e78a8858b93a6f52cadd44207790a300d4408a2233dc783d5fdbcbb443bd8f7be174b1344b1de24c8c2a9bc750bd8b70a5ed7e25b89ed4a782cf0344b76b2835e6d83b61153c9fd458be1e94c78a5ba1516aa2d140ab56708bef969296371bfa7df2e3cc314527835c443e0b30e51f5f95146de41ac3cdbdf3a14a7dd93484a19097725cb860fb22407f9e19f099a882e793f17a2a2a2b1c1b002017e9b6173a47ee444f8b6e799de60565f4acf4d44a812ef0486d0c4a1d65f9d3d49359da945f2339d519b7971ba306e4a813c8231b21aa64df51d586e47c8bda1d98419d0815404b736c358cf807630403c7a128a9cc97e9e9ec1cbc0f5ef626508187ce1f773968a651cc80c1d29d03bea74cab408f44b71b05b5006193ab4cac8ce62c1fbc87164c1a77ff6e1792cbb491fffe0e115a00bb21b90dfffa5283ffbf92bcf2a4a6436d70b37e9278458f545d67c2918626eb777c025cf887f5af9f45288477f409a816ab0d4f843ba59a1fc33190349401070c2031a6a9a8db1ef44678be4e1eef250d4d13e8f311f7ec3c7f82b61667cf5579cd80b7415952176146c4a8cb71b219fa4aa191162a4b2ad9a7d462a8f1fd1ca74844f061ba0ed4be5f49c69cd524bcdcb4c90a7f113cfcabfe69e19ef814b9a3b7c9b428c2d26ae5249448384ee5249831a4713e205c4847c048d84de850132f66b7f21c308197f48711b2a75d88b41b7f75e3704c4c15819a5eb33d8ecbe580743c5bcfec4975b2349348ae6e0bf0afa7f25cf8bf7479c2ee4a50ff22a1c9cf05e37318487aab16bdc38d8d72f2c97fe01d2a74410673a60e183451849455ff9b14ddb6863e30f99659b59337898ed431313e23cefa87d220e0e254987252406468a9f141ab1424f2394da175fe821c622bef50bda68438d91ec0f77d72654181dd01ee2435e654ec8d9b4517da04631ba7e3f0d7accaeae1671d3a8a0411c746eeeebdad7b0185505b248d83cc3dce64904d50ddb3d22fa6938f0ad36e1c7c7d9134d1e41f88b5bd8670d713c54180c8bdd0cbbc22b9aa54dc8a791ecd8da12d029602caebc48b4597c3cc1c5494d77981582a476b39ef422a63e4ece668040a908f43ed88ff693a7522ad05752201f1a639c3ba2fe7e0efb7dacc7e912682fc60d430f202b2f383e36b4f0f38bd3c3e5d83328faebc83cc380641e42f2fec7de73a13c5fec09823de386cfb204f532cb5311c8051d59813f62207d55736a1e000bb67848f2fbc4a771809f9f176c1ffb891857d0b566f285cfdc8114601d718561359fe7275ff37794ef6ef108bda9356fcd333f24db7b8f9fa951a31ad15396efa3137f8ce3cac43f463e191ff77605525dc376cbd023cbec39cbac3f1faf4551c7e5cb7d32e99c9b542fbf7448b0bfb3c21318790a5e621f17183ac2160700039f4bb25522197db1b812169d7d31f8dc4607b15f1f140f37a123fcf394e80bb118f0db848fd901588227fd2296e0d348a88ccd8f2210e279b866b40eb0db84e387c59e81d743c5e92777ffc185af6d7f9fcde14dc153a930106d3caf3a7ed5a3ad93567bff70f8641d229dcd2b1d7efafef5ae304588151ac3b20e1a3e5ab4e6271dccfcb461dc2bfcae0de2a2e00a7cedfdf52416e30ef0889df6af83f2792ea92f7efca15051c005b2c8be618ce6cdba6628231dbc36a8958c479a7aa923a650363a6d119aad116b1777612cf67183bf6a3ba86d6b5563dce8abf4937d9aa15a8cec33ad9a6b8f1bffb7174cbdf493fde386340cfae0bf1266eb9ae1ec50351b3d4686b9c3355c9ba93b66a865fbe16053bef6996060172f1a9dd80bcaa44dfd89620dcb6cfcc47e36ec424b14f45c1d61bae82482630687e9faeb703190084215ef5426ef3e1a777bdc1977a461188422bced4985fbbbcbfc5006a68a696ddca66d91d0d113fe41fac151fa21edbcd0c7c1808dfb487e6e337154b5d0491c49c1571090beef4594091dfd1f3bf4ca3bf3df108bea4699c32a0e29bbd56a33f01909f0e0844e663408df26f06f4f790e19bb18e253739c863d32385876ab76b152b3ccbae6d6f130c0c6e0cc5383fc9498417e88e61e4dddfdd8f0f053bc306ea163b6332cf6c57aa750f37385100c443be70e5d33b0871a6c76c7ac451b0d66d9e231019fb1c701b2145456d815b48fb487be44ebcceec342fd6343220ed5e385fcadb7d15a3f3af4f813d15aeff416f6e24a01c9ccc6f050b0e390eb84c5c60a4a813c221aab0878e71911c6ac4feb87fa6b2175853c7c923bd35ed7a03176f617ebb4d117f7b2445a842b614c7852fa436dcde588bdcc857ebe686d6878e7a38f3dfec4934f3d7d5fdbf7d170fb429f52d964b5a64d4deb75c36cfccab29d42d16ee89a039a4a0c003d58b918b4fea3633c19da59f79657249a216c4145de4e8444c8a7bf3fd24a9e8c344d73365cf410b971c73fd38559414d0607c9ab5e287a7e520406c1142b6a69d99c617ccb9565cef2683165be8886879db2e9242b46c405aa1c4c8bde9e1ccaf690e8201af22cf846963002b9e2f05ca1b7eff26e1c746f79e3bbb098fd5cdbff06418aff7ed9dc8ab6a556b41d7adbd090f011626034dbc22514796b85c10665424f0aba826c550b9089f55601f1b8e3989ed10504de69353cef60ec4163d00bd93737c4d1f63fd272131bb5f525c84620c121b1ffd9d3584c1d463ed3e12a8af263da44b4a658d720d3af72286957407d50d208b1afa8630a680ad86890d835ad8e6602dfba264e09812754b6cc599b593ec2c0f4dd24d15fc5a95e83837cf1b5caedcad91a75d80cb3485537cb54279a4dc4d137fe194ef07213cb350c3f44bdedb865bec07450bc74658bd169e2d4f0b40c427ee43ac1164a93c0778def5520148f9fe2af306eb7b071d7ab662333fe0154b9c5136cbec558837cdb9f6a321b048af5caf09673cd41ec4f9c023489ada98c5064e8bf806586e74981f4c18a0820a932b3e16875ed009a581566e1863f66543583713cc0f79a436bed63ce7eadce4cd7d9154ec663d8838c10d211ebe87839d375022b3331dd65fbbc01588a586bcc2061907530c93a2c9b64b0af84e9b204f449bcfe91c3c2225100425a273c64e3d1f074b11684c133dc9cfe9e7369c83a49e978dbee4aec5b0fbe12b11dfd7979c9ce4a8b9ec5166ed55c0d10795ebb230c7236428c83a41f6cb025723384af20e9ebef0fc74d720d4103fd26121335d9ccbbc38f3ca2c8e0a081db88c5c13dfe218b363518b135c7a5de0e56f1cfb3397d76207e203859eda0bf175b8b74d2598a03079da19a8ec6579927121d8346782f43500b7935e2fd05cfab8d53e262f0940ae77d1b72d633d6436110ad3183ffb1cd3a2b9b6a13df7abb62b159cf920bb50b348361929f149f2d923a555583d9c9d68e2b1dd78577b23ed61f8ef617d54c68f72a6ac708b570d445b1de995cdcc78ddae2f8c46628d89eb6d0ce1bfb1dcbb57901f1d1125b98b0cec25ee59d4a6f46e5a7d4867fe0f99af168c5522b276a838772525b404cec51a084061f221a9eecc70ae0c7b30ecae3ee87640d70d58053d3ecc200a9998d4957d79b18dbc55b6252312d0b0883536834876f85e7c33ef518e2214b1ba8bcbf7b345ef9f1200e62f42b64b94678a0e8ab536b3ae47f0dc68167e2236578e4db92b1a022d143361a44c6eccd8e0789eac83ec7c1a0f04ca4b2dfff7e7aed37f295c85df1fb393cc8ba43fc24cefb33426cd51011ae51789088562ebd82df8851a298d0779f5967be63ccd70bb5e16720827960e1ee519cb90877d9193bd47b36d4b47c0892346d6408c2410800f8af5c86cbe8c6260422572d7ec005d9ed9bef08d4f9912eff03c877858a7aa7f0ed188e0277a88df1f3c64bec3567bf5699ee8b8c68dff385e01b1e622d39dc37fa264ad4f3c7c9109ff8511cf0cfab6a844e4c39635edab184445255123d7af5576942515f14d5171a53a2eedc304db899bcba766d14747af8835d0852c69e82a741a8113d8f90cf879fce1bae8f28848739f5e9cc880eb7a1c6f4caed4ab6f9d84428511c0bf5c823a166c5337b13903ffe5813047115c602961345cb35fac2af004904dace7ebef02fb53944e958fdfdf52da93d35fec117cfcd77f27b27971ae299459691854d84d06199c1090e71d715d9c1b70c798d99c8ff21198e34ea465695445b16cfcdd49247836b13d251c86f76bea810aaf01387d539248e9c451c7fbf102e0c0308f89efc0d09fa7ff066855f3ecf8333f3146e9d455f8daa551c8c38c5bf0ee1053861b52cda0cb90834bb38e98a1d87e11571ded193f8cb1f2c3009cd4f59ae215f1fe8318d1cd51c30ed17ee2caf97389a83136005e1bf2a84f24452f092870ec5f53c595e12b5aa33de6beaa5795fd4dda450c069761e5d2a745c102e83160113b9e33d513ae433f36b6b9866a3af5f0421f2e8f9aa3cd36c84b552d517c58c7832d3347031533c75723299c8e3c2a5b3e2f97b75dd23b19334acae39c9d4063f49229db52078d9a848e407647a4870689285d6596882786c82449aacacf1606b9222294eac78498dbbb1fc13a70b5eff0a845466132b59fdd372060b24dc892a3555b322c4aa66755786174b55c52373ebd40e8f86614d86f8f64f74f27e8fd4d1e6294ed9b8044467c132271e0665dcd81572d27110178dc904ea6e2422532c06833f1605845e40815888a53d8990468562719057a0d0df4f46c2bae488d284bb1f3042d3588851281e93e0e849e5952f72bafe71e3a0c08fa1f61179e4d72471527ae8433489ce726c77aec08bd8f47d053a5918088fce75d3706a3619218517a8e1524b63ca73ac6cf1ab12a596a3ec6d589aae9498a6bce01a1a535e70758d297bddaa6b3baeadec630d87d5cbcc525e9e764cf87dc99ce109a3ccc60b7f024f29f40fc465efab9996231400d94a89cbf424823c9006824004b007ce294c67199b566913abb4cf34545a856ae0efa866d8f0fbaac9f8c5a869a8cc82ab7fb39af0b38f3a78df85b7aff23ed300eec019b8024360057cbab028690667a094a0b8f2aaa98c9acabf59ca3e9ad65accd2548dd5f1c4d3113238539f33ea83e1b0e79afdb352647e0ec3462790811721eb9746fd5f06357eb205a70c230389e408ef9ae95a60d96886eb307b8068f68be66cc855e22b352968c90fc8f04e2962f4224b710e640f29ccd431fae3bf950a71bc287524cb99189cc94b4926f26aeaa6511da50e7b8e1fef3e1297f2e27e60f7fcf323f57a61209eb5cfcf1bb1ed4436648e8e0e964a83bff8c52f7e91c8e6f9a4542a95889c204e41e46a08425555d501922497d71b060643a556b2c660e28fd2261ee0f86ff80e11b33e415edc1f170ce8d8232c2d7f6ab10cba57199bf6942463723a9dda3ebf1fc3b7d84a6108841ec3b11729b52748165fa8d0b3d0814648e1c594e6b0988e73df005a934d224ec51e2105d3b4c8c38947dda0368e0c0fdba4ca74a6b2840a903b3e5e304883e2715ad3300825f8d848f7b09a4a50f7f9c02be83a89fcba60c0dfd07876cd2feeba5622b326caba56a2a0ea178471329ea98a822a4d142c050ac3789cc82e79fa426ea274d32f3d456942e1665314c64cf9735569f3e5c9127c725eb654cda0ba37908e8fabbf1e1ed879b0cf76d89ccafa07c3074370d2c8c867b8f04d4b1b56792e7984f40942611fcdcd91d0fd53a1fb1fee263b87fa61c4b21d864396ca0afdbbf869ebd498c6d5b32f989666935796ff4b07a038e2afbba96a4ecd2d172b667d706aca6d0407d5c6ab3fcbdf9298d2aa394b46c8f0003f6795bfe29a4d548d11c62cdb61f094c90c3530097814e30ca0e91f430fdba82021b3d441fac754463c5841ca6c863a31e648ed718767574cdaa6c15a642f3ae924a61cec4793b407321f14c8e4ab404ab4c1032d7acfad305c182185d50fc3ef686127a6fd3592f628a69d89a43d86696723698f63dadf22694f60da7c24ed494c5b88a43d8569e722694f63da4791b4214cfb8b77a4f580783793955bfd102887238557ff0a693ba3696720edd168da59487b2c9af637487b3c9a360f694f44d31620edc968da39487b2a9af611a43d1d4dfb0ba40d05956be8ae4575c039a95b3583f1cc3fb76d888c88bb61b2870cfb773bc91eb213ef1e26c34343309e3d8ae77b8bfb1fec26c350fed128cd3070798c8c90c777c514b3a36d0e5fc2b142e7ccea91d56364f5f8ea09d2f9b8b3b07a62f5cdce4785015208eec8eaeb9d85cec5ce25cc180b72cec36f84f6fcea9bab27e02581af46e76328c829f036cc3e9a3011c6c549c52ead1e597d73f58850ccbf4b28e6e5048af92911c52ead1ee92c74e6578f14828440403421ac5a2da9dab5ce42e773a198b84ea8c5d303a5c47d44259eb6d0395f88247c14bf0daba326d4597d73f5f5d5e350865ff9aaa0223ccd5383df459438b3fa666781977f5815cc56dfea2c4412222a94922df2e9eac9ce15ac275e4555e0697e4be05d5485a03cdc0af2c86d4481665281cfbd3af0ab980298e62b807731053ec76eebb58220095a41f09f88bd5eda81e8367057f6dac7e1ce00cea19aaeb3cf9d9cd45e1bf0c3e16bf6730889137808d78192dda1c1c6434e0349ebcd762c9fd41e7327c692a52676250dcb493e0049ad4aced276acb188e662201b8eb33b28457391e3071f560735efcb10b19583014cb8537693b1f0f8fbe6ea89cec2ea9bd059c2c9873be7b08725328e77163a573ad722899d3340bdfae6eab1042df4f6682274ff13f2e46389e4ce99cecdceb5ce677181d73ae73ae7578f83d818fdead1cef9d5d71319ab27565f5f3d2c2b7169f5cdce3591c1d32722b35cd44af5575929fe2a7e91ea4d4a6487fd429d85d5639d33f0a62978f9b7cec7d85c27f8edc7abc73a0b30e6773e5404e995ce391cf444c227f02a76aef19b0babc761c0e337d86879dd479e0e21f911d911b9be4c5f5e1e59c2cfd4b9a82077a57345e97ca2742e289d6b5d4aa279f4ec6bb402aafa7bccf9bf7bed2a191c1f77770e0d3d57f22eee9bdb24b7d724ee8eeb5c9f5b3d3eb8696f5c61f578010733a4daa823cef3c37577c375f5c2153ad737ec7403e5f3f9d8bafa9a4648610c5e24810a3a9faf9ee85c22e2d5426091e17fc2c2373b97e01bb891a2af3236ed7ba47296132e2a147966f578e75a5e819ecb6aa3023ddfd516b8ae7050b994e1bd0278d2b92c2180e1d347117d05bb10ff98db5d29ea51827a92a02b452d4a504b1274a550a3046a92a02b45294a504a1274a56846099a49822485fcd1372cd6e0235128040342b4b411471ca9e7a39bb1d50f57ffba7a66f5eceadf56e7571756cfad7eb4fa9789c1ea4088239e1095357af866f318922640567f20af730acf331e28a44d3b344cdb99c40fcce62b353eae6eb006be57a37b0d06b0029d53a935c8f2b93d813eb77dd4712d95368966f3f38e35cb760824886d5ea92eb7e19d84885345500c2eb013e73bd9e4056a90e19d4e2dca170905e326cbe96db37adeb6ede06da3d6e8817490bc433d9036afdbb980ce8bc3ab6f2af067f53058118a6763289d333c65f598c26d090098e80dc10bc8587d13d0e699d5d73be795b055a0842d01258cfe9508e2cf35fbbb5dd5dc9676c382d021c56e58d83abbe14ce722da274202da24c813f921af6d6c47dcdf29d7ad9b714da2e063ab6f6c1405730c9cb7601c92e62927c5c0790b6e46e01662601864368b800b81c358827ee32ee424fc2d84ddb812f01b77fd26d16f21f0ba4a906fdc4f9b84be05cfff2a01bd51076b12f3163cc7a704ed463da349b05be85c5b3d91d4da9fbf856cf4829e4f79bc59906a88432ad7d814a07aac1b9e7a6c6be0d4e8811ea0da1e80eaa7b319806a7a360d5005ee5c25ecc20d6315cf55eb6195c021ab044ed8ce55a573b3f329a0954f3be7574fa46015917ea973815fe68353db53c96c3075fe0183a9f3f71a4c7db39cb03df0d4034f3df0d4034fdbcb1bf5d3d91e7cda0ef02973f5d77072f1d7cee4daaf47934bbf1e4baefc7a3cb9f0eb89e4baaf2793cbbe9e4aaefa7a3ab9e8abb72caab72caab72caab72caab72caab72c6afb2d8b7ab199e1a2d09bbdb551df3db3bcb7362a53666f6d546f6d94ac757b6ba33c82dedaa80d2f23eaad55fa86ac557ab1d9f30e6d07ef10b54a3403b9d6696f72ad37b9d69b5cdb76c8bd37b9d69b5ceb4dae85b3b66472ed9b03a04ab407a0b60380ea0557f0d2be59c11562fedb7d5928d8de4214ece1ca38c4540237f6bd5bbbbfddd5edf9b77bc8384ad7f3696f5b9f76cf9e203d7b82fffb4edb13bd1dbddf302ff9ddada07ca29b85f7c4d61878fb7a06deb630f0a8b5dfc8b00d1c43661b6ce37db22193601b6be901dc6d6208dc373be05e9b01122b20c308c8b201ba98005d2d80bc06c0663de33d207b4f816c0a8ecd86b19928f62e416c170cdb15c26622d8ae003603bf7681af19e8b50b78cdc0ae1b7085cb40921f69d8dc04461a218fdd9f0dbafb8d1e42da0e08c9c685c92cb6ed61788414766846450bf7cec765894fc9129f1c92924a53774262bcbc246de79024f17159e2a390b6bc68549617c3c98fc993878786e4194f70d65f45dedda721d1352a6e94852cf55169ea1398fad59504e370ba786da26eeef4c034a951699ad498a19632c9662caa2b756a390a6d580c2e9b8ad6740df8a32b74e657aeed2836339c262d5b8a39cd7f0d137f54364dcb398f17695203c4812c102504811c140332803db006be395cc93fa207a8a5e05fc22ce7f6695b53964fde3e6dfdfdcfb74f1be5dba7097dedef7fa6f5afae449395679617ebe15c7eaffcfd4f3c3faf0bf947f480f2a303cf2acb27f7bec62528cfec7d0db9715ef9fcc33f3aa0fc0899200fe599bdc001196c672f71b1542a7e630fd328bbd5e54583d8943add8ed3b06999d63229fdf32faab74febb74f1ba476fbf4a473fbb47714465ad9f0211beaf2a271fbb4d1f5888d69b6bcb001115b79dec6c336b14dc3a2697ecc876d72fbf4ccccedd3bad49159d62c0395273635b4e6edd3a9603025bf2eb810f5f6e95f69bf9210780ecd34829ac7019a2bd59d29cb54bd92d06d525d99b2cc9257923653dd98c9aca6574a4b34a6efc0d4f49c33255556b97d7acebe7dba76fbb435074aaacb8b07e6f8e8b7f91994c15ff6c578f5ffcbe0dd9c66b4a14995c732e754b0ca29d32af967664493e5e0f364b636a299363ecfc3db35e75c4fd7035676f471103107406b0efe73683387890047367bf60ab445e87495214096784671835534aa930ab5199ea5798059666a75fda35b7cb493bd190eb10f9e328ae51e26c3430349e6e528c510d941a884ac1290fd7037d2edc1bf23e1434cd314eef3b0f2189d2073733e741e2b476f2b139b716cdf85d14646c893dd1cdb4f6e89d9d68baaf4c08d369f946fcae89b352d1517fb44de57dc006b5a75b0eb802284319367c11b6e1ddf9ae090592f6508db1a77cb23b7b1a1093282a3002ff0c3dd6467989efc6037790c12fa020e3f80747e1053b0019f9fc5c4790e034f7eb973227608bd5fdb30807955736a3fe3b54fd9203ccd9ad2e6a04ed4ce857f05db2e8c90f83edd42fb70eb7aeb66fb686ba9f569ebb212be6dbf15b9c5d3a422f94733c963e352a15e97ca3fdebada7ebff545fbfdd612c80fdd02c3d02d971fce3f9a491e975fabc9e4b7aeb52eb73e6d7d26e4876fdb6f456e517e24ff6826795cbeaa1680c1a7adcf5ad75b4bed534aebd3d652fb7d050bbc2729502a6181c5d6f5f6e1f6bbed134a7009b2fc9bd6e5f69f12859bcd0257f756eb53a157a0e0adf69fc2782bf4aac0c76f9a35f970502fa4e1a52e8f51f2a80ac993a2e19f8f3e7ca1b5fc42a3cf4ef27cb284763971ad400ae4116ff0e1efd4d8346b4e0c904724bbd3fd9739706494599a23a3cc521c19717345cc8614da87db47da47fd9ef3aed2faa2fd4efb48eb32d4165ebacbad9badcbd8da37a10fdf6c1f6a5dc6642fa97d0493fe84a5db27db6fb70fb5ae06ccde6f7de9ddfc17f4494108248215dede844b60d57eab7d12e8b8b82fdaef4372eb72eb4b6c7c5469a9751d79bd9b62f7130c1f400d95eaa6c192953c252ac94795500513d5139513f53915addea970f54e89ea057941054582a48a890a06d5bb0c85c2154cb112a2ce23afa6a286a27e7ebdfcfaf8351175f0b5177afbdafa1afa9a757738a5f5357864e2217cd17e47c11a8792b8a697db7f6a1f69dd42356fe2a88f97f84538d9badc3ee129f865fbddf611ec5127f06bd13edabad2ba05d5cfdb2d22fabcbb417da02ba6e983ddd4d3a77539431fcdf6e62507c7c7c7c89eb1d699f6d1f69f26c89ebe3d23ad453ed4b4be681f6dbf3307039178be5f4272fb9dfe3d64cff8f804d9a3aaaa3a980e9823de38f880425d97a06ef058db87a0379c801ae053ee36272ddc719be6b37d5c6ea475ad98c3edd6ba561cd8a8ef2d5466930eb81152186b7d085f6fe894043a45e6bc6cebf7bcaf42f74ca10e4daab6ceb44ff25e9dc199cfa3460e714fb7c1c75a673c379be018b74a53676abb48b06735a7522388f48b2a6df6f54bc978abda8c0c8d64643e9a95f97856e6132999b14620d1d736bb4d220286b3a4efccca7c6ce3aabdd55db183d9cf6f0b977eb6bec441f5b3ec838af133b9d83e2af59be2c709bee45fb44fb56eb6df275906439d8ca49843325f692eca5a6ec2dc94e82f0d508bd49f9a8b113a5003502f75b0e662d4243ef097fa5be54cf2b95f5b4bad5bed93edb7e6b02bf0effa5b7368c8bc3b871f59f8dc1e6a5dbe2b57ac84dff671c77a4d70d71ed97013deb55b9637d9c69db2e136de3ad76cfbfd39e816d75a97654ed8a40f76803498a5996aa28ade5725259b78636ba154908cae3c4b4dcf1a1d1d4dcf9c4dcf7a5596156ad6be908f56c46f0c8ee8f6131fedf75c48813f17fd509eaf2996fc683fd913f62bb7df2fa047374848f4a35055bba81c6203cf4dc6486593d4d59d3c7cf2f5a46fba9fb8cc7a7ee207ed2746574b35d5d5524d5b33d27e1731160c7c3794f6b1d6f5d6d5f6213fa1b5081760595f46d873a3f505a6b53e57daefb496a0c83bad2f80f072eb6aeb5afba8677d5f07c3aa75bdb508ec20ff56eb2698a641c252eb5638ff5344447e42bee527a8fc21a1b65056a89aa5a65050282554112ae458a282e8edd3c010bf1524802c30c4af0a339cdf82b989a63a9ae1d7db475a57db6f42b3b6df04e22f21092fdb87db6f7631c46526f2756edcde02f316250b89429a9020b86fd860be1a32988f6c95c19c612f6799cb5bba406563eb53ee76794aebb7f0a4da8749eb6ab7e529ad3368195fcf20f5168f70b3484e175e8bd2fadfd817c0844e27164cb78d859bcf88fddfa475a3f5596bb175a3b5042655eb32bc3e9ec5286a7b7f4dd94cfbbc8bf637daef76d73da7b5bb154b84da875b5fc0089361eee2a70146c01b693b1ed15579b375abf505fc8d98bbad1ba98b86b2c9eac250bc81fe451831d3d60e8588125c70851022ffc3a9ab877876528067f35e4f4e5af9eb87c020494a0d19b9adeb2946aed05c9024a587ec5bde7952571585886ea4f4861cc60c7c63e7a0ae73d08e6095de00f3f7c61c34ef661799006cc1714aab6a4ed7651f40b91349edd8021049c0e6d8da9554db2f8cf8afb7ae6698a011f11b63bb9493ed0fc128fafef72335fd014e9fe792843d3c5b92686930a4f2aa7f75034c336dfdb0a68736c0f449301ba3494fe5557e3155cee65bf45b6ac6557b66dcb630e3eaa9665c3dcd8cfb9fd498759b6c9aeaa6f21c9b752defa6442dcdd6f072efac66693abf2eddfe007fffa73b7bfb03435cea5ea19f3b9c6adfed0f1c6a945dcbc5dbdbbf9d769ddbbff5ef5f326743b9a3cc0eeef2d96fff931aa02d2809da8156a011a8023aa07c940aa240400eebeca7d4d294979cdb1f18b73f3094fdd4a20e55f65ab44c95bd3aad6b36555e70eb54d9a795354bcb6b65fd945ac814180237e0057c804d3e8beaa75479c951f6832eca5e5d79c155f6a5497fc0d160d0e81973349d4d90513266536322cba64a232763faed0facdb1f4ce408189397c7dd18603fd288c72cdbfcdaa719dd48a3e6976a1a19f46133eca7aee176218db2766e7f50bffd81c1b2046cf18680e9dbbf356eff360deb5352befd0179d826e5240dbe7f3635aa94a8b4ceffc8c1bdcda64d43d5c8c3aa14d5d73543733432cd7496587c5f0f5324cb2366e76d252f5f0b5324cb236e878e282fad06f9c9b288da61f493972d05f9c9b24dd176f2a24d3ffb617513a112ef0e7ddc9f435ccbf51efad80ee8233348e2fa42345ae14e9e180d57f8284f8cc62b7c8c27467663f34089eb0b1f47129fe0891722894ff2c48b91c4a778e22791c4a779e2a548e2104f9cf7c325f2dfb4988950cd44d044a866226a225433113611aa99889b08d54c044e846a262227423513a113a19a89d88950cd44f044a8666af4c4726a7c94b234380a0c3bebf37f5c9fbfb53e7f6e7de1f0fac29ff1faf2fac221657dfee3f58593ebf317d617dec6a450f6fc97cafafc271eeddbebf3ffa9accfbfbb3e7f5ed0ce7fb93e7f1549164e2a2061e1f0fafc39ffea2a96849c13ebf3bf5f9fbf81c5feace0d5498fcd9ff1fa13bcbeb03e7f59599f3fbe3eff3b2fef2d3ff5dcfafcc524ed87a8c58d58463ee81a6e94a02132eb9c515b51cf78f5e2f5096a12d13e072ac626bf80252e7005b9acb750e120e993f5f9d328eef7f80c828c0ba8e8422ce9e8fafce7dec339bf3e7f3626e0bfb0d0efbc471ece808a04b47961b85f8d40fbb8d281aea92ac6350b14ca07e5bb692157e1e886c5e6b303f692da48bd4e4015e85f7f4e310938d9886d6750e6b10e3634c93240ba6a9736e322297a37e81f5fb03f7683fede70730b251e824705d7b9a66106ba607f647c369365645b30a7e7730132de5b0cfbf1edb80ca349faa236d13c491a31c6fc0ec67f18bf7e47bc91ec77f8f71cf6f80f533dfdb9a8eb5cc8bb9cfd27387ef05124d1ab7cd77f17ba5a84e51f3cd1f0114b9d0de842a74658ce73e9a9d303a914a578656fadcf27a7114ae16aca289a113617d6e73f80d1366da220a09077a72d089fb8beb0b0be706e7de1a3f585f3eb0b1faf2f5c585fb8b8bef0c9fac2a5f585f92d0fa4f8cd0a9ad865399f372783df9f5bebf367e7706c1403ca1cf425f8bc9cc7bf97e7bc0f7e902f8a0d4a783f6fba966cb9a0c84e5f2788330972af3fcf27f1c99983494e7dfe8a4534897c4dd12642363fdc4d1eeb2773734929f02f513ed21201971f90c7d399c479445a2fb91b2bf46091f7236478e746271aa060bec985fbb1a43368f6eecb303367a40ae17e79d76b3ae34fb32bbfece9b2c493ddf062d1f476dab86be69b10e0b4dc0bdef50d70cd2c4a0eb0585f949c60b1be2839c2627d517286c5faa2e4108bf545c92916eb8b92632cd61725e758ac2f4a0eb2585ffc4b5ed7cca2e43c0ba866d235b32839d102aa9974cd2c4aceb4806a265d338b92532da09a49d7cca2e45c0ba866ba6bc64c75cd98a9ae99a53fafdfbab6bef8d6fad2fbf8f7bdf5a56378f1dbf5a54525917d647de98df5a5abeb4bf39c484a31bfbef4e9fad21fd228de5f5ffa13f048c93eb37eebb76979efaddfba8acc8f64307f0f29fe2383e2afebb7fef7faad2b409a2a082af269068fe339b38fe0f5d56c95c3d491f6cde94bea3dc56fe2538cf8d7a0d09fd797fe8225def05a169a5f89e645e4c6f2fe10d2f13dbcfd6b92e8ccfaadcffc8a24b37f870dff57af529fc6b2f9539d870e86d58b65cfafdf3abbbe74d37f72eb8b6fe5f6cd25aa1daf6a6af52455925443a2fac6d5f55c78db5ad98d38febab9fbee9f936fc3aebdbb73e8c153e14ff0aff8a88e7575eef1c7e1bfa04bffd135fa5f6228fb1d8e7d4784d85bbfc7e7c987893f4c74f5002e1df67b4577f75f96e83fac2ffdc61f34ee9f8b70e90cf4d90cff20f4f1df7a0a9f917b0997ce789f256887749720f0fa8df7569d585f7c5bee0f8c90fd2136daa7fb05a3c5e47ec1a513de17e13fd79716bd0f553af7c045982829f7127afdb00bdfc05b182a2077184a80400ad3c077182a23771fc2135becc22ef02122f53d74202e7eb8bef8d7f5c533eb8b67d717ffb6be38bfbeb8b0be786e7df1a3f5c5ad3f89e5dbe9408401e43fbd8ef787f5a5c53984838b023942eaa1f5a5f9b9440ffd747de9d89c87cc16bde1146ee7924cb7bf9f31a1f2661d8eb276da9cdb51d6b6df09e763f259dcb51752d6a7efde1d297dd677ed94943ef78dbb26bbb7e2b7d44769f67c940fda47991abdb1e43ad8e25b12bf11e32716ea2e8c3b4662a5a4881658d70e247278e04195cdb003b594b07ff2e877754ffd48fcbb68f8bb78004b1125d7abf973a6f50b462d5bb60fcadb5009f0ff25ccf6a812238674bfa27423a5747fa2745f22263e2dd9ac986c8cb26ed244c4e3f47008490633710607e5ad976c8a704b847677fd903c9d06b7123c70a798245c6142d59447ea770387bde6f8cf3f4531f95e280fc799934e29cc2d5b2ba048eb66094ef1f7c8d37a3f2deb4cf63ac14b31937859caf2647c850e6404cd8c881b038d8a951ab5f63a7d43fd13d82afee898d63aa1eacadb235bc623c8a068bb650eb8fb8643ef68c8dd6ea5badbad3477fb8f9931c32ce599f1f1426d96cd58cc524accb50ed49467cb16d39512654a891da8b11966283f365d6631e559d376941fcf32a36aeaa6f23c248dbaca4f9975c0cde71dfe31333c89200d44a1a0676718c80001c01f580bce39fc95fb5c5d79d1353cf54bccaa80086629bfa0a68bfa324bd94755d3ea76e285af68882730044ea8d83eaae673caed739517a1a828adfc7856d947eff97919b5313651af93bd298e349e3d62db128a7caeb4314a66b40313395c6a094a92aa5cccb79651f26e9c6ccf6b07b419a2d26eaeb55729ef3f263d50cb208f6d9b91d2851d66a30cb9a6704cee9669509b3929d45be90ba33bcacc30b203c08d8f170e98520f986b10839599ab129b554d436586612e7f9eea08639a2ec139e8c8722d32938283a4c1e0bc2f85ccdbe51a84b956aa4b4b92a78a620251c99c5639152889ca48509b34de5b0a9ba660c3618acc419582cae4bda1eb9ef83eba7c656e863977b3f9dd749d860b30370c1c86fbc91e52a0cb573096f30c73e2982b8eac3897fb7e0cc17dda1964f54cbb6d63da3916356c9d3a6c23b69cc56c570f857740c36a57d2028a97257ed836db96c56d8be16d794003de9350814776e3d643d750a934aa4ae0b409a3f850cc3a0c5717bb97bbb5a4525986d4bc3cb41cf16048f0f2f0f2bb646d5a9735695a8cf929a61a947bfb288e4a90c084fb2fae92e02f15b0996726c4dedf4726af1ad9c813cbd07b330facb6c107460d6253c77f5a66156e13ea08de52e69b7ac168e27345eef1cb25a915d9d09b459dad7bad5469a0cdcdb4a44a8dbbaa964a8dadeb7c256968d14dbdcd53cc6695fbfd36a3d0bbeb269cc7d6f5946673ab9ab46a02e8bccf4d8a42ef6e80ccd03b7f834a4f1db153bd3b769a77678a1a2e1e9f5ab6e0d73b3f55d3953a9d52a65c4353a65c5d53a85be5e7a7361c562f533c40d5845fc39ce1092aabe0453e07cf14358a20b508228b2012aea68a2012fee845105904814590550441451052cc1410b846129e91b02bc860ea14d3a7a8d230bdcb69c5754c8b4e2bb6a5c17744f9ea6de6cc580e9d561a0cfeda6ed974bab966fc0a1a4c2d02f722b02d02d322722c02b722304bab48cc416430a5612aaea3d81630501a4cb1d3bc685b78a0ea268355768b5659ecee112a6e2c5e65827cb3be1ff4bec0e7c3266e96ef07e96cd7b1683addfd8d2a49c2d115dd093226fa345cba5d4341a685a34c70e52f463ea6b9c258225378abf2f17c90312b5d2f3e65aa9a5dc2537a2e3eec3d53ee576f334bde7db65950d2482b342cf3ef1feadddb826ca81b70aecceb0c6cdb7706aeb076b75d622bbdb307689a67167b5c035e5d69a052fc0714d4229eb19df4ca7222df0f92f0cb7623a87721a875e350ab752150fd9a800591f4cb66972ef9a505504f7a64b319347d0608ef5c892736c640febcbbfa5fc7c78b72cf6be161357256d2373e32a3ddf3803e680f285815159a66555468beb30c2367ba55719215ec0d86e6c6f28242cbdcded0aa80fe9b687098ba42ab265a1c6070584c312b8e0bbfdce0b098a2321b2f324e6ff34fb65319e1825546846c95112e5e1d1f2f70153049abc22f2a82bfa80bd2a03e2a23be4a90eaa9a53212d28ce4502e74b4dce898393ab1a76f7cdcee7f04d06cca5171311baacab80d85a69368c862b41d8b0a4523ca2942fbf946949dd7884a9a0f612b4ad5dc3a33aa4c51355d770d5b51353020f197552c061753a60b3f33cc5079826dd3b293d62e09334aad1615552f2aaa5354d44a5151a78a8a0a7548ad42cc7c52ab8aaa2baaa3a815459d52d41945ed1651f3015a4fb976a88ca94c1e9c52d77daa1cdb587c36648c129dd913526b4b8f331de86a94918d0ad045499290b2595b2effa17874c6d508c5256f7d1c49d74cd7b2fbfaf9b93b3829a9331b1dca3a2df493474821cfe179c14a81bc9aa8acbefc977ba54a3e8bc2d385e3da7ba04ab0d021f7f3a969d6bd6894fc6696af0ad33dc4dfa0b64d9d7ba1d656da04f8d1fa95bb7c3163d1c6a4cc6e102b366cbe562399edadd29067d7c512099c084add8c84b989b26255062535d34a8451f5d765d44c8b258afa2b33b444417f2f91aa25cb953c752559de76a13ab3cd446e5314a44633756310359af6664f1fe8b3e68c39676ef9dc1ccdb9d822f528b52e8b2eac029198bdb1559d7b48c1e84af7684e7e8f211d9fa65b3e177f29b449efd4378e88670b646e8e84535e95ef0ef1eb5848f8d763b6f8776a314985f64ca9ed604a090369377c1a546628cb370dd352ca7f3fcd0e304351dd323394e999af3e7098a17cf536b366825f56516cabc10ce5c0f2877f3fbd7c51813f53cc5074cd76cc0655958665da9ac12a39e65fb802281ea5836814ac7cf5f60c889c41695c16970472404498fbae64dd700c23bbc9d8e02f75a60e6a0364f09720865f812c7ea5ba657e0152f9551fc89e13d5fd177e61d0fe20b332e7b78577556122dfb61afc0255e697a837bfd4359b5f342c7350f3b6100e0e92975edeffec082908760578d5fc35d4f096157c91855df0ca596cd2b4583899d45ddb210d8b5598cac29c0c7c452d5665af11c7246546265d5d6f12dcc5c8d4a2afc3cbc07756b319c16da296a0b04961b84842826824059047019e76fc11bc82127743a3612f9bc35e36277ad91cf6b239d1cb642dea5d794f600efbdd9ce87773a2dfcd79fd6eceeb77733a5351168a023928654e3cd6990a30e26c38136001a5fb07b55d8925570d3c98b6cf880cf3fe099be487f0e5c20334f93e43b8fc5fffabcf2083b83f8e63b094ed037956730d80758e40ea5eaceb2a8ce083a76492cd129b554c43b5c92074997852f49e56cd5478da175d0c333717aac11e52682c7fe8f977f1a31bbaa7f5c4ec7eb0fe0cf47c3aaa63f8f6e96cdde0439ea157ea5c7968ce1b00b6d719c48ad23ddeb2b0265645d4aa7f1373f2513985d4f620f2c9f9b2c5e874da3233f188f98a2aefe9fa77fe65d6334dac6f0a96a2f579ade827bbd8187869ba89d60856a7f127caa5fb4f34b80daeefef1345a9cda00e5bf13c79736dc1e3ac798f53ec3ce64fd3bff1ae36f42c6b7c1948fc59d6f8f401eec280cbd46759ab79cf122d4fef497a37ded5fd7d8aa87233d07e2b9e226fa82d788aaaff520234176f24bfe4bf7731beaaf045069bdb6075f9688a3b31f179a1fb543c2e712d2eeeefc352c593528de58b5bf1a080dfdd3ea3523070029af1c74d71e35dddc593aa7ff581bd7cb1c2471a7e9df6c8705b2d1f2e3972f7464befcebfbccf63a5503b5c87bf5fda92119333bbfb77ade93f473052bdc728aec5c55d3c44cb9cc6ca5be674dac36b36bd8707c2fc67e7dd7857f7f7c959e6347fe774b6255f389d399b7de7642b082ba92b082b692b08f945ea2455e82e41c32d9591f09d9c4f36e17630e3c8169a72a1caa317c1abbd6fd0e94c352837eb68ccbac35f830a2b4f75cb06f56d3dfc35e8066c3edb6a183461f9e1af417d0bd095d882fc829be7d2472aabda66ad47f9fca5df5ff02e368557ca4167839e7908630b4bbffa40674ac334e062f9a2b27cd361d6f292623b7f3fcd97953a3396c3a695c6f287f0639b1b5b56aa344ce0a9d80eb0022e8a9d76f4a0742969dec2dda73abf39eb4425cb44e3f3411ecf22172af704779d79c435a406b3c94cc61252203ab07cd1b1683ad9ab8c4d3f9805a4338477624d28b7e5abf0a2d2bc39b5eec2722d519c6184bf696e0ef5d39602c6397aef6c0e96b91610ce10fef2e7e0976b05e50cc15124a3caf956a742c79c816f404ac7f4264d1f4cc704735e37ddfbda3d51e6f2475bdc49bd9adc7d4fcddfe7784d96f2d72457cff36b7277fdcf9bf6bea72b614748a101ed9d32e39db6b4d3cecaac67af7acd5af19ab9d8356ba16b465e5666292b2f2bb39995d7dcec9a56b2bd16b5dea799d8dea2d66d31135b9949357467d2b6cab56e7efd5efb50eb8bd6e5f649a5b5d4badc3ef4f57bedc34aebcbf6d1f6eb4aeb72eb66ebb2d25a6c5d6e7daefcf7c75fffbe7da87da4b5d8baaeb48fb68f7cfd9ef2df1fb78f7206407cf5ebf75a4b4afb9dd697adcb4afbe4d7d75a3795f6a1d6e5f6ebed23909d6f1f1d574aa893a54a54095420457c8e484aadabedb7da87da8741686ba975a375b37d14b81d819ff69120e1adf6116cb04341d23bad2571d9baf9f5effffbe3d652eb7a94cbdb787bddbb7dfdebf7a026ed233c21afa5c475143a094d50ba902be408fef90ca8d655e428f879dc042fa5fd7a2a9f7b7ebaf98e526947ba39c51761c2a36f7dd13edeba2162268db58fb63efffabdf6f1af7fdf5a9a20a3633b5a8b5fffbefdfad7bf9f4831ba36ce68a0fb49e80364f36cefc24c6bfdb975b9fd2e307e713f196b1f6e5d6f1f6f5d6f1f691f6a5d4fd43f64b9b53e86f72467b910b0fefa7dded573cbe348bb30f6dfe75b37da475ad7db870578cb29d72bdffa038e444b5fff3e7ff9ad0364c1c8ccd758490d011893293a5a7793c140b57f19d48aec3556f18bee210550b7b55400f8c03b8c94088650242af08725c3a4e29b2c168d3dc215e8b23e3314ec0ac6d8f6bbad2f608093aea06c7d0903ef0e18d8c87f7f0c031a1fc1da8940e2fe8aca6cb27ac095b4165b375a4b30a8a72eb14c27a9851805ad9dbade329d440d6bc487e7b4b597f2ec525813f1b6a72ec34c23688698f03e91ba2053646f04a88670aa187f52b1aac8ff366dc3aaccf410ebb640accd54c4da9421d61152f88969d0594b79a636cb262dd3524a74d672306ca7a6eb4a896a4a89d58095f263d39a9c6486412795bdb3b6a39498aa29cf37558b4d2afb69a536cb545579a546ab93cd1cf11db868940b3245f04e9406924004480001c81d3977016000729aaa4af6b9ba82172feaaec1af44b5f835b32a3566f19b9f50975f88c89e9c015567f385f7f4a27b8220a84689590ab0cc1dde5344f784a6564a4cf9c9dd07f71c1c240e7c6df9be369b508be1cb0c5f6b426dc28c1dd5721aea4c71e06f067376d9abd4f5309d28413a42941da4930bf865e1bee799aa6ab384d6bb78e87f31695acd0c3201afc45e19295908fd8daa264b6116c26a2248a836cb9c1a9d4ca1df20364b816623a45067b369013d39c4691a64f9533d217f84149a955a53d5aa8469ba46559ad8ef6cdb7e204f8daa09882282992733ea62c3852cb336420a745612ae53ecb54866a9b84971d632cc043355f5b68448b34bb80e4db223c4dbbd92dc0e32420a657db6a9aacdc4fef36693179bd49b0653d54def089964ea1cd58c393a39a7e9734d559d63ea1cab46b687c018615155836f0bd57d7cc21721d88496cd19461e1dc6b1c3300132d4eba6a137896b33956806a998ba6efecad5a84e5e65ba5d4b609d9c513ecbfe1ad98124f60e766ac4db8ae0c0654ebb0db29b8c25f3e05fa130400a7412fe6a3afc6daa6ae88725fe4e4a7e0607c9309d248e49868726999a2289554305f94dbe24b84119c3ac0a4276ca85c4cfb3d126495f99fc30ede80c9e8d5b6886c8dc1ce1d78f87ae9f085d3f15ba1e1e92738c3e0dd07a17a80d5de3d121aa1903e449f821a6459e868b2487ec352ba13d399a3cb45bcce20a8277413bc895f699f29e32564e1c0b14bdfd6e6df769f620fb7680ec6a6ae404352d72822c1e9b9d23201b1301d99817908d7901d95223e32703b281549008f23c69200c6481201001ec81730e27b1bd7cc3506955a953fc7134cb865fd3c01fc7e4b79316831f7df986a576b5027c6d81373006aec011d8012be493cf976b2fdf50ea547134c53414c754262d28fca0fcb75bbc1ca6eb7a9831b538115d143336ad1727eeceab8ab1ad34a2d22a4166d9f1f3355237ad2a33b268bd50f78de5bf8979eb14e270047d8d5497ff66a5b18d1c382962388dd969d45bb91fdbac6747cfb7359525a023be4a93cb7f139b755802e3867663cb09d01dc89c3cfbb19d6469f4013203edce54072164ca43e53303ba43fa866c5a4d702d8972f5e5bfc17723cd19c8b393629ba2bacb7f4b66795e40c8db2406ffce4c55abbd4dc30f1c4504db212db3c26cfb95d048b3b9dd8be9278c1546c85881412b94781070b064348359defd44ec6dc25d51a2c83e0723bdfb45c47da288ea1521fb69d523afe34d92168943bb2cf7e36041622946b264c99752320dea0472f86d92be1493847431593c4d22ade94b7b81d6ac4018de25a99b31594016138549466122f49626cf6b8b6f280b9dd336363441462209c313b2e3a054960a50591a407d8103d4e704402d2d9fb50e287b11a096a8a6bc0000f50500a87b3940dde703d49705407dc903a8a3ecc00600ea0bd42882d86220b3981459048145905504414510b235c1aef69986e1d0aa021f075a55463566d878af39ceac59a929a3a661300bd39eb39806bffb681dee731f2665169592595446b5a252d28acaa859549eb38aca3e9a33d8d53e532999caa8a6943465d4549eb3eef5595219a077db61de78ace0bb5d3f5063aec3885be7f3f93faf59d993e8e98e660183b33825fccd59c421af7395d90eb3b27987970ae8cc39e030c38f6c1a2e7677e057cb3a3a6ac6b4d2c210c1b8daa0d422fb38bc4d02640fffa61100c2957c3fd38030ffda25b8d47271f11131ff00260391e6e2a2e6232be5a3ca47d6cc479542d603d3bcf2a9609af5c0740f4cf7c0f4b71a4cef75d2e1f40e6c3939a25e3e0bc0f14140eae5b33d4cddc3d41e450f53f730b5a0ea61ea1ea6defe987aafd343d53d54dd43d5df6a54fd4c2d0355576a3d3ff583c0d41b86c43d30dd03d3febf1e98ee81e910550f4c6f0730fd4cad07a61f34988e04890fad7d2facbdbf7661edc8daf9b5936bf36b47d73e0a77bdc2da9b6b17d68ead5d5e3b9a46f0c6dac2dad1b5736bbf5f3b1fcd38b97671ed7758f2a3b5b7e3996fac5d8c26bcbff6f1da91b5cbf1c4f36b6fafcdaf9d5c3b17e77d69ed9db5f9b5dfac5d5efb8f38efdfac5d40c1ffb17661ed8db5cb6bc750ed84769fac9d40a24b7282236b9facbd9ec5e1bdb573282a4cc0f3270602d4146beb936b0b6b6fad9d5b3bb97679edd4da7c94e3a1b54b6b6fc413a1d18fac5d5e7b07db3996796cedfcda5bb2c4a36b0bd8386faecdaf9d8ab7dea1b5f36b2790e87c3ce393b5236be7d60ead9d0b5727128c5f4d0d6fa1a685b7c815c7510e39bdcb0cc898412290a1d7ea8ad7c28ad7aa8ad7828ad76a8ad73a8ad71a1b58b61bc78177b7707730c7795ddd8fe2cab96837ef2eb83ab334556375ef6bb6f6c6da89b9b537d6de0c7fcb34fb67a5c8f67ccd90edcef7223d41f1020e984897b275c2931c615c335d6b40841507bbff457356b265489be494e407647867e6414c509dc4f12ea97b50221548df25b2f185ce6b6fe01831bff6d6daf96e6b9d71047e6b6d1e7ebbad7516211ab25638c3608bc3d36fd72e745de3bcf6e6da021638b5767eedf5b5737e10887bb9d679edd4da85b5a36b17f10b7072ed5c06b616c3dc3978d7d340f6da6fd6ce21dd111c93e1e5ff64edf8da05680439de561f26f142d285d1f814613cfd0f39b77a9cea3c7938b9331169a0aaefe183819159caad26a39471c405d2d0b3d65e5f9b5f3b24e7a646a97e03ed975c302df44fe5520a28e41c9a627c060ef369356bc6a9b056f24ed4b058830f4dc120c183f5a60d3f3cb768b1864e2bac6fb0736ab03a400a039118ca1111a6ed78a77f6e56c800cae89c4a159205fa9f1c40dcbecfdd1cea1fded90df60fefdc12dcdf0beff000513f093bd035fb397129f9148bc7851944336c871a15a8925784cccd9197b1758b0dcb744ca871d131f7f12e5da1baee31c5da8ff127e1179f28849daf0190647a1a9064ba0c48be64d635033f10cfa295bc727ae5cacad2ca97778eaf5cb87378e5f3952fef1c5156e657aeaf5cbd73389efc47b8b973ccbb7defcea13b87572ead7c11caf72e4faf7c79e7ed95a5e8ed1741c9b757ae01f73b47ef1ce3496756aedf3974e7d8cac59545142d28ffbc72f3ceb13bef8493fedf952fe354bf5db9be72339a98e9aafd313334691b5cc10a7d79e778b40d42c97f849b3bc7bc5bde069faf7c11ca5ff90dbf3c8d6597bc1c7efb4550f238b6c1dba20d8e076d705d544450f23678239c046d10a3e26d1049cc6c830802e43d68bfc971f880f0fb4b21e0f7a2b459401083cb2ac98e278786c05c8c03de0c13bc097cd0c751607074b0e830dbe9e3f9453f847cdf90a772513354f6dacb937d0540e285fefe7e78af0707813bc6958711991f2622264bca22d43cd2e7aa4ad07bc6a26d51c4fcbefec45ee76ed837ada1f2f24fc1fad1790fdecd45c7161d5974607ef7a6df65fdce2abaa9e89aa22b8aee27ba5c8e8da62bff79e738be2557566eae7c82e5ee1c8777fdcee1952bcaca59e8af778ead7ca6ac9c5db97ee79818653e5356fe02ef34be127803afe1953b47a19bdf390e8cceac5c58b9ba7275e50abc41792747b836420b2efd732119845c5f5914b280ff9595b4388f31f318b8224fe488fc901bf2424e696f639a45667b2699dddd26b3c90fc9f070d6bb2838903da4b0b2b8b28891d756feb8f2c70ddb692146770e798cfe226124ef941bb36afb78367984140afd45c744d1cf509bf5f58f0d4df00162653115ff45ec6c324206c740d389f1f1e29e953fee819fc8e104f93611d746ea75b237c51951e3be08493ec97f7e784e7f448a22d109ab247db6498d9fc40ca37ae5ccca272b8b2bd7e15524bf3ed8cdae864f3dff246710470ceb31395dd8ba5e5958b9b172fdce911496f94f8ede6814f45c11b7612c22080bbe5cf98c7fe2a1c1006178b36242ef94e0de2a9ba4aeeee494f5d9ca925cda67dda5e50cfa9de56f08b96282c6c6f52375b39e7dce31ffea051d0f97190c24b5e4031cc25c400175b3ee9de52d09cd1202e922dc64767c127e51a48d86de041814e7298f53224a799668e1d7070b03de48fc30d88618d005c74840779fe12889979fdf3952e84f1baff23a6fee1c5db99ebd555dc0d2443847fe3d06107a6de50a59f9547c89afdf397ce7d4ca17027f5e499d21cd5b007d322b1757964088a0ba732a756fbbcfe882d471b3b2b87269e50ab9f30e0c3aa97bdc31fbfa1d79084cc1626591838ed4fdee8240c2a61454e9ce11a0fb845fa6ee7f17241256cd08ab3b27b12d97d06a913a6da0721ed1e72b5736bb337ee533c95429b25ff96cbb4c95daceddbb4c98de73996c87895266ecfb71aa77c2d8b1efc7d94bc39adedab0a652a256a5e62f0e6b2a2fb806535e70f5a664715825b1386c2351765ea00688058920cf9306c24016080211c01e38e7307eb88351e1af8cb2df6536fcbeca54835fedafb9165e3c6769f0b38f3aaea5d266eeb55eae01cc813370057ec00af8e45cf2e52a2553d9ef2aaf32657f2d73c9d73d8fb2b395f038cf72aead5acd85b074bf8967943add30f17eb36e5a96399b411a45c472ba3022fe05aed24a171f996f7a91da8e870de5e45b39d194b96ceb613cdf510a5222276ba7029294fc3ae75017ab9053608730afa598431c199c8a3610eb49a1067a97520106bc785268214e4e4d85137ca09242097e5c672a76c07334371dd2d276e60c75ce52e79c5abf7ca9d506834d02401e92c07c1f92e341f101e99038331e2135068f776a0522b18e44dc454e633b59343b91068f5a4fa579941f08ca8f63776a71fbe93b15b1103ee53d50b53d40d55e37035451b707aabe95a0eadbed75ec01ab1eb0ea012bfeaf07acbe53c06aafdb0356db03583d931a0e9a193b2aa911a17bc0eabb0aac00dfec2895768c8eca811582a0d1812c641526c905ad64057ad88af4b0550f5bf5b0d51660ab74a0f24c2fdef436012a3f2e6700956ab90754be9540a537add643283d84d24328febfef2842f956797f7e5cee81aaed01aa7e927ad6023376685d8e5be881aa1ea8f2b31f6868811ea64ab6490f53f530550f537d6730d54f7a67396c174c95be3bddd8a14937a8f730550f53f51c553d50950daa7aa0a9079a1e3868ca4020bd1d68db0481bc7420038118077a08e45b89407a8ba57b2884f45c3b3d9412d6e43b8a52be55ae9d970ef480d5b60056662aac32d330d514622a5399e498ca54ead4724c8502a6829b295399720d0dfeea9aa9d0bf5f0460652a36475696a998d38e09bf06222bcb5454445696990f594d510384835c900a224122c84369200964007f609d035aa95a9d1a5fbd612aba6ba85823f8cbac698ba9a6f2d575faf78baaa9cc3043c5049b96a993a66d0257a95a1df8225764ca19023be0940f5ba99aa2bb4a9d2a7506c59519a6d80fc8bdd36db9f4e8d80e4a543681782873d5b484328fbb674ca71324bdac7cd08cc7ea1ea38d89f1f1a2333e5eac47a28769f6cf4ab9039b6166b152a3d65ea76f2816da8cbff28dc2466378dfb388718da253ac17f113f4b3e2fe62a9783751e368c06caf9cd9ddc0dfe74d55a37fbf48a65837005c32ad6a366514ffcae9c2f8f7798d59e91c23e8b7416dcd70a80780e525b61200374cdbc980c0d47040f394e8de361e8c634e6500603901625cec9309781dc5bfc9a208716ba695281802bf56b218225c07e1fce0a0c16000742d033e4a5fbd011f2edba136710f680e250dd3220dcb9cb6b5ba5b37539032b04a0841345c370d9aac5618295349b59afc4b94ac960f9421736ab34099a69e86430bf705093ed90d093eb92548d0ece1c0ed800343086bd404aba9c00c5604945504d8525468d982ab66119016fcd18b0aad9a45c05a45c5ac3845405b4545d52ad9a7eb7154c4050428ae0c28ae19a0b8aac9415c4580382d02e2762555e791417793b1c15f32830d6a0364f09793accc2fead4e217b46c79294d7e31e51ade852e68aa26bfb059835f9815875f18e60cbf50b5caa0e645ef0d94788555d96b643719fc651f339865ce014486df3ab50e9873b46c69fa5c9d36cd3904c8730890e768d5b41d730ee0b1062898cd9915c7855fc39c1129aa561157cc60e3e3c53dc01a7febd4c25f5ab6c47d137fa75c43fcea3cbf6ae2afcd1af86b561cfc35cc19fc55b50afcf60f6a91d66576aa8160a71908587745d45dc1ba2b587778c631e300ebae04755744dd15bfee8a5ff75cd641a8e377097f9d8599a2ef437a9cebc11da5526947249ab53c4e6592ef587dd361a6a3da65304ac19da1ce3a12be93376a2e421c553cca7bd8fffb23503da4a54c837bfca22414f1c21387ee62565929079d0dd5c943183160cdba6654d17e65365ae4f0a32d7f64554c9dd9ca94cb6698adcc68cc02027bf9c33255f35bb066bd08acc5c700f8c2378015816111b9e53ce45f353d335653a65c654683c2f7f460523467332cddbb5ac730e619a0fc2a733641424bf22c6d482db779f3aa4b38653f2c71cd6c124a745a208f903e1e5d5944ec45c8247ca3680216fac923a4200b501c8f461cd86e79d5a8d3e52bd4a0f746957c11a63d5dc43cc7562b12589f79db843699b5f50d923fe4b6af08d33de3b7416daa9a5bafd4569acf2c6bfea8462b2ccd74760dd32636ab82799c35812427a873162497092d9f42720d0a9632cd32a3a97c0ec93588ba7c31513298455abe982c59f2544e4e6905b631b393b94d51902e5f49378e217363b34824641dff9f9ba9e6f1ffb9797fece3fb345362f7ece39e7ddcb38fb7b17d3c9a3e8566ef505367d17a46f237c648ce6b23e736911fb885fc400de49cf6715ef3b8671ddfad757c4f57d9ddad859c6fe55d46c99e95dcb3927b56b2a74ecf4aee59c9df422b79b4378fdcb3937b76f276b6937f9e3193bcc3ed4d26f7ece49e9ddcb393bfa57672a934383adab3937b767254979e9d1c57a46727f7ece46fa49d3c847632dfa2bd713bf9896e76f2135b6327ffbc379ffcc0ed649fb461991566dbaf84061bb1537580cc6a4ecd749d7deee4a4f6da00c183d835fb391c792223281857dc5620bbe33d938f8d6385faf2758389bd1d5a618060822612e0be41a9e5e543f5e36cecc20819f3f7a616024e893449e93a576279b1c6f890842a2c2f4edbfc5652a21e9517144ba4494ad742f21cd730509ce31a2aa1ac4a7dd99022295c8b89f6384493542d59540dc96d2c9f6533812cbc4d9628f112d3ae4be81452e36558cb69d795942bc59404aa888ad3ae2ba95c33a421a5b68362fc0b94c7ef92259b31895ea978925398080d44a14f3118b8914e9db6a38e77e6b169d69c18db39016f7c34612492303c918ce442c2dbd5f82b13633394cae660c469e1a4ba2c1ca9bf42fcc39d41b84b5699617c97ac525f3e6b3936df25ab2b750a868b6be05f5d53280f3e62fbc147cc69c7c4e82386177d44658e9d37fc88af02971f122e938c62431b661dbbdb8e59af968de5c51ac5cead30bb4e6d7ee930cdd6f8e5b4a9d70581c1f429716931a63245a72e7f2f729a8f3f539e55f62b3f555e525e515ecc612792bc8572587f64b3ab8879c9d1d162a9544c31ff3845313b1e499c26cfcae104f9664d3cdce9b87ff9ac4107b236638a7d9bf53a4b25f3f74dbeb07cd6aad6358309b89fbe2113c99fd57439d3c866cc67999ec9722ba1ffc338aa5bd476a4f89f081a8756a9ad256d00fc372283004963202f693d3fd77a3d37692d3fd75a2d37a99a9fabaa0a5240fade87356e5de4e6562ae5266de6e7da6ca6936ec42c095925e3e3c554b3a4f8ad9abd737a36c983b64910eda49f479d7a18b56b39d4b2349d2aa66353f8ad53cb79cda40a6d6816bfd7a873802a6c9a6a0655dc030e92d1b27bc071a9a25978eb5a9646157a805a50b4cc0cd54d0b6e110b06e25a4e11847bf38b0d0daeb422082c82b822c82a82a022882982144863d9f38b59eee2b0cb5cab52436554a1b6c374566306bfa4962312e9816948346d87555d7ea15954a78a4e2dd7285327ada20900a4558b0ad58b0ad6f3405131ab45c5d48b8a6ee5749b6b5585ea0ab5147a4031ab8aa92b7a1a9adcc2bd57f72acc08e48f4d9bdc9f3d663163828c8ed18914af790a759e70231b2aaa07aaef4828aeeb7155a42aeb29742912057942d77099cd423f805555ea5a80bdc698438d84b2e1501c65ad46bb90466271a41186837150e78099ce3282ffa86b590c2a9fc97c8b5160995a969be603565da6d3f4681ce8de2565ea1c70a7bb7981d34372b8c021db0b9c5010ddbca6a54acbfa4e602090fa8041255949df090c04521f704dd36999394c56daf7047b447267b0252fed7b838160b37137b601eaba4f91377ac7556f0bd46537eb65532fd146d47d5b182e8c90c23faf84bb5c6127a65d8da43d8a69d722698f61daa791b4c731ed7a24ed094cfbaf48da9398f65924ed294cbb11497b1ad33e8fa40d61da65f1140f7adec164e5fe790528872385ff7915d27646d3ae41daa3d1b44f21edb168da75487b3c9af65f90f64434ed33487b329a7603d29e8aa67d0e694f47d32e43da9057b9c8eaa6c9d413c727538f1bffc71f3a0bab27565fffe7a9d593caeae1d5d73b57f8e5f1ce42e74ae79ad2f9ab483ba6ac1e5f3da9fce30fabaf77e6574f880b24ee2cacbede39af74aeaddeea9cef2cac1eef9ceb5c513a0bfff8a8731e2f4142907ea973cdbbc987aeb7a79261fcfdcf53fff8687cdcdd393454e97cba7aa2730e045e5a7d3db8b9b67a324ef08f13ab27b1025ec2eaadd5139d0b093e17568f773e870b919217a96f27a504f6ffe729a57349e95c53fe714259bda5742e289d4fb72ff6dfb62748c4a308ae1ee99c5b3d463a0b9daba47363f564e7ca5ce75ce7f3cea5705218516c28bae0a084175f1ec88b6d34b0a01757b07b5841f20332bc3373a946b2e61b0e265848566f4b6308e2307265f575e07eadb3d0f9bc73be5b30c1d5c39d2b9d4b9d85ae05a23105b3a8c3c64ce7d23f4fe5d0286cd57001abb7fe79aaf3e944b6a4adb46c3a973a57b2436d7395a496cd3f4eac9e80e7fa317c3de01b20376e827ca23e2cb56f6020259d4bab47fe796af548928d6fe4a493d40236a2e552ad9d34023560818f2ed5e8916797fce2f0d54c6ae85b3df2ec66a402abc752cd1e912d7fec0d8b35f890158c0800488d6adad8c3738b166be8b4c2fa06c7fe7979c73f3f9f18ac0e84974553a752cb1a267c043886a48945c5fd8180ce29e05d1828a40d6b0dd376f8a4ede66b313eae6eb0063e40ef5e8301ac40e7546a0dba9a9fabc753adcfd5e379cdcf27f8522471fac3c60dd0e19d5d0cd0e19d5b61814ed29e05ba1d2c50fe8ada3f83917d372918a6ae53d29cb635324df1afa9d71931983eb57c96cc681a24b9aead119b698ecdeacb670d324d6b2a9bb6a9419a78b17cd6f0c12589804b214d2ccbd84dc6a23d908b2f0c90023032704d0cf5af4013bce2dae0e58ca679d9ae8b57b18f7550bdb127270622f74fc5ee9f0e2d5ef15e74bf351d8b1ab64e9d4d2ed2b298edead8c2618c63cf6a4ea546faa65933310855a8cd48c12e480e15482e6f29d45dd7a1756af0755c8666e0ba5891ca131d2d0eaf8488bc3222ac054b2ae759cfabb666b8aee3698b37696ad653788a76edca35a129fc2b5b8c4e4bc5d572d6c0099ac4496fe35a0a3b89f271861bd45bcda97763f9ac36032f115fc9833772ddd5149612dd654c936cb32b50ca598169d79da6f8ca83307e67a7347f2985a9a40a32b68eb3c187d0cc598719d7f424cdb8669af6cd147612eda30c73ea1d59382798ce30ab4cf59770a8f347bc60747b841448813c22e8778519602523e90763436917debf4e7013cb0c7f408687c81ed217aa70e47b2256284e9091c8b02e52fbfd64d962bf492dd587a7a5f9f01c5aaf6bd3aeabd498ce2fea94ea9a8d496ecdc124c774a74db89866f6f2594ead19fc8ae99863379b584637a729e762591453a64c5777a75d379fbb0ef5e1ca084db81a5c07ae80900ea2512e0a1512b9b81c5e37db350c1710218831285e399a66c3ef34b3a7b5194d9b9e3615c7b430adc1ac294ea553172ff2bad26cdce7e5005bc531950653f46e13e6c2e3b5819279bd59c50c6f56b15e2fa67ab33296ff41bec9a7961d9abdf12b463640c6a6757382c8f58abab7365254e78b0de51af3b966ce4faaac9ea0c816169ebd4e2d74375e2067f9ac011f216342b0ccf600d55c18030c9a4d1df5cea410863d3f4cd35986069179ec194dab8b558c63598a6cfd7ac6e5b3b6b37c36c3e9636b8e93c4d8363a88053c96b97ad232eb59795999b5acbcac4c352b2f2bb394959795d9ccca8b646ed269b00de6acefcf4ac149ade731d80e1e83c9d49087935d4e0df30e0d03bc81fb11962f7a9b21704742da5688d84e88dc1b21a4a78569417c10377e5858d7ad0f1ef85169d5b594faf28706e597cef2922d12b569915d5bbe26d226ade58bd5ea94a0d559b34a2dbcce8f830c94867240043247bec02e3f245afe105828801397af2993a0cc77e294786f3f448ea3c2f2e18ae5b7894aab645a2f768314cb6f93ba695535238b388e28a4846144b1fc36a94e2d7f68a5318d400a7bf9e2f265db71bdddd5d3fabd06146e3d7bfa0835a286646fc408294c2e7fe86f4f94c089e0a82a2d7150294e09314dec8e769287ae4657c639490e358f83b37cb19ed0cf9f2e82dce439a9aa5798bfdd6953452aad26cb967cd5615859be9c2c1fec95e61449e59b9c87e390e50fd30f7185bc1edae0954f451bbd9862db036d58a968c3ca401b331ab394c9e58f662cb8e0786386c78d0200a00102d0749d390a3597bff001078f1a658aa8512268d4f24795fc41a35078918b2efa828b51b9c590d448dcb3e58fba043ecbbb31018f34add4181e69aae1e1a39a526756c562aaa64c3157d5bc034d3505067e35b74f46d5a2817c9855048645e057045e79c3f884ce349d6299479a7ef7d624e55e92940fadec75a74cd752ffbf43a76bae4696ffd20db38cb23ad58c0cc2285e91d3c50fd54c61975ceea232cb48a7df4a98a252c3ce002a9a4e9a247505ffaf5ca6ffca65b638383e19bd2476b27c92408472617773b83c14af31d74a940e82b9406e6a349729c9c9f43e5099929d4cef477331b58c702e924c3f9a4bc28514c47231367fba3cb3e6729e2a3f401accd24c3531e9ea4dc8a664c33fc01e2f8fbe3c425e11cbd85881ccd698e161171ca7c90fc9709194cc1946e0b3c7277234c3d65426e558d6cdca3499342d52a776c5d5e16b3c6b5aaa4dca4c37678bd242fb182335c769d823838355cda9b9e562c5ac8b4fb3f7a3d9b6cbecc1471f7df2f124133ebf342a9b5e229263e9bd93f4f1647cb287149825c22ff9e829a6e2ab588759cda9852a56b568bd4e1dad4275526586caac11ec2e03c4b1b43ab31d8b0d60cf4bb254d924757547a26fc6e421cffa1fe959a3a3d226c89850dd48ebb05ccd33c9ea9a91d63a360ec792aec3559c4dd7fed54d6b6fb190f6e192298b32bff180dfea01feed01f89f49df4f61eda8a46ea9e8a1fe1eeabfdfbb907ba8bf87fa7ba8ff41a37e767f60ff3704ccf670ee86b4cf8573d341e333bd75ecdb0536d6b26063ad071b7bb0f17ec1c6ae4bfe7ab0b1071b7bb0b1071b7bb0f15b0d1bbf55eed1676a3da4bb1d906e0842beaa39b551139a0ca1a477d49ae51415daf071a47fd29a5bf54e5a9bf64124b3739cb4f62adfea1812c517555ace4617554603e73453117b3303ae1b6c965a9acd8f05e397754ab92e08daa9c6409f2628d4144b4a5d9b1f0d165f54aa798b4ab5dc8b4ab7fc5c30ef31de93c3c142cf6e6bce09f3b4dde46161798d12db609aa1d44d6aa88c6f2f82df59931a78e19846955978396931a62ab6c14c23f77a5aada8d4cda2e2684565167ecda232691515dbcc698fecd39492a9ecd794574d65bfa93c6729fbba9d84f540ed911da5d28e6fa03d825b72a64ca612b39e61860059dda49691410656836f34c8c9840d02dca65cdb61560a3bcf08c175b89f4e5acb5ff861c753387b66c816582126b3b297d6ea4de90e9d82669006e3277d807d91240aadad9512a081a1315c5bbb7cb34bccc964f19a57dc6419f60764268aaa5e51952556e48617d5264b967c9d4df870645820909d3435bce2531a4b5f4f0b99a0f5666d11db61736a5e6b242dd6490055a358756e8e84ee9f0addff7037d939c44fd172389a55596af0926f3c7e6df6d0eb8344af71fc1a0dfe51f8ffd97bf7e7288e6451f85fe96fe3f80c1cc308618c6d76bdfed8657dfcd8d97518df6f6343683b4a9a66a6a599eef9fa215b1c9d08099987d7668d6d64c06040b6047af0107a60214044ecc0ef233b64a1f52f3df7bbbb37ee5d9fffe18bccea775775f74803967d45049aeeaaacccaceaeaeaccacccacdf10a53a2c6b996d42e66589741435cc0292ab0e6bf4789abd728726558731d3c7af245282d921519071d9284aa45c84bb57ab0b72092e7e5b5d50884e91403be1e5ea4cb94828857d12913589e48b81d2fd042e91c2efd45289c805fbf1b4334e0a760e206ea39c3b7cbb4c3b3c3bfcbaac46b97479745873987138c90419708524a0beaf3a2eec53cb4585c8056c0005bf35ed7ec04d0ec6d570ee7e5d1d2779a2bad544f3df09c5bdaa3dae70b79f1845a2291cfade10ec53cbd81bd37968d80520e55081dfe25e95f6cce02004d18aa2a3d86c6488cbe18922a27842680a5cb79102d367c43912952de7eff1dfc408b15c19768f7bc51344f7046fd9c2e61eff0d576264088c31f2629cb898e0ea9c282ca695151bcebde8c88a71a2e2ab8a229b022924888a7bcbd5618d7416632003d2221bcc272dbeaa28d57181c85cb8003a5d52854e221b523b0f7583e222475a04d185232a5249b13a23e845392a08ee11329dd5854a8908ba2a77caac302c5b52645797f70819a53a239761b1898a89b42d17a0b847c89844d604a2089dc5922a17a2c2a29dea3b162abf47c89460f908cb8bb431a32ab747c894abd7a242a2137515a982a7df51924974107b7b6923bb76ada261be4f217de5224b364c211ac2b2a89a46c584753a6cc1c413ebecc2a784d61d58b3136a1442332715c3d963c2a226c51d2331b204c675c98b4f4a5c2c6c6eeb6f2063674858dc5b165e26aa5c2a4904f7f5337b15e1df25a269040599bd652157bd64cb608af0ef724749b26b14e1d7d531d9f06e8dedd58f0be5a2acea6ec1ab66679168f6ed6fabb715a21b5480c3eafd260a9ff6fdbeea255780a4d59e1489d5b73b8a25d259cca79225a157d0123a43a51fbb1bd0072a538d511112b94659d2a443008ca25864966c61ef12057024496425569494f3d569942429c67d72c99523e572f5922345ca9d32c9bb157e01522e12577c9475101e654d9192c547396fd3b369d9646c02366a1b6b92ec589df60b8f9770d0704cf7e288be42d8b2639e2b3be63996e838e151482b3dc69a4093e44721950029a493207fec01738d0b92094e10caf6bc6c168a3ca9ceef00b1773bbe1e128a947cf0a0df428cb4e8e7a13a9624570a41c1b248e47cb19d8bbf990e11445140fce25b233b8ac090ac2a2c2034377648a44014212fab85e846bf6b916457db67e0a80a911952a66b8cc47a29da9c3a4410460600c71669a299806d8d2cc1f2c6b545326bd1d658ae5e8d1ecaee0becbfaaea0c8f07c19633f3452582d63543ba008d089b424a69338d25f20717377fcc06ca427e53e2dc081267a1c415054abc4de9778822c99a4a77a4e1a24cb443aa483a6c2752557cc7acde84bfa5922a9282aa1baaa84be844aa8aaa6998f06b3b91aa625e421f52de8662c887f41d6fe31fcf06ecd0ec33108126fc2d6581641608668198bbf59fda7d34de7b542dcb4a41154ba6a2e30190922e96abe35aa7aa49baf88eda23e9628fa4c08d5e1dee20f9a48d52cf79540d3a8f56c7b52c2074bc47abc31d69dd4755c77db43a2ebea3a2ff6875f8f16fd8aee1cce854a2535b5ea20712d2ab58218a019be6fc687ebbb58b55deab187bb8485b517d47c2fcb25bf025ce165553d3b76cc5c5a91577acaac33a7e34aac319cc468ba24ed80d812bb2a5e5a34caa37abc38f87135b744bc90a15f0523142d2f3e1099b694744558cc427b3162e1a1b8d36e794c7b60ad1495e4df7841a60a9895272e0ac0a66afe48358979595bcf4ceef0f6ec9984a662b7e1b7730e1fd23a140cf754363a479fe4ffef8498ac06e171e0747902f129625991e02ace8ce2195713ecd6c80b2e31d2c2ba6113de432e051106d6dbb3417895054b5885cecb934ab1ae17a34e7abd7f8623c54f23d9aa36ed29e1c2fe9d15acfa339d2539f4bb3da984fb35f7effeb023737d75f17323f2559b9b4292bffd0b2b20bca38f47e6d676450bfc6e06191f02fa367f6086d19a3a8e6f3921d1e41146a260c1466dab7855b62535781cc045b47caa308ca485aea26b00619d46c2c753b211851f072881e6d15a686a5e568f3a24bad47d55c623daac6002d8628618b30212864d0c9bb74f2b2eed2c9cb3a03341fa2832dc274984d73ded815555991bcd1835b95d120171e3dbb5d64fcb03c8aa0d73f7eba7f0055067fbdbdd12164f40d4bcb19dfe130ff193df02030d1e1fdc6b9dcd62df5b6b7ed680731c057d0dace3a82a0a0967f4b0c85ab7daae5ed2562283c1df435a2489af83268a09a98239a2eee45f5334764f13553115f334b4416f782ee29eea7aaa7f87b503cc5df51bd53dc271d82df745ae76ba075be0c5aa7432beb2795054a592094052a592092050acd8958dc2b1b4413f7ab65a289395529944a44137f65e67be0479374ac35bb3504520e1cc8f490d4b976f7ca46165067017316b0660167161042859252e7dc2b8bfbcb624e157f658abf0276c4fd49fec9ebd738f70ac53de5b2d0d6430e198cd3f0a9ee4981f6e83a17aef94ec3098c05744f3cac80741625d22eec53b7d92702c46328954a25f72001df3902a1566bd45dd11a2f1f4af02b7999942492e480dcf6aa6410c1b03598b66d09ae25af1366ae5ebf0bf2cbc428c5a26ba2f771ace731c9cb11ab02bcae0c0981a528248395d341a5032ba6834a07964f07950e2c970e2a1d586f3a280ed85a55912d92f664a22b416d70906348a1aa947a0552a9946449170cd5afb5e037268aa5c12c784085a16e6f94d4744d8a79fc694535fa058dd019cea01ef6e96a372995e4bebcaa548846ca7d3a51baa41646b3575453639dac6c57f38f54c68d30f6a1cab45ed8c11f7307937bb6336a83c07a26ce50669fe5bc4b78895eeea13f4f0bad3bf9b166411af6c82492498bcf19e164be7f29b4ee5c0fe3f00493a9b050c64f9cf59dabbd2bd6b0894f94dfc37467733b8f2c19cfee789bb3f3a81211ed641b2a5d86f051347c3e387330d25887a822b56922faa14d44a0d5ba072833ec3aad993d42c69abc129619333b69c558a4e2195a311ea9d8452b22a777679ea51593918addb4e26aa4e2395a11f1f5cd3c4f2bae472a5ea0153722153b68c5658ed0ed1e8fcd181b18963d3044619c302c7b6088a215e350f10ca362022a76312a26a1e25946c555a8d8cda8b80615cf312aae43c5f38c8a1b50f102a3e23254ecc804ed2a3e7b88c9358598ec788e8c3571de9a58b426c6acc913d6c40d6b72c09a386a4d4c5993fda23531694d1eb326ae62dd54a8ee3ab69bc2bacf446be2436b62c2069cb86f4d4c23c8e43111284c1eb626c6e8d58035318d2d8f8bd6c447d6c4696b621e9b5d14e1cac67111095fc7ebabd6c414851d72eabcd2316b622e0a3b8c2ccc872a92cd34cc01c93206229b3400d9f8ee67edce67c39dce867b9af53a990df46cdd9e08d8d929400d28e7686f909fc9f7b1775ed1756be2303eaa197fe955ecce1564d52b3d8da574b678a5b7f07ec8191f7f0574cf63208dcdc9cfb9c77080cf007b01aec2cc783c241ba928619ba44dcfa664d3b0b1c34faa53a2d86148b609c61994d3ce5c3cc60e4df2ac53295a34375cc93517a5a0cc89618a43116f7c8ab33de152753ec1fc049300284e5b93c752c4356d8b373ce1cc3b9684d36f8782371f60cfd155815aa458549a16def414cc1158b9f8314eb81c1db3266e53a658b14ed6c4115cdee02d42f889196bf27d5ecc93b3120fe1db1989212a23c20f29aaebb816d015e1222f102a01ace84738e47c6f867831517130793faacbce3a35cf8b908a83c985ba79dbee4274dc9ce8a904b05e3fc239e74bf4152fac2a00c39e42154daa501d3fe082212b055e083dadcd6a52a5443aa52d2d6dd6e4156b72cc9a1cb72627acc9496bf2aa3579cd9abc6e4ddeb0262fb7b714b6f993c110a3b318a707b9e25e1b8246b2a6f042ef2baa6e1cb4d7d7b576e5c0817c83dcba827b83dcb6b408ff6e761150a904453550b3a2275bd8fab32e104d12fe5f533624e1a079e850af202b4245239d86dc2965853f14e592241845499304e91d5937f4006e22687241ce036a40ac1e14889079831489961164439075a8114c5dca0b44a7b025a45056f392a6b8bc65f91621fc1a2f5a13237d28694de00779aa0f651bfbbb4e6f16710938cf33136d102b91db9dc76d2af20f50d3ec45fe4790c266f4223d237e5d5db01febe3b01d3d46d391f79893ed3ef1e69ac0734c46f65c0232dff35baf2129f0781ab627f14788fdd0f801ac3bd0b4bddf5c5300ebee04c3f6eea67848999be6af8d60fe2a4a3c234651e27972ac9c5db9b432b47272654c5c1959f96865ccb9b9b032b6322aae9c5c1959195b39bb721e4a4eae9c1557ceae0cad5c722ecec3c5c995a1958f5786568657ce882bc32b232b67562e002a5a7365e5ccca10bdbd841776dd272b97e9653a1f109bd11987cd99108b33890cce38cccd388ccd382ccd38eccca4389479656ce5e4caf8cad0ca4571659c521a073a2be37039b6f2d1cad9952fe0f2f4ca05a774dcbbf8686522ad77c8ca49e00cd9fb98f23823ae9c823f3810e389ecdade212b27c5958fc4958fc5954fc49553e2ca90b832be514f626e5bf9a83dd9d72300952e60334513f45fddd7c266b05472dd4c98bc95c2001c1a365cc879a40951a42ba770c67f2eac7cf4ed627b7c14e9ca8595d32b637190c168cf958f56c657be5839951445ba72726562e502bc773cdc81b3a2f15d195af9dcf1b05f39b572121883974b88a3d9ccc8d2958f56be58195af92426b674e5fcca08bce93cbff4950bb8b48c09744158195a896c0eb8eee97c10f4405ff964e5caca29ae773a5633daa2ff391d2fa66f7a623ca560cb7fbe504ab66a20f8a41c2438b17276e5eccae72c3f057e5880cfe71191409712e203f2f6676068e573a613fd63ea2210bcb0de2e9e45141104e12ea24bffca69988d2b917d27f4c1794c9db449aeb79b1e9ac4aef6da13f65274c2f6f63ece097b2976c27a5a42387c780708797621c6fb2406cc04e73874741dafc825e6a0c66b808e910117d553077eb672b9cf5ec9ec1bbad89e15564ead5c5e398582ded995cffbdce58e5d3eb432018b334850637d2b1ff92fbf00f9a745f6f122eb6f04e7adac54cc680e63bbcf2d7fdae26796c79f4d68ebbfd8598a294e8e91a839be14cfc62a8b8c9159b76aec8dec7abd34ecee092fb98ce2f866029fb6e018a720f97c5a92ee03cdd8422deba136ae623bb3602d6e1b45695365dd082a2bc763c3f6d6180d786bd89e1aa3014f0ddb4b6334f0b5b43d3446035292ed9d311af0ceb03d3346039e19b657c668c02bc3f6c8180d7864d8de18a3016f0cdb1363d4f1c470d6228e07067633ec7d81dd0c7b5e6037c35e17d8cdb0c7057633ec6d81dd0c7b5a6037c35e16d8cdb087057633ec5d81ddf4795604bd2a8a32d72021f30c12d6c8796b64cc1a99b346a6acd17ed11a99b446eec28dafe8ba35b2883727ac91cf446be4883532813753d6e8716b649a821c1701d9e8616b648c5e0d5823d3d8f2386d73da1a99c76623225c8ddcb74646a025145db546a628d410de5f44447629e52f0078199bcffb4bd319366887b35e47b3491dccc6742f6bf72cebf5281bee46d6ee41d663bb29c9199c87741fff2ed27199b746df4776bda2ebd6c8611cfc697fe955ecc0157fd1692c9ac23e7aa5b7b074c81e8e400574cba39ed6cce2f2edb11be0d2632ec05398158f837456196f7c6c6a361d9b888d1e7ed665ab715c04604a9eb746598e10c1381d3e64d3536d790e0c5c9abcb45b8ca6eb319e582347ad9138a7071b6ac81a994e93732bc6e1210153c04002af3dcce873f0b28c1e4b7673688641e4299803d7add163d6c8e198081ce4ed36658c6915c13763c01a392700dc68bfe0bc2a5f59235f72ed23f84a1cc3f1396c8d447d1e28e60fad9121e4124667cc1a61783cb8f8f840c500b23348f1a23512f1dc70c3fb3da0689ff3016474618d7895bae1fe5c885cb8833074c07e94a29b022001ae378072cef9b0301c1e5c7c3e20f6646a86c7c3e8156b74cc1a1db74627acd1496bf4aa357acd1abd6e8ddeb046373d1e98dcb6b408afc84a7e43ba3b206371be0ef09d5db44646faf01d1fc095fb761fbc09f0d1a5abc9541f7e4617ad91eb1b3d24c6edcf637776f00d57f39c1d82c3fe04fc1d9ce7fa630b94f19ef3babd1dfc0f72ddde0ea107b86e8707f7f934eeedc01d21f6538b0be55b87bf83b047d89d14cad7148f87a2bc693efaa1cd472ea8a111452f11232e134c24ff8b26e966c9973af4692123f827af13101c6e2bb8a1adbace8a6d0ded48b4c6ec1120034fbf286474a91b667bbafd089ac93478d0d233a17bf672c6a41a099513625f78268e48e09c10bbaf41dbff9c35a665d69072b29e64baa4bc42e82a4f93ba42817b62311b3f93c05a9e994df6c93e3276d784469e580cdf6b7960c5061f1851049d18eed3520b701b61c7c6cd44bea6178c184ffae562f44a68e8cd62c4a30a6b7d4a7966f0fe5a46324f9475752b4f94e64dbe1c33cdc19adee62e49973a9ff4db8c44d7374d288ee6cd94dede660d6941cdcb9c67fdf8861489ae6f818ce13bfd803a8263603344e36e86689ccd90b085ceb6526474b94b7a7042e922628f54ea220f4e48a2fa70d1ecea26a2a1911ea8d07be40ef82dc915bcd5f0a75b2da93dea21226a66970295baa156489e88ba61e625452d10b1a2a9baac74128ecd19fee90651f2a4a42a92cb0b51ba1c5e08e58574232f5001bcc06f49aee0ad863f362fc00a515c566c4e649b0fd2e9e783a30206f75374b92b8bbc6491912cb091051eb2c04016c8678178162843999e05a259a0d8946d1045ca77c1508815d5b9ec164d43d548b7a86b327c05c5072724a3473348b75891e0af6e76a8066fcc231b168a94cf02f62ca0851ec959c498056c594096326d9822891555340d51d70081589144dddcb899aab3b95c3666e7219bbcf590f59fdb91ec341a0167cfc0e42d0634e6c3c74f17ccb84d0684d34d43237cb874e98b1d0506f314e749ef16f619de82b3f4efe024ea11fca990cd76a1cd9ed37069b2d21b07b03e93162b7d31d221dd9d1a29bc55e970b6727062e5ceb8ca5d7195cfa66495babf72d90c7d7a78a9b5057a9af4831392c69e3ee9b35f376bfaa49f05154d7d385c4a1e0ba1a16940b14ace649036fc64a00ccbeb9d12cddc0f3c4478aed138e32af0ea323da3f11f40d093c0d15410ddf6a340ae1527b2df9704504e0028266128161300f26e4ff28c137af209ad736e6b5bcd88eee2c523e87511a0706a32b6ed4208d8cf3bf104c80307b2dca4ded94c4afbedfa52b13d9764bf7dae29f65b6dd37efb43db6f9d13f57ea3e465a5a00b2f0a991ea25787358554846275dc38f8f02345e896f2794911f4439296af0e2b42a75ebd6b546f6946f55677f5962254aae38a217523885aee2086eae5bd15dc03e61bb215c7640d57ccb26b326ecc581c6327dbe290038d37c00e9e28a154c78bd561a55728578775355f91b44eb49f31ca39564fb6a5dadb36179e4ee2214c3b99669c253723157a33b14491a6478dd2d9da80493765e71aa01367e94cd9a1ea8c460dd570551dee223c5271b45275292d25a65db0b14e29a4422929a4c2a7134728558f529161da031beb4eb13ae392a2d77c6a71e45275aa01624cbb5c83d36fbcc79e13e33dbc59ceb6ff3534f5b854fed32f7952c6335e6e7ac1bf4cc377610b73158eac992f0919a4d756ae2e948c76819ebb83a717f9be2e6d9e1ed3ee9ccbd3b6bd5bd5da33acf4f8456e3ab822331d1cee6710c5ac0e6b782e1b5e94abc35aa76cea6275b8a2c9255987922e5317bbaa0b8a4c7f4bf04bcc82a91f324c5dd40f49154382af8ba8761bd519b8a027b5499a7d529b9432677e17518015ca05b280e491385206b29420d00232402145fcb3fb9516edafb4081f69113fd144f47fa045fbeb2cdadfe6b4f6ad1ea2236e1731c58ae800573ae3568f5814bbedd66225a6dd63b55afdf18f7ffc633697cbeedb97659bad1080da995820519858c35500721b5522632c576117adbcd4973723f15ba9c3b7b032db5924da5e634bebd6aca1a2ebcdaf892e6da1a74c65cc4ca3615abae3caa327fbf2e8a963a1801943337101c94bb884ecfb4dc39e2f4c6c26c5f6df523ac3a473502e13df9a15e3a25c544b0aa9c4c33674001aaa6a9da454b2657ce866f8e3c13feb2dd366488558861a3e912dccd04152d213396ab27f347c6c7a22677979ced12c7f689e7aafc75596e32d1f71568f5883479cb123a62eae3217571757d91b57d7fbd3b06b3c99b3ca8a9b997836845da3d8bbb7cc95207bb79372831bbecb53cbf3df1e5ebeb5bcb83cfc6dfff2a4f8ede0f2e8f2fd6ffbdd82e559bcb80f97c3cb0b50b67cd52e5f9e5b9e5cbe07370e9ac0ed55fbf6db23cb5f2ecf2fdf5bbe8f7f27c5e57bcba3cb0bcbf79747976797bf581ea584a696e7976f840b6f2dcf2fcf058b469647c37069f79483dd0d75d6edaaafa3be6e063a19e862a8838cee313a17e91aa3630d6f512f4f41dfa05ff7b13fbede404fe628e3b7e8cf558773e4780120a7803e7036bbfc05f073633929e40ca9de589efcb67f79187e457c20377070be5a1e5efe6279dc291cfdf65d7fd1ede5f968e1d4f2e4f2ade52ffd45f3df1efeb67ff98be5e1e571d12e1f5ee665198a48fccb37801d9b2bfcf9f65d71f936fd81a1f8d2a500d8bf48c46ceb004dc3fbd8f32225ec6dfb36a297c7796a42086a5bbac448cc366b145541e0c337f1deb747beed4fc8210ceff3f2f4f258c2a95474562edf884f33dcd0d9c6c0dcf298b03cb13cbc3c6b3390f2e0e0f4e7062f0f2fdffa76607978f9bab399b706b24d3d4e4b589e829574399261d717d5b73cbc7c777978f90e33a26f79767952f8f65de8d9f2a480cf6f0ed7913928e286f4250162a8deb7fdcbf3cb0bcba3dc403e1e00c6e6d131e5c6edb1ab31160f1e0a374a8f55894177f8042797ef7143f27800a8142ddfa79f6d6e009e0b904e6d5ffe727972f92b7c51169787fbec67b8b83cbf7c1f0bbe1d705e225aefdcccd3e7d1b2567dbfe54f5b1250af3345cbda83768243b2ee736ec243baeee89de0b8351e72131ee894c686445da9cfb9d8be053ef27ddff62f8fb04e576beee16a290e206bf4943117a5ca3b832cb55babc04acab41d8687e746c2f015652381e16dec84b7089e1ffaf4b427b465dfbbb7bca9dc6e04e556cef3545b391f7360b04934198f0cc68b1cd12443dc5bc15383253cca17fe9464716fc1d40d5317f7bb5b21bfef3654f8fd9db313b24fd21bd809798d284017480241871c5013f7160c200424003d604ea149e564a55030c5fd92222be27ea9447422be493a4cf175529675f135b34c0c713fe930927c695d1e73880891012640046800493a45275710f72be2fe92f86687f87a597cad2ceee7b54cabca646354996cb99c5d738ad7468ef26dab98dd66a95d60b3c3d56482cdd20951155290fb749928853e5dd5a4be322991f2468f4107a69b16128e9d4f1708debaae631e352923f4f509c1621cef27121bdef08e125b347044317c06f1f22062894f2148073f059a17120e64d4d670fc211dfb66ee57bd423459901559b0dfc4f8c43abf9274b53b1e349890980beadf7a7a5d2a134d56f878fdb97628de1229997cf866ee22e561c863720e3fa50bbd442908c0115319ef903a248d548890970cb99bab7c336b51a7d6a5b2a4c80657e166d61669cb2e12598d5d659b5197a7ad8a448b7800bbba36ab3247db7598a5a8e3adab6a336b7b694b8314cd689da366d3da9fa6c02ce737c5e51f5a5c76412b255323a52d4a60e946fd13130cd30cc38ccf8cfd2c0dcd94fca6135f04a597a098db1a37c8631db17cf8c3ae58ebf4986d429e85d421e67d7d82df2d4c51bbbb351a79505d50f2a646dd66a1d42cbba591af5e527607e751d2acd44939a09dc852614b2caf411e3ddec26e0d428a385418631b0327b2bea1340be5ea35a5ba60a758b06fcc46d32b3c96417398d102ac7106cd7b6542eecd2959f1c6618d8f247ee8f8c90e1ecbd07597ccee6ed0b395bc4c87cf57b28e79e7c3c2ee27371341434f25932705536bec49f8bb9f2705ec745e8a4aee492913523e8ff47d620e649e1408b3839c4eb2906c097599bec2f9eaadc2637b49d6f05cb8ec7a4fa8016fefc6a752b93aac98d5a9f54c271b85bd0ce135675af153563c9969e570d7d4a9e576d9d7ffc7b80cafe971c5721e7c708d3be0c72eb5d561bac0568735cea4e027dd782c6bbf8fa1b5aff4a949c8ac188080b3bdac73edc97a8cb37d758150677bbc28134d174945ab5e2b896552bd867eeef4a754bd2656870bd505dd1075867f7d75c675b06fc4acec3ad8130d087b54a9773d52047ad4bbbe3ad303f85318977553514c5c47459c92f4b2baa8c9d5a92ea742ae4ef5c8ddf6dd41b95c369cebea2dddb92e11b34034ba24a7b443eba68254911e9201ec8815d0a5b345ef37c55c7558ac5ed0c49c2cbe2c8b2f576f89bfe565b7f851e58c68eb2e65db1bcd1ce16bb41e8b5af59a9027050191c55bd3aac34259d50aa612071cb47b7100fdd6b4ea35a150bdacf17006f256ebd56bd529a21bc4717de1346aa6414d3a68c85a8c41ed60af86f502652e6215fa617cb40322f3a69ff6ff197edab2be699bfba16d73287a185cd1c3e0891e05495188acc2b7bf43838b32d10ea92002c825492c93424156c5826c1614552c998592ac8aa4a0ea862aea9201c2872689aa61a8f04b63fb3449cccb9d78914ef4284861d1a30014811cd002424082c6f4c96962faf230067227114ba622e5ab5701b5412f24ad532de16541567bf0a24752240d2e74d2418ca4703c97edbc5a06fcc87659d2001fa0022ce9048b3c8ca858266259120bb2d82389fa3aa58ac7778e69239bdc896eba42147a8d92047c9c7f5f28c8022995a404ffdc7d6a9928f190d423d6962178803e5fde57258d8f30b58bed63c96d552282dea96aba2bb2b86c7254e57817ad206e95e256d3e04e99d967fd1293efb483b82de52d5b5afed4b663fb0bedd9a7ffa5652bf5e6d4312d8461671990151a752d6484a7053dc1a3d9b7bf79301241878b1129759a8a2ce852a7cace184437ef38f5b87b692a74875fe56f6e4275a47191363e7020a36a11e6dc0d4e5593981b9ca622146455532254dd3d4eac66ef7202cb921e41ecee7296253dd2b0d76e4894284d779393288acc99286c894cf089647f5d60fa7e669ecaff75e1272591199b12d9c690c87e5de4cb64db3b8b9b62d9a658d68c30aa4db16c532cdb14cbbc7f9b62d9a658b611c5b25f173705b38d209875119e58d6457832d9ff98efffc7f9e3e2ff58f8007fe6df839fbf9f3b470b4fe1dd916bb46e90de4de2ddedcff1eec480fd6323822bc4954e1e6b85363be1cf33f06717fc7916feec863fcfc19fe7e1cf0bf0a77507fec536ad3bf934fce2d93f4e8ffee3dcf97f9c1e15ff71feb87df53f07269db2a959b776ccbefa5fc73eb2affe7efe22bd4a2ba6d9648000a006a4800e10a513d31a47f098a535109b5a72b9967dfbf899b1fe7e7b36f78ff3c7f7c140b125b61054bcd41606a6f9b1582d4af11c964a29382c31a138f4d8c05bf2f9fcd658d9321cc6f2f713c7fffede893ef859fc2092ca4b682c97175d8a28ae8613773574045f42fc2ded55e3810d51d685f54636fc8f3b7ffec7e9d1a43dd87f9cf94b0c5424e195a2becdec3ffaf8aa6f673123e256e117020ad7f42ed1b5a9ed1f9f8ffeaffe9bed38cb39526dc2b928beac09eb4a4d4f87648c3324cc1c607143e21b05e117823740c943f2f723c77fe02149b3e79d2c01fee3f4287bafb4f961d94c57483bbc3a36f29a17781d098386b5f3490441a74f95018b065743829588a521fd6368ea7f5ef998a71931aa50eb69fdfbf1a33c7d885155a4a2cdd9c3ffebd34f78aa10bb364f5b46bf538e1ec4a84235a7f5ff1bbc051211470762d7f6d2bedd8e64dd703420a84aa10274914d05604328003d5c05a0e731877d579a1ff6adfbc2be2b0d877dd3486d5557c537a50e537c5dc2b06fa96cbe4d8ad883b5057e4b1d800a10019235077ef35a6e067edb132524314b4a97ac14fa74b997c67e2b86a4f429795232377af437e5bc89f1dfbd4f28001c869811028e83fe630c01b71f441382c07b9b14058e23dcb0ba441f4033b5a57d327022544c45ee56d30583e73a24a58b2885e6c783931211de9695424c547a3424bc5baa484aa15bd29e4c5cf8dbf8e8045929c40787cb4aa11b06c9658f2992eae46dc9206fcbfa3aa2c40d53291448891d0f9e2a5adcc1b0b6a8f13c4e21aef19e5d6d478ebf1d1b39ceac7523c76303c77fb271e35d3d9bf2f64690b7bbb906f76e9ec13dbc0cfb73ead607cfd4074fd607cfd70787f0e2527df08c581f3c5d1f3c551ffc08ff5e72ea3ea375e71cc02fe8fdc9fae005da300472a63e384cefcf208af3d1a2cffc4527eb831f63292dfaa23ef8b98857a7ea83a3787f0a51bb6c41a3cf9dbacfa375e7b194d1e813bc391bad8bc945eca65d668dd970cc980d87c66c9831667e28dafbe1e8b00d47876d98396cc3f1c3361c336cc3bc611b8e19b6e186731dbb63e88d9b374adef87863e28d8637085edfbdfe7a5df33ae2719eaccec5bf2c679d71be541f3c49495daa0f8e211f1fe1dfd394d761bc39c7acfb1cafae33ebaed707bfc41b46dd05670e9d44fcf4310cd1ba3078ba791ce88e3b2fa23d1a8ee9d1704c8f86637a341cd3a3e1688f86637a24eb2fdb7d6ad9521fbc8a3d3a5f1f3cd98758e85ca513e0e3ad2dfccf7340037707c71b136f10bc2e7b1df4bae3319f4e57a7a46c3a36119b828ddec66d235e971e5fdc532e0b7b398a7c916ecb31ea9bafc97318e1aaf036fc7a940e9c059771220cd39347ea839fd6074fc59e9c824fc05ecb631bf9550a5c95bec4c705733191981b21179db1b6135202611f026ffebb4ded968f513f49eb9d64bfa0742539d387377479801bfa7a9d74efafe210c0c76eabdf97298a1e7b93d5a44a89744a5b5aea8367fea5651bbc59f000328e2c166d223ced02a573844aea2728e30d76d29e937d5830541f3ce5eb6bd2c695afcf5b28b6535bed9e833020b8b3216d4037e5df3ff26b62c68fc0e6e7aa2bb534c655649f8c2e99979cf1a5af099591ced5074f09feb1e72ab67140654ac17b685ce5360ea848b1049e3657cb4d80cb535cf64ce1aabc5c881c6d6fcf2faedecb85e87547c47ea65c0d3800c45e51b8f19e3bfa5ab7d3967df4516e8f669fae0f9e4ab7bfc934dbf9d23aef885ba692360f19f8620d81becccef6d024e37690ff42d8b963abd0d7e752fbc58b981aec5fffd52d794ad8b9c3ee5400d2cb21b683fdf23af63d7bb833c2d3a9baceead5299e1f48bce18369d048618ee8dedcfedb10e6081d137d48baf0a2ff09efd82364b62f1d5ffad4bf4eb4b20a77b20a9f6115ee62153ecb2adc6d17beef2f7c8e05f93cabf00556f3d61dacd29dccd26798a5bb98a5cf32876a3713f63926ecf3ccd21798185a7778c0f69bf5f38071a99b6b5ceae66de67e7dae36f5f5974b876b534bfd626deaeb73b5fbb5a9da3db176af36b534b8d4bff47eed2b7169e09bb34b834b9f02c8ddda54edeed2fbf6e5d2e0d2c0d2fbb5bb223055bb539badcd89800c406a5f895f9f03c8dac2d7376ab76b73b50511c8d5be420a70b9d45f9b5a3a5e9b126bb76a73b53b4b876b8b5f9f5b1a80fa74fbc1947d9b719b699b5d9b559b4d9b419b399b319b1d9b159b89147bc608b8b034509babddabdd5cfa54accd420f7d0578192cf8e6ec52bfbfc9cd1044edd6d7378157d12b4bbbdf4cf9b1b9b069db146d3a36761b773ac5b6760b71528cf08762035c14130fcf4f2b1e685bf3028250c5ab7df4f58ddaccd2a7b57b02ccf4af3fa94d2d1d4eda3dab0d2df52f1daecd7dfd658a46c19dae7878bfda5bfbac36b774bc36974022a0b07e33b674b8b600934aa84dd5eee3eb756fe9fdafbf74a26fe27135f904cfa54ff135bf07eb50cc2e5bede6d73771698b1ce4435fef9bb0d4d5ee79a3016ffb20a0e56a247140650fa950bb5b9bafdd5b1a5c3acc554bf820451f226f5cb96a091f24efe70856e7c840b85a09bb3ae7473055bbcd554a5895bdfec6b796deaf45cea5721512bbba4155c43bed06a6431f7c4759a7dda4d13be0bb4abc4cb720936f8b4ae21d1ec42fa97cff12fedd232866a9f4f378f97b8b2385b5d1a2765002dc3212bced68e71db7f463dfa2eceeded40936844ed05bee504b3952092a0599d6cc1e2153bf38ec7f57333b69e11781c26768e19781c25db4702450f82c2d0c38a86676d3c2cb81c2e768e19540e1f3b4702c50f8022d1c0f14eea085971cb9799bfdfa45bb093ddc03bddd1628fc020a77860abf84c26742852350b82b54380a85cf860a2f43e1ee50e115287c2e54380685cf870ac7a1f08550e12528dcc1560fb8a7d776338fae8511bb70a67ea1bf7ee1b3fa855b225edd81a28b1fd72f9cae5f3c2e62fd7cfdc227b4fe4cfde240fdc2457a7305af4e3b3517beaa5f3889ed3f7191f523a6fefa853fd3a28b88ec925bff1ed6bf47ef3fc4c6e7e8cd79c47704eb8fe2753fadf8188b3ea95fb8eb08a7c1152d23fa3e261cc5e2ffac8e3b523ff6fa8bfa855bf50b1f21e20f11e35911c99d04dc70ff918850efe2cd6104ff4cac5ff81499fc18afa0e633ecce45bc3e857df8aa7ef104edea1d67003ec3fb8b4700fce28934da8ecb2470059c00418fa88d1f7e92759ca6e142b1e337ef904e630f26dde7aa420c4d2846118ad38312f6f312b5a0b44a50c33a50d80dd7371f6ed72ff4f7c14486fb7771e61c59f32195be40b610caa488b6c719d016ea6de3ae9a317d11929d36e31251c02244315f1cc47779a07ef198804bd77bf58befd62fbc9b90a1c2799bbfa85f3c5cbfd09faa6920654552035fea0a67adbd880bd13967197d2f91a897d6c2257a11162040f6218ee9a5fac513880f16e4f664ae1a4c01c1d14f51ef8485f5627ffdc2872cd5d486b0198b70818bd529e0947e49a04367b0439f381f854f9cb53b7212b0aedbdb3b899065e7db77af7ee16c2c60d941c98729069179e31cd5581d647c987c10993799a39aab838c0f930b221ba85f8ca8c8b99c838655db1b4470d4f9f8deaa5f8cc476f5f63a9882608d28b5022ea530c88e6ecbc9a94a819e0a649dad6852852ec7befd6f439395026f75a5b5de86705bfde270fde217f58b5fd62f8ed42f8ed62f5eae5fbc52bf3856bf385ebf78a9bda5b0cd87bb4c8cce62f2865a8e54da10b43dbccaf154dc8aaa1b8effd35abb72e040be416e5d85a8416edfc67528aa8faf4b1ddf23ec7a12293aba378f65ddf8cab8357325aa8c5b33635165dc9a198f2ae3d6cc445419b76626a3cab8357335aa8c5b33d7a2cab835733daa8c5b3337a2cab83573d955c6e92f4f23876e463472e8664423876e463472e8664423876e463472e8664423876e463472e8664423876e463472e8265f2357b81ab9c2dbb0b3a6cf5bd363d6f49c353d654ddf17ade9496be6a8357dd59a3981455ec5756b7a116ea0e2336be684684d7f684d4f3880f7ade9695a7a1d30cc0c89807be630a0c7e2f3d6cc00c21cb5663e15ade9a3d6f4696b7a1edb5fa420f3487bc2293a6a4d1f065690a8684d1fb1a687bcba99c3d6cc90bf1abb1169348caccd872ad2ed07d2d1090fca0f3616ec2108f43cdce1d87ec6689afefd496bfa1a76770c999ea35d7738b49fc2757fc5751ce9d3d6f48cbff42a36bfe22f3a8d455321bcb7f07ec83703dd0ae8e97db728ed86a6bf0361be03ec7a5c06980bf3e4b1926eeb93d20f50b6c9da046d6a361df859d75ee85ef48fe56c86d2ca2792b47a9bc0e184b71fea3688574ce37744ade963f8402f5b3303491ba1f8141761a2ce1c4db3ffb92d61cfd399a0633851c63858035b9e38ab8e3a8bc3516bfa06ddeb64916af2fe26727bd89a1e817789bfbf694ddfc64ed1318d2824f61a81bd989ec695684070de95aface92feda5606680bbdde92c5743ce2a3d8caf1ba7599912fcd87dca8233ecd7f1ef57dcbdd004b82203f169bcb9c8e8b7bb311a079467a0bc4ca708778f940b9163201b711e0d67b0dcadd364d05e06fa39e72b17192c77533500c4d1b4d6af325a3357ac99316b66dc9a99b06626ad99abd6cc356be6ba3573c39ab9bca932b2b80d5b4ff173ba0813c19153faf0fb7314bfd4f7f1237402ff1eedc397e40adedfc046b7e992d607ef2a4c90f3d6ccd18d9efb20dae1e4c401bf1076ad236d016f3c9b967f81f75cd26564d8b1aeae790ffe89e45f68c894be2bd692ce9808f1f913845f08adb15ee1fc279d8cf8b904c49c279c88786712c7be07d8f05e428a216cc404e9f3abd9624b3e33436b75ab89f8a0bb18d7e288be03ed69fbcdb5b9b7ec4e726fd9dd148b9ab26951db0816b56e956b7351793697d6efcf9d1277c29f67e0cf2ef8f32cfcd90d7f9e833fcfc39f17e04feb0efc8b6d5aa151cabcb68f8386df28f0fde777bfffecd4f79fdf15bf3f77cabefaafb3ced5f7c7cfd857ff9c18b7affef7fc7107eee8257a955681b7c90001400d48011d204aa781378ee0b16bdaa0ef6673b9ecbe7d59b6aa0d00ff3cf22ed58ef7c168b115ee085c82d61d85c7bd4d76a35202ab5e42da58564b1c381e552ebc9fd5751809be3f33f2cf3f9f89370efcf3f02c504ce1141d6b13f8fed3d9ef2f9d4fb0027c7fa5ff9f87cf7fffe55d8183b0c99aff7f9d8bec88fa14feef2f456af19dffe7c431e1fbd9481647478d6754d1e495ffbc15c1e7a8e48c2a54abff6be8bcf0fdfbe7fff7146377d7a6c6accdd3c667fef92557bf664ccf9c43f29fef5fe529d08caa5e7b6911fe7924c288a31e43552372913f7feb96ef3fbfdbf7fdb9537ddf7f7937a568f463c8e40a0f8011ea1b73623b1bcdb9537c346ff359fd437a0a5f32196d7acad9809e0e13e0fb3323df5f7ab7effb3323ff75eeddb05353e0a91b6ab7a4f0e461aca4621345b5aef4dcffad52e18bdeae4393f012128325c45e68c374b922adba29d26e04913676937895e1b0bdcaf0d75e65b86baf32bcb55719cedaab0c5fed5586abf62ac3537b95e1a8bd9ac24f7b95e1a6bdcaf0d25e653869af327cb457192edaab0c0fed558683f62ac33f7b95e19ebd1af4ceb6ab6c3de345a1cd07fab7f14757568fae1e5f3dfadd07c2a31babc7578f7f37b47a2480eed1eceaf147638fae3c0aeee33fbafce8caa3e947571edd0c123ffadd078f66006b04fabb0f22d08faead1e7f34fdddd0771f3cba196d3301bcac1e019028e9b1501120597d177ab0fa6e08cda3d94737bffb00fbf8dd07df0dad0e46fbe887e18cc3eaa06fac00cfdfc6118682b487154093ab009a1c05905e7075b748b55fedfaee83d563ffbdff83d5c147b3f402c60d2e44da9b68f1cc777f8914feede8ea717846918ad5c5effeb27af4d1d568c531fca5232786abd3ea7151eec36c07f98d321ae5707dacd9fa2134bc213e9a11ff76545c5d14578f898f6653bb690b097eda3ff69385d7eeaefde8f2777fa10f109f45dfa331fb51c11bf6dd076b76d70e236ea15969689b1ff2089250071bb7b2863ad6d434bb8f2edbafc6a39bdf1d1560997b34f1b733ab47befbcba39b491be5a18ea56c1d0c1d4e6ee3df4a8785015ef5effe92825834236f729b66aad4abefe2f0c466e365aad47f3b4a9fc9d1473784bf1d7d747375d059cce842c9d6b57d9042d0395770946e1783f0e83a7c2a39f8dcadf158a8621063706cb9fbe2f160f920cebf0d7d77f46fd15c47ce9e38bb3a17e2eb08cccebfdde0ee81f3007a432336f3e8cadf2211dfee86b75dcd9e314dd8ea5e1d5efd62f5cbd591d5d1d5cbab5756c756c7579bef13edd17bf401e0ce6ccbfcc836bd3de4dbb0038f3ee0f6206eb76737dded2186a9ad69bfa77567c27e4febcea66cf8989bdaf186d08e63721c1dfb3ab0b2d01c47c76a8148969dacc26758cd77b10a9f6535a7398e8eb1721c85209f6715be60370f2cfb768ea350e9ce1d2c52cf30617731619f650ed56e26ac9de328dc0766e90b4c1e9c1c4740ce7eb3822ed3bd5cedad97b77db7f461ed5e6dba36b5d4bff481b8f46e6dae36bdd45f9baadd59fa806607ea5f3a2c62f6927ecc42444b6bb7c5dafcd25f6af7e01e2eb062aa365d9bc1ac4787ed643a4b87973eacdd44dcb5c5da82fff65e6dd1bb99adcdd5166a53f436dd9e2065dc6639cc6a1293367b36533633361b69721c7d8a094d8ed7e66a776b376bf362ed14e6383afecd38147c7d43ac8d6106231fc41832e82bf8280cf1e9d220e638aa9df14a536739fa946639423e6cea364d9b928ddfc69e32cbd1a78893a2823f141be0b2316d66395a7396a3af6fd8598e52e538ba16c871d45886a3d4f98d8e2d9d583a114b8091dfe89bf1507ea3da3d27bf11cd8ff3f58df6783e9abc1d589b87e53439d1d15dcce136c84d74549bb7131d1d6b62a223402ad4eec2b87c331e9be8880752f421724695abb5f000f27e6ed691e4882258639223daf83127393a569bef834f711f7c36e16a7033ddd1864f77d4bba91efcd0ea810b5ad1d44e49d7dff42dc0eef6fcdbb251544d633f4ec96d42b7d4bb4d90f59771350ebc3ff0ee50ad3ba86ac0bf4c39b34768cb484a41c8c98a6918996d02dc499a73df1e7acf3245b7c57e435514af01bd8dc0e729bca408fb48c1812ee34d043667c30a39d5540c0f98de46c07b1df0d75449f3a0f1aedd37d77feeff96e12c0f0c1ecc191c9fb66ea9b7bd6d473bac48be8256c764f09fecc743c71c1f0ec39601c3ef647476ac19bad9a11bda961ddb9c0259c94beffcfee0968c90d9ea5f59e483c216493e289524ed4da92095f6562a2559d2df527f87189de592673cc91021233c6d13896e9d0720952828a7bf6f10ddd890bded91353375870198dfe7967ffb37bbc9bf096f620b1df76680475ca5552d2f744807554dc2fb82dc23b91f9392aa4b741dce6c573282a4e4a1d72e3e295bc8e280b7ee10f6495221237498063cab67e9ad03e836f8bf2b44236507fb7fc88a211524ed3fbd7acde6f03f3a54b52411c5ad6a093dc114a3eb1f5cf749a225f255c570579fd61de10727ebbf23bf4b7a4407494997d8cfc597f9fc178c3cea2d2dc2efa4022e83026558d8befd970229bd0d8a213c1a2641a8f0d3f35cdd5d5a0cf7fc9616e1f74aa9576815f27241368295d07897f00b57d4f8d77f15bc1ceab11ef92166046e0ef4c83031d966f2bd93b2ac47e5275439a02e244751612154d322b486836480ba0f4752b6fbb8a9e6510c1fd5c01e8f385c2e4b5b93078c3d64cf08aa26ecb2c70d679526759a9a2ef748a55ea1b32875763b625a7436bc5d944b924b05c54ee6a8b8af127f801befbbfdb6453b1eede45ea5d728ca4a4128110dbed64691286ea7f7707bac6c7f8639a158ddd911eed0da7ae0aec39e75add4c1b3ae953a382902e969d0ce61d062ae3a226987c4bd1d5a75b254127392e43f0eda2c98bac13c0dbac7390dfa50cad3a029e92c12ce8a39ed501688661d8a59a098058a59a497055a5920940522d99461f6514f015fbabcfdaaa2e4a58298ab8ecb78b1af3aa9e89d455a3669186fab9d45719faa28925dfab226c9f0bb9f946949ca9c77fbd52c50c90205b89acc8afbd4acf8b29615f7135e5f82a9eef6ab800110407b719f2abeac89fb49d37c2638b9edf694cb42db5e53d222e71ed919eeec33ab3830098630a8ce2626bacbfa2d5b310c05f2ddf11ac51bc5e232b0bd424c4330cb8949c6d826323c43d794340e8648b63536982fc7dabf5727f5cea2c1c5e8a552f3342ae68adbd222ec930f1e9434490105db906c410f647b21e3bd131961cb5ba6a4e749ef5681287921e37b33a0ae686ab4326f4a82a10a95a2aaa825b520779292a09925294adaf19106d52f9b27bd5bf8a71ca12bf14e8e0b3056eee2540a3e61b6edb7120e9ae298ffecb163381d0b898ec72cc4c978c3072cb127644a5b6244b362db12430a09cb96280915989dfba56e78aa9143765dfb210fa0ec91f1abe13cdb21d59aa3688aa9d0b8b643d4a519c710a7c2e29a0f519b60180f9351b82644fc86444e5aee4d85c43524a242ce9e0f8966c40307b20c9b21e20dc4103db6ac664f22ad59a963d3e8f6431bdd50cee4066196b84198d6c2b0b570d35a38662d0c580bd7ac85b3225ecd63c5056b615ac4ab396be12cdedce9c7fb095a73c15ab8652d9cc2fb293ffcacb5f02962a1ad1606ac3b27ac8551841ab016ee580ba7446c358bb4271d28e0e5acb57082de0f218a5197d694b5701c9b0c88d6c26907f88ab5309d3291d54fbbb7816c55d0bd696c374bc91fa71844aca183f02e829ca5e4e62918253c892036d7f3c8028cc504762689be6fbc7f08f24ebaa985d34096127c175053f493142b0ceac4a673330ed415fa6c50485aab9333ce5f78a5f049fd199ed49df7ac85e93e5fc5004eef63cdc84f1dc5baaea8aef57a3cf37abf860413b11d13d6ebfd8cebd557c8dc5958e8eebc871c5fa10b4f62a230aff535bc38ee7439018197e7cb996ced30dbdaac3be7e940252109a417f3b8b8429790d49d09e61c0bf382036ea34d89b0992e0838a873d6c240ac03b5b5701ec79df67b1826194b75b0163e83afd09de3d883d33823b1d59d41fc865dc195f9acf39188383c7859c9a2a002cb45a1558843e7251f8b012a3a78feecb07bc5ba73183b798ceba9900a3aef60b6670ed769810b91b331c0689e02107c49b9de0b0970bd0e3fe718c3e0e514a3d50d2a1f5be8e05a778e6f8dcf6b9d36a14cc645c83c0d95af186c86b26e08c5c0546423e4a99bd1750c4cd6a56e53c93f382dd28b878bf2c319fb5a0aac419932c2e317f3c169d1fed5ed8bb341d072c603a5200f4e0062fabd0de22d22de1e52224a9e88f457d5ed8b07c198c46231e3c2ba300f67ec0b12449c47c479595288087f551d7f4228f3f98c0d65d73f9cc19f10b21cedfd83d38aa98af023e9b273f12098883997cbd8a0922e13d98186eed32b3388ba97a2960c80950c80938c304c6f860963bf79f6cbe84e0b43238a5e2286b45fea5495bcdeb8db05483e0160eedad02d956455179c89a46712f7731c61cea62bbc44913c9c117c931007058a89835bd259f1f3dc9ecb4ac12c11adf1aec73859e85bbaa5deadd4c7628b8f7f5f5dabe37f61dfef747dadc2acea15a9532625d6da1bf4ee7a4a68b54facf61f64fd4b28f5edde0a3b77f02879ec3088e0e280ae223e5d8883c81dddb5f9f168926e967cdbb44f0b192113da888f3d3edc66d9c6f374434fbb6d47bb8f35f66e6baa19ef52df127e82b11361477bf24e27f544608c1e8f8500bd46558d357664677bccb677f0b544ab94c1b54a191cab545840b6b7c2323a3161d5ed213ad16455ec567b54b1837e031665552c4805f3e1227c713a64ede122ac4b6249962aaa2e6a66a1d2f570f2c10959856bfdc1e92e55d42b044148a55b93b1aaa0992ae2e2d805e09f6ec0a7a6a42a92c3916e73a4034744b75992759721971f1df9210e3b86ac3bdcc83a6547b7d9812ae446d663789175679bb0655f9bbaaffda52d070eb4b5fde9c081b60307dadbffedc081f6be0307f4ad4f8346ff521ffee540d0e62d1c0d3a6845d389093d86de425fa19bd043e89ba8152aa256c0ce404fc482964f3656719fb7d45d26f8cdbe215664cdbd268aa139d786263d38213b77dd92d1236b86db4852badd9b87c3d2c361e72ef503765890758f0559f75890753f0b30077c2c4023970559f7b390f6b9a24d06ed309c871331baed97bac537644ddcab18e25b9a24be2e19e21b92223ebc243d1c4e673adb2fbe21ee15df125f17df80761bd74af6c73ffef18fdb73b9edfbf6b1ad6468c56a2b67dbeddc69425b3ecbdaa2e6c26ea3632fb4f59012b3655c53bae91d87a014df092ffd5b62274a31b0093cc4378df6613de6a7879764581b2525c9d2f466afa176a58a5489b715fd3fa49b688996a03734f2e07497a93fb0b3ce3f66434f458db1f05434597a38cc00d0f1f50a4af62ca38d0bc3b0d244242696998687a0980241b11883209f02413e1f83209702412e1783a0370582de005083c617378044ed929b95c61770ad2583effa22369ed0e6b1b16923dac03622d74424e9b659e8c12765c740e4198ad80242c6b1033d9c3424b4033d9c34a0bd5de4fcf2dbaf1701da8b74c354f24417f1f7c140995e10fb87df763d8d5dab12b1ad4e0365d13345c5b45b6b43dbe8f489223d1c26a27d214b657a094a8a53c6c5b07e1468a52a903c110b20e496e147c76b6e8b744d82762e7f78831d5d10b4d6d8810434e6e145810825492918455c9be4b2f473eaa22ebc68c740b4908386a409c44e1aea80b9310fe13804aaa06c419dd8c9a517323934684c6b69117e932d6485033fdbd92ad893fac0cfb609077ef68c73ab1ff85936ee3be15a895a7d56a1a730821016b7d65647ab6fdbe92af46dcfb4a7f1be8eb0a61ff8994074415684033fab3cf8a45308546579089cbe3cf8a41c4610a86a523f7778fd0c184738a643bff0f607d928be513235d726c2b228c598ecd0b265db6788b1c5b3b1f1a60bc7e016e629859d8bc555b3d8883527a731a266f2e4e1a2dfa28b523c79b8f860a02cb8df978cc786cf8ed4c3b523f5f0bc9bba88d2f360409375f1a0d4a199f4b24c34431749457b3059c25bb94b17bb1e4e2af66f097e093ad5c3370fbdeaa19dda6da878a1a05f3d5ce5a54e7a95cefda88b28c0087000f481341246aa4012c8011d2001c853f8f9e83d0f3e31e807a2226b657aa51a1abd3034e9e130bdec8427e2424addf6a52ee9f42aad4fcffe1ef10df1f7e25be2afc537bac5fd290d0a0d35fa41dd6e1cbff89874f459a10dbe58ed8e3f7b8c41210cba2dde1587ddc4674758a7f2adc2a3162a66a95b3752e8e00f268d44e060d68838e8885a1e8b3ba89f93c283812ef3e1f08301c7973bae6d537575f83cc568ebb256d639ca7a68d964e9eaec8f0e4371e77d0958fa7b2aa4c5f4488b2c5826d27c7aa479162c13692e3dd21c0b9689b4373dd25e162c45ba46e300db2d5c60fb85ffa8b5fb9e4ded7e2368f78e354bd5822afedbaa96d7f708ff21b4b478d146058d94cbc4c008a14ea24b7a78ddda23b4d95681cc36c73e40bc4b3992eba00c2dbaa43c51a8cb25c0764979452dd07b126d814d5c601bcabb0ac3173d0a3af1e3d7090b1ac16d4084a0bf51cef37980cc13cc1491270a717fc390b91c72dc25e95227328a57c4bb8c22efed85260515de7e80c32bc9bd22813410feafbdaa6952a7f1efde73fa3509a6da74057455cbbf1ed2098488b642b5a9971c68dbbfc10b0ade198c12dfe503c5cd61e7662737af8c6b4d653219afc33873d8a622bce89bcd599cc0a8d230e2bdbba5deacadf9b3fd0904bea612180bafb78deeb187f4411fe7ec87187972c95bed814c7e6589a72595254eac71178d353e68c71a837a04da895c12cba44bec3215b1cb2c89a407a38c6d7d8868541d229aad0d11cd568648ba28e32ea264816416e865815e364c2e0bc4b240270b44b240a02911c68a94ef924a5d44aca8ce65b7681aaa46ba455d936115111f9c908c1ecd20dd624582bfbad9a11aa974244a200bc8b380350b38b388300bc8b2802b5d74b122891555340d51d7a0bd589144dd7c02b1c53cc589a3373d9670e2c6e288d711400c8bb92e9831ba1040e95da6a1110f8cad072546f5361a5abb234d90abd92eb4d913192ecdb8d859c4fa4c5aacf46d488774776aa4f02aa5c3d91a1759bca6b063ac7c3625ab76d070da98618eba8b0a6c97f9e084c49e653e453761f6387950007a1fe90d9d6ee2ff9769ab68eac3e192e44d0dc91df16df16dd442bbd0e62e8ddda4a176b08ca66f22b973ac31eeecd5b941de2a52032d2467a67a9c451b84c501c1a7f9f89e539bf7ba470488c768b9384478760bc1f633e89298960bfc87df9f6eb52477ab8223d7472d1814d227d6f09d0f1a802da7872d3680b7584c0f9b77470185ff88ed2235a29c8bc8d10d22268bd4b87a5d5ca820988cc0113eae1fafade2c9e48e2c4b9bb68a8d60ab28cb5c1546e6a830afab4579bbf160c090c4574c79bb419482a999e21baa693c9cdc6e48db35a21464f10d222905b2fdede28301f82fbe42346298447c43aec89a2cbef2f084525065f82fbe2269d276c3d4e4eddd0f4f743f181073a40828ff50943519903c18d8ae98ddc1024ae515d22d17259eae105483807160195805f69025e4c7e1063941ea406abb427f3482646269bc2915a477f6082d5b5edad39621db0f1d3860ee68ddd18a3fbbf6e1cfee5fb53f7de0c0f697b6fe47ebb667feb3458ef2894fa82998a0c74d43b426be7606d1f934c2371f0c18a4628a39a248e25b0f27354916ff202912fcbef560403624f10da2115993c45700549378431f5605df22628e004af10f12a212df20802395fed760e354ea1d47bf8bdb174b88464f0c460fc5a2b7c9edfc4d3066e274afc5dad53c5930245912caa44814b24d9013f43d52512b2a1f2a90148a09e5cb09252b442145998dcd4b0865637bbb48ba49d9344ca540d84d0279ad9245448e84b847c8c882a61aaa2073c4449aed5c16ca2689b0b047c81892507cf049b7aa10413389c600d26914ab0d158908de23648a92509614c9888896e5326dcbae2ddae489aa45d0168b365556659ed26454e469ab684dce669368a41cadccd96c326b7b695383300435da0eaad62897fd75819759e8af0b3fa52da4b2bc29966d08b1ac9b2b967573cf883983073b0cd6a696fa6bf3ee29316e41f89c98f9da1d5a76465c3a83a721ccd38b3b001c3925e6fed2613cee649a22c323596a8b5ec1bddaa2bf9e9e15e316a43c2d06bb103c2dc67f568ccbaacd68e09c98fbfe73626a730d9c1373af3687c0776a5362ed7e6dd15770af365f5b106bd3d0573c67026e9706f0989dd9da94b874ac36b77418c719466301dacfd99778aac3cddae2d2e1da54ea136290b4cd854dd7a667d3b229d8d8539e10734f126bf755c487d810176212970678d2734aef9fc66dd8e8fbd3d4b3611a3b1a66dd27c39caacde1912303426dbab698782acc974b87e101c602bbde37b58f01c83e9985d3207024ccc7382ffa6b535cfce98d9ecd3299c75abed35bb06b676a5fd5eee2293153f016c1ffc8d86c549b7688f9795808d2309f60e96ea6d1129699a581da9dda5c8cd3957da8d82cc7ef8a2e590bb5c5da9ddac2d260e0749de0716902ef109e28183d8607076f6910d74f96eb153d81c7058a60c1a4354bc76a534b03dc8436b43a4a801ebd031f81983377b03ada3667733f079d5c3aca4d5be3814479a787efccd41661785844bcb3773ca0f9b59fc0035fdc3ee84e1f8c645f6dba36df071fee3e18e0f59cc5c3cb251f9df800b9731f4dad1e8065a597f77953c4e696f7057641173929c29c84f52ef9c6d0de4b89d64923e12fc35c12e928e11c8fa7e465dc8f75c0f0b33fdd00d2d8bc6c7e4efb1b40fa9cd0d727048b9e4fcbfc5d2e9db58f28fb1dfad15bdcbb3755bb0da1da95b8aa5d899b3876f6bc353b66cd0d58b373d6ec94357b5fb46627adb9a3d6ec556bee041405ebae5bb38bd6dc5d6bf633ac86bfa235fba1353b6183cfdeb7e6ee21e0dc316bf606ad3f6fcd1db6e6169cabd9696beeb868cd7e62cd9eb666e7b1e54df7af8845471d944ec5ec61e4e9ae68cd7e6ccd0e61e9456bee7db7740cf9f4a0868197d979b7286572596744b28c91c87a23900d773b9ba6d359bbd7597627b3e1ce65bd7e65035d5abf0b15edec05e8cdec0d1ce0456b76963e55d19a1d415267f17ec89a9d09557f66cdfd19f882fbb950dd559c335790f3400505bf619746ea8e0219b89f41da374210b71061b82275125bb7ab383982dd9b5b0c77c9d78db93b51d60f3338f6584c99d91639b279b1e9db6403046d52807e5dfaf45ea1b8a75c16b6d3e9cdd1ac29d01e5de7c2353daded362181339ebe1d69b81ed5db9a3d86584ed0bf892954edc93d63cd1d4d1353b32d2919aa9f3c2c154cacc1bca7f05ecee23cbe800d2fb40b3c524d3e62354ada9a3bc1cf752ae0ca3860cddda1eb1d3bd3e9ec116bee9e353b2138eff975fcfb95f39a9eb5e616f9e94dede574c879a3efc06a192555a6a43ea6ebb9e010a104bd6f10572b4cdba0c8a0f325b671393c0cdf249ef698b6413e4ce732b699a35f09ae829900976370bfc801cdf939e600f586f1cda10cf1150bd4cd9aea0762cfd848f26af8102fc282ea7c94fb9ca239ec2ebc577dd6ec7baef8c29ec97d48fb380efa806f553886d80ef745e90477b86db65e514d8d95aedaaee6e7a9462d8bad11d17a21e1d82ec0b4c5cd984d336d477846b115f1fdf24561d756a1af8f6d7b0ae3491abd4c6a4c71839c8953d490eba785d69d8d6a68d0309d56d69c7ce3bbe2d38d479f095fb54d99c13c32df53a08c3d3030cd134f24116f89489a0a8d675f4f1ed8348a6d6953b1fda115db66242d75f61e5821496875cfe81986dd9d97fc60e9c8d289da2cfebd173cf21dadc2bcdaa5f7a3d63c9b7a1c79ef6cf0082351e25182e1c8234ab11c26681747ca5332e2d9ca291bde7d0c13453613c54879dad1385a9baacdd8e380d7b5f9da6d2ef93c9b7c3e529e92fc37e3b5d96fc697fa290370875be17c06726c067291f2f4b361ca214faf6306bf974dbc37529e7606dcaacdd7eed84f1faf397de71ffb16a09270186759e1daba149eadabf6f9d289da4c6df6eb1bb599a5134b2796faed61126ba3b5c5a58f96fa6bb34b83b599da1414ba759f2c0d2ef5a33b00abf6143cf26fc6a19681f70b6ebbd388154a995871d38b55f3796daa76bb76975937b434c0e4e2640cff50375d9baadd136af7b8c3e3012d1de18e543af35aab8374a773f18c73b1cbb978d6b9d8ed5c3ce75c3cef5cbce05cb4ee70af5cdcad3bd3f094d64856fb7ce9c3da5d782853380a5362edfcd287b519c78be4dcd2115c6ca6a1e6e2d73796fa974ed4a6c5da47383c03e87852fb0870d46e36e0afe1a76a53b469d9546c0a36ee94fe1a9f2f7d88381123e2436c880b316ddca42ea9b2c4d6166bf796de471b11ac7e02033606383ead0b35aec4b64ca7a77e7dfd9bb1beafafd746036aa3acbf9113d672881260fa418f4d82fe342ea487d916d67b28d23763b57bdf8c3bdfe144e799f3e8be4617b1e3c9de3367e0bd5e3ac2cd2cebb7e67d33b674ac360fab298f9380250f18afcd00e8d2c037e3b57b4f247bed53ba509bc521988afa00f86c77df8cd7eec2b8c6e6b16599e55225b065d9d95225ae6519ce5225ac6599c45225aa6519be5225a86559b8d61bcfe58a9be91c28b6d9491123afb1a31b71aa05beb8ec55ed8ba9dac7ac1498a9155c099ae1bb147f5a304f7414d26afacaa6a6ff436bfa20d6ebbde50eb5942395500adbd6cc1e21638d5ef1af41999db4702c50f80c2d0cac56995db4702250f82c2d9c0c14eea685570385cfd1c26b81c2e769e1f540e10bb4307892d00e5a78d939e6c7aea39335da57e82608ca011cd0cd3dd0e560e138143e132a9c80c25da1c249287c365478150a77870aaf41e173a1c2eb50f87ca8f00614be102abc0c853b7c471a85ec38fecf538e9b01939e92eeb3e7502ca1936854d3402148c884cf9f89cfd3ea2c7a944acca2a767f6f888582343d6c8a23572db1aed17ac91796bf418161db6462e677e2e746812e9662c5d9e91c787eba97cc318ca21663eb44686046be4ba3572df1a19c3bf17939194a36c043058a3c7129114d99c8ce0e8cc27372f467948db36cf267d19999f4b85211fa5de40f31cf729dc7686713119498ef9141c0c291e412f9b8d396b64ca1a3d618d7c958ca137ca83d79ccf43f47b0aff58c2fe6378cdb0e2f0fa5fb6947858af9c35b2187967523cf2e4172f1d4bac778fb264bf42699889790353b2c17a0f291bdebb948693f8b7312533ac77d27d4cee4b75c21ab9d18c97d3c6938631d65b4a19f3bd6929584a7857e39861bfaeb6dc4b516635a952229dd29696a7f22db293547a2b2b7d7359e3da5d35ae8fe1c879e4700c5fc039bc9eb246fb456b64128bae6237a6acd18150f575e7e68435f29988c33761c3c2b3984690d1632250183d6c8d8cd1ab016b64da1a3d2e5a231f5923a7f1cd3f618d5c14714251041791f061a03d324501879c8af7ddd231bc99c38adba116c3c8c2bcbf3455ae00ff68641943900df73b1bee78d6ee76d6eb7736d0f1acddf32ca3c7d97067b3ec7e66c35d6c92c321f460ce79bf17e950ce23f9ebfea2eb38a8a7ad91197fe955ece2157fd1692c9ac261f04a6f61e9903364fe0a7bb9b58b527b0f3a7c7bec06b8f4980bf01466c5e320a58ba03b3e36359b8e4dc4460f3fcdf00c7446e53cfd18247a0826c13f3e4fc124ca891e836104eb313b5a2347ad91f3890e8323efc197cdf97a34c567d01694628f48a7807445396d8df623f8e37613a4279c03d52b768f47236779bbb90970853aecac7773d6683f234f41506d8c981b1300ca49f54900c5a4fa24807c527d12402ea93e09a037a93e02c07efe154daa5063a467dce148f8b694416b3d29a3cd1abd628d8e59a3e3d6e884353a698d5eb546af59a3d7add11bd6e8e5f696c2361fee32313a8bc9513b39526943d0486e365e36db8aaa1bce21956bedca8103f906b9754d5c0d721bf175842fd2222c5fb6e4d0df875f7bba24ccd0fbcbf8f1997065aa3e47a6be815f2e0fb665c3b92f867c0523bd4df60ffc05a6382ed25e24780cb228060633915c7abce18792dc935fbe28b4ee586f5f184f7d6d3e96f1f3f371ba4b462741b26f6382e361e829afdb5732fa74d7ed1bc97b788d7b45268f1ffbd9c64528eec008c5fde6da221477274528ee6e4a84a2b6b9bdb311b677ca3ad77aa0f3ac07af615e73597c99263697c51ce914f76262f39c248baf998af89a5922b2f8fb82aa8bfb69627349137fdf6da8f0fb3b4c6c2e69e23e59c78b747e4aaf1105483ad4fcb4c4df1790109000f48039453298bd4592175fd5155911f74b25a213f14dd2618aaf174959d6c5d7cc322186b89f741849b9c15d1ef7161121a0035c800af0009274eae5dea2f8aa2eee2f896f7688af97c5d7cae27e5ecbb4be3dd918df9e6cb99ce51ed8d444355168ab98dd66a95d60b3c34ddf126c964e0cab9082dc67484a81148926f75524832885be322991324fa6da20221570de34a9c61d8174c24ceb3a84193ac419a1af2f144f8283fe38449a8810ac3b428d9e2cd5e82034c4a64ca04f225e4c402ccfc662f11e410a542fc4334487b86101833e8166ba74bd423459901559b05fcd781bcb6f74b53b1e327ccc1907d46f65795d2a9589262b7cc47e5f2e8ab8245588ce6fd04c37ae3c8c794c929da774a1972805015962065e76481d92462a44d00931b80196ac4a0c8ad4a5b2acc8d13a276292595ba42dbb486479762320197579da0a2739cb8d8b268c8c56e668bb0eb3144d02eec62f326b7b694b8314cd689d13a9486b1b179d7f14c93df44dd1796388ceb95ebef0bcbddcbb293f6fcacf9bf2f3a6fc9c486a537e6663d9949f37e567dfbf4df9d9fbb7293faf437ecef56e4ad01b428236b8f2b311233c2b44135fd68826e68876c87425e7ae2e537c70c954ba4cf1b766a9cb14f7befdb6aceba6b85f324082d64cf1f78661c22f95a03553dc273f781faf1a10a13502846d11ba0b4902412007a480882d433f783f8510fd6a69fb83cb249f175f35b6bfa5485d0a5e9464c920e26fb7ff46eb283cb842440a0562355c5d92cbb454dfbe5fee30d24ad740477c4b91c4b74ab2f81bad430494226013f7cb2905ec079789f89622be55127fa3417b682eeee79ddaf298e34f9b2b63a788348d82af471478b55432cbc241b9b4bd3d5e0af8f70757489ec441063fd61c40bf0cf06a697b872c69e4c1151e5a860c200b30edf279d2cea5d14c41e0e07fef3f1b2f07c8a5c80920f8521d346443d0a56e957db89efdfd67d7e357de39179b2f01988cd353f0d32a4b30485c21c0ae8fc80ff8b57f306c6a0a891276658107c31a51a44863fce2bf03b232571878a768462a6d59207a848c2b08e88adc509e69e1ffc483548c4d7162238813b1a18af5818168a8627de0703454b13e30180d55ac0fbc1b0d55ac0f1c89862ad6078e464315eb03c7a2a18af581e3d150c5fac07bd150c5fa40bf1baac88d52841e46a214a187912845e861244a117a188952841e46a214a187912845e861244a117a188952841e46a214a187cc28459413f97656a6911546acff58bdff54bd7f01ff7e5eef9facf79fabf75f17ebfd9fd6fb6f3a7faf2244a0fa6cbdff64bd7f41acf75fa9f70fd5fbefbac53745c47a8f22a63753f5fef3f5fe6bf5fe1bf5fe7769e9056c73188b6c4c47eafdfd48e92485aaf79fa9f75f15ebfdc30e176e354565579f72ee3f0fb5fbb8de7f1de97ba5a9421ddc61b1c721d0dff8ceb2bae9752ddc178f799bdb04e912793b898d68976ee3109e420e809750dd7977fcfce09362bdff3432f931167d52efbf88cf685e44b6ee227f17b0ab2791dd79da1397f1bb14ef11a49674e28e37aa1e9f3663363311ea1e393115097a5e611309f064f30d7baa61d289860dcbe4718719d6fb3fa3a3966d07dda40d5f85c57affd5768e784e1b9dc546f41dfe149f03bc346950f84f288c87f69d7be810bc99adf7f72751f1471db8ef78bd7fbede3f50ef9faef77fe54e1837c7491cbaa69d9148673212fa330edc57c253bae012e6c42660ab7bced21eee01c5c00a56c8382bd56dfc0bcdb3b87c9c72c8cfe352f259bd7f81ab3044707cc5802e3b4bd911447b1657c153f436aa4f388863c18a4194a770dce0731555321c7c7c987c10d9393a6fa30a87838903900ba2391fd53b1c0491aade487716d9fd760e730cc0b0e75c134220ea0303f581c3f581c1fac0bbf58123f581a3f58163f581e3f581f7ea03fd9b21102c6edfc68525aab9ad4b7103bded49a86d9b56e00da1b6291d3ce95ee9e05981bbd085423c483d28c432d17491a01db84c64b1cb54e04f49168959307543d45d1f0ad5f6a1501c1f8abcd4880f451751b240351b4b320b04b3402b0b84b240a439c1ba7a755ec993825826f863c89a0ebfaa823f864a6f0f6a12fc94aaf35a9e14d25a87f5ea3c742b2b1a72565495ac68a859f1a096053c3cee43c661bd3a2f968968c8a2aa88862a1ed4a0f1c6cd5fb82fe964ca6cb20139eb77b7e82e6563cee0762da9dc46f1922bd79a4ccfe1ce938280b8620fe09685b2aa1524250e34706e3607ce7f0eb750a88e6a3c847e01f4a0aa697241728e46e4b46850c68c3321ab091bc9ba9c9722dba0f8aa29aaa408bad40d4b73c470eab7213301d0502c1906b514c76e259b86116d8fd66249110cb92c714dc950196999b75bc29bcfb322e74921da3067372c5747e143c4b323d3ea68f35ea7c7d5d1689d634e863af6034d4caf77e040969d582ff3543efb5332272b1d9b72c946904b3633dffd5433dfa1d42971a54e29366dce9893e7879b2d87932ae7082b55cec871374f8c3f550eb43c4edb9cc6d45f6eb61ca0e74f1f731dafed0c38476272e65c8b82fbb3c97815290fe5c3b148952e27dcf76c62cfb376d7b3e12e67c39dcc06fa174c91d3acfc3847ad91639894e46a343fce557f7e9cb3c8d669ecc6d5688a1c7f11f048d3575de5a5c8b91a4d9173b5d1143936eb598fe56c98d5acc76236c05a36cc52d66325a53e608d1c7548db740f3be41c5a0e15fc4d42bb7e55612ff6e67d27e5cc559c789144284e5e1d1f30cdaec3836fba33ca362125a7317975d8081e9bfd6c3385483353888cdceff3bd8c8bd6c8589f9386ef3d6b6480be546ef290016be4f31f4fc29091fb8f3f554860e89a9a2a24f8089e5caa1078c64f2416a0a1fc20cfa4cc0f32d28483d4420f3519dfeec4cc20a187d9accc20f8acd6910d84315a6b340d098de443bb8632c2b435723ff1f005444947eeb235fa3eb5e8b46d4b0a3d70a49ef3d826e9385510503ea49fb13802cd3d83814aaf313623472c5fa4c226d37a844c1f7333e60e396941bfe45a92bc74b8f0f74b6c30cc342b45f24c43838b5c1353025c3180f28c43fa22630cbca350e3e1f20194f4251be31aa3b810b970677de99c79d6a904b8de00caab5e6a669ec12a00c49e593ff6543c8ab4696fda08f6269f82fd07d928ee5361c8025b4e9a91154945cb8a6509779cb2629759ca72769c3ae3d55f978e6a1a3e52400908011d870c500122400348000520e0c7fff3684fa83ff08b425bcb9fba88d2226f135afe7450eaa017654234a30f7af4d2bfd01252d1ec2a49b68bba4ca54dceb6bfe4de96fcb7c42cd00b5daad00bb5dba0178ada432ff252678bec48e31e6b6f4a05e91de145a1e54f5be84ea2dc676f25ca7d9433dcd9eb2b4b725f97d9a694dae53eba9568ea7dee66629fbd99d8e76c26f6e5a54e7ad145940307b22f0156fc2d6b06fe928a86bf14292d320bf8ab4b15fc55bb29a8a2f6e06f5eea84dfad2d72d07e55e2daaf4af1bba6b2b36d2a8bd8576717538a6e9c9a7afcd66967faad53dfcbb04da00a1a53acfcbfa24a896fad62bc237c91ad657b2e97dbde923524ddd862936c00b9fd62b495b358b1656b44ab4b12e818dcc6600b7e5dc2e38853768fff863dd469e070f9b1011fd72bb03578feb6c720837aecabe231d0e0ebc218442744c17717b220e552c0e9d08d3840b621f1906a6fddd3bdfbbc4c37eddf56257a915795bca4c1558f2677c1ef2162488dece01f52e9067e5ece8a6fab5931af66c51e2d2b1e2229ed758754b14cc4bc2cbead8a7955ecd1c4436423efde6fcfe5b63fb1e8afe6057f816ed303b3801404b59cb05f6fefd6f3e1029bf56c30df5e7d41d60d49e322f46fd6938305a9a45624c5d9ae673769e66e7d8fa4c5efd717a492c4dbb1972445a810a209bad409ef5214cadbb56703a0ca541daf8e2b68023113f6eda3088a1e02331a6ee5ea4f8cbabcd73269e73e1af0ed631b5617fede3dd446dbf77aedbb483484cc5586b092fd8413b7efb7e886d49797b6a63b1c8f67a9f5ce3bb601a9a152e8eb137cf7cffbee7ff922da6c5e1232ba21e161c8792913e7cef8a3761dd83c1e7f5395db54e57e74aadcaff8ce08a5ed1d5c7f844d7d6e539fdbd4e736f5b99f8c3ef744b3796cea739bfadca63eb7a9cf6d687dee579b9b731b42a35314ae84ae6cc02035aafb118dea7e244ef74b93e85737a9a8531da56167bd715167c46c28eacc54102f20058c800e50019e9441672620108dde3441673fce80b21f229eec553b9e4cedee260922cdab1852a62a09d0a1a8321ea84fb879d5092c8b8375c49b97abf39a54a88ec227d10b30e3b57cb23166d1349c768c59b726d93164092166ec0033396580193bbc4c4e8e2f8b4a0f79a7698258c34845e6b484f79dc44798116e8499bc1961b66eb142d9142a368250111f6136ce8a301b6745988db322ccc6591166e3ac08b3715684d9382bc26c9c156136ce8a301b4f1d6136ce8a301b6745988db322ccc6591166e3ac08b3715684d9382bc26c9c156136ce8a301b8f8930ab9057b94263856c974372237def3549209ae408910a294b02d1858aa409bf230ae9d68ba4280bbf76bedf1da6012f7e2fb65154433075290f0d34b920e74bbd022cb66a5ed214e10d53e9221d729625a85a63e7adb1316b6cce1a9bb2c6fb456b6cd21abb0b37bea2ebd6d822167d265a6347acb1096bfc04561eb7c6a669fd7111308d1fb6c6c6e8d58035368dcd8ed336a7adb1796b6c44a43fd6f8943576d51a9ba295435874d82d42867c2097a195739f3248ed27d3b14044dad849c0085d58a418e6adf1f79151afe83a623c8d7c7aa55791f52bfea2396bbcdf191117ddd85d001cbf89cc47ebc6c6b0d167febad44169c8bdc77480578f458f331f43c84d80899471684f82666307bbc3b09db7c6b9a1675ed01917f271049d2571977c8cbbdb748dba07f5fc87f7263960019e0df3a8f560a882fd86c21bcb3f683d10a5c0451c8c4f189bb0c6ee5b63e700f7f8b1c77f88bb138000637c1f5fcfcfe2e21482ecb1e314c68670927f2ee00c1f42bc53d6ffcfdebf7f47715c8be2f8bf52e7dceb8c88c508e13731e14b8c9f41363722273757709ad24c31d39a996eb91f524647d692102f636c1cc7d8c6f689831fe161832484400824d6cac05ddfbb0e3ff4e4f3cb0cfc32f6b5399ffc179f55bbaa5fd3553d2d6978d8472c5bd355b56bef5defbdab76d53e1db926e0df5388876337144e1f6a9c3e8e604a92c179d7136280f22e32988950e3f4470cae713ae66e8207142d72b619df5fa18262ee26c8207a9a319d6f9cbe0273c7690173fef584205c94bf7233d679985b2fc8af277810e24ed58e6b9d674e35ce9c6e9c39d33873b671e6ebc6996f1a67ce35ce9c6f9c996a9c59bbd629e4b6abcb95b7a854060a14daab1bde953b1304b6d76dd52268af3d320282daa08133969a2169f4bbbc5a2454b03308227f504dcb0ca1c64cbca3a829627d2fc228b5031eff46aa45d5c3658b82cdd750e9babed438fde52874b0b9c699438dd3d3a37434d0c9e22cedc374584c8fbaebe252e3f4f987fe02aa5baa7b7efb345069edbb7a1aa9fcfb70f534d0ba0fdfd5d316aee9bdd65eb547fa6073aeda1d7db419577de934d84acbbf742aad2771dbfdd8afbb51b57c6dfbeb61d8fe62cafaab7a49d540f2459b51cab4ca99117273bf52b4adb252c2c608c92885619564541a5bc2034a668418344229aa83f4c754893108a9c3c60831e16b10df5cc88ea8c4d0d48252544d4b1fc4592567d834f2e6fef8dd031b5a2cc890a662ca10c9e994a50c068e2c1a5bc203987194c194a10c66fcd034cacecd4fe857901decf18381214dc54dd69708e47d5e958345dbc0c50e2d3403f0aedca1a147e804ff2c7a621d6d5237fc4bd4cdc21d63631d1aea8209ee11f84b3b5db74be48d265a968135b3882dc20fe33bd130b39bebb5f7ee55ffd0890aa41ce283b6a2414cbb68a1cdfe597e0a05a7127358b53279d4d19c17813268129432cdd426e9fcc4d13f8a3adc9ae006055b508a9d8c94c10a809f92acfb858842298640a888142b77fd825c2f30374e34cf8c1c691cd638b6016bd92720613a9f98698a34a76747540da71045cb0232c6f37198e318676819e7ec5bc27a4fcf8aab8698ea8d0319c26b87864e64ca1232e5f20ac914316fe0220ed7fe1bdec008ece34a6f5a0eca6e5a364f843b75b629d4c2523604dbdab2d59f39e51204a3c7a67fb104d7d5855ec299c2260acea14969d02aa361820a9a3e8ce8e44e975d50282c1de588460c6c1121aadf90dcf37f1844fd65b7c6d08b7422b5f24443fd385340fdba954743b8a866819a896041a4c511e2533517a54170b6cc394ccbc5998e147a343291f785abd633d9a593d5a89fc1afd0b80ceb6204b62eb625b66c1be5969caecc54b9758112caebe16d75d32ad3e5100c4c0ac3aabb2ad3f58fae7e74e183258fae74748d4bb0a7ada9842e9045ac0ceaec1bdfdc470acab0a51ba4a0dcfcc4d0b374a11dc686450acaa07ae300fd35f57edd6a65d2eaf1ad6547287a65d8a208293665d0a23892ed22bf9a557668caef2ce5e6c786f2dc88b2c3527af587d4cee4a1757cb709a5fab68da8373f417a0bab92576ccbd0e550ccecc39f6985a3cc153ee81c96cee272877830227749d920584fdc7fee0cd3f73be4f6d61b27387fbf081a8947b06e4c849520d6d913a17c2c19a3306e1272f964329430e45aa3cc92bdd82e5a89707af6c82eca66d0a6ad9d37e41643bfcb8ce8061e10771bdf5ae8c1749b11628edcdc77e380b0ff4891276c6a0f79a4cda59813b6b88739d2f4a28ccb69788ebabcda0ed04663ae111c6fcc659192d8e564412d16709c2d97a75d094e4ca4697189f9b8b4b84438dde8465c1796da706962afd3ae8c2e3ce4909184030b432f084f32bc4ce2a65b33dcf2f6aed6eef73e143b578352c7d583718eab896ae8ca0b648818f0d5838dca295dd9da0ffeabb1aa2bafd85a9efe2de675656b4e372d5de925e0bb5a575eb32d9bfe72dfd5bab28d8cc0c7325c579321e6babadfa0f428394a8c92629eab6deeb99a8c2410d9b751e50272e66c2d8bd7ef25aa81959dc4a89c7203ffc3c686e50754cd0bf4923ff8df9593fd382b2b47448adfa697284d4a8912a078293a40934c90dfa62b1bff765679ec6f6795c7ff765679e26f679527ff769622f8315f8eebcb92dd4c4a87af58d95f009b4c0b90675c853ef0923e4050e52f660b85606b096bf9ca177190211373095c405a7c4db34849862fb1b4e8eec6fad2224c5a1bd0e8286a8a7b721dda22168c527d958f8b965ad25d59c8e50a6d8233156cd9065d881ee5c72bf1587033965f0416b7f5e805438da0b8873215893390cf574e0a52d9b5139859f468a26f1a2f0600db12bbc40e13f578dbf868ee3ccb8d515e37e47ebc6962246b9613ceaa7217de59359aafc765b872369ae6d9c513934452cb3c27d622e5f4ac44b0a69b2b358a173af1463f412fde836b5ebc1f12d9ea57865cba5adf6fac09586b02d68f52c0628bf18ac5ac60f635616b4dd86ab3b035a8db19dd948a546b3297ffefc1ca5c7201e657c69a08f3a045180f34385e7fa75af91d412b84449635eed9bd681a04a319aa2165684537f74280289552ae858918209fa700ba214ecd6669ea885a1427f7f4d0e4a21ddd2486e4729926634d4db598f8c82036b0a553912f6c37a4ee751f0f01d3a50dece50f3acd77f84f81d0f89ffd0c85e06039881ed88429654988d81bc17936fc32899fef51de227d0552deed9b50f9a2aba1cb0457439749ad2a7bac8b788fb811a5840d4b25eca90808aa8a6a6b2a51549b86c3cf45d00c7ac6d2d997a6ab3c8ebddb65a82499f4aaf2a7090df06cec3d4ec848a72965ff71422b4d29267d9dd017e962ddac65ed92aaa9991b930aed539489ffff27aa52528991b10d5519d0556548d588a12a66e5f352ff8d49ebc6646281d62e29db6d0d44f31e9528afe8aaf22faaa6f4563e2f2514686d65bbadf460a547555ed1957f5169ded51dfdc788a9f7efe07f79e7feab943cf1888a8aadde9228553ea7d3ba1c2e24758ac182ae898921231af64b6c5a9e1827066fa38836484c8bc41f3356ce6bc8364a372685b25aa6f2b9458630924cff20ab89d71fa1d0c65ec712bf2191080dc8673ad28d28bf20bb254292654846220b0a48718950f43014455b8b3202225d222c655e29d1473b40ba13e310f7887bb729f654ab4db1a7dab12966e86b12e5432351723bd661ddc87652f94428309a6833a21051937214126e98a5387b6d8d49505c7c020bf16e5a73145bdf86dd6813485cdcb47c33da188447cf6e468f33db730fc3b3349ebdd81614ddd67938bb294ef6b971b7cc18fddec9cf4c768ed87d57279c3967a13ae92c3a179d692518acbe150a82e970287d3216bc691661927984be73cd997716ab93d57dceb4e207aa6f05024039903629056ca6c984fdea2167ba3aa1b01f5a48f6b1e444ae9872f9dfb9e8cc398bd5a38a73d159ac1e831f67ceb9120167fa8073cd99ab4e548f550f2afe272b8e1b9813d062da8233eb2c391715f643335d75e6aafb826b6d937a502065365a4b51d36699757fb09623b529510944b6b6cd6a420aa5d0a3ee100de8099de8516e782e343347b277b6abc79c45e7027bfababa9fd61afb76ae39d3d571fe3ded5cf7beaf39d37dce95eab1dd3c3c5f7dc7590c7c5ff5f25c7066395eda495d982567a1ba8f7f2f3a4bd563fc9b768005f6f23663b7ab0be52d6b705357974686d3390397740ba70dbbcb1c34f0500177197691985ddd8f3db37ed0d007d126f4b753a87bc3635e6ee724101b77a6ab6f52069cf9ea3114ee219b5a90e8b70dbdcb24d8c8e4d763cd1c26c61673f3c6c7373ef9d8531e99e7b66ffb0dca620b6ff25b8d631d1e1e4edb9a9ad1b324ad1bb9ae4c316b7465f2d8b0ccae8d4f779976a9848d729761a7f356a9f8dfba9f7ae2b18096674bb53c5ba2e5354b82fc22738a35326dd0ea3185b532ad16e72a1d69d0d06c32807676e6fcf8630a6b5ff70312a065ab93d509c8c41ab7baaf7acc9901fcac85fd2034b21b805676a65950a2d8d07fa685b52c2eea1a09b37f34ccfe518ffd20f32cd6b9e2327fd465fe6888f966d68f86593f1a64fd6898f5a341d6c5225958f16d6a19da3baf3b4bacef38f3b4533a8b941cdaf5cf8cd7f4ae7f46cebc1b5c4ceffae74e0400c0c382b3e45c41d509e75af5adea847315310cd563d57dd5a3c899a94e3a0bce85ea24cd328daafb9ca5ea21ba4c346f5437f590b457bb695eb1695eafe956fd21edd5669a5763daabbf34af3c99022f69f028375e33a75bb5f0b2d991cbd57ce7a059df0cf2eb5c7096aa1330d7cc71ba479d398536312c631759b7a45390b3a03817a041c679b03a01ddf6225b26e7aafb9c0bce5c75dc99559cebb44161e23a0823ad3ae9cc3833ce122c2af2baf45ab52d7c51a143ce1788243e5f55d96609fda79a2f70ceba76edea435bfa9cf79c0bbbd1968e2d9b60ec2e550f3b57ab93d57746699f66b4abef54df64516f53ecebb6a02dbb76ed465ba80add15df68debe8c73a13a410bbd0845848229d543b4335d67b3c04cb2dd9915e37940afc8f359c6b9ea2c56df72e66032702ed399942f86d5090a300dfde092334d45944e363155f755c79d797f2679ab133917e97047d07116a00f2e55c7ab6f550ff02c8f87a041da6b5e7cab13de5c0413185070e69ccb7ef47c73adf92ffefbcb405ff568f5d8ee511601cff70757053795476d01007f9973bf59b4b76af05c2cc2cbc2449d5136cdb82010602030eb04e3afba68036ba41b669c86161d97571ec9790d2c432e6e8862a9deaae4a6f1089e39b04eb9001025726f407b086d8aeb4c36bace47fc5b30f268bbcd3a4bc2256dad55ee71ab2c77dc465aa9c95d46b0998e558fee6e6a1b880ab546a009bcc4beea31e78a5fef2c9e57360b34d57073b532a05045b2a840edb188507dd1285125bd577d0b0a7089cd30ce5c27f2a72667c99963d3d0125fbb285317aa93742d830907d6be053adb0526abea1fa924567dcbb986aafb010f9534ae094781b89277ed4a87ba39afd7beeabe74a0278b2af468f5587a77b0fba677fb9d34d41dfdae17ea687ea70afb517958ce0a90339b4e705ee0cca63b977968e06759c5c98173924d796c13a21339d247dfdc0c1fd2e681c5725a061e382570de03492a065874e350d38785262a7072a90fa7a994d2c19e5c00cb141696de245bc6a53394e4e2190a5eb572de4361d9cd9973e6dc07ebfa78992537ba3c6add31d45a5e740480c757ceefbc7365b9fcc6dd9c0380275a01c4dd908be797fe4dc8ef1bd168f9fd6ec43b5893ad93f8a52c019bce5252ae625968c2ba8a9286a344573b7fe4e3ce57a1e8caf7708fb980baf7d6c33edec2aae9da584b50d2f8b1d6c6136ebe9c520d32f6989b4bd0d3d1431238e7a63a6d750234a18048283d5859deb97732c0e59d81b3f394559e81bb672eab3c07f777d4577914ce24af559f85373f3209f2f121677e14ce5ec69de95126de8d824ec0e5b190b4ac9a3b7a42afeba8daa01d7d28878f95ae7fed10205cf7dff9e32c2cafe401cffbf140a15bfe044f0a8a671c17915b7fab7e9b9055d7f29f100cd66fc257045bdac0aeef70ae8cd29e375a3d26723216f531d6890689a1ead9a8e51f5fe025c9c87fb64af49c144bcaca93b66ddb264a44a243c2f5ce15d17ccd112d03cdacb32447342c67f677c969447b026af9bc4308cbeadf93fc31dc1b33ec351399076d22e39fa0a3cda8cf6fb454ed9bfac1fae1da4cfd48c86f477da27ea476ba36234a3a503b559bb91d5a3353b553f5250a59dfdf0cfbd7a6ecb56fea87eb07a351fb6ba76a27ebef86133ebf3d559bad2f862367eb47ea4bf5c5fa01ca6033fcd9fa62fd7024819651007ffb486d9647b3d8a0f76c383d6baaaccf6f1f6c26390b989b224fdd9ea195543fdc145d9ba99dae5d09479eaf1fa81fa9cd36d7c88126b8db87ea076f1f0a71eaf36a666527ee665672e2ce3ea4c7be91e4c08122fd8939b59224b3a3a8a6c4077e65adadaf80d58e267e06ac59d6abcdd54ed7ce8dd62ed64ed50f74ad58a44b310429988000f29eca6f2de42e56a8188147c0b984df645e316aa76eef6fe513a3367b7bbc76eaf6d5fa91567e3198b173edd46d3ae31c44f543f589dad9fa1144ffc4ec970295db676ba7eafbeb87ea875a3ac9b83d55bbc0e64e8f846b682da3d4667719f5a5fae1dac9182d94d68150ffbc7db07eb03685e89c7cfb6cfde0ed23d25b71721030b1ae1fba7d16d50fd40f86677b14bc19274ece7bd96f9fa5abc8edb3d2db713280ac8fe2186deafaa17a4425f46ecac9417a820539045087a5f7e65c90da29e1e53940539ba59d487a838e278b9b7ff58e2d6a47bb729d28d529751edc0e97139d40a376f427eba1d8ccae49bf0f83f40b66a3621189c8ae9ee937fe78e38f7800e748a97252d36c2567eb43439807b401bb70e36d3794b1f59b6fe93c505289697a9908f603a6adab59cd0df5eb8687fbc6db38802ea7177339dd7273152a27fb4b6eda80ad0f157920d9e53528c800b00f6c536e8149600e98025e3813409d110562491c20eb9686fb0956875465c8d64db372d2c861a5846fbe75f32dd2cf42396c16f010ce170ab692b575039b16b6947e828d019cc59652ac9c1c1ac246165b899d23eb9606f480121000cc8014f0257491ac0c292525a764957e65fbc3f9622dc895dbd2a8af3f1dfbb442040ef5596a3ad1b30af159572898511147b734822cb5c599b49ab72cf0b89be8669b182c78b3ad60c988066fb6e943d9ac6ab9129718be8d1bff8f982847f0cda5e8a57957dea23d59b564af1094749ccdba2e91e94889085c41a7c8020090a6f4828541d0cf5b913701422f11e4ad2886bc8721abaaa5e86b9f9ebcc59223f9b35e7e366148452d481e5223087afc22b049502664d1e428fdb2977d00e70b11f29e7c358073aab5e62b99175e2ae0903501e7410b385d3f1f30f3aa66a1f5bfebdeb0e1e75d01b147958a3daa4cec695cfabc7169a67179bc71f958e3d2d5c6e5f794c6a58b8dcb271a972e41389430ef068e342e9d6b5c7e5f695c3a00e047be1b7f1b123e6e5c5a6c5c3ec260df6d5c5a60193f6f5cfe00e8f881451638d0b8f469e3f2bf372e4f06b0d2c0bb0c3144bd0be88eb83c51f4ef372e7dec26ff7b3061a671f953605b90698a168c230fa525f4a00b95e55750a846fcba5876e14305f6cb162a4c88fb247e712fbdc99a0df21d031297661b97df77c394f8678dcbfb01ea7db7a179da25f61508fb4dbcdf6dab8b50f9ef019747026468d4c740e96a00074d3801b0934d69899de5ba45f20bc38be173dccc6b88219f89849e722fbd49b350220a6b6e1f3747cc51def397bc30389495c89ad8f58f2b1436a970d7d5d3d3b56d9b58d804e18f898312313300d189249c4441519f3b0c69d7770d357c5e57b3f907cd3e45c5b7bec6a553bbe3f600a1c39ea05071d0a17d40095cc829eea52330be3f96620d3bc7a5439bf5fb4fa13b2e70215492b9bd9b7ed0fbf93895effc51a84ba7903bbb5d158aa474c8d351cf86ff55c451d33a7e0fa216c4bb82cdf91e893c0bcf7ce5d2999371fa9e0b7f8e4d4f62d15596414080f9cfa5a57b57c0663e9c2cc8cffce5d25906e8455164c31002143d1ecbc7600a8ba0e80943085030afb874604d0adaa81c4ea6f95728d3a2e0e0154bb7cd3607b27dc0c0b5e02052d9f67fe8b8046d425d5e8f84ecb05c8dba03ea4873dc8974e3f238fda4bfe9959fae402277fcc991a5d0e868537c330fadca14398231dd3318b3f5218c897e89babbe34e613806b425c8f4a6969ca224862d61dcbca203e8c30d1467f922d52ed435ede2416b1721e381d400d6ecca49833dc7453f4ad82019050f1a957345a5543939a00c541634faa7d8f414173114bd605566e987068fc81283bfc3458c04e236a34e2983672d3c6808e85162940ca54091afc277a4e72652030f92ab700a4907f20bb0fade0bf790a94ddcedf55e328c4c92d1b5ac89c0355c7354388c73ba746877841f86a0b39c57822d28355839692093142a0b5a16c6bb1b616b595c52c57e15e15991ae2ef44c98c960f09978e6e8b417c398c43e78f99e32a158cd3e15514b43e4664229698520b10172bf417041e6a19337325b1bdcf6f542de675cab8a7c79561698afc70eb71efd78dbf5c15959b0745be63bb4e4b62a5fb5dc56f583fef7fd6d55c67939508a76342aafb336346ade6d54ee209cb5a91770bf96d5a2793d0b6e4e9b1a14a2597bc2a7b439e11d1c684e265ff0c67403eed7fd6d4860b9ec725f3917f5abba82766435d58666cc7a63338bcbeec0649fec7715136d96dc3c0ce5cede3cac97c4f32abc44044d063b3dbcc5f837ffb8bfed95d554c6b45639d78ea6cade3cdc8e86eaf127512a567873280fb85fab68ae1231559c61130e7ccada0c9e8362b32613addc49d30d799ff779ca04ae49b004436d993401571bdab0ecb561996077ca74bff9c72a1ad0d00b5076432fc89a0e1ee382a6a3c4bc967303eed7fd6d37432f943dc6dbd262865e58717389dc449b05e95144613546aa1092ec786b244b6e2c81cfdc2c29ea05c5b674432f28a665902c566e9eb4860c4b2f28832aa63fcbf4964b94415db12dc5b42826655055cc563e24f82ef272b2b6de0cbe8737e0d3ad2d64d3cb782f1745a157b8e5bb09a5fab21a315b7ac91dc10396811f4637b94388754f3b812752d92dd7e4ee73875afa1045cb72a83a84601025613eee82ad8f4f47ee704c8032eea26c804536aedbe5e9758839788d2972723fbc4337de26b26ef960ddf05255ad5859b8af9d93d15c6c7317754bb2ea8e9abccb2dbb20893a9e5790d575bffbe50578d0205989fd92ccfded43e800589a169718e7e2b7a5ff5f69da9a0fe0e5182415d68e0c1ef49181bfc36ee819629abf094c2b0f709b3ce12e5a4025a3aa95460a78c0755ccea4773f2276b35bacfff112c0d3e2312a1fd3c3364777f81861ddddabb6b5ac584df36fb70728cadfe690516caa0d97a24f1de793917f163dd11ee22429f196c43892845a6e484596edd227ec635b508a687ccf1e766b5344d35ddf60d27df67bd3a1024c881940f7ae3b0141d5a78d4bf8bef526eefa29403b6e20b581566b522be974f9e5763adbf07b9c6d48ba5b5e88b61dddcd252f208dee5d47b30d9553bd9f5dcc368847f5de752edb68416425dd4af8a24792f59268288b35dec3d412ca6a24e6e0e21ef4b1267e5c66447ca07bd7e1fc331032a4c776b9f6d1695feb0b9f7a49d8fa2562928cdffe109475811e21a17677019f230933e81eae7094220e12bf8f2b1c10f469dfc3f50d280db522b592ae585e7957d4519158badf156928e654e7de77448f1d2127e8def5c222e1521610be7f3db048b864090cdcabde5724563c91e4fd4e787455941e5d1565b76806c06fa5ebb5d2b792538b4a090f2803b6a6d2bf457540c143512b397da546728c34f8aa0457959ea7ca8134254aff14d39424b8aa4c535a6df654a9912c290ec0a11b7c918262e9062928261cbadd789b5886450aca20a17f977be6964d53c4698a324d31a601619a624b5364b222084fe02c5d310d8a401924ad0fefdae07cfdc7714cd7d9be733a04771db2188eeafae31e6701c001db32d400601494df9f78200776bb511febd2fa6ed4c7995cfd41da6ed4474746429cc94eaa284e3ab012225dd1094e9b8e4cfc8349299fc98ed5580f62076b0392ce16b881f3207ad0a041066e9ed4a0ffb4bf2705b1b7bb478570ff487a96cbb3baea1ed6cebb5737de2623b2c333147b7c06ff3689f6d4a3a76949414bc9b1964a8941f3c9b1e6f38941b3c9b166b389417b9263ede9490c5a4e8eb55c96838abbda8fe1b0effef8df358b6b877d0ffab00f34a4d7a51ad2eb320de915ac6143e9cd176cc3527ab0612a3b0cb558547af080f23f8861e67543f9b56e186a4179d136f396d29bb7b0a51bca4e42ffbe5af95aa3bfdbf203349c4c357a056b942278badf61a82e2d4a8712a124287a404e3127b855ff3cdaa692a2f23c7aa9f2b556f95a791ef560c3621f95af8d826dc0f7f3da804594e7d10e8394e0a3376fd95ae5ebc43efa55a2500acc497fe56b43795e1b50761884f29cd049bff212b8e8a7fc283b94defc2af49de6072c776c1bedd9d67cb57279372bd3993c36b65a1d1b98178154cf3db939c929b25b0ccfa2ee8d680b4aedd806db073ddb64247f5a0f9576267ea734d9d5fb5edd425ae5eb564f6fbe4acccad7461c64f8e94d0960f0cefdb60122c317bc6ccff01154c0451b4b3968a794a755be8ef7ec50aa7c8d06b151f95a78a73eab9a1899a440175fe99b9a9274b804af0d54be6683214a21f4c253f401a8bc975f17b0e7bdee244acc7a59b3aa80b0f7b29330b5c7e7dbc603f2479d0489652fabe0b928ef41a721d5226bef39f1c24b25aad7d724aa8741a272edfd7423eca07f5837b2e626f46fa8ab6b9bba772f318866a19c814b256ca9195c04fdd86c9e3136a13ed76026d5e9dbd174faf63cbb9b27099a658064b1c6a6090a3b40b21ae14b6c3403e4f0603954a7675ed20c9ff70998d843afe76848000de01c1020d86f94f16c964266b14621b258c3de6f33644f0f700c67839dde415da77780d50c5f2e53f81cbb60d989d817f1be706ab76411d50d8364ac17fd467a0e875fe6f54ce27423fb6b81055bf8d50c3889425b5ce8be0dbbd126efcce6979bd146da83dd239ccde8f10068370575031b77cb5eddf58c4d854c46ecf622fcd20ecca9a0cd81ae9c86de0b7eff9b3661d4bd60bb972e122d67e5630edb24862da1baf04bbbdc172d82d685e8d120e7e2468cb45ceb372ec22ff71b52bdc910e94dc283252b7caea40cd8c5a63325cccf94b07ba684dd33259c4071921f2905c9dd93f324c1711266b7b870f03c69c8b0301c28d1583be98152e83cc9b674c179929de43c2974a1cb3f4e923dcebbfce3a4b6ddf96a7196d4fa2829e949d28a0f9262ef7b610d9bc86e71e1cbb42d03cba11edcc51adbdbf4a75f767bf6fc6dbed79f0c65a2ad7e40490751329c0f7287df7677f6a56c2ee7e868c0bef13611f79ce4e746745677a1b7457cc804ffa5fa060dfde6c922f1fa05f12abc333e8b9edb8dfadc09b18097958d4e9ec9b310debf96c71a9f9397c9d92059460ee2f6529fb36886e6f51ff99d27d8467dfe388f480cf7708f407e89ca3d078a3b064a69a4a017d5828e5c115e760a149062e457ac96015b4a0e9b5f065eef242801ac7714c404fdc836436244dee98fab0744761d12a3f28e7c983a107996da3be711e1faf16e4bdca7831e636d5be2a7b92d117458eb4c536d3a143317899917ef55543f72e62806671139d79c7967b13a59dd079959c2a233174870e6241b18e1bca10ce1f0b4784723c04675c2996e6261c999e5d1a2fc795e1f6e2e17d0ff8e969d6d77308ac0217cb14cdeb778e78339c075e6aa0779d1788867f6c351aa6c2b8439bea535c2b3f8e1b9a6f0f4dae688fb6f6d73c425d87273e4b9b22137bd35d667ca86d0fe76138cb8693a509de9eab852ddefcc3933d5711e74aed19fea3ec599061fe9f3ce5516f79152fd884e32ece72a4dbfe0cc5627ab13d57d0acc41d7e944e05c736618a22567a1bacf597283747c5f08a65f84e1e34524da6a619ca739d369ce6d9a339b8ee334cd994c73ced29ca534e7a41ddb31746c03b613ceb4e25c77968211ce820273e352759c0526c0c9f945675a01ffc7fb9c0bb4e221cdb90e111c6cd299719660b24bb671c3a8a63907694e36cd29a639b934a792e624926de650dc8018b0024ac007c800d3dace4e7b7776dc85aa3a81aa932df67768fd337fde31b00f6e9787f2d4e78f0908723e57bdd9c390f131951473a23d1f17331f8649713fc8bd1fca1edbfc9133ba9cdd1f3a93d2512ee955f7660708d69fa5ea61e7aa3317ea3710147322ccbde4ccd2fce1f978c1995e09166f0a5f76feb940ff5c590942cbc40af9e72bcb4ab97797a200ff3fb69d25e7b2331dbbb704a59e8bdd5e827eb4e02c39579d79fa8b9a94b0ff92bb4dae9ed58e0da7a0fad58e5d275fdbaa4eaeed3db575ef89ea216bfb4f0fc3fe93694af541536268bceb9f7f95574bfd6a7668186b447959cb16f521ac61fe952a12ad90b78bb6d283fbb149a30bf96142ffb754e5652d5fc4fd58f9755e2ff2ecb90c8d2eeb9aaabc5c1acce32256b673d89c4eff5377fd732263e45fe5691e4a106853c2941ea5a5bc9ccb50229402c5aebc9c6b753b11d60dd5d4356bafaefcb664eaa57ebb681774653b31d57eb5a8c28765626baf0d9f1a819f7c116bb6f2db522ea3f693622b2a1ef3db5553f96da95fd96ef65334ca765355b69b798a289935f27655f9ada96cef57b65bca7653d99e577edb2ae7ea2f60e637954a68ab44b7e25ea804e9edb7d195302235d2e5f0f12a56bc95eeabb864e78b186939dcca52f7d7b689cd58c8264b5d3160d052f7654b2fea328c515bdd2229aa83795254d9f1a8385b5b0d7673714f1a0e13cd2205a811996756525247ec9161ac6154d44b19ac11a9e16e89030a2d776d9a1a393cf26c761999a8d355b8feaee675236acf9bf7b262517a96652d622d174dcbfa7985006095ab6a65619a6bb26b4900caacbc5a1917a269aed5ae5a521980b87d9b2f2290826d124d1d252595fed52c1397fa71098f927edbb40b769720ef2a5d303ddbc205538af324f1af1442247e70c143440b9504cd33f168bc5a59b6cba714afc638674e821a7e49b78d482d777ac9d2ca657bdde2d72f583ada20e7c4c5e4b53348346e6bc45511c52dafe6267cd028adb0a15f6e46dddd680b0b6c623f8fa2ee8d89c9f88d8646475153226f152117a1cadcd0ea95f9e6fa14d46973d144c558a15221d5287e5236f6e69a32f15028134352656228fe5d17d5b5bf55951236cca6875de05d17eefc4c6debbb2e61e7674103dc78cf67127dc1ac5cd2b238a7942a5fc1afa59af447d7e0c7d20df8dd6b10fa53ac5c32b2b8958cee714b7103628a95a2a4f8282e40944c47302b97280ac552155d532c5dd96bd0dc2bf694b0aa4b7a540e5fdfd3b35ee63477790a405fa198deddfaaa1e4a98a7582c7a14626e0116399c87b90d570041bacfe25c8b739b974bba91d3b5183d01a07295af8cf8539d54df8eca579eaf5cf9e3f9a9be9719549f19a73cb44177d04b31aac3deca25033d622293084cd5d8834995af7206e6667cc488bbef270428b1f7cddc7b3a12c58109b491cc799ed9524ba588c6e2a90e341547f266795e3a2bc814872cce4533f6b81c57bed270d425ae77d50f92a33c836a402c0b55be8aa6b97a034d5ba110d24146f1ba153ab8a5eb4abfff4ef523a87b83e0ec41b72df0198b3ac6c63a02a01b5017eae617a0bbc1b10f4921c16958477f0004c7816c6c0df2984788fe6d12e49a6d3f18e712d3981fbd6036b426983d1482d9b054301b8e794e02e4b1175cc1ac0767f2aab2954a66aad24354e5152a9abd6217b1aa6ccde95434ebe5d7a394d7e07694f22abb1ca56c2326fd4dfea6c40ba49fd2a3d45c529412a5438950fc1439459c402c7bc52ee141ca35fdb0b065c387a6111ea1e9cad6621e975453555e1eb04b1843424937d5a4d2d92b8345e5150b5bca2b80d6c21a45a9bc3c50525e29e9ad98e4e2d92b1b95571e535e795c79e509656b5179794079a5fbdebfa1b7f247165abca2f7703fb250243a3271cbaddb0231f3b180ee3e6bdfb05a50913a80cbba6b4861626cb5dac71dc05acb2d5c8ebaa896f541d5c2add0b7731bf71113f5639cc5e5882ce3ca63965e20d24ddcbc3aa4a24176375a248571114ce084bfc42e2314d40246257d20bab71b0488660741cbc4181555516e268895308588660659cb540bb6903213c54a1800a29941d82a0d9311159544d9993456522940347799e5c6b4d4a2dc4c1c2ba99895fa7e8b0df7e98078784d6c7828c48672a95f2ff6e0c1f0dd8454776a134a35a64e053b676a238b3c1d8a7c8c459e09453ece22cf86229f6091a1574c524fb2c86f42914fb1c873a1c8a759e4f950e4332c722a14b98145fe95b7e71b9d5c168f16939670132d6d6728f2348ddcd8147986463ed6147996463ede14f9358d7ca229f21b1af96453e4391af95453e4791af97453e4148d7ca629f2af3472835bcc9025b88565f2203c042194071be73f6d9c3fd3383fd7383fdd387f5d699c3fdb387f9dfe9d7a1ba2fc84f38df34b3440133e6e4cbdad34ce1f0b005e6051e71b5387148a756a1f450c712c70a1317558699c3fd8387fbc717e1eb27dc6d23f6e4c1d74317d06dfe7e1fb2c23a734ce1fa09978f221e0c34f3b0d4c36e7f80c8af1715342325975ad525093acdd38ff67203005086620f74c636ac2e5e038c45f04c4b43c5f42f8849bf699108895700ed2e6387a11dc5920f425abb968f21c84a700c145194373406b16d266214d0cf73134bc3839a9d610a9ac89688dcc061bb9b90a9acb1c2da4171b2e955f8064aa09e39473c7d9e1c4394d4e84a63d98fde4b61a94742e5321e96c8346d2387fc8edb9b42bb4d24c60e82e41a31e4e6256d2d94213a1f8e8ec3013cb41482fe14396667cbb71fe4be476cd69366f30454544b7cd2a0ad41c9d41654a0ac09c8791724600c667aef760969b403036ae37ce5f40ee706235fd191fef308ea4dbcacbc8536aa67b1aa0cfc3dfcf58254a37a023d0a12943a81005499d6f9cffa271fe3a729b7d5a4ccedbb24e9c232b28d49298296f57dbafad9822f4088ab0043392880d6fd73b00175b43e566f473ec4bda12ded638acca5fb80bec844f41dcb15bee9703e92f1b53132bdc338fdc2ff410cadee31c34c82063c2474e75022d2743ce52d306192ce20ce9e8ea6b4c9d6a4c9d6e4c9d694c9d6d4c7ddd98faa63175ae3175be3135d598faebeeae5c670077095b997c9c89872793f70168c4d85f7699745037adbdfc2ad84a8bb26b577699dc7a8ad232b9edea4206d94b0c94b7acc14d5d5d164e0fab05759064559cd68d5c97d9d54d8cee80f8d9649de52ef4e7590f1d8535f83074c099c6d4e151f85a62c2e3280cb22f5c79ee389b31471be7df71e7fcb3ee189c1875070dcd98c8c4cbb5f06a6de0859e95b8df714da25053a95a1868a167d193adf0856a25f50ba8f9a6d85634bac5963e01227e55a77ec108f8312db13fde0abba0ed5c3282a496f49e6e454fd02b5c7a82a456f436b66cf2f391da3b1f5f7babe941e2e1f8305ad73597a4a55ddcb368e32aace29a874ad4342ed4cfdb65f327eede896c0037242e6d0b64c9adeee2f65737c0fe6aafbdb2fdd5275bedaf3ed98efd550bafedaf3e0cfbab16916ec311e936dcf4a78de9d38de9b9c6f47463fabad298feba317dbd31fd4d63e66d88f213ce37a6976880267ccca28e35a6cfba80d71bd3171a336f03e0cc2185229ed9477143dca78d99090038ac34a60f36a63f6c4ccf43cecf1a33130a040ebac83e83ef7d940920a734a60f34a68fbb696f051318eb21d893c0cb7c1392841b70501de9e66a4827287e3a69c9d3a1e2a69b4b97e6a54a878a92f46d88e8b16d68378d32f057403ac78b33bd8fb1f3169430147b1eeaefc3c6f46c53c23750a4534db11f42ec34fc0d255c82a8e3811e154ca3850df19378b7cb2d8c5f8010d33ea321e69a19f29948b875357d9013e4d4381d4e84a3a73fabdab7da0a778a241b572cf13eed5c4938916f5df10cabdabba2a3e7101d0033ad37ae68b31e82d124855dd6c615ef91a7a17f9c6ebd6b457bdb97f76f738ace256fc5ed4cf943ed7a63fa4b3aa284fb5314ec8857ccc6f4752fe7e5c6f417301c2f346626e41b537c163beee21041b32da9e9f71ad3c7915bb1e7e1ef650163fe665433a884997c08fd8730f63f93ef39b9106264d910b26998523e15c179db4c012031ca9ea6e2d3faba20df5a7221c4c8ca2164f3509439dac2b4f2e7f9e429dd54126770eb75395b4b28b8b7343d27bd13d2989e4b09d4216fb381d3ffd2ebada38de937614a9f6a4cef1b85d63f0589530078c5eda9346d1ea2a6a04c1e867da2bd85874afd8a94398906f6f86a34b04095b64fbf92374dbbb52c117171dbb7a69c5c256bcfbe54fc268ca02fb4dc996ab16b146aecd6c89e6a814cdec82d716f6cc5a8a40d977de131412dfe44b56eb2a6753f1c5ab72557bbad187368a21ab6f2021922067cf560c3b495adfd865a547ab06a2bafd89519fab758b495ad39dbb46ca59758a4d46fd8ca6bb665d35f66116dd8ca3632021fcbb1891e0267755bfb0d4aafc926daa224b84df448023b8d6d7a49d57294c31c1d35ca4e629858f9b58d0d0b2bbf56350b2bbdc4a47f713fceb6f2bde0bbd5d34b1425a0a3d8001560a28812fad5d3390ae5d7b6f26b95e6567a65c6e33f26a382fb6ae44c359dd7f2aa86d47c9c913305dbda8f63c1f8fd2f66752c810bdc397b49375493a80519cac095326ec84c4a58c3a8a05b7661b794421b2f98a9f9b8c7291e315151b5fba38ee298e9ad665b36eac7453b7afb2c08213169e6a9aac0cf5c293637e844ba814d51debc9f2a31672eea86ae89b26603c9126be6bd76110bf3f6049225b6cc96aa89f39603c9524be6d657cb4c6b54cb8e1ad9512bffb05c31b3f2adef989956eb4b665ab6f52d33230bd7ccacfc7fe97b6616b1d664ab8741b632e1896c62862da9376c42a9f5d549e75a700ee816456e84c877c2918f89221f17657f4214f9a428f22951e4d3a2c86784cc8b8bb45118fb98b0a4420c8f6d10965508fb8430f64961ec53c2d8a785b1cf88cbb6c18fe6c3306c529e930ad539994c5d3de62c3a17fc27c52fc033d757230f8acff138e78ae2cc57df7116d98fe841f1c5eabeea3167c67b4cdc0d2c3a4beee7457887739a069209df8c4dce22678eb316c716678833c259e0e41308e8d563ce42f530bce33ce3cc29cec5ea6420080f5d0682879ca5ea7810fc3afdfcfbe540d4df2fd3c6ab1e71a6153f36a95c5f3d563deccc502ee84f7582fd1c6291d7e187e1a7b8179d9964923ec50a380123e0036ccadf2f334c323c6b527fdc618cf39173ad3afeff4c39975175c259629e2e5a9dca389f39d3ceacb3f4f7d9169982472fcefbce7c624ac1339d3e0ad6f7f75967baba1f5ead9f473042c1694902065ae19aad4e3a979de9ea611ad1025f5b5f0a9e71a6ab479c8bce7cbc82016f2a1f166a1830f00fc100bdc8385f74e6abc784da048545b4cafefe8933fff74f9c69e9014d1c50de43e55694f444460690f5514077901ec188937bfcc25ca35d507ae2224e2e870b70557aa8c293c56ddc7cde01b3e4cc287bc2faefb3a38cf5513a6db281223bbc7848ce2e18fff7fabcc2ad9eb69d55f01e72cf1f80f3dbf15e1c44dcc37308deaead8f0be25f51f41aae35a278fb5ade60add1c4bfa218688f651f2a48aa64859b0aeb3ba824334ac570d19e42c22d05dc724b21b0e900676c1bd016f8bb096976b1d842a1ef7075ad3e16b51b8d8e7afa571f0e07fba5de971ee05df1eeb6a8feb935cdff61d0fcadbc54ffcb4b6d19e74f36e6271af35f34e62f34e6f737e64f2a109e8784bf40ec9f1bf3338df9138df98f1a578e2a903007612fc79571883d03519f37e64f2890eb4b88fa4b10f5c9c6fcc5c6fc0740e044109cf130d1987f27087e16c00f35e6bf6ee28f31f47910c37140fa551090f170ba317f18f04c04c13f72919cf27224b4779c3f996eccef4f5346d28df93fa77995f048a88b7463fe731aff67179296db8d9c7023cf06f140d27137e6cf6ecc4710b35a2f578cef7350d20fa12e8ed38a80e63cec56c487b40920ea1c441d825ab9d098ff8255e57c63fe23af52bf0690b38df98f1bf3ef37e6e714a8e779de90140bad88b32c7fe3cad1c4168af782cb653147a7cc32313b9195370841993c3670c6228689b2dc0d648648d569c63e6db8c3f4cf39d6969c1ffa7b9a35fcbd7f5368f90eb7daaf7643359f628352ea7e8b55db29d6be549984369e6b5c398ce27125532168a35f390ced72027070e430111c1a853ef215ef4991e4a0e8a19a3b7a827287aa0dda96ec421b2472db9b580ab2eb80edb1a691a8339e21486cddacc0b0247151915c364c68edeaf618f86fae71e5cd500f6969004b07e417744ea0dc1d5a1e92d0ce0794f944e3ca9bb45fb6ca1db299e5abe665b709d842b48c02854d6add0ad9cdd972ebfeca04c540f93bd512633bf761a04c738df989d86d18219f62e3db2b748d86ca9a70bbd52958254eb82bc69cdcf0b62528ecd274a35810cfd4360628efe239429b833179651fb4f421b9956d12e8ac8b9937b4dcc65606d1c331d05ef03eed7930f2e5b6b5f17065979f4f04d5e01bd1b2e4247a447e4d8f7828f488e20eb926515c3f2855269ed788a12b3b48bf417f7bb061ea9e715659575eb235f85b2cebecb54a309a2a9352bf4194d70a964d7f5fd5fb79cc36d5645fc9c4f2e735424907ecb3ca9422a5e7db67c19b95fd147522d7435a2ea72bdb6d8d9814ad457fd432310a769198ca4bf630e927a6f22b1aa58181543fce2ec3db90465103bf3d2ae57598a24a6ea3b55d55b6db4a0f567a54e5255bf9951a93f51e1fd6f4f4746d8b111a4188dbd61927350641929cd630f87086158a13b42a7782439eb2aee51036f0f0ee184bad5fd9056c224dfa363837aba2284d8c4cdbb4353d8b34fe64a4dc668b6628e03c1ed4b508f980b916b0aa5346355cc006c6941311e636da6a99181575bd1f69b9f81315ccb92aaa8358fc1825b8e44126183cead2c55a920eabaf6a520c20024701420f834792f37e7edd8832e82dc6a2c4ac9f977610e9d22b4aecf1f3f6dbc3d117d3bdf556985af6735b588f26bbeb2c24ae70b7b51d8f9cfc54ed9a8a3bd6c49287422c61ddcc7c55b735136d46a9419ccb2bc3f8bbf1134a260f3fc3644029eabdca104d19c0434aaf9ec92b99bc6ee4f2ca4bb6155c1cbd76f6b8f09c87be00135f0733d70b757a908ee864b9396accc7e379b6b4aa65c91f5edbdb911ac003a975d07aebbbd7a12de10c69b3a86648c7864eb4feb175e851942a92de90c5a1009db10c74c3f87fc4a3dbf672ef32d069a4144207657e14a5d0e0cbaf07b57b77eca825c263df9057f70e6c5a0fa6b25fb2bf1b3fd1d6ea265a3babbbbf099d57dd06b1565cdd7c32ef44c3aa95d76dab170ea83af9134c9d483559ff8fb405cb47879f7766b61546a3bb3c043872fdd04b5e7d0297e829d34c096c6b438b0a50a3252eda83cddb470c49a9941c89254392cf2747621009926c363912da4f85487a7a9683c4102329979323a13df217d17530d27f440ddedc43f2b6963548166d463dd8caa7f71675dde808196a6f5807a6da1b82ba8945b4981c2c43105ea7eb93e45877583728f954b048b01dca39fba5c0591ce4797473687de9e31976d33a1ac256312fa82417392d401ce28e0ef882053c0526e3082cc653749087a85a44038a25fc520c3d5a01eda1a76b64b7980eef2c0cd3661f135d7429321adf3cd7b0bd8398ad03e9c681450cba80d31e8dd88a1e8ce1ab7b08880c84c274d50f86410208465069201806c9204c04a48460d44bb6a544382be197849102bebd245680a41ed1dc2a0814dd2db25b54af886ed1bc22058ae21621c4ba80e5e5b29af4e194a23e507ad91ac003ca36dc4b7f06f521fa93cbbf6c15f3f4aba8e7e0b7df7e9d276874624cb881728ff0f3dd9536635f73041273476e1b7e69000fb4b821075db4487a5bedbb6cdf1e732f0e9080d8d7e2569c004dfb36549a340df1864a483e16eda50cdabd2016897651bccca22d14a804108644fb27b2ac793f2b1581449b27b2ac593f2b1d21a2bd1359d69e60d6a8d3b59e98ac653f2b157244fb265ed615ee9becda9596bee4914efda476419a3741d63638dab4c18162ef6d756f42a95dbb52aa96519b6f5909a29f1647c3d52311b8247e238b6ec6228cddb84118fd8438fa31165bb9a6652a91bb64c20476e94998f4a44be2c64cf36db15dbb52b696b123f7c504f18f49e29fe4f137662204c2297ccc84af62195229d89009c1af657041b9f967bb1f5b70daa4bcaa9a58537a70f9c68ca9bc844754036bca4e522ad923cad61b9fd9a6a59bcaf3e562e55a5179bea096945f63f3c64c49d96ae0e28d99423279f3b50c06a2700ef5aa6ab273333c420901154a81a2a7d829ea0407673bf0083614f86b1153557a293f4ae510366e7e864bfd58d9418c9b9f91523f519eb34b18fe006452d16f071e51765826450c6829428a4579ce4ae8e76d0745a0f4629a5dd941f9509eb3d664b71518e2f4dbb9ca350dc93ca1058d6ecad8b831130fea99b3e44891644861397edcb2956b525fbc01bc955354cbbeaffedb4c5d3322b7ef030767954b5a26ea9e8d26f6ab4601574e21136b6ad4019c7f62264c2e710c88f968931e978993f36e6e5a49d2c3325162d6cd497b86f4a84c94d8e3e6c465e9295934a9ece62adf98294a0fc82051dc94d25b059d689018aa9e8decb5b81b9c9264e4ef0a8ab6e258d2b698243d264d980fc59cc7b9ffb2642fb68b9624b7bad72d3548471ba8b442654b739064545c64d4f7ea061a21862e461161023d1a5c29052ca1e82d2af75fb20b1ceebfa6d72336a0f508c780679673ef4356b40ef95d8f503013bafa8156f6bed68fc16ba065ac1d953ee8a3d2ae2eb475af450cafe1e887419099d7ed6216f513849159c4661e612d0b40b8a4db9a45db9a829bc854b50c41db4886403fdff86427ea7ee6a96790aaa1dfe8250c038018b868a63d8a3bf3aa49bb4fc6360ca259c532b2741dece5d58c5db450470997fb09224344436a6950374db5bf48d6214b47389b4d0704e791a254721e29c63b4a565e204306ce15f35496ad9c52b60e1995291b1eea7ab1720d5eea52b1f2a26d66f2167b166c081bca76d5b4f4c1ca9796a9bcaab3a8ff458b3e848d153c0c366484e8516a6079b65d05f414750201bab7b250c45955d95e59d048e5944a715a23aad2533969646c4355fe67beb24001fe45ad9cd18841417a2b272ddb482c425312801ff8a588012960045cc9e4e8deca02c50266689593caffcc2bff02acac52944ec788d2e95229bd52513acd44dfbe2c2e16b1b93b56a816c122316b21f1baafa8ee4671b9c5737ff3bd85ecae5d297d94fec55d6a004e3577f4a0c4f71052802605b31400a62d1d6e0d3c874dd221bb9128bd7c60bab70fccd6d70f4cf4cb16f75f3906b4c56393d6fbae5da9d7967df5a00915f6506d6debad03fd0f791555fed24ad1c99252e52f3170c10b04a84f0c17d46c54a21a32ba21edc6ac5c331029baea0d4d23b624633b751cdd1c34881a631d3880c5eea9070d3d434cf337013a221da7355829195432b07c32a86460d96450c9c07a924125032b27839280897bccda9eb93f650a2a4d667d5320e518d31be64e2dbc334cffa5ccd426d4971a52896662139924636b5933d5c97675c391bb3b9bf342665f4f0b664f799602a194088e12d0dfb52ba5a152e59c6d0548f3886896521359801351e509110c799f6865493770b0bc3c269a27df4415e0445479420443d6a73aa2da61a21011cd916da249c14424597c247f4fa0728919aa5a2202ef69ae5862124d54af101fc95ff6c96123480d1b02e07213316c884a46637707c64ad468cdedf354f7825ede5720e5dd7d1b76a34da82334484410c1886e4fcb7ea3592d1d29aee9a50f5a2f65da5d49aedd9564dadd77736f7e37778cfe7771fabbb9cfbf9b7b5ff9eee2cc7773c7ddf071e5bbb9772070fcbbb98f150a4fd3df878cef7b899fc37f7f52d80fa00c85df763fbe50be9bfb00be3ef96eee53057efef4dddca780e518e066882f2e7e37f7194d03761440f9a7efe64e46012f43c291606c32edf2bf56e1834a30e039017f59114e286e498e05c3277815f95194b3f79bc227a359de11c55ebc42294030a92afdb033ca55f58795cdd51daf3d64ef08b6d730ca6db2cbdfcd1d40df5dbcd8c244ca055ffceee2741c78e8e56f095cc0680ad07ecc87f5dca732cc9137c525706dbc98466b86f647563f732790dbd78ec5a8a27130fe7af30e74de45e9895b1c50896179c79dbbfff4ddc505e9e15b0bb83cc3c5c6edfeef2e465f0ecc7b883e75879d0b0d7885a7731ea4f4784e0f608ae0e8f1707caec3e4febef4b80e9860abcf9bb02c45909583b3d32c9f2b64a77880c587a3e8967f96f224f355822ddb589102d9bdb1e5c35a1bdb729e32525a135c1f12c1753bb6b418e1757d115b9a4c8255350d970da5dff88f2f71d9f88f2f951236fee34bf33fbe54d47e433594122e978795f2b0067f8be5e111e5ff7c317cf3a4a5dc3c396c61ad5f359482f51f5f0e530c8a363ccca2b2c303f4379920f9407808ca73d8c4256c2ab8acd1bfa60a3f0503fe0eb3a812fffd76feed326e65c9e395acdd88b9bcd42eb43fad8792db2be060335bc823e95d7a0faa80e54021994308159065b06962cd12238b083042a8368a2f594c4b6fa232d662e415712a9b574a6a412aa188123dff26dfcebf1d7b7b5e909e674f01fc9f4f24ae4fe00eba4901d4a8d10f1b50d16bf59eb441db452865e0b23e2c36fc864296cbaa21be338fcd5cf41ebf2747a834557661fe27223bd0252b5e7ec05acec6b93509e2de4b1076ee39a9f860e7d66784b2c32694aa1fa99daa1fbcf356ed546d46a94fdc79f7ce5bb599daa9fa7ea57e80c6d5ce2ab5bfd64ed5976a3377dee5b1f5234aedaff537eb47ee1caa1ff43ff703e49db76a0b770ed56669c6d93befd60fd6cede395e3b5d7fb336a3d4fe7ae7607d3210513f583f4c3970d3a7eebc5b9f7483ee7ad7b435ac040695441ef94995cb151ba050778ed7276b17ef1caf1fac9dbe739c223e1c0ccede395e3f1288b87d10caea47d4979a206adfdc395c3f403fbcb815f2e7d73c670cd80116802c900232ade5a3d5a009cb4302716885bb3d9b508a0a25eb7b7ad66fdb161561dce4fa91fa9bf5fdf5377bd643ff3a523f587ff3f6b96debeb93770ed36f81f093346beda85c7ee24245ed285a1e2af102d56c2c523f72e7ddda4cfdcdfa01549fbcf3eeed83778e8fd266b9bd74e7786d66f4f641da0d6b67eb6fd60fa2dae93b876a337408f1f87032cd0fdc1d1cad4fde397efbe043f7c47e346ff855794165a4d0e868ab6c7e7d25819654692a9caf5d0ff24b5a8832da5c7868b3953da7dfcac866596ffec777dce5bf6a0a0f0c94d06646f1e760adfb28cff50b41772ba167d1931be25dea8a7a4acc1bfa14e5332d50067a510b4cdddd8fc5a39275b156783726c2db12cdd32d4a2aeb93cb7e359677d9e5d969c56995b5d3770edf9ea21329aacdd64ed5fe7ae778ed6c0b1d9301dd399e2007d711fba0ccfb6953d727eb6fba3657f1f903aa68edec9d83f5832ea72d14d23e5826f6d7a66815d7f72525b74c6555a2abb24b2a81261668aa0c26d04b9b39a122c341dad074942110d126eb87a99816d560998a160753da84524c5a43f50394a73b8704402586480e91f7d1f81519556f5d7e6410d90037b08047f55cce8930b527c005480351759773204c2d07a8835811557a3975961aee077ea8b5a74f4f3c19e562cbe87a3ad7d597e8c849e6a7e381dda849786d063d8a52be2c28b808c2d00dcb29fd2e391dbff24494e2afebc45df691cc9d830619644deab78ae485268e9da5a60d3258c419d2d1553bda95eb44a9ce94cc72785037adbd5cb05f29914ea0513b2a25320c736213b2ae2ef4e2afba76a2a71edff0f4faee679e79fcff8e1fb97b7cfaeedbe77f3830f9c37b47bf5ff8f2eedb9fdffdcbb51fae1dfbdbe5efaf9fbc3b31c5e2fe76f9ee875fddfdf4b31fde3b7af7c34bfff8f0e2ff7bf2f47f7eb97077f6f8ff1d7febfbf9775eee7d0d3dfde486ee4dddcf3cfdf47f9e7bf3eef1c3918da15599246e424fb5da1232add5ef08d9b9e75a6c07ad1d27ddfbcd20df3ab4681bb8082f2c75d2612cb4fa34d166786b29fc7261740e804b6f4cbda245746336405d83bc0ed8b85d9d97e1979bd1c6203c7a76337a9c4674f8189ea5f1a3a3019c34d786751ece6ed712cfecdb18b4c10b95362866fc4eb5f23b58e9e5e6b0cb308235539b50b3a9600a5c7f2e5427993f4325149c0f05e1ae4030a23a190b2eb4688dd23fe05c70e69dabcebcb348e90783f3a120a31f88a0f463c085b6ad11faceacb3447907ea81c07c200094fd6075520a28b46d4d8127d5c5ea51c5b9e82c563fe03fce850838d8a6a69c6bd50faa13d563d583348b1ff820141064076bd35475bcfa81b3a054c79d256781560a7c4086c0ecd7f4f25b8194d914508aeac47cf8b4683a41f3481e67f314288f683e39d1607b45da258e60dca3bc60849b428fba934dc05eb6133d1a7db7f10df1e07577fe9ec326f90d5fa64b9d7c444606aa77e81b1daa9a5e52359807a03f2c3a73cec5ea07ced5ea31c5b90e6e3679046d59c5b9401bb7bacf59624dcd5cee8e53183aa20e3973d57dce051aa538d7bf1b3f513d56dd079e3a0f568f29ccb79eb354dde74c4b762281259cc9d8a688a57796c9121db5712cbd1360a93a19c7528e68aa80a10f9a195aa0233bc8d0029fe8781dcd87187266297813531f04eb693ec8547848850715db6bb20c9b48bb37ef037dc126dfcd5f38edee444fad4b67742d83ad8e58c80d9da87b9da083ba8cfc5374af31968130a670b7d5745ba31d1c6d461d5d1dbb76f5f539ef39179c2faa93bb77eddabd0e6da10a77d7bab4454cabc3edfa5be4bd093509ee1d1d5dbb76f56de9d8b2c9b9c64635ed53d50f47e988af4ed04ee15c0717d51faedb82b6ecdab53b11c9708f6926da3cea04d28357536e05ecee2ba5b3b8dcb16eb7642de7f75a5ed26dc37c814752193fd4161cbb2f19c588ff749a7296e83c0502551aae0f76ac63f24c37cc8e33fe139629d8e9f84574ce0fbd446917a4c76d05899d4ef36cc56a1c969e89ea07d543ce229da7ae56dfa1c38d4ecf8a33c307db6596b64087231d5c7402da07bed42fb0c02100bcc05138f3b4a96196827816e0e374ae3ac182979c2518da6e1eda499c25f02b7e1116f5ea787512d6dc6371d38969612d8b8bba460245e1eb362bccbc732558149ee6168605bde2f0a05b2017111489a7b985e2697eb178845b303f6fb0687ec1205d3229c92d9d580979d978b9bcd278e5f04ac079f7b856dcf99b73e9f1e7f1d5dad849b060c6593051b1924eee8b0a10ac4e54c795ea214af13af3aa9fd099fb8af13c3c4f1ca1ea783a819d52753cddb9dcb78e0279e2f796634c9684535faacf39593dcaa6042602a3c828f4b69a65183ea49d9275ce686e6fdb5896fbbdea2190000479fd2d6b59e62fdccd64215d9637661e4781dd3b98be61f110822177976c8364570b121f8b4b7c222ef1494922f2971b59257c1a5c93fd0a496770b108c56a7ec32544b83b8eab8d71898fb78565daf59232dd74a4fac6bd3370732e3bd3f12e6360d6bf569d149ab7c10ab000b2ef512adba238351cecdec4bb0c0223b864808921f311854d64229708551605146ba1bd5c223460201754b8852674895031d7fea07c0bcde9c448c43da7ab0bf5a4d1f3e94dc8caeb2641d6b08eb041d0906a58362e16cbc8d66c936451bf6d218c6c9318a8a4e6f2161ac69a852c1da9a5c122a1521db2f2a4040f52e555b32b4fa8e2d96faa167ba4cad44b0419049b7a40cc6f369b0069fb50f5835110091669d71a65f2d42808017c4e5db117d0ae7fed10a05bf7dfbb9844cff2de5307a0f16eecddf227701c1fef48d4afbf04a89e8ae789c9b3cb3e450ed670fbbcd03b5746e9b0be5f675b42ef0fad8fbdc4675bed3ca972aec8cfc29671b046ebf2be1c75fdd85f52b30b6b27350ffaa466081beedec066d4e7375aaaf64dfd60fd706de64e68514dd5276a33a268b067bd1d3af54f71cbd6a3e1c37a0afbd7a6ecb56fea4d26032c6a3f182334c19eba3d559b0ddb27a46844fd40ed746da619f64ced6cfd7024016c6305f053b5591ecd62dddd215a4d7cbb375449a700fba966ec4b778e36471da81fbc3dd55413b5d3b5a9db4bcdc53e50bb529ba1980509772642917726ea13b5b3772602dc063687a4ef33dbb2f799d98774d721921cd80da03f31eabf2499e9f44d893fadcb44b5a389af13358b6eb5b9dae9dab9d1dac5daa9fa8166016d19efa331048107d21ea43f7656a818e945c0b984df64ef99d53eaf7d836aa7eb87ebfb622de400f8f699fafe96c0e1a7cde2a0830f9cdd9eaa4dd72ed2e18a600ebd104b27f4e4999fd533898bc9dae6879d6ba76b576a5331fa6d7d5fed74d4200bb4dbdb07eb076b53a8367be7e8ed33f583b70f4b6f72c941e0ca56ed144d46741aad5f91deea1227e703086e4fdd5ea230e18914052f787920ef096f787144b52991059c5b1841624fa818b553510ebc0b5fe2e47290fa6ced94c8060ef9567c112338afe57e4216523fcab7d35cf177ed21e18742fcb547a472d288ecb27bf598b3e85c70a6abe34a75bf33e75c80cd81ab8a738dc655f729ceb4731d4e9a589c734571e6abef388bece7aa02a74cb3d5493873e18746fbaac79c99eab802161f5e60d159723f61abd099a68164f7e1199b9c45ce1c672d8e2dce106784b3c0c927b804ef4c390bd5c3b05932e34c2bcefbd5c960f0a433170c9e7296aae3c188cf285fc1880faa939459c539edc625bd35cf38e11c70ca9c22a7c3b173dc094fa0a69c05c00918011f60035c80e9277f4b3e00d8c92492d53bd970fe589da443c25944d50967c999aeeea3d20dea732e3ad3326ff52ce7393ae69c6967d6996e91252cbaf17df6f9240483a29cf331ecc34d27cde70972ce17d57d944b67d115e496c3423b053bda899d7967113d622267be7ac899a72465529ef34767be3a8e9c455e6e9a69c9b92a369c6333e4feea6475bc3a418b2415fae28040a6736618dd8bce34b0bb1065d113fee280f201646e454b0540194036c811349b54001427f704112c391141d513004589e560e62bcebc73552afef1e4fb2d36b5dc356c8fd834b226363d1c6253dc6b41f648ec6341bfc7da90ebcca0c83c816d1d3448113c73bd5cb635faa7a86c1dcad9a6a5f412cdc2fd86f25a017e5ed5cbf4671b29e0fe840f03fd3ee8bf60d08892a134287e8a9c624e20e6fc1e17cc3cd6fab1b2cde61fbd847f3c97d70dfeb90397f9d72b76092bbdf09d5480f93d2e0076c00c58293e8a09102593577e4f39547a09cdafeca07cd0cc6b32ca0a64945fd9395b43a6ce3c6aa1be2c8e154c9e372c9cc3b1a06181a4606b6a3cfaa018f26b92c9e3d6e09ef4f1daae5d292b873dcf60ada9b553e2f83d7e5dd5a8e4a066f26a56ea2aec57aa813428d82326d28bd9e8433b30fa4c5d53cb1124beb3306172c059d8ebeaeb71cec244c9beb3303dce599820d1731656b0e5bec204699eab305dee2a2c9ae4bb0a53633c85a93247613ffa63c591d66f02ad0909f7474818526502c2902a75949faf9cd472a85be11f1bdd8fc7dc8fc7dd8f27dc8f27dd8fa7dc8fa7dd8f67dc8fee0dde9787bb7b6332f961677e43b7b233bf6123fdf318fdf338fdf304fdf324fdf314fdf334fdf38cb233dfbd81fea1395a1048ea673e93fff6ea29a4e5bf5d38672956fedbab67501eabfcab1ff30feb7f4ff32fedc664897f9a9593b60bf8edc217e5a4a2c773af2a3b372a3b1f53763eaeec7c42d9f9a4b2f3a964f2c60a72c6d543f3a998894733f955b80beafad74cfebf77a9ab314f5a9e8ba056476201bf3e2673ead31bf5e8b30ce740993c2079eea58426420f87c8d747fb6cbcb7aa08e032aca35be62ababc0a592d163d0e842c169b012444389ccf599b1e997ca972b184345c46c5ca42a6c53320afe62a7f29a31256638143af445af6b70ba734647d7bf51379aec0bb1fc0ceeb368e85155130bebdfa273985369aed3e62b2d2c49c6b5ac6ff9efef6ea2719a1fc3954f98b8a726ae5f388f8e5c9a02c158964d0d2b7574f5868305f5988c88a9e102a4ccdfbb973eab757ff5d2a860a53b37e6e8d7602a92c2a4cedf173b3e5532a938a93cb01ea37262363c3134d2151dcba2dad19c56e979a8d18654b43c4faeea774de38a4aec9c40f834cfc871d26b1b3ba4c30fec3fa414897fa011dab9caccc54162a27c78ccaa2f2c258e54cbf515918ab9ca4c131709f3996572a13836346e55c116268c22b9585ca4ce5cc98f24a65a1385659542a139585b15c65c1b4c694deca99c131ab72a6d43f56396328953f8d65acca2c0ffc71ac323b5439531aeba7c1b16d953399ca99b1120d25f41e0a2c2b632f54cef4330e95b1cac4a011e60d7e8a34a5b29053c6284bca58e54f194b19abfcb1323bc428b7459cee1da304b39593b41e7a2ab36310a82c8e293b2b0b953363260ffdae72263b466bcdcc8e01a73bc7f29505c31ccb32be5f302ae7784aef58e5a45559305852620fa563ace43d9559fa03d495314a5619db99af2c3012b432123b2b1dab2c409168510015655a79c1188b71599a440c5f8d94f800ccee3adbf78837ec9ded1cabccb20e832a27a5aefd83d0a5caec98615466c786e37234b9c914030637fd2aff3e5639635a7468c6f313dafadb3e5639695aeec69f24473b77fb2ae7c62a33f1f7a22a27c7729559a174553989c6f656ce0ca33193ce363040a3cf837b9b7d63005499198b02955c74a5cab9cacc5865c1aa9c918a5ca5310a5459a0536104539e61a2c5ca538e16222f767bc2577eac324be709a1fc45996193844cfa62534a24778f5f145a562b2f95bf4a94fe8c35968fbe0deee2a82c56ce544e468ae0096195c5310030572a897558f951d31ad5b2a3465674b52489584697cbfe96eef175db1ab42db419758c8d7584fce377a1ee0dfc86fd3aaa195b79e1e3011dfd0118d38a83d908305a360ee6318031b229b69bd5ac8537df1861ecff44854e2eecac499e0f83e459960a9d65a9b8d9fbedc2955b1306fc559ebf356e905be345726b5cf976611e62c7357c6b5c79f9d678ae9f30907eb55f555ebb355eb06f8d676d656beedb852b259dc6e4ec5b139af2da301926cab7578fde1a1fc6b7c60d9aff57e4d644d1be35c1a20701f1ad84566e9c45e0ae087c698c1fc68ccb0a63c4658372e1f3c0e827221e9423b7de1a5701f984b2758096fee55be3267093b3358a6de0dbab6fdf9a3078c158a8ffdbab6f532e2d95f2746bbc1fdf9a2841262bf1b93027dc4c158818f0b7bf994432f1912156b60e00528a09d0316c806a55e7c6f94da512da2ad945ccb34d44417afbe5470923520192c3af46827cedd6b8a6de1a479ada4a7a846e58c4319061a9f1dbab47a1fdc791a5df9ad076ed4ad13eb61bf5891104a5c9ad74fc4a0805054811a12274672999764a939a7a6b225e982c7c7bf5ed01dacd45e2a4ca06c8807d6b02615cc6b726505625227932c5931fc90a05c920a242d4994b290214c50332e230be3551c0962a42920f4344318098488b0bf52f42916d0289e200495137ed5be3a2fc3d81e468de32479ea5b3b9287b390cf14876593224da84ba3cd677ed32e3b7f6a4a5bc9792d37d109cca6b32d34321338de4e53e6d46f2129f36b45f7e3f3f7ef7d3c3caf70b47e167fe4dfaf3c3279fb0c8f72174e01c4b9b64a1af2174e5df21f4f604ffe188e817e04a261475d33c1be99fc7e89fc7e99f27e89f27e99fa7e89fa7e99f67e89fee0df017f2746f94d308ca3e773ffaeceea79fddfdf02b857d7d3f3fee7e2d1cf5e2dee45f3f7cf28997fabe1b77e05c5279e7873f9ea6947ef8e3694a86fe2c1c65a137e90fc50e91ef43a8255e2eec5094141f4506983ef944011c5204f7f8a8948a1a54ca11f97671d37fb872b1e7eea787b7ddfdf02b899cd304b535ff9ffbae944a3f1c8e5c49db2ece40d77a79a6a2cf685784cd6231019b452154fc81a980c5655da5fde1d0d1bb274e8fdefdf0ccf7f34746bf9f3ff2c3db8747bf9f3fc77edea23f774f7cfcfdfc9187ce134cd8f5092b87c0270a2b99d8ab0b8a78766115d0d2834a52d72dac06455c419db6d9534b5717a5489b2e158fb53d6e5c56701bfa5ef871e12dbf4ad72dbc9bacd66d0bef3fabf5d2c25b71b55e5a78f75bf6733abc772ecf294bbc92f7fdd5233f7c796677bc7e77f7a377e440de96fdf7f36feda6f35cbc0277f7a3d3625ca1edffefe78f487025d1d25aeff5defdf0abd1bb9f1e1efde18fa713eef5fe187c64d0b54bfa2290f01923319a4f237d13b5f7e9a21ffe189918d0bd787128b971cd0f070fc895f51fde8c385e0591f287437ff9cf53915bf7de318f200df4ed6ef4c3e183ff78ef33e9b18e3839cff34e1fbbfbe125e9518e3839cbf37e19394bf20e7104693d2cd7f7f3676997901dde8893cb9ce295c8a380de910d4d13b79b58177eb0de447e24071854ff5bd3c41f0e4dfc25e973d723f9f579d98bd76b9a783b35f17f8ccf504aff189fa164e8cfc251167a93fe50ec10f93e84d634f1d62a6e8c161e63a9fc5f4f0317e9610fa90a7eafb5ed7349d025567fefab56bfa66bafe9da817c6bbaf68a75ed7f8ccfdc475d5b64efe42adb3169dbc4a96805ea76723cf1fab69cdbdf25a7f18ff188ef63e46bdc89d0b45de53e706a052af795a595abdcef7e14ab724793032af709f9fb2be2e455a9dc3f8cbf15a7728b9397af72cb95c897d6de3a7e4894c89dc3314aa435bca644ae2991debf3525724d895c5322d794c848af58532263d1fcf894c81616b95c8b6c618deba9912d8c6eb91ed9eace96ab48aed0b6764d9314635ad324d734c91fb126b973b84993a46bd776d5b49ec3993c419b91afa075295ebc27f69a16ce149e2b126c3481fa0961d86da448ac66bc819430f48bc41281be48ac30dc4bd814c1bd84cd305caf185f2fc507f5d0f5f39fefd2d0cfd17306c116311166f950066a8329c2c8d29169e9064105525e3f848b3641835835cc34cd0ad9ff7f83863a842dc202195d332dc3a6aa274fc5062ea17fdb6a18b8fc06ea239a65a8c4dc0da7cf4d382931200ec8bb7669de1cda4b19ebe079f914c91ccb58186d46e0565251684851d066a49161bf5dbd6c30d601d4544768b35078f8fec52e0d9c037775a1add92c2a112baf67819d3d40794f7a97061fe94143b774aaaba733bc23f88dff8b08505f2acb1a7ab70bc81a3e0a99ce416bb92d2e00c843b3bb4d2d00307d0cbd806197c6b62ed2de0607ab47be8bc25b7f0731f6ea46c94418827d7b7a7189fc0b6d94ff450c7dcfee8ebc650d6eeaea2299125eaf6a163134d863c1c5b46ee458f4c62737763d95ded0f5df4c92594f175868d41162e8eb0069462f0d624335750df5136b98100d3cfb011454739658c428a91a4842569e94c1eb1fedba435414b102bdcdb4b0a566d87789d039fcb5bd48e169aa9621e8f1f486f406de1bb14572ba5146dbb1960bf5c79fbfc1c8433f645fb4f701a3acff0541752b4f0c00655f920c6ca631d1bff5eb7a9160ed0df41b1eb3c7326cb28797ce2d78b88c9d4c86dbb317174db28763247fc0a5c122f18a4f3b3d1f999bd1bfa1144e6d42ddccc3354f04fe226990aea4c9eb1d2c7727c7b28ee5ecea429b7f09cf16488029d6102c7019064ee15427a5da022780bd0688e9f7ba56685fc5af76a257f1ab42b4c14982bcde0115ebb2cba609f709176831aa3eb11a1a1d450c1a36f6d8d7cf7ec613ffc9055be7ce0c9191445ef797907e6c921789b513e79a265c3fc19b9a55f335b7f902906eac3f33a33d2ce6bf597a2fb8f7d8830c6252b1c6207b8941b40c31d3507eca0136cb5a86d14ff5f1feb195c6b9fe60bde749696d3501466072446b02799168c4c0966e4460070dfd0fe526e81d346e772abcc8e449a660d201b0072a7b0f524d942962d354f7aa248b305d7ff6b8e8f7f0eeb9ac71bf21ddbde2714fb95bc6200e94017b927ea201aca455df49af12375402705db83fd3251e27c10110c801fcf1114095cb7f727b184ff1d40cd70f3fc5070b24c84fdc3acc3609d2f70aba221ed2d5ac8954d3a4f3d8b06ae5615edbc376b1f7207d9075178e4bd5502fde8b0d153d8386f36a268fdc4af6f6dbf7ea06ec816711a6928289b096e5a331205280d801f39c055dce1f60bc5cbf080c7900d9ecf5f8d1513786f76f3fc21b3e7e94dbafa513805fd9de7a8ab6118bf6ffbd06a17dcb50717f91a03d6c037e0fda6be825f4aa9e25e981c0d0a5c02f02041564d829408e87c3e7113cd6fb4abb33c9e6cd7c3ef5d3c4cbbf4fcbe7f9b726c942edf7db6ad15aaf6a5cfc11ce33b42e775089036df6a60d5f04f1e62ec069e974c6d28b4304fa4696d0b5522d922c3275dbc840cf72bb6e13899dbca3a1cd3ec5b4dbfbc2d38aae0d115ab83d14700f7800b64c97428656b64450e5f3815b8a378012f47a6f3cc1fa0ef89ba706e671c99f1968019b690647a6a5f7422a9cb9048625d0fca7cd48b38b456f485a46d95731ddf119a815e6be1b3071f5f50d94c1b0874087fc1b722c8cdea3289592e77c233082522969f7774be4af82bd44a847b9d1de0a08e3bb572f35037af11e24e8025175c78d0e2c966e87a35d4c3709ea57ad12360b26746c36cbfb3268a0b33df75acf8eadbf795ed9b1f5373b5fdeba5d7961fbd617d166d4cd1970937ffbea6bbfd9f6fc6f9edfe6026c0c75c2adc81c24191517d511924543c430699bd38993ce4f2f9bcfbf6ee3e2364206f7003f7c828359d3b407698dd2784035880d4bc54594256430c4727c2fe6da1560863eccbe64122d076f966ae333b10d9337dcba857ceef7de22ce9969d44b48a8ccacbc25aa3e668985d5a299960cbe8c6d5a7a491de1fc8486a09b14a90f011e42c9be201ac9be8ae18bdc266d24268c8711b2e9f40dae10ef3430955d2c03d3b62559b4076a6a0fac517ba0ee5c81c55ca626e02e76ad3481b09c6be32234a1d901f9b9c0dbe9364767a03a3bfd2ae964c509a8cfaab983f7b7cd5e53fe4c3828bcbd176c18db8996b3f26833633e5d84a007a05b790f00d8e2007c3b86ce7a3e8e7fda1c80ffd9cfd03f75f82c31699ca7fdd2279c4076d96a9a7689a04c395354334dda162e7a32045407c9ba5a33d5c15985b2d991b2ea82fcec670118a61a34b3e161e3e5f63982aad6b2e40f68335adfdde94fca20cf6f0e3f1767fe7fecbd0b7fdbb8b138fa5528ddbd325953b2ec741f11c3fa248ebd9b6e5e4d9c4db792fe5e908024c614a992941dafa5ef7e7f98c193a46c67777b4e4fff37ed5ac47b000c068399c1809f8e43c76dce874d853ce718e41c8aec8e1c659d20c61a212e65afcc639c91267047755c8ce18b79c6d76d96677d847d5570aeae4a70ad703e2e658ebbbf8fa94f8c099203032793a2f8098f5ed8c218b24f4d9179b590390014914389eff834687c36e4e3bc7a41a9283064027374d5c7c64270653bbe82c9c75951cb478c12ae125dcbc8ac4597d5f5895aecb588b5c86dd6e88a84981f32d58c19dd323359da8038cfaa245b6baddab681497a29f07f51c1c8a50dc1c181f38ec5eba24cae587a23874f9221b75c97315b5509e75b411897a68206a6c932a94a6fa03bc211b5067647ede112ab24d132463faf162ff880b52a8d3b727387eacdccbd5e539cef6aecc2558781cd4613bdd6096ba59338615e8b02462e70c6b2c16a5d2e5c05d55dbaebad5dd58e39b267498bafb55eb0e39ab5eeeab10dc86feebeaec684fea1f8b55594454b3e4d8a5a4f32e89118636ce90ea98bdafa6cf1cb8bf269315f2f614f6fca608cd48620e66572c9da85313ca5ce633ef4a084dc803c2a617d771c9440fe2059086824bfce4c8aab2a5e90f2cd75f616536e38cdd42d0dec44d5ca33093072c26df08aa66e5e94a7d97ac90a38b9da95b765b95fc49326979cd0908c334d620efe374977dae0f6a1aa874a7b14ea29833bd7736e25c2abca0367eb7a77cb83744de343df39f29d47d39d422164efcc45515b080f81c6396e2c2eadd8b6644cea2905bd74647aaf57435a3cbf0a51ed1e0f30b6a7097ca70dd1dacb703ad12ee930baae094591e77595188f32d466ebe88c8fa19d49451bc4a05dd223daffc596ee9cea4373dde0d492efc868ce078bef419653767eb36246fa3d30e050d440788536aca1054fc3c4b5068f88e5e088f135a1c1a83a30fc4cb3ca57eb941faef3e532cffefade619f2b96c199f8177ba20c2831e1d41255bd5200e8d0c0b4d6357af325c4eed97a36032589dde83120c840a4d6d9e903a3ea06e147f1e5222f9916869664c99c8cff21a53860ff92e694948b5fa486518394817dc18b5281263e8ec5c7202977c27507f5254e84c5bf4c7ff6e87f448e8ea03e588a8ee3e1f23390f83cba877e1a253e2459f51d3012f5524d22aae6a436499b8da618bba81066ad495b4959471dbe7cf375e9fcf21a842cbfa0cc9b64958122af9efefde2fdd3b3d38b17afcf4fbf3f7de784cee3e1f0dbc3c78f8fbefef3b77f1e3e7e7cd8e02b28aeca755626f38c5127c92a3697fa4ba3ee82bd28f99038a173f07fdce3d170333eec3f9e4e26f44fde57070fc1b32b92264276dfe77b3e1e8aee115bdd8f4435d9d3186509617d2cd09c60bd5ab1c289f2754641b223a1d2a0fc06ac34aab8472e9394702890bb546a1e864165c129a7da042017b0bea91497c80f94073bc7cd291f39963045ecba9d4e2a2528b891b9d854e8ece1c099be8d30ad133a7be5cd32ca5320f572fef16527a122b2cf5c425bfa17a77fc84b60e8ff750e7933431df344f6fb0ec5090c539d7fe7fb0a8515d9cac0eb64b55df3840f1929da0a40bccac9f7ad0f5592d632ca68b5af4bed8cb3602947a5b6cd8317aa41abaaeff5d4f72031f27cb926d450857d11ed7ef43b6c1f7e0fed36e07d3001d7e35323c9775371a3d8f83efeb7314dd6cc1d6b1472eb899e336a20e62e226fe51048add583f5c3a58c374ea24a606a65c4d8bab1562bf9556477e03c1533ca912acfca84b282d98479e624d55e09b565796528b0419ebd404d3c542244b7bf8087903d380dc91d640e46639ce92199239417703a07aba921cac65356963287918a9bdca04edd7ef96fb3f2f91d98aec6f1c1680e880107a2f6535bcb314f16a0790c67984194d39b41bc48525ab0eca1a5f74814df698c6366be186479be7a888d812ed37200942635b883f57a0ab95d13a1e050d869982bdcb165a846cd15f6304b9addcba65c27151c9a380b8697de104b93eac65436f94e326003e797300c7ff9dd1ccd1721dcac0d46217d6805f41e06e53d5470022578adbba73034ada2ead623774c54bd05dbd870b7a67449aa78c14a292340cda150a90b058e1c0aa8e98f9b32a9cbbf6437d228557a3a9292083e87735635cc02cb22fea939dbd095fa6c6b15a56933c0f73d3e228a0437e64c8c4b63e22ed98dafdab72750cbdcd1c44fca719399e34adbc19ac9418b2e4d89a2450a961c5fb29b292087eabb66125d1567e936c0d68e8f6a9249bb3f01199ebcc044b11d9f76f45e13819894d55b52df3b2f64b4da63abfc4756e71321ae462740a94d4ae6249c8e73da0bc6ae80a2178339ab7e81037ebeae4cd5bdba7260e89277239c542e8bb938b78cadffb966c54d8bb67e23d174c57bcbcbc0c79d88aa90ef4f36d609b31c8ae036504e185529e34fde90c094150eb51c5e97874d53d2bab653bf39a30e39bc88ad12169a443106e6de21348ba9ad5654f6af0225611e0114541deeef4fbd6950b76571b136556d18aa7a8f6595b66ca51d25c5e898fb50cba945441a3c5e13ff20ce103ef2f93dcf5bb0d94c32305ad9481979656c7dfb236555aa6da5ca1d825389161f8223046e30cfeeb3986adfe2928cd3b1aadd8c4218864edb709dd3dbd21194cfc05961a362e22d473b8deaba030d0c56f829ed814d42c8c9a0989e1dc690fa68beb564db1ccd6a351e3b6388993a236b065d3911b2899df8246145846adcbf17aa23c44ab93bbaa2b8ef4cba1717ac44d1e8a4eb4b6143ba6623c1edc14518294e96742a74488a36821c832f6260e64f1624c93879e5e719609858eda6cbba4ad2f260776e8175f7d479e484ce05dc24c857efb0f2e708977b4729ac5a4df18e0af2e893a1cec8a34f6046127d1ae861c2e5ee8c9c5be5e51322b681b3b59a2069ea0ad4e034de856ea5609da1f424d2fa05c544a4ca0b3ea7885c3cafe73b1797b0f287017e3d813a30b0bf6fd84ac8f2e30bdc63752318231112e03160e448c1c7a974556516b847adf092626e437a24403dd2b01e09608f44d000d7810a00b0a326ac4753cd426853105614398851d702f7ec7e0f6679714ae285e1974225d6ec0cb0a6badda45ec1a636ddb416517a6c55f180ac56e98dabc83e0e8cd6ebf3d644a9b6e6649794dada56e237eea0417e7322e5e634f4ef5c3172e17aae39e182a834b5e4f835de13a5f6a6411b69e17d5b1579ccca72c0b2abc1eb37cf4f2f4e5fff8497cc57454ed74250815d6eb4635086f8537950301257fda41ce8a28365920d3ea1a5a67947f9c1555176c5d27c259cbdec891eb7f546923863a1a3659541fe5e26d9e509fa3905d2666b5260c180ae8a965a694fca3299679c87d578599162cec05f8a5a6989133a878193802194bdd80227819583366778a431574c320d743d824fc66cbc109fa5bafdc0a04da18a457c5e03dfd11c045230eca2420805ce16fea7cce479bec0d9ea4110226a25ab7e0f9262c08b49570ec3a46b681031c720a9d0ee5f644509f3a4eb1c1b83679368513e8f3e71b0463bf309527e3f409cd81b3706208fc88ea9703811f0aa11758e4d704736587a60002f4d74850873db8388bb7638c8601458c9d56c56cb23fb1c8672af2deb5df5af4cea6002f52e5f57ac789e2f1bf0f70b48ead37cb9f7dfbfcd5e202ff5118f556f95cd0b6f04b0b9946b0731d5099ddb6d60aebc0440908b859718008fff66e6269ef397d0197ada780e6daa1eb4a20080c4330b8b45954cf1f8016bb7b992ecfe816cff84a42950733701cd1e5fa9271a4d25f01d95ecc88f7c666584a5bd28f26b101ef0993ee59b8a3be99e908c73f060b44750a380ca04bd403c58fb3678abbc2c9328654623c874bb254b673ed4a7c0e3513604efa48e4482512d92d2599032dbab9c88b1cc49b2a44a489a948c3a7d7e6c6685eb5939c09e830af0c46042377a3dd457e5330ce38247849974e1ba4e23d5e8ad738c092387c3dd9898245bb022a94ab75c47277cb87c840ebe659745033a01e8479dead49205a3b063a2def3cc7c972e580902b0e5baac1c96808d40c4f0fc9b17d6d5323eb393aeb3ef34e08141933d30289adac190af700d102d807511dfb9352f5b8d60d9c151420f10532639231416f9ce75817239f1eeb576c5a6e238d279b8f2cc0116f0950c2dcc38086f66ce717bfc8e49d2b00d2e2ea02770035c6711b38e27f557390525dbe9150365b7211ab5925c76850ed12c2d2bc60e96ac22fc34bfd9381841d2ca0ac755915a11e52299f12cda60093d0fd8dcc82e2e456f891727f97295671a348dc25621df317206b5238395d3b58cb52f2ab65cf9ce053a88bb28c435729e5ca76298c5aa4b73bbf71f971ac78f071f948c93c7ae4392c1f78bb9e35d7142c7850ee207a752e15dd44f0c821a48d813c47941c7face98679c729e2326950bc707cf1383287f070b92d1949da4497c69cda889677a161649f915dfc70142280f21cb0186d406c92c58402989acbc79265b36b38a58c3cd9f303e17550cac6cb6297a6b16d19bb6d317c89e5b2a7a58c90e2e23c147bc2d2088b7320e0e54ef562a5e64945560e9685d5579069bc450944cf08e4391cc179513f34a4a59a6b38322e852981fedbd969815d8775545cd921ca110404a464aaf99d6f93fba030110bd572981e384596820a21bd9c118d9ca59e58d4c8ba4ac7230aab0728a680b5bf40919da6b98ce8b32121eb7ca6d8bf976b755b21498da378a4c1a9e5e7ca45b7caded5ecd064df3cc03b845c10c7eb06019b5a92fc6d409e6228149e2bf8129ecb890ebb775f68c31c61524228c2c17691e13613f2032c918331768487416089ae9a848e73d649f2b9dcf8af69b0b5be76c212806d6619e26be21a661aa8563ec339ea0441a048d64a1d233e0e461230389abe48ac1cefe9a2c0d186a09669f9a99e3966c58c1fbea266dd40a91169456a6b2963c67d58bf22994d499121163e453247ed709088bface784fe0c79eefec492ce0df30ddfcc39a4f1e21a78d7f8be9e19f55ceffc2a8633110a0f8ce5e6df8a00a33600c0416141fb25b7b53cfc2ff45c1664ea8d632f2a03f146c26196a8e2161882064f33de7d8b905917e46969c6bcc411a80ab5fd70abde22386c76cb9230c4ee47e9467e98d6b1a4ad4d900ab1842758a8a3eb7764c1ec097e1d396433772eaf06b97c0ceb1151a49390aa7619eed5df8d8a9f281ec2df453a105cccdc8b11706ced3c8a92d07d951436c22a3786f661641e6e367d29482cdda280affa7880acf03016b9b125a2f89e09d8e6b62fcb189ff2e1224d53067d821cadef876cd4f9a676a7aa067be92d0b9b75bdf11ebc3da4014da8e9cb15ee7383083faf2d7fd386e9096111cc4a6834f7992b97bce9e37a88a64e97ad660c1421899d55800226930690b1c596a04c381e53282bf6d8cdb486c34261b69ec839ed72a797684e44a0dafb5d7f1a38840f941edb0d0d81395800a065aace99129905253562ec88ab96242f80ede9e8de3eb2029855889fa729902a1fa92229ab03ca8148c8a57af4662677b15fad20fa2eebdb92c627c6f6ebd88db3232c4fe3ac41a3176f4d9c779bf633ca33c4f215795ef8031636f663cce1db7ce34106eff8eee4d1b032d88db9de0485a7767266391df011bcf595bd5f7e6170bfa9e493316f4bd79256dd83d592815b0979d3aec208f706bcd274a5e8c11d51172f8744c6304c466be87cd3675c3a08daa6d86fc988321cfad9dfa0d33eea7a02c91d7b9eb46d946aaf6f101ebf7e97c5eb0396a0e6c439e5af22ed785d23e497a00a14e3e43cb8239baae6214fdef08fb97758ace1f8a759625c268949178e188f506063f719ea64cf8a3aa16c5daf905f51b8cfd32005386382f0a56aef28c26d95cd842e4335d192873d076212565a52ac742705201598980915752a1051ad40f15c92679454976955f328a67ce3c634afa3112e6f9deef36a13d517d6eb14192f61c7a60c430a820f8df01809dfc4adc3b6a71d33196bd0a2f06096559955437681da2ba5be54e5590ac9ce5c51266b26e202281b12c44e4ec138131ccbc6adaee4e8f08eb9d31da553ab7ce1e4d8abd91b397b219f2d239657b23e7f1b7e814d6ce04c20323d7e17008bbf09f9ca9e979ef92dd3cbb917e18b4851e72687fd22c9070f1c371f564418a939c32371ff0ba856deed6b2d1156efeee86191e7cbd0f6404ba0d5a28566f15dab9bf616cea818d0bb37d68dc091ba441df58c505ec3bc218e792c9273d6a544665046b496dbbeab55bf243c3688733e96afdf2a4fb6005b3a6a1b3bcb826057dc7664dede10ea59aa47b932e649c74bdff7e659c06db4579c75926c52bfa22d3059eed8430350c9dab3ca1ce901fe1b670ec61cb9562634df611ce132a4265a96d7590cb8c531979ca57244df3eb3392a611419126cf6e456a67352d59ebe54df061cfe43d68e4b341a049b94ac98d942900bc3a4af7ab91cd2e69362d477b0027c2cd46479845468d5a0ca3cb9d222b714a320f84cadd02366266693b3958b610f2d4a0381885331cee8e3dbec7cecedc02c33c4beb0f80b483298104e51a42a98e7ec6888c9ce65c289c1b3975f433116d6485f0acc0e945d7ef264b30f655f621c04c4cbaff159188a507c53aab92253bc07b63e5012b97072227500f597a87a0e7659e97ec0155de55dc6c4771c7024e14e570cc2af774ae77408e3003da31183500ede52d3d2bdf166c967c16190707cd24a3dcadb32ed9b33cafcaaa202b5172abca9e2fd892bd2df2ab84b2c272102aed4d8571e7ed8b6cb5aebe2ff2f5eae96ac532ba75f07777beb705c38ce26377ce73f6b9da3afcefee3cef084df2ad033fbb73812e2cca3f6f1df965ec633a9b13e2609bc86f68f5f8a9df589dc04ccb5117e44586b544085d584322ffd6322153dac9539bb24e246f8ad4124d6095204011cbd226537b34b9da5314b2b4a8fc5da24c4051d1d3f1a42bbb33e9facea4cbe1c72f052b064939e92ab9a231244d1c73d500397b091ff7fe9c0ffc9ee55c06e7c016fa198a3c2db891c46736e27f04a5b1654dc60154af36d7102c698060aa7a3ddd817d67d2ed83329f27794867146362a30e62bde286cc65e79a3ded13c8b8d7ac412c870754b1c29c2d759ca3f2e0be0a84f01986480decc8d92b5724db537c975db55c38e6bed54cb5f6853ba6d30619f70abf35e7a40b907344ab4f7c75b362238e8d724d774d14c05b2bdb96ae00b168ef0724fd8f74a2000ab6b307baad81cdaeece9144ea88d7c02196c28ed2c72246a0360673266be39e17656b50aea0bc3cea651bd81fe8a495777757496e0ffbefdfd4bf7698ee8e7c229d41fbd953d60c7e207b115a36ac3c3a04a8ef202af39cb2644b89601ae235b59788ccab4c8af807d867408dcbfdb82df1db55d0e44d074f108829e2b555ac7fc317b676dc714238301390c6688f718c3d0c3fa062c3a80010dabb10dc3b31b2cce41a6f6eca17b32188889dd1814791c6c3813b6ef9e8d167c35d4f01866bd7dbda5ca2950dbee5d99612e1576edce6c0cabc2b5ddb9cd713730efbe02726a100f77e71613a707b3b216667d87c03bb3dd3b3567756e469d8e2c1ec8f30c27ae1a392c8b081d8da686e1ae5e98c865f9fa54afa9eaa563e8896daf84b5a6ea317aa275ca0e0bb1f6b1a3c995ba55551ba75a5bca160586db6bb9e351899babc6852cb51701690de06d5be7bf66697e3dc91a171ce4ed80d0d9bbb8402fef17eb2cf9e79a5d24f4e2626f87cb77c3cb9b010c969797035c33b8d93843cfd9770e058fd076d902679ac4d58bb2694d9e9475297dbeba411baba3e1e1d7bef33359e479c77991c5033bbd74d2246659c9285ccd2840a6fb9a5d3bcfde3f775e62127a9906dfc9315cf8ce6e926ceebc7c7172fafafda9334b844cbd62c5b21c18c7b177a74f4fce2fde9f3f3d7f71f25e6a5440f92634754240a0bcf1c63aba3dd6cc6c8b1174b4299750b173260dc0eaf921a548ae187d5f918a9d15f912ac86efce52af65997c4e3233c2907fa8b84af50be7998fd18fafdf7c7c5d1fa3cc061e4d38edcad168ca1c2592a6aca847983994e1a6159754377598cedebcfbf8f4ddf38b77a76775c8f6befa0aa9c59e51090a8b7eebd4d4464a83f1eaf4d59b07b52f7ceafe4100ec9caaf39fdf9e9af0f078336e2cd6e7e04c316a7ca9b78ce6ae82afd832e745cc9edb02e939abde8396a9048fc5a66532381ae6fce7d5e13783c34370071331a06c72ffc0569292b76394af0bff6acd3bceb656f911544ea2fc8a49e34451d4ea966a61aca76d0ae4cea20cf2a22ef239e6ad5b6d516fc78b0999b3cab84182dcb92ad192d85a0cef25ed2c28925b8b3e67655c242bd4a1b696d6397405a6e5bd59cc880f1a2e6dedfb05a65b5b851a8b3c29abd77906f32491042fc8182217bc9566444429892fd3a4342f6bcb1b0f765e7c90bdce151c1c3834cff62a6c1f7490e25eb6e32eaa65ea390a0d4acd72d4ba56b3c71636f68c9ad2b179ed72820d9c69dd04f7cd9b55802382462cbc3cb5131ae781c3daacd81cd986b1906961073af3b00d9977f791f7b0154f0dd045bda0c815a6f2ad451aad786d5789b1c7a2ff08ee8ec190c5f5ddcbd6523bfb665df01ce2054fe884bcdbb9bf9fd4f00599349e699c4c6b88d0b1765864b8e0dd03353d20299401c880de925c1bfa5ecfee8e99d31e9d5ecf1e2eccd9300da426f9d84537eae384ba57cb94cf7a77462cc9a7203f9e91245d175266513042fb7996de186eaecd62358f070d1c0795ae06dab4126f7b0ec7c4f626676ed5bdd35543dbe2430679e755ea4efb556ab090ad3b23863b8b7bde609157eafd0901c322afac53566c3fb43380b0b51ea5cb5ece8a6455098f885b3103e56d12ee47aa29d357d6c4753535ac7bd0effe0f79d57f9913e0b17e418e7f9157fd14a20e8a3cafc0b956962b17398c3a79e6dce4ebc2296fca8a2d07ce9eb36f54fc3665a4c4e7c67e9102aa455e6da5c8acdecaa4fb0b5c8f6484aa975fbdc6430724e6f3e1607ff5d861183c6fc40b36b647653c9cca3b44308a18fd1f393c055be6570c6e466245044744aa45e1ed5a6b8c123ab59e592959b55e011e732a892cff046cd2d01a02317c9157ae18c69a17808303bef629474cd62ca7a58aa4ce1212d36dd47fb0f0d64739adbcbdb1dd21cc3dcb8ba5cc2325b846dcef14fbb61922e281644f2a48f68cd31a6f97478378fdcba5c58912e22686f8f63e1172549ec05316f56c66ec97c89b93f22770fb2b41c1a091fc22bbb2338808230b6e103a0786ff10252c287dfe00356c2245c39648d91eb65631b3181019109d9741ec698b0a178c870c840e0dec760d8cd526f6719e55459ebe8091d699072a5ee70498ebd920b2a94016998fdba5d616d6387b98b92f9aece3e07bcee81e91f72c2f967d5821b2c86fd2453764b552242b3d8bd1115f349b8d531f932f50514b7ceff59cbda4ecc36ceef9069e8b8424d34902bf79ca2a2f13bea4fb6873ba575769db44a1ae68b453f75af2db14c80c3645a976d9ff64d5debfc5eea086fb25effabf403bf84793f645b54ccf72ade7c3e01fa38c7b00e514edfda711c594cffe97114551e43ea238e942c67b145835a2284679a466fbf790c79dd40c507e273583d4bd3b081464f80f2550244d45b27665d4679fab821ca4497440d2f46e6ae6f3ef576c99ef266b8c51b03055344d44d4499f66462dea676d38f5fc48cc1af9d594fedb30de78c1284b93ccba154493924429a3669cd8e3ed28b1bf9b915552a5bc8d36a6fedf929fc7eeab662064da60c3481876da10fe0359fd99c444914386bfccc045dc2847f316f37a28cc874c82804e42393ca6dcac74422a3663bce4cb038d3bc30a96fafd7ebe604fd4be015920f480938b8afc7738b22022e0b79cf5fb4f2f72f27658d7dca4e21326427cdeacc497daa9265d39ac2204d0ed3811a94d5abcda123a7be57552c50bb8275eac9933322625f8e376ed2fdaaff7fe85fc8ae5393a6385495743b9131884a62e0fba6db4b4eb4c245922f9a6ab108ac9db04639d5f64f09d844eb5a9cd829492d1c53566b8ab9611e2994c90c54b340874ff4cb188cdead8fbd29dfc8ed008b7208cde1b841b43bffdd82877039be0193b429dd0c913dfc8e9c851905728d46e53a3aea41c39a4d4ecd39d8c9e31e903b915fa867bdc351b35b0434cdb438c77c4bd5e93b67ec10159acb25e4f2de6bef2c6e6cb1da861e32d499027e054b477b3698519e3ce0a325f8214000d7f13c406857abddeddd88353a33005b773a457080620aae73baedcfb361b3ddbdecefae5b666e3a0ace3d8d943d98033e2d41ebf458392a87a5e0b17bd9381deb373dd2904d0f9a4dcb1260730b3c8155ce3c47773eaffa14cbac977dfcd6bffcb4508ffaa6b320f60bdee6588aced0b723436957fb71b3535bea5c68c48f07fcf251b600ccc3b36f81afbefdbb33564bbb6e5e91fb28dc4f7ee1ebf4914fba51205bd21d864b1f53a864ad82152f88fbfc9f04071e73529b2249b8b541132d24f727db03fc9ff674ff3719eae9799e5bda37893a53723f9f6967900ff57095811084ddb78489f4b011e753085d0bf8bb4154115273380ec7f4ee2fa9bc8a7290145f2c93b248dd9f7e23ced1bf9944d8874792ce6cd3283b3ab3043da161e631f7c15c3b8c888c8d0eb397b6501b63b7bbe04a3d7335bc33eedb4889974b5490c788717cbd435c6599cab361ba723b1c6d9fb456500230af4c409e613bf3c516be42fbf38d70b9639bf8872f8d6db8ac5e0cd7300a75edc7e014a8da26dc26235ead83bef6efd5ddabc87c7cf405a32d0be51a8eb1675b9f5c4bab5676e7deec181c3ca34c9aabe3874f533f6b9eac341e453f9b94f0e0f6f0ea0d9fe82941c91fcb6785296799c908a51291540481e2c8a9fa8db18d65e784727dbbb69769487ad1d71a7a45d49648d5c5faa2dfc4f96c3ffd17700f97889fb9f8d7dc83938705e33f9f0f48c2362b5606aa891d374e81aac71f94c3b94a197568caa722742173ea402d748e0e6080eec1c39a5d9ae334faac53a1ac4f952bc1312c93e34c24959ae5979f0e8ebc75f1bb6c9ffb2a3c4ef3906944b92a66d0781e5bad2e26b08fc4bce08445c0b84167ef3890018a57f8da1c317486b70c8f83ec5e1e943b0d52881a3721b593917fc5e0bb580cbce7f14b1b86b796aa54b430f2557e37b90faddcd13369cbfdc7776e20d7cc9bcc88be628821437cdf530238cf541c6d83d9dde10db0ca4dc466468086d063ba43698ffff427a7e0fc2d44e39459e364e3945e33c847219339f3a831ab99aead2364de979fd60756e9faa0436cb1c1a457ee37ef55b5dd9ec3aad596a56fb6cf62f3896dda9d57cc05e249e38d35b878af843b62b4eedff70b195a9b2ab6d4f0afadf2bb4fa9fda9df47cf07de99a082b3b1eb3f7500d82bd79b56d5c7b2aed5e71f9e05d7ebdc3a70b6ce5457ebda79a92f2592d69120992948426615189c266400bd24582dab804b116d1268d97d41d1204cba9f6dfd69df97f0fc917fe006784a20b597c3ae08b3602f08d094697a799706dba47f3655fc261a5ef12a549276dbb6469e7aa125ee2f4f5f9e9bbd3e73e7ebc78fdbd5daeaf9b44c1f0812e6e019ecce7ac7856e4d7252bdeb1599a5f2b82dc96783749b62d57962c5f5723e7d1101f1e5ee6ebac7a939d66152bcc8ceb4ca67c4e6c57b9ab15234583c4eb8982b763ac20a70c46cc580ece942fc972915fefb5a49f3edf912c5d2f9d11fa1b5cadfc11da8e2f24e03b350d96b40dfd96c33c08699b403da343594ef55dc73644c01cc6ed1cf9f80cd4eb3956d0c8bcf59d31a4ddaf3c30117e973b30a9dba6f434a32f93b262195e373716dca4cd65582e11d1180da908d0c35056a45a973eaabadfb679431480377ce3f359b4772c5d47bb0f0b63a7dae338b8e73b758ff9fa911f23c540670477ea09118e7cd15d6f5484b2fb3623c852dbcb38342d649e50f6bf87cc8b76d47bad0d8bc8873a63bc7b47804b6d7527fd20a91be9b6858bf39d7ee47546ed907c17d51575ef9da479c90c3341083f13cf2c7d29edbac364cd78be8a278ae09730c35f48d40c3b2ed158832755e4ed4ed3657c73aa4d60bae310ad0adcc555eec530f0c662959a0a359d126c537ebccb4ea65c91cc30949974499190fe22a194d3710e15789e902ee426ddc9e4f3f36f27dd8756687462d2158a03551bdaa2287261a0509d2418497bb59c26f6abef7a6d5f2216360afeaf23377f9060f84326f40129a38ad15bab48f0e7a58bac4b06cfa4299612f3ff57c1ca8a14d5c122cf2fcb837aae3fc0e12c4dae788a7eb54596aa27fc7e4102f0644a7e213628a95536489fd22edb082ba51c64c69e66f1222fb4a44345ddc5eb7266d1f409a3f88d114086be6778932f4df2ec9094159541a4cd09acd5bd97677592fe9497be9b98af0d44795b17364a55ab854d611dbfdaeab0e0f45a4dc76bb5b438c95dc011b79191c71bdb871cb3b6ac3ab57dbf69e6bf8be36ee4ae73df863fc17adeba6f4131596d5945926904bf4cf065bcb6ec46b22aa239e1b6121af9be748badd5d4e60d78915fcbed568efd03ac9a2ccf85620094f1b7ec9e30d856d0d78e29ab87899170499946c1f82a13ce469dc8194b459f6f0480ae784297196c33d649ac85b7c3b4b5c154e4296cb250586db1c6541e8b691ae9a7ef7fb3406bd5f4cbb8dae98cd1c4c05a466b7a946554ad40ab9c4ed357df1c5760808c39111d125cab815475232ca5ebefe821530a7fa025c7625ef069b0df739aac8920d0b757cba131c946d0b40416dab77c453f4faee02c469f963ffc997336b58dcfdd5bfc1990d5ca58e7aeac44be0d01e5afe7824823f54e9e0af3bc4cb2cb1d6246e84b3f4db2cb16a7d17a53147dc5ea7e60041edbb9abc605e669a9d4ea65bb2b4668065c31fee94fce7f097f84a6bbb147e2cd1c7cd6401bb20c964936f8542a67f6daeba11b7bce19895994e7973eb83d048f6549553a64364bd28454acd42ff79c2f925238f771e29cc2cb3f2d7e115fbd3897d1ce2c5ff30a339e007558ee1031de29f29cf34b058be1edd17c066f93ca96aa8231e92eb1e67d128e67a17e9e04297c1f5f83e0e7802c34df430fc3509828a14fa75e0f7f39fbe0afc2ec5807e55b27f299b349d71b7d333c1c3ef2ffd99e8f4f154965b66ffca23ddb4c98d0cb8cdffa557b46ece20578201179bff3d73bda2e723e9c85c878f867ff6a6746e01d658d8ffdebf68cd20e555438f43fefe80ef25dfc7c2af31ef9373b7ab42e571c2764c647feafed19976c99cb4c5ffb4fdb33a5e4d71b9e6992f16cdff8cf1e36d3f88a535e046aef3b718977cb6b06e55738e92eaa6a558e0ed064e35339c88bf901cde3f28015455ef429e3a85f80c5e07192898d249c74f7891f878741fca4fea87810efef7bd17e38e9f6e085f029cfcc325ecd87772f141170f58be1f1d40b907c4fbaaf920cccc3c44a07209cff8737b73fe906ce5552269533e9ee47fb932efa175d3067b64e5367c9ca92cc999317e0a187c76779d65fca0a29bb725876951479068f7ff1c25010da28d17921a5b04f90d4e147bed93a952671e560d2dd0a421fde26e52bbe6b303ad27e5d6fb10b9dc3adcfb27faed99a9de545cc3eac28a998994fa5bfc367e4c07d686b86f7e82ccc4edcfaa7e1ed56cfe8994bfcc88fbd5bfdc27148020808bc0e230c166c5686a7f8bd06b08a30de6c9e6fcf8c07979312465ecd136fcb4c2f054ca18289f891779bcc14419a743b0a1f49af6722aa95c0b7ee4e483c74e5846e9c4edcefbef63c0bc4416d30f04178dee749570233e97a3694333df406a0628c6a151bd324eb9e748d0aa072c36ce97b3e0bdfebc642a3613d2d3ffcfe6981570dc21f8c963276ed7c1fbce035c877b5c31f82d47de11b3078c18b4152be5d17ac36939d216c217f0d6fe37551f08d984fc1d6ff31ac7b901c2c4869389ef35f86b797ec66d419fa9c3bed0cfd8b8b92a5f20b36ae5167688dd22bd97fde24f36978bbf5e721dca4ba849f2099b9880291c70912ec8fa8d8ee8461c487a5d7732ff1cbf38d944b76d3ebb9f370d2e58480073d3ff27e1cc4244dddc8675eafd77959eb82cb635d3a66d3301ab3a90723310bebc4ab7fc4c13a0cc370e6e963611807e02d8b273d9969fab908e13d3e77e6f9cb70182c9fcc82e5febeb7182fa7bae6f172ff681a18952db6c9cc25bd1eb1f8363d06b3d04ef1671e763e0c43de01d98f19f403a9cead74a53a5af920c3243e9fb039ccd7a50fe837a2fe457e9db162f4d7814080edd698b1d7b892775588379b79ad11d44af8bc889a8978595dd44f06f8b1ddaacadff0d52789bca41361931c843030b2f1300c57ba0e56c664c57845b879dd4ebae1a43b9a74c3e1a4ebc3170f1c4dba5bb59f7c35e9eebb8028c453efdf1f8cc3d1f460ee9b94419c1fa231996e3d587a6fc383c9e460ff60eeff2d1c4ff5ca7e8798ed33a07a7f13988340d1f06f8355be72bd800ef0d1bb900494a328b2c661145090ec873147094108187cafb32a1c0ac01dba15f380b5e07c621da308001fc5be283f623e941e0dadf97ccfbb452418b0e4880189880060c4b784470511a4c3e15f642f7bbdbf0d56eb72e112cf6cea5c0f098e829cd600f60575c88529a79bcda41be579ca08f22ed423d824f8c20d3b879234846148bc39a75bb0fcd0b2cda5de6d4c4a265e59c8e693ee4884b3f532e2ecde08ca4405239781489228371295681c13b5adb0927f42d92d5fa2734fcc45ec32d81300d8e878d21d4cbafb1f5ce20fbd51e4f987c13c1c0651686718710e6534e9f2be0095182425520be27992805c86c3e0f209919cd3e5febe774b4332be9c0afa14ed7f70a97fe905f3fdf0dca5fe0c06792ba9911c243ea22d9beff10cc675e4cec267bd1e193f9b6e36643ce9fed77f49c670d29dfab31dbce4ec78061b84e7ef48876e907086849778fe6538c98641c7a5211964ec73e57ade80e6190b3c1ad201be12a9fab4bfeff956af148db5080415fc418ce49ef892517874e84fba63f1dc2c6e605328111fcb0ad072195cdede4ebafb6297e3619778f89e384aa2bc7dcedd754731ccb227a9aa33d7c4e727b99f89241c7a723c1c71e4e7c5205917f86092d37b699e60863870c792cec1ce368a06558eaf91ba8fbe31eaff88f5e30a16532057b01ff962f9eeef5b0b95106b5b0e2579f06968d0868084f7571bd4b1faf8ef2ef1991fb79155b2f546a28bbd9ecb37835ecf2521df72e8bedb81b6379ba8d783ed9ca3348c041fd69120df301a8a84bff527ddaf7a073875f0137b9ecf247132c6e9ef9236f9147b8d8c4380e0c4c0496013f11dd50751f8ce8dfc3954137064207cf883f76e84bbc5cf35ae4aef17ff70b15d12fe2cf75d8bc0d9fcefa3a3438d7f441c392212de223387e59f27e58a54f18215a39f7d33e1198f3dc9b359321fddca23a860f3cc7c6f900ff05f94eff3257b07aefa59f134ae926c3e521de16719942e8cd26d20dd829e4846e676495623f318c0f14af58c78ca4b28e2da781a20860013c833cb6eb2ad3fcb8b53122f1e541d9f0aa84357c427e4a39a0fb11db6e021cfd738b239383e40ebb67e9503425ba591df101d88b0dd762c975d8ab67e9ea5762dc9cced70d4afcdf8e19f1f99336ebe05ae79f73335fcd22d4158a8a8b7422212ae75d4bad0eea1c31f54fc7b10b4bcca290b2b1d291025bc09f4ebbaef4f4fde9d9e5fbc787d7efaeef5d397ef2f9ebfb978fde6fce2c3fbd38b37ef2e7e7ef3e1e2e38b972f2f9e9d5e9cbd7877fa3c8c8801b9691613ee9c54be7329deb6be128ebef9d6279e27b027756fb7bee0333d49aefc79886ce86528794ef35871db384eccf1cbbf0c150fec058da305358f16bc42647e39670aa7238b6f170789664ac0b7c705e7e88dc3c9a2f570c2635d365e4c43351ad17831edf51468b3e3d978311df158a4378b3bce2e0b8fb59f5d16deed4c9c59165e20b9103cbb2ce0ec326b39bb1895cdb6771f0f26193f20503820ccc5e180c963c1e5561311941a8bfb9b3559821e835ecf8d427c679684bacd6bff222669bc4e79150b92cd197d9654e528f22fc4a4c2b3d32362878f7844b52818a127c82ffb52bd0c24d23fc9b372bd14a16d40d4c575a3ed2bff42b2dd64ab56ed40160d49bd8f7211bcaac59f1190ff864d3af36a102519451247bc2082a10d89262db59adeb159d8206af66ea48b68dd71d8a460ba9b9f7df17e0b31ca0a1f23b2476f8cf59e925f6feeacf0a97fc1fbcba7006dd546fd43ff429c6e6a302ed932afe144bdba5fe531573ef3a291e61878dec8a8cf30746cad966fd1662648b38bb7226aadb4b8b9dc28fc9c45eb3960a0394d5696d3d98cc577578f599ab5bf58ae382f9f5cb11f40d7d6a0b67635f5ec2297b9ebac4bf692dce4ebea015099199bb0bdda3591b23838a768147bc7e83a66c53d3d11b95407ac0adab05b179cf1f3ab59a02ed2ac1741c9a359e88a15659267e1a42b95515d7c83e041faaa3ecd97ffa93aab030e0ae7308a2cf9b5701e0d8683e1aa608e2bbcd93d5b2729f59c0d876292f1320d2d172161f3157e3fbb4bf755188965bc60748d2a22cd87afff7fd5c76f577d70de95d81cdada3d3afa164c06d51047e278e9539ff9337fee2ffc4bdcd552643b4c4502474071c094e3e13ff282aab8b98d0664b54a6fdcd84fbd2d3c22e22e85243dcfb0f5a5b7053e8892b073e8339420f933082d442821e1adc86f31e2bccc306024e49b9b02fe532bf0507f20ea0f2222204b88afa0360e9b97ad757c92a550bda0ca717e8de2c18012394e8c04569b28ecb107fef0f1779e17ccc866e3f21e0f798f533120a9e8fc52fc660274639a724b0a4005f3bad94cbaebec32cbafb33ebb02ad6d4024977c0e6fb3841971632fb8242ef5232192e72c4a231b871b1ff90809f90d87896045ea3cf2a4db7e029e74bdcdc65d91417b72ed58eedd5bb371846eadda480f6b476c690af24f121efc1f77f0276f3c817f07d303ffeae1baf98284570f52ce973b32d6b5f3d58e7c4df5fc7a47ce56fdfcd5aee61b0afaebdd396b1afacf3b723654f437bb338a0937a13d3cf47fdd35086d4afda7bbc6a1a1d57f764fce8b34292ba5ba3f1afa273b0ad87600cf77e4928600680670ba235794e6f1a5c87674e89f91df6a2ef03d11828b7b24cd9e2149094878467a3d323e236df266b5dfb501448e092e25ad479510f40f412c284e0fdeadfa0c51ad19f144ce9e045118b99c2689d34518f123d48265ca02d08dbcdba1591b9c3323797af775d587be518db7f5efaa41973ab24b79965ae6853da4f6d081f4bb756094f8cbb405db6cc820835f5d5a2a45daca0652fb21941e1519c9d93853b4005526a54e7a2bc809265c19096aa163d25a276939934c7c6a24aa558449cf9a492f61d56cebda00d5a35d6a9ccfba2ae91c4a1ecd656bd7cd2c6f151dc22cbf929144293c0607801ee6c04762e04196dc3e372055eea04648bffee90a16ce9b744793cc4ce1dc2a347f2221046419a0521f524eed14044ea43d27a364e692d05a27c70a1351976394f6b6a6f853e1e75f89964440e7687e4bb4daac227331d48f5063f667fcf9067fbec59fc321fe3e867144dd0d2ae41c1288653692ccc705e507641049fb4c85dfc3d9c29f85e618202b437b3d37e6f114e3bd8086b36086adb063fee1b804986536e018cae743c9f6ff89ea1a0ff573fb6c9026197b0daa43312d71afe762252860a14e74c32b8b319dc331e94ea461284f7141a9f901b9275ef76c1bed873128527094b7d78b849fb60d0931bcf42bb8b49724bcb5ed27880b54e247a2b4858437f6524dce4b3226533f0e7f240378b2ee0d3fd5721ad071fb874f62afc6ac3ffe06a4a93cfd35e1070f90474703780d20aec056baac9741092ce40fa3200ea301708678b147c205a747a552122ebd502c1a8fe9d49f8791bf08296ffa4d83f95a34e07cec2f3c2f7843c68b69380b504d3a1bac16a464f41d9b276555103e44f87a6b32732ff1580787d54befb2cdf2e32d712fc76cca19722f606167885cf56c50d42a3c76df12b7190d057d5ed01b31a1a1eeb03ae4dff914c66bbbb528fe5b6208beffc667ad56f070388472901646c13bfc35c67a1c4f0794adf872cfe28495803baf49389efa6f38e6f87f83bfef88651af6de58ca9d433f86198bf930110fa4dab5918a3d752218c753e8e3cb964c9bcd4b9ede09430a5d8250a34b477eec7901a485348840ab1ef57a1caf01fa7312761ab60182be5f2719cdaff140b2337940f3180e520fcd670b643dff83587b3f89df8fcd93d2dfe5664dc225ff14866e6d166d1f1aa7e3ef86427bc1f7114e8ed9eb9cb200a5da2971230e826b24f9428a1e799e613af333c0f01339fec8ff2f359ca38f241c93e9e8277e8ad5ba4641357e2252e7f813f1a3f023093ef24fec1f748acf6e2434f8c3803c89a40c83ecef7b7f276ec4d1d480e22b62c9ef38f43a9144fad86b6611313a6314b9de2d4c7f1c855f119f026232fe57a3ed2c721583d409c39f08b2379d30fc483c5e83cfbb69aeb07964ac30167926045ec0ab1f825c411a74c8ecdb59929134bdb905087cde301ea2175178f07fc6a3a7fd7f5c90feaf93c97a383c19f6e1f7f937f8f31d06cf307886c1a3b333fef3e85bccfce8dbe7f873c6838767907a341c9ef4f1f739fc60e6a3c3ef20f56488c1b3531e7c341c1ef2e0f36fa1ecd9634c3d7b7e02c1e767183c3b7b3efddf05ee64d21f0cfb8f019a67df42b34301c537d8eca3336cf6cfc3e99fbe3af093e85e33c54f11278297516d2b4d23b1889308e54d971127b7c25e771818299fcc14a0f28b6850b1b27255b473c99706c7a84ff24359feaa26976a4198981cf77afcd01023d7a25a11bc95a02391326fd254461a3895704e9b74470a7691a0cca9380b48ad0ec8b665643c2071cc5655f90ccb94c0a454f9cbfc9a1527a464ae87b23977e87fada5939454a40ff40e6c7ae16e3206153fa786c15c9a597324c2308c76d2ec68b33106cf9aa41dfd12c3274655f2a6226b1408265516e58d63dcd792954ecad7e4b51b0936fa9b7af46673f89768db9ce31353d427a493b5a10d8fb0af8ff0e7cfd03866acaa2289d615b0a6216d892c57246621c394e5baac3e94ea19e6300e9459b17c185c5a1783b250b452922ca9925fd987772fc31910b6535c1bfad69e4349366745be2ed39bf7ac7a9165acf8e1fcd54b791107f4563200ce831845871690ab5caf56052b4b384965d5294d2a12a5eca3f0fe2c937fb8a1c84ca9047cc26550aed2a472275d67d2f506c208c43565b5a77c8d65ec1a867be8770e7d82f6179d436feb05e3f1a48b837eb22045c92ab004c5987e2ca3a67ecd458a088914e59a180dbf556cb53afde71aaef861a8cf30389db6822ab6faf1701a9c8e230975e41f02d4e3c3a905383a8037c60c9aa10599cf55a85cb1348541872058d04dbaedad5b0375044ddaabda6c7d92f1715b57f93b76c58a125b639f2b5664247dc750afa35c54888189d7a5828ccf2a2baed8d374b5205f0092054497a4697e7db64ed3f771c158e690f2268b1d0ed7196f0dbedea6e446de422ed5f530ca66acd0af4a898fb7495cad0bf622131fce2c2f96aff39f84872f079d2938699eaf9c2c7f05cf293b994ecf572c73f801be7c818ec00a4628385b16ca25ea143860d429e37cc57f1859a6ac2c9da462cbf73cee8bb1fad143262bc6a50783bf5ca755b21233211c85c26d8894c5e835f4418d0e6b4b69d28dc98a0f1b62627e9da53979586d7f6e2e4c700c5e4255457e8d1f65f2ab446cbe593da0e26fda2a2ef2ebf7e8db62d205bf060faaeaeb7b86992fdf3c0a0fc693497f3475c7a4ffebd43b986bbe741599b65ee3c3e9a0ca3fac56b2ae2d27ab9cf264557fc1407b4bd2640e2ab77e444a0618450a1225313814776464bf5c24b3ca89c94a168cd364d55f916a815f05c7d3384ff3a29f64152b56790ad4b42dae3f4bd28a15a54813c2781142811127c0345f261931216319b8af8e487c392f40293c4bd2b49faf489c543718004066699ed33e5428be559e3cabfa33b24c52f1cd275c7ff509fdb42e2b1151150cfc4c62e0261519e53d66085ce370ccd39bd5a29f9125139f7991b0acc2fe2ef222f935cf2a92b6245eb1a24a62923a90ab4fe855ffb3f8ce8b649e64fdcf4eb22473660c4dcaaa8a157dbe01439083906473d1e325292e59d16719959fcb447d02363af9152b605ee583bc3aa65a24f16586efe12759d5cf0bca0a6745b2bc64fd436795c35ca2fead74144c30c559e5940bb232412dab7c25e0824f3911655524978c9f47d7f38506c38ed6b09455915fb23e25e5821405b93123f2d9ac64958ce19d88c9ca0c7eca934c869749c53bba4c540103221ebc4e68b570c01d3041ef1bf04d599c23838061dd43305ab0075347e91eacb324ce29eb47094d54a0e0ac0d0f55657fc54775e95cf509dfb1225625b173d55f906cce5bb9ea2794e5f382ac1610bf24d5822d09a2ce15583df41918b9381ca3008f6ef053a19119ba71aef3822a14ba2e12c0a0654e99f3799966e5e8739a6497ce67b1e01fb267688934ca31f3c89f64abc86b6336ec6d16da1a91b85af34d4e848ab8c85319323ee1823d7ee29387e2fbe6613b5b0b94bb6044a66a7470707d7d3db87e04f617878f1f3f3e8016275d4df03f2fd311a75340f1792025d95c058053deb505fc4e78fefeea2587e9bb834cb2e4265c15895e64947d468eb2c8cbf20dccff83f6a3c37bb7fdd3018cc40f059b8952622e7f006525d620a7778171f70fea10402f8b1873cb62449c3591075e3e15c1dfd7912176446da1ff344e83282e3eadcb1723ef984fce48dd08c24b2c9d3064c7fcf4cce08433a2c79dc351c73d52822b0f5493a870190fa7fc90fa4685785a26428790f65a85a0a26130db6cdc2c72e555015031e0f5178af227def6711ab9114f1311f131c7ac657ec59ecab39b1b792332285965c4f8e27e813762f5a3dc311933eb1c370d55dd8f5477398c7019221eb951c8ec93a24feb3180a8fedd30ba4cd4edc7213484e753d6eb7586e2160d284838e03e3db6bbf4fa3d5880c42d5d8d3dcfb3847305b04db69083282187965cd42f71d56f6eedb8f4654811464acf698b2478270c516619998401aeed623e97846490e514c6d0e358026ffe8178a286dfbd9e2b78f228ff8cf7be388e1584263906ad31a88c26a1f96383a31fa9939d1f4b19d79c55c6a278cecab84856555ee0651c79f9578bc2fcc8f385d93a194728bb6f88ee23e89331605a7a1ddb17b5b53c26e6a0ec4e2c59255732e4f467214406a21fd89482802ffedb188c67d6056737479da13f6755f31ebd236cc3aa45527a5bbf64f67d0ed9d760a6b3f9c4db6ebdbb5a66d97ac9b0dd78a003eadac6ed9c09d3f1263c1480a8a51a906c7dce819d1724be4cb2b95901195cc0fc421a2bc249865a4c96b28a397cbab65b033d3f477871d32ab4d9b8f56a00a70cd9fa8d14737688169429cb08b3286047a4656ba8a38d06b2f72e1e86b06701811b1188b56420b0f6587a231c4dbae8a5b73b2278c5cf0b4848954abcc349891b0de4d8b9c4e3dbc2c894a4fd1a09c37f01876843d691b9b75b3e7bb6104a587cfba69c4ac65d9901519bb87f161fc72332b8b82e083fb9815def20c9922a21a9a8786baddca7166c485295a508348a84d28ef3a9d8b454678ed597ce2a1a0ce2b088e4a5151cc363f13b8ac190c58436bcb5c11d515f44e010e0b56074eb35aad32865e867102adc606ae08e2c700cec7c26c62332e649e4edf5607b37651511f032c6709e88e2a21a817a45e48a9638154388b48c37f640e926378650ea1d619be2a4491068a860b3111fbc9cf8c4151aa3ce57258b58b0dc31b3991751cb75b44c2a7d6db960204f44109adbaa22e492a06ca3a6b1a1cc72fc1cc640ecc1dea825ab895293aed7eb994560d0cc1c9e1748fc143320ef95d6310efa6c47859d4e3d973571a7a68aed8e5e6d36f7f7436a99f544778cb1ee8421e5b32ac6ba03436fdcd18296d4dd598937829a897bd8fb3b96384010c49b4d64628c428088af3613d830dac621da5805c29a071186c7404b46093d92771398969a626bac9f9b63ad11bf034c0619c06daae752a9cdf9f62ba9d4ee8421f1100938db6775e5de7119d905ec15d2accabcec7c16d58c860851f744d50182587726f575e0683f249e7975529b1f0a6a41c2ccbd951a0b41d7b79c7c705c0ccff842d04f78127d5d2d322fd26a9342e310c239be7cc5a34bd488df82f6509ab6b07018b027b1d48db3fd7d2f1aa3578978cca6a0fd03a38a7018c4fa227fbcbfefb1b065217c05fc593c95c40ebea5dcb603dcb76bc585ccf359af4765bc9886f732999fb038b9ba15f7e38bc88dbd002fcd0164d80362f600ec19c64c00c189a8770be152d71a608bacb54549dce412dc6c30a790c66f366e14f2184fe5e0b36c565f33898c94132145afdab552758b1be3aeb4e412acbdbf8d39507874ef82d81a18fed71a8f02cde87bdcb1778b9c8b78673eaa3109e66e66f4b3de9f23b4d0b2afd6c76876d2710fff124a546c584d3df2bc200ee3f170ba8dc2782b3602303541321587d176172b81e303b8634dcc8f56a7ed5dbab9fd1857ea0536c67edc5174d6d86863cf6fe3a40c9f389202b5109fd8932dd11d94891af3f6d23eecb1cf95505506b805ec9e7de42c107b0d3cd67b0528545f45e1eda25aa6a3dd82179e3ce9fa4b522d76e7fbeee015a916f0e7d5cb49d72fafe6ad598f86c3e14179359f742d1b87d7e6215b9fae21a33a05df559bb424e050de59a4096be3b47df740985e8122cba84858447346ebee2af8cc1dbf8edcc8bb678c4261ae30cb0b96ccb337da92383abeaf9191f4bef036f2ff16b55c0edc71947ef5fee96ad5ebc1cf807d66f187ac2433f6328f497a262a39d686e4d26aeacefc6ef33c6a985779db11d9bab3ba4336e42d4016f4e1dd8b4e18be8a06e5d59c0faf52e0f34f877864a062c208f8dfdbb751f836da6cda8de7a4ef5b2f781b194527dd27e5d5fc2f70771e56c99b99eb69ff25defea4fbe40073c0e6c49b18cc92a2ac8059088819f0247f0d41d74cc3bbeb4154cbce17724631bb9906620163b1bcd3fb8d226e56d3c9cc8d7bbd1808444a446caff7088c77b29cb2733435816fc128ca4d716b5199d0e066de5bd4f4761bc4e39a5469ca5962332288c793ee47165d72c6789f4cc349f75a8622487c95ff2a5396f0a9789e18cd2ca3f09664c912942b2ca3a3f7913be93e953120ef55a1d38c4eba9eaff2e3b58d24cfee2cf542e6b2ca822aecce72ef5175ebf9da11b402f0dcf00ded9b410471eb7f005baf9f84add739e7237f8ac27bb075007a46abc778d12dc994cda92be432e7d1c01c371df05b32a881ba3b1b8c890e7a76cf1aa0e81aac113242c6f5d68f52fcf3014c37051240004e58e7663411822188340d8323afed78177bbd1e24ff14591587d1389ed69dd5fc3d0a3ff22934478fcff2cff5f8c4c49b7fd4534b891d5f89146b0c00d53897412278b680642bb013c15fa1e174e81a1b88c14984c396ab2a61d461595cdcac2af8a2fc2f5cb54d734219a5a422e273c92aa282a8d95d9175c9c04204fe881774e7052b4ba72015130d958c5d826d08bb442d2d0187fb78278cc20359e8e9d1b9cad3f55216bb26a026aca9d9fc280655cb8e9b411f19b97c4556c7e277f48aac0cac8863cdfe4420a17589f478a23d6cb06be71559f911886e814819a731837052a336e2c72141e7282405c3a18a79822c8bb3b81785ea1bf614124601cda1303fcbbbd10095aae764de3b1c1e7d835a1759c6f3892e2faf4fc84b2b8f507445e6c771edc6188bc542387c84727b32d70ce0922df3e4574681dd0ba4352238a332fae16bc75c6ea314b2e8922394eb8173b20bb07263b4fd62cd4cc205a3d8a93bbc59bb87df7de7798165d76c8eb7064fc86f6fa310aa32bc49d50f1458a50491b789de31c8569e70e390f8348c82408bf1c588eb5a9987bef4501bc76c40449e99774b43562b8b5704e29006719e5549b6665ba8699bcc5ce1558617c52fbcc5c1eb8760300b60b466a1365ee563c84fcd8188a7767c14ccc2d9a04ca234c9e6dbd6c1e53bbb00920327312d0e994fc31962a91c9a39dc2557f02c109e051e98c1c5601c32b87aa43ab540c92024d29005b14a5c840b05199fbe397677217b6f563fc9740333a86747033380605703f501780c57536004d40c76b4873d7db97c2846ea51078c9549b32a03ab627d7f41de0247a5e3c8607d1680c8249c4b7cedd8f71eb55b0612e0387c2dd7f766f38dfc546b0d4435026bc4af98c930f223790ec7d90411115f6c88c340a13a911caa405e83c2e29b8dfc0aeb5733352ddbaad2aad181923eaab4ad45058c459dc496b4a3b9681f0d3d634d13abd70d5792b78dc8c8d3774557eb72217c0ff0367d12880b2491e1714c7cd46b391e93295ca726153f688d891f4df58c7e8aa58cb2e1079028891f6a887b3d615d1ffb040fcd9771e3a64d2aa9a341f02ea8b8c62f9ff72bf99ea3a35f7026218bf116586310d4f5b47018506526d0eb75c82029396b43e6820dcd572b465d2fa0fbfb1efa4618d3a91f8fe954e802a25e4ff94c08dae0922e539ba0c994a47ccb8a12f257aeb7d9d87adc82a58c33fcc4bc72b38cb59c14b6a2cb384c62f73286cb6224bc8c033990386e3027690cc87319d725445f2356cde4b643c205a939cc20816dbb2f562ddf438b39ab38d465110bae7ab3413e153cc516052b577946936cfea1947cb7d85677a42a0cc46d5a1eab8ec960453815e1146564dc6dca258674ce0d052709275dce10ed4b96166e49ca7340108130f29e63811fd9460cc49f74c58286d41db7e781a1b6af73ae62cb55f03f71000755be7ac9ae587a0e4ebc11213270c2044cbf8cc251e6a823630085aabc901e66d01bef2a56c8bc8adbfcf116b175e942e5977b3c2f055e8a990d1a09185e3a7c7f53566c7996927919d28059c046bc948634d65e1c8512ddac7244fc7a8523ea1bd58d225f57368a7dd5e3d1786a216369f142ba8c1f0353098811f3c1d6630623137b6283445a10f335c0318ec28e42436aee5f7956912463c58b6c966b6620a08aa3a58a670868f8a823aa41a66a674db01f53b10145b8a5065fa33cf11ba9d569821d8755ec524fdc1c8e3d4bd350c70cd039dc029b2853f8d90ce79b2f64730ebd009cbe18f324fda19bb9c0bb627df602a17575e79bf09b3f6b27820be9db7d185c3e796dbb3446c736afc1af71daebb96998dad78ec19868e6337feef123c0229c6449ec2efcd4f3b6cbd85d9854711d1bcab14ecc8faab00f36659f7191a7e9a43bba8ac1024b86c102ce720e0d571bb4455194ae0b5d4c24422911851920064f4c2a0a7d15ca48591463ad26633e4ba96e33c677b24640e47a3d688834214d3278addcb086124a5319164ad31196928259f49d111bf7c47bbd33f4bb268f7ce8fd541ce1af63ff73ecdfc4feaf31df1e9e72aae63fc3bdc63f11bfcfc5ef69ac0e9067faf37b28f3430c72a975c9687e9d39f0b55e3955be8e173804f80da762fe81c76cb2fe1cc353a3344af14318468b322204758aeff5caa10599f38af82fd6438b7ce5c4f9529a0ef3542388992ed90d5474c96ee0ae12ff58af1c30fd026be417f00533e40800e27c75e3c4ebca5991b2620ec2284ef1c255cd92656b07a6c39193641feb5ff0b101147138f608f02b865f2923570c072cbf6285f8e22d627f21527eaf2b679e576a8ce0128793e6652daa0681c97efd3536659371cc19c41fe256db4fb500b75ef0e2de2c7ae1fe18372f09df82a71a46df6423e25bfb46d4dc37e2cda3236beb60be22b3236a6d162f45771a44a17da90bd4b6d79a9a0f9d5d4dcca43b3a692ba3e64b97911337e98e9eb71531e65317d2133be98e4ee3014a02dd6820125ed01a61684cbfaeab0d0f4667ad751a64f6556c5f6fb47c0059db44871ffee56122fc31767529dfd4ff86af395619519f7918cf24f5b9de181664e6bcbeb17048cc6ed4985d51f4591cbe8add67b1afcbf8faceac39bfa2c0091438d951c09c5c51e0391478bea3803db5527aa2863b3845e23bf35fc5ee290ae7661e1a1b1b154a1653d7db36d952106236e09f190d9ced6ec0ef0cf5fd56d37185c17255b12bb92e5bfe254806059261decb858337f03a3e48e284c22564b11b6b34e01c9b22026114148335a7cb51ca2e8a75f631a9166f8b242f92eac6258395f8347d78dff0ea94f5c856bd8df008057ba67842c8e7ec2651a90382c45dfc1bdaa26bfd8e2e6c4bf8fe161bae9d40f1ad72d62d32dfc1701a04cf6f2e029f6830fc1affd63203b0bc027dd5fc331f98a036ba7296254a590f8628ceea6fc885681a6190f1f3d845d115f006c1f0c953651e237d4e3c8dc7c369d03e0eb784036ac604fa847b0de221cdaefffe719283746c8dc3e8693c803b77ae32517916f77a7fe3c48233a0623f50c54f30f104124f6a89cf31f139243e9789a77a677c1f7bc19915345e8988e5330e1a3c696760a399ff6bbcd9c0a00f7d6391485fa7ca77b191f63a2f962495ebc73f8f6b96f93f01be6ae71cae56c57f0006d4e327176386bddb0fb10bb3eb13cdfaa333548d06b1e4f929c784781a50ab73604f5ceb9cb735e7e103126d6bf83f205db646fd03925e6bb0236bac23f3d0f4bd05210dbfe7c0f90f000e8586435d01a829be877190972c4c84f6de2a126727f57adf6bc44356fb631cde6efd9f35e3fc0ffdf9551c8e85860bafe888afbff34308b194b6fecf569ca192f5ff61a508a5ab0f4790554a6ee4f75be3dbd0a199c9e74694ad5ab3a24e7494d0b835bfa506ae35449b5f4521eee7ebaf965d1063df62ec89118b1799eb1fa8ed3382cfeda054001a51afea51a51a4f1e7a6f849a5c97886e814f28139bdf42b9d80c08dd22ffceac5057681b9bdfa87d6c7c6b6da40aca87effcaf38ee54b6f2dd9f7495a2d2fc36e45e842255d314a2661e191e999ea67cc67ff60ff12d2290e6b96c3cacddafde173e83dd43cf0b66e1ed0e8f60a3db681d4529a3a3992f469e8e66fb93ae1aefad6fbad21a8de914cf1a92508ea26df00fe49ca81f79c1cff27be6051f63787a8d1f360815e77e3cbec993a1f8c113a1f80b2747fc6b1c0ec5f72bfce6074a79aae4ffa93330597f3eb10fc3345f47291391c6a1f7b476f825f3f7fa180c7ff0b8897ff1802bff825c41fd1a67e2e7f5b3f15be3907cc96e3eac9cda01ffb979d487df0f2b7150967f418b6eebd2db8ff8273b0ffccfedc3bff8fab032f5f0857a20429cc4c5795cabe7412b1fc17d65fc6988264edac414a7b6bc023e71ac2d853e06243db48fff437efe061ce213e5a83f5a0470aabed8e704e7f3547ea078807fbd545f2012e01f6f94c060994b21c22bf595af2bfc78233fb480e18d215580b2e2fb95f16d0821deb4cb23a01614b7c99f2a9fcf53a67fd6f102ea872fa8fd7ac1588a7feb4375e80584ba5fc5fe91663a221a4ebacadc2265b161e761086deac29eddc2204902eda663ca49177d125145bce8febe27c84344c7319de2540239a3a1c17e7d2859f18c6ffd4936574c18b3b2d48e38fe0c6cafb559bd10ca0869e0a1c1385ec5b60fef7fe0f12ef2a43b29fd66e4f1d148be99371cd1704e8df74522ffd027962ce17044c3c5ce2c52a248c3a499671b1f9301a114786fa91b73239fc28daf5d4966afe6542b2e68b4d944912b1f004aa83f0b691450e5cd8d44f0301f6657aedc5c1a85fc908bcedcb406daa899519752dfea80723865696aa9a5469951cf66877bbdfee1931f4cb1aa070210ab46ffa952d1a04601bbf34eab682c4b0b905c517d07a9bd05b6b37a075e99327378b7b24e128262888a87b3d0d7fe3c724b50ccca0104a555cd85a501ed6d1c66b14b857a22b6cffca273d44c806e09c9971a8059c8400b22cd7466bc5e16bbcc6bf159e6c4c2f3ab75b847a1146b39df1b7a4568e598dd7db2372b9746e7b13c97a8418bef19315bddcf3bf9891ab6978a25c7b7873a433f02e71f2f9664ce4971c9ea91ef39b7538bfb98d06a81719fcf52f6d9f8fcbec8d72b117e53500e9b8a8af946a45bc660c93f67a29219d6702dbfdf0259bc6232fc7e5124d9a50cbd667362a6bee100c25dde22a14f0b46e4f73bac517c9e66d408bd5f91cc0c82c1a8089f008476c8288d1166052246d631cbb3ea23b8d6e0a134c9d8494a962b19f8412509ff24f0293b9117ab05c1e1a948f43ef915fa799dd0fc1a227f05a70ff095e74b682e49d337baa649067e718c98b2ca5756b0c82fd973e96fc58e428f2b3aee9572aaa2e31a7549c4d8fa9734348c86fd4977892706b014f6c12bc23430dfc2fc44db5d795cd26634defcdc278378418aa7953bf46a4c3a1994eb08efe8bb875ef0898ea369f889e2b3ba8661624a5b1fd48cea8fc36ab780c6fbaa93ee2806970efa669cce37c4cbf89f68dd8a9578bd1e40728cef3d46dea02a92a5ebc15badabcff0c2bbb6bea0f2ee1941b3612defb8cb5056eec7e8e851d2ed49b7dfe7ec040b53eac67e0482072f987467694ef04282bc361397e519467a8170bba0abf79937028fba0cfd946634ccdc5b7e9a482ab684e9bf2562f945a444ea518825cf7fd83262b08a16109b2ce7f0c39925fe71c96ee62c13ab04563b3f03f3df152908a0ba7aeedbaf0a12439e6b68c2b6b1cfa96963cf693a1f79e139a3635c9592ce5d77dff9aa5b9f3dfa563cc76b5a62ee2e6e5e2b53b704ed2abf1116579d566ff33babeef526dd8b0bbc2d9264bbf3d57bf0cda130b09360017ef1da9a4f2b88c47a0d477200ac6d7aa5075d3c97602020cf2e2fae341f09880649597f1e60d22559960b4f5a9f97a6badaf42da6a385ffafb82daa0f1e679ad1eb22698b9ee5c592546d2919b87054eab5a42c936cde07d75fda33ea61dd2be91017cc3f69f82a82279d34292ad44a7f6c59226d36878735d3a451edf66da0f4a5049e8805df1bed8667605db68e5db02d23d653c12575bd5bcb5d08158657f08840eb2d2369d2742c3fc4f546afedc9edd6673a0c87c8c4be45bcd9904194d31bf1f492e1f519a30d630c2a1fd50ae0e176eb3e8e7da746a9f3f411869a3a67a82a20e1508f5f10a37966fdde0d0dc97e6cdeb291439ccc5cf2248c7a3dfa1765997dcbcb8d625fecaa519f6c0312d22d1921dca28d185eac7e8fb69b9c19b522e4db055b1eafcdd3b6b17077bf05f86bb727afa9ed32bbd78b8e09ec609de188e0752203b93a87a30823231d8975184d7a23741c4a92acc4cb5bc74afd51a2ef21f124a2c4d1b7e2807bdce9b83b13ddc8eb1d7ee38d3a8796678ecfd4d5523c12a2c19f1f851575bd20721261e5c8716bc029dd8bb3822c251a05de2dc731f902441bcd112e503fa2a3f6348ff112cda26033817c70e0e81c82d9b247c25a11619e290cabf8b251dede15436edd60b8a1861519c758e9eec7fcaeddc192f580cf1fed1108c3f82a115e3410be354a468a78518bac585a8b5917f5981529cbebbca046b487653f577c57d77e86d0f70ae4aa79914503db5f690897cdfda7fce3807f3d83a8e349d73f81afcea4eb3fa7c284878a0be34af04077d84f44ebaa323d528be150e6482089d1610db9a4c39d68a0fcbbb62a9dbfa7f6c3e956e7f1fda195b2c4847096a377241dd38a6a8adfb05c89b4a67f110fa01c51dc9363678601f21030713fd01dc6a625abce9325cbd7d5b1fe9457da5fec2a15a78c14b29c191025f58cff555372e19901fc825b44511a5f4aea24df1b961eaed1c271db66b8f1a3dcd106ab825d25f9ba9494559bfe0f0382b4f83b8b30ea1b9a945470f5230ec3f057bad9f0df13f1fb4cfb84898ca7c2fb7d3cd6f32c4f69af17edef6f5ba0b00eefbcb997347c45aac5a02019cd97e625d647df48ffe8479eff8a0ffcc505bcbaf52243f7c9d2f4fbab4977ff25f55f1b5940fa85efae16a5487f63a49f48d984286c32d49569ff3a7e45a7e8af425d0e302ef418db85dcdea2301ebfa1d3cd26e645d15941e31a4f27942cb27a712156f81d8bfb16f86404cca7d2dc8b2d14e1d2421b914d136212c6810d5ffb55a9d7d2f09cd7b7d9100ebab45d209bcdd71d71af0bcd67c5e7e123fdad3ed5752765d342858dc6d7f272185e3021e60513f3b98edadd8c479ce7d6161fd47209fc9a435bbfeff10ef2d0dcd18f01c9db6cbd9eea8abe8f219f40332d332c4ec9840ead9e4db60e39cf9408095c875aa971c80fe4817ad049db4ee51928940cc77b187152b727cbb3e75affb423baa5d02ba91a6a8ddc55e0557ed51eb9abc087554bd4aecca7c2fccba561872aff25de6603f716c0cb1285576ae4b6273718c32f20eef8a9dc2f4863c3c6cb1a1dda78ff8a08bea6f1045ccd199fe1a5affec4cca3437f9245be4ad6b7b20c831d6a7a6e0a0197e281bca8822f59ee7a5e691c4d3d2f6ebbf092c46e5bbc1f797edc760dc6ceafe2418caa8c61e4da04ceec61109a4ffa92c185752f603c0da2c08be58d273f0adf5169121229572ac1f049d4ef07de3975e37134f5951b743ae94a3317be3945da0f50b4bf6f6417fa66c86d1d007e52234f7abd18eca9ec3ed59f990233c9f609aa670543f97ff1cc1853f311f7ef967969f68177db9a09d48718b5fd9daaeb4a1f2872ac3f0b56f41fe2f72bdab8224618be0bf49522695f517c2eda8fc27f509fef6938413ef559a87c922599f3333dfe990a977a3f53f3e8e8cf4226a755bf8614f77a70bf3d0cd9984ce14da400af84c67d02f9687818d027e19c678cfb14b3cefa740ae7fc4001184aab05e21f3ea1c7877de9b8d07c158929b71e9da18e8e8d689b45d6ca1878e6c39e11f910883103f23d10f31a0fdf9e21d2bc87063ccc8cc45ad8c91ce120a4e5553557fa793ae6158dd9348cdc981f50b165a07eec185f25c18781e948e68c7939842a299f23457c5b801d06a3a1f495249dfba894e366d4081e7591b77ad115d171c4463193d5372ffb85b1f4f90a0f996f2759e67e6f7853bd5d61ed0230d39b278e781d60e145530ca931cee03e13f94d5ddf713dc2e5a3b696cf071a0fab9abd828a8c70d839f4fc5d2318310f3d921a9d37bb7127b4b572c78d98ddf0a2e9c43320895097191176860ae29649019857784db231e4e605ca30625bdf8c18c5cca74ca2f18e7eb6223adf3f91c423a2037e46e884b9b9681a0bab6dfde9a2adbddc3563125f5b48b41d6fdf3add6ebde07bdd9ff016dc63030d4538f1db7aa0bbc5bd2d5425eca0f84e8ba5706b2b45153093e03d17ab4f96ec7d4596ab51d3379243062a79b3794e2a36c8f26bd7dbfa8de50b7525e579b12e65701b4cb2ef07ec73c5326a395e326c55bd5b83521a6e7adb9f5a17b7ff786c10e9851e52fd2defcab16b270a3297f9b14ef3022310323364a2153fde1853012ee9a8816b84d723ba45c54740e16e9fe2db78f87b4351c698658400a880d394e769ed5e672d11ef7822ee9334356c02ea77361dde6b9e51b565ee3733266fdebac494f9816fe63a4bfaed630f7d62ca4171bde070f89756b87bbd3ac4e22eabf638c2f006adcac2993a32983308301a321610797d3a9c3198e7390b25f6b8b79454e240e5f98b5d09090bc78ffdc347fed1b7fea3a3a9ff8985e7e038ec441b08d5fdf3f897e22e2fe69472477cf3d8b883dcebb9974c5f4136f349bba1543677ce3e57f5767abdce25f39798c5ed7c629bcd25ebf5be7bc2ff1e1efe25bc649e9fb110e5138359912f4f16a438c929731f1d797ecec2db88cdf282814dd4e87ec3497e3e7aa64b4cbada90b296b4d3a672d2b52dad40f32cad08d1ce541a69a16d2b292b36e94eb7be51ee34a30f84f6c42a5407d84edd05b330e6ac5988edb81da84c1e6b066316fc688df0c53d5046c4d9ae5e408e87f7e3ce7b8e0fea091a047f79579421f1ae9e6086877745b84dfad2be70b622ec1c5a4f51b01d226ea84a09acfb879d304c9852a446834b7673026b57e7c726e51daca3a3c7204913198d7c02fbadab81d41289880b89eac657f36d45adb66452a44a594592543dd5d8f25e3a1028305b171a234dfc38fd2999f5006bb56b68ea6b5af6b860eaf944ab9fc9cc7d74046371bd48e28525e7e0133254ce5bd5281964413de700a2f38af8240cc38cf57ac25df9a8fece033231e6ceb5664a215e32a5fdae7703c5369d4facd7135871ec92901f37f931f41f3494875318279f786836d6181e41c44696c0ad6d503a6e3488ab22fd91dd6c362088155f4b56911fd90d78d116197a3d9941b8de8e17a4e8f50e9fe097e400941b2a1e89fe71ac316fdb1d64966d0bc0bba67a09760a97e2a11550d9a5623a709676cd09c7b32b16deea47ad4739f32d370023d385a5f1480cefce27e645a33b3152dcc410f72c7336a8536221808b7676b15eea34a377949106c38d6248d364c9ed4cea88411151b263c031b82dd6d2203f58298a8217928e8e1ec30157d0939672d03d2f981dbbd6f4c4627a7a3db7649bcdac13b6953b9e85f5f8d38cf67a252fc760197823f7671a52ff1ff4a1529512ce7a9e3f0be74c736bee0cc49560b7ca8e67802f211bb92c2c98712914ba28123dcfff3b75679ecfc29937121c974bc2941d57388ea335fe7ac76e142eccd6723630181f69308b681a125e6fe47923e12cdb32430bd97134129fd1311b8d991f4db75bff9a85b760fbf2ff71f726cc6de3ca1ae85fb15c532ce206d1916c6731194465c7c9644f264e26f658ae29900417ed96e4d88ea5fffe0a8d1da49c64ce39f7ddf7a6a6620a0441b0d1001abd7c1db53a18b644f9971f76c0f36f5bfdba0fb4ef6f0baf2b5a81fbd5783a11ee9bc202291cab84d1975f43c23270b20213323859b191f8730d0e5aea3d977328be626c18b53a56cef76bf64f0ddc8e6dbbd76a5db133a1033f8f7c1374afd5894025c5df73c369028ef73f2b1fa8f830572880d21f4902126201425fec30164b20b89cf901013569c090eb3bd32a5af2bbc53a37ac2d9ec51af5098e7e2ae6a0bf1d9f8289055499c6b98513e44070293e649e55fd198c0dc03a996dfcc81a30304ef1d5ee26b161bc4ce5e7663f333db1a1ca040cd10bd8cfe1bcf08291696afc16f8aad36a3c8bac56fb4f9a0f298e5fdfef2c44b7077c861e30103cd21216ef908fa1ca63a583025f32c4c92029627df54b75a4d4eb09d8e0ec44584170c4c2438610a4dfffceaf31c5804985709620a0a3f028373101bfd1f019b37db3332bb3bb79fd2b3dec1a340030a543fe79f8809184773bc5079058eb87df882225b989159bb76241c79b6fad31a6b21849a1d3fa69760035b6821c16a086c30cc21ae7d5b703b7dfdad53d0356132b89c7c51c7fe76edc370cff5d2d605505c21c5fce66d3f99265d18b9fdcd249d2fbc897df489ea573c2ac958a6d5aa92c22426773d7189783e10c5c1275ea3424f4f6cf990e8fb866a1e0aa170c15e4adb8715b90d742055492570cf6ead0ee94970e2cff513a30d6906a47762808c282bc11910e05fc2804e6aaa2fc771616424d5306411952cc70826297c5424a980b5e8ff80a6f72fff0fe5a7e2ee2dd9041866173073389e8bf5ee3f7b676e45bc5ae846a4e9c2e94a6a43ff9c0c8edc16819f5b78558dadfc6cfc45ba3feb6145afbdbf81d5bd2a8bf2d25dafe363e2eab9c3f05f1cf5064adc31fad55b0a694d6b26dc1f88a54e595fce45ebd28a4280a29f9c0cee839eab55ac9193d775cdafe305695ad8f4cf2f727463af898fff31944fc2ff0ef9f8cbc679a220bc8517d2288227e9c4ac5e8a86293e589fd43de99d1829d984b555f1049b624c9217e09928a6b493af1c3ffcee80f8685555a696af9b5d4d4ced9882e59e62b7b6dedac530552e0f0a381f4dc83b5d820fdf5687b3995d7915311adf178fa0d2e4f9cf7c044d5b724cabc7eb9bea1d03058fc89f1570a12ab01ffcc7af2903c063700ed15d7d355ef2751270af9a07570c7eacde9e6de9c6eeacda9d4c625e498c5c7a63fa7aa3f5f7ed89f53d19f2faa3f6b84bf32f2a761228dcd22060ad2e18a4b910856f20a3f2a5eceb51a7f52b0c9b2a2a38f6e7935524cc72f25732dafaa856a46bcecb33608548b8ff36a4ce7376a369f30723bd69e10d1ad6fcc8d7c57899a9acfc01b610721e79c8fc5e5824178ea5d0dbf15784abfd2b0fcaebbfafcd1aad2d0b88daf843da01ef382bbfafed1aa02baba5f7bc51a9fba5beac98f364e2c1de172e29043ede04efbbc1017c426a25f4f9501246810740821210b7677845b81b73aa4ce9c5fad5a4510b47217c197646db19743c8691685bcc4719647fcc42793b554ec6ab5caa52398f0e595a200ec8a30650b00f3054f8d5a7ff47a847acb94cb11c0df2e244e694089921621a5701c4b8ce39800154ea4190dc48342e3a916b627a12a6ca2a83b18fd89dcc786e44f214f8cc8096b9bb90065635d061c0a6533355efdedb5c940e78f57e358a321f9ca30bcc8665d3cb64ae04598bf4416f4b7632a131a16bd3cfa9885058a7395e2509424281e91a1752e1a6129998cc4796876afbf2d11d17891b0f2d378e48e180055dbcd8c951d2a35cd482c2e5ea41ff29aa171468a7846000a390b8219a2d1ed9064f198cce242860e50328c694c09f8dda1e2de3d1d549090719cc4d20b08d17bf714b04b719fc668c8cb870817f7efab727abf88d198978f11a6aa9c5700061d1242c6ab15fcb140f0959f577f229b8c6513eba115682aaee3311198d44372761e674190b50819c7e8b62059a3836611049c33c7124d74284c66198a33fe8e0cad8573cad9793c0b82996e6cf6338d65a2b1198a67bcb199686c463af1ecc95039c9cceedd437f66e1f06ce6fa3e49989c19c98c5fd58c53eacf2ccc4465cbafca583ce5caf3700ff5ce46e7d1d908a7e7f609fd2fe6465148cffb4e0b2643f75fbca0fbaf04ad56548048f1b92e8ec1bfb10d6ed132fab15af4f455f417c33457e9778d75d7757bb14fc249aecf53bf893e9a8caa3075ebc15c546792a6b69bb913bea8b44e2e62984e0c0c119b14e1cc2910ab9cf24f03585a472fdcea4aa7a54e9c1937b6ecde3d0458ec32896e2230af57ab16ffa033fee31c27e22f322d59d861d0b59cfcd002daed3e6db680e22c27b7e240f793daa36379fa73b547a2f487762403bea270538412c9551fd5014b7fa450c24c2c9c38977f0bf9b7cc3db3d32077f3c8e93d33e9259a32d1be1b05944489177756e561992b6661f96ac572ce45599822cfdf97e5b1a57790b6c56ab29506c10dafde4bc9adc8d593b6dd6a984d32bbf0f9245b47614ac2d4ed4c107805ee2e2fbe10f1d5ff583515229c925b3a49cbe91c70bed3b6f981c5e50711b0a5ee889f18c64b3ea2af45a97ec0fa65d24a167910247958e43845c25e11163949b1abf7cb72f9bd38cfb180cc578a3fa576c00a0791b01c83fa0f53a52719e68e5097e53f14ea708e6e19c957abd0959f5c5ec80c2f64912f5689c8d59cb41842b734ba65240520859c7ca26d35356293d5a213174f72b50614720d80952ecccf8a73c43bd4eaea90377e9659f3d6d75c5474b8cb57e3d44d620a9153a95d9ce025560b5e6239617c0e256a02b928a7d23a5ae424cf096baa619b54f9dceb78b0cb6605f0ccb0973317e6d5317ac12cc6833c14328b1deb64ad09fc23d35ceea5fd49cd3cdc685fde92ad3a81106b3cca2d5d8cc69080d307ac2b6c44670b967dae54c16cc12e337d4897c7bbb1dd4a3aaa66c994ce01e5ac4129003a4453c304173acf8981760bf9317792dbba125701217a63b6f4a993e54199c9410b098649f96a913c4096e18ed07b757775c29eee2e42112549dced689d5877d7a415d8790212028459f668a4f6ab594e6e9f2fd2a8bffd7c91d2193fbd1dcf68ca123a8f603dc76f1928aa0ee6f3e915bfee6fe32f3355f065d6dfc69fe0ac2e4be0477f1b1f4daf26aa4c043ae023368afadb4780a2d9dfc65f2b5ee1c331a8c72697517ffb99c100eb6fe383d96c512b3c0604a5a8bf2d2ede4ed3217f7efafde3bc9ac0b479c36ea2fef6974995b1c9b2ca01646f8d2f7272fb38ea6f1fd274084900fbdb783fea6f7fa6497f1b7777f88b468cf2e371779753439e95bb0ff9bbca0abebbfb48f6673e1df19fbcc18311dce16d7da4705ec13b9d0800d616b2773b8f6cf2eeee48c2eeeec233054469e0dd3df94b126bf701f4828b87bbbc0f2fa76378fa913716bb8f9db1d8ddf70762afe30dc31e6ff9d564c1c0af66efa13d265da0c48b2e5cf2febdd8814bdeb917bb70c99f7eb107a7fc2e50e7c50328e71d7bf1102e79975e3c824bde9d178f81c4bc1f2ff6e1b20b2fe9c0b57821bc7107ded88557eef157bebf1c4b1a76a1d7cea0efecf02aef189f9d6b3c77a6dc90ddf83a2f985b6aa2cdf233f87dbe5ac15f21a3ba4ce324b45aab65c1f82e1885574809cc622ca797669fa8c9d180a29a595babc72dcb8768fa4276943f79ce6bb87d84b4bd6bac6285ffb94675ce668c4a4d99b0936fd6b4aa55a871d974e8d39fc8cf00f2449d35969fb2e9d19f2189a6076f0f7c367edc11a71bffe84d6b8417b9adbccce89242bec29ccdd516b3749850a0e42d6cf7e3cf7691d82a33a76ce300dd31a80d63b446f8d2deee6c53e2afec99dfdc4f66a3253d69a4b6b8653caa44cdfe3640d81de99bfd09eddda76dab940f22d43edddceea9dbeea9d3aebae934eb5669aaa1dffb9732ec8c96941fc2d4a75fb9d2ebd7f4276d79a73ab12048928e88d8e45e677942f19d7b9ad74e2d3f109d2899e78d92a127755232f1ea4933297ff58ec0e605bb49d3db1500a725174a00ce3b3df82cfbc04601d3ca09b03971802bab52d29ffcc9ea190a9aa4d6bb1318b06b3b61889dd2c02a72bba24145eda2a918898547610b40d3c20190e8995e894b2603a8090d2f9d864f1251ed54fefd2b89281939557ee345975e777416184ade7be49358931125df7c2e99ce6eac81b0074af9f85132ceffbd140c6e92009f6216e269add0259b932be227924ac819d49f7c651ea82325bfafb9446e8ec34ce969c157cae4ba5af399fea696c0b2d345287e4389c8c5669468100127744cfded4f2217189bc3aaf27174595493ade36a3c1b31bbe4b95663dba5c24bc879128e617689e59f6e157b3a1b14bfa3125bf23a27efd37844c91f593ca6e43a8f27947ccce2631aded6fa155de5b8b16bd129c3b5de45ef18ae75301ae6b8b98fd137b6167dbac9c9d939fe9e93fb965fee4bbe8c769e7ecfc15eab922ddee467dff3732cfe48a8f8fcfe7d2782e395503a7dcfefdd8b6545dd406c9a126ad3839cdcaef16b722b8ba3837c8ddf989fadee1a1fe6e420b73c9b7237405d05c6f0050c36133750fd209761ea5e287b160459db8353782773af7e998ce962c8447a6f7942b24d341b1f7c577b4c46fadcae710e6a917cab9a6ca5889de5e72439cb410f1f52bb7398fe52b792cdf5ebbd21cc0ac731de3acab93bb5aa0a525a7b95d0780bff527e6d8ff9511ea2db97e11b14bf0c5f5b7e40cf732b1efcb51afb162107b93f9f1f3e46287e15bec609fff3c601ad7a91bb00b4f650528523f1cc6381e6b0f68caf3836490c8444466a3743e406a7022a6b2b9481aab525e9317e45c3048983840c58b4b2aa6c4190568a6fd70022abdddc72417f970dc0c566d3c0b279e10eec6a7590c78739d13406525241ca37aa10c54db9385ede415d81eae00fd53e4271cacf6572600e738437cf895a6709c59c5730e7152cfa8922e01e39f04279f22abf0bbef8b573d74f4d81df38b7c58ea76fbe755b6617976cb1fc48abc912bf736e4da657f8bd53c219441053f504d285e00f4ead57e331cb2aba64babb1ff31fc235ffe154f1126a7c726ebe9d5ee93bc7ee9bb39179e967585dbfb8942aa797a3ecb462a30cffa9fcc55b84bccd7b6f733b58738dbf4ac3c289fc7b0aaac9bf72f22e0f11fe2d27dde77b4fffca7beff286204f5ee7fe5ff9da89aa2f421de9f13e0f9114d43fe44a41b9bf2f249c8fa6e4b128f9c3943c12259f4cc94351726c4a1e6841c3c754d901204363592bf8e4f34e0efbfbaaa10fb9687affb12af9a84a1ea9923f54c94355f249953c5025c7f9cf76282d144220744d2d1dafc4ae67452b16c69bd8a9f95a4d672b4d79a1b2bb1242bee6bdf06b4ecee8391fd8d779f821c7798150f435d7e8ceca292ab7e0b28bd0ce377492ab78e7933c960c12bfc9c1ddb808dd904ef964eb34d7083f5f73747b9a9b5076e1512bb4475ff3382dc2fd7d3bf39280fd33008754e57d49497246cfe36cba9592346c7590c4bb992858e7f51ac5929125cc5b8a6ec518e8be0401a7c8d75cc127dceb228405658a02e134d62ebe30056cefde520f43fa2fd2d54146ddcea3dd477bddc73bddfb61185abfe8bde45fdd0efa57baeaa07b5df43f16784a556823af00bf50d1cbd3d902dd2622c43741b108c332f75cb0588a4cc6fdb3f43c0842fe07725f58e84800195d18394b84640f854b0a1ec9bfe3c2f32a9ff0a11c1764541059d71ee8696174ed8342ef442fc341a19cdadb7f4b49adfdb7bc2de005acfcddb3c224f4b0519f94bce738174899e5f9f5ac1256dccfd5983d495063394994d70e00a4343e092e498dcf1accf31f368236346143081a84268b9b2ee4b70f0b42634167180031e4c6ca6ce5b1525712ff525017d01098f3f6a760c99817808be0d6960ef376025cc38ae342bca7d51599f43a2d955e6d0326b2667681d3362e08c50931a571426e251344144f93059b7f63d961b55c44099ef05211966f20dd47859d1370e8a788dfed70d1715490241e160e99c8ad4b83a883edef8e123c570744a120949e59234e79c0a32389869873391666d0b27062192f0b11402ea2b5feb864978cdc2674c184de90b6c7522482df009a0c9594d691ce5916ddf2ee5793424e4996e72c5daade5943f4ad3098d1d60be3c479bdb055259bbba4afadee8852b856bda26d71a1fb43dbf2ca4ebb79a5fbe4139e62910668c1047005a4622ea20e9ed19bd194660af5410868d2c3cef0821e0318132b48e57a0315ac847012561bba1f6bd43a41e458f254da4be47047a1bc1298ac3895e57c01930f91c419889bc23d8f9af5c9ac13df0a48481ffbdde4f535ad4d6742ab94a89e61758136f6d1eed6f7c2579dbaaf16bcabf22398012f0893c4d244b29cb86c112057ae8f39bc3f167f889838b19c3fe53a2745ec372956b5b2895a2524652eedbe62fb96459902a1b5d31ddd15e114c92cee1e910e1e8b5d6d26fe5c6bf74bd5bcf89eefa48cb3e96d41be7b2b28786a3e91e44ceb3ceed7f759fe7bdb2d8019f01d9256aa59f0bd2dafcc54f8de5697f68490ac72dd0b67e49af42729c5633244d135b996ac41e3e2a948805d2058d55476ffeb20087535ff1bcc32fd5fec3d8a0f8ab0c07e8b28a611d0f68850bc24df63bea2a794a44ab1bf041fda5b993ae6882cd5fbfce3bef1be3b42b7437224d48129c5435c20ed6c3224471a270fdadc8d8ee4aaf69916c4ba0eeeef75f61fad1eeec532b38dfdee6283e3df51cf7d6f74646d69c56aa5c5b4427b710e858c67f752bc7127e2d3b5a333171ab206417f1252d3d515d9dd81392c97679519b0e8e92272f6fd3c2a84acff1da1f577f25dcc1ad3bdefabd577c267043827fbb357b729fd4f60cffc4e9cf98fd5fcc7d6e2427252e0c6b540269eef8a1c99c0d963328c2497ce626b2a93716c37791d1f16e1882fcf2e2b9351ec6db864e8acdbcfec0394a24dacaffcd5812203ce476d703e9d5c2e39c78c647a64ac6719ba35e5a2e18cb09891f40e4595af75d9efe20ca13893f83a682d50e68f0a32a3ed4f00e92ae49343830f859f17249cb0ab2d4adb8084316193256acf59beb00098ad9d22211ed1627eac82d4742951fb93c5bb692f89c4b94404aeba044f2183bf3f32209c5acbbb35b45af7f3ba20b7d5e2ddf412609beaa64bd095b9faa61755c2e6a897a52145fcada03b66930bfe8a63b614028f6b5614a24143335265fc7b1122ccc851a157aa38232f8b30c31433143372c5aff9955a0d48126b8d8a85671b0421330c90a218e41686e25705a44bd21dfdc466239ab2ff726797b420ddff5ca75f4ce7a9cce3e8f4f9ee1ea7a2c799d3e3fe24e57d4e312491ca789fc12694419f774c3f1303860d6954753f13d9cf4cf6337562b0df14b63b242e54ce15a5ef5486f1a6059d0b91d3cb51a62792f8e4de86f23083174416045810583fdad5e2e3e59c8999ab1eedb512e1a3b75af12b867314b9dadab785abad6d753123d2c8912bcc7aa1068f9bf0598c0e26efe5645184398a4246de8609ea1de6915620e3cc6d6c8173120a6c921621996509c8500f6c320c4507398a13016b16a638afaf086acc04c9ad4664494ffe15a827eadc3227af8bd81a2692c449135f11fa6f9b53eea8df604ec92d3ba53546efac1595aa4f8b9bb92a11601813884d1a8d3eb19455df18287638bb6cbc29e6c5a636bfbc3f3e78f1fcef3b9bfe511df106d97ba104785db41b16aa909f4da016ae6912de371c43cc74631085bf20692cd3a6d5b61f069b15795ec470bafe476caecd838addf30676379580997384623842a598418ebc0dfde37d29d8f288cdab6fb2ecc57c3a168ab9e6d1c98320947b6e8e53843734bd797037bd6fb56a7e02704a8e2774b628a74b610d164b94fb40cb7aa089376037de0417cddaf5baab557f1226447e1fded4b9a6973495866863137774f78e9b21c20997ced462b481bb991a21c1ddd8628b5f1d3bebb38eaa4cf6d015dff7047ee487427a36540bf86b9b513e5a926bcae7872da66e1a20da9cf389ca8c347f839fbf484623ae21ca07ee7601df879fbd7cc5db3e4252fa48cdac5e371a0df71e618a54824dc88946ed5c00566e8b39cbdd8fb0791f6ec29ff6df22f5c6279643da471db9cf099238509e42259d09b93721843c2f00fe5a9490db3552076adacbc059772b3963e711ff87d035df6cccbb9859f20544844c0062d3d4c3a97cbc27737e693a7b15f63b409cc674167f14169686c1c669e9b42ddea074717ffb4c0cb40c3e3b0712d6c2cd549a091990857a8a3fb6aeaa65b93564378baddbfef63d37f8ab3d985693b0bf8db7fadbe85e7f7bdddf8e129d21ccce4550f819ffa51f0055a24bd21ed1c5f239f0be52ff64bd3083439f282629b66b9194cb53a0c39505eedd38b59f151e76d691feb16d670b15cc69cb05c5b7ed0e598c12a8873392b517328d48631e092b0d395559f55533498c34770fd98dc8b427e0fd30a451123f01f70f03787ce2bfccd27932255b1f0bce8865ea35d2e1329278ccc199b29ecd4375d093cf80eec450208db30dd93a34103aa784e869f624ed858945dffe6407a728ca62bb70a7214f40112680f0ae0210cd1b415b6d3d6c0958c6e6e6a0d4aa36562b1367ad9e219fe12cd11e43f81fc28934b9108a9338210c783236a50d2f1bd65e2696aba4cd84332f1741c0bd1326a32612b42dc41b8461a1217add86dfb21f599c912f45281ec780bca69e9360f6aaf7b1d74a9cd5fa9d997e8f3610694f1169b54a36a5aa152958ec12b73238aaf16f87337d8b90fe24f50acd10fcf9e321b012229d9dff603cc6fa00977b5ff6a83efc5fed77e3fc1f31c0cc72616a4cf7b421cb93c3842209a8ea4aea75c409e1b59a309ba2765148dabffd266e4b45e89c2a1f8394f35122f848ae2d0d7c94229c1a3e9a88eccc3835dd4985ca71a1db8521dcd477be077e2884d3d3e4776a418901f5cd63527872be5b6e6dcd8979aefd8383a2450f3e2e9a689c84fa98a4cd63e264afe1929f08ce14eb090c91ca91dd341c966a440f477ac770f05e02bc9f041e2064497b927dc5c068be07c88dc82c3591710e5f343438722bca3148d16af53bf5fcdbcd579a89032321889f6e20fe771b0a640391b36622eb8d8242804ac196d033e0b41292cb03a54115b581d299a674a6299d6da634157ec46a29c8608f4d23f8abde9c3963c07b91f963c0b078221a8afb58e1ee2e7ee94d23fdb41c974c8c4b6640f6884796b17ac40c4de2c7691ac185860c17b8c443938f66244c5a4be9b6410a7c430ad2c107420e90c41c07c1cd9352e9ae6feedd43b763b1953fbde98507642c2d64283a20632d80402a53721d323cc6e5d9cd391edae9d62fb45fd13808c2313990968b353f6f4cc67a8bbfb0b7f8843786e282e4e1052ef08d16bf97bd11b988965a8ab98897e4221e93034e4acefba587419b424b7864f5682c5d47bc4f1d9359c8d40760439190f7620cbdc0562fc6562fc67849c65a10190152c59864e223bcd71c90efe118337ce3bfea801ff4345f1fd8e418b7c5a1437dc101b0d54d047f11e61d3ca875f0c0eae0015e72c253de5453766db522870057687f8976e0953c35528032bfd3b0449bad1343ff78f7a083505c92a1384c9428ee4ff49094b5ca5d641c6bc764a8b8d7655b7c414a10e7439dfd6d1904ad8b76369d304e6cab02ba5dda9cbc94538173f2d2e1e423e0e425be105874786433f39166667e2c5f3accbcd4ac7ce4b3f252b0f291c3cae3de901c457a1a91a3784c8ee2a56065f10d36132f111e5a3d594a26def0b517c0cce61b14935d487ebe70d88577e5c2eaca051e930bcd0543e0e725f0f3126d7ee3f770097cddfc56c3dafd8933d7971e735f48e6be30ccfd53bde543f02bccad73435a16890ce7b8541cfe03ad6110e466cbd0639f4338eb107091736f03411282e9070df3511e21b9abe50dbb1a8d6e47f24502ad2753ec3f945840521018e9cd716859c61f45551e5a7d47b76948f150d113c5fc6c32c4f5de5bc7094a740ab9b51bb703af774f3ee25de235fdc9a61739c79721ce37be6f0ddd55334f78cc899221d18dafad0fec85191735fd0f5292678973c16ad6a18b920c4561c90566d190a8a3faea08cc25c2a5e9399c224abb2583690e0a6a2531c89ccf43399246a1c0473093233844551eee8124014861d9a6131990d929712bbb872fa8ed9dc76078327770329c7b47af0d6302fe23a9b0aa79e30266bafe44b7bccef8712137d4f3dab489b5de2059e6cd92a50604c9850231c7c61af55011b117ba1f8ae587368cbff8209cf1039ad561bf222e64b8e98722ccb5109752bda0f07bbf53ebde91b9350a0210b4f3bb92a5e741d01aaa25813a5e2ed2e1446ca03a53a4d94977b0c89237a2107dbc5ad1f604feca7c321348f062e916c5470bdf8193827c2ac25607e15371d545f8af82dcaef16f966ff05fc51ad3d2fd9db8bf6dedb4f0a307206542fef275c6dd477b083528a6b25268b55e85492942806829e2577e2bf05f0582381f9d0cd8f7d71764ea7623c0f033e0461ab82f01aa0034c5974fafa20f096c47426d598b4c849cc03d3b137a946048466cb52145772a52aa72dae3847c48b8248fd62fc3df0ad977db679f951026c5efbd0c69c9ff4d4aeb7e2e3ea90c93d284ec08e5755a86bf156e612a5f2796df3891367b49390c6f4fedc48a05344f75dbd23b143a84a143c2f6f0ce8c6dc719dab254899b25a08aa5e0044381c8280ffcab40a75c7399e33d1da69075afbcc9e674c9326cfc4b52819b4fc86166fd78668e5089862decee130db4685993d56bc130d69eb36f8c8e3ecc333617a99b5b84d87ac6e0e15e43d313274f31ba95176a7548e244dd8bf9d25c4d2ec1f691004ca2602aad4c864e2a41d4515cc9e6562bad1ab180b185195c575aeb367427549a5f4b67dc7c6eac4a1bdcee567b3e4714c3a617252a75c6a0f45d8a8e643a3836c7c3da4ddbdf6854920e7e2fc4f70fe2cf4779282d1d5fe93f421585a10d173b5d27dff1a4d4768f490da7ce64a0eec4a90e0b0982d4f866a5126d4ae0cb01b8dc06643913c050ba6059a392e4f17bf036a8bb31789ed6b2c87342ebc40333dd261a8f4f5db9cdf666657451c6143cae8476a4d62021a312dde6a41367d3db86d7417ce2ce83a7b91f9db80b01d3f93dd28d3f920f1bbfc0eaeedc7445bae735f7666d3db328e34429ea3e6899f783f02fe4cc012f7f2ff128812520b5b8dfd78ebd49d899c94b9d67f1d6a19d44a6d69eedfaa7e5617f612eebaeb41f7befbd41fe4868f4917c943ee7aa3b1f0d875e96a1cd9e1f54cfde5b0614aaa8417bde688bd7c35a431585c4b2baa947d147c74f13f4c21f49823f102a70e54d5f7c13e46e9753f40388601ee13e348425a83b4dd1011f2c67f10b597221dcb47f99a86b4d543bb2c159a83618827b494851e478dd5c95c6d6cb870692f45ed8e1007c73a911864f8b14ac889f185f0f59f6896597297813093be507f0eb345f9d93b4c1373eb70d441240b9204c0c99f8e37bcaafad560903105ac729d6698fa9b632d919b1a30a17fc82c818cd21617c651027d1618307fbe8c9481e81c735ef6fbfbeef033ef47dc029503e1ab6c50566b46073493ede9af553dc138c25ef08ceaa734dd90b0b529231ceb9985e4a250419c7a3a7ef6bbea4fd49e8179211069f60e1f7aed4e02ab0e017fddeffcbdf8cf041118eb0ff167e2a71db0299d46e24a26186552fc4e19837bb76e21f87413004f631b4cd4916492a14f16ffc6ce4ed6e68b5927162b57d2f8b13cb5b3797bf04ff96de2c924fc8297ee63565651d3fb727f1f57f6b129bf76166e62fceef105119ba7527a4cccb6d66e2742b2734cc71a18601172afe450c432188ff1b0bf35f20736e44464d5f308c5bb4f7bf57162b72e73873e87a53da492fc24d0e4a02d99086a8de29fbed148e6317229ccc0e58c38ac812ebac3e20d1b712d7fa1dd1b58871944f93ef653ba9269938a5bdc73a24b9c646f4dcecc707a5ed7679bba44544713a67fc0589c8d93cbd89529cb1d922caec852721ef9de02845fe5e98905be3602263f29cba109865f9a0a818351485a9e39da28f37bdc6fa519879f15c14cb7b99f7860db2d16169a2eff9d4712965c8f4acf42dabc010ef6d2f341a336ff80fcab0bbe24f894316d6210099302fda881647b537f0fec419a93d24fd3945b935f53ea8fdf343cddfb268cb91b49d53826052861986f0cf0542b7072538bae426fff07afdb31f983be81ccf1d698413ef41f721dec36e34fe0bb7d65173addf6bb5f6f08ea863e3719496c357a3f06319124384b92464c7ca0bdd065abbee75e66cec3dad6577ea34e29c5aec7456a50e7827e6286fe2077ae03992d2657846cfa521dbfdde97f6dc4e30450e56c1ebd249b7fd46126359636872460d1326322de479836ae96d690768022726a4f6a4de2636ed06991d7130e1fc959d75f589722b3beb9cc769bd8b76976c17f1ffbd4ec138ffa86bc661bbf4d0600afe7011ee3f7e9af5f61f4799cd25346c75d05adc7ff424ebed3f72ef8b2686a509f0b0ae1b3e7739bfe16d76114e439357cd7e265bafdd3057afbb3f8c82f125bfcc17f89892f05257b40376b5c42fff1ca93cd3bdd0e2bc27657f1685ce2900cb5300e35bad9232f802e7431c1042de0b9581b44bf102c40fcf1dcc6aa26f89ebe270a98f871be2b1545f57ab0ed80edc0a227d68d2245e617df8410ac0a3f06a8a7dba247958e014c5cc956a735520b8b28c458a8312178a89256ac790af0a9221d610d9d39f6448a9ac1625b99d33aa0233a245812f171a0d28fa037ec97bf0436ee870fd6a3c6373c801f6924eb21113a56fe9cdf47269d77bc7c65371a57842fec8c5858407e597472cb92c002840d551da36793b67f339cbac1a00760a1951a33fd67876f7f7bc29ed0f1237654f9f978d9fe4c792fdf2e2fdec8ec5bb462e370acc6d01b63b4d4eb7a6580d979b56c38d2b597f62af65f608f9df2d5609e70de2c3c30445499cf9071e4be8e5efcffea1d04b1b64dee46765deac2ef32abeab7bb9c3a751a3c1a76b93d3cefd364128d1979bd2e3dad7a5cbb65559e7dba6b1837306ce487ad639e707adb3ee79fcdc32d8ab7abfb627b090366f07fd49ba5e63d8cb907182f5e6539d4837a5d86448c237c88424bc9b92da6fcaf07d8dc9cf124ccf11a48bc11777cfcdb79be7e68be6b9f9aaac4da0df4b3d43de95363f5f956ae80f4b337c75f8adab32fc568a79f61f1855d19a37ac2ffe7bc3fa8f06b53f91dd6c1cd6b73f1ad6f9ff9bc37afd93c37afd1f1dd6ebff2f0cebf52f0c6a7f521bd60fa53443c9bf7fb876a84f8e1c7e5c860f84f307fcd3e19b8dedecd2df3e7afef6f9e7e747227758bdc80e51353ed56e108a066fb20ef5bdd0fee506c0502f00863a0130ee5d5b34fe2c3fadc1afe04164a3a7c6090170276d5f1759efac9cb3fa6e3d4fae1a78d7e738e11f641103b73a286a758577cc43e359dedf56d998c57e2ae318779deec857e09f69bbbb1b69139fb2e8ab0207fee18b7253f8a3d429b14b618c52b66b30a6492aa2db84bcce42a19a39564e34bc42b25a994a56281fa1368048b7b3f360b5130beefb506a7bd2fa53197e28b91005851f4bfe1619e204a1c65289fd8386055b7366a7d659fd4f6daf3768631674d8031143468b20d835975d7d1d23eb3168daa2df57ede6d122e48395fc8bd3e40feda00b5d80de75b0c41b4a14db5579a8bbb05af5b74b4665628820e86f27d3ec46fd6afd9e895002dbaa8f2422c7c7324e622427324e04019d61824ec4ca41414e045a8be5756c75c62f41471ab4ea56b54708506ba854e3c937c60a2a840a533f38946876365051195d4210644a083910813ab098a25bc107d4fd0ced9177ffbe608ab445c8f72c08f8df67f2ef61b65a25f7eeadbd2eade5fa2711ce3e96e443d98357182732fb65b6ecef1ac94fca10fa271756c1d2e037725a730df8703561733c7761d23e597023c27d425bc67ba74528e6b9886e3811112450094a0c6fff55da210a2904c2f2cd4f9fc3e72c8f2ff8f30cc519b14cfbb9b4ad9b89d09a9b982147b7ebe09460db6184dc7fd07d84fda3f413c21aa0f74807e1dfc4fbe1b06fa921bbb1a006d8fb7517e07b6d9ad3ca754cb00dbdf2d09dea39d5ac342c82a095546181d4798f1050a51a1c49ede49a4294329d33ab6aeac251eaae0294c8032cc28e488153d1d342f634a656709b382bc99823e16d07101173a6c68b1adf1a971884ae0b0550cdbf913dc9832064a47097049c9ace6373c4eda55192e33464380358e539840cc32bb5aa4c0e505e1b2088b32c70f6f33db59de1bc817377490a69e2bc65adde4789dbd8c5ec498e7a752f0c9fdfb0fe16146595152f6779a2556e6a402b889cd8b092a9563c51d929087f7249b4f3d8f2e3abea4984df86a90bb610e7e4591e02b1d50c4dffafcfd0f4ee199a575ec414ff6845805627fe9d0b1662ed85348deabb6d473083fd6d3e3cb4b48144ce9c5a81d5dd1d84df1632c817bf9757987121bfd571104cedc5c37a372e7defb9b890281da5c4d52b1454061ec938d1bb9038469a9946bd115914e10845e1a8ce1478249862245102c624dd887401b9859b56b9f1260c8c621306463cdb848251fc048a4a7fb2e9d98d0fad5621644d5dad869c262808def161e22be60859b08cd735cb7421c126aee3ef1020860bce41c35a3dd9fc758b90e16aa5d1df57ab65d1dbb03b8c052609e79631e79c5aa30887255916abd51b51abc419bec6433e5abdf0174978279048d10824b269536b040f692add081e726717efb819a25a8bfd49bd5b16cc47e2c27ca0e8c71fb5f969ec4d525273e3204384d5cccdb0e29d21d6b3978c7046ca7fb31b19697591ca676e2f23129fb6be9ce84e252a84c309a5ef9551a5c3984bce891b971bfc1f5a6ef09d4b4df8f36b8dc5001b561bf46f2d36ffd1a506c352539fe916ab58cb0cae2d47d86afafa1f2e33b546110ec7fe3233c4d7ff68991114ff49b22940a49f5b6854d38dc56186fb13dee55f5a714c939bef869920c5c686ed19ab1aac4dd95fdc20fd16761e3cf4d7ae46aaea2eac56a5e3eb2cb9795877805eadeeec6cebc79dfde7efe29ff5138bea75d3a27aed2daa6314f527ffffa410acf73acf75e588ecb63c5c78071f79e0901e744df11722d74c10b4b4a4cf82e0a500ac69759139d400448dc1903b35dee789f286dd34e91b9779d0e6487f24a944086b8700239117fc04268e7a8e7a0264718018b16e4261092731718c28c509d3b7320a8440eb833bb5c38689c2a9ec94c68610da8b401a297a22fb92575a2b10112e321952a42f83403eae365f3eee224acb0d445490ad55456e3da5199eb3e5fc4620ef3b814483cab5c74a6d0033ee1362efcdc93bbd5fc36e55c661d9c83d88ef75e24e1eec20e3d340cd09d6db6a500c8ec6ad8e776c7cf84068bf4c7e85a6b9a13523ac9d4b1bd16ad512053ad90ee5b53e97d5e285ae12e62bd245f1abf01dce83ae7d00e483aa0cd2a6d120f8528609d42bd06d61dd8919f95a8452a9d291d011cce825a4363114c40d7684be941a0c4e37f8444537c1bf91fc8599d26a58a938b4ee8341f89b8a6a4a7977b86c21b15e8c01a43f4962a603bad31aff5755ac660d33685119613a3ab53902c7d3bc18e56186531b1ade1f7993ec2cceac0f10246636895301b2e5da27ac2f6ba03284e0ff128d21c3860c328331928048a450442f62a423be52f031567dce7807417b68c5a5a59ad659dc9c8aa473d718a4c63a97ba6b9c1910019bf4e331e94fd235b53577bfc8c475fe039d886240f47f88cb5d1e4f9dad537dc7af0c8335157e86d262a0dc21b277e4a154f9d534624993422c41f15d092dd2a646fc42dec8acd0a3e5b8c28e3cf940c805be4566a2c0eb7d1ce1db6a7148d3e1159d670b48e3c2776ded8fa37f1e2fe97c2933bf8ce86219657849ab5194c21f331851070a204131c396c377be8ec2a26dbd8c24b868ebf68502ce2ad02f241d5c806516c444de389fb86df7b55049bd9830f984b4e5e6cee88d6b3ba6b35132c0b2d441ae388760f86aa4cc0bcebccdccae1aab60d88ccf9c8c644177b5e36a141fee39c165620ac233d4db826924a69e0a8a3573e9d6b5bd352fcb41002c9a9a444b10db2b1ef16fe926646c2e756373696c161d3b369782794de556b0a3736963742ed5d1b9d444e79a06ac244ed48fccd596536bf5586701e9aef9de9f35ad5cfe34ef4f60a2c3374b2b3ed3c9adf3e91c38b2bf1da59ae4fc8b9803fa94c68892d44c625c136d20aa1bac292902038a59eaec9c344cbd04db563b000fd78fe0d401a044f1a80a13dcea62067ef5761803f2926aab09069f233edbf92afba5eadb58ccb772d68857e97d9fb1353285e943f472ed2edc909981ae45d73b729dbfbbf7cb69c196252440565f6cbc4864c044d3e3ca43a1697d5f6f3636fca69d9ead4d3171535fb909c3144caf6f3b8a3bc289fcb008331970dc94d1cc01ce73892c1fb0e6a20ff6b48b6c638e8ea637ebc40621cb88234226d2dbac9efb7ac65a53cce6e0c67671da242835519c936c52e169856715bea8e2fe645211d78fcac4a17b8b5e2a969107444227af560fd525a26d3ae35d02ff8ed0721a32cbdb9e825c36963845b7d45de938c3a60d2b5d6a162a679d4b1bd7b954af73a9bdcec9152cd5f7d7a9bfcca93bb145f7f53a9e5a9442b7fcf0377369e79a083d7d04e7975cc0ffd50c54b1078521443d050992eaf5b19acc204d794ebe276121f4067095f167cecedd193c9d095d419493df75f5df37565f40a26da80ee94f727c0ba8589198ec6bfe34dcc86a37ea8d1950e72827aff4db5fd5dfaed68b66ed46de9e4e9e8d2a480ad4a8e3cb4c85b0684f2729bf268b0cada79940fb07fd091eca642fc038e55635d9ca014a216b9774f1e16ac2c788cd9737618982206f2a144c9b9f95e74862fcdc8c98d4919720a10f79b30554c1052afc46867c474a57ab3025b76b84d3b3e13911682d7c8af4b7333a29d87c7ab918dd1cb3e5abc984cd5f7e7ef716c851f2ef57028f29595cce6673b65880de63b27c9e557048ff4ae71305e0edd47b09aa8c6a3aa9d5a097cbe98b697ab95045e11fb44e851e5dad423e78280a29a100b024b22e95e2e8800c7d25a38f4876569ec7eafc98f7387922131dd738007040940a8f1619297d47817cd28b744e62d112e447ad06c2af56a320183595370f886e6e841a9e0a82e26c78de226474363c77c6b43f814678b9b420f17b9a687cdd16c44a11974b463f1a7911393e22a3dea8fdf7dfe5723c9294e307e65ee195496a05013f7d8f44d8ab33442384229b8da0f982104ee126d4f711e78c7a46cc117c8fdb34a0578d78f3ff299e6c66c0507fe43c0bc19a46572bf90982c80dac3942689dd6e8a1f90884704285ac607b6230d72b646fcd17fd8bfaa28f6e532173f89a6c2b4dcfbcaab9ae8a43925eddcb2acbf8a844e04dc84f3a662bb645441b7add06194f8987b3ae055dd11c3412b9f281bb6aa7d3d188ce162c0389d5eb44e6cbe07a17b73b91f912b7ec44d64b2c8c18deb0d32b71ed742dca5c49c649e67ae7d131d6c0d2c63d7847e2693d947f1f28183205b3258106e1cf63592a1f52585c7b912d324a343359f456da7751101ce5a1407e5429f894eebf0c9195253e756ccba9a7c216497ba501c6bf59ab2d8e26de39c8c8afab55eb6b0980d63553cbb40a13bbb70fa20274b32969c0ec62d2c05d3f93b41c5f9f99181e064a4bac7cac94e397ef6985f461bce522bb5b2dfae9fa1f2214f727362814f5f1c4aa3c848f46b7ae71457f84f2aa74c5b4ecec5d764e92383b7b9f9d933cae1d52ab7c4ec78ccf102966497bbdfacdc6094ca017617f7b34a5597f5b430caa79f6adcad8d43c412fb38aff14aa864e4c9fd0d4ce0afe22a4e9193daf35b3985ece53265fc5386d1ade558d0bf3a66a4c0babeba36a32ac3f7e47c7f3e97c2c1f98b3055b9a071697c9b85a363c92313eb317f2a9e5b42860c9ad75538ab60709201b429bd5e41b1d55b21f732ecef5b7a7936725df2d0dc89d2fbe66edbfafe6fc3432571a87db2bba7877395a56b3118b5aadbc3d963fd6bffe1a4bb07d2dba8afd3670bd0d2e8c4adf512d84c229400ba23591b3403a17ed59711e7bdb76d16b02992c7b599b77506ebd721fa5e4cc7e1a97e77c9bae63519641e03f0ebb7a531be2c6398aea9b74a165e51236e91417685d9f4572bcaf137e4a7f0ea40413e1266a8b8a6fe1dfe681f78f3d9bcf17a4f17c310933e7009112eac189a596bab8b6d5c32256907d387aea388f344adb901fe748e237c69410722172babd4f4286902ce1239aceab9970fd61bd9092a22da03e24e663d8dfceaa6ffd6dbea4564a4824fded27e2b9a7fdfef56efa2ff5631b0b55de78fa8d896339b563304054ab03e0b7ab45affe62866fab45c46fae41bcaadd47d80c04ef3d588c28cef454eb15fa92b43ab0b77f875a7041c46f8450546bfcfdb148d148e5c24c6161cee289d8645a5d30e35a2b3ca171416619b846ff4796effe84a2b854d8b13fb18897a41397d6225eaa45bc3cc74d4d352ee44d157f7131a7ce62ded460c3824ebd05bde9b10d8b7a6397cdc20ec8ba25f92eafdc7593fe78edd533bb24bf2716726f6d25a0de16e06d0099b501949b741abfdc3b776710b1fc71495efdf2d7aa15ab2499d8374a24bd944bd83872be6900ccf2d05f7b73a40eddc3b39c6f1ae6a49cf7c65948311cd1ee3a6fe6cde74d7decfa2381566a07c9bc71471af5fc0c5f80e30b572314049f12d5a7fa7e3492b77fe96899fff06899d7d51d79e36933178180eab099e25c39518c82e082f72cc7235ca0bb77370abb1bc5192c53fdc91dfb1b85fd8d6ee27af1ee4c60d50701a4d83a582ee75572b964617f1bcad5de3c4f4259136d9e256645b6e6449caa77c8dd2eedbde41f60d711fe4bba479263ff141dabd7766b58dbfcdd9b7369e9f6a8b335bfc864e04b6d179e3829f7ea678d75ed08f730aaf2b0f118732176987a308b3eb034294d322b07d88f0e30b55396778681034c2f748f8a59cdfd38155b2316720710b9591f01085ee18f44142437e0cfec1aa0a2c30ce957d8fb6cda40cdee6ef4327c271cda6a083f776214fb96f61427b18e77cae28cb4ba26a5e1465864e36304b48bc25a224bac33fe329c6a9d045bada0aa304428c38baa28d162ac20658d12d30bddec7d0c333bd639475178477abffec4ab2f0ef2cc0eae46c2d89406412b93666a635f75229c5a4d14b9cb730b1ad396f3a08bd0319f7e551084c7e4b2328c2e8a572bfef7b242c7e45b0576b6ab4aeb1a3e0741785d859ff117846ff8dfab0a81c752ba5a659e222daef1cd9ea325f1b512dd8eba3d2dbc3b8f7eac81e9eedfc1934a3fe5980359b33b674e32e317613d0c273886e6552856794db596a0da1d4e06fd099f03b0adfbf6b61c4cc16519e64ee418baf57d19cc7bddd8b1d8625f4fb189bd8541abe92ce684a76cce15f66f877fedfa209c64fe5764316224c339496dae0ec84e9def31abbd0e33fb6d13014fcf3cd33fac08e10677a43a9e54ae7da3e41b5c0769afd058af31ab614b63e65aa895fb406357685329ee4f6a1dac053f6a5f2eeddbe576d9dfa1fcdefb2b20bb23de30f7ccec4d9f08e21ee8687de8311f670b8b13a78418c9dbf64facf1da1751de363fd66e6ad257e13b6c2d51ab9dba1b31c98d9956eb121902e718983fd84c1e81406ecf1fcc4fa438f5e8e09cf41d25803f77b0987f1d9dee47f829713153a9f475e13bbe6c07addc70b0c92dd89f6c9c5a1a27027a53db2e261a767be77f7ecb43743f6b70df7a9a79ae5a41d07d5253642872a83505d7f6e546770a92deefa238b3ddca7aa11e959a9b4d0e8288f8424de99e314de491ae89452d923bc2464b11b4070e47f54f0bfd22c20973ef41a783702aeb638b4c24c599f469d3bbbf3d022eee69137de1059eb7104e2c6f6fcec8ac9770168e92a08b702a731dfade250f316785252d9ce401dfc147be31a3cadb90da5b9f86a4d0e3aa674cb0d7d97fd8b377209204f7f73afb8f560ff730b5b334ee467c2b8e5f866ff83faf51ecb6a8c53910e2fcecd00f108a9b5fa231cd94bd41055e00aa862348ca3b7cefc6cecbf1af7c4777df696893c8b141d8507d72815784c9c182e9ad9c4414429540b1d0eb44095e2c693a8c5ed330d1f07e87d58618bcaf8c0e8fd9b227ff46c76c69ac88cfbc2077f1062c2d1ce950efe3c6c9068c72af2189a6a5be7c4525840182341bf6798fcb295da2c1535e51c55d8084944e278be988b541c7c4bf4760193274bb60300fa6974b1b6d4970068bd7c8a2d791fc0cdea0cce85adbc492e63cf410ab6187914dc6227655762445b7cf8563a5f5be174e7c899b5e3e4177a0d2420725f86cad7d9130ca4595b58c94bfbb165fdb1ae9991d9535726727529e476262bb9b55b0f3e0a131ed19cc15ef78da000263dbbf1291aab329902af433400b89ba975af1ab2912b8117fff3d67345dbe9ac03e366a6a8e246bfb73762339e3e5b15b4e42578cf717c387bb5e0ef69792aa9c6b6d5937b193e97af8d6ce68abb943128578ce658250b8a65164300400605de232eb2b85ebac0fa05910649cf924d2b5c4aa4fe15536c6f0ff6ab7c5f9ddeaf51d5db468fb5a9bd5752ee09fe1d95755b88b53259629dea5c472038403acc5c97bc8ce8143eb71d9a13c45a92f6aca4cdef38eba9c4b53952cdac5558a69438c623d4f00fe29be46eb84a44d07ad24089e15610a407cb1cbfafe13ced04aaba095494a7a46ea61106a091bed8caa4af6d4367abe6e5385b5ee9d9a98fd89d59c69488d0c444598410b82179949ebee523808683b9fa6978bd0fdf487ce92b6e72e70de7ab71b69df4dcf8d1ef26ad51cbe55c22d770c277766e31277fe4cf97e883c9eddd78b91606dc9f23bdd9f5d9cdee809d4bca1bcad82e06d1526a8c945c59f607bb58946bdc5c371c30040b4fa9181220d7b2d160e016c9df6f61f45a90f6c4d49a652ad00989741a537b8b2da7f5588037ae32d61632c7089d61aa94b2e3514fc5ed768ed30e88b4a389ad89b5333d9d2c62d3f088e2a99ecde34fb40366b15ed45efd4b038abdd7b4728b0f21b293f609894d476d2f7637664612de514ad9f99631ff526a6356d474c7d6d47ec7a7afbbd700a8d62d6f1160b82f79c22662bfa505939661f108d56b76b2ef7d4a54daf8ff09c4c026a64291b814f26cdfb5081df8dc21cd4206f26e99b3f913a7c2225ce1ad4b005098c47d0045be3cb17572f80370668208707eeaca3a47bbf5b90becd5e02bb0f8320fc948422b73e3feed961b6dd4728a6510236e094d03896298f273fe7a7fea1d2210148c1596be2fd94c3ba78b179cf03e373ffd05c761fab6bd111fb237690f2b8df4aec84d76a3311bc2106c5aa297c5d3d377eacddf8d790c3cd7d8f40b8f336af2dba5e67bd3f40c0c6098a3ea92b9b11fff0bcff805331239c973311952010d51025ac674d8cc88606ac268b259da40c27bdc79e41c44a93c9abb1b9dcfe41848bd286b2d06b22e4bc6c5ac189ff4c8a50c42be1c4899ca048784f0a21e4d3740aca32e0596bf7328bb1d62d27ca3e063e7e96adcc0dc0c8e43e61e2fbc516c1194793d5090e9de888b7c6fbf6b87cfa4f8f4b13a5538f5e3ffd799f7ef0798df79dfc16faf38c4b6c82196975718e8b58cca516a435cb74a01cac05b133e1ebc640befae584d5173fe62c7e855ef894f66437cafd24ca71a19735556bef07b5d68ca8f0e43523adce5a46f96426ca47ca9ee273845b1ac54392e11149f1980ce3980bf46faab0c4632b8dfa588c4410ecc10fdec6d85d24c678ac6a69b3c918d2483745348e1b57d0b15e41c726d2c73430d615d6637fe55477a0921af3a21796a43fc9f9075a76573ec54b33c54b7b95b0ddac86282abd02040a6e5362358b746ed63d43672b1b8a8a91cac9c64cda62303397b01924d5f382a8f4bb405005ef5cff3d3fd34c9587d98658acac7184323d4259432c5666e68b95383c6480c395f943a6eb5a460247ae3bfe79bd4b5dc47ec9cfb2897f96b57f29a0e9c43ddd4a5f090bfec335c93425cd14a7d60c14348e4bb2a321a88b974e86c654fac369af13610bee6fcf2978a4098adecc98521d6590f439080e13112035cb84835d42e02a4332e4b613b327b9726163f7c88e92fcf333768e4bfee75ed775322a7ae32c4c71f92327a3a2f747a2ea797ead9fe48d0bfeb7c025dffbbddcd8c6bfe699fc04c187f230ebb8d5bc716af82e307c97765cc5da96a718bee39ee33183a9f29891b389f65ef2d7ba75c063266911e7511de3e4bac8343c5ff7a1899a2a697fcbb3f3888ba8fcad68bd5ebb47f29f73b2df418e5fa5712ea939cdfbba0e47dfd896e76f3035c96bbe69fe99863eee8e37ef6aea815486ca923a0a467fc2cf05519809639eb2387daec02e635bd0531dd59fc626a4555854721b7e0867bd106c8b9cbf37608ce5ed055b2a97b19ef30bdc75218d3d38654da613e19d558d67d3f9924212fb2857a9ee89aa81a2d0ed05f355bcb243cc247bd1739b5f31df91cdea07ea31f542812b21bf4ef7629439dd6696fcf8505389363245d6e30c17f971af1af960d7d814261bd012268dc844960a87ef839e934e9cdb0809fd496ef6a9ff00b242dab0c7fd02ae42facf7115be801ec3d34f3514dead3937c9011c6dc76655647db751daa09a7a5068d81cc503bbda3aacf8aa914fe7cf696ae5dd48d4cef8676565b70000b59433ac084f4adb34cbc204e1a4bd2cd924cc7086d05a1bcdbede65347b47673df9377a4767c6687652991451574568506e96b420bb313fa8dd8ca63423b752cb6ca53fcbb4712c6da7d26fca0e033fad56abf0b4e28bce5f15c9502c2d746b837463a31cdcdd137d6cba99b18db06e9bf1d0756a4ad365f565568f6507352052c8d07aad42d6dd3156deb2cd0b9fad507f4697692962d61a88d41cdb9d598866831e1d00f71cb36578b62cabc5398ae800b881ff4258765b61f8287b27bf59ef492829806ff5ad6330c11a5f03d81dd7688dec8182e93120efe8b26ca7ac1ae174e0e3ff1fc9dc566c8eb3da4d911ce04fd2c16c401ee37c40ba0f713120bb3b7859910e2e07a48bab01d9c19715d9c5df2ab2870703f2007f257fe2cfc265e044fcf9423af8982c2b3c1c8882d18058299dc7ceaf89ac73c55f321df0ddf533bf9c0dc8834e079f8abb9c4dbb9c4dc5d493cf5c40f5b9fcb51890fd0e5eca5f9703d2c1df54e303d23193eaf742a7f009bf06613e581503845a84fcd9d31debde0ff9e6fbaf6e67d54111f80b0e7a5783e8caeabc53c731f4156aae24124ccfc0cb043bda6fd45021b6b23b9a9ac6c3747f1fe250cd032645f60e7f20fc1ae403f802f5c417576a2025ef52da5e0a2bf7bbc5aab35a3d78be8b771e74900369934949757f3fa2d638d952e8fee34836d87dd0c1dd8e1bfab42f4d10fb0f552dfd1ebbd68388929d3b7598bb3b0ff93630d13e9a7c53fb1204f7efd3c6249eaf0a9da9f541e7c9e5400a850e23e82d46b87990eb8158511c2745b96bf0c13004100988bf064cd039082cd6219c756e06214551f8574811fe4aa04a51840845bc240ebf067b506fb5da7f2c5461fbfb420da65692e5a0b7142bc93b3a0bcf2035d339781b2d077c49e50d872605c46a953e4d50102c075c72132b8c6b25901ff7bf8c31a676020933e69efb847f87c19e62cec22d00f995b8223c306f5392591dca1a117112f09a6a72ee4a90f30d9b1e6ec6e54b6c4048257389ee4b6d07233523e6dae804d646b20d3fcbd8b243f0023e26847cab82e0ba0a19fe82c0ed98c11ea11c7b9cb4aa035b00023b0bef28cb003448ba33e94cc209f8498081e6a330c0a86aad03c111a6a61a71dee6c76a52c8269511eccd647a35918dbc65dfd828a6247d4a7b69a4a7e0ce53c01d02f540277226e45f322751c7a4d732dd4654efb71ed5adcdc1d4f938afa6f36a7943f6f7ad5290dc5811de0c6cc10c5906f88400f1c047d27e2ad6d97d2c9babd7b0686d53373b8dbdeb38c6ffdf1bd6908cecef475d7eb95aeda89207fcf4d7edfc4f686d2e09baef95640867a4f39464bdfdfd68e781b87a1c3d50978fa2fd07ee71514a55f59e422edb4d9f06a637f6547b96c7295f80f320789387295a6f7cae3f49e206a26471423c22348c59941561860fdd527c2b77aca84e1cbef7ae51ec0d5ab276d6c043b906820400f9c4b4d32a24277e26eee3bfb4bb9c9812c0356a6ac1465ee71f4f78f0d351ed3c42283e1a84224af67310a47cff5aad9e0f04789e19a71375c0f81a7f5d917c20110b5ef067b3e9d6727e73fb3bbf16eb8bb659bfe40d95485aaabb289e7076fb4ab2381d68d72ee8295f6e4ab521266438c0b213f85a388489ef4face5ee44797030584c26d5a264d9d7e97cc80921dab6bc1a4c15dfb91667e458c9874ab6585642442807fe96bfc7b765b8570d22189b9d27696f27722de5975524fb0d88b17c653986ac86995cbffa939448934af33a465e0d207e991fee6dce1c0d407bfbb9ba371b0083e16ee70943b08c4d07061fcb5b2fe56292af56f953ce2d7e0592c66ad4c518ae7397c3f22090b97ce02b656916049960bf5a8399c2cd53229d4873495e66e16b6f0a31f5d2d7032f42efdb8fe8f8f3549c0ac2f9fdc41d11a0c438597e822ecc250b0b02f64b64e94f1461ccb0b608190f7ab5e5753c104b48e431402f239d86d5783440f7b920ab9ca5fdfb29bacf7046d8fd0c779e66e0b9dae1cb75d8dde93ccd7add9d4eb4f7985fed3dee44dd0e5cf23f51775f54d8dfe944bbcf779f66bddde7bbd1de2e94f23f5177ff61e77f924198fd8b5f21743fc3e9934c22d6481e7e02baa11ff242b691170683c8990c2d3119e40a3519a0db9c8c0612317e32883352b493cbc5cdbb6a727429263c3f55c4b013010999ac71c446f486dfc339d0ee7ee8912e47f7c3a27634419c7af913c27a9d88ddcbeee7d6972aaef5bfb83fb9eb9b9d8fde74e6d8e7678ebf240f7a7b8b256479fbd4daf6f0b7f79f9b3b45b70482b5925e6231e13fd959126b67491a7696d4d95932676779e3ef2c4cee2cacbeb3a4f6ce92d5769654ef2c89dc59d4ce9a3a7df25ceec157e5c79b4cbc71934962b1c1c46280f91b9df1d0a3f17610da16cae540f98e2d07b1541cf0b7f80a40ce6bb7cf06618aa1f5948b1dfc6ce7481aef06b67f3bd0bb0b7e66eaac0a9e4c320fef5792da8744cbdbf6bddf4c40eeeff0c6d8e0e75bb3baf55c1f021dfa6a37ae468276f4c1c0995ff1fdae9694dd8977bf8b5f65618a5cde133e3d279ea7551a6b6f5fe52c9039312199b4fa8933d933936268a1cf859623492623471cb72a3ffec3f6b22b4a0f88654f54b73dfc6428b05db45f2fea44d322cc90ede0f499d0f804904e75f08c50947e21497c4c96552c9562f178401cbd582c3561f155453a3168c21c9d921cc76c0aa10730210726d9c602b2e58e059aa318bcf70df0dd2ef945fa7c8ba861a67cf664c4a476bc1e95a4137f241fc87bd97b489d6b898b3a1c590db75a298f4939c0c30149a47a30a6913a95e05cd7c60539c125e167d72f71e1a0b577f61ec785e37058d47c0d0dd701405f3d1155b949195c82b65e9064484aad7e2b749cb284a528ac9568d40b0bcf9f7254cbdbe4a946465e018afc2660ad12c9f63863f7274e7c339e915c79b85ef36e5e13b04bcdc4dce1c5dfc9ac394ab845c87774adecf8df2dab54afd5895a5d73664da9d586b0825d9bc4e229d551eabd563782a0ed94de11a7cd9b1f8baaeb35efb3e8e8119935d971082147a2c25269d4e32528d28728769e204b61213b5277d5b0cdccb0cdbc58e3c27178dcd97f0cfcdb85ccab9c84a613d650a34224557d64487443ae8ad0d660c34cb9817a3bf1751116f806ad6be3efeb52b7e8ba542119854c967340587b564d8a67342df92946f6e7a0173a7780385f2b5c2a2ae103d0010e7189501496e400f4854384f5c8954110365617997e4ab0631508dd9640d142e8f12ec8075bce6178880b140f8581eb025fa0b543e4bdcefec37856d309eaef9d91995a27856421197286e2920871207c45b92c783313c9d90eb6c046b1a56d21fd6d74afbfbdb550c7942d68684bc734e2ade472b935996e293eddfaf26aeb8a2eb61633965679c5b276bf3fe9f7270759b645b79e1ccb6cf8ba3e69b7db4fcdfbb6caaa28d97cab9a6c2d4bb6b59c33b6b59c6ecde6d36f55c6b6e8d6684af97ab9554db22aa5cbe97c6b3adf9a8d68cacae92863735e5b1aa5dbfded7baf29a7f2fab845c860005805d5807ffd4115969cb67292cb7d7166ed8bbbd190f42765fc531487303d725285333ce412e14d11cef021729debbad1506611bde2abc8cd8ce1cb84cc5ce72039ab1c348120d860c6bbda68fad3de9e97c9a695f83269b4cb693bdb6ad5a203e0d3cb04217f82df45896f09f9cd25c5b7c424f0be832dd727e4e3203c51710227a0083a498da95dc8cd4a4cb6a2f6063a2cc148ccb6f0bc286d200980015894aefaf440da33e8137e10db794283201c0d0845967f3c7d32d6f7c60342f164406c87f9c3021cdf9f5e5541105e55845af7b8e07f6b6bdb4f627442fe80ef35b6b25aa520687de1f256bdee1fd659e7d3c0ce958b29fe826aceff6e808015b913269cec14a1381b38318a3a18d871ee87d79e10aa76c7849cd8a70623802a763eb1bdb93b7b8f111fd6451526f884f753ee0a5f562b2eee9e3499066cacf90ece5425db6e21649cac862a401a0d15317b2a7c12188a737909b8e3c651b0b123245ddb4e105ab13f31b81dc4c3ed802fb626962d5a81686f8b5a27f62fed7279e2626d682715a7d4fe6907fe7b4d3a812376c308779fd823a5dfd39fd8cff436be27f23ec57b1592c08709f95e85274e56040bd9c782fde8ec3dc2899bf9c86ebf160183a92fc7a235e74d2bc3557de04e087557a113145bc83683018a1b8fb6af1c4583975782362378e8e9f494f692889ac65edb8df193465a84fbfbf878e0f9bfb87db11d59f569650bf414ce17cd07e867951cea186a9f5d214cb8f9e06a09926e928c5f3cfdca8c0dfa0ce7fb173e7a846a8607d9e6266b519361649f97366b563bd206f06a10a628ae9bf3088bb3274d3adb9eaceb143655dc64e2239d085aaeb76238de6da83fc90042e3494dfdab57014b45dbb16a5aba30b36098325e576ab8c213f2597b97a0b8fbc48ac8e9a993adbd2a84e9866521c58ca4ce12143192465ea13539755a0cd0e91483daa67494913c939ad1eb4cb870dc64204d0ba035f0d9ada61300dce86f03d6bf8844b85df0a2a868bb75309b6476e1f349b616d6711add96242c49e1e19e0541a9bd6c2b76b55a5d55936c7aa5d017216c5eb5c6ebdabf458f8702e269d89ed349c19e4d2f274b745b92619b4ed2723a0779500234caa20f79be604bdc9f8cc95004d042a5a1fa25ee83d6ca041fe0b1be9452d555c2df33b123c6f87b66a483afc9fd2efeceff4929e9e023d2c14b52e01b595b47a8a8cdf880ff00f0600110360a82dd16214bfdcad52abc26b37b2314f35a63516bd850eb3b99dd1ba2981fb04d791084b37bf237388e4a1773db4d203c204b07ac56288c6ec8325e9283b51553b3e4274de96499c437e29076ef5eca397e1404bca3088ac7bcf888404779c7ecad0a5ec7b9fb586c2aea7d4b72c3df69057aacf9eb4b729f8b36d7ab15fcfd2ea19004175e03db7d97a1166248d625a7a5acd0810a1d5d4166c47a9e915b9a2eab6f0af7f6882df93155a61d055e6019bf171558f3f427ce6651b98e73888a3ce52b9ad0487f1ee8c8dcabc4f6533df5f788dd0e42f1f32a3cc557098a4fc9a935d1dd5df414d96fe0a350100a0a2755418a6c17e4d4828ab980b0c94f49786a79358b441b551e5e04dd9dc7e2b14372da98f8ea50dcbe228780dd214baf369fa07a5702b323ba721619b456a1041741b7b3fb58e706f85885fcdb1cdd86e3adf5704395e32ab4ba8c4f3dd5e6ce5ee43ed1edec3cf0aa3c76abf427a2d29d2def4577de7e1c8dc8297e5785051ee112e1f75538426b6f64ff0bcc71459e67f1a158be2fc855db62dab824576d976df9001fb608b90802febfbb1607c155167a65ed4c5ec819822f904e175606c14d165e7091fc90946d986af88a946d36c98c0287b3cc15393468d5ce7e72d10b2fbc3d841ce20b670711bea1e36a125ee10be164aad62f148557243c245eaf57abccec2f874dfb0bbef27696fe24bc2257def68247e4c2866797afc585e992faee11c2a5d137020d7a456455e3441921dcba6ab3eb259b6441503c2df9c99894b824052ec888bfef5b165ee002e1b1b82a111e05c13808427ea4bbb2f6b8d5eacadae1f89e01cbbb2916bb18dc98c225bfa5773b080e540f58bb1e948bfa62600f25b209f04f88f0617bc1963050a1782356ed237c2523ee0e4623a8be08112e9e96bdf0aa4db34cb470c8ab091284a20758bf10452134ffbce11e76da80ffe24372760e610257e422e6c367768d18f17de2cada020f450a1aed707e85472c5f4657ed453a9f8e466f59ce4582e574a68b3e4f676bb4011fe142108d4f2205c1c13b72413af1c5934315c27571ef1eba22876717e7fca3c58badf791ab36ef43eddee7e98c5cb597d3d99aef31ada38c6f55471a1041adafa9bf355c98d4b36a5bb84c9c7de13209761f06c1eb2abcc0de6256e5e165223686430db9239450a71e7ed33769e73b49c9693d82f6d489a03d2427a967bae645eb66b27e4b7adf92f01045df0cc8d3e1fa7f611d3d5542c19f39588c73212bd8c4e61be70069df6d8a17039218dfcf53c22ce227ceebf0690d78f3946cf077ec485d927416aff9e17131ebdba07739b8772f0a9593304511bfdcc0ac5f0641f06560e708c4993037f38f3aad24e584b33a257f55c6635d1e7899eba50d942a8a70c399feb3af7c53dc481d6614c8acc1ce838728087eafedae4201143ce8eea0d5ea62b05a859cf61d9c15e1fe231b46054eea7647506db8ed33fe9134a6eff3f72fb4297dffd193c5a0b7ff285a0c6270c9d7510a4548f19f03dbd8fda7658f27a01810755bdd5834361fc4d2bdff273406bb5da40004d5514d04cb196702fb8437d1f1f3605195aa068d0e68433e70daa15f02967a59850f708af02bf1574d35274b10dd34d32816393c2ccac7d4e7fc989274fd952436ffb43af6007d1d983084832a4c7182e284c89022331b507c2d34cdca1fdebe65b45de05561dc0a2aed6c6fbcb9e185d0929ecd4a81537701904f4a727e05ef0a9c684730157a67aa28a3b5639ed884ba73671cd26ab52923e34f1a203284d02de54405bc2c4a7eaba0fb1e51c15f24e5444d9b889a72a21a9740cb8bc01ec50f031f9ac258088de53e6b676cc4962c4c50fc5984517f81046ac2d35cc15f0741cddd115cb23e574f66831ef88a7c41d194af0fd181f0cc03757cddaf4fd81f92279025b0e6d6075e3fc8e2973f1df4c786682d70cf37df90908e5ec1a5ab6e425e8aa4ea1391aed1446f784ccadff16910f7279f065ebe3b13e2ce1af58626fe83f989d9c01bccb15f888c106fb48e700e58060a09227b92a2db39e05e3444f3ef462584439e788e270fa21c7298017a2258b2f782403addb0b6c0e4dd083bdf0c6f2b921fbb006b16e0f8ef790d732a2b43072ddf8b74f65c606a800132824f252b6bff2d73c1c5afc24181f96f4130d0a0a0d82b7093b07477233b59b1e3dc20b2a38970d826e5364000297fd1a746213c50918c3e3e33e73a9dcc3976217b939e4e4e28422cebcf3abe4259f3683c15f24f63c276e01ad5499d613ef6308ed7ac06053f315126cccf86cf4ca642ef7b85e1df018f574e739a086b6060a9ef11cc5ce3ba4e73cec24c014338f61217470c27f502db6282005ec299868c3ccbc304bf365f715108243546a6a5b04cf42709ce30c5ac46beaed832eaee414e147af3e6a048ab5ccf0821acfddb6fe22eba4d849f48dc943c7c0310c65bbe8f48dd72ab13c34c14a4ce05a5eb2df10e8a896979c0c9929efc2b00382f8b50066315246bda09053d9bbfb50882179cac192ef816a640d7e7e475e1a4ab627cf63aa0932faa84cd4912bf178f0bd76e525462647851ab83730b829653ad833fa9fb80d29a68247e6d1613f3ea6144a35b3e012c4ccd4d0c26ce21ff80c55ed290092330d0f66ffeb9970b29abc1f72e2e47cb9811732d589db03827e28b4e06bc0d4aaa22649c82728ae45a6e4c4856996f361ef0c6372321f9dd357895bfca3babec4509a1562bbc3bc2d18322c0d0d11a774f12ed3cc452cf89e2b53b081a625acd70ecef95d81b21885d65515584196608676269cbc4fc74606afe719bb9d3a64453519b6cd68c3dc9a524edb5e827cadf79bc83c493def2e32fbe665ef658db0ec28fbf49a9fabb980a300869432a0ff5542cb18918e25201b6f7222554301b9e440192a08f25799d851b376cdb1a813f9400fcf547c9571c0034134ebaa7bc93d045805632d9fed318592721629f8aeeefaeba9d9d3d27672eccea4f723052848580a3e6b3c74a1a411d841e9d102308bec0efcdcc906f862492d3be20d27d78ce26f8f70cb8a427b3f34e343e00dcc86bc998ba0f1166d27d7da318d60b7f5a004b54760d4198c259e3104e5cb8d92d9f0e9306647923c4b880f03f90ddb0cfd1260b891af2138713226b2cd5a2ac969f7f73cefe55d6d6019d1147bcd56bceefc263bb36dff4ddfa66fc6b7ddfb9eb3d773cd7e1fb4f56136c6b8785a20633941326e56261f86d948d4b5f36f60a88ad3c0487d59214122e2227bfb1b0c439ea75a24d201bedbf533a4a2f4774c944e6beecb05a2e7a1bcaa1352b3005ad3a10ce9583a45a68328120a47e0441cb9c886eed354cbbdb69dd40a9a18e8c25242c15b28c39d795b176cf76c0692d62f42743745b90528e96d23c8cc8d0c9dba25a1c09fdc348a7a986430248e5a3f63459b0f93741832047e8b60b960881ec36b2c04ff048f8fce2eb42646a8f4b3f483e852ff2d383a17844ca7a943d24fa6f68c02fe40dcc0a4d294edc61d3737e21d1ba86111909b77e311805e976d437f64a21cb68047d58322561d55f870d35165069d43e0529d55749a8a102a2a76eeddced6bcebd7567a812dd6a26506dc7bc41f150a10bd725e94f8ab598c3cc9eb61b771c9d50439d4e71ee2f5a19c94d53f27081195970492e37aeee369740d69f902157b6ece28d6be75e4337405474fb8264b1ac823055d9c97321bd29ada3d2b05672399340f2ee7799071efdbb4bf7bf73a6c3f2a484f9f1a71752d2ea6038faa08892565793fcad109b18c2f22c01470375921067bc564748bd5eb6147d786ec84fa3b3d3c042fc45e282bcad64766ba5af3a1d48f082fef6e5246379356199bd96fefdf7a7e707cf3eff7df4fccfcf1f3ebc3dfefbf7b71f0e0fdefefdf2c387377fffedaab11372776da1eda91647d582b356b65ab592f6e272369bce970b3850a9f63ab1d15427ed6ac28fb12145f1175bd1a572934c27cfa6e371b584163e4da74b5051caa4a80ff7845ba8528cbbaa081309b85ec76fab1f35ae1299a4983a8f1aa5f7ba493ffd97d46ce20cdd021812e70b2a709186ec86a4e252652512784920a3c0a55c22441d7d24150d7196852b9b876184a1b49a64ec9a7462d94e6edd7230cb1351e620a243897b328722273ac5ae63219d8b72decd4c5c1bc15a76c6722185dfb6832914f8560043154fec14edfbba1a287527a851d21e976640942ccaaeec71b2872f11a0ea84b667f3e9720aca1e39cc618bae562ddaae1602624a69d52d85f08999604db20ad55a4efe965e37ea3850fed44e26c3bba01431b104bffbae1be87655d93353b6a7f6851dc76bb57095d4ee0e0deaf43025c7328715e4571db21b4c61480151dde2366affc2c2222101d2706aa7fcb6ac8956a20842b1bdb4a6280a538f396d0877d2c169cd369ad69312a6be93328a9bb16f9a1d866b803f3557e3d44df817a77727fc8bd3bb13fec5e9e6847f60f77504c2b431e15fd29cf0cf3fbee1fec449f9976c4cf997d829ff629337cda02ba67289a1e26f9cc22a23f23735a1eb7d29d414e39bbb42abdd89336190dc3447607240c2faae01bb6c4a664d51411e280f520f937649d5bef9b55040485cf6e1524622f7d61b1a15e471cc56e49103c4a18b9db406df748b94cf96ee0e4eb9d4b27a8cb0332bc837cee44b7d55cb7629f558075e7bbba23da41e3ea05ebb0777b576e8b5b66f5ab3db38dcd086f2bed8a049b657269df1cea889a107579c6cfd49d7033bbfe6c5fb6ed9775ed6f5b0d39f41e19e5b7804850fe3cc71a515f79ef37b3b3b1bb47ddddd8e5403d01e8dd47768f55fc2a9544822c5ae584895ea33ab1b067213ad634cd285d96180fa8f30c519d89e6b871503f2661c2234b01e3cfc501a037ff4bc35d1feb4a0f98ecb704f8bb29aef7be6323a3b974b7c82eadf973aaaf05b47d1125157f182e5cafd4cb50cddaec633414b6834a26db760dd18ee4487ea0bb4cc24c514c7295da24b5a7d50a2950923b5051ed533ebe98de111ce5d135021fae3e1023852955c4b89ee1cff619e5508cb52f0ab875738c5761885919dace8015d6859a6b50c558f7bd0d5dde80623866d2ab7c3321c01f760e0ca13f55662da88bb23c7bd23ede24f45a81fb126d275f5a3a6f106481f89fed7f045c2ee9cfd3fecbdfd7edb36d2307a2b709ffe2c2aa6653be966bb52553f69e2b4decdd7da69bb5ddb6b431424b1a64895a462abb12fe85cc7b9b1f3c30c3e062024cb499aa7cf7bdefc118bc0e06b30180c0683996f073737f0d8bb1d7a3532e80dd67ee73158ff9d87e33345079cfbb669d665fb4eb13ea02f851a38ded5c170bfed279fe279cce0db500133300f5f5b7bed588e2458db0adf4a036a3ef1d4a3a4900f40eb14b2896087830c2e2d13d6b60eda59c5086d2dc6fd67e34ea5de46f746fd1fc6d12816f1b8dde372e34b30024ee0eaaf37e8c23d7612256d746fb9a723f6341e51ed2a73ad493f216f9e27ae99045a441365b6b8ae7bfad1848d35f92242bd55bbfdde2de205c57ba984cb97a21c0b8cc4f2d4adf4f65656107a0f3c69f7fc214094a5a699d2a50af387b7bc971030e8f9284ae2cb784234a1497f820ab8a4ff6464bdc3ab51ee9b5ffda43bf05968d21bf4afe4ac8ce5d6d47003cd6f7b436b477d9a0f51061e52671f03ebf17808f64a42ee7387a0e832f60f234b84c9a53ef0e907cde928dad0aec9a949a3117c9ac1fff4a6dc8800e885a96d0010b3c1e1a57a19dd382d58c594d9d7adaf8bcd4db0432b17c409aaf9769e4d0bd5806aa8073684d627c4e6a6caa0ab6a74691d6463e3c9e6e606ac4abdb129ef4bf24c6d76f158483904bd48e07fe814f2afe82372ff5177b7dd1b12777e24d64e7fd89b8fe1a2f9e4f5f0ac3fb40fcd51993dd8dcfc7b12f1f86f60a167c2bff02ef75e8fe1fe799eaa45725414757f783bbab4277b65fce06882808f344bdaa1b46f7b4e1d73d413f51ba1fb029580c3452754cce0523f3c853fa492010c1f4d566f7b644ec697365e1c2a25f636282a3637ffe67deff900d1d74ec2cdcde9170c38ca368c657b56a479bdadd5c20cbc8473fb428c32f189a2aac1cd4d34e8f37d7f5afc4722fafd327029941807fd8d686380c318904e6d0c3a135e3da9eb321dcc6b119d7e31e435df868e9645514b491e0d7e06d643504fef24d040afcd9d403fc4044a5c2175efc683fdf78a96bb1bbbb75d6430ce32482fed49561bb7048382c9de9893eec89dfde5675e55e7442e84261d2597d1b8dd9b005f8b78fbf67670190de2710ccecce0127d4967fa934b0cb672ffae5caeeacaa5edcaab5f696c69da31e3ac0cca587af9f5d2b55a7cf40d2fc74020957a18418c804cd6c9a3b37dfa81c608d8c27b7d10ed563cbe140b15b4546d0ef2c0b7358ccde987c7ee9966e01f5892dbdbd3fc2a719882132e43bf219f8c23102b8cbf70e5abbba718eded6defdaad8686dc8800fa513b06e847edf66d6fb146a3e07cd7351a0db47b9affc81b56a2daa22d14b547993425108a08a9c3862b4a9c704503b4de4ffabc97386f6a1227c41e78d9fa6d2eca05be992aca275916a9464f6433fdd32fb6fe7efcfa5507353be96811c1640dda5badb31338809b5e9cb5f009cda0bfdb1b7c93e8273483ad2d63427d323803491f77ca6167549453f4045194532d13fe73180d9165f8e175fe2605b7c540663f1dc085d0ededad13a5c88d62c4bd40a75e14231a7e68b0b9f9832cb0b191d8d0408378634f4ed597bcfff2d7de69ce07de84515e0396ff5f515779c938fadbd73127ae0b7411ea416fe47ad0eb0d06744d473f6f467b37c4ddfbe666f4e2d7a81d3ffb3592f498b85d72bc003e5cdf6f9fbd7fbabca4f53c5c6fe53fa42bffe19989c4bd31be8c066ddfc26977d7fa6f50ac46d92881057576d97f7ff04e56d53d7995c46f86f13f87f1318f5ff3f85fc398aebe5fa58cf1f3b07d1bffc2e37ff3381dc6d3247ef66bfc5ec923dd8dbddb33b9d4225a4cfbaa18a5f910ce0edf2d7e28aafa500551d45dfbe5d7288fdedfc63c7e5fbc1365990ec50f4571796c4c1d639d8c06409054895a7b76424d44a9d2938918ce33150d1bd3123f3ac69118759787ce90dda5fdfc6e019defd2a1f1fe248978bbe1e207d82c51f8dfc64b06efd4a6b540fb8388b7d1fab8d18bea7921fb5d8a6ae28e349c5814b541948270f034167ae4383894addab7ede8fdb21ed7493c98cb2aa444d2dd8ddf89b2929bc4e9177b8f3b7b8f3abba75fc4a7398a91a27cc3934b3e16aff854744fbf40816a584c4fbfb86df7c435dc7c76cecf8f0f9e1e1dbc3d3f7cf5f6e0e8d59317c7e7cf5e9fbf7afdf6fcc7e383f3d747e7bfbcfef1fce7c3172fcebf3b387f7e7874f0ac9f5d9ad2f8dcf24d51d63ceb5fda74d9ff67af5f82fceced214a09ea1c65d4e1ceca693a97f73401878ec1e6b20acd1e96ebf09560ed1f8ebffebaed9f361f3efe3a7e0dfae6cea55854f0c0a2770ba4066f779652995584f64e7383866c5e4d8e1779e231ae3b9f59ed7d6d1db334bd9ca2a31887d9b65d86a7389dee87d6f9f95bf05a6c2b35478241bcb12b3997a9b7715ef9d06af7a05a8b38758831779a4fea10296dc0d1c36be42bd2060f89a1fb912b25ea8ea8de6cecd1534fb006f5348c1e88da10716f63cfe2c618b10c80a70d911b5672776d8038cbc825153512dcaae28fd8a33cfcaa9671068fe783ba14e230af0b3b487ffb37284fc2f36ad7f6cd8d5996c185eb3fc9fbdaa10a6c6e632f1e124a538cae4f185def34ff22fea235af0493125b52b77aa7f9699e8e58342b8b44545547e4ef3aaf5e3f3b383f78f513ebf7fbac352b8be11c86d56ab3f7a73963d34232eb8e6a88f559297e9ba7a5885a9d9de4d76a47b3f3b263cb76a669def9b56ab57ba7f92d03edd23deb1a8a77222b66f08e5a5704e3d979f080fd779626e02f11fd32bedbedecfdadb37b9ab3076c456f643ec03c2d668b321d4f6a16256df69c2762501497313bcc930ee3f990a575c5f8689466a9a4c88e29f8769256ac2ae6652258520c054b2ba6ba3264f31c1c2d4e047b79f85627b35131971582e346a8e3c5e1d38357c7076c9466423b74948763364c4b10bb17ac18b19ab424290ffab023a7cf994f903621cae7659ce15ba325a642e829c17d73684389bd1455c5c76077998b0ca5a2990a6f857f1c7d8935939bb5b52d10ef37d64e5e5c45edde2cdad88d79bb87f5296b9c41fb3dd27825eab7785913d5f16e3b1ef46e6fe379ff19af4507cb87aaa59d510bc396d89edff6460e2bd49ddd27ad8d62d9ab6e34ebf3d8eb44fb569ec01d2ef35b9fc0607cba09ed4492095eeafcdfdab7bdcb661725f3cb9a581a1565229e977c2a8e9c2da8fd1e0d2395eb169cc0ce4c94f27c0401beaf75a21c7b7c9a2ff4b7ed6bfcbb4ea33decf97462292129f2aac8d441e689292cdbcb9ee4e914cedcd0db5e98945409b9b04555bb45363755f51d01acedf40b585183b2b8aa44c98685a8f256cd94d5190bd6d1612ff9a560d5bc14ac9ef09a2d8a39f83f659ccd8a6c314ab34cae2bf47baaaaae3a6c52d7b3aabbb3331a74a66207653d0d5f9d7ed15e329c27f7ec7308537f54976ffddbffd35c4fc2b2f763577289b4d75c5257b89e6eadd7e1effad7f75b950a7cfb3b0c91f8b4bfb1173f5351d0fadb7bf1f3fe5fe2effbbba1e5c2c2fce4dbfef77219d165d2ecccb235c5dbef77bfe537377b0ffff20ddff727d62dc56a7e292a98a22aadd377925bd76c20ea2b2172b60b1bc5dec3bfc44c164bf3311bc992528cacb4bfde7ac27309c346b34aee157951b379ae4845aebb76f7797ff71bbe0fae6546595194d1dec1a31ddeeefe054d437fc0506c0e7b8e0ffb3f74640d0f7bf877af53e45304e95b25a8c3a79fb55733e9effb7ceb3988d0cf905def1f76664555ab969537a888cc5fdbe7e48102c0cd61f797057daefcaccf7b4f6f6e64a5bb71a074800d1ff4175432e5517838eddb2687fe3d3a68f724cd912b9cbf7bf799a8a4e2e85b461e678c6f37a5b3dadefbf6db6ff762d1e727c333c716506c6eee7ef30f0c9f2633fb83989f24677d1127fd21da3c991b371b09425d659dec9e69f9ce0a86ea04e54477201a0b598676808c6356ccd09b5ea262d29eec9ef513351a1cc92e444556031e7e23d410a7fd870fa2e1d65e7b7b2fcefbfc647a16bfeb4fb7f6e2b2cf4fdeb90de69b9bbbdffe23cae3a4dd368925269671dede8f000f652c4b4208a677ed2ea6e5b1ac1ad2a6d664ac5949a27049ebf070698c5382be4bfee1bdf72fcafa301f8aebed81fdedd839ec275dde4987db834e3a048ef5aa7f7216bf96ffbde9efc5ff44d675d47f141f439050f9df8ffd8d3d7adff3939c258dea41ff45f4da3a4b76221edbabcff64b09a411314037547041d8e79017930e371c07c47f8f5e197f17a8e2c46609a9fd2c3b053dfd49798ad978dbb6fce145f4aadd7e2b17e228fa9713b9cee9fee6e638fa3926fddbe66ea08f7f21c2255e7a3f6e6e46b2c57812b5dbbde3fe860ee871048ce627b9c2249afe09adeb36feb9b9196d44fff486f8eda07d73c33737372e655d7a3dfed32090bcdc18b6dfdb743c891ef5ffd99929431d8c20a8fc2237daf9a60f6e1f9670c9255730fba43dd1fd671fd1b9b9f9520eeb27f39e1a3e71b0c45df23fdbb8f0b4d706f9953b58cf11eb39c1faa0dd9b4a8eaa9f1a18dd8621d00408d4999b5f2409786697fafddcf65e4f3d99d726c97fd9f59e4792d001ee6bbfbd83affc7bf3bf1c3cc20dffdffdacb93b1f0e3361eca6fe12c89f4ec5501ebd0cd05e13e8457165b2bf6a66bf92427266201e3521de94853ce1291f05cdfc1f2b517e9715c925d83aab7a1e06741320f13d6d846de610279dd2614050d13edc0fae453297c5e896f5f6e6e6f8e62632cb32aca1b05ad23794c40302d551a00363513f87eb5d6ae6d62c0a441b10fac475ed8c5891d791212f4555ca900659ca23cf85d8a07f74ab39c3517fe0de5458bddd513fb90df461c6e755187f016075a478c3d3bceeff3b903fcf7f4eeb89996f57fc682c1e77746a59a865e38e91f71f9131723ac641638c8159d67a8d009dd1dbd9258c6b899970622c544c904e707fc3173dd13ffd229f4f07a2f43c54ec7e23f6875ba23bec25411013de79dffcea4acea36d8ce4ef58f46571b195f478ff7d3aecbed9da8af552e90e62875777796c185f57c49efd7c129b7db1bbbd77db13df0ef723b2d3f7e5eef83ae6e66137b2660ebf5eb7e516b53f89dadd1fe522936c566c0fdb6d29a8903a12d861793b6eacc87650ad6d676d52ccb3e12fa9c886cdcbf9257305fbb3de7b5f990606b837da5dd2eec9fa97e1369b9bae0821bfbd7dcedff86e6e2ea3d00abf2af92cc8db54840563a1e58e2eb4943b7c36cb16108e3e36da578ff46f7b4ac9b701cab264c2cbfad76a7b96cdc769be5dd5a5e05379d67ab7d7f95a69fcf42939e7e3f4ba334eebc97cd0498b9d6565a15094b4d9c3ddbdbfb12797e924bd2cd83fe615973540ee91c8045faad353aa38731061d1382b063c8bd98883020f14a77ac5685567bfcf5ab8025b6c7393a96c5488b20d996bf4312db6dfd494aaba23a33185f1816e34b66ad46921b1da6ab759d774016bc51ee83e431f30a3c3a743b6af3ea2135b6fcc7475676468ddd35c8d97f599fa7173c32a918d62f5dd792aab383693653b4ff30d3436d206152f5207b3a855a00a86bd670d7d3640b03ec3bf9b9bf8a333e1d5ebabfc4d59cc44592fa29662c4ad36db4788139374c6ba98d43bcdb121d6572dcafaf0d7ca0a11c4ad11d3a08b602c24b299282bddd18efa36f95671041a08d667e4a42b09eab44e472c72b46c3edd28b8d35a2b70966befd8cd0d829ed60aea4a0c2ed3fae95ab0d3e2f7f5008b35ebabee8033a8488766908181522d6c3a94148560b7f0eb561218d019a2dc50e80f3017ac0f35e7a735f04e5404e1b5b4acb3ec5a26a74c6291504d87e4fc6ca8acce088b83b871f88c741a74f6a46eb93cbc89b6638eec184eeb70d5acaf698b2a5d51f108765fca49b2d3a88f9a3fa8fa5b407bacb15accd640aac1014194ed4bb8933d6c01a76029e6bd2516ecbe2e65b082de0057b46b8629fb70ebaff72ff7022b5eadf777bcfac1700503dfc11c0556253c13c7a27c9726c2d44413159c44e6b14c667da70c38c196df4f8bbcaacbb9e4c3514b0a662d5c08770153f204db76c4e7ce0e7b5e944c8a0557bc1c5610ac8cd7e920cdd27a41b9156e3cd8a29e0b4c67ad52f00c72f4fa342b5a3fced1dda87cfe8b7dd96f0282259a64c0862ff6f4bca84e3f553b1c7bd8f96be7da8cc11f0248d4c8d09f0cf9ac361c420efe0d6870d9a82ca6b4beaf3bbbdb65d2d9638ffef2f0af8f8490d0335e5682d0399a9a31b8c6a91de6a1fd264b00441b9ada5189018b39b90e7381a26af3f19ad2d4ca94a289451b08c152653f031209eec6abeb7416b8993474e79e563ff12c1d4672763005fe7f3d8adaac8bf62c9a1beb5959139b1df6b21842fc3c39a4f5e6b14334207521974955f3e92c02ba8f199837aac182586e661a003ae73ae1e6c623869e2e52cc64e59529a2bee1f46380800864b53a17134cbe9e560d7873632031cb40eae9809e2bc647884737e4487b84a7626184a273798b35edecb0d779b640004923698df7169cd51a778c67a5e0c385d732d60d22091e0b816c0324f60a72db728c1b69f53ccdd35aa8ae343aba9cea3579eeeb3943947a34afa1ba212867e4722476087003e189535be83bc9c5d60b3e1059c57809b7f93c6769aee92f13badf3c1fb2bc601788f60b36e1151b0891eb108ec38eaaeded44b0b99cbf29d82754759a653201ce2043312b45c2e54ab9c08a2f1491c0729095a7f9b8a307b3a14821cc3b96d3064245b832cccebab3631b4de4a99629ac54c554d41329e7035b813b2f422cb124a2aa883545d54bd8dd27a21b3b8ca5f34df76b9775a191c97d3812612ed84e80adc8a1dadd3dad5ecdb3ec75f9a3dc9d14927d42a33cf25e5cc6ac9a26a3c35263511f49ca826721baf59e4bfefd25e4dfa07e594477a32ce6f9b0414a5b2e1345a5c4eb915ea36ee1de1db362305d8aaac8de89d7505a8fef522c081bd782c5eb59dd4499ce346833ba01071c0fc2865f831aa1ea18d81ee9a79d5edceaca67b85544b41f2797627116bb8d415a5b8f10240e5ef34ad45acef98758c81e9dc8c65af0cce73b9e5c8e01634f8bac285b31c92acaa1289724ff9c0eeb094d3ee2c3745e392905bea9a069c7f5221334e1873450f287e29d2857f40cf3c3dd23798d3e429ed3dc20d8c8a05135a61c5fa6b399183a69b491c9f27e4fc25d9e847b3b697474e2e1a9743e34a64ff3b39e47dc70387ac66b8ea44da83a51aa0e429f8686d3a1c9488726753847151f98da05564d4b03e06900cb888c2f961790b904baaeb3a5b0759d114850d42f85855c025de4f67c1c2e612048a929bf366898f26b9b9e4a14581b31b6cda2b47ac55f45759d4941d5206a4b8dbf2b47462a16358f6171c64c050e62a95ccca09e4a8a795ec70c5eae710c97432433d351c31f4d4a0493e84b6047f0028e15d9105a94a9c88ce457477108100c0f7832b17a2295136b2602da6bd3a81c823c41434d63513f43a097a2e69153a067b7684955fd3e8cbe73fde43aad0e9fc9ed97262f3099ecc0b232d6d79d80fe9ae334e24ee56a03042d63609b40098e266467871d8e40048299656985c4348cd9ac14e0020f72dfa515485dd001e01f1551a714258b52d667bb3d96b26fd42cf6d8d656ea34a684a7486d5d63b4a57b5e94809c28f5b1fb8d24bab657c5698dd73f34edd67e909f4041529c675beca1d5ca18a3591f6ed7c258b499b101d4eaf1dd73747db976fce1f983bba57d52caa4798ec3da569da2536c979e3fcfff1062067399f1aa66f55541279315f3ba4a8738d9103d0b8e2675c138f8928274719d56b5144707e2f754942c9997ef0455a261c7309a17bf8e30619b3d8cd96e3b845ca0d46a96a58988e87a273aa2e69edd5c9c5640b178d04bc4d36d00e8e626a352e393b2e40b5d00c5066f5268deeafed209b3a9b635213b4e976f06879cd8d3613486d3ec6f433a37d2e187f4901c1a64af4e76cff0d8a0ee553ccdb0e5c55a6fe3aca5ae62de34037ad1c5ce90aef43cf2c6f383959b695ba613846323faf48829b40a38e7ec1c1d820b458658177a1d8b54fd8af3e12358569773617ae58acb555dcc24afa76ad78668a10555b37b3684e492140755ac86e8b83964e373332c6632c14b78f0f08e673e90c2b552bbae68633990aedaa8993c74f0b2fe04f848552b4be593924a277056088e45b6206a838ee65d00580489abc3fbb6275bf46549b2b52fc31aaa3f487bf2308e0c9ba4d235bd82c07a166639d6ddcb0283d8762f84358286d4ceb3393ed525cfab54e2459d9ca097d75ddd5bb91ebbeca475dd8a592b29f2ba2cb237727379538a776931affee567bc12d7f5bf5a67b12d5f891aabd089755164753ab3f5f252c832a7faf6a35e343ab058d6815f421df825d48145a8030bd3815f5407b49ed5aa410d8e22e5a9058ecf558c3919afe94ad082878e6a788e093737ecfdad553ca4e28ac2c0b70b322d8622a33098e002a5314b33912b0ab6221b26b33ef4538b8d20e600b823e4803f04b150c027e919217ae87b68bb75c89997b88bb2edbe4589abf10675492aae966ddd8000b992a036aa9e4ac5d53a95037696d58ea893d5cbea48ed90b1bafa2643843095f73a6cdecd1dfff88367f8c0ab568239e7a86f938f21a2df1a2895df39c70c03971757ce81d164e8c31f2e188c671aabe3a122ed2af6e818280f7b5afd5094e9ef455ef32cb244674e450875950ef154549fd697c8c65cbed6c193ad7b4af02a9988743ca957d6b2b0d76e3810d657e3630f582451b06d37d789e0c336db3133db189bd548269755a714ef4449ce71a6816dfce51d798f27e9a8663ccb50865788649918d570a753946c3e93bf24bc27a906cec64454fd931c8acd9014041c6b6e6ed8c9592f708eb30c4f97bb83e9c12ed0e0eb92fb21a9765075a1e2ef868e39c07484c5e1b2aa290ca91bbe42d5bbf2329d6dbd56c3932cfbe3aed6cd4d77f99eec9ead358f7ea1cef9279d59821b35228516f3e5a285de3e184d95bd7004bbbb93bdb38e62b0b80cd12a93140185965364d714b1b56efbcbd559ce58bba37d46bdf5d3221fa5632d3de1032879ca680d8aba2ea6a8c41ca6157a7ac2ac2ccd05575ad24131cf875597b524a231495d01545df61e4522d90b2315e15555978d78568998edece02fd6ef33ce66bcae459933bcf8c33b99495dcfba3b3b7827fd6bd5498ae9ceb048aa9dffda51f7603b08be8d97563b92b8384be6555d4c993694c4e7784991bf13655de1bb5f6599085a0575e78d7dc48a681f9f1dbc393a78fae4edc133db5d7944637820adb4dd9afa8e6dbbd0994f322eecdb3c4feb30f6e67531e5759ac826b58f127695d6137625c4a5ec612eb7b385e065cc449d74d4d141ce20ad312f7211dfb392615acd32be78be02716aed55c5cf425c0ef98242d99684b85472e8902fd836ab845885a9b1a8b72b51efa455b17d85f52a3c4dd3fc4740556b9a66595a89a4c8f176405f72aa1550c9f997586d552c294ae56a5b4e934cc411b181c88a2b0727733943f79d58852639b7cea43ae8abba44cab37defb2d6a43b9d76abaa737c7cccd4620331d6cba779d3349fd742e5d18c49312f65f2139b0493d27af9f2257b66132556e59acf489d920614e42fbffcf28bcdf96dcecb5aaeeed6c93fcffec9b6bd6c49355dd68244c521637b72d20c8bf08de4d22243d2f7f1a53cfa20dd602abe9cefb296ccd62d4df9af4549b028720874617527444036665c478267d4b6cafcd661eff18a374feb9467e9efd4cec73990005fae276965767b5b93f54d68eb51c6d25311336b2b4d2fe3efb0bed2fbb995ca5c532c38d54fefbce424db9c8a816311a5f6dd0e390cd02f73b0cb979fffa7da0443ad40d470ad85c3ba711299bac790ff6144b1d0fce2f896ce2d452caa68e841684aaec948739e156b27686669b43d9e11d88a5a4226b0a69a7889cdaa3a4b4e89e687e86f7de1c33b5e91d17f040e352d0de669367c8bcc627d7ab266169624ee4d4d9f8394ecf0d62227381b5b838886f588be3efdb528a1d2069c6c08b209f8d243fe3470c25f75c69ffa077c47e51c0677d49daa00ca9da4df9840db27422b81a3c9941af4a155c391b3abb9587e8bec4763578ae60e4aaf1b00ea629ae0fc00f7224976ce1474d426e556e8323b5c4df48840efbc9ba7005b0fdcd1b03e3b91405b1addb1cc3aeb51ba492eed227051cbfa8e9d2d05f050ad0f081e944131ecdf2a93e292f5d9f69ed8fb4b230bf04072c29803adc7dcee08ca791976d928d680a2a669de8aede21b8b3ac439c8bab433ada51514bcea2eb9bacb8b62a616a326d5557de0d7f7ec839ac64e25cfd4e4bdc0da1d52684d2e2b47beb917ab417915af63a6822c01928654afa506459d0670aa8fc176753428cd59cd4bc82cb0921ba4e6ac628fd6d4820e539b5acc77111c5dd27678784c97cbed3d0ab4d3348fd9aca8ba6cf736663a915fabc4bddbb39eb71f9a956876b9511a24900fdade42733f4aeb4f238afec172a8d30490aa3a3dc90608a9e8a4e9525d2cccd58c0f3108c248d2cba35e330bcc28fdbc09b8af7cc94bd9fb28f80a6658f22bfae8458efb4929f89d53a7f5f153a28cff9432eefa3310a21339ac5582c8b2798391e1db1a35b69a6c8ea77592a533891ecc74a78cedebba095bccc4a8ee3283d68efc2677fc7531ebb25d92008ee06801482000a8f252104aab6e782cebb246dbbb7e73b6eeba982d691a75fecb9a85c298629aa6f3ff344b6760642ea7c11a4a61bef3d2a8a3116adfb0e9143d551f32bd6e1bf3dc6fc515cd87a2aacb62b1fe59f9cf73de5defb445a4338da1e025b97ffedd7920ff670fd87fcfcaf41daf057e823ec8b7d522d883f06e4b2e3896b11363a0af3683739be04129d115f3cc0dcb096dedec04ba408546632d6e2667990d3c6029f4de48cf9673b3e3b60bc96ee3cdc650dc0ad922a9e1a1e9be246ce79940c80caf5182a006cd7c546f829720ee5e3e35d6f4b781b778a518a7552d4a588a6f173311d9e772b1ab978a5dbdbd7de1aab1f0709d4788f054d194b0cf10d513eb8ed68c76d4bbedc6e2d1f705fab0d1657bbbbbbbc80ee170a279e348fb58ebb247bb4acb870ea2a104a41813597c320669a0fca09abebacec83b3ff3a0ec01baeb448fb2c00e71f3bc146226fb0929e8338571fde4980de6e8c6af1415687139c49c2872f4dbf9df335ef2297b8faafc5bb9698dd231db261528aea2fc0398fb7565b68505c805bbbb2ac1429a9874e15b57d9c4e6a6fad5a1f9fe8d770c16934fe0aa2bd6892f4892cc7e59cc2b01fed4c9ed2dadd5bed03437e453e15ca29fd6b61dccb5df3da7ec0b0a67eed91bd092f70ce6a39128c5f008bced92239b5e3548816b2b81568d2cd81e3d7cba00f0d297f5ed9b1c007070b00c0174b016052f1c68ba75294a7276216bfa8c249c56cc80c540d02cadd93caf53bc39372a99b4825b095d0f22d0d0aa6632262160b06af21a769e26a7a38452b81cf5ac3ca73a5c4fe459465bf6402acae7d3e35acc2abaa074242199d1660fd8dee3cee3c7b4aedbd506a33ef70ee0125e365a7c4e5d3f9d3ccbac29022f05e368620c2e4b98be16adc801e0a30cf4551dabac103aca302c136587dc3bef05d4adced1c83373a1b7d72a477129b9f01a35b8ac0357bde1fa9d2663518dba19ee014bc824e5eddf07f4eec9f593bc6752b6c599e335337b08e1b4524a054257cf2aa8119bdda350a870df71595f0372c7d0304bc5c48e81754b3fb30a51b991b11d16193b73532466bbf086f1d1aeb52acaf1fce322550e38675b5ed53737ea0dc06a33257fca56cd976297d0896fc026c04c96c67b91670b76351139d9efd28aa53912949d74758e348b8a9c2d0d11fa36714acc2bb97b1370171961b17529498ae04decf6d5b07d2c7f8b58d8c799e92a3b094b8f8eff9037401f5afc49875d78a48c79fa7279204645290e73475f43c9f44e420da458e34975920699cd996d938465ad54a7cf06065b2fa4b899e3db77533c986dfa2fbc190121a6a81c39722cea23917149256f0a6d9ef40e8c4ec9e3a7e6fc38d44b25f0c54c74590b3a362dde891639344385eacc4c927368bdcbb0599b7edd95bded5c93a405262d9c63b673dc460c76f870e8a025c21e0d8babbc1507b0ea9e9497159fcf5614d6a7443eaa45b99292e87b01d65712a8236e2084948fea7f17c594cc214a0a32515570a4812267be1cad1652f78ffef56d93be21455d2e394c9690241c832a0a04fa554c76466121a9fdae49ec5c3fb916e01d24e13501ee2c647abbb93f0388571d6909ca5ac582398e8103ac0080ebf4c408214fb2acb862dffdbfff0fbe4fc21d9dd5051b08e785130c9d96b5b8b05681692e3a099f7d078f9ddee03329579e5d221cb98751236f531a0bcfa779b7bd2ee32253abdf803a57323b3b2c1d81b0855304a2967ee057d5c54cdf4c192fdb4ae4b24c86d881621de4829a1a363bd3497d0b38e76967cab0cb9b94a5798fbcc3afcb3b5030260e3fe695686a05a8f9a1fff2713d6593555e7ddcddbea967d9e5be2f5e85654e8f272851f65940ed0da7b6cad3548119a74cefc8dfbefe5ba982d55ea6532894d5179b9efb6a594f07bc420dbb5cf77bdba34737622e0a770b35a782baf6aaf4bc280f870e747b1d12d4430255b61ebc49e835c04a7533e1a9b49b8215b5675db3df8b0fe9b75cc17d570bdeec35a2da81c324b7df9ec68aa8b39124eaeba6427b258f5b419f763bf51aa5fa6dddac677c02b40f7b7893ea5da9690de669660c4a920dc60a41aecae098bf13cc646283e023a614f34aac216f09729423fea282ed17f3da6b5ebd5ff73aa001d495f01d07c83bf6a7e615c2bd64e97564e68f11927bf7bb2f70593895133118eec7489acb6b58256c7ebefd15774f359fd1b20df236e45bef51d09ba6e7bdc7f303fb7b514cd96ee7af9d5df628d9fbfaaf83bf629d32fdd5b1a950cabbee87b567bc7f03587947fe79aed026292e98acdb5199339e078a38a91fd333eb7784e763f1925fbf48a7692dca4802bfe1395a5c5531cbc5d54b7e4d5c1ab900481652ac963b8997a7eb669b9b7a7637cc1c7ab7414b8a9e2c6beeacedac79d3547f592796d744b6741c2dfbd6d4474856e5f54d9ea7afb26e9c00708953a9fbcf4d9aaf9a9b34ff98b949f30f9e9b34bfdfdc80a2e4de35797393e6ec1b539f3737d080ce5b353790ebbe8594ed3bac4a3f3f9419314b445e8b12bf5e3b87a0cfe974ca33bdb4b3b5c2f9544717f01c5099f4e633cc35eb95d08d4a6522d56e5e11cda8e9fa03163d64db804cc783cf1b5126a01fca80de87cf96bd385c62c163ab607d0d8a42f1b69ac1ce759bedf859f825656ab5e538c7a850a54a6635b52e48ad260f3feb62663d3a9835cabe617bf611a83b5ac260e8baa78bfe993377de6bd025b5b95c64456da7e4f1854329ac1f9a98ba491572aee1ef16995539eba6a66dbfa6a6f78a19cf830b7228b29ac732fb7f7821fe21abc5435f64bcf781e3bee745f926bd16590448681b226be4efb6e9752840b36fd92ef1ec1798339fea66ee4ef3ccf6d6a5b8159559a25b51999af9905044df983458745856a2457c1aea391416d672e2a894e15178b37edc79bcd479304ee5ef853dd276befc5d8b91e745998ed39c670a155df6fe562b98917e555f4c599362a8c42877a9aeb7d7a8e149ae02eb06dd8c5ba2bd8f80ef2db1a05b4a6795e942deb0d564767c749ce857fd6746b1daf1407aeebb65af370dedad57da53c97aa529a3f30a5ae59e6750bfa422b50896d7424cf6439abbd3a6931bbf93bd7560fd6682672cf8a90c2bc035ba525798ded88bfb5df76cd6a35e8a28f13629cebb9968d2a9d1d9e8e5688eb3cbee34a07dca3abc056d808fe822ca9d83a373cbe69dd909b4de06b46d56e45d01221e9588e9e541d62d30640c631c8845fc7077efd13658ad48f1c78d4cfce78d424cde4a26e004eded6226aa639194606d4f623c67e9602704a57c1619962ca6b37af19c10cfedb2cc9fd37a02f3aaa0c29948943ff3324ff3f1539e4c240539a0d07e33e88a43bfccc625a926e9349a95c5ac8a99fcf38a4f450c7b008463c7cfac4894c82d419ecfb30cd32b18b3aa928162ad52c8eaf7835834b08cedecb043305d41dfd0151f09bc97974b561f2ea18e8e2e622c59e5c72dfe91f325ca9281ab2715695cc3b79ef22c934bc1f482bde3593ae47551568a42b285369f31e14cd9600174742147bb5dcb72176cc6934b3e161dd6625ba6fe1f2b61ebee2413915c9acfa8cdea0206232b9bba058f041fb269819638ea453546c79d57621b2adab6adb7b05c5b8d5c946527c7d02aad4349b029cf6bf6535a64f84c4d816134535196f07d0bffcbe9eea4d5115232389e99a4d39e431263511f4baa3073a5fd636b48ac4acedf54228ce7f5864a504e0f611d57b55c8fd5224ff081bd0d63ce548c77997fd1d9513175248d4bc43d9583979cecd7ea0266beb922f14e44768d97255f74a16b31a60c8a227312e4b89c04f4cded24a12da493844fdedda4c574402a573dc8ddf6a147af475d8d4695acee391d5095f616ec0048bad636366bc98ba10874bc0958e481d29088adb919d5843713c5359728b18998ec12797709138b35e578dcca83d7d424ffba53dca193ed6629781d0bd0cfbbfdffddbed43a3e787a74f0f6fcd9ebf357afdf9ebf79727c7cfef687c3e3f3d747e7bfbcfef1fce7c3172fcebf3b387f7e7874f0ac15de2042552322d140882797ee0e780e69adb6a696dfe63c83f77b950747725ce8ef166ff938040c192e2c5abe07ab5659067e2cea66bd98686094574f17482512a0efc078d687c254022651360c5668739460b0f3e001fb519291dc1ae4265b093648eb29af2e2bb8d7c2370370062bd34acabc401072129ebe7ef9e6c9d1c1f99b27476f0f9fbc387ffee2c9f7accff64cc517888affaa8b63605e1772fdcdb39a9562244a912782d4c6cb7185786a9d2017614fb4e9f1598b32b30654c9170602133d10ecc759cb1db21cde609e66f5769ab3a9a827c530d833ace44d59d405ebabbaacc574138d9221694735d0487105f12866a2ac535ab1eb834e1e676c4b9e833ac7fcfe09ab662241771643b37915237631e09538ac0e24195e40d31c5700cf87a64757933499b09928474539059b7a3694db24996380af4b9e5c56f20ff81bb315c0734c29c5981ae5769aa46532cf7809155a342aeb1bac1cc27128a6661fe2903700afd51b00356f6f27dae38fa64f5e224f6a96a827a2c402f0eb8e62b8e7de6a5a8782faf728e3e3aac38e8508201464a4a1a8799a556e957a0fb955be90d2df558748941c9be52ca925f5003b919f8d6a86a216e534cd858449dff10c0ca975c88f2a8ca2934a72c833f6d69fd80b44d6054cfb05e0ef424faeaa0a37b78abd97e28ce0f92d3b5229177539171752d6aecd6ca1a191ed5a8ca7ef0b309ebae8f8ef3808929f09318bb45327e849ace72526788d2d6ec0557c72a98443b55e0f25eb647dcd57558d9a43325973034436462006bf221331b5ed5beed3554c3d54af2aa51b089682a694d8401b821f7dc30af70937ebaa7c10756933abcb40be6ac9e0e6f5e057a73d53c2c58f02334d34c1d2ea984f85df7da751744aaec13637cd2ea671e79cd6366c2ee0881ccf743854657f474e5c64be95358349c521d832b7c12e6d6858d31c9014bbb901bfa62069c8c31c4818fad0a3fa1399d66f6e9cadd78c4f0f609fca241f46e3baaa2e1158fc9a701ed6add1c5ca46a479e0667077b7f36168e9e792cf6670703308dfdcf47636547ae97eb6ce21f6ed4c0ccfcf5b76e928a223f5691a5c561f8ed7adaea78f05a09ca41dbcb9711a2094a5c6f2637ee58e4597d44b0aef1f20d69a1a8bed3bf4dea9810e661f27875620bf4d67d722384372661223daebd8e9c192f9af6885b7eedc9b25e19fb3bde573675769379530fc61e4aeb58f8dc381b761b8072cb491aac0ecf5522cb6518215795da6a2422d0e844148ab9a25f20cb84c26019506b854c7efa99032c3eb117b9156359c1efd8d2cd3194f6529adb080408ae7e01af3fc9cf5d131a94aaea42880b127c24375abb427205e5545024f975e8fbcb305cdf2c5fc75655ed8b4b4c88b6e509a12ef77ba224471a81ef4cc0f86a7ba42e5addf9168f59c5d5c8a058a21695da96aef3b63a8aa5f35654632429dca2d38b5962296fc5ba020836dd705061010f7148324b52dd815af54f1e11d129099e567d07913d20299930afbe2d091dd83e5444b0493598fd027adac856ec300f98dbaa55cbec0f52ba74355330928c3b6e17847ebebf72db0a9188acc8a59a4361873fb02bc0ee61f993876543db3df23dbd1f6b6591f94a9a80dfe8eb58258fc88c502b3fdbda82b8ff03449162592ea4a421c8bfa9351e158d43e093eb0c467490e23802c25afef45fde9694b4d8d212fb66f5f8eb32e238e044ef6ceee9ebcefa9a2e7c3660e54b615bc7d58317918d0a65a3987135e7dec1ce2c468c5c03d1809cf5559bfc7eb32931f7845665b4d933397eeb463a8bf6fd9f6deddb3f40398f17ed42c1d07d6170eb32ed8054cd6ea05567dc205569905a60a3db855996fc3606606f5f19a2e463222ad3c5f3e4dc7b828b58f8ccfc0f7b7b65ce6aa19f6bc9a4427b62b6721eeed2e67d637fe4814e32661a6efa6a263bad6cde4792464d23dfa5953d00359f2de321ec8b3fe9441552b653b290a9bfede43ccb3358785d99582d1dd230cca4466887f3e790846747f5948a99751643969e1a85b67115910743a30fe982761601dab278aca170d69014f451f27287cd8d47c9c9000fd7605041a325e23bb335620ab516476f1d09e1c44d1876dc7f7c2d467df8a61a0c16dd8c5e94481acc6a9b3e7aec12dd5ba78c9671ecc4b3ea3b9a16a74b27f80e48ac8e50aaa0bbc0b102ce3e558e0190f9e654ed3df95f31373127cf1e4e8fb83f32747474f7e393f3efcf701ebb387bbbb618100e9e32365810f5b439f560ec081dc210800d0bd84007304834cf218c84cbea3a89bf1b4ac34bf73ea50aa1f492137372c02407dd4fba63965db6c8faa64117c89d480161f96d96e6db9ec969c3f95ac4054baa141abdd55132676969c18b17a178d8d1d38c8f257ca2a7a76ecca4b2b7d45e35faf3e37a1dfcd5dec4b5e5d8242902e2e9d4ce0907afc0a5fabf88b0aac2e8ef16edead4e277bf291be909cf23a99b08b23313eb89e5d40d649b5c86b7e0d26ae3ca945599d45caea472453be0d01e07258c23ceb14e518931f3e7eb8f3d7ceeece7f5522d956b118aab62668b45ec5669e4e78c9fa6ce7e4f4f4f4f43f5f761e6ced47ed93d3d3b3f7b737673be3c6a5e950d472f893a282a821555dce13308a8a8ef9889769bb439a38ac7e28aafa695d4013ff393dd5f7bc9dadfda7b6f0e9e9d9973b1fa6fe926b536bbff4a45a059873d5bcf6bdb0f2b48dcea444524c67692686dadaa218990b3eaf1f6fd5edb9b29a431d9abe52ffbcb7cffe74c166aed098560cbd81b833f58a2b275d481751eb3fcaec8c0e0d75416e9bed4e29661987b09e96a662d69214f5e5660b2e430ccc8e5bf8c6789e68771eec47fbfd53f817b56f00259d2d9b76d6de19c7acf5e55ee7c17eabcdb658ebcbd669eeae24b81de69560e974863652ca2fdd885d9c775235c80bb8082fe6351bf0211845e16c2c156956ee30f71551d426097eccd44c188a8aa19a752e61712411dd84d4e580e3eb112fbb908951f78fab958a3a7a4b9fb0505de13ea596aeb3c829ab5655746a51d591e67bba0777dc1760e5c48808cce77c2b2248fc50b5f99fce5424c07c7003b8d01ce42d1f5fdc9ff917ded03a7581d2551baa772d11d4189028112984a9d19134d8da3a570c8be95b3b16d6d7f3baaf7e74c84859d775aabfa649cdf7706f7fa14c67d2715e94f24cdeacff820efbbe2bfeb7b92817fe8ad7322b952a4b7ec59cf96b2ce6b1a88ff8d55b3e8e7c713295a4c2fac11b55808d3d84da1bda1ab00b40272ecc993e5c970b2b7706c0bc98065a3e9de7532d25990bfc5b9680d81209343fd7fd3747fc10359161b48d8cac6b770c0d000dce1d70b8bbb5b2b8f0b5604ca95496a2c3bd605d4fb76066cd9c9cff08eef37f025f5096b42aba9cdefa20b09c0a0d86f1c22e7c24989a969e26576fcad8e43a8b54814a090f69d35fa385336067a1eaa7d47793789890dcaaed8e9714a5f87bf50c0f5774d7b31901bb5025ec21e1556cca2bc9a938c46ce34da94faeb6e332f907040a8efc871eb0de21c2eccec97f3a675b5fee74c4b54822d23570cbabbf3a1060b599d4393c387f73f4faed6b298ab45a8ee581ac7f9f452de4cf515526edf3bd4e8b6dc99c36ebb2564ba22e6a2fbb35ba90bdbe903c12d4ad4a4447367207dd58ebbd51c870efde521df624ad54eb77e89b8c4c26535c62dad82013b3b9c922f299e6d0c9e504a5ebb5a404b6e32e11c9a4e5e40391fc044fc0d7989ccced5f2b1092090373e9b328ea93d6f9b9823daf26bc04239fb3b0c5b82dbc44318bab98d74ab124377765f8b8a655aa3a669e7976a974dfbe5bd334d332dc5a0a5b031dd6d9ea77c9c6bea6a16754ddeca39f65ef6a163321aaf5aa4de92775c3a3a6fe07ae2247d9a99749464bf1d19ac90fb9e599f2d9bdef78b42ac9c7ea54a5376f7ac83d4ef3ee478906ad894446179455122f6aacad299fa9d448e9dbacb64ec320dd90c2a7ea414a786e9c8eda09921d80240fb926dd4c804cc1cb8c00286638b0dffbef0ecf55aa03f503f71f46a85407ea3858d7b1a8fdcbfc52f05a120094d2b6784be69ae88e9c0509264cb7ec44d1cd995e958a9c50430acfe3b4791125083913912a4a65697505bbbd676464132a5c13a85d78bbacab5375c86972259520ad01615d4dd24cb0686b4bdfdc22b8a3d3c5eb08d38e8dd460f5aea2863e2f4e76cf62843fd93b330a53ed3ae7c97068b6f6ba601772ac9221cabf446e4a143d191aeaf920f6be4d81995b32afaa314cbc229c66f604a847514c33bb32a551291b5816b2845d0d289f2015790447b33e8cedc87edc9befa885ed9098c1ebd29b653a8c7de733921426e59af7b7f7b872a63379df1be73b871dbc70d6e36e6cacb0b0dfaa7a41655d0cd3d1fa7beae7bd9cb6b4eddd4d9bb3294c80bed393c2963a2c3a73aab75d3a5fdb7d5dc93edb635db5d1ac777a7496dc87d2be91daaa9ae74379de841b4f23345ce014a9439c11dc7e7872fcc3f98faf9e1d3c3f7c75f08cf559ebfc3c2b86bc9a00533f37e5cfcfff4f798465c44a8b900fbeee6f2c8c3ffeb65fb1df35ac2b8c2285528cb317b9661786ac3dc28537f81ea1b8e2a82170576b125255594327b66f9bf5d47bcbd7896363f8818be47f2de5524b8c10f17e9821c67d68f8b3db612869625d6a77f42f66cb8d2c9d6df4892653eebcab6974252d3a561d7f6686edda6840b51f69a2f1417cefd35a68c030969a662831f39e9619763fdff265013c06a00dbd25a7becb5ca5c4a062b5b974b6efcf5b97585fae63cc60c566456f6351bfe4b38046d0662c118c57ca87779dc683e2213d8efff9a43e7dd65e2df959b4816d352effa625e2a792f9dc4e2d33b82357c3d53cc560b9924bcc2bc178c5e679fadbdc28b42ec5e273df57eb4edda9dcfc875848b8c6a516facd863ffa86812231527eb58d7e85dddc3093864fc1dd34f4ace2a6a9b1b4d42bcc7d86dd80bda0757e0e3bfaf9b9ceeeeaecbed200ac52aeaa717dccb234e2e894cf3e521afde075f87112a9a6e5a0096a705ddd6d8a4aeafc18e452892980df0f1398ee8be6cf2e3469e405ed57c31372a71d2ba9f36326e49852fb470a211f4cee9f56109123b9c3505423ef2e89243837464519b0845cd37c728b94922c11fe5289661d11840cc252c09d46c8da31944085f993a16f5249721ad04d7d34c97129cbd538e7caa419e7c5def85475510abd6faeb6f8b84b218da5cf2cc9ac50431fab5ee3ceb2ae265ad5ea2aa255a79b7ae825d6b66be9a5a1023e541661345eef4a8db31e965cb8fa3751f87298eb40c66c0ef75064e67bc10a50a14ca63cac35d6253de38bcf77b47a321c3ab60c922b10fa5bc9d6f870e8b1353d1c4ce659ca2b2631b68e28679abb8367dd65d86e67c611d9dcb70f92e728cb231775edf56db41d12b84b0656decfd6456de0cd89083c325cc6fc79994c24e1f8f8d41e88564ac6e0c6edae372696b0434624cd872677188fb80b852073b98ddc79a72aa6c2f138a54d6195134bc84a6b51f25a20deaa4951d6139e0fef3296d39c122a464689535717ba46302e58e64569568a619a4828c71823cddf159762c86642772c2df27b49550bed3091cd7855097d61af5b03316d1dcb5b18cd71311511fc8a6d1d6b72784487cbe021cde5ef77b16f15d8199bc6be28166e5ee84362c02b0ff1bbd3307ad386c0616a33835ffe5aec02d6e8c53da56eef8a0959d55bc3b4ee6db7f1d9c5ef442f6af81130ed40d675a7c89d34e4ed9586cf8abc7e4cf3faeb800fc1739b413c22ba30e2b70f74c338e5b3b745a8519b4185bb30accdf8037d1caa4ee8ec1f5fbd3e7a767074f04c033cfc302788928c3cdf85df2165190787435e0b0fe419af85c9176559941e007821361012996efe4b3e33b9b82f7900af20d1c094622caefd4af0918681a984ef85f158d43697d86b5b0048b43040913e0c249e591fa4c040d06958c83124e650ecf19f5271d5c42024fb2e22adc9a7ea0d48acb3329da6750ae601b9b6ef742dd20745a66f7c7c73742398d2db2a67c8606f059e14684dfbf44bc5c2187da0413b719e84bbb6227ee2d4b118413df08a518a414d8373c87ff0e055518bee03e5a5d65ab7e6d9426ffe15a95e9d46c06564cdc7a69d0b45e71731bb90f42cff02d9ca1f487ef2977ac41633c94bd7b3e4fd6c3e25f5e651f331147230a6b7118ddeffeb98d2e2195fc9fee9dc522ef7b157afef600f77ecea2a85c70c35f1ae96f04a507ed4d5329594c3548b9dc1a2162f50cedbe82b2f7236adcd6e6e4e890f3a5aeaf5685489da2d8569547e0bfa5534cf7099311fd566770360a7060ed7856942679201baecf9138c71c3babfcbc51591538c334ee6a7a32bc97b8cda8b8d6947a3f6e7ae3b83c24b325ba819eece0e7b5a8832c11a04cf51f3b177017c6c17497c084aa7ba60d334cbd24a24853a1ce92a0e738816a000252d275029ec5317aff8ab0b2f320113bf455b9a76b71cb7a3aaab5a5ae87a05d5d4a0577f3d29f0b5b9a933a7a2aaf898e4ab04b705232b500c99ed3f8021288088503bab72472c78ad53627f0f560b3c26d5f10a5723324cf590e5eaeaaab3f66316ec7ae0310b6925c47a9b889438423a645beab502c1060a64dd53e28f524b1d7d2213bb8550be720aa5d51b5ed62997a2fd6a479e86e4753b37372cb26d5a11ba4d7c542a979a72ea41f36b162b7c6d6eb20dd3817bacb59d1df6a4aae653c1924592a589961014abe659870e11982ac68900a7376351eb75dfa3fd5470a17e982afac60ba7d7258dbb9bfe12019f200582f226f3b24adf896ca1f774b3e144d5bc4ac4ac4e079930e13770bf83006df87a9e31ed0214b461ce6e63c7e55c34535fb26ae22c033409e8d3f83ebe604d4fc8a5b58f60ff6e9a52a596d91d4eef88b5c139a100d45d6c1bee1902b92e6aeea974b03bfb7d1eb4acf116d53d351745ddb12961adb393ef8489d08fdba67c7681baaecab7585f53f29df219086af2eff2476c4acf46f5bba1e6bc0b29c527a2299fadd65619ca35f0c037348391dfa3a23ce0c9c4be19536a61abf9d0d59c2825d619eb33ea7a04af1adaf7b3a0b0ec3588ff4ad4f8b450df0615236bf2b2ee1448514c4e81fc7baf29709f4b52a5afc67c65a218ad87f94ad40ee6e57718f32b904e9cbedd07dbb6dbceedef932cfb876868886cc6e70856f1bfdba6f39ec77d27720351d1435d332544f85121fe2ce7ecff7b44fe731d913fcac737f54cb0aef44a8334c8d5a09e292a66d10cca30f8f585be2ad125d4cd080d7810aac98b09514f6c45aa807bc5a24464e734ab3ec2f2f17267299a919beae8153c646e6f3b56f897624106e83e0843e7fe16c3fb009de66ac185ed97d53ccadd779d400cf0df7ad2fc3a923c91e225ee08901b196295546f90695fe6e88baa95d236c934411554c74cf72fd399f24065d01a3692301368babc6aa6d4eef213da0ed217ba6ea40403203ba8df5cd8c9b66bce0b74a003f1d07edb8af7c9628d742bb1e91010038d34018873635330d6752a31456d755889cb2d9a91093eddd90aa9df8e9c1a5553d5d23e8b2cea9190f0e3e6c60dbad018d18a600b6dda42d7e0dfa6ba6b4bd1a97b581e94825fbab831f40781182c31026df5598bd81db5bc281faa11c99074413fae87aa4c9df6495d2e116a30d0021028438a3b3bec5591eb3b30bd35198b1125800cd31188589eeb3739d779513b5a00c560a16164aff07373d3f62b72c60e4c0e5bdddc64cd2c58f44ef98d48d9111b3cf4594bef782da5ff820ce2785127d18a98364836986a54a4326845987427515896bbeab4dec8b33c6e3d819d6ef05664573e91c262bb9b49c3e01dab2bb48698af320cec65a3d64be71410b6d293d8bbca99c8e753518291bbf19e90f3a9beac537db8bff787a05c1bf4d91438c6991e2eef52c8b98327d238d7ff2e9ea907882a26d85e6e1860eb279edc214cc7bce1e0c1a4af19b2706df779b6134a88b50987b9f6b835af04da605dc8d13d07972800ac5087296881ae8c3556d0009a1ffd7174d0380be84e378e02babb40ef7e4f021591e12ead6bd9c03e3d7dae204025e1dbee86deca68408763e960126ee036700f08c5ba9644d546e6b463a26eadf405f8bd47f9e6143d9b897ca89e2a20a52222518a45237368ff2e62512846b43a266ba1a7ed0a5ac9caae2930873edd3185b4530dd332c095322dfb00cbe1c651092f16fb1f6262864665aa862de6aa931c49982a73b95218adb0209363f4b8d8f334abfd60a9e724c75a12d5f341809799e43ff8e1ef1a6a65bd280fab03cbd85cdd50084435615b687416c6524f8a4a288b0c6ded8146c5953a1f5ea0fdf28536dbee78bedbbea77bbb1ae858d4e444a9b2efdcc04113e16ee2ffd33bb6c7fe94cad28e77a381837d42525d1beaded9c4ed659a36dcf44fb4276421986b78e58535c0310965477e8feccd90e90c8eca6f3344456ef43e55ceaa7e6fc3f71a1645eb1b118fa0f77799114335da94f87f87197180bc7271c570bc62a838699079ab19fd832c83e91d810ef7b5dbbc3838395b93bfcbfea8678f8c1a10133594b53056b73bcb4d8be1d241f76c6bcbbd77b8bf7b4d824f9726c172cdf0469c230e3304c1e1c9f4e0bc56527e4dbc4701e72a2fcd13c1beeaec3deaecaa1740bc16e3a25cb01feb345b8f30fc66d97f8b6b2e6567d307b3cbc9819d77ea742aaae861ccce3b86f5c01a456879ea2d32d1c98a315212facd7f20cfe7fd6fd9c9c959cc4ecece56c09fec9e814a447d293f52ba02389836aea8744722f7dc72b2dcd79c29e21e35dfcad1054e9990ee1c4854bcf0e6a14465fc4101d7f5d2717dfc43ea478665ff5f7b21b56c735f7e32530000bd9da597e2aef79c6b3b535680e60224cd27a24c6b3164c7722f1a2d1469a6f998e4b9ddfbf0335498afbf482f051c9b0c1754ed3a37226e886abc9425d1979f94632980201cc4563694de049654eb406f6005342673a3d05b7c591f2aa46235637912f7d8aba3ba4c67b01244a58782dee36535f0036a31d1939bbb0fad61df32046c486f64ca78bccdbaece4acb9116265ee6145927da46f4eb4fcedbc86892c35dcdcac72990d77249e1691767b739345543128f92606b6607f0337b364595c703d87aabb17b273555da6492d4f8fa2e3d4a415be08dbf2ac2551033b149d5f2bb6dbd9dbf51bcb8b7c1bf772bbf8993cdb033d546e53919df148378b6739f094a09366bc1479dd6afb969bb22f6f263caf8be9df8fd9c375bb22199812919afd01faa4fdc18e3bfdb1b6a48d6434880d77f5f8329d31bf436e07148fc727d34a14a28afd863483c1728c13900f946134eff0a59855412a4042b858f92c8fc8d2506151b229bf566c4dada4b5025ae80bfa1cfa845fc0de611f97f23608cdec42b7bc54e165baf649646ec3a011c9618d16f2963c366ddfcbb8266f2f939473df9ac6283f744378abdb6ea83fee2009d3e9867e1e1fb90474f36ff9b8117a48125538fc90cc2172c9bd1e34f1725c359ee528f676d6ba57901553ee035db77f443c959c30e50b12fc3d1040c5df801dd1976254e76f6e92e9d289206903e6ee8869629abbfb44436d383ef539a68947d258f3f4d238b03c97d0ee99042a88f16871163a5b4019ef6cb1daecd394fad095f2c28a136495a8bde5cfb0a062a2660dbd8633109fe5a12184787201346bff848f1155b003170651fa991f2c5e097ef9b2319e9f31f58f7bb2a8b19d15bc7ef4d04738a6bab30fa08fbf0a813efeca054df3fa6b0fee505b2c53a0bdc74da8bdc70db046ff0ef346efe68136ad99b40bf634e3d3991886a05556b350a3ab3fa6cdbece439dfd3125bd6d1caad3a1c86b799abc08440402f9874ab26645d7e6e8f4968f259b022fce6eea899ddc33e5e8cccf84e93c63fd465185cd40398d8b25a5963537b735368a7993b2a4f4d256e74eb368abe581280618a85973bd50c5ee920b14560c3154962cc04041c526430535870c4d19b2c65029e48881328619864a192e182868b85fa820b2bd40a98ac4416a94b2acee8c18a6ac2fcc597d813d93e873aa1b40f673cb7a7495de61fd8a225843f5b186c8e70a148e260324c28d0d9f3c7d1171b912d5efd57d4e89f39c978bf029b1aa0b78c03d1535072f60ab27e6ae38387cc68c481d728f63cbfbcaf184cfe404e9da82b3f2a31c472008ced2f70d2697460f5b1e78c3b46125c95129c4f75931e0be630d9b4164be67181447e6c993658a9a1fd5c00509005a0a71609a55f664a61f7dd6c2750fd6643a59d28ffaddc98ba1d03a129576471f70ac5e175e42a25ce9a43f9b9bba435395edf647a5caee2804d2de6092df1970a153cce6192fd9d3623a2df2bf1f33715d8b1cee092fdc9920bdc40c8b2ad2ebcd4df26527b1ef8ce60eacccca22115575812e6e15a77271f4064158dfeb8b6a1e49a0a32a6a080f3c81c2235ed5a234ac7022b29928e97d7b3114f2fc150aad45a2efedecc88ad9c5bc4eb38e9ca40a6f5575bd7bbb5b1d7b630700ab70a6c8399c1ab5642bad36b6e35821434ac05b9002540a30d3e51762cc938541766790e6c3341feb06dc217cc3f6763beef22593a07afac6ad6949b26e201878d084096b30013d173432f41be3dcc3bf0d3239e6a088b7f4010b4a9bf17fcc75d0ea6de712ccffd0d66f58882a6fd5fabdf78c97da8b40c578c58622af96fa6bfb0c169bc1eda669a3a982e69a49377669de9663a7dab1e9683e5c50d620fe9d856b0fe25c5e049f74581b3d9033642d1bbeb5f827575a6b14fdf1612d83fefeb2f452640bc699f5bca30cdb3fbb6c694388dfe5eada528eefe45519dd6387b4a7f8a08dfe4ca14c1bb4878dd065aa45278476261857fc5c4db475693d5399cb5c5abf21f3a3b863f14e94786349999d4a359cee8fb756531c57351c298242bbe9d7e4a14f93e19be2de5b6113a10ce46722e84e78ad6e2b2a1dca117a9ec2433b147f595df2bc1a15e5f463834b5e95caed7ea0806944593ef96daf2f7f2f15bc35424760fc6b6a5e2281f3721c94bf4d3980b84b10576d5a22d36a318fca74f25da10755ee9bb298a695bf89ab5403d58c60774c22e129bd9f07a1520dd47d14d03adeb907a9933f54a5bc5a05bb8e7a758688f18014bad654b0aeab3cbdbf07371dbf96cfaa5876a28ac1ac5d3628d32c2274d592239a30c426c8bc6e81382b0c03bee4b3b68b98309cc20ff5561d843b16e631ab4252184ee16a495c808637b24f655db3320a72304cb932a1c519b474de53fea19ff32c1bf0e412d83db8347f978aab2a0ece20244a49e8f080eded41b2423aa4dad3c2e3ce690e361d86436c6eaa5e8023299d0c1f440f1fedb5db6d292411c2b3e60210cad3ad484e8184c76545403553b1e02aa5a3a27047d8905d4da4b0e4356e3b922c24382e2b02aa198f0baea94316b16b4d8b8c663a9668481c59b4a18c22af02957462427e11feb1df1455022e10e5bf84d237d4b86fc91cdf2baa20ce56dcb5658800abfdae05333d176c765175f58644a6bce7957256bf298073eec336b84097d85baba9f6cb38dcc0c0577aa138b00dae60e0ed44fb5e8e6e9d9d97465e5bf55eccf1983316f52b90889a0ffa30dd6c5c77f9d65925f3810cc54bc1de89321da5c8d207a211769c6cfca603916c25662dbbfb87053b9dff671d9b15471a4333324978642afbcf3a3094a01a83b24180435efaffac83b1025f634046ea0b0f4a65db81214b246a16da7137f31e6f2d7955a5e3fc273c8fc2fb494c7929cab150c94af5af8cccc19dce3a265f2b552ef78ce64a23a46307d709b342207df5cc133b6eaa0171e3a7c83d449b06da684e18bc95e2db6c206eb25bb1d9635a49918fd2f11c4c1c5b5db8d3341b5dcb5a3f36b2a06b2d15a8c3265f95182a4bc12b5eae3597a053784fe5761d5f8ef86b5aa5a52198bad72ab3d2b94fb8abb4d4a039970759ba625e2b3cb60264ae8d4aa2f7b7316bb562f6feb6dd6b1c21efa9c675dbf11e113e198f4b31e65aa8f11e12da5ce73cb7b4909be99439d4968ecd123aeb439e5e5bd5845911685a7fde1997c57cf6dd9d2f59c9eb6351d701b74895a8194f92f9749ec190436e8c6c2527699ed6f8fcab54afb04859e31fc2c0acaf97e016eb4b551409a0c34e4184638a698b4bf415499165027e364c431d4ad6c6fa16becdf61bc4d4f5088508bf141f7dda31b64fbf2213f0bba943a17dd523a49414e901c4ec613ba62ddea56ff111b8eee33e77b4f489df1ffc6c6f05d15e90715fdc41b68e21b2f9a80ba257bb148b25cebbe88c42799c4543b1624815d22b89dde973f86509a16e65c46088dccc3a9df1cf1a63e48e0782d8d388744f6dd2b6f3fac8a91e0c361f8bdbb2abade87d22d6e6a0073cf1bd5fe8648fb9ea1a44e57a0bb0cbef8215b94767a0ff05870f44ef0bd50d16c4221ee433653a268955662276d6723d7063e29e98be60f013fbf97f1750d8a287ac9f101f5db588349d380503de4c63467787f7f7a77d523ce084739d25e08ed45d01cf8bf2f5551e58039861e410dc0cbe0baf1937f31ea79473ed8d74edd72a9f77417cec9b941b3f921ae51754454a98918bccc8cec5129956176dcc6b7852efe778e9cec97b7d957faab95b79aefc8367ab314fd4fb84cf35703acc29d093105d67f0eac9c7f3a26cc0a3fb9cd5de6bb0293bb596389a13ece4dd631e6d3bda2e43f5b0026c1b5c4045e4bd1e0e540c61bf729d35997b50bbc7499a1092c2f5911fa7c09c8534862b36e50b26aed3dace1613bccc16b21d713dcbd224ad33fa8eb7f9dae54f425e9fcc3bd4da74ea2e7f8722a215fce3b92fdddbb324508de92ab8d655f13cf5e172549487b95232199e70c76418238a9351594c8fd2f1a43e332fb4151af3315ae0953257222913a335767d7d46743abee474a851633ab1e440185ebac4d9d552a19a611974e2e35af0109899f247ebbbc92220463a9f355dd11a591c5389b358ea2e160a5a7cb37d5d6797696fdf4e5c85d439410e3281ae4951a8d1696d34ae84375df4ba85bab15c721181635ceb10fa1da551f35c1e5fc7065523eeb32b8fa42ff496892159f41760e5c2259975742592ab051735652a8c13f16389af82fff9b50012871e4fccee5a162bf524705167252edff3910d6d68605cafa7caacce4c27d5b2346bd19d0ef7c9ad591290594e64563c3f39ccace7e09ab96391bb62bbb34a235a9f72ef6c17a13d48935186d7a317b1f313ac496f32d659974dd9f325af9349d08b8bca71b4a12a6dc9054800c2ea46e111965f44a7decfffcb2cd8fcecfe172fe71df7a5fb4a730b0c09de3fefe84e9f7906882a4c0f86a4d015afb7ee1de8c65316f7948954b2b3c39e1579ab5631cfd1a603cc098d4d519a336e4de565b7de15e99071f6f7c3b76c301f4b00edeca2a3ead42199aaeecece603eae3a57627099d61088a99a1457e783f9b8938cd3fd74d8dffbcbe3dd475f85232d692b73ed3edf356ff40dcc9c5b102c6c4a855cb0e919708b34da536f1e1aa51db72d7a89ed87081c614e76cfd491ff64efcc14e8d202cef314c27e674e45abcf0f7a9edd057a584113a1fb07cca19e7c21e119af79f34ac86491a8aed0f563f060f214fc5f2bb6e886780d42dd6b95a93a7c53f2242b72c12e2ab01f59f74880d0f448406dc1ad7f4e6873fd5db79a8964f5db253dd3d801a29e9d12a453446b48e336df0076f48ed6677bf0e646679cec9e9d3c3cf30976c914444e3149a34ec2de59931cc33e0f9b41d1fa1acd37379408adb741c8250daef3304b2190c43b069ff09ea5a64c736fe0305448700140ce9f219cf05a8f2b01019f4703934b7aae97c42cf98015e4defa588a7f3bf1fd85695fb6680aa8630340fc972595924b48eba6ffec5e615ed632f8d73159c0e21ffab1d63bd23b289fc61608dcd9f86bbe79838302a14ece8ba736d24d9f6dd8cadd50262b1c946e64362ec99d5e4a57042e19224bb34ca5e13332727abbb909452403b372acdc582175ef8c6d18b34378bb7db20bae0dcdbf2edb8854ba8d0e40fd36ad19ebe4aebbaed5e3b26770d5171a5ae1ae0020559968003568c7167219badcb38313ebc29861c27bcd488787f1de152dc1893d3838262824d00bebc3ee075cd7512804039578f6a6c170221a055e3811bd6ebc9086b7b4cd8dc898a72e8904a2c534c5f923db98ed409097df2ce1e1a1c8206e835d355e9a7a0fc4fb3bb0729eb0ea8938301caa3eb943426b02dcefdec098a2afcfc83fb3cf6758aab86efd96bdc00c56f872249c867ffb86d26ea547c2651a3bcb2b94ef3084a01ce15d935f10d3105ac80d991807e69db818b8d73b3f8a17ff7071a76c650f172ed4983ca999f0ead0bb97842472acff87f0b5059046203e9cca3ff220635ef134fb0869ff4be4cba97b745d76d8521cf3ae75abed4067bc9ea094277f042c41c7a26e98819a6dd05190fc5127327358975db41b10b11f055283ec36ba456dac2c5368ddb317500656499a5cfbc0e585131b93786750a76b3db9422470724c3fac5203d6a15bb7abc0f8645be93d8e804da34ef57425fcd66ed97e8594c56b7621c775e1ec0dec1049553de151363b2c55f16a0c0e2f62d49d0dc588cfb3fa27f328d8dc98a6393c0b9d653c11f772d2f7a8f3d7868f3edc0e3f6c8774cc263e6a7d9ed0d15235a619b4e46704491e1a1bc7ae07eef275a157b84a372793f7acc55b5d76f29eb506adaefc4c5a5df688ddb2db33a029e3a1902e959694cf3b834ed2727c143e5a027ed2e2ad98b576e57f03f95fd23a5bab608b432368fc2c11e7b66752030289b3f46246111f924ddc931ddb278bbdab17498053387280c724f69d468d3cbb4a5ab0eb722aa645fabb788abe7dbc0d95e605364994da3c6fe257693d49ad5e14c64036ca120cbe5ff1a9e48a3b27ffe99c9c9e9e9d6ddd9c9e9e44fbdd687bfff474b815ed774f4f3bf2577bbf7d139d9c7ed13a6b47327f7fe3f4f461fbe43fa7a7a7a76737f2ff4efbc17e5b26ca8468bf8f65657da7a7676de7ebe6cb767b67bc6418039e5c5619af26f87e7179ff0faa84cfc4d30997c7f71dd98548fed7deb755e315a70d64ad9e02d7057a22b01537221cacdaa9f12f46b3c69ff70a68bdac613530e575ac78c3414a76e6debe25a8e85bbe909f0c8c1e2a813ac984974f8ba1785247bb780bf6d563b6f38049647a3e79d1d3458b064c54959402f87264e98618f6291d0ffa678bd96ff3a29627d0f9c07b72481b0120b66fa14813766a63d6fa72afd5665d162937ca37374828ed90e19f5d714bec3a28761b8bcf5d762ad15f6f5c9f94aed3e97c6a8a263c91f490fe4ede43bd7cf2aff397072f5f1ffefbe0fcf8f0df07accffeb2bbbb66d8eaf38eaa5acb97492678a91ac71ceb03ac85bb2d76e26a22e44ecac47522c4b062177e3fd67ff110f4b230e1ef04ecd4c5bc9ecd6bd39bf525ce46ff1b526793ec43b4aea094c305438e345c3ea858245a20e43b50bf8f0ea2634048c074e4dd8f2b0abb140b4b77ba43887773a485cffb84e0a783b554f992cf9e9a8a1d370d904c0813bcceb2a9a82a3e16184394e735e196cf7f7cf5f4fce0e8e8f5d1f9db837fbd657dd63ab89e89a496046da9e8ae9733f01050f5d60820722a24c182770f10072f9458525e6831705616efd2a118c6922e4dfc6fac0291274ff7d4cb1ea95ceec64370843f413ab57ef374bd60471d5a181df6dd426fcb28808ed2b2aa4d154eef96d622c5d4b9b3f867b6db1d5820387ca82ead8cfd9bf1d272514fd2ea8269375c4a7c0caf03a8e4c18357452dba0ff0308a8da515b8b0231db9808c0bbba720964cc55095c5c5615da18d022c31be600361d57260b2883c584f8065421d20391c1f7dbe0e0394e7dd2bf04a63e3da9a93b399b5938b977c7671164dea7ad6ddd911c9946fa7792dca1cfac333b8fb86e4878f1feefcb5b3bbf35f9548b6ad71e57631daae27627bca67dbc65fcfb6555f3fd06f57a1da114f04be4690cbf92296478f4cd442fe1a8b5afe99f0ea22568134457d3fcfe0bb9dbdc6a14373bc4fc84d9b57377a71352f6e548ebbaa3e962baf779ed88bf13cf1509d211008bc11f5cd21438af5ad2efb8a9e33cc7b188ce3a439fa7947056ad4b5c90f7a9f62dca4efc5ece119a90e014d985f03f728665f5938f55a822bd5cf7d9ad8d9612fe13d2fe551b871908a3a6ad3699e8a06e62cb4a249034a9b3d4201a9b92c3bea28e5a43acfaa83bbabda373541113d8eb2f00082dd70fc65dddc40fc6c2820b3e0f4641d61d22c628662b6d87a521657406d6f173301fb56e46d4e9e03384395c43587a3dde1e5189f34a94d81e8848dca18fbb46f7e76f86c962d22c99463a8a00dafb9c6957b0da5f775b326f5ceeecb16135e451802a761c807f9f27ceafb8ff3641939b866b75401b703accf2c7581261b6b01d76556f858e6dc22509d9c90c8a59e9b1b23803822b62eaba5999d1d76009b12bbd0f0921e7d52d47961b15c417b51cf0ae302a511f84c65f9d6ace6a8a77ccec1494f9d60d8935cc59553a736aa7b02358ca465dce2604b205a19b5a6f1cc978e5142dfde05fdd5ac149528df39becbd6092cb1dbd83e5ef07cec6b90420ef8c247cd90f721052a861a09618e7eded15e8a22b8e776742ead10d8f6ae0bb4bd1b0403d619b347aef6a7b5173f8c1f359438a654c08bb463a5c6f659aba5d4346fdd424b656c5d39318a81e89cbe550c249aab0a389d377d98e9e4fb46d30b35a95303e74ccff1df3b5ea6c5bc621718ffe12224e81fbe7a7ef8eaf0ed2faccff6d80edb0d5ca8a0f1a40e2a5b176c56a6d3b44edfe968d780275227826af7936a0cfbea87759c1870658425c93aa655edd32f4332b4967bdcc9583f6fde658c1aae249bb49a906d578e9cb2830f73b4ae3df5aeb116c90a6c845c0a513e3056798c87673e7836828e520bd399284745399532379ba4608a5a1553c144fe2e2d8b1ca3a82db5dbac1413bddb4ad435e56c1337cb4722999755fa4e640b836d85e1a89a578998d5a9328b4d7896296b884c925cd576fd17eb65a51f8a52d4b4d9163abc723a8534e8f74afb8a72a96fdf4b20f1eb8c37ad90e35965212b9b7736426b43c15abbe02725924bce0630dad68bb12d19d6f66eeb6e95301df1fa6183a77c7657cc6063f706957db698c19f367c191c525041be2260b02420f5ee7fbd08661f142c98c63c53664f6b7a00581afd8cba03f0a202dfd7104123c215a87e685a0f9c9b746a63a074cf144ea5fa029775378c378360f2374c4b30762c43c144c3162d1f2630fdc1977c1fe2ec18d120aed3aaae02568f779ca6cf3bf8842452c76afaad8ed76da5f2d6b2967befdce2ee8d99f291b40cb833b80778e3fcba4e135e03c140c981abf3d0ab6172da54d4e8ddf9195a5e2e064253f709080205c2a6c4432166ea5a6a3517d534a95cb59edd972aa98bb00fa1c94bb1584192be30f283331b5697be7432829ed8576e713fd85940f5795507588e4efe43035caf17b97aadb8776bd8358599264e0d784af9c4b67ef767728d2d7cc2c38fb33164821b18f61331498f370456baea94a2cc19d28ea617659e54104fe677effdb2ccd26dde86775acfc10fea9dace592dad4dbc4a2db9ae086d91b79f0aca22b13dd127db3a87449660b71ed1f89b4acdabbb9316f2a37fa4dd9a4a13092ff192c35ac26a488a474a9c4185edbc72b0379340553a19e4890a750f460131bca1c39b441978e99ada28b6acbec55acdedef2ae8a0bdabc156269cd4a910879265e22a4342e017ca925102dd43f493ec9178ee14ec8ca873aa95e53154fd5eb49915745263a59318eec834a83d3be792810dcd29d880cbaec32edccf25808f611211146573c6d6dbc69a589cfe4aebbbc8cccbe8735ecda3c7bc96528a5a180951c67e3f49dc89be136ee96771f76be5a1178f6634dd4d671270801997c6782ab68504ef609a4314d8c566e65b771306b4f6641ce19156ba77ca6a8b48ad979c73cef4499d5bd2c7918b3bd33afec79a72acafabb45b01222c9b64362b0bdf1a12b6046cd5ffd2077d6ee75df21576abfda563a4b4aab91b62d0baf9d9963c0b99ec83ab386c91f23b5aee9a0f613d0942f811adc3584cf759f55868cfa1a1be34a11f5e32c6757fb81f42dc7d5f454ebcfcde75ff7cbe6c8d2f07d266ab981e57ab3225bc59969cd2b54ad26359aafa868369e7362554dcc4ebf383f171506703bfd22d68aa16c2eb44361385eebf081ca74c4f876783ae169ce071944f103411ede0bda0ba8d902bd913cdcdd7bb40d5743791db3e73c1183a2b88cd9619ee0543cc932745c52b1e605128829eaf968520c0546714a445e8921107509d3f5ddf1b3edaa5e644267b25131074f53c6eae2c5e1d38357c7076c24a5564c475fe0a8a491bb0a108c6daf2e8580cb323e1ca66899c1c62557b632c5484e96949154e7139eb381db307bf3e4edc1abb7c74ea310a7c834aa690aee0f5f16559d2d58cd2f458e1e5d8e0487f04b338966b9181a8e59421321459374c86b2d9dd822325f02466975848b7718a3eb1ffc83f68cf0d82417798d9f599170749922419ecfb34ca63b82be53e2988fe06a96a649a9b5f5cd373c2ff2c5b49857df7edb22cf1f69bdaa344d928575ef9c4b67745aa4b3ce026e64503daec71a7a4527973adebfb734186bb12d336ab6c55aec42a6347ab9c55a17ec8a572c2f6a6474e0145ec246ad34c7524dd4c8621db577eba77bde6db91c851f17d1447c3bcf444e2ffaf5714d5b00e07101a0be658fd93e16d8668f5997edb663768ec7b2c73dfcf50de4e3c7d6164111d80100c8367b7c465b84d433bf83560806e25397f8f62e8c9daca634899c65d426f3ce3a499127bc8ec022c0e8828df1a15c0962f854d3b82441fd1b023cc29d6eac5cdf4069bf48c792cab2d29237b6dd58687e2dc8b91b7c5bfd3a31c6fb67bd10dfd61cd7b2671b015be7c171f1459a5f3e2df25a365eb2be775d088402f15287950d9687bef1e57a323c21aa7939167267b21496b23edbebb1947dd3a0b21e4b8148f045af8e426529233deb3562131a0716b01cfdb87d9d507c42fd7a57199330eca476628fb928c248b199dd9ad7ae00d763b71609a5e4a1545a8104e2aa1e211eb23e3b0783b962a688e0194e5484007e81a3625e8bf259316dd4bd5d42d6f6b098d266fc0923e29393b5b4ccaa2e3a80588199e225658ac1af12b5566654cfbb28e9ed43ba3ca428aa05f991ddf670e5d926928c57d5539e65b00c226d0019b3a7d64a5253c086c9368692c5c80184290f98489d7ef194e792dbc2152a67d02ae3f43c7afa45bb874729dabd595155e92013a41194f7a24a64a318ea33dd93496e0f8eb40582ee06080a130e77eb032172e3905d0a26db529205c7ec1442362186aa7bc62a0a155dfa4a1abefbfd3e3bfd0245c2d32fe4626de692d1b27dcce832d9efc6c4a8aba72aaae683a7125d31f60e7eeb21ab066c06b84ea0cdc85e7ad96aab5d3251c7125832bd525420f54fe755cd440ab69003812793a2243317c33e7afa05db628dfe00d2f40888ad85e16cea7e8874d1e9708704dc7c4f2d77bbc0ca40ecb508b2e138bab85dc44cc7db50e139180de7816992e8da3d7c704210acfa5789da44c27c3d62fbe1f4259364fbd6311149241b34206ad68d8f2eb9a97056d5bc161944933628ae0bc6b3acb892206565c236b0528c3a10ff4654599ad7dbc3b48227cdc0d076666082b36d2adc36f4650c6e425bd2cafdcaee40e720e67ef9540b034a06b1a4db2c1fb34621b5299b6a9b85acbda4cfaed0d2b059a2ed475558c148b00ebf5bbe29236e93aef4d26c97ec8ea580630ec117a644fe59526d63faa8a656c401ea45bc0dc240c5464880502ab29b1d25a5bd67e29a27b5266e128193c83ecdae4be927f2fbe2cc92253291af4d63a1a368b41bfb7b71e72aad27f8d50e904d5b8a5c0dc90c04e68ebe287384235e7a61401ad24bed98d1007c9f84a3843a2116e5ad8d7afcdffa980ac4c2deed3deeec3d525a4e9420701a8673543c4cd3bcf36b654ec5f6741d256def4c8d1e96eb8af1d128cd525e53cdfd9ac7e997876f3ff941da9c731d8117f4497dbacff4fb7dc5fcd1a6697353d9d78d8a324efa837dfb199d7e01c8eaa8980ba75fb4bb8f77f7761fc5c3309c9c6f9e69b0c7b108838d4a3ea6f5fd351e85017114e7d3622834ecd7f17849db652131562ac0bdafe2c952c077e9d000eefe2dbe0c0326455e8b6bddcbbddd380bc3f16a9127b4937b7bf1746995c9bc2c455e7bf0f9124c15e5152f87e7a51869d887f16c09b2e6d54c5294067c14ffd61fec9fe62b40cfb3b4d2e37bb81b97e18aa7625ae84aff12d761a08cffbed0408fe37761a041562497babdbdf86ac9a0e7f99083ae5993d2de5fe3eb306c29aa5991dbd9dcfb3a5e2c414f52cc0c6efed62312dcef116fbf4f47911509ed1ae19b9b528edae8f779fbbd5c4cf33eef7cf925e6f630e865346fbf87e890495725f03eef8028c4554ed6c55096f847e09f31fe19e19f59571b27f6f449c0d6b6b9695b35955e62c11cffd4f8a7c43f93666d2a617e7b8bc13849c2adc1c513890b9521f1d2eff7a7b77a63782209fd653114fdaca7d39e1a8a868c29cd90ab476ee352d6eb5ffa396fd43aec4f4c8eda4bfb8949798e0be0488cfab94d54fca32f4cd20bfefba25f9bcf97625af44bf3f906f8527f484ef86f14bbe88f0d147a0481618c6ca25a2afd99494a2b8b081b64dba04da2f0e646212fbb25c53c5c3d71b31c6c05ea55355ede368b19542e2f36a1c5349e9be077ac014a87fd7e3fa19592a95ade8ddc29a1e77139bca0f030c9cb61eb5b32bf690534b01cbaa4352b02590e3d74a035ed2c871f53784a584b4b8c9c129aea96c3cfdcd1fec4b374a8e6559e1283738bf738cedcdedc8485037ef3ffa9261114fe102a1742a543a834085500a10a41461048351a28c9a6a4a606855f84c6cf40e367a3f1f3d0f8e568fc0a347e251abf4c1311d6906ea16d15a8ed18aba304695105e5e79728592929d502020000ffffe1eda2830e962a00", - "344b8aa418988970b92426cfa9b6e2fd": "1f8b08000000000000ff94597b53dbb816ff2a5affb124b3da045abaed869bb9232bc135294d434a294b18c6c40a3138b66b2b3cdae5bbdf3947922d27a6bbf79f9048e7f13b4f1d891fcebdc88b284d9cde6bea14e93a9f8bc2e95d380fe23a0be677bd6eb7abbf76afd35416320f32e7923a49b0aa111e156992f1208eaf83f99d439d309081439d551aae63e1870e75e6cb7572677f2b703f17c74803bfc4a398afa5b51039d4c94591c6f7f83316c98d5c3ad4195fdf8ab974a893e5a94ce553261cea2c8362fc907ccad34ce4f209f404710c42924206712c420e7a414eb62e9625385c08729148b4e1709dcc2538843ac5325a8092502c449e8bb0c21564598c1a96627e37d8dace45b18eb7391dea2cd6f122022c0e756e9120439714591ccd81e0ea4a3bf42a17dfd6512eaeae60db36a3d2b3873ecbd25c16a539e026f801e84081a362e550e746482972873aa9421625c2729648d62b9107d7b12605331cea4c9f56d7290894e954e65172f339b871a8731fc46b20944aaf422e8ad2ce0400cd731148f8752740c37594201a4060c5cf00c8c025100196e7012c3c4449983e00751c6e8506dd75499d559065517253383d27607c48a78c4d191d32f6cde5d46393b72ef5d927467d76ec73583f85cf8f5ff0fbd97bf81c518ff1a5ebc3f7f951b992b823f81eb91fcc92fffe18be22a1a7040061c607b88cc2a6233a666c72487dc6bfbb47a54636f5941a0ff6c79c9ee286604c703a626cc495b2afd467ecfc0c7edce00f9e1d228ee918c90666c7636c4a7d367ce467d6127c1fbe019b993f0086738f0e19ff6bf482d613e00dded311e3d9600e3f2621c8413676fe9efa6c1473eab3434fc0fa37179d9bba4b977a6c28f918b1713a613c446cd35350f5f90bf5d87840c7ec3dd3f88e50e1881e33763c50c65e83c83b40ebdd0f045873a203885f7d36606809f886fb8bcaf908c23f5782bf941e6723ca99d745bc8af3c6559a8e14e95f10835b1eb96823483de19b520fe1538428f4c63552f99fbc84c226186a3104691e2cbf76bf2a05e760e4fc5089f7d8f035071cfcf083da9e6018322dd563fc8d2bd069c7caabdab90ad347544247cc9743e403aff9270863027b2b306394402c86e847ce78ee46f80bb2cd637fe90d8f79d245d74e95863d5c7b837ef0f6b593f0274f5c54565b64a7ef5c3a615e623961fade263807e5df39a6aa07d6f2f7371ca5e3f7433a51f97a0ad1fac81464956ba7679819292e8d0748a9dcccac952300dc1da082314a86a07947839266b43852c6614efa09c8f31edd73b538297dea3dba876a6daa620f7ef95085e118a4f3d7fcab2242fee189def7198ff91be5a2df5caca4cf162be58c0d7d7aaeb20b4441a421f547cba116a87252a9c584fc4a5397b1af01d8b9eb325daa01e37b3ce3db9a024d70ce5880fa38d4d4989eb1e1db41dec04003c6e6482970938ed8e47e80fe61a99b5a70943321af87f7e085c1292c60fb64a7e8b489615b4112f32efefa34c43e87c2818a67ae6946b0e731f6cea591cbd817ac8cc265d8be30bcc71e3d036f012f64145f6225fb5892a3efca9c5df5871e33ef1e441fb247d776e6700c7e94eef79af5a7cab0534002d67faee2826d688cb5290715cc7d05f3f3a12e2f00821fc790a263acc8b1f10066cf109ba63f5467846a5e1e401d1bfa63481a3651fd163e8e07a0f64f5fbbcb63fec9bd16f9ca8a85c46a5c72ad1f02f911cb455545e4d233c6dfc2277b50f978ebaa2e43a78c77396cbc531b4cf56a3a6603f6c1068fb02798a34cb5238678ecd45768949f275cd53a08edf217ce94575c93faccfbeebdd5a6bdd3a68dd9f0d1adba488052beb990a33ed3dfe7e6501e7215088cc7d91b257fcdf549028039b3b6c67044f0d87d85210dd4960767d3a315cbfbc166cb4f71e52c1e5827c927354428516719c6ecf51005605e15ee3e80f3f7dc474e7d18eda258383de76df8c79faf7783bdf97eb0ffc79ed80f8337bb9d5b1887f474cdd3448a44c2ec4c66b2db257ab02301399a8e3f7e22733d4593459a139c95499c066194dccc1232930b3d0591a6c9bb0573779bfc40ca99bc0fb4043f2c489fc0e6c5eee581b56b0de08660af46509fc90dcd2ba0d154dd2e09c290ccec617ee6109912b914440fd9448d7cb4e2914b9190451cdc10307e56de0a660e090ab45884244842b28872513aa5065ddd2da831919288f4c92e25e6ca40fae4a2346691e6ad8388fca77448475d270e48f4db6f95cb6652ef937e497911955266325ab4d4f5a3535e3e3af5ab4707c0b636ae1d25ca36f9f557b2b179a1f72e6d1c3369ece8c085655360c973b17bd9aee03d57405fa0071f19fa67cb39c69f244aecb4b021fd5bdb2d765ac6a95d374e27c685d9065c165fb5be6d9bf91b2d5a0d37b736695854855125edc3328a45ab74b04a051b60b985b7c056bbd5b67c56cf7c91c8fca94cf4459eae4cfaaaea9529311741124785d4dc1bd74a0c72076f96ad8d2dba59857fff4d2e2edbb512ccd749a5c56079801a83f2422005c945103e699e5cc8759e90a62bacb1f5f9a0de719a696bdd465d7ded9a8355accb0302d5b769f50b45085c7552683d75de5a59024379bb267d22f3b5a8760d905bd2277b07e4760b4889e3b68ec320c9b021d4792e6e2dfd988d9b25877c97e4977e9fecb66bf016415c88c6aa5db44aba3a904dcfa9378356f4fbef94ecb50fea7d631d4bd2270daf09ad86b54eb16d5b6353a9525f678f1d6eb3d9ed92cf65e327f360be14b88e89b0f18841fae4c7f341c5a84e09a89842a6b9b08f017d06ea54360ceb44bd6494ed9a24a9d46c9424eb382e37b25ca8f56e968b8590f3a5088d984f79ba8a0a51d26a6594ecd6963443cd12156a3044bb66af4776cbf229e937a2678e26db633a1ec4d45bbdf89a6259b656505ef5020e754aa285894154404faf2251cfd5ad865b6f8318e797893bfa016af3440118f8fe430292880703a505a1ccd692449244899e1110597beb6827fd9fe8b51c3e9351af9a06cac5b8a7aaac5ad1507be44799d0b51e3a545dd69a5beab16838b4cc79873d44cb37479ef95bad37c4b0dec50f611eb2d49793504d7f27ae1a5cc57ba24205dc5a21491796b07ae5d6a159156c3212760ad130c311ab85e89dab2b15bda6deb2c2731dc90e7e22dd4acf2629f38664b0c4a92640d4136719349ca09741be4a9327e3931735605736d34219b1245809aae55675112d5abf34c948eb8cb589470f4ef587d74d453f48f50edbc310a3f29eb1ecb95dafb3e76d1f54efb0244dfed1eabcc1ea9a9d30e3a50ba2de81f124db297bee0e8cb26aa763bd0fff1f566f33830ff075b9477694193b5b56ffa3d89dca093b9640f06729cc76dddc74aa45702730144516cc854e7843b54a43417e257b3d250fda6a50b6d89096fd3bdae478d5232b91df081cc5f4937724b03cb524d30993628375bf4774c12a4a3dd1e1204792a219e1bbbff77ae45a2c837b41e2e8ae3c595ecc026967012ac2de256a9960cc6f6b28cde305ee95f1aad8deb56b86580486621f6f463adfb40a48376522e69a5a355f3a55949b85c35192c051abd34585b905534189b0b1285a49511234a75a0259168a45b08ee54e73ddeaa453989f1b5cf26acbde5ffa64a7c04ad8691333b3de892738be95639b7cde0911ce9d78a25514efc4539bfca8b9e5e24e3c5d1e90e7ce759484e805646a97d03471526c57c88d900365ed108bacde63e7e92a0b64741dc5917c220f915c92244d7e37ad57b7ff17d32fb1d36fa5036adf2a74f7330709f84d9f5f56b7fb6f35ed1b6c15ea96e50cc57a51860f7c427a8ddc4ab432b9d89671409e7f9647614b01a76427d8294f910d6fabd56d8fff9b8bf68b1e4d6d8feaa717d379ecbcf857b7f92d7e65b6015ae9cfd6d77134bfca02b9bcba7a115b46fa64e674832c9b39f6845cfdf38ff489fae7dfc5acf6ffe59973f9b32dbc151f94f236ff6d48fa960a75dbc642a816756836a84065c353db266d5d3cfe83d2dca31baec11669ed06dcf8a857115f44e65a06f21ade39487fcbee037baa6b7c26c0278b542e456edfae5e7c19702ecd63e6499a4aa7e738cfff0b0000ffff625b5b8d48200000", - "629fe427503e5cf1bfa49722d21395a0": "1f8b08000000000000ff5491d14fc23010c6dff757d4be1a56718ba0e9f622898684101023fad6b565adaebda53d26fbef0d0e34f4a577dfefcb97cb1dbf5220b16f3531e89a32e1e74f0b55268410c29d4641a411216a2ce81e77a3293d21b4d8e8f2095e8c754e073213d1542082e26c4083adb1feebb73abfa09b8246ec1b1d8dd6482fa0097a575083d8c607c69c3848e5d30a002306d11e1b098efd092c4fb374cc648cff5aeaac4f658c97c1d6a3ae83c5bea0d1886c9a8fea7ad9af6fecf6b15aacba6c6b5b27b27c31bb56cf6cbc5b4da639fbbc93efccce37abd7a5916f6172b89f77b03e6c6e171fdfe3cd65be0c1023045b5b5f50e1c1f70ef6a719589970362c9557a0fa32e1ca76c4aa820600a42567ca7647d389b2e1103f010000ffff7280bcd7a0010000", - "a9780b1e2b4178ca7cdd88af9e809c6b": "1f8b08000000000000ff8c54df8be33610fe57123f080d99539da30f25dea1ef857285eb9b1187e2c8bb6eb59218cbb75dbcfedf8bec38bedbbb858540c6d2fcf8e6fb46b36f07dfa42e7869615ced1d4b86b10d2cbf1ade79741889eb52a321ae8f1a5be2faa3c6864aeca9d655731795b3fe3e3d54cde1008e62dd68fc74fec73649450e29a4e768d583e93f3df9bf3844cbe95935c63919d08110a1765a885ec5a17f90f9a32e356036a8ac320ebfebfccec0bb521af42084b4b5d7646aaf61ced009d14986aa5f9142affa87ae4d1224546cd3c07e37cc089489d13dcb01db97975a032609d38d9a2437662c329515df0d6b4e3e1cb6db4443cd1a3ded4b8c74ace25d5afd62f6cb3e86521d7555ee89426db410d2d3fe089317420eaa8fae6bace40f1ff00868c949a77a4a991c98ae90ed346b44e38481c6e3a99c70c89adc00bbac65d74a5fb3866b50b695fd2f064e7db560cd473476274677da1ff17a791aa76925c7e6a099e1b4c662c2cd768049b9dceded6c72ea912c3ad59047a72eb44d1b3226189d0ad9849797abb417db76deae82ce6ea3f5c3a3657376f6b42ff1dea6539a6042a798be9dde62f04bf4a5d8539e8ed0ee3e3f3f9e831362f957297c4edcf9fbbfcdbd106f55fcd117c7afc60df654fc192e83b3c504f85670f1e58bedaf6e6bd8be5ce0a6efda9f45390acea34a4e5a00fc4df0aa90adba56fe9a6f8b30972a68edc90a917f6aabb4052d5a5ec1356c4db2d20fce414ee714cbf416f484c5c5b66670a978cdf8d2859d003fce80fa99978d640bb755919fa905a72e32a1c75bbb0ce3374334a973e72f332ef4707b7c2973e4bf9334e7647ad5edef378f2dabba629f4e3fb9bc4d70c6c5589802199073b9f04a92abe3bbf64c0ec8392215bf98188b99fc484f9dbf8427f564cfd134fffed107ffd3b3bc5ad0505c36ce4c48846af924c64851f5f3eb5fd657cedde665b8addaf6700096b16e35cca53b32555e55b2d650fd1f0000ffffec34951bd8050000", - "bedbe88128a33813f7196383e1d80702": "1f8b08000000000000ffec7d6977dbb6d2f05f61f0f6f1259f40b4366f54999c6c6dd227897b63e776f1d17120722c31a64815806c290afffb7b80012952a2bc24767b3ff843e2d930d80683c110a4eccb2809d34bf7120613169cff22d264e2d7d0be7e3de93bee642a46f6c949b34f17edce9e77364d0219a5890d5452ee2c2e18b798bf20ee363b23dede3ed590fb59140827dede01428df00bf1f69b05a2c50afcfc9278fbad0241668ec773e2edb70b0499393e66c4dbef140832735c2866b7409099e33221defe4e8120d3e0d8096cba6af72e4228a39101106f7f0f2124233224defe3e424846644cbcfd0384908c4842bc8326429a6c909478072d84908c0827de411b212423a2a00e4248d648c08877d04508c9882868072124237241bc835d84908cc89c78077b08215923a1d2bd8f10921101e21d1c20d4609278ad66b3c0b4dc92108c14d62a30c33604548aaa2e14bd8da091d218c40aec20681888258da39f15d62d30c3ce096caab09d0233ec9ca086aed5dc2d30c3ce09c381c2f60accb07342040adb2f30c32e08bad9070566d83921f942bc56ab5960c8368454812d040d03310de2a88846a8c53a05662473c25463dd02336c433018ea5253d8c25131f36730357e2d1c0f3378889da9916bed21681888450adc47d03010d38d3d40d03010e3c46bb59b08e294b45b0586924b82b2a676bbc00cdb100c86bae60aec2068181a1bea1aba081a0662a1027710340cc4d44cb67711340cc4d2712366cabfb4da7b658211429a1ac3f63e8286a1b191b29ff601828681981ac34e134164184c0d55a785a06120a6eae8b411340cc4e60d365658a7c00c5b1322d5e54e1741c3404c833b081a0662ca543abb08e27474f60acc481a82c1b4f06735ea9d7d040d0331b5ec3b07081a86c6ce55896e13416418ec5c812d040d0331d5d36e1b41c3404ccd50b783a06120a68cb2db45d030105303dadd41d030105366d5dd45d03034162b67d1dd43d03010d375ec23681888a9a1ec1e20681888a921d96922880cc4c6ca62765a081a0662ca6276da081a06626aac763a081a0662caa677ba081a06626aac767610340cc494f1edec2268188869700fc1c6580dd0ce7e8119494330180aabfeef1c206818882915bbd863531eb1448df16e0b41c3404c0dcc6e1b41c3404c7573b7836063a0c5ba0566240dc16028ac4661770741c3d0d8843522cddb2d30c34682ae6f0f41c3404c7576771fc186dae15bbb070566240dc1605a982bebd96b22880c83290bdd6b2168181a136a4defb511340cc454eff73a081a0662ca7af6ba081a0662ca7af67610340cc45437f77611340cc4fe52e01e82868198ea31468b82378239d71a0e4ab8913624836101056208298c05194c2d140c1f85592806bb5420f6fad23034269553c1b0511aa76230353818324a333839a6660ee34599ef8e061d2a701741c3404cb9458c13a5f189068b1b13cddb2f30c33604cd3c30b06121aac60fa3466906c7605fd44862e028bf9851cc51e5103178945f8aad0ac3c69c600ae43483ea32d36123d005ba0566d84850d68151e5d45887c1745b7711340cc454cc8391e5f44bd19cfd126ea40dc960bac08532528c142f8c9122366b4c044c552cd4c6a033276821439b6b760b41c3d0d89791ee631b434d8d19764e189d2bac5360869d13e4a5c2ba0566d8ddac971fa32c61031ea2a49fd8e0f438c8294f2c6e4b272b841467119dd98fb89bda8c825314814beb15e729b7c90b9624a9b4cea224b4c669388dc1fa17790c8fc9bf88d393239e5e5ad20dd2107cf2eef0e5c7b7af4edf1f1e9ffe74f8f1fd4b426566ea6527d0cf847b0e73e117473d6761b88783cf1048cdb5999351e17210697c017e42c185d924e552f8820a370afd76672fa39d4e77edc848a6022c21791448d2e3aeea6a0f8f91dc6e3a54f8dc6eef3834f1b9bde7d0d8e7766bc7a1a96f73bbddd97528b7dbed03c7a181cfed6edba191fadb71e844156c3a3454255a0e1df9dcde777a31486bea073113c2829984241416735fa4e3499a4022171c9210f8b293cc0d383009af621843226de6fec4d950813499c631251f27321a8345a81c45c29df07422dc240de148a61cdca9e63a59d69bfad59e5386d32668e2333e9c2a95c28d2119ca118dfde4c7ce53e9a92a7cdf674f996f467b08f2f032f995a713e072fe1244c0a3894cb9ad06d363bde8cc26a91625be2fe71348cfac0f70164320b7b648de84359e1b42907226c189fd5552d1de1ec402acb394dbaae1a90fa6b98d562f7de2377b69a3e1d8c28793b4ef6c6dd9b16fab5e083b76bce48902949ad8f134e0385fbfc68585274f3a5b5bf1d696e96508675102792f4d391a67f6090ad8893b706c528c337168e2067d3a45db19fb533dd183bb9ce8ff00176af96d986921999c0af702a5d48c0f1e66fcfe677c80333ef70774a8567adba1673eb73b5d877ef617809329bc451c25e02d24246a76bc669651964463a686c65b84538e5033a3a3f402b8b728b82f4b3c0e62922622ba806775ec570f13fefd13de0bd24448eb221f0d2644344cec8508580cc25bcc9ecd4078270b1905e7c25bb0a94c8fcea389f7a849c76c76aca86fa37124bd7d7a9626f228fa02de3e1d47c987549a9952824b2ca3431e856fa344690f233189d9dc7bd4cab23e9d9bbaea05a86942c0e278c082f3b5adcd74fc1d9323970dd4de9e2ddbd45a6d6f970e601825cfe49fc053ef5133cbfa1995691acb6852aa45d9321b405ca92dafebd30f0be9864c3201529c400ebe494298f55d5d2eb37e582c5be45eb0780a4ef629cbb28c7ec6fd71f61d6e73e832f497350cf7791ace37738f23198371b6c79c2582e9fe09eb57e0d6110469121267ad24116316c7242ff7eb91b7c943c74cc8533911a76350e1862b278212b746e599cbe86204d17024bd9d265583e8d56a941371043c0241d3896eaa7791398ef2fd33ffd5759e6b869eebc89fd143e5b99a0e3d557ff71d7afee048eecc915cfe8d8e448cd2cbdfdfaa5526d4fabe67bf726a973c8b93adb4ba537635f7e84bcaad30de64c59d7cb8893b5182e05f15598d61dcbb5fa7f30ec6299f5b1f051b02a1c422f4d40677046c721a2553018f0b2c8ca161600e313001a1f318dcf1a998b0c4082b3460c1080a5c48169c9f8ab970ae73633fbfb05ecc0365a616a1e026d3f1e930a0c4b2df322191851cedd3266c2ae074186cb7609792b170ac8685ed27af814dbc1c510e098be996e3d2179450eb4dd2f828b4ca6a8f1dc5fc00924509845576dd1050d2ff1e773a86f18a3bbd34eef4837f7e9d3bfd80eef4d8ffa08deefd77ec61934de644469d7c865e32311aa48cd76d49a1eab0aefe3d1b8347c6834687646b62a32bacf62eccf97d1ac2c6cdd02caa28ac6f7e6d051b1b7ca83a7cc178c412e991b3782a4635fd3d7499fb46c2b85e07921da7666ddc6bbdf3a25ea7b6f2ef9dcca35cff9d6b3e2e5a9e65bdf70f21c3fd1f36dfa38f79a10e981d87be557f771cfaabcfed767b0777bb7757381e1d91f069a006d45988e904b8edba6e313f0eaed5e92464128e80f160e483ff64515ac1309bc429079ea797969236b892f121c83ca647653083605ad1465e251238f17d1fdc73986f6d6d542f74a167c9dc76b2acbc552f90e30145204a869eccfc4d8a36eddbab3996bb5e21bfdeacfc5b2536895900a3340e817be459187210a261a5dc92cba3883562624428511ea7a123207233d9502fa401848339f1c880892868b0304c9316a17ab63ca069f262c49221786b3640d3e4ff60fe71e2ad4f280d23c10631849ecc1ce30ade3db8827b75051546c5ce733ff10efdc44bed1776d12f3cbb6114bc9033f136ba809f00420f6ebfa6fe4b820fd5054bf5e1fbe2a3c54c78adf63a8f8c76494daaa0a6b2971b8339390216924d4cbe91939721afd50aaf09e59712ff516b9bd46dfe440ed2706ee4208f3eb2acf7ec61f5fec3abf7192ed837f77c823866c93006eb9569c23d9c23c824af0b370b352516c3ed0ac4ca7e25acc1dc12d3c9249e47c9d0922388b815a41c73dea1a2a91d0d845b6bcfef30185da33fdb405f49db8d2235d0381256349ea0944eac5891b046c02ea2786e458998441c42d556b2ae9311ba187138f3c848ca89f0b6b7e508a41e6737e54392515225383a01a896dd9b876577fff1f31bdc17bfa87db1d3c465f6fa215ebef1defe45398428d1cfb21e3529131e09a38b4d11ad32218f48984972557059097c8da39023b0d03fb9aebb0c514bbec81af3861837daa414815e11a7667a91bd7e5864fff0def61a57e073b5020f1cfa93cfed9d0387fea0fe761dfa97a2ef3af4df3eb75b07b8407fbb72811ae86514be4ba789b49dcd8b8f830069d69e43af5944c733bb2431663218b913c6d958b86a1b72b221c8a3844dc42895cfe12ce5f0511b7539836dc17ac147be7f95de6b17f775edd21b5a75ed2bfa4a245f2e471772e649fad714f8fc344e99da6a3d7e7be770a39863b9dfd705ae79bc00982fb608955b5bb73db49381099deb36fd094b36c4d52f2ab9bc381a8ea4daaf8fa3b14e62fe65277069bd5433dc82ceff4a57466310928d270e2561e88ec7ee7c3e9f5baf5f7befde794210cce67d43fbbf37ea3abc8251ca43e2d940e7677103a224aa8dacbebba2a3348e42ac4828f029f90304f1c8fb94dc4bc6f3fa7695b5abfda931e0c0cef574f369729e3fb0582dff6ff76d949cd3854cbd4fdbf99ad896b3ed1f16d295aa64f629a306bc7d26f95bdbfc9cb324187d53a307ba28b61ae1fb4942dfd4544c2eeb767d51270add1b73b4c0ee18a4a6333718d27720041b825713e35fe55d4a470ae98a68983039e5703a466da76766dddf51a69faffb961f948ae5c522324879089c64e66cffdb43fcf30fc73fbf61fcf3519f405a18e0fcfc8f043866a9fd774639376adcb7843aca2bdc26d8a1c23fe92b83968eb239bc25d0ecc18fd295b37ca9f4e0f163bc41c07d4d3f817e4fe0bbaa9b9dcf39cc3dae7b52935e2cbb9295d0835f1f7a14e1d32d3603d3944f194548bb8cef08f5cc145a882b83587757e5788cd82a40580e2a255639b3ea90ba24e65ac0e814b53dbd2eeeca05559d5b5bad66d3378869c07a733f5642c44bc69328d1499d776ce65aad66b39acf621c2c314a2f93ba3b5e77b1a3ae3f7a166ad6bcbf7f63f9f96163f98737969f712ff9e5a64f79f284d0465ff95dc7bc6a6ad9ea36bb571df7c8f1082c6c90751131eb5f442de87f5961145a492aad79047168b1646e7110d3580a9333fde5c1eafe61abfb05c399ff3c4cc49ddd17fdbf87fba2fff07dd1dfbff3be6802d1703448b9b9e72d945d9723d92884444672ee50e9831b4c398744fe773f4e5ff7f53bc539370aef2961b01adee8e70d18185f77c98e1cf26818259e4922ba419a24a02de634d59cefbee6779bc694b21aa5bcc43d8c5ae956c27b9097293fb7ece3d9f6879953b3fdea84e7248a63e5416a129fa964315eb995ee602e419c5ef2484a48d4f162bbc2e0c09411d49d38aea9e5055a7f7eb5d72c86f720df1c6e6d557157ce96355f23ca6735a35bbe07dc31f780d56a956f0e57aefdfe5fb6bc0ff1bbff9feb1e2bfe8e7ee38f9bfb8d937ebede6fe641ce52fe8a05235b6f2efe9305d41f2e7f37a74a9abb188f678e93ad0fc54d82b8f7a611022f7aebddf049f3fa431c1407b8abcf6cf9dcc773cb2c4f08adbce72ac4a3fabdd53f1e628bfb7f30fe075af09fd75af04bb8384ed3d87616cdec9adcd4d29ccdf4da4e76ddbd15fd38b9e2028334d1b7ff798d1f0cd48286d98425a147e221a18361ee5a565d0dad7ad56ebd36f739674998bf03911e8da2f1b8f6664cb4eaa87943c563355a7fd2199717792f74ea856c87c5edfdf51291cb304bb376d17fbd1df5da8b4574bdf66291df5c7b7e10b85ef9da0da39a3ad4a8bf48e3984d045486f4f354c8e86cde500600896c40523758af37e4e295da63989954cfa35ab3bc8481488373902f72f7b3eedcaa4f0543960c75c7c96f47fa645a38ae47f58fb29ebbc37a3ffbdc0d95e9b240aa7d71c2e4a86215b4585bdefb1af75d5b7a39eba5d27fdcb4743919e8e1d5e1a596df6ead453f9359d3f3f3adf5749bdd6d0f53036545bfdc5651b9f09bdac2c1fad2742a49f46014c5218704692bee50ed547f3eec547f5f3a82a753b9928cf8d331476800339676ea8e52e9d8f662140999f2b90799e33f599dfc3f69998f290d099483cfedbd1d873205ec3abd47cbf975167002ee917e89c96ff67d8220a18a7cfcebd13b0cdcfc56df274bd4b0677e5b916788e62e5869107ea7ef930a8564b684af5f6d09fe42354eedd342c1cbafb624e6798c8013e8fb3253ed8fe1c11abfdf1a695a1d46fddd9b6feaef182453270ec7346095aeb5673d8cbf0258640845b07209513b9f318cf5c776269019b9495122ac2d11a471ac372affa48f0e2cc103e26994fa27fd8c8521daa8366d570aff2ffb2593e026e9a5ed50527ab654d587071158239bf3c218ccb3be25478ca23369a3214bcca094cf6e3db9b565afb4704d5b8965d4ad760adb251dfd08d332152c03cf6a9b4e6a1bdf68f57561a15ffd7fcb84ace67dd6e4db6a353cb2e1c7a6e3d4d703fd7273747f57db842cd3cf65d54ff52dad9244f54cde5811af7229af2dab8eed1b0a2a1695c25b3e7b2cdb40a61d85ee4ae9f85c8cce4a0233a323a053b0b5c7237c3860f64e875aadfd26b5daad03da726ac94db7ab0f9072a3be0f85be7667875aad4e975a3b6da78e5868e3eaec9d3fca657eb3c77eac37b61ecb1fea0a7f45e284f57b1c0d4cb8523814938d0565e65059a23484cb67f9b3544c600a8fd33c55e99d0095fd2ccb62b04f18b8e94000bf608318680a360941f5da53ee84d0679cb3b9d3a721a8a044a68a4a49615f845ea45168351dfacdba96bd5c53a622a8a984705d154e905366e887488a2b083de9d755939b8db94e63f6ee11f826c74bde24413a8e9221c154cd499f9e993c521c25709c7f4a870e58703ee4e934095fa471ca3d634bfbd4da6d52abb5d7c2c9a7f8ccf2b7289423af65b04d255a85fc0b363992f3183c32984a9953d5a94cb568891d9e9d0990aa399af44b1a25a6dc38922a009da451229f5f5b2b8aad76e9ff9d9d9d5554e4ddd0a4d7e905f0b5329bd5a3fc5a53daed26cdffd5c9629d6da47f606134155ed3484539a1dd2c9533b49d52b03285ea630133db504cf2ea74f2ca54c9f57194570c82bc4d87b30c6d700cfe41b369f6e241ed7e8aafafeb4d3802dc7bd68f93fea316b256befca28b05b0b265960444b14b2fb96318af7157f3845a3103f7b058f6efd8a4fc8ec26f30385a6923f84f36351f2aaf37608f41671fc730be458c506efbe6c0a02255d9d5eb4530f0504d3162664e202b373b8fa5f3805cb51f238fd23ec0fd668fff9887973d9e7b7ee6c309efd36203a879aec3dc28747ae2eb571b473f04870a77194e31a77eaa5c610a53a1760b93ce8d4227538d32e7182b3db3ea4beb8f1e3a8e74a32488a721081b9caf5feb6543884145d54e6560d4665f9c4c4ac382b6d993ae9c086501d7cff3aa75cb2b0cfb8ae92f4b6d98feb28889ef329a802df3a3d8bac13a86bf3c846d1c845cb472fcbac2969cac486c2e1ead1fb6307430bf6410a7817eea4a139f5c0a8ff4cc1b62c4f77d811b6390c65b5bb6e60b4f9d691ffb647b9b3c16ee2815f231e88039d6f3532c633b717ab19b26e904125f520506712ac0e71a06ce53ee330d9b4ba8a599fee5e8f0bd3b615c808d018c8a8e049c4857edd1fd1edfdae23606324e96d964fb52106a3bc65f6c7228f6a3a67313a9d60da530802fbe74757d90f9eb511e00eeee51ab75b04bad83729059a62e63cc356f70ad0d97ddc466e113deef15cb7b3556646a91ad4686b21c19f63313659bdc5e3108a60cb2f12b9ff9d0a001f698af1f749fc5a93aad2f1da4f926e8760b3a6ac24b426c7bb7e950f63ffe6e93ca32836b06d70ca8a8dd6e771d2affc76f773131e113921fb15bbe0f5b5bb678ecc36362bd64736a1187c29356852834553ef19b48963fb69a4f49933c968f89473cfdbf4379c1e7399f6b3e473e2bf82ce7338f3954e8e129beeb73adf1bc0636b19ec5711ae4d6d2dadda7d64e935a7bbb251b2a53af3fa768adf889a3e26cd26e53ab7b40adfdbd92da32757960b95a6d18af2b6dedb7ebb42a72ae965dadf683f9a452a1c374d66aef545497c9b96ab151f59164c179757c77ba6a35b65480da299f04cbe45c71b279d1a792c5ab13d7c4295273559eb91239571c97977fea377be9eaf25f8f607a69befc83d5e55f123e49fbbd18177bb0b6fc03fc7c95988bea8131a87c018bd770c2181ccad619cb2f61890a73f9e52f9a5419f335ff1397fc4f428d37a1e28627d4089c3e1d54ce7ac2a4466f71367d9ea631b0644dd57a907a2bb5c17ae35682976f3a410fea4fe3e56de04ef596eceb567acd317d55f16ac0b8a6132f34df58dfa6ddfc6ef41ed55bd337e95a09e8ee466925a6bce3244ab5be2228cadf48ba873a56228f7bac09c3927baca00803f28c93fe7033f803a0c387a72577f1b4e4ecef7d5a423fd74d5bde66b8b4f9d7af36f77fe5e93812e038b65d480b9a388b222715dbe02c249f2f029bb909cca4bea01a30198c14275167e7e5ef1fa46569fd5b06578a07c56f2af4c00dd3049e2e6f9e7ab6f40d4ca5152542b2245003c19579c1a5c54b6d066701eac4eb388e2b4790d8314d9d2cb06de633974d26f15c0d82fe9d3c077be128e14cdbf92b587f7cf93e953fa5d324d40f30738464f62bf8fad57e659e376216eca29a050393068b9904b57fce96392939f3f162a8425818f2125a79edaac88e21157859121ff9fb8494d153bcfebf265656567c02c357a7cbcfa04f3ec609e77f8a21fddf3c9d57fe2045940cd519b6a766184f0bf8fec119a8f9fdb4cd26d136d6b2fdc3a25467f6499d015016dccf224d6ca7b7a6fd83ee829ac6c25e4a32ff5643813fa1a16c28bf80507ab14f776b71e341c9d6bf50822d587ea7a4aa06d675949fd421bd77ed1cb972f6149bbe7c4e8f31e7da4bc8d927c7ab51308e6210522d971beab9428579b5adb61e731ff7fa5af2d78c0b3d5709779b5d235b3303ab63bf92b22cccb0c8cd2e67a3323dc73325713b1bd716f6165760c5cc658d99eb8185ec93a336ae6eb3abdf90c3703ef7ccbaba7a0b7eb5f430f8b4979b2a64cdea389ed9fc566ba2f2a2e83d8f8399fabf6724f2775f6f371cda45949c43c50d573d6cc5d84a03b800573972fdbf2b522e6dbdcdfa4f60f9c6e98fa50f5f3c6d798d965372f4b0d99faf7afe4a1bd08e8b767fab9af294164ba75a02d6e4f5482eab5f560a576d59352e968561fed944d39f46cb37af412fb749f72c4a42fd4a8a2dfd27523b26df4707e5e4171f4ae2265deeb79a265f5ee25592e425bab991917b9e929bf221cf86cf6a1a6d32adcbcf3f96afabe7d911b9d6a322ca942aca948d46f12a7455f044f67b1beeadebaf1d5efd42b4dcf4a5c45bbcd2ec8ae940486e376967a7fe9b8879253c7f33a878051ab26cb876c23edb7472bf58c931e463b03c0ede40998ebc16d99a3a39bb13356ac9de4ad132295355545922b7d2589ca3eb1402bf5df38e248f92e19ab2fcf2e81d8c582570b893a12bfcc89a36937ab8e9909522c4ef55b51e2bdea5c6bbd47557e376376d323be9dd283b5e5fe3dfa4a7bc27dea146bd6b7eafbecae6b3a6acc8fc6c525766ac657e563d66b1a795733f33f02fc0dc3b3a02fd649583fb61b95fd243f017a5fdd33b025adc48d6e7f339d0ca8bd19a3803fb089c8c9e16f790639739b643cf0b020757cc93e0355e3bfe2d92235ddcb14f811e81d3cb2f98af6d9589cbe8da539043a8bbd10ecb6bcde7b0bea54295af36c4300d74a6cb1d823462cfe76f429bf03495fa9d7b7a72d2e974698bb6fbfdbed3fbff010000ffff0520ff83bd7f0000", - "cb5bbc1beeeef73181bb7fdcb9f346dd": "1f8b08000000000000ff5cce310ec2300c85e13d52ee600ed06e2ce9c601b8439a98d622d891315511eadd19c840bbfeef0d9f777d555caeb8dae565260c1fef00000c57eb3226d168241c8085114ef4a8a216d986df2d49110d309698ee2dd59833f1d415bc5980735d0f5d699a77c3826a9462e962a189032464431dfe1cc761f3cebb7ea69cb181177ad24885ec1da0f59d75fb060000ffffdbb04808e9000000", - "d12afb564af00fc492cd39248af5c289": "1f8b08000000000000ffccbdff5bdb38b338fafbfe158eef3647224a4828a5bba66a2e2dd0d225d02d74d936f8e531b142dc26326b2b058a73fef6fb6824d9b2e350fa9ef79ecf67bb0fb1a4d168f47d66341aa19b8887f14de7865d5e07a3afefd2985fd39ab82c1bfab8733d4f276838dcf0c9703ce72311c51c312208c7f7ee3c654e2a926824dc6dd661b7d7712252cad1c6d30dbc2055705444e0fb023c8fad20fc16248e20c9b649770284ef1326e609774427b8be9ede213e9f4e49905ccd678c8b142f72d84896a1819913f154047cc4e2b1b39324c15d96b9c3f8f20b1b0915f65d4ae9314474ae9358c4e2ee9a75447c2292885f7546c1748a98853db6b04b121a94359b394a85e86771a616ce6f71143a5d4a292bd2a745bacbe7b34b96b8944a9cf1d86156858e20ed674b9faf6aafdd40d8d865f06771877200e07bd99f9c2474e86f8fe30471dadde62f5867caf895986cb75a1c276ab009c486dc271ce36d4d5152201b29643a61898a49901edff0f7497ccd1271a76921c2a266ac104812802227e28ec023248768b309455331e47e5eb84c724ded5c80c92b4b45fe8909007e0ba673763cd6703a4485f9c2c4ead2899a1924c9eb73234c14697471672e46c8227d56197694b2cec5f5184abab81ed37b36bb16775ea347e67c9eb2f034feca78ea0d7d1d3ee0d7732183f137968ca7f18dd7de20a34990a4876c2c8ebfb1c4eb12895801367a24e2df8269140e622e261e4c361db31f27b30040e6294b0e5464205808b9d258fe5c0749ca423962de0789003a662c89c288cd14ae643cdaf86d6343c2de30f6350cee06513a0bc468e2357a0b4ca05645f5af65f5a331caab1ea57fc962d5d01254360fe13451bd2e3a95f24969fd29cfde05c624a08d283d0a8e6463869d2b264ea3194318379ba2631aec45b7d96c880eb4337cd90d64479ca9fa4054a56e1097b7b29d49352ac4545ab5d9440dd131ad9765c577b3c9f176349644ab85b3d944010d9a4db97c884ea9774da43d3af4fc6b36f33547742ea3abb7f13cc144b58e9e6451ba9fc4df196f362b118861ac9b33d82eba85060bb3a0e47145675ec84e50fd364147c1513edd748ff4c7688604260c7bf2b7da20b4d12562915058beadf99fc633d6af8bf4ecce37935fe8ba213189523976846e8e972f5f764942bbdbc90bbe9db45a381aa304568a6693e9f13589522286894f12224c0334baba1a8dde0236b03b1a7466b1dc9df49a14b1145640d30edf4a8b2309645fa648c816db1940464522ce32c49662690d2051d94d0600d191631d2917a48bb18e9ceac82985808a546349a7a8002da2158cf83ed300e2fb8cea085d7afaf1f4754ef2c7d3d7348f5400f1789c32835f056811ad60ae0db9d7632ac780a1371e0553668886002da2c99de9c22e2eb61913b9cd5b2d9ca2808a6142ef86dcf701cf30f169908f40b690bd71451bbda29b2e61b8aa4e6798c8dfce454839bb812d11e951dbb908fbe5e5c393635bc1eb398064914b082418268d1ea5f4aad944577280079df9b51cedc7d02a7a904abaac3d61b06ae3beccb29c35c9a9ab8c9502cda18de645b73f08c4a4336291dcc9b3aceb41783c8de3a4b4b57f2d66718b11d9d61a47b741a96836a3743fe2916048c8fd90d343e8465e20b831cca1449290804241b38823c3191033273189546a7099e6a9ed2235a65d602cd4b40d60da22de6ccade95d40c133fcb1abcd9fc0a1d8e1b947e4532562ef171ab65488f5b5141dfadac20f44ad049e7d7d7094bd35d769db05120d3cf828447fc2a6d36dd390fd938e22c741b862d1bc53c8da7acd9d41f9d9b20e1e510722d6cce8d42e7396ecb6ee54fd61a41f325c6192364f1ce7a636cd0a0131628df063c9cca95bf2e56b1cf72d32c96c48444547208b4bb1dbfc8396b337de2560b4a4aa8eb1257f184051b9a830f63bfc098ca75336951f79c0fdd56dc727dc72d78f661d7c7498ba62d57d6da8e1ea67ecb258ebb9dd0a4934ea311435dd2dec00b364d999350bbb4ed48b18e095edc22d672cff98e499568973604894d2de311ee7c89238e5c17cb6c6e0bc929b9972471823ba908465fe5bed0e82d2a9207ac0496e481259329ab7b4a76e9fda258394e54e7fd74dfc85c6477c8fc2c43b7487fd346d71a17c7abe6febe86b0187713f5b3ccfbfb32f33e46f70bc2b0e2e02bac730cccb39c4c0818e83e4a24337dbf2063f822906c0200823dd52e32d04f0cebed856cca04731260c3f3a21896ccbf2caa61cacc8b5445017590ab4e74d893cd95af89b002cb6595e1c583739b367aa4ae8728cc9e53d3985fd95ddab7be4b0c879265b9917d44511db930722df7143c90621ebe9406d26b7b15905d7618dfb0e475903284b7bfc8ea7f19f2969bbaf243f8b6ecf8d6921d5325c714b263ff0b0cb22fc30a4edf532c618166c7aa0a4980b8e5be4182be451cab3e9164d8b2540253e4a854af7d55af2339bcad1de9a0b43350d76d158bbf64d6453b31ab92428ed84bdaedf3bedb723dd7f5dcb68b5596ebf806f5ba44ed2cc12dea9200e37cc823dc49e797a948500fb7147d1fe83a3a1f0eff753ef4d7ce7d9ca1f373dc47c3b7137f3643698afbd920ce0683befc97edc6d9ee2efce9cb7f591886fdb09f85713fbb19c6d98ddfcfce867176e6f7b33fe37ef609fecb8abfd9a74fd9d515bababaeae37ef6e60d7af3e68dfc62d95e16643bd964d2cfdebeed675fbff6b3d9ac9fa5693f3bb9ef91df17d96df677f6fd7b3ffbfcb99f75f0fa1539ab25fcf0f4243b3ccd0e0ffbf25f36bdef91cd8504ff2ee7e65fa5ce785588a4b225029a6c2f8d9804440c6beb314be3244a87898fe462c89a4df497ecd1001301df62d8f5fd9a5c0728a85f528918f6e432b1e14b841c90f03a0c309315fbb71b8800e14e9c84110fa62b3133bcb096b88f2595022bf8b43e12f41d128495b063f25d8e6bf927cb6a26b9e4e229eb80ac873ea8f54bd02ee134300356bce0dba2d5c27f0d83a1f0fdbefc4b75c083004aa8fcc51acdfaf970789e9e9ff8ebb89f7412763d0d460cadffeb7c989dfbbfae5f11d7c59e95707eaee27256c190290ca71551d7b5d8252de5b4e8310a244bd4977fb5a02365301934c8a2c542ee47b201a4e8e7959bc708b3c0d55aadfcce5ebe9e15232eb13631d199c6fc4ae654a230309f6c21c93ceb4c83541cf090dd4a8efe25ed369b671dc15209b48d196579edcf488249099ef036ed95d9fb5fe9fa79b84edec81ff9f18ffcb87fba58277fc0d7e6629dfc49d787adb6df3f0fefb716ebe4b382edaf93bfd5970e315604759480a8fb1e9108b909489c092b90f688441b40726b9d4445526b9dc48cae7fce6458e2f4fa40e65544d2523cea7b2a09f765e254a2e8b67ff7efbb64e3d9d662f85f41fbfbf9bcdbdde9b6cfe7dd67fbfbe7f3eef3ae0cec3e9781fddf21b0bffb5a0676f721b0df7d2efff654606fdfbfef01b66c783eef6e4186eed6fefef9ba4940e7e95abf9c6892b0fc5dac4764ce4a0b4dc8ccfa3e67729d384602f785b5695a5a3129c1f4b92716961a909526ed08cd1961b80fb80af9951472a127d9ba0fec6aeff61a8d192a468b7b7eeecaa9624f1e743ec499fcf171763e44c37f9dfb7249c5e7be8c85a51695b5db72d217c338cb78962559162c30c6b6ee91d91c5b51e2b07dbe7e7efeaf5fd75afd0ec2d9f0dcbf5ff872069f9fffda74155f3929b7df8c95193301937979776f3611a343e66332554258422dca39bee772b991729c5c64cb3a59292c4fd850eee03eb518a96b5d36d06037846986cec50d957fb2ec7e4184eccbcec50da42dece6b8c8c780e6029bcd119ac88e6c3627aa2709ef5c0484139b25bdb35bf19b0cf49f6e6d794fb79e1530df4a2dfd6493caf5823de975bb0ddacd32f664b3dba5b4bb7885dc4f2ee9922eb16529d9a88cc2be72c7820415aa8117f4f7df7fffbdefba2de6b92db7059ac357a84b86eea74f2ed9f02b98ec2d4aa19234d89964b64d99cd95e9ae9df0c925cf56a47c72c9166974edd4d7487d11f7cec564df847a98840c6a1931fdf9c9259fc91b139041cec81f45f8934b1246feb422f2981943396d26c9275d48d0b84a3303dfcb7d9f6e504acdb0ea074a337b7a13ef465791f8249b85614f8d4183a91e4f7dd63c577d26c872c0e538ec7501b8060dad510e4b8a5a48fe7db9f55bbff77bb7eb6db0a75831e7578c5c323a60c8dd9f4fa79fa0ad1b5d5cccd0417989caf1f38af299f7d157a6354b84e33aad8f140541fbe31d1a486c2d86876c2507c33a17e1d0bd62c26de5bab8befbf1f4b5e491714bf84a43656974f23969a16936b56a1c18fca2c214943c72aee9c18d9bcd1e74f52ce66222336efc0ee110b8014d4efa00399ce499c90db383c069fc30bbbdbedce87689c6486bf67196a9af5c63eb1c0547db661145e209e2b4b7815b1c3fe1f9a46f5124da095eef6d1059bba4af169d8ddfbd8ddfbca7bd76f2e4f9938dc5155bd2464792fd381e2f29a475fcb2886898c56df14271b5e6704ce0680c3d2f576b4a99a15e6822dbbd057985dc814b86ee60000b913b88dd956b916ed3564f2d45ee40662a2f83ec01061bb2a727933811f978cc11fd1b986c24af910b912e71076a21d3c1dfd4823470c967fd35b0163228b732fd73b6d2a2f703bb62b77ad1d0f97e98d1ce032be040123770fde5f5a6a736d376af801d28e865785bcee28653d145be970b94dc39e50ea8d5eedb5a89d48762026f86382e9d40c141168ce65b46d77787f1aedfd702e1b92f45c2ec3cc52d494a7f9d7c62d47d17f07990dc5decb3cb043e0641329a5cec5c27d1f46210dc5dbc9b7376f16e3ebdbbd8995fcd537171c2ae059b5db2e4e2782462f97b147f5311bb6c041f6e27bd9e4602b9172e26a7aa145982442e511bc412af442b714a6c12934462e72f96d35d5651159388c45a0f22dbcdd6864463d4501a76ab31e1386029960e7dadcd97a2c7a02e2195c3a692a2a4a6dec676ab95e0884ed070833d25898f57e419263e2d269e9e3911f09d3515a8a7a8826375f65c8dd487c12757e97ebbd7a01405f4ca3abe5a2693c418f70350ca79f5392a34d919fe9dc2b2eca78b79748655b81fa874b1779cd8fc350c286b3f34ab2f93094b3c37acd5ebff3a0f5bbfae2b0955602ce85724f036e8ae25b6291294d52d856ae20b6c1562bad33e1c511baadc22cdde4b048623f387764817aaed02635d32453866cb87e27d7492731bb55c49a35b654b347e25b1bc6774cac89efc5b4ce32f0ce1fb3cc42acbad3ed431ace2a250360e7d12c83f51ae43855db2b7018a146e66a0f031316624d5e9c6e57c01e6af926c52a29f48b1512a3d4a279531d054e62bcabf4ad4825e74cc403f8a49a043a0efb1aab6b109c0914e8e20d95ebf6057a2965cebfe0bb9ad489f6764b2bbb14bdcc835eb497517a44bd8ca80b0ebd497123caa9487302435188af1f89a1572b55ce8d5444c0b39acd79502dd4bdaeda3b4384565adcd6eb7948fe4479069e78a09c3ba02ab0afaff3c8661ecd9a8ca68524b9bce0a7e2d1a238b16a3de7ae0bca9d0426e73299c688a8b72e59fcec7d3d7b6851bc7563d84acc7c7d3d7a5aa0859153b92e973b21f602ec8c9770d4b07bf53de73e9f396681bb6b88d9eb7644b902e49b0266937b843b82df093e7ada4dd2bf01c315b4b227145242629edb59eaf21d1eee1167adee2ed4466dc515c4f711c9fbea0dd7e4cef188a2893b0a997be041d405fc6b47a24a6691b22b027636418937bb92a7a110983bbe3b16c122fb644a6fd656e82eed86ba95c1f636a1d7bc39aab5121dc8eda3dbcfe1cb772b562fca2d74f68dc3a6028a0064fbb0798bcf8e54105791f25346e57634991b5d5c39e85892434c6e4fe86b1af5e42a06e81559f834a4fe53d4702f86e2942cc5109b4563b690578fd7981e443558e54a7ae823cc79d51cc4781402c3f8915182f5e21f7464a1c37374ae2b8895de24a124159e19ec9b4b333957626d3a2343e53c9af910224ee8d0a9924e29e29ae5f253f83ef3cf19962da6f721940169dcb006779b42c15a2af250b7e238bb901d44426d5f2e162989893a02ee961a314839a8452a47143598530b853b50bc39f9173b411583a887845620aff3d4475c257f86fe2aaa0610a87ab935575f774a4ee0a15ff1a417b10372cba5445b052afaab83dd5b110e8f5f24eb6c3367c4fabaec2bc5759feb5977fc91aaf92deac46af8a7de163f2d50a8ce1a3b2dab9600cca4caa5485e151b2a0c1f6b034d8092bc2a06e4265d7a84a872e915db06aece7e31de4c73346dd93390f83bb8b410c3fa77396cadf331672f5753a9927f0b19f44f2e72410f344f69c2dff7d578824168942669719651e99a104fb17c05e0ce28bd3f9c519bb389d5cec27172741bd40f8eadf12084b2d6a8984a5f88aec77569f368bf8528a920b9f97c5c29e8fe5de8112bc22672ed9d9abc48fa4c365d296d03c4eccbc7910c7a3c44c18d10f887ea5224a32e30f322e57f2c7a260b575abe5fd1ca50f4a914be5ac82fe114d3fdf06ab4a7a74051e22e9f139fec7643cd8c320007e0439f21dfcfdb52c4dbef9f7a449bd560c7d92ca3f53f9675e162c9f97e54a33858564c496a62a888124a89b7c2a29aacc29151b1ba33592aaaf0093a9fa8a3099e7a9f33c756e5281d238172fd3fc6b9a7fcd2bc2a7aa51aac5c91464cfa90e4d2134d7a1b9256a96f6b325216ebe5a0c5cde43690dc60ab0d9a81f01fa906c397d24590fe1487f8c6310f18730c40f4ab8ffb08a4a7e12cf9314e127bd8d2ceb6d14807fe861fd0a64add5c78b655d92be1e806cd48afc59c4e78241b07c1cfb6775fe5c182c302d25b7ff5672f46fdfea834e57e255dce144264c263ae11f06915f65e4d7af3f3816d5c465d9c6a6e63f27b3d9f299ac365f735bff30cbaa07b70e50a5561bb84093a6ff2344262e65a3988725e46f1fa4d1aed80314befd01853f42b38abe3f187203388e84cf1d97347ac08e43871177a2187115ea3d557c6de0923ff509f14ef1f93667b427f9d7d7fc4b0e855cfa92dd9f0764b71729b2b1fecebf659d99c16f25bd2d92e0e4e4ad4b64093e79aa23a474f8f5eb320b6ba45ec9c16e8be1539f6e6cc2415dd74bf27398c025ee4e5d5edeb988d2f7338bed8ed2f703b84c544c01c54b03a2896cc1491d26285a1241801bd7f76868a36b4ea8a12156109f9bb46f6c1b3c853c9a604cc470b3142be35697235bf247256d82bee1678b251b10fbac141bac26e6ed7fb8d216defffd4a1a01e933237fabe37f59db544d3626e8bd1c403c0c12ef3e0d666c37b8f3dce1691c06774e207ce7f0d4259cdd0a133f8b9324be2925495e48f1a9ced0c44f835467f9c452c1121b9d4c53798687412a7ca79c5552b1374d99e71eba0b52b6aff3ee0f4f4f3c77e2cd665e9a3a3b2e393c5541f8f6dcc1607d77775dd9751c42783070768963622a514e9e15922421c4a9035810cb4ad073f5c52e270c047389b6def4dc27a1abd47770aa70aca2612ff29441dd0618d44d03117d63a7d18c79f7e3b99827cc7323ee3c495d721da4c2739fa44e7015bb24f5dcc019b31b47af972e4953594a119e4908b5c2ba64368344bde0ba64e2b90177d4a2399940da44f57d28b381ce220c215e72072e19003675783d182864a01c77c99d4c52063a7777902203a9bb200ac2fbc488a548f74e195c91f4eec3f8c6eb9230bef3b616e6d664ea9d31623125de5f455065ffce48692ff7d687c1b57fdee9cffae79dfe7ab42042d0fb05e1a2646406ec63ae0eec570cc40b13ba0b97b86d177bd6815220725b5330945722b8180adf5c356c50ca9a4df9bfb90a8e4572779fd0cfac73115c5e2684a38da7cf31723beb6e4b60120994e0c5080c6219becf6f6448a4d6cd6f611fdc15168408719a2281fb6031eac50a0cf73f33cabd7ffbf68e128a1db7c55aaec363e18ce3390f3bce6e143a77f1dc19c7c915138e889d691c844e24fa2ec6c4d4d0ba512e725315a5d6a1966d1f837306d1915928d3b7328518321f9f205711ae0839fec692240a994be02abdba79a84fee1404525bdc5130634456711c5d6149de6812f02be604dc61b7512a227ee5e8cdd060b1cba9c5924ee2f93474623ebd732e99334f5928ebef8c121600c2c0912cb2caea9c30e64c84b8f6d6d755015fd2ce289ead5fcda390a5ebffcfbabe0c95aeab82db2adf3aa09cc50973223e8e3b2e0864b22d3a178a90fc8c55b753e73a4818178a705cc48b6139c9c7494d64096b71fb18712a477819777e64cb97d064195a8ea4431f93e56825e3ddf360c63c4654f19e58a8ebb8db89e45354a43503980fe2c71e7a8fe03aaa44cbfc66137e3ae338d90b461354d20acb21d7918510d6d15d2877d648898c329fc1afafe3401c291f93c364b2cec2e46cd65c94f5a9463b98a256e23069e4b64c9fe138bd1121866122080a16e085a91318b22eaaf674f67d5e23dcd3ee7654d8b12a00415140e58a368c7c6c348a6d176373d190cb5e5500ad9e8f719f5b50a08ed8162fbbdbfa025c2050601d8668594fe2330427b23abcd9e4e6462a15cde60d0a0897ccc24b2ada3d7c99b0e0ebb668b71751abb5c81b6251ba833515f61d22d972b9eaadd96c6f500a57dff34bea7007870f7bfe8b6e96c9df97bd5ebfe7f1e186ffa2276336fc97370cf161d7273219f7373c3e7caac19ffa2f3736a530462995a16613c9a59a0f37fd2c535fcff2af2d1ff79f7a324d65def45f3efbbdbfe9491815f30c629e791256c56cf92f7ffffdf7fe96d7ee11a0fbc210be6bced7640d24b078b9a16e146de00aa86478d266b3dd53268848d0e775207005df02fa4d0319182a4a5610736178c88a250433f7d4fac2b36eaf86a27cef439d6a0e7d6d2f7211aa9157362e55d765f353d9a0c3e31b541cbfb2cec53c651f4f5ff787cb27bdc4440db489a4c84f5e055cd95279aa194ad01a540e31c23a1737ea7a30385408861b7e29d8f39bcd15575c5465096cecaa71c0a2e5e20677debc31778f45e7acf8dcc311ed91986e124ee772f17cf38640295d9fec33742b10263db289e1c4532eeb0074467a982014a8d01ee9612c4771f0f2b91c1a53dae862bd36db6b8b647f3a617c032702d5d83be0e0e7d4141a91186f6b9aaeae729ae665426ec81c1478c62d82e8847d4997e884580ed6e0e5564e91192e1dd60708d68a08121d0683bac32c48ec05345a24b24ac9cb03863850d3af19edb4d1d568a735c961702701504a8f2492dc6e4157862af373b00f32b38ca6c5893686e150dc62b766622cab6fda2419767d4c900df2f28ea1186719f8abb1e2651557cc6f5971c2e95b8662d22dd1a409eef9945746ba1e9e79bc1ac646b9f9b4346c850f26b3fa9b82ce3391b17236e6aad0527229777f03d4f13dafeb197cb01e42402e895d13d8b403cfecc096affcb268698f36ba4467a75d65a7455131d7df32ef35c3b665468a098c680d60bc0a182b0bcf4440a8e839f17d061b6fa80d42065a5d64e53751b8cdb4cf86824c4573a05428667d28f8f5cec54d2704fc379db0416964fab8e2e304ee2983be7d24e8fabfced33584fa9ebab474bfb5c8e082156ea3be771e9e876df9273bd39fea235377a9e00763d4f7d069e66064ee3c557e871de29f872ddc877f6878de3a5fba1f959da76b9f65faafeb64fc00559aa882a6c79154fef959822662d5ad2e321374686e7db40783f6eeae4bd673a2db7903aefbfa72480e04f5a900bc79f3e64d7b78e69f9db5f77210d3f4158872fa3a69f4f222764b05dc3f5dd8a5978ab6b37dfa3418d8e4f7ba453e9d721edeffb6c8e90032723acf8a92f2443b6d6361179693f87cb1eefbe41a9af1ed5ba5ebe89c9c9c9c40f279e8e57fce3be7610bf01b38520b47aa604b1045aa9da46367b33201f93fab7809436a604819a4929aa758f13a4ec7c8a6b880d1bfde974be83942e7edbe1caaeb5121f8df89dadd1e5c8890291d890ebb652394e22c1be7df9213982a8e07d684288dc14d0fdc7d9d89eae5d7688c6652741ff67c85612a79517c1f50152d771bdae835a80e6ff8dbc02d2f72212cc096bf3464791e6af41431c3a7bee1fd250dd775345c5768782a6988289a0e37fc2c731d17b7ae353dd5f2a307ca97508dc4b85e79085251bae9835cd1980843c8a68f1fca1553f7b3bb00673e410b4559e6bab88562f825872237002c658325f99bec7eb97c0d629e9dce5976c6c2ec7432cff693283b09447632e798f4cf53dc475acd86cf53f42ee0d93ebbcc064192ed5c27d920b8cbdecd79f66e3ecd76e657d909bbce8e47223b8abf65bb6c24b3c839493617eaf33cc49efa91cb9bfac2fdf35452f2f1347b3338cd867baf07effde1c9ae7f8a3334fcfcdd973f6aadd85c60fceb7a3144af8a215ab9e1951b32bea09bbff737d8d396f0045cdc833b5c3204ed7029e8fdc753af4bde0ce4dfbddd53afbdb1d9257b27a75efb69b74b5eef9a0f88d9ea92c1aef990319b1b5df27ed77c40cc6f5d4b7d36a89f45644abfe95e969d635d3c45c37f617fed1c67c3737e2ee006a863df4c45e7e979dac24bf1ff92f16beb956bac32eed77565a1aca6a6627b91a07274114ee568270995439d04743a7ce693884e875b3e89e974f81c8ec7af0412989ce6979610c7246fef44b677110ccac148067d12379bfa7c3b4f89650a266acd685415f8da8516cbb2ef45b10c4b81d4484d422e0f8583809c11ca3204a710cbfc08e1f64420728ac28a43e624d7316c4bde87ce89766955a52b9254e8c17529860ce43c6162badb4adb995792436b043479d2eb1aa73d28690778bdd7edae6d755b81a4e0379f4c87bfcb3f3dc95a0363f896d99ca0244a25fc0c4f074bb0f6b0471bddbac5a0b84028b46b3db99c34280d3a0727c717bf6d757bd88efcb0fffa42a2c3f7d04e435f1502def068a3bb5d15845db7a5370c73938dcc73274def002fc9a5339c7b4cc8b2a1afd9fadcc5072cd6c0c313c4294a35f088a148761fb82a95a249b389504cd3e27027b5c66daeea79d96d368174cb2fa21aa13126a9cc0e7a1d3b6f8be78ea6e62d5a04fe1a467e1ff1bedd123dcf42aeddec19ab8e0b493127ca6f42eeb2afc14b0495f36c434ac9931f9db6e724fd616d526c648e17b4b7d16c36ba4657a44fe9809597e91207b253a862faf538aab8520409c728bf344871505a1c9ae6124fed11dd76c99525ef0bcf483126bf24a45f0ec2cd951c304adf0ffa0825fa53f99d112f645d9168d1de06264996f5361a948a2c936c0026027b6251f88e3334128b6e4c42654c536ca3b0962bd5323047d68d596b2382e10e2abab1a5cfd14eeaf2af2c4b41a29e2ab98d0271b9ff45de6cbaca1cec02dd5bde38bb0becd55c3652125b4485a5e8b84ed8b5b946440648e0be5c382fd114ae2279682ea360a5115e8438eeafd4f1c8154e8bb46333e675c5148f677bae94abac6155aaaeed60d607b4bb1dbcb0706d0730af2593f84d79962a245925f8ca8e34df452c2642323e12d330f025bb2330b9560e0ea216780b2c4f1812b568afbba65c492ebbbf2490908ee284d18868f62ec9b2e845a27c26c85e15b21688119e6502f4251eefc3cab97c8f1706c2769a37f392b6cf9b2fa7e54e6265fa72472f7712bdb0d808650f0ce306c10855ce048b15bfd9445a915fc491c1a321830e9ce3b0fd249ec188dc0fa6d3cb60f415316cee66177569c9bd593552246b0a5a051a2251ac1a7526eacb57f56122622f9648ec0c85865535c58e6e045dce50287d97bec14b44270ceeb24cc0bd3922c0a84626c2b64984b6a08198e9345221bf9644d66caea07201d59dd6742cf61e6a3d50bd5d23e3d232045d14965b8475955d546fd04836f27e61dc8d823abed904718967194a28273c5fc3518c182e6b72a331d2cecaae98b05c261f053396e62c4de12bae064ace7f3d8dadcbebca1b18b00d6567ccc59dfb462f277ba1eee403795dcb4904b84fcee99f2e3b3e6d7465ac5e17a6c6cb682023a794430ecae4cf980af9a37d9826445f1783c5f0ab405339786df557da09c210f5d49586b4d0df195aac8b60b7e24107ce3dbc58d9edf41352aea29deb24fe16852c74a2140e9023ee044ec246f1158fbeb3d0f9b0ff5af25c4e9c380727c7ce18565a73280b87d422996bf732c1749a3a12bd2362e74baa461f26cecd241a4d4c01099b46c1e59439c12889d3d409a653e732896f5296a44ec043e71b4bd228e669c7398ab9297f5d162e278fa6207582843961948ee279125cb110b2de4412197312368bbfc93a7127e0cefc7a14cf227ee5cc822f7122096041ca3ace7bf87512366689a4f871c7c15fd2b6a463e9209854fccbdb3350ae0d2d4bddea3ae64aacf60762f85ddbbdd882142c6f291e86fb2721fb50d18ab05c4964031b37812c248e75023f0b6ec13f230bc2ce23ab398b787b16dcaebb359e696e57f8bfdfb6ed2a2def1d258f20e059a22fff78ccbb40d000a795ca487257574656f5ff92cabc5cae8ce53240947c24495e068e02739fd711c891ea8811be484354b89c5b81b40b4a802009ed6d272f44e19923c16298f8255f293262c87cc4e58acec1f3ace5da51527322e8d078ebf9671e2482c92fe3f6425f8c5397a6b4c9a6314a72d5de0431f94ee55a0ea58f2d7674477944577b6196754942454797278301d5fba30c4454dd5e92bba4be8625a363aaf7ce2e49a9da38e5f7949add5386e6d46ca13214d2d23e9a655d6d4c6e64cfdab3fb7ce380f35a7349e04410817357c6603ea47db90c856f6d28b93f7f29dcab5b3827a55e923bd2f044f685d2b4f1222fece7fbd3381005087807ce43e0bcb8d1c58b62df12c5659ebca6296d85ad1e7bba366f6db1cdb5297ca76b5b52da373ea383bb94b6e2d6f3b5a8745f9ab682d6d3b5a4d5db58e339a808e8fd2277060142442af27b3b97f3cbcb69c9c7de7bb1ca23ecb175ab774f549c3db77b6b70d13589e73c44edde1ac39e15610b3b5fc46a6374cb6bd65c8cb4a30039fedc965b5cdceec2cede6632beed62c25b07e8bfff1bb1f5ad2e98340b08b3275b5d65ccbcf82290fbd925aee76202df9fc15f1b580c7f7649aa0d893feb6f30d195209f3faf30f6d54c83520989ef33fa56a09491e2f2db6b41d7f5918d3aec59bfb274e36fed558522011a57ad8f60783bd70e538e2d01572b8710e243a33c68f77cd05bb48afcafe5581fba6db009f74940b7ba6bc9b0e7b7bea264b851ac2292550afa5dcf6d4949311976fd7ee0b503ebe67665e92b6cfa954b08b92c7546d39833b85a8c06c087cd1193bc6b2e867892c3c19658d2e64540b61e68a4c0d13904f2b456b2e43182830d3a37386138db63f7c81e95bd676b6d7b045a2ed5bfc7dca0c4ebbd6716867d91dbce371ad55dc32c402052c2330710a11cce2fcab42e6ff607a0323f6f67e72ddc477d0f9d876b78d8717c5091b7f0b9073fa8ef99aff38e0451877b1f20b7cafc5ee61eb65b7e7fd86dff4e3afe1afea4509623077591677591bb1079ba9cf0f6d1784f14a1c5183f13956709b4e67a4e1951f2891951b0e4f4e7f47e964a11d05e0c49e8a9a3fd940c200d16ba853785abfb7358dafa70e78879f34e691965d843213d30e22dc672c0ba6d39d8c361cfefb77b5e8fcce9fd9dd725a1f715857272ac713281efa7f03d83ef4df84ee1fb998a97813d81e4da1c0eb77c8cd7f802cafbf088f2be0b288c704c062af01402372ab0098150059e4160a2025b1098a9c07308a42af09b0c2c94528bd2b96ccc85b7e45c7dde6c22779cc43337e2ce3ccb5c11c317a83ce8ad40f38e4cc5245601116312d0c89e03b1edda36a63b02c524c244c2bc62e3386128c6fd94fe25504462ec2104df120697bba79d96c2c438458104f8c224c5debd0de4758d69737741a0f7716796d2a08c69de19c08b190a47021cfcb140734c60a0359b23c488ab374378642759d6af616259d67e2f2dd7467ad7bb7d61c24c5ce276dcdc0c0b197f77fdaec7f19ab57bfe55c2974be00e376d208c73b5362bdcac6dac21617c42e4cef208334b30c89c0603f83deb44e9ce58b004745aed769ec6cb3dd112edd60358eca7165e8915fe08f38be765852ce8bfa0155a8964644f90208588e0b644cb45d72c89e29038ea412a5c161a7201af901df28c2a03711402dcf90973e0200cdb11ffc612c1c2f6759004b31a9be000f41f09496880c947ed27e14cc8595d55acf17e8b7bb211ccc31e965b8d8fa27c371f5e53290dd898ee0924d4328749aa437a006f977c28a284e68ac584a4cd26f89802e78dc66f522b5de398c4cd26b8617477e13ec461f18d5bb104880a131fd87c5979f38d240cbc2b50da811989b32cc57871263a634e8fad0700c859fe08518d83ed33013a5cb515be13f495403de20661e862f22b04db3de2a6f34b91042361dfd17f539a2cf5b3a0856a668c9cfb9571ade5a334f76add46bc85443b79d1ed2bff8c286957f248ba4c2eec69a80a4ccb82692718e32cb37cdeff6319385ba7f1ea75b6becd9a2b8366af308604db68102e6d06deb8f25c049d908d83f95468e5b965bb736aec4a3ebba402f6518c6a21879f7df564de1f65517e1af02bb434310f94f84eca53d3be41ea88d8819b0b13e6481cf3e08a694bff7902cf20749c8fcb99917d99c0e44babca99150d6997ef5931da2f4571515554ae90eab62d7aed7369ad43ec896809fcc45ac5ffae5afada1ea596dd49e1766f636b63e3f96fdddfd833afec23cae28f0bfc8c3f80df38625a85bf4887b402abe046faea9221234659ea936ee9893bce97dc2d959776d6dfd70edb24044c440f899728a207c6fb92528a449824dc7aefaa406b15972c17474b1e9f484cdf3214298d7c974496d9e9f69283e478d9bd15b15c96c665b3509d06def0e2aa65a85ccb95cfe4abab1f5c42be61eceba71affcc6fdefc20a3d69494f30a8edcab2b59a86b10bb456c4df49b37b220d74266252ca7684f3bcae9b0ac9ced6b47c7be7953b851fa643c41ef57a0b4879d378573e8abe253169c5fe19554e7014554e1345a55aa086baa0b27d2bada2a021cd2e87630eda1aba932fed83dd386e59e49a353555eeddd66b5ebe857c8fd13fc3bfd195bea3868d24237f7a76acd3ce2b9aad89f2ef955dd46fdb3c6f974cfa74fd790f2076b8ada75c9d0dddd554eb176954729c18c2f2550f1ed1a3f4932f4bb2a6837bf732df3e63db11baf7245c4fa42db552fdd9ecc32d1b988edeb942b410f198f1817f9dde75d49deaeeb930d55eb9af2c570435d9a552a8dcf609761542b01873bb38ab16974f1b66c915ddd26f2f7a96c955ddd2e7a95c81d4de92040e4bea44ce4a6699e5d97089607765df28f217e57910f15a8d30c15a6f196efaf99246e36333e0fb42256f929364ad9997654acc33d4dcb2cef34991f3a0d0899c92c33d7279baa5562d52a0373d3b4d183864965c9696a4ad6ba5e2839d702a7aa6413ee690769695eb2cc5f949cca2ca9eb9367aae49493a92afcc4dc8195858fe304bd42eec92adf04fffddfc61941ce0a23306bc2c5d27972b272e95c95bd94fb040643b7ace8b6924fb4dffc9a95b9d75d5bc65fc22d733f5b99fb11d94f5cb2b52a3f7bfa88fc272e79be12c1e663109cb8e4b795189e3d0ac3894b7e5f89626b050a18f845971077969ae16fc5f6b6d4f83b91b3512e921050a13726a482ff609272aafa743b35ead117f4f7ed94b7a87be2e290a1949380594ce03c5f6eb6e472231b1db9dd8edb8273f33841807205be19e09b7335094233fd0ab92e9f83dfb5dbbbef31673b9797daddc9773bfa28983157611a717a59485505b1e39205c162c4a5e841df093202ee0a1c06d0f232aaf5155906579412ba23903a188067e912713c46da176144831c897e3747f17638cb5c73fddf2531dc813b466218f9b82fff5a8c1dc71ec497f83175d28be22c5b7630630a44ea1883dc0a30b05b408da478552347aa737725fd48b8301a8feb4dc38ce951458d6bfbec97a9089a85a966c1f570e94d24b7a1806eb1cd3594d84713edea59052682be4502e3fb5190327540e745f44ddea0ebbd0d6504be0d00eac0ae0461271b66a18ce2a90da2678b175148875706580942ef2936c416dbb421e084d04e7fbac59ed900729814e9ed00afffb6b559068123c732cc5677f3b71c48cba09e7264d54e16b9efb7c83b4491ea4fc6c3e3f1f25d47d955b9a887187d8bc062b3b45c482130cb5674b78c556f34504b8ddf67dcfb5b98fe65a53e135479d9cc7da9922ee9e176afb6772ac0b6b4a187880e3c79da7aba84468f818790b47a4bb9547b3f94c9126c3415daa619e1d6f30a36e31ef5f108912dbc00d2766f192f0c1cfd25c7e063d1b7aad5554354e8eeb3745544b4a81caeedcf028916b2bbb7eb6d997db034452578b50ff41c5951c016db04fc648b6d56729af9b722678f3d55397bec296e178f806a58a37f130ffb4787c9a116d3d2ec605986f48169947e142384fbcbda1eaf12a5361a413f1aa7addb2b9d805dc7a9d06bb85033749cc4335aefb9b4725e06278225630bd88998bdcaf6cf04ba1731a86a8844edb145ae08b2f537187726f359c0a3ef0c354449b753fb689c21f528bea97b97476d4e493c53d77799ca20e2ff70cda046503711ff276b26e287ea25e252adae98a8033d568fc1a8c5546ee710f2b5de0c72ea827744cd4eacfcc215f7e0550675e250cb870ce064589ddd1ae3bdeaee9c650d6eb561b389aa4b3c52db6b65ed57d41713efa575c8ec59dfea491ca3bb354c90b0cfa7753dd469d6fff18abcb02b52221e76ca12e9366c510d71c318a7abfc04db7521111da827f46e45f1926ca381aac33fb00351a59a082a97d024cb5c845d29baf73502751a15484ed134973e349471901b2b63845e9e4703447626854746996a9e04b3dabe22c9637b2bf94ff496a4ddea2fc4ed20f9e1d87b4179b3c95fd01ff473a9d6c749dd8c2baf5b120ee235176e5a50469550d50efa1fe1d23d6421fb6bc521d0b5c5b84f037e45ff00e9459f6afc6305e4c247ff848859704b4fd557c4e927f8ba0e9234e257fbd3e02aad2907de70d6eb932aad649161bc242d9d8f2b67ce6a922f5bca6bdfae90ac0ccdf41599fb398f84c7c97512c54924eebca321f717c5a6aa9ca8ae50b1754caeb6c83f41ffbb400c8cefb03645e3f953c5ad1686b59a0f13bf23cbf611b302c50b319515dee685e165c4d2beafda498dcaff1b197060bfffa7cc7705c52318ef4a8eff11d38dff7f60b8f17f82d9c68f64b4dbf42779ec4773d80a3370d78fe6ad751ec957ff4fb86a73e84c7f158ab582a75768ad55a29e30c3fc498de2a5c1fc3d250606ae2a0daa0c9f46fb05b19636ccd7fc9cbe93f050a9f01c49eae5656b5b988204498097d3018e053d967beed54e083d66f97f358635ccf2ff5ab2b829519b22bcd0e44a5e74857a46dd5729ed8b86693d3839562fa6d3ea3d9cfa4523b77a1414aea730c2a9e897b6c7b994793cab951caedb075c45e9ef97f0e4ea47c489e897fc600c4f7ddb9fc3f0b3ef7a0f017c76b177ac9ec129dee6b12a86fb9a3ed54408db89087b2b1aa8b5d55d9a426b726097b317b6469f5d226be37e7631f6ac7afda056abeaa4b9fdf4ba320657768db60e3012025a5f73b4afe18ba8e53a6beb58991230aa215d22a8eb6e6b6487ca741384d7dc92d2aa7bdfe09f8b91eb99009cbe7d8e3903649fb5c2945377e8b658ebbf90ebff97dc2c5fd8cfee6ab34d3d24f4d3bbe07bd4cbdfa50da868fdd7d0c5fe7fd5e92e792b69b9b50de7b60233b2df9d1c1fad7a57beb098d323a33420e6d3a9c6519d1a652c66c06ba9d165dcc58644370c43077ca4ee2a1fa9864a67f86670ea7f363d3ce7d16d0d7eeb89a2f2b05c87b555e6d451ab88b317e636684985651b9b655dadd505378e3107f66e09d57d04b754f52822aa6e3a3826aade3aa8efddc20ee459bb115177b474940aa8254b0e007ac914837ac882ebf28bbdf663d0d68051649bf3ef3a299a576c1bcc866f36d87cf327cb727de1626c75da9d61aaf323f7c752a1b398926dbe017ca4015ecd44d1e233adc5af6d3e60a48c583445a8ac9dc4eb4fb57caaa29eae217868abcc7ea93221488fa12fc2e02e3de0eae5d1e5ceb8612bd997a267a8fe4d6b78f6e57685be01c9a06acfa2474d1086e8b9a45e60b8c067373f2d3eeb4a331631e0814e16f4334540150e7875585a372296c787c17f506e2706638a2d8d9e1af4f508f2e12159091a70dd535477d84fecde0d6d98e59937924589fd378b87ed95cc8a8388ed0a3a542fa01aa3ccdcf92eeb33cfbcd9dc7795b5682eeb214645f569248cb59346af723b571f0f953a408f46d995ac2da01bb127f29e0c6d0ef2df6925a4d973d0d5b71f583bf093e70f0c33439b3d0cfe07b4e58e1af331ff50571482757fb9b19f3ccfb2e7450741bbb3faa62eedcaf0844ade364f9ecbdab69f97258050f97179aec7b0b1c8589eb1d6051154ab9e51e7a3edfa34f56abe3e0ab3def1fb513f488e9ceadf94fecdb472632e18cdbf521a73a5b9909c37cdbf523ae50a3e67cbe9a862d11d0244ce4ead381f8d68658f7ee0b4f4c18150f7802dc385a363d017e8fb51257d80768b21fb20b84c11c32f7a5bca9109626b742b77c3d4b0968c66538019f491d0fa1d62d782eae1a3ef7237bada1744a2d940d91589b2b58994f370d4105a9375a14c4e0ff8fb24be4a589af62da36fd68e543670fbe3d567c832549f200979480eadc90117f8b5945ae2b4d4c21979a60116baaf579e06146c75d79c08c0ec5a99c13434aac95e6ede1e61ba618d108d0c59d05a96949df3ee15f1427b3905ace2fb0c57cacc1348a3478c9f56a7f6c9644598d931df0a14e783c13c74a78d840bf44c77a55dc9e28e66a1179b04e9ce34bae22c7c1bcf93a569b5face186294f5d5d19025de785d526d5cdc66f8c95697d2ae59ab774f4e57b1db56b697a5a5493147dd52617a78ff20cfb3521e4dc261799cacaea63d4375de8fcbcbcfa3aed615d9e9bed0dfa7aff5b731a1592987945fab5e983c47a5f381fa3caf6365cf2858e87ce4d13796a4c1d4398d662c4725e76f4a3f29bbcad409462396a67152358dff9832e5e7c05c717749c071cefaa6caba5e7e3d8802400c0e971c336c0419c0001f0f22901045fe4b955f3647c9bc5f46acbeaa8fac71f1b357f625e6f555c6a5393bb7ccb8e9ebbd7ab1b1662b31371fbc25bb9b05c6f9b439994463c142594b3b5c6da29f783e2015ed5421a95c1492226a14f3b25302b98fa6b992b420a0b4f99593b4b2e47e018a76638f4410a3e01b0a772e02db2f108cd80978c451b761e5c7f6325a5a9d6837004a845173228c5f6ac76e35b9732f2b3589c61c77c2e95e9dbdda6ce9ac11ee9d477422592826e09101833e18721fdcb0155702ae6d9f7953386f47727f2f5cba30cab2cc758d2feddca9942958abf7159909bcfdae1dc775b79317bd0d38490986894f214b6267317415f45c58f5712fe378ca026e73b868aa7c47712a88c86914545deef6643c50dfe8910721958d33895473c594f5a382d9f7ba05e7c5ad0a0b82782bc64f9e93443f2fac4c734d9595d7ace7e02b2b1d065063415050c9a311a68bc90a9bc2e26d24cdb668a021f3732e4a47758cd9e0766e6f90e07ea2f51484632f599089e445ece78456c9f0176530784562454a47c41fafafcd0b337e3e82b3acc1fbc2432bf0515ef8bd1c0c06836c30c87677b3300cc3f5ab7a374eda1195b2cb5f811643252d0b8ed5db50010379b475fd6a364d03144ae127a10b1cde84e7eedbe898433037e3d111f693472b8d03543136e890fb457706b81fe459bca068be27e17a941312a4621f5e54aab5a5a82982bdecf65df50893ebb932bf6b15ca719f23813dabb79ea4eb111c3e4faa07bdb9273ae57e459dda1ecb6564c88dc50bf7a992d386ee85db9221bd8eaa9b6ab944f1e0e506fbe146f4107c278de7c98899c9122f27e1969bb9adfc712a130bb5d3ecc38acb1a91796355dd1ceddba1617e4ae47ba5f8529e4e94aa819b65b70c77044b0512b8efaaa1e37a6e2a021e069271747d1be5434597caeb1418ac1ac10b538fab1680960b80a855155489b7ecdfaeccaa02974ba9af9b7ad7f94113651b1380efdd06a37c3fdb65d5db73ea72c552ae5cfcb40bce9f9a962bd3a02e015ecf2da7189b03bd47ca1d3830cfd8263e263ce7f82b5887896f5d56ad26959f37752de5708a8292e761b7030e5a5aeeafa55753aba43e8c53bd9efb30620cae18abad364cfc2c4311ad25b2e5662bcb2175a86c12a32a25868a66139ec173d53b33ab5a508d62b6f43e905bcd5ad352b5791bdce4983d0cbcb086b47aab76e5be541dc87d345283d7bdb0f2bb38cbbe58431b13569e64c5b3b8a5a90631d85b89132d01d33d56ee180b75b3f933a55697acff9d86a83c33bcbcf0ac6892226da95d2ceadf571ba752dc520b3d921c682b389fa9699f7d6614bd9533b0e2d80bf202927194c0d395552d6ea5b54dce4a9eb31209f5796e72622bc71b05a312551e25373b42fe7e62393864cd6643bf4f584ec9f7d81fec48b97f4bb8dcfe81215e6930ecb13e1f32a5ecf63d5eaac320e275faa91c5999a64154877c09a6286c29a95478753bff51f100ff4302cc365f4b0224968878f4be5bca50da795f3db8f396f2e5f3ab5c7cbec956dfbdaf6cbf2bd2c6f3e9b49a64f6e6e7cb5bb379613eb177e8251cf61e5d9758bba3e6cfced76ca7e7e79dfe8abdfaa770afdcafeb0ba836e98fd00f22fe08e4d507daebf9817273581c414d5d6a5273525614f6588e410aa7a56dbfae3f57f20cd5ccb53df640ee52e69adef801c351adf40a96a3f480ffeabd7679165bbb6d0987dc0cdfd4eeb779e72ded6e2504f64ebb8419d564a01f59b5a76b37d8c796bfbcd8fe6f364efdfebf4c4e5d33d5b224353579b7dc602bd9929f27acba53fe2fb6de20e2ab4934a4d4b59c49ab69b7bc06bf2eb55ab9b8e5367b1c394a8595be1fd4b4917b0dd7231878a02cbfed3c9a04c98e405dcd369bc71daa5bb211f45ff67a7dde77af67aee7be1fb81eefbb81fcde19b80b1209b07823f73f78cc1b8949968a8c875912e2f5fc1df065ad227bd2ebe61e455be0d4f72b9291ddf55e17f75d31713df0f4db7753e17aea353f9787aef7547d26a1eb4928bc586012a8fb0cf9b10a04ebcf7454b27ac0b8381f8a844102b671654432ea87c814508e30d5b7fcee383507ec856efedb92aaef4c804ed67a71c2b62868d1642da8782dd37e197512b868cc1d341a78e5458ed5f999bde2150fb29611a2f11d0b8666f699c0a59d69f3b76e778dadf736b7babf3f2f6006368c4a5c63eb12d87aacc68659211b0429f8e397cdf395d3438e948f821bf52d3f6f75b48bc927f539713139559fa18bc9aefabc713139519f03179363f5f9a78bc97bf57967fb3bdb7b046d158b5270f33b64be77141c298abf70bac74b979824c1af556c11f1d68029a72198eca808f5263d26472a084fd163b2afa1b5a33372a0c2ead5794c3e70cb9c869c717a9fa6dee62649bdcd676426ff4cbc8d0d127a1b5b64e0f57ad62b57df4bee9fccd94b49498d4496f548a3c1092309864afe5537b45f59cd87d8cb2e6e23f6a28bb3ac65f9f6faf8a06d73cd35d8d20d4c755627e9a57f7123565b2d0d66b32429129563bfc08236befde821e2e0b558d043edbf983fa15b5dc2e4df6de508eb1005ebbd0d4c621a3ca1bd0d92d2844ca9309e54fbbc23e2fde89685e8a9fd7657a7df6da9b7bb3cd72523aa47f58931e5076e6c64ecb9df777795c5f6988e5e74fb6edb95b926f45585e6069551236c2066050454b39a7e6d61b0dba80267169e71cb7defb650d49fb4a296fb09fcebb750dc9fb4e2963bd0c1b43f6ba52d775707a75936cfb2b0ef9e9a88fe756bda72dfeae0bc7fdd9a17b9c3fe752b6cb927108481f4aeecc9d0d0f2eea1bb6caa4a3a7d41de71390c57186ec2fc2c9fa496ecb5ee6a5bc8f6f67d571e4a768f58b9b5cbd3f29d0d995e8e29aea3e8442bde189fe94c1030575a742c7ce6375f0c685eb6b24f8048f8343640ef94c3925a25ff375ec8d83d0cb0f9ad9c1f6668eb1cc163ed5273234bb9e0d0e5969713431f04972fbb991b67eaa29b32ff93df58df5fcb6f29c97d31516681f931a5de192f391298989b6efa029a3189a85c6c33d1eb4fb7ad7b71796c6f431ddcd7956e19360e2ae3a3285d5d6633e372fd792b311e3b8adb6426d5d4c7be23a6d33636d76432b80c29ddf4ca37e1cd2e406cb1cdf2b52e0df0dbd6665741f4d85383a2b857e82d5f530052d6046e25b95b113149e21bb880b497247182dc8ffc2b8f6fb833e79170dc96dcccd530b19df4d0af5c45ea6591de7003a426c2ad0ebf8509f0498776e5a43cd501650ebe6b32aa5971a2837f1aabfa631df109e6c77b08fde05645759b2fb164ba098a2eb73bf9496f636de3d9ef1b6cabf5b4f7ece916db5afb5a1a05724301764192a1d9b3a5d58be46f78d5cc12125be38da4a5512eb7a7a5852f7a49bbcd660c7fd397b49b65d10b8881bfe90b1983a2165515bbe272e0a6b815cb8daf4b520a8ff89456b6e889dc68e5261ac14d1532cdd73570fe5f6caad37c61133281d3432474825ad9f8938d4d12b7603fded8949bf521bae428c698a42d1a90b84d1545015cc83d44d08224850d79aaace263598ceafd944cf5429814cbdf2a9f4667b925e7bb95ce1ad422446a86c590b5dcd4f551d19da536fa0203cd845e7305a0dae22d845403ecc037d4e3083e2b572a724a0e73ebeb14e1f5e78a6a5ded7dc8a92a7ea0906bcf168f5c9a1fc379d5dcea20550707c64ae50c2c2f83cb14c92efdc05122f97ac9bd6312156130558d8bf04486d3221ccaf0b4080f64785e84ef6438a4c10b7ac63b69da6c8297bcc0cfb2e0858c81081d13bda03d199eb91038e39d1904672e89fc2c8b75f2c485c019ef4c20387149ec6759aa9343170267bc1342307449ea67d954270f5c089cf1ce008203974cfd2c9bebe43b993c74efee5c32cf6d2bc2e1864f0509874f7dda622fbb241c6efa9493efdc7e5c27c40b6dbbcc2cfb2da6cc992c6b0f04eb11e11813617b91e16ac0d877413f72155309c2953a15283c04bcab7a0850b85293f91372ade0b2d762cb9d78e91e9e919c1dc463118d18382d1e05d79108a62976c9478ea16cedb5e01572ffd6eedbe63cba551edd6e758c5ed5f5fb22b78537d4bff5b3e5fdf3b005af3bdcf7c8d305eeaf2b47987fbbf51e258b37a87aece99aed7b1e9ec0d58e3565413fc80eefeca9c7aaf4035dd4dde86c6c76ba2e11f45690a033e674c44900be169698d9a1af2c9e94822b7f668914ef25ef0ae41a8f10ca162900070eff362a7054613071dbe74dbe20c1655c1edff4cd07c25ecbd459669b8b119dc8dfd2edc7626dbd550f39686a1f30b1d12689b9042ce1a3148cbae62430a33492ed683ca15f90a0136a6fd7f40c5252f5081d1d90a0fec8d1528ae54687ae8154a5d65ad3e7d5a97f0cabc8840087358f5245d8ae21f4bdc85be201d39c727300a0a2aefe10f207151b445ce50ed938e2ec5035662cf28b133a66c98d8731ff2c5e1aa14c68837f94d0c0b8500f68628cbaa4bcfd1e0544608238cc8f3d2430b410e3421724c0ca5028db401215efb8ea0265825cf68a50297f5fe55c4ef04af9f52b99102a2e3ac950d14775dbf02912a2d4d8cb1df560735bddc5e5ca3c8dbeb38f3c12297d4bca9a970f528aa8ded9377258e17efd03f75c0361d9c5369be803a70c6e5554109f4e12964ee2e92aa1107037283de3aaa5f3c2441fa23c043f5410370539acd944b0ff52d1ee6159221459f66b59ef2213fc48224194aa0b2e9a1831eb457bab5fb8c0f4f88b76afef4e835428ef1dfc45570577a5b4c45ff414b00e6df45dfdf8a30c3d572195b1c00913da281fd4f2fbf67470f8ec627f704aef77774ef74e0f067b1787c7af770ebd25c7fd2e29435c9cecbd3e3eda3d5986f4240b52011ed4c3c1ed7680b5935d22737aae2e17d0e4a5154540fcc08a52d8cef6f6fef0c03d777b78e69f9db964707c74fa362f40b6c302e105b67d8aa2ad0d0cbb16a98e6c57eee1ea86b75ba8ff927c86a0c4bc3b1aa46974c5b3cc1ebff99371b4b72d5ee48ba4fd56b81e1b79da50140e801227e20ec7ba80c21344f9b95255114ee0016075ae3b4cfcfc76115b60bd52435d8b957ac13ba11c8c815be7553759fc4c73d8ab24a5e6ed79fd26955a2def1724326df595dda58861cb4e3eb2fd0e711a0d139f08eb557390e45030e4beb2aa2d4ce7ff8d5aa847bd7f595f6bfce238afe3ebbb24ba9a08078db0b3d1ed3d77deb1d0390b441af3ce2f8e73188d184f59e8cc79c81260d90607a726da418383534c9c94b15f1c73d1e30b0b6f54feab484ce6979d285e1f4d8334e5c18ca5bfacad372c524b6d6a1eeba9f471d1d6012a8695b2e180f7e7578fada43cb6a2312a9e8851ab279c981737dd689465c545661a61a61c5025c5b538b8d4d1895275b9430e3cf3febd421dd3c0e60e12bc1d379bcc3c5cbfc86fd7e5aeb168943bc54ae5a04fb07635909054621fa67e8e20c58b7c6c77bec41147aee3e205ebb0dbeb3811691fe58e286940f2681a60aff02d5567e0152ccc4421431fab478e4de604cb45e3e1f9f0e0488c17186f73b48109471b1bda9d7a4239eac21b401d8e12e520d9bcc4fb3ae682dd0a74bfc0db51e775ccd3f98c2524eabc57eff026c59888ed5d464d319474e6a9c1815154c85059c687c2cf32b1f861751224b00d9348561feaf8eb2cbebcadade727c9f96ba8fd697cf33ae023369d02c7072ab3da5cb7c2ca76b0cb92e81be43811e07fbf26c7672bc3f165ca926fc1e5940d82eb5ae84b5e0b7ec2442df8571bfc030b46cbb7af34e4afcc82bc08a6d3f806687e0d376dd37aec0fe739e06914b2d7f1ec7a2e5858dfc82b307c604198eef1fa4cb387329d8820a96f8b49291be3e1ceead6382cc15e31b113ce221ea522a9b9bfa6f37ce1953c6fa6f165305dddf3fba542222e583262d702aa519be1449432a4aa69237e558cb3fa295b2a2861e98f693b2865812bfc0f34d7c0867e609005760582b98893793de0d4061cc5332910d44fb8e30ae0caa1c65909523dab545ff9eb52e9b088ed887856df271668c84671b2aa452f6ca48c8b245a31ab0e4a80b782f1b098e8b539eeec1ce3697c530b756a435dad5830feaa00adacf71e2f03eeb2cbf915f8e5af837ebd047dcd78c8f8e8ee3461f5592e2b94a83660c9ca0c8776864950dfb8df6da07ccad58fac1268fac0f08f2b909299388cbeaea85709f6557ccb7ed4bdbbac94e5c105754fd4c24af6ab7ed12ac33f7ea3fb54cef8832abc5d050d6d553fa8f98a2cabb6c6c1aa0c8a91a8cdf37e559e950db6b3aa26abb6e01bbb08292fd4421dd968e3871bf38f25d07ab857259cfc151bc533a6a751fde819d7e5f8c8e387f24cca790c93b17ae4bcb18773f2104f321225c859bca2a26725b8393fe00f4cd6c8064e5774da8712d075fd0865369088df9dd4335625a82418d5d7e14d058ca70f34cc1f36f09c4bac5f57744f68b736a8daeb07e0be8df266c2ea0bfe534281c0e9acfd27fffba52cbc0ea25112a7f15838afe3e43a36af1fee4ca70e00a58e6462e490ecfc5223d5ee5c07a30933822d71fe52da7b67a3d37590047075928bb79dbb78eecc823b87c7c299a7ec17318952671c4d99c36ee5de20a538c9584c23b92e3a37919840211a45c7f9a411c4972288b81338a3f8face01172bcc50e704c288d43737379d0008ecc4c9d5fa5401a4eb8707aff78e4ef6da1b9dee2fbf9cbe3d38715e1fefee390727cefb0fc77f1deceeed3ac747cece91b3b673e21c9cac39af764e0e4e88737670faf6f8e3a973b6f3e1c3ced1e9c1de8973fcc1797d7cb47b707a707c74e21cef3b3b479f7ef9e3e06897387b07a76ff73e387b7fbfffb07702900783f787077bbbc439387a7df871f7e0e84d8ef2f0607070ba23b1480c06f297874a3a3d383ddc23cefec1e991c4bf7ffcc1d971deef7c383d78fdf170e783f3fee387f7c7277be497c1de87d76f778e4e775e1d1e9c7e92888e8e8fda0747fb1f0e8edeec0df68e4e3bbffc72c298dda1763f9a861dc789935eb351348e46c5b39957f13706ce289c6b96cca254664b7f0978e84ca35924603ca5d688319df9cb7f74543b6bebbf287bd13a8d2d0a8c162965e2bdd1891d8fb3ecfee20274641717ded05f443c1572e8c5630776cb66b38c8d7572702a16b6de4ea6967c700b2c2afa18c495b28dfb540cb98f17587926d7b6744b2b008a1ea526249cf688a5b031ca1cfe22d9e6ad56ae2309802a4bb1c3fdc76909050914e181243c28f468abb584253583b16baed1c19fdccd2ee369b3c986eaab13099604224e7cc2696e042dfa4251c2b077cfd9adf06a36886693bfa4e6cd5070d362dc57dcc352ec31590c6fb57c12c69c790db658586f21a7b63ae4a7285557478c9900dbceef71516ea826311dfadb22b9835edbb68e0bb24cb4dbcecb2e6e361b28a15147560f61dc91346ee3586bd194390e5e8c02ed8c3ca0f74ceefa1e5b2cc6110fa6d3bb7b893f69361b09648663efa8a3c8c2cda62626c2397c34460156b6494107b0e53ab2b86898e94fe80e19659d51cc47814029b23588d81a3312d15cb6871e7ce384b1ef0ccdf56b65f4de1a3da3bc835bad23d699c597b76fe651585037968da1ea30418d1e6198b87fbb45fa24d73237185eb2c31a4a84bee3b690c8327747cedb6f4112055c38e3209ab2903893f8867dd32b17b49113a54e7c399ea7706cef5cb25130d72e6a6452e05c27713857a55fcea369d871315e94eb1a5a46d5b36282143e6dacf10d1629b9110a6d74095b31e9a065afed75c46ac98b8acb5475ff73f99d81a2e9ee50c9531ecb32035db843d274357adafc4557f3aab4c822eb151f4a6975cdc9325d82f580f137a35cd4c0eae0355f4865e23de3f3194b24e7ee357ae4268984faee92fc21671d56f39f2f6c1bffd2748fd2417cf9b7db62c5c308397972b96e7449cd09e30578fe51374787dcb716934b0baaacf66638cbee78e9e6c0c0b6a572ac1d68105c5bf70256419d30abddbe1683490ef31326961f868067c1f31e297acc5af7d5129722066e9cf782d1c47a23a2e89572a65d968e92e85ac4096284e34ed13fcda62955f2bdaa41e08123fb59e71bbb82cd26cbad6efac5a7f652ae030c5b0905a2db25e7c094291f9ecba3bdefba2de6a935e91355d546ae5c159ca0ac85c4a4e4f22e2f8d418be767cdb0f1b83b229efdbf6e6b94fb62e5c18cd1dcf9f17b06a7d646d853860d8d9e497ec5227e6564c73c5e0b86496a7a56bf92108dc77fc9f14dbbda3d69908a1df0bcc6c25777796c7cc3d25caf03ba48fab973747c7a71fa61e7f51f07476f8ae391821ba80ab2760b28a22a0087512a186749aa6f52ae4caf195756f783cfb405a923a5909057125380ac22a706e2a7094ad8759c88ba96d1993e32633bb99c4d69ed4bb9fe6208975699688c586dbf51fab97372ba73b8a757dfed7a300d445831746a2a29f0bd5c5eb58a30626951c6c7f717a7c717bb3ba77bcd26129d283d4d8251c4af1a94fedd393a3eda6b36df3124c0f566deb427423d1c46eab06a92645bea4b88afc0e2a7fc62c1c3cee6e5545a10b64098ecd22be42aade9a9b5a39ee447b6399b050edaae31c96338b047d7f9891abb714eed7daa41e975b33956aee00857c1890c724c12582f8ee97d14322e2271e7d55a8930d8d3482a92f948cc93d25d3f0b6c87eb078a8cb9782d945e72a35403a713388c790825e9e1c582bc2f2f6b61143ac99c3bd3e0fb9d13f14844c134facee09ad45e19f45a2d538e56b5c700f385de2fc8eb1293f6b6e435abffc57b9d5ba880f33504a630f7d55dd9dabf05b962754cfd8e1e25ca98d85f90d40613f8be0240c5c2dee4776c375b928f02af17c3f7be39e466c3bdfc701b31f21eac6b941439450fee8c0926b659428271cede2b692e46012669ced06f3752c5d217518a88394d86fa59037f7b2ee70194f33a6181da49551c9977c27c7f8580ee93d320b962c28ed9b138c25c5e102be485b4d9d4943d4a5e109a8716465eb045a8a3d218b47ad3bc77964749f12826a9626ee5744c730657a7c13c83375624c8a3c4d484ece9369dd24476ec3719452274bf20539c9bb6c82429c9decb66f5025269714f90a2a1bd98541ada4bc872437b7c41dea28030bc30237fbf107f701f713a2749bde923b85f542c5151bd3afb534c126c35f6be75977043721e5a0ecbb2a75608de8b5b72803decf959e6a63094cbd138cb36adec3977fbd42f4a3ea818f0bd15ea19bb2aa3dbffa313a84f722f176dc9807b3a41316288e905d90218288059705dca77a8a295abd522da12573e94dea0cea3cfe4323141c23cc872841add9231b2be46626c50927ed2b196c57228d74268815cdb866c7fe260cb1f86e5430dc4492c176bb8978172a341e06e19ff665d6a4e3a8c4f24439f50a1b797eff43e64ec5aae94505ddd527a93d83583d0c45f27f1ed9dd7e85aebf25f35af647cf76a3ce0abf664c49497e3f2584570fdae9af1153d4307987ca46768c9aebb5c6096bde785d0936503f573c31f3b663451bd1f8e1d0bb06e0c59c97563c94a1ea386729bf98e9ea10f98fcfa402df5dedd171e5b608b057953f2c559edb3fe7254deff5ea3071350d2d3ffe01dc058f887de5fc6b795bdbeaa8179b9d16cfe89dccbf8367f7de82feb213d60711862e40d924b2bf051440eae0efb671e4c259f0a4dffb85200b4b69c312f97811764165c3f0eeb2cb85e49fbe532de1237f010de94899578bf2ee35523ccabf6f9d2cc29345c3d1fcad1f2a5e12aff9272b6dcbf7af0fa264c2b9cdb11c87d49624e0ccbf14d28732e95a447b7fe49308969c22d9bac2b8162c81f60122f48c2c6debb9c2bfca8c6f32bcd7c7abf2ec81f4b06d875aeeaed2ad5ec117672ee8aaa7e6393157f6b3bcdd19a515a9dc6e070f78185405426b4a8cc60813d064c5ca3302275926d358d8b29f92728cd91bb777bcd4682854ecc9913278eb8898b6a3922768a13e18edb622db7e3ec46211c5d05a31170fc921b72447227a1e7295bcae10469c134f7dd5cfb07ace23f753a9562b5f843b2b1ff4866573bb1fe4cfe268cc97dab57bd44a37c12a87d0baee79194829f5932a5c1b0eb67d9fda2d89b6cfb04c81fa17bc9d1c4308f523252767f1e53ec9214e118650cddabf5c13bee1492cc0213beecc1acf6ed83bcfbd9ea71f29042b2d994b3a73ab17f88558db52574a22fbcfb45b1ed5ec1c31c0938e7add1fa4b70482489d2e1a89f2c63fad7758952c7a0042fb639d36d44052bc9f2ff1f7beffeddb68ded8ffe7efe0a8a338b0146b02277a69d73a5203a6992366ee32493c7b41955cba145c8624d811a10b2e3b174fff6bbb0f1204052b2d3999e75bf6b7d7f482c922088e7c67e7e369bb240d9428f8e6734f6efc44495a9456e3a9cd1b8bed48fdfbc7ef7eee4db971fcf408ca6aa8ef0962ea69f7e35a3b1beb943ffd86ed13fe8ad9ad476b35ee98fa91ffafd97afbf87ba5fbe36cdfaf6edf3273f4285f02bdea19fb75bf43354a8473a8ca204411df4e294795b3065fb9498c2e3d8722865f3aeb6b5083a423cf2f51323a786368ffc911d997b3016b6e4d0960cc76f543bdf2f19ea0d31e174ce90e2dfac1a25e71724a5d67599e47438ce1fa5e3dcba4e97544c73902a5f335462d815afd820cb2b4520c0f0f06db9e1592a7256e152ad40649ca49540666ed4929b3d56993aa274ded0de7007caa16eb58daf1a6abe6685a0b51a63123c3cf6848b92a1a6b1e0151b80eb43e001e999cf98875fe4299caafc5fecf170fc8a0db4c3a0ceb1c7d672f97808f972804c93576cd07269dd6e7b324962e359ac9bc0f8a21473a65d4eaaed5613f9da56c5c2185b3d8763dd5b36e0ecfab59d4350f998d3a69e5933abfde3e150bdb0e1e76aaa9eb175f5b4dc704987840dc4869f6414ec51f0d3a1e2770ed1584f7ffb01041e51e8d59eb5915263f6e4defaf06efad640d51ba1ba6967b8fb9b39e93421078b9bfb57341c352202bd2049e990e4b43d50a4a4c371f9281f976a5b80f37c45f9b49ce15a619d24c8575f1f93b447699924882bf1bcc224edf731a9daabfcb180344b1d4ff0cea6a20627fe70bed501915369ed956089cd8f8ec6ae7d729a87edfb89a18a306843ad65dfc18b29bc08a107e363dbbdf440f786e4adae0def14a3d2d0ae76ed6541584babba530b79a50e1be2e57fd8746cbe9c5f8cfd79f45384d783c055377e62484ef98c303cee6a47c34ce0be9a795f55341214609ec2dcaa8d168abe78c4459535a1b6dd3be6e00a8669f44e8b05b462cf0ef3ecc05e630362031ee0de271b4f28239e796d653fd62ae52507614e79df1acbc6c4e3dbeef1ae4b8cf76dd17006d5f4edb101d47569fbf0995a8a376abb5d317a971dcff74adb61122b9e4749372c49aec0d2ef14baf5217fd1a0c11d5eb9a68446370fdc461c5f0616d9cf9aced3de9008cfb8ca9a0871a74ceb718225e8428d89f02865e0ee40995a496699be6428f597e969a31f4392ea65fe778bf690d3dbb56057f582036d22bb7ad23cc946d79a97081fc2ca195936a394f9e2e6ddfa66d43b261002f03e5fb19120da33f1241bddb07e9fe860dd27f6de19734376c6683eb08549ee198e613d9ea9b5c75c0175eec626103c4acd112ed3f9e5000c044ad85994e2824925e22c729e57cb28e5a6e424c6e48c5136085b436a05971ede2451275fb559af05abaac059b5a2aad39f196283ce110322d77c0603a64d468a75d18febd18713de0e2339f0e563cf5ece3cdb0511f45a0d16ac224ea547c33e037f6f3922cf68bd8fac987e741216f32c242d9fdba4c595ab4b7d649e49837670555d9c161d428f24f5a9725739ee92cb01a9781f32f5ae1180c7e8b4a6d6a2a60f652f4e0ace3d6b0577c552087757b3ef6ee5498272fadaeac4f4e62aa98f702d4caa383b9e65ad2fe5a434a219298d2a8be6a41c2cd3ea03d7d65696e9a1a4bd63526acd2de548faba955dd36aa11dfa6c979d8d795e722de129eab14b75de2fcf7c49ad2fcbc4d0561dd282241e21ee15f38c19204072bcb396d4da0c9031e8a366203a74056ec3694f005d5a4c822bc4b092e8fd6a9b8968a03c8c8a6256914186d3697ad82b760ddf470c63cd837f78f5f4c59357df3f7f866f8d7341c5a4576c177ead514f136da732567292729335d36ca7cae0a8dd1a6d1c5ca81a47b1065d00c9fbefdab56fa7f56c4ed9e03773ac46db16755e0eba93761559c87f1885da65c3786fe855e52520270c4ffc4f748c70677f3d8c203ddef54feb1d12f807204c0a332c4992d9010907c11f9e7a40485964faa7dce1b071175d790f23efe3d6a7c1a6b5f697a137088d6a5d804fd74a2d2d285ee325232876a32cc82461e83ed3ef4d8cebb6de1b3b4c367b3e7d3831be16c21b2fdced98d08fa7064f1d9ad38f677158c97e58b5cfa8fe70f865eb712acb37225fe532bf62b37d8d70a9ee7744eed07b4c9e317a819a543926ef1926efd87e8f2633f1876501df3149cb1866ebb4e4ae839e4d773844ddd7f149cbe5bfc10bca9367a15487d4af21e3ce56e93acf68fc0738d43c8a61c56fc88c6b3be52246bd8ebedd709ef38b774c4a26bcfbc6b3c6f8d59025826d4a6270a7e71751b9d6c24e29221b78398a2e988cdd16ad851e78d3f33ab39a4aabfff5ce6540db9436e542a55b756136b95ecf47fa6eac8be280222a460f7e40d4bb091d7de794c4dbad55874e7cddf1a83ee9cdf1312fd7c67358b2cfd2d2c17f6e72c11cf3467b3dd6baa98b5e32b67e52e4570ccab8ab430e6d204ffbabbf771fcfaba6f87687fb55a85afc8ff96175edcac6a7bed459ab76c8ea76bafbbffe7fed06358ed1e6a60709ebe9cdbc6051c6a4b63899e826c37347e6a4d0fb6c642f334fa0196a8e2be7df2af975bb75bc5ea8603569c2dcca9f20eb7b487266d90728024a9227dcda8210f6035cfe7fe07218aee3c9011fc2d1bd76cbbe667a9bb85efb78548f962681d7a9e04fcecb8dfc60e3fe940c8a3001674d8ffe1bd9000655f349bd632da91a486e1a32d9600931be544c5b4aea00896099ad1b39a2bcda9adffbb28a9b52804d3aa4e93dbe5d3a20cce0d022f1fb258b74a1a85cb8e32882be450f8245fd20caab488a1b7584c932d28c5b94cb8a158bdaacaa38479e7905521e9dd536d5335d357138883adcaffeb2f5e09ac478cf396b04e0ba7bb568a94f1f48ef6bdde2ba8fea9d46a0812893de71d36935dc577b26cc4817740f73459bec15ef9ae7212682caed16661afe70bcddf67c4185f99e45762d1b4605131136ddafbd2dacb85c54013f33241dea837e9f302c69a1f750932ff18efa1a12e80e03881b295b4973da3cbbc8dd657d67c82e7349b33f4747dd9c5c631b6d2a358fada3c011e3ed166d98e7a66a26c204a7350eb94e71a84e474bd45a26a979d94e71210345ad564d72635854a32cb65b698d93a0c264a85b88e4b54c95d7a254ba037d5b8977c0b2a6346f1d86dd843208456a3879df43f8fa52aff05af8f256411d21a28531f65b8431f66f0b63e0affe1a64b1800f8fc93b86c91b46a7b10d6e8b210ade3126318943ab675c83afbc6df0c3711de46f1ff960111ed841c79b0d9b464ce2ee6d19ebb87fd54ea7008967e4396bed018be4fab55ef8ae34bddd919a1de9b0ef7864cf576376c87976d0ecb56195ece5ba43b0ac9c9c6a9eda31a81f38ea5f3fb2b25a5b3ddb1b369f689b90bd1fce9eabc89f63f7e10b800a0a14d62f529e157e997d93ef6adebf041a3275d7427045ec679e7a561ef7b07b65d47ddbab7927bfb22076e069ed69106fb80ef3cbea00c3eb9c67e5f544ff19397da79888515771c5574cd47fa35f754cd70ba6a6e10934fc55c7b1ac3eef25163a53cbe9c4b8a580ecff7898243dfb44033955498254bdc74a7c6e3c68dcb03ba0472982b05386edadba92176cd2786d823adbd2a7c7cd2fd67b0a44f03dcfe8edaed5563ceafe48fb1bd4b47c842a0656a972131e384fd876bb408a2f142c4a058b569b42e6eb829128cb170b26189791e976a5b8b7d3f2fc67b0255db141749a5eb2a8da08a66fe75554946906fe79c54d54f23978e96d2a167d724852e836caabb24825f3b0b54691141b16edf0a718ef3039c6c4347c873ccfdcef3cd796579e65e5a4b64aebd76ad3ab0e9c3c3aa694be610e5e5262b06f4de58caafff0b8d376d36b39ad781eebcc820ad4d2529a659084a34b6e79dc21f2ec95713aca7a8e323f757c5ac3fdaaaf83cf7f43c64c927fb1206c152e6f8db772b70a0f1ab74fbb073c64277dd631ef0c7b1f53f2d66d2d09f7fbf523256429e16548e9d1515d04dffea8f6761db9beef6b269e9d75e0abaa791df303fa4988246b0d14e24d5567d73df53eefd048208c090f037c93845b3e53b123fb7a42a77e0cf287d034b9dfcfc23878c90992fa6c050b6ea840d5cb2cd4a99ad24406fadea96ce94ffbfd19658435070028566b5086a4ad7642180366f20875afcc7ad615b986854902bfb01f9883019897bc2a0bb5672e4cfc3f0c0d9b29d195f972ab318f43947fb6614a3e4da339eceb28e72310756df91843ffac1a97d29fb5cfa45d49d3d9b8e729d88df742be40d65fe9313d667fc6be5d8feb6d10a39467d12ae537d1aa140cc7786c9fc4fdda874d60836afa8b8cb1695733063349c2eb6ed58c53794123fbc75a41722ed5a0724b55bfb32fc4193bdf5c5c3031fe853ffcd32fdc8c403098bff05ff8c772034703e3920950072cf32a3a172cbd8cd665cea50352a879f7d68c9c3378534d5716a961f1a74015e0e575a468ad2a96cb5aa330f885ffb0a964b428158106ed01783b4055a083a896e5a6c8a0828a31404a59aab65cc9b22cc02d5cdd5e0b36cf2b56dc44d7cb5446eb9ca9d369a16a10d1bccc986a84ea86eba1fefe2ffcbdfde442a42bfd49351c4559aa4d098afdbc8a5219152cad64f4ff7e73f4dfbafc11bca02a1aa8718cfba811fd0fc1241de24e9d6e6dfaa7d92f0f1f5e90f821e45bc3fd58d5f41efa57af066803b4d99b8154b091fe2cb7eb8beb0afef4f0171e45511463649027feb8d79ce4bc751a61f2963d6c3909685f02c51cc966f47cc94fdcbea4c656c03c3e99f2d07ee031bfe25ef62a7bf37ec6afc356a82fb224e5d5b3bc5a979567193bcbab77f325cb36457853edb24b7328f9f78dd4b2d7b0f4452611a33ad19f6fcae3f67eeb05bfc92e1d6cd00dffe077f29526695a4bf2236b0add03bf823dc2b6ff9146c8fdc621e5f92f7ba97eecc0c3cd5ab7db1c7eab1eaebb1a4e84a766f497a9579d5fde774a73b6f7e7808396abd7eb931a9c2a2052be43ebb82f7d51dd2770581bb617c9d080b6588d9d8da8c3e37deb69dfd2abbf96244ed99532e091efec9cd46a6a8305d08596d0f9de1ec70aa7b0f489026edd310e1f5a8178d845df28d34df898c50c7acee76a4733014751b4e1f37473b19406c80edca4d411719d561154c0a3f39b288dac6cae641acbc68026bbe48c4be2188b655e29b662bcd78d6d621999eb54708764840c4411af3fd4d4c8dbea5846a245fed9801a950b776ea5d6cdb228af718c47f643501071c2c05dff80a6a21b33c6729b1abf0037673ad30ba8c3a4669796a5263e9d6cadeaed56ef5fb70ac106d336dd992ac41e4dbd69cde03ce799aec86909a61f675a17cbeeaba174e7dc34988aa636129891705587e7a53a0fbf97b5370b0b04dbeffde09a3b26c80858a4d17910140ebd67655f86c71292e5dd51be5a17f95c7192c78647f867a71f9bdaf775477e0c65bdc7c3ed565db55472dbed3f19fa9b2f92fecdbed9a1be1b768a82ae00488156067c3c1ce3dbe3e190d27e5f26090a77809bce282b59c51fc8685ef22b262e8c8850010e95fa2359942e2413d1f1701869bc3838eba237a23c4fcf8b1bc5640aa661c3e6602b368ca7debd57ccf9238ea2b8cfa6c319b86ce8511d62ecb9f47bb7897656e62e3bc6a35467c8988a997f182210253b759d3059ff007575ad21fe23f396dbcf9e78f94f36f627d64b9c8e3a704da5c681f2445526bdc5d041d706d5fa66169da851e2e551b956a3d44459abe260397bb54ba9d8d1305088cbae4cd6b55866fe378e6eba9c811104ff76fb848420644d88130f946c67827c033c0143546eef5d0bf15eeec04b81b6a55e927fbc73215f42e71bec468e7303230e0d4c37189b7a7808dca577dc447769e3b85c999c3a24d511bd78b73314236d268e520d31edeb0a0c4d92ae544f133532d611ead186ab5fd6f1fd714c18862cfaf7aa4b4e7484031eedf97c1b5f0156dba8a735d75c2289bb8356b5825b63df790d96847b8ea9d8a795b90c3c26cf5907dac7848d0e74bd73b4d8484b569621f42203bdf5d19d534b238604011c5e98a0744115b697aa7770cc32ec6bfc0ad3b3068653866d7620754336a3719fe83c075aa0d42ec14e541149d2538bb7486fb0ceacf647864480bc5c1ba5508977da530a4e34223b044ac33cea7d9da9692539ed1d8ff7549e6fb72807fb6d401573ad08f4f91ceeb501dfa31ddef4207ccb147db5dc9627c011ee333e08ef523900f174ef0683a914136467cd123d70731cf1c997ed7ad3a4ca7030ae3ed5df16c68a5ee91ad7491ae0272977a33b48658808816feb8f2986a94986769a286fbad3da064c492603440fb7a626deef11d3ab6bd2a14ef34c279298727837da78112073d9c22dd3286566cd43c0052929b78b3d549f908aa61295a05386b5324182ba0b9252e99f8f5ea054bae750a82390bd400c2589e291c4a4a03d1e6c2dae3b45366a2b704c166aa92fd5e25e51de760e0d5d42b9732475cea1646db751196ca3c5765b4cce101e2db75bb4541fd9a033d825756779e76e75237da6a57f685c6f1dc8ca0e88756df660d3b3825386d6782ce962bbedad504eb8daf590776091247cb0c8053b59ad5896a79215374952a19cac3151c5c17d6fbbb57792042d14535f4765fbbb75ddd8ad75c4a36c80d0ac24ea4839a0cb781190875ef3f30e345f5cc966bc5d07e11793e7c026e0d173ae0961672131e2a4a4ac1fd7ee0d2e29dbb49c4dd47f6003cbf148fdb62edf689acfb07756398b6f3a65b3093077a39624a72a1833135d0bb6addcdab6b4ddc024b854e57c1e682dfd70dad07a07d1d1fb2cf08012d065372729dda75e80f0692bac5b6d93508374c08e4f2a6705e9b2e18fad6b953a869b66d22441a84b0167e1c37c7fd34ef100ebe0c156c556877ece22452f001b79517a765da12b8a527ee3d4138a6d7f0246fa17aa6560c47bca10ee324d2709f21e59ebb445f97e650db74e91ac769b0584331e530655426a0c89de10b02162b7f647851214c12a01f810bd635d80b32b26e0e9b1f7d44213e83269719dde54aa90bd6f8a3a5847141b9da0f1955c94227a102eaf075afbd38f1f908859a09a07f0f907247aa0bff120522fda463f88418c6b7899149d900a14485011a02a143b375a5c476cee7730e9716f6c4b5dfa90b749aff4ca57bafc21d7935e453a82ab7b07dff2be20c2f6879e2b3de1954c9344ef9034494281f3a7276f5f9dbcfa7e144192a568c152b9110c9c11067a255fe74511bd7afd3e126c5e5e31112d44b9d26ab42aba5e321e7deadeea9fd426605c3dc9063168d1f6f9d1f4524cf224f99901fea23bb7e41d20f56ce2299446cc875c64368e594ed96cdcccc5b8dd2241a76266a1a8ee0a0c072d604ec540b06c33f7c57ce9c967500eb47d24c5e33c49ba0548552857cc5690a8000b947aa8f16e106e5ac7d1954482fe1d30381d6e28c3e423641fd43867a98bf4c34426c985ad23c53e96c0953c08dbb6dd221f9ced87d1b73ea078b35924d791e28ad3029c087a896488125ad01255986c68e15042371a25b4bea56bcbe8c68880f33be746920c8fb56e7f41114f12083ce0133ecd66a3b97a6fc2d84860c44846e60079bad83735aac8c2c711dd9777609324a6ed10cc5bd438a2b9e61e8bc37907dc436d0470c37a1e0ab8a7123de74643e0ca9c4a2f289a086ae00c355270eddde5ec7e49d2467c793c4c122402a31f454dd085e98cc8ee3811700ee29e7e54b18246cb0ab97e3080979d4a8c7d28839761ef2ebb7a77e971239d3deb925d6a1789bab3351ccf0e1a88a4175ae781b21fae4fbdab3b7309d160a0a4b9967458b3d76ad96a517ac5aa2abd6034feeee5eb9fce9e3e79f5f4f9cb97cf9f79f9193eca7d90509f3dd1e83d943aee75e95b160852869ae3b28a8e1d9a1bb808cc53ce4ba998924dc5b20099cde0f449da568f2c8af2fa71dc918dc1291f4058aa9b4372daef5f4b522a214cf6e3e848b13b79368ae27e0e974ac48d8953c10902f8c02604bd00dee58d285779c502b44947e5bc012eec8ae0635b83c12cd8f7f19b9c155914f7d37e9f9440594c2aeb92b036d69450ab16e0fadd2737ffe62761bb7fe13733643277c8edb683f59703b9642eef8a04e23361481a2dc50855d40ce840b0aa2caeea67185e4505d9e0b1ae066544e01da78214c82abdeaf3a418cc2151dfdeceeac7611a2f03affc4ca2ca060195862cda4f10d96aa2f14a77ed5a2b51f119289738f8907e96dee069d330c6a4f068e633d82d5dec81e986a209fa972f57be9361aaeb7c814e03ecd667105b24e8afead2194e7b00f0eaf0c66c2092d543f65a4080ba88ae4631074d300351231968c10ed577f661f4715fb7e115b751e0752f5f37c4e08e0af9245488d5091c758beb5077b55c2d826518b3e1bde19797babcd79e37724f1ef4deb11a465f92b148a2fe80eb523d36fd38d30ba71a2cd30a491c6666e1d41c2c2eed87af257c1d7a763ef769720b51f5d8cc8a6ab8f7d2afc151d69e7defada0ff4fc323503b232a26a2eef9a4a7d75892b4bb3932f0c23d1882edf6195cfd43c74641bfbc6fbdf03bb6ef34e91d63f234ecdb93fbf5ed69b36faffcefbdd190c7aa07174cfec86e2a8447011cb27706338d158af1e846bf06272eea5c6372872d6871ede5dcfe3234a6518de7ee37953355cfe97dca425c0c18f1471d2dd7f3e3b71de0cc51ab91275fd8c8a924aa99f76da72a6e5a3adbd354931af85ee3acaa9b750cf55be9c19f7ed5b1a8ccf4e27c81f4ce75c9073ece0049d22c68ddd4713a11836b914ba6d569a203561cd85c2b9e3cb7828dcb900f638321c213ea70e176d7e6817632af29f84d9b82db5cfef522d729345251b113aeea3d1e624c96483ea64312bf2a6594465ab9014cb0d363c43658364cce6661fa64ff18c3ac52aefd7fa0511ec4960c24a65289323986312f490e8abb5072f07cdc6bcaaac71df69e4e6d6abbef0f97f37f6f8d57f8e47f63c858e83a513bdd87d4526f1a7dc8187a1802acdbbb7a756b9f8ddad7bdb994ff5e8f98f9106e102f39333bcfee2cbb6fd493466ddfcaa63de91e67ada73db0a7ad113d34909b2bd542e70e4e5cfb0e68b24d89dd670f538586f04ca080a99feac5f741d25b1dbb0f71fc1558b83eaf4b214fd375f5a4d255c06dc1e61b51b1e7574cdcc865ce2f46bd63cf7af4436b2822b57febaa154766b72bf1eca57ff4353ee6ec8ecfcbb260a9cf01c1420bdb2a7798c8ed1649fa416a47f0fa21ad8daac1fd494fdfebe84dbb70a34eb05429fef4345dd79e1881af7b8fb76b4e92de0b59b32b3ae0b895674e068f2dc416f6780670fbf3c5c767a964c15bcf98f719250a4070a7860dd450e51227c92ba99172419c0ffb67e3249244843c96869156e4215fa01b75026db7a1824d622bc5fd001985c874a6ed4672ff216b064e4921a9a596b90f5eaae379879064c6dc2e1f5580b80aa613451d9d7165a7c9996a5a778e3e8929a5ef98b7456a86930f3a96bdd5ac9b1e596c9e3af2bc4b5522f16d01c78fed1ed6c28bce84e30fce1db56c8c76c5af66b3d3d4fc8e4e9ea6eb2fec64e677f2345ddfd53c92e2db0cf6734a821666d0d1b9adee76779f9ae6d37446bde540e63baddbebaae512c92e7cf914df2e4c35d374e66a5a38da58bb11ca2fc9f7a90e6e3fcfa711367ac7e3369562537bee1c1dcf805cb0c1ba5c5b880c41ffa9b8391db0de90151ba1351acee660248f70feaed244a418c57b8c895f1d9f98489dd1cf8397af3d745b684c8d426e50e735f4f87054bb5976c4554199635b46095ed3e10cebdb5f356e13c8bae39df03f76fbbd5885c1df9b40bbd678dfe4836aa7c8a6ddb7cb6d69bb951dd8fb72f2b349b0f00f69215b6f7d61fa1f0d95816581eae37d20b5d783466cee8e1f55339e2bde2c70c4475669e2e56bfde9c5f35767ef4f4e9fbffef03ed64bc519fd9d9fb6bba37523c4b501db141fb50bc54f4b669d85347dbe60885be42bb658a8e12060ce0e401624be05ec1c24ada730c24424c9bc60a9b05d1498a4483b26b8ede9e1b2fe1c1ced572e0d5d5b09e86579800117244790d54a62726bfa3a4ad54111c437944835408f59ad7a0575518db36bf45adcd74ab340f53bfde8e57e92dea3b6a7d976db5a00ac2bd114d02fcee9ed32ad1a7a13758c534a3f6eb7b107b5199b54c994d23756b13134b4065aeb88a89a9b09b76caf0edd6d38fe7cd9774032f63f4504e50d912d5f20e1f31eefed692f0c0847a0e2d25647db4692eefcb67b0f98737cea66757b3df306722228e90d218fa01257ac0da7533155bf0b7daaa5225d4379cd7f6437d5a8cb1400e52fd94df54496ab3662e45bb628d4c96baa507b10708f1997cf3f4bc62108bcabe2058a9fddf07495cfbd7c2a91264995a7c65f88f25f8cc73a6341cd620b1ea6be7d23cacf378811ce03d77d9d84874a1f7a37edc454f5102d4b6d46f1af9dd9c8f3bd0be05ac2e23ad6d5bb41a7751a7563299298ac5aee46ccb32a493c3e3ad66952b8950f19d1019ab58765d00a87cb6e4f74410bd46cda74860d90bfcd6a314e1fe5498296a8872415d374a638d8ed560e00af363eb1af474be3e96f7d3f6c8f4a60eea352d421b336371291789cf6fbf596f581e2b97f72157be64557e861bbb56e75cccea6313b8d3734826178ef779ba3ac3547da7328fcbc494ce9ace23043485061f569d89b2d18523353633390c06b727adba67e76e815050495e428d6550101744a4a105e5ec20384472dda2e272b70293559f1149fd0d68d6eb779f52a7da5c8f28a37f236ea9b53391b81fe20acadd69be08e545f9e02df6bb9d1105761d33926edb627c90a5225b9c62bf2d93aaafce66b2dd5287ccd6ba5a6bff7a776b5522f825457f720720bde114cab9d44bdeaa0effb636a6dbe1252128dedb1e488eb3c642935a04515c9e94752d28a74fb05a8d7f726606fbbe5eac88972a7bf5d7804da7d6fae53a55586401704b2245ab65bcb871a467f6ce38a7ecae552cbd74332240cf0e437cea8a185ca253f14946c8123af39cb6ce0b06e4f8d1104cd31665a69a1657fe4e535d7cbcbc6f4a6b25cd93cc2dbedbee9308840c63ce59ae66b86a4ba22ac1f4f0783595c7b87b2df07197c5fb5d5fdebad67eaf1d0a8d083e7adefdc1b2bfa6e70b4266ba5c525081d6fc247ebb93420d27a09c544ab5e8724cd32967948d295a5b2fa093820068f4dfe27cd3965a3e9ccfed4459bd0d38df8438f3eed0b684e3bf9ab76135ab08e9d756b4d474b47cdb65bf6686864274fd2d2f234d0a559f47a23a3721109753c41209a759c683746ed6106e64af5e3b1accf2fee675c3a9210a536168fd89174c169ceb140e363857b5c9221e1c6c8d159801179d41c690dbfd03d20460c60763537f6f59e319945a765962ff2b9064870e1be2388db8385cdd322b2beed000f91729fa5854185c0607de06783d8445c375ad0a74dacc1b0c7adfc7bc6c16f99576303ab0f8bc8cab6ddb35507994e181d8ed8e374c2683a628f8610747a9acae560957e464392f699a260b44b8130498fd8482b66e56438f2ded23f7350661d31dccac1be6942ffe79dd0ff07362f0b779e347b999ba400b995e436630909aeebb284d37c00a5779c6a9dafe90e1ff1a629d053dd7b69033c67112da27b6bf344b25575c265a909aa9926cb521a6ae57fd600f9ea2c2630c7ef2c0bc949d901c75fa1b209ccd0f5e5ee9532f6f0671e1db3bf987142c25f29d8d4e8dc960a346544ce08c75debaa32cd65fddad7c03f56db65d5c93d98977c9eaa83afa3aebec44a4a0e7ae98dd0d3655e641f609fefd910bdfa904f1200b0b44915484ed3ed564cf62e348b8f69175a9d72a086c7e43b58f8e326d1ae7338a475f2861cefed889eeaff7c1ff66c9611b7675eb87dec8a08ce3d7bd47c694f77089315a7b7eec0efe28521c8ebe3cc7393d14978e1cceb965cba8e7b538b35fd812b06018d5c47149ab74bd110ef8801cb1935fda5f51937fd38abd5f46de653367802483551fef06eef773567a10bbd7eb5af987aaa4ae90f3606a23e5615e741bf1a8bb68ade9cab475ff94a7a31f3b6adea98d171b732ac86baeee9aca1d74edb077053c7dd51c473f8ea7caa8e78d2b8bfcfd46b677c5f354a62f7c7f6dfb56a3456026f7d9837d6010825bcc9adadcbf51d0bd29d9eb687410d47c76488c9319e0e673b522df345579465b0be6de10d6f15ffddc764b8671494902c2ad68edaf27748edbc6d8a9b5388f9718aa42a85dcb3719b15c9812a6c6d26412d9a08ee270090742f3c7ba53b233d600c3b128f8f8e5d620d3d0f809e06fad50bb6afc16a2cf385717c658f1a94a57676dd231c3472f598b7a76c86c75db80a86bf7f22255bad012f4db014f06c34930add8a1024b5c61ad026afa2528b03103b5ca9a78d56f6633c88de144cd182f992cd2f237d3f5ae4a292032b4ec0fbea13f99c553aaac6683f0c8474747e0311374a06eec8f51e2c404f2b0f22c823e1c858c5100ff860316530c82947dce739f99ed44adc1ca76d26a0c161027fe9324d214979cd294a924202ad3449906a009584ef616390ceea6e7ca18c88e2fa7358543b81190b6688443a29795e45452a2e985013c9a3b8efaa1cb7b72d2343329533bcdbedc6d358b3673189d52ebc8949bcc80b480a131b53734c62b3056212ff5ae63c26b192664edccd55ba0674ea6ca37811f3e36d7eb154d5569a4389ab72a5fe58281df8f9b29ca705333766dde1172b3e0d51b8c30db567bb5812b66f57bbad3c6533974cd247cd301cf09a93331e665982417c92ad729e5752c3bec464c9bd18e41b9f033a03efd6338ed8f4e30c83e2ea8a930b4e6f77e4fc0e0d962fc2696ee8a42563792d3b4dd7ddba283f6790e6c3a76b3ea31786273fb3261fface4f0f64fc544de6851a1c5dcfd7fbf46246e35398fab603ff69ba6eaf6658ccab741dd9086e552c5a97c5cd4251080d52c8a2f94600acf0b928af2b2606d1532034e7e9392b8e5c69489724d8d1afd543567df37095ae07bf5656da3ecb52995a9725d3c9655a9da6ebf0e68a890b3f5580cfbeab17ba7458f507c09ad7544b34df0ae1cb7a9d6e0538a85ad7ea1dc2b6ed6071346e144e7ad0ba97f74627605e266f893f9171ff1a31dc8f2731e91ddb213275560cecce982c6503d4c21d48b6a8f19584b0a71a85a203d13fcc3f121274d73f4da53de580a8950340abf9c452eb519c66d99e747892e8c0a95dc3bd04465c52d14a0fc8b5aaf44cd76d321b1289b574759666597d0f46b1a947558370608a5397d5af879a5d8af5db8dae98f6877efffe58d9f17372a1a07c72a0c63a4160bd56f5da319186e6935ae433e3f263e8b9216bb2d01205a51dbd17b0309e7329d4b102a25af8393f7da40b8c3145fce544782d5d0ab0b5d8b10847bffdddc30bcddb351ccc765e7b24eeacbba9786fd6ea750f726a2a56a09950537624d434265a3b8529159303e91e6b154430653e83a2676f489abd22a21ecbb489c5e7d6f7de1e3afda29b7f4c7e6ca721118eee909a15223c2439406eb819334769a4758c277ccf421a2aa962effadb39b7b2aed16c938a3d23170ed3fe04600dd2afb7e4a4a5af43edcda6738c8cda453b33c4fc4e861f358a7b8155f73b7b78bdd17c40477e95aa1b6251099b84fb71a75099097bb1f4e684a35bce3e774ab88f9cb2d620b3699f743e95fdfe0c93ace46cd43bde8d6ef5afe16eb76bb4cf847ffca71ba808b36b9cdb08d02c0bf8a61b3c15264245e0996baf216a7b5b3d456b4e3f12c3696954c152e0bd49685c8c4bd877c34777ed70220297919496b5a6d105aae73a50bdbe65fd812b949b8dfb1584b64f873392d1627a3c1bdb8cce24231b8d65e64596f33d91e57992988f81013bad23cb0d2e511a449673cb52bac8f2a0dbc0cced3b98cdb09dea6033c428333ab81671bb51bbfb526ddf4358a712c819276cca67102d157a85431845a73ca3096d85600cd5da19ce484ab91ac3a06aa18812c6a3535517a4e074ae6c3d7074d65908b55b418db1a5112be6455a55ac32623d5f32914bfde4345d8399cfafcf20ca773698747419a0cb462e9cafb3198acd870fc67d7dc0b73929d0df766fd071634e32d63a7f24e10defa7b20ead83d82bbb9c53bd9ceb5b562f909aa47d1e86d0cecf24d6bd68d324315582fc25ea456bf2928960d14ab368a55bb4b89d70d2a8a8ef58bc1da7302782de204e19b649c9610478733d723cd96ff4aac08d693ad4d1779073ee54ad753fa08ebba8c57aba2f988cd45d3dd10fe23e8708a7b14f57ed6b03ad56e8fa3e002c084fcfb6c35d7bcf3b8643d651d6629c5b677b202fbcccec7195ff8bc5e4b61bc9ee0b4e4755cf2e80c71b369d6476b80127fce6f50faf5b2b5fc9fcf476d75ad58ec3b97b455728ad09744173455c363457c4854f5b1e50c5a4185da302cfe8c6ae7b896f995df7f2c0ba97feba975deb9eb94c9566dd5bf1ab9d2daee37833527a57e2dac3f9e5f4d8de27c59c476dfc0a4cb6b9db28eeefe10ff6c6f55c238975b6572f8cd6e45620518cfb71b46b22431ff47cd9e764727f1f9b1dc2e4b4a1c0029dcd39c7e42528a12effb34aa8774c064a285fe974c567f425270d158d4bfb7d9636745087344fef98ecd43cbd63728fe6a962b2d63cbd63f23fa479aa98f4344f6dff2f16f87f3122c080c56af47cc8e4d1ad83fa9d4482dfe3e4d5c4d00588ff9f7602ff4e3c734573d745c32057a4fa5f6490ff3307e1017fb5df7a08a659764089869c1202ac3bb51b51a7566dbf76d053ab454e07eb89f1f8b6adf6820e411c7d873310a8afbafc23ac52a25b4b77a8854e8fe3abc0765ea37f6f05a4d335752b21ff4d1de49d6ac64e6f937f47497850717fe75286109d96c6863509c65e05c390c87d9a850e9d83239887b40e0654c299ccfbf49888968e642aa76246f854cc66f7d1901cd20bd956dda5f33930a4e33bd52d8d13e337ea858259fa0205d1fd44aeebbbf5054dc17fbb7d0922bbd4c72cda23587bd20c044ddf47a8561ccc1d42f5efcc4fde8f737fc76437e77eaf44cf6dcebbc1443778e829bafa22ad99b7b8157b7cdd608f81b1bce4987c3ec81807711a9a2f7610095a1249c5059336b799f5916c31c54dac179bcaccd96475dc0137f6d8b8934f1441466ed6d5df4027ddc8f02d7279c0e2a13b4202d751cf0022c29c755868b48b1a50a5b6f2a9c317e5cd23a9c3fca1bd32b65bdea1bc774754e892a14d31e2dea698d0cbf28029a66e8b3bd2c49d3619d1b4c984de93bbfbda8c2d96f38feca6b24992bc5bf592e3547a73e22cca3655bcf134ed754ca12d69ed39e2a0f1984863c7e126e9407331b5208dda5eafa1ecd8b5096c83bdf5d7b617a7079cc9b75b6167c763c05ade3d69bd94d27a2969d9a4366f750c476d47b70ecd30283926d272fc7b586f4118e9d8a9eff994cdb65b047fe9c1ec0bc33dd917a4f12854c400dc129a99586c010d4105fe9a3b0ca09fa687e0b2645bfa24cb72470f5a736c33dd77cfb097d2c09fc246887e7358651802634073e03c411c638218a5b4043c6306490f1431b90b32579014e3edb677dca3341ff8e39a24e6a60d6f53d2c53eac5cd93569cfcca43deb98b43d60d5f7caa3f1ceacf3fd53e94a34e652b635cbabf28a356385fc61f6d97bb977c701e92e0fee3819ee38fde5d8a7d7e2a686ff0a248936592229154acad5e44b1d33ea4a2d09e746e09f926df9c1abd1c910a4493fad1ea279df91d224c9e1a3bd63bc332905bc119ab299890c71a290e975d701e2c515a4a1074620fb952dd8b390572b0a7691163a5973e3d00efd40edeab5d86351b980b4bbeae7755a45a9c9f70c490c37174b5081b90f45f3659af341f4a162d10383abcb1ec059cfd22c926594b179910a665f5b434838d419e51272a4e573d50d577f2e1f545179cd9988bf24feef3fcab576d3b84ee6e73e72bc9b5b8f51dac715a873391060bb5763ba7735a649a2bd287a43bc3bb8fc5bde0c3f36843d63701877d5d2f2a29cce3a6d12d697f2379b26c6f9f478e6636b3007ad5de0ff5d8b44906ef123dfaffb8ee396f2fb04dba33ee0e8bce3c846947fac41caa61f67632d2d224951db1c1b8419bf36f80afdd8a9d6e1bd5611f3d8839cf90c365ce3f378ad43d91d66896a925a8802589ef7bc819c07b9a0c8b3cedbf568bdf35856e647d36cb708c0fa6bc7d7d70d514bd7dbf4a5fdecfbd2bef13675afa79d6975b5af8d4bad8f6e5b877eb6008f984379d3476080f258ebd12d4c2c800da4b25c8d1d58a43f750e5bd2824eb47060e4c4f3601a2148d8543b0749bcddf2c0430d5038f4b7851e2d08e283aeca24010cdc2461533923012ab39ca8ba7df4dc566d2387dcfcacc6ce3548baae570e62b43bf59b2a0ca3ed8f82033c08c0217f0dc937530d899f03847bce2fa2aa5c7988211e14f0afdc41e48fda0d059bb4077f39aa179786b9809aa0293e0471d0161f78d87cca820c079503d0e4e8390cb306e457f3f1c26d84b64aa35eb04f9aa14c0d6a7174dc865054acb2c32d72b29b492975fc50527afc90d7f08872bbd53f78a8aced79b8893dca6dd0aa81bb180773ab93bcd4688ce19585f80a91a62bfac21858343052d5a3ee0ef714c726eaacd26166f154571bbd6517cf3faf6726a78ebdabc76f169bc0b238ee4b4ae3b8afb1d65cb15710dcee8af5658ff6e5a4cf7bb4cf4743aa2e8e1ff6f5488dd4df6605cf52c99adffe56e3d879b5b6dfd36aa5ba7d1bae6583cc3339429124311a28d886af1776a428a55d0f380ebf739ab6878649f55d407615fdfe4ed25790808babbfdc026eb8e2a0349bc594526de6280242e8c3b6dc35d11b2afd03896490e5cd5dabda373d4ab324e975918b4d926c7ca5d0a633d966a6b397b852194e9200b02be7916cdfaa9bbacb1708d04feac60b886c176a938d739a6fb753cda0cf294a690a70483ecce6787e743456a24d3a9dcf7cd8d15c5fc39e4b1d3c50ae7f714cf4d0a239b5d1b3b857477ad7cd09bed163484ee733c2d57fe2e818367ddd19976f72417d4f1e89c9d26227e40b34a70b1b8118fafb98bb3d4ae77bbebfa40bf5e5de771c71b25422b16ad0523568d9d52017ca09408eaaf3f0b7376c034bbef239ef2632f8a94f5f5feec344f7e0babdac3ddf8547c93dd92c1fa7fd2404bc6b288967f42df7b304bd6da853d412f376bc5bbb6f34d7dff5487fe100c2c4f9cfd1d7fdda1101aa827426fa4d0b8b36884e16d14db91111e357b92839a43db169a9abcd5ab1eaee1d61ea312f9368ad63f4b2f29a5f883483fcd5f0edbf0ca2ef4a11418aade8550a99a89ff04c9479462041739e31116dd6ea2d755cfff0ee6929d820c6e3164b757676fafadb9fcf9e3dfffbfbd7af5fbe3bfbfee5eb6f9fbc3c7bf1faf58f67674972f0f120e7aab2d3f2fc33baadd637232609fb2c455a8d6e2f98840c5daf9420f594efc81fd5d88d3eeef0ce4b57c9d15fff8a0947dfa8039f345550f1a662914dd6c6071992249ec75df12d670c4c8bba48da59e4d22f72de59e4c7da299da36f944cc4d110d2470e384a312929475f7d8dc7fff5f04f7f8afe476d0d5eb148f5eb08b2ac45575f0ffe32f8cb7f457fd291998355996d0a36f8b5faafe84feaeed3727d23f28ba58cd01c475f0d8fbf8e4ef3f99215d14fac92c03db38129fb7e995751556ec49c45f332832ce4e69359a4d6ac7677393d796f6f470b13b1a91ea82a5e9e3c7dfeeaddf368917b99cbcb5246592e98a2c537913a4bbc0f49c1a0010fffcb6da7aade7ba8eacaef614fce966b5a639f4eba6c1b1671b213cab0f3c8b19f0bc42d773e2709ebb9b3dad198896ddbc87d100719240a2773f45090e548628f0abcbf593343098c5d4fade428d5aeba515a45a9cb451487c979424880e1983fb2a7ce98f7fb75ee373e1b8b41ad5ea4fec576db3b2622507fd2de90c4c092a8631520c49c2694f686789feb0811eacc51428a9fcea711be9f249bc0c94482f17ea3ed061ec19d375f0454cfc97e2dacb1fbf2c3be264176763c324908bcef2e6a41b1ed42266b40f0ee197cb7593311b1cf6bc1aa0af2a86e2a19b15c2e9988ce19a0966b80c47a4ac76c2f423d64bbaec7ead65b9c236be70e32c5373d6b762022ae1a479f9782092ded27ab00357bd289a5ddb9a1066767d0c4b3b37d08dc0c3776c62a90bd56dd4dd86e3b957edef7a824b0e782cead03c8d32e9e56fa24c04fe812aac26b8c246faedfb205138ccfed84039d5ba670f49e33c69d515e11d423751a3381705042e7498dbd34874aa6f4a049cfc2fe22496f354a7935badded883498e515ae7f82187a43aee859338fc9bef4fdf1d919ab4ee12889edde515bc268f60ed048430717a500fd677d896238b006ac608a2589f1e89be1f1f0cfeac4eb28a5da9d16a6d037ea3cec28b410e98557d75fd569d9514c1fe767ab3263a6e47f93aafbaba2540797d0c58eff428a7dc5ae14bb636afb7fc8a6b3d8bce4927d36ad3b1e2a71a8a3545addf0b9d7b8e36332df579d71340d4b2fbac7a614d7a9c8ce045b98925f9165f7f06caab53acb4db13f935567b1155b95a6c8d764dd59a448ff75638a7ce3a7d666f750ad1945e0e08f7fd44f1b79792331b2c0eb9401e6acb99f81ec1bcdf59f5cffa9f49fd2a2ce309771b7ae441de7f663a6ae8d7e6da1ff14edb7ed69b3db4189d4bbe165236d44f1534ae73b8d93fb7a41cf881c3c51537e5a668c66440e9eba79855b737d4bad9ca725afd4694537f5bd3766edd182c8c173bd97a82072f09d9ef0b76c4117ead2ec0d9a13397863d635add4056c2d9a123978073b033e5b1239c8abbfa7459e995ad5c1d56122e9c4f8eed0fd6db78c52254bab3f73fda7d27f4afd675953dfae35013981ec0c514ad7db6d70bd6a5c178deb4de37a8177d0c77af43bce2bad5b37d396e9171a1374636f0653d45197a965b3f35f70f3b7ff8542bf6027b7630a0e8e5ad069a1ebf217c7deef2e4c59bb72f697cc7549b7acf697ac4c49bde6f6974b75396f41ee2f5b02cc06baa15738496e06f551e5ccf08725fd1b129b0d1d4305e6627c65f628b9aa7728b96aec4f7dc39ffafa8e9d5b72657726b9f2f6a5ba30634baedc9e543f6174c895b71fc955c76e849b7ed39a6bd3de6a34afb5f8e05edd447f7de8cbba99f52ceb0bdb547fae802bb808b90b7ccb2cfb41af94187c4e6fe7cbbcc84c53547f2ac394daebc6253c3693a366505fe7d5ba486f40c6d72e2dcf1a25e096c8af580609c3bf13e54ae743e87ee6de5be59f730ebfd6a25cbb0648ddb01d3935b9767b43627265e9a226b5b66abbe2dd84fb05f71c388cbec8e50d54f692deeec62fa717def298d15bbb7175fe282570df6308fcd6ee602a2e69275f47aebbbd5e544515f9dcfd509ff215f97897c70c794f3bf97bf2ac65fe8046d64ea04146a8165cb836a73aefbbf7886b8b768fd26749a25e4dade52ba7d7eae967c8379d5b04c9cf88638cbdfc482fa7d291c8d9767b4e2afa72cac35b051d8e8b472e8b52bf5f58c4e97c5a801daf874ea79bd9762b9244c08f2a492af851264939ddcc5c9eee8f8843565971737b8924d990cc4bd7ba73f66459ff20aff7b890e2dbc2fa2718e4690f99debeafa4eae9ed25bb19c5258f0dd2f6617fe5b02e9ba69a34a346a9f40a790067806fcf95385a3ff610ce76bb1dd1ed61ab5c76b5a8f1fdcefc4e752c1484e1ec66b8617f7fa36a7257e004460ca839f612ac37c1ec14f7ee60888bc7df4c8aa36f46434c32facd387b548cb37e1f6fa6d9d1373eda5de6ac987a712331d8700352869ba96cc0a4103f7a94f292dfacca4df5f8714c2ac50da5c458e4a6e94c5bf21c3880ce68a61e4c6275118f3cb5f1d8f39a36b2e6fb258be27ed98fa34f71bfeac79fa2bc8a56a9b8d429ae8de21874759f2047f127129d6f6494cb2a820951e53fc57dd18f3f0d6a7761f5e9da7558435e19e8f3a91bde99dd6b1b1d226517cb79ce33303e82dfa3f32dcdabb7a63561996190e8ee79bd542bcfe1b415301f03ce593c0a9468da6838b19c52276468ad3da46cbb45f13b7729a7f1fffc8f173718cf3a795c2bf30659e68c227f8724518d735a40cfd01d266cf47102eaf57affd5c592e43982050409f964f9b2bc66e2695a3184837c7840fd1a7255fc440f5e49c520af1a6865e373c1d24b6d6f34be24ad82fabe5ff2345db78b9da66b53c6ca522d4bc707aef3b5b30cf4dbc01044b15d59d22cab02b60410e01215d852e536797b6e7c9a6b66d9244c667b7202c6e0c23d6e96d02bc99611ec827d5ec735a94685a2146c1247a5887e4daf527d1eaa9dd4988b7efc291ec55d5bf784eb9c9fe00d67776fb90055b5badea8eb6ab35e173903173ab781dd887d8250d57abcc175ef53dccffa717333e330f3c8d3fbacc67b53cfaf27c5d1d79a7a7e1d50cfaf7f33f5ecd2c6e1f6203ab7456f00e7e56a5d72c6a51db1689956516e86fb8d619c225e4af0211ac4d616a3b6a8d91a588f433b6641a718330d11e37a88d40225191daafe5b06420d43be404850d920a205c9f428f7e329ccd72cf6c929deffc5f6a4fe8a7ac7aedde469487f897eaab6a7fd6d1dc4d4e570cf8b433d262fa82e635f819b4fa84eb9f54a71b3b5f5d513d95e694fe7570118236bcc6bd3086add99e10ab9d402f1d9d91f3dcb97230d8cc4118a1d62f81312e35a7ffaa4df27523babab46000d39a1dfa178ad38b053e0f9634cdeba5b2c7ba60ed9dca8df5daf7e0a92054d4f66f0df767bbb0338163983ffd4759d4aad28e79715357fb7db2111831593cb325337cdafed763af353adfdab69b9d16e9fed8d977a1b4f3cfe6a228ebe1a81e9f0ab71fe488c7348fa998748cff96c2c756bfa7d6048f599e0ad249d69bda42e8ba0c6b9c2a4ac7d28750d474744a780852bc5fc991e7587adb11a2f53f36faec77f0f2890cff8ba3168755e789de790ab6a9c3ee22ee591d7e57436fe17c8fde6fbff2253cd4113e9f69908daf36d7306f4d4ff07e7c0cbd53a2e1fa52e57ab35cb55349d96b33177236a79ed0a3f1a26497d1f18f5ca9e8c77c53440b67f70f1d96e7bc5f4edcc9e9ee01e98d10f602a2b268567011c193a0522cc7efb5ae60fe0071bea66b314e6a4a47f474a4eb34b6d8e727abb236f81e99ba39cc4174c765ac84bc86faa4a546189d485248015c67dc179c4e4f4835ebeb62d7bda6fcae400dfaa3fe55bcae2ba8df5b0c490ac17c6fd077aaba8d23b590a568d5eecc6ce5e9516e8074dbcfe08511eb562634fd4fc0f4d50e3a66ffe6979fe393a011788528ca29b7213812bbdb8c9f985e20c5229d3f932fae47fed530419edbcd3d0fae567d1752e97d127ed54f12942a5883e19a77af109472f5e3f75b0cdd59acdf3c58d06bcf06a5795ab7bd7225daf59e67dc5f8fc0fa213c088d63efef979c182c8814fe6c5a7f6bd4f31deb50cb341f8cb8ee4951a093710ce4275c8dc199a7efd1c5adf878915623d1c4771df24f334ca96ed56da0824df1100dcc6db6ed81ff8252fafd511c29304893e8d8fd4601fc57d6e13d9d79c9627b70acfcdbeb03effe303a4300d49614e87e3fc11b7b4a741798c5155528d914310a34b45fe7c0ac9348574d431c518e341a5d67753812c0766f64e0c9742d98e3845c60209b54d3224ac3e422bb55a1a007bac2a2ec2460b68ef111d2ab1ae70fdb399314ee02441902ba82e3315333bc80610c22cd941bd55e1e836417ae62986e3db5167d5841cf366e6ecb666bae73b2d24491848a57a0c2156db2de203c1160686de8ca7759840a9b1eb1bbd2cd699ea77334cc40ea503b73feaccb1fee2a482bc433924a61d347714959d4e1939ab504efea8e8985b7dfff413d239e58be769b12728ddb9b1441cfb5781338be1d4c19f2c77440c66c34518e51540bea757695ea8adda8b4ed34b16551bc1a21ce888b1be02163c3885bf71e6d83104d449c5e781e7959f44d96eab7137eb59ef92e1cc39ab53ff2ef195517abd7eaf8f544fb1e19325da3b2688d33388426c3d1b125e2f3549a733a29d745ab91678bf8fe594fb1b99bbb5c8e83f91f41475f5447d0f1982a409813f8ab149fff8372a06c0466fb731fc8dc93f14f39b571ff8aadc700909b17f568d674cfd2fe17fce68970ff34f2cbd3c4dd71335bde6b7e51884ced3fc9aa44cd55f5de6ebb77afb639233fdc9ef4a31cff98506b98f312959976f416aadd96fd9c2da78907f1337fd1a7618d796e4daafcc815399edb0cf0fd426763ce04f14c6631ef02332b48efb49b20b66f64c3958e43c7bf6faf4559931ec25f1369d0c9f23e6298e3bf473f0bb760163b532043e389649c299fa6762641926820dd82a97e8161254d6045aff7d9fafd8880db4dca527ef39cf8ec23bef642a2491a54c0b28ff2c956cc0cb6b843b0b3afe60c4082f3308aa86859999f552cfd79c3977ab85fe59677a0e5cd4414168a31b28f3bd7a68a58366f423193aacf3c0671a1239874ed47e3e2c3fe342e02aad0d132080b8f4ab5adcef752d30494059b7ddf654a7a6ea6246a4feeb4543d89e7ace672c74fd816821c87fbbdd1e3f64941e3f942306029cec514fe1b8641d88f2e0bbc41ca9ab3d643d99b781f15550336e36f93ce19e8ff94623d407ea9b9fc188df5a04b45e23da2e62270289c1595a14e53598e7745c628551ef9854d807f862bb76cdcf79e6d70b3827e6f0c9cc2a97984847ad775e0c6fc8e5d9f872f333e0f550f356c7bb2d8cd4ed367ee4d6fde3d886b79f8122e3c42408b42c944178eb7e38381365291535387966bef69b6ac9d8f9e6624f15dfe5e74c74be0f4fdccb16f19ba41ac3dd5ee67069427f98d625e98858b5808cc2500cc0955c2d93d869727212ffa156e4942436ec13649368a8057b4592a002bc51db27861cb8e1fe292f0af894e6d39b772134a147a99cfec35aec18ed0d6155aa0e416f8698c869ca66dbadc78785287073a60f311bbe43d4a9e95426aea6634c58926c60d194958ed3ae318c3603186e8f71038ff5e9df6654a3239bf1a09c706fc3c24a5e3125637add33c77903861a3acb985dc8babee9df660e57d05cd72dd4608aff98a9a1fed90d51c10cb160ee50a9e3e59ba74ac62a29ca9bd823feba678afeb31ddeedea27cff2ecb4d9ee9f93c400a5e3b0a41ef3bd45750a72379ccdd201356549d2910f49eb1a674a84ad185b1968e43412ec480f15e4345f44a9898cf0a4df2a9222bfb8604289d94be30fafc3db23a445eca32acf188e5665c69c9cbd72ecaeabab02215f7f8f6551c98b9ba8e4731679b50c4cbe9581fa02d32180bdb9117e4026220cfb42ef9af90acdef8c0f9f3aaace6aa30b89cf807d795116c0b861921e289aca72e54ad65fca1b5823e96cbb75a48338c2afa51f481c60be905fb128865c8fe6bddd0186ecb7409fe4de26ea06779bf2595b27030f72450ecc004ff98c303cb19de284e111f2af884f2a874a466b7db8c6a008c92a0074d4ce94354bd476c46b8b5a5ab6526790cbc77fce6a092aad7456af18189da665d5850ab3ed164970fc0f76c803d0465975d128fa50c16630d7912c8d901781a85ba91d91b1b56073d03c55b95ac17f190c3556c4a7ffd18555b74ac18e6312e95f5fc538fa1f57a9dbcb4f8bb4aa3e45a5b0daabae17917d0fcd83f730fee41029ca45f4c9d58fa6ed5a66b8f9d5076a454e7eb40aed4d511086d11980468d3a5c16cca4edc636e8dbf25f4d89b149821a03fcb1a5eedb542c7a600b3c003d9f478234ad2a044bb31bb07c3dd043f5c0111be8815fc3395ba81503f7d537ec1b3164d670aef594a683371bc1dcc0dcb3e51b5822618b817086b50da2f74b56b1485e97513a5fe6ec4aff2ed7ebb2ca258b2ecab4a820facdac6a93266e03b824e505934b90334b8086f0fc214be61c2ccc59d78c6f369b49b437932e0f565a3034968ba8f6de026814d05cf8c11ba134b74f64b567aa13f06b0d4f4329846e18788c7429ca456858d45e3218ef4019d3d143bedd725f6bc55b5a2b5520af607e60e187ec0f7806ba280e8e0d6b50928a6ce81943a8a265a02cf45c735ca38d8653626214924b2471607a72c9d570ad5604d13543f24eb5a2d3ccd4f17fde8118a8fe40d326434d1b2903151b0f797d8d4745ca81af0ed721cfee929403e79f07097fcc6f55b3e7d6a7aaf62e4955f384efd086704c363b9dbeabb52acd4e5e433858a42ddb1e0928bddd66acb673ea4df576cbc73d7f96a6718b158b49dcc559fab71d2fd6998f4fe2db5ec875818d8dac182414d4d41163c2069d1cdb64cffd1ea5ab3d8f9af4088e98ce92ea248852eed93da2f3b40a0c19e0b85281b5e29c2dd3abbc14706cd46f284ab48228cbc2a01c6d6a6f16c1aa4d21ab41749af20d201be5abb5decf8a1a7eaa9e7ef8d4a0639cb10cd846c60dcdac99d1418c477b7abd77387668ae08389c363fc386367c0e2822d70ccd490c7b22c6e60ad848b36056746e89a535df5941a4bdd7969e2a81acf08e6841fb86014d68fbe9b001b8050bc609a7ccc4f712412d1122a962654590973e0dfc9af4c6b071e7a899d7f491edaa6147e8603078f8582b9aa3a2e4174cd8b86896b993519dac867d31062ec6e7450973d13271c536d3fb8f886394e2fdf4bb04f20da8cf372c202eb16d660c755d35d37e7bd6541adb2103afa689a57fa3fabe69415760c654ce3aa35cd9349f4df6782591ac84a5b981fcadfa1bb0e8cd9968227dab74c52299afd4d07d8afb1c8f3ace9d66037af76940f429eea70db7a80a01f9e8708ee20de728fbad4f6aefe855e44942172ccc34ecab6ff6398ca3e63102fb058f9d0b85bec924bc1684379e33e7f1ea9eb74d0bf76f49608280cff30907e8b09da77bf11a706a6408ebffc13dc39905d583ee8cebfb168f16ee5b38dab3503bf48ea7eb6a59caef8af44291954365f4572e98b437be05c6d364bbe5c483e0f21ac1fd4688ddee8679a7ebadf198bf62c42ed1d115db910b36383b530b44b0aa7a660490bce43fa582e71c5a7a7e7791d33b8bc0b67dc94c9883fa7a6f48147b02cefc0b70fbbf64fb3822e6eccfe3166b8404f5b9a39abcaa97c034abc6e37647ae19c459ebb548c46f6798d2c153d38941c90d2b66acafb677d839755f30f9d48becd863dd550d74f0d87b8db2aa9dd70dad05f1fd2bd86eb79bd96eecdb136d17731b6acf5a2787f32504b12cb407d8ec439f990794125a08da453a44a19f9d8d72a4241b00e42e17b51c6e046425a2cdb51aa096d0805cc15d40c1d22553cd8de8c286f350f4590d597a914ac0ed488bc211eb18931e1bd8f56b740d30a4660163e76100a1f4f83343808837e5b31ea56cca6777f4eb4dd0199bd6e9409f3492fabfd7a93a4aba837baf29fc75ad35617b3a8ac0c4aad3b2b9f73e33cfc6ff924d993ab80e0c62ac866a77c9428920740f229786e379bab78ce720bf235d1c531d49032b78bbed4927a8b9eeb72485a729d7ba439792468348d47a46ad07ea3a9af71e3fddd1f2fb287bbdd7f4c103b2ac0e762029b57bf26e853e8825134ee3f6dd78d4f9fa8757ef9e7cf7fcac5d5e2722dafb38c6f7b22fcc597e050ac96a221aadf21f7e41e3fcd7009caab38d41e5f769aa91a8d246233fd88cc9f76d9e15b350dadd3067d23781a95cdb607b940af7cbf1b32c14ac9911acbb7c01f6afc4c9dee300e118ce8a4e5e03c763bd535c1842952e5854b08b747e1315f982cd6fe605aba26bb5638c7ca6511a200194a7a5d7929ada71b584f0e4cd4935f885ffc2c1015d31d09509d339dfc8282daa12bce9d29c6beab7288ba2bc56f5b45a308afbc88ee624fe854751dce7a338c6eeb6b0b745703bb5b753b81dabe6a863283d2faf98dfc55a45acf188b341f492a582472b500a9e971ba9b17bae35bd8b964cb0d12f7c29e5ba1a3d7cb8381facd84360f88e00d7e0c80dc491fbccd1b22c2fab1814535f34c18a487790017ac1c881fd48cfd99e7db18f46ed0b3a18b4b51d9d4416ce2c4b62f72ebbe6e20165ad11b3b47d236a7f0f612b8dba2320c6e3ce2d4e4f9931c176357cdc75b31b909ddec5eb4f0e1518f1711570ac12208076e892e1f177283666c6d7dc2a950cc2fee0c041e60501383c346d7e93a55abcce79cc542606d5fae67ed5a87b1db574ac9f72b0e11538f99c9debb8013d8895f350aa71931846b7c298bbdfa9a29b8289d1de1a76cdc0a54e30b983386913ef8d51850e96b59adb8f8c02a41a0c5737aa9a1143cde56e47de332b77bd052b161323c16a13edb737afca8cbd65177925c5cd88ef79c4f433f01f71f35e352cd75d63605ccef6c0e659e32dd41b286e2aeb67e8143fd6ddd425f18bf1f8e7ed16fd4c7b43bcdb8def8b4aa79d0ade33f2912909a9b9a3027c398bfbf695c67dfb33e0bea1bf00eadb80a31c934ac3c115705d61b2a11c7d8d4946a7f1e72226717111937895c524ae5631893f57f18ccc6931f02d0d4ddf3863841a9c576f045be49f893a7f811354734a2aca066945e6d469dbaa499ce557f1a822166312a583142346a6b1ad2426b1ab2226715ac5334c2c7a14daa8e29cc4f3b2883159d1e98cace9d4393166fb531e1bc5175d4c1904fd19307d7569388bb406a0ad1d06eb4481d53ae563597726df6e73c2693a28178b0ad2d3a48352644c6820634953a3ca5383a9d8f9497c14f7d9288e8d6e4726c94ac75df4345e731cf797fd72a4fff4556969b91e91246b5d36866fc4a680b005b85700da634b70d087af8c48b9dd9a4f2e31295a3ac5796d434f31badd9105b9156c3192c44dc9a81ca48db8b3dcf977afc81a1b63d1781eea249f96454ce420a5f3f652aef11d38faeacfff8dd15d708abf65b9238efe7a8c09475ffd3756eb1e96ff5cfdf92b260bf5f72bb5ce38faea582dacdfb0f2b59f01d968265451e38ccc831db1a26c70958a3ce592accd1b2527677aa3dc50360037971fd90db9a26c50f2a7453ebf241787368bfe6a4c62fbcdc60632df33254baef71489ed9762129befc4333c76ee7399d968455ec9a30b516ed647b9642ba39f3eb7c5aac1a6624fd3a2384fe797b8e5c9bda9bd02d702be6830369001de66834a96eb37462e070a3dbe4a922b08cd27d30db99a39d1bcbd5e1783345cb1b05877e482dcdaee19cf5bb41c9c6374432e064bc11698a4d5e86cbb45eb89be3189d378149f6fa42c793c022285891996d1b9bffa114673c2499e246ee43749e20dfe2a49386cbc1559eb9f66dcedc65885f6ba5b3341232dba429da3de31b1354294ca2adc4c2ff34a7eafe6e4444d09ccc89aaec8d97d562dc9035acac8adfee68f1ae5e11d2b1401dca92d947b4b7741f37ab52f21c5905ec72b9a0f96a5c8ffa5648f82ac69aed6f2594d27d786e8afc94db08e73320d16aab7a6eb355bd76ccf02173b11acd485bf5295ac485713a0aaab895fc7c8bb5053a407bd8310ee595837e456ad9cc682a8c8822c936401d3be24dcfee476cacf0e4d79dd22ad6a27677b263b26670335e1743d5684f4ecf7e3097e03f1e3e5f71b2999a8ecb19f751dfb21393cc804b80a2dc1aad74a174320caebf800a5c83aa773416e9b5b7b095b9b974717e6eb760eb37056de96d731c91af3eada0c9b564d52f6fb4d1247c77fd627d85f86e6041baa81f9b77936bbb3b316ff964de27c75118fb2fbf36fdef1b387934b4576a46a3d307bf38ed96beec1c912f65c355a925cf10f7ad6960d2e2415d9c9ea2226cb033b72674cd54bb2b68d9dabefc6cbaf634cce1af7be89714dd88016e92e9d97d94d8cc9d5bf371f6a0ece2f60df48f65992a5ba060e109809f511e0249ce5dbf01257f5a49d99dd7776988f0848b11206b40526d65f831f9962169ccadccee879d78cc6989c063cc2295b95a1a7929eed5b55fa054b3326be358d199df7e3a325dc8a778a0b38bf83071838343213be79baeba0e957fb58857021e5e49c6449129f5f1cc5fd8ccc930446e228eecf159137e3a108bde2505693f6876eb463d51a8f34373cbe6a2fc2985c3556a01a5e201b578393d5055d91abc1fb5c16ac636949753f26b74ec01dad77985c0dde6dcee59e572af32878eb0cdefab6cc6ee80db91abcccf965c7ab45ce2f83d7e2348617dfb3cfb2ab75b06efcf26b5d5ecf72c71b66ae3160dc95b2b3cc021e409993d5c5eb2b268ab46bdbe5ab8ba3523f057d564aafee87cdde0dbcbef051d50f11e9874768801f5e98941840b237f0b4f0848d76bc67c4a6c3d940961fd66b87ee822067ab4bcc5f11d4e9672ec3d77660bf05a42c1332213dcf84854f6dbc1441b7bb91048c786f8592ca13722773c4f02887f3c74d2959d4250a435e0a253c85be672bbad947fb9c5230a732387e644d090b2a1be74f3159c0777c3226f7b3919a3ead82555211e60549dce3a0e1a4491f567847967a679b8a1a2cfdb2c1af5764759702c70bda86893a80d55d3f09f3d9fb88f28c04f0d5bb836b5cecee9bbfa0fbfdd33b73137cf44a649d259e7925bab324acbd128bee3c0a5e09d6596215eee67ad4530f12f521c0780de6cb543c9168e81971f316a00a1194f78f494a998dd7138fd23187f4e87d7a8c9936058bd998e9ec253bad126af000ad0c6fdaa849844661add6452e51fc30c600f1525288406adcad5459d50fb56fd42fa92850b5dd8221d43c9b94548c84732f40a5c9a952d2d2433021bd320c4f8c1f029a95bb6be008cba9bd73743c1b731a0fd4d065db6d3c70bfe0afd68871ea8539cee9902c68e992e13ca6c3f1e2e84857bda4e574311bebfa96931c95648147a6d6e504e91b64deefe3d13c49dcf5d1917652de609778668e4139becc1712a90af0b8b731cd2aa7c3d976abfe5783a3fee2edd62bed7c164b13fafcb0e6517992c40fe31ea5ab41b539afa44047c73849d0aa4f5531b2f2686f15a0d89b1c4c13f70be1510b6c3648d4c42c2a8bab91219b1cd0cfd7a563590f66e80a03335c146c030a4f2730d43343ebb442ea26bb62e226a0e3c2479087e4ff4019bb60ba65074cb3b30d41a6a19456a84e0f2874f0510a664a06897447becf8cf99d56557ec1d1ed0e08176eb53168e154cc5c237776687620551dffd5a308d9018a3061a3f861dc0fb3481c286d97c871905a68d10d56e4df84c8da10fbcd01f834f1f99204b033e387933fc435a2a66d864b13657ca4eb46b9277edb967bfbc3dc8eaf532c0dc951d8b555e06292ca2558e1959853b154cc97e094bb4caba576c955e4c5db5793586380a2b44fe3490c2bb01e4d3e8a27719f63229224fe832a2a4cd13fa8a2c22b2a46f11f40459e36d23610ee3c60c7ede0a709ca3b500019b493701ac744a8ff522add38c77f880d76690a1e16d28e6e8a89acaf8624c5164dc47b79e2e80a5491ebace4f6a5bc51458e31b9b5833a92440fe9c88cd4248e479ca8b11d99015177c40e80cbacd3e5a876807609ac9dce5f95b3d52bdaea2e20f5686ea670a2a7c95ed6a30eafe89b6af6faf6028feadb31c961fa277a02f545a30a754bcd695fff54afeb5b31f19365d69caaee9cfebceea60909f77a90b17999b10f6f4fbc6ef9e1e03a3dab8fcdf7e1ed091802c19dd85ea0076fcccb51fca05f57d57f104773dffb5e7f2f1be884489004e9921537d13c85f8a2f39b28e50e4570cdc49c7179c4f8bccc727e3178a03655bd3150aec81ee598a493fa9b137d0ed5371ae3e8fa5e7a1724adbbaf46d615aaef7b77b7db6015a8f32ddf9b46a42e48a9f41692ddfb705bff5437614ed52df543dd505d54d797ec26490ac4f46412697c51fdec08d61dd46192cada1478ab93bcacd6b22b8e8e51e9431233c37be9aa7410315fe462f55ea4bc0200bff7e5c8175eb40fbd396e7b36ed44dee96734d1c7f588b5694d3ee978414c04cad55997a2de10fe07aa803517053777245daf19cf5e1aa0e3162833a7bda12f54e05bae063730dcd501510e8454db064580d7cc01ba854aeb9f8abaa4584586018b8fe8fcd6b66181e9ddf27eac0d3dc53de82940cf188ec5233616fd3e0640a61ab146ccc6b2dbcadb8d2dac95f01ab1e68af63a8dffd739cfcaebedb6a77f0cb2720e5f6bdf69202b79aeffc6131e9917cc025254d773d847da57de3a2feba2cbbc92a5b8d10b7cbbbddd35a1596efda420a730c52e6710acdadb1d2657362b92d6c359dc0449380dbf43528a8e8e15e997f6094faff28b549662b0a9987872a1ba561f4f26395ff4d520062e03b667ebe95f06432589341f9f96e779c1a277e92215b92ed00b0a3c5d8a72c5ba9efc048daba237cb92b35871386147922456cb155cbbe2bc399c24a73dddcffd9dacbff55ee419e4ff51b21023152d3514c35bb610ac5a9282ba43a74a928acc6939b860f243c5c4533dd3a931e5baa9994f2e4673724a4b45ca5eea65feb27e7c3af966744a2e291b9ca715034abe4419aa2f311ec59e62e03a60456e77846b224980db001a99daae16a50e2920b947d0fba921bbfd1488ad65b92e01e47e817272893159a39c8820b7e6674fd24fe57220529e952b845dea61f4e76fb0654fbe222fb5b4f291def888eaef55eb7d46e384304c4eac9061450cf271d0a01fe8a4eecd8931987b8d7ba6eaeda202f50eb17c01ac85838be0a9c85fbf8b7512b1edf60dbab6a78fbf87df217cab1e9d236c80a45f835c6b9fbf31a6efd758dd27ef91c191fc38e838531023f19bd76f62724682c81d39798f6e756747ba801d8411dbe10e087e6f9438fdd513122ed98de24c5df6e7a10326f68484ba1064e1b38552ca8fc45871b4af696f485ea014c4074d505581e7548f03f9954e9fab5a66f5383cf526e3b2bf0a02975ea8677c70515ad9f609f54eab57ea2910a8277dca7092a8df6c62296b9a65cfaf18977689a0785dae759021798649eec844bba05af63a282026ef301ea9f5f124496ccdda55f57e9577966dd40f5dfbce421d9dd05b93edc3adf6ee197e4ef421f342b0c5e82951346ed4361a09aa4599cf08f69179198fbbd79920f19b0fef5e840b8d993806b3869eaa833fa73abb62494df40f6420c6805ee5a82d82a0999c408151b9d3060f8949811b1408bc2ba8aca1542b6fe1d5cd86154836f457275156fd633cde187e443ffe956e88bf2da03f6ed4c4ce3048dd2dd88192d3e8d4ff13c3f9f6f99b974f9e3efff746d4b4e74b07d59a0624bed7c06ac9b44a12f4ebb49a51339cde50babedc3d9af5a7f5885e94a317e4a2fc369d5ffaacde0b74740c4f0dae41f84c3d3a2f4aff953653e33818fa71e098792f7dc377db2d7a858e31f90e9285b6b5bddf250952bb8fbc528dc14422c59feadc201d24f4e320e4a9bd4fc167bc0f4085ba3e17897602bbfd25bd5544e03ce517a35b10e49812153b125ac6bd0ead52ef61dc9f2ba248b4e478ff77031d93e2c2ab22ad96411be67ea5d98eb44b6461094f8779e96b7402ad87555c8039898d6a9d909f2cf3dac96a5dbb931cae348e47b67b8adb90fde3803b61f876df22bd445d9fc3fdf80f71df3f8f3e7e214fdde4a83945f76132bfcb055b949f63ac789f94f24e0e32af59c47472314ac1c8a8d614e4edf24c73e52486198c472529ee6023c99cbe9c56337246e7837abec9399d0fea191f7b32869dae7304c87ad6fa0e23b3408c14c02ab2dfc2ebc92fe4f5d4179ea96dfc4e0bfaee3baf6b7c6325e42025369e21aea11695408a3f231fc53ba5a760eaa8bf023efdcfc0e89212c46889ff1ded85d5a6ab5adf514a578a5f32b774db49e3a078869f7d018f98ff2779c4a78322ade489599a2b2471379bd82cc7f0614ef1599b5344a96117dfc0243da767e80d1ebfe951fa3c493ea3e7ba8a5f61769ed2e90afd8a3d3ef2854687fe325ef15e1ce06bc700de97a77bbd97a5938759ba5f7d96ae3d334ebbf0cf0d1337da05b31428567b189c19eb642f60fabb60f28994223fdf4886e22564668569db43f030e140f3ce50d1d72a897d5c250736c8a84ecc9fbbd9216eb9cb7c3f2fb4425c6fd0a2afd150af11864d7afbce57c6755073d8646ca7f6b25e6bcd35e93550b15b4fdd11942a2632d74ca4548b2b3fc04072cbf2bc47f82e6ef1370f93e3b4ee3d5266989204a9715214ad1e86bc73086a43c4d3693aa3f20e564ff5fbffb272212be79f65417a78d080ac728ef48ff4b34ee8d15249b4990933000cf4365d07bfb6274156efe75c8a9c55212f308d1fc633e0075c39d802214f30046e407a3aa78def3ff3cda82059785ccf9bc7f5b93aaecfed717d3e60ba3596c265ad63fbbc3e58cedb2a9ac597e98f369ac62ee97b549121c96b7b2339a3f96095ae3bb5bede7eecb0e82d101e819a63bb5d1844df2bba0ab4b776edbc47e77a5ff519199266ef5533443d2653391b677b056e7504f0709fb3c97cdfa12d087c7624777834472efbddb93b63ce0e9f3167d3e5cc54b124a67da333ffe0b9ba4b97b04030f18e8cedef1a904ebe9f86d9313c26dc5b41862ee3b1d5803c96136ef33b4a62ef1e4922f0883b63c47cbfd06fc7cc75d851b3bb45fd7bf7d6d1cce6642609aa9782e9f28c0abfc19da235b6f4f6a283de5e1ca0b717406fe729ffbeec207b6ee13a66e1311d26897cd45cc55d24bba537b5949b6401cdee24bb2efcae4577ff3ff6debebd6d1b4b14ff7f3f85cd9daa8404512465d90e6d44374dda69669b26dba4939d51397e6809b6d850a00a427ea9c5fbd97f0f0e0012a428c7edecddbd7b7fedf33416f17a70707070009c979aab5e3ed588d1578723e6725429e86917172e04bfe179f67a61bc2f2925cfe4336dcb324d4a503e5c76cc3d5f33ad0a7e7095a4195d384fb4bd9c395fdd0b5a38d8f9f495839d37f29f3fcb7f3ec87fdec97fbefeca89cf6a5bb766a31019ae33b8bda6da9c883341728fe5c53a99cb6d24f772467142720f28bdd86e039cca129bd55b96ddebe742926cb7b5da55a1e3d1f28e78b47c96c5106266433695081568716381e704d8f73abf75033f3cc2193aa3cfc9bcd773dd05d19cdca5a3b964ecdfa4777401e15eead3afe73b100add2cf2b0d773176451eb908408e1822c062e1cf99d03070d36a82cb65bb7208eefd8e92e9bf2991f5b5046f2bb3ea9a6bd9e5b90ef37ab4bcabd75c20bfa4d9627c22d641f9f9b51e671292e6a55c2af9419ef0ff94650dea95638b7140fbf4d8ae52345afaca2df81627547a11babd0f7c9cdde726f1aea8ccf9051d37c435739bf7f040aee2556176a69ef29786915fc812e522e69b3bba88d06e87c4fb945bbdc3e20a955f03db8bb7eb4b88ddbf7109b744fc16babe0c5856ab37239d5596369d5b8969c2d117065b2a7786a155f2562be7ca4eccf56d94d41bf55574a7b0a7f6a16fe4eef297b4a67cdd2ef129eac8a3d6557cdb2809437c97e1c32abfc6d2a1ea379eee5657568616e70a4f4e7fd969153304138232e739f81952e52a64e636dea74d2d69faf643761691608fccf46f85330bbe04d727f202b8e900a7880cc1d606dec9220a5a3bd2e501dc0aaa9b14e11163b3e723b3c60e63b0aeadca3f84177099eefab3bc8ca575c8787b512955894ae6cce726a251176f53f03a797ff9370ba245dca9cfb348350444bbceaaeb27b90a9303247ae76e0ac9f896433eb4e0b93125f90bc618871561b87f57aee05592bc0efc9c53ef3b49431ca7fa057a0b9a92fb929e8bd1b23f5b659f1cc31751cec981a0d6373b0301609bfa6022f4ced4c6b21a6f8c1d85fdb6312fcfe2151baec5a4b46546a7bbb26e6a2a4b56506e4d1c5760b712b3c65ec0dc1f69d8b82665710e267bbddc5e0e1a14bbd1515c9bfc9f323f5924ce85f73c133fd1374c6ff8ddec3b5e776eb7640c35d70c15ffbaae0f48aac0f6112c476cbf02e693a898317c870cf9bfdf353f923c1497ddc67d3fb888141a13e0c8179a7c8c19cb09ad1ab9d89ab1a73b0a36b3ad811b983eb39ad4df2ba16d4d27b99b362b3a2bced645c1e9baa579585fdaa228761161e272b77e91698d6c7b3c6ef0de153e6d5475b97c32bc77d9b8aaef0c3529e7c37d85060db99a420ad7ecedc745abd20e9432852cf9d66c43067d37b15816fbb9d47f71536c9bc6316137cafad88f1f59e157ab977855eca4326b956387a432ef750c0cc91c796e17cc3b99cb8b84907ce3ab9a68e260665efffd232bab2ccbd8c578328052a515fefc57d46f155c332754de45126990b30394d8b17cafbc53da97189df80f68d14aaf177f05336f349d1e0ad4d83773b34d8188df172f1d2760c5343d6b25e05a824ad6a981cec6495a0e468215ffe5055ffcfd33530084b274bd2f627cc107863b73477f1dfc8a6d7db54cf972377e60dfa53f28fc3e84f0fa58b663fc5dbd14f3fc568748d9d9f7efa53e020fc81fc6d5a5ddefd8c5c56b7064ae2d1df30e0235a6335f2e84d8994e38157e4f0d0bd985eb81f3043d10784df9357d3a7a96b8aa6baa68a37481f0f30f8b802698990b6b2397050e95ee1024557f82d79356d2de9eff04389e728fa0ebf6baef626c944af7abd4419c158067cef31cc7af4168b3c4a4b7c57cdf6f5212197d377664ddf46efea357ddbb1a66ff03b1316e1ff26370c57d9265dfc67b96080c69ee67e417b1e040bdd15e9d2731e3a83347286aacdff04470da97297b48a967b3c34bcac40daf1d300403cd947c3a3a68da97d067fece64ace7b97906762a54ff5150a459136de2a9f74b3f5a8d1e4fcb3a699f6a1b9dbbc73f959e3cd8659e558d1b93ae599d39c8f5af41e4e1a047f18e005c9777006daf8784e1c7a970aba70f01571a41007c48597fa03bceea83290bede77a61196676c6207179019eaeca14ea97289f67a872accc106822b4c85079d4502ee38135ec7e657dfef452236857ae6175ecaa6e9d44dc81cb7f2af509490659410e16d949fc2b7ecebbb546cb7c2339fb29fa9b3a982a84673e38a9b3c14d04c9494987b8cde09e37b493bc02d3b0e45fbbc607693a3dc957b3dab77a5f200dd4e4df7f3d2f294c18875f0aa43d8ee04ffb00f6370a0da8093428518d7b879b7b1854acc1ef72e698438e3f017e295d5b19e6daff480403d10cb1fbd9c2a7648c855af27ff2c411be40a4576da76eb0ab2426507d401164d28adb0263b039e276c4eb3efad6973a1f235151fd215cd37f6b5b0a5dc627ce92b80852a5a07ee1584115e3b8a73185c7b5a1188e02a9f7b728560217f480aab426e42385285f6a9f91109841f64f988624df758e7b052826c6361f766bde315417b90158fa04253136c7b75b05a1d1d501042ae9483d035e557395fc13a7121445a23f92e152ed36ff916da1acbcd8455b0688210326f475b30f46e2d871266cc06a16dcd5d915c73da14d21362fbab9f369cd7d7dc069c3298c006863440792999a6668a52d5e4d9a1e8f50ef976bb51ad15c9157ddf1ec0b26c306ea661ca15b3a10ba5ab13d9eef9759e4b7162020276b57cf568cbb0a3c9069897b3fa5ded6bb67029ce5b357f27e438319218428dc9b94b4507ab50a1f41a3323d705efc0f799dc0536d31656247dd1c750b26a822c1a55d51e8f45073ef40a6dd6edec61fe580f66363546a2fd803ead198810da5ead369f324b1ba2dd5a654c68503b4d37a58322ee6e61d09d0d6c6b75e9781f05150dde21cc7c547152345f6e15dc4f0f877e7550d901acaac4c18ece5526711dfb2f75b944d8be5137904640fe6c972c7757ca8e33e54e0cb04a04530e007abd438b6c93c5e2ebfa5df68c4a8ed1a0eb6601cd07bbb25cba0bb4e1eea2d72baaf5b33bf75820143d5ac08739dbbdbbbda963ea34b671e5ccd792549a5139ea09d62140a4a852b9ca4a1a96cfe047c6f8b68a91e52236f15286abdfb69056a73636973a5971eafa9b366bd14661bdaf5bb51b88afd3f376ef35b3dd49a38b4652a3c38a21b593e8a2cbcf7915196bf734bcd871c1a55c1932e0cec6e41deeca1bd1602a5f0feed3db849259ceaa82a9eca2f336be92fd2f5cf450aeed601a6481d776c89f12af5b87c494458701b6a75b7e37265a26e8cdf830d072d2a18f416e3af4b19e82e802d713547fd085fa2d0b9b1f55019884e84242f5e3f76fdefef8fd87af5f111fafbdafffe3b5fc19c89fdf7ff8fa87d7dfff9984e6e3eb5764accbc8f4a333e151b2de3d40567712fea93cadeda81c1434bb924bd9fceba985424cc81a958a53c2b7db64bbfdc634ef581cd4412eb2b41dd22614464c6a381eb18ab3cf9c7aab20800774c7a7f761edd7fc87af5fbcfcb0c7d57667e8b2c7ab78f3259d7f7af5f26bf4a0e27a3fb1b86b3b1930b16f28289c5070618f70d307f2b8e356491d5cebe88749c745538a735ce08cb829192d1e027c546e57eacffdbd3b8deeefd174ebcebe5dbe293e8818fd144cb7b3efb2fcfddf3f7e1f6f9dd93f9cb8ef6cbf9cfde3cbb8ffe5e81ae764f4d3a53b8d66efdebcfcfa453c7bffea5dfc61eb4ea377c93cbd4ae75b105793946d5f522678926dbf4e0a4139dbbe1059c2443a4707ee347a2f12b648f862fb2ab9cfd2eba5d8bee3f42649b3945da303b919c836fffce6c3f6c70f2f91ec6f38887f5a3c1c95688a7eba1c5de3828c66ff180e7e5abc18fe3d1e5db7508339500028bdb62e2ab75b7315254f73f03233fa6931f2042d847aa7118462aa0f4208bb94d0ed96d1db835789a0c8f203f10a6cb35d4a4ca64b11c269f17df2bdfca59ea0242f69859c5bd4c10f13e20aa3289379aba4f854cc44bcdd8aed567f1a0e547972f3f1113a737efcf03272944aaff3e7371fd46f805de87247082418acb289714372e823f324c920a8c98f1f5eaa00260e5e113a5b0e9c571069d345786dbeefe1f3427dbec9995842c2bd4af86693657fa30987b41b95f66dbee105245ceb5a29db08aa922e55d27b3acfd94225bd31a5b22c2dacf4ef089bfa113532f8af39a36fc197b98bf02722c5517c4be6f2cf1d7958442bbc58441b7785f062b188322f0d4e99b750d77fc56c1dcbe48ef4c1498c57d1c520c0ab55b4712f0601c2abd5ca145cc911aba217b1cce8cc1904618cefef233d9df766c24284efefefefa37bbc8c6ebe08c2ed3608f172196d5cf385f0b7d10dfef65b9984f09be81abf79136ddc6b848be8121745b4712f11cea28dfb068f11fe4efe00b5d97cc316ee9b51e023844574731e84530d98141c145c7e1ceda4053116fbca871de5c731feb0a7f85147f1498c3fec2b7fdc51fe24c67f8ff85452aa13b1a90324e956979f1ee8cbb839da6e678e1323e5a0cc7286e83808e791fbdd737fea0c9dc8193868b07103dfef039aaeb23ce70a63c965e17e8746c73e1a58df5f1ccb4585df4733472ce119c8c10e5b38d8e10b279eadbe08fce7e3a91fb9f2973f94ff1e92c0477df92bc61fa34ff8fbe8b6ac5f350c682d8d7e733b7390b283bbe9dd8cc6956d5c802d2f4a704aab25954ded638e920a2b5810b1dd8667a6deb938431494e2681db8ac6a6361dd8b55dc4aae2ab37861bfb9a60256b7f98062089d0979b478a55c0d56c943f371efa2c131fae2643036d7355517a2d505302f56b5c6ecd658776b5ce9c6b757ff9075a52a4881f9a8bed54f34e435bf1d32490047a77462f0140c2c3a4950cb8797317134d09d599eb89477be138445c38957e3221fac8f1cf9cb89ea4bb0460c15236dd521d1a6e647d40e9c3f755454fde8a1acd4e58d53384d4ca77818a0a62fb0526f27e441ef2791b3582c0e56abd5c1627120f9d3c1b7df466fde4445e1e06299739896c8598d16a3fb7b07afe822ddac749aac84a19283b39c5d57c956fad526cb54ba64b9f8a0990b3dc8c98b9c65f4e6cdc1870fa68b3a312a0a48973db4530ffeeee0b4c85507b2c9e16a355c2c205195ad47a3cba9e4baec971fbe34657228f4a398d7e5e4feda59f6cbbf7fe9607ab74e392d94f7da6f72be4a143ef181c66903a1077f774aac981e79309b4e3473de6f9883e576ea60e7c3863ad8f908a11a3e2c370e76bee1a9839df789e445ef376c91dcabc2eac7870d2dd4af8f74c1ccef0fcb0dd73fbfe1a9faf13e111b2e7fc6b8deada299f39744f6fb0dbd94cd26dcc1ce8b3587dfb2d65f00b6bf6c3299beb996edd0b5839db7f04efe7d7ee360e7159dcb3209db24fc5eb5c5f5cf37099f2f55936966374a55abf7aad90d70daf7742d285c4f43fbb9faf57d7e63125fd1b9fa19e36ad388664ee26047c294ace40ff9cf0b073befe4df37f2c71b272e71edd5ac4bf32b2bf5930f6658608a949a8e11bb392a9f1c77c47ae7536f74dd2f57ff8c53d56cbfe3611f9d31f7c4765f9a5ba6e17ac93b03cb3cbce560d83216af395951b3bf9debfc5d9665dc4b929d408c74f6fe7e7599679ec8dff174958af44605dca91e1bea03a86665586cb715dc0dd791f51386e9869fd52afb96b8fdbffe97d5ddc16a5388035d21395857e9708de039c6df955bbf5313a1df5f23a5338ee4c1cca5952d91d9089c02066769e74f8511026d83f7acf1a6d60af4cae96233b74398336c94f0f182303c278b59ee6628c6576431cbe296c7e305865c9cc5600d5520845744c872eb3d71d774edd4db14f4077a85eab90043743b1b6e4f912be0ad61e6c7b8208914212d0748146f08f7b4a245fd0caa1348860fb35e6fd3ebe5ca431f38f69c65531ae5d8ee694fd4984aedf471a553f13c988a6110c1520cce927361944f87414bfd94f57aac15b288da5aa7b8d0d166588ce2d2bdc2734c67ab589e81d61203f7643d0b2a359696b7c42576dd0d7928d12c8bc905decc5631b9c71b29d4618a4a7808b7a5bbffcaf8e08bffe6f0e0f3ff57a2836f3e1bd47bf1d912f3cf95f867768bdbdfe482bb5b57e4ed67f53c5e7ed6c1f6a7cf3ae9fec1b6a4e82cf1d12ad16d7df09d5522ed2cf1de2af1736709dbeca2dbbae62bab44d659e247dbcca3b3c45fac12dd561a7fb24ae49d257eb52581e04889023e88021e731350ac719f815a8dc7dc1cf46ac0986243987ba2ec273ce66e54ac983054e1ce3ce6ce2dc6b4ac77ffda8566de34f2d3de21292a717ed57463d0e91ed20a5500d1acc1e6918a8e20f1b4c4859d01577a542ec30e4f8f56b32e950bb872efb822695b10b3f5b9eb10581ca7c4b9b85025556cc7a17e1b183a832b17b968e05c5c3838ef5625aa94876dd306b5c3c06b62ed59d35834d0552a04e56469ec18948b6f79965cb8089418cc1cefead2004fb603e3ef3c8d1938c0d27c96c68aede94e312d317f24acad3dc4f4ca7e140418415b5e416bd047da65c012007e9db96e4a389232784e1234950243badd06a39490609447e921494134c8d194113f725997cf543115cadd77e09f8c4f8e82d3708c654b2edb121fe93d4f0f4f6e6eaeee1d336d359de25c0e7aaf154897410766ada8ef79477875d76506c78597784a4eb5c2ac63fd0e6bbdf58a0ecab1664c3c4e395aef4bbd80c1c5c45fe54f7956a15eceda1a51b071f887c475fd2df5f2cb82f21bbaf82a1505ea31a41cd9182d808e3665ab9a22c5a314f9347232d729361c6ab7b753cc93f5b49eed48346876af0a995eb5b334d644512778121bd09546921a0fb589f74970511baeddb5b457d9eb31d0aeae5ab0c966cd3ceca3d7ba8169bbc16b2a5ca480db47f36e63e4d52bf8ce95139df971248f00f56bbb5afd0a7dbbcba4d2e59d37170adf5d289823fc609e75a31c1b6dfa282b4bbcd6767e17eac47b2fb7af23846f60b3ba47f89ab872ff82209e6384f0256c67a708bf811297087fd7417cabfa124f3414842916a56b0c5011feb4576b54b33db362595375b4bd502b3b7f5139f635492566de8556f2a20b7218c8ef35658b945d1b534ea3405a80bd6bb58bb9ccdb3065784fac8621a1797eb2bb98326bb537bc4375742c37688459d9548a00552549ef1b417fc8730136a11d462ccad8c0193978c333f8bb0673d3e8a1c469f1359820e85002e53fa9366aa3d048ffadc1ece8f1d5b3d255bc7cba0aa79905dd83f974f728ae182df11ded86ef2ced86c7cc0cb5098362d54d2b4555d0984c3547a8d66d6573028f2ad1ee44ba1d856bcff0b8418476a78d8c529b42a6bba690b7ff13cc4b336ff1887929ff6de6a5bb33fde9f71b977660f46e3f462b05ee47e4899dd5fdcf2d45a32f08b90da5319d66734a89fb272874371a51f9ad965562ab694c9fbe88ab86547ebb7995da05fade6957aa49bb53564dd0df6c7168458b22b95611516e97544ad4b5b1de76cbce1e611b8f18a0a5576e6d83b6d63668f890837daabd627794e42cdb4b0f5cc3ec87e00e3fe8b96d9c00e592c86852502205de129b59b2fdef70f4c0cdd80f75c405530d5e21ed26541b6a2aba7b923c57b71689b27298f4813c94f895ed24f07de332b6a59b0ee12c5a11b81e4a84f56635a5510bc51f6634360894bfb596e18dc454be5aa719b5dc8dbd3a0fe851af079588c0af0603c9615c295ee18735a742dc47877e695d9abdb50945f3eb05306b2017918309b63c8957269eca3f1cff9d54b34b325aeeafcd7173d222205c9064ca018a8857d6c59b9aa3ce912ba63b66606cfa5e1e2c3c251a98604eee85be4b65565c9bf7b6256355434a2eb581e6d42ddc8dd23d45d1d328153dc82adde4595d893646e1891c9d552957f264d4027b83c17333f85a2ee52ea3ba103938a3d254f94e52e5d73655fedc19fc4d929ebb8338b1ddee84ee52c541ec1265c5c7319cd712b184172a65a09bd67492f47acaa3ac36cb2deaacbcd7cbc126aba0a07b0ca1ecabdcacd7cb34e267d69ebafb966122931db25ecf81484e0d6e935eb915fb119ad0bae6c07106c2a36c31101a54f9a3028c937733166fb7aefc03def5d22b975b0b939b859990598c53f2c0e935bd5b47372e72294eb040f813bd2fa2a452e4f85aaf545993a4f86bb952d3d265f881b205b8e506ebd9025750449b528a2692fe65dbe0e05b368a339278f48ece251f9098c876f8ed8264333fc6739255213bf115a1849085e5c1e8f06a2a6b446a929991ac95935615596fea8c9c685149d85746eace7727a6e9c890ce8427d7564ce63316635a22fc00aed3d472029a7df94fca1abf4f90aa0fe9bf87a109f420ba199ae49e6a8b3792ee762b6a119957d90da63bed4c8d4caa9c99e9cf36afd23928124a95a97e5f33fc42e0fa386244735e42e011fd385290bc3ea067109bd1b877d8905ce3cc60a7c9180ad4eb81c16f1de451dd6320fcf821449d309212270aee69d1159ba898166e82a222caa6bbcd653841d166ba91258070f737a0880c758ab915a17dfb9b62f0bdb0fdba35380c23df5a5b32040eaba36519ff640c4d457b431276a0b5ba8a7e3d37ee0a91bd7d7f6fc1bcebbe8546d54e4251e3adee1b4b91c85a0c2d42b6e200bd76d103acd21ffeef3c63256c91d1779ba2ebb2e040543e64b47feb1fdf7feb4862d0f57e5012c553aa1a078b566d6531d121a5bfaecb7c25a5dc3d457ed321a98666af1d60f5e4c92aafecb67b0e15a10fde73f40d1ace6d971c0f65949ee5dab12a1138af98d61e0bdee923642c57c2a0a6e51245a274136c8b3c14219c7b1b9e91efddbaafcf5be6e8376acb153d6ec49a769c48009b35a36ce0e0a18c38b0c08a23377ddd8f9c28af25ccebca5d81eeca513e0854ccfacadd478cf0823cecf1bdadd1f5adcb06df2ba7d8dd8e555fd4221fe0a74048395255c7f98ad02b97a356ba26647c9d47dfb8c878fb543f8d7f4ff9a57d6a5a3515116b479d563a106eb97f6bfcd4219e9afb8745eb4627d9c381e5a47efc7f6bf3c71cdea8f60b00767f959192797da4ed5bf3f6b95bbd14f05e4f564f8bbf2659ba30f052841e1851fa51d51e0f2b501eccd5d715cf57679ce4d39fdd3a62577b268d78a0e4c1bc44959051960861aeb664db348a59a246829b220cd77e603eb70bff5a1f482d4f7fae3370a97d9f2ec702b78603073998910e4d13ef9627eb355d54bd288762f6921678e67494b2dcf2fc467a30bbc6eebdc86e433b08e792754210786d4e5bb37dfb254160e67d6c014d287ea31f766197fe2bbc4d6f0af3305de3f7ab7a45fdd5fdaeba9dac77fa1f5b05aae784aac45faa95030580242abd7029c19aabf8baca9f6c1df5e9cfee8f2eb2645814d50d7dce5b6ac3b5ee7fadd720ad0355a28e7368a5bb58c9a087b547dd4eb7bf59ba3878a14100dd42ac14097396dd1fac95a05cc966053ea874baf141ce0116cf692848c1fd91e88a80f9cf8a630dd6cb25536d7cd7c7b8476cff268152250927c7688f5b62b3729386ee1797b23233fe97777bf89751fff05f0efa072f970917decfc5c14de83df3c6326929c4ba8846a3dbdb5b10e5c5cf8597f36b99e5ced141e807cfea6a72a5408c8b9c17b2c40feada6f0188e70762490fdebcfe70f05d3aa7aca0ff72d01ffd4bd7305ae44a554cfd6552bcbd65ef78bea65cdcbbb5fae9b4721918517db5f790c833faa53c1fcdc2231f8747a7389c4c629c3091feb2a1b7cb54c8ac898fc3f1048781ccfa659344335f96d3657fd924ab84a78c46b3203c51194118e3e4d70d370d9bc29734bd86b40986ff433fc69769f10b40200b85a73878761ce3cb4cca13331ffbd8872f365fd24592ad72b6d0452544be6c13e097255517d986dea4794645340bc6a7f8688cc350b6c8f35b16cd82e3093e0af15118e3cb0dcfee6ff35c36188638383dc2c17812e379b2a042b5fa6c8283c9290e8efd18c3bc72ba29ac8142723ecfb3041015f838f027782c93739e640a5259f85425b1ab2cbfa55c351ef83e0e8e9ee1707ca2328b34fba4072767422267ced355913309a18f431f0320f7096b4cc122e19f6a2c04e3672ac9940bc6cfeac4eb3c5b50c6e5a0d5808f7010e82c9edc4b043dc3fa7f934ca96ac787c9d0695d453f2d934fa96cf8190e4ec738f04f54fa2ab9a64c2472429ed910e6597a4375fba713591e1fe92a394fd8b5a68ae0a8ea38e7f3652a619f8cb1244bff48a573ba30adeb9205104b340bc7631c4c7c1c84a1cea089ee32381ae3e0f4140747639d25e75161f224c4c7410d29e428041d9de09367f8a499417732c486ffb2c9d3026625f48f71e8eb9c8a3a8f4e25d102fa295daf5366665fd2c5894a2d3edd9ba90d9e057abed3959e2b7f82f5ff3a95eea4e68b6b437063d9ee916ae32ae5f492a772910527a7787c84c74731beca24d956eb5ed297640b7e8caf724e0ba111278966fc4cd5d8cc97459aa8d27a095e27292b2e739e6bb255ffc7f87a9917c2342e29dcf01b4994babf00169545a56120d7df048fc318eb514b26a1fe9749863ac353a829bfef6996e5b7726463582512991a3776dd65cee8fd82de5a4c4a0e75998b7a2e009172f5a66c91260ce82cf427f859889f852af53a8f662713a06b59ee469e4834f2748b7a5d402f30097e8cb3e4064e099242557238b1922f337912d3cc40cec144e6dd3243baa19cc7508e38a3ab9ccd97e9d51590bb993439f96095ac998d4445702c3bd2e986431df935465406f08d107ad01c06d2ab4931e8857ee4ff8169534d50180458ff5fa5eb057784c3b15c7047754667056b024e431c3c1bebf46a55cb9c63bdaa554eb5acc72196241d9c18a8aa3514c09e71ac310d59f5ba0e02c9268f71301937336977a6a03433b83d96bb160e2b606a0c692a0861c02b6af8b6af3e35c46abeb0828a51a651abc825c615fbb4d6d82ae179ce144103cf5396678dddd80fa1594084cab6f64a491f2ab1e2a9a7c7f874a22641e5ac377c9dc9968e4e701084380c9e99ac1add72164e9ee120185779351b0d42b90dc0ac57b96b9eb2eb6addca91069323936bb1cd1309fe33c5e355a6e29c8ad73f7b8643c9a065afe982d5941e4a944b70650613f228b4d222875a1b32bd10f73c2f2ca9230c253ef2f93c2952660923a7418c597293fc9cdb5c518a0b2763c8b9d7bbae5c3e79b6808b925938192b01474e1fec7235eb31290b9e5cca493ac1c15188a5e0d1d8f38e81485492e23a93093e7ea612d584016b8469398af13ac9a8cd36c7a7388495e0eb3cbd0427210e27010e26a14ab7101e9c4cb0aa77aaf22c7c87720104a1da98d6c93ab94f6e97e9dac8627232c6315ed364be5c6faeae0c3797189cc874be517c33188ff1b12c592ff067729e6552b691132567f558ee18418cd7f9eda212974ee40a3b5238ad2813c81f90cfe9259dcf932ac70f318c732cb31666f1f831e679716fa441b5fb2b0980e7f7895ed1c78af1035114c96291515361fc4c4e825c07352bd20c54ce4291b085693c3c3ac2c1f11196f26cbd5c8e8e61ef3c3d81c46249b3ccb0f989c27c9152c6a4b074ece3d3104bce5fa4d98ddc2a24aef4ff31de656b9288ecc5e71fe3677aa937185da800965cb8c1e3ec7456f32fbd35ed2c5c106d636c71c213d804d58629601709e04b6d7982ca0dc7da6ee4b14e6420391f2bf126388eb1c85789c855e7cf9ee19320c616911e1f292af04f636c2429d85360173d8df1ed9226422f7858a7cf649a25d1e83d0dd28a55fec93e904864b799b76f92aa257464d87589f7dd55bb823ce8335bf450965898131caa7f96cdc3bf3a933e9455501b7e903279a86f1fea3804459c89198f63521985d767c4077e7d193dcc970963342ba231ce924bf9c3e1d7974e899745d699bb2c32c8bdd9937b23736fbb5b5edeca96e7abfb4f56f651952d339c12dfddffda59fbeefe57a7945f9db95922dbcee6cbeedcf952c245efacdcc0e4ce9c25bd73e2127fa2f7b7395f7497d199b25cc28a3438ee2ea6f24ca970f248b17002e596f3eb2e9867ced2016b25e71a5a5b4b86d5598e07c7b214fc7ba9fa8635dcd9b1cc71e2b2a69f54d20f44e44eda249422f5a2e83aa62547969da531dabd445aa54591b2eb0353f460ad9b890e9c41aa74015c47c1f1f4660e54858ec6647d4fe5ea5ba4434220d140b0dbb86934610bd5f0c13cdf30511cacd2423d45abe6d56575a3313005ad7a3c333ec31a45ec44554edfa97aeaaeac42ac2c816ba49af7e7bc448f56d0c833c58b129589c7af2fbd6591ed2a7f83e7543af3e391e44f09a1b340fd4c099d85ea674eaa988e1c8270e18254c11d754a468a616eaebf0a788f12c48f3838d616c44d86291a6551a2bfc3819b0eb94c49898abb2ec8d1c0e5c3048d32845d517779ecf7051e1ffb089dfbb2dc80c80fcc889b0f0a340af14ce0c0f7fb6ea1a33bb273e24da6d9c82d06398ab2911b0e8b618e10946272956874dc74a3430e08e735528a1a29598d944d8d02702885f0826c8615d43a6ddef13eeb6e86148d8e478b8137296def198b694252e2476e4a16a30d1664eee672a073b7409893b99b219c134236d384f0218b0afd3b188d0762c8a34c7ef77a6e42c2d178c08602e1e4dc9f26031244c9f340e60c4980109e8d8ffd7e02f848e1df4d8d95dbcb2ef394991f630678007209cde5f3ac222d9722592890c8e9576810b8fac93047a80f375572b638098676e1e4ae2a9cdca9c2a8824a32fdaec9aa2789d7939454936480840edd60c88636610543868321c7c13041088ddc6028d076eb2b3a91c5f950742527bbc9a282546f003bc072c266cac8dfb2d3d79eb4718e0b128cfc8adb666ab74eafdc9d0d3b4326161d98b32f889b128a73b2c155e8b974e6c7c35c4e46a8ddfaa8d440a606edd450a68632159d2dce0b508659e08464c605c00128bce871c93176aa1ccc688582bbfb5ff790104c0fab678a77cf94771484477d5710f1dcf38ffca3c9b482d71503cf9f4cd028907f70e81da1488c82d07b16a281379e9c1cf75d46d86e3db65b8f55f582537f222992efd6e3bbf5b8aea729c20b83f0b82f06de493009fbb29f9330ec7393eb07cfc63237089e41eeb3893fe9f39ab4b3a46bc1559854af4042ce2627424e5f4a44bdfe0ef888c82595ca3fa7dee9e95832463622cf269e7f74829e7bbe7f7a3a39ae47c470301aa3e8c43b393de9b341703c0a82633c0b8263838156056e57e0ba021a06c7782207c8861ce11056f4d04d49badb406a37909a0614069645b643529d8c787cec1b462cc7ab1971e0fb72498136975e56b39448a692e114a7f19920613f1bba8c64e7724fe8bbc1a0405136288659bf403821fa5da05a7a1be29f6dcec7679bc100b99ce4836034ee0fddcd3050fb0f1f0c3097bc940f873825c77d7e1e4cc54092dd50a03e8f424861d1b8cfcfc3a918a874371c8d871cf58f238193d9260618d3337b85495474ee4936f785c1f36af038210ca7f666ecf941fdc0d6272eef93109d9360caa370c871d227a9fc4aa37098563ba7522f09fbc9c84d07098ac23e1bb97cc010c2f067144abead27eca67bc2d4341dfb7b01b57c4a09f4c5b1a4e361230de78015de979c59ca18f5571f240cebdb0d8629426705c43084414ac68f1ee649410ffc489302c719cee333480c4c62817995189ac41c739ce9c4719d5860ae138f4c6286f32a71527794e3222e0d82f64a5ab037f93108571a47798da3c21629ec89e4c40d8729eae79891b45fe099dabb5db5d45da1b30b986811858d1d8b8f48a817dbede5e7161bb8c6ac16dca60673518339279bc1c2a07e0e72c56644e67831227329a71ccb1527ecf93eee670861ff90b8414f20f0bb1848b69190cd80f75d979160b840c30d92c75ef3b408183e8ef48ca684e19c24b8209bb34b4e934f66565302dadaed8c304ac946672476c65867c8a6989d71a49bdab43326ba739991e84d7106eb579ee9fb39fc5b0086a59cf2d8f290e8dbb73ee86cac189ad5831bd412658085fc4ed0204108efe6b24773799d0b90deddfffa182dd4e076926ac561c8d07b767cfaac9f0c02eff46472da4f079e7f1448ac7022b7cc937e32187aa17f2439bfe74f4efa39169264c75e78e41fcbdcc09b8c4fc27e3a187a47cf4e8ffb39ec5ae360ec9f4e61dbed575b8990f2a57784863239826db82fc540b6b706eba8218f3c7c6f0dde518363351d96f4582d551f0b84038374d6598259257867090e25aaa9e9960af68ae1074c8901bc160324921f110384bd298ba618a0f1f904b9a116038464d9a112087e8b1ca1869c257bc4468b1acf84a2c489ef0f24e74b06c131823630276ca82449dfd78eb42db8c7c89c60d5c0c7d5f9558135ae374c4b7c4923970d359023001a0b9257d979e48a56362745955d442e6f65cf445f4f07667d355b7d335b1512b296e5b07dced1671c7dbea9f58de5614e79ef14090bdd0473340a4790f2ee75f3d03c63ea9850fcc285cbfb7c90f41384d5e9259b2fbbc9aed97da575a49881ec3cecebce64fb5c7dcc73706aa5bf0a7914ac655e75fdf52402c72909e0eec9e8f64c6b2d9f208eaaa3bc3c7e86b111065d4d00ca236c3a9af8089963d7d8d73737637f60fb8de5f21c82cecfc3ad95c8746260270a48aca8262484a4bd9e9b0f88c4716ea4808e511a79cfc2825bc95452d4974346369ac2c9d3f0544f0b98be3090e8c4f9e934388ec4f3f0e8741a8e83c81a842b86a768141e9df4c3233408c761141c0fc6c7fdf638fb133468a43293dac65d7f0290ab61eddb05bf082a895d6cb727f24fe51eeff9c4d0aa37417826881805be37e94bd94e60116b1d734fee6d83fffdbf5d59a19a8619c8167d06a55df1fc79d00beccfb0fa8c0d94e16417ccf4caa5cf49380e0dc481df77e950260c4e4d5702c0296d9f070774482403b5a41e3a1a1fa39102df4a7619a15fc89c2a937d71ac7ed5b730f4ae0379aeeb869349cfc23b8588eee7e7c1311a74640690798a06bb59618c10aa1ca6bac171cb03a271e6e7c37f8e36e8001f7ec6a6632080d2e9ddbeb96e36afbc168f66c9f0ca1f3e8b1f8ecb6df57b5c8ef4e5afa106732ed37ab192ff8f25b1ccfcb836db618479c53a4b85eb38083cfd75fa171e58a1139dca531484bc7f0d1ac0c1714545fcf9f3e0b8079713cf9f9ff6f4c34d8fd75333bffe1d3751f621ad71c9851364dfaf366ecb645e41d2fa5e5590e29cf8531f2e4dd9545d97165f1cc3379f8603371932342aa2a3019ccb47c5e0088b113956377eaef88204ea5450e82bd3f3609a8fdc6058a0c8af4fe49d63ace540568bad9c04a087a937234e983c67877dd16791fc178e72e81cee1e89cb86dea4cfe1f28c238467c0c624201cfe4daa13e66f0140f49905c201af3bfb6c4ff3ebc784f5f1bec3ac6160c66c1364438ead7fe32a489ed13bcc89f822e81fe382e45f043823c1b03047288b37e4a83ac2a6333f26014e67414c0a9ccec298f8ad938f2c91a9124147895095f01b258ad659c82a91a91241eb50244b14aa84df2c614e6a36a8ba48565d1e1220814a82667d597a901871b92f6b353e43f959cdcfbe1b918a12c4c04c4b1fee6431af69813df7e1b029466c970698d547c771bd8bda540f036fd2173bdd00e1cbaedcb0cf50c49e136f2253030d811beac5f028247b6edff78ed6b0adaa45b86ec23a9fd5e7fecfaea86068ad293614bf734dc10be49e5be299ba229a4cc66adf83deedcfd0faac8545d9e2ded624d9401d6cb86ef5195a9fd0da354fee1f054d0e4341b2e7a36e46d24cf5f3a6ab45b9f0655dabce6d67d74a1db65974e7c1c3de155b65db42bb4d1292f7d4fd774a151d2285192ebcb2b942cb17024409f1fba486ca1274c0ccc44a98ba00071006723a81d8d1680cf308379025b2cc6e78873f66dbbae2a1c482d88e8599e40e467ed1f6031cec07e84ccc9238260f8b54c5338986015e279c32a1c3781a61a274652333aaae8cc58cc69ea923178c6efc0c193012c25580862afcbf866596c472eb4f0d3805f1cf8af3fcac180cd4a83292ce8a18ab979eb3614008d9547df57a6efd4124f0d5d720c01b4fc14e12ccbd0d83c8fb6e86aa271dcb3d7fd25036a9f0c86c17922e43b65d6d5a076050a2d40cd0a0bac4549ed9989d14cf286c8075ca9998e5d56f548368254b7c25a09a92d7ede4314e11345557af8c9ee639bba1bc487346384e4b26890c33b952e1df1bf9efad4c918b0b33efeefe57cce4ea91ffce97329bde61669eba30d34719fd239cc85fcbf93556ae92296640c2fa34f9509e3549adc32f27450ff98cc69230bb5ff0656ec7933f036fcc3a75eff3bfaadc7afe87aa2a4d7bc068067cac7d4973f5d4f45056e6f8c61b37ce49f2089526b3223e33010e67999918502cca6292ba191635e9b1d2a5e8ace5ee7b175595198e98b1f84c0e6dc6e20eee651bb255468696fb8cb611115c570b1d54ab36b3041713ca9d516da65939457045c3e5ba15eead5e03ac8badc8456edf44c0a2afc406c3549c9a729d941dc8b52d6c6aa6d607f8c6e1086b8c783cb9fd0c561ad656622a22f79fc209a6e079e8f783ae43914b400b92e3ec0fdba13f6c87feb01dfac376e80fdba13f6c87feb01dfac376e80fdba13f6c87feb01dfac376e80fdba1df603bb4210fd754fc707d99440b7c4dc5b745964473acd2a2dd03e2c2f2f6267a3d5105d31dab0824df165947adf9e76add5e4657f2c78b6cbd4c3ed72d84e7954daa20c357f2d754ccc6b1f19b8197f44e871cebb48c12b5ef4dd1eb8dc1fb9d3ad14e454467e3183bffea0ceed52b29fc0df4df304603573c277eaf27ce83e9bdad07104e267d8150e438a8c4fcfaf25108ce83ed56f6d4ebc97fcf83e912f2c13eca75067093e9e003475d67ea5f613c7090038d27baf5a5e44d73ca44676fe995bbd393b9e25829c723eaa6a27d8fabef4d11e6a4f5305c6725a4f5305c659933be1a0b1b385f48f8b9fe9b0c9c2fe42834e066242bbc2cb2df86b3b5c6d9b2c83a70f6458d34e86f5964a6af355ede3e3a3f2dcfb1757cb6d9389eca7fa200616779db355776bfcec0b5492d3804676db2809074a2a6d31886753c41dfcca8b556c0b0ca5ca62e8cd641155c48df363012802b38fd6efe8f7f7567c9f0eac5f01bf5628e8f4af4a7510ac1e91d6557f0901097132ea97c36ae559a53e29fa5e7e6dafb2c055f42695c3f80f3591a0fe43ff0109ec0c3ba451355b96490c812157d8ce43f25cd0a7a20fbdf0beb71d9f80c4b3405d0d5ed6342f82c8cb1021c7f1e581346ba9fe2b09f0e42f439a89f08b35c8dd39fdc9f8abe3b1b0ce3e94f8b01faa9e8e3cf26b8d3a84e9bfdb4f8c98b211d4d7fb286f994591804313a632ae99b2c4f64e251fc3470ab8ebf68c0f894e47f6e0036ebf426937e037a18d253c7e4fe743b4023654ee8089eb042dd243b441175e30dcc8f95b1a020d94ce6c646c1ab7c0cd80b57fe51a7174bed8f6db73e216c7ae13229c7a128c07223220c8bb215fed85eaaf56c48a6d4261e771a2de8359a7622be7b3a3e371b23a4bc436b035f0ba94222d5bc065fd4d42f24e2b00f067458a79b1a21e4c026d0ca19db392a823f43d32052d889cbb215de790f526e2fff7f8992e5efd883e4727e546080cd06369aaa9f95dd8f69619f08a037b47d62405776b893ed0ab5756fb7016ac2b2fe3dfb6e91758dd9de783b467dd172d3bdab4d0d4e3499e539f87eaf525ad7ebf581611be7e1d4f1e5162f40d5efc636a8bf3e48d941866e66d9ec3a8ec93508609da671f42065ea6136bf3ab89c2adfa7cd34156306dceb91c3009baf0dd506f84624581699f5fba6fe7d5b9701c3f98a47e20424f140057edef59a4fa7ae201b4f9f1d9404aec302419cadc2054b7f299e9982f268d159705964cd82b797b25c1d68a82a78ab5adc794fa3bd5e2d67b98250e4f1edb696bc3c4e177be1b38a658d4a7015c66851ec85d82a7cd3a80a93d051eda65dedb6510dce74dd3ddedac0ca05e2cd7b3dfbeb3e61ca3dac5d0d9c1e6081104211a3b70712b1ea31b73cbbac9fecc883f6abda1140b226313878ec2b5150f17e9dcca9c66bfdf0a79c3d7cb616a0b459ebe629b56e5ab56e9f002120d3ae05b4ffd96a0a99763d7e7d098f9f8fa06d430b8f5f5f02169e5276596430f6a795bd8111ef94b53c47aba2864305107112d6f694827e97762f3ed3a9318a205de1e42940c872ea48fa7430a832ce6e77adce68bfa5996591753593ec5c23b4f717bd38f5185479b7bd7a20d901cfca2a4a11a79da73453efa5d2b4d04bc087b049ead2e5c99502a804b7514fae13429d6577151589c7a55f8021c7b93f1d1ffb031ae931351a8325a8a02e12b1e1cab7f153c0809a0af48a693ebd62d8eaf2e689556f4c9f15db7c5ac55b0bcfc9fcd36faba880553a324f0653558287a9a7d4518c46cd84793c797a3d35347d0bf8f46a618d91df506bac686ff7beadaab8f1aa5cb7c514bbefc9ac9a556ebb26de59bda8712db6a7b1e437b4b6e75ecd6ab051e2496d76dc70d97832b96e6b43d8d7d663a3adb39fd6daee7d98ddd86dd73c2c6fbb47b9739f65b5a4f39e3a9fdf6f5697943fba19c8ead58630f3e3f3f3e0782b0f04e7e7a75b791a2871b659a52c2f5271dfe5307aa7352cc82c362eb4cd4d00337a6b9cd01953be27c0b3363f279e3f7e169e4eb57f87e83127105a9b4dfb7e900718e5fe419e2db507080130cf73267852888ecb7000b71e938b207a999d501d489eb3a9f27c8146ca93058af4df914e2f71466f68d7a57d1507578261dfbf3f27275e30755ebc78e144e23939f226f2c3891ca7040591a74e971b3e7bd68743dce4f4a40f67b82038ea2bdddd808ecf83f0546f28bbb474086dcaee203e28bd6e441cb36777166341fc33713e3e134a6317bc280c5b40cd446d0bd77552d03ba606a8b5a75b18ab175ad59c3c9282f38d3ec57b8e12ba6d399edfdaf4f0694debfd95fe96c603803b7802dcf4f7353f7c5af36a83ff5cd3b7974f835c1da574d3b0e1fdb6b61f9bcd46dbd79cde17f324a39f5d1158106facd6823779a6d6821704fd86856617556a9342d3e33ca309b71966e76880c1ee6b560bbd6228fa15c9e7ebe497cd7f4eb303ab599e8b27510c66c4055e49d117e363bf9e093f264c8bb42c629f21a2557ad7199290da2142c5d49b44022724ecf3618053050a00efa22133bf704e5c37e9a7840c836912b9c9204523371824fd14a1418046212e486019e0c956f8f5a59bf7d54fba70d1a0e833f50beb64382ce80cfddb645d421079c8513f9186c506b0cf0715887d656e536291ffe5fddbeff79de224505236cd72b64ba6187c24d0db834bcced49810088fa2cd6f0f4c711df75f307271078267266eae646c562881d02b7350f6575b7a6b4862942d36496c6a47afc4251555589045057e852d13c67459e518f2a477c1b46efd6742ee8e2609e67393f50e2bae4e1961275892f6da56579c637d7660ea70b073b30050e7624c21d7d8be62c37d4c14e7d5a71b0539d791c7dbdd655086070f49d9b2e501d5ca0137d1671cc5d9c230f0c0e76f411c0c18e12ea4d61276e0e6195dc552368a80a00e0e363a5021bf8e612b09922c16aa42820f46795dcecd284d52ff6d806d83403260260fd564b551c74ddabd8731cc560ed31e3b17d6321144df77a2ef312f385306bcd60072cd52a076f1036347a65ab69c7b9fa020ce28c04f03460ddadfa583330420845191167e619aab26a4e200c6df55a6b8688702687a4bfe2aa5e7deb37b342efc50a791db267a22d19ace20cc567994447d9d1682acbfb716cbcbea5c6f2e8d1b6373316eb46e5704bf0db093f89e573c4720f5331ce6caa0b4619420d6c69792dd8d73bef6c5adb29600d1b42e697fd6ec851c57e1692fda46871a8820f27b3454c0a596311bbb266b5f20ffd1db281fbbdee107333bfa2c43a8cb4ba3baa68dfa528721d067cc9b2f18087e5476c230442ed1d8b6256dd35b560d4e7ee069475cc198bb2e53cef42cc67228e5cf0ee3013f176ebca3f6467cba498a30a02a78ac253c7f7b94dd922bfedf55cf5c37b29f92bb95497ca6ff077e4127f220f2ccfd7f66652e24dba88dc37c4c7bbdbd09bc1a044382dbedf64d95bfea3ecb3eb0242d9a1d012eb709cedd8d18d589dbd5e337427358fbc87beb665d28644358edb5b90516299558f0d7275abf0943e3e41bd9e53ef6255cef018490855ebfb86a168b4dad1546168e7b350c9c6bf49592aba6e9f7689906eb78d6724b579a25ecfb4e256b7596ff92b6d96fdb8460c9d8a88ea3a2fc46b08f1d959d57a6afbe435bb703f5933339527b248927e89e5282f9b3750d8443d962833c9d6080133952b101dac8961814a4c93f9b2d512e66ac980d332c9e56d48507ae5a6952e18e648a999a4c3e02c794efcb36438443a763dc37496c438418aa1ab82fe59729e82fd567729dd9d8e844611521a076edeb09ba308354dc2769acc67491c63f92f2a712281fffa974d92155de2ad72d0062a0f74bb3d14db2dad1d1a579b579b47830291e1d1e7fc6c3060e0c319ee3ec093a464cd3665e96597eea42927cf9f3c0b4e37c169b520836af74a0e09496b506a76dd124ed57affb4bbb80f28f8f2f8a402f5a1b31d7c5b92c94389590bedb8c3186f3048909831b0f1d5edba547dd717226565e38b2f56945f374e4a0daa03e906cc5c697c66c196a05ecffa4cd1f493072d4954618e2259af0220455547afaf76968a317fa4b114d35b1df1664749d5d1eb2b97e304453b8e63296859dadd27f2540195bafbb63c027eb2a2aa4f45341331de90acd2ae01c2b027c82012e8901317346c1e4aa460e4dbed274f0f5ccfd0066648ca6124934bcd6a4ea8f555105f9ed6d2966daa596360943a181488bb6035ad06525b6d638d9d6eae686649d67ad0535f81f8faaa944ce84e50b6d0c189bda428d26bb6dd76ec0c755bb3b8d3861207a8eaa48d78982039d9a5ec33654bca5351ec395a63d61da84d1ea304dfcc45ce21589bf5dd757cec8e512a657cabb0b945340d91ca7af5805b0fd0d69e8799952e0f9f1c334f6151d2931e1aa6929055b26bd500150eefe2a2d8ac29bfb868365ce28b055d733a4f44e325af5aa396aea63953de269cb974f06574e07c3960832f9d83b438a85bf10ede41e8bc834d4165090e25582168b2f8129525be259fce3ec14cbed49b1b519ff2a7a45715247b47b0d3486a0b90bab89607a068893f55c268b5c592f69e6b156a6fdba66c3b1d44a53bf290a58c26bcf375516eb2057dcdfe7d93743e8dd2be2ef27623f69419527094854c53fb4bba7444bc093a0fa6dea44ffb341a7a93be3b340d0c83aa8d979bcb74be071e0ba27dc55c3a24019245078105d6fee24db8fa349280c95642d54a3dba7fdf24bc5330a4fd266cfb0a0edd1aba3eb5c6fc489d5d000df26a18fbf61cfcfb26658f41d980b3bba80d650b8ffbabec82b983cb163edfa7acf321563b319de7854bfbaef633380a11aa00df57b3723cd8550fe0df5313105af5aaabf6a94d975fdfadf3ae3e9560edd74f472156fee3020be07d9503a81c447ac8aafa30f0fbd406fa735d9b561a93d0050fcc47d8ee6b38a4358e5ea6bc7bf53d27c1944643b77626190ca98d22b9caf654b6eb18e2b207b8a75e3d9e7a7e9a3d47ed74436c6860cd5c9614a2b5fab5a33fefc40f26a75889cdc1d93ebcb2edd665c41b23cccf83a9cb49800561a32314c93f6ee50c1369a79c920483114778c877e7810408d52e325daa7c85574d8c984d37ff7da037205724f938d483063ffbdd908784e879b7c03f9afc66f8e97930fd5dd8ef0fbd49b433faa755f5261616be6aeb6334c67f66b165d71503b92686a29efa27d5ae38b569612050835f3fb115b3ce1430c1c0157d127893708214547d6fd2e4e53b8564c7356bff2adfb0f91ee67ee799114221b998ad51efad48cf8351e89d4ca627dee4385442043d0f1b69800e6f02691226ef6422cbe814bb54e88556b167e39349d4c83d6e649f1e8d4f2636561f81d29b48eeab066910e1867d0abcaa3df610c4808137294bfc37f240afaee85c14d15d79762b4ba6ecfa6b9544ee40a2fb408cdbdd57e4c32838f5f17b12f63fe0b7e4c328c4efc887d111fe5aa68cc6f867f2006f8a0d30a93717771ea4ff204f5ae05accbb4d176289a9b7a4e9f552d220dcd1d2c50fcd9b305c798d87637caaa8c9726599e26414623e0a112e8818e438236c90e30d11033eccf182b04132cccfa8b7ca6fe887dc153843b838dff47ad9f962ea522fe173b7c019cef1f0031ebe4558256d54d25becd7290b9c631f57450a48788b3f201415e71bd998eea4c06ca71dab5aa6aa0dde22147541e1377bf0a18756990fb2cc3ccb0bfa2e114b577e552364daee857a1c8eb60a85a8c40b9edcbecb9be2948d61c0ad3c8a6339d83971d3edd647fd57f0c0d1ebed68528b5ecfad2e26bffdf0e6bbd7abe4da44f1570f763911b52e3c42db6da3fccb84dd24855d21b7ae678ae486c2c8c04a274b04855b074c3df516eccee56f3928e8d715782814618d42f953d1d628c43a159b24a45e22247e0a9173eaea9060c6e062bb65e7c447e841fbcea4de25bd4e99c6b4153d404d8ac41ec33e7edf9a13cbc5a523789ab0eb8c3a5135517c5071f639ea339cd442a8fc46783e205f63eac903d5ff81e27b419544f3835a8d4eb4216ce82e8837098efbac72690ead0cdea1fe0667a4ee47a568a40c0b9c0c334947c30f785eaf2c3ec870322c20e32d9ed7c9054e06501ecf0775e961869301941ebcc5f3419beedb803b919cc9143de8c859effffd870fc145d86758af063edce064b8c1611ffed70d94f30179670f5f38913d5689417ba4081a3413a9868a6ce4c3181b29303c3b458dec91f1cc795e14004a0d1da4fd93b055905484b803ad86cd86a61009ff2feb5812f33bfcdf304a99f59f324abbd145522ced85af985873a1567d25cd858b4aea5da559068cb0103cff445d5496f8222d8095bf662f384dba2f1ca977f75c7819bd12c3800e8f7b3deadd9d0b8f4b1e383029f7cf25875e5725eecf8577990b91afa04889e759baeee8c3e2cf3677349b0e748ba169acbb1c5689aafd21e4aa0590ae5d54e20debe84c765531ea122bb4edbd33675e21e87a4d17dfa58c42704665e9b94a178b8cca2d26514553e20aef6ec0bc3b340acfaae948319f32ef3e12debd3549325578f711f3eed5e6ea245702dece48d2eb1df2ed56271c42029f563585778765ada84a61de1d96ad9f3552aa960f9827282bd29c4d25667f4d297fb9e18a70a642e958e619ccfd3b4e6fd27c53fc47d44cff9ede89ffc0fb4affada3f4df60d43b6d44acbbbfced27fdb53fa6f9875e200465ce297e4e7b35b251f929fd55f7c0bbbfa0fb548087b2769d2844d753f7b96fca8af9a7fb6ef994196fd963c5c1474cf9be5adbe5117cbb498d178bb35bfc8432937fdb23cfbd693d55de73acb2f93ccc1460e8077ed48d9466a9b382f400ed6d9dfe4cc14f9d7e3e3e346fa37c92acdee23e7cb6f697643453a4f0ebea71bfa253ea853e4c70b9e26d997f8a04858312c284faf1acdbc4f7fa551103692c47d462387e57c2561d53972557c0b42501478212e96f9ad4c2aa2435f7bee7c41bec5df93dbf685f037e441e456ed2e0508d77106b4f2c1ff0f57f5bd757f5a0cdc69f493f7d36280a6c85ddf6de96afb05d8e72bc98b6db706504208abcdb00f022fec0be3c39c92019b853166b371ac5c983beb3b27aade8120e50b27a210a7a67243dba72516f9bb64b168ba7068447f39abc8c07a629aba820ca8e452dbad8f99fc0d9c4c7e71f9a51899fc4ce4a7646f52648e046184139926f31e44be8e0486aa11c3aa52c4b12c1e255809a59118700c726a940c98e4f0ca3238675d6add2f3c45849891ef5dea5d691ac0e0afd5a60a843979b85254664a2aa26b96556908d8ab9ee25b2f5fcb5e0bcf9e7957b65297aa5ba98b2079fe292449325c00195630caaf16903209e15bd527db641956f6a391e358af3f2aadc3f4f5906eb772d22c8d10977ab277d495a15081a6b2a3481694dd4ff5df8173e080ab0d977a0aa0a9f95165a9b607cefaeec01998f6c05b2a2f31a7459eddb49f3a1b7a04b820872a08674220f095795b4cce53f33e599ba7e684ce9218d926aba253b521eff5dc9ce4ae9042fa61a08f38b23cebf56eab97d51ca9723316b7cbd5472fdeeb1d16bd9ecbbd79325fd2e432a350342f4bfc9a3c5c5c2573917339bf1d8b89cc62e308066e48a952bb12243813e75c69d57f2108f141436fbd29961266fd8b8e04b202d211e2fa5b8e7a3d9dcd65c122e7c276776c0b3c435122a43d61b31267f975a0efc9e167f32955ad2493eb9adbc6efdefe39f0bfc60d3f1fa27ee425a40eeb14f898a1298b4459e21fc8ebb35bd50d79adfe023ffd486ef1afe46ff8afe425fe8a7c837f243fe0bf28474a227bb148d6a2e385d67436ed1ae683a59accec0024033164252ea8f8086cc41eab209209d23bf1224bafbb0ccb9c39655aa2a1531a39c0acd49723f99463924a7cf72edbb4d547ac0900b6f64dcebf137c7fa1b2848b8ac81e4be3a5b073148f0f41567b0cb6c153602bcb12e73794f374413fd03bf12a95f26cd3b6d1d29739733201529f5c955c64f073bb753999b9e098186e38147741de3515e6011dde565d67619a7724695bf9ef789af354dc378ac492fceb32761e16d84957eb9c8b8409478aae6b4e6f1a23201cac524192de37b4da83c14ef5339b03b93ac0784739dc1cf57e80677e8cc14d8694ad3eeadb47f22bfea8eb93bfe28f660b225fe18f52b058921ff1478f8b8cfc0556d79f1a3bc247f3c60f6a06c66c3565a948932cfd95ee514238abeafdc9520078b8907fb4113dae1b89da0a0bcb74b1a08c1c06255ea737b9e836e0a8ed902f6e527abbddbafa17a97a7f2831f52e56f9826648cee0853c7383f6915cbc3c6145ba67bab4a286d0b5210081aa8d13f953f65329b32bd75274ea26dbad5b658398cb817445dd33c28f6e65e6aa105fe1652b0882b5c52d3bb6b80d61b39c2c41396d478d28576a44794c3608bb0578e247871077dcb9904b2c9ff9b1d2f3ebac4a65d502617761b6c70d323ba59b11990dfa7bb5a70ab280e6dc39f9cecd1052aadcbd9e7b45be7337e61b3d004c57de2abd73e79823cbe6149dc9b34fca36b4ac74d43e7a95e664867a3deb7383745bd9c0dd0c33d4e7757535eeb2d4f78a928a51e48a0e6261085753058293000b8e3c13e9fa5dde26166bfb00b255a4e2dde1fbc6f77d59e26552fcb569b45c31c88f2051ad2e29771bade8f17564c9531ec27f325a391f2bad1c58c07f267fc2bf903f57a302cfe34a0c9c6f38079359ba8e7ccc362bf9ab888e7dac5845e438982bbfc2503e672f58ba02138a773cbfe6b42876325ee6abb5645c2ade06c2ff467e39eb0e74f08bc50a9cc4d457651d2cf7ef3d5632e5ded8098d2661a0afb5fee3a30d820abf802db1b9a7577984ca4e5fb48fa715d4d1c3c258e807745ca1cf561e71b085b58f1ecbf335b6d0a5524a7d46fc7752b75d4452e0a3bf6c68a1e72d592c2a7c3f26096b73a9aa2125279a1161e101657f485794bc4a04f5587eeb4a8a3763210cf815354db06b7208ae0625cfc93b784e3e4b62dd7c6d6b00caca9045043acb2b893420a46a447b97d1a3ac06f70d4f56702735977398750dda30e88fde55ca16a031e5b6868d6b59d6f25f58c3592274360cf4b6dbaa0b81e9e6d41538801bf31a1101ecf51df0eed99d94c63ca16690bd9e5bfd261feda1432b4aa54ce9f55b03507775aa12d0025593f82abda685705189102ab195b4b399268b1b894c57efddd650751809ff7393a15be8b4ef35af5d6dd2d31e01932ab08e202e25c92c8d919a08b09a362cc89c6f74a8c59a3887b4a65934a215a5f6191a04522eaa395afd84c9251fff5869f901da2553c3330873235a991d5c0ecf54b94607cf099bbafb6a9a756d6a8a06e9e0c4d0558a0384a2c1202d4bfc775249639e3ee7e2ff2033472e18073beb7ced600722ecc8bf50dfc18e0ebae3c4b5334a4a1b1695de0560f8e7e22cbdaa23b2302f4b0b4119e5054e0837aa8cf224068b21e9f5b8813291d4cf2b02d96eddffe808f602ef764a689d89b844085732ac810095e0834bb4ed7b5a6224245a52a3a0b6d8b848445250a15f353f48191296824cdf49bc68967ebbd62cd59173760d874fb83a74b07399f305e52f9335dc98d4098dec57094c46fdf1f6eaaaa0a24afa4b9eb2667d386539b182e4e96034be541b9206527da1e3c49d12b36d2d055ca7e2f64ccd301158ce3cfbf47e9e64b490c7782f592c345ceafb4229fbcad3d21b2a12177932a1c49bf522111478ecee3ea95aa7f07ea01bdf63685d358b8d5b03cd008407f6d985316fbda6e2959a3d1781986d56872a66a21551efeec55d5abc7e05ef2feae7410a72f8213709b08fe9dfc44a4de44f5accfcd84b1708574dded74ddeb79bbcb79abcaf9abcaf9bbcb79a0497ca7a188fca1f9ea40f4f936b31ab911a431312658fd7affb01f4d60d2818604ebec9f9ebfd5e93543b0abb331a97f8c2282943e5d77b3d92d594a2b1a0aa02a93cb9ea9d5db5eef5918af590b440dc02d7959b611390dfd89a3d02688dd3d63caaa26a69b8873e02f70b82e7f7bb85e4dcf67a94baf5a7b1ee9b739a082a11d1412ad6dad9e57dd5b1b7d763f4f680ba0f8ad946d6d2324c502ddd9a30ca9d9ef799ffb778abe53e5c762a7e4ba7f802fe44b40459a2623dddf6ee2d8ed1c11900b6ed76060636f001722e253e16a48ae447cfc5d9604095617002ef4f0ad6c6f05d8ace984132a97e759685ceed11bc608b1f68fb0c617b6fd9e9aab5008001e82d9762df384bf01471e95e5c8129063abbdca4d9e22dffd1ce7d048b6050d562a95c23cf553fc82c96e38799532280cb2cb2d5bfa53895f47afa0896165fdfc17bea6546c172ca15846129dca16adb9fd612402d75988340e4761fe628764c25073fcc7376955e6f787299d1e8d0c7946d56547f05da03d843d57624059012e13d628ada209d9c495c3803519b7c375d890e8c05b9147f88946af69c65c1e2e82920b666e789e1da60a6acabb5fab6fca3471350a0dac52f6e442cec32d69c31f0dece62dd36485d08e1a42ce12001b200d045227f725adcb3792d2994f8c20c79f7ce4e67918ffad5f7a1c4336b8f313b7973bb03c143457268506abcd7d2cab958519138da8657b6a67f7f34765fc62c47721bcda67785977a20e65c74012f330b09c2dbb528f4f54fbd1ac1545737a74ff37b2e105bfe176a5e26059e8a77edb17664f2445d370c4cc320add7ab7e368b2845c427485fb4ee9fd511553951cf67b4eea8fa097a032e3ae3e7ec6c30e048cc78acd3949001af915daf563b8cbce2ae0db72c8d99e09653553ad508bcd067a3575d82bdcbc1423172298197e18e3aad0a0a0cd8101e4a4c11c287cacbc5559a65bd9e8988099fdbad2bbc96c44e846749ec088b123f0ae17eb3607d61830b92eb2d3423b94108de1079fa2ce035fca1c40b52548b88ea2539cb3be4038bb7a8e505d5e7b2e5cea311be220f255e127d5158605d2aca9b9b476377cff5d6becc6f288f4469592ecfdb96cb09996bb3e5a903e59d41b297012715038e127c354b62f27777b699a531cee43f8b591ac77859b1c3ab26f23f8f79b3338205a6422f8811ade50f7a4e52f637775a095cd35557f4449fb3f002eaaa199b93cdee14b1b628d53d3f5744b3ded6e42ce5e4accce46c6016b480554d147b64a2f429b0c46bf250bd3d4787bc84d81304560ffe58bd665f29abdd9cf8b820576626f3f3e26c30c8d1729691ab591ec3a4f05926e7238bf17c96c5315e6181d79641be6aa365f97b555bfeda8da6ad46afa0c5ddc6f564aceb677425b1b478b7eef18a53fa2b759708e1a514e457f90dfd5612e02ed332bb96792dc2d4fbd35aab5b4169e032f5fd4633136e92f7b46ccb831da73eea35c4e618aec594c00c5e002c0e90900aba947c0457ddb24b6043676d90c8438b6d45499b91618b8dc9dcfa0b5b9710550e7c9578a71998360f16f657ad0e447772eaee348262ad3601b2a60d8bddbc05a1d84d82662dcedcd5240c62a7c98f4699bd9dd4a866b5075c4792935e755d73dfbd09577b20ad6e5d9b6409dbf945512de8479aae2d0dccd5ff4e37b8200fb0d473130d243734943c6577cde5c903aba395cb1b4b39a997b2396b153346f88cc6314981e3cf983c7ab1f82c6f536751c2c9da122f9f7a77b473128415038baa1267aa0022fc9c4d69e398c5311b7214f1e74ce33f6505e5a2127219e6430636fc76726b2731129e72a7246097d377ededb3a14b07b23975f278b72996bbe36cc7753eeb82ab7becbac690821f60dd49d3f94fd79113d4794cf9f7cbf46af782a37d488538ef751d4066d471a7bbef702b2ad581c6b0286e8f1ecca0552f3faa9bee1dd85a6df83b6dc0fba8a07b1e48192582624e4965f757dfa4278d9b74fd60f6825d6714c88ab285fa4888f0d6e91dcdde24fc3a653825c94878f94650fe43b24837e0d3ccbbc30511defd595ba13be173570a12cd1a6c98623e4811165eca98497e9e4c5dd5ba95d868c34a1f26b20568e9d0af6c9c6431995199536336ac4dab77cc9eb4ee78859394367d9b38d0a1f2bba4d823e80f9df1a9d663544c36ec0b9b7b6ad5efbfe429230e307e474aed5685fdc52fe90dcd409fe76a93652f533ecf68d1ebed7d0925ac9a29e5ca04a40493041aed665a079c629874269baf8aa4f60769d4e8f55a60584d0f08a74d288743b4abd02f27452b6cc3357d3daf6dd0ec6facdf62cf92f34617706eac4d19f4516e7f8f2daab37b6875ff94eeca0afbf2f46650f9bbfb3798fc1c9aaa95b883a136395780eebce61b193d7a48f83cda11988c46b0672ba5378426e75fafaeae9c86b414626b49444607b034effc39b53433943a9493f0b98353f65d7249b31f2086eb1ef9d1563a3a3c14bd5ea536498792d984e8bc4a111e07540db454a31117c2d6d6eea5793ad2fda8b743b3d5712571029abfe1f90a0c125c861fee228aef2351ea3b2b988694706f912a450c9c37560f2eecc5599ce767a890ab06a8f62c795e9ca164587fcbfc04f2251019499e93bcd74bce498137247d4e1a64d1eba5e784d9d4650e0c59afb7292b8f57f89a8a9730312ddbcd86e4015890620fb51705ad2954f251996b4130a076ef68149e551a42d4bbabed9204ea337c1f51efbeb64d926925c0d634d7d905eacc76c9f0ee75df756ba88636b4c836ae47dacb02d04b6309866868e5d8eb2c448feb3f75a0ab81adfd8069dc59600c1b5da351386824fc764c76de89551744ea30361777d8a67a6c6f6fccdedea6de781cf938210ff2507d87c174095b00464d16658d2caa3c6c3688f3ff63ef5fb8db38ae4451f8af90f872305d42a109288f754e83257cb214c79e916c8fa54471105cae265020da6a54c3d5050a3081ff7e57ed5dcfee06453b3ef7ce3d6b9265115defe7aefdde4349478406584426a95fa22cba357615b300f20530390bb42744ba28e462b75971c9c5825f494e800250d6bc0c595b88878b1651a80cc074f901859587ef800903e99fc9bcf176a9d8c817c0799eee699e1e681e1dc0b026cd8337a059295ce03cc0c69a6f808adf00369af0ebbcf18871a28c1de0e4dc241a4bf93f243ffd9799941d3c1521dad4ef171cecd3735dc21bf99d08ad39fbd0b4412a39eb7ce5268fbc951a2dcb1e8c455d96fe8136dfcd92472fe2efa327d3655ab58bac77bb53ca3ea2aff37a9dcde6b4a96e918d6843dd22eb6d0afdb4d245befd028cfa0098d7d9e588ea95c92e47eed5dd75bcba60977a0e46687c063985fa5143c8a01fb5006a54faa86c73f1977c5bd31af38a7229b9301c4c424b6f54b463a5630902624b976c38a60b5dafacaaadbea08e7a7928568949c74b8607d8d187faec82cfbd0fa9a5aabf567c938082f6653de3731c725a7f2cb6fdbe0abec843cd6a33404e6cf0a6dafb4d26842e58656db8fb7d23b5ab67a339c1109d168c14308f57f99639b68bd9d2e371d748a1455a73b067d25bdaef479f8e6da33f7c5dfd657bf10781d53c2a8fa974d74ab2558182b035dce9f1ddb824531e6991a017244776e1976e3b849211dfe9786c608c45043212c1405304f684c0a61c8f49614d99ad1d275d3260bc8c9b1b2f98df60aad870cc185b4e3b4e4256cf9660de803d806be6e1b8dfbfac8e4753abd56b662d05bc99ae393d1aa95f324e260bbd7b21202a1c864d8b10e200bbb40d7216e7408ea33757fc49786f7e5b23de4bae4364b750084a1f43f741ab2a7bc04ad9efa9d7b2ca7a0b78207a2da8b6e0111c5bc4406e4c5dc7fab7c7b8b33fd02657311b3bc0b4ee004c3098de53b174bb2a22a206045003034f0d0c35b212d207c2afd44098e533d4414888705a88bf07bf7ff815048adda8c3998dfa05e878840422dad78d32373064bf10aea970cebf00c3ed1801dd1a43586e67c72396791313ed58338783faf7453295fa73090c2770d252548216cc2e64c8666abe37d1ed52160e78f9eaf1e86e7becfb0022b112606c84504ec5506e877a8506602e7912f36f82f70ea611c34f11e0a02d09ab6edb0dcdb9d8490495c646262780d16c3e0b4ab63c8ec5e723daa2039b203c2d6f982fd3c2499b38182e17b6d2d5732073f6c30258cffb4161d597378548f481e0e96d5e7317a35f63fe4132c9a02def4c27acbc77954558d9274bc6d3c3b00069d0615010fa0046cf8aaa6a9bc9a649741ec4373ef0a6312404f1101947affa19f765ef79a74f61c6e33d665d766e58e2ddc762bbe54b883be104fed384a7eb4a163f5742e5e514e7f482a77bd0223a68d4156d23a9b18d041ea62e74cdd3435008a7d7a33d556d7b84503153737639a28264e21444cbfae08dcf6b324d241bd4d6f83cd7bf9df179a1bfbcf179a53f9df1b964392b984e43e3f3acc446e4f5683acae40b31d5b49bcc4adb5e0e19f90b3555594e6fb3d2355d404e01550a5a66a5e9a582f40a6a54c1a6dd3598afc6aa40d1dcfed4e0e012dc8bcb7e3f27fd3e1c65bb0045bf9fc8e351bd6005f4d4efab6b56e038f515cf8f47a1f354b5edf785cec2913eca2e93d681449b69b6899f49f7698e43e6762e7c3d3da67edbf120badecea0eb2dd0d980aced330a2b041a30911b1554edf08e5468cee01e08e310cdc27ea0f2b2877d66ea1d322cfe2913749dc91372057c81419e96b6d0204f952e38ccd37298a7525718e6a91ae6e92dd8f0a2a60c74018a09d0d6843f062f29e682333899eea94c0f54a69fa84cd744ff608ce5e9a77e5fa66bf8b90645e6c79ccdb45ab15201da1848c01c30553d5dfb89e6581508d51ebfe7a25a2e7bd8894113217a6533c4dc397e174282a17ef4cfa047a6e01d0f1e7a0a5a6ee718ac8f20551af00b32bde389a01c14c549061fce32d0e3466dfdeae618a0fea91b85eaac82d63ee4b3e891d79aed187cc21978c76189480f03816fc8d573d097d258bf4fa28a01dde118babf8815896fa479209f79b42f3d0ccdc395d9172fccdddbdc7f15070372e32d670f27fa86b38ad38f9ced38fdc4d99ad33d67b77cf296a72fe582bde1f42d4f35edc93ec24f5855f6097e7bcf387be438ffa02998c06b397ddf26693cbaf1bafd6a02874dbe5f17185d0af0b55ae58b8fafaa9d5080b80107501375b4641f1aee350a327d4c7d8ca737863444db600899d6b4d30b9c3b56d42dbe9ae5f3a19ae5c3f19c90c87bc61d57ef8bc5c73a21cd9624e67ea707fc652575a92427b462f98bd1b4ab133914846415154cda93529d12637140edd449361c4f226bd8680112c9ca6722d5eb7f57c9c37718f735bfe3001f6f73e953489648563cab68cec6843e2cd63bf13193571505abb12c47fe6a560fe5d5f3937be16e73d9a30fa8caf6b0a9963ceb951a56f44e144d23b207b019c9660ff822d9a1f46885dca9cb11bd93c5121dff3c60e25f5cc2e5e8749ad343d4043a75ef9de69d76a6563d48bfaf327b684f3d4bff278d669ea5ffcb3da2ef3813dcbda24d2ba9f098ff4b364ae6496fd92c45e3c26f77fe7bb4d79e0c0459db7f1117db14e28b5cbe810378c6f6a90900278247aefa1b4e0a44e0a1802691bd13c13bd9d097c744c0bca5462e35848c6d44126215fee80f1c0ed205a0213daae283497b7892d2d9feea30d727216d2e9355b88dd34967c31e9e74b61bae63d0ac4fee68b5e37ab5dbeedc3bdb434766ab1fd130d9f10b98861bded175741e7ca75172c7b41a07ababe1d6d1736d3772bc0278a7cbab2e152cb4c0463dab5dc97d99eff51768358d347474aa3fa066ad488719889ca93955d4aba19b8c968abc8f4906dc6baf4155e097d714ad987c4c535a3f38139edee059c7ca81cd546e0db8c0b3c6e15ca14350285475b426a8d4ea3b32e59c75b4b517ab47b517ab0eed454b71540d8234243caa889c35a3033c312b52780328fc9bc950791392ea999a879ab305aa952b702d65e711770d149bc6c86fa20dfc0baf365cc98351a4a8c0d54c715f81be5577d1b3ce1a61d70baf285ab1bc75e340dffc8eab2ff29ac3530ea28a2a2deaaf1c699e10bad355e1d01e8f797864972c4f1779b9d895b9e25fe412da8686ea24377baaa82474d12808dbde2ab8a3924c8a802dc04a5a0056c8c4b4ce96f09316e99e95534c58f37c992d52d4ada0457a60e5d47e66be082d0cc609d9e03dcdba9e413c9595534cc8301b4d07df69a0df11bbc75ff1e61b8042227dcf72b55817e2ee6f055847e96b6734f78094c51be86c5a753f7c095b6434176b369b1bdf5ea389baae2086a13e5334b91c33c60ac3b9af9df1b6c066c8f1e8f87a45604361b39d1cc72658ebe04bc63801886311b0da98755814f59cfda45f2a8727fa9a4d93e12695e5eb0247cbfb419a8ac02edda385306b39b51633c3b1a6b2ed917c8c226aee94b42b8c2aad5d2a8b0d9d5669172e407cd1d51412683430bb751c02c46bad3c3f13c6a70cd4a75c2c750a174bfcf6e440e62c535d92beae60c62a4e109fafebd675bf0034f228141a5e2f5887f16c42e88a2d9a4060cd96b1c23addb0c5d3cefa5617048f8bb85ceb199f3b18496f98885ffc035bb4aec67d73831021bbf301a3b728249f8eb2ad7eae5fb051bfbfd50dbf60a329fcc00c7adbaeb34df54e74d7cbf74357bb10436ce32ddb04b1d30ec19d3b04ace57b82d1d3461379fdb6df4f72b699c939f1f70deca87283713276dfef27851f5db26bad9b81957ef58899c10e66b033e3eef777662e53f881193481295c8ffafde27a743cfaf9162f46faadba1bb0c2bb08acd8a27dd2eff40391d49d59835b428695777a7813487d4a727dd3ef2725bba135bb854e2f57c7e3ad1ecc6a5a0d6fb26a7043e803c0e6926a409f5514c07b4d0d3caf07a5a6d5e89987e4ec4bd85b957cdfd36023427da767ee8aa3c36901d6c29ab87e319ae6333e1ccf8d134dc69d3f93e158670d6c56c9bae853e71f0c19b5e850b21826e6bb9e8242f1d0681967f5b020e8904067f6fb49cd8a4131ac34d42a8649310c28ec9a90abe7cf4a4be2ba15af8715645c455c06a47e1bb4b2814d121d075249b2d7dcfcb2e19923709e70da751b096a42e8b6c0ac6b273e3e2bec2f08c4ee86fd9e27b285908faf4684da8a790a437570144fc4b0be7a8ea7a21ae89fe66454e811b53ea7ea15823c7506e435cd14d1a2a0db1d85b3d72c8cbda49351591fdb0984e6a018221a786764525ce793c1c0c5d950d1dd462bec593127130c9550e98522c7a3fbcaf7e47814b3c2195dba4ebd6b6fec963ccd142e5c1caa62ef67916ddad9b69cf1b027a7099a2d9da38da5c9eca2fb9c6c283e9dec3d4f9a07b6518434686157c51faeb800e92473b15a07f9db5598b4494aacdf3cd6ad62503378f018de86f0098c0b10aac0f159870ec577bced39c8a96cddee6e6f4bde6468d5054850ce71b40c3b8a6e2dfbd5c9698a65d6db0ff37d510f47bd736caca01e8aef74ad83afe5d8bb75f660fd27d5d9832a5497838e5eef64c8ae4e0c32349e8b6ce790303b1e7b3d10e59c2d86f6bfe65175407ad0cb2e92de80a77b2000073d0aee880fc1974ce5a0477a27c769fbf3e7386dc05cfe4d3c017559d2b9e4a85e53dfc426a1ba85feb2aa17b18321dab30a06bdf9594687778cd9607418c70422f04200afb16ab0310495949313f957d818915964f51863a27e8c21517e9efd41770d9e89c5c1e8d2f12f164c4cab10337acd17c5262f93f48f24abda28532beacf6ebacbbec9bfa18a2e35122ea675833ccfea762b3b281eb067aa800b53ebdfd6d16bd9e2bc2c9fc673291fe5b994672d46cb88abe215a34aaff413aa5c95a19e8b3d8259e9d55d8c9e96988e742ad6af3f16dbac304a2df85a2edcbbb922749f2de8215b9d425ecae78c741dd7041e33ff78fd725bdbb688365c397576e562151a336fabeb73a26d5f04dfeab7a7d3c856262ddd6e022f66605a1bd40e060435033b5a5f0b557d9ab570b02256f0b1836656b96c204243945f6bb66fcdeef3a66b9b1650c8ed4d85ef9afd32e426921594d6fc5e769adfe7dd16f7ee616999a75bec3ec4bd340e55db35fb8e27b3c26978a5923a1f033651b61c0d182d2bcc9fd352032ff09cfa630702f18abb20745f71f6fcd92b4e5f72f68a5f3d7768c4b2daddadc54ec55e4ff127ff1ec2856597236a12d0d5d6e5f844bbb18e92df71b1b42198cf858c60cb6a018b6e5c27d937a3b72b7bb8c5809e57acf0fc889a194e2dfa6c486bae5e2a258bdb9de2496f51e675dda33c2d9683de1047d123d4ba212586d9460538408e184096159f4896eb53a1c7bf2eca65726e9065d123843ca968bdcd450fc8f843c95b971a86d248d44f4e3d53f37e5f3ed6c37bbe57df544b9ed4c027b067d058267cf5feed1bbb17d903ae5af670c70597b9e26ff0bb0b2ec20bef1075ace83db9bacd3049535764936f93063e80d4396f3aaf1be9fdcd6db89b92e3b30d06f1d291838aef5526a8d340c98a169c0d1416756e00d69caea24bb7efd372c945862f4780359ae3309373723ce6f6b7f14d4ed1a5993c9d08c966f3d38956e255594447bb21ae67cae00b554098067e53922ae6b41d8fb33969fa5249725635974e1062c9c87e3fc9ed6fe745bd99422695f569444e27bad8a96aa70249f21f47fe151ebee434b281c9bee2bf292e6f6429161ba792f5b28bdee09762ef5e0e23c83411cc196190d9683e6032130326a9f098fb379fc3dc5fca45e8d9d2b87cfa2d30f9c0a8ec5fc3ebe7c0022fc45ddb43a7f741a561db6822aeb9f75280a2aca23687c870701341fafdc1c07b677a5cda89475abfca1a1ce3abec1c19bd943c07999245a2766c4c976c4c176c44576c44d7ac0830fa0d5b2364dfb2326d9ec7abf168743c8ee88dce0b8f223db002d80a7a093e60289dc270e2f55b7073fd9519f03df3d8e4fff88ad33b96dc0fd8fd0bf68a4f875ff1ecfe7af88a4fbfe2d9880c6ee8ad8f55774fe85b1fa9ee9ed0373eef8ed08f3eef8ed04fecfe9a8dfafdbb176c743cdebd605f71bad7692f3924bee42675f092d31f74c6d0e40c4dd62bc87acfee1963c357366d3a1c678e87764b6f9f6de91bfae6d996d0d7ec8728f32d7dfb6c4b3fd28f3af31dfb341d7bd3c3a8e2b76c1fe685f5263b96bc1bbe2757cfe99225df0e5feb5f0b364cde0d2071c586c9b7039d7a327c6e9a7bbeb8046e97241b0d2a1d05523c4666e9a254a20a52248f354724df07671e24e689d1db1da28aee30aa45ae7654e822469313f47d9b4596b40a6df5bca6b55b4a4d825e3da7238d2b04067abe64d4c0b32d9644eccb3078e222c32a366f4df0ec9acb67ae229ee2f715085f8ec7b16e13b589fece16cfaad8c184c9f981ad1a39eb54e916f4b5b44c73d3242da2693707180eff59f36ea15995bb61b4e85e97e2b1360f7a99ce1c99a2c128c073f1cbf51d10140132e1409126072c28d2d376182d2d59828ad103ab147df59cee74a2aab603a70d0db7a1f224e922fc5835f52ad64cf4fbd61bba41968f476ededfe928937e675e85202d593919cfb3a46a18f27ec535a40c5b86b7099a0b6d48b767ca8447e426a0703581e45d6f73fa103b7295b117574591486eab7edf3c4af4de9c257a6f22742c749f70131a60d37d560e727b1de821dbb9af1f42bbe9a537965e347097756495bd8dacb737064d31b4d24b9cbd23999295d10751346f6881108b531c1c0761d2b5ffc921b0e8652330bef0a728930d8eda4c0dc773ab47e2ac820fde54396c6e70880f4ba443124381b326f1d111eef0df386af82045cf7611bf2f270fdc705e67f99c224ecdc9f128ccd93f1e1339605e039880ff51198c31ba0fe78ca60247e57a4a0e657931eaf72f6dafd3afb87179805d5d29928dd0b576f4a69cc76f9cb7bf51244087088b3ca01d1b32f2260559ac92651bdd52442f5622d9b2e5c8db20f4545d32e6d50b404e2c0312c9865ac6e19835184dfcb878732439f8b4a5c554bf3ea1e3cdeaf1373aa78a900c94892c18356e122e19abc25b0a8c8d58ad6ac7128d0a36d157f222d9b1fac56e5a673b322db39da35677ff9f63d575b1e67efc9758733ffe2ad65cb356176b0eb59c9aeffa6f423d246ae0e5ac01562e3c274235bbef328470c8c48fc622a2d373e2dc0492a4634247665a67d1a9c7d4985a38ceb93e03f7628e4fe6f5d6be68ab91c3bdedd17c5fd459eff0cba56f2d799bd73c6f4adc9eae897ea2dd965cb19d16b47a0a0577dd537a5c7d3d5a9d5facc8fe2567ef3c91fecb6313ec7f7d6c021bd6e044e8d71d0cd4ef3b24b0f4834eecb4a8f526223fc7a15afa7dee63c2168b8f808c019f5bf27b2e6b4e731668f36d0a3155d988165162bed789964966d43aa6459683aa999ce659115814fead695178f59ce60cc6059a1f3ff344d180e7566db342231dc6b4143c9458f3d20251101377173f82aebe681ad5769865624c6008090cc01c7a018d01ec030c5d75fb3e0630ff4cfc5f6fd9814e3e1ec2a0ccd43aedc82ec7f457d97c3c4d22de94809b23fdd716dfa911d9c61827b582dbc4c2e4ff02016e686fb1bb2d165f0bc5e5b62a01897d5b2d75b15551966702e0b4de5f9440b71860919b352c128e3d7c89c36c33342f73c4ccafbcc4bbeb45b6a53a5971cd47382a1c8ea9e5e7a155d08e2e700f1194b1230cbd5184e27919d6b0851df96092ad04ff09a60a2db1ba7be89cf80c3cc5d796a876243408ce9d9b7299ded80bc6bee64999da2f5abb9f35f277e4538c09e4538c09766100e7d206f80f549f4b746162d393e8dbd720b4486f6ad39be95727755a2a14dec90fabf4170acee5679ce816ba13438d598b8faa899acb06fba3b2e61eb070bb7e5f4fd476e9e76baba10ba457481ba027a4e46c5fba6d4f1e3e81bb12337bfd99a963a96b89999e8adc31c32ea24b563ad589859e079e03bad2bfcdb2af99f3676fd1fbcde3740958a8c82ebdd49692c572ba344a163b50e69bae9a4a1601bb0c16f0876489a5bd8ec522d0b158853a169b968ec5ae5bc7629f497ac872d45fa823fd05e9f41772622ffbc60a7c03a0b0e9d497d8787e54cb26ff5112677396c4d944649cf5f8f5354f6a7bfee87abab6bfb311a1b5e21a7bd4373ebbbc5cf7fbeb34480ac0f226f0fff2f4f809ede0bc0608b53ca5ab06c4d2c02df6bf559dd708680dc186620994029cbeb47302a6619ff02ec1bc7730422bbb4658260044b4f080a80ad78a7dcf93998c564f445f85fd9aeb9a8bb2d8b22f7802edeb0ffa379e2877cb94bb6331239c105a05bc173cf6bfd69ce0606ff488aed96852ac9296463f9296351bc08dfd5ea36f785d394136c1126d432aa9f832a6e5d0c0c0f91c477ed4f50e982265a4608f814af226576656581923a2854c8353bdf7fd7ee1a2ba31b648214c7152b507997b05fcebd1743d60d5f138ca56f8d71bd05c8fa61d00693da849d691be1ad4c4b826bde8c8f6ecef0e087fd6237cb83d45939317a84f58305b47dcf2d214d0afbfa75c760def316d990978fe55e454ac127f2d40ffbf4c5745a9b84c9236b57fe98ce534303ce933d9db54a252156e529576e399e403781717fcd54edef3b7a64652062128d0c8a76c9af40856820b351bd93b6a2869b8522b29278ed9443fa482ef552ba3f2b75858061d6cd177a6a9bf33e99a055f6b5d857e080b1d1a85bee17ba55bd1fdb75ad0993fd8cc032ac2b41484f414d386b744f2e465fac013416b306e7c31eaf73ff0a404db087784d06154f7e477e772288af0a891e89d5bbe1fceb6f00305011fb5f23e4228bf2e9d95861de8e0d181e2da36bb80d4cf0c1017beab667b60e7c234b5a26276074e3211ef5470510bfd05fc068ad1569c1db1373bb618b8de381f82c95e39782ada760ce847073d4b81e52192e0d35196a3c8951b8f3940809b12f03135b695598edf034bd16b8add1454d5165a52d5768884bf21e04d3e7e4dadf9264420d129039b75d2db1007a8a25d7611300d425ca81939ab8c1d45fe7fa63ae8d7ff12cff9eb5fc5736ed67a5c1dd49776aedc31073cbafdfb63860d1af84bbdaf3dfa80369186e5a21bc8cb3786f102ec4cc3ff5c16f5b6cc0fa09818b045415456e632bb1c9d10b336ba6f5105e0c7650fe01ee9a5fa079715f04fe9d3d52147a75030394cff689d71ffb73ee47feb43feb73ee4ff7e7dc8b33a90b10ae46fa1d0d8380d4e437100fa8cd68ec82b20feeeff0805c4a70a568240d369b17c7a9ce966bdc73512adfb8bbce9e6248f7856792326a987d1c7e388962c37e6fa359bcdd10d06bc29f0b9343c2af498653d79e05b9600255eed84829bbb13561c19045b47e05ab420ab1a0c48395373a6318c3cbd59549bed4e711855a208dde93c49eb01939350f1a0019c973315e8dde58ff1ce96c06024346f301e97decf4c34bbb326a43c88e7ee7153e9c3b73b3fa885488451dd1388400aaba627341e4826aa5b2d2f47553cd5ad72265b3aa3d3a89dabf168f4ac5d281b639bb1d25e5473a862a53db07a8bf912d64b4314cb82355b89b4e0b8737c134e873f52e557aac0b5dcfd9cd782cb8d4fb61d8bd49b806fbb47f78374c1caf4607eaf5815c62758b340bbad846e4dfc972f65b5c13a8ea7e15de5d00d480fe0b2e963b7659b4112e9c999ab677c46b4b4da7e4157877f45e50df1cdf2aceedbe1510cff7016c33f9cd57d3b3474df96f4902d228db551a4cd26a637d93a8a1fd252419baeb24d1049a42b7ffb192db81d55008a005b0f55cc3aa0ddf9887efe4876c4486eaa99a9a69a99d2689351f20a5012e554ccc4607022848adf8cc4a379dbe9e3ff8b9a45f9bf42e4e5bf86c6cb9fa45614be598f70ed63458b057aa84083e2d0dd426061ac29192323b1c19b3d0eca9d5d8bd3808350bdd6684fd948bdce748f3bd33d199beea986e9debff364d6902478765a2e1726dc958bb17425e6b4d02f67a01fb42d788f7e4817652578f232b56675c4abcd408987d6eb343288e25f38fb86d39f3afc8eda0664be04d5a350b3e13c811caaff602c170897d203d0d173621eef93f93ffe6595853368ec2f51628871d7cf2838fc129586ffd655f82fa0abf05f898cf895ba11883e059a1180a6ffc62a0af5d35513caaadab2cbd1afd352f8754a0affcfe822d8fd8924be9dae2dc38d313e0f51766054271d96a8688027fe02af1071ac658b4b2cc11f84419ab33ab51e220e2ee530e17647abc73d353cea23d32285a04b9047ba044be2bd22d8cb5876e8127cd6f7c2ff1e9f10f691f98927b9d325d84d77a12e41a7df88a72b0bb48854ab2b202cc11ab827fac5aa00bc4315407a55809f78a2bc2a80085401a453058032a12a806888eadcf597bf5e041c82b00012c696516d596ffd64592fb2411a52a540f65bb1ea97c97e511859b58591d5d365b6158588799d62db66dee725b77512c96ed15c8c169f935846d50e140ccaa83328eb94eeea2a46befb782f287674c55badff1f29dcfae95f126efdf4ab845bcd5a8f0bb77e7a4cb8e5d0f57a912b885cf8440f5d81bef1b8479f6e311068203f520ff5fc7f030f5d2eef11275ac677d6631603667532a7b49d5dfa7869ff09e74f66ef38453767d99f39b52455f60da7b1bdc1971ca41cd95f3975c2c3ec779c6e0b9efd8553a09bb2ffe0d4f6f9577ef230f01f3c62ecf354e4aab8e7d328ec4406f7e57b5e429e452ca0a25783ff3bef88dd406b5a1ab7788fa83b4dac8d75e1f53324446390c4c66ca8582240050ac07010b4a182a00d49cdc42c9f93200ae4f1a8923a182057a151c2cc7955808147609ba726f04aa281944a0fa4df17e821179c7a51e15b55aae993f39bdde696cbf4bb6fdf7dfdfeebbffdf9e6eb6fbefcfa9bafdfff408b473b2d56c9a5381edb7d5ba78a203d0b62a400975f268a5664525f4300fd199fd39cd524ab196379bf5fb841eb51177ed4427920391c43a830eb91b8b7ef112a5aa9879e43010284d5bbe49e46014f64ba2760c121a6519814991e8833e2c007b7fe492a1fb3398f22fa15109bd90f5baa1849fe0787286e13916a00c0f0cff1d8dbf726382ca1124c2410a4a4d08b57f3859ac261902483ed93f4724c21c487dfa0c28a3593cf1edf7455c93fe78b75fcf68752d45901c1308d370fd5ef5faa28786985fba4e07055205b84f12b066053038ca2c16ff227d92c027a7d7eec78f9a36523611287d49973422558aaba48a9636241a05456fae97d4275532e6737e5f0ab76a5b9212f46a00dd99225e312877405d22cfadc53f3b4f4bac599e6583db88168684c8cd244771518a999293951fddef0fab758112770c725085687e6e444f78f774173369bd3825d8e1f876e18d129d1d7b4dfcfddeefb136262631158ebcb11423d3f967effb200afcfb339a1f989367df5ffca61fd603b3ffc26c33a9d68e19dbffa47af52d15e7e483fadb96c0dc83d89db4a83537522c16352abc6bb595752850020a0e4a72283d096539e094f46a15927462d839f5343060f8d27eccc9619da12d108cae0e16912307c26e654cdc4dcc0524c933a4dce833676aa339453b587a84b9b7cff1d06fd9c14e084bff81914ec66422fc97cc83049ef80fecb4418f5d0e9b51955396aab0d4c350a5614a6031c40cdc2b4844c2a8df087de4850d750555bd4e659a930d3a83082191da8806b5c312c606ced9cb222ad90f008cba01e9f55843c15ab445a392720c2c3520175d588e008ac7c54b7c13db3c554b5edb9488e844a0ccb793ce6f0634ddc01fac424e5e99ae5345a47532133e5fdde2d55ec632ad82dff5eda87483254731c8186e2c8a8348eac4ae2e8e4a3cf753e6672c6e77e9594c633c48ccf8d5f037ba6133e9dc5eb32cf66f10a84a76fd13e7dce17810960805e5478d38b4a5231fd048042fc6db52756cdc59cb5e351a59f5c600c109ad1a54ac2f01b541142770a5c811704d4b72f4774e7d49b925a83177d4256bbb2fc80adee1022155e0bbedf5fa0b85090e3b1f4535b754f8d89d484d1a52584b4dd31951e1e9b693c511a4e616a8e3c0bc638c5e36f6336daf31d9610e16136e7dc8670d4cb86776ee72fd06e509995a495092962da1d9a3bb763b630c9eca04ad7793930d54cd31846d2358f0123f516d96e5c6b43bcf0a5ed8f4c54ba67a5c68ad9ae1dbab3cc0fd54e650f3652f143f75947fb592ff9592bba51ecc1c4d6adb38713cd97cb2faa66680fae7780d71056127ec12ba3fcd232151e96cb3155a9a54099ff793ce28d50f605b03f8ec71155e94d991fb8ac99fb753cb608d3d9c3cfd9a8a5668d4ac21d563c680d8f63768826957c53ddf3f6348dcd36169fda6a71bc12200e44bf6f73eb2de08b02f045e771a38513588f0b52e3033db756e0a01917a7477bb818bd3988238c194cc546930a08c28a4896cfaab9069279fded27f19dacb65caa4322c135c34cce998047ae2dfec0416844d802456f968e67c7d85579ed5c55d9c748da9b0b4c46fd24e391666298dbeb517744613da7c4e563e050c1121ee9fd3941043a323188d083d5d3b8adf699a4dbaacea43b55014f2093cdf826b8a40e9f38790dd1138688ad555229179698d04b7060e5526d94624d5bda3408490c050b9f689f39a7bba9db7b2996efab6d06bcbd45aec0ee4f37f8522cbf3026ed36ab20d4316d336cd27df708bde752158bbcf46d49124e3cf7ed9c4ef696125ab23ab555e98ed5e133b06468a19fae24e73ff3e4c103c74cd1e041cf848b809ed3fc3e2fcafcb6b4aaa5f4fe8b6aff36df9bcfabe757968f41d798631aa9ae9e9f085db042250ffec1cef4e74953a09fb282aeb38aee8d09023da00581ce9c5c9ed1320dd4497987eaa846068901dc79f87ee47a813cc8eaf755da98984ac389517bd0a36674b56892a7a4b4fbb0237449e84225255d985f3bf805efa649ec229abb90199138943ac044c47c08d8ae374dd39f0326a93cf1f4306022316795a77bf832675c240e7713893bb9a76441e84a25f88ee2d13563d7d517e927bad0ad2ed235168b8f32160d426318bc6b81bba91fa405bc69f82861f240b76a5e27c81d2cd2f5891acda03a906304ea411ef1bbadf6934225228ac84185c58970c86b70467f3ad1ad62c95a354ffdcd0d48866e6e30d28b790bb3ded5b37f8a8b6717afbf7d7b61c43617928b259785b8bb5872c561345066add4b6ceaeae96f97db1fc9497f53a15f9865f61a9a1a8967c58885adf43ac71f54ff1ffffc80f2b996f788db10c7fac87d8fcd069ed5d3cfc53fc53ad64b5b978b8a8b6f9a25087ec6294feafff35b938e92c5585196348d519c689b66f7253894255121bf4e60de77b1ea5a3d1b89e98e63a97a22e7e3ebf1277855aef6ed345b5b9dae472f1e3d5a2ae87a6eef0a71d9705afcd42b8b16acac88e949e491ff2fd3617cbb3d9f55a16e223ced3b1c02ff2dbba2a778a4f74f2b29038e0eca2541292e09c5e8c26b8a65bfb130faaf93087d47c55f75caecaea537661d4cdb143a0c687fc1e946f2e4425b0cbfba22e6e8b12762928fff3109fb58be178d2dcb88e495fbcb85816f78fce0d2db32ec623f8df760f8986186da476cef9913198957df2189e8f46ff23eade259cebb97722a4df5fabd45cc1e371ade88d62b39e3b974685a9f789df7e2cd44b9bfc0e92e7f4a0d883aa768b35bac8e96daa5dcd97d527d1a390acb13e93aa7f9a542e962671b7350a2f5ca2241f93e1b7cbd1ed454d9bf456e3267db76db75ef2dc15ae76caa56b1cdea706b28afb88e2fde06d45405b416a8454a49b5c2dd6c9d5ff95fc733920c93f53fd67baddffeeca4bb0a7c8a14fe46c3c27265a22f05bef14bbbc6cc9d62fc713250fe669327073c95785e00ef77c38d1de36afeb424ff9e18e47f10439bb1c695ae3532196d5a7345f2effacefc69ba2565c7099f478cf055b5fc0e83979b034353f25a4df7f308d6797a3603d6e1d91c9dbad6a3cf32e94cfbc0d4a23eeff990a6f1c8389e696f240553b4e8dd221456951961f8f30837de65481c454e05b72f069722a212de0e87f0c0411e7eca696c5bd173ea814acbbbec9379c718882a37c6b9fce90dd3cfd9db9cf40bdd90ff67042ec100039971de8fb4795f4ba4001c848ce651a58d5d387f26c1984253de00a07a65d1fc17d8aec4853519a6826489d702379cd03a2833c88b45ec8aa2cdf68a27cccff446dc2fb6a0bdfb25940c6054e86451d519ad84f42284f88e31ddd6a24a487957b344f6f0bb1d429763508bd55896c95d029662d0855a72491615fc52a71fbe39c79f970ca7921545e8897f5962fd4f71a106aaa749b6bd8f54db5e434d7a72e5d9405170a91dad144256f54d2c3467b54e8f5eef7a342d7b98625686bdbefb7ca9f4ec0cc0681110d065b3170cf1ea8d98020255de4659904b13672961f8f68c6733c02279b7e4825ff69c76b00e85f6a9c086b21d408303ff2005d4b43e8e7b4d2a89dfeaf934078f4eca30b368df67c27abfd213affbd7378510fcc97dda7be897a89c8c94647ba5131a26ae09434dc7ac935d2c02e2fb9716cfb1dec96465ff5cdd6004983b3a4390077f34e11a7beeb886812c29f8189eaf7156827fa344db52036fa055f5592272555e9aa90b582db4468e9cef82962bbef5548a7f8a57d3881699019c664c94baef8854be8a4723a6abbbd98887e3f39b3a00e94eb050d7a729549b49808ed1f5d4f42e1f10cd727fc324d58c8038fe50f8a3d2c8b5a138bafdebdfb5afc6810cacb31bde142272fb3de4ee04bb9ec5d5a174578a0fbfdae3cfb02e816ea9de46faa7cc99759534c0e3a5e1d7dfb95bde3eafbaa82b14fa3af8464b6935f7c5dc0232eaa28e585404da15a43d8380583e8f7ae9e5dbc0235b41f6b40f17b033541f075d63e18b48ac94436cc99f5e2f4684ff1bdd22444aff93c9cb30656449f83f88d389d1295aeab5a4d955b088c23bd551aace58b9f7685e4af2a0166b7f10af56aa5093fef6e8a4fb99fcd9dd322fce2f0f532e124e39e9dce199f8de684822f480b5775aaf94056acf11579c7951940fc95f49e2f3d26203c88d610696a5c418427471fecee4dae5117148f4ab0d688a8833ca79905387d0f4e41782e0a51a8222fb30783e34b6a5c4350e8c35bdb8bd4fca2a6a4b07c43ac209047a389745794b95fc763efb6ac161f7b36766aae911ffd17275530408fdd281dd25540a47664ff1420d0320d48d38024c52ae9215447d3741c16b13f98a97e95780391dc3fb8c7e373f44663f454701c76219b03b12c7ee0d069bc5d10c409a9e425cfeb8ea3e7af35eeb6de01e576c033426c4a6ab66432b3a3b0cb323fafaa219998f1f9e4435ad4dfeccaf25bf9570d9e1249a61680faa3c049a6e23bcacdebe69c86c342025c6fc8841566cdc49cf11360759f8cec0019ca0e9cdbd99c401c11e1ea6784ede1fa586ce592316575744408da440cda00335334c935eeb22f40cce17eeb126486ee146e7a033567e16b2492ae2b7650330e8ea7e6c723feb07a979d7a64f652bfd138a4a246ce4f393919150b720287479ff43805d8ed761031bf72619244446f31f18bf0708a263ec9fbfdb7b854b919d15e01589d7c703418bb5580ceb9e1b1b708fadf2bf6834aedeb38fd41650f67e1ad572d38073129ef828e48899d4ef47518f6d6dc88e2e748cdf13cb8d779e7ee237978ec4462cd4776863c9c4ef4bdf29aa24e7eb72d777785a8b3072b997ba7d8c38d4d9dcd298698fb7a998da8e477ba6579ce77bead3699cd2d339a9f51d482b0fbca49b838d1b861a0ec87ed99ae078313dd89dfb0770bbc7cf74ebaa622b95ad7481625cfa3a58d7ad7c449bb0a84e03fe727dcd434ef36841178599e772b6e8a9fa8a854b13aa30414688222e2c6eb852cb6aa92357ac42b437f4ec6e31d064b59253ddba4433a929a25054b72e30f0f8740666a4ed0a1dd8cbb3517205523b899ce2a9c50f0c0648d1c0a5a11ab08e7f4932e47271a8cb3f331fa9d993de28976cd0d9ea8d262c94c5c03bbfcc4b13082a627561d15f4f734da01f71d64a8c6e8c78dbcdff70ecf5ce70f8efe8eb7d04adb7cc9d9fccc192c56095c02119c423fcf62497356ccd47c72a90f66deef279723d42f4d72e68d3ef11edbeec0130d155eb1d00831313be3d44c24cbf514403801af61b0344c5258c66811a93cd19b42dce765d1b26e336fa7df8dd3897eabd8c3a212b592bb056ce5c38986a27e7b95c1b60e0c3a9b87182d4a8226667cce143567195bd249762504817b030dbef2d5ba607babe9a6509b936957f79669e9fa796d6774ae133bd08e0e3ea41b2eef78f270a2b397c690ac39b939d150d988d4cff5a81fffcf74d6ef271deb665ea9660e5584c0538356b5efab37a8e011ced1205c1cc75dc77472ac9b616f8e4b8bf533dcc5b212f54041c3e699500c1b60507c51ed51051ef841dfa9b6fffc3feb34a9c07dc3f7aa7cb9ccb78acbf6c3e78d122ce17c39a268f7873c54b49d304aa6a15d437ecf657ec77b34505d1db5ccd97af2ee364f4614fe9ffe4fd2a360f1f065e5ac5a6fab726952df6df34521eeb2e7f8f9369777853082fa3ff98aa6e5ffdf6ab53215d1a383d1ffbaad9607df92fe6a55d289519d555581578bc6a830d93786df38aef7d536fb535031ea0093a32e0e56e2fe27baf73f17b9745a87d973fc7ca771a53fd24525bd2f8a3fd1cdae54c57ff083b7cdb19d19320d06001ef8237be97003486c2c3da28125ca2d30a3de833d8a31226f18a70428b689006f7c9820a3135fd26c8454aad598b624a2a6c127c673da54581f6a59610c5920097f66f98b51bf6f9cc95e6b502f9874ce659d2f5771a2f94a71198d1827f145b53cc4296f8cd30d48fad742df073c80440c209aa626be62da8de37d24533160d63a2783df904e85d16dc73dea1e4a43c93c1e1089c374a24abf557d09f75fc4f6618debd932eb3a9981bde77bd5185c0301b38029ba60664fa2e58694f6967c0957c4a6ada22fa81215702a733f2af660404f8b39674f9d47a9bcd1f988e660e5f368f8266beea2318e629554fd7ea51f123462265653b84a0dd474642499c801abd33dcdf59f031d0c8a9339a70ffb4c5e15f490e557c5a95b5bbfe9b50d3cb6a5075a9fb5e7794ced061a2b41f546cfa1ecf7cbd61c34e2dbb2e859b20fe9d278faf982ab4f9c0b635baee88e4c96d718545ba36425399d8a5562f83f0b9677ac48c1163093457af04ba117a23a9d0249e2ab589b5d01ebd9c69a5564da946a6854ced9082b9271ab564828f7acf2af94c7429236eff078e41785c0a956ab8b77904f34f6eb8c8efe297ae4c5703ce54009294cc8822e5e06dc788b81da0be8003c4fed4f0fff796a7fd23dbe103cc51ff460bff10795aaccb87ec6a9a6835f3bcd099e46df8d478ec77792ded8cf2ff34d511eb2ef54e28b601a75527f9f467c457c14a37a68d11e55832453cb4ec4fd766384d72d6eaaf8b9d912e8f6870f3996365f4d5480a77102bd71dfe1941b8967e6dcc04fe29ae767ed8bb8f945495d13bc099017531cd72ac2864c4e34f708353205c2b4165ec2d3460abdf109e1223553cfac5213616ad43dbf4e4119b750715ae74a850895ad806b15e36836cfae561363b3f92e2540b978ea7ec7c897268afd67eb116d3954a556276c64fdd0ead40071e3691b9b6ba0713c8dbe239c8e9fb5f9e6916b2b0facbe89a06c6f812a35102193a7fb81e5b23fcf8c62623367e8015986c9f6d3f7f165007335589fcd29806194d97dadd85f3ec31344bc027d6fbc3441e26e1ce7043fcbbc562f17aab8e76c360722f47dd382bae996c2dade83fb448bef82fc3940793bdc4ed09c09bc595d990513a9c73fbb4a84269d157ba5924aaf87243ac77ee5d15741907effc263b16decebcbc6caf839a51efbb5aaf8e0c9c50dc9b41eb51ba29cbab45e9776d3a8351efb8d6bd8ac199f6038866c3607cb70e09dc23265b3f969f24a25851925ac451a60e7a87320a81e1021148a42135422f21d15c07c68195bf27867a3a1dc5ace9c08d80bde71f5d261a4bf68791d22fbd8ea1aacf5f3e731585c50a50d90e2aed3a4c9add5d9dc9ca934409abb0f6c6061ac8f5ca1174e109d63bf64f495932e538633215ce9d2c429a12bb6f0976ead3f6ca8a14570bb57846e75420e9799dee8dfe087f0c01e0c5ab46ea0456b83169de83d7bd8eb6c7ad089277ac71e5090b936a22c23e65c1b99df89de620d00f07f876af0f38793c691b7966e78d8a4067433a41ddeb2d99cbed12b77cb7e54b39563d1ccf1942de8962ed21bd038b5b82fd2291f63338b6d93d4f888c732916c0b861626e0a08b3c482bfba3b63f4afb63677f2ced8f9cb9c85fe0aac9c48a391ea5f18304fe9ad00a1c7c6a45d6cac6ab16a80c34a8ce9a042eb281611ebb1203ba0113bd9fb084d0074bcb4fc135307c7c5949a89854b42659af470d5d5c4c8bf3659058df4d7bbdc1ee7c29a0aab3a52eb53c5f0ad57dabd827614df799b45e72f489721f8713219395f1aed3ef271fd9c7475ced5cd89209a737a017455769a1f8e65d2595a9ddb2d455416d5b1698bfa605036a3fc6a0f62d9e9d55009b3c37c11e4cae0f26ec2921f4cd991a8eccefaaa501e6065f408c00064f5df291dee874ffd860a67fb45c099f17a43a288a590e16db7c04729889d0cce6ecd96dbaa79bf4c06ed303dda421ef8cada24fba0956a4666fedb79b6fcdded00df05090c6651fe91debd6d7301763a1f654b2e7cf9427df90a3a060a2102440f2e56ec1cfec301f58286f60c100dd53d5fe13d6c64ac0081d914935706f03bc3c71d1206982bc09653016630254fa57c3a4ec6c11876e2fcd0c5cc2c255b249c0de78b6a3facf34a98763f24c45544936c23cd5264530ab7ab6843fd3a4c2da21710725caa96ae2e626e3d902f39312abc6183f7a23c5a058e125c903efd654a41b9ed73b091a4a093736498395d72015e9aa128a7d803fc810487654a5372ddaaf495cba5b6a264fd78476b5b6d4759be47383360fda0a36ddc8d3824d27ba9315533191305d0e9e6723db4411030d27ae30f8d7daf5c50d9e15a6206605a63b1070ac6b420b3dfe36cdd7222c83496196eec93cd8f900ae94e392584da6d309d1ab0da1f72c168b85411df610a4e3003e033cf156dbafef9cc5738384db3161918b251396ddb260d540e32fe5a036c7c29343bb693eb49a32594040edfafd24f15957cfc9c0fc7c21f12fc82acdefa1c92334bf1e41c68810b468648c2da7c5802db262c8ac5118242a83c50c1699fd79f59c0663584e51c680c3d44d04e3d6bd0cd982646199215b35cb0cd84a3fdb594e0f59713a251b7a470f5d209186caed06b72b1d9ca4bb00643aebb125b3c3a50bf77352a7876b3ba3e982c13264757a78519ac4a1cdedf793855b14626e7cb2431bb69d31d1be7a4ed73a5155dbc1ce5a855f3d9f042bb59826827569ba5cb3d589caceac17ab13c9ce5673fb7eb63a2be3bd073bccbcb3ac3d3a83da9f66fbdb9ce517a6b5132d3a9bb0bd0c8326867113d7a313adce4c673dc55d70eecea848ea744fa6c9921941560e09fd7e126d6a95d4e9811092c9201b4f182d1ead01bbb9092823c74545b47f636eead4fec8969622d8989b3bb53fb285051c77c46332a82de5717be705cab6c80e161ad886d8c102058d77dc1bbce31ef00ed49abb33a4c6c6ea15de599d4a8399fcdda02b486800cee208a00de5fdfeca3858f5bf2c16b6217481c1cc5ee9ca67a9f51837c194fb827f0abc534203a1be1b956462426456499eeec7344f0f63fd64f9b4e73aed799cf67b9df67b2472a3463f1fce928900386b781bc1e28587c52b0f8bd700dd3700ddb74e45f1865988000a75fe62af48cd36831b0d172d985b4c939c2592adc970a789225ab17ab0a325ab873b9299bcc1960c5cee1072073b13e150f71034265992b3f56039d86183f960470220ea4b6c87cb615806d3cd1afcdd6738b8af079f546c436000156ab462d2e0860c3051afea8115133d56c9bc4c659c49ba7f9ee574fffbaca0877156d1c3f3aca687df67e5090fd1fb961cb7b14d1627042fbe069f2c56496d85497fd6c8078821c0311c3e6140ddf274cfbe5189727811ec1e01b79f7b8557a9f4bf93ce625fe435d7078df536c57209eead5b586ace628c536324362c53581879a25de88a7c223657b0d1a480807605c14e0069ac66c59c96e95e4f99509e1e06f2ea39fe607290d36200aa5da0697c18b00e4c789813b3212d16dc9928b0808a47b8f98a45a8335d3383431a6065a9916d1337a4376c440f6c3bfd26f0b6908de87df7e686d490220fc13a287a8f8b30b8c1d92fdc322c06ab13bd65f7c17e9b63121e87f5d95d3f8b647e166b76c7f096340e462c0aebc0aef54b71c3b6fdbeb9ca978cdd4e03c8b29e2eae9e0fc6d90270eb9a8de88e6dec25a9415db046ff22926d663586906c109b3ab9b0c93e291c696ec76699a27a5c251bd1a58603125174e7a6a3bc5e4e068312c4de5b3c3a6ff52b951c34700fe7df2980303d7fcf172ab90724eacb4abe5132794b17b09774a17f20f84725a631844776b1ce581cebcce67dbe453fb6762cb573a3ba4ff7df95bb3a794bc7842e86e6b88df54ffc8c16f2749754b3724e4e6e419198b923277d07dc1170c4945e699e1e861a05d4b7b3c9c26d076ab7748ca6f93db8acac82c0d3c06520c432f7a745004760b48ec16854fd3138da90aec5c7a329153c0b389f44e7e56ce4dca20620a398e5735a9f039d0d82de82482f2d6b937f8d2bde3a46e141558d83ea8f74e489d8989a2a8b8ae85d3640b50254a40654a4b4941cb8a83708df92a908a5998814825a7e97ab75a2376753dd6b2caa1a2c69ed9ffda2df47bd438be7812d8747baaa4139840a22fd69972f65ae8a05b8e3c63c5a53f877b0242131583848868ab29feb82d683dd7079be93c18e9a8100cae209d3cf0fdfd4e96a19dbb57d37866f91aecf8e1e27dfdd3e35ab2dd24559d5dced853e3949c30df58b51bf6f4f4d722e8c700be35601c6adefffe89281c2261019164d377c0e150b2694134c48f6b0cf14309e557a38d9506ef96d9db8b6aed3d1684ca6a3cca5c0f10c397dc763079b1012e3cf26db50a7450cc2492cfd325aa1fd3e9a50d5f93d87586ca8eff2b2dcae739653b74bfed682a10a38b19708da1cd714f552ab7b2e65b104869c5364d1373c566d21be6de43e43b3412ab08e9b89866f6c92b143c96b55c9cff7c76dc904946bd7b958966850d225046b0b4d3d43311456475f10d9c4fb99c098cd872d9f0a2b0f63b37996f82f1148676cf4af970a06f56525df564b30034b356da92f884c25bfe7b206535ad3864d4a08a18962971fd25ccafcf0e79f767959fbae68345082a1bc1b13312513694fc7f1280d016bca47f2301639f4f6de812e47a0a48f9149c0fefe44e8f78afda8e807c5be56930f5e499acb9a7d8f964c3fb7b59dbd36d9df5412f856f5cae5f333d6f00f50a4f9d643fcb355d20307f1b03dc763efe03e0cfbd1fa559cf17914157cc6e7c723fc415fb0f026d6f02656505abf8605fb5925151aa705fd4c7b8b5cf1bb4a1e7ace973ca1f90ba67c2ffd3e7ca04dc389d04b856d4263c72336daefe35f0d92826ca7716f12e9ec5b3854915e7d52105acd49d62c5b1946ca87f40697cdadd6e91498a97ff19bed8179926141c11c05ec247ba86f8feb05cbfc3795e4b42019e60419b6fbfccc3c614d082d60b28f4eeaaf91edbdbdea8f9a006cacf566a0ad4f15fb42398315fa7266ed6dd05e912a887369a2d5b83c9ba0284fd1c618cd12becaeff9d7af6b00c8b7bba25c7e2bffeacd2430dd2866fa1838ca26d541ae57c8498249ff7bd3a74927d310cd8de469b2ac1e24530331189c3ead8b92271fd25521962883e534272f987795267d37bf0b14872c6ea46f9c473502b5cbbfc4faa26e40a133627d4cf490667c3e1533351fca999a673a75a8d34e6dff9d3e62db891af751b3d09750e02aa8b7288bc5c79ec6e2aca723fb0165e7d4449da80484f9e834a3886c269c3f8bd73b898ec1fe301af900cf58bfed6d445795bcde56c2f8e709be5eb69ab4d1ee7e52ac533a19dbfaa07db44e0bc278fea4bc1e2ef5964d67b993930e17942c01df390f275460374eea235332a7831fa8e3c38b69ed0d9ce101a4fafbd2bc5978a55c3ef44af92951c4784378add2d80a15a79d33f4c902b6aeb4d068a8f3b359e117207313a18ffe8774572c01b35ca83dd31486710c90634c995571c71415d67d2db5a6f7aca022b46567c5b4ba2a70b785bff22e8892486f6e77ab15977cf93d78d16097637cadc169eb6c4e8de730267c309b924b26e84fe07004b49deb991ef49c09daed4e4ad09e5ef3b62b2987d51898a44b41149c082b8ab219d72fbaecf7f369222210e3910042327d90aa92a75cca4a26bd2ff3a2e4cb0b555da04f097492975d2c72f16feac2ecd7c50237ec02bcf3a935bfb82beeb9b82814dff4c889762b187a34de1eb6772a45fbd184d31ee2cf5f8b42814587e4aa10392ab4707f8cd225bf2f16fcbb62cf4bd83880be8540ab6404bab6a8bf90fd3e37fe5800efe1b01cefabaa7c5f6c1342a371008e6e86c13b2c6ddddb8a072d850220f5305796d6aada76d4f84f5d63c14b071da24a38bc47e28a06f1bc94bd1d3913dd9e9054eca7018e75e145f2230a3f576555c9046cf3dfe6fb62b3db003d9648028a91ddc5f3697195676125f4fe09b5342196186aeb92b1025c7043f6256395c64f65ecf68015d412f24eb8c02a2a8d430a5366d0dbee7b2ed196c2d4f8a8e8bbde3e2297dc998f188ab0b0b460759af8ed57d4397b9ad5737d512af13d47f7f7fe77a23465ab52bdcf40cb9adbf4b0b4e05ea48f3c06274dd874201267485ebbed1af34144c7780d329f13c7520344b6e97642230860a85c2cd9bf2b57ca865c42af56245012383ca9152c650330b956c02c4b171250c1a084e4443b10a447b434bdd270346763286d60e7477ea813413ea3f63353730daaf989d0871399988089b53e89ccb91f4e6c32ae0e5a4c6ff26d97a6d983b55fe6748951a71cd14097ed805527a0f86cf3875fd1bc0d6ab56c46b53a1120dcb06dfd662251621bb0b121971d517269511b3c5c632e41cbdeebf2c99d09d9763f1b86bf2f984c8b25ad344d2591a65229744a26bfd349b67572c9d8eff4e171fd2140086c717d0ecd67c59c5d8e8c669586601027f9a2400740b302692aa6e10a04812ae6c43ddc92d68010706015194fba8c7b6f35250b4892c0583ba9d0db5369acd8263513fcd345993c14cbacc030639533619774a13479ad3bc187529f3331abe195af4f355240ef8bc5c7da46d88438ff76f591ad83c14fc36b98d3c671e6c7a33172d728f5091c3ce199d2c8049825c7c6d2f8b8342ede2b8797744756b4fc14b8660223e55b241039e810be300fc317f2c1c0aa9fe7333ea715132de349426b56180a5984341730ee9b24730d4064c96b25ab43a39dced609c5baaca6550a7c4556e0dfe371442b342b639c56016246c20f03c10dad44a282a90fef9c90f000fd279f61b760e9e7c3de12b596d5a70b7d6cfe0c48d5bff5fe6d802507ffd6bb28ea0b51a98b1c31ab0b30abfb3732a922a4118e9ca0de7d4234f4930bbc017883e74a9d41b71ca11c6d6814731e607c636145a87d9c5aa778c4f8e0a9630c15deaa68308961097652b99f8f510c86ccfd7eaf02681f990f269cf9b796d332fff9903996c66c3c3f11fa577011ff4ea581cb089d029e2cfc832f2dde89f7a347c883f4443ba0d11893dd0828647aee3e996076a86f2ee3950eb5cfd560406473a555b4d251177e3527f6989a0baecf86f3ca65910cfd0cb41253bb58fd7e177c41c7b0667775abd88d19600d1d756d229886040641345a57c0a3edb252694925d4c2fe8b4a7a3ff768efa658ee7bd06783bc9a4629e01f33dc733723caf31acda2f0071e069eea3fa74c1adf8810088f86ab77e6a6348e87234bb0524fbf571b87ef21baa28f384a17e0a771a14679481b7aedcf6adff65571e3026768c4dd7f25412b91e5ad4df4514312821733a8d0e1f0058399e83587a0561d740fc039b769ed7cbb0eee02db4392c56e391beb082b6596d2d6f037ce4607c1c705c5085dd7c706cb851251f7092793666f30de6667a7c6b8cff9716a3f60823d6cb8ca331b0d8f9f9a87a56392a65b3a13e0a44885b7fcc6d2e0f4b191872d00d8d5c7f9cca827bf1a5c4eacd78316e8a052a375c17d03e78bf60bbd25ea06271d9b6e17036f748f5834211c7d541c266e4bd30fce5c2211487ebdaa365b8d0351f41103d6431ae259cf01fad9fc8fe441ec36ef14dfd699bc1aff29fdd39f9a3042e320065ab4d63374338e6552be5af185aa67ca24cc9102df49c985d21dd19cc92b95da6e271ca46089487242732ac98956c25181dfc9ea4ef2bacef484ec4758c04e322b4e64f29f1ab10b1806b402a7dc2809c0b83f09a145d29cf9c83aea3e11ef40fbd414ad76beb9d270343adc6a10f0433786f740e6c26a35127a69c9fa6b363a1e2d417fcd46a4df3ff7e2be96f9a79ede490301f4abe9e01a1be9c7d2895c34ce9bfe7ccd4660bc055f30751904be3031fa75ba7bb938099a79acae4c6f40c889af9c9e52fb2df3033e9da89f7fb49c169499e83e6d58d619ee078a15b519b609359a286204f08f220bd1464c22842bca3a511fcc348c627ae634c4518a9e380fdeef5f9e9b8b3e16e82ba2734a6198798b200006dfa33d00b880258493e888c87ad65b4ae7cc93cb915136683f627e2dba005bc76bd63ecd895550783c86ac5dc4e178225eb0d1643814c449d2edf3a666624e3ff7c645e733a8dd09ddf031e3f6314312c9004a3025ccd4531e38d3273e6f3c3c9770c7d4e38f9bafad8f677001cf3dcbe664ebc7d8fccc5434e8c75f65d37a346807443b07daaa811ad80629374a005dbed77205fa00758af17bb14d1ed5ae9f521d442da67614a776746a36f6f797fba2d30f9c6d6c6683e1ce9fd660a8e170c6c1aa6b5a59ebe6b6dfc60b3995b64301218ea9bffe4f5983a5bd05e7071ddca9736727025f333e9fa8f4465f82e33131bfc085a3c584206586d06ce94cb7c5f198b4731946c7c0084ab9cab3d9dc854a86447f2ff01bc3e0e0efbddeb6af5f9b9819e107c0bf4c794e86c53c091530eb18a0bc6a3af88cf1ea9161ef9c274d1f7f8af860e0026d9d68b3c89311697b4c6eabaae479704a548aab32bdb4bfb2cbce8d33b97a0504979aa20325db73c0df05fa43555c8b521af6589bcb746e26c5b27301352a0a0a48fa4480c60f1e8df9440273330489d857e25cf7fbc27e248ff2e5ac74d368751b0104eeaf789c683ac35083518a742722195a43b825087dadd2d82d70021257e205ae4674ba507bf8190254417ba6f39e9b7b5b2a7aa2aafa22aff99ffef0f526f22fd69092e3c854a527f2d7efdf04ee209c58cc47c0a481a4ef0ccdeff430807ef8a092871bc3cba5f8e36b334e9d00d71b1969f4c6b1ea83b091a8dc710258efd7f4318f14a5f1945c3310eb0425790ada105f81125c975b899367ed399541e82f603148f2f05ab5c304418c7142316e26f293bbe4a6496340468a4a4eb4bbd120580ab531309820271a9eb027adc644f5fb8973ecead39da4aac9bf7cad3ac31b712a50fbc7f12c4031041d273d669523a6bd9aab5ed6c3567b70e9d0e8dcb97dcb2136694e12c9f82c9f9fc1d865333cbd070ab36ad0f3e3e9cd1349263d5318fc0075b7c83b62de078df66e7a836ad03335a2f68951b13187ea3181b339cc8f91f6b0d416ef556d1d09086cdbe4e3812cc74a91020d4f0d8e0408e6447a03aa3d53d1c8cfe4b19914616e066d0b86e534cb9bc370a150a736824a92934c6a12c6b23fc41d20884ece6b8a79668a679880d651dad22542668b465308ed589ef1b9e5a1ea9728bf062a36e08b0406e3356123fdd127e9c17a3558f75b3caafd9aa3f66b1e716d646a94b08025000b6412e88ca718418cda0ee61a62b85071977630fdbed1f87229ba31a39c05cc6efce9dc0e35db0585753767cf51489bb02009cbd9095d8269661ed7c5bc336de471fd11a11deabe4edb3750f6a58d8d3265402f377c2cd90306e6fa0fc57e0a746fff53811026963cf5deaf8bfa62c3d5ba5a5ac153b1d9e22ef26576c10bb5e6f242541739fa28be58e4e2e2965facaa9d585e54f22217178558189ed48546bdeff0685f7ccaeb8badacee8b255fa6bd4071f11fa05118225fa87476fa49a55e62c27e527a5e7a4be1e5fb60e4826fb9bce3ec0b453fa08013bfffa6bf8d26dc3f224db8552537b9aab3ff54749bcb9aeb1f98a67fe5cba5feb32c562bfd17a0cab7f0938b25feb8414da7ce100c7af1ffa19cba3c6bb874e8180f27b83d7f57ece106445cff5027ca053303d5a44bf6001ad49dc49a77bfc9c99467bdde809f28aa009ca1c12c7febc5efa762f67c3e14b3f13cd3ff0cc56c349f388306495e8cfb7d7ec958a0cd033c3dc9f8304ab350f3435a5677e35112b44168c17a3d6b70c149b14a9c9e902b2620e44ff0291c97634ec8f5980fff6079b6ad2e3444afc32156241c5c4e26358b7bdc1422a9e9f311a110945ae3737fde6f2bc1852af232a9915d6aa4b6c3f1b3b8b5b2a3b5326eedcb62cf974969d8ae05eb8d9c1fe2e244cbea2e97855a6f8ac5b9302457d0f2b6fa948c1baa5738794e3c036c849ae8a35e36c6583dcff1cf1ff18fce56c7a302affd7651a7cd3993acd73b9d4e5409e60e1415f811b074a9146de7e5b94b7b89a84587a67f0b63c2a049a0e890589696d3382b3486960fc7048cb9eeb802ddac2f2ba9cb2705415f16703721071d5a70b1842fc03f12440cf492e453b761d5b0a6e5b02219acca3469373e26c38a5c3dcf926ad8d1f3704cc8d5739a5403565caba9cc86925cd7c3311ffee978ac5e9403fdcb0589b8a83c8cab9b8af2b1e1305dd135ddd02dbda107b74ff49ecde6f44eff736b19ac689f70002412e2d93131cb8dbf6b5ae2c726ffb19253857f33a5d7b39294a3ade08e95297ad8a54b2667bb39fc733c3e00a5f270a2770b60b92c5809865ba8ac47576ccd465488a426c7a3d27fa07bfca50756b011ad9823230bb02b2cc886d5b362ae2b6eb0a2fe93ac40d73f70f1439748222dd33bbd161b42d703b63017e873a56b42d76c31b9375eb308bdc35f6b426ff1d7e2ea7918e034d09e42edbe7b305a18591dbf3bf3895107b35bfc745a14317ff4bc7f458161c3168063e1ba5c3dd7a7337fa12cd7773411d739788276a40bb80a9733319f4fa40dec32a23986174c243d10ba65f7cef7b13ddc86dc036cf09e107ac3ee1e2d7347087d804086d9db6444a84626b2b7c9415fbb4f85a6bfb3b7c996d07571b7c68f1b12f8282d63ab0234f95a7cac356829161fdfe6f2e31be362de57da459c725f194ddfa789621f1c867c03aff3971520ed540439aa32c669094f4da87d8d2dfbd33ab05adb24ec7c196bfab9e7b8b3cb8795f7b42b05f842723e7679f041e8ca3ac775c5c07097bb9fa608d08fbe0c98e572ff9b503f7e2c16dc3e1e7c9013a10f0bf02cfb2124c1abf29e27336c1dad6779f0db455d099cf542ce9c8486338b80ae83f5e2083dec6bf3005f99a2085b38c2186b5936b5557422c954705c564d5f9416a09df18bee82c1250a9ca313e30e5163d3c685b823c87c2feb735096499108fd40effc132345a2d7c838930c7e2d9ddb7928bbe0459928508d4f144b722687825c8548c195021ca49cd4d7a309590e06162141dbca72b07ca650de18e85497744426c5f56e520c06a4625c83c98231564f93ca4c9615f44c632433e0a242d0ef6c64508196ba58829723da5003b550ed724cef64b17c037e5fc3f28b8e502063d2a3ce143b1b1bb718c06fbe1cc1d7b7e295158fda248007faa30110c623fa3397d59ba03dfbdd1586e4f91f49cf15c04e5fe7f53a9bcd3b52bfc5c959d8fd1737c3cbb171bd6cebdeb6ea9c28ac1ebab9f42b3246af96685e9ff57ad4c09cec4155dbec0fd4c4baff83469f0a139ce3ae102fd53fb8ac74f54d21beaf9431eca19b7cefbefe38a29b42535eba986d76448df1a74e0cf625dfa9eaddc7621bfefeced58131bad95b9a3ae322f57404626935c54bfc7032b7f8c1856bd888c0edb35d5c74bc39a2773ef4498bd5fa0061ea818433d378c3574abfa17a8dc2f4f7d556274b34ac0e32bed7293acbac6798871e59e00da6166d3c2bbc854d40c92f6ce5394579b4d10565bd4efebf315a4a8c88e3ab4a163f5742696c79ca4df4933ab3f142345ec4034ba7136da9f2c6b1ef423dc23027608844e309cb531025cdbbd422cfc753037fb0ee0dd5e3a24bb64beb5cd3eae037b2582565d44f4268a981157a60e0f8f195b1be802f09b1cc7cfc403807767b71f7dd8e8e4e5440bc64e81cf956651a7ddce0552b7ee63e6993e35ac33d66235aa66525ee788dbb8b430b52c18f4bbe5873d64e028e5799de58c0f7b5e29b46df5112aec53bae5e171b2e6aa38f5da6752b05b5e15ac95ef8fda6d8140a13975c71b9294433dd89ba8334e3256057944b432cd18a95a8f26912802f975c263a1d1d06f8cc8a1c8ffabf4beb288af4fb66c9016baf309edc88e6cc24db8758025a2a4965ac04d067af29349373033b2ec727f710bb9dad68cd96d79527eb4ad052bce712afeefb0aaf4c524f635cda4a204d983bfb245f29dac147cf074c121b376e1611e9731ffbf794547449b20a0e5ea82a69d7f6555e2e7665aee0aa5ac80cf98bb339b0cce72b1aefe08582af95f98b1ebfcd07aed4fbeab5cc3fb19dc580fbfd64975ad87e3cf6f44f70f998d6d54e2e389996e98dcd4f2a9255b4eef793f30b1c774488bb6f851d5078d10ba16fde89fa75fa8c74318226d667c14434a165028c64be52207644f78f1924aa6a0b690821a86497e03124a0ed193839b0b43dd866de988e20a50623ce1b3c174c0db9096af474c01a14f770b5e3e63f1d4847d57c9bf5b9d622e1626bed8c511b77801850d5956223ca71316ddc65bda83e14b303d56039be85e2b8ce8c076ac7c17b0d45fc3b1d7ec2eb1c26e093cc4666b97ff14ab56b3517df43c2a7afbcafe35beb00b751e4aa5fd64fa34a73d01ef63e7dd0be4ed09a6f270accd5d17cacd36b511901ac5a0b30a7e108e2b944bd533e2719b846d640e2a9954cf939391ecd4f14679b801d8b8f061ebd021055474a909f5b9cceea7e9dbaa0dee386913840a3f908d3f43fc1c88ea7bb1aa03b8c496375767cd42881984822bf725ee76b370f53e70bf3f4a5ebac1e2cdde75a77003ff0210ca0bf64decc74671107ba6475074f77c17669400069047fa5933c1504ccbbcb3abd296aab3fa431969d0f68bf78c156c7e3f29a8d8fc7cb162e6e5075db1c5b6409382e4055ca370ea14c083812e7b5f5ee24341c44ee96f560ec13907ea4d2f30b6a0f802df1603c0513aa067f7a91681c0aab4d7dd9ab6526af92e5700cde7972061f892b98fe311b838ca4f6f07a588aa44c1d714e863b0b74873b9de3a95467755dff2455a29ea9817826085db30fa9aa5ef33bc979eda5142832a9ed2f9d94345760f0277295533da48ed2c555a5b3863e4b5c5584e80e1d5b63415df1155debcce6feaced0dfad5c7fb7cede60dfab2504fbf2f5f16cad75f15676c7e40edc4a04ad63adc718e4768688dbeb56560999c3369ae49c164b08310e9c36d350a36827b40cbd0b9b8377d05bfddf13dd0d4db6eaa5ad84256835202269722a9c86027928210ba9b6296c118c23ce7f22cc223728fa71a67b34bb600b385851e77e3b64168196030435c9932af154495c13b08f164ccd9a3372cfdc3b325b21a43bee781e5f6e8c3f4b0d37b06a2c4f858d13b38f4dfe7cb221775d2c825f4d630f3aa3ab923f4adb93685d05f6fd8db67c651f4e0f659b2b5d020b99f6ecd45cd46840c92fbe928bb2113b738eea887abe4aed29bc1c14497a19fe8be439235224344e5e80fcca0721d52a70e49d9704c26f7d3e4232ba7b7cf5666e46f9fadec60df3e4b5676123691d04fac9cbe7d96d8303bc3b5cdc96e9fad5d233e35f9c856d6093afdc4d6ce677e036b74773ff938dc9367363c99c55c877b424764f0fb2632e9ab7d1afed051ed07ace685b1ef599e22bb6c3acaec7e1d0637137bbae3edb0a19bb1dc7b12e3b62bef9bbf89d3ae5dd6e9c48df6103af9d4a77a17a2e496ee102ef09a6189c0b6069fd220e20dd71580b1470e2e6880c1fbd6ddf364db53d536f832def3ad0a9019ec5912c3540315fc70bc7e4ba20da6712942a36174547a5f6de3326115196f7e7c289ae5c28a867669d73441145bcb61df99273e02b6ac7f034200fb19a4d202e6c9e38eb168517f69a38a7f4e01d9851f079e272c0f1a2d84987fb14a84fe6145cedfe4df804f959e8060b4e7a3a862b05ad2ef5f16f5978528146fb702da1a1dec4fe8d6496878ba27e1f8a3c18213d99375d01ed4393c5ae74002ddf14ed6c6b9186778c641546ed07b7ece75c68589ef0ca1e61e233712024e0c3a392c9c1c8fa6279a3f82db27849e1175f19930027ca66662eecdef68fca23eaa05eb4ab9eae07e25e4a72a566bc808be2744a0018cdc401a3e3394b758a7415ac0775511464da81e340851db2735d8a388489d268a0dba0e01e804893379e33909717345c1b6d4c106fdad09591b714d30dedd906e85d39c71421f3685c824dde4fb2c47c5af0cb4be32713276645e3a7446e73f98bb375db870a75ea5a8a5da9bf506e6f7a0472ff40717cb416fdecbba070910208a9266b90201b2804beed3e1fbcb4a427e4779bdd7e72662cf86a1826cfc8a90434c251b5fb90517c3444d47d998d0b1bfbad7a3e391bf10c3f154ecca32b353b30378cd17c5262f13fe4c0e12359557cf359675a2ed225d8a6f38a2881588e6a643eb5b36e0220ef8334c32d1bac00608db762bd4e5fd6ed86c885c85ed4cce8f653a1eaa4c6108cfdc249e83f8cd4d74368fbaa60d05ee9a6a5cade839da14c29ac46ff27d34bc4028391d65fc7ad4efabebd15465fc85fef96234e59a7c71ece5f341243bd829b462e1ba80fb964dbe0770028cb2e3b1baf267e81dd8040cc6b48472a10ac113cc4b79d33f069f29a3f5e4bc1aa9c07565c249369b03a7c20c6fc9cad9684e17ac9ced8663f0c7b27b51930efd9ed895fc48cf7336b29a0b5e3d406838329ac86b37363918909cf1999c53c918aba6496ea5fa125a190c8a6762ee04f9b911e4279c96747755130a2a1360617d2ea49613ef752f1a0fbcddcbebe73ece3e8e5e0358aad878a2e02152fab1d72b39e433351ccf2f1913be8a17a77042772c519e12b9929107a40b0713761a16a09469446b96e4ec43bad19937ab7ca1343ec193323468adaeeb493518e8812405cb67d59cbcd8d9668b4957fba7a4a49c8e684de8eec5082548784a76c3b13b20a0172269395373fdcf60ec054439dbbd184f93c57049ae92dd704c8cc51dd6689ab4e7643aca96c39c2e892db2e82a64973e5b0c72b393567b0cabd944eaeec353b8965445442e1468d0b9c27b247704af22eeb174e99af4d5e9b9b73a8e88f782f1b4a165002a712c9fe6d1a33f2820d0864e6eb0928a6c1441a026dfee9978513d93d3ea4a64f595ccea67f2ba7a26a6f595c8aa2b79a29e1172862b19c8f1ed3c9cdb47645440dc2190a25d3296dbe37c9907cea9cef8deb17670e0e1a065e0086ad0e082a0ed5c2a35169a8c5943c0e351a48766a245b62fed225d8e01d5dd6c778aff2514503f2d9c6fa8424aef1137bc63f766796ed9bde345bd65b701cbe90dbbf56ca58fec6ddad09ca19fd87d63ebe89edd478245fa03dbdb6097c9c7e9381b11fa9e9522794be86bf0f4c3dea65e67689a8be4ad0fed40477444b211fd96bdbb7a4ebf631fd29bff9bbdb7ef6edb46f745bf8acdbb370f6041b4e4246d8732a29526e94c4ee326d36476275b4bc71b16218b0d056a40c8b66ae9bbdf85072f0429ca76bb67df75d79af34762110440bce379fd3dacc8af85b1ed7ddb0563fc115d134e3ee11d4ca4e3b6de6b5af22dba710c20a9a8fbddff4cd654f53f90197d8b401f867b1f206c95cd9b067c9aaf0758d719d874afc8024adaecfd0fa4a2aaf781ac2964eb7d0e42f6f9f296872da9fdd9ff4c0a684506750137ddfb40e64efa0324eb5b1b4e05938c5af1d01cb29b2cfd0ffafae87d200535f97a9f81b51889f32fc04f487a371106835b0864c371e33816e7773e8c001294d29ba461e213c75776ee29a55fc768492f92869d16590529c6acf03248a98db0c02261d3f9ca58286db7039ca2256dad03418698ac4ceacc0400217b7668183e7ab5ffb1b64197fe08a9ed08192d05ba212eaef2762bc85790c9e754af26469698dc8e4b5ad08cce699e56744d67744173f2c69a40a8bb615a12b519a6155177676941d4e62c5d93bb619a91cd309d91bbb3744e3667e98218b9f0d21ad3ad42dbb3cb7dd3b3cd2e30e87f63ce7a632c47bf9037b66740f75145ded4c7c47b6fb1f288dea63e24ccc1b0a0737f1c2ce9c2de2e2bbaa88f824bbab4d236b2a1f3f6097043e7cd13e09ace045a627245974e2e432ef411b0083419e43ded8717d8bc7d7bf938dc6e4bafc628a773b7892ffa57a4a4ef6d004d1fd8b3b1796d09bd272f7a36bb89b012e6775b7535468cceedee4497e3417a81e12397fe23a630c4a09b9b0d67f3f56c3e57bb89d265ddab6fda1789a448d09b099f626badaf3727de6e5145e77b325fe15729c73d1b0dd9ac154d7c1500e3fb6b29c7d7d6c8ffda9ae986c2f38c2afd85b1b33d4f8764a37b5b111bbcd3741fbd1f0fd3e405ee67f8649da2f7e3817e3a59e314e590170de1d5e91926360cba8b3b4aa453dabcb791bf25d83aeb9dc1ef945ddc33e22321a565802ff4d56278e89be60938c6f53202182777c377d8ba8188634d6d445392b52e941915adbb48ecdf4573aa5a666206f7a1693906e86bfb17367844d54e11f3b65384a47ad20180d4c87c19adec8127e398c5312a5cec962288802449d18895c48c25da7b306da816a658fd8caae0487435d5870eadf64e4c63bb148642f266bc50b90d8c5425ea6e48aa446d86ae5a9b7a06a967d8150d8c829b1540f95671280d850b1fdc8714417c173def3333dfb5b3cc8cdcd0d614cec303b43fd497ca359c21fe141da93d339b05cd208234dcb71bdcdf9c9e91a54d33c2fb1bdcbb393d232b7a49af718a56f6a5260d6cfe4b9b64ad996c81055dd2ebe64cceda33a93b6016c0a03d097ed41664158cd7925c8603b5dbd9ddf4900904c8745b465b8d6db477675840dccccb18dd56683c430ce1f68d84708d70296956f3ec86d9bccfe7a8a428a7d9444d31782a90b55bf56b83455530c5519edc913cd9e844386e748af417c6da783595cea7691dc41a2bed90ae0f845b5b07e1daf2fa37082f9c439549b7476feded24c064b2aa45b9c687675d47518ba25e35115332200526458f96c1d16c029606992bc8365ad78bddcf672b1ae89ee8574f8f0814cd928a40bd6c00da1a736cc00aa4a60c9fe01ea269e84e07198949d1e993236b9f9cb51e21dfebd3338826eb098c191d9805d9522e304bf5f6b8573ee6cd10db8e0aefaffb85fd99721348ba57e8bf35ecee9cfaab3e1b313a1fdbba6dc6d4a95d754d7a271b07ce558fd7eac1199d8ffbc90be306faf15d5affdc29b76055b06019c9c1f9df2cd619b641abcc3af31195d58145a9c2054c8c3b0faddcf256f59ab184bd714b806bcb0068b8f5b38fdd6718fdc0ba208e8d08c15fc3c88b4eeb105e618ad57900fc9681de7b1228bb350a8b63fb23f90d5c00a8aaef74fdce3fc0fbda3dacd964714ca98c63e372062004d0b4f1e4feb754eec582e375e73af050080f7ada8597b223f7bfa5e250ad66383acb4dd3c981923aa5bb88d1325c30355be4e2da76f900e85e4d1eb5ac407c5c1663a1f4089a9c5e4e8a4bd4807f3155a063804eb098e920f01063190a37923c4b6528d848f20cef30deedf068296a1f773358b491a453c0366225e85290cb7d57e38da02be1fd0aba8c38f7599e7a546aef0f8449803eef34755482ac3cd77fd91d3112cada417ae4f946064a05e15d2919c62fe9208e514979c05ee6ad6cb9cb56e96ce0830b4c36ece925bb330f957943c5a49c9a742a26d5b461fed92d166cf44f79e13f54ebd435ee33a1ade3c060c408d838b53b78ca4db82fa488e80dbbf44d5da080b5f8ad060f79107cf2d2a9a54095f62e43b896878d3b345f2d8c2ac0e2648a69262add1b86099f3e68babe7732d5da2d6e8d42578d55ebab326021a0026dee36430835cdd18fdb2926ca857358375c3cf793d54760040851662e411dfd3313d7bc5665fa45592bd89a3ab2b6aab5235e7860187c29005cf3522001cdd754927784aa475ad89156534c2e0568b991a465871f54ca357156abf6e5765babf9e338af7e623f2165ad1fcbe6c2e57b680248426848da1f1e534d1d32bfa338c6e33c55c45508de9806cbbf43a78854bf0c471c9f96e1f03647f0214da859184d8d66adfce8566c5a25de844f09ef35b6a6f96e5333bbffe1c0dd33d03f4229af1f6e692f11c756c31974b2a931f1969ca01f1f38b4fd40a5db1fe2a7292c0dcdb5db617223e8fd7e1093d14624979694ace88d8093fe5a9ff1a084beda3fed2f1aa7fd617b176b5e63c8a1c0ba65dce36963f736aa301b58394c4d63250576a37a9c3adcf30e1c186631e4730849eed5a9350274955f83f1590efac0fa99dde191381fc4b13c1f8ce1990e52f15227e8ff4c113ac03b03a312180c2c7311ec279554ebeb6b5e299e5dc0ed15e664770772b2bb51b3c6b1f91efc4e0f54aeaffb7551c03d111609f3a4263134bbcb0569e6c1c125098db4fd87dfdd1f67778d8f0745c23ca9490cccc1f445decc833161e67286a6bd34d5e993c85609c9bda1ed08a4f587d878bdbbaf5b33b9bb5e8f34a67dbb856cfd3ef64ea940981ca24b5a24080ca6e22b400b90663c6a7db9bf50c73cf442b7d7faa96860dcb823e654e0de30453ef6b161c97dc3801292dbed70689cd979e00b4ff449ca6bc972676f9c7518988e251f3f7c7af7f9dd7fbcbd7cf7d30fef7e7af7f98bdb583e3c2f2b5e2ff406abd26bf12849b3bfd1e0620e47163a70efc62915f5e49f1181895ecdb0a6c186070694ac249fe595c15ef3bf891bf774effad10cd61dcf3eb989a9e708ef00b5c690511dd490139cd0c914ccb8fddc16b4da6e87204b714def0f41a4a29b3a33c9a003aa1bb8a0b623d476431f9df98cffb45e22b4ec2ff0e9fab4c027c0dfafce87bc3f7c1ec757026518fecc9c7271b220cbe9c8c10ec01a5a9eae1a8b6771bac2f8e53a8e51f891fc64653f8149b5dd5e0934c7633be01697e8177dc4c325f4b160335ea115c6296ae69963b20abebd3a11f854786574dd809395b3def26d3c59816fe3b1edd52f092b9665a57e59940547d9e98aac4e87fc9981a3ca3039866eb7f3cdc27c8ccec0d502b1bec4a79ad777992dd05a4e829b37c7b6e4b89198d6adcc7d476c0c6de89deb88496326cd7ad1425fc632cd8c684caf9b4b3a1c5d022ae4a5f3b50d8a23d9bb3c5961336cee4ca82b9be1314b6798943bd8c12367adbcbf0391b1a4bd03138c3bc4dc19f70b6c7f66640740b48e11aba34f136eccd4ec22e5091776e182e5b27f978bfa1dbbfb5d7e5923bba75e55e65ca9dc26b31c896e43434fe9df3bca708049e3eaeffab623e11f716ead19c8c01852dacdc8cc667c984b507a289b0c461cd7910990ec536e57e03e893f24437c7a4658cf308d21c720f53317997962fa29e016585f6a6aec7d831a33701f1693e2002284418adbed6aa8aeaf5d56468138a7a2dda065136162b9f9c0562a8efd6fa197caecebd832c86914119b344d7e2d7381a2246ad94beaeb7722a7fa9e9ac829f42b9d4c89e0d7e964bac344a7ee9022a5a98767002e40c1141b248f8203c45518eddba06765809e9553deb0d7941336c596bbc861856fb7fe89dde1edd670a313e610a5b75b544cd894eaffb6db0159eb87b57d2813c90b8096fc58e6425563c83a1c0c52a85c331250eff960ac8bf42824a785fbad77919f93db0e5b341176cc189fe5e0b1cf5a1d1313e93bc61a1d63b663ca624e051deba4ec4c69d2497899ba0c057b27e8c5ef15dd04d6db44b37d6eb995947531a8a4a22c39242e03bfa9dcaf8b35bddf8177626d0e073da1870819d319f7faa7b77f7ed57c1dc46eb37644a3e3228e39ac2c8e0b1aa21755a0f285b638aba391cb296839f159606718b69b14e3af0231b286494f6ff56ffdcbc137af9b606352d30e65e5a25372bdf4b199ad7a0ae19198f35e82c57b6316e19198db419ae09cccde10de41c0cc3fb80cd48b690c7fd281adb0999ddd35b2b33bc8ceeed2216149371b86f02354282c98870ccb5af4b251223c1f00e440a72e639f3ab7ee8f7525561bd000e2c20f10bc417b3b9ab8dd06bcb7bf6c1f95baedc528f17a1ed442b4e914993d28353a6891ec252adda6e9fdb684c25948b7852d87851e8d6efd3151c7ef13e77852e30fcb75b0be6dbf08fa5e8cee4251c71723eaf8dc0193f94638f357c0f0249f7eff5d5d03878617f68736ae5de0d013c7fc251d8c79aae060fef80764eab54ad81cce152dfde15c38e9211857370fe86c4f5a583779164c7b36e68152a14cf22ce581524127ecca878febf2e1e31a4aff5402d37eb09291d11656eed668c4e89ce3fae45e7bc31e63a9ac68d111feade8b6199d81e0b2e91032fb8aefe7f47830ba929c7ddde573e41bb1ddceadbd03bddf8d0eb401322ce9a4bb25b84595f9ba03eacc3603e08389daa7cb0017ea607f606c7c5d8bc952d36cfa0f9d4cb105ee4192ae27dc1c45b809e2633bb082922341cb83549968102fa249bc0454997004963004d6768b569af85a59d26c05349629bfdbd92b75d1bc5241316d719207ee043197a745a304d2078fcae62d5b1a1118b66bb2469e85eb5518104f836afacf5b51b88e34f0e040ff0f0d6e6b082087d9747bc3208cb60d6a277a0740e638468d3dda55957d87b11bf2e09c33df1ac31f1b0aa74d8b984f8ee18fcf527fb15d99fbda387c32e50c39709074f96fca960dddfd41206599ea80e236a9c086c3f8b5a594c6b112c653b7d43d8d43627e1f53fa8d9358632bf974f37528ab26f37b430c02005defd0161a0e3026a1ccd80bb61fadae3f6c14ad65aed4f769fc68f37b439c0e07cd26d899732d79391887c9268f11249f0f9baf1e6d334e1bf987f871ad6da788f3b8ad540419672e52b708308833dde43f450c49275392d3cf8e6d3bdc15533fc61e47247c03e2f32a943e83e839acadc478a40ffd7cece47ecdaafda66d4afcc2778dfa04701d20ddca31c9a93c69bd4df7be93b72bcfdb351a0c86828af3c1fe2202b8798cd3e1282befeb4f0f0794f67ad260889382f67a42d351c3b4c00ea5dcc9fc9a5f3b29f069b1bb5de40547e2bcdc6ef5062de3589e57a61d6b3b2fec8ee4b51392f9f01a13e625794f14d6097a2cfea0948e88386621fbf198d0ce53d0707d3480939cacee8982380ba4f4ff21bff3185360baf4df6008c078e7875c56d0df03fecfadc5cb7153476be3293456b0c2f8a4f9fc442b073ddd820e1e356ab0b23aa42c864bb30f283ce534e5f379cf77bc06bdee322304ddc9a907b3003b8740aea98f8adaf6c19a268b9631447decf6213f3e45c3be788ca16d184a397b32c4694fed71b1f8a532371638c32261be88fbaac5d986adeaa946a3f5aeec609bc5d354fea1dc799fdf0d633d88383634bbbe140769636934d86724faad169ea8265bbec3e4ada09fc4e863c8c3be353cecaf1d3ceceb83a11ec85f4284760b474e5e091a224b9b7047bc094aeda3ea468489eb82ff3140eac7b19d03b0eb592e67eb82017aa9e3b9ab4569ecf9be67b3af992c0166f9cafe0e61a9cf5ebc20eedf20f9f6058e7c366b02fb253d6b27fd3d3d3b84c96c25f06455e6c2011687bdf7f8f2c300d6b93bf64c2014f829585bbc69c4a26a14a71a7affd70678fdc17ddc3b3b51c95e770390fd1fbcf680b0ba6926140987601cf7165aa12f4ecf005e41f5c4e9d92ee5e73acbcb308379bd4bef433406d51301aefcbb700806067165f89d8d89626d6d537e3efc6ed0f2e7a9abf8b953e121924d4f9a700d75889d06aba5da41dd786d9cab266c4a4472474a4cca1e95c6e23bcc60dfd6cdf8c5cbf8ff64fb71f6ade98748367daa92c5e9598af8cbb36ff5d574fea7015864da57413dbfb5a303198987090f340031d07f34e4f34f8325ed0021ed441a0d20967e0a6e0a0c384b77af61461a01854254a9cdfe7b8f68da0febc6267f26d96d2eaef5e911ea2a3a0a1007917a7ad68d08fa80853d08b81e103fc983a22727af6f2b2f6a510323b909a4b2cfdde7d8c53c526d7140ee3501a6d2466843e6e2e6f75a565048e191d568e1edb6dcd766054c7c4e6a35bda641736294023b13fa118c56293d3826e3412a2c5b28eb6c7be3331ea492f03faa080829a75a521fac89d39f4443b68f7f9f62fae2a94a65bdecebd3db2d1933e70611be0541540b943c14150fa0a47c5535f2a83714273535a06c74a7b14aa368879f4a4f77c9f19f464e1fc444746d1ff1f06e093be2ee9943a84ddd715fbac6443360f7453a2032b57b9aa87440aed2ce7dbf2325bddf8dc04fc6f85230e74bc193cbba5a0391349902e963dd653b273250ba2a3a18a9f30c10264007a7c93f5de3474bdc20d53ca37a2f4ce8aa99ba230565a1b3e69a36c66ba2a62408c585d6787c7f9bfe12a232a18a54d66d0a9345ea848827c52ebdbf4dab46c4a4b573345ca4c5aea3e31335a586ea9b996ec0ea7965229163326fe089cef0bf3ffb664016f40781e64426774424b7644086df0d3059bad40d11c982fc6940cebe1de0d1c230a1e77952c431ca9382da145226059d61b2d07ce9cb3c91f05a5278266522f5cba52fade0b5a24b5f5a990ca6f415bcbea24b5bfa0a62482515573ff36c3d33c74a634af45d8f77861f35ec5dc595b985602a1dc169e0bbeb5a0e446e834b8369d2e0d4a36c88a4161a80ed6d22fbd2cec70087f9242625edab449d7ae80e9128bd66fa41e9ab3e926ea9cbf04ef4b599825778c4e86f202fc8f5df5cd7fe9b40a5aef037812a4c64f70d1a5ecf7dc47a395cb7cdd4b2a7ef74aceb688d98751f342316bc480fa0d8d43a7f0ba7db678d192a29ef35532a2a5a297a37d92161c190f465b3ae11eb224150093dec310bbbc03ae990aa57984caa5cf5c28f9873b7de3187a40c8e8e40fc043dfb6670da75aee01eaaa1b6b7dbfb1d360b1d2ade6e0718f69e6365c5f9602c7acfbe19a4023b9fb493b3d367df0c0cc0556ed0fe7e90e5d274e81136d911bb21984d1314d0fa7d342e592317ec1b5962cd6474c60618dbcc1c9f8814715be8c484a76f9c9d871d4e9ac713b7c68c1fdf9d9eb920557769bd0df08932179e9d78b249eb1de75fda09dfedb7a3d3c1625f59de38f639f1aaeb8353805400e9d5d1e9c6d231a29c4e58af43ed451ca2efec237fa9f3411cc3ca49d54bfdf3e560ac527dc07578e3efc3ed80eb94bec0722a03239dbc01629c27352b4f0afaab4055e09f5dd6bf31599bb7c653d77aec82c631efa21fe2787f84ba7d6083c284695644184ca3872745b4966ba020d0a7e7014fd851e007da74473ee0e5e9ad3fbb8945ef8556bda48351d5ef631b8c1414b863767a960e8062d85b7915c97b85263332fabae9e15b3de0e33b0a9d4eb3037440b54f078c42cfd67702cd31f945dffe1d044635d564cacf86240a091dfd82948df876a11b2bd277623dfb96eb7158da81ca56dfc1a0500449a67c649e65cb106422a6981c4459b34b4c33624e74441e9a3952e8d1570ed2a13fd4cbfcb58be96736814e05a4d672bbad701c1771bc064e30776b296f400414240f0004d6fa6d03faa1f1aca98406400eb6a503f807d50d989337c0074a9c274cce9067dd6b269d08322067eedac1c6e59a752dca81e625730763c0923b7dc3d616d0191d8eb2f36a9419c4bcfdf299296f810f5cf95d9ecc8ab2e2b6a5798d1991876ed0489212283430690b0e1233e00628d68e380b46b820ac31fe6bfddc18f1c633fa8b4093105143539ff5c3643ac5aefe600eda852cce40b99f34d0e5b93e7a0f9f165c9f16bcdfc78fafffbc75ce81376c2aad5ac814dfbbd30c4a6ebd38989b52e9578774abc375f673890470081bec0714e1116b78aa3f0a5cd18574503b637561c1ec1d5f8383e7b7d0f4f0af9afe7e0a1ec28367bdc700e8d82f012640fe3b31015c88d9bd532f2705be07bd7fb1dd0a379b3644f7234ba06d763f29a69888644f0e0e8e13aac14ee68e9d0cef0d9134a4e5f6ddcf7ca6509f9d9ef5455b6efc77d297fd32a9f2df78d7eb2f84f5ce4e3a4a99225defbe60dc685215e225e46440fad6b255ed2f3f83b3611c1477987c2fe82b31fa8f502ff2bde190ffa6f9f2cb8caf249f31c533f2bfbb341fffd6a13df9b397215ebcfbe9f2d3ab1fde5ebefbe9f3db3fbffd79bbedff6930f876f8a73f9dbd78feedf3c19ffe3424ffa873bffa7b2bf75ee61f05bd5fe64591577c568a2cbd9f95cb6529d2e301a94077002e4f553ae4cf345bd69d873fb3b934ffb0ccc55af1bd4cdff0e741a645b9967b599e7dc35fd83c67cf7724639bbd2cdf7df3dce77936d8915bcebfd69986f65383e7dff95ccf7764590ab5d8abeaec9bb3eff837ae7b673bf28f35938acbbdeabefdeebbe73ee3f31dd970d6d1f6e18be7fcdbdd8efc55d00f57bff2994abef24d857e1481f5e27f367900de57b5f4fdef4de97bcbbb4cefb9a553c4db8843b90884f720a77fb438e8f85dc0a2d04f40c9366fdd1653b84bd799740e8090a9115801b4a03ca7d508881146f904495af6aa972f87b83f9c6eb76004951b64db6307a9795f58eba8459ee63b20df276a7a2e7049656f68680308cbce266afa52e0a018b3652a2afb4317635bbfc8f50b5de96e675b0f4282a204a4d1b1fe95f2896ffcd9340544dbb29167918779863acf704a2a5a4ed4b49f031e2cadc648c06f7c5a01618dca89d46fe5149f143e72ff444e7beb7aac850c39539e5cb28cade00e6cdc514b0e1c135c37527760bb9556fda7094a172fc0555bbb3433c09860a8c49884e66978bb4525ddf380cec7c27c049524c7a97fb08655c79496e35e9922b6ddd61f3bf6a5a1d21ca9ae6f0575e186ca4ada21e8101b282f36d05f1fb9416a8c8ba43086fb5a8a3a7aa331e59270b9956b91c1cdd6ab07db48473ecc91243607c644d62d64ed0d61c358fd5534dd82fe2a029c81113baffa43e3246441aa7e1493bf8a099b8227075f55e3dcfc4dff21489e9843248e6b4d04127d854f517992c36585f139956e40a0a251fd50f587d3bac5b9dc77f5994c418a4daa5ae7583bfd54264ce784513591d32995246f84ec641d913a35c550c5b1183f002c1d2ee98af64a3fd46a32989a93890008949ad46632f6851dd56ac4ce693162ba34cb32c4c890488c514ef51058801435c92d78373d1ed4f223bde7f55c099ce6a0b42c6568bbae1768ce8a166eb29190b4e3eeb6cd92eab20d63a47628dd47008d961c1001f50f7abf8338027ec0a8e0b7477f57c925c4d654894dae34dd5eeb6ffe2650a48b1fd9a0ddce2c8040aa7d88ec933940224cf64be9eb2472170be4b7174b776e76e772b3bb3a37bb8bf4de87c17b17d0d43f402b2ae20ead0ae1d6709a71eb82347a206e89bb3b0363780ed27daeffb6bef01096c3ef75620863d839d785aa5ee95910da6e463373e1ae45aeb6db28639b88cce93f0459d03f0bb2d4fb72a5ffbba40041db84a3f110d3826e6a2c50017e5f9766874a892ab299f0290e73a3962705f0efed1a0e99e463b8b45b3538837038db0d5983d844b394faabab099fea0e18a03ed606eacb2934d340c12cbd85a42e3551539a1bd306a8e4d29a016a5e6bbb454bba742e69979afbd2dbbbce3c998e2e6bb7d8390dc2c65d42e88f20a8dc825c4e2eeb4306eb86f8a24b2a5e0e0f2a16ef7770801e0a1fa07bc82692f2899a4eb75bc426724a8f07ee0c95f55d94efd01227552915fa4f81d3a5ff491a6d5feeb77d395936da3e3723fa7781328cb7db395998042e4dc282cce99c52fa0f31eeadfdb1fb466f3251de224c6638d5851694d23f431e2eb2768ede305d90aa69993f270b4caaa645febc3734a9978a5d151cd00b924bbdec2bc596ab8adeeb95932e895b4ce9ca60bd56e9e5ee4193e7b6d0b889b7250387e2d232b605fc5a72b2a6326c03c974b366462c61e2eab0159be56a83981ececa8647260b0ab24225f3abb5ae1c667d4d23ddf688523a0f622acfe338aab8cc79a59f16e3356c9134329d831ce3b595b11c525d819cc19f1d4d2f69db157dce98f3834904f3f137912b5b0b59d3ff0d22200f1661327bf889e114938c469a3fd22d2ae2b84af2aafc85f3af19db90195564ae57773e479a369ad15eee17cc8c44366b443459d47a998de140038be624cbe773248822057e39e42f4ed6582d64797ba47ad11113d951d413fa97e447aa2c8fe6baef2b26d5d16dae1647aef147e5fc28eaad7bd151d42b2c09301bb173a12980dc52006b52603c37bb8bd506d046726b2ea34813abc995a6e6aaedd6e725f31d3287f80cdb6b2ba275ce385ed76702a36bcd0be4743d59077b4faf4389a4de7aa5de697a0221814b93905bf4e6751bbd1909f0abc12f298b63714ef338ce4cc36a9d172c71ca082c719a13995ceac9a4855d00a8f21115c64ca2c22f06b337ccced07bbbb5d8bc450f292daaf05f03a4bafc6548bd0a3ccafb7d43b7fe554cf229f9514ccaa9275103d219e69c11494afc92aafed0d1a765409b8a71a3ee7430d57390793977571740277c09149d7e05914d83082f711c69d65b4fb21da0c6d9ed1854d5a4c97b432202aadd1dddf91c19d25c4d5d1f03325be9d69a6f600b35a49b660ebafd2d9dcf5164ac3123c3741cbbabc2a1a9dceb2d9d2ab22aab74b023e651c0e370676c4742f0dcc9549f5c6a3aaa8d0679db681055940331ace2b83a177e59558624f08bcc3ad265edf205cd26ac37d41c4236617d606eb3099bd6a84b654063159649b1e82245afc4a76798525a6db76b0773af3b5541a7d829cafb435c330e6b18d0fa64366485eef30266dd005eb421221a4b985474400a6f8f7dc43c4a86aaf76f4e419401746a4434c741a255594598547408d6cf36aef5b09fa7a89977e8f2f6737c7aa699ecc6eb8059717516cd3acb1495fd0385ce5c213089b086a91518a616c484b54987a7a8ea0d7b05681fec722319d89194faa6b5625a3dd535d04aae8fa1acb1737e0f0c23e83cfd4dc4a80814050016d1e0bc414602375b1cf3f3962661ec9e277c9a4611202d74d8838d0213534b5356186416a2c5d057585f31aa2c0b95af0c3f3176ec041212093d2cad0c38dd937094e332ed28d6e45380c3d27dc4c6b2db24ff6047ed4113947af89a11ae40bb0d7c408b2502291214d427cc54b3c2f0e42790ac693929f421a0cf2232a356ed42e67a23aee338d36b00b2930565ae6f9cc8ed16cdc7eb548fdc92cec7330bf33f4b00e69fac806c58d6e681cb46cc7232abdfcc1a6feab847abf10a2d0cbcc4e231abc82786e2d207b20bbfe5dc6a9ae30ff1a5acec4091c0fb45365c39acd1fea1207bf690d17cb8c53eb37bcc6e576eb7e89e9dc41e46a48dc127f0894acce67d32b42605b95618d35205e7ac0041950b78d6382d2dbc26b0534ebe05b9a5745cad17d9c97690cce60821f9741fa71acfc8fb3881fc859ffb73efc04794661f61ce4c6cac27fbb33466ea2096c3a91bfa3e4441d41c436b56f564122be268cdaa27662e679233c561441ab1ac1e8b70e8c1f8c0444bdd35145ddc29bae47edcad16e808d835f920e660d75487356175f069e96d012b00622125fdb7a7f95e38eba6db549cb05e799293452a4ef25e79c276f54dd10a2ddb86d7088706ba5797743cd553627138f96dfb4864544e0490bbd3ed56d3845e25050e135d270219e8bb4f91099f1215de7e846130b968b639f73ea9ce97746f228c434199dcfa28e6a765b2e8304d738447d5ef93eae560aca9b81d2695ecc03425215f993a3a9118de23351c267172bef45edf3e4b9ede1bb15d7a3c247a50f45f20bdf48fc6d0e9849ab1d34f96b24ea36010a36621fd1defc0e4e3361e0f89618753c3eb5af9efbda5bfd3e3e16eb71b9532506d56d2f8c84a7a3f638a5f9772936e04319d4cef0409a047d28f8248bd118af7e6f57f08d3d752eec85a82bc006ee034bab8b8387a438ebe7cf9f2851c2dd2e532adaa231691505319d9f4e4d3a74ffa5d2bd96407552424e967d03a468b5711e816cd5722a3438c8a22b28a4248d79f8ebc4a309afc75fad7a3be4d05056004bf772327ac4dca1b2e659e71d4a192e1e3fbcb3c4ba365b9e44245c44a443b7c12d6724760ead3c031431c84af5571bc9726c68a021e374e5518b819c4ce14d424442ffeff60459ec1bab7ae7ec81dd3a6799d2d38d2e53d2d8577846559232391cdac9a79d789f547764433900f16020e9343704cbc2356f470a884e9532db3a0948ab10aa41d28fc7aaabc2843341a05a2b007fa6c4465cd32f6f2084a35caec76e9fd0e9357c9a5be0e23733c47e47e55ac21ccfafd3c2f0a2ed3fb952c57ecda7838ee763be3f09d992dc1ba291ae31206949491464bda81a1aecfd53816fb025f85e3583ab222b99c2df222935c404cb4dccb7283680af9b8db8ef53c8f63a689b3cb9b9cdf1a2defceae2338e398ecba1878e25eeaeb61ac120bae21e161030f21a3e0dce8c64dc33dd78a8998ee3aeeae7b532bac08ae3f41362e418e79b249e5aee1fc386bebd0284f2e9765c60b888aa707468f7a03e22707aef3f8988151c9359cd23602cab1e60e733326fa571d15359fa3e34190149532bfce4564a2b61a13a3a2640ae56438c0c42b5625b67cb8b9c3a4e6c01dad17f5a3634af3c9601ac751cffd06f875d5d3ad415233abdbad3c1f6cb7f225157a0d8caadb5ccd1628c7f7335671776ba5fec06152452378a5ca954fe722b3a9bf7159fa64d70d78631f5278301599dfba70eaa3b3dacb24f5c12c6b9de63cb06a403ce1457209ea2863e07ec882f99048df2a277d2ddd88545d66996bb7dd322b33ad83d6c242357c4ddb64dd60c694d608bbe36d2e5203ef236979d81e7b00067400405958004a3b9a94d2f5760bc3a97f8e1fa88491a0cc58a502a765d23222470c93205a9a37590523d1d91d95105069b6a132d9106ba96d1a1e98cbb1c0ac1e93cca97ddc5ece20a872c704d989a9379ba4ad0987dd08b3907b1eaa860c6c9a0de47354f7978d1ddeb90114d5157e0fcb7c2c5d14a04672ea86b4abe4e77235961002a84ea8e1c86d1a98cce7e1532a9310201f0e8d6612f2ec9bf1ecac43842477018798279b3ab2b135a0b083907bf398bb146c995b0192c6c62c866c5265602972673603a3a6a7a6de7b8bfdb3501ff3760226caec032f3535917147c74313faa40f475f10fcc498051d774c18838a9034e2ccc61929931b735f0579bd549f5109add9f983c3b77d293b2ecac8de76910f9b0b3e903010f5425218fc5923773d4598647222a688e3607056b2a98b3ee649f5355fd5192e65a7049398c05a71cc8cc09a3b4b58b08db8038165b2d19cde7094831e35c7bf2433266e58e5cc62395193bc3f9cea3f53dcb88b842e0efbd2e0ce794b5a10f02677c4fe802f30d0010c46fd7ed737400520cc87bcfed5c4e486afccee48657f6d486119d37f48853cae04bcbceb97e40cf79a899b7e45ce70bb0d1c0cc68d085c7fdd74c4b6c13e1c0f70703d6c824126b9757a6e0736f6e259b2a232a9564cfc99ad2aa77a9f4cc90d1d906b3a308af4a6113b58b92d21bc78af57e28c0ab4a66a52d0f2df9796e221059198cce84aa2352673fd37c3240f40f216713c83783ecb1e5ad0b237c498cce2783e4637f4d2e3f75cd38df99d619cdec4f1751ca3d518cde2b8ce338fe32013823506419bc9352637f49a0eea6e613c6abee70dab771e58bb32fb840c08ef8da4f79a5931c46944d85c7169c9c7ea6f2d5b970e187bc40f9b21802592a77649e18482c622a9048b2473ba13c428b238fe214d2b317635e33866f6c6886316b23a173cd157181cb2f7f60849f93e152c31d1bd4c67d2eab30890002927bc48d90e1391fc9b19069a93c2df65ed16a39c1613398598c030927421514124a9c02dc29e24742e019c2a59b2d58a4bbad48f7847aef8bc942ebc56f5a61d7cad23bca2c5db79203c970bc06823f617b5d64fbca47abb098c142d2662ea3a88e358b9d316f4a09a6c4c7881ed32d7b755934d2801d55c770524fd2dea77bb6dcba38c757719c7551ce7b5c6c61f3db3225fbd929ca135b13c8d7ec26423d11a7ace484564725994e50a135f6c2dea8218e3dd8e5c4bfa4b22156021feac8a5756387f255d18990bb967635df300ef65d34837595706891b364b1c6bcec52059bc546395d68fbb3d3eafe0d75c640d50965a3ca4a96902d1657d7861325f17560e773c2096504c8f87e416845160685d8ad745535a1be873dcce30d1bc5a61eef742ce0b3c6216c3815a16c53d8f8fe57e5c27f3caf269d67a4b73c1a5f84b79c3a5454714ef39bbe1e6c11a41dcbb214a9f0f88f57f4d870372cd0597ccc6feec8a55d73a491a5e1c66702da928bc56cafd6a4e5b1013d06f9c5640bb26d082700a1e118621d3657575488e0796e6f3d255c5ef54aa26c2c1719b40a0fe944df77608b1e379dc7130d95a3048d25eb3952e0d9e3dafd90aaa23ce21c8bf0177a1a69b50e39df507d239fe77990bff4e3fd4559a6972ef8cc759e0cd54b7037ab0f2039cb2a47ea8c33b331f7195844b33b5fddbed4c3029885a6a26f475175251689795953330134c8cece56dc1f5138ad645641c351b4b6664fdb4b87aa58c1496a36856b0aa8a084ff2ac17f5cd77234c8c662a0f3553aad7c3485296e8734e64aff5f9870eb5a0c8238cf193b26a3224c238a9f470b51706cd35a1dd5e2d90088b2a8ee5431ff9ccefd44f65c6515d02078081e55a71f997cf17ef9d9ce9aba47f7ed03c96e3fb5f5c06ab6832fec166e4fe92abefcb3b00c1b0113f17fa38e0d93bc597b4863ecdcaf5f542acd54599717a3c74179fa528aee49e1ded1e40426d2f131645d8988f18f73b6e1e8c4b2805fb1226af735151415cb94f217011b24804ad14a07af6339a0abe5fe7455647894cae5acf50782f1314fdc144234ae6f62f64fd217c087b958b4ff96f7c4782177aa43abaa1939f06c8d40e60dd09d154f0b9de0e36ca2d752048293a80dea4ca156437ec3475b9700decf4ded518003d058fa0f60f130c2b0e297618e83d34221d1053793ad8d991d91b89bd6982c4e0f1719855738dc0fd2242bc1d9534af2d32b1d4ca9470ac0923e314adb8043c40b11f2935905bba9782844ec17887012ca9f60db3761fa21160c76c3f13485bd8916877d9ad39fd70108567cf48ddf41de2d758da05842fc67bff902f64498dcf82750c6a1f0d05f51309d4690be23d9fa3f51815fb6bb1700b4e8e87837480539fc924d419821589ad591633ae96b98ff26dba9d515e7bec5674329842506916fa561a607df698676530090daf72e50eaef7c6e0a45702064843490c755b4df1080d8c74369b64b5a1514f82bba2dd122f6dcf35a331ebd1b2e7df90a014522f0710f0734a07980044cfbdee4c3a20aa5ca50362769174bba8dc91e637a9ac2bde41547d93b34767bb203e76fd713d5fb3b2582f851bd02959fa34332395317aaf0b5dd201d9d0c1e89f3f92804eb1e995bdb393f94bd778cd4ef7e86530640bc3cf5d7ae3f40d768dd23fbca1f3a566f0377ab8e74f1a4d3d64fa539d1fb033d8a3ab9d3b776d528d8be79abcb3d87f8d6c742f1b1dd8bd6fb779b8b1f6358cc077b8e0b9354a96e14ab6db205c7a678e7674f0a71d238e15042ea4c10e6ab6921baac8089f40446f3a66a012c23504878819ad75630b9bd09a0d6fee8ccce8b5444a7382f642abaf12bb8f20789e3ed516f44236fcb8654740fbe5c1a36f459770f48de6c10932ab7f23739a60323f709ccc030081e4059937100416641e486be0491f6a4b7ba88d4c3438d81d2b4c367ba72fb909cd2a25beb72a1f9500fb69153f5641e3e331db6d32dad3d8f0be6ce96c10ef0747063e3dd34cf8fe119fd1ebf1fd5d6a03e9dfa082acc1e7616363f0d75b530f463ad8a575eefa9dcb7d834a5241799b9b18a6dfe9e1f5c1e0e3eb2033cdc64fdea71afaf78a069f7eec3852cef46f41e78d234885471059d2cbdeeaf4acb72017344beec87b9a259bd14cd39930c9686f255e8f21a2eb456f5937e6a5ed7c2b731c23a8af47af48060ba7d733dfa18db135efa618a750f5fbded54b3374757dfe6c34c52f7acd83dc55115e34ee83d0041ace85ff9e612be82cb943177874dc20e8cdbd7c8c0c9ee425de6e2fcfe900e3fbb985471819e8ca0b8964807a92871c29500be19e80ccfe91306c37d46bb6aa2b7acd56be1ac746bb8c01b486cf1f30cdf91e1fed0a6aeeb92ea29f7c66cf58e3c6f62e5bbb1b0a0709a6f50dc490c6236a34b0d1340cc8eca229fa30cbb5a2970671e5d35f7ffe7c767a460a3d3d1f8b758538b93c3dc3644d955eb2232f58d307bd01669b131972f746c02e3d6befe292d4b80d3358863f94f23d58435f62a2c8a53e9cac59b91b8107338fe60d3896afe43d51986c26726ab89346b9afe685dd4cf05bb324ef0f61f3d0d5e919c9c331e819abb11e1bcd6bec0701bb1ab0fe88b002b03846f3869a209cdd3332772a1d2834771a15f7a55c5313f0c2619a60db3702a74096dcf5687006a466a3efc0995b9f6f764c9e72bcedac49a33fc95ea9c3927b0fe4c65f820c64aee2989fd3dc708071ac74b22a5771ac74aaa1132caa71debe71041d8cc4b97709ecf50436352349d944803ec07e409a234bbab34dbda4d27f077ef51c6aa1d77b8687f3444c43af6f1748e5ed0d171d763324b07a77a40aa3d1b25c577c0d841187b847e36856e4b3af516a1e41a10c99f4e4826ad89c6332b1d2cf3886df20fcb4eddc39f4025bd7b12e655e8d5c5910e6bafc8a8aa43d618827770422e5db5a402dade2d8970e7e1a1757cd4c0a882049144e916f561c2bd05087f21980826e26f8fc7bb53573e2d633d55c573d1cb689f0d4d12ebcdb05c818b70d4c04c16f8fbe4a743f53fafe07042d1b0d473905cd0e8f962af131091027103c69a9129665df9777601ee479642a4c7849abd9b2123f726929cff4abe394df89bcdbd8aa29751ea938b64d6e89b11e2f6b8ddf4d3563547b4eabda82d7bcc6448c51572ffdd2a50aa7b61d38d507d352251296a81f828c175c692ec2d6697985f6f60801296ce3e02a09361318b4912f4e8b32da53772840c2a9b51d4303410fe2e1e8aa2cb2968223d004b4d422204b8f22a7f738e3cf9cb0f2f33f4f58d99ab92fff5700f94401e4976e01e497ff2b80ac47625f00f9a52980fc22f705765f4281dd976e811dd937aa7771a64d13770023dc62bdbcbdfd18711ac42530f40d1e9bbff6ba4e87f8e400a71bc02d868229a29c48cefe65c6adc16c754e9497e1b91f6ccc4da07d2baf4bdb35ec1709c51c5f0e8b39f6c1c5bdf062d41481f086b8833f2ada68e1c81d42907b102e2e04ac2405ad4ecf02de6a4d07001eaeca1584f70799c59cba450d7236d80e0ddccd3db4a7a7e1d1edc1d0ed6f4c46673db4e8cf30d0ca59af2092eac714312b1f05b33837bce359af4817fd02f2a2793fd3e5249df733b2a60e65187515ec272fd2e405d8a57b8cbc1a138f913cc0c05bff3e0cbc9109726916783328c7d246a084209203724907a3cbf3654db35ee200056e39b99c92015969f27dd5a39531880a33809f26e0fc056c4b48e4bcd923723eff73881cb878bf2fcad9574be87c92fa1cf820e98d241f25bd93e4ad257d206b40f97c7e32e5032535e1f3e677133e5014b64eddd283b40f64791ae9f3e689a44ffd55bcdb79f8d05fe5512e8e3e19c10197f483249fa423183fc20314a46f25f9511f47c58acb8afe428213a2c65f6b100ba303ee1a7cecacbbdf098538d876f7870061e32c25a37f8f0c0ca33c1d0e06272a5931c905287435df8453a9298c00b92d304434d6a33c8e23510aaef90d1ec08ea1d018b156a3db83e13f727e0b279766403efa6f9a532b4faeb97a6d226a64c60242e0899c42b4f4bd5725bc5a53852a4c32aa5081c9ec70fc5ce7f9b2dd66638f38b21e73541141184e67241b735490121e706a3ab7fb25b95d70c95ba10c1b1b9ce338865f01249051b8616f0f6215700a5ba8b149e09f6c2481cdf8ae0a6a1546a0cf011452ecc82fc93c1719d836d0fd2fda37e336611934c26601b793dd1e052a022be4314f855fc3920e403367cf2c79ce8c09dd1c29cf73e9c990a4866377abb33f74edfe89dfa95ff606537fb88dce26207610ed0f71d004d11b8ee479dd0817999701d61f88e64373df9dfbec47c96ff2725dfdae4f7b6485b001fde148bea483917488d70f7dda0536a2fbfe2236e07ce07fc1318ee3202eb6ae8015cbb2526fffb166451bb0a0195b865d5588f7153e1775b15f1665d15eb466e505f80a35d497e8ab73bda3454fbdd4240a0476ec68f9114f24cfd6338e50a79f8ee998c2639e7ac5169ce2981c8ab1037d5de6e29ff1b55cb4beb6770cc0d72a7da35b1fd76b31eef8b07fa9e7a2cb5b754029e2b4c77d4462085fc55f0ec6c3d4ac78ef8edbd9b113e4dc1786df0db0c96f81cb0fe41f7e37387560d63aff65665c953f166cd62ad434d7e738442d1982d02c5c04270a9f2a7d888fb03aa1c30111bd9e5f17b094afb909f0f0832c9720aaed5c582ab9ebf304ec01934d9f271be7560cf6dae244f4e449ed5dcc14136748921a9e263fef272f1c5e771ca3bc476bf86e720f96d9690e7eae4ccc786ab6997bfc9eab5bce0534af1d78b631a90de371d7e6d076dcb5fe0cdb6d98b30a3c273a27e6dfcf281d8c0769f2022605545deddc217fcf93d95aea6bef0dbfc967c625e367a6f292302a7c8888a3100545f5193e91f854f618acde15a819d6f2a60b24c61e4be027305629273955102ece2608e79edc1c883cb9ebb3d640e4c9a6cfcc40749bde97c95d3f6f152a934d3fb785d6b43a85b82424a385fd35a3f204ada9d9346b3c1ea460cf2e4f506613339d987983c7953dbed3fbbb54b7727602df65c91d269b54b71152a0a9784704bf53366b6fdece6a526c56583e6f3f7e7af7fec34f8e6cb08fdbed90f787cf9b837d518a529582d347cca6213413e2c61ebd69ee597b0c823979eadcfe340da9d88fe9802c7fd4dc3ea06165fbb19c660e54e818499a4d94fe802e0f930bfb5e50f57230ce26aa3f9ca6cec05d9dcffa439dd8b389388e8f59a3a8b1b57069777de97e8d64621a07a1aee763e4f26c7c9e0d3e9da783ddb189beee2b1dcb64f92375c5d363b6ddb2bdd7c2bd36b18df489eb92f0b1350e8054570f36e50629fcf1997bfefde9d92e1830c04955d88c1661d40c029141439acdda6e51f3eaf55f26365c895d23b621ccb406dcac963f9efacc25bca99f515187ecce9b3b46ef9573faa7ed1655f4d969bdcf0a108dfd48f393eac4d703df2b83146cc119c315d2b13ac0dda8bd363a960611717c1c4e631ca335457e3df4ddbb3b7cfacc8fa3355e364e8176c3fe9dd685d60fe6fce2736efaeb13dd674c586b899a66742cd043cdd0d466d0845e771374aee0f33dfb7938f9f551021a8703c497186b62a90ec1cc278369cacd50b6df34219e7516fd0577b63df295733ad8af42ffb16f062e015a9dcff84febe561dacff8f4fe9214e5f570a0a90322296f052577119cd4589e0f9317e3612acf9f8dcf5279feedf8453a1ca4f29c0e21959e41327d01e9b8156e1cac25f83fd6bc52af44befc41b225a7d15a53dab9e059cdb2dee6222b6f1ba4184778979af4b00ed0054345dbad7d7bcbafbee6eae707f32ccbdf1ece503e52be3af0be8328b0452aae3ee74b5eae8107e7cf4ebf3194de35573ff3023454ce27f660a47c9e18f76656807264bbe5607cae98bce6fa29a9e4cc9a7b9b28475c7dafa9865c5cbf2e722e14e8be31b8cea8723d5bf06a54c5b173397e391823412bf0af83ec7f27327cfc0211ed59f092f937366c7dc0c5fc527b2ee424b2e2c6beb149d2d4c0a35955b9d239b3c7739a20b9704f3e9ad70a5f01d9b43492cd7e0952cf7ed1cf0094d364e997892a57fd757f5647ea6a304c48f882f8747e925b28177588a6d364876c5420dd37f0e9e22477f02f872b70f4f7eb52544ab25c18c39e2e5254af9d68c9eefad0a80814b9dce68ff05e3d5673f45045a675be2653c254753963c56c5d30c56d6c8b03c7175234981410a33564502ffbc3b138f1b22a4586037c3a1c0cd266127cb22131daa7c2280f84581e4c278ea34909f06f479f162c2b6f7f2e4b3505c3c344959f40728630046552c9a2ac1426ca8ed505bbcb97ebe5fe80bbe0a82d19160783a163554b7d8219f0a1e9823422a9e8778c2552addd43047e2c9fd91004c09cba564cc0ec1b329be1b1acd96649186e76bb637dfcce7e9b1a5a1db73a8927f41c54b48f77dce11f75f5dc7cece95d379a8e4ee6d1f36d9067dc7c9ca869da25e9dc175a72f0bd37a012b25c71a9362eaa80b92b552ed8a7193b20bc39c83d52b5dd06f7ea71f35e8d637b2565ad62db2d38c00f8f290d3954b0cc82dbc79ac8e64e333aaa556b2782382d5a7e029e05eace00112001d199addb91c9bfddba6728b2dda2e67bca7ad1ea2e228d5c348744730a1a2dbf3c7cd6001a70d4e3bacc51d40369581090f620b38c249506ea23630a4c87996216894526d74c5eb16bfeba2c0a3e537b09e08a6102d9198c3de46aa0dd154ca6c464a7a03536bf462d9f723a2073da880151d2c1a83c9f8fca5e4f338046068fd6544ccaa966e7347716c6e3c533fa4bd378dd401393b575b26f88b0d7464765a04f3db870755e8caa5e0f1baf4d94d1f5a49ae2edb62e97e1ed161dfa52664d3417ded9cdc4ab5fbc743d338229d3b50574cd2a53d8249f94d3e92807067cc6d1802cb003919881c4b0fee0613457aa825016f9768b4c0ae58df632674e2b1ce80326f94b037a98632281aa06f9c08739a8d001b7a4e3641c3e2cd36f6a0c1c39ff52c1e5e305ce10ff497f12a2f3d1f75de2491e7aa1bf86ddfa67c9327dbe4288824e9f684cde1f9266ce4a5195054fb894a54411644f7ead8e44a98ee69a70398e30e1f69004532be341f8b4a67d644a7129b6db079a3de6a9ed31e238a9985a4ba6384a5ee84d29bf728192214ee4f595bbb1773b84c98fca232c56f4ef4a3f7bf29cfea81f997bfcc4a53efae85f756aed6b5bd1bf729d621d635ffb175440ba87a07ba59f2ca54dffac1f9c3f01bd809cef84e292c17050064d29d8a65cab8a2ee1695530352fe592beb18f00ce453fc19339f15742ff8623d435f703bc06644ccae1f56703434b7f5181bad0acb742b63d5a5ad525925fe795e212bef779b3e248114e780db507cbef93c49f64b260d5875be16e29f4abc4715c37dc57853ec9c9af728a47411f831026d6d2fab5a43ffa60420fdc53c85e54af174c2afaa38239760ffab7315aa45e859a381db319275570ea34aa8d57a6d96e58eb7ee8771fe1e7f7ac82177692bdf9d70eda60eec4bf58ed6c30f2f6b2f4f31d7cc22e0068366011c2b0c3772ec4deec4da2ef998c48f4fdfaeaaae01189de584fd68844ba7844a28f65c1e42bc95944a29f5906d93fcd607b45d3e661f3a39af029edc49913fcf6e8474d58072d000d391270ebddeb39498da7e02b85063851e5fbf296cbd7ace208f7b80da331d48b058495afe50e05ea6a2537352f31c4bb1953fa34c4f77ad3e21d695fdfd1bae2479592f94c19430a49053ad3f49c40cf30c9a940cf3108b185c1d71468804901cf95662c058290b2450218c5b74c663ff3795b69e428a8abeaa3e4f3fc0e889a1b2673268c0fd0ca406f69f29555d54f6cc9c13c8655645e2b466763e3559dcec882ba582509c3889349e4aa8e48642b8e48a4ab051eca561a918855d11493a52bbfd6e50589ae58761d20c8eaee341dbae7c49690bac4bde4f354edc882dcfbcad31261949125a9e278d98bfae6e3b979887a394c19c6a3cc5914fd041299efe1cb2473e79ddef515bdd7a5d3e3e18ea884d1ec91896b2c3f91649a48671141fbe893573b4b194833930c66529a99fe536ba69f9db5a6fad9b77aae75c25ab3ff029d9d3dc3402e0934c37e56125655f9b5680a68023dd8489dfb5040de17dfe99405f5ef1c3e3eb4f728174702db0fd4baf7e651e954e2fac0447c22a7544ce4d4932f3c40025c864bf37ed7fc10c7caf3ca12bfa483edf6495fe6e6cbfaa3a09faeb5bc01b294b76338468d6b59611b5a030c87362bfed6d2044c686a407fe0881dc17a3b62d5113bf230a4016ed5655d3b0faafb99cfb9e462e6ea548bbc3a5ab04afc2f7574c5b93872d746c5b3a3fe51b55e7189702387fe3ecffc1e39d66c8f61efebbb44f3fcbe5575ea98a74120c48d6f6257de38b608d7aa7b343ee9a61df1bb95e4550513b9aed411cfd582cba32b0e263247a50c8687003115f5dc17f088d7d3e896ac0589865803fe25b99f0143bb06f07e1b358d132ed64b2ed95561a05b64aeccef0171d64cf619d02fe218d96f54c0799aaa3fccc79da93036294f2e2fa11597975459d0265a87c3d2242c1737711cad6499adcd1092eb065118d80fe1fb95b194f6363097d6723a8872562f556b12fec1781c7410db3682c03bbb744d50757d6cb530685e29909c128b83678f52975a36522b975c519994c2a54213462c8e19b8e5b76a461c130e585cb979ddfc847d5dc671d9785d35df57715c3df07e474422f99c36cf584bdf50ae5f3786c3ce1311eed4d9684a0f93f0ec9895cb5529b8506ff2eca25c876a7d1baa4e72917109e417c2bb83858d6d5e583a9f1b1072989044f24cb2db06567cc62b25cb8dadda0403d9ffe408928cbd7c672baa45b92eb2d7ae2ded863421d5cdea101429db22a2c0eb0683c942eda653d38639a0ba813b45e94d85015ccc08431cbe2a6f76f178a0df946070e7a41f153c19ebf230973876be408de4e30c61947bcf12bcff52d6c80dc15b239337e10d241395a6c6f572d537442d07830a8c6e1564a22e0729f0760b2f19e16e140e4dfc2f7951fc4d2c3b174e737a9b15ecb5ab53949b31c50e071f556365da6f7700d67450f891255f96f96fdc7da23abc3801092334e7de1fb73a7713ddbf39787481ee7784937b1f898c7b7c207d56badf876c028e4c7943a1195573c56ef86b2bf0b3a59166c45b33b2e0b3afeefdde600a1a9ecfc794ba131b7e3bf4ae7a2c2aae7ee49b8fb2bcc9332ef515e8a39abdaa7ee49bc010f025080f451cb3383e964ee6723c1c4170c8b79aa969f4931b577d90c31c0f80d5cce3b8297cf85f13c9d94cf5e134fbb5ea9f4d8f7e6152e4e23a3dd2351ed9361e09ce334d7fac45fe8f353ffaca37c9d1f79b234bc09223b5e04726585a74b4b2f4d151298e7858495e1dad2b9e2547af0ac5a5f11a2b36e46853ae8f966ca30bea61386247d1fed8448600d2951fa9055347661e5b8dfa5fb8355dd75cb5e694ee93c835a49a3bd1e3783fcd1a2ec3bc3df6be0194d83a45f79719edf6aa319bdbe5693c01ebe8c268ec2dda8e05a1f482a843401e5c8248e129557a57341a1ddc0add8d25e1b11f02469820accdf3a1b1c7dd01d1184b7c0f82bafd317696e29a5df3420118f70b60aa0f1721caf34107070e98a370ea46b6be60cf2369aac9e91c2e860777341e3d719d50d63aa93ca3923f325bf6541070ad194ddb66a517b03d6c4d879c68d741611bf127b18f1d070891aea8e66c94fba59949f360c77289149998881735ef0387abe6c91c41a457d4a81e5a8b07b044c296d589bafcc3a3650efd87f3901277e5f0c886cd751d1040ddebdad3313cf0cc7284029ccec035e4d4dfe09a78092e4b1b62767f0fe0911773c8ed1668848640c07d430278b1f361905dbd03bf932261a8b4e22406c87c69e5dd4f0471f109f25d6b6b87d443d7c5ddde9707afca911935cbe300e76477ba9be1a7ef06de3587b6a50726f1c1f953b5764d78b8193d917956a3e8b5054091913646c4c87e0cc13c777e82caa204099267a9f4189e90adc14ec180ef90aedfd3ce7874ddbce8bb0db2e146dd916be885e6885d04d632614929f88739889527f008e34ef44f5dd714273958d1e49267648f8f4a5d3eb2c74375bdaaf6de3968a48459758dc57a4cc3b63499babab05b96415eb73e751293926d3ecc51fd1a1343f3c3ebabb22c08acf3b6880c50fcf53cd62a870904f3c58134d64a15de891b56e4d911acb1235dddd17f453d9dbb17fdd751b55ead8a9c6747aad4c9a217fd5712e19d9df3a0d7fb87b2efa69eb8a688ef41f058ab5bdf99ae45991748dba11ebe70c054cf0603371ec7433f98f7bbaec6b4d6d9ae29396c880cec1879c901f1320313cedb04eff511bdf1ae83cd7d682f1ede69d7a43ed9cd86852d175e86b56540e3e403e94d23696ffc8cdcbcb5ffc8bfc828ac726e06a07dfe1894a47fde281c967cfcff67308a5c98d1e8388fff55b6c51593ffda3b62e1dda1bf7743f12f3a1212949affca23b0f22ade7fe551b8323af07fe521a8ac5ebf730c3445e94c3676b856a01081befdf67f44c58e04fa768889402f9e8185b640c36f8cfaf50526f3a7a8de490e689a5efd3e779cea827283e8bb04ee87ac1a2af84b4078842882003a9957964c2637c0e1b25c0078da3548e159f641141b7265f4f617b5defe6a1ce562b556517a45de3fa4b8d74d8a48a41b149128cf5aaa7bdb14f8651b1291c8372322916b84d7f37f759f836801af4bc888519630ecd88277192013bb8c33ddae3589e6a55cf66d9608931b8c727abfc393752fead79f9cd2634094f7767dd13c2f003d6c6e86fe76846e7d3978678bdcd640bb77237467f2c0bb3bc81bf51653ba2082deed0eda245c346d1276e4bde5f8e7047854e2c623bdd66ce972bbfd4a9ae60a2b22c8651c4779d5b7e3b9314fb91d5f67b4306f1a2dfc50caa535d88ac83cf981f3ec8acdbed275c2c06061fec83678d046216fda2898d8f91d9a0adff975c57fe6731c181b87afdecee79a67440d331967cc4bf90e93099f62a202db80bcfe083b50ab8b62d0acd7a37edbeae188313fdd49181c83fad36a8a77fb83e57affcd333ce209bf5b95f2906badc5ea385cc7f36fcc5973f6e2cc9c36672f9ee9f34642903363d4f7995ddb68179d9f6be04f50cac77e6ff3b1b7f1ff9b332d9b46a94ffc695d14d3282de3b83ccafd08723cd6e39aea716eb51cdf3fda000380614d0f6ae48d8e2178e8e81dc060241013af34677005cf251ec112deff787ee8a40d4dbcf27dc95196df44edadaacc3d25820d5981d4af3e7ead3eaa6b6e1b1df3cb368889d625408a639e94b782cb37d65e7ebb7596f3bb6095c3a20d2ce99d1fd6ceecc3533479d5ffcf293ebdb682efd3ffb3acfaa7752bcae09b9d722cc957059b41c4c2febf0da3968d9b6e8acf9293a8bfacfa913181a8e8e9ff41c8c3066d0d5ed016cc2c31fafbf6cbf63fb7cf323cde2e9992f91d82df2b2eab159fa9fc866fabaffc56e7c363fc6fa7796b9a6b6ba028228c46918d31d88ac75bbb5a186bf93d778212298c43dba7e666c55d9e09ca74bbbbae9115a27ee59bcac6e66dc9e7656d742da7a37cbb85c8a3e3e3fde13f46c77cbb3dae12c52bc0bed82189c7a2474b24712f4a8fa25ede8b4651ca7a54f622048ff8284a5d770d028f374dd5c5409bc8e218891e8dbc0a5757c5745598b8b2b3aafaccef548f46a3a8277ee77e7da235e2d97796447af6fb48a4b67562bd0d2b43d0ac1fa25cf62c0c47a241500812097673c564ff4a32914536fe2fadb65bb44e1692cfc7118b521b35e6b01562d63e46d6561cddbad773220edcdc3f4133be8756181701b2a473b2d243f61c934b3dc4434c367ae8bec3e4068cfc30b9d63330c0e44aa7bfc0e482de5b41e42432e8879fcb5544ec6f03ac174dad84d265790f0e55f601d0f8a2e90e1af19e22b4001ae826994d69342b8b82ad2a1e91c5e426c9ea14bd1721edaa238d05258faa45791b9185a601ef73911e0f211479b956203005db890fe2ad502e04bb4bb933b1d8d96ac59934c1d82dec5f1a39afbceb000c10366a77b0ae4964c2c8473d3e194c1355fe6db5ea30e59d12492f26bc06b9ed790f3c3bdb977ab6159100863e1ce0c3198626c36e476e0f8bf3bc2926098c2d5dfc3e09fa230b1ee8c2d28a11ebf5b09cb069609de9fd3bc08742334296c6e164a239a2a926b1674ce92362bb0523338736aa879d36ed132ae3cd9584638bf094468368475458b0e9865463a0344b8e5c95624a95090a3693655134270e70c45af5f3ec894d3368c4beec5dbeefb3f758bb8c2e776f3d214138365e597686afe0d4c1cdcfb547e2d1a6ee6c6d2bb35e38f62e829e0fafcd00c33af6ed24ba4c8302e5b72b38ee4a4438ed4ade117170a20eb8064ea20a32473db5bfc554bdc5602c8d25df6129036959aba9a434270458a3d9dfb9b8063334fbc833b2364f77b92299ffa9b3cd6848cecdf5930dafd83260576412d9fa2212d51faa1f78667edfe5caff3019c2abc755af2f20ebceb5a88797f8a4bdf56631146d9baea14db5ead28c0144c1782887ee72aeaf908732f18c54fa1a3994478fe25adf2f0f648028050fdc9237096fde932ccbde8aec7d5e292eb84c370903d3fd88c99cf5f9dd8a898c6751ba486459f0f122c9850b75682e8825a9e7245d113f27e9253153915e113f27e9c50e936ede009a5a94e29057c18e88b643c18ccced36a957d2fb899a92c8f89a83096473b7c7b17de7f807a276a8682a386e9bbac8afb000eee82df9a22ffc6f31f9fc44a2c9afe83ca4a0ca3d62c92f4d52d34db58948dea096724f2d793ac0c8dd9ad3fc05ba24aaf552af4e00dce9e037f6cbdd35075d1307862a06ce13d602de91b2eb938695db23b9f21d11d8115c9fbb08aed7ae2330d06fe867f2495354df60f2e1bf479daec33980a857262aa5215a17b5146e3e8eaed64a95224ae720eeb3360af5a67e8cb00da6d018f701adab4f23a8e821aa5795d7d7059796eebdec96ca7d49180653b60dbd4c4af119ca901b7ae9a7855cbb929f74fd8de95ec6f112714c3671bc413011f69eb2bd36719ad1ca5846b9d4ae495eb437e5cacdb833ebb826e6e830c39066fbd43739be89634f8c821c8dacb7db8e1505247fb8eb452feae7b35244763d7de85a4f667022f2a16d53a05b9446e6f5916037f935f8604686cefe483f90b77a870f31f9f5490b2ff493e2e4decd441ab9098a764690e2d76746859d30f00c726e5e0b9de79a2c215ede1dcf205458a5f2d9d78de63a8225bd010703bba46fa8d00bf9ba5ec83763bdaaa2f4463323f5d2b8a0a25e34efe1e1132ff84c91af10e2d5ccc4079778db58f5a2b9ea4da50d57b22b7dd742c3231299661fde1eb02dfcbd42eab1d23f4d037481569bf4063a7010da8d73d7dc389d22c8f771fcded2e1d611a1163892af717c15c717e87808c2c7f7e42bb92217d3c0faec16eec03886313ea6f43a8e9149a351b09c2c563fcd7b91bd40a3d19eac248b63f4997e06697686edc917f6e0822fcb2e01eabd1bb0fde8664717e8f80aef889bad34277e4d5eed74a772dba583e7bfbe379c450cb14e3d6f761d07c1db8e8c775d19af3b9d036fdb77f925c94916c79fc93c8e7318953959c4717475dd8f7a0bb28a63bbb2fa516f4596716c165c3fea2df5746db039107e6ded79d3fff47840ec724da3c2f0a9ed15060e85bf769d2711f93501a1005d925f1333f8f423f9357117177da3d3f99d17bb67baabfe7c07fdcbbd2730ac24636744a9bffe13243d48a0b3b30126020df00191cf0beb93f82db824a21703ac0f1df4e25b4c96ff7d11903f91d6e66a9dd527d27a0c7441ba26f33f70971a7991e3ba1ac36b2ed07eaef8b2f3a69ab56faaf943e220022ee6a3e5defcbfd3f58f0c4afa1244402fbeb122a0334c6ee87d9657ecaae0190846aaf452d3cfd77f64485d4566441b44cc42f23938fdf21b2ed48f7c03348c3fc41766d4970f0db0abbd35d6ba667d1edb7a9b87f0e3a35fe4e26be7e86f12d61eff25b9d75f4bd75601e7be99cef4b82d881fc89cb836a4f3d6645544903c8eebde38c2f27a6fe2deeba6b5ed0a6fac35d735b978a26e7859d380ee9e672030d72daf076ba779bb959e854dbdf62feddabf243774554ff6355df99bff8aae00819d5cd055f2ebba52f97c43ded355620e0ff295ae82b570ab9fdc5ebbd3df734d215f1a93bf221373d176ba7ecf8debb7fd5ce42fd2c3dbd07d46af879bc642b881d2feceeb245ef57d4dde74bf9b27cc2fb1cf6394d3cff540bdb781f9df6fb7ef71fa268ed192be49664c667fe12ce3f27b9bb193506d2f4056a51bbbf2ea09bc6badafaf0409aa59cdc9cd941ebf2762a2ef22ddc129d54fc65dfd7a4a8f8f973a53fd786d1f616ca7f4ca3e9a31ce79164de9053042e40b26b7b0662ff6d66c442e5af7979d230827e4bcde2f1200665c918b442f727a0517c9c5612de7d9f3a155733e776acee7cf8c66efecb9d1eda1b3e72f82600d45ad2deb0f89a04eb739487903fe154ccf0bce24c2a35e4f9d8b91876b9a28eb13527185e464303512d8ddae087dc474592a49d130b32fb8e2943512afb9a2792365c12a5a36522aae68456a1569f1c0880cbe39ac3c7622e01a6e7d24fafd11cee748223e1153dd19e571d5458d28ffc0079fe1e4d366795516c167e5e1fccf86d8caaf49641676849f56f2ec9b1787bbe6ba75799931c52e2f7d4827a4f0584cf6357a639794460b562da2692a92255b3dd0d36f07dd9f374eed7b3121b65b896a747e236c5394f7a2c8f1a8830800ac86a79cd2fef074308efa8328554f559105400eb04f6a33297b060168d5536d9382dabaeb31dff81f51df3dfbc6d272434bcc0d9faebf33475e8b740353277605b1178088f0e4c532242f568140e4d2901a9b3d52c37ca07585b8ca0f52184e3ce26c926e6a16ef0aa305d900e9836bd946c7c57275d88e4933bea3ab38461be0d2b65bdda222af94e6deae6c9a7d49f5bb08938df1b3eacbab3eb4b9ff555f7bf4866c923ca35716c9cf3a4dbccbd00d140191873589aaf4f9dfc897997c17f61c150ec7e1667c555fe19a7d4f0586518b28a51bcb6da28d9f247a319ea7fda1ff6005e3682e176c958521b1d21002ade278853826f6d3fa368de325ba211c93eb38be865f8170a8833bbc6cd3749bb6f4e7fd1e757d11c76e71046ad7c6251790d0bb279948fdb1fdf3a706408bb106cb12662340854e40ac8217d631edf366c5774fdf6915c9c380258604141d543d581966fb3ba96aefa2cd8a470f31ed797b5ab26e56a722eb3806633b6b9376d084cdbdb70276e3503523ed893326a1c61aee7f72e6fe19304a1e720d24c160d8390b59d74ea930cc9d1109d773f7a050b8a6b2fd076bb3cdb618ac9ee5a9e61f9068432f55ab5c082e238c81d2ac0eaf8145a79865d516b32cc925c9e2f8d2c89d8097d2c7a5c56022b32e14a64fb6114f825b6a1a5cf1c468f90de2e9ee41d346b9fb8316c2833634d3a04dc95afb1e7d01fc3f36caadcc97c8584ead69f9c73636d3db7a1d72ee19dc943ff2cd9bf2569059f7d60e38719f57cfffbcc38c7366587f4167ee061ea1f5765b208501ab7125e18e72b1ef30598f7952a972a5372833f2480411c220648c5f3ec8548ce318cdcced377337a415fe1393c3b600060eebe303cdeadba83f24337b13f94e4de9b19e8fc7ce28bb3e67e4dedd1c73e24723f5177afb0e8b8eccf47de59b38461dfd9f83dd1626993bd9d6adb5cce6fc95982d4abb9cd77f60c5fd600b04acc7552e3263eedef152a793c9d428dc5d847758b6dea8d2e0a3741b26760041f17168c3efd177a9daa5dc2833d6dd36017660cb8704cc475dcb5f6f2322a95e78a30efb45bbc0888c630976ab2ee0d1841335c5bb0ebab5eaa69fc922b43fd89125647c4c4e53c011cd2ab2aa77e8721cad8b285d02cdea89d98d2786359d7b4339ac7b30d3af77ee55f7ce0d45635e2242225d417b337b1d7d692cb0b3f58c4bdc85af72cc77981c0ff16438ad3d004a6fb77d3c0c2cf5cb7deaf7b6fbdd1c8f6ee318ddd09b80e8251b7a1b745ed0db36954a8a569a7c97b5d42b75d3cc7c7d69f378c7776e3de2c0307974e342d250a4a8cf42048d267bf4f63415a542fe5cc511c9914afeb1e6726366a094af8a02098cf5b6f4953573a028717427e06939cc3a06481afd21a5b4dc6b6145cb9e37f3a95e427c7671ad16718c2aaa77ecf9007e4a1ff5021339a9a63bf2b9b5e3bc3536ba8c63833c47bec6f1578336bf1b85c3d965869fcfd15d6d2affde8fa9b5c939d8e98ed1f4e330023be779395b5708ef7c9df478e8dc0aded03552e4ce6ff26a5faedea1f8f9bc23fb19b38e8cf77aafa43781042ee4f73698b4d6632ab6db05692dc8b4d86e17bbae4faeda84f095be5fdcadb277bd8eaadb5ccd1608b81f8e09dc2bf87ec62a1ebd92b2bc05a3ccb47efedb2a4a15fd82fa433cba929c7d1dd5ef8ccd6690198e02c8ee735bea393583bb53dd77d8678b3d527195c8abb78e27e7980433362017005aaa2fd237c40ceb0e5b2d98bed9964fbad98ed1e1b027dbedb1c367f746f1ed94e604984bf2f950df92ff2f7bfffadcc671250ce3dff7af18f52fa681700492b22cdb23c3f829a11ddb31937d577e36950742e669629ac488831e662e9421815bbacbf125b613dfb4f6135b91424a9464ddacb52c5372d583e483be50e0baea251057b150cf5ff2d639dd7303061065cb1b27cb0fc0f4f59cd33ddda74ff7f43967cb986ae7b78cedf49cda0131b30e4c334f99a5ae6bceb198464b7ecbe83cbc62c5e6e558ba9dc79cf99d4e647e971a067647705b29433c067ccd55ddac1afa64a9da73ac4fb12da3d9b8ddd7ee653730c06e4e659ca1213269db16a3b175d7191ada6207f6d99d1c108c36f9ca74d6f31d069b969d5b6c343c95810d8cae4391e8bebbc2324e68c3ae974c4f65d0101e539c73d0c49e8093b76088f6f481a75aaa597034373b9f9a8bd665528482b8adf9f4d616c29669ce4ed68764aed26c4822b0973ec56409954a628c146242f13448897b9bf5c3d4f979b58c240353a05c988560dc2066e0e42692ffa7c2f3c95072474f9a8f066a545bc6549a8ff9c44908444933ad4226ef1efa680d913cfbe2c40b187409cc3f939bd24e224992a86e198551a8e2ae611646a22826b41ce6b3aa37cc61fa1819a676574d900693230becad8cd6347bc5b2ec013c5d0fda45b3aa99c9cecf772b76c4aee0950b99f0802ae3e4996a26e420274ed0b8efc8db0ef53a21aa9dc705d58cbca8545d922d8cb147b43195c79de198d91fdaf5fa288aeae8a738a5a15e36ab41f6a82a55dc1cd554ed7b9df87a395d67ee846df816030689e6ad6760e5a026674edecbe1b625992835bbc45830333cf3c82363285598f8557d5b36dba5fa16d7188af015987620e0ee0c3a390595139c9ef450166acdceab6a8a78bb33e58a315e289ecf6491bff23cafd739dba704bb8f0c899522d94c8ce9f528878536ce795e04818f04e7f7fcbe34d0586e1f9b9ca5e5997fb6adda946959f57a86e50c36ebb0729729ce7995e566a95771f3c5921a1dc3608520922f96b27245cf89352ad4ad612ab16c8a37880ec44dce8ec24a92723386e5acf9f901c0cc8d033201504f4bf363c20262ff6f70a3720bf944daf71185212b455f8dd12b066e55afcb49e9d5eb7276d6eb5b68c6436f89199e2d785bf2ded010df92e79a134281956490e6e32363d90c7e9652c9049d1df471a9df3b97264ce58e7467b712622636d0eaf5c48df841746d7bf431f9ad72c776f9ad72c70ef9ad72c763f25be58ec7ff3b7dab7cfc51d9234f045f6fc7fa7ce28b84aa0ccb166027aed1fb552325c25c53ec13ddd0107b6aebd8d0107b682c9f1f1d1a624fe69f181d7d6cec8927b63dbafdb1eda34f3c31f0cbe77641fd63a8543ab22757df53cc14b4e2af8a7b4aa51fd63345f270299b296899c2963d63d9e2aff6ec29d5f7ecc9657f58d83396dd531a51edfcc8aff6ecfbe10f46fa7ed5141f664373b36381e24672686ec9044ddb020b1c71f173ac8c44c24ff87186e1fc62d96cbd9eb1039dc07a7d8b198545416f6888c51478bdc1f3eef1416c20f61a2479f12fa5143db4448ec3b04489e4f34eef4bee23efc739f0e0efc989cae93d1f77301b9855c7865ab0c30e052e2f6be563e6c4264c8e372214f65299a1452ec52ee3bec6d8a90052afc2146ef3add5a0a0c1e614c6e74cc7e620782953b68385a67ccb52d03eab5265ae4ba79942b9a150c34051825a4a8559b353bea5ec13b65add1c116e860e0871b8186b404935f2a33b337152bd50d776e42177643aedd0da2f1ac3c325dc78e5389e303ec7e52700e55f4ddb92178c85b5762b37e5d02a735fb4ffd99ecd8fa9d6fc8666a648ef6b953dca8165296e113934cf9e47672a91d5f441e3f3916df181598978540e85b8bc194b29dbd559b39f6b3237638a530f2f3b1fabe3d9338cbb2fda81a812678361e6bfb0e9a75f9acd4f49fb06c24a3f24658a24b3670ff007a2924c71cf9e915c295b40f6a1edd9a365f6ecd9379cc57026838f3d7b7275602a7bf664b2a5ec7076cf9e6cb6501f989d290effb050ca16ea993d7b7e98cd92526eaf6df20ca993ac4aa64952204c5c18511d9066ccfca86ae74755374f886ae4a5ceb865564d8f39f53a19213ba59f2c9ea739f6122b039791ab5139cf61fd99caf3e258092f86a3440d13ca1dce078a91b65a8135b1325c0e5413a7b2ee707eaa38568ac67735cf8a76499dcdf3e2b692aae779f191925acbf3e2f6923a97e7c5474bea749e177794d4c93c2f3e56dae982d82f9c4db959245f48dfe2bbf596fc6cc01aab4343d52df9fcacfa429e0c937c3e3f5daf931f62409dc9934257d23ea4a05e37d497f2b57a7d6ea7447200668ca6d7ebe6f0b03a2bae2ccfe27622ec2e6d9fb4da472d6d4675d82ca39ef6823a4b1dcfa49636a152d7638ee9ce685bb64caab3c2a593f652c1cfbc94d5260b24f743a291e2afc8b095d9971d26a5e10299cfce076643ec2759ec7c0fbbd79f743d276367d1f47dd419ce7caa0e3fe365db60ffe35f9e8b2be68f14f78c14fe7fa504c388f8fa43645858dbf9b16db0c08f8d741f35b6239b54d39bcfc6dc57b8ddd7932265d4d04d97d4490d251f3a3c9ced350751a425f4c4414bf1a9457e95296864187273b2278749f607442dc39ad6bbc1f4541a5163c2607741d43b30af5af90c15aeeb661de679b582ad853d15de8356fdfce84e3f22d50fbc9c187956f44b710b03e191842127893a95778b06725c61d61765be295c848c5c3062b2078c9c1c29c271bf9113a32cbbb36c73cfe43e9b4ff3a3f1f0d32fcde2bd0a853c3c2cb00c3f4c14cf562699220fcb1ececea3d83195152b9f91138333d531477f80dcf614515155267d08979939c70ce57f3d3cfcfcee9fff4c5e4e30a76a99a9ec30f95f040faff1eb74e8ac2ed9e6a0653bef9f9049a6b0eaac577b383b1fbcd64a7e7467e5c900d7ce0abc23732a53ce5b99a962a59455b7f0a25f12125139dd474b84935a560fde2aec4b456a30e61e26f7ec8b72d017c379ec8c4a2178b59a11f1daec70795e981242928d5cc02c0ad1bc9d8acfdb07376b352b33757f9df34d3a863c3c5c1e7e983c8c1d11f440d06805d2e643bb41f3699fc46316474632c5dcf00f0bf95f6dd17e70603e932d821c3eb2674f293b32ad923d7b7e301677a5e3f78391dfa2fd60cf082ca669d58c2ee7a533ace6e63d954525cadd672c2ec393a139562044232699ef3dda73325e563892afd7b9eae58ba56ce8b288c22acb053312d22c9e4d6fc9e7794e38d040be35bad38d38911b70223fcf8a6e29d5d6899fb587f356c68fc99353100f388c5ac91364a77e8c97929d9e5851fcacea4b86313494a90ccbb253c3956192fd21c9aaf670be92f7c3595df00346569842cb2350ae40b4a05a900469518ccccf0b39c0caf02e0924abcee66d294c6cad06ac249fcf57437372b0edc967660b41b151352aa8d9d96181bb0acffc0f0033526d16c80f8846878666f17d650a792c53ff4196a84626b1da90615b2d67781625c4f0ad56ba0e25535eae2adfa89a701125e016d22f6fb8b6ef94590e275566644f06769b85ecc834b2539e0d1d5ce547773a4f861e4e9de1e1ac1797559c404c4195da484a111ad181a0b2652c9054b68c85a20aaa8704b2ca5828aaa0f181706d35027b37aa97d5605757e896d3234a8ba5b4c55e8a2c950c2ce35845b63d8623fe16f0253a91840bc3267a2b126b8ff9e8401440119f67313128dc6f73b133d53167ef89d28198b13134df634e65bca2135aa68670b06190fb0348ca1f303547c57e9699da81f9f0c60b834af85985067555aa46619e5569ceca6f198dd2e643630fd53c5379ae9cf7549eebfa6c81b6ff6d7c5fa11bb49ed3452fed68d19917de93129d92e683526cf38786c4336e966c68a81fc6deb2c1175822ceabc9a0c3d0e8589b04d5b68c0a72bddea397b121e1dd151a90551f1f8aac40c1dcda0eb9bd12e8d050d7017af206b8d3b5c91557ab61aae69c8cd38f744725f21cbde73057ba279bcfaadb90a06ec192852c800a1f773c67641c95aaf18b36e158f24af378e507e95269241b3bd0473ccd7350d7e782b483e5e01b40daa9f37c647a24b842275cc2f39c3de8aacf3d7df279f85a676115e4199e73f363d9f94c3169a1c10b8f0358efdc8e7d2bc86cbbd7053e787d5ef04987cadb7b09f368c91dcee84efea4172a6104cbb293f78abcb4d3c945ef381f8fd4ebc0817371877330b3090e026272059d28e702e7747863addf64704046c16f8ec97d58d2a1f381f9a41d44618fcc49b347c6b207cc222be59d222ba1aba1782bb66c894755b3ab0d5b92096a266a9259af9b31ffb6e86ad14c36d1cc73b99483cc3bc71c57840cbfcc6204c6bfc43af22dd6eb7c3eab9a68ca2c74b597c087e8909a647a2111932c382b0d2aaa894cf92d4eba5d1bcdf762e8cf604d6c1e5e4832e567fd0ccdbb994ce2c833f6b5454e4c7c8da6f444b2734b0f737b806e28a5d5dfacb4a4a3f23cb1ecb2bc216c8ab48c93a7d97e6c1d888db3b5f8904f7a574c8efdc80b6334e625437412afcae97d5566f0aa02df5f15d3f56ca7867d2d2d0bfb6ea58b05d94131218c082e23af3de04ea16ff9602711ab326d27f8695476da16469f44a11fd1b83fc66439c8cb44459f11b709fb9596d961056c6018128c1f2d76259b148ff4149a96be6ea6ed942c243d164e2912909c8cc60ace87c339b45599676a86e78b0766584d23baf0ebf34238e2e6ba6cb3c97b29c190ccb3f9f9525678878c7c7e72bce2696740f051d97c269b8d65c68673d1ccd9932e73e660ac95d05568dcf7a79a5c9ce35e42632330651d4469793eabba19278eb8a7714533277c9e9702c63ecdbcd8ea37cedcb263ce7ab63318505675e2c7eb4e6cadf2bb64610fe586c2001950f438ef6a7c77d7c43a633eab81ac91e72a9befbd3203eb72301b99fce495789db9aed6e06c419f4c782d27c323ddee0c0b5f3c9aa4f427a17f2663f334fc4420bf72052f9865411c89de7cfc1b49d727a7fb72742c0e9ae3ee8e0bf18876009a125f6c7976678ad9b5d4b72fa4633cedce3b8121be4125333c9b9b322d8f39a91e12ef35c4b8cab2315e8d5f8b5427ddf79c1c5668fb381b73ce8c7671a397b493a3a74d31c8e34a5b3c13958a0aa8cebcca723e8f5eaca3b2f9c0d4f4bfd8bec79cdd9eedb054cd0c0be41459d6adf1f2b362d4fdc2f42afd2b19407e29fee927ef647866c73d953cfe69e487ff24f60b5b85afec7fca94b3ca6e931b0e5376db4ec577ffe9ff0f620c779932f1dc8bfff4c391c49621f50daa347f0f8138bcec142b1138687cce7d3a7c7b5dc67cc3c367962e1924bc7e2b6521274c32e9315ad9677a95d02d73b4f9eb36abcde27772627ded39359452125892dfc185cf33795449e864591c21b3e2a3a53c311851c9a3249f4fefbc9fd12a73332c5b1c2d4540a3397c605e1522fad8280ae75e91e86458a0ca4d3976f5c7f2c034c3b3a53cc773b4d1b16d8f6c7f74c7638f3f41b60cc4ea65fb7a24f584e82c0f2d48d7877f2792c6a1b9069b9aae987b67ac2ab7677fedb81e410f7f1e544c17cf4132cfc32c55d3eb47bd858c27d1f7304d9d1869d1bdab80c6f9f94cb690a8d3652035fa9ae8aa561e0699eae7c776fabdec12bf9804c50d74021f5ed80b79a55fca6669e0fbdd806d8155344a795e344a38109cec019c99d19169393fbab3fc6488a53c3c9c3503006eb15c1230200460f0197d52b37a3e69cb2fa3e8023018c2071206e541f408a68e9c36d1854ca5425df9758271259c20f1ef7129f5e3571fef09c10d26723e1fbb091a9c48c4ee86327514fb0c4b9af5fa169e1d1aeaadc16350d4eeea3065a365571d0d8688276673b8cd171d0e5276b250b280d8534081f9f92d5d8c81e75316c4889c4214d4cc689cf2bc398f84a4d58e776b211ed1ecd848cfdb30c8855293eae78b25d5c86f1953cbf9ad63f18bb9d903c6d090353494c15c4b8eb7829fb78235d9cf6a5049f5c3afb4954c3671562c3fbe055a116e662abbd3c86f198d71293f942e768ad962e57da46ae7f070f9496f67d61a1ab28ae552cef17926bb131146b5e62db1d5411abb345d9c7c3e1fef84e0fd27eedd323162a0ac5daf6f818d795a1d270149ed06816f049681b4c1e2c4074bef5071e24305060ade160a3bb12a854990fea77c1e789444d782792f2a379bc91e98a739ce5ef25eece3fb3efc1eddcdaab68e612f74273f35968dce7ac676f25e16279615be752c6e5c999776fa6267091805fd59756c4b3e7c6bf5ba51afbb994a765eadc6dde8f8bcc727f894cfa549b8684b8b6dcfceab34e7999ec5f264d2b1f7b9cc212acdc9a03c2ae673b00ad21c75a6e7f0443e37c71c340a4c48147145219be767a1ac119a5bc538deedc7c0d4143ec50dfa441991b4cbb28254179359d5f43030ebb059c6937065dacf793909cb0a41f4aeadc512100adbca6efbc93d2c76d6b1cbcc7583c28a2998acebcf028f470eabd25c799f91621f7984605ec5309d8d21c1a27d50f855eacea4dc901e4df912b12579da9eb8e2265606d82d592c43e814510f546dee555c8d3c4fb94f1d93e9cfb04947842628753c7dd7ac635afa0433f5e77d6e32fd79df3299becb9ff65dcf77f5dd6cd663d549e6e83f9ff16c78fecc9e1309e3ccc540288ee824ab0a7cbb2bb6e32152c0a74f083c0116c001180038800590002d01681f633306adb91ad96d73834e03b9f81c37b90bcf5fd84c04c66d6e300742ffead4e0b19b7a184f852749db6d738008d000120081ea5037b5da84c9a1923e0155f45fd8fab8adffaba3efa6c9d633c7344c56fd67eab84c1b99abd67975c4544df79f27b4dea13af22b5efdc148781b733eacdeef6b157b726c5b8117c85c9568e45f2788c60b8443f86713645eb56c3e3d4e3df68ced54a9a71d78e1458d3cfbac56ad12f5851777cbb0e6ba447d4123e3e323131323bffce52f7f49d41720ae4c4c4c4c284142324509c06086611886aaf466cfab30eeb8411ded804bab6c9cd63452fc577c6b8a5d2d292fbc485460be2263a2f1a9c312e9bf606c4680578a41ba455d59fe2730e91d259e212a145fa0d42d29c97a40c0d396cb34f20299571d66a10b7a588fb403533e6a0411db7694875ca2ce52d7d3c843ae32cd2c061b0a57230f736596524771d90c0c2f97a8aeab91878c5842154b554deefb1e51ab55cc86a8c7885ac14cdf77885aa9608e0fdb4c0393616caa8681c90665449d10a028da259d98109020c6885ac3bcbd943a44add5300b23f3aa416b3f9f9a8009f773c73039b5e4b0db631c1853b7cd675c8fd50d961d516d919d320415369c19cbe7f3ac5e7f5c3cd853f96da305e27a8c68b0bbcacee31cd00e18f63e6d4c35ec9ab67d7e3e3b9fe199b1b49d707ffe24b75c631a699f22ea368db4ff48d44734d23e4dd4ed1a699f21eaa31a69ff89a83b34d25e20ea631a692f12f5718db4cf12f5098db4cf11755423ed8f09ecdb0e001c8d8c11152069641b044e138d3c0281334423db21f027a2914721b04034b203028b44238f41e02cd1c8e310384734f204043e261aba2448fdd22b5c228d6ad86185316d1b3eb769eca1b1d1d1a7f28fe005f3d1d127f363a3854782d4b1b1c276edd17995e60fb85a91b44eb70fb78f2aed63ede34aeb7c6bb17dbcfd4aeb1c51491451da2fb7165b175b9720bd18652cc1335e72a9fd4afb3829a930245ae7a116e6632c0639192fa9d56e322eb50fb75f691f166484916e32828c908c30214ec6a5f6e1d6626ba17d9884f11076325e522bdd845c6b2db63e1764c86037112239244146e30488a4c5d61289c7cf75c54aaad185bcfd4afbe5f6311803180811035a9124918a481ce5e9f62bad45acfb9021e1b45f6d2dc6e3a4a44e74b7f6d3f689d61568050612084552d04a8c241086752126cbc663a4a4d6bad17d2e691481243a4c0ad0612489ee731c5cb285b240d84209b934af9a03ef4748c59eac54a675325e56b5f2b4c84a4508871e52605ab9a87f6a15394cb75256b56217d98d1153f844b3f3f86a8eb716dbaf606fb40fb5ce62b7c9e8b1d662eb4aeb1a34ea34e4b45f691f95e9f05a8297793c1e392a23add3ad9bad6badcf44f56badb3ada5f631008279ed23ada5f6cb32da3ede7eb97d28cabdd47ea5754d464bbd629913896576425eb263424f6bb17db4751a5e908ec13fb5ce239dc745f47cfb686b116675eb942e8b5e699dc5812f133e8177d8ba262217dac760d88b08b665906c14e08de14ce04be00af18438fac34721aa755147887aeb8adefa446f5dd05bd7524be36af6f44bb4ec695b46ef53ba19f9bf07df9880bf6f2ce1a40a385df25deb7abd7d6ca49f7847dac7d0d6cb06e53ad2ba4e34a8932e47c1ab93aca9f579fb78eb92225f2632b46ee1aa75b3750966e8e0b27181ab6fc148026b9d6e1f6b5deb0f3212c9ee017223c2198eb04b31f90cb858eb3226b89a99212ec9824c26435508542110862a10a840200c1910302010862620300181305483400d0241685e85ad28bef454a5d1e8026efb54fb8fedd3ed33ed3fb517da8bedb3ed73ed8ffb5cc955b83c050e6bb75e1b9956898af86cd79b12437d30c63d461fe85e37741580b75e4b4a743b50a21bdbf6cd44ba5edeb6d5d81fdb75b62ea0dc71a8fd8a0e7fed43c083f5802febadd322a57d54173c19b8088a3118800c9059a0dccbad253dce85f5380fd6e31c584ff0dfbe7bd3ef1769df13c6bf28f1f661fc8bdf8ef19f6e5dc4454542c58504e1200cacffc017826fb7cdddf02e37c99d8fb67f734fee2c7873ff925d8c34bd601a6fee5f72432037c29b61c2f4e3cc24da89c81d737c3352d5487c4b2037cdf15d43452391cc2eb7ce71a1ded04820aacb1d74247f4f6824908ce5263a12956b00b77d1ca0ca5d3444510a5e22718e38fa6df6b8290c71665f8c2146e2aa1e1756e37c27105403be1389a87a24a0b6aeeaad9bad4f81f37cda5a6a1fefc37764faa5d60511eccf0ebf4f840d62864b7f0366b8f45d30c3ff0a297893f96d32bf6fc2fcbea938189df08de101df363cdf7b048ff7b6e3e9dea378b8b703cff61ec3a3bdc7f164ef093cd81bc573bd077df2e66c9ebc6d9ebcfd839fbca57ab48feb39c74fdeb83879738aac54e4fd4edee8a09337f3eff4e46dab558b843133210199df973dd8e6e1dbe6e1dbf7fbf08d86876f34387ca3e1e11b0d0edf6878f84683c3371a1ebed1e0f08d86876f34387ca3e1e11bbdbfc3b77f84e3b32adddc2d6eee1637778b9bbbc5bf83dde2b7e37e7f47f741d238b5fbed3875c007bb59a21e89bf0ff683c7f793c44da1fbfbcbbdbf3702f7e622f177b748fca37e2f1707a43b1e98bceff1cdcfe59babc63fd2aab1c9ceff01d9f903bf02bed5e46513057c197a3c0c3d361a2546c16d1ad92ab283c0b6d120f468187a44235b1bcbbcdc58c63d44181e1b1d8dc57660f13f5fc14dc4569f977d2811061f89823b20f8e72bb2702c92b225885f7caa513e471d7d8acd39d4d2abd4f1743aeb3008d674b3e673f8b3743af76bdff5749771af46271ddd9e114f6ee3c360337472807e4d8d724001f001bc040eb01134c00590000e60f561a13fa2fba9a3e3bfc21cefce49d7d41b27ee9c74fef2d19d937cf2ce4985bef4978f68f5cf5792c9fa8f1bcbd578ae88eb7ff983c81fc43a7f44f7eb3fdaffb4de38b1eb250155fff1ae971082a8df9f2ffe68bffe23ac88f5f41fef825a58e9c173c7dcc444eebf404766d29f6e2c73c5a5d4ebe6852e9da495ae1ca9f6327de7a475e724572a774e4e79774e061a3051d988fd198d657ee724efd19c99618dc5812036c2ee1e7215d7e60e8d29d2dc39393777e7a4850c6fd27438a2515ccacdda9d93912a4d10af6229c5b873f2d7e6af314130be28a1224a006121db131143e44007862c4f4426440ead85ec0e8235916a5a21a333addebdce342bdf395977ef9cacdc39e9d4019ed158de5f1743bdef1e68e45799aea2d91f8cdc8f7ad7f60241cc44139b244900461f2b900038d188007f6f25a0ad19c1b0eac045ebf0134cb08e89c0e4fae8074923bd9159bbe190f749532deca1b1d19d911a9157e4a57add2be2d7f7ad32fc547e6c74b400dc97fb96554a51267aec9bad24a152af9730d1a8d2c0704295a08f53af40568f35afaebedbfc62f5dde6ade665a22512568f108d54c2b2cd6bcdcbcd4f9b9f8565e30950960d13850c679cfc3043951e57030c879ad79b37578f346f353f6d5ed6e3d1d5571351c01ecf3d32b030cc839e06e809f25f4d447b1a37b0304ca49e36eb8916bf9a88f6f4c7c0c2381b21d6bcdebcb5fa9adefcb4796bf55d1df3df827c9895cde5e6f5d543ab6fac1ed7a320400a23cdcbab7f1073b579ad79bbf9a9441261bbbdfa07325fe4a538f7771e1a1bcde7c786862030ba253f3656a0c5d19206d1a7f2db44fa93f9ed4343192cf1e4d868bdee887b23db46b3055a1c2b69b4b8ad949def5ee72759b4ce1f905b4eb27a68f5f0ea91b0b16fe8cd2f567fbb7ab879196884977ab979b37919fbfe26f4f1cdd583cdcb981c24ad1ec6a43f60edd513abafaf1e6c5e8d80bddbfc3288fc0774a32c084524288cde8420805a7d75f5049413e8be587d17929b979b5f62972149b79ad711d61b8975d3f52837a86573d6d3aad764abc4308db5a8a73db235b201af25dbf35abc3dafc9f64479518b64424a9b7a5a14b5e732548ab7683e2933056d926d912d095b10521ed22ca90de99414867485b48434a4cb59e158812e977dfac5ea6f756c402c49907379f50fab879bb791969bc81530881ce344f3f2eaf1808a2f57df583d8c23e2387293d523cd2bcddbd0c6beaf3541c01bf749008c9d7e04e0b80a08685e4e1060ba52e61ad953540ac5e6e9d523ab7f2829854c416b2e0b6ed2fc62f5c8ea6febc085e45bfa1292577f9b2d28853d25a500d2c9c87cb72c09ac121a710b8886b7b07a105ede71200d5f4afad9010a93f759f741898f4af35a2e45846c5ecba9f792236365d285c9e629e0aef04215e8e0a438d97c4fbc58789761762427364faf9e10ef3c5117a5c55e1b08c5e6e9406294a5e723e132565c3a2945c31406ad65b2c243a9328abe469547c4e351f1d8a145d095e4c8e84286ae4b9531516d9b786cef53fbd56e42e73724da36bfc441ff59524d1cd9cef2ea11146f71ca0327fc62f5b5e6cdd57795ae155cf37015572bf083bfc4a2888ba4a72616425c183d355cf070f1f37a44d4e6ade6edd513abafd69144c1005eade322fb461d27274cd383cdcb83c4d594e2f72fb2069404526b9ca040741588408088a1da88f8bafa6e1d9a75ad7939555055bd687c49c7b713d287ad219fe3e3e332b44f3e7f41b480fe87c646b7803c20028fd4eb28bee6f363dba2e02305107eb12df07c578c3c321e4119265b8142d2e51f5761f30f4ce0ed1143a663c70dab6fe038874ebda1af1e6d5e6f5e5d3d1826349721002bd5651cd0379a5f605af3737df5b7cd5b50e5b7cd2fa020acd8d7568f04abd975e082cdebcd650007f9b79b37615188126e356fc7f33fc5b91026f43fb940820f4a52258192bc41a449a2242112bd44dbe77403e7e7a7d152773b4a00f8b0d45d950b9d88c21a808b212e74d7570f37afaebe02ddb7fa0a14fe129230b87a68f595d4a5ae777dba2e5699dbb0ce2036894562905025c40dad565763abd5e1fb59ad628b557cadbaaf938ec1071d0396a6b7a12f560f29cdab3d0bd3695c94ae27b2e227b2417a6cb1fa1df61e2c56f1cc6fb6fac4969ddf29cd1bcdcf9acbcd1b2089803c046f38584024aaf4c5472e64fd41dd587da30bd00657a2d543cd2f6018c556229ccb30946f0467cb28c5dd6cde6e7e01ff8995a879233c76e94eaee2e27303452d18cac1e94b2cf1069ec020db3e149ebf882854104bdaf560cf07753f85d944a285ad795d2e6c12b24c82dae142277a293c978925ded8c84a01aca40e54d4816258d36ec0da78a30e0de973ca216ddb3f3436aa8a038df04443a81c2067bfdebc4a3474bc1cc46f118d3f35363a34c49fdc362a5607e824d44ff044a1ab10df16c6911d6a8fe5d197e8e351b165480e017c77ab4535b65afc4fcaf7f93536432d5b7f86edf39d2032411dd33531b86b9fe99896084fdcf9009fffd3df77e7032e835650e97f78a2d4ee3b1f78944ffa8e8fd13b6fcff8de9db7c3f8cfec7db1dc71e646b1fecbc4ff440352fb8030a00828012a003de0459c8809c00f3021f553ea98facfbc3b1ff03b1f70fd45ea508feabb1c3a49f55d16ad9a2ed59ff7ab54df6d4e9a8e398899ff943a0808800004a80f75a16a7fc6fd53aaffccd35f049cfa2e4b7fded7779bdf666391fc6a87bcb7e899162b29e34ad1a5bc1467ddfdb295a275e703e7ce07a5940f7b1bad93cee77f642a41b12497df6df2deac3897376c9ec88fb8fd4f7deef764c5ab7a773ea8def980b324800d1e60cfdc799bdf793be0ac5499bcf381f290ab4c429aab1197f269aa18b42afe042b1596a04ce521037968150d7f2b33cc625cf0509902f9158d08aa82fc4a9402f98646a0b3835c238843de84466096047913411cf26a485b905593d1878cefe2935d6771113fc37516cfe287b6cee239fcc8d6595cc20f799dc5f3f869adb37801bfd275162fe267bdcee227f8a1adb37809afeb751617e47d3d80282eec014c71630fa08a2b7b0057dcd903c8e2d21ec016b7f600bab8b607f0c5bd3dc0202eee018ef49b7b93f10b179d850f3b0bb73b0b673b8b873a8b1f61f87267f1a0de5938df593cd159b8d0597c1d9362d90b5fea9d854f82b2af7716fe5def2cbcd15958926517beec2c5cc5228b2774c0b078a8b370360c5dc59a9073bcb3f05e67e10656fb48c7d08900cc4718fe04c3173a0b97f5cec2b1cec23b41deab61ead9cec2c5deb2a7908a1b5d19fd196dbc23a2c60f6ce78016cab67537a9bb0d11f5098afbf070ecda0b58ea82204ac07f15898c923ee92c9c4414ef615f47191790b8c5aea4239d85cf8397b0d45938d385e03fb0d23bc1ab8d6700f151d9418b46487a447137a1117d7dc9eaa62622a2ffc2732fcce9688f6c1055daaab54ba968d5aa02e8607c7c24173091acb96e22e73e6fa0a84a0af4f46d484ad1f4b50a87ea87dd0b5530396f63dd83d011104edd9ba85d2b15563cd35525f6d155e48b6d807a3f8b148e84cb3043a2b3284928a4e11c7907f814ccb9779460f6bd83ff67f14d9e0a77017d72ab00e40d51fd131cdf62947f146e0b7ad22bb12aef07a08059863b859e7423566541400bb70eb194892431b73b0b37c23d442ca5162b76a1b3f001ccc6601311a56cfc4e626771b1b378b6b378aeb3b8d4593cdf59bcd059bcd859fca4b378a9b3b8708fdb890ff02a62cf911fcee6db9d8533751cd57280d5a1c760b22ee1ffe57ac026a37c596d2404f8aced3b5aaad7ad31d4ad467f68a35995847509ec598686d853f9edf53ae94219643ef928e625d013b9d919dba66de872f0f6420ca9c69e1c1b8584a8b9c1896237091a83bd580f762d06ed815de48c0945cb4277a1b32c94173acb427ba1b32cd4173acb427fa1b32c14183acb4283a1b32c54183acb4287a1b31c2831004429142d076a0c00550a45cb812203409642d172a0ca00d0a550b41c2833000629142df7536798b4e342d1ad8f3ab7af75965feddc7a17ffdfeadc3a8a81b73bb796f59eecc39d5bbfe9dcbadab9b5200aa59658e8dcfab473ebfd7e25deeddcfa03c0e8937dba73fbed7e796f756e5f45e08707007f0b4bfc7e40893f766effae73fb0a14ed8b081af2e90018c736987d18c35707931c2f9de8df0152dce69bfbfb797331c9160a7ed4b9f53196fa4dd09bd0e57a322f81ab2beffd185d6f61f48fbd854e776e7f1612df9bfd0e76f61f83867cda952ddee4020c2a6c5257f642e7f699cead9be1dbea2cbf3a502aee696a77f3fa3629a51929a4a790bb511285f0fc3d24b0bfc8dd2d687f73f1fa9e42753f511afa40f4d71fb1638ef688d5a2b1e130bff5fb9e5b8d3d93fe1de4128725d8dbef61ef8809f57ea947f6be7528ecd35ec17b10e8f73bb7de0ca7d23711ce6f9d86771593cce15dbe1da03a2de4f35ba703560a1446c238947d33181dc73bcbaf0b493c91fc7e17078a24f264312191df3a1e70a17fefdc5a0e9863bc76209cf79414f279f0867aea05727aac8010d553168fb05220b5c7ca08c11d7a64b9a77820bd63eefd88eecba73acb7fec2c9fee2c9fe92cffa9b3bcd0595eec2c9fed2c9feb2cdf4bb1e83b15dd6180fd7bd09def776e2dd771e15c966b2ca41eecdc5aa8f7f4fba79d5b47ebc11ab61c4c1f88d67b817e1309bf074897a89f465052e04f23ee9b88fdbd9404f27f5a57851b81540283ed402a6d5a1aae07b63be8bd9b1add1350c870ea4b115f8a7a3f4d1da86a648ea893f86f68643f091df5864e66bd22cb952bd4d9e56546b3a502d39209c3c21da2f09f36969dcfb0acc6e63307f088dae7bec7b83c56ae9afbc5f436d81cdb5fc15b952a4bb9021933614d7ec2f81c73f41f3f5cd9c7e61ce6e813cc77f657f4a7271d66e91394e9136c7f85cd31aeffc4f699c3f4a76dd7d37fb28ff169dbb2f5672169dcd77fca9cfd7e7fd9f6278c0b1c001f8023e8a7e7184005900011804958fd9c89f896fe82cf03222798537eb8c21cfd97d4f69126e6e8bba9613be91a0881f790080a8080da887e373506780ff1f517a0b8aca1ff645fb7fb908deb2c548aac54ad2abbe4a22fa29aeb624adab25fa4ca9cb9bf94b2fcf7e42831e009396040c97481e05973bf39a718b45b0cf805855eb7e9fe4a2233f12188767f001a67e587a3f2dd5f7f66a9cbbc3077236b36dd3ac9384fdeec7a78bf8debb4cf15ce26996f282e9bb6b9c138b71b9f87cb35332d9c33558df88e3217ce2179d10baab398e70f0c1b982c275678ebcb77149c74c18d2fdf51262d9beec71530ce0de42d8690b5b0987b2cefa9270a2ce33d34369ad53c98def286c358e286c3f6c435bb2762779724ca9ecb4bc34499c39cf9f97b3b1ba18d2bf539e66dccdb4881d0c615a29139e63d4007237d7402f2c87677ca1ee4f29698eb86d7b79ce1bca4ca65333e37a8f870cfeaf547c4637b3c97114d864c7911ac1a42f20a642f3338156e6028d130ca02af30b278350573502115b1acae05a5049c4a175aca15977a12a73d0d91b06825adb15038bda1146977a91734d13052001894130dfe03341313692ddbcb5c56eed732cc04642214e0abd552204ddb30b0fa40c24ce823596abe77d57263abd65ef487a54f096f58a1869e69e955ba57dfeb7353dfeb5ba64ed11196ee0a37581455f46c78727483451ddd60650cf45fbaf6529e034c394093033410da9b0334f067e5004d0e90e4007e0e80e700702e05687271885636ce8cbdccda4bf5593b08cee8be673b7446771d130688fee7d79937e77874469f65f0effa93b697be0649da393372003107a07200288750720021070072fd573ccef4595bf73ddd75a0923ecb74d7ffa65a7a7d2eae75df5ccbf52e71b9c177d77ab2d3173318e7aee2f728e8f99e43e3c91bbf7f165c13f34b4a51be3208fab10b668f240a89d7d85d6647b20cbcd2ee22f7b8a7e60777d2fce04a5ab4eceef5fffc3a7382067ea30b76019a59c7fecb29ab0b59771b442116b484dd5f4b446db3a73d1b1108f6d39830300b5d1ddcab9b158ec090e5830ce0a55feb067e18aeec92ed852b3bb2253fb8cb7d8fd5744f2e5a46c943468e7c57f7c2ca31234607e23a22d32809037b64c81d1b8b3a9d14ecd19c06c65543fe685b3a9db69141027f74986e973d1f9e823f3a4c37d04da0c312f33ed08531982230194c91c80ca6087cc6c302232698d3f044bcf844d4c6c302b9c19410bff1704081c19418114a2a1d9156ca78d11e2f15327bdcec30b083912eb5a169267838b26ed91bb96467e4748a4cdccb4127844cdcbd1f266e987e95f169a61ba665f9dcd50d1396267cb2b2c320b0d7f6e131c7b821125c974e7a6c101737a673ba61e574c3cbe94639a71b7b73ba01d4b903b8b731ad1b966e78ba51d68dbdba31a71be9f7ebbe05f34e3d9d2c1a2cb8c066593235e5c8322c061b138bb925c9dcad6425b587e72bf706606149a5074adad290a21843e77c53a10a19ce8c6dc9e79133566cdf7133d902b1984b346251921d26526926584d522019acdaf8f83e41f551d7112c71e3a0823520ad7d15d3b90fa2d2568d0014b302663d4b5d977af70176234cdd7898feda6f5c8c71f6291ab0759fbb627f17f7ee28a255dcada1b89d74ede812b1c1a34ac57668b8c5abd80e73c34d9e4923f78e26a44f08701894de1d996bbb7802ea7385f25a78e44979cddd806f47a7ceeb5ebd71b64efbaac548a7c4423c76a4d85c209c688f84695278865d43e32c0974a7f7912d78bc477e81817a3dc3f38492acca86f903be58482c6630ae376e72dbd127ff7292ed675c37fc49c6f599b93f7fe0310e92a333173d5959779d59c6f5fd8d537f39d9b8a8c3df5ec675cb743d7b961afaac63bb2667e504b3e2880a11211e408228f43fbf3e07c0e710ae802a600244009680e3e48b23bfb2983162aa23bf02681800881830fc497c02640c64007c5dd2fe0311e0341be695eb61bb825099896cd799c527928421240b4396e9e273d6b147cc924af323bfca6057d6b12bebb22bebd89575d99569a8825040591d3bb72e3bb72e3bb71e746e3de8dcbac50cc485a8000f62a9cbe6ce9501900023800008a89d1d31e3aef36387034f8de189f2d0d0d896fcbffd5b868d8c8d26bce4e390521d31b2699f6d7db429aed79d02996d9c0a6437a2c563b41aec35ddae3a7438036405fbfd5ab8df27598d0e93eeea89dd7fb08d7764d00f36edb6dfbbfb4f62c362b5a0bcc025c085a8123bfe8adc0d3b3208a83010a28aedfa93a8b0582d282f500970212aa3ab1f0d867b7dceaabd270249e006423678e3a2000cf19d81625e0266f5cf1fb88d8b6568b20885c02726fa75922c18d5f9cb25d955221a1e2074e172ec19a2c17f88a356eb83c3b167a00516932fc1625e2de538a11c3b4ef012c22297b17f61d3ec258dc6f3ba9290158ab470fe5acce054cc62da3599f1c9a99cd4863fc96938b5f1c9e97d4c71d799e5b467a2e393d370c2fb29535f04049b8a35aeb739df9441c4a564cd4191722291e202be6452e224e4cf1f584c9fb539041a17f5c64d8f398d5bbaebfde5a43807f1e61c8fcde8b38d53f070ed7b9f83e8b336c0d15d0faa434dddb5ef75f631b8c27fe13947ca31876a893a3901a4cfa90767ae32d77de8b1bf71d173683cfdfe4f3de614f19e4c09a66b7f1f160bc4c3b9d46391391028e0a5fa0930dbe30582b79d28f1688c10310a12d93b62d9383a02f889c391399851613fdcdfe148001f78bc65fb1beb0d2cdc3837b84f0288e91dd3d57a01f1561ac41dbd10bb7ae2fe8f558022297fdb2074db6a157ef057811ffc19f083bf09f8c15f0d7e35cd7e0007270fc8b15b792e7698dcbcf9d55bab075153f4848ee62b0e7ef5d6ea21bdf9e5ea91d59775612a25d06bfecff35fbdb77a70f57073b9795d5f3db27af8abb7f4ff3cbf7a44004045e7afde6aded2577fdbfc127590bfbad6bca9a3759297d1f2c0d5fe27cd821049c220f449c442bb3a1d653fb5eaababafae1e5c3d842ae6a838bd7a04201c86c7eae128e1d5d5c3d83107a3a4df366fc960f3e657effde779540a4e40791da3d783e8cb5fbd852ae28745c240656ba44bd221b12346894bc2963007a85a5f452812460041d6d7575feeaa7b9ffa7b5b2726b646bc5c1c41c0ab687eb17aac79437e612dae1e697efed55babc7be7aaf79aba48c17b73697bf7a6ff5e5afde2b498e7fff1553cd8b7c73307dd4bc3f6a5e5e7d03eabcf0a2524445df63a8357fb079bd9450fa3e2f4c45f42918f1d9afde156364004479c7eb3f979a37560f37afaf1e921cad2f6459a1f93e4ec65b5fbd37a8c206185dfae7ce9108d40f46cc1c7b899551c844d5ed5b441b11dd9ecc83598eb6bcb077d0bc71f0851aad0ebdd1fc02e694d0f9fe12e6f356983bca7f9e47fb0b37c51c0c0f35ba93ab41ad988a778ad6379e74c882512b22f5ef58921141143334d40397d18908921c54e1494894500b0b894e09cf4464f4de3ae0628026960099f6dd9da0c73c4a91e76c4ef739fa8f2bfbd894633bfa04dde7787815c6b42c7d829afa04ab4075fd27b63335c538a753faae7daea74f30c3d49fad190e9bd25fa4e5ca3e6618fabf54e8f4546dc097c5e76c8ec80091bc138328003cc005b000154122b83eec7cbc6618ca6edfd231f082e57311920d1061e6942bcc1191e7a82f02f2ce8c00408d7d1bb83803d081e009e6e80067433767a0fbf409a63ff7ed2ece7c57a690376eecf3596618e63e8556bb85ea5f4ed94e2d911ebfe012a4c72ec4183653e2c989fb33e63ee655e854586023a25a95edebba1053e34ae35361c7b356aed40c735a61a6655283faf1db3026953ad03ef78de8c054c42a1aa1fba2db301836346298fb1c6e1bb1935219c78b68b19352539c934e5afb6a8651e3215798b26a9c19c6060e4ba79851a726afd3a9ba69d56b865167469d4d0fb409414868dbf2a96da3052fbf7d54dc3778543e77c8e7e3f289b682f2ac40a6984134424d4e34f6d4e8d050c6cb170951099d222a312da2929a6184ff2cf937d5f3cfa693c17bc521582ab2525665c3de033baded667b061d7c99c2ddc06d0a266f53b0e036050b6e53b0c1b7290053cce831620004001f804ba3c77300ad0fc3731b37b841a7f52ac587673a2e3c6d8e0fcf16d12987c1c36adc708c3ebc535205f000184002280002aa63ddfe9ccd6ddcd0ab54f74cdde6ba67eb530e54788036e7ee754cd0734e503472a5e4614171c6ca0db6f7602a069d56b05892a5994ad576a6194fe6093e35dbf893dc738699116f3395e9c69f1c2591230536f971bfe846b91be16d7635c9d95cd3601c19db54e34ff24c9839b10f4141425523cc4bfb14e4416e45238c2b9e59652183838860718c43c7441c8e4e33646f8c2bd5c69f38ccd980c96114aad5105de34f4ec8e720fcb7dbf8765faa8bcedf0f54b522612667ca84b89fa662cc09a2c2cd2c16d8ede1c5b9a0808c0a57b0cce4ca8b745a6656315c822e2bb261023146d420c4a53757a8336173ea85b544ac04fd89f5302e6b8a3097ae59a1eef3b4e28455315282dec69a10951531c84929bc72ed156891978aa3250d9f63a59e536123661d963c2ff8e233922f4e34ce38fbf55dc81741507b1ef8e2f3c0177709beb83be48b3f977cf167015f1c67fbefc1179fa73c07a872119e5c2f9a1c20c901fc1c00cf01e0fbb9a0b0dbe6dca3d33a8c443aad8f9b8cbb18373d6f9f5daee8e336e7ccc1b4671c66c27337ad427ca05c68e7f4093ba78f9b397dc2cce9e3764e7fc6c9e9bbe9800b0abb6d7dc2d6c74d7dc2d4c76dfd19e73b110bbf2543edbe6036808d5698ef31c5af8a5deeffa8385d1bcf1863956c3559b65b644ce646cc759ab91e73ba6bc758acc5bcfd1ee3e12daa78b97efcd58c4b8e73b6137c6487e9364ba9a3ec161c95872c364a90b7a92051f00e4e828b5558d093e50ccd0bee5779c1c52aef41dda8dae48fff35fc712b5015b1c8c619e017ff553cb2716693496e32c94d26b9c924bfe74cb25cd99423bf118bdc20b7dbe48d9bbcf1fbc11bc5716391acbfbb7e61fdf0fad2fa89f585f523ebe7884ad65f59bfb07e74fdf2fa9164f26fd617d78fac9f5d7f6f7d09a227d62faebf83a5ceadbf2e927eb37e111eefae9f5f3fbc7e590497d65f5f5f583fb17e56d4b9b4fedbf585f537d72fafff5ed47973fd0282f9fdfa85f5dfac5f5e3f8a0825864fd68f63d6a578f2e1f54fd65fee2dfdd6fa5904164f2ea91cda78627d71fdd5f5b3eb27d62fafbfb6be00a50fae5f5aff8d0842130faf5f5eff2db60f938eae2fadbf1a058fac2f22c9afac2facbf265a72707d69fd38662d89e827eb87d7cfae1f5c3f2b10f71e5dcef5bbb8e5450c8a7771169ee41c4143f4807c3d205e0f48d60382f580443d20ee5b9cef8d7cc74e7ed77fb37ebcbefe9bf557fa3bfa85dcfb72f50b308926eaa533aef5dfe09858587f757da9fb0c1147fbabeb0bf04cfd34923c3984018ec3ebedf50b3d6787ebafac2f6281d7d697d65f5e3f1b7ef2ddd819e2fa6beb17d68fac5fc4997362fd6c8c61c92178168640c0b9d6df5c3f8be98771b4c318f864fdd8fa05204f3031e321a5bb101e38627fc028fe7d50ba9a4c5d0aacca22296f619361bccbd295de9ca5c0ce2cf4f1facbeb0beb0783d2463cf54da05f7c8581711d959a08528212354dccd88338c565a95a327549d8a2dda0f98e6fe2cf37d54bef63dfca317d37c36056c8307e66574d8e23e3694b232b2757aeacdc5af9f2eeb1950b770fad7cbef2e5ddc3facac2caf595ab770f75277f0891bb4783e85b770fde3db47269e58b587e103cb9f2e5ddd7576e25a35f44355f5fb906d0ef1eb97b54249d5eb97ef7e0dda32b17579611b52cf9d1cacdbb47effe369ef4bf57beec2ef5f6caf5959bc9c41441ee278c9b29edbe828df8f2eeb164bb63c91f42e4eed1202adafdf9ca17b1fc953745f024d6bd15e488e81751cd63d8eed765bb8f45edbe2e89972545bb7f134f8276779512ed4e24a6b43bdd860a2b10615083e4f35e6d96d9538a373434322e5da778318b1ba3aa9733b9c15efaf954066d71936c365bc00b817a77d716590e9332d992162f111f761b29d3a5bc26de977c43f28dc8372162af847d1ff6baec6fd9c7b24f653fcabeebf3696de5dfef1ec3577c65e5e6ca2758f6ee31189c770fad5cd157ce4067df3dbaf299be7266e5fadda3725a7ca6af7c0c8310df2746600c5db97b04ded1dd6300e8f4ca8595ab2b5757aec0eb1fb40b101448cc02e3e7121b00bebeb22ce103cc2b2b57fbef100012c24128080321607dac9d1c32f75a0f9f1a1b2bf00259595e59261a59f970e543a2f102b97b50c43f5ef990ccf75d7857d0324f860d1392cd79f60bf63ee6fc98ba2c932d8e967a56f222402bedc915563e2cecc91546cc7443225adc8c8836d888c820692304d4e74a84cc8fd6ffa7adb804b0727ae59395e595ebf0ce9503f3dd4200303dc19c1299f1cd4a901e89022b8b2b3756aedf3dacc4b3367a4137bafc0aa34d41aef5e5ca67820301a5c000830d8e44d0654103ab7eb6722bbdf2675d957baed38682528a5a97ea08f5383deacd222ba934ef0d0d7981d29c3c70c86478dec99ab0bfe665e054cf4878f53a29da937b59d90b934a30c27e8e69b959c7f66c606e39cfde8dbc2c57a69695e1d9ecd050c6c93b393a3b6bd5325e36ab3ae1824c0ecc13953e34b62d9f1f2b1064d59f114d043ebf7b18d6e974e1eaee9195ebc94fb472a5b885c214ae03d756ae282b9f4a7e72fdeea1bbafad7c2197802be1b6b07f81aa46562eaedc022032f5ee6be137ddb0e00514ac5696572ead5c51eefe164664f86d17a3d7ef8a2b6fb2c8cab2606de1775e9980c5260294770f43fa2722187ef7954958b4162b7af704d27e0b17e3e0437098f8f9ca957b7f115ef92cb1615df9ec3bbb0bcdf8d6dd3fe939aeaa05e755357d823ae54a786055d39ff739d39ff7ad5aca8155b9e7c0ea5e17429e47272193c249c8ac13600004001f8003580009d0fa1a86e206ade913363e5ef4990bcf5f30838bd08b15dfc1c0338e098fddd4f31d83d606df76e30010a001248001d5a1eec0cb6e13b6fea2afff82e92f56520ea5be9fd7da5eb40d5a537a1d58bf68576dc7b1f729bd1eace5c5b61e6fd5bfc4e3a538b8d816ee05ea7a01e7bc1f2fd566d7cd363a2d4c3d51658aed535c56b6b911d70396f12a9490f67712b73f98d004a65c016e1b5304f61da1084c15181dd1dd8f9ad003a60a0edee8e6070e659cfd54a9311addfb80c84654815dafce8dba63d4bdca3dbd1ced4c1862fab77fcba0cfa391b1d16c817895c0811171bdc07711e186d017f60ac4318806a51e9cc5a6144e42fd4d4ef2b7e4247f3b8170939b6c729307cd4de2f66d36b9c9f78a9b0013d83a31b1757c3ce6c56c5cedf15c269352f9495a814d86f2df9ea13c28ee313db9c93d3677359b6ce3bf09dbf80ee510b3f75af82627f907e0249b8c649391fcd732126b9391fc233292ff7622c926e7f82e772e7cff269bf89e9e7b6c9ea26e0a1d7f574287dda3e96f07aafe36eafadb42d71f227b6dd4f6b78571709dfee522f0133bd0f8776ca1f1efd8817d705b6afc775959ddb8c6ff5f2e6e54e5df30ab94fff937b66ef9dc40cae19f39330e336cfdcfd7e95f2e1ab62ecc6a1bb6eed249eaa51bf80bac6a9b558085901090000220a0f600cbdaa66ef97a95ea550655f439a6bbdf42f4e83e491d2f6ea58ac18419a7c4816a4a4e9a2852b428da7bea53b6f7aa119d2dedc9797b72d511b3efeda559bc331cf9a54ade60dac05d6279776a36e7e5aa39a2917fcebd989bc8e1fd291aa4ed12697d2cafd88649ff7251d9cbba19e284ed4c77e7c4f961901ef1c3674de6c46bc4b8e12c754deed18021062536c210676dd78bb144ca3dc021af130b9304f6de2e1b0590500daccc26f92164553452b11d3b6ea91a920d8d78c86e252f84c85e617bc5e630ee63bc9022a01a4c440024592144f6de9b15d2c42d14fac0ec30492b2d8cb3846f156195bf96f0ad326d07be5522b3fc66976f158ea0223633096ca616b199695b7099b2e43266b9d72a34e3c206f4141336a0abd4c1279d7464bc86cfbd3e974f4be44f0b23d22e13f69eedb2874f6ecf099bd26639b4f1cc3873ecba709560d7abd4d96fd7d14d42bd4a6b761d996f1d996f1d7d23d87560bd267a3ea84bcf08756ecfc914c32ccb10e36c4fae0090e151a50e3ce8a423623578ecf5b9785898376dc3c365b3f0b0cb1e3cb83d070fc32cefc915b22366ef6a1277c2838d914e269021efb7432f13b5ae95041ba3478d893b9a90296163fa2e25b1e1e5c4eef28e6c9d9898d82aefee3ad9024fdcb14d44e6bfa16ddfefeabd0d36c1fbddbcd46f679dd7b0ab269fc65598b9283fc0c36c9c73cab6c55c7dafcfe698abcf99cc81026ee3d4243506afc3763507e0240f005830f5590e80e410c220371776b0189bfa5e5f9f33a1c277ede7a2182cac7167172ff4cd4b735bd4bfdc069d5454ec9a42158ba6ba5b70894636e6a1a24a1b5728a7f705ea1e1e2a360668907f8a1a73364cd086bd5350c3de30d08dacf62cbefda9d0328b1c53d8e8990256f7846f0a9910f34ed1bde2f7f74f4123ff148d8b3107158d8bb49f870a1679a8685c89567e886c6013f47f6e2696feff73f301ab4c6eaefd7f776bff56c3de5cfe3797ff7fd4e5ffbe4efdee5704483f091c5072530cd8140336c5804d31e07b2806f89ba7009b62c07f4731606262647c7c530cd8140336c580b818308a62c08e076e5cced58aa4dab8ce59e4be19e366e0125025685a4ae67aa404dd5b64c3a1877f350a436e552b92c672457af407708de519575a872e41e7a3f9b720370a7bd2921d56f67ccea1aee77343a16c9a067020010a560418594e060d531abb4318b38d336c2eac883169d76ec6f715ba17b23014033fe3fb31eb76105365c09076ed1034a5ae07758227d61591c8c29dcc0c835eaf85bb6da5e01958bad39c7bdabe635ee273b3b07c37c702d3f28d33a16d79f445adeff58575f9bee6e5bbedcb7bee3d0dcc532e30c6d0a5e14244b10fcf5eba7b648dcc36962b145f91cedc2a7545d063a66b8ae08c6d556501ceacbd32e8306630dda2be78bb03d6be7fd69fd65fd47faaff4cff17fd85fe8b5cff62df4b8ffb2f36ce70aa767fab7dd6ae5699dafd9db6f87ce38c335d35398bd9748a3ed73e6d5a419dd897daa799d55563238cfa219c6e0e75bdd8d5158f4e53d7047eedf5f710ef056c3698bcdf2333743df330ae87eb3b1e751cd3a2baedb9149e20b1bd64539dce9a8e889bd4db4f7536434d4e757fbf87c5e8a4bfdff3a96e3a18f51dc7a43add4f1da83ac9b8e1d3fe13d177bc1c200c3676b3267a5ccf01921ca080cd9e9f03e039009d03c890c6eec712a5394db9c1a84e5d8f59acc2b80882442a43fb6720d1763d587231603ad4a2ba451d9f4fd2c18e23cde99c4e610b8ae4e5747b3aa7db564eb79c01d2a839ad534b874de87edd9ed66d4bb7d29d487c0bc394ddb746205e9cb185185974182f29e3451a77359692dbcf9dd880a256807aebb8f0ef1e2f2f515aa9e92184c03f7b1257bc4c3a4399a6be034ca0c83cca139ec826cd0aedc94ad8980b32229e42bdfd76a92b473216ea3b0e03b2ba2a6f90bd4c52c7f103e662f8cca2d11d1094fa9449eaedf767ba85c1e822880f2592c2a08fb2a0ed18324fca8290209c554cfb5ce448260509280a564c8b4e328f895c29100689422674825c291442c283705af1ad2e871c18d3c8d75788ba4d235f5f25ea231af9fa1a51b76be4eb4f89faa846bebe4ed41d1af9fa3f88fa9846befe8ca88f6be4eb1b447d42235f7f4ed4518d7c7d19f628f903004723634405481ad906816b44238f40e053a291ed10b84e34f22804fe83686407043e231a790c023788461e87c0e744234f40e032d1c82899ef61bc537195e5bfbedf5a6c1f6fbffcf56bed137afb50fbe5d615113cd65a6c5d695dd35b7f946947f5f6b1f609fdafefb75f6e2db48fcb00166e2db65f6e2de9ad6beddbada5d662fb58eb6ceb8ade5afcebb9d612060143947ea9752d88f4e7cddf27c2225efef56b7f3df77f0fbed6fab47dbc7516105c6abf1c45aeb54fc433ff7abc7d02890d12dab7dbc75b1712f52fb48fb53e87804c19c4e9ff36c871bdf8fa35bd75496f5dd3ff7a5c6fdfd65b17f4d6a77f170ed2ba2e12b60fb7ceb68f2aadc5d655a575a37da275a5de3adbfabc75299ed4d732e9484a59719ac73672bf106d95f6524034d20bb7cf0283c3f34afb652877adb5d8fabcd563ceb47da875a575a9b59852207ee330991b2d3aad4b5fbf968aa1db015cfbf6d7afb53e2d7543dac80ad4bad4ba92bc982d80e10af4d7e3ede3d017e761fec32c168b5014578c87701d82e9a0b42eb50f7ffd5afb3014938b513ca91214933486ab5294600445b0d1e1e21444276436f01d802857a7205a8b21681f0d972719ddb061d2e2d797b77efd7969645acda414e445569acf66bf9d1dd33d461fe85e37f498c5d37bacafed6389f5b57d2cbec0eef8563652e5b7176e5b16556a33aea9cc50fcb7ad2a536013db38a3cc992624f9be6b2a2e3361e7dd38c395195a31d88c4bb952c340e34ce43352c10f31450198a8044a70a212ac830140000181034273a629f37c1f035ef1b192ea151f87bf274aa5e884c8c930d551a96a8a13223b4fc84e6900900abb7fc425d27a9f621648d5f73d5aa55c1c107193132d4813499e297c651337512f565c16a3b25c3501dee4beef09a8180cc155ab44b3f3e94528d939e9303a234a56e200bd00ab1723ad5291b092b94930461ccc6ce38c39077dab054109ca3024a8de125026066f220e6fc6f76728be1a4d86dd80b8890909b1b78ce72549acc541cef9b6283be7db21b05a4d028be702987959d1cea77ffb79726cb4e014601e6b30dd34369f61aa991d260a19b67b8ea8a6cc9884e6d16ad59cf17dbdc22c11a8526a992e26f9150f933cdb9fb12130c3dcc61951dae422c42ccc716b35ac63d9335440711c8a297b6ddff2677cbfbf30863408022476815ae0154825464087b81091c42250f4f394e873ee738f22684e31e499a60bcf19e6ce9873a6393363a3cf44489b65ce5e51caa23e0606fa4df4a5ffc319a67bb63ecb746b80c3867b964e97687231892657ade6fa9d64d962cbead1e47798ae645529ce5836ec34733d22cee0a29646c6730146d8c38af24a90904ce9ae1ced7afb164a974abcc6190e13949764e1a44452f1ed2ae39c76e7c6a589302392449869b104c4d8fe77ce34abf258ad9804bcf103b6c619d76b9c49786cf43ce1b2d10191c351abf083bf0afce0cf801ffc4dc00ffe6af0ab69cef7e7606daa579f2aee39154f9b1b1783c3edfbf19c7aef83ed6e3d2a7380e7d47e87d9c80f0c3aed3b7ab5718a5311f41ab75c9968cec8ec4ae39a4c9b721a17a7a7f7cab216ab4d5307c3835903470c081bc02240840520067389c629a8a6035b6c5c43b7aaec6f68242297a6449536551baff773a5da781d7da99aa9be54fbfa516dbcae4cef6d9c4af7a4ea362e362ebb9e5f0afdb06e7c8efaddee540116e5a6f4a87a2afcc096d05532a53f55537eaff47ca7cba7aa297daa9a5cf11a17ab66e455b571b14aa55b5513fdaa42ddc8b32ae44d48d0302c1b97213f74af8a29a6f4af6a7a9ed23815f3b07aea6fe961b58741384906316732479f6a9c9b73202058c49cb81e03f3d784096c5a16f3746a37be087984b81c63cbcb31f26e4ce35c79f0dd18449813e87221b25c12572e862971a5aa71ae7c3f47efa89159ae30d4c834518fd2d4abcc293bcc30f5bdcc37cc401fd3d461541a036509c34cde00614e0e80e400460eea0fbaff1153c9dccb523432fff627281bb610b1cbdf6bfb8ef17f0f9eacf8a6d2f8b89b958cb32a35792223ce4682f4a4b2a3124f4e789a670e8fe76f847b1894bb31fe615a4a4d09cfb87fed33ebd73e73a5c237ebd60067c19d073648091cb22bcc7722bfcc180baf3decb563fc63afd01097d71eecb8f779db8cae3d44bee729df88163873eaa9dadfaa17d99d97dbcef1707323d4c0f3ac409883b74842abf2c1c60a9fff8f7c8e8f8fcb90d10f042359b13fda274bfe22a5a4c344c9f9ef4c917cca499ae3dc646dff38acad47057d93b5fdc3b336b601de3698757d672cec81f1abca26bffa87e4573d473f9bfc6a935ffdedf8d503d688d94b79a011e378399dce865c235488f1a703859899906530b74721263c3272bcfb3d32eae5a7b52433e56c1f754c57687e886095528108592a351920ab01b69a3c01f35da1fdd17d0666066760e6c033b007a7fad18f91ba9c995cafda941b4c1c94c3739f4d39063c9b4f330783530e6386ee7266f381c760664eafda39dd3373fa3e78da397dcac9e9ae3dc8ebbb8946cb4cfd17b6fea2f06c9cae3cf1ad7828487cdf3d0fadecb599a1d8d56ede59b5a9c313e9715e18a447ac73afef7acc51e219f220acf1e994d3f822bc081ad6dd08ffb499933c09b36a78464d4caecc3271b7dc4eb82d8e12aa1a31191e85356e76ddd6121e8c31db6631ce091174648c590633e367604cdcd74298364cb018ef842847f609d97b4d161d7f4104a06ec4ac19ab1be97c349a4d92bfd5eb8f8b077b2abf6db4405c0fd89dc1be435365d3b1ed65913c4d79e394e910953cc3e864c5a14425138d530ede69df654e3aac718a1395fc8851cba326f41699689c33bd0aa3d50a51c9738d9ba64554f242e326a72e56872aca338d6bd50a45c8e38c9a0ea346259eb89b420840ffccb62c6a4e9352820949d22461015592284950404b3719011112b7c426518578fa30a722196f9c53c6ed6a8553731a6a41fc055f100be109e8314f467edc38470d6a0799d4894594ca2e5b7419447653af421d4e4a5dccab48c6ed2a90eecbce078201ac84485452d9656323bc5865606150156b8a8a504f62c34a588794be075798d258d6739c9bbe42a7bb59d6ae6ae39443cb954456c2f0e27437d77a8ef3c639859ad3e9229fcb6ca54c4d8f95a2ca1b32bd98645a8d6b8a5b3105e32a376ece5a54716db36cc64ff083785523bc71cdacc2e80899562c05243e6a3a0ae54ab962d9e674c8bcba930d8d58f06a2507c3f08446aa8d8bb193fb8bc8b4262d1347a96459327a6f8e65d439ad57fb1961ec11c90ca2b187c646f3f96d05c229d148f5bb34ad386dc4f9d5aeaaf20cb561fb4861df497671e5278c3a0ec8ba9039d1f8587009aefcc49cb49848e7ca8f1b674d2f8c795b1bbf9bae564cdb0de2cff9e50a7544ec85c6e79cba1ef217ccdced23ef13d1f1c6c7010f13992123c3cccf272b162d578c1e7606641395fc042d6592804e2012a7fb5964634816b0331f5b0794c024f62dc16e3ec64cc9cc10d706b8996934ae22334390e3a615b032b3daf8583232b36c5223488ef130b342030e66bac0bf4c87b3340e661a02b6802b400a60028c80d0cbbe1a5723fef5317404f4d12ee8a167e9f79b7dede25b0dd39fae446c27c6c2b662d732e462663f3666f6f03180d9387b0f4656a1a65129c5ea6f8495510efbc1183f9bac0028d3e63cd8c74e323a4db96298f6348d04b1208a97e66d4e4d232683611c6795e467092e8619c0be60e0440c4cc490855db0633b5788511e3232a3020b798c9561c2df3b338b5ba67f897266065afd668f5abf69eb2ff98d2bf06f5931b5fec046aceff9f76923f6a568cb1b330261e6100ffc475620bc1c200837bdf7774c16a9ad475aeba8b4ee30577fc9469d75c69d6fa6b2de38e7e40048704cb65195f5c639fd251b0fcafebb58ae7b8929a97ad78d532ed148e3d4c695d51ba7ee0bd2405df50180e8c654d56deef56d590a947e8aea76979efa0609db00b74d6138a368d7377471ef73922d104e86854e3b1966f3a152bb19e9b47f5b95f6ca83d669e7319576feb7356c730f8d76af621b069347b094a34c92488bd4d81385a2b8d46467336847dd43d991cd0467b8093d762faa8bb1aa546487ba73b613549db39d98e23a6604d5205295aaeb50cb30dda09681729361885a9811d412591301951590d5423a2166c754d983ec90528c4b9d7649a91b23d576639aec222f46ad0be4762bb30f50599fb6ab5b2deaf1a4cb05e6a0c305e6e813d471f55d93c2db8219f842a0a6be0bd63d7db758f6f49fc3a2271d2d38fa38db0fcf816e1672802117c2cfc5c1e7007a0e80e700720e00e700eafd2c77bb4c8f3afa6ebb4a1d7dc2e6d396451dfd47be31070f87b998ebcf3858883f3c47075ee8db657a39009603583980930328390001197cc062b7cbd47757f5095bff91afff0890eabbd34f4defbdd4ed1296518a7374bf87faadb0e88944cd7563e9f77bc4d903b8cb536591962b8c9694715b957777bb6bc4eff8c6aef87615eb23b49bfbbb65f567a8c568cff968f139e651c5936b4451ed96d47f4aad9e13d267a8677555d8d84ddeb8770703e6d8bd15e4bd6fa0169f61ce37b969439843eee37a4dbf2f3aa91f70ba75db1cea9975d79ea19665d60d9bcf528756eb2ee57bd94858f659db77bac89748c6b6c1323b349461f9d1ac4a001a411710ecc9ed05a6b1e1b16d1a91e065068888028d4c786a6c5b541410cb744898b34d4319dd889adcf682c0ae098db9002744771422941a7b128f7d118f26aa7c5b6ddecef94554e7ed9c3f8bfabc9df3e750a1b7737e09357a3be7cfa34a6fe7fc05d4e9ed9cbf884abd9df39fa0566fe7fc2554ebed9c5f907abd005128f6024ca1d90b50856a2fc015babd005928f7026ca1dd0bd0857a2fc017fabd804128f8028e740ddfe9b86985ced2879da5db9da5b39df3af77962e75ce1fea2c1def2c5dee9c3fa87796ce77ce9fe82c5dc0bccb5d799f60bdcb98f7ef7a67e98dced2922cb8f46567e92a16397f42070ce70f7796ce8ad0a1ced255acf9b2de597aabb3f45e67e90656fb48879084f11122fe04c3173a4b9745d97782bc28f56c67e97a6fd95348c28dae8cfe8b596f2fe4525a9fbb57ab7383db9c932dce75b734d7ddbc5cd4b25ca239f7b37a224dd7b1ea754135e23dff2ab6224afaa4b37418dfc3b578ea05247b11498a52dfc3543114a2d4ffc0f83b413fc433a01911018396e790dc88ca0471099a12a474531021eebfa047bd219148f012b004098f7bdedb97cb63d0c8f7823174a2676d4f2d729f076be1729c0a2cfdb46d509df4d51c27fa87dd0b3af43054bfda397f22ede44ded5acaf1c59de8ad155bd9611a40e607628a88355ebd1f5d1d3127630b3dceac139da5cf0548dcf075968ee1d48441820596ae75cebf1a6efd025ef10e8eb653b803c4b9fd8e00ff65308e3f0ab7833de9955895770226f74eb8414c261ab1c20bc10cb911ee1993891349623e9778817eb995ec49afc5aa5c0ff8d567e10e3391b87135e4cef9c5cef9b39df3e73ae7973ae7cf77ce5fe89cbfd839ff49e7fca5cef9857be8273f4065e41ee10679c7edced2993a72fa25641f97ebc86625eb1191dbf8823ffc06124f88a257ec89a309659f382181fc931f1b4d5692e47c533928a249431dd2242590f658214988948a12c8b5189cf9076515af5be8a8c43d10af9d5cfb78ed9db537d7ceea6b67d6de5a3b1b44feb07676ed4ffada9b6b67d6ceae9d5cfb1052de5c3ba9af9d5c7b67ede320f02104de5c7b67ed776befac9d5a7b5f5f3bb57666edfdb53f002891b3b8f6feda3b22fa310664deefd71644b0bf2c2089bb169076ad8bac6bf724ea5a40d0b580986b0119d70212aef5516f5b3bbbf6e6dab9b577d63ed2d7ce09e8e700f6da39089e5d7b6bede4da1f21f8deda1f82d47351e0adb5a5416becda9b400192f13b41cb357ded6df8c3069feb4316ae986b6fea6b6fe96bbfd3d77eafafbdadafbda3af9d7b903a6dc5b5b74abdeb5e2235fda3526a114b23e3230102d46ced5175557aeaa46d7f077ea95a7b1bdffdff56d6defa7f6f97928be5da1ffe3ff6fefc398ee34814c7ff9571c74a0b7c090e01ea587b2c1aa15dda6bc9c25acfd47bfe01822b0a98d64c6366baf1ed035cd0c31738480092485307299e22040a2302040f101741900023768088cf8f3d524004a85f7adee7d92ff659fb3f7c22b3aafa9ec121eab04311c074556656665675759d59598fcf3f9e0c62fc3b4e8fdf7f3cf5f8dae3b3e1f9efe3f71edf787c156a9497d6d761620d38f7f863b1c4faf8ece3f7401054994490e74e3ad0c7ef3fbef6f8dce30f7dfb578faf3c9e809a27164b1f5fc5ea3c996015f2f1b9c737dc8ed30f2aa4a4c71f3ebefef8acdb47621471d994c434c3fe30a6653fc8f68c90e8c6e38b8f2f3efe584ac9fba4044280c771e83459deb19facc30488ae06985cc4f8c7d271e84c1f9f871c3f9ec2eeb30e1b4e1660e4c180591f66eb13c8565f5ffd6c7de2cb16ee8a353ffb6c4bf34f00cdb3096c526e1805443a3a7cd767a5c79f15f95b626156032e261e9f7dfcd9e3b3d8765e7cfc71d17d93f1f0738f6f408d81066ab2f8f87d7ff01a3435b56fd33bf087069f26b5a473368dffb02b37382fb44a31fa891ece53932f00a8adffe82b8a7ff455dfa03a48fe5324179aff23368871ba4bfcc3987cfcfe375f3428f14583125f3428f14583125f3428f14583125f3428f14583125f3428f1458392bb685072170d4aeea241c95d3428b98b062577d1a0e42e1a94dc458392bb685072170d4ab5160db27ea713cec4156762d299587026669c523f7126a69d898710f1816e3b13ab1839ed4c5c22cec44967e20646669cd2a83331cb484609302b0d3a13932c34e04ccc62ca5196e6bc33b184c9260884261e391313901240379d891946750ee363c88843997e01c2cf30f9921f5a674d003399f43297dc2e53c93a594af2dc24bd5c24c3aa27b9d6494fd55dcdf779f93fc2df5596e525a7f42e6ae5816e3b138358aeb37ee84dd4f3ba1f741e413398150fba88d0733cd7010468ef49af3bd917ba7a2a0634f3140ae81116ef49ad33d377cb814be0bc3963ce121e3b9ee943cdb9e2946226f83ecc9ee7f53e1edb4de75dd21ab3f8896167223a8b9f38e74cccee68feeea3f4cfd9276ee07bbe0c55a834b297393b7c8123cec4a07fda0e5cef33966cce0e6f79c099b89c0078a93f215efb3d67e2536fea0eaf7604351d7426f8d47de28c33710ea5809e93ce846fde1e00667dc41790c39833b1ea4dda5d20e894f611b3ef73d29bb17b90b6a002a03a882b79eec122f03e5f9205d1bef8a6eb7ee02ea6eba5eb4e69d2294d39a51b4e69da29dd744ab79cd26da774c7297dafd375f8fa579d898922bebd01acc7f78b5086d014b07a3053c48f7bd599b8bd97e9ba1011335df7c9f4a6eb41d9b13376a1ce9ea7ebae4e62baeed7444cd7438a8819bb2b3ce5e3f3d4a6ebe12d7fb6e1af1f82e1a8eba34c153eca3c6763fabe43dcda8b79d8a0ec9270b9587c8e3d9ef76365e1902cad44fc9199ad52b79c56f9cdea544a61d43dd8e5f9258b4816096205f3e4294115f65ac6c45235615093cbd43210a13ef765d1cc52b3564629ea6e50d7ff593a1dc3204d55090fbf519f23b268ceba6543eeaa953344a25d1d86fc5ec8229c325a5a516b951122a18c38d5f1888941d6e713e48fbc4d900ca55b5e3bad7653d22be7bbe9da699968ebab56778e1253a7bd80307a954e78e6951e8ceaf8c86979ad573b46896e75ab80344cad87a629314c2b2dab5a86921e5d3314b52b78f0d230a99aa6794d958570aa760be19409a739140e08100ecfbcd283511d1f5c38c8a6aa2b9b8b56b8601ab85be97870606828dd49949a4491491098046949109504414910930419003392c03e09bc77339e53e57437e48df46822982396a9e934470c5d816a4bd64ecb66af6ed21ce991e1d7b03ab5fa0ec155399d048e496005ca2a49e492040e496050c70c4295498f462c93183a24223d3231e21db77d0393bfefcabf3f7c7d46c20a0f8f0ccbd4a91f1cb672131bfa59c548a6695f43236b1613cd2961ff667524daf92b8320e3855f67e2b900117b8d619a178334f04ac3242d68049038c81ecfb3c70bfe746c7588a5397e3c700e6dedb4ac8b0cc699f1d5ce60280b3dbab63e9e0f090be78111c92227f2ee72c2522b91fcec64a0798cfa56b57aa0a8c592568f77e98a54db1c045b696112221a636119c21a4b4b7a5af7267cb37be87ba9511ed755da93c896a7ccb7d6df571339399d96d584714cd6d3e57135d165941f9ae545dd2c2fe6ca8b6aa2a73ca59a720e49b4422735b5801b546f48a086ad00e5c880c0eb718a45b35552cb53d9f2b8da972894c70d2ddd23eb5d522a0e2a47dd97d27d0dc0a4b1550aa68e49e50e062439d327b174ad52422460a48d919103ad4f998de75a9ed3a1af856779bc9bbad4d918be3568d3f19c55da03c42aedf191a663d8c611b6c5f3cc96e738350bf912b4c570ae4dde57a334a67a318353bd6eb9f9c61d349e8ebb4195a4e37e8fb8628cdc20b74a524a6a2f9497f36647426adc27b54bfbcc76af19ea6096c2edfb739ade2145072956c8b361799cbb368440a13cae77299641cae33dba92570c80745b06e92e2fab0a7be6e18907bd8fe149ef637e7787e5b990bfc3ae9dfa3b04c9281645a24094c68eb01f0bdee2d3556363c8fdc209ffc2097ce0043f6f4afc1f37e15f36e1df75bdd1402f35909fcb8c71421690bef650a09764498ea7203d11da5df4f8d04f439f7ff870d2bb0a84f7e10c1486053afd00a689f513f1eeddd372316dd55ed4962c094dc9bbb2547fd96c68694c9ada6bda5159ff176ac80d3b75e1fe93e643870ea9ad124e760eff524ab9000b00ffbdc660a4407d55dbef1d55cbabb4278c8b37bc4fe8c92e9acf63c7ddf493e6467faf6fca99109fda06fc413e2d8d3beb6d9f3112f0e9f6526f4d07fa5a15fa57b5a900fff093857ff849c33ffcb4c13ffcf4c17f5f4afde1f842ccf6eda78598a9cfc6ccc6d297831b8b1bab1be35ff66f4c932f87364a1b8fbeec77011bf3187804c1f18d65806ddce4f08d858de98d1588083681e84d1efdf2e4c6a71b4b1b2b1b8ff0779a6cac6c943696371e6d9436e637ae6d9498a0998da58d3b61e0e2c6d2c6421034b1510ad3d59c5d05f317ca9d9b375fce7cf90ae42a90a7508e62f213939b485e62725267b2b63103b9801c3c42cd7d7a83ce0b4cc545f6b8297444dd9681720624810ef31bd740f29d8df8a5e694b4716763facbfe8d7178122cdf3b98f57b1be31bd736a604b0f4e5093fe8fec6521438b331bdb1b8f1a91fb4f4e5e097fd1bd736c637a608878f6f4cd56bda37ee800a5c137c7c79826cdc670fc8f2a72e57e078ad06376cecbf21afa7e51b29b131958c317cdf984a366d77ded44713df0063f55df9f2e497fde10921d4fa8dd98dc9f0463d7b9d1b776acf1403a7b380f5c66462e3c6c6f8c63ce756ff18d5c6f8c6e297031be31bb7c5f4279ec70e5be78d19f88a37967c6bee1be31b0f37c6371ee0a468637e633af1e50990ba319dc05c2f602d5e0090bbe01e451452d297fd1b4b1bcb1b257799dd03645312d3d75d5517d1744a820cb96be82cd296923077d31b2bee82b907e84b491b8f581beb2e8fbb80488fbff1e9c6f4c63d7c51ab1be3459eddd58da58d4708f87240bc448617912596b5da57bdfca1619ba4db6d7a075786837a0ad3f6b0ba628938285a4a4961e1db1f1e2bf2e7fe06686a8a5ff66f4cecf800837b24c17714416034770ec0161ee57dd27e9080860dfb418c77e0a1cef1853d4e86c3ddb7920e9e89b2a8aee0a9280cb4515d36c9cbe8eda94dc6934bf09357c8cbdcd5d31177fcff5beeeae9dfc4f0fff0b6eece5fa52ac802312044880009e4e58c09cc812db0046e357a953645cd642c72445615951c91f3d4a0e477b4d322bfa105c520af5a056a9223b4d38c5f86e3bab461626400a92131248584b51bfdb60c39a2922379f2bb4ef29b0279b5408e747e93db0e76e33da0bdc7ca59f9f84b0e6a92453eff1e9a518a8642d54cd1d074b958a0795ad8c36612f071778a909fb73fd4e23bfda2b3132dc5a28492f6b44fd4d2d2cae4c1c7fe422b1707919fb5321129ce3dbe1ffb35d59584a22a095e34c1beec9f6543cb85517eab341fca77244b2e505d511321a43f5d9ee62d3f7e67befff234e4c7bd8faa9904f0e27e133a659df6d0445a3615efba411e2ba424432ec8aae2f35dc56259c074c3c89df738184e03344b75cf67158bb401bcd3ca53d5ed6f78ac0f3026cd5a9ee717167b6a2d967fdfcdab04cfb434371f3ad4d2522c42f027875a8e0716e3d426bd89b2c53825b843a74716e4d46291b64aaa96cbe96ccdb3bcaca62d5d4a319855706185e85a1c28d5aaec6b604cfc89bd448d29659f88466f19525ba542f9965a5ec65d311eb4a2bb794149824ef7a501496aabb2cfc7cf8b58d1cdba20c75cdecae5a051c74b0052feb8c8830f24852f2582e93b7afc4f510ca127b14ccc0e1f4a4535d99d0029655f034b02f94f9717335e4638479742300dafecb1421c572dbc532045dd18960e8694e82ea2a789a07165b989dcf4fed275050588fdb2c24b83bc9295c7757459a0c7ec4406df864bc9cb3e0c56a4c6e81ea4620497f7cacbfce6120c04af2e29dfc25536f6c8976f91f278a6bc1cbec084afe895e7bec115265c125bcf43299e53caf2dc2e2e32e1c1f2aaae9467ba054229cff4ba179abca5140aa60897170d11ce536b57179a800c640d1c9113b0a8e3cdd1226de57152beaa933685fc4a21bf2a2f92d77670f3d1d3d9e163178b6cb3cfe723aa71b5c9ad9a579b8ce3d526d62eaf36b995c8943fab73b309354cea5d6d92dc79b728bf652a7ea78e6ff5e91817979cc4afaa05daafbf9d1536c57fdf7e465655aaa0db9e4e1d02dc6d0f0cd16552a0998ca2918c6265548de4ad4c5ef1fbee119eaecdb0a76b653b47d71939fc5567400a8800fec01cd8b2057aa5d6027d5a83d1471725794b95d3e59bcc3f0f0664bd4bcb6330a368bd18e89555598780413ba9b99d9b1ee089ea15641d78407248b913ef3c32c928315eac7f905787fc36935112349f97238eaab50255c3a880cb2f17e3f35d28ebfe24bbdbea168b30799a30ba34dd70bf65976168222bb5e73546aa454877b6611d5d1d6838f087f6e6fd3feb48eef396135a251377171555623704ba0e6e9e31126f511c38d37c97a52adcdb8a12f29aadd47370a370ff36ffe8776e03b30eeeda26a368baaab923688c2a3eef36b2dfbd8de279b709b8b75195efd3bd4db4090a3adaffb115fac1b642df8dd7fc1f5ba11f5ba1efbc15eaf6df4df4bf97faff726594fcefe553f8587a1b1e7fbe7c9901cf62ece42d861b62b1698cddff1863a707f883338210f2aaddfcb400dd41f8790e7e9e879f17e0e745f8f927f8f929fcfc0c7e5a9af117d3b41c0cf3f55aa3bf9c2ffde5f295bf9c2f91bf5c19e5a1ff33302d6033f32e769287fe73e47d1efaf3953116aad72a71d6c014d801236001896bb74a3b4db4eb2b88609024ae2082f89fefcfb7fde5cae861c88467c6e083061ba930929932b8e759fd12f2f91809f91868f06c6b08d9904ea71b6b5d86ffe7d3a37f7efb74111eaba7ea584d3002349dd8e92df78cb5941269e39be1fffde09dbf9c2f85dbe0bf5cf853001a6c4bfde713e09d3734be84ad2a0bb74aed7ff9b8f49ffd773bb0685f7b43e20d77c02f22c898746544db6bdff9068ff54bb227e3cf27476bc908b6bfdb343e7f395fdae19e4c3aee8a10cfcd14d48eb86d975a5b85f04edcd61cde14b4e67f3937f37fae7f205a710c165252cb9f478745db8dc12c34251707fff3a30f45c32d6269c0403d65ad3606db5252cbff3bb4082d086fb145ac0f78df9f17ed35049f5243dbfbf437857a9ecea690e1db14ead9d1a610dbd3d10c8dfc4eeeb4c86f64dc14920bd6519a454d77be2d24774272480c0977b52dd4f3b7b52d24abdd8a9a291a4a1fdb19524d592daa699ab7f6b037c498f97687fa6a6e0f811cb14184e2f6bc41c485ba5b447d813d229493e222e2dbd6c30a10257a2c55c969f15b456d9db2da4dd5ccee778b689e268e2a6a46a9b76194937b64359393f5ddee1a1dc5fc25143513dc3a52d44c0ed4751963ab65d0a3b2498f2a469d3d24d35233199a4fd4de4b1214f17b4a692c4ccfe12b8fe2bed2d1c0bed2d1c0be52605be969ee2a859bbc9c6f6cf947bf9d5775e84275e8bdead095ead0390c7c521dba40aa43e7ab4367ab43efe3ef27027789e12e0bc26b2cfe5e75e82a4b1822b9501d1a67f10bc8e24a1474c90f7aaf3af4014219e85a75e86382a1b3d5a112c6cf226b572d48f4b1c07d1cc55d41684ca20f3172318a0bb463c2d82fae90c6eb14d278a890c6630ac94fc5b23b1e2da7f168398dc796d378fd721aaf534ee3b5ca69bc4e398dd731b8734bcb2b21af3cbc92f072efe5dbcbae974b2f675e263c953d1de37bca5065bf288aed93ead07b8cdf27d5a14914f63efe9e670a8d63e4722cee630cdd8ec5ddae0e7d8a9118dc555125de43feac54cf315c98bc463d0ce8efbed76816c6eb6461bc4e16c6eb6461bc4e16c6a359083a82570c3e1838d0501dba8959b8521d7aaf88c958e562eff183c603c7c3a31437df5e76bdfc79b9f174f734f5f4aa3d9e61ec396fce9873e52c393fce6cdbb10e1ecd7f990f7684678097f730da7119d518e6707c7c0f8f25fa1916ea3833fbae0e7d541d3a1bb02ec7fcf1862b44e4f5e7f8217e8a9987f716c38c6f7b45df265f828a3076137875c125e5943b1a0cc458e6b10ac6aafe852246587d8608ab34efb9f19ba826b4ae8ddeca96ef647b75e8c23f1c689258dea5c694bc4f84f96ad7375580bfa32202ce5587cec6ebd1c0a8cf36326da0e14fb8852735a60ef8b35223271e016372d3ed5602acc440d4802fe3139111f63e59cf74b93a7436e1cfa43ba80a020b29c99f7b7760150466812a502cee082b024f032d2f3277b8e583b4019e17a43be6f241fab846bc1cdcd15700587b5ade5c6cd9cf888aac14f687ad29ab4367eb5e8ed2cc8c22539e7124178aa7fc8b45f9a5432dcdcdcf3e2b3f73b0f9d0a16666ff03a156894b94f6c92996eeecd31b2f726745cd29697f65b4f291d4d4e2860ebaa1e7dcd0f36ee80537f4220bbd8b2e8c38eca76ee8672eb6a5d90d1ef482cf79c1e7bde00b9e422f7ad07ff2a03ff5823f6bf68970c1513f46b99c6ff6fff9657be6f34f2b83f64ca59fd8339f5fb61fd933f60ab157ec99ca50a5bff2ae7d8f5406beb85819aa7c04240fed19fb61e55d1eac0c55062aefda0f09c8b21fd8f3f60201664062df239f5f064a7bf9f33bf67d7bc15e2620cebe87122058e9b7672aa3f60cb117ed05fb4165d05efdfc726500f0b5171098ca5c59ae285791abc755e34a7185b8325c052e9e0baeb1c880c8e5ca80bd60afd8772b1f117b1e72e203603008f8e262a5df9fe46e88c25efcfc2ee8473c58bd050aa60397cce571299c37e7c8f9d5eee5ed45e4c3b8c00fe300e959ea95ef6d5f6ae71763d9ef7f7ec79eab7c64af24a09e7cfea13d53190ccfdbed7395fecaa0bdf0f9a7b144fe397818eff5f9f6257ba1326a2f4458f87aef2f262b83f632147bc29eb11f61455ba9bcfbf9a762e3299c7687e7142a1f61d55d81efc937bfb7ef7e7e173fc9159cd843d5a9f4db2b9e9e505b872099db1f0581059128613fb497ec95ca5065d0ed94fca0ac4be8e5c0ed94fca0b4c711bef215b74f12d1368f60c6beef76492cd2e721172befda0fdcee8847b75d1fdedf00055584566fdb3bb9cc76b9a35834dba14361815f4057d30a8da56ae5f31d3137737db3dea4252555c7c6b107a98e5dc3fea33af629f61ed5b109ec3baa6325ec39aa639f61bf511dbb8ebd46756c12fb8cead814babeab8e7dc25ddf0147e6fa0e7832d777c095b9be03beccf51d7066aeef8037737d07dc99eb3be0cf5cdf8104e6fa0e64c4bbbecbf94e004ad5ab17aa57fbab572f55af2e120c3d00d0d807d5abe7ab63a304f14bd5ab1f32fc85ead840f5ea188b5cc7d07981b97aaf7af53d4cffa1cbac1f39f557afbec34063c8ec1317ff36e2df66f13398f8328b5c417e27113f8ce17e86f800411f56af3eacddabfcdde4caebbeaa57af55af2e56afbe8fa9ce20f94582bcde8384107f9f20d5098c0c22f92552bdfa116af00186007309751dc3f05954f05e75ec34cbc70391bb4b181f3b09e463a7eb756a4c335005c483144f12670a8f3a33d66fc0e01b5db8fd2ddcff185a9af715f9fdead5fe225404889fc09773b2e6812c2944b8abedc890502915e156638a7df53d4e353684556aa03a3692c0cfe3edead889ead513e1be59d4a26bd5b1c1ead5fe1ab4fe2e3a4ae19b98f34f740cabf865f1f5bd1dc336bcfa8e89ce62ea3398c74faa63a791017cb81d717277d67bc30737d65fbd7ac6ebb95db6d86fa3d8b7790301f22fa0fc0fc5b7fea1f86a97bc69650caac01bad95ead58b210c9f650680d900b997356fae1900a603e4de5bf6269d01605b807ca03a36e8cd3e79b42f40322c5aafc5ead8b0370d0dc16b0f0058b6f830c067a1c2e0cfa4a51dfb08ac8e8d57c7ae55c73ead8e4d54c74ad5b1cfaa63d7ab6393d5b1a9ead827dfa58fc0a76457e373bc3bc71defce71c7bb73dcf1ee1c77bc3bc71defce71c7bb73dcf1ee1c77bc3bc71defceb98e77e75cc7bb73aee3dd39d7f1ee9ceb7877ce75bc3be73ade9d731defceb98e77e75cc7bb73b51cefe6fcf7ba39b3579cd9496776c1999d71661f116776da991b76666f3a73a711e4216e3bb3ab1001c42567ee347166cf38b33704e123677696416f0387b9730478cf0d027b045f71e6069066d899fb8838b3c3ceec79677609d38f319225947d4380869dd9415005851267f6a4337bcec3cd0d3a73e7fc68cc4624d138aab61442d4f1d28b25122e88ef2dfff1d90ee4369cc9dd78f89dbd85b99a44dd16580e8522bc806ffb11b7b110cf3bb3737ee84d4c7edd0f3a8fa09910df458c9ff3552e1701197ae482eabafaf5291dd635a0a2a75940a1b01e9ef83a3e7f5166401a17c58570099c373c76e8fc37ecf277ef8e7eb775ef5bcba9efec0816d967cedc40c4b52f94cb2abceeb9e11d39f8e5af71128b76d24de577f60be53e2cbe8c6167f6ce5efcfd829c41677602ea8acfe5efec7d14cf7233ccbcfe3279b3b3f8c10c24c47bbfe7cc7ecaabf2dc80e7fd977f45e74483318e55c5252b00c30fdcf24a880cdfc6df7b9e57e0303c1b49781e2363a8a7700f1c00a623493e6385eb3909f6206d11e2095114aef2c25b700caa2f927c4134763eb7c17ee02edc06cf5d77e6269db92967ee863337edccdd74e66e3973b79db93bcedcf7ea36181aa155280ed18817f16b1ec6f6ed117ed2a7f177b888aff23ac6ef60a2fbac8a17a1c640b15d71e686f7e25738a2438c83e11a4a79ce866b2817eb75d8a7ef9e1d0f4795161e886ba92abc11d7d254b825f66b978a13b4fddd99bc61993bb7dd2296e4527e7bf714e534df70abe5ebcb67c941f8790e7e9e879f17e0e745f8f927f8f929fcfc0c7e5a9af117d3b440a23ab6d64f8faf3738f8fae3875f5f3afbf5c70fc9d797cff2d07f5d14a1af472ff0d05f6f4cf1d0ff5d1a1574c39fb050bd8e9cb306a6c00e18010b485cbb27de69a25df6b8b13ee3fe7af204f7030739f10cae03f050ef1bc5e3045910e543a284117548543e16ee71a981f78b8aedecbfbe30f1d7772e043bf9bf0ece43da98c58240dffef547f35f7f7225d49b7f7dbdffaf8357befef461c24db0c31efcbf2e9ff075dc5f7f72023bebbfde18497c3d3f2aba630c165252cb5f174f88ae1583d994f45fe7ae24be7ef7caff9d71e7dc229606e485bf7eeaf69358a46d2cc95fdfbd293a420cf661954afcf5e409d1cd4170fb46e6eb8f1f16bfbe7cb6f8f5a70f77eae8661ba36ad0327c521fc097cf7270cc4dbdfba4af3f7d186b8a1deaeabebe30f1f527278a5f5f98f8afcb276aaf7a31fcae16bb18672925d27ed359f6165be2df622bfc5b6c817f8badef6fb1e5fd2db6babfc516f7b7d8dafe165bdadf122bfb5b62617f4baceb6f8965fd2db1aabf2516f5b7c49afe9658d2df122bfa5b62417f8bafe737e987daa527539bd7b786b746b786bf3a95d8bcb335ba35fad5b9ad935293b439bf35ba39b9797df306443edbbcbe39bb797df32e3018feead4e61ca4e398af4e71cce6adadd1cdd9afce7d756af3aec0df007e5b270121184d6200c8b64e80c4ad1348b839bf79f7ab53a8c957a7be3ab7352434f163023a6e0df9b487344fa610d311edbe7c3e50f540a7a3fbba8aaf4e6d8dfcaffe535b439bf32c008a438030b151f0dc577f8a009f0c6f8d428144105bab5ffd696b78f3661431824f96451246d7eb7ba21a87550dea18552eaad55ed4c13e0d88ef90cd39f264986cad92ad11b239ffb7b8d8bef9d9577f62a584192e6e4ef2f280daf6d5a9dadecf42097775bd17b4412141524a0a71ac31f5ddfc8cbfa2cdbb5f0d27e0abd8bcf1e4c2d6c9affeb479373c150ec9a849ed5f158fa3f126cb50e1a00a7df5a75866e125f6389a9d74b65b2750f180713b76b64f8659ee8737ef249e0c6fdedd1a12d5977d1aac17f66112cfa4b13b7629129bb7a11572e9f9e43704cdfa530473e1ce7cc3e0b43fcd93735f0d3fb9e0ce7a45b42dc0f724bc972777dc59ae07e80b683cb779fdc9823ba5e5d19d4f66b7c6b7ae6d7dba35b155dafa6cebfad6e4d6d4d676abda5eeacd5307324d5293f43467b51e651330df3c2505d6be5fc4c94ccbc16f6ec835f2f91d6ec835622f71432e0c3de7629f77432fb85834e41a710db910f65337f433861d12865c183cd8eca679ce833eef415ff0147ad18332432e26c00bfeacd927c24d17b32edee79ba855ced82bf6ac3d53e9af9c229513f6823d5be9b767ec079553cc1caabf3248d048a51f4dad18d4be4feca5ca9fec158843001133f6ac3d87a65d83dcaaa832583963df45def6aabdec8faed8ab5e64de5eb097ed1916ad3dfb63ca7235c3ea6da71857892bc215e0a26b19727d845630a3f682fdd0be6b2f11fb2c1a728d7e310580cfef107b12cdb47c1493a8940ff07e98e2a3ca101a72d9173c685d53ae8f982917cae612b91cce9df3e41ceb98727d847c5872f8611c203d4ffd3763caf5f91d6eca156bc8752b60c855df8caba611d748e574e574224a1230e2fa622a64c465af08232e66caf4f99d8eb09c1d4e1ced25f8aea3d65c0fd1c072c8b5e6b297b835d7c82eacb92051c27e081a7e3115b0e6f240599750e81fb0e5f25972316e752cb918410d4b2e86dcb325d788bd548476b108ed1d84867e48365de1fbc1bccb40fe5848b54bb29a49b429aa659a521344645d443b9ab21c7fc4d454d545b35847531ab0b29a384c331c57c07047531b62126d9aa59a2e8ac53a9afa18f2554dd65d1c463a8effdcbdd98bb6ab1dedcd1d297cb674049c2836fe5179ab413e8463885754c8554b73639362fc1bfdb706b9b191f1f849cbcf81eaa566116f66f11601483cffd221f9d967e5970efd93c034b382310fc15b11baa80dcd6ce9f6404b73ca6c3cce68e5e71bfff896a637fc1cdfdbcf1be50387fc4964716106840f1c6a919f6b8c38c5cb77460e338bb3cca4ad3c21ebc7c8cb9d7a793a9f276db2ec3fcd6c652cc3acefe1f6d8f6879993282d49daf46349909414629220260962922824090292c03d099c77730fd6114d55d37286b495a7140c1c2e4fab465796c1a64df3a8d695258735559539f457baacc0f3082d3048bd8ee9889604d649600ba1e92439ac25c9aff4243942ebdc8575448364900a1291c31af9954e8ec4dfbdb5b3dbb012ed2f5bb2de117499e701f776379697bede155982aa964f59cb4c588568bbef3f2e6cc9ba4b13eea104dceb9bfeb53c6d74654d5f9add38c6716f8b124e6f5e93919beade135588778ec3e94264c76bf942889b2434c849c3ea344cbda1b9494e428dfcf7dfbe8557263536b64a3421ed935312557d2e7176cfa557d12dc608429c979192e4440f14f3113907b55d75bb460fc0efb102206b8101c8efb4424a9313a653a6e8e30ecb72067a3853f46af8a599d0af99a227c3c6f587e33630efdfa67196c79de5bbcef288b33ce02cdf72962f120c2d21e2aab33c4b30b4e02c5fc4c8837e8cdf6098abcef2a2b37c16e3337efa7967f923e4c2522d0f380f4e3bcb25a41a70961f38cb6709a69a47d9d3820a74b9e82c9f66f173c8a2e4ca9a71964731c9007196cf0be2ebcef26c1d2b97bfc71cfaec5a204bb3483bcf448eb25404312ce32790e42213b1c4c898b06924e19a2ea158c8ff0dcc40bc4cb75cbf3b91cc3065f93c8862424e003bc6729a718202bbf1035a4ac4b706a552d37f5a788b1e2a03d44f2c8e77a0381ebced2ccf167d8801ac2b23b57735a2b4bbdae1a8a583948ae35cc3c806be8e7b98ee227c560fde4666d759358f98dd78d4b730302aa4471208ab1a51b0e825a8dd797085e9184de433d6f1a45c6715b38e727e0b9eb02ccc3a675393c14ea67798dd05677920b058e92c5fc112601a8e43c9a361cff225685d1e8ca2acf3f85a90eac110b64dd7f14bbc281a8205cfc627065548492d8910885bf204805946f78e9076dd7930883a8d78463cf1d8344bc98bdc33e1f1206d480199390b20ac579ed14e18dec7f85d46b584810e8bd6ee561b583e9c07a38d1163dfd80f8753c378e19b2c2042c9b3fb31d7ce1316585f55d6e7785836f00da0abbeb5f3843f0d1eb8c8de4500ba761a52b3cb980d7c2dbd344fd53425eca9193cb07692bd9810787d8e07a881af26adc82a25f0ab19f88074698ee0a0f5397c408ab69454583baf5a1a81876c2822b0c617a039982a8200b46521cbc09757904dc0ca26606413a1b1e0e3b137677a93d206b51126a53a0bb574a4f079b023f65244bc0b809d04fe454b33cc340f367b8434b4bcecf7cae11229a884d2a4b189a9c16f0c085cd362ec531b9a81aabdb9a3496b4c99adc6be0650a39536285c4905d46e4c69adc63e018c253ad811334d35e3ee8fa616bc885e6a505dd1484eebd548277bdbab8a463272c65a5f850ad4a9e8ebab725ed1485e917b3483e856a6a77b7d7aedb4a241d8583bdfad11a3872209edc9e90aa232baa521afdab748830a0657c10015a8c175500c570357010315a042bea91842bc6230f906970f2814af18351c611c6ed70e77b436bcd9defe8737dbdfece8f8ffbdd9517cd368dc075d6c6b117fa34896e840f8426a6a4116407d501ef406954159a2677a889e41ed403592d1d3355ca5b8af45ce15287e5277488fa2bb61aa9aba089bbabc765a11b19c6cf62abae92692d59c1b591f97d7c745acf67b103215c393a9189e4cc5f0cb8457e59309895c998ae19759b3f83ddf8a51872347e41c795dd1c9cbaa49ded065f21bd924afcb2a59ff445e1fafb320405e272f9337c86fc8eb40fbb4877130ecdadfd6b6dfef6032d15e48767083a2447b3ad9e1b37a8ae0f8fd6789f65e9a4f76f80da06248d93a4130413ea884b0698a51225f1317e1598f34aa43fc686dfd1305be5898fe070766bfeb33b5eed82589e0d0ea7fd01cd52303a7d775ba76bedb32d6ee74ecce5eaa470b5e3c2daf8ff39ba7833d71a0639072d0c41909d1ef1a524a67c0f5b984af0f965208a4825236a4e3305452c46d008ab8635311370028e2060045dc00a06cbf24ad752bdbd963024d8c178a6f7672c71b7bc8061f6fac7d5810230f6f0412982ce370637dda9471b8b13e6d42120e12cf50923da4c9a624bc5f811a049f6b030516a0fc1122df25bd18d7f011cd408178c39c30e92e687178f3a12aaf8f53c2038a5c6041e8fd042c98684fa9fa525286a629c940e35b808781e120d14ea8a2a3286fedacd5c44151cbb3cf42a0f927e865b1fd60474a6e7fae23158b6c06644b708cc56e51f26a7342daa73698edb4a3496ed21b03a3ac00a99f2832d0e90d5e52d3bb3600030bbc859a050b5437f1a69ab569bc849a2add06e95e9f56f9330f4fbc83da34c47535904ecb991a06b84b79c5e05750eba13e6e9b0b6b14148692d8fdd3e2b69abab74f1bbd6b1f9aac8641ffcc429aa9b380a9cbebe32cd80565e452ca391e34648385eaaec4f792d7c96fc91be45fc8eb3972a44e4fbb03c26fb4602296d9031752b743a5ed106be7817ba983a8a6a85be72889af83add9ab695064891e2b9f33cc98ce6d6dda8c4106fd73fab1a1fe2e11c58a8e8f66d606baadf5f1b501b1521ea4dd5127b8f66197bf1b54f48211d30bfa7bc0345d5ff5f76b2984ac0d14126e3fc0fa3abda990a2d084eb4dd9148586566f4aa728348b7a535b8a42f3a537f5a5283436faf7b76ccdbbb4a39a9e3652d0b3b5f3ae4d6ae201ea8614a9a3a9906a97bae534e55ef1a52688a95a8645295000894072a81b609bad8c81417dc90dcab080660884e003e4a6d3a976294d55a9097ea978744039b64b856ed990bb400c06a81b82a47d7da97629a341e1494d2c208b00953a8e377569ba2e7799ffaad342819a4a17cdff0b0dd86df90fdbe06cd4c4e6fa17870ee2ceeaf3ad26cc2d4d982237993a558d3c3503e97dbbd16612cbba5deff04f70f5645e563366b6556da56c43b8a523c55a7c3319af5f83dc441b8f47cd8e0a72b081b7f8256416bb83cc64d7849002ed26dd964abaad3ca1bdb8d5cadb72aab3a69ceabc25a73a6fc869fd8bc79220270942922024199691040949609e04ce49e0ba9b6d56554e77cbf96e4a7a3411cc11cbd4749a2386ae40ad226ba765b35737698ef4c8f06b589d9a59b74d57e5741238268155121825914b12382481419d2d5655263d1ab14c62e89088f4c8c4887768bdb30dd6a77019d936d790d569cee18b321256b81537ba2d53a77ef8ee6f07b13a12edfc9d4190f1c2430889e70244ec3d86695e0cd2c03b0d93b4a482fbaef878c19f8e6fa88a8b46bcbea6db5a3b2d8bfcd5beeeba5d6aefd1b5f5f1bcec654676b56812582dd39168776b688ed6a0807a1b8794dd42a8c59b57f19a9c7be4589c2c4acee3dbd1eebdb28e9dddd27d8c06278edd32ef312555ce697925a725446701dda09974dbc3a64230168c6683b16014a61294b9aff6836102c01bfeb6b60006c6efd0bc5bb804eac33c858ef62979bc2e28be66fa375a56d96fae0d9832f9b5a5ec37a99ab1748bbcae59e6faf47e53deaf5335a390d7a9ac66e8fea3d9b501f827bfa63a352d4a5e577a145d21bf5e3fad663405fec9af655dde6f5abab23fb77e3ab73640da681658fe3eabe80a30591bd8af5ab9208049f935cd295999d66eea415bd013f4039d500f5442a880e25124f0dfafb2874e91770ce3dfc919f9df53071a5a53edff48f71f7bd36a6e696e81dfe70fc3ef8bffdcb1efcdfdad8d7f6c697aeef80145688325bbb7a49091bda7dcade48390deebc77eb73660d21e8bb45155266fac4febb2427e2fab323cdf581b504c99bc4e75aae832f93590eab252af037b8392360a7cc8ef654c4f5ea790b076afb5a314dfe20e6ebbd2b19d65aa4712df5729095356e4448166a94a9b124ab8d3a23d5a8fe607fb271d4a78b6a1a854a55925a1c41f94389aa5395ab04c4bcd5041b393c65249e89aa92594d035008982c5ae9f32e54476edc39ca6d2040ccf10ca7614391837b1b272a220abb2a9f81dffcbfc062a6041fd7750f1581ad361886d0b42b08d31a33a2d50effe291eed43a4492dbfcbff1fd2fd5305bf63d4ca0534031e4227a54bae45bd0b08dbd42fd90f18ec02a95c400bdd25167800c4118bfa47954134199f65ccd094dd5ef5002bf6aa1fcfecea5d401dcb7a543b6859efb7ab77d5e3ca056cea1ff96deaed856d6cea57ec05247860cf10fb91bdea03acd84bf632b167214f68d30cd1ca001e3d98b7674865c45ea80c627942ae9721fd020fa245f25d7bb53268d775aac2c471c95c1697c1f973ae9c631d6bfa1599d88f34e4c1dca2427a4c4d2a037bbfe4775776f4f5cde8eb58d19f452fb20b9581843d6baf462ce83fad0c429184907c95c3fe0080dccadd25f099cf7f8025d96fcf2482e89d0fd0f9103c34cab62fd8f798bf517b069d0f0fda3311457634ee0e715a828a13e1b4b36bff24a84b9501fb81bde06b50f9899979310cc57ab76cafda0fece5ca50c024df5e8ab5d4b799b336cfbfaa3d13e374d5663eda2a23f64c65c0b3cfc7282448a724fcba7c86f918055c1b725f00a19561cf32df0501efbe9464cfd9aba00e4b240cf43de0d24eccf4a1612982e022e85cb467eda522b44945c84a0d837dcf1cbc49c5876be3ddecba0107be520ae2aa88af482915f7fcd5970e3623108b097d879b8c6816e207dd38368ea97f62370cfdd4237b086097c1b776cb4c21efb7c99cbfe2cc4f3a0b03cefc82333fe3cc3f22cefcb4b330ecccdf74164e032888bbedccaf3a0b0f9df94b88865fe2cc9f71e66f70f2f947cec20a122e8c38f37718fe8ab330e82c2c8bd0fcacb3304a9cf90f9df9f3cefc12a6bcebfe12040d0b9602313f883a3d24cefc07cefc39848e390befbad049d4d3a31a075de6975c501dbb4d510ac998dc27bd5c27c3594dee24a3499ed3647cc692e10c25bdbc2403d9d8cd3291337f15749ebf8345b7eacccfb3f7459cf909647811e3e79cf9b910fa92b3f00e4887f8420877136bc375d42f8060e4773834821b0631109f43d97742148bc8308ca86b11ea660f5f75304b0babe16cf8545f7810557730464b4fad3a66a2a80597cf65725101219c3db0dca13795c47e5621c35e557cf03dfa33f371a8efd7cc25ac617a393f82f8d3ec37626bc9abc89cb3b03317677e76f0d9c4b83883da3a8f6ffa2a125edd8b8bb3081367e1b4dfd7197ccf03cec203f6953293c8f993cec28a337f2321eae96dfcbd27aadc456761d5b383e41ff939511b1fc0370cac0ac0ea03d6aa240413c6d06bfd3c0bc99a04d9089f4f91c6953808ad9d6b385993201de4f319d22cb0b6c6b3a40cc3db22d2575d549b27d105f605e917b0f7b8c750dcbed20f8cda2a434bbb0adf9868758b02b4809a4165293af36fbb7d52fc4b2ea29851ccff80afea8e20b7c16254ce01650f8ec7225cd01bd8b3cfcabf38f47cb1286dafa7b87ab0beba3e1f633bb2b87ebe354eb51437c58e94a7eb586c7b75858bb1faeaa6e2c43fbd438e7c6caf729f4086ebcbc76c952a272ba7ed79fc5d099e4e4dd5c6e10506cc419061f83c033598ad5298493461234b59e0ae850a853007df3d06297fcc9f3acb5367b311f9c3f68c3d879231642fd9f7bd74c221523a1d4ef7c5943dffc554a51f52421897047c29db78cab6b6981ccfb0742ce4d7b38fa7eaeb8be472d15eb21f600e31e44a8b7a568a8c52fdfe74ed8f2ba7ed39bc5e64ae72ba729a1f12aef413bb64af56deaff4dbf395217b0e8f097bb80f2b43e85e6036167b164ae28b29c0c6f0bd5633dd79e40ad058ae38e98ac37c6ccfd8f7ed87b1b8739581582ddeaba33fe066ed197b2561afd42c1e8fa872b26649d5f18027181d1481e744e079117841045e14817f12819f8ac0cf44a0a5d90db9bc5b0ed6d6a3d6f0d6feb872c67e08c53d83f99b21f695ca197b4e2c265dae9cc40f631630639fdfa9f4574edbb3c47e1f333ec0ae0f7a1f78d877b759c2f14be252387fce9973e5fcea2ce17c5c39837c900bf2400e981e537f27b6a8f6aabd527917c77bf015270efb8d5123c8b825eaba9491fefbf3db5f4c163fbf6d97ea5c4e0ee85d1d1e02a6528aa58b1f9f7e3169af7c31255abcc892d3155c2265dfc16874cde9025498ca499f41a93754fd62125d25ccf939075c35d82bf61ca02a035f4cb91e1a76e38b619edd3a65fb9df0a21790952fa660446ae2aea238446a8a83a3a6382d6a8a53a2a6381b6a6ebb68e2760e4fc7ed9ed7d7c434f6dfd4637c897b8c2f718ff125ee31bec43dc697b8c7f812f7185fe21ee34bdc637c897b8c2fb91ee34baec7f892eb31bee47a8c2fb91ee34baec7f892eb31bee47a8c2fb91ee34baec7f892f0181fb0690cf86690a49f2b6f35988dd1410c3d243913e79c895567e2be53ea4f38134b4e69044183cec467d2cf3b7599e6bc610a3d84e3e93a5405cef48c33712ee14cdc76261e391393f83b16242c78ec02544e692440980d729c406d978224598f571c3e1d64f1190a5a8850a53d2e3548da22b9bb2f545f0d12b6057227a84259eb0bb25b7026669cd26967e25e90aacfe3e59100afe3721e2af06e5f2b220677f6726368fdafd899588dbcbf5051d47ed151d6d9086bfe3ac34c63de780cbb74849df75ec31ce3df7e0cd3b6b8ecbb2ff8b4337167a79581d38605f44504f8de7a88758dbac1980abf21d47336f64cfa80d224470d960bba7fd176e20a7298c48ab080e119a7d44f9c896904dd4431334e692084be2d22a79d894b04b37083d3429e6791a43442404269d0999864a1016762d6298d1267e27d67e23cd6c0d3cec418c117c0188ca1e041903d31c308cf09c4bb2e7412230b88b81f4a318e2a2cf9a175566c7d45908cc977329cd96438b7499ed7a497d96420b7499edd644c3693e11c26e333970ce76b574bb8a0e782a8eaabac949650c86d3fe83696d7796762ce0fbd8919b9ee079d47d00c66d6832e22f49c28183f82b7041c54773d56e8eaa918d0cc5328a04758bc27b5cea2ab5b0e5c02e7cd197396f0d8e95aabc8e115d65645d65ca3f8bdaebd46396db3061b4e50632d7662d899b81259829d781b9a4ad18ced681596f74a31a7d3f9e774de29f5237eb72bafc8e03ad7a634e23b870e9fd6a0f850179c523f0c7175613fae0bfb715dd88febc27e5c17f6e33ab71fdff1d509a5eb4e69d2294d39a51b4e69da29dd744ab79cd26da774c7297daf5727c067b40aef9a3764fd456c7cd85b9963f1cff08bb9e1b6eb45d10fdec1cfcda3ddcbbd09110562ee4d086ae45d9710d12cf6a2841acaeef9d284a8c6e2d284909e624933aaa658c2aca55a2a4ecab776b741c188380b5384b73085b4d12ef2321aafb7c90a79d552c9ab569e2ae4b719cda8eb274c31b6f713066284043f7ff2db0c3207b6c012b8d530b979394bd3e4154355547244ce538392dfd14e8bfc264b0b8a415eb50a949ae408ed34e32dc4b92e2f679109b080f4901cd242c2da3dc3cb59f28a418ee4c9ef3ac96f0ae4d50239d2b9036bbea46ff124592824f766cdd763e5ac7c4742b0ab65d117208b7cff3d34a3144d59cdd02cd595628f6c5235532cd03c2dece163066eeed7e972f53eca16f7a36482c4ce03cadbd3f7d8d2d2caa4c2b7f642ab4f28007ed62a04a5b88c5a7ecc7425a1a84a821756b05bfba5a1e5c298e0612a17e5756cbf91f305aa2b6a2284f527cccb3dd4f013eca4634b433e82a68d7d54cd249019ee1e76ca9db24e7b68c2a0d474770959a490920cb9a0a88ae99935b2581630ddb4e06ee361380d502c4fb13dc7226d00efb4f2547537e178ac0f3026cd5aaacfa21162df9e7d89b1bfd0f7630bf6630bf6630bf6630bf6b7d98299c1e64ba53af9954e75d246f56396db7675775b64ed134bedb6c86b56bedb222f1f3daa1886458ec8261e07b7c86f4dd382276bc3748b1c56d6dec5d0368d984e41186fc4ba510c080111c01e18f3566ceddd1acdd82bf9fd6b9fd1749abc62ee7f4395bb550ce415d9a4e4b5fdbfd43b336bd7296154d0b041e813a5c0a0c6fe234aa759af7d03dee40d55266fe415f24bbd93001b021cc811a54e13b7f619256fa8e48d3cf9a50e69200939a27c57a72ebe812ff057f279ab90784bc9efef087ecfffba769da66910e3ff2c5d84f735bf92dfdfa9c83a5dbb9e0860035fb3928097914ed30e1f8f9d7cd26ffdaffe8ba1e316790b3fe5b74cc54c18724e1367d3f04b1671e10e8cfabf658b1fb2301419d4713f671e37f19b5e1bb77415cf2af3af7a6d5ca7aa6ce287fdefd080ba9ff5bf672d9d7fd52a753f694355becf6316dee6527560003797aa0383b8b9541d18c2cda5eac009dc5caa0e9cc4cda5eac0306e2e5507467073a93a308a9b4bd581b77173a93ad0cf37978023db5c029e6c7309b8b2cd25e0cb36978033db5c02de6c7309b8b3cd25e0cf36974002db5c0219f1d711074660d5fe916affd96aff32fe7e5ced9faef65faef6df26d5fe8faafd77c5ef4da408a02f56fbdfabf62f936afff56affb96aff43177c9720d715c6984566aafd57aafdb7aafd77aafd2718f42aa6194410e774b2dadf8f92de6354d5fe0bd5fe9ba4da3f2eb470d18c15479f15f18f43e93ea8f6df46f91eb476ebea9605cf7c2093f5731897372f3fe10c781a73156b34d328fcac50fe3e16d659140b0a847057dc92f2934f936aff79d4ec03047d58ed1fc3b7b144509787a8d455ccdf7ba8e31253dfd5f621e37b12a5c59f4271cbcf538e6bc3358888f464903a7cb153786a5cbfcb9e63c71d47b5ff12533509a3b2443b56afd56affcd0e7f2f82d0b3a2f67f84b9859a179f26e0232b88f67a19c1f26eb2dadf1fe5e35bde75eb7eb57fa9da3f50ed9fadf6df734bda356108a6df4957c4de27a67a0733762ff18c9170b9882e0ac956442b1596cf92e0bab0243eb8fbf80bf449fc20ce0a014bf8715caaf62fbb1d5c24cd3dc416f8d77712d35dc4aff52c8bba1d60049e0d243a8b9983d6d2ed1783c07480fc327bbd6e2fe983b40508afb8dd2586fbc24257853abcfb0c0077be105e1d18a80e0c560786aa0327aa0327ab03c3d58191eac06875e0edea40ff77b910fe2d1d97543bebfa01315c3f200ae9b654f8c92bdcad93f00422734f20b2f00422eb242d6fb71411f00452534c8c331063375b844679494dd30c29507c988a6ec05353f1616a2cfa962ec3235f5ed2d3b4ee250b467909144e125349124d4d12534b92b7f424a4ade300c4282f910225a6423495981a794b8704df9ebfa79df90069cfe5933147ac1335896a1db24ed34c02c982c37e2551d0f48cac0671fe11bc8bf01db24e64ca253d11c0f036f82d4dd7958c7be9814bb29366560bcde00d258df70ea424559355e1aa49f70ff939a0909264d364037d3338ee37019f4d49b29a309582ecb67010d1b1699355281cb7394bd30c20da105128975439ed9db0c6a8cc86fe20b15cd2dde60bc2dfbbfba7bf59cbb248a327878d452685f5494d1b911a062227e30c4426465d4309bf8108a41c6569cea301946b2302f2fcf613b731cced3e4ed6b114b91525f79b5378886d2c452677642312ce6f72dbdc26797693e16c26c3194b06f214b40bd99d51c8b0333182d60037a3462137fd46211751f87954f666d42ec40f024d98d9d3cd5a762137a3762137776217c2d54d7a6a26c3ea253db5920175926135929ef83add9133312cc47159834284e02f38e3339ed5f63dd5cba8d7bbc252e326568e11613ee2433223120fbf7bf3915a926a9a8fc427f8bb3291987854f45596556762b2284c03df7626065805708d23069c898fbf9141c4c4a338538880fc802944508f7aa610a0da9e362b9e6b0dea278e7385b402f08bad714a850c1f50915490e7ee2c8e6ee1273eeb4c3c8adea5014998eccf9cd2bb6c98d3de14b93e8337445790266285749edb5d8619ecc20869d57fdc93f756abac3d66c73d81fd886b9a7b4ed86c7eea1df1746d70e1f753241867e73bc386d54030e69de90cc3b3be2417042b34d1758f6f86e1e954d8527ad23bace941da52b5eca0dd639a61789f2fc94dcfd6d93da6e9073e35eb1736f8f2cf977453784e9471ba9484e952b2c67429e43b513de4f9d2655e1e0517e67f711b4fbafaa1f6037fe8a6ea01a5e9c01fde923bf159a054378ba056eb3f2080f6e80c212b0cd06da9ed4ab2a355c4f2be18b532f834e41e7c6a39139faad68bcfb4dc7540e968a2870efca1814d5095229fa12a45261a278fc582ac14bbad7635dfa114d90cd5328aee1cb5c8e7a84531472d326f95b25eeca6ea9bc956600a8f826ec283f6e8f0600c116065e061c83df0d07248a56abdf048cb5d6f265b1b0f28d1a1663e32bf56c4045b21a8be98fbcad129b665d49f6477d59f64fb2a99e7a15d6e3db0bfadad6d3fbfed5c6f6c55dbe524266b68ec489981c8f180eb351a758c46e3dcac7d4b2faab18e7f351459f32d7a1277fc26fdc3cc948ec39bb600c4001d82206f147a4ce3cb0e6cdd21adb00587a39acc02690d269710ead5956e781ea3a6bcddeac3318d2d3ea4952439aa25495a4b925e3d498ed5bbdff198460a94a415725423698df4eae4d89e2f77acbdf2b0bfad6dffb7bf50dc0bc5493309ad10ee59f94a8356e3e2462d72716346314c59f725f1f5a2f4ad8c9cd77abc6b18b5983b236bae34f4ca7a70ad2123e765b1da20cb6aa287523d61c85d500754df8a830014525279aa3cc59c275ba13507760f2227b02cdded07319c1698f0aa838a1d1e670bb5d2e7d98d32b17d02df4da9b7f280916d971e1a0c532ea6e56daffa45c7c8cca98f5c2ccabf3804a32bc394a5949496a5a7b7ccf963a7f9b7dd69eeef8cfaa7feb1dffcb1dffcbbeb37bf9b0dd61ffbcd1ffbcdbd6d0faadfdff660f4c2979afd6d2d4b65c362cd49b9c4b6fffaeaedfe516bdbdd3f4b455ec008b8000b480e69eb6cfe599088987db537ffbe8b6dbe6fb8cbf70adfe5d372391a6e445ec18d3e4d8da0837b7d1ece67e727b6fb8248dea0fcaabca4cb997209be346fdbcf23dde3ce1f153b7f395d4e888b4c021b7f6cdb4fa9b1edc736fd94e8ae1fe5bb7e4aa421a17cdb4f61fb7e34b8ef47dd7d3fe507baef37c5f7fda6f8bedf14dff79be2fb7e537cdf6f8aeffb4df17dbf29beef37c5f7fda6dc7dbf2977df6fcaddf79b72f7fda6dc7dbf2977df6fcaddf79b72f7fda6dc7dbf2977df6faad6be5f0fddaff81b3467f28a3339e94c2e389333ce543f7126a79dc98710f1816e3b93ab08ba449cc993cee40d67ea3422479dc959861f25c0696ad0999c64a101677216938db234e79dc925677282b0873335e34cde74266718f21c82065d102ae423f90c5289789d7dbcbff1ccf8b6f026df032ea0f62a4bb5e44cbd8bca79a0dbc8e53ceae6416fa2bad7fda00567aa5f9482cb6ef221104edd4585a3b8c9494c74c98fabbb8b871a7b8a06f4f3d4f2b4f129811a0404d7d9b8fbf6e4d43bfe0d4570c5991a891efcf661f67ce4dbc763bbc3de2e698d4d17a881d14d17c879ccd5e5bc2e43ddf69fd6f6edb4f812faf758266f38938f9cc9cb90766a642f3e36211f8fb0fa5df2efb50419b3bd96c973f8f23e4ee09b3b87e9669cc9316faf250c2f40aa1167f25c023f190fceb75802c02c23c62f21e14c5e607067d2b7bfe202a7d875e27efacf5061dffe8a07690b52de7626ef639d9c44e6628bc50f07fe7dc1544bf8edcd7a5b2c2e64173bb553d79da949676aca99bae14c4d3b53379da95bced46d67ea8e33f5bdeed442ebb2ea4c4e14315b0bced488333953843284577e034a060a73a628beda5567f2f65ef66885a0980d5a9f646f7736a241eceeac4fa93d1f4e77351367d2fdfa8803e95175c4beac5f85948fdbd3de7d33ccbeae63f2fa0992b7cc3e98941c93bb48eea8227729002dd06ed2754cd60140f24a0f3c0c45d67b107b543f261b18eaa1ebcbe9638aacab4a8ee415c3d47a689a64740b80eb27c28b8e285555284895331ac8eda228d6046881765326b68b82d42eca84020e64ae5f86905f2675855294aa2a81258d9fd7bcbafda5179e7d169ebf6879f6d9fff93f1be4032dcd8dcfb434ffe4504bf07e512c4de6b48b5dcf1ef6ede4b90aa5fcd2757e6d609f24aecbf53907f57c94f26337e23afe8bd2cfc38e435d7e48d127487dce423d6e192d7d4c51811d0bb9fc7cae445d7e8ca4cf25769d81b6c5c9960d65ed64978ce2217cb1abcff503da174d90a798ab3c35a5c6a893cf1edfee618d4549093e3dbd556a90f6f9d723f74945699f1900344aa903ac57ddd512a698fb9a7d500d71429e3baa882a0ff50e6a1d5438ac6a50c3a06ed518dba98a0c95318fd7f36198ae0fca3972d4d4743947d62feb5a1a2af551aa9b728ef4286b27e16968db5ed0973e062cc95113980007d26342badaa3a97f4b93d755f27b93ac5fd2c9bf1c23af9be488f614e7e5dfd639bbc3c794f5cb092d3cce79d53275cd0fdefd057cbf4f88f7b3769173fa39bfb8c3259113ec5d05f0cff958e03b0ca57fd187c777e9e183de0fa5f6dfbb8b87d13bf87edf754cd369b7c8e4ee2e31f13438261bc7d607d74ed6caed7371b4db65cb25dc2e7f9cb22f92cf5ddfacf78c9130e5023bb89853f239ea5fcca0e26e592aee96a5307a6b49f0bec65d9c50d9e962d174e1d88cc2404cd77238f0a2dfdf0a44a4410c9d3c96155d23bf927b651d436d542f5fd7c8cb9d7800992a1a79d552b3f09bcf6ae4e58c66981a3922e3e1638dfcd6322d78f2c3c71a392c1fc3c0760e147ad9d9e34e1d64b80e145ece68ece8b1c58f1ecbc76a348287b582a22275c652d374ff5bb2a253f286ac97af8bc87fb3a86e7a1145752347e47ff7c2e5f14e9ad6eab58b87b502c801eec01478010b4c5abb693cac9183ff71833cf71f37c8f3ff7183bcf01f37c88bff7103127dfb5b20ed69b983b584180ab49f31b8f896b436610d87045ab79c287f62841bd5970b54cd963f0da2fccb9a2ec26ba57eab9a72211140c4df158a17e7782d55b1f86220de2ab5972fe54da5a089a642f04c090c0d6376d68ac8fe35d16c795c5c8b646085d40cdf6aa8001452925560eb9f5a703914b059c0d2443670c79ca65303678c56219156bca3cf6905e06d8c61f986e12d85ca866ce01cd02a24a8aab9d33eaa6ac60fe992b91e737fa7fe634bf4634b146c60d857b8e3f6c84ffe63ab54bb55ead1ac2ecd48fcbd354e4fe56e0f36dbd60fc15c9bbdbe06bc9aed17870e36e346714b73339bba371f3ad4dcf8ecb30d409b9613526393bc4fdff747039bfd2e4b4dcbace4d86e392b284d9759c11c53f2322b89bc05e345c83a5515e978bbda1199b5ea9aaf695498458bec1aefc878bfbc22b3ad638c2a44b15445268a05f1e0f63124d0ba4c8d85544de13066dca22b72ed2652e1d65f78c7bc67ffc5c425419a67ff652641cade6e9c4f5b054555bad68608140ec8fa7f2e2ba4a0c87a97a52ba45b5348afa2caba428cf2b542e7da90b93654b7a1b40ae4354bc5a6bd4d91c9ab9a42fe87a29223e56b853a0da5455eb3481b256d0a795523ff4301fa3d5f7bf9dddc7b498f29897c643bb950bea6a872001170fb12d9445664dde31338306a986e5b94dfc59e718f6c987270a255bead262cbdb036844d5257f99a29f7c27c8b7f39fcbe01c962d6276cc7d884a6474b683aa4e2f70f485ae218f3ed64422ba325f2960a687e190130a0cc9193f9d4fc37d568349a286f32247405a6b69aadc1fb2dfdd75d5686f0eec584b4af413fb44f6ea287a0e9305ba5c02599332478d50f095f27e4c70ed525c6020c2a44fcf70091c015417e456b92619bc62ee324e24e4e1158b5675953c72ee4ac9c22f6bcbd5239830f7bc1becf9a3f761d67e54c65987841a699882cd87cbf825dca49f8dd9c33c47e602f5406b1cd0c98873ed3d27ce850cbb3cf42a0f927875a5a5a697b73470aa2bf387490c15f3af43cb4dd40f1524b73b1a88b46beb195b6b774a468fbc18ec6e3f05ad543ed07fe503963afd8b3680aca6e11c620bbfc8505f1366117da6edfaf9ce960d1a5ca9fec152ff840d0cfda738c21bc254e80370db3e08abd5a39c38278e3f001a523326ed62daf67f823df549198ae7869d219f78a667bc67e0085cf2f6886d29be197b8baf03384e92a0288f05dd22c6ae34a65b072c6be8bfc99c65e14b516117641f30c8b069a4ec3a46a9ae635550ee87b2aa8efa9c885d20b2ed4be2fb43d25b43d1573a5b4a7eba9a0aea7fcba9e0aea7acaaf6b70dd3654ca4957e124d735c9554d6e57a64957c124d72ce9aa94e4fa24b729b4a878b7a892db95d2aee51ff7bae83ffa55b167f182e065783d9ce5297653b4eff6ebcaa91ddf7f8d772bcf11fb51e54c6510c8b041a80c5486ecbbb177608b57f254148156b4b622d8c67a8a5482e30ec5e04381036fb6275adbed0fecd98e446b436b0aebee6a65d47e5019aafca9c8ae530659953f55de66a0d3c0adb135d1fa6647a2157ad803c7233743cd560620372b814bb9f14a6f56ddeb5de7bdbbb47ea363356274ac468d8ed58081f6813f34785f757be554e54c479101de4cb616fddfb84072502be0bd464a8411eab6003c0d038804acc52db2da2e2830821458f7fde0079ca7af751371d431d078082d399069e96b4d04630421d26d5b048a0358525f6323f0080a987cfbacdb7f2ccfa7519e413b7d7f819ea99cea081523820225e72b2f17d95e3963dff74a89c179d9b048a844c2e5c088025967205f861920904700d53f8620aa87bf2af0fcb4570693deeb8ecbc7a9ca996487ff25273bdc77e97f6bee1bf2bf0fb7ec41c1a733474ad873c99879923d976cda66b2e491c4cf98ec717b810f28572a679a12f66ce4e6b6f390f3ca20540c0fef4d96ec0fb0bf0860a3bb8572e31f95b71ae42434ca0d8d620188c51af93ad1c1f0ba90fd81ed9a52b573de28310cfcf9f6bb74f6078960b7632fd80b113e98a825c5f728f1f17c1d164bf6fd7816cfb1b42fa442db7a1116f01b66c1b7287f7805e875e3f6ea1e0acf370a78770f05171c44c414da4e66e2bcae2ed8f782d3717bc59eb1efd93330513452128c97602865afe28869d95e0dde411bb90f904f03bd69b998f67953736f4ae7cdced9a727a6e7217b2e6c5346eca522ce3cfbed9922fb4a8b3834e31f5ded4b1e0ffca12186bef11fb8b586dcb8439b2aa186f07621b411e6544c8884e34f57ccf60b98fb1becfb45c87fb17226f6bc4acc1d88e2bedc74fc1d88fbedfbdcee26049eb35739e2284ff9fb0041e54cdcad894fd7ecbd5ddabcb935bc35ba7977eb1da949da1ad87a677372f3ae0738b9797df3ee9361a949dabcbeb50ad0ad130cfe19126cdedc1add1a1681139bd737c7b7de83e8b5277736e7b6562038b7f5ced6ead6cad64960cd7037b656b6467914e4bbb827ef6ccef14847930afa5d7b32cc52cd211906af3fb90b7a6d8d6264f3eee6e4e67d08dede3ab9f5cee61c53e724c29e8c6c0d3f1901769189ba91f626ea666042697ab32a3534e057034378f53b3d0ab7792ad67c26f4856e2e6c4e6ede2a6ece6f5edf3a79a0e66dab0cbfabfb5619672925d2c6f7de9bd79f9c08f7d79b734ffa37af3f79b0f54efc72e7e6f527504b86135b235b039b37b6de49c04fb8577f7263f3fad689ad91ad91c82ae8933b9bb3ac76ba2cc49aa8c7698796cb5bab5ba39be3be7618b4c316f8c9f0d6f0e69d04d4e82737b6869fbce36ed3f8418594b435f2e44662ebe4d6307c017cab4644b31cfde4067c2f4f6eb8db351e202d48ce40a16c8dc017c6b76efca0364fd0084247dd8d1c01dabc8ebb3948b63907c5e76ee9f0e88e6d8c374f1dc834494dd26ecc859b20c9e6a96ff1f09ee13f43adadbdbff63eeda619b9501e57558b642cadb797f288da6de5d64e8b5897a5adbfabf14841910dc34d24532f62589a925645ac53d35dde6ba7a98f5d46cb67329a2952e5cae39d0581ebb6b4de3c8fd4dec941e5bb516554153444c550215404e573c12891094201b54e076aa64a3b65aaf42aa4d7d20ca33cae672829d0f577d7df953b592c438d1ceda5d95cce22694bd3a961529374ca54efa6696a927c79bcb797ea695af73200108532903b32456ec80879d4393f487a498164489a7492d79e9e79223696879389f6ce64606b3b024fb49b4a9c9fd0a6447dd2f82650335539612a115fa159d3c40375f18da080fbf67c72a6c7c7d7da69bde9b4628a064e10ecb079cbc8747d5576c799f0ae14536c4317349a4e8bf38269ff451f1ea49092b49c49710f281bba26206b5276721029d28a5228586e03c7a2ecae00c4b37ae9b66d18ed55d87d014c04fb66bc6384e3b8edd4c7d1dd349b537ca791338af93d9e248c344d8aff18dee23567f1ae73afdfb977c6597ce0dcfb80388bf3cebd8bcee222c60388251179c759bce5dc3b4b9cc59348feceffea3f8d884bcee28a73ef1d46fb9eb3b8cc125e73ee7d8472bcc80a8b9c7416af38f73e76ee0df9b842e43dc61841ef21bb77844ec0feacb37849a03ff623ee3af7aea0da3189ee40c638f300aeced13e2c20af5002a5e0e57fd7190e64d2cb4f2003018d6b1dd85b7c9bbd1ea43d836c17e79c7b67451c048e39f74e20d559f142396e91857c71ef559e10ef641e0bf903d4ec1d9f18005d42490f7c3c007111698742b8baa7f84436bc0c70d53d2dc3fa0594f004d739c2b7f836900163c25ea5c78f33e36cf668df44f1ac1cef01a838aa875d0034d130ca3e7c987501d864b3469c37fe3e4853c2e5144625da45e586ca2566f69eac1aa7f3a028ef407bdcee2c5e0fb8f6c7177d11a0416cc0893f87fbcee72dbe8375fd5247102bcee941b566efff0abea265d74d3f27dea14f4478b7bce6f96e655dbce42c5e4f886ff2013badb7780beb29abb00f123c29e4ee03047197fb61ba67d88173fc7e99a40f04fe16fb60584f528b001964013fcf1a00d6afb851c4a7017087a75fe43ef65d0892b4711167f00358669d8b0b4192be94842f7f08f3dce78f027edb2e26e1af3adbb8bd9002c4d1e99c5bf848876d4b51bcf577c2b08b49e75e3f04e199ac3df9131412f3b521c530dce9ccf0172d2dad6aabc73115cb2cc548b8862e55305fd237f5836595c7b9eb0e0814a82e7711daa3976fe549a13cde4dbacbcb2afce463dd7794e7b6f7a0e4f79225bc764438d7739455e3f8d92f5a9e7d567ee985c841b326caec58941a47cdbc035fc5226d957acae33a0cd5cacb6a5a4ab9514b4dd382c2579b8c502225f68c1a72684c29fba470faf091b5f2b249a51415618b1d4a2b2f9b9a153dc01694c8e8fadc144c20e7e90a0c9c6acb6a693cd4467910c461c095e63bde169486647d8cbe7c4b65c2183f57563a54a069797d544a49e9f551ad2048d235f8a7550548d5f22dc63abd3eea316e0b312ec88642bb20e71870b9b7b5d52a2ba493bd14bdbcb430e6cae90bc9d1b59c84a75c5c097d7d3524e85aae8fd372deba962b2852f4c89e91abb572a6fa8fc1c969796d150fc1a5e5bc962396a9e95a8e18a62ea729591f377b7553cb911e85c26307c7df64d2a311cb248609a9498f428c786b6c1c856c4ffe4d36c2b6714853df154d9db9635a958de8b9b763b4dbd4e9373bf8d69b606fc40a1cef72f7465cb2e099adf069b1de04bebf20136f4ba5574b88171ba078c1c780bdf01a87cc7ad9d932c13f7034ae77edb4ec95c2de4ec6c12c355f5ede595930e295fa252238c6964b28f37518be1865182a885d9f9debd1e5349fd9d3dac7e5280c9268531bfcb35371f47b3e1117b6e56cd2eb1fb8f637687aaba4ca39da2d8e09a602d1d86e90ee3b84bec75a4dd1096aee416d454a1d643864ed0245b7989552f24b2f04b072002b0e7cc7749eb2ca1651f074b4ac6ac2b83fe6d8b7a760f090b816548fdfd4286e702c50bf76dce8dd452a52ca87f0c363fa5dd0d5d285a296aec51d26f7b464a44016d0cfd215048734b37499835d9d2cdd85c4f4cc7a2bbb7546457d944222adca31fdb3a7112661f4481ad04a74dc72af067a8581b15d38d3a0201b7297d00123724c471e52432412f4c1370840ea61836f106102e9bd3f04f77af098a100eaab25f2325419a62f84630605216d790a461c50352f6355434c40cdbccccefb23de050948cc7022ea3fdcef808f0de2d1035f377ae0eb46177cdd84f66eef836f1b2fa8c12bbadcd313dd49bffbdcde1db8cfad7f7a023a9b7c370e853024e708f30560e05068edb46c325700f20e1d01c8e924304b029b247049229324704802833a4e3fd9b8c8d488a14322d223d71a46ede0a0d9b7335a6adaf97089e278a9333c60eab64c5d09c0f73060ea48b4b3f7a57524da39afc878a823d10e6f3142f2629004de6984266c98121e2ab9e384ce5a83a16e378f7b1b0ef5e872f7fab88a39dc36af7ee26df21c20dd4bde0503255a063b1907ad9d968fc58f84cc889d8c290c644c6117630a6318935bc17ce391d053ba95dcf8ff074fe4529d1cc9e62cdd246d5437c8ebba92cf9336da4dfe9bac1b594d27bfd1745dc9917fb58cac498e644d6a6a3a794386df7f2b4fabf03c9ced8678fd63b847b2393cabf5baae08fec01b18035b60890c815b8d15f45f260e2b729efc32f1ebf2b45a9e26bf4cb451dd6481f2b49eb3740cff52ed3665f2cbc4ebba5cc0c091ac69a9e5e9baa7c914990057769cac3cad935faadde4755d06ddea1c2723bfc6c3642097bc4e8e6477d00a8696e75e3f5c6c3b5c7ba1ad0d97d1925d59aabf6c3634efc8bca9e560abf4fa612925b51d968eff40af413fa29909b53c1d6e75ff4d36cad37a10e3dfe274115e3376b85b4e04c07e7a3991a3798bfa38eee4db57cbd34143ba42793ad143f5f2342e60a71583f2ebce69e8fa738a4bd46a77799a8dc52185ffa42dc51568c46bc88eef6cb2489aa3d20a26740fdb62ac4df0b568b7b7a189913e8ec2ad4fbe99d9ab98f2f7ef15f5a8a6a78dd41f0d23d52ea63452933bcd6972a7431d4d8554bbd42da7a97b341062aaccfd52030150089c387f2b66331d4d5937bd41456a2d0311c4029a2110820f109b4ea7da715cdf04bf543c3aa080dbf948bb490caa9bc4f8b8034ab95dcab0b5c426169045804a1dc79bba345d97bbcc7fd569a1404da58be6ff85064c64fc9ee8d8a0b8bdb92325e36136f9a543cfb79aed2d1d29b3fd60c7f12653a7aa91a76620bd6f566b26b1a0dbf58e9ffb58eac9bcac66cc6cabcacecae11938763cd14cc6ebd72037d1c6e351a7b0865e77846d0607d8cc017560704df9e09a8ac13515836bbafbc1b55fc6d31e5953b6cc48fd43eb5edda438b606a8b5f3b1b5656a31636b6bfbb1b565fac7d6f16ec2fe36c6d6d44858e146deb04c9dfac1bb1f755aee68134256ec60d3e283cc30c58b410a789f61926d86969618525ad15175b7b5765a1699abed3fa21d06a8dafa785e767322bb4a3409a496e948b48b9a99a33508a0bec621655e00b518f3aa5d936f8f1c8b9345a9797c3bdabd77d5b1b775466140a4ca392dafe4b484e81a70b49d745b401877fb63c16836180b46d329d6d2c318dd076e4b89761ec6ec3e445f8ab5e7163365f730dfdf703ea65b0d1e2d979a828085306089f7b5950bec84a6bd92f01ffe16f0157bc107b71744071ca00d1034058fc5b31ed927a53260cf0425acda731ccae8b32c379c4a20dce092e8ae1943108801a47183bce766e712ec85ca30538c4718ad175d125d393f2eb424d879d1856074e6efb173dfdfd5a7fbd7d02a17a0342b43f64ca59f9d46be5be9e7d1f0e9ed25fb01835d20950b50c9d8e341ccb9ed475051ec87f65dc6088f99d9ab220a1562d68f9fc757e4026a0f1398bafcdcf4dd1a87b6e3d5e307a61f058f4bdbb3492e7e374309711eb972d19e091c500680bd4cf0cb58c5b388b167a4d9a1447b19d22ef0203f981c3d1f1d3e468ca2925c6c92cb4a7231492e23c9592739df3a03116088dc9095385bcc600b98fc6f7554229a8aca40a232141e9b40c6d849a00072f7231448ddee55008c728ee1810ac3b947d5c3842f460887c441f530e936e316a06503179e2a307281ef02deb09bf1baa317dfb1b985404e312a5804e856ed39a00c7e18cbf64c7d7af7aba943b9e02bc0ede407beb66da5f34f717bd9e22bf549dfc3a8c8be67cff8c645ec70b2181a61a9e1e93d7b29727acf5e7aba2325d1c946074bfeae353a62f2bacacad00f67dc14e9f20c5f6ff7cf59a5d0a9a47b8f525526afa8e9bcd64b55ca43ff9897d55cd6ca5ba48d765203c0b9ec5119fe4d85bca266f3b49392df64b53c4f9ee902709fa62ae495424f96e629798dd36634f8536a7764ff9c05329081e240168800f6e4954c17f005a6c090bc9289df734949af2986a69a6f69e4bf170cadd069e5ad9c465e930da553c92b18300d6abe65615095f191cd53d522ff1f7befd61cc771240abf9f5fd1e8cf1e751b85e180a07819a83d87e2654509106982f21e2d84ed28cc14304df4748ffb0270881904295924254b962fba5896cecab4e425a9b50840146d90b2a487f19e8813cb07c0df0b20be400a4b27f65f7c9159557d9b0b4159daf57ec711084cd72d2beb9699955559f9446db66c4d33bbef138563966f3e519b36c7fc69286a8ef99639e657a1706f763266994ff8e6d8b439169863be3956359fe89efbde0c04bd5c1c142c443ad938f815d49711a01efa4b91de9d8b3c4e6b61d5a68a33dbf134d763a14ffd4c4a4a8939dbe9e129706d574925a45ef362b655af32dbe2dbc5d9fb78a5cb994d6eb4169813b039c44d521556b3ce866717a84315dbad95a9c3229d664d2488b703cf8667c3489dc98b85a8cfb4add4b381ac4679b80249367566e39703598d8a88f1a26a390df13d2e9c43c9087c40d069d0391a2934ad9ac5233a6eb8b2b9d0678ed564350bfe3b814f6bd3b4469b6c3af4c3b970d74e74e6c32555c04113e0074b2a82c3c081921a43558baa809bc064c75e26641dd28b04af24721c311c398e485408a9cd66542b662ee0aea2504c7993b807754dd1d66fce6a65bebf53d2843fbcd31dfef0acbff8303ee310eff48e1dd0264cdedabf4b7bc4b3fa79c46bffee9e1ef1dabf932ef1ac8c4bbcf6efbc3e366deddf71a77856d229deefbeba751b50b5a1f1f12169dad09f3c26ddddf5f2a799ca63dbb680903a1eb2313e2a79efb3a163153adbe13d8f3bcfeba09bb3eddf781d5e8b4eb47f135931a4ac1d8ef1e849ff2b7ac69b69ffce53beed2b3e8bdce3b57f33ebc927e59997317783885a112ffa44ef1dc6ce363dee220f3de4a55de4453ef27abac8bb8787bce02b78c8d35893f6f0b1c9d54eecdbc385d194bbcda525fe90eaaee1825e52995a1ce6b40adfec28a9482bbf49dbdd85f461365298a392d48cd372d5320fe203aae638c3979fe19f4d2dfeb6b4654e88c309f3389e4d88a7a5a979185d6fd27b3d2c3d0d75400d127ce261e93ac0140f4bf7f2bcf96858a375c00e3e021a84f8e1384c4438ae79d0aed29ae55be6b1d3618d524ca8b9bed58fde3c5ab7cd47031a988f22a8803a00c63c76ba663e5a73bb238304e7d1dde6a323e6a37bcc471f340fdae6b1d3e6a3c35fff03d2ff410e406ce62a3eed10cee6985fcd2408e2b060cd598a759a36a2379b7d4a832cc5394d9dce37547951db6ab8752b7e4c352ebe43cbda694a2bb4c124b509dc39168969556bde52ead13baaf20c555a4555e89c3547959a7b5ad8d38a0861f3e453aad8164f053253a310230c9e7c6b2e142581d0d428460853a7da023b6b29359e3cce5d609cb5a495536d8142ad3c15884dcda2bcd6afed5dd6847fcd65e15f7359f8d75c16fe3597857fcd65e15f7359f8d75c16fe3597857fcd65e15f7339f2afb91cf9d75c8efc6b2e47fe359723ff9acb917fcde5c8bfe672e45f7339f2afb91cf9d75ceee55f33a049abdeeb6f6e5fbfb67dfde6f6f595edeb9f98dbd7dfddbefe09fc5f7e11a3e284ebdbd73f860024fc727bf94573fbfa4b898ceff3a8ebdbcb174d80bafc3400c6381e787f7bf992b97dfdc2f6f557b6afaf61b1b778fa2fb7972f48486fe1f775fc7e9757676e5f7f160a89e48b88479c761591cc96780b9bf1cb4c421febddff8b3b2261237cfd9f10e832165ac512abdbcbe765adaf60fc07080cdaf00e865f97696f75cdc45b7513d36e0af0ddf2bd8b15bdc37bab33f926869711c007bd10ba8975ddc0b41b98d63ddf2f71b0bb27f7b53ece76d0f9ce5eb8911ccc6cb3b3edec6c58149b6e498c741fb365c44e60245010158a7a046048fb4b1ea9b82f17a2fd7928e9cb44b7af5f94f3013a3bcb4c71d27f8cdd74a99baea3c359e8f5abb86e5633109306c97c2243c617b7afbfa3c8c15be12be8ab381285360055487a110560e779d3b851f2f59fe1ca3cafe0387fb27dfd7d454e0ddec6b7c47cc539113b16ed97a796867b1553afe3ffb778736287a3d9d4d474e676cb0950d7b7afbfbd7dfd134576e88a0427fd91f6ce51e940ea635989f44f1ab52685c278070a1fe34ce760a5afd2383ed38246baf84dfe95e809e9bd1428f3db92c89e8f21dc73038340dfd95e3e7f2f8be928e3fd38485dbeb2bd7c757bf9daf6f2bbdbcbffb2bdfcdbede5f7b697af6f2f2f6f2fffa73a4815a4eb3aefc72652984bd86dabdbcb979af8f531677b4d1cdab725277a85af8be6f6f51fcb35f9ae1cf9f34d39945070272ab4dd2555c920a316d9437b313a8593f463aa2471c3c83d18d905474cdd8fa95d704557a7bcfeeb09809df87c058d5d1684f00ebb3b76f19a699c50d7a5da16c5756b1a24e67249bfb15f9b67d60ee133f9dad5f6ca9bdb2b57b7576e6eafac6caf7c626eaffccbf6ca27db2bbfdd5e7d11a3e284ebdb2b1f4300127ec9a35eda5e795766fc647be5fdedd51731e3ea451300af3e0db031eecdedd5f398e192b9bd72617be5b5ed95352cf9d6f6ea7913031724b0b7f0fb694002ab33b7579edd5e7945a6fd2899c0514fe5bd8cb8ac6580f4113bb10bf2d9a6e777d0e4fc4e5b9b4f35319f6d515eb4249f42ff7eee1d6035ff8c456f0aa4579ee695fe08db918abd8e3df3daf6ca8d4cc26f11f12b99d8d7307605ffa7127e8751af24e64a320d9a94c2a7af54271b10239d4234462e85501689b8e23e22daca055189a841c016800548f8d9a1e3f7acbbf7afeee4fd9eaedd7bc96830f32ec2e459ed14d0a0a32ee2cc3bbf23014d8cdb55ecd1ab9dd2198cc73b5f45088315f1a3a404164f9d4fb657de8119827218443f1f21b0bdf24994f3f7db2b6fe3747a7f7bf57c2c8089b5f58a2cc35341f45af9d9f6ca2b8a6cd275fcff7bac480a5dd9a408783551fc359c876fc5b2958c91992b89cc2b387ddfe4f1429c4a44ca22e329f400fff763114ac6c8cc8d44e635acfa26f41834764d2cae4878ea9e41b6ebde22d4cacdd429d1f6ca4db543e01010df89c6afb9bdf21c2ee0e5ed95a79bd89f5730711933de926309696b18b58c5846109efe2afeda3bd0e8e2b83d8157ecb8bd377e5d3db8f740f92b7b73efc45bba754f622bddbaf74156fa77ef8560b15b5ddfa068d1e976368c9c3d86685f16c6be1e43f3d1b0bd0aff6d3b340fce867e104a5f8fa1f0f5184a5f8fa1f4f5d8e7f9cbafd3d763287d3d9aa798e753f33174ef683e6639013527980fffe934ad74bf99dfe9cad10708581c4b43e1bece1c7931f3b1d07ccc8212e604fd0f5217fc251af7e355cb51ac6a87cafde034cdc427ef36440931177ac4f52c9f59734a2a2d59c86735ea5065ce0dc2b9a9048c9d7023ab9a710f6d5be134e5af575a4e1884ca34b5438773181123b4ec22645568c20d602895ecae477d9e569521a161b75dcf757852250a0a05fb4c685391361e05857a3db01c99d688823b79404cf383a653697a956650fd8bcef482aa38d42ba97ec0cdf78392ea54d4e208fff42a6a11727d7da77c42e15f28aa431bcfacff4125c3d1d76ef8fa317c8d445f7ba2d407a3afbdd1d7bee86b7ff47520869ca86477fc39125718671829c455c6b10fc69f7be3cf7df1e7fef8f340a2b642f4dde584603679153bf2689272a3d5cd8956da3994700dd5cf7d56ca7956c27556ca71569f6bd7889a404b2024d0e9878a4042542eaa1555f6a0ca1b2faddfdeb884d77657d76f9ae867220ee265c444f0e2fac71be792d93f81cf3ffd3e11f5a7df43df6f3cbfbe62c6b1fd88f9c64b1b97d657a166f8d938cf7f2ef2c84ff087c304781ff573da0490100e42411808c1fcd3ef79e9d5ff02a47efd17eb7fd838f7ff2eafff5e41b780689fd1e164e5adf595f51beb1fffe94647a684a79597d7d7fa408a89fe24444ffee9c6facac60ff172fc9a82f315cd5eba56d0bfec8d8d67d67fbfbeb27109223acaefe8b2eeeafacac6f3eb1facaf65dc6e7c02f311190a4edc8b38c13ee0757cb4beb6f1123213485300f93fbdb1bef6a737d657a27d493ab22ab24a14a38d481c519159b023a39d870c8ecbcafe0083116d3464b091ace0c3682f21821d0a475c30ab4d7ee7f94f379abc9626ac203eda5f4198e7303b0578594924bc8b2675b93017d7ff552573814491df068caa86f0de92ac59dc074cd456940577e01d0428441398480fa61c73e260924d359bc124f062fe816e8a4bc0399cd0b6a7ba30dcafe97274504d2a09d72e6faf9ddf5e7b7b7bedfdedb51f6eaf5d3631bc8609bfc2d87fda5e5bdd5e7b7d7bed17dbb75e3031e12686a312b7ce61ec358cfaf5f6daeb26967a07a37e95047d797bed83edb557b182d793d9390ee7b7d77e9cccfe2e66bfb8bdf62f19fc3842bf4e42780581fe269991e370757bed12c2399fccfe0b09e44a54a28f2271ed727e7bed8779a83cbfbdf64f79d10d2212db9fdf5efb35c4ff93cc096d9591e765e4bb493898f48a8cf92719f30b8cb91f15e1da7bd888d7b099af401b71a42ec936be06bd8b51ef61d4456cf0fbdb6b6ff35e5adb5efb45d45fff8259dedd5efbe5f6dacbdb6b374decc23531460005dafb2e2fbf7deb85bebabf6f02b3af8410d70f223ad0c797e0df7bbcdb057cf8bdcac7e8eb367eba1fbe8d8db9c26772ca0e0a63a1d780e761cfdddcbe7549e95fb6f34069edfcf6ad4bd811af6376010717c6c52676f26fc4507424f77932b86fb9fbf223d31f43b578afba7ae85165efe1dfcded5bcfa57aab43b50a53e26d986500f7e2bd0a258411c4eef5ed5bcfc11874e64e686305d9fcbd6c2da7447d114c2a6b6583a644b5b2176e9d871250ff952e107622fa203637b7d7cea7249fae3570b5ee2d209fd88cf37228aee08a7f5daefe9bb14ab74b52ada80e2b9928a1c44d455679bee7a1e1bc925b4f631f5e8cf5b7dd532bbca4e8b2587b1bc78c630ee8af97614c70fac55adb6c7c83c37b03d192ea591efc9ad8b43d544f72ea230ef35cf3049bf6e0779c7abe1ba9db1aaef948e8e07fbbe1f2ebafa8126bb0dab4c7cce3734108bf8fbbd322e6b0e5f3afde3cef88c3a0ba84c6ad01b5401db1c60d2fc14e03b89ed64aceecac6b8e850ef30154003f56837973a1cd7cf39170814d33df7c18a21c54854dd3ca3d0c941c00c7df72b200a70528de5feb36669963213ee664998f84e6c35647f6fbda898d8fef3abc2beb478674ba90213db7623c3d9da12be11a3b8526410dd79955a84717524e031e0ee7a8af38b3594204857caaf8a11f3a6e4571c4a5d504f5811c73b44aebae93721980d5b9509943e7a8472900e7657742397caad8ae3bad38b3e94d1315006dab4ef98d57b41c527c54c4ba898bf5225c2baa960f39c43ba6a9bbf52e52029eee7a00307a680902159906fd152d751e189769d3e10275a2f52d420d991a50d789d63506eec3fea69bc8ff35ebcfd43a9dad9a0bf4f373af9be52afe2cb0d3a6ed4e98f390729ace9b136eb96a96abae375b351f0983eecfcc8bd708e287e4b34a44c718a741353f63bbaea7b16f0fb3915dc385824ebc4c3c5729128a3a476219aa2a158fce770bb99c660d1ac1a43335a8ced3c0aeaa3af164b4a6aa0386619554452daaaa3e184c7a53836a8d3ea2ea84f6ce44a774a282606195b037d4a2d5d2982e5ffff5e4ebbff143bed6a0aad861bdf3015d4808a284c49bb590e0b17ae7d3b190709a9eee7ccc9527789defa642c2e163135dde3785ee88e97cc03c184e00a2f0f14dc688b14e6562a753619803c930ce876404cc8d6418e749ba129c33c9a847c2c0ecc0ac461fe91ad905ef288937a09f8d976c76a2b9b299b27951b36473a26624d09768a7d0ed82e6ced0ebb5f5b2ddd3b563c1697ada3c4c27e0a7eecec3cf6cf5586057e1cb7667f1773afc81487060e6f4e1705f2b4c647f5f0bc4bf4e4390c3f491d3f474567cc701b5d94407631c1b4b8ae098ed91f0f373af67c56bccb8038ed7e5cc45d2bdc0181a1e300c96b79c0a3b737c4653a147f55290f76dabccb402191ad107559b4da8c5ce9c5e67ce05fabdce9c40533a72e21bd6c1a0aad48ffd406d7136fc97638a1db5535c99b3435ca72167808436505b201ad4c309a4d32014382009e03021850631c001e6cfa3803603ef7780e72f086a731a59be03ac5e4679c8e81de0ef3c0a3001f6eefca7bfa1385c541fb09cb285075ce26b7ff4b5af1047c69fbb8bea033c597eec2ec8af07a3af91a2fa40fb0f4eb9cd8fd1a26f3c9d8a427b31fb1f57f1e0ec81d02987fce04c7c8ec49f7be1f38fab227322d0e58c2bf9a0e0f1329d33fff59fc2698acfd006e6e32063c17ee28fabbef9083d6b79d4314fb15a2d3c6b1efce35ba11fb8be79a461b7ff609b47e6ac9af918f5ffb85a330f7ad4fee3ea5c6fe671bc4cb122dc1b3c6ef97ccf42cf0270840c5001244004703d362d27e859ea99f83f603eec15ec3fae9aed8bd4fbd7b7686d9a9a2798f7af6fb1da34330f85358aff30673faa7e829e354f04b0c3b11114008192e6a1a08fd1de0928644e5028629e80facc43c17f01b23c1dceb6ffe028b1915c4c9b1bd4fbe36a364928356699cdca6cae9f895ea5fd07a7431932cbda5798f3954df37cd7f16862bbd2fe9d5366b84d99b6bc39dabea2f8d4b11af1db093258c31c0a37c78b36293258e5a9804eb445e1810a4f813e8a36283c30ce536823da9bc06783c736feb86a47db120cb4ba792177a2278ca40f8cc8fbb8fc752377e4b157f1c89fb835a3e10b047a7ca95eae75245b5ef6620188ecf238a330e4f538d1f8da8e347a3b0059f48b93eabcc51c9ffa8acfcaa153f155a23e90899982719c64836a9c2719e06fe83de028b5f67bf8202d961721fe541e64c7b0282abef9bb780f384afb637c2343d42c82fc153cc88e6151547c4f910a2f7ad60a132531c49fc683cc1014e5f8e7141917b8323fc694f9e2a93cc48df9cc1168e2e71469f032c0184511ea89c7f2201bf5441df031d59223ed359b41894e3a53fc493a676a7278aa733b73d6eeb0db368fb2798fceda55a0cced2be6c179afbd1ce225aebf6bff016f7159d4fcbbd02f57037e4d6c9e7ae698e5076ebdfd4ee09b8fbb3cea1f58193f7678516cde4bd5c19f23670140069000ae070b9868dfb669c532c7dab71dd6be62019ce0ac658eb72f7be5d0b3ccff516ddf860cdfb7dad71ce6419689f6e520f4fa3201008b30112f008680100a96efcd0926dab7a1247f91fcb2f93faae6f7b1ca1d30837c8219e46bb5fc3d1e659bac50dba6fe54b7d7d952698a049d601093b635a5f4cbdd71225179ea01b75979ea01bacbea79bc5079c0e54fa507ee98bbc03c7cf07027cfa50bff8350bea81e7ee038ba1aac3c4031d4ebf51ff74cd552dabfca32ae0aabb57f958a4f5e5a93f109ffccccf26238096ee5b7ffe029cc96ec0a52581865dcd1bb157edd635642c7769afe67ba2ff89a5e7c08ced612a4e3f39bcf7d7ef325f8fb60e5f39bbffefce6cbe6e71fac7e7ef315197ec5fcfce68f31f0cae7377f69427e487f190bbe1c25fe1aff7e6ef21f04990abf283fde363fbff92a7ebdf1f9cd374dfcf9f9e737df44282f216c0ef8838f3ebff916a4213a2682fcf9e7372f7766fc3d263c9f8ced4dbafe6f68704c61b1ecebf89fa3fdba29b17f29197e5d744b1c05d8bc9c095fee2cf2e36eb11fdc821a30d88f4eff7522877ce0af0bb5ffc80b6c3bde7cc82efafde7379f553effe0832c2197e91f7dfec14a3a3d49d0a38498a263c15f8a597ff34d2595a56bd99d107340148683a37bf3754576f54b09029f8e93e4f1c738361f45fb9274640d72fd5892959f7ffec1ed688bd2115f85bc7c5afdf0f30f56a2fd8a2407afc7a9580ef730514ab4897113395fc2dd0c9f9c2ed28597a34d0d02e184ea39a4602fe126478ecc0d31d5e45e0773c5f1903db99bd88b5c6878f7d7c686866c1a38095e64390e6d78e6b4f76fefd086f76fef9835eafddb3bfebfbd635ad39ee59935da682c988d0507ffdb8d85b3e6ff7e7be15f2f07e6bf5e5e08a8336d79e65cf06fef2c0004d35958e0519585d3f0db9b25fc07d61b5366ead31af54dda70e0bf6fe1cf9c87ff1778544dfc7eb6f6628376575f88167c3dc090f2fd65a0fe2a2915f52b7355a5e33d34eacf51a5e354979396d92c51a2be4f9d4099ed4e8966774e872a1490f1950675128447866015d4acb988d4f0803093f86cedc5d4112d86f165a2fffd46fc746400a8feef372c07890785be966403da80e48236dc052f221356a36179fc6096fab3b0f395ef4542c8f9068940383b544e5280ade737af6c5db8fba3cd2b9babe6d6f9bb3fb9fba3cdd5cd2b5b3f34b79e85b8cd77cdcd7fdebcb2f5f1e6eadd9f88d8ade7cdcd7fde7a6eebf9bb17b72ec49f3fc49c777fb479fbeec5cd1b50f0c6dd9f6c5dd87cf7ee2b9b57b79edb5c3537fff9ee85ad6712115b17b62e0106327df9ee4fb69e91c1dee4e3bf0ad231edd97afeee2b5bcf6c7e70f795ad0b9b57efbe02a52e258337eebeb2f57c22e2d30bd8903862ebe34c8ecddfdebdb4f52c7c4471fd08166080b5625d081f61221c84d19b42dd67d9bfe879470c6f3dbff5dcd60fb79e1b1fc2717c7eebc2d6739fbe777868eb99bb97e05b10ab1de5dd7ca193906dbea0dc5fd98eddfdd6f3777fb2b9baf5dcd6b3cad633777ff2e985bbaf34a1733efdf8ee2b9babcd4f2fc0f06ebebbf5dcd60565f3eadd8b9bab30ef447c3a19ca2322179a5bcfdc7de5d30b5fe12a7a1774e4f30d315632a60772d175f51ed8c9e21cc9c47df5e495f63eba0bae621d2e14bec3068348f7f6d0de42a1d415ffa2f7d001484b34a0e83d343c3c5228f56c0264d81d67c0f0fe42b640a24d45d99cee8c6cf3eadd4b9f2ec36450366f6c5ed9fce7bbaf6cbe9b656b3cf6ee2b5db308dd0856f94368c4d6335bcf491549b640ccfd36dfbd7b61eb82acbc43d582d3f5879bcbd086ada77b03dce14141a243e2d38244b70297dcba00fd0423a3208d7c66eb12d0c98871a6236b4595134465eb59807bf722c672569a8caa461963dc23ce9a8caac4107175464c5606c76348b898236e2b838d1802aefb88eb8ae0bd0d1423c2d01404a339043373eb6318feaed611b064a5df855e8716c9c38a41352672fcb2cd82c8f6f7a94c71b56a74be115dcadaf103419b2fec9a252a51efe7ad1f0245365fe8663bf9359d7b085241a820126a0d888d530a4aeac6b3ebefafafa12f818fd657d4622a62e319b5a856a3bc29ff379937fe85d319cd330619a1c6a2ef17017aca2b9199f654900a42cd89e0c6337d33a3ce328bbc990aaea5821d0deb9b1935a1e9f69a89c05a2290e9879ed9706da175e3471b2f98eb1fac7fb4f1aaf859178f3eacff61e3d58df31b2f6d5c801c71e0d5540072c32adb38b7f1eafa6d73e3dcfac7ebb7a101f881e9ad49672a293e78df1e2e18c6702e071f8501e02de82c0882e88b083e1e32f6e4721ae67868b8d06ce2d7778ddd05bd844e85e8e4ee29bd95bc0f18cde50ec720b0a0d63f5607b561341aae5a7ebeea869eafe925757d955fcc5385eb910e797a2e16a617c5fa5137ce6fbcba7171fda38d97ccf50f377e8cfe826eac7f6caeafaedf44abd7dff3b4dbebef6fbcbaf13406b8ff96f5f779e022667c5f80585f5bff84c79fc7781e587f9f43db38cf83bf5bff78fd7d010dca6c9cc78a3f595fc1d9bc7e03bd21c118be9412d7fc803a156abb0e8b3017c3ce715f5bbf95c45ca449dc7930c25e0425fe1210b640a4c93688b4b8152242b6232e9b6c49dc0e4c4fb6a495b1f4c5b6885688164478471847b80a2c23fc0466113e11261106dd65fd34ede7774d171db76639c87ba5d7a38d57d73f84818a1ccb4004ac091310c40ef8982f128951daef12c7ed93cfcfbdbef1120cfafadac6059c213d5c2fd17239f43b31f8f17d6200a4a81f063f3693ae7e5218cc32c7eaa8ffd56cfdb761aa26ebbf2d28b1e881b554fdeb37d06b551a875793bdb0969a2182a30c704f044e3e1e17717b6b98ecd3f365d729d340eb925c20c3ba5e6425677297f6d4e4e4facfd6df5f7f7be399a9a7a674a50422d8ae7cc0fc400bf4921af7b85adcf5d464492b15a5b339e8e78dd79adca11374142c6988d24b4ae9a9a90e50b2ebd4a21aa3a44e4d32e1a7a79844b5d5c5cdd607d0cd1f99388f85572c98c89f70ebfa3e86dff759f6ebbab5a36c9ccb77d1486d9ccbdfeb69d0649e6e32bda3a993eb97375ee02499b33445d523711ed35f03ca203c6a41ab84588e693fe3a6fa3c2592f031e96d29868b323b77c0259c6b09d757290f5a0a827e333971e26af2656adb0850efee4cab070c687b57283b74349f71f9f46d5f410afd878d67b8d3277c170117f80bb08095b438943dcbcdf85f1207bb91fca1ca13de94cca1cae35e215ba8e2d437b351c7757571e3d52692fb8f00892667824d242162307b9a00eefa47ad4b76fd5b6275b21d3937df5352251e688bbdbba4c6e8c85793046b2eaac98a76629fbd7eab091db8d3fdc7b8d8505492fb8f3e5b8df55b622792dea640955df71e5feb13ea93eae66fb72e6c5dda5cbdfb824ad4adf39bab7100957d9f5e50892a947d2fc0a60ee2ff19336cfe760b7786fce387b897c4f82b9f2e6fde804da50a3f5bcf6e5edd5ce5f1d736dfddba2482a8e88bd296376f88c0147100af2b98f50acffaf1dd17f8c7b35b173e5d463436af6e2e7ffa31affdd9cd5b9bab50220ade3daf12f5eef9adf39befde3daf4e752a6a13774d83946013c4b2869321f54e8a783bffa187039b2f743d1ec82cc7cd9b9b5737df6b6e7eb07965ebd9de76b73cfdbeec6b3964b528cbf650e8fc7af3b7cae6d5ad4b5b4f772a723ebdb6f5c32e89c97387746aacaff974797365f303184b0567e8fb4a674ea1bb89b3465a9b54d61dea6c36af6ededa5c4e50e0ada737afc2c4f38beaa717b62e6c2e2b9b37eebef0e9b5ad0b9f5e4a6a69a2a85a51ddbc02410566edd6ada47e0683d528c3a7cb9f7e0c71306b856e268afa19d7cdf08c9bcb09cd0c0f8c27aad9bc0210845e46061b71e91b9b57127a1911fccf52677c4dd77fc2b37f7b19297d1ab2be9c781969c55c7f39f132d28ab97e39f132d28ab97e25f532d28a892ff4dc4a46bcbaf10c2068ae5f95717dbdce62eda256519ba845c0161005bc3ec2f1326c965ede7806a1200c8480e5b1f47fca516dea1556a4307d5f45fae9c633f8aed047d1db3c40871474399b32cb5d7f4f38fbbdb1bed29125492485a4b7d61d60e219a55fa2a0b3d23b9f2099eb6f6f3c0db5ae7f244966ff2a7624c22eafdf068953f9b6afacaf6d5c5c5fe3aec88513d39faeaf6d9c5360638a1842a68fd73f94ea3158c93fdc7866e39c74fd2dc86b3ab2860ffc209c0fd657b0badb991793e2c86a94b9ff9b4912227640446a65703ccef0f1faadf8d5240c34e2c45beb6b89579344f01b7b9c273c9bbd79f22475e6e5056a9bdbcf1cac7b0ccdfecd638dd0817fb679707e36f403738239019df6cce373f8f3b8db809fc36c8e4ef7b965f264f2ce74ddeb040d7085b17f03a0f520574fd239bf4a9d696a1e0ec5c704131f87aaae273e4fd086f87a34ac517302bffb11a227e91c42446808096040692cdc9bee3c099898130cca9827a03e28f05f80d63c1cce868ee2bbdc8e4599acd0148139e20594bb094d242509cb5ce858d9e23139798c95abb45bb2a022c71f086669644dd30dd64ee8c693f4079603f4c02a57f1914b4e301eb63cc54104beed2bae5db1b8ab3ddf75ac068d0d6c443032b0f981f583a4810d0f4a031b376960e3260c6ce6c2d8be06bf85798d1b9bd7b809f31a2b615d63d9dfdc329fb79216dfd5f66567561936c5c76ef931223ff6c88f07e5c75ef9b14f7eec971f07e4c77021fa8a600fefee4d054e550bc3e6a96a6137fc1b817f7be0df83f06f2ffcdb07fff6c3bf03e6a9ea7001fe4189ae407b194c97ab9f7d784571aa9fdd7e2f3083ea671f5e53aad4125fd3547c04ff6b457c397f7ca6263efdf6e55066fcecf6db8d7e24e3d0e3e6a9dde6a911f3d41ef3d483e6a9bde6a97dbde9c48e73a75b95d9b2f9b459aef63662d8f58fe5eab77659f7a30e19de5d724aaa4fd5a23a71104d17ca55b5a81e7a446d7d2d846b127a77aa0bfd4a24f4512376c965f3ba44556997a1f7f6214a76ea44f491f60735c5a10dc56edf2e6777a78fcfb67fd5506ad4caa4260964107e76fb8aa3049f7df846325be29562a8e10721cd247681e17df6e1cf933076b82dc5aa13bbd2c0fb5f2b9f7df84619a9e17cfb5796326bb57fdd8828a208d58a6aedb30f5f0f947ab57d3bf6392a4255993a6b7df6e1ff8c68a2085564aa033d141146111a97a99c56c47e9b45b01195fee333b5884e62e0afe571942c9d3d3354f75958719306694bedcbedd5f6edf6e525affd917974a97d6dda6bdf5e6a5f86e012da772d55cdf6f9fa92d77ecfc6184878b47dbbbddabeb6643edabe6d2fb53f32dbe7dbb79766dbb7fd60c99c685fab2f05ed6bb5e9a5f635cf6cff7ca91cb46f88c04f97da37e6dbd76a4bd3105c3adcbe566e5f5baa41a88f191ba2692e1d6d5f9be658994bedf3752f8d0ffed890d2be3d6b2e011ae652fbe7e5c05c6affb47d639ed7761fd4796209c056da97a185e3ed1b4b18687fb4649e6adf6e5f5bf245e8efdbd72a4bd01f7e6509f139b5546ddff6fca50ac7eea8d77e4fa44c2cb52f07eddb1e4fea6b1cb7c4db34debe013f58a3b90455994ba7aaeddb1c2c34b3af9ddc52fb36a20e28637140ce3cea2d7558cbddbfc3d3ffc047784f2db56ff08150da973b8ca821b5d6beb1e479ed1b4b0be91c29abb4cb1d06d4edffb9d4bee6073039b3f01332e0d852fbb21f481930cab113e2d67e6fa9bd9a3ef4685f5e9a6ddf40d2d6beac2ccdb4af2d284b3eac049c627e2cf72d61647b7509226b3c7badfd5e7b75a97d3b685f8b6f192f4164fb362c3b1f091fb46555a902c4db5e44faaa4bed1b303391fa01303e0d23a7cb38497da47ebc2aa83ba8c69e97a1fc6ab054f59102429ef647ed6bedcb09ffcb1f2d6184bf838b5141b5291f6fffaff6727b96b836926475e2b3dbb7ee9cf7f0bf79e4ce398fdd3967b33be7cccf6eaf61ec3987de39671ebb736e769af12cd3d6b4651ebf736e2ebc73ae129a07673fbb7dabe642cc6c78e7bc631e5f600bccfcecc317ee9c5ba077ce7950fe6176e7bc1dde39cfa3eb08f84e1f559d400b31b2111787e3c01190d5f3ca65d550735c2fafb34f8531f53c78e79c8500cf9b074f432b8fdd39e72306b3a103104e7ff6e18b77ce7ba2013c34fdd9872f0266810578dc39374def9caf61a1a0efa6585496ad09017bf87f3a0bb637d1e4c0cc83a711109446101c0216bfe7a6b95aacd5948342f814ee92307cbf343302d483688af41e5e2aee9c73ac3be714c7ca524c1c409ba6529294f2b30f5fc01e3ca704ee9df3ce03302e53caa4cc1ed3cf83309795647c6f30360e7102cc4ee8a763dd49bfbca9cc7df6e18ba76100d10a830ff5e9f0ce7985d206bd735ea958e2690a11160e2d9239e7a8c369673252b8b658a077cecfd1c0e299aac918e1e202eac7a6f02c9554947075e1fae19d733c7d3c0a0a57179f7df8620516354f6e2463fa3abc882a79caef902433187c4354ee6c356d07f2e7b5735fbe79c9fcf3ed17f067ed39f8f9e28d3778e4cb187af63d9ef60c0ffd0b866efd4f0cbd785efc0840f085b07a13b161c8b71bfe8dc0bf3df0ef41f8b717feed837ffbe1df01f8375cc0ff58667877166e4cabbefcc55b5fbef9d697affdc6e45f7f5e3b27bf6ebf10c53d27bebe78e38d28f56519f7ec7bfde8d3173fbd0ad0bff8e955000d3fb75fe0a1e7e0072062e4cb18ea010b891380011800004bbff18689e53285eedb9c02a852d29ce28b5b1f8c7ff9e6a5c35fbef69b84e14422f660f5ff3c7dab56fbe2d205499e321980062433d9b2a25d87f96eb8a31abb4b6c7a5fdca58a5e87c65f5c7ce1cbd7af36bf7cedda9fd79e6ffe79edf92f5ebcd4fcf3da7bfce747f0f3e5ebbffcf3daf35fc17282c396b60dbc0a19e235457611bcaa282bd6f8f59a410864a4e583c026b27a10f844460ebc0b622307816051e2d69d97fcf9c3e7bf78e7da549a8d7cf98b1f272385b4fce7b51fe133cc694ef1e52faecabc09c9facf6bcf4779d3ece05ec2e397affda6f9e59b979a5ffcf4ead774871ea6e0a8bcec92887ef352bf4bf55ffcf46ad70b2dbd741d5f5c783666665f3cc77d327f71f157ffe7cacf22c11fbff11de82f2e5df8f79fbd1509fa32886f3f7fb1f2d297affd2e12ee65105f77fee29d6b91588fdff8a2f39fd7de85d648715e06f1fde62f6e7d1009f1f0fd8d89ca67ab43d5b9bf3191fb6722ff7e6e15a0fffbb955000d3fb75fe0a1e7e0072062e4cb18faafc144d24a81ded4fdff5ae6f15e1c4cf980b9075bb9a73798bf31945e0ce5dfcfadfea732947f3fb77a7f0ce5d92b5d18caad8f7b33949ffc22c55020183194d79f4e3194d79feecb50be38f7a3244391c1ee0ce5ebe21ec1c2dfb8c7dfb8c7dfb8c7dfb84756ad25d847d68c5af20fa52b03c92afb2507e9a2a2fa1b0bf9eb65217c4a3ada9e3d3aa186a3eddeb35727167eecd3898b1ffb75e2e3c7019dd8f0f16021e1fe218c4f1cd0d8c6342b34a0a669386c41f134a68f62b46f9d6546803fad305ff7dcc00d1a75962fdb8c7a0625c9b80ab359c00c2b1539cb02c34dc554a96ff8a9189f05864d589e9da9bb5ee01b61bac1fa629cd4956830beb4d900508e60c0085abd7b6c643fefb1bd0feaa3ddc0ea8bd68c364035a68b37700786859d05768ab87c3fe94e9f66e540392aca4da99cb8c8f8bf630ef368e07abd321cf41b4eb957e209cf3dd3c0c82e0dd1a288c87652e5e5a040a3cedc1925c8e5e02f7f1ce30dc3e01fb95c9068b3d34a58351147dbdb31d3247c896762c8027722f02c67b6771f3aa16d0f184c5f0cbc861c288757c8f45699025d60fa622b91cc06553591d2129dadf619cedd7b0f8815b06fb75801fb46ba8f2cbe17ec129fd8bc78680ce71c523158de66ce6c50256523109fa3d68c561930cab9dc8016e672e5ef5632b361c6b06166c38cb066b4995c8e0703994d99318c0073568da1615233060aa46eecce39255c5e82e78cceb89e66c3f4c7de26fc33204c1f1d1cac3e5419e5889a069bac4e9186114c56a7a03e5787e879232cb95a8398a44a02c288ad175dcd240d5225d0561b51e3150d18c63c0ecabc5e769dc07242365a33068647a73d46e75ad68c5697f33e205a7a0a40b4a5d549a0e7729a09dcb9d9f4359330ec4d5b8f9a5ccfd7431f687d4bd7f5c504f816b37da658339a3960188d5c6ec0473445f1544e01ca16b44463d029e23bd049addf4cd8bf8fcf8491033011f88c8f672c710d0b48cff105e784e7d6991734886f58900103c7fc234e58631e9db619b10d4febb481a7de6c58634ee0b7345d2f79dd2eb400ddc8e55c31cd890abf8ca93a34ba23b29598a676bf85ce12ad1c11d37dff7e686590cb0d0479c7adb0538d3a103f68662ed74110582ec772b90196c8ca886fb880ab44c130ac92977f389c9961728212dbd0fc929fb7fc54b4de6cd214ee1942b25b07f2d99d96ecfa47ad542c342787870e4c3d55f98efead5d3d16ab6cb36c81b44b1ed00203680bc86f070a857dc3070eec7e70cfbe3d850307868b38495527ac4d334f350cafd954fd466ddab5d501c3cbe51c79054fcfe5d87787867339f6ed61c328e472eca17e4c63f77e49650e1404953930acf3beb6f2960f3d5a39e87914e6945ba29aab17bd44bbfc3ea00b62daeedddf8b2149e2c9096a2e473549b2605e015bea837a6f3e17334fd61dcc3df96e14e96490747239cd996453c09773b998080193562c47e18b5373745d6ff5ebf661d1ed7b0ef422e9fa22d0503eb50ac43234e0d340417549caa36e731eb2467566b049aa0593cee0e0943e1539aacae51c98fe4c6e06fae02424aebd07f84418191602d7c8ee426f24e5a641637a891529469626d954d1d25c5c2b9d15a61403829a71ed80a45f5a4054d364feb85b096da692c5796a87ac385068e904f382446c24e898ec2a6644a44cf2bec0c0e90b04d7310aa3ce436cd4191cd48349672ace3ce94cc502a4d71fa01303f48cc2a8f7101bf506077567d24b02f4a646f9f3fd304a91539afc8ceb1da1e5aaa67591290c83465765f2b45eb71b627e114717830d738e1a81de6ae93aa182a9680562c94ed1354f6f8d8a277460ec4670596b9e41f55ccecbc7bd5af28a8bd1de2249b0a30ebec7c825e42d6d6464a48b2c9fca1e24ea06a121c88f59cedc21d709a8e530cf1082039f8d625650dfb7669d6633d95972640263783478283b3aa3c1e0a024c8f1600453a3b29807abd4d1b34c34c34039d57788075497c1c8c2f0eaadf8762735548955cc8c269022e77292346712f256c065e752176a25b941abeb75d25cae4f752c5f761d3ff0c272e07a866144f103f23b6e6849e2568c2ac4d55e80b51e6a166cad42cdd10ee87c6f357c20bbb58a5162c9e9c4e2e9c45af1e33b9558d6d28042fa0175ca28c9eb7a50f5dc0505e4466033473ccff534f510751c3750600014aa946deafb0af5151ad16435f1b44f3986ce12e04eb219e631a72c6102fb56aad4771e089469c61cc572acc0a2b6e5b38a32a4f8619d799a9eca81a24c4595fba201d8c508d96320b1198947258e2db162d0e2b274e7500e0c682c5f63017d8c359a4d96a77620beca81678b4fbf6acd40b4de225523bb50528b217e3d4bcc7ae28d56b8b812e8d1a4a79d54cc12548cc2b81746dd87e8a83b38a85b936e928ab93123313ca3cc01335c1d82423132099153f2dd144bd775e2e5abd4a9d8ec906d95e73adc2f068687c2a94f1c23c897ab965df19843a811e45d078b807ceff03c320a449c5404d05f8a22834e0698a459273c36cf9c805572397ce6253f1d0681ebe4720333c08d1659bece731ce6f9357d94fb88942881302dec83518a0e5c62837c6df981eb3546dd921d990ffb7ad1e63b037c3aa3ac79c4894844c756a3db4cc9e538593782ee6b610226a6c2ced43de6fb30ccb5d00f14660555e629d30c6512c5f5128b8328b078d441590330ee68ed4bb25af618856d076ca4e36dc46282881405c76584457b87e2c03059f0ac807f1748d97566acd950a4155ac09b73394dd4e1b3e084047d7ca6d43516fba6085404b1304de06c28e3902469f6985349ce7b3e8b98c1673957f2c4f3498c144a4c79db2d53ec96205f83dd3709f27e4003ab0ccb899d09483cff80f0694134f6413e7075121a419e9da1e580540c280aac0c77d3b41c58f3ec1050a7c7698d911998c951a81ae598081a3623352c0c5f7523c85bfe414c2366976d81632cb6d2cc8ae941e46eced3bf6b149acd1d712fc6b917ca25c0c2f46829431f4faaa2a354a2ca5e52898abda41235d54b2a51652fa944153da412357055a262f76009e4f344cd740d144e7c27ba050bf15fd925ea944e1a862366e8231e9bd110b0331b733dbfb458a741d5a13556f45b455f27f3862bd77ffe904034ef3a7643b3a246c73938ec23360312a7d9f9936e183082308bf1f6d210b29761187e490d1d2ea056d422d57c5d2ff9f91807825d500c09ef826285c8de2a766ab4127312081e9f95963130a0d54b758d12472fd26e48dbae13e13c4f3c6db1454cb218f56c717286cc0b0219cf43ab54e68eaaf2a75dcbd15445d5f38167d5349d60cf17ad1242aa91aa5eac91aac7668a0d22086c9125a9780b4479bd45829666e50fb9b5baeb3027d047ab5829d02cdf581453aae84778fb555a67da2250c9442c744bdef24fb21f8496c72a444ca93e39e209d13b534b4f9690dd9cc8cf0797609f7746a7a67c677234a6710ae3e391ac55f65d1ac92e0d9c765d9b046eb21e871d9f818ed42613fd87939f64b1994a3595cfbf0c6c311933b1f184e9a823b36e3b33f029d3d1318915dd99281776a6435aa41a736cb7ee1b8bb287068645730686651306863b701364446d25b6835a81d8f9052ba8e282f674addae77861a4302c746a85115dd33aac15d185342afc12fb1c7adf5b9c8ead6a82ce47f425282db68a01f10c275e4b2093a77a0876e2796adbeec2516adbd3b43c477c23523fb8b91cc8294ebe62f9759b3670f58771157689e58158817099c852b44925c62d65a789a1c84b5a6a3fa6d1782c5d6f817a95936ca6d91cf04bdd12b48ade6d4703fb02204d7a8b2c26310a49d407458f247ba068b5125b5bcdc34d4bdf4ded3d862b527c8899c0d51e7b50e99177f85608374636867d10071c6d78442715c3d11ed449d9b0f334d954addb38b3fcb47fc26333d61962190c0f9c886fb004990e61bfef93723c5e6149ad58f36a3124334268d3689eea206dab121ab04feb6c077ff5d504a797852b50d821aae5d4c36068d673c3baaa13c03ecd0dcb4414f0a0c02290dba04566928cc6d574cd270eb1723967501d52072d58252d5d8f510da170b2ae215aaf33a7a2eaa4da3b4fdd632253ad77262e8e2c460ca8a8fa75eaa82d7db49c9cd8867a0c0afd1d369494f3a7d899c0a89172fe24ad586e376561675fd4707e76e9248e909aee2a104e8aaa07e0d51661baaeb748397fa8caca73d3ee996faec6b2a82151e941ec6c638694f327789f1a20f852a3fc8d2c8807613d7c858510cf7f580d80439d55f0d46adaf52a0cb97e14b099ef931983e5abee3cf348552ea49ac1f2f3d4b3a81390ba017b05bfee3a3e97aefbac9ce4921155ab449515479f50ad4a54ac345e6fa242948565755c724dce5b87a8b857525140d574cd220d52cbe51ab86a6aa42a3fabc4e79f1122151e8ed12927233852333c8aa3a69359a3cbb4e1f5a7a74d466e9c277c91eb78a856e763356d00e844e3e4e9705616afe772dab4318dcda877232848c692f54db7c86cb4499e856a616656ee3133bb1d0d9be6aced4e53db0c1deb072133ad8a69aaddf4d4b18a6dd2993234f8df6c16f4c1e1d63dcf897b2f91dd283f2ca254286446ceb4f8ce588633414c4e31350827d8df4081cc32a99c8872609467cdb3ca44400376d4736ba821e8911695ab59672c07bf62a60a720947ac452c63d111b572b590c8ca7795883bb56de6455f1817a98778c00a1a08cc3516bff52d3e2f78ab6b75eab11d34b83b6e3e6e84a57ecb4e104e2f6ff9e3ace66a4c2fb9457f92e565bd53cd266df9935efe68448aa6d258715dc27d22d5220013aa9c32dc517ec2def5dc825464fc2c0b121b72000afcbd6b22d7d0fa11fbcc241f667ed9b3ea81eb45cc137224d42811bf8c15025d960117e988c79551622147aa2807a36bd2e7705573f4519acbd101c3a8e5725094124f47ada66b5420b59ccb69aee14abd5f19cfbc22cd856fd85aa093ba616b8e4e4ca3306a3ee44a1dfde0a0c92b6a18eea48907ff039a35d9986a36bd5ccec38f7a2e57c70f3f97f3271b533a2f316fcc680e69e8a381d7580cb58034c87cf2ce452b3a69ef76ea19e4ab6ed0f5a8f09b9015352013059d38da83233a171a87f782d4883c7366873cd3aa20b78c5867888143a11fc042c7a899143705de68f9dfa7b65541f668f9c79c790cd5313481fb5c6272a1b3110b9d6649c8194593cc77304f0bb962cc41d3386458aaa81fbf44edf8cdeb96622a9995b5f8f9d067828cea28ad92696316e656e0b9f6b18a14682d88c46a8546512b037e215179ec902831c41ba21793b92ca2ceb85e6d08452699a30bcf6a6419e63ce19230b12a45a7d99c266969788658c0cc55cb1f122dadf190255b5ecfe5d4baeb5b30ba435ccfa00aa97974262db71e75bd1a4a8dc7b8c83793d92767a53e71150788c05790c13213294c4d2414b7829a7d34417aba0a537da7828000c35deb33dc75a3d639dc0e44760eb7d531dc369d667666b89dd4708b1cdd44149e941df4aa1c74d180e24cb359cf8c7c087b643e8cb51ec33886c07194ea468d985f71d5cf740e16ae6dc7b61c866bb962f920ed554823b1fee753eb7fd660f919c62aa83d984e8df5388ae00d9b913183e5032bb0199983af469d910583e5b193c81928240f6c9e840062444e716272382626a72262728a4cdc3f31e10d53892a9bd593a8c8067508f55cb38c4d81df461d7ec45827f5d9bc09114d3a6ea8fc6eaf6a18c65cb3f9e4a8651c4f4dbf99ecf4eb4767547ec074a2f7d48fa73d3992ca050247523725b9d5625400a8d109c291291e6fb5743279821c27ce944e4e1bfc686921971b181e30f0f70c39d4659750cdcefc0922a84ca21f4a31c929ce11410df978141b241a8fe23c9144be38709ac8c12b9a84fac5c3b04e7a6e7e2b799a3fe1b9f3568579f2c2c79156ef2d05d7468e6756e434b1c8f15c4e0e903a3807c4d81a5487c48cd25be44cb3d90915628e7a7416027c1b7e889ccee53a33d6c922cea9e2588b2ce8446b349bf37ab78c619e8a8e6c94543e5b8baa6409b00bd239e5307b500e9598fd693fe14d2a0e0cc71d3d301c0d0b7eca711918261c6b556d11338fccc5a812338ff4c9a88f72710c18bfa38d3c28f7935f794b1f260905ca27d124af725a518b69455568bbaaa4bed33d7b72fd4ac891f62b527ba5f880d07a8df28ba7f7b9d0667071cd4cdde70436bb4de05a76c1d525ab49cf650bb90b09f93499ed9c265cbd35ca77ecb3641c24ce7dc32070eed77532f69546d0b5c39a83c3e77bc71dbbd145b8943241adef60212020c408a6b75050df0965ec31a482a98b21853a8712f1a31dea0a0b2ffa9a426d29e63c17e11c12e672aaef0db988ad95cb99d158578d2af07eabd43996e3799a1e4dea1725938947b3110911d516a9e97a71875248765664e1c0bc18eb9c175ce6206319f2c187040f56704c8a03c35c7c9c33c6c8c25faec2a37ef2c8c12fa97e8ddab65af451a9570b0356e9afcecee8b1898a65bae9b353b30075c2dd24bb30bbd0667a2e3452c9e5540034c4eb9462dd4267ef9e82eab0dfce180be4c97bf45b4f72d1b1cb6012b914f315783c99c6638227922705256ff05ff2a4a0e70dfe8b589e329e2487c5c1c5c45719652164769e59206ba181d0da529fccc4c35f29e1e0a8c54affbd4324e825073f02dcf340233901ba8efd4c4f793e7b9401eb7e818abd1baf549c6d4422031f8389ceb9a09289cc228b78728b4ce44fba0b12e1c3789481f3d57317549d4ce4917c1bd364227f88d339633e4f21040cde6890893c1f66e3149910e33a4726f859c619549b4eec446bc1af778b3bbdfc46ef1e5457e41dcde597fc0aa8c9cf3b9acdd514bbf77335c5c85e9dcc88a953857205d8c4a1faa20e3ffb7562a232146f6d680f3ea8937943d33c63b1a54f9af9e92943f5abee824abc49334fe3108817e18e26623ce1bca444e1ca6eb5e494ea2a1c4ce991464eb391bd88b3533d7d0157646920309db879d739e204cccbe5a24f8d012f9e74e3b91876cc3933cf4872aa8b09472b95234e65ccf203e630af58cfd31671c9a2005cacb4f4ac654ab286e4c50f2f0dbe4582a46addd76086d10a538943bc8ecb20f3936c4a4c65214f64262e17126bcc0d83e248a1406a6ee804c7059603c3247464cc198b9fcad7eb8c7a38d7b3d2096091104c1ced00082430c5c67532672c22b72b8ee5a9b85cd0ed0e05a4f2cb020b3b9c2d7c930a3345c0206e6a0ed91dd346ee0745fe141dea37d42abf57a8761b6f4ebf6586ccf8946dd7672a71f5a8995e8bd83ae952059e6c9245957a161daa5a950a73d4a21a7821535b446dbfa6f62b15571b09352de274656a8700a58705ba0b89fb3c7364213349f8b0f11242f7c499a0a33db85727a78c4558e1a8c7f7a8c3155ec569828d1e4b9455a8cdbc406d91c3a2040e000225133b1aece4c136238775bc3e11b12dd770f20017d5b171ed40cc52c2ac139394bae1442789a6e1e40542781dad62f935cbf7ad699bc106291f372e56615a9c23a5cfe791dca93102bd7731f199a2ec09d47dc86a55a2c695025d9b96f5d6a05e8fa8bc4775329e62912932676a03c384e159fd98d165eae0c63a3da15dd832cac19a2fcd4af3a90e5eeaa3143d4deab99c380e240dfe996c05d0d0462ed759f719a0877c3d8c133ecbec964eaad1129c2f75169a4f239ba14f8516992540d6dc964ec6f4a25b1ac3cb70d0fce3b293aac896ab7b547df4787a551cb6e6f14e53e5a0ffc81ee4f3c9d483d82559ee8f8cda72e624f419848edd37645bce5ceae6c29379da0231e011462b9633dbad4c9527a58a1d6fe93be2fdff6dd777bea3fc77db2a33c767ca4946cb81323fbc373f3c922ffc37e53b8a0731b0d82b213781ad594efeb4ffdf94ef40ea21b7def0acd96aa068655d394acb6cda75e78872cc29e715ea54142bf0153a3363d9160d989f17c54e552d5ff1ddd02b33a5ec569862f98a40a1a2844e85794a5065caf8b153325a99714300e7400280183b76e8c8e313479419cb66225af15c37502a96c7ca81eb35147746091215051e6380c02e7948b36fafdedf3e431845ccb81eb10c5a8a839acabb45dcec53f5e2dec2706184b85d73d55d2fa0b6c8b497f85d33cd08a592c8b68fd85db3f161336b6e85899cfb49d8bd56cf85bef178b6e13da4d22b1baa2204b403a4dc359b389c16c00a64a67b233835363d362372ee26d5eeed08fd3a8cabc836426a5db3d558cd15591e24f5ae596c7ab621b2ec25e60e86535ad7c4a7c68db4c1905a0d82ba5fdcb50b2b38ede75d6f7657c52dfbbb98e7b9de5085c19cf550c151b21c41920d759011c7181e753aad8dd0926cd05073d49bf527a720ab03309e38792c5ab15ad2ca2cb2b31fb71c6bc66215b1321101e5ff5107d9a03aaacc5bbe85b7f8075565c6e56b6626b46da5c67c9fce32c5f51458eb10efb8ce504d02abb0798539f396e73a502316c68208dfc7954b2b15e422d456aaccaecf84b6b2403dc77266fdbcdae287ac8b963f0eb494558a1d5a3110f798f3839085eca8eb95d91375d83525f345e927f9a54ebc98d035c3040b3a135b643675f63f1d1ddf4637fd0d46302066af11f0a0c7667c63967f8788966738cde67c6c30340e1544a1b1bf1cf274e2163ec8b0b41c44236f2cb6c874fa35086cadd1691c92352d625d4d8b98341891c64edc4ea4a1ed7f5017cf5a08e4f2990e16963b2420aac442d5d3d8cdc483993a22ef063631f012b29a280fa0c7137627896aa4c22991eab005657c742e65c436463c6d2e899e4ee6f2967f22f458a68f07b8cde082b1580e3d0f3824327972a6e35244d648fe4963718e35f8ad10bc1c629a3eb3e517f2169022e289782a758b9850185f17cf59603b1ddaf668f43a44a003d941fb8dd8461866512ea7f9fc4b27899439d6c0fb14aa3a88019d04fa19713909ed38069ecca0afa175079df4a68c00ad3b0029bbc3d06b683720356c1886add348da359c51f974c1f043764c23436115867a80c268e5217bb43238a8879395a455586570f7d4680258d8b26634b4074c4a43710fd8462625d21201fab21576c24625beb363f1ed142330542e8e948f9773fc2225a6bb003bea85bc18fa84dde1e18443d12e6f0608bb2b445ad665188685f46fc2d8f5d4aec15db3e4b83199b00b3e215edae057688e4b4b757165e678beeed6b5485ea5798ff9a11d188c501850be273002c2f7b486436844633cfc0e9dc0284446bd8bbc386f382f5c0c50e22b3af24659d12358ac584834fc08349cc9da7172b204022282e3c0bf251a519063325cf8ae6c632e779c1bbab184ede5e98c6b1f6ec2cc4a8562f6ca111176cd7e64f8369ab0a819300c3f9753a75dd766d4c160b3299e4290b37a60783432923602dd86558f13583cc3e48b679884c29fbfa5241e4b28626e7c8683bfb524a643513ee1144d00e191dbe2feb35d2cd882b96deb91993b0512aa1a86e194d4bc3a78480b48412f3a3a410c6da3401c234e2f3a836a5125b8a8f296cf1757a0ebf17a2b8c860f458fb384d278b96238838780504c865324d447ed4183693ea9605f46af8ec8fee8669a5aaa6007162b5d0427ad6298b95c30694e359bc1a4fadfffbb949cd429bd5441fa49ba885b15443b302a822ee904d01f407ae6b03381a6ebf98aebb0519da36bf8793c0523a235049a872d88884fc2deca172ccd431a4824671b1926d1eb419ca04f416eaf248a2a0b565055e658c35716d54141f221a805bab07a228aaa0faa2db5e811554d1c41b734465415e7703cab0f253570fd298760c5505ba9d3c6755135d4a26a1454a216e163b72aad29d46fa9839aaa0e323df6443b6914a776cd12ad9b61f8249b6ae97a4bc39af462103d51a48dec4d60fe887cd902cda2b809a05cdb24900b7b703051e460da2c46520d428d04c91865c6bd6166a638d34b8f6b8c78c4e9da24d6d2f562f47c857618df96d1b272512f56c02fa5003f08901f00da3382273061092a3803cbf38f168c351dd406b05dcd269abeceb1069a08c3f8a96a118704bb381a9609a27e2bb70b660ffc73d0b259d0c1442f3e2ef982a47396a1aaa3f17b219601a09d1e6009d0d18324304e6801b110884e8e6801bf6c793423d6c4dce85864077b54b2bf048dcc0a8823bb87e399cf10f44963918b52bcf061cbafd3a05c655ef12849263c0cb187d0d8b7b828b77742c84ae63bce793139e64fb83576122fda32ef6039b09cd962d40ad83d7033a2a2d71a8ded358dc51aad773c50183588490accc455ccc9c8325d4c34205a5086782d225ed9d81138e8fe47b0fb114404470c82e0b05d263114ecf29612573149dba6c0c505d1c51b4eba01e2ce49afc5428216711d3b0dc79ad10660e964867a78cf4872a85b2488ed358d691244d75c0c9f04f913429b608410083d16e71d23417e02d512e36e85193604c5f0a34189694e1c3974f2c829f3d8e3a78e9c7cfce0d88479f8b8f9f8f153e6131347cce327cd278f3f61fefdb1b131f3e123e6d163278f1c364e92b429abd16784d2addabd771f61ba2e1e5541ab55b1d67554f2cfb1069e500229007993affba440be987c342c238b13db8884c87bc8e59cfc80dc289e064ccab5c8d2bba4e0bd68aee58ac5fa4a57b1bec2c5faca54c24070b23295cb4558852590c78b10cb8944a58fd45fe925f557f44529ed57e27bdb65a3305a7ea8325a46a9bf9c94facb1d52ffbd09740f81ddc659c995b9e2c647f76785e22ec8e5a448483496b8d35f266699dae5d0065055eaccb2cac356e01703628af1fcbe78c92015de0d1141d563b472888bd044dedde1f2cf21d7f1c39a08b5f4e8664fa2ea0a31a520ce6036ca22068b5b27e7f9a928e6284525669757314ee5a72da7c2c950f420a312606f1a0c4880847192cd749ab7a41905648ecf50badc798fdb3123ad2238b110f7c724e6870957c5f5055127263e1bc188e9073408fde2d03031c51626c2a7c66aee3d787c4d6ef7a4f948c24a16e5d90021258e72bb4f9c639a9ecc8469b260bf0927cbf13cc96287d974388b73c74869b230f1c8cc0c2bf707c9b324211eabd541ecb6e6d9236867df410cd300b2d9452e016c8c36dc30d8011ec98c496cc67b0d8e2cc84d6ee2022759252ca7dea3e986b5c89546b6fb8c8c8bcca02f59cc9a5598653373ed16cf3ecf3cdf721d4315c71cead771443254716bffff3c2629705b967df281dd913d89a79edcbfa9ceef57750ef29897125b5c6df7ee7d7aa257fd78ab40acf493ad7c03955016c3c8735121ea0532c20d9f02f1f89243c284f1132a6a5d8757cdf4564bea4e48c8753b15f8166a9f196351644dc994b6315020a1c15a899d463583748594316304d717e8ccc4a6815c30a9f1f43aff31b98e34793a93de7d42bb9b4d3574e61c77c119c2779ad4512605b353d49b6581616a8e9e59d702359fcc901aca79558111eaa663a4a0b76194eccc280d1fd82f44cbba118ea6baacd9d42ad02765a3aeb75a9a4702211e1206b2601a35e474fc04c5fb0ae2f1e87c561854bbefd054bdd9d4e6f3dd13333b469df4879ad8de75019b4835329b3fde61b3c6ae7fd4f2dfd1279f7aeaa95d53bbc8f40ecf5dc78de91d9cbb8e75cd9539779deb9aa9e3dc75a16bb66ee7ae67bad79a3d777db257b6f4b9eba9aed9b2e7ae877be5128399c07078984c746f729753dae3dd5b9d3da53dd1379b695bbe407577811ce99a3775a27bba6b96d489eea1ae59a66db73c276a1a268f7ca553df8399a765f9cbce9d476c5ca0eca21e65c623b91c9b7c64aad96459f5a898fc49e54f37bd823c0dea827fac7b485e296936e50b2d51d1ecedf584d242a8ae99d058cf09ef00aadcda73af02ca988c3fc1570c8f3d13c5ca19cde317647cbce91729c7a314396f78fc896cfc18cc93564ab11b212f71ceaadb4f492042e88ef651a29227b3e9722b26d2278af2cd54be8d89364e4690eee04074b0aa924cd76baa3a801e8663bb710d45085d2d26e2549dd778a4186b6e906989f843c9788e8c48395db4605a0da3be516c914a2c9fdc21e971d9e87d84f4543b1a6f155575b4e22eb262d4a7019d15dd39c24f2ff6f09fbdfc671fff192ef0df0345f18682cacf451416b99990bcd8acc07e07757aa80ee6e10914258965c42d7738a3f47239cd311ed73c1ead13cfb08865a82aa125cb50158d825446f330e1a0d32365e82c51557d502d42a26d39ec713cb5c1aee7ca5355d1f8aeb7a24c371475d081349d3886fa94a3280a08bfeaa0e6359bea135c7050f541ab150c1a0e613829a02b5b0b550bb64cf1b61af9f4318efcc9d47d83bfd770451f8b4e6950c03e29fbfee4249b228e712c7a948f3f953fa00d0d3fe4e819c9e2c05ed45a41faf7418645f123c8b3338147cbc19179144b3245b8a22bf506209435027cdf10a522bc9f294f1e853c62e11bb5c43702621ba8f97a38cbf8ed0ef40e105bd7471f9eb4a70c4bbc6c60e5eb55eab3ca49366bf981878fa8e103060032e49b020a48857a98ad80eab9dc592d9ca45328da8e5263a0208eabf25e065e493bab75c6623902e5f42215e77e03348bf67ee2117c5c3a71f07936a1437c62924d6565bc4201fb15928c803c8a3f89de9c74a6f2157c2d8739658bf9383fbe6f4c4e91878dc5167902fe3d9a9a27df8ad6237100533c1de32f36c26acff64da04792ee64c01f3d38d999a7d93c39194c0d18063f6586404743769340d74721c9f0a0ea42abe5e4727faf71a1fbef8c012d71bc1a51e005cba9b80bcd66a451e111f98a5b46f1b8774a5a97a5931ff055f318fff95e46acff07c1119951c72757bbbf7dfa83ec46697f4188e0019a22d3803dee56d82857fcd534a8564b24083d2cf444620efc0fa8fbb1d2f74adf93e734c5ef19936caaf898c1e25c8cf115fe983c41798c04c6f76044be678846412308bfc4c18cc2288bcf68d9e0a0fe0f5a8097e96390014bfb6dd182c40191c3922744c917d6f8796e94d103c47010293302462c065b1197e1ec8af6909049c8358ff15348c330bed76c6a509c40e31220233d1134d88d45087cdf6d14401746138e4a68a4569ab11c6adb8d45ac9d40a57c43193263d73f4e160f0efd834987ce3e15160a870a43f073782ffedf8f81a318388a81dd478f3e151646f661b6917d87f1ffd1a1a7c2e1a390b2bb503834843f87e13f66db3dbc1f520e153070f4c8d1a7c291426178e8a9f0f03e2873f400a61c3d7c0802878f62e0e8d1c3537fad883d35942f0c1d80aa1fde07d514789d7bb19a91a358cd9ec2d477beb58b54d83d6f2e951950a3199622475596dc0c0b75002d97593df01fe6972b7c6337bf2f30c27ff6c00fbfd44683c0b3a6c30099b3e17589f4ebb4cc0cca536aa11f3ce1470fdf180e89aed0c9076fe44d3a545f8b5a7cea588175963d71724cdcb5a96123a29bf04a853ab3cc7343df6e4cb0e098e330ef9153e3638a904f50012b036828c52a8a15e5f2c33abe958ca2a2131ca9f0e78aff9e2b69a2e4471a15ce71a2047c2d407abd5354bdfb43fd35065cc3610bbcb30b646098f0670cc9c030deab9f9c5479971faa52cf67fc3d5c080f9545c454d65809be31561ac5e2553a1113d48ffc20b4e6d16436a80f310c4c4d75474f50cfc9c2d4680d788cc43420c388e9e4f0541a59b49d4ef4934ad48a476767c5b75f67b62d6cd155bccaa1f6a839d331bbb1ba7ce08eb90bcc3b44817a646aa661e09e64f3cc434b077626609e43ed938c2b2b236320ec8c72e80b8c60f49837cf0edaf52abd2f6452d5abfc21cdd0b627ca1e638e42fd86535600a7a3501b7e9db069431116c8be9c72f0cb3c45dadbcb8f135639083d76cc111fca8cebd51e77bf2f4c0a156ebda3d8ae5b571c97bf55a93871ba5b678e02fb11ff18da0f2a1ea395e38edd503cd1118ac73baba2f865b70e3f8cd66ce6fb8a15b0da04c4ddf7fc1db9f73095f912435b5c3bb0ea380adc4496a83eb359192d74775a5d21bb5cd432ad4387c1cc73171cdba53b85b6a7cbe253cbaeedab44f5dc053f7eae0f2da27606746f37a09ebb30814655aa1f502fd821a807efd1b95cddc88c5d934f0d15a7b4493a74764adf351bd37393252f014c0e4fe503f7897a5dc28a597c83c51713f98ea0d645f82c2149c0ade6a838133768092f61e6f9a36bb085db1d093ab99ca6bae84c72b230d56caac7e5377744c443c390f2b8fcd675bdd9d4b2aad9847a2448baf2c8a40e1886c31fed77f81632724b26efe9c927edf955bf48a4e497fda4570b51aac0affac94b85321a77a9a2b2d28093658f45b542033aa40e1886067bc7d4e0718dbc56200fea7a2ec7adf22027d3333e1a0786f1ba116f9e1e2164cd685edca844aba56644b45b6ee3a5e38951b19f9745a1b379dc8352df60f98fd3c7b540281bf666a39bcde1ef06ad0839143ca9781d5e9ca97b5cef04b3a18b739281818a388a986184e9cd66142e433897d342261d509566701d0c148a5a597cc18cd75b1abab012b53825d899d7dc797650ca181afa02f05990882178714a2fd2acc051629334256d4c1911e4910139a77339552d3a452d30685a96215e3606a51bd21f3bcd314070d2a800af73098ae67203057ee3532d02c2c42ba51bf2f8041e1c385d1ae8e03330d15a9ec7459f9ef1624ac4933975bb3575a5b5f3126ce2e5fa487b989eaeaa9ad8c7ccb28420818d140a135c0f8e5bc1ce82f9cf5f774285566a990075889ea811b753f9b3b8787537ae6a9af19bca264a16a73c5a9e635eb3a96562ba5c9440244b116f2a0ad98438f77a41514b79ca49f8be087482f74ea39d7917029ab881e37475c7e340bd3d527c1648e28cd9f07d6f9f059907b6336eb0181a78a7fd6c905916741ae528347ec9546f119f65aeac61e3889578ee94e9ad964efad49bf0fce1e4e3404b278bb34cdcaae9c4c3c3ca33a911062de2076e1d47d6726693c5b3a3ce4fdfd03fa202a3d26a01514d2e9571262fc1b1ac43d30c301cd120a6c4d213836c86c6477f34f66ca4796292b1bc9865256e785d5467a8ed33b5c8f8dd66bc8de4e97c4e68e8e08483643a192824b01d6349ebe540828dcc0584357f7a6723ad6d939b1f19379f0c0868e24ead53728a2c6f2e7814c405bc2191171e8f04e05602b3b914668251e79355025d4bc7104f3c2f1635a4147dc5594565a38e31cfe4353cde6d25f15b747492c1d4584ca35af48888e0cde7d60f9e6bdbac524c531a79801c931b8c2965502da6504910bf05d1133c5d0be2227a2e8752562c0f0728c64545cf88a202849862f34c0be43cf1043631e777f4d89fa3e19534e421c0b290a862b166537c40ee5c4e132103d962314ac3703639be64ef87d3350b69b507bdc3601b0a013d79cbae93e309b2aa8f061d07c822a5740a9bcb35718e5eeccc989c34aa9ecb250b60ef2433e83a91d34ff4b3bc649f9d52d8d67494313090cd95189f27936ab09eed6936efd582c8776734960351ff0e188697cb89fe1dc0ce4edc24c52a62874f625a8821180d903c765fb37cc539cd66909c18d16007b08492581a410bcfb334c7e0678a7ce63868b8ae2672c73dd79f5a1004e7c450920613a7a29e4dcce620976379bceb7958ea90b9c70e79ab108f64853008d2560aff7b7445319d3d39fdb3609c24c3389cd1d11a545b8cbcba485ff9814eb4a08bcc11b3072ff63124f7812c7d713bb66c08060dfede42d0d212aea6f8804437696104633427586a6f0472975b87141f900f92fea1a85118a50f3952354dd1afa5fa2d75d099a4532079634ee1f63279f18a1a9d13fd5b20fe3853925ee1b7dce10fa094aba5e20c8a0ed83c192ffa7e422603fb0312b4c87150d541e0023a1186661c7796c41d9b3b49050a400d237535c4fa3164bc83a3f1aa69d7aaa5c74cf4cc8a7984ca066dcb20466fc91c827327f08e47e3388b8c742352d45d45993da34a185c48ee9ee2d9dd987a341defb10492fcfb4446b2c04a62531071a93ee9692fc8f07722f951a295d9d6ece6a79869331f47179e1d87bf6bc859d871c438a2e321f16461aa15184e4b50783cd651f11c3768f5120144dfc0b4495a38a61a9ce6b19d3c256188c367a103d21a93f43822a34ecc7c92e51356ad92da7421358e605de88bb90b1df2927693e92d163b13086df528a7efbd471d64033e5f13333766032d54353bc15095e195546a5bb3789771689afa0cd58ad4a3d356191f495464e4107a9b54cab42e0b966dab3e54a741957f79a1cd94b26bbbde90f5ff71f7eecf6ddbdebee8bf62713a1ce21856253b491b2aa826cda3491b27691e4d525f8f0796601b0d05aa2014c7b1f4bfdfc1c29ba49ce4bbcfdee7dcfb832d10044170e1b5b01e9f251493cbba02e1795fdede19af14938dbd676da6ec953189e0e27c675e2fb8a071cb98d0b373ef94ce3e9e4bb0753de355b5572fe98cab2b73010d39abea7abe0715dab42f530bb5774617bcb2e9867f6121b547e7ffac1a653394646a76e12eae2a5bd01aae9a8b4b438ef3ea6a79b1a7373e9bac25674299efbda825ff520b45ab9e9b9f98547c46ab1d28b547e79ff63edb742df939177b9f77f8829eb3883415538ac9bd467f94bed44de0e2dc7ef182ca8f4cee313177c905f749104feed49f98847e7588e321475df0d947c19a666749b9507b104e64674945ddb0bdf1ceb286be348697cd8e6f1374b1503b10cc2d6aaa3ecbd97641d27544a324ffc8f432b03abf08cd48b3435b1a25eb8f6c6f4e9b0baa979538a33e3b6b987239fa236674195ffe5373e1ae175ce90f5d70ff40d4227d79c9e7ea6207601ea9985dd4d2a4e76c561b7d90b90e5f08b6d829314356f88295e0b37acef64ef99cfb0ba9b7097da59abda5a6ea62e7d31ead9617f494293edbf9b47741c5b97ecba73d3e67f5b9a4cb0bc85f5075c116d40c9d4f60cdbdc7c0607f478f2818475726e987517c75b57359cbb91f429792c3085ad473b6f3795189a6fc5c71f171e7b39df05f571c040b2b63b4b364f884a17e2d53aa6981379574a65654b11d7b2567b2aedc55946c2eea4b9b04b46297befa16e5c677b511d469e58f3f5e5e5e0e2f0fc09a7d7cf7eedd1f3f1b98262ffbffbca84abd466518921515e7360902c36dba80ff6a5bde1f3ed3edf9f947e14493519b143d7d2ae60c105365dd342fa0d7bf512d31fe9ace67c186408427929db9c7329f93990a6cb75e40ced76839d28d6ee44c97340f50231f33f09df7cdc57fb9f923af5579c0c8d6365da84595e127bd25f647a3d18fcda7f32cb2258de5b14e10ab8b38e1e94db540613d996f280dbd7c48d505fc3b7c96b5a5b3377e48c4153d4f4f37d61e75bdbeb902cd714cef8374fba64f21e0f0aebb8bf173f1c23bedabe9cdd597c6d5f831c34ffb9c781214082b2b3d7c7d7fb9cc73f819b2cf6cf65634f48c3dab67b47a6c6b082a0a6f557363f91e6c6f17e110a14dc9366d8c41b0dff273efedaba703429e68627a53830cecbc347f6633889af8d34ef19891c76cbdee37a032407b0845cf66f79a4fe7bf64bb96937d7156a0e0e58f76b37b3fc27dacc863363ce3b25170069d2417c88970e0b288ef1973c2896a153761f94cf1f81eda6c62af9557e10c14816d4655e963439e0b605f2b6a73f3fc009479a29eb33741a107d2a6c264ffe538d7840f262a8cea77ac151ad90defa3d622704c547b5538cadeb1d38f5c65bbec98649736adf48dc3fa8bc95de884c20286e91746aea9e00b6005989897ef5891dd7719190ee94710a7d0973506e2bc16db9f78ea8ac4cf01c3b6fd99d7a06e461196a66bd49b800589a30b68d606ff05e641bfa6e6416f9db8fc2fbda2bace800b10637d89b38d97bdc2824076306d140842b3f72847e0f6af2ca9988823751c5cd17fcbf3e257466e9c15360a49446af002e2c2db2f16562bf0850de3ce0a17b8a780efa19b8b4187844b9410b7dd90f07cd241d195d98e7e67e42d2bb2b8b119c23fb4727934407e6bdd6bec40f8d7e427afcb10fe83918c9ed6521fe2c412cc56ccafe5b577e62b53f50c1ca477d862a9389bef303193574b05a9b9fe0f9e74554de76c3ea78adae48229ea2fcd196349570d038315f8a7b9cca5accfa566862555ccbea861ec2398aab08fe6bc40ab4a5f83b7c07c47f10533c0623b9fea6ab5708f5d52605863960fff0938617dfe14ef18fd78489753fb5b1ed265b476fd1d9db6ff64c373a62223f0b67b39bbdc39a44bfc27686961e141385a8cdec727772c084859d8905660bca418b28bac95e922457c1ab60646d4645e5f8f06a4188ff6efe8573234349cfd1b7a6ef4f1ee1184994f7beb75e7187060941bf47c2a5afe28f07d7a9a8f0f8c6e969e077674c11635ff622305c6884ac12c02e48de18b802ead07bdac83389dda8e1aced90518d5b179bff38272ed02220eda000f7531fef9e758582b5cf941c17ac4b1511bad762f5899904211784b5b1405aff00e00ba0dc605886d9c405510862551934950d6da0e0cb55364b0a40cd20b4d1b62cbf0d8aca59084ba4e45d782c8c9ac168a8b15db404d1b7e56585c05fda849193b7b5dffcc6cb113a892c75251a50a8a30bc97c7fa1c93af269cf061c34f2b2ece377dc486a5dc6a450991ae8d82502c090fec8cc1ee1a8c71e59b5399e680b104ba6ec86084dd63fe9b2a6893b92909c5c2dfac48e51ba67baf315f5bb98fefaf9eeb5ab655cff5fbb756dffefabb086dcce7fbde0393fbb65be8c850e960005649f4fca601258271ba730b35a624a502cd75e21a163cabd9c47ceb6d37a5d7eb3b2ee93b74025a2b3330ecafed2da2b072b25dd363ba28200099610a6bd24039824c9c0b8a797cbd7629d2f65e0babd7c63fed5f6a13f06e47eafe892f552240271dd1f2c128a2a1c5905365074faa8da1362d18d8f85b4f5fb0e160a8b4b985b9ea3c74c48e5dc44a85ca2386d571682a554e95d5793bf3a75363c693e7cad85208cc8cdb05572d3f88daad60d1a27532b76eba2e1a40a3b79190fd546ff562667c6db6a2c649329ac8c8506fc086bcd1cc183db77c63bd5cb2798126727717016d8ee4311600b0085a6195e7cefb7ad2d72a8705d86d98bbc39b974c36505e1568bd4e2d6b24ab98e6c2592cb76f54e42b6920d40aae8854055758ef2a8c7085b9032284a2d025b54298773412b78d46626ef31999250eeeb162bf52e1cc690cfbc05f5bb7ba9133cb80aed786b143c3592d4dece33917e76f1bc7a1024419db761761b3e1bae3ce940d97542f027a412823fddecaef6cbfb5ed560a46b25a64bb0c71b1e3d864bf61add745a16ee69e516a5ec67066b72f7d8ae873a6053f166c9ce1e62a81bb9c29639fa5eae533f689556f00abd5f4be001c12e0885d9621a91e272e07c68baaa5837c309892f3306ee7aa8b2a79a612eda72fed3664fd4c8ab399b48f616a7cba5e5f358a2d1e57f4bc017ccdb8c50ad3a4b9017433aeab64b85d532971544fa970a8a514d87f6f79741c0dbe0b95e87bfc13581876508f04a1091de8055411c86e6716af430f763dc4a4d919888cf79b5a28ca05934fc5591d36ee89f4bca8f4fbfb44928381adc6f03f5b6bb290166623b93d00cecaec83797ec7ea56bbcdc682bc118544966b1528d142b74705e8a3af81a373778ec4b1c5f9d21337ee3a34019c88a8972c1b96940240b076df4dac794d51afc99d5b71a46218ae15194daa7b7fb946550e897345fe3aaa8e27ab3c2f5664953a6e825127c714d7a0d16ff452d640bcb646154dbcf42d54647e3280f333f8c6b5058b3359575556fea60a85dd151e8c500c5f0afe10d6baf3b45a4957dce483b8d564c04db80653c3c26618835f9b651f82bcf82533dd19957d8b895952c2c295e750396bb7ca0536b426a8c622c65c188398d21476d2cdbd3121e40f1639d1e6f90f169048d8e397c1d083f1bf54f844e12b853f29bdc69feba50a9fdaa5e6d0fe3eb3bf1fc351ee32243fc3331f14c916f5aa61f3fa52ec406ab5dc51f56a7661bed9a4e178aa13e6bc4b579f67159f7ddc999f5626617565f6197b0575daf46ab93397f45c57a47f4d3d73592f7766f5c26993f4dde8d214fac8aea0a28fec0abc957462b5dc01835b505041acaf1de8951ddb8059bdbcda99adf4c9bc516cc7b4d11ea72dd4c48289d50ef4c58eed9ef87cfd466f0fe0fba247896dba62265531fa891962d59f98b429fd36f3ad90e9d22bb5735e2b4f1f70efd8a9eaa69515bf3d6c3a0f55d755f21a4021d8fc8528194e5668d55da10ff6d72259a429f64b5a29a329f9daf2a5ad29d89d5d7694c583dd53c716f434cacac36e694f375bda512f2b9f750b4714b5c5035db3f2a33e68574cb1426f8390ff749eccc30ee96d2d3d1d505ef6d6161bbfa8d4a5b003aa912cbb0342f8b460e4a12ac23338325570e761451e0acdcfe6f98966c31ddfdeeecb359138660d5e461be91b51b8bd1445be145e52fc9e15c90d905b8248c46f61c9115d11a62082bdc7e6f0838e58c41f3e5ce9097a5ab113b912efb8ba7829792db9bad2670e9b4c1041af74951b14009b0f8cac253e295aa949221c8f5f6e64e8b0556fdba50d7cc4267e2a3d823d6a33dea1649b03fd5b6fb8f11cc3dd7ec1d1fb716b7beee90ae8ebf880674c684e3471704ae7c1d879a98c227b19bf773e321b90f0a336c66d5685c52bd31bc46474efdc7b6c3b2fef7375343a9ef493e13a88bf1e8ab803f4285d82cc303063ff7532391a4d93ef2fcfd5108c710a6f9b76aaf2fc912a4ec177e6d42160da9b87e6e621dc3c6cdd7c666e3e839bcfdccd8fca1f64ff51085f26971196b47260d2a179cedc281d65f8933e9768a28f7034439ad9059bafaa00c018dd7b5ecb05addce4c10f54e201731f066b901b1641a7f904380f90c844fd8bae9fa802fa16b3c0d619d4b930088463e8a41e07e27822934f039bffd6a7e9955033aea1279ee89ec02ce98027ba03a2bc6726ef19e445e44ea9ad3497ac19e2cf490b0b493eebd6a1af37ce087646a1020f0550085dc928ae64825ec27473fe4de14e9e7f0e834ed3e739842d791cf8a6a721f94a9123a369c8b0fbfd9de1a0a87824e619fe21ce097a2ffc5b9c6f745b38b39a0a937ae95391f622dc7ae33352854694f1c065581d479a72fa8e4e7a9efe4a096ed8eeb7bba742de4b93f7c0e781f76af263f428fee2617ce1d42a3ee330cd682c8574fab54f77767193d9698b55cba429aba24993563b93a68ca6264d19ad4d920a1a1c7b61e3bfe07f591cb00e8645e6d43a2115491bded91527ccdf96d132d90ff029e21853fdb33b3ec6dc884c0a7a346a79c8ee52ebb2394668c2c9f516589bf2fa74750ac1d339b6449d977c3773b4dce01816a63c92c786eb740b58a936f82978fee8f320c28f5d9a23fc5c1dd163c2379b77f6f865b86bc7b4db1fc3acdbffc0d49bff11df6ed38726ad797dc7f0eb3f7f3ca1abcf0fd273cabc5e9d56cc6646e79147ad73093d7f1d4e28f0cf9c06cc7f73f670ffe1a4e77fa3e3cac3f6b1e565747ef9c8aede2e775a67af87f1290c7edf2eed19c6fd074d63aa6fec3f7d3dd87a167b989ecb6ceaed32d6554a0f206d0f49f6a8145498a0b93c05eb42f3d339353ee83b413e4a8f929034b44e949ee6c2ae5ff1c96c84b01e3dba8b76fcbf70367be453ec33373df9c825ccb94da79ef9149cd574e2853fc92d6a77ba3bf4297d8c83c40b970827bf17d1710f9eb5e9c3281d9d0e5ff41f14a11623e3703faa3e3faf58f859cd2ea07e4841ed97178c55e67f42a43110e995c2fb8105f8a248e615d1159b451af0e814dd3e7d6f3f9ddb852e7eed5f8a8c267fa97b5ffc2efe97dadd457639f8a28efe52c77864cc007e55246282de364cfeaa37612ece3d2bf43629d23a65e0df21d855809fb22ba693c7c4ee68bfa9145bf529383b6a3edc1e77bde65b4ef74b697dce47a524ffaa08855ce13166f1f172675c4af2c7d622de748dfcd92db3115336a4f339b0c04ed350282cf16084ca6db7e2affa37960db3f55ab2c20504f853614e389b700f68245841b12beed18c0ace0847ebb5c133f235ff11d5fc5615bf2a9c7c8077e60f4ffc99caa97f5728e54af37c6f7cef838ae45b084ec6497df8dc4bc08dd0d67cccdfa1ee44ef0c220b191cfbfadf40b756af9f1974917383bf792a03b15cf7a9222f0cdfeb1fc00e5f211284d8d28750fab0b7742408b1a59f41e967bda513498853b67b31853b507e34538de317aaf86846b9eedf98cc1051c5d5da231f71680971f59a57f7f55ede586f04ac10488fae6d67614640a5e122941800e78a1517709471e312942d099cdddfaa0f22a300d9ba20952a2442c86945de83983d1e2be694104695fe3a45cf274e0cc25bb53255d048476d611d13c98579846e175e1c1830117a3ea537ca2a92caa9f5a8f167ae40b0af502b5637eb4f7caf22f33d7fee30e11d06237c0ade0e4f17f45cef690d6b67bed6bc622bef1d9fab0b93f7f971c53e474988de6faf5fc8b96e99cf9ae9bd3cbcd95c363a79662b3933355cbaf44bd8633e3177fdfa4272f1d15d3d67e734befb423710b000249fdf978cbaf42b53a34d3e12f3e8eaf5928af8126c0fedf50368617a153d6d32e20a6c8eabe3ac16ea1df812e8ab8a0bf6a0a28ba5bb78e26f59870c48ba8fa8e5f2821af2287afa9a7f81efbce4f3fa1232bf80b53ba4ea7a01afe355f522d4046e40d175a3ea657229eb8feca1732f49b38c8349c83bf43e2421af53971b161bcc04f166a6385be8f3d461fd25c3d98bf870a3dac1113c1c8e07f5081ad9f53ab3a6d55929d66be7553b880a8c0caec6fb8e13274379fe5e1db1e3699165bb0a0d95e48b02956a375b7ece22eb2ad13a6d016c25002f5e55fa4e9f97b4f0decf06a5c76d3cd9de5e8630254a14022b7d389368929d5535051b7133b9b359d33c862ce4e05142c598a2529fea08dd6ce2106eefd5165f8fc8f736e48377acda65c3d90595f7553142adf3201b36ab53838e528c117eaf8ed43179efe2ab59e70129082daef5a18b2bb6804ebea6768a9dd2c6ac10d24e6bfdc316a70c66ca05e4f2c539fc68ee52273eb2ab7326ec4c8019ad0ffefa77492585e1ec638d6225e90cca5cc22b369166848ad8089b9f15521cb1632f550fee9d6693bac951b56dc574f013662634de3778b9c69eb0dea139adf0cec842de7661a0b7d69be7d9c909f80c70b1bd54bbe977c6d68ccd3608866f9e77c3219a3beda7f7e1aba34d37b2ffdf3360cd6190676e77ec0073ab216f5a90dc1915a2b65e809f175e911a3b45da3cebb538eb5cef3572d6c95b49dec93babe582aa4eb6a00b5727c4df17e77be0a1e8c1b0c66ddcaa91d1b536823c6061e0552236c1ff9b158cdc4d2c5dd6ebf1b865fa52b6bcffd14491df8fd4f1a4df8409ec9416aa00332596c4635c892462f3dc453ef30798820194409f2b89339599ba8475b36ed9e245f0a72c852958afd9f0b49e5fd9181b117680c90eed9a09172f65022ec3899f45ea2ce1cde183cd4b4c612c09543671d8b3d298ec19d30fef4c619cbad9ae8c3d272c3931bb076aa65fbc81eeb57eae94d8ee766a8f6d268c880d2bad9d88798784389eaf8d3d1fba9624c97058e11b9d1f6c9b36d222506fa0e5329e4f17a2089b0cb3b8c25891b928d044ed706b55569fedb0a19edf4f1f4bba70d49fa06bdd3516aabc3be92c78e53b03565cd53363e07f21d959088a22c860bc312636e68c0a2f2f18693d8f3cdab1672c23cbef456c7aacfbd72161c5e9d4ffc49b6de57911c0b2e00a023f18eb6c0358d3302a67174996625572bd92e9f59236cd652de72113c1539f95deac1cf0166016418916d2a791f52fad0ee744b443b3885ee5f8e94a298fb867bec9da7b807cc55ef846b87565a0861e5a339c9602e659126e2af90688dbb0b4266b70256a03e6e5ae7b8685df07032049dfcdefd89a3c68cb574a6c2d30347b1b10fd5cf419e2354cbde10b56afd434241d2cc469ef23b38a51e91e8a2fec63a13b0fc3ea64b14920a86b32d99d819a5b615c004187166ca6cfa6bb7a3d331c1961c3a5649f78bd6adc7a118c9c47136656989f938d223893cda9a210f4e2076019d7ebec87814f4d33e2702c80f30d5e4a6a6f0f4e91d98f3f585653edee6e7adad2392c7e14e490aa8ba1a4625e2f6277bb833b0eea711fe14b41b29313884df254188c5a670afb43b6fb51e0cfa10048af4c6c36d998bb1fc2dd07ee186c1e8ca2ca27d8bd970254d4c1b322d268c616a5136108aa8838fa208ed76ba11ff5581fdeacdddb5f98a1ef98434d2a97b276e566bf81de74fa69db69c2b42b08076cb1b0500abd0d0b94ec0a7dc6e00f635049bd73eb7ad76ba63f01add7b707d665c59817dae4f820a47dd27b6e787b1ec719dc767e2fc6909ec586f409b27c6a857e104bf75e2401588f3e0381932f790925e6f57537c6449efbef087158dbcf3f4ab8aab85d66b38a1914c3302dac886720939b8248cd58f958204e88570b50fa38804873f520b109aac5c3a01deacb6b173f742a9b6e4e6fd1c3fa534f4e6fd1b7cbf6756fb14746d8584832901ed207add73aa370fb1371f0ad76570c5095b0d756d67999b5364c63823e909d9828ccf2109de83e090ea4673bdbc7a1fd833156d8df0cb630918d8b1710148ac0d01043677a6fa26f6d0bca71a48ec1f854f459f14bd59b8f15c2a2cfb63f2deff37182bbf8c04d34838df34dad8c4309b2e14962047d743c511324bcdb86222fc162c8049bf7e056a37b6a6f6f82fe11853852c7d80147cf3367f5a1771915c0b0d4ee6e286c35bc194e1c129e78aab33c176058947e4d3b380978c3f5774fbbe8ff70a7dc379b704f8f74bf417f76da07c6df22c21280dac0f7e281b081c82dabf8d4febe6ab38cef8409aaf1caaf5daf04ac5c4062f2541f6c5ce7604a2ce41e173b8fc5f4b1b070908f457c9cc19c50d79d211287cc7371c48e0921f4881d433c0e784f4de41eb323613c51f748ad0bca3d658af23d750c8362e29b479c8100c3e37b6a3adef307c428aa4c800c888dd2fe8ab22356f6d708d7da83b499f09cbc69f58c8b8f10f5840b9390b85760462033f6af015e449ff25107a896ea81e720cea6fac9237a4c5421509999376580f26c623398b885b274e5847eca1f5d7411de3c7481acc1ec81cd89c3af0c21aeed9d6937ab04c06ae7666820b9a65f44f9978d18d1e7b844eccd40d7b7295e383c698c30eaba6a7988b46e26de22869010533368c9a8e755d825942882dad035e07711dc51e3632be0edb6d7fb9fee223461c33973fd55203c1efdd2dbea3c6fb7b7ed11f38399daa108393ac6e0c9ac2fd89cbc1598398f2bf2bbd8d0e25711611b5f2f4d5fd86e8c4177cda86c77af45c8b5c32e1a8b13839796d6376d6714a874213ca3607bf100805aa26b321823bc6db07d11c8a00647e324fe861b9bda7a6edac9d9d25863d4f12bec1a06ab31ca208311ba61f0428397c639ae43ecd86d8e7c111b1c67e84911064de723b1ba6121300ba489300f93d922a24f3a0b4a77d1e9599b8cb272eb376eeb2c37ab7bb6b1343ff534dc6c10fe55848f21d71091c034021a6ad249b4d51ef069a8cb5a676946c43c6536ffc656011d6950ada17abe60af155d2ccb2e3ccd0e1bfadbebf543aaf4c9f5b2401bdc59e5a02edebc91abc65d6ef427b1cf8a8979e2c01e99b6c692cd1843bb3f7aad7504d3b9932838108980ccad37142c64017c92e3683d40f105496ec5238b081c7708205846c30d0c5eddd7499bc03f083032dde8c4af16fde237413c1d8a6b7dce777169ffdd7ae70f418eeee2f101deff091fec1fe33f05f92dcfb307c116a705c681ffb6ec882ee6047910c03272a4ccf3e26f11fc27e362a6a9efcd6bdeb0cfaa557f9e0ffe1698497dbf18fc29d6ebbf459eff7c4fff1f8f7f217f0b8495244682303c93f5e2c105950fea392b0ef61116925c9fb2b35a32303a2abf6e8a98d5e2d7f040160c13d31bdb6c14b3d48a29c399b3cacb70e68d9f329c81915d76bcc1d1038fc4fcdb5af82079266d647a6f4b3b8d4964cbe26a8bfb93371c8c0db092761b6df4f7b6dc9ad66e693bdcfdd6d6dfe8bef5f5f61bdbd9effe006772bbe50bcced6ffd040bc7f25ddfb0c1522611eaa8ec951e431d4e28bc371e10f247502283c6f7014c4557185ee4ac73f6f7ef8214cb96f285cca08e1cabe6413c61fcb73cec7f374a8b6f31971128594b300ca2843953945748af2e545100ff9a1aa965e9458a3550013468925c87c892a59038f11b2ddb3658967585088402b1b24db9f61873f650420edbe3df0b2fda0fea65a06c3ff248ccb73e60cd1d3bcf9801e59541dc697fc09aa79653e87d40abef791b2a7dcf1ac786fdfdbb703eb0fddaf3147c96e7e0f9b46032cfb38f35609283da0778b45aaed75c67751f9e026a4abb29795ecb3c2f28d1275754164f453894168f059168ebb954f7f40821ccc96f2230e205f7278a2987b14168e92cac28e1b230c8dfee1ec2cf45c111a684a3921a96ab60e47d046fd7378dda7dea08235d00a0685a38c3ac7d983b97177c766104a7859eb223ac6c80e2684f283d4c82827622428892792ea515b9b6e69161ba36d0e7650745af76c2ca76b38dfc6df0a7c873bb5c4c0b065d815f09f254102770805985193296632d5a98ed2b6e499b02706453c39992d51fec6abd06d1b84d2d98a27fb02b80fdb705f2dc15b09102661754e6f9f89e49b9a3a6873dd299069c0588eb6ef43102aec8a6d3da2d3d1a8d7365c7b9e902d33137f4039a168522ffc66353c861c481382b453312991e880aa1d2fa4f3b23c2a961bbc11889964714abe3cd0657925c832143391861d8b1ecafe695753a73177bd0e8cc18c9500ed6328b5a188b3aa39b3376304695a9d3009a0b3631a012059b1856999fcf604fe3deb292907dc9d8c772308a80ee56f23fd5d5466adae96050c92323423e2e53bdaa01cbd0540063f26fdcb0ad6352b24b43decd5bb375e106ff8dd81723daa157cbb67d7bba3d47901e32b5432b98e6c0c32099cba1a9c008471032c13b33e766f55eb3f7201cc406d8f3cc06eab9902d69e0023a01105fc22ebb94568872c80a50d70477db50e844fac5c3bd37862632d4bf4a198e4fb240d7677a353f93b055cf2e60a72db25ab82061ee1bce25d2cdb52d8f5a77ee5a677701d01dc521c6f27c298b0b8920ba3399e9346618b06510e60cc1d75a0c266f86ae58b190b1ed2a8fe2e946c1b07ccf58eb6b00662df4870171717126894243aabef671c88c1cbbbdea0aa29049fe13db03c6aa430c8b162efc46edc86f2810297fe3de023552ab74ec55fa312a9ce8647afad93caa8f5b5792ac947b40ef9f83de23dc7a7df75effd9ce1cee2e539e6c2ef1096f6031046abe5e2d97b5d467f7ab6fe4d6889abed6cb66698fa09cd068a9a1db969a407dfdbd3c564ff13ccfc032cc07654446b07d22bdfdfe4a161446e0954435f9686e5cd7e4501ace939c4ae0c48ab83949bc367e73bc36da89a2649ba2792cf2ccb824d470511b8844d7653359d4c669a1c9f3a660986285703c1a0b46681adf00e945390474caf328888c8be1f7861514bb7c4c6db087cd067f96b100e1136797460e639875274cf820c9f5fd4a9599d9d733fcc0bcaeccec9e9fe143a66899597620c3af2ff8992a33f08ad519d10afa26da5c3a3247cf159c333df2f819b75f39ed66150c958341c1c80779c48e519e0f0660881a54e5320884de4858f55e4b32c22ff4bf97c0143d82ffff48f2597a2a3410d0f6bd2184b9f860255f156742bd8f2fec9d253d67ef43d29537d4b135595a982b434993b6543317edaf2c1f4a6c94b24e14a7d35614275945159bb7a579b1f82d2902318f344b1505118af0bba67aa6d9749914441bbca83f41f27df21e3d17fd1d83e8ec5fedf32d32c26be9faf7b5d4ef3574c62fe534f34e74c1186bea4beca97254162f81dd1e452df9b0b5251fb6b4e4836dc90bdf9217a1251ff0a3afb4e48369c923d7920dc20f24f9270c1deffc62ba07822598a40913604788e6ab57d24b67c539138ad3ea659acf2b37d474d20e2975c91b578d79d91b2fe7e5cd4bc917545eb979fb4492eb85d7f997d76d456699da04b425601e6505477e47c79afeab86813be40d55c2fd6faed27ecb0ded7c1995e8541b01bce0c4eb29547d437b5f4625bea7ea0dbe9fee884fbeb6ef618aac2b51f4f976078febd659b826815cad323607604b21e26f71b09f53a32f6f4d78914ce3f57a50e7f98027661805277268b66070679425e4a4e6c7fa3c6e43f27076b95e736ba9646c3fdd0e5ea36951138503280c182074dae49719347d031c007092795ea80131c833c694490553266551d30a0bc481ca9a382b923ab66973991deaa5244766b3ff47e28a3c91c330a8f1ca5fc368c373db1119700a71271808c6a4eb06262e5b431ed88ae3f167aa8e07bbaedc5e67c017301b3fb29ef2f2b5286a84b98b28697214c245459ae8cc51e1da9e45e1ac31dfcd0c9212ae9c769ae12aed03c27121924a56fe40eb2a315e8958b84a386e752461784e142e24a9519ecf9135855e9139aec90833d21039611346c0d20bd5bbbbce06012bb29aa889b55341ccde998ceed57b6c821a9ddf205cefedb97cb6574fd04ae7af10662e5f178095bf2184acd66bf889b0979d60ce55682bd83491f75c63cf5dd0f20637e4e87822f35c0e08598568cb454d6454f17a5debfb68822c669f4458eacaa5b1a491ba96799ecf3bb5cc7b6b91a69639c2735d8b8d363027a3c9fc9e87f99befeea227a2688ee6b13d4ee5caca60e733d77479220a0945839d8ff04240bd66dcb99553343daa8ecba30a8be3cd0676c7e7b2cf52d6fa14f166ea532d5195db6cad89f6c84c84f18f8c90f18f7a3e3308e8a706446df063e9020d07d5596a851118c6a7e1ccf3dc249388e01d4f15e60371b360a31cfb7e39894c8adce4431f83df1484428b332c3293a531a03f26922c7d98868e1f4d6430a192bbbbfaa431782c6ddc600321bb5e0ff4a71ce98b63accc2f0a35796b19ddb057a033bb4127371effd2af93c3ef24b93627a56f13b198f07fa988c5e47d45fb1160361c428691b4a432962e6ae08d5217fcc5ca46feb2bfbfdadfb7a9ece2779986eff35b999a067a94770112da3bd8a852a53b9c9b196f7d20f72f72bdfea2d781b92804b252df70ee376a2f2e0a41be4894e70b538a5c9b9814629896c44ccce3cc4762be2905b93661b400e2b610a41069abf2bc9591eec20e6ff79cd9d08da0cc47c3502936c917c66d450ce34b0c9d04af16439f36b9fe81e86a837f9579fe5416bf4aec09f22bc8565a62b077d27e28fe4b6298b2560e66cfed1eed967c914e1c868c7afe8794a77af7759e0a736b57c4c9a0a084afd745cacfa48320b8004d65d966731042d7acbca6e46f5650bdf7fe3e7453c09b91d76434a9ef7137c76b3bc7296092f2a3fa18a16baa47a853f05032186d3819d08d66d8123ec54ae33ba2901698a2115a44ee28b4e38e92e7c51749a89e2ccacd9404d7d0e8f27e95e42f49ecccea602c1ad59f9e5fa304cb344cf05851b85a46e88db1dc1d2628fe5d1620cb88fc5bc24c2ff959f1ca01e3a6facaaeaa73c7569598c46ff06f89f4c23bae035f6f2c322bba6cd8fc0d7719cb86ade6fe88ebac28926a66155f9ed65402d454cf993a4b0a383d66fa94e9c434539f16ff48040de9e9dd3426ac6a7fc64278afb4756db02a11f37ae7c43774d928cfc7070e6e8e8c0f50c988c2e39197218d0f103ed8bf073b34806e4f5969769bbf25b97ed4cccaec5133a34b96e1d74b3a63a75496d94e869fb1335566f7a5ac2f7532c36f97f6f2ed32c3afe08c6bae219de187f5a5b03960f58e1fb2aacc1e02fa6086df7151662f5e67f8908955993d08104d19bebf5c36adacd780715366e6f7593dfb98e1c3facb4bc905cc813fd85599bd157caecfd3679ccdb30d7e2fc9f5cf65f62b9d7db451e0ee96d91b7a9ae1f17e993da81895191e1f94993d598eef941948af323cfec9bc5fd65586c73f97d9fd4ae7de2db397541f07f0fea8cc1ed065635ab2ff5320dac13e90ebe040973d679a3807b74cda90e1e0b67ee33cc30777caec49bdd0cffc9450f6e0e788b2077753b2de1a2544bd75bbcc9e8a86497deb4ea0ef587fe3e3b14e1c94d9e37d9db855668f0f74e276993dbea51377caecf16d9df8a9cc1edfd1899fcbecf14f3a71b7cc1effac49352ab3c7777562ac2b1ce91454adebded7758f75e5b76e95d9f3d5c2d063ac5b1577d5fefead323b648a661bcc683c133eb2abb62c0786bc1bff7fcb23b83e5eafe117f8bea4a393502a7699083acc20ca3100a68cc0ec4253dbeb659fb691b534ed4eaa1b24fca6caf7b671faa1e3f53a6d5799651bec1c2bff73a9a0644b46addcc7e831b74b0bdd22d0b776f5500428518e36d87ec296c7be4a064f035d17e869bfab01dffd8e0dc28ac6c2b7395514624d9d31e99676910c33832ad6c456916fe22cb335cd93bcad5d724337f6f4ca066149e36d26568b7dcf6645d36f6695a2effb086dee78331b532e03d8af87d1ad3d368cf274d741d10f5babfc9054f921aef2434f9549819efbfe8d7f3bc543a5e82170a4e67b394dd8c1e7ea1b554b8f958b5405bc591fd3155955055307bd47fe0976267d26115d06851146bb5c56ccbb31f2874c9829e32bc6cf8a7d03240a12fdeeeb1c24a1e3b12c1ee1164bad20b7ee63d00260762f9e76c2df31f28f6c4375b7f9bcad18deecb307ad8f20bdfd75f44e0f9de8af6b20a74ac81901043adf680b0d185f46df1d7002756522ae6ce7770665767eb0bfbfb19291dfe28fddf95767c9a4092ea400239f13ba1808bd92114a535e7979e5c8ea096ead6c18f957fea750e331a257429008ad31cd89a81223a0df0c926ec6f403d9c2a3d3e73bc77d3f1710d12c9cf6a8931d62b5d9e8f9f6b48d8f321a2334794a4c3c9e20f201df212319c95e9988304cc2c47e59adceb9d879cd17cb8ac5398fbc3035ce357620c99370de887322a3df283b163920fcae4078415e08bc240f053e21af05fea1b8eeb4a2e414f736a4bc2f71a72de5a5c49de6943f48dcdfa2b2911beb8f45c9d1316e28d98ba41d15d50bd7e897868236cfc5c9aae951438fb1f931629286eeedc53820d41ac3d1dd5d57ce3f8f434dd63a8792eb0d9e51726df3cb39dde0b3e87a30dee00b4ae634b259a1a94bae3389d78b0bacdfa96bee9c5ac7dc96f3aecc73396cf98c1fdaf8796fc582361f9909b96a4f07b1f47feb83879dc70cf021e610e4b39605b5e139c1dbeb88fab09b32cf8b82c58d44dfd53a4ddc6f6e14e108f3c8e08746da5ca355b127bdf0085036eae8135aa0eb8a166714e18a16331addbba251189519759d3e20644edb93f6cecf084d56ba02ac105ee90a1360994f3485c86cf522731ef37133718fb7afd44b494c83e026ef442e5c778d249d920518720c0ab8cf3ab04ca39ff173d025656fad8712e6c17b183c3204bede247e6ae731c51969757c9e6fef4b26cfd3be5cafe7544f9140676cc8c91c39cffc1dc0410cc64c379376d089b377e72e4213312d18b1bd724111de3e173a4d250c2723c637149536dff7bf6ed121bd0966f55972b70d648f3f26b7cd5ee66f5ea635b37f57ac512f29170a7f4e6e89fa127f4872f4d830c4742d81e002f84d52eae962c1e69c2ae69bfb907e1556f67552a405bfff22b9f9acbef4775ea66f9e57e1a58f607dfd27a5d445bdaae61f38abe6f801b556e103422ee9f492c6ce5a1bfcc45a3bdfb7bfcf29198cf1634a3ed302e1a7948cd9ad5f1ed3e967dae3e4a5cbec3da69151ce2bbd6458b6f8032d9085b37d439d00eeee5dc31f3d0c393f9b9cd721e72793f322e4dc31392f43ce6dcf52b4d123f6131cb177b41b367ee7ee5d57cf1b6a6abefbb3cb79e8727e7239af5dce1d97f3c2e5dc76392fe937b6e70b6da9b9a081f8d064476ecdb40554e84a3e7337225fe7f6e24e087942a7c5134a8ed8b1eedb67b47843f1ef14a1f209758eadf8118dfc7a6911e390dea7ce9ff33e9db8c1f151bf67f33b8d0d197fb7cf0d9e538f63f284a26b3d909cf7aab1bf3422982774f2851677ef26e1590c5a570021632e448420ea881d4fe6f5b520a2188c7c2433174b66b341c80de2800d66bac0b726cf35299e781ff3dd31023abea1f82d85b8c2d62214467f6c0cfa43bb17c6a39f0e7eba35fe797fbc578c778b22ba66bbeac7f108fd58881fc97884d62384fe57042cf11b0d01ed011cc0392ed6cb0625e88fcaf8f829848dbf4b542e84493e12c7795ee81f40e10f7ed5b0aefe1bf157c603f20fdb877fdadfbf69cb4ef8bdeec8bf29f993125b360a65cc830cf95fbfd54c2a5afc4b11b6fcd98965d08627f6be8d291f451ee601eb3206b6716c5e12bfd7f2268f3e2fb95133bee10b764fa1defc602a02e011bd4f82554befb3c8876b1d145fad06595dc396ba36110a4de4526abffc0f4a183644f6f6fd2ed473ac10457e2e39c03a435bf08066c92b7f01e9fc8b1a7ca1d3d26dbb6ac9fd10fc9b1a9b93c1d844841a81e0939f155da4ae3cf783fcc0441a2cfed69fa148c84758916bdbff25c3f569c3e42736ff95aba65458e85c330cedeaf4278da344ffd166190f469a65fc931285ffa00961c875faf5e508c75f5c2a2cddf9cf08de36c63ae34f4d7380d9225e43cbd2910a1387f24425ccb9f1f8371e587faed88a91eb53da30238f6b85e306545228e4a47954b27979ad9bcfc5b925818932ee5a17002f6de7e8a110bd0eabe4e546f1a2b637c8a7a3c6985c539d6d131b9a846f0db3d1cf9b4d34601a1e6f5605eb509f611381a461c65b1d02719e9723bca457554de7ced3db3065e62a8c06643a247239a87812a2d84d8de86b915b2e0c430d1f818696c2133ba0c454d9be2e0b9b12f08385cdd753c53e4454d40b2b9e9e3cc3921416869a43ac6137960bd16d6420384447f657c4b50bbb04dadac2086a93a752499ebe6d6206ad5129f3b8af09b714f2040a846d622ad7a6e28ad4f0f689f9218d6992f921d5a6260d6e57992e64553b667db8512514caf3a28ae8d2c4e8b1ba39be2926f4278f06f69c8c5c68e133ebf4e22df86c0595df5117a4b261bd8b862c5a6b27ba6729baec8cec76d1f6405f0cd30c18f78ba1a2e77eec2f86361526c062e892d13470a3f6625a9c910bb2c433b242e505b930645fe2e697799e1773d298f8752e42da459e17be54bbfd616dfe6f6c39c2bc2a1adcae114d5809643d210c5f918513943744e12511f80a4c30af6d180bbde9740cc58a1372e51a81d0f58a9c18f1de12af7083bc45c48a9c245eb33b07e5895dc8ded073b2776b74f7a73cca59dfb935b10136fcf653343d866ac9fba7c9cbcb13e40d025786558bdb64eadf2ff5a41c6d5cf4b8403eb385fb0691837dbf90e8f96a576134f54972b4382ead79e0224c13fdc0822ca0f7d17abd207ad4479b6ad19dfd8e755990fef98da3c5836c9debe69b60bccec8aab4e3ef0c475394cc92aa2e705d1573bde4a68394cc716b0725ab18c997473226bd745a82609f4ad61e8602f6188bb1c77cb02a758c2991be27a2f5825ad05d77cb542c09c594885e59535b7072778c2542136b9f47d1c620389f71f269f80a50270dabf16b8076c1179c14825deec821a0040826141a4a76d64492d068e917d680b7d06721891569110fa1a92acdd1014340c794b40283dd46ab0f6038460b73d4895646b3e4e49a3787f50ae055bafa3cf09d61c35442f4989f3289f2fc3d2b18d2afdd6026fed52f78cd94e155528d9b617c7a2ab1a2dddf9b02614aceb85f6b2605250d2f24f9a129246698224c117293d69f08449e1734ea588481c9a008ffd6405c10dfb2576c59d119fb6f6d9da2e7648ce97fa1958f6b39b3c1dd5a96b33735519826cab489523751e8260a0c2152a46de2be6d96827887be59ca364bda6689c4a7f584c7b674b8f60adfeeeada92821b81959f04e6eba6ac3fbf90507939888c7ed7ebf86ac89b972bc9ccb4730fafd7c5e0a931ff5aaf758a621ee3f65df154543a18634ae61473874f6d24cf937e688a1dee4f6c7cca89e405476541c992160a4d2f6819c96e39298cd9dc402792da1b84a6a0fca0a89c537daa0200a14260de33a11d9e2c5032cfbd9ccfe64cedafb553b0b35c9225c711f58117ed193684e1ffaac2827eafc22292157c8a163ee6be08f758942b032621c087a4aa5eb119e39f18884bf2fc869b3012fa2b7cfbfcf5fdc78f4e6eacf76b654cf5b6dde6acbde4c39e95a650ae146e1dd7cf79db182116df53f0886e88c036c44f7b3bc014f61272c1311c632d22553a9a6f1cc7d41575e399f78ee7500c862e4708c38945600a101c5b9ad7b32ce8d69d33f59049fec9167b2ceb85917de579617743aeb7b72dd56ee9d26db5aed73dc529d8410bba6c2e6a6594ab66e9894b0f42e9beb100fb652f282d1d760baed7852274fb20ef7b26cffb728b5e02dcd8c61b6e16082bcd1eb92566cb10a6ae37cc10fe96eedfd24cdf84877c6e9b97b2cbb70c5372caad11006fe03742588fb9c62044107a32a0de0ee90b5362c33a0c4fc0acdb626f2797e3810d07de915ddd75f16b4814287cd3ab6ebbf513765ef19464d92e6b45e75611e2bd646771f3a3c10d77e067786250f85fb133031ba233cba25009ee9d11e44ac36a2acdc973f0873339e47ae3651b6c6a027cefa8237a5c420855b641f15b2856702471f0ff11055b589c3fdfb2b1683c195b05ee8ec078bf07d73e488502fec7c0475b68d17f8cb323d39dd6dbe83823a4eb26e450e6ad430d9ada31b073c9d5c5ce4776d5ec5c67bba9ebcef09f9a8b22c33b19dacd3659a94cd49a00abc0db11b3dde9c571156a58d1463d82f1ec444a726ac37d986c22705c8a08542a23d6b519e95d2b30729770208a8ec03fc752e8c2c1b60e5200ed58202f274899cd4b12396c6c00815e0c7919c4f9cc45a6f601d527c88fdc8feccac49932d86258a1d25d02e81806ac69d57e593402684b0ef9a1320e5ce67932d20c8d79d850207a9417760bf59800e619890d868f5e1e648cd38fa685fe722885ee8969a12272ee63814a5976f3224d4f1387a7f1b1c0a3378004377a3e617caab0e9a71a3db55e7bff5540157a5d69b67db8a8e70c1877539c68c2c094a785418e89f2234167ef6bcc92a386cc188b6a16016c0bc16ab628a4a9d3701e50f319f1eb2d96e14d52b740923755619ec5002be69eb430d771cbb7d61349416f20cc2d4798f55a6d0b7868022cc439696130ced25f0d6763289d6601d15f7c0bd1a3e02647c7db7a60e64f4bbce78b7e4abafa61fc56cd617d5f679f455b62374e4b5f7816bb3c98519665bbcabd3d7d47ec38196b8cdc580a014d873ffc606e5bb9dfa14337137a9428334aecf2d0334a443c4acc790661115a228cd8ed59e9dbfda22ab6345a6f57a71cec79ee17de0bd450393c625899e463ed3ed41f50e3a2cdac3b1a4ce1ab4a27a1eed0bf2f3c4e62c6ab1930e32467d6862cdb7501693bb48f828978da8b6db4df8159098c8299a684908f533b2e4d27f8910ca0036558354a6f60ec891e55374fcb598a0ba0786a121d3e2ecc07a0bca1b6d842ed450c85d04755d943551fae03fad9989e42a3604065d9aeaead97acd293557ab2caad64f5559bd92c61031425fcbab7c998e00a332cdb04a7d83c50aecc7dddb694def3f8336e7a17a6c87681842e900129a88f1212d3d007aaed2f176c0a0b8a6bdce02a20ecafccf63b373f3352e325a9c9089f18058da5e12ccf97c11d7db9bb8bae6766bffd65392d4ec8ccaa77507942669e2b00b4317251503cc3cdd1f21857719cdd2b746d53b33c2f66e4c40ae4372ccf677e13be8a3761a5ab42b826bcb8c2355e7aae773e5d91ab72ee598a2b3c275778464e3411978490a6853e284c4daba83d336be6d0fa50c771ccc85941dd671840275ecc3aad9845ad98e13999793b8fd546573f23125ebded35276451cc30c5cbf855cc0fe693981cb3a1e1f5dd179cc0505a96f06bc874d269e049d4c0133cd7640f9ccfac3f64a863c40a8a19da20845791cda9a60aaef0caaca27372bf30dddc736e9bb74f53b747281a124545e686b9af50c7a2f3f61885f0f4336207ec9234f884346484af4cc6275201775df8404ccb3c1f7c1ace6bc12627bbbb510174bdb463f8645a5c91255eda317c4596c9183e8731bcc49f0c7c165ec5c3f8dc0fe3659e174b72150de3a51fc6e7ed61bc44b821bc38c70d3ef1fd339bcec979e9271039c733728e97e44a0f63f30df1005e223c8f5ab2b40378cbd7ba11f6090672f8163dc074533e759af2296aca273c239ffc5099c3585ec2585ea2afbf71512c31c527adb78661fd2926cfb235ac3fc1b03e293f9961fdbd6d851abf6d58cfddb21989e925e67abd346be54dc2b73ce77e87f0fdcec1697105d0bcbcb55f1829c2fcc64a75f7ce91ddbf7877ffb2c82b73f322bc22d20dfb95d1a1afec0e3ff7bbe02ad2e5fe54f2b322341b5deb2f5e3942220ce78715eeb43c62b218f1419f36a9e708bc3d3d9798577de53531e3b8c23c395ec46fdb402d6eba29b8c02be2ebdd840f8393d0c3aa687f88e31d2b0cf46b7d97e6d32bcdec9a8a4c19d7ca84d9ade2366b761f60777c4d95df8f9b82799ec0a3e69841124ef346b369fa6d0557b78051004424b9edb404e44d72d2c2e9d1084aa759a65b64ab5b24e65b0f47716fc0b37167a4f2884d213583cf538a857a62026dfad843dec31e7a44054eb26c973bbdb2ccf33b8e60d362cb4775fbda7c812ef0fa868622dc58dfc2535e70cf962dfd52a16fdd8fee9c2477e6790e6c3247d89b86f23c1facdc246789a985357d307ba18bcb86c3a6b88f4dd0aa8a823fe97acd86027e33af46cb8284ce7ca1d1735f72f291178311c29f4d6a8cf0074eae37f80d0fa6a81ff8063f6c5dbf4eaf8320f705772edc84900fbcbd83ff742b786044e29e973c81ea5ed1e235b76e270fb9759878c3f1078e308b705c9c61b821d1785c02e258807df130630a280210006f5f3d2d9f9b7d0567196a79ba29f29c158a148c40a4cda98a4232960a25d558be9b9950858013baa9743b5d73e3c3fc236edc72f4dd4a7f15fcbce651917f80742f78f19a7bbf100759c88b3721130b68a535e14513652cdc8a16b54412750e2a7fe82bb13689498b8c90fe49d4b5312ef47dee82a05a588a486808a275c09c3023d781f124ca83c8724344a8580202615d5ccd2555108bd0052c0570ed10c9d4a0a907377f87e83abe4b3c545ca44c75af0685d150b24f8c562fe4dcea01460340c08a047a3d358b24f427bab609b71428107f42d644afb95cac406100b4b5463b5e460b6d740c656cf1a36c75ebb54bc530be700053bed0c6d7e11b6113b128b6ffe0f73c310bbdf616b725c3b09995ca2c0a8fdbc62f0f6dcc2126f1d39b0c635e7132c2ef0c601dfe627fffb2bfbfa626ba6f79e10cfebd0a607f1c0fd8df53a3d214b22bc4741d4d84f740c873116c888405e631505b80b3d50bb215bc06780754e815275c7f91c2aa478bdf32f2b5592d63a9117e1ce69cf0c8642e95563bbdaacb4f356660294451b736425ee99691d1645e1b7cfdceeb06c5feed5f78fbe874003eb87c978c758fb8cee9f980a8b5e7a125d681a3bf3d7acc478f9dd4583931da97c0c67ee1c66c0d468969c3bb786c60d569f2a877aff88dfba865d709f52c44ae37abf6979171f7bf21199972a672dcbff8f41d6ff5f75f9cb0f22f4efee2d6fa19ff15f969fecb8b78a07ee1ae81ef78648bec6d3fd8b4d5efa619b0ec304728bbf26f6f5369db122dab0afda507eb174e98778e7023ada370d3d4ed90b0d0cfa21e037973fb0bef3555ff12db2fffebb220d1e346f04df4756b584ce63f9215ac4fa93a55054365a497f933f681e185de3a95695874686e079c3d18ebc9224061f78ae93592cd5fb1f96ac624615649fc85835562f86c4e448fbd368f15dad63bab21c6a761625d1becc4b05fde6ca25a093511c66243cea43e6aeb0236db77cdc4988537c44eb015a17ac13047cd556b1203477aef951db3b38e4d72bb7cdb3279d5b64ca640fa72353409cce83993967ebab6e8d2dc3363cbde3163ab6b675d4d8b86546486b966d42b2b6120333cffe51def9a4776f2c8dcd8b31a6b6c27c5ae340fe4eafa766becffe66f060bed396ebf451fa6d2ba80478d2b295921b16b059ae893b0ae3675c05be5f90a864fa02d27b2b45468f07359c8f68e87d66be7aed4de0b75d9607fcaed9519bf154ea7917dc2ceeea356555158e008c9fdefffae391cde866998bd603bb88d71a5e83a9d8e366a809b87b02f135670dcb84ec08db5d8b69dd018d23f9705ff0e2273ecf9454f5dd048479447bdc4e68ed81ccb88aaef23aaea2d75b2755535a071ac40dd56c5afd7276330f8fed7f837c5fe53d811da8258753ba5fc83e34edb4bb641be8fc8b21e9e72313747b77770d0e90ca0380200ab3bba6746ae153d2f199e49a6eb57265e687d550a3c67cba6943dfb55a1f43e1ebbc14c0b45ae8339872d9e1602a63132f9607663436538f8c405f421b5a77859c8968f11c3f69e6cbd00c50614aa0e1edf7ad2a4748aac4beab6061406c33b1e9b6f314c5b1dcfea62bcd68f9913579063d82857b10980ecbce25f186fa4f390357634f9d1ac730c55ad99a3ced4e4a41eda6e8ca43fbff342627d63d9f8a31d54cc6ab02de158a2cd377f264f8c1a689db8838bbab83dbe836fe1547fcfd352b2bf54dd29750befb7ca34f557191f3343b1e67f70e4a36d548c68836c20b550d0f3eb2c299f9c5536c806f48e0c5dea966fb5b05cad98829dc68caae2881d238b5c67bea68967ae022fbcd8a8a54e02b9ce5282fcd619bce48885f1a66c48afe378f09fd5b13f208c36453a8ff85d201d51a99a3be890158c2985e5d1f8184de5d1e8b82c44b765ba25d1c75dfc4f35c574ebd71bb4a8538bf957b440e0dcfff32f727af7e752263efe0cdcf711c2bac44ff7e4f4ee4fad12a696a791834294eef95225af74ad63844511a23ac5cfc8cd2616042c5b0deef1daa01dd62df6e068f16ed4316b2d2ecd08f30227d53e243a43ec16934f8ccd35acc8b42c7a797a38ca3bae81621ebb5b627d8a7ec78d48c0ea902007e963f108d3361ffb8ae32e73fb8afb03df167f21d7d6f51ac4cd6d9f4a3fb6c09cbb678346c8c141d4ad0266e76d082f6a2c40c04d532695631ab1a886c16c70ed96658b00c1d0f5c6b9cd8020eaa426d79251e76a504a8e578d079229df9a4b7bd35cd9fdd85c3c5d2c9984f0424fa89857cc663fa357f54a25250fd9a2b649371adcd5994d993161d20fd9e9ea1cbccf7d31274b7305ce98946c1e9701704a885158bee51b7c75f3c7cdeaf8e364fc71b4eefdb8b6ebd3b72ccfe286e5b943aad46d296c7d7ebbf2944c4b9a952f6231777a16407ce3f2b5897ba6fda16655e8ab7f40f467170a950acbf6a125e25c95e15ce57fc8b9b21ec6557d8d71955dc6d50db81ef5340b2279b6c13d5ba2219179f7fbf6205dd5e9207dde3348fbfa0c8e08581271343ad627a4a3b14745a375d1de04c4776e02004bd3b7fe8bcd0661e87984e5a63577ba16f1ef8dde4a1075343a0e43401d8d8ff1d1ac2e169dd17da4303b4610f4027fba791e9e6d9f87bc7f1e567567e6d4b59f1a17753c94fff48b8caa43ff75219bfee4c51fdc4cb0ff0ddd6a6aebef57fe7f4fbfda66f6f7ebd9d7faf5fcff64bffefd8dfdfaf7ffd67efdfbff1bfdfaf77fa95f4f4ddc277c687f9fd5895ee963c26e5f56c56d63a301ff466822126394ece1a3678fde3c7a08718eda19b1af656cb31cbb69782ff6e8203e2de2abd44584b55c4458e22292de0d1cf0659d06b28eac036e9731da66ebc050280240415e5f6e826f45c12bfddd6ea04ddbf560a395d06230b2d62b77caceeb321bf5d56ca0d657ef2069c3d7eb1d1f9437849aff5c5b038367b51b5187358490f66a67f057b244b3c1411439148511a0bcb6562068bdf6853cb6508442311eeddfce632fb67d33d8e0ec599cd684a1c9c7ba38d54cef465fea3179280aebf6035eb256d8fc6df5ea3aa20ffd503b7d7b00a7f2f85b797edbb852d1f33c3f08c9b14f4f50f41854ed6b7ee348c806849cd64129aa49f5cc5d9b0640db46d822d52837d0f859e11bb05e67178c1a14fe3ccf4eebf9954d0f3e09639b1febe291457c38ac276a82ec84c5ca902eee20fd12d30613a5c20c7be84eaf4a2bba2e8a804eeecc094c68b98e6cf8270468278eb8d15bb122a309331a7a3001898c4ddc5483e8e1fcacc87efc012c13903b7629746dc6004b3fc4d947a9bd3d1810d90f993182c87e18f8d41452ebb5daddddb41ab5b1ab9d85c53aacc9693d85d704d3aef885c6ccbfabe27e5817d0c2d378f134a151eb9662ffc5a56012bf4857d7979124cf5a3e789df6f433f86cc1628b252a2f39743d14829cc816a68efd00047879ea9dce1fb1253bf34b99ae86ea5d2dd2cf739d1394e92feac4dd6b4dc6d8b6d46ad18dfd46d942e06a2376f90a72b2777bfc5307f8e41ea13d486e6484f06fe66d34165bfc5377cc09bc2ad61ea345bc68f7984ad7ebf5e7aaa8d17aedcf3375822ce88506025c70a964515191149d16058b3dbb8cc780b5020023376eed1781fc9845562eb6a7195010b0306e63e3fb436afcc07c676dbfd3db99d50ea718d37b3ccf0b4aea741dc085f0b358842f4053513e95a8a05802deae04a75868149a5a427354b63bdcb817d6de31ed86af888ca25a7d94ee670ca25db556af6eab2c8edf587f279a766d24da0306fb8f40e5fd3a72270bed7a52a731cdf47cf0a327f80af9ee67b649e04094fa29aec978ffe7a8eafb75371ce99216a2050fe0f946b2a0856e2b761351fc471351fc9f9b88cfeb96d7117caefbf6c168724e0b65376a3052d233d57dacb7dcf2581a81e44524c573f6349d8c8818fb085f39bf567c6e53666d1b8c26b1d159bc4844efc64ddbae6d525b3c8966e290e02caa035e59bfc9ad98112b3f9056d31591bc58a17265ba7bd537249ca9bad80acb80677dc123e7bd680df536b486c9ac17afa1fe067c8fdec7b6965faf41152bd76ba001caf34fba4ff442b64238a0f39d75d4c1b5054738c37390c2e35af762d52e876df57a5a56eb7540fb5eaf299ff6c0a7edcc0d5a861e18733d483a55225c3484f2f5fac4946ab0c467e07883a6c5f7106e3bd045dd0f74d1db857d55f6e5f6c35bdcd8b21b6e16684b757d30142a85a140e557be64fba3b835f748c746825408bb0929b11b2515f69392acb024cd7fa50d920cc676ad4a97060b44da5d227c8b94f384481cc5a74df91b759ebc8d1e726109692f19456b4d41dfbb82e0a26f85286e5a53d0f7ad1ee8ff9ec5a367410843225e383a0b0c8eaa3efb8f168e4e950817f3f6c251e1b3ef5f380c99bf855c0e7ce71b960e57696f7621a19ddfbe8284dab6dfb5957ec342e26aeb4cc5ef1996edc7f76fdf4997a23e22fa979bd0d62d4634cf7b0c88d7eb1b9a39f86a33fff317e90ffa8605f2ac6f813c6b2d90f3ffff5106966dc7533fae13fe3970aa8f5bc7117b0cb018c13d2e0b261a489e0fbccc86e6f929804ae0c1188593c644269bc5eb3ac4fbb1066c75ef94ee5d97418c622d76ecc93dd2bda5ec7fe096e168608e60a96840f3c9dc1f0ecc4dc86ce088640f108d29d356e219fcaae8ab47bea640d7a7751c4c3580b1799dbcd5034caf6831c2eddc4e867109b1c16a4a9fcc73fbb8db3e750f18c7a6d425cfb8d9bcaaf1bb1a7fa9f15f35b96e09acb0644a5e19a4f4c803e7d7d4120253e28eeec12cc1eef9e48937c8c78d3dd414b26f0ca1f5daded8cf6b140c0558385db6014bb19c160d198c5a47b53bb79d951109003a9dd9113cde8667561bb35e0f4c868f854275a93717bc79ec8b14f59a8cc1b5e909c7e3bc0ee74e38d479b147a836cf3fd7856689a04013ddc10507701608f188472dd01085474453c310d7882b23dcc6d463c3f904c1ffd25e3977c9e023c526c8cb2238b88ca5b04985d00d6a30ed409828cc034a526706fc55fb89c3b18fd14649f0d7dce6ba621e0a423b88ee134ceeda9dae4948a3e853c835ca929727e41506eb29d5046ca530389f7f0f7d1134d02475ef58e81ed238723713d4b8970930c06d919bea06d2d8035461e1e94c717f9c88d14df417987ac7ab74898b3a437417b1a43fc4869f0522ff0743d78f3c9c082adcd043ff178f6d916c9bee3ddfd305d114b891caa677d27e8982ea58e95b47ecd417c883d8fd795bd801d157493b93288415f7dd94d87efede620a0c33d09a9ece90bf6e7b16916bdefc4a671f2fa99c371067436fd7deb8c55fbe56542a1b9aa3a28d2a25569457a5809fd007e5083220462bc5910934df94453d8c5e4614ae87be7e43ff28c3bf908c700d7a4fe00875e544d844782d14722f26d43e6135a5b1e4f48796b1606b5fa48096e85d41310707710e104f4e65904c56b32f1632da4f1142928c73b9de4fc57b776e253e5766ead90d97c51b2e2bcdac73bea3611a79375aa3ebea5f8af31c06a84093c403d63cd2bee5abb02eac2c756165d8af35890b2b88093c5e7eecc4ca7a9d5899776265c18935541045d7616d07563fe8a38563237332d6ed30bbbd6caf5a7d93db7cb25591531bdcf7ac9630183320b97024c7344136121ef5102047e34818f6fbc0f7199418026141fc4e3109b6fc144d0bea5f106bc70052da3f126d337013ff5e179a5784e5912726fd28092dec2696fb16b305f4bed17d189db4f054e9d68f0b0a3deab06b08f56da6f1320df8fa6c63da3db28bfa4d4d57f53953174c66a5fbd6609361fd07fa9ef53ef93dbd1d96f916afff9b5f00a2fd4fa5d1885a519b266ea9e8fac58d8cd9755d15d29f2b5aa1a5d2d8cdc9e4b70f44f3af8d677410a08f624773d3c19a85f2dddb62a522aec3dba67868d2688e46930af46dbe1f6fe6cf26e920dd4aed7fbb9629668db6f3ef82cfe74c6425d80de87536386ec7e334861d8df1360569618c0a172988d99d421f42d3b6a6d1982b13563d2b45bb0572cb12209216c82d135e4e55e4c4ad2b4e9a64d249bb4a999234726bbd71cf9a782cc660f5b36f012feed8dfdb0e23c4e16058601ff8f9d9e6da871c58c6add87ac71adeb8aca59308a33c3fa185396ab9502db6cc235ea056d450586023d4f9f4d86c22b9b91867ed43763bc32e8ee97932cca4f57af0a60630c88e5827b4f576f980170097d103aac1ad403c9db226157fc53b2b43c1d284e7306a56a7f9ed685a43503a99a23c841adbc15bef043777611d7c591bf1033e165da7621cff094684d3d60d3ac4c3a34b714c1496479fc53169340f0993839f49ba7021c2ada4df5cb0c5a99e323fa822ab6a3acf3ca68f99559ff89cd5b6285dcd799d5986663461f7fe607138c81f54f1073b62c7ad1a9a7a2567ccbc81693ab45fc1172ee83c5fd0731f189d8b8fad87f0b6469ed57261ca4ad630e5cb36abd30557edd273a6e76b631e50f5f979c53a4d12cb95caca8fac90b8317571f189561c5e8d2b51089cd5c2c4ffced2cf85f0df5929872797922e97ce11e2fa923687ab4af165c5cac1a0192eecc5e6bbaaf7e0dae5cb6f6cdcc62d82d50e173b54145c3f650f490dd247cee1056d5e5c0a3d9298545745851cfe5973541d4f32c72467e03edc416a5a4de550b70b663344985e8117e9517810af8e51d981735ae579fbc92cdbed3eac338f51f9b6db4e378957790edf5da18dc34e7323df74e529d3bbfa07a019581ff6d2d494fa47ffefeb53337b9620362d53bea54741d00c6bf1a0e2104f4a0e6b31d369b212680358b5291c47141cb3bdc8998862f6b32a7217f071828565298680d5fed0e220818f51238088f759c111b239d3ac9949be54197831150523d5d0b8c65ae8a4229bf34f1940760b269fbc397c46b27be6995feefd3f3fda54860d87bfa83f31b07b2c586c0489ca2ed0eb9037d3eedb38bee64da96f6e50d9d31a8eb0a3bcc1cc2a2ac2b0f413675af924198c60cbfd0230479020e61a215476aa7efeda007231bb5a32582d257ee5ec13235b55862b52eb4923d17fb29a3204187d5f5f5157643459452beacaafa8ab63ccd0a4554bcfaada7dd537aeac2c5e59bbb574565796aeaedd277a57d89ee6f9551670d856e4994d254b1abb794174d371451eb208912e9db8ece6c558468bb18d1727f13520573a9fd8ef6b54b24adb8f7bf17d1fe7169615911b58b457ce2667056c6da357f3b95ebee7ed65b1410ede637ed41c4fb2465d554ccfa1662a44c1f00c95d95cbf4cd6aba6ba7acdd45337e16d2913f9684666d3d9f0e4e4422d2a4b0794e74f99ad22de159aeeae309ba6a120f87a9de9df19caf357ae8ef68e30b3f7b26c57df6e56cba5644d63f78747730e2a8377540a13c9823479ee4b3d01b50aaf45eb3e5da9fa713d5b3536a3e86c240db2df3cb3fb48e3b41bb33cbfd20d6af00c57e886dd85c1eec2b0c483f1f6dd85c1eec27a47b079a13488a9790ef117ee2b25f9e94ab122836cd80b3fb1c296425b467b5817a3b16db79842b877a0e96bdde2b48c6ebe6f8a1d847f9916754ba725a27df5866d71156d8b2cd916afcc32dbb3038a24c24a8fc963e77873a73451bcbb3cfe97ba18e18ea1ba5e381c37df099422a3101137b3f6edd307ee63eda7e9d909cb8e198fb01b93d9e781b84638d163e25408527c8d274076ff7bc33e03ba612111b2af88f73ad143c8b13f0456b478022e476d0b961e45638f69ac803808de0c58829e3c44b1d98ae617347c40bcd247662305ef862c12fea41ebcaca19c11853a54d028ecad3e4b458e39d0f4d851875bc76e7bd98045ebd6602fadd2e660cb63372284b0c8f38134f2e2582f168c7e077d84b84961aaab1ae791dc7afaa621849cead5ee4d430e75abdf3403930389c366bdd6b79e3520f8268f1a7fecbed44ffd5315970dfed020fc00528f1a84903ef6afd77d53d4a2d1c390b995880da2a134f2f0fbe6a81eeefcf40dd288f15d3da7ed2874b2d8ce68446d111def538447015d65d0531807228efead0bb38c3bc9ba255d6c83dd27ec877db92dea6fda72d9fb5cefd046f0d7522a60f7661c0fdd5650e6f4e4c0715f4f001a6e1896f0543c66cdb84c466e5c1e2679f21572821a2270c18944b121c07e77bc63de7915e689b79b130813a0074f02fb6cd3047650101aaf9cb46f48ed915a99916290778110792a33b682fcfea6b0bedc6ef33a9e005e95ea55ab6983db1b52bbedede07cfc06b3fab6d8bbef033da757b6f1349a76d393f8fdcd30be8c83f937c370b1e90d4ee50c3ac242b5de0f363c91eade383f81688da3ded963003193c903101ac27b997c65e288cec431936f14cd207d8cc97327d9f65987f55c2fd24d34703bde915be7966949678f101e1572ff7f3da505da933dfad35f644b579ae7e37b1d918123855f4c3a7b71af768388bd319ac858af3b2d7c8f74744f7a4b09c4365f88a6413edf94be2436774993f0170347ce29f8d3753fad6867114d98dddb23dd45b63c96b1de194b2b97f77a9098f2499fe03efac20b5a4a3bac62fb2a3382f9749cabf57e39cef5366623e8b4f53d77b011e3471aeb3fc138ad17f87b490b166f7cde05d377ac9b44b74677efe4e079dc0ea3aed6776e611607fe39d05b668ff4deee5e45f2824e0c8efd9f6f47a8ac5b5ee7c4efb618604fe31bf847687eebc5dff631e3bbadaac2ad6f62395cbb5287e39d9686e6ef0492ca4a011836029752e146d1d9c7f271a1d066f3aa26a9737e5079b5f64f61b880dbc486a45cafefb8246243bad48bb391a645cee88101b9e54259068730a73f14a9965f8006ababe58f94f4898e5ff4eaf885d7f18b58c7ef1c93fdfd8d68abf8dd9d5891b6d9e07729a55c50b5b6818b5166f0b3a236819c40d9812bbc8a0f4c4ed9d13a5bd9bd5ca447f39a3c63c50ad77a3f8294d4258f8efb4ee03579e8cb3edc52d61db26b2327aa3b7222b94d80d4ae2908066af2c2bff745f7bdddc37464c3ec0fd33d476d191db557c951db4b90a8893889ad89410d30dab22b1fc9f3ba2fd30cc6faa83946e6e0ec244dc00b83c661656eaffa84f7fa34510813cef4a83a26596686fc56f19495e878d1534b02f43f202762eb75a1fb0644d60c02640c97abe6a268acbd5b90ce491721491e35c77a50afecc9b59e6a92d891817ba93db75a14f3c0dc9d3c56a84d675dad59770cb5d1a087d2ebf53ccf3b72429ddfd703beb239ea7926cf5747d5f18090f95175dced429deb607735a91cb930f364d2276032bfb9a3813b2de6643e9da71248bc22abe9aa9567a964a06ee706c234e91ad04ba402cb15219aae1d61cf3ccf9d587210b93576aaccb2ddf9ff2e1165ef482bfc57554e69b75edb561b9af68cc139421bd121801d305820cc09c3ed23649fc86d83bf74976c742dfae5500631ef7ddde713fa8ed18faf999adadff23553c1cc9d35a9f7b3d966b1d57dcf3e7a1b8cb0f181a5c6e3028691cf7a6e9ddd8d0989093a150eeb63e241339e173e9286bcba9ed5a2a92b36044d88ded23d3c5dc38023ac572a01d3b181593608452c836a629f03c9ce1298f624345a14bf53bfdf41769ad76a3a98b0b96602b5003a038e6b9358e2c4d6222db310672db2bf6fb91d67fcc1cf8afddb77629948b0ba08e0172d1169c712551910e0c80c648b4b4dd10e586b843c531139240a04fbdef0e444323a534f059cadaabeea88dac49f73505a1ed48a7e2d4b988a96dafcf99d839833974d1281c29ce1e2d35c02091c1f242cea881bc144056ce8b3a2304c1b43c1cb1ba0a80d82edc4a74802ad6be6982cd046583c6087e90d032a1a79f47fb4d946881cb5fa5b9ac81b67f1e4839d7efb703528beb4290eb040d1d86571e0767c2b8fccc9511c4484751d6d0b2be8771fd51b48b9257bd5a354b800b829c0cd84f5b8aa7521d5bf6d5cfbf331c00e453dda1265cc7821002e0b45c7bc6dc56d84262f758b0e0fbe47cc1122869a62ae50c47707e67567dc5760e3db954ccfdb21ea6adc6bfe1b09e007259d98e7572204a64e299ee76c78a6d9b4027970aa64c6b7d6ba83b24d54e8e7969d35184c06a0d668b311edc2ed9bc1a12bba735fe91d0ab9268eeffae5c88c703bf2f7c7dfb43cd5ed49d4b3a33cabf2fc595580fdc2f61976ab33d312f19a6a8d3411412f45322cb7261828a289010c16d3bb3f95a20318cc887401290050c9ae7db11f977060e1067d4e14d146fca932e11a3d4e925d68402386f4469c0c4bd5680af4389eb7ec15533f61b1303ef8e9691e7668ebc2dade0c6d651db1aceaadb9e8d9e237100f3c9e54b74debe3ac5be5dc757db4a63609c311459df1a77013ab30928fb77d456c664714ceba9262dcc13e615d093feb48f85383e3762b92cc480519ad522acf1b4d8f0890bc8970526f138f49761092b75c32c21c87a72c0458e0d2628c351bd6ac6a0a15f6c400e515c5e46acdd251b00950c9ea263ac07d920cc671d71eb8554b9196d3a801896919c6b75e3c466833be93ae99c52b56289c652876afcac9def8273461a5b2be046c32b18163bf5104543585bb4000e1e52daf77d826920519efbc6f90074d6e0771d69d901cffecd2a621fbc9b6ee84593b2a8e04e22c846f79695a546ebb686c03c872e90b0c3a596bb7db619b8d9c86e34a91c43680851673a2872235223d008be348113e8dd69b52c5813945a3a898312ca63f83e0db2bee651481501763d2b207b05494b227af685501b2f8500b6a3f02812f894489cc510585a3247268189557750d5a1e1896288ab7272328322b545aaf0b110b9852c9250dfb888fa267dd111d4452dbf0dfccc9bedb9b8261b025f86feb943e32cb16bdfefbbf2fac5f7e07f00b18b80712ebed6d26cba041d70de16e5d337e67936446371d93951142de729c3431f854b27a51bf72edb0d6daa5874bba7651bf76ed3050e9d9d5a12183d1c68ac079108173f326d35e836bc5f08a703c2702cfc86a32d10c7ddd14159ee1b91fa73343e53cbf051730f1d3d93ec33357ca5bf6cc20c06e9fabdbac770d9cf9357016c4e0a182992fb099b5d73d77075ae1ba964e8b8a48fd7911adf504aec204aee2352036b35da1b26a65200065083951b5c847b6bc15a81cc52a73ea0319b7a5a72b9dde3a38fd72f770d02ff877019fcaf551befd9e6fa906ac35fad514bcb77fb8ef1fdea3a6d01f0ebeea76ef32bb4cd100ac126f77982b060df38a8b10a9e4db652e5d163b3ecc4a7d985528f5c2992400bfb1aec37759e4329472a2b42fd4a039b6ca098bdd4678cade03906e9703143e9a1d6ce8d636daea538c7d5226e99cd756217eb5f476761262e6e6f925335a0560a4a95ede6a1b6c9992d184dee3ceca99ee927d17288f1fd1635ce99fdd71c76a55e0ea6b56ab4f992d95ca795fd9ec2bfddbe04a2fad4e039baa8a3e9b56f7eb681e756f3a559066fc12fbe261645e8c6fb8d76b9ec912f34c911a5c3230cf5403923ceaf504a93d66cff35d83cdb2af9037b13f3a2eb34cbf136d36c999fe4ef96dfe4efb41810cc7ef78cbf5b68ded218d5aee67f0246cadd101ce9eb941166dd36430c6ff2f77ffda9d468e2d8ec3efe75300ab571da9914961274e5c44e149e7729239769289d3dd93210c2340988a8b2aa6246cd386effe2c6d5d4a551424e939bff3e2bf56564ca924952e5bfba67d792e5135048b93c1771403702f2a8bc88fe590088a618f500e5625cefce18500238142f7ec5cbcd35e71c7abeff6633f020dc9fb355229201b05e9b823b8b4eaff7eec3fa196c9f8dd22ad344b798bb4e2c532cb254b650b47b14d084ef5db0895bf6bf103625521d67c390858f5fac17d11f799ed3e32a652d0c87d53a6def098c7f89dba65e0b57b9ef75b60aa5cbaf9b584ba708cf79c012b1a9bb436e88c9f5efabec6f2d3f7868fcb37e47fc27ddefacfa73524eb07bce7d3ffc07bde232d33d01e546c2576de7c9f427c56523154a886bbdbb8dfd520b80819050db3c21ae8cb4ad23ebf6dfc3dc344766659fe8a4de6de5d8bb4f46e9c783902204656aac0553b84a61d369d1a9dd79ca728273906a510c45d9a8b7d1752176cd9377fa30bb62c2ea4168ed94629153172614c24bba22724ed2cd93ac9d894de1bc5b197312ab7574fcec5b3333126bad4538a3d179b0d7a0e4195de099a63622ec1b6c4cb03b03c388e9e55bfa929ed8ddbd5abbf7af224253dda6252bb692bccd8488e9859d41276a96421886bed10e2928afc059393b97610ae599c1a2387bcb08d7e2dfaaf0580cd25976820e7b118e2e8b5d050308f855b4c1ba9c5de23aa97bbc340f6aef0debdba04fb1e8bddfb69d46a6df1169354e7a912642de80593f3ce84c709b911fb13a85f55dfe938eb6341437221e8093917f421b9568fb746157667fe7e56859f041d0bf2d2145d0aeae5a87d5f7afa60eabc52cdbe2a0657d1a990bc31e5cfa1e89d797a6dfebe85d28fe6e97741cf42f28779fa4d35ffc53cfc2a68589c90bf8a023ac226450f9f04d702f7dd70ba474851c807dd7013e2286c52faabe8ff2aa25fbd2197ea78115d1cd0eb20fbe83800b2af23815823cb62e23d2fad9d69f13028523c9c9d81f77e51bfc8f27b6c223ea0eea91abd4b83203cf496624e7f628893709376a4be0cbe109bcd237e428e1f85b814852437c2c0d959c4bdadf1157e674f22d361f75148ba61c90bb571666e06ce4e6d2df71dbfd6a388d3e383bac193e3535c35b4bc1541a0e8d46711044747dccf9ff8dfc515e2a3f0e96f56495002004723c020b07461f06f73dcacd614f6a2983f249651eb0c401204b0451a60feae284c84fea6fe9090527a2d82e057c55b45ae0c3d5455379bb327fa56e5ec4cc74277d9d745ff0f8d0f2ed8120d2031cd1047c8059e4329fd4328048938c69b4dfa4ce220f84328f64a8fdb13f1cc54fe6f6341394c6e68bb895653300c79101451825809f702fc3996435be903ab4173ef2a2baf0d6522c1beb6ce0c58fa7615b5b1d1cc5c0e3406c950cf480f3fd7f232b3611c0b0deb3677552b40cb8200dd0aaa7f6470b3055e2de72208be268891cf02837b0a531b49981765a3c4bcc0c5841a269ffab15eac9e402b949bafe05a869aab8d0ffaea02d22516f5ec86ab1e3fc4e995e9d0bc3f7e0631859eb93423ff9366b7a9e9e99cdff004f7d348f1db12a4f530f28e2180fcbd19dace983177c4b2b2e01e1528ea7cc8e32c8fe59a9e9d79a5c072fdc2d0df85cf5061ef3e5c525839a2e6e8b7eab99c27ded567a5637be5543fccb0767461e92e5e1116f5a50af6c8e9d959d4553f379b635bf228ca69f88ca29c76c39f914757243eaa94e418f7cfcea2e347e1330a594f1fd99f8fa3b347851c6798a2dd71aa31ed9d185c53b1673477c6b14d4a5fb120b86628c5dbbded64dd82e444d2caec6bf62bfa8da19cfca35c4aee0d858a76174491da2dae4282dcfa56cf051550d49eb8c3f1461f0bb5379868bcec71f9002ef64069b22d2bb0430a1ea19a9ae7f8b1a626cb04e920058a4ca540a6369b3481e866767fee849507ae45ef5a6c68f7d485f761942508f77a605295a89f1ab3b82bd7dc5cb9c633f47786b0e2b97272239c7915230abe3e59da27e94b41ecf7bf9abf7aeefee5d39db006140cd0461a8b399ffe9ee5d76a0974d77eee5757a5ea774172fa49381ed072126311d93bedf2b23d7c64351ac7116ccff1d3b47f1c95ef922f4414cf901d7caa7de5345eb984646e538359e024d7622b3a4910c3989420f2520441377c8a187d21da8fc210804bdb987c1536d1c60e8634f823de6ce2670a4eaa15686ad7db6cddd6c0148a358ce120889b859c5d84ebca35e0ed7498dbc8669673d3a9fde8558a6649f9e430fbd1595276cd6e9cffef2de2571104b006002ce5c1e2cd86a965f98e75b1cbc2dcb2b03fb52c2534dba4f4bde8efa0d2f742a38ea80200fd9c86d12ee6bd14f848b1ace13394ab0102601c81b3684e438818556991e223869faadadde3f059deef1e87d1c327ead7c32761d40de1a7fa1375cf7485b3e3303ae127cff2fe093f891e9e40a9fa1375cf4ec39fd702e50fd4afe2c32900f0d35cadc5372121df0b098fa2ea8a5d160eb31f04be8fe9a530b1993e8010a1a953b8119df14aac2fe2f4e54a9ff90b81f50a32f7f6254fd8fa42905cc13b787fa1ca52c5f808a9da65310463fc94b27e18b1767e14db895a78fd91099766bc4fae38c380423526ac50138f9faa50a6adcfd61514e7efdfe2d124052ead2f3df8fb5162227d62227788495a434c729f9888ef2326a94f4cf23231491d319186984847483d51eaae7a3b7b7cda55acd97f4057a42329b0b9faa3f59bc113df0cdb2e0a1863593d1018e2988ca080c7d4bcb196d87c5be8dd9e027a744c54874ffe4c8766e9ee2b2be1ec906aa71e3a56bd7404d47a1f751dff5a3e1e475d324e7db3f23bedc592d23b5131174a7bce28d6dd9f97bcf98cc63d37f7635a547a51645311d6cbaf640fb4eba85746412fe27260aac6436852b2cb3437f3ddb3483bc9955e8611575df8463bb7827272272046a4f372045523f92ca8ac28a1de0b7af90dcd9367539d144e71bd9e36a7b387e6b573dca2a38cfc12e3c273eef7b826de7179d175f26e27f582286b53eeebb13babe478863ec63424bfc5f48f98fe1eebe1fe127bc127ee840b1ae176dae2b24f8276d5eca555cdf5786405051217f54946ef04113a1fa9a49f05c94a11aec3874f4856b29acb6a5de28dbf48357f97a8d5ab0ad079eb5549a8e839a559663466268a5be66928567d94554c01573b996b2a5a8a55a50047d52e009b6867a79d50146442636b000a9e11330ad73bda6a038ae77452d9f30231cef1cc5e70cfbdcb9d42705c788df52dd2acc809bff0e287a0a62e391448a339c5c07bcef4c096745277f741295dea0a23ab8cee8d40079d60526a4147da366269de167b34b17b14cfd0a4e2be9d95ccf78ecf9e7481a664fa56d18dc1db579ce9648d8f8b755953117b2c8b89d0b1867ac724895146d678bbb3d955dd2558f118f784cca410b9a1acb38cd3ab176c32f717e5a68f4aaf6071e6ea5c98552237a0794b88c0382a947482de808e2ec1263fc06e6dd284308528c3f85eabfb33ad3bbba2573e53c3484232dc4bf475d015b9c2dbd2ea3e0ccf4ec964470fe7e6ead9f41887066370847b826ada8cdea14cfb106d36ade70dd0f037dcfd410bb75b0d61a5830674d270aee6a4315ec9469a352c58367e7ddbb865a221967c12cf623eed7c49bfa4cfa7d3066b3cbd3469b75d6ddae9749e15df6acce3ab39cf1b71da9073de9039e70d9935967976134f798335928c29a4d888d3693c6132cb1b59de58266cc2e75932e5b9aa6d6e6f3badf66bb5badb474dc5bde8c031c79808fa8f0c0992b9736c08dec4237827514205f99e7526ab184dc842a0095862e0b2595957f503bb3a56e861bde4e4824ecad630eaf49c3e0cbc8f2998a9c18ee3bdf762ce7ef1a216ad5ed45f57d91ba8cda6f95ac3e2055692eff74f7bb933eded0178dbde093a4dd09df08ce125e5c5e5b3e5dc9d3350e22cee0b76d4595f089fe0dacbe8fe28f39590b1e5b59e2ae9e6f8290f02742928c79e49367ffadebd7baf98870f82fad68a5902d6d6cf5e29107a254a3958153b7def2bacef440fdf09bad2d32cecbc77eb0541f3ab6298eaaaaf92429418093f5527e1e4b3f042185443ae941206a4ce170549b5f21c6372254a3e78447a6699f0d53b41b9a56e52f10305a905db80824300b41f3e7c12dc8992d531300cff9321c56240c0a5ae115aba30f13a35bb1f682024b9abe5df03682625df0943436bb5fe3df64c5fcf334c62f3332ec570d9d60f4567317106014e559e169192ecbc79f9c83a83088f2b02b6dce792ee44293857c19a97a31b39db8d52e9bedcfcd54e4bbe0ba5ae31e93ef5b7abfe53fdfd1f8aaad3a97e0ce36d25930492f46f9902f0e2e2a11471297cf898f8eb5b59b13a478c0a27eae7fe4130636b1d53ec9f82eb3246ba2b0e5229b8d82313bca630954c7cc9be1268df7ee019da134a09f7a58f92665e6770b7683af883a1b33332afda8654c73237186d9add2f1384cb33fa28aceefa904ec14a92bef809beb0f5b2a7ef9d508d45f663322c281c9d505635ad7b0c79edff17ee60c83ecda516a2199d2428c576f8e5bb31ca48feb44e23da37754b857515f75d95d130829e777b2920bedc517ed4c5c5680a9da743049e1a34f46a7a6aa702671465aaae5527a13b416f3d130d851e3c1792be95547ddc80d23dc801ee7a4b882862348d2a8516e3b904de46397372bc439b9629fdab4df1374ff55dda228570b0103402cc55e32c857047ad386d08ac25c77ba14a22d12957213c9dfa85afd2e956df391b19784551a2fe894ab4c920489c9d69cc6f379bdb389d66b7da3bdcf6a62af9cf7abc2b88ac47579d9ca557fc45b64a25be4fe8aac3d2c93ccb81093461704dd1fbd94c70492674a5bd42a1caca3ee9b7a0772a6cecc9c4fd2c58aba4ecd7a4b34187644e8fba64a1fe5bd2908c6848d654901b5d593a2f0b4b8faf7a6b9d013ad491284e9a94aeddd7361b34a7b3f61413556ba26bad6a6a2de8acbdc24489c9457910a059db3c830da5b1a22e9c77aee8da8fc5ddc337744dd6f4aae73983acc113444f13b4153794d22408daed25d5c133e67486892a9da8d211d5914816aad4ff9002e54b4b37b496e986a235bdc19e07c3764dafb6093d523ccd7cb381bf0b13764e43dd1cc06c617c08f42e6c13b584a6420815c25285de28a5f76c22e31b1bd3fb25974ae234391561eff954bd8b047110fc510155946cc95f256d76c91b4199e2dd14742c12dfe9b4c0e16faa7ad9939350118504bd118463d5c71be11deb6d99c4bc11b8e77f468788e4242932b8bc11865b1bab9e8a705ff10c754f833144447ee33be7b45a98748f9f0463ddec42352b719d56bad1efcfe905c4a430a5e7f5d2d279ff5cc7a288ce4b58056fadb57c373c816f9a9bc795406f849a7f49575132783add57894c54b9c7a6ab652a292a8f1f469546ddf0f851a5ce93ba3adfeafb61f48d0a4fa2a940824ce91b41124c844053bcdddde6ff37b012cfd0391da5e402303819d3f38e07cb24a1e79d3234938b26a5e340c1c9b88c860b6f66ed21678df69aa829379b660a515fa836a75225271073d6221be0d0b5ed8e1759183af2dd0ba396b1b5178aa0c8beb3bd1728c551b3a9dda159ceeda83e6422d6e8bfd954f0bdb782769fdfa2caac3a53f3c39c7b32c62efd5312048b148dd5d02f68d201f4410a2dd3394d3a3c9daad7e7f4c26517f029e2b88fc6152a482fc8b84403b5f5e7224ed139196bf3518b887184ce29baa095316f36d382345e7c0f6944e7f4bc421dc9948efd6419e69b4414e3b1539e629250376f98745f445e359e4e55a5e67987df499e4e83403c4b82004d6942122a88a053f5bd598ac6446032d1bf124ca641300902a424d3738f446f36e71e8156940f40a628d664185e64f053bd72e41a5cf86c038f6c43b9aeaf360d5dd00b138304401f61709a805d42fa8bc4f68fc9b9f18c7b9e24505b204cc4b3a48fce3b6c3ad51d5ca86a7a09901e01711fc411ba50ddbfaa79474a7d4060e40b3a1802993da7e39edabde290f4b0a27ae71e1dbfd061999c09f93949f84c46e71d31c9b32439e7334964b674059fb2e556c7e5aad573c192a9f36fc26290310d7be3a717d6cb6adc6e6305f283f110db7827dea7e879477d5e2d45e9dda76c49cf3b325b6e15b96c2e53324ae9b2082e60a904a912b871912fd411b7eb1de276721a5c07412cd09854d13190b76b7c7f61a01858be5bd54339b8d2adeefb8efaf4d1dec8bd293bb15ed0bbcaf5f605bddbd6ace76dff165de0e8d64df062fb7f86feadc1f60b73b11c6ba6c75b6c35fbb7023bdb6d4e7e175416a6a0b017dee2cbf23749e9497fec8db9b60224596b011904c8188d57ac81645f8946bf88fe6fa2dd8e90351ae638829f75cad524082e123fca25c9ed7df873bb80da5e9dd377c219ad3bcd813326de6c7eb501c20b797f51d51c3a00e4650084e0eb8f4e030872b2cb1080b6ee51f738e078b3792b361bf4161c367e63e8ec7129c4890d5c9ed8b1286cb0bbd58563871a613c43678af7ff5dd8c19d3d7efabbe89f3d8e7e1776a6c6229f214e46897f253e325d18b8fb288c9ea1d9ede9ce3ec25da0b5ecdfafdf38e9621b68f65a007e31a225f72c0d3c61d44f5faa0ebb518d58258a5aaf5244851f8bf824d0239262c2f4df6d6171e1794fed3b616091911a65820175be03e99c3a1be36b412501006a86c5caae13eb8090403277aadd81e83f329412e9037f6126608de0fd7741a08d2d5cc766886a2a8535377c0d3c9adcf1b5caa65d7b03d3d2ace53a41a96e5ad873156fed3579e9e2a4e630a687fd87369bdaa0a2df793b92630ccb98124e9702fefc23435261c2da654cd532a6bbcb58d8047a660bc5ca5e25e58c8adcbb992c0c04f2ce94275c722431019b721e049f05a4973436e59b0dfcb800fbc68ac1239864bd104f1f85611fec513e0b1c7d5508217aa58dad8240dbe5c95de3be20904f2114e6ae6d1f0089ef75372e59cf547de8ac497e311583b243cdcbff2490b6d425dc788b55615416a0391295f08e857ff96e6ed4b4141a9055d356826eb074b7d284d81b33e6b497ef33da0c9d7f67feb40865a5de744b31ab4ea2b790ccff6586768df0be42ee8887266f461018731ed6d151da3d9df9f7c43cd74620e5c8667e0e8a2bb61390e9438c4a69532adec615839b1d7f7de370c68c637e6764d264921543ff6684754666c940c583ab05a5145ad687d9dcbe543261140453e7c9f012bc5754ee41903fa369ff179b9c3442bb91fa0b5892d425dec57d17b7440714ecd5342c0d189278e4f5bbf18ca6a42eaf06408c9d8ecbfaddab04bdf72f35d8ce62040162d514e5acc8e28a4d64777fbecddcd7df5bc2e1e6be05c0356a29f85da46fe5bb89ecfd8cae660974783bff22a712674bee16f8573998f0dda4e70b862499306fdb6290fe09a33fc5faa244929c70c25461399512d9313c2a42dbb0dabb72bba6363c10a594757efa49bf35591ac030652795bf99cf4ef889255394c328bb9b610f4ea00930a2d6b8ae1f353c7d20bd3045a6a46ffe1af775853d8c8e3caf237c1aa1d5195b05c142ad644e80996766e4395dc6a5244a70844b911e5fc7639e5349ae7473b0cd95f475566c463384a02936eaab5ab0907c7015f44eb990f2ee8e6e621203f3482db482792f98e5ff326015b40276f54887d41da979af04be773fcdad91a283a389ccf29ea4124158d79c8b552221e514d8e6945cbd43bfbb407b7d1a398d147d77fd7ef01693837d14ed8e2bedf0768b18265d80123b07cd59325bb1e77c3b5c11d14796329d8d975dd1caaad4808d43c37709e2b8df8dc2829eea467011ea8e8ce2389ca36bb767e20bbc72450f2d1e3a862970fadf0ce223dae4948d3092f4b9073a85f340616523e9bbc33554955787ab3c8c24fdea5551e3d0188d63c89f5c84cf2bb3ece12961a4d52a7c540d20bb540d0e3556f90cf25ce3de9c54601ddc7c59f4df0ce584612f54ec377b7cf7633d02b9d5cc495e0ea6e34c6a9c2d69be934de3585ba857b37e17117c6ae8569f75fc4003248bb505f95423136d388ac96e222cdb4c4114c38a95221ee1769c187cb2e0658c7925a850337a91a2bd8c8e7fd144c6199584d173c5e461c2acdd34501ef069d2b4c6c4a3eca53d9cfa093f4e7cb171d30d8f1f96c205025afc60772a358ca14388153872e166bfba2c639adfbf73fb560f0bf1fe404a30094159c7c61622372940465f98bcf42efe01bcd80da9de3dc5e48dc92fbb9779ad499bb78f6d95364b95591751a21198487b05e3b130fe32a435195a1cff5749aaf20d8e97ec00b4332fb35b7e5b8284c8df4b4bd52ce2f9e6917df56347d6a596331fad0eb53282279520c2f5cd0a38d89941a8c871bec3ddef4c6327873b8929330139f4b57ca50bb81e071921a9ca0895021a3b5b721ccfe0825e0b1da18e88f62e470989713f8cc24d6d8090ce68c292c92a6192ebb4b4d35f6229fa7bcaa1b3c897db81ae158b044ca17d0882a62716defb38c919453a7588c58b89036c48f06c02e2486cc5e2a4676ddd9352fc5a4f765de17b4113b35556d532a5ab523a33dbdf542b5ca61db3f6da0f5fc926d34e36163cbfd1530f628cefbb70c9a283cba1e94eb016b0b54ec814ab7daa040548613ad54c9985a835a58967e31d04d3ba0eaa85aa0319bb6552205ab5e08776d542ea342d533ad5de137a2704ed86c51c13cd041531fc15feb30b5bacb7c0d6f29126857e4bd0a492185180ebd8bdf0cc2f7c492ea19e75dabddb7a6755a93ad48dbc589309155b736e59f9a8eea1192e5a9215cbb52b5ef9c862af2b2353e534478ce63162242efc0a7c08c13b32d67ee4e7106e0c5c9d1d4a6514e4ab9919d1d574a5d8305d56ab6a7a7a61b1574d4f7e83c7dfc6bbdf40b7ff89b461654490fdfa88d3664840eec3110475b3cbbdd64c0fc3569602c9a82249f162566e5b9dd2e0409636c0ba175a1d40ce8d9d89d3cc5d274512148825a446cc09fcbce66b9aea9f2e5b1e841b02da073f2dc6823a4e56d41da9c5845ffeeaea19a9d2389df23b1a12d3cfcc7b550ab02d7559297c379494e56528f2a5ee521d2f2cb72e57c3ccf5ef82613383f153eba9e752565c5550d5bf17ab52755584fe779426aab40c3a85aaf4d6db10cbe3f05b7f9f8aba207b15e60f20712df34c66c68ba3c93bb1d0919aac6edb6bfdb9a2942d6c6dcabc55da4728a56a5c10815809aed77c4db871f4296d2f2f8bea1a08b84d785040082f85142fd6829783b2e308a55568484b1b96ee6c46ba1bc43dadda0e63521fe6a53e09ea4e789b9d24a86925096afa8d24a8e93792a0a60792a0ca6a12d4b43609aaac4f825a65c4cb4950e5de24a8d24f82eaa5927411fb486a4e34d77f490a871af206f901e03e39405698de06493dd60224afbb5ae518e01c3ca8bce4c53b99f93916f49135e42c87426d5c5b8cf932b1117e14bd632476316b5f46823e216c431ffb8add5b5b5a8a717f67ba435c9d8bee314989244f36ac721aee88067df85181a1d8a6987c5feeeb04fa523d41cbf7a474a4f4f39e9e3e947b3a733df91d7ca8efc01a0fa885ad2a4bb99743c925f92c94a1f0edcf91e2a6caba944f91a067e5a24b55ad1274fb952a7b582efbaaca4e495e325ed5af5e44821e1fefd1c2744f4223a5f13e8fecf87db50c926a7144edda70ab09cb7773cbc6be8fcccb1d24add7fc31e1242752755b8d85e2d9fe5fbaab3dbfeda9b9ddfa66f3f7d5e630a3878e5571e0dd2f7e4683a141dbb5bdfb8adefb92141c5583671b6cfcc276acd5cf8ba55e46e834e29d72c1d65fbb0f6ef88edf3024beec91a4031b7a9fb66c49e186e9330b76405eebbd0e08a5b785cb821e4fd579bef4112336b9c1a987a2ad8dd76b98a65d1f8652b1efab50f01d9e85be2bf42e571dffb1eb59e0aa97fd070a16665fb9eff8e0190dbcaaf007bb7d3807b43a0f0848bf9f0641fa4cbbd7510f06be7eb36b521b90a6973e95fbfc242426287f26379b105c549ccfc34e2df9ddbe14f2fb7d298ab9bd307393cf762d8e8ab1fb6b2e7d679c9d3536cb88e4339afe6fb89fc867750df62d57bb8b899a496d6f07c20349fffaff4d65bbab5151c0442bb5610c6bd6d7675b9f7bb8d7dedadb000fb1361310741677847132eec5f4278162c288c03d0ef7caf85ec2d5d2df3924baaab9d6c23a1e63d7666ed9f1520a8d85514253cf7938a9380f2715e522bfb31ed9d2cbfab664482b1f30be2fb7a9e456bb304ce205cfafb8ced9f1a2dceb76ab3aa873bc4d70af3a87ae8e7b5331b0599964713d3db2152490b96128252b9278caac949ac4ee299db28ac820ed6cfbb2409391aca2d1942049450c5940f16e0462bef5d2b7b87bd85c33b6b95645bb58bb3926490c2113c97f0ba4584b121740f32e3157595a48b26a3aa37cf3ddd91c83b39b3bae92609befe4892bbef7da407ceae519ab5edc3b7a5d447f08023091cad75e7c4ef75c3a056fcd07cc87087cc157a99917458b8f15832225555a5a6c6e08d22068c25174f7258429dee2c4dcc7a8ff74a8c2c73a7261ff240a712ff702ce318f93c8491cc365dee0733aa4791186453b43ede425d3e8e11f1c49dcfb5c173b9be3fb85b41a0f8cc9a7efa8b4452139831bd4c2da3fe215cf2e4d7f47b139671fb34cd2bc58badfcb7236d788817b96cf6795e76eb5027a522ad86c5a0d38da479047ed6899c5a93cb29ab646cb55d69a706f1bfff0e4276b4e90d6a536d2b9814c2af2b83cb93d7673cc8a63acc7e84ebabb7709ca704ff32f88e3edf6798224c90827ac70f6dd33984a3ef97886e46683246da2269294f7ab3b547587b0fec680f3b4498ede04e92d695376e64c3c97328fc72bc9516bca243b82c1e459265b1863d29445489e9ea545d06b0f97f3d2a4ce27579d14383d2191fd7b7334a266b835a13ef0d6a405a92e739d34cb6c5c9b036b9c146b2c93529e5e7fc98b9b66685580c86f95937ef294e557b09ac298cefbe624f6d5e064d8f71f6095cd12dc5b692f3a27d75ca74c7098b8d56ae7c4091a9c94e50759150e7c23c75f4a8cc1f1f78df3d81fe7b119a742edbf2748566d818fc3b048d56117465f2e6f3f2685b6ccd8fb942c1f34a7b183190a6488b7a4d4c74a6745dcddd69a4e209ea8bf52bde789f5f7863fa5f4cc80418d19f6962c65d542a3482c619dca7f620878211793db04c4266f6d9e46322a77e327a74050fbc4d43e511f5d7fc74721d4adfe10586d16069bc557ffbd639f69cdcbca696be219bae3c85815a590818714097ad252821e138d2ba53ae87fe1a1a2d83bef595782385bf95a3b2165f9f32441faa303f511da6afff5f2fdbb8e562fc5b3356ab5da12b7ff6b3800dd8019c3f0bfd4b8c29e7c9a5a7f14d96e3be23a90901a3fd77707b9a2530b1d1522cb1796717d9fa21c4c279aac02b6670a6a2f38ca31b9e37013b1dd6ef725f0e1e57c9b2e818f5e1b48e0a833ef04c1a5aadd6ca645561c499a5db52d92539e9094ef2447275517ed877eb8bb3f183a7b42b817aec036da8d8217bb287824e7fe218188e8673a92ba0ff6c57dd91fcea1e00fd1fbc325d8aca1fe0a9dbc49b43df6df20cd26c6447f1561b24c908265c6691deb612678fc03f1fc4008f835217f4dc84f09bd7f75a3b05234789992cb94bc4fc94fe417f22e2d999931c59d3c4ff196fc9d704efe2689906499907bc31f45cdee76b8edfd35a1e8d784decfe2740a32c92feb3799906f4d42bfe8534ac6ab749a00f18b4272c373a1f06bab7bdae99e74c216d1288de71fd8e49a5df1776cc1a396e63aa6d9a2b5c59d3d7d57ade25aab74ca6771caa7051d1b8d3ebe7afee2d3e8e5abdf3ebd7f7f7e39faeff3f7bf3c3f1fbd79fffe7f46a3b2e786a4876beb8c5db178190bc5fe4c81948bd57299e5526879ccf417f60aff0cd989d3af7c2211c7bd8ba4849c7486db2c7d912d16b1841e14d205df0213f3ebf4213516b9d621c4b3cc2ddca0b65b72fecdbe6d36dc94f05253ff3762e87e4b7e4dc87d76c3f33c9ef23759767d599870da62df32874b1b2a4beba372533e99f3e92a31d9b575d9a49aa7e3239f457b7378a88df777fc97354c24f2275a16e910a729641bd044dfbbc0d9927d205ad3db5f93fe5f1567a3d3cbec8c43bcced4c0732ee6e5a9d6176699742b656a9416ea8adbb9ebe9190a4a646734ba7cf5e2e3ab4fa3b7ef3ebdfaf8eef9f9e5e8e5fbd1bbf79f46bf5ebe1abdff38fafcfed7d1ef6fcfcf47bfbc1abd7efbf1d54bfa5342a4f1d3fc90e59225f41755a2a6f0f2fd05483c95736334d1d57029dd12b36bdff2c2c074571f51a495d666057b8c320d1753d5563c7982abd2fff1e913f21ef4fc9d6bbe36fe1a4e9d57da7359bbe7b2334b56627eb94e27bbccfd5ed7acee9322f44c5d38561dfea6444e3c420221690d0529b2a355d989ef6205ff70cc9624cd50718344eef2807fb6c3aee9d03084eef6f5b9ac039326c89795ce1f167d379bbc4ea60a0254910eec18cc409add121359db89a1a425fe528949a119bf31fd1803de986a842314a7e0bd2c9d89322c580b3ccd78ff070c7e79387aa32e57639973fe369559bda0a995846685d3faed2b8ee966e34e58ed19acfae83d296dbefe5cb34b7218aaa1c6d451e32da982556b257843719913d9eac1a59c22773445c7278ff037aaffe5c1cf3f37fe7f493c81308a3a54e34dd8e99e75c2bf347e6e5804992be164ba827e3a8b38ed7c157f69fcac6abcc896eb3cbe9acb069ae0c66b36e1e32cbb268db7e9a4d360e9b4114bd160b3599cc46ac73ba6d9a7792c1a225be513de986453de8845c38c62da505c420e111b2fde7eb2c58d59b652dd412847d5c5f9db17afde5dbe6acce284db088f4a3c6f4ce31cf8f175239b35a4f721b5c96a000f5c8e609211b081ab634c74e401dfc7cf65dcbae042b02bb0f14b7962057138012bfda7942aac603f136cd90e4e3d304cb35b847b096a868adb34315e8aa086002e82cb4ffa4a094d498809df6ec984be64525100d5bcdc5f4daab2a2eed1644bca22aa1d5fdffb4c4ed4702294504e2a5f57ac6fe584aea85747a76b8bfd414c12ce72fb7e85b724db1d62b3bb05bb4f379159964ff8eb9c2df8c71286568c900be43aa37aab3a4b9e2ba90838cfb92d54b3260bfb548c912c6d993fb20a30b81d9f64a9c8126e83dada96ea53c9f3345e804a0206daab8117533de7ff5e7121cbf583c0f4dde180105a7034c679762b78de98665ca4ff251b86896dd476d1695cb06bde10ab9c37e49cc9c63a5b4168d3066b2cb3643d8b93449d101dd2d4742d3a8db9944b113d78301b7716fc8166e86d7dd1c2a46626a31f1b6edd02fd3f1aedb6cee26056eb943553a7007ff3bcccf461d9fa2183e7df7bd84cc5a3b54e0a78439b5d62dceac6f4a84b2ee823724ec35ecd29685431c3337aaece850ffde43b0e09c7f7e133bed9748f1f3de5fdcab6951b3524bbe6023640c432be51085536c65cde729e364240e4dde347a4a19ac5e95563a65a2aae49d818bb72ce5255a7315b0a85cdd34c3656a901043e6de1e882864f791fc2accc922ccb51979f3ce0387aa485df6b9da7ac845ac92dbdeea80e8e7bfa6fb793a50b5da51ec35ee17de8f59cf2f605f088571ad1f66f3bcb4c48f34513dd09793b85ab38b8a601b1e6d8aa5d15ab5e514e6e361bd567486a1a57d1688aefc7745162c538aa4e04922d56b1eb128d310096a714bdab5c966ae512d7b15524f672e01b5dd351f7d9b3675dc2281fe4a0756aa282ab0a82f0e94b9d4aacc8c63ac88754123e4887949194e6ded73f7bc25a116388533e0887560ef0acb9bc909883705888293a8daa9dc3325bea3878a949af3a0887d466f3d7b308092b269b3f653dab753afe19e5ed2e3eea928cf2413c2482c6ed2e49281f88f207b320089fbd441949317685892e4c4886fb0826aed85d3184f4440247ba2c23aa6b288b0b27226f1d5d3769751dfdee5c36e986ac4f48f1b2e2079fe5f26d3ae57747b2f8ed450481449dbc134f8f64279e0246baa4832179affefb40bbe495464d5fe9097901a1df2057346d760b0bdf77c88bab2be967f4deb917c8520adfe232157f52958a55903a00135c4a526ea3e2a94ac41bf78e873db943978aa1d01ff56f478de0f31cd277228e49f30d2e70c1677489f11b75f672f4b694c6ad34f82060e835f1c676c4fd8fbcd50753af4810e88fc50863b552a1c94ff8b56783fbbc432926afe0dbf60baf820035d1abcaac9ea578b3e141d0cc10c63d7b63f6ca2d5ec957e0be28b73bf5aab334863f602961ac08c4ce779ed214f7d21d7c5877a794f4bdcf24d12baad730083ea14b4cde21eb82ab1e7b7a8e9e2fc22bacaffd6d1c03ed40e22ff5542ff5d45bea149395c29c0656574e4677109903447a1bf251ed7ac52ed3fa451d756de62feb06fa28acb8bd7901fccb6e5c5dfeb057b99a7fc44f34fdfe9d0a9fe6bf9d26dc995d3df289f1dbc5824f95a8e35e77fdd7e7d9ad7bf1d07ff14e31ae897b77e2bffb90674a7eb26ef9de9b5f05cf7f49b2c935d8359bb6c725991a38b0173b99843924f0f641aac453d820eaafeef864a51af8c4e6cd66f362b341ee649565ea4257f6c187cf1a3ee76bb5dd6bb89af5addd761b01d0f9ed527e57be5132a0f1d581868108634da331c049359713fdbad5d8f46bef2b9565cd7da139fa4ad36de9eb4bb612f5ab54513400dffe81c5a9a4bf97deacd2df633977bb5796aa76c0bc3c171bb151037879469c9e7833e2fe8ce4a1195999bf0666484a328ba876f8ab3afe3b73d629999592b3ce94276cdd4b682b5d2dc63cf7d08fe23192be68279120d9eefbcc1a55f6ddaf4821038d9432aa7e93848ac29cf03e9e461fda6d62013d4a490969469c38541425a462e39ed1a49d114797a2a3ee9624cf441f79049726e40ebd27dc39d26a8409c984d17bace8453f46387aae0e8b427ec991c058b10b5e1f1950388ec9cec952fc656973e6d92a997e8e7932adb91dae6e89228946490af4c8b2129a2615d4292d82e7d808cd139716262d11ed9accbd5582b3d964a87c446f73b6ac4541fa2c7eb503abcca8ee2c76d87299ac21973971cabd0a346f77955e7f79f073f32f8d9f1b9339cbe55771b44c5657717a2464ced942093437ddce13adf3b27266caaee2bbce552ce7ab7127ce1eec6baadaa0096e1c87ddb3c6f3eb781e5f678dff5909a63a502f3ff284b3bd7aadbf347e7ef097426b573efe65d59e5a7dde9933f1fe36fd90674b9ecb356a99f3dec27dde71679f48c5d7c803955dfc88a8c8db3be7c992e7c29762aaf776159d86bd7438a010b1313c3bb77c7c1dcb1787aa2cb23f0ebecf0eb716f5af6bae8f6a543f602683306126deb7168ef56590aae25f6a99eb8926efcc742dc0ee6f5f5a51ca37b980e81ee56a10a7cb2972b456042c75f4b0488eb7bd3fd1664b84cc9687c65da41d2877de33e9aebdfe24263a8e566367925b257c16d092d1586dfc0d1344285964c2127ec9f39b78c215368638adaaec45960a99af2632cb514be1ef16eed5bea5bb1ba6eb53e340495b396789eec219f8dbd6a20af41cf777ea0cf8d0185d69e5c38ade2f592efcabc6c23162d743280876cad23ea7125a45bc119b6bc86cd6909b0d82370a977762f11b4be2295287156c29decf90b9c3dc16a2d6d44158dc89c5bb5592bccf7f55471015c9fbd322cb30ef644bd54e3b1d90aa919cad346253b6943cdf6c5660155f6ac468de8115c8494cd966a32d4d98849c5666196a8cd082006594a10c638276e9f56693f94bf10edee32088c5eb388d254719de6c5046771633eea77a342823318edc4311b12debb7b308b15af57cbcd9ec0c06653456abf7bd43f23f99e12de204e2007e8cafe63a8880eaac62ad9c6f366927cf56e91452abb68b25d724f4fd0ce5c4d4c0987886a193f24ed99db1500edb05f4c7bdd25448741c19b263890d5ce52f357a47e9400e493e90436c82f60f5a6025fa0b9b5c5fc1585e644996b78829cef229cf6b8a7e8fa7726e8b3eb269bc12ee29d33679f6f952ae136e1fdec495da6fb21b9eeff9ba7eb73b04afbc340e2877dd8f773a1d97bad24f97d7f172c9a7eed97638af1fd77c7748f3ddd1cc4b03997b73cedd0fbb4ac3e2a4cf7d9cecb65b49ebb987c1dfbeeca54180805ac155e20d4b50ea1074b5f24eb96de3d9762ef67c584162cb346be15eb56b2ab87423403bfc5aa5757387f2187fcd8c08929095856a32a5bc134fc95c77303599805b982c4c8912195a982cf5a394490b93917e0009ac85c95a3f66e947fb7d72437967c1eec895774f768462f18ebd434bdc9fb717d112f7d641b0462b4c569d29930cfe135c8a1aa3b009999b7c542b888da66b5e70c9d01c9329e8beee9edfc5e2edcbcd463faef5a3d68fd109f44e726a6dfdc848ebd4180d7bec69aef83b2508abd57e9de5201d2046e6f8e94dafdd66b89751d63eb6f24ed8d34db3c34de9956e2b283bca889d3db8c1ea98e7ec0e89a363122aecda114bc598a28c084c66f566f1935d0a1b048a523dcf73b64693011fe220507ffcdeb61893b8c319e4c653cb90b0314f0429755df4a2fae4d5f656c074a83e1d84c320402e474b4626d92a9591d8e2ad6a900481d956fd35dba10d059f74a0beda7ced1b8dee9739170abec1c8b8196e15f2c764e72c694f23bd9aa9a219ea281375acb482bea645bad53933efd580a241ebae45203d409e251f1432fb90f39b385b89bf57cadff13bf9f7d69018c884964322b32c91f1d2f6c372ae2a6dc9c8f5bfded3ffe79afe3f97fa5f97fa5fdbfe3fb7861e97b22e598743bc0d1d522e979bcdfd9664eaf106a2f8df6f81351c2db2294fd42340ae56d64b5f59df6ee7565120e112a20a6a8902dc78900c8f688a4956f73ad381a650666bed7084aa96d08a7e244c2d4fc178f33de8cae1ccd90ed29a9791d64223b71bbaea98352557f4a633d2f959c8d8bfc4571ce29b2c8fffc852c91284fb1031f756111992d2258ee079ce151b42523a82e0523fa3f1d1b433e76c8a1fcc88cfd84dae151371c373c1812539cadd19ac603b8276a41bb68be5a49a0da5acc072fad16139b5ad19d5dd6e36832111342409cdec1e8ba749afdd16788db2811892d4e043dc732351c8d83d980aea57ae0ff455105ce9335f333cf5a633322d000362b2687ae30d02fdb8b6c35fa31b92ba6dc981475fb03b05aba0ba187487c01fd3f1d15cbd8ad3e255685e418ba319d15b40c75b9d7635b19913ee156319b324fec3132f7c8bfe9e6ffb5f5436aa0eeee93988119cc0adc76d3338ad7c9341c4c60b4c83ad07c1703c35e2221a09d60f93f8ac42cf97cbfecc70fac8a7de1085b446764512478875ea0572244b7669ead86aa34cd887e254615272ae8029d62c2e8ebeabda968c577132fda40ed78185321307b5a8155ea57136687e7bb30c37ef8fa8f86ccda8b428a8a3f769794e9af3bf605fb39c643b584a94b1d4aac2bc9129959db16284059951d999c642fb43c5594ae6549a5c1f644173752cc852fd657764445987a7607e4dd61ec0c0a61c097243d74719b9a283757b45d64317add57ccba6522e7f90b69238e52c6f11fb5ddaec12f8303deaf2ee23021fa7f0d37d9f36436b9baad55705c3425a8b386d91fb2b2ea3dd3b869b2d517430eea459b6dce2039db0bbbd9d5c75c43c9e49842b9da5f4bb37b5d0c0a8152e1ed89dc14537065dad895bbf6975e966c59acdcd922dcc722dbdb51a118bd8e8e05e6d587443969988c22dd18f6b78ec6e8724dd92592cbf03f6fd89ce627918a1c91f406416b64d6e6655e07e564928a0bd259b6a9ff299a427c43d83380f057330f7be60b9fa16f8764c73765ba33a8349a610278de5b238de3083320e4c0fccc105939fc83b38ac15ba7f0f196fb8ce3c23b365141230b38c7807fe92712665b68852c30c6c23dd2284cabc23b3a569901af6c134e01dfd63dbcb3a93245e3ecfb90951e6ef969abc55b5fbdb95755669d1cadcbc7c47c32d997221f36ced438db772f3585416cfc4c2fa2649db4b387438308d7c30994381dad7aa9014d568cb141e05573bd55848b680f86eb9e396067238e0c342e55256d231480e46bd199458ad811cc2ef011f124655638d5f508afb537db391e2c8fcca8de0a2642a4cd8768b7b6a5a57b1903c07c5e9a7f592a342214aaec8fdd2e4088b5a7aaf5bc4c7089143a61a6544e0dfda22465725a2fb2d8113af55a279d4ec12ad0c54bf56690c7f4147a27e9883f7dad58845f63be7d753b6564f8b38fd5535692de22489059f64e9b4556e24a27bef65d49a478b452444e7f2f2b2c15aa452ac8a1671ba925c17a9e779b6caa3d6fc798ba8afb62e2e2e1a2f5be496f3eba895242db2c85239d7e59f3f7ffedc22ff5eb15cf23c6a0dfe36fc5be3c894ae39cba316fc06df32bda47a3d14b5bf672b995d5ec74b35316d541cb554598b00958dee0d365572a3da2a9db6b050955fd0b151951762d4392aa04edb246b1c23f40d8e2f8ef60400565630ac8ab366423ed7a204a36967e43d679dd178359bf19c4f3f6a978466a838dc3d5c4ee69f74f5a99af6dd72a77025a0cd12fc91d09c94464219c93a4c5fcba4577d6e7f67a9b928280aeaf42eda58419d240a425b663c2cd0bde567a2ee69e7f4f467c43be96a7129f9521c39872cf588b78a358cb26faa78000764bb724fc708cc09cf3b3267a949c2d7058e33b5c25c10d8886b48ad348a6956602b589f8b6c253878f72949b5c3d52fe36a84628cb7ee0e4f74ae926ccc925dac47bd59f3870418b82824336bcc199d84c4b07151979f10a711d3be4cc0712b00963229dd815cc37579cb7da745c67c96e5fc6dea137b4f6d588cc8fb0dd204d04780732533ebbb2188c0ed667fae1058c9cfc2b9998f41d1ce13a656b448774838eec9ca1ad27b05c5510bfa5d6437bc45004c224e52681ea5e42eca3b77641de59df576db4b3b6c3a2d8d00e9d6d3ec366d915c6de69e1aab650b9c32d84cf2bcbc2812dfdb68e7f41c343f82cb7f64d942b123eaaf79f9d19623a9e40858de5f2b2297b7c086f0c172c2b59a336d803c3777cfef385c6b4d9844a9126ab9c0f5c7a7a00f20ab6931a4552ed86c908b602a3a8a4674266cf90bff23e639e889046d768d578f59859db19793f31890200aeff4c65aef602e082b7abfd295d95510a03ca0e3ea4dc6eec54807809948fd57bb1ce57b65c914477b45c9b4244aee2aae4bf3f1ef68768e67c71d4492d32e3f79809c96352521de6c4e42acd55e4cc89739bb4ddbf9661392d89358150da8807a8f3d05ad162ff0a8e2950d25707a37cd81a91e14e895d04ba64463f751cadaf9b3b8cfa218149c100f4003a4417c2fcbfc6fb1b3b2b3e0a0c4363859f18284519fff2c98d50aef69985507c6856226f531acbd14563cda14b95ab802240cd8639a6b2e9969ce98e6faaf3ac9ebefea7dbdaf779929a956b1d2cc70cd34373f30b928d867aeb978ef60d4af21bebff0f96768e6961d76f95b47c9aa5d0a84e7059aae2247691063b692bef6c1c891d5ea30f81d2e7d0ffccbc358bdb75f9d03f13cd5c8bf8184f757d27898fc103e5164156686747a1372eb716577542369f347eba73d3b76a30f355f525816e22bb1f48a5fb0bb2068de560480e2e5c06b34c4c586d6beefc96710a08da645ee8f9289fca181c4e98181c4e9e18154def7e4d3dd81d83c2d9d3fb26cf1da8c4ad0ca3390ffbbce92a57e15ffd1d428b52ad492bb6e9710e202d8e29a8b71f1ed8b7192d0db2a25c93a968522c2fdc464555b53f157aa9afa8bc994263fa3e323897b8cee6aeb8d747e9476eef003f7a4c57830fad3d8e328edace1bd7904791d9398caa7ddfe679493298e3ec11f520c95c6c48c86aedaec67941cc5b8bad6fb16b2c8feb7b384ec3b9630de5d98dc2c0c330bd346602001b611afb3fc437cc71324f1514d2978249b99c86761ff334a49ac26acfea8195598a51a9341def9e90f7d5447591e5fc5294bdeebd147f7db2dd129224d73a054ba4b520a95747b08831cb0c5909dea4707bc134f878afa565ec0bd7dde4769b18b79c1bd38204ccd6af8ef605523e4b0b5ab5c944015cdf498484fa4900dc22d5891e5bbaba8a429c3ac3292827d9a79ccb75be2f0a2c7df3325341aa8b0ca07748dc9f516a5e8e418132509e12d39ec6c6cdc8cd0f1c9192e102c43f8bec072b17a8af5a87f6779ea62b43252632489ef5d436e3006a00a40935993d2dc9a2ba7dc7a5cb75eb02489d3abc6873c5b7e5a2fb968dcb0249e3299e5c2380f276bebc2e61cd81ae335986efe6b9967cb234549c5bf1a4b1d11a5d3f855f0a2bfce64ce27d7ee11e186cc1a6a7f54078b4ee32367d3c622cb7983493037755e8d2bc18fa0f151f195960db9203a3aacd0dbf486e5314b65e3b7384b8ce18df0ee2f65a184e65b1dbafddfab38e753ca8dc5d83dcb73b68e3819675912e9382d4a66026ba888137dcd0ed6d1799c5ea91febc518aab254b583f6ef6791242ec822f12220479c58fa0b95d26cca5db75092a5bcf80b4d241173067ff91d9bc84892f2324631d9818a8879aca4ab495392d6d800eff1936f99001e266cc787e79797a34f6fde5ed606efa871bf77501d3e527c7d8a8ebba142e5293a7efc5071f2eac7134cc023ffec14fcbbd1f143456d54dd634552d48f87984c686ba0d7a8a15582c316995173fb50286dcab7d9bd7ae3619292395990a575594e10c7644d154e263774d4775f02738b612b8214d357745df7466232a6e8867aaf8ca268d8a2f4a63f896e30a5137241d1d59e4a57fd49740595cee90da590e2fc3c085688eb7438cd5561dcd8ecf646b41992316d76b7ba5e736cafc4969b0d5ac279ce31196d3653c4719f95a61c41123072e30ab433633748b1cdb63e0e8299c599ad1158a82ff974346a61724b2fdc4b5979a93abade6c5c62f56b6bc78970c4c9677adb97eed9da4d9647bc4077e4330c6c89ad975fb3791e04a8542d2b4d0857c05961f01a64a875d670013e1ad1c1d0e6dcf883d3b0e64058c87d08800bbbed4199b694a9852eff2ec47d8fa43487705936da084a9f865a13ee6c3c8eba7da99d3823661738255d4c8e8edc502166c8c1c1fef93135d2a7615febbc2239488783eef04f7dca268341e5af71fceca8fb273af464eb527f8ce65aef65b3ef3c0dfba8dd2e962ad5cebc034ee410e3281d3035251307fdd0401ed60ea40a41008b0780a8160cf7ee84b489998b09155d4b33a1effc82dfde7e42319a60c4ffe77b9833b1db4365e100c79f3ed428fef4f48776147c3a7dd134b78155d3529d26db6caccdccd3eed999c57d99bfdfdec6b4dba95e3f3027a97c14b631469993e5d28ee03a4687d785d7c181f91f878f0d917b6457e091a171e199a2710ffef9c5a2ff4ebbef19f57f19fef48024d44a2a05a221ab1d0aa784ac8ecc2e81f92013baaa903c32a31ff9d5abbb256afdb3d59e6a4c32c19d9c2f1336e1e8c1e0cb977ffed4f9b9dd4778f06578bfdd0c1f5c91d6972f3f052daf56b9d38d63ff71e7e73eead32f5fbe20bc69ccb25c4d45170cb1eae8a76ee7e77e0bb75b3fb50e6388266ac688e3cd862932a7440145ac6691c01dc985441958dd1c00b753b5da3bcb1353565d918cb262c504cdfbb97bfcc4ae8c9eff20e28c2d391458c94f033104c72b704a37cdf5b09aa1178f4e07a0cc6ca0597bb021a8545f3bb447d670612086708549eacec90e9763877f1805a74588dbfa5534d0fa48412bcae983c13f3bc3f64f0f3afc8e4f100b020671cbecdfcedb57a30f1fdf7f7abfd9b45a18f75b97c0f722914ff0a8db69b5f3a8d53abce5cd3808e246ac78ef03e7e8040f5aa3d124cbf9d15731127396038331f4facebf079179c1b16cbe1243dff8401e226ec78f9ee893fcd01ee4833441e37f52462cf77326e691a6120bb654bf50bcd9306ce5067855e78f578ce2cce09353cb349f760d42393d364cf3e989272e2605c41e754dc47135eb3072511f669921cc60308f70afdd964f5317e7422d4c4f4f8a4b940fc221c907dd21de6e7d4306684bf3b25504003265a5c22b2e695c2a993341b35289e0920a4f804d0e1cf9c7df459af37e6e2296dc6fff330aad699e530b973ee31939b86f1c51d9ef46219187f0d6e33abcf53d824b2df30011701d412d06d51a8d926ccac47ca40071e4bc14472308ed6b4f426a099fe33939ee4bcf05ecff6e22163df68be8266a1cdec00e0fe687988deaceb5fd0def875197a4033ea47e727ad93fb0a6d1b7f9ca278799737d2e09c70758c17df0f50d50369e79bd1d97bdcdc6f305db6c5a5a93611ec6599670061e6d6ae6b0c3a311dc899ae0e4f4101adf3fdf9284a0265ccb9cfec9bebecda6eee9ab8014d719188da875ef1de00edba60ea50ce0e61b60707a6a90fa63a709e97a283cfb01145e96452c26d7990fa753c4c1af2df38e269b4ea9ffac1866303f29e3e7d8c3c6d97f2031e8b53a706870dd62fde742c97e6ec0a525508b9bd72d6ebb9d3ecd7b389e2189f8201d1225631691915d2cbe1fe43f606191fc363fabe0e191018cf0d450fb6e68a8fd63ab227bfc18931570b26eeb0cc22653baeaafac03ed21e6d644115f910999b9681aa909106f0595974cb2df627e3b8460f1bc335e4b7e0e4bd5a4d27bda6cf4bbf7604d6bdfe9a74273c529ef68032948a7ab7ff64a1f0455cb2ff062d88aaca870e8c3cd09520740891144ff9018e372afbf685c366c45d5d9f16a99767b75df6ec4a8cd495b563a047d7951896bfd3395f0370878c74662039300f859ee400b69d58f6bb6deeb9752d96eb5ca4d2f986aa7e0664e45f9d52597e6d582760308693cdf6cd09c26987040534da34e0882e6a21c417c49670613435a22a753a454f6f20d3d263387fd7a5a6f9a69c7ae39e4c63780e4e25514648c8c2a83042aa321ca25069a5a618552f3535aa17ce7b855a485ceaf712a9f00e0fca88850c2b5c6b90e96c7cda33e007e8eefd341bb2d877490133e0443b71fa2c93ff841f7395ef7a9d27a3c3efbb36c19200488fb6afdccba41aad08cdac3295d591ca9b6ada9a8247611869b49014b16c94ee8b437393a32b2c58cae061313392fe9cf202a6dc1dbcd70a1dfde1ac8f680711e04fab1f0f19f2bb0d480de0c7ba220ccfa272836ed489634e9b5db93a7d39ed5f8f3811ecf90aca91ccc863a91cf0d44a34cfa315a931199114994c41fc56844d6640661a705f683ff514a6ffa234ae97ab3c9a0965a4081a31b8cef17b469b2706eb5fabae5455968513a8300618b20689a8b882b9daec45621639de3cb3ef7ae9a741c04a55e9428bd5b2483a05917bbfc2a08ae2ac61f35b5c64130f66b8d7110a005d8b799b517ded976bf25268b4370f92434f4edc9b111aaf7b0ec1e53c7490c69390ef4da35bdd64be85ef518024d3875b162f3e3284731496b144ddfcd4258edbd1f59d1f0107cc0dae990ca41ea04c5836a8f2727768140ebb0738297e6ecbe15afd2d582e76c9c7092d97a575c7ae75ba3584104cdfa759a21c3f80c8611e2a607b5993968ddbccbfe8283712a30c8f681b711f3d65bfcaf316084d190c47430b4ab6874c08a17eb4994013f066eaeacdd1ed242711b7fdf3590ae3d38a8fd796239b16ed77062f6aeb26bd52edd13c38875e1b2f2cf615b2b6fc41abf36d320002666023f9bd32080dd98b9c7e62408e0ae724ed3cd66bad94c369b1959d0793f476e01350b81a3c1902ce9c2171a00f581f60d37158a58d92d1de1cd661e04a8a52bb7281d6d361355a09da374414b27f9510f78b399a9d79a8133af0b9ecc2b78ef3ac09b8d4023b2c478b359685dfdc81dc72ae6f86e08b20ef1002ebc87f3813a725e62b1fcc04e9f1835dfc9d9373011032d50fde56dfe9d028817c8fbdb233a7da221efe44c41defdb6970ddcd75f27199327c7e6067a48abaf4e1fd6bd7a6b59a4ddf2eee99e17f51f29b8adba172f12b658f2e9bef7f5df526fbc8f3543e2bdf456bbd4a8aea392f4507ae32480526921de548b79a5c830fce5e536bb582906febc5462658a52a1356328155ab1a054085c7db9c4c809a5c2df39bb36df6e76eb4c820a808e01a099c31a38089acd6ca060b98a1abf218fd7900a48e75403e43b3664fad60c405ee123e9e5729424a62c08eaf2a46b27e1a2aa22827110c46e9410911924e30917a21c1dbcc831004d726dfde3fd44ad958c93964e0d5f844bdc6cc0b7661c437255efa7ad5fca43844bb4111b2e17bcd7d0e931d6fee47be9cf996504ceea1981efd2b02a2e556d27f65098c97e33183a72902a72e0e83f76443ec515ae1212974a8db60be4baab87acbfb03aa8f80471d9e7730bd997d671b1c6f5cb74bdd9a40719c4b347187949788cbf32fe0fee925c61ea433c4a712dd01703795cbe1e3f3e7b62b88ab333cd559c84a1e62a141558d97be3295da15c31052bc41433b042b162005628c36441574860a2e41b947b04aa406b4dba04ed480eff7be81175b1a2c4cc6b05b8c3366078b389bd971ff26c110bae2b80116296dc700451c3bc6a80aa6c1f99a2f9de4b87a06c050117bfcb1aa0003627ddb5f9a254f64bd062d55e394dfb2b94e2a8d5d2572246a1959bf0b053a352a959231deb7852ad0023d5ef66d5776e35f4fb79f53d2c837eb7a8be73ab50d88f630f5b2f0f70075d8c40e3415a76f4ad0390bca7a919fb9f6879c9e59f6865e6fbdd2dc3e343a29c771301f1c973c5fb1249ee27593a8baf56201645cd90702724a927d0874629b9cd6369cab618ee81e9216dca098897b5f423376885b4cab10f5a852607dd6f49ab45eed5feeea50fecd05218939a93d0e8844fbaf60678afbc5b83a70a854e8652dccf23465654f625c2d1bd33124d20735f8c0439c664b583cbf6a145ed8860e909535c795caf58674f634f9c634a9ccb49465285c8b893e30ef2ebe15e9322921256521c94b47524c6f71231c241d82731d88557ad2dca5f32d8faa41b62947ff77e59f6fdc06da4058e20d0807b50bf71129e61f4c3c4aa8639abdd2643f8a50229f03f125e3422a7b94b6836e07d11b5db4cebef20993d049a2209894daa8202991d2282dd03567ebb60cbbcd409a90beed9d3ac4dea581b0e551d4f131711e4322afb7174d42582ba38023d24fbd9d151d46e674f63c5f7769b94322406d910549fbdc220f2d0544ebac71642ecd93c3e756753d3f3e36f68b8ead20bf6ede52aefc7d12efbdbcf8c49ef201c123ee80e71a4b8bce81b979e27dd133b5acb7e74f70e4e5360e669cbba85996a10c841381c1c0ffb31825fe190c05f35941ad628a590f60d8c3549bd5cb063257e7a72e098c78559a0d965b028a1cdb8b7930eb229002a3c15572f7370bda2e92003884e8260a566b41a74874d4af960350887c3a889d45fd09714ca69c80ba36047986ea614e99eb05a8a09e583e950b16983aedf3740b2531a4f82a089a68d4ad72e33c4dcdce83aa5f482c6684266640a3ae8795507bde83334231372426232c7d1c2ebd35ea11c32e438ee9e1e465b7e6e137dcd5644a64bdd7ac6a0ea3419647aea371dc4242339caf070bb4762285d8d3b183db527ea449fa8d333ab77b317a0ddc79a457eb84775e321940c645d8124ee276805010bcb90aac18995cc89ddda2ab10f8c3f62781fe5901cfee4302077f7da18d86a8c564cd2727db156fd3ceba7d14142d50592f360f0cfcee0cb70d8de7c19a07e848efa5fa66dd48fbe74be4cdbb88f3768d0faaf2146ea5dbff9e5180ffef9e5cb70f3e54b07ffdcc75f8ef197e106f529b4d87c197c19e2e2e7e6278c1f5c91983ef8f2057df982fb0fae805eec88f320599a093c3c85148f9339cb5f6453fe5ca2103b01b2d5520cafb53565255a6db2619b9a799fb97a3169fdd46de128dd6c4c30b32df697393bb44a7b357cd6f886975ddccc341e85212442d737a6a9b59a23fa1a0e5c7d2773be4f1caed87df87e5dd65fb52644b3126975c675ff7ac6bd962647a642119fd64b6e3cb75edd2df944f26983390adab2090e3cfe550fc7c532214cf1817ee2801c4760f61743a203353908b53d670231477163b88c63baff8cf272073dcffe7432e734861b3946943818936c5b7d9ff25bc43ae0b4b4d9e498a45bf34473f27d7cd771f71b0a5c7bd85aada8465f5b678671727c5c56fe3f06238c5a938b848abe7046b9fb6d2e403306bb5e0dea6d6d241a10352bf6ee39195c65b6b5549b792f927e62efc995cc6b8cdc5445c35c842d485bd17d20293dea3e08fbada3b0157ddf35f5f7ded568f57b8eed6d0dd3ea776739e3aedb0ea1b0632be51c7f9b3bd4278383ee92e8c8973f6e090c1dc892eaeb20363fdb7b1f74a2e9d2e9134d96f65323d5a15dd0955ad02945d238e0d86b7432a1cd6eafdd5eb98bea194d901cac8686e04fa81bbdea7466d3a4f538e58399a3b193cda6dd5e35e9b43f899a4d34add93a2088531c04199a91295ca815b6f83fa6003e74a779726c6f588ecfcca5ef995eba7d2b55d250f7f57d248ed80ffbaed4a8a5f52ac8c2c7890fff14113ff48ddcd8a97ec3c3b23e682238d47171914d57096f917badb368865b4c5c4692325766f18a44361c6f5c6421629b4debe9539666e97a91adc4b3672d92d06cb3c90b3e391de4438779fa9e1fb0f58a6db4da71bbd5f857ab9db45bff6adc32e3f9bbe4937816736061ffd56a8b76eb5f9d964ed6d02bc0bc9a899a4c0dc2583d3bedaf8e4ea31093093ded4d9eae7a93761b4f0793a3d3a197a57a52dc9c1b126330ee40cd56909824431be4678ab1c9e924bdd4e6cdae478e3c6fdf529d50d11c8fd4b8d5fec636ca4eb15fb41912d981a879e7717a5d24cb2ef987988d6742c4576939fb4ac162777b722789774fb6db56bb5eac8f2c34f9b9da8a147fe3b240538c94e410fa71900f3508b8acf45bc2a840290ab13eae5d38aeaae4f8f8187b1c8cf03100c457772bd1e7d1bd4bb6e3b95e278ee969a2721a105ccfd2bc60a90236f00e678d49c28468305162708ade5745efdcebee239ff19ca713db27e4bc9e33c8c43be63c6dd898c2824f1b470db15af21ce1520df57d3e756abda6dc6c7662adef61d5fa3c925b2d24d6c2c69ec3ec56d65c1a494c56c626b93ec793dbc03286ace72fa54b65b58795bc548bd0e077cb9c0b010911564236782ce73c6f8c3920d246967b1b41002bb4da8e9be97981f42cd0eb14f6a87c7d037a5ba7cb37288f9794b75d5f694b2a6adead428e4160af7804971f6cd7ef67fdda52589b4841ac51245389b780b7897f707418bd9a2c7bcc620733a357dab71fc2a14039c991753c59e6d952907bedb5af3039de12b94545172fb2c5324b792a71afc0f1282471e73696f38fd94af21ca329de4ffcb46fb2490d5097d0a97a614ef7fb931d7018fb766a7c9385ff2f8d9f1b3a03b59effffc752e3d31aa59db6b60a02fdb733cb72c268de2f1e2106e9c445906be1e834ec862724aeada5f69525a6d2a992b56b2acd7276e5f5f5186493dd6a7ac720b980a9f98424f55f854c9a3cd7d5ba0fc1bebcb6da4d3cb5d5c23332adad36c952c9efcce8ba2199d4d662629d4ebcc175bb64b6af3b13b1b25c7b5ebf36597ecbf2e928e73353f3982cea976725960a4c4cb513b23c586d94c4c2cce93824a3daba0bbec84c778fc8bab64ac2fe589b2aa7e4a6b6ca38c926d7e64b5d72553fcd553a650a062cb0741f93716dcd9c8b6596ba5deb3e2117f5f39c644bbb16677e18566d5050678d6148891f7de827fdb6676e60a5b9816591cdd869822a9af24964ee58e14fa6ff24fa8f884a77a80dee5278167d29eec37ed35df69a6b59f8b3d67f46facf6ab7af427d033562afa06030ae3d8ee71cecd4e96c2b3bcf15085f64534e2744a1730ba75034d345ea24bcc852a1681a042137651fcc59a22b223b868c504664e7b506e08f7c46e7ead19c759a11d939677fac21a8f9055f64744464e703e00b1aab9fe610d384c8ce259c7d1888508f0688e98248452fdcc06b449b6b9006cd34275b685099dbb52d2ccdaea62fd3cb74eb377053dfdf60a51bd875a9216c07c0d1070a4a29d37d79ebbaffbb7353d72efafe9a99ae093bb2bfd65ad782edda5f6ba46b99bddc5f2f36f5ec46efaf99e89a1e14ecaf2b4c5d0b22fb6b2e744d48d5f7aa886a54b73d3ba901fd8c747e29576ba9ffccf49f44ff11facf42ff59168c77fd96a3d29eaf379bd2f3a8f2bcaa3c4f2bcff3caf355e5795c79bea83cdf40a257cd73d2f3ed70887bffff000000ffffa12b42d1da9b0b00", - }) - if err != nil { - panic(err) - } - g.DefaultResolver = hgr - - func() { - b := packr.New("SPA_App", "./frontend/build") - b.SetResolver("7d6930a1c4a461e4da50.js", packr.Pointer{ForwardBox: gk, ForwardPath: "a9780b1e2b4178ca7cdd88af9e809c6b"}) - b.SetResolver("7d6930a1c4a461e4da50.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "344b8aa418988970b92426cfa9b6e2fd"}) - b.SetResolver("app.375413848a49980fe06d.js", packr.Pointer{ForwardBox: gk, ForwardPath: "bedbe88128a33813f7196383e1d80702"}) - b.SetResolver("app.375413848a49980fe06d.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "27369919a4954e44d1e4636e64316459"}) - b.SetResolver("index.html", packr.Pointer{ForwardBox: gk, ForwardPath: "0a565b7e0dc999e762aac08b16b48d84"}) - b.SetResolver("vendor.9453cfe969250230eab8.js", packr.Pointer{ForwardBox: gk, ForwardPath: "d12afb564af00fc492cd39248af5c289"}) - b.SetResolver("vendor.9453cfe969250230eab8.js.map", packr.Pointer{ForwardBox: gk, ForwardPath: "33b0d57119113a82bb8b4c59edcb6141"}) - }() - - func() { - b := packr.New("SPA_Assets", "./frontend/src/assets") - b.SetResolver("index.html", packr.Pointer{ForwardBox: gk, ForwardPath: "629fe427503e5cf1bfa49722d21395a0"}) - b.SetResolver("main.css", packr.Pointer{ForwardBox: gk, ForwardPath: "cb5bbc1beeeef73181bb7fdcb9f346dd"}) - }() - return nil -}() diff --git a/plugins/spa/parameters.go b/plugins/spa/parameters.go deleted file mode 100644 index a1149018f0af4973ebf43ed125cd5fa6c6efb1c1..0000000000000000000000000000000000000000 --- a/plugins/spa/parameters.go +++ /dev/null @@ -1,21 +0,0 @@ -package spa - -import ( - flag "github.com/spf13/pflag" -) - -const ( - CFG_BIND_ADDRESS = "dashboard.bindAddress" - CFG_DEV = "dashboard.dev" - CFG_BASIC_AUTH_ENABLED = "dashboard.basic_auth.enabled" - CFG_BASIC_AUTH_USERNAME = "dashboard.basic_auth.username" - CFG_BASIC_AUTH_PASSWORD = "dashboard.basic_auth.password" -) - -func init() { - flag.String(CFG_BIND_ADDRESS, "127.0.0.1", "the bind address of the dashboard") - flag.Bool(CFG_DEV, false, "whether the dashboard runs in dev mode") - flag.Bool(CFG_BASIC_AUTH_ENABLED, false, "whether to enable HTTP basic auth") - flag.String(CFG_BASIC_AUTH_USERNAME, "goshimmer", "HTTP basic auth username") - flag.String(CFG_BASIC_AUTH_PASSWORD, "goshimmer", "HTTP basic auth password") -} diff --git a/plugins/spa/plugin.go b/plugins/spa/plugin.go deleted file mode 100644 index 7141a88fa65e2b309918853721940ede45174d35..0000000000000000000000000000000000000000 --- a/plugins/spa/plugin.go +++ /dev/null @@ -1,222 +0,0 @@ -package spa - -import ( - "net/http" - "runtime" - "sync" - "time" - - "github.com/gorilla/websocket" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/autopeering" - "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/goshimmer/plugins/cli" - "github.com/iotaledger/goshimmer/plugins/gossip" - "github.com/iotaledger/goshimmer/plugins/metrics" - "github.com/iotaledger/hive.go/autopeering/peer/service" - "github.com/labstack/echo" - "github.com/labstack/echo/middleware" - - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/hive.go/workerpool" -) - -var ( - PLUGIN = node.NewPlugin("SPA", node.Enabled, configure, run) - log *logger.Logger - - nodeStartAt = time.Now() - - clientsMu sync.Mutex - clients = make(map[uint64]chan interface{}, 0) - nextClientID uint64 = 0 - - wsSendWorkerCount = 1 - wsSendWorkerQueueSize = 250 - wsSendWorkerPool *workerpool.WorkerPool -) - -func configure(plugin *node.Plugin) { - log = logger.NewLogger(plugin.Name) - - wsSendWorkerPool = workerpool.New(func(task workerpool.Task) { - sendToAllWSClient(&msg{MsgTypeTPSMetric, task.Param(0).(uint64)}) - sendToAllWSClient(&msg{MsgTypeNodeStatus, currentNodeStatus()}) - sendToAllWSClient(&msg{MsgTypeNeighborMetric, neighborMetrics()}) - task.Return(nil) - }, workerpool.WorkerCount(wsSendWorkerCount), workerpool.QueueSize(wsSendWorkerQueueSize)) - - configureLiveFeed() -} - -func run(plugin *node.Plugin) { - - notifyStatus := events.NewClosure(func(tps uint64) { - wsSendWorkerPool.TrySubmit(tps) - }) - - daemon.BackgroundWorker("SPA[WSSend]", func(shutdownSignal <-chan struct{}) { - metrics.Events.ReceivedTPSUpdated.Attach(notifyStatus) - wsSendWorkerPool.Start() - <-shutdownSignal - log.Info("Stopping SPA[WSSend] ...") - metrics.Events.ReceivedTPSUpdated.Detach(notifyStatus) - wsSendWorkerPool.Stop() - log.Info("Stopping SPA[WSSend] ... done") - }, shutdown.ShutdownPrioritySPA) - - runLiveFeed() - - // allow any origin for websocket connections - upgrader.CheckOrigin = func(r *http.Request) bool { - return true - } - - e := echo.New() - e.HideBanner = true - e.Use(middleware.Recover()) - - if parameter.NodeConfig.GetBool(CFG_BASIC_AUTH_ENABLED) { - e.Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) { - if username == parameter.NodeConfig.GetString(CFG_BASIC_AUTH_USERNAME) && - password == parameter.NodeConfig.GetString(CFG_BASIC_AUTH_PASSWORD) { - return true, nil - } - return false, nil - })) - } - - setupRoutes(e) - addr := parameter.NodeConfig.GetString(CFG_BIND_ADDRESS) - - log.Infof("You can now access the dashboard using: http://%s", addr) - go e.Start(addr) -} - -// sends the given message to all connected websocket clients -func sendToAllWSClient(msg interface{}) { - clientsMu.Lock() - defer clientsMu.Unlock() - for _, channel := range clients { - select { - case channel <- msg: - default: - // drop if buffer not drained - } - } -} - -var webSocketWriteTimeout = time.Duration(3) * time.Second - -var ( - upgrader = websocket.Upgrader{ - HandshakeTimeout: webSocketWriteTimeout, - EnableCompression: true, - } -) - -const ( - MsgTypeNodeStatus byte = iota - MsgTypeTPSMetric - MsgTypeTx - MsgTypeNeighborMetric -) - -type msg struct { - Type byte `json:"type"` - Data interface{} `json:"data"` -} - -type tx struct { - Hash string `json:"hash"` - Value int64 `json:"value"` -} - -type nodestatus struct { - ID string `json:"id"` - Version string `json:"version"` - Uptime int64 `json:"uptime"` - Mem *memmetrics `json:"mem"` -} - -type memmetrics struct { - Sys uint64 `json:"sys"` - HeapSys uint64 `json:"heap_sys"` - HeapInuse uint64 `json:"heap_inuse"` - HeapIdle uint64 `json:"heap_idle"` - HeapReleased uint64 `json:"heap_released"` - HeapObjects uint64 `json:"heap_objects"` - MSpanInuse uint64 `json:"m_span_inuse"` - MCacheInuse uint64 `json:"m_cache_inuse"` - StackSys uint64 `json:"stack_sys"` - NumGC uint32 `json:"num_gc"` - LastPauseGC uint64 `json:"last_pause_gc"` -} - -type neighbormetric struct { - ID string `json:"id"` - Address string `json:"address"` - ConnectionOrigin string `json:"connection_origin"` - BytesRead uint32 `json:"bytes_read"` - BytesWritten uint32 `json:"bytes_written"` -} - -func neighborMetrics() []neighbormetric { - stats := []neighbormetric{} - - // gossip plugin might be disabled - neighbors := gossip.GetAllNeighbors() - if neighbors == nil { - return stats - } - - for _, neighbor := range neighbors { - // unfortunately the neighbor manager doesn't keep track of the origin of the connection - origin := "Inbound" - for _, peer := range autopeering.Selection.GetOutgoingNeighbors() { - if neighbor.Peer == peer { - origin = "Outbound" - break - } - } - stats = append(stats, neighbormetric{ - ID: neighbor.Peer.ID().String(), - Address: neighbor.Peer.Services().Get(service.GossipKey).String(), - BytesRead: neighbor.BytesRead(), - BytesWritten: neighbor.BytesWritten(), - ConnectionOrigin: origin, - }) - } - return stats -} - -func currentNodeStatus() *nodestatus { - var m runtime.MemStats - runtime.ReadMemStats(&m) - status := &nodestatus{} - status.ID = local.GetInstance().ID().String() - - // node status - status.Version = cli.AppVersion - status.Uptime = time.Since(nodeStartAt).Milliseconds() - - // memory metrics - status.Mem = &memmetrics{ - Sys: m.Sys, - HeapSys: m.HeapSys, - HeapInuse: m.HeapInuse, - HeapIdle: m.HeapIdle, - HeapReleased: m.HeapReleased, - HeapObjects: m.HeapObjects, - MSpanInuse: m.MSpanInuse, - MCacheInuse: m.MCacheInuse, - StackSys: m.StackSys, - NumGC: m.NumGC, - LastPauseGC: m.PauseNs[(m.NumGC+255)%256], - } - return status -} diff --git a/plugins/sync/plugin.go b/plugins/sync/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..d29842dd74e5967daec7784f4638a434c27701a6 --- /dev/null +++ b/plugins/sync/plugin.go @@ -0,0 +1,367 @@ +package sync + +import ( + "errors" + "sync" + "time" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle" + gossipPkg "github.com/iotaledger/goshimmer/packages/gossip" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/gossip" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/events" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/iotaledger/hive.go/types" + flag "github.com/spf13/pflag" + "go.uber.org/atomic" +) + +const ( + // PluginName is the plugin name of the sync plugin. + PluginName = "Sync" + // CfgSyncAnchorPointsCount defines the amount of anchor points to use to determine + // whether a node is synchronized. + CfgSyncAnchorPointsCount = "sync.anchorPointsCount" + // CfgSyncAnchorPointsCleanupAfterSec defines the amount of time which is allowed to pass between setting an anchor + // point and it not becoming solid (to clean its slot for another anchor point). It basically defines the expectancy + // of how long it should take for an anchor point to become solid. Even if this value is set too low, usually a node + // would eventually solidify collected anchor points. + CfgSyncAnchorPointsCleanupAfterSec = "sync.anchorPointsCleanupAfterSec" + // CfgSyncAnchorPointsCleanupIntervalSec defines the interval at which it is checked whether anchor points fall + // into the cleanup window. + CfgSyncAnchorPointsCleanupIntervalSec = "sync.anchorPointsCleanupIntervalSec" + // CfgSyncDesyncedIfNoMessageAfterSec defines the time period in which new messages must be received and if not + // the node is marked as desynced. + CfgSyncDesyncedIfNoMessageAfterSec = "sync.desyncedIfNoMessagesAfterSec" + + // defines the max. divergence a potential new anchor point's issuance time can have + // from the current issuance threshold. say the current threshold is at 1000, the boundary at 10, + // we allow a new potential anchor point's issuance time to be within >=990 / 10 seconds older + // than the current threshold. + issuanceThresholdBeforeTimeBoundary = 20 * time.Second +) + +func init() { + flag.Int(CfgSyncAnchorPointsCount, 3, "the amount of anchor points to use to determine whether a node is synchronized") + flag.Int(CfgSyncDesyncedIfNoMessageAfterSec, 300, "the time period in seconds which sets the node as desynced if no new messages are received") + flag.Int(CfgSyncAnchorPointsCleanupIntervalSec, 10, "the interval at which it is checked whether anchor points fall into the cleanup window") + flag.Int(CfgSyncAnchorPointsCleanupAfterSec, 60, "the amount of time which is allowed to pass between setting an anchor point and it not becoming solid (to clean its slot for another anchor point)") +} + +var ( + // plugin is the plugin instance of the sync plugin. + plugin *node.Plugin + once sync.Once + // ErrNodeNotSynchronized is returned when an operation can't be executed because + // the node is not synchronized. + ErrNodeNotSynchronized = errors.New("node is not synchronized") + // tells whether the node is synced or not. + synced atomic.Bool + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} + +// Synced tells whether the node is in a state we consider synchronized, meaning +// it has the relevant past and present message data. +func Synced() bool { + return synced.Load() +} + +// OverwriteSyncedState overwrites the synced state with the given value. +func OverwriteSyncedState(syncedOverwrite bool) { + synced.Store(syncedOverwrite) +} + +func configure(_ *node.Plugin) { + log = logger.NewLogger(PluginName) +} + +func run(_ *node.Plugin) { + // per default the node starts in a desynced state + if !Synced() { + monitorForSynchronization() + return + } + + // however, another plugin might want to overwrite the synced state (i.e. the bootstrap plugin) + // in order to start issuing messages + monitorForDesynchronization() +} + +// marks the node as synced and spawns the background worker to monitor desynchronization. +func markSynced() { + synced.Store(true) + monitorForDesynchronization() +} + +// marks the node as desynced and spawns the background worker to monitor synchronization. +func markDesynced() { + synced.Store(false) + monitorForSynchronization() +} + +// starts a background worker and event handlers to check whether the node is desynchronized by checking +// whether the node has no more peers or didn't receive any message in a given time period. +func monitorForDesynchronization() { + log.Info("monitoring for desynchronization") + + // monitors the peer count of the manager and sets the node as desynced if it has no more peers. + noPeers := make(chan types.Empty) + monitorPeerCountClosure := events.NewClosure(func(_ *gossipPkg.Neighbor) { + anyPeers := len(gossip.Manager().AllNeighbors()) > 0 + if anyPeers { + return + } + noPeers <- types.Empty{} + }) + + msgReceived := make(chan types.Empty, 1) + + monitorMessageInflowClosure := events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + defer cachedMessage.Release() + defer cachedMessageMetadata.Release() + // ignore messages sent by the node itself + if local.GetInstance().LocalIdentity().PublicKey() == cachedMessage.Unwrap().IssuerPublicKey() { + return + } + select { + case msgReceived <- types.Empty{}: + default: + // via this default clause, a slow desync-monitor select-loop + // worker should not increase latency as it auto. falls through + } + }) + + if err := daemon.BackgroundWorker("Desync-Monitor", func(shutdownSignal <-chan struct{}) { + gossip.Manager().Events().NeighborRemoved.Attach(monitorPeerCountClosure) + defer gossip.Manager().Events().NeighborRemoved.Detach(monitorPeerCountClosure) + messagelayer.Tangle().Events.MessageAttached.Attach(monitorMessageInflowClosure) + defer messagelayer.Tangle().Events.MessageAttached.Detach(monitorMessageInflowClosure) + + timeForDesync := config.Node().GetDuration(CfgSyncDesyncedIfNoMessageAfterSec) * time.Second + timer := time.NewTimer(timeForDesync) + for { + select { + + case <-msgReceived: + // we received a message, therefore reset the timer to check for message receives + if !timer.Stop() { + <-timer.C + } + // TODO: perhaps find a better way instead of constantly resetting the timer + timer.Reset(timeForDesync) + + case <-timer.C: + log.Infof("no message received in %d seconds, marking node as desynced", int(timeForDesync.Seconds())) + markDesynced() + return + + case <-noPeers: + log.Info("all peers have been lost, marking node as desynced") + markDesynced() + return + + case <-shutdownSignal: + return + } + } + }, shutdown.PrioritySynchronization); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} + +// starts a background worker and event handlers to check whether the node is synchronized by first collecting +// a set of newly received messages and then waiting for them to become solid. +func monitorForSynchronization() { + wantedAnchorPointsCount := config.Node().GetInt(CfgSyncAnchorPointsCount) + anchorPoints := newAnchorPoints(wantedAnchorPointsCount) + log.Infof("monitoring for synchronization, awaiting %d anchor point messages to become solid", wantedAnchorPointsCount) + + synced := make(chan types.Empty) + + initAnchorPointClosure := events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + defer cachedMessage.Release() + defer cachedMessageMetadata.Release() + if addedAnchorID := initAnchorPoint(anchorPoints, cachedMessage.Unwrap()); addedAnchorID != nil { + anchorPoints.Lock() + defer anchorPoints.Unlock() + log.Infof("added message %s as anchor point (%d of %d collected)", addedAnchorID.String()[:10], anchorPoints.collectedCount(), anchorPoints.wanted) + } + }) + + checkAnchorPointSolidityClosure := events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) { + defer cachedMessage.Release() + defer cachedMessageMetadata.Release() + allSolid, newSolidAnchorID := checkAnchorPointSolidity(anchorPoints, cachedMessage.Unwrap()) + + if newSolidAnchorID != nil { + log.Infof("anchor message %s has become solid", newSolidAnchorID.String()[:10]) + } + + if !allSolid { + return + } + synced <- types.Empty{} + }) + + if err := daemon.BackgroundWorker("Sync-Monitor", func(shutdownSignal <-chan struct{}) { + messagelayer.Tangle().Events.MessageAttached.Attach(initAnchorPointClosure) + defer messagelayer.Tangle().Events.MessageAttached.Detach(initAnchorPointClosure) + messagelayer.Tangle().Events.MessageSolid.Attach(checkAnchorPointSolidityClosure) + defer messagelayer.Tangle().Events.MessageSolid.Detach(checkAnchorPointSolidityClosure) + + cleanupDelta := config.Node().GetDuration(CfgSyncAnchorPointsCleanupAfterSec) * time.Second + ticker := time.NewTicker(config.Node().GetDuration(CfgSyncAnchorPointsCleanupIntervalSec) * time.Second) + defer ticker.Stop() + for { + select { + case <-ticker.C: + anchorPoints.Lock() + for id, itGotAdded := range anchorPoints.ids { + if time.Since(itGotAdded) > cleanupDelta { + log.Infof("freeing anchor point slot of %s as it didn't become solid within %v", id.String()[:10], cleanupDelta) + delete(anchorPoints.ids, id) + } + } + anchorPoints.Unlock() + case <-shutdownSignal: + return + case <-synced: + log.Infof("all anchor messages have become solid, marking node as synced") + markSynced() + return + } + } + }, shutdown.PrioritySynchronization); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} + +// fills up the anchor points with newly attached messages which then are used to determine whether we are synchronized. +func initAnchorPoint(anchorPoints *anchorpoints, msg *message.Message) *message.Id { + if synced.Load() { + return nil + } + + anchorPoints.Lock() + defer anchorPoints.Unlock() + + // we don't need to add additional anchor points if the set was already filled once + if anchorPoints.wasFilled() { + return nil + } + + // as a rule, we don't consider messages attaching directly to genesis anchors + if msg.TrunkId() == message.EmptyId || msg.BranchId() == message.EmptyId { + return nil + } + + // add a new anchor point if its issuance time is newer than any other anchor point + id := msg.Id() + if !anchorPoints.add(id, msg.IssuingTime()) { + return nil + } + return &id +} + +// checks whether an anchor point message became solid. +// if all anchor points became solid, it sets the node's state to synchronized. +func checkAnchorPointSolidity(anchorPoints *anchorpoints, msg *message.Message) (bool, *message.Id) { + anchorPoints.Lock() + defer anchorPoints.Unlock() + + if synced.Load() || len(anchorPoints.ids) == 0 { + return false, nil + } + + // check whether an anchor message become solid + msgID := msg.Id() + if !anchorPoints.has(msgID) { + return false, nil + } + + // an anchor became solid + anchorPoints.markAsSolidified(msgID) + + if !anchorPoints.wereAllSolidified() { + return false, &msgID + } + + // all anchor points have become solid + return true, &msgID +} + +func newAnchorPoints(wantedAnchorPointsCount int) *anchorpoints { + return &anchorpoints{ + ids: make(map[message.Id]time.Time), + wanted: wantedAnchorPointsCount, + } +} + +// anchorpoints are a set of messages which we use to determine whether the node has become synchronized. +type anchorpoints struct { + sync.Mutex + // the ids of the anchor points with their addition time. + ids map[message.Id]time.Time + // the wanted amount of anchor points which should become solid. + wanted int + // how many anchor points have been solidified. + solidified int + // holds the highest issuance time of any message which was an anchor point. + // this is used to determine whether further attached messages should become an + // anchor point by matching their issuance time against this time. + issuanceTimeThreshold time.Time +} + +// adds the given message to the anchor points set if its issuance time is newer than +// any other existing anchor point's. +func (ap *anchorpoints) add(id message.Id, issuanceTime time.Time) bool { + if !ap.issuanceTimeThreshold.IsZero() && + ap.issuanceTimeThreshold.Add(-issuanceThresholdBeforeTimeBoundary).After(issuanceTime) { + return false + } + ap.ids[id] = time.Now() + ap.issuanceTimeThreshold = issuanceTime + return true +} + +func (ap *anchorpoints) has(id message.Id) bool { + _, has := ap.ids[id] + return has +} + +// marks the given anchor point as solidified which removes it from the set and bumps the solidified count. +func (ap *anchorpoints) markAsSolidified(id message.Id) { + delete(ap.ids, id) + ap.solidified++ +} + +// tells whether the anchor points set was filled at some point. +func (ap *anchorpoints) wasFilled() bool { + return ap.collectedCount() == ap.wanted +} + +// tells whether all anchor points have become solid. +func (ap *anchorpoints) wereAllSolidified() bool { + return ap.solidified == ap.wanted +} + +// tells the number of effectively collected anchor points. +func (ap *anchorpoints) collectedCount() int { + // since an anchor point potentially was solidified before the set became full, + // we need to incorporate that count too + return ap.solidified + len(ap.ids) +} diff --git a/plugins/tangle/approvers.go b/plugins/tangle/approvers.go deleted file mode 100644 index 3e50c29caec97397832490d911ca3989ebe3be6b..0000000000000000000000000000000000000000 --- a/plugins/tangle/approvers.go +++ /dev/null @@ -1,128 +0,0 @@ -package tangle - -import ( - "fmt" - - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/model/approvers" - "github.com/iotaledger/hive.go/lru_cache" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -// region global public api //////////////////////////////////////////////////////////////////////////////////////////// - -// GetApprovers retrieves approvers from the database. -func GetApprovers(transactionHash trinary.Trytes, computeIfAbsent ...func(trinary.Trytes) *approvers.Approvers) (result *approvers.Approvers, err error) { - if cacheResult := approversCache.ComputeIfAbsent(transactionHash, func() interface{} { - if dbApprovers, dbErr := getApproversFromDatabase(transactionHash); dbErr != nil { - err = dbErr - - return nil - } else if dbApprovers != nil { - return dbApprovers - } else { - if len(computeIfAbsent) >= 1 { - return computeIfAbsent[0](transactionHash) - } - - return nil - } - }); cacheResult != nil && cacheResult.(*approvers.Approvers) != nil { - result = cacheResult.(*approvers.Approvers) - } - - return -} - -func ContainsApprovers(transactionHash trinary.Trytes) (result bool, err error) { - if approversCache.Contains(transactionHash) { - result = true - } else { - result, err = databaseContainsApprovers(transactionHash) - } - - return -} - -func StoreApprovers(approvers *approvers.Approvers) { - approversCache.Set(approvers.GetHash(), approvers) -} - -// region lru cache //////////////////////////////////////////////////////////////////////////////////////////////////// - -var approversCache = lru_cache.NewLRUCache(APPROVERS_CACHE_SIZE, &lru_cache.LRUCacheOptions{ - EvictionCallback: onEvictApprovers, - EvictionBatchSize: 100, -}) - -func onEvictApprovers(_ interface{}, values interface{}) { - // TODO: replace with apply - for _, obj := range values.([]interface{}) { - if approvers := obj.(*approvers.Approvers); approvers.GetModified() { - if err := storeApproversInDatabase(approvers); err != nil { - panic(err) - } - } - } -} - -func FlushApproversCache() { - approversCache.DeleteAll() -} - -const ( - APPROVERS_CACHE_SIZE = 50000 -) - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region database ///////////////////////////////////////////////////////////////////////////////////////////////////// - -var approversDatabase database.Database - -func configureApproversDatabase() { - if db, err := database.Get(database.DBPrefixApprovers, database.GetBadgerInstance()); err != nil { - panic(err) - } else { - approversDatabase = db - } -} - -func storeApproversInDatabase(approvers *approvers.Approvers) error { - if approvers.GetModified() { - if err := approversDatabase.Set(database.Entry{Key: typeutils.StringToBytes(approvers.GetHash()), Value: approvers.Marshal()}); err != nil { - return fmt.Errorf("%w: failed to store approvers: %s", ErrDatabaseError, err) - } - approvers.SetModified(false) - } - - return nil -} - -func getApproversFromDatabase(transactionHash trinary.Trytes) (*approvers.Approvers, error) { - approversData, err := approversDatabase.Get(typeutils.StringToBytes(transactionHash)) - if err != nil { - if err == database.ErrKeyNotFound { - return nil, nil - } - return nil, fmt.Errorf("%w: failed to retrieve approvers: %s", ErrDatabaseError, err) - } - - var result approvers.Approvers - if err = result.Unmarshal(approversData.Value); err != nil { - panic(err) - } - - return &result, nil -} - -func databaseContainsApprovers(transactionHash trinary.Trytes) (bool, error) { - if contains, err := approversDatabase.Contains(typeutils.StringToBytes(transactionHash)); err != nil { - return false, fmt.Errorf("%w: failed to check if the approvers exist: %s", ErrDatabaseError, err) - } else { - return contains, nil - } -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/tangle/bundle.go b/plugins/tangle/bundle.go deleted file mode 100644 index 2cb1fb896ae5cd5a8d6152a0e2398ef4651f4a87..0000000000000000000000000000000000000000 --- a/plugins/tangle/bundle.go +++ /dev/null @@ -1,133 +0,0 @@ -package tangle - -import ( - "fmt" - - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/model/bundle" - "github.com/iotaledger/hive.go/lru_cache" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -// region global public api //////////////////////////////////////////////////////////////////////////////////////////// - -// GetBundle retrieves bundle from the database. -func GetBundle(headerTransactionHash trinary.Trytes, computeIfAbsent ...func(trinary.Trytes) (*bundle.Bundle, error)) (result *bundle.Bundle, err error) { - if cacheResult := bundleCache.ComputeIfAbsent(headerTransactionHash, func() interface{} { - if dbBundle, dbErr := getBundleFromDatabase(headerTransactionHash); dbErr != nil { - err = dbErr - - return nil - } else if dbBundle != nil { - return dbBundle - } else { - if len(computeIfAbsent) >= 1 { - if computedBundle, computedErr := computeIfAbsent[0](headerTransactionHash); computedErr != nil { - err = computedErr - } else { - return computedBundle - } - } - - return nil - } - }); cacheResult != nil && cacheResult.(*bundle.Bundle) != nil { - result = cacheResult.(*bundle.Bundle) - } - - return -} - -func ContainsBundle(headerTransactionHash trinary.Trytes) (result bool, err error) { - if bundleCache.Contains(headerTransactionHash) { - result = true - } else { - result, err = databaseContainsBundle(headerTransactionHash) - } - - return -} - -func StoreBundle(bundle *bundle.Bundle) { - bundleCache.Set(bundle.GetHash(), bundle) -} - -// region lru cache //////////////////////////////////////////////////////////////////////////////////////////////////// - -var bundleCache = lru_cache.NewLRUCache(BUNDLE_CACHE_SIZE, &lru_cache.LRUCacheOptions{ - EvictionCallback: onEvictBundles, - EvictionBatchSize: 100, -}) - -func onEvictBundles(_ interface{}, values interface{}) { - // TODO: replace with apply - for _, obj := range values.([]interface{}) { - if bndl := obj.(*bundle.Bundle); bndl.GetModified() { - if err := storeBundleInDatabase(bndl); err != nil { - panic(err) - } - } - } -} - -func FlushBundleCache() { - bundleCache.DeleteAll() -} - -const ( - BUNDLE_CACHE_SIZE = 500 -) - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region database ///////////////////////////////////////////////////////////////////////////////////////////////////// - -var bundleDatabase database.Database - -func configureBundleDatabase() { - if db, err := database.Get(database.DBPrefixBundle, database.GetBadgerInstance()); err != nil { - panic(err) - } else { - bundleDatabase = db - } -} - -func storeBundleInDatabase(bundle *bundle.Bundle) error { - if bundle.GetModified() { - if err := bundleDatabase.Set(database.Entry{Key: typeutils.StringToBytes(bundle.GetHash()), Value: bundle.Marshal()}); err != nil { - return fmt.Errorf("%w: failed to store bundle: %s", ErrDatabaseError, err) - } - bundle.SetModified(false) - } - - return nil -} - -func getBundleFromDatabase(transactionHash trinary.Trytes) (*bundle.Bundle, error) { - bundleData, err := bundleDatabase.Get(typeutils.StringToBytes(transactionHash)) - if err != nil { - if err == database.ErrKeyNotFound { - return nil, nil - } - - return nil, fmt.Errorf("%w: failed to retrieve bundle: %s", ErrDatabaseError, err) - } - - var result bundle.Bundle - if err = result.Unmarshal(bundleData.Value); err != nil { - panic(err) - } - - return &result, nil -} - -func databaseContainsBundle(transactionHash trinary.Trytes) (bool, error) { - if contains, err := bundleDatabase.Contains(typeutils.StringToBytes(transactionHash)); err != nil { - return false, fmt.Errorf("%w: failed to check if the bundle exists: %s", ErrDatabaseError, err) - } else { - return contains, nil - } -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/tangle/errors.go b/plugins/tangle/errors.go deleted file mode 100644 index 5ca8797f9ff4f5d0c08e7a744988108b6605b1d7..0000000000000000000000000000000000000000 --- a/plugins/tangle/errors.go +++ /dev/null @@ -1,7 +0,0 @@ -package tangle - -import "errors" - -var ( - ErrDatabaseError = errors.New("database error") -) diff --git a/plugins/tangle/events.go b/plugins/tangle/events.go deleted file mode 100644 index 2a89c7248afbdb38762b0a2beb44fa27afb72f88..0000000000000000000000000000000000000000 --- a/plugins/tangle/events.go +++ /dev/null @@ -1,18 +0,0 @@ -package tangle - -import ( - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/hive.go/events" -) - -var Events = struct { - TransactionStored *events.Event - TransactionSolid *events.Event -}{ - TransactionStored: events.NewEvent(transactionCaller), - TransactionSolid: events.NewEvent(transactionCaller), -} - -func transactionCaller(handler interface{}, params ...interface{}) { - handler.(func(*value_transaction.ValueTransaction))(params[0].(*value_transaction.ValueTransaction)) -} diff --git a/plugins/tangle/misc.go b/plugins/tangle/misc.go deleted file mode 100644 index 490f52d74aa145b2498f2afa7b65da5ba2fc6f03..0000000000000000000000000000000000000000 --- a/plugins/tangle/misc.go +++ /dev/null @@ -1,16 +0,0 @@ -package tangle - -import ( - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -func databaseKeyForHashPrefixedHash(address trinary.Hash, transactionHash trinary.Hash) []byte { - //return append(databaseKeyForHashPrefix(address), trinary.MustTrytesToBytes(transactionHash)...) - return append(databaseKeyForHashPrefix(address), typeutils.StringToBytes(transactionHash)...) -} - -func databaseKeyForHashPrefix(hash trinary.Hash) []byte { - //return trinary.MustTrytesToBytes(hash) - return typeutils.StringToBytes(hash) -} diff --git a/plugins/tangle/plugin.go b/plugins/tangle/plugin.go deleted file mode 100644 index 6c6bc09015f462d137784c7c9c5fad2a26c59929..0000000000000000000000000000000000000000 --- a/plugins/tangle/plugin.go +++ /dev/null @@ -1,67 +0,0 @@ -package tangle - -import ( - "time" - - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/hive.go/timeutil" - "github.com/iotaledger/iota.go/trinary" -) - -// region plugin module setup ////////////////////////////////////////////////////////////////////////////////////////// - -var PLUGIN = node.NewPlugin("Tangle", node.Enabled, configure, run) -var log *logger.Logger - -func configure(*node.Plugin) { - log = logger.NewLogger("Tangle") - - configureTransactionDatabase() - configureTransactionMetaDataDatabase() - configureApproversDatabase() - configureBundleDatabase() - configureTransactionHashesForAddressDatabase() - configureSolidifier() - - daemon.BackgroundWorker("Cache Flush", func(shutdownSignal <-chan struct{}) { - <-shutdownSignal - - log.Info("Flushing caches to database...") - FlushTransactionCache() - FlushTransactionMetadata() - FlushApproversCache() - FlushBundleCache() - log.Info("Flushing caches to database... done") - - log.Info("Syncing database to disk...") - database.GetBadgerInstance().Close() - log.Info("Syncing database to disk... done") - }, shutdown.ShutdownPriorityTangle) - -} - -func run(*node.Plugin) { - - daemon.BackgroundWorker("Badger garbage collection", func(shutdownSignal <-chan struct{}) { - timeutil.Ticker(func() { - database.CleanupBadgerInstance(log) - }, 5*time.Minute, shutdownSignal) - }, shutdown.ShutdownPriorityBadgerGarbageCollection) - - runSolidifier() -} - -// Requester provides the functionality to request a transaction from the network. -type Requester interface { - RequestTransaction(hash trinary.Hash) -} - -type RequesterFunc func(hash trinary.Hash) - -func (f RequesterFunc) RequestTransaction(hash trinary.Hash) { f(hash) } - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/tangle/solidifier.go b/plugins/tangle/solidifier.go deleted file mode 100644 index 0c274c491c13bf1a94384d9b51922894b0d59555..0000000000000000000000000000000000000000 --- a/plugins/tangle/solidifier.go +++ /dev/null @@ -1,269 +0,0 @@ -package tangle - -import ( - "runtime" - "time" - - "github.com/iotaledger/goshimmer/packages/gossip" - "github.com/iotaledger/goshimmer/packages/model/approvers" - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/goshimmer/packages/model/transactionmetadata" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/workerpool" - "github.com/iotaledger/iota.go/trinary" -) - -// region plugin module setup ////////////////////////////////////////////////////////////////////////////////////////// - -const UnsolidInterval = time.Minute - -var ( - workerCount = runtime.NumCPU() - workerPool *workerpool.WorkerPool - requestedTxs *UnsolidTxs - - requester Requester -) - -func SetRequester(req Requester) { - requester = req -} - -func configureSolidifier() { - workerPool = workerpool.New(func(task workerpool.Task) { - processMetaTransaction(task.Param(0).(*meta_transaction.MetaTransaction)) - - task.Return(nil) - }, workerpool.WorkerCount(workerCount), workerpool.QueueSize(10000)) - - requestedTxs = NewUnsolidTxs() - - gossip.Events.TransactionReceived.Attach(events.NewClosure(func(ev *gossip.TransactionReceivedEvent) { - metaTx, err := meta_transaction.FromBytes(ev.Data) - if err != nil { - log.Warnf("invalid transaction: %s", err) - return - } - if err = metaTx.Validate(); err != nil { - log.Warnf("invalid transaction: %s", err) - return - } - workerPool.Submit(metaTx) - })) -} - -func runSolidifier() { - daemon.BackgroundWorker("Tangle Solidifier", func(shutdownSignal <-chan struct{}) { - log.Info("Starting Solidifier ...") - workerPool.Start() - log.Info("Starting Solidifier ... done") - - <-shutdownSignal - - log.Info("Stopping Solidifier ...") - workerPool.StopAndWait() - log.Info("Stopping Solidifier ... done") - }, shutdown.ShutdownPrioritySolidifier) - -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -func processMetaTransaction(metaTransaction *meta_transaction.MetaTransaction) { - metaTransactionHash := metaTransaction.GetHash() - - var newTransaction bool - tx, err := GetTransaction(metaTransactionHash, func(transactionHash trinary.Trytes) *value_transaction.ValueTransaction { - newTransaction = true - - tx := value_transaction.FromMetaTransaction(metaTransaction) - tx.SetModified(true) - return tx - }) - if err != nil { - log.Errorf("Unable to process transaction %s: %s", metaTransactionHash, err.Error()) - return - } - if newTransaction { - log.Debugw("process new transaction", "hash", tx.GetHash()) - processNewTransaction(tx) - requestedTxs.Remove(tx.GetHash()) - updateRequestedTxs() - } -} - -func processNewTransaction(transaction *value_transaction.ValueTransaction) { - Events.TransactionStored.Trigger(transaction) - - // store transaction hash for address in DB - if err := StoreTransactionHashForAddressInDatabase( - &TxHashForAddress{ - Address: transaction.GetAddress(), - TxHash: transaction.GetHash(), - }, - ); err != nil { - log.Errorw(err.Error()) - } - - transactionHash := transaction.GetHash() - - // register tx as approver for trunk - if trunkApprovers, err := GetApprovers(transaction.GetTrunkTransactionHash(), approvers.New); err != nil { - log.Errorf("Unable to get approvers of transaction %s: %s", transaction.GetTrunkTransactionHash(), err.Error()) - return - } else { - trunkApprovers.Add(transactionHash) - } - - // register tx as approver for branch - if branchApprovers, err := GetApprovers(transaction.GetBranchTransactionHash(), approvers.New); err != nil { - log.Errorf("Unable to get approvers of transaction %s: %s", transaction.GetBranchTransactionHash(), err.Error()) - return - } else { - branchApprovers.Add(transactionHash) - } - - isSolid, err := isSolid(transactionHash) - if err != nil { - log.Errorf("Unable to check solidity: %s", err.Error()) - } - // if the transaction was solidified propagate this information - if isSolid { - if err := propagateSolidity(transaction.GetHash()); err != nil { - log.Errorf("Unable to propagate solidity: %s", err.Error()) - } - } -} - -// isSolid checks whether the transaction with the given hash is solid. A transaction is solid, if it is -// either marked as solid or all its referenced transactions are in the database. -func isSolid(hash trinary.Hash) (bool, error) { - // the genesis is always solid - if hash == meta_transaction.BRANCH_NULL_HASH { - return true, nil - } - // if the transaction is not in the DB, request it - transaction, err := GetTransaction(hash) - if err != nil { - return false, err - } - if transaction == nil { - if requestedTxs.Add(hash) { - requestTransaction(hash) - } - return false, nil - } - - // check whether the transaction is marked solid - metadata, err := GetTransactionMetadata(hash, transactionmetadata.New) - if err != nil { - return false, err - } - if metadata.GetSolid() { - return true, nil - } - - branch := contains(transaction.GetBranchTransactionHash()) - trunk := contains(transaction.GetTrunkTransactionHash()) - - if !branch || !trunk { - return false, nil - } - // everything is good, mark the transaction as solid - return true, markSolid(transaction) -} - -func contains(hash trinary.Hash) bool { - if hash == meta_transaction.BRANCH_NULL_HASH { - return true - } - if contains, _ := ContainsTransaction(hash); !contains { - if requestedTxs.Add(hash) { - requestTransaction(hash) - } - return false - } - return true -} - -func isMarkedSolid(hash trinary.Hash) (bool, error) { - if hash == meta_transaction.BRANCH_NULL_HASH { - return true, nil - } - metadata, err := GetTransactionMetadata(hash, transactionmetadata.New) - if err != nil { - return false, err - } - return metadata.GetSolid(), nil -} - -func markSolid(transaction *value_transaction.ValueTransaction) error { - txMetadata, err := GetTransactionMetadata(transaction.GetHash(), transactionmetadata.New) - if err != nil { - return err - } - if txMetadata.SetSolid(true) { - log.Debugw("transaction solidified", "hash", transaction.GetHash()) - Events.TransactionSolid.Trigger(transaction) - return propagateSolidity(transaction.GetHash()) - } - return nil -} - -func propagateSolidity(transactionHash trinary.Trytes) error { - approvingTransactions, err := GetApprovers(transactionHash, approvers.New) - if err != nil { - return err - } - for _, hash := range approvingTransactions.GetHashes() { - approver, err := GetTransaction(hash) - if err != nil { - return err - } - if approver != nil { - branchSolid, err := isMarkedSolid(approver.GetBranchTransactionHash()) - if err != nil { - return err - } - if !branchSolid { - continue - } - trunkSolid, err := isMarkedSolid(approver.GetTrunkTransactionHash()) - if err != nil { - return err - } - if !trunkSolid { - continue - } - - if err := markSolid(approver); err != nil { - return err - } - } - } - return nil -} - -func updateRequestedTxs() { - targetTime := time.Now().Add(-UnsolidInterval) - txs := requestedTxs.Update(targetTime) - for _, txHash := range txs { - if contains, _ := ContainsTransaction(txHash); contains { - requestedTxs.Remove(txHash) - continue - } - requestTransaction(txHash) - } -} - -func requestTransaction(hash trinary.Trytes) { - if requester == nil { - return - } - - log.Debugw("Requesting tx", "hash", hash) - requester.RequestTransaction(hash) -} diff --git a/plugins/tangle/solidifier_test.go b/plugins/tangle/solidifier_test.go deleted file mode 100644 index 9cd09962987473549f83edbc520c86e1bc62b653..0000000000000000000000000000000000000000 --- a/plugins/tangle/solidifier_test.go +++ /dev/null @@ -1,144 +0,0 @@ -package tangle - -import ( - "io/ioutil" - stdlog "log" - "os" - "sync/atomic" - "testing" - "time" - - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/gossip" - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/trinary" - "github.com/stretchr/testify/require" -) - -// use much lower min weight magnitude for the tests -const testMWM = 8 - -func init() { - if err := parameter.LoadDefaultConfig(false); err != nil { - stdlog.Fatalf("Failed to initialize config: %s", err) - } - if err := logger.InitGlobalLogger(parameter.NodeConfig); err != nil { - stdlog.Fatalf("Failed to initialize config: %s", err) - } -} - -func TestTangle(t *testing.T) { - dir, err := ioutil.TempDir("", t.Name()) - require.NoError(t, err) - defer os.Remove(dir) - // use the tempdir for the database - parameter.NodeConfig.Set(database.CFG_DIRECTORY, dir) - - // start a test node - node.Start(node.Plugins(PLUGIN)) - defer node.Shutdown() - - t.Run("ReadTransactionHashesForAddressFromDatabase", func(t *testing.T) { - tx1 := value_transaction.New() - tx1.SetAddress("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") - tx1.SetTimestamp(uint(time.Now().UnixNano())) - require.NoError(t, tx1.DoProofOfWork(testMWM)) - - tx2 := value_transaction.New() - tx2.SetTimestamp(uint(time.Now().UnixNano())) - require.NoError(t, tx2.DoProofOfWork(testMWM)) - - transactionReceived(&gossip.TransactionReceivedEvent{Data: tx1.GetBytes()}) - - txAddr, err := ReadTransactionHashesForAddressFromDatabase(tx1.GetAddress()) - require.NoError(t, err) - require.ElementsMatch(t, []trinary.Hash{tx1.GetHash()}, txAddr) - }) - - t.Run("ProofOfWork", func(t *testing.T) { - tx1 := value_transaction.New() - tx1.SetTimestamp(uint(time.Now().UnixNano())) - require.NoError(t, tx1.DoProofOfWork(1)) - - tx2 := value_transaction.New() - tx2.SetTimestamp(uint(time.Now().UnixNano())) - require.NoError(t, tx2.DoProofOfWork(testMWM)) - - var counter int32 - closure := events.NewClosure(func(transaction *value_transaction.ValueTransaction) { - atomic.AddInt32(&counter, 1) - }) - Events.TransactionSolid.Attach(closure) - defer Events.TransactionSolid.Detach(closure) - - transactionReceived(&gossip.TransactionReceivedEvent{Data: tx1.GetBytes()}) - transactionReceived(&gossip.TransactionReceivedEvent{Data: tx2.GetBytes()}) - - time.Sleep(100 * time.Millisecond) - require.EqualValues(t, 1, counter) - }) - - t.Run("Solidifier", func(t *testing.T) { - transaction1 := value_transaction.New() - transaction1.SetTimestamp(uint(time.Now().UnixNano())) - require.NoError(t, transaction1.DoProofOfWork(testMWM)) - - transaction2 := value_transaction.New() - transaction2.SetTimestamp(uint(time.Now().UnixNano())) - transaction2.SetBranchTransactionHash(transaction1.GetHash()) - require.NoError(t, transaction2.DoProofOfWork(testMWM)) - - transaction3 := value_transaction.New() - transaction3.SetTimestamp(uint(time.Now().UnixNano())) - transaction3.SetBranchTransactionHash(transaction2.GetHash()) - require.NoError(t, transaction3.DoProofOfWork(testMWM)) - - transaction4 := value_transaction.New() - transaction4.SetTimestamp(uint(time.Now().UnixNano())) - transaction4.SetBranchTransactionHash(transaction3.GetHash()) - require.NoError(t, transaction4.DoProofOfWork(testMWM)) - - var counter int32 - closure := events.NewClosure(func(tx *value_transaction.ValueTransaction) { - atomic.AddInt32(&counter, 1) - log.Infof("Transaction solid: hash=%s", tx.GetHash()) - }) - Events.TransactionSolid.Attach(closure) - defer Events.TransactionSolid.Detach(closure) - - // only transaction3 should be requested - SetRequester(RequesterFunc(func(hash trinary.Hash) { - if transaction3.GetHash() == hash { - // return the transaction data - transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction3.GetBytes()}) - } - })) - - transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction1.GetBytes()}) - transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction2.GetBytes()}) - // transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction3.GetBytes()}) - transactionReceived(&gossip.TransactionReceivedEvent{Data: transaction4.GetBytes()}) - - time.Sleep(100 * time.Millisecond) - require.EqualValues(t, 4, counter) - }) -} - -// transactionReceived mocks the TransactionReceived event by allowing lower mwm -func transactionReceived(ev *gossip.TransactionReceivedEvent) { - metaTx, err := meta_transaction.FromBytes(ev.Data) - if err != nil { - log.Warnf("invalid transaction: %s", err) - return - } - if metaTx.GetWeightMagnitude() < testMWM { - log.Warnf("invalid weight magnitude: %d / %d", metaTx.GetWeightMagnitude(), testMWM) - return - } - processMetaTransaction(metaTx) -} diff --git a/plugins/tangle/transaction.go b/plugins/tangle/transaction.go deleted file mode 100644 index bff7b6b726d8bda3b4f3fdc4278f0a3bbe80a254..0000000000000000000000000000000000000000 --- a/plugins/tangle/transaction.go +++ /dev/null @@ -1,124 +0,0 @@ -package tangle - -import ( - "fmt" - - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/hive.go/lru_cache" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -// region public api /////////////////////////////////////////////////////////////////////////////////////////////////// - -func GetTransaction(transactionHash trinary.Trytes, computeIfAbsent ...func(trinary.Trytes) *value_transaction.ValueTransaction) (result *value_transaction.ValueTransaction, err error) { - if cacheResult := transactionCache.ComputeIfAbsent(transactionHash, func() interface{} { - if transaction, dbErr := getTransactionFromDatabase(transactionHash); dbErr != nil { - err = dbErr - - return nil - } else if transaction != nil { - return transaction - } else { - if len(computeIfAbsent) >= 1 { - return computeIfAbsent[0](transactionHash) - } - - return nil - } - }); !typeutils.IsInterfaceNil(cacheResult) { - result = cacheResult.(*value_transaction.ValueTransaction) - } - - return -} - -func ContainsTransaction(transactionHash trinary.Trytes) (result bool, err error) { - if transactionCache.Contains(transactionHash) { - result = true - } else { - result, err = databaseContainsTransaction(transactionHash) - } - - return -} - -func StoreTransaction(transaction *value_transaction.ValueTransaction) { - transactionCache.Set(transaction.GetHash(), transaction) -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region lru cache //////////////////////////////////////////////////////////////////////////////////////////////////// - -var transactionCache = lru_cache.NewLRUCache(TRANSACTION_CACHE_SIZE, &lru_cache.LRUCacheOptions{ - EvictionCallback: onEvictTransactions, - EvictionBatchSize: 200, -}) - -func onEvictTransactions(_ interface{}, values interface{}) { - // TODO: replace with apply - for _, obj := range values.([]interface{}) { - if tx := obj.(*value_transaction.ValueTransaction); tx.GetModified() { - if err := storeTransactionInDatabase(tx); err != nil { - panic(err) - } - } - } -} - -func FlushTransactionCache() { - transactionCache.DeleteAll() -} - -const ( - TRANSACTION_CACHE_SIZE = 500 -) - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region database ///////////////////////////////////////////////////////////////////////////////////////////////////// - -var transactionDatabase database.Database - -func configureTransactionDatabase() { - if db, err := database.Get(database.DBPrefixTransaction, database.GetBadgerInstance()); err != nil { - panic(err) - } else { - transactionDatabase = db - } -} - -func storeTransactionInDatabase(transaction *value_transaction.ValueTransaction) error { - if transaction.GetModified() { - if err := transactionDatabase.Set(database.Entry{Key: typeutils.StringToBytes(transaction.GetHash()), Value: transaction.MetaTransaction.GetBytes()}); err != nil { - return fmt.Errorf("%w: failed to store transaction: %s", ErrDatabaseError, err.Error()) - } - transaction.SetModified(false) - } - - return nil -} - -func getTransactionFromDatabase(transactionHash trinary.Trytes) (*value_transaction.ValueTransaction, error) { - txData, err := transactionDatabase.Get(typeutils.StringToBytes(transactionHash)) - if err != nil { - if err == database.ErrKeyNotFound { - return nil, nil - } - return nil, fmt.Errorf("%w: failed to retrieve transaction: %s", ErrDatabaseError, err) - } - - return value_transaction.FromBytes(txData.Value), nil -} - -func databaseContainsTransaction(transactionHash trinary.Trytes) (bool, error) { - if contains, err := transactionDatabase.Contains(typeutils.StringToBytes(transactionHash)); err != nil { - return contains, fmt.Errorf("%w: failed to check if the transaction exists: %s", ErrDatabaseError, err) - } else { - return contains, nil - } -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/tangle/transaction_metadata.go b/plugins/tangle/transaction_metadata.go deleted file mode 100644 index 152f0126da1f00dd741d2c9953743a8010e9f764..0000000000000000000000000000000000000000 --- a/plugins/tangle/transaction_metadata.go +++ /dev/null @@ -1,134 +0,0 @@ -package tangle - -import ( - "fmt" - - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/goshimmer/packages/model/transactionmetadata" - "github.com/iotaledger/hive.go/lru_cache" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -// region public api /////////////////////////////////////////////////////////////////////////////////////////////////// - -func GetTransactionMetadata(transactionHash trinary.Trytes, computeIfAbsent ...func(trinary.Trytes) *transactionmetadata.TransactionMetadata) (result *transactionmetadata.TransactionMetadata, err error) { - if cacheResult := transactionMetadataCache.ComputeIfAbsent(transactionHash, func() interface{} { - if transactionMetadata, dbErr := getTransactionMetadataFromDatabase(transactionHash); dbErr != nil { - err = dbErr - - return nil - } else if transactionMetadata != nil { - return transactionMetadata - } else { - if len(computeIfAbsent) >= 1 { - return computeIfAbsent[0](transactionHash) - } - - return nil - } - }); !typeutils.IsInterfaceNil(cacheResult) { - result = cacheResult.(*transactionmetadata.TransactionMetadata) - } - - return -} - -func ContainsTransactionMetadata(transactionHash trinary.Trytes) (result bool, err error) { - if transactionMetadataCache.Contains(transactionHash) { - result = true - } else { - result, err = databaseContainsTransactionMetadata(transactionHash) - } - - return -} - -func StoreTransactionMetadata(transactionMetadata *transactionmetadata.TransactionMetadata) { - transactionMetadataCache.Set(transactionMetadata.GetHash(), transactionMetadata) -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region lru cache //////////////////////////////////////////////////////////////////////////////////////////////////// - -var transactionMetadataCache = lru_cache.NewLRUCache(TRANSACTION_METADATA_CACHE_SIZE, &lru_cache.LRUCacheOptions{ - EvictionCallback: onEvictTransactionMetadatas, - EvictionBatchSize: 200, -}) - -func onEvictTransactionMetadatas(_ interface{}, values interface{}) { - // TODO: replace with apply - for _, obj := range values.([]interface{}) { - if txMetadata := obj.(*transactionmetadata.TransactionMetadata); txMetadata.GetModified() { - if err := storeTransactionMetadataInDatabase(txMetadata); err != nil { - panic(err) - } - } - } -} - -func FlushTransactionMetadata() { - transactionCache.DeleteAll() -} - -const ( - TRANSACTION_METADATA_CACHE_SIZE = 500 -) - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region database ///////////////////////////////////////////////////////////////////////////////////////////////////// - -var transactionMetadataDatabase database.Database - -func configureTransactionMetaDataDatabase() { - if db, err := database.Get(database.DBPrefixTransactionMetadata, database.GetBadgerInstance()); err != nil { - panic(err) - } else { - transactionMetadataDatabase = db - } -} - -func storeTransactionMetadataInDatabase(metadata *transactionmetadata.TransactionMetadata) error { - if metadata.GetModified() { - if marshaledMetadata, err := metadata.Marshal(); err != nil { - return err - } else { - if err := transactionMetadataDatabase.Set(database.Entry{Key: typeutils.StringToBytes(metadata.GetHash()), Value: marshaledMetadata}); err != nil { - return fmt.Errorf("%w: failed to store transaction metadata: %s", ErrDatabaseError, err) - } - - metadata.SetModified(false) - } - } - - return nil -} - -func getTransactionMetadataFromDatabase(transactionHash trinary.Trytes) (*transactionmetadata.TransactionMetadata, error) { - txMetadata, err := transactionMetadataDatabase.Get(typeutils.StringToBytes(transactionHash)) - if err != nil { - if err == database.ErrKeyNotFound { - return nil, nil - } - return nil, fmt.Errorf("%w: failed to retrieve transaction: %s", ErrDatabaseError, err) - } - - var result transactionmetadata.TransactionMetadata - if err := result.Unmarshal(txMetadata.Value); err != nil { - panic(err) - } - - return &result, nil -} - -func databaseContainsTransactionMetadata(transactionHash trinary.Trytes) (bool, error) { - if contains, err := transactionMetadataDatabase.Contains(typeutils.StringToBytes(transactionHash)); err != nil { - return contains, fmt.Errorf("%w: failed to check if the transaction metadata exists: %s", ErrDatabaseError, err) - } else { - return contains, nil - } -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/tangle/tx_per_address.go b/plugins/tangle/tx_per_address.go deleted file mode 100644 index 092a75248419251137c6205be0abf108b9b495df..0000000000000000000000000000000000000000 --- a/plugins/tangle/tx_per_address.go +++ /dev/null @@ -1,59 +0,0 @@ -package tangle - -import ( - "fmt" - - "github.com/iotaledger/goshimmer/packages/database" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/trinary" -) - -var ( - transactionsHashesForAddressDatabase database.Database -) - -func configureTransactionHashesForAddressDatabase() { - if db, err := database.Get(database.DBPrefixAddressTransactions, database.GetBadgerInstance()); err != nil { - panic(err) - } else { - transactionsHashesForAddressDatabase = db - } -} - -type TxHashForAddress struct { - Address trinary.Hash - TxHash trinary.Hash -} - -func StoreTransactionHashForAddressInDatabase(address *TxHashForAddress) error { - if err := transactionsHashesForAddressDatabase.Set(database.Entry{ - Key: databaseKeyForHashPrefixedHash(address.Address, address.TxHash), - Value: []byte{}, - }); err != nil { - return fmt.Errorf("%w: failed to store tx for address in database: %s", ErrDatabaseError, err) - } - return nil -} - -func DeleteTransactionHashForAddressInDatabase(address *TxHashForAddress) error { - if err := transactionsHashesForAddressDatabase.Delete( - databaseKeyForHashPrefixedHash(address.Address, address.TxHash), - ); err != nil { - return fmt.Errorf("%w: failed to delete tx for address: %s", ErrDatabaseError, err) - } - - return nil -} - -func ReadTransactionHashesForAddressFromDatabase(address trinary.Hash) ([]trinary.Hash, error) { - var transactionHashes []trinary.Hash - err := transactionsHashesForAddressDatabase.StreamForEachPrefixKeyOnly(databaseKeyForHashPrefix(address), func(key database.KeyOnlyEntry) error { - transactionHashes = append(transactionHashes, typeutils.BytesToString(key.Key)) - return nil - }) - - if err != nil { - return nil, fmt.Errorf("%w: failed to read tx per address from database: %s", ErrDatabaseError, err) - } - return transactionHashes, nil -} diff --git a/plugins/tangle/unsolidTxs.go b/plugins/tangle/unsolidTxs.go deleted file mode 100644 index 36924fa75ff8ce1a757fc1f96695822ae03e6969..0000000000000000000000000000000000000000 --- a/plugins/tangle/unsolidTxs.go +++ /dev/null @@ -1,59 +0,0 @@ -package tangle - -import ( - "sync" - "time" -) - -type UnsolidTxs struct { - internal map[string]Info - sync.RWMutex -} - -type Info struct { - lastRequest time.Time - counter int -} - -func NewUnsolidTxs() *UnsolidTxs { - return &UnsolidTxs{ - internal: make(map[string]Info), - } -} - -func (u *UnsolidTxs) Add(hash string) bool { - u.Lock() - defer u.Unlock() - _, contains := u.internal[hash] - if contains { - return false - } - info := Info{ - lastRequest: time.Now(), - counter: 1, - } - u.internal[hash] = info - return true -} - -func (u *UnsolidTxs) Remove(hash string) { - u.Lock() - delete(u.internal, hash) - u.Unlock() -} - -func (u *UnsolidTxs) Update(targetTime time.Time) (result []string) { - u.Lock() - for k, v := range u.internal { - if v.lastRequest.Before(targetTime) { - result = append(result, k) - - v.lastRequest = time.Now() - v.counter++ - - u.internal[k] = v - } - } - u.Unlock() - return result -} diff --git a/plugins/tipselection/plugin.go b/plugins/tipselection/plugin.go deleted file mode 100644 index 7587075e303638b84e24fe51494eeff6e257ac8f..0000000000000000000000000000000000000000 --- a/plugins/tipselection/plugin.go +++ /dev/null @@ -1,27 +0,0 @@ -package tipselection - -import ( - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/trinary" -) - -var PLUGIN = node.NewPlugin("Tipselection", node.Enabled, configure, run) - -func configure(*node.Plugin) { - tipSet = make(map[trinary.Hash]struct{}) - - tangle.Events.TransactionSolid.Attach(events.NewClosure(func(transaction *value_transaction.ValueTransaction) { - mutex.Lock() - defer mutex.Unlock() - - delete(tipSet, transaction.GetBranchTransactionHash()) - delete(tipSet, transaction.GetTrunkTransactionHash()) - tipSet[transaction.GetHash()] = struct{}{} - })) -} - -func run(*node.Plugin) { -} diff --git a/plugins/tipselection/tipselection.go b/plugins/tipselection/tipselection.go deleted file mode 100644 index 95cb4bc1b523637286be4eabb9692458bc07627f..0000000000000000000000000000000000000000 --- a/plugins/tipselection/tipselection.go +++ /dev/null @@ -1,54 +0,0 @@ -package tipselection - -import ( - "math/rand" - "sync" - - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/iota.go/trinary" -) - -var ( - tipSet map[trinary.Hash]struct{} - mutex sync.RWMutex -) - -func GetRandomTip(excluding ...trinary.Hash) trinary.Trytes { - mutex.RLock() - defer mutex.RUnlock() - - numTips := len(tipSet) - if numTips == 0 { - return meta_transaction.BRANCH_NULL_HASH - } - - var ignore trinary.Hash - if len(excluding) > 0 { - ignore = excluding[0] - } - if _, contains := tipSet[ignore]; contains { - if numTips == 1 { - return ignore - } - numTips -= 1 - } - - i := rand.Intn(numTips) - for k := range tipSet { - if k == ignore { - continue - } - if i == 0 { - return k - } - i-- - } - panic("unreachable") -} - -func GetTipsCount() int { - mutex.RLock() - defer mutex.RUnlock() - - return len(tipSet) -} diff --git a/plugins/tipselection/tipselection_test.go b/plugins/tipselection/tipselection_test.go deleted file mode 100644 index cb18e47815cde237bcfdedd9dac431d4156af5fb..0000000000000000000000000000000000000000 --- a/plugins/tipselection/tipselection_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package tipselection - -import ( - "log" - "testing" - - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/hive.go/logger" - "github.com/spf13/viper" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func init() { - if err := logger.InitGlobalLogger(viper.New()); err != nil { - log.Fatal(err) - } -} - -func TestEmptyTipSet(t *testing.T) { - configure(nil) - assert.Equal(t, 0, GetTipsCount()) - assert.Equal(t, meta_transaction.BRANCH_NULL_HASH, GetRandomTip()) -} - -func TestSingleTip(t *testing.T) { - configure(nil) - - tx := value_transaction.New() - tx.SetValue(int64(1)) - tx.SetBranchTransactionHash(meta_transaction.BRANCH_NULL_HASH) - tx.SetTrunkTransactionHash(meta_transaction.BRANCH_NULL_HASH) - - tangle.Events.TransactionSolid.Trigger(tx) - - assert.Equal(t, 1, GetTipsCount()) - - tip1 := GetRandomTip() - assert.NotNil(t, tip1) - tip2 := GetRandomTip(tip1) - assert.NotNil(t, tip2) - assert.Equal(t, tip1, tip2) -} - -func TestGetRandomTip(t *testing.T) { - configure(nil) - - tx := value_transaction.New() - tx.SetValue(int64(1)) - tx.SetBranchTransactionHash(meta_transaction.BRANCH_NULL_HASH) - tx.SetTrunkTransactionHash(meta_transaction.BRANCH_NULL_HASH) - - tangle.Events.TransactionSolid.Trigger(tx) - - tx = value_transaction.New() - tx.SetValue(int64(2)) - tx.SetBranchTransactionHash(meta_transaction.BRANCH_NULL_HASH) - tx.SetTrunkTransactionHash(meta_transaction.BRANCH_NULL_HASH) - - tangle.Events.TransactionSolid.Trigger(tx) - - assert.Equal(t, 2, GetTipsCount()) - - tip1 := GetRandomTip() - require.NotNil(t, tip1) - tip2 := GetRandomTip(tip1) - require.NotNil(t, tip2) - require.NotEqual(t, tip1, tip2) - - tx = value_transaction.New() - tx.SetValue(int64(3)) - tx.SetBranchTransactionHash(tip1) - tx.SetTrunkTransactionHash(tip2) - - tangle.Events.TransactionSolid.Trigger(tx) - - assert.Equal(t, 1, GetTipsCount()) - assert.Equal(t, tx.GetHash(), GetRandomTip()) -} diff --git a/plugins/webapi/getNeighbors/plugin.go b/plugins/webapi/autopeering/plugin.go similarity index 53% rename from plugins/webapi/getNeighbors/plugin.go rename to plugins/webapi/autopeering/plugin.go index fe9c397196235d99dde63a7c5b2b467b3965e11e..512a5c25d0f7b419b00dfe08b4360d1ae03566b4 100644 --- a/plugins/webapi/getNeighbors/plugin.go +++ b/plugins/webapi/autopeering/plugin.go @@ -1,8 +1,10 @@ -package getNeighbors +package autopeering import ( - "encoding/base64" + "net" "net/http" + "strconv" + "sync" "github.com/iotaledger/goshimmer/plugins/autopeering" "github.com/iotaledger/goshimmer/plugins/webapi" @@ -12,58 +14,61 @@ import ( "github.com/labstack/echo" ) -var PLUGIN = node.NewPlugin("WebAPI getNeighbors Endpoint", node.Enabled, configure) +// PluginName is the name of the web API autopeering endpoint plugin. +const PluginName = "WebAPI autopeering Endpoint" + +var ( + // plugin is the plugin instance of the web API autopeering endpoint plugin. + plugin *node.Plugin + once sync.Once +) func configure(plugin *node.Plugin) { - webapi.Server.GET("getNeighbors", getNeighbors) + webapi.Server().GET("autopeering/neighbors", getNeighbors) +} + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin } // getNeighbors returns the chosen and accepted neighbors of the node func getNeighbors(c echo.Context) error { - chosen := []Neighbor{} - accepted := []Neighbor{} - knownPeers := []Neighbor{} - - if autopeering.Selection == nil { - return c.JSON(http.StatusNotImplemented, Response{Error: "Neighbor Selection is not enabled"}) - } - - if autopeering.Discovery == nil { - return c.JSON(http.StatusNotImplemented, Response{Error: "Neighbor Discovery is not enabled"}) - } + var chosen []Neighbor + var accepted []Neighbor + var knownPeers []Neighbor if c.QueryParam("known") == "1" { - for _, peer := range autopeering.Discovery.GetVerifiedPeers() { - n := Neighbor{ - ID: peer.ID().String(), - PublicKey: base64.StdEncoding.EncodeToString(peer.PublicKey()), - } - n.Services = getServices(peer) - knownPeers = append(knownPeers, n) + for _, p := range autopeering.Discovery().GetVerifiedPeers() { + knownPeers = append(knownPeers, createNeighborFromPeer(p)) } } - for _, peer := range autopeering.Selection.GetOutgoingNeighbors() { - n := Neighbor{ - ID: peer.ID().String(), - PublicKey: base64.StdEncoding.EncodeToString(peer.PublicKey()), - } - n.Services = getServices(peer) - chosen = append(chosen, n) + for _, p := range autopeering.Selection().GetOutgoingNeighbors() { + chosen = append(chosen, createNeighborFromPeer(p)) } - for _, peer := range autopeering.Selection.GetIncomingNeighbors() { - n := Neighbor{ - ID: peer.ID().String(), - PublicKey: base64.StdEncoding.EncodeToString(peer.PublicKey()), - } - n.Services = getServices(peer) - accepted = append(accepted, n) + for _, p := range autopeering.Selection().GetIncomingNeighbors() { + accepted = append(accepted, createNeighborFromPeer(p)) } return c.JSON(http.StatusOK, Response{KnownPeers: knownPeers, Chosen: chosen, Accepted: accepted}) } +func createNeighborFromPeer(p *peer.Peer) Neighbor { + n := Neighbor{ + ID: p.ID().String(), + PublicKey: p.PublicKey().String(), + } + n.Services = getServices(p) + + return n +} + +// Response contains information of the autopeering. type Response struct { KnownPeers []Neighbor `json:"known,omitempty"` Chosen []Neighbor `json:"chosen"` @@ -71,6 +76,7 @@ type Response struct { Error string `json:"error,omitempty"` } +// Neighbor contains information of a neighbor peer. type Neighbor struct { ID string `json:"id"` // comparable node identifier PublicKey string `json:"publicKey"` // public key used to verify signatures @@ -83,12 +89,14 @@ type peerService struct { } func getServices(p *peer.Peer) []peerService { - services := []peerService{} + var services []peerService + + host := p.IP().String() peeringService := p.Services().Get(service.PeeringKey) if peeringService != nil { services = append(services, peerService{ ID: "peering", - Address: peeringService.String(), + Address: net.JoinHostPort(host, strconv.Itoa(peeringService.Port())), }) } @@ -96,7 +104,7 @@ func getServices(p *peer.Peer) []peerService { if gossipService != nil { services = append(services, peerService{ ID: "gossip", - Address: gossipService.String(), + Address: net.JoinHostPort(host, strconv.Itoa(gossipService.Port())), }) } @@ -104,7 +112,7 @@ func getServices(p *peer.Peer) []peerService { if fpcService != nil { services = append(services, peerService{ ID: "FPC", - Address: fpcService.String(), + Address: net.JoinHostPort(host, strconv.Itoa(fpcService.Port())), }) } diff --git a/plugins/webapi/broadcastData/plugin.go b/plugins/webapi/broadcastData/plugin.go deleted file mode 100644 index 180144daece29905658d1e667c5521ed0cb838c2..0000000000000000000000000000000000000000 --- a/plugins/webapi/broadcastData/plugin.go +++ /dev/null @@ -1,88 +0,0 @@ -package broadcastData - -import ( - "net/http" - "time" - - "github.com/iotaledger/goshimmer/packages/gossip" - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/goshimmer/plugins/tipselection" - "github.com/iotaledger/goshimmer/plugins/webapi" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/hive.go/typeutils" - "github.com/iotaledger/iota.go/address" - "github.com/iotaledger/iota.go/trinary" - "github.com/labstack/echo" -) - -var PLUGIN = node.NewPlugin("WebAPI broadcastData Endpoint", node.Enabled, configure) -var log *logger.Logger - -func configure(plugin *node.Plugin) { - log = logger.NewLogger("API-broadcastData") - webapi.Server.POST("broadcastData", broadcastData) -} - -// broadcastData creates a data (0-value) transaction given an input of bytes and -// broadcasts it to the node's neighbors. It returns the transaction hash if successful. -func broadcastData(c echo.Context) error { - - var request Request - if err := c.Bind(&request); err != nil { - log.Info(err.Error()) - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } - - log.Debug("Received - address:", request.Address, " data:", request.Data) - - tx := value_transaction.New() - tx.SetHead(true) - tx.SetTail(true) - - buffer := make([]byte, 2187) - if len(request.Data) > 2187 { - log.Warnf("data exceeds 2187 byte limit - (payload data size: %d)", len(request.Data)) - return c.JSON(http.StatusBadRequest, Response{Error: "data exceeds 2187 byte limit"}) - } - - copy(buffer, typeutils.StringToBytes(request.Data)) - - trytes, err := trinary.BytesToTrytes(buffer) - if err != nil { - log.Warnf("trytes conversion failed: %s", err.Error()) - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } - - err = address.ValidAddress(request.Address) - if err != nil { - log.Warnf("invalid Address: %s", request.Address) - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } - - tx.SetAddress(request.Address) - tx.SetSignatureMessageFragment(trytes) - tx.SetValue(0) - tx.SetBranchTransactionHash(tipselection.GetRandomTip()) - tx.SetTrunkTransactionHash(tipselection.GetRandomTip(tx.GetBranchTransactionHash())) - tx.SetTimestamp(uint(time.Now().Unix())) - if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil { - log.Warnf("PoW failed: %s", err) - return c.JSON(http.StatusInternalServerError, Response{Error: err.Error()}) - } - - gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: tx.GetBytes(), Peer: &local.GetInstance().Peer}) - return c.JSON(http.StatusOK, Response{Hash: tx.GetHash()}) -} - -type Response struct { - Hash string `json:"hash,omitempty"` - Error string `json:"error,omitempty"` -} - -type Request struct { - Address string `json:"address"` - Data string `json:"data"` -} diff --git a/plugins/webapi/data/plugin.go b/plugins/webapi/data/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..605ad8d8f36f83c78080cf1017dccdadaea336db --- /dev/null +++ b/plugins/webapi/data/plugin.go @@ -0,0 +1,70 @@ +package data + +import ( + "fmt" + "net/http" + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/labstack/echo" +) + +// PluginName is the name of the web API data endpoint plugin. +const PluginName = "WebAPI data Endpoint" + +var ( + // plugin is the plugin instance of the web API data endpoint plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(plugin *node.Plugin) { + log = logger.NewLogger(PluginName) + webapi.Server().POST("data", broadcastData) +} + +// broadcastData creates a message of the given payload and +// broadcasts it to the node's neighbors. It returns the message ID if successful. +func broadcastData(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + dataPayload := payload.NewData(request.Data) + if len(dataPayload.Bytes()) > payload.MaxDataPayloadSize { + err := fmt.Errorf("%w: %d", payload.ErrMaximumPayloadSizeExceeded, payload.MaxDataPayloadSize) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + msg, err := issuer.IssuePayload(payload.NewData(request.Data)) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + return c.JSON(http.StatusOK, Response{ID: msg.Id().String()}) +} + +// Response contains the ID of the message sent. +type Response struct { + ID string `json:"id,omitempty"` + Error string `json:"error,omitempty"` +} + +// Request contains the data of the message to send. +type Request struct { + Data []byte `json:"data"` +} diff --git a/plugins/webapi/drng/collectivebeacon/handler.go b/plugins/webapi/drng/collectivebeacon/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..3c21953c861e2b7ef011a772633d2b601a615b2b --- /dev/null +++ b/plugins/webapi/drng/collectivebeacon/handler.go @@ -0,0 +1,43 @@ +package collectivebeacon + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/iotaledger/hive.go/marshalutil" + "github.com/labstack/echo" + "github.com/labstack/gommon/log" +) + +// Handler gets the current DRNG committee. +func Handler(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + marshalUtil := marshalutil.New(request.Payload) + parsedPayload, err := payload.Parse(marshalUtil) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + msg, err := issuer.IssuePayload(parsedPayload) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + return c.JSON(http.StatusOK, Response{ID: msg.Id().String()}) +} + +// Response is the HTTP response from broadcasting a collective beacon message. +type Response struct { + ID string `json:"id,omitempty"` + Error string `json:"error,omitempty"` +} + +// Request is a request containing a collective beacon response. +type Request struct { + Payload []byte `json:"payload"` +} diff --git a/plugins/webapi/drng/info/committee/handler.go b/plugins/webapi/drng/info/committee/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..cc46699296f755ab7ccb1403e5600f1afc95a1dd --- /dev/null +++ b/plugins/webapi/drng/info/committee/handler.go @@ -0,0 +1,29 @@ +package committee + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/plugins/drng" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/labstack/echo" +) + +// Handler returns the current DRNG committee used. +func Handler(c echo.Context) error { + committee := drng.Instance().State.Committee() + return c.JSON(http.StatusOK, Response{ + InstanceID: committee.InstanceID, + Threshold: committee.Threshold, + Identities: committee.Identities, + DistributedPK: committee.DistributedPK, + }) +} + +// Response is the HTTP message containing the DRNG committee. +type Response struct { + InstanceID uint32 `json:"instanceID,omitempty"` + Threshold uint8 `json:"threshold,omitempty"` + Identities []ed25519.PublicKey `json:"identities,omitempty"` + DistributedPK []byte `json:"distributedPK,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/plugins/webapi/drng/info/randomness/handler.go b/plugins/webapi/drng/info/randomness/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..7f8c12a34981867cf6b7f4d3cd966a135952c7df --- /dev/null +++ b/plugins/webapi/drng/info/randomness/handler.go @@ -0,0 +1,27 @@ +package randomness + +import ( + "net/http" + "time" + + "github.com/iotaledger/goshimmer/plugins/drng" + "github.com/labstack/echo" +) + +// Handler returns the current DRNG randomness used. +func Handler(c echo.Context) error { + randomness := drng.Instance().State.Randomness() + return c.JSON(http.StatusOK, Response{ + Round: randomness.Round, + Randomness: randomness.Randomness, + Timestamp: randomness.Timestamp, + }) +} + +// Response is the HTTP message containing the current DRNG randomness. +type Response struct { + Round uint64 `json:"round,omitempty"` + Timestamp time.Time `json:"timestamp,omitempty"` + Randomness []byte `json:"randomness,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/plugins/webapi/drng/plugin.go b/plugins/webapi/drng/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..ccbcc152f9c919acbe08c019e1d630ffd64f6668 --- /dev/null +++ b/plugins/webapi/drng/plugin.go @@ -0,0 +1,34 @@ +package drng + +import ( + "sync" + + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/goshimmer/plugins/webapi/drng/collectivebeacon" + "github.com/iotaledger/goshimmer/plugins/webapi/drng/info/committee" + "github.com/iotaledger/goshimmer/plugins/webapi/drng/info/randomness" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the web API DRNG endpoint plugin. +const PluginName = "WebAPI DRNG Endpoint" + +var ( + // plugin is the plugin instance of the web API DRNG endpoint plugin. + plugin *node.Plugin + once sync.Once +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(_ *node.Plugin) { + webapi.Server().POST("drng/collectiveBeacon", collectivebeacon.Handler) + webapi.Server().GET("drng/info/committee", committee.Handler) + webapi.Server().GET("drng/info/randomness", randomness.Handler) +} diff --git a/plugins/webapi/endpoints.go b/plugins/webapi/endpoints.go index c01bd84cca2f270568f5762d65fdf1d94d540d37..dcc8ec1df05aaa859ca1e7e8a15924d25bcc8b5a 100644 --- a/plugins/webapi/endpoints.go +++ b/plugins/webapi/endpoints.go @@ -6,6 +6,7 @@ import ( "github.com/labstack/echo" ) +// IndexRequest returns INDEX func IndexRequest(c echo.Context) error { return c.String(http.StatusOK, "INDEX") } diff --git a/plugins/webapi/faucet/plugin.go b/plugins/webapi/faucet/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..74d2c796f59c61d6e2dc1af8b31db619b3672ba3 --- /dev/null +++ b/plugins/webapi/faucet/plugin.go @@ -0,0 +1,76 @@ +package faucet + +import ( + "net/http" + goSync "sync" + + faucetpayload "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/labstack/echo" +) + +const ( + // PluginName is the name of the web API faucet endpoint plugin. + PluginName = "WebAPI faucet Endpoint" +) + +var ( + // plugin is the plugin instance of the web API info endpoint plugin. + plugin *node.Plugin + once goSync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(plugin *node.Plugin) { + log = logger.NewLogger("API-faucet") + webapi.Server().POST("faucet", requestFunds) +} + +// requestFunds creates a faucet request (0-value) message with the given destination address and +// broadcasts it to the node's neighbors. It returns the message ID if successful. +func requestFunds(c echo.Context) error { + var request Request + var addr address.Address + if err := c.Bind(&request); err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + log.Debug("Received - address:", request.Address) + + addr, err := address.FromBase58(request.Address) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: "Invalid address"}) + } + + // build faucet message with transaction factory + msg := messagelayer.MessageFactory().IssuePayload(faucetpayload.New(addr)) + if msg == nil { + return c.JSON(http.StatusInternalServerError, Response{Error: "Fail to send faucetrequest"}) + } + + return c.JSON(http.StatusOK, Response{ID: msg.Id().String()}) +} + +// Response contains the ID of the message sent. +type Response struct { + ID string `json:"id,omitempty"` + Error string `json:"error,omitempty"` +} + +// Request contains the address to request funds from faucet. +type Request struct { + Address string `json:"address"` +} diff --git a/plugins/webapi/findTransactionHashes/plugin.go b/plugins/webapi/findTransactionHashes/plugin.go deleted file mode 100644 index 7ae655f84217564fa4811c0fd9025670ef4284d2..0000000000000000000000000000000000000000 --- a/plugins/webapi/findTransactionHashes/plugin.go +++ /dev/null @@ -1,54 +0,0 @@ -package findTransactionHashes - -import ( - "net/http" - - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/goshimmer/plugins/webapi" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/trinary" - "github.com/labstack/echo" -) - -var PLUGIN = node.NewPlugin("WebAPI findTransactionHashes Endpoint", node.Enabled, configure) -var log *logger.Logger - -func configure(plugin *node.Plugin) { - log = logger.NewLogger("API-findTransactionHashes") - webapi.Server.POST("findTransactionHashes", findTransactionHashes) -} - -// findTransactionHashes returns the array of transaction hashes for the -// given addresses (in the same order as the parameters). -// If a node doesn't have any transaction hash for a given address in its ledger, -// the value at the index of that address is empty. -func findTransactionHashes(c echo.Context) error { - var request Request - - if err := c.Bind(&request); err != nil { - log.Info(err.Error()) - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } - log.Debug("Received:", request.Addresses) - result := make([][]trinary.Trytes, len(request.Addresses)) - - for i, address := range request.Addresses { - txs, err := tangle.ReadTransactionHashesForAddressFromDatabase(address) - if err != nil { - return c.JSON(http.StatusInternalServerError, Response{Error: err.Error()}) - } - result[i] = append(result[i], txs...) - } - - return c.JSON(http.StatusOK, Response{Transactions: result}) -} - -type Response struct { - Transactions [][]trinary.Trytes `json:"transactions,omitempty"` //string - Error string `json:"error,omitempty"` -} - -type Request struct { - Addresses []string `json:"addresses"` -} diff --git a/plugins/webapi/getTransactionObjectsByHash/plugin.go b/plugins/webapi/getTransactionObjectsByHash/plugin.go deleted file mode 100644 index e2b0e766658d8f15765fbb017f31174a7001160d..0000000000000000000000000000000000000000 --- a/plugins/webapi/getTransactionObjectsByHash/plugin.go +++ /dev/null @@ -1,87 +0,0 @@ -package getTransactionObjectsByHash - -import ( - "fmt" - "net/http" - - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/goshimmer/plugins/webapi" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/trinary" - "github.com/labstack/echo" -) - -var PLUGIN = node.NewPlugin("WebAPI getTransactionObjectsByHash Endpoint", node.Enabled, configure) -var log *logger.Logger - -func configure(plugin *node.Plugin) { - log = logger.NewLogger("API-getTransactionObjectsByHash") - webapi.Server.POST("getTransactionObjectsByHash", getTransactionObjectsByHash) -} - -// getTransactionObjectsByHash returns the array of transactions for the -// given transaction hashes (in the same order as the parameters). -// If a node doesn't have the transaction for a given transaction hash in its ledger, -// the value at the index of that transaction hash is empty. -func getTransactionObjectsByHash(c echo.Context) error { - - var request Request - result := []Transaction{} - - if err := c.Bind(&request); err != nil { - log.Info(err.Error()) - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } - - log.Debug("Received:", request.Hashes) - - for _, hash := range request.Hashes { - tx, err := tangle.GetTransaction(hash) - if err != nil { - return c.JSON(http.StatusInternalServerError, Response{Error: err.Error()}) - } - if tx == nil { - return c.JSON(http.StatusNotFound, Response{Error: fmt.Sprintf("transaction not found: %s", hash)}) - } - t := Transaction{ - Hash: tx.GetHash(), - WeightMagnitude: tx.GetWeightMagnitude(), - TrunkTransactionHash: tx.GetTrunkTransactionHash(), - BranchTransactionHash: tx.GetBranchTransactionHash(), - Head: tx.IsHead(), - Tail: tx.IsTail(), - Nonce: tx.GetNonce(), - Address: tx.GetAddress(), - Value: tx.GetValue(), - Timestamp: tx.GetTimestamp(), - SignatureMessageFragment: tx.GetSignatureMessageFragment(), - } - result = append(result, t) - } - - return c.JSON(http.StatusOK, Response{Transactions: result}) -} - -type Response struct { - Transactions []Transaction `json:"transaction,omitempty"` - Error string `json:"error,omitempty"` -} - -type Request struct { - Hashes []string `json:"hashes"` -} - -type Transaction struct { - Hash trinary.Trytes `json:"hash,omitempty"` - WeightMagnitude int `json:"weightMagnitude,omitempty"` - TrunkTransactionHash trinary.Trytes `json:"trunkTransactionHash,omitempty"` - BranchTransactionHash trinary.Trytes `json:"branchTransactionHash,omitempty"` - Head bool `json:"head,omitempty"` - Tail bool `json:"tail,omitempty"` - Nonce trinary.Trytes `json:"nonce,omitempty"` - Address trinary.Trytes `json:"address,omitempty"` - Value int64 `json:"value,omitempty"` - Timestamp uint `json:"timestamp,omitempty"` - SignatureMessageFragment trinary.Trytes `json:"signatureMessageFragment,omitempty"` -} diff --git a/plugins/webapi/getTransactionTrytesByHash/plugin.go b/plugins/webapi/getTransactionTrytesByHash/plugin.go deleted file mode 100644 index 8cb797782e73b90a74d0227429c4b1deac2a830f..0000000000000000000000000000000000000000 --- a/plugins/webapi/getTransactionTrytesByHash/plugin.go +++ /dev/null @@ -1,59 +0,0 @@ -package getTransactionTrytesByHash - -import ( - "fmt" - "net/http" - - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/goshimmer/plugins/webapi" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/trinary" - "github.com/labstack/echo" -) - -var PLUGIN = node.NewPlugin("WebAPI getTransactionTrytesByHash Endpoint", node.Enabled, configure) -var log *logger.Logger - -func configure(plugin *node.Plugin) { - log = logger.NewLogger("API-getTransactionTrytesByHash") - webapi.Server.POST("getTransactionTrytesByHash", getTransactionTrytesByHash) -} - -// getTransactionTrytesByHash returns the array of transaction trytes for the -// given transaction hashes (in the same order as the parameters). -// If a node doesn't have the trytes for a given transaction hash in its ledger, -// the value at the index of that transaction hash is empty. -func getTransactionTrytesByHash(c echo.Context) error { - - var request Request - result := []trinary.Trytes{} - if err := c.Bind(&request); err != nil { - log.Info(err.Error()) - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } - log.Debug("Received:", request.Hashes) - - for _, hash := range request.Hashes { - tx, err := tangle.GetTransaction(hash) - if err != nil { - return c.JSON(http.StatusInternalServerError, Response{Error: err.Error()}) - } - if tx == nil { - return c.JSON(http.StatusNotFound, Response{Error: fmt.Sprintf("transaction not found: %s", hash)}) - } - trytes := trinary.MustTritsToTrytes(tx.GetTrits()) - result = append(result, trytes) - } - - return c.JSON(http.StatusOK, Response{Trytes: result}) -} - -type Response struct { - Trytes []trinary.Trytes `json:"trytes,omitempty"` //string - Error string `json:"error,omitempty"` -} - -type Request struct { - Hashes []string `json:"hashes"` -} diff --git a/plugins/webapi/gtta/plugin.go b/plugins/webapi/gtta/plugin.go deleted file mode 100644 index 54444bce56bcbb2a7df88dc54816433f5871e762..0000000000000000000000000000000000000000 --- a/plugins/webapi/gtta/plugin.go +++ /dev/null @@ -1,31 +0,0 @@ -package gtta - -import ( - "net/http" - - "github.com/iotaledger/goshimmer/plugins/tipselection" - "github.com/iotaledger/goshimmer/plugins/webapi" - "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/trinary" - "github.com/labstack/echo" -) - -var PLUGIN = node.NewPlugin("WebAPI GTTA Endpoint", node.Disabled, func(plugin *node.Plugin) { - webapi.Server.GET("getTransactionsToApprove", Handler) -}) - -func Handler(c echo.Context) error { - - branchTransactionHash := tipselection.GetRandomTip() - trunkTransactionHash := tipselection.GetRandomTip(branchTransactionHash) - - return c.JSON(http.StatusOK, Response{ - BranchTransaction: branchTransactionHash, - TrunkTransaction: trunkTransactionHash, - }) -} - -type Response struct { - BranchTransaction trinary.Trytes `json:"branchTransaction"` - TrunkTransaction trinary.Trytes `json:"trunkTransaction"` -} diff --git a/plugins/webapi/healthz/plugin.go b/plugins/webapi/healthz/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..d81d90edf8aac73b34207635def36d24914385aa --- /dev/null +++ b/plugins/webapi/healthz/plugin.go @@ -0,0 +1,56 @@ +package healthz + +import ( + "net/http" + goSync "sync" + + "github.com/iotaledger/goshimmer/plugins/gossip" + "github.com/iotaledger/goshimmer/plugins/sync" + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/hive.go/node" + "github.com/labstack/echo" +) + +// PluginName is the name of the web API healthz endpoint plugin. +const PluginName = "WebAPI healthz Endpoint" + +var ( + // plugin is the plugin instance of the web API info endpoint plugin. + plugin *node.Plugin + once goSync.Once +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(_ *node.Plugin) { + webapi.Server().GET("healthz", getHealthz) +} + +func getHealthz(c echo.Context) error { + if !IsNodeHealthy() { + return c.NoContent(http.StatusServiceUnavailable) + } + + return c.NoContent(http.StatusOK) +} + +// IsNodeHealthy returns whether the node is synced, has active neighbors. +func IsNodeHealthy() bool { + // Synced + if !sync.Synced() { + return false + } + + // Has connected neighbors + if len(gossip.Manager().AllNeighbors()) == 0 { + return false + } + + return true +} diff --git a/plugins/webapi/info/plugin.go b/plugins/webapi/info/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..a64f121b790023fb34a3e45b2607e72cbe913b23 --- /dev/null +++ b/plugins/webapi/info/plugin.go @@ -0,0 +1,112 @@ +package info + +import ( + "net/http" + "sort" + goSync "sync" + + "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/banner" + "github.com/iotaledger/goshimmer/plugins/sync" + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/hive.go/node" + "github.com/labstack/echo" +) + +// PluginName is the name of the web API info endpoint plugin. +const PluginName = "WebAPI info Endpoint" + +var ( + // plugin is the plugin instance of the web API info endpoint plugin. + plugin *node.Plugin + once goSync.Once +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(_ *node.Plugin) { + webapi.Server().GET("info", getInfo) +} + +// getInfo returns the info of the node +// e.g., +// { +// "version":"v0.2.0", +// "synchronized": true, +// "identityID":"5bf4aa1d6c47e4ce", +// "publickey":"CjUsn86jpFHWnSCx3NhWfU4Lk16mDdy1Hr7ERSTv3xn9", +// "enabledplugins":[ +// "Config", +// "Autopeering", +// "Analysis", +// "WebAPI data Endpoint", +// "WebAPI dRNG Endpoint", +// "MessageLayer", +// "CLI", +// "Database", +// "DRNG", +// "WebAPI autopeering Endpoint", +// "Metrics", +// "PortCheck", +// "Dashboard", +// "WebAPI", +// "WebAPI info Endpoint", +// "WebAPI message Endpoint", +// "Banner", +// "Gossip", +// "Graceful Shutdown", +// "Logger" +// ], +// "disabledplugins":[ +// "RemoteLog", +// "Spammer", +// "WebAPI Auth" +// ] +// } +func getInfo(c echo.Context) error { + var enabledPlugins []string + var disabledPlugins []string + for pluginName, plugin := range node.GetPlugins() { + if node.IsSkipped(plugin) { + disabledPlugins = append(disabledPlugins, pluginName) + } else { + enabledPlugins = append(enabledPlugins, pluginName) + } + } + + sort.Strings(enabledPlugins) + sort.Strings(disabledPlugins) + + return c.JSON(http.StatusOK, Response{ + Version: banner.AppVersion, + Synced: sync.Synced(), + IdentityID: local.GetInstance().Identity.ID().String(), + PublicKey: local.GetInstance().PublicKey().String(), + EnabledPlugins: enabledPlugins, + DisabledPlugins: disabledPlugins, + }) +} + +// Response holds the response of the GET request. +type Response struct { + // version of GoShimmer + Version string `json:"version,omitempty"` + // whether the node is synchronized + Synced bool `json:"synced"` + // identity ID of the node encoded in base58 and truncated to its first 8 bytes + IdentityID string `json:"identityID,omitempty"` + // public key of the node encoded in base58 + PublicKey string `json:"publicKey,omitempty"` + // list of enabled plugins + EnabledPlugins []string `json:"enabledPlugins,omitempty"` + // list if disabled plugins + DisabledPlugins []string `json:"disabledPlugins,omitempty"` + // error of the response + Error string `json:"error,omitempty"` +} diff --git a/plugins/webapi/message/plugin.go b/plugins/webapi/message/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..c65b6c3e4409e2c15bc6d427896552157b25773b --- /dev/null +++ b/plugins/webapi/message/plugin.go @@ -0,0 +1,123 @@ +package message + +import ( + "net/http" + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/plugins/messagelayer" + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/hive.go/logger" + "github.com/iotaledger/hive.go/node" + "github.com/labstack/echo" +) + +// PluginName is the name of the web API message endpoint plugin. +const PluginName = "WebAPI message Endpoint" + +var ( + // plugin is the plugin instance of the web API message endpoint plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(plugin *node.Plugin) { + log = logger.NewLogger(PluginName) + webapi.Server().POST("message/findById", findMessageByID) + webapi.Server().POST("message/sendPayload", sendPayload) +} + +// findMessageByID returns the array of messages for the +// given message ids (MUST be encoded in base58), in the same order as the parameters. +// If a node doesn't have the message for a given ID in its ledger, +// the value at the index of that message ID is empty. +// If an ID is not base58 encoded, an error is returned +func findMessageByID(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + var result []Message + for _, id := range request.IDs { + log.Info("Received:", id) + + msgID, err := message.NewId(id) + if err != nil { + log.Info(err) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + msgObject := messagelayer.Tangle().Message(msgID) + msgMetadataObject := messagelayer.Tangle().MessageMetadata(msgID) + + if !msgObject.Exists() || !msgMetadataObject.Exists() { + result = append(result, Message{}) + continue + } + + msg := msgObject.Unwrap() + msgMetadata := msgMetadataObject.Unwrap() + + msgResp := Message{ + Metadata: Metadata{ + Solid: msgMetadata.IsSolid(), + SolidificationTime: msgMetadata.SolidificationTime().Unix(), + }, + ID: msg.Id().String(), + TrunkID: msg.TrunkId().String(), + BranchID: msg.BranchId().String(), + IssuerPublicKey: msg.IssuerPublicKey().String(), + IssuingTime: msg.IssuingTime().Unix(), + SequenceNumber: msg.SequenceNumber(), + Payload: msg.Payload().Bytes(), + Signature: msg.Signature().String(), + } + result = append(result, msgResp) + + msgMetadataObject.Release() + msgObject.Release() + } + + return c.JSON(http.StatusOK, Response{Messages: result}) +} + +// Response is the HTTP response containing the queried messages. +type Response struct { + Messages []Message `json:"messages,omitempty"` + Error string `json:"error,omitempty"` +} + +// Request holds the message ids to query. +type Request struct { + IDs []string `json:"ids"` +} + +// Message contains information about a given message. +type Message struct { + Metadata `json:"metadata,omitempty"` + ID string `json:"ID,omitempty"` + TrunkID string `json:"trunkId,omitempty"` + BranchID string `json:"branchId,omitempty"` + IssuerPublicKey string `json:"issuerPublicKey,omitempty"` + IssuingTime int64 `json:"issuingTime,omitempty"` + SequenceNumber uint64 `json:"sequenceNumber,omitempty"` + Payload []byte `json:"payload,omitempty"` + Signature string `json:"signature,omitempty"` +} + +// Metadata contains metadata information of a message. +type Metadata struct { + Solid bool `json:"solid,omitempty"` + SolidificationTime int64 `json:"solidificationTime,omitempty"` +} diff --git a/plugins/webapi/message/sendPayload.go b/plugins/webapi/message/sendPayload.go new file mode 100644 index 0000000000000000000000000000000000000000..cffc572be8a36141ec6f2086edcb1d1d4ec26a3d --- /dev/null +++ b/plugins/webapi/message/sendPayload.go @@ -0,0 +1,42 @@ +package message + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/labstack/echo" +) + +// sendPayload creates a message of the given payload and +// broadcasts it to the node's neighbors. It returns the message ID if successful. +func sendPayload(c echo.Context) error { + var request MsgRequest + if err := c.Bind(&request); err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, MsgResponse{Error: err.Error()}) + } + + parsedPayload, _, err := payload.FromBytes(request.Payload) + if err != nil { + return c.JSON(http.StatusBadRequest, MsgResponse{Error: err.Error()}) + } + + msg, err := issuer.IssuePayload(parsedPayload) + if err != nil { + return c.JSON(http.StatusBadRequest, MsgResponse{Error: err.Error()}) + } + + return c.JSON(http.StatusOK, MsgResponse{ID: msg.Id().String()}) +} + +// MsgResponse contains the ID of the message sent. +type MsgResponse struct { + ID string `json:"id,omitempty"` + Error string `json:"error,omitempty"` +} + +// MsgRequest contains the message to send. +type MsgRequest struct { + Payload []byte `json:"payload"` +} diff --git a/plugins/webapi/parameters.go b/plugins/webapi/parameters.go index d87284c8422b2f587c36a4dc6d9894a0ad3acc65..26e35904646077ea084c0100747103311e6c0236 100644 --- a/plugins/webapi/parameters.go +++ b/plugins/webapi/parameters.go @@ -5,9 +5,10 @@ import ( ) const ( - BIND_ADDRESS = "webapi.bindAddress" + // CfgBindAddress defines the config flag of the web API binding address. + CfgBindAddress = "webapi.bindAddress" ) func init() { - flag.String(BIND_ADDRESS, "127.0.0.1:8080", "the bind address for the web API") + flag.String(CfgBindAddress, "127.0.0.1:8080", "the bind address for the web API") } diff --git a/plugins/webapi/plugin.go b/plugins/webapi/plugin.go index 79365c8727fa71c9c031c3228c5af22e505567c9..24074bf6193a7e8272fe7fc93be44cf36c298a36 100644 --- a/plugins/webapi/plugin.go +++ b/plugins/webapi/plugin.go @@ -2,48 +2,90 @@ package webapi import ( "context" + "errors" + "net/http" + "sync" "time" - "github.com/iotaledger/goshimmer/packages/parameter" "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" "github.com/labstack/echo" ) -var PLUGIN = node.NewPlugin("WebAPI", node.Enabled, configure, run) -var log *logger.Logger +// PluginName is the name of the web API plugin. +const PluginName = "WebAPI" -var Server = echo.New() +var ( + // plugin is the plugin instance of the web API plugin. + plugin *node.Plugin + pluginOnce sync.Once + // server is the web API server. + server *echo.Echo + serverOnce sync.Once -func configure(plugin *node.Plugin) { - log = logger.NewLogger("WebAPI") - Server.HideBanner = true - Server.HidePort = true - Server.GET("/", IndexRequest) -} + log *logger.Logger +) -func run(plugin *node.Plugin) { - log.Info("Starting Web Server ...") +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + pluginOnce.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + }) + return plugin +} - daemon.BackgroundWorker("WebAPI Server", func(shutdownSignal <-chan struct{}) { - log.Info("Starting Web Server ... done") +// Server gets the server instance. +func Server() *echo.Echo { + serverOnce.Do(func() { + server = echo.New() + }) + return server +} - go func() { - if err := Server.Start(parameter.NodeConfig.GetString(BIND_ADDRESS)); err != nil { - log.Info("Stopping Web Server ... done") - } - }() +func configure(*node.Plugin) { + server = Server() + log = logger.NewLogger(PluginName) + // configure the server + server.HideBanner = true + server.HidePort = true + server.GET("/", IndexRequest) +} - <-shutdownSignal +func run(*node.Plugin) { + log.Infof("Starting %s ...", PluginName) + if err := daemon.BackgroundWorker("WebAPI server", worker, shutdown.PriorityWebAPI); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } +} - log.Info("Stopping Web Server ...") - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) - defer cancel() +func worker(shutdownSignal <-chan struct{}) { + defer log.Infof("Stopping %s ... done", PluginName) - if err := Server.Shutdown(ctx); err != nil { - log.Errorf("Couldn't stop server cleanly: %s", err.Error()) + stopped := make(chan struct{}) + bindAddr := config.Node().GetString(CfgBindAddress) + go func() { + log.Infof("%s started, bind-address=%s", PluginName, bindAddr) + if err := server.Start(bindAddr); err != nil { + if !errors.Is(err, http.ErrServerClosed) { + log.Errorf("Error serving: %s", err) + } + close(stopped) } - }, shutdown.ShutdownPriorityWebAPI) + }() + + // stop if we are shutting down or the server could not be started + select { + case <-shutdownSignal: + case <-stopped: + } + + log.Infof("Stopping %s ...", PluginName) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := server.Shutdown(ctx); err != nil { + log.Errorf("Error stopping: %s", err) + } } diff --git a/plugins/webapi/spammer/plugin.go b/plugins/webapi/spammer/plugin.go index 7aa057fc2fc18c85982fa27ef373b1f8a3b586b6..80a540d1d48755a58454a38d9eb4ea931c051c34 100644 --- a/plugins/webapi/spammer/plugin.go +++ b/plugins/webapi/spammer/plugin.go @@ -1,50 +1,49 @@ package spammer import ( - "net/http" + "sync" - "github.com/iotaledger/goshimmer/packages/transactionspammer" + "github.com/iotaledger/goshimmer/packages/binary/spammer" + "github.com/iotaledger/goshimmer/packages/shutdown" + "github.com/iotaledger/goshimmer/plugins/issuer" "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/hive.go/daemon" + "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" - "github.com/labstack/echo" ) -var PLUGIN = node.NewPlugin("Spammer", node.Disabled, configure) +var messageSpammer *spammer.Spammer -func configure(plugin *node.Plugin) { - webapi.Server.GET("spammer", WebApiHandler) -} - -func WebApiHandler(c echo.Context) error { +// PluginName is the name of the spammer plugin. +const PluginName = "Spammer" - var request Request - if err := c.Bind(&request); err != nil { - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } +var ( + // plugin is the plugin instance of the spammer plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger +) - switch request.Cmd { - case "start": - if request.Tps == 0 { - request.Tps = 1 - } - - transactionspammer.Stop() - transactionspammer.Start(request.Tps) - return c.JSON(http.StatusOK, Response{Message: "started spamming transactions"}) - case "stop": - transactionspammer.Stop() - return c.JSON(http.StatusOK, Response{Message: "stopped spamming transactions"}) - default: - return c.JSON(http.StatusBadRequest, Response{Error: "invalid cmd in request"}) - } +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) + }) + return plugin } -type Response struct { - Message string `json:"message"` - Error string `json:"error"` +func configure(plugin *node.Plugin) { + log = logger.NewLogger(PluginName) + messageSpammer = spammer.New(issuer.IssuePayload) + webapi.Server().GET("spammer", handleRequest) } -type Request struct { - Cmd string `json:"cmd"` - Tps uint64 `json:"tps"` +func run(*node.Plugin) { + if err := daemon.BackgroundWorker("Tangle", func(shutdownSignal <-chan struct{}) { + <-shutdownSignal + + messageSpammer.Shutdown() + }, shutdown.PrioritySpammer); err != nil { + log.Panicf("Failed to start as daemon: %s", err) + } } diff --git a/plugins/webapi/spammer/webapi.go b/plugins/webapi/spammer/webapi.go new file mode 100644 index 0000000000000000000000000000000000000000..bc92a6053dc2e863ac8cdc936c8779f9cd9a71b8 --- /dev/null +++ b/plugins/webapi/spammer/webapi.go @@ -0,0 +1,43 @@ +package spammer + +import ( + "net/http" + "time" + + "github.com/labstack/echo" +) + +func handleRequest(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + switch request.Cmd { + case "start": + if request.MPS == 0 { + request.MPS = 1 + } + + messageSpammer.Shutdown() + messageSpammer.Start(request.MPS, time.Second) + return c.JSON(http.StatusOK, Response{Message: "started spamming messages"}) + case "stop": + messageSpammer.Shutdown() + return c.JSON(http.StatusOK, Response{Message: "stopped spamming messages"}) + default: + return c.JSON(http.StatusBadRequest, Response{Error: "invalid cmd in request"}) + } +} + +// Response is the HTTP response of a spammer request. +type Response struct { + Message string `json:"message"` + Error string `json:"error"` +} + +// Request contains the parameters of a spammer request. +type Request struct { + Cmd string `json:"cmd"` + MPS int `json:"mps"` +} diff --git a/plugins/webapi/value/attachments/handler.go b/plugins/webapi/value/attachments/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..973ec5e87f7ae01ba4621969e8677982b02db77d --- /dev/null +++ b/plugins/webapi/value/attachments/handler.go @@ -0,0 +1,71 @@ +package attachments + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/labstack/echo" + "github.com/labstack/gommon/log" +) + +// Handler gets the value attachments. +func Handler(c echo.Context) error { + txnID, err := transaction.IDFromBase58(c.QueryParam("txnID")) + if err != nil { + log.Info(err) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + var valueObjs []ValueObject + + // get txn by txn id + txnObj := valuetransfers.Tangle().Transaction(txnID) + defer txnObj.Release() + if !txnObj.Exists() { + return c.JSON(http.StatusNotFound, Response{Error: "Transaction not found"}) + } + txn := utils.ParseTransaction(txnObj.Unwrap()) + + // get attachments by txn id + for _, attachmentObj := range valuetransfers.Tangle().Attachments(txnID) { + defer attachmentObj.Release() + if !attachmentObj.Exists() { + continue + } + attachment := attachmentObj.Unwrap() + + // get payload by payload id + payloadObj := valuetransfers.Tangle().Payload(attachment.PayloadID()) + defer payloadObj.Release() + if !payloadObj.Exists() { + continue + } + payload := payloadObj.Unwrap() + + // append value object + valueObjs = append(valueObjs, ValueObject{ + ID: payload.ID().String(), + ParentID0: payload.TrunkID().String(), + ParentID1: payload.BranchID().String(), + Transaction: txn, + }) + } + + return c.JSON(http.StatusOK, Response{Attachments: valueObjs}) +} + +// Response is the HTTP response from retrieving value objects. +type Response struct { + Attachments []ValueObject `json:"attachments,omitempty"` + Error string `json:"error,omitempty"` +} + +// ValueObject holds the information of a value object. +type ValueObject struct { + ID string `json:"id"` + ParentID0 string `json:"parent0_id"` + ParentID1 string `json:"parent1_id"` + Transaction utils.Transaction `json:"transaction"` +} diff --git a/plugins/webapi/value/gettransactionbyid/handler.go b/plugins/webapi/value/gettransactionbyid/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..769c9dda5ed8f4eaf68185679c3755f8cc90be9f --- /dev/null +++ b/plugins/webapi/value/gettransactionbyid/handler.go @@ -0,0 +1,53 @@ +package gettransactionbyid + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/labstack/echo" +) + +// Handler gets the transaction by id. +func Handler(c echo.Context) error { + txnID, err := transaction.IDFromBase58(c.QueryParam("txnID")) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + // get txn by txn id + cachedTxnMetaObj := valuetransfers.Tangle().TransactionMetadata(txnID) + defer cachedTxnMetaObj.Release() + if !cachedTxnMetaObj.Exists() { + return c.JSON(http.StatusNotFound, Response{Error: "Transaction not found"}) + } + cachedTxnObj := valuetransfers.Tangle().Transaction(txnID) + defer cachedTxnObj.Release() + if !cachedTxnObj.Exists() { + return c.JSON(http.StatusNotFound, Response{Error: "Transaction not found"}) + } + txn := utils.ParseTransaction(cachedTxnObj.Unwrap()) + + txnMeta := cachedTxnMetaObj.Unwrap() + txnMeta.Preferred() + return c.JSON(http.StatusOK, Response{ + Transaction: txn, + InclusionState: utils.InclusionState{ + Confirmed: txnMeta.Confirmed(), + Conflicting: txnMeta.Conflicting(), + Liked: txnMeta.Liked(), + Solid: txnMeta.Solid(), + Rejected: txnMeta.Rejected(), + Finalized: txnMeta.Finalized(), + Preferred: txnMeta.Preferred(), + }, + }) +} + +// Response is the HTTP response from retrieving transaction. +type Response struct { + Transaction utils.Transaction `json:"transaction,omitempty"` + InclusionState utils.InclusionState `json:"inclusion_state,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/plugins/webapi/value/plugin.go b/plugins/webapi/value/plugin.go new file mode 100644 index 0000000000000000000000000000000000000000..f9f4cb9b16b70f835a275b30528b27703e9a54d4 --- /dev/null +++ b/plugins/webapi/value/plugin.go @@ -0,0 +1,38 @@ +package value + +import ( + "sync" + + "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/goshimmer/plugins/webapi/value/attachments" + "github.com/iotaledger/goshimmer/plugins/webapi/value/gettransactionbyid" + "github.com/iotaledger/goshimmer/plugins/webapi/value/sendtransaction" + "github.com/iotaledger/goshimmer/plugins/webapi/value/testsendtxn" + "github.com/iotaledger/goshimmer/plugins/webapi/value/unspentoutputs" + "github.com/iotaledger/hive.go/node" +) + +// PluginName is the name of the web API DRNG endpoint plugin. +const PluginName = "WebAPI Value Endpoint" + +var ( + // plugin is the plugin instance of the web API DRNG endpoint plugin. + plugin *node.Plugin + once sync.Once +) + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) + }) + return plugin +} + +func configure(_ *node.Plugin) { + webapi.Server().GET("value/attachments", attachments.Handler) + webapi.Server().POST("value/unspentOutputs", unspentoutputs.Handler) + webapi.Server().POST("value/sendTransaction", sendtransaction.Handler) + webapi.Server().POST("value/testSendTxn", testsendtxn.Handler) + webapi.Server().GET("value/transactionByID", gettransactionbyid.Handler) +} diff --git a/plugins/webapi/value/sendtransaction/handler.go b/plugins/webapi/value/sendtransaction/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..dda59ab8c3d80fbe5c3b69a08dd82254acc81b6c --- /dev/null +++ b/plugins/webapi/value/sendtransaction/handler.go @@ -0,0 +1,49 @@ +package sendtransaction + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/labstack/echo" +) + +// Handler sends a transaction. +func Handler(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + // prepare transaction + tx, _, err := transaction.FromBytes(request.TransactionBytes) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + err = valuetransfers.Tangle().ValidateTransactionToAttach(tx) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + // Prepare value payload and send the message to tangle + payload := valuetransfers.ValueObjectFactory().IssueTransaction(tx) + _, err = issuer.IssuePayload(payload) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + return c.JSON(http.StatusOK, Response{TransactionID: tx.ID().String()}) +} + +// Request holds the transaction object(bytes) to send. +type Request struct { + TransactionBytes []byte `json:"txn_bytes"` +} + +// Response is the HTTP response from sending transaction. +type Response struct { + TransactionID string `json:"transaction_id,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/plugins/webapi/value/testsendtxn/handler.go b/plugins/webapi/value/testsendtxn/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..222e919ede5d6b2390bd0540475b5f0cde0be4f4 --- /dev/null +++ b/plugins/webapi/value/testsendtxn/handler.go @@ -0,0 +1,88 @@ +package testsendtxn + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/plugins/issuer" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/labstack/echo" + "github.com/labstack/gommon/log" +) + +// Handler sends a transaction. +func Handler(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + // prepare inputs + outputids := []transaction.OutputID{} + for _, in := range request.Inputs { + id, err := transaction.OutputIDFromBase58(in) + if err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + outputids = append(outputids, id) + } + inputs := transaction.NewInputs(outputids...) + + // prepare outputs + outmap := map[address.Address][]*balance.Balance{} + for _, out := range request.Outputs { + addr, err := address.FromBase58(out.Address) + if err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + // iterate balances + balances := []*balance.Balance{} + for _, b := range out.Balances { + // get token color + if b.Color == "IOTA" { + balances = append(balances, balance.New(balance.ColorIOTA, b.Value)) + } else { + color, _, err := balance.ColorFromBytes([]byte(b.Color)) + if err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + balances = append(balances, balance.New(color, b.Value)) + } + } + outmap[addr] = balances + } + outputs := transaction.NewOutputs(outmap) + + // prepare transaction + // Note: not signed + tx := transaction.New(inputs, outputs) + + // Prepare value payload and send the message to tangle + payload := valuetransfers.ValueObjectFactory().IssueTransaction(tx) + _, err := issuer.IssuePayload(payload) + if err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + return c.JSON(http.StatusOK, Response{TransactionID: tx.ID().String()}) +} + +// Request holds the inputs and outputs to send. +type Request struct { + Inputs []string `json:"inputs"` + Outputs []utils.Output `json:"outputs"` +} + +// Response is the HTTP response from sending transaction. +type Response struct { + TransactionID string `json:"transaction_id,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/plugins/webapi/value/unspentoutputs/handler.go b/plugins/webapi/value/unspentoutputs/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..1e0f08bb3447ce96ee372a36ae5721730318506a --- /dev/null +++ b/plugins/webapi/value/unspentoutputs/handler.go @@ -0,0 +1,99 @@ +package unspentoutputs + +import ( + "net/http" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/labstack/echo" + "github.com/labstack/gommon/log" +) + +// Handler gets the unspent outputs. +func Handler(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + log.Info(err.Error()) + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + var unspents []UnspentOutput + for _, strAddress := range request.Addresses { + address, err := address.FromBase58(strAddress) + if err != nil { + log.Info(err.Error()) + continue + } + + outputids := make([]OutputID, 0) + // get outputids by address + for id, cachedOutput := range valuetransfers.Tangle().OutputsOnAddress(address) { + // TODO: don't do this in a for + defer cachedOutput.Release() + output := cachedOutput.Unwrap() + cachedTxMeta := valuetransfers.Tangle().TransactionMetadata(output.TransactionID()) + // TODO: don't do this in a for + defer cachedTxMeta.Release() + + if output.ConsumerCount() == 0 { + // iterate balances + var b []utils.Balance + for _, balance := range output.Balances() { + b = append(b, utils.Balance{ + Value: balance.Value, + Color: balance.Color.String(), + }) + } + + inclusionState := utils.InclusionState{} + if cachedTxMeta.Exists() { + txMeta := cachedTxMeta.Unwrap() + inclusionState.Confirmed = txMeta.Confirmed() + inclusionState.Liked = txMeta.Liked() + inclusionState.Rejected = txMeta.Rejected() + inclusionState.Finalized = txMeta.Finalized() + inclusionState.Conflicting = txMeta.Conflicting() + inclusionState.Confirmed = txMeta.Confirmed() + } + outputids = append(outputids, OutputID{ + ID: id.String(), + Balances: b, + InclusionState: inclusionState, + }) + } + } + + unspents = append(unspents, UnspentOutput{ + Address: strAddress, + OutputIDs: outputids, + }) + } + + return c.JSON(http.StatusOK, Response{UnspentOutputs: unspents}) +} + +// Request holds the addresses to query. +type Request struct { + Addresses []string `json:"addresses,omitempty"` + Error string `json:"error,omitempty"` +} + +// Response is the HTTP response from retrieving value objects. +type Response struct { + UnspentOutputs []UnspentOutput `json:"unspent_outputs,omitempty"` + Error string `json:"error,omitempty"` +} + +// UnspentOutput holds the address and the corresponding unspent output ids +type UnspentOutput struct { + Address string `json:"address"` + OutputIDs []OutputID `json:"output_ids"` +} + +// OutputID holds the output id and its inclusion state +type OutputID struct { + ID string `json:"id"` + Balances []utils.Balance `json:"balances"` + InclusionState utils.InclusionState `json:"inclusion_state"` +} diff --git a/plugins/webapi/value/utils/transaction_handler.go b/plugins/webapi/value/utils/transaction_handler.go new file mode 100644 index 0000000000000000000000000000000000000000..9664c52df05f7f9ec2a7c975b9f6fa0ab6cd8fe8 --- /dev/null +++ b/plugins/webapi/value/utils/transaction_handler.go @@ -0,0 +1,74 @@ +package utils + +import ( + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" +) + +// ParseTransaction handle transaction json object. +func ParseTransaction(t *transaction.Transaction) (txn Transaction) { + var inputs []string + var outputs []Output + // process inputs + t.Inputs().ForEachAddress(func(currentAddress address.Address) bool { + inputs = append(inputs, currentAddress.String()) + return true + }) + + // process outputs: address + balance + t.Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { + var b []Balance + for _, balance := range balances { + b = append(b, Balance{ + Value: balance.Value, + Color: balance.Color.String(), + }) + } + t := Output{ + Address: address.String(), + Balances: b, + } + outputs = append(outputs, t) + + return true + }) + + return Transaction{ + Inputs: inputs, + Outputs: outputs, + Signature: t.SignatureBytes(), + DataPayload: t.GetDataPayload(), + } +} + +// Transaction holds the information of a transaction. +type Transaction struct { + Inputs []string `json:"inputs"` + Outputs []Output `json:"outputs"` + Signature []byte `json:"signature"` + DataPayload []byte `json:"data_payload"` +} + +// Output consists an address and balances +type Output struct { + Address string `json:"address"` + Balances []Balance `json:"balances"` +} + +// Balance holds the value and the color of token +type Balance struct { + Value int64 `json:"value"` + Color string `json:"color"` +} + +// InclusionState represents the different states of an OutputID +type InclusionState struct { + Solid bool `json:"solid,omitempty"` + Confirmed bool `json:"confirmed,omitempty"` + Rejected bool `json:"rejected,omitempty"` + Liked bool `json:"liked,omitempty"` + Conflicting bool `json:"conflicting,omitempty"` + Finalized bool `json:"finalized,omitempty"` + Preferred bool `json:"preferred,omitempty"` +} diff --git a/plugins/webauth/parameters.go b/plugins/webauth/parameters.go index 5084ce564029b3dc5e7d4ffc2ed8380e8fd1e3c9..e9c2eb20ff7e26c359d034346d72aea15ee61b3b 100644 --- a/plugins/webauth/parameters.go +++ b/plugins/webauth/parameters.go @@ -5,13 +5,16 @@ import ( ) const ( - WEBAPI_AUTH_USERNAME = "webapi.auth.username" - WEBAPI_AUTH_PASSWORD = "webapi.auth.password" - WEBAPI_AUTH_PRIVATE_KEY = "webapi.auth.privateKey" + // CfgWebAPIAuthUsername defines the config flag of the web API authentication username. + CfgWebAPIAuthUsername = "webapi.auth.username" + // CfgWebAPIAuthPassword defines the config flag of the web API authentication password. + CfgWebAPIAuthPassword = "webapi.auth.password" + // CfgWebAPIAuthPrivateKey defines the config flag of the web API authentication private key. + CfgWebAPIAuthPrivateKey = "webapi.auth.privateKey" ) func init() { - flag.String(WEBAPI_AUTH_USERNAME, "goshimmer", "username for the webapi") - flag.String(WEBAPI_AUTH_PASSWORD, "goshimmer", "password for the webapi") - flag.String(WEBAPI_AUTH_PRIVATE_KEY, "", "private key used to sign the JWTs") + flag.String(CfgWebAPIAuthUsername, "goshimmer", "username for the webapi") + flag.String(CfgWebAPIAuthPassword, "goshimmer", "password for the webapi") + flag.String(CfgWebAPIAuthPrivateKey, "", "private key used to sign the JWTs") } diff --git a/plugins/webauth/webauth.go b/plugins/webauth/webauth.go index 21e943fa9f10518118227f65c3e584c622df1af8..25321d29a2864c6ae277dfac83a4652935cd23e2 100644 --- a/plugins/webauth/webauth.go +++ b/plugins/webauth/webauth.go @@ -3,30 +3,45 @@ package webauth import ( "net/http" "strings" + "sync" "time" - "github.com/iotaledger/goshimmer/packages/parameter" + "github.com/dgrijalva/jwt-go" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/goshimmer/plugins/webapi" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" "github.com/labstack/echo" "github.com/labstack/echo/middleware" +) - "github.com/dgrijalva/jwt-go" +// PluginName is the name of the web API auth plugin. +const PluginName = "WebAPI Auth" + +var ( + // plugin is the plugin instance of the web API auth plugin. + plugin *node.Plugin + once sync.Once + log *logger.Logger + privateKey string ) -var PLUGIN = node.NewPlugin("WebAPI Auth", node.Disabled, configure) -var log *logger.Logger -var privateKey string +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Disabled, configure) + }) + return plugin +} func configure(plugin *node.Plugin) { - log = logger.NewLogger("WebAPI Auth") - privateKey = parameter.NodeConfig.GetString(WEBAPI_AUTH_PRIVATE_KEY) + log = logger.NewLogger(PluginName) + privateKey = config.Node().GetString(CfgWebAPIAuthPrivateKey) if len(privateKey) == 0 { panic("") } - webapi.Server.Use(middleware.JWTWithConfig(middleware.JWTConfig{ + webapi.Server().Use(middleware.JWTWithConfig(middleware.JWTConfig{ SigningKey: []byte(privateKey), Skipper: func(c echo.Context) bool { if strings.HasPrefix(c.Path(), "/ui") || c.Path() == "/login" { @@ -36,27 +51,33 @@ func configure(plugin *node.Plugin) { }, })) - webapi.Server.POST("/login", Handler) + webapi.Server().POST("/login", Handler) log.Info("WebAPI is now secured through JWT authentication") } +// Request defines the struct of the request. type Request struct { + // Username is the username of the request. Username string `json:"username"` + // Password is the password of the request. Password string `json:"password"` } +// Response defines the struct of the response. type Response struct { + // Token is the json web token. Token string `json:"token"` } +// Handler handles the web auth request. func Handler(c echo.Context) error { login := &Request{} if err := c.Bind(login); err != nil { return echo.ErrBadRequest } - if login.Username != parameter.NodeConfig.GetString(WEBAPI_AUTH_USERNAME) || - login.Password != parameter.NodeConfig.GetString(WEBAPI_AUTH_PASSWORD) { + if login.Username != config.Node().GetString(CfgWebAPIAuthUsername) || + login.Password != config.Node().GetString(CfgWebAPIAuthPassword) { return echo.ErrUnauthorized } diff --git a/runNetwork.sh b/runNetwork.sh deleted file mode 100755 index 6b918b58c375183bd2020757dce067f8e89197b1..0000000000000000000000000000000000000000 --- a/runNetwork.sh +++ /dev/null @@ -1,32 +0,0 @@ - -#!/bin/bash - -if [ -z "$1" ]; then - echo "Usage: `basename $0` number_of_nodes" - exit 0 -fi - -re='^[0-9]+$' -if ! [[ $1 =~ $re ]] ; then - echo "Error: Number of nodes given is not a number" >&2; exit 1 -fi - -PEERING_PORT=14630 -GOSSIP_PORT=15670 - -if [ -d testNodes ]; then - rm -r testNodes -fi -mkdir testNodes -cd testNodes - -for i in `seq 1 $1`; do - PEERING_PORT=$((PEERING_PORT+1)) - GOSSIP_PORT=$((GOSSIP_PORT+1)) - mkdir node_$i - mkdir node_$i/logs - cp ../goshimmer node_$i/ - cd node_$i - ./goshimmer --autopeering.port $PEERING_PORT --gossip.port $GOSSIP_PORT --autopeering.address 127.0.0.1 --autopeering.entryNodes 2TwlC5mtYVrCHNKG8zkFWmEUlL0pJPS1DOOC2U4yjwo=@127.0.0.1:14626 --node.LogLevel 4 --node.disablePlugins statusscreen --analysis.serverAddress 127.0.0.1:188 & - cd .. -done \ No newline at end of file diff --git a/snapshot.bin b/snapshot.bin new file mode 100644 index 0000000000000000000000000000000000000000..e40ce8ea6736cebfda287ac64e4fbfb920be0f96 Binary files /dev/null and b/snapshot.bin differ diff --git a/socket.io-client b/socket.io-client deleted file mode 160000 index 661f1e7fac2488b6d3d206f96bb59073c4c98b1c..0000000000000000000000000000000000000000 --- a/socket.io-client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 661f1e7fac2488b6d3d206f96bb59073c4c98b1c diff --git a/tools/docker-network/.gitignore b/tools/docker-network/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..cddda8ee7bfbc1ac0f24fef60c98d54da0b92be1 --- /dev/null +++ b/tools/docker-network/.gitignore @@ -0,0 +1,4 @@ +*.txt +grafana/grafana.db +grafana/plugins +grafana/png diff --git a/tools/docker-network/README.md b/tools/docker-network/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bb00f066e35603c5b9c62e976e6301aaddbcb6e2 --- /dev/null +++ b/tools/docker-network/README.md @@ -0,0 +1,30 @@ +# GoShimmer Network with Docker + + + +Running `./run.sh` spins up a GoShimmer network within Docker as schematically shown in the figure above. +`N` defines the number of `peer_replicas` and can be specified when running the network. +The peers can communicate freely within the Docker network +while the analysis dashboard, `master_peer's` dashboard and web API are reachable from the host system on the respective ports. + +The different containers (`entry_node`, `peer_master`, `peer_replica`) are based on the same config file +and separate config file and modified as necessary, respectively. + +## How to use as development tool +Using a standalone throwaway Docker network can be really helpful as a development tool. + +Prerequisites: +- Docker 17.12.0+ +- Docker compose: file format 3.5 + +Reachable from the host system +- analysis dashboard (autopeering visualizer): http://localhost:9000 +- `master_peer's` dashboard: http: http://localhost:8081 +- `master_peer's` web API: http: http://localhost:8080 + +It is therefore possible to send messages to the local network via the `master_peer` and observe log messages either +via `docker logs --follow CONTAINER` or all of them combined when running via: + +``` +./run.sh 5 +``` \ No newline at end of file diff --git a/tools/docker-network/builder/docker-compose.builder.yml b/tools/docker-network/builder/docker-compose.builder.yml new file mode 100644 index 0000000000000000000000000000000000000000..d94cbaf6073e5e20253963caa217bcac4795b6a1 --- /dev/null +++ b/tools/docker-network/builder/docker-compose.builder.yml @@ -0,0 +1,15 @@ +version: "3.5" + +services: + builder: + container_name: builder + image: golang:1.14.4 + working_dir: /tmp/goshimmer/ + entrypoint: go install main.go + volumes: + - ../../..:/tmp/goshimmer:ro + - goshimmer-cache:/go + +volumes: + goshimmer-cache: + name: goshimmer-cache \ No newline at end of file diff --git a/config.json b/tools/docker-network/config.docker.json similarity index 63% rename from config.json rename to tools/docker-network/config.docker.json index 43e4801b30afa8dc6198b189c894a62b9ef57b39..e1fabdcb193606a723c9e7caca0089dbbd43df12 100644 --- a/config.json +++ b/tools/docker-network/config.docker.json @@ -1,23 +1,24 @@ { "analysis": { "client": { - "serverAddress": "ressims.iota.cafe:188" + "serverAddress": "entry_node:1888" }, "server": { - "port": 0 + "bindAddress": "0.0.0.0:1888" }, - "httpServer": { - "bindAddress": "0.0.0.0:80" + "dashboard": { + "bindAddress": "0.0.0.0:9000", + "dev": false } }, "autopeering": { "entryNodes": [ - "V8LYtWWcPYYDTTXLeIEFjJEuWlsjDiI0+Pq/Cx9ai6g=@116.202.49.178:14626" + "DLoMdp3nJ7jnFT1K13R2m5nZN7ijLcmaZhCdTPJs2duo@entry_node:14626" ], "port": 14626 }, "dashboard": { - "bindAddress": "127.0.0.1:8081", + "bindAddress": "0.0.0.0:8081", "dev": false, "basic_auth": { "enabled": false, @@ -28,24 +29,22 @@ "database": { "directory": "mainnetdb" }, + "drng": { + "instanceId": 1, + "threshold": 3, + "distributedPubKey": "", + "committeeMembers": [] + }, "gossip": { "port": 14666 }, - "graph": { - "bindAddress": "127.0.0.1:8082", - "domain": "", - "networkName": "GoShimmer", - "socketIOPath": "socket.io-client/dist/socket.io.js", - "webrootPath": "IOTAtangle/webroot" - }, "logger": { "level": "info", "disableCaller": false, "disableStacktrace": false, "encoding": "console", "outputPaths": [ - "stdout", - "goshimmer.log" + "stdout" ], "disableEvents": true, "remotelog": { @@ -57,15 +56,20 @@ "externalAddress": "auto" }, "node": { - "disablePlugins": [], + "disablePlugins": "portcheck", "enablePlugins": [] }, + "pow": { + "difficulty": 2, + "numThreads": 1, + "timeout": "10s" + }, "webapi": { "auth": { "password": "goshimmer", "privateKey": "", "username": "goshimmer" }, - "bindAddress": "127.0.0.1:8080" + "bindAddress": "0.0.0.0:8080" } } diff --git a/tools/docker-network/docker-compose.yml b/tools/docker-network/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..8effbec25fce4bce5d728fdda3a46bda183af11f --- /dev/null +++ b/tools/docker-network/docker-compose.yml @@ -0,0 +1,110 @@ +version: "3.5" + +services: + mongodb_container: + image: mongo:latest + environment: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: password + ports: + - 27017:27017 + volumes: + - mongodb_data_container:/data/db + + entry_node: + container_name: entry_node + image: golang:1.14.4 + entrypoint: /go/bin/main + command: > + --config-dir=/tmp + --database.directory=/tmp/mainnetdb + --autopeering.seed=base58:8kPPCqaJFAt8BJtx6qw5PN8bKEM2XKXor6PxkmHf6bcr + --autopeering.entryNodes= + --analysis.server.bindAddress=0.0.0.0:1888 + --analysis.dashboard.bindAddress=0.0.0.0:9000 + --analysis.dashboard.dev=false + --analysis.dashboard.mongodb.enabled=true + --analysis.dashboard.mongodb.hostAddress=mongodb_container:27017 + --metrics.local=false + --metrics.global=true + --prometheus.bindAddress=0.0.0.0:9312 + --node.enablePlugins=analysis-server,analysis-dashboard,prometheus + --node.disablePlugins=portcheck,dashboard,analysis-client,gossip,drng,issuer,sync,messagelayer,pow,valuetransfers,webapi,webapibroadcastdataendpoint,webapifindtransactionhashesendpoint,webapigetneighborsendpoint,webapigettransactionobjectsbyhashendpoint,webapigettransactiontrytesbyhashendpoint + volumes: + - ./config.docker.json:/tmp/config.json:ro + - goshimmer-cache:/go + ports: + - "127.0.0.1:9000:9000/tcp" # analysis dashboard + - "127.0.0.1:9312:9312/tcp" # prometheus + expose: + - "1888/tcp" # analysis server (within Docker network) + + peer_master: + container_name: peer_master + image: golang:1.14.4 + entrypoint: /go/bin/main + command: > + --config-dir=/tmp + --database.directory=/tmp/mainnetdb + --node.enablePlugins=bootstrap,prometheus,spammer,faucet + --faucet.seed=7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih + --valueLayer.snapshot.file=/tmp/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin + volumes: + - ./config.docker.json:/tmp/config.json:ro + - goshimmer-cache:/go + - ../integration-tests/assets:/tmp/assets + ports: + - "127.0.0.1:8080:8080/tcp" # web API + - "127.0.0.1:8081:8081/tcp" # dashboard + - "127.0.0.1:9311:9311/tcp" # prometheus + depends_on: + - entry_node + + peer_replica: + image: golang:1.14.4 + entrypoint: /go/bin/main + command: > + --config-dir=/tmp + --database.directory=/tmp/mainnetdb + --node.enablePlugins=bootstrap + --valueLayer.snapshot.file=/tmp/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin + --node.disablePlugins=dashboard,portcheck + volumes: + - ./config.docker.json:/tmp/config.json:ro + - goshimmer-cache:/go + - ../integration-tests/assets:/tmp/assets + expose: + - "8080/tcp" # web API (within Docker network) + depends_on: + - entry_node + + prometheus: + image: prom/prometheus:latest + container_name: prometheus + ports: + - 9090:9090 + command: + - --config.file=/etc/prometheus/prometheus.yml + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro + depends_on: + - peer_master + + grafana: + image: grafana/grafana:latest + container_name: grafana + restart: unless-stopped + environment: + # path to provisioning definitions can only be defined as + # environment variables for grafana within docker + - GF_PATHS_PROVISIONING=/var/lib/grafana/provisioning + ports: + - 3000:3000 + user: "104" + volumes: + - ./grafana:/var/lib/grafana:rw + +volumes: + goshimmer-cache: + name: goshimmer-cache + mongodb_data_container: diff --git a/tools/docker-network/grafana/dashboards/global_dashboard.json b/tools/docker-network/grafana/dashboards/global_dashboard.json new file mode 100644 index 0000000000000000000000000000000000000000..8002cdf35ab588a61663bcecce59eaeaf9658787 --- /dev/null +++ b/tools/docker-network/grafana/dashboards/global_dashboard.json @@ -0,0 +1,916 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 1, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 31, + "panels": [], + "title": "Autopeering", + "type": "row" + }, + { + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 4, + "options": { + "displayMode": "gradient", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "sum by (nodeID) (global_nodes_neighbor_count)", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Neighbor Count", + "type": "bargauge" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 12, + "y": 1 + }, + "id": 9, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "global_network_diameter", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Diameter", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 29, + "panels": [], + "title": "Resources", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 10 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "7.0.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "global_nodes_info_cpu", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Load", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "percent", + "label": null, + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 12, + "y": 10 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "global_nodes_info_mem/1024/1024", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Consumption", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decmbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": true, + "datasource": "Prometheus", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 22, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "7.0.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "count by (conflictID) (sum by (conflictID, opinion) (global_conflict_outcome)) > 1", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Agreement Failures", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": "2", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 12, + "y": 1 + }, + "id": 25, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "count(count by (conflictID) (sum by (conflictID, opinion) (global_conflict_outcome)) > 1)", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Number of Agreement Failures", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 15, + "options": { + "displayMode": "lcd", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "(sum by (nodeID) (global_conflict_finalization_rounds))/(count by (nodeID) (global_conflict_finalization_rounds))", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Number of Rounds To Finalize", + "type": "bargauge" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 13, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "global_conflict_count", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Conflicts Seen", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 17, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "(sum by (nodeID, opinion) (global_conflict_initial_opinion{opinion=\"DISLIKE\"}))", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Initial Opinion DISLIKE", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 18, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "(sum by (nodeID, opinion) (global_conflict_initial_opinion{opinion=\"LIKE\"}))", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Initial Opinion LIKE", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 19, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "(sum by (nodeID, opinion) (global_conflict_outcome{opinion=\"DISLIKE\"}))", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Final Opinions DISLIKE", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 25 + }, + "id": 20, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "(sum by (nodeID, opinion) (global_conflict_outcome{opinion=\"LIKE\"}))", + "interval": "", + "legendFormat": "{{nodeID}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Final Opinions LIKE", + "type": "stat" + } + ], + "title": "FPC", + "type": "row" + } + ], + "refresh": "5s", + "schemaVersion": 25, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "GoShimmer Global Metrics", + "uid": "d6UQ22WGk", + "version": 3 +} diff --git a/tools/docker-network/grafana/dashboards/local_dashboard.json b/tools/docker-network/grafana/dashboards/local_dashboard.json new file mode 100644 index 0000000000000000000000000000000000000000..7e4d3cb1805ad1cdb26b8570d2ab5eacc0d24c33 --- /dev/null +++ b/tools/docker-network/grafana/dashboards/local_dashboard.json @@ -0,0 +1,2380 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Shows metrics of a single node.", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 1, + "links": [], + "panels": [ + { + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 57, + "title": "Status", + "type": "row" + }, + { + "datasource": "Prometheus", + "description": "Version number of node software.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 0, + "y": 1 + }, + "id": 48, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^version$/", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "iota_info_app", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "GoShimmer", + "transformations": [ + { + "id": "labelsToFields", + "options": {} + } + ], + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Describes if the node is in synced state.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [ + { + "from": "", + "id": 0, + "operator": "", + "text": "No", + "to": "", + "type": 1, + "value": "0" + }, + { + "from": "", + "id": 1, + "operator": "", + "text": "Yes", + "to": "", + "type": 1, + "value": "1" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 2, + "y": 1 + }, + "id": 22, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "sync", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Synced", + "transformations": [], + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Aggregated MPS for all message types in the communication layer.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "MPS" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 4, + "y": 1 + }, + "id": 30, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "irate(tangle_message_total_count[5m])", + "interval": "", + "legendFormat": "Total MPS", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total MPS", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Current CPU usage of the node.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 6, + "y": 1 + }, + "id": 53, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "process_cpu_usage", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Memory consumed by the node.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 8, + "y": 1 + }, + "id": 20, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "process_mem_usage_bytes/1024/1024", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Consumption", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Size of the ledger database.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 10, + "y": 1 + }, + "id": 58, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "db_size_bytes/1024/1024", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Database Size", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 55, + "panels": [], + "title": "MPS, Autopeering, Traffic, Resources", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 11, + "x": 0, + "y": 4 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "7.0.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"data\"}[5m])", + "interval": "", + "legendFormat": "Data Message Per Second", + "refId": "A" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"value\"}[5m])", + "interval": "", + "legendFormat": "Transaction Per Second", + "refId": "B" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"drng\"}[5m])", + "interval": "", + "legendFormat": "dRNG Messages Per Second", + "refId": "C" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"faucet\"}[5m])", + "interval": "", + "legendFormat": "Faucet Messages Per Second", + "refId": "D" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"netowrkdelay\"}[5m])", + "interval": "", + "legendFormat": "Network Delay Messages Per Second", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Message Per Second Per Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "MPS", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 13, + "x": 11, + "y": 4 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 0.5, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "autopeering_avg_distance", + "interval": "", + "legendFormat": "Average", + "refId": "A" + }, + { + "expr": "autopeering_max_distance", + "interval": "", + "legendFormat": "Max", + "refId": "B" + }, + { + "expr": "autopeering_min_distance", + "interval": "", + "legendFormat": "Min", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Autopeering Neighbor Distance", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": "Distance", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "Prometheus", + "description": "Number of currently connected neighbors.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 11, + "y": 12 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_neighbor_connections_count - autopeering_neighbor_drop_count", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Neighbors", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Calculated for each dropped neighbor.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 14, + "y": 12 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_avg_neighbor_connection_lifetime", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "AvgNeighbor Connection Lifetime", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Amount of newly registered neighbor connections.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 12 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_neighbor_connections_count", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "New Neighbor Connections", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Amount of neighbor connections dropped.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 21, + "y": 12 + }, + "id": 10, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_neighbor_drop_count", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Dropped Neighbor Connections", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Shows tips in message and value layer.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 11, + "x": 0, + "y": 15 + }, + "hiddenSeries": false, + "id": 52, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "tangle_message_tips_count", + "interval": "", + "legendFormat": "Message Layer Tips", + "refId": "A" + }, + { + "expr": "tangle_value_tips", + "interval": "", + "legendFormat": "Value Layer Tips", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Tips", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 7, + "x": 11, + "y": 16 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_cpu_usage", + "interval": "", + "legendFormat": "CPU Usage", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 16 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_mem_usage_bytes/1024/1024", + "interval": "", + "legendFormat": "Memory Consumption", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Consumption", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decmbytes", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 11, + "x": 0, + "y": 25 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(traffic_analysis_outbound_bytes[1m])", + "interval": "", + "legendFormat": "Analysis TX", + "refId": "A" + }, + { + "expr": "irate(traffic_autopeering_inbound_bytes[1m])", + "interval": "", + "legendFormat": "Autopeering RX", + "refId": "B" + }, + { + "expr": "irate(traffic_autopeering_outbound_bytes[1m])", + "interval": "", + "legendFormat": "Autopeering TX", + "refId": "C" + }, + { + "expr": "irate(traffic_fpc_inbound_bytes[1m])", + "interval": "", + "legendFormat": "FPC RX", + "refId": "D" + }, + { + "expr": "irate(traffic_fpc_outbound_bytes[1m])", + "interval": "", + "legendFormat": "FPC TX", + "refId": "E" + }, + { + "expr": "irate(traffic_gossip_inbound_bytes[1m])", + "interval": "", + "legendFormat": "Gossip RX", + "refId": "F" + }, + { + "expr": "irate(traffic_gossip_outbound_bytes[1m])", + "interval": "", + "legendFormat": "Gossip Tx", + "refId": "G" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "content": "\n# Total Network Traffic\n\n\nSince the start of the node.\n", + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 11, + "y": 25 + }, + "id": 61, + "mode": "markdown", + "timeFrom": null, + "timeShift": null, + "title": "", + "type": "text" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 11, + "y": 28 + }, + "id": 67, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_gossip_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Gossip TX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 13, + "y": 28 + }, + "id": 66, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_gossip_inbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Gossip RX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 15, + "y": 28 + }, + "id": 59, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_analysis_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Analysis", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 11, + "y": 30 + }, + "id": 63, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_autopeering_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Autopeering TX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 14, + "y": 30 + }, + "id": 62, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_autopeering_inbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Autopeering RX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 11, + "y": 32 + }, + "id": 64, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_fpc_inbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "FPC RX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 13, + "y": 32 + }, + "id": 65, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_fpc_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "FPC TX", + "type": "stat" + }, + { + "collapsed": false, + "datasource": "Prometheus", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 34, + "panels": [], + "title": "FPC", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 36 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "fpc_active_conflicts", + "interval": "", + "legendFormat": "Active Conflicts", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Conflicts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "Prometheus", + "description": "The average number of rounds it takes to finalize a conflict.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 12, + "y": 36 + }, + "id": 38, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "fpc_avg_rounds_to_finalize", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rounds To Finalize", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Number of finalized conflicts.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 16, + "y": 36 + }, + "id": 42, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "fpc_finalized_conflicts", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Finalized Conflicts", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Number of failed conflicts.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 19, + "y": 36 + }, + "id": 40, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "fpc_failed_conflicts", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failed Conflicts", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Describes how many FPC query requests the node has received.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 44 + }, + "hiddenSeries": false, + "id": 44, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_queries_received[5m])", + "interval": "", + "legendFormat": "FPC Queries RX", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Queries RX", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 44 + }, + "hiddenSeries": false, + "id": 50, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_query_replies_not_received[5m])", + "interval": "", + "legendFormat": "FPC Queries TX Failed", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Queries TX Failed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Describes how many FPC opinions were requested from the node.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 52 + }, + "hiddenSeries": false, + "id": 49, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_queries_opinion_received[5m])", + "interval": "", + "legendFormat": "FPC Conflict Queries RX", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Conflict Queries RX", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Conflict Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 52 + }, + "hiddenSeries": false, + "id": 46, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_query_opinion_replies_not_received[5m])", + "interval": "", + "legendFormat": "FPC Conflict Queries TX Failed", + "refId": "A" + }, + { + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Conflict Queries TX Failed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Conflict Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 25, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "GoShimmer Local Metrics", + "uid": "kjOQZ2ZMk", + "version": 5 +} diff --git a/tools/docker-network/grafana/provisioning/dashboards/dashboards.yaml b/tools/docker-network/grafana/provisioning/dashboards/dashboards.yaml new file mode 100755 index 0000000000000000000000000000000000000000..305b0dcb2cd27fd2d36670f3afe59321d6296af6 --- /dev/null +++ b/tools/docker-network/grafana/provisioning/dashboards/dashboards.yaml @@ -0,0 +1,24 @@ +apiVersion: 1 + +providers: + # <string> an unique provider name. Required + - name: 'Goshimmer Local Metrics' + # <int> Org id. Default to 1 + orgId: 1 + # <string> name of the dashboard folder. + folder: '' + # <string> folder UID. will be automatically generated if not specified + folderUid: '' + # <string> provider type. Default to 'file' + type: file + # <bool> disable dashboard deletion + disableDeletion: false + # <bool> enable dashboard editing + editable: true + # <int> how often Grafana will scan for changed dashboards + updateIntervalSeconds: 10 + # <bool> allow updating provisioned dashboards from the UI + allowUiUpdates: true + options: + # <string, required> path to dashboard files on disk. Required when using the 'file' type + path: /var/lib/grafana/dashboards diff --git a/tools/docker-network/grafana/provisioning/datasources/datasources.yaml b/tools/docker-network/grafana/provisioning/datasources/datasources.yaml new file mode 100755 index 0000000000000000000000000000000000000000..58b53f86acb2f0ec9123cacc7f80f2a480883bf3 --- /dev/null +++ b/tools/docker-network/grafana/provisioning/datasources/datasources.yaml @@ -0,0 +1,52 @@ +# config file version +apiVersion: 1 + +# list of datasources to insert/update depending +# what's available in the database +datasources: + # <string, required> name of the datasource. Required + - name: Prometheus + # <string, required> datasource type. Required + type: prometheus + # <string, required> access mode. proxy or direct (Server or Browser in the UI). Required + access: direct + # <int> org id. will default to orgId 1 if not specified + orgId: 1 + # <string> custom UID which can be used to reference this datasource in other parts of the configuration, if not specified will be generated automatically + uid: + # <string> url + url: http://localhost:9090 + # <string> Deprecated, use secureJsonData.password + password: + # <string> database user, if used + user: + # <string> database name, if used + database: + # <bool> enable/disable basic auth + basicAuth: + # <string> basic auth username + basicAuthUser: + # <string> Deprecated, use secureJsonData.basicAuthPassword + basicAuthPassword: + # <bool> enable/disable with credentials headers + withCredentials: + # <bool> mark as default datasource. Max one per org + isDefault: + # <map> fields that will be converted to json and stored in jsonData + jsonData: + graphiteVersion: '1.1' + tlsAuth: true + tlsAuthWithCACert: true + timeInterval: '1s' + # <string> json object of data that will be encrypted. + secureJsonData: + tlsCACert: '...' + tlsClientCert: '...' + tlsClientKey: '...' + # <string> database password, if used + password: + # <string> basic auth password + basicAuthPassword: + version: 1 + # <bool> allow users to edit datasources from the UI. + editable: true diff --git a/tools/docker-network/grafana/provisioning/notifiers/notifiers.yaml b/tools/docker-network/grafana/provisioning/notifiers/notifiers.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tools/docker-network/prometheus.yml b/tools/docker-network/prometheus.yml new file mode 100644 index 0000000000000000000000000000000000000000..3185565acdaaa4afbb39321577cd1fa098dabc78 --- /dev/null +++ b/tools/docker-network/prometheus.yml @@ -0,0 +1,7 @@ +scrape_configs: + - job_name: peer_master + scrape_interval: 5s + static_configs: + - targets: + - peer_master:9311 + - entry_node:9312 \ No newline at end of file diff --git a/tools/docker-network/run.sh b/tools/docker-network/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..903fe83aa74b6873a379b242eff5a925c319f0c5 --- /dev/null +++ b/tools/docker-network/run.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [[ $# -eq 0 ]] ; then + echo 'Call with ./run replicas' + exit 0 +fi + +REPLICAS=$1 + +echo "Build GoShimmer" +docker-compose -f builder/docker-compose.builder.yml up + +echo "Run GoShimmer network" +docker-compose up --scale peer_replica=$REPLICAS + +echo "Clean up docker network" +docker-compose down \ No newline at end of file diff --git a/tools/double-spend/double-spend.go b/tools/double-spend/double-spend.go new file mode 100644 index 0000000000000000000000000000000000000000..cab37ea885be28bcfb8a47cce91812cf0b73b44d --- /dev/null +++ b/tools/double-spend/double-spend.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "net/http" + "time" + + "github.com/iotaledger/goshimmer/client" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/mr-tron/base58" +) + +func main() { + + client := client.NewGoShimmerAPI("http://localhost:8080", http.Client{Timeout: 30 * time.Second}) + + // genesis wallet + genesisSeedBytes, err := base58.Decode("7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih") + if err != nil { + fmt.Println(err) + } + + const genesisBalance = 1000000000 + genesisWallet := wallet.New(genesisSeedBytes) + genesisAddr := genesisWallet.Seed().Address(0) + genesisOutputID := transaction.NewOutputID(genesisAddr, transaction.GenesisID) + + // issue transactions which spend the same genesis output in all partitions + conflictingTxs := make([]*transaction.Transaction, 2) + conflictingTxIDs := make([]string, 2) + receiverSeeds := make([]*wallet.Seed, 2) + for i := range conflictingTxs { + + // create a new receiver wallet for the given conflict + receiverSeeds[i] = wallet.NewSeed() + destAddr := receiverSeeds[i].Address(0) + + tx := transaction.New( + transaction.NewInputs(genesisOutputID), + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + destAddr: { + {Value: genesisBalance, Color: balance.ColorIOTA}, + }, + })) + tx = tx.Sign(signaturescheme.ED25519(*genesisWallet.Seed().KeyPair(0))) + conflictingTxs[i] = tx + + valueObject := valuepayload.New(valuepayload.GenesisID, valuepayload.GenesisID, tx) + + // issue the value object + txID, err := client.SendPayload(valueObject.Bytes()) + if err != nil { + fmt.Println(err) + } + conflictingTxIDs[i] = txID + fmt.Printf("issued conflict transaction %s\n", txID) + //time.Sleep(7 * time.Second) + } +} diff --git a/tools/entry-node/.gitignore b/tools/entry-node/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..4c49bd78f1d08f2bc09fa0bd8191ed38b7dce5e3 --- /dev/null +++ b/tools/entry-node/.gitignore @@ -0,0 +1 @@ +.env diff --git a/tools/entry-node/README.md b/tools/entry-node/README.md new file mode 100644 index 0000000000000000000000000000000000000000..086371ec43698fd86f219b178ae2763d414b4ac9 --- /dev/null +++ b/tools/entry-node/README.md @@ -0,0 +1,38 @@ +# Docker entry node + +This folder contains the scripts for running a GoShimmer entry node with Docker. + +It builds the Docker image directly from the specified Git tag (such as `v0.1.3`, `master`, `af0ae41d5bfd607123e6cbae271da839a050b220`, ...) and does not depend on the locally checked out version. +The GoShimmer DB is persisted in a named Docker volume. + +The entry node exposes the following ports on the host: +- 14626/udp (Autopeering) +- 188/tcp (Analysis Server) +- 80/tcp (Analysis Dashboard) + +## How to run + +### Create the Docker volume +Before starting an entry node for the specified git tag the first time, a Docker volume needs to be created. +This is only needed once and can be done via the following command: +```sh +TAG=tag ./create-volume.sh +``` +The environment variable `TAG` contains the Git tag of the desired GoShimmer version. +### Run the GoShimmer entry node +To start the actual entry node, run the following: +```sh +TAG=tag SEED=seed docker-compose up -d --build +``` +The optional environment variable `SEED` contains the autopeering seed of the entry node in Base64 encoding. +If `SEED` is not set, the seed will be taken from the DB (if present) in the volume. +As such, `SEED` is only required once when setting or changing the seed of the entry node. + +Alternatively to providing the variables in the command, create the file `.env` in the base folder with the following content: +``` +# Git tag of the entry node version +TAG=tag + +# Autopeering seed used for the entry node +SEED=seed +``` diff --git a/tools/entry-node/create-volume.sh b/tools/entry-node/create-volume.sh new file mode 100755 index 0000000000000000000000000000000000000000..5bde3f24dd7e889ec6e717c914fe0bdb74f69466 --- /dev/null +++ b/tools/entry-node/create-volume.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +[ -z "$TAG" ] && echo "TAG not set" >&2 && exit 1 + +# create docker volume and fix permissions +docker run --rm -v entrynode_db-"$TAG":/volume busybox chown -R 65532:65532 /volume diff --git a/tools/entry-node/docker-compose.yml b/tools/entry-node/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..64ba01d30ab0bb5b7134b0a4c1045ef50db1a827 --- /dev/null +++ b/tools/entry-node/docker-compose.yml @@ -0,0 +1,29 @@ +version: "3" + +services: + entrynode: + image: "iotaledger/goshimmer-entrynode:${TAG}" + container_name: goshimmer-entrynode + build: + context: "https://github.com/iotaledger/goshimmer.git#${TAG}" + volumes: + - entrynode:/tmp/mainnetdb + - entrynode:/mainnetdb + ports: + - "1888:188/tcp" # analysis server + - "8080:80/tcp" # analysis dashboard + - "14626:14626/udp" # autopeering discovery + restart: unless-stopped + command: > + --autopeering.seed=${SEED} + --autopeering.entryNodes= + --analysis.client.serverAddress= + --analysis.server.bindAddress=0.0.0.0:1888 + --analysis.dashboard.bindAddress=0.0.0.0:8080 + --node.enablePlugins=analysis-server,analysis-dashboard + --node.disablePlugins=analysis-client,gossip,portcheck,spa,dashboard,webapi,webapibroadcastdataendpoint,webapifindtransactionhashesendpoint,webapigetneighborsendpoint,webapigettransactionobjectsbyhashendpoint,webapigettransactiontrytesbyhashendpoint + +volumes: + entrynode: + external: + name: entrynode_db-${TAG} diff --git a/tools/genesis-snapshot/main.go b/tools/genesis-snapshot/main.go new file mode 100644 index 0000000000000000000000000000000000000000..1a887e139ba8e606516899e781401e2700361de0 --- /dev/null +++ b/tools/genesis-snapshot/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "log" + "os" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + flag "github.com/spf13/pflag" + "github.com/spf13/viper" +) + +const ( + cfgGenesisTokenAmount = "token-amount" + cfgSnapshotFileName = "snapshot-file" + defaultSnapshotFileName = "./snapshot.bin" +) + +func init() { + flag.Int(cfgGenesisTokenAmount, 1000000000000000, "the amount of tokens to add to the genesis output") + flag.String(cfgSnapshotFileName, defaultSnapshotFileName, "the name of the generated snapshot file") +} + +func main() { + flag.Parse() + if err := viper.BindPFlags(flag.CommandLine); err != nil { + panic(err) + } + genesisTokenAmount := viper.GetInt64(cfgGenesisTokenAmount) + snapshotFileName := viper.GetString(cfgSnapshotFileName) + log.Printf("creating snapshot %s...", snapshotFileName) + + genesisWallet := wallet.New() + genesisAddress := genesisWallet.Seed().Address(0) + + log.Println("genesis:") + log.Printf("-> seed (base58): %s", genesisWallet.Seed().String()) + log.Printf("-> output address (base58): %s", genesisAddress.String()) + log.Printf("-> output id (base58): %s", transaction.NewOutputID(genesisAddress, transaction.GenesisID)) + log.Printf("-> token amount: %d", genesisTokenAmount) + + snapshot := tangle.Snapshot{ + transaction.GenesisID: { + genesisAddress: { + balance.New(balance.ColorIOTA, genesisTokenAmount), + }, + }, + } + + f, err := os.OpenFile(snapshotFileName, os.O_RDWR|os.O_CREATE, 0666) + if err != nil { + log.Fatal("unable to create snapshot file", err) + } + defer f.Close() + + if _, err = snapshot.WriteTo(f); err != nil { + log.Fatal("unable to write snapshot content to file", err) + } + + log.Printf("created %s, bye", snapshotFileName) +} diff --git a/tools/integration-tests/README.md b/tools/integration-tests/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c24d2c58cf0ca8e09ebf8a194cbc752d4121affb --- /dev/null +++ b/tools/integration-tests/README.md @@ -0,0 +1,39 @@ +# Integration tests with Docker + + + +Running the integration tests spins up a `tester` container within which every test can specify its own GoShimmer network with Docker as schematically shown in the figure above. + +Peers can communicate freely within their Docker network and this is exactly how the tests are run using the `tester` container. +Test can be written in regular Go style while the framework provides convenience functions to create a new network, access a specific peer's web API or logs. + +## How to run +Prerequisites: +- Docker 17.12.0+ +- Docker compose: file format 3.5 + +``` +# Mac & Linux +./runTests.sh +``` +The tests produce `*.log` files for every networks' peer in the `logs` folder after every run. + +On GitHub logs of every peer are stored as artifacts and can be downloaded for closer inspection once the job finishes. + +## Creating tests +Tests can be written in regular Go style. Each tested component should reside in its own test file in `tester/tests`. +`main_test` with its `TestMain` function is executed before any test in the package and initializes the integration test framework. + +Each test has to specify its network where the tests are run. This can be done via the framework at the beginning of a test. +```go +// create a network with name 'testnetwork' with 6 peers and wait until every peer has at least 3 neighbors +n := f.CreateNetwork("testnetwork", 6, 3) +// must be called to create log files and properly clean up +defer n.Shutdown() +``` + +## Other tips +Useful for development is to only execute the test you're currently building. For that matter, simply modify the `docker-compose.yml` file as follows: +```yaml +entrypoint: go test ./tests -run <YOUR_TEST_NAME> -v -mod=readonly +``` \ No newline at end of file diff --git a/tools/integration-tests/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin b/tools/integration-tests/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin new file mode 100644 index 0000000000000000000000000000000000000000..2e55197593a21cb650727fb4a4f9c58e92acbc4d Binary files /dev/null and b/tools/integration-tests/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin differ diff --git a/tools/integration-tests/assets/entrypoint.sh b/tools/integration-tests/assets/entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..a5ec0407b81c57c162ead53b0494c224f3c76ae7 --- /dev/null +++ b/tools/integration-tests/assets/entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/bash +echo "copying assets into shared volume..." +rm -rf /assets/* +cp -rp /tmp/assets/* /assets +chmod 777 /assets/* +echo "assets:" +ls /assets +echo "running tests..." +go test ./tests/"${TEST_NAME}" -v -timeout 30m diff --git a/tools/integration-tests/logs/.gitkeep b/tools/integration-tests/logs/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tools/integration-tests/runTests.sh b/tools/integration-tests/runTests.sh new file mode 100755 index 0000000000000000000000000000000000000000..da9004da397c9c8ca8e07bfa4447bb64636be337 --- /dev/null +++ b/tools/integration-tests/runTests.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +TEST_NAMES='autopeering common drng message value consensus faucet' + +echo "Build GoShimmer image" +docker build -t iotaledger/goshimmer ../../. + +echo "Pull additional Docker images" +docker pull angelocapossele/drand:latest +docker pull gaiaadm/pumba:0.7.2 +docker pull gaiadocker/iproute2:latest + +echo "Run integration tests" + +for name in $TEST_NAMES +do + TEST_NAME=$name docker-compose -f tester/docker-compose.yml up --abort-on-container-exit --exit-code-from tester --build + docker logs tester &> logs/"$name"_tester.log +done + +echo "Clean up" +docker-compose -f tester/docker-compose.yml down +docker rm -f $(docker ps -a -q -f ancestor=gaiadocker/iproute2) diff --git a/tools/integration-tests/tester/docker-compose.yml b/tools/integration-tests/tester/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..578b04c356c583a23f55591e9801c2c7dd7c443e --- /dev/null +++ b/tools/integration-tests/tester/docker-compose.yml @@ -0,0 +1,23 @@ +version: "3.5" + +services: + tester: + container_name: tester + image: golang:1.14.4 + working_dir: /tmp/goshimmer/tools/integration-tests/tester + command: /tmp/assets/entrypoint.sh + environment: + - TEST_NAME=${TEST_NAME} + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ../../..:/tmp/goshimmer:rw + - ../logs:/tmp/logs + - ../assets:/tmp/assets + - goshimmer-testing-cache:/go + - goshimmer-testing-assets:/assets + +volumes: + goshimmer-testing-cache: + name: goshimmer-testing-cache + goshimmer-testing-assets: + name: goshimmer-testing-assets \ No newline at end of file diff --git a/tools/integration-tests/tester/framework/docker.go b/tools/integration-tests/tester/framework/docker.go new file mode 100644 index 0000000000000000000000000000000000000000..cbf017797caf4426122ff700ac075ecd6ce6be44 --- /dev/null +++ b/tools/integration-tests/tester/framework/docker.go @@ -0,0 +1,259 @@ +package framework + +import ( + "context" + "fmt" + "io" + "strings" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/strslice" + "github.com/docker/docker/client" + "github.com/docker/go-connections/nat" +) + +// newDockerClient creates a Docker client that communicates via the Docker socket. +func newDockerClient() (*client.Client, error) { + return client.NewClient( + "unix:///var/run/docker.sock", + "", + nil, + nil, + ) +} + +// DockerContainer is a wrapper object for a Docker container. +type DockerContainer struct { + client *client.Client + id string +} + +// NewDockerContainer creates a new DockerContainer. +func NewDockerContainer(c *client.Client) *DockerContainer { + return &DockerContainer{client: c} +} + +// NewDockerContainerFromExisting creates a new DockerContainer from an already existing Docker container by name. +func NewDockerContainerFromExisting(c *client.Client, name string) (*DockerContainer, error) { + containers, err := c.ContainerList(context.Background(), types.ContainerListOptions{}) + if err != nil { + return nil, err + } + + for _, cont := range containers { + if cont.Names[0] == name { + return &DockerContainer{ + client: c, + id: cont.ID, + }, nil + } + } + + return nil, fmt.Errorf("could not find container with name '%s'", name) +} + +// CreateGoShimmerEntryNode creates a new container with the GoShimmer entry node's configuration. +func (d *DockerContainer) CreateGoShimmerEntryNode(name string, seed string) error { + containerConfig := &container.Config{ + Image: "iotaledger/goshimmer", + ExposedPorts: nil, + Cmd: strslice.StrSlice{ + "--skip-config=true", + "--logger.level=debug", + fmt.Sprintf("--node.disablePlugins=%s", disabledPluginsEntryNode), + "--autopeering.entryNodes=", + fmt.Sprintf("--autopeering.seed=base58:%s", seed), + }, + } + + return d.CreateContainer(name, containerConfig) +} + +// CreateGoShimmerPeer creates a new container with the GoShimmer peer's configuration. +func (d *DockerContainer) CreateGoShimmerPeer(config GoShimmerConfig) error { + // configure GoShimmer container instance + containerConfig := &container.Config{ + Image: "iotaledger/goshimmer", + ExposedPorts: nat.PortSet{ + nat.Port("8080/tcp"): {}, + }, + Cmd: strslice.StrSlice{ + "--skip-config=true", + "--logger.level=debug", + fmt.Sprintf("--valueLayer.fcob.averageNetworkDelay=%d", ParaFCoBAverageNetworkDelay), + fmt.Sprintf("--node.disablePlugins=%s", config.DisabledPlugins), + fmt.Sprintf("--pow.difficulty=%d", ParaPoWDifficulty), + fmt.Sprintf("--gracefulshutdown.waitToKillTime=%d", ParaWaitToKill), + fmt.Sprintf("--node.enablePlugins=%s", func() string { + var plugins []string + if config.Bootstrap { + plugins = append(plugins, "Bootstrap") + } + if config.Faucet { + plugins = append(plugins, "faucet") + } + return strings.Join(plugins[:], ",") + }()), + // define the faucet seed in case the faucet dApp is enabled + func() string { + if !config.Faucet { + return "" + } + return fmt.Sprintf("--faucet.seed=%s", genesisSeedBase58) + }(), + fmt.Sprintf("--faucet.tokensPerRequest=%d", ParaFaucetTokensPerRequest), + fmt.Sprintf("--valueLayer.snapshot.file=%s", config.SnapshotFilePath), + fmt.Sprintf("--bootstrap.initialIssuance.timePeriodSec=%d", config.BootstrapInitialIssuanceTimePeriodSec), + "--webapi.bindAddress=0.0.0.0:8080", + fmt.Sprintf("--autopeering.seed=base58:%s", config.Seed), + fmt.Sprintf("--autopeering.entryNodes=%s@%s:14626", config.EntryNodePublicKey, config.EntryNodeHost), + fmt.Sprintf("--drng.instanceId=%d", config.DRNGInstance), + fmt.Sprintf("--drng.threshold=%d", config.DRNGThreshold), + fmt.Sprintf("--drng.committeeMembers=%s", config.DRNGCommittee), + fmt.Sprintf("--drng.distributedPubKey=%s", config.DRNGDistKey), + }, + } + + return d.CreateContainer(config.Name, containerConfig, &container.HostConfig{ + Binds: []string{"goshimmer-testing-assets:/assets:rw"}, + }) +} + +// CreateDrandMember creates a new container with the drand configuration. +func (d *DockerContainer) CreateDrandMember(name string, goShimmerAPI string, leader bool) error { + // configure drand container instance + env := []string{} + if leader { + env = append(env, "LEADER=1") + } + env = append(env, "GOSHIMMER=http://"+goShimmerAPI) + containerConfig := &container.Config{ + Image: "angelocapossele/drand:latest", + ExposedPorts: nat.PortSet{ + nat.Port("8000/tcp"): {}, + }, + Env: env, + Entrypoint: strslice.StrSlice{"/data/client-script.sh"}, + } + + return d.CreateContainer(name, containerConfig) +} + +// CreatePumba creates a new container with Pumba configuration. +func (d *DockerContainer) CreatePumba(name string, containerName string, targetIPs []string) error { + hostConfig := &container.HostConfig{ + Binds: strslice.StrSlice{"/var/run/docker.sock:/var/run/docker.sock:ro"}, + } + + cmd := strslice.StrSlice{ + "--log-level=debug", + "netem", + "--duration=100m", + } + + for _, ip := range targetIPs { + targetFlag := "--target=" + ip + cmd = append(cmd, targetFlag) + } + + slice := strslice.StrSlice{ + "--tc-image=gaiadocker/iproute2", + "loss", + "--percent=100", + containerName, + } + cmd = append(cmd, slice...) + + containerConfig := &container.Config{ + Image: "gaiaadm/pumba:0.7.2", + Cmd: cmd, + } + + return d.CreateContainer(name, containerConfig, hostConfig) +} + +// CreateContainer creates a new container with the given configuration. +func (d *DockerContainer) CreateContainer(name string, containerConfig *container.Config, hostConfigs ...*container.HostConfig) error { + var hostConfig *container.HostConfig + if len(hostConfigs) > 0 { + hostConfig = hostConfigs[0] + } + + resp, err := d.client.ContainerCreate(context.Background(), containerConfig, hostConfig, nil, name) + if err != nil { + return err + } + + d.id = resp.ID + return nil +} + +// ConnectToNetwork connects a container to an existent network in the docker host. +func (d *DockerContainer) ConnectToNetwork(networkID string) error { + return d.client.NetworkConnect(context.Background(), networkID, d.id, nil) +} + +// DisconnectFromNetwork disconnects a container from an existent network in the docker host. +func (d *DockerContainer) DisconnectFromNetwork(networkID string) error { + return d.client.NetworkDisconnect(context.Background(), networkID, d.id, true) +} + +// Start sends a request to the docker daemon to start a container. +func (d *DockerContainer) Start() error { + return d.client.ContainerStart(context.Background(), d.id, types.ContainerStartOptions{}) +} + +// Remove kills and removes a container from the docker host. +func (d *DockerContainer) Remove() error { + return d.client.ContainerRemove(context.Background(), d.id, types.ContainerRemoveOptions{Force: true}) +} + +// Stop stops a container without terminating the process. +// The process is blocked until the container stops or the timeout expires. +func (d *DockerContainer) Stop() error { + duration := 30 * time.Second + return d.client.ContainerStop(context.Background(), d.id, &duration) +} + +// ExitStatus returns the exit status according to the container information. +func (d *DockerContainer) ExitStatus() (int, error) { + resp, err := d.client.ContainerInspect(context.Background(), d.id) + if err != nil { + return -1, err + } + + return resp.State.ExitCode, nil +} + +// IP returns the IP address according to the container information for the given network. +func (d *DockerContainer) IP(network string) (string, error) { + resp, err := d.client.ContainerInspect(context.Background(), d.id) + if err != nil { + return "", err + } + + for name, v := range resp.NetworkSettings.Networks { + if name == network { + return v.IPAddress, nil + } + } + + return "", fmt.Errorf("IP address in %s could not be determined", network) +} + +// Logs returns the logs of the container as io.ReadCloser. +func (d *DockerContainer) Logs() (io.ReadCloser, error) { + options := types.ContainerLogsOptions{ + ShowStdout: true, + ShowStderr: true, + Since: "", + Timestamps: false, + Follow: false, + Tail: "", + Details: false, + } + + return d.client.ContainerLogs(context.Background(), d.id, options) +} diff --git a/tools/integration-tests/tester/framework/drand.go b/tools/integration-tests/tester/framework/drand.go new file mode 100644 index 0000000000000000000000000000000000000000..67277a3971609707002935c94d9c1a78c20ca1d9 --- /dev/null +++ b/tools/integration-tests/tester/framework/drand.go @@ -0,0 +1,32 @@ +package framework + +import ( + "fmt" + + "github.com/drand/drand/core" +) + +// Drand represents a drand node (committe member) inside the Docker network +type Drand struct { + // name of the drand instance, Docker container and hostname + name string + + // Web API of this drand node + *core.Client + + // the DockerContainer that this peer is running in + *DockerContainer +} + +// newDrand creates a new instance of Drand with the given information. +func newDrand(name string, dockerContainer *DockerContainer) *Drand { + return &Drand{ + name: name, + Client: core.NewGrpcClient(), + DockerContainer: dockerContainer, + } +} + +func (d *Drand) String() string { + return fmt.Sprintf("Drand:{%s}", d.name) +} diff --git a/tools/integration-tests/tester/framework/drngnetwork.go b/tools/integration-tests/tester/framework/drngnetwork.go new file mode 100644 index 0000000000000000000000000000000000000000..2f3031ceab001dc7d8e415bb41dce956673cf7b5 --- /dev/null +++ b/tools/integration-tests/tester/framework/drngnetwork.go @@ -0,0 +1,152 @@ +package framework + +import ( + "encoding/hex" + "fmt" + "log" + "time" + + "github.com/docker/docker/client" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" +) + +// DRNGNetwork represents a complete drand with GoShimmer network within Docker. +// Including an entry node, drand members and arbitrary many peers. +type DRNGNetwork struct { + network *Network + members []*Drand + distKey []byte +} + +// newDRNGNetwork returns a DRNGNetwork instance, creates its underlying Docker network and adds the tester container to the network. +func newDRNGNetwork(dockerClient *client.Client, name string, tester *DockerContainer) (*DRNGNetwork, error) { + network, err := newNetwork(dockerClient, name, tester) + if err != nil { + return nil, err + } + return &DRNGNetwork{ + network: network, + }, nil +} + +// CreatePeer creates a new peer/GoShimmer node in the network and returns it. +func (n *DRNGNetwork) CreatePeer(c GoShimmerConfig, publicKey ed25519.PublicKey) (*Peer, error) { + name := n.network.namePrefix(fmt.Sprintf("%s%d", containerNameReplica, len(n.network.peers))) + + config := c + config.Name = name + config.EntryNodeHost = n.network.namePrefix(containerNameEntryNode) + config.EntryNodePublicKey = n.network.entryNodePublicKey() + config.DisabledPlugins = disabledPluginsPeer + + // create Docker container + container := NewDockerContainer(n.network.dockerClient) + err := container.CreateGoShimmerPeer(config) + if err != nil { + return nil, err + } + err = container.ConnectToNetwork(n.network.id) + if err != nil { + return nil, err + } + err = container.Start() + if err != nil { + return nil, err + } + + peer, err := newPeer(name, identity.New(publicKey), container, nil, n.network) + if err != nil { + return nil, err + } + n.network.peers = append(n.network.peers, peer) + return peer, nil +} + +// CreateMember creates a new member/drand node in the network and returns it. +// Passing leader true enables the leadership on the given peer. +func (n *DRNGNetwork) CreateMember(leader bool) (*Drand, error) { + name := n.network.namePrefix(fmt.Sprintf("%s%d", containerNameDrand, len(n.members))) + + // create Docker container + container := NewDockerContainer(n.network.dockerClient) + err := container.CreateDrandMember(name, fmt.Sprintf("%s:8080", n.network.namePrefix(fmt.Sprintf("%s%d", containerNameReplica, len(n.members)))), leader) + if err != nil { + return nil, err + } + err = container.ConnectToNetwork(n.network.id) + if err != nil { + return nil, err + } + err = container.Start() + if err != nil { + return nil, err + } + + member := newDrand(name, container) + n.members = append(n.members, member) + return member, nil +} + +// Shutdown creates logs and removes network and containers. +// Should always be called when a network is not needed anymore! +func (n *DRNGNetwork) Shutdown() error { + // stop drand members + for _, p := range n.members { + err := p.Stop() + if err != nil { + return err + } + } + + // retrieve logs + for _, p := range n.members { + logs, err := p.Logs() + if err != nil { + return err + } + err = createLogFile(p.name, logs) + if err != nil { + return err + } + } + + // remove containers + for _, p := range n.members { + err := p.Remove() + if err != nil { + return err + } + } + + return n.network.Shutdown() +} + +// WaitForDKG waits until all members have concluded the DKG phase. +func (n *DRNGNetwork) WaitForDKG() error { + log.Printf("Waiting for DKG...\n") + defer log.Printf("Waiting for DKG... done\n") + + for i := dkgMaxTries; i > 0; i-- { + if dkey, err := n.members[0].Client.DistKey(n.members[0].name+":8000", false); err == nil { + n.SetDistKey(dkey.Key) + log.Printf("DistKey: %v", hex.EncodeToString(n.distKey)) + return nil + } + + log.Println("Not done yet. Try again in 5 seconds...") + time.Sleep(5 * time.Second) + } + + return fmt.Errorf("DKG not successful") +} + +// SetDistKey sets the distributed key. +func (n *DRNGNetwork) SetDistKey(key []byte) { + n.distKey = key +} + +// Peers returns the list of peers. +func (n *DRNGNetwork) Peers() []*Peer { + return n.network.Peers() +} diff --git a/tools/integration-tests/tester/framework/framework.go b/tools/integration-tests/tester/framework/framework.go new file mode 100644 index 0000000000000000000000000000000000000000..fa1a80a90f48784f4931dff730fb1bbfbd15476f --- /dev/null +++ b/tools/integration-tests/tester/framework/framework.go @@ -0,0 +1,267 @@ +// Package framework provides integration test functionality for GoShimmer with a Docker network. +// It effectively abstracts away all complexity with creating a custom Docker network per test, +// discovering peers, waiting for them to autopeer and offers easy access to the peers' web API and logs. +package framework + +import ( + "encoding/hex" + "fmt" + "strings" + "sync" + "time" + + "github.com/docker/docker/api/types/strslice" + "github.com/docker/docker/client" + "github.com/iotaledger/hive.go/crypto/ed25519" +) + +var ( + once sync.Once + instance *Framework +) + +// Framework is a wrapper that provides the integration testing functionality. +type Framework struct { + tester *DockerContainer + dockerClient *client.Client +} + +// Instance returns the singleton Framework instance. +func Instance() (f *Framework, err error) { + once.Do(func() { + f, err = newFramework() + instance = f + }) + + return instance, err +} + +// newFramework creates a new instance of Framework, creates a DockerClient +// and creates a DockerContainer for the tester container where the tests are running in. +func newFramework() (*Framework, error) { + dockerClient, err := newDockerClient() + if err != nil { + return nil, err + } + + tester, err := NewDockerContainerFromExisting(dockerClient, containerNameTester) + if err != nil { + return nil, err + } + + f := &Framework{ + dockerClient: dockerClient, + tester: tester, + } + + return f, nil +} + +// CreateNetwork creates and returns a (Docker) Network that contains `peers` GoShimmer nodes. +// It waits for the peers to autopeer until the minimum neighbors criteria is met for every peer. +// The first peer automatically starts with the bootstrap plugin enabled. +func (f *Framework) CreateNetwork(name string, peers int, minimumNeighbors int, networkConfig ...NetworkConfig) (*Network, error) { + network, err := newNetwork(f.dockerClient, strings.ToLower(name), f.tester) + if err != nil { + return nil, err + } + + err = network.createEntryNode() + if err != nil { + return nil, err + } + + // configuration of bootstrap plugin + bootstrapInitialIssuanceTimePeriodSec := -1 + if len(networkConfig) > 0 { + bootstrapInitialIssuanceTimePeriodSec = networkConfig[0].BootstrapInitialIssuanceTimePeriodSec + } + + // create peers/GoShimmer nodes + for i := 0; i < peers; i++ { + config := GoShimmerConfig{ + Bootstrap: func(i int) bool { + if ParaBootstrapOnEveryNode { + return true + } + return i == 0 + }(i), + BootstrapInitialIssuanceTimePeriodSec: bootstrapInitialIssuanceTimePeriodSec, + Faucet: i == 0, + } + if _, err = network.CreatePeer(config); err != nil { + return nil, err + } + } + + // wait until containers are fully started + time.Sleep(1 * time.Second) + err = network.WaitForAutopeering(minimumNeighbors) + if err != nil { + return nil, err + } + + return network, nil +} + +// CreateNetworkWithPartitions creates and returns a partitioned network that contains `peers` GoShimmer nodes per partition. +// It waits for the peers to autopeer until the minimum neighbors criteria is met for every peer. +// The first peer automatically starts with the bootstrap plugin enabled. +func (f *Framework) CreateNetworkWithPartitions(name string, peers, partitions, minimumNeighbors int) (*Network, error) { + network, err := newNetwork(f.dockerClient, strings.ToLower(name), f.tester) + if err != nil { + return nil, err + } + + err = network.createEntryNode() + if err != nil { + return nil, err + } + + // block all traffic from/to entry node + pumbaEntryNodeName := network.namePrefix(containerNameEntryNode) + containerNameSuffixPumba + pumbaEntryNode, err := network.createPumba( + pumbaEntryNodeName, + network.namePrefix(containerNameEntryNode), + strslice.StrSlice{}, + ) + if err != nil { + return nil, err + } + // wait until pumba is started and blocks all traffic + time.Sleep(5 * time.Second) + + // create peers/GoShimmer nodes + for i := 0; i < peers; i++ { + config := GoShimmerConfig{Bootstrap: func(i int) bool { + if ParaBootstrapOnEveryNode { + return true + } + return i == 0 + }(i)} + if _, err = network.CreatePeer(config); err != nil { + return nil, err + } + } + // wait until containers are fully started + time.Sleep(2 * time.Second) + + // create partitions + chunkSize := peers / partitions + var end int + for i := 0; end < peers; i += chunkSize { + end = i + chunkSize + // last partitions takes the rest + if i/chunkSize == partitions-1 { + end = peers + } + _, err = network.createPartition(network.peers[i:end]) + if err != nil { + return nil, err + } + } + // wait until pumba containers are started and block traffic between partitions + time.Sleep(5 * time.Second) + + // delete pumba for entry node + err = pumbaEntryNode.Stop() + if err != nil { + return nil, err + } + logs, err := pumbaEntryNode.Logs() + if err != nil { + return nil, err + } + err = createLogFile(pumbaEntryNodeName, logs) + if err != nil { + return nil, err + } + err = pumbaEntryNode.Remove() + if err != nil { + return nil, err + } + + err = network.WaitForAutopeering(minimumNeighbors) + if err != nil { + return nil, err + } + + return network, nil +} + +// CreateDRNGNetwork creates and returns a (Docker) Network that contains drand and `peers` GoShimmer nodes. +func (f *Framework) CreateDRNGNetwork(name string, members, peers, minimumNeighbors int) (*DRNGNetwork, error) { + drng, err := newDRNGNetwork(f.dockerClient, strings.ToLower(name), f.tester) + if err != nil { + return nil, err + } + + err = drng.network.createEntryNode() + if err != nil { + return nil, err + } + + // create members/drand nodes + for i := 0; i < members; i++ { + leader := i == 0 + if _, err = drng.CreateMember(leader); err != nil { + return nil, err + } + } + + // wait until containers are fully started + time.Sleep(1 * time.Second) + err = drng.WaitForDKG() + if err != nil { + return nil, err + } + + // create GoShimmer identities + pubKeys := make([]ed25519.PublicKey, peers) + privKeys := make([]ed25519.PrivateKey, peers) + var drngCommittee string + + for i := 0; i < peers; i++ { + pubKeys[i], privKeys[i], err = ed25519.GenerateKey() + if err != nil { + return nil, err + } + + if i < members { + if drngCommittee != "" { + drngCommittee += fmt.Sprintf(",") + } + drngCommittee += pubKeys[i].String() + } + } + + config := GoShimmerConfig{ + DRNGInstance: 1, + DRNGThreshold: 3, + DRNGDistKey: hex.EncodeToString(drng.distKey), + DRNGCommittee: drngCommittee, + } + + // create peers/GoShimmer nodes + for i := 0; i < peers; i++ { + config.Bootstrap = func(i int) bool { + if ParaBootstrapOnEveryNode { + return true + } + return i == 0 + }(i) + config.Seed = privKeys[i].Seed().String() + if _, err = drng.CreatePeer(config, pubKeys[i]); err != nil { + return nil, err + } + } + + // wait until peers are fully started and connected + time.Sleep(1 * time.Second) + err = drng.network.WaitForAutopeering(minimumNeighbors) + if err != nil { + return nil, err + } + + return drng, nil +} diff --git a/tools/integration-tests/tester/framework/network.go b/tools/integration-tests/tester/framework/network.go new file mode 100644 index 0000000000000000000000000000000000000000..d72337f1553f376b4dae72247decb02e65ab2181 --- /dev/null +++ b/tools/integration-tests/tester/framework/network.go @@ -0,0 +1,428 @@ +package framework + +import ( + "context" + "fmt" + "log" + "math/rand" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/hive.go/crypto/ed25519" + "github.com/iotaledger/hive.go/identity" +) + +// Network represents a complete GoShimmer network within Docker. +// Including an entry node and arbitrary many peers. +type Network struct { + id string + name string + + peers []*Peer + tester *DockerContainer + + entryNode *DockerContainer + entryNodeIdentity *identity.Identity + + partitions []*Partition + + dockerClient *client.Client +} + +// newNetwork returns a Network instance, creates its underlying Docker network and adds the tester container to the network. +func newNetwork(dockerClient *client.Client, name string, tester *DockerContainer) (*Network, error) { + // create Docker network + resp, err := dockerClient.NetworkCreate(context.Background(), name, types.NetworkCreate{}) + if err != nil { + return nil, err + } + + // the tester container needs to join the Docker network in order to communicate with the peers + err = tester.ConnectToNetwork(resp.ID) + if err != nil { + return nil, err + } + + return &Network{ + id: resp.ID, + name: name, + tester: tester, + dockerClient: dockerClient, + }, nil +} + +// createEntryNode creates the network's entry node. +func (n *Network) createEntryNode() error { + // create identity + publicKey, privateKey, err := ed25519.GenerateKey() + if err != nil { + return err + } + + n.entryNodeIdentity = identity.New(publicKey) + seed := privateKey.Seed().String() + + // create entry node container + n.entryNode = NewDockerContainer(n.dockerClient) + err = n.entryNode.CreateGoShimmerEntryNode(n.namePrefix(containerNameEntryNode), seed) + if err != nil { + return err + } + err = n.entryNode.ConnectToNetwork(n.id) + if err != nil { + return err + } + err = n.entryNode.Start() + if err != nil { + return err + } + + return nil +} + +// CreatePeer creates a new peer/GoShimmer node in the network and returns it. +// Passing bootstrap true enables the bootstrap plugin on the given peer. +func (n *Network) CreatePeer(c GoShimmerConfig) (*Peer, error) { + name := n.namePrefix(fmt.Sprintf("%s%d", containerNameReplica, len(n.peers))) + + // create identity + publicKey, privateKey, err := ed25519.GenerateKey() + if err != nil { + return nil, err + } + seed := privateKey.Seed().String() + + config := c + config.Name = name + config.Seed = seed + config.EntryNodeHost = n.namePrefix(containerNameEntryNode) + config.EntryNodePublicKey = n.entryNodePublicKey() + config.DisabledPlugins = disabledPluginsPeer + config.SnapshotFilePath = snapshotFilePath + + // create wallet + var nodeWallet *wallet.Wallet + if c.Faucet == true { + nodeWallet = wallet.New(genesisSeed) + } else { + nodeWallet = wallet.New() + } + + // create Docker container + container := NewDockerContainer(n.dockerClient) + err = container.CreateGoShimmerPeer(config) + if err != nil { + return nil, err + } + err = container.ConnectToNetwork(n.id) + if err != nil { + return nil, err + } + err = container.Start() + if err != nil { + return nil, err + } + + peer, err := newPeer(name, identity.New(publicKey), container, nodeWallet, n) + if err != nil { + return nil, err + } + n.peers = append(n.peers, peer) + return peer, nil +} + +// Shutdown creates logs and removes network and containers. +// Should always be called when a network is not needed anymore! +func (n *Network) Shutdown() error { + // stop containers + err := n.entryNode.Stop() + if err != nil { + return err + } + for _, p := range n.peers { + err = p.Stop() + if err != nil { + return err + } + } + + // delete all partitions + err = n.DeletePartitions() + if err != nil { + return err + } + + // retrieve logs + logs, err := n.entryNode.Logs() + if err != nil { + return err + } + err = createLogFile(n.namePrefix(containerNameEntryNode), logs) + if err != nil { + return err + } + for _, p := range n.peers { + logs, err = p.Logs() + if err != nil { + return err + } + err = createLogFile(p.name, logs) + if err != nil { + return err + } + } + + // save exit status of containers to check at end of shutdown process + exitStatus := make(map[string]int, len(n.peers)+1) + exitStatus[containerNameEntryNode], err = n.entryNode.ExitStatus() + if err != nil { + return err + } + for _, p := range n.peers { + exitStatus[p.name], err = p.ExitStatus() + if err != nil { + return err + } + } + + // remove containers + err = n.entryNode.Remove() + if err != nil { + return err + } + for _, p := range n.peers { + err = p.Remove() + if err != nil { + return err + } + } + + // disconnect tester from network otherwise the network can't be removed + err = n.tester.DisconnectFromNetwork(n.id) + if err != nil { + return err + } + + // remove network + err = n.dockerClient.NetworkRemove(context.Background(), n.id) + if err != nil { + return err + } + + // check exit codes of containers + for name, status := range exitStatus { + if status != exitStatusSuccessful { + return fmt.Errorf("container %s exited with code %d", name, status) + } + } + + return nil +} + +// WaitForAutopeering waits until all peers have reached the minimum amount of neighbors. +// Returns error if this minimum is not reached after autopeeringMaxTries. +func (n *Network) WaitForAutopeering(minimumNeighbors int) error { + log.Printf("Waiting for autopeering...\n") + defer log.Printf("Waiting for autopeering... done\n") + + if minimumNeighbors == 0 { + return nil + } + + for i := autopeeringMaxTries; i > 0; i-- { + + for _, p := range n.peers { + if resp, err := p.GetNeighbors(false); err != nil { + log.Printf("request error: %v\n", err) + } else { + p.SetNeighbors(resp.Chosen, resp.Accepted) + } + } + + // verify neighbor requirement + min := 100 + total := 0 + for _, p := range n.peers { + neighbors := p.TotalNeighbors() + if neighbors < min { + min = neighbors + } + total += neighbors + } + if min >= minimumNeighbors { + log.Printf("Neighbors: min=%d avg=%.2f\n", min, float64(total)/float64(len(n.peers))) + return nil + } + + log.Println("Not done yet. Try again in 5 seconds...") + time.Sleep(5 * time.Second) + } + + return fmt.Errorf("autopeering not successful") +} + +// namePrefix returns the suffix prefixed with the name. +func (n *Network) namePrefix(suffix string) string { + return fmt.Sprintf("%s-%s", n.name, suffix) +} + +// entryNodePublicKey returns the entry node's public key encoded as base58 +func (n *Network) entryNodePublicKey() string { + return n.entryNodeIdentity.PublicKey().String() +} + +// Peers returns all available peers in the network. +func (n *Network) Peers() []*Peer { + return n.peers +} + +// RandomPeer returns a random peer out of the list of peers. +func (n *Network) RandomPeer() *Peer { + return n.peers[rand.Intn(len(n.peers))] +} + +// createPumba creates and starts a Pumba Docker container. +func (n *Network) createPumba(name string, containerName string, targetIPs []string) (*DockerContainer, error) { + container := NewDockerContainer(n.dockerClient) + err := container.CreatePumba(name, containerName, targetIPs) + if err != nil { + return nil, err + } + err = container.Start() + if err != nil { + return nil, err + } + + return container, nil +} + +// createPartition creates a partition with the given peers. +// It starts a Pumba container for every peer that blocks traffic to all other partitions. +func (n *Network) createPartition(peers []*Peer) (*Partition, error) { + peersMap := make(map[string]*Peer) + for _, peer := range peers { + peersMap[peer.ID().String()] = peer + } + + // block all traffic to all other peers except in the current partition + var targetIPs []string + for _, peer := range n.peers { + if _, ok := peersMap[peer.ID().String()]; ok { + continue + } + targetIPs = append(targetIPs, peer.ip) + } + + partitionName := n.namePrefix(fmt.Sprintf("partition_%d-", len(n.partitions))) + + // create pumba container for every peer in the partition + pumbas := make([]*DockerContainer, len(peers)) + for i, p := range peers { + name := partitionName + p.name + containerNameSuffixPumba + pumba, err := n.createPumba(name, p.name, targetIPs) + if err != nil { + return nil, err + } + pumbas[i] = pumba + time.Sleep(1 * time.Second) + } + + partition := &Partition{ + name: partitionName, + peers: peers, + peersMap: peersMap, + pumbas: pumbas, + } + n.partitions = append(n.partitions, partition) + + return partition, nil +} + +// DeletePartitions deletes all partitions of the network. +// All nodes can communicate with the full network again. +func (n *Network) DeletePartitions() error { + for _, p := range n.partitions { + err := p.deletePartition() + if err != nil { + return err + } + } + n.partitions = nil + return nil +} + +// Partitions returns the network's partitions. +func (n *Network) Partitions() []*Partition { + return n.partitions +} + +// Split splits the existing network in given partitions. +func (n *Network) Split(partitions ...[]*Peer) error { + for _, peers := range partitions { + _, err := n.createPartition(peers) + if err != nil { + return err + } + } + // wait until pumba containers are started and block traffic between partitions + time.Sleep(5 * time.Second) + + return nil +} + +// Partition represents a network partition. +// It contains its peers and the corresponding Pumba instances that block all traffic to peers in other partitions. +type Partition struct { + name string + peers []*Peer + peersMap map[string]*Peer + pumbas []*DockerContainer +} + +// Peers returns the partition's peers. +func (p *Partition) Peers() []*Peer { + return p.peers +} + +// PeersMap returns the partition's peers map. +func (p *Partition) PeersMap() map[string]*Peer { + return p.peersMap +} + +func (p *Partition) String() string { + return fmt.Sprintf("Partition{%s, %s}", p.name, p.peers) +} + +// deletePartition deletes a partition, all its Pumba containers and creates logs for them. +func (p *Partition) deletePartition() error { + // stop containers + for _, pumba := range p.pumbas { + err := pumba.Stop() + if err != nil { + return err + } + } + + // retrieve logs + for i, pumba := range p.pumbas { + logs, err := pumba.Logs() + if err != nil { + return err + } + err = createLogFile(fmt.Sprintf("%s%s", p.name, p.peers[i].name), logs) + if err != nil { + return err + } + } + + for _, pumba := range p.pumbas { + err := pumba.Remove() + if err != nil { + return err + } + } + + return nil +} diff --git a/tools/integration-tests/tester/framework/parameters.go b/tools/integration-tests/tester/framework/parameters.go new file mode 100644 index 0000000000000000000000000000000000000000..9fa13fe839cefc05874ce95917f054d1e8d1f40d --- /dev/null +++ b/tools/integration-tests/tester/framework/parameters.go @@ -0,0 +1,71 @@ +package framework + +const ( + autopeeringMaxTries = 50 + + apiPort = "8080" + + containerNameTester = "/tester" + containerNameEntryNode = "entry_node" + containerNameReplica = "replica_" + containerNameDrand = "drand_" + containerNameSuffixPumba = "_pumba" + + logsDir = "/tmp/logs/" + + disabledPluginsEntryNode = "portcheck,dashboard,analysis-client,profiling,gossip,drng,issuer,sync,metrics,valuetransfers,messagelayer,pow,webapi,webapibroadcastdataendpoint,webapifindtransactionhashesendpoint,webapigetneighborsendpoint,webapigettransactionobjectsbyhashendpoint,webapigettransactiontrytesbyhashendpoint" + disabledPluginsPeer = "portcheck,dashboard,analysis-client,profiling" + snapshotFilePath = "/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin" + dockerLogsPrefixLen = 8 + + dkgMaxTries = 50 + + exitStatusSuccessful = 0 +) + +// Parameters to override before calling any peer creation function. +var ( + // ParaFCoBAverageNetworkDelay defines the configured avg. network delay (in seconds) for the FCOB rules. + ParaFCoBAverageNetworkDelay = 5 + // ParaOutboundUpdateIntervalMs the autopeering outbound update interval in milliseconds. + ParaOutboundUpdateIntervalMs = 100 + // ParaBootstrapOnEveryNode whether to enable the bootstrap plugin on every node. + ParaBootstrapOnEveryNode = false + // ParaFaucetTokensPerRequest defines the tokens to send up on each faucet request message. + ParaFaucetTokensPerRequest int64 = 1337 + // ParaPoWDifficulty defines the PoW difficulty. + ParaPoWDifficulty = 2 + // ParaWaitToKill defines the time to wait before killing the node. + ParaWaitToKill = 60 +) + +var ( + genesisSeed = []byte{95, 76, 224, 164, 168, 80, 141, 174, 133, 77, 153, 100, 4, 202, 113, + 104, 71, 130, 88, 200, 46, 56, 243, 121, 216, 236, 70, 146, 234, 158, 206, 230} + genesisSeedBase58 = "7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih" +) + +//GoShimmerConfig defines the config of a GoShimmer node. +type GoShimmerConfig struct { + Seed string + Name string + EntryNodeHost string + EntryNodePublicKey string + DisabledPlugins string + SnapshotFilePath string + + Bootstrap bool + BootstrapInitialIssuanceTimePeriodSec int + + DRNGCommittee string + DRNGDistKey string + DRNGInstance int + DRNGThreshold int + + Faucet bool +} + +// NetworkConfig defines the config of a GoShimmer Docker network. +type NetworkConfig struct { + BootstrapInitialIssuanceTimePeriodSec int +} diff --git a/tools/integration-tests/tester/framework/peer.go b/tools/integration-tests/tester/framework/peer.go new file mode 100644 index 0000000000000000000000000000000000000000..8da31c20ef4634f2dc408034b5046a9b7b589712 --- /dev/null +++ b/tools/integration-tests/tester/framework/peer.go @@ -0,0 +1,70 @@ +package framework + +import ( + "fmt" + "net/http" + "time" + + "github.com/iotaledger/goshimmer/client" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/goshimmer/plugins/webapi/autopeering" + "github.com/iotaledger/hive.go/identity" +) + +// Peer represents a GoShimmer node inside the Docker network +type Peer struct { + // name of the GoShimmer instance, Docker container and hostname + name string + ip string + // GoShimmer identity + *identity.Identity + + // Web API of this peer + *client.GoShimmerAPI + + // the DockerContainer that this peer is running in + *DockerContainer + + // Wallet + *wallet.Wallet + + chosen []autopeering.Neighbor + accepted []autopeering.Neighbor +} + +// newPeer creates a new instance of Peer with the given information. +// dockerContainer needs to be started in order to determine the container's (and therefore peer's) IP correctly. +func newPeer(name string, identity *identity.Identity, dockerContainer *DockerContainer, wallet *wallet.Wallet, network *Network) (*Peer, error) { + // after container is started we can get its IP + ip, err := dockerContainer.IP(network.name) + if err != nil { + return nil, err + } + + return &Peer{ + name: name, + ip: ip, + Identity: identity, + GoShimmerAPI: client.NewGoShimmerAPI(getWebAPIBaseURL(name), http.Client{Timeout: 30 * time.Second}), + DockerContainer: dockerContainer, + Wallet: wallet, + }, nil +} + +func (p *Peer) String() string { + return fmt.Sprintf("Peer:{%s, %s, %s, %d}", p.name, p.ID().String(), p.BaseURL(), p.TotalNeighbors()) +} + +// TotalNeighbors returns the total number of neighbors the peer has. +func (p *Peer) TotalNeighbors() int { + return len(p.chosen) + len(p.accepted) +} + +// SetNeighbors sets the neighbors of the peer accordingly. +func (p *Peer) SetNeighbors(chosen, accepted []autopeering.Neighbor) { + p.chosen = make([]autopeering.Neighbor, len(chosen)) + copy(p.chosen, chosen) + + p.accepted = make([]autopeering.Neighbor, len(accepted)) + copy(p.accepted, accepted) +} diff --git a/tools/integration-tests/tester/framework/util.go b/tools/integration-tests/tester/framework/util.go new file mode 100644 index 0000000000000000000000000000000000000000..09a7805dc1798a5d641d9d530473f511c5c05137 --- /dev/null +++ b/tools/integration-tests/tester/framework/util.go @@ -0,0 +1,50 @@ +package framework + +import ( + "bufio" + "fmt" + "io" + "os" +) + +// getWebAPIBaseURL returns the web API base url for the given IP. +func getWebAPIBaseURL(hostname string) string { + return fmt.Sprintf("http://%s:%s", hostname, apiPort) +} + +// createLogFile creates a log file from the given logs ReadCloser. +func createLogFile(name string, logs io.ReadCloser) error { + defer logs.Close() + + f, err := os.Create(fmt.Sprintf("%s%s.log", logsDir, name)) + if err != nil { + return err + } + defer f.Close() + + // remove non-ascii chars at beginning of line + scanner := bufio.NewScanner(logs) + for scanner.Scan() { + line := scanner.Bytes() + + // in case of an error there is no Docker prefix + var bytes []byte + if len(line) < dockerLogsPrefixLen { + bytes = append(line, '\n') + } else { + bytes = append(line[dockerLogsPrefixLen:], '\n') + } + + _, err = f.Write(bytes) + if err != nil { + return err + } + } + + err = f.Sync() + if err != nil { + return err + } + + return nil +} diff --git a/tools/integration-tests/tester/go.mod b/tools/integration-tests/tester/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..bf7684da5c7af5a85162cf78f74871b69282e102 --- /dev/null +++ b/tools/integration-tests/tester/go.mod @@ -0,0 +1,19 @@ +module github.com/iotaledger/goshimmer/tools/integration-tests/tester + +go 1.14 + +require ( + github.com/Microsoft/go-winio v0.4.14 // indirect + github.com/docker/distribution v2.7.1+incompatible // indirect + github.com/docker/docker v1.13.1 + github.com/docker/go-connections v0.4.0 + github.com/docker/go-units v0.4.0 // indirect + github.com/drand/drand v0.9.1 + github.com/iotaledger/goshimmer v0.1.3 + github.com/iotaledger/hive.go v0.0.0-20200625105326-310ea88f1337 + github.com/mr-tron/base58 v1.2.0 + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/stretchr/testify v1.6.1 +) + +replace github.com/iotaledger/goshimmer => ../../.. diff --git a/tools/integration-tests/tester/go.sum b/tools/integration-tests/tester/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..6dbd85bccedbfb13897fc3b27bd2d0da6c5a25c5 --- /dev/null +++ b/tools/integration-tests/tester/go.sum @@ -0,0 +1,971 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= +github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= +github.com/dchest/blake2b v1.0.0/go.mod h1:U034kXgbJpCle2wSk5ybGIVhOSHCVLMDqOzcPEA0F7s= +github.com/dgraph-io/badger v1.5.4/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger v1.6.1 h1:w9pSFNSdq/JPM1N12Fz/F/bzo993Is1W+Q7HjPzi7yg= +github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/badger/v2 v2.0.3 h1:inzdf6VF/NZ+tJ8RwwYMjJMvsOALTHYdozn0qSl6XJI= +github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM= +github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= +github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20190323231341-8198c7b169ec/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= +github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE= +github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= +github.com/drand/drand v0.8.1/go.mod h1:ZdzIrSqqEYZvMiS1UuZlJs3WTb9uLz1I9uH0icYPqoE= +github.com/drand/drand v0.8.2-0.20200508124210-33866c2232e3/go.mod h1:pX75MGTg1J5n6iJ9Jf1jFfl4TsiohiJqzhY0GHfQOnY= +github.com/drand/drand v0.9.1 h1:mb4IVD4/bVNY+/eoZaPpqJZ6oYSMcXkqc7zd+u3YzrQ= +github.com/drand/drand v0.9.1/go.mod h1:0fNgEy+kUnfo025hmcr08b1lXjDY2aYHKd7qAohvaeM= +github.com/drand/drand/cmd/relay-gossip v0.0.0-20200515173025-07c732b552f9/go.mod h1:I0uunc7yfb1r4o1w/B3JBPGA9Vd82bdytHywMU9fyj8= +github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= +github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99/go.mod h1:Rzu9PGFt3q8d7WWdrHmR8dktHucO0dSTWlMYrgqjSpA= +github.com/drand/kyber v1.0.1-0.20200502215402-daa30f0ec4f8 h1:YtYT6e0l93FNNWnsya5fu9CYouLtevAOqthplH75pcE= +github.com/drand/kyber v1.0.1-0.20200502215402-daa30f0ec4f8/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/packr/v2 v2.8.0/go.mod h1:PDk2k3vGevNE3SwVyVRgQCCXETC9SaONCNSXT1Q8M1g= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY= +github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iotaledger/hive.go v0.0.0-20200625105326-310ea88f1337 h1:F6PzAkymPcKr1vJVK3/80wiVovjkL47c9FMjUOesXGA= +github.com/iotaledger/hive.go v0.0.0-20200625105326-310ea88f1337/go.mod h1:42UvBc41QBsuM7z1P1fABMonTJb7kGqkzshRebClQvA= +github.com/iotaledger/iota.go v1.0.0-beta.15/go.mod h1:Rn6v5hLAn8YBaJlRu1ZQdPAgKlshJR1PTeLQaft2778= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-cid v0.0.6-0.20200501230655-7c82f3b81c00/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= +github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= +github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= +github.com/ipfs/go-ds-badger2 v0.1.0/go.mod h1:pbR1p817OZbdId9EvLOhKBgUVTM3BMCSTan78lDDVaw= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= +github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= +github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= +github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1 h1:qBCV/RLV02TSfQa7tFmxTihnG+u+7JXByOkhlkR5rmQ= +github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3 h1:Iy7Ifq2ysilWU4QlCx/97OoI4xT1IV7i8byT/EyIT/M= +github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3/go.mod h1:BYpt4ufZiIGv2nXn4gMxnfKV306n3mWXgNu/d2TqdTU= +github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/karrick/godirwalk v1.15.3/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= +github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= +github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= +github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= +github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= +github.com/libp2p/go-libp2p v0.8.2/go.mod h1:NQDA/F/qArMHGe0J7sDScaKjW8Jh4y/ozQqBbYJ+BnA= +github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= +github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= +github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= +github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= +github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= +github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= +github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= +github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= +github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= +github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= +github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= +github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= +github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= +github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.2/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.4-0.20200508062439-98b95a487749/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= +github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= +github.com/libp2p/go-libp2p-discovery v0.4.0/go.mod h1:bZ0aJSrFc/eX2llP0ryhb1kpgkPyTo23SJ5b7UQCMh4= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= +github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= +github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= +github.com/libp2p/go-libp2p-nat v0.0.6/go.mod h1:iV59LVhB3IkFvS6S6sauVTSOrNEANnINbI/fkaLimiw= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= +github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= +github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= +github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= +github.com/libp2p/go-libp2p-peerstore v0.2.4-0.20200508064014-7a58f873f4df/go.mod h1:wv61HcYms743GsUAaKJFH3Ipf8GP5SxypeTzojTGGVU= +github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= +github.com/libp2p/go-libp2p-pubsub v0.2.7-0.20200508182004-fedb87bd57ea/go.mod h1:tFvkRgsW96JilTvYwe1X/lYqpruTXBqEatNXq3/MqBw= +github.com/libp2p/go-libp2p-pubsub v0.2.7/go.mod h1:R4R0kH/6p2vu8O9xsue0HNSjEuXMEPBgg4h3nVDI15o= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= +github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= +github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= +github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= +github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= +github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.2/go.mod h1:lIohaR0pT6mOt0AZ0L2dFze9hds9Req3OfS+B+dv4qw= +github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ48OpsfmQVTErwA= +github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= +github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= +github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= +github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= +github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= +github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= +github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= +github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= +github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= +github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= +github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= +github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= +github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= +github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= +github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= +github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e h1:07zdEcJ4Fble5uWsqKpjW19699kQWRLXP+RZh1a6ZRg= +github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e/go.mod h1:79GLCU4P87rYvYYACbNwVyc1WmRvkwQbYnybpCmRXzg= +github.com/oasisprotocol/ed25519 v0.0.0-20200528083105-55566edd6df0 h1:qmiMZ6ZhkeQZkV/Huajj+QBAu1jX0HTGsOwi+eXTGY8= +github.com/oasisprotocol/ed25519 v0.0.0-20200528083105-55566edd6df0/go.mod h1:IZbb50w3AB72BVobEF6qG93NNSrTw/V2QlboxqSu3Xw= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/panjf2000/ants/v2 v2.4.1 h1:7RtUqj5lGOw0WnZhSKDZ2zzJhaX5490ZW1sUolRXCxY= +github.com/panjf2000/ants/v2 v2.4.1/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U= +github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sasha-s/go-deadlock v0.2.0 h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y= +github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/simia-tech/env v0.1.0/go.mod h1:eVRQ7W5NXXHifpPAcTJ3r5EmoGgMn++dXfSVbZv3Opo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk= +github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= +github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= +go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= +go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= +go.dedis.ch/kyber/v3 v3.0.12 h1:15d61EyBcBoFIS97kS2c/Vz4o3FR8ALnZ2ck9J/ebYM= +go.dedis.ch/kyber/v3 v3.0.12/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U= +go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= +go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= +go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo= +go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.mongodb.org/mongo-driver v1.0.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200427175716-29b57079015a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200330040139-fa3cc9eebcfe h1:sOd+hT8wBUrIFR5Q6uQb/rg50z8NjHk96kC4adwvxjw= +golang.org/x/tools v0.0.0-20200330040139-fa3cc9eebcfe/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2 h1:KlOjjpQjL4dqscfbhtQvAnRMm5PaRTchHHczffkUiq0= +google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.30.0-dev.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc/examples v0.0.0-20200617041141-9a465503579e/go.mod h1:wwLo5XaKQhinfnT+PqwJ17u2NXm7cllRQ4fKKyB22+w= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/h2non/gock.v1 v1.0.14/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= +gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/tools/integration-tests/tester/tests/autopeering/autopeering_test.go b/tools/integration-tests/tester/tests/autopeering/autopeering_test.go new file mode 100644 index 0000000000000000000000000000000000000000..9bbb7ec3e6a9717571187c99877eec55249d12d8 --- /dev/null +++ b/tools/integration-tests/tester/tests/autopeering/autopeering_test.go @@ -0,0 +1,38 @@ +package autopeering + +import ( + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNetworkSplit(t *testing.T) { + n, err := f.CreateNetworkWithPartitions("autopeering_TestNetworkSplit", 6, 2, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + // test that nodes only have neighbors from same partition + for _, partition := range n.Partitions() { + for _, peer := range partition.Peers() { + resp, err := peer.GetNeighbors(false) + require.NoError(t, err) + + // check that all neighbors are indeed in the same partition + for _, n := range resp.Accepted { + assert.Contains(t, partition.PeersMap(), n.ID) + } + for _, n := range resp.Chosen { + assert.Contains(t, partition.PeersMap(), n.ID) + } + } + } + + err = n.DeletePartitions() + require.NoError(t, err) + + // let them mingle and check that they all peer with each other + err = n.WaitForAutopeering(4) + require.NoError(t, err) +} diff --git a/tools/integration-tests/tester/tests/autopeering/main_test.go b/tools/integration-tests/tester/tests/autopeering/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bcc09c2e53590df061cbff5a2159071d567440f1 --- /dev/null +++ b/tools/integration-tests/tester/tests/autopeering/main_test.go @@ -0,0 +1,23 @@ +package autopeering + +import ( + "os" + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" +) + +var f *framework.Framework + +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. +func TestMain(m *testing.M) { + var err error + f, err = framework.Instance() + if err != nil { + panic(err) + } + + // call the tests + os.Exit(m.Run()) +} diff --git a/tools/integration-tests/tester/tests/common/common_test.go b/tools/integration-tests/tester/tests/common/common_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2d28acc16e304f0f680edf629fc39ae31069fabf --- /dev/null +++ b/tools/integration-tests/tester/tests/common/common_test.go @@ -0,0 +1,80 @@ +package common + +import ( + "testing" + "time" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestSynchronization checks whether messages are relayed through the network, +// a node that joins later solidifies, whether it is desyned after a restart +// and becomes synced again. +func TestSynchronization(t *testing.T) { + initialPeers := 4 + n, err := f.CreateNetwork("common_TestSynchronization", initialPeers, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + // wait for peers to change their state to synchronized + time.Sleep(5 * time.Second) + + numMessages := 100 + + // 1. issue data messages + ids := tests.SendDataMessagesOnRandomPeer(t, n.Peers(), numMessages) + + // wait for messages to be gossiped + time.Sleep(10 * time.Second) + + // 2. spawn peer without knowledge of previous messages + newPeer, err := n.CreatePeer(framework.GoShimmerConfig{}) + require.NoError(t, err) + err = n.WaitForAutopeering(3) + require.NoError(t, err) + + // 3. issue some messages on old peers so that new peer can solidify + ids = tests.SendDataMessagesOnRandomPeer(t, n.Peers()[:initialPeers], 10, ids) + + // wait for peer to solidify + time.Sleep(15 * time.Second) + + // 4. check whether all issued messages are available on all nodes + tests.CheckForMessageIds(t, n.Peers(), ids, true) + + // 5. shut down newly added peer + err = newPeer.Stop() + require.NoError(t, err) + + // 6. let it startup again + err = newPeer.Start() + require.NoError(t, err) + // wait for peer to start + time.Sleep(5 * time.Second) + + err = n.WaitForAutopeering(3) + require.NoError(t, err) + + // note: this check is too dependent on the initial time a node sends bootstrap messages + // and therefore very error prone. Therefore it's not done for now. + // 7. check that it is in state desynced + //resp, err := newPeer.Info() + //require.NoError(t, err) + //assert.Falsef(t, resp.Synced, "Peer %s should be desynced but is synced!", newPeer.String()) + + // 8. issue some messages on old peers so that new peer can sync again + ids = tests.SendDataMessagesOnRandomPeer(t, n.Peers()[:initialPeers], 10, ids) + // wait for peer to sync + time.Sleep(10 * time.Second) + + // 9. newPeer becomes synced again + resp, err := newPeer.Info() + require.NoError(t, err) + assert.Truef(t, resp.Synced, "Peer %s should be synced but is desynced!", newPeer.String()) + + // 10. check whether all issued messages are available on all nodes + tests.CheckForMessageIds(t, n.Peers(), ids, true) +} diff --git a/tools/integration-tests/tester/tests/common/main_test.go b/tools/integration-tests/tester/tests/common/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..cdffe476461e98e312c15ef4dd3f001c67e1faf4 --- /dev/null +++ b/tools/integration-tests/tester/tests/common/main_test.go @@ -0,0 +1,23 @@ +package common + +import ( + "os" + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" +) + +var f *framework.Framework + +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. +func TestMain(m *testing.M) { + var err error + f, err = framework.Instance() + if err != nil { + panic(err) + } + + // call the tests + os.Exit(m.Run()) +} diff --git a/tools/integration-tests/tester/tests/consensus/consensus_conflicts_test.go b/tools/integration-tests/tester/tests/consensus/consensus_conflicts_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4aec007c066a5feaeab1cb9fe530631228da5f4f --- /dev/null +++ b/tools/integration-tests/tester/tests/consensus/consensus_conflicts_test.go @@ -0,0 +1,212 @@ +package consensus + +import ( + "log" + "testing" + "time" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/mr-tron/base58/base58" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestConsensusFiftyFiftyOpinionSplit spawns two network partitions with their own peers, +// then issues valid value objects spending the genesis in both, deletes the partitions (and lets them merge) +// and then checks that the conflicts are resolved via FPC. +func TestConsensusFiftyFiftyOpinionSplit(t *testing.T) { + + // override avg. network delay to accustom integration test slowness + backupFCoBAvgNetworkDelay := framework.ParaFCoBAverageNetworkDelay + backupBootstrapOnEveryNode := framework.ParaBootstrapOnEveryNode + backupParaWaitToKill := framework.ParaWaitToKill + framework.ParaFCoBAverageNetworkDelay = 90 + framework.ParaBootstrapOnEveryNode = true + framework.ParaWaitToKill = 2 * framework.ParaFCoBAverageNetworkDelay + + // reset framework paras + defer func() { + framework.ParaFCoBAverageNetworkDelay = backupFCoBAvgNetworkDelay + framework.ParaBootstrapOnEveryNode = backupBootstrapOnEveryNode + framework.ParaWaitToKill = backupParaWaitToKill + }() + + // create two partitions with their own peers + n, err := f.CreateNetworkWithPartitions("abc", 6, 2, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + // split the network + for i, partition := range n.Partitions() { + log.Printf("partition %d peers:", i) + for _, p := range partition.Peers() { + log.Println(p.ID().String()) + } + } + + // genesis wallet + genesisSeedBytes, err := base58.Decode("7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih") + require.NoError(t, err, "couldn't decode genesis seed from base58 seed") + + const genesisBalance = 1000000000 + genesisWallet := wallet.New(genesisSeedBytes) + genesisAddr := genesisWallet.Seed().Address(0) + genesisOutputID := transaction.NewOutputID(genesisAddr, transaction.GenesisID) + + // issue transactions which spend the same genesis output in all partitions + conflictingTxs := make([]*transaction.Transaction, len(n.Partitions())) + conflictingTxIDs := make([]string, len(n.Partitions())) + receiverWallets := make([]*wallet.Wallet, len(n.Partitions())) + for i, partition := range n.Partitions() { + + // create a new receiver wallet for the given partition + partitionReceiverWallet := wallet.New() + destAddr := partitionReceiverWallet.Seed().Address(0) + receiverWallets[i] = partitionReceiverWallet + tx := transaction.New( + transaction.NewInputs(genesisOutputID), + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + destAddr: { + {Value: genesisBalance, Color: balance.ColorIOTA}, + }, + })) + tx = tx.Sign(signaturescheme.ED25519(*genesisWallet.Seed().KeyPair(0))) + conflictingTxs[i] = tx + + // issue the transaction on the first peer of the partition + issuerPeer := partition.Peers()[0] + txID, err := issuerPeer.SendTransaction(tx.Bytes()) + conflictingTxIDs[i] = txID + log.Printf("issued conflict transaction %s on partition %d on peer %s", txID, i, issuerPeer.ID().String()) + assert.NoError(t, err) + + // check that the transaction is actually available on all the peers of the partition + missing, err := tests.AwaitTransactionAvailability(partition.Peers(), []string{txID}, 15*time.Second) + if err != nil { + assert.NoError(t, err, "transactions should have been available in partition") + for p, missingOnPeer := range missing { + log.Printf("missing on peer %s:", p) + for missingTx := range missingOnPeer { + log.Println("tx id: ", missingTx) + } + } + return + } + + require.NoError(t, err) + } + + // sleep the avg. network delay so both partitions prefer their own first seen transaction + log.Printf("waiting %d seconds avg. network delay to make the transactions "+ + "preferred in their corresponding partition", framework.ParaFCoBAverageNetworkDelay) + time.Sleep(time.Duration(framework.ParaFCoBAverageNetworkDelay) * time.Second) + + // check that each partition is preferring its corresponding transaction + log.Println("checking that each partition likes its corresponding transaction before the conflict:") + for i, partition := range n.Partitions() { + tests.CheckTransactions(t, partition.Peers(), map[string]*tests.ExpectedTransaction{ + conflictingTxIDs[i]: nil, + }, true, tests.ExpectedInclusionState{ + Confirmed: tests.False(), + Finalized: tests.False(), + Conflicting: tests.False(), + Solid: tests.True(), + Rejected: tests.False(), + Liked: tests.True(), + Preferred: tests.True(), + }) + } + + // merge back the partitions + log.Println("merging partitions...") + assert.NoError(t, n.DeletePartitions(), "merging the network partitions should work") + log.Println("waiting for resolved partitions to autopeer to each other") + err = n.WaitForAutopeering(4) + require.NoError(t, err) + + // ensure message flow so that both partitions will get the conflicting tx + for _, p := range n.Peers() { + tests.SendDataMessage(t, p, []byte("DATA"), 10) + } + + log.Println("waiting for transactions to be available on all peers...") + missing, err := tests.AwaitTransactionAvailability(n.Peers(), conflictingTxIDs, 30*time.Second) + if err != nil { + assert.NoError(t, err, "transactions should have been available") + for p, missingOnPeer := range missing { + log.Printf("missing on peer %s:", p) + for missingTx := range missingOnPeer { + log.Println("tx id: ", missingTx) + } + } + return + } + + expectations := map[string]*tests.ExpectedTransaction{} + for _, conflictingTx := range conflictingTxs { + utilsTx := utils.ParseTransaction(conflictingTx) + expectations[conflictingTx.ID().String()] = &tests.ExpectedTransaction{ + Inputs: &utilsTx.Inputs, + Outputs: &utilsTx.Outputs, + Signature: &utilsTx.Signature, + } + } + + // check that the transactions are marked as conflicting + tests.CheckTransactions(t, n.Peers(), expectations, true, tests.ExpectedInclusionState{ + Finalized: tests.False(), + Conflicting: tests.True(), + Solid: tests.True(), + }) + + // wait until the voting has finalized + log.Println("waiting for voting/transaction finalization to be done on all peers...") + awaitFinalization := map[string]tests.ExpectedInclusionState{} + for _, conflictingTx := range conflictingTxs { + awaitFinalization[conflictingTx.ID().String()] = tests.ExpectedInclusionState{ + Finalized: tests.True(), + } + } + err = tests.AwaitTransactionInclusionState(n.Peers(), awaitFinalization, 2*time.Minute) + assert.NoError(t, err) + + // now all transactions must be finalized and at most one must be confirmed + var confirmedOverConflictSet int + for _, conflictingTx := range conflictingTxIDs { + var rejected, confirmed int + for _, p := range n.Peers() { + tx, err := p.GetTransactionByID(conflictingTx) + assert.NoError(t, err) + if tx.InclusionState.Confirmed { + confirmed++ + continue + } + if tx.InclusionState.Rejected { + rejected++ + } + } + + if rejected != 0 { + assert.Len(t, n.Peers(), rejected, "the rejected count for %s should be equal to the amount of peers", conflictingTx) + } + if confirmed != 0 { + assert.Len(t, n.Peers(), confirmed, "the confirmed count for %s should be equal to the amount of peers", conflictingTx) + confirmedOverConflictSet++ + } + + assert.False(t, rejected == 0 && confirmed == 0, "a transaction must either be rejected or confirmed") + } + + // there must only be one confirmed transaction out of the conflict set + if confirmedOverConflictSet != 0 { + assert.Equal(t, 1, confirmedOverConflictSet, "only one transaction can be confirmed out of the conflict set. %d of %d are confirmed", confirmedOverConflictSet, len(conflictingTxIDs)) + } +} diff --git a/tools/integration-tests/tester/tests/consensus/consensus_noconflicts_test.go b/tools/integration-tests/tester/tests/consensus/consensus_noconflicts_test.go new file mode 100644 index 0000000000000000000000000000000000000000..badf4040180e3135368f021125eca471be2a8f19 --- /dev/null +++ b/tools/integration-tests/tester/tests/consensus/consensus_noconflicts_test.go @@ -0,0 +1,129 @@ +package consensus + +import ( + "log" + "math/rand" + "testing" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/mr-tron/base58/base58" + "github.com/stretchr/testify/require" +) + +// TestConsensusNoConflicts issues valid non-conflicting value objects and then checks +// whether the ledger of every peer reflects the same correct state. +func TestConsensusNoConflicts(t *testing.T) { + n, err := f.CreateNetwork("consensus_TestConsensusNoConflicts", 4, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + time.Sleep(5 * time.Second) + + // genesis wallet + genesisSeedBytes, err := base58.Decode("7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih") + require.NoError(t, err, "couldn't decode genesis seed from base58 seed") + + const genesisBalance = 1000000000 + genesisWallet := wallet.New(genesisSeedBytes) + genesisAddr := genesisWallet.Seed().Address(0) + genesisOutputID := transaction.NewOutputID(genesisAddr, transaction.GenesisID) + + firstReceiver := wallet.New() + const depositCount = 10 + const deposit = genesisBalance / depositCount + firstReceiverAddresses := make([]string, depositCount) + firstReceiverDepositAddrs := make([]address.Address, depositCount) + firstReceiverDepositOutputs := map[address.Address][]*balance.Balance{} + firstReceiverExpectedBalances := map[string]map[balance.Color]int64{} + for i := 0; i < depositCount; i++ { + addr := firstReceiver.Seed().Address(uint64(i)) + firstReceiverDepositAddrs[i] = addr + firstReceiverAddresses[i] = addr.String() + firstReceiverDepositOutputs[addr] = []*balance.Balance{{Value: deposit, Color: balance.ColorIOTA}} + firstReceiverExpectedBalances[addr.String()] = map[balance.Color]int64{balance.ColorIOTA: deposit} + } + + // issue transaction spending from the genesis output + log.Printf("issuing transaction spending genesis to %d addresses", depositCount) + tx := transaction.New(transaction.NewInputs(genesisOutputID), transaction.NewOutputs(firstReceiverDepositOutputs)) + tx = tx.Sign(signaturescheme.ED25519(*genesisWallet.Seed().KeyPair(0))) + utilsTx := utils.ParseTransaction(tx) + + txID, err := n.Peers()[0].SendTransaction(tx.Bytes()) + require.NoError(t, err) + + // wait for the transaction to be propagated through the network + // and it becoming preferred, finalized and confirmed + log.Println("waiting 2.5 avg. network delays") + time.Sleep(valuetransfers.DefaultAverageNetworkDelay*2 + valuetransfers.DefaultAverageNetworkDelay/2) + + // since we just issued a transaction spending the genesis output, there + // shouldn't be any UTXOs on the genesis address anymore + log.Println("checking that genesis has no UTXOs") + tests.CheckAddressOutputsFullyConsumed(t, n.Peers(), []string{genesisAddr.String()}) + + // since we waited 2.5 avg. network delays and there were no conflicting transactions, + // the transaction we just issued must be preferred, liked, finalized and confirmed + log.Println("check that the transaction is finalized/confirmed by all peers") + tests.CheckTransactions(t, n.Peers(), map[string]*tests.ExpectedTransaction{ + txID: {Inputs: &utilsTx.Inputs, Outputs: &utilsTx.Outputs, Signature: &utilsTx.Signature}, + }, true, tests.ExpectedInclusionState{ + Confirmed: tests.True(), Finalized: tests.True(), + Conflicting: tests.False(), Solid: tests.True(), + Rejected: tests.False(), Liked: tests.True(), + }) + + // check balances on peers + log.Println("ensure that all the peers have the same ledger state") + tests.CheckBalances(t, n.Peers(), firstReceiverExpectedBalances) + + // issue transactions spending all the outputs which were just created from a random peer + secondReceiverWallet := wallet.New() + secondReceiverAddresses := make([]string, depositCount) + secondReceiverExpectedBalances := map[string]map[balance.Color]int64{} + secondReceiverExpectedTransactions := map[string]*tests.ExpectedTransaction{} + for i := 0; i < depositCount; i++ { + addr := secondReceiverWallet.Seed().Address(uint64(i)) + tx := transaction.New( + transaction.NewInputs(transaction.NewOutputID(firstReceiver.Seed().Address(uint64(i)), tx.ID())), + transaction.NewOutputs(map[address.Address][]*balance.Balance{ + addr: {{Value: deposit, Color: balance.ColorIOTA}}, + }), + ) + secondReceiverAddresses[i] = addr.String() + tx = tx.Sign(signaturescheme.ED25519(*firstReceiver.Seed().KeyPair(uint64(i)))) + txID, err := n.Peers()[rand.Intn(len(n.Peers()))].SendTransaction(tx.Bytes()) + require.NoError(t, err) + + utilsTx := utils.ParseTransaction(tx) + secondReceiverExpectedBalances[addr.String()] = map[balance.Color]int64{balance.ColorIOTA: deposit} + secondReceiverExpectedTransactions[txID] = &tests.ExpectedTransaction{ + Inputs: &utilsTx.Inputs, Outputs: &utilsTx.Outputs, Signature: &utilsTx.Signature, + } + } + + // wait again some network delays for the transactions to materialize + log.Println("waiting 2.5 avg. network delays") + time.Sleep(valuetransfers.DefaultAverageNetworkDelay*2 + valuetransfers.DefaultAverageNetworkDelay/2) + log.Println("checking that first set of addresses contain no UTXOs") + tests.CheckAddressOutputsFullyConsumed(t, n.Peers(), firstReceiverAddresses) + log.Println("checking that the 2nd batch transactions are finalized/confirmed") + tests.CheckTransactions(t, n.Peers(), secondReceiverExpectedTransactions, true, + tests.ExpectedInclusionState{ + Confirmed: tests.True(), Finalized: tests.True(), + Conflicting: tests.False(), Solid: tests.True(), + Rejected: tests.False(), Liked: tests.True(), + }, + ) + + log.Println("check that the 2nd batch of receive addresses is the same on all peers") + tests.CheckBalances(t, n.Peers(), secondReceiverExpectedBalances) +} diff --git a/tools/integration-tests/tester/tests/consensus/main_test.go b/tools/integration-tests/tester/tests/consensus/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..422928f9627868376b0610691f0e3ac2f6108636 --- /dev/null +++ b/tools/integration-tests/tester/tests/consensus/main_test.go @@ -0,0 +1,23 @@ +package consensus + +import ( + "os" + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" +) + +var f *framework.Framework + +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. +func TestMain(m *testing.M) { + var err error + f, err = framework.Instance() + if err != nil { + panic(err) + } + + // call the tests + os.Exit(m.Run()) +} diff --git a/tools/integration-tests/tester/tests/drng/drng_test.go b/tools/integration-tests/tester/tests/drng/drng_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4db5911975cc4a2b89b6ab892faccfd30bea1f50 --- /dev/null +++ b/tools/integration-tests/tester/tests/drng/drng_test.go @@ -0,0 +1,82 @@ +package drng + +import ( + "encoding/json" + "fmt" + "log" + "sync" + "testing" + "time" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/stretchr/testify/require" +) + +var ( + errWrongRound = fmt.Errorf("wrong round") +) + +// TestDRNG checks whether drng messages are actually relayed/gossiped through the network +// by checking the messages' existence on all nodes after a cool down. +func TestDRNG(t *testing.T) { + var wg sync.WaitGroup + + drng, err := f.CreateDRNGNetwork("TestDRNG", 5, 8, 3) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, drng) + + // wait for randomness generation to be started + log.Printf("Waiting for randomness generation to be started...\n") + + // randomness starts at round = 2 + firstRound := uint64(2) + _, err = waitForRound(t, drng.Peers()[0], firstRound, 200) + require.NoError(t, err) + + log.Printf("Waiting for randomness generation to be started... done\n") + + ticker := time.NewTimer(0) + defer ticker.Stop() + + numChecks := 3 + i := 0 + for { + select { + case <-ticker.C: + ticker.Reset(10 * time.Second) + + // check for randomness on every peer + for _, peer := range drng.Peers() { + wg.Add(1) + go func(peer *framework.Peer) { + defer wg.Done() + s, err := waitForRound(t, peer, firstRound+uint64(i), 8) + require.NoError(t, err, peer.ID().String(), s) + t.Log(peer.ID().String(), s) + }(peer) + } + + wg.Wait() + i++ + + if i == numChecks { + return + } + } + } +} + +func waitForRound(t *testing.T, peer *framework.Peer, round uint64, maxAttempts int) (string, error) { + var b []byte + for i := 0; i < maxAttempts; i++ { + resp, err := peer.GetRandomness() + require.NoError(t, err) + b, _ = json.MarshalIndent(resp, "", " ") + if resp.Round == round { + return string(b), nil + } + time.Sleep(1 * time.Second) + } + return string(b), errWrongRound +} diff --git a/tools/integration-tests/tester/tests/drng/main_test.go b/tools/integration-tests/tester/tests/drng/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..27877125211c397ac15776329b7a87ce5cb2c9f9 --- /dev/null +++ b/tools/integration-tests/tester/tests/drng/main_test.go @@ -0,0 +1,23 @@ +package drng + +import ( + "os" + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" +) + +var f *framework.Framework + +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. +func TestMain(m *testing.M) { + var err error + f, err = framework.Instance() + if err != nil { + panic(err) + } + + // call the tests + os.Exit(m.Run()) +} diff --git a/tools/integration-tests/tester/tests/faucet/faucet_test.go b/tools/integration-tests/tester/tests/faucet/faucet_test.go new file mode 100644 index 0000000000000000000000000000000000000000..7870e202ede127a4a93c83384638b70bd30d6e75 --- /dev/null +++ b/tools/integration-tests/tester/tests/faucet/faucet_test.go @@ -0,0 +1,64 @@ +package faucet + +import ( + "testing" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/stretchr/testify/require" +) + +// TestFaucetPersistence sends funds by faucet request. +func TestFaucetPersistence(t *testing.T) { + prevPoWDiff := framework.ParaPoWDifficulty + framework.ParaPoWDifficulty = 0 + defer func() { + framework.ParaPoWDifficulty = prevPoWDiff + }() + n, err := f.CreateNetwork("faucet_TestPersistence", 5, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + peers := n.Peers() + + // wait for peers to change their state to synchronized + time.Sleep(5 * time.Second) + + // master node sends funds to all peers in the network + ids, addrBalance := tests.SendFaucetRequestOnRandomPeer(t, peers[1:], 10) + + // wait for messages to be gossiped + time.Sleep(2 * valuetransfers.DefaultAverageNetworkDelay) + + // check whether all issued messages are available on all nodes + tests.CheckForMessageIds(t, n.Peers(), ids, true) + + // wait for transactions to be gossiped + time.Sleep(2 * valuetransfers.DefaultAverageNetworkDelay) + + // check ledger state + tests.CheckBalances(t, peers[1:], addrBalance) + + // stop all nodes + for _, peer := range n.Peers() { + err = peer.Stop() + require.NoError(t, err) + } + + // start all nodes + for _, peer := range n.Peers() { + err = peer.Start() + require.NoError(t, err) + } + + // wait for peers to start + time.Sleep(20 * time.Second) + + // check whether all issued messages are available on all nodes + tests.CheckForMessageIds(t, n.Peers(), ids, true) + + // check ledger state + tests.CheckBalances(t, peers[1:], addrBalance) +} diff --git a/tools/integration-tests/tester/tests/faucet/main_test.go b/tools/integration-tests/tester/tests/faucet/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a7f7a9692bfe546a8c4de580dc9a440748b778e0 --- /dev/null +++ b/tools/integration-tests/tester/tests/faucet/main_test.go @@ -0,0 +1,23 @@ +package faucet + +import ( + "os" + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" +) + +var f *framework.Framework + +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. +func TestMain(m *testing.M) { + var err error + f, err = framework.Instance() + if err != nil { + panic(err) + } + + // call the tests + os.Exit(m.Run()) +} diff --git a/tools/integration-tests/tester/tests/message/main_test.go b/tools/integration-tests/tester/tests/message/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4d3e5451fbcbed76b446721062a23f6c515d1dbf --- /dev/null +++ b/tools/integration-tests/tester/tests/message/main_test.go @@ -0,0 +1,23 @@ +package message + +import ( + "os" + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" +) + +var f *framework.Framework + +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. +func TestMain(m *testing.M) { + var err error + f, err = framework.Instance() + if err != nil { + panic(err) + } + + // call the tests + os.Exit(m.Run()) +} diff --git a/tools/integration-tests/tester/tests/message/message_test.go b/tools/integration-tests/tester/tests/message/message_test.go new file mode 100644 index 0000000000000000000000000000000000000000..11315ebb0804713a320a751d923445bf512b2659 --- /dev/null +++ b/tools/integration-tests/tester/tests/message/message_test.go @@ -0,0 +1,46 @@ +package message + +import ( + "testing" + "time" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/stretchr/testify/require" +) + +// TestPersistence issues messages on random peers, restarts them and checks for persistence after restart. +func TestPersistence(t *testing.T) { + n, err := f.CreateNetwork("message_TestPersistence", 4, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + // wait for peers to change their state to synchronized + time.Sleep(5 * time.Second) + + // 1. issue data messages + ids := tests.SendDataMessagesOnRandomPeer(t, n.Peers(), 100) + + // wait for messages to be gossiped + time.Sleep(10 * time.Second) + + // 2. check whether all issued messages are available on all nodes + tests.CheckForMessageIds(t, n.Peers(), ids, true) + + // 3. stop all nodes + for _, peer := range n.Peers() { + err = peer.Stop() + require.NoError(t, err) + } + + // 4. start all nodes + for _, peer := range n.Peers() { + err = peer.Start() + require.NoError(t, err) + } + + // wait for peers to start + time.Sleep(10 * time.Second) + + // 5. check whether all issued messages are persistently available on all nodes + tests.CheckForMessageIds(t, n.Peers(), ids, false) +} diff --git a/tools/integration-tests/tester/tests/testutil.go b/tools/integration-tests/tester/tests/testutil.go new file mode 100644 index 0000000000000000000000000000000000000000..42aa18741dbfbcd9967bab878feeb77b2e1a12a8 --- /dev/null +++ b/tools/integration-tests/tester/tests/testutil.go @@ -0,0 +1,617 @@ +package tests + +import ( + "errors" + "fmt" + "math/rand" + "sync" + "sync/atomic" + "testing" + "time" + + faucet_payload "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/plugins/webapi/value/utils" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" + "github.com/iotaledger/hive.go/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ( + ErrTransactionNotAvailableInTime = errors.New("transaction was not available in time") + ErrTransactionStateNotSameInTime = errors.New("transaction state did not materialize in time") +) + +const maxRetry = 50 + +// DataMessageSent defines a struct to identify from which issuer a data message was sent. +type DataMessageSent struct { + number int + id string + data []byte + issuerPublicKey string +} + +type Shutdowner interface { + Shutdown() error +} + +// SendDataMessagesOnRandomPeer sends data messages on a random peer and saves the sent message to a map. +func SendDataMessagesOnRandomPeer(t *testing.T, peers []*framework.Peer, numMessages int, idsMap ...map[string]DataMessageSent) map[string]DataMessageSent { + var ids map[string]DataMessageSent + if len(idsMap) > 0 { + ids = idsMap[0] + } else { + ids = make(map[string]DataMessageSent, numMessages) + } + + for i := 0; i < numMessages; i++ { + data := []byte(fmt.Sprintf("Test%d", i)) + + peer := peers[rand.Intn(len(peers))] + id, sent := SendDataMessage(t, peer, data, i) + + ids[id] = sent + } + + return ids +} + +// SendDataMessage sends a data message on a given peer and returns the id and a DataMessageSent struct. +func SendDataMessage(t *testing.T, peer *framework.Peer, data []byte, number int) (string, DataMessageSent) { + id, err := peer.Data(data) + require.NoErrorf(t, err, "could not send message on %s", peer.String()) + + sent := DataMessageSent{ + number: number, + id: id, + // save payload to be able to compare API response + data: payload.NewData(data).Bytes(), + issuerPublicKey: peer.Identity.PublicKey().String(), + } + return id, sent +} + +// SendFaucetRequestOnRandomPeer sends a faucet request on a given peer and returns the id and a DataMessageSent struct. +func SendFaucetRequestOnRandomPeer(t *testing.T, peers []*framework.Peer, numMessages int) (ids map[string]DataMessageSent, addrBalance map[string]map[balance.Color]int64) { + ids = make(map[string]DataMessageSent, numMessages) + addrBalance = make(map[string]map[balance.Color]int64) + for _, p := range peers { + addr := p.Seed().Address(0).String() + addrBalance[addr] = make(map[balance.Color]int64) + addrBalance[addr][balance.ColorIOTA] = 0 + } + + for i := 0; i < numMessages; i++ { + peer := peers[rand.Intn(len(peers))] + id, sent := SendFaucetRequest(t, peer) + + ids[id] = sent + addrBalance[peer.Seed().Address(0).String()][balance.ColorIOTA] += framework.ParaFaucetTokensPerRequest + } + + return ids, addrBalance +} + +// SendFaucetRequest sends a data message on a given peer and returns the id and a DataMessageSent struct. +func SendFaucetRequest(t *testing.T, peer *framework.Peer) (string, DataMessageSent) { + addr := peer.Seed().Address(0) + resp, err := peer.SendFaucetRequest(addr.String()) + require.NoErrorf(t, err, "Could not send faucet request on %s", peer.String()) + + sent := DataMessageSent{ + id: resp.ID, + // save payload to be able to compare API response + data: faucet_payload.New(addr).Bytes(), + issuerPublicKey: peer.Identity.PublicKey().String(), + } + return resp.ID, sent +} + +// CheckForMessageIds performs checks to make sure that all peers received all given messages defined in ids. +func CheckForMessageIds(t *testing.T, peers []*framework.Peer, ids map[string]DataMessageSent, checkSynchronized bool) { + var idsSlice []string + for id := range ids { + idsSlice = append(idsSlice, id) + } + + for _, peer := range peers { + if checkSynchronized { + // check that the peer sees itself as synchronized + info, err := peer.Info() + require.NoError(t, err) + require.True(t, info.Synced) + } + + resp, err := peer.FindMessageByID(idsSlice) + require.NoError(t, err) + + // check that all messages are present in response + respIDs := make([]string, len(resp.Messages)) + for i, msg := range resp.Messages { + respIDs[i] = msg.ID + } + assert.ElementsMatchf(t, idsSlice, respIDs, "messages do not match sent in %s", peer.String()) + + // check for general information + for _, msg := range resp.Messages { + msgSent := ids[msg.ID] + + assert.Equalf(t, msgSent.issuerPublicKey, msg.IssuerPublicKey, "messageID=%s, issuer=%s not correct issuer in %s.", msgSent.id, msgSent.issuerPublicKey, peer.String()) + assert.Equalf(t, msgSent.data, msg.Payload, "messageID=%s, issuer=%s data not equal in %s.", msgSent.id, msgSent.issuerPublicKey, peer.String()) + assert.Truef(t, msg.Metadata.Solid, "messageID=%s, issuer=%s not solid in %s.", msgSent.id, msgSent.issuerPublicKey, peer.String()) + } + } +} + +// SendTransactionFromFaucet sends funds to peers from the faucet, sends back the remainder to faucet, and returns the transaction ID. +func SendTransactionFromFaucet(t *testing.T, peers []*framework.Peer, sentValue int64) (txIds []string, addrBalance map[string]map[balance.Color]int64) { + // initiate addrBalance map + addrBalance = make(map[string]map[balance.Color]int64) + for _, p := range peers { + addr := p.Seed().Address(0).String() + addrBalance[addr] = make(map[balance.Color]int64) + } + + faucetPeer := peers[0] + faucetAddrStr := faucetPeer.Seed().Address(0).String() + + // get faucet balances + unspentOutputs, err := faucetPeer.GetUnspentOutputs([]string{faucetAddrStr}) + require.NoErrorf(t, err, "could not get unspent outputs on %s", faucetPeer.String()) + addrBalance[faucetAddrStr][balance.ColorIOTA] = unspentOutputs.UnspentOutputs[0].OutputIDs[0].Balances[0].Value + + // send funds to other peers + for i := 1; i < len(peers); i++ { + fail, txId := SendIotaTransaction(t, faucetPeer, peers[i], addrBalance, sentValue) + require.False(t, fail) + txIds = append(txIds, txId) + + // let the transaction propagate + time.Sleep(3 * time.Second) + } + + return +} + +// SendTransactionOnRandomPeer sends sentValue amount of IOTA tokens from/to a random peer, mutates the given balance map and returns the transaction IDs. +func SendTransactionOnRandomPeer(t *testing.T, peers []*framework.Peer, addrBalance map[string]map[balance.Color]int64, numMessages int, sentValue int64) (txIds []string) { + counter := 0 + for i := 0; i < numMessages; i++ { + from := rand.Intn(len(peers)) + to := rand.Intn(len(peers)) + fail, txId := SendIotaTransaction(t, peers[from], peers[to], addrBalance, sentValue) + if fail { + i-- + counter++ + if counter >= maxRetry { + return + } + continue + } + + // attach tx id + txIds = append(txIds, txId) + + // let the transaction propagate + time.Sleep(3 * time.Second) + } + + return +} + +// SendIotaTransaction sends sentValue amount of IOTA tokens and remainders from and to a given peer and returns the fail flag and the transaction ID. +// Every peer sends and receives the transaction on the address of index 0. +func SendIotaTransaction(t *testing.T, from *framework.Peer, to *framework.Peer, addrBalance map[string]map[balance.Color]int64, sentValue int64) (fail bool, txId string) { + sigScheme := signaturescheme.ED25519(*from.Seed().KeyPair(0)) + inputAddr := from.Seed().Address(0) + outputAddr := to.Seed().Address(0) + + // prepare inputs + resp, err := from.GetUnspentOutputs([]string{inputAddr.String()}) + require.NoErrorf(t, err, "could not get unspent outputs on %s", from.String()) + + // abort if no unspent outputs + if len(resp.UnspentOutputs[0].OutputIDs) == 0 { + return true, "" + } + availableValue := resp.UnspentOutputs[0].OutputIDs[0].Balances[0].Value + + // abort if the balance is not enough + if availableValue < sentValue { + return true, "" + } + + out, err := transaction.OutputIDFromBase58(resp.UnspentOutputs[0].OutputIDs[0].ID) + require.NoErrorf(t, err, "invalid unspent outputs ID on %s", from.String()) + inputs := transaction.NewInputs([]transaction.OutputID{out}...) + + // prepare outputs + outmap := map[address.Address][]*balance.Balance{} + if inputAddr == outputAddr { + sentValue = availableValue + } + + // set balances + outmap[outputAddr] = []*balance.Balance{balance.New(balance.ColorIOTA, sentValue)} + outputs := transaction.NewOutputs(outmap) + + // handle remainder address + if availableValue > sentValue { + outputs.Add(inputAddr, []*balance.Balance{balance.New(balance.ColorIOTA, availableValue-sentValue)}) + } + + // sign transaction + txn := transaction.New(inputs, outputs).Sign(sigScheme) + + // send transaction + txId, err = from.SendTransaction(txn.Bytes()) + require.NoErrorf(t, err, "could not send transaction on %s", from.String()) + + addrBalance[inputAddr.String()][balance.ColorIOTA] -= sentValue + addrBalance[outputAddr.String()][balance.ColorIOTA] += sentValue + + return false, txId +} + +// SendColoredTransactionOnRandomPeer sends colored tokens on a random peer, saves the sent token amount to a map, and returns transaction IDs. +func SendColoredTransactionOnRandomPeer(t *testing.T, peers []*framework.Peer, addrBalance map[string]map[balance.Color]int64, numMessages int) (txIds []string) { + counter := 0 + for i := 0; i < numMessages; i++ { + from := rand.Intn(len(peers)) + to := rand.Intn(len(peers)) + fail, txId := SendColoredTransaction(t, peers[from], peers[to], addrBalance) + if fail { + i-- + counter++ + if counter >= maxRetry { + return + } + continue + } + + // attach tx id + txIds = append(txIds, txId) + + // let the transaction propagate + time.Sleep(3 * time.Second) + } + + return +} + +// SendColoredTransaction sends IOTA and colored tokens from and to a given peer and returns the fail flag and the transaction ID. +// 1. Get the first unspent outputs of `from` +// 2. Accumulate the token amount of the first unspent output +// 3. Send 50 IOTA tokens + [accumalate token amount - 50] new minted tokens to `to` +func SendColoredTransaction(t *testing.T, from *framework.Peer, to *framework.Peer, addrBalance map[string]map[balance.Color]int64) (fail bool, txId string) { + var sentValue int64 = 50 + var balanceList []*balance.Balance + sigScheme := signaturescheme.ED25519(*from.Seed().KeyPair(0)) + inputAddr := from.Seed().Address(0) + outputAddr := to.Seed().Address(0) + + // prepare inputs + resp, err := from.GetUnspentOutputs([]string{inputAddr.String()}) + require.NoErrorf(t, err, "could not get unspent outputs on %s", from.String()) + + // abort if no unspent outputs + if len(resp.UnspentOutputs[0].OutputIDs) == 0 { + return true, "" + } + + // calculate available token in the unspent output + var availableValue int64 = 0 + for _, b := range resp.UnspentOutputs[0].OutputIDs[0].Balances { + availableValue += b.Value + balanceList = append(balanceList, balance.New(getColorFromString(b.Color), (-1)*b.Value)) + } + + // abort if not enough tokens + if availableValue < sentValue { + return true, "" + } + + out, err := transaction.OutputIDFromBase58(resp.UnspentOutputs[0].OutputIDs[0].ID) + require.NoErrorf(t, err, "invalid unspent outputs ID on %s", from.String()) + inputs := transaction.NewInputs([]transaction.OutputID{out}...) + + // prepare outputs + outmap := map[address.Address][]*balance.Balance{} + + // set balances + outmap[outputAddr] = []*balance.Balance{balance.New(balance.ColorIOTA, sentValue)} + if availableValue > sentValue { + outmap[outputAddr] = append(outmap[outputAddr], balance.New(balance.ColorNew, availableValue-sentValue)) + } + outputs := transaction.NewOutputs(outmap) + + // sign transaction + txn := transaction.New(inputs, outputs).Sign(sigScheme) + + // send transaction + txId, err = from.SendTransaction(txn.Bytes()) + require.NoErrorf(t, err, "could not send transaction on %s", from.String()) + + // update balance list + balanceList = append(balanceList, outmap[outputAddr]...) + updateBalanceList(addrBalance, balanceList, inputAddr.String(), outputAddr.String(), txId) + + return false, txId +} + +// updateBalanceList updates the token amount map with given peers and balances. +// If the value of balance is negative, it is the balance to be deducted from peer from, else it is deposited to peer to. +// If the color is balance.ColorNew, it should be recolored with txId. +func updateBalanceList(addrBalance map[string]map[balance.Color]int64, balances []*balance.Balance, from, to, txId string) { + for _, b := range balances { + color := b.Color + value := b.Value + if value < 0 { + // deduct + addrBalance[from][color] += value + continue + } + // deposit + if color == balance.ColorNew { + addrBalance[to][getColorFromString(txId)] = value + continue + } + addrBalance[to][color] += value + } + return +} + +func getColorFromString(colorStr string) (color balance.Color) { + if colorStr == "IOTA" { + color = balance.ColorIOTA + } else { + t, _ := transaction.IDFromBase58(colorStr) + color, _, _ = balance.ColorFromBytes(t.Bytes()) + } + return +} + +// CheckBalances performs checks to make sure that all peers have the same ledger state. +func CheckBalances(t *testing.T, peers []*framework.Peer, addrBalance map[string]map[balance.Color]int64) { + for _, peer := range peers { + for addr, b := range addrBalance { + sum := make(map[balance.Color]int64) + resp, err := peer.GetUnspentOutputs([]string{addr}) + require.NoError(t, err) + assert.Equal(t, addr, resp.UnspentOutputs[0].Address) + + // calculate the balances of each colored coin + for _, unspents := range resp.UnspentOutputs[0].OutputIDs { + for _, respBalance := range unspents.Balances { + color := getColorFromString(respBalance.Color) + sum[color] += respBalance.Value + } + } + + // check balances + for color, value := range sum { + assert.Equal(t, b[color], value) + } + } + } +} + +// CheckAddressOutputsFullyConsumed performs checks to make sure that on all given peers, +// the given addresses have no UTXOs. +func CheckAddressOutputsFullyConsumed(t *testing.T, peers []*framework.Peer, addrs []string) { + for _, peer := range peers { + resp, err := peer.GetUnspentOutputs(addrs) + assert.NoError(t, err) + assert.Len(t, resp.Error, 0) + for i, utxos := range resp.UnspentOutputs { + assert.Len(t, utxos.OutputIDs, 0, "address %s should not have any UTXOs", addrs[i]) + } + } +} + +// ExpectedInclusionState is an expected inclusion state. +// All fields are optional. +type ExpectedInclusionState struct { + // The optional confirmed state to check against. + Confirmed *bool + // The optional finalized state to check against. + Finalized *bool + // The optional conflict state to check against. + Conflicting *bool + // The optional solid state to check against. + Solid *bool + // The optional rejected state to check against. + Rejected *bool + // The optional liked state to check against. + Liked *bool + // The optional preferred state to check against. + Preferred *bool +} + +// True returns a pointer to a true bool. +func True() *bool { + x := true + return &x +} + +// False returns a pointer to a false bool. +func False() *bool { + x := false + return &x +} + +// ExpectedTransaction defines the expected data of a transaction. +// All fields are optional. +type ExpectedTransaction struct { + // The optional input IDs to check against. + Inputs *[]string + // The optional outputs to check against. + Outputs *[]utils.Output + // The optional signature to check against. + Signature *[]byte +} + +// CheckTransactions performs checks to make sure that all peers have received all transactions. +// Optionally takes an expected inclusion state for all supplied transaction IDs and expected transaction +// data per transaction ID. +func CheckTransactions(t *testing.T, peers []*framework.Peer, transactionIDs map[string]*ExpectedTransaction, checkSynchronized bool, expectedInclusionState ExpectedInclusionState) { + for _, peer := range peers { + if checkSynchronized { + // check that the peer sees itself as synchronized + info, err := peer.Info() + require.NoError(t, err) + require.True(t, info.Synced) + } + + for txId, expectedTransaction := range transactionIDs { + resp, err := peer.GetTransactionByID(txId) + require.NoError(t, err) + + // check inclusion state + if expectedInclusionState.Confirmed != nil { + assert.Equal(t, *expectedInclusionState.Confirmed, resp.InclusionState.Confirmed, "confirmed state doesn't match - %s", txId) + } + if expectedInclusionState.Conflicting != nil { + assert.Equal(t, *expectedInclusionState.Conflicting, resp.InclusionState.Conflicting, "conflict state doesn't match - %s", txId) + } + if expectedInclusionState.Solid != nil { + assert.Equal(t, *expectedInclusionState.Solid, resp.InclusionState.Solid, "solid state doesn't match - %s", txId) + } + if expectedInclusionState.Rejected != nil { + assert.Equal(t, *expectedInclusionState.Rejected, resp.InclusionState.Rejected, "rejected state doesn't match - %s", txId) + } + if expectedInclusionState.Liked != nil { + assert.Equal(t, *expectedInclusionState.Liked, resp.InclusionState.Liked, "liked state doesn't match - %s", txId) + } + if expectedInclusionState.Preferred != nil { + assert.Equal(t, *expectedInclusionState.Preferred, resp.InclusionState.Preferred, "preferred state doesn't match - %s", txId) + } + + if expectedTransaction != nil { + if expectedTransaction.Inputs != nil { + assert.Equal(t, *expectedTransaction.Inputs, resp.Transaction.Inputs, "inputs do not match - %s", txId) + } + if expectedTransaction.Outputs != nil { + assert.Equal(t, *expectedTransaction.Outputs, resp.Transaction.Outputs, "outputs do not match - %s", txId) + } + if expectedTransaction.Signature != nil { + assert.Equal(t, *expectedTransaction.Signature, resp.Transaction.Signature, "signatures do not match - %s", txId) + } + } + } + } +} + +// AwaitTransactionAvailability awaits until the given transaction IDs become available on all given peers or +// the max duration is reached. Returns a map of missing transactions per peer. An error is returned if at least +// one peer does not have all specified transactions available. +func AwaitTransactionAvailability(peers []*framework.Peer, transactionIDs []string, maxAwait time.Duration) (missing map[string]map[string]types.Empty, err error) { + s := time.Now() + var missingMu sync.Mutex + missing = map[string]map[string]types.Empty{} + for ; time.Since(s) < maxAwait; time.Sleep(500 * time.Millisecond) { + var wg sync.WaitGroup + wg.Add(len(peers)) + counter := int32(len(peers) * len(transactionIDs)) + for _, p := range peers { + go func(p *framework.Peer) { + defer wg.Done() + for _, txID := range transactionIDs { + _, err := p.GetTransactionByID(txID) + if err == nil { + missingMu.Lock() + m, has := missing[p.ID().String()] + if has { + delete(m, txID) + if len(m) == 0 { + delete(missing, p.ID().String()) + } + } + missingMu.Unlock() + atomic.AddInt32(&counter, -1) + continue + } + missingMu.Lock() + m, has := missing[p.ID().String()] + if !has { + m = map[string]types.Empty{} + } + m[txID] = types.Empty{} + missing[p.ID().String()] = m + missingMu.Unlock() + } + }(p) + } + wg.Wait() + if counter == 0 { + // everything available + return missing, nil + } + } + return missing, ErrTransactionNotAvailableInTime +} + +// AwaitTransactionInclusionState awaits on all given peers until the specified transactions +// have the expected state or max duration is reached. This function does not gracefully +// handle the transactions not existing on the given peers, therefore it must be ensured +// the the transactions exist beforehand. +func AwaitTransactionInclusionState(peers []*framework.Peer, transactionIDs map[string]ExpectedInclusionState, maxAwait time.Duration) error { + s := time.Now() + for ; time.Since(s) < maxAwait; time.Sleep(1 * time.Second) { + var wg sync.WaitGroup + wg.Add(len(peers)) + counter := int32(len(peers) * len(transactionIDs)) + for _, p := range peers { + go func(p *framework.Peer) { + defer wg.Done() + for txID := range transactionIDs { + tx, err := p.GetTransactionByID(txID) + if err != nil { + continue + } + expInclState := transactionIDs[txID] + if expInclState.Confirmed != nil && *expInclState.Confirmed != tx.InclusionState.Confirmed { + continue + } + if expInclState.Conflicting != nil && *expInclState.Conflicting != tx.InclusionState.Conflicting { + continue + } + if expInclState.Finalized != nil && *expInclState.Finalized != tx.InclusionState.Finalized { + continue + } + if expInclState.Liked != nil && *expInclState.Liked != tx.InclusionState.Liked { + continue + } + if expInclState.Preferred != nil && *expInclState.Preferred != tx.InclusionState.Preferred { + continue + } + if expInclState.Rejected != nil && *expInclState.Rejected != tx.InclusionState.Rejected { + continue + } + if expInclState.Solid != nil && *expInclState.Solid != tx.InclusionState.Solid { + continue + } + atomic.AddInt32(&counter, -1) + } + }(p) + } + wg.Wait() + if counter == 0 { + // everything available + return nil + } + } + return ErrTransactionStateNotSameInTime +} + +// ShutdownNetwork shuts down the network and reports errors. +func ShutdownNetwork(t *testing.T, n Shutdowner) { + err := n.Shutdown() + require.NoError(t, err) +} diff --git a/tools/integration-tests/tester/tests/value/main_test.go b/tools/integration-tests/tester/tests/value/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f5d00e21e7f402c843a19a25175355c7cead2ab2 --- /dev/null +++ b/tools/integration-tests/tester/tests/value/main_test.go @@ -0,0 +1,23 @@ +package value + +import ( + "os" + "testing" + + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework" +) + +var f *framework.Framework + +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. +func TestMain(m *testing.M) { + var err error + f, err = framework.Instance() + if err != nil { + panic(err) + } + + // call the tests + os.Exit(m.Run()) +} diff --git a/tools/integration-tests/tester/tests/value/value_test.go b/tools/integration-tests/tester/tests/value/value_test.go new file mode 100644 index 0000000000000000000000000000000000000000..316e661d802fa2690db8e37e1277ef7604ab90b3 --- /dev/null +++ b/tools/integration-tests/tester/tests/value/value_test.go @@ -0,0 +1,146 @@ +package value + +import ( + "testing" + "time" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers" + "github.com/iotaledger/goshimmer/tools/integration-tests/tester/tests" + "github.com/stretchr/testify/require" +) + +// TestTransactionPersistence issues messages on random peers, restarts them and checks for persistence after restart. +func TestTransactionPersistence(t *testing.T) { + n, err := f.CreateNetwork("transaction_TestPersistence", 4, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + // wait for peers to change their state to synchronized + time.Sleep(5 * time.Second) + + // master node sends funds to all peers in the network + txIdsSlice, addrBalance := tests.SendTransactionFromFaucet(t, n.Peers(), 100) + txIds := make(map[string]*tests.ExpectedTransaction) + for _, txID := range txIdsSlice { + txIds[txID] = nil + } + + // wait for messages to be gossiped + time.Sleep(2 * valuetransfers.DefaultAverageNetworkDelay) + + // check whether the first issued transaction is available on all nodes, and confirmed + tests.CheckTransactions(t, n.Peers(), txIds, true, tests.ExpectedInclusionState{ + Confirmed: tests.True(), + }) + + // check ledger state + tests.CheckBalances(t, n.Peers(), addrBalance) + + // send value message randomly + randomTxIds := tests.SendTransactionOnRandomPeer(t, n.Peers(), addrBalance, 10, 100) + for _, randomTxId := range randomTxIds { + txIds[randomTxId] = nil + } + + // wait for messages to be gossiped + time.Sleep(2 * valuetransfers.DefaultAverageNetworkDelay) + + // check whether all issued transactions are available on all nodes and confirmed + tests.CheckTransactions(t, n.Peers(), txIds, true, tests.ExpectedInclusionState{ + Confirmed: tests.True(), + }) + + // check ledger state + tests.CheckBalances(t, n.Peers(), addrBalance) + + // 3. stop all nodes + for _, peer := range n.Peers() { + err = peer.Stop() + require.NoError(t, err) + } + + // 4. start all nodes + for _, peer := range n.Peers() { + err = peer.Start() + require.NoError(t, err) + } + + // wait for peers to start + time.Sleep(20 * time.Second) + + // check whether all issued transactions are available on all nodes and confirmed + tests.CheckTransactions(t, n.Peers(), txIds, true, tests.ExpectedInclusionState{ + Confirmed: tests.True(), + }) + + // 5. check ledger state + tests.CheckBalances(t, n.Peers(), addrBalance) +} + +// TestValueColoredPersistence issues colored tokens on random peers, restarts them and checks for persistence after restart. +func TestValueColoredPersistence(t *testing.T) { + n, err := f.CreateNetwork("valueColor_TestPersistence", 4, 2) + require.NoError(t, err) + defer tests.ShutdownNetwork(t, n) + + // wait for peers to change their state to synchronized + time.Sleep(5 * time.Second) + + // master node sends funds to all peers in the network + txIdsSlice, addrBalance := tests.SendTransactionFromFaucet(t, n.Peers(), 100) + txIds := make(map[string]*tests.ExpectedTransaction) + for _, txID := range txIdsSlice { + txIds[txID] = nil + } + + // wait for messages to be gossiped + time.Sleep(2 * valuetransfers.DefaultAverageNetworkDelay) + + // check whether the transactions are available on all nodes, and confirmed + tests.CheckTransactions(t, n.Peers(), txIds, true, tests.ExpectedInclusionState{ + Confirmed: tests.True(), + }) + + // check ledger state + tests.CheckBalances(t, n.Peers(), addrBalance) + + // send funds around + randomTxIds := tests.SendColoredTransactionOnRandomPeer(t, n.Peers(), addrBalance, 10) + for _, randomTxId := range randomTxIds { + txIds[randomTxId] = nil + } + + // wait for value messages to be gossiped + time.Sleep(2 * valuetransfers.DefaultAverageNetworkDelay) + + // check whether all issued transactions are persistently available on all nodes, and confirmed + tests.CheckTransactions(t, n.Peers(), txIds, true, tests.ExpectedInclusionState{ + Confirmed: tests.True(), + }) + + // check ledger state + tests.CheckBalances(t, n.Peers(), addrBalance) + + // stop all nodes + for _, peer := range n.Peers() { + err = peer.Stop() + require.NoError(t, err) + } + + // start all nodes + for _, peer := range n.Peers() { + err = peer.Start() + require.NoError(t, err) + } + + // wait for peers to start + time.Sleep(20 * time.Second) + + // check whether all issued transactions are persistently available on all nodes, and confirmed + tests.CheckTransactions(t, n.Peers(), txIds, true, tests.ExpectedInclusionState{ + Confirmed: tests.True(), + }) + + // 5. check ledger state + tests.CheckBalances(t, n.Peers(), addrBalance) +} diff --git a/tools/monitoring/grafana/dashboards/local_dashboard.json b/tools/monitoring/grafana/dashboards/local_dashboard.json new file mode 100755 index 0000000000000000000000000000000000000000..7e4d3cb1805ad1cdb26b8570d2ab5eacc0d24c33 --- /dev/null +++ b/tools/monitoring/grafana/dashboards/local_dashboard.json @@ -0,0 +1,2380 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Shows metrics of a single node.", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 1, + "links": [], + "panels": [ + { + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 57, + "title": "Status", + "type": "row" + }, + { + "datasource": "Prometheus", + "description": "Version number of node software.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 0, + "y": 1 + }, + "id": 48, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^version$/", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "iota_info_app", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "GoShimmer", + "transformations": [ + { + "id": "labelsToFields", + "options": {} + } + ], + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Describes if the node is in synced state.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [ + { + "from": "", + "id": 0, + "operator": "", + "text": "No", + "to": "", + "type": 1, + "value": "0" + }, + { + "from": "", + "id": 1, + "operator": "", + "text": "Yes", + "to": "", + "type": 1, + "value": "1" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 2, + "y": 1 + }, + "id": 22, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "sync", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Synced", + "transformations": [], + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Aggregated MPS for all message types in the communication layer.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "MPS" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 4, + "y": 1 + }, + "id": 30, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "irate(tangle_message_total_count[5m])", + "interval": "", + "legendFormat": "Total MPS", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total MPS", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Current CPU usage of the node.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 6, + "y": 1 + }, + "id": 53, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "process_cpu_usage", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Memory consumed by the node.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 8, + "y": 1 + }, + "id": 20, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "process_mem_usage_bytes/1024/1024", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Consumption", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Size of the ledger database.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 10, + "y": 1 + }, + "id": 58, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "db_size_bytes/1024/1024", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Database Size", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 55, + "panels": [], + "title": "MPS, Autopeering, Traffic, Resources", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 11, + "x": 0, + "y": 4 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "7.0.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"data\"}[5m])", + "interval": "", + "legendFormat": "Data Message Per Second", + "refId": "A" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"value\"}[5m])", + "interval": "", + "legendFormat": "Transaction Per Second", + "refId": "B" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"drng\"}[5m])", + "interval": "", + "legendFormat": "dRNG Messages Per Second", + "refId": "C" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"faucet\"}[5m])", + "interval": "", + "legendFormat": "Faucet Messages Per Second", + "refId": "D" + }, + { + "expr": "irate(tangle_messages_per_type_count{message_type=\"netowrkdelay\"}[5m])", + "interval": "", + "legendFormat": "Network Delay Messages Per Second", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Message Per Second Per Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "MPS", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 13, + "x": 11, + "y": 4 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 0.5, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "autopeering_avg_distance", + "interval": "", + "legendFormat": "Average", + "refId": "A" + }, + { + "expr": "autopeering_max_distance", + "interval": "", + "legendFormat": "Max", + "refId": "B" + }, + { + "expr": "autopeering_min_distance", + "interval": "", + "legendFormat": "Min", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Autopeering Neighbor Distance", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": "Distance", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "Prometheus", + "description": "Number of currently connected neighbors.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 11, + "y": 12 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_neighbor_connections_count - autopeering_neighbor_drop_count", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Neighbors", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Calculated for each dropped neighbor.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 14, + "y": 12 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_avg_neighbor_connection_lifetime", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "AvgNeighbor Connection Lifetime", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Amount of newly registered neighbor connections.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 12 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_neighbor_connections_count", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "New Neighbor Connections", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Amount of neighbor connections dropped.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 21, + "y": 12 + }, + "id": 10, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "autopeering_neighbor_drop_count", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Dropped Neighbor Connections", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Shows tips in message and value layer.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 11, + "x": 0, + "y": 15 + }, + "hiddenSeries": false, + "id": 52, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "tangle_message_tips_count", + "interval": "", + "legendFormat": "Message Layer Tips", + "refId": "A" + }, + { + "expr": "tangle_value_tips", + "interval": "", + "legendFormat": "Value Layer Tips", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Tips", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 7, + "x": 11, + "y": 16 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_cpu_usage", + "interval": "", + "legendFormat": "CPU Usage", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 16 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_mem_usage_bytes/1024/1024", + "interval": "", + "legendFormat": "Memory Consumption", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Consumption", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decmbytes", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 11, + "x": 0, + "y": 25 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(traffic_analysis_outbound_bytes[1m])", + "interval": "", + "legendFormat": "Analysis TX", + "refId": "A" + }, + { + "expr": "irate(traffic_autopeering_inbound_bytes[1m])", + "interval": "", + "legendFormat": "Autopeering RX", + "refId": "B" + }, + { + "expr": "irate(traffic_autopeering_outbound_bytes[1m])", + "interval": "", + "legendFormat": "Autopeering TX", + "refId": "C" + }, + { + "expr": "irate(traffic_fpc_inbound_bytes[1m])", + "interval": "", + "legendFormat": "FPC RX", + "refId": "D" + }, + { + "expr": "irate(traffic_fpc_outbound_bytes[1m])", + "interval": "", + "legendFormat": "FPC TX", + "refId": "E" + }, + { + "expr": "irate(traffic_gossip_inbound_bytes[1m])", + "interval": "", + "legendFormat": "Gossip RX", + "refId": "F" + }, + { + "expr": "irate(traffic_gossip_outbound_bytes[1m])", + "interval": "", + "legendFormat": "Gossip Tx", + "refId": "G" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "content": "\n# Total Network Traffic\n\n\nSince the start of the node.\n", + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 11, + "y": 25 + }, + "id": 61, + "mode": "markdown", + "timeFrom": null, + "timeShift": null, + "title": "", + "type": "text" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 11, + "y": 28 + }, + "id": 67, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_gossip_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Gossip TX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 13, + "y": 28 + }, + "id": 66, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_gossip_inbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Gossip RX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 15, + "y": 28 + }, + "id": 59, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_analysis_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Analysis", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 11, + "y": 30 + }, + "id": 63, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_autopeering_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Autopeering TX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 14, + "y": 30 + }, + "id": 62, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_autopeering_inbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Autopeering RX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 11, + "y": 32 + }, + "id": 64, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_fpc_inbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "FPC RX", + "type": "stat" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 13, + "y": 32 + }, + "id": 65, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "traffic_fpc_outbound_bytes", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "FPC TX", + "type": "stat" + }, + { + "collapsed": false, + "datasource": "Prometheus", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 34, + "panels": [], + "title": "FPC", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 36 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "fpc_active_conflicts", + "interval": "", + "legendFormat": "Active Conflicts", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Conflicts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "Prometheus", + "description": "The average number of rounds it takes to finalize a conflict.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 12, + "y": 36 + }, + "id": 38, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "fpc_avg_rounds_to_finalize", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rounds To Finalize", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Number of finalized conflicts.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 16, + "y": 36 + }, + "id": 42, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "fpc_finalized_conflicts", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Finalized Conflicts", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Number of failed conflicts.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 19, + "y": 36 + }, + "id": 40, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.3", + "targets": [ + { + "expr": "fpc_failed_conflicts", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failed Conflicts", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Describes how many FPC query requests the node has received.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 44 + }, + "hiddenSeries": false, + "id": 44, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_queries_received[5m])", + "interval": "", + "legendFormat": "FPC Queries RX", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Queries RX", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 44 + }, + "hiddenSeries": false, + "id": 50, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_query_replies_not_received[5m])", + "interval": "", + "legendFormat": "FPC Queries TX Failed", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Queries TX Failed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Describes how many FPC opinions were requested from the node.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 52 + }, + "hiddenSeries": false, + "id": 49, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_queries_opinion_received[5m])", + "interval": "", + "legendFormat": "FPC Conflict Queries RX", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Conflict Queries RX", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Conflict Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 52 + }, + "hiddenSeries": false, + "id": 46, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(fpc_query_opinion_replies_not_received[5m])", + "interval": "", + "legendFormat": "FPC Conflict Queries TX Failed", + "refId": "A" + }, + { + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "FPC Conflict Queries TX Failed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "Conflict Queries Per Second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 25, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "GoShimmer Local Metrics", + "uid": "kjOQZ2ZMk", + "version": 5 +} diff --git a/tools/monitoring/grafana/plugins/placeholder.txt b/tools/monitoring/grafana/plugins/placeholder.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tools/monitoring/grafana/png/placeholder.txt b/tools/monitoring/grafana/png/placeholder.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tools/monitoring/grafana/provisioning/dashboards/dashboards.yaml b/tools/monitoring/grafana/provisioning/dashboards/dashboards.yaml new file mode 100755 index 0000000000000000000000000000000000000000..305b0dcb2cd27fd2d36670f3afe59321d6296af6 --- /dev/null +++ b/tools/monitoring/grafana/provisioning/dashboards/dashboards.yaml @@ -0,0 +1,24 @@ +apiVersion: 1 + +providers: + # <string> an unique provider name. Required + - name: 'Goshimmer Local Metrics' + # <int> Org id. Default to 1 + orgId: 1 + # <string> name of the dashboard folder. + folder: '' + # <string> folder UID. will be automatically generated if not specified + folderUid: '' + # <string> provider type. Default to 'file' + type: file + # <bool> disable dashboard deletion + disableDeletion: false + # <bool> enable dashboard editing + editable: true + # <int> how often Grafana will scan for changed dashboards + updateIntervalSeconds: 10 + # <bool> allow updating provisioned dashboards from the UI + allowUiUpdates: true + options: + # <string, required> path to dashboard files on disk. Required when using the 'file' type + path: /var/lib/grafana/dashboards diff --git a/tools/monitoring/grafana/provisioning/datasources/datasources.yaml b/tools/monitoring/grafana/provisioning/datasources/datasources.yaml new file mode 100755 index 0000000000000000000000000000000000000000..58b53f86acb2f0ec9123cacc7f80f2a480883bf3 --- /dev/null +++ b/tools/monitoring/grafana/provisioning/datasources/datasources.yaml @@ -0,0 +1,52 @@ +# config file version +apiVersion: 1 + +# list of datasources to insert/update depending +# what's available in the database +datasources: + # <string, required> name of the datasource. Required + - name: Prometheus + # <string, required> datasource type. Required + type: prometheus + # <string, required> access mode. proxy or direct (Server or Browser in the UI). Required + access: direct + # <int> org id. will default to orgId 1 if not specified + orgId: 1 + # <string> custom UID which can be used to reference this datasource in other parts of the configuration, if not specified will be generated automatically + uid: + # <string> url + url: http://localhost:9090 + # <string> Deprecated, use secureJsonData.password + password: + # <string> database user, if used + user: + # <string> database name, if used + database: + # <bool> enable/disable basic auth + basicAuth: + # <string> basic auth username + basicAuthUser: + # <string> Deprecated, use secureJsonData.basicAuthPassword + basicAuthPassword: + # <bool> enable/disable with credentials headers + withCredentials: + # <bool> mark as default datasource. Max one per org + isDefault: + # <map> fields that will be converted to json and stored in jsonData + jsonData: + graphiteVersion: '1.1' + tlsAuth: true + tlsAuthWithCACert: true + timeInterval: '1s' + # <string> json object of data that will be encrypted. + secureJsonData: + tlsCACert: '...' + tlsClientCert: '...' + tlsClientKey: '...' + # <string> database password, if used + password: + # <string> basic auth password + basicAuthPassword: + version: 1 + # <bool> allow users to edit datasources from the UI. + editable: true diff --git a/tools/monitoring/grafana/provisioning/notifiers/notifiers.yaml b/tools/monitoring/grafana/provisioning/notifiers/notifiers.yaml new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tools/monitoring/prometheus/prometheus.yml b/tools/monitoring/prometheus/prometheus.yml new file mode 100644 index 0000000000000000000000000000000000000000..f11383dd42aa4c8b1ca5f481b5bc0782e7c79277 --- /dev/null +++ b/tools/monitoring/prometheus/prometheus.yml @@ -0,0 +1,7 @@ +scrape_configs: + - job_name: goshimmer_local + scrape_interval: 5s + static_configs: + - targets: + # goshimmer prometheus plugin export + - 127.0.0.1:9311 \ No newline at end of file diff --git a/tools/rand-address/main.go b/tools/rand-address/main.go new file mode 100644 index 0000000000000000000000000000000000000000..dd13cc419882fb2f1f7408dd9db1462f062b2f79 --- /dev/null +++ b/tools/rand-address/main.go @@ -0,0 +1,11 @@ +package main + +import ( + "fmt" + + "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/wallet" +) + +func main() { + fmt.Println(wallet.New().Seed().Address(0)) +} diff --git a/tools/relay-checker/config.go b/tools/relay-checker/config.go index 6833f365dd0c59933def5969c74492dcf1c49f74..5e8d2ed774ba1e3e2a0cd09795c99ccdf7e77197 100644 --- a/tools/relay-checker/config.go +++ b/tools/relay-checker/config.go @@ -1,46 +1,34 @@ package main -import ( - "github.com/iotaledger/goshimmer/packages/parameter" -) +import "github.com/iotaledger/goshimmer/plugins/config" var ( nodes []string target = "" - txnAddr = "GOSHIMMER99TEST999999999999999999999999999999999999999999999999999999999999999999" - txnData = "TEST99BROADCAST99DATA" + msgData = "TEST99BROADCAST99DATA" cooldownTime = 2 repeat = 1 ) -func LoadConfig() { - if err := parameter.FetchConfig(false); err != nil { - panic(err) - } -} - -func SetConfig() { - if parameter.NodeConfig.GetString(CFG_TARGET_NODE) == "" { +func initConfig() { + if config.Node().GetString(CfgTargetNode) == "" { panic("Set the target node address\n") } - target = parameter.NodeConfig.GetString(CFG_TARGET_NODE) + target = config.Node().GetString(CfgTargetNode) - if len(parameter.NodeConfig.GetStringSlice(CFG_TEST_NODES)) == 0 { + if len(config.Node().GetStringSlice(CfgTestNodes)) == 0 { panic("Set node addresses\n") } - nodes = append(nodes, parameter.NodeConfig.GetStringSlice(CFG_TEST_NODES)...) + nodes = append(nodes, config.Node().GetStringSlice(CfgTestNodes)...) // optional settings - if parameter.NodeConfig.GetString(CFG_TX_ADDRESS) != "" { - txnAddr = parameter.NodeConfig.GetString(CFG_TX_ADDRESS) - } - if parameter.NodeConfig.GetString(CFG_DATA) != "" { - txnData = parameter.NodeConfig.GetString(CFG_DATA) + if config.Node().GetString(CfgData) != "" { + msgData = config.Node().GetString(CfgData) } - if parameter.NodeConfig.GetInt(CFG_COOLDOWN_TIME) > 0 { - cooldownTime = parameter.NodeConfig.GetInt(CFG_COOLDOWN_TIME) + if config.Node().GetInt(CfgCooldownTime) > 0 { + cooldownTime = config.Node().GetInt(CfgCooldownTime) } - if parameter.NodeConfig.GetInt(CFG_REPEAT) > 0 { - repeat = parameter.NodeConfig.GetInt(CFG_REPEAT) + if config.Node().GetInt(CfgRepeat) > 0 { + repeat = config.Node().GetInt(CfgRepeat) } } diff --git a/tools/relay-checker/config.json b/tools/relay-checker/config.json index a830da125c7c13353b020933dc0a7a9a884cfc86..27a1dee20a7c4300a37878c889d1e7a1ae4e88a8 100644 --- a/tools/relay-checker/config.json +++ b/tools/relay-checker/config.json @@ -4,7 +4,6 @@ "testNodes": [ "http://127.0.0.1:8080" ], - "txAddress": "SHIMMER99TEST99999999999999999999999999999999999999999999999999999999999999999999", "data": "TEST99BROADCAST99DATA", "cooldownTime": 10, "repeat": 2 diff --git a/tools/relay-checker/main.go b/tools/relay-checker/main.go index 4bdc570883eae4b519e5fdf1deee5828e14cd1df..998fda5f212cca982397f988f0857039fefb0dcb 100644 --- a/tools/relay-checker/main.go +++ b/tools/relay-checker/main.go @@ -5,62 +5,65 @@ import ( "time" client "github.com/iotaledger/goshimmer/client" - "github.com/iotaledger/iota.go/trinary" + "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/logger" ) -func testBroadcastData(api *client.GoShimmerAPI) (trinary.Hash, error) { - txnHash, err := api.BroadcastData(txnAddr, txnData) +func testBroadcastData(api *client.GoShimmerAPI) (string, error) { + msgID, err := api.Data([]byte(msgData)) if err != nil { return "", fmt.Errorf("broadcast failed: %w", err) } - return txnHash, nil + return msgID, nil } -func testTargetGetTransactions(api *client.GoShimmerAPI, txnHash trinary.Hash) error { +func testTargetGetMessages(api *client.GoShimmerAPI, msgID string) error { // query target node for broadcasted data - if _, err := api.GetTransactionObjectsByHash([]trinary.Hash{txnHash}); err != nil { + if _, err := api.FindMessageByID([]string{msgID}); err != nil { return fmt.Errorf("querying the target node failed: %w", err) } return nil } -func testNodesGetTransactions(txnHash trinary.Hash) error { +func testNodesGetMessages(msgID string) error { // query nodes node for broadcasted data for _, n := range nodes { - nodesApi := client.NewGoShimmerAPI(n) - if _, err := nodesApi.GetTransactionObjectsByHash([]trinary.Hash{txnHash}); err != nil { + nodesAPI := client.NewGoShimmerAPI(n) + if _, err := nodesAPI.FindMessageByID([]string{msgID}); err != nil { return fmt.Errorf("querying node %s failed: %w", n, err) } - fmt.Printf("txn found in node %s\n", n) + fmt.Printf("msg found in node %s\n", n) } return nil } func main() { - LoadConfig() - SetConfig() + config.Init() + logger.Init() + + initConfig() api := client.NewGoShimmerAPI(target) for i := 0; i < repeat; i++ { - txnHash, err := testBroadcastData(api) + msgID, err := testBroadcastData(api) if err != nil { fmt.Printf("%s\n", err) break } - fmt.Printf("txnHash: %s\n", txnHash) + fmt.Printf("msgID: %s\n", msgID) // cooldown time time.Sleep(time.Duration(cooldownTime) * time.Second) // query target node - err = testTargetGetTransactions(api, txnHash) + err = testTargetGetMessages(api, msgID) if err != nil { fmt.Printf("%s\n", err) break } // query test nodes - err = testNodesGetTransactions(txnHash) + err = testNodesGetMessages(msgID) if err != nil { fmt.Printf("%s\n", err) break diff --git a/tools/relay-checker/parameters.go b/tools/relay-checker/parameters.go index ac64aaf77069fc73aa26bf65116c61cca23eee91..ffe9a5ea460c49b88c3cbe8fc10f7769691cd483 100644 --- a/tools/relay-checker/parameters.go +++ b/tools/relay-checker/parameters.go @@ -5,19 +5,22 @@ import ( ) const ( - CFG_TARGET_NODE = "relayChecker.targetNode" - CFG_TEST_NODES = "relayChecker.testNodes" - CFG_TX_ADDRESS = "relayChecker.txAddress" - CFG_DATA = "relayChecker.data" - CFG_COOLDOWN_TIME = "relayChecker.cooldownTime" - CFG_REPEAT = "relayChecker.repeat" + // CfgTargetNode defines the config flag of the target node. + CfgTargetNode = "relayChecker.targetNode" + // CfgTestNodes defines the config flag of the test nodes. + CfgTestNodes = "relayChecker.testNodes" + // CfgData defines the config flag of the data. + CfgData = "relayChecker.data" + // CfgCooldownTime defines the config flag of the cooldown time. + CfgCooldownTime = "relayChecker.cooldownTime" + // CfgRepeat defines the config flag of the repeat. + CfgRepeat = "relayChecker.repeat" ) func init() { - flag.StringSlice(CFG_TEST_NODES, []string{""}, "the list of nodes to check after the cooldown") - flag.String(CFG_TARGET_NODE, "http://127.0.0.1:8080", "the target node from the which transaction will be broadcasted from") - flag.String(CFG_TX_ADDRESS, "SHIMMER99TEST99999999999999999999999999999999999999999999999999999999999999999999", "the transaction address") - flag.String(CFG_DATA, "TEST99BROADCAST99DATA", "data to broadcast") - flag.Int(CFG_COOLDOWN_TIME, 10, "the cooldown time after broadcasting the data on the specified target node") - flag.Int(CFG_REPEAT, 1, "the amount of times to repeat the relay-checker queries") + flag.StringSlice(CfgTargetNode, []string{""}, "the list of nodes to check after the cooldown") + flag.String(CfgTestNodes, "http://127.0.0.1:8080", "the target node from the which message will be broadcasted from") + flag.String(CfgData, "TEST99BROADCAST99DATA", "data to broadcast") + flag.Int(CfgCooldownTime, 10, "the cooldown time after broadcasting the data on the specified target node") + flag.Int(CfgRepeat, 1, "the amount of times to repeat the relay-checker queries") } diff --git a/tools/spammer/main.go b/tools/spammer/main.go new file mode 100644 index 0000000000000000000000000000000000000000..cf6adb0b1fb345e7ae9fc401070efbb09b214bf3 --- /dev/null +++ b/tools/spammer/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + + "github.com/iotaledger/goshimmer/client" + flag "github.com/spf13/pflag" + "github.com/spf13/viper" +) + +const ( + cfgNodeURI = "node" + cfgMessage = "message" +) + +func init() { + flag.String(cfgNodeURI, "http://127.0.0.1:8080", "the URI of the node API") + flag.String(cfgMessage, "", "the URI of the node API") +} + +func main() { + flag.Parse() + if err := viper.BindPFlags(flag.CommandLine); err != nil { + panic(err) + } + goshimAPI := client.NewGoShimmerAPI(viper.GetString(cfgNodeURI)) + messageBytes := []byte(viper.GetString(cfgMessage)) + var issued, failed int + for { + fmt.Printf("issued %d, failed %d\r", issued, failed) + _, err := goshimAPI.Data(messageBytes) + if err != nil { + failed++ + continue + } + issued++ + } +}